[Speex-dev] Patch for Analog Devices compiler & fixed-point AGC

Stephane Lesage
Tue, 19 Feb 2008 11:36:32 -0000

Hi Jean-Marc,

As I told you, bank is a reserved keyword in Analog Devices compiler for
  Blackfin architecture.
So we need to change the variables named bank to something else.

Here's a patch that changes bank to bnk in the 3 concerned files.
(Hope the format is OK)


About my previous problems with the Blackfin:
-> strange block repetition that could be cancelled by the AEC

I was busy with higher-level code and new hardware,
but I did some new tests now, and it was really stupid:

ADC buffer in SDRAM + DMA reception = my cache is a trash...

This was a problem on my test program, because he's doing nothing else,
but didn't occur in my software which can do a bunch of other things.


Something else:
I need the AGC on my fixed-point platform,
I've looked at the code, I think I will do it, as it seems pretty easy:
- I can live with a few emulated floating point operations for gain
computation
- extract gain mantissa and exponent
- multiply fixed-point buffer by mantissa
- offset spectrum exponent before IFFT reconstruction

What do you think ?

Best regards.

--
Stephane Lesage
ATEIS International
-------------- next part --------------
--- C:/Documents and Settings/Stephane/Local Settings/Temp/filterbank-HEAD.2.h
Tue Feb 19 19:58:52 2008
+++ c:/Dev/Speex/libspeex/filterbank.h	Thu Nov 22 14:18:38 2007
@@ -51,15 +51,15 @@

 FilterBank *filterbank_new(int banks, spx_word32_t sampling, int len, int
type);

-void filterbank_destroy(FilterBank *bank);
+void filterbank_destroy(FilterBank *bnk);

-void filterbank_compute_bank32(FilterBank *bank, spx_word32_t *ps, spx_word32_t
*mel);
+void filterbank_compute_bank32(FilterBank *bnk, spx_word32_t *ps, spx_word32_t
*mel);

-void filterbank_compute_psd16(FilterBank *bank, spx_word16_t *mel, spx_word16_t
*psd);
+void filterbank_compute_psd16(FilterBank *bnk, spx_word16_t *mel, spx_word16_t
*psd);

 #ifndef FIXED_POINT
-void filterbank_compute_bank(FilterBank *bank, float *psd, float *mel);
-void filterbank_compute_psd(FilterBank *bank, float *mel, float *psd);
+void filterbank_compute_bank(FilterBank *bnk, float *psd, float *mel);
+void filterbank_compute_psd(FilterBank *bnk, float *mel, float *psd);
 #endif


--- C:/Documents and Settings/Stephane/Local Settings/Temp/preprocess-HEAD.3.c
Tue Feb 19 19:59:23 2008
+++ c:/Dev/Speex/libspeex/preprocess.c	Tue Feb 19 19:44:10 2008
@@ -184,7 +184,7 @@
    int    ps_size;           /**< Number of points in the power spectrum */
    int    sampling_rate;     /**< Sampling rate of the input/output */
    int    nbands;
-   FilterBank *bank;
+   FilterBank *bnk;

    /* Parameters */
    int    denoise_enabled;
@@ -444,7 +444,7 @@

    st->nbands = NB_BANDS;
    M = st->nbands;
-   st->bank = filterbank_new(M, sampling_rate, N, 1);
+   st->bnk = filterbank_new(M, sampling_rate, N, 1);

    st->frame = (spx_word16_t*)speex_alloc(2*N*sizeof(spx_word16_t));
    st->window = (spx_word16_t*)speex_alloc(2*N*sizeof(spx_word16_t));
@@ -562,7 +562,7 @@
    speex_free(st->outbuf);

    spx_fft_destroy(st->fft_lookup);
-   filterbank_destroy(st->bank);
+   filterbank_destroy(st->bnk);
    speex_free(st);
 }

@@ -661,7 +661,7 @@
    for (i=0;i<N;i++)
       st->ps[i] = PSHR32(st->ps[i], 2*st->frame_shift);

-   filterbank_compute_bank32(st->bank, ps, ps+N);
+   filterbank_compute_bank32(st->bnk, ps, ps+N);
 }

 static void update_noise_prob(SpeexPreprocessState *st)
