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