First step to variable bit-rate (VBR): it is now possible to change the
authorjmvalin <jmvalin@0101bb08-14d6-0310-b084-bc0e0c8e3800>
Tue, 25 Jun 2002 18:46:13 +0000 (18:46 +0000)
committerjmvalin <jmvalin@0101bb08-14d6-0310-b084-bc0e0c8e3800>
Tue, 25 Jun 2002 18:46:13 +0000 (18:46 +0000)
modes (bit-rate) of the encoder dynamically (decoder adjusts itself).

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

12 files changed:
configure.in
libspeex/modes.c
libspeex/modes.h
libspeex/nb_celp.c
libspeex/nb_celp.h
libspeex/sb_celp.c
libspeex/sb_celp.h
libspeex/speex.h
libspeex/testenc.c
libspeex/testenc_wb.c
src/speexdec.c
src/speexenc.c

index 932acdf..ac759b5 100644 (file)
@@ -3,8 +3,8 @@ dnl Process this file with autoconf to produce a configure script. -*-m4-*-
 AC_INIT(libspeex/speex.h)
 
 SPEEX_MAJOR_VERSION=0
-SPEEX_MINOR_VERSION=3
-SPEEX_MICRO_VERSION=1
+SPEEX_MINOR_VERSION=4
+SPEEX_MICRO_VERSION=0
 SPEEX_VERSION=$SPEEX_MAJOR_VERSION.$SPEEX_MINOR_VERSION.$SPEEX_MICRO_VERSION
 SPEEX_BINARY_AGE=0
 SPEEX_INTERFACE_AGE=0
index 068cf70..bdcc04a 100644 (file)
@@ -29,7 +29,7 @@
 #include "post_filter.h"
 
 
-SpeexMode *speex_mode_list[] = {&speex_nb_mode, &speex_nb_lbr_mode, &speex_wb_mode, &speex_wb_mode_lbr};
+SpeexMode *speex_mode_list[SPEEX_NB_MODES] = {&speex_nb_mode, &speex_wb_mode};
 
 /* Extern declarations for all codebooks we use here */
 extern float gain_cdbk_nb[];
@@ -125,81 +125,44 @@ static split_cb_params split_cb_high_lbr = {
 };
 
 
