Allow more than one frame per packet
authorjmvalin <jmvalin@0101bb08-14d6-0310-b084-bc0e0c8e3800>
Sun, 28 Jul 2002 04:09:51 +0000 (04:09 +0000)
committerjmvalin <jmvalin@0101bb08-14d6-0310-b084-bc0e0c8e3800>
Sun, 28 Jul 2002 04:09:51 +0000 (04:09 +0000)
git-svn-id: http://svn.xiph.org/trunk/speex@3721 0101bb08-14d6-0310-b084-bc0e0c8e3800

doc/manual.lyx
libspeex/bits.c
libspeex/cb_search.c
libspeex/speex_bits.h
libspeex/speex_header.c
libspeex/speex_header.h
src/speexdec.c
src/speexenc.c

index 9257e97..10ce136 100644 (file)
@@ -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
index 6be836a..fdb0cc9 100644 (file)
@@ -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);
+}
index 12ac91c..2b54688 100644 (file)
@@ -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);
 }
 
 
index 545d863..86c9af6 100644 (file)
@@ -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
index fb1ae21..715c9ea 100644 (file)
@@ -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;
 
index a71fc5e..97dfa64 100644 (file)
@@ -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);
index f569f0a..8ed031c 100644 (file)
@@ -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++;
          }
index 9ab5146..ac7a9b2 100644 (file)
@@ -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)*/