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