1 /*
2 ** Copyright 2003-2010, VisualOn, Inc.
3 **
4 ** Licensed under the Apache License, Version 2.0 (the "License");
5 ** you may not use this file except in compliance with the License.
6 ** You may obtain a copy of the License at
7 **
8 ** http://www.apache.org/licenses/LICENSE-2.0
9 **
10 ** Unless required by applicable law or agreed to in writing, software
11 ** distributed under the License is distributed on an "AS IS" BASIS,
12 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 ** See the License for the specific language governing permissions and
14 ** limitations under the License.
15 */
16
17 /***********************************************************************
18 * File: p_med_ol.c *
19 * *
20 * Description: Compute the open loop pitch lag *
21 * output: open loop pitch lag *
22 ************************************************************************/
23
24 #include "typedef.h"
25 #include "basic_op.h"
26 #include "acelp.h"
27 #include "oper_32b.h"
28 #include "math_op.h"
29 #include "p_med_ol.tab"
30
Pitch_med_ol(Word16 wsp[],Coder_State * st,Word16 L_frame)31 Word16 Pitch_med_ol(
32 Word16 wsp[], /* i: signal used to compute the open loop pitch*/
33 /* wsp[-pit_max] to wsp[-1] should be known */
34 Coder_State *st, /* i/o: codec global structure */
35 Word16 L_frame /* i: length of frame to compute pitch */
36 )
37 {
38 Word16 Tm;
39 Word16 hi, lo;
40 Word16 *ww, *we, *hp_wsp;
41 Word16 exp_R0, exp_R1, exp_R2;
42 Word32 i, j, max, R0, R1, R2;
43 Word16 *p1, *p2;
44 Word16 L_min = 17; /* minimum pitch lag: PIT_MIN / OPL_DECIM */
45 Word16 L_max = 115; /* maximum pitch lag: PIT_MAX / OPL_DECIM */
46 Word16 L_0 = st->old_T0_med; /* old open-loop pitch */
47 Word16 *gain = &(st->ol_gain); /* normalize correlation of hp_wsp for the lag */
48 Word16 *hp_wsp_mem = st->hp_wsp_mem; /* memory of the hypass filter for hp_wsp[] (lg = 9)*/
49 Word16 *old_hp_wsp = st->old_hp_wsp; /* hypass wsp[] */
50 Word16 wght_flg = st->ol_wght_flg; /* is weighting function used */
51
52 ww = &corrweight[198];
53 we = &corrweight[98 + L_max - L_0];
54
55 max = MIN_32;
56 Tm = 0;
57 for (i = L_max; i > L_min; i--)
58 {
59 /* Compute the correlation */
60 R0 = 0;
61 p1 = wsp;
62 p2 = &wsp[-i];
63 for (j = 0; j < L_frame; j+=4)
64 {
65 R0 += vo_L_mult((*p1++), (*p2++));
66 R0 += vo_L_mult((*p1++), (*p2++));
67 R0 += vo_L_mult((*p1++), (*p2++));
68 R0 += vo_L_mult((*p1++), (*p2++));
69 }
70 /* Weighting of the correlation function. */
71 hi = R0>>16;
72 lo = (R0 & 0xffff)>>1;
73
74 R0 = Mpy_32_16(hi, lo, *ww);
75 ww--;
76
77 if ((L_0 > 0) && (wght_flg > 0))
78 {
79 /* Weight the neighbourhood of the old lag. */
80 hi = R0>>16;
81 lo = (R0 & 0xffff)>>1;
82 R0 = Mpy_32_16(hi, lo, *we);
83 we--;
84 }
85 if(R0 >= max)
86 {
87 max = R0;
88 Tm = i;
89 }
90 }
91
92 /* Hypass the wsp[] vector */
93 hp_wsp = old_hp_wsp + L_max;
94 Hp_wsp(wsp, hp_wsp, L_frame, hp_wsp_mem);
95
96 /* Compute normalize correlation at delay Tm */
97 R0 = 0;
98 R1 = 0;
99 R2 = 0;
100 p1 = hp_wsp;
101 p2 = hp_wsp - Tm;
102 for (j = 0; j < L_frame; j+=4)
103 {
104 R2 += vo_mult32(*p1, *p1);
105 R1 += vo_mult32(*p2, *p2);
106 R0 += vo_mult32(*p1++, *p2++);
107 R2 += vo_mult32(*p1, *p1);
108 R1 += vo_mult32(*p2, *p2);
109 R0 += vo_mult32(*p1++, *p2++);
110 R2 += vo_mult32(*p1, *p1);
111 R1 += vo_mult32(*p2, *p2);
112 R0 += vo_mult32(*p1++, *p2++);
113 R2 += vo_mult32(*p1, *p1);
114 R1 += vo_mult32(*p2, *p2);
115 R0 += vo_mult32(*p1++, *p2++);
116 }
117 R0 = R0 <<1;
118 R1 = (R1 <<1) + 1L;
119 R2 = (R2 <<1) + 1L;
120 /* gain = R0/ sqrt(R1*R2) */
121
122 exp_R0 = norm_l(R0);
123 R0 = (R0 << exp_R0);
124
125 exp_R1 = norm_l(R1);
126 R1 = (R1 << exp_R1);
127
128 exp_R2 = norm_l(R2);
129 R2 = (R2 << exp_R2);
130
131
132 R1 = vo_L_mult(voround(R1), voround(R2));
133
134 i = norm_l(R1);
135 R1 = (R1 << i);
136
137 exp_R1 += exp_R2;
138 exp_R1 += i;
139 exp_R1 = 62 - exp_R1;
140
141 Isqrt_n(&R1, &exp_R1);
142
143 R0 = vo_L_mult(voround(R0), voround(R1));
144 exp_R0 = 31 - exp_R0;
145 exp_R0 += exp_R1;
146
147 *gain = vo_round(L_shl(R0, exp_R0));
148
149 /* Shitf hp_wsp[] for next frame */
150
151 for (i = 0; i < L_max; i++)
152 {
153 old_hp_wsp[i] = old_hp_wsp[i + L_frame];
154 }
155
156 return (Tm);
157 }
158
159 /************************************************************************
160 * Function: median5 *
161 * *
162 * Returns the median of the set {X[-2], X[-1],..., X[2]}, *
163 * whose elements are 16-bit integers. *
164 * *
165 * Input: *
166 * X[-2:2] 16-bit integers. *
167 * *
168 * Return: *
169 * The median of {X[-2], X[-1],..., X[2]}. *
170 ************************************************************************/
171
median5(Word16 x[])172 Word16 median5(Word16 x[])
173 {
174 Word16 x1, x2, x3, x4, x5;
175 Word16 tmp;
176
177 x1 = x[-2];
178 x2 = x[-1];
179 x3 = x[0];
180 x4 = x[1];
181 x5 = x[2];
182
183 if (x2 < x1)
184 {
185 tmp = x1;
186 x1 = x2;
187 x2 = tmp;
188 }
189 if (x3 < x1)
190 {
191 tmp = x1;
192 x1 = x3;
193 x3 = tmp;
194 }
195 if (x4 < x1)
196 {
197 tmp = x1;
198 x1 = x4;
199 x4 = tmp;
200 }
201 if (x5 < x1)
202 {
203 x5 = x1;
204 }
205 if (x3 < x2)
206 {
207 tmp = x2;
208 x2 = x3;
209 x3 = tmp;
210 }
211 if (x4 < x2)
212 {
213 tmp = x2;
214 x2 = x4;
215 x4 = tmp;
216 }
217 if (x5 < x2)
218 {
219 x5 = x2;
220 }
221 if (x4 < x3)
222 {
223 x3 = x4;
224 }
225 if (x5 < x3)
226 {
227 x3 = x5;
228 }
229 return (x3);
230 }
231
232
Med_olag(Word16 prev_ol_lag,Word16 old_ol_lag[5])233 Word16 Med_olag( /* output : median of 5 previous open-loop lags */
234 Word16 prev_ol_lag, /* input : previous open-loop lag */
235 Word16 old_ol_lag[5]
236 )
237 {
238 Word32 i;
239
240 /* Use median of 5 previous open-loop lags as old lag */
241
242 for (i = 4; i > 0; i--)
243 {
244 old_ol_lag[i] = old_ol_lag[i - 1];
245 }
246
247 old_ol_lag[0] = prev_ol_lag;
248
249 i = median5(&old_ol_lag[2]);
250
251 return i;
252
253 }
254
255
256
257