Packet loss concealment converted to fixed-point. Added hooks for blackfin
authorjm <jm@0101bb08-14d6-0310-b084-bc0e0c8e3800>
Sun, 5 Jun 2005 03:45:46 +0000 (03:45 +0000)
committerjm <jm@0101bb08-14d6-0310-b084-bc0e0c8e3800>
Sun, 5 Jun 2005 03:45:46 +0000 (03:45 +0000)
optimizations.

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

libspeex/arch.h
libspeex/cb_search.c
libspeex/filters.c
libspeex/ltp.c
libspeex/misc.c
libspeex/misc.h
libspeex/nb_celp.c
libspeex/nb_celp.h
libspeex/testenc.c
libspeex/vq.c

index 35c3913..c1967bb 100644 (file)
@@ -53,6 +53,8 @@ typedef spx_word16_t spx_coef_t;
 typedef spx_word16_t spx_lsp_t;
 typedef spx_word32_t spx_sig_t;
 
+#define Q15ONE 32767
+
 #define LPC_SCALING  8192
 #define SIG_SCALING  16384
 #define LSP_SCALING  8192.
@@ -61,6 +63,7 @@ typedef spx_word32_t spx_sig_t;
 #define GAIN_SCALING_1 0.015625
 
 #define LPC_SHIFT    13
+#define LSP_SHIFT    13
 #define SIG_SHIFT    14
 
 #define VERY_SMALL 0
@@ -76,6 +79,10 @@ typedef spx_word32_t spx_sig_t;
 #include "fixed_arm5e.h"
 #elif defined (ARM4_ASM)
 #include "fixed_arm4.h"
+#elif defined (ARM5E_ASM)
+#include "fixed_arm5e.h"
+#elif defined (BFIN_ASM)
+#include "fixed_bfin.h"
 #endif
 
 #endif
@@ -91,14 +98,16 @@ typedef float spx_word16_t;
 typedef float spx_word32_t;
 typedef float spx_word64_t;
 
-#define LPC_SCALING  1.
-#define SIG_SCALING  1.
-#define LSP_SCALING  1.
-#define GAMMA_SCALING 1.
-#define GAIN_SCALING 1.
-#define GAIN_SCALING_1 1.
+#define Q15ONE 1.0f
+#define LPC_SCALING  1.f
+#define SIG_SCALING  1.f
+#define LSP_SCALING  1.f
+#define GAMMA_SCALING 1.f
+#define GAIN_SCALING 1.f
+#define GAIN_SCALING_1 1.f
 
 #define LPC_SHIFT    0
+#define LSP_SHIFT    0
 #define SIG_SHIFT    0
 
 #define VERY_SMALL 1e-15
index 5295df6..f087332 100644 (file)
@@ -43,6 +43,8 @@
 #include "cb_search_sse.h"
 #elif defined(ARM4_ASM) || defined(ARM5E_ASM)
 #include "cb_search_arm4.h"
+#elif defined(BFIN_ASM)
+#include "cb_search_bfin.h"
 #endif
 
 #ifndef OVERRIDE_COMPUTE_WEIGHTED_CODEBOOK
index 51d16bf..ebdf024 100644 (file)
@@ -45,6 +45,8 @@
 #include "filters_sse.h"
 #elif defined (ARM4_ASM) || defined(ARM5E_ASM)
 #include "filters_arm4.h"
+#elif defined (BFIN_ASM)
+#include "filters_bfin.h"
 #endif
 
 
@@ -364,6 +366,7 @@ void residue_percep_zero(const spx_sig_t *xx, const spx_coef_t *ak, const spx_co
    fir_mem2(y, awk2, y, N, ord, mem);
 }
 
+#ifndef OVERRIDE_COMPUTE_IMPULSE_RESPONSE
 void compute_impulse_response(const spx_coef_t *ak, const spx_coef_t *awk1, const spx_coef_t *awk2, spx_word16_t *y, int N, int ord, char *stack)
 {
    int i,j;
@@ -397,6 +400,7 @@ void compute_impulse_response(const spx_coef_t *ak, const spx_coef_t *awk1, cons
       mem2[ord-1] = MULT16_16(ak[ord-1],ny2i);
    }
 }
