FreeCalypso > hg > gsm-codec-lib
comparison libtwamr/ph_disp.c @ 390:bde9f5804670
libtwamr: integrate ph_disp.c
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Mon, 06 May 2024 18:20:22 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
389:9cd332a94c97 | 390:bde9f5804670 |
---|---|
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 : ph_disp.c | |
11 * Purpose : Perform adaptive phase dispersion of the excitation | |
12 * signal. | |
13 * | |
14 ******************************************************************************** | |
15 */ | |
16 /* | |
17 ******************************************************************************** | |
18 * MODULE INCLUDE FILE AND VERSION ID | |
19 ******************************************************************************** | |
20 */ | |
21 #include "namespace.h" | |
22 #include "ph_disp.h" | |
23 | |
24 /* | |
25 ******************************************************************************** | |
26 * INCLUDE FILES | |
27 ******************************************************************************** | |
28 */ | |
29 #include "typedef.h" | |
30 #include "basic_op.h" | |
31 #include "no_count.h" | |
32 #include "cnst.h" | |
33 #include "memops.h" | |
34 | |
35 /* | |
36 ******************************************************************************** | |
37 * LOCAL VARIABLES AND TABLES | |
38 ******************************************************************************** | |
39 */ | |
40 | |
41 #include "ph_disp.tab" | |
42 | |
43 /* | |
44 ******************************************************************************** | |
45 * PUBLIC PROGRAM CODE | |
46 ******************************************************************************** | |
47 */ | |
48 | |
49 /************************************************************************* | |
50 * | |
51 * Function: ph_disp_reset | |
52 * | |
53 ************************************************************************** | |
54 */ | |
55 void ph_disp_reset (ph_dispState *state) | |
56 { | |
57 Word16 i; | |
58 | |
59 for (i=0; i<PHDGAINMEMSIZE; i++) | |
60 { | |
61 state->gainMem[i] = 0; | |
62 } | |
63 state->prevState = 0; | |
64 state->prevCbGain = 0; | |
65 state->lockFull = 0; | |
66 state->onset = 0; /* assume no onset in start */ | |
67 } | |
68 | |
69 /************************************************************************* | |
70 * | |
71 * Function: ph_disp_lock | |
72 * | |
73 ************************************************************************** | |
74 */ | |
75 void ph_disp_lock (ph_dispState *state) | |
76 { | |
77 state->lockFull = 1; | |
78 return; | |
79 } | |
80 | |
81 /************************************************************************* | |
82 * | |
83 * Function: ph_disp_release | |
84 * | |
85 ************************************************************************** | |
86 */ | |
87 void ph_disp_release (ph_dispState *state) | |
88 { | |
89 state->lockFull = 0; | |
90 return; | |
91 } | |
92 | |
93 | |
94 /************************************************************************* | |
95 * | |
96 * Function: ph_disp | |
97 * | |
98 * Adaptive phase dispersion; forming of total excitation | |
99 * (for synthesis part of decoder) | |
100 * | |
101 ************************************************************************** | |
102 */ | |
103 void ph_disp ( | |
104 ph_dispState *state, /* i/o : State struct */ | |
105 enum Mode mode, /* i : codec mode */ | |
106 Word16 x[], /* i/o Q0 : in: LTP excitation signal */ | |
107 /* out: total excitation signal */ | |
108 Word16 cbGain, /* i Q1 : Codebook gain */ | |
109 Word16 ltpGain, /* i Q14 : LTP gain */ | |
110 Word16 inno[], /* i/o Q13 : Innovation vector (Q12 for 12.2) */ | |
111 Word16 pitch_fac, /* i Q14 : pitch factor used to scale the | |
112 LTP excitation (Q13 for 12.2) */ | |
113 Word16 tmp_shift /* i Q0 : shift factor applied to sum of | |
114 scaled LTP ex & innov. before | |
115 rounding */ | |
116 ) | |
117 { | |
118 Word16 i, i1; | |
119 Word16 tmp1; | |
120 Word32 L_temp; | |
121 Word16 impNr; /* indicator for amount of disp./filter used */ | |
122 | |
123 Word16 inno_sav[L_SUBFR]; | |
124 Word16 ps_poss[L_SUBFR]; | |
125 Word16 j, nze, nPulse, ppos; | |
126 const Word16 *ph_imp; /* Pointer to phase dispersion filter */ | |
127 | |
128 /* Update LTP gain memory */ | |
129 for (i = PHDGAINMEMSIZE-1; i > 0; i--) | |
130 { | |
131 state->gainMem[i] = state->gainMem[i-1]; move16 (); | |
132 } | |
133 state->gainMem[0] = ltpGain; move16 (); | |
134 | |
135 /* basic adaption of phase dispersion */ | |
136 test (); | |
137 if (sub(ltpGain, PHDTHR2LTP) < 0) { /* if (ltpGain < 0.9) */ | |
138 test (); | |
139 if (sub(ltpGain, PHDTHR1LTP) > 0) | |
140 { /* if (ltpGain > 0.6 */ | |
141 impNr = 1; /* medium dispersion */ move16 (); | |
142 } | |
143 else | |
144 { | |
145 impNr = 0; /* maximum dispersion */ move16 (); | |
146 } | |
147 } | |
148 else | |
149 { | |
150 impNr = 2; /* no dispersion */ move16 (); | |
151 } | |
152 | |
153 /* onset indicator */ | |
154 /* onset = (cbGain > onFact * cbGainMem[0]) */ | |
155 move32 (); | |
156 tmp1 = round(L_shl(L_mult(state->prevCbGain, ONFACTPLUS1), 2)); | |
157 test (); | |
158 if (sub(cbGain, tmp1) > 0) | |
159 { | |
160 state->onset = ONLENGTH; move16 (); | |
161 } | |
162 else | |
163 { | |
164 test (); | |
165 if (state->onset > 0) | |
166 { | |
167 state->onset = sub (state->onset, 1); move16 (); | |
168 } | |
169 } | |
170 | |
171 /* if not onset, check ltpGain buffer and use max phase dispersion if | |
172 half or more of the ltpGain-parameters say so */ | |
173 test (); | |
174 if (state->onset == 0) | |
175 { | |
176 /* Check LTP gain memory and set filter accordingly */ | |
177 i1 = 0; move16 (); | |
178 for (i = 0; i < PHDGAINMEMSIZE; i++) | |
179 { | |
180 test (); | |
181 if (sub(state->gainMem[i], PHDTHR1LTP) < 0) | |
182 { | |
183 i1 = add (i1, 1); | |
184 } | |
185 } | |
186 test (); | |
187 if (sub(i1, 2) > 0) | |
188 { | |
189 impNr = 0; move16 (); | |
190 } | |
191 | |
192 } | |
193 /* Restrict decrease in phase dispersion to one step if not onset */ | |
194 test (); test (); | |
195 if ((sub(impNr, add(state->prevState, 1)) > 0) && (state->onset == 0)) | |
196 { | |
197 impNr = sub (impNr, 1); | |
198 } | |
199 /* if onset, use one step less phase dispersion */ | |
200 test (); test (); | |
201 if((sub(impNr, 2) < 0) && (state->onset > 0)) | |
202 { | |
203 impNr = add (impNr, 1); | |
204 } | |
205 | |
206 /* disable for very low levels */ | |
207 test (); | |
208 if(sub(cbGain, 10) < 0) | |
209 { | |
210 impNr = 2; move16 (); | |
211 } | |
212 | |
213 test (); | |
214 if(sub(state->lockFull, 1) == 0) | |
215 { | |
216 impNr = 0; move16 (); | |
217 } | |
218 | |
219 /* update static memory */ | |
220 state->prevState = impNr; move16 (); | |
221 state->prevCbGain = cbGain; move16 (); | |
222 | |
223 /* do phase dispersion for all modes but 12.2 and 7.4; | |
224 don't modify the innovation if impNr >=2 (= no phase disp) */ | |
225 test (); test (); test(); test(); | |
226 if (sub(mode, MR122) != 0 && | |
227 sub(mode, MR102) != 0 && | |
228 sub(mode, MR74) != 0 && | |
229 sub(impNr, 2) < 0) | |
230 { | |
231 /* track pulse positions, save innovation, | |
232 and initialize new innovation */ | |
233 nze = 0; move16 (); | |
234 for (i = 0; i < L_SUBFR; i++) | |
235 { | |
236 move16 (); test(); | |
237 if (inno[i] != 0) | |
238 { | |
239 ps_poss[nze] = i; move16 (); | |
240 nze = add (nze, 1); | |
241 } | |
242 inno_sav[i] = inno[i]; move16 (); | |
243 inno[i] = 0; move16 (); | |
244 } | |
245 /* Choose filter corresponding to codec mode and dispersion criterium */ | |
246 test (); | |
247 if (sub (mode, MR795) == 0) | |
248 { | |
249 test (); | |
250 if (impNr == 0) | |
251 { | |
252 ph_imp = ph_imp_low_MR795; move16 (); | |
253 } | |
254 else | |
255 { | |
256 ph_imp = ph_imp_mid_MR795; move16 (); | |
257 } | |
258 } | |
259 else | |
260 { | |
261 test (); | |
262 if (impNr == 0) | |
263 { | |
264 ph_imp = ph_imp_low; move16 (); | |
265 } | |
266 else | |
267 { | |
268 ph_imp = ph_imp_mid; move16 (); | |
269 } | |
270 } | |
271 | |
272 /* Do phase dispersion of innovation */ | |
273 for (nPulse = 0; nPulse < nze; nPulse++) | |
274 { | |
275 ppos = ps_poss[nPulse]; move16 (); | |
276 | |
277 /* circular convolution with impulse response */ | |
278 j = 0; move16 (); | |
279 for (i = ppos; i < L_SUBFR; i++) | |
280 { | |
281 /* inno[i1] += inno_sav[ppos] * ph_imp[i1-ppos] */ | |
282 tmp1 = mult(inno_sav[ppos], ph_imp[j++]); | |
283 inno[i] = add(inno[i], tmp1); move16 (); | |
284 } | |
285 | |
286 for (i = 0; i < ppos; i++) | |
287 { | |
288 /* inno[i] += inno_sav[ppos] * ph_imp[L_SUBFR-ppos+i] */ | |
289 tmp1 = mult(inno_sav[ppos], ph_imp[j++]); | |
290 inno[i] = add(inno[i], tmp1); move16 (); | |
291 } | |
292 } | |
293 } | |
294 | |
295 /* compute total excitation for synthesis part of decoder | |
296 (using modified innovation if phase dispersion is active) */ | |
297 for (i = 0; i < L_SUBFR; i++) | |
298 { | |
299 /* x[i] = gain_pit*x[i] + cbGain*code[i]; */ | |
300 L_temp = L_mult ( x[i], pitch_fac); | |
301 /* 12.2: Q0 * Q13 */ | |
302 /* 7.4: Q0 * Q14 */ | |
303 L_temp = L_mac (L_temp, inno[i], cbGain); | |
304 /* 12.2: Q12 * Q1 */ | |
305 /* 7.4: Q13 * Q1 */ | |
306 L_temp = L_shl (L_temp, tmp_shift); /* Q16 */ | |
307 x[i] = round (L_temp); move16 (); | |
308 } | |
309 | |
310 return; | |
311 } |