198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project/* Copyright (C) 2002-2006 Jean-Marc Valin 298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project File: ltp.c 398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project Long-Term Prediction functions 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 <math.h> 3898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include "ltp.h" 3998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include "stack_alloc.h" 4098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include "filters.h" 4198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include <speex/speex_bits.h> 4298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include "math_approx.h" 4398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include "os_support.h" 4498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 4598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifndef NULL 4698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define NULL 0 4798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 4898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 4998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 5098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef _USE_SSE 5198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include "ltp_sse.h" 5298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#elif defined (ARM4_ASM) || defined(ARM5E_ASM) 5398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include "ltp_arm4.h" 5498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#elif defined (BFIN_ASM) 5598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include "ltp_bfin.h" 5698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 5798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 5898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifndef OVERRIDE_INNER_PROD 5998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectspx_word32_t inner_prod(const spx_word16_t *x, const spx_word16_t *y, int len) 6098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{ 6198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word32_t sum=0; 6298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project len >>= 2; 6398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project while(len--) 6498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 6598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word32_t part=0; 6698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project part = MAC16_16(part,*x++,*y++); 6798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project part = MAC16_16(part,*x++,*y++); 6898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project part = MAC16_16(part,*x++,*y++); 6998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project part = MAC16_16(part,*x++,*y++); 7098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* HINT: If you had a 40-bit accumulator, you could shift only at the end */ 7198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project sum = ADD32(sum,SHR32(part,6)); 7298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 7398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project return sum; 7498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project} 7598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 7698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 7798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifndef OVERRIDE_PITCH_XCORR 7898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#if 0 /* HINT: Enable this for machines with enough registers (i.e. not x86) */ 7998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectvoid pitch_xcorr(const spx_word16_t *_x, const spx_word16_t *_y, spx_word32_t *corr, int len, int nb_pitch, char *stack) 8098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{ 8198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int i,j; 8298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<nb_pitch;i+=4) 8398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 8498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* Compute correlation*/ 8598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /*corr[nb_pitch-1-i]=inner_prod(x, _y+i, len);*/ 8698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word32_t sum1=0; 8798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word32_t sum2=0; 8898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word32_t sum3=0; 8998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word32_t sum4=0; 9098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project const spx_word16_t *y = _y+i; 9198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project const spx_word16_t *x = _x; 9298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t y0, y1, y2, y3; 9398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /*y0=y[0];y1=y[1];y2=y[2];y3=y[3];*/ 9498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project y0=*y++; 9598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project y1=*y++; 9698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project y2=*y++; 9798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project y3=*y++; 9898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (j=0;j<len;j+=4) 9998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 10098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word32_t part1; 10198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word32_t part2; 10298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word32_t part3; 10398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word32_t part4; 10498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project part1 = MULT16_16(*x,y0); 10598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project part2 = MULT16_16(*x,y1); 10698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project part3 = MULT16_16(*x,y2); 10798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project part4 = MULT16_16(*x,y3); 10898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project x++; 10998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project y0=*y++; 11098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project part1 = MAC16_16(part1,*x,y1); 11198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project part2 = MAC16_16(part2,*x,y2); 11298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project part3 = MAC16_16(part3,*x,y3); 11398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project part4 = MAC16_16(part4,*x,y0); 11498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project x++; 11598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project y1=*y++; 11698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project part1 = MAC16_16(part1,*x,y2); 11798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project part2 = MAC16_16(part2,*x,y3); 11898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project part3 = MAC16_16(part3,*x,y0); 11998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project part4 = MAC16_16(part4,*x,y1); 12098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project x++; 12198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project y2=*y++; 12298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project part1 = MAC16_16(part1,*x,y3); 12398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project part2 = MAC16_16(part2,*x,y0); 12498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project part3 = MAC16_16(part3,*x,y1); 12598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project part4 = MAC16_16(part4,*x,y2); 12698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project x++; 12798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project y3=*y++; 12898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 12998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project sum1 = ADD32(sum1,SHR32(part1,6)); 13098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project sum2 = ADD32(sum2,SHR32(part2,6)); 13198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project sum3 = ADD32(sum3,SHR32(part3,6)); 13298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project sum4 = ADD32(sum4,SHR32(part4,6)); 13398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 13498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project corr[nb_pitch-1-i]=sum1; 13598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project corr[nb_pitch-2-i]=sum2; 13698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project corr[nb_pitch-3-i]=sum3; 13798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project corr[nb_pitch-4-i]=sum4; 13898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 13998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 14098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project} 14198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#else 14298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectvoid pitch_xcorr(const spx_word16_t *_x, const spx_word16_t *_y, spx_word32_t *corr, int len, int nb_pitch, char *stack) 14398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{ 14498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int i; 14598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<nb_pitch;i++) 14698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 14798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* Compute correlation*/ 14898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project corr[nb_pitch-1-i]=inner_prod(_x, _y+i, len); 14998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 15098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 15198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project} 15298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 15398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 15498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 15598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifndef OVERRIDE_COMPUTE_PITCH_ERROR 15698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectstatic inline spx_word32_t compute_pitch_error(spx_word16_t *C, spx_word16_t *g, spx_word16_t pitch_control) 15798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{ 15898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word32_t sum = 0; 15998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project sum = ADD32(sum,MULT16_16(MULT16_16_16(g[0],pitch_control),C[0])); 16098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project sum = ADD32(sum,MULT16_16(MULT16_16_16(g[1],pitch_control),C[1])); 16198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project sum = ADD32(sum,MULT16_16(MULT16_16_16(g[2],pitch_control),C[2])); 16298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project sum = SUB32(sum,MULT16_16(MULT16_16_16(g[0],g[1]),C[3])); 16398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project sum = SUB32(sum,MULT16_16(MULT16_16_16(g[2],g[1]),C[4])); 16498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project sum = SUB32(sum,MULT16_16(MULT16_16_16(g[2],g[0]),C[5])); 16598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project sum = SUB32(sum,MULT16_16(MULT16_16_16(g[0],g[0]),C[6])); 16698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project sum = SUB32(sum,MULT16_16(MULT16_16_16(g[1],g[1]),C[7])); 16798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project sum = SUB32(sum,MULT16_16(MULT16_16_16(g[2],g[2]),C[8])); 16898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project return sum; 16998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project} 17098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 17198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 17298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifndef OVERRIDE_OPEN_LOOP_NBEST_PITCH 17398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectvoid open_loop_nbest_pitch(spx_word16_t *sw, int start, int end, int len, int *pitch, spx_word16_t *gain, int N, char *stack) 17498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{ 17598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int i,j,k; 17698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project VARDECL(spx_word32_t *best_score); 17798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project VARDECL(spx_word32_t *best_ener); 17898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word32_t e0; 17998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project VARDECL(spx_word32_t *corr); 18098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef FIXED_POINT 18198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* In fixed-point, we need only one (temporary) array of 32-bit values and two (corr16, ener16) 18298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project arrays for (normalized) 16-bit values */ 18398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project VARDECL(spx_word16_t *corr16); 18498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project VARDECL(spx_word16_t *ener16); 18598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word32_t *energy; 18698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int cshift=0, eshift=0; 18798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int scaledown = 0; 18898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project ALLOC(corr16, end-start+1, spx_word16_t); 18998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project ALLOC(ener16, end-start+1, spx_word16_t); 19098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project ALLOC(corr, end-start+1, spx_word32_t); 19198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project energy = corr; 19298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#else 19398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* In floating-point, we need to float arrays and no normalized copies */ 19498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project VARDECL(spx_word32_t *energy); 19598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t *corr16; 19698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t *ener16; 19798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project ALLOC(energy, end-start+2, spx_word32_t); 19898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project ALLOC(corr, end-start+1, spx_word32_t); 19998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project corr16 = corr; 20098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project ener16 = energy; 20198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 20298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 20398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project ALLOC(best_score, N, spx_word32_t); 20498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project ALLOC(best_ener, N, spx_word32_t); 20598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<N;i++) 20698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 20798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project best_score[i]=-1; 20898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project best_ener[i]=0; 20998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project pitch[i]=start; 21098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 21198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 21298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef FIXED_POINT 21398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=-end;i<len;i++) 21498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 21598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (ABS16(sw[i])>16383) 21698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 21798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project scaledown=1; 21898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project break; 21998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 22098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 22198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* If the weighted input is close to saturation, then we scale it down */ 22298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (scaledown) 22398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 22498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=-end;i<len;i++) 22598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 22698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project sw[i]=SHR16(sw[i],1); 22798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 22898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 22998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 23098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project energy[0]=inner_prod(sw-start, sw-start, len); 23198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project e0=inner_prod(sw, sw, len); 23298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=start;i<end;i++) 23398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 23498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* Update energy for next pitch*/ 23598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project energy[i-start+1] = SUB32(ADD32(energy[i-start],SHR32(MULT16_16(sw[-i-1],sw[-i-1]),6)), SHR32(MULT16_16(sw[-i+len-1],sw[-i+len-1]),6)); 23698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (energy[i-start+1] < 0) 23798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project energy[i-start+1] = 0; 23898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 23998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 24098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef FIXED_POINT 24198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project eshift = normalize16(energy, ener16, 32766, end-start+1); 24298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 24398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 24498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* In fixed-point, this actually overrites the energy array (aliased to corr) */ 24598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project pitch_xcorr(sw, sw-end, corr, len, end-start+1, stack); 24698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 24798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef FIXED_POINT 24898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* Normalize to 180 so we can square it and it still fits in 16 bits */ 24998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project cshift = normalize16(corr, corr16, 180, end-start+1); 25098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* If we scaled weighted input down, we need to scale it up again (OK, so we've just lost the LSB, who cares?) */ 25198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (scaledown) 25298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 25398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=-end;i<len;i++) 25498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 25598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project sw[i]=SHL16(sw[i],1); 25698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 25798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 25898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 25998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 26098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* Search for the best pitch prediction gain */ 26198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=start;i<=end;i++) 26298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 26398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t tmp = MULT16_16_16(corr16[i-start],corr16[i-start]); 26498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* Instead of dividing the tmp by the energy, we multiply on the other side */ 26598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (MULT16_16(tmp,best_ener[N-1])>MULT16_16(best_score[N-1],ADD16(1,ener16[i-start]))) 26698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 26798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* We can safely put it last and then check */ 26898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project best_score[N-1]=tmp; 26998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project best_ener[N-1]=ener16[i-start]+1; 27098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project pitch[N-1]=i; 27198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* Check if it comes in front of others */ 27298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (j=0;j<N-1;j++) 27398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 27498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (MULT16_16(tmp,best_ener[j])>MULT16_16(best_score[j],ADD16(1,ener16[i-start]))) 27598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 27698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (k=N-1;k>j;k--) 27798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 27898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project best_score[k]=best_score[k-1]; 27998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project best_ener[k]=best_ener[k-1]; 28098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project pitch[k]=pitch[k-1]; 28198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 28298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project best_score[j]=tmp; 28398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project best_ener[j]=ener16[i-start]+1; 28498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project pitch[j]=i; 28598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project break; 28698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 28798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 28898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 28998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 29098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 29198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* Compute open-loop gain if necessary */ 29298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (gain) 29398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 29498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (j=0;j<N;j++) 29598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 29698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t g; 29798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project i=pitch[j]; 29898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project g = DIV32(SHL32(EXTEND32(corr16[i-start]),cshift), 10+SHR32(MULT16_16(spx_sqrt(e0),spx_sqrt(SHL32(EXTEND32(ener16[i-start]),eshift))),6)); 29998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* FIXME: g = max(g,corr/energy) */ 30098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (g<0) 30198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project g = 0; 30298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project gain[j]=g; 30398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 30498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 30598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 30698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 30798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project} 30898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 30998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 31098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifndef OVERRIDE_PITCH_GAIN_SEARCH_3TAP_VQ 31198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectstatic int pitch_gain_search_3tap_vq( 31298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project const signed char *gain_cdbk, 31398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int gain_cdbk_size, 31498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t *C16, 31598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t max_gain 31698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project) 31798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{ 31898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project const signed char *ptr=gain_cdbk; 31998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int best_cdbk=0; 32098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word32_t best_sum=-VERY_LARGE32; 32198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word32_t sum=0; 32298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t g[3]; 32398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t pitch_control=64; 32498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t gain_sum; 32598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int i; 32698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 32798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<gain_cdbk_size;i++) { 32898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 32998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project ptr = gain_cdbk+4*i; 33098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project g[0]=ADD16((spx_word16_t)ptr[0],32); 33198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project g[1]=ADD16((spx_word16_t)ptr[1],32); 33298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project g[2]=ADD16((spx_word16_t)ptr[2],32); 33398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project gain_sum = (spx_word16_t)ptr[3]; 33498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 33598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project sum = compute_pitch_error(C16, g, pitch_control); 33698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 33798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (sum>best_sum && gain_sum<=max_gain) { 33898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project best_sum=sum; 33998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project best_cdbk=i; 34098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 34198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 34298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 34398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project return best_cdbk; 34498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project} 34598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 34698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 34798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project/** Finds the best quantized 3-tap pitch predictor by analysis by synthesis */ 34898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectstatic spx_word32_t pitch_gain_search_3tap( 34998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectconst spx_word16_t target[], /* Target vector */ 35098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectconst spx_coef_t ak[], /* LPCs for this subframe */ 35198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectconst spx_coef_t awk1[], /* Weighted LPCs #1 for this subframe */ 35298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectconst spx_coef_t awk2[], /* Weighted LPCs #2 for this subframe */ 35398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectspx_sig_t exc[], /* Excitation */ 35498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectconst signed char *gain_cdbk, 35598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectint gain_cdbk_size, 35698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectint pitch, /* Pitch value */ 35798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectint p, /* Number of LPC coeffs */ 35898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectint nsf, /* Number of samples in subframe */ 35998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source ProjectSpeexBits *bits, 36098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectchar *stack, 36198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectconst spx_word16_t *exc2, 36298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectconst spx_word16_t *r, 36398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectspx_word16_t *new_target, 36498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectint *cdbk_index, 36598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectint plc_tuning, 36698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectspx_word32_t cumul_gain, 36798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectint scaledown 36898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project) 36998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{ 37098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int i,j; 37198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project VARDECL(spx_word16_t *tmp1); 37298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project VARDECL(spx_word16_t *e); 37398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t *x[3]; 37498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word32_t corr[3]; 37598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word32_t A[3][3]; 37698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t gain[3]; 37798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word32_t err; 37898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t max_gain=128; 37998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int best_cdbk=0; 38098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 38198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project ALLOC(tmp1, 3*nsf, spx_word16_t); 38298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project ALLOC(e, nsf, spx_word16_t); 38398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 38498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (cumul_gain > 262144) 38598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project max_gain = 31; 38698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 38798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project x[0]=tmp1; 38898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project x[1]=tmp1+nsf; 38998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project x[2]=tmp1+2*nsf; 39098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 39198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (j=0;j<nsf;j++) 39298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project new_target[j] = target[j]; 39398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 39498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 39598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project VARDECL(spx_mem_t *mm); 39698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int pp=pitch-1; 39798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project ALLOC(mm, p, spx_mem_t); 39898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (j=0;j<nsf;j++) 39998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 40098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (j-pp<0) 40198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project e[j]=exc2[j-pp]; 40298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project else if (j-pp-pitch<0) 40398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project e[j]=exc2[j-pp-pitch]; 40498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project else 40598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project e[j]=0; 40698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 40798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef FIXED_POINT 40898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* Scale target and excitation down if needed (avoiding overflow) */ 40998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (scaledown) 41098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 41198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (j=0;j<nsf;j++) 41298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project e[j] = SHR16(e[j],1); 41398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (j=0;j<nsf;j++) 41498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project new_target[j] = SHR16(new_target[j],1); 41598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 41698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 41798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (j=0;j<p;j++) 41898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project mm[j] = 0; 41998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project iir_mem16(e, ak, e, nsf, p, mm, stack); 42098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (j=0;j<p;j++) 42198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project mm[j] = 0; 42298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project filter_mem16(e, awk1, awk2, e, nsf, p, mm, stack); 42398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (j=0;j<nsf;j++) 42498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project x[2][j] = e[j]; 42598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 42698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=1;i>=0;i--) 42798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 42898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t e0=exc2[-pitch-1+i]; 42998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef FIXED_POINT 43098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* Scale excitation down if needed (avoiding overflow) */ 43198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (scaledown) 43298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project e0 = SHR16(e0,1); 43398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 43498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project x[i][0]=MULT16_16_Q14(r[0], e0); 43598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (j=0;j<nsf-1;j++) 43698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project x[i][j+1]=ADD32(x[i+1][j],MULT16_16_P14(r[j+1], e0)); 43798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 43898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 43998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<3;i++) 44098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project corr[i]=inner_prod(x[i],new_target,nsf); 44198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<3;i++) 44298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (j=0;j<=i;j++) 44398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project A[i][j]=A[j][i]=inner_prod(x[i],x[j],nsf); 44498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 44598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 44698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word32_t C[9]; 44798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef FIXED_POINT 44898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t C16[9]; 44998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#else 45098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t *C16=C; 45198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 45298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project C[0]=corr[2]; 45398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project C[1]=corr[1]; 45498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project C[2]=corr[0]; 45598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project C[3]=A[1][2]; 45698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project C[4]=A[0][1]; 45798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project C[5]=A[0][2]; 45898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project C[6]=A[2][2]; 45998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project C[7]=A[1][1]; 46098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project C[8]=A[0][0]; 46198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 46298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /*plc_tuning *= 2;*/ 46398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (plc_tuning<2) 46498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project plc_tuning=2; 46598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (plc_tuning>30) 46698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project plc_tuning=30; 46798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef FIXED_POINT 46898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project C[0] = SHL32(C[0],1); 46998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project C[1] = SHL32(C[1],1); 47098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project C[2] = SHL32(C[2],1); 47198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project C[3] = SHL32(C[3],1); 47298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project C[4] = SHL32(C[4],1); 47398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project C[5] = SHL32(C[5],1); 47498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project C[6] = MAC16_32_Q15(C[6],MULT16_16_16(plc_tuning,655),C[6]); 47598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project C[7] = MAC16_32_Q15(C[7],MULT16_16_16(plc_tuning,655),C[7]); 47698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project C[8] = MAC16_32_Q15(C[8],MULT16_16_16(plc_tuning,655),C[8]); 47798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project normalize16(C, C16, 32767, 9); 47898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#else 47998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project C[6]*=.5*(1+.02*plc_tuning); 48098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project C[7]*=.5*(1+.02*plc_tuning); 48198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project C[8]*=.5*(1+.02*plc_tuning); 48298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 48398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 48498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project best_cdbk = pitch_gain_search_3tap_vq(gain_cdbk, gain_cdbk_size, C16, max_gain); 48598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 48698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef FIXED_POINT 48798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project gain[0] = ADD16(32,(spx_word16_t)gain_cdbk[best_cdbk*4]); 48898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project gain[1] = ADD16(32,(spx_word16_t)gain_cdbk[best_cdbk*4+1]); 48998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project gain[2] = ADD16(32,(spx_word16_t)gain_cdbk[best_cdbk*4+2]); 49098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /*printf ("%d %d %d %d\n",gain[0],gain[1],gain[2], best_cdbk);*/ 49198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#else 49298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project gain[0] = 0.015625*gain_cdbk[best_cdbk*4] + .5; 49398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project gain[1] = 0.015625*gain_cdbk[best_cdbk*4+1]+ .5; 49498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project gain[2] = 0.015625*gain_cdbk[best_cdbk*4+2]+ .5; 49598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 49698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project *cdbk_index=best_cdbk; 49798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 49898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 49998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project SPEEX_MEMSET(exc, 0, nsf); 50098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<3;i++) 50198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 50298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int j; 50398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int tmp1, tmp3; 50498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int pp=pitch+1-i; 50598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project tmp1=nsf; 50698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (tmp1>pp) 50798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project tmp1=pp; 50898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (j=0;j<tmp1;j++) 50998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project exc[j]=MAC16_16(exc[j],SHL16(gain[2-i],7),exc2[j-pp]); 51098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project tmp3=nsf; 51198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (tmp3>pp+pitch) 51298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project tmp3=pp+pitch; 51398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (j=tmp1;j<tmp3;j++) 51498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project exc[j]=MAC16_16(exc[j],SHL16(gain[2-i],7),exc2[j-pp-pitch]); 51598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 51698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<nsf;i++) 51798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 51898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word32_t tmp = ADD32(ADD32(MULT16_16(gain[0],x[2][i]),MULT16_16(gain[1],x[1][i])), 51998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project MULT16_16(gain[2],x[0][i])); 52098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project new_target[i] = SUB16(new_target[i], EXTRACT16(PSHR32(tmp,6))); 52198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 52298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project err = inner_prod(new_target, new_target, nsf); 52398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 52498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project return err; 52598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project} 52698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 52798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project/** Finds the best quantized 3-tap pitch predictor by analysis by synthesis */ 52898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectint pitch_search_3tap( 52998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectspx_word16_t target[], /* Target vector */ 53098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectspx_word16_t *sw, 53198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectspx_coef_t ak[], /* LPCs for this subframe */ 53298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectspx_coef_t awk1[], /* Weighted LPCs #1 for this subframe */ 53398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectspx_coef_t awk2[], /* Weighted LPCs #2 for this subframe */ 53498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectspx_sig_t exc[], /* Excitation */ 53598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectconst void *par, 53698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectint start, /* Smallest pitch value allowed */ 53798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectint end, /* Largest pitch value allowed */ 53898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectspx_word16_t pitch_coef, /* Voicing (pitch) coefficient */ 53998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectint p, /* Number of LPC coeffs */ 54098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectint nsf, /* Number of samples in subframe */ 54198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source ProjectSpeexBits *bits, 54298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectchar *stack, 54398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectspx_word16_t *exc2, 54498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectspx_word16_t *r, 54598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectint complexity, 54698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectint cdbk_offset, 54798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectint plc_tuning, 54898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectspx_word32_t *cumul_gain 54998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project) 55098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{ 55198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int i; 55298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int cdbk_index, pitch=0, best_gain_index=0; 55398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project VARDECL(spx_sig_t *best_exc); 55498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project VARDECL(spx_word16_t *new_target); 55598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project VARDECL(spx_word16_t *best_target); 55698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int best_pitch=0; 55798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word32_t err, best_err=-1; 55898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int N; 55998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project const ltp_params *params; 56098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project const signed char *gain_cdbk; 56198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int gain_cdbk_size; 56298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int scaledown=0; 56398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 56498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project VARDECL(int *nbest); 56598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 56698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project params = (const ltp_params*) par; 56798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project gain_cdbk_size = 1<<params->gain_bits; 56898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project gain_cdbk = params->gain_cdbk + 4*gain_cdbk_size*cdbk_offset; 56998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 57098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project N=complexity; 57198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (N>10) 57298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project N=10; 57398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (N<1) 57498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project N=1; 57598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 57698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project ALLOC(nbest, N, int); 57798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project params = (const ltp_params*) par; 57898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 57998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (end<start) 58098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 58198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project speex_bits_pack(bits, 0, params->pitch_bits); 58298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project speex_bits_pack(bits, 0, params->gain_bits); 58398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project SPEEX_MEMSET(exc, 0, nsf); 58498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project return start; 58598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 58698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 58798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef FIXED_POINT 58898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* Check if we need to scale everything down in the pitch search to avoid overflows */ 58998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<nsf;i++) 59098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 59198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (ABS16(target[i])>16383) 59298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 59398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project scaledown=1; 59498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project break; 59598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 59698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 59798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=-end;i<nsf;i++) 59898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 59998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (ABS16(exc2[i])>16383) 60098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 60198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project scaledown=1; 60298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project break; 60398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 60498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 60598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 60698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (N>end-start+1) 60798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project N=end-start+1; 60898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (end != start) 60998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project open_loop_nbest_pitch(sw, start, end, nsf, nbest, NULL, N, stack); 61098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project else 61198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project nbest[0] = start; 61298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 61398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project ALLOC(best_exc, nsf, spx_sig_t); 61498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project ALLOC(new_target, nsf, spx_word16_t); 61598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project ALLOC(best_target, nsf, spx_word16_t); 61698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 61798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<N;i++) 61898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 61998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project pitch=nbest[i]; 62098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project SPEEX_MEMSET(exc, 0, nsf); 62198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project err=pitch_gain_search_3tap(target, ak, awk1, awk2, exc, gain_cdbk, gain_cdbk_size, pitch, p, nsf, 62298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project bits, stack, exc2, r, new_target, &cdbk_index, plc_tuning, *cumul_gain, scaledown); 62398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (err<best_err || best_err<0) 62498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 62598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project SPEEX_COPY(best_exc, exc, nsf); 62698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project SPEEX_COPY(best_target, new_target, nsf); 62798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project best_err=err; 62898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project best_pitch=pitch; 62998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project best_gain_index=cdbk_index; 63098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 63198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 63298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /*printf ("pitch: %d %d\n", best_pitch, best_gain_index);*/ 63398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project speex_bits_pack(bits, best_pitch-start, params->pitch_bits); 63498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project speex_bits_pack(bits, best_gain_index, params->gain_bits); 63598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef FIXED_POINT 63698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project *cumul_gain = MULT16_32_Q13(SHL16(params->gain_cdbk[4*best_gain_index+3],8), MAX32(1024,*cumul_gain)); 63798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#else 63898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project *cumul_gain = 0.03125*MAX32(1024,*cumul_gain)*params->gain_cdbk[4*best_gain_index+3]; 63998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 64098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /*printf ("%f\n", cumul_gain);*/ 64198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /*printf ("encode pitch: %d %d\n", best_pitch, best_gain_index);*/ 64298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project SPEEX_COPY(exc, best_exc, nsf); 64398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project SPEEX_COPY(target, best_target, nsf); 64498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef FIXED_POINT 64598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /* Scale target back up if needed */ 64698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (scaledown) 64798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 64898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<nsf;i++) 64998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project target[i]=SHL16(target[i],1); 65098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 65198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 65298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project return pitch; 65398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project} 65498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 65598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectvoid pitch_unquant_3tap( 65698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectspx_word16_t exc[], /* Input excitation */ 65798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectspx_word32_t exc_out[], /* Output excitation */ 65898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectint start, /* Smallest pitch value allowed */ 65998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectint end, /* Largest pitch value allowed */ 66098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectspx_word16_t pitch_coef, /* Voicing (pitch) coefficient */ 66198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectconst void *par, 66298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectint nsf, /* Number of samples in subframe */ 66398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectint *pitch_val, 66498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectspx_word16_t *gain_val, 66598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source ProjectSpeexBits *bits, 66698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectchar *stack, 66798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectint count_lost, 66898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectint subframe_offset, 66998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectspx_word16_t last_pitch_gain, 67098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectint cdbk_offset 67198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project) 67298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{ 67398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int i; 67498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int pitch; 67598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int gain_index; 67698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t gain[3]; 67798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project const signed char *gain_cdbk; 67898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int gain_cdbk_size; 67998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project const ltp_params *params; 68098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 68198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project params = (const ltp_params*) par; 68298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project gain_cdbk_size = 1<<params->gain_bits; 68398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project gain_cdbk = params->gain_cdbk + 4*gain_cdbk_size*cdbk_offset; 68498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 68598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project pitch = speex_bits_unpack_unsigned(bits, params->pitch_bits); 68698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project pitch += start; 68798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project gain_index = speex_bits_unpack_unsigned(bits, params->gain_bits); 68898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /*printf ("decode pitch: %d %d\n", pitch, gain_index);*/ 68998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef FIXED_POINT 69098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project gain[0] = ADD16(32,(spx_word16_t)gain_cdbk[gain_index*4]); 69198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project gain[1] = ADD16(32,(spx_word16_t)gain_cdbk[gain_index*4+1]); 69298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project gain[2] = ADD16(32,(spx_word16_t)gain_cdbk[gain_index*4+2]); 69398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#else 69498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project gain[0] = 0.015625*gain_cdbk[gain_index*4]+.5; 69598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project gain[1] = 0.015625*gain_cdbk[gain_index*4+1]+.5; 69698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project gain[2] = 0.015625*gain_cdbk[gain_index*4+2]+.5; 69798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 69898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 69998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (count_lost && pitch > subframe_offset) 70098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 70198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t gain_sum; 70298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (1) { 70398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef FIXED_POINT 70498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t tmp = count_lost < 4 ? last_pitch_gain : SHR16(last_pitch_gain,1); 70598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (tmp>62) 70698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project tmp=62; 70798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#else 70898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t tmp = count_lost < 4 ? last_pitch_gain : 0.5 * last_pitch_gain; 70998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (tmp>.95) 71098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project tmp=.95; 71198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 71298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project gain_sum = gain_3tap_to_1tap(gain); 71398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 71498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (gain_sum > tmp) 71598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 71698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project spx_word16_t fact = DIV32_16(SHL32(EXTEND32(tmp),14),gain_sum); 71798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<3;i++) 71898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project gain[i]=MULT16_16_Q14(fact,gain[i]); 71998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 72098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 72198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 72298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 72398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 72498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 72598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project *pitch_val = pitch; 72698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project gain_val[0]=gain[0]; 72798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project gain_val[1]=gain[1]; 72898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project gain_val[2]=gain[2]; 72998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project gain[0] = SHL16(gain[0],7); 73098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project gain[1] = SHL16(gain[1],7); 73198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project gain[2] = SHL16(gain[2],7); 73298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project SPEEX_MEMSET(exc_out, 0, nsf); 73398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<3;i++) 73498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 73598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int j; 73698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int tmp1, tmp3; 73798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int pp=pitch+1-i; 73898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project tmp1=nsf; 73998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (tmp1>pp) 74098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project tmp1=pp; 74198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (j=0;j<tmp1;j++) 74298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project exc_out[j]=MAC16_16(exc_out[j],gain[2-i],exc[j-pp]); 74398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project tmp3=nsf; 74498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (tmp3>pp+pitch) 74598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project tmp3=pp+pitch; 74698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (j=tmp1;j<tmp3;j++) 74798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project exc_out[j]=MAC16_16(exc_out[j],gain[2-i],exc[j-pp-pitch]); 74898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 74998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /*for (i=0;i<nsf;i++) 75098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project exc[i]=PSHR32(exc32[i],13);*/ 75198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project} 75298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 75398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 75498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project/** Forced pitch delay and gain */ 75598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectint forced_pitch_quant( 75698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectspx_word16_t target[], /* Target vector */ 75798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectspx_word16_t *sw, 75898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectspx_coef_t ak[], /* LPCs for this subframe */ 75998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectspx_coef_t awk1[], /* Weighted LPCs #1 for this subframe */ 76098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectspx_coef_t awk2[], /* Weighted LPCs #2 for this subframe */ 76198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectspx_sig_t exc[], /* Excitation */ 76298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectconst void *par, 76398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectint start, /* Smallest pitch value allowed */ 76498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectint end, /* Largest pitch value allowed */ 76598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectspx_word16_t pitch_coef, /* Voicing (pitch) coefficient */ 76698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectint p, /* Number of LPC coeffs */ 76798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectint nsf, /* Number of samples in subframe */ 76898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source ProjectSpeexBits *bits, 76998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectchar *stack, 77098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectspx_word16_t *exc2, 77198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectspx_word16_t *r, 77298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectint complexity, 77398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectint cdbk_offset, 77498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectint plc_tuning, 77598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectspx_word32_t *cumul_gain 77698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project) 77798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{ 77898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int i; 77998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project VARDECL(spx_word16_t *res); 78098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project ALLOC(res, nsf, spx_word16_t); 78198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef FIXED_POINT 78298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (pitch_coef>63) 78398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project pitch_coef=63; 78498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#else 78598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (pitch_coef>.99) 78698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project pitch_coef=.99; 78798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 78898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<nsf&&i<start;i++) 78998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 79098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project exc[i]=MULT16_16(SHL16(pitch_coef, 7),exc2[i-start]); 79198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 79298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (;i<nsf;i++) 79398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 79498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project exc[i]=MULT16_32_Q15(SHL16(pitch_coef, 9),exc[i-start]); 79598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 79698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<nsf;i++) 79798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project res[i] = EXTRACT16(PSHR32(exc[i], SIG_SHIFT-1)); 79898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project syn_percep_zero16(res, ak, awk1, awk2, res, nsf, p, stack); 79998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<nsf;i++) 80098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project target[i]=EXTRACT16(SATURATE(SUB32(EXTEND32(target[i]),EXTEND32(res[i])),32700)); 80198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project return start; 80298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project} 80398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 80498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project/** Unquantize forced pitch delay and gain */ 80598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectvoid forced_pitch_unquant( 80698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectspx_word16_t exc[], /* Input excitation */ 80798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectspx_word32_t exc_out[], /* Output excitation */ 80898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectint start, /* Smallest pitch value allowed */ 80998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectint end, /* Largest pitch value allowed */ 81098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectspx_word16_t pitch_coef, /* Voicing (pitch) coefficient */ 81198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectconst void *par, 81298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectint nsf, /* Number of samples in subframe */ 81398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectint *pitch_val, 81498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectspx_word16_t *gain_val, 81598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source ProjectSpeexBits *bits, 81698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectchar *stack, 81798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectint count_lost, 81898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectint subframe_offset, 81998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectspx_word16_t last_pitch_gain, 82098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectint cdbk_offset 82198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project) 82298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project{ 82398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project int i; 82498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifdef FIXED_POINT 82598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (pitch_coef>63) 82698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project pitch_coef=63; 82798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#else 82898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (pitch_coef>.99) 82998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project pitch_coef=.99; 83098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#endif 83198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project for (i=0;i<nsf;i++) 83298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project { 83398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project exc_out[i]=MULT16_16(exc[i-start],SHL16(pitch_coef,7)); 83498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project exc[i] = EXTRACT16(PSHR32(exc_out[i],13)); 83598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 83698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project *pitch_val = start; 83798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project gain_val[0]=gain_val[2]=0; 83898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project gain_val[1] = pitch_coef; 83998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project} 840