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