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 }