FreeCalypso > hg > gsm-codec-lib
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 } |