Line data Source code
1 : /*====================================================================================
2 : EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
3 : ====================================================================================*/
4 :
5 : #include <stdint.h>
6 : #include "options.h" /* Compilation switches */
7 : #include "cnst.h" /* Common constants */
8 : #include "rom_com_fx.h" /* Static table prototypes */
9 : #include "rom_com.h" /* Static table prototypes */
10 : #include "rom_enc.h" /* Static table prototypes */
11 : //#include "prot_fx.h" /* Function prototypes */
12 : #include "prot_fx.h" /* Function prototypes */
13 : #include "prot_fx_enc.h" /* Function prototypes */
14 :
15 : /*-------------------------------------------------------------------*
16 : * analy_lp()
17 : *
18 : * Perform LP analysis
19 : *
20 : * - autocorrelations + lag windowing
21 : * - Levinson-Durbin algorithm to find A(z)
22 : * - convert A(z) to LSPs
23 : * - find interpolated LSPs and convert back to A(z) for all subframes
24 : * - update LSPs for the next frame
25 : *-------------------------------------------------------------------*/
26 1297646 : void analy_lp_ivas_fx(
27 : const Word16 speech[], /* i :(Q_new) pointer to the speech frame */
28 : const Word16 L_frame, /* i :(q0) length of the frame */
29 : const Word16 L_look, /* i :(q0) look-ahead */
30 : Word32 *ener, /* o :(Q_r) residual energy from Levinson-Durbin */
31 : Word16 A[], /* o :(q14) A(z) filter coefficients */
32 : Word16 epsP_h[], /* o :(high part of epsP(Q_r)) LP analysis residual energies for each iteration */
33 : Word16 epsP_l[], /* o :(low part of epsP(Q_r)) LP analysis residual energies for each iteration */
34 : Word16 lsp_new[], /* o :(q15) current frame LSPs */
35 : Word16 lsp_mid[], /* o :(q15) current mid-frame LSPs */
36 : Word16 lsp_old[], /* i/o:(q15) previous frame unquantized LSPs */
37 : const Word16 Top[2], /* i :(q0) open loop pitch lag */
38 : const Word16 Tnc[2], /* i :(q15) open loop pitch gain */
39 : const Word32 Core_sr, /* i :(q0) Internal core sampling rate */
40 : #ifdef REMOVE_EVS_DUPLICATES
41 : const Word16 element_mode, /* i : element mode */
42 : #endif
43 : const Word16 sec_chan_low_rate, /* i :(q0) flag to signal second channel */
44 : Word16 Q_new, /*i: stores Q for speech*/
45 : Word16 *Q_r /*stores q for ener*/ )
46 : {
47 : Word16 r_h[M + 1]; /* Autocorrelations of windowed speech MSB */
48 : Word16 r_l[M + 1]; /* Autocorrelations of windowed speech LSB */
49 : Word32 LepsP[M + 1];
50 1297646 : Word16 i, i_subfr, wind_length = 0;
51 : Word16 *lsp;
52 1297646 : const Word16 *wind = NULL;
53 : const Word16 *pt;
54 : Word16 half_frame;
55 1297646 : move16(); /* wind_length*/
56 :
57 1297646 : IF( EQ_16( L_frame, L_FRAME ) )
58 : {
59 1132100 : wind_length = L_LP;
60 1132100 : move16();
61 1132100 : wind = Assym_window_W16fx; /*q15*/
62 : }
63 : ELSE /* L_frame == L_FRAME16k */
64 : {
65 165546 : wind_length = L_LP_16k;
66 165546 : move16();
67 165546 : wind = assym_window_16k_fx; /*q15*/
68 : }
69 1297646 : lsp = lsp_mid; /* Q15 */
70 1297646 : half_frame = shr( L_frame, 1 );
71 :
72 3892938 : FOR( i_subfr = 0; i_subfr <= 1; i_subfr++ )
73 : {
74 2595292 : pt = speech + sub( add( half_frame, L_look ), wind_length );
75 2595292 : half_frame = shl( half_frame, 1 );
76 :
77 : /* Autocorrelations */
78 2595292 : autocorr_fx( pt, M, r_h, r_l, &Q_r[1 - i_subfr], wind_length, wind, 0, 0 );
79 :
80 : #ifdef REMOVE_EVS_DUPLICATES
81 2595292 : IF( NE_16( element_mode, EVS_MONO ) )
82 : #endif
83 : {
84 : /*if ( r[0] < 100.0f && no_thr == 0 )*/
85 : /*r[0] = 100.0f*/
86 2584992 : IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( L_Comp( r_h[0], r_l[0] ) /* Q_r[1 - i_subfr]*/, sub( 31, add( Q_r[1 - i_subfr], shl( Q_new, 1 ) ) ), 100 /*q0*/, 31 ), -1 ) )
87 : {
88 : /*Q_min stores min of 24 and the actual Q for r*/
89 236418 : Word16 Q_min = s_min( add( Q_r[1 - i_subfr], shl( Q_new, 1 ) ), 24 ); /* comparing q with 24 because exponent of 100 is 7 so max q should be 24*/
90 236418 : L_Extract( L_shl( 100, Q_min ), &r_h[0], &r_l[0] ); /*extracting high and low components of r[0]*/
91 4019106 : FOR( i = 1; i < 17; i++ )
92 : {
93 3782688 : L_Extract( L_shr( L_Comp( r_h[i], r_l[i] ), sub( add( Q_r[1 - i_subfr], shl( Q_new, 1 ) ), Q_min ) ), &r_h[i], &r_l[i] ); /*scaling all the values to q24*/
94 : }
95 236418 : Q_r[1 - i_subfr] = sub( Q_min, shl( Q_new, 1 ) ); /*updating the q (subtracting shl( Q_new, 1 ) as in later part it is being added-> to maintain q24 )*/
96 236418 : move16();
97 : }
98 : }
99 :
100 : /* Lag windowing */
101 2595292 : adapt_lag_wind( r_h, r_l, M, Top[i_subfr], Tnc[i_subfr], Core_sr );
102 :
103 : /* Levinson-Durbin */
104 2595292 : E_LPC_lev_dur( r_h, r_l, A, LepsP, M, NULL );
105 46715256 : FOR( i = 0; i <= M; i++ )
106 : {
107 44119964 : L_Extract( LepsP[i], &epsP_h[i], &epsP_l[i] );
108 : }
109 : /*Q_r[... might not be needed from external...*/
110 2595292 : Q_r[1 - i_subfr] = add( Q_r[1 - i_subfr], shl( Q_new, 1 ) );
111 2595292 : move16();
112 :
113 : /* Conversion of A(z) to LSPs */
114 2595292 : E_LPC_a_lsp_conversion( A, lsp, lsp_old, M );
115 :
116 2595292 : lsp = lsp_new; /* Q15 */
117 : }
118 1297646 : IF( EQ_16( sec_chan_low_rate, 1 ) )
119 : {
120 : /* LSP interpolation */
121 0 : int_lsp4_ivas_fx( L_frame, lsp_old, lsp_mid, lsp_new, A, M, -2 );
122 : }
123 : ELSE
124 : {
125 : /* LSP interpolation */
126 1297646 : int_lsp4_ivas_fx( L_frame, lsp_old, lsp_mid, lsp_new, A, M, 0 );
127 : }
128 1297646 : Copy( lsp_new, lsp_old, M ); /* Q15 */
129 1297646 : *ener = L_Comp( epsP_h[M], epsP_l[M] ); /* Q_r */
130 1297646 : move32();
131 :
132 1297646 : return;
133 : }
134 :
135 : #ifndef REMOVE_EVS_DUPLICATES
136 : void analy_lp_fx(
137 : const Word16 speech[], /* i : pointer to the speech frame Q_new*/
138 : const Word16 L_frame, /* i : length of the frame Q0*/
139 : const Word16 L_look, /* i : look-ahead Q0*/
140 : Word32 *ener, /* o : residual energy from Levinson-Durbin Q_r*/
141 : Word16 A[], /* o : A(z) filter coefficients Q14*/
142 : Word16 epsP_h[], /* o : LP analysis residual energies for each iteration Q_r*/
143 : Word16 epsP_l[], /* o : LP analysis residual energies for each iteration Q_r*/
144 : Word16 lsp_new[], /* o : current frame LSPs Q15*/
145 : Word16 lsp_mid[], /* o : current mid-frame LSPs Q15*/
146 : Word16 lsp_old[], /* i/o: previous frame unquantized LSPs Q15*/
147 : const Word16 Top[2], /* i : open loop pitch lag Q0*/
148 : const Word16 Tnc[2], /* i : open loop pitch gain Q15*/
149 : const Word32 Core_sr, /* i : Internal core sampling rate Q0*/
150 : const Word16 sec_chan_low_rate, /* i : flag to signal second channel Q0*/
151 : Word16 Q_new,
152 : Word16 *Q_r )
153 : {
154 : Word16 r_h[M + 1]; /* Autocorrelations of windowed speech MSB */
155 : Word16 r_l[M + 1]; /* Autocorrelations of windowed speech LSB */
156 : Word32 LepsP[M + 1];
157 : Word16 i, i_subfr, wind_length = 0;
158 : Word16 *lsp;
159 : const Word16 *wind = NULL;
160 : const Word16 *pt;
161 : Word16 half_frame;
162 :
163 : IF( EQ_16( L_frame, L_FRAME ) )
164 : {
165 : wind_length = L_LP;
166 : move16();
167 : wind = Assym_window_W16fx; /* Q15 */
168 : }
169 : ELSE /* L_frame == L_FRAME16k */
170 : {
171 : wind_length = L_LP_16k;
172 : move16();
173 : wind = assym_window_16k_fx; /* Q15 */
174 : }
175 : lsp = lsp_mid; /* Q15 */
176 : half_frame = shr( L_frame, 1 );
177 :
178 : FOR( i_subfr = 0; i_subfr <= 1; i_subfr++ )
179 : {
180 : pt = speech + sub( add( half_frame, L_look ), wind_length );
181 : half_frame = shl( half_frame, 1 );
182 :
183 : /* Autocorrelations */
184 : autocorr_fx( pt, M, r_h, r_l, &Q_r[1 - i_subfr], wind_length, wind, 0, 0 );
185 :
186 : /* Lag windowing */
187 : adapt_lag_wind( r_h, r_l, M, Top[i_subfr], Tnc[i_subfr], Core_sr );
188 :
189 : /* Levinson-Durbin */
190 : E_LPC_lev_dur( r_h, r_l, A, LepsP, M, NULL );
191 : FOR( i = 0; i <= M; i++ )
192 : {
193 : L_Extract( LepsP[i], &epsP_h[i], &epsP_l[i] );
194 : }
195 : /*Q_r[... might not be needed from external...*/
196 : Q_r[1 - i_subfr] = add( Q_r[1 - i_subfr], shl( Q_new, 1 ) );
197 : move16();
198 :
199 : /* Conversion of A(z) to LSPs */
200 : E_LPC_a_lsp_conversion( A, lsp, lsp_old, M );
201 :
202 : lsp = lsp_new; /* Q15 */
203 : }
204 : IF( EQ_16( sec_chan_low_rate, 1 ) )
205 : {
206 : /* LSP interpolation */
207 : #ifdef REMOVE_EVS_DUPLICATES
208 : int_lsp4_ivas_fx( L_frame, lsp_old, lsp_mid, lsp_new, A, M, -2 );
209 : #else
210 : int_lsp4_fx( L_frame, lsp_old, lsp_mid, lsp_new, A, M, -2 );
211 : #endif
212 : }
213 : ELSE
214 : {
215 : /* LSP interpolation */
216 : #ifdef REMOVE_EVS_DUPLICATES
217 : int_lsp4_fx( L_frame, lsp_old, lsp_mid, lsp_new, A, M, 0 );
218 : #else
219 : int_lsp4_fx( L_frame, lsp_old, lsp_mid, lsp_new, A, M, 0 );
220 : #endif
221 : }
222 : Copy( lsp_new, lsp_old, M ); /* Q15 */
223 : *ener = L_Comp( epsP_h[M], epsP_l[M] ); /* Q_r */
224 : move32();
225 :
226 : return;
227 : }
228 : #endif
229 :
230 : /*-------------------------------------------------------------------*
231 : * analy_lp_AMR_WB()
232 : *
233 : * Perform LP analysis for AMR-WB IO mode
234 : *
235 : * - autocorrelations + lag windowing
236 : * - Levinson-Durbin algorithm to find A(z)
237 : * - convert A(z) to ISPs
238 : * - find interpolated ISPs and convert back to A(z) for all subframes
239 : * - update ISPs for the next frame
240 : *-------------------------------------------------------------------*/
241 :
242 0 : void analy_lp_AMR_WB_fx(
243 : const Word16 speech[], /* i : pointer to the speech frame Q_new*/
244 : Word32 *ener, /* o : residual energy from Levinson-Durbin Q_r*/
245 : Word16 A[], /* o : A(z) filter coefficients Q14*/
246 : Word16 epsP_h[], /* o : LP analysis residual energies for each iteration Q_r*/
247 : Word16 epsP_l[], /* o : LP analysis residual energies for each iteration Q_r*/
248 : Word16 isp_new[], /* o : current frame ISPs Q15*/
249 : Word16 isp_old[], /* i/o: previous frame unquantized ISPs Q15*/
250 : Word16 isf_new[], /* o : current frame ISPs Q15*/
251 : Word16 Top, /* i : open loop pitch lag Q0*/
252 : Word16 Tnc, /* i : open loop pitch gain Qx*/
253 : Word16 Q_new,
254 : Word16 *Q_r )
255 : {
256 : Word16 r_h[M + 1]; /* Autocorrelations of windowed speech MSB */
257 : Word16 r_l[M + 1]; /* Autocorrelations of windowed speech LSB */
258 : Word32 LepsP[M + 1];
259 0 : Word16 i, wind_length = 0;
260 : const Word16 *wind;
261 :
262 : /* Initialization */
263 0 : wind_length = L_LP_AMR_WB;
264 0 : move16();
265 0 : wind = hamcos_window_fx;
266 :
267 : /* Autocorrelations */
268 0 : autocorr_fx( speech - L_SUBFR, M, r_h, r_l, &Q_r[0], wind_length, wind, 0, 0 );
269 :
270 : /* Lag windowing */
271 0 : adapt_lag_wind( r_h, r_l, M, Top, Tnc, INT_FS_FX );
272 :
273 : /* Levinson-Durbin */
274 : /*lev_dur( A, r, M, epsP );*/
275 0 : E_LPC_lev_dur( r_h, r_l, A, LepsP, M, NULL );
276 0 : FOR( i = 0; i <= M; i++ )
277 : {
278 0 : L_Extract( LepsP[i], &epsP_h[i], &epsP_l[i] );
279 : }
280 : /*Q_r[... might not be needed from external...*/
281 0 : Q_r[0] = add( Q_r[0], shl( Q_new, 1 ) );
282 0 : move16();
283 :
284 0 : E_LPC_a_lsf_isf_conversion( A, isf_new, stable_ISF_fx, M, 0 );
285 0 : E_LPC_isf_isp_conversion( isf_new, isp_new, M );
286 :
287 : /* ISP interpolation */
288 0 : int_lsp_fx( L_FRAME, isp_old, isp_new, A, M, interpol_isp_amr_wb_fx, 1 );
289 :
290 : /**ener = epsP[M];*/
291 0 : *ener = L_Comp( epsP_h[M], epsP_l[M] ); /* Q_r */
292 0 : move32();
293 :
294 : /* updates */
295 0 : Copy( isp_new, isp_old, M ); /* Q15 */
296 :
297 0 : return;
298 : }
|