Line data Source code
1 : /******************************************************************************************************
2 :
3 : (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
4 : Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
5 : Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
6 : Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
7 : contributors to this repository. All Rights Reserved.
8 :
9 : This software is protected by copyright law and by international treaties.
10 : The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
11 : Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
12 : Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
13 : Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
14 : contributors to this repository retain full ownership rights in their respective contributions in
15 : the software. This notice grants no license of any kind, including but not limited to patent
16 : license, nor is any license granted by implication, estoppel or otherwise.
17 :
18 : Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
19 : contributions.
20 :
21 : This software is provided "AS IS", without any express or implied warranties. The software is in the
22 : development stage. It is intended exclusively for experts who have experience with such software and
23 : solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
24 : and fitness for a particular purpose are hereby disclaimed and excluded.
25 :
26 : Any dispute, controversy or claim arising under or in relation to providing this software shall be
27 : submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
28 : accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
29 : the United Nations Convention on Contracts on the International Sales of Goods.
30 :
31 : *******************************************************************************************************/
32 :
33 : #include <assert.h>
34 : #include <stdint.h>
35 : #include "options.h"
36 : #include <math.h>
37 : #include "cnst.h"
38 : #include "prot_fx.h"
39 : #include "ivas_prot_rend_fx.h"
40 : #include "ivas_stat_dec.h"
41 : #include "ivas_cnst.h"
42 : #include "ivas_rom_com.h"
43 : #include "ivas_rom_dec.h"
44 : #include "wmc_auto.h"
45 : #include "ivas_prot_fx.h"
46 : #include "ivas_rom_com_fx.h"
47 :
48 : /*-------------------------------------------------------------------------
49 : * Local constants
50 : *------------------------------------------------------------------------*/
51 :
52 : #define DIRAC_AVG_LENGTH_SYNTH_MS 20 /*averaging length in ms for DirAC synthesis*/
53 : #define DIRAC_ALPHA_MAX_Q15 3276 /*0.1f q15*/
54 : #define DIRAC_AVG_LENGTH_SYNTH_MS_FAST 10
55 : #define DIRAC_ALPHA_MAX_FAST_Q15 3932 /*0.12f q15*/
56 : #define DIRECTION_SMOOTHNESS_ALPHA_Q31 ( 21474836 ) /*0.01f q31*/
57 :
58 : #define POINT_3679_Q31 790059234 /*.3679 q31*/
59 : #define POINT_1175_Q31 252329329 /*.1175 q31*/
60 :
61 : /*-------------------------------------------------------------------------
62 : * Local function prototypes
63 : *------------------------------------------------------------------------*/
64 :
65 : static void computeTargetPSDs_direct_fx( const Word16 num_channels, const Word16 num_freq_bands, const Word32 *direct_power_factor, const Word32 *reference_power, const Word16 *q_reference_power, const Word32 *direct_responses, const Word32 *direct_responses_square, Word32 *cy_auto_dir_smooth, Word16 *q_cy_auto_dir_smooth, Word32 *cy_cross_dir_smooth, Word16 *q_cy_cross_dir_smooth );
66 :
67 : static void computeTargetPSDs_direct_subframe_fx( const Word16 num_channels, const Word16 num_freq_bands, const Word32 *direct_power_factor, const Word32 *reference_power, const Word16 *q_reference_power, const Word32 *direct_responses, const Word32 *direct_responses_square, Word32 *cy_auto_dir_smooth, Word16 *q_cy_auto_dir_smooth, Word32 *cy_cross_dir_smooth, Word16 *q_cy_cross_dir_smooth );
68 :
69 : static void computeTargetPSDs_diffuse_fx( const Word16 num_channels, const Word16 num_freq_bands, const Word16 start_band, const Word32 *diffuse_power_factor, const Word32 *reference_power, const Word16 *q_reference_power, const Word32 *diffuse_responses_square, Word32 *cy_auto_diff_smooth, Word16 *q_cy_auto_diff_smooth );
70 :
71 : static void computeTargetPSDs_diffuse_subframe_fx( const Word16 num_channels, const Word16 num_freq_bands, const Word16 start_band, const Word32 *diffuse_power_factor, const Word32 *reference_power, const Word16 *q_reference_power, const Word32 *diffuse_responses_square, Word32 *cy_auto_diff_smooth, Word16 *q_cy_auto_diff_smooth );
72 :
73 : static void computeTargetPSDs_diffuse_with_onsets_fx( const Word16 num_channels, const Word16 num_freq_bands, const Word16 num_decorr_freq_bands, const Word16 *proto_frame_diff_index, const Word32 *diffuse_power_factor, const Word32 *reference_power, const Word16 *q_reference_power, const Word32 *diffuse_responses_square, const Word32 *onset_filter, Word32 *cy_auto_diff_smooth, Word16 *q_cy_auto_diff_smooth );
74 :
75 : static void computeAlphaSynthesis_fx( Word16 *alpha_synthesis_fx /*q15*/, const Word16 averaging_length_ms, const Word16 maxAlpha_fx /*q15*/, Word16 *numAlphas, const Word16 slot_size, const Word16 num_freq_bands, Word16 *frequency_axis_fx /*q0*/, const Word32 output_Fs );
76 :
77 : static void spreadCoherencePanningHoa_fx( const Word16 azimuth, const Word16 elevation, const Word16 spreadCoh_fx, Word32 *direct_response_fx, Word16 *Q_direct_response_hoa, const Word16 num_channels_dir, const Word16 ambisonics_order );
78 :
79 : static void spreadCoherencePanningVbap_fx( const Word16 azimuth, const Word16 elevation, const Word16 spreadCoh_fx, Word32 *direct_response_fx, Word16 *Q_direct_response, const Word16 num_channels_dir, const VBAP_HANDLE hVBAPdata );
80 :
81 : static void normalizePanningGains_fx( Word32 *direct_response_fx, Word16 *q_direct_res, const Word16 num_channels_dir );
82 :
83 :
84 : /*-------------------------------------------------------------------------
85 : * ivas_dirac_dec_output_synthesis_open()
86 : *
87 : *
88 : *------------------------------------------------------------------------*/
89 :
90 2153 : ivas_error ivas_dirac_dec_output_synthesis_open_fx(
91 : SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common spatial renderer data handle */
92 : DIRAC_REND_HANDLE hDirACRend, /* i/o: DirAC renderer handle */
93 : RENDERER_TYPE renderer_type, /* i : renderer type */
94 : const Word16 nchan_transport, /* i : number of transport channels */
95 : const Word32 output_Fs, /* i : output sampling rate */
96 : const Word16 hodirac_flag /* i : flag to indicate HO-DirAC mode */
97 : )
98 : {
99 : Word16 idx, ch_idx;
100 : Word16 size;
101 : UWord16 num_diffuse_responses;
102 : Word16 tmp_fx, tmp16;
103 : Word16 temp_alpha_synthesis_fx[CLDFB_NO_CHANNELS_MAX];
104 2153 : Word16 interpolator_tbl[JBM_CLDFB_SLOTS_IN_SUBFRAME] = { 8192, 16384, 24576, MAX16B }; /* idx / JBM_CLDFB_SLOTS_IN_SUBFRAME Q15 */
105 2153 : move16();
106 2153 : move16();
107 2153 : move16();
108 2153 : move16();
109 :
110 : /* pointers to structs for allocation */
111 2153 : DIRAC_OUTPUT_SYNTHESIS_PARAMS *dirac_output_synthesis_params = &( hDirACRend->h_output_synthesis_psd_params );
112 2153 : DIRAC_OUTPUT_SYNTHESIS_STATE *dirac_output_synthesis_state = &( hDirACRend->h_output_synthesis_psd_state );
113 :
114 : /* check / set input parameters */
115 2153 : assert( hSpatParamRendCom->num_freq_bands > 0 && "Error: Number of frequency bands <= 0!" );
116 2153 : assert( hDirACRend->hOutSetup.nchan_out_woLFE > 0 && "Error: Number of output channels > 0!" );
117 2153 : assert( hDirACRend->num_outputs_diff > 0 );
118 2153 : assert( hSpatParamRendCom->slot_size > 0 );
119 2153 : assert( hDirACRend->hOutSetup.is_loudspeaker_setup == 0 || hDirACRend->hOutSetup.is_loudspeaker_setup == 1 );
120 2153 : assert( hDirACRend->diffuse_response_function_fx != NULL );
121 :
122 2153 : IF( hDirACRend->proto_signal_decorr_on )
123 : {
124 1995 : dirac_output_synthesis_params->max_band_decorr = hDirACRend->h_freq_domain_decorr_ap_params->max_band_decorr;
125 1995 : move16();
126 : }
127 : ELSE
128 : {
129 158 : dirac_output_synthesis_params->max_band_decorr = 0;
130 158 : move16();
131 : }
132 :
133 : /*-----------------------------------------------------------------*
134 : * memory allocation
135 : *-----------------------------------------------------------------*/
136 :
137 2153 : dirac_output_synthesis_state->diffuse_responses_square_fx = NULL;
138 :
139 2153 : IF( EQ_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_MONO ) )
140 : {
141 111 : IF( ( dirac_output_synthesis_state->diffuse_responses_square_fx = (Word32 *) malloc( 2 * sizeof( Word32 ) ) ) == NULL )
142 : {
143 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
144 : }
145 : }
146 2042 : ELSE IF( NE_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) )
147 : {
148 1247 : IF( ( dirac_output_synthesis_state->diffuse_responses_square_fx = (Word32 *) malloc( hDirACRend->hOutSetup.nchan_out_woLFE * sizeof( Word32 ) ) ) == NULL )
149 : {
150 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
151 : }
152 : }
153 :
154 : /* prototype power buffers */
155 2153 : dirac_output_synthesis_state->proto_power_smooth_prev_fx = NULL;
156 :
157 2153 : IF( NE_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) )
158 : {
159 1358 : IF( ( dirac_output_synthesis_state->proto_power_smooth_prev_fx = (Word32 *) malloc( hSpatParamRendCom->num_freq_bands * hDirACRend->num_protos_dir * sizeof( Word32 ) ) ) == NULL )
160 : {
161 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
162 : }
163 1358 : dirac_output_synthesis_state->proto_power_smooth_prev_len = imult1616( hSpatParamRendCom->num_freq_bands, hDirACRend->num_protos_dir );
164 1358 : move16();
165 : }
166 2153 : test();
167 2153 : test();
168 2153 : IF( dirac_output_synthesis_params->max_band_decorr > 0 && ( EQ_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_PSD_LS ) || EQ_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_PSD_SHD ) ) )
169 : {
170 1200 : IF( ( dirac_output_synthesis_state->proto_power_diff_smooth_prev_fx = (Word32 *) malloc( dirac_output_synthesis_params->max_band_decorr * hDirACRend->hOutSetup.nchan_out_woLFE * sizeof( Word32 ) ) ) == NULL )
171 : {
172 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
173 : }
174 1200 : dirac_output_synthesis_state->proto_power_diff_smooth_prev_len = imult1616( dirac_output_synthesis_params->max_band_decorr, hDirACRend->hOutSetup.nchan_out_woLFE );
175 1200 : move16();
176 : }
177 : ELSE
178 : {
179 953 : dirac_output_synthesis_state->proto_power_diff_smooth_prev_fx = NULL;
180 : }
181 :
182 : /* buffer length and interpolator */
183 2153 : IF( ( dirac_output_synthesis_params->interpolator_fx = (Word16 *) malloc( JBM_CLDFB_SLOTS_IN_SUBFRAME * sizeof( Word16 ) ) ) == NULL )
184 : {
185 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
186 : }
187 :
188 : /* target PSD buffers */
189 2153 : IF( hodirac_flag )
190 : {
191 112 : size = imult1616( imult1616( hSpatParamRendCom->num_freq_bands, hDirACRend->num_outputs_dir ), DIRAC_HO_NUMSECTORS );
192 : }
193 : ELSE
194 : {
195 2041 : size = imult1616( hSpatParamRendCom->num_freq_bands, hDirACRend->num_outputs_dir );
196 : }
197 2153 : IF( ( dirac_output_synthesis_state->cy_cross_dir_smooth_prev_fx = (Word32 *) malloc( size * sizeof( Word32 ) ) ) == NULL )
198 : {
199 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
200 : }
201 2153 : dirac_output_synthesis_state->cy_cross_dir_smooth_prev_len = size;
202 2153 : move16();
203 2153 : IF( EQ_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) )
204 : {
205 795 : dirac_output_synthesis_state->cy_auto_dir_smooth_prev_fx = NULL;
206 795 : IF( ( dirac_output_synthesis_state->cy_auto_diff_smooth_prev_fx = (Word32 *) malloc( dirac_output_synthesis_params->max_band_decorr * hDirACRend->num_outputs_diff * sizeof( Word32 ) ) ) == NULL )
207 : {
208 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
209 : }
210 795 : dirac_output_synthesis_state->cy_auto_dir_smooth_prev_len = imult1616( dirac_output_synthesis_params->max_band_decorr, hDirACRend->num_outputs_diff );
211 795 : move16();
212 : }
213 : ELSE
214 : {
215 1358 : IF( ( dirac_output_synthesis_state->cy_auto_dir_smooth_prev_fx = (Word32 *) malloc( hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_dir * sizeof( Word32 ) ) ) == NULL )
216 : {
217 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
218 : }
219 1358 : dirac_output_synthesis_state->cy_auto_dir_smooth_prev_len = imult1616( hSpatParamRendCom->num_freq_bands, hDirACRend->num_outputs_dir );
220 1358 : move16();
221 :
222 1358 : IF( EQ_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_PSD_SHD ) )
223 : {
224 412 : IF( ( dirac_output_synthesis_state->cy_auto_diff_smooth_prev_fx = (Word32 *) malloc( hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_dir * sizeof( Word32 ) ) ) == NULL )
225 : {
226 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
227 : }
228 412 : dirac_output_synthesis_state->cy_auto_diff_smooth_prev_len = imult1616( hSpatParamRendCom->num_freq_bands, hDirACRend->num_outputs_dir );
229 412 : move16();
230 : }
231 : ELSE
232 : {
233 946 : IF( ( dirac_output_synthesis_state->cy_auto_diff_smooth_prev_fx = (Word32 *) malloc( hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_diff * sizeof( Word32 ) ) ) == NULL )
234 : {
235 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
236 : }
237 946 : dirac_output_synthesis_state->cy_auto_diff_smooth_prev_len = imult1616( hSpatParamRendCom->num_freq_bands, hDirACRend->num_outputs_diff );
238 946 : move16();
239 : }
240 : }
241 :
242 : /* direct and diffuse gain buffers */
243 2153 : IF( ( dirac_output_synthesis_state->gains_dir_prev_fx = (Word32 *) malloc( size * sizeof( Word32 ) ) ) == NULL )
244 : {
245 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
246 : }
247 2153 : dirac_output_synthesis_state->gains_dir_prev_len = size;
248 2153 : move16();
249 2153 : test();
250 2153 : IF( EQ_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) )
251 : {
252 795 : IF( ( dirac_output_synthesis_state->gains_diff_prev_fx = (Word32 *) malloc( dirac_output_synthesis_params->max_band_decorr * hDirACRend->num_outputs_diff * sizeof( Word32 ) ) ) == NULL )
253 : {
254 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
255 : }
256 795 : dirac_output_synthesis_state->gains_diff_prev_len = imult1616( dirac_output_synthesis_params->max_band_decorr, hDirACRend->num_outputs_diff );
257 795 : move16();
258 : }
259 1358 : ELSE IF( NE_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_PSD_SHD ) && NE_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_MONO ) )
260 : {
261 835 : IF( ( dirac_output_synthesis_state->gains_diff_prev_fx = (Word32 *) malloc( hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_diff * sizeof( Word32 ) ) ) == NULL )
262 : {
263 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
264 : }
265 835 : dirac_output_synthesis_state->gains_diff_prev_len = imult1616( hSpatParamRendCom->num_freq_bands, hDirACRend->num_outputs_diff );
266 835 : move16();
267 : }
268 : ELSE
269 : {
270 523 : IF( ( dirac_output_synthesis_state->gains_diff_prev_fx = (Word32 *) malloc( hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_dir * sizeof( Word32 ) ) ) == NULL )
271 : {
272 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
273 : }
274 523 : dirac_output_synthesis_state->gains_diff_prev_len = imult1616( hSpatParamRendCom->num_freq_bands, hDirACRend->num_outputs_dir );
275 523 : move16();
276 : }
277 :
278 : /*-----------------------------------------------------------------*
279 : * prepare processing parameters
280 : *-----------------------------------------------------------------*/
281 :
282 : /* compute alpha */
283 2153 : test();
284 2153 : test();
285 2153 : IF( !( EQ_32( renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || EQ_32( renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) || EQ_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) ) )
286 : {
287 1358 : computeAlphaSynthesis_fx( temp_alpha_synthesis_fx, DIRAC_AVG_LENGTH_SYNTH_MS, DIRAC_ALPHA_MAX_Q15, &dirac_output_synthesis_params->numAlphas, hSpatParamRendCom->slot_size, hSpatParamRendCom->num_freq_bands, hDirACRend->frequency_axis_fx, output_Fs );
288 :
289 1358 : IF( ( dirac_output_synthesis_params->alpha_synthesis_fx = (Word16 *) malloc( dirac_output_synthesis_params->numAlphas * sizeof( Word16 ) ) ) == NULL )
290 : {
291 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
292 : }
293 1358 : Copy( temp_alpha_synthesis_fx, dirac_output_synthesis_params->alpha_synthesis_fx, dirac_output_synthesis_params->numAlphas ); /*q15*/
294 :
295 1358 : computeAlphaSynthesis_fx( temp_alpha_synthesis_fx, DIRAC_AVG_LENGTH_SYNTH_MS_FAST, DIRAC_ALPHA_MAX_FAST_Q15, &dirac_output_synthesis_params->numAlphasFast, hSpatParamRendCom->slot_size, hSpatParamRendCom->num_freq_bands, hDirACRend->frequency_axis_fx, output_Fs );
296 :
297 1358 : IF( ( dirac_output_synthesis_params->alpha_synthesis_fast_fx = (Word16 *) malloc( dirac_output_synthesis_params->numAlphasFast * sizeof( Word16 ) ) ) == NULL )
298 : {
299 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
300 : }
301 1358 : Copy( temp_alpha_synthesis_fx, dirac_output_synthesis_params->alpha_synthesis_fast_fx, dirac_output_synthesis_params->numAlphasFast ); /*q15*/
302 :
303 1358 : IF( ( dirac_output_synthesis_state->reference_power_smooth_prev_fx = (Word32 *) malloc( hSpatParamRendCom->num_freq_bands * sizeof( Word32 ) ) ) == NULL )
304 : {
305 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
306 : }
307 1358 : set32_fx( dirac_output_synthesis_state->reference_power_smooth_prev_fx, 0, hSpatParamRendCom->num_freq_bands );
308 : #ifdef FIX_867_CLDFB_NRG_SCALE
309 1358 : dirac_output_synthesis_state->reference_power_smooth_prev_q[0] = Q31;
310 1358 : dirac_output_synthesis_state->reference_power_smooth_prev_q[1] = Q31;
311 1358 : move16();
312 1358 : move16();
313 : #else
314 : dirac_output_synthesis_state->reference_power_smooth_prev_q = Q31;
315 : move16();
316 : #endif
317 :
318 1358 : IF( ( dirac_output_synthesis_state->direction_smoothness_prev_fx = (Word32 *) malloc( hSpatParamRendCom->num_freq_bands * sizeof( Word32 ) ) ) == NULL )
319 : {
320 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
321 : }
322 1358 : set32_fx( dirac_output_synthesis_state->direction_smoothness_prev_fx, 0, hSpatParamRendCom->num_freq_bands );
323 : }
324 : ELSE
325 : {
326 795 : dirac_output_synthesis_params->alpha_synthesis_fx = NULL;
327 795 : dirac_output_synthesis_params->alpha_synthesis_fast_fx = NULL;
328 795 : dirac_output_synthesis_state->reference_power_smooth_prev_fx = NULL;
329 795 : dirac_output_synthesis_state->direction_smoothness_prev_fx = NULL;
330 : }
331 :
332 : /* compute interpolator */
333 10765 : FOR( idx = 1; idx <= JBM_CLDFB_SLOTS_IN_SUBFRAME; ++idx )
334 : {
335 8612 : dirac_output_synthesis_params->interpolator_fx[idx - 1] = interpolator_tbl[idx - 1]; /* Q15 */
336 8612 : move16();
337 : }
338 :
339 : /* prepare diffuse response function */
340 2153 : IF( EQ_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_MONO ) )
341 : {
342 111 : num_diffuse_responses = 2;
343 111 : move16();
344 : }
345 : ELSE
346 : {
347 2042 : num_diffuse_responses = hDirACRend->hOutSetup.nchan_out_woLFE;
348 2042 : move16();
349 : }
350 :
351 2153 : IF( dirac_output_synthesis_state->diffuse_responses_square_fx != NULL )
352 : {
353 12406 : FOR( ch_idx = 0; ch_idx < num_diffuse_responses; ++ch_idx )
354 : {
355 : /*dirac_output_synthesis_state->diffuse_responses_square[ch_idx] = pow(dirac_output_synthesis_params->diffuse_response_function[ch_idx]/max_response, 2.0f);*/
356 11048 : tmp_fx = hDirACRend->diffuse_response_function_fx[ch_idx]; /*q15*/
357 11048 : move16();
358 :
359 11048 : dirac_output_synthesis_state->diffuse_responses_square_fx[ch_idx] = L_mult( tmp_fx, tmp_fx ); /* Q15 + Q15 + 1 -> Q31 */
360 11048 : move32();
361 : }
362 : }
363 :
364 :
365 2153 : IF( EQ_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) )
366 : {
367 : Word16 diff_compensation_order;
368 : Word32 diff_nrg_total_fx, diff_nrg_fx, diff_nrg_trans_fx, diff_nrg_decorr_fx;
369 :
370 : /* compensate missing diffuseness modelling up order 2, except for HR*/
371 795 : IF( GE_16( nchan_transport, 3 ) )
372 : {
373 786 : diff_compensation_order = 3;
374 786 : move16();
375 : }
376 : ELSE
377 : {
378 9 : diff_compensation_order = 2;
379 9 : move16();
380 : }
381 795 : diff_compensation_order = s_min( diff_compensation_order, hDirACRend->hOutSetup.ambisonics_order );
382 :
383 795 : diff_nrg_total_fx = 0;
384 795 : move32();
385 795 : diff_nrg_trans_fx = 0;
386 795 : move32();
387 795 : diff_nrg_decorr_fx = 0;
388 795 : move32();
389 :
390 795 : Word16 gaurd_bits = find_guarded_bits_fx( imult1616( add( diff_compensation_order, 1 ), add( diff_compensation_order, 1 ) ) );
391 795 : tmp16 = add( diff_compensation_order, 1 );
392 795 : tmp16 = imult1616( tmp16, tmp16 );
393 13404 : FOR( ch_idx = 0; ch_idx < tmp16; ch_idx++ )
394 : {
395 12609 : diff_nrg_fx = L_shr( L_mult0( hDirACRend->diffuse_response_function_fx[ch_idx], hDirACRend->diffuse_response_function_fx[ch_idx] ), gaurd_bits ); // Q30 - gaurd_bits
396 :
397 12609 : diff_nrg_total_fx = L_add( diff_nrg_total_fx, diff_nrg_fx ); // Q30 - gaurd_bits
398 :
399 : /* is it a transport channel?*/
400 12609 : test();
401 12609 : if ( ch_idx == 0 || hDirACRend->proto_index_dir[ch_idx] != 0 )
402 : {
403 3882 : diff_nrg_trans_fx = L_add( diff_nrg_trans_fx, diff_nrg_fx ); // Q30 - gaurd_bits
404 : }
405 : /* is it a decorrelated or transport channel?*/
406 12609 : if ( LT_16( ch_idx, hDirACRend->num_outputs_diff ) )
407 : {
408 3180 : diff_nrg_decorr_fx = L_add( diff_nrg_decorr_fx, diff_nrg_fx ); // Q30 - gaurd_bits
409 : }
410 : }
411 795 : Word16 exp_1 = 0, exp_2 = 0, tmp;
412 795 : move16();
413 795 : move16();
414 795 : tmp = BASOP_Util_Divide3232_Scale( diff_nrg_total_fx, diff_nrg_trans_fx, &exp_1 ); // Q(15 - exp_1)
415 795 : dirac_output_synthesis_params->diffuse_compensation_factor_fx = L_shl( L_deposit_l( tmp ), add( Q12, exp_1 ) ); // Q27
416 795 : move32();
417 :
418 795 : tmp = BASOP_Util_Divide3232_Scale( diff_nrg_total_fx, diff_nrg_decorr_fx, &exp_2 ); // (Q15 - exp_2)
419 795 : dirac_output_synthesis_params->diffuse_compensation_factor_decorr_fx = L_shl( L_deposit_l( tmp ), add( Q14, exp_2 ) ); // Q29
420 795 : move32();
421 : }
422 : ELSE
423 : {
424 1358 : dirac_output_synthesis_params->diffuse_compensation_factor_fx = 0;
425 1358 : move32();
426 1358 : dirac_output_synthesis_params->diffuse_compensation_factor_decorr_fx = 0;
427 1358 : move32();
428 : }
429 :
430 2153 : return IVAS_ERR_OK;
431 : }
432 :
433 :
434 : /*-------------------------------------------------------------------------
435 : * ivas_dirac_dec_output_synthesis_init()
436 : *
437 : *
438 : *------------------------------------------------------------------------*/
439 :
440 2171 : void ivas_dirac_dec_output_synthesis_init_fx(
441 : SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common spatial renderer data handle */
442 : DIRAC_REND_HANDLE hDirACRend, /* i/o: DirAC renderer handle */
443 : const Word16 nchan_out_woLFE, /* i : number of output audio channels without LFE */
444 : const Word16 hodirac_flag /* i : flag to indicate HO-DirAC mode */
445 : )
446 : {
447 : Word16 size;
448 :
449 : DIRAC_OUTPUT_SYNTHESIS_PARAMS *h_dirac_output_synthesis_params;
450 : DIRAC_OUTPUT_SYNTHESIS_STATE *h_dirac_output_synthesis_state;
451 :
452 2171 : h_dirac_output_synthesis_params = &( hDirACRend->h_output_synthesis_psd_params );
453 2171 : h_dirac_output_synthesis_state = &( hDirACRend->h_output_synthesis_psd_state );
454 :
455 : /*-----------------------------------------------------------------*
456 : * init outputSynthesisPSD_Init
457 : *-----------------------------------------------------------------*/
458 :
459 : /* initialize buffers */
460 2171 : IF( h_dirac_output_synthesis_state->cy_auto_dir_smooth_prev_fx != NULL )
461 : {
462 1358 : set32_fx( h_dirac_output_synthesis_state->cy_auto_dir_smooth_prev_fx, 0, imult1616( hSpatParamRendCom->num_freq_bands, hDirACRend->num_outputs_dir ) );
463 : }
464 2171 : h_dirac_output_synthesis_state->q_cy_auto_dir_smooth_prev = 0;
465 2171 : move16();
466 :
467 2171 : IF( hodirac_flag )
468 : {
469 112 : size = imult1616( imult1616( hSpatParamRendCom->num_freq_bands, hDirACRend->num_outputs_dir ), DIRAC_HO_NUMSECTORS );
470 : }
471 : ELSE
472 : {
473 2059 : size = imult1616( hSpatParamRendCom->num_freq_bands, hDirACRend->num_outputs_dir );
474 : }
475 2171 : set32_fx( h_dirac_output_synthesis_state->cy_cross_dir_smooth_prev_fx, 0, size );
476 2171 : h_dirac_output_synthesis_state->q_cy_cross_dir_smooth_prev = 0;
477 2171 : move16();
478 :
479 2171 : IF( EQ_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) )
480 : {
481 813 : set32_fx( h_dirac_output_synthesis_state->cy_auto_diff_smooth_prev_fx, 0, imult1616( h_dirac_output_synthesis_params->max_band_decorr, hDirACRend->num_outputs_diff ) );
482 : }
483 1358 : ELSE IF( NE_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_PSD_SHD ) )
484 : {
485 946 : set32_fx( h_dirac_output_synthesis_state->cy_auto_diff_smooth_prev_fx, 0, imult1616( hSpatParamRendCom->num_freq_bands, hDirACRend->num_outputs_diff ) );
486 : }
487 : ELSE
488 : {
489 412 : set32_fx( h_dirac_output_synthesis_state->cy_auto_diff_smooth_prev_fx, 0, imult1616( hSpatParamRendCom->num_freq_bands, hDirACRend->num_outputs_dir ) );
490 : }
491 2171 : h_dirac_output_synthesis_state->q_cy_auto_diff_smooth_prev = 0;
492 2171 : move16();
493 :
494 2171 : IF( h_dirac_output_synthesis_state->proto_power_smooth_prev_fx != NULL )
495 : {
496 1358 : set32_fx( h_dirac_output_synthesis_state->proto_power_smooth_prev_fx, 0, imult1616( hSpatParamRendCom->num_freq_bands, hDirACRend->num_protos_dir ) );
497 : #ifdef FIX_867_CLDFB_NRG_SCALE
498 1358 : h_dirac_output_synthesis_state->proto_power_smooth_prev_q[0] = Q31;
499 1358 : h_dirac_output_synthesis_state->proto_power_smooth_prev_q[1] = Q31;
500 1358 : move16();
501 1358 : move16();
502 : #else
503 : h_dirac_output_synthesis_state->proto_power_smooth_prev_q = Q31;
504 : move16();
505 : #endif
506 : }
507 2171 : set32_fx( h_dirac_output_synthesis_state->gains_dir_prev_fx, 0, size );
508 2171 : h_dirac_output_synthesis_state->gains_dir_prev_q = 0;
509 2171 : move16();
510 :
511 2171 : IF( EQ_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) )
512 : {
513 813 : set32_fx( h_dirac_output_synthesis_state->gains_diff_prev_fx, 0, imult1616( h_dirac_output_synthesis_params->max_band_decorr, hDirACRend->num_outputs_diff ) );
514 : }
515 : ELSE
516 : {
517 1358 : set32_fx( h_dirac_output_synthesis_state->gains_diff_prev_fx, 0, imult1616( hSpatParamRendCom->num_freq_bands, hDirACRend->num_outputs_dir ) );
518 : }
519 2171 : h_dirac_output_synthesis_state->gains_diff_prev_q = 0;
520 2171 : move16();
521 :
522 2171 : IF( h_dirac_output_synthesis_state->proto_power_diff_smooth_prev_fx != NULL )
523 : {
524 1200 : set32_fx( h_dirac_output_synthesis_state->proto_power_diff_smooth_prev_fx, 0, imult1616( h_dirac_output_synthesis_params->max_band_decorr, nchan_out_woLFE ) );
525 : }
526 2171 : h_dirac_output_synthesis_state->proto_power_diff_smooth_prev_q = Q31;
527 2171 : move16();
528 :
529 2171 : return;
530 : }
531 :
532 :
533 : /*-------------------------------------------------------------------------
534 : * ivas_dirac_dec_output_synthesis_close()
535 : *
536 : * Memory deallocation of Output synthesis sub-module
537 : *------------------------------------------------------------------------*/
538 :
539 2153 : void ivas_dirac_dec_output_synthesis_close_fx(
540 : DIRAC_REND_HANDLE hDirACRend /* i/o: DirAC handle */
541 : )
542 : {
543 : /* pointers to structs for allocation */
544 2153 : DIRAC_OUTPUT_SYNTHESIS_PARAMS *dirac_output_synthesis_params = &( hDirACRend->h_output_synthesis_psd_params );
545 2153 : DIRAC_OUTPUT_SYNTHESIS_STATE *dirac_output_synthesis_state = &( hDirACRend->h_output_synthesis_psd_state );
546 :
547 : /*-----------------------------------------------------------------*
548 : * memory deallocation
549 : *-----------------------------------------------------------------*/
550 :
551 : /* free interpolator */
552 2153 : IF( ( dirac_output_synthesis_params )->interpolator_fx != NULL )
553 : {
554 2153 : free( ( dirac_output_synthesis_params )->interpolator_fx );
555 2153 : ( dirac_output_synthesis_params )->interpolator_fx = NULL;
556 : }
557 :
558 : /* free alpha */
559 2153 : IF( ( dirac_output_synthesis_params )->alpha_synthesis_fx != NULL )
560 : {
561 1358 : free( ( dirac_output_synthesis_params )->alpha_synthesis_fx );
562 1358 : ( dirac_output_synthesis_params )->alpha_synthesis_fx = NULL;
563 : }
564 2153 : IF( ( dirac_output_synthesis_params )->alpha_synthesis_fast_fx != NULL )
565 : {
566 1358 : free( ( dirac_output_synthesis_params )->alpha_synthesis_fast_fx );
567 1358 : ( dirac_output_synthesis_params )->alpha_synthesis_fast_fx = NULL;
568 : }
569 :
570 2153 : IF( ( dirac_output_synthesis_state )->reference_power_smooth_prev_fx != NULL )
571 : {
572 1358 : free( ( dirac_output_synthesis_state )->reference_power_smooth_prev_fx );
573 1358 : ( dirac_output_synthesis_state )->reference_power_smooth_prev_fx = NULL;
574 : }
575 :
576 2153 : IF( ( dirac_output_synthesis_state )->direction_smoothness_prev_fx != NULL )
577 : {
578 1358 : free( ( dirac_output_synthesis_state )->direction_smoothness_prev_fx );
579 1358 : ( dirac_output_synthesis_state )->direction_smoothness_prev_fx = NULL;
580 : }
581 :
582 2153 : IF( ( dirac_output_synthesis_state )->diffuse_responses_square_fx != NULL )
583 : {
584 1358 : free( ( dirac_output_synthesis_state )->diffuse_responses_square_fx );
585 1358 : ( dirac_output_synthesis_state )->diffuse_responses_square_fx = NULL;
586 : }
587 :
588 : /* free power buffers */
589 2153 : IF( ( dirac_output_synthesis_state )->proto_power_smooth_prev_fx != NULL )
590 : {
591 1358 : free( ( dirac_output_synthesis_state )->proto_power_smooth_prev_fx );
592 1358 : ( dirac_output_synthesis_state )->proto_power_smooth_prev_fx = NULL;
593 : }
594 :
595 2153 : IF( ( dirac_output_synthesis_state )->proto_power_diff_smooth_prev_fx != NULL )
596 : {
597 1200 : free( ( dirac_output_synthesis_state )->proto_power_diff_smooth_prev_fx );
598 1200 : ( dirac_output_synthesis_state )->proto_power_diff_smooth_prev_fx = NULL;
599 : }
600 :
601 : /* free target power buffers */
602 2153 : IF( ( dirac_output_synthesis_state )->cy_auto_dir_smooth_prev_fx != NULL )
603 : {
604 1358 : free( ( dirac_output_synthesis_state )->cy_auto_dir_smooth_prev_fx );
605 1358 : ( dirac_output_synthesis_state )->cy_auto_dir_smooth_prev_fx = NULL;
606 : }
607 2153 : IF( ( dirac_output_synthesis_state )->cy_cross_dir_smooth_prev_fx != NULL )
608 : {
609 2153 : free( ( dirac_output_synthesis_state )->cy_cross_dir_smooth_prev_fx );
610 2153 : ( dirac_output_synthesis_state )->cy_cross_dir_smooth_prev_fx = NULL;
611 : }
612 2153 : IF( ( dirac_output_synthesis_state )->cy_auto_diff_smooth_prev_fx != NULL )
613 : {
614 2153 : free( ( dirac_output_synthesis_state )->cy_auto_diff_smooth_prev_fx );
615 2153 : ( dirac_output_synthesis_state )->cy_auto_diff_smooth_prev_fx = NULL;
616 : }
617 :
618 : /* free gain buffers */
619 2153 : IF( ( dirac_output_synthesis_state )->gains_dir_prev_fx != NULL )
620 : {
621 2153 : free( ( dirac_output_synthesis_state )->gains_dir_prev_fx );
622 2153 : ( dirac_output_synthesis_state )->gains_dir_prev_fx = NULL;
623 : }
624 2153 : IF( ( dirac_output_synthesis_state )->gains_diff_prev_fx != NULL )
625 : {
626 2153 : free( ( dirac_output_synthesis_state )->gains_diff_prev_fx );
627 2153 : ( dirac_output_synthesis_state )->gains_diff_prev_fx = NULL;
628 : }
629 2153 : return;
630 : }
631 :
632 :
633 : /*-------------------------------------------------------------------------
634 : * ivas_dirac_dec_output_synthesis_process_slot()
635 : *
636 : *
637 : *------------------------------------------------------------------------*/
638 :
639 1265265 : void ivas_dirac_dec_output_synthesis_process_slot_fx(
640 : const Word32 *reference_power, /* i : Estimated power Q(q_reference_power)*/
641 : #ifdef FIX_867_CLDFB_NRG_SCALE
642 : const Word16 *q_reference_power, /* i : Estimated power Q */
643 : #else
644 : const Word16 q_reference_power, /* i : Estimated power Q */
645 : #endif
646 : const Word32 *onset, /* i : onset filter Q31*/
647 : const Word16 *azimuth,
648 : const Word16 *elevation,
649 : const Word32 *diffuseness, /* Q(q_diffuseness)*/
650 : Word16 q_diffuseness,
651 : SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common spatial renderer data handle */
652 : DIRAC_REND_HANDLE hDirACRend, /* i/o: DirAC renderer handle */
653 : const Word16 sh_rot_max_order,
654 : const Word32 *p_Rmat, /* i : rotation matrix Q30*/
655 : const VBAP_HANDLE hVBAPdata, /* i : VBAP structure */
656 : const IVAS_OUTPUT_SETUP hOutSetup, /* i : output setup structure */
657 : const Word16 nchan_transport, /* i : number of transport channels*/
658 : const Word16 md_idx,
659 : const Word16 hodirac_flag, /* i : flag to indicate HO-DirAC mode */
660 : const Word16 dec_param_estim )
661 : {
662 : Word16 num_freq_bands, num_channels_dir;
663 : Word16 num_freq_bands_diff, num_channels_diff;
664 : Word16 ch_idx;
665 : Word32 aux_buf[CLDFB_NO_CHANNELS_MAX];
666 : Word16 diff_start_band, tmp16;
667 : DIRAC_OUTPUT_SYNTHESIS_PARAMS *h_dirac_output_synthesis_params;
668 : DIRAC_OUTPUT_SYNTHESIS_STATE *h_dirac_output_synthesis_state;
669 :
670 1265265 : h_dirac_output_synthesis_params = &( hDirACRend->h_output_synthesis_psd_params );
671 1265265 : h_dirac_output_synthesis_state = &( hDirACRend->h_output_synthesis_psd_state );
672 :
673 1265265 : h_dirac_output_synthesis_state->onset_filter_fx = onset; /*Q31*/
674 :
675 : /*-----------------------------------------------------------------*
676 : * processing
677 : *-----------------------------------------------------------------*/
678 :
679 : /* collect some often used parameters */
680 1265265 : num_freq_bands = hSpatParamRendCom->num_freq_bands;
681 1265265 : move16();
682 1265265 : num_channels_dir = hDirACRend->num_outputs_dir;
683 1265265 : move16();
684 1265265 : num_channels_diff = hDirACRend->num_outputs_diff;
685 1265265 : move16();
686 1265265 : num_freq_bands_diff = h_dirac_output_synthesis_params->max_band_decorr;
687 1265265 : move16();
688 :
689 1265265 : IF( EQ_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_PSD_LS ) )
690 : {
691 281936 : num_channels_dir = hOutSetup.nchan_out_woLFE;
692 281936 : move16();
693 : }
694 :
695 1265265 : test();
696 1265265 : IF( EQ_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) && hodirac_flag )
697 : {
698 212624 : ivas_dirac_dec_compute_directional_responses_fx( hSpatParamRendCom,
699 : hDirACRend,
700 : hVBAPdata,
701 : NULL,
702 : NULL,
703 : azimuth,
704 : elevation,
705 : md_idx,
706 : NULL,
707 : 0,
708 : 2,
709 : p_Rmat,
710 : hodirac_flag );
711 : {
712 :
713 212624 : IF( h_dirac_output_synthesis_state->direct_responses_square_fx )
714 : {
715 0 : Scale_sig32( h_dirac_output_synthesis_state->direct_responses_square_fx, imult1616( num_channels_dir, num_freq_bands ), sub( 31, h_dirac_output_synthesis_state->direct_responses_square_q ) ); /* h_dirac_output_synthesis_state->direct_responses_square_q->Q31*/
716 0 : h_dirac_output_synthesis_state->direct_responses_square_q = 31;
717 0 : move16();
718 : }
719 212624 : Scale_sig32( hDirACRend->h_output_synthesis_psd_state.direct_responses_fx, i_mult( hSpatParamRendCom->num_freq_bands, hDirACRend->num_outputs_dir ), sub( 31, h_dirac_output_synthesis_state->direct_responses_q ) ); /*h_dirac_output_synthesis_state->direct_responses_q->Q31*/
720 212624 : IF( hodirac_flag )
721 : {
722 212624 : Scale_sig32( &hDirACRend->h_output_synthesis_psd_state.direct_responses_fx[hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_dir], i_mult( hSpatParamRendCom->num_freq_bands, hDirACRend->num_outputs_dir ), sub( 31, h_dirac_output_synthesis_state->direct_responses_q ) ); /*h_dirac_output_synthesis_state->direct_responses_q->Q31*/
723 : }
724 212624 : h_dirac_output_synthesis_state->direct_responses_q = 31;
725 212624 : move16();
726 : }
727 : }
728 :
729 1265265 : test();
730 1265265 : IF( dec_param_estim == FALSE && hodirac_flag )
731 : {
732 212624 : IF( EQ_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) )
733 : {
734 212624 : v_multc_fixed( hSpatParamRendCom->energy_ratio1_fx[md_idx], -MAX_32 /*-1 Q31*/, aux_buf, num_freq_bands ); /* 30 + 31 - 31 -> 30 */
735 212624 : v_addc_fixed( aux_buf, ONE_IN_Q30 /*1 Q30*/, aux_buf, num_freq_bands ); /*30*/
736 212624 : Copy32( hSpatParamRendCom->energy_ratio1_fx[md_idx],
737 : h_dirac_output_synthesis_state->direct_power_factor_fx,
738 : num_freq_bands ); /*Q30*/
739 212624 : Copy32( aux_buf,
740 : h_dirac_output_synthesis_state->diffuse_power_factor_fx,
741 : num_freq_bands ); /*Q30*/
742 :
743 212624 : v_multc_fixed( hSpatParamRendCom->energy_ratio2_fx[md_idx], -MAX_32 /*-1 Q31*/, aux_buf, num_freq_bands ); /*30+31-31->30*/
744 212624 : v_addc_fixed( aux_buf, ONE_IN_Q30 /*1 Q30*/, aux_buf, num_freq_bands ); /*30*/
745 212624 : Copy32( hSpatParamRendCom->energy_ratio2_fx[md_idx],
746 212624 : &h_dirac_output_synthesis_state->direct_power_factor_fx[hSpatParamRendCom->num_freq_bands],
747 : num_freq_bands ); /*Q30*/
748 212624 : Copy32( aux_buf,
749 212624 : &h_dirac_output_synthesis_state->diffuse_power_factor_fx[hSpatParamRendCom->num_freq_bands],
750 : num_freq_bands ); /*Q30*/
751 :
752 212624 : h_dirac_output_synthesis_state->diffuse_power_factor_q = 30;
753 212624 : move16();
754 212624 : h_dirac_output_synthesis_state->direct_power_factor_q = 30;
755 212624 : move16();
756 : }
757 : ELSE
758 : {
759 0 : ivas_dirac_dec_compute_gain_factors_fx( num_freq_bands,
760 0 : hSpatParamRendCom->diffuseness_vector_fx[md_idx],
761 : h_dirac_output_synthesis_state->direct_power_factor_fx,
762 : h_dirac_output_synthesis_state->diffuse_power_factor_fx,
763 : &h_dirac_output_synthesis_state->direct_power_factor_q,
764 : &h_dirac_output_synthesis_state->diffuse_power_factor_q );
765 : }
766 : }
767 1052641 : ELSE IF( EQ_16( dec_param_estim, TRUE ) )
768 : {
769 : /* compute direct responses */
770 694820 : ivas_dirac_dec_compute_directional_responses_fx( hSpatParamRendCom,
771 : hDirACRend,
772 : hVBAPdata,
773 : NULL,
774 : NULL,
775 : azimuth,
776 : elevation,
777 : md_idx,
778 : NULL,
779 : 0,
780 : sh_rot_max_order,
781 : p_Rmat,
782 : hodirac_flag );
783 :
784 : {
785 694820 : IF( h_dirac_output_synthesis_state->direct_responses_square_fx )
786 : {
787 72000 : Scale_sig32( h_dirac_output_synthesis_state->direct_responses_square_fx, imult1616( num_channels_dir, num_freq_bands ), sub( 31, h_dirac_output_synthesis_state->direct_responses_square_q ) ); /*h_dirac_output_synthesis_state->direct_responses_square_q->Q31*/
788 72000 : h_dirac_output_synthesis_state->direct_responses_square_q = 31;
789 72000 : move16();
790 : }
791 694820 : Scale_sig32( hDirACRend->h_output_synthesis_psd_state.direct_responses_fx, i_mult( hSpatParamRendCom->num_freq_bands, hDirACRend->num_outputs_dir ), sub( 31, h_dirac_output_synthesis_state->direct_responses_q ) ); /*h_dirac_output_synthesis_state->direct_responses_q->Q31*/
792 694820 : IF( hodirac_flag )
793 : {
794 0 : Scale_sig32( &hDirACRend->h_output_synthesis_psd_state.direct_responses_fx[hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_dir], i_mult( hSpatParamRendCom->num_freq_bands, hDirACRend->num_outputs_dir ), sub( 31, h_dirac_output_synthesis_state->direct_responses_q ) ); /*h_dirac_output_synthesis_state->direct_responses_q->Q31*/
795 : }
796 694820 : h_dirac_output_synthesis_state->direct_responses_q = 31;
797 694820 : move16();
798 : }
799 :
800 694820 : IF( EQ_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) )
801 : {
802 622820 : ivas_dirac_dec_compute_gain_factors_fx( num_freq_bands,
803 : diffuseness,
804 : h_dirac_output_synthesis_state->direct_power_factor_fx,
805 : h_dirac_output_synthesis_state->diffuse_power_factor_fx,
806 : &h_dirac_output_synthesis_state->direct_power_factor_q,
807 : &h_dirac_output_synthesis_state->diffuse_power_factor_q );
808 622820 : h_dirac_output_synthesis_state->direct_power_factor_q = sub( 31, h_dirac_output_synthesis_state->direct_power_factor_q );
809 622820 : h_dirac_output_synthesis_state->diffuse_power_factor_q = sub( 31, h_dirac_output_synthesis_state->diffuse_power_factor_q );
810 :
811 622820 : v_multc_fixed( h_dirac_output_synthesis_state->direct_power_factor_fx,
812 : ONE_IN_Q29 /*0.25f Q31*/,
813 : h_dirac_output_synthesis_state->direct_power_factor_fx,
814 : num_freq_bands ); /*h_dirac_output_synthesis_state->direct_power_factor_q+Q31-Q31->h_dirac_output_synthesis_state->direct_power_factor_q*/
815 622820 : v_multc_fixed( h_dirac_output_synthesis_state->diffuse_power_factor_fx,
816 : ONE_IN_Q29 /*0.25f Q31*/,
817 : h_dirac_output_synthesis_state->diffuse_power_factor_fx,
818 : num_freq_bands ); /*h_dirac_output_synthesis_state->diffuse_power_factor_q+Q31-Q31->h_dirac_output_synthesis_state->diffuse_power_factor_q*/
819 :
820 : /*Direct gain*/
821 :
822 622820 : Word16 *Q_temp_cy_cross_dir_smooth_fx = (Word16 *) malloc( num_freq_bands * num_channels_dir * sizeof( Word16 ) );
823 :
824 622820 : tmp16 = imult1616( num_freq_bands, num_channels_dir );
825 483283940 : FOR( Word16 kk = 0; kk < tmp16; kk++ )
826 : {
827 482661120 : Q_temp_cy_cross_dir_smooth_fx[kk] = h_dirac_output_synthesis_state->q_cy_cross_dir_smooth;
828 482661120 : move16();
829 : }
830 :
831 3114100 : FOR( ch_idx = 0; ch_idx < s_min( 4, nchan_transport ); ch_idx++ )
832 : {
833 : Word16 k;
834 2491280 : IF( ch_idx != 0 )
835 : {
836 : Word32 a, c;
837 : Word16 b, b_exp, sqr_exp, q_diff_aab, q_diff_c;
838 : Word32 mpy_a_a_b, mpy_diff_c, mpy_diff_aab;
839 : Word32 sqr_inp, sqr;
840 :
841 : /*Directonal sound gain nrg compensation*/
842 1868460 : c = L_add( ONE_IN_Q29 /*1 Q29*/, Mpy_32_16_1( L_sub( h_dirac_output_synthesis_params->diffuse_compensation_factor_decorr_fx, ONE_IN_Q29 /*1 Q29*/ ), 5461 /*1.0 / 6.0 Q15*/ ) ); /*Diffuseness modellling nrg compensation*/ /*Q29*/
843 11210760 : FOR( k = 0; k < num_freq_bands_diff; k++ )
844 : {
845 9342300 : a = h_dirac_output_synthesis_state->direct_responses_fx[ch_idx * num_freq_bands + k]; // Q = h_dirac_output_synthesis_state->q_direct_responses
846 9342300 : move32();
847 9342300 : IF( reference_power[k + num_freq_bands] == 0 )
848 : {
849 20370 : b = 0;
850 20370 : move16();
851 20370 : b_exp = 0;
852 20370 : move16();
853 : }
854 : ELSE
855 : {
856 9321930 : IF( reference_power[k + ( ch_idx + 1 ) * num_freq_bands] == 0 )
857 : {
858 493668 : b = MAX_16;
859 493668 : move16();
860 493668 : b_exp = 0;
861 493668 : move16();
862 : }
863 : ELSE
864 : {
865 8828262 : b = BASOP_Util_Divide3232_Scale( reference_power[k + num_freq_bands], reference_power[k + ( ch_idx + 1 ) * num_freq_bands], &b_exp ); /*Q(15-b_exp)*/
866 : }
867 : }
868 :
869 9342300 : mpy_a_a_b = Mpy_32_32( a, Mpy_32_16_1( a, b ) ); // Q = (h_dirac_output_synthesis_state->q_direct_responses + (15 - b_exp) - 15) + (h_dirac_output_synthesis_state->q_direct_responses) - 31
870 9342300 : mpy_diff_aab = Mpy_32_32( L_sub( L_shl( 1, q_diffuseness ), diffuseness[k] ), mpy_a_a_b ); // Q(q_diff_aab) = 2*(h_dirac_output_synthesis_state->q_direct_responses) - b_exp - 31 + q_diffuseness -31
871 9342300 : mpy_diff_c = Mpy_32_32( diffuseness[k], c ); // Q(q_diff_c) = q_diffuseness - 2
872 :
873 9342300 : q_diff_aab = add( sub( add( h_dirac_output_synthesis_state->direct_responses_q, sub( 15, b_exp ) ), 15 ), add( sub( h_dirac_output_synthesis_state->direct_responses_q, 31 ), sub( q_diffuseness, 31 ) ) );
874 9342300 : q_diff_c = sub( q_diffuseness, 2 );
875 :
876 9342300 : test();
877 9342300 : IF( mpy_diff_c != 0 && mpy_diff_aab != 0 )
878 : {
879 7920520 : sqr_inp = BASOP_Util_Add_Mant32Exp( mpy_diff_c, sub( 31, q_diff_c ), mpy_diff_aab, sub( 31, q_diff_aab ), &sqr_exp ); /*Q(31-sqr_exp)*/
880 : }
881 : ELSE
882 : {
883 1421780 : IF( mpy_diff_c == 0 )
884 : {
885 604527 : sqr_inp = mpy_diff_aab; /*Q(q_diff_aab)*/
886 604527 : move32();
887 604527 : sqr_exp = sub( 31, q_diff_aab );
888 : }
889 : ELSE
890 : {
891 817253 : sqr_inp = mpy_diff_c; /*Q(q_diff_c)*/
892 817253 : move32();
893 817253 : sqr_exp = sub( 31, q_diff_c );
894 : }
895 : }
896 9342300 : sqr = Sqrt32( sqr_inp, &sqr_exp ); /*Q(31-sqr_exp)*/
897 9342300 : sqr = L_shr( sqr, 2 ); /*Q(31-sqr_exp)*/
898 9342300 : IF( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] != 0 )
899 : {
900 6965947 : IF( LT_16( sub( 31, sqr_exp ), h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ) )
901 : {
902 33535 : h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = L_shr( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k], sub( h_dirac_output_synthesis_state->q_cy_cross_dir_smooth, sub( 31, sqr_exp ) ) ); /*h_dirac_output_synthesis_state->q_cy_cross_dir_smooth-> (31-sqr_exp) */
903 33535 : move32();
904 33535 : Q_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = sub( 31, sqr_exp );
905 33535 : move16();
906 : }
907 : ELSE
908 : {
909 6932412 : sqr = L_shr( sqr, sub( sub( 31, sqr_exp ), h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ) ); /*( 31- sqr_exp )-> h_dirac_output_synthesis_state->q_cy_cross_dir_smooth*/
910 6932412 : Q_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = h_dirac_output_synthesis_state->q_cy_cross_dir_smooth;
911 6932412 : move16();
912 : }
913 6965947 : h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = L_add( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k], sqr ); /*Q_temp_cy_cross_dir_smooth_fx*/
914 6965947 : move32();
915 : }
916 : ELSE
917 : {
918 2376353 : h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = L_add( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k], sqr ); /*31-sqr_exp*/
919 2376353 : move32();
920 2376353 : Q_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = sub( 31, sqr_exp );
921 2376353 : move16();
922 : }
923 : }
924 1868460 : c = Madd_32_16( ONE_IN_Q27 /*1 Q27*/, L_sub( h_dirac_output_synthesis_params->diffuse_compensation_factor_fx, ONE_IN_Q27 /*1 Q27*/ ), 5461 ); /*Diffuseness modellling nrg compensation*/ /* 1.0 / 6.0 = 5461 in Q15*/ /*Q27*/
925 : #ifdef FIX_1310_SPEEDUP_ivas_dirac_dec_output_synthesis_process_slot
926 85545120 : FOR( ; k < num_freq_bands; k++ )
927 : {
928 83676660 : a = h_dirac_output_synthesis_state->direct_responses_fx[ch_idx * num_freq_bands + k]; // Q = h_dirac_output_synthesis_state->q_direct_responses
929 83676660 : move32();
930 83676660 : IF( reference_power[k + num_freq_bands] == 0 )
931 : {
932 14036874 : sqr_inp = Mpy_32_32( diffuseness[k], c );
933 14036874 : sqr_exp = sub( 31 + 4, q_diffuseness );
934 : }
935 : ELSE
936 : {
937 : Word16 diff_c_exp;
938 : Word16 diff_aab_exp;
939 69639786 : IF( reference_power[k + ( ch_idx + 1 ) * num_freq_bands] == 0 )
940 : {
941 12248610 : mpy_a_a_b = Mpy_32_32( a, a ); // Q = (h_dirac_output_synthesis_state->q_direct_responses + (15 - b_exp) - 15) + (h_dirac_output_synthesis_state->q_direct_responses) - 31
942 12248610 : mpy_diff_aab = Mpy_32_32( L_sub( L_shl( 1, q_diffuseness ), diffuseness[k] ), mpy_a_a_b ); // Q = 2*(h_dirac_output_synthesis_state->q_direct_responses) - b_exp - 31 + q_diffuseness -31
943 12248610 : mpy_diff_c = Mpy_32_32( diffuseness[k], c ); // Q = q_diffuseness - 4
944 12248610 : diff_aab_exp = sub( 31 + 62, add( h_dirac_output_synthesis_state->direct_responses_q, add( h_dirac_output_synthesis_state->direct_responses_q, q_diffuseness ) ) );
945 12248610 : diff_c_exp = sub( 31 + 4, q_diffuseness );
946 :
947 12248610 : sqr_inp = BASOP_Util_Add_Mant32Exp( mpy_diff_c, diff_c_exp, mpy_diff_aab, diff_aab_exp, &sqr_exp ); /*q(31-sqr_exp)*/
948 : }
949 : ELSE
950 : {
951 57391176 : b = BASOP_Util_Divide3232_Scale( reference_power[k + num_freq_bands], reference_power[k + ( ch_idx + 1 ) * num_freq_bands], &b_exp ); /*q(15-b_exp)*/
952 :
953 57391176 : mpy_a_a_b = Mpy_32_32( a, Mpy_32_16_1( a, b ) ); // Q = (h_dirac_output_synthesis_state->q_direct_responses + (15 - b_exp) - 15) + (h_dirac_output_synthesis_state->q_direct_responses) - 31
954 57391176 : mpy_diff_aab = Mpy_32_32( L_sub( L_shl( 1, q_diffuseness ), diffuseness[k] ), mpy_a_a_b ); // Q = 2*(h_dirac_output_synthesis_state->q_direct_responses) - b_exp - 31 + q_diffuseness -31
955 57391176 : mpy_diff_c = Mpy_32_32( diffuseness[k], c ); // Q = q_diffuseness - 4
956 57391176 : diff_aab_exp = sub( sub( add( sub( 31 + 62, h_dirac_output_synthesis_state->direct_responses_q ), b_exp ), h_dirac_output_synthesis_state->direct_responses_q ), q_diffuseness );
957 57391176 : diff_c_exp = sub( 31 + 4, q_diffuseness );
958 :
959 57391176 : sqr_inp = BASOP_Util_Add_Mant32Exp( mpy_diff_c, diff_c_exp, mpy_diff_aab, diff_aab_exp, &sqr_exp ); /*q(31-sqr_exp)*/
960 : }
961 : }
962 83676660 : sqr = Sqrt32( sqr_inp, &sqr_exp ); /*Q(31-sqr_exp)*/
963 83676660 : sqr = L_shr( sqr, 2 ); /*Q(31-sqr_exp)*/
964 :
965 :
966 83676660 : IF( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] != 0 )
967 : {
968 60215437 : IF( LT_16( sub( 31, sqr_exp ), h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ) )
969 : {
970 106401 : h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = L_shr( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k], sub( h_dirac_output_synthesis_state->q_cy_cross_dir_smooth, sub( 31, sqr_exp ) ) ); /*h_dirac_output_synthesis_state->q_cy_cross_dir_smooth->Q( 31- sqr_exp )*/
971 106401 : move32();
972 106401 : Q_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = sub( 31, sqr_exp );
973 106401 : move16();
974 : }
975 : ELSE
976 : {
977 60109036 : sqr = L_shr( sqr, sub( sub( 31, sqr_exp ), h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ) ); /*Q(31- sqr_exp)->h_dirac_output_synthesis_state->q_cy_cross_dir_smooth*/
978 60109036 : Q_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = h_dirac_output_synthesis_state->q_cy_cross_dir_smooth;
979 60109036 : move16();
980 : }
981 60215437 : h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = L_add( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k], sqr ); /*Q_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k]*/
982 60215437 : move32();
983 : }
984 : ELSE
985 : {
986 23461223 : h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = L_add( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k], sqr ); /*Q(31- sqr_exp)*/
987 23461223 : move32();
988 23461223 : Q_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = sub( 31, sqr_exp );
989 23461223 : move16();
990 : }
991 : }
992 : #else
993 : FOR( ; k < num_freq_bands; k++ )
994 : {
995 : a = h_dirac_output_synthesis_state->direct_responses_fx[ch_idx * num_freq_bands + k]; // Q = h_dirac_output_synthesis_state->q_direct_responses
996 : move32();
997 : IF( reference_power[k + num_freq_bands] == 0 )
998 : {
999 : b = 0;
1000 : move16();
1001 : b_exp = 0;
1002 : move16();
1003 : }
1004 : ELSE
1005 : {
1006 : IF( reference_power[k + ( ch_idx + 1 ) * num_freq_bands] == 0 )
1007 : {
1008 : b = MAX_16;
1009 : move16();
1010 : b_exp = 0;
1011 : move16();
1012 : }
1013 : ELSE
1014 : {
1015 : b = BASOP_Util_Divide3232_Scale( reference_power[k + num_freq_bands], reference_power[k + ( ch_idx + 1 ) * num_freq_bands], &b_exp ); /*q(15-b_exp)*/
1016 : }
1017 : }
1018 :
1019 : mpy_a_a_b = Mpy_32_32( a, Mpy_32_16_1( a, b ) ); // Q = (h_dirac_output_synthesis_state->q_direct_responses + (15 - b_exp) - 15) + (h_dirac_output_synthesis_state->q_direct_responses) - 31
1020 : mpy_diff_aab = Mpy_32_32( L_sub( L_shl( 1, q_diffuseness ), diffuseness[k] ), mpy_a_a_b ); // Q = 2*(h_dirac_output_synthesis_state->q_direct_responses) - b_exp - 31 + q_diffuseness -31
1021 : mpy_diff_c = Mpy_32_32( diffuseness[k], c ); // Q = q_diffuseness - 4
1022 :
1023 : q_diff_aab = add( add( h_dirac_output_synthesis_state->direct_responses_q, sub( sub( 15, b_exp ), 15 ) ), add( sub( h_dirac_output_synthesis_state->direct_responses_q, 31 ), sub( q_diffuseness, 31 ) ) );
1024 : q_diff_c = sub( q_diffuseness, 4 );
1025 :
1026 : test();
1027 : IF( mpy_diff_c != 0 && mpy_diff_aab != 0 )
1028 : {
1029 : sqr_inp = BASOP_Util_Add_Mant32Exp( mpy_diff_c, sub( 31, q_diff_c ), mpy_diff_aab, sub( 31, q_diff_aab ), &sqr_exp ); /*q(31-sqr_exp)*/
1030 : }
1031 : ELSE
1032 : {
1033 : IF( mpy_diff_c == 0 )
1034 : {
1035 : sqr_inp = mpy_diff_aab; /*q_diff_aab*/
1036 : move32();
1037 : sqr_exp = sub( 31, q_diff_aab );
1038 : }
1039 : ELSE
1040 : {
1041 : sqr_inp = mpy_diff_c;
1042 : move32();
1043 : sqr_exp = sub( 31, q_diff_c ); /*q_diff_c*/
1044 : }
1045 : }
1046 : sqr = Sqrt32( sqr_inp, &sqr_exp ); /*Q(31-sqr_exp)*/
1047 : sqr = L_shr( sqr, 2 ); /*Q(31-sqr_exp)*/
1048 : IF( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] != 0 )
1049 : {
1050 : IF( LT_16( sub( 31, sqr_exp ), h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ) )
1051 : {
1052 : h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = L_shr( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k], sub( h_dirac_output_synthesis_state->q_cy_cross_dir_smooth, sub( 31, sqr_exp ) ) ); /*h_dirac_output_synthesis_state->q_cy_cross_dir_smooth->Q( 31- sqr_exp )*/
1053 : move32();
1054 : Q_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = sub( 31, sqr_exp );
1055 : move16();
1056 : }
1057 : ELSE
1058 : {
1059 : sqr = L_shr( sqr, sub( sub( 31, sqr_exp ), h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ) ); /*Q(31- sqr_exp)->h_dirac_output_synthesis_state->q_cy_cross_dir_smooth*/
1060 : Q_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = h_dirac_output_synthesis_state->q_cy_cross_dir_smooth;
1061 : move16();
1062 : }
1063 : h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = L_add( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k], sqr ); /*Q_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k]*/
1064 : move32();
1065 : }
1066 : ELSE
1067 : {
1068 : h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = L_add( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k], sqr ); /*Q(31- sqr_exp)*/
1069 : move32();
1070 : Q_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = sub( 31, sqr_exp );
1071 : move16();
1072 : }
1073 : }
1074 : #endif
1075 : }
1076 : ELSE
1077 : {
1078 : Word32 sqr_inp, mpy_diff, sqr;
1079 : Word16 sqr_exp;
1080 : /*Diffuseness modellling nrg compensation*/
1081 3736920 : FOR( k = 0; k < num_freq_bands_diff; k++ )
1082 : {
1083 : /*diffuseness[k] * 0.5f * ( h_dirac_output_synthesis_params->diffuse_compensation_factor_decorr - 1.f ) )*/
1084 3114100 : mpy_diff = Mpy_32_32( diffuseness[k], L_sub( h_dirac_output_synthesis_params->diffuse_compensation_factor_decorr_fx /*q29=0.5 * q30*/, ONE_IN_Q29 /*0.5 Q30*/ ) /*q30*/ ); // Q = q_diffuseness - 1
1085 3114100 : sqr_inp = L_add( L_shl( 1, sub( q_diffuseness, 1 ) ), mpy_diff ); // Q = q_diffuseness - 1
1086 3114100 : sqr_exp = sub( 31, sub( q_diffuseness, 1 ) );
1087 3114100 : sqr = Sqrt32( sqr_inp, &sqr_exp ); /*Q(31-sqr_exp)*/
1088 3114100 : sqr = L_shr( sqr, 2 ); /*Q(31-sqr_exp)*/
1089 3114100 : IF( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] != 0 )
1090 : {
1091 2329020 : IF( LT_16( sub( 31, sqr_exp ), h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ) )
1092 : {
1093 0 : h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = L_shr( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k], sub( h_dirac_output_synthesis_state->q_cy_cross_dir_smooth, sub( 31, sqr_exp ) ) ); /*h_dirac_output_synthesis_state->q_cy_cross_dir_smooth->Q(31- sqr_exp)*/
1094 0 : move32();
1095 0 : Q_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = sub( 31, sqr_exp );
1096 0 : move16();
1097 : }
1098 : ELSE
1099 : {
1100 2329020 : sqr = L_shr( sqr, sub( sub( 31, sqr_exp ), h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ) ); /*Q(31-sqr_exp)->h_dirac_output_synthesis_state->q_cy_cross_dir_smooth*/
1101 2329020 : Q_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = h_dirac_output_synthesis_state->q_cy_cross_dir_smooth;
1102 2329020 : move16();
1103 : }
1104 2329020 : h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = L_add( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k], sqr ); /*Q_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k]*/
1105 2329020 : move32();
1106 : }
1107 : ELSE
1108 : {
1109 785080 : h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = L_add( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k], sqr ); /*Q(31-sqr_exp)*/
1110 785080 : move32();
1111 785080 : Q_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = sub( 31, sqr_exp );
1112 785080 : move16();
1113 : }
1114 : }
1115 28515040 : FOR( ; k < num_freq_bands; k++ )
1116 : {
1117 27892220 : mpy_diff = Mpy_32_32( diffuseness[k], L_sub( h_dirac_output_synthesis_params->diffuse_compensation_factor_decorr_fx, ONE_IN_Q29 /*1 Q29*/ ) ); // Q = q_diffuseness - 1
1118 27892220 : sqr_inp = L_add( L_shl( 1, sub( q_diffuseness, 1 ) ), mpy_diff ); // Q = q_diffuseness - 1
1119 27892220 : sqr_exp = sub( 31, sub( q_diffuseness, 1 ) );
1120 27892220 : sqr = Sqrt32( sqr_inp, &sqr_exp ); /*Q(31-sqr_exp)*/
1121 27892220 : sqr = L_shr( sqr, 2 ); /*Q(31-sqr_exp)*/
1122 27892220 : IF( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] != 0 )
1123 : {
1124 20865680 : IF( LT_16( sub( 31, sqr_exp ), h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ) )
1125 : {
1126 0 : h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = L_shr( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k], sub( h_dirac_output_synthesis_state->q_cy_cross_dir_smooth, sub( 31, sqr_exp ) ) ); /*h_dirac_output_synthesis_state->q_cy_cross_dir_smooth, Q( 31- sqr_exp )*/
1127 0 : move32();
1128 0 : Q_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = sub( 31, sqr_exp );
1129 0 : move16();
1130 : }
1131 : ELSE
1132 : {
1133 20865680 : sqr = L_shr( sqr, sub( sub( 31, sqr_exp ), h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ) ); /*Q( 31- sqr_exp ), h_dirac_output_synthesis_state->q_cy_cross_dir_smooth*/
1134 20865680 : Q_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = h_dirac_output_synthesis_state->q_cy_cross_dir_smooth;
1135 20865680 : move16();
1136 : }
1137 20865680 : h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = L_add( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k], sqr ); /*Q_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k]*/
1138 20865680 : move32();
1139 : }
1140 : ELSE
1141 : {
1142 7026540 : h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = L_add( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k], sqr ); /*Q(31-sqr_exp)*/
1143 7026540 : move32();
1144 7026540 : Q_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = sub( 31, sqr_exp );
1145 7026540 : move16();
1146 : }
1147 : }
1148 : }
1149 : }
1150 622820 : Word16 temp = MAX_16; /*q0*/
1151 622820 : move16();
1152 622820 : tmp16 = imult1616( num_freq_bands, num_channels_dir );
1153 483283940 : FOR( Word16 kk = 0; kk < tmp16; kk++ )
1154 : {
1155 482661120 : temp = s_min( Q_temp_cy_cross_dir_smooth_fx[kk], temp );
1156 : }
1157 622820 : h_dirac_output_synthesis_state->q_cy_cross_dir_smooth = temp;
1158 622820 : move16();
1159 483283940 : FOR( Word16 kk = 0; kk < tmp16; kk++ )
1160 : {
1161 482661120 : h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[kk] = L_shl( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[kk], sub( temp, Q_temp_cy_cross_dir_smooth_fx[kk] ) ); /*Q_temp_cy_cross_dir_smooth_fx[kk]->temp*/
1162 482661120 : move32();
1163 : }
1164 622820 : free( Q_temp_cy_cross_dir_smooth_fx );
1165 : /*Directional gain (panning)*/
1166 622820 : Word16 temp_q = sub( add( h_dirac_output_synthesis_state->direct_power_factor_q, h_dirac_output_synthesis_state->direct_responses_q ), 31 );
1167 622820 : IF( LT_16( temp_q, h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ) )
1168 : {
1169 0 : Word16 temp_q1 = sub( temp_q, h_dirac_output_synthesis_state->q_cy_cross_dir_smooth );
1170 0 : FOR( Word16 kk = 0; kk < tmp16; kk++ )
1171 : {
1172 0 : h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[kk] = L_shl( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[kk], temp_q1 ); /*h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ->temp_q*/
1173 0 : move32();
1174 : }
1175 0 : h_dirac_output_synthesis_state->q_cy_cross_dir_smooth = temp_q;
1176 0 : move16();
1177 : }
1178 622820 : Word16 temp_q1 = sub( h_dirac_output_synthesis_state->q_cy_cross_dir_smooth, temp_q );
1179 7872660 : FOR( ch_idx = s_min( 4, nchan_transport ); ch_idx < num_channels_dir; ch_idx++ )
1180 : {
1181 7249840 : IF( NE_16( temp_q, h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ) )
1182 : {
1183 : Word16 i;
1184 : Word32 aux;
1185 7105517 : IF( temp_q1 < 0 )
1186 : {
1187 7105517 : Word32 temp_q1_equiv = L_lshl( (Word32) 0x80000000, temp_q1 );
1188 358685897 : FOR( i = 0; i < num_freq_bands; i++ )
1189 : {
1190 351580380 : aux = Mpy_32_32( h_dirac_output_synthesis_state->direct_power_factor_fx[i], h_dirac_output_synthesis_state->direct_responses_fx[ch_idx * num_freq_bands + i] );
1191 351580380 : h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + i] = Madd_32_32( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + i], aux, temp_q1_equiv );
1192 351580380 : move32();
1193 : }
1194 : }
1195 : ELSE
1196 : {
1197 0 : FOR( i = 0; i < num_freq_bands; i++ )
1198 : {
1199 0 : aux = Mpy_32_32( h_dirac_output_synthesis_state->direct_power_factor_fx[i], h_dirac_output_synthesis_state->direct_responses_fx[ch_idx * num_freq_bands + i] );
1200 0 : aux = L_shl( aux, temp_q1 );
1201 0 : h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + i] = L_add( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + i], aux );
1202 0 : move32();
1203 : }
1204 : }
1205 : }
1206 : ELSE
1207 : {
1208 : Word16 i;
1209 7199783 : FOR( i = 0; i < num_freq_bands; i++ )
1210 : {
1211 7055460 : h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + i] = Madd_32_32( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + i], h_dirac_output_synthesis_state->direct_power_factor_fx[i], h_dirac_output_synthesis_state->direct_responses_fx[ch_idx * num_freq_bands + i] );
1212 7055460 : move32();
1213 : }
1214 : }
1215 : }
1216 :
1217 :
1218 : /*Diffuse gain*/
1219 622820 : FOR( ch_idx = s_min( 4, nchan_transport ); ch_idx < num_channels_diff; ch_idx++ )
1220 : {
1221 0 : v_multc_fixed_16( h_dirac_output_synthesis_state->diffuse_power_factor_fx,
1222 0 : hDirACRend->diffuse_response_function_fx[ch_idx],
1223 : aux_buf,
1224 : num_freq_bands_diff ); /* h_dirac_output_synthesis_state->diffuse_power_factor_q+15-15*/
1225 0 : temp_q = h_dirac_output_synthesis_state->diffuse_power_factor_q;
1226 0 : IF( NE_16( temp_q, h_dirac_output_synthesis_state->q_cy_auto_diff_smooth ) )
1227 : {
1228 0 : Scale_sig32( aux_buf, num_freq_bands, sub( h_dirac_output_synthesis_state->q_cy_auto_diff_smooth, temp_q ) ); /*temp_q->(h_dirac_output_synthesis_state->q_cy_auto_diff_smooth)*/
1229 : }
1230 : #ifdef VEC_ARITH_OPT_v1
1231 0 : v_add_fixed_no_hdrm( aux_buf,
1232 0 : &h_dirac_output_synthesis_state->cy_auto_diff_smooth_fx[ch_idx * num_freq_bands_diff],
1233 0 : &h_dirac_output_synthesis_state->cy_auto_diff_smooth_fx[ch_idx * num_freq_bands_diff],
1234 : num_freq_bands_diff ); /*h_dirac_output_synthesis_state->q_cy_auto_diff_smooth*/
1235 : #else /* VEC_ARITH_OPT_v1 */
1236 : v_add_fixed( aux_buf,
1237 : &h_dirac_output_synthesis_state->cy_auto_diff_smooth_fx[ch_idx * num_freq_bands_diff],
1238 : &h_dirac_output_synthesis_state->cy_auto_diff_smooth_fx[ch_idx * num_freq_bands_diff],
1239 : num_freq_bands_diff, 0 ); /*h_dirac_output_synthesis_state->q_cy_auto_diff_smooth*/
1240 : #endif /* VEC_ARITH_OPT_v1 */
1241 : }
1242 :
1243 622820 : return;
1244 : }
1245 : ELSE
1246 : {
1247 : /* compute reference and diffuse power factor for this frame */
1248 72000 : ivas_dirac_dec_compute_power_factors_fx( num_freq_bands,
1249 : diffuseness,
1250 72000 : h_dirac_output_synthesis_params->max_band_decorr,
1251 : h_dirac_output_synthesis_state->direct_power_factor_fx,
1252 : h_dirac_output_synthesis_state->diffuse_power_factor_fx );
1253 :
1254 72000 : Scale_sig32( h_dirac_output_synthesis_state->direct_power_factor_fx, num_freq_bands, 2 ); /*q29->q31*/
1255 72000 : Scale_sig32( h_dirac_output_synthesis_state->diffuse_power_factor_fx, num_freq_bands, 2 ); /*q29->q31*/
1256 72000 : h_dirac_output_synthesis_state->diffuse_power_factor_q = 31;
1257 72000 : move16();
1258 72000 : h_dirac_output_synthesis_state->direct_power_factor_q = 31;
1259 72000 : move16();
1260 : }
1261 : }
1262 :
1263 642445 : diff_start_band = 0;
1264 642445 : move16();
1265 642445 : IF( h_dirac_output_synthesis_params->use_onset_filters )
1266 : {
1267 209936 : computeTargetPSDs_diffuse_with_onsets_fx( num_channels_dir,
1268 209936 : num_freq_bands, h_dirac_output_synthesis_params->max_band_decorr,
1269 209936 : hDirACRend->proto_index_diff,
1270 209936 : h_dirac_output_synthesis_state->diffuse_power_factor_fx,
1271 : reference_power,
1272 : #ifdef FIX_867_CLDFB_NRG_SCALE
1273 : q_reference_power,
1274 : #else
1275 : &q_reference_power,
1276 : #endif
1277 209936 : h_dirac_output_synthesis_state->diffuse_responses_square_fx,
1278 : onset,
1279 : h_dirac_output_synthesis_state->cy_auto_diff_smooth_fx,
1280 : &h_dirac_output_synthesis_state->q_cy_auto_diff_smooth );
1281 :
1282 209936 : diff_start_band = h_dirac_output_synthesis_params->max_band_decorr;
1283 209936 : move16();
1284 : }
1285 :
1286 : /* process other PSDs only slot wise for 4 transport channels */
1287 642445 : IF( EQ_16( dec_param_estim, TRUE ) )
1288 : {
1289 : #ifdef FIX_867_CLDFB_NRG_SCALE
1290 72000 : computeTargetPSDs_direct_fx( num_channels_dir, num_freq_bands, h_dirac_output_synthesis_state->direct_power_factor_fx, reference_power, q_reference_power, h_dirac_output_synthesis_state->direct_responses_fx, h_dirac_output_synthesis_state->direct_responses_square_fx, h_dirac_output_synthesis_state->cy_auto_dir_smooth_fx, &h_dirac_output_synthesis_state->q_cy_auto_dir_smooth, h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx, &h_dirac_output_synthesis_state->q_cy_cross_dir_smooth );
1291 :
1292 72000 : computeTargetPSDs_diffuse_fx( num_channels_dir, num_freq_bands, diff_start_band, h_dirac_output_synthesis_state->diffuse_power_factor_fx, reference_power, q_reference_power, h_dirac_output_synthesis_state->diffuse_responses_square_fx, h_dirac_output_synthesis_state->cy_auto_diff_smooth_fx, &h_dirac_output_synthesis_state->q_cy_auto_diff_smooth );
1293 : #else
1294 : computeTargetPSDs_direct_fx( num_channels_dir, num_freq_bands, h_dirac_output_synthesis_state->direct_power_factor_fx, reference_power, &q_reference_power, h_dirac_output_synthesis_state->direct_responses_fx, h_dirac_output_synthesis_state->direct_responses_square_fx, h_dirac_output_synthesis_state->cy_auto_dir_smooth_fx, &h_dirac_output_synthesis_state->q_cy_auto_dir_smooth, h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx, &h_dirac_output_synthesis_state->q_cy_cross_dir_smooth );
1295 :
1296 : computeTargetPSDs_diffuse_fx( num_channels_dir, num_freq_bands, diff_start_band, h_dirac_output_synthesis_state->diffuse_power_factor_fx, reference_power, &q_reference_power, h_dirac_output_synthesis_state->diffuse_responses_square_fx, h_dirac_output_synthesis_state->cy_auto_diff_smooth_fx, &h_dirac_output_synthesis_state->q_cy_auto_diff_smooth );
1297 : #endif
1298 : }
1299 :
1300 642445 : return;
1301 : }
1302 :
1303 :
1304 : /*-------------------------------------------------------------------------
1305 : * ivas_dirac_dec_output_synthesis_process_subframe_gain_shd()
1306 : *
1307 : *
1308 : *------------------------------------------------------------------------*/
1309 :
1310 222420 : void ivas_dirac_dec_output_synthesis_process_subframe_gain_shd_fx(
1311 : Word32 RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : LS signals */
1312 : Word32 ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : LS signals */
1313 : SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common spatial renderer data handle */
1314 : DIRAC_REND_HANDLE hDirACRend, /* i/o: DirAC renderer handle */
1315 : const Word16 nchan_transport, /* i : number of transport channels */
1316 : const Word16 nbslots, /* i : number of slots to process */
1317 : const Word32 *onset_filter, /* Q31 */
1318 : Word32 *diffuseness, // Q30
1319 : const Word16 hodirac_flag, /* i : flag to indicate HO-DirAC mode */
1320 : const Word16 dec_param_estim,
1321 : Word16 *q_cy_cross_dir_smooth_prev,
1322 : Word16 *q_cy_auto_diff_smooth_prev )
1323 : {
1324 : Word16 buf_idx, ch_idx, i, l;
1325 : Word16 num_freq_bands, num_freq_bands_diff;
1326 : Word16 num_channels_dir, num_channels_diff;
1327 : Word32 g, g1[MAX_FREQUENCY_BANDS], g2;
1328 : Word32 *p_gains_dir, *p_gains_diff;
1329 : Word32 *p_gains_dir_prev, *p_gains_diff_prev;
1330 : Word32 *p_cy_cross_dir_smooth;
1331 : Word32 *p_cy_auto_diff_smooth;
1332 : Word32 *p_proto, *p_out_real, *p_out_imag;
1333 : Word32 *p_proto_diff;
1334 : Word16 *proto_direct_index, num_protos_dir;
1335 : Word32 output_real[CLDFB_NO_CHANNELS_MAX * MAX_OUTPUT_CHANNELS];
1336 : Word32 output_imag[CLDFB_NO_CHANNELS_MAX * MAX_OUTPUT_CHANNELS];
1337 : DIRAC_OUTPUT_SYNTHESIS_PARAMS h_dirac_output_synthesis_params;
1338 : DIRAC_OUTPUT_SYNTHESIS_STATE h_dirac_output_synthesis_state;
1339 : Word16 nchan_transport_foa;
1340 : Word16 ch_idx_diff;
1341 : Word32 cmp1, cmp2;
1342 : Word32 aux_buf[CLDFB_NO_CHANNELS_MAX];
1343 : Word32 ratio_float[DIRAC_HO_NUMSECTORS * CLDFB_NO_CHANNELS_MAX];
1344 222420 : Word16 q_com = 0;
1345 222420 : move16();
1346 222420 : Word16 exp = 0;
1347 222420 : move16();
1348 : Word16 q_shift;
1349 :
1350 : /* collect some often used parameters */
1351 222420 : h_dirac_output_synthesis_params = hDirACRend->h_output_synthesis_psd_params;
1352 222420 : h_dirac_output_synthesis_state = hDirACRend->h_output_synthesis_psd_state;
1353 222420 : proto_direct_index = hDirACRend->proto_index_dir;
1354 :
1355 222420 : num_protos_dir = hDirACRend->num_protos_dir;
1356 222420 : move16();
1357 222420 : num_freq_bands = hSpatParamRendCom->num_freq_bands;
1358 222420 : move16();
1359 222420 : num_freq_bands_diff = h_dirac_output_synthesis_params.max_band_decorr;
1360 222420 : move16();
1361 222420 : num_channels_dir = hDirACRend->num_outputs_dir;
1362 222420 : move16();
1363 222420 : num_channels_diff = hDirACRend->num_outputs_diff;
1364 222420 : move16();
1365 222420 : nchan_transport_foa = s_min( 4, nchan_transport );
1366 222420 : move16();
1367 :
1368 222420 : Word16 prod = imult1616( num_freq_bands, num_channels_dir );
1369 : /*-----------------------------------------------------------------*
1370 : * comput target Gains
1371 : *-----------------------------------------------------------------*/
1372 :
1373 222420 : IF( hodirac_flag )
1374 : {
1375 : /*Direct gain*/
1376 265780 : FOR( ch_idx = 0; ch_idx < nchan_transport_foa; ch_idx++ )
1377 : {
1378 212624 : v_multc_fixed( diffuseness, // Q30
1379 : ONE_IN_Q31, // Q31
1380 212624 : &h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands], // Q30
1381 : num_freq_bands );
1382 212624 : v_multc_fixed( &h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands], // Q30
1383 : L_sub( h_dirac_output_synthesis_params.diffuse_compensation_factor_fx, ONE_IN_Q27 ), // Q27
1384 212624 : &h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands], // Q26
1385 : num_freq_bands );
1386 :
1387 12861264 : FOR( l = 0; l < num_freq_bands; l++ )
1388 : {
1389 12648640 : exp = Q31 - Q26;
1390 25297280 : h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + l] =
1391 12648640 : Sqrt32( L_add( ONE_IN_Q26 /*1 in Q26*/, h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + l] ),
1392 : &exp ); // (Q31 - exp)
1393 12648640 : move32();
1394 : }
1395 :
1396 : // Scale to bring in common Q-factor
1397 212624 : q_com = s_min( h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev, sub( Q31, exp ) );
1398 212624 : Scale_sig32( &h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands],
1399 : num_freq_bands,
1400 212624 : sub( q_com, sub( Q31, exp ) ) ); /*Q( Q31- exp)->q_com*/
1401 212624 : Scale_sig32( &h_dirac_output_synthesis_state.cy_cross_dir_smooth_prev_fx[ch_idx * num_freq_bands],
1402 : num_freq_bands,
1403 212624 : sub( q_com, h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev ) ); /*h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev->q_com*/
1404 : }
1405 :
1406 3215316 : FOR( l = 0; l < num_freq_bands; l++ )
1407 : {
1408 3162160 : aux_buf[l] = L_sub( ONE_IN_Q30, diffuseness[l] ); // Q30
1409 3162160 : move32();
1410 3162160 : ratio_float[l] = L_sub( ONE_IN_Q31, h_dirac_output_synthesis_state.direct_power_factor_fx[num_freq_bands + l] ); // Q31
1411 3162160 : move32();
1412 3162160 : ratio_float[l + num_freq_bands] = L_sub( ONE_IN_Q31, ratio_float[l] ); // Q31
1413 3162160 : move32();
1414 : }
1415 :
1416 53156 : v_mult_fixed( aux_buf, ratio_float, ratio_float, num_freq_bands ); //(Q30, Q31) -> Q30
1417 53156 : v_mult_fixed( aux_buf, &ratio_float[num_freq_bands], &ratio_float[num_freq_bands], num_freq_bands ); //(Q30, Q31) -> Q30
1418 :
1419 : /*Directional gain*/
1420 635028 : FOR( ch_idx = nchan_transport_foa; ch_idx < num_channels_dir; ch_idx++ )
1421 : {
1422 581872 : v_mult_fixed( ratio_float, // Q30
1423 581872 : &h_dirac_output_synthesis_state.direct_responses_fx[ch_idx * num_freq_bands], // Q31
1424 581872 : &h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands], //(Q30, Q31) -> Q30
1425 : num_freq_bands );
1426 581872 : v_mult_fixed( &ratio_float[num_freq_bands], // Q30
1427 581872 : &h_dirac_output_synthesis_state.direct_responses_fx[ch_idx * num_freq_bands + num_freq_bands * num_channels_dir], // Q31
1428 581872 : &h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + num_freq_bands * num_channels_dir], //(Q30, Q31) -> Q30
1429 : num_freq_bands );
1430 :
1431 : // Scale to bring in common Q-factor
1432 581872 : q_com = s_min( h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev, Q30 );
1433 581872 : Scale_sig32( &h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands],
1434 : num_freq_bands,
1435 581872 : sub( q_com, Q30 ) ); /*Q30->q_com*/
1436 581872 : Scale_sig32( &h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + num_freq_bands * num_channels_dir],
1437 : num_freq_bands,
1438 581872 : sub( q_com, Q30 ) ); /*Q30->q_com*/
1439 581872 : Scale_sig32( &h_dirac_output_synthesis_state.cy_cross_dir_smooth_prev_fx[ch_idx * num_freq_bands],
1440 : num_freq_bands,
1441 581872 : sub( q_com, h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev ) ); /*h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev->q_com*/
1442 581872 : Scale_sig32( &h_dirac_output_synthesis_state.cy_cross_dir_smooth_prev_fx[ch_idx * num_freq_bands + num_freq_bands * num_channels_dir],
1443 : num_freq_bands,
1444 581872 : sub( q_com, h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev ) ); /*h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev->q_com*/
1445 : }
1446 :
1447 53156 : h_dirac_output_synthesis_state.q_cy_cross_dir_smooth = q_com;
1448 53156 : move16();
1449 53156 : h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev = q_com;
1450 53156 : move16();
1451 :
1452 : /*Diffuse gain*/
1453 53156 : FOR( ch_idx = nchan_transport_foa; ch_idx < num_channels_diff; ch_idx++ )
1454 : {
1455 0 : v_multc_fixed_16( h_dirac_output_synthesis_state.diffuse_power_factor_fx, // Q31
1456 0 : hDirACRend->diffuse_response_function_fx[ch_idx], // Q15
1457 0 : &h_dirac_output_synthesis_state.cy_auto_diff_smooth_fx[ch_idx * num_freq_bands_diff], // Q31
1458 : num_freq_bands_diff );
1459 :
1460 : // Scale to bring in common Q-factor
1461 0 : q_com = s_min( h_dirac_output_synthesis_state.q_cy_auto_diff_smooth_prev, Q31 );
1462 0 : Scale_sig32( &h_dirac_output_synthesis_state.cy_auto_diff_smooth_fx[ch_idx * num_freq_bands_diff],
1463 : num_freq_bands_diff,
1464 0 : sub( q_com, Q31 ) ); /*q31->q_com*/
1465 0 : Scale_sig32( &h_dirac_output_synthesis_state.cy_auto_diff_smooth_prev_fx[ch_idx * num_freq_bands_diff],
1466 : num_freq_bands_diff,
1467 0 : sub( q_com, h_dirac_output_synthesis_state.q_cy_auto_diff_smooth_prev ) ); /* h_dirac_output_synthesis_state.q_cy_auto_diff_smooth_prev->q_com*/
1468 : }
1469 :
1470 53156 : h_dirac_output_synthesis_state.q_cy_auto_diff_smooth = q_com;
1471 53156 : move16();
1472 53156 : h_dirac_output_synthesis_state.q_cy_auto_diff_smooth_prev = q_com;
1473 53156 : move16();
1474 : }
1475 169264 : ELSE IF( EQ_16( dec_param_estim, FALSE ) )
1476 : {
1477 : /*Direct gain*/
1478 24496 : FOR( ch_idx = 0; ch_idx < nchan_transport_foa; ch_idx++ )
1479 : {
1480 12248 : v_mult_fixed( h_dirac_output_synthesis_state.diffuse_power_factor_fx, // Q31
1481 12248 : h_dirac_output_synthesis_state.diffuse_power_factor_fx, // Q31
1482 12248 : &h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands], // Q31
1483 : num_freq_bands );
1484 12248 : v_multc_fixed( &h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands], // Q31
1485 : L_sub( L_shr( h_dirac_output_synthesis_params.diffuse_compensation_factor_decorr_fx, Q3 ), ONE_IN_Q26 ), // Q26
1486 12248 : &h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands], // Q26
1487 : num_freq_bands_diff );
1488 12248 : v_multc_fixed( &h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + num_freq_bands_diff], // Q31
1489 : L_sub( L_shr( h_dirac_output_synthesis_params.diffuse_compensation_factor_fx, Q1 ), ONE_IN_Q26 ), // Q26
1490 12248 : &h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + num_freq_bands_diff], // Q26
1491 12248 : num_freq_bands - num_freq_bands_diff );
1492 :
1493 747128 : FOR( l = 0; l < num_freq_bands; l++ )
1494 : {
1495 734880 : exp = Q31 - Q26;
1496 1469760 : h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + l] =
1497 734880 : Sqrt32( L_add( ONE_IN_Q26, h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + l] ),
1498 : &exp ); // (Q31 - exp)
1499 734880 : move32();
1500 : }
1501 :
1502 : // Scale to bring in common Q-factor
1503 12248 : q_com = s_min( h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev, sub( Q31, exp ) );
1504 12248 : Scale_sig32( &h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands],
1505 : num_freq_bands,
1506 12248 : sub( q_com, sub( Q31, exp ) ) ); /*( Q31- exp )->q_com*/
1507 12248 : Scale_sig32( &h_dirac_output_synthesis_state.cy_cross_dir_smooth_prev_fx[ch_idx * num_freq_bands],
1508 : num_freq_bands,
1509 12248 : sub( q_com, h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev ) ); /*h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev->q_com*/
1510 : }
1511 :
1512 : /*Directional gain*/
1513 76592 : FOR( ch_idx = nchan_transport_foa; ch_idx < num_channels_dir; ch_idx++ )
1514 : {
1515 64344 : v_mult_fixed( h_dirac_output_synthesis_state.direct_power_factor_fx, // Q31
1516 64344 : &h_dirac_output_synthesis_state.direct_responses_fx[ch_idx * num_freq_bands], // Q31
1517 64344 : &h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands], // Q31
1518 : num_freq_bands );
1519 :
1520 : // Scale to bring in common Q-factor
1521 64344 : q_com = s_min( h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev, Q31 );
1522 64344 : Scale_sig32( &h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands],
1523 : num_freq_bands,
1524 64344 : sub( q_com, Q31 ) ); /*q31->q_com*/
1525 64344 : Scale_sig32( &h_dirac_output_synthesis_state.cy_cross_dir_smooth_prev_fx[ch_idx * num_freq_bands],
1526 : num_freq_bands,
1527 64344 : sub( q_com, h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev ) ); /*h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev->q_com*/
1528 : }
1529 :
1530 12248 : h_dirac_output_synthesis_state.q_cy_cross_dir_smooth = q_com;
1531 12248 : move16();
1532 12248 : h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev = q_com;
1533 12248 : move16();
1534 :
1535 : /*Diffuse gain*/
1536 12248 : q_com = s_min( h_dirac_output_synthesis_state.q_cy_auto_diff_smooth_prev, Q31 );
1537 48992 : FOR( ch_idx = nchan_transport_foa; ch_idx < num_channels_diff; ch_idx++ )
1538 : {
1539 36744 : v_multc_fixed_16( h_dirac_output_synthesis_state.diffuse_power_factor_fx, // Q31
1540 36744 : hDirACRend->diffuse_response_function_fx[ch_idx], // Q15
1541 36744 : &h_dirac_output_synthesis_state.cy_auto_diff_smooth_fx[ch_idx * num_freq_bands_diff], // Q31
1542 : num_freq_bands_diff );
1543 :
1544 : // Scale to bring in common Q-factor
1545 36744 : Scale_sig32( &h_dirac_output_synthesis_state.cy_auto_diff_smooth_fx[ch_idx * num_freq_bands_diff],
1546 : num_freq_bands_diff,
1547 36744 : sub( q_com, Q31 ) ); /*q31->q_com*/
1548 36744 : Scale_sig32( &h_dirac_output_synthesis_state.cy_auto_diff_smooth_prev_fx[ch_idx * num_freq_bands_diff],
1549 : num_freq_bands_diff,
1550 36744 : sub( q_com, h_dirac_output_synthesis_state.q_cy_auto_diff_smooth_prev ) ); /*h_dirac_output_synthesis_state.q_cy_auto_diff_smooth_prev->q_com*/
1551 : }
1552 :
1553 12248 : h_dirac_output_synthesis_state.q_cy_auto_diff_smooth = q_com;
1554 12248 : move16();
1555 12248 : h_dirac_output_synthesis_state.q_cy_auto_diff_smooth_prev = q_com;
1556 12248 : move16();
1557 : }
1558 :
1559 : /*-----------------------------------------------------------------*
1560 : * compute gains
1561 : *-----------------------------------------------------------------*/
1562 :
1563 222420 : p_cy_cross_dir_smooth = h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx;
1564 222420 : p_gains_dir = h_dirac_output_synthesis_state.cy_cross_dir_smooth_prev_fx;
1565 :
1566 11931080 : FOR( l = 0; l < num_freq_bands; l++ )
1567 : {
1568 11708660 : g1[l] = Madd_32_32( POINT_3679_Q31, onset_filter[l], POINT_1175_Q31 - POINT_3679_Q31 ); // Q31, (Q31, Q31) -> Q31
1569 11708660 : move32();
1570 : }
1571 :
1572 222420 : q_shift = sub( 26, h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev );
1573 222420 : move16();
1574 :
1575 : /* Direct gains */
1576 222420 : IF( hodirac_flag )
1577 : {
1578 53156 : cmp1 = L_shr( 66437775 /* 0.99f in Q26 */, q_shift );
1579 53156 : cmp2 = L_shr( ONE_IN_Q27 /* 2.0f in Q26 */, q_shift );
1580 265780 : FOR( ch_idx = 0; ch_idx < nchan_transport_foa; ch_idx++ )
1581 : {
1582 12861264 : FOR( l = 0; l < num_freq_bands; l++ )
1583 : {
1584 12648640 : g2 = Mpy_32_32( L_sub( ONE_IN_Q31, g1[l] ), *( p_gains_dir ) ); // (Q31, p_gains_dir_q) -> p_gains_dir_q
1585 12648640 : g2 = L_add_sat( g2, Mpy_32_32( g1[l], ( *( p_cy_cross_dir_smooth++ ) ) ) ); // p_gains_diff_q, (Q31, p_gains_diff_q) -> p_gains_diff_q
1586 12648640 : g2 = L_max( g2, cmp1 ); // p_gains_dir_q
1587 12648640 : g2 = L_min( g2, cmp2 ); // p_gains_dir_q
1588 12648640 : *( p_gains_dir++ ) = g2; // p_gains_dir_q
1589 12648640 : move32();
1590 : }
1591 : }
1592 : }
1593 : ELSE
1594 : {
1595 169264 : cmp1 = L_shr( 57042534 /* 0.85f in Q26 */, q_shift );
1596 169264 : cmp2 = L_shr( 77175193 /* 1.15f in Q26 */, q_shift );
1597 809576 : FOR( ch_idx = 0; ch_idx < nchan_transport_foa; ch_idx++ )
1598 : {
1599 32621672 : FOR( l = 0; l < num_freq_bands; l++ )
1600 : {
1601 31981360 : g2 = Mpy_32_32( L_sub( ONE_IN_Q31, g1[l] ), *( p_gains_dir ) ); // (Q31, p_gains_dir_q) -> p_gains_dir_q
1602 31981360 : g2 = L_add_sat( g2, Mpy_32_32( g1[l], ( *( p_cy_cross_dir_smooth++ ) ) ) ); // p_gains_diff_q, (Q31, p_gains_diff_q) -> p_gains_diff_q
1603 31981360 : g2 = L_max( g2, cmp1 ); // p_gains_dir_q
1604 31981360 : g2 = L_min( g2, cmp2 ); // p_gains_dir_q
1605 31981360 : *( p_gains_dir++ ) = g2; // p_gains_dir_q
1606 31981360 : move32();
1607 : }
1608 : }
1609 : }
1610 :
1611 : /*Directional gains*/
1612 222420 : cmp1 = L_shr( -DIRAC_GAIN_LIMIT_Q26, q_shift );
1613 222420 : cmp2 = L_negate( cmp1 );
1614 2696828 : FOR( ch_idx = nchan_transport_foa; ch_idx < num_channels_dir; ch_idx++ )
1615 : {
1616 131300408 : FOR( l = 0; l < num_freq_bands; l++ )
1617 : {
1618 128826000 : g2 = Mpy_32_32( L_sub( ONE_IN_Q31, g1[l] ), *( p_gains_dir ) ); // (Q31, p_gains_dir_q) -> p_gains_dir_q
1619 128826000 : g2 = L_add_sat( g2, Mpy_32_32( g1[l], ( *( p_cy_cross_dir_smooth++ ) ) ) ); // p_gains_diff_q, (Q31, p_gains_diff_q) -> p_gains_diff_q
1620 128826000 : g2 = L_max( g2, cmp1 ); // p_gains_dir_q
1621 128826000 : g2 = L_min( g2, cmp2 ); // p_gains_dir_q
1622 128826000 : *( p_gains_dir++ ) = g2; // p_gains_dir_q
1623 128826000 : move32();
1624 : }
1625 : }
1626 :
1627 222420 : IF( hodirac_flag )
1628 : {
1629 53156 : p_cy_cross_dir_smooth = h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx + prod;
1630 53156 : p_gains_dir = h_dirac_output_synthesis_state.cy_cross_dir_smooth_prev_fx + prod;
1631 :
1632 : /*Direct gains*/
1633 265780 : FOR( ch_idx = 0; ch_idx < nchan_transport_foa; ch_idx++ )
1634 : {
1635 12861264 : FOR( l = 0; l < num_freq_bands; l++ )
1636 : {
1637 12648640 : p_cy_cross_dir_smooth++;
1638 12648640 : p_gains_dir++;
1639 : }
1640 : }
1641 :
1642 : /*Directional gains*/
1643 635028 : FOR( ch_idx = nchan_transport_foa; ch_idx < num_channels_dir; ch_idx++ )
1644 : {
1645 35167792 : FOR( l = 0; l < num_freq_bands; l++ )
1646 : {
1647 34585920 : g2 = Mpy_32_32( L_sub( ONE_IN_Q31, g1[l] ), *( p_gains_dir ) ); // (Q31, p_gains_dir_q) -> p_gains_dir_q
1648 34585920 : g2 = L_add_sat( g2, Mpy_32_32( g1[l], ( *( p_cy_cross_dir_smooth++ ) ) ) ); // (p_gains_diff_q, (Q31, p_gains_diff_q) -> p_gains_diff_q
1649 34585920 : g2 = L_max( g2, cmp1 ); // p_gains_dir_q
1650 34585920 : g2 = L_min( g2, cmp2 ); // p_gains_dir_q
1651 34585920 : *( p_gains_dir++ ) = g2; // p_gains_dir_q
1652 34585920 : move32();
1653 : }
1654 : }
1655 : }
1656 :
1657 : /*Diffuse gains*/
1658 222420 : p_cy_auto_diff_smooth = h_dirac_output_synthesis_state.cy_auto_diff_smooth_fx + imult1616( nchan_transport_foa, num_freq_bands_diff );
1659 222420 : p_gains_diff = h_dirac_output_synthesis_state.cy_auto_diff_smooth_prev_fx + imult1616( nchan_transport_foa, num_freq_bands_diff );
1660 222420 : g1[0] = POINT_1175_Q31; // Q31
1661 222420 : move32();
1662 259164 : FOR( ch_idx = nchan_transport_foa; ch_idx < num_channels_diff; ch_idx++ )
1663 : {
1664 845112 : FOR( l = 0; l < num_freq_bands_diff; l++ )
1665 : {
1666 808368 : move32();
1667 808368 : g2 = Mpy_32_32( L_sub( ONE_IN_Q31, g1[0] ), *( p_gains_diff ) ); // (Q31, p_gains_dir_q) -> p_gains_dir_q
1668 808368 : g2 = L_add_sat( g2, Mpy_32_32( g1[0], ( *( p_cy_auto_diff_smooth++ ) ) ) ); // p_gains_diff_q, (Q31, p_gains_diff_q) -> p_gains_diff_q
1669 808368 : g2 = L_max( g2, 0 ); // p_gains_diff_q
1670 808368 : g2 = L_min( g2, cmp2 ); // p_gains_diff_q
1671 808368 : *( p_gains_diff++ ) = g2; // p_gains_diff_q
1672 808368 : move32();
1673 : }
1674 : }
1675 :
1676 : /*-----------------------------------------------------------------*
1677 : * gain interpolation and output streams
1678 : *-----------------------------------------------------------------*/
1679 :
1680 1106856 : FOR( buf_idx = 0; buf_idx < nbslots; ++buf_idx )
1681 : {
1682 884436 : g1[0] = L_deposit_h( h_dirac_output_synthesis_params.interpolator_fx[buf_idx] ); // Q31
1683 884436 : move32();
1684 884436 : g2 = L_sub( ONE_IN_Q31, g1[0] ); // Q31
1685 :
1686 : /*Direct input->output*/
1687 884436 : p_gains_dir = h_dirac_output_synthesis_state.cy_cross_dir_smooth_prev_fx; // (p_gains_dir_q)
1688 884436 : p_gains_dir_prev = h_dirac_output_synthesis_state.gains_dir_prev_fx;
1689 14109908 : FOR( ch_idx = 0; ch_idx < num_channels_dir; ch_idx++ )
1690 : {
1691 13225472 : Scale_sig32( &h_dirac_output_synthesis_state.gains_dir_prev_fx[ch_idx * num_freq_bands],
1692 : num_freq_bands,
1693 13225472 : sub( h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev, h_dirac_output_synthesis_state.gains_dir_prev_q ) ); /*h_dirac_output_synthesis_state.gains_dir_prev_q->h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev*/
1694 : }
1695 884436 : h_dirac_output_synthesis_state.gains_dir_prev_q = h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev;
1696 884436 : move16();
1697 :
1698 4275204 : FOR( ch_idx = 0; ch_idx < nchan_transport_foa; ch_idx++ )
1699 : {
1700 6781536 : p_proto_diff = h_dirac_output_synthesis_state.proto_diffuse_buffer_f_fx +
1701 3390768 : shl( i_mult( buf_idx, i_mult( num_freq_bands, num_channels_diff ) ), Q1 ) +
1702 3390768 : shl( ch_idx * num_freq_bands, Q1 );
1703 180950128 : FOR( l = 0; l < num_freq_bands; l++ )
1704 : {
1705 177559360 : g = Madd_32_32( Mpy_32_32( g1[0], ( *( p_gains_dir++ ) ) ), g2, ( *( p_gains_dir_prev++ ) ) ); // (Q31, p_gains_dir_q) -> (p_gains_dir_q)
1706 :
1707 177559360 : output_real[l * num_channels_dir + ch_idx] = Mpy_32_32( g, ( *( p_proto_diff++ ) ) ); // (p_gains_dir_q, p_proto_diff_q) -> (p_gains_dir_q + p_proto_diff_q - 31)
1708 177559360 : move32();
1709 177559360 : output_imag[l * num_channels_dir + ch_idx] = Mpy_32_32( g, ( *( p_proto_diff++ ) ) ); // (p_gains_dir_q, p_proto_diff_q) -> (p_gains_dir_q + p_proto_diff_q - 31)
1710 177559360 : move32();
1711 : }
1712 : }
1713 :
1714 : /*Directional stream*/
1715 884436 : Word16 offset = shl( i_mult( buf_idx, i_mult( num_freq_bands, num_protos_dir ) ), Q1 );
1716 10719140 : FOR( ch_idx = nchan_transport_foa; ch_idx < num_channels_dir; ch_idx++ )
1717 : {
1718 9834704 : IF( hodirac_flag )
1719 : {
1720 2327488 : IF( proto_direct_index[ch_idx] == 0 )
1721 : {
1722 : Word32 *p_proto2;
1723 : Word32 gs1, gs2;
1724 2305024 : p_proto = h_dirac_output_synthesis_state.proto_direct_buffer_f_fx +
1725 1152512 : shl( i_mult( buf_idx, i_mult( num_freq_bands, num_protos_dir ) ), Q1 ) +
1726 1152512 : shl( i_mult( proto_direct_index[0], num_freq_bands ), Q1 );
1727 2305024 : p_proto2 = h_dirac_output_synthesis_state.proto_direct_buffer_f_fx +
1728 1152512 : shl( i_mult( buf_idx, i_mult( num_freq_bands, num_protos_dir ) ), Q1 ) +
1729 1152512 : shl( i_mult( proto_direct_index[1], num_freq_bands ), Q1 );
1730 69458432 : FOR( l = 0; l < num_freq_bands; l++ )
1731 : {
1732 :
1733 : Word32 temp1, temp2;
1734 68305920 : gs1 = Madd_32_32( Mpy_32_32( g1[0], ( *( p_gains_dir ) ) ), g2, ( *( p_gains_dir_prev ) ) ); // (Q31, p_gains_dir_q) -> (p_gains_dir_q)
1735 68305920 : gs2 = Madd_32_32( Mpy_32_32( g1[0], ( *( p_gains_dir + prod ) ) ), g2, ( *( p_gains_dir_prev + prod ) ) ); // (Q31, p_gains_dir_q) -> (p_gains_dir_q)
1736 68305920 : p_gains_dir++;
1737 68305920 : p_gains_dir_prev++;
1738 :
1739 68305920 : temp1 = Mpy_32_32( 1903158016 /* 1.772454e+00f / 2 in Q31 */, ( *p_proto ) );
1740 68305920 : temp2 = Mpy_32_32( 1098788992 /* 1.023327e+00f / 2 in Q31 */, ( *p_proto2 ) );
1741 : // ((p_gains_dir_q, p_proto_dir_q) >> 1) -> (p_gains_dir_q + p_proto_dir_q - 31)
1742 136611840 : output_real[l * num_channels_dir + ch_idx] =
1743 68305920 : Madd_32_32(
1744 : Mpy_32_32( gs1, ( L_add( temp1, temp2 ) ) ), /* s1 */
1745 : gs2, L_sub( temp1, temp2 ) ); /* s2 */
1746 68305920 : move32();
1747 68305920 : p_proto++;
1748 68305920 : p_proto2++;
1749 :
1750 68305920 : temp1 = Mpy_32_32( 1903158016 /* 1.772454e+00f / 2 in Q31 */, ( *p_proto ) );
1751 68305920 : temp2 = Mpy_32_32( 1098788992 /* 1.023327e+00f / 2 in Q31 */, ( *p_proto2 ) );
1752 : // ((p_gains_dir_q, p_proto_dir_q) >> 1) -> (p_gains_dir_q + p_proto_dir_q - 31)
1753 136611840 : output_imag[l * num_channels_dir + ch_idx] =
1754 68305920 : Madd_32_32(
1755 : Mpy_32_32( gs1, ( L_add( temp1, temp2 ) ) ),
1756 : gs2, L_sub( temp1, temp2 ) );
1757 68305920 : move32();
1758 68305920 : p_proto++;
1759 68305920 : p_proto2++;
1760 : }
1761 : }
1762 : ELSE
1763 : {
1764 2349952 : p_proto = h_dirac_output_synthesis_state.proto_direct_buffer_f_fx +
1765 1174976 : shl( i_mult( buf_idx, i_mult( num_freq_bands, num_protos_dir ) ), Q1 ) +
1766 1174976 : shl( i_mult( proto_direct_index[ch_idx], num_freq_bands ), Q1 );
1767 1174976 : Word16 diff = sub( h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev, 31 );
1768 71212736 : FOR( l = 0; l < num_freq_bands; l++ )
1769 : {
1770 70037760 : p_gains_dir++;
1771 70037760 : p_gains_dir_prev++;
1772 :
1773 70037760 : output_real[l * num_channels_dir + ch_idx] = L_shl( *( p_proto++ ), diff ); // p_proto_dir_q -> (p_gains_dir_q + p_proto_dir_q - 31)
1774 70037760 : move32();
1775 70037760 : output_imag[l * num_channels_dir + ch_idx] = L_shl( *( p_proto++ ), diff ); // p_proto_dir_q -> (p_gains_dir_q + p_proto_dir_q - 31)
1776 70037760 : move32();
1777 : }
1778 : }
1779 : }
1780 : ELSE
1781 : {
1782 15014432 : p_proto = h_dirac_output_synthesis_state.proto_direct_buffer_f_fx +
1783 15014432 : offset +
1784 7507216 : shl( i_mult( proto_direct_index[ch_idx], num_freq_bands ), Q1 );
1785 7507216 : IF( EQ_16( proto_direct_index[ch_idx], 0 ) )
1786 : {
1787 367849064 : FOR( l = 0; l < num_freq_bands; l++ )
1788 : {
1789 360589280 : g = Madd_32_32( Mpy_32_32( g1[0], ( *( p_gains_dir++ ) ) ), g2, ( *( p_gains_dir_prev++ ) ) ); // (Q31, p_gains_dir_q) -> (p_gains_dir_q)
1790 :
1791 360589280 : output_real[l * num_channels_dir + ch_idx] = Mpy_32_32( g, ( *( p_proto++ ) ) ); // (p_gains_dir_q, p_proto_dir_q) -> (p_gains_dir_q + p_proto_dir_q - 31)
1792 360589280 : move32();
1793 360589280 : output_imag[l * num_channels_dir + ch_idx] = Mpy_32_32( g, ( *( p_proto++ ) ) ); // (p_gains_dir_q, p_proto_dir_q) -> (p_gains_dir_q + p_proto_dir_q - 31)
1794 360589280 : move32();
1795 : }
1796 : }
1797 : ELSE
1798 : {
1799 247432 : Word16 shift_q = sub( h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev, 31 );
1800 13736552 : FOR( l = 0; l < num_freq_bands; l++ )
1801 : {
1802 13489120 : p_gains_dir++;
1803 13489120 : p_gains_dir_prev++;
1804 :
1805 13489120 : output_real[l * num_channels_dir + ch_idx] = L_shl( *( p_proto++ ), shift_q ); // p_proto_dir_q -> (p_gains_dir_q + p_proto_dir_q - 31)
1806 13489120 : move32();
1807 13489120 : output_imag[l * num_channels_dir + ch_idx] = L_shl( *( p_proto++ ), shift_q ); // p_proto_dir_q -> (p_gains_dir_q + p_proto_dir_q - 31)
1808 13489120 : move32();
1809 : }
1810 : }
1811 : }
1812 : }
1813 :
1814 : /*Diffuse stream*/
1815 884436 : p_gains_diff = h_dirac_output_synthesis_state.cy_auto_diff_smooth_prev_fx + i_mult( nchan_transport_foa, num_freq_bands_diff );
1816 884436 : p_gains_diff_prev = h_dirac_output_synthesis_state.gains_diff_prev_fx + i_mult( nchan_transport_foa, num_freq_bands_diff );
1817 1031412 : FOR( ch_idx = nchan_transport_foa; ch_idx < num_channels_diff; ch_idx++ )
1818 : {
1819 146976 : Scale_sig32( &h_dirac_output_synthesis_state.gains_diff_prev_fx[ch_idx * num_freq_bands_diff],
1820 : num_freq_bands_diff,
1821 146976 : sub( h_dirac_output_synthesis_state.q_cy_auto_diff_smooth_prev, h_dirac_output_synthesis_state.gains_diff_prev_q ) ); /*h_dirac_output_synthesis_state.gains_diff_prev_q->h_dirac_output_synthesis_state.q_cy_auto_diff_smooth_prev*/
1822 : }
1823 884436 : h_dirac_output_synthesis_state.gains_diff_prev_q = h_dirac_output_synthesis_state.q_cy_auto_diff_smooth_prev;
1824 884436 : move16();
1825 :
1826 884436 : ch_idx_diff = nchan_transport_foa;
1827 884436 : move16();
1828 1031412 : FOR( ch_idx = nchan_transport_foa; ch_idx < num_channels_diff; ch_idx++ )
1829 : {
1830 146976 : IF( proto_direct_index[ch_idx] == 0 )
1831 : {
1832 293952 : p_proto = h_dirac_output_synthesis_state.proto_diffuse_buffer_f_fx +
1833 146976 : shl( i_mult( buf_idx, i_mult( num_freq_bands, num_channels_diff ) ), Q1 ) +
1834 146976 : shl( i_mult( ch_idx_diff, num_freq_bands ), Q1 );
1835 146976 : ch_idx_diff = add( ch_idx_diff, 1 );
1836 3380448 : FOR( l = 0; l < num_freq_bands_diff; l++ )
1837 : {
1838 3233472 : g = Madd_32_32( Mpy_32_32( g1[0], ( *( p_gains_diff++ ) ) ), g2, ( *( p_gains_diff_prev++ ) ) ); // (Q31, p_gains_diff_q) -> p_gains_diff_q
1839 :
1840 : // ((p_gains_diff_q, p_proto_diff_q) >> Q1) -> (p_gains_diff_q + p_proto_diff_q - 31)
1841 6466944 : output_real[l * num_channels_dir + hDirACRend->sba_map_tc[ch_idx]] =
1842 3233472 : Madd_32_32( output_real[l * num_channels_dir + hDirACRend->sba_map_tc[ch_idx]],
1843 3233472 : g, ( *( p_proto++ ) ) );
1844 3233472 : move32();
1845 :
1846 : // ((p_gains_diff_q, p_proto_diff_q) >> Q1) -> (p_gains_diff_q + p_proto_diff_q - 31)
1847 6466944 : output_imag[l * num_channels_dir + hDirACRend->sba_map_tc[ch_idx]] =
1848 3233472 : Madd_32_32( output_imag[l * num_channels_dir + hDirACRend->sba_map_tc[ch_idx]],
1849 3233472 : g, ( *( p_proto++ ) ) );
1850 3233472 : move32();
1851 : }
1852 : }
1853 : ELSE
1854 : {
1855 0 : p_gains_diff += num_freq_bands_diff;
1856 0 : p_gains_diff_prev += num_freq_bands_diff;
1857 : }
1858 : }
1859 :
1860 : /*-----------------------------------------------------------------*
1861 : * Copy output or HOA decoder
1862 : *-----------------------------------------------------------------*/
1863 :
1864 884436 : test();
1865 : /*q=(p_gains_dir_q + p_proto_dir_q - 31)*/
1866 884436 : IF( hDirACRend->hOutSetup.is_loudspeaker_setup && hDirACRend->hoa_decoder != NULL )
1867 156000 : {
1868 : Word32 *p_real, *p_imag;
1869 : const Word32 *hoa_decoder;
1870 :
1871 156000 : hoa_decoder = hDirACRend->hoa_decoder;
1872 :
1873 1592000 : FOR( ch_idx = 0; ch_idx < hDirACRend->hOutSetup.nchan_out_woLFE; ch_idx++ )
1874 : {
1875 1436000 : p_real = RealBuffer[ch_idx][buf_idx]; /*q - Q2*/
1876 1436000 : p_imag = ImagBuffer[ch_idx][buf_idx]; /*q - Q2*/
1877 :
1878 80556000 : FOR( l = 0; l < num_freq_bands; l++ )
1879 : {
1880 79120000 : p_out_real = output_real + i_mult( l, num_channels_dir );
1881 79120000 : p_out_imag = output_imag + i_mult( l, num_channels_dir );
1882 79120000 : p_real[l] = Mpy_32_32( *( p_out_real++ ), hoa_decoder[0] ); // (q, Q29) -> q - Q2
1883 79120000 : move32();
1884 79120000 : p_imag[l] = Mpy_32_32( *( p_out_imag++ ), hoa_decoder[0] ); // (q, Q29) -> q - Q2
1885 79120000 : move32();
1886 1265920000 : FOR( i = 1; i < num_channels_dir; i++ )
1887 : {
1888 1186800000 : p_real[l] = Madd_32_32( p_real[l], *( p_out_real++ ), hoa_decoder[i] ); // (q, Q29) -> q - Q2
1889 1186800000 : move32();
1890 1186800000 : p_imag[l] = Madd_32_32( p_imag[l], *( p_out_imag++ ), hoa_decoder[i] ); // (q, Q29) -> q - Q2
1891 1186800000 : move32();
1892 : }
1893 : }
1894 1436000 : hoa_decoder += 16;
1895 : }
1896 : }
1897 : ELSE
1898 : {
1899 11457908 : FOR( ch_idx = 0; ch_idx < num_channels_dir; ch_idx++ )
1900 : {
1901 561190912 : FOR( l = 0; l < num_freq_bands; l++ )
1902 : {
1903 550461440 : RealBuffer[ch_idx][buf_idx][l] = L_shr( output_real[l * num_channels_dir + ch_idx], Q2 ); /* q - Q2*/
1904 550461440 : move32();
1905 550461440 : ImagBuffer[ch_idx][buf_idx][l] = L_shr( output_imag[l * num_channels_dir + ch_idx], Q2 ); /* q - Q2*/
1906 550461440 : move32();
1907 : }
1908 : }
1909 : }
1910 : }
1911 :
1912 : /*-----------------------------------------------------------------*
1913 : * update buffers
1914 : *-----------------------------------------------------------------*/
1915 :
1916 : /* store estimates for next synthesis block */
1917 222420 : IF( hodirac_flag )
1918 : {
1919 53156 : Copy32( h_dirac_output_synthesis_state.cy_cross_dir_smooth_prev_fx, h_dirac_output_synthesis_state.gains_dir_prev_fx, prod * DIRAC_HO_NUMSECTORS ); /*h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev*/
1920 : }
1921 : ELSE
1922 : {
1923 169264 : Copy32( h_dirac_output_synthesis_state.cy_cross_dir_smooth_prev_fx, h_dirac_output_synthesis_state.gains_dir_prev_fx, prod ); /*h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev*/
1924 : }
1925 222420 : *q_cy_cross_dir_smooth_prev = h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev;
1926 222420 : move16();
1927 :
1928 222420 : Copy32( h_dirac_output_synthesis_state.cy_auto_diff_smooth_prev_fx, h_dirac_output_synthesis_state.gains_diff_prev_fx, imult1616( num_freq_bands_diff, num_channels_diff ) ); /* h_dirac_output_synthesis_state.q_cy_auto_diff_smooth_prev*/
1929 222420 : *q_cy_auto_diff_smooth_prev = h_dirac_output_synthesis_state.q_cy_auto_diff_smooth_prev;
1930 222420 : move16();
1931 :
1932 : /* reset values */
1933 222420 : IF( hodirac_flag )
1934 : {
1935 53156 : set_zero_fx( h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx, prod * DIRAC_HO_NUMSECTORS );
1936 : }
1937 : ELSE
1938 : {
1939 169264 : set_zero_fx( h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx, prod );
1940 : }
1941 :
1942 222420 : set_zero_fx( h_dirac_output_synthesis_state.cy_auto_diff_smooth_fx, imult1616( num_freq_bands_diff, num_channels_diff ) );
1943 :
1944 222420 : return;
1945 : }
1946 :
1947 :
1948 : /*-------------------------------------------------------------------------
1949 : * ivas_dirac_dec_output_synthesis_process_subframe_psd_ls()
1950 : *
1951 : *
1952 : *------------------------------------------------------------------------*/
1953 95963 : void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx(
1954 : Word32 RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : LS signals Q(q_Cldfb)*/
1955 : Word32 ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : LS signals Q(q_Cldfb)*/
1956 : SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common spatial renderer data handle */
1957 : DIRAC_REND_HANDLE hDirACRend, /* i/o: DirAC renderer handle */
1958 : const Word16 nbslots, /* i : number of slots to process */
1959 : Word32 *diffuseness_vector, /* i : diffuseness (needed for direction smoothing) Q(31)*/
1960 : Word32 *reference_power_smooth, /*Q(q_reference_power_smooth)*/
1961 : Word16 *q_reference_power_smooth,
1962 : Word32 qualityBasedSmFactor, /*Q(31)*/
1963 : const Word16 enc_param_start_band,
1964 : Word16 *q_Cldfb )
1965 : {
1966 : Word16 buf_idx, num_freq_bands;
1967 : Word16 diff_start_band;
1968 : Word16 k, l;
1969 : Word16 nchan_out_woLFE;
1970 : Word32 *p_power_smooth_prev, *p_power_diff_smooth_prev;
1971 : Word32 *p_gain_1, *p_gain_2;
1972 : Word32 *p_power_smooth_diff, *p_power_smooth;
1973 : Word32 *p_gains_dir, *p_gains_diff;
1974 : Word32 g, g1, g2;
1975 : Word32 *p_cy_auto_dir_smooth, *p_cy_auto_dir_smooth_prev;
1976 : Word16 q_cy_auto_dir_smooth_local[MAX_OUTPUT_CHANNELS], q_cy_auto_dir_smooth_prev_local[MAX_OUTPUT_CHANNELS];
1977 : Word32 *p_cy_cross_dir_smooth, *p_cy_cross_dir_smooth_prev;
1978 : Word32 *p_cy_auto_diff_smooth, *p_cy_auto_diff_smooth_prev;
1979 : Word32 gains_dir[CLDFB_NO_CHANNELS_MAX * MAX_OUTPUT_CHANNELS];
1980 : Word32 gains_diff[CLDFB_NO_CHANNELS_MAX * MAX_OUTPUT_CHANNELS];
1981 : DIRAC_OUTPUT_SYNTHESIS_PARAMS *h_dirac_output_synthesis_params;
1982 : DIRAC_OUTPUT_SYNTHESIS_STATE *h_dirac_output_synthesis_state;
1983 : Word16 *proto_direct_index, num_protos_dir;
1984 : Word32 target_power_y, target_power_y1;
1985 : Word16 q_target_power_y, q_target_power_y1;
1986 : Word32 subtract_power_y;
1987 : Word32 subtract_target_ratio;
1988 : Word32 subtract_target_ratio_db;
1989 : Word32 a, b;
1990 : UWord16 nchan_target_psds;
1991 : Word32 alpha[CLDFB_NO_CHANNELS_MAX];
1992 : Word16 *alpha_synthesis;
1993 : Word16 *alpha_synthesis_fast;
1994 : Word16 alphaMaxBin;
1995 : Word16 alphaMaxBinFast;
1996 : Word32 L_tmp;
1997 : Word16 exp_arr[CLDFB_NO_CHANNELS_MAX * MAX_OUTPUT_CHANNELS];
1998 95963 : Word16 exp = 0, exp1, tmp, q_com, q_tmp, min_exp;
1999 : Word32 tmp32;
2000 95963 : move16();
2001 :
2002 : Word64 Cldfb_RealBuffer64_fx[MAX_OUTPUT_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
2003 : Word64 Cldfb_ImagBuffer64_fx[MAX_OUTPUT_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
2004 95963 : Word64 W_temp = 0;
2005 95963 : move64();
2006 95963 : push_wmops( "dirac_out_synth_sfr" );
2007 :
2008 95963 : h_dirac_output_synthesis_params = &( hDirACRend->h_output_synthesis_psd_params );
2009 95963 : h_dirac_output_synthesis_state = &( hDirACRend->h_output_synthesis_psd_state );
2010 :
2011 : /* collect some often used parameters */
2012 95963 : proto_direct_index = hDirACRend->proto_index_dir;
2013 95963 : move16();
2014 95963 : num_protos_dir = hDirACRend->num_protos_dir;
2015 95963 : move16();
2016 95963 : nchan_out_woLFE = hDirACRend->hOutSetup.nchan_out_woLFE;
2017 95963 : move16();
2018 95963 : num_freq_bands = hSpatParamRendCom->num_freq_bands;
2019 95963 : move16();
2020 95963 : set16_fx( q_cy_auto_dir_smooth_local, h_dirac_output_synthesis_state->q_cy_auto_dir_smooth, nchan_out_woLFE );
2021 :
2022 : /*-----------------------------------------------------------------*
2023 : * compute target PSDs
2024 : *-----------------------------------------------------------------*/
2025 95963 : IF( enc_param_start_band == 0 )
2026 : {
2027 77963 : IF( EQ_16( h_dirac_output_synthesis_params->use_onset_filters, 1 ) )
2028 : {
2029 52517 : diff_start_band = h_dirac_output_synthesis_params->max_band_decorr;
2030 52517 : move16();
2031 : }
2032 : ELSE
2033 : {
2034 25446 : diff_start_band = 0;
2035 25446 : move16();
2036 : }
2037 :
2038 77963 : IF( EQ_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_MONO ) )
2039 : {
2040 9414 : nchan_target_psds = 2;
2041 9414 : move16();
2042 : }
2043 : ELSE
2044 : {
2045 68549 : nchan_target_psds = nchan_out_woLFE;
2046 68549 : move16();
2047 : }
2048 :
2049 77963 : computeTargetPSDs_direct_subframe_fx( nchan_target_psds, num_freq_bands,
2050 77963 : h_dirac_output_synthesis_state->direct_power_factor_fx,
2051 : reference_power_smooth,
2052 : q_reference_power_smooth,
2053 77963 : h_dirac_output_synthesis_state->direct_responses_fx,
2054 77963 : h_dirac_output_synthesis_state->direct_responses_square_fx,
2055 : h_dirac_output_synthesis_state->cy_auto_dir_smooth_fx,
2056 : q_cy_auto_dir_smooth_local,
2057 : h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx,
2058 : &h_dirac_output_synthesis_state->q_cy_cross_dir_smooth );
2059 :
2060 : #ifndef FIX_867_CLDFB_NRG_SCALE
2061 : // Scale cy_auto_diff_smooth_fx if required
2062 : IF( diff_start_band != 0 )
2063 : {
2064 : q_com = s_min( *q_reference_power_smooth, h_dirac_output_synthesis_state->q_cy_auto_diff_smooth );
2065 : scale_sig32( reference_power_smooth, num_freq_bands, sub( q_com, *q_reference_power_smooth ) ); /**q_reference_power_smooth->q_com*/
2066 : scale_sig32( h_dirac_output_synthesis_state->reference_power_smooth_prev_fx, num_freq_bands, sub( q_com, *q_reference_power_smooth ) ); /**q_reference_power_smooth->q_com*/
2067 : scale_sig32( h_dirac_output_synthesis_state->cy_auto_diff_smooth_fx,
2068 : i_mult( num_freq_bands, nchan_target_psds ),
2069 : sub( q_com, h_dirac_output_synthesis_state->q_cy_auto_diff_smooth ) ); /*h_dirac_output_synthesis_state->q_cy_auto_diff_smooth -> q_com*/
2070 : *q_reference_power_smooth = q_com;
2071 : move16();
2072 : h_dirac_output_synthesis_state->reference_power_smooth_prev_q = q_com;
2073 : move16();
2074 :
2075 : h_dirac_output_synthesis_state->q_cy_auto_diff_smooth = q_com;
2076 : move16();
2077 : }
2078 : #endif
2079 :
2080 77963 : computeTargetPSDs_diffuse_subframe_fx( nchan_target_psds, num_freq_bands, diff_start_band,
2081 77963 : h_dirac_output_synthesis_state->diffuse_power_factor_fx,
2082 : reference_power_smooth,
2083 : q_reference_power_smooth,
2084 77963 : h_dirac_output_synthesis_state->diffuse_responses_square_fx,
2085 : h_dirac_output_synthesis_state->cy_auto_diff_smooth_fx,
2086 : &h_dirac_output_synthesis_state->q_cy_auto_diff_smooth );
2087 : }
2088 :
2089 : /*-----------------------------------------------------------------*
2090 : * compute variables for stereo transport signal type detection
2091 : *-----------------------------------------------------------------*/
2092 :
2093 95963 : IF( hDirACRend->masa_stereo_type_detect != NULL )
2094 : {
2095 16206 : MASA_STEREO_TYPE_DETECT *masa_stereo_type_detect = hDirACRend->masa_stereo_type_detect;
2096 :
2097 16206 : p_cy_auto_dir_smooth = h_dirac_output_synthesis_state->cy_auto_dir_smooth_fx; // q_cy_auto_dir_smooth
2098 16206 : p_cy_auto_diff_smooth = h_dirac_output_synthesis_state->cy_auto_diff_smooth_fx; // q_cy_auto_diff_smooth
2099 16206 : q_com = s_min( q_cy_auto_dir_smooth_local[1], h_dirac_output_synthesis_state->q_cy_auto_diff_smooth );
2100 :
2101 16206 : IF( EQ_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_MONO ) )
2102 : {
2103 9414 : exp = Q31 - Q31;
2104 9414 : move16();
2105 9414 : exp1 = 0;
2106 9414 : move16();
2107 9414 : tmp32 = BASOP_Util_Divide3232_Scale_newton( L_shl( p_cy_auto_dir_smooth[num_freq_bands], sub( q_com, q_cy_auto_dir_smooth_local[1] ) ),
2108 9414 : ( L_add( Sqrt32( h_dirac_output_synthesis_state->direct_power_factor_fx[0], &exp ), EPSILON_FX ) ), // (Q31 - exp)
2109 : &exp1 );
2110 9414 : target_power_y = L_shr( tmp32, 1 ); // Q31 + (q_com - (31 - exp))
2111 9414 : q_target_power_y = add( sub( Q31, exp1 ), sub( q_com, sub( Q31, exp ) ) );
2112 9414 : q_target_power_y = sub( q_target_power_y, 1 );
2113 :
2114 9414 : exp = Q31 - Q31;
2115 9414 : move16();
2116 9414 : exp1 = 0;
2117 9414 : move16();
2118 9414 : tmp32 = BASOP_Util_Divide3232_Scale_newton( L_shl( p_cy_auto_diff_smooth[num_freq_bands], sub( q_com, h_dirac_output_synthesis_state->q_cy_auto_diff_smooth ) ),
2119 9414 : ( L_add( Sqrt32( h_dirac_output_synthesis_state->diffuse_power_factor_fx[0], &exp ), EPSILON_FX ) ), // (Q31 - exp)
2120 : &exp1 );
2121 9414 : target_power_y1 = L_shr( tmp32, 1 ); // Q31 + (q_com - (31 - exp))
2122 9414 : q_target_power_y1 = add( sub( Q31, exp1 ), sub( q_com, sub( Q31, exp ) ) );
2123 9414 : q_target_power_y1 = sub( q_target_power_y1, 1 );
2124 :
2125 9414 : target_power_y = L_add( L_shl( target_power_y, sub( s_min( q_target_power_y1, q_target_power_y ), q_target_power_y ) ), L_shl( target_power_y1, sub( s_min( q_target_power_y1, q_target_power_y ), q_target_power_y1 ) ) ); /*min(q_target_power_y1, q_target_power_y )*/
2126 9414 : exp = s_min( q_target_power_y1, q_target_power_y );
2127 : }
2128 : ELSE
2129 : {
2130 6792 : target_power_y = L_add(
2131 6792 : L_shl( p_cy_auto_dir_smooth[num_freq_bands], sub( q_com, q_cy_auto_dir_smooth_local[1] ) ),
2132 6792 : L_shl( p_cy_auto_diff_smooth[num_freq_bands], sub( q_com, h_dirac_output_synthesis_state->q_cy_auto_diff_smooth ) ) ); // q_com
2133 6792 : exp = q_com;
2134 6792 : move16();
2135 : }
2136 :
2137 16206 : a = 858993; /* ( 0.0004f in Q31 ); Temporal smoothing coefficient */
2138 16206 : move32();
2139 16206 : b = L_sub( ONE_IN_Q31, a ); /* Temporal smoothing coefficient */
2140 :
2141 16206 : q_com = s_min( exp, masa_stereo_type_detect->q_target_power_y_smooth );
2142 16206 : target_power_y = L_shl( target_power_y, sub( q_com, exp ) );
2143 16206 : masa_stereo_type_detect->target_power_y_smooth_fx = L_shl( masa_stereo_type_detect->target_power_y_smooth_fx,
2144 16206 : sub( q_com, masa_stereo_type_detect->q_target_power_y_smooth ) );
2145 16206 : move32();
2146 16206 : masa_stereo_type_detect->target_power_y_smooth_fx =
2147 16206 : L_add( Mpy_32_32( a, target_power_y ),
2148 : Mpy_32_32( b, masa_stereo_type_detect->target_power_y_smooth_fx ) ); //(Q31, q_com) -> q_com
2149 16206 : move32();
2150 16206 : masa_stereo_type_detect->q_target_power_y_smooth = q_com;
2151 16206 : move16();
2152 :
2153 16206 : IF( NE_16( masa_stereo_type_detect->q_subtract_power_y, masa_stereo_type_detect->q_subtract_power_y_smooth ) )
2154 : {
2155 0 : exp = s_min( add( masa_stereo_type_detect->q_subtract_power_y, norm_l( masa_stereo_type_detect->subtract_power_y_fx ) ), add( masa_stereo_type_detect->q_subtract_power_y_smooth, norm_l( masa_stereo_type_detect->subtract_power_y_smooth_fx ) ) );
2156 0 : masa_stereo_type_detect->subtract_power_y_fx = L_shl( masa_stereo_type_detect->subtract_power_y_fx, sub( exp, masa_stereo_type_detect->q_subtract_power_y ) );
2157 0 : move32();
2158 0 : masa_stereo_type_detect->subtract_power_y_smooth_fx = L_shl( masa_stereo_type_detect->subtract_power_y_smooth_fx, sub( exp, masa_stereo_type_detect->q_subtract_power_y_smooth ) );
2159 0 : move32();
2160 0 : masa_stereo_type_detect->q_subtract_power_y = exp;
2161 0 : move16();
2162 0 : masa_stereo_type_detect->q_subtract_power_y_smooth = exp;
2163 0 : move16();
2164 : }
2165 16206 : subtract_power_y = masa_stereo_type_detect->subtract_power_y_fx; // q_subtract_power_y
2166 16206 : move32();
2167 :
2168 16206 : W_temp = W_add( W_mult0_32_32( a, subtract_power_y ), W_mult0_32_32( b, masa_stereo_type_detect->subtract_power_y_smooth_fx ) ); // Q31 + masa_stereo_type_detect->q_subtract_power_y_smooth
2169 16206 : IF( W_temp )
2170 : {
2171 16193 : exp = W_norm( W_temp );
2172 16193 : masa_stereo_type_detect->subtract_power_y_smooth_fx = W_extract_h( W_shl( W_temp, exp ) ); // Q31 + masa_stereo_type_detect->q_subtract_power_y_smooth + exp - 32
2173 16193 : move32();
2174 16193 : masa_stereo_type_detect->q_subtract_power_y_smooth = sub( add( masa_stereo_type_detect->q_subtract_power_y_smooth, exp ), 1 );
2175 16193 : move16();
2176 : }
2177 : ELSE
2178 : {
2179 13 : masa_stereo_type_detect->subtract_power_y_smooth_fx = 0; // Q31
2180 13 : move32();
2181 13 : masa_stereo_type_detect->q_subtract_power_y_smooth = Q31;
2182 13 : move16();
2183 : }
2184 16206 : exp = 0;
2185 16206 : move16();
2186 16206 : test();
2187 16206 : IF( masa_stereo_type_detect->target_power_y_smooth_fx && masa_stereo_type_detect->subtract_power_y_smooth_fx )
2188 : {
2189 16190 : subtract_target_ratio = L_sub( BASOP_Util_Log2( masa_stereo_type_detect->subtract_power_y_smooth_fx ),
2190 : BASOP_Util_Log2( masa_stereo_type_detect->target_power_y_smooth_fx ) ); // Q25
2191 16190 : exp = sub( masa_stereo_type_detect->q_subtract_power_y_smooth, q_com );
2192 16190 : L_tmp = Mpy_32_32( L_sub( subtract_target_ratio, L_shl( exp, 25 ) ), LOG10_2_Q31 ); // Q25
2193 : }
2194 : ELSE
2195 : {
2196 16 : subtract_target_ratio = BASOP_Util_Log2( masa_stereo_type_detect->subtract_power_y_smooth_fx ); // Q25
2197 16 : exp = sub( 31, masa_stereo_type_detect->q_subtract_power_y_smooth );
2198 16 : L_tmp = L_sub( Mpy_32_32( L_add( subtract_target_ratio, L_shl( exp, 25 ) ), LOG10_2_Q31 ), -503316480 /* L_shl( -15, 25 ) */ /*log(EPSILON)*/ ); // Q25
2199 : }
2200 16206 : subtract_target_ratio_db = Mpy_32_32( 1342177280 /* 10.0f * in Q27*/, L_tmp ); // (Q27, (Q25, Q31)) -> (Q27, Q25) -> Q21
2201 :
2202 16206 : masa_stereo_type_detect->subtract_target_ratio_db_fx = subtract_target_ratio_db; // Q21
2203 16206 : move32();
2204 16206 : masa_stereo_type_detect->subtract_power_y_fx = 0;
2205 16206 : move32();
2206 16206 : masa_stereo_type_detect->q_subtract_power_y = Q31;
2207 16206 : move16();
2208 : }
2209 :
2210 : /*-----------------------------------------------------------------*
2211 : * compute smoothing coefficients
2212 : *-----------------------------------------------------------------*/
2213 :
2214 95963 : alpha_synthesis = h_dirac_output_synthesis_params->alpha_synthesis_fx; // Q15
2215 95963 : alpha_synthesis_fast = h_dirac_output_synthesis_params->alpha_synthesis_fast_fx; // Q15
2216 95963 : alphaMaxBin = sub( h_dirac_output_synthesis_params->numAlphas, 1 );
2217 95963 : alphaMaxBinFast = sub( h_dirac_output_synthesis_params->numAlphasFast, 1 );
2218 :
2219 5600663 : FOR( l = 0; l < num_freq_bands; l++ )
2220 : {
2221 : Word32 instDirectionSmoothness, weightedDirectionSmoothness, smoothedDirectionSmoothness;
2222 : Word32 currWeight, prevWeight, sumWeight;
2223 : Word16 indexFast, indexSlow;
2224 5504700 : Word32 alpha_quality_based = 42949672; /* 0.02f in Q31 */
2225 5504700 : move32();
2226 :
2227 5504700 : indexSlow = s_min( l, alphaMaxBin );
2228 5504700 : indexFast = s_min( l, alphaMaxBinFast );
2229 :
2230 : /* Estimate the smoothness of the directions based on the diffuseness parameter */
2231 5504700 : instDirectionSmoothness = L_sub( ONE_IN_Q31, diffuseness_vector[l] ); // Q31
2232 5504700 : instDirectionSmoothness = L_min( L_max( instDirectionSmoothness, 0 ), ONE_IN_Q31 ); // Q31
2233 :
2234 : /* Average the direction smoothness parameter over time */
2235 5504700 : currWeight = Mpy_32_32( DIRECTION_SMOOTHNESS_ALPHA_Q31,
2236 5504700 : reference_power_smooth[l] ); //(Q31, q_reference_power_smooth) -> q_reference_power_smooth
2237 5504700 : prevWeight = Mpy_32_32( L_sub( ONE_IN_Q31, DIRECTION_SMOOTHNESS_ALPHA_Q31 ),
2238 5504700 : h_dirac_output_synthesis_state->reference_power_smooth_prev_fx[l] ); //(Q31, q_reference_power_smooth) -> q_reference_power_smooth
2239 :
2240 : #ifdef FIX_867_CLDFB_NRG_SCALE
2241 5504700 : assert( q_reference_power_smooth[0] == h_dirac_output_synthesis_state->reference_power_smooth_prev_q[0] );
2242 5504700 : assert( q_reference_power_smooth[1] == h_dirac_output_synthesis_state->reference_power_smooth_prev_q[1] );
2243 : #else
2244 : assert( *q_reference_power_smooth == h_dirac_output_synthesis_state->reference_power_smooth_prev_q );
2245 : #endif
2246 : weightedDirectionSmoothness =
2247 5504700 : L_add( Mpy_32_32( currWeight, instDirectionSmoothness ),
2248 5504700 : Mpy_32_32( prevWeight, h_dirac_output_synthesis_state->direction_smoothness_prev_fx[l] ) ); //(q_reference_power_smooth, Q31) -> q_reference_power_smooth
2249 5504700 : sumWeight = L_add( currWeight, prevWeight ); // q_reference_power_smooth
2250 :
2251 5504700 : exp = 0;
2252 5504700 : move16();
2253 :
2254 5504700 : tmp = BASOP_Util_Divide3232_Scale( weightedDirectionSmoothness, L_add( sumWeight, EPSILON_FX ), &exp ); /*Q(15-exp)*/
2255 5504700 : smoothedDirectionSmoothness = L_shl_sat( L_deposit_l( tmp ), add( sub( Q31, Q15 ), exp ) ); // Q31
2256 :
2257 5504700 : h_dirac_output_synthesis_state->direction_smoothness_prev_fx[l] = smoothedDirectionSmoothness; // Q31
2258 5504700 : move32();
2259 5504700 : h_dirac_output_synthesis_state->reference_power_smooth_prev_fx[l] = sumWeight; // q_reference_power_smooth
2260 5504700 : move32();
2261 :
2262 : /* Determine smoothing parameter for rendering. The smoother the directions, the less smoothing is required (i.e., faster smoothing can be used). */
2263 11009400 : alpha[l] =
2264 5504700 : L_add( Mpy_32_16_1( smoothedDirectionSmoothness, alpha_synthesis_fast[indexFast] ),
2265 5504700 : Mpy_32_16_1( L_sub( ONE_IN_Q31, smoothedDirectionSmoothness ), alpha_synthesis[indexSlow] ) ); //(Q31, Q15) -> Q31
2266 5504700 : move32();
2267 :
2268 : /* Adjust smoothing parameter based on encoding quality */
2269 11009400 : alpha[l] =
2270 5504700 : L_add( Mpy_32_32( qualityBasedSmFactor, alpha[l] ),
2271 : Mpy_32_32( L_sub( ONE_IN_Q31, qualityBasedSmFactor ), alpha_quality_based ) ); //(Q31, Q31) -> Q31
2272 5504700 : move32();
2273 : }
2274 :
2275 : /*-----------------------------------------------------------------*
2276 : * compute gains
2277 : *-----------------------------------------------------------------*/
2278 :
2279 : /*Direct normalization gains on reduced number of protos*/
2280 95963 : p_power_smooth_prev = h_dirac_output_synthesis_state->proto_power_smooth_prev_fx;
2281 95963 : p_power_smooth = h_dirac_output_synthesis_state->proto_power_smooth_fx;
2282 95963 : set16_fx( exp_arr, 0, i_mult( num_protos_dir, num_freq_bands ) );
2283 :
2284 419919 : FOR( k = 0; k < num_protos_dir; k++ )
2285 : {
2286 19311796 : FOR( l = 0; l < num_freq_bands; l++ )
2287 : {
2288 18987840 : g1 = alpha[l]; // Q31
2289 18987840 : move32();
2290 18987840 : g2 = L_sub( ONE_IN_Q31, g1 ); // Q31
2291 18987840 : *p_power_smooth_prev = L_add( EPSILON_FX, Mpy_32_32( g2, ( *p_power_smooth_prev ) ) ); //(Q31, q_proto_power_smooth) -> q_proto_power_smooth
2292 18987840 : move32();
2293 18987840 : *( p_power_smooth_prev ) = L_add( *( p_power_smooth_prev ), Mpy_32_32( g1, ( *p_power_smooth ) ) ); //(Q31, q_proto_power_smooth) -> q_proto_power_smooth
2294 18987840 : move32();
2295 :
2296 : #ifdef FIX_867_CLDFB_NRG_SCALE
2297 18987840 : assert( h_dirac_output_synthesis_state->proto_power_smooth_prev_q[0] == h_dirac_output_synthesis_state->proto_power_smooth_q[0] );
2298 18987840 : assert( h_dirac_output_synthesis_state->proto_power_smooth_prev_q[1] == h_dirac_output_synthesis_state->proto_power_smooth_q[1] );
2299 : #else
2300 : assert( h_dirac_output_synthesis_state->proto_power_smooth_prev_q == h_dirac_output_synthesis_state->proto_power_smooth_q );
2301 : #endif
2302 18987840 : IF( EQ_32( *( p_power_smooth_prev ), EPSILON_FX ) )
2303 : {
2304 12353 : p_power_smooth_prev++;
2305 12353 : L_tmp = BASOP_Util_Divide3232_Scale_newton( ONE_IN_Q31, EPSILON_FX, &exp ); /*Q=31-(exp-(31-q_proto_power_smooth))*/
2306 12353 : exp_arr[k * num_freq_bands + l] = exp;
2307 12353 : move16();
2308 :
2309 12353 : *( p_power_smooth++ ) = L_tmp; /*Q=31-(exp-(31-q_proto_power_smooth))*/
2310 12353 : move32();
2311 : }
2312 : ELSE
2313 : {
2314 18975487 : L_tmp = BASOP_Util_Divide3232_Scale_newton( ONE_IN_Q31, *( p_power_smooth_prev++ ), &exp ); /*Q=31-(exp-(31-q_proto_power_smooth))*/
2315 18975487 : exp_arr[k * num_freq_bands + l] = exp;
2316 18975487 : move16();
2317 :
2318 18975487 : *( p_power_smooth++ ) = L_tmp; /*Q=31-(exp-(31-q_proto_power_smooth))*/
2319 18975487 : move32();
2320 : }
2321 : }
2322 : }
2323 :
2324 : // Move proto_power_smooth_fx to common Q-factor
2325 :
2326 : #ifdef FIX_867_CLDFB_NRG_SCALE
2327 95963 : Word16 min_exp2 = -64;
2328 95963 : min_exp = MIN_16;
2329 95963 : move16();
2330 95963 : move16();
2331 95963 : Word16 q_tmp2 = Q31;
2332 95963 : q_tmp = Q31;
2333 95963 : move16();
2334 95963 : move16();
2335 :
2336 419919 : FOR( k = 0; k < num_protos_dir; k++ )
2337 : {
2338 10000636 : FOR( l = 0; l < s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ); l++ )
2339 : {
2340 9676680 : min_exp = s_max( min_exp, exp_arr[k * num_freq_bands + l] );
2341 : }
2342 9635116 : FOR( l = CLDFB_NO_CHANNELS_HALF; l < num_freq_bands; l++ )
2343 : {
2344 9311160 : min_exp2 = s_max( min_exp2, exp_arr[k * num_freq_bands + l] );
2345 : }
2346 : }
2347 :
2348 95963 : p_power_smooth = h_dirac_output_synthesis_state->proto_power_smooth_fx;
2349 :
2350 419919 : FOR( k = 0; k < num_protos_dir; k++ )
2351 : {
2352 10000636 : FOR( l = 0; l < s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ); l++ )
2353 : {
2354 9676680 : *p_power_smooth = L_shr( *p_power_smooth, sub( min_exp, exp_arr[k * num_freq_bands + l] ) ); /*(31-(exp-(31-q_proto_power_smooth)))->(31-(min_exp-(31-q_proto_power_smooth)))*/
2355 9676680 : move32();
2356 9676680 : p_power_smooth++;
2357 : }
2358 9635116 : FOR( l = CLDFB_NO_CHANNELS_HALF; l < num_freq_bands; l++ )
2359 : {
2360 9311160 : *p_power_smooth = L_shr( *p_power_smooth, sub( min_exp2, exp_arr[k * num_freq_bands + l] ) ); /*(31-(exp-(31-q_proto_power_smooth)))->(31-(min_exp-(31-q_proto_power_smooth)))*/
2361 9311160 : move32();
2362 9311160 : p_power_smooth++;
2363 : }
2364 : }
2365 :
2366 : // Update the Q-factor
2367 95963 : h_dirac_output_synthesis_state->proto_power_smooth_prev_q[0] = s_min( h_dirac_output_synthesis_state->proto_power_smooth_q[0], h_dirac_output_synthesis_state->proto_power_smooth_prev_q[0] );
2368 95963 : h_dirac_output_synthesis_state->proto_power_smooth_prev_q[1] = s_min( h_dirac_output_synthesis_state->proto_power_smooth_q[1], h_dirac_output_synthesis_state->proto_power_smooth_prev_q[1] );
2369 95963 : move16();
2370 95963 : move16();
2371 :
2372 95963 : q_tmp = add( sub( Q31, min_exp ), sub( Q31, h_dirac_output_synthesis_state->proto_power_smooth_prev_q[0] ) );
2373 95963 : q_tmp2 = add( sub( Q31, min_exp2 ), sub( Q31, h_dirac_output_synthesis_state->proto_power_smooth_prev_q[1] ) );
2374 :
2375 95963 : h_dirac_output_synthesis_state->proto_power_smooth_q[0] = q_tmp;
2376 95963 : h_dirac_output_synthesis_state->proto_power_smooth_q[1] = q_tmp2;
2377 95963 : move16();
2378 95963 : move16();
2379 : #else
2380 : min_exp = MIN_16;
2381 : move16();
2382 : q_tmp = Q31;
2383 : move16();
2384 :
2385 : FOR( k = 0; k < num_protos_dir; k++ )
2386 : {
2387 : FOR( l = 0; l < num_freq_bands; l++ )
2388 : {
2389 : IF( GT_16( exp_arr[k * num_freq_bands + l], min_exp ) )
2390 : {
2391 : min_exp = exp_arr[k * num_freq_bands + l];
2392 : move16();
2393 : }
2394 : }
2395 : }
2396 :
2397 : p_power_smooth_prev = h_dirac_output_synthesis_state->proto_power_smooth_prev_fx;
2398 : p_power_smooth = h_dirac_output_synthesis_state->proto_power_smooth_fx;
2399 :
2400 : FOR( k = 0; k < num_protos_dir; k++ )
2401 : {
2402 : FOR( l = 0; l < num_freq_bands; l++ )
2403 : {
2404 : *p_power_smooth = L_shr( *p_power_smooth, sub( min_exp, exp_arr[k * num_freq_bands + l] ) ); /*(31-(exp-(31-q_proto_power_smooth)))->(31-(min_exp-(31-q_proto_power_smooth)))*/
2405 : move32();
2406 : p_power_smooth++;
2407 : q_tmp = add( sub( Q31, min_exp ), sub( Q31, h_dirac_output_synthesis_state->proto_power_smooth_q ) );
2408 : }
2409 : }
2410 :
2411 : // Update the Q-factor
2412 : h_dirac_output_synthesis_state->proto_power_smooth_prev_q = h_dirac_output_synthesis_state->proto_power_smooth_q;
2413 : move16();
2414 : h_dirac_output_synthesis_state->proto_power_smooth_q = q_tmp;
2415 : move16();
2416 : #endif
2417 :
2418 : /*Direct gains and diffuse gains on number of output channels*/
2419 95963 : p_power_diff_smooth_prev = h_dirac_output_synthesis_state->proto_power_diff_smooth_prev_fx;
2420 95963 : p_power_smooth_diff = h_dirac_output_synthesis_state->proto_power_diff_smooth_fx;
2421 :
2422 95963 : p_gains_diff = gains_diff;
2423 95963 : p_gains_dir = gains_dir;
2424 :
2425 95963 : p_cy_auto_dir_smooth = h_dirac_output_synthesis_state->cy_auto_dir_smooth_fx;
2426 95963 : p_cy_auto_dir_smooth_prev = h_dirac_output_synthesis_state->cy_auto_dir_smooth_prev_fx;
2427 782400 : FOR( k = 0; k < nchan_out_woLFE; k++ )
2428 : {
2429 686437 : q_cy_auto_dir_smooth_prev_local[k] = getScaleFactor32( p_cy_auto_dir_smooth_prev + imult1616( k, num_freq_bands ), num_freq_bands );
2430 686437 : move16();
2431 686437 : scale_sig32( p_cy_auto_dir_smooth_prev + imult1616( k, num_freq_bands ), num_freq_bands, q_cy_auto_dir_smooth_prev_local[k] ); /*q_cy_auto_dir_smooth_prev_local[k]+h_dirac_output_synthesis_state -> q_cy_auto_dir_smooth_prev*/
2432 686437 : q_cy_auto_dir_smooth_prev_local[k] = add( q_cy_auto_dir_smooth_prev_local[k], h_dirac_output_synthesis_state->q_cy_auto_dir_smooth_prev );
2433 686437 : move16();
2434 686437 : q_com = s_min( q_cy_auto_dir_smooth_local[k], q_cy_auto_dir_smooth_prev_local[k] );
2435 686437 : scale_sig32( p_cy_auto_dir_smooth + imult1616( k, num_freq_bands ), num_freq_bands, sub( q_com, q_cy_auto_dir_smooth_local[k] ) ); /*q_cy_auto_dir_smooth_local -> q_com*/
2436 686437 : scale_sig32( p_cy_auto_dir_smooth_prev + imult1616( k, num_freq_bands ), num_freq_bands, sub( q_com, q_cy_auto_dir_smooth_prev_local[k] ) ); /*q_cy_auto_dir_smooth_prev_local -> q_com*/
2437 686437 : q_cy_auto_dir_smooth_local[k] = q_cy_auto_dir_smooth_prev_local[k] = q_com;
2438 686437 : move16();
2439 686437 : move16();
2440 : }
2441 :
2442 :
2443 95963 : p_cy_cross_dir_smooth = h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx;
2444 95963 : p_cy_cross_dir_smooth_prev = h_dirac_output_synthesis_state->cy_cross_dir_smooth_prev_fx;
2445 95963 : q_com = s_min( h_dirac_output_synthesis_state->q_cy_cross_dir_smooth, h_dirac_output_synthesis_state->q_cy_cross_dir_smooth_prev );
2446 95963 : scale_sig32( p_cy_cross_dir_smooth, imult1616( nchan_out_woLFE, num_freq_bands ), sub( q_com, h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ) ); /*h_dirac_output_synthesis_state->q_cy_cross_dir_smooth -> q_com*/
2447 95963 : scale_sig32( p_cy_cross_dir_smooth_prev, imult1616( nchan_out_woLFE, num_freq_bands ), sub( q_com, h_dirac_output_synthesis_state->q_cy_cross_dir_smooth_prev ) ); /*h_dirac_output_synthesis_state->q_cy_cross_dir_smooth_prev -> q_com*/
2448 95963 : h_dirac_output_synthesis_state->q_cy_cross_dir_smooth = h_dirac_output_synthesis_state->q_cy_cross_dir_smooth_prev = q_com;
2449 95963 : move16();
2450 95963 : move16();
2451 :
2452 95963 : p_cy_auto_diff_smooth = h_dirac_output_synthesis_state->cy_auto_diff_smooth_fx;
2453 95963 : p_cy_auto_diff_smooth_prev = h_dirac_output_synthesis_state->cy_auto_diff_smooth_prev_fx;
2454 95963 : q_com = s_min( h_dirac_output_synthesis_state->q_cy_auto_diff_smooth, h_dirac_output_synthesis_state->q_cy_auto_diff_smooth_prev );
2455 95963 : scale_sig32( p_cy_auto_diff_smooth, imult1616( nchan_out_woLFE, num_freq_bands ), sub( q_com, h_dirac_output_synthesis_state->q_cy_auto_diff_smooth ) ); /*h_dirac_output_synthesis_state->q_cy_auto_diff_smooth -> q_com*/
2456 95963 : scale_sig32( p_cy_auto_diff_smooth_prev, imult1616( nchan_out_woLFE, num_freq_bands ), sub( q_com, h_dirac_output_synthesis_state->q_cy_auto_diff_smooth_prev ) ); /*h_dirac_output_synthesis_state->q_cy_auto_diff_smooth_prev -> q_com*/
2457 95963 : h_dirac_output_synthesis_state->q_cy_auto_diff_smooth = h_dirac_output_synthesis_state->q_cy_auto_diff_smooth_prev = q_com;
2458 95963 : move16();
2459 95963 : move16();
2460 :
2461 782400 : FOR( k = 0; k < nchan_out_woLFE; k++ )
2462 : {
2463 : Word32 power_smooth_temp;
2464 : #ifdef FIX_867_CLDFB_NRG_SCALE
2465 : Word16 qidx;
2466 : #endif
2467 686437 : p_power_smooth = h_dirac_output_synthesis_state->proto_power_smooth_fx + i_mult( proto_direct_index[k], num_freq_bands ); // q_proto_power_smooth
2468 8171782 : FOR( l = 0; l < h_dirac_output_synthesis_params->max_band_decorr; l++ )
2469 : {
2470 : /*Direct*/
2471 7485345 : g1 = alpha[l]; // Q31
2472 7485345 : move32();
2473 7485345 : g2 = L_sub( ONE_IN_Q31, g1 ); // Q31
2474 7485345 : assert( q_cy_auto_dir_smooth_local[k] == q_cy_auto_dir_smooth_prev_local[k] );
2475 7485345 : *( p_cy_auto_dir_smooth_prev ) = L_add( Mpy_32_32( g1, ( *( p_cy_auto_dir_smooth++ ) ) ),
2476 : Mpy_32_32( g2, ( *( p_cy_auto_dir_smooth_prev ) ) ) ); // (Q31, q_cy_auto_dir_smooth_prev_local) -> q_cy_auto_dir_smooth_prev_local
2477 7485345 : move32();
2478 7485345 : assert( h_dirac_output_synthesis_state->q_cy_cross_dir_smooth == h_dirac_output_synthesis_state->q_cy_cross_dir_smooth_prev );
2479 7485345 : *( p_cy_cross_dir_smooth_prev ) = L_add( Mpy_32_32( g1, ( *( p_cy_cross_dir_smooth++ ) ) ),
2480 : Mpy_32_32( g2, ( *( p_cy_cross_dir_smooth_prev ) ) ) ); // (Q31, q_cy_cross_dir_smooth_prev) -> q_cy_cross_dir_smooth_prev
2481 7485345 : move32();
2482 :
2483 7485345 : power_smooth_temp = L_shl( *p_power_smooth, norm_l( *p_power_smooth ) ); // proto_power_smooth_q + norm_l( *p_power_smooth )
2484 7485345 : L_tmp = Mpy_32_32( power_smooth_temp, ( *( p_cy_auto_dir_smooth_prev++ ) ) ); // proto_power_smooth_q + norm_l( *p_power_smooth ) ) + q_cy_auto_dir_smooth_prev_local - 31
2485 : #ifdef FIX_867_CLDFB_NRG_SCALE
2486 7485345 : qidx = s_min( 1, s_max( 0, sub( l, CLDFB_NO_CHANNELS_HALF - 1 ) ) );
2487 7485345 : exp = sub( Q31, sub( add( add( h_dirac_output_synthesis_state->proto_power_smooth_q[qidx], norm_l( *p_power_smooth ) ),
2488 7485345 : q_cy_auto_dir_smooth_prev_local[k] ),
2489 : Q31 ) );
2490 :
2491 : #else
2492 : exp = sub( Q31, sub( add( add( h_dirac_output_synthesis_state->proto_power_smooth_q, norm_l( *p_power_smooth ) ),
2493 : q_cy_auto_dir_smooth_prev_local[k] ),
2494 : Q31 ) );
2495 : #endif
2496 7485345 : p_power_smooth++;
2497 :
2498 7485345 : *( p_gains_dir ) = Sqrt32( L_tmp, &exp ); // (Q31 - exp)
2499 7485345 : move32();
2500 7485345 : *( p_gains_dir ) = L_shl_sat( *( p_gains_dir ), sub( h_dirac_output_synthesis_state->gains_dir_prev_q, sub( Q31, exp ) ) ); // gains_dir_prev_q
2501 7485345 : move32();
2502 :
2503 7485345 : IF( *( p_gains_dir ) < 0 )
2504 : {
2505 0 : *( p_gains_dir ) = 0;
2506 0 : move32();
2507 : }
2508 7485345 : ELSE IF( GT_32( *( p_gains_dir ), W_extract_h( W_shl( W_mult_32_32( DIRAC_GAIN_LIMIT_Q26, L_shl( 1, h_dirac_output_synthesis_state->gains_dir_prev_q ) ), Q5 ) ) ) )
2509 : {
2510 18332 : *( p_gains_dir ) = W_extract_h( W_shl( W_mult_32_32( DIRAC_GAIN_LIMIT_Q26, L_shl( 1, h_dirac_output_synthesis_state->gains_dir_prev_q ) ), Q5 ) ); /*26 + h_dirac_output_synthesis_state->gains_dir_prev_q + 1 + 5 - 32 -> h_dirac_output_synthesis_state->gains_dir_prev_q*/
2511 18332 : move32();
2512 : }
2513 :
2514 7485345 : IF( *( p_cy_cross_dir_smooth_prev++ ) < 0 )
2515 : {
2516 884551 : *( p_gains_dir ) = L_negate( *( p_gains_dir ) ); /*h_dirac_output_synthesis_state->gains_dir_prev_q*/
2517 884551 : move32();
2518 : }
2519 7485345 : p_gains_dir++;
2520 :
2521 : /*diffuse*/
2522 7485345 : *p_power_diff_smooth_prev = L_add( L_add( Mpy_32_32( g1, ( *( p_power_smooth_diff++ ) ) ),
2523 : Mpy_32_32( g2, ( *( p_power_diff_smooth_prev ) ) ) ),
2524 : EPSILLON_FX ); // (Q31, q_power_diff_smooth_prev) -> q_power_diff_smooth_prev
2525 7485345 : move32();
2526 7485345 : *( p_cy_auto_diff_smooth_prev ) = L_add( Mpy_32_32( g1, ( *( p_cy_auto_diff_smooth++ ) ) ),
2527 : Mpy_32_32( g2, ( *( p_cy_auto_diff_smooth_prev ) ) ) ); // (Q31, q_cy_auto_diff_smooth_prev) -> q_cy_auto_diff_smooth_prev
2528 7485345 : move32();
2529 :
2530 7485345 : exp = 0;
2531 7485345 : move16();
2532 7485345 : L_tmp = BASOP_Util_Divide3232_Scale_newton( *( p_cy_auto_diff_smooth_prev++ ), ( *( p_power_diff_smooth_prev++ ) ), &exp ); // (Q31 - exp) + (q_a - q_b)
2533 7485345 : exp = sub( Q31, add( sub( Q31, exp ), sub( h_dirac_output_synthesis_state->q_cy_auto_diff_smooth_prev, h_dirac_output_synthesis_state->proto_power_diff_smooth_q ) ) );
2534 :
2535 7485345 : *( p_gains_diff ) = Sqrt32( L_tmp, &exp ); // (31 - exp)
2536 7485345 : move32();
2537 7485345 : *( p_gains_diff ) = L_shl_sat( *( p_gains_diff ), sub( h_dirac_output_synthesis_state->gains_diff_prev_q, sub( Q31, exp ) ) ); // gains_diff_prev_q
2538 7485345 : move32();
2539 :
2540 7485345 : IF( *( p_gains_diff ) < 0 )
2541 : {
2542 0 : *( p_gains_diff ) = 0;
2543 0 : move32();
2544 : }
2545 7485345 : ELSE IF( GT_32( *( p_gains_diff ), W_extract_h( W_shl( W_mult_32_32( DIRAC_GAIN_LIMIT_Q26, L_shl( 1, h_dirac_output_synthesis_state->gains_diff_prev_q ) ), Q5 ) ) ) ) /*h_dirac_output_synthesis_state->gains_diff_prev_q*/
2546 : {
2547 144111 : *( p_gains_diff ) = W_extract_h( W_shl( W_mult_32_32( DIRAC_GAIN_LIMIT_Q26, L_shl( 1, h_dirac_output_synthesis_state->gains_diff_prev_q ) ), Q5 ) ); /*h_dirac_output_synthesis_state->gains_diff_prev_q*/
2548 144111 : move32();
2549 : }
2550 7485345 : p_gains_diff++;
2551 : }
2552 :
2553 : /*Only direct prototype*/
2554 33115672 : FOR( ; l < num_freq_bands; l++ )
2555 : {
2556 : /*Direct*/
2557 32429235 : g1 = alpha[l]; // Q31
2558 32429235 : move32();
2559 32429235 : g2 = L_sub( ONE_IN_Q31, g1 ); // Q31
2560 32429235 : W_temp = W_add( W_mult_32_32( g1, ( *( p_cy_auto_dir_smooth++ ) ) ),
2561 : W_mult_32_32( g2, ( *( p_cy_auto_dir_smooth_prev ) ) ) ); /*32+q_cy_auto_dir_smooth_prev_local*/
2562 32429235 : q_tmp = W_norm( W_temp );
2563 32429235 : L_tmp = W_extract_h( W_shl( W_temp, q_tmp ) ); // q_cy_auto_dir_smooth_prev_local + q_tmp
2564 32429235 : *( p_cy_auto_dir_smooth_prev++ ) = L_shr_r( L_tmp, q_tmp ); // q_cy_auto_dir_smooth_prev_local
2565 :
2566 32429235 : move32();
2567 32429235 : *( p_cy_cross_dir_smooth_prev ) = L_add( Mpy_32_32( g1, ( *( p_cy_cross_dir_smooth ) ) ),
2568 : Mpy_32_32( g2, ( *( p_cy_cross_dir_smooth_prev ) ) ) ); // (Q31, q_cy_cross_dir_smooth_prev) -> q_cy_cross_dir_smooth_prev
2569 32429235 : move32();
2570 32429235 : test();
2571 32429235 : if ( *( p_cy_cross_dir_smooth_prev ) == 0 && ( *( p_cy_cross_dir_smooth ) != 0 ) )
2572 : {
2573 812890 : *( p_cy_cross_dir_smooth_prev ) = 1;
2574 812890 : move32();
2575 : }
2576 32429235 : ( p_cy_cross_dir_smooth++ );
2577 32429235 : power_smooth_temp = L_shl( *p_power_smooth, norm_l( *p_power_smooth ) );
2578 32429235 : L_tmp = Mpy_32_32( power_smooth_temp, L_tmp ); // proto_power_smooth_q + norm_l( *p_power_smooth ) ) + q_cy_auto_dir_smooth_prev_local - 31
2579 : #ifdef FIX_867_CLDFB_NRG_SCALE
2580 32429235 : qidx = s_min( 1, s_max( 0, sub( l, CLDFB_NO_CHANNELS_HALF - 1 ) ) );
2581 32429235 : exp = sub( Q31, sub( add( add( h_dirac_output_synthesis_state->proto_power_smooth_q[qidx], norm_l( *p_power_smooth ) ),
2582 32429235 : add( q_cy_auto_dir_smooth_prev_local[k], q_tmp ) ),
2583 : Q31 ) );
2584 : #else
2585 : exp = sub( Q31, sub( add( add( h_dirac_output_synthesis_state->proto_power_smooth_q, norm_l( *p_power_smooth ) ),
2586 : add( q_cy_auto_dir_smooth_prev_local[k], q_tmp ) ),
2587 : Q31 ) );
2588 : #endif
2589 :
2590 32429235 : *( p_gains_dir ) = Sqrt32( L_tmp, &exp ); // (Q31 - exp)
2591 32429235 : move32();
2592 32429235 : *( p_gains_dir ) = L_shl_sat( *( p_gains_dir ), sub( h_dirac_output_synthesis_state->gains_dir_prev_q, sub( Q31, exp ) ) ); // gains_dir_prev_q
2593 32429235 : move32();
2594 :
2595 32429235 : IF( *( p_gains_dir ) < 0 )
2596 : {
2597 0 : *( p_gains_dir ) = 0;
2598 0 : move32();
2599 : }
2600 32429235 : ELSE IF( GT_32( *( p_gains_dir ), W_extract_h( W_shl( W_mult_32_32( DIRAC_GAIN_LIMIT_Q26, L_shl( 1, h_dirac_output_synthesis_state->gains_dir_prev_q ) ), Q5 ) ) ) ) /*gains_dir_prev_q*/
2601 : {
2602 24927 : *( p_gains_dir ) = W_extract_h( W_shl( W_mult_32_32( DIRAC_GAIN_LIMIT_Q26, L_shl( 1, h_dirac_output_synthesis_state->gains_dir_prev_q ) ), Q5 ) ); /*gains_dir_prev_q*/
2603 24927 : move32();
2604 : }
2605 :
2606 32429235 : IF( *( p_cy_cross_dir_smooth_prev++ ) < 0 )
2607 : {
2608 2838346 : *( p_gains_dir ) = L_negate( *( p_gains_dir ) ); /*gains_dir_prev_q*/
2609 2838346 : move32();
2610 : }
2611 32429235 : p_gains_dir++;
2612 :
2613 : /*diffuse*/
2614 32429235 : *( p_cy_auto_diff_smooth_prev ) = L_add( Mpy_32_32( g1, ( *( p_cy_auto_diff_smooth ) ) ),
2615 : Mpy_32_32( g2, ( *( p_cy_auto_diff_smooth_prev ) ) ) ); // (Q31, q_cy_auto_diff_smooth_prev) -> q_cy_auto_diff_smooth_prev
2616 :
2617 32429235 : test();
2618 32429235 : if ( *( p_cy_auto_diff_smooth_prev ) == 0 && ( *( p_cy_auto_diff_smooth ) != 0 ) )
2619 : {
2620 1918152 : *( p_cy_auto_diff_smooth_prev ) = 1;
2621 1918152 : move32();
2622 : }
2623 32429235 : ( p_cy_auto_diff_smooth++ );
2624 32429235 : move32();
2625 :
2626 32429235 : power_smooth_temp = L_shl( *p_power_smooth, norm_l( *p_power_smooth ) ); // proto_power_smooth_q + norm_l( *p_power_smooth )
2627 32429235 : L_tmp = Mpy_32_32( power_smooth_temp, ( *( p_cy_auto_diff_smooth_prev ) ) ); // proto_power_smooth_q + norm_l( *p_power_smooth ) ) + q_cy_auto_diff_smooth_prev - 31
2628 :
2629 32429235 : test();
2630 32429235 : test();
2631 32429235 : if ( L_tmp == 0 && ( power_smooth_temp != 0 && *( p_cy_auto_diff_smooth_prev ) != 0 ) )
2632 : {
2633 2382876 : L_tmp = 1;
2634 2382876 : move32();
2635 : }
2636 32429235 : ( p_cy_auto_diff_smooth_prev++ );
2637 : #ifdef FIX_867_CLDFB_NRG_SCALE
2638 32429235 : exp = sub( Q31, sub( add( add( h_dirac_output_synthesis_state->proto_power_smooth_q[qidx], norm_l( *p_power_smooth ) ),
2639 32429235 : h_dirac_output_synthesis_state->q_cy_auto_diff_smooth_prev ),
2640 : Q31 ) );
2641 : #else
2642 : exp = sub( Q31, sub( add( add( h_dirac_output_synthesis_state->proto_power_smooth_q, norm_l( *p_power_smooth ) ),
2643 : h_dirac_output_synthesis_state->q_cy_auto_diff_smooth_prev ),
2644 : Q31 ) );
2645 : #endif
2646 32429235 : p_power_smooth++;
2647 :
2648 32429235 : *( p_gains_diff ) = Sqrt32( L_tmp, &exp ); /*31-exp*/
2649 32429235 : move32();
2650 32429235 : *( p_gains_diff ) = L_shl_sat( *( p_gains_diff ), sub( h_dirac_output_synthesis_state->gains_diff_prev_q, sub( Q31, exp ) ) ); // gains_diff_prev_q
2651 32429235 : move32();
2652 :
2653 32429235 : IF( *( p_gains_diff ) < 0 )
2654 : {
2655 0 : *( p_gains_diff ) = 0;
2656 0 : move32();
2657 : }
2658 32429235 : ELSE IF( GT_32( *( p_gains_diff ), W_extract_h( W_shl( W_mult_32_32( DIRAC_GAIN_LIMIT_Q26, L_shl( 1, h_dirac_output_synthesis_state->gains_diff_prev_q ) ), Q5 ) ) ) ) // gains_diff_prev_q
2659 : {
2660 17063 : *( p_gains_diff ) = W_extract_h( W_shl( W_mult_32_32( DIRAC_GAIN_LIMIT_Q26, L_shl( 1, h_dirac_output_synthesis_state->gains_diff_prev_q ) ), Q5 ) ); // gains_diff_prev_q
2661 17063 : move32();
2662 : }
2663 32429235 : p_gains_diff++;
2664 : }
2665 : }
2666 :
2667 : /*-----------------------------------------------------------------*
2668 : * gain interpolation and output streams
2669 : *-----------------------------------------------------------------*/
2670 95963 : Word16 q_align = sub( h_dirac_output_synthesis_state->proto_direct_buffer_f_q, h_dirac_output_synthesis_state->proto_power_diff_smooth_q );
2671 95963 : if ( h_dirac_output_synthesis_params->max_band_decorr != 0 )
2672 : {
2673 68549 : q_align = sub( h_dirac_output_synthesis_state->proto_direct_buffer_f_q, h_dirac_output_synthesis_state->proto_diffuse_buffer_f_q );
2674 : }
2675 :
2676 476792 : FOR( buf_idx = 0; buf_idx < nbslots; ++buf_idx )
2677 : {
2678 380829 : g1 = L_deposit_h( h_dirac_output_synthesis_params->interpolator_fx[buf_idx] ); // Q15 -> Q31
2679 380829 : g2 = L_sub( ONE_IN_Q31, g1 ); // Q31
2680 :
2681 : /*Direct stream*/
2682 380829 : p_gain_1 = gains_dir;
2683 380829 : p_gain_2 = h_dirac_output_synthesis_state->gains_dir_prev_fx; // gains_dir_prev_q
2684 3122762 : FOR( k = 0; k < nchan_out_woLFE; k++ )
2685 : {
2686 5483866 : p_power_smooth = h_dirac_output_synthesis_state->proto_direct_buffer_f_fx +
2687 2741933 : shl( i_mult( buf_idx, i_mult( num_freq_bands, num_protos_dir ) ), Q1 ) +
2688 2741933 : shl( i_mult( proto_direct_index[k], num_freq_bands ), Q1 );
2689 162229173 : FOR( l = 0; l < num_freq_bands; l++ )
2690 : {
2691 159487240 : g = L_add( Mpy_32_32( g1, *( p_gain_1++ ) ), Mpy_32_32( g2, *( p_gain_2++ ) ) ); // (Q31, gains_dir_prev_q) -> gains_dir_prev_q
2692 :
2693 159487240 : Cldfb_RealBuffer64_fx[k][buf_idx][l] = W_mult0_32_32( g, ( *( p_power_smooth++ ) ) ); // (gains_dir_prev_q, q_proto_direct_buffer) -> gains_dir_prev_q + q_proto_direct_buffer
2694 159487240 : move64();
2695 :
2696 159487240 : Cldfb_ImagBuffer64_fx[k][buf_idx][l] = W_mult0_32_32( g, ( *( p_power_smooth++ ) ) ); // (gains_dir_prev_q, q_proto_direct_buffer) -> gains_dir_prev_q + q_proto_direct_buffer
2697 159487240 : move64();
2698 : }
2699 : }
2700 :
2701 : /*Diffuse stream*/
2702 380829 : IF( h_dirac_output_synthesis_params->max_band_decorr != 0 )
2703 : {
2704 548128 : p_power_smooth_diff = h_dirac_output_synthesis_state->proto_diffuse_buffer_f_fx +
2705 274064 : shl( i_mult( buf_idx, i_mult( h_dirac_output_synthesis_params->max_band_decorr, nchan_out_woLFE ) ), Q1 );
2706 : }
2707 380829 : p_gain_1 = gains_diff;
2708 380829 : p_gain_2 = h_dirac_output_synthesis_state->gains_diff_prev_fx; // gains_diff_prev_q
2709 3122762 : FOR( k = 0; k < nchan_out_woLFE; k++ )
2710 : {
2711 32669453 : FOR( l = 0; l < h_dirac_output_synthesis_params->max_band_decorr; l++ )
2712 : {
2713 29927520 : g = L_add( Mpy_32_32( g1, *( p_gain_1++ ) ), Mpy_32_32( g2, *( p_gain_2++ ) ) ); // (Q31, gains_diff_prev_q) -> gains_diff_prev_q
2714 29927520 : Cldfb_RealBuffer64_fx[k][buf_idx][l] = W_add( Cldfb_RealBuffer64_fx[k][buf_idx][l],
2715 29927520 : W_shr( W_mult0_32_32( g, ( *( p_power_smooth_diff++ ) ) ), negate( q_align ) ) ); // (gains_diff_prev_q, q_proto_direct_buffer) -> gains_diff_prev_q + q_proto_direct_buffer
2716 29927520 : move64();
2717 :
2718 29927520 : if ( LT_64( W_temp, W_abs( Cldfb_RealBuffer64_fx[k][buf_idx][l] ) ) )
2719 : {
2720 208132 : W_temp = W_abs( Cldfb_RealBuffer64_fx[k][buf_idx][l] );
2721 : }
2722 :
2723 29927520 : Cldfb_ImagBuffer64_fx[k][buf_idx][l] = W_add( Cldfb_ImagBuffer64_fx[k][buf_idx][l],
2724 29927520 : W_shr( W_mult0_32_32( g, ( *( p_power_smooth_diff++ ) ) ), negate( q_align ) ) ); // (gains_diff_prev_q, q_proto_direct_buffer) -> gains_diff_prev_q + q_proto_direct_buffer
2725 29927520 : move64();
2726 :
2727 29927520 : if ( LT_64( W_temp, W_abs( Cldfb_ImagBuffer64_fx[k][buf_idx][l] ) ) )
2728 : {
2729 116796 : W_temp = W_abs( Cldfb_ImagBuffer64_fx[k][buf_idx][l] );
2730 : }
2731 : }
2732 :
2733 : /*Direct proto*/
2734 5483866 : p_power_smooth = h_dirac_output_synthesis_state->proto_direct_buffer_f_fx +
2735 2741933 : shl( i_mult( buf_idx, i_mult( num_freq_bands, num_protos_dir ) ), Q1 ) +
2736 2741933 : shl( i_mult( proto_direct_index[k], num_freq_bands ), Q1 ) +
2737 2741933 : shl( h_dirac_output_synthesis_params->max_band_decorr, Q1 );
2738 132301653 : FOR( ; l < num_freq_bands; l++ )
2739 : {
2740 129559720 : g = L_add( Mpy_32_32( g1, *( p_gain_1++ ) ), Mpy_32_32( g2, *( p_gain_2++ ) ) ); // (Q31, gains_diff_prev_q) -> gains_diff_prev_q
2741 129559720 : Cldfb_RealBuffer64_fx[k][buf_idx][l] = W_add( Cldfb_RealBuffer64_fx[k][buf_idx][l],
2742 129559720 : W_mult0_32_32( g, ( *( p_power_smooth++ ) ) ) ); // (gains_diff_prev_q, q_proto_direct_buffer) -> gains_diff_prev_q + q_proto_direct_buffer
2743 129559720 : move64();
2744 :
2745 129559720 : if ( LT_64( W_temp, W_abs( Cldfb_RealBuffer64_fx[k][buf_idx][l] ) ) )
2746 : {
2747 85621 : W_temp = W_abs( Cldfb_RealBuffer64_fx[k][buf_idx][l] );
2748 : }
2749 :
2750 129559720 : Cldfb_ImagBuffer64_fx[k][buf_idx][l] = W_add( Cldfb_ImagBuffer64_fx[k][buf_idx][l],
2751 129559720 : W_mult0_32_32( g, ( *( p_power_smooth++ ) ) ) ); // (gains_diff_prev_q, q_proto_direct_buffer) -> gains_diff_prev_q + q_proto_direct_buffer
2752 129559720 : move64();
2753 :
2754 129559720 : if ( LT_64( W_temp, W_abs( Cldfb_ImagBuffer64_fx[k][buf_idx][l] ) ) )
2755 : {
2756 49668 : W_temp = W_abs( Cldfb_ImagBuffer64_fx[k][buf_idx][l] ); // gains_diff_prev_q + q_proto_direct_buffer
2757 : }
2758 : }
2759 : }
2760 : }
2761 95963 : q_align = W_norm( W_temp );
2762 476792 : FOR( buf_idx = 0; buf_idx < nbslots; ++buf_idx )
2763 : {
2764 3122762 : FOR( k = 0; k < nchan_out_woLFE; k++ )
2765 : {
2766 162229173 : FOR( l = 0; l < num_freq_bands; l++ )
2767 : {
2768 159487240 : RealBuffer[k][buf_idx][l] = W_extract_h( W_shl( Cldfb_RealBuffer64_fx[k][buf_idx][l], q_align ) ); /*( ( ( h_dirac_output_synthesis_state->proto_direct_buffer_f_q+h_dirac_output_synthesis_state->gains_dir_prev_q )+ q_align )- 32 )*/
2769 159487240 : move32();
2770 159487240 : ImagBuffer[k][buf_idx][l] = W_extract_h( W_shl( Cldfb_ImagBuffer64_fx[k][buf_idx][l], q_align ) ); /*( ( ( h_dirac_output_synthesis_state->proto_direct_buffer_f_q+h_dirac_output_synthesis_state->gains_dir_prev_q )+ q_align )- 32 )*/
2771 159487240 : move32();
2772 : }
2773 : }
2774 : }
2775 :
2776 95963 : *q_Cldfb = sub( add( add( h_dirac_output_synthesis_state->proto_direct_buffer_f_q, h_dirac_output_synthesis_state->gains_dir_prev_q ), q_align ), 32 );
2777 95963 : move16();
2778 :
2779 : /*-----------------------------------------------------------------*
2780 : * update buffers
2781 : *-----------------------------------------------------------------*/
2782 :
2783 : /* store estimates for next synthesis block */
2784 95963 : Copy32( gains_dir, h_dirac_output_synthesis_state->gains_dir_prev_fx, imult1616( num_freq_bands, nchan_out_woLFE ) ); /*gains_dir_prev_q*/
2785 95963 : Copy32( gains_diff, h_dirac_output_synthesis_state->gains_diff_prev_fx, imult1616( num_freq_bands, nchan_out_woLFE ) ); /*gains_diff_prev_q*/
2786 :
2787 : /* reset values */
2788 95963 : set_zero_fx( h_dirac_output_synthesis_state->proto_power_smooth_fx, imult1616( num_freq_bands, num_protos_dir ) );
2789 95963 : IF( h_dirac_output_synthesis_state->proto_power_diff_smooth_fx != NULL )
2790 : {
2791 95963 : set_zero_fx( h_dirac_output_synthesis_state->proto_power_diff_smooth_fx, h_dirac_output_synthesis_params->max_band_decorr * nchan_out_woLFE );
2792 : }
2793 :
2794 95963 : minimum_fx( q_cy_auto_dir_smooth_prev_local, nchan_out_woLFE, &h_dirac_output_synthesis_state->q_cy_auto_dir_smooth_prev );
2795 782400 : FOR( k = 0; k < nchan_out_woLFE; k++ )
2796 : {
2797 686437 : scale_sig32( h_dirac_output_synthesis_state->cy_auto_dir_smooth_prev_fx + ( k * num_freq_bands ), num_freq_bands, sub( h_dirac_output_synthesis_state->q_cy_auto_dir_smooth_prev, q_cy_auto_dir_smooth_prev_local[k] ) ); /*q_cy_auto_dir_smooth_prev_local[k] -> h_dirac_output_synthesis_state->q_cy_auto_dir_smooth_prev*/
2798 : }
2799 :
2800 95963 : set_zero_fx( h_dirac_output_synthesis_state->cy_auto_dir_smooth_fx, imult1616( num_freq_bands, nchan_out_woLFE ) );
2801 95963 : h_dirac_output_synthesis_state->q_cy_auto_dir_smooth = 0;
2802 95963 : move16();
2803 95963 : set_zero_fx( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx, imult1616( num_freq_bands, nchan_out_woLFE ) );
2804 95963 : h_dirac_output_synthesis_state->q_cy_cross_dir_smooth = 0;
2805 95963 : move16();
2806 95963 : set_zero_fx( h_dirac_output_synthesis_state->cy_auto_diff_smooth_fx, imult1616( num_freq_bands, nchan_out_woLFE ) );
2807 95963 : h_dirac_output_synthesis_state->q_cy_auto_diff_smooth = 0;
2808 95963 : move16();
2809 :
2810 95963 : pop_wmops();
2811 :
2812 95963 : return;
2813 : }
2814 :
2815 :
2816 : /*-------------------------------------------------------------------------
2817 : * ivas_dirac_dec_get_response_split_order()
2818 : *
2819 : * calculate reponse, 1 degree resolution
2820 : *------------------------------------------------------------------------*/
2821 :
2822 144000 : static void ivas_dirac_dec_get_response_split_order_fx(
2823 : const Word16 azimuth, /*q0*/
2824 : const Word16 elevation, /*q0*/
2825 : Word32 *response, /*q_response*/
2826 : const Word16 shd_rot_max_order,
2827 : const Word32 *p_Rmat /* Q30 */,
2828 : Word16 *q_response )
2829 : {
2830 : Word16 index_azimuth, index_elevation;
2831 : Word16 el, e, az;
2832 : Word32 cos_1, cos_2, sin_1, cos_az[3];
2833 : Word32 sin_az[3];
2834 : Word32 f, c;
2835 : Word16 l, m;
2836 : Word16 b, b1, b_2, b1_2, a;
2837 : Word32 dv_0, dv_1, dv_2, dv_r_0, dv_r_1, dv_r_2;
2838 : Word32 w;
2839 : Word16 tmp;
2840 : Word32 temp;
2841 : Word16 exp;
2842 :
2843 144000 : push_wmops( "ivas_dirac_dec_get_response_split_order" );
2844 :
2845 : /* Corner case for handling crash in idiv1616 when numerator is 0 */
2846 144000 : IF( EQ_16( azimuth, -180 ) )
2847 : {
2848 0 : tmp = 0;
2849 0 : move16();
2850 : }
2851 : ELSE
2852 : {
2853 144000 : tmp = idiv1616( add( azimuth, 180 ), 360 );
2854 : }
2855 144000 : index_azimuth = sub( add( azimuth, 180 ), i_mult( tmp, 360 ) ); // index_azimuth = (azimuth + 180) % 360
2856 144000 : index_elevation = add( elevation, 90 );
2857 :
2858 144000 : IF( GT_16( index_elevation, 90 ) )
2859 : {
2860 22893 : e = -ONE_IN_Q14; /*-1 in Q14*/
2861 22893 : move16();
2862 22893 : el = sub( 180, index_elevation );
2863 : }
2864 : ELSE
2865 : {
2866 121107 : e = ONE_IN_Q14; /*1 in Q14*/
2867 121107 : move16();
2868 121107 : el = index_elevation;
2869 121107 : move16();
2870 : }
2871 :
2872 144000 : IF( GT_16( index_azimuth, 180 ) )
2873 : {
2874 57389 : az = sub( 360, index_azimuth );
2875 57389 : f = -ONE_IN_Q30; /*-1 Q30*/
2876 57389 : move32();
2877 : }
2878 : ELSE
2879 : {
2880 86611 : az = index_azimuth;
2881 86611 : move16();
2882 86611 : f = ONE_IN_Q30; /*1 Q30*/
2883 86611 : move32();
2884 : }
2885 :
2886 : // dirac_gains_trg_term_int Q30
2887 144000 : cos_1 = L_shr( dirac_gains_trg_term_int[az][0], 1 ); // Q29
2888 144000 : cos_2 = L_shl( Mpy_32_32( cos_1, cos_1 ), 2 ); // Q29
2889 144000 : sin_1 = Mpy_32_32( f, dirac_gains_trg_term_int[az][1] ); // Q29
2890 :
2891 144000 : cos_az[0] = cos_1; // Q29
2892 144000 : move32();
2893 144000 : cos_az[1] = L_shl( L_sub( Mpy_32_32( TWO_IN_Q29, cos_2 ), ONE_IN_Q27 ), 2 ); // Q29
2894 144000 : move32();
2895 144000 : cos_az[2] = L_sub( L_shl( Mpy_32_32( Mpy_32_32( TWO_IN_Q29, cos_1 ), cos_az[1] ), 4 ), cos_az[0] ); // Q29
2896 144000 : move32();
2897 :
2898 144000 : sin_az[0] = sin_1; // Q29
2899 144000 : move32();
2900 144000 : sin_az[1] = L_shl( Mpy_32_32( Mpy_32_32( sin_1, TWO_IN_Q29 ), cos_1 ), 4 ); // Q29
2901 144000 : move32();
2902 144000 : sin_az[2] = L_shl( Mpy_32_32( sin_1, L_sub( Mpy_32_32( FOUR_IN_Q28, cos_2 ), ONE_IN_Q26 ) ), 5 ); // Q29
2903 144000 : move32();
2904 :
2905 144000 : response[0] = ONE_IN_Q29;
2906 144000 : move32();
2907 :
2908 480000 : FOR( l = 1; l <= shd_rot_max_order; l++ )
2909 : {
2910 336000 : b_2 = i_mult( l, l );
2911 336000 : b1_2 = add( b_2, i_mult( 2, l ) );
2912 720000 : FOR( m = 0; m < l; m += 2 )
2913 : {
2914 384000 : b = add( b_2, m );
2915 384000 : a = dirac_gains_P_idx[b];
2916 384000 : move16();
2917 :
2918 384000 : c = Mpy_32_32( Mpy_32_32( SQRT2_FIXED, dirac_gains_norm_term_int[a] ), dirac_gains_Pnm_int[el][a] ); // Q25
2919 :
2920 384000 : response[b] = L_shl( Mpy_32_32( c, sin_az[l - m - 1] ), 6 ); // Q29
2921 384000 : move32();
2922 :
2923 384000 : b1 = sub( b1_2, m );
2924 384000 : response[b1] = L_shl( Mpy_32_32( c, cos_az[l - m - 1] ), 6 ); // Q29
2925 384000 : move32();
2926 : }
2927 :
2928 528000 : FOR( m = 1; m < l; m += 2 )
2929 : {
2930 192000 : b = add( b_2, m );
2931 192000 : a = dirac_gains_P_idx[b];
2932 192000 : move16();
2933 :
2934 192000 : c = Mpy_32_32( Mpy_32_32( SQRT2_FIXED, dirac_gains_norm_term_int[a] ), dirac_gains_Pnm_int[el][a] ); // Q25
2935 192000 : c = Mpy_32_16_1( c, e ); // Q24
2936 :
2937 192000 : response[b] = L_shl( Mpy_32_32( c, sin_az[l - m - 1] ), 7 ); // Q29
2938 192000 : move32();
2939 :
2940 192000 : b1 = sub( b1_2, m );
2941 192000 : response[b1] = L_shl( Mpy_32_32( c, cos_az[l - m - 1] ), 7 ); // Q29
2942 192000 : move32();
2943 : }
2944 :
2945 336000 : b = add( b_2, l );
2946 336000 : a = dirac_gains_P_idx[b];
2947 336000 : move16();
2948 :
2949 336000 : c = L_shl( Mpy_32_32( dirac_gains_norm_term_int[a], dirac_gains_Pnm_int[el][a] ), 3 ); // Q29
2950 336000 : IF( EQ_16( l % 2, 1 ) )
2951 : {
2952 192000 : c = L_shl( Mpy_32_16_1( c, e ), 1 ); // Q29
2953 : }
2954 :
2955 336000 : response[b] = c; // Q29
2956 336000 : move32();
2957 : }
2958 :
2959 : /*Conversion spherical to cartesian coordinates*/
2960 144000 : w = L_negate( dirac_gains_trg_term_int[el][1] ); // Q30
2961 144000 : dv_0 = Mpy_32_32( w, cos_1 ); // Q28
2962 144000 : dv_1 = Mpy_32_32( w, sin_1 ); // Q28
2963 144000 : dv_2 = L_shr( Mpy_32_16_1( dirac_gains_trg_term_int[el][0], e ), 1 ); // Q28
2964 :
2965 : /*Rotation mtx multiplication*/
2966 144000 : dv_r_0 = Madd_32_32( Madd_32_32( Mpy_32_32( L_shr( p_Rmat[0], Q1 ), dv_0 ), L_shr( p_Rmat[1], Q1 ), dv_1 ), L_shr( p_Rmat[2], Q1 ), dv_2 ); // Q26
2967 144000 : dv_r_1 = Madd_32_32( Madd_32_32( Mpy_32_32( L_shr( p_Rmat[3], Q1 ), dv_0 ), L_shr( p_Rmat[4], Q1 ), dv_1 ), L_shr( p_Rmat[5], Q1 ), dv_2 ); // Q26
2968 144000 : dv_r_2 = Madd_32_32( Madd_32_32( Mpy_32_32( L_shr( p_Rmat[6], Q1 ), dv_0 ), L_shr( p_Rmat[7], Q1 ), dv_1 ), L_shr( p_Rmat[8], Q1 ), dv_2 ); // Q26
2969 :
2970 144000 : tmp = BASOP_util_atan2( dv_r_1, dv_r_0, 0 ); // Q13
2971 144000 : index_azimuth = shr( mult( tmp, _180_OVER_PI_Q9 ), 7 ); // Q0;
2972 144000 : IF( EQ_16( index_azimuth, -180 ) )
2973 : {
2974 6462 : tmp = 0;
2975 6462 : move16();
2976 : }
2977 : ELSE
2978 : {
2979 137538 : tmp = idiv1616( add( index_azimuth, 180 ), 360 );
2980 : }
2981 144000 : index_azimuth = sub( add( index_azimuth, 180 ), i_mult( tmp, 360 ) ); // index_azimuth = (index_azimuth + 180) % 360
2982 :
2983 144000 : temp = L_add( Mpy_32_32( dv_r_0, dv_r_0 ), Mpy_32_32( dv_r_1, dv_r_1 ) ); // Q21
2984 144000 : exp = sub( 31, Q21 );
2985 144000 : temp = Sqrt32( temp, &exp );
2986 :
2987 144000 : tmp = BASOP_util_atan2( dv_r_2, temp, sub( sub( 31, Q26 ), exp ) ); // Q13
2988 144000 : index_elevation = shr( mult( tmp, _180_OVER_PI_Q9 ), Q7 ); // Q0
2989 144000 : index_elevation = add( index_elevation, 90 );
2990 :
2991 144000 : IF( GT_16( index_elevation, 90 ) )
2992 : {
2993 22893 : e = -ONE_IN_Q14; /*-1 Q14*/
2994 22893 : move16();
2995 22893 : el = sub( 180, index_elevation );
2996 : }
2997 : ELSE
2998 : {
2999 121107 : e = ONE_IN_Q14; /*1 Q14*/
3000 121107 : move16();
3001 121107 : el = index_elevation;
3002 121107 : move16();
3003 : }
3004 :
3005 144000 : IF( GT_16( index_azimuth, 180 ) )
3006 : {
3007 110941 : az = sub( 360, index_azimuth );
3008 110941 : f = -ONE_IN_Q30; /*-1 Q30*/
3009 110941 : move32();
3010 : }
3011 : ELSE
3012 : {
3013 33059 : az = index_azimuth;
3014 33059 : move16();
3015 33059 : f = ONE_IN_Q30; /*1 Q30*/
3016 33059 : move32();
3017 : }
3018 :
3019 : // dirac_gains_trg_term_int Q30
3020 144000 : cos_1 = L_shr( dirac_gains_trg_term_int[az][0], 1 ); // Q29
3021 144000 : cos_2 = L_shl( Mpy_32_32( cos_1, cos_1 ), 2 ); // Q29
3022 144000 : sin_1 = Mpy_32_32( f, dirac_gains_trg_term_int[az][1] ); // Q29
3023 :
3024 144000 : cos_az[0] = cos_1; // Q29
3025 144000 : move32();
3026 144000 : cos_az[1] = L_shl( L_sub( Mpy_32_32( TWO_IN_Q29, cos_2 ), ONE_IN_Q27 ), 2 ); // Q29
3027 144000 : move32();
3028 144000 : cos_az[2] = L_sub( L_shl( Mpy_32_32( Mpy_32_32( TWO_IN_Q29, cos_1 ), cos_az[1] ), 4 ), cos_az[0] ); // Q29
3029 144000 : move32();
3030 :
3031 144000 : sin_az[0] = sin_1; // Q29
3032 144000 : move32();
3033 144000 : sin_az[1] = L_shl( Mpy_32_32( Mpy_32_32( sin_1, TWO_IN_Q29 ), cos_1 ), 4 ); // Q29
3034 144000 : move32();
3035 144000 : sin_az[2] = L_shl( Mpy_32_32( sin_1, L_sub( Mpy_32_32( FOUR_IN_Q28, cos_2 ), ONE_IN_Q26 ) ), 5 ); // Q29
3036 144000 : move32();
3037 :
3038 240000 : FOR( l = shd_rot_max_order + 1; l <= 3; l++ )
3039 : {
3040 96000 : b_2 = i_mult( l, l );
3041 96000 : b1_2 = add( b_2, i_mult( 2, l ) );
3042 :
3043 288000 : FOR( m = 0; m < l; m += 2 )
3044 : {
3045 192000 : b = add( b_2, m );
3046 192000 : a = dirac_gains_P_idx[b];
3047 192000 : move16();
3048 :
3049 192000 : c = Mpy_32_32( Mpy_32_32( SQRT2_FIXED, dirac_gains_norm_term_int[a] ), dirac_gains_Pnm_int[el][a] ); // Q25
3050 :
3051 192000 : response[b] = L_shl( Mpy_32_32( c, sin_az[l - m - 1] ), 6 ); // Q29
3052 192000 : move32();
3053 :
3054 192000 : b1 = sub( b1_2, m );
3055 192000 : response[b1] = L_shl( Mpy_32_32( c, cos_az[l - m - 1] ), 6 ); // Q29
3056 192000 : move32();
3057 : }
3058 :
3059 192000 : FOR( m = 1; m < l; m += 2 )
3060 : {
3061 96000 : b = add( b_2, m );
3062 96000 : a = dirac_gains_P_idx[b];
3063 96000 : move16();
3064 :
3065 96000 : c = Mpy_32_32( Mpy_32_32( SQRT2_FIXED, dirac_gains_norm_term_int[a] ), dirac_gains_Pnm_int[el][a] ); // Q25
3066 96000 : c = Mpy_32_16_1( c, e ); // Q24
3067 :
3068 96000 : response[b] = L_shl( Mpy_32_32( c, sin_az[l - m - 1] ), 7 ); // Q29
3069 96000 : move32();
3070 :
3071 96000 : b1 = sub( b1_2, m );
3072 96000 : response[b1] = L_shl( Mpy_32_32( c, cos_az[l - m - 1] ), 7 ); // Q29
3073 96000 : move32();
3074 : }
3075 :
3076 96000 : b = add( b_2, l );
3077 96000 : a = dirac_gains_P_idx[b];
3078 96000 : move16();
3079 :
3080 96000 : c = L_shl( Mpy_32_32( dirac_gains_norm_term_int[a], dirac_gains_Pnm_int[el][a] ), 3 ); // Q29
3081 :
3082 96000 : IF( EQ_16( l % 2, 1 ) )
3083 : {
3084 96000 : c = L_shl( Mpy_32_16_1( c, e ), 1 ); // Q29
3085 : }
3086 :
3087 96000 : response[b] = c; // Q29
3088 96000 : move32();
3089 : }
3090 :
3091 144000 : *q_response = Q29;
3092 144000 : move16();
3093 :
3094 144000 : pop_wmops();
3095 :
3096 144000 : return;
3097 : }
3098 :
3099 : /*-------------------------------------------------------------------------
3100 : * ivas_dirac_dec_compute_directional_responses()
3101 : *
3102 : *
3103 : *------------------------------------------------------------------------*/
3104 :
3105 1050811 : void ivas_dirac_dec_compute_directional_responses_fx(
3106 : SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common spatial renderer data handle */
3107 : DIRAC_REND_HANDLE hDirACRend, /* i/o: DirAC renderer handle */
3108 : const VBAP_HANDLE hVBAPdata, /* i : VBAP structure */
3109 : const Word16 *masa_band_mapping, /* i : Band mapping for MASA, NULL assumes not using MASA in any form */
3110 : MASA_ISM_DATA_HANDLE hMasaIsm, /* i : MASA_ISM data structure */
3111 : const Word16 *azimuth,
3112 : const Word16 *elevation,
3113 : const Word16 md_idx,
3114 : const Word32 *surCohRatio_fx, /*i:Q_surCohRatio*/
3115 : Word16 Q_surCohRatio,
3116 : const Word16 shd_rot_max_order, /* i : split-order rotation method */
3117 : const Word32 *p_Rmat, /* i : rotation matrix Q30*/
3118 : const Word16 hodirac_flag /* i : flag to indicate HO-DirAC mode */
3119 : )
3120 : {
3121 : Word16 k, l, i;
3122 : Word16 num_channels_dir;
3123 : const Word16 *azimuth2, *elevation2;
3124 :
3125 : Word32 direct_response_hoa_fx[MAX_OUTPUT_CHANNELS]; /* number of output channels (HOA 3rd order) -> 16 */
3126 : Word32 direct_response_ls_fx[MAX_OUTPUT_CHANNELS];
3127 : Word32 direct_response_square_fx[MAX_OUTPUT_CHANNELS];
3128 : Word32 direct_response_dir2_fx[MAX_OUTPUT_CHANNELS];
3129 : Word32 directRatio_fx[MASA_MAXIMUM_DIRECTIONS];
3130 : Word16 Q_direct_response_ls, exp_direct_response_ls;
3131 : Word16 Q_direct_response_dir2, exp_direct_response_dir2;
3132 : Word16 Q_direct_response_hoa, exp_direct_response_hoa;
3133 : Word16 direct_response_square_q, direct_response_q;
3134 1050811 : Word16 exp_surCohRatio = sub( 31, Q_surCohRatio );
3135 : Word32 totalDirect_fx;
3136 : Word32 *direct_response_fx;
3137 : Word16 codingBand;
3138 : Word16 dipole_freq_range[2];
3139 : MASA_TRANSPORT_SIGNAL_TYPE transport_signal_type;
3140 :
3141 1050811 : Q_direct_response_ls = Q31;
3142 1050811 : move16();
3143 1050811 : exp_direct_response_ls = 0;
3144 1050811 : move16();
3145 1050811 : Q_direct_response_dir2 = Q31;
3146 1050811 : move16();
3147 1050811 : exp_direct_response_dir2 = 0;
3148 1050811 : move16();
3149 1050811 : Q_direct_response_hoa = Q31;
3150 1050811 : move16();
3151 1050811 : exp_direct_response_hoa = 0;
3152 1050811 : move16();
3153 1050811 : direct_response_square_q = Q31;
3154 1050811 : move16();
3155 1050811 : direct_response_q = Q29;
3156 1050811 : move16();
3157 :
3158 1050811 : azimuth2 = NULL;
3159 1050811 : elevation2 = NULL;
3160 1050811 : transport_signal_type = MASA_STEREO_NOT_DEFINED;
3161 1050811 : move32();
3162 :
3163 1050811 : IF( hDirACRend->masa_stereo_type_detect != NULL )
3164 : {
3165 16206 : dipole_freq_range[0] = hDirACRend->masa_stereo_type_detect->dipole_freq_range[0];
3166 16206 : move16();
3167 16206 : dipole_freq_range[1] = hDirACRend->masa_stereo_type_detect->dipole_freq_range[1];
3168 16206 : move16();
3169 16206 : transport_signal_type = hDirACRend->masa_stereo_type_detect->masa_stereo_type;
3170 16206 : move16();
3171 : }
3172 :
3173 1050811 : num_channels_dir = hDirACRend->num_outputs_dir;
3174 1050811 : move16();
3175 1050811 : IF( EQ_16( hSpatParamRendCom->numParametricDirections, 2 ) )
3176 : {
3177 280616 : azimuth2 = hSpatParamRendCom->azimuth2[md_idx]; /*q0*/
3178 280616 : move16();
3179 280616 : elevation2 = hSpatParamRendCom->elevation2[md_idx]; /*q0*/
3180 280616 : move16();
3181 : }
3182 :
3183 1050811 : codingBand = -1;
3184 :
3185 1050811 : assert( num_channels_dir <= MAX_OUTPUT_CHANNELS && "Number of channels is too high" );
3186 :
3187 57347511 : FOR( k = 0; k < hSpatParamRendCom->num_freq_bands; ++k )
3188 : {
3189 56296700 : test();
3190 56296700 : if ( masa_band_mapping != NULL && EQ_16( k, MASA_band_grouping_24[masa_band_mapping[add( codingBand, 1 )]] ) )
3191 : {
3192 1027115 : codingBand = add( codingBand, 1 );
3193 : }
3194 :
3195 56296700 : test();
3196 56296700 : test();
3197 56296700 : test();
3198 56296700 : IF( masa_band_mapping != NULL && GT_16( k, MASA_band_grouping_24[masa_band_mapping[codingBand]] ) &&
3199 : LT_16( k, MASA_band_grouping_24[masa_band_mapping[add( codingBand, 1 )]] ) &&
3200 : NE_16( k, hDirACRend->h_output_synthesis_psd_params.max_band_decorr ) )
3201 : {
3202 : /* Panning gains have to be computed only for the first bin of the coding band in MASA, for other bins the previous values can be used */
3203 4116660 : IF( NE_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) )
3204 : {
3205 3526317 : mvr2r_inc_fixed( &hDirACRend->h_output_synthesis_psd_state.direct_responses_square_fx[k - 1],
3206 3526317 : hSpatParamRendCom->num_freq_bands, &hDirACRend->h_output_synthesis_psd_state.direct_responses_square_fx[k],
3207 3526317 : hSpatParamRendCom->num_freq_bands, num_channels_dir ); /*direct_response_square_q*/
3208 : }
3209 4116660 : mvr2r_inc_fixed( &hDirACRend->h_output_synthesis_psd_state.direct_responses_fx[k - 1],
3210 4116660 : hSpatParamRendCom->num_freq_bands,
3211 4116660 : &hDirACRend->h_output_synthesis_psd_state.direct_responses_fx[k],
3212 4116660 : hSpatParamRendCom->num_freq_bands, num_channels_dir ); /*direct_response_q*/
3213 : }
3214 : ELSE
3215 : {
3216 : /* HOA3 PANNING */
3217 52180040 : IF( EQ_16( hDirACRend->panningConf, DIRAC_PANNING_HOA3 ) )
3218 : {
3219 47265169 : set32_fx( direct_response_hoa_fx, ONE_IN_Q29, MAX_OUTPUT_CHANNELS ); /*q29*/
3220 47265169 : set32_fx( direct_response_dir2_fx, ONE_IN_Q29, MAX_OUTPUT_CHANNELS ); /*q29*/
3221 :
3222 47265169 : Q_direct_response_hoa = Q29;
3223 47265169 : move16();
3224 47265169 : Q_direct_response_dir2 = Q29;
3225 47265169 : move16();
3226 47265169 : exp_direct_response_hoa = 0;
3227 47265169 : move16();
3228 47265169 : exp_direct_response_dir2 = 0;
3229 47265169 : move16();
3230 :
3231 47265169 : IF( p_Rmat != 0 )
3232 : {
3233 96000 : ivas_dirac_dec_get_response_split_order_fx( azimuth[k], elevation[k], direct_response_hoa_fx, shd_rot_max_order, p_Rmat, &Q_direct_response_hoa );
3234 :
3235 96000 : IF( hodirac_flag )
3236 : {
3237 48000 : ivas_dirac_dec_get_response_split_order_fx( azimuth2[k], elevation2[k], direct_response_dir2_fx, shd_rot_max_order, p_Rmat, &Q_direct_response_dir2 );
3238 : }
3239 : }
3240 : ELSE
3241 : {
3242 : #ifdef FIX_1310_SPEEDUP_ivas_dirac_dec_get_response_fx
3243 47169169 : ivas_dirac_dec_get_response_fx_29( azimuth[k], elevation[k], direct_response_hoa_fx, hDirACRend->hOutSetup.ambisonics_order );
3244 : #else
3245 : ivas_dirac_dec_get_response_fx( azimuth[k], elevation[k], direct_response_hoa_fx, hDirACRend->hOutSetup.ambisonics_order, Q_direct_response_hoa );
3246 : #endif
3247 :
3248 47169169 : IF( hodirac_flag )
3249 : {
3250 : #ifdef FIX_1310_SPEEDUP_ivas_dirac_dec_get_response_fx
3251 15762800 : ivas_dirac_dec_get_response_fx_29( azimuth2[k], elevation2[k], direct_response_dir2_fx, hDirACRend->hOutSetup.ambisonics_order );
3252 : #else
3253 : ivas_dirac_dec_get_response_fx( azimuth2[k], elevation2[k], direct_response_dir2_fx, hDirACRend->hOutSetup.ambisonics_order, Q_direct_response_dir2 );
3254 : #endif
3255 : }
3256 : }
3257 :
3258 47265169 : test();
3259 47265169 : test();
3260 47265169 : test();
3261 47265169 : test();
3262 47265169 : IF( masa_band_mapping == NULL && EQ_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) )
3263 : {
3264 46817120 : mvr2r_inc_fixed( direct_response_hoa_fx, 1, &hDirACRend->h_output_synthesis_psd_state.direct_responses_fx[k], hSpatParamRendCom->num_freq_bands, num_channels_dir ); /*Q_direct_response_hoa*/
3265 :
3266 46817120 : IF( hodirac_flag )
3267 : {
3268 15810800 : mvr2r_inc_fixed( direct_response_dir2_fx, 1, &hDirACRend->h_output_synthesis_psd_state.direct_responses_fx[k + hSpatParamRendCom->num_freq_bands * num_channels_dir], hSpatParamRendCom->num_freq_bands, num_channels_dir ); /*Q_direct_response_dir2*/
3269 : }
3270 : }
3271 448049 : ELSE IF( ( ( EQ_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) ) && ( masa_band_mapping != NULL ) ) ||
3272 : EQ_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_PSD_SHD ) || EQ_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_MONO ) )
3273 : {
3274 : /* Synthesize the first direction */
3275 448049 : IF( GT_16( Q_direct_response_hoa, Q29 ) )
3276 : {
3277 0 : Scale_sig32( direct_response_hoa_fx, MAX_OUTPUT_CHANNELS, sub( Q_direct_response_hoa, Q29 ) ); /*Q_direct_response_hoa->q29*/
3278 0 : Q_direct_response_hoa = Q29;
3279 0 : move16();
3280 0 : exp_direct_response_hoa = sub( 31, Q_direct_response_hoa );
3281 : }
3282 448049 : spreadCoherencePanningHoa_fx( azimuth[k], elevation[k], hSpatParamRendCom->spreadCoherence_fx[md_idx][k],
3283 448049 : direct_response_hoa_fx, &Q_direct_response_hoa, num_channels_dir, hDirACRend->hOutSetup.ambisonics_order );
3284 :
3285 448049 : exp_direct_response_hoa = sub( 31, Q_direct_response_hoa );
3286 : /* Synthesize the second direction and combine the gains */
3287 448049 : IF( EQ_16( hSpatParamRendCom->numParametricDirections, 2 ) )
3288 : {
3289 118200 : IF( GT_16( Q_direct_response_dir2, Q29 ) )
3290 : {
3291 0 : Scale_sig32( direct_response_dir2_fx, MAX_OUTPUT_CHANNELS, sub( Q_direct_response_dir2, Q29 ) ); /*Q_direct_response_dir2->q29*/
3292 0 : Q_direct_response_dir2 = Q29;
3293 0 : move16();
3294 0 : exp_direct_response_dir2 = sub( 31, Q_direct_response_dir2 );
3295 : }
3296 118200 : spreadCoherencePanningHoa_fx( azimuth2[k], elevation2[k], hSpatParamRendCom->spreadCoherence2_fx[md_idx][k],
3297 118200 : direct_response_dir2_fx, &Q_direct_response_dir2, num_channels_dir, hDirACRend->hOutSetup.ambisonics_order );
3298 :
3299 118200 : exp_direct_response_hoa = sub( 31, Q_direct_response_hoa );
3300 : /* Combine gains from the two directions */
3301 118200 : totalDirect_fx = L_add( hSpatParamRendCom->energy_ratio1_fx[md_idx][k], hSpatParamRendCom->energy_ratio2_fx[md_idx][k] ); /*q30*/
3302 118200 : IF( totalDirect_fx == 0 )
3303 : {
3304 10 : totalDirect_fx = EPSILON_FIX;
3305 10 : move32();
3306 : }
3307 :
3308 : Word16 var_a, var_b, exp_1, exp_2;
3309 118200 : var_a = BASOP_Util_Divide3232_Scale( hSpatParamRendCom->energy_ratio1_fx[md_idx][k], totalDirect_fx, &exp_1 ); /*15-exp_1*/
3310 118200 : var_b = BASOP_Util_Divide3232_Scale( hSpatParamRendCom->energy_ratio2_fx[md_idx][k], totalDirect_fx, &exp_2 ); /*15-exp_2*/
3311 :
3312 118200 : directRatio_fx[0] = L_deposit_h( var_a ); /*15-exp_1+16*/
3313 118200 : move32();
3314 118200 : directRatio_fx[1] = L_deposit_h( var_b ); /*15-exp_2+16*/
3315 118200 : move32();
3316 :
3317 : Word32 temp_a;
3318 : Word16 exp_arr[MAX_OUTPUT_CHANNELS], exp_temp_a, final_exp;
3319 118200 : set16_fx( exp_arr, exp_direct_response_hoa, MAX_OUTPUT_CHANNELS );
3320 118200 : exp_direct_response_hoa = sub( 31, Q_direct_response_hoa );
3321 :
3322 1023000 : FOR( l = 0; l < num_channels_dir; l++ )
3323 : {
3324 904800 : direct_response_hoa_fx[l] = Mpy_32_32( direct_response_hoa_fx[l], directRatio_fx[0] ); /*Q(Q_direct_response_hoa+31-exp_1-31)*/
3325 904800 : move32();
3326 904800 : exp_arr[l] = add( exp_1, sub( 31, Q_direct_response_hoa ) );
3327 904800 : move16();
3328 904800 : temp_a = Mpy_32_32( directRatio_fx[1], direct_response_dir2_fx[l] ); /*Q(Q_direct_response_dir2+31-exp_2-31)*/
3329 904800 : exp_temp_a = add( exp_2, sub( 31, Q_direct_response_dir2 ) );
3330 904800 : direct_response_hoa_fx[l] = BASOP_Util_Add_Mant32Exp( direct_response_hoa_fx[l], exp_arr[l], temp_a, exp_temp_a, &final_exp ); /*Q(31-final_exp)*/
3331 904800 : move32();
3332 904800 : exp_arr[l] = final_exp;
3333 904800 : move16();
3334 : }
3335 :
3336 118200 : Word16 max_exp = MIN16B;
3337 118200 : move16();
3338 118200 : maximum_fx( exp_arr, MAX_OUTPUT_CHANNELS, &max_exp );
3339 2009400 : FOR( l = 0; l < MAX_OUTPUT_CHANNELS; l++ )
3340 : {
3341 1891200 : direct_response_hoa_fx[l] = L_shr( direct_response_hoa_fx[l], sub( max_exp, exp_arr[l] ) ); /*Q(31-exp_arr[l])->Q(31-max_exp)*/
3342 1891200 : move32();
3343 : }
3344 118200 : exp_direct_response_hoa = max_exp;
3345 118200 : move16();
3346 118200 : Q_direct_response_hoa = sub( 31, max_exp );
3347 : }
3348 :
3349 448049 : IF( hSpatParamRendCom->numIsmDirections > 0 )
3350 : {
3351 : Word16 dir;
3352 : Word32 direct_response_temp_fx[MAX_OUTPUT_CHANNELS];
3353 : Word32 direct_response_ism_fx[MAX_OUTPUT_CHANNELS];
3354 8152 : Word16 exp_direct_response_ism = 0, exp_direct_response_temp;
3355 : Word32 masaDirect_fx;
3356 : Word32 ismDirect_fx;
3357 8152 : move16();
3358 :
3359 8152 : set32_fx( direct_response_ism_fx, 0, num_channels_dir );
3360 :
3361 40760 : FOR( dir = 0; dir < hSpatParamRendCom->numIsmDirections; dir++ )
3362 : {
3363 32608 : IF( hMasaIsm->ism_is_edited[dir] )
3364 : {
3365 0 : ivas_dirac_dec_get_response_fx( hMasaIsm->azimuth_ism_edited[dir], hMasaIsm->elevation_ism_edited[dir], direct_response_temp_fx, hDirACRend->hOutSetup.ambisonics_order, Q29 );
3366 : }
3367 : ELSE
3368 : {
3369 32608 : ivas_dirac_dec_get_response_fx( hMasaIsm->azimuth_ism[dir][md_idx], hMasaIsm->elevation_ism[dir][md_idx], direct_response_temp_fx, hDirACRend->hOutSetup.ambisonics_order, Q29 );
3370 : }
3371 32608 : exp_direct_response_temp = 2;
3372 32608 : move16();
3373 :
3374 32608 : Word32 temp_1 = 0;
3375 32608 : Word16 exp_temp = 0, exp_arr[MAX_OUTPUT_CHANNELS];
3376 32608 : move16();
3377 32608 : move16();
3378 32608 : set16_fx( exp_arr, 0, MAX_OUTPUT_CHANNELS );
3379 348992 : FOR( l = 0; l < num_channels_dir; l++ )
3380 : {
3381 316384 : temp_1 = Mpy_32_32( direct_response_temp_fx[l], hMasaIsm->energy_ratio_ism_fx[dir][md_idx][k] ); // Q28
3382 316384 : direct_response_ism_fx[l] = BASOP_Util_Add_Mant32Exp( direct_response_ism_fx[l], exp_direct_response_ism, temp_1, add( exp_direct_response_temp, 1 ), &exp_temp ); //(31-exp_temp)
3383 316384 : move32();
3384 316384 : exp_arr[l] = exp_temp;
3385 316384 : move16();
3386 : }
3387 32608 : Word16 max_exp = MIN16B;
3388 32608 : move16();
3389 32608 : maximum_fx( exp_arr, num_channels_dir, &max_exp );
3390 348992 : FOR( l = 0; l < num_channels_dir; l++ )
3391 : {
3392 316384 : direct_response_ism_fx[l] = L_shr( direct_response_ism_fx[l], sub( max_exp, exp_arr[l] ) ); /*Q(31- exp_arr[l])->Q(31-max_exp)*/
3393 316384 : move32();
3394 : }
3395 32608 : exp_direct_response_ism = max_exp;
3396 32608 : move16();
3397 : }
3398 : Word16 exp_1, exp_2;
3399 8152 : masaDirect_fx = hSpatParamRendCom->energy_ratio1_fx[md_idx][k]; /*q30*/
3400 8152 : move32();
3401 8152 : if ( masaDirect_fx == 0 )
3402 : {
3403 92 : masaDirect_fx = L_add( masaDirect_fx, EPSILLON_FX ); /*q30*/
3404 : }
3405 8152 : if ( EQ_16( hSpatParamRendCom->numParametricDirections, 2 ) )
3406 : {
3407 0 : masaDirect_fx = L_add( masaDirect_fx, hSpatParamRendCom->energy_ratio2_fx[md_idx][k] ); /*q30*/
3408 : }
3409 :
3410 8152 : ismDirect_fx = hMasaIsm->energy_ratio_ism_fx[0][md_idx][k]; /*q30*/
3411 8152 : move32();
3412 32608 : FOR( dir = 1; dir < hSpatParamRendCom->numIsmDirections; dir++ )
3413 : {
3414 24456 : ismDirect_fx = L_add( ismDirect_fx, hMasaIsm->energy_ratio_ism_fx[dir][md_idx][k] ); /*q30*/
3415 : }
3416 :
3417 8152 : totalDirect_fx = L_add_sat( masaDirect_fx, ismDirect_fx ); /*q30*/ // saturating as 1.0 (Q30) + 1.0 (Q30) is observed
3418 8152 : Word16 var_a = 0, var_b = 0;
3419 8152 : var_a = BASOP_Util_Divide3232_Scale( masaDirect_fx, totalDirect_fx, &exp_1 ); /*Q(15-exp_1)*/
3420 8152 : var_b = BASOP_Util_Divide3232_Scale( ismDirect_fx, totalDirect_fx, &exp_2 ); /*q(15-exp_2)*/
3421 8152 : directRatio_fx[0] = L_deposit_h( var_a ); // Q(31-exp_1)
3422 8152 : move32();
3423 8152 : directRatio_fx[1] = L_deposit_h( var_b ); // Q(31-exp_2)
3424 8152 : move32();
3425 :
3426 : Word32 temp_2, temp_3;
3427 : Word16 exp_arr[MAX_OUTPUT_CHANNELS], exp_temp_3;
3428 8152 : set16_fx( exp_arr, exp_direct_response_hoa, MAX_OUTPUT_CHANNELS );
3429 87248 : FOR( l = 0; l < num_channels_dir; l++ )
3430 : {
3431 79096 : direct_response_hoa_fx[l] = Mpy_32_32( direct_response_hoa_fx[l], directRatio_fx[0] ); /*31-exp_direct_response_hoa+31-exp_1-31*/
3432 79096 : move32();
3433 79096 : exp_arr[l] = add( exp_direct_response_hoa, exp_1 );
3434 79096 : move16();
3435 79096 : temp_2 = Mpy_32_32( directRatio_fx[1], direct_response_ism_fx[l] ); /*31-exp_direct_response_ism+31-exp_2-31*/
3436 79096 : temp_3 = BASOP_Util_Add_Mant32Exp( direct_response_hoa_fx[l], exp_arr[l], temp_2, add( exp_2, exp_direct_response_ism ), &exp_temp_3 ); /*31-exp_temp_3*/
3437 :
3438 79096 : direct_response_hoa_fx[l] = temp_3; /*31-exp_temp_3*/
3439 79096 : move32();
3440 79096 : exp_arr[l] = exp_temp_3;
3441 79096 : move16();
3442 : }
3443 :
3444 8152 : Word16 max_exp = MIN16B;
3445 8152 : move16();
3446 8152 : maximum_fx( exp_arr, num_channels_dir, &max_exp );
3447 87248 : FOR( l = 0; l < num_channels_dir; l++ )
3448 : {
3449 79096 : direct_response_hoa_fx[l] = L_shr( direct_response_hoa_fx[l], sub( max_exp, exp_arr[l] ) ); /*q(31-exp_arr[l])->q(31-max_exp)*/
3450 79096 : move32();
3451 : }
3452 8152 : Q_direct_response_hoa = sub( 31, max_exp );
3453 8152 : exp_direct_response_hoa = max_exp;
3454 8152 : move16();
3455 : }
3456 :
3457 : /* Synthesize surrounding coherence */
3458 448049 : IF( surCohRatio_fx != NULL && surCohRatio_fx[k] > 0 )
3459 : {
3460 : Word32 var_a, var_b;
3461 : Word16 exp_arr[MAX_OUTPUT_CHANNELS], exp;
3462 279197 : set16_fx( exp_arr, exp_direct_response_hoa, MAX_OUTPUT_CHANNELS );
3463 :
3464 1864349 : FOR( l = 1; l < num_channels_dir; l++ )
3465 : {
3466 1585152 : exp = 0;
3467 1585152 : move16();
3468 1585152 : var_a = BASOP_Util_Add_Mant32Exp( ONE_IN_Q30 /*1 Q30*/, 1, L_negate( surCohRatio_fx[k] ), exp_surCohRatio, &exp ); /*q(31-exp)*/
3469 1585152 : var_b = Sqrt32( var_a, &exp ); /*31-exp*/
3470 1585152 : direct_response_hoa_fx[l] = Mpy_32_32( direct_response_hoa_fx[l], var_b ); /*Q_direct_response_hoa+31-exp-31*/
3471 1585152 : move32();
3472 1585152 : exp_arr[l] = add( sub( 31, Q_direct_response_hoa ), exp );
3473 1585152 : move16();
3474 : }
3475 279197 : Word16 max_exp = MIN_16;
3476 279197 : move16();
3477 279197 : maximum_fx( exp_arr, MAX_OUTPUT_CHANNELS, &max_exp );
3478 4746349 : FOR( l = 0; l < MAX_OUTPUT_CHANNELS; l++ )
3479 : {
3480 4467152 : direct_response_hoa_fx[l] = L_shr( direct_response_hoa_fx[l], sub( max_exp, exp_arr[l] ) ); /*q(31-exp_arr[l])->q(31-max_exp)*/
3481 4467152 : move32();
3482 : }
3483 279197 : Q_direct_response_hoa = sub( 31, max_exp );
3484 279197 : exp_direct_response_hoa = max_exp;
3485 279197 : move16();
3486 : }
3487 :
3488 448049 : Q_direct_response_hoa = sub( Q31, exp_direct_response_hoa );
3489 :
3490 448049 : Scale_sig32( direct_response_hoa_fx, MAX_OUTPUT_CHANNELS, sub( Q29, Q_direct_response_hoa ) ); /*Q_direct_response_hoa->q29*/
3491 448049 : direct_response_q = Q29;
3492 448049 : move16();
3493 :
3494 448049 : direct_response_fx = direct_response_hoa_fx;
3495 448049 : IF( NE_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) )
3496 : {
3497 303512 : v_mult_fixed( direct_response_fx, direct_response_fx, direct_response_square_fx, num_channels_dir ); /*Q(2*direct_response_q-31)*/
3498 303512 : direct_response_square_q = sub( add( direct_response_q, direct_response_q ), 31 );
3499 :
3500 303512 : mvr2r_inc_fixed( direct_response_square_fx, 1, &hDirACRend->h_output_synthesis_psd_state.direct_responses_square_fx[k], hSpatParamRendCom->num_freq_bands, num_channels_dir ); /*direct_response_square_q*/
3501 :
3502 303512 : IF( EQ_16( transport_signal_type, MASA_STEREO_SPACED_MICS ) )
3503 : {
3504 30683 : direct_response_fx[0] = ONE_IN_Q29; /*q29*/
3505 30683 : move32();
3506 30683 : test();
3507 30683 : IF( GE_16( k, dipole_freq_range[0] ) && LT_16( k, dipole_freq_range[1] ) )
3508 : {
3509 3897 : direct_response_fx[1] = ONE_IN_Q29; /*q29*/
3510 3897 : move32();
3511 : }
3512 : }
3513 : ELSE
3514 : {
3515 272829 : set32_fx( direct_response_fx, ONE_IN_Q29, hDirACRend->num_protos_ambi ); /*q29*/
3516 : }
3517 : }
3518 :
3519 448049 : mvr2r_inc_fixed( direct_response_fx, 1, &hDirACRend->h_output_synthesis_psd_state.direct_responses_fx[k], hSpatParamRendCom->num_freq_bands, num_channels_dir ); /*q29*/
3520 : }
3521 : ELSE
3522 : {
3523 0 : assert( 0 && "Not supported synthesis method!" );
3524 : }
3525 : }
3526 4914871 : ELSE IF( EQ_16( hDirACRend->panningConf, DIRAC_PANNING_VBAP ) ) /*VBAP*/
3527 : {
3528 : /* Synthesize the first direction */
3529 4914871 : spreadCoherencePanningVbap_fx( azimuth[k], elevation[k], hSpatParamRendCom->spreadCoherence_fx[md_idx][k],
3530 : direct_response_ls_fx, &Q_direct_response_ls, num_channels_dir, hVBAPdata );
3531 4914871 : normalizePanningGains_fx( direct_response_ls_fx, &Q_direct_response_ls, num_channels_dir );
3532 4914871 : exp_direct_response_ls = sub( 31, Q_direct_response_ls );
3533 :
3534 : /* Synthesize the second direction and combine the gains */
3535 4914871 : IF( EQ_16( hSpatParamRendCom->numParametricDirections, 2 ) )
3536 : {
3537 204188 : spreadCoherencePanningVbap_fx( azimuth2[k], elevation2[k], hSpatParamRendCom->spreadCoherence2_fx[md_idx][k], direct_response_dir2_fx, &Q_direct_response_dir2, num_channels_dir, hVBAPdata );
3538 204188 : normalizePanningGains_fx( direct_response_dir2_fx, &Q_direct_response_dir2, num_channels_dir );
3539 :
3540 : /* Combine gains from the two directions */
3541 204188 : Word32 test = L_add( hSpatParamRendCom->energy_ratio1_fx[md_idx][k], hSpatParamRendCom->energy_ratio2_fx[md_idx][k] ); /*q30*/
3542 :
3543 204188 : IF( test == 0 )
3544 : {
3545 1337 : totalDirect_fx = L_add( test, EPSILON_FIX ); // Q30
3546 : }
3547 : ELSE
3548 : {
3549 202851 : totalDirect_fx = test; // q30
3550 202851 : move32();
3551 : }
3552 : Word16 var_1, var_2, exp_1, exp_2;
3553 204188 : var_1 = BASOP_Util_Divide3232_Scale( hSpatParamRendCom->energy_ratio1_fx[md_idx][k], totalDirect_fx, &exp_1 ); // 15-exp_1
3554 204188 : var_2 = BASOP_Util_Divide3232_Scale( hSpatParamRendCom->energy_ratio2_fx[md_idx][k], totalDirect_fx, &exp_2 ); // 15-exp_2
3555 :
3556 204188 : directRatio_fx[0] = L_deposit_h( var_1 ); // 31-exp_1
3557 204188 : move32();
3558 204188 : directRatio_fx[1] = L_deposit_h( var_2 ); // 31-exp_2
3559 204188 : move32();
3560 :
3561 : Word32 var_a;
3562 : Word16 exp_tmp;
3563 204188 : Word16 exp_max = MIN16B, exp_table[MAX_OUTPUT_CHANNELS];
3564 204188 : move16();
3565 204188 : set16_fx( exp_table, exp_direct_response_ls, MAX_OUTPUT_CHANNELS );
3566 :
3567 204188 : exp_direct_response_ls = sub( 31, Q_direct_response_ls );
3568 204188 : exp_direct_response_dir2 = sub( 31, Q_direct_response_dir2 );
3569 :
3570 204188 : Word32 temp = 0;
3571 204188 : move32();
3572 1855504 : FOR( l = 0; l < num_channels_dir; l++ )
3573 : {
3574 1651316 : temp = Mpy_32_32( direct_response_ls_fx[l], directRatio_fx[0] ); // exp_direct_response_ls + exp_1
3575 1651316 : var_a = Mpy_32_32( directRatio_fx[1], direct_response_dir2_fx[l] ); // exp_direct_response_dir2 + exp_2
3576 1651316 : exp_tmp = 0;
3577 1651316 : move16();
3578 1651316 : direct_response_ls_fx[l] = BASOP_Util_Add_Mant32Exp( temp, add( exp_direct_response_ls, exp_1 ), var_a, add( exp_direct_response_dir2, exp_2 ), &exp_tmp ); // q(31-exp_tmp)
3579 1651316 : move32();
3580 1651316 : exp_table[l] = exp_tmp;
3581 1651316 : move16();
3582 : }
3583 :
3584 204188 : maximum_fx( exp_table, MAX_OUTPUT_CHANNELS, &exp_max );
3585 :
3586 3471196 : FOR( i = 0; i < MAX_OUTPUT_CHANNELS; i++ )
3587 : {
3588 3267008 : direct_response_ls_fx[i] = L_shr( direct_response_ls_fx[i], sub( exp_max, exp_table[i] ) ); /*(q(31-exp_table[i])->q(31-exp_max))*/
3589 3267008 : move32();
3590 : }
3591 204188 : Q_direct_response_ls = sub( 31, exp_max );
3592 204188 : exp_direct_response_ls = exp_max;
3593 204188 : move16();
3594 :
3595 204188 : normalizePanningGains_fx( direct_response_ls_fx, &Q_direct_response_ls, num_channels_dir );
3596 204188 : exp_direct_response_ls = sub( 31, Q_direct_response_ls );
3597 : }
3598 :
3599 4914871 : IF( hSpatParamRendCom->numIsmDirections > 0 )
3600 : {
3601 : Word16 dir;
3602 :
3603 : Word32 direct_response_temp_fx[MAX_OUTPUT_CHANNELS];
3604 9195 : set32_fx( direct_response_temp_fx, 0, MAX_OUTPUT_CHANNELS );
3605 9195 : Word16 Q_direct_response_temp = Q31;
3606 9195 : move16();
3607 : Word32 direct_response_ism_fx[MAX_OUTPUT_CHANNELS];
3608 9195 : set32_fx( direct_response_ism_fx, 0, num_channels_dir );
3609 : Word32 masaDirect_fx;
3610 : Word32 ismDirect_fx;
3611 :
3612 35695 : FOR( dir = 0; dir < hSpatParamRendCom->numIsmDirections; dir++ )
3613 : {
3614 26500 : IF( hMasaIsm->ism_is_edited[dir] )
3615 : {
3616 0 : vbap_determine_gains_fx( hVBAPdata, direct_response_temp_fx, hMasaIsm->azimuth_ism_edited[dir], hMasaIsm->elevation_ism_edited[dir], 1 );
3617 : }
3618 : ELSE
3619 : {
3620 26500 : vbap_determine_gains_fx( hVBAPdata, direct_response_temp_fx, hMasaIsm->azimuth_ism[dir][md_idx], hMasaIsm->elevation_ism[dir][md_idx], 1 );
3621 : }
3622 26500 : Word32 tmp = 0;
3623 26500 : move32();
3624 : Word16 Q_arr[MAX_OUTPUT_CHANNELS], exp_tmp;
3625 245264 : FOR( l = 0; l < num_channels_dir; l++ )
3626 : {
3627 218764 : tmp = Mpy_32_32( direct_response_temp_fx[l], hMasaIsm->energy_ratio_ism_fx[dir][md_idx][k] ); // Q30 * 2 - 31
3628 218764 : direct_response_ism_fx[l] = BASOP_Util_Add_Mant32Exp( direct_response_ism_fx[l], 0, tmp, 31 - ( 60 - 31 ), &exp_tmp ); // q(31-exp_tmp)
3629 218764 : move32();
3630 218764 : Q_arr[l] = sub( 31, exp_tmp );
3631 218764 : move16();
3632 : }
3633 26500 : Word16 Q_min = MAX16B;
3634 26500 : move32();
3635 26500 : minimum_fx( Q_arr, num_channels_dir, &Q_min );
3636 245264 : FOR( i = 0; i < num_channels_dir; i++ )
3637 : {
3638 218764 : direct_response_ism_fx[i] = L_shr( direct_response_ism_fx[i], sub( Q_arr[i], Q_min ) ); // Q_arr[i]->Q_min
3639 218764 : move32();
3640 : }
3641 26500 : Q_direct_response_temp = Q_min;
3642 26500 : move16();
3643 26500 : normalizePanningGains_fx( direct_response_ism_fx, &Q_direct_response_temp, num_channels_dir );
3644 : }
3645 :
3646 : Word16 exp_1, exp_2;
3647 9195 : masaDirect_fx = hSpatParamRendCom->energy_ratio1_fx[md_idx][k]; // q30
3648 9195 : move32();
3649 9195 : IF( masaDirect_fx == 0 )
3650 : {
3651 39 : masaDirect_fx = L_add( masaDirect_fx, EPSILLON_FX ); // q30
3652 : }
3653 9195 : IF( EQ_32( hSpatParamRendCom->numParametricDirections, 2 ) )
3654 : {
3655 3000 : masaDirect_fx = L_add( masaDirect_fx, hSpatParamRendCom->energy_ratio2_fx[md_idx][k] ); // q30
3656 : }
3657 :
3658 9195 : ismDirect_fx = hMasaIsm->energy_ratio_ism_fx[0][md_idx][k]; // q30
3659 9195 : move32();
3660 26500 : FOR( dir = 1; dir < hSpatParamRendCom->numIsmDirections; dir++ )
3661 : {
3662 17305 : ismDirect_fx = L_add( ismDirect_fx, hMasaIsm->energy_ratio_ism_fx[dir][md_idx][k] ); // q30
3663 : }
3664 :
3665 9195 : totalDirect_fx = L_add_sat( masaDirect_fx, ismDirect_fx ); // q30 // saturating as 1.0 (Q30) + 1.0 (Q30) is observed
3666 : Word16 var_a, var_b;
3667 9195 : var_a = BASOP_Util_Divide3232_Scale( masaDirect_fx, totalDirect_fx, &exp_1 ); // 15-exp_1
3668 9195 : var_b = BASOP_Util_Divide3232_Scale( ismDirect_fx, totalDirect_fx, &exp_2 ); // 15- exp_2
3669 9195 : directRatio_fx[0] = L_deposit_h( var_a ); // 31- exp_1
3670 9195 : move32();
3671 9195 : directRatio_fx[1] = L_deposit_h( var_b ); // 31 - exp_2
3672 9195 : move32();
3673 :
3674 : Word32 temp_2, temp_3;
3675 : Word16 exp_arr[MAX_OUTPUT_CHANNELS], exp_temp_3;
3676 9195 : set16_fx( exp_arr, exp_direct_response_ls, MAX_OUTPUT_CHANNELS );
3677 84648 : FOR( l = 0; l < num_channels_dir; l++ )
3678 : {
3679 75453 : direct_response_ls_fx[l] = Mpy_32_32( direct_response_ls_fx[l], directRatio_fx[0] ); // q(31-exp_direct_response_ls+31-exp_1-31)
3680 75453 : move32();
3681 75453 : exp_arr[l] = add( exp_direct_response_ls, exp_1 );
3682 75453 : move16();
3683 75453 : temp_2 = Mpy_32_32( directRatio_fx[1], direct_response_ism_fx[l] ); // q(Q_direct_response_temp+31-exp_2-31)
3684 75453 : temp_3 = BASOP_Util_Add_Mant32Exp( direct_response_ls_fx[l], exp_arr[l], temp_2, add( exp_2, sub( 31, Q_direct_response_temp ) ), &exp_temp_3 ); // 31-exp_temp_3
3685 :
3686 75453 : direct_response_ls_fx[l] = temp_3; // 31-exp_temp_3
3687 75453 : move32();
3688 75453 : exp_arr[l] = exp_temp_3;
3689 75453 : move16();
3690 : }
3691 :
3692 9195 : Word16 max_exp = MIN16B;
3693 9195 : move16();
3694 9195 : maximum_fx( exp_arr, num_channels_dir, &max_exp );
3695 84648 : FOR( l = 0; l < num_channels_dir; l++ )
3696 : {
3697 75453 : direct_response_ls_fx[l] = L_shr( direct_response_ls_fx[l], sub( max_exp, exp_arr[l] ) ); /*q(31-exp_arr[l])->q(31-max_exp)*/
3698 75453 : move16();
3699 : }
3700 9195 : Q_direct_response_ls = sub( 31, max_exp );
3701 9195 : exp_direct_response_ls = max_exp;
3702 9195 : move16();
3703 :
3704 9195 : normalizePanningGains_fx( direct_response_ls_fx, &Q_direct_response_ls, num_channels_dir );
3705 9195 : exp_direct_response_ls = sub( 31, Q_direct_response_ls );
3706 : }
3707 :
3708 : /* Synthesize surrounding coherence */
3709 4914871 : test();
3710 4914871 : IF( surCohRatio_fx != NULL && surCohRatio_fx[k] > 0 )
3711 : {
3712 : Word16 num_channels_surrCoh;
3713 :
3714 349421 : num_channels_surrCoh = num_channels_dir;
3715 349421 : move16();
3716 349421 : num_channels_surrCoh = sub( num_channels_surrCoh, hDirACRend->num_ele_spk_no_diffuse_rendering );
3717 :
3718 : Word32 temp, final;
3719 : Word16 exp_temp, exp_temp_a, temp_a, final_exp;
3720 349421 : Word16 exp_arr[MAX_OUTPUT_CHANNELS], max_exp = MIN16B;
3721 349421 : move16();
3722 349421 : set16_fx( exp_arr, exp_direct_response_ls, MAX_OUTPUT_CHANNELS );
3723 2981906 : FOR( l = 0; l < num_channels_dir; l++ )
3724 : {
3725 2632485 : exp_temp = 0;
3726 2632485 : move16();
3727 2632485 : temp = BASOP_Util_Add_Mant32Exp( ONE_IN_Q30 /*1 Q30*/, 1, L_negate( surCohRatio_fx[k] ), exp_surCohRatio, &exp_temp ); // q(31-exp_temp)
3728 2632485 : temp = Sqrt32( temp, &exp_temp ); // q(31-exp_temp)
3729 2632485 : direct_response_ls_fx[l] = Mpy_32_32( direct_response_ls_fx[l], temp ); // Q31-(exp_direct_response_ls + exp_temp)
3730 2632485 : move32();
3731 :
3732 2632485 : exp_arr[l] = add( exp_direct_response_ls, exp_temp );
3733 2632485 : move16();
3734 2632485 : IF( hDirACRend->diffuse_response_function_fx[l] > 0 )
3735 : {
3736 2621285 : exp_temp_a = 0;
3737 2621285 : move16();
3738 2621285 : temp_a = BASOP_Util_Divide3216_Scale( surCohRatio_fx[k], num_channels_surrCoh, &exp_temp_a ); /*15-(exp_temp_a+exp_surCohRatio-15)*/
3739 2621285 : exp_temp_a = add( exp_temp_a, sub( exp_surCohRatio, 15 ) );
3740 2621285 : temp_a = Sqrt16( temp_a, &exp_temp_a ); /*15-temp_a*/
3741 2621285 : final_exp = 0;
3742 2621285 : move16();
3743 2621285 : final = BASOP_Util_Add_Mant32Exp( direct_response_ls_fx[l], exp_arr[l], L_deposit_h( temp_a ), exp_temp_a, &final_exp ); /*31-final_exp*/
3744 2621285 : direct_response_ls_fx[l] = final; /*31-final_exp*/
3745 2621285 : move32();
3746 2621285 : exp_arr[l] = final_exp;
3747 2621285 : move16();
3748 : }
3749 : }
3750 :
3751 349421 : max_exp = MIN16B; /*Q0*/
3752 349421 : move16();
3753 349421 : maximum_fx( exp_arr, MAX_OUTPUT_CHANNELS, &max_exp );
3754 5940157 : FOR( l = 0; l < MAX_OUTPUT_CHANNELS; l++ )
3755 : {
3756 5590736 : direct_response_ls_fx[l] = L_shr( direct_response_ls_fx[l], sub( max_exp, exp_arr[l] ) ); /*Q(31-exp_arr[l])->Q(31-max_exp)*/
3757 5590736 : move32();
3758 : }
3759 :
3760 349421 : Q_direct_response_ls = sub( 31, max_exp );
3761 349421 : exp_direct_response_ls = max_exp;
3762 349421 : move16();
3763 : }
3764 :
3765 4914871 : normalizePanningGains_fx( direct_response_ls_fx, &Q_direct_response_ls, num_channels_dir );
3766 4914871 : exp_direct_response_ls = sub( 31, Q_direct_response_ls );
3767 :
3768 4914871 : Scale_sig32( direct_response_ls_fx, MAX_OUTPUT_CHANNELS, sub( Q29, Q_direct_response_ls ) ); /*Q_direct_response_ls->Q29*/
3769 4914871 : direct_response_q = Q29;
3770 4914871 : move16();
3771 :
3772 : /* Set computed gains */
3773 4914871 : direct_response_fx = direct_response_ls_fx;
3774 4914871 : v_mult_fixed( direct_response_fx, direct_response_fx, direct_response_square_fx, num_channels_dir ); /*2*direct_response_q-31*/
3775 4914871 : direct_response_square_q = sub( add( direct_response_q, direct_response_q ), 31 );
3776 :
3777 4914871 : mvr2r_inc_fixed( direct_response_square_fx, 1, &hDirACRend->h_output_synthesis_psd_state.direct_responses_square_fx[k], hSpatParamRendCom->num_freq_bands, num_channels_dir ); /*direct_response_square_q*/
3778 4914871 : mvr2r_inc_fixed( direct_response_fx, 1, &hDirACRend->h_output_synthesis_psd_state.direct_responses_fx[k], hSpatParamRendCom->num_freq_bands, num_channels_dir ); /*direct_response_q*/
3779 : }
3780 : ELSE
3781 : {
3782 0 : assert( 0 && "Not supported panning method!" );
3783 : }
3784 : }
3785 : }
3786 :
3787 1050811 : hDirACRend->h_output_synthesis_psd_state.direct_responses_q = direct_response_q;
3788 1050811 : move16();
3789 1050811 : hDirACRend->h_output_synthesis_psd_state.direct_responses_square_q = direct_response_square_q;
3790 1050811 : move16();
3791 :
3792 1050811 : return;
3793 : }
3794 :
3795 :
3796 : /*-------------------------------------------------------------------------
3797 : * ivas_dirac_dec_compute_gain_factors()
3798 : *
3799 : *
3800 : *------------------------------------------------------------------------*/
3801 :
3802 688224 : void ivas_dirac_dec_compute_gain_factors_fx(
3803 : const Word16 num_freq_bands,
3804 : const Word32 *diffuseness_fx, /*i:q30*/
3805 : Word32 *direct_gain_factor, /*o:exponent is max_exp_direct*/
3806 : Word32 *diffuse_gain_factor, /*o:exponent is max_exp_diffusion*/
3807 : Word16 *max_exp_direct_fx,
3808 : Word16 *max_exp_diffusion )
3809 : {
3810 : Word16 i;
3811 : Word16 exp1, exp2;
3812 : Word16 exp_diffuse_gain_factor[60], exp_direct_gain_factor[60]; /*exp buffers*/
3813 :
3814 35591584 : FOR( i = 0; i < num_freq_bands; i++ )
3815 : {
3816 34903360 : exp1 = 1;
3817 34903360 : move16();
3818 34903360 : exp2 = 1;
3819 34903360 : move16();
3820 34903360 : direct_gain_factor[i] = Sqrt32( L_sub( ONE_IN_Q30 /*1 Q30*/, diffuseness_fx[i] ), &exp1 ); /*31-exp1*/
3821 34903360 : move32();
3822 34903360 : diffuse_gain_factor[i] = Sqrt32( diffuseness_fx[i], &exp2 ); /*31-exp2*/
3823 34903360 : move32();
3824 34903360 : exp_direct_gain_factor[i] = exp1;
3825 34903360 : move16();
3826 34903360 : exp_diffuse_gain_factor[i] = exp2;
3827 34903360 : move16();
3828 : }
3829 :
3830 : /*make common exp for both buffers*/
3831 688224 : Word16 max_exp_direct = MIN16B; /*Q0*/
3832 688224 : move16();
3833 688224 : Word16 max_exp_diffuse = MIN16B; /*Q0*/
3834 688224 : move16();
3835 35591584 : FOR( i = 0; i < num_freq_bands; i++ )
3836 : {
3837 34903360 : max_exp_direct = s_max( max_exp_direct, exp_direct_gain_factor[i] );
3838 34903360 : max_exp_diffuse = s_max( max_exp_diffuse, exp_diffuse_gain_factor[i] );
3839 : }
3840 :
3841 688224 : *max_exp_direct_fx = max_exp_direct;
3842 688224 : move16();
3843 688224 : *max_exp_diffusion = max_exp_diffuse;
3844 688224 : move16();
3845 :
3846 35591584 : FOR( i = 0; i < num_freq_bands; i++ )
3847 : {
3848 34903360 : direct_gain_factor[i] = L_shr( direct_gain_factor[i], sub( max_exp_direct, exp_direct_gain_factor[i] ) ); /*Q(31-max_exp_direct)*/
3849 34903360 : move32();
3850 34903360 : diffuse_gain_factor[i] = L_shr( diffuse_gain_factor[i], sub( max_exp_diffuse, exp_diffuse_gain_factor[i] ) ); /*Q(31-max_exp_diffuse)*/
3851 34903360 : move32();
3852 : }
3853 :
3854 :
3855 688224 : return;
3856 : }
3857 :
3858 :
3859 : /*-------------------------------------------------------------------------
3860 : * ivas_dirac_dec_compute_power_factors()
3861 : *
3862 : *
3863 : *------------------------------------------------------------------------*/
3864 :
3865 149963 : void ivas_dirac_dec_compute_power_factors_fx(
3866 : const Word16 num_freq_bands,
3867 : const Word32 *diffuseness_fx, // Q3O
3868 : const Word16 max_band_decorr,
3869 : Word32 *direct_power_factor, /*input is q30 and ouput is q29*/
3870 : Word32 *diffuse_power_factor /*input is q30 and ouput is q29*/ )
3871 : {
3872 : Word16 i;
3873 :
3874 149963 : v_multc_fixed( diffuseness_fx, L_negate( ( ONE_IN_Q31 ) ), direct_power_factor, num_freq_bands ); // Q30
3875 :
3876 149963 : v_addc_fixed( direct_power_factor, ONE_IN_Q30, direct_power_factor, num_freq_bands ); // Q30
3877 :
3878 149963 : Copy32( diffuseness_fx, diffuse_power_factor, num_freq_bands ); // Q30
3879 :
3880 149963 : v_mult_fixed( &direct_power_factor[max_band_decorr], &direct_power_factor[max_band_decorr], &direct_power_factor[max_band_decorr], num_freq_bands - max_band_decorr ); // Q29
3881 :
3882 149963 : v_mult_fixed( &diffuse_power_factor[max_band_decorr], &diffuse_power_factor[max_band_decorr], &diffuse_power_factor[max_band_decorr], num_freq_bands - max_band_decorr ); // Q29
3883 :
3884 :
3885 1178198 : FOR( i = 0; i < max_band_decorr; i++ )
3886 : {
3887 1028235 : direct_power_factor[i] = L_shr( direct_power_factor[i], 1 ); // Q29
3888 1028235 : move32();
3889 1028235 : diffuse_power_factor[i] = L_shr( diffuse_power_factor[i], 1 ); // Q29
3890 1028235 : move32();
3891 : }
3892 149963 : return;
3893 : }
3894 :
3895 :
3896 : /*-------------------------------------------------------------------------
3897 : * ivas_lfe_synth_with_filters()
3898 : *
3899 : *
3900 : *------------------------------------------------------------------------*/
3901 150 : void ivas_lfe_synth_with_filters_fx(
3902 : MCMASA_LFE_SYNTH_DATA_HANDLE hMasaLfeSynth, /* i/o: LFE synthesis structure for McMASA */
3903 : Word32 *data_fx[], /* o : output signals (Q11) */
3904 : const Word16 output_frame, /* i : output frame length per channel */
3905 : const Word16 separateChannelIndex, /* i : separate channel index */
3906 : const Word16 lfeChannelIndex /* i : LFE channel index */
3907 : )
3908 : {
3909 : Word16 lowpassCoef_fx;
3910 : Word16 lowpassCoef_fx_exp;
3911 : Word16 i, j;
3912 : Word32 lowPassSignal_fx[L_FRAME48k];
3913 : Word32 highPassSignal_fx[L_FRAME48k];
3914 : Word16 slot_index;
3915 : Word16 subframe_index;
3916 : Word16 slotSize;
3917 : Word32 transportEne_fx, targetEneLfe_fx, targetEneTrans_fx;
3918 : Word16 mrange[2];
3919 : Word16 lfeGain_fx;
3920 : Word16 lfeGain_fx_exp;
3921 : Word16 transportGain_fx;
3922 : Word16 transportGain_fx_exp;
3923 : Word16 delay;
3924 :
3925 : /* Delay the separated channel to sync the LFE synthesis with the DirAC rendering */
3926 150 : delay = hMasaLfeSynth->delayBuffer_syncDirAC_size;
3927 150 : move16();
3928 150 : delay_signal32_fx( data_fx[separateChannelIndex], output_frame, hMasaLfeSynth->delayBuffer_syncDirAC_fx, delay ); /*q11*/
3929 :
3930 : /* Filterbank for dividing the separated channel to LFE frequencies and higher frequencies */
3931 150 : lowpassCoef_fx_exp = 15;
3932 150 : move16();
3933 150 : lowpassCoef_fx = Inv16( hMasaLfeSynth->ringBufferSize, &lowpassCoef_fx_exp ); /*15-lowpassCoef_fx_exp*/
3934 144150 : FOR( i = 0; i < output_frame; i++ )
3935 : {
3936 144000 : hMasaLfeSynth->lowpassSum_fx = L_add( hMasaLfeSynth->lowpassSum_fx, L_shl( Mpy_32_16_1( L_sub( data_fx[separateChannelIndex][i], hMasaLfeSynth->lfeSynthRingBuffer_fx[hMasaLfeSynth->ringBufferLoPointer] ), lowpassCoef_fx ), lowpassCoef_fx_exp ) ); // Q11
3937 144000 : lowPassSignal_fx[i] = hMasaLfeSynth->lowpassSum_fx; // Q11
3938 144000 : move32();
3939 144000 : highPassSignal_fx[i] = L_sub( hMasaLfeSynth->lfeSynthRingBuffer_fx[hMasaLfeSynth->ringBufferHiPointer], lowPassSignal_fx[i] ); // Q11
3940 144000 : move32();
3941 144000 : hMasaLfeSynth->lfeSynthRingBuffer_fx[hMasaLfeSynth->ringBufferLoPointer] = data_fx[separateChannelIndex][i]; // Q11
3942 144000 : move32();
3943 :
3944 144000 : hMasaLfeSynth->ringBufferLoPointer = sub( hMasaLfeSynth->ringBufferLoPointer, 1 );
3945 144000 : move16();
3946 144000 : IF( hMasaLfeSynth->ringBufferLoPointer < 0 )
3947 : {
3948 600 : hMasaLfeSynth->ringBufferLoPointer = sub( hMasaLfeSynth->ringBufferSize, 1 );
3949 600 : move16();
3950 : }
3951 :
3952 144000 : hMasaLfeSynth->ringBufferHiPointer = sub( hMasaLfeSynth->ringBufferHiPointer, 1 );
3953 144000 : move16();
3954 144000 : IF( hMasaLfeSynth->ringBufferHiPointer < 0 )
3955 : {
3956 600 : hMasaLfeSynth->ringBufferHiPointer = sub( hMasaLfeSynth->ringBufferSize, 1 );
3957 600 : move16();
3958 : }
3959 : }
3960 :
3961 : /* Synthesize the LFE signal */
3962 150 : slotSize = shr_r( output_frame, 4 ); // output_frame / CLDFB_NO_COL_MAX
3963 2550 : FOR( slot_index = 0; slot_index < CLDFB_NO_COL_MAX; slot_index++ )
3964 : {
3965 2400 : subframe_index = shr( slot_index, 4 );
3966 :
3967 2400 : mrange[0] = i_mult( slot_index, slotSize );
3968 2400 : move16();
3969 2400 : mrange[1] = i_mult( add( slot_index, 1 ), slotSize );
3970 2400 : move16();
3971 :
3972 2400 : transportEne_fx = 0;
3973 2400 : move32();
3974 2400 : Word64 W_tmp = 0;
3975 2400 : move64();
3976 146400 : FOR( i = mrange[0]; i < mrange[1]; i++ )
3977 : {
3978 144000 : W_tmp = W_add( W_tmp, W_mult0_32_32( lowPassSignal_fx[i], lowPassSignal_fx[i] ) ); // Q22
3979 : }
3980 :
3981 2400 : Word16 tmp_shift = W_norm( W_tmp );
3982 :
3983 2400 : W_tmp = W_shl( W_tmp, tmp_shift ); /*Q22+tmp_shift*/
3984 :
3985 2400 : Word16 tmp_q = sub( add( Q22, tmp_shift ), 32 );
3986 : Word16 tmp_exp;
3987 :
3988 2400 : transportEne_fx = W_extract_h( W_tmp ); /* Q22 + tmp_shift - 32 */
3989 2400 : targetEneLfe_fx = W_extract_l( W_shr( W_mult0_32_32( transportEne_fx, hMasaLfeSynth->lfeToTotalEnergyRatio_fx[subframe_index] ), Q14 ) ); /* Q22 + tmp_shift - 32 */
3990 2400 : targetEneTrans_fx = W_extract_l( W_shr( W_mult0_32_32( transportEne_fx, s_max( sub( ONE_IN_Q14, hMasaLfeSynth->lfeToTotalEnergyRatio_fx[subframe_index] ), 168 ) ), Q14 ) ); /* Q22 + tmp_shift - 32 */
3991 :
3992 2400 : hMasaLfeSynth->transportEneSmooth_fx = Mpy_32_16_1( hMasaLfeSynth->transportEneSmooth_fx, MCMASA_LFE_SYNTH_ALPHA_Q15 ); /* transportEneSmooth_q */
3993 2400 : move32();
3994 2400 : hMasaLfeSynth->targetEneLfeSmooth_fx = Mpy_32_16_1( hMasaLfeSynth->targetEneLfeSmooth_fx, MCMASA_LFE_SYNTH_ALPHA_Q15 ); /* targetEneLfeSmooth_q */
3995 2400 : move32();
3996 2400 : hMasaLfeSynth->targetEneTransSmooth_fx = Mpy_32_16_1( hMasaLfeSynth->targetEneTransSmooth_fx, MCMASA_LFE_SYNTH_ALPHA_Q15 ); /* targetEneTransSmooth_q */
3997 2400 : move32();
3998 :
3999 2400 : hMasaLfeSynth->transportEneSmooth_fx = BASOP_Util_Add_Mant32Exp( hMasaLfeSynth->transportEneSmooth_fx, sub( Q31, hMasaLfeSynth->transportEneSmooth_q ), transportEne_fx, sub( Q31, tmp_q ), &tmp_exp ); /* Q31 - tmp_exp */
4000 2400 : move32();
4001 2400 : hMasaLfeSynth->transportEneSmooth_q = sub( Q31, tmp_exp );
4002 2400 : move16();
4003 2400 : hMasaLfeSynth->targetEneLfeSmooth_fx = BASOP_Util_Add_Mant32Exp( hMasaLfeSynth->targetEneLfeSmooth_fx, sub( Q31, hMasaLfeSynth->targetEneLfeSmooth_q ), targetEneLfe_fx, sub( Q31, tmp_q ), &tmp_exp ); /* Q31 - tmp_exp */
4004 2400 : move32();
4005 2400 : hMasaLfeSynth->targetEneLfeSmooth_q = sub( Q31, tmp_exp );
4006 2400 : move16();
4007 2400 : hMasaLfeSynth->targetEneTransSmooth_fx = BASOP_Util_Add_Mant32Exp( hMasaLfeSynth->targetEneTransSmooth_fx, sub( Q31, hMasaLfeSynth->targetEneTransSmooth_q ), targetEneTrans_fx, sub( Q31, tmp_q ), &tmp_exp ); /* Q31 - tmp_exp */
4008 2400 : move32();
4009 2400 : hMasaLfeSynth->targetEneTransSmooth_q = sub( Q31, tmp_exp );
4010 2400 : move16();
4011 :
4012 2400 : IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( hMasaLfeSynth->targetEneLfeSmooth_fx, sub( Q31, hMasaLfeSynth->targetEneLfeSmooth_q ), /*EPSILON + */ hMasaLfeSynth->transportEneSmooth_fx, sub( Q31, hMasaLfeSynth->transportEneSmooth_q ) ), 1 ) )
4013 : {
4014 0 : lfeGain_fx = MAX_16; /* 1.0 in q15*/
4015 0 : move16();
4016 : }
4017 : ELSE
4018 : {
4019 2400 : lfeGain_fx = extract_h( BASOP_Util_Divide3232_Scale_newton( hMasaLfeSynth->targetEneLfeSmooth_fx, L_add( EPSILON_FX, hMasaLfeSynth->transportEneSmooth_fx ), &lfeGain_fx_exp ) ); /*Q(31-(lfeGain_fx_exp+hMasaLfeSynth->transportEneSmooth_q-hMasaLfeSynth->targetEneLfeSmooth_q))-16*/
4020 2400 : lfeGain_fx_exp = add( sub( hMasaLfeSynth->transportEneSmooth_q, hMasaLfeSynth->targetEneLfeSmooth_q ), lfeGain_fx_exp );
4021 2400 : lfeGain_fx = Sqrt16( lfeGain_fx, &lfeGain_fx_exp ); // Q15-lfeGain_fx_exp
4022 2400 : lfeGain_fx = shl_r( lfeGain_fx, lfeGain_fx_exp ); // Q15
4023 : }
4024 2400 : IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( hMasaLfeSynth->targetEneTransSmooth_fx, sub( Q31, hMasaLfeSynth->targetEneTransSmooth_q ), /*EPSILON + */ hMasaLfeSynth->transportEneSmooth_fx, sub( Q31, hMasaLfeSynth->transportEneSmooth_q ) ), 1 ) )
4025 : {
4026 0 : transportGain_fx = MAX_16; // q15
4027 0 : move16();
4028 : }
4029 : ELSE
4030 : {
4031 : Flag overFlow;
4032 2400 : transportGain_fx = BASOP_Util_Divide3232_Scale( hMasaLfeSynth->targetEneTransSmooth_fx, /*EPSILON + */ hMasaLfeSynth->transportEneSmooth_fx, &transportGain_fx_exp ); /*Q=15-(transportGain_fx_exp+hMasaLfeSynth->transportEneSmooth_q-hMasaLfeSynth->targetEneTransSmooth_q)*/
4033 2400 : transportGain_fx_exp = add( sub( hMasaLfeSynth->transportEneSmooth_q, hMasaLfeSynth->targetEneTransSmooth_q ), transportGain_fx_exp );
4034 2400 : transportGain_fx = Sqrt16( transportGain_fx, &transportGain_fx_exp ); // q15-transportGain_fx_exp
4035 2400 : transportGain_fx = shl_ro( transportGain_fx, transportGain_fx_exp, &overFlow ); // Q15
4036 : }
4037 2400 : j = 0;
4038 2400 : move16();
4039 146400 : FOR( i = mrange[0]; i < mrange[1]; i++ )
4040 : {
4041 144000 : Word32 L_tmp1 = L_mult( transportGain_fx, hMasaLfeSynth->interpolator_fx[j] ); // Q31
4042 144000 : Word32 L_tmp2 = L_mult( hMasaLfeSynth->transportGainPrev_fx, sub( MAX_16, hMasaLfeSynth->interpolator_fx[j] ) ); // Q31
4043 144000 : data_fx[separateChannelIndex][i] = L_add( Mpy_32_32( L_add( L_tmp1, L_tmp2 ), lowPassSignal_fx[i] ), highPassSignal_fx[i] ); /*q31+q11-q31->q11*/
4044 144000 : move32();
4045 144000 : Word32 L_tmp3 = L_mult( lfeGain_fx, hMasaLfeSynth->interpolator_fx[j] ); // Q31
4046 144000 : Word32 L_tmp4 = L_mult( hMasaLfeSynth->lfeGainPrev_fx, sub( MAX_16, hMasaLfeSynth->interpolator_fx[j] ) ); /*q31*/
4047 144000 : data_fx[lfeChannelIndex][i] = Mpy_32_32( L_add( L_tmp3, L_tmp4 ), lowPassSignal_fx[i] ); /*q31+q11-q31->q11*/
4048 144000 : move32();
4049 144000 : j = add( j, 1 );
4050 : }
4051 :
4052 2400 : hMasaLfeSynth->lfeGainPrev_fx = lfeGain_fx; /*q15*/
4053 2400 : move16();
4054 2400 : hMasaLfeSynth->transportGainPrev_fx = transportGain_fx; /*q15*/
4055 2400 : move16();
4056 : }
4057 :
4058 : /* Lowpass filter for removing remaining mid and high frequencies from the LFE signal */
4059 150 : lowpassCoef_fx_exp = 15;
4060 150 : move16();
4061 150 : lowpassCoef_fx = Inv16( hMasaLfeSynth->ringBufferSize2, &lowpassCoef_fx_exp ); // q15-lowpassCoef_fx_exp
4062 144150 : FOR( i = 0; i < output_frame; i++ )
4063 : {
4064 144000 : hMasaLfeSynth->lowpassSum2_fx = L_add( hMasaLfeSynth->lowpassSum2_fx,
4065 144000 : L_shl_r( L_sub( Mpy_32_16_1( data_fx[lfeChannelIndex][i], lowpassCoef_fx ),
4066 144000 : Mpy_32_16_1( hMasaLfeSynth->lfeSynthRingBuffer2_fx[hMasaLfeSynth->ringBufferLoPointer2], lowpassCoef_fx ) ),
4067 : lowpassCoef_fx_exp ) ); /*q11+15-lowpassCoef_fx_exp-15+lowpassCoef_fx_exp->q11*/
4068 144000 : move32();
4069 144000 : hMasaLfeSynth->lfeSynthRingBuffer2_fx[hMasaLfeSynth->ringBufferLoPointer2] = data_fx[lfeChannelIndex][i]; /*q11*/
4070 144000 : move32();
4071 :
4072 144000 : hMasaLfeSynth->ringBufferLoPointer2 = sub( hMasaLfeSynth->ringBufferLoPointer2, 1 );
4073 144000 : move16();
4074 144000 : IF( hMasaLfeSynth->ringBufferLoPointer2 < 0 )
4075 : {
4076 1200 : hMasaLfeSynth->ringBufferLoPointer2 = sub( hMasaLfeSynth->ringBufferSize2, 1 );
4077 1200 : move16();
4078 : }
4079 :
4080 144000 : data_fx[lfeChannelIndex][i] = hMasaLfeSynth->lowpassSum2_fx; /*q11*/
4081 144000 : move32();
4082 : }
4083 :
4084 : /* Delay the separated channel to match the delay of the lowpass filter */
4085 150 : delay = hMasaLfeSynth->delayBuffer_syncLp_size;
4086 150 : move16();
4087 150 : delay_signal32_fx( data_fx[separateChannelIndex], output_frame, hMasaLfeSynth->delayBuffer_syncLp_fx, delay ); /*q11*/
4088 :
4089 150 : return;
4090 : }
4091 :
4092 : /*-------------------------------------------------------------------------
4093 : * Local functions
4094 : *------------------------------------------------------------------------*/
4095 :
4096 72000 : static void computeTargetPSDs_direct_fx(
4097 : const Word16 num_channels,
4098 : const Word16 num_freq_bands,
4099 : const Word32 *direct_power_factor, /*q31*/
4100 : const Word32 *reference_power, /*q_reference_power*/
4101 : const Word16 *q_reference_power,
4102 : const Word32 *direct_responses, /*q31*/
4103 : const Word32 *direct_responses_square, /*q31*/
4104 : Word32 *cy_auto_dir_smooth, /*q_cy_auto_dir_smooth*/
4105 : Word16 *q_cy_auto_dir_smooth,
4106 : Word32 *cy_cross_dir_smooth, /*q_cy_cross_dir_smooth*/
4107 : Word16 *q_cy_cross_dir_smooth )
4108 : {
4109 : Word16 ch_idx, cur_idx;
4110 :
4111 : /* segment auxiliary buffer */
4112 : Word32 direct_power[CLDFB_NO_CHANNELS_MAX]; /* size: num_freq_bands. */
4113 : Word32 aux_buffer_res[CLDFB_NO_CHANNELS_MAX]; /* size: num_freq_bands. */
4114 :
4115 : /* estimate direct and diffuse power */
4116 72000 : v_mult_fixed( direct_power_factor, reference_power, direct_power, num_freq_bands ); /* Q31 + Q(q_reference_power) - Q31 = Q(q_reference_power) */
4117 :
4118 : #ifdef FIX_867_CLDFB_NRG_SCALE
4119 72000 : Word16 common1_q = s_min( *q_cy_auto_dir_smooth, s_min( q_reference_power[0], q_reference_power[1] ) );
4120 72000 : Word16 common2_q = s_min( *q_cy_cross_dir_smooth, s_min( q_reference_power[0], q_reference_power[1] ) );
4121 : #else
4122 : Word16 common1_q = s_min( *q_cy_auto_dir_smooth, *q_reference_power );
4123 : Word16 common2_q = s_min( *q_cy_cross_dir_smooth, *q_reference_power );
4124 : #endif
4125 :
4126 : /* compute target auto and cross PSDs of current frame (smoothed) */
4127 784000 : FOR( ch_idx = 0; ch_idx < num_channels; ++ch_idx )
4128 : {
4129 712000 : cur_idx = imult1616( ch_idx, num_freq_bands );
4130 :
4131 712000 : v_mult_fixed( direct_power, &direct_responses_square[cur_idx], aux_buffer_res, num_freq_bands ); /* Q31 + Q(q_reference_power) - Q31 = Q(q_reference_power) */
4132 : #ifdef FIX_867_CLDFB_NRG_SCALE
4133 712000 : scale_sig32( aux_buffer_res, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( common1_q, q_reference_power[0] ) ); /* Q(common1_q) */
4134 712000 : scale_sig32( aux_buffer_res + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( common1_q, q_reference_power[1] ) ); /* Q(common1_q) */
4135 : #else
4136 : scale_sig32( aux_buffer_res, num_freq_bands, sub( common1_q, *q_reference_power ) ); /* Q(common1_q) */
4137 : #endif
4138 712000 : scale_sig32( &cy_auto_dir_smooth[cur_idx], num_freq_bands, sub( common1_q, *q_cy_auto_dir_smooth ) ); /* Q(common1_q) */
4139 712000 : v_add_fixed( &cy_auto_dir_smooth[cur_idx], aux_buffer_res, &cy_auto_dir_smooth[cur_idx], num_freq_bands, Q1 ); /* Q(common1_q) - Q1 */
4140 :
4141 712000 : v_mult_fixed( direct_power, &direct_responses[cur_idx], aux_buffer_res, num_freq_bands ); /* Q31 + Q(q_reference_power) - Q31 = Q(q_reference_power) */
4142 : #ifdef FIX_867_CLDFB_NRG_SCALE
4143 712000 : scale_sig32( aux_buffer_res, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( common2_q, q_reference_power[0] ) ); /* Q(common2_q) */
4144 712000 : scale_sig32( aux_buffer_res + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( common2_q, q_reference_power[1] ) ); /* Q(common2_q) */
4145 : #else
4146 : scale_sig32( aux_buffer_res, num_freq_bands, sub( common2_q, *q_reference_power ) ); /* Q(common2_q) */
4147 : #endif
4148 712000 : scale_sig32( &cy_cross_dir_smooth[cur_idx], num_freq_bands, sub( common2_q, *q_cy_cross_dir_smooth ) ); /* Q(common2_q) */
4149 712000 : v_add_fixed( &cy_cross_dir_smooth[cur_idx], aux_buffer_res, &cy_cross_dir_smooth[cur_idx], num_freq_bands, Q1 ); /* Q(common2_q) - Q1 */
4150 : }
4151 :
4152 : /* Q adjustment */
4153 72000 : *q_cy_auto_dir_smooth = sub( common1_q, Q1 );
4154 72000 : move16();
4155 72000 : *q_cy_cross_dir_smooth = sub( common2_q, Q1 );
4156 72000 : move16();
4157 :
4158 72000 : return;
4159 : }
4160 :
4161 :
4162 77963 : static void computeTargetPSDs_direct_subframe_fx(
4163 : const Word16 num_channels,
4164 : const Word16 num_freq_bands,
4165 : const Word32 *direct_power_factor, /*q31*/
4166 : const Word32 *reference_power, /*q_reference_power*/
4167 : const Word16 *q_reference_power,
4168 : const Word32 *direct_responses, /*q31*/
4169 : const Word32 *direct_responses_square, /*q31*/
4170 : Word32 *cy_auto_dir_smooth, /*q_cy_auto_dir_smooth*/
4171 : Word16 *q_cy_auto_dir_smooth,
4172 : Word32 *cy_cross_dir_smooth, /*q_cy_cross_dir_smooth*/
4173 : Word16 *q_cy_cross_dir_smooth )
4174 : {
4175 : #ifdef FIX_867_CLDFB_NRG_SCALE
4176 : Word16 ch_idx, cur_idx, q_tmp;
4177 : Word32 L_tmp[CLDFB_NO_CHANNELS_MAX];
4178 : Word16 q_cy_auto_dir_smooth_local[2];
4179 : #else
4180 : Word16 ch_idx, cur_idx, i, q_tmp;
4181 : Word64 W_tmp[CLDFB_NO_CHANNELS_MAX], W_max;
4182 : set64_fx( W_tmp, 0, CLDFB_NO_CHANNELS_MAX );
4183 : #endif
4184 :
4185 : /* segment auxiliary buffer */
4186 : Word32 direct_power[CLDFB_NO_CHANNELS_MAX]; /* size: num_freq_bands. */
4187 :
4188 : /* estimate direct and diffuse power */
4189 : #ifndef FIX_867_CLDFB_NRG_SCALE
4190 : FOR( i = 0; i < num_freq_bands; i++ )
4191 : {
4192 : direct_power[i] = Mpy_32_32( direct_power_factor[i], reference_power[i] );
4193 : move32();
4194 : test();
4195 : if ( direct_power[i] == 0 && ( direct_power_factor[i] != 0 && reference_power[i] != 0 ) )
4196 : {
4197 : direct_power[i] = 1;
4198 : move32();
4199 : }
4200 : }
4201 : #else
4202 77963 : v_mult_fixed( direct_power_factor, reference_power, direct_power, num_freq_bands );
4203 : #endif
4204 : /* compute target auto and cross PSDs of current frame (smoothed) */
4205 595814 : FOR( ch_idx = 0; ch_idx < num_channels; ++ch_idx )
4206 : {
4207 517851 : cur_idx = imult1616( ch_idx, num_freq_bands );
4208 :
4209 : #ifndef FIX_867_CLDFB_NRG_SCALE
4210 : W_max = 0;
4211 : move64();
4212 : FOR( i = 0; i < num_freq_bands; i++ )
4213 : {
4214 : W_tmp[i] = W_mult_32_32( direct_power[i], direct_responses_square[cur_idx + i] ); // q_reference_power + Q31 + 1
4215 : move64();
4216 : IF( LT_64( W_max, W_abs( W_tmp[i] ) ) )
4217 : {
4218 : W_max = W_abs( W_tmp[i] );
4219 : }
4220 : }
4221 : q_tmp = W_norm( W_max );
4222 : #ifdef FIX_867_CLDFB_NRG_SCALE
4223 : FOR( i = 0; i < s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ); i++ )
4224 : {
4225 : cy_auto_dir_smooth[cur_idx + i] = W_extract_h( W_shl( W_tmp[i], q_tmp ) ); /*q_reference_power[0]+q_tmp*/
4226 : move32();
4227 : }
4228 : Word16 q_tmp2 = sub( q_tmp, sub( q_reference_power[1], q_reference_power[0] ) );
4229 : FOR( i = CLDFB_NO_CHANNELS_HALF; i < num_freq_bands; i++ )
4230 : {
4231 : cy_auto_dir_smooth[cur_idx + i] = W_extract_h( W_shl( W_tmp[i], q_tmp2 ) ); /*q_reference_power[1]+q_tmp*/
4232 : move32();
4233 : }
4234 : q_cy_auto_dir_smooth[ch_idx] = add( q_reference_power[0], q_tmp );
4235 : move16();
4236 : #else
4237 : FOR( i = 0; i < num_freq_bands; i++ )
4238 : {
4239 : cy_auto_dir_smooth[cur_idx + i] = W_extract_h( W_shl( W_tmp[i], q_tmp ) ); /*q_reference_power+q_tmp*/
4240 : move32();
4241 : }
4242 : q_cy_auto_dir_smooth[ch_idx] = add( *q_reference_power, q_tmp );
4243 : move16();
4244 : #endif
4245 : #else
4246 517851 : q_tmp = L_norm_arr( &direct_responses_square[cur_idx], num_freq_bands );
4247 517851 : Copy_Scale_sig32( &direct_responses_square[cur_idx], L_tmp, num_freq_bands, q_tmp );
4248 517851 : v_mult_fixed( direct_power, L_tmp, &cy_auto_dir_smooth[cur_idx], num_freq_bands ); // (q_reference_power, q_tmp) -> q_reference_power + q_tmp
4249 :
4250 517851 : q_cy_auto_dir_smooth_local[0] = add( add( q_reference_power[0], q_tmp ), L_norm_arr( cy_auto_dir_smooth + cur_idx, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) );
4251 517851 : q_cy_auto_dir_smooth_local[1] = add( add( q_reference_power[1], q_tmp ), L_norm_arr( cy_auto_dir_smooth + cur_idx + CLDFB_NO_CHANNELS_HALF, s_max( sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), 0 ) ) );
4252 517851 : q_cy_auto_dir_smooth[ch_idx] = s_min( q_cy_auto_dir_smooth_local[0], q_cy_auto_dir_smooth_local[1] );
4253 517851 : move16();
4254 :
4255 517851 : Scale_sig32( cy_auto_dir_smooth + cur_idx, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( q_cy_auto_dir_smooth[ch_idx], add( q_reference_power[0], q_tmp ) ) );
4256 517851 : Scale_sig32( cy_auto_dir_smooth + cur_idx + CLDFB_NO_CHANNELS_HALF, s_max( sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), 0 ), sub( q_cy_auto_dir_smooth[ch_idx], add( q_reference_power[1], q_tmp ) ) );
4257 :
4258 : #endif
4259 517851 : v_mult_fixed( direct_power, &direct_responses[cur_idx], &cy_cross_dir_smooth[cur_idx], num_freq_bands ); // (q_reference_power, Q31) -> q_reference_power
4260 : #ifdef FIX_867_CLDFB_NRG_SCALE
4261 517851 : Scale_sig32( &cy_cross_dir_smooth[cur_idx] + CLDFB_NO_CHANNELS_HALF, s_max( sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), 0 ), sub( q_reference_power[0], q_reference_power[1] ) );
4262 : #endif
4263 : }
4264 :
4265 : #ifdef FIX_867_CLDFB_NRG_SCALE
4266 77963 : *q_cy_cross_dir_smooth = q_reference_power[0];
4267 77963 : move16();
4268 : #else
4269 : *q_cy_cross_dir_smooth = *q_reference_power;
4270 : move16();
4271 : #endif
4272 :
4273 77963 : return;
4274 : }
4275 :
4276 :
4277 72000 : static void computeTargetPSDs_diffuse_fx(
4278 : const Word16 num_channels,
4279 : const Word16 num_freq_bands,
4280 : const Word16 start_band,
4281 : const Word32 *diffuse_power_factor, /*q31*/
4282 : const Word32 *reference_power, /*q_reference_power*/
4283 : const Word16 *q_reference_power,
4284 : const Word32 *diffuse_responses_square, /*Q31*/
4285 : Word32 *cy_auto_diff_smooth, /*q_cy_auto_diff_smooth*/
4286 : Word16 *q_cy_auto_diff_smooth )
4287 : {
4288 : Word16 ch_idx, cur_idx;
4289 :
4290 : /* segment auxiliary buffer */
4291 : Word32 diffuse_power[CLDFB_NO_CHANNELS_MAX]; /* size: num_freq_bands. */
4292 : Word32 aux_buffer_res[CLDFB_NO_CHANNELS_MAX]; /* size: num_freq_bands. */
4293 :
4294 : /* estimate direct and diffuse power */
4295 72000 : v_mult_fixed( diffuse_power_factor, reference_power, diffuse_power, num_freq_bands ); /* Q31 + Q(q_reference_power) - Q31 = Q(q_reference_power) */
4296 :
4297 : #ifdef FIX_867_CLDFB_NRG_SCALE
4298 72000 : Word16 common_q = s_min( *q_cy_auto_diff_smooth, s_min( q_reference_power[0], q_reference_power[1] ) );
4299 : #else
4300 : Word16 common_q = s_min( *q_cy_auto_diff_smooth, *q_reference_power );
4301 : #endif
4302 :
4303 : /* compute target auto and cross PSDs of current frame (smoothed) */
4304 784000 : FOR( ch_idx = 0; ch_idx < num_channels; ++ch_idx )
4305 : {
4306 712000 : cur_idx = imult1616( ch_idx, num_freq_bands );
4307 :
4308 712000 : v_multc_fixed( &diffuse_power[start_band], diffuse_responses_square[ch_idx], aux_buffer_res, sub( num_freq_bands, start_band ) ); /* Q31 + Q(q_reference_power) - Q31 = Q(q_reference_power) */
4309 : #ifdef FIX_867_CLDFB_NRG_SCALE
4310 712000 : scale_sig32( aux_buffer_res, s_min( sub( num_freq_bands, start_band ), CLDFB_NO_CHANNELS_HALF ), sub( common_q, q_reference_power[0] ) ); /* Q(common_q) */
4311 712000 : scale_sig32( aux_buffer_res + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( sub( num_freq_bands, start_band ), CLDFB_NO_CHANNELS_HALF ) ), sub( common_q, q_reference_power[1] ) ); /* Q(common_q) */
4312 : #else
4313 : scale_sig32( aux_buffer_res, sub( num_freq_bands, start_band ), sub( common_q, *q_reference_power ) ); /* Q(common_q) */
4314 : #endif
4315 712000 : scale_sig32( &cy_auto_diff_smooth[cur_idx + start_band], sub( num_freq_bands, start_band ), sub( common_q, *q_cy_auto_diff_smooth ) ); /* Q(common_q) */
4316 712000 : v_add_fixed( &cy_auto_diff_smooth[cur_idx + start_band], aux_buffer_res, &cy_auto_diff_smooth[cur_idx + start_band], sub( num_freq_bands, start_band ), Q1 ); /* Q(common_q) - Q1 */
4317 : }
4318 :
4319 : /* Q adjustment */
4320 72000 : *q_cy_auto_diff_smooth = sub( common_q, Q1 );
4321 72000 : move16();
4322 :
4323 72000 : return;
4324 : }
4325 :
4326 :
4327 77963 : static void computeTargetPSDs_diffuse_subframe_fx(
4328 : const Word16 num_channels,
4329 : const Word16 num_freq_bands,
4330 : const Word16 start_band,
4331 : const Word32 *diffuse_power_factor, /*q31*/
4332 : const Word32 *reference_power, /*q_reference_power*/
4333 : const Word16 *q_reference_power,
4334 : const Word32 *diffuse_responses_square, /*q31*/
4335 : Word32 *cy_auto_diff_smooth, /*q_cy_auto_diff_smooth*/
4336 : Word16 *q_cy_auto_diff_smooth )
4337 : {
4338 : Word16 ch_idx, cur_idx;
4339 : Word32 diffuse_power[CLDFB_NO_CHANNELS_MAX]; /* segment auxiliary buffer; size: num_freq_bands. */
4340 : #ifdef FIX_867_CLDFB_NRG_SCALE
4341 : Word16 q_cy_auto_diff_smooth_new, q_diffuse_power;
4342 : #endif
4343 :
4344 : /* estimate direct and diffuse power */
4345 77963 : v_mult_fixed( diffuse_power_factor, reference_power, diffuse_power, num_freq_bands ); // (Q31, q_reference_power) -> q_reference_power
4346 :
4347 : #ifdef FIX_867_CLDFB_NRG_SCALE
4348 77963 : q_diffuse_power = s_min( q_reference_power[0], q_reference_power[1] );
4349 77963 : Scale_sig32( diffuse_power, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( q_diffuse_power, q_reference_power[0] ) );
4350 77963 : Scale_sig32( diffuse_power + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( q_diffuse_power, q_reference_power[1] ) );
4351 77963 : q_cy_auto_diff_smooth_new = q_diffuse_power;
4352 77963 : IF( LT_16( *q_cy_auto_diff_smooth, q_diffuse_power ) )
4353 : {
4354 3966 : Scale_sig32( diffuse_power, num_freq_bands, sub( *q_cy_auto_diff_smooth, q_cy_auto_diff_smooth_new ) );
4355 3966 : q_cy_auto_diff_smooth_new = *q_cy_auto_diff_smooth;
4356 3966 : move16();
4357 : }
4358 : #endif
4359 : /* compute target auto and cross PSDs of current frame (smoothed) */
4360 595814 : FOR( ch_idx = 0; ch_idx < num_channels; ++ch_idx )
4361 : {
4362 517851 : cur_idx = imult1616( ch_idx, num_freq_bands );
4363 :
4364 : #ifdef FIX_867_CLDFB_NRG_SCALE
4365 517851 : IF( GT_16( *q_cy_auto_diff_smooth, q_diffuse_power ) )
4366 : {
4367 460751 : Scale_sig32( &cy_auto_diff_smooth[cur_idx], start_band, sub( q_diffuse_power, *q_cy_auto_diff_smooth ) );
4368 : }
4369 : #endif
4370 517851 : v_multc_fixed( &diffuse_power[start_band], diffuse_responses_square[ch_idx], &cy_auto_diff_smooth[cur_idx + start_band], sub( num_freq_bands, start_band ) ); // (q_reference_power, Q31) -> q_reference_power
4371 : }
4372 :
4373 : #ifdef FIX_867_CLDFB_NRG_SCALE
4374 77963 : *q_cy_auto_diff_smooth = q_cy_auto_diff_smooth_new;
4375 77963 : move16();
4376 : #else
4377 : *q_cy_auto_diff_smooth = *q_reference_power;
4378 : move16();
4379 : #endif
4380 :
4381 77963 : return;
4382 : }
4383 :
4384 :
4385 209936 : static void computeTargetPSDs_diffuse_with_onsets_fx(
4386 : const Word16 num_channels,
4387 : const Word16 num_freq_bands,
4388 : const Word16 num_decorr_freq_bands,
4389 : const Word16 *proto_frame_diff_index,
4390 : const Word32 *diffuse_power_factor, /*q31*/
4391 : const Word32 *reference_power, /* q_reference_power */
4392 : const Word16 *q_reference_power,
4393 : const Word32 *diffuse_responses_square, /*q31*/
4394 : const Word32 *onset_filter, /*q31*/
4395 : Word32 *cy_auto_diff_smooth, /*q_cy_auto_diff_smooth*/
4396 : Word16 *q_cy_auto_diff_smooth )
4397 : {
4398 : Word16 ch_idx, cur_idx, diff_idx;
4399 : Word32 diffuse_response_p4, aux_buffer_res1[CLDFB_NO_CHANNELS_MAX];
4400 : /* segment auxiliary buffer */
4401 : Word32 diffuse_power[CLDFB_NO_CHANNELS_MAX]; /* size: num_freq_bands. */
4402 : Word32 aux_buffer_res[CLDFB_NO_CHANNELS_MAX]; /* size: num_freq_bands. */
4403 : #ifdef FIX_867_CLDFB_NRG_SCALE
4404 : Word16 q_common, q_reference_power_min_one[2];
4405 :
4406 209936 : q_reference_power_min_one[0] = sub( q_reference_power[0], Q1 );
4407 209936 : q_reference_power_min_one[1] = sub( q_reference_power[1], Q1 );
4408 : #else
4409 : Word16 q_common, q_reference_power_min_one;
4410 :
4411 : q_reference_power_min_one = sub( *q_reference_power, Q1 );
4412 : #endif
4413 :
4414 : /* estimate direct and diffuse power */
4415 209936 : v_mult_fixed( diffuse_power_factor, reference_power, diffuse_power, num_decorr_freq_bands ); // (Q31, q_reference_power) -> q_reference_power
4416 :
4417 : #ifdef FIX_867_CLDFB_NRG_SCALE
4418 209936 : q_common = s_min( *q_cy_auto_diff_smooth, s_min( q_reference_power_min_one[0], q_reference_power_min_one[1] ) );
4419 : #else
4420 : IF( GT_16( *q_cy_auto_diff_smooth, q_reference_power_min_one ) )
4421 : {
4422 : q_common = q_reference_power_min_one;
4423 : move16();
4424 : }
4425 : ELSE
4426 : {
4427 : q_common = *q_cy_auto_diff_smooth;
4428 : move16();
4429 : }
4430 : #endif
4431 :
4432 : /* compute target auto and cross PSDs of current frame (smoothed) */
4433 1682192 : FOR( ch_idx = 0; ch_idx < num_channels; ++ch_idx )
4434 : {
4435 1472256 : diffuse_response_p4 = Mpy_32_32( diffuse_responses_square[ch_idx], diffuse_responses_square[ch_idx] ); // (Q31, Q31) -> Q31
4436 :
4437 1472256 : cur_idx = imult1616( ch_idx, num_freq_bands );
4438 1472256 : diff_idx = imult1616( proto_frame_diff_index[ch_idx], num_freq_bands );
4439 :
4440 1472256 : v_multc_fixed( &onset_filter[diff_idx], diffuse_responses_square[ch_idx], aux_buffer_res1, num_decorr_freq_bands ); // (Q31, Q31) -> Q31
4441 1472256 : v_multc_fixed( &onset_filter[diff_idx], INT_MIN, aux_buffer_res, num_decorr_freq_bands ); // (Q31, Q31) -> Q31
4442 1472256 : v_addc_fixed( aux_buffer_res, ONE_IN_Q31, aux_buffer_res, num_decorr_freq_bands ); // Q31
4443 1472256 : v_multc_fixed( aux_buffer_res, diffuse_response_p4, aux_buffer_res, num_decorr_freq_bands ); // (Q31, Q31) -> Q31
4444 1472256 : v_add_fixed( aux_buffer_res1, aux_buffer_res, aux_buffer_res, num_decorr_freq_bands, Q1 ); // Q30
4445 1472256 : v_mult_fixed( aux_buffer_res, diffuse_power, aux_buffer_res, num_decorr_freq_bands ); // (Q30, q_reference_power) -> q_reference_power - Q1
4446 :
4447 : #ifdef FIX_867_CLDFB_NRG_SCALE
4448 1472256 : IF( NE_16( q_common, q_reference_power_min_one[0] ) )
4449 : {
4450 17631 : scale_sig32( aux_buffer_res, s_min( num_decorr_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( q_common, q_reference_power_min_one[0] ) ); // q_common
4451 : }
4452 1472256 : IF( NE_16( q_common, q_reference_power_min_one[1] ) )
4453 : {
4454 686647 : scale_sig32( aux_buffer_res + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_decorr_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( q_common, q_reference_power_min_one[1] ) ); // q_common
4455 : }
4456 1472256 : IF( NE_16( q_common, *q_cy_auto_diff_smooth ) )
4457 : {
4458 1168005 : scale_sig32( &cy_auto_diff_smooth[cur_idx], num_decorr_freq_bands, sub( q_common, *q_cy_auto_diff_smooth ) ); // q_common
4459 : }
4460 1472256 : v_add_fixed( &cy_auto_diff_smooth[cur_idx], aux_buffer_res, &cy_auto_diff_smooth[cur_idx], num_decorr_freq_bands, Q1 ); // (q_common - Q1)
4461 1472256 : scale_sig32( &cy_auto_diff_smooth[cur_idx + num_decorr_freq_bands], sub( num_freq_bands, num_decorr_freq_bands ), sub( sub( q_common, Q1 ), *q_cy_auto_diff_smooth ) ); // (q_common - Q1)
4462 : #else
4463 : IF( NE_16( q_common, q_reference_power_min_one ) )
4464 : {
4465 : scale_sig32( aux_buffer_res, num_decorr_freq_bands, sub( q_common, q_reference_power_min_one ) ); // q_common
4466 : }
4467 : IF( NE_16( q_common, *q_cy_auto_diff_smooth ) )
4468 : {
4469 : scale_sig32( &cy_auto_diff_smooth[cur_idx], num_decorr_freq_bands, sub( q_common, *q_cy_auto_diff_smooth ) ); // q_common
4470 : }
4471 : v_add_fixed( &cy_auto_diff_smooth[cur_idx], aux_buffer_res, &cy_auto_diff_smooth[cur_idx], num_decorr_freq_bands, Q1 ); // (q_common - Q1)
4472 : scale_sig32( &cy_auto_diff_smooth[cur_idx + num_decorr_freq_bands], sub( num_freq_bands, num_decorr_freq_bands ), sub( sub( q_common, Q1 ), *q_cy_auto_diff_smooth ) ); // (q_common - Q1)
4473 : #endif
4474 : }
4475 :
4476 : /* Q adjustment */
4477 209936 : *q_cy_auto_diff_smooth = sub( q_common, Q1 );
4478 209936 : move16();
4479 :
4480 209936 : return;
4481 : }
4482 :
4483 :
4484 2716 : static void computeAlphaSynthesis_fx( Word16 *alpha_synthesis_fx /*q15*/, const Word16 averaging_length_ms, const Word16 maxAlpha_fx /*q15*/, Word16 *numAlphas, const Word16 slot_size, const Word16 num_freq_bands, Word16 *frequency_axis_fx /*q0*/, const Word32 output_Fs )
4485 : {
4486 : Word16 k;
4487 : Word16 avg_length_f_ms_fx;
4488 :
4489 : /* check input pointer */
4490 2716 : IF( alpha_synthesis_fx == NULL )
4491 : {
4492 0 : return;
4493 : }
4494 :
4495 2716 : IF( averaging_length_ms == 0 )
4496 : {
4497 0 : set16_fx( alpha_synthesis_fx, MAX16B, num_freq_bands ); /*q15*/
4498 : }
4499 : ELSE
4500 : {
4501 10864 : FOR( k = 0; k < num_freq_bands; k++ )
4502 : {
4503 10864 : Word16 faxis_idx = s_max( k, 1 );
4504 :
4505 : // avg_length_f_ms = 1000.f * (float)averaging_length_ms / fabsf(frequency_axis[faxis_idx]);
4506 10864 : Word16 tmp_exp = 0;
4507 10864 : Word16 tmp_1 = BASOP_Util_Divide1616_Scale( averaging_length_ms, frequency_axis_fx[faxis_idx], &tmp_exp ); /*Q(15-(tmp_exp+15-15))*/
4508 10864 : Word16 tmp_2 = mult( tmp_1, 1000 ); // 15 - tmp_exp + 0 -15 = -tmp_exp (Q-fac)
4509 10864 : avg_length_f_ms_fx = tmp_2; // Q(-tmp_exp)
4510 10864 : move16();
4511 10864 : move16();
4512 :
4513 : /* alpha_synthesis[k] = min( (float) slot_size / ( avg_length_f_ms * (float) output_Fs / 1000.f ), 1.0f );*/
4514 10864 : Word32 tmp_3 = Mpy_32_16_1( output_Fs, avg_length_f_ms_fx ); // 0 - tmp_exp - 15 (Q-fac)
4515 : Word16 tmp_exp_3;
4516 10864 : Word16 tmp_4 = BASOP_Util_Divide3232_Scale( tmp_3, 1000, &tmp_exp_3 ); /*tmp_exp_4 stores resultant exponent*/
4517 10864 : Word16 tmp_exp_4 = sub( add( tmp_exp_3, add( add( 31, tmp_exp ), 15 ) ), 31 );
4518 : Word16 tmp_exp_5;
4519 10864 : Word16 tmp_5 = BASOP_Util_Divide1616_Scale( slot_size, tmp_4, &tmp_exp_5 ); /*res_exp stores resultant exponent*/
4520 10864 : Word16 res_exp = sub( add( tmp_exp_5, 15 ), tmp_exp_4 );
4521 :
4522 10864 : Word16 flag = BASOP_Util_Cmp_Mant32Exp( L_deposit_h( tmp_5 ), res_exp, 1, 31 );
4523 10864 : IF( EQ_16( flag, -1 ) )
4524 : {
4525 10864 : alpha_synthesis_fx[k] = shr( tmp_5, negate( res_exp ) ); // q15
4526 10864 : move16();
4527 : }
4528 : ELSE
4529 : {
4530 0 : alpha_synthesis_fx[k] = MAX16B; /*q15*/
4531 0 : move16();
4532 : }
4533 :
4534 10864 : Word16 flag2 = BASOP_Util_Cmp_Mant32Exp( L_deposit_h( alpha_synthesis_fx[k] ), 0, L_deposit_h( maxAlpha_fx ), 0 );
4535 10864 : test();
4536 10864 : IF( flag2 == 0 || EQ_16( flag2, 1 ) )
4537 : {
4538 2716 : alpha_synthesis_fx[k] = maxAlpha_fx; /*q15*/
4539 2716 : move16();
4540 2716 : *numAlphas = add( k, 1 );
4541 2716 : move16();
4542 2716 : BREAK;
4543 : }
4544 : }
4545 : }
4546 :
4547 2716 : return;
4548 : }
4549 :
4550 :
4551 566249 : static void spreadCoherencePanningHoa_fx(
4552 : const Word16 azimuth,
4553 : const Word16 elevation,
4554 : const Word16 spreadCoh_fx, /*i:Q15*/
4555 : Word32 *direct_response_fx, /*i/o:Q_direct_response*/
4556 : Word16 *Q_direct_response, /*i/o:stores q for direct_response_fx*/
4557 : const Word16 num_channels_dir,
4558 : const Word16 ambisonics_order )
4559 : {
4560 : Word16 i;
4561 :
4562 : Word32 direct_response_left_fx[MAX_OUTPUT_CHANNELS];
4563 : Word32 direct_response_right_fx[MAX_OUTPUT_CHANNELS];
4564 : Word32 gainCenter_fx;
4565 : Word32 gainSide_fx;
4566 :
4567 566249 : ivas_dirac_dec_get_response_fx( azimuth, elevation, direct_response_fx /*Q_direct_response*/, ambisonics_order, *Q_direct_response );
4568 :
4569 : Word16 exp_Gain_side, exp_Gain_center;
4570 566249 : IF( spreadCoh_fx > 0 )
4571 : {
4572 322745 : ivas_dirac_dec_get_response_fx( add( azimuth, 30 ), elevation, direct_response_left_fx /*Q_direct_response*/, ambisonics_order, *Q_direct_response );
4573 322745 : ivas_dirac_dec_get_response_fx( add( azimuth, 330 ), elevation, direct_response_right_fx /*Q_direct_response*/, ambisonics_order, *Q_direct_response );
4574 :
4575 :
4576 : Word16 var_a, var_b, exp_a;
4577 :
4578 322745 : IF( LT_16( spreadCoh_fx, ONE_IN_Q14 /*0.5 q15*/ ) )
4579 : {
4580 : /*gainCenter = (3 - 4*spreadCoh )/3*/
4581 317873 : var_a = sub( 24576 /*3 in Q13*/, spreadCoh_fx ); // Q13
4582 317873 : var_a = mult( var_a, ONE_BY_THREE_Q15 ); // Q13
4583 :
4584 317873 : gainCenter_fx = L_deposit_h( shr( var_a, 2 ) ); // Q11 + 16 = Q27
4585 317873 : gainSide_fx = L_deposit_h( mult( spreadCoh_fx, ONE_BY_THREE_Q15 ) ); // Q14 + 16 (reduce Q by 1 to *2) = Q30
4586 317873 : exp_Gain_side = 31 - Q30;
4587 317873 : move16();
4588 317873 : exp_Gain_center = 31 - Q27;
4589 317873 : move16();
4590 : }
4591 : ELSE
4592 : {
4593 4872 : var_a = shl( sub( 16384 /*2 in Q13*/, shr( spreadCoh_fx, 2 ) ), 1 ); // q13
4594 4872 : exp_a = 15 - Q13;
4595 4872 : move16();
4596 4872 : var_a = Inv16( var_a, &exp_a ); // 15-exp_a
4597 4872 : gainSide_fx = L_deposit_h( var_a ); // 15-exp_a + 16 = Q31 -exp_a
4598 4872 : exp_Gain_side = exp_a;
4599 4872 : move16();
4600 :
4601 4872 : var_b = sub( 8192 /*2 in Q12*/, shr( spreadCoh_fx, 2 ) /*Q14*/ ); // exp => 3
4602 4872 : gainCenter_fx = L_deposit_h( mult( var_b, var_a ) ); // 15-exp_a + 12-15+16=>28-exp_a = // 3 + exp_a
4603 4872 : exp_Gain_center = add( 3, exp_a );
4604 : }
4605 :
4606 :
4607 : Word32 mpy1, mpy2;
4608 : Word16 exp_arr[16], exp;
4609 322745 : set16_fx( exp_arr, sub( 31, *Q_direct_response ), 16 );
4610 2589658 : FOR( i = 0; i < num_channels_dir; i++ )
4611 : {
4612 2266913 : mpy1 = Mpy_32_32( L_add( direct_response_left_fx[i], direct_response_right_fx[i] ), gainSide_fx ); // 31 - Q_direct_response + exp_Gain_Side
4613 2266913 : mpy2 = Mpy_32_32( direct_response_fx[i], gainCenter_fx ); // 31 - Q_direct_response + exp_Gain_Center
4614 2266913 : exp = 0;
4615 2266913 : move16();
4616 2266913 : direct_response_fx[i] = BASOP_Util_Add_Mant32Exp( mpy1, add( sub( 31, *Q_direct_response ), exp_Gain_side ), mpy2, add( sub( 31, *Q_direct_response ), exp_Gain_center ), &exp ); // 31-exp
4617 2266913 : move32();
4618 2266913 : exp_arr[i] = exp;
4619 2266913 : move16();
4620 : }
4621 322745 : Word16 max_val = MIN_16;
4622 322745 : move16();
4623 5486665 : FOR( i = 0; i < 16; i++ )
4624 : {
4625 5163920 : max_val = s_max( max_val, exp_arr[i] );
4626 : }
4627 5486665 : FOR( i = 0; i < 16; i++ )
4628 : {
4629 5163920 : direct_response_fx[i] = L_shr( direct_response_fx[i], sub( max_val, exp_arr[i] ) ); // Q(31-exp_arr[i])->q(31-max_val)
4630 5163920 : move32();
4631 : }
4632 322745 : *Q_direct_response = sub( 31, max_val );
4633 322745 : move16();
4634 : }
4635 :
4636 566249 : return;
4637 : }
4638 :
4639 :
4640 5119059 : static void spreadCoherencePanningVbap_fx(
4641 : const Word16 azimuth, /*i:q0*/
4642 : const Word16 elevation, /*i:q0*/
4643 : const Word16 spreadCoh_fx, /*i:q15*/
4644 : Word32 *direct_response_fx, /*i/o:Q_direct_response*/
4645 : Word16 *Q_direct_response, /*o: stores q for direct_response_fx*/
4646 : const Word16 num_channels_dir,
4647 : const VBAP_HANDLE hVBAPdata )
4648 : {
4649 : Word16 i;
4650 : Word32 direct_response_left_fx[MAX_OUTPUT_CHANNELS];
4651 : Word32 direct_response_right_fx[MAX_OUTPUT_CHANNELS];
4652 5119059 : set32_fx( direct_response_left_fx, 0, MAX_OUTPUT_CHANNELS );
4653 5119059 : set32_fx( direct_response_right_fx, 0, MAX_OUTPUT_CHANNELS );
4654 : Word32 gainCenter_fx;
4655 : Word32 gainSide_fx;
4656 :
4657 5119059 : IF( hVBAPdata == NULL )
4658 : {
4659 : /* Distribute signal to all channels if VBAP is not properly initialized. */
4660 0 : Word16 exp_tmp = 0;
4661 0 : move16();
4662 0 : Word16 var_temp = ISqrt16( num_channels_dir, &exp_tmp );
4663 0 : set32_fx( direct_response_fx, var_temp, num_channels_dir );
4664 0 : *Q_direct_response = sub( 31, exp_tmp );
4665 0 : move16();
4666 :
4667 0 : return;
4668 : }
4669 :
4670 5119059 : set32_fx( direct_response_fx, 0, MAX_OUTPUT_CHANNELS );
4671 5119059 : vbap_determine_gains_fx( hVBAPdata, direct_response_fx /*q29*/, azimuth, elevation, 0 );
4672 5119059 : *Q_direct_response = Q29;
4673 5119059 : move16();
4674 :
4675 5119059 : IF( spreadCoh_fx > 0 )
4676 : {
4677 459977 : vbap_determine_gains_fx( hVBAPdata, direct_response_left_fx /*q29*/, add( azimuth, 30 ), elevation, 0 );
4678 459977 : vbap_determine_gains_fx( hVBAPdata, direct_response_right_fx /*q29*/, sub( azimuth, 30 ), elevation, 0 );
4679 :
4680 459977 : Word32 var1 = 0;
4681 459977 : move32();
4682 459977 : Word32 var2 = 0;
4683 459977 : move32();
4684 459977 : Word16 var_a = 0;
4685 459977 : move16();
4686 459977 : Word16 var_b = 0;
4687 459977 : move16();
4688 459977 : IF( LT_16( spreadCoh_fx, 16384 ) ) // 16384 = 0.5 in Q15
4689 : {
4690 449157 : var_a = mult( spreadCoh_fx, INV_SQRT3_FX ); // Q14
4691 449157 : var_b = sub( ONE_IN_Q14, spreadCoh_fx ); // Q14
4692 449157 : gainCenter_fx = L_deposit_h( add( var_a, var_b ) ); // Q30
4693 449157 : gainSide_fx = L_deposit_h( var_a ); // Q30
4694 : }
4695 : ELSE
4696 : {
4697 10820 : var_a = sub( ONE_IN_Q14, shr( spreadCoh_fx, 1 ) ); // Q13
4698 10820 : gainCenter_fx = L_shl( L_deposit_h( var_a ), 1 ); // Q30
4699 10820 : gainSide_fx = ONE_IN_Q30;
4700 10820 : move32();
4701 : }
4702 :
4703 459977 : Word32 var3 = 0;
4704 459977 : move32();
4705 459977 : *Q_direct_response = Q28;
4706 459977 : move16();
4707 3988489 : FOR( i = 0; i < num_channels_dir; i++ )
4708 : {
4709 3528512 : var1 = L_add( direct_response_left_fx[i], direct_response_right_fx[i] ); // Q29
4710 3528512 : var2 = Mpy_32_32( var1, gainSide_fx ); // Q28
4711 3528512 : var3 = Mpy_32_32( direct_response_fx[i], gainCenter_fx ); // Q28
4712 3528512 : direct_response_fx[i] = L_add( var3, var2 ); // Q28
4713 3528512 : move32();
4714 : }
4715 : }
4716 :
4717 5119059 : return;
4718 : }
4719 :
4720 :
4721 10273813 : static void normalizePanningGains_fx(
4722 : Word32 *direct_response_fx, /*i/o:resultant q is q_direct_res*/
4723 : Word16 *q_direct_res, /*i/o: stores q for direct_response_fx*/
4724 : const Word16 num_channels_dir )
4725 : {
4726 : Word32 energySum_fx;
4727 10273813 : Word16 exp_energySum = 0;
4728 : Word32 normVal_fx;
4729 : Word16 i;
4730 10273813 : move16();
4731 :
4732 10273813 : Word16 gb = find_guarded_bits_fx( num_channels_dir );
4733 10273813 : energySum_fx = sum2_f_32_fx( direct_response_fx, num_channels_dir, gb ); // exp_energySum stores resultant exponent
4734 10273813 : IF( GT_16( *q_direct_res, Q31 ) )
4735 : {
4736 1691 : exp_energySum = add( shl( sub( Q31, *q_direct_res ), 1 ), gb );
4737 : }
4738 10273813 : exp_energySum = sub( Q31, sub( sub( shl( *q_direct_res, 1 ), Q31 ), gb ) );
4739 :
4740 10273813 : IF( energySum_fx > 0 )
4741 : {
4742 10260101 : normVal_fx = ISqrt32( energySum_fx, &exp_energySum ); // 31-exp_energySum
4743 : }
4744 : ELSE
4745 : {
4746 13712 : energySum_fx = BASOP_Util_Add_Mant32Exp( energySum_fx, exp_energySum, ONE_IN_Q30, 1, &exp_energySum ); // 31-exp_energySum
4747 13712 : normVal_fx = ISqrt32( energySum_fx, &exp_energySum ); // 31-exp_energySum
4748 : }
4749 :
4750 108107232 : FOR( i = 0; i < num_channels_dir; i++ )
4751 : {
4752 97833419 : direct_response_fx[i] = Mpy_32_32( direct_response_fx[i], normVal_fx ); // q_direct_res stores resultant q for the same
4753 97833419 : move32();
4754 : }
4755 10273813 : Word16 exp = add( sub( Q31, *q_direct_res ), exp_energySum );
4756 10273813 : *q_direct_res = sub( Q31, exp );
4757 :
4758 10273813 : return;
4759 : }
|