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