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 16384 // Q15
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 35397 : 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 : Word16 d, d_e;
99 :
100 35397 : IF( EQ_32( input_Fs, 32000 ) )
101 : {
102 12815 : *td_itd_32 = *td_itd = extract_l( L_shr_r( itd, q_itd ) );
103 12815 : move16();
104 12815 : move16();
105 : }
106 : ELSE
107 : {
108 22582 : assert( ( input_Fs % 16000 ) == 0 && "sampling frequency should be divisible by 16000" );
109 : Word16 temp_div, temp_e, temp_add;
110 22582 : d = BASOP_Util_Divide3232_Scale( input_Fs, 16000, &d_e );
111 22582 : temp_div = BASOP_Util_Divide3232_Scale( itd, L_deposit_h( d ), &temp_e );
112 22582 : temp_e = add( temp_e, sub( sub( 31, q_itd ), d_e ) ); // e+(e1-e2)//
113 22582 : temp_add = add_sat( temp_div, shr_sat( FLR_FX, temp_e ) );
114 :
115 22582 : IF( itd != 0 )
116 : {
117 9975 : *td_itd_32 = extract_l( L_shl( L_shr( L_add( temp_add, EPSILON_FX ), sub( 15, temp_e ) ), 1 ) );
118 : }
119 : ELSE
120 : {
121 12607 : *td_itd_32 = shl( shr( temp_add, sub( 15, temp_e ) ), 1 );
122 : }
123 22582 : move16();
124 :
125 22582 : *td_itd = i_mult( shr( *td_itd_32, 1 ), shr( d, sub( 15, d_e ) ) );
126 22582 : move16();
127 : }
128 :
129 35397 : return;
130 : }
131 :
132 : /*---------------------------------------------------------------
133 : * stereo_td_channel_extrapolate()
134 : *
135 : *
136 : * ---------------------------------------------------------------*/
137 :
138 15669 : static void stereo_td_channel_extrapolate_fx(
139 : Encoder_State **sts,
140 : const Word16 dft_ovl,
141 : const Word16 shift_mem[], // q_shift
142 : Word16 q_shift,
143 : Word16 shift_input[], // q_shift
144 : const Word16 input_frame,
145 : const Word16 itd_shift,
146 : const Word16 lagging_channel,
147 : Word16 *input_mem[CPE_CHANNELS], /* i/o: input buffer memory q_input_mem */
148 : Word16 *q_input_mem,
149 : Word16 *q_new_shift )
150 : {
151 : Word16 leading_channel, i, size_ovl, pred_ovlp;
152 : Word16 g, nsr, g_lpc;
153 : Word32 dot_lead_lag_1, dot_lead_lead_1, dot_lag_lag_1;
154 : Word64 dot_lead_lag, dot_lead_lead, dot_lag_lag;
155 : Word16 q_dot_lead_lag, q_dot_lead_lead, q_dot_lag_lag;
156 : Word16 window[STEREO_DFT_CHANNEL_EXTR_LPC_VEC_LIMIT], mem_zero[STEREO_DFT_CHANNEL_EXTR_LPC_ORDER];
157 : Word16 residual[STEREO_DFT_CHANNEL_EXTR_LPC_VEC_LIMIT + ( STEREO_DFT_ITD_MAX * L_FRAME48k ) / L_FRAME32k];
158 : Word16 r_h[STEREO_DFT_CHANNEL_EXTR_LPC_ORDER + 1];
159 : Word16 r_l[STEREO_DFT_CHANNEL_EXTR_LPC_ORDER + 1];
160 : Word16 Q_r;
161 : Word16 A[STEREO_DFT_CHANNEL_EXTR_LPC_ORDER + 1];
162 : Word16 shift_combined[L_FRAME48k + L_FRAME48k];
163 : // Word16 q_shift_combined;
164 : Word16 flag;
165 : Word16 pitch_lag;
166 : Word16 res_shift;
167 : Word16 pitch0, tmp, tmp_e;
168 : Word32 L_tmp;
169 : // shift_mem and shift_input are of same Q q_shift//
170 15669 : set16_fx( shift_combined, 0, add( L_FRAME48k, L_FRAME48k ) );
171 15669 : set16_fx( residual, 0, STEREO_DFT_CHANNEL_EXTR_LPC_VEC_LIMIT + ( STEREO_DFT_ITD_MAX * input_frame ) / L_FRAME32k );
172 :
173 15669 : leading_channel = s_and( add( lagging_channel, 1 ), 1 );
174 15669 : IF( EQ_16( sts[0]->element_mode, IVAS_CPE_DFT ) )
175 : {
176 12128 : size_ovl = dft_ovl;
177 12128 : pitch0 = sts[0]->pitch[0];
178 : }
179 : ELSE
180 : {
181 3541 : size_ovl = input_frame;
182 3541 : pitch0 = sts[lagging_channel]->pitch[0];
183 : }
184 15669 : move16();
185 15669 : move16();
186 :
187 15669 : pred_ovlp = idiv1616( input_frame, 10 );
188 :
189 : /*get pitch lag from previous frame */
190 : // pitch_lag = (int16_t) ( pitch0 * ( (float) input_frame / L_FRAME ) );
191 15669 : tmp = BASOP_Util_Divide3232_Scale( input_frame, L_FRAME, &tmp_e );
192 15669 : L_tmp = L_mult0( pitch0, tmp );
193 15669 : pitch_lag = extract_l( L_shr( L_tmp, sub( 15, tmp_e ) ) ); /* Q0 */
194 :
195 : /* compute the parameters g, nsr and g_lpc */
196 15669 : dot_lead_lag = EPSILON_FX;
197 15669 : dot_lead_lead = EPSILON_FX;
198 15669 : dot_lag_lag = EPSILON_FX;
199 15669 : dot_lead_lag_1 = EPSILON_FX;
200 15669 : dot_lead_lead_1 = EPSILON_FX;
201 15669 : dot_lag_lag_1 = EPSILON_FX;
202 15669 : move64();
203 15669 : move64();
204 15669 : move64();
205 15669 : move32();
206 15669 : move32();
207 15669 : move32();
208 5872949 : FOR( i = 0; i < size_ovl; i++ )
209 : {
210 5857280 : shift_combined[i] = shift_mem[i]; // q_shift
211 5857280 : move16();
212 : // q_shift_combined = q_shift;
213 5857280 : dot_lead_lag = W_mac0_16_16( dot_lead_lag, input_mem[leading_channel][i], shift_mem[i] );
214 5857280 : dot_lead_lead = W_mac0_16_16( dot_lead_lead, input_mem[leading_channel][i], input_mem[leading_channel][i] );
215 5857280 : dot_lag_lag = W_mac0_16_16( dot_lag_lag, shift_mem[i], shift_mem[i] );
216 : }
217 10376555 : FOR( i = 0; i < input_frame - itd_shift; i++ )
218 : {
219 10360886 : shift_combined[i + size_ovl] = shift_input[i]; // q_shift
220 10360886 : move16();
221 10360886 : dot_lead_lag = W_mac0_16_16( dot_lead_lag, sts[leading_channel]->input_fx[i], shift_input[i] );
222 10360886 : dot_lead_lead = W_mac0_16_16( dot_lead_lead, sts[leading_channel]->input_fx[i], sts[leading_channel]->input_fx[i] );
223 10360886 : dot_lag_lag = W_mac0_16_16( dot_lag_lag, shift_input[i], shift_input[i] );
224 : }
225 15669 : q_dot_lead_lag = q_shift + q_input_mem[leading_channel]; // q_input_mem = q_input
226 15669 : q_dot_lead_lead = q_input_mem[leading_channel] + q_input_mem[leading_channel];
227 15669 : q_dot_lag_lag = add( q_shift, q_shift );
228 :
229 :
230 15669 : q_dot_lead_lag = sub( add( q_dot_lead_lag, W_norm( dot_lead_lag ) ), 32 );
231 15669 : q_dot_lead_lead = sub( add( q_dot_lead_lead, W_norm( dot_lead_lead ) ), 32 );
232 15669 : q_dot_lag_lag = sub( add( q_dot_lag_lag, W_norm( dot_lag_lag ) ), 32 );
233 15669 : dot_lead_lag_1 = W_extract_h( W_shl( dot_lead_lag, W_norm( dot_lead_lag ) ) );
234 15669 : dot_lead_lead_1 = W_extract_h( W_shl( dot_lead_lead, W_norm( dot_lead_lead ) ) );
235 15669 : dot_lag_lag_1 = W_extract_h( W_shl( dot_lag_lag, W_norm( dot_lag_lag ) ) );
236 :
237 :
238 : Word16 g_e, f, f_e, g_lpc_e, nsr_e;
239 15669 : g = BASOP_Util_Divide3232_Scale( dot_lead_lag_1, dot_lead_lead_1, &g_e );
240 15669 : g_e = add( g_e, sub( q_dot_lead_lead, q_dot_lead_lag ) );
241 :
242 15669 : f = BASOP_Util_Divide3232_Scale( dot_lead_lag_1, dot_lag_lag_1, &f_e );
243 15669 : f_e = add( f_e, sub( q_dot_lag_lag, q_dot_lead_lag ) );
244 :
245 15669 : nsr = mult( g, f );
246 15669 : nsr_e = BASOP_Util_Add_MantExp( ONE_IN_Q14, 1, negate( nsr ), add( g_e, f_e ), &nsr );
247 15669 : IF( g_e > 0 )
248 : {
249 2944 : g = check_bounds_s_fx( g, negate( shl( 1, sub( 15, g_e ) ) ), shl( ONE_HALF, sub( 1, g_e ) ) );
250 : }
251 15669 : IF( nsr_e > 0 )
252 : {
253 0 : nsr = check_bounds_s_fx( nsr, 0, shl( 1, sub( 15, nsr_e ) ) );
254 : }
255 15669 : g = shl( g, sub( g_e, 1 ) ); // q14
256 15669 : nsr = shl( nsr, nsr_e ); // Q15
257 15669 : g_lpc_e = 0;
258 15669 : move16();
259 15669 : g_lpc = Sqrt16( nsr, &g_lpc_e );
260 15669 : g_lpc = shl( g_lpc, sub( g_lpc_e, 1 ) ); // Q14
261 : /* rectangular window */
262 15669 : set16_fx( window, 32767, STEREO_DFT_CHANNEL_EXTR_LPC_VEC_LIMIT );
263 15669 : set16_zero_fx( mem_zero, STEREO_DFT_CHANNEL_EXTR_LPC_ORDER );
264 :
265 : /* get the LPC filter */
266 15669 : 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 );
267 : /* Ensure R[0] isn't zero when entering Levinson-Durbin */
268 15669 : r_l[0] = s_max( r_l[0], 1 );
269 15669 : move16();
270 188028 : FOR( i = 0; i <= STEREO_DFT_CHANNEL_EXTR_LPC_ORDER; i++ )
271 : {
272 172359 : L_tmp = Mpy_32( r_h[i], r_l[i], wac_swb_h_fx[i], wac_swb_l_fx[i] );
273 172359 : L_Extract( L_tmp, &r_h[i], &r_l[i] );
274 : }
275 15669 : r_l[0] = s_max( r_l[0], 1 );
276 15669 : move16();
277 15669 : flag = E_LPC_lev_dur( r_h, r_l, A, NULL, STEREO_DFT_CHANNEL_EXTR_LPC_ORDER, NULL );
278 15669 : Copy_Scale_sig( A, A, STEREO_DFT_CHANNEL_EXTR_LPC_ORDER + 1, sub( norm_s( A[0] ), 2 ) );
279 15669 : IF( EQ_16( flag, 1 ) )
280 : {
281 0 : g_lpc = 0;
282 0 : move16();
283 : }
284 : ELSE
285 : {
286 : /* get the residual */
287 15669 : 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 );
288 :
289 : /* extend the residual */
290 : /* to prevent out of bound reading */
291 15669 : IF( LT_16( pitch_lag, PIT_MAX ) )
292 : {
293 9569 : res_shift = pitch_lag;
294 9569 : move16();
295 : }
296 : ELSE
297 : {
298 6100 : res_shift = itd_shift;
299 6100 : move16();
300 : }
301 :
302 658623 : FOR( i = STEREO_DFT_CHANNEL_EXTR_LPC_VEC_LIMIT; i < STEREO_DFT_CHANNEL_EXTR_LPC_VEC_LIMIT + itd_shift; i++ )
303 : {
304 642954 : residual[i] = residual[i - res_shift];
305 642954 : move16();
306 : }
307 :
308 : /* perform sythesis */
309 15669 : 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 );
310 : }
311 :
312 15669 : Copy( shift_combined + size_ovl, shift_input, input_frame ); // q_shift
313 :
314 15669 : Word16 offset = sub( input_frame, itd_shift );
315 15669 : Word16 offset_pred_ovlp = sub( offset, pred_ovlp );
316 :
317 658623 : FOR( i = offset; i < input_frame; i++ )
318 : {
319 642954 : 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
320 642954 : move16();
321 : }
322 15669 : Word16 q_temp = sub( q_shift, 2 );
323 :
324 : /* smooth transition (currently done by blending over linearly, could be replaced by something more elaborate.) */
325 15669 : Word16 e_shift = 0;
326 15669 : move16();
327 1116053 : FOR( i = offset_pred_ovlp; i < offset; i++ )
328 : {
329 : /*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;*/
330 1100384 : L_tmp = L_shr( L_mult0( shift_input[i], sub( offset, i ) ), 1 ); // q_shift - 1
331 1100384 : 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
332 :
333 1100384 : 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
334 1100384 : move16();
335 1100384 : shift_input[i] = shr( shift_input[i], sub( add( sub( 14, e_shift ), q_shift ), q_temp ) ); // q_temp
336 1100384 : move16();
337 : }
338 :
339 : // scaling whole buffer to q_temp//
340 9276171 : FOR( i = 0; i < offset_pred_ovlp; i++ )
341 : {
342 9260502 : shift_input[i] = shr( shift_input[i], sub( q_shift, q_temp ) );
343 9260502 : move16();
344 : }
345 :
346 15669 : *q_new_shift = q_temp;
347 15669 : move16();
348 15669 : return;
349 : }
350 :
351 : /*---------------------------------------------------------------
352 : * stereo_td_itd()
353 : *
354 : *
355 : * ---------------------------------------------------------------*/
356 :
357 74333 : void stereo_td_itd_fx(
358 : ITD_DATA *hITD, /* i/o: ITD data structure */
359 : Word16 input_mem_itd[CPE_CHANNELS][STEREO_DFT_OVL_MAX], /* o : ITD memory (only used in DFT Stereo) q_input_mem_itd*/
360 : Word16 *q_input_mem_itd,
361 : const Word16 hybrid_itd_flag, /* i : flag for hybrid TD/FD ITD processing */
362 : const Word16 dft_ovl, /* i : size of DFT overlap */
363 : Encoder_State **sts, /* i/o: Encoder state structure */
364 : const Word16 input_frame, /* i : input frame length */
365 : Word16 *input_mem[CPE_CHANNELS], /* i/o: input buffer memory q_input_mem */
366 : Word16 *q_input_mem )
367 : {
368 : Word16 i, ch, n;
369 : Word16 size_ovl, k_offset;
370 : Word16 shift[2];
371 : Word16 itd, itd_max;
372 : Word16 shift_input[L_FRAME48k];
373 : Word16 shift_mem[L_FRAME48k];
374 : Word16 q_shift_mem;
375 : Word16 *mdct_mem[CPE_CHANNELS];
376 : // Word16 q_mdct_mem[CPE_CHANNELS];
377 : Word16 q_shift, q_new_shift;
378 :
379 74333 : k_offset = STEREO_DFT_OFFSET;
380 74333 : move16();
381 74333 : set16_fx( shift_input, 0, input_frame );
382 :
383 74333 : IF( EQ_16( sts[0]->element_mode, IVAS_CPE_MDCT ) )
384 : {
385 44070 : FOR( n = 0; n < CPE_CHANNELS; n++ )
386 : {
387 29380 : mdct_mem[n] = sts[n]->old_input_signal_fx;
388 29380 : move16();
389 : // q_mdct_mem[n] = sts[n]->q_old_inp;
390 : }
391 : }
392 74333 : IF( EQ_16( sts[0]->element_mode, IVAS_CPE_DFT ) )
393 : {
394 : /* Update the parameters */
395 119286 : FOR( i = 0; i < k_offset; i++ )
396 : {
397 59643 : hITD->deltaItd_fx[i] = hITD->deltaItd_fx[i + 1];
398 59643 : move32();
399 59643 : hITD->td_itd[i] = hITD->td_itd[i + 1];
400 59643 : move16();
401 59643 : hITD->td_itd_32k[i] = hITD->td_itd_32k[i + 1];
402 59643 : move16();
403 : }
404 : }
405 : /*reset TD ITDs in case of hybrid itd_max change - turn hybrid ITD off*/
406 74333 : test();
407 74333 : IF( EQ_16( hITD->hybrid_itd_max, -1 ) && EQ_16( hybrid_itd_flag, 0 ) )
408 : {
409 21 : hITD->td_itd[k_offset] = 0;
410 21 : move16();
411 21 : hITD->td_itd_32k[k_offset] = 0;
412 21 : move16();
413 : }
414 74333 : IF( EQ_16( hybrid_itd_flag, 0 ) )
415 : {
416 38936 : return;
417 : }
418 35397 : 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 );
419 :
420 : /* initializations*/
421 : {
422 35397 : size_ovl = dft_ovl;
423 35397 : move16();
424 :
425 35397 : itd_max = shr( input_frame, 2 );
426 35397 : Word16 comp_flag1 = extract_l( LE_16( extract_l( L_shr( hITD->itd_fx[k_offset], Q16 ) ), itd_max ) );
427 35397 : Word16 comp_flag2 = extract_l( LE_16( extract_l( L_shr( hITD->itd_fx[sub( k_offset, 1 )], Q16 ) ), itd_max ) );
428 35397 : assert( ( comp_flag1 ) && "ITD value is too high!" );
429 35397 : assert( ( comp_flag2 ) && "ITD value is too high!" );
430 :
431 35397 : itd = hITD->td_itd[k_offset];
432 :
433 : /*Time shift with current ITD*/
434 35397 : IF( LT_16( itd, 0 ) )
435 : {
436 10414 : shift[1] = 0;
437 10414 : move16();
438 10414 : shift[0] = negate( itd );
439 10414 : move16();
440 10414 : ch = 0;
441 10414 : move16();
442 : }
443 : ELSE
444 : {
445 24983 : shift[1] = itd;
446 24983 : move16();
447 24983 : shift[0] = 0;
448 24983 : move16();
449 24983 : ch = 1;
450 24983 : move16();
451 : }
452 :
453 : /* extrapolate lagging channel */
454 35397 : IF( GT_16( shift[ch], 0 ) )
455 : {
456 15669 : IF( EQ_16( sts[0]->element_mode, IVAS_CPE_DFT ) )
457 : {
458 : /* store last part of signal before extrapolation */
459 36384 : FOR( n = 0; n < CPE_CHANNELS; n++ )
460 : {
461 24256 : Copy( sts[n]->input_fx + input_frame - dft_ovl, input_mem_itd[n], dft_ovl );
462 24256 : q_input_mem_itd[n] = sts[n]->q_inp;
463 24256 : move16();
464 : }
465 :
466 : /*shift past part*/
467 12128 : Copy( input_mem[ch] + shift[ch], shift_mem, sub( size_ovl, shift[ch] ) );
468 12128 : Copy( sts[ch]->input_fx, shift_mem + size_ovl - shift[ch], shift[ch] );
469 12128 : q_shift_mem = sts[ch]->q_inp;
470 12128 : move16();
471 : }
472 : ELSE
473 : {
474 : /*shift past part*/
475 3541 : Copy( mdct_mem[ch] + shift[ch], shift_mem, input_frame - shift[ch] );
476 3541 : Copy( sts[ch]->input_fx, shift_mem + input_frame - shift[ch], shift[ch] );
477 3541 : q_shift_mem = sts[ch]->q_inp;
478 3541 : move16();
479 : }
480 : /*shift current part*/
481 15669 : Copy( sts[ch]->input_fx + shift[ch], shift_input, sub( input_frame, shift[ch] ) );
482 :
483 15669 : q_shift = sts[ch]->q_inp;
484 15669 : move16();
485 : // q_shift is shift for both shift_mem and shift_inp//
486 : // both channels input maintain same q//
487 15669 : IF( EQ_16( sts[0]->element_mode, IVAS_CPE_DFT ) )
488 : {
489 : /*Extrapolate current frame*/
490 12128 : 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 );
491 : }
492 : ELSE
493 : {
494 : /*Extrapolate current frame*/
495 3541 : 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 );
496 : }
497 :
498 : /* write back the extrapolated signal into sts[ch]->input */
499 15669 : Copy( shift_input, sts[ch]->input_fx, input_frame );
500 15669 : sts[ch]->q_inp = q_new_shift;
501 15669 : move16();
502 : /*sts[ch]->q_old_inp = q_new_shift;
503 : move16();*/
504 15669 : IF( EQ_16( sts[0]->element_mode, IVAS_CPE_DFT ) )
505 : {
506 : // here shift_mem has same as input_mem, no need to update q //
507 12128 : Copy( shift_mem, input_mem[ch], size_ovl );
508 : }
509 : ELSE
510 : {
511 3541 : Copy( shift_mem, mdct_mem[ch], input_frame );
512 3541 : sts[ch]->q_old_inp = q_new_shift;
513 3541 : move16();
514 3541 : Scale_sig( mdct_mem[ch], input_frame, sub( sts[ch]->q_inp, q_shift_mem ) ); // Q(sts[ch]->q_inp)
515 : }
516 : }
517 : }
518 :
519 35397 : return;
520 : }
521 :
522 : /*---------------------------------------------------------------
523 : * stereo_td_itd_mdct_stereo()
524 : *
525 : * Time-domain ITD in MDCT stereo
526 : * ---------------------------------------------------------------*/
527 346785 : void stereo_td_itd_mdct_stereo_fx(
528 : CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder handle */
529 : const Word16 vad_flag_dtx[], /* i : VAD dtx flags */
530 : const Word16 vad_hover_flag[], /* i : VAD hangover flags */
531 : const Word16 input_frame /* i : frame length */
532 : )
533 : {
534 : Word16 i, n, q_com;
535 : Word32 bin_nrgL_fx[STEREO_DFT_N_32k_ENC];
536 : Word16 bin_nrgL_e[STEREO_DFT_N_32k_ENC];
537 : Word32 bin_nrgR_fx[STEREO_DFT_N_32k_ENC];
538 : Word16 bin_nrgR_e[STEREO_DFT_N_32k_ENC];
539 : Word32 DFT_fx[CPE_CHANNELS][STEREO_DFT_N_MAX_ENC];
540 : Word16 DFT_e[CPE_CHANNELS];
541 : Word16 DFT_tmp_e[CPE_CHANNELS][STEREO_DFT_N_MAX_ENC];
542 : STEREO_MDCT_ENC_DATA_HANDLE hStereoMdct;
543 :
544 346785 : test();
545 346785 : IF( hCPE->hStereoMdct != NULL && hCPE->hStereoMdct->hItd != NULL )
546 : {
547 14690 : hStereoMdct = hCPE->hStereoMdct;
548 :
549 14690 : hCPE->hStereoMdct->hItd->td_itd_32k[STEREO_DFT_OFFSET] = 0;
550 14690 : move16();
551 14690 : hStereoMdct->hItd->td_itd[STEREO_DFT_OFFSET] = 0;
552 14690 : move16();
553 :
554 : /* Update the parameters */
555 29380 : FOR( i = 0; i < STEREO_DFT_OFFSET; i++ )
556 : {
557 14690 : hStereoMdct->hItd->deltaItd_fx[i] = hStereoMdct->hItd->deltaItd_fx[i + 1];
558 14690 : move32();
559 14690 : hStereoMdct->hItd->td_itd[i] = hStereoMdct->hItd->td_itd[i + 1];
560 14690 : move16();
561 14690 : hStereoMdct->hItd->td_itd_32k[i] = hStereoMdct->hItd->td_itd_32k[i + 1];
562 14690 : move16();
563 : }
564 :
565 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 );
566 :
567 28219490 : FOR( i = 0; i < STEREO_DFT_N_MAX_ENC; i++ )
568 : {
569 28204800 : DFT_tmp_e[0][i] = DFT_e[0];
570 28204800 : move16();
571 28204800 : DFT_tmp_e[1][i] = DFT_e[1];
572 28204800 : move16();
573 : }
574 :
575 : /*call ITD function*/
576 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 );
577 :
578 14690 : q_com = MAX_16;
579 14690 : move16();
580 :
581 44070 : FOR( n = 0; n < CPE_CHANNELS; n++ )
582 : {
583 29380 : q_com = s_min( q_com, add( norm_arr( hCPE->hCoreCoder[n]->input_fx, input_frame ), hCPE->hCoreCoder[n]->q_inp ) );
584 29380 : q_com = s_min( q_com, add( norm_arr( hCPE->hCoreCoder[n]->old_input_signal_fx, input_frame ), hCPE->hCoreCoder[n]->q_old_inp ) );
585 29380 : q_com = s_min( q_com, add( norm_arr( hCPE->input_mem_fx[n], hStereoMdct->hDft_ana->dft_ovl ), hCPE->q_input_mem[n] ) );
586 :
587 29380 : if ( EQ_16( q_com, Q15 ) )
588 : {
589 0 : q_com = 0;
590 0 : move16();
591 : }
592 : }
593 :
594 44070 : FOR( n = 0; n < CPE_CHANNELS; n++ )
595 : {
596 29380 : scale_sig( hCPE->hCoreCoder[n]->input_fx, input_frame, sub( q_com, hCPE->hCoreCoder[n]->q_inp ) );
597 29380 : hCPE->hCoreCoder[n]->q_inp = q_com;
598 29380 : move16();
599 :
600 29380 : scale_sig( hCPE->hCoreCoder[n]->old_input_signal_fx, input_frame, sub( q_com, hCPE->hCoreCoder[n]->q_old_inp ) );
601 29380 : hCPE->hCoreCoder[n]->q_old_inp = q_com;
602 29380 : move16();
603 :
604 29380 : scale_sig( hCPE->input_mem_fx[n], hStereoMdct->hDft_ana->dft_ovl, sub( q_com, hCPE->q_input_mem[n] ) );
605 29380 : hCPE->q_input_mem[n] = q_com;
606 29380 : move16();
607 : }
608 :
609 : /* Time Domain ITD compensation using extrapolation */
610 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 );
611 : }
612 :
613 346785 : return;
614 : }
|