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 }