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