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 "options.h"
34 : #include <stdlib.h>
35 : #include <math.h>
36 : #include "ivas_cnst.h"
37 : #include "ivas_prot_rend_fx.h"
38 : #include "ivas_prot_fx.h"
39 : #include "prot_fx.h"
40 : #include "ivas_stat_rend.h"
41 : #include "ivas_rom_com.h"
42 : #include "wmc_auto.h"
43 :
44 :
45 : /*-------------------------------------------------------------------------
46 : * Local function prototypes
47 : *------------------------------------------------------------------------*/
48 :
49 :
50 : static void ivas_omasa_dmx_fx(
51 : Word32 data_in_f_fx[][L_FRAME48k],
52 : Word16 *data_in_q,
53 : const Word16 input_frame,
54 : const Word16 nchan_transport,
55 : const Word16 nchan_ism,
56 : const Word32 ism_azimuth_fx[MAX_NUM_OBJECTS],
57 : const Word32 ism_elevation_fx[MAX_NUM_OBJECTS],
58 : Word32 prev_gains_fx[][MASA_MAX_TRANSPORT_CHANNELS],
59 : const Word16 interpolator_fx[L_FRAME48k] );
60 :
61 :
62 : static void ivas_omasa_param_est_ana_fx(
63 : OMASA_ANA_HANDLE hOMasa,
64 : Word32 data_f_fx[][L_FRAME48k],
65 : Word16 data_f_q,
66 : Word32 elevation_m_values_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], // Q22
67 : Word32 azimuth_m_values_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], // Q22
68 : Word32 energyRatio_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS],
69 : Word16 *energyRatio_q,
70 : Word32 spreadCoherence_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS],
71 : Word16 *spreadCoherence_q,
72 : Word32 surroundingCoherence_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS],
73 : Word16 *surroundingCoherence_q,
74 : const Word16 input_frame,
75 : const Word16 nchan_ism );
76 :
77 : /*--------------------------------------------------------------------------*
78 : * ivas_omasa_ana_open()
79 : *
80 : * Allocate and initialize OMASA handle
81 : *--------------------------------------------------------------------------*/
82 :
83 1 : ivas_error ivas_omasa_ana_open(
84 : OMASA_ANA_HANDLE *hOMasaPtr, /* i/o: OMASA data handle pointer */
85 : Word32 input_Fs, /* i : Sampling frequency */
86 : UWord16 total_num_objects /* i : Number of objects */
87 : )
88 : {
89 : Word16 i, j;
90 : OMASA_ANA_HANDLE hOMasa;
91 : Word16 numAnalysisChannels;
92 : Word16 maxBin, input_frame;
93 : ivas_error error;
94 : Word16 scale;
95 :
96 1 : error = IVAS_ERR_OK;
97 1 : move32();
98 :
99 1 : IF( ( hOMasa = (OMASA_ANA_HANDLE) malloc( sizeof( OMASA_ANA_DATA ) ) ) == NULL )
100 : {
101 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for OMASA\n" ) );
102 : }
103 :
104 1 : numAnalysisChannels = (Word16) total_num_objects;
105 1 : move16();
106 :
107 : /* Determine the number of bands */
108 1 : hOMasa->nbands = MASA_FREQUENCY_BANDS;
109 1 : move16();
110 :
111 : /* Determine band grouping */
112 1 : Copy( MASA_band_grouping_24, hOMasa->band_grouping, 24 + 1 );
113 :
114 : /* maxBin = (int16_t) ( input_Fs * INV_CLDFB_BANDWIDTH + 0.5f ); */
115 1 : maxBin = extract_l( Mpy_32_32( input_Fs, 2684355 /* INV_CLDFB_BANDWIDTH in Q31 */ ) ); // Q: ( ( Q0 + Q31 ) - Q31 ) -> Q0
116 :
117 24 : FOR( i = 1; i < hOMasa->nbands + 1; i++ )
118 : {
119 24 : IF( GE_16( hOMasa->band_grouping[i], maxBin ) )
120 : {
121 1 : hOMasa->band_grouping[i] = maxBin;
122 1 : move16();
123 1 : hOMasa->nbands = i;
124 1 : move16();
125 1 : BREAK;
126 : }
127 : }
128 :
129 : /* Determine block grouping */
130 1 : Copy( DirAC_block_grouping, hOMasa->block_grouping, MAX_PARAM_SPATIAL_SUBFRAMES + 1 );
131 :
132 : /* open/initialize CLDFB */
133 1 : hOMasa->num_Cldfb_instances = numAnalysisChannels;
134 5 : FOR( i = 0; i < hOMasa->num_Cldfb_instances; i++ )
135 : {
136 4 : IF( NE_32( ( error = openCldfb_ivas_fx( &( hOMasa->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS, DEC ) ), IVAS_ERR_OK ) )
137 : {
138 0 : return error;
139 : }
140 : }
141 :
142 1 : FOR( ; i < MAX_NUM_OBJECTS; i++ )
143 : {
144 0 : hOMasa->cldfbAnaEnc[i] = NULL;
145 : }
146 :
147 4 : FOR( i = 0; i < DIRAC_NUM_DIMS; i++ )
148 : {
149 3 : IF( ( hOMasa->direction_vector_m_fx[i] = (Word32 **) malloc( MAX_PARAM_SPATIAL_SUBFRAMES * sizeof( Word32 * ) ) ) == NULL )
150 : {
151 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for OMASA data\n" ) );
152 : }
153 :
154 15 : FOR( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ )
155 : {
156 12 : IF( ( hOMasa->direction_vector_m_fx[i][j] = (Word32 *) malloc( MASA_FREQUENCY_BANDS * sizeof( Word32 ) ) ) == NULL )
157 : {
158 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for OMASA data\n" ) );
159 : }
160 12 : set_zero_fx( hOMasa->direction_vector_m_fx[i][j], MASA_FREQUENCY_BANDS );
161 : }
162 : }
163 :
164 4 : FOR( i = 0; i < DIRAC_NUM_DIMS; i++ )
165 : {
166 99 : FOR( j = 0; j < DIRAC_NO_COL_AVG_DIFF; j++ )
167 : {
168 96 : IF( ( hOMasa->buffer_intensity_real_fx[i][j] = (Word32 *) malloc( MASA_FREQUENCY_BANDS * sizeof( Word32 ) ) ) == NULL )
169 : {
170 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for OMASA data\n" ) );
171 : }
172 96 : set_zero_fx( hOMasa->buffer_intensity_real_fx[i][j], MASA_FREQUENCY_BANDS );
173 : }
174 : }
175 :
176 1 : set_zero_fx( hOMasa->buffer_energy_fx, DIRAC_NO_COL_AVG_DIFF * MASA_FREQUENCY_BANDS );
177 :
178 5 : FOR( i = 0; i < MAX_NUM_OBJECTS; i++ )
179 : {
180 4 : set32_fx( hOMasa->prev_object_dm_gains_fx[i], INV_SQRT_2_Q31, MASA_MAX_TRANSPORT_CHANNELS );
181 : }
182 :
183 : /* input_frame = (int16_t) ( input_Fs / FRAMES_PER_SEC ); */
184 1 : input_frame = extract_l( Mpy_32_32( input_Fs, ONE_BY_FRAMES_PER_SEC_Q31 ) );
185 961 : FOR( i = 0; i < input_frame; i++ )
186 : {
187 960 : hOMasa->interpolator_fx[i] = BASOP_Util_Divide1616_Scale( i, input_frame, &scale );
188 960 : move16();
189 960 : hOMasa->interpolator_fx[i] = shl( hOMasa->interpolator_fx[i], scale ); // Q15
190 960 : move16();
191 : }
192 :
193 1 : hOMasa->index_buffer_intensity = 0;
194 1 : move16();
195 :
196 1 : IF( ( hOMasa->hMasaOut = (MASA_DECODER_EXT_OUT_META_HANDLE) malloc( sizeof( MASA_DECODER_EXT_OUT_META ) ) ) == NULL )
197 : {
198 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MASA decoder\n" ) );
199 : }
200 :
201 1 : IF( ( hOMasa->sph_grid16 = (SPHERICAL_GRID_DATA *) malloc( sizeof( SPHERICAL_GRID_DATA ) ) ) == NULL )
202 : {
203 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MASA decoder\n" ) );
204 : }
205 :
206 1 : generate_gridEq_fx( hOMasa->sph_grid16 );
207 :
208 5 : FOR( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ )
209 : {
210 4 : set_zero_fx( hOMasa->energy_fx[i], MASA_FREQUENCY_BANDS );
211 : }
212 :
213 1 : set_zero_fx( hOMasa->ism_azimuth_fx, MAX_NUM_OBJECTS );
214 1 : set_zero_fx( hOMasa->ism_elevation_fx, MAX_NUM_OBJECTS );
215 :
216 1 : ( *hOMasaPtr ) = hOMasa;
217 :
218 1 : return error;
219 : }
220 :
221 : /*--------------------------------------------------------------------------*
222 : * ivas_omasa_ana_close()
223 : *
224 : * Close OMASA handle
225 : *--------------------------------------------------------------------------*/
226 :
227 2632 : void ivas_omasa_ana_close(
228 : OMASA_ANA_HANDLE *hOMasa /* i/o: analysis OMASA handle */
229 : )
230 : {
231 : Word16 i, j;
232 :
233 2632 : test();
234 2632 : IF( hOMasa == NULL || *hOMasa == NULL )
235 : {
236 2631 : return;
237 : }
238 :
239 5 : FOR( i = 0; i < ( *hOMasa )->num_Cldfb_instances; i++ )
240 : {
241 4 : deleteCldfb_ivas_fx( &( ( *hOMasa )->cldfbAnaEnc[i] ) );
242 : }
243 :
244 4 : FOR( i = 0; i < DIRAC_NUM_DIMS; i++ )
245 : {
246 15 : FOR( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ )
247 : {
248 12 : free( ( *hOMasa )->direction_vector_m_fx[i][j] );
249 12 : ( *hOMasa )->direction_vector_m_fx[i][j] = NULL;
250 : }
251 :
252 99 : FOR( j = 0; j < DIRAC_NO_COL_AVG_DIFF; j++ )
253 : {
254 96 : free( ( *hOMasa )->buffer_intensity_real_fx[i][j] );
255 96 : ( *hOMasa )->buffer_intensity_real_fx[i][j] = NULL;
256 : }
257 :
258 3 : free( ( *hOMasa )->direction_vector_m_fx[i] );
259 3 : ( *hOMasa )->direction_vector_m_fx[i] = NULL;
260 : }
261 :
262 1 : free( ( *hOMasa )->hMasaOut );
263 1 : ( *hOMasa )->hMasaOut = NULL;
264 1 : free( ( *hOMasa )->sph_grid16 );
265 1 : ( *hOMasa )->sph_grid16 = NULL;
266 :
267 1 : free( ( *hOMasa ) );
268 1 : ( *hOMasa ) = NULL;
269 :
270 1 : return;
271 : }
272 :
273 : /*--------------------------------------------------------------------------*
274 : * ivas_omasa_ana()
275 : *
276 : * OMASA analysis function
277 : *--------------------------------------------------------------------------*/
278 :
279 :
280 150 : void ivas_omasa_ana_fx(
281 : OMASA_ANA_HANDLE hOMasa, /* i/o: OMASA analysis handle */
282 : Word32 data_in_f_fx[][L_FRAME48k], /* i/o: Input / transport audio signals */
283 : Word16 *data_in_q,
284 : const Word16 input_frame, /* i : Input frame size */
285 : const Word16 nchan_transport, /* i : Number of transport channels */
286 : const Word16 nchan_ism /* i : Number of objects for parameter analysis */
287 : )
288 : {
289 : Word32 elevation_m_values_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
290 : Word32 azimuth_m_values_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
291 : Word32 energyRatio_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
292 : Word32 spreadCoherence_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
293 : Word32 surroundingCoherence_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
294 : Word16 spreadCoherence_q, sorroundingCoherence_q, energyRatio_q;
295 :
296 : /* Estimate MASA parameters from the objects */
297 150 : ivas_omasa_param_est_ana_fx( hOMasa, data_in_f_fx, *data_in_q, elevation_m_values_fx, azimuth_m_values_fx, energyRatio_fx, &energyRatio_q, spreadCoherence_fx, &spreadCoherence_q, surroundingCoherence_fx, &sorroundingCoherence_q, input_frame, nchan_ism );
298 :
299 : /* Create MASA metadata buffer from the estimated values */
300 :
301 150 : ivas_create_masa_out_meta_fx( hOMasa->hMasaOut, hOMasa->sph_grid16, nchan_transport, elevation_m_values_fx, azimuth_m_values_fx, energyRatio_fx, spreadCoherence_fx, surroundingCoherence_fx, energyRatio_q, spreadCoherence_q, sorroundingCoherence_q );
302 :
303 : /* Downmix */
304 150 : ivas_omasa_dmx_fx( data_in_f_fx, data_in_q, input_frame, nchan_transport, nchan_ism, hOMasa->ism_azimuth_fx, hOMasa->ism_elevation_fx, hOMasa->prev_object_dm_gains_fx, hOMasa->interpolator_fx );
305 150 : return;
306 : }
307 :
308 :
309 : /*--------------------------------------------------------------------------*
310 : * Local functions
311 : *--------------------------------------------------------------------------*/
312 :
313 : /* Estimate MASA parameters from the objects */
314 :
315 :
316 150 : static void ivas_omasa_param_est_ana_fx(
317 : OMASA_ANA_HANDLE hOMasa,
318 : Word32 data_f_fx[][L_FRAME48k],
319 : Word16 data_f_q,
320 : Word32 elevation_m_values_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], // Q22
321 : Word32 azimuth_m_values_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], // Q22
322 : Word32 energyRatio_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS],
323 : Word16 *energyRatio_q,
324 : Word32 spreadCoherence_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS],
325 : Word16 *spreadCoherence_q,
326 : Word32 surroundingCoherence_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS],
327 : Word16 *surroundingCoherence_q,
328 : const Word16 input_frame,
329 : const Word16 nchan_ism )
330 : {
331 : Word16 ts, i, d, j;
332 : Word16 num_freq_bins, num_freq_bands, index;
333 : Word16 l_ts;
334 :
335 : Word32 reference_power_fx[MASA_FREQUENCY_BANDS];
336 : Word32 Chnl_RealBuffer_fx[MAX_NUM_OBJECTS][CLDFB_NO_CHANNELS_MAX];
337 : Word16 Chnl_RealBuffer_q[MAX_NUM_OBJECTS];
338 : Word16 Chnl_ImagBuffer_q[MAX_NUM_OBJECTS];
339 : Word32 Chnl_ImagBuffer_fx[MAX_NUM_OBJECTS][CLDFB_NO_CHANNELS_MAX];
340 : Word32 Foa_RealBuffer_fx[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX];
341 : Word32 Foa_ImagBuffer_fx[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX];
342 : Word32 intensity_real_fx[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS];
343 : Word32 direction_vector_fx[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS];
344 : Word32 diffuseness_vector_fx[MASA_FREQUENCY_BANDS];
345 150 : Word16 diffuseness_q = 0;
346 150 : move16();
347 : Word32 diffuseness_m_fx[MASA_FREQUENCY_BANDS];
348 150 : Word16 diffuseness_m_q = 0;
349 150 : move16();
350 : Word32 renormalization_factor_diff_fx[MASA_FREQUENCY_BANDS];
351 150 : Word16 renormalization_factor_diff_q = 0;
352 150 : move16();
353 : Word32 norm_tmp_fx;
354 : Word16 scale;
355 : Word16 tmp_ener_e[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
356 :
357 : Word32 dir_v_fx[DIRAC_NUM_DIMS], L_tmp1, L_tmp2;
358 : Word16 dir_v_q, norm_tmp_q;
359 : Word16 foa_q;
360 :
361 : Word16 band_m_idx, block_m_idx;
362 :
363 : Word16 mrange[2];
364 : Word16 brange[2];
365 :
366 150 : num_freq_bins = hOMasa->cldfbAnaEnc[0]->no_channels;
367 150 : move16();
368 150 : num_freq_bands = hOMasa->nbands;
369 150 : move16();
370 :
371 : // l_ts = input_frame / CLDFB_NO_COL_MAX;
372 150 : l_ts = shr( input_frame, 4 );
373 150 : move16();
374 :
375 : Word16 intensity_q;
376 : Word16 direction_q, reference_power_q;
377 :
378 150 : set16_zero_fx( Chnl_RealBuffer_q, MAX_NUM_OBJECTS );
379 150 : set16_zero_fx( Chnl_ImagBuffer_q, MAX_NUM_OBJECTS );
380 :
381 : /* Compute ISM to FOA matrices */
382 750 : FOR( i = 0; i < nchan_ism; i++ )
383 : {
384 : Word16 tmp, tmp1;
385 : // 180 in Q22 754974720
386 600 : hOMasa->chnlToFoaMtx_fx[0][i] = 32767; // 1 in Q15
387 600 : move16();
388 :
389 600 : tmp = BASOP_Util_Divide3232_Scale( hOMasa->ism_azimuth_fx[i], 754974720, &scale );
390 600 : tmp = mult( tmp, EVS_PI_FX ); // Q13 + Q15 - Q15 --> Q13
391 600 : tmp = getSinWord16( tmp ); // Q15 sine value
392 :
393 600 : tmp1 = BASOP_Util_Divide3232_Scale( hOMasa->ism_elevation_fx[i], 754974720, &scale );
394 600 : tmp1 = mult( tmp1, EVS_PI_FX );
395 600 : tmp1 = getCosWord16( tmp1 );
396 600 : hOMasa->chnlToFoaMtx_fx[1][i] = shl( mult( tmp, tmp1 ), 1 ); // Q14 + Q15 - Q15 + Q1 -> Q15
397 600 : move16();
398 :
399 600 : tmp = BASOP_Util_Divide3232_Scale( hOMasa->ism_elevation_fx[i], 754974720, &scale );
400 600 : tmp = mult( tmp, EVS_PI_FX ); // Q13 + Q15 - Q15 --> Q13
401 600 : hOMasa->chnlToFoaMtx_fx[2][i] = getSinWord16( tmp ); // Q15
402 600 : move16();
403 :
404 600 : tmp = BASOP_Util_Divide3232_Scale( hOMasa->ism_azimuth_fx[i], 754974720, &scale );
405 600 : tmp = mult( tmp, EVS_PI_FX ); // Q13 + Q15 - Q15 --> Q13
406 600 : tmp = getCosWord16( tmp ); // Q14
407 :
408 :
409 600 : tmp1 = BASOP_Util_Divide3232_Scale( hOMasa->ism_elevation_fx[i], 754974720, &scale );
410 600 : tmp1 = mult( tmp, EVS_PI_FX ); // Q13 + Q15 - Q15 --> Q13
411 600 : tmp1 = getCosWord16( tmp ); // Q14
412 :
413 600 : hOMasa->chnlToFoaMtx_fx[3][i] = shl( mult( tmp, tmp1 ), 2 ); // Q14 + Q14 - Q15 + Q2-> Q13 + Q2 -> Q15
414 600 : move16();
415 : }
416 :
417 : /* do processing over all CLDFB time slots */
418 750 : FOR( block_m_idx = 0; block_m_idx < MAX_PARAM_SPATIAL_SUBFRAMES; block_m_idx++ )
419 : {
420 600 : mrange[0] = hOMasa->block_grouping[block_m_idx];
421 600 : move16();
422 600 : mrange[1] = hOMasa->block_grouping[block_m_idx + 1];
423 600 : move16();
424 :
425 15000 : FOR( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ )
426 : {
427 14400 : hOMasa->direction_vector_m_fx[0][block_m_idx][band_m_idx] = 0;
428 14400 : move32();
429 14400 : hOMasa->direction_vector_m_fx[1][block_m_idx][band_m_idx] = 0;
430 14400 : move32();
431 14400 : hOMasa->direction_vector_m_fx[2][block_m_idx][band_m_idx] = 0;
432 14400 : move32();
433 : }
434 :
435 : /* Need to initialize renormalization_factors, and variables to be normalized */
436 :
437 600 : set_zero_fx( renormalization_factor_diff_fx, hOMasa->nbands );
438 600 : set_zero_fx( diffuseness_m_fx, hOMasa->nbands );
439 600 : set_zero_fx( hOMasa->energy_fx[block_m_idx], MASA_FREQUENCY_BANDS );
440 :
441 600 : set16_fx( tmp_ener_e[block_m_idx], 0, MASA_FREQUENCY_BANDS );
442 :
443 3000 : FOR( ts = mrange[0]; ts < mrange[1]; ts++ )
444 : {
445 12000 : FOR( i = 0; i < nchan_ism; i++ )
446 : {
447 9600 : Word16 in_q = Q11;
448 9600 : move16();
449 :
450 : /* Keep input to cldfbAnalysis_ts_fx in Q11 */
451 9600 : IF( NE_16( in_q, data_f_q ) )
452 : {
453 8896 : scale_sig32( &( data_f_fx[i][i_mult( l_ts, ts )] ), l_ts, sub( in_q, data_f_q ) ); /* Q11 */
454 : }
455 :
456 9600 : cldfbAnalysis_ts_fx( &( data_f_fx[i][i_mult( l_ts, ts )] ), Chnl_RealBuffer_fx[i], Chnl_ImagBuffer_fx[i], l_ts, hOMasa->cldfbAnaEnc[i], &in_q );
457 :
458 : /* Restore data_f_fx to it's original Q */
459 9600 : IF( NE_16( data_f_q, Q11 ) )
460 : {
461 8896 : scale_sig32( &( data_f_fx[i][i_mult( l_ts, ts )] ), l_ts, sub( data_f_q, Q11 ) ); /* Q(data_f_q) */
462 : }
463 :
464 585600 : FOR( Word16 ind = 0; ind < CLDFB_NO_CHANNELS_MAX; ind++ )
465 : {
466 576000 : Chnl_RealBuffer_fx[i][ind] = L_shr( Chnl_RealBuffer_fx[i][ind], 4 ); // Q: in_q - 4
467 576000 : move32();
468 576000 : Chnl_ImagBuffer_fx[i][ind] = L_shr( Chnl_ImagBuffer_fx[i][ind], 4 ); // Q: in_q - 4
469 576000 : move32();
470 : }
471 :
472 9600 : Chnl_RealBuffer_q[i] = sub( in_q, 4 );
473 9600 : move16();
474 9600 : Chnl_ImagBuffer_q[i] = sub( in_q, 4 );
475 9600 : move16();
476 : }
477 :
478 2400 : IF( GT_16( nchan_ism, 1 ) )
479 : {
480 : Word16 anaBuf_com_q;
481 2400 : minimum_fx( Chnl_RealBuffer_q, nchan_ism, &anaBuf_com_q );
482 :
483 12000 : FOR( i = 0; i < nchan_ism; i++ )
484 : {
485 9600 : IF( NE_16( anaBuf_com_q, Chnl_RealBuffer_q[i] ) )
486 : {
487 412055 : FOR( Word16 ind = 0; ind < CLDFB_NO_CHANNELS_MAX; ind++ )
488 : {
489 405300 : Chnl_RealBuffer_fx[i][ind] = L_shr( Chnl_RealBuffer_fx[i][ind], sub( Chnl_RealBuffer_q[i], anaBuf_com_q ) ); // Q: anaBuf_com_q
490 405300 : move32();
491 405300 : Chnl_ImagBuffer_fx[i][ind] = L_shr( Chnl_ImagBuffer_fx[i][ind], sub( Chnl_ImagBuffer_q[i], anaBuf_com_q ) ); // Q: anaBuf_com_q
492 405300 : move32();
493 : }
494 6755 : Chnl_ImagBuffer_q[i] = anaBuf_com_q;
495 6755 : move16();
496 6755 : Chnl_RealBuffer_q[i] = anaBuf_com_q;
497 6755 : move16();
498 : }
499 : }
500 : }
501 :
502 :
503 : /* Compute channel-based energy for metadata processing */
504 60000 : FOR( band_m_idx = 0; band_m_idx < num_freq_bands; band_m_idx++ )
505 : {
506 57600 : brange[0] = hOMasa->band_grouping[band_m_idx];
507 57600 : move16();
508 57600 : brange[1] = hOMasa->band_grouping[band_m_idx + 1];
509 57600 : move16();
510 201600 : FOR( j = brange[0]; j < brange[1]; j++ )
511 : {
512 720000 : FOR( i = 0; i < nchan_ism; i++ )
513 : {
514 : Word16 tmp_e, tmp_r_q, tmp_i_q;
515 : Word32 tmp_r, tmp_i, L_tmp_sum;
516 576000 : tmp_r_q = norm_l( Chnl_RealBuffer_fx[i][j] );
517 576000 : tmp_r = L_shl( Chnl_RealBuffer_fx[i][j], tmp_r_q ); /* Q(Chnl_RealBuffer_q[i] + tmp_r_q) */
518 576000 : tmp_r_q = add( tmp_r_q, Chnl_RealBuffer_q[i] );
519 576000 : L_tmp1 = Mpy_32_32( tmp_r, tmp_r ); /* Q(2*tmp_r_q - 31)*/
520 576000 : tmp_r_q = sub( add( tmp_r_q, tmp_r_q ), 31 );
521 576000 : tmp_i_q = norm_l( Chnl_ImagBuffer_fx[i][j] );
522 576000 : tmp_i = L_shl( Chnl_ImagBuffer_fx[i][j], tmp_i_q ); /* Q(Chnl_ImagBuffer_q[i] + tmp_i_q)*/
523 576000 : tmp_i_q = add( tmp_i_q, Chnl_ImagBuffer_q[i] );
524 576000 : tmp_i_q = sub( add( tmp_i_q, tmp_i_q ), 31 );
525 576000 : L_tmp2 = Mpy_32_32( tmp_i, tmp_i ); /* Q(2*tmp_i_q - 31) */
526 576000 : L_tmp_sum = BASOP_Util_Add_Mant32Exp( L_tmp1, sub( 31, tmp_r_q ), L_tmp2, sub( 31, tmp_i_q ), &tmp_e ); /* Q(31 - tmp_e) */
527 576000 : hOMasa->energy_fx[block_m_idx][band_m_idx] = BASOP_Util_Add_Mant32Exp( hOMasa->energy_fx[block_m_idx][band_m_idx], tmp_ener_e[block_m_idx][band_m_idx], L_tmp_sum, tmp_e, &tmp_ener_e[block_m_idx][band_m_idx] ); /* Q(31 - tmp_ener_e[block_m_idx][band_m_idx]) */
528 576000 : move32();
529 : }
530 : }
531 : }
532 :
533 : /* Compute FOA */
534 : /* W */
535 :
536 2400 : Copy32( Chnl_RealBuffer_fx[0], Foa_RealBuffer_fx[0], num_freq_bins );
537 2400 : Copy32( Chnl_ImagBuffer_fx[0], Foa_ImagBuffer_fx[0], num_freq_bins );
538 :
539 9600 : FOR( i = 1; i < nchan_ism; i++ )
540 : {
541 : #ifdef VEC_ARITH_OPT_v1
542 7200 : v_add_fixed_no_hdrm( Chnl_RealBuffer_fx[i], Foa_RealBuffer_fx[0], Foa_RealBuffer_fx[0], num_freq_bins ); // Q: Chnl_RealBuffer_q
543 7200 : v_add_fixed_no_hdrm( Chnl_ImagBuffer_fx[i], Foa_ImagBuffer_fx[0], Foa_ImagBuffer_fx[0], num_freq_bins ); // Q: Chnl_ImagBuffer_q
544 : #else /* VEC_ARITH_OPT_v1 */
545 : v_add_fixed( Chnl_RealBuffer_fx[i], Foa_RealBuffer_fx[0], Foa_RealBuffer_fx[0], num_freq_bins, 0 ); // Q: Chnl_RealBuffer_q
546 : v_add_fixed( Chnl_ImagBuffer_fx[i], Foa_ImagBuffer_fx[0], Foa_ImagBuffer_fx[0], num_freq_bins, 0 ); // Q: Chnl_ImagBuffer_q
547 : #endif /* VEC_ARITH_OPT_v1 */
548 : }
549 :
550 : /* Y */
551 :
552 2400 : v_multc_fixed( Chnl_RealBuffer_fx[0], L_deposit_h( hOMasa->chnlToFoaMtx_fx[1][0] ), Foa_RealBuffer_fx[1], num_freq_bins ); // Q: Chnl_RealBuffer_q
553 2400 : v_multc_fixed( Chnl_ImagBuffer_fx[0], L_deposit_h( hOMasa->chnlToFoaMtx_fx[1][0] ), Foa_ImagBuffer_fx[1], num_freq_bins ); // Q: Chnl_ImagBuffer_q
554 :
555 9600 : FOR( i = 1; i < nchan_ism; i++ )
556 : {
557 7200 : v_multc_acc_32_16( Chnl_RealBuffer_fx[i], hOMasa->chnlToFoaMtx_fx[1][i], Foa_RealBuffer_fx[1], num_freq_bins ); // Q: Chnl_RealBuffer_q
558 7200 : v_multc_acc_32_16( Chnl_ImagBuffer_fx[i], hOMasa->chnlToFoaMtx_fx[1][i], Foa_ImagBuffer_fx[1], num_freq_bins ); // Q: Chnl_ImagBuffer_q
559 : }
560 :
561 : /* Z */
562 :
563 2400 : v_multc_fixed( Chnl_RealBuffer_fx[0], L_deposit_h( hOMasa->chnlToFoaMtx_fx[2][0] ), Foa_RealBuffer_fx[2], num_freq_bins ); // Q: Chnl_RealBuffer_q
564 2400 : v_multc_fixed( Chnl_ImagBuffer_fx[0], L_deposit_h( hOMasa->chnlToFoaMtx_fx[2][0] ), Foa_ImagBuffer_fx[2], num_freq_bins ); // Q: Chnl_ImagBuffer_q
565 :
566 9600 : FOR( i = 1; i < nchan_ism; i++ )
567 : {
568 7200 : v_multc_acc_32_16( Chnl_RealBuffer_fx[i], hOMasa->chnlToFoaMtx_fx[2][i], Foa_RealBuffer_fx[2], num_freq_bins ); // Q: Chnl_RealBuffer_q
569 7200 : v_multc_acc_32_16( Chnl_ImagBuffer_fx[i], hOMasa->chnlToFoaMtx_fx[2][i], Foa_ImagBuffer_fx[2], num_freq_bins ); // Q: Chnl_ImagBuffer_q
570 : }
571 :
572 2400 : v_multc_fixed( Chnl_RealBuffer_fx[0], L_deposit_h( hOMasa->chnlToFoaMtx_fx[3][0] ), Foa_RealBuffer_fx[2], num_freq_bins ); // Q: Chnl_RealBuffer_q
573 2400 : v_multc_fixed( Chnl_ImagBuffer_fx[0], L_deposit_h( hOMasa->chnlToFoaMtx_fx[3][0] ), Foa_ImagBuffer_fx[2], num_freq_bins ); // Q: Chnl_ImagBuffer_q
574 :
575 9600 : FOR( i = 1; i < nchan_ism; i++ )
576 : {
577 7200 : v_multc_acc_32_16( Chnl_RealBuffer_fx[i], hOMasa->chnlToFoaMtx_fx[3][i], Foa_RealBuffer_fx[3], num_freq_bins ); // Q: Chnl_RealBuffer_q
578 7200 : v_multc_acc_32_16( Chnl_ImagBuffer_fx[i], hOMasa->chnlToFoaMtx_fx[3][i], Foa_ImagBuffer_fx[3], num_freq_bins ); // Q: Chnl_ImagBuffer_q
579 : }
580 :
581 : /* Direction estimation */
582 12000 : FOR( i = 0; i < FOA_CHANNELS; i++ )
583 : {
584 585600 : FOR( j = 0; j < CLDFB_NO_CHANNELS_MAX; j++ )
585 : {
586 576000 : Foa_RealBuffer_fx[i][j] = L_shr( Foa_RealBuffer_fx[i][j], 5 ); // Q: ( Chnl_RealBuffer_q - 5 )
587 576000 : move32();
588 576000 : Foa_ImagBuffer_fx[i][j] = L_shr( Foa_ImagBuffer_fx[i][j], 5 ); // Q: ( Chnl_RealBuffer_q - 5 )
589 576000 : move32();
590 : }
591 : }
592 2400 : foa_q = sub( Chnl_ImagBuffer_q[0], 5 );
593 2400 : computeIntensityVector_ana_fx( hOMasa->band_grouping, Foa_RealBuffer_fx, Foa_ImagBuffer_fx, num_freq_bands, intensity_real_fx );
594 :
595 2400 : intensity_q = sub( shl( add( foa_q, Q1 ), 1 ), 31 );
596 2400 : direction_q = intensity_q;
597 2400 : move16();
598 :
599 2400 : computeDirectionVectors_fx( intensity_real_fx[0], intensity_real_fx[1], intensity_real_fx[2], 0, num_freq_bands, direction_vector_fx[0], direction_vector_fx[1], direction_vector_fx[2], &direction_q );
600 :
601 : /* Power estimation for diffuseness */
602 :
603 2400 : computeReferencePower_ana_fx( hOMasa->band_grouping, Foa_RealBuffer_fx, Foa_ImagBuffer_fx, reference_power_fx, num_freq_bands ); // 2 * inputq - 30
604 2400 : reference_power_q = sub( shl( Chnl_ImagBuffer_q[0], 1 ), 30 );
605 :
606 : /* Fill buffers of length "averaging_length" time slots for intensity and energy */
607 2400 : hOMasa->index_buffer_intensity = add( ( hOMasa->index_buffer_intensity % DIRAC_NO_COL_AVG_DIFF ), 1 ); /* averaging_length = 32 */
608 2400 : move16();
609 2400 : index = hOMasa->index_buffer_intensity;
610 2400 : move16();
611 :
612 9600 : FOR( i = 0; i < DIRAC_NUM_DIMS; i++ )
613 : {
614 : /* only real part needed */
615 7200 : Copy32( intensity_real_fx[i], &( hOMasa->buffer_intensity_real_fx[i][index - 1][0] ), num_freq_bands ); // intensity_q
616 : }
617 2400 : hOMasa->buffer_intensity_real_q[index - 1] = intensity_q;
618 2400 : move16();
619 2400 : Copy32( reference_power_fx, &( hOMasa->buffer_energy_fx[( index - 1 ) * num_freq_bands] ), num_freq_bands );
620 2400 : hOMasa->buffer_energy_q[index - 1] = reference_power_q;
621 2400 : move16();
622 :
623 2400 : computeDiffuseness_fixed( hOMasa->buffer_intensity_real_fx, hOMasa->buffer_energy_fx, num_freq_bands, diffuseness_vector_fx, hOMasa->buffer_intensity_real_q, hOMasa->buffer_energy_q, &diffuseness_q );
624 :
625 60000 : FOR( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ )
626 : {
627 57600 : norm_tmp_fx = Mpy_32_32( reference_power_fx[band_m_idx], L_sub( ONE_IN_Q30, diffuseness_vector_fx[band_m_idx] ) ); // reference_power_q + 30 - 31
628 57600 : norm_tmp_q = sub( add( reference_power_q, 30 ), 31 );
629 :
630 57600 : hOMasa->direction_vector_m_fx[0][block_m_idx][band_m_idx] = L_add( hOMasa->direction_vector_m_fx[0][block_m_idx][band_m_idx], Mpy_32_32( norm_tmp_fx, direction_vector_fx[0][band_m_idx] ) ); // Q: hOMasa->direction_vector_m_q: ( ( norm_tmp_q + direction_q ) - 31 )
631 57600 : move32();
632 :
633 57600 : hOMasa->direction_vector_m_fx[1][block_m_idx][band_m_idx] = L_add( hOMasa->direction_vector_m_fx[0][block_m_idx][band_m_idx], Mpy_32_32( norm_tmp_fx, direction_vector_fx[1][band_m_idx] ) ); // Q: hOMasa->direction_vector_m_q: ( ( norm_tmp_q + direction_q ) - 31 )
634 57600 : move32();
635 57600 : hOMasa->direction_vector_m_fx[2][block_m_idx][band_m_idx] = L_add( hOMasa->direction_vector_m_fx[0][block_m_idx][band_m_idx], Mpy_32_32( norm_tmp_fx, direction_vector_fx[2][band_m_idx] ) ); // Q: hOMasa->direction_vector_m_q: ( ( norm_tmp_q + direction_q ) - 31 )
636 57600 : move32();
637 :
638 57600 : hOMasa->direction_vector_m_q = sub( add( norm_tmp_q, direction_q ), 31 );
639 :
640 :
641 57600 : diffuseness_m_fx[band_m_idx] = L_add( diffuseness_m_fx[band_m_idx], Mpy_32_32( reference_power_fx[band_m_idx], diffuseness_vector_fx[band_m_idx] ) ); // diffuseness_m_q: ( ( reference_power_q + diffuseness_q ) - 31 );
642 57600 : move32();
643 57600 : diffuseness_m_q = sub( add( reference_power_q, diffuseness_q ), 31 );
644 57600 : renormalization_factor_diff_fx[band_m_idx] = L_add( renormalization_factor_diff_fx[band_m_idx], reference_power_fx[band_m_idx] );
645 57600 : move32();
646 57600 : renormalization_factor_diff_q = reference_power_q;
647 57600 : move16();
648 : }
649 : }
650 :
651 15000 : FOR( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ )
652 : {
653 57600 : FOR( d = 0; d < DIRAC_NUM_DIMS; d++ )
654 : {
655 43200 : dir_v_fx[d] = hOMasa->direction_vector_m_fx[d][block_m_idx][band_m_idx];
656 43200 : move32();
657 : }
658 14400 : dir_v_q = hOMasa->direction_vector_m_q;
659 14400 : move16();
660 :
661 57600 : FOR( i = 0; i < DIRAC_NUM_DIMS; i++ )
662 : {
663 43200 : dir_v_fx[i] = L_shr( dir_v_fx[i], 1 );
664 43200 : move32();
665 : }
666 :
667 14400 : dir_v_q = sub( dir_v_q, 1 );
668 14400 : ivas_qmetadata_direction_vector_to_azimuth_elevation_fx( dir_v_fx, dir_v_q, &azimuth_m_values_fx[block_m_idx][band_m_idx], &elevation_m_values_fx[block_m_idx][band_m_idx] );
669 : }
670 :
671 : /* Determine energy ratios */
672 15000 : FOR( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ )
673 : {
674 14400 : IF( BASOP_Util_Cmp_Mant32Exp( renormalization_factor_diff_fx[band_m_idx], sub( 31, renormalization_factor_diff_q ), L_deposit_h( EPSILON_FX ), 2 ) > 0 )
675 : {
676 3861 : diffuseness_m_fx[band_m_idx] = BASOP_Util_Divide3232_Scale( diffuseness_m_fx[band_m_idx], renormalization_factor_diff_fx[band_m_idx], &scale );
677 3861 : move32();
678 3861 : scale = add( scale, sub( sub( 31, diffuseness_m_q ), sub( 31, renormalization_factor_diff_q ) ) );
679 :
680 3861 : diffuseness_m_fx[band_m_idx] = L_shr( diffuseness_m_fx[band_m_idx], sub( 31, add( scale, diffuseness_m_q ) ) );
681 3861 : move32();
682 : }
683 : ELSE
684 : {
685 10539 : diffuseness_m_fx[band_m_idx] = 0;
686 10539 : move32();
687 : }
688 14400 : energyRatio_fx[block_m_idx][band_m_idx] = L_sub( L_shl( 1, diffuseness_m_q ), diffuseness_m_fx[band_m_idx] ); // Q: diffuseness_m_q
689 14400 : move32();
690 : }
691 :
692 : /* Set coherences to zero, as this mode is used at lowest bit rates where the coherences are not transmitted */
693 15000 : FOR( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ )
694 : {
695 14400 : spreadCoherence_fx[block_m_idx][band_m_idx] = 0;
696 14400 : move32();
697 14400 : surroundingCoherence_fx[block_m_idx][band_m_idx] = 0;
698 14400 : move32();
699 : }
700 : }
701 :
702 150 : Word16 q_ener_min = MAX_16;
703 150 : move16();
704 750 : FOR( block_m_idx = 0; block_m_idx < MAX_PARAM_SPATIAL_SUBFRAMES; block_m_idx++ )
705 : {
706 : Word16 e_max;
707 600 : maximum_fx( tmp_ener_e[block_m_idx], num_freq_bands, &e_max );
708 600 : e_max = sub( 31, e_max );
709 600 : if ( GT_16( q_ener_min, e_max ) )
710 : {
711 256 : q_ener_min = e_max;
712 256 : move16();
713 : }
714 : }
715 :
716 750 : FOR( block_m_idx = 0; block_m_idx < MAX_PARAM_SPATIAL_SUBFRAMES; block_m_idx++ )
717 : {
718 15000 : FOR( band_m_idx = 0; band_m_idx < num_freq_bands; band_m_idx++ )
719 : {
720 14400 : hOMasa->energy_fx[block_m_idx][band_m_idx] = L_shr( hOMasa->energy_fx[block_m_idx][band_m_idx], sub( sub( 31, tmp_ener_e[block_m_idx][band_m_idx] ), q_ener_min ) ); /* Q(q_ener_min) */
721 14400 : move32();
722 : }
723 : }
724 :
725 150 : hOMasa->energy_q = q_ener_min;
726 150 : move16();
727 :
728 150 : *spreadCoherence_q = 0;
729 150 : move16();
730 150 : *surroundingCoherence_q = 0;
731 150 : move16();
732 150 : *energyRatio_q = 0;
733 150 : move16();
734 :
735 150 : return;
736 : }
737 :
738 :
739 : /* Compute downmix */
740 150 : static void ivas_omasa_dmx_fx(
741 : Word32 data_in_f_fx[][L_FRAME48k],
742 : Word16 *data_in_q,
743 : const Word16 input_frame,
744 : const Word16 nchan_transport,
745 : const Word16 nchan_ism,
746 : const Word32 ism_azimuth_fx[MAX_NUM_OBJECTS],
747 : const Word32 ism_elevation_fx[MAX_NUM_OBJECTS],
748 : Word32 prev_gains_fx[][MASA_MAX_TRANSPORT_CHANNELS],
749 : const Word16 interpolator_fx[L_FRAME48k] )
750 : {
751 : Word16 i, j, k, l, tmp1, tmp2;
752 :
753 : Word16 azimuth_fx, elevation_fx;
754 : Word16 gains_fx[MASA_MAX_TRANSPORT_CHANNELS];
755 : Word16 g1_fx, g2_fx, scale;
756 : Word32 data_out_f_fx[MASA_MAX_TRANSPORT_CHANNELS][L_FRAME48k], L_tmp;
757 : Word16 max_e, tmp_e;
758 : Word16 in_e[960];
759 : Word16 data_e[4];
760 :
761 450 : FOR( i = 0; i < nchan_transport; i++ )
762 : {
763 300 : set_zero_fx( data_out_f_fx[i], input_frame );
764 : }
765 150 : set16_fx( data_e, 0, 4 );
766 150 : set16_fx( in_e, 0, 960 );
767 :
768 750 : FOR( i = 0; i < nchan_ism; i++ )
769 : {
770 :
771 600 : azimuth_fx = extract_l( L_shr( ism_azimuth_fx[i], Q22 ) ); // Q0
772 600 : elevation_fx = extract_l( L_shr( ism_elevation_fx[i], Q22 ) ); // Q0
773 :
774 600 : ivas_ism_get_stereo_gains_fx( azimuth_fx, elevation_fx, &gains_fx[0], &gains_fx[1] );
775 :
776 : /* Downmix using the panning gains */
777 1800 : FOR( j = 0; j < nchan_transport; j++ )
778 : {
779 1200 : test();
780 1200 : IF( abs_s( gains_fx[j] ) > 0 || L_abs( prev_gains_fx[i][j] ) > 0 )
781 : {
782 1060944 : FOR( k = 0; k < input_frame; k++ )
783 : {
784 :
785 1059840 : g1_fx = interpolator_fx[k]; // Q15
786 1059840 : move16();
787 1059840 : scale = BASOP_Util_Add_MantExp( 16384, 1, negate( g1_fx ), 0, &g2_fx );
788 :
789 1059840 : tmp1 = mult( g1_fx, gains_fx[j] );
790 1059840 : tmp2 = mult( g2_fx, (Word16) L_shr( prev_gains_fx[i][j], 16 ) ); // Q: ( ( ( 15 - scale ) + ( Q31 - Q16 ) ) - Q15 ) -> ( 15 - scale )
791 1059840 : scale = BASOP_Util_Add_MantExp( tmp1, 0, tmp2, scale, &tmp1 );
792 :
793 1059840 : L_tmp = data_in_f_fx[i][k]; // data_in_q
794 1059840 : move32();
795 1059840 : tmp_e = sub( 31, *data_in_q );
796 1059840 : move16();
797 :
798 1059840 : L_tmp = Mpy_32_16_1( L_tmp, tmp1 );
799 1059840 : scale = add( scale, tmp_e );
800 :
801 1059840 : data_out_f_fx[j][k] = BASOP_Util_Add_Mant32Exp( data_out_f_fx[j][k], data_e[j], L_tmp, scale, &in_e[k] );
802 1059840 : move32();
803 : }
804 : }
805 1200 : max_e = in_e[0];
806 1200 : move16();
807 1152000 : FOR( l = 1; l < L_FRAME48k; l++ )
808 : {
809 1150800 : IF( LT_16( max_e, in_e[l] ) )
810 : {
811 2449 : max_e = in_e[l];
812 2449 : move16();
813 : }
814 : }
815 :
816 1153200 : FOR( l = 0; l < L_FRAME48k; l++ )
817 : {
818 1152000 : data_out_f_fx[j][l] = L_shr( data_out_f_fx[j][l], sub( max_e, in_e[l] ) ); // exponent: max_e, Q: ( 15 - max_e )
819 1152000 : move32();
820 : }
821 1200 : data_e[j] = max_e;
822 1200 : move16();
823 :
824 1200 : prev_gains_fx[i][j] = L_deposit_h( gains_fx[j] ); // Q31
825 1200 : move32();
826 : }
827 : }
828 :
829 150 : max_e = data_e[0];
830 150 : move16();
831 300 : FOR( i = 1; i < nchan_transport; i++ )
832 : {
833 150 : if ( LT_16( max_e, data_e[i] ) )
834 : {
835 50 : max_e = data_e[i];
836 50 : move16();
837 : }
838 : }
839 :
840 450 : FOR( i = 0; i < nchan_transport; i++ )
841 : {
842 288300 : FOR( j = 0; j < input_frame; j++ )
843 : {
844 288000 : data_out_f_fx[i][j] = L_shr( data_out_f_fx[i][j], sub( max_e, data_e[i] ) ); // exponent: max_e, Q: ( 15 - max_e )
845 288000 : move32();
846 : }
847 : }
848 :
849 450 : FOR( i = 0; i < nchan_transport; i++ )
850 : {
851 300 : Copy32( data_out_f_fx[i], data_in_f_fx[i], input_frame );
852 300 : *data_in_q = sub( 31, max_e );
853 300 : move16();
854 : }
855 :
856 150 : return;
857 : }
858 :
859 : /* Compute downmix */
860 :
861 :
862 : /*--------------------------------------------------------------------------*
863 : * computeIntensityVector_ana()
864 : *
865 : *
866 : *--------------------------------------------------------------------------*/
867 :
868 9600 : void computeIntensityVector_ana_fx(
869 : const Word16 *band_grouping, /* i : Band grouping for estimation */
870 : Word32 Cldfb_RealBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i : Real part of input signal Qx */
871 : Word32 Cldfb_ImagBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i : Imag part of input sig Qx */
872 : const Word16 num_frequency_bands, /* i : Number of frequency bands */
873 : Word32 intensity_real[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS] /* o : Intensity 2 * Qx -31 */
874 : )
875 : {
876 : /* Reminder
877 : * X = a + ib; Y = c + id
878 : * X*Y = ac - bd + i(ad +bc)
879 : */
880 : Word16 i, j;
881 : Word32 real, img;
882 : Word16 brange[2];
883 :
884 240000 : FOR( i = 0; i < num_frequency_bands; i++ )
885 : {
886 230400 : brange[0] = band_grouping[i];
887 230400 : move16();
888 230400 : brange[1] = band_grouping[i + 1];
889 230400 : move16();
890 :
891 230400 : intensity_real[0][i] = 0;
892 230400 : move32();
893 230400 : intensity_real[1][i] = 0;
894 230400 : move32();
895 230400 : intensity_real[2][i] = 0;
896 230400 : move32();
897 :
898 806400 : FOR( j = brange[0]; j < brange[1]; j++ )
899 : {
900 576000 : real = Cldfb_RealBuffer[0][j]; // Qx
901 576000 : img = Cldfb_ImagBuffer[0][j]; // Qx
902 : /* Intensity is XYZ order, audio is WYZX order. */
903 576000 : intensity_real[0][i] = L_add( intensity_real[0][i], L_add( Mpy_32_32( Cldfb_RealBuffer[3][j], real ), Mpy_32_32( Cldfb_ImagBuffer[3][j], img ) ) ); // output Q = 2 * Qx -31
904 576000 : move32();
905 576000 : intensity_real[1][i] = L_add( intensity_real[1][i], L_add( Mpy_32_32( Cldfb_RealBuffer[1][j], real ), Mpy_32_32( Cldfb_ImagBuffer[1][j], img ) ) ); // output Q = 2 * Qx -31
906 576000 : move32();
907 576000 : intensity_real[2][i] = L_add( intensity_real[2][i], L_add( Mpy_32_32( Cldfb_RealBuffer[2][j], real ), Mpy_32_32( Cldfb_ImagBuffer[2][j], img ) ) ); // output Q = 2 * Qx -31
908 576000 : move32();
909 : }
910 : }
911 :
912 9600 : return;
913 : }
914 : /*--------------------------------------------------------------------------*
915 : * computeIntensityVector_ana()
916 : *
917 : *
918 : *--------------------------------------------------------------------------*/
919 :
920 :
921 : /*--------------------------------------------------------------------------*
922 : * computeReferencePower_ana()
923 : *
924 : *
925 : *--------------------------------------------------------------------------*/
926 :
927 7200 : void computeReferencePower_ana_fx(
928 : const Word16 *band_grouping, /* i : Band grouping for estimation */
929 : Word32 Cldfb_RealBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i : Real part of input signal input_q */
930 : Word32 Cldfb_ImagBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i : Imag part of input signal input_q */
931 : Word32 *reference_power, /* o : Estimated power 2 * inputq - 31 */
932 : const Word16 num_freq_bands /* i : Number of frequency bands */
933 : )
934 : {
935 : Word16 brange[2];
936 : Word16 ch_idx, i, j;
937 :
938 180000 : FOR( i = 0; i < num_freq_bands; i++ )
939 : {
940 172800 : brange[0] = band_grouping[i];
941 172800 : move16();
942 172800 : brange[1] = band_grouping[i + 1];
943 172800 : move16();
944 172800 : reference_power[i] = 0;
945 172800 : move32();
946 :
947 864000 : FOR( ch_idx = 0; ch_idx < FOA_CHANNELS; ch_idx++ )
948 : {
949 : /* abs()^2 */
950 2419200 : FOR( j = brange[0]; j < brange[1]; j++ )
951 : {
952 : // Q = 2*inputq - 31
953 1728000 : reference_power[i] = L_add( L_add( Mpy_32_32( Cldfb_RealBuffer[ch_idx][j], Cldfb_RealBuffer[ch_idx][j] ), Mpy_32_32( Cldfb_ImagBuffer[ch_idx][j], Cldfb_ImagBuffer[ch_idx][j] ) ), reference_power[i] );
954 1728000 : move32();
955 : }
956 : }
957 : }
958 :
959 : // v_multc( reference_power, 0.5f, reference_power, num_freq_bands );
960 :
961 : /* Bypassing the v_multc ,so output q = 2*inputq - 30*/
962 7200 : return;
963 : }
964 :
965 : /*--------------------------------------------------------------------------*
966 : * computeReferencePower_ana()
967 : *
968 : *
969 : *--------------------------------------------------------------------------*/
|