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 3214 : 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 3214 : sba_dirac_stereo_flag = 0;
62 3214 : move16();
63 3214 : output_config = st_ivas->hDecoderConfig->output_config;
64 3214 : move16();
65 :
66 3214 : test();
67 3214 : test();
68 3214 : 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 1812 : IF( EQ_16( st_ivas->ivas_format, SBA_FORMAT ) )
71 : {
72 1264 : test();
73 1264 : test();
74 1264 : 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 3214 : 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 18486 : static Word16 get_panning_tangent_gain(
223 : const Word16 sinAngleMapped )
224 : {
225 18486 : 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 18486 : move16();
227 18486 : Word16 idx = shr( tbl_len, 1 ); /*Q0*/
228 18486 : move16();
229 18486 : const Word16 *ptr_sin = &ivas_sine_panning_tbl_fx[0]; /*Q15*/
230 18486 : const Word16 *ptr_tan = &ivas_tan_panning_gain_dirac_tbl_fx[0]; /*Q15*/
231 18486 : Word16 lim_l = 0;
232 18486 : move16();
233 18486 : Word16 lim_r = tbl_len; /*Q0*/
234 18486 : move16();
235 : WHILE( 1 )
236 : {
237 59871 : idx = shr( add( lim_l, lim_r ), 1 ); /*Q0*/
238 59871 : IF( GE_16( idx, tbl_len ) )
239 : {
240 0 : return ptr_tan[tbl_len - 1]; /*Q15*/
241 : }
242 59871 : ELSE IF( idx <= 0 )
243 : {
244 0 : return ptr_tan[0]; /*Q15*/
245 : }
246 59871 : ELSE IF( LE_16( sinAngleMapped, ptr_sin[idx + 1] ) && GE_16( sinAngleMapped, ptr_sin[idx] ) )
247 : {
248 18486 : IF( EQ_16( sinAngleMapped, ptr_sin[idx + 1] ) )
249 : {
250 1438 : return ptr_tan[idx + 1]; /*Q15*/
251 : }
252 17048 : ELSE IF( EQ_16( sinAngleMapped, ptr_sin[idx] ) )
253 : {
254 14697 : return ptr_tan[idx]; /*Q15*/
255 : }
256 : ELSE
257 : {
258 2351 : Word16 mid = add( shr( ptr_sin[idx], 1 ), shr( ptr_sin[idx + 1], 1 ) );
259 2351 : move16();
260 2351 : IF( LE_16( sinAngleMapped, mid ) )
261 : {
262 569 : return ptr_tan[idx]; /*Q15*/
263 : }
264 : ELSE
265 : {
266 1782 : return ptr_tan[idx + 1]; /*Q15*/
267 : }
268 : }
269 : }
270 41385 : ELSE IF( GT_16( sinAngleMapped, ptr_sin[idx] ) )
271 : {
272 18401 : lim_l = add( idx, 1 ); /*Q0*/
273 : }
274 22984 : ELSE IF( LT_16( sinAngleMapped, ptr_sin[idx] ) )
275 : {
276 22984 : 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 32758 : WHILE( GT_16( azAddEl, 180 ) )
296 : {
297 9158 : azAddEl = sub( azAddEl, 360 ); /*Q0*/
298 : }
299 23600 : WHILE( LT_16( azAddEl, negate( 180 ) ) )
300 : {
301 0 : azAddEl = add( azAddEl, 360 ); /*Q0*/
302 : }
303 32716 : WHILE( GT_16( azSubEl, 180 ) )
304 : {
305 9116 : 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 558 : panning = (Word16) 0x7fff; /*Q15*/
317 558 : move16();
318 : }
319 23042 : ELSE IF( LE_32( sin_az_cos_el, SIN_NEG_30_DEGREES_Q15 ) )
320 : { /* Right side */
321 4556 : panning = (Word16) 0x8000; /*Q15*/
322 4556 : move16();
323 : }
324 : ELSE
325 : { /* Tangent panning law */
326 18486 : 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 229118 : 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 229118 : 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 225042 : 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 225042 : move32();
438 225042 : IF( GT_16( q_div, norm_s( hStereoDft->smooth_fac_fx[k][b] ) ) )
439 : {
440 120082 : hStereoDft->smooth_fac_fx[k][b] = MAX_16; /*Q15*/
441 120082 : move32();
442 : }
443 : ELSE
444 : {
445 104960 : hStereoDft->smooth_fac_fx[k][b] = shl( hStereoDft->smooth_fac_fx[k][b], q_div ); /*Q15*/
446 104960 : move32();
447 104960 : q_div = 0;
448 104960 : move16();
449 : }
450 : }
451 : ELSE
452 : {
453 5398 : hStereoDft->smooth_fac_fx[k][b] = 0;
454 5398 : 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 9143 : 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 9143 : 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 3120 : 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 3190 : 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 : #ifdef NONBE_FIX_1096_NAN_VALUES_IN_DIRAC_TO_STEREO
626 : /* Clamp values here. [-1, 1] is the allowed range, but due to precision issues they can be slightly off which can cause problems later. */
627 : /* In Q31, this clamping happens implicitly */
628 : #endif
629 5900 : q_sqrt = 0;
630 5900 : move16();
631 5900 : side_gain[b] = Mpy_32_32( side_gain[b], Sqrt32( L_sub( MAX_32, diffuseness[b] ), &q_sqrt ) ); /*Q31 - q_sqrt*/
632 5900 : move32();
633 5900 : IF( q_sqrt )
634 : {
635 2291 : side_gain[b] = L_shl( side_gain[b], q_sqrt ); /*Q31*/
636 2291 : q_sqrt = 0;
637 2291 : move16();
638 : }
639 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*/
640 5900 : move32();
641 5900 : IF( q_sqrt )
642 : {
643 2291 : side_gain[b + STEREO_DFT_BAND_MAX] = L_shl( side_gain[b], q_sqrt ); /*Q31*/
644 2291 : q_sqrt = 0;
645 2291 : move16();
646 : }
647 : #ifdef NONBE_FIX_1096_NAN_VALUES_IN_DIRAC_TO_STEREO
648 : /* for residual prediction gain, allowed range is [0, 1]*/
649 5900 : res_pred_gain[b] = L_max( Mpy_32_16_1( diffuseness[b], sub( MAX_16, surrCoh[b] ) ), 0 ); /*Q31*/
650 5900 : move32();
651 5900 : res_pred_gain[b + STEREO_DFT_BAND_MAX] = L_max( Mpy_32_16_1( diffuseness[b], sub( MAX_16, surrCoh[b] ) ), 0 ); /*Q31*/
652 5900 : move32();
653 : #else
654 : res_pred_gain[b] = Mpy_32_16_1( diffuseness[b], sub( MAX_16, surrCoh[b] ) ); /*Q31*/
655 : move32();
656 : res_pred_gain[b + STEREO_DFT_BAND_MAX] = Mpy_32_16_1( diffuseness[b], sub( MAX_16, surrCoh[b] ) ); /*Q31*/
657 : move32();
658 : #endif
659 : }
660 : }
661 :
662 10790 : hStereoDft->frame_nodata = 0;
663 10790 : move16();
664 10790 : hStereoDft->frame_sid_nodata = 0;
665 10790 : move16();
666 10790 : hStereoDft->frame_sid = 0;
667 10790 : move16();
668 :
669 10790 : return;
670 : }
671 :
672 :
673 : /*-------------------------------------------------------------------*
674 : * ivas_sba_dirac_stereo_compute_td_stefi_nrgs()
675 : *
676 : * Compute energies for TD stereo filling
677 : *-------------------------------------------------------------------*/
678 :
679 4511 : static void ivas_sba_dirac_stereo_compute_td_stefi_nrgs(
680 : STEREO_DFT_DEC_DATA_HANDLE hStereoDft, /* i/o: decoder DFT stereo handle */
681 : const Word32 hb_synth[L_FRAME48k], /* i : HB signal q_hb_synth*/
682 : const Word16 core, /* i : core decision Q0*/
683 : const Word16 output_frame, /* i : output frame length per channel Q0*/
684 : const Word16 fd_cng_flag, /* i : FD-CNG indicator Q0*/
685 : const Word16 q_hb_synth )
686 : {
687 : Word16 i;
688 4511 : Word32 hb_nrg = EPSILON_FIX;
689 4511 : move32();
690 4511 : Word32 hb_nrg2 = EPSILON_FIX;
691 4511 : move32();
692 :
693 4511 : test();
694 4511 : test();
695 4511 : IF( ( EQ_16( core, ACELP_CORE ) && !fd_cng_flag ) || EQ_16( hStereoDft->core_hist[1], ACELP_CORE ) )
696 : {
697 423887 : FOR( i = 0; i < shr( output_frame, 2 ); i++ )
698 : {
699 421680 : 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[0] = hb_nrg2; /*2*q_hb_synth-31*/
703 2207 : move32();
704 2207 : hStereoDft->q_hb_nrg_subr = sub( shl( q_hb_synth, 1 ), 31 );
705 2207 : move32();
706 2207 : hb_nrg = L_add( hb_nrg, hb_nrg2 );
707 2207 : move32();
708 2207 : hb_nrg2 = EPSILON_FIX;
709 2207 : move32();
710 :
711 1267247 : FOR( ; i < output_frame; i++ )
712 : {
713 1265040 : hb_nrg2 = Madd_32_32( hb_nrg2, hb_synth[i], hb_synth[i] ); /*2*q_hb_synth-31*/
714 : }
715 :
716 2207 : hStereoDft->hb_nrg_subr_fx[1] = hb_nrg2; /*2*q_hb_synth-31*/
717 2207 : move32();
718 2207 : hb_nrg = L_add( hb_nrg, hb_nrg2 );
719 :
720 2207 : IF( EQ_16( hStereoDft->q_hb_stefi_sig_fx, q_hb_synth ) )
721 : {
722 445 : Copy32( hb_synth, hStereoDft->hb_stefi_sig_fx + hStereoDft->hb_stefi_delay, output_frame ); /*q_hb_synth*/
723 : }
724 : ELSE
725 : {
726 1762 : IF( GT_16( hStereoDft->q_hb_stefi_sig_fx, q_hb_synth ) )
727 : {
728 173 : 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*/
729 173 : hStereoDft->q_hb_stefi_sig_fx = q_hb_synth;
730 173 : move16();
731 173 : Copy32( hb_synth, hStereoDft->hb_stefi_sig_fx + hStereoDft->hb_stefi_delay, output_frame ); /*q_hb_synth*/
732 : }
733 : ELSE
734 : {
735 1589 : 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*/
736 : }
737 : }
738 : }
739 : ELSE
740 : {
741 2304 : set32_fx( hStereoDft->hb_stefi_sig_fx + hStereoDft->hb_stefi_delay, 0, output_frame );
742 2304 : hStereoDft->hb_nrg_subr_fx[0] = 0;
743 2304 : move32();
744 2304 : hStereoDft->hb_nrg_subr_fx[1] = 0;
745 2304 : move32();
746 : }
747 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*/
748 4511 : move32();
749 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*/
750 4511 : move32();
751 4511 : hStereoDft->hb_nrg_fx[0] = hb_nrg;
752 4511 : move32();
753 4511 : hStereoDft->td_gain_fx[0] = 0;
754 4511 : move32();
755 4511 : hStereoDft->core_hist[0] = core; /* full signal available for DTX with FD-CNG, thus apply stereo filling on full spectrum like in TCX */
756 4511 : move16();
757 :
758 4511 : if ( fd_cng_flag )
759 : {
760 91 : hStereoDft->core_hist[0] = TCX_20_CORE;
761 91 : move16();
762 : }
763 4511 : return;
764 : }
765 :
766 :
767 : /*-------------------------------------------------------------------*
768 : * ivas_sba_dirac_stereo_compute_hb_gain()
769 : *
770 : * Compute HB gains
771 : *-------------------------------------------------------------------*/
772 :
773 2044 : static void ivas_sba_dirac_stereo_compute_hb_gain(
774 : STEREO_DFT_DEC_DATA_HANDLE hStereoDft, /* i/o: decoder DFT stereo handle */
775 : Word32 hb_gain[NB_DIV] /* o : side gains for HB signal Q31*/
776 : )
777 : {
778 : Word16 k_offset;
779 :
780 2044 : k_offset = STEREO_DFT_OFFSET;
781 2044 : move16();
782 :
783 : /* last band covers whole HB range, no averaging needed */
784 2044 : hb_gain[0] = hStereoDft->side_gain_fx[( ( ( k_offset * STEREO_DFT_BAND_MAX ) + hStereoDft->nbands ) - 1 )]; /*Q31*/
785 2044 : move32();
786 2044 : hb_gain[1] = hStereoDft->side_gain_fx[( ( ( ( k_offset + 1 ) * STEREO_DFT_BAND_MAX ) + hStereoDft->nbands ) - 1 )]; /*Q31*/
787 2044 : move32();
788 :
789 2044 : return;
790 : }
791 :
792 :
793 : /*-------------------------------------------------------------------*
794 : * ivas_sba_dirac_stereo_upmix_hb()
795 : *
796 : * Apply panning to HB signal
797 : *-------------------------------------------------------------------*/
798 :
799 2044 : static void ivas_sba_dirac_stereo_upmix_hb(
800 : Word32 hb_stereo_synth[CPE_CHANNELS][L_FRAME48k], /* i/o: stereo HB synthesis signal Qx*/
801 : Word32 hb_synth[L_FRAME48k], /* i : HB signal Qx*/
802 : Word32 hb_gain[NB_DIV], /* i : side gains for HB signal Q31*/
803 : const Word16 output_frame, /* i : output frame length per channel Q0*/
804 : const Word16 mcmasa, /* i : McMASA flag Q0*/
805 : const Word16 sba_mono_flag, /* i : flag for mono output Q0*/
806 : const Word16 bwidth, /* i : bandwidth of signal Q0*/
807 : const STEREO_DFT_DEC_DATA_HANDLE hStereoDft /* i : Stereo DFT handle for mixing matrix */
808 : )
809 : {
810 : Word16 i;
811 : Word32 gp, gm;
812 : Word16 gain_fac;
813 :
814 2044 : IF( !mcmasa )
815 : {
816 1686 : gain_fac = (Word32) 0x2A3D; /* last matrix element not used for SWB, divide by 3 instead of 4*/ /*Q15*/
817 1686 : move16();
818 1686 : if ( EQ_16( bwidth, FB ) )
819 : {
820 50 : gain_fac = (Word32) 0x2000; /*Q15*/
821 50 : move16();
822 : }
823 :
824 1686 : IF( sba_mono_flag )
825 : {
826 211 : gp = L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[0][0][8], gain_fac ),
827 : Madd_32_16( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[0][0][9], gain_fac ),
828 : hStereoDft->mixer_mat_smooth_fx[0][0][10], 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], gain_fac ); /*Q31*/
832 : }
833 :
834 101491 : FOR( i = 0; i < shr( output_frame, 1 ); i++ )
835 : {
836 101280 : hb_stereo_synth[0][i] = Mpy_32_32( hb_synth[i], gp ); /*Qx*/
837 101280 : move32();
838 : }
839 :
840 211 : gp = L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[0][0][8 + IVAS_MAX_NUM_BANDS], gain_fac ),
841 : Madd_32_16( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[0][0][9 + IVAS_MAX_NUM_BANDS], gain_fac ),
842 : hStereoDft->mixer_mat_smooth_fx[0][0][10 + IVAS_MAX_NUM_BANDS], gain_fac ) ); /*Q31*/
843 211 : IF( EQ_16( bwidth, FB ) )
844 : {
845 18 : gp = Madd_32_16( gp, hStereoDft->mixer_mat_smooth_fx[0][0][11 + IVAS_MAX_NUM_BANDS], gain_fac ); /*Q31*/
846 : }
847 :
848 101491 : FOR( i = shr( output_frame, 1 ); i < output_frame; i++ )
849 : {
850 101280 : hb_stereo_synth[0][i] = Mpy_32_32( hb_synth[i], gp ); /*Qx*/
851 101280 : move32();
852 : }
853 : }
854 : ELSE
855 : {
856 : /* Accounting for the 0.5 multiplication */
857 1475 : gain_fac = shr( gain_fac, 1 ); /*Q15*/
858 1475 : gp = L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[0][0][8], gain_fac ),
859 : L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[1][0][8], gain_fac ),
860 : L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[0][0][9], gain_fac ),
861 : L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[1][0][9], gain_fac ),
862 : L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[0][0][10], gain_fac ),
863 : Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[1][0][10], gain_fac ) ) ) ) ) ); /*Q31*/
864 1475 : IF( EQ_32( bwidth, FB ) )
865 : {
866 32 : gp = L_add( gp, Madd_32_16( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[0][0][11], gain_fac ),
867 : hStereoDft->mixer_mat_smooth_fx[1][0][11], gain_fac ) ); /*Q31*/
868 : }
869 :
870 1475 : gm = L_add( Msub_32_16( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[0][0][8], gain_fac ),
871 : hStereoDft->mixer_mat_smooth_fx[1][0][8], gain_fac ),
872 : L_add( Msub_32_16( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[0][0][9], gain_fac ),
873 : hStereoDft->mixer_mat_smooth_fx[1][0][9], gain_fac ),
874 : Msub_32_16( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[0][0][10], gain_fac ),
875 : hStereoDft->mixer_mat_smooth_fx[1][0][10], gain_fac ) ) ); /*Q31*/
876 1475 : IF( EQ_32( bwidth, FB ) )
877 : {
878 32 : gm = L_add( gm, Msub_32_16( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[0][0][11], gain_fac ),
879 : hStereoDft->mixer_mat_smooth_fx[1][0][11], gain_fac ) ); /*Q31*/
880 : }
881 :
882 506595 : FOR( i = 0; i < shr( output_frame, 1 ); i++ )
883 : {
884 505120 : hb_stereo_synth[0][i] = Mpy_32_32( hb_synth[i], gp ); /*Qx*/
885 505120 : move32();
886 505120 : hb_stereo_synth[1][i] = Mpy_32_32( hb_synth[i], gm ); /*Qx*/
887 505120 : move32();
888 : }
889 :
890 1475 : gp = L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[0][0][8 + IVAS_MAX_NUM_BANDS], gain_fac ),
891 : L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[1][0][8 + IVAS_MAX_NUM_BANDS], gain_fac ),
892 : L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[0][0][9 + IVAS_MAX_NUM_BANDS], gain_fac ),
893 : L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[1][0][9 + IVAS_MAX_NUM_BANDS], gain_fac ),
894 : Madd_32_16( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[0][0][10 + IVAS_MAX_NUM_BANDS], gain_fac ),
895 : hStereoDft->mixer_mat_smooth_fx[1][0][10 + IVAS_MAX_NUM_BANDS], gain_fac ) ) ) ) ); /*Q31*/
896 1475 : IF( EQ_32( bwidth, FB ) )
897 : {
898 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*/
899 : }
900 :
901 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 ),
902 : 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 ),
903 : 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*/
904 1475 : IF( EQ_32( bwidth, FB ) )
905 : {
906 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*/
907 : }
908 :
909 506595 : FOR( i = shr( output_frame, 1 ); i < output_frame; i++ )
910 : {
911 505120 : hb_stereo_synth[0][i] = Mpy_32_32( hb_synth[i], gp ); /*Qx*/
912 505120 : move32();
913 505120 : hb_stereo_synth[1][i] = Mpy_32_32( hb_synth[i], gm ); /*Qx*/
914 505120 : move32();
915 : }
916 : }
917 : }
918 : ELSE
919 : {
920 171238 : FOR( i = 0; i < L_shr( output_frame, 1 ); i++ )
921 : {
922 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*/
923 170880 : move32();
924 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*/
925 170880 : move32();
926 : }
927 :
928 171238 : FOR( i = shr( output_frame, 1 ); i < output_frame; i++ )
929 : {
930 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*/
931 170880 : move32();
932 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*/
933 170880 : move32();
934 : }
935 : }
936 :
937 2044 : return;
938 : }
939 :
940 :
941 : /*-------------------------------------------------------------------*
942 : * ivas_sba_dirac_stereo_apply_td_stefi()
943 : *
944 : * Apply TD stereo filling for ACELP HB
945 : *-------------------------------------------------------------------*/
946 :
947 1833 : static void ivas_sba_dirac_stereo_apply_td_stefi(
948 : STEREO_DFT_DEC_DATA_HANDLE hStereoDft, /* i/o: decoder DFT stereo handle */
949 : Word32 *output[CPE_CHANNELS], /* i/o: output synthesis signal hStereoDft->q_dft*/
950 : const Word16 output_frame, /* i : output frame length per channel Q0*/
951 : const Word16 spar_flag /* i : SPAR flag Q0*/
952 : )
953 : {
954 : Word16 i;
955 : Word16 dftOvlLen;
956 : Word16 win_in, win_out;
957 : Word32 tmp;
958 : const Word16 *win_dft;
959 :
960 1833 : IF( spar_flag )
961 : {
962 1475 : win_dft = hStereoDft->win32ms_fx; /*Q15*/
963 1475 : dftOvlLen = hStereoDft->dft32ms_ovl; /*Q0*/
964 :
965 : Word32 g_W_1, g_Y_1;
966 : Word32 g_W_2, g_Y_2;
967 : Word32 g_L, g_R;
968 : Word32 stefi_L, stefi_R;
969 :
970 1475 : g_W_1 = L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[0][1][8], 0x147B ),
971 : L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[0][2][8], 0x147B ),
972 : L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[0][3][8], 0x147B ),
973 : L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[0][1][9], 0x147B ),
974 : L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[0][2][9], 0x147B ),
975 : L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[0][3][9], 0x147B ),
976 : L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[0][1][10], 0x147B ),
977 : L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[0][2][10], 0x147B ),
978 : Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[0][3][10], 0x147B ) ) ) ) ) ) ) ) ); /*Q31*/
979 :
980 1475 : g_Y_1 = L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[1][1][8], 0x147B ),
981 : L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[1][2][8], 0x147B ),
982 : L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[1][3][8], 0x147B ),
983 : L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[1][1][9], 0x147B ),
984 : L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[1][2][9], 0x147B ),
985 : L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[1][3][9], 0x147B ),
986 : L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[1][1][10], 0x147B ),
987 : L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[1][2][10], 0x147B ),
988 : Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[1][3][10], 0x147B ) ) ) ) ) ) ) ) ); /*Q31*/
989 :
990 1475 : g_W_2 = L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[0][1][8 + IVAS_MAX_NUM_BANDS], 0x147B ),
991 : L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[0][2][8 + IVAS_MAX_NUM_BANDS], 0x147B ),
992 : L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[0][3][8 + IVAS_MAX_NUM_BANDS], 0x147B ),
993 : L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[0][1][9 + IVAS_MAX_NUM_BANDS], 0x147B ),
994 : L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[0][2][9 + IVAS_MAX_NUM_BANDS], 0x147B ),
995 : L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[0][3][9 + IVAS_MAX_NUM_BANDS], 0x147B ),
996 : L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[0][1][10 + IVAS_MAX_NUM_BANDS], 0x147B ),
997 : L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[0][2][10 + IVAS_MAX_NUM_BANDS], 0x147B ),
998 : Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[0][3][10 + IVAS_MAX_NUM_BANDS], 0x147B ) ) ) ) ) ) ) ) ); /*Q31*/
999 :
1000 1475 : g_Y_2 = L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[1][1][8 + IVAS_MAX_NUM_BANDS], 0x147B ),
1001 : L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[1][2][8 + IVAS_MAX_NUM_BANDS], 0x147B ),
1002 : L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[1][3][8 + IVAS_MAX_NUM_BANDS], 0x147B ),
1003 : L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[1][1][9 + IVAS_MAX_NUM_BANDS], 0x147B ),
1004 : L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[1][2][9 + IVAS_MAX_NUM_BANDS], 0x147B ),
1005 : L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[1][3][9 + IVAS_MAX_NUM_BANDS], 0x147B ),
1006 : L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[1][1][10 + IVAS_MAX_NUM_BANDS], 0x147B ),
1007 : L_add( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[1][2][10 + IVAS_MAX_NUM_BANDS], 0x147B ),
1008 : Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[1][3][10 + IVAS_MAX_NUM_BANDS], 0x147B ) ) ) ) ) ) ) ) ); /*Q31*/
1009 :
1010 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*/
1011 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*/
1012 159325 : FOR( i = 0; i < dftOvlLen; i++ )
1013 : {
1014 157850 : win_in = mult_r( win_dft[STEREO_DFT32MS_STEP * i], win_dft[STEREO_DFT32MS_STEP * i] ); /*Q15*/
1015 157850 : win_out = sub( MAX_16, win_in ); /*Q15*/
1016 :
1017 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*/
1018 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*/
1019 :
1020 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*/
1021 157850 : move32();
1022 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*/
1023 157850 : move32();
1024 : }
1025 853865 : FOR( i = dftOvlLen; i < output_frame; i++ )
1026 : {
1027 :
1028 852390 : stefi_L = L_shr( Mpy_32_32( g_L, hStereoDft->hb_stefi_sig_fx[i] ), 1 ); /*hStereoDft->q_hb_stefi_sig_fx*/
1029 852390 : stefi_R = L_shr( Mpy_32_32( g_R, hStereoDft->hb_stefi_sig_fx[i] ), 1 ); /*hStereoDft->q_hb_stefi_sig_fx*/
1030 :
1031 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*/
1032 852390 : move32();
1033 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*/
1034 852390 : move32();
1035 : }
1036 1475 : hStereoDft->g_L_prev_fx = g_L; /*Q31*/
1037 1475 : move32();
1038 1475 : hStereoDft->g_R_prev_fx = g_R; /*Q31*/
1039 1475 : move32();
1040 : }
1041 358 : ELSE IF( L_max( hStereoDft->td_gain_fx[0], hStereoDft->td_gain_fx[1] ) > 0 )
1042 : {
1043 327 : win_dft = hStereoDft->win32ms_fx; /*Q15*/
1044 327 : dftOvlLen = hStereoDft->dft32ms_ovl; /*Q0*/
1045 :
1046 49327 : FOR( i = 0; i < dftOvlLen; i++ )
1047 : {
1048 49000 : win_in = mult( win_dft[STEREO_DFT32MS_STEP * i], win_dft[STEREO_DFT32MS_STEP * i] ); /*Q15*/
1049 49000 : win_out = sub( MAX_16, win_in ); /*Q15*/
1050 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*/
1051 :
1052 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*/
1053 49000 : move32();
1054 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*/
1055 49000 : move32();
1056 : }
1057 264927 : FOR( i = dftOvlLen; i < output_frame; i++ )
1058 : {
1059 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*/
1060 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*/
1061 264600 : move32();
1062 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*/
1063 264600 : move32();
1064 : }
1065 : }
1066 :
1067 1833 : return;
1068 : }
1069 :
1070 :
1071 : /*-------------------------------------------------------------------*
1072 : * ivas_sba_dirac_stereo_smooth_parameters_fx()
1073 : *
1074 : * Smooth DFT Stereo parameters
1075 : *-------------------------------------------------------------------*/
1076 :
1077 10753 : void ivas_sba_dirac_stereo_smooth_parameters_fx(
1078 : STEREO_DFT_DEC_DATA_HANDLE hStereoDft, /* i/o: decoder DFT stereo handle */
1079 : ivas_spar_md_dec_state_t *hMdDec, /* i/o: SPAR MD handle for upmixing */
1080 : const Word16 cross_fade_start_offset, /* i : SPAR mixer delay compensation Q0*/
1081 : const Word32 output_Fs, /* i : Fs for delay calculation Q0*/
1082 : const Word16 num_md_sub_frames /* i : number of subframes in mixing matrix Q0*/
1083 : )
1084 : {
1085 : Word16 i, j, k, i_sf;
1086 : Word16 b;
1087 : Word16 k_offset;
1088 : Word32 *side_gain, *prev_side_gain;
1089 : Word32 *res_pred_gain, *prev_res_pred_gain;
1090 :
1091 10753 : k_offset = STEREO_DFT_OFFSET;
1092 10753 : move16();
1093 10753 : prev_side_gain = hStereoDft->side_gain_fx; /*Q31*/
1094 10753 : side_gain = hStereoDft->side_gain_fx + k_offset * STEREO_DFT_BAND_MAX; /*Q31*/
1095 10753 : prev_res_pred_gain = hStereoDft->res_pred_gain_fx; /*Q31*/
1096 10753 : res_pred_gain = hStereoDft->res_pred_gain_fx + k_offset * STEREO_DFT_BAND_MAX; /*Q31*/
1097 :
1098 10753 : IF( !hMdDec )
1099 : {
1100 : /* Smoothing of side and prediction gains between ftrames */
1101 7032 : FOR( b = hStereoDft->res_pred_band_min; b < hStereoDft->nbands; b++ )
1102 : {
1103 5860 : IF( hStereoDft->attackPresent )
1104 : {
1105 0 : res_pred_gain[b] = Mpy_32_16_1( res_pred_gain[b], (Word16) 0x6666 /*0.8f in Q15*/ ); /*Q31*/
1106 0 : move32();
1107 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*/
1108 0 : move32();
1109 : }
1110 : ELSE
1111 : {
1112 5860 : side_gain[b] = Madd_32_16( Mpy_32_16_1( prev_side_gain[b], hStereoDft->smooth_fac_fx[0][b] ),
1113 5860 : side_gain[b], sub( (Word16) 0x7FFF /*1.0f in Q15*/, hStereoDft->smooth_fac_fx[0][b] ) ); /*Q31*/
1114 5860 : move32();
1115 5860 : side_gain[b + STEREO_DFT_BAND_MAX] = Madd_32_16( Mpy_32_16_1( side_gain[b], hStereoDft->smooth_fac_fx[1][b] ),
1116 5860 : side_gain[b + STEREO_DFT_BAND_MAX],
1117 5860 : sub( (Word16) 0x7FFF /*1.0f in Q15*/, hStereoDft->smooth_fac_fx[1][b] ) ); /*Q31*/
1118 5860 : move32();
1119 5860 : res_pred_gain[b] = Madd_32_16( Mpy_32_16_1( prev_res_pred_gain[b], hStereoDft->smooth_fac_fx[0][b] ),
1120 5860 : res_pred_gain[b],
1121 5860 : sub( (Word16) 0x7FFF /*1.0f in Q15*/, hStereoDft->smooth_fac_fx[0][b] ) ); /*Q31*/
1122 5860 : move32();
1123 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] ),
1124 5860 : res_pred_gain[b + STEREO_DFT_BAND_MAX],
1125 5860 : sub( (Word16) 0x7FFF /*1.0f in Q15*/, hStereoDft->smooth_fac_fx[1][b] ) ); /*Q31*/
1126 5860 : move32();
1127 : }
1128 : }
1129 : }
1130 :
1131 10753 : IF( hMdDec != 0 )
1132 : {
1133 : Word64 xfade_start_ns;
1134 : Word16 xfade_delay_subframes;
1135 : Word16 i_hist;
1136 : Word16 md_sf;
1137 :
1138 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 ) );
1139 : /*
1140 : 64-bit container is needed for storing the result in the previous step.
1141 : ToDo: Replace the 64-bit division below with appropriate BASOP
1142 : */
1143 9581 : xfade_delay_subframes = (Word16) ( xfade_start_ns / W_mult_32_32( ( FRAME_SIZE_NS / MAX_PARAM_SPATIAL_SUBFRAMES ), output_Fs ) ); /*Q0*/
1144 9581 : move16();
1145 9581 : i_hist = sub( (Word16) 4, xfade_delay_subframes ); /*Q0*/
1146 9581 : move16();
1147 28743 : FOR( k = 0; k < 2; k++ )
1148 : {
1149 57486 : FOR( i_sf = ( k * 2 ); i_sf < ( k + 1 ) * 2; i_sf++ )
1150 : {
1151 38324 : md_sf = 0;
1152 38324 : move16();
1153 :
1154 38324 : IF( EQ_16( num_md_sub_frames, MAX_PARAM_SPATIAL_SUBFRAMES ) )
1155 : {
1156 31032 : md_sf = i_sf; /*Q0*/
1157 31032 : move16();
1158 : }
1159 38324 : IF( hStereoDft->first_frame )
1160 : {
1161 1092 : FOR( i = 0; i < 2; i++ )
1162 : {
1163 3640 : FOR( j = 0; j < 4; j++ )
1164 : {
1165 36800 : FOR( b = 0; b < hStereoDft->nbands; b++ )
1166 : {
1167 : // The Q format of mixer_mat_fx is Q30 so applying the left shift.
1168 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*/
1169 33888 : move32();
1170 : }
1171 3968 : FOR( ; b < IVAS_MAX_NUM_BANDS; b++ )
1172 : {
1173 1056 : hStereoDft->mixer_mat_smooth_fx[i][j][( b + ( k * IVAS_MAX_NUM_BANDS ) )] = 0;
1174 1056 : move32();
1175 : }
1176 : }
1177 : }
1178 : }
1179 : ELSE
1180 : {
1181 113880 : FOR( i = 0; i < 2; i++ )
1182 : {
1183 379600 : FOR( j = 0; j < 4; j++ )
1184 : {
1185 3757824 : FOR( b = 0; b < hStereoDft->nbands; b++ )
1186 : {
1187 3454144 : Word16 beta = hStereoDft->smooth_fac_fx[k][b]; /*Q15*/
1188 3454144 : move16();
1189 : // The Q format of mixer_mat_prev_fx is Q30 so applying the left shift.
1190 6908288 : hStereoDft->mixer_mat_smooth_fx[i][j][b + k * IVAS_MAX_NUM_BANDS] =
1191 3454144 : L_add_sat( Mpy_32_16_1( hStereoDft->mixer_mat_smooth_fx[i][j][( b + ( k * IVAS_MAX_NUM_BANDS ) )], beta ),
1192 3454144 : L_shl_sat( Mpy_32_16_1( hMdDec->mixer_mat_prev_fx[i_hist][i][j][b], sub( (Word16) 0x7FFF, beta ) ), Q1 ) ); /*Q31*/
1193 3454144 : move32();
1194 : }
1195 : }
1196 : }
1197 : }
1198 :
1199 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*/
1200 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*/
1201 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*/
1202 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*/
1203 :
1204 114972 : FOR( i = 0; i < 2; i++ )
1205 : {
1206 383240 : FOR( j = 0; j < 4; j++ )
1207 : {
1208 3794624 : FOR( b = 0; b < hStereoDft->nbands; b++ )
1209 : {
1210 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*/
1211 3488032 : move32();
1212 : }
1213 : }
1214 : }
1215 : }
1216 : }
1217 :
1218 9581 : hStereoDft->first_frame = 0;
1219 9581 : move16();
1220 : }
1221 :
1222 10753 : return;
1223 : }
1224 :
1225 :
1226 : /*-------------------------------------------------------------------*
1227 : * ivas_sba_dirac_stereo_dec_fx()
1228 : *
1229 : * Create stereo output for SBA DirAC via DFT stereo
1230 : *-------------------------------------------------------------------*/
1231 :
1232 10790 : void ivas_sba_dirac_stereo_dec_fx(
1233 : Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
1234 : Word32 *output[CPE_CHANNELS], /* i/o: output synthesis signal */
1235 : const Word16 output_frame, /* i : output frame length per channel Q0*/
1236 : const Word16 mcmasa /* i : McMASA flag Q0*/
1237 : )
1238 : {
1239 : Word16 dtx_flag, fd_cng_flag;
1240 : Word16 sba_mono_flag;
1241 : Word16 memOffset;
1242 : Word32 tmp_buf[NS2SA( 48000, IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS )];
1243 : Word32 tmp_synth[L_FRAME16k];
1244 : Word32 hb_gain[NB_DIV];
1245 : Word32 hb_synth_stereo[CPE_CHANNELS][L_FRAME48k];
1246 : Word32 DFT[CPE_CHANNELS][STEREO_DFT_BUF_MAX];
1247 10790 : Word16 q_dft[2] = { 0, 0 };
1248 10790 : Word16 q = 0;
1249 10790 : Word16 q_synth = 0;
1250 10790 : move16();
1251 : SCE_DEC_HANDLE hSCE;
1252 : CPE_DEC_HANDLE hCPE;
1253 : STEREO_DFT_DEC_DATA_HANDLE hStereoDft;
1254 :
1255 32370 : FOR( Word16 i = 0; i < CPE_CHANNELS; i++ )
1256 : {
1257 21580 : set32_fx( DFT[i], 0, STEREO_DFT_BUF_MAX );
1258 : }
1259 :
1260 10790 : hSCE = st_ivas->hSCE[0];
1261 10790 : hCPE = st_ivas->hCPE[0];
1262 10790 : hStereoDft = hCPE->hStereoDft;
1263 10790 : q = hCPE->hStereoDft->q_dft;
1264 10790 : move16();
1265 10790 : q_dft[0] = hCPE->hStereoDft->q_dft;
1266 10790 : move16();
1267 10790 : q_dft[1] = hCPE->hStereoDft->q_dft;
1268 10790 : move16();
1269 :
1270 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*/
1271 10790 : IF( hSCE != NULL )
1272 : {
1273 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*/
1274 4511 : hSCE->q_prev_hb_synth_fx = hCPE->hStereoDft->q_dft;
1275 4511 : move16();
1276 : }
1277 :
1278 10790 : test();
1279 10790 : IF( GT_16( st_ivas->nchan_transport, 1 ) && !mcmasa )
1280 : {
1281 6279 : dtx_flag = 0;
1282 6279 : move16();
1283 6279 : fd_cng_flag = 0;
1284 6279 : move16();
1285 : }
1286 : ELSE
1287 : {
1288 4511 : dtx_flag = (Word16) LE_32( hSCE->hCoreCoder[0]->core_brate, SID_2k40 ); /*Q0*/
1289 4511 : move16();
1290 4511 : test();
1291 4511 : fd_cng_flag = ( dtx_flag && EQ_16( hSCE->hCoreCoder[0]->cng_type, FD_CNG ) ); /*Q0*/
1292 4511 : move16();
1293 : }
1294 10790 : sba_mono_flag = (Word16) EQ_16( st_ivas->hDecoderConfig->nchan_out, 1 );
1295 10790 : move16();
1296 :
1297 10790 : memOffset = NS2SA_FX2( L_mult0( output_frame, FRAMES_PER_SEC ), IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS );
1298 10790 : move16();
1299 :
1300 10790 : ivas_sba_dirac_stereo_config( hStereoDft->hConfig );
1301 10790 : test();
1302 10790 : test();
1303 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 ) );
1304 10790 : stereo_dft_dec_update_fx( hStereoDft, output_frame, 1 /*st_ivas->sba_dirac_stereo_flag*/ );
1305 10790 : IF( GT_16( st_ivas->nchan_transport, 1 ) )
1306 : {
1307 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] );
1308 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] );
1309 6279 : hStereoDft->core_hist[0] = hCPE->hCoreCoder[0]->core;
1310 6279 : move16();
1311 : }
1312 : ELSE
1313 : {
1314 : /* nrg calculation for TD Stereo Filling, as done in ICBWE which is not used in this case */
1315 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 );
1316 :
1317 : /* do DFT Stereo core switching (including DFT analysis) here as CPE element was not available in SCE decoder */
1318 4511 : Copy32( hSCE->save_synth_fx, tmp_synth, hSCE->hCoreCoder[0]->L_frame ); /*hSCE->q_save_synth_fx*/
1319 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] );
1320 :
1321 : /* do updates here after skipping this in SCE decoder (needs to be done after core switching) */
1322 4511 : ivas_updt_dec_common_fx( hSCE->hCoreCoder[0], NORMAL_HQ_CORE, -1, hSCE->save_synth_fx, q );
1323 :
1324 4511 : q_synth = sub( getScaleFactor32( tmp_synth, hSCE->hCoreCoder[0]->L_frame ), 10 );
1325 4511 : scale_sig32( tmp_synth, hSCE->hCoreCoder[0]->L_frame, q_synth ); /*hSCE->q_save_synth_fx + q_synth*/
1326 4511 : q_synth = add( q_synth, hSCE->q_save_synth_fx );
1327 : }
1328 :
1329 : /* mapping of DirAC parameters (azimuth, elevation, diffuseness) to DFT Stereo parameters (side gain, prediction gain) */
1330 10790 : test();
1331 10790 : test();
1332 10790 : test();
1333 10790 : test();
1334 32370 : map_params_dirac_to_stereo( hStereoDft, st_ivas->hQMetaData, tmp_synth, DFT[0], st_ivas->ivas_format == MC_FORMAT,
1335 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,
1336 10790 : ( ( NE_16( st_ivas->ivas_format, SBA_FORMAT ) && NE_16( st_ivas->ivas_format, SBA_ISM_FORMAT ) ) || mcmasa ), hSCE != NULL ? q_synth : 0 );
1337 :
1338 10790 : IF( ( EQ_32( st_ivas->ivas_format, SBA_FORMAT ) || EQ_32( st_ivas->ivas_format, SBA_ISM_FORMAT ) ) && !mcmasa )
1339 : {
1340 9610 : set32_fx( hStereoDft->res_pred_gain_fx, MAX_32, 3 * STEREO_DFT_BAND_MAX ); /*Q31*/
1341 : }
1342 :
1343 : /* DFT Stereo upmix */
1344 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,
1345 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 ) );
1346 :
1347 : /* DFT synthesis */
1348 10790 : stereo_dft_dec_synthesize_fx( hCPE, DFT, 0, output[0], output_frame );
1349 10790 : IF( !sba_mono_flag )
1350 : {
1351 10180 : stereo_dft_dec_synthesize_fx( hCPE, DFT, 1, output[1], output_frame );
1352 : }
1353 :
1354 10790 : synchro_synthesis_fx( st_ivas->hDecoderConfig->ivas_total_brate, hCPE, output, output_frame, 1 /*st_ivas->sba_dirac_stereo_flag*/, q_dft[0] );
1355 :
1356 : /* output scaling */
1357 10790 : IF( !sba_mono_flag )
1358 : {
1359 10180 : v_shr( output[0], 1, output[0], output_frame ); /*0.5f*/
1360 10180 : v_shr( output[1], 1, output[1], output_frame ); /*0.5f*/
1361 : }
1362 :
1363 : /* delay HB synth */
1364 10790 : IF( EQ_16( st_ivas->nchan_transport, 1 ) )
1365 : {
1366 4511 : Copy32( hSCE->save_hb_synth_fx + output_frame - memOffset, tmp_buf, memOffset ); /*hSCE->q_save_hb_synth_fx*/
1367 4511 : Copy32( hSCE->save_hb_synth_fx, hSCE->save_hb_synth_fx + memOffset, sub( output_frame, memOffset ) ); /*hSCE->q_save_hb_synth_fx*/
1368 4511 : Copy32( hSCE->prev_hb_synth_fx, hSCE->save_hb_synth_fx, memOffset ); /*hSCE->q_prev_hb_synth_fx*/
1369 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*/
1370 : }
1371 :
1372 10790 : test();
1373 10790 : test();
1374 10790 : test();
1375 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 ) )
1376 : {
1377 : /* upmix ACELP BWE */
1378 2044 : ivas_sba_dirac_stereo_compute_hb_gain( hStereoDft, hb_gain );
1379 :
1380 2044 : test();
1381 2044 : test();
1382 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 );
1383 :
1384 : /* add HB to ACELP core */
1385 2044 : v_add_fx( output[0], hb_synth_stereo[0], output[0], output_frame ); /*q*/
1386 2044 : IF( !sba_mono_flag )
1387 : {
1388 1833 : v_add_fx( output[1], hb_synth_stereo[1], output[1], output_frame ); /*q*/
1389 :
1390 : /* apply TD Stereo Filling as is done in ICBWE */
1391 1833 : test();
1392 1833 : test();
1393 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 ) );
1394 : }
1395 : }
1396 :
1397 : /* reset the other channels to 0 (they are not used since here) */
1398 18151 : FOR( Word16 ch = CPE_CHANNELS; ch < st_ivas->nchan_transport; ch++ )
1399 : {
1400 7361 : set32_fx( output[ch], 0, output_frame );
1401 : }
1402 :
1403 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*/
1404 10790 : IF( hSCE != NULL )
1405 : {
1406 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*/
1407 4511 : hSCE->q_prev_hb_synth_fx = Q11;
1408 4511 : move16();
1409 : }
1410 :
1411 10790 : return;
1412 : }
|