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 "options.h"
34 : #include <stdlib.h>
35 : #include <assert.h>
36 : #include <math.h>
37 : #include "ivas_cnst.h"
38 : #include "prot_fx.h"
39 : #include "ivas_rom_com.h"
40 : #include "ivas_rom_enc.h"
41 : #include "wmc_auto.h"
42 : #include "ivas_prot_fx.h"
43 :
44 :
45 : /*-------------------------------------------------------------------------
46 : * Local function prototypes
47 : *------------------------------------------------------------------------*/
48 : static void ivas_osba_render_ism_to_sba_fx(
49 : Word32 *data_in_fx[],
50 : Word32 data_out_fx[][L_FRAME48k],
51 : const Word16 input_frame,
52 : const Word16 sba_analysis_order,
53 : const Word16 nchan_ism,
54 : ISM_METADATA_HANDLE hIsmMeta[],
55 : Word32 prev_gains_fx[][MAX_INPUT_CHANNELS],
56 : const Word32 interpolator_fx[L_FRAME48k],
57 : Word16 *Q_data );
58 : /*-------------------------------------------------------------------*
59 : * ivas_merge_sba_transports()
60 : *
61 : * Merge SBA transport channels
62 : *-------------------------------------------------------------------*/
63 14920 : static void ivas_merge_sba_transports_fx(
64 : Word32 data_in_f1[][L_FRAME48k], // Q_f1
65 : Word32 *data_in_f2[], // Q_f2
66 : Word32 *data_out_f[], // Q_out
67 : const Word16 input_frame,
68 : const Word16 sba_analysis_order,
69 : Word16 Q_f1,
70 : Word16 Q_f2,
71 : Word16 *Q_out )
72 : {
73 : Word16 i, j, nchan_sba;
74 14920 : nchan_sba = imult1616( add( sba_analysis_order, 1 ), add( sba_analysis_order, 1 ) );
75 :
76 74600 : FOR( i = 0; i < nchan_sba; i++ )
77 : {
78 51950880 : FOR( j = 0; j < input_frame; j++ )
79 : {
80 51891200 : data_out_f[i][j] = L_shr( L_add( L_shr( data_in_f1[i][j], 1 ), L_shr( data_in_f2[i][j], sub( Q_f2, sub( Q_f1, 1 ) ) ) ), Q1 );
81 51891200 : move32();
82 : }
83 : }
84 14920 : *Q_out = sub( Q_f1, 1 );
85 14920 : return;
86 : }
87 : /*--------------------------------------------------------------------------*
88 : * ivas_osba_enc_open()
89 : *
90 : * Allocate and initialize OMASA handle
91 : *--------------------------------------------------------------------------*/
92 37 : ivas_error ivas_osba_enc_open_fx(
93 : Encoder_Struct *st_ivas /* i/o: IVAS encoder handle */
94 : )
95 : {
96 : Word16 i;
97 : OSBA_ENC_HANDLE hOSba;
98 : Word16 input_frame;
99 : ivas_error error;
100 : Word16 len;
101 37 : error = IVAS_ERR_OK;
102 :
103 37 : IF( ( hOSba = (OSBA_ENC_HANDLE) malloc( sizeof( OSBA_ENC_DATA ) ) ) == NULL )
104 : {
105 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for OMASA encoder\n" ) );
106 : }
107 185 : FOR( i = 0; i < MAX_NUM_OBJECTS; i++ )
108 : {
109 148 : set_val_Word32( hOSba->prev_object_dm_gains_fx[i], INV_SQRT_2_Q30, MAX_INPUT_CHANNELS );
110 : }
111 37 : len = NS2SA_FX2( st_ivas->hEncoderConfig->input_Fs, IVAS_FB_ENC_DELAY_NS );
112 37 : move16();
113 147 : FOR( i = 0; i < st_ivas->hEncoderConfig->nchan_ism; i++ )
114 : {
115 110 : IF( ( hOSba->input_data_mem_fx[i] = (Word32 *) malloc( len * sizeof( Word32 ) ) ) == NULL )
116 : {
117 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for OSBA input buffers" );
118 : }
119 110 : set_val_Word32( hOSba->input_data_mem_fx[i], 0, len );
120 : }
121 75 : FOR( ; i < MAX_NUM_OBJECTS; i++ )
122 : {
123 38 : hOSba->input_data_mem_fx[i] = NULL;
124 : }
125 :
126 37 : input_frame = extract_l( Mpy_32_32_r( st_ivas->hEncoderConfig->input_Fs, ONE_BY_FRAMES_PER_SEC_Q31 ) );
127 :
128 : Word16 tmp_e;
129 : Word32 tmp32;
130 :
131 31717 : FOR( i = 0; i < input_frame; i++ )
132 : {
133 31680 : tmp32 = L_deposit_h( BASOP_Util_Divide1616_Scale( i, input_frame, &tmp_e ) );
134 31680 : hOSba->interpolator_fx[i] = L_shl( tmp32, tmp_e ); // Q31
135 31680 : move32();
136 : }
137 37 : st_ivas->hOSba = hOSba;
138 :
139 37 : return error;
140 : }
141 :
142 : /*--------------------------------------------------------------------------*
143 : * ivas_omasa_enc_close()
144 : *
145 : * Close OMASA handle
146 : *--------------------------------------------------------------------------*/
147 628 : void ivas_osba_enc_close_fx(
148 : OSBA_ENC_HANDLE *hOSba /* i/o: encoder OSBA handle */
149 : )
150 : {
151 : Word16 n;
152 628 : test();
153 628 : IF( hOSba == NULL || *hOSba == NULL )
154 : {
155 591 : return;
156 : }
157 185 : FOR( n = 0; n < MAX_NUM_OBJECTS; n++ )
158 : {
159 148 : IF( ( *hOSba )->input_data_mem_fx[n] != NULL )
160 : {
161 110 : free( ( *hOSba )->input_data_mem_fx[n] );
162 110 : ( *hOSba )->input_data_mem_fx[n] = NULL;
163 : }
164 : }
165 37 : free( *hOSba );
166 37 : ( *hOSba ) = NULL;
167 :
168 37 : return;
169 : }
170 :
171 : /*--------------------------------------------------------------------------*
172 : * ivas_osba_enc_reconfig()
173 : *
174 : * oSBA encoder reconfiguration
175 : *--------------------------------------------------------------------------*/
176 37000 : ivas_error ivas_osba_enc_reconfig(
177 : Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */
178 : )
179 : {
180 :
181 : Word16 n, nSCE_old, nCPE_old, nchan_transport_old;
182 : ISM_MODE old_ism_mode;
183 : Word32 ivas_total_brate;
184 : ivas_error error;
185 : ENCODER_CONFIG_HANDLE hEncoderConfig;
186 :
187 37000 : error = IVAS_ERR_OK;
188 37000 : move32();
189 37000 : hEncoderConfig = st_ivas->hEncoderConfig;
190 37000 : ivas_total_brate = hEncoderConfig->ivas_total_brate;
191 37000 : move32();
192 : Word16 nchan_transport;
193 :
194 37000 : IF( NE_32( ivas_total_brate, hEncoderConfig->last_ivas_total_brate ) )
195 : {
196 653 : DIRAC_ENC_HANDLE hDirAC = st_ivas->hDirAC;
197 : SPAR_ENC_HANDLE hSpar;
198 : Word16 analysis_order_old;
199 : Word16 spar_reconfig_flag;
200 : Word16 nbands_old;
201 : Word16 ndir_old;
202 :
203 653 : spar_reconfig_flag = 0;
204 653 : move16();
205 653 : old_ism_mode = st_ivas->ism_mode;
206 653 : move32();
207 653 : st_ivas->ism_mode = ivas_osba_ism_mode_select( ivas_total_brate, st_ivas->hEncoderConfig->nchan_ism );
208 653 : nchan_transport_old = st_ivas->nchan_transport;
209 653 : nCPE_old = st_ivas->nCPE;
210 653 : nSCE_old = st_ivas->nSCE;
211 653 : move16();
212 653 : move16();
213 653 : move16();
214 :
215 653 : st_ivas->sba_analysis_order = ivas_sba_get_analysis_order_fx( ivas_total_brate, hEncoderConfig->sba_order );
216 653 : move16();
217 653 : analysis_order_old = ivas_sba_get_analysis_order_fx( hEncoderConfig->last_ivas_total_brate, hEncoderConfig->sba_order );
218 :
219 653 : nbands_old = st_ivas->hQMetaData->q_direction->cfg.nbands;
220 653 : move16();
221 653 : ndir_old = st_ivas->hQMetaData->no_directions;
222 653 : move16();
223 :
224 653 : test();
225 653 : IF( NE_16( analysis_order_old, st_ivas->sba_analysis_order ) || NE_32( old_ism_mode, st_ivas->ism_mode ) )
226 : {
227 : Word16 i, n_old;
228 : Word32 **old_mem_hp20_in_fx;
229 :
230 396 : n_old = add( st_ivas->hEncoderConfig->nchan_ism, imult1616( add( analysis_order_old, 1 ), add( analysis_order_old, 1 ) ) );
231 396 : n = add( st_ivas->hEncoderConfig->nchan_ism, imult1616( add( st_ivas->sba_analysis_order, 1 ), add( st_ivas->sba_analysis_order, 1 ) ) );
232 :
233 396 : IF( GT_16( n, n_old ) )
234 : {
235 : /* save old mem_hp_20 pointer */
236 92 : old_mem_hp20_in_fx = st_ivas->mem_hp20_in_fx;
237 92 : st_ivas->mem_hp20_in_fx = NULL;
238 :
239 92 : IF( ( st_ivas->mem_hp20_in_fx = (Word32 **) malloc( n * sizeof( Word32 * ) ) ) == NULL )
240 : {
241 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HP20 filter memory\n" ) );
242 : }
243 :
244 762 : FOR( i = 0; i < n_old; i++ )
245 : {
246 670 : st_ivas->mem_hp20_in_fx[i] = old_mem_hp20_in_fx[i];
247 670 : old_mem_hp20_in_fx[i] = NULL;
248 : }
249 : /* create additional hp20 memories */
250 909 : FOR( ; i < n; i++ )
251 : {
252 817 : IF( ( st_ivas->mem_hp20_in_fx[i] = (Word32 *) malloc( ( L_HP20_MEM + 2 ) * sizeof( Word32 ) ) ) == NULL )
253 : {
254 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HP20 filter memory\n" ) );
255 : }
256 :
257 817 : set32_fx( st_ivas->mem_hp20_in_fx[i], 0, L_HP20_MEM + 2 );
258 : }
259 :
260 92 : free( old_mem_hp20_in_fx );
261 92 : old_mem_hp20_in_fx = NULL;
262 : }
263 304 : ELSE IF( LT_16( n, n_old ) )
264 : {
265 : /* save old mem_hp_20 pointer */
266 87 : old_mem_hp20_in_fx = st_ivas->mem_hp20_in_fx;
267 87 : st_ivas->mem_hp20_in_fx = NULL;
268 :
269 87 : IF( ( st_ivas->mem_hp20_in_fx = (Word32 **) malloc( n * sizeof( Word32 * ) ) ) == NULL )
270 : {
271 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HP20 filter memory\n" ) );
272 : }
273 :
274 720 : FOR( i = 0; i < n; i++ )
275 : {
276 633 : st_ivas->mem_hp20_in_fx[i] = old_mem_hp20_in_fx[i];
277 633 : old_mem_hp20_in_fx[i] = NULL;
278 : }
279 : /* remove superfluous hp20 memories */
280 858 : FOR( ; i < n_old; i++ )
281 : {
282 771 : free( old_mem_hp20_in_fx[i] );
283 771 : old_mem_hp20_in_fx[i] = NULL;
284 : }
285 :
286 87 : free( old_mem_hp20_in_fx );
287 87 : old_mem_hp20_in_fx = NULL;
288 : }
289 : }
290 :
291 653 : ivas_spar_config_fx( ivas_total_brate, s_min( st_ivas->sba_analysis_order, IVAS_MAX_SBA_ORDER ), &st_ivas->nchan_transport, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->hSpar->core_nominal_brate, -1 );
292 :
293 653 : hSpar = st_ivas->hSpar;
294 :
295 653 : IF( EQ_16( st_ivas->nchan_transport, 1 ) )
296 : {
297 228 : hEncoderConfig->element_mode_init = IVAS_SCE;
298 228 : move16();
299 : }
300 : ELSE
301 : {
302 425 : hEncoderConfig->element_mode_init = IVAS_CPE_MDCT;
303 425 : move16();
304 : }
305 653 : test();
306 653 : test();
307 653 : test();
308 653 : test();
309 653 : IF( NE_16( nchan_transport_old, st_ivas->nchan_transport ) || ( LT_32( ivas_total_brate, IVAS_512k ) && GE_32( hEncoderConfig->last_ivas_total_brate, IVAS_512k ) ) || ( GE_32( ivas_total_brate, IVAS_512k ) && LT_32( hEncoderConfig->last_ivas_total_brate, IVAS_512k ) ) )
310 : {
311 : /* FB mixer handle */
312 540 : IF( hDirAC->hFbMixer != NULL )
313 : {
314 0 : ivas_FB_mixer_close_fx( &( hDirAC->hFbMixer ), hEncoderConfig->input_Fs, 0 );
315 0 : hDirAC->hFbMixer = NULL;
316 : }
317 540 : spar_reconfig_flag = 1;
318 540 : move16();
319 540 : ivas_spar_enc_close_fx( &( st_ivas->hSpar ), hEncoderConfig->input_Fs, hEncoderConfig->nchan_inp, spar_reconfig_flag );
320 :
321 540 : IF( NE_32( ( error = ivas_spar_enc_open_fx( st_ivas, spar_reconfig_flag ) ), IVAS_ERR_OK ) )
322 : {
323 0 : return error;
324 : }
325 : }
326 653 : st_ivas->hSpar->spar_reconfig_flag = spar_reconfig_flag;
327 653 : move16();
328 653 : IF( NE_32( ( error = ivas_dirac_enc_reconfigure( st_ivas ) ), IVAS_ERR_OK ) )
329 : {
330 0 : return error;
331 : }
332 653 : test();
333 653 : IF( NE_16( st_ivas->hQMetaData->q_direction->cfg.nbands, nbands_old ) || NE_16( st_ivas->hQMetaData->no_directions, ndir_old ) )
334 : {
335 : Word16 dir, j, i;
336 334 : IVAS_QDIRECTION *q_direction = st_ivas->hQMetaData->q_direction;
337 730 : FOR( dir = 0; dir < st_ivas->hQMetaData->no_directions; dir++ )
338 : {
339 2447 : FOR( j = 0; j < q_direction[dir].cfg.nbands; j++ )
340 : {
341 10255 : FOR( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ )
342 : {
343 8204 : q_direction[dir].band_data[j].energy_ratio_index[i] = 0;
344 8204 : move32();
345 8204 : q_direction[dir].band_data[j].energy_ratio_index_mod[i] = 0;
346 8204 : move32();
347 : }
348 : }
349 : }
350 : }
351 653 : hSpar->enc_param_start_band = hDirAC->hConfig->enc_param_start_band;
352 653 : move16();
353 :
354 : /*-----------------------------------------------------------------*
355 : * Allocate, initialize, and configure SCE/CPE/MCT handles
356 : *-----------------------------------------------------------------*/
357 :
358 653 : nchan_transport = st_ivas->nchan_transport;
359 :
360 653 : test();
361 653 : test();
362 653 : IF( old_ism_mode == ISM_MODE_NONE && EQ_32( st_ivas->ism_mode, ISM_SBA_MODE_DISC ) )
363 : {
364 186 : nchan_transport = add( st_ivas->nchan_transport, st_ivas->hEncoderConfig->nchan_ism );
365 186 : st_ivas->nCPE = shr_r( nchan_transport, 1 );
366 : }
367 467 : ELSE IF( EQ_32( old_ism_mode, ISM_SBA_MODE_DISC ) && st_ivas->ism_mode == ISM_MODE_NONE )
368 : {
369 180 : nchan_transport_old = add( nchan_transport_old, st_ivas->hEncoderConfig->nchan_ism );
370 180 : nchan_transport = st_ivas->nchan_transport;
371 : }
372 287 : ELSE IF( EQ_32( st_ivas->ism_mode, ISM_SBA_MODE_DISC ) )
373 : {
374 69 : nchan_transport_old = add( nchan_transport_old, st_ivas->hEncoderConfig->nchan_ism );
375 69 : nchan_transport = add( st_ivas->nchan_transport, st_ivas->hEncoderConfig->nchan_ism );
376 69 : st_ivas->nCPE = shr_r( nchan_transport, 1 );
377 : }
378 :
379 : Word16 tmp_e;
380 653 : Word32 bitrate_per_chan = L_deposit_h( BASOP_Util_Divide3216_Scale( ivas_total_brate, st_ivas->nchan_transport, &tmp_e ) );
381 653 : bitrate_per_chan = L_shr( bitrate_per_chan, sub( 15, tmp_e ) );
382 653 : IF( NE_32( ( error = ivas_corecoder_enc_reconfig_fx( st_ivas, nSCE_old, nCPE_old, nchan_transport_old, bitrate_per_chan, imult3216( bitrate_per_chan, CPE_CHANNELS ), MC_MODE_NONE ) ), IVAS_ERR_OK ) )
383 : {
384 0 : return error;
385 : }
386 : }
387 :
388 37000 : return error;
389 : }
390 : /*--------------------------------------------------------------------------*
391 : * ivas_osba_enc()
392 : *
393 : * Main OSBA encoding function
394 : *--------------------------------------------------------------------------*/
395 :
396 37000 : void ivas_osba_enc_fx(
397 : OSBA_ENC_HANDLE hOSba, /* i/o: OSBA encoder handle */
398 : ISM_METADATA_HANDLE hIsmMeta[], /* i/o: ISM metadata handle */
399 : Word32 *data_in_fx[], /* i/o: Input / transport audio signals q_data*/
400 : const Word16 input_frame, /* i : Input frame size */
401 : const Word16 nchan_ism, /* i : Number of objects for parameter analysis */
402 : const ISM_MODE ism_mode, /* i : ISM mode */
403 : const Word16 sba_analysis_order, /* i : SBA order evaluated in DirAC/SPAR encoder */
404 : const Word32 input_Fs, /* i : input sampling rate */
405 : const Word16 sba_planar, /* i : planar SBA flag */
406 : Word16 *q_data )
407 : {
408 : Word32 data_out_fx[MAX_INPUT_CHANNELS][L_FRAME48k];
409 37000 : Word16 Q_out = *q_data;
410 37000 : move16();
411 : Word16 n, delay_s;
412 37000 : delay_s = NS2SA_FX2( input_Fs, IVAS_FB_ENC_DELAY_NS );
413 37000 : IF( ism_mode == ISM_MODE_NONE )
414 : {
415 : /*keep the delay buffer up to date*/
416 55560 : FOR( n = 0; n < nchan_ism; n++ )
417 : {
418 40640 : MVR2R_WORD32( &data_in_fx[n][input_frame - delay_s], hOSba->input_data_mem_fx[n], delay_s ); // Q_data
419 : }
420 : /* Convert ISM to SBA */
421 :
422 14920 : ivas_osba_render_ism_to_sba_fx( data_in_fx, data_out_fx, input_frame, sba_analysis_order, nchan_ism, hIsmMeta, hOSba->prev_object_dm_gains_fx, hOSba->interpolator_fx, &Q_out );
423 :
424 14920 : IF( sba_planar )
425 : {
426 0 : ivas_sba_zero_vert_comp_fx( &( data_in_fx[nchan_ism] ), sba_analysis_order, sba_planar, input_frame );
427 : }
428 :
429 :
430 : /* Merge SBA signals */
431 14920 : ivas_merge_sba_transports_fx( data_out_fx, &( data_in_fx[nchan_ism] ), data_in_fx, input_frame, sba_analysis_order, Q_out, *q_data, q_data );
432 : }
433 : ELSE
434 : {
435 : Word16 azimuth_fx, elevation_fx;
436 : /* delay ISM input channels to match the SBA encoder delay */
437 91440 : FOR( n = 0; n < nchan_ism; n++ )
438 : {
439 69360 : delay_signal32_fx( data_in_fx[n], input_frame, hOSba->input_data_mem_fx[n], delay_s );
440 :
441 69360 : azimuth_fx = extract_l( L_shr( L_add( hIsmMeta[n]->azimuth_fx, 2097152 /*0.5.Q22*/ ), Q22 ) ); // Q0
442 69360 : elevation_fx = extract_l( L_shr( L_add( hIsmMeta[n]->elevation_fx, 2097152 /*0.5.Q22*/ ), Q22 ) ); // Q0
443 69360 : ivas_dirac_dec_get_response_fx( azimuth_fx, elevation_fx, hOSba->prev_object_dm_gains_fx[n], sba_analysis_order, Q30 );
444 : }
445 : }
446 :
447 : /* Set the number of objects */
448 37000 : hOSba->nchan_ism = nchan_ism;
449 37000 : move16();
450 37000 : return;
451 : }
452 :
453 : /*--------------------------------------------------------------------------*
454 : * Local functions
455 : *--------------------------------------------------------------------------*/
456 : /* Render ISMs to SBA */
457 14920 : static void ivas_osba_render_ism_to_sba_fx(
458 : Word32 *data_in_fx[], // Q_data
459 : Word32 data_out_fx[][L_FRAME48k], // Q_data
460 : const Word16 input_frame,
461 : const Word16 sba_analysis_order,
462 : const Word16 nchan_ism,
463 : ISM_METADATA_HANDLE hIsmMeta[],
464 : Word32 prev_gains_fx[][MAX_INPUT_CHANNELS], // Q30
465 : const Word32 interpolator_fx[L_FRAME48k], // Q31
466 : Word16 *Q_data )
467 : {
468 : Word16 i, j, k;
469 : Word16 azimuth_fx, elevation_fx;
470 : Word32 gains_fx[MAX_INPUT_CHANNELS];
471 : Word32 g1_fx, g2_fx;
472 : Word16 nchan_sba;
473 14920 : nchan_sba = imult1616( add( sba_analysis_order, 1 ), add( sba_analysis_order, 1 ) );
474 :
475 74600 : FOR( i = 0; i < nchan_sba; i++ )
476 : {
477 59680 : set_val_Word32( data_out_fx[i], 0, input_frame );
478 : }
479 :
480 55560 : FOR( i = 0; i < nchan_ism; i++ )
481 : {
482 : // azimuth = (int16_t) floorf( hIsmMeta[i]->azimuth + 0.5f );
483 40640 : azimuth_fx = extract_l( L_shr( L_add( hIsmMeta[i]->azimuth_fx, 2097152 /*0.5.Q22*/ ), Q22 ) ); // Q0
484 : // elevation = (int16_t) floorf( hIsmMeta[i]->elevation + 0.5f );
485 40640 : elevation_fx = extract_l( L_shr( L_add( hIsmMeta[i]->elevation_fx, 2097152 /*0.5.Q22*/ ), Q22 ) ); // Q0
486 :
487 40640 : ivas_dirac_dec_get_response_fx( azimuth_fx, elevation_fx, gains_fx, sba_analysis_order, Q30 );
488 :
489 : /* Render using the sh gains */
490 203200 : FOR( j = 0; j < nchan_sba; j++ )
491 : {
492 162560 : test();
493 162560 : IF( L_abs( gains_fx[j] ) > 0 || L_abs( prev_gains_fx[i][j] ) > 0 )
494 : {
495 145480862 : FOR( k = 0; k < input_frame; k++ )
496 : {
497 : // g1 = interpolator[k];
498 145319360 : g1_fx = interpolator_fx[k]; // Q31
499 145319360 : move32();
500 : // g2 = 1.0f - g1;
501 145319360 : g2_fx = L_sub( ONE_IN_Q31, g1_fx ); // Q31
502 145319360 : move32();
503 : // data_out_f[j][k] += ( g1 * gains[j] + g2 * prev_gains[i][j] ) * data_in_f[i][k];
504 145319360 : data_out_fx[j][k] = L_add( data_out_fx[j][k], L_shr( Mpy_32_32( L_add( Mpy_32_32( g1_fx, gains_fx[j] ), Mpy_32_32( g2_fx, prev_gains_fx[i][j] ) ), data_in_fx[i][k] ), 1 ) ); // Q_data-2
505 145319360 : move32();
506 : }
507 : }
508 162560 : prev_gains_fx[i][j] = gains_fx[j]; // Q30
509 162560 : move32();
510 : }
511 : }
512 14920 : *Q_data = sub( *Q_data, 2 );
513 :
514 :
515 14920 : return;
516 : }
|