Now the narrowband and wideband bit-streams are compatible and can be
authorjmvalin <jmvalin@0101bb08-14d6-0310-b084-bc0e0c8e3800>
Wed, 14 Aug 2002 17:58:31 +0000 (17:58 +0000)
committerjmvalin <jmvalin@0101bb08-14d6-0310-b084-bc0e0c8e3800>
Wed, 14 Aug 2002 17:58:31 +0000 (17:58 +0000)
decoded in either mode

git-svn-id: http://svn.xiph.org/trunk/speex@3820 0101bb08-14d6-0310-b084-bc0e0c8e3800

libspeex/bits.c
libspeex/modes.c
libspeex/modes.h
libspeex/nb_celp.c
libspeex/sb_celp.c
libspeex/speex_bits.h

index c2980c5..b317751 100644 (file)
@@ -189,6 +189,27 @@ unsigned int speex_bits_unpack_unsigned(SpeexBits *bits, int nbBits)
    return d;
 }
 
+int speex_bits_peek(SpeexBits *bits)
+{
+   return (bits->bytes[bits->bytePtr]>>(7-bits->bitPtr))&1;
+}
+
+void speex_bits_advance(SpeexBits *bits, int n)
+{
+   int nbytes, nbits;
+   nbytes = n >> 3;
+   nbits = n & 7;
+   
+   bits->bytePtr += nbytes;
+   bits->bitPtr += nbits;
+   
+   if (bits->bitPtr>7)
+   {
+      bits->bitPtr-=8;
+      bits->bytePtr++;
+   }
+}
+
 int speex_bits_nbytes(SpeexBits *bits)
 {
    return ((bits->nbBits+7)>>3);
index dcc3355..a7a961e 100644 (file)
@@ -144,7 +144,7 @@ static SpeexSubmode nb_submode1 = {
    NULL,
 
    0, 0, -1,
-   2100
+   43
 };
 
 static SpeexSubmode nb_submode2 = {
@@ -163,7 +163,7 @@ static SpeexSubmode nb_submode2 = {
    &split_cb_nb_vlbr,
 
    0.75, 0.6, .6,
-   5900
+   119
 };
 
 
@@ -183,7 +183,7 @@ static SpeexSubmode nb_submode3 = {
    &split_cb_nb_lbr,
 
    0.75, 0.6, .5,
-   7950
+   160
 };
 
 static SpeexSubmode nb_submode4 = {
@@ -202,7 +202,7 @@ static SpeexSubmode nb_submode4 = {
    &split_cb_nb_med,
 
    0.72, 0.65, .3,
-   10950
+   220
 };
 
 static SpeexSubmode nb_submode5 = {
@@ -221,7 +221,7 @@ static SpeexSubmode nb_submode5 = {
    &split_cb_nb,
 
    0.7, 0.65, .2,
-   14950
+   300
 };
 
 static SpeexSubmode nb_submode6 = {
@@ -240,7 +240,7 @@ static SpeexSubmode nb_submode6 = {
    &split_cb_sb,
 
    0.68, 0.65, .1,
-   18150
+   364
 };
 
 
@@ -297,7 +297,7 @@ static SpeexSubmode wb_submode1 = {
    NULL,
 
    0, 0, -1,
-   1750
+   36
 };
 
 
@@ -317,7 +317,7 @@ static SpeexSubmode wb_submode2 = {
    &split_cb_high_lbr,
 
    0, 0, -1,
-   5550
+   112
 };
 
 
@@ -337,12 +337,12 @@ static SpeexSubmode wb_submode3 = {
    &split_cb_high,
 
    0, 0, -1,
-   9550
+   192
 };
 
 
 /* Split-band wideband CELP mode*/
-static SpeexSBMode sb_wb_mode = {
+SpeexSBMode sb_wb_mode = {
    &speex_nb_mode,
    160,    /*frameSize*/
    40,     /*subframeSize*/
index 7d40fd6..fb7b707 100644 (file)
@@ -74,7 +74,7 @@ typedef struct SpeexSubmode {
    /*Synthesis filter enhancement*/
    float lpc_enh_k1, lpc_enh_k2, comb_gain;
 
-   int               bitrate;
+   int               bits_per_frame;
 } SpeexSubmode;
 
 /*Struct defining the encoding/decoding mode*/
@@ -117,6 +117,6 @@ typedef struct SpeexSBMode {
 } SpeexSBMode;
 
 
-
+extern SpeexSBMode sb_wb_mode;
 
 #endif
index fc63165..7ff27b0 100644 (file)
@@ -273,6 +273,7 @@ void nb_encode(void *state, float *in, SpeexBits *bits)
                                nol_pitch, nol_pitch_coef, 4, st->stack);
          ol_pitch=nol_pitch[0];
          ol_pitch_coef = nol_pitch_coef[0];
+         /*Try to remove pitch multiples*/
          for (i=1;i<4;i++)
          {
             if ((nol_pitch_coef[i] > .85*ol_pitch_coef) && 
@@ -283,7 +284,7 @@ void nb_encode(void *state, float *in, SpeexBits *bits)
                ol_pitch = nol_pitch[i];
             }
          }
-         printf ("ol_pitch: %d %f\n", ol_pitch, ol_pitch_coef);
+         /*printf ("ol_pitch: %d %f\n", ol_pitch, ol_pitch_coef);*/
       }
       /*Compute "real" excitation*/
       residue(st->frame, st->interp_lpc, st->exc, st->frameSize, st->lpcSize);
@@ -314,7 +315,10 @@ void nb_encode(void *state, float *in, SpeexBits *bits)
    }
    /*printf ("VBR quality = %f\n", vbr_qual);*/
 
-   /* First, transmit the sub-mode we use for this frame */
+   /* First, transmit a zero for narrowband */
+   speex_bits_pack(bits, 0, 1);
+
+   /* Transmit the sub-mode we use for this frame */
    speex_bits_pack(bits, st->submodeID, NB_SUBMODE_BITS);
 
 
@@ -748,8 +752,25 @@ void nb_decode(void *state, SpeexBits *bits, float *out, int lost)
    float ol_pitch_coef=0;
    int best_pitch=40;
    float best_pitch_gain=-1;
+   int wideband;
+
    st=state;
 
+   wideband = speex_bits_unpack_unsigned(bits, 1);
+   if (wideband)
+   {
+      int submode;
+      int advance;
+      submode = speex_bits_unpack_unsigned(bits, SB_SUBMODE_BITS);
+      advance = sb_wb_mode.submodes[submode]->bits_per_frame - (SB_SUBMODE_BITS+1);
+      speex_bits_advance(bits, advance);
+      wideband = speex_bits_unpack_unsigned(bits, 1);
+      if (wideband)
+      {
+         fprintf (stderr, "Corrupted stream\n");
+      }
+   }
+
    /* Get the sub-mode that was used */
    st->submodeID = speex_bits_unpack_unsigned(bits, NB_SUBMODE_BITS);
 
@@ -1067,9 +1088,9 @@ void nb_encoder_ctl(void *state, int request, void *ptr)
       break;
    case SPEEX_GET_BITRATE:
       if (st->submodes[st->submodeID])
-         (*(int*)ptr) = SUBMODE(bitrate);
+         (*(int*)ptr) = 50*SUBMODE(bits_per_frame);
       else
-         (*(int*)ptr) = 200;
+         (*(int*)ptr) = 50*(NB_SUBMODE_BITS+1);
       break;
    default:
       fprintf(stderr, "Unknown nb_ctl request: %d\n", request);
@@ -1093,9 +1114,9 @@ void nb_decoder_ctl(void *state, int request, void *ptr)
       break;
    case SPEEX_GET_BITRATE:
       if (st->submodes[st->submodeID])
-         (*(int*)ptr) = SUBMODE(bitrate);
+         (*(int*)ptr) = 50*SUBMODE(bits_per_frame);
       else
-         (*(int*)ptr) = 200;
+         (*(int*)ptr) = 50*(NB_SUBMODE_BITS+1);
       break;
    default:
       fprintf(stderr, "Unknown nb_ctl request: %d\n", request);
index ad12835..e309a11 100644 (file)
@@ -272,6 +272,7 @@ void sb_encode(void *state, float *in, SpeexBits *bits)
    /* Encode the narrowband part*/
    nb_encode(st->st_low, st->x0d, bits);
 
+   speex_bits_pack(bits, 1, 1);
    speex_bits_pack(bits, st->submodeID, SB_SUBMODE_BITS);
 
    /* High-band buffering / sync with low band */
@@ -723,12 +724,24 @@ void sb_decode(void *state, SpeexBits *bits, float *out, int lost)
 {
    int i, sub;
    SBDecState *st;
-   
+   int wideband;
+
    st = state;
    /* Decode the low-band */
    nb_decode(st->st_low, bits, st->x0d, lost);
 
-   st->submodeID = speex_bits_unpack_unsigned(bits, SB_SUBMODE_BITS);
+   /*Check "wideband bit"*/
+   wideband = speex_bits_peek(bits);
+   if (wideband)
+   {
+      /*Regular wideband frame, read the submode*/
+      wideband = speex_bits_unpack_unsigned(bits, 1);
+      st->submodeID = speex_bits_unpack_unsigned(bits, SB_SUBMODE_BITS);
+   } else
+   {
+      /*Was a narrowband frame, set "null submode"*/
+      st->submodeID = 0;
+   }
 
    for (i=0;i<st->frame_size;i++)
       st->exc[i]=0;
@@ -952,9 +965,9 @@ void sb_encoder_ctl(void *state, int request, void *ptr)
    case SPEEX_GET_BITRATE:
       speex_encoder_ctl(st->st_low, request, ptr);
       if (st->submodes[st->submodeID])
-         (*(int*)ptr) += SUBMODE(bitrate);
+         (*(int*)ptr) += 50*SUBMODE(bits_per_frame);
       else
-         (*(int*)ptr) += 150;
+         (*(int*)ptr) += 50*(SB_SUBMODE_BITS+1);
       break;
    default:
       fprintf(stderr, "Unknown nb_ctl request: %d\n", request);
@@ -977,9 +990,9 @@ void sb_decoder_ctl(void *state, int request, void *ptr)
    case SPEEX_GET_BITRATE:
       speex_decoder_ctl(st->st_low, request, ptr);
       if (st->submodes[st->submodeID])
-         (*(int*)ptr) += SUBMODE(bitrate);
+         (*(int*)ptr) += 50*SUBMODE(bits_per_frame);
       else
-         (*(int*)ptr) += 150;
+         (*(int*)ptr) += 50*(SB_SUBMODE_BITS+1);
       break;
    default:
       fprintf(stderr, "Unknown sb_ctl request: %d\n", request);
index 9cb3241..569631d 100644 (file)
@@ -70,6 +70,10 @@ unsigned int speex_bits_unpack_unsigned(SpeexBits *bits, int nbBits);
 
 int speex_bits_nbytes(SpeexBits *bits);
 
+int speex_bits_peek(SpeexBits *bits);
+
+   void speex_bits_advance(SpeexBits *bits, int n);
+
 #ifdef __cplusplus
 }
 #endif