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.h"
39 : #include "prot.h"
40 : #include "ivas_rom_com.h"
41 : #include "ivas_rom_enc.h"
42 : #ifdef DEBUGGING
43 : #include "debug.h"
44 : #endif
45 : #include "wmc_auto.h"
46 :
47 :
48 : /*-------------------------------------------------------------------------
49 : * Local constants
50 : *------------------------------------------------------------------------*/
51 :
52 : #define OMASA_FEC_MAX 5
53 :
54 : /*-------------------------------------------------------------------------
55 : * Local function prototypes
56 : *------------------------------------------------------------------------*/
57 :
58 : static void ivas_omasa_param_est_enc( OMASA_ENC_HANDLE hOMasa, OMASA_ENCODER_DATA_HANDLE hOmasaData, ISM_METADATA_HANDLE hIsmMeta[], float *data_f[], float elevation_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], float azimuth_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], float energyRatio[MASA_FREQUENCY_BANDS], float spreadCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], float surroundingCoherence[MASA_FREQUENCY_BANDS], float diffuseness_m[MASA_FREQUENCY_BANDS], const int16_t input_frame, const int16_t nchan_inp );
59 :
60 : static void ivas_omasa_energy_and_ratio_est( OMASA_ENC_HANDLE hOMasa, OMASA_ENCODER_DATA_HANDLE hOmasaData, float *data_f[], const int16_t input_frame, const int16_t nchan_inp );
61 :
62 : static void ivas_omasa_dmx( float *data_in_f[], float data_out_f[][L_FRAME48k], const int16_t input_frame, const int16_t nchan_transport, const int16_t nchan_ism, ISM_METADATA_HANDLE hIsmMeta[], float prev_gains[][MASA_MAX_TRANSPORT_CHANNELS], const float interpolator[L_FRAME48k] );
63 :
64 : static void computeIntensityVector_enc( const int16_t *band_grouping, float Cldfb_RealBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], float Cldfb_ImagBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], const int16_t num_frequency_bands, float intensity_real[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS] );
65 :
66 : static void computeReferencePower_omasa( const int16_t *band_grouping, float Cldfb_RealBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], float Cldfb_ImagBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], float *reference_power, const int16_t enc_param_start_band, const int16_t num_freq_bands );
67 :
68 : /*--------------------------------------------------------------------------*
69 : * ivas_omasa_enc_open()
70 : *
71 : * Allocate and initialize OMASA handle
72 : *--------------------------------------------------------------------------*/
73 :
74 464 : ivas_error ivas_omasa_enc_open(
75 : Encoder_Struct *st_ivas /* i/o: IVAS encoder handle */
76 : )
77 : {
78 : int16_t i, j;
79 : OMASA_ENC_HANDLE hOMasa;
80 : int16_t numAnalysisChannels;
81 : int16_t input_frame;
82 : ivas_error error;
83 :
84 464 : error = IVAS_ERR_OK;
85 :
86 464 : assert( st_ivas->hMasa != NULL && "MASA encoder handle is not present" );
87 :
88 464 : if ( ( hOMasa = (OMASA_ENC_HANDLE) malloc( sizeof( OMASA_ENC_STATE ) ) ) == NULL )
89 : {
90 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for OMASA encoder\n" ) );
91 : }
92 :
93 464 : numAnalysisChannels = st_ivas->hEncoderConfig->nchan_ism;
94 :
95 : /* open/initialize CLDFB */
96 464 : hOMasa->num_Cldfb_instances = numAnalysisChannels;
97 1906 : for ( i = 0; i < hOMasa->num_Cldfb_instances; i++ )
98 : {
99 1442 : if ( ( error = openCldfb( &( hOMasa->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, st_ivas->hEncoderConfig->input_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK )
100 : {
101 0 : return error;
102 : }
103 : }
104 :
105 : /* intensity 3-dim */
106 1856 : for ( i = 0; i < DIRAC_NUM_DIMS; i++ )
107 : {
108 1392 : hOMasa->direction_vector_m[i] = (float **) malloc( MAX_PARAM_SPATIAL_SUBFRAMES * sizeof( float * ) );
109 :
110 6960 : for ( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ )
111 : {
112 5568 : if ( ( hOMasa->direction_vector_m[i][j] = (float *) malloc( MASA_FREQUENCY_BANDS * sizeof( float ) ) ) == NULL )
113 : {
114 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for OMASA data\n" ) );
115 : }
116 5568 : set_zero( hOMasa->direction_vector_m[i][j], MASA_FREQUENCY_BANDS );
117 : }
118 : }
119 :
120 1856 : for ( i = 0; i < DIRAC_NUM_DIMS; i++ )
121 : {
122 45936 : for ( j = 0; j < DIRAC_NO_COL_AVG_DIFF; j++ )
123 : {
124 44544 : if ( ( hOMasa->buffer_intensity_real[i][j] = (float *) malloc( MASA_FREQUENCY_BANDS * sizeof( float ) ) ) == NULL )
125 : {
126 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for OMASA data\n" ) );
127 : }
128 44544 : set_zero( hOMasa->buffer_intensity_real[i][j], MASA_FREQUENCY_BANDS );
129 : }
130 : }
131 :
132 464 : set_zero( hOMasa->buffer_energy, DIRAC_NO_COL_AVG_DIFF * MASA_FREQUENCY_BANDS );
133 :
134 2320 : for ( i = 0; i < MAX_NUM_OBJECTS; i++ )
135 : {
136 1856 : set_f( hOMasa->prev_object_dm_gains[i], INV_SQRT_2, MASA_MAX_TRANSPORT_CHANNELS );
137 : }
138 464 : set_zero( hOMasa->broadband_energy_sm, MAX_NUM_OBJECTS + MASA_MAX_TRANSPORT_CHANNELS );
139 464 : set_zero( hOMasa->broadband_energy_prev, MAX_NUM_OBJECTS + MASA_MAX_TRANSPORT_CHANNELS );
140 464 : hOMasa->prev_selected_object = 0;
141 464 : hOMasa->changing_object = 0;
142 464 : hOMasa->since_obj_change_cnt = 0;
143 :
144 464 : input_frame = (int16_t) ( st_ivas->hEncoderConfig->input_Fs / FRAMES_PER_SEC );
145 420304 : for ( i = 0; i < input_frame; i++ )
146 : {
147 419840 : hOMasa->interpolator[i] = ( (float) i ) / ( (float) input_frame );
148 419840 : hOMasa->fade_out_gain[i] = ( 1.0f + cosf( ( (float) i ) / ( (float) input_frame ) * EVS_PI ) ) / 2.0f;
149 419840 : hOMasa->fade_in_gain[i] = 1.0f - hOMasa->fade_out_gain[i];
150 : }
151 :
152 464 : hOMasa->index_buffer_intensity = 0;
153 :
154 464 : st_ivas->hOMasa = hOMasa;
155 :
156 464 : return error;
157 : }
158 :
159 :
160 : /*--------------------------------------------------------------------------*
161 : * ivas_omasa_enc_close()
162 : *
163 : * Close OMASA handle
164 : *--------------------------------------------------------------------------*/
165 :
166 1066 : void ivas_omasa_enc_close(
167 : OMASA_ENC_HANDLE *hOMasa /* i/o: encoder OMASA handle */
168 : )
169 : {
170 : int16_t i, j;
171 :
172 1066 : if ( hOMasa == NULL || *hOMasa == NULL )
173 : {
174 602 : return;
175 : }
176 :
177 1906 : for ( i = 0; i < ( *hOMasa )->num_Cldfb_instances; i++ )
178 : {
179 1442 : deleteCldfb( &( ( *hOMasa )->cldfbAnaEnc[i] ) );
180 : }
181 :
182 1856 : for ( i = 0; i < DIRAC_NUM_DIMS; i++ )
183 : {
184 6960 : for ( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ )
185 : {
186 5568 : free( ( *hOMasa )->direction_vector_m[i][j] );
187 5568 : ( *hOMasa )->direction_vector_m[i][j] = NULL;
188 : }
189 :
190 45936 : for ( j = 0; j < DIRAC_NO_COL_AVG_DIFF; j++ )
191 : {
192 44544 : free( ( *hOMasa )->buffer_intensity_real[i][j] );
193 44544 : ( *hOMasa )->buffer_intensity_real[i][j] = NULL;
194 : }
195 :
196 1392 : free( ( *hOMasa )->direction_vector_m[i] );
197 1392 : ( *hOMasa )->direction_vector_m[i] = NULL;
198 : }
199 :
200 464 : free( *hOMasa );
201 464 : ( *hOMasa ) = NULL;
202 :
203 464 : return;
204 : }
205 :
206 :
207 : /*--------------------------------------------------------------------------*
208 : * ivas_omasa_enc_config()
209 : *
210 : * oMASA encoder configuration
211 : *--------------------------------------------------------------------------*/
212 :
213 9000 : ivas_error ivas_omasa_enc_config(
214 : Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */
215 : )
216 : {
217 : int16_t k, sce_id, nSCE_old;
218 : int32_t ivas_total_brate, ism_total_brate;
219 : ENCODER_CONFIG_HANDLE hEncoderConfig;
220 : ivas_error error;
221 :
222 9000 : hEncoderConfig = st_ivas->hEncoderConfig;
223 9000 : ivas_total_brate = hEncoderConfig->ivas_total_brate;
224 9000 : nSCE_old = st_ivas->nSCE;
225 :
226 9000 : st_ivas->ism_mode = ivas_omasa_ism_mode_select( ivas_total_brate, hEncoderConfig->nchan_ism );
227 9000 : st_ivas->nchan_transport = 2;
228 :
229 : /* reconfiguration in case of bitrate switching */
230 9000 : if ( hEncoderConfig->last_ivas_total_brate != ivas_total_brate )
231 : {
232 1634 : ivas_set_omasa_TC( st_ivas->ism_mode, hEncoderConfig->nchan_ism, &st_ivas->nSCE, &st_ivas->nCPE );
233 :
234 1634 : k = 0;
235 12910 : while ( k < SIZE_IVAS_BRATE_TBL && ivas_total_brate != ivas_brate_tbl[k] )
236 : {
237 11276 : k++;
238 : }
239 :
240 1634 : ism_total_brate = 0;
241 3746 : for ( sce_id = 0; sce_id < st_ivas->nSCE; sce_id++ )
242 : {
243 2112 : ism_total_brate += sep_object_brate[k - 2][st_ivas->nSCE - 1];
244 : }
245 :
246 1634 : if ( st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ )
247 : {
248 403 : if ( ( error = ivas_ism_config( st_ivas->hEncoderConfig->ivas_total_brate, st_ivas->nchan_transport, 1, NULL, 0, NULL, NULL, NULL, NULL, NULL, 1 ) ) != IVAS_ERR_OK )
249 : {
250 0 : return error;
251 : }
252 : }
253 1231 : else if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC )
254 : {
255 439 : if ( ( error = ivas_ism_config( st_ivas->hEncoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->nSCE, NULL, 0, NULL, NULL, NULL, NULL, NULL, 1 ) ) != IVAS_ERR_OK )
256 : {
257 0 : return error;
258 : }
259 : }
260 :
261 : /* reconfigure core-coders for ISMs */
262 1634 : if ( ( error = ivas_corecoder_enc_reconfig( st_ivas, nSCE_old, 1, 2, st_ivas->nSCE > 0 ? sep_object_brate[k - 2][st_ivas->nSCE - 1] : 0, ivas_total_brate - ism_total_brate, MC_MODE_NONE ) ) != IVAS_ERR_OK )
263 : {
264 0 : return error;
265 : }
266 :
267 : /* re-write IVAS format signalling - actual 'ism_mode' was not known before */
268 1634 : if ( st_ivas->nSCE > 0 )
269 : {
270 1190 : reset_indices_enc( st_ivas->hSCE[0]->hCoreCoder[0]->hBstr, st_ivas->hSCE[0]->hCoreCoder[0]->hBstr->nb_bits_tot );
271 : }
272 : else
273 : {
274 444 : reset_indices_enc( st_ivas->hCPE[0]->hCoreCoder[0]->hBstr, st_ivas->hCPE[0]->hCoreCoder[0]->hBstr->nb_bits_tot );
275 : }
276 :
277 1634 : ivas_write_format( st_ivas );
278 :
279 : /* OMASA encoder handle */
280 1634 : if ( st_ivas->ism_mode != ISM_MASA_MODE_DISC && st_ivas->hOMasa == NULL )
281 : {
282 437 : if ( ( error = ivas_omasa_enc_open( st_ivas ) ) != IVAS_ERR_OK )
283 : {
284 0 : return error;
285 : }
286 : }
287 1197 : else if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC && st_ivas->hOMasa != NULL )
288 : {
289 439 : ivas_omasa_enc_close( &( st_ivas->hOMasa ) );
290 439 : st_ivas->hOMasa = NULL;
291 : }
292 :
293 : /* OMASA energy handle */
294 1634 : if ( st_ivas->ism_mode != ISM_MASA_MODE_DISC && st_ivas->hMasa->data.hOmasaData->hOmasaEnergy == NULL )
295 : {
296 437 : if ( ( st_ivas->hMasa->data.hOmasaData->hOmasaEnergy = (OMASA_ENCODER_ENERGY_HANDLE) malloc( sizeof( OMASA_ENCODER_ENERGY_STATE ) ) ) == NULL )
297 : {
298 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for OMASA energy handle\n" ) );
299 : }
300 : }
301 1197 : else if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC && st_ivas->hMasa->data.hOmasaData->hOmasaEnergy != NULL )
302 : {
303 439 : free( st_ivas->hMasa->data.hOmasaData->hOmasaEnergy );
304 439 : st_ivas->hMasa->data.hOmasaData->hOmasaEnergy = NULL;
305 : }
306 :
307 1634 : st_ivas->hCPE[0]->element_brate = ivas_total_brate - ism_total_brate;
308 :
309 1634 : if ( ivas_total_brate - ism_total_brate >= MIN_BRATE_MDCT_STEREO )
310 : {
311 709 : hEncoderConfig->element_mode_init = IVAS_CPE_MDCT;
312 : }
313 : else
314 : {
315 925 : hEncoderConfig->element_mode_init = IVAS_CPE_DFT;
316 : }
317 : }
318 :
319 : /* Configure MASA encoder based on frame parameters */
320 9000 : if ( ( error = ivas_masa_enc_config( st_ivas ) ) != IVAS_ERR_OK )
321 : {
322 0 : return error;
323 : }
324 :
325 9000 : if ( st_ivas->ism_mode != ISM_MASA_MODE_DISC )
326 : {
327 : /* Configure oMASA analysis based on MASA config */
328 5858 : ivas_omasa_set_config( st_ivas->hOMasa, st_ivas->hMasa, st_ivas->hEncoderConfig->input_Fs, st_ivas->ism_mode );
329 : }
330 :
331 9000 : return IVAS_ERR_OK;
332 : }
333 :
334 :
335 : /*--------------------------------------------------------------------------*
336 : * ivas_omasa_set_config()
337 : *
338 : * Frame-by-frame config for oMASA
339 : *--------------------------------------------------------------------------*/
340 :
341 5858 : void ivas_omasa_set_config(
342 : OMASA_ENC_HANDLE hOMasa, /* i/o: OMASA encoder handle */
343 : MASA_ENCODER_HANDLE hMasa, /* i : MASA encoder handle */
344 : const int32_t input_Fs, /* i : Input sample rate */
345 : const ISM_MODE ism_mode /* i : ISM mode */
346 : )
347 : {
348 : uint8_t i, maxBin;
349 :
350 : /* Determine the number of bands */
351 5858 : if ( ism_mode == ISM_MODE_NONE || ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ )
352 : {
353 : /* use full resolution for the ISM+MASA merge and reduce later */
354 3996 : hOMasa->nbands = 24;
355 : }
356 : else
357 : {
358 1862 : hOMasa->nbands = hMasa->config.numCodingBands;
359 : }
360 :
361 5858 : hOMasa->nCodingBands = hMasa->config.numCodingBands;
362 :
363 : /* Determine the number of subframes */
364 5858 : hOMasa->nSubframes = hMasa->config.joinedSubframes == TRUE ? 1 : MAX_PARAM_SPATIAL_SUBFRAMES;
365 :
366 : /* Determine band grouping */
367 5858 : if ( hOMasa->nbands == 24 )
368 : {
369 3996 : mvs2s( MASA_band_grouping_24, hOMasa->band_grouping, 24 + 1 );
370 : }
371 : else
372 : {
373 15680 : for ( i = 0; i < hOMasa->nbands + 1; i++ )
374 : {
375 13818 : hOMasa->band_grouping[i] = MASA_band_grouping_24[hMasa->data.band_mapping[i]];
376 : }
377 : }
378 :
379 5858 : maxBin = (uint8_t) ( input_Fs * INV_CLDFB_BANDWIDTH + 0.5f );
380 :
381 106960 : for ( i = 1; i < hOMasa->nbands + 1; i++ )
382 : {
383 106960 : if ( hOMasa->band_grouping[i] >= maxBin )
384 : {
385 5858 : hOMasa->band_grouping[i] = maxBin;
386 5858 : hOMasa->nbands = i;
387 5858 : break;
388 : }
389 : }
390 :
391 5858 : mvs2s( DirAC_block_grouping, hOMasa->block_grouping, MAX_PARAM_SPATIAL_SUBFRAMES + 1 );
392 5858 : if ( hOMasa->nSubframes == 1 )
393 : {
394 1426 : hOMasa->block_grouping[1] = hOMasa->block_grouping[MAX_PARAM_SPATIAL_SUBFRAMES];
395 : }
396 :
397 5858 : return;
398 : }
399 :
400 :
401 : /*--------------------------------------------------------------------------*
402 : * ivas_omasa_enc()
403 : *
404 : * Main OMASA encoding function
405 : *--------------------------------------------------------------------------*/
406 :
407 5858 : void ivas_omasa_enc(
408 : OMASA_ENC_HANDLE hOMasa, /* i/o: OMASA encoder handle */
409 : MASA_ENCODER_HANDLE hMasa, /* i/o: MASA encoder handle */
410 : ISM_METADATA_HANDLE hIsmMeta[], /* i/o: ISM metadata handle */
411 : float *data_in_f[], /* i/o: Input / transport audio signals */
412 : const int16_t input_frame, /* i : Input frame size */
413 : const int16_t nchan_transport, /* i : Number of transport channels */
414 : const int16_t nchan_ism, /* i : Number of objects for parameter analysis */
415 : const ISM_MODE ism_mode, /* i : ISM mode */
416 : float *data_separated_object, /* o : Separated object audio signal */
417 : int16_t *idx_separated_object /* o : Index of the separated object */
418 : )
419 : {
420 : int16_t i, j;
421 : float data_out_f[MASA_MAX_TRANSPORT_CHANNELS][L_FRAME48k];
422 :
423 : /* Determine separated object (when applicable) */
424 5858 : if ( ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ )
425 : {
426 : float broadband_energy[MAX_NUM_OBJECTS + MASA_MAX_TRANSPORT_CHANNELS];
427 : int16_t loudest_object;
428 : int16_t selected_object;
429 : int16_t nchan_all_inp;
430 : float alpha;
431 : uint8_t fade_out_separate_object;
432 : uint8_t fade_in_separate_object;
433 :
434 : /* Estimate broadband energies */
435 3916 : nchan_all_inp = nchan_ism + nchan_transport;
436 3916 : set_zero( broadband_energy, nchan_all_inp );
437 25272 : for ( i = 0; i < nchan_all_inp; i++ )
438 : {
439 19569516 : for ( j = 0; j < input_frame; j++ )
440 : {
441 19548160 : broadband_energy[i] += data_in_f[i][j] * data_in_f[i][j];
442 : }
443 : }
444 :
445 : /* Temporal averaging */
446 3916 : alpha = 0.8f;
447 25272 : for ( i = 0; i < nchan_all_inp; i++ )
448 : {
449 21356 : hOMasa->broadband_energy_sm[i] = ( 1.0f - alpha ) * broadband_energy[i] + alpha * hOMasa->broadband_energy_sm[i];
450 : }
451 :
452 : /* Determine loudest object */
453 3916 : loudest_object = 0;
454 13524 : for ( i = 1; i < nchan_ism; i++ )
455 : {
456 9608 : if ( hOMasa->broadband_energy_sm[i] > hOMasa->broadband_energy_sm[loudest_object] )
457 : {
458 1998 : loudest_object = i;
459 : }
460 : }
461 :
462 : /* Determine object to separate */
463 3916 : selected_object = hOMasa->prev_selected_object;
464 3916 : fade_out_separate_object = 0;
465 3916 : fade_in_separate_object = 0;
466 3916 : if ( hOMasa->changing_object )
467 : {
468 125 : hOMasa->changing_object = 0;
469 125 : selected_object = loudest_object;
470 125 : fade_in_separate_object = 1;
471 : }
472 : else
473 : {
474 3791 : if ( loudest_object != hOMasa->prev_selected_object )
475 : {
476 : float selected_ene;
477 : float total_ene;
478 : float selected_ratio;
479 : float adaptive_threshold_dB;
480 : float ratio_objects_dB;
481 763 : float hardswitch_threshold = 0.25f;
482 :
483 : /* Compute the energy of the current and the previous selected object in the current and the previous frame */
484 763 : selected_ene = broadband_energy[loudest_object] + broadband_energy[hOMasa->prev_selected_object] + hOMasa->broadband_energy_prev[loudest_object] + hOMasa->broadband_energy_prev[hOMasa->prev_selected_object];
485 :
486 : /* Compute the energy of all objects and MASA channels in the current and the previous frame */
487 763 : total_ene = 0.0f;
488 4917 : for ( i = 0; i < nchan_all_inp; i++ )
489 : {
490 4154 : total_ene += broadband_energy[i] + hOMasa->broadband_energy_prev[i];
491 : }
492 :
493 : /* Compute the ratio */
494 763 : selected_ratio = selected_ene / ( total_ene + EPSILON );
495 :
496 763 : adaptive_threshold_dB = selected_ratio * 9.0f + 1.0f; /* selected ratio = 0 -> 1 dB, selected ratio = 1 -> 10 dB */
497 763 : ratio_objects_dB = 10.0f * log10f( hOMasa->broadband_energy_sm[loudest_object] / ( hOMasa->broadband_energy_sm[hOMasa->prev_selected_object] + EPSILON ) );
498 :
499 : /* 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. */
500 763 : if ( ratio_objects_dB > adaptive_threshold_dB )
501 : {
502 184 : if ( selected_ratio < hardswitch_threshold ) /* If low level compared to all audio channels, perform hardswitch */
503 : {
504 53 : selected_object = loudest_object;
505 : }
506 : else /* If high level compared to all audio channels, perform switch via fade out fade in */
507 : {
508 131 : hOMasa->changing_object = 1;
509 131 : fade_out_separate_object = 1;
510 : }
511 : }
512 : }
513 : }
514 :
515 : /* Set values for next frame */
516 25272 : for ( i = 0; i < nchan_all_inp; i++ )
517 : {
518 21356 : hOMasa->broadband_energy_prev[i] = broadband_energy[i];
519 : }
520 :
521 : /* force absolute MD coding in case of change of separated object */
522 3916 : if ( hOMasa->prev_selected_object != selected_object )
523 : {
524 178 : hOMasa->since_obj_change_cnt = 0;
525 178 : hIsmMeta[0]->position_angle.angle1_diff_cnt = ISM_FEC_MAX;
526 : }
527 : else
528 : {
529 3738 : hOMasa->since_obj_change_cnt++;
530 3738 : hOMasa->since_obj_change_cnt = min( OMASA_FEC_MAX, hOMasa->since_obj_change_cnt );
531 3738 : if ( hOMasa->since_obj_change_cnt < OMASA_FEC_MAX )
532 : {
533 1293 : hIsmMeta[0]->position_angle.angle1_diff_cnt = ISM_FEC_MAX;
534 : }
535 : }
536 3916 : hOMasa->prev_selected_object = selected_object;
537 :
538 : /* Separate the selected object */
539 3916 : *idx_separated_object = selected_object;
540 3916 : mvr2r( data_in_f[selected_object], data_separated_object, input_frame );
541 3916 : if ( fade_out_separate_object )
542 : {
543 131 : v_mult( data_separated_object, hOMasa->fade_out_gain, data_separated_object, input_frame );
544 131 : v_mult( data_in_f[selected_object], hOMasa->fade_in_gain, data_in_f[selected_object], input_frame );
545 : }
546 3785 : else if ( fade_in_separate_object )
547 : {
548 125 : v_mult( data_separated_object, hOMasa->fade_in_gain, data_separated_object, input_frame );
549 125 : v_mult( data_in_f[selected_object], hOMasa->fade_out_gain, data_in_f[selected_object], input_frame );
550 : }
551 : else
552 : {
553 3660 : set_zero( data_in_f[selected_object], input_frame );
554 : }
555 : }
556 :
557 : /* Analysis */
558 5858 : if ( ism_mode == ISM_MODE_NONE || ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ )
559 3996 : {
560 : OMASA_SPATIAL_META OMasaMeta; /* working memory for the ISM-object MASA-parameters */
561 : OMASA_SPATIAL_META_HANDLE hOMasaMeta;
562 : uint8_t n_bands_orig, n_subframes_orig;
563 : uint8_t numCodingBands_orig, joinedSubframes_orig;
564 :
565 3996 : hOMasaMeta = &OMasaMeta;
566 3996 : hOMasaMeta->num_dirs = 1;
567 :
568 : /* merge MASA directions before adding ISM to the mixture */
569 3996 : if ( hMasa->config.numberOfDirections == 2 )
570 : {
571 2198 : n_bands_orig = hMasa->config.numCodingBands;
572 2198 : hMasa->config.numCodingBands = MASA_FREQUENCY_BANDS;
573 :
574 2198 : ivas_masa_combine_directions( hMasa );
575 :
576 2198 : hMasa->config.numCodingBands = (int8_t) n_bands_orig;
577 : }
578 :
579 : /* force computation into high resolution */
580 :
581 3996 : n_subframes_orig = hOMasa->nSubframes;
582 3996 : hOMasa->nSubframes = MAX_PARAM_SPATIAL_SUBFRAMES;
583 :
584 : /* Estimate MASA parameters from the objects */
585 : /* NB: only first direction is populated */
586 : /* NB2: in energy_ratios and surround_coherence only first sub-frame contains valid data */
587 3996 : ivas_omasa_param_est_enc( hOMasa, hMasa->data.hOmasaData, hIsmMeta, data_in_f, hOMasaMeta->directional_meta[0].elevation, hOMasaMeta->directional_meta[0].azimuth, hOMasaMeta->directional_meta[0].energy_ratio[0], hOMasaMeta->directional_meta[0].spread_coherence, hOMasaMeta->common_meta.surround_coherence[0],
588 3996 : hOMasaMeta->common_meta.diffuse_to_total_ratio[0], input_frame, nchan_ism );
589 :
590 : /* copy energy_ratios and surrCoh from first sub-frame to the remaining ones */
591 15984 : for ( i = 1; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ )
592 : {
593 11988 : mvr2r( hOMasaMeta->directional_meta[0].energy_ratio[0], hOMasaMeta->directional_meta[0].energy_ratio[i], MASA_FREQUENCY_BANDS );
594 11988 : mvr2r( hOMasaMeta->common_meta.surround_coherence[0], hOMasaMeta->common_meta.surround_coherence[i], MASA_FREQUENCY_BANDS );
595 11988 : mvr2r( hOMasaMeta->common_meta.diffuse_to_total_ratio[0], hOMasaMeta->common_meta.diffuse_to_total_ratio[i], MASA_FREQUENCY_BANDS );
596 : }
597 :
598 : /* restore resolution parameters */
599 3996 : hOMasa->nSubframes = n_subframes_orig;
600 :
601 : /* perform MASA+ISM merge in full resolution */
602 3996 : numCodingBands_orig = hMasa->config.numCodingBands;
603 3996 : joinedSubframes_orig = hMasa->config.joinedSubframes;
604 :
605 3996 : hMasa->config.numCodingBands = hOMasa->nbands;
606 3996 : hMasa->config.joinedSubframes = 0;
607 :
608 3996 : ivas_merge_masa_metadata( hMasa, hOMasaMeta ); /* => merge result in hMasa->masaMetadata */
609 :
610 3996 : hMasa->config.numCodingBands = numCodingBands_orig;
611 3996 : hMasa->config.joinedSubframes = joinedSubframes_orig;
612 : }
613 1862 : else if ( ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ )
614 : {
615 : /* Estimate energies and ratios */
616 1862 : ivas_omasa_energy_and_ratio_est( hOMasa, hMasa->data.hOmasaData, data_in_f, input_frame, nchan_ism );
617 : }
618 :
619 : /* Downmix */
620 5858 : ivas_omasa_dmx( data_in_f, data_out_f, input_frame, nchan_transport, nchan_ism, hIsmMeta, hOMasa->prev_object_dm_gains, hOMasa->interpolator );
621 :
622 : /* Move the ISM metadata to the first entry for encoding in the MASA_ONE_OBJ mode */
623 5858 : if ( ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ )
624 : {
625 2054 : hIsmMeta[0]->azimuth = hIsmMeta[*idx_separated_object]->azimuth;
626 2054 : hIsmMeta[0]->elevation = hIsmMeta[*idx_separated_object]->elevation;
627 : }
628 :
629 : /* Merge transport signals */
630 5858 : ivas_merge_masa_transports( data_out_f, &( data_in_f[nchan_ism] ), data_in_f, input_frame, nchan_transport );
631 :
632 5858 : return;
633 : }
634 :
635 :
636 : /*-------------------------------------------------------------------------*
637 : * ivas_set_ism_importance_interformat()
638 : *
639 : * Set the importance of particular ISM streams in combined-format coding
640 : *-------------------------------------------------------------------------*/
641 :
642 7058 : void ivas_set_ism_importance_interformat(
643 : const int32_t ism_total_brate, /* i/o: ISms total bitrate */
644 : const int16_t nchan_transport, /* i : number of transported channels */
645 : ISM_METADATA_HANDLE hIsmMeta[], /* i/o: ISM metadata handles */
646 : SCE_ENC_HANDLE hSCE[], /* i/o: SCE encoder handles */
647 : const float lp_noise_CPE, /* i : LP filtered total noise estimation */
648 : int16_t ism_imp[] /* o : ISM importance flags */
649 : )
650 : {
651 : Encoder_State *st;
652 : int16_t ch, ctype, active_flag;
653 :
654 19434 : for ( ch = 0; ch < nchan_transport; ch++ )
655 : {
656 12376 : st = hSCE[ch]->hCoreCoder[0];
657 :
658 12376 : active_flag = st->vad_flag;
659 :
660 12376 : if ( active_flag == 0 )
661 : {
662 272 : if ( st->lp_noise > 15 || lp_noise_CPE - st->lp_noise < 30 )
663 : {
664 272 : active_flag = 1;
665 : }
666 : }
667 :
668 : /* do not use the low-rate core-coder mode at highest bit-rates */
669 12376 : if ( ism_total_brate / nchan_transport > IVAS_48k )
670 : {
671 1428 : active_flag = 1;
672 : }
673 :
674 12376 : ctype = hSCE[ch]->hCoreCoder[0]->coder_type_raw;
675 :
676 12376 : st->low_rate_mode = 0;
677 12376 : if ( active_flag == 0 )
678 : {
679 0 : ism_imp[ch] = ISM_INACTIVE_IMP;
680 0 : st->low_rate_mode = 1;
681 : }
682 12376 : else if ( ctype == INACTIVE || ctype == UNVOICED )
683 : {
684 449 : ism_imp[ch] = ISM_LOW_IMP;
685 : }
686 11927 : else if ( ctype == VOICED )
687 : {
688 3111 : ism_imp[ch] = ISM_MEDIUM_IMP;
689 : }
690 : else /* GENERIC */
691 : {
692 8816 : ism_imp[ch] = ISM_HIGH_IMP;
693 : }
694 :
695 12376 : hIsmMeta[ch]->ism_metadata_flag = active_flag; /* flag is needed for the MD coding */
696 : }
697 :
698 7058 : return;
699 : }
700 :
701 :
702 : /*--------------------------------------------------------------------------*
703 : * ivas_set_surplus_brate_enc()
704 : *
705 : * set bit-rate surplus in combined format coding
706 : *--------------------------------------------------------------------------*/
707 :
708 9000 : void ivas_set_surplus_brate_enc(
709 : Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */
710 : #ifdef DEBUG_MODE_INFO
711 : ,
712 : const int16_t *nb_bits_metadata /* i : number of metadata bits */
713 : #endif
714 : )
715 : {
716 9000 : if ( st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ )
717 : {
718 1862 : st_ivas->hCPE[0]->brate_surplus = st_ivas->hSCE[0]->element_brate - ivas_interformat_brate( ISM_MASA_MODE_PARAM_ONE_OBJ, 1, st_ivas->hSCE[0]->element_brate, st_ivas->hIsmMetaData[0]->ism_imp, 0 );
719 : /* note: ISM st->total_brate is iset in ivas_sce_enc() */
720 : }
721 7138 : else if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC || st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ )
722 : {
723 : /* it is already set in ivas_ism_enc() */
724 : }
725 : else
726 : {
727 1942 : st_ivas->hCPE[0]->brate_surplus = 0;
728 : }
729 :
730 : #ifdef DEBUG_MODE_INFO
731 : if ( st_ivas->hSCE[0] != NULL )
732 : {
733 : int16_t input_frame = (int16_t) ( st_ivas->hEncoderConfig->input_Fs / FRAMES_PER_SEC );
734 : float tmpF = 0;
735 :
736 : if ( st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ )
737 : {
738 : tmpF += st_ivas->hSCE[0]->hCoreCoder[0]->total_brate + (float) ( nb_bits_metadata[1] * 50 );
739 : }
740 : else
741 : {
742 : for ( int16_t i = 0; i < st_ivas->hEncoderConfig->nchan_ism; i++ )
743 : {
744 : tmpF += st_ivas->hSCE[i]->hCoreCoder[0]->total_brate + (float) ( nb_bits_metadata[i + 1] * 50 );
745 : }
746 : }
747 : tmpF /= 1000.f;
748 : dbgwrite( &tmpF, 4, 1, input_frame, "res/brate_ISM" ); /* == ism_total_brate incl. ISM MD */
749 : tmpF = st_ivas->hEncoderConfig->ivas_total_brate / 1000.0f - tmpF;
750 : dbgwrite( &tmpF, 4, 1, input_frame, "res/brate_MASA" ); /* == masa_total_brate incl. MASA MD */
751 : tmpF = nb_bits_metadata[0] * FRAMES_PER_SEC / 1000.0f;
752 : dbgwrite( &tmpF, 4, 1, input_frame, "res/brate_MASA_MD" ); /* == MASA MD bitrate */
753 : }
754 : #endif
755 :
756 9000 : return;
757 : }
758 :
759 :
760 : /*--------------------------------------------------------------------------*
761 : * ivas_omasa_ener_brate()
762 : *
763 : *
764 : *--------------------------------------------------------------------------*/
765 :
766 : /*! r: OMASA energy bitrate flag */
767 3142 : int16_t ivas_omasa_ener_brate(
768 : const int16_t nchan_ism, /* i : number of ISMs */
769 : const int32_t ivas_total_brate, /* i : IVAS total bitrate */
770 : float *data_f[], /* i : Input / transport audio signals */
771 : const int16_t input_frame /* i : Input frame size */
772 : )
773 : {
774 : int16_t i, flag_omasa_ener_brate;
775 : float energy_ism, energy_masa;
776 :
777 3142 : flag_omasa_ener_brate = 0;
778 :
779 3142 : if ( nchan_ism >= 3 && ivas_total_brate == IVAS_128k )
780 : {
781 126 : energy_ism = 0.0f;
782 570 : for ( i = 0; i < nchan_ism; i++ )
783 : {
784 444 : energy_ism += sum2_f( data_f[i], input_frame );
785 : }
786 :
787 126 : energy_masa = 0.0f;
788 378 : for ( i = nchan_ism; i < nchan_ism + MASA_MAXIMUM_DIRECTIONS; i++ )
789 : {
790 252 : energy_masa += sum2_f( data_f[i], input_frame );
791 : }
792 :
793 126 : energy_ism = energy_ism / ( energy_masa + 1.0f ) * 2.0f / (float) ( nchan_ism );
794 :
795 126 : if ( energy_ism < 1.0f )
796 : {
797 38 : flag_omasa_ener_brate = 1;
798 : }
799 : }
800 :
801 3142 : return flag_omasa_ener_brate;
802 : }
803 :
804 :
805 : /*--------------------------------------------------------------------------*
806 : * Local functions
807 : *--------------------------------------------------------------------------*/
808 :
809 : /* Estimate MASA parameters from the objects */
810 3996 : static void ivas_omasa_param_est_enc(
811 : OMASA_ENC_HANDLE hOMasa,
812 : OMASA_ENCODER_DATA_HANDLE hOmasaData,
813 : ISM_METADATA_HANDLE hIsmMeta[],
814 : float *data_f[],
815 : float elevation_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS],
816 : float azimuth_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS],
817 : float energyRatio[MASA_FREQUENCY_BANDS],
818 : float spreadCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS],
819 : float surroundingCoherence[MASA_FREQUENCY_BANDS],
820 : float diffuseness_m[MASA_FREQUENCY_BANDS],
821 : const int16_t input_frame,
822 : const int16_t nchan_ism )
823 : {
824 : float reference_power[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
825 : int16_t ts, i, j, d, k;
826 : int16_t num_freq_bins, num_freq_bands, index;
827 : float dir_v[DIRAC_NUM_DIMS];
828 : int16_t l_ts;
829 : float Chnl_RealBuffer[MCMASA_MAX_ANA_CHANS][CLDFB_NO_CHANNELS_MAX];
830 : float Chnl_ImagBuffer[MCMASA_MAX_ANA_CHANS][CLDFB_NO_CHANNELS_MAX];
831 : float Foa_RealBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX];
832 : float Foa_ImagBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX];
833 : float intensity_real[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS];
834 : float direction_vector[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS];
835 : float diffuseness_vector[MASA_FREQUENCY_BANDS];
836 : int16_t band_m_idx, block_m_idx;
837 : float renormalization_factor_diff[MASA_FREQUENCY_BANDS];
838 : float norm_tmp;
839 : int16_t mrange[2], brange[2];
840 3996 : OMASA_ENCODER_ENERGY_HANDLE hOmasaEnergy = hOmasaData->hOmasaEnergy;
841 :
842 3996 : num_freq_bins = hOMasa->cldfbAnaEnc[0]->no_channels;
843 3996 : num_freq_bands = hOMasa->nbands;
844 3996 : l_ts = input_frame / CLDFB_NO_COL_MAX;
845 :
846 : /* Need to initialize renormalization_factors, and variables to be normalized */
847 3996 : set_zero( renormalization_factor_diff, hOMasa->nbands );
848 3996 : set_zero( diffuseness_m, hOMasa->nbands );
849 :
850 : /* Compute ISM to FOA matrices */
851 17156 : for ( i = 0; i < nchan_ism; i++ )
852 : {
853 13160 : hOMasa->chnlToFoaMtx[0][i] = 1.0f;
854 13160 : hOMasa->chnlToFoaMtx[1][i] = sinf( ( hIsmMeta[i]->azimuth / 180.0f * EVS_PI ) ) * cosf( ( hIsmMeta[i]->elevation / 180.0f * EVS_PI ) );
855 13160 : hOMasa->chnlToFoaMtx[2][i] = sinf( ( hIsmMeta[i]->elevation / 180.0f * EVS_PI ) );
856 13160 : hOMasa->chnlToFoaMtx[3][i] = cosf( ( hIsmMeta[i]->azimuth / 180.0f * EVS_PI ) ) * cosf( ( hIsmMeta[i]->elevation / 180.0f * EVS_PI ) );
857 : }
858 :
859 : /* do processing over all CLDFB time slots */
860 19980 : for ( block_m_idx = 0; block_m_idx < hOMasa->nSubframes; block_m_idx++ )
861 : {
862 15984 : mrange[0] = hOMasa->block_grouping[block_m_idx];
863 15984 : mrange[1] = hOMasa->block_grouping[block_m_idx + 1];
864 :
865 396000 : for ( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ )
866 : {
867 380016 : hOMasa->direction_vector_m[0][block_m_idx][band_m_idx] = 0.0f;
868 380016 : hOMasa->direction_vector_m[1][block_m_idx][band_m_idx] = 0.0f;
869 380016 : hOMasa->direction_vector_m[2][block_m_idx][band_m_idx] = 0.0f;
870 : }
871 :
872 15984 : set_zero( hOmasaEnergy->energy_ism[block_m_idx], num_freq_bands );
873 :
874 88304 : for ( ts = mrange[0]; ts < mrange[1]; ts++ )
875 : {
876 311616 : for ( i = 0; i < nchan_ism; i++ )
877 : {
878 239296 : cldfbAnalysis_ts( &( data_f[i][l_ts * ts] ), Chnl_RealBuffer[i], Chnl_ImagBuffer[i], l_ts, hOMasa->cldfbAnaEnc[i] );
879 : }
880 :
881 : /* Compute energy */
882 1792416 : for ( i = 0; i < num_freq_bands; i++ )
883 : {
884 1720096 : brange[0] = hOMasa->band_grouping[i];
885 1720096 : brange[1] = hOMasa->band_grouping[i + 1];
886 5843616 : for ( j = brange[0]; j < brange[1]; j++ )
887 : {
888 17930240 : for ( k = 0; k < nchan_ism; k++ )
889 : {
890 13806720 : hOmasaEnergy->energy_ism[block_m_idx][i] += Chnl_RealBuffer[k][j] * Chnl_RealBuffer[k][j] + Chnl_ImagBuffer[k][j] * Chnl_ImagBuffer[k][j];
891 : }
892 : }
893 : }
894 :
895 : /* Compute FOA */
896 : /* W */
897 72320 : mvr2r( Chnl_RealBuffer[0], Foa_RealBuffer[0], num_freq_bins );
898 72320 : mvr2r( Chnl_ImagBuffer[0], Foa_ImagBuffer[0], num_freq_bins );
899 239296 : for ( i = 1; i < nchan_ism; i++ )
900 : {
901 166976 : v_add( Chnl_RealBuffer[i], Foa_RealBuffer[0], Foa_RealBuffer[0], num_freq_bins );
902 166976 : v_add( Chnl_ImagBuffer[i], Foa_ImagBuffer[0], Foa_ImagBuffer[0], num_freq_bins );
903 : }
904 :
905 : /* Y */
906 72320 : v_multc( Chnl_RealBuffer[0], hOMasa->chnlToFoaMtx[1][0], Foa_RealBuffer[1], num_freq_bins );
907 72320 : v_multc( Chnl_ImagBuffer[0], hOMasa->chnlToFoaMtx[1][0], Foa_ImagBuffer[1], num_freq_bins );
908 239296 : for ( i = 1; i < nchan_ism; i++ )
909 : {
910 166976 : v_multc_acc( Chnl_RealBuffer[i], hOMasa->chnlToFoaMtx[1][i], Foa_RealBuffer[1], num_freq_bins );
911 166976 : v_multc_acc( Chnl_ImagBuffer[i], hOMasa->chnlToFoaMtx[1][i], Foa_ImagBuffer[1], num_freq_bins );
912 : }
913 :
914 : /* Z */
915 72320 : v_multc( Chnl_RealBuffer[0], hOMasa->chnlToFoaMtx[2][0], Foa_RealBuffer[2], num_freq_bins );
916 72320 : v_multc( Chnl_ImagBuffer[0], hOMasa->chnlToFoaMtx[2][0], Foa_ImagBuffer[2], num_freq_bins );
917 239296 : for ( i = 1; i < nchan_ism; i++ )
918 : {
919 166976 : v_multc_acc( Chnl_RealBuffer[i], hOMasa->chnlToFoaMtx[2][i], Foa_RealBuffer[2], num_freq_bins );
920 166976 : v_multc_acc( Chnl_ImagBuffer[i], hOMasa->chnlToFoaMtx[2][i], Foa_ImagBuffer[2], num_freq_bins );
921 : }
922 :
923 : /* X */
924 72320 : v_multc( Chnl_RealBuffer[0], hOMasa->chnlToFoaMtx[3][0], Foa_RealBuffer[3], num_freq_bins );
925 72320 : v_multc( Chnl_ImagBuffer[0], hOMasa->chnlToFoaMtx[3][0], Foa_ImagBuffer[3], num_freq_bins );
926 239296 : for ( i = 1; i < nchan_ism; i++ )
927 : {
928 166976 : v_multc_acc( Chnl_RealBuffer[i], hOMasa->chnlToFoaMtx[3][i], Foa_RealBuffer[3], num_freq_bins );
929 166976 : v_multc_acc( Chnl_ImagBuffer[i], hOMasa->chnlToFoaMtx[3][i], Foa_ImagBuffer[3], num_freq_bins );
930 : }
931 :
932 : /* Direction estimation */
933 72320 : computeIntensityVector_enc( hOMasa->band_grouping, Foa_RealBuffer, Foa_ImagBuffer, num_freq_bands, intensity_real );
934 72320 : computeDirectionVectors( intensity_real[0], intensity_real[1], intensity_real[2], 0, num_freq_bands, direction_vector[0], direction_vector[1], direction_vector[2] );
935 :
936 : /* Power estimation for diffuseness */
937 72320 : computeReferencePower_omasa( hOMasa->band_grouping, Foa_RealBuffer, Foa_ImagBuffer, reference_power[ts], 0, num_freq_bands );
938 :
939 : /* Fill buffers of length "averaging_length" time slots for intensity and energy */
940 72320 : hOMasa->index_buffer_intensity = ( hOMasa->index_buffer_intensity % DIRAC_NO_COL_AVG_DIFF ) + 1; /* averaging_length = 32 */
941 72320 : index = hOMasa->index_buffer_intensity;
942 289280 : for ( i = 0; i < DIRAC_NUM_DIMS; i++ )
943 : {
944 : /* only real part needed */
945 216960 : mvr2r( intensity_real[i], &( hOMasa->buffer_intensity_real[i][index - 1][0] ), num_freq_bands );
946 : }
947 72320 : mvr2r( reference_power[ts], &( hOMasa->buffer_energy[( index - 1 ) * num_freq_bands] ), num_freq_bands );
948 :
949 72320 : computeDiffuseness( hOMasa->buffer_intensity_real, hOMasa->buffer_energy, num_freq_bands, diffuseness_vector );
950 :
951 1792416 : for ( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ )
952 : {
953 1720096 : norm_tmp = reference_power[ts][band_m_idx] * ( 1 - diffuseness_vector[band_m_idx] );
954 :
955 1720096 : hOMasa->direction_vector_m[0][block_m_idx][band_m_idx] += norm_tmp * direction_vector[0][band_m_idx];
956 1720096 : hOMasa->direction_vector_m[1][block_m_idx][band_m_idx] += norm_tmp * direction_vector[1][band_m_idx];
957 1720096 : hOMasa->direction_vector_m[2][block_m_idx][band_m_idx] += norm_tmp * direction_vector[2][band_m_idx];
958 :
959 1720096 : diffuseness_m[band_m_idx] += reference_power[ts][band_m_idx] * diffuseness_vector[band_m_idx];
960 1720096 : renormalization_factor_diff[band_m_idx] += reference_power[ts][band_m_idx];
961 : }
962 : }
963 :
964 396000 : for ( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ )
965 : {
966 1520064 : for ( d = 0; d < DIRAC_NUM_DIMS; d++ )
967 : {
968 1140048 : dir_v[d] = hOMasa->direction_vector_m[d][block_m_idx][band_m_idx];
969 : }
970 :
971 380016 : ivas_qmetadata_direction_vector_to_azimuth_elevation( dir_v, &azimuth_m_values[block_m_idx][band_m_idx], &elevation_m_values[block_m_idx][band_m_idx] );
972 : }
973 :
974 : /* Set coherences to zero, as this mode is used at lowest bit rates where the coherences are not transmitted */
975 396000 : for ( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ )
976 : {
977 380016 : spreadCoherence[block_m_idx][band_m_idx] = 0.0f;
978 380016 : surroundingCoherence[band_m_idx] = 0.0f;
979 : }
980 : }
981 :
982 : /* Determine energy ratios */
983 99000 : for ( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ )
984 : {
985 95004 : if ( renormalization_factor_diff[band_m_idx] > EPSILON )
986 : {
987 95004 : diffuseness_m[band_m_idx] /= renormalization_factor_diff[band_m_idx];
988 : }
989 : else
990 : {
991 0 : diffuseness_m[band_m_idx] = 0.0f;
992 : }
993 :
994 95004 : energyRatio[band_m_idx] = 1.0f - diffuseness_m[band_m_idx];
995 : }
996 :
997 3996 : return;
998 : }
999 :
1000 :
1001 : /* Estimate energies and ratios */
1002 1862 : static void ivas_omasa_energy_and_ratio_est(
1003 : OMASA_ENC_HANDLE hOMasa,
1004 : OMASA_ENCODER_DATA_HANDLE hOmasaData,
1005 : float *data_f[],
1006 : const int16_t input_frame,
1007 : const int16_t nchan_ism )
1008 : {
1009 : int16_t ts, i, j, k;
1010 : int16_t num_freq_bands;
1011 : int16_t l_ts;
1012 : float Chnl_RealBuffer[MAX_NUM_OBJECTS][CLDFB_NO_CHANNELS_MAX];
1013 : float Chnl_ImagBuffer[MAX_NUM_OBJECTS][CLDFB_NO_CHANNELS_MAX];
1014 : int16_t block_m_idx;
1015 : int16_t mrange[2], brange[2];
1016 : float tftile_energy;
1017 : float ism_ratio_sum;
1018 1862 : OMASA_ENCODER_ENERGY_HANDLE hOmasaEnergy = hOmasaData->hOmasaEnergy;
1019 :
1020 1862 : num_freq_bands = hOMasa->nbands;
1021 1862 : l_ts = input_frame / CLDFB_NO_COL_MAX;
1022 :
1023 : /* do processing over all CLDFB time slots */
1024 8176 : for ( block_m_idx = 0; block_m_idx < hOMasa->nSubframes; block_m_idx++ )
1025 : {
1026 6314 : mrange[0] = hOMasa->block_grouping[block_m_idx];
1027 6314 : mrange[1] = hOMasa->block_grouping[block_m_idx + 1];
1028 :
1029 : /* Reset variable */
1030 40530 : for ( i = 0; i < hOMasa->nbands; i++ )
1031 : {
1032 34216 : set_zero( hOmasaEnergy->energy_ratio_ism[block_m_idx][i], nchan_ism );
1033 : }
1034 6314 : set_zero( hOmasaEnergy->energy_ism[block_m_idx], num_freq_bands );
1035 :
1036 : /* Compute CLDFB */
1037 36106 : for ( ts = mrange[0]; ts < mrange[1]; ts++ )
1038 : {
1039 130272 : for ( i = 0; i < nchan_ism; i++ )
1040 : {
1041 100480 : cldfbAnalysis_ts( &( data_f[i][l_ts * ts] ), Chnl_RealBuffer[i], Chnl_ImagBuffer[i], l_ts, hOMasa->cldfbAnaEnc[i] );
1042 : }
1043 :
1044 : /* Compute energy */
1045 221088 : for ( i = 0; i < num_freq_bands; i++ )
1046 : {
1047 191296 : brange[0] = hOMasa->band_grouping[i];
1048 191296 : brange[1] = hOMasa->band_grouping[i + 1];
1049 1835456 : for ( j = brange[0]; j < brange[1]; j++ )
1050 : {
1051 7242880 : for ( k = 0; k < nchan_ism; k++ )
1052 : {
1053 5598720 : tftile_energy = Chnl_RealBuffer[k][j] * Chnl_RealBuffer[k][j] + Chnl_ImagBuffer[k][j] * Chnl_ImagBuffer[k][j];
1054 5598720 : hOmasaEnergy->energy_ism[block_m_idx][i] += tftile_energy;
1055 5598720 : hOmasaEnergy->energy_ratio_ism[block_m_idx][i][k] += tftile_energy;
1056 : }
1057 : }
1058 : }
1059 : }
1060 :
1061 : /* Compute ISM energy ratios */
1062 40530 : for ( i = 0; i < num_freq_bands; i++ )
1063 : {
1064 34216 : ism_ratio_sum = 0.0f;
1065 148936 : for ( j = 0; j < nchan_ism; j++ )
1066 : {
1067 114720 : hOmasaEnergy->energy_ratio_ism[block_m_idx][i][j] /= ( hOmasaEnergy->energy_ism[block_m_idx][i] + EPSILON );
1068 114720 : ism_ratio_sum += hOmasaEnergy->energy_ratio_ism[block_m_idx][i][j];
1069 : }
1070 :
1071 34216 : if ( ism_ratio_sum == 0.0f )
1072 : {
1073 0 : float temp_ism_ratio = 1.0f / ( (float) nchan_ism );
1074 0 : for ( j = 0; j < nchan_ism; j++ )
1075 : {
1076 0 : hOmasaEnergy->energy_ratio_ism[block_m_idx][i][j] = temp_ism_ratio;
1077 : }
1078 : }
1079 : }
1080 : }
1081 :
1082 1862 : return;
1083 : }
1084 :
1085 :
1086 : /* Compute downmix */
1087 5858 : static void ivas_omasa_dmx(
1088 : float *data_in_f[],
1089 : float data_out_f[][L_FRAME48k],
1090 : const int16_t input_frame,
1091 : const int16_t nchan_transport,
1092 : const int16_t nchan_ism,
1093 : ISM_METADATA_HANDLE hIsmMeta[],
1094 : float prev_gains[][MASA_MAX_TRANSPORT_CHANNELS],
1095 : const float interpolator[L_FRAME48k] )
1096 : {
1097 : int16_t i, j, k;
1098 : float azimuth, elevation;
1099 : float gains[MASA_MAX_TRANSPORT_CHANNELS];
1100 : float g1, g2;
1101 :
1102 17574 : for ( i = 0; i < nchan_transport; i++ )
1103 : {
1104 11716 : set_zero( data_out_f[i], input_frame );
1105 : }
1106 :
1107 25298 : for ( i = 0; i < nchan_ism; i++ )
1108 : {
1109 19440 : azimuth = hIsmMeta[i]->azimuth;
1110 19440 : elevation = hIsmMeta[i]->elevation;
1111 :
1112 19440 : ivas_get_stereo_panning_gains( azimuth, elevation, gains );
1113 :
1114 : /* Downmix using the panning gains */
1115 58320 : for ( j = 0; j < nchan_transport; j++ )
1116 : {
1117 38880 : if ( fabsf( gains[j] ) > 0.0 || fabsf( prev_gains[i][j] ) > 0.0f )
1118 : {
1119 32614184 : for ( k = 0; k < input_frame; k++ )
1120 : {
1121 32578560 : g1 = interpolator[k];
1122 32578560 : g2 = 1.0f - g1;
1123 32578560 : data_out_f[j][k] += ( g1 * gains[j] + g2 * prev_gains[i][j] ) * data_in_f[i][k];
1124 : }
1125 : }
1126 38880 : prev_gains[i][j] = gains[j];
1127 : }
1128 : }
1129 :
1130 5858 : return;
1131 : }
1132 :
1133 :
1134 72320 : static void computeIntensityVector_enc(
1135 : const int16_t *band_grouping,
1136 : float Cldfb_RealBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX],
1137 : float Cldfb_ImagBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX],
1138 : const int16_t num_frequency_bands,
1139 : float intensity_real[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS] )
1140 : {
1141 : /* Reminder
1142 : * X = a + ib; Y = c + id
1143 : * X*Y = ac - bd + i(ad +bc)
1144 : */
1145 : int16_t i, j;
1146 : float real, img;
1147 : int16_t brange[2];
1148 :
1149 1792416 : for ( i = 0; i < num_frequency_bands; i++ )
1150 : {
1151 1720096 : brange[0] = band_grouping[i];
1152 1720096 : brange[1] = band_grouping[i + 1];
1153 :
1154 1720096 : intensity_real[0][i] = 0;
1155 1720096 : intensity_real[1][i] = 0;
1156 1720096 : intensity_real[2][i] = 0;
1157 :
1158 5843616 : for ( j = brange[0]; j < brange[1]; j++ )
1159 : {
1160 4123520 : real = Cldfb_RealBuffer[0][j];
1161 4123520 : img = Cldfb_ImagBuffer[0][j];
1162 4123520 : intensity_real[0][i] += Cldfb_RealBuffer[3][j] * real + Cldfb_ImagBuffer[3][j] * img; /* Intensity is XYZ order, audio is WYZX order. */
1163 4123520 : intensity_real[1][i] += Cldfb_RealBuffer[1][j] * real + Cldfb_ImagBuffer[1][j] * img;
1164 4123520 : intensity_real[2][i] += Cldfb_RealBuffer[2][j] * real + Cldfb_ImagBuffer[2][j] * img;
1165 : }
1166 : }
1167 :
1168 72320 : return;
1169 : }
1170 :
1171 :
1172 72320 : static void computeReferencePower_omasa(
1173 : const int16_t *band_grouping, /* i : Band grouping for estimation */
1174 : float Cldfb_RealBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i : Real part of input signal */
1175 : float Cldfb_ImagBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i : Imag part of input signal */
1176 : float *reference_power, /* o : Estimated power */
1177 : const int16_t enc_param_start_band, /* i : first band to process */
1178 : const int16_t num_freq_bands /* i : Number of frequency bands */
1179 : )
1180 : {
1181 : int16_t brange[2];
1182 : int16_t ch_idx, i, j;
1183 :
1184 1792416 : for ( i = 0; i < num_freq_bands; i++ )
1185 : {
1186 1720096 : brange[0] = band_grouping[i + enc_param_start_band];
1187 1720096 : brange[1] = band_grouping[i + enc_param_start_band + 1];
1188 1720096 : reference_power[i] = 0;
1189 :
1190 8600480 : for ( ch_idx = 0; ch_idx < FOA_CHANNELS; ch_idx++ )
1191 : {
1192 : /* abs()^2 */
1193 23374464 : for ( j = brange[0]; j < brange[1]; j++ )
1194 : {
1195 16494080 : reference_power[i] += ( Cldfb_RealBuffer[ch_idx][j] * Cldfb_RealBuffer[ch_idx][j] ) + ( Cldfb_ImagBuffer[ch_idx][j] * Cldfb_ImagBuffer[ch_idx][j] );
1196 : }
1197 : }
1198 : }
1199 :
1200 72320 : v_multc( reference_power, 0.5f, reference_power, num_freq_bands );
1201 :
1202 72320 : return;
1203 : }
|