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 2 : 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 2 : error = IVAS_ERR_OK;
76 :
77 2 : 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 2 : numAnalysisChannels = (int16_t) total_num_objects;
83 :
84 : /* Determine the number of bands */
85 2 : hOMasa->nbands = MASA_FREQUENCY_BANDS;
86 :
87 : /* Determine band grouping */
88 2 : mvs2s( MASA_band_grouping_24, hOMasa->band_grouping, 24 + 1 );
89 :
90 2 : maxBin = (int16_t) ( input_Fs * INV_CLDFB_BANDWIDTH + 0.5f );
91 48 : for ( i = 1; i < hOMasa->nbands + 1; i++ )
92 : {
93 48 : if ( hOMasa->band_grouping[i] >= maxBin )
94 : {
95 2 : hOMasa->band_grouping[i] = maxBin;
96 2 : hOMasa->nbands = i;
97 2 : break;
98 : }
99 : }
100 :
101 : /* Determine block grouping */
102 2 : mvs2s( DirAC_block_grouping, hOMasa->block_grouping, MAX_PARAM_SPATIAL_SUBFRAMES + 1 );
103 :
104 : /* open/initialize CLDFB */
105 2 : hOMasa->num_Cldfb_instances = numAnalysisChannels;
106 10 : for ( i = 0; i < hOMasa->num_Cldfb_instances; i++ )
107 : {
108 8 : 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 2 : for ( ; i < MAX_NUM_OBJECTS; i++ )
115 : {
116 0 : hOMasa->cldfbAnaEnc[i] = NULL;
117 : }
118 :
119 : /* intensity 3-dim */
120 8 : for ( i = 0; i < DIRAC_NUM_DIMS; i++ )
121 : {
122 6 : 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 30 : for ( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ )
128 : {
129 24 : 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 24 : set_zero( hOMasa->direction_vector_m[i][j], MASA_FREQUENCY_BANDS );
134 : }
135 : }
136 :
137 8 : for ( i = 0; i < DIRAC_NUM_DIMS; i++ )
138 : {
139 198 : for ( j = 0; j < DIRAC_NO_COL_AVG_DIFF; j++ )
140 : {
141 192 : 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 192 : set_zero( hOMasa->buffer_intensity_real[i][j], MASA_FREQUENCY_BANDS );
146 : }
147 : }
148 :
149 2 : set_zero( hOMasa->buffer_energy, DIRAC_NO_COL_AVG_DIFF * MASA_FREQUENCY_BANDS );
150 :
151 10 : for ( i = 0; i < MAX_NUM_OBJECTS; i++ )
152 : {
153 8 : set_f( hOMasa->prev_object_dm_gains[i], INV_SQRT_2, MASA_MAX_TRANSPORT_CHANNELS );
154 : }
155 :
156 2 : input_frame = (int16_t) ( input_Fs / FRAMES_PER_SEC );
157 1922 : for ( i = 0; i < input_frame; i++ )
158 : {
159 1920 : hOMasa->interpolator[i] = ( (float) i ) / ( (float) input_frame );
160 : }
161 :
162 2 : hOMasa->index_buffer_intensity = 0;
163 :
164 2 : 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 2 : 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 2 : generate_gridEq( hOMasa->sph_grid16 );
174 :
175 10 : for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ )
176 : {
177 8 : set_zero( hOMasa->energy[i], MASA_FREQUENCY_BANDS );
178 : }
179 :
180 2 : set_zero( hOMasa->ism_azimuth, MAX_NUM_OBJECTS );
181 2 : set_zero( hOMasa->ism_elevation, MAX_NUM_OBJECTS );
182 :
183 2 : ( *hOMasaPtr ) = hOMasa;
184 :
185 2 : return error;
186 : }
187 :
188 :
189 : /*--------------------------------------------------------------------------*
190 : * ivas_omasa_ana_close()
191 : *
192 : * Close OMASA handle
193 : *--------------------------------------------------------------------------*/
194 :
195 5264 : void ivas_omasa_ana_close(
196 : OMASA_ANA_HANDLE *hOMasa /* i/o: analysis OMASA handle */
197 : )
198 : {
199 : int16_t i, j;
200 :
201 5264 : if ( hOMasa == NULL || *hOMasa == NULL )
202 : {
203 5262 : return;
204 : }
205 :
206 10 : for ( i = 0; i < ( *hOMasa )->num_Cldfb_instances; i++ )
207 : {
208 8 : deleteCldfb( &( ( *hOMasa )->cldfbAnaEnc[i] ) );
209 : }
210 :
211 8 : for ( i = 0; i < DIRAC_NUM_DIMS; i++ )
212 : {
213 30 : for ( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ )
214 : {
215 24 : free( ( *hOMasa )->direction_vector_m[i][j] );
216 24 : ( *hOMasa )->direction_vector_m[i][j] = NULL;
217 : }
218 :
219 198 : for ( j = 0; j < DIRAC_NO_COL_AVG_DIFF; j++ )
220 : {
221 192 : free( ( *hOMasa )->buffer_intensity_real[i][j] );
222 192 : ( *hOMasa )->buffer_intensity_real[i][j] = NULL;
223 : }
224 :
225 6 : free( ( *hOMasa )->direction_vector_m[i] );
226 6 : ( *hOMasa )->direction_vector_m[i] = NULL;
227 : }
228 :
229 2 : free( ( *hOMasa )->hMasaOut );
230 2 : ( *hOMasa )->hMasaOut = NULL;
231 2 : free( ( *hOMasa )->sph_grid16 );
232 2 : ( *hOMasa )->sph_grid16 = NULL;
233 :
234 2 : free( ( *hOMasa ) );
235 2 : ( *hOMasa ) = NULL;
236 :
237 2 : return;
238 : }
239 :
240 :
241 : /*--------------------------------------------------------------------------*
242 : * ivas_omasa_ana()
243 : *
244 : * OMASA analysis function
245 : *--------------------------------------------------------------------------*/
246 :
247 300 : 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 300 : 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 300 : 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 300 : 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 300 : return;
271 : }
272 :
273 :
274 : /*--------------------------------------------------------------------------*
275 : * Local functions
276 : *--------------------------------------------------------------------------*/
277 :
278 : /* Estimate MASA parameters from the objects */
279 300 : 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 300 : num_freq_bins = hOMasa->cldfbAnaEnc[0]->no_channels;
311 300 : num_freq_bands = hOMasa->nbands;
312 300 : l_ts = input_frame / CLDFB_NO_COL_MAX;
313 :
314 :
315 : /* Compute ISM to FOA matrices */
316 1500 : for ( i = 0; i < nchan_ism; i++ )
317 : {
318 1200 : hOMasa->chnlToFoaMtx[0][i] = 1.0f;
319 1200 : hOMasa->chnlToFoaMtx[1][i] = sinf( ( hOMasa->ism_azimuth[i] / 180.0f * EVS_PI ) ) * cosf( ( hOMasa->ism_elevation[i] / 180.0f * EVS_PI ) );
320 1200 : hOMasa->chnlToFoaMtx[2][i] = sinf( ( hOMasa->ism_elevation[i] / 180.0f * EVS_PI ) );
321 1200 : 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 1500 : for ( block_m_idx = 0; block_m_idx < MAX_PARAM_SPATIAL_SUBFRAMES; block_m_idx++ )
326 : {
327 1200 : mrange[0] = hOMasa->block_grouping[block_m_idx];
328 1200 : mrange[1] = hOMasa->block_grouping[block_m_idx + 1];
329 :
330 30000 : for ( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ )
331 : {
332 28800 : hOMasa->direction_vector_m[0][block_m_idx][band_m_idx] = 0.0f;
333 28800 : hOMasa->direction_vector_m[1][block_m_idx][band_m_idx] = 0.0f;
334 28800 : 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 1200 : set_zero( renormalization_factor_diff, hOMasa->nbands );
339 1200 : set_zero( diffuseness_m, hOMasa->nbands );
340 1200 : set_zero( hOMasa->energy[block_m_idx], MASA_FREQUENCY_BANDS );
341 :
342 6000 : for ( ts = mrange[0]; ts < mrange[1]; ts++ )
343 : {
344 24000 : for ( i = 0; i < nchan_ism; i++ )
345 : {
346 19200 : 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 120000 : for ( band_m_idx = 0; band_m_idx < num_freq_bands; band_m_idx++ )
351 : {
352 115200 : brange[0] = hOMasa->band_grouping[band_m_idx];
353 115200 : brange[1] = hOMasa->band_grouping[band_m_idx + 1];
354 403200 : for ( j = brange[0]; j < brange[1]; j++ )
355 : {
356 1440000 : for ( i = 0; i < nchan_ism; i++ )
357 : {
358 1152000 : 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 4800 : mvr2r( Chnl_RealBuffer[0], Foa_RealBuffer[0], num_freq_bins );
366 4800 : mvr2r( Chnl_ImagBuffer[0], Foa_ImagBuffer[0], num_freq_bins );
367 19200 : for ( i = 1; i < nchan_ism; i++ )
368 : {
369 14400 : v_add( Chnl_RealBuffer[i], Foa_RealBuffer[0], Foa_RealBuffer[0], num_freq_bins );
370 14400 : v_add( Chnl_ImagBuffer[i], Foa_ImagBuffer[0], Foa_ImagBuffer[0], num_freq_bins );
371 : }
372 :
373 : /* Y */
374 4800 : v_multc( Chnl_RealBuffer[0], hOMasa->chnlToFoaMtx[1][0], Foa_RealBuffer[1], num_freq_bins );
375 4800 : v_multc( Chnl_ImagBuffer[0], hOMasa->chnlToFoaMtx[1][0], Foa_ImagBuffer[1], num_freq_bins );
376 19200 : for ( i = 1; i < nchan_ism; i++ )
377 : {
378 14400 : v_multc_acc( Chnl_RealBuffer[i], hOMasa->chnlToFoaMtx[1][i], Foa_RealBuffer[1], num_freq_bins );
379 14400 : v_multc_acc( Chnl_ImagBuffer[i], hOMasa->chnlToFoaMtx[1][i], Foa_ImagBuffer[1], num_freq_bins );
380 : }
381 :
382 : /* Z */
383 4800 : v_multc( Chnl_RealBuffer[0], hOMasa->chnlToFoaMtx[2][0], Foa_RealBuffer[2], num_freq_bins );
384 4800 : v_multc( Chnl_ImagBuffer[0], hOMasa->chnlToFoaMtx[2][0], Foa_ImagBuffer[2], num_freq_bins );
385 19200 : for ( i = 1; i < nchan_ism; i++ )
386 : {
387 14400 : v_multc_acc( Chnl_RealBuffer[i], hOMasa->chnlToFoaMtx[2][i], Foa_RealBuffer[2], num_freq_bins );
388 14400 : v_multc_acc( Chnl_ImagBuffer[i], hOMasa->chnlToFoaMtx[2][i], Foa_ImagBuffer[2], num_freq_bins );
389 : }
390 :
391 : /* X */
392 4800 : v_multc( Chnl_RealBuffer[0], hOMasa->chnlToFoaMtx[3][0], Foa_RealBuffer[3], num_freq_bins );
393 4800 : v_multc( Chnl_ImagBuffer[0], hOMasa->chnlToFoaMtx[3][0], Foa_ImagBuffer[3], num_freq_bins );
394 19200 : for ( i = 1; i < nchan_ism; i++ )
395 : {
396 14400 : v_multc_acc( Chnl_RealBuffer[i], hOMasa->chnlToFoaMtx[3][i], Foa_RealBuffer[3], num_freq_bins );
397 14400 : v_multc_acc( Chnl_ImagBuffer[i], hOMasa->chnlToFoaMtx[3][i], Foa_ImagBuffer[3], num_freq_bins );
398 : }
399 :
400 : /* Direction estimation */
401 4800 : computeIntensityVector_ana( hOMasa->band_grouping, Foa_RealBuffer, Foa_ImagBuffer, num_freq_bands, intensity_real );
402 4800 : 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 4800 : 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 4800 : hOMasa->index_buffer_intensity = ( hOMasa->index_buffer_intensity % DIRAC_NO_COL_AVG_DIFF ) + 1; /* averaging_length = 32 */
409 4800 : index = hOMasa->index_buffer_intensity;
410 19200 : for ( i = 0; i < DIRAC_NUM_DIMS; i++ )
411 : {
412 : /* only real part needed */
413 14400 : mvr2r( intensity_real[i], &( hOMasa->buffer_intensity_real[i][index - 1][0] ), num_freq_bands );
414 : }
415 4800 : mvr2r( reference_power, &( hOMasa->buffer_energy[( index - 1 ) * num_freq_bands] ), num_freq_bands );
416 :
417 4800 : computeDiffuseness( hOMasa->buffer_intensity_real, hOMasa->buffer_energy, num_freq_bands, diffuseness_vector );
418 :
419 120000 : for ( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ )
420 : {
421 115200 : norm_tmp = reference_power[band_m_idx] * ( 1 - diffuseness_vector[band_m_idx] );
422 :
423 115200 : hOMasa->direction_vector_m[0][block_m_idx][band_m_idx] += norm_tmp * direction_vector[0][band_m_idx];
424 115200 : hOMasa->direction_vector_m[1][block_m_idx][band_m_idx] += norm_tmp * direction_vector[1][band_m_idx];
425 115200 : hOMasa->direction_vector_m[2][block_m_idx][band_m_idx] += norm_tmp * direction_vector[2][band_m_idx];
426 :
427 115200 : diffuseness_m[band_m_idx] += reference_power[band_m_idx] * diffuseness_vector[band_m_idx];
428 115200 : renormalization_factor_diff[band_m_idx] += reference_power[band_m_idx];
429 : }
430 : }
431 :
432 30000 : for ( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ )
433 : {
434 115200 : for ( d = 0; d < DIRAC_NUM_DIMS; d++ )
435 : {
436 86400 : dir_v[d] = hOMasa->direction_vector_m[d][block_m_idx][band_m_idx];
437 : }
438 28800 : 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 30000 : for ( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ )
443 : {
444 28800 : if ( renormalization_factor_diff[band_m_idx] > EPSILON )
445 : {
446 28800 : diffuseness_m[band_m_idx] /= renormalization_factor_diff[band_m_idx];
447 : }
448 : else
449 : {
450 0 : diffuseness_m[band_m_idx] = 0.0f;
451 : }
452 :
453 28800 : 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 30000 : for ( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ )
458 : {
459 28800 : spreadCoherence[block_m_idx][band_m_idx] = 0.0f;
460 28800 : surroundingCoherence[block_m_idx][band_m_idx] = 0.0f;
461 : }
462 : }
463 :
464 300 : return;
465 : }
466 :
467 :
468 : /* Compute downmix */
469 300 : 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 :
486 900 : for ( i = 0; i < nchan_transport; i++ )
487 : {
488 600 : set_zero( data_out_f[i], input_frame );
489 : }
490 :
491 1500 : for ( i = 0; i < nchan_ism; i++ )
492 : {
493 1200 : azimuth = ism_azimuth[i];
494 1200 : elevation = ism_elevation[i];
495 :
496 1200 : ivas_ism_get_stereo_gains( azimuth, elevation, &gains[0], &gains[1] );
497 :
498 : /* Downmix using the panning gains */
499 3600 : for ( j = 0; j < nchan_transport; j++ )
500 : {
501 2400 : if ( fabsf( gains[j] ) > 0.0 || fabsf( prev_gains[i][j] ) > 0.0f )
502 : {
503 2121888 : for ( k = 0; k < input_frame; k++ )
504 : {
505 2119680 : g1 = interpolator[k];
506 2119680 : g2 = 1.0f - g1;
507 2119680 : data_out_f[j][k] += ( g1 * gains[j] + g2 * prev_gains[i][j] ) * data_in_f[i][k];
508 : }
509 : }
510 2400 : prev_gains[i][j] = gains[j];
511 : }
512 : }
513 :
514 900 : for ( i = 0; i < nchan_transport; i++ )
515 : {
516 600 : mvr2r( data_out_f[i], data_in_f[i], input_frame );
517 : }
518 :
519 300 : return;
520 : }
521 :
522 :
523 : /*--------------------------------------------------------------------------*
524 : * computeIntensityVector_ana()
525 : *
526 : *
527 : *--------------------------------------------------------------------------*/
528 :
529 19200 : void computeIntensityVector_ana(
530 : const int16_t *band_grouping, /* i : Band grouping for estimation */
531 : float Cldfb_RealBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i : Real part of input signal */
532 : float Cldfb_ImagBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i : Imag part of input signal */
533 : const int16_t num_frequency_bands, /* i : Number of frequency bands */
534 : float intensity_real[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS] /* o : Intensity vector */
535 : )
536 : {
537 : /* Reminder
538 : * X = a + ib; Y = c + id
539 : * X*Y = ac - bd + i(ad +bc)
540 : */
541 : int16_t i, j;
542 : float real, img;
543 : int16_t brange[2];
544 :
545 480000 : for ( i = 0; i < num_frequency_bands; i++ )
546 : {
547 460800 : brange[0] = band_grouping[i];
548 460800 : brange[1] = band_grouping[i + 1];
549 :
550 460800 : intensity_real[0][i] = 0;
551 460800 : intensity_real[1][i] = 0;
552 460800 : intensity_real[2][i] = 0;
553 :
554 1612800 : for ( j = brange[0]; j < brange[1]; j++ )
555 : {
556 1152000 : real = Cldfb_RealBuffer[0][j];
557 1152000 : img = Cldfb_ImagBuffer[0][j];
558 1152000 : intensity_real[0][i] += Cldfb_RealBuffer[3][j] * real + Cldfb_ImagBuffer[3][j] * img; /* Intensity is XYZ order, audio is WYZX order. */
559 1152000 : intensity_real[1][i] += Cldfb_RealBuffer[1][j] * real + Cldfb_ImagBuffer[1][j] * img;
560 1152000 : intensity_real[2][i] += Cldfb_RealBuffer[2][j] * real + Cldfb_ImagBuffer[2][j] * img;
561 : }
562 : }
563 :
564 19200 : return;
565 : }
566 :
567 :
568 : /*--------------------------------------------------------------------------*
569 : * computeReferencePower_ana()
570 : *
571 : *
572 : *--------------------------------------------------------------------------*/
573 :
574 14400 : void computeReferencePower_ana(
575 : const int16_t *band_grouping, /* i : Band grouping for estimation */
576 : float Cldfb_RealBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i : Real part of input signal */
577 : float Cldfb_ImagBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i : Imag part of input signal */
578 : float *reference_power, /* o : Estimated power */
579 : const int16_t num_freq_bands /* i : Number of frequency bands */
580 : )
581 : {
582 : int16_t brange[2];
583 : int16_t ch_idx, i, j;
584 :
585 360000 : for ( i = 0; i < num_freq_bands; i++ )
586 : {
587 345600 : brange[0] = band_grouping[i];
588 345600 : brange[1] = band_grouping[i + 1];
589 345600 : reference_power[i] = 0;
590 :
591 1728000 : for ( ch_idx = 0; ch_idx < FOA_CHANNELS; ch_idx++ )
592 : {
593 : /* abs()^2 */
594 4838400 : for ( j = brange[0]; j < brange[1]; j++ )
595 : {
596 3456000 : reference_power[i] += ( Cldfb_RealBuffer[ch_idx][j] * Cldfb_RealBuffer[ch_idx][j] ) + ( Cldfb_ImagBuffer[ch_idx][j] * Cldfb_ImagBuffer[ch_idx][j] );
597 : }
598 : }
599 : }
600 :
601 14400 : v_multc( reference_power, 0.5f, reference_power, num_freq_bands );
602 :
603 14400 : return;
604 : }
|