|
- /* Copyright (C) 2007 Hong Zhiqian */
- /**
- @file preprocess_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"
-
- #ifdef FIXED_POINT
- #define OVERRIDE_PREPROCESS_ANALYSIS
- static void preprocess_analysis(SpeexPreprocessState * restrict st, spx_int16_t * restrict x)
- {
- register int i, j, framesize = st->frame_size;
- register int N = st->ps_size;
- register int N3 = 2*N - framesize;
- register int N4 = framesize - N3;
- register int * restrict ps = st->ps;
- register int * restrict frame;
- register int * restrict inbuf;
- register int * restrict ptr;
- register int max_val;
-
- frame = (int*)(st->frame);
- inbuf = (int*)(st->inbuf);
- ptr = (int*)(st->frame+N3);
-
- TMDEBUG_ALIGNMEM(x);
- TMDEBUG_ALIGNMEM(frame);
- TMDEBUG_ALIGNMEM(inbuf);
-
- PREPROCESSANAYLSIS_START();
-
- N3 >>= 1;
- framesize >>= 1;
- max_val = 0;
-
- for ( i=0,j=0 ; i<N3 ; i+=2,j+=8 )
- { register int r1, r2;
-
- r1 = ld32x(inbuf,i);
- r2 = ld32x(inbuf,i+1);
-
- st32d(j, frame, r1);
- st32d(j+4, frame, r2);
- }
-
- for ( i=0,j=0 ; i<framesize ; i+=2,j+=8 )
- { register int r1, r2;
-
- r1 = ld32x(x, i);
- r2 = ld32x(x, i+1);
-
- st32d(j, ptr, r1);
- st32d(j+4,ptr, r2);
- }
-
- for ( i=0,j=0,ptr=(int*)(x+N4) ; i<N3 ; i+=2,j+=8 )
- { register int r1, r2;
-
- r1 = ld32x(ptr, i);
- r2 = ld32x(ptr, i+1);
-
- st32d(j, inbuf, r1);
- st32d(j+4,inbuf, r2);
- }
- #if (TM_UNROLL && TM_UNROLL_PREPROCESSANALYSIS)
- #pragma TCS_unroll=2
- #pragma TCS_unrollexact=1
- #endif
- for ( i=0,j=0,ptr=(int*)st->window ; i<N ; ++i,j+=4 )
- { register int f10, w10, r0, r1;
-
- f10 = ld32x(frame, i);
- w10 = ld32x(ptr, i);
-
- r0 = (sex16(f10) * sex16(w10)) >> 15;
- r1 = (asri(16,f10) * asri(16,w10)) >> 15;
-
- max_val = imax(iabs(sex16(r0)), max_val);
- max_val = imax(iabs(sex16(r1)), max_val);
-
- r0 = pack16lsb(r1, r0);
- st32d(j, frame, r0);
- }
- #if (TM_UNROLL && TM_UNROLL_PREPROCESSANALYSIS)
- #pragma TCS_unrollexact=0
- #pragma TCS_unroll=0
- #endif
-
- max_val = 14 - spx_ilog2(max_val);
- st->frame_shift = max_val;
-
- if ( max_val != 0 )
- {
- #if (TM_UNROLL && TM_UNROLL_PREPROCESSANALYSIS)
- #pragma TCS_unroll=4
- #pragma TCS_unrollexact=1
- #endif
- for ( i=0,j=0 ; i<N ; ++i,j+=4 )
- { register int f10;
-
- f10 = ld32x(frame, i);
- f10 = dualasl(f10, max_val);
- st32d(j, frame, f10);
-
- }
- #if (TM_UNROLL && TM_UNROLL_PREPROCESSANALYSIS)
- #pragma TCS_unrollexact=0
- #pragma TCS_unroll=0
- #endif
- }
-
- spx_fft(st->fft_lookup, st->frame, st->ft);
- power_spectrum(st->ft, ps, N << 1);
-
- #if (TM_UNROLL && TM_UNROLL_PREPROCESSANALYSIS)
- #pragma TCS_unroll=4
- #pragma TCS_unrollexact=1
- #endif
- for ( i=0,ptr=(int*)st->ps,max_val<<=1,j=((1<<((max_val))>>1)) ;i<N ; ++i )
- {
- ps[i] = (ps[i] + j) >> max_val;
- }
- #if (TM_UNROLL && TM_UNROLL_PREPROCESSANALYSIS)
- #pragma TCS_unrollexact=0
- #pragma TCS_unroll=0
- #endif
-
- filterbank_compute_bank32(st->bank, ps, ps+N);
-
- PREPROCESSANAYLSIS_STOP();
- }
-
- #define _MULT16_32_Q15(a,b,c) ADD32(MULT16_16((a),(b)), SHR(MULT16_16((a),(c)),15))
-
- #define OVERRIDE_UPDATE_NOISE_PROB
- static void update_noise_prob(SpeexPreprocessState * restrict st)
- {
- register int i;
- register int min_range, nb_adapt;
- register int N = st->ps_size;
- register int * restrict Smin = (int*)st->Smin;
- register int * restrict Stmp = (int*)st->Stmp;
- register int * restrict S = (int*)st->S;
-
- UPDATENOISEPROB_START();
-
- {
- register int psi_lsb, psi_msb, ips_lsb, ips_msb, psii_lsb, psii_msb;
- register int psiii_lsb, psiii_msb;
- register int q8, q05, q2, q1;
- register int *ps = (int*)st->ps;
- register int si_lsb, si_msb, sii_lsb, sii_msb;
-
- q8 = QCONST16(.8f,15);
- q05 = QCONST16(.05f,15);
- q2 = QCONST16(.2f,15);
- q1 = QCONST16(.1f,15);
-
- ips_lsb = ps[0];
- psi_lsb = ps[1];
- si_lsb = S[0];
- ips_msb = ips_lsb >> 15;
- psi_msb = psi_lsb >> 15;
- si_msb = si_lsb >> 15;
-
- ips_lsb &= 0x00007fff;
- psi_lsb &= 0x00007fff;
- si_lsb &= 0x00007fff;
-
- S[0] = _MULT16_32_Q15(q8,si_msb,si_lsb) + _MULT16_32_Q15(q2,ips_msb,ips_lsb);
-
- for ( i=1 ; i<N-1 ; i+=2 )
- {
- psii_lsb = ps[i+1];
- si_lsb = S[i];
-
- psii_msb = psii_lsb >> 15;
- si_msb = si_lsb >> 15;
- si_lsb &= 0x00007fff;
- psii_lsb &= 0x00007fff;
-
- S[i]= _MULT16_32_Q15(q8,si_msb,si_lsb) +
- _MULT16_32_Q15(q05,ips_msb,ips_lsb) +
- _MULT16_32_Q15(q1,psi_msb,psi_lsb) +
- _MULT16_32_Q15(q05,psii_msb,psii_lsb);
-
- psiii_lsb = ps[i+2];
- sii_lsb = S[i+1];
-
- sii_msb = sii_lsb >> 15;
- psiii_msb= psiii_lsb >> 15;
- sii_lsb &= 0x00007fff;
- psiii_lsb&= 0x00007fff;
-
- S[i+1]= _MULT16_32_Q15(q8,sii_msb,sii_lsb) +
- _MULT16_32_Q15(q05,psi_msb,psi_lsb) +
- _MULT16_32_Q15(q1,psii_msb,psii_lsb) +
- _MULT16_32_Q15(q05,psiii_msb,psiii_lsb);
-
- ips_lsb = psii_lsb;
- ips_msb = psii_msb;
- psi_lsb = psiii_lsb;
- psi_msb = psiii_msb;
- }
-
- S[N-1] = MULT16_32_Q15(q8,S[N-1]) + MULT16_32_Q15(q2,ps[N-1]);
- }
-
- nb_adapt = st->nb_adapt;
-
- if ( nb_adapt==1 )
- { for ( i=0 ; i<N ; ++i )
- Smin[i] = Stmp[i] = 0;
-
- }
-
- min_range = mux(nb_adapt < 100, 15,
- mux(nb_adapt < 1000, 50,
- mux(nb_adapt < 10000, 150, 300)));
-
- if ( st->min_count > min_range )
- {
- st->min_count = 0;
-
- #if (TM_UNROLL && TM_UNROLL_UPDATENOISEPROB)
- #pragma TCS_unroll=2
- #pragma TCS_unrollexact=1
- #endif
- for ( i=0 ; i<N ; ++i )
- { register int si, stmpi;
-
- si = S[i];
- stmpi = Stmp[i];
-
- Smin[i] = imin(stmpi,si);
- Stmp[i] = si;
- }
- #if (TM_UNROLL && TM_UNROLL_UPDATENOISEPROB)
- #pragma TCS_unrollexact=0
- #pragma TCS_unroll=0
- #endif
- } else
- {
-
- #if (TM_UNROLL && TM_UNROLL_UPDATENOISEPROB)
- #pragma TCS_unroll=2
- #pragma TCS_unrollexact=1
- #endif
- for ( i=0 ; i<N ; ++i )
- { register int si, stmpi, smini;
-
- si = S[i];
- stmpi = Stmp[i];
- smini = Smin[i];
-
- Smin[i] = imin(smini,si);
- Stmp[i] = imin(stmpi,si);
- }
- #if (TM_UNROLL && TM_UNROLL_UPDATENOISEPROB)
- #pragma TCS_unrollexact=0
- #pragma TCS_unroll=0
- #endif
- }
-
-
- {
- register int q4;
- register int * restrict update_prob = (int*)st->update_prob;
-
- q4 = QCONST16(.4f,15);
-
- #if (TM_UNROLL && TM_UNROLL_UPDATENOISEPROB)
- #pragma TCS_unroll=4
- #pragma TCS_unrollexact=1
- #endif
- for ( i=0 ; i<N ; ++i )
- { register int si;
- register int smini;
-
- si = S[i];
- smini = Smin[i];
- update_prob[i] = mux(MULT16_32_Q15(q4,si) > ADD32(smini,20), 1, 0);
- }
- #if (TM_UNROLL && TM_UNROLL_UPDATENOISEPROB)
- #pragma TCS_unrollexact=0
- #pragma TCS_unroll=0
- #endif
- }
-
- UPDATENOISEPROB_STOP();
- }
-
- #else
-
- #define OVERRIDE_PREPROCESS_ANALYSIS
- static void preprocess_analysis(SpeexPreprocessState * restrict st, spx_int16_t * restrict x)
- {
- register int i;
- register int framesize = st->frame_size;
- register int N = st->ps_size;
- register int N3 = 2*N - framesize;
- register int N4 = framesize - N3;
- register float * restrict ps = st->ps;
- register float * restrict frame = st->frame;
- register float * restrict inbuf = st->inbuf;
-
- PREPROCESSANAYLSIS_START();
-
- #if (TM_UNROLL && TM_UNROLL_PREPROCESSANALYSIS)
- #pragma TCS_unroll=4
- #pragma TCS_unrollexact=1
- #endif
- for ( i=0 ; i<N3 ; ++i )
- {
- frame[i] = inbuf[i];
- }
- #if (TM_UNROLL && TM_UNROLL_PREPROCESSANALYSIS)
- #pragma TCS_unrollexact=0
- #pragma TCS_unroll=0
- #endif
-
- #if (TM_UNROLL && TM_UNROLL_PREPROCESSANALYSIS)
- #pragma TCS_unroll=4
- #pragma TCS_unrollexact=1
- #endif
- for ( i=0 ; i<framesize ; ++i )
- { frame[N3+i] = x[i];
- }
- #if (TM_UNROLL && TM_UNROLL_PREPROCESSANALYSIS)
- #pragma TCS_unrollexact=0
- #pragma TCS_unroll=0
- #endif
-
- #if (TM_UNROLL && TM_UNROLL_PREPROCESSANALYSIS)
- #pragma TCS_unroll=4
- #pragma TCS_unrollexact=1
- #endif
- for ( i=0,x+=N4 ; i<N3 ; ++i )
- { inbuf[i] = x[i];
- }
- #if (TM_UNROLL && TM_UNROLL_PREPROCESSANALYSIS)
- #pragma TCS_unrollexact=0
- #pragma TCS_unroll=0
- #endif
-
- inbuf = st->window;
-
- #if (TM_UNROLL && TM_UNROLL_PREPROCESSANALYSIS)
- #pragma TCS_unroll=4
- #pragma TCS_unrollexact=1
- #endif
- for ( i=0 ; i<2*N ; ++i )
- {
- frame[i] = frame[i] * inbuf[i];
- }
- #if (TM_UNROLL && TM_UNROLL_PREPROCESSANALYSIS)
- #pragma TCS_unrollexact=0
- #pragma TCS_unroll=0
- #endif
-
- spx_fft(st->fft_lookup, frame, st->ft);
- power_spectrum(st->ft, ps, N << 1);
- filterbank_compute_bank32(st->bank, ps, ps+N);
-
- PREPROCESSANAYLSIS_STOP();
- }
-
-
- #define OVERRIDE_UPDATE_NOISE_PROB
- static void update_noise_prob(SpeexPreprocessState * restrict st)
- {
-
- register float * restrict S = st->S;
- register float * restrict ps = st->ps;
- register int N = st->ps_size;
- register int min_range;
- register int i;
- register int nb_adapt;
- register float * restrict Smin = st->Smin;
- register float * restrict Stmp = st->Stmp;
-
- UPDATENOISEPROB_START();
-
- {
- register float ips, psi;
-
- ips = ps[0];
- psi = ps[1];
-
- S[0] = .8f * S[0] + .2f * ips;
-
- for ( i=1 ; i<N-1 ; i+=2 )
- {
- register float psii, psiii;
-
- psii = ps[i+1];
- psiii = ps[i+2];
- S[i] = .8f * S[i] + .05f * ips + .1f * psi + .05f * psii;
- S[i+1] = .8f * S[i+1] + .05f * psi + .1f * psii + .05f * psiii;
- ips = psii;
- psi = psiii;
- }
-
- S[N-1] = .8f * S[N-1] + .2f * ps[N-1];
- }
-
- nb_adapt = st->nb_adapt;
-
- if ( nb_adapt==1 )
- {
- for (i=0;i<N;i++)
- Smin[i] = st->Stmp[i] = 0;
- }
-
- min_range = mux(nb_adapt < 100, 15,
- mux(nb_adapt < 1000, 50,
- mux(nb_adapt < 10000, 150, 300)));
-
-
- if ( st->min_count > min_range )
- {
- st->min_count = 0;
- #if (TM_UNROLL && TM_UNROLL_UPDATENOISEPROB)
- #pragma TCS_unroll=4
- #pragma TCS_unrollexact=1
- #endif
- for ( i=0 ; i<N ; ++i )
- {
- register float stmpi, si;
-
- stmpi = Stmp[i];
- si = S[i];
-
- Smin[i] = fmin(stmpi,si);
- Stmp[i] = si;
- }
- #if (TM_UNROLL && TM_UNROLL_UPDATENOISEPROB)
- #pragma TCS_unrollexact=0
- #pragma TCS_unroll=0
- #endif
-
- } else
- {
- register float * restrict Smin = st->Smin;
-
- #if (TM_UNROLL && TM_UNROLL_UPDATENOISEPROB)
- #pragma TCS_unroll=4
- #pragma TCS_unrollexact=1
- #endif
- for ( i=0 ; i<N ; ++i )
- {
- register float stmpi, si, smini;
-
- stmpi = Stmp[i];
- si = S[i];
- smini = Smin[i];
-
- Smin[i] = fmin(smini,si);
- Stmp[i] = fmin(stmpi,si);
- }
- #if (TM_UNROLL && TM_UNROLL_UPDATENOISEPROB)
- #pragma TCS_unrollexact=0
- #pragma TCS_unroll=0
- #endif
- }
-
- {
- register int * restrict update_prob = (int*)st->update_prob;
-
- #if (TM_UNROLL && TM_UNROLL_UPDATENOISEPROB)
- #pragma TCS_unroll=4
- #pragma TCS_unrollexact=1
- #endif
- for (i=0;i<N;i++)
- { register float si;
- register float smini;
-
- si = S[i];
- smini = Smin[i];
- update_prob[i] = mux( (.4 * si) > (smini + 20.f), 1, 0);
-
- }
- #if (TM_UNROLL && TM_UNROLL_UPDATENOISEPROB)
- #pragma TCS_unrollexact=0
- #pragma TCS_unroll=0
- #endif
- }
-
- UPDATENOISEPROB_STOP();
- }
-
-
- #define OVERRIDE_COMPUTE_GAIN_FLOOR
- static void compute_gain_floor(
- int noise_suppress,
- int effective_echo_suppress,
- float * restrict noise,
- float * restrict echo,
- float * gain_floor,
- int len
- )
- {
- register int i;
- register float echo_floor;
- register float noise_floor;
-
- COMPUTEGAINFLOOR_START();
-
- noise_floor = exp(.2302585f*noise_suppress);
- echo_floor = exp(.2302585f*effective_echo_suppress);
-
- #if (TM_UNROLL && TM_UNROLL_COMPUTEGAINFLOOR)
- #pragma TCS_unroll=4
- #pragma TCS_unrollexact=1
- #endif
- for (i=0;i<len;i++)
- { register float noisei, echoi;
-
- noisei = noise[i];
- echoi = echo[i];
-
- gain_floor[i] = FRAC_SCALING * sqrt(noise_floor * noisei + echo_floor * echoi) / sqrt(1+noisei+echoi);
-
- }
- #if (TM_UNROLL && TM_UNROLL_COMPUTEGAINFLOOR)
- #pragma TCS_unrollexact=0
- #pragma TCS_unroll=0
- #endif
-
- COMPUTEGAINFLOOR_STOP();
- }
-
- #endif
-
- static inline spx_word32_t hypergeom_gain(spx_word32_t xx);
- static inline spx_word16_t qcurve(spx_word16_t x);
- static void compute_gain_floor(int noise_suppress, int effective_echo_suppress, spx_word32_t *noise, spx_word32_t *echo, spx_word16_t *gain_floor, int len);
- void speex_echo_get_residual(SpeexEchoState *st, spx_word32_t *Yout, int len);
-
- #ifndef FIXED_POINT
- static void speex_compute_agc(SpeexPreprocessState *st, spx_word16_t Pframe, spx_word16_t *ft);
- #endif
-
- void preprocess_residue_echo(
- SpeexPreprocessState * restrict st,
- int N,
- int NM
- )
- {
- if (st->echo_state)
- {
- register spx_word32_t * restrict r_echo = st->residual_echo;
- register spx_word32_t * restrict e_noise = st->echo_noise;
- register int i;
-
- #ifndef FIXED_POINT
- register spx_word32_t r;
- #endif
-
- speex_echo_get_residual(st->echo_state, r_echo, N);
-
- #ifndef FIXED_POINT
- r = r_echo[0];
- if (!(r >=0 && r < N*1e9f) )
- {
- memset(r_echo, 0, N * sizeof(spx_word32_t));
- }
- #endif
-
- #if (TM_UNROLL && TM_UNROLL_SPEEXPREPROCESSRUN)
- #pragma TCS_unroll=4
- #pragma TCS_unrollexact=1
- #endif
- for (i=0;i<N;i++)
- { register spx_word32_t eni = e_noise[i];
- e_noise[i] = MAX32(MULT16_32_Q15(QCONST16(.6f,15),eni), r_echo[i]);
- }
- #if (TM_UNROLL && TM_UNROLL_SPEEXPREPROCESSRUN)
- #pragma TCS_unrollexact=0
- #pragma TCS_unroll=0
- #endif
- filterbank_compute_bank32(st->bank, e_noise, e_noise+N);
-
- } else
- { memset(st->echo_noise, 0, (NM) * sizeof(spx_word32_t));
- }
- }
-
- void preprocess_update_noise(
- SpeexPreprocessState * restrict st,
- spx_word32_t * restrict ps,
- int N
- )
- {
- register spx_word16_t beta, beta_1;
- register int * restrict up = st->update_prob;
- register spx_word32_t * restrict noise = st->noise;
- register int i;
-
- beta = MAX16(QCONST16(.03,15),DIV32_16(Q15_ONE,st->nb_adapt));
- beta_1 = Q15_ONE-beta;
-
- #if (TM_UNROLL && TM_UNROLL_SPEEXPREPROCESSRUN)
- #pragma TCS_unroll=4
- #pragma TCS_unrollexact=1
- #endif
- for (i=0;i<N;i++)
- { register spx_word32_t ni = noise[i];
- register spx_word32_t psi = ps[i];
-
- if ( !up[i] || psi < PSHR32(ni, NOISE_SHIFT) )
- { noise[i] = MAX32(EXTEND32(0),MULT16_32_Q15(beta_1,ni) +
- MULT16_32_Q15(beta,SHL32(psi,NOISE_SHIFT)));
- }
- }
- #if (TM_UNROLL && TM_UNROLL_SPEEXPREPROCESSRUN)
- #pragma TCS_unrollexact=0
- #pragma TCS_unroll=0
- #endif
- filterbank_compute_bank32(st->bank, noise, noise+N);
- }
-
- void preprocess_compute_SNR(
- SpeexPreprocessState * restrict st,
- spx_word32_t * restrict ps,
- int NM
- )
- {
- register spx_word32_t * restrict noise = st->noise;
- register spx_word32_t * restrict echo = st->echo_noise;
- register spx_word32_t * restrict reverb = st->reverb_estimate;
- register spx_word16_t * restrict post = st->post;
- register spx_word32_t * restrict old_ps = st->old_ps;
- register spx_word16_t * restrict prior = st->prior;
- register int i;
-
- #if (TM_UNROLL && TM_UNROLL_SPEEXPREPROCESSRUN)
- #pragma TCS_unroll=4
- #pragma TCS_unrollexact=1
- #endif
- for ( i=0 ; i<NM ; i++)
- {
- register spx_word16_t gamma;
- register spx_word32_t tot_noise;
- register spx_word16_t posti;
- register spx_word32_t opsi;
- register spx_word16_t priori;
-
- tot_noise = ADD32(ADD32(ADD32(EXTEND32(1), PSHR32(noise[i],NOISE_SHIFT)), echo[i]) , reverb[i]);
-
- posti = SUB16(DIV32_16_Q8(ps[i],tot_noise), QCONST16(1.f,SNR_SHIFT));
- posti = MIN16(posti, QCONST16(100.f,SNR_SHIFT));
- post[i] = posti;
-
- opsi = old_ps[i];
-
- gamma = QCONST16(.1f,15)+MULT16_16_Q15(QCONST16(.89f,15),SQR16_Q15(DIV32_16_Q15(opsi,ADD32(opsi,tot_noise))));
-
- priori = EXTRACT16(PSHR32(ADD32(MULT16_16(gamma,MAX16(0,posti)), MULT16_16(Q15_ONE-gamma,DIV32_16_Q8(opsi,tot_noise))), 15));
- prior[i]=MIN16(priori, QCONST16(100.f,SNR_SHIFT));
- }
- #if (TM_UNROLL && TM_UNROLL_SPEEXPREPROCESSRUN)
- #pragma TCS_unrollexact=0
- #pragma TCS_unroll=0
- #endif
- }
-
- spx_word32_t preprocess_smooth_SNR(
- SpeexPreprocessState * restrict st,
- int N,
- int NM
- )
- {
- register spx_word16_t * restrict zeta = st->zeta;
- register spx_word16_t * restrict prior = st->prior;
- register spx_word32_t Zframe;
- register spx_word16_t iprior, priori;
- register int _N = N-1;
- register int i;
-
- iprior = prior[0];
- priori = prior[1];
- zeta[0] = PSHR32(ADD32(MULT16_16(QCONST16(.7f,15),zeta[0]), MULT16_16(QCONST16(.3f,15),iprior)),15);
-
- #if (TM_UNROLL && TM_UNROLL_SPEEXPREPROCESSRUN)
- #pragma TCS_unroll=2
- #pragma TCS_unrollexact=1
- #endif
- for ( i=1 ; i<_N ; i++)
- { register spx_word16_t zetai = zeta[i];
- register spx_word16_t priorii = prior[i+1];
-
- zeta[i] = PSHR32(ADD32(ADD32(ADD32(MULT16_16(QCONST16(.7f,15),zetai), MULT16_16(QCONST16(.15f,15),priori)),
- MULT16_16(QCONST16(.075f,15),iprior)), MULT16_16(QCONST16(.075f,15),priorii)),15);
-
- iprior = priori;
- priori = priorii;
- }
- #if (TM_UNROLL && TM_UNROLL_SPEEXPREPROCESSRUN)
- #pragma TCS_unrollexact=0
- #pragma TCS_unroll=0
- #endif
-
- for (i=_N; i<NM ; i++)
- { register spx_word16_t zetai = zeta[i];
-
- priori = prior[i];
- zeta[i] = PSHR32(ADD32(MULT16_16(QCONST16(.7f,15),zetai), MULT16_16(QCONST16(.3f,15),priori)),15);
- }
-
- Zframe = 0;
-
- #if (TM_UNROLL && TM_UNROLL_SPEEXPREPROCESSRUN)
- #pragma TCS_unroll=4
- #pragma TCS_unrollexact=1
- #endif
- for ( i=N ; i<NM ; i++ )
- { Zframe = ADD32(Zframe, EXTEND32(zeta[i]));
- }
- #if (TM_UNROLL && TM_UNROLL_SPEEXPREPROCESSRUN)
- #pragma TCS_unrollexact=0
- #pragma TCS_unroll=0
- #endif
-
- return Zframe;
- }
-
- void preprocess_compute_emgain(
- SpeexPreprocessState * restrict st,
- spx_word32_t * restrict ps,
- spx_word16_t Pframe,
- int NM
- )
- {
- register spx_word16_t * restrict zeta = st->zeta;
- register spx_word16_t * restrict prior = st->prior;
- register spx_word16_t * restrict gain = st->gain;
- register spx_word32_t * restrict old_ps = st->old_ps;
- register spx_word16_t * restrict post = st->post;
- register spx_word16_t * restrict gain2 = st->gain2;
- register int i;
- register int N=st->ps_size;
-
- for ( i=N ; i<NM ; ++i )
- {
- register spx_word32_t theta;
- register spx_word32_t MM;
- register spx_word16_t prior_ratio;
- register spx_word16_t P1;
- register spx_word16_t q;
-
- #ifdef FIXED_POINT
- register spx_word16_t tmp;
- #endif
- register spx_word16_t priori = prior[i];
-
- prior_ratio = PDIV32_16(SHL32(EXTEND32(priori), 15), ADD16(priori, SHL32(1,SNR_SHIFT)));
- theta = MULT16_32_P15(prior_ratio, QCONST32(1.f,EXPIN_SHIFT)+SHL32(EXTEND32(post[i]),EXPIN_SHIFT-SNR_SHIFT));
-
- MM = hypergeom_gain(theta);
- gain[i] = EXTRACT16(MIN32(Q15_ONE, MULT16_32_Q15(prior_ratio, MM)));
- old_ps[i] = MULT16_32_P15(QCONST16(.2f,15),old_ps[i]) + MULT16_32_P15(MULT16_16_P15(QCONST16(.8f,15),SQR16_Q15(gain[i])),ps[i]);
-
- P1 = QCONST16(.199f,15)+MULT16_16_Q15(QCONST16(.8f,15),qcurve (zeta[i]));
- q = Q15_ONE-MULT16_16_Q15(Pframe,P1);
-
- #ifdef FIXED_POINT
- theta = MIN32(theta, EXTEND32(32767));
- tmp = MULT16_16_Q15((SHL32(1,SNR_SHIFT)+priori),EXTRACT16(MIN32(Q15ONE,SHR32(spx_exp(-EXTRACT16(theta)),1))));
- tmp = MIN16(QCONST16(3.,SNR_SHIFT), tmp);
- tmp = EXTRACT16(PSHR32(MULT16_16(PDIV32_16(SHL32(EXTEND32(q),8),(Q15_ONE-q)),tmp),8));
- gain2[i]=DIV32_16(SHL32(EXTEND32(32767),SNR_SHIFT), ADD16(256,tmp));
- #else
- gain2[i]=1/(1.f + (q/(1.f-q))*(1+priori)*exp(-theta));
- #endif
- }
-
- filterbank_compute_psd16(st->bank,gain2+N, gain2);
- filterbank_compute_psd16(st->bank,gain+N, gain);
- }
-
- void preprocess_compute_linear_gain(
- SpeexPreprocessState * restrict st,
- spx_word32_t * restrict ps,
- int N
- )
- {
- register spx_word16_t * restrict gain_floor = st->gain_floor;
- register spx_word16_t * restrict prior = st->prior;
- register spx_word16_t * restrict gain = st->gain;
- register spx_word32_t * restrict old_ps = st->old_ps;
- register spx_word16_t * restrict post = st->post;
- register spx_word16_t * restrict gain2 = st->gain2;
- register int i;
-
- filterbank_compute_psd16(st->bank,gain_floor+N,gain_floor);
-
- #if (TM_UNROLL && TM_UNROLL_SPEEXPREPROCESSRUN)
- #pragma TCS_unroll=4
- #pragma TCS_unrollexact=1
- #endif
- for (i=0;i<N;i++)
- {
- register spx_word32_t MM;
- register spx_word32_t theta;
- register spx_word16_t prior_ratio;
- register spx_word16_t tmp;
- register spx_word16_t p;
- register spx_word16_t g;
- register spx_word16_t gfi = gain_floor[i];
-
- prior_ratio = PDIV32_16(SHL32(EXTEND32(st->prior[i]), 15), ADD16(prior[i], SHL32(1,SNR_SHIFT)));
- theta = MULT16_32_P15(prior_ratio, QCONST32(1.f,EXPIN_SHIFT)+SHL32(EXTEND32(post[i]),EXPIN_SHIFT-SNR_SHIFT));
- MM = hypergeom_gain(theta);
-
- g = EXTRACT16(MIN32(Q15_ONE, MULT16_32_Q15(prior_ratio, MM)));
- p = gain2[i];
-
- g = VMUX( MULT16_16_Q15(QCONST16(.333f,15),g) > gain[i], MULT16_16(3,gain[i]), g);
-
- old_ps[i]= MULT16_32_P15(QCONST16(.2f,15),old_ps[i]) +
- MULT16_32_P15(MULT16_16_P15(QCONST16(.8f,15),SQR16_Q15(g)),ps[i]);
-
- g = VMUX( g < gfi, gfi, g );
- gain[i] = g;
-
- tmp = MULT16_16_P15(p,spx_sqrt(SHL32(EXTEND32(g),15))) +
- MULT16_16_P15(SUB16(Q15_ONE,p),spx_sqrt(SHL32(EXTEND32(gfi),15)));
-
- gain2[i]=SQR16_Q15(tmp);
-
- /* Use this if you want a log-domain MMSE estimator instead */
- /* gain2[i] = pow(g, p) * pow(gfi,1.f-p);*/
- }
- #if (TM_UNROLL && TM_UNROLL_SPEEXPREPROCESSRUN)
- #pragma TCS_unrollexact=0
- #pragma TCS_unroll=0
- #endif
- }
-
-
- #if 0
- void preprocess_compute_bark_gain(
- SpeexPreprocessState * restrict st,
- int N,
- int NM
- )
- {
- register spx_word16_t * restrict gain_floor = st->gain_floor;
- register spx_word16_t * restrict gain = st->gain;
- register spx_word16_t * restrict gain2 = st->gain2;
- register int i;
-
- for (i=N;i<NM;i++)
- {
- register spx_word16_t tmp;
- register spx_word16_t p = gain2[i];
- register spx_word16_t gaini;
- register spx_word16_t gfi = gain_floor[i];
-
- gaini = MAX16(gain[i], gfi);
-
- gain[i] = gaini;
-
- tmp = MULT16_16_P15(p,spx_sqrt(SHL32(EXTEND32(gaini),15))) +
- MULT16_16_P15(SUB16(Q15_ONE,p),spx_sqrt(SHL32(EXTEND32(gfi),15)));
-
- gain2[i]=SQR16_Q15(tmp);
- }
-
- filterbank_compute_psd16(st->bank,gain2+N, gain2);
- }
- #endif
-
- void preprocess_apply_gain(
- SpeexPreprocessState * restrict st,
- int N
- )
- {
- register spx_word16_t * restrict ft = st->ft;
- register spx_word16_t * restrict gain2 = st->gain2;
- register int j, i;
-
- ft[0] = MULT16_16_P15(gain2[0],ft[0]);
-
- for (i=1,j=1; i<N ; i++,j+=2)
- {
- register spx_word16_t gain2i = gain2[i];
- register spx_word16_t ftj = ft[j];
- register spx_word16_t ftjj = ft[j+1];
-
- ft[j] = MULT16_16_P15(gain2i,ftj);
- ft[j+1] = MULT16_16_P15(gain2i,ftjj);
- }
-
- ft[(N<<1)-1] = MULT16_16_P15(gain2[N-1],ft[(N<<1)-1]);
- }
-
- #ifdef FIXED_POINT
- void preprocess_scale(
- SpeexPreprocessState * restrict st,
- int N
- )
- {
- register spx_word16_t * restrict frame = st->frame;
- register int shift = st->frame_shift;
- register int i;
- register int N2 = N << 1;
-
- #if (TM_UNROLL && TM_UNROLL_SPEEXPREPROCESSRUN)
- #pragma TCS_unroll=4
- #pragma TCS_unrollexact=1
- #endif
- for ( i=0 ; i<N2 ;i++)
- { register spx_word16_t framei = frame[i];
-
- frame[i] = PSHR16(framei,shift);
- }
- #if (TM_UNROLL && TM_UNROLL_SPEEXPREPROCESSRUN)
- #pragma TCS_unrollexact=0
- #pragma TCS_unroll=0
- #endif
- }
-
- #else
-
- void preprocess_apply_agc(
- SpeexPreprocessState * restrict st,
- int N
- )
- {
- register spx_word16_t max_sample=0;
- register spx_word16_t * restrict frame = st->frame;
- register int i;
- register int N2 = N << 1;
-
- #if (TM_UNROLL && TM_UNROLL_SPEEXPREPROCESSRUN)
- #pragma TCS_unroll=4
- #pragma TCS_unrollexact=1
- #endif
- for (i=0;i<N2;i++)
- { register spx_word16_t framei = VABS(frame[i]);
-
- max_sample = VMUX( framei > max_sample, framei, max_sample);
- }
- #if (TM_UNROLL && TM_UNROLL_SPEEXPREPROCESSRUN)
- #pragma TCS_unrollexact=0
- #pragma TCS_unroll=0
- #endif
-
- if ( max_sample > 28000.f )
- {
- float damp = 28000.f/max_sample;
-
- #if (TM_UNROLL && TM_UNROLL_SPEEXPREPROCESSRUN)
- #pragma TCS_unroll=4
- #pragma TCS_unrollexact=1
- #endif
- for ( i=0 ; i< N2 ; i++ )
- { frame[i] *= damp;
- }
- #if (TM_UNROLL && TM_UNROLL_SPEEXPREPROCESSRUN)
- #pragma TCS_unrollexact=0
- #pragma TCS_unroll=0
- #endif
- }
- }
- #endif
-
-
- void preprocess_update(
- SpeexPreprocessState * restrict st,
- spx_int16_t * restrict x,
- int N
- )
- {
- register spx_word16_t * restrict frame = st->frame;
- register spx_word16_t * restrict window = st->window;
- register spx_word16_t * restrict outbuf = st->outbuf;
- register int framesize = st->frame_size;
- register int N2 = N << 1;
- register int N3 = N2 - framesize;
- register int N4 = (framesize) - N3;
- register int i;
-
- #if (TM_UNROLL && TM_UNROLL_SPEEXPREPROCESSRUN)
- #pragma TCS_unroll=4
- #pragma TCS_unrollexact=1
- #endif
- for ( i=0 ; i<N2 ; i++)
- { register spx_word16_t fi = frame[i];
- register spx_word16_t wi = window[i];
-
- frame[i] = MULT16_16_Q15(fi, wi);
- }
- for (i=0;i<N3;i++)
- { x[i] = outbuf[i] + frame[i];
- }
- #if (TM_UNROLL && TM_UNROLL_SPEEXPREPROCESSRUN)
- #pragma TCS_unrollexact=0
- #pragma TCS_unroll=0
- #endif
-
- for ( i=0;i<N4;i++)
- { x[N3+i] = frame[N3+i];
- }
-
- memcpy(outbuf, frame+framesize, (N3) * sizeof(spx_word16_t));
- }
-
- #define OVERRIDE_SPEEX_PREPROCESS_RUN
- int speex_preprocess_run(SpeexPreprocessState * restrict st, spx_int16_t * restrict x)
- {
- register int i, N, M, NM;
- register spx_word32_t * restrict ps=st->ps;
- register spx_word32_t Zframe;
- register spx_word16_t Pframe;
-
- st->nb_adapt++;
- st->min_count++;
- N = st->ps_size;
- M = st->nbands;
- NM = N + M;
-
- preprocess_residue_echo(st, N, NM);
- preprocess_analysis(st, x);
- update_noise_prob(st);
- preprocess_update_noise(st, ps, N);
-
- if ( st->nb_adapt == 1 )
- { memcpy(st->old_ps, ps, (NM) * sizeof(spx_word32_t));
- }
-
- preprocess_compute_SNR(st, ps, NM);
- Zframe = preprocess_smooth_SNR(st, N, NM);
-
-
- {
- register spx_word16_t effective_echo_suppress;
-
- Pframe = QCONST16(.1f,15)+MULT16_16_Q15(QCONST16(.899f,15),qcurve(DIV32_16(Zframe,M)));
- effective_echo_suppress = EXTRACT16(PSHR32(ADD32(MULT16_16(SUB16(Q15_ONE,Pframe), st->echo_suppress),
- MULT16_16(Pframe, st->echo_suppress_active)),15));
- compute_gain_floor(st->noise_suppress, effective_echo_suppress, st->noise+N, st->echo_noise+N, st->gain_floor+N, M);
-
- }
-
- preprocess_compute_emgain(st, ps, Pframe, NM);
- preprocess_compute_linear_gain(st, ps, N);
-
-
- if (!st->denoise_enabled)
- {
- register spx_word16_t * restrict gain2 = st->gain2;
-
- #if (TM_UNROLL && TM_UNROLL_SPEEXPREPROCESSRUN)
- #pragma TCS_unroll=4
- #pragma TCS_unrollexact=1
- #endif
- for ( i=0 ; i<NM ; i++ )
- { gain2[i] = Q15_ONE;
- }
- #if (TM_UNROLL && TM_UNROLL_SPEEXPREPROCESSRUN)
- #pragma TCS_unrollexact=0
- #pragma TCS_unroll=0
- #endif
- }
-
- preprocess_apply_gain(st, N);
-
- #ifndef FIXED_POINT
- if (st->agc_enabled)
- { speex_compute_agc(st, Pframe, st->ft);
- }
- #endif
-
-
- spx_ifft(st->fft_lookup, st->ft, st->frame);
-
- #ifdef FIXED_POINT
- preprocess_scale(st, N);
- #endif
-
- #ifndef FIXED_POINT
- if ( st->agc_enabled )
- { preprocess_apply_agc(st, N);
- }
- #endif
-
- preprocess_update(st, x, N);
-
- if ( st->vad_enabled )
- {
- if (Pframe > st->speech_prob_start || (st->was_speech && Pframe > st->speech_prob_continue))
- { st->was_speech=1;
- return 1;
-
- } else
- { st->was_speech=0;
- return 0;
- }
- } else
- { return 1;
- }
- }
|