Commit 418f44e5 authored by jmvalin's avatar jmvalin
Browse files

Allow more than one frame per packet


git-svn-id: http://svn.xiph.org/trunk/speex@3721 0101bb08-14d6-0310-b084-bc0e0c8e3800
parent 6778befa
......@@ -108,7 +108,7 @@ Good for Voice over IP (VoIP)
Provide very good quality speech (at least as an option)
\layout Itemize
Allow a wide range of quality/bit-rate
Allow a wide range of quality/bit-rates
\layout Itemize
Integrate both narrowband and wideband coding
......
......@@ -169,3 +169,8 @@ unsigned int speex_bits_unpack_unsigned(SpeexBits *bits, int nbBits)
}
return d;
}
int speex_bits_nbytes(SpeexBits *bits)
{
return ((bits->nbBits+7)>>3);
}
......@@ -335,14 +335,14 @@ float *stack
float *t, *r, *e, *E;
/*FIXME: Should make this dynamic*/
float *tmp, *ot[20], *nt[20];
float *ndist;
float *ndist, *odist;
int *itmp, *nind[20], *oind[20];
int *ind;
float *shape_cb;
int shape_cb_size, subvect_size, nb_subvect;
split_cb_params *params;
int N=4;
int N=2;
int *best_index;
float *best_dist;
......@@ -370,6 +370,7 @@ float *stack
best_index = (int*)PUSH(stack, N);
best_dist = PUSH(stack, N);
ndist = PUSH(stack, N);
odist = PUSH(stack, N);
itmp = (int*)PUSH(stack, 2*N*nb_subvect);
for (i=0;i<N;i++)
......@@ -415,6 +416,8 @@ float *stack
E[i]+=res[j]*res[j];
}
for (j=0;j<N;j++)
odist[j]=0;
/*For all subvectors*/
for (i=0;i<nb_subvect;i++)
{
......@@ -433,8 +436,10 @@ float *stack
for (k=0;k<N;k++)
{
float err=0;
/*previous target*/
for (m=0;m<nsf;m++)
t[m]=ot[j][m];
/*update target*/
for (m=0;m<subvect_size;m++)
{
float g=shape_cb[best_index[k]*subvect_size+m];
......@@ -442,8 +447,11 @@ float *stack
t[n] -= g*r[q];
}
for (m=0;m<(i+1)*subvect_size;m++)
/*compute error (distance)*/
err=odist[j];
for (m=i*subvect_size;m<(i+1)*subvect_size;m++)
err += t[m]*t[m];
/*update n-best list*/
if (err<ndist[N-1] || ndist[N-1]<-.5)
{
for (m=0;m<N;m++)
......@@ -473,15 +481,18 @@ float *stack
break;
}
/*opdate old-new data*/
for (j=0;j<N;j++)
for (m=0;m<nsf;m++)
ot[j][m]=nt[j][m];
for (j=0;j<N;j++)
for (m=0;m<nb_subvect;m++)
oind[j][m]=nind[j][m];
for (j=0;j<N;j++)
odist[j]=ndist[j];
}
/*save indices*/
for (i=0;i<nb_subvect;i++)
{
ind[i]=nind[0][i];
......@@ -515,6 +526,7 @@ float *stack
POP(stack);
POP(stack);
POP(stack);
POP(stack);
}
......
......@@ -64,6 +64,8 @@ int speex_bits_unpack_signed(SpeexBits *bits, int nbBits);
unsigned int speex_bits_unpack_unsigned(SpeexBits *bits, int nbBits);
int speex_bits_nbytes(SpeexBits *bits);
#ifdef __cplusplus
}
#endif
......
......@@ -41,10 +41,10 @@ typedef struct SpeexHeader {
int bitrate;
int frame_size;
int vbr;
int frames_per_packet;
int reserved1;
int reserved2;
int reserved3;
int reserved4;
} SpeexHeader;
*/
......@@ -67,10 +67,10 @@ void speex_init_header(SpeexHeader *header, int rate, int nb_channels, SpeexMode
header->frame_size = m->frame_size;
header->vbr = m->vbr;
header->frames_per_packet = 0;
header->reserved1 = 0;
header->reserved2 = 0;
header->reserved3 = 0;
header->reserved4 = 0;
}
char *speex_header_to_packet(SpeexHeader *header, int *size)
......@@ -90,6 +90,7 @@ char *speex_header_to_packet(SpeexHeader *header, int *size)
ENDIAN_SWITCH(le_header->bitrate);
ENDIAN_SWITCH(le_header->frame_size);
ENDIAN_SWITCH(le_header->vbr);
ENDIAN_SWITCH(le_header->frames_per_packet);
*size = sizeof(SpeexHeader);
return (char *)le_header;
......@@ -125,6 +126,7 @@ SpeexHeader *speex_packet_to_header(char *packet, int size)
ENDIAN_SWITCH(le_header->bitrate);
ENDIAN_SWITCH(le_header->frame_size);
ENDIAN_SWITCH(le_header->vbr);
ENDIAN_SWITCH(le_header->frames_per_packet);
return le_header;
......
......@@ -43,10 +43,10 @@ typedef struct SpeexHeader {
int bitrate;
int frame_size;
int vbr;
int frames_per_packet;
int reserved1;
int reserved2;
int reserved3;
int reserved4;
} SpeexHeader;
void speex_init_header(SpeexHeader *header, int rate, int nb_channels, struct SpeexMode *m);
......
......@@ -130,7 +130,7 @@ void version()
fprintf (stderr, "Speex decoder version " VERSION "\n");
}
static void *process_header(ogg_packet *op, int pf_enabled, int *frame_size, int *rate)
static void *process_header(ogg_packet *op, int pf_enabled, int *frame_size, int *rate, int *nframes)
{
void *st;
SpeexMode *mode;
......@@ -167,7 +167,8 @@ static void *process_header(ogg_packet *op, int pf_enabled, int *frame_size, int
speex_decoder_ctl(st, SPEEX_GET_FRAME_SIZE, frame_size);
*rate = header->rate;
*nframes = header->frames_per_packet;
fprintf (stderr, "Decoding %d Hz audio using %s mode\n",
*rate, mode->modeName);
......@@ -203,6 +204,7 @@ int main(int argc, char **argv)
ogg_packet op;
ogg_stream_state os;
int pf_enabled;
int nframes=2;
pf_enabled = 0;
......@@ -281,7 +283,7 @@ int main(int argc, char **argv)
while (1)
{
char *data;
int i, nb_read;
int i, j, nb_read;
/*Get the ogg buffer for writing*/
data = ogg_sync_buffer(&oy, 200);
/*Read bitstream from input file*/
......@@ -300,7 +302,9 @@ int main(int argc, char **argv)
if (packet_count==0)
{
int rate;
st = process_header(&op, pf_enabled, &frame_size, &rate);
st = process_header(&op, pf_enabled, &frame_size, &rate, &nframes);
if (!nframes)
nframes=1;
if (!st)
exit(1);
fout = out_file_open(outFile, rate);
......@@ -314,28 +318,13 @@ int main(int argc, char **argv)
/*End of stream condition*/
if (strncmp((char *)op.packet, "END OF STREAM", 13)==0)
break;
/* Put 0 here only to simulate packet loss */
if (1)
/*Copy Ogg packet to Speex bitstream*/
speex_bits_read_from(&bits, (char*)op.packet, op.bytes);
for (j=0;j<nframes;j++)
{
/*Copy Ogg packet to Speex bitstream*/
speex_bits_read_from(&bits, (char*)op.packet, op.bytes);
/*Decode a frame*/
/*Decode frame*/
speex_decode(st, &bits, output, 0);
} else {
static int first=1;
if ((((float)rand())/RAND_MAX < .1) && !first)
{
printf ("PACKET LOSS\n");
speex_bits_rewind(&bits);
speex_decode(st, &bits, output, 1);
} else {
printf ("PACKET OK\n");
speex_bits_read_from(&bits, (char*)op.packet, op.bytes);
speex_decode(st, &bits, output, 0);
}
first=0;
}
/*PCM saturation (just in case)*/
for (i=0;i<frame_size;i++)
{
......@@ -348,6 +337,7 @@ int main(int argc, char **argv)
for (i=0;i<frame_size;i++)
out[i]=(short)le_short(output[i]);
fwrite(out, sizeof(short), frame_size, fout);
}
}
packet_count++;
}
......
......@@ -62,6 +62,7 @@ void usage()
fprintf (stderr, " --quality n Encoding quality setting from 0 to 10\n");
fprintf (stderr, " --lbr Low bit-rate mode (equivalent to --quality 3)\n");
fprintf (stderr, " --vbr Enable variable bit-rate (VBR)\n");
fprintf (stderr, " --nframes n Number of frames per Ogg packet\n");
fprintf (stderr, " --help -h This help\n");
fprintf (stderr, " --version -v Version information\n");
fprintf (stderr, "\n");
......@@ -84,7 +85,7 @@ int main(int argc, char **argv)
short in[MAX_FRAME_SIZE];
float input[MAX_FRAME_SIZE];
int frame_size;
int vbr_enabled;
int vbr_enabled=0;
int i,nbBytes;
SpeexMode *mode=NULL;
void *st;
......@@ -110,6 +111,7 @@ int main(int argc, char **argv)
int bytes_written, ret, result;
int id=0;
SpeexHeader header;
int nframes=1;
char *comments = "Encoded with Speex " VERSION;
/*Process command-line options*/
......@@ -134,6 +136,9 @@ int main(int argc, char **argv)
else if (strcmp(long_options[option_index].name,"quality")==0)
{
quality = atoi (optarg);
} else if (strcmp(long_options[option_index].name,"nframes")==0)
{
nframes = atoi (optarg);
} else if (strcmp(long_options[option_index].name,"help")==0)
{
usage();
......@@ -231,6 +236,7 @@ int main(int argc, char **argv)
}
speex_init_header(&header, rate, 1, mode);
header.frames_per_packet=nframes;
fprintf (stderr, "Encoding %d Hz audio using %s mode\n",
header.rate, mode->modeName);
......@@ -316,16 +322,16 @@ int main(int argc, char **argv)
/*Encode current frame*/
speex_encode(st, input, &bits);
/*if (id%5!=0)
continue;*/
nbBytes = speex_bits_write(&bits, cbits, 500);
if (id%nframes!=0)
continue;
nbBytes = speex_bits_write(&bits, cbits, MAX_FRAME_BYTES);
speex_bits_reset(&bits);
op.packet = (unsigned char *)cbits;
op.bytes = nbBytes;
op.b_o_s = 0;
op.e_o_s = 0;
op.granulepos = id;
op.packetno = id;
op.granulepos = id*frame_size;
op.packetno = id/nframes;
ogg_stream_packetin(&os, &op);
/*Write all new pages (not likely 0 or 1)*/
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment