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_fx.h"
39 : #include "options.h"
40 : #include "prot_fx.h"
41 : #include "ivas_rom_com.h"
42 : #include "ivas_rom_com_fx.h"
43 : #include "ivas_rom_enc.h"
44 : #include "wmc_auto.h"
45 : #include "ivas_prot_fx.h"
46 :
47 :
48 : /*-------------------------------------------------------------------------
49 : * Local constants
50 : *------------------------------------------------------------------------*/
51 :
52 : #define NEAR_HORIZONTAL_PLANE_ELEVATION_FX 73400320 /*Q22*/
53 : #define VERTICAL_ENERGY_RATIO_OFFSET_FX 4915 /*Q15*/
54 :
55 : /*-------------------------------------------------------------------------
56 : * Local function prototypes
57 : *------------------------------------------------------------------------*/
58 :
59 : /* Structure for covariance matrix */
60 : typedef struct
61 : {
62 : Word32 xr_fx[MCMASA_MAX_ANA_CHANS][MCMASA_MAX_ANA_CHANS];
63 : Word32 xi_fx[MCMASA_MAX_ANA_CHANS][MCMASA_MAX_ANA_CHANS];
64 : Word16 xr_e[MCMASA_MAX_ANA_CHANS][MCMASA_MAX_ANA_CHANS]; /*Stores exponent for xr_fx*/
65 : Word16 xi_e[MCMASA_MAX_ANA_CHANS][MCMASA_MAX_ANA_CHANS]; /*Stores exponent for xi_fx*/
66 : } CovarianceMatrix;
67 :
68 : static void ivas_mcmasa_dmx_fx(
69 : MCMASA_ENC_HANDLE hMcMasa,
70 : Word32 *data_fx[],
71 : Word16 data_e,
72 : const Word16 input_frame,
73 : const Word16 nchan_transport,
74 : const Word16 nchan_inp );
75 :
76 : static void compute_cov_mtx_fx(
77 : Word32 sr[MCMASA_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX], /* i : Input matrix, real, s[ch][freq] */
78 : Word32 si[MCMASA_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX], /* i : Input matrix, imag, s[ch][freq] */
79 : const Word16 freq, /* i : Freq to process */
80 : const Word16 N, /* i : Number of channels */
81 : CovarianceMatrix *COVls, /* o : Output matrix, contains upper part of cov mtx */
82 : Word16 inp_exp /*Stores exponent for temp*/
83 : );
84 : static void computeIntensityVector_enc_fx( const Word16 *band_grouping, Word32 Cldfb_RealBuffer[FOA_CHANNELS][DIRAC_NO_FB_BANDS_MAX], Word32 Cldfb_ImagBuffer[FOA_CHANNELS][DIRAC_NO_FB_BANDS_MAX], const Word16 enc_param_start_band, const Word16 num_frequency_bands, Word32 intensity_real[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS] );
85 :
86 : static void computeVerticalDiffuseness_fx(
87 : Word32 **buffer_intensity, /* i : Intensity vectors */
88 : const Word32 *buffer_energy, /* i : Energy */
89 : const Word16 averaging_length, /* i : Averaging length */
90 : const Word16 num_freq_bands, /* i : Number of frequency bands */
91 : Word32 *diffuseness, /* o : Estimated diffuseness */
92 : Word16 *buffer_intensity_q,
93 : Word16 *buffer_energy_q );
94 :
95 : static void computeEvenLayout_fx(
96 : const Word32 *ls_azimuth,
97 : Word32 *ls_azimuth_even,
98 : const Word16 numChannels );
99 :
100 : static void computeLfeEnergy_fx( MCMASA_ENC_HANDLE hMcMasa, Word32 *data_fx[], const Word16 input_frame, Word16 q_fac );
101 :
102 :
103 : /*--------------------------------------------------------------------------*
104 : * ivas_mcmasa_enc_open()
105 : *
106 : *
107 : *--------------------------------------------------------------------------*/
108 :
109 277 : ivas_error ivas_mcmasa_enc_open_fx(
110 : Encoder_Struct *st_ivas /* i/o: IVAS encoder handle */
111 : )
112 : {
113 : Word16 i, j;
114 : Word16 tmp_f;
115 : MCMASA_ENC_HANDLE hMcMasa;
116 : MASA_ENCODER_HANDLE hMasa;
117 : Word32 ls_azimuth[MCMASA_MAX_ANA_CHANS];
118 : Word32 ls_elevation[MCMASA_MAX_ANA_CHANS];
119 : Word32 ls_azimuth_even[MCMASA_MAX_ANA_CHANS];
120 : Word16 numAnalysisChannels;
121 : Word32 left_min, right_min, azi_diff;
122 : const Word16 *band_mapping;
123 : Word16 maxBin, input_frame;
124 : Word16 nchan_inp;
125 : Word32 input_Fs;
126 : IVAS_FB_CFG *fb_cfg, *fb_cfgLfe;
127 : ivas_error error;
128 :
129 277 : error = IVAS_ERR_OK;
130 277 : move32();
131 :
132 277 : assert( st_ivas->hMasa != NULL && "MASA encoder handle is not present" );
133 277 : hMasa = st_ivas->hMasa;
134 :
135 277 : IF( ( hMcMasa = (MCMASA_ENC_HANDLE) malloc( sizeof( MCMASA_ENC_DATA ) ) ) == NULL )
136 : {
137 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for McMasa\n" ) );
138 : }
139 :
140 277 : nchan_inp = st_ivas->hEncoderConfig->nchan_inp;
141 277 : move16();
142 277 : input_Fs = st_ivas->hEncoderConfig->input_Fs;
143 277 : move32();
144 :
145 : /* Determine if to separate some channels from the analysis */
146 277 : ivas_mcmasa_set_separate_channel_mode_fx( &( hMcMasa->separateChannelEnabled ), &( hMcMasa->separateChannelIndex ), st_ivas->hEncoderConfig->ivas_total_brate );
147 :
148 277 : numAnalysisChannels = sub( nchan_inp, 1 );
149 277 : IF( hMcMasa->separateChannelEnabled )
150 : {
151 28 : numAnalysisChannels = sub( nchan_inp, 2 );
152 : }
153 :
154 : /* With McMASA, we config MASA encoder only in init as we know the input and there are no frame-by-frame changes currently. */
155 277 : IF( NE_32( ( error = ivas_masa_enc_config_fx( st_ivas ) ), IVAS_ERR_OK ) )
156 : {
157 0 : return error;
158 : }
159 :
160 :
161 : /* Determine the number of bands */
162 277 : hMcMasa->nbands = st_ivas->hMasa->config.numCodingBands;
163 277 : move16();
164 277 : hMcMasa->nCodingBands = st_ivas->hMasa->config.numCodingBands;
165 277 : move16();
166 :
167 : /* Determine band grouping */
168 277 : IF( EQ_16( hMcMasa->nbands, 24 ) )
169 : {
170 0 : FOR( i = 0; i < hMcMasa->nbands + 1; i++ )
171 : {
172 0 : hMcMasa->band_grouping[i] = i_mult( MASA_band_grouping_24[i], CLDFB_TO_MDFT_FAC );
173 0 : move16();
174 : }
175 : }
176 : ELSE
177 : {
178 277 : band_mapping = hMasa->data.band_mapping;
179 1939 : FOR( i = 0; i < hMcMasa->nbands + 1; i++ )
180 : {
181 1662 : hMcMasa->band_grouping[i] = i_mult( MASA_band_grouping_24[band_mapping[i]], CLDFB_TO_MDFT_FAC );
182 1662 : move16();
183 : }
184 : }
185 :
186 277 : maxBin = extract_l( W_extract_h( W_add( W_mult_32_32( input_Fs, INV_CLDFB_BANDWIDTH_MDFT_FAC_Q31 ), ONE_IN_Q31 /*0.5f in Q32*/ ) ) ); // Q0
187 :
188 1385 : FOR( i = 1; i < hMcMasa->nbands + 1; i++ )
189 : {
190 1385 : IF( GE_32( hMcMasa->band_grouping[i], maxBin ) )
191 : {
192 277 : hMcMasa->band_grouping[i] = maxBin; // Q0
193 277 : move16();
194 277 : hMcMasa->nbands = i;
195 277 : move16();
196 277 : BREAK;
197 : }
198 : }
199 :
200 : /* initialize delay compensation */
201 277 : hMcMasa->num_samples_delay_comp = NS2SA_FX2( input_Fs, DELAY_DIRAC_ENC_CMP_NS );
202 277 : move16();
203 : #ifdef DISABLE_DIRAC_DELAY_COMP
204 : hMcMasa->num_samples_delay_comp = 0; /* disable delay compensation by setting to 0 */
205 : #endif
206 277 : tmp_f = idiv1616( hMcMasa->num_samples_delay_comp, ( NS2SA_FX2( input_Fs, DIRAC_SLOT_ENC_NS ) ) );
207 277 : hMcMasa->num_slots_delay_comp = tmp_f;
208 277 : move16();
209 :
210 277 : IF( GT_16( hMcMasa->num_samples_delay_comp, ( NS2SA_FX2( input_Fs, DIRAC_SLOT_ENC_NS ) ) ) )
211 : {
212 277 : hMcMasa->num_slots_delay_comp = add( hMcMasa->num_slots_delay_comp, 1 );
213 277 : move16();
214 277 : hMcMasa->offset_comp = negate( hMcMasa->num_samples_delay_comp );
215 277 : move16();
216 277 : hMcMasa->num_samples_delay_comp = i_mult( hMcMasa->num_slots_delay_comp, NS2SA_FX2( input_Fs, DIRAC_SLOT_ENC_NS ) );
217 277 : move16();
218 277 : hMcMasa->offset_comp = add( hMcMasa->offset_comp, hMcMasa->num_samples_delay_comp );
219 277 : move16();
220 : }
221 : ELSE
222 : {
223 0 : hMcMasa->offset_comp = 0;
224 0 : move16();
225 : }
226 :
227 : /* set FB config. */
228 277 : IF( NE_32( ( error = ivas_fb_set_cfg( &fb_cfg, MASA_FORMAT, numAnalysisChannels, 0, 0, input_Fs, 0 ) ), IVAS_ERR_OK ) )
229 : {
230 0 : return error;
231 : }
232 :
233 : /* Allocate and initialize FB mixer handle */
234 277 : IF( NE_32( ( error = ivas_FB_mixer_open_fx( &( hMcMasa->hFbMixer ), input_Fs, fb_cfg, 0 ) ), IVAS_ERR_OK ) )
235 : {
236 0 : return error;
237 : }
238 :
239 277 : IF( hMcMasa->separateChannelEnabled )
240 : {
241 : /* TD Energy calculation with LP */
242 28 : IF( ( hMcMasa->delay_buffer_lfe[0] = (Word32 *) malloc( NS2SA_FX2( input_Fs, DELAY_DIRAC_ENC_CMP_NS + DIRAC_SLOT_ENC_NS ) * sizeof( Word32 ) ) ) == NULL )
243 : {
244 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for McMasa\n" ) );
245 : }
246 28 : set_zero_fx( hMcMasa->delay_buffer_lfe[0], NS2SA_FX2( input_Fs, DELAY_DIRAC_ENC_CMP_NS + DIRAC_SLOT_ENC_NS ) );
247 :
248 28 : IF( ( hMcMasa->delay_buffer_lfe[1] = (Word32 *) malloc( NS2SA_FX2( input_Fs, DELAY_DIRAC_ENC_CMP_NS + DIRAC_SLOT_ENC_NS ) * sizeof( Word32 ) ) ) == NULL )
249 : {
250 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for McMasa\n" ) );
251 : }
252 28 : set_zero_fx( hMcMasa->delay_buffer_lfe[1], NS2SA_FX2( input_Fs, DELAY_DIRAC_ENC_CMP_NS + DIRAC_SLOT_ENC_NS ) );
253 28 : hMcMasa->hFbMixerLfe = NULL;
254 : }
255 : ELSE
256 : {
257 : /* Allocate and initialize FB mixer handle for LFE channel */
258 249 : IF( NE_32( ( error = ivas_fb_set_cfg( &fb_cfgLfe, MASA_FORMAT, 1, 0, 0, input_Fs, 0 ) ), IVAS_ERR_OK ) )
259 : {
260 0 : return error;
261 : }
262 :
263 249 : IF( NE_32( ( error = ivas_FB_mixer_open_fx( &( hMcMasa->hFbMixerLfe ), input_Fs, fb_cfgLfe, 0 ) ), IVAS_ERR_OK ) )
264 : {
265 0 : return error;
266 : }
267 :
268 249 : hMcMasa->delay_buffer_lfe[0] = NULL;
269 249 : hMcMasa->delay_buffer_lfe[1] = NULL;
270 : }
271 :
272 277 : IF( hMcMasa->separateChannelEnabled )
273 : {
274 : Word16 bufferSize;
275 :
276 : /* Ring buffer for the filterbank of the LFE analysis.
277 : * The filterbank is using moving average lowpass filter with the crossover of 120 Hz. */
278 28 : bufferSize = (Word16) ( ( input_Fs / FRAMES_PER_SEC ) / MAX_PARAM_SPATIAL_SUBFRAMES );
279 84 : FOR( i = 0; i < 2; i++ )
280 : {
281 56 : IF( ( hMcMasa->lfeAnaRingBuffer[i] = (Word32 *) malloc( bufferSize * sizeof( float ) ) ) == NULL )
282 : {
283 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for McMasa\n" ) );
284 : }
285 56 : set_zero_fx( hMcMasa->lfeAnaRingBuffer[i], bufferSize );
286 56 : hMcMasa->lowpassSum[i] = 0;
287 56 : move32();
288 : }
289 28 : hMcMasa->ringBufferPointer = 0;
290 28 : move16();
291 28 : hMcMasa->ringBufferSize = bufferSize;
292 28 : move16();
293 : }
294 :
295 :
296 : /*dirac_slot_ns = DIRAC_SLOT_ENC_NS;*/
297 :
298 : /* intensity 3-dim */
299 1108 : FOR( i = 0; i < DIRAC_NUM_DIMS; i++ )
300 : {
301 831 : IF( ( hMcMasa->direction_vector_m_fx[i] = (Word32 **) malloc( MAX_PARAM_SPATIAL_SUBFRAMES * sizeof( Word32 * ) ) ) == NULL )
302 : {
303 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for McMasa\n" ) );
304 : }
305 :
306 4155 : FOR( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ )
307 : {
308 3324 : IF( ( hMcMasa->direction_vector_m_fx[i][j] = (Word32 *) malloc( hMcMasa->nbands * sizeof( Word32 ) ) ) == NULL )
309 : {
310 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for McMasa\n" ) );
311 : }
312 : }
313 : }
314 :
315 1108 : FOR( i = 0; i < DIRAC_NUM_DIMS; i++ )
316 : {
317 831 : IF( ( hMcMasa->direction_vector_e[i] = (Word16 **) malloc( MAX_PARAM_SPATIAL_SUBFRAMES * sizeof( Word16 * ) ) ) == NULL )
318 : {
319 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for McMasa\n" ) );
320 : }
321 :
322 4155 : FOR( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ )
323 : {
324 3324 : IF( ( hMcMasa->direction_vector_e[i][j] = (Word16 *) malloc( hMcMasa->nbands * sizeof( Word16 ) ) ) == NULL )
325 : {
326 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for McMasa\n" ) );
327 : }
328 : }
329 : }
330 :
331 277 : hMcMasa->no_col_avg_diff = (Word8) ( DIRAC_NO_COL_AVG_DIFF_NS / DIRAC_SLOT_ENC_NS ); /* dirac_slot_ns = DIRAC_SLOT_ENC_NS */
332 277 : move16();
333 :
334 1108 : FOR( i = 0; i < DIRAC_NUM_DIMS; i++ )
335 : {
336 831 : IF( ( hMcMasa->buffer_intensity_real_fx[i] = (Word32 **) malloc( hMcMasa->no_col_avg_diff * sizeof( Word32 * ) ) ) == NULL )
337 : {
338 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for McMasa\n" ) );
339 : }
340 :
341 7479 : FOR( j = 0; j < hMcMasa->no_col_avg_diff; j++ )
342 : {
343 6648 : IF( ( hMcMasa->buffer_intensity_real_fx[i][j] = (Word32 *) malloc( hMcMasa->nbands * sizeof( Word32 ) ) ) == NULL )
344 : {
345 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for McMasa\n" ) );
346 : }
347 6648 : set_zero_fx( hMcMasa->buffer_intensity_real_fx[i][j], hMcMasa->nbands ); // hMcMasa->buffer_intensity_real_q
348 : }
349 : }
350 277 : set16_fx( hMcMasa->buffer_intensity_real_q, 31, DIRAC_NO_COL_AVG_DIFF );
351 :
352 277 : IF( ( hMcMasa->buffer_intensity_real_vert_fx = (Word32 **) malloc( hMcMasa->no_col_avg_diff * sizeof( Word32 * ) ) ) == NULL )
353 : {
354 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for McMasa\n" ) );
355 : }
356 :
357 2493 : FOR( j = 0; j < hMcMasa->no_col_avg_diff; j++ )
358 : {
359 2216 : IF( ( hMcMasa->buffer_intensity_real_vert_fx[j] = (Word32 *) malloc( hMcMasa->nbands * sizeof( Word32 ) ) ) == NULL ) // hMcMasa->buffer_intensity_real_vert_q
360 : {
361 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for McMasa\n" ) );
362 : }
363 2216 : set_zero_fx( hMcMasa->buffer_intensity_real_vert_fx[j], hMcMasa->nbands );
364 : }
365 :
366 277 : IF( ( hMcMasa->buffer_energy_fx = (Word32 *) malloc( hMcMasa->nbands * hMcMasa->no_col_avg_diff * sizeof( Word32 ) ) ) == NULL )
367 : {
368 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for McMasa\n" ) );
369 : }
370 277 : set_zero_fx( hMcMasa->buffer_energy_fx, imult1616( hMcMasa->nbands, hMcMasa->no_col_avg_diff ) ); // hMcMasa->buffer_energy_q
371 277 : set16_fx( hMcMasa->buffer_intensity_real_vert_q, 31, DIRAC_NO_COL_AVG_DIFF );
372 277 : set16_fx( hMcMasa->buffer_energy_q, 31, DIRAC_NO_COL_AVG_DIFF );
373 :
374 277 : IF( EQ_32( st_ivas->hEncoderConfig->mc_input_setup, MC_LS_SETUP_5_1 ) )
375 : {
376 169 : Copy32( ls_azimuth_CICP6_fx, ls_azimuth, sub( nchan_inp, 1 ) );
377 169 : Copy32( ls_elevation_CICP6_fx, ls_elevation, sub( nchan_inp, 1 ) );
378 169 : hMcMasa->numHorizontalChannels = 5;
379 169 : move16();
380 169 : hMcMasa->isHorizontalSetup = 1;
381 169 : move16();
382 : }
383 108 : ELSE IF( EQ_32( st_ivas->hEncoderConfig->mc_input_setup, MC_LS_SETUP_7_1 ) )
384 : {
385 13 : Copy32( ls_azimuth_CICP12_fx, ls_azimuth, sub( nchan_inp, 1 ) );
386 13 : Copy32( ls_elevation_CICP12_fx, ls_elevation, sub( nchan_inp, 1 ) );
387 13 : hMcMasa->numHorizontalChannels = 7;
388 13 : move16();
389 13 : hMcMasa->isHorizontalSetup = 1;
390 13 : move16();
391 : }
392 95 : ELSE IF( EQ_32( st_ivas->hEncoderConfig->mc_input_setup, MC_LS_SETUP_5_1_2 ) )
393 : {
394 10 : Copy32( ls_azimuth_CICP14_fx, ls_azimuth, sub( nchan_inp, 1 ) );
395 10 : Copy32( ls_elevation_CICP14_fx, ls_elevation, sub( nchan_inp, 1 ) );
396 10 : hMcMasa->numHorizontalChannels = 5;
397 10 : move16();
398 10 : hMcMasa->isHorizontalSetup = 0;
399 10 : move16();
400 : }
401 85 : ELSE IF( EQ_32( st_ivas->hEncoderConfig->mc_input_setup, MC_LS_SETUP_5_1_4 ) )
402 : {
403 10 : Copy32( ls_azimuth_CICP16_fx, ls_azimuth, sub( nchan_inp, 1 ) ); // Q22
404 10 : Copy32( ls_elevation_CICP16_fx, ls_elevation, sub( nchan_inp, 1 ) ); // Q22
405 10 : hMcMasa->numHorizontalChannels = 5;
406 10 : move16();
407 10 : hMcMasa->isHorizontalSetup = 0;
408 10 : move16();
409 : }
410 : ELSE
411 : {
412 75 : Copy32( ls_azimuth_CICP19_fx, ls_azimuth, sub( nchan_inp, 1 ) ); // Q22
413 75 : Copy32( ls_elevation_CICP19_fx, ls_elevation, sub( nchan_inp, 1 ) ); // Q22
414 75 : hMcMasa->numHorizontalChannels = 7;
415 75 : move16();
416 75 : hMcMasa->isHorizontalSetup = 0;
417 75 : move16();
418 : }
419 :
420 277 : IF( hMcMasa->separateChannelEnabled )
421 : {
422 28 : Copy32( &ls_azimuth[hMcMasa->separateChannelIndex + 1], &ls_azimuth[hMcMasa->separateChannelIndex], numAnalysisChannels - hMcMasa->separateChannelIndex ); // Q22
423 28 : Copy32( &ls_elevation[hMcMasa->separateChannelIndex + 1], &ls_elevation[hMcMasa->separateChannelIndex], numAnalysisChannels - hMcMasa->separateChannelIndex ); // Q22
424 28 : hMcMasa->numHorizontalChannels = sub( hMcMasa->numHorizontalChannels, 1 );
425 28 : move16();
426 : }
427 :
428 277 : computeEvenLayout_fx( ls_azimuth, ls_azimuth_even, hMcMasa->numHorizontalChannels );
429 277 : IF( !hMcMasa->isHorizontalSetup )
430 : {
431 95 : computeEvenLayout_fx( &ls_azimuth[hMcMasa->numHorizontalChannels], &ls_azimuth_even[hMcMasa->numHorizontalChannels], sub( numAnalysisChannels, hMcMasa->numHorizontalChannels ) );
432 : }
433 :
434 2170 : FOR( i = 0; i < numAnalysisChannels; i++ )
435 : {
436 1893 : hMcMasa->chnlToFoaMtx_fx[0][i] = ONE_IN_Q31;
437 1893 : move32();
438 1893 : hMcMasa->chnlToFoaMtx_fx[1][i] = L_mult( getSineWord16R2( extract_l( Mpy_32_32( ls_azimuth[i], 46603 /*32767/360*/ ) /*Q22+Q24-31=>Q15*/ ) ), getCosWord16R2( extract_l( Mpy_32_32( ls_elevation[i], 46603 /*2^24/360*/ ) ) ) ); // Q31
439 1893 : move32();
440 1893 : hMcMasa->chnlToFoaMtx_fx[2][i] = L_shl( getSineWord16R2( extract_l( Mpy_32_32( ls_elevation[i], 46603 /*2^24/360*/ ) ) ), 16 ); // Q31
441 1893 : move32();
442 1893 : hMcMasa->chnlToFoaMtx_fx[3][i] = L_mult( getCosWord16R2( extract_l( Mpy_32_32( ls_azimuth[i], 46603 /*2^24/360*/ ) ) ), getCosWord16R2( extract_l( Mpy_32_32( ls_elevation[i], 46603 /*2^24/360*/ ) ) ) ); // Q31
443 1893 : move32();
444 :
445 1893 : hMcMasa->chnlToFoaEvenMtx_fx[0][i] = ONE_IN_Q31;
446 1893 : move32();
447 1893 : hMcMasa->chnlToFoaEvenMtx_fx[1][i] = L_shl( getSineWord16R2( extract_l( Mpy_32_32( ls_azimuth_even[i], 46603 /*2^24/360*/ ) ) ), 16 ); // Q31
448 1893 : move32();
449 1893 : hMcMasa->chnlToFoaEvenMtx_fx[2][i] = 0;
450 1893 : move32();
451 1893 : hMcMasa->chnlToFoaEvenMtx_fx[3][i] = L_shl( getCosWord16R2( extract_l( Mpy_32_32( ls_azimuth_even[i], 46603 /*2^24/360*/ ) ) ), 16 );
452 1893 : move32();
453 : }
454 :
455 277 : hMcMasa->combineRatios = hMasa->config.mergeRatiosOverSubframes;
456 277 : move16();
457 :
458 277 : Copy32( ls_azimuth, hMcMasa->ls_azimuth_fx, numAnalysisChannels ); // Q22
459 :
460 1810 : FOR( i = 0; i < hMcMasa->numHorizontalChannels; i++ )
461 : {
462 1533 : left_min = ( 360 << 22 );
463 1533 : right_min = -( ( 360 << 22 ) );
464 :
465 10214 : FOR( j = 0; j < hMcMasa->numHorizontalChannels; j++ )
466 : {
467 8681 : azi_diff = L_sub( ls_azimuth[j], ls_azimuth[i] );
468 :
469 8681 : IF( GT_32( azi_diff, ( 180 << 22 ) ) )
470 : {
471 466 : azi_diff = L_sub( azi_diff, 360 << 22 );
472 : }
473 8215 : ELSE IF( LT_32( azi_diff, -( 180 << 22 ) ) )
474 : {
475 466 : azi_diff = L_add( azi_diff, 360 << 22 );
476 : }
477 8681 : test();
478 8681 : IF( LT_32( azi_diff, left_min ) && azi_diff > 0 )
479 : {
480 2336 : hMcMasa->leftNearest[i] = j;
481 2336 : move16();
482 2336 : left_min = azi_diff;
483 2336 : move32();
484 : }
485 8681 : test();
486 8681 : IF( GT_32( azi_diff, right_min ) && azi_diff < 0 )
487 : {
488 2059 : hMcMasa->rightNearest[i] = j;
489 2059 : move16();
490 2059 : right_min = azi_diff;
491 2059 : move32();
492 : }
493 : }
494 : }
495 :
496 277 : hMcMasa->prevMultiChEne_fx = 0;
497 277 : move32();
498 277 : hMcMasa->prevDownmixEne_fx = 0;
499 277 : move32();
500 277 : hMcMasa->prevMultiChEne_e = 0;
501 277 : move16();
502 277 : hMcMasa->prevDownmixEne_e = 0;
503 277 : move16();
504 277 : hMcMasa->prevEQ_e = 1;
505 277 : move16();
506 277 : hMcMasa->prevEQ_fx = 1073741824;
507 277 : move32();
508 277 : input_frame = (Word16) Mpy_32_32( input_Fs, ONE_BY_FRAMES_PER_SEC_Q31 );
509 253397 : FOR( i = 0; i < input_frame; i++ )
510 : {
511 253120 : hMcMasa->interpolator_fx[i] = div_s( i, input_frame );
512 253120 : move16();
513 : }
514 :
515 277 : mvs2s( DirAC_block_grouping_5ms_MDFT, hMcMasa->block_grouping, MAX_PARAM_SPATIAL_SUBFRAMES + 1 );
516 :
517 277 : hMcMasa->index_buffer_intensity = 0;
518 277 : move16();
519 277 : st_ivas->hMcMasa = hMcMasa;
520 :
521 277 : return error;
522 : }
523 : /*-------------------------------------------------------------------------
524 : * ivas_mcmasa_enc_reconfig()
525 : *
526 : * Reconfigure McMASA encoder
527 : *------------------------------------------------------------------------*/
528 :
529 46 : ivas_error ivas_mcmasa_enc_reconfig_fx(
530 : Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */
531 : )
532 : {
533 : Word32 ivas_total_brate;
534 : ivas_error error;
535 :
536 46 : error = IVAS_ERR_OK;
537 46 : move32();
538 :
539 46 : ivas_total_brate = st_ivas->hEncoderConfig->ivas_total_brate;
540 46 : move32();
541 :
542 46 : IF( NE_32( ivas_total_brate, st_ivas->hEncoderConfig->last_ivas_total_brate ) )
543 : {
544 : /* bitrate changed, may need to do something */
545 :
546 : /* brute-force solution: close McMASA and re-instantiate with new settings */
547 46 : ivas_masa_enc_close_fx( &( st_ivas->hMasa ) );
548 :
549 46 : ivas_mcmasa_enc_close_fx( &( st_ivas->hMcMasa ), st_ivas->hEncoderConfig->input_Fs );
550 :
551 : /* Determine if to separate some channels from the analysis */
552 46 : ivas_mcmasa_setNumTransportChannels_fx( &( st_ivas->nchan_transport ), &( st_ivas->hEncoderConfig->element_mode_init ), ivas_total_brate );
553 :
554 46 : IF( NE_32( ( error = ivas_masa_enc_open_fx( st_ivas ) ), IVAS_ERR_OK ) )
555 : {
556 0 : return error;
557 : }
558 46 : IF( NE_32( ( error = ivas_mcmasa_enc_open_fx( st_ivas ) ), IVAS_ERR_OK ) )
559 : {
560 0 : return error;
561 : }
562 :
563 : /* core SCE, CPE reconfiguration happens later */
564 : }
565 :
566 46 : return error;
567 : }
568 : /*--------------------------------------------------------------------------*
569 : * ivas_mcmasa_enc_close()
570 : *
571 : *
572 : *--------------------------------------------------------------------------*/
573 :
574 1271 : void ivas_mcmasa_enc_close_fx(
575 : MCMASA_ENC_HANDLE *hMcMasa, /* i/o: encoder McMASA handle */
576 : const Word32 input_Fs /* i : input sampling rate */
577 : )
578 : {
579 : Word16 i, j;
580 :
581 1271 : test();
582 1271 : IF( hMcMasa == NULL || *hMcMasa == NULL )
583 : {
584 994 : return;
585 : }
586 :
587 277 : IF( ( *hMcMasa )->separateChannelEnabled )
588 : {
589 28 : free( ( *hMcMasa )->delay_buffer_lfe[0] );
590 28 : free( ( *hMcMasa )->delay_buffer_lfe[1] );
591 :
592 84 : FOR( i = 0; i < 2; i++ )
593 : {
594 56 : free( ( *hMcMasa )->lfeAnaRingBuffer[i] );
595 : }
596 : }
597 :
598 277 : ivas_FB_mixer_close_fx( &( *hMcMasa )->hFbMixer, input_Fs, 0 );
599 :
600 277 : IF( !( *hMcMasa )->separateChannelEnabled )
601 : {
602 249 : ivas_FB_mixer_close_fx( &( *hMcMasa )->hFbMixerLfe, input_Fs, 0 );
603 : }
604 :
605 : /* intensity 3-dim */
606 1108 : FOR( i = 0; i < DIRAC_NUM_DIMS; i++ )
607 : {
608 4155 : FOR( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ )
609 : {
610 3324 : free( ( *hMcMasa )->direction_vector_m_fx[i][j] );
611 3324 : ( *hMcMasa )->direction_vector_m_fx[i][j] = NULL;
612 : }
613 4155 : FOR( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ )
614 : {
615 3324 : free( ( *hMcMasa )->direction_vector_e[i][j] );
616 3324 : ( *hMcMasa )->direction_vector_e[i][j] = NULL;
617 : }
618 :
619 7479 : FOR( j = 0; j < ( *hMcMasa )->no_col_avg_diff; j++ )
620 : {
621 6648 : free( ( *hMcMasa )->buffer_intensity_real_fx[i][j] );
622 6648 : ( *hMcMasa )->buffer_intensity_real_fx[i][j] = NULL;
623 : }
624 :
625 831 : free( ( *hMcMasa )->buffer_intensity_real_fx[i] );
626 831 : ( *hMcMasa )->buffer_intensity_real_fx[i] = NULL;
627 :
628 831 : free( ( *hMcMasa )->direction_vector_m_fx[i] );
629 831 : ( *hMcMasa )->direction_vector_m_fx[i] = NULL;
630 :
631 831 : free( ( *hMcMasa )->direction_vector_e[i] );
632 831 : ( *hMcMasa )->direction_vector_e[i] = NULL;
633 : }
634 :
635 2493 : FOR( j = 0; j < ( *hMcMasa )->no_col_avg_diff; j++ )
636 : {
637 2216 : free( ( *hMcMasa )->buffer_intensity_real_vert_fx[j] );
638 2216 : ( *hMcMasa )->buffer_intensity_real_vert_fx[j] = NULL;
639 : }
640 277 : free( ( *hMcMasa )->buffer_intensity_real_vert_fx );
641 277 : ( *hMcMasa )->buffer_intensity_real_vert_fx = NULL;
642 :
643 277 : free( ( *hMcMasa )->buffer_energy_fx );
644 277 : ( *hMcMasa )->buffer_energy_fx = NULL;
645 :
646 277 : free( ( *hMcMasa ) );
647 277 : ( *hMcMasa ) = NULL;
648 :
649 277 : return;
650 : }
651 : /*--------------------------------------------------------------------------*
652 : * ivas_mcmasa_enc()
653 : *
654 : * Multichannel MASA encoder
655 : *--------------------------------------------------------------------------*/
656 :
657 11470 : void ivas_mcmasa_enc_fx(
658 : MCMASA_ENC_HANDLE hMcMasa, /* i/o: Encoder McMASA handle */
659 : IVAS_QMETADATA_HANDLE hQMeta, /* o : Qmetadata handle */
660 : MASA_ENCODER_HANDLE hMasa, /* i/o: Encoder MASA handle */
661 : Word32 *data_fx[], /* i : Input frame of audio Q(q_inp) */
662 : const Word16 input_frame, /* i : Input frame size */
663 : const Word16 nchan_transport, /* i : Number of transport channels */
664 : const Word16 nchan_inp, /* i : Number of input channels */
665 : const Word16 q_inp /* i : Input data q-format */
666 : )
667 : {
668 : Word16 i, j, k;
669 11470 : Word16 nBands = hMcMasa->nbands;
670 11470 : move16();
671 11470 : Word16 nBlocks = MAX_PARAM_SPATIAL_SUBFRAMES;
672 11470 : move16();
673 11470 : UWord8 fixedDistance = 0;
674 11470 : move16();
675 : Word32 elevation_m_values_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; // Q22
676 : Word32 azimuth_m_values_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; // Q22
677 : Word32 energyRatio_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; // Q31
678 : Word32 spreadCoherence_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; // Q30
679 : Word32 surroundingCoherence_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; // Q31
680 : Word32 separatedChannelSignal[L_FRAME48k];
681 :
682 : /* Compute low frequency energy */
683 11470 : computeLfeEnergy_fx( hMcMasa, data_fx, input_frame, q_inp );
684 :
685 : /* Sum center and LFE, move surround channels */
686 11470 : v_add_32( data_fx[2], data_fx[3], data_fx[2], input_frame ); // q_inp
687 42430 : FOR( i = 4; i < nchan_inp; i++ )
688 : {
689 30960 : Copy32( data_fx[i], data_fx[i - 1], input_frame ); // q_inp
690 : }
691 :
692 11470 : IF( hMcMasa->separateChannelEnabled )
693 : {
694 : /* Identify channel to separate */
695 625 : i = hMcMasa->separateChannelIndex;
696 625 : move16();
697 :
698 : /* Separate the identified channel */
699 625 : Copy32( data_fx[i], separatedChannelSignal, input_frame ); // q_inp
700 :
701 : /* Move the remaining channels in order to perform the analysis without the separated channel */
702 5585 : FOR( i = ( hMcMasa->separateChannelIndex + 1 ); i < ( nchan_inp - 1 ); i++ )
703 : {
704 4960 : Copy32( data_fx[i], data_fx[i - 1], input_frame ); // q_inp
705 : }
706 : }
707 :
708 : /* Analysis */
709 11470 : ivas_mcmasa_param_est_enc_fx( hMcMasa, hMasa, data_fx, elevation_m_values_fx, azimuth_m_values_fx, energyRatio_fx, spreadCoherence_fx, surroundingCoherence_fx, input_frame, nchan_inp, q_inp );
710 :
711 : /* Determine LFE-to-total energy ratio */
712 57350 : FOR( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ )
713 : {
714 45880 : hMasa->data.lfeToTotalEnergyRatio_fx[i] = L_deposit_h( BASOP_Util_Divide3232_Scale( hMcMasa->lfeLfEne[i], L_add( EPSILON_FX, hMcMasa->totalLfEne[i] ), &hMasa->data.lfeToTotalEnergyRatio_e[i] ) ); // hMasa->data.lfeToTotalEnergyRatio_e[i]
715 45880 : hMasa->data.lfeToTotalEnergyRatio_e[i] = add( sub( hMcMasa->lfeLfEne_e[i], hMcMasa->totalLfEne_e[i] ), hMasa->data.lfeToTotalEnergyRatio_e[i] );
716 45880 : move32();
717 45880 : move16();
718 : }
719 :
720 : /* Set analyzed values to the MASA struct */
721 68820 : FOR( i = 0; i < nBands; i++ )
722 : {
723 286750 : FOR( j = 0; j < nBlocks; j++ )
724 : {
725 229400 : IF( hMcMasa->combineRatios )
726 : {
727 229400 : k = 0;
728 229400 : move16();
729 : }
730 : ELSE
731 : {
732 0 : k = j;
733 0 : move16();
734 : }
735 :
736 229400 : hQMeta->q_direction[0].band_data[i].azimuth_fx[j] = azimuth_m_values_fx[j][i]; // Q22
737 229400 : move32();
738 229400 : hQMeta->q_direction[0].band_data[i].elevation_fx[j] = elevation_m_values_fx[j][i]; // Q22
739 229400 : move32();
740 229400 : hQMeta->q_direction[0].band_data[i].energy_ratio_fx[j] = energyRatio_fx[k][i]; // Q30
741 229400 : move32();
742 229400 : hQMeta->q_direction[0].band_data[i].distance[j] = fixedDistance;
743 229400 : move16();
744 :
745 229400 : IF( hQMeta->surcoh_band_data != NULL )
746 : {
747 202200 : hQMeta->q_direction[0].coherence_band_data[i].spread_coherence[j] = (UWord8) round_fx( Mpy_32_32( spreadCoherence_fx[j][i], L_shl( UINT8_MAX, Q17 ) ) ); // Q0
748 202200 : hQMeta->surcoh_band_data[i].surround_coherence[j] = (UWord8) round_fx( Mpy_32_32( surroundingCoherence_fx[k][i], L_shl( UINT8_MAX, Q16 ) ) ); // Q0
749 202200 : move16();
750 202200 : move16();
751 : }
752 : }
753 : }
754 :
755 : /* At lower sampling rates, set zeros for higher bands that were not analyzed */
756 11470 : IF( LT_16( nBands, hMcMasa->nCodingBands ) )
757 : {
758 0 : FOR( i = nBands; i < hMcMasa->nCodingBands; i++ )
759 : {
760 0 : FOR( j = 0; j < nBlocks; j++ )
761 : {
762 0 : hQMeta->q_direction[0].band_data[i].azimuth_fx[j] = 0; // Q22
763 0 : move32();
764 0 : hQMeta->q_direction[0].band_data[i].elevation_fx[j] = 0; // Q22
765 0 : move32();
766 0 : hQMeta->q_direction[0].band_data[i].energy_ratio_fx[j] = 0; // Q30
767 0 : move32();
768 0 : hQMeta->q_direction[0].band_data[i].distance[j] = 0;
769 0 : move16();
770 :
771 0 : IF( hQMeta->surcoh_band_data != NULL )
772 : {
773 0 : hQMeta->q_direction[0].coherence_band_data[i].spread_coherence[j] = 0;
774 0 : move16();
775 0 : hQMeta->surcoh_band_data[i].surround_coherence[j] = 0;
776 0 : move16();
777 : }
778 : }
779 : }
780 : }
781 :
782 : /* Downmix */
783 11470 : ivas_mcmasa_dmx_fx( hMcMasa, data_fx, sub( 31, q_inp ), input_frame, nchan_transport, nchan_inp );
784 :
785 11470 : IF( hMcMasa->separateChannelEnabled )
786 : {
787 : /* Put separated channel back to data_f to first empty channel after the transport audio signals for encoding */
788 625 : Copy32( separatedChannelSignal, data_fx[2], input_frame );
789 : }
790 :
791 : /* Update mcMASA-relevant coding parameters */
792 : /* These are reset to default values as they may be modified during later processing. */
793 11470 : hMasa->config.joinedSubframes = FALSE;
794 11470 : move16();
795 11470 : hQMeta->q_direction[0].cfg.nbands = hMcMasa->nbands;
796 11470 : move16();
797 11470 : hQMeta->q_direction[0].cfg.nblocks = MAX_PARAM_SPATIAL_SUBFRAMES;
798 11470 : move16();
799 11470 : hQMeta->all_coherence_zero = 1;
800 11470 : move16();
801 :
802 : /* Check spread coherence */
803 11470 : i = 0;
804 11470 : move16();
805 11470 : test();
806 25892 : WHILE( ( i < nBlocks ) && hQMeta->all_coherence_zero )
807 : {
808 14422 : test();
809 14422 : j = 0;
810 14422 : move16();
811 14422 : test();
812 44499 : WHILE( LT_16( j, nBands ) && hQMeta->all_coherence_zero )
813 : {
814 30077 : test();
815 30077 : IF( GT_32( spreadCoherence_fx[i][j], MASA_COHERENCE_THRESHOLD_FX >> 1 ) )
816 : {
817 10678 : hQMeta->all_coherence_zero = 0;
818 10678 : move16();
819 : }
820 30077 : j++;
821 : }
822 14422 : i++;
823 : }
824 :
825 : /* Check surrounding coherence */
826 11470 : IF( hQMeta->all_coherence_zero )
827 : {
828 : Word32 diffuse_to_total_ratio_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
829 : UWord8 cohSignificant;
830 : Word16 nSubFrames;
831 :
832 792 : IF( hMcMasa->combineRatios )
833 : {
834 792 : nSubFrames = 1;
835 792 : move16();
836 : }
837 : ELSE
838 : {
839 0 : nSubFrames = MAX_PARAM_SPATIAL_SUBFRAMES;
840 0 : move16();
841 : }
842 :
843 1584 : FOR( i = 0; i < nSubFrames; i++ )
844 : {
845 4752 : FOR( j = 0; j < nBands; j++ )
846 : {
847 3960 : diffuse_to_total_ratio_fx[i][j] = L_max( 0, L_sub( ONE_IN_Q31, energyRatio_fx[i][j] ) ); // Q31
848 3960 : move32();
849 : }
850 : }
851 :
852 792 : cohSignificant = ivas_masa_surrcoh_signicant_fx( surroundingCoherence_fx, diffuse_to_total_ratio_fx, nSubFrames, nBands );
853 792 : IF( cohSignificant )
854 : {
855 417 : hQMeta->all_coherence_zero = 0;
856 417 : move16();
857 : }
858 : }
859 11470 : hMasa->config.coherencePresent = !hQMeta->all_coherence_zero;
860 11470 : move16();
861 :
862 11470 : return;
863 : }
864 :
865 : /*--------------------------------------------------------------------------*
866 : * ivas_mcmasa_param_est_enc()
867 : *
868 : * Estimate metadata parameters for McMASA
869 : *--------------------------------------------------------------------------*/
870 :
871 11470 : void ivas_mcmasa_param_est_enc_fx(
872 : MCMASA_ENC_HANDLE hMcMasa, /* i : McMASA encoder structure */
873 : MASA_ENCODER_HANDLE hMasa, /* i : MASA encoder structure */
874 : Word32 *data_f[], /* i : Audio frame in MC-format Q(q_inp) */
875 : Word32 elevation_m_values_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* o : Estimated elevation Q22 */
876 : Word32 azimuth_m_values_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* o : Estimated azimuth Q22 */
877 : Word32 energyRatio_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* o : Estimated direct-to-total ratio Q31 */
878 : Word32 spreadCoherence_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* o : Estimated spread coherence Q30 */
879 : Word32 surroundingCoherence_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* o : Estimated surround coherence Q31 */
880 : const Word16 input_frame, /* i : Input frame size */
881 : const Word16 nchan_inp, /* i : Number of input channels */
882 : const Word16 q_inp /* i : Q factor of the data_f */
883 : )
884 : {
885 : Word32 reference_power_fx[MDFT_NO_COL_MAX][DIRAC_NO_FB_BANDS_MAX];
886 : Word16 ts, i, j, d;
887 : Word16 num_freq_bins, num_freq_bands, index;
888 : Word32 dir_v_fx[DIRAC_NUM_DIMS];
889 : Word16 out_exp[MASA_FREQUENCY_BANDS];
890 : Word16 q_vdv[MASA_FREQUENCY_BANDS];
891 : Word16 l_ts;
892 : Word32 *pcm_in[MCMASA_MAX_ANA_CHANS];
893 : Word32 Chnl_RealBuffer_fx[MCMASA_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX];
894 : Word32 Chnl_ImagBuffer_fx[MCMASA_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX];
895 : Word32 *p_Chnl_RealBuffer_fx[MCMASA_MAX_ANA_CHANS];
896 : Word32 *p_Chnl_ImagBuffer_fx[MCMASA_MAX_ANA_CHANS];
897 : Word32 Foa_RealBuffer_fx[FOA_CHANNELS][DIRAC_NO_FB_BANDS_MAX];
898 : Word32 Foa_ImagBuffer_fx[FOA_CHANNELS][DIRAC_NO_FB_BANDS_MAX];
899 : Word32 FoaEven_RealBuffer_fx[FOA_CHANNELS][DIRAC_NO_FB_BANDS_MAX];
900 : Word32 FoaEven_ImagBuffer_fx[FOA_CHANNELS][DIRAC_NO_FB_BANDS_MAX];
901 : Word32 intensity_real_fx[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS];
902 : Word32 intensity_even_real_fx[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS];
903 : Word32 direction_vector_fx[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS];
904 : Word32 diffuseness_vector_fx[MASA_FREQUENCY_BANDS];
905 : Word32 vertical_diffuseness_vector_fx[MASA_FREQUENCY_BANDS]; // q_vdv
906 : Word32 diffuseness_m_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; // diffuseness_e
907 : Word16 diffuseness_e[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
908 : Word32 coherentEnergyRatio_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; // coherentEnergyRatio_e
909 : Word16 coherentEnergyRatio_e[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
910 : Word16 band_m_idx, block_m_idx;
911 : Word32 renormalization_factor_diff_fx[MASA_FREQUENCY_BANDS]; // renormalization_factor_diff_e
912 : Word16 renormalization_factor_diff_e[MASA_FREQUENCY_BANDS];
913 : Word32 norm_tmp_fx;
914 : Word16 mrange[2], brange[2];
915 : Word16 numSubFramesForRatio;
916 : CovarianceMatrix COVls[MASA_FREQUENCY_BANDS];
917 : Word32 absCOVls_fx[MCMASA_MAX_ANA_CHANS][MCMASA_MAX_ANA_CHANS];
918 : Word16 absCOVls_e[MCMASA_MAX_ANA_CHANS][MCMASA_MAX_ANA_CHANS];
919 : Word32 lsEnergy_fx[MCMASA_MAX_ANA_CHANS]; // lsEnergy_e
920 : Word16 lsEnergy_e[MCMASA_MAX_ANA_CHANS];
921 : Word32 lsEnergySum_fx, maxEne_fx;
922 11470 : Word16 lsEnergySum_e = 0, maxEne_e;
923 11470 : move16();
924 : Word16 loudestCh;
925 : Word32 surrCoh_fx, tempCoh_fx, tempCoh2_fx;
926 : Word16 surrCoh_e, tempCoh_e, tempCoh2_e;
927 : Word16 i1, i2, i3;
928 : Word32 angleDist_fx, minAngleDist_fx;
929 : Word32 currentAzi_fx;
930 : Word32 lsEnergyRelation_fx; // lsEnergyRelation_e
931 : Word16 lsEnergyRelation_e;
932 : Word32 tempLsEnergyRelation_fx; // tempLsEnergyRelation_e
933 : Word16 tempLsEnergyRelation_e;
934 : Word32 stereoness_fx, cohwideness_fx, spreadCoh_fx;
935 : Word32 stereoRatio_fx, cohPanRatio_fx;
936 : Word32 stereoCoh_fx, cohPanCoh_fx, cohRatio_fx;
937 : Word16 stereoCoh_e, cohPanCoh_e, spreadCoh_e, stereoness_e;
938 : Word32 renormalization_factor_coh_fx[MASA_FREQUENCY_BANDS]; // renormalization_factor_coh_e
939 : Word16 renormalization_factor_coh_e[MASA_FREQUENCY_BANDS];
940 : Word16 surroundingCoherence_e[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
941 : Word16 numAnalysisChannels;
942 :
943 137640 : FOR( i = 0; i < MCMASA_MAX_ANA_CHANS; i++ )
944 : {
945 126170 : set_zero_fx( Chnl_RealBuffer_fx[i], DIRAC_NO_FB_BANDS_MAX );
946 126170 : set_zero_fx( Chnl_ImagBuffer_fx[i], DIRAC_NO_FB_BANDS_MAX );
947 : }
948 :
949 11470 : num_freq_bins = idiv1616( input_frame, MDFT_NO_COL_MAX );
950 11470 : num_freq_bands = hMcMasa->nbands;
951 11470 : move16();
952 11470 : l_ts = idiv1616( input_frame, MDFT_NO_COL_MAX );
953 :
954 11470 : set16_fx( q_vdv, 31, MASA_FREQUENCY_BANDS );
955 11470 : set16_fx( out_exp, 30, MASA_FREQUENCY_BANDS );
956 :
957 11470 : numAnalysisChannels = sub( nchan_inp, 1 );
958 11470 : IF( hMcMasa->separateChannelEnabled )
959 : {
960 625 : numAnalysisChannels = sub( nchan_inp, 2 );
961 : }
962 :
963 11470 : IF( hMcMasa->combineRatios )
964 : {
965 : /* Need to initialize renormalization_factors, and variables to be normalized */
966 11470 : set_zero_fx( renormalization_factor_diff_fx, hMcMasa->nbands ); // renormalization_factor_diff_e
967 11470 : set16_fx( renormalization_factor_diff_e, 0, hMcMasa->nbands );
968 11470 : set_zero_fx( &diffuseness_m_fx[0][0], MASA_FREQUENCY_BANDS * MAX_PARAM_SPATIAL_SUBFRAMES ); // diffuseness_e
969 11470 : set16_fx( &diffuseness_e[0][0], 31, MASA_FREQUENCY_BANDS * MAX_PARAM_SPATIAL_SUBFRAMES );
970 11470 : set_zero_fx( renormalization_factor_coh_fx, hMcMasa->nbands ); // renormalization_factor_coh_e
971 11470 : set16_fx( renormalization_factor_coh_e, 31, hMcMasa->nbands );
972 11470 : set_zero_fx( surroundingCoherence_fx[0], hMcMasa->nbands ); // surroundingCoherence_e
973 11470 : set16_fx( &surroundingCoherence_e[0][0], 31, MASA_FREQUENCY_BANDS * MAX_PARAM_SPATIAL_SUBFRAMES );
974 11470 : set_zero_fx( coherentEnergyRatio_fx[0], hMcMasa->nbands ); // coherentEnergyRatio_e
975 11470 : set16_fx( &coherentEnergyRatio_e[0][0], 0, MASA_FREQUENCY_BANDS * MAX_PARAM_SPATIAL_SUBFRAMES );
976 : }
977 :
978 : /* Copy current frame to memory for delay compensation */
979 76215 : FOR( i = 0; i < numAnalysisChannels; i++ )
980 : {
981 64745 : pcm_in[i] = data_f[i]; // q_inp
982 64745 : p_Chnl_RealBuffer_fx[i] = &Chnl_RealBuffer_fx[i][0]; // q_inp
983 64745 : p_Chnl_ImagBuffer_fx[i] = &Chnl_ImagBuffer_fx[i][0]; // q_inp
984 : }
985 :
986 : /* initialising energy_fx */
987 57350 : FOR( block_m_idx = 0; block_m_idx < MAX_PARAM_SPATIAL_SUBFRAMES; block_m_idx++ )
988 : {
989 1147000 : FOR( i = 0; i < MASA_FREQUENCY_BANDS; i++ )
990 : {
991 1101120 : hMasa->data.energy_fx[block_m_idx][i] = 0; // hMasa->data.energy_e
992 1101120 : move32();
993 1101120 : hMasa->data.energy_e[block_m_idx][i] = 31;
994 1101120 : move16();
995 : }
996 : }
997 11470 : hMasa->data.q_energy = 0;
998 11470 : move16();
999 :
1000 : /* do processing over all CLDFB time slots */
1001 57350 : FOR( block_m_idx = 0; block_m_idx < MAX_PARAM_SPATIAL_SUBFRAMES; block_m_idx++ )
1002 : {
1003 45880 : mrange[0] = hMcMasa->block_grouping[block_m_idx];
1004 45880 : move16();
1005 45880 : mrange[1] = hMcMasa->block_grouping[block_m_idx + 1];
1006 45880 : move16();
1007 :
1008 275280 : FOR( band_m_idx = 0; band_m_idx < hMcMasa->nbands; band_m_idx++ )
1009 : {
1010 229400 : hMcMasa->direction_vector_m_fx[0][block_m_idx][band_m_idx] = 0;
1011 229400 : move32();
1012 229400 : hMcMasa->direction_vector_m_fx[1][block_m_idx][band_m_idx] = 0;
1013 229400 : move32();
1014 229400 : hMcMasa->direction_vector_m_fx[2][block_m_idx][band_m_idx] = 0;
1015 229400 : move32();
1016 : }
1017 :
1018 : /* Reset variable */
1019 275280 : FOR( i = 0; i < hMcMasa->nbands; i++ )
1020 : {
1021 1524300 : FOR( j = 0; j < numAnalysisChannels; j++ )
1022 : {
1023 1294900 : set_zero_fx( COVls[i].xr_fx[j], numAnalysisChannels ); // COVls[i].xr_e[j]
1024 1294900 : set_zero_fx( COVls[i].xi_fx[j], numAnalysisChannels ); // COVls[i].xi_e[j]
1025 1294900 : set16_fx( COVls[i].xr_e[j], 0, numAnalysisChannels );
1026 1294900 : set16_fx( COVls[i].xi_e[j], 0, numAnalysisChannels );
1027 : }
1028 : }
1029 :
1030 91760 : FOR( ts = mrange[0]; ts < mrange[1]; ts++ )
1031 : {
1032 45880 : Word16 cr_q = MAX_16, ci_q = MAX_16, sf, c_e;
1033 45880 : Word16 inp_q = q_inp;
1034 45880 : move16();
1035 45880 : move16();
1036 45880 : move16();
1037 :
1038 45880 : ivas_fb_mixer_get_windowed_fr_fx( hMcMasa->hFbMixer, pcm_in, p_Chnl_RealBuffer_fx, p_Chnl_ImagBuffer_fx, l_ts, l_ts, hMcMasa->hFbMixer->fb_cfg->num_in_chans, 0 );
1039 :
1040 45880 : ivas_fb_mixer_update_prior_input_fx( hMcMasa->hFbMixer, pcm_in, l_ts, hMcMasa->hFbMixer->fb_cfg->num_in_chans );
1041 :
1042 304860 : FOR( i = 0; i < numAnalysisChannels; i++ )
1043 : {
1044 258980 : pcm_in[i] += l_ts;
1045 258980 : cr_q = s_min( cr_q, L_norm_arr( Chnl_ImagBuffer_fx[i], DIRAC_NO_FB_BANDS_MAX ) );
1046 258980 : ci_q = s_min( ci_q, L_norm_arr( Chnl_RealBuffer_fx[i], DIRAC_NO_FB_BANDS_MAX ) );
1047 : }
1048 :
1049 45880 : sf = sub( s_min( cr_q, ci_q ), 5 );
1050 304860 : FOR( i = 0; i < numAnalysisChannels; i++ )
1051 : {
1052 258980 : scale_sig32( Chnl_RealBuffer_fx[i], DIRAC_NO_FB_BANDS_MAX, sf ); // Q-> inp_q + sf
1053 258980 : scale_sig32( Chnl_ImagBuffer_fx[i], DIRAC_NO_FB_BANDS_MAX, sf ); // Q-> inp_q + sf
1054 : }
1055 45880 : inp_q = add( inp_q, sf );
1056 45880 : c_e = sub( 31, inp_q );
1057 :
1058 : /* Compute covariance matrix */
1059 275280 : FOR( i = 0; i < num_freq_bands; i++ )
1060 : {
1061 229400 : brange[0] = hMcMasa->band_grouping[i];
1062 229400 : move16();
1063 229400 : brange[1] = hMcMasa->band_grouping[i + 1];
1064 229400 : move16();
1065 11176600 : FOR( j = brange[0]; j < brange[1]; j++ )
1066 : {
1067 10947200 : compute_cov_mtx_fx( Chnl_RealBuffer_fx, Chnl_ImagBuffer_fx, j, numAnalysisChannels, &( COVls[i] ), sub( 31, inp_q ) );
1068 : }
1069 :
1070 : /* Store energies for guiding metadata encoding */
1071 1524300 : FOR( j = 0; j < numAnalysisChannels; j++ )
1072 : {
1073 1294900 : move32();
1074 1294900 : hMasa->data.energy_fx[block_m_idx][i] = BASOP_Util_Add_Mant32Exp( hMasa->data.energy_fx[block_m_idx][i], hMasa->data.energy_e[block_m_idx][i], COVls[i].xr_fx[j][j], COVls[i].xr_e[j][j], &hMasa->data.energy_e[block_m_idx][i] );
1075 : }
1076 : }
1077 :
1078 45880 : IF( !hMcMasa->separateChannelEnabled )
1079 : {
1080 : /* Compute low frequency energy */
1081 277520 : FOR( i = 0; i < numAnalysisChannels; i++ )
1082 : {
1083 1170700 : FOR( j = 0; j < CLDFB_TO_MDFT_FAC; j++ )
1084 : {
1085 936560 : move32();
1086 936560 : hMcMasa->totalLfEne[block_m_idx] = BASOP_Util_Add_Mant32Exp( hMcMasa->totalLfEne[block_m_idx], hMcMasa->totalLfEne_e[block_m_idx], L_add( Mpy_32_32( Chnl_RealBuffer_fx[i][j], Chnl_RealBuffer_fx[i][j] ), Mpy_32_32( Chnl_ImagBuffer_fx[i][j], Chnl_ImagBuffer_fx[i][j] ) ), sub( 31, sub( shl( inp_q, 1 ), 31 ) ), &hMcMasa->totalLfEne_e[block_m_idx] );
1087 : }
1088 : }
1089 : }
1090 :
1091 : /* Compute standard FOA */
1092 : /* W */
1093 45880 : v_add_32( Chnl_RealBuffer_fx[0], Chnl_RealBuffer_fx[1], Foa_RealBuffer_fx[0], num_freq_bins ); // inp_q
1094 45880 : v_add_32( Chnl_ImagBuffer_fx[0], Chnl_ImagBuffer_fx[1], Foa_ImagBuffer_fx[0], num_freq_bins ); // inp_q
1095 213100 : FOR( i = 2; i < numAnalysisChannels; i++ )
1096 : {
1097 167220 : v_add_32( Chnl_RealBuffer_fx[i], Foa_RealBuffer_fx[0], Foa_RealBuffer_fx[0], num_freq_bins ); // inp_q
1098 167220 : v_add_32( Chnl_ImagBuffer_fx[i], Foa_ImagBuffer_fx[0], Foa_ImagBuffer_fx[0], num_freq_bins ); // inp_q
1099 : }
1100 :
1101 : /* Y */
1102 45880 : v_multc_fixed( Chnl_RealBuffer_fx[0], hMcMasa->chnlToFoaMtx_fx[1][0], Foa_RealBuffer_fx[1], num_freq_bins ); // inp_q
1103 45880 : v_multc_fixed( Chnl_ImagBuffer_fx[0], hMcMasa->chnlToFoaMtx_fx[1][0], Foa_ImagBuffer_fx[1], num_freq_bins ); // inp_q
1104 258980 : FOR( i = 1; i < numAnalysisChannels; i++ )
1105 : {
1106 213100 : v_multc_acc_32_32( Chnl_RealBuffer_fx[i], hMcMasa->chnlToFoaMtx_fx[1][i], Foa_RealBuffer_fx[1], num_freq_bins ); // inp_q
1107 213100 : v_multc_acc_32_32( Chnl_ImagBuffer_fx[i], hMcMasa->chnlToFoaMtx_fx[1][i], Foa_ImagBuffer_fx[1], num_freq_bins ); // inp_q
1108 : }
1109 :
1110 : /* Z */
1111 45880 : IF( hMcMasa->isHorizontalSetup )
1112 : {
1113 : /* Set zero for horizontal setups */
1114 39760 : set_zero_fx( Foa_RealBuffer_fx[2], num_freq_bins );
1115 39760 : set_zero_fx( Foa_ImagBuffer_fx[2], num_freq_bins );
1116 : }
1117 : ELSE
1118 : {
1119 6120 : v_multc_fixed( Chnl_RealBuffer_fx[0], hMcMasa->chnlToFoaMtx_fx[2][0], Foa_RealBuffer_fx[2], num_freq_bins ); // inp_q
1120 6120 : v_multc_fixed( Chnl_ImagBuffer_fx[0], hMcMasa->chnlToFoaMtx_fx[2][0], Foa_ImagBuffer_fx[2], num_freq_bins ); // inp_q
1121 59060 : FOR( i = 1; i < numAnalysisChannels; i++ )
1122 : {
1123 52940 : v_multc_acc_32_32( Chnl_RealBuffer_fx[i], hMcMasa->chnlToFoaMtx_fx[2][i], Foa_RealBuffer_fx[2], num_freq_bins ); // inp_q
1124 52940 : v_multc_acc_32_32( Chnl_ImagBuffer_fx[i], hMcMasa->chnlToFoaMtx_fx[2][i], Foa_ImagBuffer_fx[2], num_freq_bins ); // inp_q
1125 : }
1126 : }
1127 :
1128 : /* X */
1129 45880 : v_multc_fixed( Chnl_RealBuffer_fx[0], hMcMasa->chnlToFoaMtx_fx[3][0], Foa_RealBuffer_fx[3], num_freq_bins ); // inp_q
1130 45880 : v_multc_fixed( Chnl_ImagBuffer_fx[0], hMcMasa->chnlToFoaMtx_fx[3][0], Foa_ImagBuffer_fx[3], num_freq_bins ); // inp_q
1131 258980 : FOR( i = 1; i < numAnalysisChannels; i++ )
1132 : {
1133 213100 : v_multc_acc_32_32( Chnl_RealBuffer_fx[i], hMcMasa->chnlToFoaMtx_fx[3][i], Foa_RealBuffer_fx[3], num_freq_bins ); // inp_q
1134 213100 : v_multc_acc_32_32( Chnl_ImagBuffer_fx[i], hMcMasa->chnlToFoaMtx_fx[3][i], Foa_ImagBuffer_fx[3], num_freq_bins ); // inp_q
1135 : }
1136 :
1137 : /* Compute even FOA */
1138 : /* W */
1139 45880 : Copy32( Foa_RealBuffer_fx[0], FoaEven_RealBuffer_fx[0], num_freq_bins ); // inp_q
1140 45880 : Copy32( Foa_ImagBuffer_fx[0], FoaEven_ImagBuffer_fx[0], num_freq_bins ); // inp_q
1141 :
1142 : /* Y */
1143 45880 : v_multc_fixed( Chnl_RealBuffer_fx[0], hMcMasa->chnlToFoaEvenMtx_fx[1][0], FoaEven_RealBuffer_fx[1], num_freq_bins ); // inp_q
1144 45880 : v_multc_fixed( Chnl_ImagBuffer_fx[0], hMcMasa->chnlToFoaEvenMtx_fx[1][0], FoaEven_ImagBuffer_fx[1], num_freq_bins ); // inp_q
1145 258980 : FOR( i = 1; i < numAnalysisChannels; i++ )
1146 : {
1147 213100 : v_multc_acc_32_32( Chnl_RealBuffer_fx[i], hMcMasa->chnlToFoaEvenMtx_fx[1][i], FoaEven_RealBuffer_fx[1], num_freq_bins ); // inp_q
1148 213100 : v_multc_acc_32_32( Chnl_ImagBuffer_fx[i], hMcMasa->chnlToFoaEvenMtx_fx[1][i], FoaEven_ImagBuffer_fx[1], num_freq_bins ); // inp_q
1149 : }
1150 :
1151 : /* Z (even setups are handled as horizontal) */
1152 45880 : set_zero_fx( FoaEven_RealBuffer_fx[2], num_freq_bins ); // inp_q
1153 45880 : set_zero_fx( FoaEven_ImagBuffer_fx[2], num_freq_bins ); // inp_q
1154 :
1155 : /* X */
1156 45880 : v_multc_fixed( Chnl_RealBuffer_fx[0], hMcMasa->chnlToFoaEvenMtx_fx[3][0], FoaEven_RealBuffer_fx[3], num_freq_bins ); // inp_q
1157 45880 : v_multc_fixed( Chnl_ImagBuffer_fx[0], hMcMasa->chnlToFoaEvenMtx_fx[3][0], FoaEven_ImagBuffer_fx[3], num_freq_bins ); // inp_q
1158 258980 : FOR( i = 1; i < numAnalysisChannels; i++ )
1159 : {
1160 213100 : v_multc_acc_32_32( Chnl_RealBuffer_fx[i], hMcMasa->chnlToFoaEvenMtx_fx[3][i], FoaEven_RealBuffer_fx[3], num_freq_bins ); // inp_q
1161 213100 : v_multc_acc_32_32( Chnl_ImagBuffer_fx[i], hMcMasa->chnlToFoaEvenMtx_fx[3][i], FoaEven_ImagBuffer_fx[3], num_freq_bins ); // inp_q
1162 : }
1163 :
1164 : /* Direction estimation */
1165 45880 : computeIntensityVector_enc_fx(
1166 45880 : hMcMasa->band_grouping,
1167 : Foa_RealBuffer_fx,
1168 : Foa_ImagBuffer_fx,
1169 : 0,
1170 : num_freq_bands,
1171 : intensity_real_fx );
1172 :
1173 45880 : computeDirectionVectors_fixed(
1174 : intensity_real_fx[0],
1175 : intensity_real_fx[1],
1176 : intensity_real_fx[2],
1177 : 0,
1178 : num_freq_bands,
1179 : direction_vector_fx[0],
1180 : direction_vector_fx[1],
1181 : direction_vector_fx[2], c_e,
1182 : NULL );
1183 :
1184 : /* Power and intensity estimation for diffuseness */
1185 45880 : computeIntensityVector_enc_fx(
1186 45880 : hMcMasa->band_grouping,
1187 : FoaEven_RealBuffer_fx,
1188 : FoaEven_ImagBuffer_fx,
1189 : 0,
1190 : num_freq_bands,
1191 : intensity_even_real_fx );
1192 45880 : Word16 ref_e = 0;
1193 45880 : move16();
1194 45880 : computeReferencePower_enc_fx( hMcMasa->band_grouping,
1195 : FoaEven_RealBuffer_fx,
1196 : FoaEven_ImagBuffer_fx,
1197 45880 : reference_power_fx[ts],
1198 : 0,
1199 : num_freq_bands,
1200 : MC_FORMAT,
1201 : 0,
1202 : FOA_CHANNELS, inp_q, &ref_e );
1203 :
1204 : /* Fill buffers of length "averaging_length" time slots for intensity and energy */
1205 45880 : hMcMasa->index_buffer_intensity = add( ( hMcMasa->index_buffer_intensity % hMcMasa->no_col_avg_diff ), 1 ); /* averaging_length = 32 */
1206 45880 : move16();
1207 45880 : index = hMcMasa->index_buffer_intensity;
1208 45880 : move16();
1209 183520 : FOR( i = 0; i < DIRAC_NUM_DIMS; i++ )
1210 : {
1211 : /* only real part needed */
1212 137640 : Copy32( intensity_even_real_fx[i], &( hMcMasa->buffer_intensity_real_fx[i][index - 1][0] ), num_freq_bands ); // hMcMasa->buffer_intensity_real_q
1213 : }
1214 45880 : hMcMasa->buffer_intensity_real_q[index - 1] = sub( shl( inp_q, 1 ), 31 );
1215 45880 : move16();
1216 45880 : Copy32( reference_power_fx[ts], &( hMcMasa->buffer_energy_fx[( index - 1 ) * num_freq_bands] ), num_freq_bands ); // ref_e
1217 45880 : hMcMasa->buffer_energy_q[index - 1] = sub( Q31, ref_e );
1218 45880 : move16();
1219 :
1220 45880 : computeDiffuseness_mdft_fx( hMcMasa->buffer_intensity_real_fx, hMcMasa->buffer_energy_fx, num_freq_bands, hMcMasa->no_col_avg_diff, diffuseness_vector_fx, hMcMasa->buffer_intensity_real_q, hMcMasa->buffer_energy_q, &out_exp[0] );
1221 229400 : FOR( i = 1; i < num_freq_bands; i++ )
1222 : {
1223 183520 : out_exp[i] = out_exp[0];
1224 183520 : move16();
1225 : }
1226 : /* Compute vertical diffuseness, and tune original diffuseness if needed */
1227 45880 : IF( !hMcMasa->isHorizontalSetup )
1228 : {
1229 6120 : Copy32( intensity_real_fx[2], &( hMcMasa->buffer_intensity_real_vert_fx[index - 1][0] ), num_freq_bands );
1230 6120 : hMcMasa->buffer_intensity_real_vert_q[index - 1] = sub( shl( inp_q, 1 ), 31 );
1231 6120 : move16();
1232 6120 : computeVerticalDiffuseness_fx( hMcMasa->buffer_intensity_real_vert_fx, hMcMasa->buffer_energy_fx, hMcMasa->no_col_avg_diff, num_freq_bands, vertical_diffuseness_vector_fx, hMcMasa->buffer_intensity_real_vert_q, hMcMasa->buffer_energy_q );
1233 6120 : v_min_fx( diffuseness_vector_fx, out_exp, vertical_diffuseness_vector_fx, q_vdv, diffuseness_vector_fx, out_exp, num_freq_bands );
1234 : }
1235 :
1236 275280 : FOR( band_m_idx = 0; band_m_idx < hMcMasa->nbands; band_m_idx++ )
1237 : {
1238 229400 : norm_tmp_fx = Mult_32_32( reference_power_fx[ts][band_m_idx], L_sub( ONE_IN_Q31, diffuseness_vector_fx[band_m_idx] ) ); /*31-ref_e*/
1239 229400 : hMcMasa->direction_vector_m_fx[0][block_m_idx][band_m_idx] = BASOP_Util_Add_Mant32Exp( hMcMasa->direction_vector_m_fx[0][block_m_idx][band_m_idx], hMcMasa->direction_vector_e[0][block_m_idx][band_m_idx], Mult_32_32( norm_tmp_fx, direction_vector_fx[0][band_m_idx] ), add( 1, ref_e ), &hMcMasa->direction_vector_e[0][block_m_idx][band_m_idx] );
1240 229400 : move32();
1241 229400 : hMcMasa->direction_vector_m_fx[1][block_m_idx][band_m_idx] = BASOP_Util_Add_Mant32Exp( hMcMasa->direction_vector_m_fx[1][block_m_idx][band_m_idx], hMcMasa->direction_vector_e[1][block_m_idx][band_m_idx], Mult_32_32( norm_tmp_fx, direction_vector_fx[1][band_m_idx] ), add( 1, ref_e ), &hMcMasa->direction_vector_e[1][block_m_idx][band_m_idx] );
1242 229400 : move32();
1243 229400 : hMcMasa->direction_vector_m_fx[2][block_m_idx][band_m_idx] = BASOP_Util_Add_Mant32Exp( hMcMasa->direction_vector_m_fx[2][block_m_idx][band_m_idx], hMcMasa->direction_vector_e[2][block_m_idx][band_m_idx], Mult_32_32( norm_tmp_fx, direction_vector_fx[2][band_m_idx] ), add( 1, ref_e ), &hMcMasa->direction_vector_e[2][block_m_idx][band_m_idx] );
1244 229400 : move32();
1245 229400 : IF( hMcMasa->combineRatios )
1246 : {
1247 229400 : diffuseness_m_fx[0][band_m_idx] = BASOP_Util_Add_Mant32Exp( diffuseness_m_fx[0][band_m_idx], diffuseness_e[0][band_m_idx], Mult_32_32( reference_power_fx[ts][band_m_idx], diffuseness_vector_fx[band_m_idx] ), ref_e, &diffuseness_e[0][band_m_idx] );
1248 229400 : move32();
1249 229400 : renormalization_factor_diff_fx[band_m_idx] = BASOP_Util_Add_Mant32Exp( renormalization_factor_diff_fx[band_m_idx], renormalization_factor_diff_e[band_m_idx], reference_power_fx[ts][band_m_idx], ref_e, &renormalization_factor_diff_e[band_m_idx] );
1250 229400 : move32();
1251 : }
1252 : ELSE
1253 : {
1254 0 : diffuseness_m_fx[block_m_idx][band_m_idx] = diffuseness_vector_fx[band_m_idx];
1255 0 : diffuseness_e[block_m_idx][band_m_idx] = 0; // Q31
1256 0 : move32();
1257 0 : move16();
1258 : }
1259 : }
1260 : }
1261 :
1262 275280 : FOR( band_m_idx = 0; band_m_idx < hMcMasa->nbands; band_m_idx++ )
1263 : {
1264 229400 : Word16 max_e = MIN_16;
1265 229400 : move16();
1266 917600 : FOR( d = 0; d < DIRAC_NUM_DIMS; d++ )
1267 : {
1268 688200 : max_e = s_max( max_e, hMcMasa->direction_vector_e[d][block_m_idx][band_m_idx] );
1269 : }
1270 229400 : max_e = add( max_e, 1 ); /*1 as guard bit to prevent overflow*/
1271 917600 : FOR( d = 0; d < DIRAC_NUM_DIMS; d++ )
1272 : {
1273 688200 : dir_v_fx[d] = L_shr( hMcMasa->direction_vector_m_fx[d][block_m_idx][band_m_idx], sub( max_e, hMcMasa->direction_vector_e[d][block_m_idx][band_m_idx] ) );
1274 688200 : move32();
1275 : }
1276 229400 : Word16 div_q = sub( 31, max_e );
1277 229400 : ivas_qmetadata_direction_vector_to_azimuth_elevation_fx( dir_v_fx, div_q, &azimuth_m_values_fx[block_m_idx][band_m_idx], &elevation_m_values_fx[block_m_idx][band_m_idx] );
1278 : }
1279 :
1280 : /* Coherence processing */
1281 275280 : FOR( band_m_idx = 0; band_m_idx < hMcMasa->nbands; band_m_idx++ )
1282 : {
1283 : /* Compute absolute values */
1284 1524300 : FOR( i = 0; i < numAnalysisChannels; i++ )
1285 : {
1286 5913000 : FOR( j = i; j < numAnalysisChannels; j++ )
1287 : {
1288 4618100 : Word32 temp = BASOP_Util_Add_Mant32Exp( Mult_32_32( COVls[band_m_idx].xr_fx[i][j], COVls[band_m_idx].xr_fx[i][j] ), shl( COVls[band_m_idx].xr_e[i][j], 1 ), Mult_32_32( COVls[band_m_idx].xi_fx[i][j], COVls[band_m_idx].xi_fx[i][j] ), shl( COVls[band_m_idx].xi_e[i][j], 1 ), &absCOVls_e[i][j] );
1289 4618100 : absCOVls_fx[i][j] = Sqrt32( temp, &absCOVls_e[i][j] );
1290 4618100 : move32();
1291 : }
1292 1294900 : lsEnergy_fx[i] = absCOVls_fx[i][i];
1293 1294900 : move32();
1294 1294900 : lsEnergy_e[i] = absCOVls_e[i][i];
1295 1294900 : move16();
1296 : }
1297 :
1298 : /* Find loudest channel */
1299 229400 : maxEne_fx = lsEnergy_fx[0];
1300 229400 : move32();
1301 229400 : maxEne_e = lsEnergy_e[0];
1302 229400 : move16();
1303 229400 : loudestCh = 0;
1304 229400 : move16();
1305 1294900 : FOR( i = 1; i < numAnalysisChannels; i++ )
1306 : {
1307 1065500 : IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( lsEnergy_fx[i], lsEnergy_e[i], maxEne_fx, maxEne_e ), 1 ) )
1308 : {
1309 349831 : maxEne_fx = lsEnergy_fx[i];
1310 349831 : move32();
1311 349831 : maxEne_e = lsEnergy_e[i];
1312 349831 : move16();
1313 349831 : loudestCh = i;
1314 349831 : move16();
1315 : }
1316 : }
1317 :
1318 : /* Compute surrounding coherence */
1319 229400 : surrCoh_fx = ONE_IN_Q31;
1320 229400 : move32();
1321 229400 : surrCoh_e = 0;
1322 229400 : move16();
1323 1524300 : FOR( i = 0; i < numAnalysisChannels; i++ )
1324 : {
1325 1294900 : IF( NE_16( i, loudestCh ) )
1326 : {
1327 1065500 : IF( LT_16( i, loudestCh ) )
1328 : {
1329 656098 : i1 = i;
1330 656098 : move16();
1331 656098 : i2 = loudestCh;
1332 656098 : move16();
1333 : }
1334 : ELSE
1335 : {
1336 409402 : i1 = loudestCh;
1337 409402 : move16();
1338 409402 : i2 = i;
1339 409402 : move16();
1340 : }
1341 1065500 : Word16 temp_exp = add( lsEnergy_e[i1], lsEnergy_e[i2] );
1342 1065500 : Word32 temp = Sqrt32( L_add( Mult_32_32( lsEnergy_fx[i1], lsEnergy_fx[i2] ), EPSILON_FX ), &temp_exp );
1343 1065500 : tempCoh_e = 0;
1344 1065500 : move16();
1345 1065500 : tempCoh_fx = L_shl( BASOP_Util_Divide3232_Scale( absCOVls_fx[i1][i2], temp, &tempCoh_e ), 16 );
1346 1065500 : tempCoh_e = add( sub( absCOVls_e[i1][i2], temp_exp ), tempCoh_e );
1347 1065500 : IF( NE_16( BASOP_Util_Cmp_Mant32Exp( surrCoh_fx, surrCoh_e, tempCoh_fx, tempCoh_e ), -1 ) )
1348 : {
1349 453599 : surrCoh_fx = tempCoh_fx;
1350 453599 : move32();
1351 453599 : surrCoh_e = tempCoh_e;
1352 453599 : move16();
1353 : }
1354 : }
1355 : }
1356 229400 : surrCoh_fx = L_shl( surrCoh_fx, surrCoh_e ); // Q31
1357 229400 : surrCoh_e = 0;
1358 229400 : move16();
1359 229400 : surrCoh_fx = Mult_32_32( surrCoh_fx, surrCoh_fx );
1360 229400 : IF( GE_32( surrCoh_fx, ONE_IN_Q31 ) )
1361 : {
1362 0 : surrCoh_fx = ONE_IN_Q31;
1363 0 : move32();
1364 : }
1365 229400 : surrCoh_fx = L_max( surrCoh_fx, 0 );
1366 :
1367 : /* Compute spread coherence */
1368 229400 : IF( LT_32( elevation_m_values_fx[block_m_idx][band_m_idx], NEAR_HORIZONTAL_PLANE_ELEVATION_FX ) ) /* Computed only near horizontal plane */
1369 : {
1370 203279 : minAngleDist_fx = 754974720; /*180.0f Q.22*/
1371 203279 : move32();
1372 203279 : i1 = 0;
1373 203279 : move16();
1374 203279 : currentAzi_fx = azimuth_m_values_fx[block_m_idx][band_m_idx];
1375 203279 : move32();
1376 1228209 : FOR( i = 0; i < hMcMasa->numHorizontalChannels; i++ )
1377 : {
1378 1024930 : angleDist_fx = L_abs( L_sub( currentAzi_fx, hMcMasa->ls_azimuth_fx[i] ) );
1379 1024930 : IF( GT_32( angleDist_fx, 754974720 /*180.0f Q.22*/ ) )
1380 : {
1381 10052 : angleDist_fx = L_abs( L_sub( angleDist_fx, 1509949440 /*360.0f Q.22*/ ) );
1382 : }
1383 1024930 : IF( LT_32( angleDist_fx, minAngleDist_fx ) )
1384 : {
1385 450443 : minAngleDist_fx = angleDist_fx;
1386 450443 : move32();
1387 450443 : i1 = i;
1388 450443 : move16();
1389 : }
1390 : }
1391 203279 : i2 = hMcMasa->leftNearest[i1];
1392 203279 : move16();
1393 203279 : i3 = hMcMasa->rightNearest[i1];
1394 203279 : move16();
1395 203279 : Word16 temp_e = add( lsEnergy_e[i2], lsEnergy_e[i3] );
1396 203279 : Word32 temp = Sqrt32( L_add( Mult_32_32( lsEnergy_fx[i2], lsEnergy_fx[i3] ), EPSILON_FX ), &temp_e );
1397 203279 : IF( LT_16( i2, i3 ) )
1398 : {
1399 183018 : stereoCoh_fx = BASOP_Util_Divide3232_Scale( absCOVls_fx[i2][i3], temp, &stereoCoh_e );
1400 183018 : stereoCoh_e = add( sub( absCOVls_e[i2][i3], temp_e ), stereoCoh_e );
1401 : }
1402 : ELSE
1403 : {
1404 20261 : stereoCoh_fx = BASOP_Util_Divide3232_Scale( absCOVls_fx[i3][i2], temp, &stereoCoh_e );
1405 20261 : stereoCoh_e = add( sub( absCOVls_e[i3][i2], temp_e ), stereoCoh_e );
1406 : }
1407 203279 : stereoCoh_fx = L_shl( stereoCoh_fx, 16 );
1408 : Word32 temp1, temp2;
1409 : Word16 temp1_e, temp2_e;
1410 203279 : temp1 = BASOP_Util_Add_Mant32Exp( lsEnergy_fx[i2], lsEnergy_e[i2], lsEnergy_fx[i3], lsEnergy_e[i3], &temp1_e );
1411 203279 : temp2 = BASOP_Util_Add_Mant32Exp( temp1, temp1_e, lsEnergy_fx[i1], lsEnergy_e[i1], &temp2_e );
1412 203279 : temp2 = L_add( temp2, EPSILON_FX );
1413 203279 : lsEnergyRelation_fx = BASOP_Util_Divide3232_Scale( temp1, temp2, &lsEnergyRelation_e );
1414 203279 : lsEnergyRelation_e = add( lsEnergyRelation_e, sub( temp1_e, temp2_e ) );
1415 203279 : lsEnergyRelation_fx = L_shl_sat( lsEnergyRelation_fx, add( 16, lsEnergyRelation_e ) );
1416 203279 : stereoness_fx = Mult_32_32( stereoCoh_fx, lsEnergyRelation_fx );
1417 203279 : stereoness_e = stereoCoh_e;
1418 203279 : move16();
1419 :
1420 203279 : IF( LT_16( i1, i2 ) )
1421 : {
1422 95808 : temp_e = add( lsEnergy_e[i1], lsEnergy_e[i2] );
1423 95808 : tempCoh_fx = BASOP_Util_Divide3232_Scale( absCOVls_fx[i1][i2], ( Sqrt32( L_add( Mult_32_32( lsEnergy_fx[i1], lsEnergy_fx[i2] ), EPSILON_FX ), &temp_e ) ), &tempCoh_e );
1424 95808 : tempCoh_e = add( tempCoh_e, sub( absCOVls_e[i1][i2], temp_e ) );
1425 : }
1426 : ELSE
1427 : {
1428 107471 : temp_e = add( lsEnergy_e[i1], lsEnergy_e[i2] );
1429 107471 : tempCoh_fx = BASOP_Util_Divide3232_Scale( absCOVls_fx[i2][i1], ( Sqrt32( L_add( Mult_32_32( lsEnergy_fx[i1], lsEnergy_fx[i2] ), EPSILON_FX ), &temp_e ) ), &tempCoh_e );
1430 107471 : tempCoh_e = add( tempCoh_e, sub( absCOVls_e[i2][i1], temp_e ) );
1431 : }
1432 203279 : tempCoh_fx = L_shl( tempCoh_fx, 16 );
1433 203279 : IF( LT_16( i1, i3 ) )
1434 : {
1435 95789 : temp_e = add( lsEnergy_e[i1], lsEnergy_e[i3] );
1436 95789 : tempCoh2_fx = BASOP_Util_Divide3232_Scale( absCOVls_fx[i1][i3], ( Sqrt32( L_add( Mult_32_32( lsEnergy_fx[i1], lsEnergy_fx[i3] ), EPSILON_FX ), &temp_e ) ), &tempCoh2_e );
1437 95789 : tempCoh2_e = add( tempCoh2_e, sub( absCOVls_e[i1][i3], temp_e ) );
1438 : }
1439 : ELSE
1440 : {
1441 107490 : temp_e = add( lsEnergy_e[i1], lsEnergy_e[i3] );
1442 107490 : tempCoh2_fx = BASOP_Util_Divide3232_Scale( absCOVls_fx[i3][i1], ( Sqrt32( L_add( Mult_32_32( lsEnergy_fx[i1], lsEnergy_fx[i3] ), EPSILON_FX ), &temp_e ) ), &tempCoh2_e );
1443 107490 : tempCoh2_e = add( tempCoh2_e, sub( absCOVls_e[i3][i1], temp_e ) );
1444 : }
1445 203279 : tempCoh2_fx = L_shl( tempCoh2_fx, 16 );
1446 203279 : IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( tempCoh_fx, tempCoh_e, tempCoh2_fx, tempCoh2_e ), -1 ) )
1447 : {
1448 104786 : cohPanCoh_fx = tempCoh_fx;
1449 104786 : move32();
1450 104786 : cohPanCoh_e = tempCoh_e;
1451 104786 : move16();
1452 : }
1453 : ELSE
1454 : {
1455 98493 : cohPanCoh_fx = tempCoh2_fx;
1456 98493 : move32();
1457 98493 : cohPanCoh_e = tempCoh2_e;
1458 98493 : move16();
1459 : }
1460 : /* IF( GT_32( cohPanCoh_fx, ONE_IN_Q30 ) )
1461 : {
1462 : cohPanCoh_fx = ONE_IN_Q30;
1463 : move32();
1464 : }*/
1465 203279 : cohPanCoh_fx = L_shl_sat( cohPanCoh_fx, cohPanCoh_e ); /*Q31*/
1466 203279 : cohPanCoh_e = 0;
1467 203279 : move16();
1468 203279 : lsEnergyRelation_fx = BASOP_Util_Divide3232_Scale( lsEnergy_fx[i2], L_add( lsEnergy_fx[i1], EPSILON_FX ), &lsEnergyRelation_e );
1469 203279 : lsEnergyRelation_e = add( lsEnergyRelation_e, sub( lsEnergy_e[i2], lsEnergy_e[i1] ) );
1470 203279 : tempLsEnergyRelation_fx = BASOP_Util_Divide3232_Scale( lsEnergy_fx[i1], L_add( lsEnergy_fx[i2], EPSILON_FX ), &tempLsEnergyRelation_e );
1471 203279 : tempLsEnergyRelation_e = add( tempLsEnergyRelation_e, sub( lsEnergy_e[i1], lsEnergy_e[i2] ) );
1472 203279 : IF( NE_16( BASOP_Util_Cmp_Mant32Exp( lsEnergyRelation_fx, lsEnergyRelation_e, tempLsEnergyRelation_fx, tempLsEnergyRelation_e ), -1 ) )
1473 : {
1474 101468 : lsEnergyRelation_fx = tempLsEnergyRelation_fx;
1475 101468 : move32();
1476 101468 : lsEnergyRelation_e = tempLsEnergyRelation_e;
1477 101468 : move16();
1478 : }
1479 203279 : tempLsEnergyRelation_fx = BASOP_Util_Divide3232_Scale( lsEnergy_fx[i3], L_add( lsEnergy_fx[i1], EPSILON_FX ), &tempLsEnergyRelation_e );
1480 203279 : tempLsEnergyRelation_e = add( tempLsEnergyRelation_e, sub( lsEnergy_e[i3], lsEnergy_e[i1] ) );
1481 203279 : IF( NE_16( BASOP_Util_Cmp_Mant32Exp( lsEnergyRelation_fx, lsEnergyRelation_e, tempLsEnergyRelation_fx, tempLsEnergyRelation_e ), -1 ) )
1482 : {
1483 22822 : lsEnergyRelation_fx = tempLsEnergyRelation_fx;
1484 22822 : move32();
1485 22822 : lsEnergyRelation_e = tempLsEnergyRelation_e;
1486 22822 : move16();
1487 : }
1488 203279 : tempLsEnergyRelation_fx = BASOP_Util_Divide3232_Scale( lsEnergy_fx[i1], L_add( lsEnergy_fx[i3], EPSILON_FX ), &tempLsEnergyRelation_e );
1489 203279 : tempLsEnergyRelation_e = add( tempLsEnergyRelation_e, sub( lsEnergy_e[i1], lsEnergy_e[i3] ) );
1490 203279 : IF( NE_16( BASOP_Util_Cmp_Mant32Exp( lsEnergyRelation_fx, lsEnergyRelation_e, tempLsEnergyRelation_fx, tempLsEnergyRelation_e ), -1 ) )
1491 : {
1492 60087 : lsEnergyRelation_fx = tempLsEnergyRelation_fx;
1493 60087 : move32();
1494 60087 : lsEnergyRelation_e = tempLsEnergyRelation_e;
1495 60087 : move16();
1496 : }
1497 203279 : lsEnergyRelation_fx = L_shl_sat( lsEnergyRelation_fx, add( 16, lsEnergyRelation_e ) ); /*Q31*/
1498 203279 : cohwideness_fx = Mult_32_32( cohPanCoh_fx, lsEnergyRelation_fx );
1499 203279 : IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( cohwideness_fx, cohPanCoh_e, stereoness_fx, stereoness_e ), 1 ) )
1500 : {
1501 32464 : spreadCoh_fx = cohwideness_fx;
1502 32464 : move32();
1503 32464 : spreadCoh_e = cohPanCoh_e;
1504 32464 : move16();
1505 : }
1506 : ELSE
1507 : {
1508 170815 : spreadCoh_fx = stereoness_fx;
1509 170815 : move32();
1510 170815 : spreadCoh_e = stereoness_e;
1511 170815 : move16();
1512 : }
1513 203279 : IF( ( spreadCoh_e < 0 ) )
1514 : {
1515 5425 : spreadCoh_fx = L_shl( spreadCoh_fx, spreadCoh_e );
1516 5425 : spreadCoh_e = 0;
1517 5425 : move16();
1518 : }
1519 203279 : IF( GT_32( spreadCoh_fx, L_shl_sat( 1, sub( 30, spreadCoh_e ) /*0.5f with exp=spreadCoh_e*/ ) ) )
1520 : {
1521 128438 : IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( cohwideness_fx, cohPanCoh_e, stereoness_fx, stereoness_e ), 1 ) )
1522 : {
1523 21850 : tempCoh_fx = BASOP_Util_Add_Mant32Exp( stereoness_fx, stereoness_e, L_negate( L_sub( cohwideness_fx, L_shl( 1, sub( 30, cohPanCoh_e ) ) ) ), cohPanCoh_e, &tempCoh_e );
1524 21850 : IF( ( tempCoh_e < 0 ) )
1525 : {
1526 21850 : tempCoh_fx = L_shl( tempCoh_fx, tempCoh_e ); // Q31
1527 21850 : tempCoh_e = 0;
1528 21850 : move16();
1529 : }
1530 21850 : IF( GT_32( tempCoh_fx, L_shl_sat( 1, sub( 30, tempCoh_e ) ) ) )
1531 : {
1532 0 : spreadCoh_fx = tempCoh_fx; // tempCoh_e
1533 0 : move32();
1534 : }
1535 : ELSE
1536 : {
1537 21850 : spreadCoh_fx = L_shl_sat( 1, sub( 30, tempCoh_e ) ); // Q30
1538 : }
1539 21850 : spreadCoh_e = tempCoh_e;
1540 21850 : move16();
1541 : }
1542 : }
1543 203279 : IF( ( spreadCoh_e < 0 ) )
1544 : {
1545 0 : spreadCoh_fx = L_shl( spreadCoh_fx, spreadCoh_e ); // Q31
1546 0 : spreadCoh_e = 0;
1547 0 : move16();
1548 : }
1549 :
1550 203279 : IF( ( GE_32( spreadCoh_fx, L_shl_sat( 1, sub( 31, spreadCoh_e ) ) ) ) )
1551 : {
1552 0 : spreadCoh_fx = L_shl_sat( 1, sub( 31, spreadCoh_e ) ); // Q31
1553 : }
1554 203279 : IF( ( spreadCoh_fx <= 0 ) )
1555 : {
1556 1385 : spreadCoh_fx = 0;
1557 1385 : move32();
1558 : }
1559 203279 : spreadCoh_fx = L_shl( spreadCoh_fx, sub( spreadCoh_e, 1 ) ); /*Q30*/
1560 :
1561 : /* Compute energy ratio tuning parameter */
1562 203279 : lsEnergySum_fx = 0;
1563 203279 : move32();
1564 203279 : lsEnergySum_e = 0;
1565 203279 : move16();
1566 1241837 : FOR( i = 0; i < numAnalysisChannels; i++ )
1567 : {
1568 1038558 : lsEnergySum_fx = BASOP_Util_Add_Mant32Exp( lsEnergy_fx[i], lsEnergy_e[i], lsEnergySum_fx, lsEnergySum_e, &lsEnergySum_e );
1569 : }
1570 203279 : lsEnergySum_fx = L_add_sat( lsEnergySum_fx, EPSILON_FX );
1571 203279 : lsEnergyRelation_fx = BASOP_Util_Divide3232_Scale( temp1, lsEnergySum_fx, &lsEnergyRelation_e );
1572 203279 : lsEnergyRelation_e = add( lsEnergyRelation_e, sub( temp1_e, lsEnergySum_e ) );
1573 203279 : lsEnergyRelation_fx = L_shl_sat( lsEnergyRelation_fx, add( 16, lsEnergyRelation_e ) ); // Q31
1574 203279 : stereoRatio_fx = L_sub( Mult_32_32( L_shl_sat( stereoCoh_fx, stereoCoh_e ), lsEnergyRelation_fx ), surrCoh_fx ); // Q31
1575 :
1576 203279 : temp2 = L_sub( temp2, EPSILLON_FX );
1577 203279 : lsEnergyRelation_fx = BASOP_Util_Divide3232_Scale( temp2, lsEnergySum_fx, &lsEnergyRelation_e );
1578 203279 : lsEnergyRelation_e = add( lsEnergyRelation_e, sub( temp2_e, lsEnergySum_e ) );
1579 203279 : lsEnergyRelation_fx = L_shl_sat( lsEnergyRelation_fx, add( 16, lsEnergyRelation_e ) ); // Q31
1580 203279 : cohPanRatio_fx = L_sub( Mult_32_32( cohPanCoh_fx, lsEnergyRelation_fx ), surrCoh_fx ); // Q31
1581 203279 : IF( GT_32( stereoRatio_fx, cohPanRatio_fx ) )
1582 : {
1583 3970 : cohRatio_fx = stereoRatio_fx;
1584 3970 : move32();
1585 : }
1586 : ELSE
1587 : {
1588 199309 : cohRatio_fx = cohPanRatio_fx;
1589 199309 : move32();
1590 : }
1591 :
1592 203279 : IF( GE_32( cohRatio_fx, ONE_IN_Q31 ) )
1593 : {
1594 0 : cohRatio_fx = ONE_IN_Q31; // Q31
1595 0 : move32();
1596 : }
1597 203279 : IF( cohRatio_fx <= 0 )
1598 : {
1599 91308 : cohRatio_fx = 0;
1600 91308 : move32();
1601 : }
1602 : }
1603 : ELSE /* Otherwise, set spread coherence to zero */
1604 : {
1605 26121 : spreadCoh_fx = 0;
1606 26121 : move32();
1607 26121 : cohRatio_fx = 0;
1608 26121 : move32();
1609 26121 : lsEnergySum_fx = 0;
1610 26121 : move32();
1611 282463 : FOR( i = 0; i < numAnalysisChannels; i++ )
1612 : {
1613 256342 : lsEnergySum_fx = BASOP_Util_Add_Mant32Exp( lsEnergy_fx[i], lsEnergy_e[i], lsEnergySum_fx, lsEnergySum_e, &lsEnergySum_e );
1614 : }
1615 26121 : lsEnergySum_fx = L_add_sat( lsEnergySum_fx, EPSILON_FX );
1616 : }
1617 :
1618 : /* Store values */
1619 229400 : spreadCoherence_fx[block_m_idx][band_m_idx] = spreadCoh_fx; /*Q30*/
1620 229400 : move32();
1621 :
1622 229400 : IF( hMcMasa->combineRatios )
1623 : {
1624 229400 : surroundingCoherence_fx[0][band_m_idx] = BASOP_Util_Add_Mant32Exp( surroundingCoherence_fx[0][band_m_idx], surroundingCoherence_e[0][band_m_idx], Mult_32_32( lsEnergySum_fx, surrCoh_fx ), lsEnergySum_e, &surroundingCoherence_e[0][band_m_idx] );
1625 229400 : move32();
1626 229400 : coherentEnergyRatio_fx[0][band_m_idx] = BASOP_Util_Add_Mant32Exp( coherentEnergyRatio_fx[0][band_m_idx], coherentEnergyRatio_e[0][band_m_idx], Mult_32_32( lsEnergySum_fx, cohRatio_fx ), lsEnergySum_e, &coherentEnergyRatio_e[0][band_m_idx] );
1627 229400 : move32();
1628 229400 : renormalization_factor_coh_fx[band_m_idx] = BASOP_Util_Add_Mant32Exp( renormalization_factor_coh_fx[band_m_idx], renormalization_factor_coh_e[band_m_idx], lsEnergySum_fx, lsEnergySum_e, &renormalization_factor_coh_e[band_m_idx] );
1629 229400 : move32();
1630 : }
1631 : ELSE
1632 : {
1633 0 : surroundingCoherence_fx[block_m_idx][band_m_idx] = surrCoh_fx; // Q31
1634 0 : move32();
1635 0 : coherentEnergyRatio_fx[block_m_idx][band_m_idx] = cohRatio_fx; // Q31
1636 0 : move32();
1637 : }
1638 : }
1639 : }
1640 :
1641 11470 : IF( hMcMasa->combineRatios )
1642 : {
1643 68820 : FOR( band_m_idx = 0; band_m_idx < hMcMasa->nbands; band_m_idx++ )
1644 : {
1645 : Word16 diffuseness_m_e;
1646 57350 : IF( GT_32( renormalization_factor_diff_fx[band_m_idx], EPSILON_FX ) )
1647 : {
1648 57350 : diffuseness_m_fx[0][band_m_idx] = BASOP_Util_Divide3232_Scale( diffuseness_m_fx[0][band_m_idx], renormalization_factor_diff_fx[band_m_idx], &diffuseness_m_e );
1649 57350 : move32();
1650 57350 : diffuseness_m_e = add( diffuseness_m_e, sub( diffuseness_e[0][band_m_idx], renormalization_factor_diff_e[band_m_idx] ) );
1651 57350 : diffuseness_m_fx[0][band_m_idx] = L_shl_sat( diffuseness_m_fx[0][band_m_idx], add( 16, diffuseness_m_e ) ); // Q(31 - diffuseness_m_e) -> Q31
1652 57350 : move32();
1653 : }
1654 : ELSE
1655 : {
1656 0 : diffuseness_m_fx[0][band_m_idx] = 0;
1657 0 : move32();
1658 : }
1659 57350 : IF( GT_32( renormalization_factor_coh_fx[band_m_idx], EPSILON_FX ) )
1660 : {
1661 57350 : Word16 cer_e = 31, sc_e = 31;
1662 57350 : move16();
1663 57350 : move16();
1664 57350 : surroundingCoherence_fx[0][band_m_idx] = BASOP_Util_Divide3232_Scale( surroundingCoherence_fx[0][band_m_idx], renormalization_factor_coh_fx[band_m_idx], &sc_e );
1665 57350 : move32();
1666 57350 : sc_e = add( sc_e, sub( surroundingCoherence_e[0][band_m_idx], renormalization_factor_coh_e[band_m_idx] ) );
1667 57350 : surroundingCoherence_fx[0][band_m_idx] = L_shl_sat( surroundingCoherence_fx[0][band_m_idx], add( 16, sc_e ) ); // Q(31 - sc_e) -> Q31
1668 57350 : move32();
1669 57350 : coherentEnergyRatio_fx[0][band_m_idx] = BASOP_Util_Divide3232_Scale( coherentEnergyRatio_fx[0][band_m_idx], renormalization_factor_coh_fx[band_m_idx], &cer_e );
1670 57350 : move32();
1671 57350 : cer_e = add( cer_e, sub( coherentEnergyRatio_e[0][band_m_idx], renormalization_factor_coh_e[band_m_idx] ) );
1672 57350 : coherentEnergyRatio_fx[0][band_m_idx] = L_shl_sat( coherentEnergyRatio_fx[0][band_m_idx], add( 16, cer_e ) ); // Q(31 - cer_e) -> Q31
1673 57350 : move32();
1674 : }
1675 : ELSE
1676 : {
1677 0 : surroundingCoherence_fx[0][band_m_idx] = 0;
1678 0 : move32();
1679 0 : coherentEnergyRatio_fx[0][band_m_idx] = 0;
1680 0 : move32();
1681 : }
1682 : }
1683 : }
1684 :
1685 : /* Determine energy ratios */
1686 11470 : IF( hMcMasa->combineRatios )
1687 : {
1688 11470 : numSubFramesForRatio = 1;
1689 11470 : move16();
1690 : }
1691 : ELSE
1692 : {
1693 0 : numSubFramesForRatio = MAX_PARAM_SPATIAL_SUBFRAMES;
1694 0 : move16();
1695 : }
1696 :
1697 22940 : FOR( i = 0; i < numSubFramesForRatio; i++ )
1698 : {
1699 68820 : FOR( j = 0; j < hMcMasa->nbands; j++ )
1700 : {
1701 57350 : energyRatio_fx[i][j] = L_sub( ONE_IN_Q31, diffuseness_m_fx[i][j] ); // Q31
1702 57350 : move32();
1703 57350 : IF( GT_32( energyRatio_fx[i][j], coherentEnergyRatio_fx[i][j] ) )
1704 : {
1705 53860 : energyRatio_fx[i][j] = energyRatio_fx[i][j];
1706 53860 : move32();
1707 : }
1708 : ELSE
1709 : {
1710 3490 : energyRatio_fx[i][j] = coherentEnergyRatio_fx[i][j]; // Q31
1711 3490 : move32();
1712 : }
1713 : }
1714 : }
1715 :
1716 11470 : return;
1717 : }
1718 :
1719 :
1720 : /*--------------------------------------------------------------------------*
1721 : * ivas_mcmasa_dmx_modify()
1722 : *
1723 : *
1724 : *--------------------------------------------------------------------------*/
1725 :
1726 39 : void ivas_mcmasa_dmx_modify_fx(
1727 : const Word16 n_samples, /* i : input frame length in samples */
1728 : Word32 dmx_fx[][L_FRAME48k + NS2SA( 48000, IVAS_FB_ENC_DELAY_NS )], /* i/o: downmix signal to be transformed into another format Qx*/
1729 : Word16 dmx_Q[], /* i/o : Q of the intput signal which is being transformed*/
1730 : const Word16 n_chnls_dmx_old, /* i : number of downmix channels in the old format Q0 */
1731 : const Word16 n_chnls_dmx_new ) /* i : number of downmix channels in the target format Q0*/
1732 : {
1733 : /* assumed data ordering in **dmx: [sce][cpe_chnl0][cpe_chnl1], i.e., [c][l][r] */
1734 : Word16 i;
1735 :
1736 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." );
1737 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." );
1738 :
1739 39 : IF( EQ_16( n_chnls_dmx_old, n_chnls_dmx_new ) )
1740 : {
1741 : /* same dmx layout -> nothing to do */
1742 0 : return;
1743 : }
1744 :
1745 : Word16 Q_min_1_2, Q_min_0_1_2;
1746 :
1747 39 : Q_min_1_2 = s_min( dmx_Q[1], dmx_Q[2] );
1748 39 : Q_min_0_1_2 = s_min( dmx_Q[1], s_min( dmx_Q[2], dmx_Q[0] ) );
1749 :
1750 39 : IF( EQ_16( n_chnls_dmx_old, 1 ) )
1751 : {
1752 : /* split mono energy into identical channels */
1753 17298 : FOR( i = 0; i < n_samples; i++ )
1754 : {
1755 17280 : IF( EQ_16( n_chnls_dmx_new, 2 ) )
1756 : {
1757 5760 : dmx_fx[1][i] = Mpy_32_16_1( dmx_fx[0][i], INV_SQRT2_FX_Q15 ); // dmx_q + Q15 - 15
1758 5760 : dmx_fx[2][i] = dmx_fx[1][i];
1759 5760 : move32();
1760 5760 : move32();
1761 : }
1762 11520 : ELSE IF( EQ_16( n_chnls_dmx_new, 3 ) )
1763 : {
1764 11520 : dmx_fx[0][i] = Mpy_32_16_1( dmx_fx[0][i], INV_SQRT3_FX ); // dmx_q + Q15 - 15
1765 11520 : move32();
1766 : }
1767 : }
1768 : }
1769 21 : ELSE IF( EQ_16( n_chnls_dmx_old, 2 ) )
1770 : {
1771 9610 : FOR( i = 0; i < n_samples; i++ )
1772 : {
1773 9600 : IF( EQ_16( n_chnls_dmx_new, 1 ) )
1774 : {
1775 : /* sum l and r */
1776 6720 : dmx_fx[1][i] = L_shl( dmx_fx[1][i], sub( Q_min_1_2, dmx_Q[1] ) );
1777 6720 : dmx_fx[2][i] = L_shl( dmx_fx[2][i], sub( Q_min_1_2, dmx_Q[2] ) );
1778 6720 : move32();
1779 6720 : move32();
1780 :
1781 6720 : dmx_fx[0][i] = L_add( dmx_fx[1][i], dmx_fx[2][i] ); // dmx_q
1782 6720 : move32();
1783 : }
1784 2880 : ELSE IF( EQ_16( n_chnls_dmx_new, 3 ) )
1785 : {
1786 2880 : dmx_fx[1][i] = L_shl( dmx_fx[1][i], sub( Q_min_1_2, dmx_Q[1] ) );
1787 2880 : dmx_fx[2][i] = L_shl( dmx_fx[2][i], sub( Q_min_1_2, dmx_Q[2] ) );
1788 2880 : move32();
1789 2880 : move32();
1790 :
1791 2880 : dmx_fx[0][i] = L_shr( L_add( dmx_fx[1][i], dmx_fx[2][i] ), 1 );
1792 2880 : dmx_fx[1][i] = L_sub( dmx_fx[1][i], dmx_fx[0][i] ); // dmx_q
1793 2880 : dmx_fx[2][i] = L_sub( dmx_fx[2][i], dmx_fx[0][i] ); // dmx_q
1794 2880 : move32();
1795 2880 : move32();
1796 2880 : move32();
1797 : }
1798 : }
1799 : }
1800 11 : ELSE IF( EQ_16( n_chnls_dmx_old, 3 ) )
1801 : {
1802 10571 : FOR( i = 0; i < n_samples; i++ )
1803 : {
1804 10560 : IF( EQ_16( n_chnls_dmx_new, 1 ) )
1805 : {
1806 : /* sum all channels */
1807 :
1808 6720 : dmx_fx[0][i] = L_shl( dmx_fx[0][i], sub( Q_min_0_1_2, dmx_Q[1] ) );
1809 6720 : dmx_fx[1][i] = L_shl( dmx_fx[1][i], sub( Q_min_0_1_2, dmx_Q[1] ) );
1810 6720 : dmx_fx[2][i] = L_shl( dmx_fx[2][i], sub( Q_min_0_1_2, dmx_Q[2] ) );
1811 6720 : move32();
1812 6720 : move32();
1813 6720 : move32();
1814 :
1815 6720 : dmx_fx[0][i] = L_add( L_add( dmx_fx[0][i], dmx_fx[1][i] ), dmx_fx[2][i] );
1816 6720 : move32();
1817 : }
1818 3840 : ELSE IF( EQ_16( n_chnls_dmx_new, 2 ) )
1819 : {
1820 :
1821 3840 : dmx_fx[0][i] = L_shl( dmx_fx[0][i], sub( Q_min_0_1_2, dmx_Q[1] ) );
1822 3840 : dmx_fx[1][i] = L_shl( dmx_fx[1][i], sub( Q_min_0_1_2, dmx_Q[1] ) );
1823 3840 : dmx_fx[2][i] = L_shl( dmx_fx[2][i], sub( Q_min_0_1_2, dmx_Q[2] ) );
1824 3840 : move32();
1825 3840 : move32();
1826 3840 : move32();
1827 :
1828 : /* mix center into sides */
1829 3840 : dmx_fx[0][i] = Mpy_32_16_1( dmx_fx[0][i], INV_SQRT2_FX_Q15 );
1830 3840 : dmx_fx[1][i] = L_add( dmx_fx[1][i], dmx_fx[0][i] ); // dmx_q
1831 3840 : dmx_fx[2][i] = L_add( dmx_fx[2][i], dmx_fx[0][i] ); // dmx_q
1832 3840 : move32();
1833 3840 : move32();
1834 3840 : move32();
1835 : }
1836 : }
1837 : }
1838 :
1839 : // Q updation for different channels
1840 :
1841 39 : IF( EQ_16( n_chnls_dmx_old, 1 ) )
1842 : {
1843 : /* split mono energy into identical channels */
1844 18 : IF( EQ_16( n_chnls_dmx_new, 2 ) )
1845 : {
1846 6 : dmx_Q[1] = dmx_Q[0];
1847 6 : move16();
1848 6 : dmx_Q[2] = dmx_Q[0];
1849 6 : move16();
1850 : }
1851 : }
1852 21 : ELSE IF( EQ_16( n_chnls_dmx_old, 2 ) )
1853 : {
1854 10 : dmx_Q[0] = Q_min_1_2;
1855 10 : move16();
1856 10 : dmx_Q[1] = Q_min_1_2;
1857 10 : move16();
1858 10 : dmx_Q[2] = Q_min_1_2;
1859 10 : move16();
1860 : }
1861 11 : ELSE IF( EQ_16( n_chnls_dmx_old, 3 ) )
1862 : {
1863 11 : dmx_Q[0] = Q_min_0_1_2;
1864 11 : move16();
1865 11 : dmx_Q[1] = Q_min_0_1_2;
1866 11 : move16();
1867 11 : dmx_Q[2] = Q_min_0_1_2;
1868 11 : move16();
1869 : }
1870 :
1871 :
1872 39 : return;
1873 : }
1874 :
1875 :
1876 : /*--------------------------------------------------------------------------*
1877 : * Local functions
1878 : *--------------------------------------------------------------------------*/
1879 : /* Compute downmix */
1880 11470 : static void ivas_mcmasa_dmx_fx(
1881 : MCMASA_ENC_HANDLE hMcMasa,
1882 : Word32 *data_fx[], // Q(31 - data_e)
1883 : Word16 data_e,
1884 : const Word16 input_frame,
1885 : const Word16 nchan_transport,
1886 : const Word16 nchan_inp )
1887 : {
1888 : Word16 i, j;
1889 : Word16 numAnalysisChannels;
1890 : Word32 dmx_c_fx;
1891 : Word32 multiChEne_fx, downmixEne_fx;
1892 : Word32 prevEQ_fx, currEQ_fx, instEQ_fx;
1893 : Word32 alpha_fx, L_tmp, L_tmp1;
1894 11470 : Word16 multiChEne_e, scale, downmixEne_e = 0, prevEQ_e, tmp, currEQ_e, instEQ_e;
1895 11470 : move16();
1896 :
1897 11470 : numAnalysisChannels = sub( nchan_inp, 1 );
1898 11470 : IF( hMcMasa->separateChannelEnabled )
1899 : {
1900 625 : numAnalysisChannels = sub( nchan_inp, 2 );
1901 : }
1902 :
1903 11470 : multiChEne_fx = 0;
1904 11470 : move32();
1905 11470 : multiChEne_e = 0;
1906 11470 : move16();
1907 76215 : FOR( j = 0; j < numAnalysisChannels; j++ )
1908 : {
1909 61899945 : FOR( i = 0; i < input_frame; i++ )
1910 : {
1911 61835200 : L_tmp1 = BASOP_Util_Add_Mant32Exp( data_fx[j][i], data_e, 0, 0, &scale );
1912 61835200 : L_tmp = Mpy_32_32( L_tmp1, L_tmp1 ); // data_e + data_e
1913 61835200 : multiChEne_fx = BASOP_Util_Add_Mant32Exp( L_tmp, scale + scale, multiChEne_fx, multiChEne_e, &scale );
1914 61835200 : multiChEne_e = scale;
1915 61835200 : move16();
1916 : }
1917 : }
1918 :
1919 11470 : IF( EQ_16( nchan_transport, 2 ) )
1920 : {
1921 : Word16 numSideChannels; /* Channels other than left, right, center */
1922 : Word16 leftIndex, rightIndex;
1923 :
1924 1045 : numSideChannels = sub( shr( numAnalysisChannels, 1 ), 1 );
1925 5045 : FOR( j = 0; j < numSideChannels; j++ )
1926 : {
1927 4000 : IF( hMcMasa->separateChannelEnabled )
1928 : {
1929 2480 : leftIndex = add( shl( j, 1 ), 2 );
1930 2480 : rightIndex = add( shl( j, 1 ), 3 );
1931 : }
1932 : ELSE
1933 : {
1934 1520 : leftIndex = add( shl( j, 1 ), 3 );
1935 1520 : rightIndex = add( shl( j, 1 ), 4 );
1936 : }
1937 :
1938 3844000 : FOR( i = 0; i < input_frame; i++ )
1939 : {
1940 3840000 : data_fx[0][i] = L_add( data_fx[0][i], data_fx[leftIndex][i] ); // data_e
1941 3840000 : move32();
1942 3840000 : data_fx[1][i] = L_add( data_fx[1][i], data_fx[rightIndex][i] );
1943 3840000 : move32();
1944 : }
1945 : }
1946 :
1947 1045 : IF( !hMcMasa->separateChannelEnabled )
1948 : {
1949 403620 : FOR( i = 0; i < input_frame; i++ )
1950 : {
1951 403200 : dmx_c_fx = W_extract_h( W_mult_32_32( INV_SQRT2_FX, data_fx[2][i] ) );
1952 403200 : move32();
1953 403200 : data_fx[0][i] = L_add( dmx_c_fx, data_fx[0][i] ); // data_e
1954 403200 : move32();
1955 403200 : data_fx[1][i] = L_add( dmx_c_fx, data_fx[1][i] ); // data_e
1956 403200 : move32();
1957 : }
1958 : }
1959 : }
1960 10425 : ELSE IF( EQ_16( nchan_transport, 1 ) )
1961 : {
1962 9954425 : FOR( i = 0; i < input_frame; i++ )
1963 : {
1964 51745600 : FOR( j = 1; j < numAnalysisChannels; j++ )
1965 : {
1966 41801600 : data_fx[0][i] = L_add( data_fx[0][i], data_fx[j][i] );
1967 41801600 : move32();
1968 : }
1969 : }
1970 : }
1971 11470 : downmixEne_fx = 0;
1972 11470 : move32();
1973 23985 : FOR( j = 0; j < nchan_transport; j++ )
1974 : {
1975 11962915 : FOR( i = 0; i < input_frame; i++ )
1976 : {
1977 11950400 : L_tmp1 = BASOP_Util_Add_Mant32Exp( data_fx[j][i], data_e, 0, 0, &scale );
1978 11950400 : L_tmp = Mpy_32_32( L_tmp1, L_tmp1 ); // data_e + data_e
1979 11950400 : downmixEne_fx = BASOP_Util_Add_Mant32Exp( L_tmp, scale + scale, downmixEne_fx, downmixEne_e, &downmixEne_e );
1980 : }
1981 : }
1982 :
1983 11470 : alpha_fx = 214748364; // 0.1 in Q31
1984 11470 : move32();
1985 :
1986 11470 : L_tmp = Mpy_32_32( alpha_fx, multiChEne_fx );
1987 11470 : L_tmp1 = Mpy_32_32( 1932735284 /* 0.9f in Q31 */, hMcMasa->prevMultiChEne_fx );
1988 11470 : hMcMasa->prevMultiChEne_fx = BASOP_Util_Add_Mant32Exp( L_tmp, multiChEne_e, L_tmp1, hMcMasa->prevMultiChEne_e, &hMcMasa->prevMultiChEne_e );
1989 11470 : move32();
1990 :
1991 11470 : L_tmp = Mpy_32_32( alpha_fx, downmixEne_fx );
1992 11470 : L_tmp1 = Mpy_32_32( 1932735284 /* 0.9f in Q31 */, hMcMasa->prevDownmixEne_fx );
1993 11470 : hMcMasa->prevDownmixEne_fx = BASOP_Util_Add_Mant32Exp( L_tmp, downmixEne_e, L_tmp1, hMcMasa->prevDownmixEne_e, &hMcMasa->prevDownmixEne_e );
1994 11470 : move32();
1995 :
1996 11470 : prevEQ_fx = hMcMasa->prevEQ_fx;
1997 11470 : move32();
1998 11470 : prevEQ_e = hMcMasa->prevEQ_e;
1999 11470 : move16();
2000 :
2001 11470 : tmp = BASOP_Util_Divide3232_Scale( hMcMasa->prevMultiChEne_fx, L_add( hMcMasa->prevDownmixEne_fx, EPSILON_FX ), &scale );
2002 11470 : currEQ_e = add( scale, sub( hMcMasa->prevMultiChEne_e, hMcMasa->prevDownmixEne_e ) );
2003 11470 : currEQ_fx = Sqrt32( L_deposit_h( tmp ), &currEQ_e );
2004 :
2005 11470 : hMcMasa->prevEQ_fx = currEQ_fx;
2006 11470 : move32();
2007 11470 : hMcMasa->prevEQ_e = currEQ_e;
2008 11470 : move16();
2009 :
2010 10958670 : FOR( i = 0; i < input_frame; i++ )
2011 : {
2012 10947200 : L_tmp = Mpy_32_32( L_deposit_h( hMcMasa->interpolator_fx[i] ), currEQ_fx );
2013 10947200 : L_tmp1 = L_sub( 1073741824 /* 1 in Q30 */, L_lshr( L_deposit_h( hMcMasa->interpolator_fx[i] ), 1 ) );
2014 10947200 : L_tmp1 = Mpy_32_32( L_tmp1, prevEQ_fx );
2015 10947200 : instEQ_fx = BASOP_Util_Add_Mant32Exp( L_tmp, currEQ_e, L_tmp1, add( prevEQ_e, 1 ), &instEQ_e );
2016 :
2017 22897600 : FOR( j = 0; j < nchan_transport; j++ )
2018 : {
2019 11950400 : data_fx[j][i] = Mpy_32_32( instEQ_fx, data_fx[j][i] ); // data_e + instEQ_e - 31
2020 11950400 : move32();
2021 11950400 : move32();
2022 11950400 : data_fx[j][i] = L_shl( data_fx[j][i], instEQ_e ); // data_e + 2*instEQ_e - 31
2023 : }
2024 : }
2025 :
2026 11470 : return;
2027 : }
2028 : /* Compute covariance matrix, i.e., xT * conj(x), and accumulate to the output */
2029 10947200 : static void compute_cov_mtx_fx(
2030 : Word32 sr[MCMASA_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX], /* i : Input matrix, real, s[ch][freq] (inp_exp) */
2031 : Word32 si[MCMASA_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX], /* i : Input matrix, imag, s[ch][freq] (inp_exp) */
2032 : const Word16 freq, /* i : Freq to process */
2033 : const Word16 N, /* i : Number of channels */
2034 : CovarianceMatrix *COVls, /* o : Output matrix, contains upper part of cov mtx */
2035 : Word16 inp_exp /*Stores exponent for temp*/
2036 : )
2037 : {
2038 : Word16 i, j;
2039 : Word32 a, b, c, d;
2040 : Word32 temp;
2041 : Word16 norm_a, norm_b, norm_c, norm_d;
2042 : Word16 shift;
2043 72782400 : FOR( i = 0; i < N; i++ )
2044 : {
2045 61835200 : a = sr[i][freq];
2046 61835200 : move32();
2047 61835200 : b = si[i][freq];
2048 61835200 : move32();
2049 61835200 : norm_a = norm_l( a );
2050 61835200 : norm_b = norm_l( b );
2051 61835200 : a = L_shl( a, norm_a ); /*inp_exp-norm_a*/
2052 61835200 : b = L_shl( b, norm_b ); /*inp_exp-norm_b*/
2053 282544000 : FOR( j = i; j < N; j++ )
2054 : {
2055 220708800 : c = sr[j][freq];
2056 220708800 : move32();
2057 220708800 : d = si[j][freq];
2058 220708800 : move32();
2059 220708800 : norm_c = norm_l( c );
2060 220708800 : norm_d = norm_l( d );
2061 220708800 : c = L_shl( c, norm_c ); /*inp_exp-norm_c*/
2062 220708800 : d = L_shl( d, norm_d ); /*inp_exp-norm_d*/
2063 220708800 : temp = BASOP_Util_Add_Mant32Exp( Mult_32_32( a, c ), sub( shl( inp_exp, 1 ), add( norm_a, norm_c ) ), Mult_32_32( b, d ), sub( shl( inp_exp, 1 ), add( norm_b, norm_d ) ), &shift ); /*exp=inp_exp-norm_ab+inp_exp-norm_cd*/
2064 220708800 : COVls->xr_fx[i][j] = BASOP_Util_Add_Mant32Exp( COVls->xr_fx[i][j], COVls->xr_e[i][j], temp, shift, &COVls->xr_e[i][j] );
2065 220708800 : move32();
2066 220708800 : temp = BASOP_Util_Add_Mant32Exp( Mult_32_32( b, c ), sub( shl( inp_exp, 1 ), add( norm_b, norm_c ) ), L_negate( Mult_32_32( a, d ) ), sub( shl( inp_exp, 1 ), add( norm_a, norm_d ) ), &shift );
2067 220708800 : COVls->xi_fx[i][j] = BASOP_Util_Add_Mant32Exp( COVls->xi_fx[i][j], COVls->xi_e[i][j], temp, shift, &COVls->xi_e[i][j] );
2068 220708800 : move32();
2069 : }
2070 : }
2071 :
2072 10947200 : return;
2073 : }
2074 91760 : static void computeIntensityVector_enc_fx(
2075 : const Word16 *band_grouping,
2076 : Word32 Cldfb_RealBuffer[FOA_CHANNELS][DIRAC_NO_FB_BANDS_MAX],
2077 : Word32 Cldfb_ImagBuffer[FOA_CHANNELS][DIRAC_NO_FB_BANDS_MAX],
2078 : const Word16 enc_param_start_band, /* i : first band to process */
2079 : const Word16 num_frequency_bands,
2080 : Word32 intensity_real[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS] )
2081 : {
2082 : /* Reminder
2083 : * X = a + ib; Y = c + id
2084 : * X*Y = ac - bd + i(ad +bc)
2085 : */
2086 : Word16 i, j;
2087 : Word32 real, img;
2088 : Word16 brange[2];
2089 :
2090 550560 : FOR( i = enc_param_start_band; i < enc_param_start_band + num_frequency_bands; i++ )
2091 : {
2092 458800 : brange[0] = band_grouping[i];
2093 458800 : move16();
2094 458800 : brange[1] = band_grouping[i + 1];
2095 458800 : move16();
2096 :
2097 458800 : intensity_real[0][i] = 0;
2098 458800 : move32();
2099 458800 : intensity_real[1][i] = 0;
2100 458800 : move32();
2101 458800 : intensity_real[2][i] = 0;
2102 458800 : move32();
2103 :
2104 22353200 : FOR( j = brange[0]; j < brange[1]; j++ )
2105 : {
2106 21894400 : real = Cldfb_RealBuffer[0][j];
2107 21894400 : move32();
2108 21894400 : img = Cldfb_ImagBuffer[0][j];
2109 21894400 : move32();
2110 : /* Intensity is XYZ order, audio is WYZX order. */
2111 21894400 : intensity_real[0][i] = L_add( intensity_real[0][i], L_add( Mpy_32_32( Cldfb_RealBuffer[3][j], real ), Mpy_32_32( Cldfb_ImagBuffer[3][j], img ) ) ); // output Q= 2* input_q -31
2112 21894400 : move32();
2113 21894400 : intensity_real[1][i] = L_add( intensity_real[1][i], L_add( Mpy_32_32( Cldfb_RealBuffer[1][j], real ), Mpy_32_32( Cldfb_ImagBuffer[1][j], img ) ) ); // output Q= 2* input_q -31
2114 21894400 : move32();
2115 21894400 : intensity_real[2][i] = L_add( intensity_real[2][i], L_add( Mpy_32_32( Cldfb_RealBuffer[2][j], real ), Mpy_32_32( Cldfb_ImagBuffer[2][j], img ) ) ); // output Q= 2* input_q -31
2116 21894400 : move32();
2117 : }
2118 : }
2119 :
2120 91760 : return;
2121 : }
2122 6120 : static void computeVerticalDiffuseness_fx(
2123 : Word32 **buffer_intensity, /* i : Intensity vectors */
2124 : const Word32 *buffer_energy, /* i : Energy */
2125 : const Word16 averaging_length, /* i : Averaging length */
2126 : const Word16 num_freq_bands, /* i : Number of frequency bands */
2127 : Word32 *diffuseness, /* o : Estimated diffuseness Q31 */
2128 : Word16 *buffer_intensity_q,
2129 : Word16 *buffer_energy_q )
2130 : {
2131 : Word32 intensity_slow[MASA_FREQUENCY_BANDS];
2132 : Word32 intensity_slow_abs[MASA_FREQUENCY_BANDS];
2133 : Word32 energy_slow[MASA_FREQUENCY_BANDS];
2134 : Word16 i, k;
2135 6120 : Word32 tmp = 0;
2136 6120 : move32();
2137 : const Word32 *p_tmp_c;
2138 : Word16 intensity_slow_e[MASA_FREQUENCY_BANDS], energy_slow_e[MASA_FREQUENCY_BANDS];
2139 :
2140 : /* Set variables to zero */
2141 6120 : set32_fx( intensity_slow, 0, MASA_FREQUENCY_BANDS );
2142 6120 : set32_fx( energy_slow, 0, MASA_FREQUENCY_BANDS );
2143 6120 : set16_fx( intensity_slow_e, 0, MASA_FREQUENCY_BANDS );
2144 6120 : set16_fx( energy_slow_e, 0, MASA_FREQUENCY_BANDS );
2145 :
2146 55080 : FOR( i = 0; i < averaging_length; ++i )
2147 : {
2148 : /* Energy slow */
2149 48960 : p_tmp_c = buffer_energy + i_mult( i, num_freq_bands );
2150 293760 : FOR( k = 0; k < num_freq_bands; k++ )
2151 : {
2152 244800 : energy_slow[k] = BASOP_Util_Add_Mant32Exp( energy_slow[k], energy_slow_e[k], *( p_tmp_c ), sub( 31, buffer_energy_q[i] ), &energy_slow_e[k] ); /*q=min_q*/
2153 244800 : move32();
2154 244800 : p_tmp_c++;
2155 : }
2156 :
2157 : /* Intensity slow */
2158 293760 : FOR( k = 0; k < num_freq_bands; k++ )
2159 : {
2160 244800 : intensity_slow[k] = BASOP_Util_Add_Mant32Exp( intensity_slow[k], intensity_slow_e[k], buffer_intensity[i][k], sub( 31, buffer_intensity_q[i] ), &intensity_slow_e[k] ); /*q=min_q*/
2161 244800 : move32();
2162 : }
2163 : }
2164 :
2165 : /* Compute absolute value */
2166 36720 : FOR( k = 0; k < num_freq_bands; k++ )
2167 : {
2168 30600 : intensity_slow_abs[k] = L_abs( intensity_slow[k] ); /*min_q*/
2169 30600 : move32();
2170 : }
2171 :
2172 : /* Compute Diffuseness */
2173 36720 : FOR( i = 0; i < num_freq_bands; ++i )
2174 : {
2175 : Word16 tmp_e1, tmp_e2, tmp1;
2176 30600 : tmp = BASOP_Util_Divide3232_Scale( intensity_slow_abs[i], L_add( energy_slow[i], EPSILON_FX_SMALL ), &tmp_e1 );
2177 30600 : tmp_e1 = add( tmp_e1, sub( intensity_slow_e[i], energy_slow_e[i] ) );
2178 30600 : tmp_e1 = BASOP_Util_Add_MantExp( (Word16) tmp, tmp_e1, -VERTICAL_ENERGY_RATIO_OFFSET_FX, 0, &tmp1 );
2179 30600 : tmp = BASOP_Util_Divide3232_Scale( (Word32) tmp1, ONE_IN_Q15 - VERTICAL_ENERGY_RATIO_OFFSET_FX, &tmp_e2 ); /* Tuned to avoid effect due to ambience of vertically un-even setups */
2180 30600 : tmp_e2 = add( tmp_e2, tmp_e1 );
2181 30600 : tmp = L_sub( L_shl( 1, sub( 15, tmp_e2 ) ), tmp );
2182 30600 : IF( tmp < 0 )
2183 : {
2184 1 : tmp = 0;
2185 1 : move32();
2186 : }
2187 30599 : ELSE IF( GE_32( tmp, L_shl( 1, sub( 15, tmp_e2 ) ) ) )
2188 : {
2189 1332 : tmp = ONE_IN_Q31;
2190 1332 : move32();
2191 : }
2192 : ELSE
2193 : {
2194 29267 : tmp = L_shl( tmp, add( 16, tmp_e2 ) );
2195 : }
2196 30600 : diffuseness[i] = tmp; // Q31
2197 30600 : move32();
2198 : }
2199 :
2200 6120 : return;
2201 : }
2202 372 : static void computeEvenLayout_fx(
2203 : const Word32 *ls_azimuth, // Q22
2204 : Word32 *ls_azimuth_even, // Q22
2205 : const Word16 numChannels )
2206 : {
2207 : Word16 i;
2208 : Word16 j;
2209 : Word32 ls_azimuth_temp[MCMASA_MAX_ANA_CHANS];
2210 : Word32 ls_azimuth_even_ordered[MCMASA_MAX_ANA_CHANS];
2211 : Word16 ls_azimuth_order[MCMASA_MAX_ANA_CHANS];
2212 : Word32 smallestAzimuth;
2213 : Word16 smallestAzimuthIndex;
2214 : Word32 lsSpacing;
2215 : UWord8 oddLayout;
2216 : Word32 startAzimuth;
2217 : Word16 numChannelsHalf;
2218 :
2219 372 : lsSpacing = L_shl( L_mult0( 360, div_s( 1, numChannels ) ), 6 ); /*Q.21*/
2220 372 : oddLayout = (UWord8) s_and( numChannels, 1 );
2221 372 : move16();
2222 372 : numChannelsHalf = shr( numChannels, 1 );
2223 :
2224 372 : Copy32( ls_azimuth, ls_azimuth_temp, numChannels );
2225 372 : Scale_sig32( ls_azimuth_temp, numChannels, -1 ); /*Q.21*/
2226 2265 : FOR( i = 0; i < numChannels; i++ )
2227 : {
2228 1893 : smallestAzimuth = 1000 << 21; /*Q21*/
2229 1893 : move32();
2230 1893 : smallestAzimuthIndex = 0;
2231 1893 : move16();
2232 11974 : FOR( j = 0; j < numChannels; j++ )
2233 : {
2234 10081 : IF( LT_32( ls_azimuth_temp[j], smallestAzimuth ) )
2235 : {
2236 3502 : smallestAzimuth = ls_azimuth_temp[j];
2237 3502 : move32();
2238 3502 : smallestAzimuthIndex = j;
2239 3502 : move16();
2240 : }
2241 : }
2242 1893 : ls_azimuth_order[i] = smallestAzimuthIndex;
2243 1893 : move32();
2244 1893 : ls_azimuth_temp[smallestAzimuthIndex] = ( 1000 << 21 );
2245 1893 : move32();
2246 : }
2247 :
2248 372 : IF( oddLayout )
2249 : {
2250 249 : startAzimuth = W_extract_l( W_mult0_32_32( -lsSpacing, shl( numChannelsHalf, 1 ) ) ); /*Q.22*/
2251 : }
2252 : ELSE
2253 : {
2254 123 : startAzimuth = W_extract_l( W_mult0_32_32( -lsSpacing, sub( shl( numChannelsHalf, 1 ), 1 ) ) ); /*Q.22*/
2255 : }
2256 :
2257 2265 : FOR( i = 0; i < numChannels; i++ )
2258 : {
2259 1893 : ls_azimuth_even_ordered[i] = W_extract_l( W_add( W_mult_32_16( lsSpacing, i ), startAzimuth ) ); /*Q.22*/
2260 1893 : move32();
2261 : }
2262 :
2263 2265 : FOR( i = 0; i < numChannels; i++ )
2264 : {
2265 1893 : ls_azimuth_even[ls_azimuth_order[i]] = L_shl( L_shr( L_add( ls_azimuth_even_ordered[i], ONE_IN_Q21 ), 22 ), 22 ); /*((a+2^21)/2^22)*2^22*/
2266 1893 : move32();
2267 : }
2268 :
2269 372 : return;
2270 : }
2271 11470 : static void computeLfeEnergy_fx(
2272 : MCMASA_ENC_HANDLE hMcMasa,
2273 : Word32 *data_fx[], // q_inp
2274 : const Word16 input_frame,
2275 : Word16 q_inp )
2276 : {
2277 : Word16 l_ts;
2278 : Word16 block_m_idx;
2279 : Word16 mrange[2];
2280 : Word16 separateChannelIndex;
2281 : Word16 lfeChannelIndex;
2282 : Word32 *pcm_in[1];
2283 11470 : Word16 inp_q = q_inp;
2284 11470 : move16();
2285 :
2286 11470 : l_ts = idiv1616( input_frame, MDFT_NO_COL_MAX );
2287 11470 : separateChannelIndex = hMcMasa->separateChannelIndex;
2288 11470 : move16();
2289 11470 : lfeChannelIndex = LFE_CHANNEL;
2290 11470 : move16();
2291 :
2292 11470 : IF( hMcMasa->separateChannelEnabled )
2293 : {
2294 625 : Copy32( data_fx[lfeChannelIndex], &( hMcMasa->delay_buffer_lfe[0][hMcMasa->num_samples_delay_comp - hMcMasa->offset_comp] ), hMcMasa->offset_comp ); // q_inp
2295 625 : Copy32( data_fx[separateChannelIndex], &( hMcMasa->delay_buffer_lfe[1][hMcMasa->num_samples_delay_comp - hMcMasa->offset_comp] ), hMcMasa->offset_comp ); // q_inp
2296 : }
2297 : ELSE
2298 : {
2299 10845 : pcm_in[0] = &data_fx[lfeChannelIndex][0];
2300 : }
2301 :
2302 : /* Reset variables */
2303 11470 : set32_fx( hMcMasa->lfeLfEne, 0, MAX_PARAM_SPATIAL_SUBFRAMES );
2304 11470 : set16_fx( hMcMasa->lfeLfEne_e, 0, MAX_PARAM_SPATIAL_SUBFRAMES );
2305 11470 : set32_fx( hMcMasa->totalLfEne, 0, MAX_PARAM_SPATIAL_SUBFRAMES );
2306 11470 : set16_fx( hMcMasa->totalLfEne_e, 0, MAX_PARAM_SPATIAL_SUBFRAMES );
2307 :
2308 : /* Compute low-frequency energies */
2309 11470 : IF( hMcMasa->separateChannelEnabled ) /* Using low-pass filter */
2310 : {
2311 : Word32 lowpassCoef;
2312 : Word16 lowPassSignal_q;
2313 : Word16 i, j;
2314 : Word32 delayedInputSignal[2][L_FRAME48k];
2315 : Word32 lowPassSignal[2][L_FRAME48k];
2316 :
2317 625 : Copy32( &( hMcMasa->delay_buffer_lfe[0][0] ), &( delayedInputSignal[0][0] ), hMcMasa->num_slots_delay_comp * l_ts ); // q_inp
2318 625 : Copy32( data_fx[lfeChannelIndex] + hMcMasa->offset_comp, &( delayedInputSignal[0][hMcMasa->num_slots_delay_comp * l_ts] ), ( MDFT_NO_COL_MAX - hMcMasa->num_slots_delay_comp ) * l_ts ); // q_inp
2319 625 : Copy32( &( hMcMasa->delay_buffer_lfe[1][0] ), &( delayedInputSignal[1][0] ), hMcMasa->num_slots_delay_comp * l_ts ); // q_inp
2320 625 : Copy32( data_fx[separateChannelIndex] + hMcMasa->offset_comp, &( delayedInputSignal[1][hMcMasa->num_slots_delay_comp * l_ts] ), ( MDFT_NO_COL_MAX - hMcMasa->num_slots_delay_comp ) * l_ts ); // q_inp
2321 :
2322 625 : lowpassCoef = L_shl( div_w( 1, (Word32) hMcMasa->ringBufferSize ), Q6 ); // Q.37(31+6)
2323 :
2324 600625 : FOR( i = 0; i < input_frame; i++ )
2325 : {
2326 1800000 : FOR( j = 0; j < 2; j++ )
2327 : {
2328 : Word32 temp1, temp2;
2329 1200000 : temp1 = Mpy_32_32( delayedInputSignal[j][i], lowpassCoef ); // Q(q_inp+6)
2330 1200000 : temp2 = Mpy_32_32( hMcMasa->lfeAnaRingBuffer[j][hMcMasa->ringBufferPointer], lowpassCoef ); // Q(q_inp+6)
2331 1200000 : hMcMasa->lowpassSum[j] = L_add( hMcMasa->lowpassSum[j], L_sub( temp1, temp2 ) );
2332 1200000 : move32();
2333 1200000 : lowPassSignal[j][i] = hMcMasa->lowpassSum[j];
2334 1200000 : move32();
2335 1200000 : hMcMasa->lfeAnaRingBuffer[j][hMcMasa->ringBufferPointer] = delayedInputSignal[j][i];
2336 1200000 : move32();
2337 : }
2338 :
2339 600000 : hMcMasa->ringBufferPointer = sub( hMcMasa->ringBufferPointer, 1 );
2340 600000 : move16();
2341 600000 : IF( hMcMasa->ringBufferPointer < 0 )
2342 : {
2343 2500 : hMcMasa->ringBufferPointer = sub( hMcMasa->ringBufferSize, 1 );
2344 : }
2345 : }
2346 625 : lowPassSignal_q = add( q_inp, Q6 );
2347 3125 : FOR( block_m_idx = 0; block_m_idx < MAX_PARAM_SPATIAL_SUBFRAMES; block_m_idx++ )
2348 : {
2349 2500 : mrange[0] = i_mult( hMcMasa->block_grouping[block_m_idx], l_ts );
2350 2500 : move16();
2351 2500 : mrange[1] = i_mult( hMcMasa->block_grouping[block_m_idx + 1], l_ts );
2352 2500 : move16();
2353 :
2354 602500 : FOR( i = mrange[0]; i < mrange[1]; i++ )
2355 : {
2356 600000 : hMcMasa->lfeLfEne[block_m_idx] = BASOP_Util_Add_Mant32Exp( hMcMasa->lfeLfEne[block_m_idx], hMcMasa->lfeLfEne_e[block_m_idx], Mpy_32_32( lowPassSignal[0][i], lowPassSignal[0][i] ), sub( 31, sub( shl( lowPassSignal_q, 1 ), 31 ) ), &hMcMasa->lfeLfEne_e[block_m_idx] );
2357 600000 : move32();
2358 600000 : hMcMasa->totalLfEne[block_m_idx] = BASOP_Util_Add_Mant32Exp( hMcMasa->totalLfEne[block_m_idx], hMcMasa->totalLfEne_e[block_m_idx], Mpy_32_32( lowPassSignal[1][i], lowPassSignal[1][i] ), sub( 31, sub( shl( lowPassSignal_q, 1 ), 31 ) ), &hMcMasa->totalLfEne_e[block_m_idx] );
2359 600000 : move32();
2360 : }
2361 2500 : hMcMasa->totalLfEne[block_m_idx] = BASOP_Util_Add_Mant32Exp( hMcMasa->totalLfEne[block_m_idx], hMcMasa->totalLfEne_e[block_m_idx], hMcMasa->lfeLfEne[block_m_idx], hMcMasa->lfeLfEne_e[block_m_idx], &hMcMasa->totalLfEne_e[block_m_idx] );
2362 2500 : move32();
2363 : }
2364 : }
2365 : ELSE /* Using CLDFB */
2366 : {
2367 : Word16 ts;
2368 : Word16 i;
2369 : Word32 Chnl_RealBuffer[2][DIRAC_NO_FB_BANDS_MAX];
2370 : Word32 Chnl_ImagBuffer[2][DIRAC_NO_FB_BANDS_MAX];
2371 : Word32 *p_Chnl_RealBuffer[2];
2372 : Word32 *p_Chnl_ImagBuffer[2];
2373 :
2374 10845 : p_Chnl_RealBuffer[0] = &Chnl_RealBuffer[0][0];
2375 10845 : p_Chnl_RealBuffer[1] = &Chnl_RealBuffer[1][0];
2376 10845 : p_Chnl_ImagBuffer[0] = &Chnl_ImagBuffer[0][0];
2377 10845 : p_Chnl_ImagBuffer[1] = &Chnl_ImagBuffer[1][0];
2378 :
2379 :
2380 54225 : FOR( block_m_idx = 0; block_m_idx < MAX_PARAM_SPATIAL_SUBFRAMES; block_m_idx++ )
2381 : {
2382 43380 : mrange[0] = hMcMasa->block_grouping[block_m_idx];
2383 43380 : move16();
2384 43380 : mrange[1] = hMcMasa->block_grouping[block_m_idx + 1];
2385 43380 : move16();
2386 :
2387 86760 : FOR( ts = mrange[0]; ts < mrange[1]; ts++ )
2388 : {
2389 43380 : ivas_fb_mixer_get_windowed_fr_fx( hMcMasa->hFbMixerLfe, pcm_in, p_Chnl_RealBuffer, p_Chnl_ImagBuffer, l_ts, l_ts, hMcMasa->hFbMixerLfe->fb_cfg->num_in_chans, 0 );
2390 :
2391 43380 : ivas_fb_mixer_update_prior_input_fx( hMcMasa->hFbMixerLfe, pcm_in, l_ts, hMcMasa->hFbMixerLfe->fb_cfg->num_in_chans );
2392 :
2393 43380 : pcm_in[0] += l_ts;
2394 :
2395 : /* Compute low frequency energy for LFE, for other channels it is computed in ivas_chnl_param_est_enc() */
2396 216900 : FOR( i = 0; i < CLDFB_TO_MDFT_FAC; i++ )
2397 : {
2398 173520 : hMcMasa->lfeLfEne[block_m_idx] = BASOP_Util_Add_Mant32Exp( hMcMasa->lfeLfEne[block_m_idx], hMcMasa->lfeLfEne_e[block_m_idx], L_add( Mpy_32_32( Chnl_RealBuffer[0][i], Chnl_RealBuffer[0][i] ), Mpy_32_32( Chnl_ImagBuffer[0][i], Chnl_ImagBuffer[0][i] ) ), sub( 31, sub( shl( inp_q, 1 ), 31 ) ), &hMcMasa->lfeLfEne_e[block_m_idx] );
2399 173520 : move32();
2400 : }
2401 : }
2402 : }
2403 : }
2404 :
2405 11470 : IF( hMcMasa->separateChannelEnabled )
2406 : {
2407 625 : Copy32( data_fx[lfeChannelIndex] + ( input_frame - hMcMasa->num_samples_delay_comp + hMcMasa->offset_comp ), &( hMcMasa->delay_buffer_lfe[0][0] ), sub( hMcMasa->num_samples_delay_comp, hMcMasa->offset_comp ) ); // q_in
2408 625 : Copy32( data_fx[separateChannelIndex] + ( input_frame - hMcMasa->num_samples_delay_comp + hMcMasa->offset_comp ), &( hMcMasa->delay_buffer_lfe[1][0] ), sub( hMcMasa->num_samples_delay_comp, hMcMasa->offset_comp ) ); // q_in
2409 : }
2410 :
2411 11470 : return;
2412 : }
|