fixed-point: converting wideband excitation gain to int (halfway done)
authorjm <jm@0101bb08-14d6-0310-b084-bc0e0c8e3800>
Thu, 13 Nov 2003 08:45:55 +0000 (08:45 +0000)
committerjm <jm@0101bb08-14d6-0310-b084-bc0e0c8e3800>
Thu, 13 Nov 2003 08:45:55 +0000 (08:45 +0000)
git-svn-id: http://svn.xiph.org/trunk/speex@5571 0101bb08-14d6-0310-b084-bc0e0c8e3800

libspeex/sb_celp.c
libspeex/testenc_wb.c

index fbdb167..1dbf1c6 100644 (file)
@@ -489,10 +489,11 @@ int sb_encode(void *state, short *in, SpeexBits *bits)
    for (sub=0;sub<st->nbSubframes;sub++)
    {
       spx_sig_t *exc, *sp, *res, *target, *sw;
-      float tmp, filter_ratio;
+      float tmp;
+      spx_word16_t filter_ratio;
       int offset;
-      float rl, rh, eh=0, el=0;
-      int fold;
+      float rl, rh;
+      spx_word16_t eh=0;
 
       offset = st->subframeSize*sub;
       sp=st->high+offset;
@@ -532,12 +533,11 @@ int sb_encode(void *state, short *in, SpeexBits *bits)
       rl=1/(fabs(rl)+.01);
       rh=1/(fabs(rh)+.01);
       /* Compute ratio, will help predict the gain */
+#ifdef FIXED_POINT
+      filter_ratio=128*fabs(.01+rh)/(.01+fabs(rl));
+#else
       filter_ratio=fabs(.01+rh)/(.01+fabs(rl));
-
-      fold = filter_ratio<5;
-      /*printf ("filter_ratio %f\n", filter_ratio);*/
-      fold=0;
-
+#endif
       /* Compute "real excitation" */
       fir_mem2(sp, st->interp_qlpc, exc, st->subframeSize, st->lpcSize, st->mem_sp2);
       /* Compute energy of low-band and high-band excitation */
@@ -546,13 +546,13 @@ int sb_encode(void *state, short *in, SpeexBits *bits)
 
       if (!SUBMODE(innovation_quant)) {/* 1 for spectral folding excitation, 0 for stochastic */
          float g;
-
+         float el;
          el = compute_rms(low_innov+offset, st->subframeSize);
 
          /* Gain to use if we want to use the low-band excitation for high-band */
          g=eh/(.01+el);
 
-         g *= filter_ratio;
+         g *= filter_ratio/128.;
          /*print_vec(&g, 1, "gain factor");*/
          /* Gain quantization */
          {
@@ -566,25 +566,46 @@ int sb_encode(void *state, short *in, SpeexBits *bits)
          }
 
       } else {
-         float gc, scale, scale_1;
-
+         spx_word16_t gc;
+         spx_word32_t scale;
+         spx_word16_t el;
          el = compute_rms(low_exc+offset, st->subframeSize);
-         /*FIXME: cleanup the "historical" mess with sqrt(st->subframeSize) */
-         gc = (1+eh)*filter_ratio/(1+el)/sqrt(st->subframeSize);
 
+         gc = DIV32_16(MULT16_16((int)(filter_ratio),(1+eh)),1+el);
+
+         /* This is a kludge that cleans up a historical bug */
+         if (st->subframeSize==80)
+            gc *= 0.70711;
+         /*printf ("%f %f %f %f\n", el, eh, filter_ratio, gc);*/
+#ifdef FIXED_POINT
          {
-            int qgc = (int)floor(.5+3.7*(log(gc)+2));
+            int qgc = (int)floor(.5+3.7*(log(gc/128.)+0.15556));
             if (qgc<0)
                qgc=0;
             if (qgc>15)
                qgc=15;
             speex_bits_pack(bits, qgc, 4);
-            gc = exp((1/3.7)*qgc-2);
+            gc = 128*exp((1/3.7)*qgc-0.15556);
          }
+#else
+         {
+            int qgc = (int)floor(.5+3.7*(log(gc)+0.15556));
+            if (qgc<0)
+               qgc=0;
+            if (qgc>15)
+               qgc=15;
+            speex_bits_pack(bits, qgc, 4);
+            gc = exp((1/3.7)*qgc-0.15556);
+         }         
+#endif
+         if (st->subframeSize==80)
+            gc *= 1.4142;
 
-         scale = gc*(1+el*sqrt(st->subframeSize))/filter_ratio;
-         scale_1 = 1/scale;
-
+#ifdef FIXED_POINT
+         scale = SHL(DIV32_16(SHL(gc,SIG_SHIFT-4),filter_ratio),4)*(1+el);
+#else
+         scale = gc*(1.+el)/filter_ratio;
+#endif
          for (i=0;i<st->subframeSize;i++)
             exc[i]=VERY_SMALL;
          exc[0]=SIG_SCALING;
@@ -615,7 +636,7 @@ int sb_encode(void *state, short *in, SpeexBits *bits)
          for (i=0;i<st->subframeSize;i++)
            exc[i]=0;
 
-         signal_div(target, target, SIG_SCALING*scale, st->subframeSize);
+         signal_div(target, target, scale, st->subframeSize);
 
          /* Reset excitation */
          for (i=0;i<st->subframeSize;i++)
@@ -627,7 +648,7 @@ int sb_encode(void *state, short *in, SpeexBits *bits)
                                    innov, syn_resp, bits, stack, (st->complexity+1)>>1);
          /*print_vec(target, st->subframeSize, "after");*/
 
-         signal_mul(innov, innov, SIG_SCALING*scale, st->subframeSize);
+         signal_mul(innov, innov, scale, st->subframeSize);
 
          for (i=0;i<st->subframeSize;i++)
             exc[i] += innov[i];
@@ -643,7 +664,7 @@ int sb_encode(void *state, short *in, SpeexBits *bits)
                                       SUBMODE(innovation_params), st->lpcSize, st->subframeSize, 
                                       innov2, syn_resp, bits, tmp_stack, (st->complexity+1)>>1);
             for (i=0;i<st->subframeSize;i++)
