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 : Word16 tmp_e;
126 37 : Word32 tmp32 = L_deposit_h( BASOP_Util_Divide3216_Scale( st_ivas->hEncoderConfig->input_Fs, FRAMES_PER_SEC, &tmp_e ) );
127 37 : tmp32 = L_shr( tmp32, sub( 15, tmp_e ) );
128 37 : input_frame = extract_l( tmp32 );
129 :
130 31717 : FOR( i = 0; i < input_frame; i++ )
131 : {
132 31680 : tmp32 = L_deposit_h( BASOP_Util_Divide1616_Scale( i, input_frame, &tmp_e ) );
133 31680 : hOSba->interpolator_fx[i] = L_shl( tmp32, tmp_e ); // Q31
134 31680 : move32();
135 : }
136 37 : st_ivas->hOSba = hOSba;
137 :
138 37 : return error;
139 : }
140 :
141 : /*--------------------------------------------------------------------------*
142 : * ivas_omasa_enc_close()
143 : *
144 : * Close OMASA handle
145 : *--------------------------------------------------------------------------*/
146 627 : void ivas_osba_enc_close_fx(
147 : OSBA_ENC_HANDLE *hOSba /* i/o: encoder OSBA handle */
148 : )
149 : {
150 : Word16 n;
151 627 : test();
152 627 : IF( hOSba == NULL || *hOSba == NULL )
153 : {
154 590 : return;
155 : }
156 185 : FOR( n = 0; n < MAX_NUM_OBJECTS; n++ )
157 : {
158 148 : IF( ( *hOSba )->input_data_mem_fx[n] != NULL )
159 : {
160 110 : free( ( *hOSba )->input_data_mem_fx[n] );
161 110 : ( *hOSba )->input_data_mem_fx[n] = NULL;
162 : }
163 : }
164 37 : free( *hOSba );
165 37 : ( *hOSba ) = NULL;
166 :
167 37 : return;
168 : }
169 :
170 : /*--------------------------------------------------------------------------*
171 : * ivas_osba_enc_reconfig()
172 : *
173 : * oSBA encoder reconfiguration
174 : *--------------------------------------------------------------------------*/
175 37000 : 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 37000 : error = IVAS_ERR_OK;
187 37000 : move32();
188 37000 : hEncoderConfig = st_ivas->hEncoderConfig;
189 37000 : ivas_total_brate = hEncoderConfig->ivas_total_brate;
190 37000 : move32();
191 : Word16 nchan_transport;
192 :
193 37000 : IF( NE_32( ivas_total_brate, hEncoderConfig->last_ivas_total_brate ) )
194 : {
195 653 : DIRAC_ENC_HANDLE hDirAC = st_ivas->hDirAC;
196 : SPAR_ENC_HANDLE hSpar;
197 : Word16 analysis_order_old;
198 : Word16 spar_reconfig_flag;
199 : Word16 nbands_old;
200 : Word16 ndir_old;
201 :
202 653 : spar_reconfig_flag = 0;
203 653 : move16();
204 653 : old_ism_mode = st_ivas->ism_mode;
205 653 : move32();
206 653 : st_ivas->ism_mode = ivas_osba_ism_mode_select( ivas_total_brate, st_ivas->hEncoderConfig->nchan_ism );
207 653 : nchan_transport_old = st_ivas->nchan_transport;
208 653 : nCPE_old = st_ivas->nCPE;
209 653 : nSCE_old = st_ivas->nSCE;
210 653 : move16();
211 653 : move16();
212 653 : move16();
213 :
214 653 : st_ivas->sba_analysis_order = ivas_sba_get_analysis_order_fx( ivas_total_brate, hEncoderConfig->sba_order );
215 653 : move16();
216 653 : analysis_order_old = ivas_sba_get_analysis_order_fx( hEncoderConfig->last_ivas_total_brate, hEncoderConfig->sba_order );
217 :
218 653 : nbands_old = st_ivas->hQMetaData->q_direction->cfg.nbands;
219 653 : move16();
220 653 : ndir_old = st_ivas->hQMetaData->no_directions;
221 653 : move16();
222 :
223 653 : test();
224 653 : IF( NE_16( analysis_order_old, st_ivas->sba_analysis_order ) || NE_32( old_ism_mode, st_ivas->ism_mode ) )
225 : {
226 : Word16 i, n_old;
227 : Word32 **old_mem_hp20_in_fx;
228 :
229 396 : n_old = add( st_ivas->hEncoderConfig->nchan_ism, imult1616( add( analysis_order_old, 1 ), add( analysis_order_old, 1 ) ) );
230 396 : n = add( st_ivas->hEncoderConfig->nchan_ism, imult1616( add( st_ivas->sba_analysis_order, 1 ), add( st_ivas->sba_analysis_order, 1 ) ) );
231 :
232 396 : IF( GT_16( n, n_old ) )
233 : {
234 : /* save old mem_hp_20 pointer */
235 92 : old_mem_hp20_in_fx = st_ivas->mem_hp20_in_fx;
236 92 : st_ivas->mem_hp20_in_fx = NULL;
237 :
238 92 : IF( ( st_ivas->mem_hp20_in_fx = (Word32 **) malloc( n * sizeof( Word32 * ) ) ) == NULL )
239 : {
240 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HP20 filter memory\n" ) );
241 : }
242 :
243 762 : FOR( i = 0; i < n_old; i++ )
244 : {
245 670 : st_ivas->mem_hp20_in_fx[i] = old_mem_hp20_in_fx[i];
246 670 : old_mem_hp20_in_fx[i] = NULL;
247 : }
248 : /* create additional hp20 memories */
249 909 : FOR( ; i < n; i++ )
250 : {
251 817 : IF( ( st_ivas->mem_hp20_in_fx[i] = (Word32 *) malloc( ( L_HP20_MEM + 2 ) * sizeof( Word32 ) ) ) == NULL )
252 : {
253 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HP20 filter memory\n" ) );
254 : }
255 :
256 817 : set32_fx( st_ivas->mem_hp20_in_fx[i], 0, L_HP20_MEM + 2 );
257 : }
258 :
259 92 : free( old_mem_hp20_in_fx );
260 92 : old_mem_hp20_in_fx = NULL;
261 : }
262 304 : ELSE IF( LT_16( n, n_old ) )
263 : {
264 : /* save old mem_hp_20 pointer */
265 87 : old_mem_hp20_in_fx = st_ivas->mem_hp20_in_fx;
266 87 : st_ivas->mem_hp20_in_fx = NULL;
267 :
268 87 : IF( ( st_ivas->mem_hp20_in_fx = (Word32 **) malloc( n * sizeof( Word32 * ) ) ) == NULL )
269 : {
270 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HP20 filter memory\n" ) );
271 : }
272 :
273 720 : FOR( i = 0; i < n; i++ )
274 : {
275 633 : st_ivas->mem_hp20_in_fx[i] = old_mem_hp20_in_fx[i];
276 633 : old_mem_hp20_in_fx[i] = NULL;
277 : }
278 : /* remove superfluous hp20 memories */
279 858 : FOR( ; i < n_old; i++ )
280 : {
281 771 : free( old_mem_hp20_in_fx[i] );
282 771 : old_mem_hp20_in_fx[i] = NULL;
283 : }
284 :
285 87 : free( old_mem_hp20_in_fx );
286 87 : old_mem_hp20_in_fx = NULL;
287 : }
288 : }
289 :
290 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 );
291 :
292 653 : hSpar = st_ivas->hSpar;
293 :
294 653 : IF( EQ_16( st_ivas->nchan_transport, 1 ) )
295 : {
296 228 : hEncoderConfig->element_mode_init = IVAS_SCE;
297 228 : move16();
298 : }
299 : ELSE
300 : {
301 425 : hEncoderConfig->element_mode_init = IVAS_CPE_MDCT;
302 425 : move16();
303 : }
304 653 : test();
305 653 : test();
306 653 : test();
307 653 : test();
308 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 ) ) )
309 : {
310 : /* FB mixer handle */
311 540 : IF( hDirAC->hFbMixer != NULL )
312 : {
313 0 : ivas_FB_mixer_close_fx( &( hDirAC->hFbMixer ), hEncoderConfig->input_Fs, 0 );
314 0 : hDirAC->hFbMixer = NULL;
315 : }
316 540 : spar_reconfig_flag = 1;
317 540 : move16();
318 540 : ivas_spar_enc_close_fx( &( st_ivas->hSpar ), hEncoderConfig->input_Fs, hEncoderConfig->nchan_inp, spar_reconfig_flag );
319 :
320 540 : IF( NE_32( ( error = ivas_spar_enc_open_fx( st_ivas, spar_reconfig_flag ) ), IVAS_ERR_OK ) )
321 : {
322 0 : return error;
323 : }
324 : }
325 653 : st_ivas->hSpar->spar_reconfig_flag = spar_reconfig_flag;
326 653 : move16();
327 653 : IF( NE_32( ( error = ivas_dirac_enc_reconfigure( st_ivas ) ), IVAS_ERR_OK ) )
328 : {
329 0 : return error;
330 : }
331 653 : test();
332 653 : IF( NE_16( st_ivas->hQMetaData->q_direction->cfg.nbands, nbands_old ) || NE_16( st_ivas->hQMetaData->no_directions, ndir_old ) )
333 : {
334 : Word16 dir, j, i;
335 334 : IVAS_QDIRECTION *q_direction = st_ivas->hQMetaData->q_direction;
336 730 : FOR( dir = 0; dir < st_ivas->hQMetaData->no_directions; dir++ )
337 : {
338 2447 : FOR( j = 0; j < q_direction[dir].cfg.nbands; j++ )
339 : {
340 10255 : FOR( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ )
341 : {
342 8204 : q_direction[dir].band_data[j].energy_ratio_index[i] = 0;
343 8204 : move32();
344 8204 : q_direction[dir].band_data[j].energy_ratio_index_mod[i] = 0;
345 8204 : move32();
346 : }
347 : }
348 : }
349 : }
350 653 : hSpar->enc_param_start_band = hDirAC->hConfig->enc_param_start_band;
351 653 : move16();
352 :
353 : /*-----------------------------------------------------------------*
354 : * Allocate, initialize, and configure SCE/CPE/MCT handles
355 : *-----------------------------------------------------------------*/
356 653 : nchan_transport = st_ivas->nchan_transport;
357 :
358 653 : test();
359 653 : test();
360 653 : IF( old_ism_mode == ISM_MODE_NONE && EQ_32( st_ivas->ism_mode, ISM_SBA_MODE_DISC ) )
361 : {
362 : {
363 186 : nchan_transport = add( st_ivas->nchan_transport, st_ivas->hEncoderConfig->nchan_ism );
364 186 : st_ivas->nCPE = shr_r( nchan_transport, 1 );
365 : }
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 :
371 180 : nchan_transport = st_ivas->nchan_transport;
372 : }
373 287 : ELSE IF( EQ_32( st_ivas->ism_mode, ISM_SBA_MODE_DISC ) )
374 : {
375 69 : nchan_transport_old = add( nchan_transport_old, st_ivas->hEncoderConfig->nchan_ism );
376 69 : nchan_transport = add( st_ivas->nchan_transport, st_ivas->hEncoderConfig->nchan_ism );
377 69 : st_ivas->nCPE = shr_r( nchan_transport, 1 );
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 : }
|