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 <math.h>
36 : #include "ivas_cnst.h"
37 : #include "ivas_prot_rend.h"
38 : #include "ivas_prot.h"
39 : #include "prot.h"
40 : #include "ivas_stat_rend.h"
41 : #include "ivas_rom_com.h"
42 : #ifdef DEBUGGING
43 : #include "debug.h"
44 : #endif
45 : #include "wmc_auto.h"
46 :
47 :
48 : /*-------------------------------------------------------------------------
49 : * Local function prototypes
50 : *------------------------------------------------------------------------*/
51 :
52 : static void ivas_omasa_param_est_ana( OMASA_ANA_HANDLE hOMasa, float data_f[][L_FRAME48k], float elevation_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], float azimuth_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], float energyRatio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], float spreadCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], float surroundingCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], const int16_t input_frame, const int16_t nchan_ism );
53 :
54 : static void ivas_omasa_dmx( float data_in_f[][L_FRAME48k], const int16_t input_frame, const int16_t nchan_transport, const int16_t nchan_ism, const float ism_azimuth[MAX_NUM_OBJECTS], const float ism_elevation[MAX_NUM_OBJECTS], float prev_gains[][MASA_MAX_TRANSPORT_CHANNELS], const float interpolator[L_FRAME48k] );
55 :
56 :
57 : /*--------------------------------------------------------------------------*
58 : * ivas_omasa_ana_open()
59 : *
60 : * Allocate and initialize OMASA handle
61 : *--------------------------------------------------------------------------*/
62 :
63 163 : ivas_error ivas_omasa_ana_open(
64 : OMASA_ANA_HANDLE *hOMasaPtr, /* i/o: OMASA data handle pointer */
65 : int32_t input_Fs, /* i : Sampling frequency */
66 : uint16_t total_num_objects /* i : Number of objects */
67 : )
68 : {
69 : int16_t i, j;
70 : OMASA_ANA_HANDLE hOMasa;
71 : int16_t numAnalysisChannels;
72 : int16_t maxBin, input_frame;
73 : ivas_error error;
74 :
75 163 : error = IVAS_ERR_OK;
76 :
77 163 : if ( ( hOMasa = (OMASA_ANA_HANDLE) malloc( sizeof( OMASA_ANA_DATA ) ) ) == NULL )
78 : {
79 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for OMASA\n" ) );
80 : }
81 :
82 163 : numAnalysisChannels = (int16_t) total_num_objects;
83 :
84 : /* Determine the number of bands */
85 163 : hOMasa->nbands = MASA_FREQUENCY_BANDS;
86 :
87 : /* Determine band grouping */
88 163 : mvs2s( MASA_band_grouping_24, hOMasa->band_grouping, 24 + 1 );
89 :
90 163 : maxBin = (int16_t) ( input_Fs * INV_CLDFB_BANDWIDTH + 0.5f );
91 3642 : for ( i = 1; i < hOMasa->nbands + 1; i++ )
92 : {
93 3642 : if ( hOMasa->band_grouping[i] >= maxBin )
94 : {
95 163 : hOMasa->band_grouping[i] = maxBin;
96 163 : hOMasa->nbands = i;
97 163 : break;
98 : }
99 : }
100 :
101 : /* Determine block grouping */
102 163 : mvs2s( DirAC_block_grouping, hOMasa->block_grouping, MAX_PARAM_SPATIAL_SUBFRAMES + 1 );
103 :
104 : /* open/initialize CLDFB */
105 163 : hOMasa->num_Cldfb_instances = numAnalysisChannels;
106 599 : for ( i = 0; i < hOMasa->num_Cldfb_instances; i++ )
107 : {
108 436 : if ( ( error = openCldfb( &( hOMasa->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK )
109 : {
110 0 : return error;
111 : }
112 : }
113 :
114 379 : for ( ; i < MAX_NUM_OBJECTS; i++ )
115 : {
116 216 : hOMasa->cldfbAnaEnc[i] = NULL;
117 : }
118 :
119 : /* intensity 3-dim */
120 652 : for ( i = 0; i < DIRAC_NUM_DIMS; i++ )
121 : {
122 489 : if ( ( hOMasa->direction_vector_m[i] = (float **) malloc( MAX_PARAM_SPATIAL_SUBFRAMES * sizeof( float * ) ) ) == NULL )
123 : {
124 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for OMASA data\n" ) );
125 : }
126 :
127 2445 : for ( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ )
128 : {
129 1956 : if ( ( hOMasa->direction_vector_m[i][j] = (float *) malloc( MASA_FREQUENCY_BANDS * sizeof( float ) ) ) == NULL )
130 : {
131 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for OMASA data\n" ) );
132 : }
133 1956 : set_zero( hOMasa->direction_vector_m[i][j], MASA_FREQUENCY_BANDS );
134 : }
135 : }
136 :
137 652 : for ( i = 0; i < DIRAC_NUM_DIMS; i++ )
138 : {
139 16137 : for ( j = 0; j < DIRAC_NO_COL_AVG_DIFF; j++ )
140 : {
141 15648 : if ( ( hOMasa->buffer_intensity_real[i][j] = (float *) malloc( MASA_FREQUENCY_BANDS * sizeof( float ) ) ) == NULL )
142 : {
143 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for OMASA data\n" ) );
144 : }
145 15648 : set_zero( hOMasa->buffer_intensity_real[i][j], MASA_FREQUENCY_BANDS );
146 : }
147 : }
148 :
149 163 : set_zero( hOMasa->buffer_energy, DIRAC_NO_COL_AVG_DIFF * MASA_FREQUENCY_BANDS );
150 :
151 815 : for ( i = 0; i < MAX_NUM_OBJECTS; i++ )
152 : {
153 652 : set_f( hOMasa->prev_object_dm_gains[i], INV_SQRT_2, MASA_MAX_TRANSPORT_CHANNELS );
154 : }
155 :
156 163 : input_frame = (int16_t) ( input_Fs / FRAMES_PER_SEC );
157 104803 : for ( i = 0; i < input_frame; i++ )
158 : {
159 104640 : hOMasa->interpolator[i] = ( (float) i ) / ( (float) input_frame );
160 : }
161 :
162 163 : hOMasa->index_buffer_intensity = 0;
163 :
164 163 : if ( ( hOMasa->hMasaOut = (MASA_DECODER_EXT_OUT_META_HANDLE) malloc( sizeof( MASA_DECODER_EXT_OUT_META ) ) ) == NULL )
165 : {
166 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MASA decoder\n" ) );
167 : }
168 :
169 163 : if ( ( hOMasa->sph_grid16 = (SPHERICAL_GRID_DATA *) malloc( sizeof( SPHERICAL_GRID_DATA ) ) ) == NULL )
170 : {
171 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MASA decoder\n" ) );
172 : }
173 163 : generate_gridEq( hOMasa->sph_grid16 );
174 :
175 815 : for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ )
176 : {
177 652 : set_zero( hOMasa->energy[i], MASA_FREQUENCY_BANDS );
178 : }
179 :
180 163 : set_zero( hOMasa->ism_azimuth, MAX_NUM_OBJECTS );
181 163 : set_zero( hOMasa->ism_elevation, MAX_NUM_OBJECTS );
182 :
183 163 : ( *hOMasaPtr ) = hOMasa;
184 :
185 163 : return error;
186 : }
187 :
188 :
189 : /*--------------------------------------------------------------------------*
190 : * ivas_omasa_ana_close()
191 : *
192 : * Close OMASA handle
193 : *--------------------------------------------------------------------------*/
194 :
195 56716 : void ivas_omasa_ana_close(
196 : OMASA_ANA_HANDLE *hOMasa /* i/o: analysis OMASA handle */
197 : )
198 : {
199 : int16_t i, j;
200 :
201 56716 : if ( hOMasa == NULL || *hOMasa == NULL )
202 : {
203 56553 : return;
204 : }
205 :
206 599 : for ( i = 0; i < ( *hOMasa )->num_Cldfb_instances; i++ )
207 : {
208 436 : deleteCldfb( &( ( *hOMasa )->cldfbAnaEnc[i] ) );
209 : }
210 :
211 652 : for ( i = 0; i < DIRAC_NUM_DIMS; i++ )
212 : {
213 2445 : for ( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ )
214 : {
215 1956 : free( ( *hOMasa )->direction_vector_m[i][j] );
216 1956 : ( *hOMasa )->direction_vector_m[i][j] = NULL;
217 : }
218 :
219 16137 : for ( j = 0; j < DIRAC_NO_COL_AVG_DIFF; j++ )
220 : {
221 15648 : free( ( *hOMasa )->buffer_intensity_real[i][j] );
222 15648 : ( *hOMasa )->buffer_intensity_real[i][j] = NULL;
223 : }
224 :
225 489 : free( ( *hOMasa )->direction_vector_m[i] );
226 489 : ( *hOMasa )->direction_vector_m[i] = NULL;
227 : }
228 :
229 163 : free( ( *hOMasa )->hMasaOut );
230 163 : ( *hOMasa )->hMasaOut = NULL;
231 163 : free( ( *hOMasa )->sph_grid16 );
232 163 : ( *hOMasa )->sph_grid16 = NULL;
233 :
234 163 : free( ( *hOMasa ) );
235 163 : ( *hOMasa ) = NULL;
236 :
237 163 : return;
238 : }
239 :
240 :
241 : /*--------------------------------------------------------------------------*
242 : * ivas_omasa_ana()
243 : *
244 : * OMASA analysis function
245 : *--------------------------------------------------------------------------*/
246 :
247 304693 : void ivas_omasa_ana(
248 : OMASA_ANA_HANDLE hOMasa, /* i/o: OMASA analysis handle */
249 : float data_in_f[][L_FRAME48k], /* i/o: Input / transport audio signals */
250 : const int16_t input_frame, /* i : Input frame size */
251 : const int16_t nchan_transport, /* i : Number of transport channels */
252 : const int16_t nchan_ism /* i : Number of objects for parameter analysis */
253 : )
254 : {
255 : float elevation_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
256 : float azimuth_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
257 : float energyRatio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
258 : float spreadCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
259 : float surroundingCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
260 :
261 : /* Estimate MASA parameters from the objects */
262 304693 : ivas_omasa_param_est_ana( hOMasa, data_in_f, elevation_m_values, azimuth_m_values, energyRatio, spreadCoherence, surroundingCoherence, input_frame, nchan_ism );
263 :
264 : /* Add zeros to higher bands in case of lower sampling rates */
265 304693 : if ( hOMasa->nbands < MASA_FREQUENCY_BANDS )
266 : {
267 203028 : ivas_masa_zero_high_bands( hOMasa->nbands, elevation_m_values, azimuth_m_values, energyRatio, spreadCoherence, surroundingCoherence );
268 : }
269 :
270 : /* Create MASA metadata buffer from the estimated values */
271 304693 : ivas_create_masa_out_meta( hOMasa->hMasaOut, hOMasa->sph_grid16, nchan_transport, elevation_m_values, azimuth_m_values, energyRatio, spreadCoherence, surroundingCoherence );
272 :
273 : /* Downmix */
274 304693 : ivas_omasa_dmx( data_in_f, input_frame, nchan_transport, nchan_ism, hOMasa->ism_azimuth, hOMasa->ism_elevation, hOMasa->prev_object_dm_gains, hOMasa->interpolator );
275 :
276 304693 : return;
277 : }
278 :
279 :
280 : /*--------------------------------------------------------------------------*
281 : * Local functions
282 : *--------------------------------------------------------------------------*/
283 :
284 : /* Estimate MASA parameters from the objects */
285 304693 : static void ivas_omasa_param_est_ana(
286 : OMASA_ANA_HANDLE hOMasa,
287 : float data_f[][L_FRAME48k],
288 : float elevation_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS],
289 : float azimuth_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS],
290 : float energyRatio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS],
291 : float spreadCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS],
292 : float surroundingCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS],
293 : const int16_t input_frame,
294 : const int16_t nchan_ism )
295 : {
296 : float reference_power[MASA_FREQUENCY_BANDS];
297 : int16_t ts, i, d, j;
298 : int16_t num_freq_bins, num_freq_bands, index;
299 : float dir_v[DIRAC_NUM_DIMS];
300 : int16_t l_ts;
301 : float Chnl_RealBuffer[MAX_NUM_OBJECTS][CLDFB_NO_CHANNELS_MAX];
302 : float Chnl_ImagBuffer[MAX_NUM_OBJECTS][CLDFB_NO_CHANNELS_MAX];
303 : float Foa_RealBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX];
304 : float Foa_ImagBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX];
305 : float intensity_real[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS];
306 : float direction_vector[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS];
307 : float diffuseness_vector[MASA_FREQUENCY_BANDS];
308 : float diffuseness_m[MASA_FREQUENCY_BANDS];
309 :
310 : int16_t band_m_idx, block_m_idx;
311 : float renormalization_factor_diff[MASA_FREQUENCY_BANDS];
312 : float norm_tmp;
313 : int16_t mrange[2];
314 : int16_t brange[2];
315 :
316 304693 : num_freq_bins = hOMasa->cldfbAnaEnc[0]->no_channels;
317 304693 : num_freq_bands = hOMasa->nbands;
318 304693 : l_ts = input_frame / CLDFB_NO_COL_MAX;
319 :
320 :
321 : /* Compute ISM to FOA matrices */
322 1070729 : for ( i = 0; i < nchan_ism; i++ )
323 : {
324 766036 : hOMasa->chnlToFoaMtx[0][i] = 1.0f;
325 766036 : hOMasa->chnlToFoaMtx[1][i] = sinf( ( hOMasa->ism_azimuth[i] / 180.0f * EVS_PI ) ) * cosf( ( hOMasa->ism_elevation[i] / 180.0f * EVS_PI ) );
326 766036 : hOMasa->chnlToFoaMtx[2][i] = sinf( ( hOMasa->ism_elevation[i] / 180.0f * EVS_PI ) );
327 766036 : hOMasa->chnlToFoaMtx[3][i] = cosf( ( hOMasa->ism_azimuth[i] / 180.0f * EVS_PI ) ) * cosf( ( hOMasa->ism_elevation[i] / 180.0f * EVS_PI ) );
328 : }
329 :
330 : /* do processing over all CLDFB time slots */
331 1523465 : for ( block_m_idx = 0; block_m_idx < MAX_PARAM_SPATIAL_SUBFRAMES; block_m_idx++ )
332 : {
333 1218772 : mrange[0] = hOMasa->block_grouping[block_m_idx];
334 1218772 : mrange[1] = hOMasa->block_grouping[block_m_idx + 1];
335 :
336 28439020 : for ( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ )
337 : {
338 27220248 : hOMasa->direction_vector_m[0][block_m_idx][band_m_idx] = 0.0f;
339 27220248 : hOMasa->direction_vector_m[1][block_m_idx][band_m_idx] = 0.0f;
340 27220248 : hOMasa->direction_vector_m[2][block_m_idx][band_m_idx] = 0.0f;
341 : }
342 :
343 : /* Need to initialize renormalization_factors, and variables to be normalized */
344 1218772 : set_zero( renormalization_factor_diff, hOMasa->nbands );
345 1218772 : set_zero( diffuseness_m, hOMasa->nbands );
346 1218772 : set_zero( hOMasa->energy[block_m_idx], MASA_FREQUENCY_BANDS );
347 :
348 6093860 : for ( ts = mrange[0]; ts < mrange[1]; ts++ )
349 : {
350 17131664 : for ( i = 0; i < nchan_ism; i++ )
351 : {
352 12256576 : cldfbAnalysis_ts( &( data_f[i][l_ts * ts] ), Chnl_RealBuffer[i], Chnl_ImagBuffer[i], l_ts, hOMasa->cldfbAnaEnc[i] );
353 : }
354 :
355 : /* Compute channel-based energy for metadata processing */
356 113756080 : for ( band_m_idx = 0; band_m_idx < num_freq_bands; band_m_idx++ )
357 : {
358 108880992 : brange[0] = hOMasa->band_grouping[band_m_idx];
359 108880992 : brange[1] = hOMasa->band_grouping[band_m_idx + 1];
360 303932832 : for ( j = brange[0]; j < brange[1]; j++ )
361 : {
362 685508160 : for ( i = 0; i < nchan_ism; i++ )
363 : {
364 490456320 : hOMasa->energy[block_m_idx][band_m_idx] += Chnl_RealBuffer[i][j] * Chnl_RealBuffer[i][j] + Chnl_ImagBuffer[i][j] * Chnl_ImagBuffer[i][j];
365 : }
366 : }
367 : }
368 :
369 : /* Compute FOA */
370 : /* W */
371 4875088 : mvr2r( Chnl_RealBuffer[0], Foa_RealBuffer[0], num_freq_bins );
372 4875088 : mvr2r( Chnl_ImagBuffer[0], Foa_ImagBuffer[0], num_freq_bins );
373 12256576 : for ( i = 1; i < nchan_ism; i++ )
374 : {
375 7381488 : v_add( Chnl_RealBuffer[i], Foa_RealBuffer[0], Foa_RealBuffer[0], num_freq_bins );
376 7381488 : v_add( Chnl_ImagBuffer[i], Foa_ImagBuffer[0], Foa_ImagBuffer[0], num_freq_bins );
377 : }
378 :
379 : /* Y */
380 4875088 : v_multc( Chnl_RealBuffer[0], hOMasa->chnlToFoaMtx[1][0], Foa_RealBuffer[1], num_freq_bins );
381 4875088 : v_multc( Chnl_ImagBuffer[0], hOMasa->chnlToFoaMtx[1][0], Foa_ImagBuffer[1], num_freq_bins );
382 12256576 : for ( i = 1; i < nchan_ism; i++ )
383 : {
384 7381488 : v_multc_acc( Chnl_RealBuffer[i], hOMasa->chnlToFoaMtx[1][i], Foa_RealBuffer[1], num_freq_bins );
385 7381488 : v_multc_acc( Chnl_ImagBuffer[i], hOMasa->chnlToFoaMtx[1][i], Foa_ImagBuffer[1], num_freq_bins );
386 : }
387 :
388 : /* Z */
389 4875088 : v_multc( Chnl_RealBuffer[0], hOMasa->chnlToFoaMtx[2][0], Foa_RealBuffer[2], num_freq_bins );
390 4875088 : v_multc( Chnl_ImagBuffer[0], hOMasa->chnlToFoaMtx[2][0], Foa_ImagBuffer[2], num_freq_bins );
391 12256576 : for ( i = 1; i < nchan_ism; i++ )
392 : {
393 7381488 : v_multc_acc( Chnl_RealBuffer[i], hOMasa->chnlToFoaMtx[2][i], Foa_RealBuffer[2], num_freq_bins );
394 7381488 : v_multc_acc( Chnl_ImagBuffer[i], hOMasa->chnlToFoaMtx[2][i], Foa_ImagBuffer[2], num_freq_bins );
395 : }
396 :
397 : /* X */
398 4875088 : v_multc( Chnl_RealBuffer[0], hOMasa->chnlToFoaMtx[3][0], Foa_RealBuffer[3], num_freq_bins );
399 4875088 : v_multc( Chnl_ImagBuffer[0], hOMasa->chnlToFoaMtx[3][0], Foa_ImagBuffer[3], num_freq_bins );
400 12256576 : for ( i = 1; i < nchan_ism; i++ )
401 : {
402 7381488 : v_multc_acc( Chnl_RealBuffer[i], hOMasa->chnlToFoaMtx[3][i], Foa_RealBuffer[3], num_freq_bins );
403 7381488 : v_multc_acc( Chnl_ImagBuffer[i], hOMasa->chnlToFoaMtx[3][i], Foa_ImagBuffer[3], num_freq_bins );
404 : }
405 :
406 : /* Direction estimation */
407 4875088 : computeIntensityVector_ana( hOMasa->band_grouping, Foa_RealBuffer, Foa_ImagBuffer, num_freq_bands, intensity_real );
408 4875088 : computeDirectionVectors( intensity_real[0], intensity_real[1], intensity_real[2], 0, num_freq_bands, direction_vector[0], direction_vector[1], direction_vector[2] );
409 :
410 : /* Power estimation for diffuseness */
411 4875088 : computeReferencePower_ana( hOMasa->band_grouping, Foa_RealBuffer, Foa_ImagBuffer, reference_power, num_freq_bands );
412 :
413 : /* Fill buffers of length "averaging_length" time slots for intensity and energy */
414 4875088 : hOMasa->index_buffer_intensity = ( hOMasa->index_buffer_intensity % DIRAC_NO_COL_AVG_DIFF ) + 1; /* averaging_length = 32 */
415 4875088 : index = hOMasa->index_buffer_intensity;
416 19500352 : for ( i = 0; i < DIRAC_NUM_DIMS; i++ )
417 : {
418 : /* only real part needed */
419 14625264 : mvr2r( intensity_real[i], &( hOMasa->buffer_intensity_real[i][index - 1][0] ), num_freq_bands );
420 : }
421 4875088 : mvr2r( reference_power, &( hOMasa->buffer_energy[( index - 1 ) * num_freq_bands] ), num_freq_bands );
422 :
423 4875088 : computeDiffuseness( hOMasa->buffer_intensity_real, hOMasa->buffer_energy, num_freq_bands, diffuseness_vector );
424 :
425 113756080 : for ( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ )
426 : {
427 108880992 : norm_tmp = reference_power[band_m_idx] * ( 1 - diffuseness_vector[band_m_idx] );
428 :
429 108880992 : hOMasa->direction_vector_m[0][block_m_idx][band_m_idx] += norm_tmp * direction_vector[0][band_m_idx];
430 108880992 : hOMasa->direction_vector_m[1][block_m_idx][band_m_idx] += norm_tmp * direction_vector[1][band_m_idx];
431 108880992 : hOMasa->direction_vector_m[2][block_m_idx][band_m_idx] += norm_tmp * direction_vector[2][band_m_idx];
432 :
433 108880992 : diffuseness_m[band_m_idx] += reference_power[band_m_idx] * diffuseness_vector[band_m_idx];
434 108880992 : renormalization_factor_diff[band_m_idx] += reference_power[band_m_idx];
435 : }
436 : }
437 :
438 28439020 : for ( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ )
439 : {
440 108880992 : for ( d = 0; d < DIRAC_NUM_DIMS; d++ )
441 : {
442 81660744 : dir_v[d] = hOMasa->direction_vector_m[d][block_m_idx][band_m_idx];
443 : }
444 27220248 : 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] );
445 : }
446 :
447 : /* Determine energy ratios */
448 28439020 : for ( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ )
449 : {
450 27220248 : if ( renormalization_factor_diff[band_m_idx] > EPSILON )
451 : {
452 23683962 : diffuseness_m[band_m_idx] /= renormalization_factor_diff[band_m_idx];
453 : }
454 : else
455 : {
456 3536286 : diffuseness_m[band_m_idx] = 0.0f;
457 : }
458 :
459 27220248 : energyRatio[block_m_idx][band_m_idx] = 1.0f - diffuseness_m[band_m_idx];
460 : }
461 :
462 : /* Set coherences to zero, as this mode is used at lowest bit rates where the coherences are not transmitted */
463 28439020 : for ( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ )
464 : {
465 27220248 : spreadCoherence[block_m_idx][band_m_idx] = 0.0f;
466 27220248 : surroundingCoherence[block_m_idx][band_m_idx] = 0.0f;
467 : }
468 : }
469 :
470 304693 : return;
471 : }
472 :
473 :
474 : /* Compute downmix */
475 304693 : static void ivas_omasa_dmx(
476 : float data_in_f[][L_FRAME48k],
477 : const int16_t input_frame,
478 : const int16_t nchan_transport,
479 : const int16_t nchan_ism,
480 : const float ism_azimuth[MAX_NUM_OBJECTS],
481 : const float ism_elevation[MAX_NUM_OBJECTS],
482 : float prev_gains[][MASA_MAX_TRANSPORT_CHANNELS],
483 : const float interpolator[L_FRAME48k] )
484 : {
485 : int16_t i, j, k;
486 : float azimuth, elevation;
487 : float gains[MASA_MAX_TRANSPORT_CHANNELS];
488 : float g1, g2;
489 : float data_out_f[MASA_MAX_TRANSPORT_CHANNELS][L_FRAME48k];
490 :
491 761808 : for ( i = 0; i < nchan_transport; i++ )
492 : {
493 457115 : set_zero( data_out_f[i], input_frame );
494 : }
495 :
496 1070729 : for ( i = 0; i < nchan_ism; i++ )
497 : {
498 766036 : if ( nchan_transport == 1 )
499 : {
500 382716 : v_add( data_out_f[0], data_in_f[i], data_out_f[0], input_frame );
501 : }
502 : else
503 : {
504 383320 : azimuth = ism_azimuth[i];
505 383320 : elevation = ism_elevation[i];
506 :
507 383320 : ivas_ism_get_stereo_gains( azimuth, elevation, &gains[0], &gains[1] );
508 :
509 : /* Downmix using the panning gains */
510 1149960 : for ( j = 0; j < nchan_transport; j++ )
511 : {
512 766640 : if ( fabsf( gains[j] ) > 0.0 || fabsf( prev_gains[i][j] ) > 0.0f )
513 : {
514 424197860 : for ( k = 0; k < input_frame; k++ )
515 : {
516 423536640 : g1 = interpolator[k];
517 423536640 : g2 = 1.0f - g1;
518 423536640 : data_out_f[j][k] += ( g1 * gains[j] + g2 * prev_gains[i][j] ) * data_in_f[i][k];
519 : }
520 : }
521 766640 : prev_gains[i][j] = gains[j];
522 : }
523 : }
524 : }
525 :
526 761808 : for ( i = 0; i < nchan_transport; i++ )
527 : {
528 457115 : mvr2r( data_out_f[i], data_in_f[i], input_frame );
529 : }
530 :
531 304693 : return;
532 : }
533 :
534 :
535 : /*--------------------------------------------------------------------------*
536 : * computeIntensityVector_ana()
537 : *
538 : *
539 : *--------------------------------------------------------------------------*/
540 :
541 5012800 : void computeIntensityVector_ana(
542 : const int16_t *band_grouping, /* i : Band grouping for estimation */
543 : float Cldfb_RealBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i : Real part of input signal */
544 : float Cldfb_ImagBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i : Imag part of input signal */
545 : const int16_t num_frequency_bands, /* i : Number of frequency bands */
546 : float intensity_real[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS] /* o : Intensity vector */
547 : )
548 : {
549 : /* Reminder
550 : * X = a + ib; Y = c + id
551 : * X*Y = ac - bd + i(ad +bc)
552 : */
553 : int16_t i, j;
554 : float real, img;
555 : int16_t brange[2];
556 :
557 116981440 : for ( i = 0; i < num_frequency_bands; i++ )
558 : {
559 111968640 : brange[0] = band_grouping[i];
560 111968640 : brange[1] = band_grouping[i + 1];
561 :
562 111968640 : intensity_real[0][i] = 0;
563 111968640 : intensity_real[1][i] = 0;
564 111968640 : intensity_real[2][i] = 0;
565 :
566 312673920 : for ( j = brange[0]; j < brange[1]; j++ )
567 : {
568 200705280 : real = Cldfb_RealBuffer[0][j];
569 200705280 : img = Cldfb_ImagBuffer[0][j];
570 200705280 : intensity_real[0][i] += Cldfb_RealBuffer[3][j] * real + Cldfb_ImagBuffer[3][j] * img; /* Intensity is XYZ order, audio is WYZX order. */
571 200705280 : intensity_real[1][i] += Cldfb_RealBuffer[1][j] * real + Cldfb_ImagBuffer[1][j] * img;
572 200705280 : intensity_real[2][i] += Cldfb_RealBuffer[2][j] * real + Cldfb_ImagBuffer[2][j] * img;
573 : }
574 : }
575 :
576 5012800 : return;
577 : }
578 :
579 :
580 : /*--------------------------------------------------------------------------*
581 : * computeReferencePower_ana()
582 : *
583 : *
584 : *--------------------------------------------------------------------------*/
585 :
586 4966896 : void computeReferencePower_ana(
587 : const int16_t *band_grouping, /* i : Band grouping for estimation */
588 : float Cldfb_RealBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i : Real part of input signal */
589 : float Cldfb_ImagBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i : Imag part of input signal */
590 : float *reference_power, /* o : Estimated power */
591 : const int16_t num_freq_bands /* i : Number of frequency bands */
592 : )
593 : {
594 : int16_t brange[2];
595 : int16_t ch_idx, i, j;
596 :
597 115906320 : for ( i = 0; i < num_freq_bands; i++ )
598 : {
599 110939424 : brange[0] = band_grouping[i];
600 110939424 : brange[1] = band_grouping[i + 1];
601 110939424 : reference_power[i] = 0;
602 :
603 554697120 : for ( ch_idx = 0; ch_idx < FOA_CHANNELS; ch_idx++ )
604 : {
605 : /* abs()^2 */
606 1239040896 : for ( j = brange[0]; j < brange[1]; j++ )
607 : {
608 795283200 : reference_power[i] += ( Cldfb_RealBuffer[ch_idx][j] * Cldfb_RealBuffer[ch_idx][j] ) + ( Cldfb_ImagBuffer[ch_idx][j] * Cldfb_ImagBuffer[ch_idx][j] );
609 : }
610 : }
611 : }
612 :
613 4966896 : v_multc( reference_power, 0.5f, reference_power, num_freq_bands );
614 :
615 4966896 : return;
616 : }
|