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