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