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 36 : 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 36 : error = IVAS_ERR_OK;
76 :
77 36 : 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 36 : numAnalysisChannels = (int16_t) total_num_objects;
83 :
84 : /* Determine the number of bands */
85 36 : hOMasa->nbands = MASA_FREQUENCY_BANDS;
86 :
87 : /* Determine band grouping */
88 36 : mvs2s( MASA_band_grouping_24, hOMasa->band_grouping, 24 + 1 );
89 :
90 36 : maxBin = (int16_t) ( input_Fs * INV_CLDFB_BANDWIDTH + 0.5f );
91 864 : for ( i = 1; i < hOMasa->nbands + 1; i++ )
92 : {
93 864 : if ( hOMasa->band_grouping[i] >= maxBin )
94 : {
95 36 : hOMasa->band_grouping[i] = maxBin;
96 36 : hOMasa->nbands = i;
97 36 : break;
98 : }
99 : }
100 :
101 : /* Determine block grouping */
102 36 : mvs2s( DirAC_block_grouping, hOMasa->block_grouping, MAX_PARAM_SPATIAL_SUBFRAMES + 1 );
103 :
104 : /* open/initialize CLDFB */
105 36 : hOMasa->num_Cldfb_instances = numAnalysisChannels;
106 132 : for ( i = 0; i < hOMasa->num_Cldfb_instances; i++ )
107 : {
108 96 : 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 84 : for ( ; i < MAX_NUM_OBJECTS; i++ )
115 : {
116 48 : hOMasa->cldfbAnaEnc[i] = NULL;
117 : }
118 :
119 : /* intensity 3-dim */
120 144 : for ( i = 0; i < DIRAC_NUM_DIMS; i++ )
121 : {
122 108 : 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 540 : for ( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ )
128 : {
129 432 : 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 432 : set_zero( hOMasa->direction_vector_m[i][j], MASA_FREQUENCY_BANDS );
134 : }
135 : }
136 :
137 144 : for ( i = 0; i < DIRAC_NUM_DIMS; i++ )
138 : {
139 3564 : for ( j = 0; j < DIRAC_NO_COL_AVG_DIFF; j++ )
140 : {
141 3456 : 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 3456 : set_zero( hOMasa->buffer_intensity_real[i][j], MASA_FREQUENCY_BANDS );
146 : }
147 : }
148 :
149 36 : set_zero( hOMasa->buffer_energy, DIRAC_NO_COL_AVG_DIFF * MASA_FREQUENCY_BANDS );
150 :
151 180 : for ( i = 0; i < MAX_NUM_OBJECTS; i++ )
152 : {
153 144 : set_f( hOMasa->prev_object_dm_gains[i], INV_SQRT_2, MASA_MAX_TRANSPORT_CHANNELS );
154 : }
155 :
156 36 : input_frame = (int16_t) ( input_Fs / FRAMES_PER_SEC );
157 34596 : for ( i = 0; i < input_frame; i++ )
158 : {
159 34560 : hOMasa->interpolator[i] = ( (float) i ) / ( (float) input_frame );
160 : }
161 :
162 36 : hOMasa->index_buffer_intensity = 0;
163 :
164 36 : 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 36 : 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 36 : generate_gridEq( hOMasa->sph_grid16 );
174 :
175 180 : for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ )
176 : {
177 144 : set_zero( hOMasa->energy[i], MASA_FREQUENCY_BANDS );
178 : }
179 :
180 36 : set_zero( hOMasa->ism_azimuth, MAX_NUM_OBJECTS );
181 36 : set_zero( hOMasa->ism_elevation, MAX_NUM_OBJECTS );
182 :
183 36 : ( *hOMasaPtr ) = hOMasa;
184 :
185 36 : return error;
186 : }
187 :
188 :
189 : /*--------------------------------------------------------------------------*
190 : * ivas_omasa_ana_close()
191 : *
192 : * Close OMASA handle
193 : *--------------------------------------------------------------------------*/
194 :
195 33528 : void ivas_omasa_ana_close(
196 : OMASA_ANA_HANDLE *hOMasa /* i/o: analysis OMASA handle */
197 : )
198 : {
199 : int16_t i, j;
200 :
201 33528 : if ( hOMasa == NULL || *hOMasa == NULL )
202 : {
203 33492 : return;
204 : }
205 :
206 132 : for ( i = 0; i < ( *hOMasa )->num_Cldfb_instances; i++ )
207 : {
208 96 : deleteCldfb( &( ( *hOMasa )->cldfbAnaEnc[i] ) );
209 : }
210 :
211 144 : for ( i = 0; i < DIRAC_NUM_DIMS; i++ )
212 : {
213 540 : for ( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ )
214 : {
215 432 : free( ( *hOMasa )->direction_vector_m[i][j] );
216 432 : ( *hOMasa )->direction_vector_m[i][j] = NULL;
217 : }
218 :
219 3564 : for ( j = 0; j < DIRAC_NO_COL_AVG_DIFF; j++ )
220 : {
221 3456 : free( ( *hOMasa )->buffer_intensity_real[i][j] );
222 3456 : ( *hOMasa )->buffer_intensity_real[i][j] = NULL;
223 : }
224 :
225 108 : free( ( *hOMasa )->direction_vector_m[i] );
226 108 : ( *hOMasa )->direction_vector_m[i] = NULL;
227 : }
228 :
229 36 : free( ( *hOMasa )->hMasaOut );
230 36 : ( *hOMasa )->hMasaOut = NULL;
231 36 : free( ( *hOMasa )->sph_grid16 );
232 36 : ( *hOMasa )->sph_grid16 = NULL;
233 :
234 36 : free( ( *hOMasa ) );
235 36 : ( *hOMasa ) = NULL;
236 :
237 36 : return;
238 : }
239 :
240 :
241 : /*--------------------------------------------------------------------------*
242 : * ivas_omasa_ana()
243 : *
244 : * OMASA analysis function
245 : *--------------------------------------------------------------------------*/
246 :
247 7836 : 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 7836 : ivas_omasa_param_est_ana( hOMasa, data_in_f, elevation_m_values, azimuth_m_values, energyRatio, spreadCoherence, surroundingCoherence, input_frame, nchan_ism );
263 :
264 : /* Create MASA metadata buffer from the estimated values */
265 7836 : ivas_create_masa_out_meta( hOMasa->hMasaOut, hOMasa->sph_grid16, nchan_transport, elevation_m_values, azimuth_m_values, energyRatio, spreadCoherence, surroundingCoherence );
266 :
267 : /* Downmix */
268 7836 : 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 );
269 :
270 7836 : return;
271 : }
272 :
273 :
274 : /*--------------------------------------------------------------------------*
275 : * Local functions
276 : *--------------------------------------------------------------------------*/
277 :
278 : /* Estimate MASA parameters from the objects */
279 7836 : static void ivas_omasa_param_est_ana(
280 : OMASA_ANA_HANDLE hOMasa,
281 : float data_f[][L_FRAME48k],
282 : float elevation_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS],
283 : float azimuth_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS],
284 : float energyRatio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS],
285 : float spreadCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS],
286 : float surroundingCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS],
287 : const int16_t input_frame,
288 : const int16_t nchan_ism )
289 : {
290 : float reference_power[MASA_FREQUENCY_BANDS];
291 : int16_t ts, i, d, j;
292 : int16_t num_freq_bins, num_freq_bands, index;
293 : float dir_v[DIRAC_NUM_DIMS];
294 : int16_t l_ts;
295 : float Chnl_RealBuffer[MAX_NUM_OBJECTS][CLDFB_NO_CHANNELS_MAX];
296 : float Chnl_ImagBuffer[MAX_NUM_OBJECTS][CLDFB_NO_CHANNELS_MAX];
297 : float Foa_RealBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX];
298 : float Foa_ImagBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX];
299 : float intensity_real[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS];
300 : float direction_vector[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS];
301 : float diffuseness_vector[MASA_FREQUENCY_BANDS];
302 : float diffuseness_m[MASA_FREQUENCY_BANDS];
303 :
304 : int16_t band_m_idx, block_m_idx;
305 : float renormalization_factor_diff[MASA_FREQUENCY_BANDS];
306 : float norm_tmp;
307 : int16_t mrange[2];
308 : int16_t brange[2];
309 :
310 7836 : num_freq_bins = hOMasa->cldfbAnaEnc[0]->no_channels;
311 7836 : num_freq_bands = hOMasa->nbands;
312 7836 : l_ts = input_frame / CLDFB_NO_COL_MAX;
313 :
314 :
315 : /* Compute ISM to FOA matrices */
316 28332 : for ( i = 0; i < nchan_ism; i++ )
317 : {
318 20496 : hOMasa->chnlToFoaMtx[0][i] = 1.0f;
319 20496 : hOMasa->chnlToFoaMtx[1][i] = sinf( ( hOMasa->ism_azimuth[i] / 180.0f * EVS_PI ) ) * cosf( ( hOMasa->ism_elevation[i] / 180.0f * EVS_PI ) );
320 20496 : hOMasa->chnlToFoaMtx[2][i] = sinf( ( hOMasa->ism_elevation[i] / 180.0f * EVS_PI ) );
321 20496 : hOMasa->chnlToFoaMtx[3][i] = cosf( ( hOMasa->ism_azimuth[i] / 180.0f * EVS_PI ) ) * cosf( ( hOMasa->ism_elevation[i] / 180.0f * EVS_PI ) );
322 : }
323 :
324 : /* do processing over all CLDFB time slots */
325 39180 : for ( block_m_idx = 0; block_m_idx < MAX_PARAM_SPATIAL_SUBFRAMES; block_m_idx++ )
326 : {
327 31344 : mrange[0] = hOMasa->block_grouping[block_m_idx];
328 31344 : mrange[1] = hOMasa->block_grouping[block_m_idx + 1];
329 :
330 783600 : for ( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ )
331 : {
332 752256 : hOMasa->direction_vector_m[0][block_m_idx][band_m_idx] = 0.0f;
333 752256 : hOMasa->direction_vector_m[1][block_m_idx][band_m_idx] = 0.0f;
334 752256 : hOMasa->direction_vector_m[2][block_m_idx][band_m_idx] = 0.0f;
335 : }
336 :
337 : /* Need to initialize renormalization_factors, and variables to be normalized */
338 31344 : set_zero( renormalization_factor_diff, hOMasa->nbands );
339 31344 : set_zero( diffuseness_m, hOMasa->nbands );
340 31344 : set_zero( hOMasa->energy[block_m_idx], MASA_FREQUENCY_BANDS );
341 :
342 156720 : for ( ts = mrange[0]; ts < mrange[1]; ts++ )
343 : {
344 453312 : for ( i = 0; i < nchan_ism; i++ )
345 : {
346 327936 : cldfbAnalysis_ts( &( data_f[i][l_ts * ts] ), Chnl_RealBuffer[i], Chnl_ImagBuffer[i], l_ts, hOMasa->cldfbAnaEnc[i] );
347 : }
348 :
349 : /* Compute channel-based energy for metadata processing */
350 3134400 : for ( band_m_idx = 0; band_m_idx < num_freq_bands; band_m_idx++ )
351 : {
352 3009024 : brange[0] = hOMasa->band_grouping[band_m_idx];
353 3009024 : brange[1] = hOMasa->band_grouping[band_m_idx + 1];
354 10531584 : for ( j = brange[0]; j < brange[1]; j++ )
355 : {
356 27198720 : for ( i = 0; i < nchan_ism; i++ )
357 : {
358 19676160 : hOMasa->energy[block_m_idx][band_m_idx] += Chnl_RealBuffer[i][j] * Chnl_RealBuffer[i][j] + Chnl_ImagBuffer[i][j] * Chnl_ImagBuffer[i][j];
359 : }
360 : }
361 : }
362 :
363 : /* Compute FOA */
364 : /* W */
365 125376 : mvr2r( Chnl_RealBuffer[0], Foa_RealBuffer[0], num_freq_bins );
366 125376 : mvr2r( Chnl_ImagBuffer[0], Foa_ImagBuffer[0], num_freq_bins );
367 327936 : for ( i = 1; i < nchan_ism; i++ )
368 : {
369 202560 : v_add( Chnl_RealBuffer[i], Foa_RealBuffer[0], Foa_RealBuffer[0], num_freq_bins );
370 202560 : v_add( Chnl_ImagBuffer[i], Foa_ImagBuffer[0], Foa_ImagBuffer[0], num_freq_bins );
371 : }
372 :
373 : /* Y */
374 125376 : v_multc( Chnl_RealBuffer[0], hOMasa->chnlToFoaMtx[1][0], Foa_RealBuffer[1], num_freq_bins );
375 125376 : v_multc( Chnl_ImagBuffer[0], hOMasa->chnlToFoaMtx[1][0], Foa_ImagBuffer[1], num_freq_bins );
376 327936 : for ( i = 1; i < nchan_ism; i++ )
377 : {
378 202560 : v_multc_acc( Chnl_RealBuffer[i], hOMasa->chnlToFoaMtx[1][i], Foa_RealBuffer[1], num_freq_bins );
379 202560 : v_multc_acc( Chnl_ImagBuffer[i], hOMasa->chnlToFoaMtx[1][i], Foa_ImagBuffer[1], num_freq_bins );
380 : }
381 :
382 : /* Z */
383 125376 : v_multc( Chnl_RealBuffer[0], hOMasa->chnlToFoaMtx[2][0], Foa_RealBuffer[2], num_freq_bins );
384 125376 : v_multc( Chnl_ImagBuffer[0], hOMasa->chnlToFoaMtx[2][0], Foa_ImagBuffer[2], num_freq_bins );
385 327936 : for ( i = 1; i < nchan_ism; i++ )
386 : {
387 202560 : v_multc_acc( Chnl_RealBuffer[i], hOMasa->chnlToFoaMtx[2][i], Foa_RealBuffer[2], num_freq_bins );
388 202560 : v_multc_acc( Chnl_ImagBuffer[i], hOMasa->chnlToFoaMtx[2][i], Foa_ImagBuffer[2], num_freq_bins );
389 : }
390 :
391 : /* X */
392 125376 : v_multc( Chnl_RealBuffer[0], hOMasa->chnlToFoaMtx[3][0], Foa_RealBuffer[3], num_freq_bins );
393 125376 : v_multc( Chnl_ImagBuffer[0], hOMasa->chnlToFoaMtx[3][0], Foa_ImagBuffer[3], num_freq_bins );
394 327936 : for ( i = 1; i < nchan_ism; i++ )
395 : {
396 202560 : v_multc_acc( Chnl_RealBuffer[i], hOMasa->chnlToFoaMtx[3][i], Foa_RealBuffer[3], num_freq_bins );
397 202560 : v_multc_acc( Chnl_ImagBuffer[i], hOMasa->chnlToFoaMtx[3][i], Foa_ImagBuffer[3], num_freq_bins );
398 : }
399 :
400 : /* Direction estimation */
401 125376 : computeIntensityVector_ana( hOMasa->band_grouping, Foa_RealBuffer, Foa_ImagBuffer, num_freq_bands, intensity_real );
402 125376 : computeDirectionVectors( intensity_real[0], intensity_real[1], intensity_real[2], 0, num_freq_bands, direction_vector[0], direction_vector[1], direction_vector[2] );
403 :
404 : /* Power estimation for diffuseness */
405 125376 : computeReferencePower_ana( hOMasa->band_grouping, Foa_RealBuffer, Foa_ImagBuffer, reference_power, num_freq_bands );
406 :
407 : /* Fill buffers of length "averaging_length" time slots for intensity and energy */
408 125376 : hOMasa->index_buffer_intensity = ( hOMasa->index_buffer_intensity % DIRAC_NO_COL_AVG_DIFF ) + 1; /* averaging_length = 32 */
409 125376 : index = hOMasa->index_buffer_intensity;
410 501504 : for ( i = 0; i < DIRAC_NUM_DIMS; i++ )
411 : {
412 : /* only real part needed */
413 376128 : mvr2r( intensity_real[i], &( hOMasa->buffer_intensity_real[i][index - 1][0] ), num_freq_bands );
414 : }
415 125376 : mvr2r( reference_power, &( hOMasa->buffer_energy[( index - 1 ) * num_freq_bands] ), num_freq_bands );
416 :
417 125376 : computeDiffuseness( hOMasa->buffer_intensity_real, hOMasa->buffer_energy, num_freq_bands, diffuseness_vector );
418 :
419 3134400 : for ( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ )
420 : {
421 3009024 : norm_tmp = reference_power[band_m_idx] * ( 1 - diffuseness_vector[band_m_idx] );
422 :
423 3009024 : hOMasa->direction_vector_m[0][block_m_idx][band_m_idx] += norm_tmp * direction_vector[0][band_m_idx];
424 3009024 : hOMasa->direction_vector_m[1][block_m_idx][band_m_idx] += norm_tmp * direction_vector[1][band_m_idx];
425 3009024 : hOMasa->direction_vector_m[2][block_m_idx][band_m_idx] += norm_tmp * direction_vector[2][band_m_idx];
426 :
427 3009024 : diffuseness_m[band_m_idx] += reference_power[band_m_idx] * diffuseness_vector[band_m_idx];
428 3009024 : renormalization_factor_diff[band_m_idx] += reference_power[band_m_idx];
429 : }
430 : }
431 :
432 783600 : for ( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ )
433 : {
434 3009024 : for ( d = 0; d < DIRAC_NUM_DIMS; d++ )
435 : {
436 2256768 : dir_v[d] = hOMasa->direction_vector_m[d][block_m_idx][band_m_idx];
437 : }
438 752256 : 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] );
439 : }
440 :
441 : /* Determine energy ratios */
442 783600 : for ( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ )
443 : {
444 752256 : if ( renormalization_factor_diff[band_m_idx] > EPSILON )
445 : {
446 751392 : diffuseness_m[band_m_idx] /= renormalization_factor_diff[band_m_idx];
447 : }
448 : else
449 : {
450 864 : diffuseness_m[band_m_idx] = 0.0f;
451 : }
452 :
453 752256 : energyRatio[block_m_idx][band_m_idx] = 1.0f - diffuseness_m[band_m_idx];
454 : }
455 :
456 : /* Set coherences to zero, as this mode is used at lowest bit rates where the coherences are not transmitted */
457 783600 : for ( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ )
458 : {
459 752256 : spreadCoherence[block_m_idx][band_m_idx] = 0.0f;
460 752256 : surroundingCoherence[block_m_idx][band_m_idx] = 0.0f;
461 : }
462 : }
463 :
464 7836 : return;
465 : }
466 :
467 :
468 : /* Compute downmix */
469 7836 : static void ivas_omasa_dmx(
470 : float data_in_f[][L_FRAME48k],
471 : const int16_t input_frame,
472 : const int16_t nchan_transport,
473 : const int16_t nchan_ism,
474 : const float ism_azimuth[MAX_NUM_OBJECTS],
475 : const float ism_elevation[MAX_NUM_OBJECTS],
476 : float prev_gains[][MASA_MAX_TRANSPORT_CHANNELS],
477 : const float interpolator[L_FRAME48k] )
478 : {
479 : int16_t i, j, k;
480 : float azimuth, elevation;
481 : float gains[MASA_MAX_TRANSPORT_CHANNELS];
482 : float g1, g2;
483 : float data_out_f[MASA_MAX_TRANSPORT_CHANNELS][L_FRAME48k];
484 :
485 19590 : for ( i = 0; i < nchan_transport; i++ )
486 : {
487 11754 : set_zero( data_out_f[i], input_frame );
488 : }
489 :
490 28332 : for ( i = 0; i < nchan_ism; i++ )
491 : {
492 20496 : if ( nchan_transport == 1 )
493 : {
494 10248 : v_add( data_out_f[0], data_in_f[i], data_out_f[0], input_frame );
495 : }
496 : else
497 : {
498 10248 : azimuth = ism_azimuth[i];
499 10248 : elevation = ism_elevation[i];
500 :
501 10248 : ivas_ism_get_stereo_gains( azimuth, elevation, &gains[0], &gains[1] );
502 :
503 : /* Downmix using the panning gains */
504 30744 : for ( j = 0; j < nchan_transport; j++ )
505 : {
506 20496 : if ( fabsf( gains[j] ) > 0.0 || fabsf( prev_gains[i][j] ) > 0.0f )
507 : {
508 17298000 : for ( k = 0; k < input_frame; k++ )
509 : {
510 17280000 : g1 = interpolator[k];
511 17280000 : g2 = 1.0f - g1;
512 17280000 : data_out_f[j][k] += ( g1 * gains[j] + g2 * prev_gains[i][j] ) * data_in_f[i][k];
513 : }
514 : }
515 20496 : prev_gains[i][j] = gains[j];
516 : }
517 : }
518 : }
519 :
520 19590 : for ( i = 0; i < nchan_transport; i++ )
521 : {
522 11754 : mvr2r( data_out_f[i], data_in_f[i], input_frame );
523 : }
524 :
525 7836 : return;
526 : }
527 :
528 :
529 : /*--------------------------------------------------------------------------*
530 : * computeIntensityVector_ana()
531 : *
532 : *
533 : *--------------------------------------------------------------------------*/
534 :
535 154368 : void computeIntensityVector_ana(
536 : const int16_t *band_grouping, /* i : Band grouping for estimation */
537 : float Cldfb_RealBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i : Real part of input signal */
538 : float Cldfb_ImagBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i : Imag part of input signal */
539 : const int16_t num_frequency_bands, /* i : Number of frequency bands */
540 : float intensity_real[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS] /* o : Intensity vector */
541 : )
542 : {
543 : /* Reminder
544 : * X = a + ib; Y = c + id
545 : * X*Y = ac - bd + i(ad +bc)
546 : */
547 : int16_t i, j;
548 : float real, img;
549 : int16_t brange[2];
550 :
551 3859200 : for ( i = 0; i < num_frequency_bands; i++ )
552 : {
553 3704832 : brange[0] = band_grouping[i];
554 3704832 : brange[1] = band_grouping[i + 1];
555 :
556 3704832 : intensity_real[0][i] = 0;
557 3704832 : intensity_real[1][i] = 0;
558 3704832 : intensity_real[2][i] = 0;
559 :
560 12966912 : for ( j = brange[0]; j < brange[1]; j++ )
561 : {
562 9262080 : real = Cldfb_RealBuffer[0][j];
563 9262080 : img = Cldfb_ImagBuffer[0][j];
564 9262080 : intensity_real[0][i] += Cldfb_RealBuffer[3][j] * real + Cldfb_ImagBuffer[3][j] * img; /* Intensity is XYZ order, audio is WYZX order. */
565 9262080 : intensity_real[1][i] += Cldfb_RealBuffer[1][j] * real + Cldfb_ImagBuffer[1][j] * img;
566 9262080 : intensity_real[2][i] += Cldfb_RealBuffer[2][j] * real + Cldfb_ImagBuffer[2][j] * img;
567 : }
568 : }
569 :
570 154368 : return;
571 : }
572 :
573 :
574 : /*--------------------------------------------------------------------------*
575 : * computeReferencePower_ana()
576 : *
577 : *
578 : *--------------------------------------------------------------------------*/
579 :
580 144704 : void computeReferencePower_ana(
581 : const int16_t *band_grouping, /* i : Band grouping for estimation */
582 : float Cldfb_RealBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i : Real part of input signal */
583 : float Cldfb_ImagBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i : Imag part of input signal */
584 : float *reference_power, /* o : Estimated power */
585 : const int16_t num_freq_bands /* i : Number of frequency bands */
586 : )
587 : {
588 : int16_t brange[2];
589 : int16_t ch_idx, i, j;
590 :
591 3617600 : for ( i = 0; i < num_freq_bands; i++ )
592 : {
593 3472896 : brange[0] = band_grouping[i];
594 3472896 : brange[1] = band_grouping[i + 1];
595 3472896 : reference_power[i] = 0;
596 :
597 17364480 : for ( ch_idx = 0; ch_idx < FOA_CHANNELS; ch_idx++ )
598 : {
599 : /* abs()^2 */
600 48620544 : for ( j = brange[0]; j < brange[1]; j++ )
601 : {
602 34728960 : reference_power[i] += ( Cldfb_RealBuffer[ch_idx][j] * Cldfb_RealBuffer[ch_idx][j] ) + ( Cldfb_ImagBuffer[ch_idx][j] * Cldfb_ImagBuffer[ch_idx][j] );
603 : }
604 : }
605 : }
606 :
607 144704 : v_multc( reference_power, 0.5f, reference_power, num_freq_bands );
608 :
609 144704 : return;
610 : }
|