198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project/* Copyright (C) 2002-2006 Jean-Marc Valin 298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project File: filters.c 398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project Various analysis/synthesis filters 498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project Redistribution and use in source and binary forms, with or without 698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project modification, are permitted provided that the following conditions 798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project are met: 898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project - Redistributions of source code must retain the above copyright 1098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project notice, this list of conditions and the following disclaimer. 1198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 1298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project - Redistributions in binary form must reproduce the above copyright 1398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project notice, this list of conditions and the following disclaimer in the 1498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project documentation and/or other materials provided with the distribution. 1598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 1698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project - Neither the name of the Xiph.org Foundation nor the names of its 1798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project contributors may be used to endorse or promote products derived from 1898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project this software without specific prior written permission. 1998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 2098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR 2498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 2598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 2698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 2798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 2898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 2998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 3098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project*/ 3298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 3398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef HAVE_CONFIG_H 3498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include "config.h" 3598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 3698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 3798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include "filters.h" 3898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include "stack_alloc.h" 3998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include "arch.h" 4098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include "math_approx.h" 4198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include "ltp.h" 4298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include <math.h> 4398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 4498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef _USE_SSE 4598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include "filters_sse.h" 4698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#elif defined (ARM4_ASM) || defined(ARM5E_ASM) 4798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include "filters_arm4.h" 4898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#elif defined (BFIN_ASM) 4998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include "filters_bfin.h" 5098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 5198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 5298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 5398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 5498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectvoid bw_lpc(spx_word16_t gamma, const spx_coef_t *lpc_in, spx_coef_t *lpc_out, int order) 5598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{ 5698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int i; 5798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t tmp=gamma; 5898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<order;i++) 5998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 6098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project lpc_out[i] = MULT16_16_P15(tmp,lpc_in[i]); 6198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project tmp = MULT16_16_P15(tmp, gamma); 6298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 6398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project} 6498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 6598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectvoid sanitize_values32(spx_word32_t *vec, spx_word32_t min_val, spx_word32_t max_val, int len) 6698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{ 6798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int i; 6898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<len;i++) 6998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 7098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* It's important we do the test that way so we can catch NaNs, which are neither greater nor smaller */ 7198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (!(vec[i]>=min_val && vec[i] <= max_val)) 7298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 7398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (vec[i] < min_val) 7498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project vec[i] = min_val; 7598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project else if (vec[i] > max_val) 7698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project vec[i] = max_val; 7798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project else /* Has to be NaN */ 7898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project vec[i] = 0; 7998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 8098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 8198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project} 8298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 8398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectvoid highpass(const spx_word16_t *x, spx_word16_t *y, int len, int filtID, spx_mem_t *mem) 8498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{ 8598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int i; 8698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef FIXED_POINT 8798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project const spx_word16_t Pcoef[5][3] = {{16384, -31313, 14991}, {16384, -31569, 15249}, {16384, -31677, 15328}, {16384, -32313, 15947}, {16384, -22446, 6537}}; 8898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project const spx_word16_t Zcoef[5][3] = {{15672, -31344, 15672}, {15802, -31601, 15802}, {15847, -31694, 15847}, {16162, -32322, 16162}, {14418, -28836, 14418}}; 8998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#else 9098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project const spx_word16_t Pcoef[5][3] = {{1.00000f, -1.91120f, 0.91498f}, {1.00000f, -1.92683f, 0.93071f}, {1.00000f, -1.93338f, 0.93553f}, {1.00000f, -1.97226f, 0.97332f}, {1.00000f, -1.37000f, 0.39900f}}; 9198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project const spx_word16_t Zcoef[5][3] = {{0.95654f, -1.91309f, 0.95654f}, {0.96446f, -1.92879f, 0.96446f}, {0.96723f, -1.93445f, 0.96723f}, {0.98645f, -1.97277f, 0.98645f}, {0.88000f, -1.76000f, 0.88000f}}; 9298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 9398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project const spx_word16_t *den, *num; 9498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (filtID>4) 9598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project filtID=4; 9698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 9798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project den = Pcoef[filtID]; num = Zcoef[filtID]; 9898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /*return;*/ 9998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<len;i++) 10098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 10198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t yi; 10298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word32_t vout = ADD32(MULT16_16(num[0], x[i]),mem[0]); 10398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project yi = EXTRACT16(SATURATE(PSHR32(vout,14),32767)); 10498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project mem[0] = ADD32(MAC16_16(mem[1], num[1],x[i]), SHL32(MULT16_32_Q15(-den[1],vout),1)); 10598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project mem[1] = ADD32(MULT16_16(num[2],x[i]), SHL32(MULT16_32_Q15(-den[2],vout),1)); 10698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project y[i] = yi; 10798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 10898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project} 10998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 11098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef FIXED_POINT 11198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 11298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project/* FIXME: These functions are ugly and probably introduce too much error */ 11398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectvoid signal_mul(const spx_sig_t *x, spx_sig_t *y, spx_word32_t scale, int len) 11498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{ 11598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int i; 11698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<len;i++) 11798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 11898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project y[i] = SHL32(MULT16_32_Q14(EXTRACT16(SHR32(x[i],7)),scale),7); 11998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 12098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project} 12198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 12298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectvoid signal_div(const spx_word16_t *x, spx_word16_t *y, spx_word32_t scale, int len) 12398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{ 12498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int i; 12598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (scale > SHL32(EXTEND32(SIG_SCALING), 8)) 12698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 12798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t scale_1; 12898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project scale = PSHR32(scale, SIG_SHIFT); 12998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project scale_1 = EXTRACT16(PDIV32_16(SHL32(EXTEND32(SIG_SCALING),7),scale)); 13098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<len;i++) 13198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 13298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project y[i] = MULT16_16_P15(scale_1, x[i]); 13398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 13498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } else if (scale > SHR32(EXTEND32(SIG_SCALING), 2)) { 13598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t scale_1; 13698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project scale = PSHR32(scale, SIG_SHIFT-5); 13798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project scale_1 = DIV32_16(SHL32(EXTEND32(SIG_SCALING),3),scale); 13898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<len;i++) 13998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 14098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project y[i] = PSHR32(MULT16_16(scale_1, SHL16(x[i],2)),8); 14198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 14298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } else { 14398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t scale_1; 14498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project scale = PSHR32(scale, SIG_SHIFT-7); 14598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (scale < 5) 14698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project scale = 5; 14798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project scale_1 = DIV32_16(SHL32(EXTEND32(SIG_SCALING),3),scale); 14898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<len;i++) 14998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 15098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project y[i] = PSHR32(MULT16_16(scale_1, SHL16(x[i],2)),6); 15198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 15298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 15398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project} 15498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 15598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#else 15698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 15798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectvoid signal_mul(const spx_sig_t *x, spx_sig_t *y, spx_word32_t scale, int len) 15898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{ 15998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int i; 16098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<len;i++) 16198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project y[i] = scale*x[i]; 16298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project} 16398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 16498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectvoid signal_div(const spx_sig_t *x, spx_sig_t *y, spx_word32_t scale, int len) 16598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{ 16698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int i; 16798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project float scale_1 = 1/scale; 16898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<len;i++) 16998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project y[i] = scale_1*x[i]; 17098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project} 17198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 17298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 17398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 17498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 17598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef FIXED_POINT 17698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 17798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 17898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 17998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectspx_word16_t compute_rms(const spx_sig_t *x, int len) 18098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{ 18198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int i; 18298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word32_t sum=0; 18398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_sig_t max_val=1; 18498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int sig_shift; 18598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 18698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<len;i++) 18798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 18898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_sig_t tmp = x[i]; 18998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (tmp<0) 19098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project tmp = -tmp; 19198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (tmp > max_val) 19298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project max_val = tmp; 19398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 19498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 19598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project sig_shift=0; 19698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project while (max_val>16383) 19798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 19898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project sig_shift++; 19998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project max_val >>= 1; 20098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 20198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 20298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<len;i+=4) 20398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 20498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word32_t sum2=0; 20598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t tmp; 20698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project tmp = EXTRACT16(SHR32(x[i],sig_shift)); 20798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project sum2 = MAC16_16(sum2,tmp,tmp); 20898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project tmp = EXTRACT16(SHR32(x[i+1],sig_shift)); 20998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project sum2 = MAC16_16(sum2,tmp,tmp); 21098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project tmp = EXTRACT16(SHR32(x[i+2],sig_shift)); 21198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project sum2 = MAC16_16(sum2,tmp,tmp); 21298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project tmp = EXTRACT16(SHR32(x[i+3],sig_shift)); 21398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project sum2 = MAC16_16(sum2,tmp,tmp); 21498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project sum = ADD32(sum,SHR32(sum2,6)); 21598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 21698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 21798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project return EXTRACT16(PSHR32(SHL32(EXTEND32(spx_sqrt(DIV32(sum,len))),(sig_shift+3)),SIG_SHIFT)); 21898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project} 21998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 22098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectspx_word16_t compute_rms16(const spx_word16_t *x, int len) 22198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{ 22298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int i; 22398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t max_val=10; 22498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 22598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<len;i++) 22698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 22798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_sig_t tmp = x[i]; 22898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (tmp<0) 22998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project tmp = -tmp; 23098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (tmp > max_val) 23198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project max_val = tmp; 23298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 23398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (max_val>16383) 23498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 23598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word32_t sum=0; 23698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<len;i+=4) 23798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 23898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word32_t sum2=0; 23998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project sum2 = MAC16_16(sum2,SHR16(x[i],1),SHR16(x[i],1)); 24098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project sum2 = MAC16_16(sum2,SHR16(x[i+1],1),SHR16(x[i+1],1)); 24198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project sum2 = MAC16_16(sum2,SHR16(x[i+2],1),SHR16(x[i+2],1)); 24298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project sum2 = MAC16_16(sum2,SHR16(x[i+3],1),SHR16(x[i+3],1)); 24398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project sum = ADD32(sum,SHR32(sum2,6)); 24498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 24598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project return SHL16(spx_sqrt(DIV32(sum,len)),4); 24698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } else { 24798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word32_t sum=0; 24898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int sig_shift=0; 24998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (max_val < 8192) 25098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project sig_shift=1; 25198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (max_val < 4096) 25298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project sig_shift=2; 25398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (max_val < 2048) 25498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project sig_shift=3; 25598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<len;i+=4) 25698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 25798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word32_t sum2=0; 25898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project sum2 = MAC16_16(sum2,SHL16(x[i],sig_shift),SHL16(x[i],sig_shift)); 25998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project sum2 = MAC16_16(sum2,SHL16(x[i+1],sig_shift),SHL16(x[i+1],sig_shift)); 26098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project sum2 = MAC16_16(sum2,SHL16(x[i+2],sig_shift),SHL16(x[i+2],sig_shift)); 26198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project sum2 = MAC16_16(sum2,SHL16(x[i+3],sig_shift),SHL16(x[i+3],sig_shift)); 26298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project sum = ADD32(sum,SHR32(sum2,6)); 26398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 26498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project return SHL16(spx_sqrt(DIV32(sum,len)),3-sig_shift); 26598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 26698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project} 26798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 26898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifndef OVERRIDE_NORMALIZE16 26998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectint normalize16(const spx_sig_t *x, spx_word16_t *y, spx_sig_t max_scale, int len) 27098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{ 27198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int i; 27298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_sig_t max_val=1; 27398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int sig_shift; 27498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 27598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<len;i++) 27698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 27798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_sig_t tmp = x[i]; 27898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (tmp<0) 27998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project tmp = NEG32(tmp); 28098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (tmp >= max_val) 28198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project max_val = tmp; 28298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 28398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 28498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project sig_shift=0; 28598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project while (max_val>max_scale) 28698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 28798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project sig_shift++; 28898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project max_val >>= 1; 28998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 29098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 29198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<len;i++) 29298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project y[i] = EXTRACT16(SHR32(x[i], sig_shift)); 29398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 29498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project return sig_shift; 29598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project} 29698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 29798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 29898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#else 29998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 30098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectspx_word16_t compute_rms(const spx_sig_t *x, int len) 30198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{ 30298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int i; 30398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project float sum=0; 30498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<len;i++) 30598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 30698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project sum += x[i]*x[i]; 30798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 30898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project return sqrt(.1+sum/len); 30998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project} 31098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectspx_word16_t compute_rms16(const spx_word16_t *x, int len) 31198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{ 31298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project return compute_rms(x, len); 31398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project} 31498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 31598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 31698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 31798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 31898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifndef OVERRIDE_FILTER_MEM16 31998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectvoid filter_mem16(const spx_word16_t *x, const spx_coef_t *num, const spx_coef_t *den, spx_word16_t *y, int N, int ord, spx_mem_t *mem, char *stack) 32098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{ 32198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int i,j; 32298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t xi,yi,nyi; 32398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<N;i++) 32498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 32598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project xi= x[i]; 32698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project yi = EXTRACT16(SATURATE(ADD32(EXTEND32(x[i]),PSHR32(mem[0],LPC_SHIFT)),32767)); 32798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project nyi = NEG16(yi); 32898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (j=0;j<ord-1;j++) 32998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 33098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project mem[j] = MAC16_16(MAC16_16(mem[j+1], num[j],xi), den[j],nyi); 33198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 33298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project mem[ord-1] = ADD32(MULT16_16(num[ord-1],xi), MULT16_16(den[ord-1],nyi)); 33398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project y[i] = yi; 33498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 33598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project} 33698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 33798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 33898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifndef OVERRIDE_IIR_MEM16 33998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectvoid iir_mem16(const spx_word16_t *x, const spx_coef_t *den, spx_word16_t *y, int N, int ord, spx_mem_t *mem, char *stack) 34098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{ 34198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int i,j; 34298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t yi,nyi; 34398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 34498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<N;i++) 34598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 34698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project yi = EXTRACT16(SATURATE(ADD32(EXTEND32(x[i]),PSHR32(mem[0],LPC_SHIFT)),32767)); 34798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project nyi = NEG16(yi); 34898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (j=0;j<ord-1;j++) 34998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 35098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project mem[j] = MAC16_16(mem[j+1],den[j],nyi); 35198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 35298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project mem[ord-1] = MULT16_16(den[ord-1],nyi); 35398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project y[i] = yi; 35498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 35598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project} 35698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 35798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 35898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifndef OVERRIDE_FIR_MEM16 35998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectvoid fir_mem16(const spx_word16_t *x, const spx_coef_t *num, spx_word16_t *y, int N, int ord, spx_mem_t *mem, char *stack) 36098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{ 36198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int i,j; 36298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t xi,yi; 36398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 36498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<N;i++) 36598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 36698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project xi=x[i]; 36798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project yi = EXTRACT16(SATURATE(ADD32(EXTEND32(x[i]),PSHR32(mem[0],LPC_SHIFT)),32767)); 36898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (j=0;j<ord-1;j++) 36998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 37098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project mem[j] = MAC16_16(mem[j+1], num[j],xi); 37198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 37298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project mem[ord-1] = MULT16_16(num[ord-1],xi); 37398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project y[i] = yi; 37498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 37598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project} 37698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 37798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 37898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 37998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectvoid syn_percep_zero16(const spx_word16_t *xx, const spx_coef_t *ak, const spx_coef_t *awk1, const spx_coef_t *awk2, spx_word16_t *y, int N, int ord, char *stack) 38098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{ 38198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int i; 38298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project VARDECL(spx_mem_t *mem); 38398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project ALLOC(mem, ord, spx_mem_t); 38498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<ord;i++) 38598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project mem[i]=0; 38698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project iir_mem16(xx, ak, y, N, ord, mem, stack); 38798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<ord;i++) 38898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project mem[i]=0; 38998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project filter_mem16(y, awk1, awk2, y, N, ord, mem, stack); 39098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project} 39198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectvoid residue_percep_zero16(const spx_word16_t *xx, const spx_coef_t *ak, const spx_coef_t *awk1, const spx_coef_t *awk2, spx_word16_t *y, int N, int ord, char *stack) 39298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{ 39398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int i; 39498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project VARDECL(spx_mem_t *mem); 39598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project ALLOC(mem, ord, spx_mem_t); 39698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<ord;i++) 39798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project mem[i]=0; 39898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project filter_mem16(xx, ak, awk1, y, N, ord, mem, stack); 39998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<ord;i++) 40098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project mem[i]=0; 40198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project fir_mem16(y, awk2, y, N, ord, mem, stack); 40298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project} 40398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 40498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 40598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifndef OVERRIDE_COMPUTE_IMPULSE_RESPONSE 40698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectvoid compute_impulse_response(const spx_coef_t *ak, const spx_coef_t *awk1, const spx_coef_t *awk2, spx_word16_t *y, int N, int ord, char *stack) 40798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{ 40898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int i,j; 40998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t y1, ny1i, ny2i; 41098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project VARDECL(spx_mem_t *mem1); 41198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project VARDECL(spx_mem_t *mem2); 41298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project ALLOC(mem1, ord, spx_mem_t); 41398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project ALLOC(mem2, ord, spx_mem_t); 41498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 41598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project y[0] = LPC_SCALING; 41698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<ord;i++) 41798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project y[i+1] = awk1[i]; 41898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project i++; 41998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (;i<N;i++) 42098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project y[i] = VERY_SMALL; 42198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<ord;i++) 42298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project mem1[i] = mem2[i] = 0; 42398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<N;i++) 42498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 42598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project y1 = ADD16(y[i], EXTRACT16(PSHR32(mem1[0],LPC_SHIFT))); 42698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project ny1i = NEG16(y1); 42798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project y[i] = PSHR32(ADD32(SHL32(EXTEND32(y1),LPC_SHIFT+1),mem2[0]),LPC_SHIFT); 42898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project ny2i = NEG16(y[i]); 42998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (j=0;j<ord-1;j++) 43098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 43198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project mem1[j] = MAC16_16(mem1[j+1], awk2[j],ny1i); 43298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project mem2[j] = MAC16_16(mem2[j+1], ak[j],ny2i); 43398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 43498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project mem1[ord-1] = MULT16_16(awk2[ord-1],ny1i); 43598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project mem2[ord-1] = MULT16_16(ak[ord-1],ny2i); 43698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 43798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project} 43898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 43998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 44098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project/* Decomposes a signal into low-band and high-band using a QMF */ 44198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectvoid qmf_decomp(const spx_word16_t *xx, const spx_word16_t *aa, spx_word16_t *y1, spx_word16_t *y2, int N, int M, spx_word16_t *mem, char *stack) 44298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{ 44398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int i,j,k,M2; 44498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project VARDECL(spx_word16_t *a); 44598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project VARDECL(spx_word16_t *x); 44698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t *x2; 44798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 44898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project ALLOC(a, M, spx_word16_t); 44998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project ALLOC(x, N+M-1, spx_word16_t); 45098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project x2=x+M-1; 45198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project M2=M>>1; 45298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<M;i++) 45398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project a[M-i-1]= aa[i]; 45498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<M-1;i++) 45598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project x[i]=mem[M-i-2]; 45698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<N;i++) 45798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project x[i+M-1]=SHR16(xx[i],1); 45898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<M-1;i++) 45998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project mem[i]=SHR16(xx[N-i-1],1); 46098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0,k=0;i<N;i+=2,k++) 46198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 46298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word32_t y1k=0, y2k=0; 46398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (j=0;j<M2;j++) 46498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 46598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project y1k=ADD32(y1k,MULT16_16(a[j],ADD16(x[i+j],x2[i-j]))); 46698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project y2k=SUB32(y2k,MULT16_16(a[j],SUB16(x[i+j],x2[i-j]))); 46798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project j++; 46898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project y1k=ADD32(y1k,MULT16_16(a[j],ADD16(x[i+j],x2[i-j]))); 46998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project y2k=ADD32(y2k,MULT16_16(a[j],SUB16(x[i+j],x2[i-j]))); 47098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 47198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project y1[k] = EXTRACT16(SATURATE(PSHR32(y1k,15),32767)); 47298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project y2[k] = EXTRACT16(SATURATE(PSHR32(y2k,15),32767)); 47398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 47498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project} 47598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 47698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project/* Re-synthesised a signal from the QMF low-band and high-band signals */ 47798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectvoid qmf_synth(const spx_word16_t *x1, const spx_word16_t *x2, const spx_word16_t *a, spx_word16_t *y, int N, int M, spx_word16_t *mem1, spx_word16_t *mem2, char *stack) 47898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* assumptions: 47998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project all odd x[i] are zero -- well, actually they are left out of the array now 48098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project N and M are multiples of 4 */ 48198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{ 48298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int i, j; 48398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int M2, N2; 48498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project VARDECL(spx_word16_t *xx1); 48598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project VARDECL(spx_word16_t *xx2); 48698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 48798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project M2 = M>>1; 48898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project N2 = N>>1; 48998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project ALLOC(xx1, M2+N2, spx_word16_t); 49098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project ALLOC(xx2, M2+N2, spx_word16_t); 49198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 49298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i = 0; i < N2; i++) 49398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project xx1[i] = x1[N2-1-i]; 49498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i = 0; i < M2; i++) 49598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project xx1[N2+i] = mem1[2*i+1]; 49698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i = 0; i < N2; i++) 49798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project xx2[i] = x2[N2-1-i]; 49898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i = 0; i < M2; i++) 49998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project xx2[N2+i] = mem2[2*i+1]; 50098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 50198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i = 0; i < N2; i += 2) { 50298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_sig_t y0, y1, y2, y3; 50398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t x10, x20; 50498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 50598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project y0 = y1 = y2 = y3 = 0; 50698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project x10 = xx1[N2-2-i]; 50798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project x20 = xx2[N2-2-i]; 50898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 50998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (j = 0; j < M2; j += 2) { 51098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t x11, x21; 51198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t a0, a1; 51298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 51398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project a0 = a[2*j]; 51498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project a1 = a[2*j+1]; 51598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project x11 = xx1[N2-1+j-i]; 51698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project x21 = xx2[N2-1+j-i]; 51798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 51898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef FIXED_POINT 51998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* We multiply twice by the same coef to avoid overflows */ 52098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project y0 = MAC16_16(MAC16_16(y0, a0, x11), NEG16(a0), x21); 52198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project y1 = MAC16_16(MAC16_16(y1, a1, x11), a1, x21); 52298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project y2 = MAC16_16(MAC16_16(y2, a0, x10), NEG16(a0), x20); 52398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project y3 = MAC16_16(MAC16_16(y3, a1, x10), a1, x20); 52498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#else 52598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project y0 = ADD32(y0,MULT16_16(a0, x11-x21)); 52698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project y1 = ADD32(y1,MULT16_16(a1, x11+x21)); 52798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project y2 = ADD32(y2,MULT16_16(a0, x10-x20)); 52898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project y3 = ADD32(y3,MULT16_16(a1, x10+x20)); 52998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 53098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project a0 = a[2*j+2]; 53198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project a1 = a[2*j+3]; 53298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project x10 = xx1[N2+j-i]; 53398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project x20 = xx2[N2+j-i]; 53498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 53598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef FIXED_POINT 53698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* We multiply twice by the same coef to avoid overflows */ 53798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project y0 = MAC16_16(MAC16_16(y0, a0, x10), NEG16(a0), x20); 53898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project y1 = MAC16_16(MAC16_16(y1, a1, x10), a1, x20); 53998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project y2 = MAC16_16(MAC16_16(y2, a0, x11), NEG16(a0), x21); 54098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project y3 = MAC16_16(MAC16_16(y3, a1, x11), a1, x21); 54198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#else 54298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project y0 = ADD32(y0,MULT16_16(a0, x10-x20)); 54398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project y1 = ADD32(y1,MULT16_16(a1, x10+x20)); 54498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project y2 = ADD32(y2,MULT16_16(a0, x11-x21)); 54598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project y3 = ADD32(y3,MULT16_16(a1, x11+x21)); 54698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 54798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 54898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef FIXED_POINT 54998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project y[2*i] = EXTRACT16(SATURATE32(PSHR32(y0,15),32767)); 55098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project y[2*i+1] = EXTRACT16(SATURATE32(PSHR32(y1,15),32767)); 55198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project y[2*i+2] = EXTRACT16(SATURATE32(PSHR32(y2,15),32767)); 55298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project y[2*i+3] = EXTRACT16(SATURATE32(PSHR32(y3,15),32767)); 55398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#else 55498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* Normalize up explicitly if we're in float */ 55598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project y[2*i] = 2.f*y0; 55698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project y[2*i+1] = 2.f*y1; 55798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project y[2*i+2] = 2.f*y2; 55898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project y[2*i+3] = 2.f*y3; 55998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 56098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 56198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 56298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i = 0; i < M2; i++) 56398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project mem1[2*i+1] = xx1[i]; 56498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i = 0; i < M2; i++) 56598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project mem2[2*i+1] = xx2[i]; 56698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project} 56798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 56898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef FIXED_POINT 56998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#if 0 57098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectconst spx_word16_t shift_filt[3][7] = {{-33, 1043, -4551, 19959, 19959, -4551, 1043}, 57198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project {-98, 1133, -4425, 29179, 8895, -2328, 444}, 57298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project {444, -2328, 8895, 29179, -4425, 1133, -98}}; 57398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#else 57498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectconst spx_word16_t shift_filt[3][7] = {{-390, 1540, -4993, 20123, 20123, -4993, 1540}, 57598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project {-1064, 2817, -6694, 31589, 6837, -990, -209}, 57698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project {-209, -990, 6837, 31589, -6694, 2817, -1064}}; 57798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 57898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#else 57998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#if 0 58098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectconst float shift_filt[3][7] = {{-9.9369e-04, 3.1831e-02, -1.3889e-01, 6.0910e-01, 6.0910e-01, -1.3889e-01, 3.1831e-02}, 58198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project {-0.0029937, 0.0345613, -0.1350474, 0.8904793, 0.2714479, -0.0710304, 0.0135403}, 58298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project {0.0135403, -0.0710304, 0.2714479, 0.8904793, -0.1350474, 0.0345613, -0.0029937}}; 58398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#else 58498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectconst float shift_filt[3][7] = {{-0.011915f, 0.046995f, -0.152373f, 0.614108f, 0.614108f, -0.152373f, 0.046995f}, 58598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project {-0.0324855f, 0.0859768f, -0.2042986f, 0.9640297f, 0.2086420f, -0.0302054f, -0.0063646f}, 58698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project {-0.0063646f, -0.0302054f, 0.2086420f, 0.9640297f, -0.2042986f, 0.0859768f, -0.0324855f}}; 58798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 58898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 58998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 59098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectint interp_pitch( 59198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectspx_word16_t *exc, /*decoded excitation*/ 59298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectspx_word16_t *interp, /*decoded excitation*/ 59398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectint pitch, /*pitch period*/ 59498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectint len 59598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project) 59698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{ 59798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int i,j,k; 59898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word32_t corr[4][7]; 59998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word32_t maxcorr; 60098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int maxi, maxj; 60198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<7;i++) 60298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 60398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project corr[0][i] = inner_prod(exc, exc-pitch-3+i, len); 60498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 60598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<3;i++) 60698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 60798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (j=0;j<7;j++) 60898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 60998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int i1, i2; 61098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word32_t tmp=0; 61198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project i1 = 3-j; 61298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (i1<0) 61398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project i1 = 0; 61498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project i2 = 10-j; 61598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (i2>7) 61698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project i2 = 7; 61798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (k=i1;k<i2;k++) 61898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project tmp += MULT16_32_Q15(shift_filt[i][k],corr[0][j+k-3]); 61998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project corr[i+1][j] = tmp; 62098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 62198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 62298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project maxi=maxj=0; 62398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project maxcorr = corr[0][0]; 62498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<4;i++) 62598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 62698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (j=0;j<7;j++) 62798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 62898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (corr[i][j] > maxcorr) 62998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 63098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project maxcorr = corr[i][j]; 63198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project maxi=i; 63298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project maxj=j; 63398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 63498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 63598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 63698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<len;i++) 63798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 63898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word32_t tmp = 0; 63998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (maxi>0) 64098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 64198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (k=0;k<7;k++) 64298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 64398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project tmp += MULT16_16(exc[i-(pitch-maxj+3)+k-3],shift_filt[maxi-1][k]); 64498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 64598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } else { 64698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project tmp = SHL32(exc[i-(pitch-maxj+3)],15); 64798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 64898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project interp[i] = PSHR32(tmp,15); 64998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 65098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project return pitch-maxj+3; 65198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project} 65298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 65398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectvoid multicomb( 65498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectspx_word16_t *exc, /*decoded excitation*/ 65598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectspx_word16_t *new_exc, /*enhanced excitation*/ 65698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectspx_coef_t *ak, /*LPC filter coefs*/ 65798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectint p, /*LPC order*/ 65898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectint nsf, /*sub-frame size*/ 65998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectint pitch, /*pitch period*/ 66098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectint max_pitch, 66198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectspx_word16_t comb_gain, /*gain of comb filter*/ 66298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectchar *stack 66398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project) 66498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{ 66598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int i; 66698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project VARDECL(spx_word16_t *iexc); 66798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t old_ener, new_ener; 66898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int corr_pitch; 66998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 67098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t iexc0_mag, iexc1_mag, exc_mag; 67198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word32_t corr0, corr1; 67298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t gain0, gain1; 67398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t pgain1, pgain2; 67498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t c1, c2; 67598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t g1, g2; 67698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t ngain; 67798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t gg1, gg2; 67898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef FIXED_POINT 67998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int scaledown=0; 68098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 68198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#if 0 /* Set to 1 to enable full pitch search */ 68298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int nol_pitch[6]; 68398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t nol_pitch_coef[6]; 68498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t ol_pitch_coef; 68598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project open_loop_nbest_pitch(exc, 20, 120, nsf, 68698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project nol_pitch, nol_pitch_coef, 6, stack); 68798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project corr_pitch=nol_pitch[0]; 68898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project ol_pitch_coef = nol_pitch_coef[0]; 68998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /*Try to remove pitch multiples*/ 69098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=1;i<6;i++) 69198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 69298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef FIXED_POINT 69398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if ((nol_pitch_coef[i]>MULT16_16_Q15(nol_pitch_coef[0],19661)) && 69498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#else 69598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if ((nol_pitch_coef[i]>.6*nol_pitch_coef[0]) && 69698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 69798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project (ABS(2*nol_pitch[i]-corr_pitch)<=2 || ABS(3*nol_pitch[i]-corr_pitch)<=3 || 69898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project ABS(4*nol_pitch[i]-corr_pitch)<=4 || ABS(5*nol_pitch[i]-corr_pitch)<=5)) 69998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 70098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project corr_pitch = nol_pitch[i]; 70198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 70298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 70398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#else 70498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project corr_pitch = pitch; 70598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 70698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 70798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project ALLOC(iexc, 2*nsf, spx_word16_t); 70898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 70998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project interp_pitch(exc, iexc, corr_pitch, 80); 71098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (corr_pitch>max_pitch) 71198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project interp_pitch(exc, iexc+nsf, 2*corr_pitch, 80); 71298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project else 71398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project interp_pitch(exc, iexc+nsf, -corr_pitch, 80); 71498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 71598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef FIXED_POINT 71698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<nsf;i++) 71798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 71898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (ABS16(exc[i])>16383) 71998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 72098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project scaledown = 1; 72198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project break; 72298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 72398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 72498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (scaledown) 72598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 72698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<nsf;i++) 72798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project exc[i] = SHR16(exc[i],1); 72898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<2*nsf;i++) 72998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project iexc[i] = SHR16(iexc[i],1); 73098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 73198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 73298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /*interp_pitch(exc, iexc+2*nsf, 2*corr_pitch, 80);*/ 73398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 73498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /*printf ("%d %d %f\n", pitch, corr_pitch, max_corr*ener_1);*/ 73598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project iexc0_mag = spx_sqrt(1000+inner_prod(iexc,iexc,nsf)); 73698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project iexc1_mag = spx_sqrt(1000+inner_prod(iexc+nsf,iexc+nsf,nsf)); 73798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project exc_mag = spx_sqrt(1+inner_prod(exc,exc,nsf)); 73898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project corr0 = inner_prod(iexc,exc,nsf); 73998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (corr0<0) 74098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project corr0=0; 74198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project corr1 = inner_prod(iexc+nsf,exc,nsf); 74298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (corr1<0) 74398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project corr1=0; 74498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef FIXED_POINT 74598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* Doesn't cost much to limit the ratio and it makes the rest easier */ 74698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (SHL32(EXTEND32(iexc0_mag),6) < EXTEND32(exc_mag)) 74798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project iexc0_mag = ADD16(1,PSHR16(exc_mag,6)); 74898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (SHL32(EXTEND32(iexc1_mag),6) < EXTEND32(exc_mag)) 74998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project iexc1_mag = ADD16(1,PSHR16(exc_mag,6)); 75098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 75198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (corr0 > MULT16_16(iexc0_mag,exc_mag)) 75298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project pgain1 = QCONST16(1., 14); 75398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project else 75498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project pgain1 = PDIV32_16(SHL32(PDIV32(corr0, exc_mag),14),iexc0_mag); 75598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (corr1 > MULT16_16(iexc1_mag,exc_mag)) 75698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project pgain2 = QCONST16(1., 14); 75798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project else 75898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project pgain2 = PDIV32_16(SHL32(PDIV32(corr1, exc_mag),14),iexc1_mag); 75998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project gg1 = PDIV32_16(SHL32(EXTEND32(exc_mag),8), iexc0_mag); 76098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project gg2 = PDIV32_16(SHL32(EXTEND32(exc_mag),8), iexc1_mag); 76198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (comb_gain>0) 76298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 76398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef FIXED_POINT 76498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project c1 = (MULT16_16_Q15(QCONST16(.4,15),comb_gain)+QCONST16(.07,15)); 76598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project c2 = QCONST16(.5,15)+MULT16_16_Q14(QCONST16(1.72,14),(c1-QCONST16(.07,15))); 76698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#else 76798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project c1 = .4*comb_gain+.07; 76898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project c2 = .5+1.72*(c1-.07); 76998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 77098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } else 77198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 77298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project c1=c2=0; 77398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 77498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef FIXED_POINT 77598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project g1 = 32767 - MULT16_16_Q13(MULT16_16_Q15(c2, pgain1),pgain1); 77698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project g2 = 32767 - MULT16_16_Q13(MULT16_16_Q15(c2, pgain2),pgain2); 77798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#else 77898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project g1 = 1-c2*pgain1*pgain1; 77998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project g2 = 1-c2*pgain2*pgain2; 78098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 78198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (g1<c1) 78298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project g1 = c1; 78398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (g2<c1) 78498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project g2 = c1; 78598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project g1 = (spx_word16_t)PDIV32_16(SHL32(EXTEND32(c1),14),(spx_word16_t)g1); 78698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project g2 = (spx_word16_t)PDIV32_16(SHL32(EXTEND32(c1),14),(spx_word16_t)g2); 78798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (corr_pitch>max_pitch) 78898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 78998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project gain0 = MULT16_16_Q15(QCONST16(.7,15),MULT16_16_Q14(g1,gg1)); 79098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project gain1 = MULT16_16_Q15(QCONST16(.3,15),MULT16_16_Q14(g2,gg2)); 79198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } else { 79298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project gain0 = MULT16_16_Q15(QCONST16(.6,15),MULT16_16_Q14(g1,gg1)); 79398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project gain1 = MULT16_16_Q15(QCONST16(.6,15),MULT16_16_Q14(g2,gg2)); 79498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 79598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<nsf;i++) 79698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project new_exc[i] = ADD16(exc[i], EXTRACT16(PSHR32(ADD32(MULT16_16(gain0,iexc[i]), MULT16_16(gain1,iexc[i+nsf])),8))); 79798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* FIXME: compute_rms16 is currently not quite accurate enough (but close) */ 79898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project new_ener = compute_rms16(new_exc, nsf); 79998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project old_ener = compute_rms16(exc, nsf); 80098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 80198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (old_ener < 1) 80298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project old_ener = 1; 80398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (new_ener < 1) 80498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project new_ener = 1; 80598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (old_ener > new_ener) 80698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project old_ener = new_ener; 80798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project ngain = PDIV32_16(SHL32(EXTEND32(old_ener),14),new_ener); 80898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 80998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<nsf;i++) 81098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project new_exc[i] = MULT16_16_Q14(ngain, new_exc[i]); 81198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef FIXED_POINT 81298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (scaledown) 81398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 81498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<nsf;i++) 81598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project exc[i] = SHL16(exc[i],1); 81698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<nsf;i++) 81798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project new_exc[i] = SHL16(SATURATE16(new_exc[i],16383),1); 81898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 81998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 82098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project} 82198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 822