@@ -761,7 +761,7 @@
 #endif
       for (i=0;i<N;i++)
          st->echo_noise[i] =
MAX32(MULT16_32_Q15(QCONST16(.6f,15),st->echo_noise[i]),
st->residual_echo[i]);
-      filterbank_compute_bank32(st->bank, st->echo_noise,
st->echo_noise+N);
+      filterbank_compute_bank32(st->bnk, st->echo_noise,
st->echo_noise+N);
    } else {
       for (i=0;i<N+M;i++)
          st->echo_noise[i] = 0;
@@ -784,7 +784,7 @@
       if (!st->update_prob[i] || st->ps[i] < PSHR32(st->noise[i],
NOISE_SHIFT))
          st->noise[i] =
MAX32(EXTEND32(0),MULT16_32_Q15(beta_1,st->noise[i]) +
MULT16_32_Q15(beta,SHL32(st->ps[i],NOISE_SHIFT)));
    }
-   filterbank_compute_bank32(st->bank, st->noise, st->noise+N);
+   filterbank_compute_bank32(st->bnk, st->noise, st->noise+N);

    /* Special case for first frame */
    if (st->nb_adapt==1)
@@ -872,13 +872,13 @@
 #endif
    }
    /* Convert the EM gains and speech prob to linear frequency */
-   filterbank_compute_psd16(st->bank,st->gain2+N, st->gain2);
-   filterbank_compute_psd16(st->bank,st->gain+N, st->gain);
+   filterbank_compute_psd16(st->bnk,st->gain2+N, st->gain2);
+   filterbank_compute_psd16(st->bnk,st->gain+N, st->gain);

    /* Use 1 for linear gain resolution (best) or 0 for Bark gain resolution
(faster) */
    if (1)
    {
-      filterbank_compute_psd16(st->bank,st->gain_floor+N,
st->gain_floor);
+      filterbank_compute_psd16(st->bnk,st->gain_floor+N,
st->gain_floor);

       /* Compute gain according to the Ephraim-Malah algorithm -- linear
frequency */
       for (i=0;i<N;i++)
@@ -933,7 +933,7 @@
          tmp = MULT16_16_P15(p,spx_sqrt(SHL32(EXTEND32(st->gain[i]),15))) +
MULT16_16_P15(SUB16(Q15_ONE,p),spx_sqrt(SHL32(EXTEND32(st->gain_floor[i]),15)));
          st->gain2[i]=SQR16_Q15(tmp);
       }
-      filterbank_compute_psd16(st->bank,st->gain2+N, st->gain2);
+      filterbank_compute_psd16(st->bnk,st->gain2+N, st->gain2);
    }

    /* If noise suppression is off, don't apply the gain (but then why call
this in the first place!) */
--- C:/Documents and Settings/Stephane/Local Settings/Temp/filterbank-HEAD.3.c
Tue Feb 19 19:59:02 2008
+++ c:/Dev/Speex/libspeex/filterbank.c	Thu Nov 22 14:20:03 2007
@@ -53,7 +53,7 @@

 FilterBank *filterbank_new(int banks, spx_word32_t sampling, int len, int type)
 {
-   FilterBank *bank;
+   FilterBank *bnk;
    spx_word32_t df;
    spx_word32_t max_mel, mel_interval;
    int i;
@@ -63,16 +63,16 @@
    max_mel = toBARK(EXTRACT16(sampling/2));
    mel_interval = PDIV32(max_mel,banks-1);

-   bank = (FilterBank*)speex_alloc(sizeof(FilterBank));
-   bank->nb_banks = banks;
-   bank->len = len;
-   bank->bank_left = (int*)speex_alloc(len*sizeof(int));
-   bank->bank_right = (int*)speex_alloc(len*sizeof(int));
-   bank->filter_left = (spx_word16_t*)speex_alloc(len*sizeof(spx_word16_t));
-   bank->filter_right =
(spx_word16_t*)speex_alloc(len*sizeof(spx_word16_t));
+   bnk = (FilterBank*)speex_alloc(sizeof(FilterBank));
+   bnk->nb_banks = banks;
+   bnk->len = len;
+   bnk->bank_left = (int*)speex_alloc(len*sizeof(int));
+   bnk->bank_right = (int*)speex_alloc(len*sizeof(int));
+   bnk->filter_left = (spx_word16_t*)speex_alloc(len*sizeof(spx_word16_t));
+   bnk->filter_right = (spx_word16_t*)speex_alloc(len*sizeof(spx_word16_t));
    /* Think I can safely disable normalisation that for fixed-point (and
probably float as well) */
 #ifndef FIXED_POINT
-   bank->scaling = (float*)speex_alloc(banks*sizeof(float));
+   bnk->scaling = (float*)speex_alloc(banks*sizeof(float));
 #endif
    for (i=0;i<len;i++)
    {
@@ -96,110 +96,110 @@
          val = DIV32_16(mel -
id1*mel_interval,EXTRACT16(PSHR32(mel_interval,15)));
       }
       id2 = id1+1;
-      bank->bank_left[i] = id1;
-      bank->filter_left[i] = SUB16(Q15_ONE,val);
-      bank->bank_right[i] = id2;
-      bank->filter_right[i] = val;
+      bnk->bank_left[i] = id1;
+      bnk->filter_left[i] = SUB16(Q15_ONE,val);
+      bnk->bank_right[i] = id2;
+      bnk->filter_right[i] = val;
    }

    /* Think I can safely disable normalisation for fixed-point (and probably
float as well) */
 #ifndef FIXED_POINT
