Ultra-wideband VBR seems to work. Also, fixed a bug for wideband VBR.
authorjm <jm@0101bb08-14d6-0310-b084-bc0e0c8e3800>
Sat, 30 Nov 2002 05:24:41 +0000 (05:24 +0000)
committerjm <jm@0101bb08-14d6-0310-b084-bc0e0c8e3800>
Sat, 30 Nov 2002 05:24:41 +0000 (05:24 +0000)
git-svn-id: http://svn.xiph.org/trunk/speex@4128 0101bb08-14d6-0310-b084-bc0e0c8e3800

libspeex/modes.c
libspeex/modes.h
libspeex/sb_celp.c
libspeex/sb_celp.h
libspeex/vbr.c
libspeex/vbr.h

index 37cbf48..5402d18 100644 (file)
@@ -40,6 +40,7 @@
 #include "cb_search.h"
 #include "sb_celp.h"
 #include "nb_celp.h"
+#include "vbr.h"
 
 SpeexMode *speex_mode_list[SPEEX_NB_MODES] = {&speex_nb_mode, &speex_wb_mode, &speex_uwb_mode};
 
@@ -446,7 +447,9 @@ static SpeexSBMode sb_wb_mode = {
    {NULL, &wb_submode1, &wb_submode2, &wb_submode3, &wb_submode4, NULL, NULL, NULL},
    3,
    {0, 1, 2, 3, 4, 5, 5, 6, 6, 7, 7},
-   {0, 1, 1, 1, 1, 1, 2, 2, 3, 3, 4}
+   {0, 1, 1, 1, 1, 1, 2, 2, 3, 3, 4},
+   vbr_hb_thresh,
+   5
 };
 
 
