Added low bit-rate (8 kbps) narrowband mode. It is still sub-optimal but
authorjmvalin <jmvalin@0101bb08-14d6-0310-b084-bc0e0c8e3800>
Tue, 11 Jun 2002 06:08:31 +0000 (06:08 +0000)
committerjmvalin <jmvalin@0101bb08-14d6-0310-b084-bc0e0c8e3800>
Tue, 11 Jun 2002 06:08:31 +0000 (06:08 +0000)
at least it seems to work...

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

12 files changed:
libspeex/Makefile.am
libspeex/exc_10_32_table.c [new file with mode: 0644]
libspeex/ltp.c
libspeex/ltp.h
libspeex/modes.c
libspeex/modes.h
libspeex/nb_celp.c
libspeex/nb_celp.h
libspeex/quant_lsp.c
libspeex/quant_lsp.h
libspeex/speex.h
libspeex/speex_header.h

index ccead19..1747538 100644 (file)
@@ -1,6 +1,6 @@
 ## Process this file with automake to produce Makefile.in. -*-Makefile-*-
 
-# $Id: Makefile.am,v 1.30 2002/06/05 06:07:18 jmvalin Exp $
+# $Id: Makefile.am,v 1.31 2002/06/11 06:08:31 jmvalin Exp $
 
 # Disable automatic dependency tracking if using other tools than gcc and gmake
 #AUTOMAKE_OPTIONS = no-dependencies
@@ -27,6 +27,7 @@ libspeex_la_SOURCES = nb_celp.c \
        hexc_table.c \
        exc_5_256_table.c \
        exc_5_64_table.c \
+       exc_10_32_table.c \
        post_filter.c
 
 
