[xiph-commits] r10631 - trunk/speex/libspeex
jm at svn.xiph.org
jm at svn.xiph.org
Sun Dec 18 04:02:30 PST 2005
Author: jm
Date: 2005-12-18 04:02:28 -0800 (Sun, 18 Dec 2005)
New Revision: 10631
Modified:
trunk/speex/libspeex/mdf.c
Log:
converted initial adaptation rate
Modified: trunk/speex/libspeex/mdf.c
===================================================================
--- trunk/speex/libspeex/mdf.c 2005-12-18 02:49:46 UTC (rev 10630)
+++ trunk/speex/libspeex/mdf.c 2005-12-18 12:02:28 UTC (rev 10631)
@@ -82,7 +82,7 @@
int M;
int cancel_count;
int adapted;
- float sum_adapt;
+ spx_word32_t sum_adapt;
spx_word16_t *e;
spx_word16_t *x;
spx_word16_t *X;
@@ -311,10 +311,11 @@
spx_word32_t Syy,See;
spx_word16_t leak_estimate;
spx_word16_t ss, ss_1;
- float adapt_rate=0;
spx_float_t Pey = FLOAT_ONE, Pyy=FLOAT_ONE;
spx_float_t alpha;
float RER;
+ spx_word32_t tmp32;
+ spx_word16_t M_1;
N = st->window_size;
M = st->M;
@@ -322,9 +323,11 @@
#ifdef FIXED_POINT
ss=DIV32_16(11469,M);
ss_1 = SUB16(32767,ss);
+ M_1 = DIV32_16(32767,M);
#else
ss=.35/M;
ss_1 = 1-ss;
+ M_1 = 1.f/M;
#endif
/* Copy input data to buffer */
@@ -387,6 +390,7 @@
/* Compute a bunch of correlations */
See = inner_prod(st->e+st->frame_size, st->e+st->frame_size, st->frame_size);
+ See = ADD32(See, SHR32(10000,6));
Syy = inner_prod(st->y+st->frame_size, st->y+st->frame_size, st->frame_size);
/* Convert error to frequency domain */
@@ -404,6 +408,7 @@
for (j=0;j<=st->frame_size;j++)
st->power[j] = MULT16_32_Q15(ss_1,st->power[j]) + 1 + MULT16_32_Q15(ss,st->Xf[j]);
+ /* Compute filtered spectra and (cross-)correlations */
for (j=st->frame_size;j>=0;j--)
{
spx_float_t Eh, Yh;
@@ -420,22 +425,23 @@
#endif
}
- spx_word32_t tmp;
- tmp = MULT16_32_Q15(QCONST16(.05,15),Syy);
- if (tmp > MULT16_32_Q15(QCONST16(.008,15),See))
- tmp = MULT16_32_Q15(QCONST16(.008,15),See);
- alpha = FLOAT_DIV32(tmp, SHR(10000,6)+See);
+ /* Compute correlation updatete rate */
+ tmp32 = MULT16_32_Q15(QCONST16(.05,15),Syy);
+ if (tmp32 > MULT16_32_Q15(QCONST16(.008,15),See))
+ tmp32 = MULT16_32_Q15(QCONST16(.008,15),See);
+ alpha = FLOAT_DIV32(tmp32, See);
spx_float_t alpha_1 = FLOAT_SUB(FLOAT_ONE, alpha);
- /*printf ("%f %f\n", REALFLOAT(alpha), REALFLOAT(alpha_1));*/
+ /* Update correlations (recursive average) */
st->Pey = FLOAT_ADD(FLOAT_MULT(alpha_1,st->Pey) , FLOAT_MULT(alpha,Pey));
st->Pyy = FLOAT_ADD(FLOAT_MULT(alpha_1,st->Pyy) , FLOAT_MULT(alpha,Pyy));
- /* We don't really hope to get better than 33 dB attenuation anyway */
if (FLOAT_LT(st->Pyy, FLOAT_ONE))
st->Pyy = FLOAT_ONE;
+ /* We don't really hope to get better than 33 dB (MIN_LEAK-3dB) attenuation anyway */
if (FLOAT_LT(st->Pey, FLOAT_MULT(MIN_LEAK,st->Pyy)))
st->Pey = FLOAT_MULT(MIN_LEAK,st->Pyy);
if (FLOAT_GT(st->Pey, st->Pyy))
st->Pey = st->Pyy;
+ /* leak_estimate is the limear regression result */
leak_estimate = FLOAT_EXTRACT16(FLOAT_SHL(FLOAT_DIVU(st->Pey, st->Pyy),14));
if (leak_estimate > 16383)
leak_estimate = 32767;
@@ -444,24 +450,18 @@
/*printf ("%f\n", leak_estimate);*/
- RER = 3.*MULT16_32_Q15(leak_estimate,Syy) / (SHR(10000,6)+See);
+ RER = 3.*MULT16_32_Q15(leak_estimate,Syy) / See;
if (RER > .5)
RER = .5;
/* We consider that the filter has had minimal adaptation if the following is true*/
- if (!st->adapted && st->sum_adapt > 1)
+ if (!st->adapted && st->sum_adapt > QCONST32(1,15))
{
st->adapted = 1;
}
if (st->adapted)
{
- spx_word16_t M_1;
-#ifdef FIXED_POINT
- M_1 = DIV32_16(32767,M);
-#else
- M_1 = 1.f/M;
-#endif
for (i=0;i<=st->frame_size;i++)
{
spx_word32_t r, e;
@@ -481,20 +481,22 @@
}
} else {
spx_word32_t Sxx;
-
+ spx_word16_t adapt_rate=0;
+
Sxx = inner_prod(st->x+st->frame_size, st->x+st->frame_size, st->frame_size);
/* Temporary adaption rate if filter is not adapted correctly */
- adapt_rate = .15f * Sxx / (SHR(10000,6)+See);
- if (adapt_rate>.25)
- adapt_rate = .25;
- adapt_rate /= M;
+
+ tmp32 = MULT16_32_Q15(QCONST16(.15f, 15), Sxx);
+ if (Sxx > SHR32(See,2))
+ Sxx = SHR32(See,2);
+ adapt_rate = FLOAT_EXTRACT16(FLOAT_SHL(FLOAT_DIV32(MULT16_32_Q15(M_1,Sxx), See),15));
for (i=0;i<=st->frame_size;i++)
- st->power_1[i] = FLOAT_DIV32(WEIGHT_SCALING*adapt_rate,ADD32(10,st->power[i]));
+ st->power_1[i] = FLOAT_SHL(FLOAT_DIV32(EXTEND32(adapt_rate),ADD32(st->power[i],10)),WEIGHT_SHIFT-15);
/* How much have we adapted so far? */
- st->sum_adapt += adapt_rate;
+ st->sum_adapt = ADD32(st->sum_adapt,adapt_rate);
}
/* Compute weight gradient */
for (j=0;j<M;j++)
More information about the commits
mailing list