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