-   for (i=0;i<bank->nb_banks;i++)
-      bank->scaling[i] = 0;
-   for (i=0;i<bank->len;i++)
-   {
-      int id = bank->bank_left[i];
-      bank->scaling[id] += bank->filter_left[i];
-      id = bank->bank_right[i];
-      bank->scaling[id] += bank->filter_right[i];
+   for (i=0;i<bnk->nb_banks;i++)
+      bnk->scaling[i] = 0;
+   for (i=0;i<bnk->len;i++)
+   {
+      int id = bnk->bank_left[i];
+      bnk->scaling[id] += bnk->filter_left[i];
+      id = bnk->bank_right[i];
+      bnk->scaling[id] += bnk->filter_right[i];
    }
-   for (i=0;i<bank->nb_banks;i++)
-      bank->scaling[i] = Q15_ONE/(bank->scaling[i]);
+   for (i=0;i<bnk->nb_banks;i++)
+      bnk->scaling[i] = Q15_ONE/(bnk->scaling[i]);
 #endif
-   return bank;
+   return bnk;
 }

-void filterbank_destroy(FilterBank *bank)
+void filterbank_destroy(FilterBank *bnk)
 {
-   speex_free(bank->bank_left);
-   speex_free(bank->bank_right);
-   speex_free(bank->filter_left);
-   speex_free(bank->filter_right);
+   speex_free(bnk->bank_left);
+   speex_free(bnk->bank_right);
+   speex_free(bnk->filter_left);
+   speex_free(bnk->filter_right);
 #ifndef FIXED_POINT
-   speex_free(bank->scaling);
+   speex_free(bnk->scaling);
 #endif
-   speex_free(bank);
+   speex_free(bnk);
 }

-void filterbank_compute_bank32(FilterBank *bank, spx_word32_t *ps, spx_word32_t
*mel)
+void filterbank_compute_bank32(FilterBank *bnk, spx_word32_t *ps, spx_word32_t
*mel)
 {
    int i;
-   for (i=0;i<bank->nb_banks;i++)
+   for (i=0;i<bnk->nb_banks;i++)
       mel[i] = 0;

-   for (i=0;i<bank->len;i++)
+   for (i=0;i<bnk->len;i++)
    {
       int id;
-      id = bank->bank_left[i];
-      mel[id] += MULT16_32_P15(bank->filter_left[i],ps[i]);
-      id = bank->bank_right[i];
-      mel[id] += MULT16_32_P15(bank->filter_right[i],ps[i]);
+      id = bnk->bank_left[i];
+      mel[id] += MULT16_32_P15(bnk->filter_left[i],ps[i]);
+      id = bnk->bank_right[i];
+      mel[id] += MULT16_32_P15(bnk->filter_right[i],ps[i]);
    }
    /* Think I can safely disable normalisation that for fixed-point (and
probably float as well) */
 #ifndef FIXED_POINT
-   /*for (i=0;i<bank->nb_banks;i++)
-      mel[i] = MULT16_32_P15(Q15(bank->scaling[i]),mel[i]);
+   /*for (i=0;i<bnk->nb_banks;i++)
+      mel[i] = MULT16_32_P15(Q15(bnk->scaling[i]),mel[i]);
    */
 #endif
 }