-               innov2[i]*=scale*(1/2.5);
+               innov2[i]*=scale*(1/2.5)/SIG_SCALING;
             for (i=0;i<st->subframeSize;i++)
                exc[i] += innov2[i];
          }
index 55f578c..426e30b 100644 (file)
@@ -1,6 +1,11 @@
 #include "speex.h"
 #include <stdio.h>
 #include <stdlib.h>
+#include "speex_callbacks.h"
+
+#ifdef COUNT_MIPS
+extern long long spx_mips;
+#endif
 
 #define FRAME_SIZE 320
 #include <math.h>
@@ -8,8 +13,11 @@ int main(int argc, char **argv)
 {
    char *inFile, *outFile, *bitsFile;
    FILE *fin, *fout, *fbits=NULL;
-   short in[FRAME_SIZE];
-   float input[FRAME_SIZE], bak[FRAME_SIZE], bak2[FRAME_SIZE];
+   short in_short[FRAME_SIZE];
+   short out_short[FRAME_SIZE];
+   float in_float[FRAME_SIZE];
+   float sigpow,errpow,snr, seg_snr=0;
+   int snr_frames = 0;
    char cbits[200];
    int nbBits;
    int i;
@@ -18,34 +26,52 @@ int main(int argc, char **argv)
    SpeexBits bits;
    int tmp;
    int bitCount=0;
+   int skip_group_delay;
+   SpeexCallback callback;
+
+   sigpow = 0;
+   errpow = 0;
 
-   for (i=0;i<FRAME_SIZE;i++)
-      bak2[i]=0;
    st = speex_encoder_init(&speex_wb_mode);
    dec = speex_decoder_init(&speex_wb_mode);
-   
+
+   callback.callback_id = SPEEX_INBAND_CHAR;
+   callback.func = speex_std_char_handler;
+   callback.data = stderr;
+   speex_decoder_ctl(dec, SPEEX_SET_HANDLER, &callback);
+
+   callback.callback_id = SPEEX_INBAND_MODE_REQUEST;
+   callback.func = speex_std_mode_request_handler;
+   callback.data = st;
+   speex_decoder_ctl(dec, SPEEX_SET_HANDLER, &callback);
+
    tmp=0;
    speex_decoder_ctl(dec, SPEEX_SET_ENH, &tmp);
    tmp=0;
    speex_encoder_ctl(st, SPEEX_SET_VBR, &tmp);
-   tmp=10;
+   tmp=8;
    speex_encoder_ctl(st, SPEEX_SET_QUALITY, &tmp);
    tmp=5;
    speex_encoder_ctl(st, SPEEX_SET_COMPLEXITY, &tmp);
    tmp=3;
    speex_encoder_ctl(st, SPEEX_SET_HIGH_MODE, &tmp);
-   tmp=6;
+   tmp=7;
    speex_encoder_ctl(st, SPEEX_SET_LOW_MODE, &tmp);
-   
+
+
+   speex_mode_query(&speex_wb_mode, SPEEX_MODE_FRAME_SIZE, &tmp);
+   fprintf (stderr, "frame size: %d\n", tmp);
+   skip_group_delay = 223;
+
    if (argc != 4 && argc != 3)
-   { 
+   {
       fprintf (stderr, "Usage: encode [in file] [out file] [bits file]\nargc = %d", argc);
       exit(1);
    }
    inFile = argv[1];
    fin = fopen(inFile, "r");
    outFile = argv[2];
-   fout = fopen(outFile, "w");
+   fout = fopen(outFile, "w+");
    if (argc==4)
    {
       bitsFile = argv[3];
@@ -54,41 +80,58 @@ int main(int argc, char **argv)
    speex_bits_init(&bits);
    while (!feof(fin))
    {
-      fread(in, sizeof(short), FRAME_SIZE, fin);
+      fread(in_short, sizeof(short), FRAME_SIZE, fin);
       if (feof(fin))
          break;
       for (i=0;i<FRAME_SIZE;i++)
-         bak[i]=input[i]=in[i];
+         in_float[i]=in_short[i];
       speex_bits_reset(&bits);
-      speex_encode(st, in, &bits);
+
+      speex_encode(st, in_short, &bits);
       nbBits = speex_bits_write(&bits, cbits, 200);
       bitCount+=bits.nbBits;
-      /*printf ("Encoding frame in %d bits\n", nbBits*8);*/
+
       if (argc==4)
          fwrite(cbits, 1, nbBits, fbits);
-      {
-         float enoise=0, esig=0, snr;
-         for (i=0;i<FRAME_SIZE;i++)
-         {
-            enoise+=(bak2[i]-input[i])*(bak2[i]-input[i]);
-            esig += bak2[i]*bak2[i];
-         }
-         snr = 10*log10((esig+1)/(enoise+1));
-         /*printf ("real SNR = %f\n", snr);*/
-      }
       speex_bits_rewind(&bits);
-      
-      speex_decode(dec, &bits, in);
 
+      speex_decode(dec, &bits, out_short);
       speex_bits_reset(&bits);
-      fwrite(in, sizeof(short), FRAME_SIZE, fout);
+
+      fwrite(&out_short[skip_group_delay], sizeof(short), FRAME_SIZE-skip_group_delay, fout);
+      skip_group_delay = 0;
    }
-   
    fprintf (stderr, "Total encoded size: %d bits\n", bitCount);
    speex_encoder_destroy(st);
    speex_decoder_destroy(dec);
-   speex_bits_destroy(&bits);
+
+   rewind(fin);
+   rewind(fout);
+
+   while ( FRAME_SIZE == fread(in_short, sizeof(short), FRAME_SIZE, fin) 
+           &&
+           FRAME_SIZE ==  fread(out_short, sizeof(short), FRAME_SIZE,fout) )
+   {
+       float s=0, e=0;
+        for (i=0;i<FRAME_SIZE;++i) {
+            s += (float)in_short[i] * in_short[i];
+            e += ((float)in_short[i]-out_short[i]) * ((float)in_short[i]-out_short[i]);
+        }
+       seg_snr += 10*log10((s+160)/(e+160));
+       sigpow += s;
+       errpow += e;
+       snr_frames++;
+   }
    fclose(fin);
    fclose(fout);
+
+   snr = 10 * log10( sigpow / errpow );
+   seg_snr /= snr_frames;
+   fprintf(stderr,"SNR = %f\nsegmental SNR = %f\n",snr, seg_snr);
+
+#ifdef COUNT_MIPS
+   printf ("Total: %f MIPS\n", (float)(1e-6*50*spx_mips/snr_frames));
+#endif
+   
    return 1;
 }