FreeCalypso > hg > gsm-codec-lib
comparison libgsmfr2/long_term.c @ 267:65d3304502bd
libgsmfr2: integrate long_term.c from libgsm
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sun, 14 Apr 2024 01:01:19 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
266:8821ffaa93a5 | 267:65d3304502bd |
---|---|
1 /* | |
2 * This C source file has been adapted from TU-Berlin libgsm source, | |
3 * original notice follows: | |
4 * | |
5 * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische | |
6 * Universitaet Berlin. See the accompanying file "COPYRIGHT" for | |
7 * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. | |
8 */ | |
9 | |
10 #include <stdint.h> | |
11 #include <assert.h> | |
12 #include "tw_gsmfr.h" | |
13 #include "typedef.h" | |
14 #include "ed_state.h" | |
15 #include "ed_internal.h" | |
16 | |
17 /* | |
18 * 4.2.11 .. 4.2.12 LONG TERM PREDICTOR (LTP) SECTION | |
19 */ | |
20 | |
21 | |
22 /* | |
23 * This module computes the LTP gain (bc) and the LTP lag (Nc) | |
24 * for the long term analysis filter. This is done by calculating a | |
25 * maximum of the cross-correlation function between the current | |
26 * sub-segment short term residual signal d[0..39] (output of | |
27 * the short term analysis filter; for simplification the index | |
28 * of this array begins at 0 and ends at 39 for each sub-segment of the | |
29 * RPE-LTP analysis) and the previous reconstructed short term | |
30 * residual signal dp[ -120 .. -1 ]. A dynamic scaling must be | |
31 * performed to avoid overflow. | |
32 */ | |
33 | |
34 static void Calculation_of_the_LTP_parameters ( | |
35 register word * d, /* [0..39] IN */ | |
36 register word * dp, /* [-120..-1] IN */ | |
37 word * bc_out, /* OUT */ | |
38 word * Nc_out /* OUT */ | |
39 ) | |
40 { | |
41 register int k, lambda; | |
42 word Nc, bc; | |
43 word wt[40]; | |
44 | |
45 longword L_max, L_power; | |
46 word R, S, dmax, scal; | |
47 register word temp; | |
48 | |
49 /* Search of the optimum scaling of d[0..39]. | |
50 */ | |
51 dmax = 0; | |
52 | |
53 for (k = 0; k <= 39; k++) { | |
54 temp = d[k]; | |
55 temp = GSM_ABS( temp ); | |
56 if (temp > dmax) dmax = temp; | |
57 } | |
58 | |
59 temp = 0; | |
60 if (dmax == 0) scal = 0; | |
61 else { | |
62 assert(dmax > 0); | |
63 temp = gsm_norm( (longword)dmax << 16 ); | |
64 } | |
65 | |
66 if (temp > 6) scal = 0; | |
67 else scal = 6 - temp; | |
68 | |
69 assert(scal >= 0); | |
70 | |
71 /* Initialization of a working array wt | |
72 */ | |
73 | |
74 for (k = 0; k <= 39; k++) wt[k] = SASR( d[k], scal ); | |
75 | |
76 /* Search for the maximum cross-correlation and coding of the LTP lag | |
77 */ | |
78 L_max = 0; | |
79 Nc = 40; /* index for the maximum cross-correlation */ | |
80 | |
81 for (lambda = 40; lambda <= 120; lambda++) { | |
82 | |
83 # undef STEP | |
84 # define STEP(k) (longword)wt[k] * dp[k - lambda] | |
85 | |
86 register longword L_result; | |
87 | |
88 L_result = STEP(0) ; L_result += STEP(1) ; | |
89 L_result += STEP(2) ; L_result += STEP(3) ; | |
90 L_result += STEP(4) ; L_result += STEP(5) ; | |
91 L_result += STEP(6) ; L_result += STEP(7) ; | |
92 L_result += STEP(8) ; L_result += STEP(9) ; | |
93 L_result += STEP(10) ; L_result += STEP(11) ; | |
94 L_result += STEP(12) ; L_result += STEP(13) ; | |
95 L_result += STEP(14) ; L_result += STEP(15) ; | |
96 L_result += STEP(16) ; L_result += STEP(17) ; | |
97 L_result += STEP(18) ; L_result += STEP(19) ; | |
98 L_result += STEP(20) ; L_result += STEP(21) ; | |
99 L_result += STEP(22) ; L_result += STEP(23) ; | |
100 L_result += STEP(24) ; L_result += STEP(25) ; | |
101 L_result += STEP(26) ; L_result += STEP(27) ; | |
102 L_result += STEP(28) ; L_result += STEP(29) ; | |
103 L_result += STEP(30) ; L_result += STEP(31) ; | |
104 L_result += STEP(32) ; L_result += STEP(33) ; | |
105 L_result += STEP(34) ; L_result += STEP(35) ; | |
106 L_result += STEP(36) ; L_result += STEP(37) ; | |
107 L_result += STEP(38) ; L_result += STEP(39) ; | |
108 | |
109 if (L_result > L_max) { | |
110 | |
111 Nc = lambda; | |
112 L_max = L_result; | |
113 } | |
114 } | |
115 | |
116 *Nc_out = Nc; | |
117 | |
118 L_max <<= 1; | |
119 | |
120 /* Rescaling of L_max | |
121 */ | |
122 assert(scal <= 100 && scal >= -100); | |
123 L_max = L_max >> (6 - scal); /* sub(6, scal) */ | |
124 | |
125 assert( Nc <= 120 && Nc >= 40); | |
126 | |
127 /* Compute the power of the reconstructed short term residual | |
128 * signal dp[..] | |
129 */ | |
130 L_power = 0; | |
131 for (k = 0; k <= 39; k++) { | |
132 | |
133 register longword L_temp; | |
134 | |
135 L_temp = SASR( dp[k - Nc], 3 ); | |
136 L_power += L_temp * L_temp; | |
137 } | |
138 L_power <<= 1; /* from L_MULT */ | |
139 | |
140 /* Normalization of L_max and L_power | |
141 */ | |
142 | |
143 if (L_max <= 0) { | |
144 *bc_out = 0; | |
145 return; | |
146 } | |
147 if (L_max >= L_power) { | |
148 *bc_out = 3; | |
149 return; | |
150 } | |
151 | |
152 temp = gsm_norm( L_power ); | |
153 | |
154 R = SASR( L_max << temp, 16 ); | |
155 S = SASR( L_power << temp, 16 ); | |
156 | |
157 /* Coding of the LTP gain | |
158 */ | |
159 | |
160 /* Table 4.3a must be used to obtain the level DLB[i] for the | |
161 * quantization of the LTP gain b to get the coded version bc. | |
162 */ | |
163 for (bc = 0; bc <= 2; bc++) if (R <= gsm_mult(S, gsm_DLB[bc])) break; | |
164 *bc_out = bc; | |
165 } | |
166 | |
167 /* 4.2.12 */ | |
168 | |
169 static void Long_term_analysis_filtering ( | |
170 word bc, /* IN */ | |
171 word Nc, /* IN */ | |
172 register word * dp, /* previous d [-120..-1] IN */ | |
173 register word * d, /* d [0..39] IN */ | |
174 register word * dpp, /* estimate [0..39] OUT */ | |
175 register word * e /* long term res. signal [0..39] OUT */ | |
176 ) | |
177 /* | |
178 * In this part, we have to decode the bc parameter to compute | |
179 * the samples of the estimate dpp[0..39]. The decoding of bc needs the | |
180 * use of table 4.3b. The long term residual signal e[0..39] | |
181 * is then calculated to be fed to the RPE encoding section. | |
182 */ | |
183 { | |
184 register int k; | |
185 register longword ltmp; | |
186 | |
187 # undef STEP | |
188 # define STEP(BP) \ | |
189 for (k = 0; k <= 39; k++) { \ | |
190 dpp[k] = GSM_MULT_R( BP, dp[k - Nc]); \ | |
191 e[k] = GSM_SUB( d[k], dpp[k] ); \ | |
192 } | |
193 | |
194 switch (bc) { | |
195 case 0: STEP( 3277 ); break; | |
196 case 1: STEP( 11469 ); break; | |
197 case 2: STEP( 21299 ); break; | |
198 case 3: STEP( 32767 ); break; | |
199 } | |
200 } | |
201 | |
202 void Gsm_Long_Term_Predictor ( /* 4x for 160 samples */ | |
203 struct gsmfr_0610_state * S, | |
204 | |
205 word * d, /* [0..39] residual signal IN */ | |
206 word * dp, /* [-120..-1] d' IN */ | |
207 | |
208 word * e, /* [0..39] OUT */ | |
209 word * dpp, /* [0..39] OUT */ | |
210 word * Nc, /* correlation lag OUT */ | |
211 word * bc /* gain factor OUT */ | |
212 ) | |
213 { | |
214 assert( d ); assert( dp ); assert( e ); | |
215 assert( dpp); assert( Nc ); assert( bc ); | |
216 | |
217 Calculation_of_the_LTP_parameters(d, dp, bc, Nc); | |
218 Long_term_analysis_filtering( *bc, *Nc, dp, d, dpp, e ); | |
219 } | |
220 | |
221 /* 4.3.2 */ | |
222 void Gsm_Long_Term_Synthesis_Filtering ( | |
223 struct gsmfr_0610_state * S, | |
224 | |
225 word Ncr, | |
226 word bcr, | |
227 register word * erp, /* [0..39] IN */ | |
228 register word * drp /* [-120..-1] IN, [-120..40] OUT */ | |
229 ) | |
230 /* | |
231 * This procedure uses the bcr and Ncr parameter to realize the | |
232 * long term synthesis filtering. The decoding of bcr needs | |
233 * table 4.3b. | |
234 */ | |
235 { | |
236 register longword ltmp; /* for ADD */ | |
237 register int k; | |
238 word brp, drpp, Nr; | |
239 | |
240 /* Check the limits of Nr. | |
241 */ | |
242 Nr = Ncr < 40 || Ncr > 120 ? S->nrp : Ncr; | |
243 S->nrp = Nr; | |
244 assert(Nr >= 40 && Nr <= 120); | |
245 | |
246 /* Decoding of the LTP gain bcr | |
247 */ | |
248 brp = gsm_QLB[ bcr ]; | |
249 | |
250 /* Computation of the reconstructed short term residual | |
251 * signal drp[0..39] | |
252 */ | |
253 assert(brp != MIN_WORD); | |
254 | |
255 for (k = 0; k <= 39; k++) { | |
256 drpp = GSM_MULT_R( brp, drp[ k - Nr ] ); | |
257 drp[k] = GSM_ADD( erp[k], drpp ); | |
258 } | |
259 | |
260 /* | |
261 * Update of the reconstructed short term residual signal | |
262 * drp[ -1..-120 ] | |
263 */ | |
264 | |
265 for (k = 0; k <= 119; k++) drp[ -120 + k ] = drp[ -80 + k ]; | |
266 } |