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 7070 : 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 7070 : error = IVAS_ERR_OK;
109 :
110 7070 : assert( st_ivas->hMasa != NULL && "MASA encoder handle is not present" );
111 7070 : hMasa = st_ivas->hMasa;
112 :
113 7070 : 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 7070 : nchan_inp = st_ivas->hEncoderConfig->nchan_inp;
119 7070 : input_Fs = st_ivas->hEncoderConfig->input_Fs;
120 :
121 : /* Determine if to separate some channels from the analysis */
122 7070 : ivas_mcmasa_set_separate_channel_mode( &( hMcMasa->separateChannelEnabled ), &( hMcMasa->separateChannelIndex ), st_ivas->hEncoderConfig->ivas_total_brate );
123 :
124 7070 : numAnalysisChannels = nchan_inp - 1;
125 7070 : 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 7070 : 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 7070 : hMcMasa->nbands = st_ivas->hMasa->config.numCodingBands;
139 7070 : hMcMasa->nCodingBands = st_ivas->hMasa->config.numCodingBands;
140 :
141 : /* Determine band grouping */
142 7070 : 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 7070 : band_mapping = hMasa->data.band_mapping;
152 49490 : for ( i = 0; i < hMcMasa->nbands + 1; i++ )
153 : {
154 42420 : hMcMasa->band_grouping[i] = MASA_band_grouping_24[band_mapping[i]] * CLDFB_TO_MDFT_FAC;
155 : }
156 : }
157 :
158 7070 : maxBin = (int16_t) ( input_Fs * INV_CLDFB_BANDWIDTH * CLDFB_TO_MDFT_FAC + 0.5f );
159 :
160 35350 : for ( i = 1; i < hMcMasa->nbands + 1; i++ )
161 : {
162 35350 : if ( hMcMasa->band_grouping[i] >= maxBin )
163 : {
164 7070 : hMcMasa->band_grouping[i] = maxBin;
165 7070 : hMcMasa->nbands = i;
166 7070 : break;
167 : }
168 : }
169 :
170 : /* initialize delay compensation */
171 7070 : 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 7070 : tmp_f = (float) hMcMasa->num_samples_delay_comp / (float) ( NS2SA( input_Fs, DIRAC_SLOT_ENC_NS ) );
176 7070 : hMcMasa->num_slots_delay_comp = (int16_t) ( tmp_f );
177 :
178 7070 : if ( tmp_f > (float) hMcMasa->num_slots_delay_comp )
179 : {
180 7070 : hMcMasa->num_slots_delay_comp++;
181 7070 : hMcMasa->offset_comp = -hMcMasa->num_samples_delay_comp;
182 7070 : hMcMasa->num_samples_delay_comp = hMcMasa->num_slots_delay_comp * NS2SA( input_Fs, DIRAC_SLOT_ENC_NS );
183 7070 : 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 7070 : 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 7070 : 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 7070 : if ( hMcMasa->separateChannelEnabled )
204 : {
205 : /* TD Energy calculation with LP */
206 1535 : 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 1535 : set_zero( hMcMasa->delay_buffer_lfe[0], NS2SA( input_Fs, DELAY_DIRAC_ENC_CMP_NS + DIRAC_SLOT_ENC_NS ) );
211 :
212 1535 : 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 1535 : set_zero( hMcMasa->delay_buffer_lfe[1], NS2SA( input_Fs, DELAY_DIRAC_ENC_CMP_NS + DIRAC_SLOT_ENC_NS ) );
217 1535 : hMcMasa->hFbMixerLfe = NULL;
218 : }
219 : else
220 : {
221 : /* Allocate and initialize FB mixer handle for LFE channel */
222 5535 : 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 5535 : if ( ( error = ivas_FB_mixer_open( &( hMcMasa->hFbMixerLfe ), input_Fs, fb_cfgLfe, 0 ) ) != IVAS_ERR_OK )
228 : {
229 0 : return error;
230 : }
231 :
232 5535 : hMcMasa->delay_buffer_lfe[0] = NULL;
233 5535 : hMcMasa->delay_buffer_lfe[1] = NULL;
234 : }
235 :
236 7070 : 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 1535 : bufferSize = (int16_t) ( ( input_Fs / FRAMES_PER_SEC ) / MAX_PARAM_SPATIAL_SUBFRAMES );
243 4605 : for ( i = 0; i < 2; i++ )
244 : {
245 3070 : 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 3070 : set_zero( hMcMasa->lfeAnaRingBuffer[i], bufferSize );
250 3070 : hMcMasa->lowpassSum[i] = 0.0f;
251 : }
252 1535 : hMcMasa->ringBufferPointer = 0;
253 1535 : hMcMasa->ringBufferSize = bufferSize;
254 : }
255 :
256 :
257 7070 : dirac_slot_ns = DIRAC_SLOT_ENC_NS;
258 :
259 : /* intensity 3-dim */
260 28280 : for ( i = 0; i < DIRAC_NUM_DIMS; i++ )
261 : {
262 21210 : 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 106050 : for ( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ )
268 : {
269 84840 : 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 7070 : hMcMasa->no_col_avg_diff = (int8_t) ( DIRAC_NO_COL_AVG_DIFF_NS / dirac_slot_ns );
277 28280 : for ( i = 0; i < DIRAC_NUM_DIMS; i++ )
278 : {
279 21210 : 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 190890 : for ( j = 0; j < hMcMasa->no_col_avg_diff; j++ )
285 : {
286 169680 : 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 169680 : set_zero( hMcMasa->buffer_intensity_real[i][j], hMcMasa->nbands );
291 : }
292 : }
293 :
294 7070 : 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 63630 : for ( j = 0; j < hMcMasa->no_col_avg_diff; j++ )
300 : {
301 56560 : 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 56560 : set_zero( hMcMasa->buffer_intensity_real_vert[j], hMcMasa->nbands );
306 : }
307 :
308 7070 : 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 7070 : set_zero( hMcMasa->buffer_energy, hMcMasa->nbands * hMcMasa->no_col_avg_diff );
313 :
314 7070 : if ( st_ivas->hEncoderConfig->mc_input_setup == MC_LS_SETUP_5_1 )
315 : {
316 1807 : mvr2r( ls_azimuth_CICP6, ls_azimuth, nchan_inp - 1 );
317 1807 : mvr2r( ls_elevation_CICP6, ls_elevation, nchan_inp - 1 );
318 1807 : hMcMasa->numHorizontalChannels = 5;
319 1807 : hMcMasa->isHorizontalSetup = 1;
320 : }
321 5263 : else if ( st_ivas->hEncoderConfig->mc_input_setup == MC_LS_SETUP_7_1 )
322 : {
323 549 : mvr2r( ls_azimuth_CICP12, ls_azimuth, nchan_inp - 1 );
324 549 : mvr2r( ls_elevation_CICP12, ls_elevation, nchan_inp - 1 );
325 549 : hMcMasa->numHorizontalChannels = 7;
326 549 : hMcMasa->isHorizontalSetup = 1;
327 : }
328 4714 : else if ( st_ivas->hEncoderConfig->mc_input_setup == MC_LS_SETUP_5_1_2 )
329 : {
330 392 : mvr2r( ls_azimuth_CICP14, ls_azimuth, nchan_inp - 1 );
331 392 : mvr2r( ls_elevation_CICP14, ls_elevation, nchan_inp - 1 );
332 392 : hMcMasa->numHorizontalChannels = 5;
333 392 : hMcMasa->isHorizontalSetup = 0;
334 : }
335 4322 : else if ( st_ivas->hEncoderConfig->mc_input_setup == MC_LS_SETUP_5_1_4 )
336 : {
337 408 : mvr2r( ls_azimuth_CICP16, ls_azimuth, nchan_inp - 1 );
338 408 : mvr2r( ls_elevation_CICP16, ls_elevation, nchan_inp - 1 );
339 408 : hMcMasa->numHorizontalChannels = 5;
340 408 : hMcMasa->isHorizontalSetup = 0;
341 : }
342 : else
343 : {
344 3914 : mvr2r( ls_azimuth_CICP19, ls_azimuth, nchan_inp - 1 );
345 3914 : mvr2r( ls_elevation_CICP19, ls_elevation, nchan_inp - 1 );
346 3914 : hMcMasa->numHorizontalChannels = 7;
347 3914 : hMcMasa->isHorizontalSetup = 0;
348 : }
349 :
350 7070 : if ( hMcMasa->separateChannelEnabled )
351 : {
352 1535 : mvr2r( &ls_azimuth[hMcMasa->separateChannelIndex + 1], &ls_azimuth[hMcMasa->separateChannelIndex], numAnalysisChannels - hMcMasa->separateChannelIndex );
353 1535 : mvr2r( &ls_elevation[hMcMasa->separateChannelIndex + 1], &ls_elevation[hMcMasa->separateChannelIndex], numAnalysisChannels - hMcMasa->separateChannelIndex );
354 1535 : hMcMasa->numHorizontalChannels--;
355 : }
356 :
357 7070 : computeEvenLayout( ls_azimuth, ls_azimuth_even, hMcMasa->numHorizontalChannels );
358 7070 : if ( !hMcMasa->isHorizontalSetup )
359 : {
360 4714 : computeEvenLayout( &ls_azimuth[hMcMasa->numHorizontalChannels], &ls_azimuth_even[hMcMasa->numHorizontalChannels], numAnalysisChannels - hMcMasa->numHorizontalChannels );
361 : }
362 :
363 67883 : for ( i = 0; i < numAnalysisChannels; i++ )
364 : {
365 60813 : hMcMasa->chnlToFoaMtx[0][i] = 1.0f;
366 60813 : hMcMasa->chnlToFoaMtx[1][i] = sinf( ls_azimuth[i] * PI_OVER_180 ) * cosf( ls_elevation[i] * PI_OVER_180 );
367 60813 : hMcMasa->chnlToFoaMtx[2][i] = sinf( ls_elevation[i] * PI_OVER_180 );
368 60813 : hMcMasa->chnlToFoaMtx[3][i] = cosf( ls_azimuth[i] * PI_OVER_180 ) * cosf( ls_elevation[i] * PI_OVER_180 );
369 :
370 60813 : hMcMasa->chnlToFoaEvenMtx[0][i] = 1.0f;
371 60813 : hMcMasa->chnlToFoaEvenMtx[1][i] = sinf( ls_azimuth_even[i] * PI_OVER_180 );
372 60813 : hMcMasa->chnlToFoaEvenMtx[2][i] = 0.0f;
373 60813 : hMcMasa->chnlToFoaEvenMtx[3][i] = cosf( ls_azimuth_even[i] * PI_OVER_180 );
374 : }
375 :
376 7070 : hMcMasa->combineRatios = hMasa->config.mergeRatiosOverSubframes;
377 :
378 7070 : mvr2r( ls_azimuth, hMcMasa->ls_azimuth, numAnalysisChannels );
379 :
380 49811 : for ( i = 0; i < hMcMasa->numHorizontalChannels; i++ )
381 : {
382 42741 : left_min = 360.0f;
383 42741 : right_min = -360.0f;
384 :
385 307048 : for ( j = 0; j < hMcMasa->numHorizontalChannels; j++ )
386 : {
387 264307 : azi_diff = ls_azimuth[j] - ls_azimuth[i];
388 :
389 264307 : if ( azi_diff > 180.0f )
390 : {
391 16545 : azi_diff -= 360.0f;
392 : }
393 247762 : else if ( azi_diff < -180.0f )
394 : {
395 16545 : azi_diff += 360.0f;
396 : }
397 :
398 264307 : if ( azi_diff < left_min && azi_diff > 0.0f )
399 : {
400 69284 : hMcMasa->leftNearest[i] = j;
401 69284 : left_min = azi_diff;
402 : }
403 :
404 264307 : if ( azi_diff > right_min && azi_diff < 0.0f )
405 : {
406 62214 : hMcMasa->rightNearest[i] = j;
407 62214 : right_min = azi_diff;
408 : }
409 : }
410 : }
411 :
412 7070 : hMcMasa->prevMultiChEne = 0.0f;
413 7070 : hMcMasa->prevDownmixEne = 0.0f;
414 7070 : hMcMasa->prevEQ = 1.0f;
415 7070 : input_frame = (int16_t) ( input_Fs / FRAMES_PER_SEC );
416 6628830 : for ( i = 0; i < input_frame; i++ )
417 : {
418 6621760 : hMcMasa->interpolator[i] = ( (float) i ) / ( (float) input_frame );
419 : }
420 :
421 7070 : mvs2s( DirAC_block_grouping_5ms_MDFT, hMcMasa->block_grouping, MAX_PARAM_SPATIAL_SUBFRAMES + 1 );
422 :
423 7070 : hMcMasa->index_buffer_intensity = 0;
424 :
425 7070 : st_ivas->hMcMasa = hMcMasa;
426 :
427 7070 : return error;
428 : }
429 :
430 :
431 : /*-------------------------------------------------------------------------
432 : * ivas_mcmasa_enc_reconfig()
433 : *
434 : * Reconfigure McMASA encoder
435 : *------------------------------------------------------------------------*/
436 :
437 2234 : 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 2234 : error = IVAS_ERR_OK;
445 :
446 2234 : ivas_total_brate = st_ivas->hEncoderConfig->ivas_total_brate;
447 :
448 2234 : 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 2234 : ivas_masa_enc_close( &( st_ivas->hMasa ) );
454 2234 : ivas_mcmasa_enc_close( &( st_ivas->hMcMasa ), st_ivas->hEncoderConfig->input_Fs );
455 :
456 : /* Determine if to separate some channels from the analysis */
457 2234 : ivas_mcmasa_setNumTransportChannels( &( st_ivas->nchan_transport ), &( st_ivas->hEncoderConfig->element_mode_init ), ivas_total_brate );
458 :
459 2234 : if ( ( error = ivas_masa_enc_open( st_ivas ) ) != IVAS_ERR_OK )
460 : {
461 0 : return error;
462 : }
463 :
464 2234 : 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 2234 : return error;
473 : }
474 :
475 : /*--------------------------------------------------------------------------*
476 : * ivas_mcmasa_enc_close()
477 : *
478 : *
479 : *--------------------------------------------------------------------------*/
480 :
481 19935 : 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 19935 : if ( hMcMasa == NULL || *hMcMasa == NULL )
489 : {
490 12865 : return;
491 : }
492 :
493 7070 : if ( ( *hMcMasa )->separateChannelEnabled )
494 : {
495 1535 : free( ( *hMcMasa )->delay_buffer_lfe[0] );
496 1535 : free( ( *hMcMasa )->delay_buffer_lfe[1] );
497 :
498 4605 : for ( i = 0; i < 2; i++ )
499 : {
500 3070 : free( ( *hMcMasa )->lfeAnaRingBuffer[i] );
501 : }
502 : }
503 :
504 7070 : ivas_FB_mixer_close( &( *hMcMasa )->hFbMixer, input_Fs, 0 );
505 :
506 7070 : if ( !( *hMcMasa )->separateChannelEnabled )
507 : {
508 5535 : ivas_FB_mixer_close( &( *hMcMasa )->hFbMixerLfe, input_Fs, 0 );
509 : }
510 :
511 : /* intensity 3-dim */
512 28280 : for ( i = 0; i < DIRAC_NUM_DIMS; i++ )
513 : {
514 106050 : for ( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ )
515 : {
516 84840 : free( ( *hMcMasa )->direction_vector_m[i][j] );
517 84840 : ( *hMcMasa )->direction_vector_m[i][j] = NULL;
518 : }
519 :
520 190890 : for ( j = 0; j < ( *hMcMasa )->no_col_avg_diff; j++ )
521 : {
522 169680 : free( ( *hMcMasa )->buffer_intensity_real[i][j] );
523 169680 : ( *hMcMasa )->buffer_intensity_real[i][j] = NULL;
524 : }
525 :
526 21210 : free( ( *hMcMasa )->buffer_intensity_real[i] );
527 21210 : ( *hMcMasa )->buffer_intensity_real[i] = NULL;
528 :
529 21210 : free( ( *hMcMasa )->direction_vector_m[i] );
530 21210 : ( *hMcMasa )->direction_vector_m[i] = NULL;
531 : }
532 :
533 63630 : for ( j = 0; j < ( *hMcMasa )->no_col_avg_diff; j++ )
534 : {
535 56560 : free( ( *hMcMasa )->buffer_intensity_real_vert[j] );
536 56560 : ( *hMcMasa )->buffer_intensity_real_vert[j] = NULL;
537 : }
538 7070 : free( ( *hMcMasa )->buffer_intensity_real_vert );
539 7070 : ( *hMcMasa )->buffer_intensity_real_vert = NULL;
540 :
541 7070 : free( ( *hMcMasa )->buffer_energy );
542 7070 : ( *hMcMasa )->buffer_energy = NULL;
543 :
544 7070 : free( ( *hMcMasa ) );
545 7070 : ( *hMcMasa ) = NULL;
546 :
547 7070 : return;
548 : }
549 :
550 :
551 : /*--------------------------------------------------------------------------*
552 : * ivas_mcmasa_enc()
553 : *
554 : * Multichannel MASA encoder
555 : *--------------------------------------------------------------------------*/
556 :
557 190640 : 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 190640 : int16_t nBands = hMcMasa->nbands;
569 190640 : int16_t nBlocks = MAX_PARAM_SPATIAL_SUBFRAMES;
570 190640 : 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 190640 : computeLfeEnergy( hMcMasa, data_f, input_frame );
580 :
581 : /* Sum center and LFE, move surround channels */
582 190640 : v_add( data_f[2], data_f[3], data_f[2], input_frame );
583 1024128 : for ( i = 4; i < nchan_inp; i++ )
584 : {
585 833488 : mvr2r( data_f[i], data_f[i - 1], input_frame );
586 : }
587 :
588 190640 : if ( hMcMasa->separateChannelEnabled )
589 : {
590 : /* Identify channel to separate */
591 36974 : i = hMcMasa->separateChannelIndex;
592 :
593 : /* Separate the identified channel */
594 36974 : mvr2r( data_f[i], separatedChannelSignal, input_frame );
595 :
596 : /* Move the remaining channels in order to perform the analysis without the separated channel */
597 329966 : for ( i = ( hMcMasa->separateChannelIndex + 1 ); i < ( nchan_inp - 1 ); i++ )
598 : {
599 292992 : mvr2r( data_f[i], data_f[i - 1], input_frame );
600 : }
601 : }
602 :
603 : /* Analysis */
604 190640 : 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 953200 : for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ )
608 : {
609 762560 : hMasa->data.lfeToTotalEnergyRatio[i] = hMcMasa->lfeLfEne[i] / ( EPSILON + hMcMasa->totalLfEne[i] );
610 : }
611 :
612 : /* Set analyzed values to the MASA struct */
613 1143840 : for ( i = 0; i < nBands; i++ )
614 : {
615 4766000 : for ( j = 0; j < nBlocks; j++ )
616 : {
617 3812800 : if ( hMcMasa->combineRatios )
618 : {
619 3812800 : k = 0;
620 : }
621 : else
622 : {
623 0 : k = j;
624 : }
625 :
626 3812800 : hQMeta->q_direction[0].band_data[i].azimuth[j] = azimuth_m_values[j][i];
627 3812800 : hQMeta->q_direction[0].band_data[i].elevation[j] = elevation_m_values[j][i];
628 3812800 : hQMeta->q_direction[0].band_data[i].energy_ratio[j] = energyRatio[k][i];
629 3812800 : hQMeta->q_direction[0].band_data[i].distance[j] = fixedDistance;
630 :
631 3812800 : if ( hQMeta->surcoh_band_data != NULL )
632 : {
633 3481920 : hQMeta->q_direction[0].coherence_band_data[i].spread_coherence[j] = (uint8_t) roundf( spreadCoherence[j][i] * UINT8_MAX );
634 3481920 : 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 190640 : 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 190640 : ivas_mcmasa_dmx( hMcMasa, data_f, input_frame, nchan_transport, nchan_inp );
662 :
663 190640 : if ( hMcMasa->separateChannelEnabled )
664 : {
665 : /* Put separated channel back to data_f to first empty channel after the transport audio signals for encoding */
666 36974 : 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 190640 : hMasa->config.joinedSubframes = FALSE;
672 190640 : hQMeta->q_direction[0].cfg.nbands = hMcMasa->nbands;
673 190640 : hQMeta->q_direction[0].cfg.nblocks = MAX_PARAM_SPATIAL_SUBFRAMES;
674 190640 : hQMeta->all_coherence_zero = 1;
675 :
676 : /* Check spread coherence */
677 190640 : i = 0;
678 480560 : while ( i < nBlocks && hQMeta->all_coherence_zero )
679 : {
680 289920 : j = 0;
681 1140323 : while ( j < nBands && hQMeta->all_coherence_zero )
682 : {
683 850403 : if ( spreadCoherence[i][j] > MASA_COHERENCE_THRESHOLD )
684 : {
685 168710 : hQMeta->all_coherence_zero = 0;
686 : }
687 850403 : j++;
688 : }
689 289920 : i++;
690 : }
691 :
692 : /* Check surrounding coherence */
693 190640 : 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 21930 : nSubFrames = hMcMasa->combineRatios ? 1 : MAX_PARAM_SPATIAL_SUBFRAMES;
700 43860 : for ( i = 0; i < nSubFrames; i++ )
701 : {
702 131580 : for ( j = 0; j < nBands; j++ )
703 : {
704 109650 : diffuse_to_total_ratio[i][j] = fmaxf( 0.0f, 1.0f - energyRatio[i][j] );
705 : }
706 : }
707 :
708 21930 : cohSignificant = ivas_masa_surrcoh_signicant( surroundingCoherence, diffuse_to_total_ratio, nSubFrames, nBands );
709 21930 : if ( cohSignificant )
710 : {
711 14253 : hQMeta->all_coherence_zero = 0;
712 : }
713 : }
714 190640 : hMasa->config.coherencePresent = !hQMeta->all_coherence_zero;
715 :
716 190640 : return;
717 : }
718 :
719 :
720 : /*--------------------------------------------------------------------------*
721 : * ivas_mcmasa_param_est_enc()
722 : *
723 : * Estimate metadata parameters for McMASA
724 : *--------------------------------------------------------------------------*/
725 :
726 190640 : 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 190640 : num_freq_bins = input_frame / MDFT_NO_COL_MAX;
783 190640 : num_freq_bands = hMcMasa->nbands;
784 190640 : l_ts = input_frame / MDFT_NO_COL_MAX;
785 :
786 190640 : numAnalysisChannels = nchan_inp - 1;
787 190640 : if ( hMcMasa->separateChannelEnabled )
788 : {
789 36974 : numAnalysisChannels = nchan_inp - 2;
790 : }
791 :
792 190640 : if ( hMcMasa->combineRatios )
793 : {
794 : /* Need to initialize renormalization_factors, and variables to be normalized */
795 190640 : set_zero( renormalization_factor_diff, hMcMasa->nbands );
796 190640 : set_zero( diffuseness_m[0], hMcMasa->nbands );
797 190640 : set_zero( renormalization_factor_coh, hMcMasa->nbands );
798 190640 : set_zero( surroundingCoherence[0], hMcMasa->nbands );
799 190640 : set_zero( coherentEnergyRatio[0], hMcMasa->nbands );
800 : }
801 :
802 : /* Copy current frame to memory for delay compensation */
803 1559074 : for ( i = 0; i < numAnalysisChannels; i++ )
804 : {
805 1368434 : pcm_in[i] = data_f[i];
806 1368434 : p_Chnl_RealBuffer[i] = &Chnl_RealBuffer[i][0];
807 1368434 : p_Chnl_ImagBuffer[i] = &Chnl_ImagBuffer[i][0];
808 : }
809 :
810 : /* do processing over all CLDFB time slots */
811 953200 : for ( block_m_idx = 0; block_m_idx < MAX_PARAM_SPATIAL_SUBFRAMES; block_m_idx++ )
812 : {
813 762560 : mrange[0] = hMcMasa->block_grouping[block_m_idx];
814 762560 : mrange[1] = hMcMasa->block_grouping[block_m_idx + 1];
815 :
816 4575360 : for ( band_m_idx = 0; band_m_idx < hMcMasa->nbands; band_m_idx++ )
817 : {
818 3812800 : hMcMasa->direction_vector_m[0][block_m_idx][band_m_idx] = 0;
819 3812800 : hMcMasa->direction_vector_m[1][block_m_idx][band_m_idx] = 0;
820 3812800 : hMcMasa->direction_vector_m[2][block_m_idx][band_m_idx] = 0;
821 : }
822 :
823 : /* Reset variable */
824 4575360 : for ( i = 0; i < hMcMasa->nbands; i++ )
825 : {
826 31181480 : for ( j = 0; j < numAnalysisChannels; j++ )
827 : {
828 27368680 : set_zero( COVls[i].xr[j], numAnalysisChannels );
829 27368680 : set_zero( COVls[i].xi[j], numAnalysisChannels );
830 : }
831 : }
832 :
833 1525120 : for ( ts = mrange[0]; ts < mrange[1]; ts++ )
834 : {
835 762560 : 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 762560 : ivas_fb_mixer_update_prior_input( hMcMasa->hFbMixer, pcm_in, l_ts, hMcMasa->hFbMixer->fb_cfg->num_in_chans );
838 :
839 6236296 : for ( i = 0; i < numAnalysisChannels; i++ )
840 : {
841 5473736 : pcm_in[i] += l_ts;
842 : }
843 :
844 : /* Compute covariance matrix */
845 4575360 : for ( i = 0; i < num_freq_bands; i++ )
846 : {
847 3812800 : brange[0] = hMcMasa->band_grouping[i];
848 3812800 : brange[1] = hMcMasa->band_grouping[i + 1];
849 184785600 : for ( j = brange[0]; j < brange[1]; j++ )
850 : {
851 180972800 : compute_cov_mtx( Chnl_RealBuffer, Chnl_ImagBuffer, j, numAnalysisChannels, &( COVls[i] ) );
852 : }
853 :
854 : /* Store energies for guiding metadata encoding */
855 3812800 : hMasa->data.energy[block_m_idx][i] = 0.0f;
856 31181480 : for ( j = 0; j < numAnalysisChannels; j++ )
857 : {
858 27368680 : hMasa->data.energy[block_m_idx][i] += COVls[i].xr[j][j];
859 : }
860 : }
861 :
862 762560 : if ( !hMcMasa->separateChannelEnabled )
863 : {
864 : /* Compute low frequency energy */
865 4620640 : for ( i = 0; i < numAnalysisChannels; i++ )
866 : {
867 20029880 : for ( j = 0; j < CLDFB_TO_MDFT_FAC; j++ )
868 : {
869 16023904 : 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 762560 : v_add( Chnl_RealBuffer[0], Chnl_RealBuffer[1], Foa_RealBuffer[0], num_freq_bins );
877 762560 : v_add( Chnl_ImagBuffer[0], Chnl_ImagBuffer[1], Foa_ImagBuffer[0], num_freq_bins );
878 4711176 : for ( i = 2; i < numAnalysisChannels; i++ )
879 : {
880 3948616 : v_add( Chnl_RealBuffer[i], Foa_RealBuffer[0], Foa_RealBuffer[0], num_freq_bins );
881 3948616 : v_add( Chnl_ImagBuffer[i], Foa_ImagBuffer[0], Foa_ImagBuffer[0], num_freq_bins );
882 : }
883 :
884 : /* Y */
885 762560 : v_multc( Chnl_RealBuffer[0], hMcMasa->chnlToFoaMtx[1][0], Foa_RealBuffer[1], num_freq_bins );
886 762560 : v_multc( Chnl_ImagBuffer[0], hMcMasa->chnlToFoaMtx[1][0], Foa_ImagBuffer[1], num_freq_bins );
887 5473736 : for ( i = 1; i < numAnalysisChannels; i++ )
888 : {
889 4711176 : v_multc_acc( Chnl_RealBuffer[i], hMcMasa->chnlToFoaMtx[1][i], Foa_RealBuffer[1], num_freq_bins );
890 4711176 : v_multc_acc( Chnl_ImagBuffer[i], hMcMasa->chnlToFoaMtx[1][i], Foa_ImagBuffer[1], num_freq_bins );
891 : }
892 :
893 : /* Z */
894 762560 : if ( hMcMasa->isHorizontalSetup )
895 : {
896 : /* Set zero for horizontal setups */
897 416504 : set_zero( Foa_RealBuffer[2], num_freq_bins );
898 416504 : set_zero( Foa_ImagBuffer[2], num_freq_bins );
899 : }
900 : else
901 : {
902 346056 : v_multc( Chnl_RealBuffer[0], hMcMasa->chnlToFoaMtx[2][0], Foa_RealBuffer[2], num_freq_bins );
903 346056 : v_multc( Chnl_ImagBuffer[0], hMcMasa->chnlToFoaMtx[2][0], Foa_ImagBuffer[2], num_freq_bins );
904 3340336 : for ( i = 1; i < numAnalysisChannels; i++ )
905 : {
906 2994280 : v_multc_acc( Chnl_RealBuffer[i], hMcMasa->chnlToFoaMtx[2][i], Foa_RealBuffer[2], num_freq_bins );
907 2994280 : v_multc_acc( Chnl_ImagBuffer[i], hMcMasa->chnlToFoaMtx[2][i], Foa_ImagBuffer[2], num_freq_bins );
908 : }
909 : }
910 :
911 : /* X */
912 762560 : v_multc( Chnl_RealBuffer[0], hMcMasa->chnlToFoaMtx[3][0], Foa_RealBuffer[3], num_freq_bins );
913 762560 : v_multc( Chnl_ImagBuffer[0], hMcMasa->chnlToFoaMtx[3][0], Foa_ImagBuffer[3], num_freq_bins );
914 5473736 : for ( i = 1; i < numAnalysisChannels; i++ )
915 : {
916 4711176 : v_multc_acc( Chnl_RealBuffer[i], hMcMasa->chnlToFoaMtx[3][i], Foa_RealBuffer[3], num_freq_bins );
917 4711176 : 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 762560 : mvr2r( Foa_RealBuffer[0], FoaEven_RealBuffer[0], num_freq_bins );
923 762560 : mvr2r( Foa_ImagBuffer[0], FoaEven_ImagBuffer[0], num_freq_bins );
924 :
925 : /* Y */
926 762560 : v_multc( Chnl_RealBuffer[0], hMcMasa->chnlToFoaEvenMtx[1][0], FoaEven_RealBuffer[1], num_freq_bins );
927 762560 : v_multc( Chnl_ImagBuffer[0], hMcMasa->chnlToFoaEvenMtx[1][0], FoaEven_ImagBuffer[1], num_freq_bins );
928 5473736 : for ( i = 1; i < numAnalysisChannels; i++ )
929 : {
930 4711176 : v_multc_acc( Chnl_RealBuffer[i], hMcMasa->chnlToFoaEvenMtx[1][i], FoaEven_RealBuffer[1], num_freq_bins );
931 4711176 : 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 762560 : set_zero( FoaEven_RealBuffer[2], num_freq_bins );
936 762560 : set_zero( FoaEven_ImagBuffer[2], num_freq_bins );
937 :
938 : /* X */
939 762560 : v_multc( Chnl_RealBuffer[0], hMcMasa->chnlToFoaEvenMtx[3][0], FoaEven_RealBuffer[3], num_freq_bins );
940 762560 : v_multc( Chnl_ImagBuffer[0], hMcMasa->chnlToFoaEvenMtx[3][0], FoaEven_ImagBuffer[3], num_freq_bins );
941 5473736 : for ( i = 1; i < numAnalysisChannels; i++ )
942 : {
943 4711176 : v_multc_acc( Chnl_RealBuffer[i], hMcMasa->chnlToFoaEvenMtx[3][i], FoaEven_RealBuffer[3], num_freq_bins );
944 4711176 : v_multc_acc( Chnl_ImagBuffer[i], hMcMasa->chnlToFoaEvenMtx[3][i], FoaEven_ImagBuffer[3], num_freq_bins );
945 : }
946 :
947 : /* Direction estimation */
948 762560 : computeIntensityVector_enc(
949 762560 : hMcMasa->band_grouping,
950 : Foa_RealBuffer,
951 : Foa_ImagBuffer,
952 : 0,
953 : num_freq_bands,
954 : intensity_real );
955 :
956 762560 : 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 762560 : computeIntensityVector_enc(
968 762560 : hMcMasa->band_grouping,
969 : FoaEven_RealBuffer,
970 : FoaEven_ImagBuffer,
971 : 0,
972 : num_freq_bands,
973 : intensity_even_real );
974 :
975 762560 : computeReferencePower_enc( hMcMasa->band_grouping,
976 : FoaEven_RealBuffer,
977 : FoaEven_ImagBuffer,
978 762560 : 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 762560 : hMcMasa->index_buffer_intensity = ( hMcMasa->index_buffer_intensity % hMcMasa->no_col_avg_diff ) + 1; /* averaging_length = 32 */
989 762560 : index = hMcMasa->index_buffer_intensity;
990 3050240 : for ( i = 0; i < DIRAC_NUM_DIMS; i++ )
991 : {
992 : /* only real part needed */
993 2287680 : mvr2r( intensity_even_real[i], &( hMcMasa->buffer_intensity_real[i][index - 1][0] ), num_freq_bands );
994 : }
995 762560 : mvr2r( reference_power[ts], &( hMcMasa->buffer_energy[( index - 1 ) * num_freq_bands] ), num_freq_bands );
996 :
997 762560 : 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 762560 : if ( !hMcMasa->isHorizontalSetup )
1001 : {
1002 346056 : mvr2r( intensity_real[2], &( hMcMasa->buffer_intensity_real_vert[index - 1][0] ), num_freq_bands );
1003 346056 : computeVerticalDiffuseness( hMcMasa->buffer_intensity_real_vert, hMcMasa->buffer_energy, hMcMasa->no_col_avg_diff, num_freq_bands, vertical_diffuseness_vector );
1004 346056 : v_min( diffuseness_vector, vertical_diffuseness_vector, diffuseness_vector, num_freq_bands );
1005 : }
1006 :
1007 4575360 : for ( band_m_idx = 0; band_m_idx < hMcMasa->nbands; band_m_idx++ )
1008 : {
1009 3812800 : norm_tmp = reference_power[ts][band_m_idx] * ( 1 - diffuseness_vector[band_m_idx] );
1010 :
1011 3812800 : hMcMasa->direction_vector_m[0][block_m_idx][band_m_idx] += norm_tmp * direction_vector[0][band_m_idx];
1012 3812800 : hMcMasa->direction_vector_m[1][block_m_idx][band_m_idx] += norm_tmp * direction_vector[1][band_m_idx];
1013 3812800 : hMcMasa->direction_vector_m[2][block_m_idx][band_m_idx] += norm_tmp * direction_vector[2][band_m_idx];
1014 :
1015 3812800 : if ( hMcMasa->combineRatios )
1016 : {
1017 3812800 : diffuseness_m[0][band_m_idx] += reference_power[ts][band_m_idx] * diffuseness_vector[band_m_idx];
1018 3812800 : 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 4575360 : for ( band_m_idx = 0; band_m_idx < hMcMasa->nbands; band_m_idx++ )
1028 : {
1029 15251200 : for ( d = 0; d < DIRAC_NUM_DIMS; d++ )
1030 : {
1031 11438400 : dir_v[d] = hMcMasa->direction_vector_m[d][block_m_idx][band_m_idx];
1032 : }
1033 3812800 : 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 4575360 : for ( band_m_idx = 0; band_m_idx < hMcMasa->nbands; band_m_idx++ )
1038 : {
1039 : /* Compute absolute values */
1040 31181480 : for ( i = 0; i < numAnalysisChannels; i++ )
1041 : {
1042 150708800 : for ( j = i; j < numAnalysisChannels; j++ )
1043 : {
1044 123340120 : 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 27368680 : lsEnergy[i] = absCOVls[i][i];
1047 : }
1048 :
1049 : /* Find loudest channel */
1050 3812800 : maxEne = lsEnergy[0];
1051 3812800 : loudestCh = 0;
1052 27368680 : for ( i = 1; i < numAnalysisChannels; i++ )
1053 : {
1054 23555880 : if ( lsEnergy[i] > maxEne )
1055 : {
1056 6676810 : maxEne = lsEnergy[i];
1057 6676810 : loudestCh = i;
1058 : }
1059 : }
1060 :
1061 : /* Compute surrounding coherence */
1062 3812800 : surrCoh = 1.0f;
1063 31181480 : for ( i = 0; i < numAnalysisChannels; i++ )
1064 : {
1065 27368680 : if ( i != loudestCh )
1066 : {
1067 23555880 : if ( i < loudestCh )
1068 : {
1069 12184248 : i1 = i;
1070 12184248 : i2 = loudestCh;
1071 : }
1072 : else
1073 : {
1074 11371632 : i1 = loudestCh;
1075 11371632 : i2 = i;
1076 : }
1077 23555880 : tempCoh = absCOVls[i1][i2] / ( sqrtf( ( lsEnergy[i1] * lsEnergy[i2] + EPSILON ) ) );
1078 23555880 : surrCoh = ( surrCoh < tempCoh ) ? surrCoh : tempCoh;
1079 : }
1080 : }
1081 3812800 : surrCoh = surrCoh * surrCoh;
1082 3812800 : surrCoh = ( surrCoh < 1.0f ) ? surrCoh : 1.0f;
1083 3812800 : surrCoh = ( surrCoh > 0.0f ) ? surrCoh : 0.0f;
1084 :
1085 : /* Compute spread coherence */
1086 3812800 : if ( elevation_m_values[block_m_idx][band_m_idx] < NEAR_HORIZONTAL_PLANE_ELEVATION ) /* Computed only near horizontal plane */
1087 : {
1088 2567911 : minAngleDist = 180.0f;
1089 2567911 : i1 = 0;
1090 2567911 : currentAzi = azimuth_m_values[block_m_idx][band_m_idx];
1091 16081916 : for ( i = 0; i < hMcMasa->numHorizontalChannels; i++ )
1092 : {
1093 13514005 : angleDist = fabsf( currentAzi - hMcMasa->ls_azimuth[i] );
1094 13514005 : if ( angleDist > 180.0f )
1095 : {
1096 421750 : angleDist = fabsf( angleDist - 360.0f );
1097 : }
1098 13514005 : if ( angleDist < minAngleDist )
1099 : {
1100 5593913 : minAngleDist = angleDist;
1101 5593913 : i1 = i;
1102 : }
1103 : }
1104 2567911 : i2 = hMcMasa->leftNearest[i1];
1105 2567911 : i3 = hMcMasa->rightNearest[i1];
1106 :
1107 2567911 : if ( i2 < i3 )
1108 : {
1109 2067963 : stereoCoh = absCOVls[i2][i3] / ( sqrtf( lsEnergy[i2] * lsEnergy[i3] + EPSILON ) );
1110 : }
1111 : else
1112 : {
1113 499948 : stereoCoh = absCOVls[i3][i2] / ( sqrtf( lsEnergy[i2] * lsEnergy[i3] + EPSILON ) );
1114 : }
1115 2567911 : lsEnergyRelation = ( lsEnergy[i2] + lsEnergy[i3] ) / ( lsEnergy[i1] + lsEnergy[i2] + lsEnergy[i3] + EPSILON );
1116 2567911 : stereoness = stereoCoh * lsEnergyRelation;
1117 :
1118 2567911 : if ( i1 < i2 )
1119 : {
1120 1138439 : tempCoh = absCOVls[i1][i2] / ( sqrtf( lsEnergy[i1] * lsEnergy[i2] + EPSILON ) );
1121 : }
1122 : else
1123 : {
1124 1429472 : tempCoh = absCOVls[i2][i1] / ( sqrtf( lsEnergy[i1] * lsEnergy[i2] + EPSILON ) );
1125 : }
1126 2567911 : if ( i1 < i3 )
1127 : {
1128 1134099 : tempCoh2 = absCOVls[i1][i3] / ( sqrtf( lsEnergy[i1] * lsEnergy[i3] + EPSILON ) );
1129 : }
1130 : else
1131 : {
1132 1433812 : tempCoh2 = absCOVls[i3][i1] / ( sqrtf( lsEnergy[i1] * lsEnergy[i3] + EPSILON ) );
1133 : }
1134 2567911 : cohPanCoh = ( tempCoh < tempCoh2 ) ? tempCoh : tempCoh2;
1135 2567911 : lsEnergyRelation = lsEnergy[i2] / ( lsEnergy[i1] + EPSILON );
1136 2567911 : tempLsEnergyRelation = lsEnergy[i1] / ( lsEnergy[i2] + EPSILON );
1137 2567911 : lsEnergyRelation = ( lsEnergyRelation < tempLsEnergyRelation ) ? lsEnergyRelation : tempLsEnergyRelation;
1138 2567911 : tempLsEnergyRelation = lsEnergy[i3] / ( lsEnergy[i1] + EPSILON );
1139 2567911 : lsEnergyRelation = ( lsEnergyRelation < tempLsEnergyRelation ) ? lsEnergyRelation : tempLsEnergyRelation;
1140 2567911 : tempLsEnergyRelation = lsEnergy[i1] / ( lsEnergy[i3] + EPSILON );
1141 2567911 : lsEnergyRelation = ( lsEnergyRelation < tempLsEnergyRelation ) ? lsEnergyRelation : tempLsEnergyRelation;
1142 2567911 : cohwideness = cohPanCoh * lsEnergyRelation;
1143 :
1144 2567911 : spreadCoh = ( cohwideness > stereoness ) ? cohwideness : stereoness;
1145 2567911 : if ( spreadCoh > 0.5f )
1146 : {
1147 1335111 : if ( cohwideness > stereoness )
1148 : {
1149 342866 : tempCoh = stereoness - ( cohwideness - 0.5f );
1150 342866 : spreadCoh = ( tempCoh > 0.5f ) ? tempCoh : 0.5f;
1151 : }
1152 : }
1153 2567911 : spreadCoh = ( spreadCoh < 1.0f ) ? spreadCoh : 1.0f;
1154 2567911 : spreadCoh = ( spreadCoh > 0.0f ) ? spreadCoh : 0.0f;
1155 :
1156 : /* Compute energy ratio tuning parameter */
1157 2567911 : lsEnergySum = sum_f( lsEnergy, numAnalysisChannels ) + EPSILON;
1158 2567911 : lsEnergyRelation = ( lsEnergy[i2] + lsEnergy[i3] ) / lsEnergySum;
1159 2567911 : stereoRatio = stereoCoh * lsEnergyRelation - surrCoh;
1160 :
1161 2567911 : lsEnergyRelation = ( lsEnergy[i1] + lsEnergy[i2] + lsEnergy[i3] ) / lsEnergySum;
1162 2567911 : cohPanRatio = cohPanCoh * lsEnergyRelation - surrCoh;
1163 :
1164 2567911 : cohRatio = ( stereoRatio > cohPanRatio ) ? stereoRatio : cohPanRatio;
1165 2567911 : cohRatio = ( cohRatio < 1.0f ) ? cohRatio : 1.0f;
1166 2567911 : cohRatio = ( cohRatio > 0.0f ) ? cohRatio : 0.0f;
1167 : }
1168 : else /* Otherwise, set spread coherence to zero */
1169 : {
1170 1244889 : spreadCoh = 0.0f;
1171 1244889 : cohRatio = 0.0f;
1172 1244889 : lsEnergySum = sum_f( lsEnergy, numAnalysisChannels );
1173 : }
1174 :
1175 : /* Store values */
1176 3812800 : spreadCoherence[block_m_idx][band_m_idx] = spreadCoh;
1177 :
1178 3812800 : if ( hMcMasa->combineRatios )
1179 : {
1180 3812800 : surroundingCoherence[0][band_m_idx] += lsEnergySum * surrCoh;
1181 3812800 : coherentEnergyRatio[0][band_m_idx] += lsEnergySum * cohRatio;
1182 3812800 : 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 190640 : if ( hMcMasa->combineRatios )
1193 : {
1194 1143840 : for ( band_m_idx = 0; band_m_idx < hMcMasa->nbands; band_m_idx++ )
1195 : {
1196 953200 : if ( renormalization_factor_diff[band_m_idx] > EPSILON )
1197 : {
1198 953200 : 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 953200 : if ( renormalization_factor_coh[band_m_idx] > EPSILON )
1205 : {
1206 953200 : surroundingCoherence[0][band_m_idx] /= renormalization_factor_coh[band_m_idx];
1207 953200 : 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 190640 : if ( hMcMasa->combineRatios )
1219 : {
1220 190640 : numSubFramesForRatio = 1;
1221 : }
1222 : else
1223 : {
1224 0 : numSubFramesForRatio = MAX_PARAM_SPATIAL_SUBFRAMES;
1225 : }
1226 :
1227 381280 : for ( i = 0; i < numSubFramesForRatio; i++ )
1228 : {
1229 1143840 : for ( j = 0; j < hMcMasa->nbands; j++ )
1230 : {
1231 953200 : energyRatio[i][j] = 1.0f - diffuseness_m[i][j];
1232 953200 : energyRatio[i][j] = ( energyRatio[i][j] > coherentEnergyRatio[i][j] ) ? energyRatio[i][j] : coherentEnergyRatio[i][j];
1233 : }
1234 : }
1235 :
1236 190640 : return;
1237 : }
1238 :
1239 :
1240 : /*--------------------------------------------------------------------------*
1241 : * ivas_mcmasa_dmx_modify()
1242 : *
1243 : *
1244 : *--------------------------------------------------------------------------*/
1245 :
1246 1919 : 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 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." );
1256 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." );
1257 :
1258 1919 : if ( n_chnls_dmx_old == n_chnls_dmx_new )
1259 : {
1260 : /* same dmx layout -> nothing to do */
1261 0 : return;
1262 : }
1263 :
1264 1919 : if ( n_chnls_dmx_old == 1 )
1265 : {
1266 : /* split mono energy into identical channels */
1267 643870 : for ( i = 0; i < n_samples; i++ )
1268 : {
1269 643200 : if ( n_chnls_dmx_new == 2 )
1270 : {
1271 287040 : dmx[1][i] = dmx[0][i] * INV_SQRT2;
1272 287040 : dmx[2][i] = dmx[1][i];
1273 : }
1274 356160 : else if ( n_chnls_dmx_new == 3 )
1275 : {
1276 356160 : dmx[0][i] = dmx[0][i] * INV_SQRT3;
1277 : }
1278 : }
1279 : }
1280 1249 : else if ( n_chnls_dmx_old == 2 )
1281 : {
1282 566029 : for ( i = 0; i < n_samples; i++ )
1283 : {
1284 565440 : if ( n_chnls_dmx_new == 1 )
1285 : {
1286 : /* sum l and r */
1287 268800 : dmx[0][i] = dmx[1][i] + dmx[2][i];
1288 : }
1289 296640 : else if ( n_chnls_dmx_new == 3 )
1290 : {
1291 296640 : dmx[0][i] = 0.5f * ( dmx[1][i] + dmx[2][i] );
1292 296640 : dmx[1][i] = dmx[1][i] - dmx[0][i];
1293 296640 : dmx[2][i] = dmx[2][i] - dmx[0][i];
1294 : }
1295 : }
1296 : }
1297 660 : else if ( n_chnls_dmx_old == 3 )
1298 : {
1299 634260 : for ( i = 0; i < n_samples; i++ )
1300 : {
1301 633600 : if ( n_chnls_dmx_new == 1 )
1302 : {
1303 : /* sum all channels */
1304 357120 : dmx[0][i] = dmx[0][i] + dmx[1][i] + dmx[2][i];
1305 : }
1306 276480 : else if ( n_chnls_dmx_new == 2 )
1307 : {
1308 : /* mix center into sides */
1309 276480 : dmx[0][i] *= INV_SQRT2;
1310 276480 : dmx[1][i] += dmx[0][i];
1311 276480 : dmx[2][i] += dmx[0][i];
1312 : }
1313 : }
1314 : }
1315 :
1316 1919 : return;
1317 : }
1318 :
1319 :
1320 : /*--------------------------------------------------------------------------*
1321 : * Local functions
1322 : *--------------------------------------------------------------------------*/
1323 :
1324 : /* Compute downmix */
1325 190640 : 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 190640 : numAnalysisChannels = nchan_inp - 1;
1340 190640 : if ( hMcMasa->separateChannelEnabled )
1341 : {
1342 36974 : numAnalysisChannels = nchan_inp - 2;
1343 : }
1344 :
1345 190640 : multiChEne = 0.0f;
1346 1559074 : for ( j = 0; j < numAnalysisChannels; j++ )
1347 : {
1348 1300412274 : for ( i = 0; i < input_frame; i++ )
1349 : {
1350 1299043840 : multiChEne += data_f[j][i] * data_f[j][i];
1351 : }
1352 : }
1353 :
1354 190640 : if ( nchan_transport == 2 )
1355 : {
1356 : int16_t numSideChannels; /* Channels other than left, right, center */
1357 : int16_t leftIndex, rightIndex;
1358 :
1359 61353 : numSideChannels = numAnalysisChannels / 2 - 1;
1360 296199 : for ( j = 0; j < numSideChannels; j++ )
1361 : {
1362 234846 : if ( hMcMasa->separateChannelEnabled )
1363 : {
1364 146496 : leftIndex = j * 2 + 2;
1365 146496 : rightIndex = j * 2 + 3;
1366 : }
1367 : else
1368 : {
1369 88350 : leftIndex = j * 2 + 3;
1370 88350 : rightIndex = j * 2 + 4;
1371 : }
1372 :
1373 224487006 : for ( i = 0; i < input_frame; i++ )
1374 : {
1375 224252160 : data_f[0][i] += data_f[leftIndex][i];
1376 224252160 : data_f[1][i] += data_f[rightIndex][i];
1377 : }
1378 : }
1379 :
1380 61353 : if ( !hMcMasa->separateChannelEnabled )
1381 : {
1382 23332219 : for ( i = 0; i < input_frame; i++ )
1383 : {
1384 23307840 : dmx_c = INV_SQRT2 * data_f[2][i];
1385 23307840 : data_f[0][i] += dmx_c;
1386 23307840 : data_f[1][i] += dmx_c;
1387 : }
1388 : }
1389 : }
1390 129287 : else if ( nchan_transport == 1 )
1391 : {
1392 122539207 : for ( i = 0; i < input_frame; i++ )
1393 : {
1394 710105920 : for ( j = 1; j < numAnalysisChannels; j++ )
1395 : {
1396 587696000 : data_f[0][i] += data_f[j][i];
1397 : }
1398 : }
1399 : }
1400 :
1401 190640 : downmixEne = 0.0f;
1402 442633 : for ( j = 0; j < nchan_transport; j++ )
1403 : {
1404 239787673 : for ( i = 0; i < input_frame; i++ )
1405 : {
1406 239535680 : downmixEne += data_f[j][i] * data_f[j][i];
1407 : }
1408 : }
1409 :
1410 190640 : alpha = 0.1f;
1411 190640 : hMcMasa->prevMultiChEne = alpha * multiChEne + ( 1.0f - alpha ) * hMcMasa->prevMultiChEne;
1412 190640 : hMcMasa->prevDownmixEne = alpha * downmixEne + ( 1.0f - alpha ) * hMcMasa->prevDownmixEne;
1413 :
1414 190640 : prevEQ = hMcMasa->prevEQ;
1415 190640 : currEQ = sqrtf( hMcMasa->prevMultiChEne / ( hMcMasa->prevDownmixEne + EPSILON ) );
1416 190640 : hMcMasa->prevEQ = currEQ;
1417 :
1418 181163440 : for ( i = 0; i < input_frame; i++ )
1419 : {
1420 180972800 : instEQ = hMcMasa->interpolator[i] * currEQ + ( 1.0f - hMcMasa->interpolator[i] ) * prevEQ;
1421 420508480 : for ( j = 0; j < nchan_transport; j++ )
1422 : {
1423 239535680 : data_f[j][i] *= instEQ;
1424 : }
1425 : }
1426 :
1427 190640 : return;
1428 : }
1429 :
1430 :
1431 : /* Compute covariance matrix, i.e., xT * conj(x), and accumulate to the output */
1432 180972800 : 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 1480016640 : for ( i = 0; i < N; i++ )
1444 : {
1445 1299043840 : a = sr[i][freq];
1446 1299043840 : b = si[i][freq];
1447 7154483200 : for ( j = i; j < N; j++ )
1448 : {
1449 5855439360 : c = sr[j][freq];
1450 5855439360 : d = si[j][freq];
1451 5855439360 : COVls->xr[i][j] += a * c + b * d;
1452 5855439360 : COVls->xi[i][j] += b * c - a * d;
1453 : }
1454 : }
1455 :
1456 180972800 : return;
1457 : }
1458 :
1459 :
1460 1525120 : 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 9150720 : for ( i = enc_param_start_band; i < enc_param_start_band + num_frequency_bands; i++ )
1477 : {
1478 7625600 : brange[0] = band_grouping[i];
1479 7625600 : brange[1] = band_grouping[i + 1];
1480 :
1481 7625600 : intensity_real[0][i] = 0;
1482 7625600 : intensity_real[1][i] = 0;
1483 7625600 : intensity_real[2][i] = 0;
1484 :
1485 369571200 : for ( j = brange[0]; j < brange[1]; j++ )
1486 : {
1487 361945600 : real = Cldfb_RealBuffer[0][j];
1488 361945600 : img = Cldfb_ImagBuffer[0][j];
1489 361945600 : intensity_real[0][i] += Cldfb_RealBuffer[3][j] * real + Cldfb_ImagBuffer[3][j] * img;
1490 361945600 : intensity_real[1][i] += Cldfb_RealBuffer[1][j] * real + Cldfb_ImagBuffer[1][j] * img;
1491 361945600 : intensity_real[2][i] += Cldfb_RealBuffer[2][j] * real + Cldfb_ImagBuffer[2][j] * img;
1492 : }
1493 : }
1494 :
1495 1525120 : return;
1496 : }
1497 :
1498 :
1499 : /*-------------------------------------------------------------------------
1500 : * computeVerticalDiffuseness()
1501 : *
1502 : *
1503 : *------------------------------------------------------------------------*/
1504 :
1505 346056 : 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 346056 : float tmp = 0;
1518 : const float *p_tmp_c;
1519 :
1520 : /* Set variables to zero */
1521 346056 : set_f( intensity_slow, 0.0f, MASA_FREQUENCY_BANDS );
1522 346056 : set_f( energy_slow, 0.0f, MASA_FREQUENCY_BANDS );
1523 :
1524 3114504 : for ( i = 0; i < averaging_length; ++i )
1525 : {
1526 : /* Energy slow */
1527 2768448 : p_tmp_c = buffer_energy + i * num_freq_bands;
1528 16610688 : for ( k = 0; k < num_freq_bands; k++ )
1529 : {
1530 13842240 : energy_slow[k] += *( p_tmp_c++ );
1531 : }
1532 :
1533 : /* Intensity slow */
1534 16610688 : for ( k = 0; k < num_freq_bands; k++ )
1535 : {
1536 13842240 : intensity_slow[k] += buffer_intensity[i][k];
1537 : }
1538 : }
1539 :
1540 : /* Compute absolute value */
1541 2076336 : for ( k = 0; k < num_freq_bands; k++ )
1542 : {
1543 1730280 : intensity_slow_abs[k] = fabsf( intensity_slow[k] );
1544 : }
1545 :
1546 : /* Compute Diffuseness */
1547 2076336 : for ( i = 0; i < num_freq_bands; ++i )
1548 : {
1549 1730280 : tmp = intensity_slow_abs[i] / ( energy_slow[i] + EPSILON );
1550 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 */
1551 1730280 : tmp = 1.0f - tmp;
1552 1730280 : diffuseness[i] = ( ( tmp < 1.0f ) ? ( ( tmp < 0.0f ) ? 0.f : tmp ) : 1.0f );
1553 : }
1554 :
1555 346056 : return;
1556 : }
1557 :
1558 :
1559 11784 : 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 11784 : lsSpacing = 360.0f / (float) numChannels;
1577 11784 : oddLayout = numChannels % 2;
1578 11784 : numChannelsHalf = numChannels / 2;
1579 :
1580 11784 : mvr2r( ls_azimuth, ls_azimuth_temp, numChannels );
1581 72597 : for ( i = 0; i < numChannels; i++ )
1582 : {
1583 60813 : smallestAzimuth = 1000.0f;
1584 60813 : smallestAzimuthIndex = 0;
1585 395840 : for ( j = 0; j < numChannels; j++ )
1586 : {
1587 335027 : if ( ls_azimuth_temp[j] < smallestAzimuth )
1588 : {
1589 114305 : smallestAzimuth = ls_azimuth_temp[j];
1590 114305 : smallestAzimuthIndex = j;
1591 : }
1592 : }
1593 60813 : ls_azimuth_order[i] = smallestAzimuthIndex;
1594 60813 : ls_azimuth_temp[smallestAzimuthIndex] = 1000.0f;
1595 : }
1596 :
1597 11784 : if ( oddLayout )
1598 : {
1599 5535 : startAzimuth = -lsSpacing * ( (float) numChannelsHalf );
1600 : }
1601 : else
1602 : {
1603 6249 : startAzimuth = -lsSpacing * ( (float) numChannelsHalf - 0.5f );
1604 : }
1605 :
1606 72597 : for ( i = 0; i < numChannels; i++ )
1607 : {
1608 60813 : ls_azimuth_even_ordered[i] = (float) i * lsSpacing + startAzimuth;
1609 : }
1610 :
1611 72597 : for ( i = 0; i < numChannels; i++ )
1612 : {
1613 60813 : ls_azimuth_even[ls_azimuth_order[i]] = roundf( ls_azimuth_even_ordered[i] );
1614 : }
1615 :
1616 11784 : return;
1617 : }
1618 :
1619 190640 : 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 190640 : l_ts = input_frame / MDFT_NO_COL_MAX;
1633 190640 : separateChannelIndex = hMcMasa->separateChannelIndex;
1634 190640 : lfeChannelIndex = LFE_CHANNEL;
1635 :
1636 190640 : if ( hMcMasa->separateChannelEnabled )
1637 : {
1638 36974 : mvr2r( data_f[lfeChannelIndex], &( hMcMasa->delay_buffer_lfe[0][hMcMasa->num_samples_delay_comp - hMcMasa->offset_comp] ), hMcMasa->offset_comp );
1639 36974 : 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 153666 : pcm_in[0] = &data_f[lfeChannelIndex][0];
1644 : }
1645 :
1646 : /* Reset variables */
1647 190640 : set_zero( hMcMasa->lfeLfEne, MAX_PARAM_SPATIAL_SUBFRAMES );
1648 190640 : set_zero( hMcMasa->totalLfEne, MAX_PARAM_SPATIAL_SUBFRAMES );
1649 :
1650 : /* Compute low-frequency energies */
1651 190640 : 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 36974 : mvr2r( &( hMcMasa->delay_buffer_lfe[0][0] ), &( delayedInputSignal[0][0] ), hMcMasa->num_slots_delay_comp * l_ts );
1659 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 );
1660 36974 : mvr2r( &( hMcMasa->delay_buffer_lfe[1][0] ), &( delayedInputSignal[1][0] ), hMcMasa->num_slots_delay_comp * l_ts );
1661 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 );
1662 :
1663 36974 : lowpassCoef = 1.0f / ( (float) hMcMasa->ringBufferSize );
1664 :
1665 35292014 : for ( i = 0; i < input_frame; i++ )
1666 : {
1667 105765120 : for ( j = 0; j < 2; j++ )
1668 : {
1669 70510080 : hMcMasa->lowpassSum[j] += lowpassCoef * delayedInputSignal[j][i] - lowpassCoef * hMcMasa->lfeAnaRingBuffer[j][hMcMasa->ringBufferPointer];
1670 70510080 : lowPassSignal[j][i] = hMcMasa->lowpassSum[j];
1671 70510080 : hMcMasa->lfeAnaRingBuffer[j][hMcMasa->ringBufferPointer] = delayedInputSignal[j][i];
1672 : }
1673 :
1674 35255040 : hMcMasa->ringBufferPointer--;
1675 35255040 : if ( hMcMasa->ringBufferPointer < 0 )
1676 : {
1677 147896 : hMcMasa->ringBufferPointer = hMcMasa->ringBufferSize - 1;
1678 : }
1679 : }
1680 :
1681 184870 : for ( block_m_idx = 0; block_m_idx < MAX_PARAM_SPATIAL_SUBFRAMES; block_m_idx++ )
1682 : {
1683 147896 : mrange[0] = hMcMasa->block_grouping[block_m_idx] * l_ts;
1684 147896 : mrange[1] = hMcMasa->block_grouping[block_m_idx + 1] * l_ts;
1685 :
1686 35402936 : for ( i = mrange[0]; i < mrange[1]; i++ )
1687 : {
1688 35255040 : hMcMasa->lfeLfEne[block_m_idx] += lowPassSignal[0][i] * lowPassSignal[0][i];
1689 35255040 : hMcMasa->totalLfEne[block_m_idx] += lowPassSignal[1][i] * lowPassSignal[1][i];
1690 : }
1691 147896 : 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 153666 : p_Chnl_RealBuffer[0] = &Chnl_RealBuffer[0][0];
1704 153666 : p_Chnl_RealBuffer[1] = &Chnl_RealBuffer[1][0];
1705 153666 : p_Chnl_ImagBuffer[0] = &Chnl_ImagBuffer[0][0];
1706 153666 : p_Chnl_ImagBuffer[1] = &Chnl_ImagBuffer[1][0];
1707 :
1708 768330 : for ( block_m_idx = 0; block_m_idx < MAX_PARAM_SPATIAL_SUBFRAMES; block_m_idx++ )
1709 : {
1710 614664 : mrange[0] = hMcMasa->block_grouping[block_m_idx];
1711 614664 : mrange[1] = hMcMasa->block_grouping[block_m_idx + 1];
1712 :
1713 1229328 : for ( ts = mrange[0]; ts < mrange[1]; ts++ )
1714 : {
1715 614664 : 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 614664 : ivas_fb_mixer_update_prior_input( hMcMasa->hFbMixerLfe, pcm_in, l_ts, hMcMasa->hFbMixerLfe->fb_cfg->num_in_chans );
1718 :
1719 614664 : 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 3073320 : for ( i = 0; i < CLDFB_TO_MDFT_FAC; i++ )
1723 : {
1724 2458656 : 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 190640 : if ( hMcMasa->separateChannelEnabled )
1731 : {
1732 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 ) );
1733 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 ) );
1734 : }
1735 :
1736 190640 : return;
1737 : }
|