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 "ivas_prot_fx.h"
39 : #include "prot_fx.h"
40 : #include "ivas_rom_com.h"
41 : #include "ivas_rom_enc.h"
42 : #include "wmc_auto.h"
43 : #ifdef DEBUGGING
44 : #include "debug.h"
45 : #endif
46 :
47 :
48 : /*-------------------------------------------------------------------------
49 : * Local function prototypes
50 : *------------------------------------------------------------------------*/
51 : static void ivas_omasa_param_est_enc_fx(
52 : OMASA_ENC_HANDLE hOMasa,
53 : OMASA_ENCODER_DATA_HANDLE hOmasaData,
54 : ISM_METADATA_HANDLE hIsmMeta[],
55 : Word32 *data[], /*i:q_data*/
56 : Word32 elevation_m_values_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /*o:q22*/
57 : Word32 azimuth_m_values_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /*o:q22*/
58 : Word32 energyRatio_fx[MASA_FREQUENCY_BANDS], /*o:Q30*/
59 : Word16 spreadCoherence_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /*o:Q15*/
60 : Word16 surroundingCoherence_fx[MASA_FREQUENCY_BANDS], /*o:Q15*/
61 : Word32 diffuseness_m_fx[MASA_FREQUENCY_BANDS], /*o:q30*/
62 : const Word16 input_frame,
63 : const Word16 nchan_ism,
64 : Word16 q_data /*i: Qfactor for data*/
65 : );
66 :
67 : static void ivas_omasa_energy_and_ratio_est_fx(
68 : OMASA_ENC_HANDLE hOMasa,
69 : OMASA_ENCODER_DATA_HANDLE hOmasaData,
70 : Word32 *data_fx[],
71 : const Word16 input_frame,
72 : const Word16 nchan_ism,
73 : const Word16 q_data );
74 :
75 : static void ivas_omasa_dmx_fx(
76 : Word32 *data_in[], /*i:Qx*/
77 : Word32 data_out[][L_FRAME48k], /*i:Qx*/
78 : const Word16 input_frame, /*i:q0*/
79 : const Word16 nchan_transport, /*i:q0*/
80 : const Word16 nchan_ism, /*i:q0*/
81 : ISM_METADATA_HANDLE hIsmMeta[], /*i*/
82 : Word16 prev_gains[][MASA_MAX_TRANSPORT_CHANNELS], /*o:q15*/
83 : const Word16 interpolator[L_FRAME48k] /*i:q15*/
84 : );
85 :
86 : void computeIntensityVector_enc_fx(
87 : const Word16 *band_grouping,
88 : Word32 Cldfb_RealBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /*inp_q*/
89 : Word32 Cldfb_ImagBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /*inp_q*/
90 : const Word16 num_frequency_bands,
91 : Word32 intensity_real[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS], /*exp: exp_intensity_real*/
92 : Word16 q_intensity_real[MASA_FREQUENCY_BANDS],
93 : Word16 inp_q );
94 :
95 : static void computeReferencePower_omasa_ivas_fx( const Word16 *band_grouping, Word32 Cldfb_RealBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], Word32 Cldfb_ImagBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], Word32 *reference_power, const Word16 enc_param_start_band, const Word16 num_freq_bands, Word16 q_Cldfb, Word16 q_reference_power[CLDFB_NO_CHANNELS_MAX] );
96 : /*--------------------------------------------------------------------------*
97 : * ivas_omasa_enc_open()
98 : *
99 : * Allocate and initialize OMASA handle
100 : *--------------------------------------------------------------------------*/
101 :
102 464 : ivas_error ivas_omasa_enc_open_fx(
103 : Encoder_Struct *st_ivas /* i/o: IVAS encoder handle */
104 : )
105 : {
106 : Word16 i, j;
107 : OMASA_ENC_HANDLE hOMasa;
108 : Word16 numAnalysisChannels;
109 : Word16 input_frame;
110 : ivas_error error;
111 :
112 464 : error = IVAS_ERR_OK;
113 464 : move16();
114 :
115 464 : assert( st_ivas->hMasa != NULL && "MASA encoder handle is not present" );
116 :
117 464 : IF( ( hOMasa = (OMASA_ENC_HANDLE) malloc( sizeof( OMASA_ENC_STATE ) ) ) == NULL )
118 : {
119 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for OMASA encoder\n" ) );
120 : }
121 :
122 464 : numAnalysisChannels = st_ivas->hEncoderConfig->nchan_ism;
123 464 : move16();
124 :
125 : /* open/initialize CLDFB */
126 464 : hOMasa->num_Cldfb_instances = numAnalysisChannels;
127 464 : move16();
128 1906 : FOR( i = 0; i < hOMasa->num_Cldfb_instances; i++ )
129 : {
130 1442 : IF( ( error = openCldfb_ivas_fx( &( hOMasa->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, st_ivas->hEncoderConfig->input_Fs, CLDFB_PROTOTYPE_5_00MS, ENC ) ) != IVAS_ERR_OK )
131 : {
132 0 : return error;
133 : }
134 : }
135 464 : set_zero_fx( &hOMasa->chnlToFoaMtx_fx[0][0], DIRAC_MAX_ANA_CHANS * MCMASA_MAX_ANA_CHANS );
136 :
137 : /* intensity 3-dim */
138 1856 : FOR( i = 0; i < DIRAC_NUM_DIMS; i++ )
139 : {
140 1392 : hOMasa->direction_vector_m_fx[i] = (Word32 **) malloc( MAX_PARAM_SPATIAL_SUBFRAMES * sizeof( Word32 * ) );
141 :
142 6960 : FOR( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ )
143 : {
144 5568 : IF( ( hOMasa->direction_vector_m_fx[i][j] = (Word32 *) malloc( MASA_FREQUENCY_BANDS * sizeof( Word32 ) ) ) == NULL )
145 : {
146 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for OMASA data\n" ) );
147 : }
148 5568 : set_zero_fx( hOMasa->direction_vector_m_fx[i][j], MASA_FREQUENCY_BANDS );
149 : }
150 1392 : hOMasa->direction_vector_e[i] = (Word16 **) malloc( MAX_PARAM_SPATIAL_SUBFRAMES * sizeof( Word16 * ) );
151 :
152 6960 : FOR( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ )
153 : {
154 5568 : IF( ( hOMasa->direction_vector_e[i][j] = (Word16 *) malloc( MASA_FREQUENCY_BANDS * sizeof( Word16 ) ) ) == NULL )
155 : {
156 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for OMASA data\n" ) );
157 : }
158 5568 : set16_fx( hOMasa->direction_vector_e[i][j], 0, MASA_FREQUENCY_BANDS );
159 : }
160 : }
161 :
162 1856 : FOR( i = 0; i < DIRAC_NUM_DIMS; i++ )
163 : {
164 45936 : FOR( j = 0; j < DIRAC_NO_COL_AVG_DIFF; j++ )
165 : {
166 44544 : IF( ( hOMasa->buffer_intensity_real_fx[i][j] = (Word32 *) malloc( MASA_FREQUENCY_BANDS * sizeof( Word32 ) ) ) == NULL )
167 : {
168 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for OMASA data\n" ) );
169 : }
170 44544 : set_zero_fx( hOMasa->buffer_intensity_real_fx[i][j], MASA_FREQUENCY_BANDS );
171 : }
172 : }
173 464 : set16_fx( hOMasa->buffer_intensity_real_q, 31, DIRAC_NO_COL_AVG_DIFF );
174 464 : set_zero_fx( hOMasa->buffer_energy_fx, DIRAC_NO_COL_AVG_DIFF * MASA_FREQUENCY_BANDS );
175 464 : set16_fx( hOMasa->buffer_energy_q, 31, DIRAC_NO_COL_AVG_DIFF );
176 :
177 2320 : FOR( i = 0; i < MAX_NUM_OBJECTS; i++ )
178 : {
179 1856 : set16_fx( hOMasa->prev_object_dm_gains_fx[i], INV_SQRT_2_Q15, MASA_MAX_TRANSPORT_CHANNELS ); /*q15*/
180 : }
181 464 : set_zero_fx( hOMasa->broadband_energy_sm_fx, MAX_NUM_OBJECTS + MASA_MAX_TRANSPORT_CHANNELS );
182 464 : hOMasa->broadband_energy_sm_e = 0;
183 464 : move16();
184 464 : set_zero_fx( hOMasa->broadband_energy_prev_fx, MAX_NUM_OBJECTS + MASA_MAX_TRANSPORT_CHANNELS );
185 464 : hOMasa->broadband_energy_prev_e = 0;
186 464 : move16();
187 :
188 464 : hOMasa->prev_selected_object = 0;
189 464 : hOMasa->changing_object = 0;
190 464 : move16();
191 464 : move16();
192 :
193 464 : input_frame = extract_l( Mult_32_16( st_ivas->hEncoderConfig->input_Fs /*q0*/, INV_FRAME_PER_SEC_Q15 /*q15*/ ) ); /*Q0+Q15-Q15->Q0*/
194 420304 : FOR( i = 0; i < input_frame; i++ )
195 : {
196 419840 : hOMasa->interpolator_fx[i] = divide1616( i, input_frame ); /*q15*/
197 419840 : hOMasa->fade_out_gain_fx[i] = add( 16384 /*0.5 in q15*/, shr( getCosWord16R2( mult( hOMasa->interpolator_fx[i], 32767 / 2 ) /*15+15-15=>15*/ ), 1 ) /*q15*/ ); /*(angle in degrees=((float)i/(float)input_frame *pi)*180/pi)/360*32767 =>(float)i/(float)input_frame )*32767/2*/ /*q15*/
198 419840 : hOMasa->fade_in_gain_fx[i] = sub( 32767 /*1.0 in Q15*/, hOMasa->fade_out_gain_fx[i] ); /*q15*/
199 419840 : move16();
200 419840 : move16();
201 419840 : move16();
202 : }
203 :
204 464 : hOMasa->index_buffer_intensity = 0;
205 464 : move16();
206 :
207 464 : st_ivas->hOMasa = hOMasa;
208 :
209 464 : return error;
210 : }
211 :
212 : /*--------------------------------------------------------------------------*
213 : * ivas_omasa_enc_close()
214 : *
215 : * Close OMASA handle
216 : *--------------------------------------------------------------------------*/
217 :
218 :
219 1063 : void ivas_omasa_enc_close_fx(
220 : OMASA_ENC_HANDLE *hOMasa /* i/o: encoder OMASA handle */
221 : )
222 : {
223 : Word16 i, j;
224 :
225 1063 : test();
226 1063 : IF( hOMasa == NULL || *hOMasa == NULL )
227 : {
228 599 : return;
229 : }
230 :
231 1906 : FOR( i = 0; i < ( *hOMasa )->num_Cldfb_instances; i++ )
232 : {
233 1442 : deleteCldfb_ivas_fx( &( ( *hOMasa )->cldfbAnaEnc[i] ) );
234 : }
235 :
236 1856 : FOR( i = 0; i < DIRAC_NUM_DIMS; i++ )
237 : {
238 6960 : FOR( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ )
239 : {
240 5568 : free( ( *hOMasa )->direction_vector_m_fx[i][j] );
241 5568 : ( *hOMasa )->direction_vector_m_fx[i][j] = NULL;
242 5568 : free( ( *hOMasa )->direction_vector_e[i][j] );
243 5568 : ( *hOMasa )->direction_vector_e[i][j] = NULL;
244 : }
245 :
246 45936 : FOR( j = 0; j < DIRAC_NO_COL_AVG_DIFF; j++ )
247 : {
248 44544 : free( ( *hOMasa )->buffer_intensity_real_fx[i][j] );
249 44544 : ( *hOMasa )->buffer_intensity_real_fx[i][j] = NULL;
250 : }
251 1392 : free( ( *hOMasa )->direction_vector_m_fx[i] );
252 1392 : ( *hOMasa )->direction_vector_m_fx[i] = NULL;
253 1392 : free( ( *hOMasa )->direction_vector_e[i] );
254 1392 : ( *hOMasa )->direction_vector_e[i] = NULL;
255 : }
256 :
257 464 : free( *hOMasa );
258 464 : ( *hOMasa ) = NULL;
259 :
260 464 : return;
261 : }
262 :
263 : /*--------------------------------------------------------------------------*
264 : * ivas_omasa_enc_config()
265 : *
266 : * oMASA encoder configuration
267 : *--------------------------------------------------------------------------*/
268 9000 : ivas_error ivas_omasa_enc_config_fx(
269 : Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */
270 : )
271 : {
272 : Word16 k, sce_id, nSCE_old;
273 : Word32 ivas_total_brate, ism_total_brate;
274 : ENCODER_CONFIG_HANDLE hEncoderConfig;
275 : ivas_error error;
276 :
277 9000 : hEncoderConfig = st_ivas->hEncoderConfig;
278 9000 : ivas_total_brate = hEncoderConfig->ivas_total_brate;
279 9000 : nSCE_old = st_ivas->nSCE;
280 9000 : move16();
281 9000 : move32(); /*hEncoderConfig->ivas_total_brate*/
282 :
283 9000 : st_ivas->ism_mode = ivas_omasa_ism_mode_select_fx( ivas_total_brate, hEncoderConfig->nchan_ism );
284 9000 : move16();
285 9000 : st_ivas->nchan_transport = 2;
286 9000 : move16();
287 :
288 : /* reconfiguration in case of bitrate switching */
289 9000 : IF( NE_32( hEncoderConfig->last_ivas_total_brate, ivas_total_brate ) )
290 : {
291 1634 : ivas_set_omasa_TC_fx( st_ivas->ism_mode, hEncoderConfig->nchan_ism, &st_ivas->nSCE, &st_ivas->nCPE );
292 :
293 1634 : k = 0;
294 1634 : move16();
295 12910 : WHILE( ( k < SIZE_IVAS_BRATE_TBL ) && ( ivas_total_brate != ivas_brate_tbl[k] ) )
296 : {
297 11276 : test();
298 11276 : k = add( k, 1 );
299 : }
300 :
301 1634 : ism_total_brate = 0;
302 1634 : move32();
303 3746 : FOR( sce_id = 0; sce_id < st_ivas->nSCE; sce_id++ )
304 : {
305 2112 : ism_total_brate = L_add( ism_total_brate, sep_object_brate[k - 2][st_ivas->nSCE - 1] );
306 : }
307 :
308 1634 : IF( EQ_16( st_ivas->ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) )
309 : {
310 403 : IF( ( error = ivas_ism_config_fx( st_ivas->hEncoderConfig->ivas_total_brate, st_ivas->nchan_transport, 1, NULL, 0, NULL, NULL, NULL, NULL, NULL, 1 ) ) != IVAS_ERR_OK )
311 : {
312 0 : return error;
313 : }
314 : }
315 1231 : ELSE IF( EQ_16( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) )
316 : {
317 439 : IF( ( error = ivas_ism_config_fx( st_ivas->hEncoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->nSCE, NULL, 0, NULL, NULL, NULL, NULL, NULL, 1 ) ) != IVAS_ERR_OK )
318 : {
319 0 : return error;
320 : }
321 : }
322 :
323 : /* reconfigure core-coders for ISMs */
324 1634 : IF( st_ivas->nSCE > 0 )
325 : {
326 1190 : IF( ( error = ivas_corecoder_enc_reconfig_fx( st_ivas, nSCE_old, 1, 2, sep_object_brate[k - 2][st_ivas->nSCE - 1], L_sub( ivas_total_brate, ism_total_brate ), MC_MODE_NONE ) ) != IVAS_ERR_OK )
327 : {
328 0 : return error;
329 : }
330 : }
331 : ELSE
332 : {
333 444 : IF( ( error = ivas_corecoder_enc_reconfig_fx( st_ivas, nSCE_old, 1, 2, 0, L_sub( ivas_total_brate, ism_total_brate ), MC_MODE_NONE ) ) != IVAS_ERR_OK )
334 : {
335 0 : return error;
336 : }
337 : }
338 :
339 : /* re-write IVAS format signalling - actual 'ism_mode' was not known before */
340 1634 : IF( st_ivas->nSCE > 0 )
341 : {
342 1190 : reset_indices_enc_fx( st_ivas->hSCE[0]->hCoreCoder[0]->hBstr, st_ivas->hSCE[0]->hCoreCoder[0]->hBstr->nb_bits_tot );
343 : }
344 : ELSE
345 : {
346 444 : reset_indices_enc_fx( st_ivas->hCPE[0]->hCoreCoder[0]->hBstr, st_ivas->hCPE[0]->hCoreCoder[0]->hBstr->nb_bits_tot );
347 : }
348 :
349 1634 : ivas_write_format_fx( st_ivas );
350 :
351 1634 : test();
352 1634 : test();
353 1634 : IF( NE_16( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) && st_ivas->hOMasa == NULL )
354 : {
355 437 : IF( ( error = ivas_omasa_enc_open_fx( st_ivas ) ) != IVAS_ERR_OK )
356 : {
357 0 : return error;
358 : }
359 : }
360 1197 : ELSE IF( EQ_16( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) && st_ivas->hOMasa != NULL )
361 : {
362 439 : ivas_omasa_enc_close_fx( &( st_ivas->hOMasa ) );
363 439 : st_ivas->hOMasa = NULL;
364 : }
365 :
366 1634 : st_ivas->hCPE[0]->element_brate = L_sub( ivas_total_brate, ism_total_brate );
367 1634 : move32();
368 :
369 1634 : IF( GE_32( L_sub( ivas_total_brate, ism_total_brate ), MIN_BRATE_MDCT_STEREO ) )
370 : {
371 709 : hEncoderConfig->element_mode_init = IVAS_CPE_MDCT;
372 : }
373 : ELSE
374 : {
375 925 : hEncoderConfig->element_mode_init = IVAS_CPE_DFT;
376 : }
377 1634 : move16();
378 : }
379 :
380 : /* Configure MASA encoder based on frame parameters */
381 9000 : IF( ( error = ivas_masa_enc_config_fx( st_ivas ) ) != IVAS_ERR_OK )
382 : {
383 0 : return error;
384 : }
385 :
386 9000 : IF( NE_16( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) )
387 : {
388 : /* Configure oMASA analysis based on MASA config */
389 5858 : ivas_omasa_set_config_fx( st_ivas->hOMasa, st_ivas->hMasa, st_ivas->hEncoderConfig->input_Fs, st_ivas->ism_mode );
390 : }
391 :
392 9000 : return IVAS_ERR_OK;
393 : }
394 :
395 :
396 : /*--------------------------------------------------------------------------*
397 : * ivas_omasa_set_config()
398 : *
399 : * Frame-by-frame config for oMASA
400 : *--------------------------------------------------------------------------*/
401 5858 : void ivas_omasa_set_config_fx(
402 : OMASA_ENC_HANDLE hOMasa, /* i/o: OMASA encoder handle */
403 : MASA_ENCODER_HANDLE hMasa, /* i : MASA encoder handle */
404 : const Word32 input_Fs, /* i : Input sample rate */
405 : const ISM_MODE ism_mode /* i : ISM mode */
406 : )
407 : {
408 : UWord8 i, maxBin;
409 :
410 : /* Determine the number of bands */
411 5858 : test();
412 5858 : IF( EQ_16( ism_mode, ISM_MODE_NONE ) || EQ_16( ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) )
413 : {
414 : /* use full resolution for the ISM+MASA merge and reduce later */
415 3996 : hOMasa->nbands = 24;
416 : }
417 : ELSE
418 : {
419 1862 : hOMasa->nbands = hMasa->config.numCodingBands;
420 : }
421 5858 : move16();
422 :
423 5858 : hOMasa->nCodingBands = hMasa->config.numCodingBands;
424 5858 : move16();
425 :
426 : /* Determine the number of subframes */
427 5858 : IF( EQ_16( hMasa->config.joinedSubframes, TRUE ) )
428 1426 : hOMasa->nSubframes = 1;
429 : ELSE
430 4432 : hOMasa->nSubframes = MAX_PARAM_SPATIAL_SUBFRAMES;
431 5858 : move16();
432 :
433 : /* Determine band grouping */
434 5858 : IF( EQ_16( hOMasa->nbands, 24 ) )
435 : {
436 3996 : Copy( MASA_band_grouping_24, hOMasa->band_grouping, 24 + 1 );
437 : }
438 : ELSE
439 : {
440 15680 : FOR( i = 0; i < hOMasa->nbands + 1; i++ )
441 : {
442 13818 : hOMasa->band_grouping[i] = MASA_band_grouping_24[hMasa->data.band_mapping[i]];
443 13818 : move16();
444 : }
445 : }
446 :
447 5858 : maxBin = (UWord8) L_shr( L_add( Mpy_32_32( L_shl( input_Fs, 1 ), INV_CLDFB_BANDWIDTH_Q31 ), 1 ), 1 ); /*(uint8_t) ( input_Fs * INV_CLDFB_BANDWIDTH + 0.5f )*/
448 5858 : move16();
449 :
450 106960 : FOR( i = 1; i < hOMasa->nbands + 1; i++ )
451 : {
452 106960 : IF( GE_16( hOMasa->band_grouping[i], maxBin ) )
453 : {
454 5858 : hOMasa->band_grouping[i] = maxBin;
455 5858 : hOMasa->nbands = i;
456 5858 : move16();
457 5858 : move16();
458 5858 : BREAK;
459 : }
460 : }
461 :
462 5858 : Copy( DirAC_block_grouping, hOMasa->block_grouping, MAX_PARAM_SPATIAL_SUBFRAMES + 1 ); // Q0
463 5858 : IF( EQ_16( hOMasa->nSubframes, 1 ) )
464 : {
465 1426 : hOMasa->block_grouping[1] = hOMasa->block_grouping[MAX_PARAM_SPATIAL_SUBFRAMES];
466 1426 : move16();
467 : }
468 :
469 5858 : return;
470 : }
471 :
472 :
473 : /*--------------------------------------------------------------------------*
474 : * ivas_omasa_enc()
475 : *
476 : * Main OMASA encoding function
477 : *--------------------------------------------------------------------------*/
478 5858 : void ivas_omasa_enc_fx(
479 : OMASA_ENC_HANDLE hOMasa, /* i/o: OMASA encoder handle */
480 : MASA_ENCODER_HANDLE hMasa, /* i/o: MASA encoder handle */
481 : ISM_METADATA_HANDLE hIsmMeta[], /* i/o: ISM metadata handle */
482 : Word32 *data_in[], /* i/o: Input / transport audio signals q_data*/
483 : Word16 q_data, /* i : Q0 Stores the q for data_in */
484 : const Word16 input_frame, /* i : Input frame size */
485 : const Word16 nchan_transport, /* i : Number of transport channels */
486 : const Word16 nchan_ism, /* i : Number of objects for parameter analysis */
487 : const ISM_MODE ism_mode, /* i : ISM mode */
488 : Word32 *data_separated_object_fx, /* o : Separated object audio signal */
489 : Word16 *idx_separated_object /* o : Index of the separated object */
490 : )
491 : {
492 : Word16 i, j;
493 : Word32 data_out[MASA_MAX_TRANSPORT_CHANNELS][L_FRAME48k];
494 :
495 : /* Determine separated object (when applicable) */
496 5858 : test();
497 5858 : IF( EQ_16( ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) || EQ_16( ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) )
498 : {
499 : Word32 broadband_energy_fx[MAX_NUM_OBJECTS + MASA_MAX_TRANSPORT_CHANNELS];
500 : Word16 broadband_energy_e[MAX_NUM_OBJECTS + MASA_MAX_TRANSPORT_CHANNELS];
501 3916 : Word16 max_broadband_energy_e = MIN_16;
502 3916 : move16();
503 : Word16 loudest_object;
504 : Word16 selected_object;
505 : Word16 nchan_all_inp;
506 : UWord8 fade_out_separate_object;
507 : UWord8 fade_in_separate_object;
508 : Word32 temp32; /*temp32_e*/
509 : /* Estimate broadband energies */
510 3916 : nchan_all_inp = add( nchan_ism, nchan_transport );
511 3916 : set_zero_fx( broadband_energy_fx, nchan_all_inp );
512 3916 : set16_fx( broadband_energy_e, 0, nchan_all_inp );
513 :
514 25272 : FOR( i = 0; i < nchan_all_inp; i++ )
515 : {
516 19569516 : FOR( j = 0; j < input_frame; j++ )
517 : {
518 19548160 : temp32 = L_shl( data_in[i][j], 6 ); /* scaling data_in to prevent zeroes values in Mpy_32_32 due to precision loss*/
519 19548160 : broadband_energy_fx[i] = BASOP_Util_Add_Mant32Exp( broadband_energy_fx[i], broadband_energy_e[i], Mpy_32_32( temp32, temp32 ), sub( 50, shl( q_data, 1 ) ) /*exponent=62-2*(q+6)*/, &broadband_energy_e[i] );
520 19548160 : move32();
521 : }
522 21356 : max_broadband_energy_e = s_max( max_broadband_energy_e, broadband_energy_e[i] ); /*calculating maximum exponent for all values in broadband_energy_e*/
523 : }
524 :
525 : /*scaling all the values in broadband_energy_fx to max_broadband_energy_e*/
526 25272 : FOR( i = 0; i < nchan_all_inp; i++ )
527 : {
528 21356 : broadband_energy_fx[i] = L_shr( broadband_energy_fx[i], sub( max_broadband_energy_e, broadband_energy_e[i] ) );
529 21356 : move32();
530 : }
531 : /*making exponent for hOMasa->broadband_energy_sm_fx and broadband_energy_fx equal as they are used in addition later*/
532 3916 : IF( GT_16( max_broadband_energy_e, hOMasa->broadband_energy_sm_e ) )
533 : {
534 680 : Scale_sig32( hOMasa->broadband_energy_sm_fx, nchan_all_inp, sub( hOMasa->broadband_energy_sm_e, max_broadband_energy_e ) );
535 680 : hOMasa->broadband_energy_sm_e = max_broadband_energy_e;
536 680 : move16();
537 : }
538 : ELSE
539 : {
540 3236 : Scale_sig32( broadband_energy_fx, nchan_all_inp, sub( max_broadband_energy_e, hOMasa->broadband_energy_sm_e ) );
541 3236 : max_broadband_energy_e = hOMasa->broadband_energy_sm_e;
542 3236 : move16();
543 : }
544 :
545 : /* Temporal averaging */
546 : // alpha = 26214;/*0.8 Q15*/
547 25272 : FOR( i = 0; i < nchan_all_inp; i++ )
548 : {
549 21356 : hOMasa->broadband_energy_sm_fx[i] = L_add( Mpy_32_16_1( broadband_energy_fx[i], 6554 /*0.2 Q15*/ ), Mpy_32_16_1( hOMasa->broadband_energy_sm_fx[i], 26214 /*0.8 Q15*/ ) );
550 21356 : move32();
551 : }
552 :
553 : /* Determine loudest object */
554 3916 : loudest_object = 0;
555 3916 : move16();
556 13524 : FOR( i = 1; i < nchan_ism; i++ )
557 : {
558 9608 : if ( GT_32( hOMasa->broadband_energy_sm_fx[i], hOMasa->broadband_energy_sm_fx[loudest_object] ) )
559 : {
560 1998 : loudest_object = i;
561 1998 : move16();
562 : }
563 : }
564 :
565 : /* Determine object to separate */
566 3916 : selected_object = hOMasa->prev_selected_object;
567 3916 : fade_out_separate_object = 0;
568 3916 : fade_in_separate_object = 0;
569 3916 : move16();
570 3916 : move16();
571 3916 : move16();
572 3916 : IF( hOMasa->changing_object )
573 : {
574 125 : hOMasa->changing_object = 0;
575 125 : selected_object = loudest_object;
576 125 : fade_in_separate_object = 1;
577 125 : move16();
578 125 : move16();
579 125 : move16();
580 : }
581 : ELSE
582 : {
583 3791 : IF( NE_16( loudest_object, hOMasa->prev_selected_object ) )
584 : {
585 : Word32 selected_ene_fx; /*selected_ene_e*/
586 : Word16 selected_ene_e;
587 : Word32 total_ene_fx; /*total_ene_e*/
588 : Word16 total_ene_e;
589 : Word32 selected_ratio_fx; /*selected_ratio_e*/
590 : Word16 selected_ratio_e;
591 : Word32 adaptive_threshold_dB_fx;
592 : Word32 ratio_objects_dB_fx;
593 : Word32 hardswitch_threshold_fx; /*(0.25 q30) as selected_ratio_fx is in q30(both are compared later)*/
594 : Word16 temp32_e;
595 763 : selected_ene_e = 0;
596 763 : temp32_e = 0;
597 763 : hardswitch_threshold_fx = 268435456; /*(0.25 q30)*/
598 763 : selected_ratio_e = 0;
599 763 : total_ene_e = 0;
600 763 : move16();
601 763 : move16();
602 763 : move16();
603 763 : move16();
604 763 : move32();
605 :
606 : /* Compute the energy of the current and the previous selected object in the current and the previous frame */
607 : /*scaling broadband_energy_fx and broadband_energy_prev_fx by 1 (guard bit for addition operation)*/
608 763 : selected_ene_fx = BASOP_Util_Add_Mant32Exp( L_add( L_shr( broadband_energy_fx[loudest_object], 1 ), L_shr( broadband_energy_fx[hOMasa->prev_selected_object], 1 ) ), add( max_broadband_energy_e, 1 ), L_add( L_shr( hOMasa->broadband_energy_prev_fx[loudest_object], 1 ), L_shr( hOMasa->broadband_energy_prev_fx[hOMasa->prev_selected_object], 1 ) ), add( hOMasa->broadband_energy_prev_e, 1 ), &selected_ene_e );
609 :
610 : /* Compute the energy of all objects and MASA channels in the current and the previous frame */
611 763 : total_ene_fx = 0;
612 763 : move32();
613 4917 : FOR( i = 0; i < nchan_all_inp; i++ )
614 : {
615 4154 : total_ene_fx = BASOP_Util_Add_Mant32Exp( total_ene_fx, total_ene_e, broadband_energy_fx[i], max_broadband_energy_e, &total_ene_e );
616 4154 : total_ene_fx = BASOP_Util_Add_Mant32Exp( total_ene_fx, total_ene_e, hOMasa->broadband_energy_prev_fx[i], hOMasa->broadband_energy_prev_e, &total_ene_e );
617 : }
618 :
619 : /* Compute the ratio */
620 763 : selected_ratio_fx = BASOP_Util_Divide3232_Scale( selected_ene_fx, L_add_sat( total_ene_fx, EPSILON_FX ), &selected_ratio_e );
621 763 : selected_ratio_e = add( selected_ratio_e, sub( selected_ene_e, total_ene_e ) );
622 763 : selected_ratio_fx = L_shl( selected_ratio_fx, add( selected_ratio_e, 15 ) ); /*scaling to q30 as the value will always be <=1*/
623 763 : adaptive_threshold_dB_fx = L_add( Mpy_32_16_1( selected_ratio_fx /*q30*/, 576 /*9 in q6*/ ), ONE_IN_Q21 ); /* selected ratio = 0 -> 1 dB, selected ratio = 1 -> 10 dB */ /*q21*/
624 763 : temp32 = BASOP_Util_Divide3232_Scale( hOMasa->broadband_energy_sm_fx[loudest_object], L_add_sat( hOMasa->broadband_energy_sm_fx[hOMasa->prev_selected_object], EPSILON_FX ), &temp32_e );
625 763 : ratio_objects_dB_fx = Mult_32_16( BASOP_Util_Log10( temp32, add( 16, temp32_e ) ) /*q25*/, 20480 /*10 in q11*/ ); /*q21 as the maximum value can go up to 320*/
626 :
627 : /* Adaptively determine whether to change the separated object. If they are quiet compared to the total energy, change easier, as other signals mask the change. */
628 763 : IF( GT_32( ratio_objects_dB_fx, adaptive_threshold_dB_fx ) )
629 : {
630 184 : IF( LT_32( selected_ratio_fx, hardswitch_threshold_fx ) ) /* If low level compared to all audio channels, perform hardswitch */
631 : {
632 53 : selected_object = loudest_object;
633 53 : move16();
634 : }
635 : ELSE /* If high level compared to all audio channels, perform switch via fade out fade in */
636 : {
637 131 : hOMasa->changing_object = 1;
638 131 : fade_out_separate_object = 1;
639 131 : move16();
640 131 : move16();
641 : }
642 : }
643 : }
644 : }
645 :
646 : /* Set values for next frame */
647 25272 : FOR( i = 0; i < nchan_all_inp; i++ )
648 : {
649 21356 : hOMasa->broadband_energy_prev_fx[i] = broadband_energy_fx[i];
650 21356 : hOMasa->broadband_energy_prev_e = max_broadband_energy_e;
651 21356 : move32();
652 21356 : move16();
653 : }
654 3916 : hOMasa->prev_selected_object = selected_object;
655 3916 : move16();
656 :
657 : /* Separate the selected object */
658 3916 : *idx_separated_object = selected_object;
659 3916 : move16();
660 3916 : Copy32( data_in[selected_object], data_separated_object_fx, input_frame );
661 3916 : IF( fade_out_separate_object )
662 : {
663 131 : v_L_mult_3216( data_separated_object_fx, hOMasa->fade_out_gain_fx, data_separated_object_fx, input_frame ); /*q_data + q15 -q15*/
664 131 : v_L_mult_3216( data_in[selected_object], hOMasa->fade_in_gain_fx, data_in[selected_object], input_frame ); /*q_data + q15 -q15*/
665 : }
666 3785 : ELSE IF( fade_in_separate_object )
667 : {
668 125 : v_L_mult_3216( data_separated_object_fx, hOMasa->fade_in_gain_fx, data_separated_object_fx, input_frame ); /*q_data + q15 -q15*/
669 125 : v_L_mult_3216( data_in[selected_object], hOMasa->fade_out_gain_fx, data_in[selected_object], input_frame ); /*q_data + q15 -q15*/
670 : }
671 : ELSE
672 : {
673 3660 : set_zero_fx( data_in[selected_object], input_frame );
674 : }
675 : }
676 :
677 : /* Analysis */
678 5858 : test();
679 5858 : IF( EQ_16( ism_mode, ISM_MODE_NONE ) || EQ_16( ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) )
680 3996 : {
681 : OMASA_SPATIAL_META OMasaMeta; /* working memory for the ISM-object MASA-parameters */
682 : OMASA_SPATIAL_META_HANDLE hOMasaMeta;
683 : UWord8 n_bands_orig, n_subframes_orig;
684 : UWord8 numCodingBands_orig, joinedSubframes_orig;
685 :
686 3996 : hOMasaMeta = &OMasaMeta;
687 3996 : hOMasaMeta->num_dirs = 1;
688 3996 : move16();
689 :
690 : /* merge MASA directions before adding ISM to the mixture */
691 3996 : IF( EQ_16( hMasa->config.numberOfDirections, 2 ) )
692 : {
693 2198 : n_bands_orig = hMasa->config.numCodingBands;
694 2198 : move16();
695 2198 : hMasa->config.numCodingBands = MASA_FREQUENCY_BANDS;
696 2198 : move16();
697 : /* Estimate the importance of having two directions instead of one */
698 :
699 2198 : ivas_masa_combine_directions_fx( hMasa );
700 :
701 2198 : hMasa->config.numCodingBands = (Word8) n_bands_orig;
702 2198 : move16();
703 : }
704 :
705 : /* force computation into high resolution */
706 :
707 3996 : n_subframes_orig = hOMasa->nSubframes;
708 3996 : hOMasa->nSubframes = MAX_PARAM_SPATIAL_SUBFRAMES;
709 3996 : move16();
710 3996 : move16();
711 :
712 : /* Estimate MASA parameters from the objects */
713 : /* NB: only first direction is populated */
714 : /* NB2: in energy_ratios and surround_coherence only first sub-frame contains valid data */
715 3996 : ivas_omasa_param_est_enc_fx( hOMasa, hMasa->data.hOmasaData, hIsmMeta, data_in, hOMasaMeta->directional_meta[0].elevation_fx, hOMasaMeta->directional_meta[0].azimuth_fx, hOMasaMeta->directional_meta[0].energy_ratio_fx[0], hOMasaMeta->directional_meta[0].spread_coherence_fx, hOMasaMeta->common_meta.surround_coherence_fx[0],
716 3996 : hOMasaMeta->common_meta.diffuse_to_total_ratio_fx[0], input_frame, nchan_ism, q_data );
717 :
718 : /* copy energy_ratios and surrCoh from first sub-frame to the remaining ones */
719 15984 : FOR( i = 1; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ )
720 : {
721 11988 : Copy32( hOMasaMeta->directional_meta[0].energy_ratio_fx[0], hOMasaMeta->directional_meta[0].energy_ratio_fx[i], MASA_FREQUENCY_BANDS ); /*q30*/
722 11988 : Copy( hOMasaMeta->common_meta.surround_coherence_fx[0], hOMasaMeta->common_meta.surround_coherence_fx[i], MASA_FREQUENCY_BANDS ); /*q14*/
723 11988 : Copy32( hOMasaMeta->common_meta.diffuse_to_total_ratio_fx[0], hOMasaMeta->common_meta.diffuse_to_total_ratio_fx[i], MASA_FREQUENCY_BANDS ); /*q30*/
724 : }
725 :
726 : /* restore resolution parameters */
727 3996 : hOMasa->nSubframes = n_subframes_orig;
728 3996 : move16();
729 :
730 : /* perform MASA+ISM merge in full resolution */
731 3996 : numCodingBands_orig = hMasa->config.numCodingBands;
732 3996 : joinedSubframes_orig = hMasa->config.joinedSubframes;
733 3996 : move16();
734 3996 : move16();
735 :
736 3996 : hMasa->config.numCodingBands = hOMasa->nbands;
737 3996 : hMasa->config.joinedSubframes = 0;
738 3996 : move16();
739 3996 : move16();
740 :
741 3996 : ivas_merge_masa_metadata_fx( hMasa, hOMasaMeta ); /* => merge result in hMasa->masaMetadata */
742 :
743 3996 : hMasa->config.numCodingBands = numCodingBands_orig;
744 3996 : hMasa->config.joinedSubframes = joinedSubframes_orig;
745 3996 : move16();
746 3996 : move16();
747 : }
748 1862 : ELSE IF( EQ_16( ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) )
749 : {
750 : /* Estimate energies and ratios */
751 1862 : ivas_omasa_energy_and_ratio_est_fx( hOMasa, hMasa->data.hOmasaData, data_in, input_frame, nchan_ism, q_data );
752 : }
753 :
754 : /* Downmix */
755 :
756 5858 : ivas_omasa_dmx_fx( data_in, data_out, input_frame, nchan_transport, nchan_ism, hIsmMeta, hOMasa->prev_object_dm_gains_fx, hOMasa->interpolator_fx );
757 : /* Move the ISM metadata to the first entry for encoding in the MASA_ONE_OBJ mode */
758 5858 : IF( EQ_16( ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) )
759 : {
760 2054 : hIsmMeta[0]->azimuth_fx = hIsmMeta[*idx_separated_object]->azimuth_fx; // Q22
761 2054 : hIsmMeta[0]->elevation_fx = hIsmMeta[*idx_separated_object]->elevation_fx; // Q22
762 2054 : move32();
763 2054 : move32();
764 : }
765 :
766 : /* Merge transport signals */
767 5858 : ivas_merge_masa_transports_fx( data_out, &( data_in[nchan_ism] ), data_in, input_frame, nchan_transport );
768 :
769 5858 : return;
770 : }
771 :
772 :
773 : /*-------------------------------------------------------------------------*
774 : * ivas_set_ism_importance_interformat()
775 : *
776 : * Set the importance of particular ISM streams in combined-format coding
777 : *-------------------------------------------------------------------------*/
778 :
779 7058 : void ivas_set_ism_importance_interformat_fx(
780 : const Word32 ism_total_brate, /* i/o: ISms total bitrate */
781 : const Word16 nchan_transport, /* i : number of transported channels */
782 : ISM_METADATA_HANDLE hIsmMeta[], /* i/o: ISM metadata handles */
783 : SCE_ENC_HANDLE hSCE[], /* i/o: SCE encoder handles */
784 : const Word16 lp_noise_CPE_fx, /* i : LP filtered total noise estimation Q8 */
785 : Word16 ism_imp[] /* o : ISM importance flags */
786 : )
787 : {
788 : Encoder_State *st;
789 : Word16 ch, ctype, active_flag;
790 :
791 19434 : FOR( ch = 0; ch < nchan_transport; ch++ )
792 : {
793 12376 : st = hSCE[ch]->hCoreCoder[0];
794 :
795 12376 : active_flag = st->vad_flag;
796 12376 : move16();
797 :
798 12376 : IF( active_flag == 0 )
799 : {
800 272 : test();
801 272 : if ( GT_32( st->lp_noise_32fx, 251658240 /* 15 in Q24 */ ) || LT_16( sub( lp_noise_CPE_fx, extract_h( st->lp_noise_32fx ) ), 7680 /* 30 in Q8 */ ) )
802 : {
803 272 : active_flag = 1;
804 272 : move16();
805 : }
806 : }
807 :
808 : Word32 quo, rem;
809 12376 : iDiv_and_mod_32( ism_total_brate, nchan_transport, &quo, &rem, 0 );
810 :
811 : /* do not use the low-rate core-coder mode at highest bit-rates */
812 12376 : if ( GT_32( quo, IVAS_48k ) )
813 : {
814 1428 : active_flag = 1;
815 1428 : move16();
816 : }
817 :
818 12376 : ctype = hSCE[ch]->hCoreCoder[0]->coder_type_raw;
819 12376 : move16();
820 :
821 12376 : st->low_rate_mode = 0;
822 12376 : move16();
823 12376 : test();
824 12376 : IF( active_flag == 0 )
825 : {
826 0 : ism_imp[ch] = ISM_INACTIVE_IMP;
827 0 : move16();
828 0 : st->low_rate_mode = 1;
829 0 : move16();
830 : }
831 12376 : ELSE IF( EQ_16( ctype, INACTIVE ) || EQ_16( ctype, UNVOICED ) )
832 : {
833 449 : ism_imp[ch] = ISM_LOW_IMP;
834 449 : move16();
835 : }
836 11927 : ELSE IF( EQ_16( ctype, VOICED ) )
837 : {
838 3105 : ism_imp[ch] = ISM_MEDIUM_IMP;
839 3105 : move16();
840 : }
841 : ELSE /* GENERIC */
842 : {
843 8822 : ism_imp[ch] = ISM_HIGH_IMP;
844 8822 : move16();
845 : }
846 :
847 12376 : hIsmMeta[ch]->ism_metadata_flag = active_flag; /* flag is needed for the MD coding */
848 12376 : move16();
849 : }
850 :
851 7058 : return;
852 : }
853 :
854 : /*--------------------------------------------------------------------------*
855 : * ivas_set_surplus_brate_enc()
856 : *
857 : * set bit-rate surplus in combined format coding
858 : *--------------------------------------------------------------------------*/
859 :
860 9000 : void ivas_set_surplus_brate_enc(
861 : Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */
862 : #ifdef DEBUG_MODE_INFO
863 : ,
864 : const int16_t *nb_bits_metadata /* i : number of metadata bits */
865 : #endif
866 : )
867 : {
868 9000 : test();
869 9000 : IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) )
870 : {
871 1862 : st_ivas->hCPE[0]->brate_surplus = L_sub( st_ivas->hSCE[0]->element_brate, ivas_interformat_brate_fx( ISM_MASA_MODE_PARAM_ONE_OBJ, 1, st_ivas->hSCE[0]->element_brate, st_ivas->hIsmMetaData[0]->ism_imp, 0 ) );
872 1862 : move32();
873 : /* note: ISM st->total_brate is iset in ivas_sce_enc() */
874 : }
875 7138 : ELSE IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) || EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) )
876 : {
877 : /* it is already set in ivas_ism_enc() */
878 : }
879 : ELSE
880 : {
881 1942 : st_ivas->hCPE[0]->brate_surplus = 0;
882 1942 : move32();
883 : }
884 :
885 : #ifdef DEBUG_MODE_INFO
886 : if ( st_ivas->hSCE[0] != NULL )
887 : {
888 : int16_t input_frame = (int16_t) ( st_ivas->hEncoderConfig->input_Fs / FRAMES_PER_SEC );
889 : float tmpF = 0;
890 :
891 : if ( st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ )
892 : {
893 : tmpF += st_ivas->hSCE[0]->hCoreCoder[0]->total_brate + (float) ( nb_bits_metadata[1] * 50 );
894 : }
895 : else
896 : {
897 : for ( int16_t i = 0; i < st_ivas->hEncoderConfig->nchan_ism; i++ )
898 : {
899 : tmpF += st_ivas->hSCE[i]->hCoreCoder[0]->total_brate + (float) ( nb_bits_metadata[i + 1] * 50 );
900 : }
901 : }
902 : tmpF /= 1000.f;
903 : dbgwrite( &tmpF, 4, 1, input_frame, "res/brate_ISM" ); /* == ism_total_brate incl. ISM MD */
904 : tmpF = st_ivas->hEncoderConfig->ivas_total_brate / 1000.0f - tmpF;
905 : dbgwrite( &tmpF, 4, 1, input_frame, "res/brate_MASA" ); /* == masa_total_brate incl. MASA MD */
906 : tmpF = nb_bits_metadata[0] * FRAMES_PER_SEC / 1000.0f;
907 : dbgwrite( &tmpF, 4, 1, input_frame, "res/brate_MASA_MD" ); /* == MASA MD bitrate */
908 : }
909 : #endif
910 :
911 9000 : return;
912 : }
913 :
914 :
915 : /*--------------------------------------------------------------------------*
916 : * ivas_omasa_ener_brate()
917 : *
918 : *
919 : *--------------------------------------------------------------------------*/
920 :
921 : /*! r: OMASA energy bitrate flag */
922 3142 : Word16 ivas_omasa_ener_brate_fx(
923 : const Word16 nchan_ism, /* i : number of ISMs */
924 : const Word32 ivas_total_brate, /* i : IVAS total bitrate */
925 : Word32 *data_f[], /* i : Input / transport audio signals data_e*/
926 : const Word16 input_frame, /* i : Input frame size */
927 : Word16 data_e /*i:exponent for data_f */
928 : )
929 : {
930 : Word16 i, flag_omasa_ener_brate;
931 : Word32 energy_ism, energy_masa;
932 : Word16 energy_ism_e, energy_masa_e;
933 : Word32 temp_32;
934 : Word16 temp, temp_e;
935 3142 : flag_omasa_ener_brate = 0;
936 3142 : energy_ism_e = 0;
937 3142 : energy_masa_e = 0;
938 3142 : move16();
939 3142 : move16();
940 3142 : move16();
941 :
942 3142 : test();
943 3142 : IF( GE_16( nchan_ism, 3 ) && EQ_32( ivas_total_brate, IVAS_128k ) )
944 : {
945 126 : energy_ism = 0;
946 126 : move32();
947 570 : FOR( i = 0; i < nchan_ism; i++ )
948 : {
949 444 : temp_e = data_e;
950 444 : move16();
951 444 : temp_32 = sum2_32_fx( data_f[i], input_frame, &temp_e );
952 444 : energy_ism = BASOP_Util_Add_Mant32Exp( energy_ism, energy_ism_e, temp_32, temp_e, &energy_ism_e );
953 : }
954 :
955 126 : energy_masa = 0;
956 126 : move32();
957 378 : FOR( i = nchan_ism; i < nchan_ism + MASA_MAXIMUM_DIRECTIONS; i++ )
958 : {
959 252 : temp_e = data_e;
960 252 : move16();
961 252 : temp_32 = sum2_32_fx( data_f[i], input_frame, &temp_e );
962 252 : energy_masa = BASOP_Util_Add_Mant32Exp( energy_masa, energy_masa_e, temp_32, temp_e, &energy_masa_e );
963 : }
964 126 : IF( energy_masa_e < 0 )
965 : {
966 0 : energy_masa = L_shl( energy_masa, energy_masa_e );
967 0 : energy_masa_e = 0;
968 0 : move16();
969 : }
970 126 : energy_masa = L_shr( energy_masa, 1 );
971 126 : energy_masa_e = add( energy_masa_e, 1 );
972 126 : temp = divide1616( 2, nchan_ism ); /*q15*/
973 126 : energy_ism = BASOP_Util_Divide3232_Scale( energy_ism, L_add( energy_masa, L_shr( ONE_IN_Q31, energy_masa_e ) ), &temp_e );
974 126 : energy_ism_e = add( temp_e, sub( energy_ism_e, energy_masa_e ) );
975 126 : energy_ism = Mpy_32_16_1( energy_ism, temp );
976 126 : IF( energy_ism_e < 0 )
977 : {
978 15 : energy_ism = L_shl( energy_ism, energy_ism_e ); // Q31
979 15 : energy_ism_e = 0;
980 15 : move16();
981 : }
982 :
983 126 : IF( LT_32( energy_ism, L_shr( ONE_IN_Q31, energy_ism_e ) ) )
984 : {
985 126 : flag_omasa_ener_brate = 1;
986 126 : move16();
987 : }
988 : }
989 :
990 3142 : return flag_omasa_ener_brate;
991 : }
992 :
993 : /*--------------------------------------------------------------------------*
994 : * Local functions
995 : *--------------------------------------------------------------------------*/
996 :
997 : /* Estimate MASA parameters from the objects */
998 3996 : static void ivas_omasa_param_est_enc_fx(
999 : OMASA_ENC_HANDLE hOMasa,
1000 : OMASA_ENCODER_DATA_HANDLE hOmasaData,
1001 : ISM_METADATA_HANDLE hIsmMeta[],
1002 : Word32 *data[], /*i:q_data*/
1003 : Word32 elevation_m_values_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /*o:q22*/
1004 : Word32 azimuth_m_values_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /*o:q22*/
1005 : Word32 energyRatio_fx[MASA_FREQUENCY_BANDS], /*o:Q30*/
1006 : Word16 spreadCoherence_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /*o:Q15*/
1007 : Word16 surroundingCoherence_fx[MASA_FREQUENCY_BANDS], /*o:Q15*/
1008 : Word32 diffuseness_m_fx[MASA_FREQUENCY_BANDS], /*o:q30*/
1009 : const Word16 input_frame,
1010 : const Word16 nchan_ism,
1011 : Word16 q_data /*i: Qfactor for data*/
1012 : )
1013 : {
1014 : Word32 reference_power_fx[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; // Q(31-ref_exp)
1015 : Word16 ref_exp;
1016 : Word16 ts, i, j, d, k;
1017 : Word16 num_freq_bins, num_freq_bands, index;
1018 : Word32 dir_v_fx[DIRAC_NUM_DIMS];
1019 : Word16 dir_v_e;
1020 : Word16 l_ts;
1021 : Word32 Chnl_RealBuffer_fx[MCMASA_MAX_ANA_CHANS][CLDFB_NO_CHANNELS_MAX];
1022 : Word32 Chnl_ImagBuffer_fx[MCMASA_MAX_ANA_CHANS][CLDFB_NO_CHANNELS_MAX];
1023 : Word16 norm_buff;
1024 : Word32 Foa_RealBuffer_fx[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX];
1025 : Word32 Foa_ImagBuffer_fx[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX];
1026 : Word32 intensity_real_fx[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS];
1027 : Word32 direction_vector_fx[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS];
1028 : Word16 intensity_real_e; /*exponent for intensity_real_fx*/
1029 : Word32 diffuseness_vector_fx[MASA_FREQUENCY_BANDS];
1030 : Word16 q_diffuseness_vector;
1031 : Word32 norm_tmp_fx;
1032 : Word32 renormalization_factor_diff_fx[MASA_FREQUENCY_BANDS];
1033 : Word16 renormalization_factor_diff_e[MASA_FREQUENCY_BANDS];
1034 : Word16 band_m_idx, block_m_idx;
1035 : Word16 mrange[2], brange[2];
1036 : Word16 diffuseness_e[MASA_FREQUENCY_BANDS];
1037 : Word16 azimuth_16, elevation_16;
1038 : Word16 band_grouping_diff[MASA_FREQUENCY_BANDS], guard_bits, max_band_grouping_diff;
1039 : Word16 q; /*stores q for cldfb buffers*/
1040 : Word32 temp;
1041 : Word16 temp_e;
1042 : Word16 q_intensity_real_fx[MASA_FREQUENCY_BANDS], q_reference_power_fx[CLDFB_NO_CHANNELS_MAX];
1043 :
1044 3996 : ref_exp = 0;
1045 3996 : norm_buff = MAX16B;
1046 3996 : dir_v_e = MIN_16;
1047 3996 : num_freq_bins = hOMasa->cldfbAnaEnc[0]->no_channels;
1048 3996 : num_freq_bands = hOMasa->nbands;
1049 3996 : l_ts = idiv1616( input_frame, CLDFB_NO_COL_MAX );
1050 3996 : move16();
1051 3996 : move16();
1052 3996 : move16();
1053 3996 : move16();
1054 3996 : move16();
1055 :
1056 : /* Need to initialize renormalization_factors, and variables to be normalized */
1057 3996 : set_zero_fx( &Foa_RealBuffer_fx[0][0], FOA_CHANNELS * CLDFB_NO_CHANNELS_MAX );
1058 3996 : set_zero_fx( &Foa_ImagBuffer_fx[0][0], FOA_CHANNELS * CLDFB_NO_CHANNELS_MAX );
1059 :
1060 3996 : set_zero_fx( renormalization_factor_diff_fx, hOMasa->nbands );
1061 3996 : set_zero_fx( diffuseness_m_fx, hOMasa->nbands );
1062 3996 : set16_fx( renormalization_factor_diff_e, 0, hOMasa->nbands );
1063 3996 : set16_fx( diffuseness_e, 0, hOMasa->nbands );
1064 17156 : FOR( i = 0; i < nchan_ism; i++ )
1065 : {
1066 13160 : set_zero_fx( Chnl_RealBuffer_fx[i], 60 );
1067 13160 : set_zero_fx( Chnl_ImagBuffer_fx[i], 60 );
1068 : }
1069 : /* Compute ISM to FOA matrices */
1070 17156 : FOR( i = 0; i < nchan_ism; i++ )
1071 : {
1072 13160 : azimuth_16 = extract_l( Mpy_32_32( hIsmMeta[i]->azimuth_fx, 46603 /*1<<24/360*/ ) ); /*q15*/
1073 13160 : elevation_16 = extract_l( Mpy_32_32( hIsmMeta[i]->elevation_fx, 46603 /*1<<24/360*/ ) ); /*q15*/
1074 13160 : hOMasa->chnlToFoaMtx_fx[0][i] = ONE_IN_Q31; /*q31*/
1075 13160 : hOMasa->chnlToFoaMtx_fx[1][i] = L_mult( getSineWord16R2( azimuth_16 ), getCosWord16R2( elevation_16 ) ); /*q31*/
1076 13160 : hOMasa->chnlToFoaMtx_fx[2][i] = L_deposit_h( getSineWord16R2( elevation_16 ) ); /*q31*/
1077 13160 : hOMasa->chnlToFoaMtx_fx[3][i] = L_mult( getCosWord16R2( azimuth_16 ), getCosWord16R2( elevation_16 ) ); /*q31*/
1078 13160 : move32();
1079 13160 : move32();
1080 13160 : move32();
1081 13160 : move32();
1082 : }
1083 :
1084 3996 : q = q_data;
1085 3996 : move16();
1086 : /* do processing over all CLDFB time slots */
1087 19980 : FOR( block_m_idx = 0; block_m_idx < hOMasa->nSubframes; block_m_idx++ )
1088 : {
1089 15984 : mrange[0] = hOMasa->block_grouping[block_m_idx];
1090 15984 : mrange[1] = hOMasa->block_grouping[block_m_idx + 1];
1091 15984 : move16();
1092 15984 : move16();
1093 :
1094 396000 : FOR( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ )
1095 : {
1096 380016 : hOMasa->direction_vector_m_fx[0][block_m_idx][band_m_idx] = 0;
1097 380016 : hOMasa->direction_vector_m_fx[1][block_m_idx][band_m_idx] = 0;
1098 380016 : hOMasa->direction_vector_m_fx[2][block_m_idx][band_m_idx] = 0;
1099 380016 : hOMasa->direction_vector_e[0][block_m_idx][band_m_idx] = 0;
1100 380016 : hOMasa->direction_vector_e[1][block_m_idx][band_m_idx] = 0;
1101 380016 : hOMasa->direction_vector_e[2][block_m_idx][band_m_idx] = 0;
1102 380016 : move32();
1103 380016 : move32();
1104 380016 : move32();
1105 380016 : move16();
1106 380016 : move16();
1107 380016 : move16();
1108 : }
1109 15984 : set_zero_fx( hOmasaData->energy_ism_fx[block_m_idx], num_freq_bands );
1110 15984 : set16_fx( hOmasaData->energy_ism_fx_e[block_m_idx], 0, num_freq_bands );
1111 88304 : FOR( ts = mrange[0]; ts < mrange[1]; ts++ )
1112 : {
1113 72320 : norm_buff = MAX16B;
1114 72320 : move16();
1115 311616 : FOR( i = 0; i < nchan_ism; i++ )
1116 : {
1117 239296 : q = q_data;
1118 239296 : move16();
1119 239296 : cldfbAnalysis_ts_fx_var_q( &( data[i][l_ts * ts] ), Chnl_RealBuffer_fx[i], Chnl_ImagBuffer_fx[i], l_ts, hOMasa->cldfbAnaEnc[i], &q ); /*q_data-5*/
1120 239296 : norm_buff = s_min( norm_buff, L_norm_arr( Chnl_RealBuffer_fx[i], 60 ) );
1121 239296 : norm_buff = s_min( norm_buff, L_norm_arr( Chnl_ImagBuffer_fx[i], 60 ) );
1122 : }
1123 : /* Compute energy */
1124 1792416 : FOR( i = 0; i < num_freq_bands; i++ )
1125 : {
1126 1720096 : band_grouping_diff[i] = sub( hOMasa->band_grouping[i + 1], hOMasa->band_grouping[i] );
1127 1720096 : move16();
1128 : }
1129 72320 : maximum_abs_16_fx( band_grouping_diff, num_freq_bands, &max_band_grouping_diff );
1130 72320 : guard_bits = find_guarded_bits_fx( num_freq_bins );
1131 72320 : norm_buff = sub( norm_buff, guard_bits );
1132 311616 : FOR( i = 0; i < nchan_ism; i++ )
1133 : {
1134 239296 : scale_sig32( Chnl_RealBuffer_fx[i], 60, norm_buff );
1135 239296 : scale_sig32( Chnl_ImagBuffer_fx[i], 60, norm_buff );
1136 : }
1137 72320 : q = add( q, norm_buff );
1138 1792416 : FOR( i = 0; i < num_freq_bands; i++ )
1139 : {
1140 1720096 : brange[0] = hOMasa->band_grouping[i];
1141 1720096 : brange[1] = hOMasa->band_grouping[i + 1];
1142 1720096 : move16();
1143 1720096 : move16();
1144 7426048 : FOR( k = 0; k < nchan_ism; k++ )
1145 : {
1146 19512672 : FOR( j = brange[0]; j < brange[1]; j++ )
1147 : {
1148 13806720 : temp = L_add( Mpy_32_32( Chnl_RealBuffer_fx[k][j], Chnl_RealBuffer_fx[k][j] ), Mpy_32_32( Chnl_ImagBuffer_fx[k][j], Chnl_ImagBuffer_fx[k][j] ) );
1149 13806720 : temp_e = sub( 62, shl( q, 1 ) );
1150 13806720 : hOmasaData->energy_ism_fx[block_m_idx][i] = BASOP_Util_Add_Mant32Exp( hOmasaData->energy_ism_fx[block_m_idx][i], hOmasaData->energy_ism_fx_e[block_m_idx][i], temp, temp_e, &hOmasaData->energy_ism_fx_e[block_m_idx][i] ); /*2q-31*/
1151 13806720 : move32();
1152 : }
1153 : }
1154 : }
1155 :
1156 : /* Compute FOA */
1157 : /* W */
1158 72320 : Copy32( Chnl_RealBuffer_fx[0], Foa_RealBuffer_fx[0], num_freq_bins ); /*q*/
1159 72320 : Copy32( Chnl_ImagBuffer_fx[0], Foa_ImagBuffer_fx[0], num_freq_bins ); /*q*/
1160 239296 : FOR( i = 1; i < nchan_ism; i++ )
1161 : {
1162 166976 : v_add_32( Chnl_RealBuffer_fx[i], Foa_RealBuffer_fx[0], Foa_RealBuffer_fx[0], num_freq_bins );
1163 166976 : v_add_32( Chnl_ImagBuffer_fx[i], Foa_ImagBuffer_fx[0], Foa_ImagBuffer_fx[0], num_freq_bins );
1164 : }
1165 :
1166 : /* Y */
1167 72320 : v_multc_fixed( Chnl_RealBuffer_fx[0], hOMasa->chnlToFoaMtx_fx[1][0], Foa_RealBuffer_fx[1], num_freq_bins ); /*q*/
1168 72320 : v_multc_fixed( Chnl_ImagBuffer_fx[0], hOMasa->chnlToFoaMtx_fx[1][0], Foa_ImagBuffer_fx[1], num_freq_bins ); /*q*/
1169 239296 : FOR( i = 1; i < nchan_ism; i++ )
1170 : {
1171 166976 : v_multc_acc_32_32( Chnl_RealBuffer_fx[i], hOMasa->chnlToFoaMtx_fx[1][i], Foa_RealBuffer_fx[1], num_freq_bins ); /*q*/
1172 166976 : v_multc_acc_32_32( Chnl_ImagBuffer_fx[i], hOMasa->chnlToFoaMtx_fx[1][i], Foa_ImagBuffer_fx[1], num_freq_bins ); /*q*/
1173 : }
1174 :
1175 : /* Z */
1176 72320 : v_multc_fixed( Chnl_RealBuffer_fx[0], hOMasa->chnlToFoaMtx_fx[2][0], Foa_RealBuffer_fx[2], num_freq_bins ); /*q*/
1177 72320 : v_multc_fixed( Chnl_ImagBuffer_fx[0], hOMasa->chnlToFoaMtx_fx[2][0], Foa_ImagBuffer_fx[2], num_freq_bins ); /*q*/
1178 239296 : FOR( i = 1; i < nchan_ism; i++ )
1179 : {
1180 166976 : v_multc_acc_32_32( Chnl_RealBuffer_fx[i], hOMasa->chnlToFoaMtx_fx[2][i], Foa_RealBuffer_fx[2], num_freq_bins ); /*q*/
1181 166976 : v_multc_acc_32_32( Chnl_ImagBuffer_fx[i], hOMasa->chnlToFoaMtx_fx[2][i], Foa_ImagBuffer_fx[2], num_freq_bins ); /*q*/
1182 : }
1183 :
1184 :
1185 : /* X */
1186 72320 : v_multc_fixed( Chnl_RealBuffer_fx[0], hOMasa->chnlToFoaMtx_fx[3][0], Foa_RealBuffer_fx[3], num_freq_bins ); /*q*/
1187 72320 : v_multc_fixed( Chnl_ImagBuffer_fx[0], hOMasa->chnlToFoaMtx_fx[3][0], Foa_ImagBuffer_fx[3], num_freq_bins ); /*q*/
1188 239296 : FOR( i = 1; i < nchan_ism; i++ )
1189 : {
1190 166976 : v_multc_acc_32_32( Chnl_RealBuffer_fx[i], hOMasa->chnlToFoaMtx_fx[3][i], Foa_RealBuffer_fx[3], num_freq_bins ); /*q*/
1191 166976 : v_multc_acc_32_32( Chnl_ImagBuffer_fx[i], hOMasa->chnlToFoaMtx_fx[3][i], Foa_ImagBuffer_fx[3], num_freq_bins ); /*q*/
1192 : }
1193 : /* Direction estimation */
1194 72320 : computeIntensityVector_enc_fx( hOMasa->band_grouping, Foa_RealBuffer_fx, Foa_ImagBuffer_fx, num_freq_bands, intensity_real_fx, q_intensity_real_fx, q );
1195 :
1196 72320 : computeDirectionVectors_fixed( intensity_real_fx[0], intensity_real_fx[1], intensity_real_fx[2], 0, num_freq_bands, direction_vector_fx[0], direction_vector_fx[1], direction_vector_fx[2], 0, q_intensity_real_fx );
1197 :
1198 : /* Power estimation for diffuseness */
1199 :
1200 72320 : computeReferencePower_omasa_ivas_fx( hOMasa->band_grouping, Foa_RealBuffer_fx, Foa_ImagBuffer_fx, reference_power_fx[ts], 0, num_freq_bands, q, q_reference_power_fx );
1201 :
1202 72320 : minimum_fx( q_intensity_real_fx, num_freq_bands, &intensity_real_e );
1203 72320 : minimum_fx( q_reference_power_fx, num_freq_bands, &ref_exp );
1204 :
1205 : Word16 tmp;
1206 1792416 : FOR( i = 0; i < num_freq_bands; i++ )
1207 : {
1208 1720096 : tmp = sub( intensity_real_e, q_intensity_real_fx[i] );
1209 1720096 : intensity_real_fx[0][i] = L_shl( intensity_real_fx[0][i], tmp ); // intensity_real_e
1210 1720096 : move32();
1211 1720096 : intensity_real_fx[1][i] = L_shl( intensity_real_fx[1][i], tmp ); // intensity_real_e
1212 1720096 : move32();
1213 1720096 : intensity_real_fx[2][i] = L_shl( intensity_real_fx[2][i], tmp ); // intensity_real_e
1214 1720096 : move32();
1215 :
1216 1720096 : tmp = sub( ref_exp, q_reference_power_fx[i] );
1217 1720096 : reference_power_fx[ts][i] = L_shl( reference_power_fx[ts][i], tmp ); // ref_exp
1218 : }
1219 :
1220 72320 : intensity_real_e = sub( Q31, intensity_real_e );
1221 72320 : ref_exp = sub( Q31, ref_exp );
1222 :
1223 : /* Fill buffers of length "averaging_length" time slots for intensity and energy */
1224 72320 : hOMasa->index_buffer_intensity = add( ( hOMasa->index_buffer_intensity % DIRAC_NO_COL_AVG_DIFF ), 1 ); /* averaging_length = 32 */
1225 72320 : index = hOMasa->index_buffer_intensity;
1226 72320 : move16();
1227 72320 : move16();
1228 289280 : FOR( i = 0; i < DIRAC_NUM_DIMS; i++ )
1229 : {
1230 : /* only real part needed */
1231 216960 : Copy32( intensity_real_fx[i], &( hOMasa->buffer_intensity_real_fx[i][index - 1][0] ), num_freq_bands );
1232 : }
1233 72320 : hOMasa->buffer_intensity_real_q[index - 1] = sub( 31, intensity_real_e );
1234 72320 : move16();
1235 72320 : Copy32( reference_power_fx[ts], &( hOMasa->buffer_energy_fx[( index - 1 ) * num_freq_bands] ), num_freq_bands );
1236 72320 : hOMasa->buffer_energy_q[( index - 1 )] = sub( 31, ref_exp );
1237 72320 : move16();
1238 72320 : computeDiffuseness_fixed( hOMasa->buffer_intensity_real_fx, hOMasa->buffer_energy_fx, num_freq_bands, diffuseness_vector_fx, hOMasa->buffer_intensity_real_q, hOMasa->buffer_energy_q, &q_diffuseness_vector );
1239 :
1240 1792416 : FOR( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ )
1241 : {
1242 1720096 : temp_e = norm_l( reference_power_fx[ts][band_m_idx] );
1243 1720096 : reference_power_fx[ts][band_m_idx] = L_shl( reference_power_fx[ts][band_m_idx], temp_e );
1244 1720096 : move32();
1245 1720096 : norm_tmp_fx = Mpy_32_32( reference_power_fx[ts][band_m_idx], L_sub( L_shl( 1, q_diffuseness_vector ), diffuseness_vector_fx[band_m_idx] ) ); /*30+(31-(ref_exp-temp_e))-31*/
1246 :
1247 1720096 : hOMasa->direction_vector_m_fx[0][block_m_idx][band_m_idx] = BASOP_Util_Add_Mant32Exp( hOMasa->direction_vector_m_fx[0][block_m_idx][band_m_idx], hOMasa->direction_vector_e[0][block_m_idx][band_m_idx], Mpy_32_32( norm_tmp_fx, direction_vector_fx[0][band_m_idx] ), sub( add( ref_exp, 2 ), temp_e ), &hOMasa->direction_vector_e[0][block_m_idx][band_m_idx] ); /*hOMasa->direction_vector_e[0][block_m_idx][band_m_idx]*/
1248 1720096 : hOMasa->direction_vector_m_fx[1][block_m_idx][band_m_idx] = BASOP_Util_Add_Mant32Exp( hOMasa->direction_vector_m_fx[1][block_m_idx][band_m_idx], hOMasa->direction_vector_e[1][block_m_idx][band_m_idx], Mpy_32_32( norm_tmp_fx, direction_vector_fx[1][band_m_idx] ), sub( add( ref_exp, 2 ), temp_e ), &hOMasa->direction_vector_e[1][block_m_idx][band_m_idx] ); /*hOMasa->direction_vector_e[1][block_m_idx][band_m_idx]*/
1249 1720096 : hOMasa->direction_vector_m_fx[2][block_m_idx][band_m_idx] = BASOP_Util_Add_Mant32Exp( hOMasa->direction_vector_m_fx[2][block_m_idx][band_m_idx], hOMasa->direction_vector_e[2][block_m_idx][band_m_idx], Mpy_32_32( norm_tmp_fx, direction_vector_fx[2][band_m_idx] ), sub( add( ref_exp, 2 ), temp_e ), &hOMasa->direction_vector_e[2][block_m_idx][band_m_idx] ); /*hOMasa->direction_vector_e[2][block_m_idx][band_m_idx]*/
1250 1720096 : move32();
1251 1720096 : move32();
1252 1720096 : move32();
1253 :
1254 1720096 : diffuseness_m_fx[band_m_idx] = BASOP_Util_Add_Mant32Exp( diffuseness_m_fx[band_m_idx], diffuseness_e[band_m_idx], W_extract_l( W_shr( W_mult0_32_32( reference_power_fx[ts][band_m_idx], diffuseness_vector_fx[band_m_idx] ), 30 ) ), sub( ref_exp, temp_e ), &diffuseness_e[band_m_idx] ); /*diffuseness_e[band_m_idx]*/
1255 1720096 : renormalization_factor_diff_fx[band_m_idx] = BASOP_Util_Add_Mant32Exp( renormalization_factor_diff_fx[band_m_idx], renormalization_factor_diff_e[band_m_idx], reference_power_fx[ts][band_m_idx], sub( ref_exp, temp_e ), &renormalization_factor_diff_e[band_m_idx] ); /*renormalization_factor_diff_e[band_m_idx]*/
1256 1720096 : move32();
1257 1720096 : move32();
1258 : }
1259 : }
1260 :
1261 396000 : FOR( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ )
1262 : {
1263 380016 : dir_v_e = MIN_16;
1264 380016 : move16();
1265 1520064 : FOR( d = 0; d < DIRAC_NUM_DIMS; d++ )
1266 : {
1267 1140048 : dir_v_fx[d] = hOMasa->direction_vector_m_fx[d][block_m_idx][band_m_idx];
1268 1140048 : move32();
1269 1140048 : dir_v_e = s_max( dir_v_e, hOMasa->direction_vector_e[d][block_m_idx][band_m_idx] ) + 1;
1270 : }
1271 1520064 : FOR( d = 0; d < DIRAC_NUM_DIMS; d++ )
1272 : {
1273 1140048 : dir_v_fx[d] = L_shr( hOMasa->direction_vector_m_fx[d][block_m_idx][band_m_idx], sub( dir_v_e, hOMasa->direction_vector_e[d][block_m_idx][band_m_idx] ) );
1274 1140048 : move32();
1275 : }
1276 :
1277 380016 : ivas_qmetadata_direction_vector_to_azimuth_elevation_fx( dir_v_fx, sub( 31, dir_v_e ), &azimuth_m_values_fx[block_m_idx][band_m_idx], &elevation_m_values_fx[block_m_idx][band_m_idx] );
1278 : }
1279 :
1280 : /* Set coherences to zero, as this mode is used at lowest bit rates where the coherences are not transmitted */
1281 396000 : FOR( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ )
1282 : {
1283 380016 : spreadCoherence_fx[block_m_idx][band_m_idx] = 0;
1284 380016 : surroundingCoherence_fx[band_m_idx] = 0;
1285 380016 : move16();
1286 380016 : move16();
1287 : }
1288 : }
1289 :
1290 : /* Determine energy ratios */
1291 99000 : FOR( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ )
1292 : {
1293 95004 : IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( renormalization_factor_diff_fx[band_m_idx], renormalization_factor_diff_e[band_m_idx], 1 /*EPSILON Q50*/, -19 ), 1 ) )
1294 : {
1295 95004 : diffuseness_m_fx[band_m_idx] = BASOP_Util_Divide3232_Scale( diffuseness_m_fx[band_m_idx], L_add( renormalization_factor_diff_fx[band_m_idx], EPSILON_FX ), &temp_e ); // Q=15-temp_e
1296 95004 : temp_e = add( temp_e, sub( diffuseness_e[band_m_idx], renormalization_factor_diff_e[band_m_idx] ) );
1297 : }
1298 : ELSE
1299 : {
1300 0 : diffuseness_m_fx[band_m_idx] = 0;
1301 0 : temp_e = 0;
1302 0 : move16();
1303 : }
1304 95004 : move32();
1305 95004 : diffuseness_m_fx[band_m_idx] = L_shl( diffuseness_m_fx[band_m_idx], add( 15, temp_e ) ); // Scaling to Q30
1306 95004 : energyRatio_fx[band_m_idx] = L_sub( ONE_IN_Q30, diffuseness_m_fx[band_m_idx] ); // Q30
1307 95004 : move32();
1308 95004 : move32();
1309 : }
1310 3996 : return;
1311 : }
1312 :
1313 :
1314 : /* Estimate energies and ratios */
1315 1862 : static void ivas_omasa_energy_and_ratio_est_fx(
1316 : OMASA_ENC_HANDLE hOMasa,
1317 : OMASA_ENCODER_DATA_HANDLE hOmasaData,
1318 : Word32 *data_fx[], /*i: q_data*/
1319 : const Word16 input_frame,
1320 : const Word16 nchan_ism,
1321 : const Word16 q_data /*i: stoes the q for data_fx*/
1322 : )
1323 : {
1324 : Word16 ts, i, j, k;
1325 : Word16 num_freq_bands;
1326 : Word16 l_ts;
1327 : Word32 Chnl_RealBuffer_fx[MAX_NUM_OBJECTS][CLDFB_NO_CHANNELS_MAX];
1328 : Word32 Chnl_ImagBuffer_fx[MAX_NUM_OBJECTS][CLDFB_NO_CHANNELS_MAX];
1329 : Word16 block_m_idx;
1330 : Word16 mrange[2], brange[2];
1331 : Word32 tftile_energy_fx;
1332 : Word16 tftile_energy_e;
1333 : Word64 ism_ratio_sum_fx;
1334 : Word16 q_cldfb;
1335 : Word16 norm_Chnl;
1336 : Word16 temp_e; /* to store temporary exp*/
1337 : Word16 energy_ratio_ism_e[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS][MAX_NUM_OBJECTS]; /*q30*/
1338 1862 : num_freq_bands = hOMasa->nbands;
1339 1862 : l_ts = shr( input_frame, 4 ); /*input_frame / CLDFB_NO_COL_MAX*/
1340 1862 : q_cldfb = q_data;
1341 1862 : move16(); /*num_freq_bands*/
1342 1862 : move16(); /*q_cldfb*/
1343 1862 : set_zero_fx( &Chnl_RealBuffer_fx[0][0], MAX_NUM_OBJECTS * CLDFB_NO_CHANNELS_MAX );
1344 1862 : set_zero_fx( &Chnl_ImagBuffer_fx[0][0], MAX_NUM_OBJECTS * CLDFB_NO_CHANNELS_MAX );
1345 : /* do processing over all CLDFB time slots */
1346 8176 : FOR( block_m_idx = 0; block_m_idx < hOMasa->nSubframes; block_m_idx++ )
1347 : {
1348 6314 : mrange[0] = hOMasa->block_grouping[block_m_idx];
1349 6314 : mrange[1] = hOMasa->block_grouping[block_m_idx + 1];
1350 6314 : move16();
1351 6314 : move16();
1352 :
1353 : /* Reset variable */
1354 40530 : FOR( i = 0; i < hOMasa->nbands; i++ )
1355 : {
1356 34216 : set_zero_fx( hOmasaData->energy_ratio_ism_fx[block_m_idx][i], nchan_ism );
1357 34216 : set16_fx( energy_ratio_ism_e[block_m_idx][i], 0, nchan_ism );
1358 : }
1359 6314 : set_zero_fx( hOmasaData->energy_ism_fx[block_m_idx], num_freq_bands );
1360 6314 : set16_fx( hOmasaData->energy_ism_fx_e[block_m_idx], 0, num_freq_bands );
1361 : /* Compute CLDFB */
1362 36106 : FOR( ts = mrange[0]; ts < mrange[1]; ts++ )
1363 : {
1364 29792 : norm_Chnl = MAX_16;
1365 29792 : move16();
1366 130272 : FOR( i = 0; i < nchan_ism; i++ )
1367 : {
1368 100480 : q_cldfb = q_data;
1369 100480 : move16();
1370 100480 : scale_sig32( hOMasa->cldfbAnaEnc[i]->cldfb_state_fx, hOMasa->cldfbAnaEnc[i]->cldfb_state_length, sub( q_cldfb, hOMasa->cldfbAnaEnc[i]->Q_cldfb_state ) );
1371 100480 : hOMasa->cldfbAnaEnc[i]->Q_cldfb_state = q_cldfb;
1372 100480 : move16();
1373 100480 : cldfbAnalysis_ts_fx_fixed_q( &( data_fx[i][l_ts * ts] ), Chnl_RealBuffer_fx[i], Chnl_ImagBuffer_fx[i], l_ts, hOMasa->cldfbAnaEnc[i], &q_cldfb );
1374 100480 : norm_Chnl = s_min( norm_Chnl, L_norm_arr( Chnl_ImagBuffer_fx[i], 60 ) );
1375 100480 : norm_Chnl = s_min( norm_Chnl, L_norm_arr( Chnl_RealBuffer_fx[i], 60 ) );
1376 : }
1377 29792 : norm_Chnl = sub( norm_Chnl, 1 );
1378 : /*scaling cldfb buffers to avoid loss of values in Mpy_32_32*/
1379 130272 : FOR( i = 0; i < nchan_ism; i++ )
1380 : {
1381 100480 : scale_sig32( Chnl_RealBuffer_fx[i], CLDFB_NO_CHANNELS_MAX, norm_Chnl );
1382 100480 : scale_sig32( Chnl_ImagBuffer_fx[i], CLDFB_NO_CHANNELS_MAX, norm_Chnl );
1383 : }
1384 29792 : q_cldfb = add( q_cldfb, norm_Chnl );
1385 : /* Compute energy */
1386 221088 : FOR( i = 0; i < num_freq_bands; i++ )
1387 : {
1388 191296 : brange[0] = hOMasa->band_grouping[i];
1389 191296 : brange[1] = hOMasa->band_grouping[i + 1];
1390 191296 : move16();
1391 191296 : move16();
1392 1835456 : FOR( j = brange[0]; j < brange[1]; j++ )
1393 : {
1394 7242880 : FOR( k = 0; k < nchan_ism; k++ )
1395 : {
1396 : Word64 tmp64;
1397 : Word16 tmpNorm;
1398 5598720 : tmp64 = W_add( W_mult0_32_32( Chnl_RealBuffer_fx[k][j], Chnl_RealBuffer_fx[k][j] ), W_mult0_32_32( Chnl_ImagBuffer_fx[k][j], Chnl_ImagBuffer_fx[k][j] ) ); // exp: 2 * (31 - q_cldfb) + 1
1399 5598720 : tftile_energy_e = sub( 63, shl( q_cldfb, 1 ) );
1400 5598720 : tmpNorm = W_norm( tmp64 );
1401 5598720 : tmp64 = W_shl( tmp64, tmpNorm );
1402 5598720 : tftile_energy_fx = W_extract_h( tmp64 );
1403 5598720 : tftile_energy_e = sub( tftile_energy_e, tmpNorm );
1404 5598720 : hOmasaData->energy_ism_fx[block_m_idx][i] = BASOP_Util_Add_Mant32Exp( hOmasaData->energy_ism_fx[block_m_idx][i], hOmasaData->energy_ism_fx_e[block_m_idx][i], tftile_energy_fx, tftile_energy_e, &hOmasaData->energy_ism_fx_e[block_m_idx][i] );
1405 5598720 : hOmasaData->energy_ratio_ism_fx[block_m_idx][i][k] = BASOP_Util_Add_Mant32Exp( hOmasaData->energy_ratio_ism_fx[block_m_idx][i][k], energy_ratio_ism_e[block_m_idx][i][k], tftile_energy_fx, tftile_energy_e, &energy_ratio_ism_e[block_m_idx][i][k] );
1406 5598720 : move32();
1407 5598720 : move32();
1408 : }
1409 : }
1410 : }
1411 : }
1412 :
1413 : /* Compute ISM energy ratios */
1414 40530 : FOR( i = 0; i < num_freq_bands; i++ )
1415 : {
1416 34216 : ism_ratio_sum_fx = 0;
1417 34216 : move64();
1418 148936 : FOR( j = 0; j < nchan_ism; j++ )
1419 : {
1420 114720 : hOmasaData->energy_ratio_ism_fx[block_m_idx][i][j] = L_deposit_h( BASOP_Util_Divide3232_Scale( hOmasaData->energy_ratio_ism_fx[block_m_idx][i][j], L_add( hOmasaData->energy_ism_fx[block_m_idx][i], EPSILON_FX ), &temp_e ) );
1421 114720 : move32();
1422 114720 : temp_e = add( temp_e, sub( energy_ratio_ism_e[block_m_idx][i][j], hOmasaData->energy_ism_fx_e[block_m_idx][i] ) );
1423 :
1424 114720 : hOmasaData->energy_ratio_ism_fx[block_m_idx][i][j] = L_shl( hOmasaData->energy_ratio_ism_fx[block_m_idx][i][j], sub( temp_e, 1 ) ); /* scaling to q30 */
1425 114720 : move32();
1426 114720 : ism_ratio_sum_fx = W_add( ism_ratio_sum_fx, hOmasaData->energy_ratio_ism_fx[block_m_idx][i][j] );
1427 : }
1428 34216 : IF( ism_ratio_sum_fx == 0 )
1429 : {
1430 0 : Word16 temp_ism_ratio = BASOP_Util_Divide1616_Scale( 1, nchan_ism, &temp_e );
1431 0 : FOR( j = 0; j < nchan_ism; j++ )
1432 : {
1433 0 : hOmasaData->energy_ratio_ism_fx[block_m_idx][i][j] = L_shl( temp_ism_ratio, add( temp_e, 15 ) ); /*scaling to q30*/
1434 0 : move32();
1435 : }
1436 : }
1437 : }
1438 : }
1439 :
1440 1862 : return;
1441 : }
1442 :
1443 :
1444 : /* Compute downmix */
1445 5858 : static void ivas_omasa_dmx_fx(
1446 : Word32 *data_in[], /*i:Qx*/
1447 : Word32 data_out[][L_FRAME48k], /*i:Qx*/
1448 : const Word16 input_frame, /*i:q0*/
1449 : const Word16 nchan_transport, /*i:q0*/
1450 : const Word16 nchan_ism, /*i:q0*/
1451 : ISM_METADATA_HANDLE hIsmMeta[], /*i*/
1452 : Word16 prev_gains[][MASA_MAX_TRANSPORT_CHANNELS], /*o:q15*/
1453 : const Word16 interpolator[L_FRAME48k] /*i:q15*/
1454 : )
1455 : {
1456 : Word16 i, j, k;
1457 : Word16 azimuth, elevation;
1458 : Word16 gains[MASA_MAX_TRANSPORT_CHANNELS];
1459 : Word16 g1, g2;
1460 :
1461 17574 : FOR( i = 0; i < nchan_transport; i++ )
1462 : {
1463 11716 : set_zero_fx( data_out[i], input_frame );
1464 : }
1465 :
1466 25298 : FOR( i = 0; i < nchan_ism; i++ )
1467 : {
1468 19440 : azimuth = extract_l( L_shr( L_add( hIsmMeta[i]->azimuth_fx, ONE_IN_Q21 ), 22 ) ); /* scaling from q22 to q0 for ivas_get_stereo_panning_gains_fx*/
1469 19440 : elevation = extract_l( L_shr( L_add( hIsmMeta[i]->elevation_fx, ONE_IN_Q21 ), 22 ) ); /* scaling from q22 to q0 for ivas_get_stereo_panning_gains_fx*/
1470 :
1471 : /*gains is q15*/
1472 : /*azimuth is q0*/
1473 : /*elevation is q0*/
1474 19440 : ivas_get_stereo_panning_gains_fx( azimuth, elevation, gains );
1475 :
1476 : /* Downmix using the panning gains */
1477 58320 : FOR( j = 0; j < nchan_transport; j++ )
1478 : {
1479 38880 : test();
1480 38880 : IF( abs_s( gains[j] ) > 0 || abs_s( prev_gains[i][j] ) > 0 )
1481 : {
1482 32614184 : FOR( k = 0; k < input_frame; k++ )
1483 : {
1484 32578560 : g1 = interpolator[k];
1485 32578560 : move16();
1486 32578560 : g2 = sub( MAX_WORD16, g1 ); /*q15*/
1487 32578560 : data_out[j][k] = L_add( data_out[j][k], Mpy_32_32( L_add( L_mult( g1, gains[j] ), L_mult( g2, prev_gains[i][j] ) ) /*q31*/, data_in[i][k] ) ); /*Qx*/
1488 32578560 : move32();
1489 : }
1490 : }
1491 38880 : prev_gains[i][j] = gains[j]; /*q15*/
1492 38880 : move16();
1493 : }
1494 : }
1495 :
1496 5858 : return;
1497 : }
1498 :
1499 72320 : void computeIntensityVector_enc_fx(
1500 : const Word16 *band_grouping,
1501 : Word32 Cldfb_RealBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /*inp_q*/
1502 : Word32 Cldfb_ImagBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /*inp_q*/
1503 : const Word16 num_frequency_bands,
1504 : Word32 intensity_real[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS], /*exp: exp_intensity_real*/
1505 : Word16 q_intensity_real[MASA_FREQUENCY_BANDS],
1506 : Word16 inp_q )
1507 : {
1508 : Word16 i, j;
1509 : Word32 real, img;
1510 : Word16 brange[2];
1511 : Word16 shift_intensity_real, num_bins, guard_bits, norm;
1512 :
1513 : Word64 intensity_real64[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS];
1514 :
1515 289280 : FOR( i = 0; i < DIRAC_NUM_DIMS; i++ )
1516 : {
1517 216960 : set64_fx( intensity_real64[i], 0, MASA_FREQUENCY_BANDS );
1518 : }
1519 :
1520 72320 : shift_intensity_real = sub( shl( inp_q, 1 ), 32 );
1521 :
1522 1792416 : FOR( i = 0; i < num_frequency_bands; i++ )
1523 : {
1524 1720096 : brange[0] = band_grouping[i];
1525 1720096 : move16();
1526 1720096 : brange[1] = band_grouping[i + 1];
1527 1720096 : move16();
1528 :
1529 1720096 : num_bins = sub( brange[1], brange[0] );
1530 1720096 : guard_bits = find_guarded_bits_fx( num_bins );
1531 :
1532 5843616 : FOR( j = brange[0]; j < brange[1]; j++ )
1533 : {
1534 4123520 : real = Cldfb_RealBuffer[0][j];
1535 4123520 : move32();
1536 4123520 : img = Cldfb_ImagBuffer[0][j];
1537 4123520 : move32();
1538 : /* Intensity is XYZ order, audio is WYZX order. */
1539 4123520 : intensity_real64[0][i] = W_add( intensity_real64[0][i], W_shr( W_add( W_mult0_32_32( Cldfb_RealBuffer[3][j], real ), W_mult0_32_32( Cldfb_ImagBuffer[3][j], img ) ), guard_bits ) ); // output Q= 2* input_q -guard_bits
1540 4123520 : move64();
1541 4123520 : intensity_real64[1][i] = W_add( intensity_real64[1][i], W_shr( W_add( W_mult0_32_32( Cldfb_RealBuffer[1][j], real ), W_mult0_32_32( Cldfb_ImagBuffer[1][j], img ) ), guard_bits ) ); // output Q= 2* input_q - guard_bits
1542 4123520 : move64();
1543 4123520 : intensity_real64[2][i] = W_add( intensity_real64[2][i], W_shr( W_add( W_mult0_32_32( Cldfb_RealBuffer[2][j], real ), W_mult0_32_32( Cldfb_ImagBuffer[2][j], img ) ), guard_bits ) ); // output Q= 2* input_q - guard_bits
1544 4123520 : move64();
1545 : }
1546 1720096 : norm = 63;
1547 1720096 : move16();
1548 1720096 : IF( intensity_real64[0][i] != 0 )
1549 : {
1550 1720096 : norm = s_min( norm, W_norm( intensity_real64[0][i] ) );
1551 : }
1552 1720096 : IF( intensity_real64[1][i] != 0 )
1553 : {
1554 1580944 : norm = s_min( norm, W_norm( intensity_real64[1][i] ) );
1555 : }
1556 1720096 : IF( intensity_real64[2][i] != 0 )
1557 : {
1558 1552560 : norm = s_min( norm, W_norm( intensity_real64[2][i] ) );
1559 : }
1560 1720096 : intensity_real[0][i] = W_extract_h( W_shl( intensity_real64[0][i], norm ) ); // output Q = 2 * inp_q - guard_bits + norm - 32
1561 1720096 : move32();
1562 1720096 : intensity_real[1][i] = W_extract_h( W_shl( intensity_real64[1][i], norm ) ); // output Q = 2 * inp_q - guard_bits + norm - 32
1563 1720096 : move32();
1564 1720096 : intensity_real[2][i] = W_extract_h( W_shl( intensity_real64[2][i], norm ) ); // output Q = 2 * inp_q - guard_bits + norm - 32
1565 1720096 : move32();
1566 1720096 : q_intensity_real[i] = add( shift_intensity_real, sub( norm, guard_bits ) );
1567 1720096 : move16();
1568 : }
1569 :
1570 72320 : return;
1571 : }
1572 :
1573 72320 : static void computeReferencePower_omasa_ivas_fx(
1574 : const Word16 *band_grouping, /* i : Band grouping for estimation */
1575 : Word32 Cldfb_RealBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i : Real part of input signal Q6*/
1576 : Word32 Cldfb_ImagBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i : Imag part of input signal Q6*/
1577 : Word32 *reference_power, /* o : Estimated power Q(31-ref_exp)*/
1578 : const Word16 enc_param_start_band, /* i : first band to process */
1579 : const Word16 num_freq_bands, /* i : Number of frequency bands */
1580 : Word16 q_Cldfb,
1581 : Word16 q_reference_power[CLDFB_NO_CHANNELS_MAX] )
1582 : {
1583 : Word16 brange[2];
1584 : Word16 ch_idx, i, j;
1585 : Word64 reference_power_tmp[CLDFB_NO_CHANNELS_MAX];
1586 : Word16 shift_ref_power, num_bins, guard_bits, norm;
1587 :
1588 72320 : shift_ref_power = sub( shl( q_Cldfb, 1 ), 30 );
1589 :
1590 1792416 : FOR( i = 0; i < num_freq_bands; i++ )
1591 : {
1592 1720096 : brange[0] = band_grouping[i + enc_param_start_band];
1593 1720096 : move16();
1594 1720096 : brange[1] = band_grouping[i + enc_param_start_band + 1];
1595 1720096 : move16();
1596 1720096 : reference_power[i] = 0;
1597 1720096 : move32();
1598 1720096 : reference_power_tmp[i] = 0;
1599 1720096 : move64();
1600 :
1601 1720096 : num_bins = sub( brange[1], brange[0] );
1602 1720096 : guard_bits = find_guarded_bits_fx( num_bins );
1603 :
1604 8600480 : FOR( ch_idx = 0; ch_idx < FOA_CHANNELS; ch_idx++ )
1605 : {
1606 : /* abs()^2 */
1607 23374464 : FOR( j = brange[0]; j < brange[1]; j++ )
1608 : {
1609 16494080 : reference_power_tmp[i] = W_add( reference_power_tmp[i], W_shr( W_mac_32_32( W_mult_32_32( Cldfb_RealBuffer[ch_idx][j], Cldfb_RealBuffer[ch_idx][j] ), Cldfb_ImagBuffer[ch_idx][j], Cldfb_ImagBuffer[ch_idx][j] ), guard_bits ) ); // output Q = 2 * q_cldfb + 1 - guard_bits
1610 16494080 : move64();
1611 : }
1612 : }
1613 1720096 : norm = 63;
1614 1720096 : move16();
1615 1720096 : IF( reference_power_tmp[i] != 0 )
1616 : {
1617 1720096 : norm = W_norm( reference_power_tmp[i] );
1618 : }
1619 1720096 : reference_power[i] = W_extract_h( W_shl( reference_power_tmp[i], norm ) ); // output Q = 2 * q_cldfb + 2 - guard_bits + norm - 32
1620 1720096 : move32();
1621 1720096 : q_reference_power[i] = add( shift_ref_power, sub( norm, guard_bits ) );
1622 1720096 : move16();
1623 : }
1624 :
1625 72320 : return;
1626 : }
|