Skip to content

Commit

Permalink
Merge pull request #76 from joseph-yiu/main
Browse files Browse the repository at this point in the history
AudioMark improvements on KWS unit test, floating-point handling, documentation.
  • Loading branch information
joseph-yiu authored Jun 14, 2024
2 parents 9ea7506 + c151b31 commit 6e31df2
Show file tree
Hide file tree
Showing 21 changed files with 791 additions and 706 deletions.
1,008 changes: 520 additions & 488 deletions README.md
100644 → 100755

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion lib/speexdsp/include/speex/speex_echo.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ extern "C" {
#endif

#ifndef M_PI
#define M_PI 3.14159265358979323846
#define M_PI 3.14159265358979323846f
#endif

#ifdef FIXED_POINT
Expand Down
3 changes: 2 additions & 1 deletion lib/speexdsp/libspeexdsp/arch.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ typedef float spx_word32_t;
#define VERY_LARGE16 1e15f
#define Q15_ONE ((spx_word16_t)1.f)

#define Q0CONST(x) ((float)(x))
#define QCONST16(x,bits) (x)
#define QCONST32(x,bits) (x)

Expand Down Expand Up @@ -203,7 +204,7 @@ typedef float spx_word32_t;
#define PDIV32(a,b) (((spx_word32_t)(a))/(spx_word32_t)(b))

#define WORD2INT(x) ((x) < -32767.5f ? -32768 : \
((x) > 32766.5f ? 32767 : (spx_int16_t)floor(.5 + (x))))
((x) > 32766.5f ? 32767 : (spx_int16_t)floorf(.5f + (x))))
#endif


Expand Down
4 changes: 2 additions & 2 deletions lib/speexdsp/libspeexdsp/filterbank.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,10 @@
#define toBARK(n) (MULT16_16(26829,spx_atan(SHR32(MULT16_16(97,n),2))) + MULT16_16(4588,spx_atan(MULT16_32_Q15(20,MULT16_16(n,n)))) + MULT16_16(3355,n))

#else
#define toBARK(n) (13.1f*atan(.00074f*(n))+2.24f*atan((n)*(n)*1.85e-8f)+1e-4f*(n))
#define toBARK(n) (13.1f*atanf(.00074f*(n))+2.24f*atanf((n)*(n)*1.85e-8f)+1e-4f*(n))
#endif

#define toMEL(n) (2595.f*log10(1.f+(n)/700.f))
#define toMEL(n) (2595.f*log10f(1.f+(n)/700.f))

/* Optimized filter bank routines */
#include "filterbank_opt.c"
Expand Down
4 changes: 2 additions & 2 deletions lib/speexdsp/libspeexdsp/fixed_debug.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@
extern long long spx_mips;
#define MIPS_INC spx_mips++,

#define QCONST16(x,bits) ((spx_word16_t)(.5+(x)*(((spx_word32_t)1)<<(bits))))
#define QCONST32(x,bits) ((spx_word32_t)(.5+(x)*(((spx_word32_t)1)<<(bits))))
#define QCONST16(x,bits) ((spx_word16_t)(.5f+(x)*(((spx_word32_t)1)<<(bits))))
#define QCONST32(x,bits) ((spx_word32_t)(.5f+(x)*(((spx_word32_t)1)<<(bits))))


#define VERIFY_SHORT(x) ((x)<=32767&&(x)>=-32768)
Expand Down
5 changes: 3 additions & 2 deletions lib/speexdsp/libspeexdsp/fixed_generic.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,9 @@
#ifndef FIXED_GENERIC_H
#define FIXED_GENERIC_H

#define QCONST16(x,bits) ((spx_word16_t)(.5+(x)*(((spx_word32_t)1)<<(bits))))
#define QCONST32(x,bits) ((spx_word32_t)(.5+(x)*(((spx_word32_t)1)<<(bits))))
#define Q0CONST(x) (x)
#define QCONST16(x,bits) ((spx_word16_t)(.5f+(x)*(((spx_word32_t)1)<<(bits))))
#define QCONST32(x,bits) ((spx_word32_t)(.5f+(x)*(((spx_word32_t)1)<<(bits))))

#define NEG16(x) (-(x))
#define NEG32(x) (-(x))
Expand Down
10 changes: 5 additions & 5 deletions lib/speexdsp/libspeexdsp/math_approx.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,11 @@

#ifndef FIXED_POINT

