Line data Source code
1 : /******************************************************************************************************
2 :
3 : (C) 2022-2026 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 <assert.h>
34 : #include <math.h>
35 : #include <stdlib.h>
36 : #include <stdio.h>
37 : #include "ivas_cnst.h"
38 : #include "ivas_prot.h"
39 : #include "options.h"
40 : #include "prot.h"
41 : #include "ivas_rom_com.h"
42 : #include "ivas_rom_enc.h"
43 : #ifdef DEBUGGING
44 : #include "debug.h"
45 : #endif
46 : #include "wmc_auto.h"
47 :
48 :
49 : /*-------------------------------------------------------------------------
50 : * Local constants
51 : *------------------------------------------------------------------------*/
52 :
53 : #define NEAR_HORIZONTAL_PLANE_ELEVATION 17.5f
54 : #define VERTICAL_ENERGY_RATIO_OFFSET 0.15f
55 :
56 :
57 : /*-------------------------------------------------------------------------
58 : * Local function prototypes
59 : *------------------------------------------------------------------------*/
60 :
61 : /* Structure for covariance matrix */
62 : typedef struct
63 : {
64 : float xr[MCMASA_MAX_ANA_CHANS][MCMASA_MAX_ANA_CHANS];
65 : float xi[MCMASA_MAX_ANA_CHANS][MCMASA_MAX_ANA_CHANS];
66 : } CovarianceMatrix;
67 :
68 : static void ivas_mcmasa_dmx( MCMASA_ENC_HANDLE hMcMasa, float *data_f[], const int16_t input_frame, const int16_t nchan_transport, const int16_t nchan_inp );
69 :
70 : static void compute_cov_mtx( float sr[MCMASA_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX], float si[MCMASA_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX], const int16_t freq, const int16_t N, CovarianceMatrix *COVls );
71 :
72 : static void computeIntensityVector_enc( const int16_t *band_grouping, float Cldfb_RealBuffer[FOA_CHANNELS][DIRAC_NO_FB_BANDS_MAX], float Cldfb_ImagBuffer[FOA_CHANNELS][DIRAC_NO_FB_BANDS_MAX], const int16_t enc_param_start_band, const int16_t num_frequency_bands, float intensity_real[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS] );
73 :
74 : static void computeVerticalDiffuseness( float **buffer_intensity, const float *buffer_energy, const int16_t averaging_length, const int16_t num_freq_bands, float *diffuseness );
75 :
76 : static void computeEvenLayout( const float *ls_azimuth, float *ls_azimuth_even, const int16_t numChannels );
77 :
78 : static void computeLfeEnergy( MCMASA_ENC_HANDLE hMcMasa, float *data_f[], const int16_t input_frame );
79 :
80 :
81 : /*--------------------------------------------------------------------------*
82 : * ivas_mcmasa_enc_open()
83 : *
84 : *
85 : *--------------------------------------------------------------------------*/
86 :
87 7110 : ivas_error ivas_mcmasa_enc_open(
88 : Encoder_Struct *st_ivas /* i/o: IVAS encoder handle */
89 : )
90 : {
91 : int16_t i, j;
92 : float tmp_f;
93 : MCMASA_ENC_HANDLE hMcMasa;
94 : MASA_ENCODER_HANDLE hMasa;
95 : float ls_azimuth[MCMASA_MAX_ANA_CHANS];
96 : float ls_elevation[MCMASA_MAX_ANA_CHANS];
97 : float ls_azimuth_even[MCMASA_MAX_ANA_CHANS];
98 : int16_t numAnalysisChannels;
99 : float left_min, right_min, azi_diff;
100 : const int16_t *band_mapping;
101 : int16_t maxBin, input_frame;
102 : int16_t nchan_inp;
103 : int32_t input_Fs;
104 : int32_t dirac_slot_ns;
105 : IVAS_FB_CFG *fb_cfg, *fb_cfgLfe;
106 : ivas_error error;
107 :
108 7110 : error = IVAS_ERR_OK;
109 :
110 7110 : assert( st_ivas->hMasa != NULL && "MASA encoder handle is not present" );
111 7110 : hMasa = st_ivas->hMasa;
112 :
113 7110 : if ( ( hMcMasa = (MCMASA_ENC_HANDLE) malloc( sizeof( MCMASA_ENC_DATA ) ) ) == NULL )
114 : {
115 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for McMasa\n" ) );
116 : }
117 :
118 7110 : nchan_inp = st_ivas->hEncoderConfig->nchan_inp;
119 7110 : input_Fs = st_ivas->hEncoderConfig->input_Fs;
120 :
121 : /* Determine if to separate some channels from the analysis */
122 7110 : ivas_mcmasa_set_separate_channel_mode( &( hMcMasa->separateChannelEnabled ), &( hMcMasa->separateChannelIndex ), st_ivas->hEncoderConfig->ivas_total_brate );
123 :
124 7110 : numAnalysisChannels = nchan_inp - 1;
125 7110 : if ( hMcMasa->separateChannelEnabled )
126 : {
127 1535 : numAnalysisChannels = nchan_inp - 2;
128 : }
129 :
130 : /* With McMASA, we config MASA encoder only in init as we know the input and there are no frame-by-frame changes currently. */
131 7110 : if ( ( error = ivas_masa_enc_config( st_ivas ) ) != IVAS_ERR_OK )
132 : {
133 0 : return error;
134 : }
135 :
136 :
137 : /* Determine the number of bands */
138 7110 : hMcMasa->nbands = st_ivas->hMasa->config.numCodingBands;
139 7110 : hMcMasa->nCodingBands = st_ivas->hMasa->config.numCodingBands;
140 :
141 : /* Determine band grouping */
142 7110 : if ( hMcMasa->nbands == 24 )
143 : {
144 0 : for ( i = 0; i < hMcMasa->nbands + 1; i++ )
145 : {
146 0 : hMcMasa->band_grouping[i] = MASA_band_grouping_24[i] * CLDFB_TO_MDFT_FAC;
147 : }
148 : }
149 : else
150 : {
151 7110 : band_mapping = hMasa->data.band_mapping;
152 49770 : for ( i = 0; i < hMcMasa->nbands + 1; i++ )
153 : {
154 42660 : hMcMasa->band_grouping[i] = MASA_band_grouping_24[band_mapping[i]] * CLDFB_TO_MDFT_FAC;
155 : }
156 : }
157 :
158 7110 : maxBin = (int16_t) ( input_Fs * INV_CLDFB_BANDWIDTH * CLDFB_TO_MDFT_FAC + 0.5f );
159 :
160 35550 : for ( i = 1; i < hMcMasa->nbands + 1; i++ )
161 : {
162 35550 : if ( hMcMasa->band_grouping[i] >= maxBin )
163 : {
164 7110 : hMcMasa->band_grouping[i] = maxBin;
165 7110 : hMcMasa->nbands = i;
166 7110 : break;
167 : }
168 : }
169 :
170 : /* initialize delay compensation */
171 7110 : hMcMasa->num_samples_delay_comp = NS2SA( input_Fs, DELAY_DIRAC_ENC_CMP_NS );
172 7110 : tmp_f = (float) hMcMasa->num_samples_delay_comp / (float) ( NS2SA( input_Fs, DIRAC_SLOT_ENC_NS ) );
173 7110 : hMcMasa->num_slots_delay_comp = (int16_t) ( tmp_f );
174 :
175 7110 : if ( tmp_f > (float) hMcMasa->num_slots_delay_comp )
176 : {
177 7110 : hMcMasa->num_slots_delay_comp++;
178 7110 : hMcMasa->offset_comp = -hMcMasa->num_samples_delay_comp;
179 7110 : hMcMasa->num_samples_delay_comp = hMcMasa->num_slots_delay_comp * NS2SA( input_Fs, DIRAC_SLOT_ENC_NS );
180 7110 : hMcMasa->offset_comp += hMcMasa->num_samples_delay_comp;
181 : }
182 : else
183 : {
184 0 : hMcMasa->offset_comp = 0;
185 : }
186 :
187 : /* set FB config. */
188 7110 : if ( ( error = ivas_fb_set_cfg( &fb_cfg, MASA_FORMAT, numAnalysisChannels, 0, 0, input_Fs, 0 ) ) != IVAS_ERR_OK )
189 : {
190 0 : return error;
191 : }
192 :
193 : /* Allocate and initialize FB mixer handle */
194 7110 : if ( ( error = ivas_FB_mixer_open( &( hMcMasa->hFbMixer ), input_Fs, fb_cfg, 0 ) ) != IVAS_ERR_OK )
195 : {
196 0 : return error;
197 : }
198 :
199 :
200 7110 : if ( hMcMasa->separateChannelEnabled )
201 : {
202 : /* TD Energy calculation with LP */
203 1535 : if ( ( hMcMasa->delay_buffer_lfe[0] = (float *) malloc( NS2SA( input_Fs, DELAY_DIRAC_ENC_CMP_NS + DIRAC_SLOT_ENC_NS ) * sizeof( float ) ) ) == NULL )
204 : {
205 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for McMasa\n" ) );
206 : }
207 1535 : set_zero( hMcMasa->delay_buffer_lfe[0], NS2SA( input_Fs, DELAY_DIRAC_ENC_CMP_NS + DIRAC_SLOT_ENC_NS ) );
208 :
209 1535 : if ( ( hMcMasa->delay_buffer_lfe[1] = (float *) malloc( NS2SA( input_Fs, DELAY_DIRAC_ENC_CMP_NS + DIRAC_SLOT_ENC_NS ) * sizeof( float ) ) ) == NULL )
210 : {
211 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for McMasa\n" ) );
212 : }
213 1535 : set_zero( hMcMasa->delay_buffer_lfe[1], NS2SA( input_Fs, DELAY_DIRAC_ENC_CMP_NS + DIRAC_SLOT_ENC_NS ) );
214 1535 : hMcMasa->hFbMixerLfe = NULL;
215 : }
216 : else
217 : {
218 : /* Allocate and initialize FB mixer handle for LFE channel */
219 5575 : if ( ( error = ivas_fb_set_cfg( &fb_cfgLfe, MASA_FORMAT, 1, 0, 0, input_Fs, 0 ) ) != IVAS_ERR_OK )
220 : {
221 0 : return error;
222 : }
223 :
224 5575 : if ( ( error = ivas_FB_mixer_open( &( hMcMasa->hFbMixerLfe ), input_Fs, fb_cfgLfe, 0 ) ) != IVAS_ERR_OK )
225 : {
226 0 : return error;
227 : }
228 :
229 5575 : hMcMasa->delay_buffer_lfe[0] = NULL;
230 5575 : hMcMasa->delay_buffer_lfe[1] = NULL;
231 : }
232 :
233 7110 : if ( hMcMasa->separateChannelEnabled )
234 : {
235 : int16_t bufferSize;
236 :
237 : /* Ring buffer for the filterbank of the LFE analysis.
238 : * The filterbank is using moving average lowpass filter with the crossover of 120 Hz. */
239 1535 : bufferSize = (int16_t) ( ( input_Fs / FRAMES_PER_SEC ) / MAX_PARAM_SPATIAL_SUBFRAMES );
240 4605 : for ( i = 0; i < 2; i++ )
241 : {
242 3070 : if ( ( hMcMasa->lfeAnaRingBuffer[i] = (float *) malloc( bufferSize * sizeof( float ) ) ) == NULL )
243 : {
244 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for McMasa\n" ) );
245 : }
246 3070 : set_zero( hMcMasa->lfeAnaRingBuffer[i], bufferSize );
247 3070 : hMcMasa->lowpassSum[i] = 0.0f;
248 : }
249 1535 : hMcMasa->ringBufferPointer = 0;
250 1535 : hMcMasa->ringBufferSize = bufferSize;
251 : }
252 :
253 :
254 7110 : dirac_slot_ns = DIRAC_SLOT_ENC_NS;
255 :
256 : /* intensity 3-dim */
257 28440 : for ( i = 0; i < DIRAC_NUM_DIMS; i++ )
258 : {
259 21330 : if ( ( hMcMasa->direction_vector_m[i] = (float **) malloc( MAX_PARAM_SPATIAL_SUBFRAMES * sizeof( float * ) ) ) == NULL )
260 : {
261 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for McMasa\n" ) );
262 : }
263 :
264 106650 : for ( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ )
265 : {
266 85320 : if ( ( hMcMasa->direction_vector_m[i][j] = (float *) malloc( hMcMasa->nbands * sizeof( float ) ) ) == NULL )
267 : {
268 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for McMasa\n" ) );
269 : }
270 : }
271 : }
272 :
273 7110 : hMcMasa->no_col_avg_diff = (int8_t) ( DIRAC_NO_COL_AVG_DIFF_NS / dirac_slot_ns );
274 28440 : for ( i = 0; i < DIRAC_NUM_DIMS; i++ )
275 : {
276 21330 : if ( ( hMcMasa->buffer_intensity_real[i] = (float **) malloc( hMcMasa->no_col_avg_diff * sizeof( float * ) ) ) == NULL )
277 : {
278 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for McMasa\n" ) );
279 : }
280 :
281 191970 : for ( j = 0; j < hMcMasa->no_col_avg_diff; j++ )
282 : {
283 170640 : if ( ( hMcMasa->buffer_intensity_real[i][j] = (float *) malloc( hMcMasa->nbands * sizeof( float ) ) ) == NULL )
284 : {
285 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for McMasa\n" ) );
286 : }
287 170640 : set_zero( hMcMasa->buffer_intensity_real[i][j], hMcMasa->nbands );
288 : }
289 : }
290 :
291 7110 : if ( ( hMcMasa->buffer_intensity_real_vert = (float **) malloc( hMcMasa->no_col_avg_diff * sizeof( float * ) ) ) == NULL )
292 : {
293 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for McMasa\n" ) );
294 : }
295 :
296 63990 : for ( j = 0; j < hMcMasa->no_col_avg_diff; j++ )
297 : {
298 56880 : if ( ( hMcMasa->buffer_intensity_real_vert[j] = (float *) malloc( hMcMasa->nbands * sizeof( float ) ) ) == NULL )
299 : {
300 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for McMasa\n" ) );
301 : }
302 56880 : set_zero( hMcMasa->buffer_intensity_real_vert[j], hMcMasa->nbands );
303 : }
304 :
305 7110 : if ( ( hMcMasa->buffer_energy = (float *) malloc( hMcMasa->nbands * hMcMasa->no_col_avg_diff * sizeof( float ) ) ) == NULL )
306 : {
307 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for McMasa\n" ) );
308 : }
309 7110 : set_zero( hMcMasa->buffer_energy, hMcMasa->nbands * hMcMasa->no_col_avg_diff );
310 :
311 7110 : if ( st_ivas->hEncoderConfig->mc_input_setup == MC_LS_SETUP_5_1 )
312 : {
313 1847 : mvr2r( ls_azimuth_CICP6, ls_azimuth, nchan_inp - 1 );
314 1847 : mvr2r( ls_elevation_CICP6, ls_elevation, nchan_inp - 1 );
315 1847 : hMcMasa->numHorizontalChannels = 5;
316 1847 : hMcMasa->isHorizontalSetup = 1;
317 : }
318 5263 : else if ( st_ivas->hEncoderConfig->mc_input_setup == MC_LS_SETUP_7_1 )
319 : {
320 549 : mvr2r( ls_azimuth_CICP12, ls_azimuth, nchan_inp - 1 );
321 549 : mvr2r( ls_elevation_CICP12, ls_elevation, nchan_inp - 1 );
322 549 : hMcMasa->numHorizontalChannels = 7;
323 549 : hMcMasa->isHorizontalSetup = 1;
324 : }
325 4714 : else if ( st_ivas->hEncoderConfig->mc_input_setup == MC_LS_SETUP_5_1_2 )
326 : {
327 392 : mvr2r( ls_azimuth_CICP14, ls_azimuth, nchan_inp - 1 );
328 392 : mvr2r( ls_elevation_CICP14, ls_elevation, nchan_inp - 1 );
329 392 : hMcMasa->numHorizontalChannels = 5;
330 392 : hMcMasa->isHorizontalSetup = 0;
331 : }
332 4322 : else if ( st_ivas->hEncoderConfig->mc_input_setup == MC_LS_SETUP_5_1_4 )
333 : {
334 408 : mvr2r( ls_azimuth_CICP16, ls_azimuth, nchan_inp - 1 );
335 408 : mvr2r( ls_elevation_CICP16, ls_elevation, nchan_inp - 1 );
336 408 : hMcMasa->numHorizontalChannels = 5;
337 408 : hMcMasa->isHorizontalSetup = 0;
338 : }
339 : else
340 : {
341 3914 : mvr2r( ls_azimuth_CICP19, ls_azimuth, nchan_inp - 1 );
342 3914 : mvr2r( ls_elevation_CICP19, ls_elevation, nchan_inp - 1 );
343 3914 : hMcMasa->numHorizontalChannels = 7;
344 3914 : hMcMasa->isHorizontalSetup = 0;
345 : }
346 :
347 7110 : if ( hMcMasa->separateChannelEnabled )
348 : {
349 1535 : mvr2r( &ls_azimuth[hMcMasa->separateChannelIndex + 1], &ls_azimuth[hMcMasa->separateChannelIndex], numAnalysisChannels - hMcMasa->separateChannelIndex );
350 1535 : mvr2r( &ls_elevation[hMcMasa->separateChannelIndex + 1], &ls_elevation[hMcMasa->separateChannelIndex], numAnalysisChannels - hMcMasa->separateChannelIndex );
351 1535 : hMcMasa->numHorizontalChannels--;
352 : }
353 :
354 7110 : computeEvenLayout( ls_azimuth, ls_azimuth_even, hMcMasa->numHorizontalChannels );
355 7110 : if ( !hMcMasa->isHorizontalSetup )
356 : {
357 4714 : computeEvenLayout( &ls_azimuth[hMcMasa->numHorizontalChannels], &ls_azimuth_even[hMcMasa->numHorizontalChannels], numAnalysisChannels - hMcMasa->numHorizontalChannels );
358 : }
359 :
360 68123 : for ( i = 0; i < numAnalysisChannels; i++ )
361 : {
362 61013 : hMcMasa->chnlToFoaMtx[0][i] = 1.0f;
363 61013 : hMcMasa->chnlToFoaMtx[1][i] = sinf( ls_azimuth[i] * PI_OVER_180 ) * cosf( ls_elevation[i] * PI_OVER_180 );
364 61013 : hMcMasa->chnlToFoaMtx[2][i] = sinf( ls_elevation[i] * PI_OVER_180 );
365 61013 : hMcMasa->chnlToFoaMtx[3][i] = cosf( ls_azimuth[i] * PI_OVER_180 ) * cosf( ls_elevation[i] * PI_OVER_180 );
366 :
367 61013 : hMcMasa->chnlToFoaEvenMtx[0][i] = 1.0f;
368 61013 : hMcMasa->chnlToFoaEvenMtx[1][i] = sinf( ls_azimuth_even[i] * PI_OVER_180 );
369 61013 : hMcMasa->chnlToFoaEvenMtx[2][i] = 0.0f;
370 61013 : hMcMasa->chnlToFoaEvenMtx[3][i] = cosf( ls_azimuth_even[i] * PI_OVER_180 );
371 : }
372 :
373 7110 : hMcMasa->combineRatios = hMasa->config.mergeRatiosOverSubframes;
374 :
375 7110 : mvr2r( ls_azimuth, hMcMasa->ls_azimuth, numAnalysisChannels );
376 :
377 50051 : for ( i = 0; i < hMcMasa->numHorizontalChannels; i++ )
378 : {
379 42941 : left_min = 360.0f;
380 42941 : right_min = -360.0f;
381 :
382 308248 : for ( j = 0; j < hMcMasa->numHorizontalChannels; j++ )
383 : {
384 265307 : azi_diff = ls_azimuth[j] - ls_azimuth[i];
385 :
386 265307 : if ( azi_diff > 180.0f )
387 : {
388 16585 : azi_diff -= 360.0f;
389 : }
390 248722 : else if ( azi_diff < -180.0f )
391 : {
392 16585 : azi_diff += 360.0f;
393 : }
394 :
395 265307 : if ( azi_diff < left_min && azi_diff > 0.0f )
396 : {
397 69564 : hMcMasa->leftNearest[i] = j;
398 69564 : left_min = azi_diff;
399 : }
400 :
401 265307 : if ( azi_diff > right_min && azi_diff < 0.0f )
402 : {
403 62454 : hMcMasa->rightNearest[i] = j;
404 62454 : right_min = azi_diff;
405 : }
406 : }
407 : }
408 :
409 7110 : hMcMasa->prevMultiChEne = 0.0f;
410 7110 : hMcMasa->prevDownmixEne = 0.0f;
411 7110 : hMcMasa->prevEQ = 1.0f;
412 7110 : input_frame = (int16_t) ( input_Fs / FRAMES_PER_SEC );
413 6667270 : for ( i = 0; i < input_frame; i++ )
414 : {
415 6660160 : hMcMasa->interpolator[i] = ( (float) i ) / ( (float) input_frame );
416 : }
417 :
418 7110 : mvs2s( DirAC_block_grouping_5ms_MDFT, hMcMasa->block_grouping, MAX_PARAM_SPATIAL_SUBFRAMES + 1 );
419 :
420 7110 : hMcMasa->index_buffer_intensity = 0;
421 :
422 7110 : st_ivas->hMcMasa = hMcMasa;
423 :
424 7110 : return error;
425 : }
426 :
427 :
428 : /*-------------------------------------------------------------------------
429 : * ivas_mcmasa_enc_reconfig()
430 : *
431 : * Reconfigure McMASA encoder
432 : *------------------------------------------------------------------------*/
433 :
434 2234 : ivas_error ivas_mcmasa_enc_reconfig(
435 : Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */
436 : )
437 : {
438 : int32_t ivas_total_brate;
439 : ivas_error error;
440 :
441 2234 : error = IVAS_ERR_OK;
442 :
443 2234 : ivas_total_brate = st_ivas->hEncoderConfig->ivas_total_brate;
444 :
445 2234 : if ( ivas_total_brate != st_ivas->hEncoderConfig->last_ivas_total_brate )
446 : {
447 : /* bitrate changed, may need to do something */
448 :
449 : /* brute-force solution: close McMASA and re-instantiate with new settings */
450 2234 : ivas_masa_enc_close( &( st_ivas->hMasa ) );
451 2234 : ivas_mcmasa_enc_close( &( st_ivas->hMcMasa ), st_ivas->hEncoderConfig->input_Fs );
452 :
453 : /* Determine if to separate some channels from the analysis */
454 2234 : ivas_mcmasa_setNumTransportChannels( &( st_ivas->nchan_transport ), &( st_ivas->hEncoderConfig->element_mode_init ), ivas_total_brate );
455 :
456 2234 : if ( ( error = ivas_masa_enc_open( st_ivas ) ) != IVAS_ERR_OK )
457 : {
458 0 : return error;
459 : }
460 :
461 2234 : if ( ( error = ivas_mcmasa_enc_open( st_ivas ) ) != IVAS_ERR_OK )
462 : {
463 0 : return error;
464 : }
465 :
466 : /* core SCE, CPE reconfiguration happens later */
467 : }
468 :
469 2234 : return error;
470 : }
471 :
472 : /*--------------------------------------------------------------------------*
473 : * ivas_mcmasa_enc_close()
474 : *
475 : *
476 : *--------------------------------------------------------------------------*/
477 :
478 20096 : void ivas_mcmasa_enc_close(
479 : MCMASA_ENC_HANDLE *hMcMasa, /* i/o: encoder McMASA handle */
480 : const int32_t input_Fs /* i : input sampling rate */
481 : )
482 : {
483 : int16_t i, j;
484 :
485 20096 : if ( hMcMasa == NULL || *hMcMasa == NULL )
486 : {
487 12986 : return;
488 : }
489 :
490 7110 : if ( ( *hMcMasa )->separateChannelEnabled )
491 : {
492 1535 : free( ( *hMcMasa )->delay_buffer_lfe[0] );
493 1535 : free( ( *hMcMasa )->delay_buffer_lfe[1] );
494 :
495 4605 : for ( i = 0; i < 2; i++ )
496 : {
497 3070 : free( ( *hMcMasa )->lfeAnaRingBuffer[i] );
498 : }
499 : }
500 :
501 7110 : ivas_FB_mixer_close( &( *hMcMasa )->hFbMixer, input_Fs, 0 );
502 :
503 7110 : if ( !( *hMcMasa )->separateChannelEnabled )
504 : {
505 5575 : ivas_FB_mixer_close( &( *hMcMasa )->hFbMixerLfe, input_Fs, 0 );
506 : }
507 :
508 : /* intensity 3-dim */
509 28440 : for ( i = 0; i < DIRAC_NUM_DIMS; i++ )
510 : {
511 106650 : for ( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ )
512 : {
513 85320 : free( ( *hMcMasa )->direction_vector_m[i][j] );
514 85320 : ( *hMcMasa )->direction_vector_m[i][j] = NULL;
515 : }
516 :
517 191970 : for ( j = 0; j < ( *hMcMasa )->no_col_avg_diff; j++ )
518 : {
519 170640 : free( ( *hMcMasa )->buffer_intensity_real[i][j] );
520 170640 : ( *hMcMasa )->buffer_intensity_real[i][j] = NULL;
521 : }
522 :
523 21330 : free( ( *hMcMasa )->buffer_intensity_real[i] );
524 21330 : ( *hMcMasa )->buffer_intensity_real[i] = NULL;
525 :
526 21330 : free( ( *hMcMasa )->direction_vector_m[i] );
527 21330 : ( *hMcMasa )->direction_vector_m[i] = NULL;
528 : }
529 :
530 63990 : for ( j = 0; j < ( *hMcMasa )->no_col_avg_diff; j++ )
531 : {
532 56880 : free( ( *hMcMasa )->buffer_intensity_real_vert[j] );
533 56880 : ( *hMcMasa )->buffer_intensity_real_vert[j] = NULL;
534 : }
535 7110 : free( ( *hMcMasa )->buffer_intensity_real_vert );
536 7110 : ( *hMcMasa )->buffer_intensity_real_vert = NULL;
537 :
538 7110 : free( ( *hMcMasa )->buffer_energy );
539 7110 : ( *hMcMasa )->buffer_energy = NULL;
540 :
541 7110 : free( ( *hMcMasa ) );
542 7110 : ( *hMcMasa ) = NULL;
543 :
544 7110 : return;
545 : }
546 :
547 :
548 : /*--------------------------------------------------------------------------*
549 : * ivas_mcmasa_enc()
550 : *
551 : * Multichannel MASA encoder
552 : *--------------------------------------------------------------------------*/
553 :
554 190840 : void ivas_mcmasa_enc(
555 : MCMASA_ENC_HANDLE hMcMasa, /* i/o: Encoder McMASA handle */
556 : IVAS_QMETADATA_HANDLE hQMeta, /* o : Qmetadata handle */
557 : MASA_ENCODER_HANDLE hMasa, /* i/o: Encoder MASA handle */
558 : float *data_f[], /* i : Input frame of audio */
559 : const int16_t input_frame, /* i : Input frame size */
560 : const int16_t nchan_transport, /* i : Number of transport channels */
561 : const int16_t nchan_inp /* i : Number of input channels */
562 : )
563 : {
564 : int16_t i, j, k;
565 190840 : int16_t nBands = hMcMasa->nbands;
566 190840 : int16_t nBlocks = MAX_PARAM_SPATIAL_SUBFRAMES;
567 190840 : uint8_t fixedDistance = 0;
568 : float elevation_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
569 : float azimuth_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
570 : float energyRatio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
571 : float spreadCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
572 : float surroundingCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
573 : float separatedChannelSignal[L_FRAME48k];
574 :
575 : /* Compute low frequency energy */
576 190840 : computeLfeEnergy( hMcMasa, data_f, input_frame );
577 :
578 : /* Sum center and LFE, move surround channels */
579 190840 : v_add( data_f[2], data_f[3], data_f[2], input_frame );
580 1024728 : for ( i = 4; i < nchan_inp; i++ )
581 : {
582 833888 : mvr2r( data_f[i], data_f[i - 1], input_frame );
583 : }
584 :
585 190840 : if ( hMcMasa->separateChannelEnabled )
586 : {
587 : /* Identify channel to separate */
588 36974 : i = hMcMasa->separateChannelIndex;
589 :
590 : /* Separate the identified channel */
591 36974 : mvr2r( data_f[i], separatedChannelSignal, input_frame );
592 :
593 : /* Move the remaining channels in order to perform the analysis without the separated channel */
594 329966 : for ( i = ( hMcMasa->separateChannelIndex + 1 ); i < ( nchan_inp - 1 ); i++ )
595 : {
596 292992 : mvr2r( data_f[i], data_f[i - 1], input_frame );
597 : }
598 : }
599 :
600 : /* Analysis */
601 190840 : ivas_mcmasa_param_est_enc( hMcMasa, hMasa, data_f, elevation_m_values, azimuth_m_values, energyRatio, spreadCoherence, surroundingCoherence, input_frame, nchan_inp );
602 :
603 : /* Determine LFE-to-total energy ratio */
604 954200 : for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ )
605 : {
606 763360 : hMasa->data.lfeToTotalEnergyRatio[i] = hMcMasa->lfeLfEne[i] / ( EPSILON + hMcMasa->totalLfEne[i] );
607 : }
608 :
609 : /* Set analyzed values to the MASA struct */
610 1145040 : for ( i = 0; i < nBands; i++ )
611 : {
612 4771000 : for ( j = 0; j < nBlocks; j++ )
613 : {
614 3816800 : if ( hMcMasa->combineRatios )
615 : {
616 3816800 : k = 0;
617 : }
618 : else
619 : {
620 0 : k = j;
621 : }
622 :
623 3816800 : hQMeta->q_direction[0].band_data[i].azimuth[j] = azimuth_m_values[j][i];
624 3816800 : hQMeta->q_direction[0].band_data[i].elevation[j] = elevation_m_values[j][i];
625 3816800 : hQMeta->q_direction[0].band_data[i].energy_ratio[j] = energyRatio[k][i];
626 3816800 : hQMeta->q_direction[0].band_data[i].distance[j] = fixedDistance;
627 :
628 3816800 : if ( hQMeta->surcoh_band_data != NULL )
629 : {
630 3484720 : hQMeta->q_direction[0].coherence_band_data[i].spread_coherence[j] = (uint8_t) roundf( spreadCoherence[j][i] * UINT8_MAX );
631 3484720 : hQMeta->surcoh_band_data[i].surround_coherence[j] = (uint8_t) roundf( surroundingCoherence[k][i] * UINT8_MAX );
632 : }
633 : }
634 : }
635 :
636 : /* At lower sampling rates, set zeros for higher bands that were not analyzed */
637 190840 : if ( nBands < hMcMasa->nCodingBands )
638 : {
639 0 : for ( i = nBands; i < hMcMasa->nCodingBands; i++ )
640 : {
641 0 : for ( j = 0; j < nBlocks; j++ )
642 : {
643 0 : hQMeta->q_direction[0].band_data[i].azimuth[j] = 0.0f;
644 0 : hQMeta->q_direction[0].band_data[i].elevation[j] = 0.0f;
645 0 : hQMeta->q_direction[0].band_data[i].energy_ratio[j] = 0.0f;
646 0 : hQMeta->q_direction[0].band_data[i].distance[j] = 0;
647 :
648 0 : if ( hQMeta->surcoh_band_data != NULL )
649 : {
650 0 : hQMeta->q_direction[0].coherence_band_data[i].spread_coherence[j] = 0;
651 0 : hQMeta->surcoh_band_data[i].surround_coherence[j] = 0;
652 : }
653 : }
654 : }
655 : }
656 :
657 : /* Downmix */
658 190840 : ivas_mcmasa_dmx( hMcMasa, data_f, input_frame, nchan_transport, nchan_inp );
659 :
660 190840 : if ( hMcMasa->separateChannelEnabled )
661 : {
662 : /* Put separated channel back to data_f to first empty channel after the transport audio signals for encoding */
663 36974 : mvr2r( separatedChannelSignal, data_f[2], input_frame );
664 : }
665 :
666 : /* Update mcMASA-relevant coding parameters */
667 : /* These are reset to default values as they may be modified during later processing. */
668 190840 : hMasa->config.joinedSubframes = FALSE;
669 190840 : hQMeta->q_direction[0].cfg.nbands = hMcMasa->nbands;
670 190840 : hQMeta->q_direction[0].cfg.nblocks = MAX_PARAM_SPATIAL_SUBFRAMES;
671 190840 : hQMeta->all_coherence_zero = 1;
672 :
673 : /* Check spread coherence */
674 190840 : i = 0;
675 481000 : while ( i < nBlocks && hQMeta->all_coherence_zero )
676 : {
677 290160 : j = 0;
678 1140971 : while ( j < nBands && hQMeta->all_coherence_zero )
679 : {
680 850811 : if ( spreadCoherence[i][j] > MASA_COHERENCE_THRESHOLD )
681 : {
682 168910 : hQMeta->all_coherence_zero = 0;
683 : }
684 850811 : j++;
685 : }
686 290160 : i++;
687 : }
688 :
689 : /* Check surrounding coherence */
690 190840 : if ( hQMeta->all_coherence_zero )
691 : {
692 : float diffuse_to_total_ratio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
693 : uint8_t cohSignificant;
694 : int16_t nSubFrames;
695 :
696 21930 : nSubFrames = hMcMasa->combineRatios ? 1 : MAX_PARAM_SPATIAL_SUBFRAMES;
697 43860 : for ( i = 0; i < nSubFrames; i++ )
698 : {
699 131580 : for ( j = 0; j < nBands; j++ )
700 : {
701 109650 : diffuse_to_total_ratio[i][j] = fmaxf( 0.0f, 1.0f - energyRatio[i][j] );
702 : }
703 : }
704 :
705 21930 : cohSignificant = ivas_masa_surrcoh_signicant( surroundingCoherence, diffuse_to_total_ratio, nSubFrames, nBands );
706 21930 : if ( cohSignificant )
707 : {
708 14253 : hQMeta->all_coherence_zero = 0;
709 : }
710 : }
711 190840 : hMasa->config.coherencePresent = !hQMeta->all_coherence_zero;
712 :
713 190840 : return;
714 : }
715 :
716 :
717 : /*--------------------------------------------------------------------------*
718 : * ivas_mcmasa_param_est_enc()
719 : *
720 : * Estimate metadata parameters for McMASA
721 : *--------------------------------------------------------------------------*/
722 :
723 190840 : void ivas_mcmasa_param_est_enc(
724 : MCMASA_ENC_HANDLE hMcMasa, /* i : McMASA encoder structure */
725 : MASA_ENCODER_HANDLE hMasa, /* i : MASA encoder structure */
726 : float *data_f[], /* i : Audio frame in MC-format */
727 : float elevation_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* o : Estimated elevation */
728 : float azimuth_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* o : Estimated azimuth */
729 : float energyRatio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* o : Estimated direct-to-total ratio */
730 : float spreadCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* o : Estimated spread coherence */
731 : float surroundingCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* o : Estimated surround coherence */
732 : const int16_t input_frame, /* i : Input frame size */
733 : const int16_t nchan_inp /* i : Number of input channels */
734 : )
735 : {
736 : float reference_power[MDFT_NO_COL_MAX][DIRAC_NO_FB_BANDS_MAX];
737 : int16_t ts, i, j, d;
738 : int16_t num_freq_bins, num_freq_bands, index;
739 : float dir_v[DIRAC_NUM_DIMS];
740 : int16_t l_ts;
741 : float *pcm_in[MCMASA_MAX_ANA_CHANS];
742 : float Chnl_RealBuffer[MCMASA_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX];
743 : float Chnl_ImagBuffer[MCMASA_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX];
744 : float *p_Chnl_RealBuffer[MCMASA_MAX_ANA_CHANS];
745 : float *p_Chnl_ImagBuffer[MCMASA_MAX_ANA_CHANS];
746 : float Foa_RealBuffer[FOA_CHANNELS][DIRAC_NO_FB_BANDS_MAX];
747 : float Foa_ImagBuffer[FOA_CHANNELS][DIRAC_NO_FB_BANDS_MAX];
748 : float FoaEven_RealBuffer[FOA_CHANNELS][DIRAC_NO_FB_BANDS_MAX];
749 : float FoaEven_ImagBuffer[FOA_CHANNELS][DIRAC_NO_FB_BANDS_MAX];
750 : float intensity_real[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS];
751 : float intensity_even_real[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS];
752 : float direction_vector[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS];
753 : float diffuseness_vector[MASA_FREQUENCY_BANDS];
754 : float vertical_diffuseness_vector[MASA_FREQUENCY_BANDS];
755 : float diffuseness_m[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
756 : float coherentEnergyRatio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
757 : int16_t band_m_idx, block_m_idx;
758 : float renormalization_factor_diff[MASA_FREQUENCY_BANDS];
759 : float norm_tmp;
760 : int16_t mrange[2], brange[2];
761 : int16_t numSubFramesForRatio;
762 : CovarianceMatrix COVls[MASA_FREQUENCY_BANDS];
763 : float absCOVls[MCMASA_MAX_ANA_CHANS][MCMASA_MAX_ANA_CHANS];
764 : float lsEnergy[MCMASA_MAX_ANA_CHANS];
765 : float lsEnergySum, maxEne;
766 : int16_t loudestCh;
767 : float surrCoh, tempCoh, tempCoh2;
768 : int16_t i1, i2, i3;
769 : float angleDist, minAngleDist;
770 : float currentAzi;
771 : float lsEnergyRelation;
772 : float tempLsEnergyRelation;
773 : float stereoness, cohwideness, spreadCoh;
774 : float stereoRatio, cohPanRatio;
775 : float stereoCoh, cohPanCoh, cohRatio;
776 : float renormalization_factor_coh[MASA_FREQUENCY_BANDS];
777 : int16_t numAnalysisChannels;
778 :
779 190840 : num_freq_bins = input_frame / MDFT_NO_COL_MAX;
780 190840 : num_freq_bands = hMcMasa->nbands;
781 190840 : l_ts = input_frame / MDFT_NO_COL_MAX;
782 :
783 190840 : numAnalysisChannels = nchan_inp - 1;
784 190840 : if ( hMcMasa->separateChannelEnabled )
785 : {
786 36974 : numAnalysisChannels = nchan_inp - 2;
787 : }
788 :
789 190840 : if ( hMcMasa->combineRatios )
790 : {
791 : /* Need to initialize renormalization_factors, and variables to be normalized */
792 190840 : set_zero( renormalization_factor_diff, hMcMasa->nbands );
793 190840 : set_zero( diffuseness_m[0], hMcMasa->nbands );
794 190840 : set_zero( renormalization_factor_coh, hMcMasa->nbands );
795 190840 : set_zero( surroundingCoherence[0], hMcMasa->nbands );
796 190840 : set_zero( coherentEnergyRatio[0], hMcMasa->nbands );
797 : }
798 :
799 : /* Copy current frame to memory for delay compensation */
800 1560274 : for ( i = 0; i < numAnalysisChannels; i++ )
801 : {
802 1369434 : pcm_in[i] = data_f[i];
803 1369434 : p_Chnl_RealBuffer[i] = &Chnl_RealBuffer[i][0];
804 1369434 : p_Chnl_ImagBuffer[i] = &Chnl_ImagBuffer[i][0];
805 : }
806 :
807 : /* do processing over all CLDFB time slots */
808 954200 : for ( block_m_idx = 0; block_m_idx < MAX_PARAM_SPATIAL_SUBFRAMES; block_m_idx++ )
809 : {
810 763360 : mrange[0] = hMcMasa->block_grouping[block_m_idx];
811 763360 : mrange[1] = hMcMasa->block_grouping[block_m_idx + 1];
812 :
813 4580160 : for ( band_m_idx = 0; band_m_idx < hMcMasa->nbands; band_m_idx++ )
814 : {
815 3816800 : hMcMasa->direction_vector_m[0][block_m_idx][band_m_idx] = 0;
816 3816800 : hMcMasa->direction_vector_m[1][block_m_idx][band_m_idx] = 0;
817 3816800 : hMcMasa->direction_vector_m[2][block_m_idx][band_m_idx] = 0;
818 : }
819 :
820 : /* Reset variable */
821 4580160 : for ( i = 0; i < hMcMasa->nbands; i++ )
822 : {
823 31205480 : for ( j = 0; j < numAnalysisChannels; j++ )
824 : {
825 27388680 : set_zero( COVls[i].xr[j], numAnalysisChannels );
826 27388680 : set_zero( COVls[i].xi[j], numAnalysisChannels );
827 : }
828 : }
829 :
830 1526720 : for ( ts = mrange[0]; ts < mrange[1]; ts++ )
831 : {
832 763360 : ivas_fb_mixer_get_windowed_fr( hMcMasa->hFbMixer, pcm_in, p_Chnl_RealBuffer, p_Chnl_ImagBuffer, l_ts, l_ts, hMcMasa->hFbMixer->fb_cfg->num_in_chans );
833 :
834 763360 : ivas_fb_mixer_update_prior_input( hMcMasa->hFbMixer, pcm_in, l_ts, hMcMasa->hFbMixer->fb_cfg->num_in_chans );
835 :
836 6241096 : for ( i = 0; i < numAnalysisChannels; i++ )
837 : {
838 5477736 : pcm_in[i] += l_ts;
839 : }
840 :
841 : /* Compute covariance matrix */
842 4580160 : for ( i = 0; i < num_freq_bands; i++ )
843 : {
844 3816800 : brange[0] = hMcMasa->band_grouping[i];
845 3816800 : brange[1] = hMcMasa->band_grouping[i + 1];
846 184981600 : for ( j = brange[0]; j < brange[1]; j++ )
847 : {
848 181164800 : compute_cov_mtx( Chnl_RealBuffer, Chnl_ImagBuffer, j, numAnalysisChannels, &( COVls[i] ) );
849 : }
850 :
851 : /* Store energies for guiding metadata encoding */
852 3816800 : hMasa->data.energy[block_m_idx][i] = 0.0f;
853 31205480 : for ( j = 0; j < numAnalysisChannels; j++ )
854 : {
855 27388680 : hMasa->data.energy[block_m_idx][i] += COVls[i].xr[j][j];
856 : }
857 : }
858 :
859 763360 : if ( !hMcMasa->separateChannelEnabled )
860 : {
861 : /* Compute low frequency energy */
862 4625440 : for ( i = 0; i < numAnalysisChannels; i++ )
863 : {
864 20049880 : for ( j = 0; j < CLDFB_TO_MDFT_FAC; j++ )
865 : {
866 16039904 : hMcMasa->totalLfEne[block_m_idx] += Chnl_RealBuffer[i][j] * Chnl_RealBuffer[i][j] + Chnl_ImagBuffer[i][j] * Chnl_ImagBuffer[i][j];
867 : }
868 : }
869 : }
870 :
871 : /* Compute standard FOA */
872 : /* W */
873 763360 : v_add( Chnl_RealBuffer[0], Chnl_RealBuffer[1], Foa_RealBuffer[0], num_freq_bins );
874 763360 : v_add( Chnl_ImagBuffer[0], Chnl_ImagBuffer[1], Foa_ImagBuffer[0], num_freq_bins );
875 4714376 : for ( i = 2; i < numAnalysisChannels; i++ )
876 : {
877 3951016 : v_add( Chnl_RealBuffer[i], Foa_RealBuffer[0], Foa_RealBuffer[0], num_freq_bins );
878 3951016 : v_add( Chnl_ImagBuffer[i], Foa_ImagBuffer[0], Foa_ImagBuffer[0], num_freq_bins );
879 : }
880 :
881 : /* Y */
882 763360 : v_multc( Chnl_RealBuffer[0], hMcMasa->chnlToFoaMtx[1][0], Foa_RealBuffer[1], num_freq_bins );
883 763360 : v_multc( Chnl_ImagBuffer[0], hMcMasa->chnlToFoaMtx[1][0], Foa_ImagBuffer[1], num_freq_bins );
884 5477736 : for ( i = 1; i < numAnalysisChannels; i++ )
885 : {
886 4714376 : v_multc_acc( Chnl_RealBuffer[i], hMcMasa->chnlToFoaMtx[1][i], Foa_RealBuffer[1], num_freq_bins );
887 4714376 : v_multc_acc( Chnl_ImagBuffer[i], hMcMasa->chnlToFoaMtx[1][i], Foa_ImagBuffer[1], num_freq_bins );
888 : }
889 :
890 : /* Z */
891 763360 : if ( hMcMasa->isHorizontalSetup )
892 : {
893 : /* Set zero for horizontal setups */
894 417304 : set_zero( Foa_RealBuffer[2], num_freq_bins );
895 417304 : set_zero( Foa_ImagBuffer[2], num_freq_bins );
896 : }
897 : else
898 : {
899 346056 : v_multc( Chnl_RealBuffer[0], hMcMasa->chnlToFoaMtx[2][0], Foa_RealBuffer[2], num_freq_bins );
900 346056 : v_multc( Chnl_ImagBuffer[0], hMcMasa->chnlToFoaMtx[2][0], Foa_ImagBuffer[2], num_freq_bins );
901 3340336 : for ( i = 1; i < numAnalysisChannels; i++ )
902 : {
903 2994280 : v_multc_acc( Chnl_RealBuffer[i], hMcMasa->chnlToFoaMtx[2][i], Foa_RealBuffer[2], num_freq_bins );
904 2994280 : v_multc_acc( Chnl_ImagBuffer[i], hMcMasa->chnlToFoaMtx[2][i], Foa_ImagBuffer[2], num_freq_bins );
905 : }
906 : }
907 :
908 : /* X */
909 763360 : v_multc( Chnl_RealBuffer[0], hMcMasa->chnlToFoaMtx[3][0], Foa_RealBuffer[3], num_freq_bins );
910 763360 : v_multc( Chnl_ImagBuffer[0], hMcMasa->chnlToFoaMtx[3][0], Foa_ImagBuffer[3], num_freq_bins );
911 5477736 : for ( i = 1; i < numAnalysisChannels; i++ )
912 : {
913 4714376 : v_multc_acc( Chnl_RealBuffer[i], hMcMasa->chnlToFoaMtx[3][i], Foa_RealBuffer[3], num_freq_bins );
914 4714376 : v_multc_acc( Chnl_ImagBuffer[i], hMcMasa->chnlToFoaMtx[3][i], Foa_ImagBuffer[3], num_freq_bins );
915 : }
916 :
917 : /* Compute even FOA */
918 : /* W */
919 763360 : mvr2r( Foa_RealBuffer[0], FoaEven_RealBuffer[0], num_freq_bins );
920 763360 : mvr2r( Foa_ImagBuffer[0], FoaEven_ImagBuffer[0], num_freq_bins );
921 :
922 : /* Y */
923 763360 : v_multc( Chnl_RealBuffer[0], hMcMasa->chnlToFoaEvenMtx[1][0], FoaEven_RealBuffer[1], num_freq_bins );
924 763360 : v_multc( Chnl_ImagBuffer[0], hMcMasa->chnlToFoaEvenMtx[1][0], FoaEven_ImagBuffer[1], num_freq_bins );
925 5477736 : for ( i = 1; i < numAnalysisChannels; i++ )
926 : {
927 4714376 : v_multc_acc( Chnl_RealBuffer[i], hMcMasa->chnlToFoaEvenMtx[1][i], FoaEven_RealBuffer[1], num_freq_bins );
928 4714376 : v_multc_acc( Chnl_ImagBuffer[i], hMcMasa->chnlToFoaEvenMtx[1][i], FoaEven_ImagBuffer[1], num_freq_bins );
929 : }
930 :
931 : /* Z (even setups are handled as horizontal) */
932 763360 : set_zero( FoaEven_RealBuffer[2], num_freq_bins );
933 763360 : set_zero( FoaEven_ImagBuffer[2], num_freq_bins );
934 :
935 : /* X */
936 763360 : v_multc( Chnl_RealBuffer[0], hMcMasa->chnlToFoaEvenMtx[3][0], FoaEven_RealBuffer[3], num_freq_bins );
937 763360 : v_multc( Chnl_ImagBuffer[0], hMcMasa->chnlToFoaEvenMtx[3][0], FoaEven_ImagBuffer[3], num_freq_bins );
938 5477736 : for ( i = 1; i < numAnalysisChannels; i++ )
939 : {
940 4714376 : v_multc_acc( Chnl_RealBuffer[i], hMcMasa->chnlToFoaEvenMtx[3][i], FoaEven_RealBuffer[3], num_freq_bins );
941 4714376 : v_multc_acc( Chnl_ImagBuffer[i], hMcMasa->chnlToFoaEvenMtx[3][i], FoaEven_ImagBuffer[3], num_freq_bins );
942 : }
943 :
944 : /* Direction estimation */
945 763360 : computeIntensityVector_enc(
946 763360 : hMcMasa->band_grouping,
947 : Foa_RealBuffer,
948 : Foa_ImagBuffer,
949 : 0,
950 : num_freq_bands,
951 : intensity_real );
952 :
953 763360 : computeDirectionVectors(
954 : intensity_real[0],
955 : intensity_real[1],
956 : intensity_real[2],
957 : 0,
958 : num_freq_bands,
959 : direction_vector[0],
960 : direction_vector[1],
961 : direction_vector[2] );
962 :
963 : /* Power and intensity estimation for diffuseness */
964 763360 : computeIntensityVector_enc(
965 763360 : hMcMasa->band_grouping,
966 : FoaEven_RealBuffer,
967 : FoaEven_ImagBuffer,
968 : 0,
969 : num_freq_bands,
970 : intensity_even_real );
971 :
972 763360 : computeReferencePower_enc( hMcMasa->band_grouping,
973 : FoaEven_RealBuffer,
974 : FoaEven_ImagBuffer,
975 763360 : reference_power[ts],
976 : 0,
977 : num_freq_bands,
978 : MC_FORMAT,
979 : 0,
980 : FOA_CHANNELS,
981 : NULL,
982 : NULL );
983 :
984 : /* Fill buffers of length "averaging_length" time slots for intensity and energy */
985 763360 : hMcMasa->index_buffer_intensity = ( hMcMasa->index_buffer_intensity % hMcMasa->no_col_avg_diff ) + 1; /* averaging_length = 32 */
986 763360 : index = hMcMasa->index_buffer_intensity;
987 3053440 : for ( i = 0; i < DIRAC_NUM_DIMS; i++ )
988 : {
989 : /* only real part needed */
990 2290080 : mvr2r( intensity_even_real[i], &( hMcMasa->buffer_intensity_real[i][index - 1][0] ), num_freq_bands );
991 : }
992 763360 : mvr2r( reference_power[ts], &( hMcMasa->buffer_energy[( index - 1 ) * num_freq_bands] ), num_freq_bands );
993 :
994 763360 : computeDiffuseness_mdft( hMcMasa->buffer_intensity_real, hMcMasa->buffer_energy, num_freq_bands, hMcMasa->no_col_avg_diff, diffuseness_vector );
995 :
996 : /* Compute vertical diffuseness, and tune original diffuseness if needed */
997 763360 : if ( !hMcMasa->isHorizontalSetup )
998 : {
999 346056 : mvr2r( intensity_real[2], &( hMcMasa->buffer_intensity_real_vert[index - 1][0] ), num_freq_bands );
1000 346056 : computeVerticalDiffuseness( hMcMasa->buffer_intensity_real_vert, hMcMasa->buffer_energy, hMcMasa->no_col_avg_diff, num_freq_bands, vertical_diffuseness_vector );
1001 346056 : v_min( diffuseness_vector, vertical_diffuseness_vector, diffuseness_vector, num_freq_bands );
1002 : }
1003 :
1004 4580160 : for ( band_m_idx = 0; band_m_idx < hMcMasa->nbands; band_m_idx++ )
1005 : {
1006 3816800 : norm_tmp = reference_power[ts][band_m_idx] * ( 1 - diffuseness_vector[band_m_idx] );
1007 :
1008 3816800 : hMcMasa->direction_vector_m[0][block_m_idx][band_m_idx] += norm_tmp * direction_vector[0][band_m_idx];
1009 3816800 : hMcMasa->direction_vector_m[1][block_m_idx][band_m_idx] += norm_tmp * direction_vector[1][band_m_idx];
1010 3816800 : hMcMasa->direction_vector_m[2][block_m_idx][band_m_idx] += norm_tmp * direction_vector[2][band_m_idx];
1011 :
1012 3816800 : if ( hMcMasa->combineRatios )
1013 : {
1014 3816800 : diffuseness_m[0][band_m_idx] += reference_power[ts][band_m_idx] * diffuseness_vector[band_m_idx];
1015 3816800 : renormalization_factor_diff[band_m_idx] += reference_power[ts][band_m_idx];
1016 : }
1017 : else
1018 : {
1019 0 : diffuseness_m[block_m_idx][band_m_idx] = diffuseness_vector[band_m_idx];
1020 : }
1021 : }
1022 : }
1023 :
1024 4580160 : for ( band_m_idx = 0; band_m_idx < hMcMasa->nbands; band_m_idx++ )
1025 : {
1026 15267200 : for ( d = 0; d < DIRAC_NUM_DIMS; d++ )
1027 : {
1028 11450400 : dir_v[d] = hMcMasa->direction_vector_m[d][block_m_idx][band_m_idx];
1029 : }
1030 3816800 : 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] );
1031 : }
1032 :
1033 : /* Coherence processing */
1034 4580160 : for ( band_m_idx = 0; band_m_idx < hMcMasa->nbands; band_m_idx++ )
1035 : {
1036 : /* Compute absolute values */
1037 31205480 : for ( i = 0; i < numAnalysisChannels; i++ )
1038 : {
1039 150788800 : for ( j = i; j < numAnalysisChannels; j++ )
1040 : {
1041 123400120 : absCOVls[i][j] = sqrtf( ( COVls[band_m_idx].xr[i][j] * COVls[band_m_idx].xr[i][j] + COVls[band_m_idx].xi[i][j] * COVls[band_m_idx].xi[i][j] ) );
1042 : }
1043 27388680 : lsEnergy[i] = absCOVls[i][i];
1044 : }
1045 :
1046 : /* Find loudest channel */
1047 3816800 : maxEne = lsEnergy[0];
1048 3816800 : loudestCh = 0;
1049 27388680 : for ( i = 1; i < numAnalysisChannels; i++ )
1050 : {
1051 23571880 : if ( lsEnergy[i] > maxEne )
1052 : {
1053 6682854 : maxEne = lsEnergy[i];
1054 6682854 : loudestCh = i;
1055 : }
1056 : }
1057 :
1058 : /* Compute surrounding coherence */
1059 3816800 : surrCoh = 1.0f;
1060 31205480 : for ( i = 0; i < numAnalysisChannels; i++ )
1061 : {
1062 27388680 : if ( i != loudestCh )
1063 : {
1064 23571880 : if ( i < loudestCh )
1065 : {
1066 12194839 : i1 = i;
1067 12194839 : i2 = loudestCh;
1068 : }
1069 : else
1070 : {
1071 11377041 : i1 = loudestCh;
1072 11377041 : i2 = i;
1073 : }
1074 23571880 : tempCoh = absCOVls[i1][i2] / ( sqrtf( ( lsEnergy[i1] * lsEnergy[i2] + EPSILON ) ) );
1075 23571880 : surrCoh = ( surrCoh < tempCoh ) ? surrCoh : tempCoh;
1076 : }
1077 : }
1078 3816800 : surrCoh = surrCoh * surrCoh;
1079 3816800 : surrCoh = ( surrCoh < 1.0f ) ? surrCoh : 1.0f;
1080 3816800 : surrCoh = ( surrCoh > 0.0f ) ? surrCoh : 0.0f;
1081 :
1082 : /* Compute spread coherence */
1083 3816800 : if ( elevation_m_values[block_m_idx][band_m_idx] < NEAR_HORIZONTAL_PLANE_ELEVATION ) /* Computed only near horizontal plane */
1084 : {
1085 2571911 : minAngleDist = 180.0f;
1086 2571911 : i1 = 0;
1087 2571911 : currentAzi = azimuth_m_values[block_m_idx][band_m_idx];
1088 16105916 : for ( i = 0; i < hMcMasa->numHorizontalChannels; i++ )
1089 : {
1090 13534005 : angleDist = fabsf( currentAzi - hMcMasa->ls_azimuth[i] );
1091 13534005 : if ( angleDist > 180.0f )
1092 : {
1093 421887 : angleDist = fabsf( angleDist - 360.0f );
1094 : }
1095 13534005 : if ( angleDist < minAngleDist )
1096 : {
1097 5602698 : minAngleDist = angleDist;
1098 5602698 : i1 = i;
1099 : }
1100 : }
1101 2571911 : i2 = hMcMasa->leftNearest[i1];
1102 2571911 : i3 = hMcMasa->rightNearest[i1];
1103 :
1104 2571911 : if ( i2 < i3 )
1105 : {
1106 2071568 : stereoCoh = absCOVls[i2][i3] / ( sqrtf( lsEnergy[i2] * lsEnergy[i3] + EPSILON ) );
1107 : }
1108 : else
1109 : {
1110 500343 : stereoCoh = absCOVls[i3][i2] / ( sqrtf( lsEnergy[i2] * lsEnergy[i3] + EPSILON ) );
1111 : }
1112 2571911 : lsEnergyRelation = ( lsEnergy[i2] + lsEnergy[i3] ) / ( lsEnergy[i1] + lsEnergy[i2] + lsEnergy[i3] + EPSILON );
1113 2571911 : stereoness = stereoCoh * lsEnergyRelation;
1114 :
1115 2571911 : if ( i1 < i2 )
1116 : {
1117 1140124 : tempCoh = absCOVls[i1][i2] / ( sqrtf( lsEnergy[i1] * lsEnergy[i2] + EPSILON ) );
1118 : }
1119 : else
1120 : {
1121 1431787 : tempCoh = absCOVls[i2][i1] / ( sqrtf( lsEnergy[i1] * lsEnergy[i2] + EPSILON ) );
1122 : }
1123 2571911 : if ( i1 < i3 )
1124 : {
1125 1135775 : tempCoh2 = absCOVls[i1][i3] / ( sqrtf( lsEnergy[i1] * lsEnergy[i3] + EPSILON ) );
1126 : }
1127 : else
1128 : {
1129 1436136 : tempCoh2 = absCOVls[i3][i1] / ( sqrtf( lsEnergy[i1] * lsEnergy[i3] + EPSILON ) );
1130 : }
1131 2571911 : cohPanCoh = ( tempCoh < tempCoh2 ) ? tempCoh : tempCoh2;
1132 2571911 : lsEnergyRelation = lsEnergy[i2] / ( lsEnergy[i1] + EPSILON );
1133 2571911 : tempLsEnergyRelation = lsEnergy[i1] / ( lsEnergy[i2] + EPSILON );
1134 2571911 : lsEnergyRelation = ( lsEnergyRelation < tempLsEnergyRelation ) ? lsEnergyRelation : tempLsEnergyRelation;
1135 2571911 : tempLsEnergyRelation = lsEnergy[i3] / ( lsEnergy[i1] + EPSILON );
1136 2571911 : lsEnergyRelation = ( lsEnergyRelation < tempLsEnergyRelation ) ? lsEnergyRelation : tempLsEnergyRelation;
1137 2571911 : tempLsEnergyRelation = lsEnergy[i1] / ( lsEnergy[i3] + EPSILON );
1138 2571911 : lsEnergyRelation = ( lsEnergyRelation < tempLsEnergyRelation ) ? lsEnergyRelation : tempLsEnergyRelation;
1139 2571911 : cohwideness = cohPanCoh * lsEnergyRelation;
1140 :
1141 2571911 : spreadCoh = ( cohwideness > stereoness ) ? cohwideness : stereoness;
1142 2571911 : if ( spreadCoh > 0.5f )
1143 : {
1144 1337648 : if ( cohwideness > stereoness )
1145 : {
1146 343305 : tempCoh = stereoness - ( cohwideness - 0.5f );
1147 343305 : spreadCoh = ( tempCoh > 0.5f ) ? tempCoh : 0.5f;
1148 : }
1149 : }
1150 2571911 : spreadCoh = ( spreadCoh < 1.0f ) ? spreadCoh : 1.0f;
1151 2571911 : spreadCoh = ( spreadCoh > 0.0f ) ? spreadCoh : 0.0f;
1152 :
1153 : /* Compute energy ratio tuning parameter */
1154 2571911 : lsEnergySum = sum_f( lsEnergy, numAnalysisChannels ) + EPSILON;
1155 2571911 : lsEnergyRelation = ( lsEnergy[i2] + lsEnergy[i3] ) / lsEnergySum;
1156 2571911 : stereoRatio = stereoCoh * lsEnergyRelation - surrCoh;
1157 :
1158 2571911 : lsEnergyRelation = ( lsEnergy[i1] + lsEnergy[i2] + lsEnergy[i3] ) / lsEnergySum;
1159 2571911 : cohPanRatio = cohPanCoh * lsEnergyRelation - surrCoh;
1160 :
1161 2571911 : cohRatio = ( stereoRatio > cohPanRatio ) ? stereoRatio : cohPanRatio;
1162 2571911 : cohRatio = ( cohRatio < 1.0f ) ? cohRatio : 1.0f;
1163 2571911 : cohRatio = ( cohRatio > 0.0f ) ? cohRatio : 0.0f;
1164 : }
1165 : else /* Otherwise, set spread coherence to zero */
1166 : {
1167 1244889 : spreadCoh = 0.0f;
1168 1244889 : cohRatio = 0.0f;
1169 1244889 : lsEnergySum = sum_f( lsEnergy, numAnalysisChannels );
1170 : }
1171 :
1172 : /* Store values */
1173 3816800 : spreadCoherence[block_m_idx][band_m_idx] = spreadCoh;
1174 :
1175 3816800 : if ( hMcMasa->combineRatios )
1176 : {
1177 3816800 : surroundingCoherence[0][band_m_idx] += lsEnergySum * surrCoh;
1178 3816800 : coherentEnergyRatio[0][band_m_idx] += lsEnergySum * cohRatio;
1179 3816800 : renormalization_factor_coh[band_m_idx] += lsEnergySum;
1180 : }
1181 : else
1182 : {
1183 0 : surroundingCoherence[block_m_idx][band_m_idx] = surrCoh;
1184 0 : coherentEnergyRatio[block_m_idx][band_m_idx] = cohRatio;
1185 : }
1186 : }
1187 : }
1188 :
1189 190840 : if ( hMcMasa->combineRatios )
1190 : {
1191 1145040 : for ( band_m_idx = 0; band_m_idx < hMcMasa->nbands; band_m_idx++ )
1192 : {
1193 954200 : if ( renormalization_factor_diff[band_m_idx] > EPSILON )
1194 : {
1195 954200 : diffuseness_m[0][band_m_idx] /= renormalization_factor_diff[band_m_idx];
1196 : }
1197 : else
1198 : {
1199 0 : diffuseness_m[0][band_m_idx] = 0.f;
1200 : }
1201 954200 : if ( renormalization_factor_coh[band_m_idx] > EPSILON )
1202 : {
1203 954200 : surroundingCoherence[0][band_m_idx] /= renormalization_factor_coh[band_m_idx];
1204 954200 : coherentEnergyRatio[0][band_m_idx] /= renormalization_factor_coh[band_m_idx];
1205 : }
1206 : else
1207 : {
1208 0 : surroundingCoherence[0][band_m_idx] = 0.f;
1209 0 : coherentEnergyRatio[0][band_m_idx] = 0.f;
1210 : }
1211 : }
1212 : }
1213 :
1214 : /* Determine energy ratios */
1215 190840 : if ( hMcMasa->combineRatios )
1216 : {
1217 190840 : numSubFramesForRatio = 1;
1218 : }
1219 : else
1220 : {
1221 0 : numSubFramesForRatio = MAX_PARAM_SPATIAL_SUBFRAMES;
1222 : }
1223 :
1224 381680 : for ( i = 0; i < numSubFramesForRatio; i++ )
1225 : {
1226 1145040 : for ( j = 0; j < hMcMasa->nbands; j++ )
1227 : {
1228 954200 : energyRatio[i][j] = 1.0f - diffuseness_m[i][j];
1229 954200 : energyRatio[i][j] = ( energyRatio[i][j] > coherentEnergyRatio[i][j] ) ? energyRatio[i][j] : coherentEnergyRatio[i][j];
1230 : }
1231 : }
1232 :
1233 190840 : return;
1234 : }
1235 :
1236 :
1237 : /*--------------------------------------------------------------------------*
1238 : * ivas_mcmasa_dmx_modify()
1239 : *
1240 : *
1241 : *--------------------------------------------------------------------------*/
1242 :
1243 1919 : void ivas_mcmasa_dmx_modify(
1244 : const int16_t n_samples, /* i : input frame length in samples */
1245 : float dmx[][L_FRAME48k + NS2SA( 48000, IVAS_FB_ENC_DELAY_NS )], /* i/o: downmix signal to be transformed into another format */
1246 : const int16_t n_chnls_dmx_old, /* i : number of downmix channels in the old format */
1247 : const int16_t n_chnls_dmx_new ) /* i : number of downmix channels in the target format */
1248 : {
1249 : /* assumed data ordering in **dmx: [sce][cpe_chnl0][cpe_chnl1], i.e., [c][l][r] */
1250 : int16_t i;
1251 :
1252 1919 : assert( ( n_chnls_dmx_old == 1 || n_chnls_dmx_old == 2 || n_chnls_dmx_old == 3 ) && "Input downmix may contain only 1-3 channels." );
1253 1919 : assert( ( n_chnls_dmx_new == 1 || n_chnls_dmx_new == 2 || n_chnls_dmx_new == 3 ) && "Output downmix may contain only 1-3 channels." );
1254 :
1255 1919 : if ( n_chnls_dmx_old == n_chnls_dmx_new )
1256 : {
1257 : /* same dmx layout -> nothing to do */
1258 0 : return;
1259 : }
1260 :
1261 1919 : if ( n_chnls_dmx_old == 1 )
1262 : {
1263 : /* split mono energy into identical channels */
1264 643870 : for ( i = 0; i < n_samples; i++ )
1265 : {
1266 643200 : if ( n_chnls_dmx_new == 2 )
1267 : {
1268 287040 : dmx[1][i] = dmx[0][i] * INV_SQRT2;
1269 287040 : dmx[2][i] = dmx[1][i];
1270 : }
1271 356160 : else if ( n_chnls_dmx_new == 3 )
1272 : {
1273 356160 : dmx[0][i] = dmx[0][i] * INV_SQRT3;
1274 : }
1275 : }
1276 : }
1277 1249 : else if ( n_chnls_dmx_old == 2 )
1278 : {
1279 566029 : for ( i = 0; i < n_samples; i++ )
1280 : {
1281 565440 : if ( n_chnls_dmx_new == 1 )
1282 : {
1283 : /* sum l and r */
1284 268800 : dmx[0][i] = dmx[1][i] + dmx[2][i];
1285 : }
1286 296640 : else if ( n_chnls_dmx_new == 3 )
1287 : {
1288 296640 : dmx[0][i] = 0.5f * ( dmx[1][i] + dmx[2][i] );
1289 296640 : dmx[1][i] = dmx[1][i] - dmx[0][i];
1290 296640 : dmx[2][i] = dmx[2][i] - dmx[0][i];
1291 : }
1292 : }
1293 : }
1294 660 : else if ( n_chnls_dmx_old == 3 )
1295 : {
1296 634260 : for ( i = 0; i < n_samples; i++ )
1297 : {
1298 633600 : if ( n_chnls_dmx_new == 1 )
1299 : {
1300 : /* sum all channels */
1301 357120 : dmx[0][i] = dmx[0][i] + dmx[1][i] + dmx[2][i];
1302 : }
1303 276480 : else if ( n_chnls_dmx_new == 2 )
1304 : {
1305 : /* mix center into sides */
1306 276480 : dmx[0][i] *= INV_SQRT2;
1307 276480 : dmx[1][i] += dmx[0][i];
1308 276480 : dmx[2][i] += dmx[0][i];
1309 : }
1310 : }
1311 : }
1312 :
1313 1919 : return;
1314 : }
1315 :
1316 :
1317 : /*--------------------------------------------------------------------------*
1318 : * Local functions
1319 : *--------------------------------------------------------------------------*/
1320 :
1321 : /* Compute downmix */
1322 190840 : static void ivas_mcmasa_dmx(
1323 : MCMASA_ENC_HANDLE hMcMasa,
1324 : float *data_f[],
1325 : const int16_t input_frame,
1326 : const int16_t nchan_transport,
1327 : const int16_t nchan_inp )
1328 : {
1329 : int16_t i, j;
1330 : int16_t numAnalysisChannels;
1331 : float dmx_c;
1332 : float multiChEne, downmixEne;
1333 : float prevEQ, currEQ, instEQ;
1334 : float alpha;
1335 :
1336 190840 : numAnalysisChannels = nchan_inp - 1;
1337 190840 : if ( hMcMasa->separateChannelEnabled )
1338 : {
1339 36974 : numAnalysisChannels = nchan_inp - 2;
1340 : }
1341 :
1342 190840 : multiChEne = 0.0f;
1343 1560274 : for ( j = 0; j < numAnalysisChannels; j++ )
1344 : {
1345 1301373274 : for ( i = 0; i < input_frame; i++ )
1346 : {
1347 1300003840 : multiChEne += data_f[j][i] * data_f[j][i];
1348 : }
1349 : }
1350 :
1351 190840 : if ( nchan_transport == 2 )
1352 : {
1353 : int16_t numSideChannels; /* Channels other than left, right, center */
1354 : int16_t leftIndex, rightIndex;
1355 :
1356 61353 : numSideChannels = numAnalysisChannels / 2 - 1;
1357 296199 : for ( j = 0; j < numSideChannels; j++ )
1358 : {
1359 234846 : if ( hMcMasa->separateChannelEnabled )
1360 : {
1361 146496 : leftIndex = j * 2 + 2;
1362 146496 : rightIndex = j * 2 + 3;
1363 : }
1364 : else
1365 : {
1366 88350 : leftIndex = j * 2 + 3;
1367 88350 : rightIndex = j * 2 + 4;
1368 : }
1369 :
1370 224487006 : for ( i = 0; i < input_frame; i++ )
1371 : {
1372 224252160 : data_f[0][i] += data_f[leftIndex][i];
1373 224252160 : data_f[1][i] += data_f[rightIndex][i];
1374 : }
1375 : }
1376 :
1377 61353 : if ( !hMcMasa->separateChannelEnabled )
1378 : {
1379 23332219 : for ( i = 0; i < input_frame; i++ )
1380 : {
1381 23307840 : dmx_c = INV_SQRT2 * data_f[2][i];
1382 23307840 : data_f[0][i] += dmx_c;
1383 23307840 : data_f[1][i] += dmx_c;
1384 : }
1385 : }
1386 : }
1387 129487 : else if ( nchan_transport == 1 )
1388 : {
1389 122731407 : for ( i = 0; i < input_frame; i++ )
1390 : {
1391 711065920 : for ( j = 1; j < numAnalysisChannels; j++ )
1392 : {
1393 588464000 : data_f[0][i] += data_f[j][i];
1394 : }
1395 : }
1396 : }
1397 :
1398 190840 : downmixEne = 0.0f;
1399 443033 : for ( j = 0; j < nchan_transport; j++ )
1400 : {
1401 239979873 : for ( i = 0; i < input_frame; i++ )
1402 : {
1403 239727680 : downmixEne += data_f[j][i] * data_f[j][i];
1404 : }
1405 : }
1406 :
1407 190840 : alpha = 0.1f;
1408 190840 : hMcMasa->prevMultiChEne = alpha * multiChEne + ( 1.0f - alpha ) * hMcMasa->prevMultiChEne;
1409 190840 : hMcMasa->prevDownmixEne = alpha * downmixEne + ( 1.0f - alpha ) * hMcMasa->prevDownmixEne;
1410 :
1411 190840 : prevEQ = hMcMasa->prevEQ;
1412 190840 : currEQ = sqrtf( hMcMasa->prevMultiChEne / ( hMcMasa->prevDownmixEne + EPSILON ) );
1413 190840 : hMcMasa->prevEQ = currEQ;
1414 :
1415 181355640 : for ( i = 0; i < input_frame; i++ )
1416 : {
1417 181164800 : instEQ = hMcMasa->interpolator[i] * currEQ + ( 1.0f - hMcMasa->interpolator[i] ) * prevEQ;
1418 420892480 : for ( j = 0; j < nchan_transport; j++ )
1419 : {
1420 239727680 : data_f[j][i] *= instEQ;
1421 : }
1422 : }
1423 :
1424 190840 : return;
1425 : }
1426 :
1427 :
1428 : /* Compute covariance matrix, i.e., xT * conj(x), and accumulate to the output */
1429 181164800 : static void compute_cov_mtx(
1430 : float sr[MCMASA_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX], /* i : Input matrix, real, s[ch][freq] */
1431 : float si[MCMASA_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX], /* i : Input matrix, imag, s[ch][freq] */
1432 : const int16_t freq, /* i : Freq to process */
1433 : const int16_t N, /* i : Number of channels */
1434 : CovarianceMatrix *COVls /* o : Output matrix, contains upper part of cov mtx */
1435 : )
1436 : {
1437 : int16_t i, j;
1438 : float a, b, c, d;
1439 :
1440 1481168640 : for ( i = 0; i < N; i++ )
1441 : {
1442 1300003840 : a = sr[i][freq];
1443 1300003840 : b = si[i][freq];
1444 7158323200 : for ( j = i; j < N; j++ )
1445 : {
1446 5858319360 : c = sr[j][freq];
1447 5858319360 : d = si[j][freq];
1448 5858319360 : COVls->xr[i][j] += a * c + b * d;
1449 5858319360 : COVls->xi[i][j] += b * c - a * d;
1450 : }
1451 : }
1452 :
1453 181164800 : return;
1454 : }
1455 :
1456 :
1457 1526720 : static void computeIntensityVector_enc(
1458 : const int16_t *band_grouping,
1459 : float Cldfb_RealBuffer[FOA_CHANNELS][DIRAC_NO_FB_BANDS_MAX],
1460 : float Cldfb_ImagBuffer[FOA_CHANNELS][DIRAC_NO_FB_BANDS_MAX],
1461 : const int16_t enc_param_start_band, /* i : first band to process */
1462 : const int16_t num_frequency_bands,
1463 : float intensity_real[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS] )
1464 : {
1465 : /* Reminder
1466 : * X = a + ib; Y = c + id
1467 : * X*Y = ac - bd + i(ad +bc)
1468 : */
1469 : int16_t i, j;
1470 : float real, img;
1471 : int16_t brange[2];
1472 :
1473 9160320 : for ( i = enc_param_start_band; i < enc_param_start_band + num_frequency_bands; i++ )
1474 : {
1475 7633600 : brange[0] = band_grouping[i];
1476 7633600 : brange[1] = band_grouping[i + 1];
1477 :
1478 7633600 : intensity_real[0][i] = 0;
1479 7633600 : intensity_real[1][i] = 0;
1480 7633600 : intensity_real[2][i] = 0;
1481 :
1482 369963200 : for ( j = brange[0]; j < brange[1]; j++ )
1483 : {
1484 362329600 : real = Cldfb_RealBuffer[0][j];
1485 362329600 : img = Cldfb_ImagBuffer[0][j];
1486 362329600 : intensity_real[0][i] += Cldfb_RealBuffer[3][j] * real + Cldfb_ImagBuffer[3][j] * img;
1487 362329600 : intensity_real[1][i] += Cldfb_RealBuffer[1][j] * real + Cldfb_ImagBuffer[1][j] * img;
1488 362329600 : intensity_real[2][i] += Cldfb_RealBuffer[2][j] * real + Cldfb_ImagBuffer[2][j] * img;
1489 : }
1490 : }
1491 :
1492 1526720 : return;
1493 : }
1494 :
1495 :
1496 : /*-------------------------------------------------------------------------
1497 : * computeVerticalDiffuseness()
1498 : *
1499 : *
1500 : *------------------------------------------------------------------------*/
1501 :
1502 346056 : static void computeVerticalDiffuseness(
1503 : float **buffer_intensity, /* i : Intensity vectors */
1504 : const float *buffer_energy, /* i : Energy */
1505 : const int16_t averaging_length, /* i : Averaging length */
1506 : const int16_t num_freq_bands, /* i : Number of frequency bands */
1507 : float *diffuseness /* o : Estimated diffuseness */
1508 : )
1509 : {
1510 : float intensity_slow[MASA_FREQUENCY_BANDS];
1511 : float intensity_slow_abs[MASA_FREQUENCY_BANDS];
1512 : float energy_slow[MASA_FREQUENCY_BANDS];
1513 : int16_t i, k;
1514 346056 : float tmp = 0;
1515 : const float *p_tmp_c;
1516 :
1517 : /* Set variables to zero */
1518 346056 : set_f( intensity_slow, 0.0f, MASA_FREQUENCY_BANDS );
1519 346056 : set_f( energy_slow, 0.0f, MASA_FREQUENCY_BANDS );
1520 :
1521 3114504 : for ( i = 0; i < averaging_length; ++i )
1522 : {
1523 : /* Energy slow */
1524 2768448 : p_tmp_c = buffer_energy + i * num_freq_bands;
1525 16610688 : for ( k = 0; k < num_freq_bands; k++ )
1526 : {
1527 13842240 : energy_slow[k] += *( p_tmp_c++ );
1528 : }
1529 :
1530 : /* Intensity slow */
1531 16610688 : for ( k = 0; k < num_freq_bands; k++ )
1532 : {
1533 13842240 : intensity_slow[k] += buffer_intensity[i][k];
1534 : }
1535 : }
1536 :
1537 : /* Compute absolute value */
1538 2076336 : for ( k = 0; k < num_freq_bands; k++ )
1539 : {
1540 1730280 : intensity_slow_abs[k] = fabsf( intensity_slow[k] );
1541 : }
1542 :
1543 : /* Compute Diffuseness */
1544 2076336 : for ( i = 0; i < num_freq_bands; ++i )
1545 : {
1546 1730280 : tmp = intensity_slow_abs[i] / ( energy_slow[i] + EPSILON );
1547 1730280 : tmp = ( tmp - VERTICAL_ENERGY_RATIO_OFFSET ) / ( 1.0f - VERTICAL_ENERGY_RATIO_OFFSET ); /* Tuned to avoid effect due to ambience of vertically un-even setups */
1548 1730280 : tmp = 1.0f - tmp;
1549 1730280 : diffuseness[i] = ( ( tmp < 1.0f ) ? ( ( tmp < 0.0f ) ? 0.f : tmp ) : 1.0f );
1550 : }
1551 :
1552 346056 : return;
1553 : }
1554 :
1555 :
1556 11824 : static void computeEvenLayout(
1557 : const float *ls_azimuth,
1558 : float *ls_azimuth_even,
1559 : const int16_t numChannels )
1560 : {
1561 : int16_t i;
1562 : int16_t j;
1563 : float ls_azimuth_temp[MCMASA_MAX_ANA_CHANS];
1564 : float ls_azimuth_even_ordered[MCMASA_MAX_ANA_CHANS];
1565 : int16_t ls_azimuth_order[MCMASA_MAX_ANA_CHANS];
1566 : float smallestAzimuth;
1567 : int16_t smallestAzimuthIndex;
1568 : float lsSpacing;
1569 : uint8_t oddLayout;
1570 : float startAzimuth;
1571 : int16_t numChannelsHalf;
1572 :
1573 11824 : lsSpacing = 360.0f / (float) numChannels;
1574 11824 : oddLayout = numChannels % 2;
1575 11824 : numChannelsHalf = numChannels / 2;
1576 :
1577 11824 : mvr2r( ls_azimuth, ls_azimuth_temp, numChannels );
1578 72837 : for ( i = 0; i < numChannels; i++ )
1579 : {
1580 61013 : smallestAzimuth = 1000.0f;
1581 61013 : smallestAzimuthIndex = 0;
1582 397040 : for ( j = 0; j < numChannels; j++ )
1583 : {
1584 336027 : if ( ls_azimuth_temp[j] < smallestAzimuth )
1585 : {
1586 114665 : smallestAzimuth = ls_azimuth_temp[j];
1587 114665 : smallestAzimuthIndex = j;
1588 : }
1589 : }
1590 61013 : ls_azimuth_order[i] = smallestAzimuthIndex;
1591 61013 : ls_azimuth_temp[smallestAzimuthIndex] = 1000.0f;
1592 : }
1593 :
1594 11824 : if ( oddLayout )
1595 : {
1596 5575 : startAzimuth = -lsSpacing * ( (float) numChannelsHalf );
1597 : }
1598 : else
1599 : {
1600 6249 : startAzimuth = -lsSpacing * ( (float) numChannelsHalf - 0.5f );
1601 : }
1602 :
1603 72837 : for ( i = 0; i < numChannels; i++ )
1604 : {
1605 61013 : ls_azimuth_even_ordered[i] = (float) i * lsSpacing + startAzimuth;
1606 : }
1607 :
1608 72837 : for ( i = 0; i < numChannels; i++ )
1609 : {
1610 61013 : ls_azimuth_even[ls_azimuth_order[i]] = roundf( ls_azimuth_even_ordered[i] );
1611 : }
1612 :
1613 11824 : return;
1614 : }
1615 :
1616 190840 : static void computeLfeEnergy(
1617 : MCMASA_ENC_HANDLE hMcMasa,
1618 : float *data_f[],
1619 : const int16_t input_frame )
1620 : {
1621 : int16_t l_ts;
1622 : int16_t block_m_idx;
1623 : int16_t mrange[2];
1624 : int16_t separateChannelIndex;
1625 : int16_t lfeChannelIndex;
1626 : float *pcm_in[1];
1627 :
1628 :
1629 190840 : l_ts = input_frame / MDFT_NO_COL_MAX;
1630 190840 : separateChannelIndex = hMcMasa->separateChannelIndex;
1631 190840 : lfeChannelIndex = LFE_CHANNEL;
1632 :
1633 190840 : if ( hMcMasa->separateChannelEnabled )
1634 : {
1635 36974 : mvr2r( data_f[lfeChannelIndex], &( hMcMasa->delay_buffer_lfe[0][hMcMasa->num_samples_delay_comp - hMcMasa->offset_comp] ), hMcMasa->offset_comp );
1636 36974 : mvr2r( data_f[separateChannelIndex], &( hMcMasa->delay_buffer_lfe[1][hMcMasa->num_samples_delay_comp - hMcMasa->offset_comp] ), hMcMasa->offset_comp );
1637 : }
1638 : else
1639 : {
1640 153866 : pcm_in[0] = &data_f[lfeChannelIndex][0];
1641 : }
1642 :
1643 : /* Reset variables */
1644 190840 : set_zero( hMcMasa->lfeLfEne, MAX_PARAM_SPATIAL_SUBFRAMES );
1645 190840 : set_zero( hMcMasa->totalLfEne, MAX_PARAM_SPATIAL_SUBFRAMES );
1646 :
1647 : /* Compute low-frequency energies */
1648 190840 : if ( hMcMasa->separateChannelEnabled ) /* Using low-pass filter */
1649 : {
1650 : float lowpassCoef;
1651 : int16_t i, j;
1652 : float delayedInputSignal[2][L_FRAME48k];
1653 : float lowPassSignal[2][L_FRAME48k];
1654 :
1655 36974 : mvr2r( &( hMcMasa->delay_buffer_lfe[0][0] ), &( delayedInputSignal[0][0] ), hMcMasa->num_slots_delay_comp * l_ts );
1656 36974 : mvr2r( data_f[lfeChannelIndex] + hMcMasa->offset_comp, &( delayedInputSignal[0][hMcMasa->num_slots_delay_comp * l_ts] ), ( MDFT_NO_COL_MAX - hMcMasa->num_slots_delay_comp ) * l_ts );
1657 36974 : mvr2r( &( hMcMasa->delay_buffer_lfe[1][0] ), &( delayedInputSignal[1][0] ), hMcMasa->num_slots_delay_comp * l_ts );
1658 36974 : mvr2r( data_f[separateChannelIndex] + hMcMasa->offset_comp, &( delayedInputSignal[1][hMcMasa->num_slots_delay_comp * l_ts] ), ( MDFT_NO_COL_MAX - hMcMasa->num_slots_delay_comp ) * l_ts );
1659 :
1660 36974 : lowpassCoef = 1.0f / ( (float) hMcMasa->ringBufferSize );
1661 :
1662 35292014 : for ( i = 0; i < input_frame; i++ )
1663 : {
1664 105765120 : for ( j = 0; j < 2; j++ )
1665 : {
1666 70510080 : hMcMasa->lowpassSum[j] += lowpassCoef * delayedInputSignal[j][i] - lowpassCoef * hMcMasa->lfeAnaRingBuffer[j][hMcMasa->ringBufferPointer];
1667 70510080 : lowPassSignal[j][i] = hMcMasa->lowpassSum[j];
1668 70510080 : hMcMasa->lfeAnaRingBuffer[j][hMcMasa->ringBufferPointer] = delayedInputSignal[j][i];
1669 : }
1670 :
1671 35255040 : hMcMasa->ringBufferPointer--;
1672 35255040 : if ( hMcMasa->ringBufferPointer < 0 )
1673 : {
1674 147896 : hMcMasa->ringBufferPointer = hMcMasa->ringBufferSize - 1;
1675 : }
1676 : }
1677 :
1678 184870 : for ( block_m_idx = 0; block_m_idx < MAX_PARAM_SPATIAL_SUBFRAMES; block_m_idx++ )
1679 : {
1680 147896 : mrange[0] = hMcMasa->block_grouping[block_m_idx] * l_ts;
1681 147896 : mrange[1] = hMcMasa->block_grouping[block_m_idx + 1] * l_ts;
1682 :
1683 35402936 : for ( i = mrange[0]; i < mrange[1]; i++ )
1684 : {
1685 35255040 : hMcMasa->lfeLfEne[block_m_idx] += lowPassSignal[0][i] * lowPassSignal[0][i];
1686 35255040 : hMcMasa->totalLfEne[block_m_idx] += lowPassSignal[1][i] * lowPassSignal[1][i];
1687 : }
1688 147896 : hMcMasa->totalLfEne[block_m_idx] += hMcMasa->lfeLfEne[block_m_idx];
1689 : }
1690 : }
1691 : else /* Using CLDFB */
1692 : {
1693 : int16_t ts;
1694 : int16_t i;
1695 : float Chnl_RealBuffer[2][DIRAC_NO_FB_BANDS_MAX];
1696 : float Chnl_ImagBuffer[2][DIRAC_NO_FB_BANDS_MAX];
1697 : float *p_Chnl_RealBuffer[2];
1698 : float *p_Chnl_ImagBuffer[2];
1699 :
1700 153866 : p_Chnl_RealBuffer[0] = &Chnl_RealBuffer[0][0];
1701 153866 : p_Chnl_RealBuffer[1] = &Chnl_RealBuffer[1][0];
1702 153866 : p_Chnl_ImagBuffer[0] = &Chnl_ImagBuffer[0][0];
1703 153866 : p_Chnl_ImagBuffer[1] = &Chnl_ImagBuffer[1][0];
1704 :
1705 769330 : for ( block_m_idx = 0; block_m_idx < MAX_PARAM_SPATIAL_SUBFRAMES; block_m_idx++ )
1706 : {
1707 615464 : mrange[0] = hMcMasa->block_grouping[block_m_idx];
1708 615464 : mrange[1] = hMcMasa->block_grouping[block_m_idx + 1];
1709 :
1710 1230928 : for ( ts = mrange[0]; ts < mrange[1]; ts++ )
1711 : {
1712 615464 : ivas_fb_mixer_get_windowed_fr( hMcMasa->hFbMixerLfe, pcm_in, p_Chnl_RealBuffer, p_Chnl_ImagBuffer, l_ts, l_ts, hMcMasa->hFbMixerLfe->fb_cfg->num_in_chans );
1713 :
1714 615464 : ivas_fb_mixer_update_prior_input( hMcMasa->hFbMixerLfe, pcm_in, l_ts, hMcMasa->hFbMixerLfe->fb_cfg->num_in_chans );
1715 :
1716 615464 : pcm_in[0] += l_ts;
1717 :
1718 : /* Compute low frequency energy for LFE, for other channels it is computed in ivas_chnl_param_est_enc() */
1719 3077320 : for ( i = 0; i < CLDFB_TO_MDFT_FAC; i++ )
1720 : {
1721 2461856 : hMcMasa->lfeLfEne[block_m_idx] += Chnl_RealBuffer[0][i] * Chnl_RealBuffer[0][i] + Chnl_ImagBuffer[0][i] * Chnl_ImagBuffer[0][i];
1722 : }
1723 : }
1724 : }
1725 : }
1726 :
1727 190840 : if ( hMcMasa->separateChannelEnabled )
1728 : {
1729 36974 : mvr2r( data_f[lfeChannelIndex] + ( input_frame - hMcMasa->num_samples_delay_comp + hMcMasa->offset_comp ), &( hMcMasa->delay_buffer_lfe[0][0] ), ( hMcMasa->num_samples_delay_comp - hMcMasa->offset_comp ) );
1730 36974 : mvr2r( data_f[separateChannelIndex] + ( input_frame - hMcMasa->num_samples_delay_comp + hMcMasa->offset_comp ), &( hMcMasa->delay_buffer_lfe[1][0] ), ( hMcMasa->num_samples_delay_comp - hMcMasa->offset_comp ) );
1731 : }
1732 :
1733 190840 : return;
1734 : }
|