1885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/* Copyright (c) 2007-2008 CSIRO 2885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Copyright (c) 2007-2009 Xiph.Org Foundation 3885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Written by Jean-Marc Valin */ 4885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/** 5885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org @file pitch.c 6885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org @brief Pitch analysis 7885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org */ 8885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 9885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/* 10885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Redistribution and use in source and binary forms, with or without 11885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org modification, are permitted provided that the following conditions 12885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org are met: 13885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 14885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org - Redistributions of source code must retain the above copyright 15885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org notice, this list of conditions and the following disclaimer. 16885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 17885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org - Redistributions in binary form must reproduce the above copyright 18885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org notice, this list of conditions and the following disclaimer in the 19885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org documentation and/or other materials provided with the distribution. 20885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 21885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 25885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 26885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 27885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 28885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 29885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 30885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 31885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org*/ 33885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 34885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifdef HAVE_CONFIG_H 35885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "config.h" 36885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif 37885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 38885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "pitch.h" 39885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "os_support.h" 40885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "modes.h" 41885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "stack_alloc.h" 42885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "mathops.h" 43885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "celt_lpc.h" 44885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 45885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgstatic void find_best_pitch(opus_val32 *xcorr, opus_val16 *y, int len, 46885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int max_pitch, int *best_pitch 47885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifdef FIXED_POINT 48885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org , int yshift, opus_val32 maxcorr 49885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif 50885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org ) 51885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{ 52885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int i, j; 53885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_val32 Syy=1; 54885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_val16 best_num[2]; 55885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_val32 best_den[2]; 56885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifdef FIXED_POINT 57885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int xshift; 58885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 59885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org xshift = celt_ilog2(maxcorr)-14; 60885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif 61885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 62885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org best_num[0] = -1; 63885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org best_num[1] = -1; 64885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org best_den[0] = 0; 65885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org best_den[1] = 0; 66885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org best_pitch[0] = 0; 67885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org best_pitch[1] = 1; 68885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for (j=0;j<len;j++) 69885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Syy = ADD32(Syy, SHR32(MULT16_16(y[j],y[j]), yshift)); 70885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for (i=0;i<max_pitch;i++) 71885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 72885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (xcorr[i]>0) 73885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 74885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_val16 num; 75885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_val32 xcorr16; 76885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org xcorr16 = EXTRACT16(VSHR32(xcorr[i], xshift)); 77885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifndef FIXED_POINT 78885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* Considering the range of xcorr16, this should avoid both underflows 79885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org and overflows (inf) when squaring xcorr16 */ 806b6bee25314cfac02cc555cddedb9680c63a26d6sergeyu@chromium.org xcorr16 *= 1e-12f; 81885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif 82885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org num = MULT16_16_Q15(xcorr16,xcorr16); 83885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (MULT16_32_Q15(num,best_den[1]) > MULT16_32_Q15(best_num[1],Syy)) 84885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 85885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (MULT16_32_Q15(num,best_den[0]) > MULT16_32_Q15(best_num[0],Syy)) 86885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 87885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org best_num[1] = best_num[0]; 88885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org best_den[1] = best_den[0]; 89885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org best_pitch[1] = best_pitch[0]; 90885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org best_num[0] = num; 91885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org best_den[0] = Syy; 92885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org best_pitch[0] = i; 93885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } else { 94885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org best_num[1] = num; 95885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org best_den[1] = Syy; 96885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org best_pitch[1] = i; 97885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 98885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 99885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 100885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Syy += SHR32(MULT16_16(y[i+len],y[i+len]),yshift) - SHR32(MULT16_16(y[i],y[i]),yshift); 101885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Syy = MAX32(1, Syy); 102885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 103885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org} 104885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 105e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.orgstatic void celt_fir5(const opus_val16 *x, 106e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org const opus_val16 *num, 107e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_val16 *y, 108e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int N, 109e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_val16 *mem) 110e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org{ 111e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int i; 112e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_val16 num0, num1, num2, num3, num4; 113e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_val32 mem0, mem1, mem2, mem3, mem4; 114e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org num0=num[0]; 115e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org num1=num[1]; 116e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org num2=num[2]; 117e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org num3=num[3]; 118e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org num4=num[4]; 119e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org mem0=mem[0]; 120e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org mem1=mem[1]; 121e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org mem2=mem[2]; 122e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org mem3=mem[3]; 123e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org mem4=mem[4]; 124e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org for (i=0;i<N;i++) 125e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 126e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_val32 sum = SHL32(EXTEND32(x[i]), SIG_SHIFT); 127e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org sum = MAC16_16(sum,num0,mem0); 128e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org sum = MAC16_16(sum,num1,mem1); 129e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org sum = MAC16_16(sum,num2,mem2); 130e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org sum = MAC16_16(sum,num3,mem3); 131e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org sum = MAC16_16(sum,num4,mem4); 132e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org mem4 = mem3; 133e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org mem3 = mem2; 134e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org mem2 = mem1; 135e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org mem1 = mem0; 136e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org mem0 = x[i]; 137e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org y[i] = ROUND16(sum, SIG_SHIFT); 138e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 139e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org mem[0]=mem0; 140e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org mem[1]=mem1; 141e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org mem[2]=mem2; 142e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org mem[3]=mem3; 143e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org mem[4]=mem4; 144e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org} 145e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 146e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 147885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgvoid pitch_downsample(celt_sig * OPUS_RESTRICT x[], opus_val16 * OPUS_RESTRICT x_lp, 1483c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com int len, int C, int arch) 149885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{ 150885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int i; 151885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_val32 ac[5]; 152885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_val16 tmp=Q15ONE; 153e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_val16 lpc[4], mem[5]={0,0,0,0,0}; 154e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_val16 lpc2[5]; 155e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_val16 c1 = QCONST16(.8f,15); 156885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifdef FIXED_POINT 157885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int shift; 158885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_val32 maxabs = celt_maxabs32(x[0], len); 159885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (C==2) 160885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 161885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_val32 maxabs_1 = celt_maxabs32(x[1], len); 162885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org maxabs = MAX32(maxabs, maxabs_1); 163885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 164885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (maxabs<1) 165885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org maxabs=1; 166885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org shift = celt_ilog2(maxabs)-10; 167885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (shift<0) 168885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org shift=0; 169885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (C==2) 170885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org shift++; 171885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif 172885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for (i=1;i<len>>1;i++) 173885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org x_lp[i] = SHR32(HALF32(HALF32(x[0][(2*i-1)]+x[0][(2*i+1)])+x[0][2*i]), shift); 174885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org x_lp[0] = SHR32(HALF32(HALF32(x[0][1])+x[0][0]), shift); 175885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (C==2) 176885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 177885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for (i=1;i<len>>1;i++) 178885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org x_lp[i] += SHR32(HALF32(HALF32(x[1][(2*i-1)]+x[1][(2*i+1)])+x[1][2*i]), shift); 179885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org x_lp[0] += SHR32(HALF32(HALF32(x[1][1])+x[1][0]), shift); 180885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 181885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 182885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org _celt_autocorr(x_lp, ac, NULL, 0, 1833c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com 4, len>>1, arch); 184885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 185885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* Noise floor -40 dB */ 186885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifdef FIXED_POINT 187885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org ac[0] += SHR32(ac[0],13); 188885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#else 189885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org ac[0] *= 1.0001f; 190885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif 191885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* Lag windowing */ 192885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for (i=1;i<=4;i++) 193885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 194885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /*ac[i] *= exp(-.5*(2*M_PI*.002*i)*(2*M_PI*.002*i));*/ 195885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifdef FIXED_POINT 196885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org ac[i] -= MULT16_32_Q15(2*i*i, ac[i]); 197885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#else 198885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org ac[i] -= ac[i]*(.008f*i)*(.008f*i); 199885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif 200885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 201885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 202885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org _celt_lpc(lpc, ac, 4); 203885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for (i=0;i<4;i++) 204885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 205885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org tmp = MULT16_16_Q15(QCONST16(.9f,15), tmp); 206885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org lpc[i] = MULT16_16_Q15(lpc[i], tmp); 207885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 208e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org /* Add a zero */ 209e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org lpc2[0] = lpc[0] + QCONST16(.8f,SIG_SHIFT); 210e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org lpc2[1] = lpc[1] + MULT16_16_Q15(c1,lpc[0]); 211e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org lpc2[2] = lpc[2] + MULT16_16_Q15(c1,lpc[1]); 212e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org lpc2[3] = lpc[3] + MULT16_16_Q15(c1,lpc[2]); 213e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org lpc2[4] = MULT16_16_Q15(c1,lpc[3]); 214e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org celt_fir5(x_lp, lpc2, x_lp, len>>1, mem); 215e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org} 216885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 217e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#if 0 /* This is a simple version of the pitch correlation that should work 218e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org well on DSPs like Blackfin and TI C5x/C6x */ 219885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 220e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#ifdef FIXED_POINT 221e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.orgopus_val32 222e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#else 223e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.orgvoid 224e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#endif 225e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.orgcelt_pitch_xcorr(opus_val16 *x, opus_val16 *y, opus_val32 *xcorr, int len, int max_pitch) 226e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org{ 227e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int i, j; 228e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#ifdef FIXED_POINT 229e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_val32 maxcorr=1; 230e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#endif 231e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org for (i=0;i<max_pitch;i++) 232e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 233e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_val32 sum = 0; 234e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org for (j=0;j<len;j++) 235e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org sum = MAC16_16(sum, x[j],y[i+j]); 236e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org xcorr[i] = sum; 237e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#ifdef FIXED_POINT 238e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org maxcorr = MAX32(maxcorr, sum); 239e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#endif 240e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 241e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#ifdef FIXED_POINT 242e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org return maxcorr; 243e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#endif 244885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org} 245885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 246e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#else /* Unrolled version of the pitch correlation -- runs faster on x86 and ARM */ 247e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 248e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#ifdef FIXED_POINT 249e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.orgopus_val32 250e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#else 251e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.orgvoid 252e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#endif 2533c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.comcelt_pitch_xcorr_c(const opus_val16 *_x, const opus_val16 *_y, opus_val32 *xcorr, int len, int max_pitch) 254e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org{ 255e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int i,j; 2563c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com /*The EDSP version requires that max_pitch is at least 1, and that _x is 2573c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com 32-bit aligned. 2583c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com Since it's hard to put asserts in assembly, put them here.*/ 2593c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com celt_assert(max_pitch>0); 2603c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com celt_assert((((unsigned char *)_x-(unsigned char *)NULL)&3)==0); 261e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#ifdef FIXED_POINT 262e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_val32 maxcorr=1; 263e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#endif 264e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org for (i=0;i<max_pitch-3;i+=4) 265e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 266e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_val32 sum[4]={0,0,0,0}; 267e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org xcorr_kernel(_x, _y+i, sum, len); 268e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org xcorr[i]=sum[0]; 269e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org xcorr[i+1]=sum[1]; 270e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org xcorr[i+2]=sum[2]; 271e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org xcorr[i+3]=sum[3]; 272e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#ifdef FIXED_POINT 273e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org sum[0] = MAX32(sum[0], sum[1]); 274e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org sum[2] = MAX32(sum[2], sum[3]); 275e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org sum[0] = MAX32(sum[0], sum[2]); 276e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org maxcorr = MAX32(maxcorr, sum[0]); 277e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#endif 278e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 279e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org /* In case max_pitch isn't a multiple of 4, do non-unrolled version. */ 280e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org for (;i<max_pitch;i++) 281e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 282e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_val32 sum = 0; 283e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org for (j=0;j<len;j++) 284e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org sum = MAC16_16(sum, _x[j],_y[i+j]); 285e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org xcorr[i] = sum; 286e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#ifdef FIXED_POINT 287e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org maxcorr = MAX32(maxcorr, sum); 288e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#endif 289e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 290e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#ifdef FIXED_POINT 291e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org return maxcorr; 292e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#endif 293e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org} 294e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 295e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#endif 296885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgvoid pitch_search(const opus_val16 * OPUS_RESTRICT x_lp, opus_val16 * OPUS_RESTRICT y, 2973c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com int len, int max_pitch, int *pitch, int arch) 298885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{ 299885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int i, j; 300885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int lag; 301885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int best_pitch[2]={0,0}; 302885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org VARDECL(opus_val16, x_lp4); 303885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org VARDECL(opus_val16, y_lp4); 304885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org VARDECL(opus_val32, xcorr); 305885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifdef FIXED_POINT 306e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_val32 maxcorr; 307e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_val32 xmax, ymax; 308885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int shift=0; 309885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif 310885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int offset; 311885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 312885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org SAVE_STACK; 313885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 314885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org celt_assert(len>0); 315885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org celt_assert(max_pitch>0); 316885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org lag = len+max_pitch; 317885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 318885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org ALLOC(x_lp4, len>>2, opus_val16); 319885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org ALLOC(y_lp4, lag>>2, opus_val16); 320885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org ALLOC(xcorr, max_pitch>>1, opus_val32); 321885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 322885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* Downsample by 2 again */ 323885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for (j=0;j<len>>2;j++) 324885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org x_lp4[j] = x_lp[2*j]; 325885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for (j=0;j<lag>>2;j++) 326885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org y_lp4[j] = y[2*j]; 327885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 328885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifdef FIXED_POINT 329885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org xmax = celt_maxabs16(x_lp4, len>>2); 330885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org ymax = celt_maxabs16(y_lp4, lag>>2); 331e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org shift = celt_ilog2(MAX32(1, MAX32(xmax, ymax)))-11; 332885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (shift>0) 333885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 334885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for (j=0;j<len>>2;j++) 335885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org x_lp4[j] = SHR16(x_lp4[j], shift); 336885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for (j=0;j<lag>>2;j++) 337885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org y_lp4[j] = SHR16(y_lp4[j], shift); 338885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* Use double the shift for a MAC */ 339885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org shift *= 2; 340885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } else { 341885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org shift = 0; 342885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 343885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif 344885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 345885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* Coarse search with 4x decimation */ 346885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 347885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifdef FIXED_POINT 348e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org maxcorr = 349885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif 3503c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com celt_pitch_xcorr(x_lp4, y_lp4, xcorr, len>>2, max_pitch>>2, arch); 351e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 352885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org find_best_pitch(xcorr, y_lp4, len>>2, max_pitch>>2, best_pitch 353885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifdef FIXED_POINT 354885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org , 0, maxcorr 355885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif 356885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org ); 357885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 358885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* Finer search with 2x decimation */ 359885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifdef FIXED_POINT 360885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org maxcorr=1; 361885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif 362885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for (i=0;i<max_pitch>>1;i++) 363885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 364885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_val32 sum=0; 365885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org xcorr[i] = 0; 366885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (abs(i-2*best_pitch[0])>2 && abs(i-2*best_pitch[1])>2) 367885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org continue; 368885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for (j=0;j<len>>1;j++) 369885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org sum += SHR32(MULT16_16(x_lp[j],y[i+j]), shift); 370885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org xcorr[i] = MAX32(-1, sum); 371885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifdef FIXED_POINT 372885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org maxcorr = MAX32(maxcorr, sum); 373885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif 374885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 375885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org find_best_pitch(xcorr, y, len>>1, max_pitch>>1, best_pitch 376885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifdef FIXED_POINT 377885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org , shift+1, maxcorr 378885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif 379885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org ); 380885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 381885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* Refine by pseudo-interpolation */ 382885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (best_pitch[0]>0 && best_pitch[0]<(max_pitch>>1)-1) 383885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 384885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_val32 a, b, c; 385885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org a = xcorr[best_pitch[0]-1]; 386885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org b = xcorr[best_pitch[0]]; 387885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org c = xcorr[best_pitch[0]+1]; 388885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if ((c-a) > MULT16_32_Q15(QCONST16(.7f,15),b-a)) 389885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org offset = 1; 390885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org else if ((a-c) > MULT16_32_Q15(QCONST16(.7f,15),b-c)) 391885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org offset = -1; 392885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org else 393885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org offset = 0; 394885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } else { 395885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org offset = 0; 396885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 397885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org *pitch = 2*best_pitch[0]-offset; 398885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 399885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org RESTORE_STACK; 400885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org} 401885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 402885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgstatic const int second_check[16] = {0, 0, 3, 2, 3, 2, 5, 2, 3, 2, 3, 2, 5, 2, 3, 2}; 403885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgopus_val16 remove_doubling(opus_val16 *x, int maxperiod, int minperiod, 404885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int N, int *T0_, int prev_period, opus_val16 prev_gain) 405885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{ 406885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int k, i, T, T0; 407885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_val16 g, g0; 408885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_val16 pg; 409e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_val32 xy,xx,yy,xy2; 410885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_val32 xcorr[3]; 411885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_val32 best_xy, best_yy; 412885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int offset; 413885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int minperiod0; 414e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org VARDECL(opus_val32, yy_lookup); 415e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org SAVE_STACK; 416885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 417885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org minperiod0 = minperiod; 418885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org maxperiod /= 2; 419885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org minperiod /= 2; 420885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org *T0_ /= 2; 421885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org prev_period /= 2; 422885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org N /= 2; 423885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org x += maxperiod; 424885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (*T0_>=maxperiod) 425885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org *T0_=maxperiod-1; 426885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 427885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org T = T0 = *T0_; 428e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ALLOC(yy_lookup, maxperiod+1, opus_val32); 429e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org dual_inner_prod(x, x, x-T0, N, &xx, &xy); 430e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org yy_lookup[0] = xx; 431e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org yy=xx; 432e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org for (i=1;i<=maxperiod;i++) 433885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 434e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org yy = yy+MULT16_16(x[-i],x[-i])-MULT16_16(x[N-i],x[N-i]); 435e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org yy_lookup[i] = MAX32(0, yy); 436885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 437e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org yy = yy_lookup[T0]; 438885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org best_xy = xy; 439885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org best_yy = yy; 440885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifdef FIXED_POINT 441885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 442885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_val32 x2y2; 443885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int sh, t; 444885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org x2y2 = 1+HALF32(MULT32_32_Q31(xx,yy)); 445885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org sh = celt_ilog2(x2y2)>>1; 446885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org t = VSHR32(x2y2, 2*(sh-7)); 447885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org g = g0 = VSHR32(MULT16_32_Q15(celt_rsqrt_norm(t), xy),sh+1); 448885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 449885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#else 450885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org g = g0 = xy/celt_sqrt(1+xx*yy); 451885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif 452885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* Look for any pitch at T/k */ 453885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for (k=2;k<=15;k++) 454885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 455885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int T1, T1b; 456885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_val16 g1; 457885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_val16 cont=0; 458e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_val16 thresh; 459885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org T1 = (2*T0+k)/(2*k); 460885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (T1 < minperiod) 461885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org break; 462885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /* Look for another strong correlation at T1b */ 463885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (k==2) 464885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 465885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (T1+T0>maxperiod) 466885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org T1b = T0; 467885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org else 468885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org T1b = T0+T1; 469885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } else 470885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 471885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org T1b = (2*second_check[k]*T0+k)/(2*k); 472885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 473e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org dual_inner_prod(x, &x[-T1], &x[-T1b], N, &xy, &xy2); 474e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org xy += xy2; 475e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org yy = yy_lookup[T1] + yy_lookup[T1b]; 476885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifdef FIXED_POINT 477885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 478885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org opus_val32 x2y2; 479885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int sh, t; 480885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org x2y2 = 1+MULT32_32_Q31(xx,yy); 481885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org sh = celt_ilog2(x2y2)>>1; 482885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org t = VSHR32(x2y2, 2*(sh-7)); 483885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org g1 = VSHR32(MULT16_32_Q15(celt_rsqrt_norm(t), xy),sh+1); 484885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 485885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#else 486885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org g1 = xy/celt_sqrt(1+2.f*xx*1.f*yy); 487885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif 488885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (abs(T1-prev_period)<=1) 489885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org cont = prev_gain; 490885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org else if (abs(T1-prev_period)<=2 && 5*k*k < T0) 491885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org cont = HALF32(prev_gain); 492885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org else 493885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org cont = 0; 494e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org thresh = MAX16(QCONST16(.3f,15), MULT16_16_Q15(QCONST16(.7f,15),g0)-cont); 495e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org /* Bias against very high pitch (very short period) to avoid false-positives 496e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org due to short-term correlation */ 497e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (T1<3*minperiod) 498e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org thresh = MAX16(QCONST16(.4f,15), MULT16_16_Q15(QCONST16(.85f,15),g0)-cont); 499e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org else if (T1<2*minperiod) 500e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org thresh = MAX16(QCONST16(.5f,15), MULT16_16_Q15(QCONST16(.9f,15),g0)-cont); 501e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (g1 > thresh) 502885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 503885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org best_xy = xy; 504885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org best_yy = yy; 505885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org T = T1; 506885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org g = g1; 507885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 508885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 509885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org best_xy = MAX32(0, best_xy); 510885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (best_yy <= best_xy) 511885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org pg = Q15ONE; 512885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org else 513885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org pg = SHR32(frac_div32(best_xy,best_yy+1),16); 514885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 515885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for (k=0;k<3;k++) 516885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org { 517885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org int T1 = T+k-1; 518885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org xy = 0; 519885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org for (i=0;i<N;i++) 520885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org xy = MAC16_16(xy, x[i], x[i-T1]); 521885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org xcorr[k] = xy; 522885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 523885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if ((xcorr[2]-xcorr[0]) > MULT16_32_Q15(QCONST16(.7f,15),xcorr[1]-xcorr[0])) 524885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org offset = 1; 525885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org else if ((xcorr[0]-xcorr[2]) > MULT16_32_Q15(QCONST16(.7f,15),xcorr[1]-xcorr[2])) 526885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org offset = -1; 527885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org else 528885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org offset = 0; 529885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (pg > g) 530885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org pg = g; 531885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org *T0_ = 2*T+offset; 532885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 533885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org if (*T0_<minperiod0) 534885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org *T0_=minperiod0; 535e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org RESTORE_STACK; 536885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org return pg; 537885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org} 538