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 277 : 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 277 : error = IVAS_ERR_OK;
139 277 : move32();
140 :
141 277 : assert( st_ivas->hMasa != NULL && "MASA encoder handle is not present" );
142 277 : hMasa = st_ivas->hMasa;
143 :
144 277 : 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 277 : nchan_inp = st_ivas->hEncoderConfig->nchan_inp;
150 277 : move16();
151 277 : input_Fs = st_ivas->hEncoderConfig->input_Fs;
152 277 : move32();
153 :
154 : /* Determine if to separate some channels from the analysis */
155 277 : ivas_mcmasa_set_separate_channel_mode_fx( &( hMcMasa->separateChannelEnabled ), &( hMcMasa->separateChannelIndex ), st_ivas->hEncoderConfig->ivas_total_brate );
156 :
157 277 : numAnalysisChannels = sub( nchan_inp, 1 );
158 277 : 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 277 : 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 277 : hMcMasa->nbands = st_ivas->hMasa->config.numCodingBands;
172 277 : move16();
173 277 : hMcMasa->nCodingBands = st_ivas->hMasa->config.numCodingBands;
174 277 : move16();
175 :
176 : /* Determine band grouping */
177 277 : 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 277 : band_mapping = hMasa->data.band_mapping;
188 1939 : FOR( i = 0; i < hMcMasa->nbands + 1; i++ )
189 : {
190 1662 : hMcMasa->band_grouping[i] = i_mult( MASA_band_grouping_24[band_mapping[i]], CLDFB_TO_MDFT_FAC );
191 1662 : move16();
192 : }
193 : }
194 :
195 277 : maxBin = extract_l( W_extract_h( W_add( W_mult_32_32( input_Fs, INV_CLDFB_BANDWIDTH_MDFT_FAC_Q31 ), ONE_IN_Q31 /*0.5f in Q32*/ ) ) ); // Q0
196 :
197 1385 : FOR( i = 1; i < hMcMasa->nbands + 1; i++ )
198 : {
199 1385 : IF( GE_32( hMcMasa->band_grouping[i], maxBin ) )
200 : {
201 277 : hMcMasa->band_grouping[i] = maxBin; // Q0
202 277 : move16();
203 277 : hMcMasa->nbands = i;
204 277 : move16();
205 277 : BREAK;
206 : }
207 : }
208 :
209 : /* initialize delay compensation */
210 277 : hMcMasa->num_samples_delay_comp = NS2SA_FX2( input_Fs, DELAY_DIRAC_ENC_CMP_NS );
211 277 : move16();
212 : #ifdef DISABLE_DIRAC_DELAY_COMP
213 : hMcMasa->num_samples_delay_comp = 0; /* disable delay compensation by setting to 0 */
214 : #endif
215 277 : tmp_f = idiv1616( hMcMasa->num_samples_delay_comp, ( NS2SA_FX2( input_Fs, DIRAC_SLOT_ENC_NS ) ) );
216 277 : hMcMasa->num_slots_delay_comp = tmp_f;
217 277 : move16();
218 :
219 277 : IF( GT_16( hMcMasa->num_samples_delay_comp, ( NS2SA_FX2( input_Fs, DIRAC_SLOT_ENC_NS ) ) ) )
220 : {
221 277 : hMcMasa->num_slots_delay_comp = add( hMcMasa->num_slots_delay_comp, 1 );
222 277 : move16();
223 277 : hMcMasa->offset_comp = negate( hMcMasa->num_samples_delay_comp );
224 277 : move16();
225 277 : hMcMasa->num_samples_delay_comp = i_mult( hMcMasa->num_slots_delay_comp, NS2SA_FX2( input_Fs, DIRAC_SLOT_ENC_NS ) );
226 277 : move16();
227 277 : hMcMasa->offset_comp = add( hMcMasa->offset_comp, hMcMasa->num_samples_delay_comp );
228 277 : move16();
229 : }
230 : ELSE
231 : {
232 0 : hMcMasa->offset_comp = 0;
233 0 : move16();
234 : }
235 :
236 : /* set FB config. */
237 277 : 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 277 : 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 277 : 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 249 : 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 249 : 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 249 : hMcMasa->delay_buffer_lfe[0] = NULL;
278 249 : hMcMasa->delay_buffer_lfe[1] = NULL;
279 : }
280 :
281 277 : 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 1108 : FOR( i = 0; i < DIRAC_NUM_DIMS; i++ )
309 : {
310 831 : 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 4155 : FOR( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ )
316 : {
317 3324 : 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 1108 : FOR( i = 0; i < DIRAC_NUM_DIMS; i++ )
325 : {
326 831 : 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 4155 : FOR( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ )
332 : {
333 3324 : 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 277 : hMcMasa->no_col_avg_diff = (Word8) ( DIRAC_NO_COL_AVG_DIFF_NS / DIRAC_SLOT_ENC_NS ); /* dirac_slot_ns = DIRAC_SLOT_ENC_NS */
341 277 : move16();
342 :
343 1108 : FOR( i = 0; i < DIRAC_NUM_DIMS; i++ )
344 : {
345 831 : 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 7479 : FOR( j = 0; j < hMcMasa->no_col_avg_diff; j++ )
351 : {
352 6648 : 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 6648 : set_zero_fx( hMcMasa->buffer_intensity_real_fx[i][j], hMcMasa->nbands ); // hMcMasa->buffer_intensity_real_q
357 : }
358 : }
359 277 : set16_fx( hMcMasa->buffer_intensity_real_q, 31, DIRAC_NO_COL_AVG_DIFF );
360 :
361 277 : 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 2493 : FOR( j = 0; j < hMcMasa->no_col_avg_diff; j++ )
367 : {
368 2216 : 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 2216 : set_zero_fx( hMcMasa->buffer_intensity_real_vert_fx[j], hMcMasa->nbands );
373 : }
374 :
375 277 : 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 277 : set_zero_fx( hMcMasa->buffer_energy_fx, imult1616( hMcMasa->nbands, hMcMasa->no_col_avg_diff ) ); // hMcMasa->buffer_energy_q
380 277 : set16_fx( hMcMasa->buffer_intensity_real_vert_q, 31, DIRAC_NO_COL_AVG_DIFF );
381 277 : set16_fx( hMcMasa->buffer_energy_q, 31, DIRAC_NO_COL_AVG_DIFF );
382 :
383 277 : IF( EQ_32( st_ivas->hEncoderConfig->mc_input_setup, MC_LS_SETUP_5_1 ) )
384 : {
385 169 : Copy32( ls_azimuth_CICP6_fx, ls_azimuth, sub( nchan_inp, 1 ) );
386 169 : Copy32( ls_elevation_CICP6_fx, ls_elevation, sub( nchan_inp, 1 ) );
387 169 : hMcMasa->numHorizontalChannels = 5;
388 169 : move16();
389 169 : hMcMasa->isHorizontalSetup = 1;
390 169 : 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 277 : 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 277 : computeEvenLayout_fx( ls_azimuth, ls_azimuth_even, hMcMasa->numHorizontalChannels );
438 277 : IF( !hMcMasa->isHorizontalSetup )
439 : {
440 95 : computeEvenLayout_fx( &ls_azimuth[hMcMasa->numHorizontalChannels], &ls_azimuth_even[hMcMasa->numHorizontalChannels], sub( numAnalysisChannels, hMcMasa->numHorizontalChannels ) );
441 : }
442 :
443 2170 : FOR( i = 0; i < numAnalysisChannels; i++ )
444 : {
445 1893 : hMcMasa->chnlToFoaMtx_fx[0][i] = ONE_IN_Q31;
446 1893 : move32();
447 1893 : hMcMasa->chnlToFoaMtx_fx[1][i] = L_mult( getSineWord16R2( extract_l( Mpy_32_32( ls_azimuth[i], 46603 /*32767/360*/ ) /*Q22+Q24-31=>Q15*/ ) ), getCosWord16R2( extract_l( Mpy_32_32( ls_elevation[i], 46603 /*2^24/360*/ ) ) ) ); // Q31
448 1893 : move32();
449 1893 : hMcMasa->chnlToFoaMtx_fx[2][i] = L_shl( getSineWord16R2( extract_l( Mpy_32_32( ls_elevation[i], 46603 /*2^24/360*/ ) ) ), 16 ); // Q31
450 1893 : move32();
451 1893 : hMcMasa->chnlToFoaMtx_fx[3][i] = L_mult( getCosWord16R2( extract_l( Mpy_32_32( ls_azimuth[i], 46603 /*2^24/360*/ ) ) ), getCosWord16R2( extract_l( Mpy_32_32( ls_elevation[i], 46603 /*2^24/360*/ ) ) ) ); // Q31
452 1893 : move32();
453 :
454 1893 : hMcMasa->chnlToFoaEvenMtx_fx[0][i] = ONE_IN_Q31;
455 1893 : move32();
456 1893 : hMcMasa->chnlToFoaEvenMtx_fx[1][i] = L_shl( getSineWord16R2( extract_l( Mpy_32_32( ls_azimuth_even[i], 46603 /*2^24/360*/ ) ) ), 16 ); // Q31
457 1893 : move32();
458 1893 : hMcMasa->chnlToFoaEvenMtx_fx[2][i] = 0;
459 1893 : move32();
460 1893 : hMcMasa->chnlToFoaEvenMtx_fx[3][i] = L_shl( getCosWord16R2( extract_l( Mpy_32_32( ls_azimuth_even[i], 46603 /*2^24/360*/ ) ) ), 16 );
461 1893 : move32();
462 : }
463 :
464 277 : hMcMasa->combineRatios = hMasa->config.mergeRatiosOverSubframes;
465 277 : move16();
466 :
467 277 : Copy32( ls_azimuth, hMcMasa->ls_azimuth_fx, numAnalysisChannels ); // Q22
468 :
469 1810 : FOR( i = 0; i < hMcMasa->numHorizontalChannels; i++ )
470 : {
471 1533 : left_min = ( 360 << 22 );
472 1533 : right_min = -( ( 360 << 22 ) );
473 :
474 10214 : FOR( j = 0; j < hMcMasa->numHorizontalChannels; j++ )
475 : {
476 8681 : azi_diff = L_sub( ls_azimuth[j], ls_azimuth[i] );
477 :
478 8681 : IF( GT_32( azi_diff, ( 180 << 22 ) ) )
479 : {
480 466 : azi_diff = L_sub( azi_diff, 360 << 22 );
481 : }
482 8215 : ELSE IF( LT_32( azi_diff, -( 180 << 22 ) ) )
483 : {
484 466 : azi_diff = L_add( azi_diff, 360 << 22 );
485 : }
486 8681 : test();
487 8681 : IF( LT_32( azi_diff, left_min ) && azi_diff > 0 )
488 : {
489 2336 : hMcMasa->leftNearest[i] = j;
490 2336 : move16();
491 2336 : left_min = azi_diff;
492 2336 : move32();
493 : }
494 8681 : test();
495 8681 : IF( GT_32( azi_diff, right_min ) && azi_diff < 0 )
496 : {
497 2059 : hMcMasa->rightNearest[i] = j;
498 2059 : move16();
499 2059 : right_min = azi_diff;
500 2059 : move32();
501 : }
502 : }
503 : }
504 :
505 277 : hMcMasa->prevMultiChEne_fx = 0;
506 277 : move32();
507 277 : hMcMasa->prevDownmixEne_fx = 0;
508 277 : move32();
509 277 : hMcMasa->prevMultiChEne_e = 0;
510 277 : move16();
511 277 : hMcMasa->prevDownmixEne_e = 0;
512 277 : move16();
513 277 : hMcMasa->prevEQ_e = 1;
514 277 : move16();
515 277 : hMcMasa->prevEQ_fx = 1073741824;
516 277 : move32();
517 277 : input_frame = (Word16) Mpy_32_32( input_Fs, ONE_BY_FRAMES_PER_SEC_Q31 );
518 253397 : FOR( i = 0; i < input_frame; i++ )
519 : {
520 253120 : hMcMasa->interpolator_fx[i] = div_s( i, input_frame );
521 253120 : move16();
522 : }
523 :
524 277 : mvs2s( DirAC_block_grouping_5ms_MDFT, hMcMasa->block_grouping, MAX_PARAM_SPATIAL_SUBFRAMES + 1 );
525 :
526 277 : hMcMasa->index_buffer_intensity = 0;
527 277 : move16();
528 277 : st_ivas->hMcMasa = hMcMasa;
529 :
530 277 : return error;
531 : }
532 : /*-------------------------------------------------------------------------
533 : * ivas_mcmasa_enc_reconfig()
534 : *
535 : * Reconfigure McMASA encoder
536 : *------------------------------------------------------------------------*/
537 :
538 46 : 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 46 : error = IVAS_ERR_OK;
546 46 : move32();
547 :
548 46 : ivas_total_brate = st_ivas->hEncoderConfig->ivas_total_brate;
549 46 : move32();
550 :
551 46 : 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 46 : ivas_masa_enc_close_fx( &( st_ivas->hMasa ) );
557 :
558 46 : 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 46 : ivas_mcmasa_setNumTransportChannels_fx( &( st_ivas->nchan_transport ), &( st_ivas->hEncoderConfig->element_mode_init ), ivas_total_brate );
562 :
563 46 : IF( NE_32( ( error = ivas_masa_enc_open_fx( st_ivas ) ), IVAS_ERR_OK ) )
564 : {
565 0 : return error;
566 : }
567 46 : 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 46 : return error;
576 : }
577 : /*--------------------------------------------------------------------------*
578 : * ivas_mcmasa_enc_close()
579 : *
580 : *
581 : *--------------------------------------------------------------------------*/
582 :
583 1271 : 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 1271 : test();
591 1271 : IF( hMcMasa == NULL || *hMcMasa == NULL )
592 : {
593 994 : return;
594 : }
595 :
596 277 : 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 277 : ivas_FB_mixer_close_fx( &( *hMcMasa )->hFbMixer, input_Fs, 0 );
608 :
609 277 : IF( !( *hMcMasa )->separateChannelEnabled )
610 : {
611 249 : ivas_FB_mixer_close_fx( &( *hMcMasa )->hFbMixerLfe, input_Fs, 0 );
612 : }
613 :
614 : /* intensity 3-dim */
615 1108 : FOR( i = 0; i < DIRAC_NUM_DIMS; i++ )
616 : {
617 4155 : FOR( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ )
618 : {
619 3324 : free( ( *hMcMasa )->direction_vector_m_fx[i][j] );
620 3324 : ( *hMcMasa )->direction_vector_m_fx[i][j] = NULL;
621 : }
622 4155 : FOR( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ )
623 : {
624 3324 : free( ( *hMcMasa )->direction_vector_e[i][j] );
625 3324 : ( *hMcMasa )->direction_vector_e[i][j] = NULL;
626 : }
627 :
628 7479 : FOR( j = 0; j < ( *hMcMasa )->no_col_avg_diff; j++ )
629 : {
630 6648 : free( ( *hMcMasa )->buffer_intensity_real_fx[i][j] );
631 6648 : ( *hMcMasa )->buffer_intensity_real_fx[i][j] = NULL;
632 : }
633 :
634 831 : free( ( *hMcMasa )->buffer_intensity_real_fx[i] );
635 831 : ( *hMcMasa )->buffer_intensity_real_fx[i] = NULL;
636 :
637 831 : free( ( *hMcMasa )->direction_vector_m_fx[i] );
638 831 : ( *hMcMasa )->direction_vector_m_fx[i] = NULL;
639 :
640 831 : free( ( *hMcMasa )->direction_vector_e[i] );
641 831 : ( *hMcMasa )->direction_vector_e[i] = NULL;
642 : }
643 :
644 2493 : FOR( j = 0; j < ( *hMcMasa )->no_col_avg_diff; j++ )
645 : {
646 2216 : free( ( *hMcMasa )->buffer_intensity_real_vert_fx[j] );
647 2216 : ( *hMcMasa )->buffer_intensity_real_vert_fx[j] = NULL;
648 : }
649 277 : free( ( *hMcMasa )->buffer_intensity_real_vert_fx );
650 277 : ( *hMcMasa )->buffer_intensity_real_vert_fx = NULL;
651 :
652 277 : free( ( *hMcMasa )->buffer_energy_fx );
653 277 : ( *hMcMasa )->buffer_energy_fx = NULL;
654 :
655 277 : free( ( *hMcMasa ) );
656 277 : ( *hMcMasa ) = NULL;
657 :
658 277 : return;
659 : }
660 : /*--------------------------------------------------------------------------*
661 : * ivas_mcmasa_enc()
662 : *
663 : * Multichannel MASA encoder
664 : *--------------------------------------------------------------------------*/
665 :
666 11470 : 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 11470 : Word16 nBands = hMcMasa->nbands;
679 11470 : move16();
680 11470 : Word16 nBlocks = MAX_PARAM_SPATIAL_SUBFRAMES;
681 11470 : move16();
682 11470 : UWord8 fixedDistance = 0;
683 11470 : 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 11470 : computeLfeEnergy_fx( hMcMasa, data_fx, input_frame, q_inp );
693 :
694 : /* Sum center and LFE, move surround channels */
695 11470 : v_add_32( data_fx[2], data_fx[3], data_fx[2], input_frame ); // q_inp
696 42430 : FOR( i = 4; i < nchan_inp; i++ )
697 : {
698 30960 : Copy32( data_fx[i], data_fx[i - 1], input_frame ); // q_inp
699 : }
700 :
701 11470 : 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 11470 : ivas_mcmasa_param_est_enc_fx( hMcMasa, hMasa, data_fx, elevation_m_values_fx, azimuth_m_values_fx, energyRatio_fx, spreadCoherence_fx, surroundingCoherence_fx, input_frame, nchan_inp, q_inp );
719 :
720 : /* Determine LFE-to-total energy ratio */
721 57350 : FOR( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ )
722 : {
723 45880 : hMasa->data.lfeToTotalEnergyRatio_fx[i] = L_deposit_h( BASOP_Util_Divide3232_Scale( hMcMasa->lfeLfEne[i], L_add( EPSILON_FX, hMcMasa->totalLfEne[i] ), &hMasa->data.lfeToTotalEnergyRatio_e[i] ) ); // hMasa->data.lfeToTotalEnergyRatio_e[i]
724 45880 : hMasa->data.lfeToTotalEnergyRatio_e[i] = add( sub( hMcMasa->lfeLfEne_e[i], hMcMasa->totalLfEne_e[i] ), hMasa->data.lfeToTotalEnergyRatio_e[i] );
725 45880 : move32();
726 45880 : move16();
727 : }
728 :
729 : /* Set analyzed values to the MASA struct */
730 68820 : FOR( i = 0; i < nBands; i++ )
731 : {
732 286750 : FOR( j = 0; j < nBlocks; j++ )
733 : {
734 229400 : IF( hMcMasa->combineRatios )
735 : {
736 229400 : k = 0;
737 229400 : move16();
738 : }
739 : ELSE
740 : {
741 0 : k = j;
742 0 : move16();
743 : }
744 :
745 229400 : hQMeta->q_direction[0].band_data[i].azimuth_fx[j] = azimuth_m_values_fx[j][i]; // Q22
746 229400 : move32();
747 229400 : hQMeta->q_direction[0].band_data[i].elevation_fx[j] = elevation_m_values_fx[j][i]; // Q22
748 229400 : move32();
749 229400 : hQMeta->q_direction[0].band_data[i].energy_ratio_fx[j] = energyRatio_fx[k][i]; // Q31
750 229400 : move32();
751 229400 : hQMeta->q_direction[0].band_data[i].distance[j] = fixedDistance;
752 229400 : move16();
753 :
754 229400 : IF( hQMeta->surcoh_band_data != NULL )
755 : {
756 202200 : hQMeta->q_direction[0].coherence_band_data[i].spread_coherence[j] = (UWord8) round_fx( Mpy_32_32( spreadCoherence_fx[j][i], L_shl( UINT8_MAX, Q17 ) ) ); // Q0
757 202200 : hQMeta->surcoh_band_data[i].surround_coherence[j] = (UWord8) round_fx( Mpy_32_32( surroundingCoherence_fx[k][i], L_shl( UINT8_MAX, Q16 ) ) ); // Q0
758 202200 : move16();
759 202200 : move16();
760 : }
761 : }
762 : }
763 :
764 : /* At lower sampling rates, set zeros for higher bands that were not analyzed */
765 11470 : 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 11470 : ivas_mcmasa_dmx_fx( hMcMasa, data_fx, sub( 31, q_inp ), input_frame, nchan_transport, nchan_inp );
793 :
794 11470 : 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 11470 : hMasa->config.joinedSubframes = FALSE;
803 11470 : move16();
804 11470 : hQMeta->q_direction[0].cfg.nbands = hMcMasa->nbands;
805 11470 : move16();
806 11470 : hQMeta->q_direction[0].cfg.nblocks = MAX_PARAM_SPATIAL_SUBFRAMES;
807 11470 : move16();
808 11470 : hQMeta->all_coherence_zero = 1;
809 11470 : move16();
810 :
811 : /* Check spread coherence */
812 11470 : i = 0;
813 11470 : move16();
814 11470 : test();
815 25892 : WHILE( ( i < nBlocks ) && hQMeta->all_coherence_zero )
816 : {
817 14422 : test();
818 14422 : j = 0;
819 14422 : move16();
820 14422 : test();
821 44499 : WHILE( LT_16( j, nBands ) && hQMeta->all_coherence_zero )
822 : {
823 30077 : test();
824 30077 : IF( GT_32( spreadCoherence_fx[i][j], MASA_COHERENCE_THRESHOLD_FX >> 1 ) )
825 : {
826 10678 : hQMeta->all_coherence_zero = 0;
827 10678 : move16();
828 : }
829 30077 : j++;
830 : }
831 14422 : i++;
832 : }
833 :
834 : /* Check surrounding coherence */
835 11470 : 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 11470 : hMasa->config.coherencePresent = !hQMeta->all_coherence_zero;
869 11470 : move16();
870 :
871 11470 : return;
872 : }
873 :
874 : /*--------------------------------------------------------------------------*
875 : * ivas_mcmasa_param_est_enc()
876 : *
877 : * Estimate metadata parameters for McMASA
878 : *--------------------------------------------------------------------------*/
879 :
880 11470 : 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 11470 : Word16 lsEnergySum_e = 0, maxEne_e;
932 11470 : 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 137640 : FOR( i = 0; i < MCMASA_MAX_ANA_CHANS; i++ )
955 : {
956 126170 : set_zero_fx( Chnl_RealBuffer_fx[i], DIRAC_NO_FB_BANDS_MAX );
957 126170 : set_zero_fx( Chnl_ImagBuffer_fx[i], DIRAC_NO_FB_BANDS_MAX );
958 : }
959 :
960 11470 : num_freq_bins = idiv1616( input_frame, MDFT_NO_COL_MAX );
961 11470 : num_freq_bands = hMcMasa->nbands;
962 11470 : move16();
963 11470 : l_ts = idiv1616( input_frame, MDFT_NO_COL_MAX );
964 :
965 11470 : set16_fx( q_vdv, 31, MASA_FREQUENCY_BANDS );
966 11470 : set16_fx( out_exp, 30, MASA_FREQUENCY_BANDS );
967 :
968 11470 : numAnalysisChannels = sub( nchan_inp, 1 );
969 11470 : IF( hMcMasa->separateChannelEnabled )
970 : {
971 625 : numAnalysisChannels = sub( nchan_inp, 2 );
972 : }
973 :
974 11470 : IF( hMcMasa->combineRatios )
975 : {
976 : /* Need to initialize renormalization_factors, and variables to be normalized */
977 11470 : set_zero_fx( renormalization_factor_diff_fx, hMcMasa->nbands ); // renormalization_factor_diff_e
978 11470 : set16_fx( renormalization_factor_diff_e, 0, hMcMasa->nbands );
979 11470 : set_zero_fx( &diffuseness_m_fx[0][0], MASA_FREQUENCY_BANDS * MAX_PARAM_SPATIAL_SUBFRAMES ); // diffuseness_e
980 11470 : set16_fx( &diffuseness_e[0][0], 31, MASA_FREQUENCY_BANDS * MAX_PARAM_SPATIAL_SUBFRAMES );
981 11470 : set_zero_fx( renormalization_factor_coh_fx, hMcMasa->nbands ); // renormalization_factor_coh_e
982 11470 : set16_fx( renormalization_factor_coh_e, 31, hMcMasa->nbands );
983 11470 : set_zero_fx( surroundingCoherence_fx[0], hMcMasa->nbands ); // surroundingCoherence_e
984 11470 : set16_fx( &surroundingCoherence_e[0][0], 31, MASA_FREQUENCY_BANDS * MAX_PARAM_SPATIAL_SUBFRAMES );
985 11470 : set_zero_fx( coherentEnergyRatio_fx[0], hMcMasa->nbands ); // coherentEnergyRatio_e
986 11470 : 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 76215 : FOR( i = 0; i < numAnalysisChannels; i++ )
991 : {
992 64745 : pcm_in[i] = data_f[i]; // q_inp
993 64745 : p_Chnl_RealBuffer_fx[i] = &Chnl_RealBuffer_fx[i][0]; // q_inp
994 64745 : p_Chnl_ImagBuffer_fx[i] = &Chnl_ImagBuffer_fx[i][0]; // q_inp
995 : }
996 :
997 : /* initialising energy_fx */
998 57350 : FOR( block_m_idx = 0; block_m_idx < MAX_PARAM_SPATIAL_SUBFRAMES; block_m_idx++ )
999 : {
1000 1147000 : FOR( i = 0; i < MASA_FREQUENCY_BANDS; i++ )
1001 : {
1002 1101120 : hMasa->data.energy_fx[block_m_idx][i] = 0; // hMasa->data.energy_e
1003 1101120 : move32();
1004 1101120 : hMasa->data.energy_e[block_m_idx][i] = 31;
1005 1101120 : move16();
1006 : }
1007 : }
1008 11470 : hMasa->data.q_energy = 0;
1009 11470 : move16();
1010 :
1011 : /* do processing over all CLDFB time slots */
1012 57350 : FOR( block_m_idx = 0; block_m_idx < MAX_PARAM_SPATIAL_SUBFRAMES; block_m_idx++ )
1013 : {
1014 45880 : mrange[0] = hMcMasa->block_grouping[block_m_idx];
1015 45880 : move16();
1016 45880 : mrange[1] = hMcMasa->block_grouping[block_m_idx + 1];
1017 45880 : move16();
1018 :
1019 275280 : FOR( band_m_idx = 0; band_m_idx < hMcMasa->nbands; band_m_idx++ )
1020 : {
1021 229400 : hMcMasa->direction_vector_m_fx[0][block_m_idx][band_m_idx] = 0;
1022 229400 : move32();
1023 229400 : hMcMasa->direction_vector_m_fx[1][block_m_idx][band_m_idx] = 0;
1024 229400 : move32();
1025 229400 : hMcMasa->direction_vector_m_fx[2][block_m_idx][band_m_idx] = 0;
1026 229400 : move32();
1027 : }
1028 :
1029 : /* Reset variable */
1030 275280 : FOR( i = 0; i < hMcMasa->nbands; i++ )
1031 : {
1032 1524300 : FOR( j = 0; j < numAnalysisChannels; j++ )
1033 : {
1034 1294900 : set_zero_fx( COVls[i].xr_fx[j], numAnalysisChannels ); // COVls[i].xr_e[j]
1035 1294900 : set_zero_fx( COVls[i].xi_fx[j], numAnalysisChannels ); // COVls[i].xi_e[j]
1036 1294900 : set16_fx( COVls[i].xr_e[j], 0, numAnalysisChannels );
1037 1294900 : set16_fx( COVls[i].xi_e[j], 0, numAnalysisChannels );
1038 : }
1039 : }
1040 :
1041 91760 : FOR( ts = mrange[0]; ts < mrange[1]; ts++ )
1042 : {
1043 45880 : Word16 cr_q = MAX_16, ci_q = MAX_16, sf;
1044 45880 : Word16 inp_q = q_inp;
1045 45880 : move16();
1046 45880 : move16();
1047 45880 : move16();
1048 :
1049 45880 : ivas_fb_mixer_get_windowed_fr_fx( hMcMasa->hFbMixer, pcm_in, p_Chnl_RealBuffer_fx, p_Chnl_ImagBuffer_fx, l_ts, l_ts, hMcMasa->hFbMixer->fb_cfg->num_in_chans, 0 );
1050 :
1051 45880 : ivas_fb_mixer_update_prior_input_fx( hMcMasa->hFbMixer, pcm_in, l_ts, hMcMasa->hFbMixer->fb_cfg->num_in_chans );
1052 :
1053 304860 : FOR( i = 0; i < numAnalysisChannels; i++ )
1054 : {
1055 258980 : pcm_in[i] += l_ts;
1056 258980 : cr_q = s_min( cr_q, L_norm_arr( Chnl_ImagBuffer_fx[i], DIRAC_NO_FB_BANDS_MAX ) );
1057 258980 : ci_q = s_min( ci_q, L_norm_arr( Chnl_RealBuffer_fx[i], DIRAC_NO_FB_BANDS_MAX ) );
1058 : }
1059 :
1060 45880 : sf = sub( s_min( cr_q, ci_q ), 5 );
1061 304860 : FOR( i = 0; i < numAnalysisChannels; i++ )
1062 : {
1063 258980 : scale_sig32( Chnl_RealBuffer_fx[i], DIRAC_NO_FB_BANDS_MAX, sf ); // Q-> inp_q + sf
1064 258980 : scale_sig32( Chnl_ImagBuffer_fx[i], DIRAC_NO_FB_BANDS_MAX, sf ); // Q-> inp_q + sf
1065 : }
1066 45880 : inp_q = add( inp_q, sf );
1067 :
1068 : /* Compute covariance matrix */
1069 275280 : FOR( i = 0; i < num_freq_bands; i++ )
1070 : {
1071 229400 : brange[0] = hMcMasa->band_grouping[i];
1072 229400 : move16();
1073 229400 : brange[1] = hMcMasa->band_grouping[i + 1];
1074 229400 : move16();
1075 11176600 : FOR( j = brange[0]; j < brange[1]; j++ )
1076 : {
1077 10947200 : 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 1524300 : FOR( j = 0; j < numAnalysisChannels; j++ )
1082 : {
1083 1294900 : move32();
1084 1294900 : hMasa->data.energy_fx[block_m_idx][i] = BASOP_Util_Add_Mant32Exp( hMasa->data.energy_fx[block_m_idx][i], hMasa->data.energy_e[block_m_idx][i], COVls[i].xr_fx[j][j], COVls[i].xr_e[j][j], &hMasa->data.energy_e[block_m_idx][i] );
1085 : }
1086 : }
1087 :
1088 45880 : IF( !hMcMasa->separateChannelEnabled )
1089 : {
1090 : /* Compute low frequency energy */
1091 277520 : FOR( i = 0; i < numAnalysisChannels; i++ )
1092 : {
1093 1170700 : FOR( j = 0; j < CLDFB_TO_MDFT_FAC; j++ )
1094 : {
1095 936560 : move32();
1096 936560 : hMcMasa->totalLfEne[block_m_idx] = BASOP_Util_Add_Mant32Exp( hMcMasa->totalLfEne[block_m_idx], hMcMasa->totalLfEne_e[block_m_idx], L_add( Mpy_32_32( Chnl_RealBuffer_fx[i][j], Chnl_RealBuffer_fx[i][j] ), Mpy_32_32( Chnl_ImagBuffer_fx[i][j], Chnl_ImagBuffer_fx[i][j] ) ), sub( 31, sub( shl( inp_q, 1 ), 31 ) ), &hMcMasa->totalLfEne_e[block_m_idx] );
1097 : }
1098 : }
1099 : }
1100 :
1101 : /* Compute standard FOA */
1102 : /* W */
1103 45880 : v_add_32( Chnl_RealBuffer_fx[0], Chnl_RealBuffer_fx[1], Foa_RealBuffer_fx[0], num_freq_bins ); // inp_q
1104 45880 : v_add_32( Chnl_ImagBuffer_fx[0], Chnl_ImagBuffer_fx[1], Foa_ImagBuffer_fx[0], num_freq_bins ); // inp_q
1105 213100 : FOR( i = 2; i < numAnalysisChannels; i++ )
1106 : {
1107 167220 : v_add_32( Chnl_RealBuffer_fx[i], Foa_RealBuffer_fx[0], Foa_RealBuffer_fx[0], num_freq_bins ); // inp_q
1108 167220 : 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 45880 : v_multc_fixed( Chnl_RealBuffer_fx[0], hMcMasa->chnlToFoaMtx_fx[1][0], Foa_RealBuffer_fx[1], num_freq_bins ); // inp_q
1113 45880 : v_multc_fixed( Chnl_ImagBuffer_fx[0], hMcMasa->chnlToFoaMtx_fx[1][0], Foa_ImagBuffer_fx[1], num_freq_bins ); // inp_q
1114 258980 : FOR( i = 1; i < numAnalysisChannels; i++ )
1115 : {
1116 213100 : v_multc_acc_32_32( Chnl_RealBuffer_fx[i], hMcMasa->chnlToFoaMtx_fx[1][i], Foa_RealBuffer_fx[1], num_freq_bins ); // inp_q
1117 213100 : 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 45880 : IF( hMcMasa->isHorizontalSetup )
1122 : {
1123 : /* Set zero for horizontal setups */
1124 39760 : set_zero_fx( Foa_RealBuffer_fx[2], num_freq_bins );
1125 39760 : 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 45880 : v_multc_fixed( Chnl_RealBuffer_fx[0], hMcMasa->chnlToFoaMtx_fx[3][0], Foa_RealBuffer_fx[3], num_freq_bins ); // inp_q
1140 45880 : v_multc_fixed( Chnl_ImagBuffer_fx[0], hMcMasa->chnlToFoaMtx_fx[3][0], Foa_ImagBuffer_fx[3], num_freq_bins ); // inp_q
1141 258980 : FOR( i = 1; i < numAnalysisChannels; i++ )
1142 : {
1143 213100 : v_multc_acc_32_32( Chnl_RealBuffer_fx[i], hMcMasa->chnlToFoaMtx_fx[3][i], Foa_RealBuffer_fx[3], num_freq_bins ); // inp_q
1144 213100 : 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 45880 : Copy32( Foa_RealBuffer_fx[0], FoaEven_RealBuffer_fx[0], num_freq_bins ); // inp_q
1150 45880 : Copy32( Foa_ImagBuffer_fx[0], FoaEven_ImagBuffer_fx[0], num_freq_bins ); // inp_q
1151 :
1152 : /* Y */
1153 45880 : v_multc_fixed( Chnl_RealBuffer_fx[0], hMcMasa->chnlToFoaEvenMtx_fx[1][0], FoaEven_RealBuffer_fx[1], num_freq_bins ); // inp_q
1154 45880 : v_multc_fixed( Chnl_ImagBuffer_fx[0], hMcMasa->chnlToFoaEvenMtx_fx[1][0], FoaEven_ImagBuffer_fx[1], num_freq_bins ); // inp_q
1155 258980 : FOR( i = 1; i < numAnalysisChannels; i++ )
1156 : {
1157 213100 : v_multc_acc_32_32( Chnl_RealBuffer_fx[i], hMcMasa->chnlToFoaEvenMtx_fx[1][i], FoaEven_RealBuffer_fx[1], num_freq_bins ); // inp_q
1158 213100 : 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 45880 : set_zero_fx( FoaEven_RealBuffer_fx[2], num_freq_bins ); // inp_q
1163 45880 : set_zero_fx( FoaEven_ImagBuffer_fx[2], num_freq_bins ); // inp_q
1164 :
1165 : /* X */
1166 45880 : v_multc_fixed( Chnl_RealBuffer_fx[0], hMcMasa->chnlToFoaEvenMtx_fx[3][0], FoaEven_RealBuffer_fx[3], num_freq_bins ); // inp_q
1167 45880 : v_multc_fixed( Chnl_ImagBuffer_fx[0], hMcMasa->chnlToFoaEvenMtx_fx[3][0], FoaEven_ImagBuffer_fx[3], num_freq_bins ); // inp_q
1168 258980 : FOR( i = 1; i < numAnalysisChannels; i++ )
1169 : {
1170 213100 : v_multc_acc_32_32( Chnl_RealBuffer_fx[i], hMcMasa->chnlToFoaEvenMtx_fx[3][i], FoaEven_RealBuffer_fx[3], num_freq_bins ); // inp_q
1171 213100 : 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 45880 : computeIntensityVector_enc_fx(
1176 45880 : 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 45880 : 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 45880 : computeIntensityVector_enc_fx(
1199 45880 : 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 45880 : computeReferencePower_enc_fx(
1209 45880 : hMcMasa->band_grouping,
1210 : FoaEven_RealBuffer_fx,
1211 : FoaEven_ImagBuffer_fx,
1212 45880 : 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 45880 : minimum_fx( q_intensity_real_fx, num_freq_bands, &c_e );
1222 45880 : minimum_fx( q_intensity_even_real_fx, num_freq_bands, &shift );
1223 45880 : minimum_fx( q_reference_power_fx, num_freq_bands, &ref_e );
1224 :
1225 : Word16 tmp;
1226 275280 : FOR( i = 0; i < num_freq_bands; i++ )
1227 : {
1228 229400 : tmp = sub( c_e, q_intensity_real_fx[i] );
1229 229400 : intensity_real_fx[0][i] = L_shl( intensity_real_fx[0][i], tmp );
1230 229400 : move32();
1231 229400 : intensity_real_fx[1][i] = L_shl( intensity_real_fx[1][i], tmp );
1232 229400 : move32();
1233 229400 : intensity_real_fx[2][i] = L_shl( intensity_real_fx[2][i], tmp );
1234 229400 : move32();
1235 :
1236 229400 : tmp = sub( shift, q_intensity_even_real_fx[i] );
1237 229400 : intensity_even_real_fx[0][i] = L_shl( intensity_even_real_fx[0][i], tmp );
1238 229400 : move32();
1239 229400 : intensity_even_real_fx[1][i] = L_shl( intensity_even_real_fx[1][i], tmp );
1240 229400 : move32();
1241 229400 : intensity_even_real_fx[2][i] = L_shl( intensity_even_real_fx[2][i], tmp );
1242 229400 : move32();
1243 :
1244 229400 : tmp = sub( ref_e, q_reference_power_fx[i] );
1245 229400 : reference_power_fx[ts][i] = L_shl( reference_power_fx[ts][i], tmp );
1246 229400 : move32();
1247 : }
1248 :
1249 45880 : c_e = sub( Q31, c_e );
1250 45880 : shift = sub( Q31, shift );
1251 45880 : ref_e = sub( Q31, ref_e );
1252 :
1253 : /* Fill buffers of length "averaging_length" time slots for intensity and energy */
1254 45880 : hMcMasa->index_buffer_intensity = add( ( hMcMasa->index_buffer_intensity % hMcMasa->no_col_avg_diff ), 1 ); /* averaging_length = 32 */
1255 45880 : move16();
1256 45880 : index = hMcMasa->index_buffer_intensity;
1257 45880 : move16();
1258 183520 : FOR( i = 0; i < DIRAC_NUM_DIMS; i++ )
1259 : {
1260 : /* only real part needed */
1261 137640 : 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 45880 : hMcMasa->buffer_intensity_real_q[index - 1] = sub( 31, shift );
1264 45880 : move16();
1265 45880 : Copy32( reference_power_fx[ts], &( hMcMasa->buffer_energy_fx[( index - 1 ) * num_freq_bands] ), num_freq_bands ); // ref_e
1266 45880 : hMcMasa->buffer_energy_q[index - 1] = sub( Q31, ref_e );
1267 45880 : move16();
1268 :
1269 45880 : computeDiffuseness_mdft_fx( hMcMasa->buffer_intensity_real_fx, hMcMasa->buffer_energy_fx, num_freq_bands, hMcMasa->no_col_avg_diff, diffuseness_vector_fx, hMcMasa->buffer_intensity_real_q, hMcMasa->buffer_energy_q, &out_exp[0] );
1270 229400 : FOR( i = 1; i < num_freq_bands; i++ )
1271 : {
1272 183520 : out_exp[i] = out_exp[0];
1273 183520 : move16();
1274 : }
1275 : /* Compute vertical diffuseness, and tune original diffuseness if needed */
1276 45880 : 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 275280 : FOR( band_m_idx = 0; band_m_idx < hMcMasa->nbands; band_m_idx++ )
1286 : {
1287 229400 : norm_tmp_fx = Mult_32_32( reference_power_fx[ts][band_m_idx], L_sub( ONE_IN_Q31, diffuseness_vector_fx[band_m_idx] ) ); /*31-ref_e*/
1288 229400 : hMcMasa->direction_vector_m_fx[0][block_m_idx][band_m_idx] = BASOP_Util_Add_Mant32Exp( hMcMasa->direction_vector_m_fx[0][block_m_idx][band_m_idx], hMcMasa->direction_vector_e[0][block_m_idx][band_m_idx], Mult_32_32( norm_tmp_fx, direction_vector_fx[0][band_m_idx] ), add( 1, ref_e ), &hMcMasa->direction_vector_e[0][block_m_idx][band_m_idx] );
1289 229400 : move32();
1290 229400 : hMcMasa->direction_vector_m_fx[1][block_m_idx][band_m_idx] = BASOP_Util_Add_Mant32Exp( hMcMasa->direction_vector_m_fx[1][block_m_idx][band_m_idx], hMcMasa->direction_vector_e[1][block_m_idx][band_m_idx], Mult_32_32( norm_tmp_fx, direction_vector_fx[1][band_m_idx] ), add( 1, ref_e ), &hMcMasa->direction_vector_e[1][block_m_idx][band_m_idx] );
1291 229400 : move32();
1292 229400 : hMcMasa->direction_vector_m_fx[2][block_m_idx][band_m_idx] = BASOP_Util_Add_Mant32Exp( hMcMasa->direction_vector_m_fx[2][block_m_idx][band_m_idx], hMcMasa->direction_vector_e[2][block_m_idx][band_m_idx], Mult_32_32( norm_tmp_fx, direction_vector_fx[2][band_m_idx] ), add( 1, ref_e ), &hMcMasa->direction_vector_e[2][block_m_idx][band_m_idx] );
1293 229400 : move32();
1294 229400 : IF( hMcMasa->combineRatios )
1295 : {
1296 229400 : diffuseness_m_fx[0][band_m_idx] = BASOP_Util_Add_Mant32Exp( diffuseness_m_fx[0][band_m_idx], diffuseness_e[0][band_m_idx], Mult_32_32( reference_power_fx[ts][band_m_idx], diffuseness_vector_fx[band_m_idx] ), ref_e, &diffuseness_e[0][band_m_idx] );
1297 229400 : move32();
1298 229400 : renormalization_factor_diff_fx[band_m_idx] = BASOP_Util_Add_Mant32Exp( renormalization_factor_diff_fx[band_m_idx], renormalization_factor_diff_e[band_m_idx], reference_power_fx[ts][band_m_idx], ref_e, &renormalization_factor_diff_e[band_m_idx] );
1299 229400 : 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 275280 : FOR( band_m_idx = 0; band_m_idx < hMcMasa->nbands; band_m_idx++ )
1312 : {
1313 229400 : Word16 max_e = MIN_16;
1314 229400 : move16();
1315 917600 : FOR( d = 0; d < DIRAC_NUM_DIMS; d++ )
1316 : {
1317 688200 : max_e = s_max( max_e, hMcMasa->direction_vector_e[d][block_m_idx][band_m_idx] );
1318 : }
1319 229400 : max_e = add( max_e, 1 ); /*1 as guard bit to prevent overflow*/
1320 917600 : FOR( d = 0; d < DIRAC_NUM_DIMS; d++ )
1321 : {
1322 688200 : dir_v_fx[d] = L_shr( hMcMasa->direction_vector_m_fx[d][block_m_idx][band_m_idx], sub( max_e, hMcMasa->direction_vector_e[d][block_m_idx][band_m_idx] ) );
1323 688200 : move32();
1324 : }
1325 229400 : Word16 div_q = sub( 31, max_e );
1326 229400 : ivas_qmetadata_direction_vector_to_azimuth_elevation_fx( dir_v_fx, div_q, &azimuth_m_values_fx[block_m_idx][band_m_idx], &elevation_m_values_fx[block_m_idx][band_m_idx] );
1327 : }
1328 :
1329 : /* Coherence processing */
1330 275280 : FOR( band_m_idx = 0; band_m_idx < hMcMasa->nbands; band_m_idx++ )
1331 : {
1332 : /* Compute absolute values */
1333 1524300 : FOR( i = 0; i < numAnalysisChannels; i++ )
1334 : {
1335 5913000 : FOR( j = i; j < numAnalysisChannels; j++ )
1336 : {
1337 4618100 : Word32 temp = BASOP_Util_Add_Mant32Exp( Mult_32_32( COVls[band_m_idx].xr_fx[i][j], COVls[band_m_idx].xr_fx[i][j] ), shl( COVls[band_m_idx].xr_e[i][j], 1 ), Mult_32_32( COVls[band_m_idx].xi_fx[i][j], COVls[band_m_idx].xi_fx[i][j] ), shl( COVls[band_m_idx].xi_e[i][j], 1 ), &absCOVls_e[i][j] );
1338 4618100 : absCOVls_fx[i][j] = Sqrt32( temp, &absCOVls_e[i][j] );
1339 4618100 : move32();
1340 : }
1341 1294900 : lsEnergy_fx[i] = absCOVls_fx[i][i];
1342 1294900 : move32();
1343 1294900 : lsEnergy_e[i] = absCOVls_e[i][i];
1344 1294900 : move16();
1345 : }
1346 :
1347 : /* Find loudest channel */
1348 229400 : maxEne_fx = lsEnergy_fx[0];
1349 229400 : move32();
1350 229400 : maxEne_e = lsEnergy_e[0];
1351 229400 : move16();
1352 229400 : loudestCh = 0;
1353 229400 : move16();
1354 1294900 : FOR( i = 1; i < numAnalysisChannels; i++ )
1355 : {
1356 1065500 : IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( lsEnergy_fx[i], lsEnergy_e[i], maxEne_fx, maxEne_e ), 1 ) )
1357 : {
1358 349831 : maxEne_fx = lsEnergy_fx[i];
1359 349831 : move32();
1360 349831 : maxEne_e = lsEnergy_e[i];
1361 349831 : move16();
1362 349831 : loudestCh = i;
1363 349831 : move16();
1364 : }
1365 : }
1366 :
1367 : /* Compute surrounding coherence */
1368 229400 : surrCoh_fx = ONE_IN_Q31;
1369 229400 : move32();
1370 229400 : surrCoh_e = 0;
1371 229400 : move16();
1372 1524300 : FOR( i = 0; i < numAnalysisChannels; i++ )
1373 : {
1374 1294900 : IF( NE_16( i, loudestCh ) )
1375 : {
1376 1065500 : IF( LT_16( i, loudestCh ) )
1377 : {
1378 656098 : i1 = i;
1379 656098 : move16();
1380 656098 : i2 = loudestCh;
1381 656098 : move16();
1382 : }
1383 : ELSE
1384 : {
1385 409402 : i1 = loudestCh;
1386 409402 : move16();
1387 409402 : i2 = i;
1388 409402 : move16();
1389 : }
1390 1065500 : Word16 temp_exp = add( lsEnergy_e[i1], lsEnergy_e[i2] );
1391 1065500 : Word32 temp = Sqrt32( L_add( Mult_32_32( lsEnergy_fx[i1], lsEnergy_fx[i2] ), EPSILON_FX ), &temp_exp );
1392 1065500 : tempCoh_e = 0;
1393 1065500 : move16();
1394 1065500 : tempCoh_fx = L_shl( BASOP_Util_Divide3232_Scale( absCOVls_fx[i1][i2], temp, &tempCoh_e ), 16 );
1395 1065500 : tempCoh_e = add( sub( absCOVls_e[i1][i2], temp_exp ), tempCoh_e );
1396 1065500 : IF( NE_16( BASOP_Util_Cmp_Mant32Exp( surrCoh_fx, surrCoh_e, tempCoh_fx, tempCoh_e ), -1 ) )
1397 : {
1398 453599 : surrCoh_fx = tempCoh_fx;
1399 453599 : move32();
1400 453599 : surrCoh_e = tempCoh_e;
1401 453599 : move16();
1402 : }
1403 : }
1404 : }
1405 229400 : surrCoh_fx = L_shl( surrCoh_fx, surrCoh_e ); // Q31
1406 229400 : surrCoh_e = 0;
1407 229400 : move16();
1408 229400 : surrCoh_fx = Mult_32_32( surrCoh_fx, surrCoh_fx );
1409 229400 : IF( GE_32( surrCoh_fx, ONE_IN_Q31 ) )
1410 : {
1411 0 : surrCoh_fx = ONE_IN_Q31;
1412 0 : move32();
1413 : }
1414 229400 : surrCoh_fx = L_max( surrCoh_fx, 0 );
1415 :
1416 : /* Compute spread coherence */
1417 229400 : 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 203236 : minAngleDist_fx = 754974720; /*180.0f Q.22*/
1420 203236 : move32();
1421 203236 : i1 = 0;
1422 203236 : move16();
1423 203236 : currentAzi_fx = azimuth_m_values_fx[block_m_idx][band_m_idx];
1424 203236 : move32();
1425 1227951 : FOR( i = 0; i < hMcMasa->numHorizontalChannels; i++ )
1426 : {
1427 1024715 : angleDist_fx = L_abs( L_sub( currentAzi_fx, hMcMasa->ls_azimuth_fx[i] ) );
1428 1024715 : IF( GT_32( angleDist_fx, 754974720 /*180.0f Q.22*/ ) )
1429 : {
1430 7687 : angleDist_fx = L_abs( L_sub( angleDist_fx, 1509949440 /*360.0f Q.22*/ ) );
1431 : }
1432 1024715 : IF( LT_32( angleDist_fx, minAngleDist_fx ) )
1433 : {
1434 450307 : minAngleDist_fx = angleDist_fx;
1435 450307 : move32();
1436 450307 : i1 = i;
1437 450307 : move16();
1438 : }
1439 : }
1440 203236 : i2 = hMcMasa->leftNearest[i1];
1441 203236 : move16();
1442 203236 : i3 = hMcMasa->rightNearest[i1];
1443 203236 : move16();
1444 203236 : Word16 temp_e = add( lsEnergy_e[i2], lsEnergy_e[i3] );
1445 203236 : Word32 temp = Sqrt32( L_add( Mult_32_32( lsEnergy_fx[i2], lsEnergy_fx[i3] ), EPSILON_FX ), &temp_e );
1446 203236 : IF( LT_16( i2, i3 ) )
1447 : {
1448 182683 : stereoCoh_fx = BASOP_Util_Divide3232_Scale( absCOVls_fx[i2][i3], temp, &stereoCoh_e );
1449 182683 : stereoCoh_e = add( sub( absCOVls_e[i2][i3], temp_e ), stereoCoh_e );
1450 : }
1451 : ELSE
1452 : {
1453 20553 : stereoCoh_fx = BASOP_Util_Divide3232_Scale( absCOVls_fx[i3][i2], temp, &stereoCoh_e );
1454 20553 : stereoCoh_e = add( sub( absCOVls_e[i3][i2], temp_e ), stereoCoh_e );
1455 : }
1456 203236 : stereoCoh_fx = L_shl( stereoCoh_fx, 16 );
1457 : Word32 temp1, temp2;
1458 : Word16 temp1_e, temp2_e;
1459 203236 : temp1 = BASOP_Util_Add_Mant32Exp( lsEnergy_fx[i2], lsEnergy_e[i2], lsEnergy_fx[i3], lsEnergy_e[i3], &temp1_e );
1460 203236 : temp2 = BASOP_Util_Add_Mant32Exp( temp1, temp1_e, lsEnergy_fx[i1], lsEnergy_e[i1], &temp2_e );
1461 203236 : temp2 = L_add( temp2, EPSILON_FX );
1462 203236 : lsEnergyRelation_fx = BASOP_Util_Divide3232_Scale( temp1, temp2, &lsEnergyRelation_e );
1463 203236 : lsEnergyRelation_e = add( lsEnergyRelation_e, sub( temp1_e, temp2_e ) );
1464 203236 : lsEnergyRelation_fx = L_shl_sat( lsEnergyRelation_fx, add( 16, lsEnergyRelation_e ) );
1465 203236 : stereoness_fx = Mult_32_32( stereoCoh_fx, lsEnergyRelation_fx );
1466 203236 : stereoness_e = stereoCoh_e;
1467 203236 : move16();
1468 :
1469 203236 : IF( LT_16( i1, i2 ) )
1470 : {
1471 90017 : temp_e = add( lsEnergy_e[i1], lsEnergy_e[i2] );
1472 90017 : 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 90017 : tempCoh_e = add( tempCoh_e, sub( absCOVls_e[i1][i2], temp_e ) );
1474 : }
1475 : ELSE
1476 : {
1477 113219 : temp_e = add( lsEnergy_e[i1], lsEnergy_e[i2] );
1478 113219 : 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 113219 : tempCoh_e = add( tempCoh_e, sub( absCOVls_e[i2][i1], temp_e ) );
1480 : }
1481 203236 : tempCoh_fx = L_shl( tempCoh_fx, 16 );
1482 203236 : IF( LT_16( i1, i3 ) )
1483 : {
1484 89986 : temp_e = add( lsEnergy_e[i1], lsEnergy_e[i3] );
1485 89986 : 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 89986 : tempCoh2_e = add( tempCoh2_e, sub( absCOVls_e[i1][i3], temp_e ) );
1487 : }
1488 : ELSE
1489 : {
1490 113250 : temp_e = add( lsEnergy_e[i1], lsEnergy_e[i3] );
1491 113250 : 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 113250 : tempCoh2_e = add( tempCoh2_e, sub( absCOVls_e[i3][i1], temp_e ) );
1493 : }
1494 203236 : tempCoh2_fx = L_shl( tempCoh2_fx, 16 );
1495 203236 : IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( tempCoh_fx, tempCoh_e, tempCoh2_fx, tempCoh2_e ), -1 ) )
1496 : {
1497 105321 : cohPanCoh_fx = tempCoh_fx;
1498 105321 : move32();
1499 105321 : cohPanCoh_e = tempCoh_e;
1500 105321 : move16();
1501 : }
1502 : ELSE
1503 : {
1504 97915 : cohPanCoh_fx = tempCoh2_fx;
1505 97915 : move32();
1506 97915 : cohPanCoh_e = tempCoh2_e;
1507 97915 : move16();
1508 : }
1509 : /* IF( GT_32( cohPanCoh_fx, ONE_IN_Q30 ) )
1510 : {
1511 : cohPanCoh_fx = ONE_IN_Q30;
1512 : move32();
1513 : }*/
1514 203236 : cohPanCoh_fx = L_shl_sat( cohPanCoh_fx, cohPanCoh_e ); /*Q31*/
1515 203236 : cohPanCoh_e = 0;
1516 203236 : move16();
1517 203236 : lsEnergyRelation_fx = BASOP_Util_Divide3232_Scale( lsEnergy_fx[i2], L_add( lsEnergy_fx[i1], EPSILON_FX ), &lsEnergyRelation_e );
1518 203236 : lsEnergyRelation_e = add( lsEnergyRelation_e, sub( lsEnergy_e[i2], lsEnergy_e[i1] ) );
1519 203236 : tempLsEnergyRelation_fx = BASOP_Util_Divide3232_Scale( lsEnergy_fx[i1], L_add( lsEnergy_fx[i2], EPSILON_FX ), &tempLsEnergyRelation_e );
1520 203236 : tempLsEnergyRelation_e = add( tempLsEnergyRelation_e, sub( lsEnergy_e[i1], lsEnergy_e[i2] ) );
1521 203236 : IF( NE_16( BASOP_Util_Cmp_Mant32Exp( lsEnergyRelation_fx, lsEnergyRelation_e, tempLsEnergyRelation_fx, tempLsEnergyRelation_e ), -1 ) )
1522 : {
1523 108336 : lsEnergyRelation_fx = tempLsEnergyRelation_fx;
1524 108336 : move32();
1525 108336 : lsEnergyRelation_e = tempLsEnergyRelation_e;
1526 108336 : move16();
1527 : }
1528 203236 : tempLsEnergyRelation_fx = BASOP_Util_Divide3232_Scale( lsEnergy_fx[i3], L_add( lsEnergy_fx[i1], EPSILON_FX ), &tempLsEnergyRelation_e );
1529 203236 : tempLsEnergyRelation_e = add( tempLsEnergyRelation_e, sub( lsEnergy_e[i3], lsEnergy_e[i1] ) );
1530 203236 : IF( NE_16( BASOP_Util_Cmp_Mant32Exp( lsEnergyRelation_fx, lsEnergyRelation_e, tempLsEnergyRelation_fx, tempLsEnergyRelation_e ), -1 ) )
1531 : {
1532 22540 : lsEnergyRelation_fx = tempLsEnergyRelation_fx;
1533 22540 : move32();
1534 22540 : lsEnergyRelation_e = tempLsEnergyRelation_e;
1535 22540 : move16();
1536 : }
1537 203236 : tempLsEnergyRelation_fx = BASOP_Util_Divide3232_Scale( lsEnergy_fx[i1], L_add( lsEnergy_fx[i3], EPSILON_FX ), &tempLsEnergyRelation_e );
1538 203236 : tempLsEnergyRelation_e = add( tempLsEnergyRelation_e, sub( lsEnergy_e[i1], lsEnergy_e[i3] ) );
1539 203236 : IF( NE_16( BASOP_Util_Cmp_Mant32Exp( lsEnergyRelation_fx, lsEnergyRelation_e, tempLsEnergyRelation_fx, tempLsEnergyRelation_e ), -1 ) )
1540 : {
1541 64071 : lsEnergyRelation_fx = tempLsEnergyRelation_fx;
1542 64071 : move32();
1543 64071 : lsEnergyRelation_e = tempLsEnergyRelation_e;
1544 64071 : move16();
1545 : }
1546 203236 : lsEnergyRelation_fx = L_shl_sat( lsEnergyRelation_fx, add( 16, lsEnergyRelation_e ) ); /*Q31*/
1547 203236 : cohwideness_fx = Mult_32_32( cohPanCoh_fx, lsEnergyRelation_fx );
1548 203236 : IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( cohwideness_fx, cohPanCoh_e, stereoness_fx, stereoness_e ), 1 ) )
1549 : {
1550 31335 : spreadCoh_fx = cohwideness_fx;
1551 31335 : move32();
1552 31335 : spreadCoh_e = cohPanCoh_e;
1553 31335 : move16();
1554 : }
1555 : ELSE
1556 : {
1557 171901 : spreadCoh_fx = stereoness_fx;
1558 171901 : move32();
1559 171901 : spreadCoh_e = stereoness_e;
1560 171901 : move16();
1561 : }
1562 203236 : IF( ( spreadCoh_e < 0 ) )
1563 : {
1564 5362 : spreadCoh_fx = L_shl( spreadCoh_fx, spreadCoh_e );
1565 5362 : spreadCoh_e = 0;
1566 5362 : move16();
1567 : }
1568 203236 : IF( GT_32( spreadCoh_fx, L_shl_sat( 1, sub( 30, spreadCoh_e ) /*0.5f with exp=spreadCoh_e*/ ) ) )
1569 : {
1570 130440 : IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( cohwideness_fx, cohPanCoh_e, stereoness_fx, stereoness_e ), 1 ) )
1571 : {
1572 21890 : 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 21890 : IF( ( tempCoh_e < 0 ) )
1574 : {
1575 21890 : tempCoh_fx = L_shl( tempCoh_fx, tempCoh_e ); // Q31
1576 21890 : tempCoh_e = 0;
1577 21890 : move16();
1578 : }
1579 21890 : 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 21890 : spreadCoh_fx = L_shl_sat( 1, sub( 30, tempCoh_e ) ); // Q30
1587 : }
1588 21890 : spreadCoh_e = tempCoh_e;
1589 21890 : move16();
1590 : }
1591 : }
1592 203236 : 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 203236 : 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 203236 : IF( ( spreadCoh_fx <= 0 ) )
1604 : {
1605 1385 : spreadCoh_fx = 0;
1606 1385 : move32();
1607 : }
1608 203236 : spreadCoh_fx = L_shl( spreadCoh_fx, sub( spreadCoh_e, 1 ) ); /*Q30*/
1609 :
1610 : /* Compute energy ratio tuning parameter */
1611 203236 : lsEnergySum_fx = 0;
1612 203236 : move32();
1613 203236 : lsEnergySum_e = 0;
1614 203236 : move16();
1615 1241493 : FOR( i = 0; i < numAnalysisChannels; i++ )
1616 : {
1617 1038257 : lsEnergySum_fx = BASOP_Util_Add_Mant32Exp( lsEnergy_fx[i], lsEnergy_e[i], lsEnergySum_fx, lsEnergySum_e, &lsEnergySum_e );
1618 : }
1619 203236 : lsEnergySum_fx = L_add_sat( lsEnergySum_fx, EPSILON_FX );
1620 203236 : lsEnergyRelation_fx = BASOP_Util_Divide3232_Scale( temp1, lsEnergySum_fx, &lsEnergyRelation_e );
1621 203236 : lsEnergyRelation_e = add( lsEnergyRelation_e, sub( temp1_e, lsEnergySum_e ) );
1622 203236 : lsEnergyRelation_fx = L_shl_sat( lsEnergyRelation_fx, add( 16, lsEnergyRelation_e ) ); // Q31
1623 203236 : stereoRatio_fx = L_sub( Mult_32_32( L_shl_sat( stereoCoh_fx, stereoCoh_e ), lsEnergyRelation_fx ), surrCoh_fx ); // Q31
1624 :
1625 203236 : temp2 = L_sub( temp2, EPSILLON_FX );
1626 203236 : lsEnergyRelation_fx = BASOP_Util_Divide3232_Scale( temp2, lsEnergySum_fx, &lsEnergyRelation_e );
1627 203236 : lsEnergyRelation_e = add( lsEnergyRelation_e, sub( temp2_e, lsEnergySum_e ) );
1628 203236 : lsEnergyRelation_fx = L_shl_sat( lsEnergyRelation_fx, add( 16, lsEnergyRelation_e ) ); // Q31
1629 203236 : cohPanRatio_fx = L_sub( Mult_32_32( cohPanCoh_fx, lsEnergyRelation_fx ), surrCoh_fx ); // Q31
1630 203236 : IF( GT_32( stereoRatio_fx, cohPanRatio_fx ) )
1631 : {
1632 4011 : cohRatio_fx = stereoRatio_fx;
1633 4011 : move32();
1634 : }
1635 : ELSE
1636 : {
1637 199225 : cohRatio_fx = cohPanRatio_fx;
1638 199225 : move32();
1639 : }
1640 :
1641 203236 : IF( GE_32( cohRatio_fx, ONE_IN_Q31 ) )
1642 : {
1643 0 : cohRatio_fx = ONE_IN_Q31; // Q31
1644 0 : move32();
1645 : }
1646 203236 : IF( cohRatio_fx <= 0 )
1647 : {
1648 93228 : cohRatio_fx = 0;
1649 93228 : 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 229400 : spreadCoherence_fx[block_m_idx][band_m_idx] = spreadCoh_fx; /*Q30*/
1669 229400 : move32();
1670 :
1671 229400 : IF( hMcMasa->combineRatios )
1672 : {
1673 229400 : surroundingCoherence_fx[0][band_m_idx] = BASOP_Util_Add_Mant32Exp( surroundingCoherence_fx[0][band_m_idx], surroundingCoherence_e[0][band_m_idx], Mult_32_32( lsEnergySum_fx, surrCoh_fx ), lsEnergySum_e, &surroundingCoherence_e[0][band_m_idx] );
1674 229400 : move32();
1675 229400 : coherentEnergyRatio_fx[0][band_m_idx] = BASOP_Util_Add_Mant32Exp( coherentEnergyRatio_fx[0][band_m_idx], coherentEnergyRatio_e[0][band_m_idx], Mult_32_32( lsEnergySum_fx, cohRatio_fx ), lsEnergySum_e, &coherentEnergyRatio_e[0][band_m_idx] );
1676 229400 : move32();
1677 229400 : renormalization_factor_coh_fx[band_m_idx] = BASOP_Util_Add_Mant32Exp( renormalization_factor_coh_fx[band_m_idx], renormalization_factor_coh_e[band_m_idx], lsEnergySum_fx, lsEnergySum_e, &renormalization_factor_coh_e[band_m_idx] );
1678 229400 : 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 11470 : IF( hMcMasa->combineRatios )
1691 : {
1692 68820 : FOR( band_m_idx = 0; band_m_idx < hMcMasa->nbands; band_m_idx++ )
1693 : {
1694 : Word16 diffuseness_m_e;
1695 57350 : IF( GT_32( renormalization_factor_diff_fx[band_m_idx], EPSILON_FX ) )
1696 : {
1697 57350 : diffuseness_m_fx[0][band_m_idx] = BASOP_Util_Divide3232_Scale( diffuseness_m_fx[0][band_m_idx], renormalization_factor_diff_fx[band_m_idx], &diffuseness_m_e );
1698 57350 : move32();
1699 57350 : diffuseness_m_e = add( diffuseness_m_e, sub( diffuseness_e[0][band_m_idx], renormalization_factor_diff_e[band_m_idx] ) );
1700 57350 : diffuseness_m_fx[0][band_m_idx] = L_shl_sat( diffuseness_m_fx[0][band_m_idx], add( 16, diffuseness_m_e ) ); // Q(31 - diffuseness_m_e) -> Q31
1701 57350 : move32();
1702 : }
1703 : ELSE
1704 : {
1705 0 : diffuseness_m_fx[0][band_m_idx] = 0;
1706 0 : move32();
1707 : }
1708 57350 : IF( GT_32( renormalization_factor_coh_fx[band_m_idx], EPSILON_FX ) )
1709 : {
1710 57350 : Word16 cer_e = 31, sc_e = 31;
1711 57350 : move16();
1712 57350 : move16();
1713 57350 : surroundingCoherence_fx[0][band_m_idx] = BASOP_Util_Divide3232_Scale( surroundingCoherence_fx[0][band_m_idx], renormalization_factor_coh_fx[band_m_idx], &sc_e );
1714 57350 : move32();
1715 57350 : sc_e = add( sc_e, sub( surroundingCoherence_e[0][band_m_idx], renormalization_factor_coh_e[band_m_idx] ) );
1716 57350 : surroundingCoherence_fx[0][band_m_idx] = L_shl_sat( surroundingCoherence_fx[0][band_m_idx], add( 16, sc_e ) ); // Q(31 - sc_e) -> Q31
1717 57350 : move32();
1718 57350 : coherentEnergyRatio_fx[0][band_m_idx] = BASOP_Util_Divide3232_Scale( coherentEnergyRatio_fx[0][band_m_idx], renormalization_factor_coh_fx[band_m_idx], &cer_e );
1719 57350 : move32();
1720 57350 : cer_e = add( cer_e, sub( coherentEnergyRatio_e[0][band_m_idx], renormalization_factor_coh_e[band_m_idx] ) );
1721 57350 : coherentEnergyRatio_fx[0][band_m_idx] = L_shl_sat( coherentEnergyRatio_fx[0][band_m_idx], add( 16, cer_e ) ); // Q(31 - cer_e) -> Q31
1722 57350 : 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 11470 : IF( hMcMasa->combineRatios )
1736 : {
1737 11470 : numSubFramesForRatio = 1;
1738 11470 : move16();
1739 : }
1740 : ELSE
1741 : {
1742 0 : numSubFramesForRatio = MAX_PARAM_SPATIAL_SUBFRAMES;
1743 0 : move16();
1744 : }
1745 :
1746 22940 : FOR( i = 0; i < numSubFramesForRatio; i++ )
1747 : {
1748 68820 : FOR( j = 0; j < hMcMasa->nbands; j++ )
1749 : {
1750 57350 : energyRatio_fx[i][j] = L_sub( ONE_IN_Q31, diffuseness_m_fx[i][j] ); // Q31
1751 57350 : move32();
1752 57350 : IF( GT_32( energyRatio_fx[i][j], coherentEnergyRatio_fx[i][j] ) )
1753 : {
1754 53654 : energyRatio_fx[i][j] = energyRatio_fx[i][j];
1755 53654 : move32();
1756 : }
1757 : ELSE
1758 : {
1759 3696 : energyRatio_fx[i][j] = coherentEnergyRatio_fx[i][j]; // Q31
1760 3696 : move32();
1761 : }
1762 : }
1763 : }
1764 :
1765 11470 : 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 11470 : 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 11470 : Word16 multiChEne_e, scale, downmixEne_e = 0, prevEQ_e, tmp, currEQ_e, instEQ_e;
1944 11470 : move16();
1945 :
1946 11470 : numAnalysisChannels = sub( nchan_inp, 1 );
1947 11470 : IF( hMcMasa->separateChannelEnabled )
1948 : {
1949 625 : numAnalysisChannels = sub( nchan_inp, 2 );
1950 : }
1951 :
1952 11470 : multiChEne_fx = 0;
1953 11470 : move32();
1954 11470 : multiChEne_e = 0;
1955 11470 : move16();
1956 76215 : FOR( j = 0; j < numAnalysisChannels; j++ )
1957 : {
1958 61899945 : FOR( i = 0; i < input_frame; i++ )
1959 : {
1960 61835200 : L_tmp1 = BASOP_Util_Add_Mant32Exp( data_fx[j][i], data_e, 0, 0, &scale );
1961 61835200 : L_tmp = Mpy_32_32( L_tmp1, L_tmp1 ); // data_e + data_e
1962 61835200 : multiChEne_fx = BASOP_Util_Add_Mant32Exp( L_tmp, scale + scale, multiChEne_fx, multiChEne_e, &scale );
1963 61835200 : multiChEne_e = scale;
1964 61835200 : move16();
1965 : }
1966 : }
1967 :
1968 11470 : IF( EQ_16( nchan_transport, 2 ) )
1969 : {
1970 : Word16 numSideChannels; /* Channels other than left, right, center */
1971 : Word16 leftIndex, rightIndex;
1972 :
1973 1045 : numSideChannels = sub( shr( numAnalysisChannels, 1 ), 1 );
1974 5045 : FOR( j = 0; j < numSideChannels; j++ )
1975 : {
1976 4000 : IF( hMcMasa->separateChannelEnabled )
1977 : {
1978 2480 : leftIndex = add( shl( j, 1 ), 2 );
1979 2480 : rightIndex = add( shl( j, 1 ), 3 );
1980 : }
1981 : ELSE
1982 : {
1983 1520 : leftIndex = add( shl( j, 1 ), 3 );
1984 1520 : rightIndex = add( shl( j, 1 ), 4 );
1985 : }
1986 :
1987 3844000 : FOR( i = 0; i < input_frame; i++ )
1988 : {
1989 3840000 : data_fx[0][i] = L_add( data_fx[0][i], data_fx[leftIndex][i] ); // data_e
1990 3840000 : move32();
1991 3840000 : data_fx[1][i] = L_add( data_fx[1][i], data_fx[rightIndex][i] );
1992 3840000 : move32();
1993 : }
1994 : }
1995 :
1996 1045 : IF( !hMcMasa->separateChannelEnabled )
1997 : {
1998 403620 : FOR( i = 0; i < input_frame; i++ )
1999 : {
2000 403200 : dmx_c_fx = W_extract_h( W_mult_32_32( INV_SQRT2_FX, data_fx[2][i] ) );
2001 403200 : move32();
2002 403200 : data_fx[0][i] = L_add( dmx_c_fx, data_fx[0][i] ); // data_e
2003 403200 : move32();
2004 403200 : data_fx[1][i] = L_add( dmx_c_fx, data_fx[1][i] ); // data_e
2005 403200 : move32();
2006 : }
2007 : }
2008 : }
2009 10425 : ELSE IF( EQ_16( nchan_transport, 1 ) )
2010 : {
2011 9954425 : FOR( i = 0; i < input_frame; i++ )
2012 : {
2013 51745600 : FOR( j = 1; j < numAnalysisChannels; j++ )
2014 : {
2015 41801600 : data_fx[0][i] = L_add( data_fx[0][i], data_fx[j][i] );
2016 41801600 : move32();
2017 : }
2018 : }
2019 : }
2020 11470 : downmixEne_fx = 0;
2021 11470 : move32();
2022 23985 : FOR( j = 0; j < nchan_transport; j++ )
2023 : {
2024 11962915 : FOR( i = 0; i < input_frame; i++ )
2025 : {
2026 11950400 : L_tmp1 = BASOP_Util_Add_Mant32Exp( data_fx[j][i], data_e, 0, 0, &scale );
2027 11950400 : L_tmp = Mpy_32_32( L_tmp1, L_tmp1 ); // data_e + data_e
2028 11950400 : downmixEne_fx = BASOP_Util_Add_Mant32Exp( L_tmp, scale + scale, downmixEne_fx, downmixEne_e, &downmixEne_e );
2029 : }
2030 : }
2031 :
2032 11470 : alpha_fx = 214748364; // 0.1 in Q31
2033 11470 : move32();
2034 :
2035 11470 : L_tmp = Mpy_32_32( alpha_fx, multiChEne_fx );
2036 11470 : L_tmp1 = Mpy_32_32( 1932735284 /* 0.9f in Q31 */, hMcMasa->prevMultiChEne_fx );
2037 11470 : hMcMasa->prevMultiChEne_fx = BASOP_Util_Add_Mant32Exp( L_tmp, multiChEne_e, L_tmp1, hMcMasa->prevMultiChEne_e, &hMcMasa->prevMultiChEne_e );
2038 11470 : move32();
2039 :
2040 11470 : L_tmp = Mpy_32_32( alpha_fx, downmixEne_fx );
2041 11470 : L_tmp1 = Mpy_32_32( 1932735284 /* 0.9f in Q31 */, hMcMasa->prevDownmixEne_fx );
2042 11470 : hMcMasa->prevDownmixEne_fx = BASOP_Util_Add_Mant32Exp( L_tmp, downmixEne_e, L_tmp1, hMcMasa->prevDownmixEne_e, &hMcMasa->prevDownmixEne_e );
2043 11470 : move32();
2044 :
2045 11470 : prevEQ_fx = hMcMasa->prevEQ_fx;
2046 11470 : move32();
2047 11470 : prevEQ_e = hMcMasa->prevEQ_e;
2048 11470 : move16();
2049 :
2050 11470 : tmp = BASOP_Util_Divide3232_Scale( hMcMasa->prevMultiChEne_fx, L_add( hMcMasa->prevDownmixEne_fx, EPSILON_FX ), &scale );
2051 11470 : currEQ_e = add( scale, sub( hMcMasa->prevMultiChEne_e, hMcMasa->prevDownmixEne_e ) );
2052 11470 : currEQ_fx = Sqrt32( L_deposit_h( tmp ), &currEQ_e );
2053 :
2054 11470 : hMcMasa->prevEQ_fx = currEQ_fx;
2055 11470 : move32();
2056 11470 : hMcMasa->prevEQ_e = currEQ_e;
2057 11470 : move16();
2058 :
2059 10958670 : FOR( i = 0; i < input_frame; i++ )
2060 : {
2061 10947200 : L_tmp = Mpy_32_32( L_deposit_h( hMcMasa->interpolator_fx[i] ), currEQ_fx );
2062 10947200 : L_tmp1 = L_sub( 1073741824 /* 1 in Q30 */, L_lshr( L_deposit_h( hMcMasa->interpolator_fx[i] ), 1 ) );
2063 10947200 : L_tmp1 = Mpy_32_32( L_tmp1, prevEQ_fx );
2064 10947200 : instEQ_fx = BASOP_Util_Add_Mant32Exp( L_tmp, currEQ_e, L_tmp1, add( prevEQ_e, 1 ), &instEQ_e );
2065 :
2066 22897600 : FOR( j = 0; j < nchan_transport; j++ )
2067 : {
2068 11950400 : data_fx[j][i] = Mpy_32_32( instEQ_fx, data_fx[j][i] ); // data_e + instEQ_e - 31
2069 11950400 : move32();
2070 11950400 : move32();
2071 11950400 : data_fx[j][i] = L_shl( data_fx[j][i], instEQ_e ); // data_e + 2*instEQ_e - 31
2072 : }
2073 : }
2074 :
2075 11470 : return;
2076 : }
2077 : /* Compute covariance matrix, i.e., xT * conj(x), and accumulate to the output */
2078 10947200 : static void compute_cov_mtx_fx(
2079 : Word32 sr[MCMASA_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX], /* i : Input matrix, real, s[ch][freq] (inp_exp) */
2080 : Word32 si[MCMASA_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX], /* i : Input matrix, imag, s[ch][freq] (inp_exp) */
2081 : const Word16 freq, /* i : Freq to process */
2082 : const Word16 N, /* i : Number of channels */
2083 : CovarianceMatrix *COVls, /* o : Output matrix, contains upper part of cov mtx */
2084 : Word16 inp_exp /*Stores exponent for temp*/
2085 : )
2086 : {
2087 : Word16 i, j;
2088 : #ifdef OPT_MCT_ENC_V1_NBE
2089 : Word64 temp64_1, temp64_2;
2090 : Word16 tmp_16, max_exp;
2091 10947200 : Word16 temp_exp = shl( inp_exp, 1 );
2092 72782400 : FOR( i = 0; i < N; i++ )
2093 : {
2094 282544000 : FOR( j = i; j < N; j++ )
2095 : {
2096 220708800 : 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
2097 220708800 : temp64_2 = W_deposit32_h( COVls->xr_fx[i][j] ); // exp:COVls->xr_e[i][j]
2098 220708800 : max_exp = s_max( COVls->xr_e[i][j], temp_exp );
2099 220708800 : temp64_2 = W_shl( temp64_2, sub( COVls->xr_e[i][j], max_exp ) ); // exp:max_exp
2100 220708800 : temp64_1 = W_shl( temp64_1, sub( temp_exp, max_exp ) ); // exp:max_exp
2101 220708800 : temp64_1 = W_add( temp64_1, temp64_2 ); // exp:max_exp
2102 220708800 : tmp_16 = W_norm( temp64_1 );
2103 :
2104 220708800 : COVls->xr_fx[i][j] = W_extract_h( W_shl( temp64_1, tmp_16 ) ); // exp:max_exp-tmp_16
2105 220708800 : COVls->xr_e[i][j] = sub( max_exp, tmp_16 );
2106 220708800 : move32();
2107 220708800 : move16();
2108 :
2109 220708800 : 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
2110 220708800 : temp64_2 = W_deposit32_h( COVls->xi_fx[i][j] ); // exp:COVls->xi_e[i][j]
2111 220708800 : max_exp = s_max( COVls->xi_e[i][j], temp_exp );
2112 220708800 : temp64_2 = W_shl( temp64_2, sub( COVls->xi_e[i][j], max_exp ) ); // exp:max_exp
2113 220708800 : temp64_1 = W_shl( temp64_1, sub( temp_exp, max_exp ) ); // exp:max_exp
2114 220708800 : temp64_1 = W_add( temp64_1, temp64_2 ); // exp:max_exp
2115 220708800 : tmp_16 = W_norm( temp64_1 );
2116 :
2117 220708800 : COVls->xi_fx[i][j] = W_extract_h( W_shl( temp64_1, tmp_16 ) ); // exp:max_exp-tmp_16
2118 220708800 : COVls->xi_e[i][j] = sub( max_exp, tmp_16 );
2119 220708800 : move32();
2120 : }
2121 : }
2122 : #else
2123 : Word32 a, b, c, d;
2124 : Word32 temp;
2125 : Word16 norm_a, norm_b, norm_c, norm_d;
2126 : Word16 shift;
2127 : FOR( i = 0; i < N; i++ )
2128 : {
2129 : a = sr[i][freq];
2130 : move32();
2131 : b = si[i][freq];
2132 : move32();
2133 : norm_a = norm_l( a );
2134 : norm_b = norm_l( b );
2135 : a = L_shl( a, norm_a ); /*inp_exp-norm_a*/
2136 : b = L_shl( b, norm_b ); /*inp_exp-norm_b*/
2137 : FOR( j = i; j < N; j++ )
2138 : {
2139 : c = sr[j][freq];
2140 : move32();
2141 : d = si[j][freq];
2142 : move32();
2143 : norm_c = norm_l( c );
2144 : norm_d = norm_l( d );
2145 : c = L_shl( c, norm_c ); /*inp_exp-norm_c*/
2146 : d = L_shl( d, norm_d ); /*inp_exp-norm_d*/
2147 : temp = BASOP_Util_Add_Mant32Exp( Mult_32_32( a, c ), sub( shl( inp_exp, 1 ), add( norm_a, norm_c ) ), Mult_32_32( b, d ), sub( shl( inp_exp, 1 ), add( norm_b, norm_d ) ), &shift ); /*exp=inp_exp-norm_ab+inp_exp-norm_cd*/
2148 : COVls->xr_fx[i][j] = BASOP_Util_Add_Mant32Exp( COVls->xr_fx[i][j], COVls->xr_e[i][j], temp, shift, &COVls->xr_e[i][j] );
2149 : move32();
2150 : temp = BASOP_Util_Add_Mant32Exp( Mult_32_32( b, c ), sub( shl( inp_exp, 1 ), add( norm_b, norm_c ) ), L_negate( Mult_32_32( a, d ) ), sub( shl( inp_exp, 1 ), add( norm_a, norm_d ) ), &shift );
2151 : COVls->xi_fx[i][j] = BASOP_Util_Add_Mant32Exp( COVls->xi_fx[i][j], COVls->xi_e[i][j], temp, shift, &COVls->xi_e[i][j] );
2152 : move32();
2153 : }
2154 : }
2155 : #endif
2156 10947200 : return;
2157 : }
2158 :
2159 91760 : static void computeIntensityVector_enc_fx(
2160 : const Word16 *band_grouping,
2161 : Word32 Cldfb_RealBuffer[FOA_CHANNELS][DIRAC_NO_FB_BANDS_MAX], /*inp_q*/
2162 : Word32 Cldfb_ImagBuffer[FOA_CHANNELS][DIRAC_NO_FB_BANDS_MAX], /*inp_q*/
2163 : const Word16 enc_param_start_band, /* i : first band to process */
2164 : const Word16 num_frequency_bands,
2165 : Word32 intensity_real[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS], /*exp: exp_intensity_real*/
2166 : Word16 q_intensity_real[MASA_FREQUENCY_BANDS],
2167 : Word16 inp_q )
2168 : {
2169 : Word16 i, j;
2170 : Word32 real, img;
2171 : Word16 brange[2];
2172 : Word16 shift_intensity_real, num_bins, guard_bits, norm;
2173 :
2174 : Word64 intensity_real64[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS];
2175 :
2176 367040 : FOR( i = 0; i < DIRAC_NUM_DIMS; i++ )
2177 : {
2178 275280 : set64_fx( intensity_real64[i], 0, MASA_FREQUENCY_BANDS );
2179 : }
2180 :
2181 91760 : shift_intensity_real = sub( shl( inp_q, 1 ), 32 );
2182 :
2183 550560 : FOR( i = enc_param_start_band; i < enc_param_start_band + num_frequency_bands; i++ )
2184 : {
2185 458800 : brange[0] = band_grouping[i];
2186 458800 : move16();
2187 458800 : brange[1] = band_grouping[i + 1];
2188 458800 : move16();
2189 :
2190 458800 : num_bins = sub( brange[1], brange[0] );
2191 458800 : guard_bits = find_guarded_bits_fx( num_bins );
2192 :
2193 458800 : intensity_real[0][i] = 0;
2194 458800 : move32();
2195 458800 : intensity_real[1][i] = 0;
2196 458800 : move32();
2197 458800 : intensity_real[2][i] = 0;
2198 458800 : move32();
2199 :
2200 22353200 : FOR( j = brange[0]; j < brange[1]; j++ )
2201 : {
2202 21894400 : real = Cldfb_RealBuffer[0][j];
2203 21894400 : move32();
2204 21894400 : img = Cldfb_ImagBuffer[0][j];
2205 21894400 : move32();
2206 : /* Intensity is XYZ order, audio is WYZX order. */
2207 21894400 : intensity_real64[0][i] = W_add( intensity_real64[0][i], W_shr( W_add( W_mult0_32_32( Cldfb_RealBuffer[3][j], real ), W_mult0_32_32( Cldfb_ImagBuffer[3][j], img ) ), guard_bits ) ); // output Q= 2* input_q - guard_bits
2208 21894400 : move32();
2209 21894400 : intensity_real64[1][i] = W_add( intensity_real64[1][i], W_shr( W_add( W_mult0_32_32( Cldfb_RealBuffer[1][j], real ), W_mult0_32_32( Cldfb_ImagBuffer[1][j], img ) ), guard_bits ) ); // output Q= 2* input_q - guard_bits
2210 21894400 : move32();
2211 21894400 : intensity_real64[2][i] = W_add( intensity_real64[2][i], W_shr( W_add( W_mult0_32_32( Cldfb_RealBuffer[2][j], real ), W_mult0_32_32( Cldfb_ImagBuffer[2][j], img ) ), guard_bits ) ); // output Q= 2* input_q - guard_bits
2212 21894400 : move32();
2213 : }
2214 :
2215 458800 : norm = 63;
2216 458800 : move16();
2217 458800 : IF( intensity_real64[0][i] != 0 )
2218 : {
2219 456030 : norm = s_min( norm, W_norm( intensity_real64[0][i] ) );
2220 : }
2221 458800 : IF( intensity_real64[1][i] != 0 )
2222 : {
2223 456030 : norm = s_min( norm, W_norm( intensity_real64[1][i] ) );
2224 : }
2225 458800 : IF( intensity_real64[2][i] != 0 )
2226 : {
2227 30125 : norm = s_min( norm, W_norm( intensity_real64[2][i] ) );
2228 : }
2229 :
2230 458800 : intensity_real[0][i] = W_extract_h( W_shl( intensity_real64[0][i], norm ) ); /*2 * inp_q - guard_bits + norm - 32*/
2231 458800 : move32();
2232 458800 : intensity_real[1][i] = W_extract_h( W_shl( intensity_real64[1][i], norm ) ); /*2 * inp_q - guard_bits + norm - 32*/
2233 458800 : move32();
2234 458800 : intensity_real[2][i] = W_extract_h( W_shl( intensity_real64[2][i], norm ) ); /*2 * inp_q - guard_bits + norm - 32*/
2235 458800 : move32();
2236 :
2237 458800 : q_intensity_real[i] = add( shift_intensity_real, sub( norm, guard_bits ) );
2238 458800 : move16();
2239 : }
2240 :
2241 91760 : return;
2242 : }
2243 :
2244 6120 : static void computeVerticalDiffuseness_fx(
2245 : Word32 **buffer_intensity, /* i : Intensity vectors */
2246 : const Word32 *buffer_energy, /* i : Energy */
2247 : const Word16 averaging_length, /* i : Averaging length */
2248 : const Word16 num_freq_bands, /* i : Number of frequency bands */
2249 : Word32 *diffuseness, /* o : Estimated diffuseness Q31 */
2250 : Word16 *buffer_intensity_q,
2251 : Word16 *buffer_energy_q )
2252 : {
2253 : Word32 intensity_slow[MASA_FREQUENCY_BANDS];
2254 : Word32 intensity_slow_abs[MASA_FREQUENCY_BANDS];
2255 : Word32 energy_slow[MASA_FREQUENCY_BANDS];
2256 : Word16 i, k;
2257 6120 : Word32 tmp = 0;
2258 6120 : move32();
2259 : const Word32 *p_tmp_c;
2260 : Word16 intensity_slow_e[MASA_FREQUENCY_BANDS], energy_slow_e[MASA_FREQUENCY_BANDS];
2261 :
2262 : /* Set variables to zero */
2263 6120 : set32_fx( intensity_slow, 0, MASA_FREQUENCY_BANDS );
2264 6120 : set32_fx( energy_slow, 0, MASA_FREQUENCY_BANDS );
2265 6120 : set16_fx( intensity_slow_e, 0, MASA_FREQUENCY_BANDS );
2266 6120 : set16_fx( energy_slow_e, 0, MASA_FREQUENCY_BANDS );
2267 :
2268 55080 : FOR( i = 0; i < averaging_length; ++i )
2269 : {
2270 : /* Energy slow */
2271 48960 : p_tmp_c = buffer_energy + i_mult( i, num_freq_bands );
2272 293760 : FOR( k = 0; k < num_freq_bands; k++ )
2273 : {
2274 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*/
2275 244800 : move32();
2276 244800 : p_tmp_c++;
2277 : }
2278 :
2279 : /* Intensity slow */
2280 293760 : FOR( k = 0; k < num_freq_bands; k++ )
2281 : {
2282 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*/
2283 244800 : move32();
2284 : }
2285 : }
2286 :
2287 : /* Compute absolute value */
2288 36720 : FOR( k = 0; k < num_freq_bands; k++ )
2289 : {
2290 30600 : intensity_slow_abs[k] = L_abs( intensity_slow[k] ); /*min_q*/
2291 30600 : move32();
2292 : }
2293 :
2294 : /* Compute Diffuseness */
2295 36720 : FOR( i = 0; i < num_freq_bands; ++i )
2296 : {
2297 : Word16 tmp_e1, tmp_e2, tmp1;
2298 30600 : tmp = BASOP_Util_Divide3232_Scale( intensity_slow_abs[i], L_add( energy_slow[i], EPSILON_FX_SMALL ), &tmp_e1 );
2299 30600 : tmp_e1 = add( tmp_e1, sub( intensity_slow_e[i], energy_slow_e[i] ) );
2300 30600 : tmp_e1 = BASOP_Util_Add_MantExp( (Word16) tmp, tmp_e1, -VERTICAL_ENERGY_RATIO_OFFSET_FX, 0, &tmp1 );
2301 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 */
2302 30600 : tmp_e2 = add( tmp_e2, tmp_e1 );
2303 30600 : tmp = L_sub( L_shl( 1, sub( 15, tmp_e2 ) ), tmp );
2304 30600 : IF( tmp < 0 )
2305 : {
2306 1 : tmp = 0;
2307 1 : move32();
2308 : }
2309 30599 : ELSE IF( GE_32( tmp, L_shl( 1, sub( 15, tmp_e2 ) ) ) )
2310 : {
2311 1323 : tmp = ONE_IN_Q31;
2312 1323 : move32();
2313 : }
2314 : ELSE
2315 : {
2316 29276 : tmp = L_shl( tmp, add( 16, tmp_e2 ) );
2317 : }
2318 30600 : diffuseness[i] = tmp; // Q31
2319 30600 : move32();
2320 : }
2321 :
2322 6120 : return;
2323 : }
2324 372 : static void computeEvenLayout_fx(
2325 : const Word32 *ls_azimuth, // Q22
2326 : Word32 *ls_azimuth_even, // Q22
2327 : const Word16 numChannels )
2328 : {
2329 : Word16 i;
2330 : Word16 j;
2331 : Word32 ls_azimuth_temp[MCMASA_MAX_ANA_CHANS];
2332 : Word32 ls_azimuth_even_ordered[MCMASA_MAX_ANA_CHANS];
2333 : Word16 ls_azimuth_order[MCMASA_MAX_ANA_CHANS];
2334 : Word32 smallestAzimuth;
2335 : Word16 smallestAzimuthIndex;
2336 : Word32 lsSpacing;
2337 : UWord8 oddLayout;
2338 : Word32 startAzimuth;
2339 : Word16 numChannelsHalf;
2340 :
2341 372 : lsSpacing = L_shl( L_mult0( 360, div_s( 1, numChannels ) ), 6 ); /*Q.21*/
2342 372 : oddLayout = (UWord8) s_and( numChannels, 1 );
2343 372 : move16();
2344 372 : numChannelsHalf = shr( numChannels, 1 );
2345 :
2346 372 : Copy32( ls_azimuth, ls_azimuth_temp, numChannels );
2347 372 : Scale_sig32( ls_azimuth_temp, numChannels, -1 ); /*Q.21*/
2348 2265 : FOR( i = 0; i < numChannels; i++ )
2349 : {
2350 1893 : smallestAzimuth = 1000 << 21; /*Q21*/
2351 1893 : move32();
2352 1893 : smallestAzimuthIndex = 0;
2353 1893 : move16();
2354 11974 : FOR( j = 0; j < numChannels; j++ )
2355 : {
2356 10081 : IF( LT_32( ls_azimuth_temp[j], smallestAzimuth ) )
2357 : {
2358 3502 : smallestAzimuth = ls_azimuth_temp[j];
2359 3502 : move32();
2360 3502 : smallestAzimuthIndex = j;
2361 3502 : move16();
2362 : }
2363 : }
2364 1893 : ls_azimuth_order[i] = smallestAzimuthIndex;
2365 1893 : move32();
2366 1893 : ls_azimuth_temp[smallestAzimuthIndex] = ( 1000 << 21 );
2367 1893 : move32();
2368 : }
2369 :
2370 372 : IF( oddLayout )
2371 : {
2372 249 : startAzimuth = W_extract_l( W_mult0_32_32( -lsSpacing, shl( numChannelsHalf, 1 ) ) ); /*Q.22*/
2373 : }
2374 : ELSE
2375 : {
2376 123 : startAzimuth = W_extract_l( W_mult0_32_32( -lsSpacing, sub( shl( numChannelsHalf, 1 ), 1 ) ) ); /*Q.22*/
2377 : }
2378 :
2379 2265 : FOR( i = 0; i < numChannels; i++ )
2380 : {
2381 1893 : ls_azimuth_even_ordered[i] = W_extract_l( W_add( W_mult_32_16( lsSpacing, i ), startAzimuth ) ); /*Q.22*/
2382 1893 : move32();
2383 : }
2384 :
2385 2265 : FOR( i = 0; i < numChannels; i++ )
2386 : {
2387 1893 : ls_azimuth_even[ls_azimuth_order[i]] = L_shl( L_shr( L_add( ls_azimuth_even_ordered[i], ONE_IN_Q21 ), 22 ), 22 ); /*((a+2^21)/2^22)*2^22*/
2388 1893 : move32();
2389 : }
2390 :
2391 372 : return;
2392 : }
2393 11470 : static void computeLfeEnergy_fx(
2394 : MCMASA_ENC_HANDLE hMcMasa,
2395 : Word32 *data_fx[], // q_inp
2396 : const Word16 input_frame,
2397 : Word16 q_inp )
2398 : {
2399 : Word16 l_ts;
2400 : Word16 block_m_idx;
2401 : Word16 mrange[2];
2402 : Word16 separateChannelIndex;
2403 : Word16 lfeChannelIndex;
2404 : Word32 *pcm_in[1];
2405 11470 : Word16 inp_q = q_inp;
2406 11470 : move16();
2407 :
2408 11470 : l_ts = idiv1616( input_frame, MDFT_NO_COL_MAX );
2409 11470 : separateChannelIndex = hMcMasa->separateChannelIndex;
2410 11470 : move16();
2411 11470 : lfeChannelIndex = LFE_CHANNEL;
2412 11470 : move16();
2413 :
2414 11470 : IF( hMcMasa->separateChannelEnabled )
2415 : {
2416 625 : Copy32( data_fx[lfeChannelIndex], &( hMcMasa->delay_buffer_lfe[0][hMcMasa->num_samples_delay_comp - hMcMasa->offset_comp] ), hMcMasa->offset_comp ); // q_inp
2417 625 : Copy32( data_fx[separateChannelIndex], &( hMcMasa->delay_buffer_lfe[1][hMcMasa->num_samples_delay_comp - hMcMasa->offset_comp] ), hMcMasa->offset_comp ); // q_inp
2418 : }
2419 : ELSE
2420 : {
2421 10845 : pcm_in[0] = &data_fx[lfeChannelIndex][0];
2422 : }
2423 :
2424 : /* Reset variables */
2425 11470 : set32_fx( hMcMasa->lfeLfEne, 0, MAX_PARAM_SPATIAL_SUBFRAMES );
2426 11470 : set16_fx( hMcMasa->lfeLfEne_e, 0, MAX_PARAM_SPATIAL_SUBFRAMES );
2427 11470 : set32_fx( hMcMasa->totalLfEne, 0, MAX_PARAM_SPATIAL_SUBFRAMES );
2428 11470 : set16_fx( hMcMasa->totalLfEne_e, 0, MAX_PARAM_SPATIAL_SUBFRAMES );
2429 :
2430 : /* Compute low-frequency energies */
2431 11470 : IF( hMcMasa->separateChannelEnabled ) /* Using low-pass filter */
2432 : {
2433 : Word32 lowpassCoef;
2434 : Word16 lowPassSignal_q;
2435 : Word16 i, j;
2436 : Word32 delayedInputSignal[2][L_FRAME48k];
2437 : Word32 lowPassSignal[2][L_FRAME48k];
2438 :
2439 625 : Copy32( &( hMcMasa->delay_buffer_lfe[0][0] ), &( delayedInputSignal[0][0] ), hMcMasa->num_slots_delay_comp * l_ts ); // q_inp
2440 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
2441 625 : Copy32( &( hMcMasa->delay_buffer_lfe[1][0] ), &( delayedInputSignal[1][0] ), hMcMasa->num_slots_delay_comp * l_ts ); // q_inp
2442 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
2443 :
2444 625 : lowpassCoef = L_shl( div_w( 1, (Word32) hMcMasa->ringBufferSize ), Q6 ); // Q.37(31+6)
2445 :
2446 600625 : FOR( i = 0; i < input_frame; i++ )
2447 : {
2448 1800000 : FOR( j = 0; j < 2; j++ )
2449 : {
2450 : Word32 temp1, temp2;
2451 1200000 : temp1 = Mpy_32_32( delayedInputSignal[j][i], lowpassCoef ); // Q(q_inp+6)
2452 1200000 : temp2 = Mpy_32_32( hMcMasa->lfeAnaRingBuffer[j][hMcMasa->ringBufferPointer], lowpassCoef ); // Q(q_inp+6)
2453 1200000 : hMcMasa->lowpassSum[j] = L_add( hMcMasa->lowpassSum[j], L_sub( temp1, temp2 ) );
2454 1200000 : move32();
2455 1200000 : lowPassSignal[j][i] = hMcMasa->lowpassSum[j];
2456 1200000 : move32();
2457 1200000 : hMcMasa->lfeAnaRingBuffer[j][hMcMasa->ringBufferPointer] = delayedInputSignal[j][i];
2458 1200000 : move32();
2459 : }
2460 :
2461 600000 : hMcMasa->ringBufferPointer = sub( hMcMasa->ringBufferPointer, 1 );
2462 600000 : move16();
2463 600000 : IF( hMcMasa->ringBufferPointer < 0 )
2464 : {
2465 2500 : hMcMasa->ringBufferPointer = sub( hMcMasa->ringBufferSize, 1 );
2466 : }
2467 : }
2468 625 : lowPassSignal_q = add( q_inp, Q6 );
2469 3125 : FOR( block_m_idx = 0; block_m_idx < MAX_PARAM_SPATIAL_SUBFRAMES; block_m_idx++ )
2470 : {
2471 2500 : mrange[0] = i_mult( hMcMasa->block_grouping[block_m_idx], l_ts );
2472 2500 : move16();
2473 2500 : mrange[1] = i_mult( hMcMasa->block_grouping[block_m_idx + 1], l_ts );
2474 2500 : move16();
2475 :
2476 602500 : FOR( i = mrange[0]; i < mrange[1]; i++ )
2477 : {
2478 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] );
2479 600000 : move32();
2480 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] );
2481 600000 : move32();
2482 : }
2483 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] );
2484 2500 : move32();
2485 : }
2486 : }
2487 : ELSE /* Using CLDFB */
2488 : {
2489 : Word16 ts;
2490 : Word16 i;
2491 : Word32 Chnl_RealBuffer[2][DIRAC_NO_FB_BANDS_MAX];
2492 : Word32 Chnl_ImagBuffer[2][DIRAC_NO_FB_BANDS_MAX];
2493 : Word32 *p_Chnl_RealBuffer[2];
2494 : Word32 *p_Chnl_ImagBuffer[2];
2495 :
2496 10845 : p_Chnl_RealBuffer[0] = &Chnl_RealBuffer[0][0];
2497 10845 : p_Chnl_RealBuffer[1] = &Chnl_RealBuffer[1][0];
2498 10845 : p_Chnl_ImagBuffer[0] = &Chnl_ImagBuffer[0][0];
2499 10845 : p_Chnl_ImagBuffer[1] = &Chnl_ImagBuffer[1][0];
2500 :
2501 :
2502 54225 : FOR( block_m_idx = 0; block_m_idx < MAX_PARAM_SPATIAL_SUBFRAMES; block_m_idx++ )
2503 : {
2504 43380 : mrange[0] = hMcMasa->block_grouping[block_m_idx];
2505 43380 : move16();
2506 43380 : mrange[1] = hMcMasa->block_grouping[block_m_idx + 1];
2507 43380 : move16();
2508 :
2509 86760 : FOR( ts = mrange[0]; ts < mrange[1]; ts++ )
2510 : {
2511 43380 : ivas_fb_mixer_get_windowed_fr_fx( hMcMasa->hFbMixerLfe, pcm_in, p_Chnl_RealBuffer, p_Chnl_ImagBuffer, l_ts, l_ts, hMcMasa->hFbMixerLfe->fb_cfg->num_in_chans, 0 );
2512 :
2513 43380 : ivas_fb_mixer_update_prior_input_fx( hMcMasa->hFbMixerLfe, pcm_in, l_ts, hMcMasa->hFbMixerLfe->fb_cfg->num_in_chans );
2514 :
2515 43380 : pcm_in[0] += l_ts;
2516 :
2517 : /* Compute low frequency energy for LFE, for other channels it is computed in ivas_chnl_param_est_enc() */
2518 216900 : FOR( i = 0; i < CLDFB_TO_MDFT_FAC; i++ )
2519 : {
2520 173520 : hMcMasa->lfeLfEne[block_m_idx] = BASOP_Util_Add_Mant32Exp( hMcMasa->lfeLfEne[block_m_idx], hMcMasa->lfeLfEne_e[block_m_idx], L_add( Mpy_32_32( Chnl_RealBuffer[0][i], Chnl_RealBuffer[0][i] ), Mpy_32_32( Chnl_ImagBuffer[0][i], Chnl_ImagBuffer[0][i] ) ), sub( 31, sub( shl( inp_q, 1 ), 31 ) ), &hMcMasa->lfeLfEne_e[block_m_idx] );
2521 173520 : move32();
2522 : }
2523 : }
2524 : }
2525 : }
2526 :
2527 11470 : IF( hMcMasa->separateChannelEnabled )
2528 : {
2529 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
2530 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
2531 : }
2532 :
2533 11470 : return;
2534 : }
|