1e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/*
2e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** Copyright 2003-2010, VisualOn, Inc.
3e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard **
4e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** Licensed under the Apache License, Version 2.0 (the "License");
5e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** you may not use this file except in compliance with the License.
6e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** You may obtain a copy of the License at
7e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard **
8e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard **     http://www.apache.org/licenses/LICENSE-2.0
9e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard **
10e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** Unless required by applicable law or agreed to in writing, software
11e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** distributed under the License is distributed on an "AS IS" BASIS,
12e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** See the License for the specific language governing permissions and
14e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** limitations under the License.
15e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard */
16e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
17e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/***********************************************************************
18e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*      File: pitch_f4.c                                                *
19e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*                                                                      *
20e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*      Description: Find the closed loop pitch period with             *
21e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*	            1/4 subsample resolution.                          *
22e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*                                                                      *
23e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard************************************************************************/
24e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
25e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "typedef.h"
26e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "basic_op.h"
27e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "math_op.h"
28e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "acelp.h"
29e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "cnst.h"
30e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
31e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#define UP_SAMP      4
32e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#define L_INTERPOL1  4
33e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
34442cc6dc48f8188e097617f7f804c314a9dacd0eAndreas Huber#define UNUSED(x) (void)(x)
35442cc6dc48f8188e097617f7f804c314a9dacd0eAndreas Huber
36e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/* Local functions */
37e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
38e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#ifdef ASM_OPT
39e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardvoid Norm_corr_asm(
40e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 exc[],                         /* (i)     : excitation buffer                     */
41e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 xn[],                          /* (i)     : target vector                         */
42e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 h[],                           /* (i) Q15 : impulse response of synth/wgt filters */
43e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 L_subfr,
44e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 t_min,                         /* (i)     : minimum value of pitch lag.           */
45e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 t_max,                         /* (i)     : maximum value of pitch lag.           */
46e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 corr_norm[]                    /* (o) Q15 : normalized correlation                */
47e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		);
48e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#else
49e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardstatic void Norm_Corr(
50e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 exc[],                         /* (i)     : excitation buffer                     */
51e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 xn[],                          /* (i)     : target vector                         */
52e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 h[],                           /* (i) Q15 : impulse response of synth/wgt filters */
53e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 L_subfr,
54e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 t_min,                         /* (i)     : minimum value of pitch lag.           */
55e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 t_max,                         /* (i)     : maximum value of pitch lag.           */
56e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 corr_norm[]                    /* (o) Q15 : normalized correlation                */
57e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		);
58e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#endif
59e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
60e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardstatic Word16 Interpol_4(                  /* (o)  : interpolated value  */
61e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 * x,                           /* (i)  : input vector        */
62e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word32 frac                           /* (i)  : fraction (-4..+3)   */
63e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		);
64e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
65e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
66e2e838afcf03e603a41a0455846eaf9614537c16Mans RullgardWord16 Pitch_fr4(                          /* (o)     : pitch period.                         */
67e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 exc[],                         /* (i)     : excitation buffer                     */
68e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 xn[],                          /* (i)     : target vector                         */
69e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 h[],                           /* (i) Q15 : impulse response of synth/wgt filters */
70e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 t0_min,                        /* (i)     : minimum value in the searched range.  */
71e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 t0_max,                        /* (i)     : maximum value in the searched range.  */
72e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 * pit_frac,                    /* (o)     : chosen fraction (0, 1, 2 or 3).       */
73e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 i_subfr,                       /* (i)     : indicator for first subframe.         */
74e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 t0_fr2,                        /* (i)     : minimum value for resolution 1/2      */
75e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 t0_fr1,                        /* (i)     : minimum value for resolution 1        */
76e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 L_subfr                        /* (i)     : Length of subframe                    */
77e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		)
78e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{
79e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Word32 fraction, i;
80e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Word16 t_min, t_max;
81e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Word16 max, t0, step, temp;
82e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Word16 *corr;
83e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Word16 corr_v[40];                     /* Total length = t0_max-t0_min+1+2*L_inter */
84e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
85e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* Find interval to compute normalized correlation */
86e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
87e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	t_min = t0_min - L_INTERPOL1;
88e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	t_max = t0_max + L_INTERPOL1;
89e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	corr = &corr_v[-t_min];
90e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* Compute normalized correlation between target and filtered excitation */
91e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#ifdef ASM_OPT               /* asm optimization branch */
92e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard    Norm_corr_asm(exc, xn, h, L_subfr, t_min, t_max, corr);
93e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#else
94e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Norm_Corr(exc, xn, h, L_subfr, t_min, t_max, corr);
95b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard#endif
96e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
97e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* Find integer pitch */
98e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
99e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	max = corr[t0_min];
100e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	t0 = t0_min;
101e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	for (i = t0_min + 1; i <= t0_max; i++)
102e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
103e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		if (corr[i] >= max)
104e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		{
105b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			max = corr[i];
106b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			t0 = i;
107e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		}
108e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	}
109e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* If first subframe and t0 >= t0_fr1, do not search fractionnal pitch */
110e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	if ((i_subfr == 0) && (t0 >= t0_fr1))
111e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
112e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		*pit_frac = 0;
113e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		return (t0);
114e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	}
115e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/*------------------------------------------------------------------*
116e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	 * Search fractionnal pitch with 1/4 subsample resolution.          *
117e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	 * Test the fractions around t0 and choose the one which maximizes  *
118e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	 * the interpolated normalized correlation.                         *
119e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	 *------------------------------------------------------------------*/
120e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
121e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	step = 1;               /* 1/4 subsample resolution */
122e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	fraction = -3;
123e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	if ((t0_fr2 == PIT_MIN)||((i_subfr == 0) && (t0 >= t0_fr2)))
124e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
125e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		step = 2;              /* 1/2 subsample resolution */
126e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		fraction = -2;
127e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	}
128e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	if(t0 == t0_min)
129e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
130e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		fraction = 0;
131e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	}
132e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	max = Interpol_4(&corr[t0], fraction);
133e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
134e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	for (i = fraction + step; i <= 3; i += step)
135e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
136e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		temp = Interpol_4(&corr[t0], i);
137e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		if(temp > max)
138e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		{
139e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			max = temp;
140e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			fraction = i;
141e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		}
142e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	}
143e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* limit the fraction value in the interval [0,1,2,3] */
144e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	if (fraction < 0)
145e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
146e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		fraction += UP_SAMP;
147e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		t0 -= 1;
148e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	}
149e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	*pit_frac = fraction;
150e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	return (t0);
151e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard}
152e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
153e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
154e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/***********************************************************************************
155e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* Function:  Norm_Corr()                                                            *
156e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*                                                                                   *
157e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* Description: Find the normalized correlation between the target vector and the    *
158e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* filtered past excitation.                                                         *
159e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* (correlation between target and filtered excitation divided by the                *
160e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*  square root of energy of target and filtered excitation).                        *
161e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard************************************************************************************/
162e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#ifndef ASM_OPT
163e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardstatic void Norm_Corr(
164e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 exc[],                         /* (i)     : excitation buffer                     */
165e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 xn[],                          /* (i)     : target vector                         */
166e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 h[],                           /* (i) Q15 : impulse response of synth/wgt filters */
167e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 L_subfr,
168e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 t_min,                         /* (i)     : minimum value of pitch lag.           */
169e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 t_max,                         /* (i)     : maximum value of pitch lag.           */
170e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 corr_norm[])                   /* (o) Q15 : normalized correlation                */
171e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{
172e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Word32 i, k, t;
173e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Word32 corr, exp_corr, norm, exp, scale;
174e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Word16 exp_norm, excf[L_SUBFR], tmp;
175e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Word32 L_tmp, L_tmp1, L_tmp2;
176442cc6dc48f8188e097617f7f804c314a9dacd0eAndreas Huber        UNUSED(L_subfr);
177e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
178e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* compute the filtered excitation for the first delay t_min */
179e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	k = -t_min;
180e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
181e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#ifdef ASM_OPT              /* asm optimization branch */
182e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Convolve_asm(&exc[k], h, excf, 64);
183e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#else
184e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Convolve(&exc[k], h, excf, 64);
185e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#endif
186e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
187e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* Compute rounded down 1/sqrt(energy of xn[]) */
188b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	L_tmp = 0;
189e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	for (i = 0; i < 64; i+=4)
190e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
191e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		L_tmp += (xn[i] * xn[i]);
192e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		L_tmp += (xn[i+1] * xn[i+1]);
193e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		L_tmp += (xn[i+2] * xn[i+2]);
194e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		L_tmp += (xn[i+3] * xn[i+3]);
195e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	}
196e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
197e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	L_tmp = (L_tmp << 1) + 1;
198e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	exp = norm_l(L_tmp);
199e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	exp = (32 - exp);
200e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	//exp = exp + 2;                     /* energy of xn[] x 2 + rounded up     */
201e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	scale = -(exp >> 1);           /* (1<<scale) < 1/sqrt(energy rounded) */
202e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
203e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* loop for every possible period */
204e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
205e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	for (t = t_min; t <= t_max; t++)
206e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
207e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		/* Compute correlation between xn[] and excf[] */
208b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		L_tmp  = 0;
209e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		L_tmp1 = 0;
210e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		for (i = 0; i < 64; i+=4)
211e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		{
212e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			L_tmp  += (xn[i] * excf[i]);
213e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			L_tmp1 += (excf[i] * excf[i]);
214e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			L_tmp  += (xn[i+1] * excf[i+1]);
215e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			L_tmp1 += (excf[i+1] * excf[i+1]);
216e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			L_tmp  += (xn[i+2] * excf[i+2]);
217e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			L_tmp1 += (excf[i+2] * excf[i+2]);
218e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			L_tmp  += (xn[i+3] * excf[i+3]);
219e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			L_tmp1 += (excf[i+3] * excf[i+3]);
220e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		}
221e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
222e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		L_tmp = (L_tmp << 1) + 1;
223e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		L_tmp1 = (L_tmp1 << 1) + 1;
224e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
225e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		exp = norm_l(L_tmp);
226e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		L_tmp = (L_tmp << exp);
227e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		exp_corr = (30 - exp);
228e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		corr = extract_h(L_tmp);
229e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
230e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		exp = norm_l(L_tmp1);
231e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		L_tmp = (L_tmp1 << exp);
232e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		exp_norm = (30 - exp);
233e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
234e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Isqrt_n(&L_tmp, &exp_norm);
235e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		norm = extract_h(L_tmp);
236e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
237e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		/* Normalize correlation = correlation * (1/sqrt(energy)) */
238e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
239e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		L_tmp = vo_L_mult(corr, norm);
240e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
241e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		L_tmp2 = exp_corr + exp_norm + scale;
242e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		if(L_tmp2 < 0)
243e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		{
244e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			L_tmp2 = -L_tmp2;
245e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			L_tmp = L_tmp >> L_tmp2;
246e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		}
247e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		else
248e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		{
249e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			L_tmp = L_tmp << L_tmp2;
250e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		}
251e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
252b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		corr_norm[t] = vo_round(L_tmp);
253e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		/* modify the filtered excitation excf[] for the next iteration */
254e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
255e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		if(t != t_max)
256e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		{
257e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			k = -(t + 1);
258e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			tmp = exc[k];
259e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			for (i = 63; i > 0; i--)
260e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			{
261e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard				excf[i] = add1(vo_mult(tmp, h[i]), excf[i - 1]);
262e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			}
263e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			excf[0] = vo_mult(tmp, h[0]);
264e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		}
265e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	}
266e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	return;
267e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard}
268e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
269e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#endif
270e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/************************************************************************************
271e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* Function: Interpol_4()                                                             *
272e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*                                                                                    *
273e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* Description: For interpolating the normalized correlation with 1/4 resolution.     *
274e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard**************************************************************************************/
275e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
276e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/* 1/4 resolution interpolation filter (-3 dB at 0.791*fs/2) in Q14 */
277e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardstatic Word16 inter4_1[4][8] =
278e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{
279e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{-12, 420, -1732, 5429, 13418, -1242, 73, 32},
280e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{-26, 455, -2142, 9910, 9910,  -2142, 455, -26},
281e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{32,  73, -1242, 13418, 5429, -1732, 420, -12},
282e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{206, -766, 1376, 14746, 1376, -766, 206, 0}
283e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard};
284e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
285e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/*** Coefficients in floating point
286e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardstatic float inter4_1[UP_SAMP*L_INTERPOL1+1] = {
287e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard0.900000,
288e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard0.818959,  0.604850,  0.331379,  0.083958,
289e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard-0.075795, -0.130717, -0.105685, -0.046774,
290e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard0.004467,  0.027789,  0.025642,  0.012571,
291e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard0.001927, -0.001571, -0.000753,  0.000000};
292e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard***/
293e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
294e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardstatic Word16 Interpol_4(                  /* (o)  : interpolated value  */
295e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 * x,                           /* (i)  : input vector        */
296e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word32 frac                           /* (i)  : fraction (-4..+3)   */
297e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		)
298e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{
299e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Word16 sum;
300e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Word32  k, L_sum;
301e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Word16 *ptr;
302e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
303e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	if (frac < 0)
304e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
305e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		frac += UP_SAMP;
306e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		x--;
307e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	}
308e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	x = x - L_INTERPOL1 + 1;
309e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	k = UP_SAMP - 1 - frac;
310e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	ptr = &(inter4_1[k][0]);
311e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
312e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	L_sum  = vo_mult32(x[0], (*ptr++));
313e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	L_sum += vo_mult32(x[1], (*ptr++));
314e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	L_sum += vo_mult32(x[2], (*ptr++));
315e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	L_sum += vo_mult32(x[3], (*ptr++));
316b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	L_sum += vo_mult32(x[4], (*ptr++));
317e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	L_sum += vo_mult32(x[5], (*ptr++));
318e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	L_sum += vo_mult32(x[6], (*ptr++));
319b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	L_sum += vo_mult32(x[7], (*ptr++));
320e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
321e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	sum = extract_h(L_add(L_shl2(L_sum, 2), 0x8000));
322e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	return (sum);
323e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard}
324e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
325e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
326e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
327e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
328