diff --git a/libspeex/exc_10_32_table.c b/libspeex/exc_10_32_table.c
new file mode 100644 (file)
index 0000000..357c2de
--- /dev/null
@@ -0,0 +1,32 @@
+float exc_10_32_table[32][10]={{-0.0650833,-0.0127175,0.15243,0.412487,0.70276,0.648247,0.239389,-0.481389,-0.971266,-0.782175},
+{0.823255,-1.38751,1.46535,-0.74324,-0.0729989,0.310202,-0.346112,0.364435,-0.304743,0.208398},
+{0.925485,-1.02196,0.269,0.67272,-0.984351,0.76207,-0.315047,-0.121744,0.192334,-0.135836},
+{-0.629032,0.849876,-0.951448,0.75439,-0.0329939,-0.700964,0.876844,-0.690453,0.564513,-0.394044},
+{-0.0417819,0.0446498,-0.0210186,-0.0319054,0.0492155,0.1814,-0.984497,1.96363,-1.62843,0.480187},
+{0.159291,-0.155808,0.0397108,-0.287783,1.25157,-1.71232,0.555061,0.704883,-0.61184,0.117399},
+{-1.01205,1.80694,-1.64157,0.683777,-0.2295,0.290442,-0.276946,0.204107,-0.201362,0.218884},
+{0.112654,-0.132651,0.129492,-0.152157,0.204945,-0.22453,0.357274,-1.04578,1.98288,-1.84874},
+{0.184115,0.246724,0.0753163,-0.120653,-0.487387,-0.594183,-0.528711,0.138581,0.767295,1.22995},
+{1.29268,0.594388,-0.236972,-0.532,-0.266004,-0.106981,0.0568159,-0.0222551,-0.0831287,-0.190151},
+{-0.805679,0.964487,-1.1675,1.3281,-1.24135,0.999758,-0.941164,0.922136,-0.852255,0.737061},
+{0.842752,-1.21308,1.49299,-1.42549,1.18894,-0.959532,0.85528,-0.747771,0.658172,-0.60694},
+{-0.0532811,0.0787138,-0.122763,0.0329663,0.0427411,0.62878,-1.74116,1.22109,0.365764,-0.678148},
+{-0.750448,0.1252,1.27873,-0.747464,-0.640997,0.404841,0.321208,-0.277069,0.00380886,0.0361227},
+{-0.13398,0.245071,-0.162342,0.107937,-0.156469,0.127712,-0.155854,0.195145,-0.279554,0.167991},
+{-0.685915,-0.434041,0.461219,0.814491,0.437365,-0.364736,-0.672887,-0.323771,0.129575,0.252148},
+{-0.0659221,-0.517433,0.366341,0.833583,-0.913421,-0.695998,0.86603,0.531177,-0.508925,-0.271964},
+{1.82897,-1.59782,0.343249,-0.138259,0.449941,-0.40065,0.239173,-0.244677,0.276439,-0.223304},
+{0.694612,0.0273125,-1.50751,1.27622,0.0148847,-0.186515,-0.237778,0.238604,-0.105283,0.086892},
+{0.120101,-0.100098,0.0237457,0.117561,-0.298729,0.0549176,1.04098,-2.00316,1.27185,-0.112897},
+{-0.0732836,0.0706076,-0.115325,0.116897,-0.150037,0.2285,-0.2878,0.602568,-1.58479,2.02217},
+{-0.624569,0.9511,-0.225748,-1.10234,1.34359,-0.63785,0.280883,-0.271444,0.297317,-0.208585},
+{-1.78726,1.12847,-0.0442747,0.113599,-0.219116,0.180292,-0.164597,0.294796,-0.309492,0.168715},
+{-0.0954666,0.0746028,-0.0196098,0.0594211,-0.132036,0.0351186,-0.063248,0.438139,0.525251,-1.87477},
+{0.101718,-0.0828372,0.0866638,-0.183715,0.168252,-0.419872,1.08406,-0.856321,-0.747,1.31035},
+{0.351146,-0.394581,0.404593,-0.339666,0.374607,-0.414098,0.334761,-0.347885,0.425438,-0.3967},
+{-0.313345,0.482818,-0.688464,1.27194,-1.67114,1.07701,-0.103382,-0.330088,0.33062,-0.195219},
+{0.0849411,-0.132119,0.249548,-0.495836,1.01882,-1.67923,1.85051,-1.34076,0.829642,-0.600037},
+{0.0469392,-0.046845,-0.00332371,0.376391,-1.20727,1.81952,-1.56888,0.962301,-0.75061,0.623107},
+{0.0976541,-0.35783,1.01755,-1.62301,1.29225,-0.187937,-0.467274,0.421445,-0.350532,0.296101},
+{0.0348442,0.380331,-0.245299,-0.615952,0.252616,1.18765,-0.809042,-0.743674,0.575318,0.253249},
+{-0.592265,-0.797179,-0.715578,-0.374579,0.0758649,0.412432,0.568196,0.618405,0.448291,0.250063}};
index e1587bb..48dd829 100644 (file)
@@ -28,7 +28,7 @@
 #define abs(x) ((x)<0 ? -(x) : (x))
 
 
