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 "ivas_cnst.h"
36 : #include "ivas_prot_rend_fx.h"
37 : #include "prot_fx.h"
38 : #include "ivas_stat_rend.h"
39 : #include "ivas_rom_com.h"
40 : #include "wmc_auto.h"
41 : #include "ivas_prot_fx.h"
42 :
43 : /*-------------------------------------------------------------------------
44 : * Local function prototypes
45 : *------------------------------------------------------------------------*/
46 : static void ivas_dirac_param_est_ana_fx( DIRAC_ANA_HANDLE hDirAC, Word32 data_f[][L_FRAME48k], Word32 elevation_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], Word32 azimuth_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], Word32 energyRatio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], Word32 spreadCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], Word32 surroundingCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], const Word16 input_frame );
47 : static void ivas_dirac_dmx_fx( Word32 data_in_fx[][L_FRAME48k], const Word16 input_frame, const Word16 nchan_transport );
48 :
49 :
50 : /*--------------------------------------------------------------------------*
51 : * ivas_dirac_ana_open()
52 : *
53 : * Allocate and initialize DIRAC handle
54 : *--------------------------------------------------------------------------*/
55 :
56 1 : ivas_error ivas_dirac_ana_open_fx(
57 : DIRAC_ANA_HANDLE *hDirACPtr, /* i/o: DIRAC data handle pointer */
58 : Word32 input_Fs /* i : Sampling frequency */
59 : )
60 : {
61 : Word16 i, j;
62 : DIRAC_ANA_HANDLE hDirAC;
63 : Word16 numAnalysisChannels;
64 : Word16 maxBin;
65 : ivas_error error;
66 :
67 1 : error = IVAS_ERR_OK;
68 1 : move16();
69 :
70 1 : IF( ( hDirAC = (DIRAC_ANA_HANDLE) malloc( sizeof( DIRAC_ANA_DATA ) ) ) == NULL )
71 : {
72 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DIRAC\n" ) );
73 : }
74 :
75 1 : numAnalysisChannels = FOA_CHANNELS;
76 1 : move16();
77 :
78 : /* Determine the number of bands */
79 1 : hDirAC->nbands = MASA_FREQUENCY_BANDS;
80 1 : move16();
81 :
82 : /* Determine band grouping */
83 1 : Copy( MASA_band_grouping_24, hDirAC->band_grouping, 24 + 1 );
84 :
85 : // maxBin = (int16_t) ( input_Fs * INV_CLDFB_BANDWIDTH + 0.5f );
86 1 : Word32 n_input_Fs = L_shl( input_Fs, 1 );
87 1 : Word32 val = L_add( Mpy_32_16_1( n_input_Fs, 41 /* INV_CLDFB_BANDWIDTH in Q15 */ ), 1 );
88 1 : val = L_shr( val, 1 );
89 1 : maxBin = extract_l( val );
90 24 : FOR( i = 1; i < hDirAC->nbands + 1; i++ )
91 : {
92 24 : IF( GE_16( hDirAC->band_grouping[i], maxBin ) )
93 : {
94 1 : hDirAC->band_grouping[i] = maxBin;
95 1 : move16();
96 1 : hDirAC->nbands = i;
97 1 : move16();
98 1 : BREAK;
99 : }
100 : }
101 :
102 : /* Determine block grouping */
103 1 : Copy( DirAC_block_grouping, hDirAC->block_grouping, MAX_PARAM_SPATIAL_SUBFRAMES + 1 );
104 :
105 : /* open/initialize CLDFB */
106 1 : hDirAC->num_Cldfb_instances = numAnalysisChannels;
107 1 : move16();
108 5 : FOR( i = 0; i < hDirAC->num_Cldfb_instances; i++ )
109 : {
110 4 : IF( NE_32( ( error = openCldfb_ivas_fx( &( hDirAC->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS, DEC ) ), IVAS_ERR_OK ) )
111 : {
112 0 : return error;
113 : }
114 : }
115 4 : FOR( i = 0; i < DIRAC_NUM_DIMS; i++ )
116 : {
117 3 : IF( ( hDirAC->direction_vector_m_fx[i] = (Word32 **) malloc( MAX_PARAM_SPATIAL_SUBFRAMES * sizeof( Word32 * ) ) ) == NULL )
118 : {
119 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MASA decoder\n" ) );
120 : }
121 :
122 15 : FOR( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ )
123 : {
124 12 : IF( ( hDirAC->direction_vector_m_fx[i][j] = (Word32 *) malloc( MASA_FREQUENCY_BANDS * sizeof( Word32 ) ) ) == NULL )
125 : {
126 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MASA decoder\n" ) );
127 : }
128 12 : set32_fx( hDirAC->direction_vector_m_fx[i][j], 0, MASA_FREQUENCY_BANDS );
129 : }
130 3 : IF( ( hDirAC->direction_vector_e[i] = (Word16 **) malloc( MAX_PARAM_SPATIAL_SUBFRAMES * sizeof( Word16 * ) ) ) == NULL )
131 : {
132 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for OMASA data\n" ) );
133 : }
134 :
135 15 : FOR( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ )
136 : {
137 12 : IF( ( hDirAC->direction_vector_e[i][j] = (Word16 *) malloc( MASA_FREQUENCY_BANDS * sizeof( Word16 ) ) ) == NULL )
138 : {
139 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for OMASA data\n" ) );
140 : }
141 12 : set16_fx( hDirAC->direction_vector_e[i][j], 31, MASA_FREQUENCY_BANDS );
142 : }
143 : }
144 :
145 4 : FOR( i = 0; i < DIRAC_NUM_DIMS; i++ )
146 : {
147 99 : FOR( j = 0; j < DIRAC_NO_COL_AVG_DIFF; j++ )
148 : {
149 96 : IF( ( hDirAC->buffer_intensity_real_fx[i][j] = (Word32 *) malloc( MASA_FREQUENCY_BANDS * sizeof( Word32 ) ) ) == NULL )
150 : {
151 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MASA decoder\n" ) );
152 : }
153 96 : set32_fx( hDirAC->buffer_intensity_real_fx[i][j], 0, MASA_FREQUENCY_BANDS );
154 : }
155 : }
156 1 : set32_fx( hDirAC->buffer_energy_fx, 0, DIRAC_NO_COL_AVG_DIFF * MASA_FREQUENCY_BANDS );
157 1 : set16_fx( hDirAC->buffer_intensity_real_q, 31, DIRAC_NO_COL_AVG_DIFF );
158 1 : set16_fx( hDirAC->buffer_energy_q, 31, DIRAC_NO_COL_AVG_DIFF );
159 1 : hDirAC->index_buffer_intensity = 0;
160 1 : move16();
161 :
162 1 : IF( ( hDirAC->hMasaOut = (MASA_DECODER_EXT_OUT_META_HANDLE) malloc( sizeof( MASA_DECODER_EXT_OUT_META ) ) ) == NULL )
163 : {
164 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MASA decoder\n" ) );
165 : }
166 :
167 1 : IF( ( hDirAC->sph_grid16 = (SPHERICAL_GRID_DATA *) malloc( sizeof( SPHERICAL_GRID_DATA ) ) ) == NULL )
168 : {
169 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MASA decoder\n" ) );
170 : }
171 1 : generate_gridEq_fx( hDirAC->sph_grid16 );
172 :
173 1 : ( *hDirACPtr ) = hDirAC;
174 :
175 1 : return error;
176 : }
177 :
178 :
179 : /*--------------------------------------------------------------------------*
180 : * ivas_dirac_ana_close()
181 : *
182 : * Close DIRAC handle
183 : *--------------------------------------------------------------------------*/
184 :
185 666 : void ivas_dirac_ana_close_fx(
186 : DIRAC_ANA_HANDLE( *hDirAC ) /* i/o: analysis DIRAC handle */
187 : )
188 : {
189 : Word16 i, j;
190 :
191 666 : test();
192 666 : IF( hDirAC == NULL || *hDirAC == NULL )
193 : {
194 665 : return;
195 : }
196 :
197 5 : FOR( i = 0; i < ( *hDirAC )->num_Cldfb_instances; i++ )
198 : {
199 4 : deleteCldfb_ivas_fx( &( ( *hDirAC )->cldfbAnaEnc[i] ) );
200 : }
201 :
202 4 : FOR( i = 0; i < DIRAC_NUM_DIMS; i++ )
203 : {
204 15 : FOR( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ )
205 : {
206 12 : free( ( *hDirAC )->direction_vector_m_fx[i][j] );
207 12 : ( *hDirAC )->direction_vector_m_fx[i][j] = NULL;
208 : }
209 3 : free( ( *hDirAC )->direction_vector_m_fx[i] );
210 3 : ( *hDirAC )->direction_vector_m_fx[i] = NULL;
211 :
212 15 : FOR( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ )
213 : {
214 12 : free( ( *hDirAC )->direction_vector_e[i][j] );
215 12 : ( *hDirAC )->direction_vector_e[i][j] = NULL;
216 : }
217 :
218 3 : free( ( *hDirAC )->direction_vector_e[i] );
219 3 : ( *hDirAC )->direction_vector_e[i] = NULL;
220 :
221 99 : FOR( j = 0; j < DIRAC_NO_COL_AVG_DIFF; j++ )
222 : {
223 96 : free( ( *hDirAC )->buffer_intensity_real_fx[i][j] );
224 96 : ( *hDirAC )->buffer_intensity_real_fx[i][j] = NULL;
225 : }
226 : }
227 :
228 1 : free( ( *hDirAC )->hMasaOut );
229 1 : ( *hDirAC )->hMasaOut = NULL;
230 1 : free( ( *hDirAC )->sph_grid16 );
231 1 : ( *hDirAC )->sph_grid16 = NULL;
232 :
233 1 : free( ( *hDirAC ) );
234 1 : ( *hDirAC ) = NULL;
235 :
236 1 : return;
237 : }
238 :
239 :
240 : /*--------------------------------------------------------------------------*
241 : * ivas_dirac_ana()
242 : *
243 : * DIRAC analysis function
244 : *--------------------------------------------------------------------------*/
245 :
246 150 : void ivas_dirac_ana_fx(
247 : DIRAC_ANA_HANDLE hDirAC, /* i/o: DIRAC analysis handle */
248 : Word32 data_fx[][L_FRAME48k], /* i/o: Input / transport audio signals, Q7 */
249 : const Word16 input_frame, /* i : Input frame size */
250 : const Word16 nchan_transport /* i : Number of transport channels */
251 : )
252 : {
253 : Word32 elevation_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
254 : Word32 azimuth_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
255 : Word32 energyRatio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
256 : Word32 spreadCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
257 : Word32 surroundingCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
258 : /* Estimate MASA parameters from the SBA signals */
259 150 : ivas_dirac_param_est_ana_fx( hDirAC, data_fx, elevation_m_values, azimuth_m_values, energyRatio, spreadCoherence, surroundingCoherence, input_frame );
260 : /* Create MASA metadata buffer from the estimated values */
261 :
262 150 : ivas_create_masa_out_meta_fx( hDirAC->hMasaOut, hDirAC->sph_grid16, nchan_transport, elevation_m_values, azimuth_m_values, energyRatio, spreadCoherence, surroundingCoherence, Q31, Q31, Q31 );
263 :
264 : /* Downmix */
265 150 : ivas_dirac_dmx_fx( data_fx, input_frame, nchan_transport ); // output Q of data_fx is same as that of input
266 :
267 150 : return;
268 : }
269 :
270 :
271 : /*--------------------------------------------------------------------------*
272 : * Local functions
273 : *--------------------------------------------------------------------------*/
274 :
275 : /* Estimate MASA parameters from the SBA signals */
276 150 : static void ivas_dirac_param_est_ana_fx(
277 : DIRAC_ANA_HANDLE hDirAC,
278 : Word32 data_fx[][L_FRAME48k], /* Q7 */
279 : Word32 elevation_m_values_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* Q22 */
280 : Word32 azimuth_m_values_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* Q22 */
281 : Word32 energyRatio_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* Q30 */
282 : Word32 spreadCoherence_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* Qx */
283 : Word32 surroundingCoherence_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* Qx */
284 : const Word16 input_frame )
285 : {
286 : Word32 reference_power_fx[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
287 : Word16 ts, i, d, j;
288 : Word16 num_freq_bands, index;
289 : Word32 dir_v_fx[DIRAC_NUM_DIMS];
290 : Word16 dir_v_q;
291 : Word16 l_ts;
292 : Word32 Foa_RealBuffer_fx[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX];
293 : Word32 Foa_ImagBuffer_fx[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX];
294 : Word32 intensity_real_fx[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS];
295 : Word32 direction_vector_fx[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS];
296 : Word32 diffuseness_vector_fx[MASA_FREQUENCY_BANDS];
297 : Word32 diffuseness_m_fx[MASA_FREQUENCY_BANDS];
298 : Word16 diffuseness_e[MASA_FREQUENCY_BANDS];
299 150 : Word16 diffuseness_q = 0;
300 150 : move16();
301 : Word16 band_m_idx, block_m_idx;
302 : Word32 renormalization_factor_diff_fx[MASA_FREQUENCY_BANDS];
303 : Word16 renormalization_factor_diff_e[MASA_FREQUENCY_BANDS];
304 : Word32 norm_tmp_fx;
305 : Word16 mrange[2];
306 : Word16 brange[2];
307 : Word16 numAnalysisChannels;
308 : Word16 inp_q;
309 : Word16 intensity_q, reference_power_q;
310 150 : num_freq_bands = hDirAC->nbands;
311 : /* l_ts = input_frame / CLDFB_NO_COL_MAX; */
312 150 : l_ts = shr( input_frame, 4 );
313 150 : numAnalysisChannels = FOA_CHANNELS;
314 150 : move16();
315 150 : move16();
316 150 : move16();
317 150 : move16();
318 150 : move16();
319 150 : move16();
320 150 : move16();
321 150 : move16();
322 :
323 : /* do processing over all CLDFB time slots */
324 750 : FOR( block_m_idx = 0; block_m_idx < MAX_PARAM_SPATIAL_SUBFRAMES; block_m_idx++ )
325 : {
326 600 : mrange[0] = hDirAC->block_grouping[block_m_idx];
327 600 : move16();
328 600 : mrange[1] = hDirAC->block_grouping[block_m_idx + 1];
329 600 : move16();
330 :
331 15000 : FOR( band_m_idx = 0; band_m_idx < hDirAC->nbands; band_m_idx++ )
332 : {
333 14400 : hDirAC->direction_vector_m_fx[0][block_m_idx][band_m_idx] = 0;
334 14400 : move32();
335 14400 : hDirAC->direction_vector_m_fx[1][block_m_idx][band_m_idx] = 0;
336 14400 : move32();
337 14400 : hDirAC->direction_vector_m_fx[2][block_m_idx][band_m_idx] = 0;
338 14400 : move32();
339 :
340 14400 : hDirAC->direction_vector_e[0][block_m_idx][band_m_idx] = 0;
341 14400 : move16();
342 14400 : hDirAC->direction_vector_e[1][block_m_idx][band_m_idx] = 0;
343 14400 : move16();
344 14400 : hDirAC->direction_vector_e[2][block_m_idx][band_m_idx] = 0;
345 14400 : move16();
346 : }
347 :
348 : /* Need to initialize renormalization_factors, and variables to be normalized */
349 600 : set32_fx( renormalization_factor_diff_fx, 0, hDirAC->nbands );
350 600 : set16_fx( renormalization_factor_diff_e, 31, hDirAC->nbands );
351 600 : set32_fx( diffuseness_m_fx, 0, hDirAC->nbands );
352 600 : set16_fx( diffuseness_e, 0, hDirAC->nbands );
353 600 : set32_fx( hDirAC->energy_fx[block_m_idx], 0, MASA_FREQUENCY_BANDS );
354 600 : set16_fx( hDirAC->energy_e[block_m_idx], 0, MASA_FREQUENCY_BANDS );
355 :
356 3000 : FOR( ts = mrange[0]; ts < mrange[1]; ts++ )
357 : {
358 2400 : Word16 cr_q = MAX_16, ci_q = MAX_16, sf, c_e;
359 2400 : inp_q = Q7; // Input Q of data_fx
360 2400 : move16();
361 2400 : move16();
362 2400 : move16();
363 12000 : FOR( i = 0; i < numAnalysisChannels; i++ )
364 : {
365 9600 : inp_q = Q7;
366 9600 : move16();
367 9600 : cldfbAnalysis_ts_fx_var_q( &( data_fx[i][l_ts * ts] ), Foa_RealBuffer_fx[i], Foa_ImagBuffer_fx[i], l_ts, hDirAC->cldfbAnaEnc[i], &inp_q );
368 9600 : cr_q = s_min( cr_q, getScaleFactor32( Foa_RealBuffer_fx[i], CLDFB_NO_CHANNELS_MAX ) );
369 9600 : ci_q = s_min( ci_q, getScaleFactor32( Foa_ImagBuffer_fx[i], CLDFB_NO_CHANNELS_MAX ) );
370 : }
371 2400 : sf = sub( s_min( cr_q, ci_q ), 4 );
372 12000 : FOR( i = 0; i < numAnalysisChannels; i++ )
373 : {
374 9600 : scale_sig32( Foa_RealBuffer_fx[i], CLDFB_NO_CHANNELS_MAX, sf ); // Q-> inp_q + sf
375 9600 : scale_sig32( Foa_ImagBuffer_fx[i], CLDFB_NO_CHANNELS_MAX, sf ); // Q-> inp_q + sf
376 : }
377 2400 : inp_q = add( inp_q, sf );
378 2400 : c_e = sub( 31, inp_q );
379 : /* Compute omni energy for metadata processing */
380 60000 : FOR( band_m_idx = 0; band_m_idx < num_freq_bands; band_m_idx++ )
381 : {
382 57600 : brange[0] = hDirAC->band_grouping[band_m_idx];
383 57600 : move16();
384 57600 : brange[1] = hDirAC->band_grouping[band_m_idx + 1];
385 57600 : move16();
386 201600 : FOR( j = brange[0]; j < brange[1]; j++ )
387 : {
388 144000 : Word32 temp = L_add( Mult_32_32( Foa_RealBuffer_fx[0][j], Foa_RealBuffer_fx[0][j] ), Mult_32_32( Foa_ImagBuffer_fx[0][j], Foa_ImagBuffer_fx[0][j] ) ); // Q-> 2*inp_q - 31, e = 31 - (2*inp_q - 31) = 62 - 2*inp_q = 2*(31 - inp_q) = 2*c_e
389 144000 : hDirAC->energy_fx[block_m_idx][band_m_idx] = BASOP_Util_Add_Mant32Exp( hDirAC->energy_fx[block_m_idx][band_m_idx], hDirAC->energy_e[block_m_idx][band_m_idx], temp, shl( c_e, 1 ), &hDirAC->energy_e[block_m_idx][band_m_idx] );
390 144000 : move32();
391 : }
392 : }
393 : /* Direction estimation */
394 2400 : computeIntensityVector_ana_fx( hDirAC->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 */
395 2400 : intensity_q = sub( 31, shl( c_e, 1 ) );
396 :
397 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 );
398 : /* Power estimation for diffuseness */
399 2400 : computeReferencePower_ana_fx( hDirAC->band_grouping, Foa_RealBuffer_fx, Foa_ImagBuffer_fx, reference_power_fx[ts], num_freq_bands ); //( 2 * ( scale_fact - Q1 ) - 31 - 1 ); // computeReferencePower_ana( hDirAC->band_grouping, Foa_RealBuffer, Foa_ImagBuffer, reference_power[ts], num_freq_bands );
400 2400 : reference_power_q = sub( shl( inp_q, 1 ), 30 );
401 : /* Fill buffers of length "averaging_length" time slots for intensity and energy */
402 2400 : hDirAC->index_buffer_intensity = add( ( hDirAC->index_buffer_intensity % DIRAC_NO_COL_AVG_DIFF ), 1 ); /* averaging_length = 32 */
403 2400 : move16();
404 2400 : index = hDirAC->index_buffer_intensity;
405 2400 : move16();
406 9600 : FOR( i = 0; i < DIRAC_NUM_DIMS; i++ )
407 : {
408 : /* only real part needed */
409 7200 : Copy32( intensity_real_fx[i], &( hDirAC->buffer_intensity_real_fx[i][index - 1][0] ), num_freq_bands ); // intensity_q
410 : }
411 2400 : hDirAC->buffer_intensity_real_q[index - 1] = intensity_q;
412 2400 : move16();
413 2400 : Copy32( reference_power_fx[ts], &( hDirAC->buffer_energy_fx[( index - 1 ) * num_freq_bands] ), num_freq_bands );
414 2400 : hDirAC->buffer_energy_q[index - 1] = reference_power_q;
415 2400 : move16();
416 2400 : computeDiffuseness_fixed( hDirAC->buffer_intensity_real_fx, hDirAC->buffer_energy_fx, num_freq_bands, diffuseness_vector_fx, hDirAC->buffer_intensity_real_q, hDirAC->buffer_energy_q, &diffuseness_q );
417 :
418 60000 : FOR( band_m_idx = 0; band_m_idx < hDirAC->nbands; band_m_idx++ )
419 : {
420 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*/
421 :
422 57600 : hDirAC->direction_vector_m_fx[0][block_m_idx][band_m_idx] = BASOP_Util_Add_Mant32Exp( hDirAC->direction_vector_m_fx[0][block_m_idx][band_m_idx], hDirAC->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 ), &hDirAC->direction_vector_e[0][block_m_idx][band_m_idx] );
423 57600 : move32();
424 57600 : hDirAC->direction_vector_m_fx[1][block_m_idx][band_m_idx] = BASOP_Util_Add_Mant32Exp( hDirAC->direction_vector_m_fx[1][block_m_idx][band_m_idx], hDirAC->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 ), &hDirAC->direction_vector_e[1][block_m_idx][band_m_idx] );
425 57600 : move32();
426 57600 : hDirAC->direction_vector_m_fx[2][block_m_idx][band_m_idx] = BASOP_Util_Add_Mant32Exp( hDirAC->direction_vector_m_fx[2][block_m_idx][band_m_idx], hDirAC->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 ), &hDirAC->direction_vector_e[2][block_m_idx][band_m_idx] );
427 57600 : move32();
428 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] );
429 57600 : move32();
430 :
431 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] );
432 57600 : move32();
433 : }
434 : }
435 15000 : FOR( band_m_idx = 0; band_m_idx < hDirAC->nbands; band_m_idx++ )
436 : {
437 14400 : Word16 max_e = MIN_16;
438 14400 : move16();
439 57600 : FOR( d = 0; d < DIRAC_NUM_DIMS; d++ )
440 : {
441 43200 : max_e = s_max( max_e, hDirAC->direction_vector_e[d][block_m_idx][band_m_idx] );
442 : }
443 14400 : max_e = add( max_e, 1 ); /*1 as guard bit to prevent overflow*/
444 57600 : FOR( d = 0; d < DIRAC_NUM_DIMS; d++ )
445 : {
446 43200 : dir_v_fx[d] = L_shr( hDirAC->direction_vector_m_fx[d][block_m_idx][band_m_idx], sub( max_e, hDirAC->direction_vector_e[d][block_m_idx][band_m_idx] ) );
447 43200 : move32();
448 : }
449 14400 : dir_v_q = sub( 31, max_e );
450 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] );
451 : }
452 : /* Determine energy ratios */
453 15000 : FOR( band_m_idx = 0; band_m_idx < hDirAC->nbands; band_m_idx++ )
454 : {
455 : Word16 diffuseness_m_e;
456 14400 : IF( GT_32( renormalization_factor_diff_fx[band_m_idx], EPSILON_FX ) )
457 : {
458 14362 : 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 );
459 14362 : move32();
460 14362 : diffuseness_m_e = add( diffuseness_m_e, sub( diffuseness_e[band_m_idx], renormalization_factor_diff_e[band_m_idx] ) );
461 14362 : diffuseness_m_fx[band_m_idx] = L_shl_sat( diffuseness_m_fx[band_m_idx], add( 16, diffuseness_m_e ) ); // Q31
462 14362 : move32();
463 : }
464 : ELSE
465 : {
466 38 : diffuseness_m_fx[band_m_idx] = 0;
467 38 : move32();
468 : }
469 14400 : energyRatio_fx[block_m_idx][band_m_idx] = L_sub( ONE_IN_Q31, diffuseness_m_fx[band_m_idx] );
470 14400 : move32();
471 : }
472 15000 : FOR( band_m_idx = 0; band_m_idx < hDirAC->nbands; band_m_idx++ )
473 : {
474 14400 : spreadCoherence_fx[block_m_idx][band_m_idx] = 0;
475 14400 : move32();
476 14400 : surroundingCoherence_fx[block_m_idx][band_m_idx] = 0;
477 14400 : move32();
478 : }
479 : }
480 :
481 150 : return;
482 : }
483 :
484 :
485 : /* Compute downmix */
486 150 : static void ivas_dirac_dmx_fx(
487 : Word32 data_in_fx[][L_FRAME48k], /* Qx (same as the input Q) */
488 : const Word16 input_frame,
489 : const Word16 nchan_transport )
490 : {
491 : Word16 i;
492 : Word32 data_out_fx[MASA_MAX_TRANSPORT_CHANNELS][L_FRAME48k];
493 :
494 150 : IF( EQ_16( nchan_transport, 2 ) )
495 : {
496 150 : v_add_fx( data_in_fx[0], data_in_fx[1], data_out_fx[0], input_frame );
497 150 : v_multc_fixed( data_out_fx[0], ONE_IN_Q30, data_out_fx[0], input_frame ); // ONE_IN_Q30 = 0.5* ONE_IN_Q31
498 :
499 150 : v_sub_fixed_no_hdrm( data_in_fx[0], data_in_fx[1], data_out_fx[1], input_frame );
500 150 : v_multc_fixed( data_out_fx[1], ONE_IN_Q30, data_out_fx[1], input_frame );
501 :
502 450 : FOR( i = 0; i < nchan_transport; i++ )
503 : {
504 300 : Copy32( data_out_fx[i], data_in_fx[i], input_frame );
505 : }
506 : }
507 : /* output Q is same as input Q*/
508 150 : return;
509 : }
|