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 : }
131 4 : FOR( i = 0; i < DIRAC_NUM_DIMS; i++ )
132 : {
133 99 : FOR( j = 0; j < DIRAC_NO_COL_AVG_DIFF; j++ )
134 : {
135 96 : IF( ( hDirAC->buffer_intensity_real_fx[i][j] = (Word32 *) malloc( MASA_FREQUENCY_BANDS * sizeof( Word32 ) ) ) == NULL )
136 : {
137 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MASA decoder\n" ) );
138 : }
139 96 : set32_fx( hDirAC->buffer_intensity_real_fx[i][j], 0, MASA_FREQUENCY_BANDS );
140 : }
141 : }
142 1 : set32_fx( hDirAC->buffer_energy_fx, 0, DIRAC_NO_COL_AVG_DIFF * MASA_FREQUENCY_BANDS );
143 :
144 1 : hDirAC->index_buffer_intensity = 0;
145 1 : move16();
146 :
147 1 : IF( ( hDirAC->hMasaOut = (MASA_DECODER_EXT_OUT_META_HANDLE) malloc( sizeof( MASA_DECODER_EXT_OUT_META ) ) ) == NULL )
148 : {
149 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MASA decoder\n" ) );
150 : }
151 :
152 1 : IF( ( hDirAC->sph_grid16 = (SPHERICAL_GRID_DATA *) malloc( sizeof( SPHERICAL_GRID_DATA ) ) ) == NULL )
153 : {
154 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MASA decoder\n" ) );
155 : }
156 1 : generate_gridEq_fx( hDirAC->sph_grid16 );
157 :
158 1 : ( *hDirACPtr ) = hDirAC;
159 :
160 1 : return error;
161 : }
162 :
163 :
164 : /*--------------------------------------------------------------------------*
165 : * ivas_dirac_ana_close()
166 : *
167 : * Close DIRAC handle
168 : *--------------------------------------------------------------------------*/
169 :
170 658 : void ivas_dirac_ana_close_fx(
171 : DIRAC_ANA_HANDLE( *hDirAC ) /* i/o: analysis DIRAC handle */
172 : )
173 : {
174 : Word16 i, j;
175 :
176 658 : test();
177 658 : IF( hDirAC == NULL || *hDirAC == NULL )
178 : {
179 657 : return;
180 : }
181 :
182 5 : FOR( i = 0; i < ( *hDirAC )->num_Cldfb_instances; i++ )
183 : {
184 4 : deleteCldfb_ivas_fx( &( ( *hDirAC )->cldfbAnaEnc[i] ) );
185 : }
186 :
187 4 : FOR( i = 0; i < DIRAC_NUM_DIMS; i++ )
188 : {
189 15 : FOR( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ )
190 : {
191 12 : free( ( *hDirAC )->direction_vector_m_fx[i][j] );
192 12 : ( *hDirAC )->direction_vector_m_fx[i][j] = NULL;
193 : }
194 3 : free( ( *hDirAC )->direction_vector_m_fx[i] );
195 3 : ( *hDirAC )->direction_vector_m_fx[i] = NULL;
196 :
197 99 : FOR( j = 0; j < DIRAC_NO_COL_AVG_DIFF; j++ )
198 : {
199 96 : free( ( *hDirAC )->buffer_intensity_real_fx[i][j] );
200 96 : ( *hDirAC )->buffer_intensity_real_fx[i][j] = NULL;
201 : }
202 : }
203 :
204 1 : free( ( *hDirAC )->hMasaOut );
205 1 : ( *hDirAC )->hMasaOut = NULL;
206 1 : free( ( *hDirAC )->sph_grid16 );
207 1 : ( *hDirAC )->sph_grid16 = NULL;
208 :
209 1 : free( ( *hDirAC ) );
210 1 : ( *hDirAC ) = NULL;
211 :
212 1 : return;
213 : }
214 :
215 :
216 : /*--------------------------------------------------------------------------*
217 : * ivas_dirac_ana()
218 : *
219 : * DIRAC analysis function
220 : *--------------------------------------------------------------------------*/
221 :
222 150 : void ivas_dirac_ana_fx(
223 : DIRAC_ANA_HANDLE hDirAC, /* i/o: DIRAC analysis handle */
224 : Word32 data_fx[][L_FRAME48k], /* i/o: Input / transport audio signals, Q7 */
225 : const Word16 input_frame, /* i : Input frame size */
226 : const Word16 nchan_transport /* i : Number of transport channels */
227 : )
228 : {
229 : Word32 elevation_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
230 : Word32 azimuth_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
231 : Word32 energyRatio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
232 : Word32 spreadCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
233 : Word32 surroundingCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
234 150 : Word16 energyRatio_q, surroundingCoherence_q = 0, spreadCoherence_q = 0;
235 150 : move16();
236 150 : move16();
237 : /* Estimate MASA parameters from the SBA signals */
238 150 : ivas_dirac_param_est_ana_fx( hDirAC, data_fx, elevation_m_values, azimuth_m_values, energyRatio, spreadCoherence, surroundingCoherence, input_frame );
239 150 : energyRatio_q = 30;
240 150 : move16();
241 : /* Create MASA metadata buffer from the estimated values */
242 150 : ivas_create_masa_out_meta_fx( hDirAC->hMasaOut, hDirAC->sph_grid16, nchan_transport, elevation_m_values, azimuth_m_values, energyRatio, spreadCoherence, surroundingCoherence, energyRatio_q, spreadCoherence_q, surroundingCoherence_q );
243 :
244 : /* Downmix */
245 150 : ivas_dirac_dmx_fx( data_fx, input_frame, nchan_transport ); // output Q of data_fx is same as that of input
246 :
247 150 : return;
248 : }
249 :
250 :
251 : /*--------------------------------------------------------------------------*
252 : * Local functions
253 : *--------------------------------------------------------------------------*/
254 :
255 : /* Estimate MASA parameters from the SBA signals */
256 150 : static void ivas_dirac_param_est_ana_fx(
257 : DIRAC_ANA_HANDLE hDirAC,
258 : Word32 data_fx[][L_FRAME48k], /* Q7 */
259 : Word32 elevation_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* Q22 */
260 : Word32 azimuth_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* Q22 */
261 : Word32 energyRatio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* Q30 */
262 : Word32 spreadCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* Qx */
263 : Word32 surroundingCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* Qx */
264 : const Word16 input_frame )
265 : {
266 : Word32 reference_power_fx[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
267 : Word16 ts, i, d, j;
268 : Word16 num_freq_bands, index;
269 : Word32 dir_v[DIRAC_NUM_DIMS];
270 : Word16 dir_q;
271 : Word16 l_ts;
272 : Word32 Foa_RealBuffer_fx[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX];
273 : Word32 Foa_ImagBuffer_fx[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX];
274 : Word32 intensity_real_fx[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS];
275 : Word32 direction_vector_fx[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS];
276 : Word16 diffuseness_vector_exp[MASA_FREQUENCY_BANDS];
277 : Word32 diffuseness_vector_fx[MASA_FREQUENCY_BANDS];
278 : Word32 diffuseness_m_fx[MASA_FREQUENCY_BANDS];
279 :
280 : Word16 band_m_idx, block_m_idx;
281 : Word32 renormalization_factor_diff_fx[MASA_FREQUENCY_BANDS];
282 : Word32 norm_tmp_fx;
283 : Word16 mrange[2];
284 : Word16 brange[2];
285 : Word16 numAnalysisChannels;
286 : Word16 io_q;
287 : Word16 scale_fact, scale_fact2;
288 150 : Word16 q_factor_intensity, q_factor_intensity_old = 0;
289 150 : Word16 q_factor_energy = 0, q_factor_energy_old = 0;
290 150 : Word16 exp = 0, exp_div = 0;
291 150 : num_freq_bands = hDirAC->nbands;
292 : /* l_ts = input_frame / CLDFB_NO_COL_MAX; */
293 150 : l_ts = shr( input_frame, 4 );
294 150 : numAnalysisChannels = FOA_CHANNELS;
295 150 : move16();
296 150 : move16();
297 150 : move16();
298 150 : move16();
299 150 : move16();
300 150 : move16();
301 150 : move16();
302 150 : move16();
303 :
304 : /* do processing over all CLDFB time slots */
305 750 : FOR( block_m_idx = 0; block_m_idx < MAX_PARAM_SPATIAL_SUBFRAMES; block_m_idx++ )
306 : {
307 600 : mrange[0] = hDirAC->block_grouping[block_m_idx];
308 600 : move16();
309 600 : mrange[1] = hDirAC->block_grouping[block_m_idx + 1];
310 600 : move16();
311 :
312 15000 : FOR( band_m_idx = 0; band_m_idx < hDirAC->nbands; band_m_idx++ )
313 : {
314 14400 : hDirAC->direction_vector_m_fx[0][block_m_idx][band_m_idx] = 0;
315 14400 : move32();
316 14400 : hDirAC->direction_vector_m_fx[1][block_m_idx][band_m_idx] = 0;
317 14400 : move32();
318 14400 : hDirAC->direction_vector_m_fx[2][block_m_idx][band_m_idx] = 0;
319 14400 : move32();
320 : }
321 :
322 : /* Need to initialize renormalization_factors, and variables to be normalized */
323 600 : set32_fx( renormalization_factor_diff_fx, 0, hDirAC->nbands );
324 600 : set32_fx( diffuseness_m_fx, 0, hDirAC->nbands );
325 600 : set32_fx( hDirAC->energy_fx[block_m_idx], 0, MASA_FREQUENCY_BANDS );
326 600 : set32_fx( hDirAC->energy_fx[block_m_idx], 0, MASA_FREQUENCY_BANDS );
327 :
328 3000 : FOR( ts = mrange[0]; ts < mrange[1]; ts++ )
329 : {
330 12000 : FOR( i = 0; i < numAnalysisChannels; i++ )
331 : {
332 9600 : io_q = Q7; // Input Q of data_fx
333 9600 : move16();
334 9600 : cldfbAnalysis_ts_fx_fixed_q( &( data_fx[i][imult1616( l_ts, ts )] ), Foa_RealBuffer_fx[i], Foa_ImagBuffer_fx[i], l_ts, hDirAC->cldfbAnaEnc[i], &io_q );
335 : }
336 2400 : scale_fact = getScaleFactor32( (const Word32 *) Foa_RealBuffer_fx, FOA_CHANNELS * CLDFB_NO_CHANNELS_MAX );
337 2400 : scale_fact = s_min( getScaleFactor32( (const Word32 *) Foa_ImagBuffer_fx, FOA_CHANNELS * CLDFB_NO_CHANNELS_MAX ), scale_fact );
338 9600 : FOR( i = 0; i < DIRAC_NUM_DIMS; i++ )
339 : {
340 180000 : FOR( j = 0; j < MASA_FREQUENCY_BANDS; j++ )
341 : {
342 172800 : Foa_RealBuffer_fx[i][j] = L_shl( Foa_RealBuffer_fx[i][j], sub( scale_fact, Q3 ) ); // Q( scale_fact + Q1 )
343 172800 : move32();
344 172800 : Foa_ImagBuffer_fx[i][j] = L_shl( Foa_ImagBuffer_fx[i][j], sub( scale_fact, Q3 ) ); // Q( scale_fact + Q1 )
345 172800 : move32();
346 : }
347 : }
348 : /* Compute omni energy for metadata processing */
349 60000 : FOR( band_m_idx = 0; band_m_idx < num_freq_bands; band_m_idx++ )
350 : {
351 57600 : brange[0] = hDirAC->band_grouping[band_m_idx];
352 57600 : move16();
353 57600 : brange[1] = hDirAC->band_grouping[band_m_idx + 1];
354 57600 : move16();
355 201600 : FOR( j = brange[0]; j < brange[1]; j++ )
356 : {
357 144000 : hDirAC->energy_fx[block_m_idx][band_m_idx] = ( L_add( hDirAC->energy_fx[block_m_idx][band_m_idx], L_add( Mpy_32_32( Foa_RealBuffer_fx[0][j], Foa_RealBuffer_fx[0][j] ), Mpy_32_32( Foa_ImagBuffer_fx[0][j], Foa_ImagBuffer_fx[0][j] ) ) ) ); // 2*( scale_fact + Q1 )-31
358 144000 : move32();
359 : }
360 : }
361 : /* Direction estimation */
362 2400 : computeIntensityVector_ana_fx( hDirAC->band_grouping, Foa_RealBuffer_fx, Foa_ImagBuffer_fx, num_freq_bands, intensity_real_fx ); // 2 * ( scale_fact + Q1 ) - 31
363 2400 : exp = sub( shl( sub( scale_fact, Q1 ), 1 ), 31 );
364 :
365 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], &exp );
366 :
367 : /* Power estimation for diffuseness */
368 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 );
369 :
370 : /* Fill buffers of length "averaging_length" time slots for intensity and energy */
371 2400 : hDirAC->index_buffer_intensity = add( ( hDirAC->index_buffer_intensity % DIRAC_NO_COL_AVG_DIFF ), 1 ); /* averaging_length = 32 */
372 2400 : move16();
373 2400 : index = hDirAC->index_buffer_intensity;
374 2400 : move16();
375 2400 : Word16 guard_bits = find_guarded_bits_fx( DIRAC_NO_COL_AVG_DIFF );
376 2400 : scale_fact2 = getScaleFactor32( (const Word32 *) intensity_real_fx, DIRAC_NUM_DIMS * MASA_FREQUENCY_BANDS );
377 2400 : IF( GT_16( guard_bits, scale_fact2 ) )
378 : {
379 0 : FOR( i = 0; i < DIRAC_NUM_DIMS; i++ )
380 : {
381 0 : FOR( j = 0; j < MASA_FREQUENCY_BANDS; j++ )
382 : {
383 0 : intensity_real_fx[i][j] = L_shr( intensity_real_fx[i][j], sub( guard_bits, scale_fact2 ) );
384 0 : move32();
385 : }
386 : }
387 0 : q_factor_intensity = sub( sub( shl( sub( scale_fact, 1 ), 1 ), 31 ), sub( guard_bits, scale_fact2 ) );
388 : }
389 : ELSE
390 : {
391 9600 : FOR( i = 0; i < DIRAC_NUM_DIMS; i++ )
392 : {
393 180000 : FOR( j = 0; j < MASA_FREQUENCY_BANDS; j++ )
394 : {
395 172800 : intensity_real_fx[i][j] = L_shl( intensity_real_fx[i][j], sub( scale_fact2, guard_bits ) );
396 172800 : move32();
397 : }
398 : }
399 2400 : q_factor_intensity = add( sub( shl( sub( scale_fact, 1 ), 1 ), 31 ), sub( scale_fact2, guard_bits ) );
400 : }
401 2400 : scale_fact2 = getScaleFactor32( reference_power_fx[ts], MASA_FREQUENCY_BANDS );
402 2400 : IF( GT_16( guard_bits, scale_fact2 ) )
403 : {
404 :
405 2300 : FOR( j = 0; j < MASA_FREQUENCY_BANDS; j++ )
406 : {
407 2208 : reference_power_fx[ts][j] = L_shr( reference_power_fx[ts][j], sub( guard_bits, scale_fact2 ) );
408 2208 : move32();
409 : }
410 :
411 92 : q_factor_energy = sub( sub( shl( scale_fact, 1 ), 31 ), sub( guard_bits, scale_fact2 ) );
412 : }
413 : ELSE
414 : {
415 57700 : FOR( j = 0; j < MASA_FREQUENCY_BANDS; j++ )
416 : {
417 55392 : reference_power_fx[ts][j] = L_shl( reference_power_fx[ts][j], sub( scale_fact2, guard_bits ) );
418 55392 : move32();
419 : }
420 :
421 2308 : q_factor_energy = add( sub( shl( scale_fact, 1 ), 31 ), sub( scale_fact2, guard_bits ) );
422 : }
423 :
424 2400 : IF( q_factor_intensity_old != 0 )
425 : {
426 :
427 2242 : IF( LT_16( q_factor_intensity_old, q_factor_intensity ) )
428 : {
429 6372 : FOR( i = 0; i < DIRAC_NUM_DIMS; i++ )
430 : {
431 119475 : FOR( j = 0; j < MASA_FREQUENCY_BANDS; j++ )
432 : {
433 114696 : intensity_real_fx[i][j] = L_shr( intensity_real_fx[i][j], sub( q_factor_intensity, q_factor_intensity_old ) );
434 114696 : move32();
435 : }
436 : }
437 1593 : q_factor_intensity = q_factor_intensity_old;
438 1593 : move16();
439 : }
440 : ELSE
441 : {
442 2596 : FOR( i = 0; i < DIRAC_NUM_DIMS; i++ )
443 : {
444 30144 : FOR( j = 0; j < index - 1; j++ )
445 : {
446 : /* only real part needed */
447 704925 : FOR( Word16 k = 0; k < num_freq_bands; k++ )
448 : {
449 676728 : hDirAC->buffer_intensity_real_fx[i][j][k] = L_shr( hDirAC->buffer_intensity_real_fx[i][j][k], sub( q_factor_intensity_old, q_factor_intensity ) );
450 676728 : move32();
451 : }
452 : }
453 : }
454 : }
455 : }
456 2400 : IF( q_factor_energy_old != 0 )
457 : {
458 :
459 2239 : IF( LT_16( q_factor_energy_old, q_factor_energy ) )
460 : {
461 :
462 89243 : FOR( j = 0; j < CLDFB_NO_CHANNELS_MAX; j++ )
463 : {
464 87780 : reference_power_fx[ts][j] = L_shr( reference_power_fx[ts][j], sub( q_factor_energy, q_factor_energy_old ) );
465 87780 : move32();
466 : }
467 :
468 1463 : q_factor_energy = q_factor_energy_old;
469 1463 : move16();
470 : }
471 : ELSE
472 : {
473 12075 : FOR( i = 0; i < index - 1; i++ )
474 : {
475 282475 : FOR( j = 0; j < num_freq_bands; j++ )
476 : {
477 6779400 : FOR( Word16 k = 0; k < num_freq_bands; k++ )
478 : {
479 6508224 : hDirAC->buffer_energy_fx[add( imult1616( i, j ), k )] = L_shr( hDirAC->buffer_energy_fx[add( imult1616( i, j ), k )], sub( q_factor_energy_old, q_factor_energy_old ) );
480 6508224 : move32();
481 : }
482 : }
483 : }
484 : }
485 : }
486 :
487 9600 : FOR( i = 0; i < DIRAC_NUM_DIMS; i++ )
488 : {
489 : /* only real part needed */
490 7200 : Copy32( intensity_real_fx[i], &( hDirAC->buffer_intensity_real_fx[i][index - 1][0] ), num_freq_bands );
491 : }
492 2400 : Copy32( reference_power_fx[ts], &( hDirAC->buffer_energy_fx[imult1616( sub( index, 1 ), num_freq_bands )] ), num_freq_bands );
493 :
494 2400 : computeDiffuseness_fx( hDirAC->buffer_intensity_real_fx, hDirAC->buffer_energy_fx, num_freq_bands, diffuseness_vector_fx, q_factor_intensity, q_factor_energy, diffuseness_vector_exp );
495 2400 : q_factor_intensity_old = q_factor_intensity;
496 2400 : move16();
497 2400 : q_factor_energy_old = q_factor_energy;
498 2400 : move16();
499 60000 : FOR( j = 0; j < MASA_FREQUENCY_BANDS; j++ )
500 : {
501 57600 : if ( LT_16( diffuseness_vector_exp[j], 10 ) )
502 : {
503 7665 : diffuseness_vector_fx[j] = 0;
504 7665 : move16();
505 : }
506 : }
507 :
508 60000 : FOR( band_m_idx = 0; band_m_idx < hDirAC->nbands; band_m_idx++ )
509 : {
510 57600 : norm_tmp_fx = Mpy_32_32( reference_power_fx[ts][band_m_idx], ( L_sub( ONE_IN_Q30, L_shr( diffuseness_vector_fx[band_m_idx], sub( 30, diffuseness_vector_exp[band_m_idx] ) ) ) ) ); // q_factor_energy-1
511 :
512 57600 : hDirAC->direction_vector_m_fx[0][block_m_idx][band_m_idx] = L_add( Mpy_32_32( norm_tmp_fx, direction_vector_fx[0][band_m_idx] ), hDirAC->direction_vector_m_fx[0][block_m_idx][band_m_idx] ); // Q (q_factor_energy + exp -32)
513 57600 : move32();
514 57600 : hDirAC->direction_vector_m_fx[1][block_m_idx][band_m_idx] = L_add( Mpy_32_32( norm_tmp_fx, direction_vector_fx[1][band_m_idx] ), hDirAC->direction_vector_m_fx[1][block_m_idx][band_m_idx] ); // Q (q_factor_energy + exp -32)
515 57600 : move32();
516 57600 : hDirAC->direction_vector_m_fx[2][block_m_idx][band_m_idx] = L_add( Mpy_32_32( norm_tmp_fx, direction_vector_fx[2][band_m_idx] ), hDirAC->direction_vector_m_fx[2][block_m_idx][band_m_idx] ); // Q (q_factor_energy + exp -32)
517 57600 : move32();
518 :
519 57600 : diffuseness_m_fx[band_m_idx] = L_add( diffuseness_m_fx[band_m_idx], Mpy_32_32( reference_power_fx[ts][band_m_idx], L_shr( diffuseness_vector_fx[band_m_idx], sub( 30, diffuseness_vector_exp[band_m_idx] ) ) ) ); // Qq_factor_energy-1
520 57600 : move32();
521 57600 : renormalization_factor_diff_fx[band_m_idx] = L_add( renormalization_factor_diff_fx[band_m_idx], reference_power_fx[ts][band_m_idx] ); // Qq_factor_energy
522 57600 : move32();
523 : }
524 : }
525 :
526 15000 : FOR( band_m_idx = 0; band_m_idx < hDirAC->nbands; band_m_idx++ )
527 : {
528 57600 : FOR( d = 0; d < DIRAC_NUM_DIMS; d++ )
529 : {
530 43200 : dir_v[d] = hDirAC->direction_vector_m_fx[d][block_m_idx][band_m_idx];
531 43200 : move32();
532 : }
533 14400 : dir_q = add( q_factor_energy, sub( exp, 32 ) );
534 14400 : ivas_qmetadata_direction_vector_to_azimuth_elevation_fx( dir_v, dir_q, &azimuth_m_values[block_m_idx][band_m_idx], &elevation_m_values[block_m_idx][band_m_idx] );
535 : }
536 : /* Determine energy ratios */
537 15000 : FOR( band_m_idx = 0; band_m_idx < hDirAC->nbands; band_m_idx++ )
538 : {
539 14400 : IF( GT_32( renormalization_factor_diff_fx[band_m_idx], EPSILON_FX ) )
540 : {
541 12601 : diffuseness_m_fx[band_m_idx] = BASOP_Util_Divide3232_Scale( diffuseness_m_fx[band_m_idx], renormalization_factor_diff_fx[band_m_idx], &exp_div );
542 12601 : move32();
543 : }
544 : ELSE
545 : {
546 1799 : diffuseness_m_fx[band_m_idx] = 0;
547 1799 : move32();
548 : }
549 14400 : exp_div = sub( 30, exp_div );
550 14400 : energyRatio[block_m_idx][band_m_idx] = L_sub( L_shl( 1, 30 ), L_shl( diffuseness_m_fx[band_m_idx], sub( 30, exp_div ) ) ); // Q30
551 14400 : move32();
552 : }
553 :
554 15000 : FOR( band_m_idx = 0; band_m_idx < hDirAC->nbands; band_m_idx++ )
555 : {
556 14400 : spreadCoherence[block_m_idx][band_m_idx] = 0;
557 14400 : move32();
558 14400 : surroundingCoherence[block_m_idx][band_m_idx] = 0;
559 14400 : move32();
560 : }
561 : }
562 :
563 150 : return;
564 : }
565 :
566 :
567 : /* Compute downmix */
568 150 : static void ivas_dirac_dmx_fx(
569 : Word32 data_in_fx[][L_FRAME48k], /* Qx (same as the input Q) */
570 : const Word16 input_frame,
571 : const Word16 nchan_transport )
572 : {
573 : Word16 i;
574 : Word32 data_out_fx[MASA_MAX_TRANSPORT_CHANNELS][L_FRAME48k];
575 :
576 150 : IF( EQ_16( nchan_transport, 2 ) )
577 : {
578 150 : v_add_fx( data_in_fx[0], data_in_fx[1], data_out_fx[0], input_frame );
579 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
580 :
581 : #ifdef VEC_ARITH_OPT_v1
582 150 : v_sub_fixed_no_hdrm( data_in_fx[0], data_in_fx[1], data_out_fx[1], input_frame );
583 : #else /* VEC_ARITH_OPT_v1 */
584 : v_sub_fixed( data_in_fx[0], data_in_fx[1], data_out_fx[1], input_frame, 0 );
585 : #endif /* VEC_ARITH_OPT_v1 */
586 150 : v_multc_fixed( data_out_fx[1], ONE_IN_Q30, data_out_fx[1], input_frame );
587 :
588 450 : FOR( i = 0; i < nchan_transport; i++ )
589 : {
590 300 : Copy32( data_out_fx[i], data_in_fx[i], input_frame );
591 : }
592 : }
593 : /* output Q is same as input Q*/
594 150 : return;
595 : }
|