-static void open_loop_nbest_pitch(float *sw, int start, int end, int len, int *pitch, int N, float *stack)
+void open_loop_nbest_pitch(float *sw, int start, int end, int len, int *pitch, int N, float *stack)
 {
    int i,j,k;
    float corr;
index 03eb6bd..24143b6 100644 (file)
@@ -27,6 +27,8 @@ typedef struct ltp_params {
 } ltp_params;
 
 
+void open_loop_nbest_pitch(float *sw, int start, int end, int len, int *pitch, int N, float *stack);
+
 
 /** Finds the best quantized 3-tap pitch predictor by analysis by synthesis */
 int pitch_search_3tap(
index 3859413..e2bf358 100644 (file)
@@ -33,6 +33,7 @@ extern float gain_cdbk_nb[];
 extern float hexc_table[];
 extern float exc_5_256_table[];
 extern float exc_5_64_table[];
+extern float exc_10_32_table[];
 
 /* Post-filter parameters for narrowband */
 pf_params pf_params_nb = {
@@ -55,7 +56,23 @@ ltp_params ltp_params_nb = {
    7
 };
 
-/* Split-VQ innovation parameters */
+/* Parameters for Long-Term Prediction (LTP)*/
+ltp_params ltp_params_lbr = {
+   gain_cdbk_nb,
+   5,
+   4
+};
+
+/* Split-VQ innovation parameters for low bit-rate narrowband */
+split_cb_params split_cb_nb_lbr = {
+   10,               /*subvect_size*/
+   4,               /*nb_subvect*/
+   exc_10_32_table, /*shape_cb*/
+   5,               /*shape_bits*/
+};
+
+
+/* Split-VQ innovation parameters narrowband */
 split_cb_params split_cb_nb = {
    5,               /*subvect_size*/
    8,               /*nb_subvect*/
@@ -63,6 +80,7 @@ split_cb_params split_cb_nb = {
    6,               /*shape_bits*/
 };
 
+/* Split-VQ innovation for low-band wideband */
 split_cb_params split_cb_sb = {
    5,               /*subvect_size*/
    8,              /*nb_subvect*/
@@ -70,6 +88,7 @@ split_cb_params split_cb_sb = {
    8,               /*shape_bits*/
 };
 
+/* Split-VQ innovation for high-band wideband */
 static split_cb_params split_cb_high = {
    8,               /*subvect_size*/
    5,               /*nb_subvect*/
@@ -86,6 +105,7 @@ SpeexNBMode nb_mode = {
    640,    /*bufSize*/
    17,     /*pitchStart*/
    144,    /*pitchEnd*/
+   0,      /*lbr_pitch*/
    0.9,    /*gamma1*/
    0.6,    /*gamma2*/
    .005,   /*lag_factor*/
@@ -106,6 +126,39 @@ SpeexNBMode nb_mode = {
    &pf_params_nb
 };
 
+
+/* Default mode for narrowband */
+SpeexNBMode nb_lbr_mode = {
+   160,    /*frameSize*/
+   40,     /*subframeSize*/
+   320,    /*windowSize*/
+   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*/
+   /*LSP quantization*/
+   lsp_quant_lbr,
+   lsp_unquant_lbr,
+   /*Pitch quantization*/
+   pitch_search_3tap,
+   pitch_unquant_3tap,
+   &ltp_params_lbr,
+   /*Innovation quantization*/
+   split_cb_search_nogain2,
+   split_cb_nogain_unquant,
+   &split_cb_nb_lbr,
+   nb_post_filter,
+   &pf_params_nb
+};
+
+
+
 /* Narrowband mode used for split-band wideband CELP*/
 static SpeexNBMode low_sb_mode = {
    160,    /*frameSize*/
@@ -115,6 +168,7 @@ static SpeexNBMode low_sb_mode = {
    640,    /*bufSize*/
    17,     /*pitchStart*/
    144,    /*pitchEnd*/
+   0,      /*lbr_pitch*/
    .9,    /*gamma1*/
    0.6,    /*gamma2*/
    .002,   /*lag_factor*/
@@ -159,6 +213,18 @@ SpeexMode speex_nb_mode = {
    &nb_decoder_ctl,
 };
 
+SpeexMode speex_nb_lbr_mode = {
+   &nb_lbr_mode,
+   &nb_encoder_init,
+   &nb_encoder_destroy,
+   &nb_encode,
+   &nb_decoder_init,
+   &nb_decoder_destroy,
+   &nb_decode,
+   &nb_encoder_ctl,
+   &nb_decoder_ctl,
+};
+
 /* Split-band wideband CELP mode*/
 static SpeexSBMode sb_wb_mode = {
    &low_wb_mode,
index f0f8c3a..f469e44 100644 (file)
@@ -58,6 +58,7 @@ typedef struct SpeexNBMode {
    int     bufSize;
    int     pitchStart;
    int     pitchEnd;
+   int     lbr_pitch;
    float   gamma1;
    float   gamma2;
    float   lag_factor;
index 6281617..aa9f1d9 100644 (file)
 #define M_PI           3.14159265358979323846  /* pi */
 #endif
 
+/*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};
+
+float exc_gain_quant_scal16[16]={-2.941970,  -2.375000,  -1.918470,  -1.546230,  -1.266590,  -1.073730,  -0.916557, -0.777102,  -0.648242,  -0.521670,  -0.394253,  -0.265417,  -0.127491,  0.015092,  0.198158,   0.470588};
 
 #define sqr(x) ((x)*(x))
 #define min(a,b) ((a) < (b) ? (a) : (b))
@@ -60,6 +65,7 @@ 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;
@@ -167,7 +173,9 @@ void nb_encode(void *state, float *in, SpeexBits *bits)
    EncState *st;
    int i, sub, roots;
    float error;
-   
+   int ol_pitch;
+   float ol_gain;
+
    st=state;
    /* Copy new data in input buffer */
    memmove(st->inBuf, st->inBuf+st->frameSize, (st->bufSize-st->frameSize)*sizeof(float));
@@ -233,6 +241,51 @@ void nb_encode(void *state, float *in, SpeexBits *bits)
          st->old_qlsp[i] = st->qlsp[i];
    }
 
+
+   /* Whole frame analysis */
+   {
+      for (i=0;i<st->lpcSize;i++)
+         st->interp_lsp[i] = .5*st->old_lsp[i] + .5*st->lsp[i];
+
+      lsp_enforce_margin(st->interp_lsp, st->lpcSize, .002);
+
+      /* Compute interpolated LPCs (unquantized) */
+      for (i=0;i<st->lpcSize;i++)
+         st->interp_lsp[i] = cos(st->interp_lsp[i]);
+      lsp_to_lpc(st->interp_lsp, st->interp_lpc, st->lpcSize,st->stack);
+
+      bw_lpc(st->gamma1, st->interp_lpc, st->bw_lpc1, st->lpcSize);
+      bw_lpc(st->gamma2, st->interp_lpc, st->bw_lpc2, st->lpcSize);
+
+      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);
+      
+      open_loop_nbest_pitch(st->sw, st->min_pitch, st->max_pitch, st->frameSize, &ol_pitch, 1, st->stack);
+      printf ("ol_pitch: %d\n", ol_pitch);
+      if (st->lbr_pitch)
+         speex_bits_pack(bits, ol_pitch-st->min_pitch, 7);
+
+      residue(st->frame, st->interp_lpc, st->exc, st->frameSize, st->lpcSize);
+      
+      ol_gain=0;
+      for (i=0;i<st->frameSize;i++)
+         ol_gain += st->exc[i]*st->exc[i];
+      
+      ol_gain=sqrt(1+ol_gain/st->frameSize);
+
+      printf ("ol_gain: %f\n", ol_gain);
+      if (1) {
+         int qe = (int)(floor(3.5*log(ol_gain)));
+         if (qe<0)
+            qe=0;
+         if (qe>31)
+            qe=31;
+         ol_gain = exp(qe/3.5);
+         speex_bits_pack(bits, qe, 5);
+      }
+
+   }
+
    /* Loop on sub-frames */
    for (sub=0;sub<st->nbSubframes;sub++)
    {
@@ -359,9 +412,21 @@ void nb_encode(void *state, float *in, SpeexBits *bits)
          exc[i]=0;
 
       /* Long-term prediction */
-      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, 
-                    st->lpcSize, st->subframeSize, bits, st->stack, exc2);
+      if (st->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, 
+                               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, 
+                               st->lpcSize, st->subframeSize, bits, st->stack, exc2);
+      printf ("cl_pitch: %d\n", pitch);
       st->pitch[sub]=pitch;
 
       /* Update target for adaptive codebook contribution */
@@ -443,7 +508,21 @@ void nb_encode(void *state, float *in, SpeexBits *bits)
             ener+=st->buf2[i]*st->buf2[i];
          ener=sqrt(.1+ener/st->subframeSize);
 
+         printf ("cl_ener: %f %f\n", ener, ol_gain);
+         if (0){
+            static float old_ener=1;
+            if (sub)
+               printf ("ener: %f %f\n", old_ener, ener);
+            old_ener=ener;
+         }
+         ener /= ol_gain;
          {
+            float ratio = log(ener);
+            if (ratio<-3)
+               ratio=-3;
+         printf ("ener_ratio: %f\n", ratio);
+         }
+         if (0) {
             int qe = (int)(floor(7*log(ener)));
             if (qe<0)
                qe=0;
@@ -451,7 +530,17 @@ void nb_encode(void *state, float *in, SpeexBits *bits)
                qe=63;
             ener = exp(qe/7.0);
             speex_bits_pack(bits, qe, 6);
+         } else {
+            int qe;
+            ener=log(ener);
+            qe = vq_index(&ener, exc_gain_quant_scal, 1, 8);
+            speex_bits_pack(bits, qe, 3);
+            ener=exc_gain_quant_scal[qe];
+            ener=exp(ener);
+            printf ("encode gain: %d %f\n", qe, ener);
          }
+         ener*=ol_gain;
+         printf ("transmit gain: %f\n", ener);
          ener_1 = 1/ener;
          
          for (i=0;i<st->subframeSize;i++)
@@ -556,6 +645,7 @@ 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;
@@ -624,7 +714,8 @@ void nb_decode(void *state, SpeexBits *bits, float *out, int lost)
    int i, sub;
    int pitch;
    float pitch_gain[3];
-
+   float ol_gain;
+   int ol_pitch;
    st=state;
 
    memmove(st->inBuf, st->inBuf+st->frameSize, (st->bufSize-st->frameSize)*sizeof(float));
@@ -639,6 +730,16 @@ void nb_decode(void *state, SpeexBits *bits, float *out, int lost)
          st->old_qlsp[i] = st->qlsp[i];
    }
 
+   if (st->lbr_pitch)
+      ol_pitch = st->min_pitch+speex_bits_unpack_unsigned(bits, 7);
+   
+   {
+      int qe;
+      qe = speex_bits_unpack_unsigned(bits, 5);
+      ol_gain = exp(qe/3.5);
+      printf ("decode_ol_gain: %f\n", ol_gain);
+   }
+
    /*Loop on subframes */
    for (sub=0;sub<st->nbSubframes;sub++)
    {
@@ -680,7 +781,16 @@ void nb_decode(void *state, SpeexBits *bits, float *out, int lost)
          exc[i]=0;
 
       /*Adaptive codebook contribution*/
-      st->ltp_unquant(exc, st->min_pitch, st->max_pitch, st->ltp_params, st->subframeSize, &pitch, &pitch_gain[0], bits, st->stack, lost);
+      if (st->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, lost);
+      } else
+         st->ltp_unquant(exc, st->min_pitch, st->max_pitch, st->ltp_params, st->subframeSize, &pitch, &pitch_gain[0], bits, st->stack, lost);
       
 
       {
@@ -692,8 +802,12 @@ void nb_decode(void *state, SpeexBits *bits, float *out, int lost)
          for (i=0;i<st->subframeSize;i++)
             innov[i]=0;
 
-         q_energy = speex_bits_unpack_unsigned(bits, 6);
-         ener = exp(q_energy/7.0);
+         q_energy = speex_bits_unpack_unsigned(bits, 3);
+         /*ener = exp(q_energy/7.0);*/
+
+         ener = ol_gain*exp(exc_gain_quant_scal[q_energy]);
+         printf ("decode_cl_gain: %f\n", ener);
+
          /*printf ("unquant_energy: %d %f\n", q_energy, ener);*/
          
          /*Fixed codebook contribution*/
index 8d3a7eb..29c14de 100644 (file)
@@ -35,6 +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;
@@ -93,6 +94,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*/
index e93f1ec..d77de16 100644 (file)
@@ -152,6 +152,64 @@ void lsp_unquant_nb(float *lsp, int order, SpeexBits *bits)
 }
 
 
+void lsp_quant_lbr(float *lsp, float *qlsp, int order, SpeexBits *bits)
+{
+   int i;
+   float tmp1, tmp2;
+   int id;
+
+   for (i=0;i<order;i++)
+      qlsp[i]=lsp[i];
+
+   quant_weight[0] = 1/(qlsp[1]-qlsp[0]);
+   quant_weight[order-1] = 1/(qlsp[order-1]-qlsp[order-2]);
+   for (i=1;i<order-1;i++)
+   {
+#if 1
+      tmp1 = 1/((.15+qlsp[i]-qlsp[i-1])*(.15+qlsp[i]-qlsp[i-1]));
+      tmp2 = 1/((.15+qlsp[i+1]-qlsp[i])*(.15+qlsp[i+1]-qlsp[i]));
+#else
+      tmp1 = 1/(qlsp[i]-qlsp[i-1]);
+      tmp2 = 1/(qlsp[i+1]-qlsp[i]);
+#endif
+      quant_weight[i] = tmp1 > tmp2 ? tmp1 : tmp2;
+   }
+   id = lsp_quant(qlsp, cdbk_nb, NB_CDBK_SIZE, order);
+   speex_bits_pack(bits, id, 6);
+
+   id = lsp_weight_quant(qlsp, quant_weight, cdbk_nb_low1, NB_CDBK_SIZE_LOW1, 5);
+   speex_bits_pack(bits, id, 6);
+
+   id = lsp_weight_quant(qlsp+5, quant_weight+5, cdbk_nb_high1, NB_CDBK_SIZE_HIGH1, 5);
+   speex_bits_pack(bits, id, 6);
+
+   for (i=0;i<order;i++)
+      qlsp[i]=lsp[i]-qlsp[i];
+}
+
+void lsp_unquant_lbr(float *lsp, int order, SpeexBits *bits)
+{
+   int i, id;
+   for (i=0;i<order;i++)
+      lsp[i]=0;
+
+
+   id=speex_bits_unpack_unsigned(bits, 6);
+   for (i=0;i<10;i++)
+      lsp[i] += cdbk_nb[id*10+i];
+
+   id=speex_bits_unpack_unsigned(bits, 6);
+   for (i=0;i<5;i++)
+      lsp[i] += cdbk_nb_low1[id*5+i];
+
+   id=speex_bits_unpack_unsigned(bits, 6);
+   for (i=0;i<5;i++)
+      lsp[i+5] += cdbk_nb_high1[id*5+i];
+   
+}
+
+
+
 extern float lsp_cdbk_wb[];
 extern float lsp_cdbk_wb11[];
 extern float lsp_cdbk_wb12[];
index e1ece03..292e892 100644 (file)
@@ -43,6 +43,12 @@ void lsp_quant_nb(float *lsp, float *qlsp, int order, SpeexBits *bits);
 /* Decodes quantized narrowband LSPs */
 void lsp_unquant_nb(float *lsp, int order, SpeexBits *bits);
 
+/* Quantizes low bit-rate narrowband LSPs with 18 bits */
+void lsp_quant_lbr(float *lsp, float *qlsp, int order, SpeexBits *bits);
+
+/* Decodes quantized low bit-rate narrowband LSPs */
+void lsp_unquant_lbr(float *lsp, int order, SpeexBits *bits);
+
 /* Quantizes wideband LSPs with 50 bits */
 void lsp_quant_wb(float *lsp, float *qlsp, int order, SpeexBits *bits);
 
index bf00847..70d06d2 100644 (file)
@@ -111,6 +111,9 @@ 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;
 
index 1688dab..ef34ee5 100644 (file)
 #define SPEEX_HEADER_H
 
 typedef struct SpeexHeader {
+   char speex_version[20];
+   int speex_header_version;
    int rate;
    int mode;
    int nb_channels;
+   int byte_rate;
+   int frame_size;
 } SpeexHeader;
 
+char *speex_header_to_packet(SpeexHeader *header, int *size);
+
+SpeexHeader *speex_packet_to_header(char *packet, int size);
+
 #endif