diff options
Diffstat (limited to '3rdparty/speex/tmv/mdf_tm.h')
-rw-r--r-- | 3rdparty/speex/tmv/mdf_tm.h | 1192 |
1 files changed, 0 insertions, 1192 deletions
diff --git a/3rdparty/speex/tmv/mdf_tm.h b/3rdparty/speex/tmv/mdf_tm.h deleted file mode 100644 index 0a6128e9..00000000 --- a/3rdparty/speex/tmv/mdf_tm.h +++ /dev/null @@ -1,1192 +0,0 @@ -/* Copyright (C) 2007 Hong Zhiqian */ -/** - @file mdf_tm.h - @author Hong Zhiqian - @brief Various compatibility routines for Speex (TriMedia version) -*/ -/* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - - Neither the name of the Xiph.org Foundation nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ -#include <ops/custom_defs.h> -#include "profile_tm.h" - -// shifted power spectrum to fftwrap.c so that optimisation can be shared between mdf.c and preprocess.c -#define OVERRIDE_POWER_SPECTRUM - -#ifdef FIXED_POINT - -#else - -#define OVERRIDE_FILTER_DC_NOTCH16 -void filter_dc_notch16( - const spx_int16_t * restrict in, - float radius, - float * restrict out, - int len, - float * restrict mem -) -{ - register int i; - register float den2, r1; - register float mem0, mem1; - - FILTERDCNOTCH16_START(); - - r1 = 1 - radius; - den2 = (radius * radius) + (0.7 * r1 * r1); - mem0 = mem[0]; - mem1 = mem[1]; - -#if (TM_UNROLL && TM_UNROLL_FILTERDCNOTCH16) -#pragma TCS_unroll=4 -#pragma TCS_unrollexact=1 -#endif - for ( i=0 ; i<len ; ++i ) - { - register float vin = in[i]; - register float vout = mem0 + vin; - register float rvout = radius * vout; - - mem0 = mem1 + 2 * (-vin + rvout); - mem1 = vin - (den2 * vout); - - out[i] = rvout; - } -#if (TM_UNROLL && TM_UNROLL_FILTERDCNOTCH16) -#pragma TCS_unrollexact=0 -#pragma TCS_unroll=0 -#endif - - mem[0] = mem0; - mem[1] = mem1; - - FILTERDCNOTCH16_STOP(); -} - -#define OVERRIDE_MDF_INNER_PROD -float mdf_inner_prod( - const float * restrict x, - const float * restrict y, - int len -) -{ - register float sum = 0; - - MDFINNERPROD_START(); - - len >>= 1; - -#if (TM_UNROLL && TM_UNROLL_MDFINNERPRODUCT) -#pragma TCS_unroll=4 -#pragma TCS_unrollexact=1 -#endif - while(len--) - { - register float acc0, acc1; - - acc0 = (*x++) * (*y++); - acc1 = (*x++) * (*y++); - - sum += acc0 + acc1; - } -#if (TM_UNROLL && TM_UNROLL_MDFINNERPRODUCT) -#pragma TCS_unrollexact=0 -#pragma TCS_unroll=0 -#endif - - MDFINNERPROD_STOP(); - - return sum; -} - -#define OVERRIDE_SPECTRAL_MUL_ACCUM -void spectral_mul_accum( - const float * restrict X, - const float * restrict Y, - float * restrict acc, - int N, int M -) -{ - register int i, j; - register float Xi, Yi, Xii, Yii; - register int _N; - - SPECTRALMULACCUM_START(); - - acc[0] = X[0] * Y[0]; - _N = N-1; - - for ( i=1 ; i<_N ; i+=2 ) - { - Xi = X[i]; - Yi = Y[i]; - Xii = X[i+1]; - Yii = Y[i+1]; - - acc[i] = (Xi * Yi - Xii * Yii); - acc[i+1]= (Xii * Yi + Xi * Yii); - } - - acc[_N] = X[_N] * Y[_N]; - - for ( j=1,X+=N,Y+=N ; j<M ; j++ ) - { - acc[0] += X[0] * Y[0]; - - for ( i=1 ; i<N-1 ; i+=2 ) - { - Xi = X[i]; - Yi = Y[i]; - Xii = X[i+1]; - Yii = Y[i+1]; - - acc[i] += (Xi * Yi - Xii * Yii); - acc[i+1]+= (Xii * Yi + Xi * Yii); - } - - acc[_N] += X[_N] * Y[_N]; - X += N; - Y += N; - } - - SPECTRALMULACCUM_STOP(); -} - -#define OVERRIDE_WEIGHTED_SPECTRAL_MUL_CONJ -void weighted_spectral_mul_conj( - const float * restrict w, - const float p, - const float * restrict X, - const float * restrict Y, - float * restrict prod, - int N -) -{ - register int i, j; - register int _N; - - WEIGHTEDSPECTRALMULCONJ_START(); - - prod[0] = p * w[0] * X[0] * Y[0]; - _N = N-1; - - for (i=1,j=1;i<_N;i+=2,j++) - { - register float W; - register float Xi, Yi, Xii, Yii; - - Xi = X[i]; - Yi = Y[i]; - Xii = X[i+1]; - Yii = Y[i+1]; - W = p * w[j]; - - - prod[i] = W * (Xi * Yi + Xii * Yii); - prod[i+1]= W * (Xi * Yii - Xii * Yi); - } - - prod[_N] = p * w[j] * X[_N] * Y[_N]; - - WEIGHTEDSPECTRALMULCONJ_STOP(); -} - -#define OVERRIDE_MDF_ADJUST_PROP -void mdf_adjust_prop( - const float * restrict W, - int N, - int M, - float * restrict prop -) -{ - register int i, j; - register float max_sum = 1; - register float prop_sum = 1; - - MDFADJUSTPROP_START(); - - for ( i=0 ; i<M ; ++i ) - { - register float tmp = 1; - register int k = i * N; - register int l = k + N; - register float propi; - -#if (TM_UNROLL && TM_UNROLL_MDFADJUSTPROP) -#pragma TCS_unroll=4 -#pragma TCS_unrollexact=1 -#endif - for ( j=k ; j<l ; ++j ) - { - register float wi = W[j]; - - tmp += wi * wi; - } -#if (TM_UNROLL && TM_UNROLL_MDFADJUSTPROP) -#pragma TCS_unrollexact=0 -#pragma TCS_unroll=0 -#endif - - propi = spx_sqrt(tmp); - prop[i]= propi; - max_sum= fmux(propi > max_sum, propi, max_sum); - } - - for ( i=0 ; i<M ; ++i ) - { - register float propi = prop[i]; - - propi += .1f * max_sum; - prop_sum += propi; - prop[i] = propi; - } - - prop_sum = 0.99f / prop_sum; - for ( i=0 ; i<M ; ++i ) - { prop[i] = prop_sum * prop[i]; - } - - MDFADJUSTPROP_STOP(); -} - - -#define OVERRIDE_SPEEX_ECHO_GET_RESIDUAL -void speex_echo_get_residual( - SpeexEchoState * restrict st, - float * restrict residual_echo, - int len -) -{ - register int i; - register float leak2, leake; - register int N; - register float * restrict window; - register float * restrict last_y; - register float * restrict y; - - SPEEXECHOGETRESIDUAL_START(); - - window = st->window; - last_y = st->last_y; - y = st->y; - N = st->window_size; - - -#if (TM_UNROLL && TM_UNROLL_SPEEXECHOGETRESIDUAL) -#pragma TCS_unroll=4 -#pragma TCS_unrollexact=1 -#endif - for (i=0;i<N;i++) - { y[i] = window[i] * last_y[i]; - } -#if (TM_UNROLL && TM_UNROLL_SPEEXECHOGETRESIDUAL) -#pragma TCS_unrollexact=0 -#pragma TCS_unroll=0 -#endif - - spx_fft(st->fft_table, st->y, st->Y); - power_spectrum(st->Y, residual_echo, N); - - leake = st->leak_estimate; - leak2 = fmux(leake > .5, 1, 2 * leake); - N = st->frame_size; - -#if (TM_UNROLL && TM_UNROLL_SPEEXECHOGETRESIDUAL) -#pragma TCS_unroll=4 -#pragma TCS_unrollexact=1 -#endif - for ( i=0 ; i<N ; ++i ) - { residual_echo[i] *= leak2; - } -#if (TM_UNROLL && TM_UNROLL_SPEEXECHOGETRESIDUAL) -#pragma TCS_unrollexact=0 -#pragma TCS_unroll=0 -#endif - - residual_echo[N] *= leak2; - -#ifndef NO_REMARK - (void)len; -#endif - - SPEEXECHOGETRESIDUAL_STOP(); -} -#endif - - -void mdf_preemph( - SpeexEchoState * restrict st, - spx_word16_t * restrict x, - const spx_int16_t * restrict far_end, - int framesize -) -{ - register spx_word16_t preemph = st->preemph; - register spx_word16_t memX = st->memX; - register spx_word16_t memD = st->memD; - register spx_word16_t * restrict input = st->input; - register int i; -#ifdef FIXED_POINT - register int saturated = st->saturated; -#endif - -#if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION) -#pragma TCS_unroll=4 -#pragma TCS_unrollexact=1 -#endif - for ( i=0 ; i<framesize ; ++i ) - { - register spx_int16_t far_endi = far_end[i]; - register spx_word32_t tmp32; - register spx_word16_t inputi = input[i]; - - tmp32 = SUB32(EXTEND32(far_endi), EXTEND32(MULT16_16_P15(preemph,memX))); - -#ifdef FIXED_POINT - saturated = mux(iabs(tmp32) > 32767, M+1, saturated); - tmp32 = iclipi(tmp32,32767); -#endif - - x[i] = EXTRACT16(tmp32); - memX = far_endi; - tmp32 = SUB32(EXTEND32(inputi), EXTEND32(MULT16_16_P15(preemph, memD))); - -#ifdef FIXED_POINT - saturated = mux( ((tmp32 > 32767) && (saturated == 0)), 1, - mux( ((tmp32 <-32767) && (saturated == 0)), 1, saturated )); - tmp32 = iclipi(tmp32,32767); -#endif - memD = inputi; - input[i] = tmp32; - } -#if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION) -#pragma TCS_unrollexact=0 -#pragma TCS_unroll=0 -#endif - - st->memD = memD; - st->memX = memX; - -#ifdef FIXED_POINT - st->saturated = saturated; -#endif -} - -void mdf_sub( - spx_word16_t * restrict dest, - const spx_word16_t * restrict src1, - const spx_word16_t * restrict src2, - int framesize -) -{ - register int i; - -#if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION) -#pragma TCS_unroll=4 -#pragma TCS_unrollexact=1 -#endif - -#ifdef FIXED_POINT - for ( i=0,framesize<<=1 ; i<framesize ; i+=4 ) - { register int src1i, src2i, desti; - - src1i = ld32d(src1,i); - src2i = ld32d(src2,i); - desti = dspidualsub(src1i,src2i); - st32d(i, dest, desti); - } -#else - for ( i=0 ; i<framesize ; ++i ) - { dest[i] = src1[i] - src2[i]; - } -#endif - -#if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION) -#pragma TCS_unrollexact=0 -#pragma TCS_unroll=0 -#endif -} - -void mdf_sub_int( - spx_word16_t * restrict dest, - const spx_int16_t * restrict src1, - const spx_int16_t * restrict src2, - int framesize -) -{ - register int i, j; - -#if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION) -#pragma TCS_unroll=4 -#pragma TCS_unrollexact=1 -#endif - -#ifdef FIXED_POINT - for ( i=0,framesize<<=1 ; i<framesize ; i+=4 ) - { register int src1i, src2i, desti; - - src1i = ld32d(src1,i); - src2i = ld32d(src2,i); - desti = dspidualsub(src1i,src2i); - st32d(i, dest, desti); - } -#else - for ( i=0,j=0 ; i<framesize ; i+=2,++j ) - { register int src1i, src2i, desti; - - - src1i = ld32d(src1,j); - src2i = ld32d(src2,j); - desti = dspidualsub(src1i,src2i); - - dest[i] = sex16(desti); - dest[i+1] = asri(16,desti); - } -#endif - -#if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION) -#pragma TCS_unrollexact=0 -#pragma TCS_unroll=0 -#endif -} - -void mdf_compute_weight_gradient( - SpeexEchoState * restrict st, - spx_word16_t * restrict X, - int N, - int M -) -{ - register int i, j; - register spx_word32_t * restrict PHI = st->PHI; - - for (j=M-1;j>=0;j--) - { - register spx_word32_t * restrict W = &(st->W[j*N]); - - weighted_spectral_mul_conj( - st->power_1, - FLOAT_SHL(PSEUDOFLOAT(st->prop[j]),-15), - &X[(j+1)*N], - st->E, - st->PHI, - N); -#if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION) -#pragma TCS_unroll=4 -#pragma TCS_unrollexact=1 -#endif - for (i=0;i<N;i++) - { W[i] = ADD32(W[i],PHI[i]); - } -#if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION) -#pragma TCS_unrollexact=0 -#pragma TCS_unroll=0 -#endif - } -} - -void mdf_update_weight( - SpeexEchoState * restrict st, - int N, - int M, - int framesize -) -{ - register int j; - register int cancel_count = st->cancel_count; - register spx_word16_t * restrict wtmp = st->wtmp; -#ifdef FIXED_POINT - register spx_word16_t * restrict wtmp2 = st->wtmp2; - register int i; -#endif - - for ( j=0 ; j<M ; j++ ) - { - register spx_word32_t * restrict W = &(st->W[j*N]); - - if (j==0 || cancel_count%(M-1) == j-1) - { -#ifdef FIXED_POINT - -#if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION) -#pragma TCS_unroll=4 -#pragma TCS_unrollexact=1 -#endif - for ( i=0 ; i<N ; i++ ) - wtmp2[i] = EXTRACT16(PSHR32(W[i],NORMALIZE_SCALEDOWN+16)); -#if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION) -#pragma TCS_unrollexact=0 -#pragma TCS_unroll=0 -#endif - spx_ifft(st->fft_table, wtmp2, wtmp); - memset(wtmp, 0, framesize * sizeof(spx_word16_t)); - -#if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION) -#pragma TCS_unroll=4 -#pragma TCS_unrollexact=1 -#endif - for (j=framesize; j<N ; ++j) - { wtmp[j]=SHL16(wtmp[j],NORMALIZE_SCALEUP); - } -#if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION) -#pragma TCS_unrollexact=0 -#pragma TCS_unroll=0 -#endif - - spx_fft(st->fft_table, wtmp, wtmp2); - -#if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION) -#pragma TCS_unroll=4 -#pragma TCS_unrollexact=1 -#endif - for (i=0;i<N;i++) - { W[i] -= SHL32(EXTEND32(wtmp2[i]),16+NORMALIZE_SCALEDOWN-NORMALIZE_SCALEUP-1); - } -#if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION) -#pragma TCS_unrollexact=0 -#pragma TCS_unroll=0 -#endif - -#else - spx_ifft(st->fft_table, W, wtmp); - memset(&wtmp[framesize], 0, (N-framesize) * sizeof(spx_word16_t)); - spx_fft(st->fft_table, wtmp, W); -#endif - } - } -} - -#ifdef TWO_PATH -// first four parameters is passed by registers -// generate faster performance with 4 parameters functions -spx_word32_t mdf_update_foreground( - SpeexEchoState * restrict st, - spx_word32_t Dbf, - spx_word32_t Sff, - spx_word32_t See -) -{ - register spx_word32_t Davg1 = st->Davg1; - register spx_word32_t Davg2 = st->Davg2; - register spx_word32_t Dvar1 = st->Dvar1; - register spx_word32_t Dvar2 = st->Dvar2; - register spx_word16_t * restrict input = st->input; - register int framesize = st->frame_size; - register spx_word16_t * restrict xx = st->x + framesize; - register spx_word16_t * restrict y = st->y + framesize; - register spx_word16_t * restrict ee = st->e + framesize; - register int update_foreground; - register int i; - register int N = st->window_size; - register int M = st->M; - -#ifdef FIXED_POINT - register spx_word32_t sc0 = SUB32(Sff,See); - register spx_float_t sc1 = FLOAT_MUL32U(Sff,Dbf); - - Davg1 = ADD32(MULT16_32_Q15(QCONST16(.6f,15),Davg1), MULT16_32_Q15(QCONST16(.4f,15),sc0)); - Davg2 = ADD32(MULT16_32_Q15(QCONST16(.85f,15),Davg2), MULT16_32_Q15(QCONST16(.15f,15),sc0)); - Dvar1 = FLOAT_ADD( - FLOAT_MULT(VAR1_SMOOTH,Dvar1), - FLOAT_MUL32U(MULT16_32_Q15(QCONST16(.4f,15),Sff), - MULT16_32_Q15(QCONST16(.4f,15),Dbf))); - Dvar2 = FLOAT_ADD( - FLOAT_MULT(VAR2_SMOOTH,Dvar2), - FLOAT_MUL32U(MULT16_32_Q15(QCONST16(.15f,15),Sff), - MULT16_32_Q15(QCONST16(.15f,15),Dbf))); -#else - register spx_word32_t sc0 = Sff - See; - register spx_word32_t sc1 = Sff * Dbf; - - Davg1 = .6*Davg1 + .4*sc0; - Davg2 = .85*Davg2 + .15*sc0; - Dvar1 = VAR1_SMOOTH*Dvar1 + .16*sc1; - Dvar2 = VAR2_SMOOTH*Dvar2 + .0225*sc1; -#endif - - update_foreground = - mux( FLOAT_GT(FLOAT_MUL32U(sc0, VABS(sc0)), sc1), 1, - mux( FLOAT_GT(FLOAT_MUL32U(Davg1, VABS(Davg1)), FLOAT_MULT(VAR1_UPDATE,(Dvar1))), 1, - mux( FLOAT_GT(FLOAT_MUL32U(Davg2, VABS(Davg2)), FLOAT_MULT(VAR2_UPDATE,(Dvar2))), 1, 0))); - - if ( update_foreground ) - { - register spx_word16_t * restrict windowf = st->window + framesize; - register spx_word16_t * restrict window = st->window; - - st->Davg1 = st->Davg2 = 0; - st->Dvar1 = st->Dvar2 = FLOAT_ZERO; - - memcpy(st->foreground, st->W, N*M*sizeof(spx_word32_t)); - -#if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION) -#pragma TCS_unroll=4 -#pragma TCS_unrollexact=1 -#endif - for ( i=0 ; i<framesize ; ++i) - { register spx_word16_t wi = window[i]; - register spx_word16_t wfi = windowf[i]; - register spx_word16_t ei = ee[i]; - register spx_word16_t yi = y[i]; - - ee[i] = MULT16_16_Q15(wfi,ei) + MULT16_16_Q15(wi,yi); - } -#if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION) -#pragma TCS_unrollexact=0 -#pragma TCS_unroll=0 -#endif - - } else - { - register int reset_background; - - reset_background = - mux( FLOAT_GT(FLOAT_MUL32U(-(sc0),VABS(sc0)), FLOAT_MULT(VAR_BACKTRACK,sc1)), 1, - mux( FLOAT_GT(FLOAT_MUL32U(-(Davg1), VABS(Davg1)), FLOAT_MULT(VAR_BACKTRACK,Dvar1)), 1, - mux( FLOAT_GT(FLOAT_MUL32U(-(Davg2), VABS(Davg2)), FLOAT_MULT(VAR_BACKTRACK,Dvar2)), 1, 0))); - - if ( reset_background ) - { - memcpy(st->W, st->foreground, N*M*sizeof(spx_word32_t)); - memcpy(y, ee, framesize * sizeof(spx_word16_t)); - mdf_sub(xx,input,y,framesize); - See = Sff; - st->Davg1 = st->Davg2 = 0; - st->Dvar1 = st->Dvar2 = FLOAT_ZERO; - } else - { - st->Davg1 = Davg1; - st->Davg2 = Davg2; - st->Dvar1 = Dvar1; - st->Dvar2 = Dvar2; - } - } - - return See; -} -#endif - -void mdf_compute_error_signal( - SpeexEchoState * restrict st, - const spx_int16_t * restrict in, - spx_int16_t * restrict out, - int framesize -) -{ - register spx_word16_t preemph = st->preemph; - register spx_word16_t memE = st->memE; - register int saturated = st->saturated; - register spx_word16_t * restrict e = st->e; - register spx_word16_t * restrict ee = st->e + framesize; - register spx_word16_t * restrict input = st->input; - register spx_word16_t * restrict xx = st->x + framesize; - register int i; - -#if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION) -#pragma TCS_unroll=4 -#pragma TCS_unrollexact=1 -#endif - for ( i=0 ; i<framesize ; ++i ) - { - register spx_word32_t tmp_out; - register spx_int16_t ini = in[i]; - register int flg; - -#ifdef FIXED_POINT - -#ifdef TWO_PATH - tmp_out = SUB32(EXTEND32(input[i]), EXTEND32(ee[i])); - tmp_out = iclipi(tmp_out,32767); -#else - tmp_out = SUB32(EXTEND32(input[i]), EXTEND32(y[i])); - tmp_out = iclipi(tmp_out,32767); -#endif - -#else -#ifdef TWO_PATH - tmp_out = SUB32(EXTEND32(input[i]), EXTEND32(ee[i])); -#else - tmp_out = SUB32(EXTEND32(input[i]), EXTEND32(y[i])); -#endif - tmp_out = - fmux( tmp_out > 32767, 32767, - fmux( tmp_out < -32768, -32768, tmp_out)); -#endif - - tmp_out = ADD32(tmp_out, EXTEND32(MULT16_16_P15(preemph,memE))); - flg = iabs(ini) >= 32000; - tmp_out = VMUX( flg, 0, tmp_out); - saturated = mux( flg && (saturated == 0), 1, saturated); - - out[i] = (spx_int16_t)tmp_out; - memE = tmp_out; - } -#if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION) -#pragma TCS_unrollexact=0 -#pragma TCS_unroll=0 -#endif - - st->memE = memE; - st->saturated = saturated; - memset(e, 0, framesize * sizeof(spx_word16_t)); - memcpy(ee, xx, framesize * sizeof(spx_word16_t)); -} - -inline int mdf_check( - SpeexEchoState * restrict st, - spx_int16_t * out, - spx_word32_t Syy, - spx_word32_t Sxx, - spx_word32_t See, - spx_word32_t Sff, - spx_word32_t Sdd -) -{ - register int N = st->window_size; - register spx_word32_t N1e9 = N * 1e9; - register int screwed_up = st->screwed_up; - register int framesize = st->frame_size; - - if (!(Syy>=0 && Sxx>=0 && See >= 0) -#ifndef FIXED_POINT - || !(Sff < N1e9 && Syy < N1e9 && Sxx < N1e9 ) -#endif - ) - { - screwed_up += 50; - memset(out, 0, framesize * sizeof(spx_int16_t)); - - } else - { screwed_up = mux( SHR32(Sff, 2) > ADD32(Sdd, SHR32(MULT16_16(N, 10000),6)), screwed_up+1, 0); - } - - st->screwed_up = screwed_up; - - return screwed_up; -} - -void mdf_smooth( - spx_word32_t * restrict power, - spx_word32_t * restrict Xf, - int framesize, - int M -) -{ - register spx_word16_t ss, ss_1, pf, xff; - register int j; - -#ifdef FIXED_POINT - ss=DIV32_16(11469,M); - ss_1 = SUB16(32767,ss); -#else - ss=.35/M; - ss_1 = 1-ss; -#endif - -#if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION) -#pragma TCS_unroll=4 -#pragma TCS_unrollexact=1 -#endif - for ( j=0 ; j<framesize ; ++j ) - { register spx_word32_t pi = power[j]; - register spx_word32_t xfi = Xf[j]; - - power[j] = MULT16_32_Q15(ss_1,pi) + 1 + MULT16_32_Q15(ss,xfi); - } -#if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION) -#pragma TCS_unrollexact=0 -#pragma TCS_unroll=0 -#endif - - pf = power[framesize]; - xff = Xf[framesize]; - power[framesize] = MULT16_32_Q15(ss_1,pf) + 1 + MULT16_32_Q15(ss,xff); -} - -void mdf_compute_filtered_spectra_crosscorrelations( - SpeexEchoState * restrict st, - spx_word32_t Syy, - spx_word32_t See, - int framesize -) -{ - register spx_float_t Pey = FLOAT_ONE; - register spx_float_t Pyy = FLOAT_ONE; - register spx_word16_t spec_average = st->spec_average; - register spx_word32_t * restrict pRf = st->Rf; - register spx_word32_t * restrict pYf = st->Yf; - register spx_word32_t * restrict pEh = st->Eh; - register spx_word32_t * restrict pYh = st->Yh; - register spx_word16_t beta0 = st->beta0; - register spx_word16_t beta_max = st->beta_max; - register spx_float_t alpha, alpha_1; - register spx_word32_t tmp32, tmpx; - register spx_float_t sPey = st->Pey; - register spx_float_t sPyy = st->Pyy; - register spx_float_t tmp; - register spx_word16_t leak_estimate; - register int j; - register spx_float_t Eh, Yh; - register spx_word32_t _Ehj, _Rfj, _Yfj, _Yhj; - -#ifdef FIXED_POINT - register spx_word16_t spec_average1 = SUB16(32767,spec_average); -#else - register spx_word16_t spec_average1 = 1 - spec_average; -#endif - -#if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION) -#pragma TCS_unroll=4 -#pragma TCS_unrollexact=1 -#endif - for (j=framesize; j>0 ; --j) - { - _Ehj = pEh[j]; - _Rfj = pRf[j]; - _Yfj = pYf[j]; - _Yhj = pYh[j]; - - Eh = PSEUDOFLOAT(_Rfj - _Ehj); - Yh = PSEUDOFLOAT(_Yfj - _Yhj); - - Pey = FLOAT_ADD(Pey,FLOAT_MULT(Eh,Yh)); - Pyy = FLOAT_ADD(Pyy,FLOAT_MULT(Yh,Yh)); - - pEh[j] = MAC16_32_Q15(MULT16_32_Q15(spec_average1, _Ehj), spec_average, _Rfj); - pYh[j] = MAC16_32_Q15(MULT16_32_Q15(spec_average1, _Yhj), spec_average, _Yfj); - } -#if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION) -#pragma TCS_unrollexact=0 -#pragma TCS_unroll=0 -#endif - _Ehj = pEh[0]; - _Rfj = pRf[0]; - _Yfj = pYf[0]; - _Yhj = pYh[0]; - - Eh = PSEUDOFLOAT(_Rfj - _Ehj); - Yh = PSEUDOFLOAT(_Yfj - _Yhj); - - Pey = FLOAT_ADD(Pey,FLOAT_MULT(Eh,Yh)); - Pyy = FLOAT_ADD(Pyy,FLOAT_MULT(Yh,Yh)); - - pEh[0] = MAC16_32_Q15(MULT16_32_Q15(spec_average1, _Ehj), spec_average, _Rfj); - pYh[0] = MAC16_32_Q15(MULT16_32_Q15(spec_average1, _Yhj), spec_average, _Yfj); - - Pyy = FLOAT_SQRT(Pyy); - Pey = FLOAT_DIVU(Pey,Pyy); - - tmp32 = MULT16_32_Q15(beta0,Syy); - tmpx = MULT16_32_Q15(beta_max,See); - tmp32 = VMUX(tmp32 > tmpx, tmpx, tmp32); - alpha = FLOAT_DIV32(tmp32, See); - alpha_1 = FLOAT_SUB(FLOAT_ONE, alpha); - - sPey = FLOAT_ADD(FLOAT_MULT(alpha_1,sPey) , FLOAT_MULT(alpha,Pey)); - sPyy = FLOAT_ADD(FLOAT_MULT(alpha_1,sPyy) , FLOAT_MULT(alpha,Pyy)); - tmp = FLOAT_MULT(MIN_LEAK,sPyy); - -#ifndef FIXED_POINT - sPyy = VMUX(FLOAT_LT(sPyy, FLOAT_ONE), FLOAT_ONE, sPyy); - sPey = VMUX(FLOAT_LT(sPey, tmp), tmp, sPey); - sPey = VMUX(FLOAT_LT(sPey, sPyy), sPey, sPyy); -#else - sPyy = FLOAT_LT(sPyy, FLOAT_ONE) ? FLOAT_ONE : sPyy; - sPey = FLOAT_LT(sPey, tmp) ? tmp : sPey; - sPey = FLOAT_LT(sPey, sPyy) ? sPey : sPyy; -#endif - - leak_estimate = FLOAT_EXTRACT16(FLOAT_SHL(FLOAT_DIVU(sPey, sPyy),14)); - - leak_estimate = VMUX( leak_estimate > 16383, 32767, SHL16(leak_estimate,1)); - st->Pey = sPey; - st->Pyy = sPyy; - st->leak_estimate = leak_estimate; -} - -inline spx_word16_t mdf_compute_RER( - spx_word32_t See, - spx_word32_t Syy, - spx_word32_t Sey, - spx_word32_t Sxx, - spx_word16_t leake -) -{ - register spx_word16_t RER; - -#ifdef FIXED_POINT - register spx_word32_t tmp32; - register spx_word32_t tmp; - spx_float_t bound = PSEUDOFLOAT(Sey); - - tmp32 = MULT16_32_Q15(leake,Syy); - tmp32 = ADD32(SHR32(Sxx,13), ADD32(tmp32, SHL32(tmp32,1))); - - bound = FLOAT_DIVU(FLOAT_MULT(bound, bound), PSEUDOFLOAT(ADD32(1,Syy))); - tmp = FLOAT_EXTRACT32(bound); - tmp32 = imux( FLOAT_GT(bound, PSEUDOFLOAT(See)), See, - imux( tmp32 < tmp, tmp, tmp32)); - - tmp = SHR32(See,1); - tmp32 = imux(tmp32 > tmp, tmp, tmp32); - RER = FLOAT_EXTRACT16(FLOAT_SHL(FLOAT_DIV32(tmp32,See),15)); -#else - register spx_word32_t r0; - - r0 = (Sey * Sey)/(1 + See * Syy); - - RER = (.0001*Sxx + 3.* MULT16_32_Q15(leake,Syy)) / See; - RER = fmux( RER < r0, r0, RER); - RER = fmux( RER > .5, .5, RER); -#endif - - return RER; -} - -void mdf_adapt( - SpeexEchoState * restrict st, - spx_word16_t RER, - spx_word32_t Syy, - spx_word32_t See, - spx_word32_t Sxx -) -{ - register spx_float_t * restrict power_1 = st->power_1; - register spx_word32_t * restrict power = st->power; - register int adapted = st->adapted; - register spx_word32_t sum_adapt = st->sum_adapt; - register spx_word16_t leake = st->leak_estimate; - register int framesize = st->frame_size; - register int i; - register int M = st->M; - - adapted = mux( !adapted && sum_adapt > QCONST32(M,15) && - MULT16_32_Q15(leake,Syy) > MULT16_32_Q15(QCONST16(.03f,15),Syy), 1, adapted); - - if ( adapted ) - { register spx_word32_t * restrict Yf = st->Yf; - register spx_word32_t * restrict Rf = st->Rf; - register spx_word32_t r, e, e2; - -#if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION) -#pragma TCS_unroll=4 -#pragma TCS_unrollexact=1 -#endif - for ( i=0 ; i<framesize ; ++i ) - { - r = SHL32(Yf[i],3); - r = MULT16_32_Q15(leake,r); - e = SHL32(Rf[i],3)+1; - -#ifdef FIXED_POINT - e2 = SHR32(e,1); - r = mux( r > e2, e2, r); -#else - e2 = e * .5; - r = fmux( r > e2, e2, r); -#endif - - r = MULT16_32_Q15(QCONST16(.7,15),r) + - MULT16_32_Q15(QCONST16(.3,15),(spx_word32_t)(MULT16_32_Q15(RER,e))); - - power_1[i] = FLOAT_SHL(FLOAT_DIV32_FLOAT(r,FLOAT_MUL32U(e,power[i]+10)),WEIGHT_SHIFT+16); - } -#if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION) -#pragma TCS_unrollexact=0 -#pragma TCS_unroll=0 -#endif - - r = SHL32(Yf[framesize],3); - r = MULT16_32_Q15(leake,r); - e = SHL32(Rf[framesize],3)+1; - -#ifdef FIXED_POINT - e2 = SHR32(e,1); - r = mux( r > e2, e2, r); -#else - e2 = e * .5; - r = fmux( r > e2, e2, r); -#endif - - r = MULT16_32_Q15(QCONST16(.7,15),r) + - MULT16_32_Q15(QCONST16(.3,15),(spx_word32_t)(MULT16_32_Q15(RER,e))); - - power_1[framesize] = FLOAT_SHL(FLOAT_DIV32_FLOAT(r,FLOAT_MUL32U(e,power[framesize]+10)),WEIGHT_SHIFT+16); - - } else - { - register spx_word16_t adapt_rate=0; - register int N = st->window_size; - - if ( Sxx > SHR32(MULT16_16(N, 1000),6) ) - { register spx_word32_t tmp32, tmp32q; - - tmp32 = MULT16_32_Q15(QCONST16(.25f, 15), Sxx); -#ifdef FIXED_POINT - tmp32q = SHR32(See,2); - tmp32 = mux(tmp32 > tmp32q, tmp32q, tmp32); -#else - tmp32q = 0.25 * See; - tmp32 = fmux(tmp32 > tmp32q, tmp32q, tmp32); -#endif - adapt_rate = FLOAT_EXTRACT16(FLOAT_SHL(FLOAT_DIV32(tmp32, See),15)); - } - -#if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION) -#pragma TCS_unroll=4 -#pragma TCS_unrollexact=1 -#endif - for (i=0;i<framesize;i++) - power_1[i] = FLOAT_SHL(FLOAT_DIV32(EXTEND32(adapt_rate),ADD32(power[i],10)),WEIGHT_SHIFT+1); -#if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION) -#pragma TCS_unrollexact=0 -#pragma TCS_unroll=0 -#endif - power_1[framesize] = FLOAT_SHL(FLOAT_DIV32(EXTEND32(adapt_rate),ADD32(power[framesize],10)),WEIGHT_SHIFT+1); - sum_adapt = ADD32(sum_adapt,adapt_rate); - } - - st->sum_adapt = sum_adapt; - st->adapted = adapted; -} - -#define OVERRIDE_ECHO_CANCELLATION -void speex_echo_cancellation( - SpeexEchoState * restrict st, - const spx_int16_t * restrict in, - const spx_int16_t * restrict far_end, - spx_int16_t * restrict out -) -{ - register int framesize = st->frame_size; - register spx_word16_t * restrict x = st->x; - register spx_word16_t * restrict xx = st->x + framesize; - register spx_word16_t * restrict yy = st->y + framesize; - register spx_word16_t * restrict ee = st->e + framesize; - register spx_word32_t Syy, See, Sxx, Sdd, Sff; - register spx_word16_t RER; - register spx_word32_t Sey; - register int j; - register int N,M; -#ifdef TWO_PATH - register spx_word32_t Dbf; -#endif - - N = st->window_size; - M = st->M; - st->cancel_count++; - - filter_dc_notch16(in, st->notch_radius, st->input, framesize, st->notch_mem); - mdf_preemph(st, xx, far_end, framesize); - - { - - register spx_word16_t * restrict X = st->X; - - for ( j=M-1 ; j>=0 ; j-- ) - { register spx_word16_t * restrict Xdes = &(X[(j+1)*N]); - register spx_word16_t * restrict Xsrc = &(X[j*N]); - - memcpy(Xdes, Xsrc, N * sizeof(spx_word16_t)); - } - - spx_fft(st->fft_table, x, X); - memcpy(st->last_y, st->x, N * sizeof(spx_word16_t)); - Sxx = mdf_inner_prod(xx, xx, framesize); - memcpy(x, xx, framesize * sizeof(spx_word16_t)); - -#ifdef TWO_PATH - spectral_mul_accum(st->X, st->foreground, st->Y, N, M); - spx_ifft(st->fft_table, st->Y, st->e); - mdf_sub(xx, st->input, ee, framesize); - Sff = mdf_inner_prod(xx, xx, framesize); -#endif - - mdf_adjust_prop (st->W, N, M, st->prop); - - if (st->saturated == 0) - { mdf_compute_weight_gradient(st, X, N, M); - } else - { st->saturated--; - } - } - - mdf_update_weight(st, N, M, framesize); - spectral_mul_accum(st->X, st->W, st->Y, N, M); - spx_ifft(st->fft_table, st->Y, st->y); - -#ifdef TWO_PATH - mdf_sub(xx, ee, yy, framesize); - Dbf = 10+mdf_inner_prod(xx, xx, framesize); -#endif - - mdf_sub(xx, st->input, yy, framesize); - See = mdf_inner_prod(xx, xx, framesize); - -#ifndef TWO_PATH - Sff = See; -#else - See = mdf_update_foreground(st,Dbf,Sff,See); -#endif - - - mdf_compute_error_signal(st, in, out, framesize); - Sey = mdf_inner_prod(ee, yy, framesize); - Syy = mdf_inner_prod(yy, yy, framesize); - Sdd = mdf_inner_prod(st->input, st->input, framesize); - - if ( mdf_check(st,out,Syy,Sxx,See,Sff,Sdd) >= 50 ) - { speex_warning("The echo canceller started acting funny and got slapped (reset). It swears it will behave now."); - speex_echo_state_reset(st); - return; - } - - See = MAX32(See, SHR32(MULT16_16(N, 100),6)); - spx_fft(st->fft_table, st->e, st->E); - memset(st->y, 0, framesize * sizeof(spx_word16_t)); - spx_fft(st->fft_table, st->y, st->Y); - power_spectrum(st->E, st->Rf, N); - power_spectrum(st->Y, st->Yf, N); - power_spectrum(st->X, st->Xf, N); - - mdf_smooth(st->power,st->Xf,framesize, M); - mdf_compute_filtered_spectra_crosscorrelations(st,Syy,See,framesize); - RER = mdf_compute_RER(See,Syy,Sey,Sxx,st->leak_estimate); - mdf_adapt(st, RER, Syy, See, Sxx); - - if ( st->adapted ) - { register spx_word16_t * restrict last_yy = st->last_y + framesize; - - memcpy(st->last_y, last_yy, framesize * sizeof(spx_word16_t)); - mdf_sub_int(last_yy, in, out, framesize); - - } -} - - - |