-/* Default mode for narrowband */
-SpeexNBMode nb_mode = {
-   160,    /*frameSize*/
-   40,     /*subframeSize*/
-   10,     /*lpcSize*/
-   640,    /*bufSize*/
-   17,     /*pitchStart*/
-   144,    /*pitchEnd*/
-   0,      /*lbr_pitch*/
-   0.9,    /*gamma1*/
-   0.6,    /*gamma2*/
-   .005,   /*lag_factor*/
-   1.0001, /*lpc_floor*/
-   0.0,    /*preemph*/
+
+SpeexSubmode nb_submode1 = {
+   1,
    /*LSP quantization*/
-   lsp_quant_nb,
-   lsp_unquant_nb,
+   lsp_quant_lbr,
+   lsp_unquant_lbr,
    /*Pitch quantization*/
    pitch_search_3tap,
    pitch_unquant_3tap,
-   &ltp_params_nb,
+   &ltp_params_lbr,
    /*Innovation quantization*/
    split_cb_search_nogain2,
    split_cb_nogain_unquant,
-   &split_cb_nb,
+   &split_cb_nb_lbr,
    nb_post_filter,
-   &pf_params_nb
+   &pf_params_lbr
 };
 
 
-/* Default mode for narrowband */
-SpeexNBMode nb_lbr_mode = {
-   160,    /*frameSize*/
-   40,     /*subframeSize*/
-   10,     /*lpcSize*/
-   640,    /*bufSize*/
-   17,     /*pitchStart*/
-   144,    /*pitchEnd*/
-   1,      /*lbr_pitch*/
-   0.9,    /*gamma1*/
-   0.6,    /*gamma2*/
-   .005,   /*lag_factor*/
-   1.0001, /*lpc_floor*/
-   0.0,    /*preemph*/
+SpeexSubmode nb_submode2 = {
+   0,
    /*LSP quantization*/
-   lsp_quant_lbr,
-   lsp_unquant_lbr,
+   lsp_quant_nb,
+   lsp_unquant_nb,
    /*Pitch quantization*/
    pitch_search_3tap,
    pitch_unquant_3tap,
-   &ltp_params_lbr,
+   &ltp_params_nb,
    /*Innovation quantization*/
    split_cb_search_nogain2,
    split_cb_nogain_unquant,
-   &split_cb_nb_lbr,
+   &split_cb_nb,
    nb_post_filter,
-   &pf_params_lbr
+   &pf_params_nb
 };
 
-
-
-/* Narrowband mode used for split-band wideband CELP*/
-static SpeexNBMode low_sb_mode = {
-   160,    /*frameSize*/
-   40,     /*subframeSize*/
-   10,     /*lpcSize*/
-   640,    /*bufSize*/
-   17,     /*pitchStart*/
-   144,    /*pitchEnd*/
-   0,      /*lbr_pitch*/
-   .9,    /*gamma1*/
-   0.6,    /*gamma2*/
-   .002,   /*lag_factor*/
-   1.00005, /*lpc_floor*/
-   0.0,    /*preemph*/
+SpeexSubmode nb_submode3 = {
+   0,
    /*LSP quantization*/
    lsp_quant_nb,
    lsp_unquant_nb,
@@ -215,29 +178,30 @@ static SpeexNBMode low_sb_mode = {
    &pf_params_sb
 };
 
-SpeexMode low_wb_mode = {
-   &low_sb_mode,
-   "low sub-band (used internally)",
-   -1,
-   -1,
-   &nb_encoder_init,
-   &nb_encoder_destroy,
-   &nb_encode,
-   &nb_decoder_init,
-   &nb_decoder_destroy,
-   &nb_decode,
-   &nb_encoder_ctl,
-   &nb_decoder_ctl,
-   160,
-   17950,
-   0
+
+/* Default mode for narrowband */
+SpeexNBMode nb_mode = {
+   160,    /*frameSize*/
+   40,     /*subframeSize*/
+   10,     /*lpcSize*/
+   640,    /*bufSize*/
+   17,     /*pitchStart*/
+   144,    /*pitchEnd*/
+   0.9,    /*gamma1*/
+   0.6,    /*gamma2*/
+   .005,   /*lag_factor*/
+   1.0001, /*lpc_floor*/
+   0.0,    /*preemph*/
+   {NULL, &nb_submode1, &nb_submode2, &nb_submode3},
+   2
 };
 
+
 SpeexMode speex_nb_mode = {
    &nb_mode,
-   "full-rate narrowband",
-   0,
+   "narrowband",
    0,
+   1,
    &nb_encoder_init,
    &nb_encoder_destroy,
    &nb_encode,
@@ -251,70 +215,45 @@ SpeexMode speex_nb_mode = {
    0
 };
 
-SpeexMode speex_nb_lbr_mode = {
-   &nb_lbr_mode,
-   "low bit-rate narrowband",
-   1,
-   0,
-   &nb_encoder_init,
-   &nb_encoder_destroy,
-   &nb_encode,
-   &nb_decoder_init,
-   &nb_decoder_destroy,
-   &nb_decode,
-   &nb_encoder_ctl,
-   &nb_decoder_ctl,
-   160,
-   7900,
-   0
-};
 
-/* Split-band wideband CELP mode*/
-static SpeexSBMode sb_wb_mode = {
-   &low_wb_mode,
-   160,    /*frameSize*/
-   40,     /*subframeSize*/
-   8,     /*lpcSize*/
-   640,    /*bufSize*/
-   .9,    /*gamma1*/
-   0.6,    /*gamma2*/
-   .002,   /*lag_factor*/
-   1.0001, /*lpc_floor*/
-   0.0,    /*preemph*/
+SpeexSubmode wb_submode1 = {
+   0,
    /*LSP quantization*/
    lsp_quant_high,
    lsp_unquant_high,
+   /*Pitch quantization*/
+   NULL,
+   NULL,
+   NULL,
    /*Innovation quantization*/
-   split_cb_search_shape_sign,
-   split_cb_shape_sign_unquant,
-   &split_cb_high
+   split_cb_search_nogain2,
+   split_cb_nogain_unquant,
+   &split_cb_high_lbr,
+   NULL,
+   NULL
 };
 
 
-SpeexMode speex_wb_mode = {
-   &sb_wb_mode,
-   "full-rate wideband (sub-band CELP)",
-   2,
+SpeexSubmode wb_submode2 = {
    0,
-   &sb_encoder_init,
-   &sb_encoder_destroy,
-   &sb_encode,
-   &sb_decoder_init,
-   &sb_decoder_destroy,
-   &sb_decode,
-   &sb_encoder_ctl,
-   &sb_decoder_ctl,
-   320,
-   27350,
-   0
+   /*LSP quantization*/
+   lsp_quant_high,
+   lsp_unquant_high,
+   /*Pitch quantization*/
+   NULL,
+   NULL,
+   NULL,
+   /*Innovation quantization*/
+   split_cb_search_shape_sign,
+   split_cb_shape_sign_unquant,
+   &split_cb_high,
+   NULL,
+   NULL
 };
 
 
-
-
-
 /* Split-band wideband CELP mode*/
-static SpeexSBMode sb_wb_mode_lbr = {
+static SpeexSBMode sb_wb_mode = {
    &speex_nb_mode,
    160,    /*frameSize*/
    40,     /*subframeSize*/
@@ -325,21 +264,16 @@ static SpeexSBMode sb_wb_mode_lbr = {
    .002,   /*lag_factor*/
    1.0001, /*lpc_floor*/
    0.0,    /*preemph*/
-   /*LSP quantization*/
-   lsp_quant_high,
-   lsp_unquant_high,
-   /*Innovation quantization*/
-   split_cb_search_nogain2,
-   split_cb_nogain_unquant,
-   &split_cb_high_lbr
+   {NULL, &wb_submode1, &wb_submode2},
+   2
 };
 
 
-SpeexMode speex_wb_mode_lbr = {
-   &sb_wb_mode_lbr,
-   "low bit-rate wideband (sub-band CELP)",
-   3,
-   0,
+SpeexMode speex_wb_mode = {
+   &sb_wb_mode,
+   "full-rate wideband (sub-band CELP)",
+   1,
+   1,
    &sb_encoder_init,
    &sb_encoder_destroy,
    &sb_encode,
@@ -349,15 +283,12 @@ SpeexMode speex_wb_mode_lbr = {
    &sb_encoder_ctl,
    &sb_decoder_ctl,
    320,
-   20150,
+   27350,
    0
 };
 
 
 
-
-
-
 void *speex_encoder_init(SpeexMode *mode)
 {
    return mode->enc_init(mode);
index 2dceee0..f536308 100644 (file)
 #include "speex.h"
 #include "speex_bits.h"
 
+
+#define NB_SUBMODES 16
+#define NB_SUBMODE_BITS 4
+
+#define SB_SUBMODES 8
+#define SB_SUBMODE_BITS 3
+
+
 /* Quantizes LSPs */
 typedef void (*lsp_quant_func)(float *, float *, int, SpeexBits *);
 
@@ -49,21 +57,8 @@ typedef void (*innovation_unquant_func)(float *, void *, int, SpeexBits*, float
 typedef void (*nb_post_filter_func)(float *, float *, float *, int, int, int, 
                                float *, void *, float *, float *, float *);
 
-/*Struct defining the encoding/decoding mode*/
-typedef struct SpeexNBMode {
-   int     frameSize;
-   int     subframeSize;
-   int     lpcSize;
-   int     bufSize;
-   int     pitchStart;
-   int     pitchEnd;
+typedef struct SpeexSubmode {
    int     lbr_pitch;
-   float   gamma1;
-   float   gamma2;
-   float   lag_factor;
-   float   lpc_floor;
-   float   preemph;
-
    /*LSP functions*/
    lsp_quant_func    lsp_quant;
    lsp_unquant_func  lsp_unquant;
@@ -81,6 +76,27 @@ typedef struct SpeexNBMode {
    /*Post-filter*/
    nb_post_filter_func post_filter_func;
    void             *post_filter_params;
+
+} SpeexSubmode;
+
+/*Struct defining the encoding/decoding mode*/
+typedef struct SpeexNBMode {
+   int     frameSize;
+   int     subframeSize;
+   int     lpcSize;
+   int     bufSize;
+   int     pitchStart;
+   int     pitchEnd;
+
+   float   gamma1;
+   float   gamma2;
+   float   lag_factor;
+   float   lpc_floor;
+   float   preemph;
+
+   SpeexSubmode *submodes[NB_SUBMODES];
+   int     defaultSubmode;
+
 } SpeexNBMode;
 
 
@@ -96,14 +112,9 @@ typedef struct SpeexSBMode {
    float   lag_factor;
    float   lpc_floor;
    float   preemph;
-   /*LSP functions*/
-   lsp_quant_func    lsp_quant;
-   lsp_unquant_func  lsp_unquant;
 
-   /*Quantization of innovation */
-   innovation_quant_func innovation_quant;
-   innovation_unquant_func innovation_unquant;
-   void             *innovation_params;
+   SpeexSubmode *submodes[SB_SUBMODES];
+   int     defaultSubmode;
 
 } SpeexSBMode;
 
index 2ff8f71..fd1a5c1 100644 (file)
@@ -36,6 +36,8 @@
 #define M_PI           3.14159265358979323846  /* pi */
 #endif
 
+#define SUBMODE(x) st->submodes[st->submodeID]->x
+
 /*float exc_gain_quant_scal[8]={-1.24094, -0.439969, -0.66471,  0.371277, -1.90821, -0.213486, -0.908305, 0.0211083};*/
 
 float exc_gain_quant_scal[8]={-2.794750, -1.810660, -1.169850, -0.848119, -0.587190, -0.329818, -0.063266, 0.282826};
@@ -65,18 +67,12 @@ void *nb_encoder_init(SpeexMode *m)
    st->gamma2=mode->gamma2;
    st->min_pitch=mode->pitchStart;
    st->max_pitch=mode->pitchEnd;
-   st->lbr_pitch=mode->lbr_pitch;
    st->lag_factor=mode->lag_factor;
    st->lpc_floor = mode->lpc_floor;
    st->preemph = mode->preemph;
   
-
-   st->lsp_quant = mode->lsp_quant;
-   st->ltp_quant = mode->ltp_quant;
-   st->ltp_params = mode->ltp_params;
-   st->innovation_quant = mode->innovation_quant;
-   st->innovation_params = mode->innovation_params;
-
+   st->submodes=mode->submodes;
+   st->submodeID=mode->defaultSubmode;
    st->pre_mem=0;
    st->pre_mem2=0;
 
@@ -183,6 +179,9 @@ void nb_encode(void *state, float *in, SpeexBits *bits)
    float ol_gain;
 
    st=state;
+
+   speex_bits_pack(bits, st->submodeID, NB_SUBMODE_BITS);
+
    /* Copy new data in input buffer */
    memmove(st->inBuf, st->inBuf+st->frameSize, (st->bufSize-st->frameSize)*sizeof(float));
    st->inBuf[st->bufSize-st->frameSize] = in[0] - st->preemph*st->pre_mem;
@@ -225,7 +224,7 @@ void nb_encode(void *state, float *in, SpeexBits *bits)
    /*print_vec(st->lsp, 10, "LSP:");*/
    /* LSP Quantization */
 #if 1
-   st->lsp_quant(st->lsp, st->qlsp, st->lpcSize, bits);
+   SUBMODE(lsp_quant)(st->lsp, st->qlsp, st->lpcSize, bits);
 #else
    for (i=0;i<st->lpcSize;i++)
      st->qlsp[i]=st->lsp[i];
@@ -266,7 +265,7 @@ void nb_encode(void *state, float *in, SpeexBits *bits)
       residue(st->frame, st->bw_lpc1, st->exc, st->frameSize, st->lpcSize);
       syn_filt(st->exc, st->bw_lpc2, st->sw, st->frameSize, st->lpcSize);
       
-      if (st->lbr_pitch)
+      if (SUBMODE(lbr_pitch))
       {
          open_loop_nbest_pitch(st->sw, st->min_pitch, st->max_pitch, st->frameSize, &ol_pitch, 1, st->stack);
          speex_bits_pack(bits, ol_pitch-st->min_pitch, 7);
@@ -420,19 +419,19 @@ void nb_encode(void *state, float *in, SpeexBits *bits)
          exc[i]=0;
 
       /* Long-term prediction */
-      if (st->lbr_pitch)
+      if (SUBMODE(lbr_pitch))
       {
          int pit_min, pit_max;
          if (ol_pitch < st->min_pitch+7)
             ol_pitch=st->min_pitch+7;
          pit_min = ol_pitch-7;
          pit_max = ol_pitch+8;
-         pitch = st->ltp_quant(target, sw, st->interp_qlpc, st->bw_lpc1, st->bw_lpc2,
-                               exc, st->ltp_params, pit_min, pit_max, 
+         pitch = SUBMODE(ltp_quant)(target, sw, st->interp_qlpc, st->bw_lpc1, st->bw_lpc2,
+                               exc, SUBMODE(ltp_params), pit_min, pit_max, 
                                st->lpcSize, st->subframeSize, bits, st->stack, exc2);
       } else
-         pitch = st->ltp_quant(target, sw, st->interp_qlpc, st->bw_lpc1, st->bw_lpc2,
-                               exc, st->ltp_params, st->min_pitch, st->max_pitch, 
+         pitch = SUBMODE(ltp_quant)(target, sw, st->interp_qlpc, st->bw_lpc1, st->bw_lpc2,
+                               exc, SUBMODE(ltp_params), st->min_pitch, st->max_pitch, 
                                st->lpcSize, st->subframeSize, bits, st->stack, exc2);
       /*printf ("cl_pitch: %d\n", pitch);*/
       st->pitch[sub]=pitch;
@@ -498,8 +497,8 @@ void nb_encode(void *state, float *in, SpeexBits *bits)
       if (0)
       {
       /* Perform innovation search */
-      st->innovation_quant(target, st->interp_qlpc, st->bw_lpc1, st->bw_lpc2,
-                           st->innovation_params, st->lpcSize,
+      SUBMODE(innovation_quant)(target, st->interp_qlpc, st->bw_lpc1, st->bw_lpc2,
+                           SUBMODE(innovation_params), st->lpcSize,
                            st->subframeSize, exc, bits, st->stack);
       }
       else
@@ -541,8 +540,8 @@ void nb_encode(void *state, float *in, SpeexBits *bits)
          for (i=0;i<st->subframeSize;i++)
             target[i]*=ener_1;
 #if 1
-         st->innovation_quant(target, st->interp_qlpc, st->bw_lpc1, st->bw_lpc2, 
-                                st->innovation_params, st->lpcSize, st->subframeSize, 
+         SUBMODE(innovation_quant)(target, st->interp_qlpc, st->bw_lpc1, st->bw_lpc2, 
+                                SUBMODE(innovation_params), st->lpcSize, st->subframeSize, 
                                 innov, bits, st->stack);
          
          for (i=0;i<st->subframeSize;i++)
@@ -640,19 +639,12 @@ void *nb_decoder_init(SpeexMode *m)
    st->gamma2=mode->gamma2;
    st->min_pitch=mode->pitchStart;
    st->max_pitch=mode->pitchEnd;
-   st->lbr_pitch=mode->lbr_pitch;
    st->preemph = mode->preemph;
 
-   st->pre_mem=0;
-   st->lsp_unquant = mode->lsp_unquant;
-   st->ltp_unquant = mode->ltp_unquant;
-   st->ltp_params = mode->ltp_params;
-
-   st->innovation_unquant = mode->innovation_unquant;
-   st->innovation_params = mode->innovation_params;
+   st->submodes=mode->submodes;
+   st->submodeID=mode->defaultSubmode;
 
-   st->post_filter_func = mode->post_filter_func;
-   st->post_filter_params = mode->post_filter_params;
+   st->pre_mem=0;
    st->pf_enabled=0;
 
    st->stack = calloc(10000, sizeof(float));
@@ -716,19 +708,21 @@ void nb_decode(void *state, SpeexBits *bits, float *out, int lost)
    float best_pitch_gain=-1;
    st=state;
 
+   st->submodeID = speex_bits_unpack_unsigned(bits, NB_SUBMODE_BITS);
+
    memmove(st->inBuf, st->inBuf+st->frameSize, (st->bufSize-st->frameSize)*sizeof(float));
    memmove(st->excBuf, st->excBuf+st->frameSize, (st->bufSize-st->frameSize)*sizeof(float));
    memmove(st->exc2Buf, st->exc2Buf+st->frameSize, (st->bufSize-st->frameSize)*sizeof(float));
 
 
-   st->lsp_unquant(st->qlsp, st->lpcSize, bits);
+   SUBMODE(lsp_unquant)(st->qlsp, st->lpcSize, bits);
    if (st->first || st->count_lost)
    {
       for (i=0;i<st->lpcSize;i++)
          st->old_qlsp[i] = st->qlsp[i];
    }
 
-   if (st->lbr_pitch)
+   if (SUBMODE(lbr_pitch))
       ol_pitch = st->min_pitch+speex_bits_unpack_unsigned(bits, 7);
    
    {
@@ -780,16 +774,16 @@ void nb_decode(void *state, SpeexBits *bits, float *out, int lost)
          exc[i]=0;
 
       /*Adaptive codebook contribution*/
-      if (st->lbr_pitch)
+      if (SUBMODE(lbr_pitch))
       {
          int pit_min, pit_max;
          if (ol_pitch < st->min_pitch+7)
             ol_pitch=st->min_pitch+7;
          pit_min = ol_pitch-7;
          pit_max = ol_pitch+8;
-         st->ltp_unquant(exc, pit_min, pit_max, st->ltp_params, st->subframeSize, &pitch, &pitch_gain[0], bits, st->stack, 0);
+         SUBMODE(ltp_unquant)(exc, pit_min, pit_max, SUBMODE(ltp_params), st->subframeSize, &pitch, &pitch_gain[0], bits, st->stack, 0);
       } else {
-         st->ltp_unquant(exc, st->min_pitch, st->max_pitch, st->ltp_params, st->subframeSize, &pitch, &pitch_gain[0], bits, st->stack, 0);
+         SUBMODE(ltp_unquant)(exc, st->min_pitch, st->max_pitch, SUBMODE(ltp_params), st->subframeSize, &pitch, &pitch_gain[0], bits, st->stack, 0);
       }
 
       if (!lost)
@@ -833,7 +827,7 @@ void nb_decode(void *state, SpeexBits *bits, float *out, int lost)
          /*printf ("unquant_energy: %d %f\n", q_energy, ener);*/
          
          /*Fixed codebook contribution*/
-         st->innovation_unquant(innov, st->innovation_params, st->subframeSize, bits, st->stack);
+         SUBMODE(innovation_unquant)(innov, SUBMODE(innovation_params), st->subframeSize, bits, st->stack);
 
          if (st->count_lost)
             ener*=pow(.8,st->count_lost);
@@ -855,8 +849,8 @@ void nb_decode(void *state, SpeexBits *bits, float *out, int lost)
                               pitch, pitch_gain, st->post_filter_params, st->mem_pf, st->stack);
 #else
       if (st->pf_enabled)
-         st->post_filter_func(exc, exc2, st->interp_qlpc, st->lpcSize, st->subframeSize,
-                              pitch, pitch_gain, st->post_filter_params, st->mem_pf, 
+         SUBMODE(post_filter_func)(exc, exc2, st->interp_qlpc, st->lpcSize, st->subframeSize,
+                              pitch, pitch_gain, SUBMODE(post_filter_params), st->mem_pf, 
                               st->mem_pf2, st->stack);
       
       syn_filt_mem(exc2, st->interp_qlpc, sp, st->subframeSize, st->lpcSize, st->mem_sp);
@@ -902,6 +896,22 @@ void nb_encoder_ctl(void *state, int request, void *ptr)
    case SPEEX_GET_FRAME_SIZE:
       (*(int*)ptr) = st->frameSize;
       break;
+   case SPEEX_SET_MODE:
+      st->submodeID = (*(int*)ptr);
+      break;
+   case SPEEX_SET_QUALITY:
+      {
+         int quality = (*(int*)ptr);
+         if (quality<5)
+            st->submodeID = 1;
+         else if (quality<=8)
+            st->submodeID = 2;
+         else if (quality<=10)
+            st->submodeID = 3;
+         else
+            fprintf(stderr, "Unknown nb_ctl quality: %d\n", quality);
+      }
+      break;
    default:
       fprintf(stderr, "Unknown nb_ctl request: %d\n", request);
    }
@@ -910,7 +920,7 @@ void nb_encoder_ctl(void *state, int request, void *ptr)
 void nb_decoder_ctl(void *state, int request, void *ptr)
 {
    DecState *st;
-   st=state;     
+   st=state;
    switch(request)
    {
    case SPEEX_SET_PF:
index 13ec2ea..a3634f2 100644 (file)
@@ -35,7 +35,7 @@ typedef struct EncState {
    int    bufSize;        /* Buffer size */
    int    min_pitch;      /* Minimum pitch value allowed */
    int    max_pitch;      /* Maximum pitch value allowed */
-   int    lbr_pitch;      /* Forces pitch to be within +-7 samples of open-loop pitch*/
+
    int    ol_pitch;       /* Open-loop pitch */
    int    ol_voiced;      /* Open-loop voiced/non-voiced decision */
    int   *pitch;
@@ -75,11 +75,8 @@ typedef struct EncState {
    float *dmem1, *dmem2;
    float *pi_gain;
 
-   lsp_quant_func    lsp_quant;
-   ltp_quant_func    ltp_quant;
-   void             *ltp_params;
-   innovation_quant_func innovation_quant;
-   void             *innovation_params;
+   SpeexSubmode **submodes;
+   int    submodeID;
 } EncState;
 
 /**Structure representing the full state of the narrowband decoder*/
@@ -95,7 +92,7 @@ typedef struct DecState {
    int    bufSize;        /* Buffer size */
    int    min_pitch;      /* Minimum pitch value allowed */
    int    max_pitch;      /* Maximum pitch value allowed */
-   int    lbr_pitch;      /* Forces pitch to be within +-7 samples of open-loop pitch*/
+
    float  gamma1;         /* Perceptual filter: A(z/gamma1) */
    float  gamma2;         /* Perceptual filter: A(z/gamma2) */
    float  preemph;        /* Pre-emphasis: P(z) = 1 - a*z^-1*/
@@ -118,14 +115,9 @@ typedef struct DecState {
    int    last_pitch;
    float  last_pitch_gain;
 
-   lsp_unquant_func  lsp_unquant;
-   ltp_unquant_func  ltp_unquant;
-   void             *ltp_params;
-   innovation_unquant_func innovation_unquant;
-   void             *innovation_params;
-   nb_post_filter_func post_filter_func;
-   void             *post_filter_params;
-   int               pf_enabled;
+   SpeexSubmode **submodes;
+   int    submodeID;
+   int    pf_enabled;
 } DecState;
 
 /**Initializes encoder state*/
index e104532..7484b13 100644 (file)
@@ -39,6 +39,8 @@
 
 #define sqr(x) ((x)*(x))
 
+#define SUBMODE(x) st->submodes[st->submodeID]->x
+
 
 #if 0
 #define QMF_ORDER 32
@@ -171,6 +173,13 @@ void *sb_encoder_init(SpeexMode *m)
    st->lpcSize=mode->lpcSize;
    st->bufSize=mode->bufSize;
 
+   st->submodes=mode->submodes;
+   st->submodeID=mode->defaultSubmode;
+   {
+      int mod=3;
+      speex_encoder_ctl(st->st_low, SPEEX_SET_MODE, &mod);
+   }
+
    st->lag_factor = mode->lag_factor;
    st->lpc_floor = mode->lpc_floor;
    st->gamma1=mode->gamma1;
@@ -233,9 +242,7 @@ void *sb_encoder_init(SpeexMode *m)
    st->mem_sp2 = calloc(st->lpcSize, sizeof(float));
    st->mem_sw = calloc(st->lpcSize, sizeof(float));
 
-   st->lsp_quant = mode->lsp_quant;
-   st->innovation_quant = mode->innovation_quant;
-   st->innovation_params = mode->innovation_params;
+
    return st;
 }
 
@@ -306,6 +313,8 @@ 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, st->submodeID, SB_SUBMODE_BITS);
+
    /* High-band buffering / sync with low band */
 #if 0
    for (i=0;i<st->frame_size;i++)
@@ -354,7 +363,7 @@ void sb_encode(void *state, float *in, SpeexBits *bits)
       st->lsp[i] = acos(st->lsp[i]);
 
    /* LSP quantization */
-   st->lsp_quant(st->lsp, st->qlsp, st->lpcSize, bits);
+   SUBMODE(lsp_quant)(st->lsp, st->qlsp, st->lpcSize, bits);
    
    /*printf ("high_lsp:");
    for (i=0;i<st->lpcSize;i++)
@@ -574,8 +583,8 @@ void sb_encode(void *state, float *in, SpeexBits *bits)
             innov[i]=0;
 
          /*print_vec(target, st->subframeSize, "\ntarget");*/
-         st->innovation_quant(target, st->interp_qlpc, st->bw_lpc1, st->bw_lpc2, 
-                                st->innovation_params, st->lpcSize, st->subframeSize, 
+         SUBMODE(innovation_quant)(target, st->interp_qlpc, st->bw_lpc1, st->bw_lpc2, 
+                                SUBMODE(innovation_params), st->lpcSize, st->subframeSize, 
                                 innov, bits, st->stack);
          /*print_vec(target, st->subframeSize, "after");*/
 
@@ -656,6 +665,9 @@ void *sb_decoder_init(SpeexMode *m)
    st->pf_order=15;
    st->pf_gamma=.05;
 
+   st->submodes=mode->submodes;
+   st->submodeID=mode->defaultSubmode;
+
    st->first=1;
    st->stack = calloc(10000, sizeof(float));
 
@@ -691,9 +703,6 @@ void *sb_decoder_init(SpeexMode *m)
    st->mem_pf_exc2 = calloc(st->pf_order, sizeof(float));
    st->mem_pf_sp = calloc(st->pf_order, sizeof(float));
 
-   st->lsp_unquant = mode->lsp_unquant;
-   st->innovation_unquant = mode->innovation_unquant;
-   st->innovation_params = mode->innovation_params;
    return st;
 }
 
@@ -745,10 +754,12 @@ void sb_decode(void *state, SpeexBits *bits, float *out, int lost)
    /* Decode the low-band */
    nb_decode(st->st_low, bits, st->x0d, lost);
 
+   st->submodeID = speex_bits_unpack_unsigned(bits, SB_SUBMODE_BITS);
+
    for (i=0;i<st->frame_size;i++)
       st->exc[i]=0;
 
-   st->lsp_unquant(st->qlsp, st->lpcSize, bits);
+   SUBMODE(lsp_unquant)(st->qlsp, st->lpcSize, bits);
    
    if (st->first)
    {
@@ -821,7 +832,7 @@ void sb_decode(void *state, SpeexBits *bits, float *out, int lost)
          scale = gc*sqrt(1+el)/filter_ratio;
 
 
-         st->innovation_unquant(exc, st->innovation_params, st->subframeSize, 
+         SUBMODE(innovation_unquant)(exc, SUBMODE(innovation_params), st->subframeSize, 
                                 bits, st->stack);
          for (i=0;i<st->subframeSize;i++)
             exc[i]*=scale;
@@ -904,6 +915,30 @@ void sb_encoder_ctl(void *state, int request, void *ptr)
    case SPEEX_GET_FRAME_SIZE:
       (*(int*)ptr) = st->full_frame_size;
       break;
+   case SPEEX_SET_HIGH_MODE:
+      st->submodeID = (*(int*)ptr);
+      break;
+   case SPEEX_SET_LOW_MODE:
+      speex_encoder_ctl(st->st_low, SPEEX_SET_MODE, ptr);
+      break;
+   case SPEEX_SET_QUALITY:
+      {
+         int tmp;
+         int quality = (*(int*)ptr);
+         if (quality<5)
+         {
+            st->submodeID = 1;
+            tmp=2;
+            speex_encoder_ctl(st->st_low, SPEEX_SET_MODE, &tmp);
+         } else if (quality<=10)
+         {
+            st->submodeID = 2;
+            tmp=3;
+            speex_encoder_ctl(st->st_low, SPEEX_SET_MODE, &tmp);
+         } else
+            fprintf(stderr, "Unknown sb_ctl quality: %d\n", quality);
+      }
+      break;
    default:
       fprintf(stderr, "Unknown nb_ctl request: %d\n", request);
    }
@@ -923,7 +958,7 @@ void sb_decoder_ctl(void *state, int request, void *ptr)
       speex_decoder_ctl(st->st_low, request, ptr);
       break;
    default:
-      fprintf(stderr, "Unknown nb_ctl request: %d\n", request);
+      fprintf(stderr, "Unknown sb_ctl request: %d\n", request);
    }
 
 }
index 839d37c..745c5bc 100644 (file)
@@ -73,9 +73,8 @@ typedef struct SBEncState {
    float *mem_sp2;
    float *mem_sw;              /* Perceptual signal memory */
 
-   lsp_quant_func    lsp_quant;
-   innovation_quant_func innovation_quant;
-   void             *innovation_params;
+   SpeexSubmode **submodes;
+   int    submodeID;
 } SBEncState;
 
 
@@ -114,9 +113,8 @@ typedef struct SBDecState {
    float *mem_pf_exc2;
    float *mem_pf_sp;
 
-   lsp_unquant_func  lsp_unquant;
-   innovation_unquant_func innovation_unquant;
-   void             *innovation_params;
+   SpeexSubmode **submodes;
+   int    submodeID;
 } SBDecState;
 
 
index cc94d95..3d35a42 100644 (file)
 extern "C" {
 #endif
 
+/*values for *ctl() requests*/
 #define SPEEX_SET_PF 0
 #define SPEEX_GET_PF 1
+/*Would be SPEEX_SET_FRAME_SIZE, but it's (currently) invalid*/
 #define SPEEX_GET_FRAME_SIZE 3
+#define SPEEX_SET_QUALITY 4
+#define SPEEX_GET_QUALITY 5
+#define SPEEX_SET_MODE 6
+#define SPEEX_GET_MODE 7
+#define SPEEX_SET_LOW_MODE 8
+#define SPEEX_GET_LOW_MODE 9
+#define SPEEX_SET_HIGH_MODE 10
+#define SPEEX_GET_HIGH_MODE 11
+
+
+#define SPEEX_NB_MODES 2
+
 
 struct SpeexMode;
 
@@ -129,16 +143,10 @@ void speex_decoder_ctl(void *state, int request, void *ptr);
 /** Default narrowband mode */
 extern SpeexMode speex_nb_mode;
 
-/** Low bit-rate narrowband mode */
-extern SpeexMode speex_nb_lbr_mode;
-
 /** Default wideband mode */
 extern SpeexMode speex_wb_mode;
 
-/** Low bit-rate wideband mode */
-extern SpeexMode speex_wb_mode_lbr;
-
-extern SpeexMode *speex_mode_list[];
+extern SpeexMode *speex_mode_list[SPEEX_NB_MODES];
 
 #ifdef __cplusplus
 }
index 4a86ee7..167c59e 100644 (file)
@@ -20,8 +20,8 @@ int main(int argc, char **argv)
 
    for (i=0;i<FRAME_SIZE;i++)
       bak2[i]=0;
-   st = speex_encoder_init(&speex_nb_lbr_mode);
-   dec = speex_decoder_init(&speex_nb_lbr_mode);
+   st = speex_encoder_init(&speex_nb_mode);
+   dec = speex_decoder_init(&speex_nb_mode);
 
    pf=0;
    speex_decoder_ctl(dec, SPEEX_SET_PF, &pf);
index 32b1939..6fa6a75 100644 (file)
@@ -23,7 +23,7 @@ int main(int argc, char **argv)
    st = speex_encoder_init(&speex_wb_mode);
    dec = speex_decoder_init(&speex_wb_mode);
 
-   pf=1;
+   pf=0;
    speex_decoder_ctl(dec, SPEEX_SET_PF, &pf);
 
    if (argc != 4 && argc != 3)
index 223b1eb..7916187 100644 (file)
@@ -127,6 +127,13 @@ static void *process_header(ogg_packet *op, int pf_enabled, int *frame_size, int
       fprintf (stderr, "Cannot read header\n");
       return NULL;
    }
+   if (header->mode >= SPEEX_NB_MODES)
+   {
+      fprintf (stderr, "Mode number %d does not (any longer) exist in this version\n", 
+               header->mode);
+      return NULL;
+   }
+      
    mode = speex_mode_list[header->mode];
    
    if (mode->bitstream_version < header->mode_bitstream_version)
index c9f04b5..abd18f6 100644 (file)
@@ -196,19 +196,13 @@ int main(int argc, char **argv)
    {
       if (!rate)
          rate = 8000;
-      if (lbr)
-         mode=&speex_nb_lbr_mode;
-      else
-         mode=&speex_nb_mode;
+      mode=&speex_nb_mode;
    }
    if (wideband)
    {
       if (!rate)
          rate = 16000;
-      if (lbr)
-         mode=&speex_wb_mode_lbr;
-      else
-         mode=&speex_wb_mode;
+      mode=&speex_wb_mode;
    }
 
    speex_init_header(&header, rate, 1, mode);
@@ -273,7 +267,11 @@ int main(int argc, char **argv)
    }
 
    speex_encoder_ctl(st, SPEEX_GET_FRAME_SIZE, &frame_size);
-
+   if (lbr)
+   {
+      int tmp=3;
+      speex_encoder_ctl(st, SPEEX_SET_QUALITY, &tmp);
+   }
    /*Main encoding loop (one frame per iteration)*/
    while (1)
    {