+#endif
 
 void qmf_decomp(const spx_word16_t *xx, const spx_word16_t *aa, spx_sig_t *y1, spx_sig_t *y2, int N, int M, spx_word16_t *mem, char *stack)
 {
index 3631f12..6f5de30 100644 (file)
@@ -50,6 +50,8 @@
 #include "ltp_sse.h"
 #elif defined (ARM4_ASM) || defined(ARM5E_ASM)
 #include "ltp_arm4.h"
+#elif defined (BFIN_ASM)
+#include "ltp_bfin.h"
 #endif
 
 #ifndef OVERRIDE_INNER_PROD
@@ -672,9 +674,9 @@ int cdbk_offset
    gain_index = speex_bits_unpack_unsigned(bits, params->gain_bits);
    /*printf ("decode pitch: %d %d\n", pitch, gain_index);*/
 #ifdef FIXED_POINT
-   gain[0] = 32+(spx_word16_t)gain_cdbk[gain_index*3];
-   gain[1] = 32+(spx_word16_t)gain_cdbk[gain_index*3+1];
-   gain[2] = 32+(spx_word16_t)gain_cdbk[gain_index*3+2];
+   gain[0] = ADD16(32,(spx_word16_t)gain_cdbk[gain_index*3]);
+   gain[1] = ADD16(32,(spx_word16_t)gain_cdbk[gain_index*3+1]);
+   gain[2] = ADD16(32,(spx_word16_t)gain_cdbk[gain_index*3+2]);
 #else
    gain[0] = 0.015625*gain_cdbk[gain_index*3]+.5;
    gain[1] = 0.015625*gain_cdbk[gain_index*3+1]+.5;
@@ -683,19 +685,25 @@ int cdbk_offset
 
    if (count_lost && pitch > subframe_offset)
    {
-      float gain_sum;
+      spx_word16_t gain_sum;
       if (1) {
-        float tmp = count_lost < 4 ? GAIN_SCALING_1*last_pitch_gain : 0.4 * GAIN_SCALING_1 * last_pitch_gain;
+#ifdef FIXED_POINT
+         spx_word16_t tmp = count_lost < 4 ? last_pitch_gain : SHR16(last_pitch_gain,1);
+         if (tmp>62)
+            tmp=62;
+#else
+         spx_word16_t tmp = count_lost < 4 ? last_pitch_gain : 0.5 * last_pitch_gain;
          if (tmp>.95)
             tmp=.95;
-         gain_sum = GAIN_SCALING_1*gain_3tap_to_1tap(gain);
-
-        if (gain_sum > tmp) {
-           float fact = tmp/gain_sum;
-           for (i=0;i<3;i++)
-              gain[i]*=fact;
+#endif
+         gain_sum = gain_3tap_to_1tap(gain);
 
-        }
+         if (gain_sum > tmp)
+         {
+            spx_word16_t fact = DIV32_16(SHL32(EXTEND32(tmp),14),gain_sum);
+            for (i=0;i<3;i++)
+               gain[i]=MULT16_16_Q14(fact,gain[i]);
+         }
 
       }
 
index 01c9495..2d80e4a 100644 (file)
@@ -159,6 +159,25 @@ void speex_warning_int(const char *str, int val)
    fprintf (stderr, "warning: %s %d\n", str, val);
 }
 
+#ifdef FIXED_POINT
+spx_word32_t speex_rand(spx_word16_t std, spx_int32_t *seed)
+{
+   *seed = 1664525 * *seed + 1013904223;
+   return MULT16_16(EXTRACT16(SHR32(*seed,16)),std);
+}
+#else
+spx_word16_t speex_rand(spx_word16_t std, spx_int32_t *seed)
+{
+   const unsigned int jflone = 0x3f800000;
+   const unsigned int jflmsk = 0x007fffff;
+   union {int i; float f;} ran;
+   *seed = 1664525 * *seed + 1013904223;
+   ran.i = jflone | (jflmsk & *seed);
+   ran.f -= 1;
+   return 1.7321*std*ran.f;
+}
+#endif
+
 void speex_rand_vec(float std, spx_sig_t *data, int len)
 {
    int i;
@@ -166,10 +185,11 @@ void speex_rand_vec(float std, spx_sig_t *data, int len)
       data[i]+=SIG_SCALING*3*std*((((float)rand())/RAND_MAX)-.5);
 }
 
-float speex_rand(float std)
+
+/*float speex_rand(float std)
 {
    return 3*std*((((float)rand())/RAND_MAX)-.5);
-}
+}*/
 
 void _speex_putc(int ch, void *file)
 {
index 6a02774..150d763 100644 (file)
@@ -75,7 +75,7 @@ void speex_warning_int(const char *str, int val);
 
 void speex_rand_vec(float std, spx_sig_t *data, int len);
 
-float speex_rand(float std);
+spx_word32_t speex_rand(spx_word16_t std, spx_int32_t *seed);
 
 void _speex_putc(int ch, void *file);
 
index 57ef444..392d024 100644 (file)
@@ -1033,7 +1033,8 @@ void *nb_decoder_init(const SpeexMode *m)
    st->count_lost=0;
    st->pitch_gain_buf[0] = st->pitch_gain_buf[1] = st->pitch_gain_buf[2] = 0;
    st->pitch_gain_buf_idx = 0;
-
+   st->seed = 1000;
+   
    st->sampling_rate=8000;
    st->last_ol_gain = 0;
 
@@ -1072,25 +1073,45 @@ void nb_decoder_destroy(void *state)
 
 #define median3(a, b, c)       ((a) < (b) ? ((b) < (c) ? (b) : ((a) < (c) ? (c) : (a))) : ((c) < (b) ? (b) : ((c) < (a) ? (c) : (a))))
 
+#ifdef FIXED_POINT
+const spx_word16_t attenuation[10] = {32767, 31483, 27923, 22861, 17278, 12055, 7764, 4616, 2533, 1283};
+#else
+const spx_word16_t attenuation[10] = {1., 0.961, 0.852, 0.698, 0.527, 0.368, 0.237, 0.141, 0.077, 0.039};
+
+#endif
+
 static void nb_decode_lost(DecState *st, spx_word16_t *out, char *stack)
 {
    int i, sub;
    VARDECL(spx_coef_t *awk1);
    VARDECL(spx_coef_t *awk2);
    VARDECL(spx_coef_t *awk3);
-   float pitch_gain, fact;
+   spx_word16_t pitch_gain;
+   spx_word16_t fact;
    spx_word16_t gain_med;
+   spx_word16_t innov_gain;
+   
+   if (st->count_lost<10)
+      fact = attenuation[st->count_lost];
+   else
+      fact = 0;
 
-   fact = exp(-.04*st->count_lost*st->count_lost);
    gain_med = median3(st->pitch_gain_buf[0], st->pitch_gain_buf[1], st->pitch_gain_buf[2]);
    if (gain_med < st->last_pitch_gain)
       st->last_pitch_gain = gain_med;
    
+#ifdef FIXED_POINT
+   pitch_gain = st->last_pitch_gain;
+   if (pitch_gain>62)
+      pitch_gain = 62;
+   pitch_gain = SHL(pitch_gain, 9);
+#else   
    pitch_gain = GAIN_SCALING_1*st->last_pitch_gain;
    if (pitch_gain>.95)
       pitch_gain=.95;
+#endif
 
-   pitch_gain = fact*pitch_gain + VERY_SMALL;
+   pitch_gain = MULT16_16_Q15(fact,pitch_gain) + VERY_SMALL;
 
    /* Shift all buffers by one frame */
    /*speex_move(st->inBuf, st->inBuf+st->frameSize, (st->bufSize-st->frameSize)*sizeof(spx_sig_t));*/
@@ -1134,22 +1155,13 @@ static void nb_decode_lost(DecState *st, spx_word16_t *out, char *stack)
       /* FIXME: THIS CAN BE IMPROVED */
       /*if (pitch_gain>.95)
         pitch_gain=.95;*/
-      {
-      float innov_gain=0;
       innov_gain = compute_rms(st->innov, st->frameSize);
       for (i=0;i<st->subframeSize;i++)
       {
-#if 0
-         exc[i] = pitch_gain * exc[i - st->last_pitch] + fact*sqrt(1-pitch_gain)*st->innov[i+offset];
-         /*Just so it give the same lost packets as with if 0*/
-         /*rand();*/
-#else
-         /*exc[i]=pitch_gain*exc[i-st->last_pitch] +  fact*st->innov[i+offset];*/
-         exc[i]=pitch_gain*(exc[i-st->last_pitch]+VERY_SMALL) + 
-         fact*sqrt(1-pitch_gain)*speex_rand(innov_gain);
-#endif
-      }
+         exc[i]= MULT16_32_Q15(pitch_gain, (exc[i-st->last_pitch]+VERY_SMALL)) + 
+               MULT16_32_Q15(fact, MULT16_32_Q15(sqrt(SHL(Q15ONE,15)-SHL(pitch_gain,15)),speex_rand(innov_gain, &st->seed)));
       }
+      
       for (i=0;i<st->subframeSize;i++)
          sp[i]=exc[i];
       
@@ -1180,7 +1192,7 @@ static void nb_decode_lost(DecState *st, spx_word16_t *out, char *stack)
    
    st->first = 0;
    st->count_lost++;
-   st->pitch_gain_buf[st->pitch_gain_buf_idx++] = GAIN_SCALING*pitch_gain;
+   st->pitch_gain_buf[st->pitch_gain_buf_idx++] = PSHR(pitch_gain,9);
    if (st->pitch_gain_buf_idx > 2) /* rollover */
       st->pitch_gain_buf_idx = 0;
 }
@@ -1314,8 +1326,8 @@ int nb_decode(void *state, SpeexBits *bits, void *vout)
    if (st->submodes[st->submodeID] == NULL)
    {
       VARDECL(spx_coef_t *lpc);
-      ALLOC(lpc, 11, spx_coef_t);
-      bw_lpc(GAMMA_SCALING*.93, st->interp_qlpc, lpc, 10);
+      ALLOC(lpc, st->lpcSize, spx_coef_t);
+      bw_lpc(GAMMA_SCALING*.93, st->interp_qlpc, lpc, st->lpcSize);
       {
          float innov_gain=0;
          float pgain=GAIN_SCALING_1*st->last_pitch_gain;
@@ -1353,13 +1365,17 @@ int nb_decode(void *state, SpeexBits *bits, void *vout)
    /*Damp memory if a frame was lost and the LSP changed too much*/
    if (st->count_lost)
    {
-      float lsp_dist=0, fact;
+      spx_word16_t fact;
+      spx_word32_t lsp_dist=0;
       for (i=0;i<st->lpcSize;i++)
-         lsp_dist += fabs(st->old_qlsp[i] - st->qlsp[i]);
-      lsp_dist /= LSP_SCALING;
+         lsp_dist = ADD32(lsp_dist, EXTEND32(ABS(st->old_qlsp[i] - st->qlsp[i])));
+#ifdef FIXED_POINT
+      fact = SHR16(19661,SHR32(lsp_dist,LSP_SHIFT+2));      
+#else
       fact = .6*exp(-.2*lsp_dist);
+#endif
       for (i=0;i<2*st->lpcSize;i++)
-         st->mem_sp[i] = (spx_mem_t)(st->mem_sp[i]*fact);
+         st->mem_sp[i] = MULT16_32_Q15(fact,st->mem_sp[i]);
    }
 
 
@@ -1544,9 +1560,12 @@ int nb_decode(void *state, SpeexBits *bits, void *vout)
          /* If we had lost frames, check energy of last received frame */
          if (st->count_lost && ol_gain < st->last_ol_gain)
          {
-            float fact = (float)ol_gain/(st->last_ol_gain+1);
+            /*float fact = (float)ol_gain/(st->last_ol_gain+1);
+            for (i=0;i<st->subframeSize;i++)
+            exc[i]*=fact;*/
+            spx_word16_t fact = DIV32_16(SHL32(EXTEND32(ol_gain),15),st->last_ol_gain+1);
             for (i=0;i<st->subframeSize;i++)
-               exc[i]*=fact;
+               exc[i] = MULT16_32_Q15(fact, exc[i]);
          }
 
          tmp = gain_3tap_to_1tap(pitch_gain);
index 5f2675f..9e3a291 100644 (file)
@@ -151,7 +151,8 @@ typedef struct DecState {
    spx_word16_t  last_pitch_gain; /**< Pitch gain of last correctly decoded frame */
    spx_word16_t  pitch_gain_buf[3];  /**< Pitch gain of last decoded frames */
    int    pitch_gain_buf_idx; /**< Tail of the buffer */
-
+   spx_int32_t seed;          /** Seed used for random number generation */
+   
    int    encode_submode;
    const SpeexSubmode * const *submodes; /**< Sub-mode data */
    int    submodeID;      /**< Activated sub-mode */
index a4ca903..7ef6427 100644 (file)
@@ -53,7 +53,7 @@ int main(int argc, char **argv)
    speex_decoder_ctl(dec, SPEEX_SET_ENH, &tmp);
    tmp=0;
    speex_encoder_ctl(st, SPEEX_SET_VBR, &tmp);
-   tmp=4;
+   tmp=8;
    speex_encoder_ctl(st, SPEEX_SET_QUALITY, &tmp);
    tmp=1;
    speex_encoder_ctl(st, SPEEX_SET_COMPLEXITY, &tmp);
@@ -133,5 +133,5 @@ int main(int argc, char **argv)
    printf ("Total: %f MIPS\n", (float)(1e-6*50*spx_mips/snr_frames));
 #endif
    
-   return 1;
+   return 0;
 }
index c900779..bd2e1e5 100644 (file)
@@ -42,6 +42,8 @@
 #include <xmmintrin.h>
 #elif defined(SHORTCUTS) && (defined(ARM4_ASM) || defined(ARM5E_ASM))
 #include "vq_arm4.h"
+#elif defined(BFIN_ASM)
+#include "vq_bfin.h"
 #endif