FreeCalypso > hg > gsm-codec-lib
comparison libtwamr/pitch_ol.c @ 415:01c4becb9fda
libtwamr: integrate pitch_ol.c
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Tue, 07 May 2024 03:01:01 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
414:028ed5114e52 | 415:01c4becb9fda |
---|---|
1 /* | |
2 ******************************************************************************** | |
3 * | |
4 * GSM AMR-NB speech codec R98 Version 7.6.0 December 12, 2001 | |
5 * R99 Version 3.3.0 | |
6 * REL-4 Version 4.1.0 | |
7 * | |
8 ******************************************************************************** | |
9 * | |
10 * File : pitch_ol.c | |
11 * Purpose : Compute the open loop pitch lag. | |
12 * | |
13 ******************************************************************************** | |
14 */ | |
15 /* | |
16 ******************************************************************************** | |
17 * MODULE INCLUDE FILE AND VERSION ID | |
18 ******************************************************************************** | |
19 */ | |
20 #include "namespace.h" | |
21 #include "pitch_ol.h" | |
22 /* | |
23 ******************************************************************************** | |
24 * INCLUDE FILES | |
25 ******************************************************************************** | |
26 */ | |
27 #include "typedef.h" | |
28 #include "basic_op.h" | |
29 #include "oper_32b.h" | |
30 #include "no_count.h" | |
31 #include "cnst.h" | |
32 #include "inv_sqrt.h" | |
33 #include "vad.h" | |
34 #include "calc_cor.h" | |
35 #include "hp_max.h" | |
36 | |
37 /* | |
38 ******************************************************************************** | |
39 * LOCAL VARIABLES AND TABLES | |
40 ******************************************************************************** | |
41 */ | |
42 #define THRESHOLD 27853 | |
43 | |
44 /* | |
45 ******************************************************************************** | |
46 * LOCAL PROGRAM CODE | |
47 ******************************************************************************** | |
48 */ | |
49 /************************************************************************* | |
50 * | |
51 * FUNCTION: Lag_max | |
52 * | |
53 * PURPOSE: Find the lag that has maximum correlation of scal_sig[] in a | |
54 * given delay range. | |
55 * | |
56 * DESCRIPTION: | |
57 * The correlation is given by | |
58 * cor[t] = <scal_sig[n],scal_sig[n-t]>, t=lag_min,...,lag_max | |
59 * The functions outputs the maximum correlation after normalization | |
60 * and the corresponding lag. | |
61 * | |
62 *************************************************************************/ | |
63 static Word16 Lag_max ( /* o : lag found */ | |
64 vadState *vadSt, /* i/o : VAD state struct */ | |
65 Word32 corr[], /* i : correlation vector. */ | |
66 Word16 scal_sig[], /* i : scaled signal. */ | |
67 Word16 scal_fac, /* i : scaled signal factor. */ | |
68 Word16 scal_flag, /* i : if 1 use EFR compatible scaling */ | |
69 Word16 L_frame, /* i : length of frame to compute pitch */ | |
70 Word16 lag_max, /* i : maximum lag */ | |
71 Word16 lag_min, /* i : minimum lag */ | |
72 Word16 *cor_max, /* o : normalized correlation of selected lag */ | |
73 Word32 *rmax, /* o : max(<s[i]*s[j]>) */ | |
74 Word32 *r0, /* o : residual energy */ | |
75 Flag dtx /* i : dtx flag; use dtx=1, do not use dtx=0 */ | |
76 ) | |
77 { | |
78 Word16 i, j; | |
79 Word16 *p; | |
80 Word32 max, t0; | |
81 Word16 max_h, max_l, ener_h, ener_l; | |
82 Word16 p_max = 0; /* initialization only needed to keep gcc silent */ | |
83 | |
84 max = MIN_32; move32 (); | |
85 p_max = lag_max; move16 (); | |
86 | |
87 for (i = lag_max, j = (PIT_MAX-lag_max-1); i >= lag_min; i--, j--) | |
88 { | |
89 test (); | |
90 if (L_sub (corr[-i], max) >= 0) | |
91 { | |
92 max = corr[-i]; move32 (); | |
93 p_max = i; move16 (); | |
94 } | |
95 } | |
96 | |
97 /* compute energy */ | |
98 | |
99 t0 = 0; move32 (); | |
100 p = &scal_sig[-p_max]; move16 (); | |
101 for (i = 0; i < L_frame; i++, p++) | |
102 { | |
103 t0 = L_mac (t0, *p, *p); | |
104 } | |
105 /* 1/sqrt(energy) */ | |
106 | |
107 if (dtx) | |
108 { /* no test() call since this if is only in simulation env */ | |
109 *rmax = max; move32(); | |
110 *r0 = t0; move32(); | |
111 /* check tone */ | |
112 if (!vadSt->use_vad2) | |
113 vad_tone_detection (&vadSt->u.v1, max, t0); | |
114 } | |
115 | |
116 t0 = Inv_sqrt (t0); move32 (); /* function result */ | |
117 | |
118 test(); | |
119 if (scal_flag) | |
120 { | |
121 t0 = L_shl (t0, 1); | |
122 } | |
123 | |
124 /* max = max/sqrt(energy) */ | |
125 | |
126 L_Extract (max, &max_h, &max_l); | |
127 L_Extract (t0, &ener_h, &ener_l); | |
128 | |
129 t0 = Mpy_32 (max_h, max_l, ener_h, ener_l); | |
130 | |
131 test(); | |
132 if (scal_flag) | |
133 { | |
134 t0 = L_shr (t0, scal_fac); | |
135 *cor_max = extract_h (L_shl (t0, 15)); /* divide by 2 */ | |
136 } | |
137 else | |
138 { | |
139 *cor_max = extract_l(t0); | |
140 } | |
141 | |
142 return (p_max); | |
143 } | |
144 | |
145 /* | |
146 ******************************************************************************** | |
147 * PUBLIC PROGRAM CODE | |
148 ******************************************************************************** | |
149 */ | |
150 /************************************************************************* | |
151 * | |
152 * FUNCTION: Pitch_ol | |
153 * | |
154 * PURPOSE: Compute the open loop pitch lag. | |
155 * | |
156 * DESCRIPTION: | |
157 * The open-loop pitch lag is determined based on the perceptually | |
158 * weighted speech signal. This is done in the following steps: | |
159 * - find three maxima of the correlation <sw[n],sw[n-T]>, | |
160 * dividing the search range into three parts: | |
161 * pit_min ... 2*pit_min-1 | |
162 * 2*pit_min ... 4*pit_min-1 | |
163 * 4*pit_min ... pit_max | |
164 * - divide each maximum by <sw[n-t], sw[n-t]> where t is the delay at | |
165 * that maximum correlation. | |
166 * - select the delay of maximum normalized correlation (among the | |
167 * three candidates) while favoring the lower delay ranges. | |
168 * | |
169 *************************************************************************/ | |
170 Word16 Pitch_ol ( /* o : open loop pitch lag */ | |
171 vadState *vadSt, /* i/o : VAD state struct */ | |
172 enum Mode mode, /* i : coder mode */ | |
173 Word16 signal[], /* i : signal used to compute the open loop pitch */ | |
174 /* signal[-pit_max] to signal[-1] should be known */ | |
175 Word16 pit_min, /* i : minimum pitch lag */ | |
176 Word16 pit_max, /* i : maximum pitch lag */ | |
177 Word16 L_frame, /* i : length of frame to compute pitch */ | |
178 Word16 idx, /* i : frame index */ | |
179 Flag dtx /* i : dtx flag; use dtx=1, do not use dtx=0 */ | |
180 ) | |
181 { | |
182 Word16 i, j; | |
183 Word16 max1, max2, max3; | |
184 Word16 p_max1, p_max2, p_max3; | |
185 Word16 scal_flag = 0; | |
186 Word32 t0; | |
187 Word32 r01, r02, r03; | |
188 Word32 rmax1, rmax2, rmax3; | |
189 Word16 corr_hp_max; | |
190 Word32 corr[PIT_MAX+1], *corr_ptr; | |
191 | |
192 /* Scaled signal */ | |
193 | |
194 Word16 scaled_signal[L_FRAME + PIT_MAX]; | |
195 Word16 *scal_sig, scal_fac; | |
196 | |
197 if (dtx && !vadSt->use_vad2) | |
198 { /* no test() call since this if is only in simulation env */ | |
199 /* update tone detection */ | |
200 test(); test(); | |
201 if ((sub(mode, MR475) == 0) || (sub(mode, MR515) == 0)) | |
202 { | |
203 vad_tone_detection_update (&vadSt->u.v1, 1); | |
204 } | |
205 else | |
206 { | |
207 vad_tone_detection_update (&vadSt->u.v1, 0); | |
208 } | |
209 } | |
210 | |
211 scal_sig = &scaled_signal[pit_max]; move16 (); | |
212 | |
213 t0 = 0L; move32 (); | |
214 for (i = -pit_max; i < L_frame; i++) | |
215 { | |
216 t0 = L_mac (t0, signal[i], signal[i]); | |
217 } | |
218 | |
219 /*--------------------------------------------------------* | |
220 * Scaling of input signal. * | |
221 * * | |
222 * if Overflow -> scal_sig[i] = signal[i]>>3 * | |
223 * else if t0 < 1^20 -> scal_sig[i] = signal[i]<<3 * | |
224 * else -> scal_sig[i] = signal[i] * | |
225 *--------------------------------------------------------*/ | |
226 | |
227 /*--------------------------------------------------------* | |
228 * Verification for risk of overflow. * | |
229 *--------------------------------------------------------*/ | |
230 | |
231 test (); | |
232 if (L_sub (t0, MAX_32) == 0L) /* Test for overflow */ | |
233 { | |
234 for (i = -pit_max; i < L_frame; i++) | |
235 { | |
236 scal_sig[i] = shr (signal[i], 3); move16 (); | |
237 } | |
238 scal_fac = 3; move16 (); | |
239 } | |
240 else if (L_sub (t0, (Word32) 1048576L) < (Word32) 0) | |
241 /* if (t0 < 2^20) */ | |
242 { | |
243 test (); | |
244 for (i = -pit_max; i < L_frame; i++) | |
245 { | |
246 scal_sig[i] = shl (signal[i], 3); move16 (); | |
247 } | |
248 scal_fac = -3; move16 (); | |
249 } | |
250 else | |
251 { | |
252 test (); | |
253 for (i = -pit_max; i < L_frame; i++) | |
254 { | |
255 scal_sig[i] = signal[i]; move16 (); | |
256 } | |
257 scal_fac = 0; move16 (); | |
258 } | |
259 | |
260 /* calculate all coreelations of scal_sig, from pit_min to pit_max */ | |
261 corr_ptr = &corr[pit_max]; move32 (); | |
262 comp_corr (scal_sig, L_frame, pit_max, pit_min, corr_ptr); | |
263 | |
264 /*--------------------------------------------------------------------* | |
265 * The pitch lag search is divided in three sections. * | |
266 * Each section cannot have a pitch multiple. * | |
267 * We find a maximum for each section. * | |
268 * We compare the maximum of each section by favoring small lags. * | |
269 * * | |
270 * First section: lag delay = pit_max downto 4*pit_min * | |
271 * Second section: lag delay = 4*pit_min-1 downto 2*pit_min * | |
272 * Third section: lag delay = 2*pit_min-1 downto pit_min * | |
273 *--------------------------------------------------------------------*/ | |
274 | |
275 /* mode dependent scaling in Lag_max */ | |
276 test (); | |
277 if (sub(mode, MR122) == 0) | |
278 { | |
279 scal_flag = 1; move16 (); | |
280 } | |
281 else | |
282 { | |
283 scal_flag = 0; move16 (); | |
284 } | |
285 | |
286 j = shl (pit_min, 2); | |
287 p_max1 = Lag_max (vadSt, corr_ptr, scal_sig, scal_fac, scal_flag, L_frame, | |
288 pit_max, j, &max1, &rmax1, &r01, dtx); | |
289 | |
290 i = sub (j, 1); | |
291 j = shl (pit_min, 1); | |
292 p_max2 = Lag_max (vadSt, corr_ptr, scal_sig, scal_fac, scal_flag, L_frame, | |
293 i, j, &max2, &rmax2, &r02, dtx); | |
294 | |
295 i = sub (j, 1); | |
296 p_max3 = Lag_max (vadSt, corr_ptr, scal_sig, scal_fac, scal_flag, L_frame, | |
297 i, pit_min, &max3, &rmax3, &r03, dtx); | |
298 | |
299 if (dtx && !vadSt->use_vad2) | |
300 { /* no test() call since this if is only in simulation env */ | |
301 test (); | |
302 if (sub(idx, 1) == 0) | |
303 { | |
304 /* calculate max high-passed filtered correlation of all lags */ | |
305 hp_max (corr_ptr, scal_sig, L_frame, pit_max, pit_min, &corr_hp_max); | |
306 | |
307 /* update complex background detector */ | |
308 vad_complex_detection_update(&vadSt->u.v1, corr_hp_max); | |
309 } | |
310 } | |
311 | |
312 /*--------------------------------------------------------------------* | |
313 * Compare the 3 sections maximum, and favor small lag. * | |
314 *--------------------------------------------------------------------*/ | |
315 | |
316 test (); | |
317 if (sub (mult (max1, THRESHOLD), max2) < 0) | |
318 { | |
319 max1 = max2; move16 (); | |
320 p_max1 = p_max2; move16 (); | |
321 if (dtx) | |
322 { | |
323 rmax1 = rmax2; move32 (); | |
324 r01 = r02; move32 (); | |
325 } | |
326 } | |
327 test (); | |
328 if (sub (mult (max1, THRESHOLD), max3) < 0) | |
329 { | |
330 p_max1 = p_max3; move16 (); | |
331 if (dtx) | |
332 { | |
333 rmax1 = rmax3; move32 (); | |
334 r01 = r03; move32 (); | |
335 } | |
336 } | |
337 | |
338 if (dtx && vadSt->use_vad2) | |
339 { | |
340 /* Save max correlation */ | |
341 vadSt->u.v2.L_Rmax = L_add(vadSt->u.v2.L_Rmax, rmax1); | |
342 /* Save max energy */ | |
343 vadSt->u.v2.L_R0 = L_add(vadSt->u.v2.L_R0, r01); | |
344 } | |
345 | |
346 return (p_max1); | |
347 } |