@@ -487,7 +490,9 @@ static SpeexSBMode sb_uwb_mode = {
    {NULL, &wb_submode1, NULL, NULL, NULL, NULL, NULL, NULL},
    1,
    {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
-   {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
+   {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
+   vbr_uhb_thresh,
+   2
 };
 
 
index 3afe5d0..0d70931 100644 (file)
@@ -137,7 +137,8 @@ typedef struct SpeexSBMode {
    int     defaultSubmode; /**< Default sub-mode to use when encoding */
    int     low_quality_map[11]; /**< Mode corresponding to each quality setting */
    int     quality_map[11]; /**< Mode corresponding to each quality setting */
-
+   float   (*vbr_thresh)[11];
+   int     nb_modes;
 } SpeexSBMode;
 
 
index ced7605..5a07ed4 100644 (file)
@@ -220,6 +220,7 @@ void *sb_encoder_init(SpeexMode *m)
 
    st->vbr_quality = 8;
    st->vbr_enabled = 0;
+   st->relative_quality=0;
 
    st->complexity=2;
    speex_decoder_ctl(st->st_low, SPEEX_GET_SAMPLING_RATE, &st->sampling_rate);
@@ -282,9 +283,11 @@ void sb_encode(void *state, float *in, SpeexBits *bits)
    void *stack;
    float *mem, *innov, *syn_resp;
    float *low_pi_gain, *low_exc, *low_innov;
+   SpeexSBMode *mode;
 
    st = (SBEncState*)state;
    stack=st->stack;
+   mode = (SpeexSBMode*)(st->mode->mode);
 
    /* Compute the two sub-bands by filtering with h0 and h1*/
    qmf_decomp(in, h0, st->x0d, st->x1d, st->full_frame_size, QMF_ORDER, st->h0_mem, stack);
@@ -349,49 +352,39 @@ void sb_encode(void *state, float *in, SpeexBits *bits)
    if (st->vbr_enabled){
       float e_low=0, e_high=0;
       float ratio;
-      float low_qual;
       for (i=0;i<st->frame_size;i++)
       {
          e_low  += st->x0d[i]* st->x0d[i];
          e_high += st->high[i]* st->high[i];
       }
       ratio = log((1+e_high)/(1+e_low));
-      speex_encoder_ctl(st->st_low, SPEEX_GET_RELATIVE_QUALITY, &low_qual);
+      speex_encoder_ctl(st->st_low, SPEEX_GET_RELATIVE_QUALITY, &st->relative_quality);
       if (ratio<-4)
          ratio=-4;
       if (ratio>2)
          ratio=2;
       /*if (ratio>-2)*/
-      low_qual+=1.0*(ratio+2);
-      /*{
-         int high_mode=2;
-         if (low_qual>10)
-            high_mode=4;
-         else if (low_qual>7.5)
-            high_mode=3;
-         else if (low_qual>5)
-            high_mode=2;
-         speex_encoder_ctl(st, SPEEX_SET_HIGH_MODE, &high_mode);
-      }*/
+      st->relative_quality+=1.0*(ratio+2);
       {
-         int mode;
-         mode = 4;
-         while (mode)
+         int modeid;
+         modeid = mode->nb_modes-1;
+         while (modeid)
          {
             int v1;
             float thresh;
             v1=(int)floor(st->vbr_quality);
             if (v1==10)
-               thresh = vbr_nb_thresh[mode][v1];
+               thresh = mode->vbr_thresh[modeid][v1];
             else
-               thresh = (st->vbr_quality-v1)*vbr_hb_thresh[mode][v1+1] + (1+v1-st->vbr_quality)*vbr_hb_thresh[mode][v1];
-            if (low_qual > thresh)
+               thresh = (st->vbr_quality-v1)   * mode->vbr_thresh[modeid][v1+1] + 
+                        (1+v1-st->vbr_quality) * mode->vbr_thresh[modeid][v1];
+            if (st->relative_quality > thresh)
                break;
-            mode--;
+            modeid--;
          }
-         /*fprintf (stderr, "%f %d\n", low_qual, mode);*/
-         speex_encoder_ctl(state, SPEEX_SET_HIGH_MODE, &mode);
-         /*fprintf (stderr, "%d %d\n", st->submodeID, mode);*/
+         /*fprintf (stderr, "%f %d\n", low_qual, modeid);*/
+         speex_encoder_ctl(state, SPEEX_SET_HIGH_MODE, &modeid);
+         /*fprintf (stderr, "%d %d\n", st->submodeID, modeid);*/
       }
       /*fprintf (stderr, "%f %f\n", ratio, low_qual);*/
    }
@@ -1087,6 +1080,9 @@ void sb_encoder_ctl(void *state, int request, void *ptr)
             e[2*i]=2*st->exc[i];
       }
       break;
+   case SPEEX_GET_RELATIVE_QUALITY:
+      (*(float*)ptr)=st->relative_quality;
+      break;
    default:
       fprintf(stderr, "Unknown nb_ctl request: %d\n", request);
    }
index 651d83f..0240da5 100644 (file)
@@ -92,6 +92,7 @@ typedef struct SBEncState {
 
    float  vbr_quality;         /**< Quality setting for VBR encoding */
    int    vbr_enabled;         /**< 1 for enabling VBR, 0 otherwise */
+   float  relative_quality;
 
    SpeexSubmode **submodes;
    int    submodeID;
index a43db62..b3078d9 100644 (file)
@@ -60,11 +60,16 @@ float vbr_nb_thresh[8][11]={
 float vbr_hb_thresh[5][11]={
    {-1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0}, /* silence */
    { 3.9,  2.5,  0.0,  0.0,  0.0,  0.0,  0.0,  0.0,  0.0,  0.0, -1.0}, /*  2 kbps */
-   {11.0, 11.0,  9.9,  9.0,  8.0,  7.0,  6.5,  6.0,  5.0,  4.0,  2.0}, /*  6 kbps */
-   {11.0, 11.0, 11.0, 11.0, 11.0, 11.0,  9.5,  8.5,  8.0,  6.5,  4.0}, /* 10 kbps */
+   {11.0, 11.0,  9.5,  8.5,  7.5,  6.5,  6.0,  5.0,  4.0,  3.0,  1.0}, /*  6 kbps */
+   {11.0, 11.0, 11.0, 11.0, 11.0,  9.5,  8.7,  8.0,  7.0,  6.5,  4.0}, /* 10 kbps */
    {11.0, 11.0, 11.0, 11.0, 11.0, 11.0, 11.0, 11.0,  9.8,  7.5,  5.5}  /* 18 kbps */ 
 };
 
+float vbr_uhb_thresh[2][11]={
+   {-1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0}, /* silence */
+   { 3.9,  2.5,  0.0,  0.0,  0.0,  0.0,  0.0,  0.0,  0.0,  0.0, -1.0}  /*  2 kbps */
+};
+
 void vbr_init(VBRState *vbr)
 {
    int i;
index 51c834e..d735daf 100644 (file)
@@ -40,6 +40,7 @@
 
 extern float vbr_nb_thresh[8][11];
 extern float vbr_hb_thresh[5][11];
+extern float vbr_uhb_thresh[2][11];
 
 typedef struct VBRState {
    float energy_alpha;