Average bit-rate (ABR) now seems to work good for narrowband (no wideband
authorjm <jm@0101bb08-14d6-0310-b084-bc0e0c8e3800>
Sun, 15 Dec 2002 06:01:45 +0000 (06:01 +0000)
committerjm <jm@0101bb08-14d6-0310-b084-bc0e0c8e3800>
Sun, 15 Dec 2002 06:01:45 +0000 (06:01 +0000)
yet, but shouldn't be hard)

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

libspeex/nb_celp.c
libspeex/nb_celp.h
src/speexenc.c

index 83d1f77..f8666dd 100644 (file)
@@ -375,10 +375,17 @@ void nb_encode(void *state, float *in, SpeexBits *bits)
       
       if (st->abr_enabled)
       {
-         if (st->abr_drift>0)
-            st->vbr_quality -= .02;
-         else
-            st->vbr_quality += .02;
+         float qual_change=0;
+         if (st->abr_drift2 * st->abr_drift > 0)
+         {
+            /* Only adapt if long-term and short-term drift are the same sign */
+            qual_change = -.00001*st->abr_drift/(1+st->abr_count);
+            if (qual_change>.1)
+               qual_change=.1;
+            if (qual_change<-.1)
+               qual_change=-.1;
+         }
+         st->vbr_quality += qual_change;
          if (st->vbr_quality>10)
             st->vbr_quality=10;
          if (st->vbr_quality<0)
@@ -417,6 +424,8 @@ void nb_encode(void *state, float *in, SpeexBits *bits)
             int bitrate;
             speex_encoder_ctl(state, SPEEX_GET_BITRATE, &bitrate);
             st->abr_drift+=(bitrate-st->abr_enabled);
+            st->abr_drift2 = .95*st->abr_drift2 + .05*(bitrate-st->abr_enabled);
+            st->abr_count += 1.0;
          }
          /*fprintf(stderr, "encode: %d %d\n",st->submodeID, mode);*/
       } else {
@@ -1454,8 +1463,10 @@ void nb_encoder_ctl(void *state, int request, void *ptr)
       break;
    case SPEEX_SET_ABR:
       st->abr_enabled = (*(int*)ptr);
+      st->vbr_enabled = 1;
       {
-         int i=10, rate, target, vbr_qual;
+         int i=10, rate, target;
+         float vbr_qual;
          target = (*(int*)ptr);
          while (i>=0)
          {
@@ -1468,7 +1479,11 @@ void nb_encoder_ctl(void *state, int request, void *ptr)
          vbr_qual=i;
          if (vbr_qual<0)
             vbr_qual=0;
+         fprintf (stderr, "%f\n", vbr_qual);
          speex_encoder_ctl(st, SPEEX_SET_VBR_QUALITY, &vbr_qual);
+         st->abr_count=0;
+         st->abr_drift=0;
+         st->abr_drift2=0;
       }
       
       break;
index d7dab22..d7ae95e 100644 (file)
@@ -105,6 +105,8 @@ typedef struct EncState {
    int    vad_enabled;    /**< 1 for enabling VAD, 0 otherwise */
    int    abr_enabled;    /**< 1 for enabling ABR, 0 otherwise */
    float  abr_drift;
+   float  abr_drift2;
+   float  abr_count;
    int    complexity;     /**< Complexity setting (0-10 from least complex to most complex) */
    int    sampling_rate;
 
index 042743c..405ea5f 100644 (file)
@@ -144,6 +144,7 @@ void usage()
    printf (" --quality n        Encoding quality (0-10), default 3\n"); 
    printf (" --bitrate n        Encoding bit-rate (use bit-rate n or lower)\n"); 
    printf (" --vbr              Enable variable bit-rate (VBR)\n"); 
+   printf (" --abr rate         Enable average bit-rate (ABR) at rate bps\n"); 
    printf (" --vad              Enable voice activity detection (VAD)\n"); 
    printf (" --comp n           Set encoding complexity (0-10), default 3\n"); 
    printf (" --nframes n        Number of frames per Ogg packet (1-10), default 1\n"); 
@@ -178,6 +179,7 @@ int main(int argc, char **argv)
    float input[MAX_FRAME_SIZE];
    int frame_size;
    int vbr_enabled=0;
+   int abr_enabled=0;
    int vad_enabled=0;
    int nbBytes;
    SpeexMode *mode=NULL;
@@ -190,6 +192,7 @@ int main(int argc, char **argv)
       {"ultra-wideband", no_argument, NULL, 0},
       {"narrowband", no_argument, NULL, 0},
       {"vbr", no_argument, NULL, 0},
+      {"abr", required_argument, NULL, 0},
       {"vad", no_argument, NULL, 0},
       {"quality", required_argument, NULL, 0},
       {"bitrate", required_argument, NULL, 0},
@@ -230,7 +233,7 @@ int main(int argc, char **argv)
    int close_in=0, close_out=0;
    int eos=0;
    int bitrate=0;
-
+   int cumul_bits=0, enc_frames=0;
    comment_init(&comments, &comments_length, vendor_string);
 
    /*Process command-line options*/
@@ -256,6 +259,14 @@ int main(int argc, char **argv)
          } else if (strcmp(long_options[option_index].name,"vbr")==0)
          {
             vbr_enabled=1;
+         } else if (strcmp(long_options[option_index].name,"abr")==0)
+         {
+            abr_enabled=atoi(optarg);
+            if (!abr_enabled)
+            {
+               fprintf (stderr, "Invalid ABR value: %d\n", abr_enabled);
+               exit(1);
+            }
          } else if (strcmp(long_options[option_index].name,"vad")==0)
          {
             vad_enabled=1;
@@ -534,6 +545,19 @@ int main(int argc, char **argv)
    speex_encoder_ctl(st, SPEEX_SET_COMPLEXITY, &complexity);
    speex_encoder_ctl(st, SPEEX_SET_SAMPLING_RATE, &rate);
 
+   if (quality >= 0)
+   {
+      if (vbr_enabled)
+         speex_encoder_ctl(st, SPEEX_SET_VBR_QUALITY, &vbr_quality);
+      else
+         speex_encoder_ctl(st, SPEEX_SET_QUALITY, &quality);
+   }
+   if (bitrate)
+   {
+      if (quality >= 0 && vbr_enabled)
+         fprintf (stderr, "--bitrate option is overriding --quality\n");
+      speex_encoder_ctl(st, SPEEX_SET_BITRATE, &bitrate);
+   }
    if (vbr_enabled)
    {
       int tmp;
@@ -546,18 +570,9 @@ int main(int argc, char **argv)
       tmp=1;
       speex_encoder_ctl(st, SPEEX_SET_VAD, &tmp);
    }
-   if (quality >= 0)
+   if (abr_enabled)
    {
-      if (vbr_enabled)
-         speex_encoder_ctl(st, SPEEX_SET_VBR_QUALITY, &vbr_quality);
-      else
-         speex_encoder_ctl(st, SPEEX_SET_QUALITY, &quality);
-   }
-   if (bitrate)
-   {
-      if (quality >= 0 && vbr_enabled)
-         fprintf (stderr, "--bitrate option is overriding --quality\n");
-      speex_encoder_ctl(st, SPEEX_SET_BITRATE, &bitrate);
+      speex_encoder_ctl(st, SPEEX_SET_ABR, &abr_enabled);
    }
 
    speex_bits_init(&bits);
@@ -579,7 +594,13 @@ int main(int argc, char **argv)
          char ch=13;
          speex_encoder_ctl(st, SPEEX_GET_BITRATE, &tmp);
          fputc (ch, stderr);
-         fprintf (stderr, "Bitrate is use: %d bps     ", tmp);
+         cumul_bits += tmp;
+         enc_frames++;
+         if (vad_enabled || vbr_enabled || abr_enabled)
+            fprintf (stderr, "Bitrate is use: %d bps  (average %d bps)   ", tmp, cumul_bits/enc_frames);
+         else
+            fprintf (stderr, "Bitrate is use: %d bps     ", tmp);
+         
       }
 
       if (read_samples(fin,frame_size,fmt,chan,lsb,input))