Line data Source code
1 : /******************************************************************************************************
2 :
3 : (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
4 : Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
5 : Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
6 : Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
7 : contributors to this repository. All Rights Reserved.
8 :
9 : This software is protected by copyright law and by international treaties.
10 : The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
11 : Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
12 : Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
13 : Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
14 : contributors to this repository retain full ownership rights in their respective contributions in
15 : the software. This notice grants no license of any kind, including but not limited to patent
16 : license, nor is any license granted by implication, estoppel or otherwise.
17 :
18 : Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
19 : contributions.
20 :
21 : This software is provided "AS IS", without any express or implied warranties. The software is in the
22 : development stage. It is intended exclusively for experts who have experience with such software and
23 : solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
24 : and fitness for a particular purpose are hereby disclaimed and excluded.
25 :
26 : Any dispute, controversy or claim arising under or in relation to providing this software shall be
27 : submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
28 : accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
29 : the United Nations Convention on Contracts on the International Sales of Goods.
30 :
31 : *******************************************************************************************************/
32 :
33 : #include <stdint.h>
34 : #include "options.h"
35 : #include "prot_fx.h"
36 : #include "ivas_prot_rend_fx.h"
37 : #include "ivas_stat_dec.h"
38 : #include "ivas_cnst.h"
39 : #include <math.h>
40 : #include "wmc_auto.h"
41 : #include "ivas_prot_fx.h"
42 : #ifdef DEBUGGING
43 : #include "debug.h"
44 : #endif
45 :
46 : /*-------------------------------------------------------------------------*
47 : * ivas_sba2MC_cldfb()
48 : *
49 : * SBA signals transformed into MC in CLDFB domain
50 : *-------------------------------------------------------------------------*/
51 :
52 27996 : void ivas_sba2mc_cldfb_fx(
53 : IVAS_OUTPUT_SETUP hInSetup, /* i : Format of input layout */
54 : Word32 RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i/o: cldfb real part (Q_real) */
55 : Word32 ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i/o: cldfb imag part (Q_imag) */
56 : const Word16 nb_channels_out, /* i : nb of output channels Q0*/
57 : const Word16 nb_bands, /* i : nb of CLDFB bands to process Q0*/
58 : const Word16 nb_timeslots, /* i : number of time slots to process Q0*/
59 : const Word32 *hoa_dec_mtx /* i : HOA decoding mtx Q29*/
60 : )
61 : {
62 : Word16 iBlock, iBand, n, m;
63 : Word32 realOut_fx[16][MAX_PARAM_SPATIAL_SUBFRAMES * CLDFB_NO_CHANNELS_MAX], imagOut_fx[16][MAX_PARAM_SPATIAL_SUBFRAMES * CLDFB_NO_CHANNELS_MAX];
64 : Word32 g_fx;
65 : Word32 *p_real_fx, *p_imag_fx, *p_realOut_fx, *p_imagOut_fx;
66 : Word16 nb_channels_in;
67 :
68 27996 : push_wmops( "ivas_sba2mc_cldfb_fx" );
69 27996 : nb_channels_in = hInSetup.nchan_out_woLFE; /*Q0*/
70 27996 : move16();
71 27996 : assert( EQ_16( nb_channels_in, 16 ) && EQ_16( nb_channels_out, 11 ) && "ivas_sba2mc_cldfb_fx; only HOA3 to CICP19 is for now supported!" );
72 :
73 335952 : FOR( n = 0; n < nb_channels_out; n++ )
74 : {
75 307956 : set32_fx( realOut_fx[n], 0, i_mult( MAX_PARAM_SPATIAL_SUBFRAMES, nb_bands ) ); /*Q_real*/
76 307956 : set32_fx( imagOut_fx[n], 0, i_mult( MAX_PARAM_SPATIAL_SUBFRAMES, nb_bands ) ); /*Q_imag*/
77 :
78 5235252 : FOR( m = 0; m < nb_channels_in; m++ )
79 : {
80 4927296 : g_fx = L_shl_sat( hoa_dec_mtx[( ( SBA_NHARM_HOA3 * n ) + m )], Q2 );
81 4927296 : p_realOut_fx = realOut_fx[n];
82 4927296 : p_imagOut_fx = imagOut_fx[n];
83 :
84 24636480 : FOR( iBlock = 0; iBlock < nb_timeslots; iBlock++ )
85 : {
86 19709184 : p_real_fx = RealBuffer[m][iBlock]; /*Q_real*/
87 19709184 : p_imag_fx = ImagBuffer[m][iBlock]; /*Q_imag*/
88 836208384 : FOR( iBand = 0; iBand < nb_bands; iBand++ )
89 : {
90 816499200 : *p_realOut_fx = Madd_32_32( *p_realOut_fx, g_fx, *( p_real_fx++ ) ); // Q_real
91 816499200 : move32();
92 816499200 : *p_imagOut_fx = Madd_32_32( *p_imagOut_fx, g_fx, *( p_imag_fx++ ) ); // Q_imag
93 816499200 : move32();
94 816499200 : p_realOut_fx++;
95 816499200 : p_imagOut_fx++;
96 : }
97 : }
98 : }
99 : }
100 :
101 335952 : FOR( n = 0; n < nb_channels_out; n++ )
102 : {
103 307956 : p_realOut_fx = realOut_fx[n]; /*Q_real*/
104 307956 : p_imagOut_fx = imagOut_fx[n]; /*Q_imag*/
105 :
106 1539780 : FOR( iBlock = 0; iBlock < nb_timeslots; iBlock++ )
107 : {
108 1231824 : p_real_fx = RealBuffer[n][iBlock]; /*Q_real*/
109 1231824 : p_imag_fx = ImagBuffer[n][iBlock]; /*Q_imag*/
110 52263024 : FOR( iBand = 0; iBand < nb_bands; iBand++ )
111 : {
112 51031200 : *( p_real_fx++ ) = *p_realOut_fx++;
113 51031200 : move32();
114 51031200 : *( p_imag_fx++ ) = *p_imagOut_fx++;
115 51031200 : move32();
116 : }
117 : }
118 : }
119 :
120 27996 : pop_wmops();
121 27996 : return;
122 : }
123 :
124 :
125 : /*-------------------------------------------------------------------------*
126 : * ivas_mc2sba()
127 : *
128 : * MC signals transformed into SBA in TD domain
129 : *-------------------------------------------------------------------------*/
130 :
131 8671 : void ivas_mc2sba_fx(
132 : IVAS_OUTPUT_SETUP hIntSetup, /* i : Format of decoder output */
133 : Word32 *in_buffer_td_fx[], /* i : MC signals (on input) and the HOA3 (on output) Q*/
134 : Word32 *buffer_td_fx[], /* i/o: MC signals (on input) and the HOA3 (on output) Q*/
135 : const Word16 output_frame, /* i : output frame length per channel Q0*/
136 : const Word16 sba_order, /* i : Ambisonic (SBA) order Q0*/
137 : const Word16 gain_lfe_fx /* i : gain for LFE, 0 = ignore LFE Q14*/
138 : )
139 : {
140 : Word16 i, j, k;
141 : Word16 idx_lfe, idx_in;
142 : Word32 buffer_tmp_fx[16][L_FRAME48k];
143 : Word32 gains_fx[16];
144 : Word16 azimuth, elevation;
145 : Word16 sba_num_chans;
146 :
147 8671 : assert( ( LE_16( sba_order, 3 ) ) && "Only order up to 3 is supported!" );
148 : /* Init*/
149 8671 : sba_num_chans = imult1616( add( sba_order, 1 ), add( sba_order, 1 ) );
150 62159 : FOR( j = 0; j < sba_num_chans; j++ )
151 : {
152 53488 : set32_fx( buffer_tmp_fx[j], 0, output_frame );
153 : }
154 :
155 : /* HOA encoding*/
156 8671 : idx_lfe = 0;
157 8671 : idx_in = 0;
158 8671 : move16();
159 8671 : move16();
160 106723 : FOR( i = 0; i < ( hIntSetup.nchan_out_woLFE + hIntSetup.num_lfe ); i++ )
161 : {
162 98052 : test();
163 98052 : IF( ( hIntSetup.num_lfe > 0 ) && EQ_16( i, hIntSetup.index_lfe[idx_lfe] ) )
164 : {
165 8671 : IF( gain_lfe_fx > 0 )
166 : {
167 : /* Add LFE to omni W with gain*/
168 203973 : FOR( k = 0; k < output_frame; k++ )
169 : {
170 203760 : buffer_tmp_fx[0][k] = Madd_32_16( buffer_tmp_fx[0][k], L_shl( in_buffer_td_fx[i][k], 1 ), gain_lfe_fx ); /*Q+14-15+1==Q*/
171 203760 : move32();
172 : }
173 : }
174 :
175 8671 : if ( LT_16( idx_lfe, sub( hIntSetup.num_lfe, 1 ) ) )
176 : {
177 0 : idx_lfe = add( idx_lfe, 1 ); /*Q0*/
178 : }
179 : }
180 : ELSE
181 : {
182 89381 : azimuth = extract_l( L_shr( hIntSetup.ls_azimuth_fx[idx_in], Q22 ) ); /*Q0*/
183 89381 : move16();
184 89381 : elevation = extract_l( L_shr( hIntSetup.ls_elevation_fx[idx_in], Q22 ) ); /*Q0*/
185 89381 : move16();
186 89381 : idx_in = add( idx_in, 1 ); /*Q0*/
187 89381 : ivas_dirac_dec_get_response_fx(
188 : azimuth,
189 : elevation,
190 : gains_fx, /*Q-29*/
191 : sba_order,
192 : Q29 );
193 : /* get HOA response for direction (ACN/SN3D)*/
194 :
195 581749 : FOR( j = 0; j < sba_num_chans; j++ )
196 : {
197 363552848 : FOR( k = 0; k < output_frame; k++ )
198 : {
199 363060480 : buffer_tmp_fx[j][k] = Madd_32_32( buffer_tmp_fx[j][k], L_shl_sat( in_buffer_td_fx[i][k], 2 ), gains_fx[j] ); /*Q+29-31+2==Q*/
200 363060480 : move32();
201 : }
202 : }
203 : }
204 : }
205 :
206 62159 : FOR( j = 0; j < sba_num_chans; j++ )
207 : {
208 53488 : Copy32( buffer_tmp_fx[j], buffer_td_fx[j], output_frame ); /*Q*/
209 : }
210 :
211 8671 : return;
212 : }
213 :
214 :
215 : /*-------------------------------------------------------------------------*
216 : * ivas_param_mc_mc2sba_cldfb()
217 : *
218 : * MC signals transformed into SBA in CLDFB domain
219 : * used for binaural rendering with head rotation
220 : *-------------------------------------------------------------------------*/
221 :
222 58723 : void ivas_param_mc_mc2sba_cldfb_fx(
223 : IVAS_OUTPUT_SETUP hTransSetup, /* i : transported MC Format */
224 : Word32 *hoa_encoder_fx, /* i : HOA3 encoder for the transported MC format Q31*/
225 : const Word16 slot_idx, /* i : current slot in the subframe Q0*/
226 : Word32 Cldfb_RealBuffer_fx[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i/o: Contains the MC signals (on input) and the HOA3 (on output) Q_Cldfb_RealBuffer*/
227 : Word32 Cldfb_ImagBuffer_fx[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i/o: Contains the MC signals (on input) and the HOA3 (on output) Q_Cldfb_ImagBuffer*/
228 : const Word16 nBands, /* i : number of synth CLDFB bands Q0*/
229 : const Word16 gain_lfe_fx /* i : gain applied to LFE Q14*/
230 : )
231 : {
232 : Word16 idx_ch, idx_band;
233 : Word16 idx_lfe, idx_in, idx_out;
234 : Word32 Cldfb_RealBuffer_tmp_fx[MAX_INTERN_CHANNELS][CLDFB_NO_CHANNELS_MAX];
235 : Word32 Cldfb_ImagBuffer_tmp_fx[MAX_INTERN_CHANNELS][CLDFB_NO_CHANNELS_MAX];
236 : Word32 *gains_fx;
237 : Word16 sba_num_chans;
238 :
239 : /* Init*/
240 58723 : sba_num_chans = MAX_INTERN_CHANNELS;
241 58723 : move16();
242 998291 : FOR( idx_ch = 0; idx_ch < sba_num_chans; idx_ch++ )
243 : {
244 939568 : set32_fx( Cldfb_RealBuffer_tmp_fx[idx_ch], 0, CLDFB_NO_CHANNELS_MAX );
245 939568 : set32_fx( Cldfb_ImagBuffer_tmp_fx[idx_ch], 0, CLDFB_NO_CHANNELS_MAX );
246 : }
247 :
248 58723 : idx_lfe = 0;
249 58723 : idx_in = 0;
250 58723 : move16();
251 58723 : move16();
252 :
253 461307 : FOR( idx_ch = 0; idx_ch < ( hTransSetup.nchan_out_woLFE + hTransSetup.num_lfe ); idx_ch++ )
254 : {
255 402584 : test();
256 402584 : IF( ( hTransSetup.num_lfe > 0 ) && EQ_16( idx_ch, hTransSetup.index_lfe[idx_lfe] ) )
257 : {
258 58723 : IF( gain_lfe_fx > 0 )
259 : {
260 : /* Add LFE to Omni Channel i.e. W (Just first Band) */
261 58723 : Cldfb_RealBuffer_tmp_fx[0][0] = L_add_sat( Cldfb_RealBuffer_tmp_fx[0][0], Mult_32_16( L_shl( Cldfb_RealBuffer_fx[idx_ch][slot_idx][0], 1 ), gain_lfe_fx ) ); /*Q_Cldfb_RealBuffer*/
262 58723 : move32();
263 58723 : Cldfb_ImagBuffer_tmp_fx[0][0] = L_add_sat( Cldfb_ImagBuffer_tmp_fx[0][0], Mult_32_16( L_shl( Cldfb_ImagBuffer_fx[idx_ch][slot_idx][0], 1 ), gain_lfe_fx ) ); /*Q_Cldfb_ImagBuffer*/
264 58723 : move32();
265 : }
266 :
267 58723 : if ( LT_16( idx_lfe, sub( hTransSetup.num_lfe, 1 ) ) )
268 : {
269 0 : idx_lfe = add( idx_lfe, 1 ); /*Q0*/
270 : }
271 : }
272 : ELSE
273 : {
274 343861 : gains_fx = hoa_encoder_fx + imult1616( idx_in, sba_num_chans ); /*Pointer addition*/ /*Q31*/
275 5845637 : FOR( idx_out = 0; idx_out < sba_num_chans; idx_out++ )
276 : {
277 291672016 : FOR( idx_band = 0; idx_band < nBands; idx_band++ )
278 : {
279 286170240 : Cldfb_RealBuffer_tmp_fx[idx_out][idx_band] = L_add( Cldfb_RealBuffer_tmp_fx[idx_out][idx_band], Mult_32_32( ( *gains_fx ), Cldfb_RealBuffer_fx[idx_ch][slot_idx][idx_band] ) ); /*Q_Cldfb_RealBuffer*/
280 286170240 : move32();
281 286170240 : Cldfb_ImagBuffer_tmp_fx[idx_out][idx_band] = L_add( Cldfb_ImagBuffer_tmp_fx[idx_out][idx_band], Mult_32_32( ( *gains_fx ), Cldfb_ImagBuffer_fx[idx_ch][slot_idx][idx_band] ) ); /*Q_Cldfb_ImagBuffer*/
282 286170240 : move32();
283 : }
284 5501776 : gains_fx++;
285 : }
286 343861 : idx_in = add( idx_in, 1 ); /*Q0*/
287 : }
288 : }
289 998291 : FOR( idx_ch = 0; idx_ch < sba_num_chans; idx_ch++ )
290 : {
291 939568 : Copy32( Cldfb_RealBuffer_tmp_fx[idx_ch], Cldfb_RealBuffer_fx[idx_ch][slot_idx], nBands ); /*Q_Cldfb_RealBuffer*/
292 939568 : Copy32( Cldfb_ImagBuffer_tmp_fx[idx_ch], Cldfb_ImagBuffer_fx[idx_ch][slot_idx], nBands ); /*Q_Cldfb_ImagBuffer*/
293 : }
294 :
295 58723 : return;
296 : }
297 :
298 :
299 : /*-------------------------------------------------------------------*
300 : * ivas_sba_remapTCs()
301 : *
302 : * Get TCs from Ambisonics signal in ACN
303 : *-------------------------------------------------------------------*/
304 :
305 : /*! r: SBA DirAC stereo flag */
306 158813 : Word16 ivas_sba_remapTCs_fx(
307 : Word32 *sba_data_fx[], /* i/o: SBA signals Q11*/
308 : Decoder_Struct *st_ivas, /* i/o: decoder struct */
309 : const Word16 output_frame /* i : frame length Q0*/
310 : )
311 : {
312 : Word16 nchan_remapped;
313 158813 : nchan_remapped = st_ivas->nchan_transport; /*Q0*/
314 158813 : move16();
315 158813 : IF( EQ_16( nchan_remapped, 3 ) )
316 : {
317 33766 : nchan_remapped = add( nchan_remapped, 1 ); /*Q0*/
318 33766 : IF( EQ_16( nchan_remapped, 4 ) )
319 : {
320 33766 : Copy32( sba_data_fx[2], sba_data_fx[3], output_frame ); /*Q11*/
321 : }
322 : }
323 158813 : IF( GE_16( st_ivas->nchan_transport, 3 ) )
324 : {
325 74935 : Word16 i = 0;
326 74935 : move16();
327 : Word32 temp_fx;
328 :
329 : /*convert WYXZ downmix to WYZX*/
330 61700535 : FOR( i = 0; i < output_frame; i++ )
331 : {
332 61625600 : temp_fx = sba_data_fx[2][i]; /*Q11*/
333 61625600 : move32();
334 61625600 : sba_data_fx[2][i] = sba_data_fx[3][i]; /*Q11*/
335 61625600 : move32();
336 61625600 : sba_data_fx[3][i] = temp_fx; /*Q11*/
337 61625600 : move32();
338 :
339 61625600 : if ( EQ_16( st_ivas->nchan_transport, 3 ) )
340 : {
341 26986560 : sba_data_fx[2][i] = 0;
342 26986560 : move32();
343 : }
344 : }
345 : }
346 :
347 158813 : return ( nchan_remapped );
348 : }
349 :
350 :
351 : /*-------------------------------------------------------------------------*
352 : * ivas_ism2sba_sf()
353 : *
354 : * ISM transformed into SBA in TD domain.
355 : *-------------------------------------------------------------------------*/
356 :
357 7843 : void ivas_ism2sba_sf_fx(
358 : Word32 *buffer_in_fx[], /* i : TC buffer Q_buffer_in*/
359 : Word32 *buffer_out_fx[], /* o : TD signal buffers Q_buffer_in + 29 - 31*/
360 : ISM_RENDERER_HANDLE hIsmRendererData, /* i/o: renderer data */
361 : const Word16 num_objects, /* i : number of objects Q0*/
362 : const Word16 n_samples_to_render, /* i : output frame length per channel Q0*/
363 : const Word16 offset, /* i : offset for the interpolatr Q0*/
364 : const Word16 sba_order /* i : Ambisonic (SBA) order Q0*/
365 : )
366 : {
367 : Word16 i, j, k;
368 : Word32 buffer_tmp_fx[HOA3_CHANNELS][L_FRAME48k];
369 : Word16 *g2_fx, g1_fx;
370 : Word32 *tc_fx, *out_fx, gain_fx, prev_gain_fx;
371 : Word16 sba_num_chans;
372 :
373 7843 : assert( LE_16( sba_order, 3 ) && "Only order up to 3 is supported!" );
374 7843 : assert( hIsmRendererData != NULL && "hIsmRendererData not allocated!" );
375 : /* Init*/
376 7843 : sba_num_chans = imult1616( add( sba_order, 1 ), add( sba_order, 1 ) ); /*Q0*/
377 79755 : FOR( j = 0; j < sba_num_chans; j++ )
378 : {
379 71912 : set32_fx( buffer_tmp_fx[j], 0, n_samples_to_render );
380 : }
381 32568 : FOR( i = 0; i < num_objects; i++ )
382 : {
383 256797 : FOR( j = 0; j < sba_num_chans; j++ )
384 : {
385 232072 : g2_fx = hIsmRendererData->interpolator_fx + offset; /*Pointer addition*/ /*Q15*/
386 232072 : tc_fx = buffer_in_fx[i]; /*Q_buffer_in*/
387 232072 : out_fx = buffer_tmp_fx[j]; /*Q_buffer_in + 29 - 31*/
388 232072 : gain_fx = hIsmRendererData->gains_fx[i][j]; /*Q29*/
389 232072 : move32();
390 232072 : prev_gain_fx = hIsmRendererData->prev_gains_fx[i][j]; /*Q29*/
391 232072 : move32();
392 183374632 : FOR( k = 0; k < n_samples_to_render; k++ )
393 : {
394 183142560 : g1_fx = sub( 32767, *g2_fx ); /*Q15*/
395 183142560 : *( out_fx ) = Madd_32_32( *( out_fx ), Madd_32_16( Mult_32_16( gain_fx, ( *( g2_fx ) ) ), prev_gain_fx, g1_fx ), ( *( tc_fx ) ) ); /*Q_buffer_in + 29 - 31*/
396 183142560 : move32();
397 183142560 : g2_fx++;
398 183142560 : tc_fx++;
399 183142560 : out_fx++;
400 : }
401 : }
402 : }
403 :
404 79755 : FOR( j = 0; j < sba_num_chans; j++ )
405 : {
406 71912 : Copy32( buffer_tmp_fx[j], buffer_out_fx[j], n_samples_to_render ); /*Q_buffer_in + 29 - 31*/
407 : }
408 :
409 7843 : return;
410 : }
411 :
412 :
413 : /*-------------------------------------------------------------------*
414 : * ivas_sba_linear_renderer()
415 : *
416 : * Linear rendering for SBA format
417 : *-------------------------------------------------------------------*/
418 :
419 63200 : ivas_error ivas_sba_linear_renderer_fx(
420 : Word32 *output_fx[], /* i/o: synthesized core-coder transport channels/DirAC output Q11*/
421 : const Word16 output_frame, /* i : output frame length per channel Q0*/
422 : const Word16 nchan_in, /* i : number of input ambisonics channels Q0*/
423 : const Word16 nchan_ism, /* i : number of objects Q0*/
424 : const AUDIO_CONFIG output_config, /* i : output audio configuration */
425 : const IVAS_OUTPUT_SETUP output_setup /* i : output format setup */
426 : )
427 : {
428 : Word16 i;
429 : Word16 nchan_hoa;
430 : ivas_error error;
431 :
432 63200 : error = IVAS_ERR_OK;
433 63200 : move32();
434 :
435 : /* Number of channels of HOA depends of transport format which is mixed order xH1V*/
436 63200 : nchan_hoa = nchan_in; /*Q0*/
437 63200 : move16();
438 :
439 63200 : IF( EQ_16( nchan_in, 6 ) ) /*2H1V*/
440 : {
441 0 : nchan_hoa = 9;
442 0 : move16();
443 : }
444 63200 : ELSE IF( EQ_16( nchan_in, 8 ) ) /*3H1V*/
445 : {
446 0 : nchan_hoa = 16;
447 0 : move16();
448 : }
449 :
450 63200 : SWITCH( output_config )
451 : {
452 56302 : case IVAS_AUDIO_CONFIG_FOA: /* Ambisonics output, order: 1 */
453 : case IVAS_AUDIO_CONFIG_HOA2: /* Ambisonics output, order: 2 */
454 : case IVAS_AUDIO_CONFIG_HOA3: /* Ambisonics output, order: 3 */
455 56302 : FOR( i = nchan_hoa; i < output_setup.nchan_out_woLFE; i++ )
456 : {
457 0 : set_zero_fx( output_fx[i], output_frame );
458 : }
459 56302 : BREAK;
460 6898 : case IVAS_AUDIO_CONFIG_EXTERNAL:
461 80566 : FOR( i = output_setup.nchan_out_woLFE - 1; i >= nchan_ism; i-- )
462 : {
463 73668 : Copy32( output_fx[i - nchan_ism], output_fx[i], output_frame ); /*Q11*/
464 : }
465 6898 : FOR( ; i >= 0; i-- )
466 : {
467 0 : set_zero_fx( output_fx[i], output_frame );
468 : }
469 6898 : BREAK;
470 0 : default:
471 0 : return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Error: illegal output configuration, Exiting.\n" );
472 : }
473 :
474 63200 : return error;
475 : }
476 :
477 :
478 : /*-------------------------------------------------------------------*
479 : * ivas_sba_mix_matrix_determiner()
480 : *
481 : * Determine SBA mixing matrices
482 : *-------------------------------------------------------------------*/
483 :
484 38555 : void ivas_sba_mix_matrix_determiner_fx(
485 : SPAR_DEC_HANDLE hSpar, /* i/o: SPAR decoder handle */
486 : Word32 *output_fx[], /* i/o: transport/output audio channels Q_output*/
487 : const Word16 bfi, /* i : BFI flag Q0*/
488 : const Word16 nchan_remapped, /* i : num channels after remapping of TCs Q0*/
489 : const Word16 output_frame, /* i : output frame length Q0*/
490 : const Word16 num_md_sub_frames, /* i : number of subframes in mixing matrix Q0*/
491 : const Word16 Q_output /* i : Q of transport/output audio channels */
492 : )
493 : {
494 : Word16 i, ch;
495 : Word16 num_bands_out, nchan_transport, nchan_out;
496 38555 : Word16 Q_p_output = add( 11, Q_output );
497 : Word32 temp_fx;
498 :
499 : /* Convert numeric range */
500 98948 : FOR( ch = 0; ch < nchan_remapped; ch++ )
501 : {
502 41927273 : FOR( i = 0; i < output_frame; i++ )
503 : {
504 41866880 : temp_fx = output_fx[ch][i]; /*Q_output*/
505 41866880 : move32();
506 41866880 : temp_fx = L_shr( temp_fx + L_shl( 1, Q_p_output - 1 ), Q_p_output ); /*Q0*/
507 :
508 41866880 : IF( GT_32( temp_fx, MAX16B ) )
509 : {
510 1 : temp_fx = MAX16B; /*Q0*/
511 1 : move32();
512 : }
513 41866879 : ELSE IF( LT_32( temp_fx, -( PCM16_TO_FLT_FAC_FX ) ) )
514 : {
515 0 : temp_fx = -( PCM16_TO_FLT_FAC_FX ); /*Q0*/
516 0 : move32();
517 : }
518 41866880 : temp_fx = Mult_32_32( MAX_32 / PCM16_TO_FLT_FAC_FX, L_shl( temp_fx, Q_p_output ) ); /*Q_p_output*/
519 41866880 : output_fx[ch][i] = temp_fx; /*Q_p_output*/
520 41866880 : move32();
521 : }
522 : }
523 : /* AGC */
524 38555 : nchan_transport = hSpar->hMdDec->spar_md_cfg.nchan_transport; /*Q0*/
525 38555 : move16();
526 38555 : nchan_out = nchan_transport; /*Q0*/
527 38555 : move16();
528 :
529 38555 : ivas_agc_dec_process_fx( hSpar->hAgcDec, ( output_fx ), ( output_fx ), nchan_transport, output_frame );
530 38555 : Q_p_output = sub( Q_p_output, 3 );
531 : #ifdef DEBUGGING
532 : dbgwrite_txt( (const float *) ( output_fx[0] ), output_frame, "fix_ivas_agc_dec_process_output.txt", NULL );
533 : #endif
534 :
535 : /* Convert numeric range back */
536 98948 : FOR( ch = 0; ch < nchan_out; ch++ )
537 : {
538 41927273 : FOR( i = 0; i < output_frame; i++ )
539 : {
540 41866880 : output_fx[ch][i] = Mult_32_32( L_shl_sat( output_fx[ch][i], sub( 15, Q_p_output ) ), 2147483647 /* PCM16_TO_FLT_FAC_FX << 16 */ ); /* Q0 */
541 : }
542 : }
543 :
544 : /* Mixing matrix determiner */
545 38555 : num_bands_out = hSpar->hFbMixer->pFb->filterbank_num_bands; /*Q0*/
546 38555 : move16();
547 :
548 38555 : ivas_spar_dec_gen_umx_mat_fx( hSpar->hMdDec, nchan_transport, num_bands_out, bfi, num_md_sub_frames );
549 :
550 38555 : return;
551 : }
|