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 : #include <stdint.h>
33 : #include <math.h>
34 : #include "options.h"
35 : #include "cnst.h"
36 : #include "ivas_cnst.h"
37 : #include "prot_fx.h"
38 : #include "ivas_prot_fx.h"
39 : #include "rom_com.h"
40 : #include "ivas_rom_com.h"
41 : #include "ivas_rom_dec.h"
42 : #include "wmc_auto.h"
43 :
44 :
45 : #define SIN_NEG_30_DEGREES_Q15 ( (Word16) 0xC000 )
46 : #define SIN_30_DEGREES_Q15 ( (Word16) 0x4000 )
47 :
48 : /*-------------------------------------------------------------------*
49 : * ivas_get_sba_dirac_stereo_flag()
50 : *
51 : * Set sba_dirac_stereo_flag
52 : *-------------------------------------------------------------------*/
53 :
54 3215 : Word16 ivas_get_sba_dirac_stereo_flag(
55 : Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */
56 : )
57 : {
58 : Word16 sba_dirac_stereo_flag;
59 : AUDIO_CONFIG output_config;
60 :
61 3215 : sba_dirac_stereo_flag = 0;
62 3215 : move16();
63 3215 : output_config = st_ivas->hDecoderConfig->output_config;
64 3215 : move16();
65 :
66 3215 : test();
67 3215 : test();
68 3215 : IF( EQ_16( st_ivas->ivas_format, SBA_FORMAT ) || ( EQ_16( st_ivas->ivas_format, MC_FORMAT ) && EQ_16( st_ivas->mc_mode, MC_MODE_MCMASA ) ) )
69 : {
70 1813 : IF( EQ_16( st_ivas->ivas_format, SBA_FORMAT ) )
71 : {
72 1265 : test();
73 1265 : test();
74 1265 : if ( EQ_16( output_config, IVAS_AUDIO_CONFIG_STEREO ) || ( EQ_16( output_config, IVAS_AUDIO_CONFIG_MONO ) && EQ_16( st_ivas->nchan_transport, 1 ) ) )
75 : {
76 132 : sba_dirac_stereo_flag = 1;
77 132 : move16();
78 : }
79 : }
80 : ELSE
81 : {
82 548 : test();
83 548 : if ( EQ_16( st_ivas->nchan_transport, 1 ) && EQ_16( output_config, IVAS_AUDIO_CONFIG_STEREO ) )
84 : {
85 7 : sba_dirac_stereo_flag = 1;
86 7 : move16();
87 : }
88 : }
89 : }
90 1402 : ELSE IF( EQ_16( st_ivas->ivas_format, SBA_ISM_FORMAT ) )
91 : {
92 596 : if ( EQ_16( output_config, IVAS_AUDIO_CONFIG_STEREO ) )
93 : {
94 94 : sba_dirac_stereo_flag = 1;
95 94 : move16();
96 : }
97 : }
98 :
99 3215 : return sba_dirac_stereo_flag;
100 : }
101 :
102 :
103 : /*-------------------------------------------------------------------*
104 : * ivas_sba_dirac_stereo_config()
105 : *
106 : * DFT Stereo Configuration for SBA DirAC stereo output
107 : *-------------------------------------------------------------------*/
108 :
109 10886 : void ivas_sba_dirac_stereo_config(
110 : STEREO_DFT_CONFIG_DATA_HANDLE hConfig /* o : DFT stereo configuration */
111 : )
112 : {
113 10886 : IF( hConfig != NULL )
114 : {
115 10886 : hConfig->dmx_active = STEREO_DFT_DMX_ACTIVE;
116 10886 : move16();
117 10886 : hConfig->band_res = STEREO_DFT_BAND_RES_HIGH;
118 10886 : move16();
119 10886 : hConfig->prm_res = 2;
120 10886 : move16();
121 :
122 10886 : hConfig->res_pred_mode = STEREO_DFT_RESPRED_ESF;
123 10886 : move16();
124 :
125 10886 : hConfig->res_cod_mode = STEREO_DFT_RES_COD_OFF;
126 10886 : move16();
127 10886 : hConfig->ada_wb_res_cod_mode = 0;
128 10886 : move16();
129 :
130 10886 : hConfig->hybrid_itd_flag = 0;
131 10886 : move16();
132 : }
133 :
134 10886 : return;
135 : }
136 :
137 :
138 : /*-------------------------------------------------------------------*
139 : * ivas_sba_dirac_stereo_band_config()
140 : *
141 : * Band Configuration for SBA DirAC stereo output
142 : *-------------------------------------------------------------------*/
143 :
144 10790 : static Word16 ivas_sba_dirac_stereo_band_config(
145 : Word16 *band_limits, /* o : DFT band limits Q0*/
146 : const Word32 output_Fs, /* i : output sampling rate Q0*/
147 : const Word16 NFFT, /* i : analysis/synthesis window length Q0*/
148 : const Word16 spar_flag /* i : SPAR or DirAC band grouping */
149 : )
150 : {
151 : Word16 i;
152 : Word16 bins_per_cldfb_band;
153 : Word16 nbands, num_cldfb_bands;
154 :
155 10790 : nbands = SBA_DIRAC_STEREO_NUM_BANDS;
156 10790 : move16();
157 :
158 10790 : IF( spar_flag )
159 : {
160 9610 : nbands = IVAS_MAX_NUM_BANDS;
161 9610 : move16();
162 : }
163 : ELSE
164 : {
165 1180 : nbands = 5;
166 1180 : move16();
167 : }
168 :
169 10790 : SWITCH( output_Fs )
170 : {
171 0 : case 8000:
172 0 : num_cldfb_bands = 10;
173 0 : move16();
174 0 : BREAK;
175 0 : case 16000:
176 0 : num_cldfb_bands = 20;
177 0 : move16();
178 0 : BREAK;
179 6030 : case 32000:
180 6030 : num_cldfb_bands = 40;
181 6030 : move16();
182 6030 : BREAK;
183 4760 : case 48000:
184 4760 : num_cldfb_bands = 60;
185 4760 : move16();
186 4760 : BREAK;
187 0 : default:
188 0 : num_cldfb_bands = 60;
189 0 : move16();
190 0 : assert( 0 );
191 : }
192 :
193 10790 : bins_per_cldfb_band = idiv1616( NFFT, shl( num_cldfb_bands, 1 ) /*( 2 * num_cldfb_bands )*/ ); /*Q0*/
194 10790 : move16();
195 10790 : band_limits[0] = 1;
196 10790 : move16();
197 115220 : FOR( i = 1; i < nbands; i++ )
198 : {
199 110430 : IF( spar_flag )
200 : {
201 105710 : band_limits[i] = i_mult( DirAC_band_grouping_12[i], bins_per_cldfb_band ); /*Q0*/
202 105710 : move16();
203 : }
204 : ELSE
205 : {
206 4720 : band_limits[i] = i_mult( DirAC_band_grouping_5[i], bins_per_cldfb_band ); /*Q0*/
207 4720 : move16();
208 : }
209 110430 : IF( GE_16( band_limits[i], shr( NFFT, 1 ) /* NFFT / 2 */ ) )
210 : {
211 6000 : nbands = i;
212 6000 : move16();
213 6000 : BREAK;
214 : }
215 : }
216 10790 : band_limits[nbands] = shr( NFFT, 1 ); /* NFFT / 2 */
217 10790 : move16();
218 :
219 10790 : return nbands;
220 : }
221 :
222 18468 : static Word16 get_panning_tangent_gain(
223 : const Word16 sinAngleMapped )
224 : {
225 18468 : Word16 tbl_len = sizeof( ivas_sine_panning_tbl_fx ) / sizeof( ivas_sine_panning_tbl_fx[0] ); // Not using BASOP because size can be calculted at compile-time.
226 18468 : move16();
227 18468 : Word16 idx = shr( tbl_len, 1 ); /*Q0*/
228 18468 : move16();
229 18468 : const Word16 *ptr_sin = &ivas_sine_panning_tbl_fx[0]; /*Q15*/
230 18468 : const Word16 *ptr_tan = &ivas_tan_panning_gain_dirac_tbl_fx[0]; /*Q15*/
231 18468 : Word16 lim_l = 0;
232 18468 : move16();
233 18468 : Word16 lim_r = tbl_len; /*Q0*/
234 18468 : move16();
235 : WHILE( 1 )
236 : {
237 59773 : idx = shr( add( lim_l, lim_r ), 1 ); /*Q0*/
238 59773 : IF( GE_16( idx, tbl_len ) )
239 : {
240 0 : return ptr_tan[tbl_len - 1]; /*Q15*/
241 : }
242 59773 : ELSE IF( idx <= 0 )
243 : {
244 0 : return ptr_tan[0]; /*Q15*/
245 : }
246 59773 : ELSE IF( LE_16( sinAngleMapped, ptr_sin[idx + 1] ) && GE_16( sinAngleMapped, ptr_sin[idx] ) )
247 : {
248 18468 : IF( EQ_16( sinAngleMapped, ptr_sin[idx + 1] ) )
249 : {
250 1420 : return ptr_tan[idx + 1]; /*Q15*/
251 : }
252 17048 : ELSE IF( EQ_16( sinAngleMapped, ptr_sin[idx] ) )
253 : {
254 14700 : return ptr_tan[idx]; /*Q15*/
255 : }
256 : ELSE
257 : {
258 2348 : Word16 mid = add( shr( ptr_sin[idx], 1 ), shr( ptr_sin[idx + 1], 1 ) );
259 2348 : move16();
260 2348 : IF( LE_16( sinAngleMapped, mid ) )
261 : {
262 574 : return ptr_tan[idx]; /*Q15*/
263 : }
264 : ELSE
265 : {
266 1774 : return ptr_tan[idx + 1]; /*Q15*/
267 : }
268 : }
269 : }
270 41305 : ELSE IF( GT_16( sinAngleMapped, ptr_sin[idx] ) )
271 : {
272 18339 : lim_l = add( idx, 1 ); /*Q0*/
273 : }
274 22966 : ELSE IF( LT_16( sinAngleMapped, ptr_sin[idx] ) )
275 : {
276 22966 : lim_r = sub( idx, 1 ); /*Q0*/
277 : }
278 : }
279 : assert( "should not be reached, added to avoid issues with WMC tool instrumentation" );
280 : return 0; /* should not be reached, added to avoid issues with WMC tool instrumentation */
281 : }
282 :
283 23600 : static Word16 get_panning(
284 : const Word16 aziDeg, /*Q0*/
285 : const Word16 eleDeg /*Q0*/
286 : )
287 : {
288 23600 : Word16 panning = 0;
289 23600 : move16();
290 23600 : Word16 azAddEl = add( aziDeg, eleDeg ); /*Q0*/
291 :
292 23600 : Word16 azSubEl = sub( aziDeg, eleDeg ); /*Q0*/
293 :
294 23600 : const Word16 *ptr_sin_az = &ivas_sin_az_fx[180];
295 32760 : WHILE( GT_16( azAddEl, 180 ) )
296 : {
297 9160 : azAddEl = sub( azAddEl, 360 ); /*Q0*/
298 : }
299 23600 : WHILE( LT_16( azAddEl, negate( 180 ) ) )
300 : {
301 0 : azAddEl = add( azAddEl, 360 ); /*Q0*/
302 : }
303 32718 : WHILE( GT_16( azSubEl, 180 ) )
304 : {
305 9118 : azSubEl = sub( azSubEl, 360 ); /*Q0*/
306 : }
307 23600 : WHILE( LT_16( azSubEl, negate( 180 ) ) )
308 : {
309 0 : azSubEl = add( azSubEl, 360 ); /*Q0*/
310 : }
311 : /*sin(az)cos(el) = 0.5 * (sin(az + el) + sin(az - el)) */
312 23600 : Word16 sin_az_cos_el = add( shr( ptr_sin_az[azAddEl], 1 ), shr( ptr_sin_az[azSubEl], 1 ) ); /*Q15*/
313 23600 : move16();
314 23600 : IF( GE_32( sin_az_cos_el, SIN_30_DEGREES_Q15 ) )
315 : { /* Left side */
316 563 : panning = (Word16) 0x7fff; /*Q15*/
317 563 : move16();
318 : }
319 23037 : ELSE IF( LE_32( sin_az_cos_el, SIN_NEG_30_DEGREES_Q15 ) )
320 : { /* Right side */
321 4569 : panning = (Word16) 0x8000; /*Q15*/
322 4569 : move16();
323 : }
324 : ELSE
325 : { /* Tangent panning law */
326 18468 : panning = get_panning_tangent_gain( sin_az_cos_el ); /*Q15*/
327 : }
328 23600 : return panning; /*Q15*/
329 : }
330 :
331 :
332 : /*-------------------------------------------------------------------*
333 : * map_params_dirac_to_stereo()
334 : *
335 : * Compute DFT Stereo parameters from DirAC parameters
336 : *-------------------------------------------------------------------*/
337 :
338 10790 : static void map_params_dirac_to_stereo(
339 : STEREO_DFT_DEC_DATA_HANDLE hStereoDft, /* i/o: decoder DFT stereo handle */
340 : const IVAS_QMETADATA_HANDLE hQMetaData, /* i : frame of MASA q_metadata */
341 : Word32 synth[], /* i : decoded downmix signal q_synth*/
342 : Word32 DFT[STEREO_DFT_BUF_MAX], /* i/o: DFT buffer hStereoDft->q_dft*/
343 : const UWord8 b_wide_panning, /* i : flag indicating wider panning Q0*/
344 : const Word16 L_frame, /* i : core signal length Q0*/
345 : const Word16 mcmasa, /* i : McMASA flag Q0*/
346 : const Word16 q_synth )
347 : {
348 : Word16 i, b, k;
349 : Word16 k_offset;
350 : Word16 nbands, nBlocks;
351 : Word16 block;
352 : Word16 block_len;
353 : Word16 azimuth[MAX_PARAM_SPATIAL_SUBFRAMES][SBA_DIRAC_STEREO_NUM_BANDS];
354 : Word16 elevation[MAX_PARAM_SPATIAL_SUBFRAMES][SBA_DIRAC_STEREO_NUM_BANDS];
355 : Word32 diffuseness[SBA_DIRAC_STEREO_NUM_BANDS];
356 : Word32 block_nrg[MAX_PARAM_SPATIAL_SUBFRAMES];
357 : Word32 nrg_norm1, nrg_norm2;
358 : Word32 *pSynth;
359 : Word16 surrCoh[SBA_DIRAC_STEREO_NUM_BANDS];
360 : Word32 *pDFT;
361 : Word32 subframe_band_nrg[NB_DIV][SBA_DIRAC_STEREO_NUM_BANDS];
362 : Word16 q_nrg;
363 : Word32 smooth_long_avg[NB_DIV][SBA_DIRAC_STEREO_NUM_BANDS];
364 : Word32 smooth_short_avg[NB_DIV][SBA_DIRAC_STEREO_NUM_BANDS];
365 : Word32 *side_gain, *res_pred_gain;
366 : IVAS_QDIRECTION *q_direction;
367 : Word16 q_div, q_sqrt;
368 10790 : const Word16 *ptr_sin_az = &ivas_sin_az_fx[180]; /*Q15*/
369 10790 : const Word16 *ptr_cos_el = &ivas_sin_az_fx[270]; /*Q15*/
370 :
371 10790 : nBlocks = MAX_PARAM_SPATIAL_SUBFRAMES;
372 10790 : move16();
373 10790 : nbands = hStereoDft->nbands; /*Q15*/
374 10790 : move16();
375 10790 : k_offset = STEREO_DFT_OFFSET;
376 10790 : move16();
377 10790 : side_gain = hStereoDft->side_gain_fx + i_mult( k_offset, STEREO_DFT_BAND_MAX ); /*Q31*/
378 10790 : res_pred_gain = hStereoDft->res_pred_gain_fx + i_mult( k_offset, STEREO_DFT_BAND_MAX ); /*Q31*/
379 10790 : q_direction = &( hQMetaData->q_direction[0] );
380 :
381 : /* gain smoothing factor */
382 10790 : pDFT = DFT; /*q_dft*/
383 10790 : q_nrg = hStereoDft->q_dft;
384 10790 : move16();
385 32370 : FOR( k = 0; k < NB_DIV; k++ )
386 : {
387 252020 : FOR( b = 0; b < hStereoDft->nbands; b++ )
388 : {
389 230440 : Word64 tmp64 = 0;
390 : /* calculate band-wise subframe energies */
391 230440 : subframe_band_nrg[k][b] = 0;
392 230440 : move32();
393 8637660 : FOR( i = hStereoDft->band_limits[b]; i < hStereoDft->band_limits[b + 1]; i++ )
394 : {
395 8407220 : tmp64 = W_add( tmp64, W_add( W_mult0_32_32( pDFT[2 * i], pDFT[2 * i] ),
396 8407220 : W_mult0_32_32( pDFT[( 2 * i + 1 )], pDFT[( 2 * i + 1 )] ) ) ); /* 2*q_nrg */
397 8407220 : move64();
398 : }
399 230440 : subframe_band_nrg[k][b] = W_extract_h( W_shl( tmp64, 1 ) ); /* 2*q_nrg-31 */
400 230440 : move32();
401 230440 : q_nrg = sub( Q31, sub( shl( hStereoDft->q_dft, 1 ), Q31 ) );
402 230440 : subframe_band_nrg[k][b] = Sqrt32( subframe_band_nrg[k][b], &q_nrg ); /* Q31 - q_nrg */
403 230440 : move32();
404 230440 : IF( NE_16( sub( Q31, q_nrg ), hStereoDft->q_smooth_buf_fx ) )
405 : {
406 229132 : subframe_band_nrg[k][b] = L_shl( subframe_band_nrg[k][b], sub( hStereoDft->q_smooth_buf_fx, sub( Q31, q_nrg ) ) ); /*hStereoDft->q_smooth_buf_fx*/
407 229132 : move32();
408 : }
409 230440 : hStereoDft->smooth_buf_fx[b][NB_DIV - 1 - k] = subframe_band_nrg[k][b]; /*hStereoDft->q_smooth_buf_fx*/
410 230440 : move32();
411 :
412 : /* calculate short and long energy averages */
413 230440 : smooth_short_avg[k][b] = EPSILON_FIX;
414 230440 : move32();
415 230440 : smooth_long_avg[k][b] = 0;
416 230440 : move32();
417 : /* Multiplying and adding avoids overflow */
418 921760 : FOR( i = ( ( NB_DIV - 1 ) - k ); i < ( ( ( SBA_DIRAC_NRG_SMOOTH_SHORT + NB_DIV ) - 1 ) - k ); i++ )
419 : {
420 691320 : smooth_short_avg[k][b] = Madd_32_16( smooth_short_avg[k][b], hStereoDft->smooth_buf_fx[b][i], (Word16) 0x2AAB ); /* 1/ 3 in Q15*/ /*hStereoDft->q_smooth_buf_fx*/
421 691320 : move32();
422 691320 : smooth_long_avg[k][b] = Madd_32_16( smooth_long_avg[k][b], hStereoDft->smooth_buf_fx[b][i], (Word16) 0x0CCD ); /* 1/ 10 in Q15*/ /*hStereoDft->q_smooth_buf_fx*/
423 691320 : move32();
424 : }
425 :
426 1843520 : FOR( i = ( ( ( NB_DIV - 1 ) + SBA_DIRAC_NRG_SMOOTH_SHORT ) - k ); i < ( ( ( SBA_DIRAC_NRG_SMOOTH_LONG + NB_DIV ) - 1 ) - k ); i++ )
427 : {
428 1613080 : smooth_long_avg[k][b] = Madd_32_16( smooth_long_avg[k][b], hStereoDft->smooth_buf_fx[b][i], (Word16) 0x0CCD ); /* 1/ 10 in Q15*/ /*hStereoDft->q_smooth_buf_fx*/
429 1613080 : move32();
430 : }
431 :
432 : /* calculate smoothing factor based on energy averages */
433 : /* reduce factor for higher short-term energy */
434 230440 : IF( smooth_long_avg[k][b] )
435 : {
436 225154 : hStereoDft->smooth_fac_fx[k][b] = extract_l( s_min( MAX_16, BASOP_Util_Divide3232_Scale( smooth_long_avg[k][b], smooth_short_avg[k][b], &q_div ) ) ); /*15 - q_div*/
437 225154 : move32();
438 225154 : IF( GT_16( q_div, norm_s( hStereoDft->smooth_fac_fx[k][b] ) ) )
439 : {
440 120070 : hStereoDft->smooth_fac_fx[k][b] = MAX_16; /*Q15*/
441 120070 : move32();
442 : }
443 : ELSE
444 : {
445 105084 : hStereoDft->smooth_fac_fx[k][b] = shl( hStereoDft->smooth_fac_fx[k][b], q_div ); /*Q15*/
446 105084 : move32();
447 105084 : q_div = 0;
448 105084 : move16();
449 : }
450 : }
451 : ELSE
452 : {
453 5286 : hStereoDft->smooth_fac_fx[k][b] = 0;
454 5286 : move32();
455 : }
456 :
457 : /* map factor to range [0;1] */
458 230440 : hStereoDft->smooth_fac_fx[k][b] = s_max( 0, extract_l( L_shr( Mpy_32_16_1( SBA_DIRAC_NRG_SMOOTH_LONG_BY_LONG_SHORT_FX, sub( hStereoDft->smooth_fac_fx[k][b], SBA_DIRAC_NRG_SMOOTH_SHORT_BY_LONG_FX ) ), Q15 ) ) ); /*Q15*/
459 230440 : move16();
460 : /* compress factor (higher compression in lowest bands) */
461 230440 : q_sqrt = 0;
462 230440 : move16();
463 230440 : IF( LT_16( b, 2 ) )
464 : {
465 43160 : Word16 tmp_val = Sqrt16( hStereoDft->smooth_fac_fx[k][b], &q_sqrt );
466 43160 : hStereoDft->smooth_fac_fx[k][b] = Sqrt16( tmp_val, &q_sqrt ); /*q_sqrt*/
467 43160 : move16();
468 : }
469 : ELSE
470 : {
471 187280 : hStereoDft->smooth_fac_fx[k][b] = Sqrt16( hStereoDft->smooth_fac_fx[k][b], &q_sqrt ); /*q_sqrt*/
472 187280 : move16();
473 : }
474 230440 : hStereoDft->smooth_fac_fx[k][b] = shl( hStereoDft->smooth_fac_fx[k][b], q_sqrt ); /*q_sqrt*/
475 230440 : move16();
476 :
477 : /* apply upper bounds depending on band */
478 230440 : hStereoDft->smooth_fac_fx[0][b] = s_max( hStereoDft->min_smooth_gains_fx[b], s_min( hStereoDft->max_smooth_gains_fx[b], hStereoDft->smooth_fac_fx[0][b] ) ); /*Q15*/
479 230440 : move16();
480 230440 : hStereoDft->smooth_fac_fx[1][b] = s_max( hStereoDft->min_smooth_gains_fx[b], s_min( hStereoDft->max_smooth_gains_fx[b], hStereoDft->smooth_fac_fx[1][b] ) ); /*Q15*/
481 230440 : move16();
482 : }
483 21580 : pDFT += STEREO_DFT32MS_N_MAX;
484 : }
485 :
486 10790 : IF( mcmasa )
487 : {
488 : Word16 q_div1;
489 : /* calculate block energies for side gain weighting (combine angles of 2 DirAC blocks to side gain for 1 DFT Stereo subframe; 4 blocks and 2 subframes overall) */
490 1180 : pSynth = synth; /*q_synth*/
491 1180 : block_len = idiv1616( L_frame, nBlocks ); /*Q0*/
492 5900 : FOR( block = 0; block < nBlocks; block++ )
493 : {
494 4720 : block_nrg[block] = 0;
495 4720 : move32();
496 382320 : FOR( i = 0; i < block_len; i++ )
497 : {
498 377600 : block_nrg[block] = Madd_32_32( block_nrg[block], pSynth[i], pSynth[i] ); /*2*q_synth-31*/
499 377600 : move32();
500 : }
501 4720 : q_nrg = sub( Q31, sub( shl( q_synth, 1 ), Q31 ) );
502 4720 : block_nrg[block] = Sqrt32( block_nrg[block], &q_nrg ); /*Q31 - q_nrg*/
503 4720 : move32();
504 4720 : IF( NE_16( sub( Q31, q_nrg ), q_synth ) )
505 : {
506 4718 : block_nrg[block] = L_shl( block_nrg[block], sub( q_synth, sub( Q31, q_nrg ) ) ); /*q_synth*/
507 4718 : move32();
508 : }
509 4720 : pSynth += block_len;
510 : }
511 :
512 1180 : nrg_norm1 = L_add( block_nrg[0], L_add( block_nrg[1], EPSILON_FIX ) ); /*Q31 - q_nrg*/
513 1180 : nrg_norm2 = L_add( block_nrg[2], L_add( block_nrg[3], EPSILON_FIX ) ); /*Q31 - q_nrg*/
514 :
515 : /* extract DirAC parameters from metadata */
516 7080 : FOR( b = 0; b < nbands; b++ )
517 : {
518 5900 : diffuseness[b] = L_shl( L_sub( ONE_IN_Q30, q_direction->band_data[b].energy_ratio_fx[0] ), 1 ); /*Q31*/
519 5900 : move32();
520 5900 : IF( hQMetaData->surcoh_band_data != NULL )
521 : {
522 5900 : surrCoh[b] = extract_h( imult3216( (Word32) 0x00808080 /*1/255.0f in Q31*/, hQMetaData->surcoh_band_data[b].surround_coherence[0] ) ); /*Q15*/
523 5900 : move32();
524 : }
525 : ELSE
526 : {
527 0 : surrCoh[b] = 0;
528 0 : move32();
529 : }
530 :
531 29500 : FOR( block = 0; block < nBlocks; block++ )
532 : {
533 : Word16 block_metadata;
534 :
535 23600 : IF( hQMetaData->useLowerRes )
536 : {
537 0 : block_metadata = 0;
538 0 : move16();
539 : }
540 : ELSE
541 : {
542 23600 : block_metadata = block;
543 23600 : move16();
544 : }
545 23600 : IF( q_direction->band_data[b].azimuth_fx[block_metadata] < 0 )
546 : {
547 9146 : q_direction->band_data[b].azimuth_fx[block_metadata] = L_add( (Word32) 0x5A000000 /*360.f in Q22*/, q_direction->band_data[b].azimuth_fx[block_metadata] ); /*Q22*/
548 9146 : move16();
549 : }
550 : /*
551 : * Converting Azimuth and elevation to Q0 as the ensuing blocks expect them in Q0.
552 : * Before converting rounding is done.
553 : */
554 :
555 23600 : azimuth[block][b] = extract_l( L_shr( L_add( q_direction->band_data[b].azimuth_fx[block_metadata], ONE_IN_Q21 ), Q22 ) ); /*Q0*/
556 23600 : move16();
557 23600 : elevation[block][b] = extract_l( L_shr( L_add( q_direction->band_data[b].elevation_fx[block_metadata], ONE_IN_Q21 ), Q22 ) ); /*Q0*/
558 23600 : move16();
559 : }
560 : }
561 :
562 : /* map angles (azi, ele), surround coherence, and diffuseness to DFT Stereo side and prediction gains */
563 7080 : FOR( b = 0; b < hStereoDft->nbands; b++ )
564 : {
565 : /* combine angles of first 2 blocks to side gain of first subframe */
566 5900 : side_gain[b] = 0;
567 5900 : move32();
568 17700 : FOR( block = 0; block < ( nBlocks / 2 ); block++ )
569 : {
570 : /*
571 : * The floating point version of the code computes
572 : * nrg_norm1 = 1 / (block_nrg[0] + block_nrg[1]); and then computes
573 : * block_nrg[0] * nrg_norm1; which effectively is block_nrg[0] / (block_nrg[0] + block_nrg[1]);
574 : */
575 11800 : IF( EQ_16( b_wide_panning, 1 ) )
576 : {
577 11800 : Word32 temp = L_mult( BASOP_Util_Divide3232_Scale( block_nrg[block], nrg_norm1, &q_div1 ), get_panning( azimuth[block][b], elevation[block][b] ) ); /*Q31 - q_div1*/
578 11800 : IF( q_div1 )
579 : {
580 3110 : temp = L_shl_sat( temp, q_div1 ); /*Q31*/
581 : }
582 : /* panning between left and ride, saturate at the stereo ls positions (+/- 30deg azi) */
583 11800 : side_gain[b] = L_add_sat( side_gain[b], temp ); /*Q31*/
584 11800 : move32();
585 : }
586 : ELSE
587 : {
588 0 : Word32 temp = L_mult( BASOP_Util_Divide3232_Scale( block_nrg[block], nrg_norm1, &q_div1 ), mult( ptr_sin_az[azimuth[block][b]], ptr_cos_el[elevation[block][b]] ) ); /*Q31 - q_div1*/
589 0 : IF( q_div1 )
590 : {
591 0 : temp = L_shl_sat( temp, q_div1 ); /*Q31*/
592 : }
593 0 : side_gain[b] = L_add_sat( side_gain[b], temp ); /*Q31*/
594 0 : move32();
595 : }
596 : }
597 :
598 : /* combine angles of last 2 blocks to side gain of second subframe */
599 5900 : side_gain[b + STEREO_DFT_BAND_MAX] = 0;
600 5900 : move32();
601 17700 : FOR( block = shr( nBlocks, 1 ); block < nBlocks; block++ )
602 : {
603 11800 : IF( EQ_16( b_wide_panning, 1 ) )
604 : {
605 11800 : Word32 temp = L_mult( BASOP_Util_Divide3232_Scale( block_nrg[block], nrg_norm2, &q_div1 ), get_panning( azimuth[block][b], elevation[block][b] ) ); /*Q31 - q_div1*/
606 11800 : IF( q_div1 )
607 : {
608 3185 : temp = L_shl_sat( temp, q_div1 ); /*Q31*/
609 : }
610 : /* panning between left and ride, saturate at the stereo ls positions (+/- 30deg azi) */
611 11800 : side_gain[b + STEREO_DFT_BAND_MAX] = L_add_sat( side_gain[b + STEREO_DFT_BAND_MAX], temp ); /*Q31*/
612 11800 : move32();
613 : }
614 : ELSE
615 : {
616 0 : Word32 temp = L_mult( BASOP_Util_Divide3232_Scale( block_nrg[block], nrg_norm2, &q_div1 ), mult( ptr_sin_az[azimuth[block][b]], ptr_cos_el[elevation[block][b]] ) ); /*Q31 - q_div1*/
617 0 : IF( q_div1 )
618 : {
619 0 : temp = L_shl_sat( temp, q_div1 ); /*Q31*/
620 : }
621 0 : side_gain[b + STEREO_DFT_BAND_MAX] = L_add_sat( side_gain[b + STEREO_DFT_BAND_MAX], temp ); /*Q31*/
622 0 : move32();
623 : }
624 : }
625 : /* Clamp values here. [-1, 1] is the allowed range, but due to precision issues they can be slightly off which can cause problems later. */
626 : /* In Q31, this clamping happens implicitly */
627 5900 : q_sqrt = 0;
628 5900 : move16();
629 5900 : side_gain[b] = Mpy_32_32( side_gain[b], Sqrt32( L_sub( MAX_32, diffuseness[b] ), &q_sqrt ) ); /*Q31 - q_sqrt*/
630 5900 : move32();
631 5900 : IF( q_sqrt )
632 : {
633 2292 : side_gain[b] = L_shl( side_gain[b], q_sqrt ); /*Q31*/
634 2292 : q_sqrt = 0;
635 2292 : move16();
636 : }
637 5900 : side_gain[b + STEREO_DFT_BAND_MAX] = Mpy_32_32( side_gain[b + STEREO_DFT_BAND_MAX], Sqrt32( L_sub( MAX_32, diffuseness[b] ), &q_sqrt ) ); /*Q31 - q_sqrt*/
638 5900 : move32();
639 5900 : IF( q_sqrt )
640 : {
641 2292 : side_gain[b + STEREO_DFT_BAND_MAX] = L_shl( side_gain[b], q_sqrt ); /*Q31*/
642 2292 : q_sqrt = 0;
643 2292 : move16();
644 : }
645 : /* for residual prediction gain, allowed range is [0, 1]*/
646 5900 : res_pred_gain[b] = L_max( Mpy_32_16_1( diffuseness[b], sub( MAX_16, surrCoh[b] ) ), 0 ); /*Q31*/
647 5900 : move32();
648 5900 : res_pred_gain[b + STEREO_DFT_BAND_MAX] = L_max( Mpy_32_16_1( diffuseness[b], sub( MAX_16, surrCoh[b] ) ), 0 ); /*Q31*/
649 5900 : move32();
650 : }
651 : }
652 :
653 10790 : hStereoDft->frame_nodata = 0;
654 10790 : move16();
655 10790 : hStereoDft->frame_sid_nodata = 0;
656 10790 : move16();
657 10790 : hStereoDft->frame_sid = 0;
658 10790 : move16();
659 :
660 10790 : return;
661 : }
662 :
663 :
664 : /*-------------------------------------------------------------------*
665 : * ivas_sba_dirac_stereo_compute_td_stefi_nrgs()
666 : *
667 : * Compute energies for TD stereo filling
668 : *-------------------------------------------------------------------*/
669 :
670 4511 : static void ivas_sba_dirac_stereo_compute_td_stefi_nrgs(
671 : STEREO_DFT_DEC_DATA_HANDLE hStereoDft, /* i/o: decoder DFT stereo handle */
672 : const Word32 hb_synth[L_FRAME48k], /* i : HB signal q_hb_synth*/
673 : const Word16 core, /* i : core decision Q0*/
674 : const Word16 output_frame, /* i : output frame length per channel Q0*/
675 : const Word16 fd_cng_flag, /* i : FD-CNG indicator Q0*/
676 : const Word16 q_hb_synth )
677 : {
678 : Word16 i;
679 4511 : Word32 hb_nrg = EPSILON_FIX;
680 4511 : move32();
681 4511 : Word32 hb_nrg2 = EPSILON_FIX;
682 4511 : move32();
683 :
684 4511 : test();
685 4511 : test();
686 4511 : IF( ( EQ_16( core, ACELP_CORE ) && !fd_cng_flag ) || EQ_16( hStereoDft->core_hist[1], ACELP_CORE ) )
687 : {
688 418739 : FOR( i = 0; i < shr( output_frame, 2 ); i++ )
689 : {
690 416560 : hb_nrg2 = Madd_32_32( hb_nrg2, hb_synth[i], hb_synth[i] ); /*2*q_hb_synth-31*/
691 : }
692 :
693 2179 : hStereoDft->hb_nrg_subr_fx[0] = hb_nrg2; /*2*q_hb_synth-31*/
694 2179 : move32();
695 2179 : hStereoDft->q_hb_nrg_subr = sub( shl( q_hb_synth, 1 ), 31 );
696 2179 : move32();
697 2179 : hb_nrg = L_add( hb_nrg, hb_nrg2 );
698 2179 : move32();
699 2179 : hb_nrg2 = EPSILON_FIX;
700 2179 : move32();
701 :
702 1251859 : FOR( ; i < output_frame; i++ )
703 : {
704 1249680 : hb_nrg2 = Madd_32_32( hb_nrg2, hb_synth[i], hb_synth[i] ); /*2*q_hb_synth-31*/
705 : }
706 :
707 2179 : hStereoDft->hb_nrg_subr_fx[1] = hb_nrg2; /*2*q_hb_synth-31*/
708 2179 : move32();
709 2179 : hb_nrg = L_add( hb_nrg, hb_nrg2 );
710 :
711 2179 : IF( EQ_16( hStereoDft->q_hb_stefi_sig_fx, q_hb_synth ) )
712 : {
713 431 : Copy32( hb_synth, hStereoDft->hb_stefi_sig_fx + hStereoDft->hb_stefi_delay, output_frame ); /*q_hb_synth*/
714 : }
715 : ELSE
716 : {
717 1748 : IF( GT_16( hStereoDft->q_hb_stefi_sig_fx, q_hb_synth ) )
718 : {
719 172 : v_shr( hStereoDft->hb_stefi_sig_fx, sub( hStereoDft->q_hb_stefi_sig_fx, q_hb_synth ), hStereoDft->hb_stefi_sig_fx, idiv1616( sizeof( hStereoDft->hb_stefi_sig_fx ), sizeof( hStereoDft->hb_stefi_sig_fx[0] ) ) ); /*q_hb_synth*/
720 172 : hStereoDft->q_hb_stefi_sig_fx = q_hb_synth;
721 172 : move16();
722 172 : Copy32( hb_synth, hStereoDft->hb_stefi_sig_fx + hStereoDft->hb_stefi_delay, output_frame ); /*q_hb_synth*/
723 : }
724 : ELSE
725 : {
726 1576 : v_shr( hb_synth, sub( q_hb_synth, hStereoDft->q_hb_stefi_sig_fx ), hStereoDft->hb_stefi_sig_fx + hStereoDft->hb_stefi_delay, output_frame ); /*hStereoDft->q_hb_stefi_sig_fx*/
727 : }
728 : }
729 : }
730 : ELSE
731 : {
732 2332 : set32_fx( hStereoDft->hb_stefi_sig_fx + hStereoDft->hb_stefi_delay, 0, output_frame );
733 2332 : hStereoDft->hb_nrg_subr_fx[0] = 0;
734 2332 : move32();
735 2332 : hStereoDft->hb_nrg_subr_fx[1] = 0;
736 2332 : move32();
737 : }
738 4511 : hStereoDft->hb_nrg_subr_fx[0] = hStereoDft->hb_nrg_subr_fx[0]; // imult3216(hStereoDft->hb_nrg_subr_fx[0] , shr(hStereoDft->NFFT, 1)); /*hStereoDft->q_hb_nrg_subr*/
739 4511 : move32();
740 4511 : hStereoDft->hb_nrg_subr_fx[1] = hStereoDft->hb_nrg_subr_fx[1]; // imult3216(hStereoDft->hb_nrg_subr_fx[1] , shr(hStereoDft->NFFT, 1)); /*hStereoDft->q_hb_nrg_subr*/
741 4511 : move32();
742 4511 : hStereoDft->hb_nrg_fx[0] = hb_nrg;
743 4511 : move32();
744 4511 : hStereoDft->td_gain_fx[0] = 0;
745 4511 : move32();
746 4511 : hStereoDft->core_hist[0] = core; /* full signal available for DTX with FD-CNG, thus apply stereo filling on full spectrum like in TCX */
747 4511 : move16();
748 :
749 4511 : if ( fd_cng_flag )
750 : {
751 19 : hStereoDft->core_hist[0] = TCX_20_CORE;
752 19 : move16();
753 : }
754 4511 : return;
755 : }
756 :
757 :
758 : /*-------------------------------------------------------------------*
759 : * ivas_sba_dirac_stereo_compute_hb_gain()
760 : *
761 : * Compute HB gains
762 : *-------------------------------------------------------------------*/
763 :
764 2017 : static void ivas_sba_dirac_stereo_compute_hb_gain(
765 : STEREO_DFT_DEC_DATA_HANDLE hStereoDft, /* i/o: decoder DFT stereo handle */
766 : Word32 hb_gain[NB_DIV] /* o : side gains for HB signal Q31*/
767 : )
768 : {
769 : Word16 k_offset;
770 :
771 2017 : k_offset = STEREO_DFT_OFFSET;
772 2017 : move16();
773 :
774 : /* last band covers whole HB range, no averaging needed */
775 2017 : hb_gain[0] = hStereoDft->side_gain_fx[( ( ( k_offset * STEREO_DFT_BAND_MAX ) + hStereoDft->nbands ) - 1 )]; /*Q31*/
776 2017 : move32();
777 2017 : hb_gain[1] = hStereoDft->side_gain_fx[( ( ( ( k_offset + 1 ) * STEREO_DFT_BAND_MAX ) + hStereoDft->nbands ) - 1 )]; /*Q31*/
778 2017 : move32();
779 :
780 2017 : return;
781 : }
782 :
783 :
784 : /*-------------------------------------------------------------------*
785 : * ivas_sba_dirac_stereo_upmix_hb()
786 : *
787 : * Apply panning to HB signal
788 : *-------------------------------------------------------------------*/
789 :
790 2017 : static void ivas_sba_dirac_stereo_upmix_hb(
791 : Word32 hb_stereo_synth[CPE_CHANNELS][L_FRAME48k], /* i/o: stereo HB synthesis signal Qx*/
792 : Word32 hb_synth[L_FRAME48k], /* i : HB signal Qx*/
793 : Word32 hb_gain[NB_DIV], /* i : side gains for HB signal Q31*/
794 : const Word16 output_frame, /* i : output frame length per channel Q0*/
795 : const Word16 mcmasa, /* i : McMASA flag Q0*/
796 : const Word16 sba_mono_flag, /* i : flag for mono output Q0*/
797 : const Word16 bwidth, /* i : bandwidth of signal Q0*/
798 : const STEREO_DFT_DEC_DATA_HANDLE hStereoDft /* i : Stereo DFT handle for mixing matrix */
799 : )
800 : {
801 : Word16 i;
802 : Word32 gp, gm;
803 : Word16 gain_fac;
804 :
805 2017 : IF( !mcmasa )
806 : {
807 1652 : gain_fac = (Word32) 0x2A3D; /* last matrix element not used for SWB, divide by 3 instead of 4*/ /*Q15*/
808 1652 : move16();
809 1652 : if ( EQ_16( bwidth, FB ) )
810 : {
811 50 : gain_fac = (Word32) 0x2000; /*Q15*/
812 50 : move16();
813 : }
814 :
815 1652 : IF( sba_mono_flag )
816 : {
817 203 : gp = L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[0][0][8], gain_fac ),
818 : Madd_32_16( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[0][0][9], gain_fac ),
819 : hStereoDft->mixer_mat_smooth_fx[0][0][10], gain_fac ) ); /*Q31*/
820 203 : IF( EQ_16( bwidth, FB ) )
821 : {
822 18 : gp = Madd_32_16( gp, hStereoDft->mixer_mat_smooth_fx[0][0][11], gain_fac ); /*Q31*/
823 : }
824 :
825 97643 : FOR( i = 0; i < shr( output_frame, 1 ); i++ )
826 : {
827 97440 : hb_stereo_synth[0][i] = Mpy_32_32( hb_synth[i], gp ); /*Qx*/
828 97440 : move32();
829 : }
830 :
831 203 : gp = L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[0][0][8 + IVAS_MAX_NUM_BANDS], gain_fac ),
832 : Madd_32_16( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[0][0][9 + IVAS_MAX_NUM_BANDS], gain_fac ),
833 : hStereoDft->mixer_mat_smooth_fx[0][0][10 + IVAS_MAX_NUM_BANDS], gain_fac ) ); /*Q31*/
834 203 : IF( EQ_16( bwidth, FB ) )
835 : {
836 18 : gp = Madd_32_16( gp, hStereoDft->mixer_mat_smooth_fx[0][0][11 + IVAS_MAX_NUM_BANDS], gain_fac ); /*Q31*/
837 : }
838 :
839 97643 : FOR( i = shr( output_frame, 1 ); i < output_frame; i++ )
840 : {
841 97440 : hb_stereo_synth[0][i] = Mpy_32_32( hb_synth[i], gp ); /*Qx*/
842 97440 : move32();
843 : }
844 : }
845 : ELSE
846 : {
847 : /* Accounting for the 0.5 multiplication */
848 1449 : gain_fac = shr( gain_fac, 1 ); /*Q15*/
849 1449 : gp = L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[0][0][8], gain_fac ),
850 : L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[1][0][8], gain_fac ),
851 : L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[0][0][9], gain_fac ),
852 : L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[1][0][9], gain_fac ),
853 : L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[0][0][10], gain_fac ),
854 : Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[1][0][10], gain_fac ) ) ) ) ) ); /*Q31*/
855 1449 : IF( EQ_32( bwidth, FB ) )
856 : {
857 32 : gp = L_add( gp, Madd_32_16( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[0][0][11], gain_fac ),
858 : hStereoDft->mixer_mat_smooth_fx[1][0][11], gain_fac ) ); /*Q31*/
859 : }
860 :
861 1449 : gm = L_add( Msub_32_16( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[0][0][8], gain_fac ),
862 : hStereoDft->mixer_mat_smooth_fx[1][0][8], gain_fac ),
863 : L_add( Msub_32_16( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[0][0][9], gain_fac ),
864 : hStereoDft->mixer_mat_smooth_fx[1][0][9], gain_fac ),
865 : Msub_32_16( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[0][0][10], gain_fac ),
866 : hStereoDft->mixer_mat_smooth_fx[1][0][10], gain_fac ) ) ); /*Q31*/
867 1449 : IF( EQ_32( bwidth, FB ) )
868 : {
869 32 : gm = L_add( gm, Msub_32_16( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[0][0][11], gain_fac ),
870 : hStereoDft->mixer_mat_smooth_fx[1][0][11], gain_fac ) ); /*Q31*/
871 : }
872 :
873 496969 : FOR( i = 0; i < shr( output_frame, 1 ); i++ )
874 : {
875 495520 : hb_stereo_synth[0][i] = Mpy_32_32( hb_synth[i], gp ); /*Qx*/
876 495520 : move32();
877 495520 : hb_stereo_synth[1][i] = Mpy_32_32( hb_synth[i], gm ); /*Qx*/
878 495520 : move32();
879 : }
880 :
881 1449 : gp = L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[0][0][8 + IVAS_MAX_NUM_BANDS], gain_fac ),
882 : L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[1][0][8 + IVAS_MAX_NUM_BANDS], gain_fac ),
883 : L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[0][0][9 + IVAS_MAX_NUM_BANDS], gain_fac ),
884 : L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[1][0][9 + IVAS_MAX_NUM_BANDS], gain_fac ),
885 : Madd_32_16( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[0][0][10 + IVAS_MAX_NUM_BANDS], gain_fac ),
886 : hStereoDft->mixer_mat_smooth_fx[1][0][10 + IVAS_MAX_NUM_BANDS], gain_fac ) ) ) ) ); /*Q31*/
887 1449 : IF( EQ_32( bwidth, FB ) )
888 : {
889 32 : gp = L_add( gp, Madd_32_16( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[0][0][11 + IVAS_MAX_NUM_BANDS], gain_fac ), hStereoDft->mixer_mat_smooth_fx[1][0][11 + IVAS_MAX_NUM_BANDS], gain_fac ) ); /*Q31*/
890 : }
891 :
892 1449 : gm = L_add( Msub_32_16( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[0][0][8 + IVAS_MAX_NUM_BANDS], gain_fac ), hStereoDft->mixer_mat_smooth_fx[1][0][8 + IVAS_MAX_NUM_BANDS], gain_fac ),
893 : L_add( Msub_32_16( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[0][0][9 + IVAS_MAX_NUM_BANDS], gain_fac ), hStereoDft->mixer_mat_smooth_fx[1][0][9 + IVAS_MAX_NUM_BANDS], gain_fac ),
894 : Msub_32_16( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[0][0][10 + IVAS_MAX_NUM_BANDS], gain_fac ), hStereoDft->mixer_mat_smooth_fx[1][0][10 + IVAS_MAX_NUM_BANDS], gain_fac ) ) ); /*Q31*/
895 1449 : IF( EQ_32( bwidth, FB ) )
896 : {
897 32 : gm = L_add( gm, Msub_32_16( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[0][0][11 + IVAS_MAX_NUM_BANDS], gain_fac ), hStereoDft->mixer_mat_smooth_fx[1][0][11 + IVAS_MAX_NUM_BANDS], gain_fac ) ); /*Q31*/
898 : }
899 :
900 496969 : FOR( i = shr( output_frame, 1 ); i < output_frame; i++ )
901 : {
902 495520 : hb_stereo_synth[0][i] = Mpy_32_32( hb_synth[i], gp ); /*Qx*/
903 495520 : move32();
904 495520 : hb_stereo_synth[1][i] = Mpy_32_32( hb_synth[i], gm ); /*Qx*/
905 495520 : move32();
906 : }
907 : }
908 : }
909 : ELSE
910 : {
911 174605 : FOR( i = 0; i < L_shr( output_frame, 1 ); i++ )
912 : {
913 174240 : hb_stereo_synth[0][i] = L_add( L_shr( hb_synth[i], 1 ), L_shr( Mpy_32_32( hb_gain[0], hb_synth[i] ), 1 ) ); /*Qx*/
914 174240 : move32();
915 174240 : hb_stereo_synth[1][i] = L_sub( L_shr( hb_synth[i], 1 ), L_shr( Mpy_32_32( hb_gain[0], hb_synth[i] ), 1 ) ); /*Qx*/
916 174240 : move32();
917 : }
918 :
919 174605 : FOR( i = shr( output_frame, 1 ); i < output_frame; i++ )
920 : {
921 174240 : hb_stereo_synth[0][i] = L_add( L_shr( hb_synth[i], 1 ), L_shr( Mpy_32_32( hb_gain[1], hb_synth[i] ), 1 ) ); /*Qx*/
922 174240 : move32();
923 174240 : hb_stereo_synth[1][i] = L_sub( L_shr( hb_synth[i], 1 ), L_shr( Mpy_32_32( hb_gain[1], hb_synth[i] ), 1 ) ); /*Qx*/
924 174240 : move32();
925 : }
926 : }
927 :
928 2017 : return;
929 : }
930 :
931 :
932 : /*-------------------------------------------------------------------*
933 : * ivas_sba_dirac_stereo_apply_td_stefi()
934 : *
935 : * Apply TD stereo filling for ACELP HB
936 : *-------------------------------------------------------------------*/
937 :
938 1814 : static void ivas_sba_dirac_stereo_apply_td_stefi(
939 : STEREO_DFT_DEC_DATA_HANDLE hStereoDft, /* i/o: decoder DFT stereo handle */
940 : Word32 *output[CPE_CHANNELS], /* i/o: output synthesis signal hStereoDft->q_dft*/
941 : const Word16 output_frame, /* i : output frame length per channel Q0*/
942 : const Word16 spar_flag /* i : SPAR flag Q0*/
943 : )
944 : {
945 : Word16 i;
946 : Word16 dftOvlLen;
947 : Word16 win_in, win_out;
948 : Word32 tmp;
949 : const Word16 *win_dft;
950 :
951 1814 : IF( spar_flag )
952 : {
953 1449 : win_dft = hStereoDft->win32ms_fx; /*Q15*/
954 1449 : dftOvlLen = hStereoDft->dft32ms_ovl; /*Q0*/
955 :
956 : Word32 g_W_1, g_Y_1;
957 : Word32 g_W_2, g_Y_2;
958 : Word32 g_L, g_R;
959 : Word32 stefi_L, stefi_R;
960 :
961 1449 : g_W_1 = L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[0][1][8], 0x147B ),
962 : L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[0][2][8], 0x147B ),
963 : L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[0][3][8], 0x147B ),
964 : L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[0][1][9], 0x147B ),
965 : L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[0][2][9], 0x147B ),
966 : L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[0][3][9], 0x147B ),
967 : L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[0][1][10], 0x147B ),
968 : L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[0][2][10], 0x147B ),
969 : Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[0][3][10], 0x147B ) ) ) ) ) ) ) ) ); /*Q31*/
970 :
971 1449 : g_Y_1 = L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[1][1][8], 0x147B ),
972 : L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[1][2][8], 0x147B ),
973 : L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[1][3][8], 0x147B ),
974 : L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[1][1][9], 0x147B ),
975 : L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[1][2][9], 0x147B ),
976 : L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[1][3][9], 0x147B ),
977 : L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[1][1][10], 0x147B ),
978 : L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[1][2][10], 0x147B ),
979 : Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[1][3][10], 0x147B ) ) ) ) ) ) ) ) ); /*Q31*/
980 :
981 1449 : g_W_2 = L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[0][1][8 + IVAS_MAX_NUM_BANDS], 0x147B ),
982 : L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[0][2][8 + IVAS_MAX_NUM_BANDS], 0x147B ),
983 : L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[0][3][8 + IVAS_MAX_NUM_BANDS], 0x147B ),
984 : L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[0][1][9 + IVAS_MAX_NUM_BANDS], 0x147B ),
985 : L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[0][2][9 + IVAS_MAX_NUM_BANDS], 0x147B ),
986 : L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[0][3][9 + IVAS_MAX_NUM_BANDS], 0x147B ),
987 : L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[0][1][10 + IVAS_MAX_NUM_BANDS], 0x147B ),
988 : L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[0][2][10 + IVAS_MAX_NUM_BANDS], 0x147B ),
989 : Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[0][3][10 + IVAS_MAX_NUM_BANDS], 0x147B ) ) ) ) ) ) ) ) ); /*Q31*/
990 :
991 1449 : g_Y_2 = L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[1][1][8 + IVAS_MAX_NUM_BANDS], 0x147B ),
992 : L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[1][2][8 + IVAS_MAX_NUM_BANDS], 0x147B ),
993 : L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[1][3][8 + IVAS_MAX_NUM_BANDS], 0x147B ),
994 : L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[1][1][9 + IVAS_MAX_NUM_BANDS], 0x147B ),
995 : L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[1][2][9 + IVAS_MAX_NUM_BANDS], 0x147B ),
996 : L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[1][3][9 + IVAS_MAX_NUM_BANDS], 0x147B ),
997 : L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[1][1][10 + IVAS_MAX_NUM_BANDS], 0x147B ),
998 : L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[1][2][10 + IVAS_MAX_NUM_BANDS], 0x147B ),
999 : Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[1][3][10 + IVAS_MAX_NUM_BANDS], 0x147B ) ) ) ) ) ) ) ) ); /*Q31*/
1000 :
1001 1449 : g_L = L_sub( L_add( g_W_1, g_W_2 ), L_add( g_Y_1, g_Y_2 ) ); /* 0x147B = 0.16 in Q15 */ /*Q31*/
1002 1449 : g_R = L_add( L_add( g_W_1, g_W_2 ), L_add( g_Y_1, g_Y_2 ) ); /* 0x147B = 0.16 in Q15 */ /*Q31*/
1003 156299 : FOR( i = 0; i < dftOvlLen; i++ )
1004 : {
1005 154850 : win_in = mult_r( win_dft[STEREO_DFT32MS_STEP * i], win_dft[STEREO_DFT32MS_STEP * i] ); /*Q15*/
1006 154850 : win_out = sub( MAX_16, win_in ); /*Q15*/
1007 :
1008 154850 : stefi_L = L_shr( Mpy_32_32( Madd_32_16( Mpy_32_32( win_out, hStereoDft->g_L_prev_fx ), g_L, win_in ), hStereoDft->hb_stefi_sig_fx[i] ), 1 ); /*hStereoDft->q_hb_stefi_sig_fx*/
1009 154850 : stefi_R = L_shr( Mpy_32_32( Madd_32_16( Mpy_32_32( win_out, hStereoDft->g_R_prev_fx ), g_R, win_in ), hStereoDft->hb_stefi_sig_fx[i] ), 1 ); /*hStereoDft->q_hb_stefi_sig_fx*/
1010 :
1011 154850 : output[0][i] = L_add( output[0][i], L_shr( stefi_L, sub( hStereoDft->q_hb_stefi_sig_fx, hStereoDft->q_dft ) ) ); /*hStereoDft->q_dft*/
1012 154850 : move32();
1013 154850 : output[1][i] = L_add( output[1][i], L_shr( stefi_R, sub( hStereoDft->q_hb_stefi_sig_fx, hStereoDft->q_dft ) ) ); /*hStereoDft->q_dft*/
1014 154850 : move32();
1015 : }
1016 837639 : FOR( i = dftOvlLen; i < output_frame; i++ )
1017 : {
1018 :
1019 836190 : stefi_L = L_shr( Mpy_32_32( g_L, hStereoDft->hb_stefi_sig_fx[i] ), 1 ); /*hStereoDft->q_hb_stefi_sig_fx*/
1020 836190 : stefi_R = L_shr( Mpy_32_32( g_R, hStereoDft->hb_stefi_sig_fx[i] ), 1 ); /*hStereoDft->q_hb_stefi_sig_fx*/
1021 :
1022 836190 : output[0][i] = L_add( output[0][i], L_shr( stefi_L, sub( hStereoDft->q_hb_stefi_sig_fx, hStereoDft->q_dft ) ) ); /*hStereoDft->q_dft*/
1023 836190 : move32();
1024 836190 : output[1][i] = L_add( output[1][i], L_shr( stefi_R, sub( hStereoDft->q_hb_stefi_sig_fx, hStereoDft->q_dft ) ) ); /*hStereoDft->q_dft*/
1025 836190 : move32();
1026 : }
1027 1449 : hStereoDft->g_L_prev_fx = g_L; /*Q31*/
1028 1449 : move32();
1029 1449 : hStereoDft->g_R_prev_fx = g_R; /*Q31*/
1030 1449 : move32();
1031 : }
1032 365 : ELSE IF( L_max( hStereoDft->td_gain_fx[0], hStereoDft->td_gain_fx[1] ) > 0 )
1033 : {
1034 334 : win_dft = hStereoDft->win32ms_fx; /*Q15*/
1035 334 : dftOvlLen = hStereoDft->dft32ms_ovl; /*Q0*/
1036 :
1037 50384 : FOR( i = 0; i < dftOvlLen; i++ )
1038 : {
1039 50050 : win_in = mult( win_dft[STEREO_DFT32MS_STEP * i], win_dft[STEREO_DFT32MS_STEP * i] ); /*Q15*/
1040 50050 : win_out = sub( MAX_16, win_in ); /*Q15*/
1041 50050 : tmp = L_shr( Mpy_32_32( Madd_32_16( Mpy_32_16_1( hStereoDft->td_gain_fx[0], win_in ), hStereoDft->td_gain_fx[1], win_out ), hStereoDft->hb_stefi_sig_fx[i] ), 1 ); /*hStereoDft->q_hb_stefi_sig_fx*/
1042 :
1043 50050 : output[0][i] = L_add( output[0][i], L_shr( tmp, sub( hStereoDft->q_hb_stefi_sig_fx, hStereoDft->q_dft ) ) ); /*hStereoDft->q_dft*/
1044 50050 : move32();
1045 50050 : output[1][i] = L_sub( output[1][i], L_shr( tmp, sub( hStereoDft->q_hb_stefi_sig_fx, hStereoDft->q_dft ) ) ); /*hStereoDft->q_dft*/
1046 50050 : move32();
1047 : }
1048 270604 : FOR( i = dftOvlLen; i < output_frame; i++ )
1049 : {
1050 270270 : tmp = L_shr( Mpy_32_32( hStereoDft->hb_stefi_sig_fx[i], hStereoDft->td_gain_fx[0] ), 1 ); /*hStereoDft->q_hb_stefi_sig_fx + hStereoDft->q_td_gain - 31*/
1051 270270 : output[0][i] = L_add( output[0][i], L_shr( tmp, sub( hStereoDft->q_hb_stefi_sig_fx, hStereoDft->q_dft ) ) ); /*hStereoDft->q_dft + hStereoDft->q_td_gain - 31*/
1052 270270 : move32();
1053 270270 : output[1][i] = L_sub( output[1][i], L_shr( tmp, sub( hStereoDft->q_hb_stefi_sig_fx, hStereoDft->q_dft ) ) ); /*hStereoDft->q_dft + hStereoDft->q_td_gain - 31*/
1054 270270 : move32();
1055 : }
1056 : }
1057 :
1058 1814 : return;
1059 : }
1060 :
1061 :
1062 : /*-------------------------------------------------------------------*
1063 : * ivas_sba_dirac_stereo_smooth_parameters_fx()
1064 : *
1065 : * Smooth DFT Stereo parameters
1066 : *-------------------------------------------------------------------*/
1067 :
1068 10753 : void ivas_sba_dirac_stereo_smooth_parameters_fx(
1069 : STEREO_DFT_DEC_DATA_HANDLE hStereoDft, /* i/o: decoder DFT stereo handle */
1070 : ivas_spar_md_dec_state_t *hMdDec, /* i/o: SPAR MD handle for upmixing */
1071 : const Word16 cross_fade_start_offset, /* i : SPAR mixer delay compensation Q0*/
1072 : const Word32 output_Fs, /* i : Fs for delay calculation Q0*/
1073 : const Word16 num_md_sub_frames /* i : number of subframes in mixing matrix Q0*/
1074 : )
1075 : {
1076 : Word16 i, j, k, i_sf;
1077 : Word16 b;
1078 : Word16 k_offset;
1079 : Word32 *side_gain, *prev_side_gain;
1080 : Word32 *res_pred_gain, *prev_res_pred_gain;
1081 :
1082 10753 : k_offset = STEREO_DFT_OFFSET;
1083 10753 : move16();
1084 10753 : prev_side_gain = hStereoDft->side_gain_fx; /*Q31*/
1085 10753 : side_gain = hStereoDft->side_gain_fx + k_offset * STEREO_DFT_BAND_MAX; /*Q31*/
1086 10753 : prev_res_pred_gain = hStereoDft->res_pred_gain_fx; /*Q31*/
1087 10753 : res_pred_gain = hStereoDft->res_pred_gain_fx + k_offset * STEREO_DFT_BAND_MAX; /*Q31*/
1088 :
1089 10753 : IF( !hMdDec )
1090 : {
1091 : /* Smoothing of side and prediction gains between ftrames */
1092 7032 : FOR( b = hStereoDft->res_pred_band_min; b < hStereoDft->nbands; b++ )
1093 : {
1094 5860 : IF( hStereoDft->attackPresent )
1095 : {
1096 0 : res_pred_gain[b] = Mpy_32_16_1( res_pred_gain[b], (Word16) 0x6666 /*0.8f in Q15*/ ); /*Q31*/
1097 0 : move32();
1098 0 : res_pred_gain[b + STEREO_DFT_BAND_MAX] = Mpy_32_16_1( res_pred_gain[b + STEREO_DFT_BAND_MAX], (Word16) 0x6666 /*0.8f in Q15*/ ); /*Q31*/
1099 0 : move32();
1100 : }
1101 : ELSE
1102 : {
1103 5860 : side_gain[b] = Madd_32_16( Mpy_32_16_1( prev_side_gain[b], hStereoDft->smooth_fac_fx[0][b] ),
1104 5860 : side_gain[b], sub( (Word16) 0x7FFF /*1.0f in Q15*/, hStereoDft->smooth_fac_fx[0][b] ) ); /*Q31*/
1105 5860 : move32();
1106 5860 : side_gain[b + STEREO_DFT_BAND_MAX] = Madd_32_16( Mpy_32_16_1( side_gain[b], hStereoDft->smooth_fac_fx[1][b] ),
1107 5860 : side_gain[b + STEREO_DFT_BAND_MAX],
1108 5860 : sub( (Word16) 0x7FFF /*1.0f in Q15*/, hStereoDft->smooth_fac_fx[1][b] ) ); /*Q31*/
1109 5860 : move32();
1110 5860 : res_pred_gain[b] = Madd_32_16( Mpy_32_16_1( prev_res_pred_gain[b], hStereoDft->smooth_fac_fx[0][b] ),
1111 5860 : res_pred_gain[b],
1112 5860 : sub( (Word16) 0x7FFF /*1.0f in Q15*/, hStereoDft->smooth_fac_fx[0][b] ) ); /*Q31*/
1113 5860 : move32();
1114 5860 : res_pred_gain[b + STEREO_DFT_BAND_MAX] = Madd_32_16( Mpy_32_16_1( res_pred_gain[b], hStereoDft->smooth_fac_fx[1][b] ),
1115 5860 : res_pred_gain[b + STEREO_DFT_BAND_MAX],
1116 5860 : sub( (Word16) 0x7FFF /*1.0f in Q15*/, hStereoDft->smooth_fac_fx[1][b] ) ); /*Q31*/
1117 5860 : move32();
1118 : }
1119 : }
1120 : }
1121 :
1122 10753 : IF( hMdDec != 0 )
1123 : {
1124 : Word64 xfade_start_ns;
1125 : Word16 xfade_delay_subframes;
1126 : Word16 i_hist;
1127 : Word16 md_sf;
1128 :
1129 9581 : xfade_start_ns = W_sub( W_mult_32_32( (Word32) cross_fade_start_offset, 1000000000 ), W_mult_32_32( IVAS_FB_ENC_DELAY_NS, output_Fs ) );
1130 : /*
1131 : 64-bit container is needed for storing the result in the previous step.
1132 : ToDo: Replace the 64-bit division below with appropriate BASOP
1133 : */
1134 9581 : xfade_delay_subframes = (Word16) ( xfade_start_ns / W_mult_32_32( ( FRAME_SIZE_NS / MAX_PARAM_SPATIAL_SUBFRAMES ), output_Fs ) ); /*Q0*/
1135 9581 : move16();
1136 9581 : i_hist = sub( (Word16) 4, xfade_delay_subframes ); /*Q0*/
1137 9581 : move16();
1138 28743 : FOR( k = 0; k < 2; k++ )
1139 : {
1140 57486 : FOR( i_sf = ( k * 2 ); i_sf < ( k + 1 ) * 2; i_sf++ )
1141 : {
1142 38324 : md_sf = 0;
1143 38324 : move16();
1144 :
1145 38324 : IF( EQ_16( num_md_sub_frames, MAX_PARAM_SPATIAL_SUBFRAMES ) )
1146 : {
1147 31032 : md_sf = i_sf; /*Q0*/
1148 31032 : move16();
1149 : }
1150 38324 : IF( hStereoDft->first_frame )
1151 : {
1152 1092 : FOR( i = 0; i < 2; i++ )
1153 : {
1154 3640 : FOR( j = 0; j < 4; j++ )
1155 : {
1156 36800 : FOR( b = 0; b < hStereoDft->nbands; b++ )
1157 : {
1158 : // The Q format of mixer_mat_fx is Q30 so applying the left shift.
1159 33888 : hStereoDft->mixer_mat_smooth_fx[i][j][( b + ( k * IVAS_MAX_NUM_BANDS ) )] = L_shl_sat( hMdDec->mixer_mat_fx[i][j][b], 1 ); /*Q31*/
1160 33888 : move32();
1161 : }
1162 3968 : FOR( ; b < IVAS_MAX_NUM_BANDS; b++ )
1163 : {
1164 1056 : hStereoDft->mixer_mat_smooth_fx[i][j][( b + ( k * IVAS_MAX_NUM_BANDS ) )] = 0;
1165 1056 : move32();
1166 : }
1167 : }
1168 : }
1169 : }
1170 : ELSE
1171 : {
1172 113880 : FOR( i = 0; i < 2; i++ )
1173 : {
1174 379600 : FOR( j = 0; j < 4; j++ )
1175 : {
1176 3757824 : FOR( b = 0; b < hStereoDft->nbands; b++ )
1177 : {
1178 3454144 : Word16 beta = hStereoDft->smooth_fac_fx[k][b]; /*Q15*/
1179 3454144 : move16();
1180 : // The Q format of mixer_mat_prev_fx is Q30 so applying the left shift.
1181 6908288 : hStereoDft->mixer_mat_smooth_fx[i][j][b + k * IVAS_MAX_NUM_BANDS] =
1182 3454144 : L_add_sat( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[i][j][( b + ( k * IVAS_MAX_NUM_BANDS ) )], beta ),
1183 3454144 : L_shl_sat( Mpy_32_16_1( hMdDec->mixer_mat_prev_fx[i_hist][i][j][b], sub( (Word16) 0x7FFF, beta ) ), Q1 ) ); /*Q31*/
1184 3454144 : move32();
1185 : }
1186 : }
1187 : }
1188 : }
1189 :
1190 38324 : Copy32( hMdDec->mixer_mat_prev_fx[1][0][0], hMdDec->mixer_mat_prev_fx[0][0][0], IVAS_MAX_FB_MIXER_OUT_CH * IVAS_MAX_SPAR_FB_MIXER_IN_CH * IVAS_MAX_NUM_BANDS ); /*hMdDec->Q_mixer_mat*/
1191 38324 : Copy32( hMdDec->mixer_mat_prev_fx[2][0][0], hMdDec->mixer_mat_prev_fx[1][0][0], IVAS_MAX_FB_MIXER_OUT_CH * IVAS_MAX_SPAR_FB_MIXER_IN_CH * IVAS_MAX_NUM_BANDS ); /*hMdDec->Q_mixer_mat*/
1192 38324 : Copy32( hMdDec->mixer_mat_prev_fx[3][0][0], hMdDec->mixer_mat_prev_fx[2][0][0], IVAS_MAX_FB_MIXER_OUT_CH * IVAS_MAX_SPAR_FB_MIXER_IN_CH * IVAS_MAX_NUM_BANDS ); /*hMdDec->Q_mixer_mat*/
1193 38324 : Copy32( hMdDec->mixer_mat_prev_fx[4][0][0], hMdDec->mixer_mat_prev_fx[3][0][0], IVAS_MAX_FB_MIXER_OUT_CH * IVAS_MAX_SPAR_FB_MIXER_IN_CH * IVAS_MAX_NUM_BANDS ); /*hMdDec->Q_mixer_mat*/
1194 :
1195 114972 : FOR( i = 0; i < 2; i++ )
1196 : {
1197 383240 : FOR( j = 0; j < 4; j++ )
1198 : {
1199 3794624 : FOR( b = 0; b < hStereoDft->nbands; b++ )
1200 : {
1201 3488032 : hMdDec->mixer_mat_prev_fx[4][i][j][b] = hMdDec->mixer_mat_fx[i][j][( b + ( md_sf * IVAS_MAX_NUM_BANDS ) )]; /*hMdDec->Q_mixer_mat*/
1202 3488032 : move32();
1203 : }
1204 : }
1205 : }
1206 : }
1207 : }
1208 :
1209 9581 : hStereoDft->first_frame = 0;
1210 9581 : move16();
1211 : }
1212 :
1213 10753 : return;
1214 : }
1215 :
1216 :
1217 : /*-------------------------------------------------------------------*
1218 : * ivas_sba_dirac_stereo_dec_fx()
1219 : *
1220 : * Create stereo output for SBA DirAC via DFT stereo
1221 : *-------------------------------------------------------------------*/
1222 :
1223 10790 : void ivas_sba_dirac_stereo_dec_fx(
1224 : Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
1225 : Word32 *output[CPE_CHANNELS], /* i/o: output synthesis signal */
1226 : const Word16 output_frame, /* i : output frame length per channel Q0*/
1227 : const Word16 mcmasa /* i : McMASA flag Q0*/
1228 : )
1229 : {
1230 : Word16 dtx_flag, fd_cng_flag;
1231 : Word16 sba_mono_flag;
1232 : Word16 memOffset;
1233 : Word32 tmp_buf[NS2SA( 48000, IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS )];
1234 : Word32 tmp_synth[L_FRAME16k];
1235 : Word32 hb_gain[NB_DIV];
1236 : Word32 hb_synth_stereo[CPE_CHANNELS][L_FRAME48k];
1237 : Word32 DFT[CPE_CHANNELS][STEREO_DFT_BUF_MAX];
1238 10790 : Word16 q_dft[2] = { 0, 0 };
1239 10790 : Word16 q = 0;
1240 10790 : Word16 q_synth = 0;
1241 10790 : move16();
1242 : SCE_DEC_HANDLE hSCE;
1243 : CPE_DEC_HANDLE hCPE;
1244 : STEREO_DFT_DEC_DATA_HANDLE hStereoDft;
1245 :
1246 32370 : FOR( Word16 i = 0; i < CPE_CHANNELS; i++ )
1247 : {
1248 21580 : set32_fx( DFT[i], 0, STEREO_DFT_BUF_MAX );
1249 : }
1250 :
1251 10790 : hSCE = st_ivas->hSCE[0];
1252 10790 : hCPE = st_ivas->hCPE[0];
1253 10790 : hStereoDft = hCPE->hStereoDft;
1254 10790 : q = hCPE->hStereoDft->q_dft;
1255 10790 : move16();
1256 10790 : q_dft[0] = hCPE->hStereoDft->q_dft;
1257 10790 : move16();
1258 10790 : q_dft[1] = hCPE->hStereoDft->q_dft;
1259 10790 : move16();
1260 :
1261 10790 : Scale_sig32( hCPE->prev_hb_synth_fx[0], NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS ), negate( sub( Q11, hCPE->hStereoDft->q_dft ) ) ); /*hSCE->q_prev_hb_synth_fx + hCPE->hStereoDft->q_dft - Q11*/
1262 10790 : IF( hSCE != NULL )
1263 : {
1264 4511 : Scale_sig32( hSCE->prev_hb_synth_fx, NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS ), negate( sub( Q11, hCPE->hStereoDft->q_dft ) ) ); /*hSCE->q_prev_hb_synth_fx + hCPE->hStereoDft->q_dft - Q11*/
1265 4511 : hSCE->q_prev_hb_synth_fx = hCPE->hStereoDft->q_dft;
1266 4511 : move16();
1267 : }
1268 :
1269 10790 : test();
1270 10790 : IF( GT_16( st_ivas->nchan_transport, 1 ) && !mcmasa )
1271 : {
1272 6279 : dtx_flag = 0;
1273 6279 : move16();
1274 6279 : fd_cng_flag = 0;
1275 6279 : move16();
1276 : }
1277 : ELSE
1278 : {
1279 4511 : dtx_flag = (Word16) LE_32( hSCE->hCoreCoder[0]->core_brate, SID_2k40 ); /*Q0*/
1280 4511 : move16();
1281 4511 : test();
1282 4511 : fd_cng_flag = ( dtx_flag && EQ_16( hSCE->hCoreCoder[0]->cng_type, FD_CNG ) ); /*Q0*/
1283 4511 : move16();
1284 : }
1285 10790 : sba_mono_flag = (Word16) EQ_16( st_ivas->hDecoderConfig->nchan_out, 1 );
1286 10790 : move16();
1287 :
1288 10790 : memOffset = NS2SA_FX2( L_mult0( output_frame, FRAMES_PER_SEC ), IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS );
1289 10790 : move16();
1290 :
1291 10790 : ivas_sba_dirac_stereo_config( hStereoDft->hConfig );
1292 10790 : test();
1293 10790 : test();
1294 10790 : hStereoDft->nbands = ivas_sba_dirac_stereo_band_config( hStereoDft->band_limits, st_ivas->hDecoderConfig->output_Fs, hStereoDft->NFFT, ( ( EQ_16( st_ivas->ivas_format, SBA_FORMAT ) || EQ_16( st_ivas->ivas_format, SBA_ISM_FORMAT ) ) && !mcmasa ) );
1295 10790 : stereo_dft_dec_update_fx( hStereoDft, output_frame, 1 /*st_ivas->sba_dirac_stereo_flag*/ );
1296 10790 : IF( GT_16( st_ivas->nchan_transport, 1 ) )
1297 : {
1298 6279 : stereo_dft_dec_analyze_fx( hCPE, output[0], DFT, 0, output_frame, output_frame, DFT_STEREO_DEC_ANA_FB, 0, 0, &q, &q_dft[0] );
1299 6279 : stereo_dft_dec_analyze_fx( hCPE, output[1], DFT, 1, output_frame, output_frame, DFT_STEREO_DEC_ANA_FB, 0, 0, &q, &q_dft[0] );
1300 6279 : hStereoDft->core_hist[0] = hCPE->hCoreCoder[0]->core;
1301 6279 : move16();
1302 : }
1303 : ELSE
1304 : {
1305 : /* nrg calculation for TD Stereo Filling, as done in ICBWE which is not used in this case */
1306 4511 : ivas_sba_dirac_stereo_compute_td_stefi_nrgs( hStereoDft, hSCE->save_hb_synth_fx, hSCE->hCoreCoder[0]->core, output_frame, fd_cng_flag, hSCE->q_save_synth_fx );
1307 :
1308 : /* do DFT Stereo core switching (including DFT analysis) here as CPE element was not available in SCE decoder */
1309 4511 : Copy32( hSCE->save_synth_fx, tmp_synth, hSCE->hCoreCoder[0]->L_frame ); /*hSCE->q_save_synth_fx*/
1310 4511 : stereo_dft_dec_core_switching_fx( hCPE, output[0] /*hSCE->save_output*/, hSCE->save_synth_fx, hSCE->save_hb_synth_fx, DFT, output_frame, 0, dtx_flag, &q, &q_dft[0] );
1311 :
1312 : /* do updates here after skipping this in SCE decoder (needs to be done after core switching) */
1313 4511 : ivas_updt_dec_common_fx( hSCE->hCoreCoder[0], NORMAL_HQ_CORE, -1, hSCE->save_synth_fx, q );
1314 :
1315 4511 : q_synth = sub( getScaleFactor32( tmp_synth, hSCE->hCoreCoder[0]->L_frame ), 10 );
1316 4511 : scale_sig32( tmp_synth, hSCE->hCoreCoder[0]->L_frame, q_synth ); /*hSCE->q_save_synth_fx + q_synth*/
1317 4511 : q_synth = add( q_synth, hSCE->q_save_synth_fx );
1318 : }
1319 :
1320 : /* mapping of DirAC parameters (azimuth, elevation, diffuseness) to DFT Stereo parameters (side gain, prediction gain) */
1321 10790 : test();
1322 10790 : test();
1323 10790 : test();
1324 10790 : test();
1325 32370 : map_params_dirac_to_stereo( hStereoDft, st_ivas->hQMetaData, tmp_synth, DFT[0], st_ivas->ivas_format == MC_FORMAT,
1326 21580 : ( ( NE_16( st_ivas->ivas_format, SBA_FORMAT ) && NE_16( st_ivas->ivas_format, SBA_ISM_FORMAT ) ) || mcmasa ) ? hSCE->hCoreCoder[0]->L_frame : output_frame,
1327 10790 : ( ( NE_16( st_ivas->ivas_format, SBA_FORMAT ) && NE_16( st_ivas->ivas_format, SBA_ISM_FORMAT ) ) || mcmasa ), hSCE != NULL ? q_synth : 0 );
1328 :
1329 10790 : IF( ( EQ_32( st_ivas->ivas_format, SBA_FORMAT ) || EQ_32( st_ivas->ivas_format, SBA_ISM_FORMAT ) ) && !mcmasa )
1330 : {
1331 9610 : set32_fx( hStereoDft->res_pred_gain_fx, MAX_32, 3 * STEREO_DFT_BAND_MAX ); /*Q31*/
1332 : }
1333 :
1334 : /* DFT Stereo upmix */
1335 10790 : stereo_dft_dec_fx( hStereoDft, hCPE->hCoreCoder[0], DFT, NULL, NULL, 1 /*st_ivas->sba_dirac_stereo_flag*/, sba_mono_flag, ( st_ivas->hSpar != NULL && !mcmasa ) ? st_ivas->hSpar->hMdDec : NULL, ( st_ivas->hSpar != NULL && ( !mcmasa ) ) ? st_ivas->hSpar->hFbMixer->cross_fade_start_offset : 0,
1336 10790 : st_ivas->hDecoderConfig->output_Fs, st_ivas->nchan_transport, ivas_get_spar_dec_md_num_subframes( st_ivas->sba_order, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->last_active_ivas_total_brate ) );
1337 :
1338 : /* DFT synthesis */
1339 10790 : stereo_dft_dec_synthesize_fx( hCPE, DFT, 0, output[0], output_frame );
1340 10790 : IF( !sba_mono_flag )
1341 : {
1342 10180 : stereo_dft_dec_synthesize_fx( hCPE, DFT, 1, output[1], output_frame );
1343 : }
1344 :
1345 10790 : synchro_synthesis_fx( st_ivas->hDecoderConfig->ivas_total_brate, hCPE, output, output_frame, 1 /*st_ivas->sba_dirac_stereo_flag*/, q_dft[0] );
1346 :
1347 : /* output scaling */
1348 10790 : IF( !sba_mono_flag )
1349 : {
1350 10180 : v_shr( output[0], 1, output[0], output_frame ); /*0.5f*/
1351 10180 : v_shr( output[1], 1, output[1], output_frame ); /*0.5f*/
1352 : }
1353 :
1354 : /* delay HB synth */
1355 10790 : IF( EQ_16( st_ivas->nchan_transport, 1 ) )
1356 : {
1357 4511 : Copy32( hSCE->save_hb_synth_fx + output_frame - memOffset, tmp_buf, memOffset ); /*hSCE->q_save_hb_synth_fx*/
1358 4511 : Copy32( hSCE->save_hb_synth_fx, hSCE->save_hb_synth_fx + memOffset, sub( output_frame, memOffset ) ); /*hSCE->q_save_hb_synth_fx*/
1359 4511 : Copy32( hSCE->prev_hb_synth_fx, hSCE->save_hb_synth_fx, memOffset ); /*hSCE->q_prev_hb_synth_fx*/
1360 4511 : v_shr( tmp_buf, sub( hSCE->q_prev_hb_synth_fx, hSCE->q_save_hb_synth_fx ), hSCE->prev_hb_synth_fx, memOffset ); /*hSCE->q_prev_hb_synth_fx*/
1361 : }
1362 :
1363 10790 : test();
1364 10790 : test();
1365 10790 : test();
1366 10790 : IF( ( EQ_16( hCPE->hCoreCoder[0]->core, ACELP_CORE ) || EQ_16( hCPE->hCoreCoder[0]->last_core, ACELP_CORE ) ) && !fd_cng_flag && EQ_16( st_ivas->nchan_transport, 1 ) )
1367 : {
1368 : /* upmix ACELP BWE */
1369 2017 : ivas_sba_dirac_stereo_compute_hb_gain( hStereoDft, hb_gain );
1370 :
1371 2017 : test();
1372 2017 : test();
1373 2017 : ivas_sba_dirac_stereo_upmix_hb( hb_synth_stereo, hSCE->save_hb_synth_fx, hb_gain, output_frame, ( ( NE_16( st_ivas->ivas_format, SBA_FORMAT ) && NE_16( st_ivas->ivas_format, SBA_ISM_FORMAT ) ) || mcmasa ), sba_mono_flag, hSCE->hCoreCoder[0]->bwidth, hStereoDft );
1374 :
1375 : /* add HB to ACELP core */
1376 2017 : v_add_fx( output[0], hb_synth_stereo[0], output[0], output_frame ); /*q*/
1377 2017 : IF( !sba_mono_flag )
1378 : {
1379 1814 : v_add_fx( output[1], hb_synth_stereo[1], output[1], output_frame ); /*q*/
1380 :
1381 : /* apply TD Stereo Filling as is done in ICBWE */
1382 1814 : test();
1383 1814 : test();
1384 1814 : ivas_sba_dirac_stereo_apply_td_stefi( hStereoDft, output, output_frame, ( ( EQ_16( st_ivas->ivas_format, SBA_FORMAT ) || EQ_16( st_ivas->ivas_format, SBA_ISM_FORMAT ) ) && !mcmasa ) );
1385 : }
1386 : }
1387 :
1388 : /* reset the other channels to 0 (they are not used since here) */
1389 18151 : FOR( Word16 ch = CPE_CHANNELS; ch < st_ivas->nchan_transport; ch++ )
1390 : {
1391 7361 : set32_fx( output[ch], 0, output_frame );
1392 : }
1393 :
1394 10790 : Scale_sig32( hCPE->prev_hb_synth_fx[0], NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS ), sub( Q11, hCPE->hStereoDft->q_dft ) ); /*hSCE->q_prev_hb_synth_fx + Q11 - hCPE->hStereoDft->q_dft*/
1395 10790 : IF( hSCE != NULL )
1396 : {
1397 4511 : Scale_sig32( hSCE->prev_hb_synth_fx, NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS ), sub( Q11, hCPE->hStereoDft->q_dft ) ); /*hSCE->q_prev_hb_synth_fx + Q11 - hCPE->hStereoDft->q_dft*/
1398 4511 : hSCE->q_prev_hb_synth_fx = Q11;
1399 4511 : move16();
1400 : }
1401 :
1402 10790 : return;
1403 : }
|