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