#define spx_sqrt sqrt
#define spx_acos acos
#define spx_exp exp
#define spx_cos_norm(x) (cos((.5f*M_PI)*(x)))
#define spx_atan atan
#define spx_sqrt sqrtf
#define spx_acos acosf
#define spx_exp expf
#define spx_cos_norm(x) (cosf((.5f*M_PI)*(x)))
#define spx_atan atanf

/** Generate a pseudo-random number */
static inline spx_word16_t speex_rand(spx_word16_t std, spx_int32_t *seed)
Expand Down
60 changes: 30 additions & 30 deletions lib/speexdsp/libspeexdsp/mdf.c
Original file line number Diff line number Diff line change
Expand Up @@ -181,9 +181,9 @@ static inline void filter_dc_notch16(const spx_int16_t *in, spx_word16_t radius,
int i;
spx_word16_t den2;
#ifdef FIXED_POINT
den2 = MULT16_16_Q15(radius,radius) + MULT16_16_Q15(QCONST16(.7,15),MULT16_16_Q15(32767-radius,32767-radius));
den2 = MULT16_16_Q15(radius,radius) + MULT16_16_Q15(QCONST16(.7f,15),MULT16_16_Q15(32767-radius,32767-radius));
#else
den2 = radius*radius + .7*(1-radius)*(1-radius);
den2 = radius*radius + .7f*(1.0f-radius)*(1.0f-radius);
#endif
/*printf ("%d %d %d %d %d %d\n", num[0], num[1], num[2], den[0], den[1], den[2]);*/
for (i=0;i<len;i++)
Expand All @@ -193,7 +193,7 @@ static inline void filter_dc_notch16(const spx_int16_t *in, spx_word16_t radius,
#ifdef FIXED_POINT
mem[0] = mem[1] + SHL32(SHL32(-EXTEND32(vin),15) + MULT16_32_Q15(radius,vout),1);
#else
mem[0] = mem[1] + 2*(-vin + radius*vout);
mem[0] = mem[1] + 2.0f*(-vin + radius*vout);
#endif
mem[1] = SHL32(EXTEND32(vin),15) - MULT16_32_Q15(den2,vout);
out[i] = SATURATE32(PSHR32(MULT16_32_Q15(radius,vout),15),32767);
Expand Down Expand Up @@ -485,7 +485,7 @@ EXPORT SpeexEchoState *speex_echo_state_init_mc(int frame_size, int filter_lengt
}
#else
for (i=0;i<N;i++)
st->window[i] = .5-.5*cos(2*M_PI*i/N);
st->window[i] = .5f-.5f*cosf(2*M_PI*i/N);
#endif
for (i=0;i<=st->frame_size;i++)
st->power_1[i] = FLOAT_ONE;
Expand All @@ -494,8 +494,8 @@ EXPORT SpeexEchoState *speex_echo_state_init_mc(int frame_size, int filter_lengt
{
spx_word32_t sum = 0;
/* Ratio of ~10 between adaptation rate of first and last block */
spx_word16_t decay = SHR32(spx_exp(NEG16(DIV32_16(QCONST16(2.4,11),M))),1);
st->prop[0] = QCONST16(.7, 15);
spx_word16_t decay = SHR32(spx_exp(NEG16(DIV32_16(QCONST16(2.4f,11),M))),1);
st->prop[0] = QCONST16(.7f, 15);
sum = EXTEND32(st->prop[0]);
for (i=1;i<M;i++)
{
Expand All @@ -511,13 +511,13 @@ EXPORT SpeexEchoState *speex_echo_state_init_mc(int frame_size, int filter_lengt
st->memX = (spx_word16_t*)speex_alloc(K*sizeof(spx_word16_t));
st->memD = (spx_word16_t*)speex_alloc(C*sizeof(spx_word16_t));
st->memE = (spx_word16_t*)speex_alloc(C*sizeof(spx_word16_t));
st->preemph = QCONST16(.9,15);
st->preemph = QCONST16(.9f,15);
if (st->sampling_rate<12000)
st->notch_radius = QCONST16(.9, 15);
st->notch_radius = QCONST16(.9f, 15);
else if (st->sampling_rate<24000)
st->notch_radius = QCONST16(.982, 15);
st->notch_radius = QCONST16(.982f, 15);
else
st->notch_radius = QCONST16(.992, 15);
st->notch_radius = QCONST16(.992f, 15);

st->notch_mem = (spx_mem_t*)speex_alloc(2*C*sizeof(spx_mem_t));
st->adapted = 0;
Expand Down Expand Up @@ -724,8 +724,8 @@ EXPORT void speex_echo_cancellation(SpeexEchoState *st, const spx_int16_t *in, c
ss=DIV32_16(11469,M);
ss_1 = SUB16(32767,ss);
#else
ss=.35/M;
ss_1 = 1-ss;
ss=.35f/M;
ss_1 = 1.0f-ss;
#endif

for (chan = 0; chan < C; chan++)
Expand Down Expand Up @@ -1103,7 +1103,7 @@ EXPORT void speex_echo_cancellation(SpeexEchoState *st, const spx_int16_t *in, c
/* Do some sanity check */
if (!(Syy>=0 && Sxx>=0 && See >= 0)
#ifndef FIXED_POINT
|| !(Sff < N*1e9 && Syy < N*1e9 && Sxx < N*1e9)
|| !(Sff < N*1e9f && Syy < N*1e9f && Sxx < N*1e9f)
#endif
)
{
Expand Down Expand Up @@ -1142,7 +1142,7 @@ EXPORT void speex_echo_cancellation(SpeexEchoState *st, const spx_int16_t *in, c
#ifndef OVERRIDE_MDF_SMOOTH_FE_NRG
/* Smooth far end energy estimate over time */
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]);
st->power[j] = MULT16_32_Q15(ss_1,st->power[j]) + Q0CONST(1) + MULT16_32_Q15(ss,st->Xf[j]);
#else
smooth_fe_nrg(st->power, ss_1, st->Xf, ss, st->power, st->frame_size + 1);
#endif
Expand Down Expand Up @@ -1211,12 +1211,12 @@ EXPORT void speex_echo_cancellation(SpeexEchoState *st, const spx_int16_t *in, c
tmp32 = SHR32(See,1);
RER = FLOAT_EXTRACT16(FLOAT_SHL(FLOAT_DIV32(tmp32,See),15));
#else
RER = (.0001*Sxx + 3.*MULT16_32_Q15(st->leak_estimate,Syy)) / See;
RER = (.0001f*Sxx + 3.0f*MULT16_32_Q15(st->leak_estimate,Syy)) / See;
/* Check for y in e (lower bound on RER) */
if (RER < Sey*Sey/(1+See*Syy))
RER = Sey*Sey/(1+See*Syy);
if (RER > .5)
RER = .5;
if (RER < Sey*Sey/(1.0f+See*Syy))
RER = Sey*Sey/(1.0f+See*Syy);
if (RER > .5f)
RER = .5f;
#endif

/* We consider that the filter has had minimal adaptation if the following is true*/
Expand All @@ -1239,12 +1239,12 @@ EXPORT void speex_echo_cancellation(SpeexEchoState *st, const spx_int16_t *in, c
if (r>SHR32(e,1))
r = SHR32(e,1);
#else
if (r>.5*e)
r = .5*e;
if (r>.5f*e)
r = .5f*e;
#endif
r = MULT16_32_Q15(QCONST16(.7,15),r) + MULT16_32_Q15(QCONST16(.3,15),(spx_word32_t)(MULT16_32_Q15(RER,e)));
r = MULT16_32_Q15(QCONST16(.7f,15),r) + MULT16_32_Q15(QCONST16(.3f,15),(spx_word32_t)(MULT16_32_Q15(RER,e)));
/*st->power_1[i] = adapt_rate*r/(e*(1+st->power[i]));*/
st->power_1[i] = FLOAT_SHL(FLOAT_DIV32_FLOAT(r,FLOAT_MUL32U(e,st->power[i]+10)),WEIGHT_SHIFT+16);
st->power_1[i] = FLOAT_SHL(FLOAT_DIV32_FLOAT(r,FLOAT_MUL32U(e,st->power[i]+Q0CONST(10))),WEIGHT_SHIFT+16);
}
#else
mdf_nominal_learning_rate_calc(st->Rf, st->power, st->Yf, st->power_1, st->leak_estimate, RER, st->frame_size + 1);
Expand All @@ -1260,14 +1260,14 @@ EXPORT void speex_echo_cancellation(SpeexEchoState *st, const spx_int16_t *in, c
if (tmp32 > SHR32(See,2))
tmp32 = SHR32(See,2);
#else
if (tmp32 > .25*See)
tmp32 = .25*See;
if (tmp32 > .25f*See)
tmp32 = .25f*See;
#endif
adapt_rate = FLOAT_EXTRACT16(FLOAT_SHL(FLOAT_DIV32(tmp32, See),15));
}
#ifndef OVERRIDE_MDF_CONVERG_LEARN_RATE_CALC
for (i=0;i<=st->frame_size;i++)
st->power_1[i] = FLOAT_SHL(FLOAT_DIV32(EXTEND32(adapt_rate),ADD32(st->power[i],10)),WEIGHT_SHIFT+1);
st->power_1[i] = FLOAT_SHL(FLOAT_DIV32(EXTEND32(adapt_rate),ADD32(st->power[i],Q0CONST(10))),WEIGHT_SHIFT+1);
#else
mdf_non_adapt_learning_rate_calc(st->power, st->power_1, adapt_rate, st->frame_size + 1);
#endif
Expand Down Expand Up @@ -1328,7 +1328,7 @@ void speex_echo_get_residual(SpeexEchoState *st, spx_word32_t *residual_echo, in
else
leak2 = SHL16(st->leak_estimate, 1);
#else
if (st->leak_estimate>.5)
if (st->leak_estimate>.5f)
leak2 = 1;
else
leak2 = 2*st->leak_estimate;
Expand Down Expand Up @@ -1362,11 +1362,11 @@ EXPORT int speex_echo_ctl(SpeexEchoState *st, int request, void *ptr)
st->beta_max = (.5f*st->frame_size)/st->sampling_rate;
#endif
if (st->sampling_rate<12000)
st->notch_radius = QCONST16(.9, 15);
st->notch_radius = QCONST16(.9f, 15);
else if (st->sampling_rate<24000)
st->notch_radius = QCONST16(.982, 15);
st->notch_radius = QCONST16(.982f, 15);
else
st->notch_radius = QCONST16(.992, 15);
st->notch_radius = QCONST16(.992f, 15);
break;
case SPEEX_ECHO_GET_SAMPLING_RATE:
(*(int*)ptr) = st->sampling_rate;
Expand Down
18 changes: 9 additions & 9 deletions lib/speexdsp/libspeexdsp/mdf_opt_generic.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@ static void filter_dc_notch16(const spx_int16_t * in, spx_word16_t radius, spx_w
int i;
spx_word16_t den2;
#ifdef FIXED_POINT
den2 = MULT16_16_Q15(radius, radius) + MULT16_16_Q15(QCONST16(.7, 15), MULT16_16_Q15(32767 - radius, 32767 - radius));
den2 = MULT16_16_Q15(radius, radius) + MULT16_16_Q15(QCONST16(.7f, 15), MULT16_16_Q15(32767 - radius, 32767 - radius));
#else
den2 = radius * radius + .7 * (1 - radius) * (1 - radius);
den2 = radius * radius + .7f * (1.0f - radius) * (1.0f - radius);
#endif
/*printf ("%d %d %d %d %d %d\n", num[0], num[1], num[2], den[0], den[1], den[2]); */
for (i = 0; i < len; i++) {
Expand All @@ -56,7 +56,7 @@ static void filter_dc_notch16(const spx_int16_t * in, spx_word16_t radius, spx_w
#ifdef FIXED_POINT
mem[0] = mem[1] + SHL32(SHL32(-EXTEND32(vin), 15) + MULT16_32_Q15(radius, vout), 1);
#else
mem[0] = mem[1] + 2 * (-vin + radius * vout);
mem[0] = mem[1] + 2.0f * (-vin + radius * vout);
#endif
mem[1] = SHL32(EXTEND32(vin), 15) - MULT16_32_Q15(den2, vout);
out[i] = SATURATE32(PSHR32(MULT16_32_Q15(radius, vout), 15), 32767);
Expand Down Expand Up @@ -415,7 +415,7 @@ static void smooth_fe_nrg(spx_word32_t * in1, spx_word16_t c1, spx_word32_t * in
int j;

for (j = 0; j <= frame_size; j++)
pDst[j] = MULT16_32_Q15(c1, in1[j]) + 1 + MULT16_32_Q15(c2, in2[j]);
pDst[j] = MULT16_32_Q15(c1, in1[j]) + Q0CONST(1) + MULT16_32_Q15(c2, in2[j]);
}
#endif

Expand Down Expand Up @@ -458,12 +458,12 @@ static void mdf_nominal_learning_rate_calc(spx_word32_t * pRf, spx_word32_t * po
if (r > SHR32(e, 1))
r = SHR32(e, 1);
#else
if (r > .5 * e)
r = .5 * e;
if (r > .5f * e)
r = .5f * e;
#endif
r = MULT16_32_Q15(QCONST16(.7, 15), r) + MULT16_32_Q15(QCONST16(.3, 15), (spx_word32_t) (MULT16_32_Q15(RER, e)));
r = MULT16_32_Q15(QCONST16(.7f, 15), r) + MULT16_32_Q15(QCONST16(.3f, 15), (spx_word32_t) (MULT16_32_Q15(RER, e)));
/*st->power_1[i] = adapt_rate*r/(e*(1+st->power[i])); */
power_1[i] = FLOAT_SHL(FLOAT_DIV32_FLOAT(r, FLOAT_MUL32U(e, power[i] + 10)), WEIGHT_SHIFT + 16);
power_1[i] = FLOAT_SHL(FLOAT_DIV32_FLOAT(r, FLOAT_MUL32U(e, power[i] + 10.f)), WEIGHT_SHIFT + 16);
}
}

Expand All @@ -475,7 +475,7 @@ static void mdf_non_adapt_learning_rate_calc(spx_word32_t * power, spx_float_t *
int i;

for (i = 0; i < frame_size; i++)
power_1[i] = FLOAT_SHL(FLOAT_DIV32(EXTEND32(adapt_rate), ADD32(power[i], 10)), WEIGHT_SHIFT + 1);
power_1[i] = FLOAT_SHL(FLOAT_DIV32(EXTEND32(adapt_rate), ADD32(power[i], Q0CONST(10))), WEIGHT_SHIFT + 1);
}

#endif
12 changes: 6 additions & 6 deletions lib/speexdsp/libspeexdsp/mdf_opt_helium.c
Original file line number Diff line number Diff line change
Expand Up @@ -733,8 +733,8 @@ VISIB_ATTR void mdf_nominal_learning_rate_calc(spx_word32_t * pRf, spx_word32_t
spx_word32_t * pYf, spx_float_t * power_1, spx_word16_t leak_estimate, spx_word16_t RER, uint16_t len)
{
int blockSize = len >> 2;
float32_t cst_0_7 = QCONST16(.7, 15);
float32_t cst_0_3 = QCONST16(.3, 15);
float32_t cst_0_7 = QCONST16(.7f, 15);
float32_t cst_0_3 = QCONST16(.3f, 15);

do {
float32x4_t vecYf = vld1q(pYf);
Expand Down Expand Up @@ -771,10 +771,10 @@ VISIB_ATTR void mdf_nominal_learning_rate_calc(spx_word32_t * pRf, spx_word32_t
r = MULT16_32_Q15(leak_estimate, SHL32(*pYf++, 3));
e = SHL32(*pRf++, 3) + 1;

if (r > .5 * e)
r = .5 * e;
if (r > .5f * e)
r = .5f * e;

r = MULT16_32_Q15(QCONST16(.7, 15), r) + MULT16_32_Q15(QCONST16(.3, 15), (spx_word32_t) (MULT16_32_Q15(RER, e)));
r = MULT16_32_Q15(QCONST16(.7f, 15), r) + MULT16_32_Q15(QCONST16(.3f, 15), (spx_word32_t) (MULT16_32_Q15(RER, e)));
/*st->power_1[i] = adapt_rate*r/(e*(1+st->power[i])); */
*power_1++ = FLOAT_SHL(FLOAT_DIV32_FLOAT(r, FLOAT_MUL32U(e, *power++ + 10)), WEIGHT_SHIFT + 16);
}
Expand Down Expand Up @@ -804,7 +804,7 @@ VISIB_ATTR void mdf_non_adapt_learning_rate_calc(spx_word32_t * power, spx_float

/* tail */
for (int i = 0; i <= (len & 3); i++) {
*power_1++ = FLOAT_SHL(FLOAT_DIV32(EXTEND32(adapt_rate), ADD32(*power++, 10)), WEIGHT_SHIFT + 1);
*power_1++ = FLOAT_SHL(FLOAT_DIV32(EXTEND32(adapt_rate), ADD32(*power++, Q0CONST(10))), WEIGHT_SHIFT + 1);
}
}

Expand Down
Loading

0 comments on commit 6e31df2

Please sign in to comment.