comparison libtwamr/p_ol_wgh.c @ 416:48c7f8e8c9af

libtwamr: integrate p_ol_wgh.c
author Mychaela Falconia <falcon@freecalypso.org>
date Tue, 07 May 2024 03:15:19 +0000
parents
children
comparison
equal deleted inserted replaced
415:01c4becb9fda 416:48c7f8e8c9af
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 : p_ol_wgh.c
11 * Purpose : Compute the open loop pitch lag with weighting
12 *
13 *************************************************************************/
14 /*
15 ********************************************************************************
16 * MODULE INCLUDE FILE AND VERSION ID
17 ********************************************************************************
18 */
19 #include "namespace.h"
20 #include "p_ol_wgh.h"
21
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 "corrwght.tab"
33 #include "gmed_n.h"
34 #include "inv_sqrt.h"
35 #include "vad.h"
36 #include "calc_cor.h"
37 #include "hp_max.h"
38
39 /*
40 *****************************************************************************
41 * LOCAL VARIABLES AND TABLES
42 *****************************************************************************
43 */
44 /*************************************************************************
45 *
46 * FUNCTION: Lag_max
47 *
48 * PURPOSE: Find the lag that has maximum correlation of scal_sig[] in a
49 * given delay range.
50 *
51 * DESCRIPTION:
52 * The correlation is given by
53 * cor[t] = <scal_sig[n],scal_sig[n-t]>, t=lag_min,...,lag_max
54 * The functions outputs the maximum correlation after normalization
55 * and the corresponding lag.
56 *
57 *************************************************************************/
58 static Word16 Lag_max ( /* o : lag found */
59 vadState *vadSt, /* i/o : VAD state struct */
60 Word32 corr[], /* i : correlation vector. */
61 Word16 scal_sig[], /* i : scaled signal. */
62 Word16 L_frame, /* i : length of frame to compute pitch */
63 Word16 lag_max, /* i : maximum lag */
64 Word16 lag_min, /* i : minimum lag */
65 Word16 old_lag, /* i : old open-loop lag */
66 Word16 *cor_max, /* o : normalized correlation of selected lag */
67 Word16 wght_flg, /* i : is weighting function used */
68 Word16 *gain_flg, /* o : open-loop flag */
69 Flag dtx /* i : dtx flag; use dtx=1, do not use dtx=0 */
70 )
71 {
72 Word16 i, j;
73 Word16 *p, *p1;
74 Word32 max, t0;
75 Word16 t0_h, t0_l;
76 Word16 p_max;
77 const Word16 *ww, *we;
78 Word32 t1;
79
80 ww = &corrweight[250]; move16 ();
81 we = &corrweight[123 + lag_max - old_lag]; move16 ();
82
83 max = MIN_32; move32 ();
84 p_max = lag_max; move16 ();
85
86 for (i = lag_max; i >= lag_min; i--)
87 {
88 t0 = corr[-i]; move32 ();
89
90 /* Weighting of the correlation function. */
91 L_Extract (corr[-i], &t0_h, &t0_l);
92 t0 = Mpy_32_16 (t0_h, t0_l, *ww);
93 ww--; move16();
94 test ();
95 if (wght_flg > 0) {
96 /* Weight the neighbourhood of the old lag. */
97 L_Extract (t0, &t0_h, &t0_l);
98 t0 = Mpy_32_16 (t0_h, t0_l, *we);
99 we--; move16();
100 }
101
102 test ();
103 if (L_sub (t0, max) >= 0)
104 {
105 max = t0; move32 ();
106 p_max = i; move16 ();
107 }
108 }
109
110 p = &scal_sig[0]; move16 ();
111 p1 = &scal_sig[-p_max]; move16 ();
112 t0 = 0; move32 ();
113 t1 = 0; move32 ();
114
115 for (j = 0; j < L_frame; j++, p++, p1++)
116 {
117 t0 = L_mac (t0, *p, *p1);
118 t1 = L_mac (t1, *p1, *p1);
119 }
120
121 if (dtx)
122 { /* no test() call since this if is only in simulation env */
123 if (vadSt->use_vad2) {
124 /* Save max correlation */
125 vadSt->u.v2.L_Rmax = L_add(vadSt->u.v2.L_Rmax, t0);
126 /* Save max energy */
127 vadSt->u.v2.L_R0 = L_add(vadSt->u.v2.L_R0, t1);
128 } else {
129 /* update and detect tone */
130 vad_tone_detection_update (&vadSt->u.v1, 0);
131 vad_tone_detection (&vadSt->u.v1, t0, t1);
132 }
133 }
134
135 /* gain flag is set according to the open_loop gain */
136 /* is t2/t1 > 0.4 ? */
137 *gain_flg = round(L_msu(t0, round(t1), 13107)); move16();
138
139 *cor_max = 0; move16 ();
140
141 return (p_max);
142 }
143
144 /*
145 *****************************************************************************
146 * PUBLIC PROGRAM CODE
147 *****************************************************************************
148 */
149
150 /*************************************************************************
151 *
152 * Function: p_ol_wgh_reset
153 * Purpose: Initializes state memory to zero
154 *
155 **************************************************************************
156 */
157 void p_ol_wgh_reset (pitchOLWghtState *st)
158 {
159 /* Reset pitch search states */
160 st->old_T0_med = 40;
161 st->ada_w = 0;
162 st->wght_flg = 0;
163 }
164
165 /*************************************************************************
166 *
167 * Function: p_ol_wgh
168 * Purpose: open-loop pitch search with weighting
169 *
170 **************************************************************************
171 */
172 Word16 Pitch_ol_wgh ( /* o : open loop pitch lag */
173 pitchOLWghtState *st, /* i/o : State struct */
174 vadState *vadSt, /* i/o : VAD state struct */
175 Word16 signal[], /* i : signal used to compute the open loop pitch */
176 /* signal[-pit_max] to signal[-1] should be known */
177 Word16 pit_min, /* i : minimum pitch lag */
178 Word16 pit_max, /* i : maximum pitch lag */
179 Word16 L_frame, /* i : length of frame to compute pitch */
180 Word16 old_lags[], /* i : history with old stored Cl lags */
181 Word16 ol_gain_flg[], /* i : OL gain flag */
182 Word16 idx, /* i : index */
183 Flag dtx /* i : dtx flag; use dtx=1, do not use dtx=0 */
184 )
185 {
186 Word16 i;
187 Word16 max1;
188 Word16 p_max1;
189 Word32 t0;
190 Word16 corr_hp_max;
191 Word32 corr[PIT_MAX+1], *corr_ptr;
192
193 /* Scaled signal */
194 Word16 scaled_signal[PIT_MAX + L_FRAME];
195 Word16 *scal_sig;
196
197 scal_sig = &scaled_signal[pit_max]; move16 ();
198
199 t0 = 0L; move32 ();
200 for (i = -pit_max; i < L_frame; i++)
201 {
202 t0 = L_mac (t0, signal[i], signal[i]);
203 }
204 /*--------------------------------------------------------*
205 * Scaling of input signal. *
206 * *
207 * if Overflow -> scal_sig[i] = signal[i]>>2 *
208 * else if t0 < 1^22 -> scal_sig[i] = signal[i]<<2 *
209 * else -> scal_sig[i] = signal[i] *
210 *--------------------------------------------------------*/
211
212 /*--------------------------------------------------------*
213 * Verification for risk of overflow. *
214 *--------------------------------------------------------*/
215
216 test (); test ();
217 if (L_sub (t0, MAX_32) == 0L) /* Test for overflow */
218 {
219 for (i = -pit_max; i < L_frame; i++)
220 {
221 scal_sig[i] = shr (signal[i], 3); move16 ();
222 }
223 }
224 else if (L_sub (t0, (Word32) 1048576L) < (Word32) 0)
225 {
226 for (i = -pit_max; i < L_frame; i++)
227 {
228 scal_sig[i] = shl (signal[i], 3); move16 ();
229 }
230 }
231 else
232 {
233 for (i = -pit_max; i < L_frame; i++)
234 {
235 scal_sig[i] = signal[i]; move16 ();
236 }
237 }
238
239 /* calculate all coreelations of scal_sig, from pit_min to pit_max */
240 corr_ptr = &corr[pit_max]; move32 ();
241 comp_corr (scal_sig, L_frame, pit_max, pit_min, corr_ptr);
242
243 p_max1 = Lag_max (vadSt, corr_ptr, scal_sig, L_frame, pit_max, pit_min,
244 st->old_T0_med, &max1, st->wght_flg, &ol_gain_flg[idx],
245 dtx);
246 move16 ();
247
248 test (); move16 ();
249 if (ol_gain_flg[idx] > 0)
250 {
251 /* Calculate 5-point median of previous lags */
252 for (i = 4; i > 0; i--) /* Shift buffer */
253 {
254 old_lags[i] = old_lags[i-1]; move16 ();
255 }
256 old_lags[0] = p_max1; move16 ();
257 st->old_T0_med = gmed_n (old_lags, 5); move16 ();
258 st->ada_w = 32767; move16 (); /* Q15 = 1.0 */
259 }
260 else
261 {
262 st->old_T0_med = p_max1; move16 ();
263 st->ada_w = mult(st->ada_w, 29491); /* = ada_w = ada_w * 0.9 */
264 }
265
266 test ();
267 if (sub(st->ada_w, 9830) < 0) /* ada_w - 0.3 */
268 {
269 st->wght_flg = 0; move16 ();
270 }
271 else
272 {
273 st->wght_flg = 1; move16 ();
274 }
275
276 if (dtx && !vadSt->use_vad2)
277 { /* no test() call since this if is only in simulation env */
278 test ();
279 if (sub(idx, 1) == 0)
280 {
281 /* calculate max high-passed filtered correlation of all lags */
282 hp_max (corr_ptr, scal_sig, L_frame, pit_max, pit_min, &corr_hp_max);
283
284 /* update complex background detector */
285 vad_complex_detection_update(&vadSt->u.v1, corr_hp_max);
286 }
287 }
288
289 return (p_max1);
290 }