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 2254 : 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 2254 : Word16 interpolator_tbl[JBM_CLDFB_SLOTS_IN_SUBFRAME] = { 8192, 16384, 24576, MAX16B }; /* idx / JBM_CLDFB_SLOTS_IN_SUBFRAME Q15 */
105 2254 : move16();
106 2254 : move16();
107 2254 : move16();
108 2254 : move16();
109 :
110 : /* pointers to structs for allocation */
111 2254 : DIRAC_OUTPUT_SYNTHESIS_PARAMS *dirac_output_synthesis_params = &( hDirACRend->h_output_synthesis_psd_params );
112 2254 : DIRAC_OUTPUT_SYNTHESIS_STATE *dirac_output_synthesis_state = &( hDirACRend->h_output_synthesis_psd_state );
113 :
114 : /* check / set input parameters */
115 2254 : assert( hSpatParamRendCom->num_freq_bands > 0 && "Error: Number of frequency bands <= 0!" );
116 2254 : assert( hDirACRend->hOutSetup.nchan_out_woLFE > 0 && "Error: Number of output channels > 0!" );
117 2254 : assert( hDirACRend->num_outputs_diff > 0 );
118 2254 : assert( hSpatParamRendCom->slot_size > 0 );
119 2254 : assert( hDirACRend->hOutSetup.is_loudspeaker_setup == 0 || hDirACRend->hOutSetup.is_loudspeaker_setup == 1 );
120 2254 : assert( hDirACRend->diffuse_response_function_fx != NULL );
121 :
122 2254 : IF( hDirACRend->proto_signal_decorr_on )
123 : {
124 2097 : dirac_output_synthesis_params->max_band_decorr = hDirACRend->h_freq_domain_decorr_ap_params->max_band_decorr;
125 2097 : move16();
126 : }
127 : ELSE
128 : {
129 157 : dirac_output_synthesis_params->max_band_decorr = 0;
130 157 : move16();
131 : }
132 :
133 : /*-----------------------------------------------------------------*
134 : * memory allocation
135 : *-----------------------------------------------------------------*/
136 :
137 2254 : dirac_output_synthesis_state->diffuse_responses_square_fx = NULL;
138 :
139 2254 : 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 2143 : ELSE IF( NE_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) )
147 : {
148 1308 : 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 2254 : dirac_output_synthesis_state->proto_power_smooth_prev_fx = NULL;
156 :
157 2254 : IF( NE_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) )
158 : {
159 1419 : 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 1419 : dirac_output_synthesis_state->proto_power_smooth_prev_len = imult1616( hSpatParamRendCom->num_freq_bands, hDirACRend->num_protos_dir );
164 1419 : move16();
165 : }
166 2254 : test();
167 2254 : test();
168 2254 : 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 1262 : 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 1262 : dirac_output_synthesis_state->proto_power_diff_smooth_prev_len = imult1616( dirac_output_synthesis_params->max_band_decorr, hDirACRend->hOutSetup.nchan_out_woLFE );
175 1262 : move16();
176 : }
177 : ELSE
178 : {
179 992 : dirac_output_synthesis_state->proto_power_diff_smooth_prev_fx = NULL;
180 : }
181 :
182 : /* buffer length and interpolator */
183 2254 : 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 2254 : 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 2142 : size = imult1616( hSpatParamRendCom->num_freq_bands, hDirACRend->num_outputs_dir );
196 : }
197 2254 : 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 2254 : dirac_output_synthesis_state->cy_cross_dir_smooth_prev_len = size;
202 2254 : move16();
203 :
204 2254 : 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 2254 : IF( EQ_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) )
210 : {
211 835 : dirac_output_synthesis_state->cy_auto_dir_smooth_prev_fx = NULL;
212 835 : 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 835 : dirac_output_synthesis_state->cy_auto_dir_smooth_prev_len = imult1616( dirac_output_synthesis_params->max_band_decorr, hDirACRend->num_outputs_diff );
217 835 : move16();
218 : }
219 : ELSE
220 : {
221 1419 : 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 1419 : dirac_output_synthesis_state->cy_auto_dir_smooth_prev_len = imult1616( hSpatParamRendCom->num_freq_bands, hDirACRend->num_outputs_dir );
226 1419 : move16();
227 :
228 1419 : 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 1007 : 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 1007 : dirac_output_synthesis_state->cy_auto_diff_smooth_prev_len = imult1616( hSpatParamRendCom->num_freq_bands, hDirACRend->num_outputs_diff );
244 1007 : move16();
245 : }
246 : }
247 :
248 : /* direct and diffuse gain buffers */
249 2254 : 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 2254 : dirac_output_synthesis_state->gains_dir_prev_len = size;
254 2254 : move16();
255 2254 : test();
256 2254 : IF( EQ_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) )
257 : {
258 835 : 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 835 : dirac_output_synthesis_state->gains_diff_prev_len = imult1616( dirac_output_synthesis_params->max_band_decorr, hDirACRend->num_outputs_diff );
263 835 : move16();
264 : }
265 1419 : ELSE IF( NE_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_PSD_SHD ) && NE_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_MONO ) )
266 : {
267 896 : 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 896 : dirac_output_synthesis_state->gains_diff_prev_len = imult1616( hSpatParamRendCom->num_freq_bands, hDirACRend->num_outputs_diff );
272 896 : 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 2254 : test();
290 2254 : test();
291 2254 : 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 1419 : 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 1419 : 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 1419 : Copy( temp_alpha_synthesis_fx, dirac_output_synthesis_params->alpha_synthesis_fx, dirac_output_synthesis_params->numAlphas ); /*q15*/
300 :
301 1419 : 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 1419 : 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 1419 : Copy( temp_alpha_synthesis_fx, dirac_output_synthesis_params->alpha_synthesis_fast_fx, dirac_output_synthesis_params->numAlphasFast ); /*q15*/
308 :
309 1419 : 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 1419 : set32_fx( dirac_output_synthesis_state->reference_power_smooth_prev_fx, 0, hSpatParamRendCom->num_freq_bands );
314 1419 : dirac_output_synthesis_state->reference_power_smooth_prev_q[0] = Q31;
315 1419 : dirac_output_synthesis_state->reference_power_smooth_prev_q[1] = Q31;
316 1419 : move16();
317 1419 : move16();
318 :
319 1419 : IF( ( dirac_output_synthesis_state->direction_smoothness_prev_fx = (Word32 *) malloc( hSpatParamRendCom->num_freq_bands * sizeof( Word32 ) ) ) == NULL )
320 : {
321 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
322 : }
323 1419 : set32_fx( dirac_output_synthesis_state->direction_smoothness_prev_fx, 0, hSpatParamRendCom->num_freq_bands );
324 : }
325 : ELSE
326 : {
327 835 : dirac_output_synthesis_params->alpha_synthesis_fx = NULL;
328 835 : dirac_output_synthesis_params->alpha_synthesis_fast_fx = NULL;
329 835 : dirac_output_synthesis_state->reference_power_smooth_prev_fx = NULL;
330 835 : dirac_output_synthesis_state->direction_smoothness_prev_fx = NULL;
331 : }
332 :
333 : /* compute interpolator */
334 11270 : FOR( idx = 1; idx <= JBM_CLDFB_SLOTS_IN_SUBFRAME; ++idx )
335 : {
336 9016 : dirac_output_synthesis_params->interpolator_fx[idx - 1] = interpolator_tbl[idx - 1]; /* Q15 */
337 9016 : move16();
338 : }
339 :
340 : /* prepare diffuse response function */
341 2254 : IF( EQ_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_MONO ) )
342 : {
343 111 : num_diffuse_responses = 2;
344 111 : move16();
345 : }
346 : ELSE
347 : {
348 2143 : num_diffuse_responses = hDirACRend->hOutSetup.nchan_out_woLFE;
349 2143 : move16();
350 : }
351 :
352 2254 : IF( dirac_output_synthesis_state->diffuse_responses_square_fx != NULL )
353 : {
354 13050 : FOR( ch_idx = 0; ch_idx < num_diffuse_responses; ++ch_idx )
355 : {
356 : /*dirac_output_synthesis_state->diffuse_responses_square[ch_idx] = pow(dirac_output_synthesis_params->diffuse_response_function[ch_idx]/max_response, 2.0f);*/
357 11631 : tmp_fx = hDirACRend->diffuse_response_function_fx[ch_idx]; /*q15*/
358 11631 : move16();
359 :
360 11631 : dirac_output_synthesis_state->diffuse_responses_square_fx[ch_idx] = L_mult( tmp_fx, tmp_fx ); /* Q15 + Q15 + 1 -> Q31 */
361 11631 : move32();
362 : }
363 : }
364 :
365 :
366 2254 : IF( EQ_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) )
367 : {
368 : Word16 diff_compensation_order;
369 : Word32 diff_nrg_total_fx, diff_nrg_fx, diff_nrg_trans_fx, diff_nrg_decorr_fx;
370 :
371 : /* compensate missing diffuseness modelling up order 2, except for HR*/
372 835 : IF( GE_16( nchan_transport, 3 ) )
373 : {
374 826 : diff_compensation_order = 3;
375 826 : move16();
376 : }
377 : ELSE
378 : {
379 9 : diff_compensation_order = 2;
380 9 : move16();
381 : }
382 835 : diff_compensation_order = s_min( diff_compensation_order, hDirACRend->hOutSetup.ambisonics_order );
383 :
384 835 : diff_nrg_total_fx = 0;
385 835 : move32();
386 835 : diff_nrg_trans_fx = 0;
387 835 : move32();
388 835 : diff_nrg_decorr_fx = 0;
389 835 : move32();
390 :
391 835 : Word16 gaurd_bits = find_guarded_bits_fx( imult1616( add( diff_compensation_order, 1 ), add( diff_compensation_order, 1 ) ) );
392 835 : tmp16 = add( diff_compensation_order, 1 );
393 835 : tmp16 = imult1616( tmp16, tmp16 );
394 12331 : FOR( ch_idx = 0; ch_idx < tmp16; ch_idx++ )
395 : {
396 11496 : 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
397 :
398 11496 : diff_nrg_total_fx = L_add( diff_nrg_total_fx, diff_nrg_fx ); // Q30 - gaurd_bits
399 :
400 : /* is it a transport channel?*/
401 11496 : test();
402 11496 : if ( ch_idx == 0 || hDirACRend->proto_index_dir[ch_idx] != 0 )
403 : {
404 4042 : diff_nrg_trans_fx = L_add( diff_nrg_trans_fx, diff_nrg_fx ); // Q30 - gaurd_bits
405 : }
406 : /* is it a decorrelated or transport channel?*/
407 11496 : if ( LT_16( ch_idx, hDirACRend->num_outputs_diff ) )
408 : {
409 3340 : diff_nrg_decorr_fx = L_add( diff_nrg_decorr_fx, diff_nrg_fx ); // Q30 - gaurd_bits
410 : }
411 : }
412 835 : Word16 exp_1 = 0, exp_2 = 0, tmp;
413 835 : move16();
414 835 : move16();
415 835 : tmp = BASOP_Util_Divide3232_Scale( diff_nrg_total_fx, diff_nrg_trans_fx, &exp_1 ); // Q(15 - exp_1)
416 835 : dirac_output_synthesis_params->diffuse_compensation_factor_fx = L_shl( L_deposit_l( tmp ), add( Q12, exp_1 ) ); // Q27
417 835 : move32();
418 :
419 835 : tmp = BASOP_Util_Divide3232_Scale( diff_nrg_total_fx, diff_nrg_decorr_fx, &exp_2 ); // (Q15 - exp_2)
420 835 : dirac_output_synthesis_params->diffuse_compensation_factor_decorr_fx = L_shl( L_deposit_l( tmp ), add( Q14, exp_2 ) ); // Q29
421 835 : move32();
422 : }
423 : ELSE
424 : {
425 1419 : dirac_output_synthesis_params->diffuse_compensation_factor_fx = 0;
426 1419 : move32();
427 1419 : dirac_output_synthesis_params->diffuse_compensation_factor_decorr_fx = 0;
428 1419 : move32();
429 : }
430 :
431 2254 : return IVAS_ERR_OK;
432 : }
433 :
434 :
435 : /*-------------------------------------------------------------------------
436 : * ivas_dirac_dec_output_synthesis_init()
437 : *
438 : *
439 : *------------------------------------------------------------------------*/
440 :
441 2277 : void ivas_dirac_dec_output_synthesis_init_fx(
442 : SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common spatial renderer data handle */
443 : DIRAC_REND_HANDLE hDirACRend, /* i/o: DirAC renderer handle */
444 : const Word16 nchan_out_woLFE, /* i : number of output audio channels without LFE */
445 : const Word16 hodirac_flag /* i : flag to indicate HO-DirAC mode */
446 : )
447 : {
448 : Word16 size;
449 :
450 : DIRAC_OUTPUT_SYNTHESIS_PARAMS *h_dirac_output_synthesis_params;
451 : DIRAC_OUTPUT_SYNTHESIS_STATE *h_dirac_output_synthesis_state;
452 :
453 2277 : h_dirac_output_synthesis_params = &( hDirACRend->h_output_synthesis_psd_params );
454 2277 : h_dirac_output_synthesis_state = &( hDirACRend->h_output_synthesis_psd_state );
455 :
456 : /*-----------------------------------------------------------------*
457 : * init outputSynthesisPSD_Init
458 : *-----------------------------------------------------------------*/
459 :
460 : /* initialize buffers */
461 2277 : IF( h_dirac_output_synthesis_state->cy_auto_dir_smooth_prev_fx != NULL )
462 : {
463 1419 : set32_fx( h_dirac_output_synthesis_state->cy_auto_dir_smooth_prev_fx, 0, imult1616( hSpatParamRendCom->num_freq_bands, hDirACRend->num_outputs_dir ) );
464 : }
465 2277 : h_dirac_output_synthesis_state->q_cy_auto_dir_smooth_prev = 0;
466 2277 : move16();
467 :
468 2277 : IF( hodirac_flag )
469 : {
470 112 : size = imult1616( imult1616( hSpatParamRendCom->num_freq_bands, hDirACRend->num_outputs_dir ), DIRAC_HO_NUMSECTORS );
471 : }
472 : ELSE
473 : {
474 2165 : size = imult1616( hSpatParamRendCom->num_freq_bands, hDirACRend->num_outputs_dir );
475 : }
476 2277 : set32_fx( h_dirac_output_synthesis_state->cy_cross_dir_smooth_prev_fx, 0, size );
477 2277 : h_dirac_output_synthesis_state->q_cy_cross_dir_smooth_prev = 0;
478 2277 : move16();
479 :
480 2277 : IF( EQ_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) )
481 : {
482 858 : 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 ) );
483 : }
484 1419 : ELSE IF( NE_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_PSD_SHD ) )
485 : {
486 1007 : set32_fx( h_dirac_output_synthesis_state->cy_auto_diff_smooth_prev_fx, 0, imult1616( hSpatParamRendCom->num_freq_bands, hDirACRend->num_outputs_diff ) );
487 : }
488 : ELSE
489 : {
490 412 : set32_fx( h_dirac_output_synthesis_state->cy_auto_diff_smooth_prev_fx, 0, imult1616( hSpatParamRendCom->num_freq_bands, hDirACRend->num_outputs_dir ) );
491 : }
492 2277 : h_dirac_output_synthesis_state->q_cy_auto_diff_smooth_prev = 0;
493 2277 : move16();
494 :
495 2277 : IF( h_dirac_output_synthesis_state->proto_power_smooth_prev_fx != NULL )
496 : {
497 1419 : set32_fx( h_dirac_output_synthesis_state->proto_power_smooth_prev_fx, 0, imult1616( hSpatParamRendCom->num_freq_bands, hDirACRend->num_protos_dir ) );
498 1419 : h_dirac_output_synthesis_state->proto_power_smooth_prev_q[0] = Q31;
499 1419 : h_dirac_output_synthesis_state->proto_power_smooth_prev_q[1] = Q31;
500 1419 : move16();
501 1419 : move16();
502 : }
503 2277 : set32_fx( h_dirac_output_synthesis_state->gains_dir_prev_fx, 0, size );
504 2277 : h_dirac_output_synthesis_state->gains_dir_prev_q = 0;
505 2277 : move16();
506 :
507 2277 : IF( EQ_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) )
508 : {
509 858 : 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 ) );
510 : }
511 : ELSE
512 : {
513 1419 : set32_fx( h_dirac_output_synthesis_state->gains_diff_prev_fx, 0, imult1616( hSpatParamRendCom->num_freq_bands, hDirACRend->num_outputs_dir ) );
514 : }
515 2277 : h_dirac_output_synthesis_state->gains_diff_prev_q = 0;
516 2277 : move16();
517 :
518 2277 : IF( h_dirac_output_synthesis_state->proto_power_diff_smooth_prev_fx != NULL )
519 : {
520 1262 : 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 ) );
521 : }
522 2277 : h_dirac_output_synthesis_state->proto_power_diff_smooth_prev_q = Q31;
523 2277 : move16();
524 :
525 2277 : return;
526 : }
527 :
528 :
529 : /*-------------------------------------------------------------------------
530 : * ivas_dirac_dec_output_synthesis_close()
531 : *
532 : * Memory deallocation of Output synthesis sub-module
533 : *------------------------------------------------------------------------*/
534 :
535 2254 : void ivas_dirac_dec_output_synthesis_close_fx(
536 : DIRAC_REND_HANDLE hDirACRend /* i/o: DirAC handle */
537 : )
538 : {
539 : /* pointers to structs for allocation */
540 2254 : DIRAC_OUTPUT_SYNTHESIS_PARAMS *dirac_output_synthesis_params = &( hDirACRend->h_output_synthesis_psd_params );
541 2254 : DIRAC_OUTPUT_SYNTHESIS_STATE *dirac_output_synthesis_state = &( hDirACRend->h_output_synthesis_psd_state );
542 :
543 : /*-----------------------------------------------------------------*
544 : * memory deallocation
545 : *-----------------------------------------------------------------*/
546 :
547 : /* free interpolator */
548 2254 : IF( ( dirac_output_synthesis_params )->interpolator_fx != NULL )
549 : {
550 2254 : free( ( dirac_output_synthesis_params )->interpolator_fx );
551 2254 : ( dirac_output_synthesis_params )->interpolator_fx = NULL;
552 : }
553 :
554 : /* free alpha */
555 2254 : IF( ( dirac_output_synthesis_params )->alpha_synthesis_fx != NULL )
556 : {
557 1419 : free( ( dirac_output_synthesis_params )->alpha_synthesis_fx );
558 1419 : ( dirac_output_synthesis_params )->alpha_synthesis_fx = NULL;
559 : }
560 2254 : IF( ( dirac_output_synthesis_params )->alpha_synthesis_fast_fx != NULL )
561 : {
562 1419 : free( ( dirac_output_synthesis_params )->alpha_synthesis_fast_fx );
563 1419 : ( dirac_output_synthesis_params )->alpha_synthesis_fast_fx = NULL;
564 : }
565 :
566 2254 : IF( ( dirac_output_synthesis_state )->reference_power_smooth_prev_fx != NULL )
567 : {
568 1419 : free( ( dirac_output_synthesis_state )->reference_power_smooth_prev_fx );
569 1419 : ( dirac_output_synthesis_state )->reference_power_smooth_prev_fx = NULL;
570 : }
571 :
572 2254 : IF( ( dirac_output_synthesis_state )->direction_smoothness_prev_fx != NULL )
573 : {
574 1419 : free( ( dirac_output_synthesis_state )->direction_smoothness_prev_fx );
575 1419 : ( dirac_output_synthesis_state )->direction_smoothness_prev_fx = NULL;
576 : }
577 :
578 2254 : IF( ( dirac_output_synthesis_state )->diffuse_responses_square_fx != NULL )
579 : {
580 1419 : free( ( dirac_output_synthesis_state )->diffuse_responses_square_fx );
581 1419 : ( dirac_output_synthesis_state )->diffuse_responses_square_fx = NULL;
582 : }
583 :
584 : /* free power buffers */
585 2254 : IF( ( dirac_output_synthesis_state )->proto_power_smooth_prev_fx != NULL )
586 : {
587 1419 : free( ( dirac_output_synthesis_state )->proto_power_smooth_prev_fx );
588 1419 : ( dirac_output_synthesis_state )->proto_power_smooth_prev_fx = NULL;
589 : }
590 :
591 2254 : IF( ( dirac_output_synthesis_state )->proto_power_diff_smooth_prev_fx != NULL )
592 : {
593 1262 : free( ( dirac_output_synthesis_state )->proto_power_diff_smooth_prev_fx );
594 1262 : ( dirac_output_synthesis_state )->proto_power_diff_smooth_prev_fx = NULL;
595 : }
596 :
597 : /* free target power buffers */
598 2254 : IF( ( dirac_output_synthesis_state )->cy_auto_dir_smooth_prev_fx != NULL )
599 : {
600 1419 : free( ( dirac_output_synthesis_state )->cy_auto_dir_smooth_prev_fx );
601 1419 : ( dirac_output_synthesis_state )->cy_auto_dir_smooth_prev_fx = NULL;
602 : }
603 2254 : IF( ( dirac_output_synthesis_state )->cy_cross_dir_smooth_prev_fx != NULL )
604 : {
605 2254 : free( ( dirac_output_synthesis_state )->cy_cross_dir_smooth_prev_fx );
606 2254 : ( dirac_output_synthesis_state )->cy_cross_dir_smooth_prev_fx = NULL;
607 : }
608 2254 : IF( ( dirac_output_synthesis_state )->Q_temp_cy_cross_dir_smooth_fx != NULL )
609 : {
610 2254 : free( ( dirac_output_synthesis_state )->Q_temp_cy_cross_dir_smooth_fx );
611 2254 : ( dirac_output_synthesis_state )->Q_temp_cy_cross_dir_smooth_fx = NULL;
612 : }
613 2254 : IF( ( dirac_output_synthesis_state )->cy_auto_diff_smooth_prev_fx != NULL )
614 : {
615 2254 : free( ( dirac_output_synthesis_state )->cy_auto_diff_smooth_prev_fx );
616 2254 : ( dirac_output_synthesis_state )->cy_auto_diff_smooth_prev_fx = NULL;
617 : }
618 :
619 : /* free gain buffers */
620 2254 : IF( ( dirac_output_synthesis_state )->gains_dir_prev_fx != NULL )
621 : {
622 2254 : free( ( dirac_output_synthesis_state )->gains_dir_prev_fx );
623 2254 : ( dirac_output_synthesis_state )->gains_dir_prev_fx = NULL;
624 : }
625 2254 : IF( ( dirac_output_synthesis_state )->gains_diff_prev_fx != NULL )
626 : {
627 2254 : free( ( dirac_output_synthesis_state )->gains_diff_prev_fx );
628 2254 : ( dirac_output_synthesis_state )->gains_diff_prev_fx = NULL;
629 : }
630 2254 : return;
631 : }
632 :
633 :
634 : /*-------------------------------------------------------------------------
635 : * ivas_dirac_dec_output_synthesis_process_slot()
636 : *
637 : *
638 : *------------------------------------------------------------------------*/
639 :
640 1304655 : void ivas_dirac_dec_output_synthesis_process_slot_fx(
641 : const Word32 *reference_power, /* i : Estimated power Q(q_reference_power)*/
642 : const Word16 *q_reference_power, /* i : Estimated power Q */
643 : const Word32 *onset, /* i : onset filter Q31*/
644 : const Word16 *azimuth,
645 : const Word16 *elevation,
646 : const Word32 *diffuseness, /* Q(q_diffuseness)*/
647 : Word16 q_diffuseness,
648 : SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common spatial renderer data handle */
649 : DIRAC_REND_HANDLE hDirACRend, /* i/o: DirAC renderer handle */
650 : const VBAP_HANDLE hVBAPdata, /* i : VBAP structure */
651 : const IVAS_OUTPUT_SETUP hOutSetup, /* i : output setup structure */
652 : const Word16 nchan_transport, /* i : number of transport channels*/
653 : const Word16 md_idx,
654 : const Word16 hodirac_flag, /* i : flag to indicate HO-DirAC mode */
655 : const Word16 dec_param_estim )
656 : {
657 : Word16 num_freq_bands, num_channels_dir;
658 : Word16 num_freq_bands_diff, num_channels_diff;
659 : Word16 ch_idx;
660 : Word32 aux_buf[CLDFB_NO_CHANNELS_MAX];
661 : Word16 diff_start_band;
662 : DIRAC_OUTPUT_SYNTHESIS_PARAMS *h_dirac_output_synthesis_params;
663 : DIRAC_OUTPUT_SYNTHESIS_STATE *h_dirac_output_synthesis_state;
664 :
665 1304655 : h_dirac_output_synthesis_params = &( hDirACRend->h_output_synthesis_psd_params );
666 1304655 : h_dirac_output_synthesis_state = &( hDirACRend->h_output_synthesis_psd_state );
667 :
668 1304655 : h_dirac_output_synthesis_state->onset_filter_fx = onset; /*Q31*/
669 :
670 : /*-----------------------------------------------------------------*
671 : * processing
672 : *-----------------------------------------------------------------*/
673 :
674 : /* collect some often used parameters */
675 1304655 : num_freq_bands = hSpatParamRendCom->num_freq_bands;
676 1304655 : move16();
677 1304655 : num_channels_dir = hDirACRend->num_outputs_dir;
678 1304655 : move16();
679 1304655 : num_channels_diff = hDirACRend->num_outputs_diff;
680 1304655 : move16();
681 1304655 : num_freq_bands_diff = h_dirac_output_synthesis_params->max_band_decorr;
682 1304655 : move16();
683 :
684 1304655 : IF( EQ_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_PSD_LS ) )
685 : {
686 269809 : num_channels_dir = hOutSetup.nchan_out_woLFE;
687 269809 : move16();
688 : }
689 :
690 1304655 : test();
691 1304655 : IF( EQ_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) && hodirac_flag )
692 : {
693 212624 : ivas_dirac_dec_compute_directional_responses_fx( hSpatParamRendCom,
694 : hDirACRend,
695 : hVBAPdata,
696 : NULL,
697 : NULL,
698 : azimuth,
699 : elevation,
700 : md_idx,
701 : NULL,
702 : 0,
703 : hodirac_flag );
704 : {
705 :
706 212624 : IF( h_dirac_output_synthesis_state->direct_responses_square_fx )
707 : {
708 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*/
709 0 : h_dirac_output_synthesis_state->direct_responses_square_q = 31;
710 0 : move16();
711 : }
712 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*/
713 212624 : IF( hodirac_flag )
714 : {
715 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*/
716 : }
717 212624 : h_dirac_output_synthesis_state->direct_responses_q = 31;
718 212624 : move16();
719 : }
720 : }
721 :
722 1304655 : test();
723 1304655 : IF( dec_param_estim == FALSE && hodirac_flag )
724 : {
725 212624 : IF( EQ_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) )
726 : {
727 212624 : v_multc_fixed( hSpatParamRendCom->energy_ratio1_fx[md_idx], -MAX_32 /*-1 Q31*/, aux_buf, num_freq_bands ); /* 30 + 31 - 31 -> 30 */
728 212624 : v_addc_fixed( aux_buf, ONE_IN_Q30 /*1 Q30*/, aux_buf, num_freq_bands ); /*30*/
729 212624 : Copy32( hSpatParamRendCom->energy_ratio1_fx[md_idx],
730 : h_dirac_output_synthesis_state->direct_power_factor_fx,
731 : num_freq_bands ); /*Q30*/
732 212624 : Copy32( aux_buf,
733 : h_dirac_output_synthesis_state->diffuse_power_factor_fx,
734 : num_freq_bands ); /*Q30*/
735 :
736 212624 : v_multc_fixed( hSpatParamRendCom->energy_ratio2_fx[md_idx], -MAX_32 /*-1 Q31*/, aux_buf, num_freq_bands ); /*30+31-31->30*/
737 212624 : v_addc_fixed( aux_buf, ONE_IN_Q30 /*1 Q30*/, aux_buf, num_freq_bands ); /*30*/
738 212624 : Copy32( hSpatParamRendCom->energy_ratio2_fx[md_idx],
739 212624 : &h_dirac_output_synthesis_state->direct_power_factor_fx[hSpatParamRendCom->num_freq_bands],
740 : num_freq_bands ); /*Q30*/
741 212624 : Copy32( aux_buf,
742 212624 : &h_dirac_output_synthesis_state->diffuse_power_factor_fx[hSpatParamRendCom->num_freq_bands],
743 : num_freq_bands ); /*Q30*/
744 :
745 212624 : h_dirac_output_synthesis_state->diffuse_power_factor_q = 30;
746 212624 : move16();
747 212624 : h_dirac_output_synthesis_state->direct_power_factor_q = 30;
748 212624 : move16();
749 : }
750 : ELSE
751 : {
752 0 : ivas_dirac_dec_compute_gain_factors_fx( num_freq_bands,
753 0 : hSpatParamRendCom->diffuseness_vector_fx[md_idx],
754 : h_dirac_output_synthesis_state->direct_power_factor_fx,
755 : h_dirac_output_synthesis_state->diffuse_power_factor_fx,
756 : &h_dirac_output_synthesis_state->direct_power_factor_q,
757 : &h_dirac_output_synthesis_state->diffuse_power_factor_q );
758 : }
759 : }
760 1092031 : ELSE IF( EQ_16( dec_param_estim, TRUE ) )
761 : {
762 : /* compute direct responses */
763 730303 : ivas_dirac_dec_compute_directional_responses_fx( hSpatParamRendCom,
764 : hDirACRend,
765 : hVBAPdata,
766 : NULL,
767 : NULL,
768 : azimuth,
769 : elevation,
770 : md_idx,
771 : NULL,
772 : 0,
773 : hodirac_flag );
774 :
775 : {
776 730303 : IF( h_dirac_output_synthesis_state->direct_responses_square_fx )
777 : {
778 56000 : 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*/
779 56000 : h_dirac_output_synthesis_state->direct_responses_square_q = 31;
780 56000 : move16();
781 : }
782 730303 : 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*/
783 730303 : IF( hodirac_flag )
784 : {
785 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*/
786 : }
787 730303 : h_dirac_output_synthesis_state->direct_responses_q = 31;
788 730303 : move16();
789 : }
790 :
791 730303 : IF( EQ_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) )
792 : {
793 674303 : ivas_dirac_dec_compute_gain_factors_fx( num_freq_bands,
794 : diffuseness,
795 : h_dirac_output_synthesis_state->direct_power_factor_fx,
796 : h_dirac_output_synthesis_state->diffuse_power_factor_fx,
797 : &h_dirac_output_synthesis_state->direct_power_factor_q,
798 : &h_dirac_output_synthesis_state->diffuse_power_factor_q );
799 674303 : h_dirac_output_synthesis_state->direct_power_factor_q = sub( 31, h_dirac_output_synthesis_state->direct_power_factor_q );
800 674303 : h_dirac_output_synthesis_state->diffuse_power_factor_q = sub( 31, h_dirac_output_synthesis_state->diffuse_power_factor_q );
801 :
802 674303 : v_multc_fixed( h_dirac_output_synthesis_state->direct_power_factor_fx,
803 : ONE_IN_Q29 /*0.25f Q31*/,
804 : h_dirac_output_synthesis_state->direct_power_factor_fx,
805 : num_freq_bands ); /*h_dirac_output_synthesis_state->direct_power_factor_q+Q31-Q31->h_dirac_output_synthesis_state->direct_power_factor_q*/
806 674303 : v_multc_fixed( h_dirac_output_synthesis_state->diffuse_power_factor_fx,
807 : ONE_IN_Q29 /*0.25f Q31*/,
808 : h_dirac_output_synthesis_state->diffuse_power_factor_fx,
809 : num_freq_bands ); /*h_dirac_output_synthesis_state->diffuse_power_factor_q+Q31-Q31->h_dirac_output_synthesis_state->diffuse_power_factor_q*/
810 : /*Direct gain*/
811 :
812 674303 : Word16 *exp_temp_cy_cross_dir_smooth_fx = (Word16 *) malloc( num_freq_bands * num_channels_dir * sizeof( Word16 ) );
813 674303 : Word16 cy_cross_dir_smooth_e = sub( 31, h_dirac_output_synthesis_state->q_cy_cross_dir_smooth );
814 :
815 529513343 : FOR( Word16 kk = 0; kk < ( num_freq_bands * num_channels_dir ); kk++ )
816 : {
817 528839040 : exp_temp_cy_cross_dir_smooth_fx[kk] = cy_cross_dir_smooth_e; // h_dirac_output_synthesis_state->q_cy_cross_dir_smooth;
818 528839040 : move16();
819 : }
820 :
821 674303 : Word16 q_temp = sub( add( shl( h_dirac_output_synthesis_state->direct_responses_q, 1 ), q_diffuseness ), 62 );
822 674303 : Word32 one_in_qdiff = L_shl( 1, q_diffuseness );
823 674303 : 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*/
824 674303 : Word16 q_diff_c = sub( q_diffuseness, 2 );
825 :
826 3371515 : FOR( ch_idx = 0; ch_idx < s_min( 4, nchan_transport ); ch_idx++ )
827 : {
828 : Word16 k;
829 2697212 : IF( ch_idx != 0 )
830 : {
831 : Word32 a, c;
832 : Word16 b, b_exp, sqr_exp, q_diff_aab; // , q_diff_c;
833 : Word32 mpy_a_a_b, mpy_diff_c, mpy_diff_aab;
834 : Word32 sqr_inp, sqr;
835 :
836 : /*Directonal sound gain nrg compensation*/
837 12137454 : FOR( k = 0; k < num_freq_bands_diff; k++ )
838 : {
839 10114545 : a = h_dirac_output_synthesis_state->direct_responses_fx[ch_idx * num_freq_bands + k]; // Q = h_dirac_output_synthesis_state->q_direct_responses
840 10114545 : move32();
841 :
842 :
843 10114545 : b_exp = 0;
844 10114545 : move16();
845 :
846 10114545 : b = 0;
847 10114545 : move16();
848 :
849 10114545 : if ( 0 == reference_power[k + ( ch_idx + 1 ) * num_freq_bands] )
850 : {
851 582105 : b = MAX_16;
852 582105 : move16();
853 : }
854 :
855 10114545 : test();
856 10114545 : IF( reference_power[k + ( ch_idx + 1 ) * num_freq_bands] && reference_power[k + num_freq_bands] )
857 : {
858 9523003 : 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)*/
859 : }
860 :
861 :
862 10114545 : 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
863 10114545 : 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
864 10114545 : mpy_diff_c = Mpy_32_32( diffuseness[k], c1 ); // Q(q_diff_c) = q_diffuseness - 2
865 :
866 10114545 : 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 ) ) );
867 :
868 10114545 : Word16 minq = sub( s_min( q_diff_aab, q_diff_c ), 1 );
869 10114545 : Word32 op1 = L_shr( mpy_diff_aab, sub( q_diff_aab, minq ) );
870 10114545 : Word32 op2 = L_shr( mpy_diff_c, sub( q_diff_c, minq ) );
871 10114545 : sqr_inp = L_add( op1, op2 );
872 10114545 : sqr_exp = sub( 31, minq );
873 10114545 : sqr = Sqrt32( sqr_inp, &sqr_exp ); /*Q(31-sqr_exp)*/
874 10114545 : sqr = L_shr( sqr, 2 ); /*Q(31-sqr_exp)*/
875 10114545 : IF( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] != 0 )
876 : {
877 7543388 : IF( GT_16( sqr_exp, cy_cross_dir_smooth_e ) )
878 : {
879 32625 : 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) */
880 32625 : move32();
881 32625 : exp_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = sqr_exp; // sub( 31, sqr_exp );
882 32625 : move16();
883 : }
884 : ELSE
885 : {
886 7510763 : 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*/
887 : }
888 7543388 : 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*/
889 7543388 : move32();
890 : }
891 : ELSE
892 : {
893 2571157 : 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*/
894 2571157 : move32();
895 2571157 : exp_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = sqr_exp; // sub( 31, sqr_exp );
896 2571157 : move16();
897 : }
898 : }
899 2022909 : 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*/
900 2022909 : Word16 diff_c_exp = sub( q_diffuseness, 4 );
901 94492884 : FOR( ; k < num_freq_bands; k++ )
902 : {
903 92469975 : a = h_dirac_output_synthesis_state->direct_responses_fx[ch_idx * num_freq_bands + k]; // Q = h_dirac_output_synthesis_state->q_direct_responses
904 92469975 : move32();
905 92469975 : IF( reference_power[k + num_freq_bands] == 0 )
906 : {
907 18976818 : sqr_inp = Mpy_32_32( diffuseness[k], c );
908 18976818 : sqr_exp = sub( 31 + 4, q_diffuseness );
909 : }
910 : ELSE
911 : {
912 : Word16 diff_aab_exp;
913 73493157 : IF( reference_power[k + ( ch_idx + 1 ) * num_freq_bands] == 0 )
914 : {
915 14620162 : 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
916 14620162 : 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
917 14620162 : mpy_diff_c = Mpy_32_32( diffuseness[k], c ); // Q = q_diffuseness - 4
918 14620162 : diff_aab_exp = q_temp;
919 14620162 : move16();
920 : }
921 : ELSE
922 : {
923 58872995 : 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)*/
924 :
925 58872995 : 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
926 58872995 : 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
927 58872995 : mpy_diff_c = Mpy_32_32( diffuseness[k], c ); // Q = q_diffuseness - 4
928 58872995 : 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);
929 : }
930 73493157 : Word16 minq = sub( s_min( diff_aab_exp, diff_c_exp ), 1 );
931 73493157 : Word32 op1 = L_shr( mpy_diff_aab, sub( diff_aab_exp, minq ) );
932 73493157 : Word32 op2 = L_shr( mpy_diff_c, sub( diff_c_exp, minq ) );
933 73493157 : sqr_inp = L_add( op1, op2 );
934 73493157 : sqr_exp = sub( 31, minq );
935 : }
936 92469975 : sqr = Sqrt32( sqr_inp, &sqr_exp ); /*Q(31-sqr_exp)*/
937 92469975 : sqr = L_shr( sqr, 2 ); /*Q(31-sqr_exp)*/
938 :
939 :
940 92469975 : IF( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] != 0 )
941 : {
942 66463030 : IF( GT_16( sqr_exp, cy_cross_dir_smooth_e ) )
943 : {
944 109454 : 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 )*/
945 109454 : move32();
946 109454 : exp_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = sqr_exp; // sub( 31, sqr_exp );
947 109454 : move16();
948 : }
949 : ELSE
950 : {
951 66353576 : 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*/
952 : }
953 66463030 : 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]*/
954 66463030 : move32();
955 : }
956 : ELSE
957 : {
958 26006945 : 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)*/
959 26006945 : move32();
960 26006945 : exp_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = sqr_exp;
961 26006945 : move16();
962 : }
963 : }
964 : }
965 : ELSE
966 : {
967 : Word32 sqr_inp, sqr;
968 : Word16 sqr_exp;
969 674303 : Word32 One_in_qdiff = L_shl( 1, sub( q_diffuseness, 1 ) );
970 674303 : 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
971 674303 : Word16 sq_e = sub( 32, q_diffuseness ); // 31-(q_diffuseness-1)
972 : /*Diffuseness modellling nrg compensation*/
973 4045818 : FOR( k = 0; k < num_freq_bands_diff; k++ )
974 : {
975 : /*diffuseness[k] * 0.5f * ( h_dirac_output_synthesis_params->diffuse_compensation_factor_decorr - 1.f ) )*/
976 3371515 : sqr_inp = Madd_32_32( One_in_qdiff, diffuseness[k], diff ); // Q = q_diffuseness - 1
977 3371515 : sqr_exp = sq_e;
978 3371515 : move16();
979 3371515 : sqr = Sqrt32( sqr_inp, &sqr_exp ); /*Q(31-sqr_exp)*/
980 3371515 : sqr = L_shr( sqr, 2 ); /*Q(31-sqr_exp)*/
981 3371515 : IF( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] != 0 )
982 : {
983 2521530 : IF( LT_16( cy_cross_dir_smooth_e, sqr_exp ) )
984 : {
985 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)*/
986 0 : move32();
987 0 : exp_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = sqr_exp; // sub( 31, sqr_exp );
988 0 : move16();
989 : }
990 : ELSE
991 : {
992 2521530 : 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*/
993 : }
994 2521530 : 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]*/
995 2521530 : move32();
996 : }
997 : ELSE
998 : {
999 849985 : h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = sqr; /*Q(31-sqr_exp)*/
1000 849985 : move32();
1001 849985 : exp_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = sqr_exp; // sub( 31, sqr_exp );
1002 849985 : move16();
1003 : }
1004 : }
1005 674303 : diff = L_sub( h_dirac_output_synthesis_params->diffuse_compensation_factor_fx, ONE_IN_Q27 /*1 Q27*/ );
1006 674303 : diff = L_shl( diff, 2 ); // Q29
1007 31497628 : FOR( ; k < num_freq_bands; k++ )
1008 : {
1009 30823325 : sqr_inp = Madd_32_32( One_in_qdiff, diffuseness[k], diff ); // Q = q_diffuseness - 1
1010 30823325 : sqr_exp = sq_e;
1011 30823325 : move16();
1012 30823325 : sqr = Sqrt32( sqr_inp, &sqr_exp ); /*Q(31-sqr_exp)*/
1013 30823325 : sqr = L_shr( sqr, 2 ); /*Q(31-sqr_exp)*/
1014 30823325 : IF( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] != 0 )
1015 : {
1016 23057950 : IF( GT_16( sqr_exp, cy_cross_dir_smooth_e ) )
1017 : {
1018 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 )*/
1019 0 : move32();
1020 0 : exp_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = sqr_exp; // sub( 31, sqr_exp );
1021 0 : move16();
1022 : }
1023 : ELSE
1024 : {
1025 23057950 : 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*/
1026 : }
1027 23057950 : 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]*/
1028 23057950 : move32();
1029 : }
1030 : ELSE
1031 : {
1032 7765375 : 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)*/
1033 7765375 : move32();
1034 7765375 : exp_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = sqr_exp;
1035 7765375 : move16();
1036 : }
1037 : }
1038 : }
1039 : }
1040 674303 : Word16 temp = exp_temp_cy_cross_dir_smooth_fx[0]; /*q0*/
1041 674303 : move16();
1042 528839040 : FOR( Word16 kk = 1; kk < ( num_freq_bands * num_channels_dir ); kk++ )
1043 : {
1044 528164737 : temp = s_max( exp_temp_cy_cross_dir_smooth_fx[kk], temp );
1045 : }
1046 :
1047 :
1048 : /*Directional gain (panning)*/
1049 674303 : Word16 temp_q = sub( add( h_dirac_output_synthesis_state->direct_power_factor_q, h_dirac_output_synthesis_state->direct_responses_q ), 31 );
1050 674303 : Word16 temp_exp = sub( 31, temp_q );
1051 :
1052 674303 : IF( LT_16( temp, temp_exp ) )
1053 : {
1054 0 : FOR( Word16 kk = 0; kk < ( num_freq_bands * num_channels_dir ); kk++ )
1055 : {
1056 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*/
1057 0 : move32();
1058 : }
1059 0 : h_dirac_output_synthesis_state->q_cy_cross_dir_smooth = temp_q;
1060 0 : move16();
1061 : }
1062 : ELSE
1063 : {
1064 529513343 : FOR( Word16 kk = 0; kk < ( num_freq_bands * num_channels_dir ); kk++ )
1065 : {
1066 528839040 : 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*/
1067 528839040 : move32();
1068 : }
1069 674303 : h_dirac_output_synthesis_state->q_cy_cross_dir_smooth = sub( 31, temp );
1070 674303 : move16();
1071 : }
1072 674303 : free( exp_temp_cy_cross_dir_smooth_fx );
1073 :
1074 674303 : Word16 temp_q1 = sub( h_dirac_output_synthesis_state->q_cy_cross_dir_smooth, temp_q );
1075 8420979 : FOR( ch_idx = s_min( 4, nchan_transport ); ch_idx < num_channels_dir; ch_idx++ )
1076 : {
1077 7746676 : IF( NE_16( temp_q, h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ) )
1078 : {
1079 : Word16 i;
1080 : Word32 aux;
1081 7727750 : IF( temp_q1 < 0 )
1082 : {
1083 7727750 : Word32 temp_q1_equiv = L_lshl( (Word32) 0x80000000, temp_q1 );
1084 398850110 : FOR( i = 0; i < num_freq_bands; i++ )
1085 : {
1086 391122360 : 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] );
1087 391122360 : 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 );
1088 391122360 : move32();
1089 : }
1090 : }
1091 : ELSE
1092 : {
1093 0 : FOR( i = 0; i < num_freq_bands; i++ )
1094 : {
1095 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] );
1096 0 : aux = L_shl( aux, temp_q1 );
1097 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 );
1098 0 : move32();
1099 : }
1100 : }
1101 : }
1102 : ELSE
1103 : {
1104 : Word16 i;
1105 956246 : FOR( i = 0; i < num_freq_bands; i++ )
1106 : {
1107 937320 : 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] );
1108 937320 : move32();
1109 : }
1110 : }
1111 : }
1112 :
1113 :
1114 : /*Diffuse gain*/
1115 674303 : FOR( ch_idx = s_min( 4, nchan_transport ); ch_idx < num_channels_diff; ch_idx++ )
1116 : {
1117 0 : v_multc_fixed_16( h_dirac_output_synthesis_state->diffuse_power_factor_fx,
1118 0 : hDirACRend->diffuse_response_function_fx[ch_idx],
1119 : aux_buf,
1120 : num_freq_bands_diff ); /* h_dirac_output_synthesis_state->diffuse_power_factor_q+15-15*/
1121 0 : temp_q = h_dirac_output_synthesis_state->diffuse_power_factor_q;
1122 0 : IF( NE_16( temp_q, h_dirac_output_synthesis_state->q_cy_auto_diff_smooth ) )
1123 : {
1124 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)*/
1125 : }
1126 0 : v_add_fixed_no_hdrm( aux_buf,
1127 0 : &h_dirac_output_synthesis_state->cy_auto_diff_smooth_fx[ch_idx * num_freq_bands_diff],
1128 0 : &h_dirac_output_synthesis_state->cy_auto_diff_smooth_fx[ch_idx * num_freq_bands_diff],
1129 : num_freq_bands_diff ); /*h_dirac_output_synthesis_state->q_cy_auto_diff_smooth*/
1130 : }
1131 :
1132 674303 : return;
1133 : }
1134 : ELSE
1135 : {
1136 : /* compute reference and diffuse power factor for this frame */
1137 56000 : ivas_dirac_dec_compute_power_factors_fx( num_freq_bands,
1138 : diffuseness,
1139 56000 : h_dirac_output_synthesis_params->max_band_decorr,
1140 : h_dirac_output_synthesis_state->direct_power_factor_fx,
1141 : h_dirac_output_synthesis_state->diffuse_power_factor_fx );
1142 :
1143 56000 : Scale_sig32( h_dirac_output_synthesis_state->direct_power_factor_fx, num_freq_bands, 2 ); /*q29->q31*/
1144 56000 : Scale_sig32( h_dirac_output_synthesis_state->diffuse_power_factor_fx, num_freq_bands, 2 ); /*q29->q31*/
1145 56000 : h_dirac_output_synthesis_state->diffuse_power_factor_q = 31;
1146 56000 : move16();
1147 56000 : h_dirac_output_synthesis_state->direct_power_factor_q = 31;
1148 56000 : move16();
1149 : }
1150 : }
1151 :
1152 630352 : diff_start_band = 0;
1153 630352 : move16();
1154 630352 : IF( h_dirac_output_synthesis_params->use_onset_filters )
1155 : {
1156 213809 : computeTargetPSDs_diffuse_with_onsets_fx( num_channels_dir,
1157 213809 : num_freq_bands, h_dirac_output_synthesis_params->max_band_decorr,
1158 213809 : hDirACRend->proto_index_diff,
1159 213809 : h_dirac_output_synthesis_state->diffuse_power_factor_fx,
1160 : reference_power,
1161 : q_reference_power,
1162 213809 : h_dirac_output_synthesis_state->diffuse_responses_square_fx,
1163 : onset,
1164 : h_dirac_output_synthesis_state->cy_auto_diff_smooth_fx,
1165 : &h_dirac_output_synthesis_state->q_cy_auto_diff_smooth );
1166 :
1167 213809 : diff_start_band = h_dirac_output_synthesis_params->max_band_decorr;
1168 213809 : move16();
1169 : }
1170 :
1171 : /* process other PSDs only slot wise for 4 transport channels */
1172 630352 : IF( EQ_16( dec_param_estim, TRUE ) )
1173 : {
1174 56000 : 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 );
1175 :
1176 56000 : 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 );
1177 : }
1178 :
1179 630352 : return;
1180 : }
1181 :
1182 :
1183 : /*-------------------------------------------------------------------------
1184 : * ivas_dirac_dec_output_synthesis_process_subframe_gain_shd()
1185 : *
1186 : *
1187 : *------------------------------------------------------------------------*/
1188 :
1189 235404 : void ivas_dirac_dec_output_synthesis_process_subframe_gain_shd_fx(
1190 : Word32 RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : LS signals */
1191 : Word32 ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : LS signals */
1192 : SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common spatial renderer data handle */
1193 : DIRAC_REND_HANDLE hDirACRend, /* i/o: DirAC renderer handle */
1194 : const Word16 nchan_transport, /* i : number of transport channels */
1195 : const Word16 nbslots, /* i : number of slots to process */
1196 : const Word32 *onset_filter, /* Q31 */
1197 : Word32 *diffuseness, // Q30
1198 : const Word16 hodirac_flag, /* i : flag to indicate HO-DirAC mode */
1199 : const Word16 dec_param_estim,
1200 : Word16 *q_cy_cross_dir_smooth_prev,
1201 : Word16 *q_cy_auto_diff_smooth_prev )
1202 : {
1203 : Word16 buf_idx, ch_idx, i, l;
1204 : Word16 num_freq_bands, num_freq_bands_diff;
1205 : Word16 num_channels_dir, num_channels_diff;
1206 : Word32 g, g1[MAX_FREQUENCY_BANDS], g2;
1207 : Word32 *p_gains_dir, *p_gains_diff;
1208 : Word32 *p_gains_dir_prev, *p_gains_diff_prev;
1209 : Word32 *p_cy_cross_dir_smooth;
1210 : Word32 *p_cy_auto_diff_smooth;
1211 : Word32 *p_proto, *p_out_real, *p_out_imag;
1212 : Word32 *p_proto_diff;
1213 : Word16 *proto_direct_index, num_protos_dir;
1214 : Word32 output_real[CLDFB_NO_CHANNELS_MAX * MAX_OUTPUT_CHANNELS];
1215 : Word32 output_imag[CLDFB_NO_CHANNELS_MAX * MAX_OUTPUT_CHANNELS];
1216 : DIRAC_OUTPUT_SYNTHESIS_PARAMS h_dirac_output_synthesis_params;
1217 : DIRAC_OUTPUT_SYNTHESIS_STATE h_dirac_output_synthesis_state;
1218 : Word16 nchan_transport_foa;
1219 : Word16 ch_idx_diff;
1220 : Word32 cmp1, cmp2;
1221 : Word32 aux_buf[CLDFB_NO_CHANNELS_MAX];
1222 : Word32 ratio_float[DIRAC_HO_NUMSECTORS * CLDFB_NO_CHANNELS_MAX];
1223 235404 : Word16 q_com = 0;
1224 235404 : move16();
1225 235404 : Word16 exp = 0;
1226 235404 : move16();
1227 : Word16 q_shift;
1228 :
1229 : /* collect some often used parameters */
1230 235404 : h_dirac_output_synthesis_params = hDirACRend->h_output_synthesis_psd_params;
1231 235404 : h_dirac_output_synthesis_state = hDirACRend->h_output_synthesis_psd_state;
1232 235404 : proto_direct_index = hDirACRend->proto_index_dir;
1233 :
1234 235404 : num_protos_dir = hDirACRend->num_protos_dir;
1235 235404 : move16();
1236 235404 : num_freq_bands = hSpatParamRendCom->num_freq_bands;
1237 235404 : move16();
1238 235404 : num_freq_bands_diff = h_dirac_output_synthesis_params.max_band_decorr;
1239 235404 : move16();
1240 235404 : num_channels_dir = hDirACRend->num_outputs_dir;
1241 235404 : move16();
1242 235404 : num_channels_diff = hDirACRend->num_outputs_diff;
1243 235404 : move16();
1244 235404 : nchan_transport_foa = s_min( 4, nchan_transport );
1245 235404 : move16();
1246 :
1247 235404 : Word16 prod = imult1616( num_freq_bands, num_channels_dir );
1248 : /*-----------------------------------------------------------------*
1249 : * comput target Gains
1250 : *-----------------------------------------------------------------*/
1251 :
1252 235404 : IF( hodirac_flag )
1253 : {
1254 : /*Direct gain*/
1255 265780 : FOR( ch_idx = 0; ch_idx < nchan_transport_foa; ch_idx++ )
1256 : {
1257 212624 : v_multc_fixed( diffuseness, // Q30
1258 : ONE_IN_Q31, // Q31
1259 212624 : &h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands], // Q30
1260 : num_freq_bands );
1261 212624 : v_multc_fixed( &h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands], // Q30
1262 : L_sub( h_dirac_output_synthesis_params.diffuse_compensation_factor_fx, ONE_IN_Q27 ), // Q27
1263 212624 : &h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands], // Q26
1264 : num_freq_bands );
1265 :
1266 12861264 : FOR( l = 0; l < num_freq_bands; l++ )
1267 : {
1268 12648640 : exp = Q31 - Q26;
1269 25297280 : h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + l] =
1270 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] ),
1271 : &exp ); // (Q31 - exp)
1272 12648640 : move32();
1273 : }
1274 :
1275 : // Scale to bring in common Q-factor
1276 212624 : q_com = s_min( h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev, sub( Q31, exp ) );
1277 212624 : Scale_sig32( &h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands],
1278 : num_freq_bands,
1279 212624 : sub( q_com, sub( Q31, exp ) ) ); /*Q( Q31- exp)->q_com*/
1280 212624 : Scale_sig32( &h_dirac_output_synthesis_state.cy_cross_dir_smooth_prev_fx[ch_idx * num_freq_bands],
1281 : num_freq_bands,
1282 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*/
1283 : }
1284 :
1285 3215316 : FOR( l = 0; l < num_freq_bands; l++ )
1286 : {
1287 3162160 : aux_buf[l] = L_sub( ONE_IN_Q30, diffuseness[l] ); // Q30
1288 3162160 : move32();
1289 3162160 : ratio_float[l] = L_sub( ONE_IN_Q31, h_dirac_output_synthesis_state.direct_power_factor_fx[num_freq_bands + l] ); // Q31
1290 3162160 : move32();
1291 3162160 : ratio_float[l + num_freq_bands] = L_sub( ONE_IN_Q31, ratio_float[l] ); // Q31
1292 3162160 : move32();
1293 : }
1294 :
1295 53156 : v_mult_fixed( aux_buf, ratio_float, ratio_float, num_freq_bands ); //(Q30, Q31) -> Q30
1296 53156 : v_mult_fixed( aux_buf, &ratio_float[num_freq_bands], &ratio_float[num_freq_bands], num_freq_bands ); //(Q30, Q31) -> Q30
1297 :
1298 : /*Directional gain*/
1299 630268 : FOR( ch_idx = nchan_transport_foa; ch_idx < num_channels_dir; ch_idx++ )
1300 : {
1301 577112 : v_mult_fixed( ratio_float, // Q30
1302 577112 : &h_dirac_output_synthesis_state.direct_responses_fx[ch_idx * num_freq_bands], // Q31
1303 577112 : &h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands], //(Q30, Q31) -> Q30
1304 : num_freq_bands );
1305 577112 : v_mult_fixed( &ratio_float[num_freq_bands], // Q30
1306 577112 : &h_dirac_output_synthesis_state.direct_responses_fx[ch_idx * num_freq_bands + num_freq_bands * num_channels_dir], // Q31
1307 577112 : &h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + num_freq_bands * num_channels_dir], //(Q30, Q31) -> Q30
1308 : num_freq_bands );
1309 :
1310 : // Scale to bring in common Q-factor
1311 577112 : q_com = s_min( h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev, Q30 );
1312 577112 : Scale_sig32( &h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands],
1313 : num_freq_bands,
1314 577112 : sub( q_com, Q30 ) ); /*Q30->q_com*/
1315 577112 : Scale_sig32( &h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + num_freq_bands * num_channels_dir],
1316 : num_freq_bands,
1317 577112 : sub( q_com, Q30 ) ); /*Q30->q_com*/
1318 577112 : Scale_sig32( &h_dirac_output_synthesis_state.cy_cross_dir_smooth_prev_fx[ch_idx * num_freq_bands],
1319 : num_freq_bands,
1320 577112 : 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*/
1321 577112 : Scale_sig32( &h_dirac_output_synthesis_state.cy_cross_dir_smooth_prev_fx[ch_idx * num_freq_bands + num_freq_bands * num_channels_dir],
1322 : num_freq_bands,
1323 577112 : 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*/
1324 : }
1325 :
1326 53156 : h_dirac_output_synthesis_state.q_cy_cross_dir_smooth = q_com;
1327 53156 : move16();
1328 53156 : h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev = q_com;
1329 53156 : move16();
1330 :
1331 : /*Diffuse gain*/
1332 53156 : FOR( ch_idx = nchan_transport_foa; ch_idx < num_channels_diff; ch_idx++ )
1333 : {
1334 0 : v_multc_fixed_16( h_dirac_output_synthesis_state.diffuse_power_factor_fx, // Q31
1335 0 : hDirACRend->diffuse_response_function_fx[ch_idx], // Q15
1336 0 : &h_dirac_output_synthesis_state.cy_auto_diff_smooth_fx[ch_idx * num_freq_bands_diff], // Q31
1337 : num_freq_bands_diff );
1338 :
1339 : // Scale to bring in common Q-factor
1340 0 : q_com = s_min( h_dirac_output_synthesis_state.q_cy_auto_diff_smooth_prev, Q31 );
1341 0 : Scale_sig32( &h_dirac_output_synthesis_state.cy_auto_diff_smooth_fx[ch_idx * num_freq_bands_diff],
1342 : num_freq_bands_diff,
1343 0 : sub( q_com, Q31 ) ); /*q31->q_com*/
1344 0 : Scale_sig32( &h_dirac_output_synthesis_state.cy_auto_diff_smooth_prev_fx[ch_idx * num_freq_bands_diff],
1345 : num_freq_bands_diff,
1346 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*/
1347 : }
1348 :
1349 53156 : h_dirac_output_synthesis_state.q_cy_auto_diff_smooth = q_com;
1350 53156 : move16();
1351 53156 : h_dirac_output_synthesis_state.q_cy_auto_diff_smooth_prev = q_com;
1352 53156 : move16();
1353 : }
1354 182248 : ELSE IF( EQ_16( dec_param_estim, FALSE ) )
1355 : {
1356 : /*Direct gain*/
1357 24502 : FOR( ch_idx = 0; ch_idx < nchan_transport_foa; ch_idx++ )
1358 : {
1359 12251 : v_mult_fixed( h_dirac_output_synthesis_state.diffuse_power_factor_fx, // Q31
1360 12251 : h_dirac_output_synthesis_state.diffuse_power_factor_fx, // Q31
1361 12251 : &h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands], // Q31
1362 : num_freq_bands );
1363 12251 : v_multc_fixed( &h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands], // Q31
1364 : L_sub( L_shr( h_dirac_output_synthesis_params.diffuse_compensation_factor_decorr_fx, Q3 ), ONE_IN_Q26 ), // Q26
1365 12251 : &h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands], // Q26
1366 : num_freq_bands_diff );
1367 12251 : v_multc_fixed( &h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + num_freq_bands_diff], // Q31
1368 : L_sub( L_shr( h_dirac_output_synthesis_params.diffuse_compensation_factor_fx, Q1 ), ONE_IN_Q26 ), // Q26
1369 12251 : &h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + num_freq_bands_diff], // Q26
1370 12251 : num_freq_bands - num_freq_bands_diff );
1371 :
1372 747311 : FOR( l = 0; l < num_freq_bands; l++ )
1373 : {
1374 735060 : exp = Q31 - Q26;
1375 1470120 : h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + l] =
1376 735060 : Sqrt32( L_add( ONE_IN_Q26, h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + l] ),
1377 : &exp ); // (Q31 - exp)
1378 735060 : move32();
1379 : }
1380 :
1381 : // Scale to bring in common Q-factor
1382 12251 : q_com = s_min( h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev, sub( Q31, exp ) );
1383 12251 : Scale_sig32( &h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands],
1384 : num_freq_bands,
1385 12251 : sub( q_com, sub( Q31, exp ) ) ); /*( Q31- exp )->q_com*/
1386 12251 : Scale_sig32( &h_dirac_output_synthesis_state.cy_cross_dir_smooth_prev_fx[ch_idx * num_freq_bands],
1387 : num_freq_bands,
1388 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*/
1389 : }
1390 :
1391 : /*Directional gain*/
1392 76604 : FOR( ch_idx = nchan_transport_foa; ch_idx < num_channels_dir; ch_idx++ )
1393 : {
1394 64353 : v_mult_fixed( h_dirac_output_synthesis_state.direct_power_factor_fx, // Q31
1395 64353 : &h_dirac_output_synthesis_state.direct_responses_fx[ch_idx * num_freq_bands], // Q31
1396 64353 : &h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands], // Q31
1397 : num_freq_bands );
1398 :
1399 : // Scale to bring in common Q-factor
1400 64353 : q_com = s_min( h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev, Q31 );
1401 64353 : Scale_sig32( &h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands],
1402 : num_freq_bands,
1403 64353 : sub( q_com, Q31 ) ); /*q31->q_com*/
1404 64353 : Scale_sig32( &h_dirac_output_synthesis_state.cy_cross_dir_smooth_prev_fx[ch_idx * num_freq_bands],
1405 : num_freq_bands,
1406 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*/
1407 : }
1408 :
1409 12251 : h_dirac_output_synthesis_state.q_cy_cross_dir_smooth = q_com;
1410 12251 : move16();
1411 12251 : h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev = q_com;
1412 12251 : move16();
1413 :
1414 : /*Diffuse gain*/
1415 12251 : q_com = s_min( h_dirac_output_synthesis_state.q_cy_auto_diff_smooth_prev, Q31 );
1416 49004 : FOR( ch_idx = nchan_transport_foa; ch_idx < num_channels_diff; ch_idx++ )
1417 : {
1418 36753 : v_multc_fixed_16( h_dirac_output_synthesis_state.diffuse_power_factor_fx, // Q31
1419 36753 : hDirACRend->diffuse_response_function_fx[ch_idx], // Q15
1420 36753 : &h_dirac_output_synthesis_state.cy_auto_diff_smooth_fx[ch_idx * num_freq_bands_diff], // Q31
1421 : num_freq_bands_diff );
1422 :
1423 : // Scale to bring in common Q-factor
1424 36753 : Scale_sig32( &h_dirac_output_synthesis_state.cy_auto_diff_smooth_fx[ch_idx * num_freq_bands_diff],
1425 : num_freq_bands_diff,
1426 36753 : sub( q_com, Q31 ) ); /*q31->q_com*/
1427 36753 : Scale_sig32( &h_dirac_output_synthesis_state.cy_auto_diff_smooth_prev_fx[ch_idx * num_freq_bands_diff],
1428 : num_freq_bands_diff,
1429 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*/
1430 : }
1431 :
1432 12251 : h_dirac_output_synthesis_state.q_cy_auto_diff_smooth = q_com;
1433 12251 : move16();
1434 12251 : h_dirac_output_synthesis_state.q_cy_auto_diff_smooth_prev = q_com;
1435 12251 : move16();
1436 : }
1437 :
1438 : /*-----------------------------------------------------------------*
1439 : * compute gains
1440 : *-----------------------------------------------------------------*/
1441 :
1442 235404 : p_cy_cross_dir_smooth = h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx;
1443 235404 : p_gains_dir = h_dirac_output_synthesis_state.cy_cross_dir_smooth_prev_fx;
1444 :
1445 12747984 : FOR( l = 0; l < num_freq_bands; l++ )
1446 : {
1447 12512580 : g1[l] = Madd_32_32( POINT_3679_Q31, onset_filter[l], POINT_1175_Q31 - POINT_3679_Q31 ); // Q31, (Q31, Q31) -> Q31
1448 12512580 : move32();
1449 : }
1450 :
1451 235404 : q_shift = sub( 26, h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev );
1452 :
1453 : /* Direct gains */
1454 235404 : IF( hodirac_flag )
1455 : {
1456 53156 : cmp1 = L_shr( 66437775 /* 0.99f in Q26 */, q_shift );
1457 53156 : cmp2 = L_shr( ONE_IN_Q27 /* 2.0f in Q26 */, q_shift );
1458 265780 : FOR( ch_idx = 0; ch_idx < nchan_transport_foa; ch_idx++ )
1459 : {
1460 12861264 : FOR( l = 0; l < num_freq_bands; l++ )
1461 : {
1462 12648640 : g2 = Mpy_32_32( L_sub( ONE_IN_Q31, g1[l] ), *( p_gains_dir ) ); // (Q31, p_gains_dir_q) -> p_gains_dir_q
1463 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
1464 12648640 : g2 = L_max( g2, cmp1 ); // p_gains_dir_q
1465 12648640 : g2 = L_min( g2, cmp2 ); // p_gains_dir_q
1466 12648640 : *( p_gains_dir++ ) = g2; // p_gains_dir_q
1467 12648640 : move32();
1468 : }
1469 : }
1470 : }
1471 : ELSE
1472 : {
1473 182248 : cmp1 = L_shr( 57042534 /* 0.85f in Q26 */, q_shift );
1474 182248 : cmp2 = L_shr( 77175193 /* 1.15f in Q26 */, q_shift );
1475 874487 : FOR( ch_idx = 0; ch_idx < nchan_transport_foa; ch_idx++ )
1476 : {
1477 35888739 : FOR( l = 0; l < num_freq_bands; l++ )
1478 : {
1479 35196500 : g2 = Mpy_32_32( L_sub( ONE_IN_Q31, g1[l] ), *( p_gains_dir ) ); // (Q31, p_gains_dir_q) -> p_gains_dir_q
1480 35196500 : 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
1481 35196500 : g2 = L_max( g2, cmp1 ); // p_gains_dir_q
1482 35196500 : g2 = L_min( g2, cmp2 ); // p_gains_dir_q
1483 35196500 : *( p_gains_dir++ ) = g2; // p_gains_dir_q
1484 35196500 : move32();
1485 : }
1486 : }
1487 : }
1488 :
1489 : /*Directional gains*/
1490 235404 : cmp1 = L_shr( -DIRAC_GAIN_LIMIT_Q26, q_shift );
1491 235404 : cmp2 = L_negate( cmp1 );
1492 2830593 : FOR( ch_idx = nchan_transport_foa; ch_idx < num_channels_dir; ch_idx++ )
1493 : {
1494 139666609 : FOR( l = 0; l < num_freq_bands; l++ )
1495 : {
1496 137071420 : g2 = Mpy_32_32( L_sub( ONE_IN_Q31, g1[l] ), *( p_gains_dir ) ); // (Q31, p_gains_dir_q) -> p_gains_dir_q
1497 137071420 : 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
1498 137071420 : g2 = L_max( g2, cmp1 ); // p_gains_dir_q
1499 137071420 : g2 = L_min( g2, cmp2 ); // p_gains_dir_q
1500 137071420 : *( p_gains_dir++ ) = g2; // p_gains_dir_q
1501 137071420 : move32();
1502 : }
1503 : }
1504 :
1505 235404 : IF( hodirac_flag )
1506 : {
1507 53156 : p_cy_cross_dir_smooth = h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx + prod;
1508 53156 : p_gains_dir = h_dirac_output_synthesis_state.cy_cross_dir_smooth_prev_fx + prod;
1509 :
1510 : /*Direct gains*/
1511 265780 : FOR( ch_idx = 0; ch_idx < nchan_transport_foa; ch_idx++ )
1512 : {
1513 12861264 : FOR( l = 0; l < num_freq_bands; l++ )
1514 : {
1515 12648640 : p_cy_cross_dir_smooth++;
1516 12648640 : p_gains_dir++;
1517 : }
1518 : }
1519 :
1520 : /*Directional gains*/
1521 630268 : FOR( ch_idx = nchan_transport_foa; ch_idx < num_channels_dir; ch_idx++ )
1522 : {
1523 34972632 : FOR( l = 0; l < num_freq_bands; l++ )
1524 : {
1525 34395520 : g2 = Mpy_32_32( L_sub( ONE_IN_Q31, g1[l] ), *( p_gains_dir ) ); // (Q31, p_gains_dir_q) -> p_gains_dir_q
1526 34395520 : 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
1527 34395520 : g2 = L_max( g2, cmp1 ); // p_gains_dir_q
1528 34395520 : g2 = L_min( g2, cmp2 ); // p_gains_dir_q
1529 34395520 : *( p_gains_dir++ ) = g2; // p_gains_dir_q
1530 34395520 : move32();
1531 : }
1532 : }
1533 : }
1534 :
1535 : /*Diffuse gains*/
1536 235404 : p_cy_auto_diff_smooth = h_dirac_output_synthesis_state.cy_auto_diff_smooth_fx + imult1616( nchan_transport_foa, num_freq_bands_diff );
1537 235404 : p_gains_diff = h_dirac_output_synthesis_state.cy_auto_diff_smooth_prev_fx + imult1616( nchan_transport_foa, num_freq_bands_diff );
1538 235404 : g1[0] = POINT_1175_Q31; // Q31
1539 235404 : move32();
1540 272157 : FOR( ch_idx = nchan_transport_foa; ch_idx < num_channels_diff; ch_idx++ )
1541 : {
1542 845319 : FOR( l = 0; l < num_freq_bands_diff; l++ )
1543 : {
1544 808566 : move32();
1545 808566 : g2 = Mpy_32_32( L_sub( ONE_IN_Q31, g1[0] ), *( p_gains_diff ) ); // (Q31, p_gains_dir_q) -> p_gains_dir_q
1546 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
1547 808566 : g2 = L_max( g2, 0 ); // p_gains_diff_q
1548 808566 : g2 = L_min( g2, cmp2 ); // p_gains_diff_q
1549 808566 : *( p_gains_diff++ ) = g2; // p_gains_diff_q
1550 808566 : move32();
1551 : }
1552 : }
1553 :
1554 : /*-----------------------------------------------------------------*
1555 : * gain interpolation and output streams
1556 : *-----------------------------------------------------------------*/
1557 :
1558 1171335 : FOR( buf_idx = 0; buf_idx < nbslots; ++buf_idx )
1559 : {
1560 935931 : g1[0] = L_deposit_h( h_dirac_output_synthesis_params.interpolator_fx[buf_idx] ); // Q31
1561 935931 : move32();
1562 935931 : g2 = L_sub( ONE_IN_Q31, g1[0] ); // Q31
1563 :
1564 : /*Direct input->output*/
1565 935931 : p_gains_dir = h_dirac_output_synthesis_state.cy_cross_dir_smooth_prev_fx; // (p_gains_dir_q)
1566 935931 : p_gains_dir_prev = h_dirac_output_synthesis_state.gains_dir_prev_fx;
1567 935931 : q_shift = sub( h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev, h_dirac_output_synthesis_state.gains_dir_prev_q );
1568 14845179 : FOR( ch_idx = 0; ch_idx < num_channels_dir; ch_idx++ )
1569 : {
1570 13909248 : Scale_sig32( &h_dirac_output_synthesis_state.gains_dir_prev_fx[ch_idx * num_freq_bands],
1571 : num_freq_bands,
1572 : q_shift ); /*h_dirac_output_synthesis_state.gains_dir_prev_q->h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev*/
1573 : }
1574 935931 : h_dirac_output_synthesis_state.gains_dir_prev_q = h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev;
1575 935931 : move16();
1576 :
1577 4532643 : FOR( ch_idx = 0; ch_idx < nchan_transport_foa; ch_idx++ )
1578 : {
1579 7193424 : p_proto_diff = h_dirac_output_synthesis_state.proto_diffuse_buffer_f_fx +
1580 3596712 : shl( i_mult( buf_idx, i_mult( num_freq_bands, num_channels_diff ) ), Q1 ) +
1581 3596712 : shl( ch_idx * num_freq_bands, Q1 );
1582 193910872 : FOR( l = 0; l < num_freq_bands; l++ )
1583 : {
1584 190314160 : 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)
1585 :
1586 190314160 : 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)
1587 190314160 : move32();
1588 190314160 : 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)
1589 190314160 : move32();
1590 : }
1591 : }
1592 :
1593 : /*Directional stream*/
1594 935931 : Word16 offset = shl( i_mult( buf_idx, i_mult( num_freq_bands, num_protos_dir ) ), Q1 );
1595 11248467 : FOR( ch_idx = nchan_transport_foa; ch_idx < num_channels_dir; ch_idx++ )
1596 : {
1597 10312536 : IF( hodirac_flag )
1598 : {
1599 2308448 : IF( proto_direct_index[ch_idx] == 0 )
1600 : {
1601 : Word32 *p_proto2;
1602 : Word32 gs1, gs2;
1603 2266944 : p_proto = h_dirac_output_synthesis_state.proto_direct_buffer_f_fx +
1604 1133472 : shl( i_mult( buf_idx, i_mult( num_freq_bands, num_protos_dir ) ), Q1 ) +
1605 1133472 : shl( i_mult( proto_direct_index[0], num_freq_bands ), Q1 );
1606 2266944 : p_proto2 = h_dirac_output_synthesis_state.proto_direct_buffer_f_fx +
1607 1133472 : shl( i_mult( buf_idx, i_mult( num_freq_bands, num_protos_dir ) ), Q1 ) +
1608 1133472 : shl( i_mult( proto_direct_index[1], num_freq_bands ), Q1 );
1609 68677792 : FOR( l = 0; l < num_freq_bands; l++ )
1610 : {
1611 :
1612 : Word32 temp1, temp2;
1613 67544320 : 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)
1614 67544320 : 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)
1615 67544320 : p_gains_dir++;
1616 67544320 : p_gains_dir_prev++;
1617 :
1618 67544320 : temp1 = Mpy_32_32( 1903158016 /* 1.772454e+00f / 2 in Q31 */, ( *p_proto ) );
1619 67544320 : temp2 = Mpy_32_32( 1098788992 /* 1.023327e+00f / 2 in Q31 */, ( *p_proto2 ) );
1620 : // ((p_gains_dir_q, p_proto_dir_q) >> 1) -> (p_gains_dir_q + p_proto_dir_q - 31)
1621 135088640 : output_real[l * num_channels_dir + ch_idx] =
1622 67544320 : Madd_32_32(
1623 : Mpy_32_32( gs1, ( L_add( temp1, temp2 ) ) ), /* s1 */
1624 : gs2, L_sub( temp1, temp2 ) ); /* s2 */
1625 67544320 : move32();
1626 67544320 : p_proto++;
1627 67544320 : p_proto2++;
1628 :
1629 67544320 : temp1 = Mpy_32_32( 1903158016 /* 1.772454e+00f / 2 in Q31 */, ( *p_proto ) );
1630 67544320 : temp2 = Mpy_32_32( 1098788992 /* 1.023327e+00f / 2 in Q31 */, ( *p_proto2 ) );
1631 : // ((p_gains_dir_q, p_proto_dir_q) >> 1) -> (p_gains_dir_q + p_proto_dir_q - 31)
1632 135088640 : output_imag[l * num_channels_dir + ch_idx] =
1633 67544320 : Madd_32_32(
1634 : Mpy_32_32( gs1, ( L_add( temp1, temp2 ) ) ),
1635 : gs2, L_sub( temp1, temp2 ) );
1636 67544320 : move32();
1637 67544320 : p_proto++;
1638 67544320 : p_proto2++;
1639 : }
1640 : }
1641 : ELSE
1642 : {
1643 2349952 : p_proto = h_dirac_output_synthesis_state.proto_direct_buffer_f_fx +
1644 1174976 : shl( i_mult( buf_idx, i_mult( num_freq_bands, num_protos_dir ) ), Q1 ) +
1645 1174976 : shl( i_mult( proto_direct_index[ch_idx], num_freq_bands ), Q1 );
1646 1174976 : Word16 diff = sub( h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev, 31 );
1647 71212736 : FOR( l = 0; l < num_freq_bands; l++ )
1648 : {
1649 70037760 : p_gains_dir++;
1650 70037760 : p_gains_dir_prev++;
1651 :
1652 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)
1653 70037760 : move32();
1654 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)
1655 70037760 : move32();
1656 : }
1657 : }
1658 : }
1659 : ELSE
1660 : {
1661 16008176 : p_proto = h_dirac_output_synthesis_state.proto_direct_buffer_f_fx +
1662 16008176 : offset +
1663 8004088 : shl( i_mult( proto_direct_index[ch_idx], num_freq_bands ), Q1 );
1664 8004088 : IF( EQ_16( proto_direct_index[ch_idx], 0 ) )
1665 : {
1666 401776328 : FOR( l = 0; l < num_freq_bands; l++ )
1667 : {
1668 394019600 : 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)
1669 :
1670 394019600 : 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)
1671 394019600 : move32();
1672 394019600 : 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)
1673 394019600 : move32();
1674 : }
1675 : }
1676 : ELSE
1677 : {
1678 247360 : Word16 shift_q = sub( h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev, 31 );
1679 13732160 : FOR( l = 0; l < num_freq_bands; l++ )
1680 : {
1681 13484800 : p_gains_dir++;
1682 13484800 : p_gains_dir_prev++;
1683 :
1684 13484800 : 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)
1685 13484800 : move32();
1686 13484800 : 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)
1687 13484800 : move32();
1688 : }
1689 : }
1690 : }
1691 : }
1692 :
1693 : /*Diffuse stream*/
1694 935931 : p_gains_diff = h_dirac_output_synthesis_state.cy_auto_diff_smooth_prev_fx + i_mult( nchan_transport_foa, num_freq_bands_diff );
1695 935931 : p_gains_diff_prev = h_dirac_output_synthesis_state.gains_diff_prev_fx + i_mult( nchan_transport_foa, num_freq_bands_diff );
1696 1082943 : FOR( ch_idx = nchan_transport_foa; ch_idx < num_channels_diff; ch_idx++ )
1697 : {
1698 147012 : Scale_sig32( &h_dirac_output_synthesis_state.gains_diff_prev_fx[ch_idx * num_freq_bands_diff],
1699 : num_freq_bands_diff,
1700 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*/
1701 : }
1702 935931 : h_dirac_output_synthesis_state.gains_diff_prev_q = h_dirac_output_synthesis_state.q_cy_auto_diff_smooth_prev;
1703 935931 : move16();
1704 :
1705 935931 : ch_idx_diff = nchan_transport_foa;
1706 935931 : move16();
1707 1082943 : FOR( ch_idx = nchan_transport_foa; ch_idx < num_channels_diff; ch_idx++ )
1708 : {
1709 147012 : IF( proto_direct_index[ch_idx] == 0 )
1710 : {
1711 294024 : p_proto = h_dirac_output_synthesis_state.proto_diffuse_buffer_f_fx +
1712 147012 : shl( i_mult( buf_idx, i_mult( num_freq_bands, num_channels_diff ) ), Q1 ) +
1713 147012 : shl( i_mult( ch_idx_diff, num_freq_bands ), Q1 );
1714 147012 : ch_idx_diff = add( ch_idx_diff, 1 );
1715 3381276 : FOR( l = 0; l < num_freq_bands_diff; l++ )
1716 : {
1717 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
1718 :
1719 : // ((p_gains_diff_q, p_proto_diff_q) >> Q1) -> (p_gains_diff_q + p_proto_diff_q - 31)
1720 6468528 : output_real[l * num_channels_dir + hDirACRend->sba_map_tc[ch_idx]] =
1721 3234264 : Madd_32_32( output_real[l * num_channels_dir + hDirACRend->sba_map_tc[ch_idx]],
1722 3234264 : g, ( *( p_proto++ ) ) );
1723 3234264 : move32();
1724 :
1725 : // ((p_gains_diff_q, p_proto_diff_q) >> Q1) -> (p_gains_diff_q + p_proto_diff_q - 31)
1726 6468528 : output_imag[l * num_channels_dir + hDirACRend->sba_map_tc[ch_idx]] =
1727 3234264 : Madd_32_32( output_imag[l * num_channels_dir + hDirACRend->sba_map_tc[ch_idx]],
1728 3234264 : g, ( *( p_proto++ ) ) );
1729 3234264 : move32();
1730 : }
1731 : }
1732 : ELSE
1733 : {
1734 0 : p_gains_diff += num_freq_bands_diff;
1735 0 : p_gains_diff_prev += num_freq_bands_diff;
1736 : }
1737 : }
1738 :
1739 : /*-----------------------------------------------------------------*
1740 : * Copy output or HOA decoder
1741 : *-----------------------------------------------------------------*/
1742 :
1743 935931 : test();
1744 : /*q=(p_gains_dir_q + p_proto_dir_q - 31)*/
1745 935931 : IF( hDirACRend->hOutSetup.is_loudspeaker_setup && hDirACRend->hoa_decoder != NULL )
1746 172000 : {
1747 : Word32 *p_real, *p_imag;
1748 : const Word32 *hoa_decoder;
1749 :
1750 172000 : hoa_decoder = hDirACRend->hoa_decoder;
1751 :
1752 1784000 : FOR( ch_idx = 0; ch_idx < hDirACRend->hOutSetup.nchan_out_woLFE; ch_idx++ )
1753 : {
1754 1612000 : p_real = RealBuffer[ch_idx][buf_idx]; /*q - Q2*/
1755 1612000 : p_imag = ImagBuffer[ch_idx][buf_idx]; /*q - Q2*/
1756 :
1757 91292000 : FOR( l = 0; l < num_freq_bands; l++ )
1758 : {
1759 89680000 : p_out_real = output_real + i_mult( l, num_channels_dir );
1760 89680000 : p_out_imag = output_imag + i_mult( l, num_channels_dir );
1761 89680000 : p_real[l] = Mpy_32_32( *( p_out_real++ ), hoa_decoder[0] ); // (q, Q29) -> q - Q2
1762 89680000 : move32();
1763 89680000 : p_imag[l] = Mpy_32_32( *( p_out_imag++ ), hoa_decoder[0] ); // (q, Q29) -> q - Q2
1764 89680000 : move32();
1765 1434880000 : FOR( i = 1; i < num_channels_dir; i++ )
1766 : {
1767 1345200000 : p_real[l] = Madd_32_32( p_real[l], *( p_out_real++ ), hoa_decoder[i] ); // (q, Q29) -> q - Q2
1768 1345200000 : move32();
1769 1345200000 : p_imag[l] = Madd_32_32( p_imag[l], *( p_out_imag++ ), hoa_decoder[i] ); // (q, Q29) -> q - Q2
1770 1345200000 : move32();
1771 : }
1772 : }
1773 1612000 : hoa_decoder += 16;
1774 : }
1775 : }
1776 : ELSE
1777 : {
1778 11921179 : FOR( ch_idx = 0; ch_idx < num_channels_dir; ch_idx++ )
1779 : {
1780 591677888 : FOR( l = 0; l < num_freq_bands; l++ )
1781 : {
1782 580520640 : RealBuffer[ch_idx][buf_idx][l] = L_shr( output_real[l * num_channels_dir + ch_idx], Q2 ); /* q - Q2*/
1783 580520640 : move32();
1784 580520640 : ImagBuffer[ch_idx][buf_idx][l] = L_shr( output_imag[l * num_channels_dir + ch_idx], Q2 ); /* q - Q2*/
1785 580520640 : move32();
1786 : }
1787 : }
1788 : }
1789 : }
1790 :
1791 : /*-----------------------------------------------------------------*
1792 : * update buffers
1793 : *-----------------------------------------------------------------*/
1794 :
1795 : /* store estimates for next synthesis block */
1796 235404 : IF( hodirac_flag )
1797 : {
1798 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*/
1799 : }
1800 : ELSE
1801 : {
1802 182248 : 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*/
1803 : }
1804 235404 : *q_cy_cross_dir_smooth_prev = h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev;
1805 235404 : move16();
1806 :
1807 235404 : 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*/
1808 235404 : *q_cy_auto_diff_smooth_prev = h_dirac_output_synthesis_state.q_cy_auto_diff_smooth_prev;
1809 235404 : move16();
1810 :
1811 : /* reset values */
1812 235404 : IF( hodirac_flag )
1813 : {
1814 53156 : set_zero_fx( h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx, prod * DIRAC_HO_NUMSECTORS );
1815 : }
1816 : ELSE
1817 : {
1818 182248 : set_zero_fx( h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx, prod );
1819 : }
1820 :
1821 235404 : set_zero_fx( h_dirac_output_synthesis_state.cy_auto_diff_smooth_fx, imult1616( num_freq_bands_diff, num_channels_diff ) );
1822 :
1823 235404 : return;
1824 : }
1825 :
1826 :
1827 : /*-------------------------------------------------------------------------
1828 : * ivas_dirac_dec_output_synthesis_process_subframe_psd_ls()
1829 : *
1830 : *
1831 : *------------------------------------------------------------------------*/
1832 92927 : void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx(
1833 : Word32 RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : LS signals Q(q_Cldfb)*/
1834 : Word32 ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : LS signals Q(q_Cldfb)*/
1835 : SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common spatial renderer data handle */
1836 : DIRAC_REND_HANDLE hDirACRend, /* i/o: DirAC renderer handle */
1837 : const Word16 nbslots, /* i : number of slots to process */
1838 : Word32 *diffuseness_vector, /* i : diffuseness (needed for direction smoothing) Q(31)*/
1839 : Word32 *reference_power_smooth, /*Q(q_reference_power_smooth)*/
1840 : Word16 *q_reference_power_smooth,
1841 : Word32 qualityBasedSmFactor, /*Q(31)*/
1842 : const Word16 enc_param_start_band,
1843 : Word16 *q_Cldfb )
1844 : {
1845 : Word16 buf_idx, num_freq_bands;
1846 : Word16 diff_start_band;
1847 : Word16 k, l;
1848 : Word16 nchan_out_woLFE;
1849 : Word32 *p_power_smooth_prev, *p_power_diff_smooth_prev;
1850 : Word32 *p_gain_1, *p_gain_2;
1851 : Word32 *p_power_smooth_diff, *p_power_smooth;
1852 : Word32 *p_gains_dir, *p_gains_diff;
1853 : Word32 g, g1, g2;
1854 : Word32 *p_cy_auto_dir_smooth, *p_cy_auto_dir_smooth_prev;
1855 : Word16 q_cy_auto_dir_smooth_local[MAX_OUTPUT_CHANNELS], q_cy_auto_dir_smooth_prev_local[MAX_OUTPUT_CHANNELS];
1856 : Word32 *p_cy_cross_dir_smooth, *p_cy_cross_dir_smooth_prev;
1857 : Word32 *p_cy_auto_diff_smooth, *p_cy_auto_diff_smooth_prev;
1858 : Word32 gains_dir[CLDFB_NO_CHANNELS_MAX * MAX_OUTPUT_CHANNELS];
1859 : Word32 gains_diff[CLDFB_NO_CHANNELS_MAX * MAX_OUTPUT_CHANNELS];
1860 : DIRAC_OUTPUT_SYNTHESIS_PARAMS *h_dirac_output_synthesis_params;
1861 : DIRAC_OUTPUT_SYNTHESIS_STATE *h_dirac_output_synthesis_state;
1862 : Word16 *proto_direct_index, num_protos_dir;
1863 : Word32 target_power_y, target_power_y1;
1864 : Word16 q_target_power_y, q_target_power_y1;
1865 : Word32 subtract_power_y;
1866 : Word32 subtract_target_ratio;
1867 : Word32 subtract_target_ratio_db;
1868 : Word32 a, b;
1869 : UWord16 nchan_target_psds;
1870 : Word32 alpha[CLDFB_NO_CHANNELS_MAX];
1871 : Word16 *alpha_synthesis;
1872 : Word16 *alpha_synthesis_fast;
1873 : Word16 alphaMaxBin;
1874 : Word16 alphaMaxBinFast;
1875 : Word32 L_tmp;
1876 : Word16 exp_arr[CLDFB_NO_CHANNELS_MAX * MAX_OUTPUT_CHANNELS];
1877 92927 : Word16 exp = 0, exp1, tmp, q_com, q_tmp, min_exp;
1878 : Word32 tmp32;
1879 92927 : move16();
1880 :
1881 : Word64 Cldfb_RealBuffer64_fx[MAX_OUTPUT_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
1882 : Word64 Cldfb_ImagBuffer64_fx[MAX_OUTPUT_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
1883 92927 : Word64 W_temp = 0;
1884 92927 : move64();
1885 92927 : push_wmops( "dirac_out_synth_sfr" );
1886 :
1887 92927 : h_dirac_output_synthesis_params = &( hDirACRend->h_output_synthesis_psd_params );
1888 92927 : h_dirac_output_synthesis_state = &( hDirACRend->h_output_synthesis_psd_state );
1889 :
1890 : /* collect some often used parameters */
1891 92927 : proto_direct_index = hDirACRend->proto_index_dir;
1892 92927 : move16();
1893 92927 : num_protos_dir = hDirACRend->num_protos_dir;
1894 92927 : move16();
1895 92927 : nchan_out_woLFE = hDirACRend->hOutSetup.nchan_out_woLFE;
1896 92927 : move16();
1897 92927 : num_freq_bands = hSpatParamRendCom->num_freq_bands;
1898 92927 : move16();
1899 92927 : set16_fx( q_cy_auto_dir_smooth_local, h_dirac_output_synthesis_state->q_cy_auto_dir_smooth, nchan_out_woLFE );
1900 :
1901 : /*-----------------------------------------------------------------*
1902 : * compute target PSDs
1903 : *-----------------------------------------------------------------*/
1904 92927 : IF( enc_param_start_band == 0 )
1905 : {
1906 78927 : IF( EQ_16( h_dirac_output_synthesis_params->use_onset_filters, 1 ) )
1907 : {
1908 53475 : diff_start_band = h_dirac_output_synthesis_params->max_band_decorr;
1909 53475 : move16();
1910 : }
1911 : ELSE
1912 : {
1913 25452 : diff_start_band = 0;
1914 25452 : move16();
1915 : }
1916 :
1917 78927 : IF( EQ_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_MONO ) )
1918 : {
1919 9417 : nchan_target_psds = 2;
1920 9417 : move16();
1921 : }
1922 : ELSE
1923 : {
1924 69510 : nchan_target_psds = nchan_out_woLFE;
1925 69510 : move16();
1926 : }
1927 :
1928 78927 : computeTargetPSDs_direct_subframe_fx( nchan_target_psds, num_freq_bands,
1929 78927 : h_dirac_output_synthesis_state->direct_power_factor_fx,
1930 : reference_power_smooth,
1931 : q_reference_power_smooth,
1932 78927 : h_dirac_output_synthesis_state->direct_responses_fx,
1933 78927 : h_dirac_output_synthesis_state->direct_responses_square_fx,
1934 : h_dirac_output_synthesis_state->cy_auto_dir_smooth_fx,
1935 : q_cy_auto_dir_smooth_local,
1936 : h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx,
1937 : &h_dirac_output_synthesis_state->q_cy_cross_dir_smooth );
1938 :
1939 :
1940 78927 : computeTargetPSDs_diffuse_subframe_fx( nchan_target_psds, num_freq_bands, diff_start_band,
1941 78927 : h_dirac_output_synthesis_state->diffuse_power_factor_fx,
1942 : reference_power_smooth,
1943 : q_reference_power_smooth,
1944 78927 : h_dirac_output_synthesis_state->diffuse_responses_square_fx,
1945 : h_dirac_output_synthesis_state->cy_auto_diff_smooth_fx,
1946 : &h_dirac_output_synthesis_state->q_cy_auto_diff_smooth );
1947 : }
1948 :
1949 : /*-----------------------------------------------------------------*
1950 : * compute variables for stereo transport signal type detection
1951 : *-----------------------------------------------------------------*/
1952 :
1953 92927 : IF( hDirACRend->masa_stereo_type_detect != NULL )
1954 : {
1955 16209 : MASA_STEREO_TYPE_DETECT *masa_stereo_type_detect = hDirACRend->masa_stereo_type_detect;
1956 :
1957 16209 : p_cy_auto_dir_smooth = h_dirac_output_synthesis_state->cy_auto_dir_smooth_fx; // q_cy_auto_dir_smooth
1958 16209 : p_cy_auto_diff_smooth = h_dirac_output_synthesis_state->cy_auto_diff_smooth_fx; // q_cy_auto_diff_smooth
1959 16209 : q_com = s_min( q_cy_auto_dir_smooth_local[1], h_dirac_output_synthesis_state->q_cy_auto_diff_smooth );
1960 :
1961 16209 : IF( EQ_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_MONO ) )
1962 : {
1963 9417 : exp = Q31 - Q31;
1964 9417 : move16();
1965 9417 : exp1 = 0;
1966 9417 : move16();
1967 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] ) ),
1968 9417 : ( L_add( Sqrt32( h_dirac_output_synthesis_state->direct_power_factor_fx[0], &exp ), EPSILON_FX ) ), // (Q31 - exp)
1969 : &exp1 );
1970 9417 : target_power_y = L_shr( tmp32, 1 ); // Q31 + (q_com - (31 - exp))
1971 9417 : q_target_power_y = add( sub( Q31, exp1 ), sub( q_com, sub( Q31, exp ) ) );
1972 9417 : q_target_power_y = sub( q_target_power_y, 1 );
1973 :
1974 9417 : exp = Q31 - Q31;
1975 9417 : move16();
1976 9417 : exp1 = 0;
1977 9417 : move16();
1978 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 ) ),
1979 9417 : ( L_add( Sqrt32( h_dirac_output_synthesis_state->diffuse_power_factor_fx[0], &exp ), EPSILON_FX ) ), // (Q31 - exp)
1980 : &exp1 );
1981 9417 : target_power_y1 = L_shr( tmp32, 1 ); // Q31 + (q_com - (31 - exp))
1982 9417 : q_target_power_y1 = add( sub( Q31, exp1 ), sub( q_com, sub( Q31, exp ) ) );
1983 9417 : q_target_power_y1 = sub( q_target_power_y1, 1 );
1984 :
1985 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 )*/
1986 9417 : exp = s_min( q_target_power_y1, q_target_power_y );
1987 : }
1988 : ELSE
1989 : {
1990 6792 : target_power_y = L_add(
1991 6792 : L_shl( p_cy_auto_dir_smooth[num_freq_bands], sub( q_com, q_cy_auto_dir_smooth_local[1] ) ),
1992 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
1993 6792 : exp = q_com;
1994 6792 : move16();
1995 : }
1996 :
1997 16209 : a = 858993; /* ( 0.0004f in Q31 ); Temporal smoothing coefficient */
1998 16209 : move32();
1999 16209 : b = L_sub( ONE_IN_Q31, a ); /* Temporal smoothing coefficient */
2000 :
2001 16209 : q_com = s_min( exp, masa_stereo_type_detect->q_target_power_y_smooth );
2002 16209 : target_power_y = L_shl( target_power_y, sub( q_com, exp ) );
2003 16209 : masa_stereo_type_detect->target_power_y_smooth_fx = L_shl( masa_stereo_type_detect->target_power_y_smooth_fx,
2004 16209 : sub( q_com, masa_stereo_type_detect->q_target_power_y_smooth ) );
2005 16209 : move32();
2006 16209 : masa_stereo_type_detect->target_power_y_smooth_fx =
2007 16209 : L_add( Mpy_32_32( a, target_power_y ),
2008 : Mpy_32_32( b, masa_stereo_type_detect->target_power_y_smooth_fx ) ); //(Q31, q_com) -> q_com
2009 16209 : move32();
2010 16209 : masa_stereo_type_detect->q_target_power_y_smooth = q_com;
2011 16209 : move16();
2012 :
2013 16209 : IF( NE_16( masa_stereo_type_detect->q_subtract_power_y, masa_stereo_type_detect->q_subtract_power_y_smooth ) )
2014 : {
2015 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 ) ) );
2016 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 ) );
2017 0 : move32();
2018 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 ) );
2019 0 : move32();
2020 0 : masa_stereo_type_detect->q_subtract_power_y = exp;
2021 0 : move16();
2022 0 : masa_stereo_type_detect->q_subtract_power_y_smooth = exp;
2023 0 : move16();
2024 : }
2025 16209 : subtract_power_y = masa_stereo_type_detect->subtract_power_y_fx; // q_subtract_power_y
2026 16209 : move32();
2027 :
2028 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
2029 16209 : IF( W_temp )
2030 : {
2031 16196 : exp = W_norm( W_temp );
2032 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
2033 16196 : move32();
2034 16196 : masa_stereo_type_detect->q_subtract_power_y_smooth = sub( add( masa_stereo_type_detect->q_subtract_power_y_smooth, exp ), 1 );
2035 16196 : move16();
2036 : }
2037 : ELSE
2038 : {
2039 13 : masa_stereo_type_detect->subtract_power_y_smooth_fx = 0; // Q31
2040 13 : move32();
2041 13 : masa_stereo_type_detect->q_subtract_power_y_smooth = Q31;
2042 13 : move16();
2043 : }
2044 16209 : exp = 0;
2045 16209 : move16();
2046 16209 : test();
2047 16209 : IF( masa_stereo_type_detect->target_power_y_smooth_fx && masa_stereo_type_detect->subtract_power_y_smooth_fx )
2048 : {
2049 16193 : subtract_target_ratio = L_sub( BASOP_Util_Log2( masa_stereo_type_detect->subtract_power_y_smooth_fx ),
2050 : BASOP_Util_Log2( masa_stereo_type_detect->target_power_y_smooth_fx ) ); // Q25
2051 16193 : exp = sub( masa_stereo_type_detect->q_subtract_power_y_smooth, q_com );
2052 16193 : L_tmp = Mpy_32_32( L_sub( subtract_target_ratio, L_shl( exp, 25 ) ), LOG10_2_Q31 ); // Q25
2053 : }
2054 : ELSE
2055 : {
2056 16 : subtract_target_ratio = BASOP_Util_Log2( masa_stereo_type_detect->subtract_power_y_smooth_fx ); // Q25
2057 16 : exp = sub( 31, masa_stereo_type_detect->q_subtract_power_y_smooth );
2058 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
2059 : }
2060 16209 : subtract_target_ratio_db = Mpy_32_32( 1342177280 /* 10.0f * in Q27*/, L_tmp ); // (Q27, (Q25, Q31)) -> (Q27, Q25) -> Q21
2061 :
2062 16209 : masa_stereo_type_detect->subtract_target_ratio_db_fx = subtract_target_ratio_db; // Q21
2063 16209 : move32();
2064 16209 : masa_stereo_type_detect->subtract_power_y_fx = 0;
2065 16209 : move32();
2066 16209 : masa_stereo_type_detect->q_subtract_power_y = Q31;
2067 16209 : move16();
2068 : }
2069 :
2070 : /*-----------------------------------------------------------------*
2071 : * compute smoothing coefficients
2072 : *-----------------------------------------------------------------*/
2073 :
2074 92927 : alpha_synthesis = h_dirac_output_synthesis_params->alpha_synthesis_fx; // Q15
2075 92927 : alpha_synthesis_fast = h_dirac_output_synthesis_params->alpha_synthesis_fast_fx; // Q15
2076 92927 : alphaMaxBin = sub( h_dirac_output_synthesis_params->numAlphas, 1 );
2077 92927 : alphaMaxBinFast = sub( h_dirac_output_synthesis_params->numAlphasFast, 1 );
2078 :
2079 5403347 : FOR( l = 0; l < num_freq_bands; l++ )
2080 : {
2081 : Word32 instDirectionSmoothness, weightedDirectionSmoothness, smoothedDirectionSmoothness;
2082 : Word32 currWeight, prevWeight, sumWeight;
2083 : Word16 indexFast, indexSlow;
2084 5310420 : Word32 alpha_quality_based = 42949672; /* 0.02f in Q31 */
2085 5310420 : move32();
2086 :
2087 5310420 : indexSlow = s_min( l, alphaMaxBin );
2088 5310420 : indexFast = s_min( l, alphaMaxBinFast );
2089 :
2090 : /* Estimate the smoothness of the directions based on the diffuseness parameter */
2091 5310420 : instDirectionSmoothness = L_sub( ONE_IN_Q31, diffuseness_vector[l] ); // Q31
2092 5310420 : instDirectionSmoothness = L_min( L_max( instDirectionSmoothness, 0 ), ONE_IN_Q31 ); // Q31
2093 :
2094 : /* Average the direction smoothness parameter over time */
2095 5310420 : currWeight = Mpy_32_32( DIRECTION_SMOOTHNESS_ALPHA_Q31,
2096 5310420 : reference_power_smooth[l] ); //(Q31, q_reference_power_smooth) -> q_reference_power_smooth
2097 5310420 : prevWeight = Mpy_32_32( L_sub( ONE_IN_Q31, DIRECTION_SMOOTHNESS_ALPHA_Q31 ),
2098 5310420 : h_dirac_output_synthesis_state->reference_power_smooth_prev_fx[l] ); //(Q31, q_reference_power_smooth) -> q_reference_power_smooth
2099 :
2100 5310420 : assert( q_reference_power_smooth[0] == h_dirac_output_synthesis_state->reference_power_smooth_prev_q[0] );
2101 5310420 : assert( q_reference_power_smooth[1] == h_dirac_output_synthesis_state->reference_power_smooth_prev_q[1] );
2102 : weightedDirectionSmoothness =
2103 5310420 : L_add( Mpy_32_32( currWeight, instDirectionSmoothness ),
2104 5310420 : Mpy_32_32( prevWeight, h_dirac_output_synthesis_state->direction_smoothness_prev_fx[l] ) ); //(q_reference_power_smooth, Q31) -> q_reference_power_smooth
2105 5310420 : sumWeight = L_add( currWeight, prevWeight ); // q_reference_power_smooth
2106 :
2107 5310420 : exp = 0;
2108 5310420 : move16();
2109 :
2110 5310420 : tmp = BASOP_Util_Divide3232_Scale( weightedDirectionSmoothness, L_add( sumWeight, EPSILON_FX ), &exp ); /*Q(15-exp)*/
2111 5310420 : smoothedDirectionSmoothness = L_shl_sat( L_deposit_l( tmp ), add( sub( Q31, Q15 ), exp ) ); // Q31
2112 :
2113 5310420 : h_dirac_output_synthesis_state->direction_smoothness_prev_fx[l] = smoothedDirectionSmoothness; // Q31
2114 5310420 : move32();
2115 5310420 : h_dirac_output_synthesis_state->reference_power_smooth_prev_fx[l] = sumWeight; // q_reference_power_smooth
2116 5310420 : move32();
2117 :
2118 : /* Determine smoothing parameter for rendering. The smoother the directions, the less smoothing is required (i.e., faster smoothing can be used). */
2119 10620840 : alpha[l] =
2120 5310420 : L_add( Mpy_32_16_1( smoothedDirectionSmoothness, alpha_synthesis_fast[indexFast] ),
2121 5310420 : Mpy_32_16_1( L_sub( ONE_IN_Q31, smoothedDirectionSmoothness ), alpha_synthesis[indexSlow] ) ); //(Q31, Q15) -> Q31
2122 5310420 : move32();
2123 :
2124 : /* Adjust smoothing parameter based on encoding quality */
2125 10620840 : alpha[l] =
2126 5310420 : L_add( Mpy_32_32( qualityBasedSmFactor, alpha[l] ),
2127 : Mpy_32_32( L_sub( ONE_IN_Q31, qualityBasedSmFactor ), alpha_quality_based ) ); //(Q31, Q31) -> Q31
2128 5310420 : move32();
2129 : }
2130 :
2131 : /*-----------------------------------------------------------------*
2132 : * compute gains
2133 : *-----------------------------------------------------------------*/
2134 :
2135 : /*Direct normalization gains on reduced number of protos*/
2136 92927 : p_power_smooth_prev = h_dirac_output_synthesis_state->proto_power_smooth_prev_fx;
2137 92927 : p_power_smooth = h_dirac_output_synthesis_state->proto_power_smooth_fx;
2138 92927 : set16_fx( exp_arr, 0, i_mult( num_protos_dir, num_freq_bands ) );
2139 :
2140 374531 : FOR( k = 0; k < num_protos_dir; k++ )
2141 : {
2142 16711344 : FOR( l = 0; l < num_freq_bands; l++ )
2143 : {
2144 16429740 : g1 = alpha[l]; // Q31
2145 16429740 : move32();
2146 16429740 : g2 = L_sub( ONE_IN_Q31, g1 ); // Q31
2147 16429740 : *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
2148 16429740 : move32();
2149 16429740 : *( 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
2150 16429740 : move32();
2151 :
2152 16429740 : assert( h_dirac_output_synthesis_state->proto_power_smooth_prev_q[0] == h_dirac_output_synthesis_state->proto_power_smooth_q[0] );
2153 16429740 : assert( h_dirac_output_synthesis_state->proto_power_smooth_prev_q[1] == h_dirac_output_synthesis_state->proto_power_smooth_q[1] );
2154 16429740 : IF( EQ_32( *( p_power_smooth_prev ), EPSILON_FX ) )
2155 : {
2156 23481 : p_power_smooth_prev++;
2157 23481 : L_tmp = BASOP_Util_Divide3232_Scale_newton( ONE_IN_Q31, EPSILON_FX, &exp ); /*Q=31-(exp-(31-q_proto_power_smooth))*/
2158 23481 : exp_arr[k * num_freq_bands + l] = exp;
2159 23481 : move16();
2160 :
2161 23481 : *( p_power_smooth++ ) = L_tmp; /*Q=31-(exp-(31-q_proto_power_smooth))*/
2162 23481 : move32();
2163 : }
2164 : ELSE
2165 : {
2166 16406259 : L_tmp = BASOP_Util_Divide3232_Scale_newton( ONE_IN_Q31, *( p_power_smooth_prev++ ), &exp ); /*Q=31-(exp-(31-q_proto_power_smooth))*/
2167 16406259 : exp_arr[k * num_freq_bands + l] = exp;
2168 16406259 : move16();
2169 :
2170 16406259 : *( p_power_smooth++ ) = L_tmp; /*Q=31-(exp-(31-q_proto_power_smooth))*/
2171 16406259 : move32();
2172 : }
2173 : }
2174 : }
2175 :
2176 : // Move proto_power_smooth_fx to common Q-factor
2177 :
2178 92927 : Word16 min_exp2 = -64;
2179 92927 : min_exp = MIN_16;
2180 92927 : move16();
2181 92927 : move16();
2182 92927 : Word16 q_tmp2 = Q31;
2183 92927 : q_tmp = Q31;
2184 92927 : move16();
2185 92927 : move16();
2186 :
2187 374531 : FOR( k = 0; k < num_protos_dir; k++ )
2188 : {
2189 8686524 : FOR( l = 0; l < s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ); l++ )
2190 : {
2191 8404920 : min_exp = s_max( min_exp, exp_arr[k * num_freq_bands + l] );
2192 : }
2193 8306424 : FOR( l = CLDFB_NO_CHANNELS_HALF; l < num_freq_bands; l++ )
2194 : {
2195 8024820 : min_exp2 = s_max( min_exp2, exp_arr[k * num_freq_bands + l] );
2196 : }
2197 : }
2198 :
2199 92927 : p_power_smooth = h_dirac_output_synthesis_state->proto_power_smooth_fx;
2200 :
2201 374531 : FOR( k = 0; k < num_protos_dir; k++ )
2202 : {
2203 8686524 : FOR( l = 0; l < s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ); l++ )
2204 : {
2205 8404920 : *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)))*/
2206 8404920 : move32();
2207 8404920 : p_power_smooth++;
2208 : }
2209 8306424 : FOR( l = CLDFB_NO_CHANNELS_HALF; l < num_freq_bands; l++ )
2210 : {
2211 8024820 : *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)))*/
2212 8024820 : move32();
2213 8024820 : p_power_smooth++;
2214 : }
2215 : }
2216 :
2217 : // Update the Q-factor
2218 92927 : 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] );
2219 92927 : 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] );
2220 92927 : move16();
2221 92927 : move16();
2222 :
2223 92927 : q_tmp = add( sub( Q31, min_exp ), sub( Q31, h_dirac_output_synthesis_state->proto_power_smooth_prev_q[0] ) );
2224 92927 : q_tmp2 = add( sub( Q31, min_exp2 ), sub( Q31, h_dirac_output_synthesis_state->proto_power_smooth_prev_q[1] ) );
2225 :
2226 92927 : h_dirac_output_synthesis_state->proto_power_smooth_q[0] = q_tmp;
2227 92927 : h_dirac_output_synthesis_state->proto_power_smooth_q[1] = q_tmp2;
2228 92927 : move16();
2229 92927 : move16();
2230 :
2231 : /*Direct gains and diffuse gains on number of output channels*/
2232 92927 : p_power_diff_smooth_prev = h_dirac_output_synthesis_state->proto_power_diff_smooth_prev_fx;
2233 92927 : p_power_smooth_diff = h_dirac_output_synthesis_state->proto_power_diff_smooth_fx;
2234 :
2235 92927 : p_gains_diff = gains_diff;
2236 92927 : p_gains_dir = gains_dir;
2237 :
2238 92927 : p_cy_auto_dir_smooth = h_dirac_output_synthesis_state->cy_auto_dir_smooth_fx;
2239 92927 : p_cy_auto_dir_smooth_prev = h_dirac_output_synthesis_state->cy_auto_dir_smooth_prev_fx;
2240 744059 : FOR( k = 0; k < nchan_out_woLFE; k++ )
2241 : {
2242 651132 : q_cy_auto_dir_smooth_prev_local[k] = getScaleFactor32( p_cy_auto_dir_smooth_prev + imult1616( k, num_freq_bands ), num_freq_bands );
2243 651132 : move16();
2244 651132 : 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*/
2245 651132 : 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 );
2246 651132 : move16();
2247 651132 : q_com = s_min( q_cy_auto_dir_smooth_local[k], q_cy_auto_dir_smooth_prev_local[k] );
2248 651132 : 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*/
2249 651132 : 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*/
2250 651132 : q_cy_auto_dir_smooth_local[k] = q_cy_auto_dir_smooth_prev_local[k] = q_com;
2251 651132 : move16();
2252 651132 : move16();
2253 : }
2254 :
2255 :
2256 92927 : p_cy_cross_dir_smooth = h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx;
2257 92927 : p_cy_cross_dir_smooth_prev = h_dirac_output_synthesis_state->cy_cross_dir_smooth_prev_fx;
2258 92927 : 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 );
2259 92927 : 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*/
2260 92927 : 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*/
2261 92927 : h_dirac_output_synthesis_state->q_cy_cross_dir_smooth = h_dirac_output_synthesis_state->q_cy_cross_dir_smooth_prev = q_com;
2262 92927 : move16();
2263 92927 : move16();
2264 :
2265 92927 : p_cy_auto_diff_smooth = h_dirac_output_synthesis_state->cy_auto_diff_smooth_fx;
2266 92927 : p_cy_auto_diff_smooth_prev = h_dirac_output_synthesis_state->cy_auto_diff_smooth_prev_fx;
2267 92927 : 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 );
2268 92927 : 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*/
2269 92927 : 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*/
2270 92927 : h_dirac_output_synthesis_state->q_cy_auto_diff_smooth = h_dirac_output_synthesis_state->q_cy_auto_diff_smooth_prev = q_com;
2271 92927 : move16();
2272 92927 : move16();
2273 :
2274 92927 : Word32 cmp = W_shl_sat_l( DIRAC_GAIN_LIMIT_Q26, sub( h_dirac_output_synthesis_state->gains_dir_prev_q, 26 ) );
2275 92927 : 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 ) );
2276 :
2277 744059 : FOR( k = 0; k < nchan_out_woLFE; k++ )
2278 : {
2279 : Word32 power_smooth_temp;
2280 : Word16 qidx;
2281 651132 : 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
2282 8266857 : FOR( l = 0; l < h_dirac_output_synthesis_params->max_band_decorr; l++ )
2283 : {
2284 : /*Direct*/
2285 7615725 : g1 = alpha[l]; // Q31
2286 7615725 : move32();
2287 7615725 : g2 = L_sub( ONE_IN_Q31, g1 ); // Q31
2288 7615725 : assert( q_cy_auto_dir_smooth_local[k] == q_cy_auto_dir_smooth_prev_local[k] );
2289 7615725 : *( p_cy_auto_dir_smooth_prev ) = L_add( Mpy_32_32( g1, ( *( p_cy_auto_dir_smooth++ ) ) ),
2290 : 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
2291 7615725 : move32();
2292 7615725 : assert( h_dirac_output_synthesis_state->q_cy_cross_dir_smooth == h_dirac_output_synthesis_state->q_cy_cross_dir_smooth_prev );
2293 7615725 : *( p_cy_cross_dir_smooth_prev ) = L_add( Mpy_32_32( g1, ( *( p_cy_cross_dir_smooth++ ) ) ),
2294 : Mpy_32_32( g2, ( *( p_cy_cross_dir_smooth_prev ) ) ) ); // (Q31, q_cy_cross_dir_smooth_prev) -> q_cy_cross_dir_smooth_prev
2295 7615725 : move32();
2296 :
2297 7615725 : power_smooth_temp = L_shl( *p_power_smooth, norm_l( *p_power_smooth ) ); // proto_power_smooth_q + norm_l( *p_power_smooth )
2298 7615725 : 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
2299 7615725 : qidx = s_min( 1, s_max( 0, sub( l, CLDFB_NO_CHANNELS_HALF - 1 ) ) );
2300 7615725 : exp = sub( Q31, sub( add( add( h_dirac_output_synthesis_state->proto_power_smooth_q[qidx], norm_l( *p_power_smooth ) ),
2301 7615725 : q_cy_auto_dir_smooth_prev_local[k] ),
2302 : Q31 ) );
2303 :
2304 7615725 : p_power_smooth++;
2305 :
2306 7615725 : *( p_gains_dir ) = Sqrt32( L_tmp, &exp ); // (Q31 - exp)
2307 7615725 : move32();
2308 7615725 : *( 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
2309 7615725 : move32();
2310 :
2311 7615725 : IF( *( p_gains_dir ) < 0 )
2312 : {
2313 0 : *( p_gains_dir ) = 0;
2314 0 : move32();
2315 : }
2316 7615725 : ELSE IF( GT_32( *( p_gains_dir ), cmp ) )
2317 : {
2318 18545 : *( 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*/
2319 18545 : move32();
2320 : }
2321 :
2322 7615725 : IF( *( p_cy_cross_dir_smooth_prev++ ) < 0 )
2323 : {
2324 884529 : *( p_gains_dir ) = L_negate( *( p_gains_dir ) ); /*h_dirac_output_synthesis_state->gains_dir_prev_q*/
2325 884529 : move32();
2326 : }
2327 7615725 : p_gains_dir++;
2328 :
2329 : /*diffuse*/
2330 7615725 : *p_power_diff_smooth_prev = L_add( L_add( Mpy_32_32( g1, ( *( p_power_smooth_diff++ ) ) ),
2331 : Mpy_32_32( g2, ( *( p_power_diff_smooth_prev ) ) ) ),
2332 : EPSILLON_FX ); // (Q31, q_power_diff_smooth_prev) -> q_power_diff_smooth_prev
2333 7615725 : move32();
2334 7615725 : *( p_cy_auto_diff_smooth_prev ) = L_add( Mpy_32_32( g1, ( *( p_cy_auto_diff_smooth++ ) ) ),
2335 : Mpy_32_32( g2, ( *( p_cy_auto_diff_smooth_prev ) ) ) ); // (Q31, q_cy_auto_diff_smooth_prev) -> q_cy_auto_diff_smooth_prev
2336 7615725 : move32();
2337 :
2338 7615725 : exp = 0;
2339 7615725 : move16();
2340 7615725 : 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)
2341 7615725 : 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 ) ) );
2342 :
2343 7615725 : *( p_gains_diff ) = Sqrt32( L_tmp, &exp ); // (31 - exp)
2344 7615725 : move32();
2345 7615725 : *( 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
2346 7615725 : move32();
2347 :
2348 7615725 : IF( *( p_gains_diff ) < 0 )
2349 : {
2350 0 : *( p_gains_diff ) = 0;
2351 0 : move32();
2352 : }
2353 7615725 : ELSE IF( GT_32( *( p_gains_diff ), cmp2 ) ) /*h_dirac_output_synthesis_state->gains_diff_prev_q*/
2354 : {
2355 144762 : *( p_gains_diff ) = cmp2; /*h_dirac_output_synthesis_state->gains_diff_prev_q*/
2356 144762 : move32();
2357 : }
2358 7615725 : p_gains_diff++;
2359 : }
2360 :
2361 : /*Only direct prototype*/
2362 30734527 : FOR( ; l < num_freq_bands; l++ )
2363 : {
2364 : /*Direct*/
2365 30083395 : g1 = alpha[l]; // Q31
2366 30083395 : move32();
2367 30083395 : g2 = L_sub( ONE_IN_Q31, g1 ); // Q31
2368 30083395 : W_temp = W_mac_32_32( W_mult_32_32( g1, ( *( p_cy_auto_dir_smooth++ ) ) ),
2369 : g2, ( *( p_cy_auto_dir_smooth_prev ) ) ); /*32+q_cy_auto_dir_smooth_prev_local*/
2370 30083395 : q_tmp = W_norm( W_temp );
2371 30083395 : L_tmp = W_extract_h( W_shl( W_temp, q_tmp ) ); // q_cy_auto_dir_smooth_prev_local + q_tmp
2372 30083395 : *( p_cy_auto_dir_smooth_prev++ ) = L_shr_r( L_tmp, q_tmp ); // q_cy_auto_dir_smooth_prev_local
2373 :
2374 30083395 : move32();
2375 30083395 : *( p_cy_cross_dir_smooth_prev ) = Madd_32_32( Mpy_32_32( g1, ( *( p_cy_cross_dir_smooth ) ) ),
2376 : g2, ( *( p_cy_cross_dir_smooth_prev ) ) ); // (Q31, q_cy_cross_dir_smooth_prev) -> q_cy_cross_dir_smooth_prev
2377 30083395 : move32();
2378 30083395 : test();
2379 30083395 : if ( *( p_cy_cross_dir_smooth_prev ) == 0 && ( *( p_cy_cross_dir_smooth ) != 0 ) )
2380 : {
2381 1311178 : *( p_cy_cross_dir_smooth_prev ) = 1;
2382 1311178 : move32();
2383 : }
2384 30083395 : ( p_cy_cross_dir_smooth++ );
2385 30083395 : power_smooth_temp = L_shl( *p_power_smooth, norm_l( *p_power_smooth ) );
2386 30083395 : 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
2387 30083395 : qidx = s_min( 1, s_max( 0, sub( l, CLDFB_NO_CHANNELS_HALF - 1 ) ) );
2388 30083395 : exp = sub( Q31, sub( add( add( h_dirac_output_synthesis_state->proto_power_smooth_q[qidx], norm_l( *p_power_smooth ) ),
2389 30083395 : add( q_cy_auto_dir_smooth_prev_local[k], q_tmp ) ),
2390 : Q31 ) );
2391 :
2392 30083395 : *( p_gains_dir ) = Sqrt32( L_tmp, &exp ); // (Q31 - exp)
2393 30083395 : move32();
2394 30083395 : *( 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
2395 30083395 : move32();
2396 :
2397 30083395 : IF( *( p_gains_dir ) < 0 )
2398 : {
2399 0 : *( p_gains_dir ) = 0;
2400 0 : move32();
2401 : }
2402 30083395 : ELSE IF( GT_32( *( p_gains_dir ), cmp ) ) /*gains_dir_prev_q*/
2403 : {
2404 25782 : *( p_gains_dir ) = cmp; /*gains_dir_prev_q*/
2405 25782 : move32();
2406 : }
2407 :
2408 30083395 : IF( *( p_cy_cross_dir_smooth_prev++ ) < 0 )
2409 : {
2410 3035844 : *( p_gains_dir ) = L_negate( *( p_gains_dir ) ); /*gains_dir_prev_q*/
2411 3035844 : move32();
2412 : }
2413 30083395 : p_gains_dir++;
2414 :
2415 : /*diffuse*/
2416 30083395 : *( p_cy_auto_diff_smooth_prev ) = L_add( Mpy_32_32( g1, ( *( p_cy_auto_diff_smooth ) ) ),
2417 : Mpy_32_32( g2, ( *( p_cy_auto_diff_smooth_prev ) ) ) ); // (Q31, q_cy_auto_diff_smooth_prev) -> q_cy_auto_diff_smooth_prev
2418 :
2419 30083395 : test();
2420 30083395 : if ( *( p_cy_auto_diff_smooth_prev ) == 0 && ( *( p_cy_auto_diff_smooth ) != 0 ) )
2421 : {
2422 2050113 : *( p_cy_auto_diff_smooth_prev ) = 1;
2423 2050113 : move32();
2424 : }
2425 30083395 : ( p_cy_auto_diff_smooth++ );
2426 30083395 : move32();
2427 :
2428 30083395 : power_smooth_temp = L_shl( *p_power_smooth, norm_l( *p_power_smooth ) ); // proto_power_smooth_q + norm_l( *p_power_smooth )
2429 30083395 : 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
2430 :
2431 30083395 : test();
2432 30083395 : test();
2433 30083395 : if ( L_tmp == 0 && ( power_smooth_temp != 0 && *( p_cy_auto_diff_smooth_prev ) != 0 ) )
2434 : {
2435 2544299 : L_tmp = 1;
2436 2544299 : move32();
2437 : }
2438 30083395 : ( p_cy_auto_diff_smooth_prev++ );
2439 30083395 : exp = sub( Q31, sub( add( add( h_dirac_output_synthesis_state->proto_power_smooth_q[qidx], norm_l( *p_power_smooth ) ),
2440 30083395 : h_dirac_output_synthesis_state->q_cy_auto_diff_smooth_prev ),
2441 : Q31 ) );
2442 30083395 : p_power_smooth++;
2443 :
2444 30083395 : *( p_gains_diff ) = Sqrt32( L_tmp, &exp ); /*31-exp*/
2445 30083395 : move32();
2446 30083395 : *( 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
2447 30083395 : move32();
2448 :
2449 30083395 : IF( *( p_gains_diff ) < 0 )
2450 : {
2451 0 : *( p_gains_diff ) = 0;
2452 0 : move32();
2453 : }
2454 30083395 : 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
2455 : {
2456 18547 : *( 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
2457 18547 : move32();
2458 : }
2459 30083395 : p_gains_diff++;
2460 : }
2461 : }
2462 :
2463 : /*-----------------------------------------------------------------*
2464 : * gain interpolation and output streams
2465 : *-----------------------------------------------------------------*/
2466 92927 : Word16 q_align = sub( h_dirac_output_synthesis_state->proto_direct_buffer_f_q, h_dirac_output_synthesis_state->proto_power_diff_smooth_q );
2467 92927 : if ( h_dirac_output_synthesis_params->max_band_decorr != 0 )
2468 : {
2469 69510 : q_align = sub( h_dirac_output_synthesis_state->proto_direct_buffer_f_q, h_dirac_output_synthesis_state->proto_diffuse_buffer_f_q );
2470 : }
2471 :
2472 461651 : FOR( buf_idx = 0; buf_idx < nbslots; ++buf_idx )
2473 : {
2474 368724 : g1 = L_deposit_h( h_dirac_output_synthesis_params->interpolator_fx[buf_idx] ); // Q15 -> Q31
2475 368724 : g2 = L_sub( ONE_IN_Q31, g1 ); // Q31
2476 :
2477 : /*Direct stream*/
2478 368724 : p_gain_1 = gains_dir;
2479 368724 : p_gain_2 = h_dirac_output_synthesis_state->gains_dir_prev_fx; // gains_dir_prev_q
2480 2969722 : FOR( k = 0; k < nchan_out_woLFE; k++ )
2481 : {
2482 5201996 : p_power_smooth = h_dirac_output_synthesis_state->proto_direct_buffer_f_fx +
2483 2600998 : shl( i_mult( buf_idx, i_mult( num_freq_bands, num_protos_dir ) ), Q1 ) +
2484 2600998 : shl( i_mult( proto_direct_index[k], num_freq_bands ), Q1 );
2485 153243538 : FOR( l = 0; l < num_freq_bands; l++ )
2486 : {
2487 150642540 : g = Madd_32_32( Mpy_32_32( g1, *( p_gain_1++ ) ), g2, *( p_gain_2++ ) ); // (Q31, gains_dir_prev_q) -> gains_dir_prev_q
2488 :
2489 150642540 : 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
2490 150642540 : move64();
2491 :
2492 150642540 : 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
2493 150642540 : move64();
2494 : }
2495 : }
2496 :
2497 : /*Diffuse stream*/
2498 368724 : IF( h_dirac_output_synthesis_params->max_band_decorr != 0 )
2499 : {
2500 555898 : p_power_smooth_diff = h_dirac_output_synthesis_state->proto_diffuse_buffer_f_fx +
2501 277949 : shl( i_mult( buf_idx, i_mult( h_dirac_output_synthesis_params->max_band_decorr, nchan_out_woLFE ) ), Q1 );
2502 : }
2503 368724 : p_gain_1 = gains_diff;
2504 368724 : p_gain_2 = h_dirac_output_synthesis_state->gains_diff_prev_fx; // gains_diff_prev_q
2505 2969722 : FOR( k = 0; k < nchan_out_woLFE; k++ )
2506 : {
2507 33054343 : FOR( l = 0; l < h_dirac_output_synthesis_params->max_band_decorr; l++ )
2508 : {
2509 30453345 : g = Madd_32_32( Mpy_32_32( g1, *( p_gain_1++ ) ), g2, *( p_gain_2++ ) ); // (Q31, gains_diff_prev_q) -> gains_diff_prev_q
2510 30453345 : Cldfb_RealBuffer64_fx[k][buf_idx][l] = W_add( Cldfb_RealBuffer64_fx[k][buf_idx][l],
2511 30453345 : 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
2512 30453345 : move64();
2513 :
2514 30453345 : if ( LT_64( W_temp, W_abs( Cldfb_RealBuffer64_fx[k][buf_idx][l] ) ) )
2515 : {
2516 215301 : W_temp = W_abs( Cldfb_RealBuffer64_fx[k][buf_idx][l] );
2517 : }
2518 :
2519 30453345 : Cldfb_ImagBuffer64_fx[k][buf_idx][l] = W_add( Cldfb_ImagBuffer64_fx[k][buf_idx][l],
2520 30453345 : 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
2521 30453345 : move64();
2522 :
2523 30453345 : if ( LT_64( W_temp, W_abs( Cldfb_ImagBuffer64_fx[k][buf_idx][l] ) ) )
2524 : {
2525 120320 : W_temp = W_abs( Cldfb_ImagBuffer64_fx[k][buf_idx][l] );
2526 : }
2527 : }
2528 :
2529 : /*Direct proto*/
2530 5201996 : p_power_smooth = h_dirac_output_synthesis_state->proto_direct_buffer_f_fx +
2531 2600998 : shl( i_mult( buf_idx, i_mult( num_freq_bands, num_protos_dir ) ), Q1 ) +
2532 2600998 : shl( i_mult( proto_direct_index[k], num_freq_bands ), Q1 ) +
2533 2600998 : shl( h_dirac_output_synthesis_params->max_band_decorr, Q1 );
2534 122790193 : FOR( ; l < num_freq_bands; l++ )
2535 : {
2536 120189195 : 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
2537 120189195 : Cldfb_RealBuffer64_fx[k][buf_idx][l] = W_add( Cldfb_RealBuffer64_fx[k][buf_idx][l],
2538 120189195 : W_mult0_32_32( g, ( *( p_power_smooth++ ) ) ) ); // (gains_diff_prev_q, q_proto_direct_buffer) -> gains_diff_prev_q + q_proto_direct_buffer
2539 120189195 : move64();
2540 :
2541 120189195 : if ( LT_64( W_temp, W_abs( Cldfb_RealBuffer64_fx[k][buf_idx][l] ) ) )
2542 : {
2543 70956 : W_temp = W_abs( Cldfb_RealBuffer64_fx[k][buf_idx][l] );
2544 : }
2545 :
2546 120189195 : Cldfb_ImagBuffer64_fx[k][buf_idx][l] = W_add( Cldfb_ImagBuffer64_fx[k][buf_idx][l],
2547 120189195 : W_mult0_32_32( g, ( *( p_power_smooth++ ) ) ) ); // (gains_diff_prev_q, q_proto_direct_buffer) -> gains_diff_prev_q + q_proto_direct_buffer
2548 120189195 : move64();
2549 :
2550 120189195 : if ( LT_64( W_temp, W_abs( Cldfb_ImagBuffer64_fx[k][buf_idx][l] ) ) )
2551 : {
2552 40466 : W_temp = W_abs( Cldfb_ImagBuffer64_fx[k][buf_idx][l] ); // gains_diff_prev_q + q_proto_direct_buffer
2553 : }
2554 : }
2555 : }
2556 : }
2557 92927 : q_align = W_norm( W_temp );
2558 92927 : Word16 shift = sub( q_align, 32 );
2559 :
2560 461651 : FOR( buf_idx = 0; buf_idx < nbslots; ++buf_idx )
2561 : {
2562 2969722 : FOR( k = 0; k < nchan_out_woLFE; k++ )
2563 : {
2564 153243538 : FOR( l = 0; l < num_freq_bands; l++ )
2565 : {
2566 150642540 : 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 )*/
2567 150642540 : move32();
2568 150642540 : 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 )*/
2569 150642540 : move32();
2570 : }
2571 : }
2572 : }
2573 :
2574 92927 : *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 );
2575 92927 : move16();
2576 :
2577 : /*-----------------------------------------------------------------*
2578 : * update buffers
2579 : *-----------------------------------------------------------------*/
2580 :
2581 : /* store estimates for next synthesis block */
2582 92927 : Copy32( gains_dir, h_dirac_output_synthesis_state->gains_dir_prev_fx, imult1616( num_freq_bands, nchan_out_woLFE ) ); /*gains_dir_prev_q*/
2583 92927 : Copy32( gains_diff, h_dirac_output_synthesis_state->gains_diff_prev_fx, imult1616( num_freq_bands, nchan_out_woLFE ) ); /*gains_diff_prev_q*/
2584 :
2585 : /* reset values */
2586 92927 : set_zero_fx( h_dirac_output_synthesis_state->proto_power_smooth_fx, imult1616( num_freq_bands, num_protos_dir ) );
2587 92927 : IF( h_dirac_output_synthesis_state->proto_power_diff_smooth_fx != NULL )
2588 : {
2589 92927 : set_zero_fx( h_dirac_output_synthesis_state->proto_power_diff_smooth_fx, h_dirac_output_synthesis_params->max_band_decorr * nchan_out_woLFE );
2590 : }
2591 :
2592 92927 : minimum_fx( q_cy_auto_dir_smooth_prev_local, nchan_out_woLFE, &h_dirac_output_synthesis_state->q_cy_auto_dir_smooth_prev );
2593 744059 : FOR( k = 0; k < nchan_out_woLFE; k++ )
2594 : {
2595 651132 : 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*/
2596 : }
2597 :
2598 92927 : set_zero_fx( h_dirac_output_synthesis_state->cy_auto_dir_smooth_fx, imult1616( num_freq_bands, nchan_out_woLFE ) );
2599 92927 : h_dirac_output_synthesis_state->q_cy_auto_dir_smooth = 0;
2600 92927 : move16();
2601 92927 : set_zero_fx( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx, imult1616( num_freq_bands, nchan_out_woLFE ) );
2602 92927 : h_dirac_output_synthesis_state->q_cy_cross_dir_smooth = 0;
2603 92927 : move16();
2604 92927 : set_zero_fx( h_dirac_output_synthesis_state->cy_auto_diff_smooth_fx, imult1616( num_freq_bands, nchan_out_woLFE ) );
2605 92927 : h_dirac_output_synthesis_state->q_cy_auto_diff_smooth = 0;
2606 92927 : move16();
2607 :
2608 92927 : pop_wmops();
2609 :
2610 92927 : return;
2611 : }
2612 :
2613 :
2614 : /*-------------------------------------------------------------------------
2615 : * ivas_dirac_dec_compute_directional_responses()
2616 : *
2617 : *
2618 : *------------------------------------------------------------------------*/
2619 :
2620 1087261 : void ivas_dirac_dec_compute_directional_responses_fx(
2621 : SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common spatial renderer data handle */
2622 : DIRAC_REND_HANDLE hDirACRend, /* i/o: DirAC renderer handle */
2623 : const VBAP_HANDLE hVBAPdata, /* i : VBAP structure */
2624 : const Word16 *masa_band_mapping, /* i : Band mapping for MASA, NULL assumes not using MASA in any form */
2625 : MASA_ISM_DATA_HANDLE hMasaIsm, /* i : MASA_ISM data structure */
2626 : const Word16 *azimuth,
2627 : const Word16 *elevation,
2628 : const Word16 md_idx,
2629 : const Word32 *surCohRatio_fx, /*i:Q_surCohRatio*/
2630 : Word16 Q_surCohRatio,
2631 : const Word16 hodirac_flag /* i : flag to indicate HO-DirAC mode */
2632 : )
2633 : {
2634 : Word16 k, l, i;
2635 : Word16 num_channels_dir;
2636 : const Word16 *azimuth2, *elevation2;
2637 :
2638 : Word32 direct_response_hoa_fx[MAX_OUTPUT_CHANNELS]; /* number of output channels (HOA 3rd order) -> 16 */
2639 : Word32 direct_response_ls_fx[MAX_OUTPUT_CHANNELS];
2640 : Word32 direct_response_square_fx[MAX_OUTPUT_CHANNELS];
2641 : Word32 direct_response_dir2_fx[MAX_OUTPUT_CHANNELS];
2642 : Word32 directRatio_fx[MASA_MAXIMUM_DIRECTIONS];
2643 : Word16 Q_direct_response_ls, exp_direct_response_ls;
2644 : Word16 Q_direct_response_dir2, exp_direct_response_dir2;
2645 : Word16 Q_direct_response_hoa, exp_direct_response_hoa;
2646 : Word16 direct_response_square_q, direct_response_q;
2647 1087261 : Word16 exp_surCohRatio = sub( 31, Q_surCohRatio );
2648 : Word32 totalDirect_fx;
2649 : Word32 *direct_response_fx;
2650 : Word16 codingBand;
2651 : Word16 dipole_freq_range[2];
2652 : MASA_TRANSPORT_SIGNAL_TYPE transport_signal_type;
2653 :
2654 1087261 : Q_direct_response_ls = Q31;
2655 1087261 : move16();
2656 1087261 : exp_direct_response_ls = 0;
2657 1087261 : move16();
2658 1087261 : Q_direct_response_dir2 = Q31;
2659 1087261 : move16();
2660 1087261 : exp_direct_response_dir2 = 0;
2661 1087261 : move16();
2662 1087261 : Q_direct_response_hoa = Q31;
2663 1087261 : move16();
2664 1087261 : exp_direct_response_hoa = 0;
2665 1087261 : move16();
2666 1087261 : direct_response_square_q = Q31;
2667 1087261 : move16();
2668 1087261 : direct_response_q = Q29;
2669 1087261 : move16();
2670 :
2671 1087261 : azimuth2 = NULL;
2672 1087261 : elevation2 = NULL;
2673 1087261 : transport_signal_type = MASA_STEREO_NOT_DEFINED;
2674 1087261 : move32();
2675 :
2676 1087261 : IF( hDirACRend->masa_stereo_type_detect != NULL )
2677 : {
2678 16209 : dipole_freq_range[0] = hDirACRend->masa_stereo_type_detect->dipole_freq_range[0];
2679 16209 : move16();
2680 16209 : dipole_freq_range[1] = hDirACRend->masa_stereo_type_detect->dipole_freq_range[1];
2681 16209 : move16();
2682 16209 : transport_signal_type = hDirACRend->masa_stereo_type_detect->masa_stereo_type;
2683 16209 : move16();
2684 : }
2685 :
2686 1087261 : num_channels_dir = hDirACRend->num_outputs_dir;
2687 1087261 : move16();
2688 1087261 : IF( EQ_16( hSpatParamRendCom->numParametricDirections, 2 ) )
2689 : {
2690 280616 : azimuth2 = hSpatParamRendCom->azimuth2[md_idx]; /*q0*/
2691 280616 : move16();
2692 280616 : elevation2 = hSpatParamRendCom->elevation2[md_idx]; /*q0*/
2693 280616 : move16();
2694 : }
2695 :
2696 1087261 : codingBand = -1;
2697 :
2698 1087261 : assert( num_channels_dir <= MAX_OUTPUT_CHANNELS && "Number of channels is too high" );
2699 :
2700 59658381 : FOR( k = 0; k < hSpatParamRendCom->num_freq_bands; ++k )
2701 : {
2702 58571120 : test();
2703 58571120 : if ( masa_band_mapping != NULL && EQ_16( k, MASA_band_grouping_24[masa_band_mapping[add( codingBand, 1 )]] ) )
2704 : {
2705 1031998 : codingBand = add( codingBand, 1 );
2706 : }
2707 :
2708 58571120 : test();
2709 58571120 : test();
2710 58571120 : test();
2711 58571120 : IF( masa_band_mapping != NULL && GT_16( k, MASA_band_grouping_24[masa_band_mapping[codingBand]] ) &&
2712 : LT_16( k, MASA_band_grouping_24[masa_band_mapping[add( codingBand, 1 )]] ) &&
2713 : NE_16( k, hDirACRend->h_output_synthesis_psd_params.max_band_decorr ) )
2714 : {
2715 : /* 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 */
2716 4157668 : IF( NE_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) )
2717 : {
2718 3567163 : mvr2r_inc_fixed( &hDirACRend->h_output_synthesis_psd_state.direct_responses_square_fx[k - 1],
2719 3567163 : hSpatParamRendCom->num_freq_bands, &hDirACRend->h_output_synthesis_psd_state.direct_responses_square_fx[k],
2720 3567163 : hSpatParamRendCom->num_freq_bands, num_channels_dir ); /*direct_response_square_q*/
2721 : }
2722 4157668 : mvr2r_inc_fixed( &hDirACRend->h_output_synthesis_psd_state.direct_responses_fx[k - 1],
2723 4157668 : hSpatParamRendCom->num_freq_bands,
2724 4157668 : &hDirACRend->h_output_synthesis_psd_state.direct_responses_fx[k],
2725 4157668 : hSpatParamRendCom->num_freq_bands, num_channels_dir ); /*direct_response_q*/
2726 : }
2727 : ELSE
2728 : {
2729 : /* HOA3 PANNING */
2730 54413452 : IF( EQ_16( hDirACRend->panningConf, DIRAC_PANNING_HOA3 ) )
2731 : {
2732 50453749 : set32_fx( direct_response_hoa_fx, ONE_IN_Q29, MAX_OUTPUT_CHANNELS ); /*q29*/
2733 50453749 : set32_fx( direct_response_dir2_fx, ONE_IN_Q29, MAX_OUTPUT_CHANNELS ); /*q29*/
2734 :
2735 50453749 : Q_direct_response_hoa = Q29;
2736 50453749 : move16();
2737 50453749 : Q_direct_response_dir2 = Q29;
2738 50453749 : move16();
2739 50453749 : exp_direct_response_hoa = 0;
2740 50453749 : move16();
2741 50453749 : exp_direct_response_dir2 = 0;
2742 50453749 : move16();
2743 :
2744 50453749 : ivas_dirac_dec_get_response_fx_29( azimuth[k], elevation[k], direct_response_hoa_fx, hDirACRend->hOutSetup.ambisonics_order );
2745 :
2746 50453749 : IF( hodirac_flag )
2747 : {
2748 15810800 : ivas_dirac_dec_get_response_fx_29( azimuth2[k], elevation2[k], direct_response_dir2_fx, hDirACRend->hOutSetup.ambisonics_order );
2749 : }
2750 :
2751 50453749 : test();
2752 50453749 : test();
2753 50453749 : test();
2754 50453749 : test();
2755 50453749 : IF( masa_band_mapping == NULL && EQ_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) )
2756 : {
2757 50005640 : 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*/
2758 :
2759 50005640 : IF( hodirac_flag )
2760 : {
2761 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*/
2762 : }
2763 : }
2764 448109 : ELSE IF( ( ( EQ_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) ) && ( masa_band_mapping != NULL ) ) ||
2765 : EQ_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_PSD_SHD ) || EQ_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_MONO ) )
2766 : {
2767 : /* Synthesize the first direction */
2768 448109 : IF( GT_16( Q_direct_response_hoa, Q29 ) )
2769 : {
2770 0 : Scale_sig32( direct_response_hoa_fx, MAX_OUTPUT_CHANNELS, sub( Q_direct_response_hoa, Q29 ) ); /*Q_direct_response_hoa->q29*/
2771 0 : Q_direct_response_hoa = Q29;
2772 0 : move16();
2773 0 : exp_direct_response_hoa = sub( 31, Q_direct_response_hoa );
2774 : }
2775 448109 : spreadCoherencePanningHoa_fx( azimuth[k], elevation[k], hSpatParamRendCom->spreadCoherence_fx[md_idx][k],
2776 448109 : direct_response_hoa_fx, &Q_direct_response_hoa, num_channels_dir, hDirACRend->hOutSetup.ambisonics_order );
2777 :
2778 448109 : exp_direct_response_hoa = sub( 31, Q_direct_response_hoa );
2779 : /* Synthesize the second direction and combine the gains */
2780 448109 : IF( EQ_16( hSpatParamRendCom->numParametricDirections, 2 ) )
2781 : {
2782 118200 : IF( GT_16( Q_direct_response_dir2, Q29 ) )
2783 : {
2784 0 : Scale_sig32( direct_response_dir2_fx, MAX_OUTPUT_CHANNELS, sub( Q_direct_response_dir2, Q29 ) ); /*Q_direct_response_dir2->q29*/
2785 0 : Q_direct_response_dir2 = Q29;
2786 0 : move16();
2787 0 : exp_direct_response_dir2 = sub( 31, Q_direct_response_dir2 );
2788 : }
2789 118200 : spreadCoherencePanningHoa_fx( azimuth2[k], elevation2[k], hSpatParamRendCom->spreadCoherence2_fx[md_idx][k],
2790 118200 : direct_response_dir2_fx, &Q_direct_response_dir2, num_channels_dir, hDirACRend->hOutSetup.ambisonics_order );
2791 :
2792 118200 : exp_direct_response_hoa = sub( 31, Q_direct_response_hoa );
2793 : /* Combine gains from the two directions */
2794 118200 : totalDirect_fx = L_add( hSpatParamRendCom->energy_ratio1_fx[md_idx][k], hSpatParamRendCom->energy_ratio2_fx[md_idx][k] ); /*q30*/
2795 118200 : IF( totalDirect_fx == 0 )
2796 : {
2797 10 : totalDirect_fx = EPSILON_FIX;
2798 10 : move32();
2799 : }
2800 :
2801 : Word16 var_a, var_b, exp_1, exp_2;
2802 118200 : var_a = BASOP_Util_Divide3232_Scale( hSpatParamRendCom->energy_ratio1_fx[md_idx][k], totalDirect_fx, &exp_1 ); /*15-exp_1*/
2803 118200 : var_b = BASOP_Util_Divide3232_Scale( hSpatParamRendCom->energy_ratio2_fx[md_idx][k], totalDirect_fx, &exp_2 ); /*15-exp_2*/
2804 :
2805 118200 : directRatio_fx[0] = L_deposit_h( var_a ); /*15-exp_1+16*/
2806 118200 : move32();
2807 118200 : directRatio_fx[1] = L_deposit_h( var_b ); /*15-exp_2+16*/
2808 118200 : move32();
2809 :
2810 : Word32 temp_a;
2811 : Word16 exp_arr[MAX_OUTPUT_CHANNELS], exp_temp_a, final_exp;
2812 118200 : set16_fx( exp_arr, exp_direct_response_hoa, MAX_OUTPUT_CHANNELS );
2813 118200 : exp_direct_response_hoa = sub( 31, Q_direct_response_hoa );
2814 :
2815 1023000 : FOR( l = 0; l < num_channels_dir; l++ )
2816 : {
2817 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)*/
2818 904800 : move32();
2819 904800 : exp_arr[l] = add( exp_1, sub( 31, Q_direct_response_hoa ) );
2820 904800 : move16();
2821 904800 : temp_a = Mpy_32_32( directRatio_fx[1], direct_response_dir2_fx[l] ); /*Q(Q_direct_response_dir2+31-exp_2-31)*/
2822 904800 : exp_temp_a = add( exp_2, sub( 31, Q_direct_response_dir2 ) );
2823 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)*/
2824 904800 : move32();
2825 904800 : exp_arr[l] = final_exp;
2826 904800 : move16();
2827 : }
2828 :
2829 118200 : Word16 max_exp = MIN16B;
2830 118200 : move16();
2831 118200 : maximum_fx( exp_arr, MAX_OUTPUT_CHANNELS, &max_exp );
2832 2009400 : FOR( l = 0; l < MAX_OUTPUT_CHANNELS; l++ )
2833 : {
2834 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)*/
2835 1891200 : move32();
2836 : }
2837 118200 : exp_direct_response_hoa = max_exp;
2838 118200 : move16();
2839 118200 : Q_direct_response_hoa = sub( 31, max_exp );
2840 : }
2841 :
2842 448109 : IF( hSpatParamRendCom->numIsmDirections > 0 )
2843 : {
2844 : Word16 dir;
2845 : Word32 direct_response_temp_fx[MAX_OUTPUT_CHANNELS];
2846 : Word32 direct_response_ism_fx[MAX_OUTPUT_CHANNELS];
2847 8152 : Word16 exp_direct_response_ism = 0, exp_direct_response_temp;
2848 : Word32 masaDirect_fx;
2849 : Word32 ismDirect_fx;
2850 8152 : move16();
2851 :
2852 8152 : set32_fx( direct_response_ism_fx, 0, num_channels_dir );
2853 :
2854 40760 : FOR( dir = 0; dir < hSpatParamRendCom->numIsmDirections; dir++ )
2855 : {
2856 32608 : IF( hMasaIsm->ism_is_edited[dir] )
2857 : {
2858 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 );
2859 : }
2860 : ELSE
2861 : {
2862 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 );
2863 : }
2864 32608 : exp_direct_response_temp = 2;
2865 32608 : move16();
2866 :
2867 32608 : Word32 temp_1 = 0;
2868 32608 : Word16 exp_temp = 0, exp_arr[MAX_OUTPUT_CHANNELS];
2869 32608 : move16();
2870 32608 : move16();
2871 32608 : set16_fx( exp_arr, 0, MAX_OUTPUT_CHANNELS );
2872 348992 : FOR( l = 0; l < num_channels_dir; l++ )
2873 : {
2874 316384 : temp_1 = Mpy_32_32( direct_response_temp_fx[l], hMasaIsm->energy_ratio_ism_fx[dir][md_idx][k] ); // Q28
2875 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)
2876 316384 : move32();
2877 316384 : exp_arr[l] = exp_temp;
2878 316384 : move16();
2879 : }
2880 32608 : Word16 max_exp = MIN16B;
2881 32608 : move16();
2882 32608 : maximum_fx( exp_arr, num_channels_dir, &max_exp );
2883 348992 : FOR( l = 0; l < num_channels_dir; l++ )
2884 : {
2885 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)*/
2886 316384 : move32();
2887 : }
2888 32608 : exp_direct_response_ism = max_exp;
2889 32608 : move16();
2890 : }
2891 : Word16 exp_1, exp_2;
2892 8152 : masaDirect_fx = hSpatParamRendCom->energy_ratio1_fx[md_idx][k]; /*q30*/
2893 8152 : move32();
2894 8152 : if ( masaDirect_fx == 0 )
2895 : {
2896 92 : masaDirect_fx = L_add( masaDirect_fx, EPSILLON_FX ); /*q30*/
2897 : }
2898 8152 : if ( EQ_16( hSpatParamRendCom->numParametricDirections, 2 ) )
2899 : {
2900 0 : masaDirect_fx = L_add( masaDirect_fx, hSpatParamRendCom->energy_ratio2_fx[md_idx][k] ); /*q30*/
2901 : }
2902 :
2903 8152 : ismDirect_fx = hMasaIsm->energy_ratio_ism_fx[0][md_idx][k]; /*q30*/
2904 8152 : move32();
2905 32608 : FOR( dir = 1; dir < hSpatParamRendCom->numIsmDirections; dir++ )
2906 : {
2907 24456 : ismDirect_fx = L_add( ismDirect_fx, hMasaIsm->energy_ratio_ism_fx[dir][md_idx][k] ); /*q30*/
2908 : }
2909 :
2910 8152 : totalDirect_fx = L_add_sat( masaDirect_fx, ismDirect_fx ); /*q30*/ // saturating as 1.0 (Q30) + 1.0 (Q30) is observed
2911 8152 : Word16 var_a = 0, var_b = 0;
2912 8152 : var_a = BASOP_Util_Divide3232_Scale( masaDirect_fx, totalDirect_fx, &exp_1 ); /*Q(15-exp_1)*/
2913 8152 : var_b = BASOP_Util_Divide3232_Scale( ismDirect_fx, totalDirect_fx, &exp_2 ); /*q(15-exp_2)*/
2914 8152 : directRatio_fx[0] = L_deposit_h( var_a ); // Q(31-exp_1)
2915 8152 : move32();
2916 8152 : directRatio_fx[1] = L_deposit_h( var_b ); // Q(31-exp_2)
2917 8152 : move32();
2918 :
2919 : Word32 temp_2, temp_3;
2920 : Word16 exp_arr[MAX_OUTPUT_CHANNELS], exp_temp_3;
2921 8152 : set16_fx( exp_arr, exp_direct_response_hoa, MAX_OUTPUT_CHANNELS );
2922 87248 : FOR( l = 0; l < num_channels_dir; l++ )
2923 : {
2924 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*/
2925 79096 : move32();
2926 79096 : exp_arr[l] = add( exp_direct_response_hoa, exp_1 );
2927 79096 : move16();
2928 79096 : temp_2 = Mpy_32_32( directRatio_fx[1], direct_response_ism_fx[l] ); /*31-exp_direct_response_ism+31-exp_2-31*/
2929 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*/
2930 :
2931 79096 : direct_response_hoa_fx[l] = temp_3; /*31-exp_temp_3*/
2932 79096 : move32();
2933 79096 : exp_arr[l] = exp_temp_3;
2934 79096 : move16();
2935 : }
2936 :
2937 8152 : Word16 max_exp = MIN16B;
2938 8152 : move16();
2939 8152 : maximum_fx( exp_arr, num_channels_dir, &max_exp );
2940 87248 : FOR( l = 0; l < num_channels_dir; l++ )
2941 : {
2942 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)*/
2943 79096 : move32();
2944 : }
2945 8152 : Q_direct_response_hoa = sub( 31, max_exp );
2946 8152 : exp_direct_response_hoa = max_exp;
2947 8152 : move16();
2948 : }
2949 :
2950 : /* Synthesize surrounding coherence */
2951 448109 : IF( surCohRatio_fx != NULL && surCohRatio_fx[k] > 0 )
2952 : {
2953 : Word32 var_a, var_b;
2954 : Word16 exp_arr[MAX_OUTPUT_CHANNELS], exp;
2955 279212 : set16_fx( exp_arr, exp_direct_response_hoa, MAX_OUTPUT_CHANNELS );
2956 :
2957 1864379 : FOR( l = 1; l < num_channels_dir; l++ )
2958 : {
2959 1585167 : exp = 0;
2960 1585167 : move16();
2961 1585167 : var_a = BASOP_Util_Add_Mant32Exp( ONE_IN_Q30 /*1 Q30*/, 1, L_negate( surCohRatio_fx[k] ), exp_surCohRatio, &exp ); /*q(31-exp)*/
2962 1585167 : var_b = Sqrt32( var_a, &exp ); /*31-exp*/
2963 1585167 : direct_response_hoa_fx[l] = Mpy_32_32( direct_response_hoa_fx[l], var_b ); /*Q_direct_response_hoa+31-exp-31*/
2964 1585167 : move32();
2965 1585167 : exp_arr[l] = add( sub( 31, Q_direct_response_hoa ), exp );
2966 1585167 : move16();
2967 : }
2968 279212 : Word16 max_exp = MIN_16;
2969 279212 : move16();
2970 279212 : maximum_fx( exp_arr, MAX_OUTPUT_CHANNELS, &max_exp );
2971 4746604 : FOR( l = 0; l < MAX_OUTPUT_CHANNELS; l++ )
2972 : {
2973 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)*/
2974 4467392 : move32();
2975 : }
2976 279212 : Q_direct_response_hoa = sub( 31, max_exp );
2977 279212 : exp_direct_response_hoa = max_exp;
2978 279212 : move16();
2979 : }
2980 :
2981 448109 : Q_direct_response_hoa = sub( Q31, exp_direct_response_hoa );
2982 :
2983 448109 : Scale_sig32( direct_response_hoa_fx, MAX_OUTPUT_CHANNELS, sub( Q29, Q_direct_response_hoa ) ); /*Q_direct_response_hoa->q29*/
2984 448109 : direct_response_q = Q29;
2985 448109 : move16();
2986 :
2987 448109 : direct_response_fx = direct_response_hoa_fx;
2988 448109 : IF( NE_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) )
2989 : {
2990 303554 : v_mult_fixed( direct_response_fx, direct_response_fx, direct_response_square_fx, num_channels_dir ); /*Q(2*direct_response_q-31)*/
2991 303554 : direct_response_square_q = sub( add( direct_response_q, direct_response_q ), 31 );
2992 :
2993 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*/
2994 :
2995 303554 : IF( EQ_16( transport_signal_type, MASA_STEREO_SPACED_MICS ) )
2996 : {
2997 30683 : direct_response_fx[0] = ONE_IN_Q29; /*q29*/
2998 30683 : move32();
2999 30683 : test();
3000 30683 : IF( GE_16( k, dipole_freq_range[0] ) && LT_16( k, dipole_freq_range[1] ) )
3001 : {
3002 3897 : direct_response_fx[1] = ONE_IN_Q29; /*q29*/
3003 3897 : move32();
3004 : }
3005 : }
3006 : ELSE
3007 : {
3008 272871 : set32_fx( direct_response_fx, ONE_IN_Q29, hDirACRend->num_protos_ambi ); /*q29*/
3009 : }
3010 : }
3011 :
3012 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*/
3013 : }
3014 : ELSE
3015 : {
3016 0 : assert( 0 && "Not supported synthesis method!" );
3017 : }
3018 : }
3019 3959703 : ELSE IF( EQ_16( hDirACRend->panningConf, DIRAC_PANNING_VBAP ) ) /*VBAP*/
3020 : {
3021 : /* Synthesize the first direction */
3022 3959703 : spreadCoherencePanningVbap_fx( azimuth[k], elevation[k], hSpatParamRendCom->spreadCoherence_fx[md_idx][k],
3023 : direct_response_ls_fx, &Q_direct_response_ls, num_channels_dir, hVBAPdata );
3024 3959703 : normalizePanningGains_fx( direct_response_ls_fx, &Q_direct_response_ls, num_channels_dir );
3025 3959703 : exp_direct_response_ls = sub( 31, Q_direct_response_ls );
3026 :
3027 : /* Synthesize the second direction and combine the gains */
3028 3959703 : IF( EQ_16( hSpatParamRendCom->numParametricDirections, 2 ) )
3029 : {
3030 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 );
3031 204188 : normalizePanningGains_fx( direct_response_dir2_fx, &Q_direct_response_dir2, num_channels_dir );
3032 :
3033 : /* Combine gains from the two directions */
3034 204188 : Word32 test = L_add( hSpatParamRendCom->energy_ratio1_fx[md_idx][k], hSpatParamRendCom->energy_ratio2_fx[md_idx][k] ); /*q30*/
3035 :
3036 204188 : IF( test == 0 )
3037 : {
3038 1337 : totalDirect_fx = L_add( test, EPSILON_FIX ); // Q30
3039 : }
3040 : ELSE
3041 : {
3042 202851 : totalDirect_fx = test; // q30
3043 202851 : move32();
3044 : }
3045 : Word16 var_1, var_2, exp_1, exp_2;
3046 204188 : var_1 = BASOP_Util_Divide3232_Scale( hSpatParamRendCom->energy_ratio1_fx[md_idx][k], totalDirect_fx, &exp_1 ); // 15-exp_1
3047 204188 : var_2 = BASOP_Util_Divide3232_Scale( hSpatParamRendCom->energy_ratio2_fx[md_idx][k], totalDirect_fx, &exp_2 ); // 15-exp_2
3048 :
3049 204188 : directRatio_fx[0] = L_deposit_h( var_1 ); // 31-exp_1
3050 204188 : move32();
3051 204188 : directRatio_fx[1] = L_deposit_h( var_2 ); // 31-exp_2
3052 204188 : move32();
3053 :
3054 : Word32 var_a;
3055 : Word16 exp_tmp;
3056 204188 : Word16 exp_max = MIN16B, exp_table[MAX_OUTPUT_CHANNELS];
3057 204188 : move16();
3058 204188 : set16_fx( exp_table, exp_direct_response_ls, MAX_OUTPUT_CHANNELS );
3059 :
3060 204188 : exp_direct_response_ls = sub( 31, Q_direct_response_ls );
3061 204188 : exp_direct_response_dir2 = sub( 31, Q_direct_response_dir2 );
3062 :
3063 204188 : Word32 temp = 0;
3064 204188 : move32();
3065 1855504 : FOR( l = 0; l < num_channels_dir; l++ )
3066 : {
3067 1651316 : temp = Mpy_32_32( direct_response_ls_fx[l], directRatio_fx[0] ); // exp_direct_response_ls + exp_1
3068 1651316 : var_a = Mpy_32_32( directRatio_fx[1], direct_response_dir2_fx[l] ); // exp_direct_response_dir2 + exp_2
3069 1651316 : exp_tmp = 0;
3070 1651316 : move16();
3071 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)
3072 1651316 : move32();
3073 1651316 : exp_table[l] = exp_tmp;
3074 1651316 : move16();
3075 : }
3076 :
3077 204188 : maximum_fx( exp_table, MAX_OUTPUT_CHANNELS, &exp_max );
3078 :
3079 3471196 : FOR( i = 0; i < MAX_OUTPUT_CHANNELS; i++ )
3080 : {
3081 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))*/
3082 3267008 : move32();
3083 : }
3084 204188 : Q_direct_response_ls = sub( 31, exp_max );
3085 204188 : exp_direct_response_ls = exp_max;
3086 204188 : move16();
3087 :
3088 204188 : normalizePanningGains_fx( direct_response_ls_fx, &Q_direct_response_ls, num_channels_dir );
3089 204188 : exp_direct_response_ls = sub( 31, Q_direct_response_ls );
3090 : }
3091 :
3092 3959703 : IF( hSpatParamRendCom->numIsmDirections > 0 )
3093 : {
3094 : Word16 dir;
3095 :
3096 : Word32 direct_response_temp_fx[MAX_OUTPUT_CHANNELS];
3097 9195 : set32_fx( direct_response_temp_fx, 0, MAX_OUTPUT_CHANNELS );
3098 9195 : Word16 Q_direct_response_temp = Q31;
3099 9195 : move16();
3100 : Word32 direct_response_ism_fx[MAX_OUTPUT_CHANNELS];
3101 9195 : set32_fx( direct_response_ism_fx, 0, num_channels_dir );
3102 : Word32 masaDirect_fx;
3103 : Word32 ismDirect_fx;
3104 :
3105 35695 : FOR( dir = 0; dir < hSpatParamRendCom->numIsmDirections; dir++ )
3106 : {
3107 26500 : IF( hMasaIsm->ism_is_edited[dir] )
3108 : {
3109 0 : vbap_determine_gains_fx( hVBAPdata, direct_response_temp_fx, hMasaIsm->azimuth_ism_edited[dir], hMasaIsm->elevation_ism_edited[dir], 1 );
3110 : }
3111 : ELSE
3112 : {
3113 26500 : vbap_determine_gains_fx( hVBAPdata, direct_response_temp_fx, hMasaIsm->azimuth_ism[dir][md_idx], hMasaIsm->elevation_ism[dir][md_idx], 1 );
3114 : }
3115 26500 : Word32 tmp = 0;
3116 26500 : move32();
3117 : Word16 Q_arr[MAX_OUTPUT_CHANNELS], exp_tmp;
3118 245264 : FOR( l = 0; l < num_channels_dir; l++ )
3119 : {
3120 218764 : tmp = Mpy_32_32( direct_response_temp_fx[l], hMasaIsm->energy_ratio_ism_fx[dir][md_idx][k] ); // Q30 * 2 - 31
3121 218764 : direct_response_ism_fx[l] = BASOP_Util_Add_Mant32Exp( direct_response_ism_fx[l], 0, tmp, 31 - ( 60 - 31 ), &exp_tmp ); // q(31-exp_tmp)
3122 218764 : move32();
3123 218764 : Q_arr[l] = sub( 31, exp_tmp );
3124 218764 : move16();
3125 : }
3126 26500 : Word16 Q_min = MAX16B;
3127 26500 : move32();
3128 26500 : minimum_fx( Q_arr, num_channels_dir, &Q_min );
3129 245264 : FOR( i = 0; i < num_channels_dir; i++ )
3130 : {
3131 218764 : direct_response_ism_fx[i] = L_shr( direct_response_ism_fx[i], sub( Q_arr[i], Q_min ) ); // Q_arr[i]->Q_min
3132 218764 : move32();
3133 : }
3134 26500 : Q_direct_response_temp = Q_min;
3135 26500 : move16();
3136 26500 : normalizePanningGains_fx( direct_response_ism_fx, &Q_direct_response_temp, num_channels_dir );
3137 : }
3138 :
3139 : Word16 exp_1, exp_2;
3140 9195 : masaDirect_fx = hSpatParamRendCom->energy_ratio1_fx[md_idx][k]; // q30
3141 9195 : move32();
3142 9195 : IF( masaDirect_fx == 0 )
3143 : {
3144 39 : masaDirect_fx = L_add( masaDirect_fx, EPSILLON_FX ); // q30
3145 : }
3146 9195 : IF( EQ_32( hSpatParamRendCom->numParametricDirections, 2 ) )
3147 : {
3148 3000 : masaDirect_fx = L_add( masaDirect_fx, hSpatParamRendCom->energy_ratio2_fx[md_idx][k] ); // q30
3149 : }
3150 :
3151 9195 : ismDirect_fx = hMasaIsm->energy_ratio_ism_fx[0][md_idx][k]; // q30
3152 9195 : move32();
3153 26500 : FOR( dir = 1; dir < hSpatParamRendCom->numIsmDirections; dir++ )
3154 : {
3155 17305 : ismDirect_fx = L_add( ismDirect_fx, hMasaIsm->energy_ratio_ism_fx[dir][md_idx][k] ); // q30
3156 : }
3157 :
3158 9195 : totalDirect_fx = L_add_sat( masaDirect_fx, ismDirect_fx ); // q30 // saturating as 1.0 (Q30) + 1.0 (Q30) is observed
3159 : Word16 var_a, var_b;
3160 9195 : var_a = BASOP_Util_Divide3232_Scale( masaDirect_fx, totalDirect_fx, &exp_1 ); // 15-exp_1
3161 9195 : var_b = BASOP_Util_Divide3232_Scale( ismDirect_fx, totalDirect_fx, &exp_2 ); // 15- exp_2
3162 9195 : directRatio_fx[0] = L_deposit_h( var_a ); // 31- exp_1
3163 9195 : move32();
3164 9195 : directRatio_fx[1] = L_deposit_h( var_b ); // 31 - exp_2
3165 9195 : move32();
3166 :
3167 : Word32 temp_2, temp_3;
3168 : Word16 exp_arr[MAX_OUTPUT_CHANNELS], exp_temp_3;
3169 9195 : set16_fx( exp_arr, exp_direct_response_ls, MAX_OUTPUT_CHANNELS );
3170 84648 : FOR( l = 0; l < num_channels_dir; l++ )
3171 : {
3172 75453 : direct_response_ls_fx[l] = Mpy_32_32( direct_response_ls_fx[l], directRatio_fx[0] ); // q(31-exp_direct_response_ls+31-exp_1-31)
3173 75453 : move32();
3174 75453 : exp_arr[l] = add( exp_direct_response_ls, exp_1 );
3175 75453 : move16();
3176 75453 : temp_2 = Mpy_32_32( directRatio_fx[1], direct_response_ism_fx[l] ); // q(Q_direct_response_temp+31-exp_2-31)
3177 75453 : temp_3 = BASOP_Util_Add_Mant32Exp( direct_response_ls_fx[l], exp_arr[l], temp_2, add( exp_2, sub( 31, Q_direct_response_temp ) ), &exp_temp_3 ); // 31-exp_temp_3
3178 :
3179 75453 : direct_response_ls_fx[l] = temp_3; // 31-exp_temp_3
3180 75453 : move32();
3181 75453 : exp_arr[l] = exp_temp_3;
3182 75453 : move16();
3183 : }
3184 :
3185 9195 : Word16 max_exp = MIN16B;
3186 9195 : move16();
3187 9195 : maximum_fx( exp_arr, num_channels_dir, &max_exp );
3188 84648 : FOR( l = 0; l < num_channels_dir; l++ )
3189 : {
3190 75453 : direct_response_ls_fx[l] = L_shr( direct_response_ls_fx[l], sub( max_exp, exp_arr[l] ) ); /*q(31-exp_arr[l])->q(31-max_exp)*/
3191 75453 : move16();
3192 : }
3193 9195 : Q_direct_response_ls = sub( 31, max_exp );
3194 9195 : exp_direct_response_ls = max_exp;
3195 9195 : move16();
3196 :
3197 9195 : normalizePanningGains_fx( direct_response_ls_fx, &Q_direct_response_ls, num_channels_dir );
3198 9195 : exp_direct_response_ls = sub( 31, Q_direct_response_ls );
3199 : }
3200 :
3201 : /* Synthesize surrounding coherence */
3202 3959703 : test();
3203 3959703 : IF( surCohRatio_fx != NULL && surCohRatio_fx[k] > 0 )
3204 : {
3205 : Word16 num_channels_surrCoh;
3206 :
3207 352823 : num_channels_surrCoh = num_channels_dir;
3208 352823 : move16();
3209 352823 : num_channels_surrCoh = sub( num_channels_surrCoh, hDirACRend->num_ele_spk_no_diffuse_rendering );
3210 :
3211 : Word32 temp, final;
3212 : Word16 exp_temp, exp_temp_a, temp_a, final_exp;
3213 352823 : Word16 exp_arr[MAX_OUTPUT_CHANNELS], max_exp = MIN16B;
3214 352823 : move16();
3215 352823 : set16_fx( exp_arr, exp_direct_response_ls, MAX_OUTPUT_CHANNELS );
3216 3015202 : FOR( l = 0; l < num_channels_dir; l++ )
3217 : {
3218 2662379 : exp_temp = 0;
3219 2662379 : move16();
3220 2662379 : temp = BASOP_Util_Add_Mant32Exp( ONE_IN_Q30 /*1 Q30*/, 1, L_negate( surCohRatio_fx[k] ), exp_surCohRatio, &exp_temp ); // q(31-exp_temp)
3221 2662379 : temp = Sqrt32( temp, &exp_temp ); // q(31-exp_temp)
3222 2662379 : direct_response_ls_fx[l] = Mpy_32_32( direct_response_ls_fx[l], temp ); // Q31-(exp_direct_response_ls + exp_temp)
3223 2662379 : move32();
3224 :
3225 2662379 : exp_arr[l] = add( exp_direct_response_ls, exp_temp );
3226 2662379 : move16();
3227 2662379 : IF( hDirACRend->diffuse_response_function_fx[l] > 0 )
3228 : {
3229 2651179 : exp_temp_a = 0;
3230 2651179 : move16();
3231 2651179 : temp_a = BASOP_Util_Divide3216_Scale( surCohRatio_fx[k], num_channels_surrCoh, &exp_temp_a ); /*15-(exp_temp_a+exp_surCohRatio-15)*/
3232 2651179 : exp_temp_a = add( exp_temp_a, sub( exp_surCohRatio, 15 ) );
3233 2651179 : temp_a = Sqrt16( temp_a, &exp_temp_a ); /*15-temp_a*/
3234 2651179 : final_exp = 0;
3235 2651179 : move16();
3236 2651179 : 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*/
3237 2651179 : direct_response_ls_fx[l] = final; /*31-final_exp*/
3238 2651179 : move32();
3239 2651179 : exp_arr[l] = final_exp;
3240 2651179 : move16();
3241 : }
3242 : }
3243 :
3244 352823 : max_exp = MIN16B; /*Q0*/
3245 352823 : move16();
3246 352823 : maximum_fx( exp_arr, MAX_OUTPUT_CHANNELS, &max_exp );
3247 5997991 : FOR( l = 0; l < MAX_OUTPUT_CHANNELS; l++ )
3248 : {
3249 5645168 : 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)*/
3250 5645168 : move32();
3251 : }
3252 :
3253 352823 : Q_direct_response_ls = sub( 31, max_exp );
3254 352823 : exp_direct_response_ls = max_exp;
3255 352823 : move16();
3256 : }
3257 :
3258 3959703 : normalizePanningGains_fx( direct_response_ls_fx, &Q_direct_response_ls, num_channels_dir );
3259 3959703 : exp_direct_response_ls = sub( 31, Q_direct_response_ls );
3260 :
3261 3959703 : Scale_sig32( direct_response_ls_fx, MAX_OUTPUT_CHANNELS, sub( Q29, Q_direct_response_ls ) ); /*Q_direct_response_ls->Q29*/
3262 3959703 : direct_response_q = Q29;
3263 3959703 : move16();
3264 :
3265 : /* Set computed gains */
3266 3959703 : direct_response_fx = direct_response_ls_fx;
3267 3959703 : v_mult_fixed( direct_response_fx, direct_response_fx, direct_response_square_fx, num_channels_dir ); /*2*direct_response_q-31*/
3268 3959703 : direct_response_square_q = sub( add( direct_response_q, direct_response_q ), 31 );
3269 :
3270 3959703 : 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*/
3271 3959703 : 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*/
3272 : }
3273 : ELSE
3274 : {
3275 0 : assert( 0 && "Not supported panning method!" );
3276 : }
3277 : }
3278 : }
3279 :
3280 1087261 : hDirACRend->h_output_synthesis_psd_state.direct_responses_q = direct_response_q;
3281 1087261 : move16();
3282 1087261 : hDirACRend->h_output_synthesis_psd_state.direct_responses_square_q = direct_response_square_q;
3283 1087261 : move16();
3284 :
3285 1087261 : return;
3286 : }
3287 :
3288 :
3289 : /*-------------------------------------------------------------------------
3290 : * ivas_dirac_dec_compute_gain_factors()
3291 : *
3292 : *
3293 : *------------------------------------------------------------------------*/
3294 :
3295 739710 : void ivas_dirac_dec_compute_gain_factors_fx(
3296 : const Word16 num_freq_bands,
3297 : const Word32 *diffuseness_fx, /*i:q30*/
3298 : Word32 *direct_gain_factor, /*o:exponent is max_exp_direct*/
3299 : Word32 *diffuse_gain_factor, /*o:exponent is max_exp_diffusion*/
3300 : Word16 *max_exp_direct_fx,
3301 : Word16 *max_exp_diffusion )
3302 : {
3303 : Word16 i;
3304 : Word16 exp1, exp2;
3305 : Word16 exp_diffuse_gain_factor[60], exp_direct_gain_factor[60]; /*exp buffers*/
3306 :
3307 38831770 : FOR( i = 0; i < num_freq_bands; i++ )
3308 : {
3309 38092060 : exp1 = 1;
3310 38092060 : move16();
3311 38092060 : exp2 = 1;
3312 38092060 : move16();
3313 38092060 : direct_gain_factor[i] = Sqrt32( L_sub( ONE_IN_Q30 /*1 Q30*/, diffuseness_fx[i] ), &exp1 ); /*31-exp1*/
3314 38092060 : move32();
3315 38092060 : diffuse_gain_factor[i] = Sqrt32( diffuseness_fx[i], &exp2 ); /*31-exp2*/
3316 38092060 : move32();
3317 38092060 : exp_direct_gain_factor[i] = exp1;
3318 38092060 : move16();
3319 38092060 : exp_diffuse_gain_factor[i] = exp2;
3320 38092060 : move16();
3321 : }
3322 :
3323 : /*make common exp for both buffers*/
3324 739710 : Word16 max_exp_direct = MIN16B; /*Q0*/
3325 739710 : move16();
3326 739710 : Word16 max_exp_diffuse = MIN16B; /*Q0*/
3327 739710 : move16();
3328 38831770 : FOR( i = 0; i < num_freq_bands; i++ )
3329 : {
3330 38092060 : max_exp_direct = s_max( max_exp_direct, exp_direct_gain_factor[i] );
3331 38092060 : max_exp_diffuse = s_max( max_exp_diffuse, exp_diffuse_gain_factor[i] );
3332 : }
3333 :
3334 739710 : *max_exp_direct_fx = max_exp_direct;
3335 739710 : move16();
3336 739710 : *max_exp_diffusion = max_exp_diffuse;
3337 739710 : move16();
3338 :
3339 38831770 : FOR( i = 0; i < num_freq_bands; i++ )
3340 : {
3341 38092060 : direct_gain_factor[i] = L_shr( direct_gain_factor[i], sub( max_exp_direct, exp_direct_gain_factor[i] ) ); /*Q(31-max_exp_direct)*/
3342 38092060 : move32();
3343 38092060 : diffuse_gain_factor[i] = L_shr( diffuse_gain_factor[i], sub( max_exp_diffuse, exp_diffuse_gain_factor[i] ) ); /*Q(31-max_exp_diffuse)*/
3344 38092060 : move32();
3345 : }
3346 :
3347 :
3348 739710 : return;
3349 : }
3350 :
3351 :
3352 : /*-------------------------------------------------------------------------
3353 : * ivas_dirac_dec_compute_power_factors()
3354 : *
3355 : *
3356 : *------------------------------------------------------------------------*/
3357 :
3358 134927 : void ivas_dirac_dec_compute_power_factors_fx(
3359 : const Word16 num_freq_bands,
3360 : const Word32 *diffuseness_fx, // Q3O
3361 : const Word16 max_band_decorr,
3362 : Word32 *direct_power_factor, /*input is q30 and ouput is q29*/
3363 : Word32 *diffuse_power_factor /*input is q30 and ouput is q29*/ )
3364 : {
3365 : Word16 i;
3366 :
3367 134927 : v_multc_fixed( diffuseness_fx, L_negate( ( ONE_IN_Q31 ) ), direct_power_factor, num_freq_bands ); // Q30
3368 :
3369 134927 : v_addc_fixed( direct_power_factor, ONE_IN_Q30, direct_power_factor, num_freq_bands ); // Q30
3370 :
3371 134927 : Copy32( diffuseness_fx, diffuse_power_factor, num_freq_bands ); // Q30
3372 :
3373 134927 : 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
3374 :
3375 134927 : 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
3376 :
3377 :
3378 1177577 : FOR( i = 0; i < max_band_decorr; i++ )
3379 : {
3380 1042650 : direct_power_factor[i] = L_shr( direct_power_factor[i], 1 ); // Q29
3381 1042650 : move32();
3382 1042650 : diffuse_power_factor[i] = L_shr( diffuse_power_factor[i], 1 ); // Q29
3383 1042650 : move32();
3384 : }
3385 134927 : return;
3386 : }
3387 :
3388 :
3389 : /*-------------------------------------------------------------------------
3390 : * ivas_lfe_synth_with_filters()
3391 : *
3392 : *
3393 : *------------------------------------------------------------------------*/
3394 195 : void ivas_lfe_synth_with_filters_fx(
3395 : MCMASA_LFE_SYNTH_DATA_HANDLE hMasaLfeSynth, /* i/o: LFE synthesis structure for McMASA */
3396 : Word32 *data_fx[], /* o : output signals (Q11) */
3397 : const Word16 output_frame, /* i : output frame length per channel */
3398 : const Word16 separateChannelIndex, /* i : separate channel index */
3399 : const Word16 lfeChannelIndex /* i : LFE channel index */
3400 : )
3401 : {
3402 : Word16 lowpassCoef_fx;
3403 : Word16 lowpassCoef_fx_exp;
3404 : Word16 i, j;
3405 : Word32 lowPassSignal_fx[L_FRAME48k];
3406 : Word32 highPassSignal_fx[L_FRAME48k];
3407 : Word16 slot_index;
3408 : Word16 subframe_index;
3409 : Word16 slotSize;
3410 : Word32 transportEne_fx, targetEneLfe_fx, targetEneTrans_fx;
3411 : Word16 mrange[2];
3412 : Word16 lfeGain_fx;
3413 : Word16 lfeGain_fx_exp;
3414 : Word16 transportGain_fx;
3415 : Word16 transportGain_fx_exp;
3416 : Word16 delay;
3417 :
3418 : /* Delay the separated channel to sync the LFE synthesis with the DirAC rendering */
3419 195 : delay = hMasaLfeSynth->delayBuffer_syncDirAC_size;
3420 195 : move16();
3421 195 : delay_signal32_fx( data_fx[separateChannelIndex], output_frame, hMasaLfeSynth->delayBuffer_syncDirAC_fx, delay ); /*q11*/
3422 :
3423 : /* Filterbank for dividing the separated channel to LFE frequencies and higher frequencies */
3424 195 : lowpassCoef_fx_exp = 15;
3425 195 : move16();
3426 195 : lowpassCoef_fx = Inv16( hMasaLfeSynth->ringBufferSize, &lowpassCoef_fx_exp ); /*15-lowpassCoef_fx_exp*/
3427 180995 : FOR( i = 0; i < output_frame; i++ )
3428 : {
3429 180800 : 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
3430 180800 : lowPassSignal_fx[i] = hMasaLfeSynth->lowpassSum_fx; // Q11
3431 180800 : move32();
3432 180800 : highPassSignal_fx[i] = L_sub( hMasaLfeSynth->lfeSynthRingBuffer_fx[hMasaLfeSynth->ringBufferHiPointer], lowPassSignal_fx[i] ); // Q11
3433 180800 : move32();
3434 180800 : hMasaLfeSynth->lfeSynthRingBuffer_fx[hMasaLfeSynth->ringBufferLoPointer] = data_fx[separateChannelIndex][i]; // Q11
3435 180800 : move32();
3436 :
3437 180800 : hMasaLfeSynth->ringBufferLoPointer = sub( hMasaLfeSynth->ringBufferLoPointer, 1 );
3438 180800 : move16();
3439 180800 : IF( hMasaLfeSynth->ringBufferLoPointer < 0 )
3440 : {
3441 780 : hMasaLfeSynth->ringBufferLoPointer = sub( hMasaLfeSynth->ringBufferSize, 1 );
3442 780 : move16();
3443 : }
3444 :
3445 180800 : hMasaLfeSynth->ringBufferHiPointer = sub( hMasaLfeSynth->ringBufferHiPointer, 1 );
3446 180800 : move16();
3447 180800 : IF( hMasaLfeSynth->ringBufferHiPointer < 0 )
3448 : {
3449 780 : hMasaLfeSynth->ringBufferHiPointer = sub( hMasaLfeSynth->ringBufferSize, 1 );
3450 780 : move16();
3451 : }
3452 : }
3453 :
3454 : /* Synthesize the LFE signal */
3455 195 : slotSize = shr_r( output_frame, 4 ); // output_frame / CLDFB_NO_COL_MAX
3456 3315 : FOR( slot_index = 0; slot_index < CLDFB_NO_COL_MAX; slot_index++ )
3457 : {
3458 3120 : subframe_index = shr( slot_index, 4 );
3459 :
3460 3120 : mrange[0] = i_mult( slot_index, slotSize );
3461 3120 : move16();
3462 3120 : mrange[1] = i_mult( add( slot_index, 1 ), slotSize );
3463 3120 : move16();
3464 :
3465 3120 : transportEne_fx = 0;
3466 3120 : move32();
3467 3120 : Word64 W_tmp = 0;
3468 3120 : move64();
3469 183920 : FOR( i = mrange[0]; i < mrange[1]; i++ )
3470 : {
3471 180800 : W_tmp = W_add( W_tmp, W_mult0_32_32( lowPassSignal_fx[i], lowPassSignal_fx[i] ) ); // Q22
3472 : }
3473 :
3474 3120 : Word16 tmp_shift = W_norm( W_tmp );
3475 :
3476 3120 : W_tmp = W_shl( W_tmp, tmp_shift ); /*Q22+tmp_shift*/
3477 :
3478 3120 : Word16 tmp_q = sub( add( Q22, tmp_shift ), 32 );
3479 : Word16 tmp_exp;
3480 :
3481 3120 : transportEne_fx = W_extract_h( W_tmp ); /* Q22 + tmp_shift - 32 */
3482 3120 : targetEneLfe_fx = W_extract_l( W_shr( W_mult0_32_32( transportEne_fx, hMasaLfeSynth->lfeToTotalEnergyRatio_fx[subframe_index] ), Q14 ) ); /* Q22 + tmp_shift - 32 */
3483 3120 : 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 */
3484 :
3485 3120 : hMasaLfeSynth->transportEneSmooth_fx = Mpy_32_16_1( hMasaLfeSynth->transportEneSmooth_fx, MCMASA_LFE_SYNTH_ALPHA_Q15 ); /* transportEneSmooth_q */
3486 3120 : move32();
3487 3120 : hMasaLfeSynth->targetEneLfeSmooth_fx = Mpy_32_16_1( hMasaLfeSynth->targetEneLfeSmooth_fx, MCMASA_LFE_SYNTH_ALPHA_Q15 ); /* targetEneLfeSmooth_q */
3488 3120 : move32();
3489 3120 : hMasaLfeSynth->targetEneTransSmooth_fx = Mpy_32_16_1( hMasaLfeSynth->targetEneTransSmooth_fx, MCMASA_LFE_SYNTH_ALPHA_Q15 ); /* targetEneTransSmooth_q */
3490 3120 : move32();
3491 :
3492 3120 : 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 */
3493 3120 : move32();
3494 3120 : hMasaLfeSynth->transportEneSmooth_q = sub( Q31, tmp_exp );
3495 3120 : move16();
3496 3120 : 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 */
3497 3120 : move32();
3498 3120 : hMasaLfeSynth->targetEneLfeSmooth_q = sub( Q31, tmp_exp );
3499 3120 : move16();
3500 3120 : 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 */
3501 3120 : move32();
3502 3120 : hMasaLfeSynth->targetEneTransSmooth_q = sub( Q31, tmp_exp );
3503 3120 : move16();
3504 :
3505 3120 : 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 ) )
3506 : {
3507 0 : lfeGain_fx = MAX_16; /* 1.0 in q15*/
3508 0 : move16();
3509 : }
3510 : ELSE
3511 : {
3512 3120 : 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*/
3513 3120 : lfeGain_fx_exp = add( sub( hMasaLfeSynth->transportEneSmooth_q, hMasaLfeSynth->targetEneLfeSmooth_q ), lfeGain_fx_exp );
3514 3120 : lfeGain_fx = Sqrt16( lfeGain_fx, &lfeGain_fx_exp ); // Q15-lfeGain_fx_exp
3515 3120 : lfeGain_fx = shr_r_sat( lfeGain_fx, negate( lfeGain_fx_exp ) ); // Q15
3516 : }
3517 3120 : 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 ) )
3518 : {
3519 0 : transportGain_fx = MAX_16; // q15
3520 0 : move16();
3521 : }
3522 : ELSE
3523 : {
3524 3120 : 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)*/
3525 3120 : transportGain_fx_exp = add( sub( hMasaLfeSynth->transportEneSmooth_q, hMasaLfeSynth->targetEneTransSmooth_q ), transportGain_fx_exp );
3526 3120 : transportGain_fx = Sqrt16( transportGain_fx, &transportGain_fx_exp ); // q15-transportGain_fx_exp
3527 3120 : transportGain_fx = shr_r_sat( transportGain_fx, negate( transportGain_fx_exp ) ); // Q15
3528 : }
3529 3120 : j = 0;
3530 3120 : move16();
3531 183920 : FOR( i = mrange[0]; i < mrange[1]; i++ )
3532 : {
3533 180800 : Word32 L_tmp1 = L_mult( transportGain_fx, hMasaLfeSynth->interpolator_fx[j] ); // Q31
3534 180800 : Word32 L_tmp2 = L_mult( hMasaLfeSynth->transportGainPrev_fx, sub( MAX_16, hMasaLfeSynth->interpolator_fx[j] ) ); // Q31
3535 180800 : 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*/
3536 180800 : move32();
3537 180800 : Word32 L_tmp3 = L_mult( lfeGain_fx, hMasaLfeSynth->interpolator_fx[j] ); // Q31
3538 180800 : Word32 L_tmp4 = L_mult( hMasaLfeSynth->lfeGainPrev_fx, sub( MAX_16, hMasaLfeSynth->interpolator_fx[j] ) ); /*q31*/
3539 180800 : data_fx[lfeChannelIndex][i] = Mpy_32_32( L_add( L_tmp3, L_tmp4 ), lowPassSignal_fx[i] ); /*q31+q11-q31->q11*/
3540 180800 : move32();
3541 180800 : j = add( j, 1 );
3542 : }
3543 :
3544 3120 : hMasaLfeSynth->lfeGainPrev_fx = lfeGain_fx; /*q15*/
3545 3120 : move16();
3546 3120 : hMasaLfeSynth->transportGainPrev_fx = transportGain_fx; /*q15*/
3547 3120 : move16();
3548 : }
3549 :
3550 : /* Lowpass filter for removing remaining mid and high frequencies from the LFE signal */
3551 195 : lowpassCoef_fx_exp = 15;
3552 195 : move16();
3553 195 : lowpassCoef_fx = Inv16( hMasaLfeSynth->ringBufferSize2, &lowpassCoef_fx_exp ); // q15-lowpassCoef_fx_exp
3554 180995 : FOR( i = 0; i < output_frame; i++ )
3555 : {
3556 180800 : hMasaLfeSynth->lowpassSum2_fx = L_add( hMasaLfeSynth->lowpassSum2_fx,
3557 180800 : L_shl_r( L_sub( Mpy_32_16_1( data_fx[lfeChannelIndex][i], lowpassCoef_fx ),
3558 180800 : Mpy_32_16_1( hMasaLfeSynth->lfeSynthRingBuffer2_fx[hMasaLfeSynth->ringBufferLoPointer2], lowpassCoef_fx ) ),
3559 : lowpassCoef_fx_exp ) ); /*q11+15-lowpassCoef_fx_exp-15+lowpassCoef_fx_exp->q11*/
3560 180800 : move32();
3561 180800 : hMasaLfeSynth->lfeSynthRingBuffer2_fx[hMasaLfeSynth->ringBufferLoPointer2] = data_fx[lfeChannelIndex][i]; /*q11*/
3562 180800 : move32();
3563 :
3564 180800 : hMasaLfeSynth->ringBufferLoPointer2 = sub( hMasaLfeSynth->ringBufferLoPointer2, 1 );
3565 180800 : move16();
3566 180800 : IF( hMasaLfeSynth->ringBufferLoPointer2 < 0 )
3567 : {
3568 1560 : hMasaLfeSynth->ringBufferLoPointer2 = sub( hMasaLfeSynth->ringBufferSize2, 1 );
3569 1560 : move16();
3570 : }
3571 :
3572 180800 : data_fx[lfeChannelIndex][i] = hMasaLfeSynth->lowpassSum2_fx; /*q11*/
3573 180800 : move32();
3574 : }
3575 :
3576 : /* Delay the separated channel to match the delay of the lowpass filter */
3577 195 : delay = hMasaLfeSynth->delayBuffer_syncLp_size;
3578 195 : move16();
3579 195 : delay_signal32_fx( data_fx[separateChannelIndex], output_frame, hMasaLfeSynth->delayBuffer_syncLp_fx, delay ); /*q11*/
3580 :
3581 195 : return;
3582 : }
3583 :
3584 : /*-------------------------------------------------------------------------
3585 : * Local functions
3586 : *------------------------------------------------------------------------*/
3587 :
3588 56000 : static void computeTargetPSDs_direct_fx(
3589 : const Word16 num_channels,
3590 : const Word16 num_freq_bands,
3591 : const Word32 *direct_power_factor, /*q31*/
3592 : const Word32 *reference_power, /*q_reference_power*/
3593 : const Word16 *q_reference_power,
3594 : const Word32 *direct_responses, /*q31*/
3595 : const Word32 *direct_responses_square, /*q31*/
3596 : Word32 *cy_auto_dir_smooth, /*q_cy_auto_dir_smooth*/
3597 : Word16 *q_cy_auto_dir_smooth,
3598 : Word32 *cy_cross_dir_smooth, /*q_cy_cross_dir_smooth*/
3599 : Word16 *q_cy_cross_dir_smooth )
3600 : {
3601 : Word16 ch_idx, cur_idx;
3602 :
3603 : /* segment auxiliary buffer */
3604 : Word32 direct_power[CLDFB_NO_CHANNELS_MAX]; /* size: num_freq_bands. */
3605 : Word32 aux_buffer_res[CLDFB_NO_CHANNELS_MAX]; /* size: num_freq_bands. */
3606 :
3607 : /* estimate direct and diffuse power */
3608 56000 : v_mult_fixed( direct_power_factor, reference_power, direct_power, num_freq_bands ); /* Q31 + Q(q_reference_power) - Q31 = Q(q_reference_power) */
3609 :
3610 56000 : Word16 common1_q = s_min( *q_cy_auto_dir_smooth, s_min( q_reference_power[0], q_reference_power[1] ) );
3611 56000 : Word16 common2_q = s_min( *q_cy_cross_dir_smooth, s_min( q_reference_power[0], q_reference_power[1] ) );
3612 :
3613 : /* compute target auto and cross PSDs of current frame (smoothed) */
3614 592000 : FOR( ch_idx = 0; ch_idx < num_channels; ++ch_idx )
3615 : {
3616 536000 : cur_idx = imult1616( ch_idx, num_freq_bands );
3617 :
3618 536000 : 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) */
3619 536000 : scale_sig32( aux_buffer_res, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( common1_q, q_reference_power[0] ) ); /* Q(common1_q) */
3620 536000 : 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) */
3621 536000 : scale_sig32( &cy_auto_dir_smooth[cur_idx], num_freq_bands, sub( common1_q, *q_cy_auto_dir_smooth ) ); /* Q(common1_q) */
3622 536000 : 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 */
3623 :
3624 536000 : 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) */
3625 536000 : scale_sig32( aux_buffer_res, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( common2_q, q_reference_power[0] ) ); /* Q(common2_q) */
3626 536000 : 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) */
3627 536000 : scale_sig32( &cy_cross_dir_smooth[cur_idx], num_freq_bands, sub( common2_q, *q_cy_cross_dir_smooth ) ); /* Q(common2_q) */
3628 536000 : 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 */
3629 : }
3630 :
3631 : /* Q adjustment */
3632 56000 : *q_cy_auto_dir_smooth = sub( common1_q, Q1 );
3633 56000 : move16();
3634 56000 : *q_cy_cross_dir_smooth = sub( common2_q, Q1 );
3635 56000 : move16();
3636 :
3637 56000 : return;
3638 : }
3639 :
3640 :
3641 78927 : static void computeTargetPSDs_direct_subframe_fx(
3642 : const Word16 num_channels,
3643 : const Word16 num_freq_bands,
3644 : const Word32 *direct_power_factor, /*q31*/
3645 : const Word32 *reference_power, /*q_reference_power*/
3646 : const Word16 *q_reference_power,
3647 : const Word32 *direct_responses, /*q31*/
3648 : const Word32 *direct_responses_square, /*q31*/
3649 : Word32 *cy_auto_dir_smooth, /*q_cy_auto_dir_smooth*/
3650 : Word16 *q_cy_auto_dir_smooth,
3651 : Word32 *cy_cross_dir_smooth, /*q_cy_cross_dir_smooth*/
3652 : Word16 *q_cy_cross_dir_smooth )
3653 : {
3654 : Word16 ch_idx, cur_idx, q_tmp;
3655 : Word32 L_tmp[CLDFB_NO_CHANNELS_MAX];
3656 : Word16 q_cy_auto_dir_smooth_local[2];
3657 :
3658 : /* segment auxiliary buffer */
3659 : Word32 direct_power[CLDFB_NO_CHANNELS_MAX]; /* size: num_freq_bands. */
3660 :
3661 : /* estimate direct and diffuse power */
3662 78927 : v_mult_fixed( direct_power_factor, reference_power, direct_power, num_freq_bands );
3663 : /* compute target auto and cross PSDs of current frame (smoothed) */
3664 605476 : FOR( ch_idx = 0; ch_idx < num_channels; ++ch_idx )
3665 : {
3666 526549 : cur_idx = imult1616( ch_idx, num_freq_bands );
3667 :
3668 526549 : q_tmp = L_norm_arr( &direct_responses_square[cur_idx], num_freq_bands );
3669 526549 : Copy_Scale_sig32( &direct_responses_square[cur_idx], L_tmp, num_freq_bands, q_tmp );
3670 526549 : 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
3671 :
3672 526549 : 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 ) ) );
3673 526549 : 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 ) ) );
3674 526549 : q_cy_auto_dir_smooth[ch_idx] = s_min( q_cy_auto_dir_smooth_local[0], q_cy_auto_dir_smooth_local[1] );
3675 526549 : move16();
3676 :
3677 526549 : 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 ) ) );
3678 526549 : 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 ) ) );
3679 :
3680 526549 : 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
3681 526549 : 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] ) );
3682 : }
3683 :
3684 78927 : *q_cy_cross_dir_smooth = q_reference_power[0];
3685 78927 : move16();
3686 :
3687 78927 : return;
3688 : }
3689 :
3690 :
3691 56000 : static void computeTargetPSDs_diffuse_fx(
3692 : const Word16 num_channels,
3693 : const Word16 num_freq_bands,
3694 : const Word16 start_band,
3695 : const Word32 *diffuse_power_factor, /*q31*/
3696 : const Word32 *reference_power, /*q_reference_power*/
3697 : const Word16 *q_reference_power,
3698 : const Word32 *diffuse_responses_square, /*Q31*/
3699 : Word32 *cy_auto_diff_smooth, /*q_cy_auto_diff_smooth*/
3700 : Word16 *q_cy_auto_diff_smooth )
3701 : {
3702 : Word16 ch_idx, cur_idx;
3703 :
3704 : /* segment auxiliary buffer */
3705 : Word32 diffuse_power[CLDFB_NO_CHANNELS_MAX]; /* size: num_freq_bands. */
3706 : Word32 aux_buffer_res[CLDFB_NO_CHANNELS_MAX]; /* size: num_freq_bands. */
3707 :
3708 : /* estimate direct and diffuse power */
3709 56000 : v_mult_fixed( diffuse_power_factor, reference_power, diffuse_power, num_freq_bands ); /* Q31 + Q(q_reference_power) - Q31 = Q(q_reference_power) */
3710 :
3711 56000 : Word16 common_q = s_min( *q_cy_auto_diff_smooth, s_min( q_reference_power[0], q_reference_power[1] ) );
3712 :
3713 : /* compute target auto and cross PSDs of current frame (smoothed) */
3714 592000 : FOR( ch_idx = 0; ch_idx < num_channels; ++ch_idx )
3715 : {
3716 536000 : cur_idx = imult1616( ch_idx, num_freq_bands );
3717 :
3718 536000 : 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) */
3719 536000 : 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) */
3720 536000 : 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) */
3721 536000 : 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) */
3722 536000 : 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 */
3723 : }
3724 :
3725 : /* Q adjustment */
3726 56000 : *q_cy_auto_diff_smooth = sub( common_q, Q1 );
3727 56000 : move16();
3728 :
3729 56000 : return;
3730 : }
3731 :
3732 :
3733 78927 : static void computeTargetPSDs_diffuse_subframe_fx(
3734 : const Word16 num_channels,
3735 : const Word16 num_freq_bands,
3736 : const Word16 start_band,
3737 : const Word32 *diffuse_power_factor, /*q31*/
3738 : const Word32 *reference_power, /*q_reference_power*/
3739 : const Word16 *q_reference_power,
3740 : const Word32 *diffuse_responses_square, /*q31*/
3741 : Word32 *cy_auto_diff_smooth, /*q_cy_auto_diff_smooth*/
3742 : Word16 *q_cy_auto_diff_smooth )
3743 : {
3744 : Word16 ch_idx, cur_idx;
3745 : Word32 diffuse_power[CLDFB_NO_CHANNELS_MAX]; /* segment auxiliary buffer; size: num_freq_bands. */
3746 : Word16 q_cy_auto_diff_smooth_new, q_diffuse_power;
3747 :
3748 : /* estimate direct and diffuse power */
3749 78927 : v_mult_fixed( diffuse_power_factor, reference_power, diffuse_power, num_freq_bands ); // (Q31, q_reference_power) -> q_reference_power
3750 :
3751 78927 : q_diffuse_power = s_min( q_reference_power[0], q_reference_power[1] );
3752 78927 : Scale_sig32( diffuse_power, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( q_diffuse_power, q_reference_power[0] ) );
3753 78927 : 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] ) );
3754 78927 : q_cy_auto_diff_smooth_new = q_diffuse_power;
3755 78927 : IF( LT_16( *q_cy_auto_diff_smooth, q_diffuse_power ) )
3756 : {
3757 4314 : Scale_sig32( diffuse_power, num_freq_bands, sub( *q_cy_auto_diff_smooth, q_cy_auto_diff_smooth_new ) );
3758 4314 : q_cy_auto_diff_smooth_new = *q_cy_auto_diff_smooth;
3759 4314 : move16();
3760 : }
3761 : /* compute target auto and cross PSDs of current frame (smoothed) */
3762 605476 : FOR( ch_idx = 0; ch_idx < num_channels; ++ch_idx )
3763 : {
3764 526549 : cur_idx = imult1616( ch_idx, num_freq_bands );
3765 :
3766 526549 : IF( GT_16( *q_cy_auto_diff_smooth, q_diffuse_power ) )
3767 : {
3768 467143 : Scale_sig32( &cy_auto_diff_smooth[cur_idx], start_band, sub( q_diffuse_power, *q_cy_auto_diff_smooth ) );
3769 : }
3770 526549 : 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
3771 : }
3772 :
3773 78927 : *q_cy_auto_diff_smooth = q_cy_auto_diff_smooth_new;
3774 78927 : move16();
3775 :
3776 78927 : return;
3777 : }
3778 :
3779 :
3780 213809 : static void computeTargetPSDs_diffuse_with_onsets_fx(
3781 : const Word16 num_channels,
3782 : const Word16 num_freq_bands,
3783 : const Word16 num_decorr_freq_bands,
3784 : const Word16 *proto_frame_diff_index,
3785 : const Word32 *diffuse_power_factor, /*q31*/
3786 : const Word32 *reference_power, /* q_reference_power */
3787 : const Word16 *q_reference_power,
3788 : const Word32 *diffuse_responses_square, /*q31*/
3789 : const Word32 *onset_filter, /*q31*/
3790 : Word32 *cy_auto_diff_smooth, /*q_cy_auto_diff_smooth*/
3791 : Word16 *q_cy_auto_diff_smooth )
3792 : {
3793 : Word16 ch_idx, cur_idx, diff_idx;
3794 : Word32 diffuse_response_p4, aux_buffer_res1[CLDFB_NO_CHANNELS_MAX];
3795 : /* segment auxiliary buffer */
3796 : Word32 diffuse_power[CLDFB_NO_CHANNELS_MAX]; /* size: num_freq_bands. */
3797 : Word32 aux_buffer_res[CLDFB_NO_CHANNELS_MAX]; /* size: num_freq_bands. */
3798 : Word16 q_common, q_reference_power_min_one[2];
3799 :
3800 213809 : q_reference_power_min_one[0] = sub( q_reference_power[0], Q1 );
3801 213809 : q_reference_power_min_one[1] = sub( q_reference_power[1], Q1 );
3802 :
3803 : /* estimate direct and diffuse power */
3804 213809 : v_mult_fixed( diffuse_power_factor, reference_power, diffuse_power, num_decorr_freq_bands ); // (Q31, q_reference_power) -> q_reference_power
3805 :
3806 213809 : q_common = s_min( *q_cy_auto_diff_smooth, s_min( q_reference_power_min_one[0], q_reference_power_min_one[1] ) );
3807 :
3808 : /* compute target auto and cross PSDs of current frame (smoothed) */
3809 1721072 : FOR( ch_idx = 0; ch_idx < num_channels; ++ch_idx )
3810 : {
3811 1507263 : diffuse_response_p4 = Mpy_32_32( diffuse_responses_square[ch_idx], diffuse_responses_square[ch_idx] ); // (Q31, Q31) -> Q31
3812 :
3813 1507263 : cur_idx = imult1616( ch_idx, num_freq_bands );
3814 1507263 : diff_idx = imult1616( proto_frame_diff_index[ch_idx], num_freq_bands );
3815 :
3816 1507263 : v_multc_fixed( &onset_filter[diff_idx], diffuse_responses_square[ch_idx], aux_buffer_res1, num_decorr_freq_bands ); // (Q31, Q31) -> Q31
3817 1507263 : v_multc_fixed( &onset_filter[diff_idx], INT_MIN, aux_buffer_res, num_decorr_freq_bands ); // (Q31, Q31) -> Q31
3818 1507263 : v_addc_fixed( aux_buffer_res, ONE_IN_Q31, aux_buffer_res, num_decorr_freq_bands ); // Q31
3819 1507263 : v_multc_fixed( aux_buffer_res, diffuse_response_p4, aux_buffer_res, num_decorr_freq_bands ); // (Q31, Q31) -> Q31
3820 1507263 : v_add_fixed( aux_buffer_res1, aux_buffer_res, aux_buffer_res, num_decorr_freq_bands, Q1 ); // Q30
3821 1507263 : v_mult_fixed( aux_buffer_res, diffuse_power, aux_buffer_res, num_decorr_freq_bands ); // (Q30, q_reference_power) -> q_reference_power - Q1
3822 :
3823 1507263 : IF( NE_16( q_common, q_reference_power_min_one[0] ) )
3824 : {
3825 18201 : 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
3826 : }
3827 1507263 : IF( NE_16( q_common, q_reference_power_min_one[1] ) )
3828 : {
3829 703545 : 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
3830 : }
3831 1507263 : IF( NE_16( q_common, *q_cy_auto_diff_smooth ) )
3832 : {
3833 1202556 : scale_sig32( &cy_auto_diff_smooth[cur_idx], num_decorr_freq_bands, sub( q_common, *q_cy_auto_diff_smooth ) ); // q_common
3834 : }
3835 1507263 : 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)
3836 1507263 : 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)
3837 : }
3838 :
3839 : /* Q adjustment */
3840 213809 : *q_cy_auto_diff_smooth = sub( q_common, Q1 );
3841 213809 : move16();
3842 :
3843 213809 : return;
3844 : }
3845 :
3846 :
3847 2838 : 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 )
3848 : {
3849 : Word16 k;
3850 : Word16 avg_length_f_ms_fx;
3851 :
3852 : /* check input pointer */
3853 2838 : IF( alpha_synthesis_fx == NULL )
3854 : {
3855 0 : return;
3856 : }
3857 :
3858 2838 : IF( averaging_length_ms == 0 )
3859 : {
3860 0 : set16_fx( alpha_synthesis_fx, MAX16B, num_freq_bands ); /*q15*/
3861 : }
3862 : ELSE
3863 : {
3864 11352 : FOR( k = 0; k < num_freq_bands; k++ )
3865 : {
3866 11352 : Word16 faxis_idx = s_max( k, 1 );
3867 :
3868 : // avg_length_f_ms = 1000.f * (float)averaging_length_ms / fabsf(frequency_axis[faxis_idx]);
3869 11352 : Word16 tmp_exp = 0;
3870 11352 : Word16 tmp_1 = BASOP_Util_Divide1616_Scale( averaging_length_ms, frequency_axis_fx[faxis_idx], &tmp_exp ); /*Q(15-(tmp_exp+15-15))*/
3871 11352 : Word16 tmp_2 = mult( tmp_1, 1000 ); // 15 - tmp_exp + 0 -15 = -tmp_exp (Q-fac)
3872 11352 : avg_length_f_ms_fx = tmp_2; // Q(-tmp_exp)
3873 11352 : move16();
3874 11352 : move16();
3875 :
3876 : /* alpha_synthesis[k] = min( (float) slot_size / ( avg_length_f_ms * (float) output_Fs / 1000.f ), 1.0f );*/
3877 11352 : Word32 tmp_3 = Mpy_32_16_1( output_Fs, avg_length_f_ms_fx ); // 0 - tmp_exp - 15 (Q-fac)
3878 : Word16 tmp_exp_3;
3879 11352 : Word16 tmp_4 = BASOP_Util_Divide3232_Scale( tmp_3, 1000, &tmp_exp_3 ); /*tmp_exp_4 stores resultant exponent*/
3880 11352 : Word16 tmp_exp_4 = sub( add( tmp_exp_3, add( add( 31, tmp_exp ), 15 ) ), 31 );
3881 : Word16 tmp_exp_5;
3882 11352 : Word16 tmp_5 = BASOP_Util_Divide1616_Scale( slot_size, tmp_4, &tmp_exp_5 ); /*res_exp stores resultant exponent*/
3883 11352 : Word16 res_exp = sub( add( tmp_exp_5, 15 ), tmp_exp_4 );
3884 :
3885 11352 : Word16 flag = BASOP_Util_Cmp_Mant32Exp( L_deposit_h( tmp_5 ), res_exp, 1, 31 );
3886 11352 : IF( EQ_16( flag, -1 ) )
3887 : {
3888 11352 : alpha_synthesis_fx[k] = shr( tmp_5, negate( res_exp ) ); // q15
3889 11352 : move16();
3890 : }
3891 : ELSE
3892 : {
3893 0 : alpha_synthesis_fx[k] = MAX16B; /*q15*/
3894 0 : move16();
3895 : }
3896 :
3897 11352 : Word16 flag2 = BASOP_Util_Cmp_Mant32Exp( L_deposit_h( alpha_synthesis_fx[k] ), 0, L_deposit_h( maxAlpha_fx ), 0 );
3898 11352 : test();
3899 11352 : IF( flag2 == 0 || EQ_16( flag2, 1 ) )
3900 : {
3901 2838 : alpha_synthesis_fx[k] = maxAlpha_fx; /*q15*/
3902 2838 : move16();
3903 2838 : *numAlphas = add( k, 1 );
3904 2838 : move16();
3905 2838 : BREAK;
3906 : }
3907 : }
3908 : }
3909 :
3910 2838 : return;
3911 : }
3912 :
3913 :
3914 566309 : static void spreadCoherencePanningHoa_fx(
3915 : const Word16 azimuth,
3916 : const Word16 elevation,
3917 : const Word16 spreadCoh_fx, /*i:Q15*/
3918 : Word32 *direct_response_fx, /*i/o:Q_direct_response*/
3919 : Word16 *Q_direct_response, /*i/o:stores q for direct_response_fx*/
3920 : const Word16 num_channels_dir,
3921 : const Word16 ambisonics_order )
3922 : {
3923 : Word16 i;
3924 :
3925 : Word32 direct_response_left_fx[MAX_OUTPUT_CHANNELS];
3926 : Word32 direct_response_right_fx[MAX_OUTPUT_CHANNELS];
3927 : Word32 gainCenter_fx;
3928 : Word32 gainSide_fx;
3929 :
3930 566309 : ivas_dirac_dec_get_response_fx( azimuth, elevation, direct_response_fx /*Q_direct_response*/, ambisonics_order, *Q_direct_response );
3931 :
3932 : Word16 exp_Gain_side, exp_Gain_center;
3933 566309 : IF( spreadCoh_fx > 0 )
3934 : {
3935 322754 : ivas_dirac_dec_get_response_fx( add( azimuth, 30 ), elevation, direct_response_left_fx /*Q_direct_response*/, ambisonics_order, *Q_direct_response );
3936 322754 : ivas_dirac_dec_get_response_fx( add( azimuth, 330 ), elevation, direct_response_right_fx /*Q_direct_response*/, ambisonics_order, *Q_direct_response );
3937 :
3938 :
3939 : Word16 var_a, var_b, exp_a;
3940 :
3941 322754 : IF( LT_16( spreadCoh_fx, ONE_IN_Q14 /*0.5 q15*/ ) )
3942 : {
3943 : /*gainCenter = (3 - 4*spreadCoh )/3*/
3944 317882 : var_a = sub( 24576 /*3 in Q13*/, spreadCoh_fx ); // Q13
3945 317882 : var_a = mult( var_a, ONE_BY_THREE_Q15 ); // Q13
3946 :
3947 317882 : gainCenter_fx = L_deposit_h( shr( var_a, 2 ) ); // Q11 + 16 = Q27
3948 317882 : gainSide_fx = L_deposit_h( mult( spreadCoh_fx, ONE_BY_THREE_Q15 ) ); // Q14 + 16 (reduce Q by 1 to *2) = Q30
3949 317882 : exp_Gain_side = 31 - Q30;
3950 317882 : move16();
3951 317882 : exp_Gain_center = 31 - Q27;
3952 317882 : move16();
3953 : }
3954 : ELSE
3955 : {
3956 4872 : var_a = shl( sub( 16384 /*2 in Q13*/, shr( spreadCoh_fx, 2 ) ), 1 ); // q13
3957 4872 : exp_a = 15 - Q13;
3958 4872 : move16();
3959 4872 : var_a = Inv16( var_a, &exp_a ); // 15-exp_a
3960 4872 : gainSide_fx = L_deposit_h( var_a ); // 15-exp_a + 16 = Q31 -exp_a
3961 4872 : exp_Gain_side = exp_a;
3962 4872 : move16();
3963 :
3964 4872 : var_b = sub( 8192 /*2 in Q12*/, shr( spreadCoh_fx, 2 ) /*Q14*/ ); // exp => 3
3965 4872 : gainCenter_fx = L_deposit_h( mult( var_b, var_a ) ); // 15-exp_a + 12-15+16=>28-exp_a = // 3 + exp_a
3966 4872 : exp_Gain_center = add( 3, exp_a );
3967 : }
3968 :
3969 :
3970 : Word32 mpy1, mpy2;
3971 : Word16 exp_arr[16], exp;
3972 322754 : set16_fx( exp_arr, sub( 31, *Q_direct_response ), 16 );
3973 2589685 : FOR( i = 0; i < num_channels_dir; i++ )
3974 : {
3975 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
3976 2266931 : mpy2 = Mpy_32_32( direct_response_fx[i], gainCenter_fx ); // 31 - Q_direct_response + exp_Gain_Center
3977 2266931 : exp = 0;
3978 2266931 : move16();
3979 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
3980 2266931 : move32();
3981 2266931 : exp_arr[i] = exp;
3982 2266931 : move16();
3983 : }
3984 322754 : Word16 max_val = MIN_16;
3985 322754 : move16();
3986 5486818 : FOR( i = 0; i < 16; i++ )
3987 : {
3988 5164064 : max_val = s_max( max_val, exp_arr[i] );
3989 : }
3990 5486818 : FOR( i = 0; i < 16; i++ )
3991 : {
3992 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)
3993 5164064 : move32();
3994 : }
3995 322754 : *Q_direct_response = sub( 31, max_val );
3996 322754 : move16();
3997 : }
3998 :
3999 566309 : return;
4000 : }
4001 :
4002 :
4003 4163891 : static void spreadCoherencePanningVbap_fx(
4004 : const Word16 azimuth, /*i:q0*/
4005 : const Word16 elevation, /*i:q0*/
4006 : const Word16 spreadCoh_fx, /*i:q15*/
4007 : Word32 *direct_response_fx, /*i/o:Q_direct_response*/
4008 : Word16 *Q_direct_response, /*o: stores q for direct_response_fx*/
4009 : const Word16 num_channels_dir,
4010 : const VBAP_HANDLE hVBAPdata )
4011 : {
4012 : Word16 i;
4013 : Word32 direct_response_left_fx[MAX_OUTPUT_CHANNELS];
4014 : Word32 direct_response_right_fx[MAX_OUTPUT_CHANNELS];
4015 4163891 : set32_fx( direct_response_left_fx, 0, MAX_OUTPUT_CHANNELS );
4016 4163891 : set32_fx( direct_response_right_fx, 0, MAX_OUTPUT_CHANNELS );
4017 : Word32 gainCenter_fx;
4018 : Word32 gainSide_fx;
4019 :
4020 4163891 : IF( hVBAPdata == NULL )
4021 : {
4022 : /* Distribute signal to all channels if VBAP is not properly initialized. */
4023 0 : Word16 exp_tmp = 0;
4024 0 : move16();
4025 0 : Word16 var_temp = ISqrt16( num_channels_dir, &exp_tmp );
4026 0 : set32_fx( direct_response_fx, var_temp, num_channels_dir );
4027 0 : *Q_direct_response = sub( 31, exp_tmp );
4028 0 : move16();
4029 :
4030 0 : return;
4031 : }
4032 :
4033 4163891 : set32_fx( direct_response_fx, 0, MAX_OUTPUT_CHANNELS );
4034 4163891 : vbap_determine_gains_fx( hVBAPdata, direct_response_fx /*q29*/, azimuth, elevation, 0 );
4035 4163891 : *Q_direct_response = Q29;
4036 4163891 : move16();
4037 :
4038 4163891 : IF( spreadCoh_fx > 0 )
4039 : {
4040 462442 : vbap_determine_gains_fx( hVBAPdata, direct_response_left_fx /*q29*/, add( azimuth, 30 ), elevation, 0 );
4041 462442 : vbap_determine_gains_fx( hVBAPdata, direct_response_right_fx /*q29*/, sub( azimuth, 30 ), elevation, 0 );
4042 :
4043 462442 : Word32 var1 = 0;
4044 462442 : move32();
4045 462442 : Word32 var2 = 0;
4046 462442 : move32();
4047 462442 : Word16 var_a = 0;
4048 462442 : move16();
4049 462442 : Word16 var_b = 0;
4050 462442 : move16();
4051 462442 : IF( LT_16( spreadCoh_fx, 16384 ) ) // 16384 = 0.5 in Q15
4052 : {
4053 451111 : var_a = mult( spreadCoh_fx, INV_SQRT3_FX ); // Q14
4054 451111 : var_b = sub( ONE_IN_Q14, spreadCoh_fx ); // Q14
4055 451111 : gainCenter_fx = L_deposit_h( add( var_a, var_b ) ); // Q30
4056 451111 : gainSide_fx = L_deposit_h( var_a ); // Q30
4057 : }
4058 : ELSE
4059 : {
4060 11331 : var_a = sub( ONE_IN_Q14, shr( spreadCoh_fx, 1 ) ); // Q13
4061 11331 : gainCenter_fx = L_shl( L_deposit_h( var_a ), 1 ); // Q30
4062 11331 : gainSide_fx = ONE_IN_Q30;
4063 11331 : move32();
4064 : }
4065 :
4066 462442 : Word32 var3 = 0;
4067 462442 : move32();
4068 462442 : *Q_direct_response = Q28;
4069 462442 : move16();
4070 4013167 : FOR( i = 0; i < num_channels_dir; i++ )
4071 : {
4072 3550725 : var1 = L_add( direct_response_left_fx[i], direct_response_right_fx[i] ); // Q29
4073 3550725 : var2 = Mpy_32_32( var1, gainSide_fx ); // Q28
4074 3550725 : var3 = Mpy_32_32( direct_response_fx[i], gainCenter_fx ); // Q28
4075 3550725 : direct_response_fx[i] = L_add( var3, var2 ); // Q28
4076 3550725 : move32();
4077 : }
4078 : }
4079 :
4080 4163891 : return;
4081 : }
4082 :
4083 :
4084 8363477 : static void normalizePanningGains_fx(
4085 : Word32 *direct_response_fx, /*i/o:resultant q is q_direct_res*/
4086 : Word16 *q_direct_res, /*i/o: stores q for direct_response_fx*/
4087 : const Word16 num_channels_dir )
4088 : {
4089 : Word32 energySum_fx;
4090 8363477 : Word16 exp_energySum = 0;
4091 : Word32 normVal_fx;
4092 : Word16 i;
4093 8363477 : move16();
4094 :
4095 8363477 : Word16 gb = find_guarded_bits_fx( num_channels_dir );
4096 8363477 : energySum_fx = sum2_f_32_fx( direct_response_fx, num_channels_dir, gb ); // exp_energySum stores resultant exponent
4097 8363477 : IF( GT_16( *q_direct_res, Q31 ) )
4098 : {
4099 1509 : exp_energySum = add( shl( sub( Q31, *q_direct_res ), 1 ), gb );
4100 : }
4101 8363477 : exp_energySum = sub( Q31, sub( sub( shl( *q_direct_res, 1 ), Q31 ), gb ) );
4102 :
4103 8363477 : IF( energySum_fx > 0 )
4104 : {
4105 8349865 : normVal_fx = ISqrt32( energySum_fx, &exp_energySum ); // 31-exp_energySum
4106 : }
4107 : ELSE
4108 : {
4109 13612 : energySum_fx = BASOP_Util_Add_Mant32Exp( energySum_fx, exp_energySum, ONE_IN_Q30, 1, &exp_energySum ); // 31-exp_energySum
4110 13612 : normVal_fx = ISqrt32( energySum_fx, &exp_energySum ); // 31-exp_energySum
4111 : }
4112 :
4113 85164284 : FOR( i = 0; i < num_channels_dir; i++ )
4114 : {
4115 76800807 : direct_response_fx[i] = Mpy_32_32( direct_response_fx[i], normVal_fx ); // q_direct_res stores resultant q for the same
4116 76800807 : move32();
4117 : }
4118 8363477 : Word16 exp = add( sub( Q31, *q_direct_res ), exp_energySum );
4119 8363477 : *q_direct_res = sub( Q31, exp );
4120 :
4121 8363477 : return;
4122 : }
|