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