Line data Source code
1 : /******************************************************************************************************
2 :
3 : (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
4 : Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
5 : Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
6 : Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
7 : contributors to this repository. All Rights Reserved.
8 :
9 : This software is protected by copyright law and by international treaties.
10 : The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
11 : Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
12 : Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
13 : Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
14 : contributors to this repository retain full ownership rights in their respective contributions in
15 : the software. This notice grants no license of any kind, including but not limited to patent
16 : license, nor is any license granted by implication, estoppel or otherwise.
17 :
18 : Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
19 : contributions.
20 :
21 : This software is provided "AS IS", without any express or implied warranties. The software is in the
22 : development stage. It is intended exclusively for experts who have experience with such software and
23 : solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
24 : and fitness for a particular purpose are hereby disclaimed and excluded.
25 :
26 : Any dispute, controversy or claim arising under or in relation to providing this software shall be
27 : submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
28 : accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
29 : the United Nations Convention on Contracts on the International Sales of Goods.
30 :
31 : *******************************************************************************************************/
32 :
33 : #include <assert.h>
34 : #include <stdint.h>
35 : #include "options.h"
36 : #include <math.h>
37 : #include "cnst.h"
38 : #include "prot_fx.h"
39 : #include "rom_com.h"
40 : #include "ivas_rom_com.h"
41 : #include "ivas_stat_enc.h"
42 : #include "ivas_cnst.h"
43 : #include "wmc_auto.h"
44 : #include "ivas_prot_fx.h"
45 :
46 :
47 : /*-------------------------------------------------------------------*
48 : * Local constants
49 : *-------------------------------------------------------------------*/
50 :
51 : #define STEREO_DFT_CHANNEL_EXTR_LPC_ORDER 10
52 : #define STEREO_DFT_CHANNEL_EXTR_LPC_VEC_LIMIT 320
53 : #define FLR_FX 1073741824 // Q31
54 : #define ONE_HALF 24576 // Q14
55 : const Word16 wac_swb_h_fx[LPC_SHB_ORDER + 1] = { // Q15
56 : 32767,
57 : 32758,
58 : 32731,
59 : 32686,
60 : 32622,
61 : 32541,
62 : 32442,
63 : 32325,
64 : 32191,
65 : 32039,
66 : 31870
67 : };
68 :
69 : const Word16 wac_swb_l_fx[LPC_SHB_ORDER + 1] = { // Q15
70 : 32767,
71 : 29696,
72 : 20864,
73 : 7872,
74 : 25856,
75 : 12800,
76 : 5952,
77 : 10560,
78 : 256,
79 : 15040,
80 : 30336
81 : };
82 : /*---------------------------------------------------------------
83 : * stereo_td_get_td_itd()
84 : *
85 : *
86 : * ---------------------------------------------------------------*/
87 :
88 35429 : static void stereo_td_get_td_itd_fx(
89 : Word16 *td_itd, /* o : td_itd in samples at sampling frequency */
90 : Word16 *td_itd_32, /* o : td_itd in samples at 32kHz */
91 : const Word32 itd, /* i : itd in samples at sampling frequency q_itd */
92 : Word16 q_itd,
93 : const Word32 input_Fs /* i : sampling frequency */
94 : )
95 : {
96 : /* *td_itd is the closest integer to itd that transforms into an integer value *
97 : * under the transform x -> (32000/fs) x. */
98 35429 : Word32 inverse_input_fs_by_16k = 0;
99 35429 : move32();
100 : Word64 tmp64;
101 35429 : Word16 d = 0, shift = 0;
102 35429 : move16();
103 35429 : move16();
104 :
105 35429 : IF( EQ_32( input_Fs, 32000 ) )
106 : {
107 12808 : *td_itd_32 = *td_itd = extract_l( L_shr_r( itd, q_itd ) );
108 12808 : move16();
109 12808 : move16();
110 : }
111 : ELSE
112 : {
113 22621 : assert( ( input_Fs % 16000 ) == 0 && "sampling frequency should be divisible by 16000" );
114 22621 : IF( itd == 0 )
115 : {
116 12654 : *td_itd_32 = *td_itd = 0;
117 12654 : move16();
118 12654 : move16();
119 : }
120 : ELSE
121 : {
122 9967 : SWITCH( input_Fs )
123 : {
124 3481 : case 16000:
125 3481 : inverse_input_fs_by_16k = 1073741824; // Q30 /* This is in Q30, because 2147483648 cannot be represnt in Word32*/
126 3481 : move32();
127 3481 : d = 1; // Q0
128 3481 : move16();
129 3481 : shift = 1;
130 3481 : move16();
131 3481 : BREAK;
132 0 : case 32000:
133 0 : inverse_input_fs_by_16k = 1073741824; // Q31
134 0 : move32();
135 0 : d = 2; // Q0
136 0 : move16();
137 0 : BREAK;
138 6486 : case 48000:
139 6486 : inverse_input_fs_by_16k = 715827883; // Q31
140 6486 : move32();
141 6486 : d = 3; // Q0
142 6486 : move16();
143 6486 : if ( itd < 0 )
144 : {
145 4247 : inverse_input_fs_by_16k = 715827882; /* Reducing the precision by 1 to handle multiplication of negative case*/
146 4247 : move32();
147 : }
148 6486 : BREAK;
149 0 : default:
150 0 : assert( 0 );
151 : }
152 9967 : tmp64 = W_add( W_mult0_32_32( itd, inverse_input_fs_by_16k ), W_shl( FLR_FX, sub( q_itd, shift ) ) ); // Q: q_itd - shift + 31
153 9967 : *td_itd_32 = shl( extract_l( W_extract_l( W_shr( tmp64, add( sub( q_itd, shift ), Q31 ) ) ) ), 1 ); // Q0
154 9967 : move16();
155 :
156 9967 : *td_itd = i_mult( shr( *td_itd_32, 1 ), d ); // Q0
157 9967 : move16();
158 : }
159 : }
160 :
161 35429 : return;
162 : }
163 :
164 : /*---------------------------------------------------------------
165 : * stereo_td_channel_extrapolate()
166 : *
167 : *
168 : * ---------------------------------------------------------------*/
169 :
170 15678 : static void stereo_td_channel_extrapolate_fx(
171 : Encoder_State **sts,
172 : const Word16 dft_ovl,
173 : const Word16 shift_mem[], // q_shift
174 : Word16 q_shift,
175 : Word16 shift_input[], // q_shift
176 : const Word16 input_frame,
177 : const Word16 itd_shift,
178 : const Word16 lagging_channel,
179 : Word16 *input_mem[CPE_CHANNELS], /* i/o: input buffer memory q_input_mem */
180 : Word16 *q_input_mem,
181 : Word16 *q_new_shift )
182 : {
183 : Word16 leading_channel, i, size_ovl, pred_ovlp;
184 : Word16 g, nsr, g_lpc;
185 : Word32 dot_lead_lag_1, dot_lead_lead_1, dot_lag_lag_1;
186 : Word64 dot_lead_lag, dot_lead_lead, dot_lag_lag;
187 : Word16 q_dot_lead_lag, q_dot_lead_lead, q_dot_lag_lag;
188 : Word16 window[STEREO_DFT_CHANNEL_EXTR_LPC_VEC_LIMIT], mem_zero[STEREO_DFT_CHANNEL_EXTR_LPC_ORDER];
189 : Word16 residual[STEREO_DFT_CHANNEL_EXTR_LPC_VEC_LIMIT + ( STEREO_DFT_ITD_MAX * L_FRAME48k ) / L_FRAME32k];
190 : Word16 r_h[STEREO_DFT_CHANNEL_EXTR_LPC_ORDER + 1];
191 : Word16 r_l[STEREO_DFT_CHANNEL_EXTR_LPC_ORDER + 1];
192 : Word16 Q_r;
193 : Word16 A[STEREO_DFT_CHANNEL_EXTR_LPC_ORDER + 1];
194 : Word16 shift_combined[L_FRAME48k + L_FRAME48k];
195 : // Word16 q_shift_combined;
196 : Word16 flag;
197 : Word16 pitch_lag;
198 : Word16 res_shift;
199 : Word16 pitch0, tmp, tmp_e;
200 : Word32 L_tmp;
201 : // shift_mem and shift_input are of same Q q_shift//
202 15678 : set16_fx( shift_combined, 0, add( L_FRAME48k, L_FRAME48k ) );
203 15678 : set16_fx( residual, 0, STEREO_DFT_CHANNEL_EXTR_LPC_VEC_LIMIT + ( STEREO_DFT_ITD_MAX * input_frame ) / L_FRAME32k );
204 :
205 15678 : leading_channel = s_and( add( lagging_channel, 1 ), 1 );
206 15678 : IF( EQ_16( sts[0]->element_mode, IVAS_CPE_DFT ) )
207 : {
208 12105 : size_ovl = dft_ovl;
209 12105 : pitch0 = sts[0]->pitch[0];
210 : }
211 : ELSE
212 : {
213 3573 : size_ovl = input_frame;
214 3573 : pitch0 = sts[lagging_channel]->pitch[0];
215 : }
216 15678 : move16();
217 15678 : move16();
218 :
219 15678 : pred_ovlp = idiv1616( input_frame, 10 );
220 :
221 : /*get pitch lag from previous frame */
222 : // pitch_lag = (int16_t) ( pitch0 * ( (float) input_frame / L_FRAME ) );
223 15678 : tmp = BASOP_Util_Divide3232_Scale( input_frame, L_FRAME, &tmp_e );
224 15678 : L_tmp = L_mult0( pitch0, tmp );
225 15678 : pitch_lag = extract_l( L_shr( L_tmp, sub( 15, tmp_e ) ) ); /* Q0 */
226 :
227 : /* compute the parameters g, nsr and g_lpc */
228 15678 : dot_lead_lag = EPSILON_FX;
229 15678 : dot_lead_lead = EPSILON_FX;
230 15678 : dot_lag_lag = EPSILON_FX;
231 15678 : dot_lead_lag_1 = EPSILON_FX;
232 15678 : dot_lead_lead_1 = EPSILON_FX;
233 15678 : dot_lag_lag_1 = EPSILON_FX;
234 15678 : move64();
235 15678 : move64();
236 15678 : move64();
237 15678 : move32();
238 15678 : move32();
239 15678 : move32();
240 5878958 : FOR( i = 0; i < size_ovl; i++ )
241 : {
242 5863280 : shift_combined[i] = shift_mem[i]; // q_shift
243 5863280 : move16();
244 : // q_shift_combined = q_shift;
245 5863280 : dot_lead_lag = W_mac0_16_16( dot_lead_lag, input_mem[leading_channel][i], shift_mem[i] );
246 5863280 : dot_lead_lead = W_mac0_16_16( dot_lead_lead, input_mem[leading_channel][i], input_mem[leading_channel][i] );
247 5863280 : dot_lag_lag = W_mac0_16_16( dot_lag_lag, shift_mem[i], shift_mem[i] );
248 : }
249 10365666 : FOR( i = 0; i < input_frame - itd_shift; i++ )
250 : {
251 10349988 : shift_combined[i + size_ovl] = shift_input[i]; // q_shift
252 10349988 : move16();
253 10349988 : dot_lead_lag = W_mac0_16_16( dot_lead_lag, sts[leading_channel]->input_fx[i], shift_input[i] );
254 10349988 : dot_lead_lead = W_mac0_16_16( dot_lead_lead, sts[leading_channel]->input_fx[i], sts[leading_channel]->input_fx[i] );
255 10349988 : dot_lag_lag = W_mac0_16_16( dot_lag_lag, shift_input[i], shift_input[i] );
256 : }
257 15678 : q_dot_lead_lag = q_shift + q_input_mem[leading_channel]; // q_input_mem = q_input
258 15678 : q_dot_lead_lead = q_input_mem[leading_channel] + q_input_mem[leading_channel];
259 15678 : q_dot_lag_lag = add( q_shift, q_shift );
260 :
261 :
262 15678 : q_dot_lead_lag = sub( add( q_dot_lead_lag, W_norm( dot_lead_lag ) ), 32 );
263 15678 : q_dot_lead_lead = sub( add( q_dot_lead_lead, W_norm( dot_lead_lead ) ), 32 );
264 15678 : q_dot_lag_lag = sub( add( q_dot_lag_lag, W_norm( dot_lag_lag ) ), 32 );
265 15678 : dot_lead_lag_1 = W_extract_h( W_shl( dot_lead_lag, W_norm( dot_lead_lag ) ) );
266 15678 : dot_lead_lead_1 = W_extract_h( W_shl( dot_lead_lead, W_norm( dot_lead_lead ) ) );
267 15678 : dot_lag_lag_1 = W_extract_h( W_shl( dot_lag_lag, W_norm( dot_lag_lag ) ) );
268 :
269 :
270 : Word16 g_e, f, f_e, g_lpc_e, nsr_e;
271 15678 : g = BASOP_Util_Divide3232_Scale( dot_lead_lag_1, dot_lead_lead_1, &g_e );
272 15678 : g_e = add( g_e, sub( q_dot_lead_lead, q_dot_lead_lag ) );
273 :
274 15678 : f = BASOP_Util_Divide3232_Scale( dot_lead_lag_1, dot_lag_lag_1, &f_e );
275 15678 : f_e = add( f_e, sub( q_dot_lag_lag, q_dot_lead_lag ) );
276 :
277 15678 : nsr = mult( g, f );
278 15678 : nsr_e = BASOP_Util_Add_MantExp( ONE_IN_Q14, 1, negate( nsr ), add( g_e, f_e ), &nsr );
279 15678 : IF( g_e > 0 )
280 : {
281 2932 : g = check_bounds_s_fx( g, negate( shl( 1, sub( 15, g_e ) ) ), shl( ONE_HALF, sub( 1, g_e ) ) );
282 : }
283 15678 : IF( nsr_e > 0 )
284 : {
285 0 : nsr = check_bounds_s_fx( nsr, 0, shl( 1, sub( 15, nsr_e ) ) );
286 : }
287 15678 : g = shl( g, sub( g_e, 1 ) ); // q14
288 15678 : nsr = shl( nsr, nsr_e ); // Q15
289 15678 : g_lpc_e = 0;
290 15678 : move16();
291 15678 : g_lpc = Sqrt16( nsr, &g_lpc_e );
292 15678 : g_lpc = shl( g_lpc, sub( g_lpc_e, 1 ) ); // Q14
293 : /* rectangular window */
294 15678 : set16_fx( window, 32767, STEREO_DFT_CHANNEL_EXTR_LPC_VEC_LIMIT );
295 15678 : set16_zero_fx( mem_zero, STEREO_DFT_CHANNEL_EXTR_LPC_ORDER );
296 :
297 : /* get the LPC filter */
298 15678 : autocorr_ivas_fx( shift_combined + input_frame + size_ovl - itd_shift - STEREO_DFT_CHANNEL_EXTR_LPC_VEC_LIMIT, q_shift, STEREO_DFT_CHANNEL_EXTR_LPC_ORDER, r_h, r_l, &Q_r, STEREO_DFT_CHANNEL_EXTR_LPC_VEC_LIMIT, window, 0, 0, 0 );
299 : /* Ensure R[0] isn't zero when entering Levinson-Durbin */
300 15678 : r_l[0] = s_max( r_l[0], 1 );
301 15678 : move16();
302 188136 : FOR( i = 0; i <= STEREO_DFT_CHANNEL_EXTR_LPC_ORDER; i++ )
303 : {
304 172458 : L_tmp = Mpy_32( r_h[i], r_l[i], wac_swb_h_fx[i], wac_swb_l_fx[i] );
305 172458 : L_Extract( L_tmp, &r_h[i], &r_l[i] );
306 : }
307 15678 : r_l[0] = s_max( r_l[0], 1 );
308 15678 : move16();
309 15678 : flag = E_LPC_lev_dur( r_h, r_l, A, NULL, STEREO_DFT_CHANNEL_EXTR_LPC_ORDER, NULL );
310 15678 : Copy_Scale_sig( A, A, STEREO_DFT_CHANNEL_EXTR_LPC_ORDER + 1, sub( norm_s( A[0] ), 2 ) );
311 15678 : IF( EQ_16( flag, 1 ) )
312 : {
313 0 : g_lpc = 0;
314 0 : move16();
315 : }
316 : ELSE
317 : {
318 : /* get the residual */
319 15678 : fir_fx( shift_combined + input_frame + size_ovl - itd_shift - STEREO_DFT_CHANNEL_EXTR_LPC_VEC_LIMIT, A, residual, mem_zero, STEREO_DFT_CHANNEL_EXTR_LPC_VEC_LIMIT, STEREO_DFT_CHANNEL_EXTR_LPC_ORDER, 0, 3 );
320 :
321 : /* extend the residual */
322 : /* to prevent out of bound reading */
323 15678 : IF( LT_16( pitch_lag, PIT_MAX ) )
324 : {
325 9598 : res_shift = pitch_lag;
326 9598 : move16();
327 : }
328 : ELSE
329 : {
330 6080 : res_shift = itd_shift;
331 6080 : move16();
332 : }
333 :
334 653210 : FOR( i = STEREO_DFT_CHANNEL_EXTR_LPC_VEC_LIMIT; i < STEREO_DFT_CHANNEL_EXTR_LPC_VEC_LIMIT + itd_shift; i++ )
335 : {
336 637532 : residual[i] = residual[i - res_shift];
337 637532 : move16();
338 : }
339 :
340 : /* perform sythesis */
341 15678 : E_UTIL_synthesis( 0, A, residual, shift_combined + sub( add( input_frame, size_ovl ), add( STEREO_DFT_CHANNEL_EXTR_LPC_VEC_LIMIT, itd_shift ) ), STEREO_DFT_CHANNEL_EXTR_LPC_VEC_LIMIT + itd_shift, mem_zero, 0, STEREO_DFT_CHANNEL_EXTR_LPC_ORDER );
342 : }
343 :
344 15678 : Copy( shift_combined + size_ovl, shift_input, input_frame ); // q_shift
345 :
346 15678 : Word16 offset = sub( input_frame, itd_shift );
347 15678 : Word16 offset_pred_ovlp = sub( offset, pred_ovlp );
348 :
349 653210 : FOR( i = offset; i < input_frame; i++ )
350 : {
351 637532 : shift_input[i] = extract_h( L_mac0( L_mult0( g_lpc, shift_input[i] ), g, sts[leading_channel]->input_fx[i] ) ); // Q = 14 + q_shift - 16
352 637532 : move16();
353 : }
354 15678 : Word16 q_temp = sub( q_shift, 2 );
355 :
356 : /* smooth transition (currently done by blending over linearly, could be replaced by something more elaborate.) */
357 15678 : Word16 e_shift = 0;
358 15678 : move16();
359 1114430 : FOR( i = offset_pred_ovlp; i < offset; i++ )
360 : {
361 : /*shift_input[i] = ( i - input_frame + itd_shift + pred_ovlp ) * ( ( g_lpc * shift_input[i] ) + ( g * sts[leading_channel]->input[i] ) ) / pred_ovlp + ( input_frame - itd_shift - i ) * shift_input[i] / pred_ovlp;*/
362 1098752 : L_tmp = L_shr( L_mult0( shift_input[i], sub( offset, i ) ), 1 ); // q_shift - 1
363 1098752 : L_tmp = Madd_32_16( L_tmp, L_mac0( L_mult0( g_lpc, shift_input[i] ), g, sts[leading_channel]->input_fx[i] ), sub( i, offset_pred_ovlp ) ); // q_shift - 1
364 :
365 1098752 : shift_input[i] = BASOP_Util_Divide3232_Scale( L_tmp, pred_ovlp, &e_shift ); // Q=15-e_shift+q_shift-1 = 14-e_shift+q_shift
366 1098752 : move16();
367 1098752 : shift_input[i] = shr( shift_input[i], sub( add( sub( 14, e_shift ), q_shift ), q_temp ) ); // q_temp
368 1098752 : move16();
369 : }
370 :
371 : // scaling whole buffer to q_temp//
372 9266914 : FOR( i = 0; i < offset_pred_ovlp; i++ )
373 : {
374 9251236 : shift_input[i] = shr( shift_input[i], sub( q_shift, q_temp ) );
375 9251236 : move16();
376 : }
377 :
378 15678 : *q_new_shift = q_temp;
379 15678 : move16();
380 15678 : return;
381 : }
382 :
383 : /*---------------------------------------------------------------
384 : * stereo_td_itd()
385 : *
386 : *
387 : * ---------------------------------------------------------------*/
388 :
389 74349 : void stereo_td_itd_fx(
390 : ITD_DATA *hITD, /* i/o: ITD data structure */
391 : Word16 input_mem_itd[CPE_CHANNELS][STEREO_DFT_OVL_MAX], /* o : ITD memory (only used in DFT Stereo) q_input_mem_itd*/
392 : Word16 *q_input_mem_itd,
393 : const Word16 hybrid_itd_flag, /* i : flag for hybrid TD/FD ITD processing */
394 : const Word16 dft_ovl, /* i : size of DFT overlap */
395 : Encoder_State **sts, /* i/o: Encoder state structure */
396 : const Word16 input_frame, /* i : input frame length */
397 : Word16 *input_mem[CPE_CHANNELS], /* i/o: input buffer memory q_input_mem */
398 : Word16 *q_input_mem )
399 : {
400 : Word16 i, ch, n;
401 : Word16 size_ovl, k_offset;
402 : Word16 shift[2];
403 : Word16 itd, itd_max;
404 : Word16 shift_input[L_FRAME48k];
405 : Word16 shift_mem[L_FRAME48k];
406 : Word16 q_shift_mem;
407 : Word16 *mdct_mem[CPE_CHANNELS];
408 : // Word16 q_mdct_mem[CPE_CHANNELS];
409 : Word16 q_shift, q_new_shift;
410 :
411 74349 : k_offset = STEREO_DFT_OFFSET;
412 74349 : move16();
413 74349 : set16_fx( shift_input, 0, input_frame );
414 :
415 74349 : IF( EQ_16( sts[0]->element_mode, IVAS_CPE_MDCT ) )
416 : {
417 44070 : FOR( n = 0; n < CPE_CHANNELS; n++ )
418 : {
419 29380 : mdct_mem[n] = sts[n]->old_input_signal_fx;
420 29380 : move16();
421 : // q_mdct_mem[n] = sts[n]->q_old_inp;
422 : }
423 : }
424 74349 : IF( EQ_16( sts[0]->element_mode, IVAS_CPE_DFT ) )
425 : {
426 : /* Update the parameters */
427 119318 : FOR( i = 0; i < k_offset; i++ )
428 : {
429 59659 : hITD->deltaItd_fx[i] = hITD->deltaItd_fx[i + 1];
430 59659 : move32();
431 59659 : hITD->td_itd[i] = hITD->td_itd[i + 1];
432 59659 : move16();
433 59659 : hITD->td_itd_32k[i] = hITD->td_itd_32k[i + 1];
434 59659 : move16();
435 : }
436 : }
437 : /*reset TD ITDs in case of hybrid itd_max change - turn hybrid ITD off*/
438 74349 : test();
439 74349 : IF( EQ_16( hITD->hybrid_itd_max, -1 ) && EQ_16( hybrid_itd_flag, 0 ) )
440 : {
441 16 : hITD->td_itd[k_offset] = 0;
442 16 : move16();
443 16 : hITD->td_itd_32k[k_offset] = 0;
444 16 : move16();
445 : }
446 74349 : IF( EQ_16( hybrid_itd_flag, 0 ) )
447 : {
448 38920 : return;
449 : }
450 35429 : stereo_td_get_td_itd_fx( &( hITD->td_itd[k_offset] ), &( hITD->td_itd_32k[k_offset] ), hITD->itd_fx[k_offset], Q16, sts[0]->input_Fs );
451 :
452 : /* initializations*/
453 : {
454 35429 : size_ovl = dft_ovl;
455 35429 : move16();
456 :
457 35429 : itd_max = shr( input_frame, 2 );
458 35429 : Word16 comp_flag1 = extract_l( LE_16( extract_l( L_shr( hITD->itd_fx[k_offset], Q16 ) ), itd_max ) );
459 35429 : Word16 comp_flag2 = extract_l( LE_16( extract_l( L_shr( hITD->itd_fx[sub( k_offset, 1 )], Q16 ) ), itd_max ) );
460 35429 : assert( ( comp_flag1 ) && "ITD value is too high!" );
461 35429 : assert( ( comp_flag2 ) && "ITD value is too high!" );
462 :
463 35429 : itd = hITD->td_itd[k_offset];
464 :
465 : /*Time shift with current ITD*/
466 35429 : IF( LT_16( itd, 0 ) )
467 : {
468 10441 : shift[1] = 0;
469 10441 : move16();
470 10441 : shift[0] = negate( itd );
471 10441 : move16();
472 10441 : ch = 0;
473 10441 : move16();
474 : }
475 : ELSE
476 : {
477 24988 : shift[1] = itd;
478 24988 : move16();
479 24988 : shift[0] = 0;
480 24988 : move16();
481 24988 : ch = 1;
482 24988 : move16();
483 : }
484 :
485 : /* extrapolate lagging channel */
486 35429 : IF( GT_16( shift[ch], 0 ) )
487 : {
488 15678 : IF( EQ_16( sts[0]->element_mode, IVAS_CPE_DFT ) )
489 : {
490 : /* store last part of signal before extrapolation */
491 36315 : FOR( n = 0; n < CPE_CHANNELS; n++ )
492 : {
493 24210 : Copy( sts[n]->input_fx + input_frame - dft_ovl, input_mem_itd[n], dft_ovl );
494 24210 : q_input_mem_itd[n] = sts[n]->q_inp;
495 24210 : move16();
496 : }
497 :
498 : /*shift past part*/
499 12105 : Copy( input_mem[ch] + shift[ch], shift_mem, sub( size_ovl, shift[ch] ) );
500 12105 : Copy( sts[ch]->input_fx, shift_mem + size_ovl - shift[ch], shift[ch] );
501 12105 : q_shift_mem = sts[ch]->q_inp;
502 12105 : move16();
503 : }
504 : ELSE
505 : {
506 : /*shift past part*/
507 3573 : Copy( mdct_mem[ch] + shift[ch], shift_mem, input_frame - shift[ch] );
508 3573 : Copy( sts[ch]->input_fx, shift_mem + input_frame - shift[ch], shift[ch] );
509 3573 : q_shift_mem = sts[ch]->q_inp;
510 3573 : move16();
511 : }
512 : /*shift current part*/
513 15678 : Copy( sts[ch]->input_fx + shift[ch], shift_input, sub( input_frame, shift[ch] ) );
514 :
515 15678 : q_shift = sts[ch]->q_inp;
516 15678 : move16();
517 : // q_shift is shift for both shift_mem and shift_inp//
518 : // both channels input maintain same q//
519 15678 : IF( EQ_16( sts[0]->element_mode, IVAS_CPE_DFT ) )
520 : {
521 : /*Extrapolate current frame*/
522 12105 : stereo_td_channel_extrapolate_fx( sts, dft_ovl, shift_mem, q_shift, shift_input, input_frame, shift[ch], ch, input_mem, q_input_mem, &q_new_shift );
523 : }
524 : ELSE
525 : {
526 : /*Extrapolate current frame*/
527 3573 : stereo_td_channel_extrapolate_fx( sts, 0, shift_mem, q_shift, shift_input, input_frame, shift[ch], ch, mdct_mem, q_input_mem, &q_new_shift );
528 : }
529 :
530 : /* write back the extrapolated signal into sts[ch]->input */
531 15678 : Copy( shift_input, sts[ch]->input_fx, input_frame );
532 15678 : sts[ch]->q_inp = q_new_shift;
533 15678 : move16();
534 15678 : Copy_Scale_sig_16_32_no_sat( sts[ch]->input_fx, sts[ch]->input32_fx, input_frame, sub( sts[ch]->q_inp32, sts[ch]->q_inp ) );
535 :
536 15678 : IF( EQ_16( sts[0]->element_mode, IVAS_CPE_DFT ) )
537 : {
538 : // here shift_mem has same as input_mem, no need to update q //
539 12105 : Copy( shift_mem, input_mem[ch], size_ovl );
540 : }
541 : ELSE
542 : {
543 3573 : Copy( shift_mem, mdct_mem[ch], input_frame );
544 3573 : sts[ch]->q_old_inp = q_new_shift;
545 3573 : move16();
546 3573 : Scale_sig( mdct_mem[ch], input_frame, sub( sts[ch]->q_inp, q_shift_mem ) ); // Q(sts[ch]->q_inp)
547 3573 : Copy_Scale_sig_16_32_no_sat( shift_mem, sts[ch]->old_input_signal32_fx, input_frame, sub( sts[ch]->q_old_inp32, q_shift_mem ) );
548 : }
549 : }
550 : }
551 :
552 35429 : return;
553 : }
554 :
555 : /*---------------------------------------------------------------
556 : * stereo_td_itd_mdct_stereo()
557 : *
558 : * Time-domain ITD in MDCT stereo
559 : * ---------------------------------------------------------------*/
560 346785 : void stereo_td_itd_mdct_stereo_fx(
561 : CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder handle */
562 : const Word16 vad_flag_dtx[], /* i : VAD dtx flags */
563 : const Word16 vad_hover_flag[], /* i : VAD hangover flags */
564 : const Word16 input_frame /* i : frame length */
565 : )
566 : {
567 : Word16 i;
568 : Word32 bin_nrgL_fx[STEREO_DFT_N_32k_ENC];
569 : Word16 bin_nrgL_e[STEREO_DFT_N_32k_ENC];
570 : Word32 bin_nrgR_fx[STEREO_DFT_N_32k_ENC];
571 : Word16 bin_nrgR_e[STEREO_DFT_N_32k_ENC];
572 : Word32 DFT_fx[CPE_CHANNELS][STEREO_DFT_N_MAX_ENC];
573 : Word16 DFT_e[CPE_CHANNELS];
574 : Word16 DFT_tmp_e[CPE_CHANNELS][STEREO_DFT_N_MAX_ENC];
575 : STEREO_MDCT_ENC_DATA_HANDLE hStereoMdct;
576 :
577 346785 : test();
578 346785 : IF( hCPE->hStereoMdct != NULL && hCPE->hStereoMdct->hItd != NULL )
579 : {
580 14690 : hStereoMdct = hCPE->hStereoMdct;
581 :
582 14690 : hCPE->hStereoMdct->hItd->td_itd_32k[STEREO_DFT_OFFSET] = 0;
583 14690 : move16();
584 14690 : hStereoMdct->hItd->td_itd[STEREO_DFT_OFFSET] = 0;
585 14690 : move16();
586 :
587 : /* Update the parameters */
588 29380 : FOR( i = 0; i < STEREO_DFT_OFFSET; i++ )
589 : {
590 14690 : hStereoMdct->hItd->deltaItd_fx[i] = hStereoMdct->hItd->deltaItd_fx[i + 1];
591 14690 : move32();
592 14690 : hStereoMdct->hItd->td_itd[i] = hStereoMdct->hItd->td_itd[i + 1];
593 14690 : move16();
594 14690 : hStereoMdct->hItd->td_itd_32k[i] = hStereoMdct->hItd->td_itd_32k[i + 1];
595 14690 : move16();
596 : }
597 :
598 14690 : stereo_dft_enc_analyze_fx( hCPE->hCoreCoder, CPE_CHANNELS, input_frame, NULL, hStereoMdct, DFT_fx, DFT_e, hCPE->input_mem_fx, hCPE->q_input_mem );
599 :
600 28219490 : FOR( i = 0; i < STEREO_DFT_N_MAX_ENC; i++ )
601 : {
602 28204800 : DFT_tmp_e[0][i] = DFT_e[0];
603 28204800 : move16();
604 28204800 : DFT_tmp_e[1][i] = DFT_e[1];
605 28204800 : move16();
606 : }
607 :
608 : /*call ITD function*/
609 14690 : stereo_dft_enc_compute_itd_fx( hCPE, DFT_fx[0], DFT_tmp_e[0], DFT_fx[1], DFT_tmp_e[1], STEREO_DFT_OFFSET, input_frame, vad_flag_dtx, vad_hover_flag, bin_nrgL_fx, bin_nrgL_e, bin_nrgR_fx, bin_nrgR_e );
610 :
611 : /* Time Domain ITD compensation using extrapolation */
612 14690 : stereo_td_itd_fx( hStereoMdct->hItd, NULL, NULL, 1, hStereoMdct->hDft_ana->dft_ovl, hCPE->hCoreCoder, input_frame, hCPE->input_mem_fx, hCPE->q_input_mem );
613 : }
614 :
615 346785 : return;
616 : }
|