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 28000 : void ivas_sba2mc_cldfb_fixed(
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 28000 : push_wmops( "ivas_sba2mc_cldfb_fixed" );
69 28000 : nb_channels_in = hInSetup.nchan_out_woLFE; /*Q0*/
70 28000 : move16();
71 28000 : assert( EQ_16( nb_channels_in, 16 ) && EQ_16( nb_channels_out, 11 ) && "ivas_sba2mc_cldfb_fixed; only HOA3 to CICP19 is for now supported!" );
72 :
73 336000 : FOR( n = 0; n < nb_channels_out; n++ )
74 : {
75 308000 : set32_fx( realOut_fx[n], 0, i_mult( MAX_PARAM_SPATIAL_SUBFRAMES, nb_bands ) ); /*Q_real*/
76 308000 : set32_fx( imagOut_fx[n], 0, i_mult( MAX_PARAM_SPATIAL_SUBFRAMES, nb_bands ) ); /*Q_imag*/
77 :
78 5236000 : FOR( m = 0; m < nb_channels_in; m++ )
79 : {
80 4928000 : g_fx = hoa_dec_mtx[( ( SBA_NHARM_HOA3 * n ) + m )]; // Q29
81 4928000 : p_realOut_fx = realOut_fx[n];
82 4928000 : p_imagOut_fx = imagOut_fx[n];
83 :
84 24640000 : FOR( iBlock = 0; iBlock < nb_timeslots; iBlock++ )
85 : {
86 19712000 : p_real_fx = RealBuffer[m][iBlock]; /*Q_real*/
87 19712000 : p_imag_fx = ImagBuffer[m][iBlock]; /*Q_imag*/
88 836352000 : FOR( iBand = 0; iBand < nb_bands; iBand++ )
89 : {
90 816640000 : *p_realOut_fx = L_add( *p_realOut_fx, Mpy_32_32( L_shl_sat( g_fx, Q2 ), *( p_real_fx++ ) ) ); // Q_real
91 816640000 : move32();
92 816640000 : *p_imagOut_fx = L_add( *p_imagOut_fx, Mpy_32_32( L_shl_sat( g_fx, Q2 ), *( p_imag_fx++ ) ) ); // Q_imag
93 816640000 : move32();
94 816640000 : p_realOut_fx++;
95 816640000 : p_imagOut_fx++;
96 : }
97 : }
98 : }
99 : }
100 :
101 336000 : FOR( n = 0; n < nb_channels_out; n++ )
102 : {
103 308000 : p_realOut_fx = realOut_fx[n]; /*Q_real*/
104 308000 : p_imagOut_fx = imagOut_fx[n]; /*Q_imag*/
105 :
106 1540000 : FOR( iBlock = 0; iBlock < nb_timeslots; iBlock++ )
107 : {
108 1232000 : p_real_fx = RealBuffer[n][iBlock]; /*Q_real*/
109 1232000 : p_imag_fx = ImagBuffer[n][iBlock]; /*Q_imag*/
110 52272000 : FOR( iBand = 0; iBand < nb_bands; iBand++ )
111 : {
112 51040000 : *( p_real_fx++ ) = *p_realOut_fx++;
113 51040000 : move32();
114 51040000 : *( p_imag_fx++ ) = *p_imagOut_fx++;
115 51040000 : move32();
116 : }
117 : }
118 : }
119 :
120 28000 : pop_wmops();
121 28000 : return;
122 : }
123 :
124 : /*-------------------------------------------------------------------------*
125 : * ivas_mc2sba()
126 : *
127 : * MC signals transformed into SBA in TD domain
128 : *-------------------------------------------------------------------------*/
129 :
130 5816 : void ivas_mc2sba_fx(
131 : IVAS_OUTPUT_SETUP hIntSetup, /* i : Format of decoder output */
132 : Word32 *in_buffer_td_fx[],
133 : /* 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 5816 : assert( ( LE_16( sba_order, 3 ) ) && "Only order up to 3 is supported!" );
148 : /* Init*/
149 5816 : sba_num_chans = imult1616( add( sba_order, 1 ), add( sba_order, 1 ) );
150 47128 : FOR( j = 0; j < sba_num_chans; j++ )
151 : {
152 41312 : set32_fx( buffer_tmp_fx[j], 0, output_frame );
153 : }
154 :
155 : /* HOA encoding*/
156 5816 : idx_lfe = 0;
157 5816 : idx_in = 0;
158 5816 : move16();
159 5816 : move16();
160 69608 : FOR( i = 0; i < ( hIntSetup.nchan_out_woLFE + hIntSetup.num_lfe ); i++ )
161 : {
162 63792 : test();
163 63792 : IF( ( hIntSetup.num_lfe > 0 ) && EQ_16( i, hIntSetup.index_lfe[idx_lfe] ) )
164 : {
165 5816 : IF( gain_lfe_fx > 0 )
166 : {
167 : /* Add LFE to omni W with gain*/
168 144150 : FOR( k = 0; k < output_frame; k++ )
169 : {
170 144000 : buffer_tmp_fx[0][k] = L_add( buffer_tmp_fx[0][k], L_shl( Mult_32_16( in_buffer_td_fx[i][k], gain_lfe_fx ), 1 ) ); /*Q+14-15+1==Q*/
171 144000 : move32();
172 : }
173 : }
174 :
175 5816 : 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 57976 : azimuth = extract_l( L_shr( hIntSetup.ls_azimuth_fx[idx_in], Q22 ) ); /*Q0*/
183 57976 : move16();
184 57976 : elevation = extract_l( L_shr( hIntSetup.ls_elevation_fx[idx_in], Q22 ) ); /*Q0*/
185 57976 : move16();
186 57976 : idx_in = add( idx_in, 1 ); /*Q0*/
187 57976 : 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 416408 : FOR( j = 0; j < sba_num_chans; j++ )
196 : {
197 289287712 : FOR( k = 0; k < output_frame; k++ )
198 : {
199 288929280 : buffer_tmp_fx[j][k] = L_add( buffer_tmp_fx[j][k], L_shl( Mult_32_32( in_buffer_td_fx[i][k], gains_fx[j] ), 2 ) ); /*Q+29-31+2==Q*/
200 288929280 : move32();
201 : }
202 : }
203 : }
204 : }
205 :
206 47128 : FOR( j = 0; j < sba_num_chans; j++ )
207 : {
208 41312 : Copy32( buffer_tmp_fx[j], buffer_td_fx[j], output_frame ); /*Q*/
209 : }
210 :
211 5816 : 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 58080 : void ivas_param_mc_mc2sba_cldfb_fx(
222 : IVAS_OUTPUT_SETUP hTransSetup, /* i : transported MC Format */
223 : Word32 *hoa_encoder_fx, /* i : HOA3 encoder for the transported MC format Q31*/
224 : const Word16 slot_idx, /* i : current slot in the subframe Q0*/
225 : 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*/
226 : 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*/
227 : const Word16 nBands, /* i : number of synth CLDFB bands Q0*/
228 : const Word16 gain_lfe_fx /* i : gain applied to LFE Q14*/
229 : )
230 : {
231 : Word16 idx_ch, idx_band;
232 : Word16 idx_lfe, idx_in, idx_out;
233 : Word32 Cldfb_RealBuffer_tmp_fx[MAX_INTERN_CHANNELS][CLDFB_NO_CHANNELS_MAX];
234 : Word32 Cldfb_ImagBuffer_tmp_fx[MAX_INTERN_CHANNELS][CLDFB_NO_CHANNELS_MAX];
235 : Word32 *gains_fx;
236 : Word16 sba_num_chans;
237 :
238 : /* Init*/
239 58080 : sba_num_chans = MAX_INTERN_CHANNELS;
240 58080 : move16();
241 987360 : FOR( idx_ch = 0; idx_ch < sba_num_chans; idx_ch++ )
242 : {
243 929280 : set32_fx( Cldfb_RealBuffer_tmp_fx[idx_ch], 0, CLDFB_NO_CHANNELS_MAX );
244 929280 : set32_fx( Cldfb_ImagBuffer_tmp_fx[idx_ch], 0, CLDFB_NO_CHANNELS_MAX );
245 : }
246 :
247 58080 : idx_lfe = 0;
248 58080 : idx_in = 0;
249 58080 : move16();
250 58080 : move16();
251 :
252 455520 : FOR( idx_ch = 0; idx_ch < ( hTransSetup.nchan_out_woLFE + hTransSetup.num_lfe ); idx_ch++ )
253 : {
254 397440 : test();
255 397440 : IF( ( hTransSetup.num_lfe > 0 ) && EQ_16( idx_ch, hTransSetup.index_lfe[idx_lfe] ) )
256 : {
257 58080 : IF( gain_lfe_fx > 0 )
258 : {
259 : /* Add LFE to Omni Channel i.e. W (Just first Band) */
260 58080 : 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*/
261 58080 : move32();
262 58080 : 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*/
263 58080 : move32();
264 : }
265 :
266 58080 : if ( LT_16( idx_lfe, sub( hTransSetup.num_lfe, 1 ) ) )
267 : {
268 0 : idx_lfe = add( idx_lfe, 1 ); /*Q0*/
269 : }
270 : }
271 : ELSE
272 : {
273 339360 : gains_fx = hoa_encoder_fx + imult1616( idx_in, sba_num_chans ); /*Pointer addition*/ /*Q31*/
274 5769120 : FOR( idx_out = 0; idx_out < sba_num_chans; idx_out++ )
275 : {
276 288719360 : FOR( idx_band = 0; idx_band < nBands; idx_band++ )
277 : {
278 283289600 : 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*/
279 283289600 : move32();
280 283289600 : 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*/
281 283289600 : move32();
282 : }
283 5429760 : gains_fx++;
284 : }
285 339360 : idx_in = add( idx_in, 1 ); /*Q0*/
286 : }
287 : }
288 987360 : FOR( idx_ch = 0; idx_ch < sba_num_chans; idx_ch++ )
289 : {
290 929280 : Copy32( Cldfb_RealBuffer_tmp_fx[idx_ch], Cldfb_RealBuffer_fx[idx_ch][slot_idx], nBands ); /*Q_Cldfb_RealBuffer*/
291 929280 : Copy32( Cldfb_ImagBuffer_tmp_fx[idx_ch], Cldfb_ImagBuffer_fx[idx_ch][slot_idx], nBands ); /*Q_Cldfb_ImagBuffer*/
292 : }
293 :
294 58080 : return;
295 : }
296 :
297 :
298 : /*-------------------------------------------------------------------*
299 : * ivas_sba_remapTCs()
300 : *
301 : * Get TCs from Ambisonics signal in ACN
302 : *-------------------------------------------------------------------*/
303 :
304 : /*! r: SBA DirAC stereo flag */
305 149027 : Word16 ivas_sba_remapTCs_fx(
306 : Word32 *sba_data_fx[], /* i/o: SBA signals Q11*/
307 : Decoder_Struct *st_ivas, /* i/o: decoder struct */
308 : const Word16 output_frame /* i : frame length Q0*/
309 : )
310 : {
311 : Word16 nchan_remapped;
312 149027 : nchan_remapped = st_ivas->nchan_transport; /*Q0*/
313 149027 : move16();
314 149027 : IF( EQ_16( nchan_remapped, 3 ) )
315 : {
316 30220 : nchan_remapped = add( nchan_remapped, 1 ); /*Q0*/
317 30220 : IF( EQ_16( nchan_remapped, 4 ) )
318 : {
319 30220 : Copy32( sba_data_fx[2], sba_data_fx[3], output_frame ); /*Q11*/
320 : }
321 : }
322 149027 : IF( GE_16( st_ivas->nchan_transport, 3 ) )
323 : {
324 67969 : Word16 i = 0;
325 67969 : move16();
326 : Word32 temp_fx;
327 :
328 : /*convert WYXZ downmix to WYZX*/
329 55311489 : FOR( i = 0; i < output_frame; i++ )
330 : {
331 55243520 : temp_fx = sba_data_fx[2][i]; /*Q11*/
332 55243520 : move32();
333 55243520 : sba_data_fx[2][i] = sba_data_fx[3][i]; /*Q11*/
334 55243520 : move32();
335 55243520 : sba_data_fx[3][i] = temp_fx; /*Q11*/
336 55243520 : move32();
337 :
338 55243520 : if ( EQ_16( st_ivas->nchan_transport, 3 ) )
339 : {
340 23753280 : sba_data_fx[2][i] = 0;
341 23753280 : move32();
342 : }
343 : }
344 : }
345 149027 : return ( nchan_remapped );
346 : }
347 :
348 : /*-------------------------------------------------------------------------*
349 : * ivas_ism2sba_sf()
350 : *
351 : * ISM transformed into SBA in TD domain.
352 : *-------------------------------------------------------------------------*/
353 4896 : void ivas_ism2sba_sf_fx(
354 : Word32 *buffer_in_fx[],
355 : /* i : TC buffer */ /*Q_buffer_in*/
356 : Word32 *buffer_out_fx[], /* o : TD signal buffers Q_buffer_in + 29 - 31*/
357 : ISM_RENDERER_HANDLE hIsmRendererData, /* i/o: renderer data */
358 : const Word16 num_objects, /* i : number of objects Q0*/
359 : const Word16 n_samples_to_render, /* i : output frame length per channel Q0*/
360 : const Word16 offset, /* i : offset for the interpolatr Q0*/
361 : const Word16 sba_order /* i : Ambisonic (SBA) order Q0*/
362 : )
363 : {
364 : Word16 i, j, k;
365 : Word32 buffer_tmp_fx[HOA3_CHANNELS][L_FRAME48k];
366 : Word16 *g2_fx, g1_fx;
367 : Word32 *tc_fx, *out_fx, gain_fx, prev_gain_fx;
368 : Word16 sba_num_chans;
369 :
370 4896 : assert( LE_16( sba_order, 3 ) && "Only order up to 3 is supported!" );
371 4896 : assert( hIsmRendererData != NULL && "hIsmRendererData not allocated!" );
372 : /* Init*/
373 4896 : sba_num_chans = imult1616( add( sba_order, 1 ), add( sba_order, 1 ) ); /*Q0*/
374 65032 : FOR( j = 0; j < sba_num_chans; j++ )
375 : {
376 60136 : set32_fx( buffer_tmp_fx[j], 0, n_samples_to_render );
377 : }
378 20780 : FOR( i = 0; i < num_objects; i++ )
379 : {
380 212628 : FOR( j = 0; j < sba_num_chans; j++ )
381 : {
382 196744 : g2_fx = hIsmRendererData->interpolator_fx + offset; /*Pointer addition*/ /*Q15*/
383 196744 : tc_fx = buffer_in_fx[i] + offset; /*Pointer addition*/ /*Q_buffer_in*/
384 196744 : out_fx = buffer_tmp_fx[j]; /*Q_buffer_in + 29 - 31*/
385 196744 : gain_fx = hIsmRendererData->gains_fx[i][j]; /*Q29*/
386 196744 : move32();
387 196744 : prev_gain_fx = hIsmRendererData->prev_gains_fx[i][j]; /*Q29*/
388 196744 : move32();
389 166030984 : FOR( k = 0; k < n_samples_to_render; k++ )
390 : {
391 165834240 : g1_fx = sub( 32767, *g2_fx ); /*Q15*/
392 165834240 : *( 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*/
393 165834240 : move32();
394 165834240 : g2_fx++;
395 165834240 : tc_fx++;
396 165834240 : out_fx++;
397 : }
398 : }
399 : }
400 65032 : FOR( j = 0; j < sba_num_chans; j++ )
401 : {
402 60136 : Copy32( buffer_tmp_fx[j], buffer_out_fx[j], n_samples_to_render ); /*Q_buffer_in + 29 - 31*/
403 : }
404 4896 : return;
405 : }
406 :
407 : /*-------------------------------------------------------------------*
408 : * ivas_sba_linear_renderer()
409 : *
410 : * Linear rendering for SBA format
411 : *-------------------------------------------------------------------*/
412 : /*TODO: To be tested*/
413 : /************************
414 : Float to fixed conversion required for:output_f
415 : *************************/
416 60953 : ivas_error ivas_sba_linear_renderer_fx(
417 : Word32 *output_f[], /* i/o: synthesized core-coder transport channels/DirAC output Q11*/
418 : const Word16 output_frame, /* i : output frame length per channel Q0*/
419 : const Word16 nchan_in, /* i : number of input ambisonics channels Q0*/
420 : const Word16 nchan_ism, /* i : number of objects Q0*/
421 : const AUDIO_CONFIG output_config, /* i : output audio configuration */
422 : const IVAS_OUTPUT_SETUP output_setup /* i : output format setup */
423 : )
424 : {
425 : Word16 i;
426 : Word16 nchan_hoa;
427 : ivas_error error;
428 :
429 60953 : error = IVAS_ERR_OK;
430 60953 : move32();
431 :
432 : /* Number of channels of HOA depends of transport format which is mixed order xH1V*/
433 60953 : nchan_hoa = nchan_in; /*Q0*/
434 60953 : move16();
435 :
436 60953 : IF( EQ_16( nchan_in, 6 ) ) /*2H1V*/
437 : {
438 0 : nchan_hoa = 9;
439 0 : move16();
440 : }
441 60953 : ELSE IF( EQ_16( nchan_in, 8 ) ) /*3H1V*/
442 : {
443 0 : nchan_hoa = 16;
444 0 : move16();
445 : }
446 :
447 60953 : SWITCH( output_config )
448 : {
449 54203 : case IVAS_AUDIO_CONFIG_FOA: /* Ambisonics output, order: 1 */
450 : case IVAS_AUDIO_CONFIG_HOA2: /* Ambisonics output, order: 2 */
451 : case IVAS_AUDIO_CONFIG_HOA3: /* Ambisonics output, order: 3 */
452 54203 : FOR( i = nchan_hoa; i < output_setup.nchan_out_woLFE; i++ )
453 : {
454 0 : set_zero_fx( output_f[i], output_frame );
455 : }
456 54203 : BREAK;
457 6750 : case IVAS_AUDIO_CONFIG_EXTERNAL:
458 58500 : FOR( i = output_setup.nchan_out_woLFE - 1; i >= nchan_ism; i-- )
459 : {
460 51750 : Copy32( output_f[i - nchan_ism], output_f[i], output_frame ); /*Q11*/
461 : }
462 6750 : FOR( ; i >= 0; i-- )
463 : {
464 0 : set_zero_fx( output_f[i], output_frame );
465 : }
466 6750 : BREAK;
467 0 : default:
468 0 : return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Error: illegal output configuration, Exiting.\n" );
469 : }
470 :
471 60953 : return error;
472 : }
473 :
474 :
475 : /*-------------------------------------------------------------------*
476 : * ivas_sba_mix_matrix_determiner()
477 : *
478 : * Determine SBA mixing matrices
479 : *-------------------------------------------------------------------*/
480 37054 : void ivas_sba_mix_matrix_determiner_fx(
481 : SPAR_DEC_HANDLE hSpar, /* i/o: SPAR decoder handle */
482 : Word32 *output_fx[], /* i/o: transport/output audio channels Q_output*/
483 : const Word16 bfi, /* i : BFI flag Q0*/
484 : const Word16 nchan_remapped, /* i : num channels after remapping of TCs Q0*/
485 : const Word16 output_frame, /* i : output frame length Q0*/
486 : const Word16 num_md_sub_frames, /* i : number of subframes in mixing matrix Q0*/
487 : const Word16 Q_output /* i : Q of transport/output audio channels */
488 : )
489 : {
490 : Word16 i, ch;
491 : Word16 num_bands_out, nchan_transport, nchan_out;
492 37054 : Word16 Q_p_output = add( 11, Q_output );
493 : Word32 temp_fx;
494 : /* Convert numeric range */
495 95357 : FOR( ch = 0; ch < nchan_remapped; ch++ )
496 : {
497 40525183 : FOR( i = 0; i < output_frame; i++ )
498 : {
499 40466880 : temp_fx = output_fx[ch][i]; /*Q_output*/
500 40466880 : move32();
501 40466880 : temp_fx = L_shr( temp_fx + L_shl( 1, Q_p_output - 1 ), Q_p_output ); /*Q0*/
502 :
503 40466880 : IF( GT_32( temp_fx, MAX16B ) )
504 : {
505 7 : temp_fx = MAX16B; /*Q0*/
506 7 : move32();
507 : }
508 40466873 : ELSE IF( LT_32( temp_fx, L_negate( PCM16_TO_FLT_FAC_FX ) ) )
509 : {
510 2 : temp_fx = -( PCM16_TO_FLT_FAC_FX ); /*Q0*/
511 2 : move32();
512 : }
513 40466880 : temp_fx = Mult_32_32( MAX_32 / PCM16_TO_FLT_FAC_FX, L_shl( temp_fx, Q_p_output ) ); /*Q_p_output*/
514 40466880 : output_fx[ch][i] = temp_fx; /*Q_p_output*/
515 40466880 : move32();
516 : }
517 : }
518 : /* AGC */
519 37054 : nchan_transport = hSpar->hMdDec->spar_md_cfg.nchan_transport; /*Q0*/
520 37054 : move16();
521 37054 : nchan_out = nchan_transport; /*Q0*/
522 37054 : move16();
523 37054 : ivas_agc_dec_process_fx( hSpar->hAgcDec, ( output_fx ), ( output_fx ), nchan_transport, output_frame );
524 37054 : Q_p_output = sub( Q_p_output, 3 );
525 : #ifdef DEBUGGING
526 : dbgwrite_txt( (const float *) ( output_fx[0] ), output_frame, "fix_ivas_agc_dec_process_output.txt", NULL );
527 : #endif
528 :
529 : /* Convert numeric range back */
530 95357 : FOR( ch = 0; ch < nchan_out; ch++ )
531 : {
532 40525183 : FOR( i = 0; i < output_frame; i++ )
533 : {
534 40466880 : 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 */
535 : }
536 : }
537 :
538 : /* Mixing matrix determiner */
539 37054 : num_bands_out = hSpar->hFbMixer->pFb->filterbank_num_bands; /*Q0*/
540 37054 : move16();
541 37054 : ivas_spar_dec_gen_umx_mat_fx( hSpar->hMdDec, nchan_transport, num_bands_out, bfi, num_md_sub_frames );
542 37054 : return;
543 : }
|