-void filterbank_compute_psd16(FilterBank *bank, spx_word16_t *mel, spx_word16_t
*ps)
+void filterbank_compute_psd16(FilterBank *bnk, spx_word16_t *mel, spx_word16_t
*ps)
 {
    int i;
-   for (i=0;i<bank->len;i++)
+   for (i=0;i<bnk->len;i++)
    {
       spx_word32_t tmp;
       int id1, id2;
-      id1 = bank->bank_left[i];
-      id2 = bank->bank_right[i];
-      tmp = MULT16_16(mel[id1],bank->filter_left[i]);
-      tmp += MULT16_16(mel[id2],bank->filter_right[i]);
+      id1 = bnk->bank_left[i];
+      id2 = bnk->bank_right[i];
+      tmp = MULT16_16(mel[id1],bnk->filter_left[i]);
+      tmp += MULT16_16(mel[id2],bnk->filter_right[i]);
       ps[i] = EXTRACT16(PSHR32(tmp,15));
    }
 }


 #ifndef FIXED_POINT
-void filterbank_compute_bank(FilterBank *bank, float *ps, float *mel)
+void filterbank_compute_bank(FilterBank *bnk, float *ps, float *mel)
 {
    int i;
-   for (i=0;i<bank->nb_banks;i++)
+   for (i=0;i<bnk->nb_banks;i++)
       mel[i] = 0;

-   for (i=0;i<bank->len;i++)
+   for (i=0;i<bnk->len;i++)
    {
-      int id = bank->bank_left[i];
-      mel[id] += bank->filter_left[i]*ps[i];
-      id = bank->bank_right[i];
-      mel[id] += bank->filter_right[i]*ps[i];
+      int id = bnk->bank_left[i];
+      mel[id] += bnk->filter_left[i]*ps[i];
+      id = bnk->bank_right[i];
+      mel[id] += bnk->filter_right[i]*ps[i];
    }
-   for (i=0;i<bank->nb_banks;i++)
-      mel[i] *= bank->scaling[i];
+   for (i=0;i<bnk->nb_banks;i++)
+      mel[i] *= bnk->scaling[i];
 }

-void filterbank_compute_psd(FilterBank *bank, float *mel, float *ps)
+void filterbank_compute_psd(FilterBank *bnk, float *mel, float *ps)
 {
    int i;
-   for (i=0;i<bank->len;i++)
+   for (i=0;i<bnk->len;i++)
    {
-      int id = bank->bank_left[i];
-      ps[i] = mel[id]*bank->filter_left[i];
-      id = bank->bank_right[i];
-      ps[i] += mel[id]*bank->filter_right[i];
+      int id = bnk->bank_left[i];
+      ps[i] = mel[id]*bnk->filter_left[i];
+      id = bnk->bank_right[i];
+      ps[i] += mel[id]*bnk->filter_right[i];
    }
 }

-void filterbank_psy_smooth(FilterBank *bank, float *ps, float *mask)
+void filterbank_psy_smooth(FilterBank *bnk, float *ps, float *mask)
 {
    /* Low freq slope: 14 dB/Bark*/
    /* High freq slope: 9 dB/Bark*/
@@ -211,13 +211,13 @@
    float decay_low = 0.34145f;
    float decay_high = 0.50119f;
    filterbank_compute_bank(bank, ps, bark);
-   for (i=1;i<bank->nb_banks;i++)
+   for (i=1;i<bnk->nb_banks;i++)
    {
       /*float decay_high = 13-1.6*log10(bark[i-1]);
       decay_high = pow(10,(-decay_high/30.f));*/
       bark[i] = bark[i] + decay_high*bark[i-1];
    }
-   for (i=bank->nb_banks-2;i>=0;i--)
+   for (i=bnk->nb_banks-2;i>=0;i--)
    {
       bark[i] = bark[i] + decay_low*bark[i+1];
    }