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.h"
39 : #include "ivas_prot.h"
40 : #include "ivas_prot_rend.h"
41 : #include "ivas_stat_dec.h"
42 : #include "ivas_cnst.h"
43 : #include "ivas_rom_com.h"
44 : #include "ivas_rom_dec.h"
45 : #ifdef DEBUGGING
46 : #include "debug.h"
47 : #endif
48 : #include "wmc_auto.h"
49 :
50 : /*-------------------------------------------------------------------------
51 : * Local constants
52 : *------------------------------------------------------------------------*/
53 :
54 : #define DIRAC_AVG_LENGTH_SYNTH_MS 20 /*averaging length in ms for DirAC synthesis*/
55 : #define DIRAC_ALPHA_MAX 0.1f
56 : #define DIRAC_AVG_LENGTH_SYNTH_MS_FAST 10
57 : #define DIRAC_ALPHA_MAX_FAST 0.12f
58 : #define DIRECTION_SMOOTHNESS_ALPHA 0.01f
59 :
60 :
61 : /*-------------------------------------------------------------------------
62 : * Local function prototypes
63 : *------------------------------------------------------------------------*/
64 :
65 : static void computeTargetPSDs_direct( const int16_t num_channels, const int16_t num_freq_bands, const float *direct_power_factor, const float *reference_power, const float *direct_responses, const float *direct_responses_square, float *cy_auto_dir_smooth, float *cy_cross_dir_smooth );
66 :
67 : static void computeTargetPSDs_direct_subframe( const int16_t num_channels, const int16_t num_freq_bands, const float *direct_power_factor, const float *reference_power, const float *direct_responses, const float *direct_responses_square, float *cy_auto_dir_smooth, float *cy_cross_dir_smooth );
68 :
69 : static void computeTargetPSDs_diffuse( const int16_t num_channels, const int16_t num_freq_bands, const int16_t start_band, const float *diffuse_power_factor, const float *reference_power, const float *diffuse_responses_square, float *cy_auto_diff_smooth );
70 :
71 : static void computeTargetPSDs_diffuse_subframe( const int16_t num_channels, const int16_t num_freq_bands, const int16_t start_band, const float *diffuse_power_factor, const float *reference_power, const float *diffuse_responses_square, float *cy_auto_diff_smooth );
72 :
73 : static void computeTargetPSDs_diffuse_with_onsets( const int16_t num_channels, const int16_t num_freq_bands, const int16_t num_decorr_freq_bands, const int16_t *proto_frame_diff_index, const float *diffuse_power_factor, const float *reference_power, const float *diffuse_responses_square, const float *onset_filter, float *cy_auto_diff_smooth );
74 :
75 : static void computeAlphaSynthesis( float *alpha_synthesis, const int16_t averaging_length_ms, const float maxAlpha, int16_t *numAlphas, const int16_t slot_size, const int16_t num_freq_bands, const float *frequency_axis, const int32_t output_Fs );
76 :
77 : static void spreadCoherencePanningHoa( const int16_t azimuth, const int16_t elevation, const float spreadCoh, float *direct_response, const int16_t num_channels_dir, const int16_t ambisonics_order );
78 :
79 : static void spreadCoherencePanningVbap( const int16_t azimuth, const int16_t elevation, const float spreadCoh, float *direct_response, const int16_t num_channels_dir, const VBAP_HANDLE hVBAPdata );
80 :
81 : static void normalizePanningGains( float *direct_response, const int16_t num_channels_dir );
82 :
83 :
84 : /*-------------------------------------------------------------------------
85 : * ivas_dirac_dec_output_synthesis_open()
86 : *
87 : *
88 : *------------------------------------------------------------------------*/
89 :
90 87077 : ivas_error ivas_dirac_dec_output_synthesis_open(
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 int16_t nchan_transport, /* i : number of transport channels */
95 : const int32_t output_Fs, /* i : output sampling rate */
96 : const int16_t hodirac_flag /* i : flag to indicate HO-DirAC mode */
97 : )
98 : {
99 : int16_t idx, ch_idx;
100 : int16_t size;
101 : float tmp;
102 : uint16_t num_diffuse_responses;
103 : float temp_alpha_synthesis[CLDFB_NO_CHANNELS_MAX];
104 :
105 : /* pointers to structs for allocation */
106 87077 : DIRAC_OUTPUT_SYNTHESIS_PARAMS *dirac_output_synthesis_params = &( hDirACRend->h_output_synthesis_psd_params );
107 87077 : DIRAC_OUTPUT_SYNTHESIS_STATE *dirac_output_synthesis_state = &( hDirACRend->h_output_synthesis_psd_state );
108 :
109 : /* check / set input parameters */
110 87077 : assert( hSpatParamRendCom->num_freq_bands > 0 && "Error: Number of frequency bands <= 0!" );
111 87077 : assert( hDirACRend->hOutSetup.nchan_out_woLFE > 0 && "Error: Number of output channels > 0!" );
112 87077 : assert( hDirACRend->num_outputs_diff > 0 );
113 87077 : assert( hSpatParamRendCom->slot_size > 0 );
114 87077 : assert( hDirACRend->hOutSetup.is_loudspeaker_setup == 0 || hDirACRend->hOutSetup.is_loudspeaker_setup == 1 );
115 87077 : assert( hDirACRend->diffuse_response_function != NULL );
116 :
117 87077 : if ( hDirACRend->proto_signal_decorr_on )
118 : {
119 82979 : dirac_output_synthesis_params->max_band_decorr = hDirACRend->h_freq_domain_decorr_ap_params->max_band_decorr;
120 : }
121 : else
122 : {
123 4098 : dirac_output_synthesis_params->max_band_decorr = 0;
124 : }
125 :
126 : /*-----------------------------------------------------------------*
127 : * memory allocation
128 : *-----------------------------------------------------------------*/
129 :
130 87077 : dirac_output_synthesis_state->diffuse_responses_square = NULL;
131 87077 : if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_MONO )
132 : {
133 1942 : if ( ( dirac_output_synthesis_state->diffuse_responses_square = (float *) malloc( 2 * sizeof( float ) ) ) == NULL )
134 : {
135 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
136 : }
137 : }
138 85135 : else if ( hDirACRend->synthesisConf != DIRAC_SYNTHESIS_GAIN_SHD )
139 : {
140 43128 : if ( ( dirac_output_synthesis_state->diffuse_responses_square = (float *) malloc( hDirACRend->hOutSetup.nchan_out_woLFE * sizeof( float ) ) ) == NULL )
141 : {
142 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
143 : }
144 : }
145 :
146 : /* prototype power buffers */
147 87077 : dirac_output_synthesis_state->proto_power_smooth_prev = NULL;
148 87077 : if ( hDirACRend->synthesisConf != DIRAC_SYNTHESIS_GAIN_SHD )
149 : {
150 45070 : if ( ( dirac_output_synthesis_state->proto_power_smooth_prev = (float *) malloc( hSpatParamRendCom->num_freq_bands * hDirACRend->num_protos_dir * sizeof( float ) ) ) == NULL )
151 : {
152 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
153 : }
154 : }
155 87077 : if ( dirac_output_synthesis_params->max_band_decorr > 0 && ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_PSD_LS || hDirACRend->synthesisConf == DIRAC_SYNTHESIS_PSD_SHD ) )
156 : {
157 40972 : if ( ( dirac_output_synthesis_state->proto_power_diff_smooth_prev = (float *) malloc( dirac_output_synthesis_params->max_band_decorr * hDirACRend->hOutSetup.nchan_out_woLFE * sizeof( float ) ) ) == NULL )
158 : {
159 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
160 : }
161 : }
162 : else
163 : {
164 46105 : dirac_output_synthesis_state->proto_power_diff_smooth_prev = NULL;
165 : }
166 :
167 : /* buffer length and interpolator */
168 87077 : if ( ( dirac_output_synthesis_params->interpolator = (float *) malloc( JBM_CLDFB_SLOTS_IN_SUBFRAME * sizeof( float ) ) ) == NULL )
169 : {
170 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
171 : }
172 :
173 : /* target PSD buffers */
174 87077 : if ( hodirac_flag )
175 : {
176 7528 : size = hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_dir * DIRAC_HO_NUMSECTORS;
177 : }
178 : else
179 : {
180 79549 : size = hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_dir;
181 : }
182 87077 : if ( ( dirac_output_synthesis_state->cy_cross_dir_smooth_prev = (float *) malloc( size * sizeof( float ) ) ) == NULL )
183 : {
184 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
185 : }
186 :
187 87077 : if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD )
188 : {
189 42007 : dirac_output_synthesis_state->cy_auto_dir_smooth_prev = NULL;
190 42007 : if ( ( dirac_output_synthesis_state->cy_auto_diff_smooth_prev = (float *) malloc( dirac_output_synthesis_params->max_band_decorr * hDirACRend->num_outputs_diff * sizeof( float ) ) ) == NULL )
191 : {
192 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
193 : }
194 : }
195 : else
196 : {
197 45070 : if ( ( dirac_output_synthesis_state->cy_auto_dir_smooth_prev = (float *) malloc( hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_dir * sizeof( float ) ) ) == NULL )
198 : {
199 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
200 : }
201 :
202 45070 : if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_PSD_SHD )
203 : {
204 12048 : if ( ( dirac_output_synthesis_state->cy_auto_diff_smooth_prev = (float *) malloc( hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_dir * sizeof( float ) ) ) == NULL )
205 : {
206 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
207 : }
208 : }
209 : else
210 : {
211 33022 : if ( ( dirac_output_synthesis_state->cy_auto_diff_smooth_prev = (float *) malloc( hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_diff * sizeof( float ) ) ) == NULL )
212 : {
213 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
214 : }
215 : }
216 : }
217 :
218 : /* direct and diffuse gain buffers */
219 87077 : if ( ( dirac_output_synthesis_state->gains_dir_prev = (float *) malloc( size * sizeof( float ) ) ) == NULL )
220 : {
221 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
222 : }
223 :
224 87077 : if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD )
225 : {
226 42007 : if ( ( dirac_output_synthesis_state->gains_diff_prev = (float *) malloc( dirac_output_synthesis_params->max_band_decorr * hDirACRend->num_outputs_diff * sizeof( float ) ) ) == NULL )
227 : {
228 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
229 : }
230 : }
231 45070 : else if ( hDirACRend->synthesisConf != DIRAC_SYNTHESIS_PSD_SHD && hDirACRend->synthesisConf != DIRAC_SYNTHESIS_MONO )
232 : {
233 31080 : if ( ( dirac_output_synthesis_state->gains_diff_prev = (float *) malloc( hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_diff * sizeof( float ) ) ) == NULL )
234 : {
235 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
236 : }
237 : }
238 : else
239 : {
240 13990 : if ( ( dirac_output_synthesis_state->gains_diff_prev = (float *) malloc( hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_dir * sizeof( float ) ) ) == NULL )
241 : {
242 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
243 : }
244 : }
245 :
246 : /*-----------------------------------------------------------------*
247 : * prepare processing parameters
248 : *-----------------------------------------------------------------*/
249 :
250 : /* compute alpha */
251 87077 : if ( !( renderer_type == RENDERER_BINAURAL_PARAMETRIC || renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) )
252 : {
253 45070 : computeAlphaSynthesis( temp_alpha_synthesis, DIRAC_AVG_LENGTH_SYNTH_MS, DIRAC_ALPHA_MAX, &dirac_output_synthesis_params->numAlphas, hSpatParamRendCom->slot_size, hSpatParamRendCom->num_freq_bands, hDirACRend->frequency_axis, output_Fs );
254 45070 : if ( ( dirac_output_synthesis_params->alpha_synthesis = (float *) malloc( dirac_output_synthesis_params->numAlphas * sizeof( float ) ) ) == NULL )
255 : {
256 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
257 : }
258 45070 : mvr2r( temp_alpha_synthesis, dirac_output_synthesis_params->alpha_synthesis, dirac_output_synthesis_params->numAlphas );
259 :
260 45070 : computeAlphaSynthesis( temp_alpha_synthesis, DIRAC_AVG_LENGTH_SYNTH_MS_FAST, DIRAC_ALPHA_MAX_FAST, &dirac_output_synthesis_params->numAlphasFast, hSpatParamRendCom->slot_size, hSpatParamRendCom->num_freq_bands, hDirACRend->frequency_axis, output_Fs );
261 45070 : if ( ( dirac_output_synthesis_params->alpha_synthesis_fast = (float *) malloc( dirac_output_synthesis_params->numAlphasFast * sizeof( float ) ) ) == NULL )
262 : {
263 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
264 : }
265 45070 : mvr2r( temp_alpha_synthesis, dirac_output_synthesis_params->alpha_synthesis_fast, dirac_output_synthesis_params->numAlphasFast );
266 :
267 45070 : if ( ( dirac_output_synthesis_state->reference_power_smooth_prev = (float *) malloc( hSpatParamRendCom->num_freq_bands * sizeof( float ) ) ) == NULL )
268 : {
269 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
270 : }
271 45070 : if ( ( dirac_output_synthesis_state->direction_smoothness_prev = (float *) malloc( hSpatParamRendCom->num_freq_bands * sizeof( float ) ) ) == NULL )
272 : {
273 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
274 : }
275 45070 : set_zero( dirac_output_synthesis_state->reference_power_smooth_prev, hSpatParamRendCom->num_freq_bands );
276 45070 : set_zero( dirac_output_synthesis_state->direction_smoothness_prev, hSpatParamRendCom->num_freq_bands );
277 : }
278 : else
279 : {
280 42007 : dirac_output_synthesis_params->alpha_synthesis = NULL;
281 42007 : dirac_output_synthesis_params->alpha_synthesis_fast = NULL;
282 42007 : dirac_output_synthesis_state->reference_power_smooth_prev = NULL;
283 42007 : dirac_output_synthesis_state->direction_smoothness_prev = NULL;
284 : }
285 :
286 : /* compute interpolator */
287 435385 : for ( idx = 1; idx <= JBM_CLDFB_SLOTS_IN_SUBFRAME; ++idx )
288 : {
289 348308 : dirac_output_synthesis_params->interpolator[idx - 1] = (float) idx / (float) JBM_CLDFB_SLOTS_IN_SUBFRAME;
290 : }
291 :
292 : /* prepare diffuse response function */
293 87077 : if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_MONO )
294 : {
295 1942 : num_diffuse_responses = 2;
296 : }
297 : else
298 : {
299 85135 : num_diffuse_responses = hDirACRend->hOutSetup.nchan_out_woLFE;
300 : }
301 :
302 87077 : if ( dirac_output_synthesis_state->diffuse_responses_square != NULL )
303 : {
304 424764 : for ( ch_idx = 0; ch_idx < num_diffuse_responses; ++ch_idx )
305 : {
306 : /*dirac_output_synthesis_state->diffuse_responses_square[ch_idx] = pow(dirac_output_synthesis_params->diffuse_response_function[ch_idx]/max_response, 2.0f);*/
307 379694 : tmp = hDirACRend->diffuse_response_function[ch_idx];
308 :
309 379694 : dirac_output_synthesis_state->diffuse_responses_square[ch_idx] = tmp * tmp;
310 : }
311 : }
312 :
313 87077 : if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD )
314 : {
315 : int16_t diff_compensation_order;
316 : float diff_nrg_total, diff_nrg, diff_nrg_trans, diff_nrg_decorr;
317 :
318 42007 : diff_compensation_order = nchan_transport >= 3 ? 3 : 2; /* compensate missing diffuseness modelling up order 2, except for HR*/
319 42007 : diff_compensation_order = min( diff_compensation_order, hDirACRend->hOutSetup.ambisonics_order );
320 :
321 42007 : diff_nrg_total = 0;
322 42007 : diff_nrg_trans = 0;
323 42007 : diff_nrg_decorr = 0;
324 643339 : for ( ch_idx = 0; ch_idx < ( diff_compensation_order + 1 ) * ( diff_compensation_order + 1 ); ch_idx++ )
325 : {
326 601332 : diff_nrg = hDirACRend->diffuse_response_function[ch_idx] * hDirACRend->diffuse_response_function[ch_idx];
327 601332 : diff_nrg_total += diff_nrg;
328 : /* is it a transport channel?*/
329 601332 : if ( ch_idx == 0 || hDirACRend->proto_index_dir[ch_idx] != 0 )
330 : {
331 206149 : diff_nrg_trans += diff_nrg;
332 : }
333 : /* is it a decorrelated or transport channel?*/
334 601332 : if ( ch_idx < hDirACRend->num_outputs_diff )
335 : {
336 168028 : diff_nrg_decorr += diff_nrg;
337 : }
338 : }
339 42007 : dirac_output_synthesis_params->diffuse_compensation_factor = diff_nrg_total / diff_nrg_trans;
340 42007 : dirac_output_synthesis_params->diffuse_compensation_factor_decorr = diff_nrg_total / diff_nrg_decorr;
341 : }
342 : else
343 : {
344 45070 : dirac_output_synthesis_params->diffuse_compensation_factor = 0.f;
345 45070 : dirac_output_synthesis_params->diffuse_compensation_factor_decorr = 0.f;
346 : }
347 :
348 87077 : return IVAS_ERR_OK;
349 : }
350 :
351 :
352 : /*-------------------------------------------------------------------------
353 : * ivas_dirac_dec_output_synthesis_init()
354 : *
355 : *
356 : *------------------------------------------------------------------------*/
357 :
358 88607 : void ivas_dirac_dec_output_synthesis_init(
359 : SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common spatial renderer data handle */
360 : DIRAC_REND_HANDLE hDirACRend, /* i/o: DirAC renderer handle */
361 : const int16_t nchan_out_woLFE, /* i : number of output audio channels without LFE */
362 : const int16_t hodirac_flag /* i : flag to indicate HO-DirAC mode */
363 : )
364 : {
365 : int16_t size;
366 :
367 : DIRAC_OUTPUT_SYNTHESIS_PARAMS *h_dirac_output_synthesis_params;
368 : DIRAC_OUTPUT_SYNTHESIS_STATE *h_dirac_output_synthesis_state;
369 :
370 88607 : h_dirac_output_synthesis_params = &( hDirACRend->h_output_synthesis_psd_params );
371 88607 : h_dirac_output_synthesis_state = &( hDirACRend->h_output_synthesis_psd_state );
372 :
373 : /*-----------------------------------------------------------------*
374 : * init outputSynthesisPSD_Init
375 : *-----------------------------------------------------------------*/
376 :
377 : /* initialize buffers */
378 88607 : if ( h_dirac_output_synthesis_state->cy_auto_dir_smooth_prev != NULL )
379 : {
380 45130 : set_zero( h_dirac_output_synthesis_state->cy_auto_dir_smooth_prev, hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_dir );
381 : }
382 :
383 88607 : if ( hodirac_flag )
384 : {
385 7528 : size = hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_dir * DIRAC_HO_NUMSECTORS;
386 : }
387 : else
388 : {
389 81079 : size = hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_dir;
390 : }
391 88607 : set_zero( h_dirac_output_synthesis_state->cy_cross_dir_smooth_prev, size );
392 :
393 88607 : if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD )
394 : {
395 43477 : set_zero( h_dirac_output_synthesis_state->cy_auto_diff_smooth_prev, h_dirac_output_synthesis_params->max_band_decorr * hDirACRend->num_outputs_diff );
396 : }
397 45130 : else if ( hDirACRend->synthesisConf != DIRAC_SYNTHESIS_PSD_SHD )
398 : {
399 33082 : set_zero( h_dirac_output_synthesis_state->cy_auto_diff_smooth_prev, hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_diff );
400 : }
401 : else
402 : {
403 12048 : set_zero( h_dirac_output_synthesis_state->cy_auto_diff_smooth_prev, hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_dir );
404 : }
405 :
406 88607 : if ( h_dirac_output_synthesis_state->proto_power_smooth_prev != NULL )
407 : {
408 45130 : set_zero( h_dirac_output_synthesis_state->proto_power_smooth_prev, hSpatParamRendCom->num_freq_bands * hDirACRend->num_protos_dir );
409 : }
410 88607 : set_zero( h_dirac_output_synthesis_state->gains_dir_prev, size );
411 :
412 88607 : if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD )
413 : {
414 43477 : set_zero( h_dirac_output_synthesis_state->gains_diff_prev, h_dirac_output_synthesis_params->max_band_decorr * hDirACRend->num_outputs_diff );
415 : }
416 : else
417 : {
418 45130 : set_zero( h_dirac_output_synthesis_state->gains_diff_prev, hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_dir );
419 : }
420 :
421 88607 : if ( h_dirac_output_synthesis_state->proto_power_diff_smooth_prev != NULL )
422 : {
423 40972 : set_zero( h_dirac_output_synthesis_state->proto_power_diff_smooth_prev, h_dirac_output_synthesis_params->max_band_decorr * nchan_out_woLFE );
424 : }
425 :
426 88607 : return;
427 : }
428 :
429 :
430 : /*-------------------------------------------------------------------------
431 : * ivas_dirac_dec_output_synthesis_close()
432 : *
433 : * Memory deallocation of Output synthesis sub-module
434 : *------------------------------------------------------------------------*/
435 :
436 87077 : void ivas_dirac_dec_output_synthesis_close(
437 : DIRAC_REND_HANDLE hDirACRend /* i/o: DirAC handle */
438 : )
439 : {
440 : /* pointers to structs for allocation */
441 87077 : DIRAC_OUTPUT_SYNTHESIS_PARAMS *dirac_output_synthesis_params = &( hDirACRend->h_output_synthesis_psd_params );
442 87077 : DIRAC_OUTPUT_SYNTHESIS_STATE *dirac_output_synthesis_state = &( hDirACRend->h_output_synthesis_psd_state );
443 :
444 : /*-----------------------------------------------------------------*
445 : * memory deallocation
446 : *-----------------------------------------------------------------*/
447 :
448 : /* free interpolator */
449 87077 : if ( ( dirac_output_synthesis_params )->interpolator != NULL )
450 : {
451 87077 : free( ( dirac_output_synthesis_params )->interpolator );
452 87077 : ( dirac_output_synthesis_params )->interpolator = NULL;
453 : }
454 :
455 : /* free alpha */
456 87077 : if ( ( dirac_output_synthesis_params )->alpha_synthesis != NULL )
457 : {
458 45070 : free( ( dirac_output_synthesis_params )->alpha_synthesis );
459 45070 : ( dirac_output_synthesis_params )->alpha_synthesis = NULL;
460 : }
461 87077 : if ( ( dirac_output_synthesis_params )->alpha_synthesis_fast != NULL )
462 : {
463 45070 : free( ( dirac_output_synthesis_params )->alpha_synthesis_fast );
464 45070 : ( dirac_output_synthesis_params )->alpha_synthesis_fast = NULL;
465 : }
466 :
467 87077 : if ( ( dirac_output_synthesis_state )->reference_power_smooth_prev != NULL )
468 : {
469 45070 : free( ( dirac_output_synthesis_state )->reference_power_smooth_prev );
470 45070 : ( dirac_output_synthesis_state )->reference_power_smooth_prev = NULL;
471 : }
472 :
473 87077 : if ( ( dirac_output_synthesis_state )->direction_smoothness_prev != NULL )
474 : {
475 45070 : free( ( dirac_output_synthesis_state )->direction_smoothness_prev );
476 45070 : ( dirac_output_synthesis_state )->direction_smoothness_prev = NULL;
477 : }
478 :
479 87077 : if ( ( dirac_output_synthesis_state )->diffuse_responses_square != NULL )
480 : {
481 45070 : free( ( dirac_output_synthesis_state )->diffuse_responses_square );
482 45070 : ( dirac_output_synthesis_state )->diffuse_responses_square = NULL;
483 : }
484 :
485 : /* free power buffers */
486 87077 : if ( ( dirac_output_synthesis_state )->proto_power_smooth_prev != NULL )
487 : {
488 45070 : free( ( dirac_output_synthesis_state )->proto_power_smooth_prev );
489 45070 : ( dirac_output_synthesis_state )->proto_power_smooth_prev = NULL;
490 : }
491 :
492 87077 : if ( ( dirac_output_synthesis_state )->proto_power_diff_smooth_prev != NULL )
493 : {
494 40972 : free( ( dirac_output_synthesis_state )->proto_power_diff_smooth_prev );
495 40972 : ( dirac_output_synthesis_state )->proto_power_diff_smooth_prev = NULL;
496 : }
497 :
498 : /* free target power buffers */
499 87077 : if ( ( dirac_output_synthesis_state )->cy_auto_dir_smooth_prev != NULL )
500 : {
501 45070 : free( ( dirac_output_synthesis_state )->cy_auto_dir_smooth_prev );
502 45070 : ( dirac_output_synthesis_state )->cy_auto_dir_smooth_prev = NULL;
503 : }
504 87077 : if ( ( dirac_output_synthesis_state )->cy_cross_dir_smooth_prev != NULL )
505 : {
506 87077 : free( ( dirac_output_synthesis_state )->cy_cross_dir_smooth_prev );
507 87077 : ( dirac_output_synthesis_state )->cy_cross_dir_smooth_prev = NULL;
508 : }
509 87077 : if ( ( dirac_output_synthesis_state )->cy_auto_diff_smooth_prev != NULL )
510 : {
511 87077 : free( ( dirac_output_synthesis_state )->cy_auto_diff_smooth_prev );
512 87077 : ( dirac_output_synthesis_state )->cy_auto_diff_smooth_prev = NULL;
513 : }
514 :
515 : /* free gain buffers */
516 87077 : if ( ( dirac_output_synthesis_state )->gains_dir_prev != NULL )
517 : {
518 87077 : free( ( dirac_output_synthesis_state )->gains_dir_prev );
519 87077 : ( dirac_output_synthesis_state )->gains_dir_prev = NULL;
520 : }
521 87077 : if ( ( dirac_output_synthesis_state )->gains_diff_prev != NULL )
522 : {
523 87077 : free( ( dirac_output_synthesis_state )->gains_diff_prev );
524 87077 : ( dirac_output_synthesis_state )->gains_diff_prev = NULL;
525 : }
526 :
527 87077 : return;
528 : }
529 :
530 :
531 : /*-------------------------------------------------------------------------
532 : * ivas_dirac_dec_output_synthesis_process_slot()
533 : *
534 : *
535 : *------------------------------------------------------------------------*/
536 :
537 46853247 : void ivas_dirac_dec_output_synthesis_process_slot(
538 : const float *reference_power, /* i : Estimated power */
539 : const float *onset, /* i : onset filter */
540 : const int16_t *azimuth,
541 : const int16_t *elevation,
542 : const float *diffuseness,
543 : SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common spatial renderer data handle */
544 : DIRAC_REND_HANDLE hDirACRend, /* i/o: DirAC renderer handle */
545 : const VBAP_HANDLE hVBAPdata, /* i : VBAP structure */
546 : const IVAS_OUTPUT_SETUP hOutSetup, /* i : output setup structure */
547 : const int16_t nchan_transport, /* i : number of transport channels*/
548 : const int16_t md_idx,
549 : const int16_t hodirac_flag, /* i : flag to indicate HO-DirAC mode */
550 : const int16_t dec_param_estim )
551 : {
552 : int16_t num_freq_bands, num_channels_dir;
553 : int16_t num_freq_bands_diff, num_channels_diff;
554 : int16_t ch_idx;
555 : float aux_buf[CLDFB_NO_CHANNELS_MAX];
556 : int16_t diff_start_band;
557 : DIRAC_OUTPUT_SYNTHESIS_PARAMS *h_dirac_output_synthesis_params;
558 : DIRAC_OUTPUT_SYNTHESIS_STATE *h_dirac_output_synthesis_state;
559 :
560 46853247 : h_dirac_output_synthesis_params = &( hDirACRend->h_output_synthesis_psd_params );
561 46853247 : h_dirac_output_synthesis_state = &( hDirACRend->h_output_synthesis_psd_state );
562 :
563 46853247 : h_dirac_output_synthesis_state->onset_filter = onset;
564 :
565 : /*-----------------------------------------------------------------*
566 : * processing
567 : *-----------------------------------------------------------------*/
568 :
569 : /* collect some often used parameters */
570 46853247 : num_freq_bands = hSpatParamRendCom->num_freq_bands;
571 46853247 : num_channels_dir = hDirACRend->num_outputs_dir;
572 46853247 : num_channels_diff = hDirACRend->num_outputs_diff;
573 46853247 : num_freq_bands_diff = h_dirac_output_synthesis_params->max_band_decorr;
574 :
575 46853247 : if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_PSD_LS )
576 : {
577 10410711 : num_channels_dir = hOutSetup.nchan_out_woLFE;
578 : }
579 :
580 46853247 : if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD && hodirac_flag )
581 : {
582 6481584 : ivas_dirac_dec_compute_directional_responses( hSpatParamRendCom,
583 : hDirACRend,
584 : hVBAPdata,
585 : NULL,
586 : NULL,
587 : azimuth,
588 : elevation,
589 : md_idx,
590 : NULL,
591 : hodirac_flag );
592 : }
593 :
594 46853247 : if ( dec_param_estim == FALSE && hodirac_flag )
595 : {
596 6481584 : if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD )
597 : {
598 6481584 : v_multc( hSpatParamRendCom->energy_ratio1[md_idx], -1.f, aux_buf, num_freq_bands );
599 6481584 : v_addc( aux_buf, 1.f, aux_buf, num_freq_bands );
600 6481584 : mvr2r( hSpatParamRendCom->energy_ratio1[md_idx],
601 : h_dirac_output_synthesis_state->direct_power_factor,
602 : num_freq_bands );
603 6481584 : mvr2r( aux_buf,
604 : h_dirac_output_synthesis_state->diffuse_power_factor,
605 : num_freq_bands );
606 :
607 6481584 : v_multc( hSpatParamRendCom->energy_ratio2[md_idx], -1.f, aux_buf, num_freq_bands );
608 6481584 : v_addc( aux_buf, 1.f, aux_buf, num_freq_bands );
609 6481584 : mvr2r( hSpatParamRendCom->energy_ratio2[md_idx],
610 6481584 : &h_dirac_output_synthesis_state->direct_power_factor[hSpatParamRendCom->num_freq_bands],
611 : num_freq_bands );
612 6481584 : mvr2r( aux_buf,
613 6481584 : &h_dirac_output_synthesis_state->diffuse_power_factor[hSpatParamRendCom->num_freq_bands],
614 : num_freq_bands );
615 : }
616 : else
617 : {
618 0 : ivas_dirac_dec_compute_gain_factors( num_freq_bands,
619 0 : hSpatParamRendCom->diffuseness_vector[md_idx],
620 0 : h_dirac_output_synthesis_params->max_band_decorr,
621 : h_dirac_output_synthesis_state->direct_power_factor,
622 : h_dirac_output_synthesis_state->diffuse_power_factor );
623 : }
624 : }
625 40371663 : else if ( dec_param_estim == TRUE )
626 : {
627 : /* compute direct responses */
628 27254357 : ivas_dirac_dec_compute_directional_responses( hSpatParamRendCom,
629 : hDirACRend,
630 : hVBAPdata,
631 : NULL,
632 : NULL,
633 : azimuth,
634 : elevation,
635 : md_idx,
636 : NULL,
637 : hodirac_flag );
638 :
639 27254357 : if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD )
640 : {
641 25327269 : ivas_dirac_dec_compute_gain_factors( num_freq_bands,
642 : diffuseness,
643 25327269 : h_dirac_output_synthesis_params->max_band_decorr,
644 : h_dirac_output_synthesis_state->direct_power_factor,
645 : h_dirac_output_synthesis_state->diffuse_power_factor );
646 :
647 25327269 : v_multc( h_dirac_output_synthesis_state->direct_power_factor,
648 : 0.25f,
649 : h_dirac_output_synthesis_state->direct_power_factor,
650 : num_freq_bands );
651 25327269 : v_multc( h_dirac_output_synthesis_state->diffuse_power_factor,
652 : 0.25f,
653 : h_dirac_output_synthesis_state->diffuse_power_factor,
654 : num_freq_bands );
655 :
656 : /*Direct gain*/
657 126636345 : for ( ch_idx = 0; ch_idx < min( 4, nchan_transport ); ch_idx++ )
658 : {
659 : int16_t k;
660 101309076 : if ( ch_idx != 0 )
661 : {
662 : float a, b, c;
663 :
664 : /*Directonal sound gain nrg compensation*/
665 455890842 : for ( k = 0; k < num_freq_bands_diff; k++ )
666 : {
667 379909035 : a = h_dirac_output_synthesis_state->direct_responses[ch_idx * num_freq_bands + k];
668 379909035 : b = reference_power[k + num_freq_bands] / ( reference_power[k + ( ch_idx + 1 ) * num_freq_bands] + EPSILON );
669 379909035 : c = 1.f + ( 1.f / 6.f ) * ( h_dirac_output_synthesis_params->diffuse_compensation_factor_decorr - 1.f ); /*Diffuseness modellling nrg compensation*/
670 379909035 : h_dirac_output_synthesis_state->cy_cross_dir_smooth[ch_idx * num_freq_bands + k] += 0.25f * sqrtf( diffuseness[k] * c + ( ( 1.f - diffuseness[k] ) * a * a * b ) );
671 : }
672 3009703812 : for ( ; k < num_freq_bands; k++ )
673 : {
674 2933722005 : a = h_dirac_output_synthesis_state->direct_responses[ch_idx * num_freq_bands + k];
675 2933722005 : b = reference_power[k + num_freq_bands] / ( reference_power[k + ( ch_idx + 1 ) * num_freq_bands] + EPSILON );
676 2933722005 : c = 1.f + ( 1.f / 6.f ) * ( h_dirac_output_synthesis_params->diffuse_compensation_factor - 1.f ); /*Diffuseness modellling nrg compensation*/
677 2933722005 : h_dirac_output_synthesis_state->cy_cross_dir_smooth[ch_idx * num_freq_bands + k] += 0.25f * sqrtf( diffuseness[k] * c + ( ( 1.f - diffuseness[k] ) * a * a * b ) );
678 : }
679 : }
680 : else
681 : {
682 : /*Diffuseness modellling nrg compensation*/
683 151963614 : for ( k = 0; k < num_freq_bands_diff; k++ )
684 : {
685 126636345 : h_dirac_output_synthesis_state->cy_cross_dir_smooth[ch_idx * num_freq_bands + k] += 0.25f * sqrtf( 1.0f + diffuseness[k] * 0.5f * ( h_dirac_output_synthesis_params->diffuse_compensation_factor_decorr - 1.f ) );
686 : }
687 1003234604 : for ( ; k < num_freq_bands; k++ )
688 : {
689 977907335 : h_dirac_output_synthesis_state->cy_cross_dir_smooth[ch_idx * num_freq_bands + k] += 0.25f * sqrtf( 1.0f + diffuseness[k] * 0.5f * ( h_dirac_output_synthesis_params->diffuse_compensation_factor - 1.f ) );
690 : }
691 : }
692 : }
693 :
694 : /*Directional gain (panning)*/
695 305271041 : for ( ch_idx = min( 4, nchan_transport ); ch_idx < num_channels_dir; ch_idx++ )
696 : {
697 279943772 : v_mult( h_dirac_output_synthesis_state->direct_power_factor,
698 279943772 : &h_dirac_output_synthesis_state->direct_responses[ch_idx * num_freq_bands],
699 : aux_buf,
700 : num_freq_bands );
701 :
702 279943772 : v_add( aux_buf,
703 279943772 : &h_dirac_output_synthesis_state->cy_cross_dir_smooth[ch_idx * num_freq_bands],
704 279943772 : &h_dirac_output_synthesis_state->cy_cross_dir_smooth[ch_idx * num_freq_bands],
705 : num_freq_bands );
706 : }
707 :
708 : /*Diffuse gain*/
709 25327269 : for ( ch_idx = min( 4, nchan_transport ); ch_idx < num_channels_diff; ch_idx++ )
710 : {
711 0 : v_multc( h_dirac_output_synthesis_state->diffuse_power_factor,
712 0 : hDirACRend->diffuse_response_function[ch_idx],
713 : aux_buf,
714 : num_freq_bands_diff );
715 :
716 0 : v_add( aux_buf,
717 0 : &h_dirac_output_synthesis_state->cy_auto_diff_smooth[ch_idx * num_freq_bands_diff],
718 0 : &h_dirac_output_synthesis_state->cy_auto_diff_smooth[ch_idx * num_freq_bands_diff],
719 : num_freq_bands_diff );
720 : }
721 :
722 25327269 : return;
723 : }
724 : else
725 : {
726 : /* compute reference and diffuse power factor for this frame */
727 1927088 : ivas_dirac_dec_compute_power_factors( num_freq_bands,
728 : diffuseness,
729 1927088 : h_dirac_output_synthesis_params->max_band_decorr,
730 : h_dirac_output_synthesis_state->direct_power_factor,
731 : h_dirac_output_synthesis_state->diffuse_power_factor );
732 : }
733 : }
734 :
735 21525978 : diff_start_band = 0;
736 21525978 : if ( h_dirac_output_synthesis_params->use_onset_filters )
737 : {
738 8483623 : computeTargetPSDs_diffuse_with_onsets( num_channels_dir,
739 8483623 : num_freq_bands, h_dirac_output_synthesis_params->max_band_decorr,
740 8483623 : hDirACRend->proto_index_diff,
741 8483623 : h_dirac_output_synthesis_state->diffuse_power_factor,
742 : reference_power,
743 8483623 : h_dirac_output_synthesis_state->diffuse_responses_square,
744 : onset,
745 : h_dirac_output_synthesis_state->cy_auto_diff_smooth );
746 :
747 8483623 : diff_start_band = h_dirac_output_synthesis_params->max_band_decorr;
748 : }
749 :
750 : /* process other PSDs only slot wise for 4 transport channels */
751 21525978 : if ( dec_param_estim == TRUE )
752 : {
753 1927088 : computeTargetPSDs_direct( num_channels_dir, num_freq_bands, h_dirac_output_synthesis_state->direct_power_factor, reference_power, h_dirac_output_synthesis_state->direct_responses, h_dirac_output_synthesis_state->direct_responses_square, h_dirac_output_synthesis_state->cy_auto_dir_smooth, h_dirac_output_synthesis_state->cy_cross_dir_smooth );
754 :
755 1927088 : computeTargetPSDs_diffuse( num_channels_dir, num_freq_bands, diff_start_band, h_dirac_output_synthesis_state->diffuse_power_factor, reference_power, h_dirac_output_synthesis_state->diffuse_responses_square, h_dirac_output_synthesis_state->cy_auto_diff_smooth );
756 : }
757 :
758 21525978 : return;
759 : }
760 :
761 :
762 : /*-------------------------------------------------------------------------
763 : * ivas_dirac_dec_output_synthesis_process_subframe_gain_shd()
764 : *
765 : *
766 : *------------------------------------------------------------------------*/
767 :
768 8157249 : void ivas_dirac_dec_output_synthesis_process_subframe_gain_shd(
769 : float RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : LS signals */
770 : float ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : LS signals */
771 : SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common spatial renderer data handle */
772 : DIRAC_REND_HANDLE hDirACRend, /* i/o: DirAC renderer handle */
773 : const int16_t nchan_transport, /* i : number of transport channels */
774 : const int16_t nbslots, /* i : number of slots to process */
775 : const float *onset_filter,
776 : float *diffuseness,
777 : const int16_t hodirac_flag, /* i : flag to indicate HO-DirAC mode */
778 : const int16_t dec_param_estim )
779 : {
780 : int16_t buf_idx, ch_idx, i, l;
781 : int16_t num_freq_bands, num_freq_bands_diff;
782 : int16_t num_channels_dir, num_channels_diff;
783 : float g, g1, g2;
784 : float *p_gains_dir, *p_gains_diff;
785 : float *p_gains_dir_prev, *p_gains_diff_prev;
786 : float *p_cy_cross_dir_smooth;
787 : float *p_cy_auto_diff_smooth;
788 : float *p_proto, *p_out_real, *p_out_imag;
789 : float *p_proto_diff;
790 : int16_t *proto_direct_index, num_protos_dir;
791 : float output_real[CLDFB_NO_CHANNELS_MAX * MAX_OUTPUT_CHANNELS];
792 : float output_imag[CLDFB_NO_CHANNELS_MAX * MAX_OUTPUT_CHANNELS];
793 : DIRAC_OUTPUT_SYNTHESIS_PARAMS h_dirac_output_synthesis_params;
794 : DIRAC_OUTPUT_SYNTHESIS_STATE h_dirac_output_synthesis_state;
795 : int16_t nchan_transport_foa;
796 : int16_t ch_idx_diff;
797 : float aux_buf[CLDFB_NO_CHANNELS_MAX];
798 : float ratio[DIRAC_HO_NUMSECTORS * CLDFB_NO_CHANNELS_MAX];
799 :
800 : /* collect some often used parameters */
801 8157249 : h_dirac_output_synthesis_params = hDirACRend->h_output_synthesis_psd_params;
802 8157249 : h_dirac_output_synthesis_state = hDirACRend->h_output_synthesis_psd_state;
803 8157249 : proto_direct_index = hDirACRend->proto_index_dir;
804 :
805 8157249 : num_protos_dir = hDirACRend->num_protos_dir;
806 8157249 : num_freq_bands = hSpatParamRendCom->num_freq_bands;
807 8157249 : num_freq_bands_diff = h_dirac_output_synthesis_params.max_band_decorr;
808 8157249 : num_channels_dir = hDirACRend->num_outputs_dir;
809 8157249 : num_channels_diff = hDirACRend->num_outputs_diff;
810 8157249 : nchan_transport_foa = min( 4, nchan_transport );
811 :
812 :
813 : /*-----------------------------------------------------------------*
814 : * comput target Gains
815 : *-----------------------------------------------------------------*/
816 :
817 8157249 : if ( hodirac_flag )
818 : {
819 : /*Direct gain*/
820 8101980 : for ( ch_idx = 0; ch_idx < nchan_transport_foa; ch_idx++ )
821 : {
822 6481584 : v_multc( diffuseness,
823 : 1.f,
824 6481584 : &h_dirac_output_synthesis_state.cy_cross_dir_smooth[ch_idx * num_freq_bands],
825 : num_freq_bands );
826 6481584 : v_multc( &h_dirac_output_synthesis_state.cy_cross_dir_smooth[ch_idx * num_freq_bands],
827 6481584 : h_dirac_output_synthesis_params.diffuse_compensation_factor - 1.f,
828 6481584 : &h_dirac_output_synthesis_state.cy_cross_dir_smooth[ch_idx * num_freq_bands],
829 : num_freq_bands );
830 :
831 332074224 : for ( l = 0; l < num_freq_bands; l++ )
832 : {
833 325592640 : h_dirac_output_synthesis_state.cy_cross_dir_smooth[ch_idx * num_freq_bands + l] = sqrtf( 1.f + h_dirac_output_synthesis_state.cy_cross_dir_smooth[ch_idx * num_freq_bands + l] );
834 : }
835 : }
836 :
837 : /*Directional gain*/
838 18855780 : for ( ch_idx = nchan_transport_foa; ch_idx < num_channels_dir; ch_idx++ )
839 : {
840 875479224 : for ( l = 0; l < num_freq_bands; l++ )
841 : {
842 858243840 : aux_buf[l] = 1.f - diffuseness[l];
843 858243840 : ratio[l] = 1.f - h_dirac_output_synthesis_state.direct_power_factor[hSpatParamRendCom->num_freq_bands + l];
844 858243840 : ratio[l + num_freq_bands] = 1.f - ratio[l];
845 : }
846 :
847 17235384 : v_mult( aux_buf, ratio, ratio, num_freq_bands );
848 17235384 : v_mult( aux_buf, &ratio[num_freq_bands], &ratio[num_freq_bands], num_freq_bands );
849 :
850 17235384 : v_mult( ratio,
851 17235384 : &h_dirac_output_synthesis_state.direct_responses[ch_idx * num_freq_bands],
852 17235384 : &h_dirac_output_synthesis_state.cy_cross_dir_smooth[ch_idx * num_freq_bands],
853 : num_freq_bands );
854 17235384 : v_mult( &ratio[num_freq_bands],
855 17235384 : &h_dirac_output_synthesis_state.direct_responses[ch_idx * num_freq_bands + num_freq_bands * num_channels_dir],
856 17235384 : &h_dirac_output_synthesis_state.cy_cross_dir_smooth[ch_idx * num_freq_bands + num_freq_bands * num_channels_dir],
857 : num_freq_bands );
858 : }
859 :
860 : /*Diffuse gain*/
861 1620396 : for ( ch_idx = nchan_transport_foa; ch_idx < num_channels_diff; ch_idx++ )
862 : {
863 0 : v_multc( h_dirac_output_synthesis_state.diffuse_power_factor,
864 0 : hDirACRend->diffuse_response_function[ch_idx],
865 0 : &h_dirac_output_synthesis_state.cy_auto_diff_smooth[ch_idx * num_freq_bands_diff],
866 : num_freq_bands_diff );
867 : }
868 : }
869 6536853 : else if ( dec_param_estim == FALSE )
870 : {
871 : /*Direct gain*/
872 387470 : for ( ch_idx = 0; ch_idx < nchan_transport_foa; ch_idx++ )
873 : {
874 193735 : v_mult( h_dirac_output_synthesis_state.diffuse_power_factor,
875 193735 : h_dirac_output_synthesis_state.diffuse_power_factor,
876 193735 : &h_dirac_output_synthesis_state.cy_cross_dir_smooth[ch_idx * num_freq_bands],
877 : num_freq_bands );
878 193735 : v_multc( &h_dirac_output_synthesis_state.cy_cross_dir_smooth[ch_idx * num_freq_bands],
879 193735 : h_dirac_output_synthesis_params.diffuse_compensation_factor_decorr - 1.f,
880 193735 : &h_dirac_output_synthesis_state.cy_cross_dir_smooth[ch_idx * num_freq_bands],
881 : num_freq_bands_diff );
882 193735 : v_multc( &h_dirac_output_synthesis_state.cy_cross_dir_smooth[ch_idx * num_freq_bands + num_freq_bands_diff],
883 193735 : h_dirac_output_synthesis_params.diffuse_compensation_factor - 1.f,
884 193735 : &h_dirac_output_synthesis_state.cy_cross_dir_smooth[ch_idx * num_freq_bands + num_freq_bands_diff],
885 193735 : num_freq_bands - num_freq_bands_diff );
886 :
887 9893275 : for ( l = 0; l < num_freq_bands; l++ )
888 : {
889 9699540 : h_dirac_output_synthesis_state.cy_cross_dir_smooth[ch_idx * num_freq_bands + l] = sqrtf( 1.f + h_dirac_output_synthesis_state.cy_cross_dir_smooth[ch_idx * num_freq_bands + l] );
890 : }
891 : }
892 :
893 : /*Directional gain*/
894 1618768 : for ( ch_idx = nchan_transport_foa; ch_idx < num_channels_dir; ch_idx++ )
895 : {
896 1425033 : v_mult( h_dirac_output_synthesis_state.direct_power_factor,
897 1425033 : &h_dirac_output_synthesis_state.direct_responses[ch_idx * num_freq_bands],
898 1425033 : &h_dirac_output_synthesis_state.cy_cross_dir_smooth[ch_idx * num_freq_bands], num_freq_bands );
899 : }
900 :
901 : /*Diffuse gain*/
902 774940 : for ( ch_idx = nchan_transport_foa; ch_idx < num_channels_diff; ch_idx++ )
903 : {
904 581205 : v_multc( h_dirac_output_synthesis_state.diffuse_power_factor, hDirACRend->diffuse_response_function[ch_idx], &h_dirac_output_synthesis_state.cy_auto_diff_smooth[ch_idx * num_freq_bands_diff], num_freq_bands_diff );
905 : }
906 : }
907 :
908 : /*-----------------------------------------------------------------*
909 : * compute gains
910 : *-----------------------------------------------------------------*/
911 :
912 8157249 : p_cy_cross_dir_smooth = h_dirac_output_synthesis_state.cy_cross_dir_smooth;
913 8157249 : p_gains_dir = h_dirac_output_synthesis_state.cy_cross_dir_smooth_prev;
914 :
915 : /* Direct gains */
916 8157249 : if ( hodirac_flag )
917 : {
918 8101980 : for ( ch_idx = 0; ch_idx < nchan_transport_foa; ch_idx++ )
919 : {
920 332074224 : for ( l = 0; l < num_freq_bands; l++ )
921 : {
922 325592640 : g1 = 0.3679f + onset_filter[l] * ( 0.1175f - 0.3679f );
923 325592640 : g2 = ( 1.f - g1 ) * *( p_gains_dir );
924 325592640 : g2 += g1 * ( *( p_cy_cross_dir_smooth++ ) );
925 325592640 : g2 = max( g2, 0.99f );
926 325592640 : g2 = min( g2, 2.0f );
927 325592640 : *( p_gains_dir++ ) = g2;
928 : }
929 : }
930 : }
931 : else
932 : {
933 32103060 : for ( ch_idx = 0; ch_idx < nchan_transport_foa; ch_idx++ )
934 : {
935 1141681587 : for ( l = 0; l < num_freq_bands; l++ )
936 : {
937 1116115380 : g1 = 0.3679f + onset_filter[l] * ( 0.1175f - 0.3679f );
938 1116115380 : g2 = ( 1.f - g1 ) * *( p_gains_dir );
939 1116115380 : g2 += g1 * ( *( p_cy_cross_dir_smooth++ ) );
940 1116115380 : g2 = max( g2, 0.85f );
941 1116115380 : g2 = min( g2, 1.15f );
942 1116115380 : *( p_gains_dir++ ) = g2;
943 : }
944 : }
945 : }
946 :
947 : /*Directional gains*/
948 96939218 : for ( ch_idx = nchan_transport_foa; ch_idx < num_channels_dir; ch_idx++ )
949 : {
950 4076132749 : for ( l = 0; l < num_freq_bands; l++ )
951 : {
952 3987350780 : g1 = 0.3679f + onset_filter[l] * ( 0.1175f - 0.3679f );
953 3987350780 : g2 = ( 1.f - g1 ) * *( p_gains_dir );
954 3987350780 : g2 += g1 * ( *( p_cy_cross_dir_smooth++ ) );
955 3987350780 : g2 = max( g2, -DIRAC_GAIN_LIMIT );
956 3987350780 : g2 = min( g2, DIRAC_GAIN_LIMIT );
957 3987350780 : *( p_gains_dir++ ) = g2;
958 : }
959 : }
960 :
961 8157249 : if ( hodirac_flag )
962 : {
963 1620396 : p_cy_cross_dir_smooth = h_dirac_output_synthesis_state.cy_cross_dir_smooth + num_freq_bands * num_channels_dir;
964 1620396 : p_gains_dir = h_dirac_output_synthesis_state.cy_cross_dir_smooth_prev + num_freq_bands * num_channels_dir;
965 :
966 : /*Direct gains*/
967 8101980 : for ( ch_idx = 0; ch_idx < nchan_transport_foa; ch_idx++ )
968 : {
969 332074224 : for ( l = 0; l < num_freq_bands; l++ )
970 : {
971 325592640 : p_cy_cross_dir_smooth++;
972 325592640 : p_gains_dir++;
973 : }
974 : }
975 :
976 : /*Directional gains*/
977 18855780 : for ( ch_idx = nchan_transport_foa; ch_idx < num_channels_dir; ch_idx++ )
978 : {
979 875479224 : for ( l = 0; l < num_freq_bands; l++ )
980 : {
981 858243840 : g1 = 0.3679f + onset_filter[l] * ( 0.1175f - 0.3679f );
982 858243840 : g2 = ( 1.f - g1 ) * *( p_gains_dir );
983 858243840 : g2 += g1 * ( *( p_cy_cross_dir_smooth++ ) );
984 858243840 : g2 = max( g2, -DIRAC_GAIN_LIMIT );
985 858243840 : g2 = min( g2, DIRAC_GAIN_LIMIT );
986 858243840 : *( p_gains_dir++ ) = g2;
987 : }
988 : }
989 : }
990 :
991 : /*Diffuse gains*/
992 8157249 : p_cy_auto_diff_smooth = h_dirac_output_synthesis_state.cy_auto_diff_smooth + nchan_transport_foa * num_freq_bands_diff;
993 8157249 : p_gains_diff = h_dirac_output_synthesis_state.cy_auto_diff_smooth_prev + nchan_transport_foa * num_freq_bands_diff;
994 8738454 : for ( ch_idx = nchan_transport_foa; ch_idx < num_channels_diff; ch_idx++ )
995 : {
996 13175259 : for ( l = 0; l < num_freq_bands_diff; l++ )
997 : {
998 12594054 : g1 = 0.1175f;
999 12594054 : g2 = ( 1.f - g1 ) * *( p_gains_diff );
1000 12594054 : g2 += g1 * ( *( p_cy_auto_diff_smooth++ ) );
1001 12594054 : g2 = max( g2, 0.f );
1002 12594054 : g2 = min( g2, DIRAC_GAIN_LIMIT );
1003 12594054 : *( p_gains_diff++ ) = g2;
1004 : }
1005 : }
1006 :
1007 : /*-----------------------------------------------------------------*
1008 : * gain interpolation and output streams
1009 : *-----------------------------------------------------------------*/
1010 :
1011 40731867 : for ( buf_idx = 0; buf_idx < nbslots; ++buf_idx )
1012 : {
1013 32574618 : g1 = h_dirac_output_synthesis_params.interpolator[buf_idx];
1014 32574618 : g2 = 1.f - g1;
1015 :
1016 : /*Direct input->output*/
1017 32574618 : p_gains_dir = h_dirac_output_synthesis_state.cy_cross_dir_smooth_prev;
1018 32574618 : p_gains_dir_prev = h_dirac_output_synthesis_state.gains_dir_prev;
1019 160575795 : for ( ch_idx = 0; ch_idx < nchan_transport_foa; ch_idx++ )
1020 : {
1021 128001177 : p_proto_diff = h_dirac_output_synthesis_state.proto_diffuse_buffer_f + buf_idx * 2 * num_freq_bands * num_channels_diff + ch_idx * 2 * num_freq_bands;
1022 5886794117 : for ( l = 0; l < num_freq_bands; l++ )
1023 : {
1024 5758792940 : g = g1 * ( *( p_gains_dir++ ) ) + g2 * ( *( p_gains_dir_prev++ ) );
1025 5758792940 : output_real[l * num_channels_dir + ch_idx] = g * ( *( p_proto_diff++ ) );
1026 5758792940 : output_imag[l * num_channels_dir + ch_idx] = g * ( *( p_proto_diff++ ) );
1027 : }
1028 : }
1029 :
1030 : /*Directional stream*/
1031 387132533 : for ( ch_idx = nchan_transport_foa; ch_idx < num_channels_dir; ch_idx++ )
1032 : {
1033 354557915 : if ( hodirac_flag )
1034 : {
1035 68941536 : if ( proto_direct_index[ch_idx] == 0 )
1036 : {
1037 : float *p_proto2;
1038 : float gs1, gs2;
1039 37938752 : p_proto = h_dirac_output_synthesis_state.proto_direct_buffer_f +
1040 37938752 : buf_idx * 2 * num_freq_bands * num_protos_dir +
1041 37938752 : proto_direct_index[0] * 2 * num_freq_bands;
1042 37938752 : p_proto2 = h_dirac_output_synthesis_state.proto_direct_buffer_f +
1043 37938752 : buf_idx * 2 * num_freq_bands * num_protos_dir +
1044 37938752 : proto_direct_index[1] * 2 * num_freq_bands;
1045 1883790272 : for ( l = 0; l < num_freq_bands; l++ )
1046 : {
1047 1845851520 : gs1 = g1 * ( *( p_gains_dir ) ) + g2 * ( *( p_gains_dir_prev ) );
1048 1845851520 : gs2 = g1 * ( *( p_gains_dir + num_freq_bands * num_channels_dir ) ) + g2 * ( *( p_gains_dir_prev + num_freq_bands * num_channels_dir ) );
1049 1845851520 : p_gains_dir++;
1050 1845851520 : p_gains_dir_prev++;
1051 :
1052 1845851520 : output_real[l * num_channels_dir + ch_idx] = 0.5f * gs1 * ( 1.772454e+00f * ( *p_proto ) + 1.023327e+00f * ( *p_proto2 ) ) + /* s1 */
1053 1845851520 : 0.5f * gs2 * ( 1.772454e+00f * ( *p_proto ) - 1.023327e+00f * ( *p_proto2 ) ); /* s2 */
1054 1845851520 : p_proto++;
1055 1845851520 : p_proto2++;
1056 1845851520 : output_imag[l * num_channels_dir + ch_idx] = 0.5f * gs1 * ( 1.772454e+00f * ( *p_proto ) + 1.023327e+00f * ( *p_proto2 ) ) +
1057 1845851520 : 0.5f * gs2 * ( 1.772454e+00f * ( *p_proto ) - 1.023327e+00f * ( *p_proto2 ) );
1058 1845851520 : p_proto++;
1059 1845851520 : p_proto2++;
1060 : }
1061 : }
1062 : else
1063 : {
1064 31002784 : p_proto = h_dirac_output_synthesis_state.proto_direct_buffer_f +
1065 31002784 : buf_idx * 2 * num_freq_bands * num_protos_dir +
1066 31002784 : proto_direct_index[ch_idx] * 2 * num_freq_bands;
1067 1618126624 : for ( l = 0; l < num_freq_bands; l++ )
1068 : {
1069 1587123840 : p_gains_dir++;
1070 1587123840 : p_gains_dir_prev++;
1071 :
1072 :
1073 1587123840 : output_real[l * num_channels_dir + ch_idx] = *( p_proto++ );
1074 1587123840 : output_imag[l * num_channels_dir + ch_idx] = *( p_proto++ );
1075 : }
1076 : }
1077 : }
1078 : else
1079 : {
1080 285616379 : p_proto = h_dirac_output_synthesis_state.proto_direct_buffer_f +
1081 285616379 : buf_idx * 2 * num_freq_bands * num_protos_dir +
1082 285616379 : proto_direct_index[ch_idx] * 2 * num_freq_bands;
1083 285616379 : if ( proto_direct_index[ch_idx] == 0 )
1084 : {
1085 12355025679 : for ( l = 0; l < num_freq_bands; l++ )
1086 : {
1087 12077633540 : g = g1 * ( *( p_gains_dir++ ) ) + g2 * ( *( p_gains_dir_prev++ ) );
1088 12077633540 : output_real[l * num_channels_dir + ch_idx] = g * ( *( p_proto++ ) );
1089 12077633540 : output_imag[l * num_channels_dir + ch_idx] = g * ( *( p_proto++ ) );
1090 : }
1091 : }
1092 : else
1093 : {
1094 422901040 : for ( l = 0; l < num_freq_bands; l++ )
1095 : {
1096 414676800 : p_gains_dir++;
1097 414676800 : p_gains_dir_prev++;
1098 414676800 : output_real[l * num_channels_dir + ch_idx] = *( p_proto++ );
1099 414676800 : output_imag[l * num_channels_dir + ch_idx] = *( p_proto++ );
1100 : }
1101 : }
1102 : }
1103 : }
1104 :
1105 : /*Diffuse stream*/
1106 32574618 : p_gains_diff = h_dirac_output_synthesis_state.cy_auto_diff_smooth_prev + nchan_transport_foa * num_freq_bands_diff;
1107 32574618 : p_gains_diff_prev = h_dirac_output_synthesis_state.gains_diff_prev + nchan_transport_foa * num_freq_bands_diff;
1108 32574618 : ch_idx_diff = nchan_transport_foa;
1109 34871913 : for ( ch_idx = nchan_transport_foa; ch_idx < num_channels_diff; ch_idx++ )
1110 : {
1111 2297295 : if ( proto_direct_index[ch_idx] == 0 )
1112 : {
1113 2297295 : p_proto = h_dirac_output_synthesis_state.proto_diffuse_buffer_f + buf_idx * 2 * num_freq_bands * num_channels_diff + ch_idx_diff * 2 * num_freq_bands;
1114 2297295 : ch_idx_diff++;
1115 52067961 : for ( l = 0; l < num_freq_bands_diff; l++ )
1116 : {
1117 49770666 : g = g1 * ( *( p_gains_diff++ ) ) + g2 * ( *( p_gains_diff_prev++ ) );
1118 49770666 : output_real[l * num_channels_dir + hDirACRend->sba_map_tc[ch_idx]] += g * ( *( p_proto++ ) ); /* maps ch_idx 5 to 8 */
1119 49770666 : output_imag[l * num_channels_dir + hDirACRend->sba_map_tc[ch_idx]] += g * ( *( p_proto++ ) );
1120 : }
1121 : }
1122 : else
1123 : {
1124 0 : for ( l = 0; l < num_freq_bands_diff; l++ )
1125 : {
1126 0 : p_gains_diff++;
1127 0 : p_gains_diff_prev++;
1128 : }
1129 : }
1130 : }
1131 :
1132 : /*-----------------------------------------------------------------*
1133 : * Copy output or HOA decoder
1134 : *-----------------------------------------------------------------*/
1135 :
1136 32574618 : if ( hDirACRend->hOutSetup.is_loudspeaker_setup && hDirACRend->hoa_decoder != NULL )
1137 12699728 : {
1138 : float *p_real, *p_imag;
1139 : const float *hoa_decoder;
1140 :
1141 12699728 : hoa_decoder = hDirACRend->hoa_decoder;
1142 :
1143 118121120 : for ( ch_idx = 0; ch_idx < hDirACRend->hOutSetup.nchan_out_woLFE; ch_idx++ )
1144 : {
1145 105421392 : p_real = RealBuffer[ch_idx][buf_idx];
1146 105421392 : p_imag = ImagBuffer[ch_idx][buf_idx];
1147 :
1148 4565684432 : for ( l = 0; l < num_freq_bands; l++ )
1149 : {
1150 4460263040 : p_out_real = output_real + l * num_channels_dir;
1151 4460263040 : p_out_imag = output_imag + l * num_channels_dir;
1152 4460263040 : p_real[l] = *( p_out_real++ ) * hoa_decoder[0];
1153 4460263040 : p_imag[l] = *( p_out_imag++ ) * hoa_decoder[0];
1154 71364208640 : for ( i = 1; i < num_channels_dir; i++ )
1155 : {
1156 66903945600 : p_real[l] += *( p_out_real++ ) * hoa_decoder[i];
1157 66903945600 : p_imag[l] += *( p_out_imag++ ) * hoa_decoder[i];
1158 : }
1159 : }
1160 105421392 : hoa_decoder += 16;
1161 : }
1162 : }
1163 : else
1164 : {
1165 299238334 : for ( ch_idx = 0; ch_idx < num_channels_dir; ch_idx++ )
1166 : {
1167 13401860004 : for ( l = 0; l < num_freq_bands; l++ )
1168 : {
1169 13122496560 : RealBuffer[ch_idx][buf_idx][l] = output_real[l * num_channels_dir + ch_idx];
1170 13122496560 : ImagBuffer[ch_idx][buf_idx][l] = output_imag[l * num_channels_dir + ch_idx];
1171 : }
1172 : }
1173 : }
1174 : }
1175 :
1176 : /*-----------------------------------------------------------------*
1177 : * update buffers
1178 : *-----------------------------------------------------------------*/
1179 :
1180 : /* store estimates for next synthesis block */
1181 8157249 : if ( hodirac_flag )
1182 : {
1183 1620396 : mvr2r( h_dirac_output_synthesis_state.cy_cross_dir_smooth_prev, h_dirac_output_synthesis_state.gains_dir_prev, num_freq_bands * num_channels_dir * DIRAC_HO_NUMSECTORS );
1184 : }
1185 : else
1186 : {
1187 6536853 : mvr2r( h_dirac_output_synthesis_state.cy_cross_dir_smooth_prev, h_dirac_output_synthesis_state.gains_dir_prev, num_freq_bands * num_channels_dir );
1188 : }
1189 :
1190 8157249 : mvr2r( h_dirac_output_synthesis_state.cy_auto_diff_smooth_prev, h_dirac_output_synthesis_state.gains_diff_prev, num_freq_bands_diff * num_channels_diff );
1191 :
1192 : /* reset values */
1193 8157249 : if ( hodirac_flag )
1194 : {
1195 1620396 : set_zero( h_dirac_output_synthesis_state.cy_cross_dir_smooth, num_freq_bands * num_channels_dir * DIRAC_HO_NUMSECTORS );
1196 : }
1197 : else
1198 : {
1199 6536853 : set_zero( h_dirac_output_synthesis_state.cy_cross_dir_smooth, num_freq_bands * num_channels_dir );
1200 : }
1201 :
1202 8157249 : set_zero( h_dirac_output_synthesis_state.cy_auto_diff_smooth, num_freq_bands_diff * num_channels_diff );
1203 :
1204 8157249 : return;
1205 : }
1206 :
1207 :
1208 : /*-------------------------------------------------------------------------
1209 : * ivas_dirac_dec_output_synthesis_process_subframe_psd_ls()
1210 : *
1211 : *
1212 : *------------------------------------------------------------------------*/
1213 :
1214 3598409 : void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls(
1215 : float RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : LS signals */
1216 : float ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : LS signals */
1217 : SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common spatial renderer data handle */
1218 : DIRAC_REND_HANDLE hDirACRend, /* i/o: DirAC renderer handle */
1219 : const int16_t nbslots, /* i : number of slots to process */
1220 : float *diffuseness_vector,
1221 : float *reference_power_smooth,
1222 : float qualityBasedSmFactor,
1223 : const int16_t enc_param_start_band )
1224 : {
1225 : int16_t buf_idx, num_freq_bands;
1226 : int16_t diff_start_band;
1227 : int16_t k, l;
1228 : int16_t nchan_out_woLFE;
1229 : float *p_power_smooth_prev, *p_power_diff_smooth_prev;
1230 : float *p_gain_1, *p_gain_2;
1231 : float *p_power_smooth_diff, *p_power_smooth;
1232 : float *p_gains_dir, *p_gains_diff;
1233 : float g, g1, g2;
1234 : float *p_cy_auto_dir_smooth, *p_cy_auto_dir_smooth_prev;
1235 : float *p_cy_cross_dir_smooth, *p_cy_cross_dir_smooth_prev;
1236 : float *p_cy_auto_diff_smooth, *p_cy_auto_diff_smooth_prev;
1237 : float gains_dir[CLDFB_NO_CHANNELS_MAX * MAX_OUTPUT_CHANNELS];
1238 : float gains_diff[CLDFB_NO_CHANNELS_MAX * MAX_OUTPUT_CHANNELS];
1239 : DIRAC_OUTPUT_SYNTHESIS_PARAMS *h_dirac_output_synthesis_params;
1240 : DIRAC_OUTPUT_SYNTHESIS_STATE *h_dirac_output_synthesis_state;
1241 : int16_t *proto_direct_index, num_protos_dir;
1242 : float target_power_y;
1243 : float subtract_power_y;
1244 : float subtract_target_ratio;
1245 : float subtract_target_ratio_db;
1246 : float a, b;
1247 : uint16_t nchan_target_psds;
1248 : float alpha[CLDFB_NO_CHANNELS_MAX];
1249 : float *alpha_synthesis;
1250 : float *alpha_synthesis_fast;
1251 : int16_t alphaMaxBin;
1252 : int16_t alphaMaxBinFast;
1253 :
1254 3598409 : push_wmops( "dirac_out_synth_sfr" );
1255 :
1256 3598409 : h_dirac_output_synthesis_params = &( hDirACRend->h_output_synthesis_psd_params );
1257 3598409 : h_dirac_output_synthesis_state = &( hDirACRend->h_output_synthesis_psd_state );
1258 3598409 : proto_direct_index = hDirACRend->proto_index_dir;
1259 3598409 : num_protos_dir = hDirACRend->num_protos_dir;
1260 3598409 : nchan_out_woLFE = hDirACRend->hOutSetup.nchan_out_woLFE;
1261 :
1262 : /* collect some often used parameters */
1263 3598409 : num_freq_bands = hSpatParamRendCom->num_freq_bands;
1264 :
1265 : /*-----------------------------------------------------------------*
1266 : * compute target PSDs
1267 : *-----------------------------------------------------------------*/
1268 :
1269 3598409 : if ( enc_param_start_band == 0 )
1270 : {
1271 3116637 : diff_start_band = h_dirac_output_synthesis_params->use_onset_filters == 1 ? h_dirac_output_synthesis_params->max_band_decorr : 0;
1272 :
1273 3116637 : if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_MONO )
1274 : {
1275 162553 : nchan_target_psds = 2;
1276 : }
1277 : else
1278 : {
1279 2954084 : nchan_target_psds = nchan_out_woLFE;
1280 : }
1281 :
1282 3116637 : computeTargetPSDs_direct_subframe( nchan_target_psds, num_freq_bands,
1283 3116637 : h_dirac_output_synthesis_state->direct_power_factor,
1284 : reference_power_smooth,
1285 3116637 : h_dirac_output_synthesis_state->direct_responses,
1286 3116637 : h_dirac_output_synthesis_state->direct_responses_square,
1287 : h_dirac_output_synthesis_state->cy_auto_dir_smooth,
1288 : h_dirac_output_synthesis_state->cy_cross_dir_smooth );
1289 :
1290 3116637 : computeTargetPSDs_diffuse_subframe( nchan_target_psds, num_freq_bands, diff_start_band,
1291 3116637 : h_dirac_output_synthesis_state->diffuse_power_factor,
1292 : reference_power_smooth,
1293 3116637 : h_dirac_output_synthesis_state->diffuse_responses_square,
1294 : h_dirac_output_synthesis_state->cy_auto_diff_smooth );
1295 : }
1296 :
1297 : /*-----------------------------------------------------------------*
1298 : * compute variables for stereo transport signal type detection
1299 : *-----------------------------------------------------------------*/
1300 :
1301 3598409 : if ( hDirACRend->masa_stereo_type_detect != NULL )
1302 : {
1303 379138 : MASA_STEREO_TYPE_DETECT *masa_stereo_type_detect = hDirACRend->masa_stereo_type_detect;
1304 :
1305 379138 : p_cy_auto_dir_smooth = h_dirac_output_synthesis_state->cy_auto_dir_smooth;
1306 379138 : p_cy_auto_diff_smooth = h_dirac_output_synthesis_state->cy_auto_diff_smooth;
1307 379138 : if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_MONO )
1308 : {
1309 162553 : target_power_y = p_cy_auto_dir_smooth[num_freq_bands] / ( sqrtf( h_dirac_output_synthesis_state->direct_power_factor[0] ) + EPSILON );
1310 162553 : target_power_y += p_cy_auto_diff_smooth[num_freq_bands] / ( sqrtf( h_dirac_output_synthesis_state->diffuse_power_factor[0] ) + EPSILON );
1311 : }
1312 : else
1313 : {
1314 216585 : target_power_y = p_cy_auto_dir_smooth[num_freq_bands] + p_cy_auto_diff_smooth[num_freq_bands];
1315 : }
1316 379138 : subtract_power_y = masa_stereo_type_detect->subtract_power_y;
1317 :
1318 379138 : a = 0.0004f; /* Temporal smoothing coefficient */
1319 379138 : b = 1.0f - a; /* Temporal smoothing coefficient */
1320 :
1321 379138 : masa_stereo_type_detect->target_power_y_smooth = a * target_power_y + b * masa_stereo_type_detect->target_power_y_smooth;
1322 379138 : masa_stereo_type_detect->subtract_power_y_smooth = a * subtract_power_y + b * masa_stereo_type_detect->subtract_power_y_smooth;
1323 :
1324 379138 : subtract_target_ratio = masa_stereo_type_detect->subtract_power_y_smooth / ( masa_stereo_type_detect->target_power_y_smooth + EPSILON );
1325 379138 : subtract_target_ratio_db = 10.0f * log10f( subtract_target_ratio );
1326 379138 : masa_stereo_type_detect->subtract_target_ratio_db = subtract_target_ratio_db;
1327 :
1328 379138 : masa_stereo_type_detect->subtract_power_y = 0.0f;
1329 : }
1330 :
1331 : /*-----------------------------------------------------------------*
1332 : * compute smoothing coefficients
1333 : *-----------------------------------------------------------------*/
1334 :
1335 3598409 : alpha_synthesis = h_dirac_output_synthesis_params->alpha_synthesis;
1336 3598409 : alpha_synthesis_fast = h_dirac_output_synthesis_params->alpha_synthesis_fast;
1337 3598409 : alphaMaxBin = h_dirac_output_synthesis_params->numAlphas - 1;
1338 3598409 : alphaMaxBinFast = h_dirac_output_synthesis_params->numAlphasFast - 1;
1339 :
1340 171743589 : for ( l = 0; l < num_freq_bands; l++ )
1341 : {
1342 : float instDirectionSmoothness, weightedDirectionSmoothness, smoothedDirectionSmoothness;
1343 : float currWeight, prevWeight, sumWeight;
1344 : int16_t indexFast, indexSlow;
1345 168145180 : float alpha_quality_based = 0.02f;
1346 :
1347 168145180 : indexSlow = min( l, alphaMaxBin );
1348 168145180 : indexFast = min( l, alphaMaxBinFast );
1349 :
1350 : /* Estimate the smoothness of the directions based on the diffuseness parameter */
1351 168145180 : instDirectionSmoothness = 1.0f - diffuseness_vector[l];
1352 168145180 : instDirectionSmoothness = min( max( instDirectionSmoothness, 0.0f ), 1.0f );
1353 :
1354 : /* Average the direction smoothness parameter over time */
1355 168145180 : currWeight = DIRECTION_SMOOTHNESS_ALPHA * reference_power_smooth[l];
1356 168145180 : prevWeight = ( 1.0f - DIRECTION_SMOOTHNESS_ALPHA ) * h_dirac_output_synthesis_state->reference_power_smooth_prev[l];
1357 :
1358 168145180 : weightedDirectionSmoothness = currWeight * instDirectionSmoothness + prevWeight * h_dirac_output_synthesis_state->direction_smoothness_prev[l];
1359 168145180 : sumWeight = currWeight + prevWeight;
1360 168145180 : smoothedDirectionSmoothness = weightedDirectionSmoothness / ( sumWeight + EPSILON );
1361 :
1362 168145180 : h_dirac_output_synthesis_state->direction_smoothness_prev[l] = smoothedDirectionSmoothness;
1363 168145180 : h_dirac_output_synthesis_state->reference_power_smooth_prev[l] = sumWeight;
1364 :
1365 : /* Determine smoothing parameter for rendering. The smoother the directions, the less smoothing is required (i.e., faster smoothing can be used). */
1366 168145180 : alpha[l] = smoothedDirectionSmoothness * alpha_synthesis_fast[indexFast] + ( 1.0f - smoothedDirectionSmoothness ) * alpha_synthesis[indexSlow];
1367 :
1368 : /* Adjust smoothing parameter based on encoding quality */
1369 168145180 : alpha[l] = qualityBasedSmFactor * alpha[l] + ( 1.0f - qualityBasedSmFactor ) * alpha_quality_based;
1370 : }
1371 :
1372 : /*-----------------------------------------------------------------*
1373 : * compute gains
1374 : *-----------------------------------------------------------------*/
1375 :
1376 : /*Direct normalization gains on reduced number of protos*/
1377 3598409 : p_power_smooth_prev = h_dirac_output_synthesis_state->proto_power_smooth_prev;
1378 3598409 : p_power_smooth = h_dirac_output_synthesis_state->proto_power_smooth;
1379 :
1380 14112062 : for ( k = 0; k < num_protos_dir; k++ )
1381 : {
1382 506344493 : for ( l = 0; l < num_freq_bands; l++ )
1383 : {
1384 495830840 : g1 = alpha[l];
1385 495830840 : g2 = ( 1.f - g1 );
1386 495830840 : *p_power_smooth_prev = EPSILON + g2 * ( *p_power_smooth_prev );
1387 495830840 : *( p_power_smooth_prev ) += g1 * ( *p_power_smooth );
1388 495830840 : *( p_power_smooth++ ) = 1.f / ( *( p_power_smooth_prev++ ) );
1389 : }
1390 : }
1391 :
1392 : /*Direct gains and diffuse gains on number of output channels*/
1393 3598409 : p_power_diff_smooth_prev = h_dirac_output_synthesis_state->proto_power_diff_smooth_prev;
1394 3598409 : p_power_smooth_diff = h_dirac_output_synthesis_state->proto_power_diff_smooth;
1395 :
1396 3598409 : p_gains_diff = gains_diff;
1397 3598409 : p_gains_dir = gains_dir;
1398 :
1399 3598409 : p_cy_auto_dir_smooth = h_dirac_output_synthesis_state->cy_auto_dir_smooth;
1400 3598409 : p_cy_auto_dir_smooth_prev = h_dirac_output_synthesis_state->cy_auto_dir_smooth_prev;
1401 3598409 : p_cy_cross_dir_smooth = h_dirac_output_synthesis_state->cy_cross_dir_smooth;
1402 3598409 : p_cy_cross_dir_smooth_prev = h_dirac_output_synthesis_state->cy_cross_dir_smooth_prev;
1403 :
1404 3598409 : p_cy_auto_diff_smooth = h_dirac_output_synthesis_state->cy_auto_diff_smooth;
1405 3598409 : p_cy_auto_diff_smooth_prev = h_dirac_output_synthesis_state->cy_auto_diff_smooth_prev;
1406 31165412 : for ( k = 0; k < nchan_out_woLFE; k++ )
1407 : {
1408 27567003 : p_power_smooth = h_dirac_output_synthesis_state->proto_power_smooth + proto_direct_index[k] * num_freq_bands;
1409 378394713 : for ( l = 0; l < h_dirac_output_synthesis_params->max_band_decorr; l++ )
1410 : {
1411 : /*Direct*/
1412 350827710 : g1 = alpha[l];
1413 350827710 : g2 = 1.f - g1;
1414 350827710 : *( p_cy_auto_dir_smooth_prev ) = g1 * ( *( p_cy_auto_dir_smooth++ ) ) + g2 * ( *( p_cy_auto_dir_smooth_prev ) );
1415 350827710 : *( p_cy_cross_dir_smooth_prev ) = g1 * ( *( p_cy_cross_dir_smooth++ ) ) + g2 * ( *( p_cy_cross_dir_smooth_prev ) );
1416 :
1417 350827710 : *( p_gains_dir ) = sqrtf( *( p_power_smooth++ ) * ( *( p_cy_auto_dir_smooth_prev++ ) ) );
1418 :
1419 350827710 : if ( *( p_gains_dir ) < 0.f )
1420 : {
1421 0 : *( p_gains_dir ) = 0.f;
1422 : }
1423 350827710 : else if ( *( p_gains_dir ) > DIRAC_GAIN_LIMIT )
1424 : {
1425 2823863 : *( p_gains_dir ) = DIRAC_GAIN_LIMIT;
1426 : }
1427 :
1428 350827710 : if ( *( p_cy_cross_dir_smooth_prev++ ) < 0 )
1429 : {
1430 47652953 : *( p_gains_dir ) *= -1.f;
1431 : }
1432 350827710 : p_gains_dir++;
1433 :
1434 : /*diffuse*/
1435 350827710 : *p_power_diff_smooth_prev = g1 * ( *p_power_smooth_diff++ ) + g2 * ( *p_power_diff_smooth_prev ) + EPSILON;
1436 350827710 : *( p_cy_auto_diff_smooth_prev ) = g1 * ( *( p_cy_auto_diff_smooth++ ) ) + g2 * ( *( p_cy_auto_diff_smooth_prev ) );
1437 :
1438 350827710 : *( p_gains_diff ) = sqrtf( *( p_cy_auto_diff_smooth_prev++ ) / ( *( p_power_diff_smooth_prev++ ) ) );
1439 :
1440 350827710 : if ( *( p_gains_diff ) < 0.f )
1441 : {
1442 0 : *( p_gains_diff ) = 0.f;
1443 : }
1444 350827710 : else if ( *( p_gains_diff ) > DIRAC_GAIN_LIMIT )
1445 : {
1446 11726815 : *( p_gains_diff ) = DIRAC_GAIN_LIMIT;
1447 : }
1448 350827710 : p_gains_diff++;
1449 : }
1450 :
1451 : /*Only direct prototype*/
1452 951069713 : for ( ; l < num_freq_bands; l++ )
1453 : {
1454 : /*Direct*/
1455 923502710 : g1 = alpha[l];
1456 923502710 : g2 = 1.f - g1;
1457 923502710 : *( p_cy_auto_dir_smooth_prev ) = g1 * ( *( p_cy_auto_dir_smooth++ ) ) + g2 * ( *( p_cy_auto_dir_smooth_prev ) );
1458 923502710 : *( p_cy_cross_dir_smooth_prev ) = g1 * ( *( p_cy_cross_dir_smooth++ ) ) + g2 * ( *( p_cy_cross_dir_smooth_prev ) );
1459 :
1460 923502710 : *( p_gains_dir ) = sqrtf( *( p_power_smooth ) * ( *( p_cy_auto_dir_smooth_prev++ ) ) );
1461 :
1462 923502710 : if ( *( p_gains_dir ) < 0.f )
1463 : {
1464 0 : *( p_gains_dir ) = 0.f;
1465 : }
1466 923502710 : else if ( *( p_gains_dir ) > DIRAC_GAIN_LIMIT )
1467 : {
1468 5095825 : *( p_gains_dir ) = DIRAC_GAIN_LIMIT;
1469 : }
1470 :
1471 923502710 : if ( *( p_cy_cross_dir_smooth_prev++ ) < 0 )
1472 : {
1473 94634730 : *( p_gains_dir ) *= -1.f;
1474 : }
1475 923502710 : p_gains_dir++;
1476 :
1477 : /*diffuse*/
1478 923502710 : *( p_cy_auto_diff_smooth_prev ) = g1 * ( *( p_cy_auto_diff_smooth++ ) ) + g2 * ( *( p_cy_auto_diff_smooth_prev ) );
1479 923502710 : *( p_gains_diff ) = sqrtf( *( p_power_smooth++ ) * ( *( p_cy_auto_diff_smooth_prev++ ) ) );
1480 923502710 : if ( *( p_gains_diff ) < 0.f )
1481 : {
1482 0 : *( p_gains_diff ) = 0.f;
1483 : }
1484 923502710 : else if ( *( p_gains_diff ) > DIRAC_GAIN_LIMIT )
1485 : {
1486 5348999 : *( p_gains_diff ) = DIRAC_GAIN_LIMIT;
1487 : }
1488 923502710 : p_gains_diff++;
1489 : }
1490 : }
1491 :
1492 : /*-----------------------------------------------------------------*
1493 : * gain interpolation and output streams
1494 : *-----------------------------------------------------------------*/
1495 :
1496 17877038 : for ( buf_idx = 0; buf_idx < nbslots; ++buf_idx )
1497 : {
1498 14278629 : g1 = h_dirac_output_synthesis_params->interpolator[buf_idx];
1499 14278629 : g2 = 1.f - g1;
1500 :
1501 : /*Direct stream*/
1502 14278629 : p_gain_1 = gains_dir;
1503 14278629 : p_gain_2 = h_dirac_output_synthesis_state->gains_dir_prev;
1504 124050611 : for ( k = 0; k < nchan_out_woLFE; k++ )
1505 : {
1506 109771982 : p_power_smooth = h_dirac_output_synthesis_state->proto_direct_buffer_f + buf_idx * 2 * num_freq_bands * num_protos_dir + proto_direct_index[k] * 2 * num_freq_bands;
1507 5179384802 : for ( l = 0; l < num_freq_bands; l++ )
1508 : {
1509 5069612820 : g = g1 * ( *( p_gain_1++ ) ) + g2 * ( *( p_gain_2++ ) );
1510 5069612820 : RealBuffer[k][buf_idx][l] = g * ( *( p_power_smooth++ ) );
1511 5069612820 : ImagBuffer[k][buf_idx][l] = g * ( *( p_power_smooth++ ) );
1512 : }
1513 : }
1514 :
1515 : /*Diffuse stream*/
1516 14278629 : if ( h_dirac_output_synthesis_params->max_band_decorr != 0 )
1517 : {
1518 11724672 : p_power_smooth_diff = h_dirac_output_synthesis_state->proto_diffuse_buffer_f + buf_idx * 2 * h_dirac_output_synthesis_params->max_band_decorr * nchan_out_woLFE;
1519 : }
1520 14278629 : p_gain_1 = gains_diff;
1521 14278629 : p_gain_2 = h_dirac_output_synthesis_state->gains_diff_prev;
1522 124050611 : for ( k = 0; k < nchan_out_woLFE; k++ )
1523 : {
1524 1505992517 : for ( l = 0; l < h_dirac_output_synthesis_params->max_band_decorr; l++ )
1525 : {
1526 1396220535 : g = g1 * ( *( p_gain_1++ ) ) + g2 * ( *( p_gain_2++ ) );
1527 1396220535 : RealBuffer[k][buf_idx][l] += g * ( *( p_power_smooth_diff++ ) );
1528 1396220535 : ImagBuffer[k][buf_idx][l] += g * ( *( p_power_smooth_diff++ ) );
1529 : }
1530 :
1531 : /*Direct proto*/
1532 109771982 : p_power_smooth = h_dirac_output_synthesis_state->proto_direct_buffer_f + buf_idx * 2 * num_freq_bands * num_protos_dir + proto_direct_index[k] * 2 * num_freq_bands + 2 * h_dirac_output_synthesis_params->max_band_decorr;
1533 3783164267 : for ( ; l < num_freq_bands; l++ )
1534 : {
1535 3673392285 : g = g1 * ( *( p_gain_1++ ) ) + g2 * ( *( p_gain_2++ ) );
1536 3673392285 : RealBuffer[k][buf_idx][l] += g * ( *( p_power_smooth++ ) );
1537 3673392285 : ImagBuffer[k][buf_idx][l] += g * ( *( p_power_smooth++ ) );
1538 : }
1539 : }
1540 : }
1541 :
1542 : /*-----------------------------------------------------------------*
1543 : * update buffers
1544 : *-----------------------------------------------------------------*/
1545 :
1546 : /* store estimates for next synthesis block */
1547 3598409 : mvr2r( gains_dir, h_dirac_output_synthesis_state->gains_dir_prev, num_freq_bands * nchan_out_woLFE );
1548 3598409 : mvr2r( gains_diff, h_dirac_output_synthesis_state->gains_diff_prev, num_freq_bands * nchan_out_woLFE );
1549 :
1550 : /* reset values */
1551 3598409 : set_zero( h_dirac_output_synthesis_state->proto_power_smooth, num_freq_bands * num_protos_dir );
1552 :
1553 3598409 : if ( h_dirac_output_synthesis_state->proto_power_diff_smooth != NULL )
1554 : {
1555 3598409 : set_zero( h_dirac_output_synthesis_state->proto_power_diff_smooth, h_dirac_output_synthesis_params->max_band_decorr * nchan_out_woLFE );
1556 : }
1557 :
1558 3598409 : set_zero( h_dirac_output_synthesis_state->cy_auto_dir_smooth, num_freq_bands * nchan_out_woLFE );
1559 3598409 : set_zero( h_dirac_output_synthesis_state->cy_cross_dir_smooth, num_freq_bands * nchan_out_woLFE );
1560 3598409 : set_zero( h_dirac_output_synthesis_state->cy_auto_diff_smooth, num_freq_bands * nchan_out_woLFE );
1561 :
1562 3598409 : pop_wmops();
1563 :
1564 3598409 : return;
1565 : }
1566 :
1567 :
1568 : /*-------------------------------------------------------------------------
1569 : * ivas_dirac_dec_compute_directional_responses()
1570 : *
1571 : *
1572 : *------------------------------------------------------------------------*/
1573 :
1574 38666709 : void ivas_dirac_dec_compute_directional_responses(
1575 : SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common spatial renderer data handle */
1576 : DIRAC_REND_HANDLE hDirACRend, /* i/o: DirAC renderer handle */
1577 : const VBAP_HANDLE hVBAPdata, /* i : VBAP structure */
1578 : const int16_t *masa_band_mapping, /* i : Band mapping for MASA, NULL assumes not using MASA in any form */
1579 : MASA_ISM_DATA_HANDLE hMasaIsm, /* i : MASA_ISM data structure */
1580 : const int16_t *azimuth,
1581 : const int16_t *elevation,
1582 : const int16_t md_idx,
1583 : const float *surCohRatio,
1584 : const int16_t hodirac_flag /* i : flag to indicate HO-DirAC mode */
1585 : )
1586 : {
1587 : int16_t k, l;
1588 : int16_t num_channels_dir;
1589 : float direct_response_hoa[MAX_OUTPUT_CHANNELS]; /* number of output channels (HOA 3rd order) -> 16 */
1590 : float direct_response_ls[MAX_OUTPUT_CHANNELS];
1591 : float direct_response_square[MAX_OUTPUT_CHANNELS];
1592 : float *direct_response;
1593 : const int16_t *azimuth2, *elevation2;
1594 : float direct_response_dir2[MAX_OUTPUT_CHANNELS];
1595 : float directRatio[MASA_MAXIMUM_DIRECTIONS];
1596 : float totalDirect;
1597 : int16_t codingBand;
1598 : int16_t dipole_freq_range[2];
1599 : MASA_TRANSPORT_SIGNAL_TYPE transport_signal_type;
1600 :
1601 38666709 : azimuth2 = NULL;
1602 38666709 : elevation2 = NULL;
1603 38666709 : transport_signal_type = MASA_STEREO_NOT_DEFINED;
1604 :
1605 38666709 : if ( hDirACRend->masa_stereo_type_detect != NULL )
1606 : {
1607 379138 : dipole_freq_range[0] = hDirACRend->masa_stereo_type_detect->dipole_freq_range[0];
1608 379138 : dipole_freq_range[1] = hDirACRend->masa_stereo_type_detect->dipole_freq_range[1];
1609 379138 : transport_signal_type = hDirACRend->masa_stereo_type_detect->masa_stereo_type;
1610 : }
1611 :
1612 38666709 : num_channels_dir = hDirACRend->num_outputs_dir;
1613 38666709 : if ( hSpatParamRendCom->numParametricDirections == 2 )
1614 : {
1615 8323617 : azimuth2 = hSpatParamRendCom->azimuth2[md_idx];
1616 8323617 : elevation2 = hSpatParamRendCom->elevation2[md_idx];
1617 : }
1618 :
1619 38666709 : codingBand = -1;
1620 :
1621 38666709 : assert( num_channels_dir <= MAX_OUTPUT_CHANNELS && "Number of channels is too high" );
1622 :
1623 1795792869 : for ( k = 0; k < hSpatParamRendCom->num_freq_bands; ++k )
1624 : {
1625 1757126160 : if ( masa_band_mapping != NULL && k == MASA_band_grouping_24[masa_band_mapping[codingBand + 1]] )
1626 : {
1627 29042930 : codingBand++;
1628 : }
1629 :
1630 1757126160 : if ( masa_band_mapping != NULL && k > MASA_band_grouping_24[masa_band_mapping[codingBand]] &&
1631 126219470 : k < MASA_band_grouping_24[masa_band_mapping[codingBand + 1]] &&
1632 126219470 : k != hDirACRend->h_output_synthesis_psd_params.max_band_decorr )
1633 : {
1634 : /* 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 */
1635 125709367 : if ( hDirACRend->synthesisConf != DIRAC_SYNTHESIS_GAIN_SHD )
1636 : {
1637 117894698 : mvr2r_inc( &hDirACRend->h_output_synthesis_psd_state.direct_responses_square[k - 1],
1638 117894698 : hSpatParamRendCom->num_freq_bands, &hDirACRend->h_output_synthesis_psd_state.direct_responses_square[k],
1639 117894698 : hSpatParamRendCom->num_freq_bands, num_channels_dir );
1640 : }
1641 125709367 : mvr2r_inc( &hDirACRend->h_output_synthesis_psd_state.direct_responses[k - 1],
1642 125709367 : hSpatParamRendCom->num_freq_bands,
1643 125709367 : &hDirACRend->h_output_synthesis_psd_state.direct_responses[k],
1644 125709367 : hSpatParamRendCom->num_freq_bands, num_channels_dir );
1645 : }
1646 : else
1647 : {
1648 : /* HOA3 PANNING */
1649 1631416793 : if ( hDirACRend->panningConf == DIRAC_PANNING_HOA3 )
1650 : {
1651 1522384043 : set_f( direct_response_hoa, 1.0f, MAX_OUTPUT_CHANNELS );
1652 1522384043 : set_f( direct_response_dir2, 1.0f, MAX_OUTPUT_CHANNELS );
1653 :
1654 1522384043 : ivas_dirac_dec_get_response( azimuth[k], elevation[k], direct_response_hoa, hDirACRend->hOutSetup.ambisonics_order );
1655 :
1656 1522384043 : if ( hodirac_flag )
1657 : {
1658 406990800 : ivas_dirac_dec_get_response( azimuth2[k], elevation2[k], direct_response_dir2, hDirACRend->hOutSetup.ambisonics_order );
1659 : }
1660 :
1661 1522384043 : if ( masa_band_mapping == NULL && hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD )
1662 : {
1663 1511534480 : mvr2r_inc( direct_response_hoa, 1, &hDirACRend->h_output_synthesis_psd_state.direct_responses[k], hSpatParamRendCom->num_freq_bands, num_channels_dir );
1664 :
1665 1511534480 : if ( hodirac_flag )
1666 : {
1667 406990800 : mvr2r_inc( direct_response_dir2, 1, &hDirACRend->h_output_synthesis_psd_state.direct_responses[k + hSpatParamRendCom->num_freq_bands * num_channels_dir], hSpatParamRendCom->num_freq_bands, num_channels_dir );
1668 : }
1669 : }
1670 10849563 : else if ( ( ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) && ( masa_band_mapping != NULL ) ) ||
1671 8964692 : hDirACRend->synthesisConf == DIRAC_SYNTHESIS_PSD_SHD || hDirACRend->synthesisConf == DIRAC_SYNTHESIS_MONO )
1672 : {
1673 : /* Synthesize the first direction */
1674 10849563 : spreadCoherencePanningHoa( azimuth[k], elevation[k], hSpatParamRendCom->spreadCoherence[md_idx][k], direct_response_hoa, num_channels_dir, hDirACRend->hOutSetup.ambisonics_order );
1675 :
1676 : /* Synthesize the second direction and combine the gains */
1677 10849563 : if ( hSpatParamRendCom->numParametricDirections == 2 )
1678 : {
1679 1167645 : spreadCoherencePanningHoa( azimuth2[k], elevation2[k], hSpatParamRendCom->spreadCoherence2[md_idx][k], direct_response_dir2, num_channels_dir, hDirACRend->hOutSetup.ambisonics_order );
1680 : /* Combine gains from the two directions */
1681 1167645 : totalDirect = hSpatParamRendCom->energy_ratio1[md_idx][k] + hSpatParamRendCom->energy_ratio2[md_idx][k] + EPSILON;
1682 1167645 : directRatio[0] = hSpatParamRendCom->energy_ratio1[md_idx][k] / totalDirect;
1683 1167645 : directRatio[1] = hSpatParamRendCom->energy_ratio2[md_idx][k] / totalDirect;
1684 9807845 : for ( l = 0; l < num_channels_dir; l++ )
1685 : {
1686 8640200 : direct_response_hoa[l] *= directRatio[0];
1687 8640200 : direct_response_hoa[l] += directRatio[1] * direct_response_dir2[l];
1688 : }
1689 : }
1690 :
1691 10849563 : if ( hSpatParamRendCom->numIsmDirections > 0 )
1692 : {
1693 : int16_t dir;
1694 : float direct_response_temp[MAX_OUTPUT_CHANNELS];
1695 : float direct_response_ism[MAX_OUTPUT_CHANNELS];
1696 : float masaDirect;
1697 : float ismDirect;
1698 :
1699 541273 : set_zero( direct_response_ism, num_channels_dir );
1700 :
1701 2563805 : for ( dir = 0; dir < hSpatParamRendCom->numIsmDirections; dir++ )
1702 : {
1703 2022532 : if ( hMasaIsm->ism_dir_is_edited[dir] )
1704 : {
1705 0 : ivas_dirac_dec_get_response( hMasaIsm->azimuth_ism_edited[dir], hMasaIsm->elevation_ism_edited[dir], direct_response_temp, hDirACRend->hOutSetup.ambisonics_order );
1706 : }
1707 : else
1708 : {
1709 2022532 : ivas_dirac_dec_get_response( hMasaIsm->azimuth_ism[dir][md_idx], hMasaIsm->elevation_ism[dir][md_idx], direct_response_temp, hDirACRend->hOutSetup.ambisonics_order );
1710 : }
1711 :
1712 21092276 : for ( l = 0; l < num_channels_dir; l++ )
1713 : {
1714 19069744 : direct_response_ism[l] += direct_response_temp[l] * hMasaIsm->energy_ratio_ism[dir][md_idx][k];
1715 : }
1716 : }
1717 :
1718 541273 : masaDirect = hSpatParamRendCom->energy_ratio1[md_idx][k] + EPSILON;
1719 541273 : if ( hSpatParamRendCom->numParametricDirections == 2 )
1720 : {
1721 28981 : masaDirect += hSpatParamRendCom->energy_ratio2[md_idx][k];
1722 : }
1723 :
1724 541273 : ismDirect = hMasaIsm->energy_ratio_ism[0][md_idx][k];
1725 2022532 : for ( dir = 1; dir < hSpatParamRendCom->numIsmDirections; dir++ )
1726 : {
1727 1481259 : ismDirect += hMasaIsm->energy_ratio_ism[dir][md_idx][k];
1728 : }
1729 :
1730 541273 : totalDirect = masaDirect + ismDirect;
1731 541273 : directRatio[0] = masaDirect / totalDirect;
1732 541273 : directRatio[1] = ismDirect / totalDirect;
1733 5653229 : for ( l = 0; l < num_channels_dir; l++ )
1734 : {
1735 5111956 : direct_response_hoa[l] *= directRatio[0];
1736 5111956 : direct_response_hoa[l] += directRatio[1] * direct_response_ism[l];
1737 : }
1738 : }
1739 :
1740 : /* Synthesize surrounding coherence */
1741 10849563 : if ( surCohRatio != NULL && surCohRatio[k] > 0.f )
1742 : {
1743 60024759 : for ( l = 1; l < num_channels_dir; l++ )
1744 : {
1745 52753895 : direct_response_hoa[l] *= sqrtf( 1.0f - surCohRatio[k] );
1746 : }
1747 : }
1748 :
1749 : /* Set computed gains */
1750 10849563 : direct_response = direct_response_hoa;
1751 10849563 : if ( hDirACRend->synthesisConf != DIRAC_SYNTHESIS_GAIN_SHD )
1752 : {
1753 8964692 : v_mult( direct_response, direct_response, direct_response_square, num_channels_dir );
1754 8964692 : mvr2r_inc( direct_response_square, 1, &hDirACRend->h_output_synthesis_psd_state.direct_responses_square[k], hSpatParamRendCom->num_freq_bands, num_channels_dir );
1755 :
1756 8964692 : if ( transport_signal_type == MASA_STEREO_SPACED_MICS )
1757 : {
1758 1100412 : direct_response[0] = 1.0f;
1759 1100412 : if ( k >= dipole_freq_range[0] && k < dipole_freq_range[1] )
1760 : {
1761 146097 : direct_response[1] = 1.0f;
1762 : }
1763 : }
1764 : else
1765 : {
1766 7864280 : set_f( direct_response, 1.0f, hDirACRend->num_protos_ambi );
1767 : }
1768 : }
1769 :
1770 10849563 : mvr2r_inc( direct_response, 1, &hDirACRend->h_output_synthesis_psd_state.direct_responses[k], hSpatParamRendCom->num_freq_bands, num_channels_dir );
1771 : }
1772 : else
1773 : {
1774 0 : assert( 0 && "Not supported synthesis method!" );
1775 : }
1776 : }
1777 109032750 : else if ( hDirACRend->panningConf == DIRAC_PANNING_VBAP ) /*VBAP*/
1778 : {
1779 : /* Synthesize the first direction */
1780 109032750 : spreadCoherencePanningVbap( azimuth[k], elevation[k], hSpatParamRendCom->spreadCoherence[md_idx][k], direct_response_ls, num_channels_dir, hVBAPdata );
1781 109032750 : normalizePanningGains( direct_response_ls, num_channels_dir );
1782 :
1783 : /* Synthesize the second direction and combine the gains */
1784 109032750 : if ( hSpatParamRendCom->numParametricDirections == 2 )
1785 : {
1786 1898527 : spreadCoherencePanningVbap( azimuth2[k], elevation2[k], hSpatParamRendCom->spreadCoherence2[md_idx][k], direct_response_dir2, num_channels_dir, hVBAPdata );
1787 1898527 : normalizePanningGains( direct_response_dir2, num_channels_dir );
1788 :
1789 : /* Combine gains from the two directions */
1790 1898527 : totalDirect = hSpatParamRendCom->energy_ratio1[md_idx][k] + hSpatParamRendCom->energy_ratio2[md_idx][k] + EPSILON;
1791 1898527 : directRatio[0] = hSpatParamRendCom->energy_ratio1[md_idx][k] / totalDirect;
1792 1898527 : directRatio[1] = hSpatParamRendCom->energy_ratio2[md_idx][k] / totalDirect;
1793 16871002 : for ( l = 0; l < num_channels_dir; l++ )
1794 : {
1795 14972475 : direct_response_ls[l] *= directRatio[0];
1796 14972475 : direct_response_ls[l] += directRatio[1] * direct_response_dir2[l];
1797 : }
1798 1898527 : normalizePanningGains( direct_response_ls, num_channels_dir );
1799 : }
1800 :
1801 109032750 : if ( hSpatParamRendCom->numIsmDirections > 0 )
1802 : {
1803 : int16_t dir;
1804 : float direct_response_temp[MAX_OUTPUT_CHANNELS];
1805 : float direct_response_ism[MAX_OUTPUT_CHANNELS];
1806 : float masaDirect;
1807 : float ismDirect;
1808 :
1809 706346 : set_zero( direct_response_ism, num_channels_dir );
1810 :
1811 2890574 : for ( dir = 0; dir < hSpatParamRendCom->numIsmDirections; dir++ )
1812 : {
1813 2184228 : if ( hMasaIsm->ism_dir_is_edited[dir] )
1814 : {
1815 0 : vbap_determine_gains( hVBAPdata, direct_response_temp, hMasaIsm->azimuth_ism_edited[dir], hMasaIsm->elevation_ism_edited[dir], 1 );
1816 : }
1817 : else
1818 : {
1819 2184228 : vbap_determine_gains( hVBAPdata, direct_response_temp, hMasaIsm->azimuth_ism[dir][md_idx], hMasaIsm->elevation_ism[dir][md_idx], 1 );
1820 : }
1821 :
1822 19894800 : for ( l = 0; l < num_channels_dir; l++ )
1823 : {
1824 17710572 : direct_response_ism[l] += direct_response_temp[l] * hMasaIsm->energy_ratio_ism[dir][md_idx][k];
1825 : }
1826 : }
1827 706346 : normalizePanningGains( direct_response_ism, num_channels_dir );
1828 :
1829 706346 : masaDirect = hSpatParamRendCom->energy_ratio1[md_idx][k] + EPSILON;
1830 706346 : if ( hSpatParamRendCom->numParametricDirections == 2 )
1831 : {
1832 120884 : masaDirect += hSpatParamRendCom->energy_ratio2[md_idx][k];
1833 : }
1834 :
1835 706346 : ismDirect = hMasaIsm->energy_ratio_ism[0][md_idx][k];
1836 2184228 : for ( dir = 1; dir < hSpatParamRendCom->numIsmDirections; dir++ )
1837 : {
1838 1477882 : ismDirect += hMasaIsm->energy_ratio_ism[dir][md_idx][k];
1839 : }
1840 :
1841 706346 : totalDirect = masaDirect + ismDirect;
1842 706346 : directRatio[0] = masaDirect / totalDirect;
1843 706346 : directRatio[1] = ismDirect / totalDirect;
1844 6426080 : for ( l = 0; l < num_channels_dir; l++ )
1845 : {
1846 5719734 : direct_response_ls[l] *= directRatio[0];
1847 5719734 : direct_response_ls[l] += directRatio[1] * direct_response_ism[l];
1848 : }
1849 706346 : normalizePanningGains( direct_response_ls, num_channels_dir );
1850 : }
1851 :
1852 : /* Synthesize surrounding coherence */
1853 109032750 : if ( surCohRatio != NULL && surCohRatio[k] > 0.f )
1854 : {
1855 : int16_t num_channels_surrCoh;
1856 :
1857 12172153 : num_channels_surrCoh = num_channels_dir;
1858 12172153 : num_channels_surrCoh -= hDirACRend->num_ele_spk_no_diffuse_rendering;
1859 :
1860 105382124 : for ( l = 0; l < num_channels_dir; l++ )
1861 : {
1862 93209971 : direct_response_ls[l] *= sqrtf( 1.0f - surCohRatio[k] );
1863 93209971 : if ( hDirACRend->diffuse_response_function[l] > 0.f )
1864 : {
1865 92926691 : direct_response_ls[l] += sqrtf( surCohRatio[k] / (float) num_channels_surrCoh );
1866 : }
1867 : }
1868 : }
1869 :
1870 109032750 : normalizePanningGains( direct_response_ls, num_channels_dir );
1871 :
1872 : /* Set computed gains */
1873 109032750 : direct_response = direct_response_ls;
1874 109032750 : v_mult( direct_response, direct_response, direct_response_square, num_channels_dir );
1875 109032750 : mvr2r_inc( direct_response_square, 1, &hDirACRend->h_output_synthesis_psd_state.direct_responses_square[k], hSpatParamRendCom->num_freq_bands, num_channels_dir );
1876 109032750 : mvr2r_inc( direct_response, 1, &hDirACRend->h_output_synthesis_psd_state.direct_responses[k], hSpatParamRendCom->num_freq_bands, num_channels_dir );
1877 : }
1878 : else
1879 : {
1880 0 : assert( 0 && "Not supported panning method!" );
1881 : }
1882 : }
1883 : }
1884 :
1885 38666709 : return;
1886 : }
1887 :
1888 :
1889 : /*-------------------------------------------------------------------------
1890 : * ivas_dirac_dec_compute_gain_factors()
1891 : *
1892 : *
1893 : *------------------------------------------------------------------------*/
1894 :
1895 27141400 : void ivas_dirac_dec_compute_gain_factors(
1896 : const int16_t num_freq_bands,
1897 : const float *diffuseness,
1898 : const int16_t max_band_decorr,
1899 : float *direct_gain_factor,
1900 : float *diffuse_gain_factor )
1901 : {
1902 : int16_t i;
1903 :
1904 166077743 : for ( i = 0; i < max_band_decorr; i++ )
1905 : {
1906 138936343 : direct_gain_factor[i] = sqrtf( 1.f - diffuseness[i] );
1907 138936343 : diffuse_gain_factor[i] = sqrtf( diffuseness[i] );
1908 : }
1909 1083846437 : for ( ; i < num_freq_bands; i++ )
1910 : {
1911 1056705037 : direct_gain_factor[i] = sqrtf( 1.f - diffuseness[i] );
1912 1056705037 : diffuse_gain_factor[i] = sqrtf( diffuseness[i] );
1913 : }
1914 :
1915 27141400 : return;
1916 : }
1917 :
1918 :
1919 : /*-------------------------------------------------------------------------
1920 : * ivas_dirac_dec_compute_power_factors()
1921 : *
1922 : *
1923 : *------------------------------------------------------------------------*/
1924 :
1925 5043725 : void ivas_dirac_dec_compute_power_factors(
1926 : const int16_t num_freq_bands,
1927 : const float *diffuseness,
1928 : const int16_t max_band_decorr,
1929 : float *direct_power_factor,
1930 : float *diffuse_power_factor )
1931 : {
1932 5043725 : v_multc( diffuseness, -1.0f, direct_power_factor, num_freq_bands );
1933 :
1934 5043725 : v_addc( direct_power_factor, 1.0f, direct_power_factor, num_freq_bands );
1935 :
1936 5043725 : mvr2r( diffuseness, diffuse_power_factor, num_freq_bands );
1937 :
1938 5043725 : v_mult( &direct_power_factor[max_band_decorr], &direct_power_factor[max_band_decorr], &direct_power_factor[max_band_decorr], num_freq_bands - max_band_decorr );
1939 :
1940 5043725 : v_mult( &diffuse_power_factor[max_band_decorr], &diffuse_power_factor[max_band_decorr], &diffuse_power_factor[max_band_decorr], num_freq_bands - max_band_decorr );
1941 :
1942 5043725 : return;
1943 : }
1944 :
1945 :
1946 : /*-------------------------------------------------------------------------
1947 : * ivas_lfe_synth_with_filters()
1948 : *
1949 : *
1950 : *------------------------------------------------------------------------*/
1951 :
1952 20257 : void ivas_lfe_synth_with_filters(
1953 : MCMASA_LFE_SYNTH_DATA_HANDLE hMasaLfeSynth, /* i/o: LFE synthesis structure for McMASA */
1954 : float *data_f[], /* o : output signals */
1955 : const int16_t output_frame, /* i : output frame length per channel */
1956 : const int16_t separateChannelIndex, /* i : separate channel index */
1957 : const int16_t lfeChannelIndex /* i : LFE channel index */
1958 : )
1959 : {
1960 : float lowpassCoef;
1961 : int16_t i, j;
1962 : float lowPassSignal[L_FRAME48k];
1963 : float highPassSignal[L_FRAME48k];
1964 : int16_t slot_index;
1965 : int16_t subframe_index;
1966 : int16_t slotSize;
1967 : float transportEne, targetEneLfe, targetEneTrans;
1968 : int16_t mrange[2];
1969 : float lfeGain;
1970 : float transportGain;
1971 : int16_t delay;
1972 :
1973 : /* Delay the separated channel to sync the LFE synthesis with the DirAC rendering */
1974 20257 : delay = hMasaLfeSynth->delayBuffer_syncDirAC_size;
1975 20257 : delay_signal( data_f[separateChannelIndex], output_frame, hMasaLfeSynth->delayBuffer_syncDirAC, delay );
1976 :
1977 : /* Filterbank for dividing the separated channel to LFE frequencies and higher frequencies */
1978 20257 : lowpassCoef = 1.0f / ( (float) hMasaLfeSynth->ringBufferSize );
1979 16289377 : for ( i = 0; i < output_frame; i++ )
1980 : {
1981 16269120 : hMasaLfeSynth->lowpassSum += lowpassCoef * data_f[separateChannelIndex][i] - lowpassCoef * hMasaLfeSynth->lfeSynthRingBuffer[hMasaLfeSynth->ringBufferLoPointer];
1982 16269120 : lowPassSignal[i] = hMasaLfeSynth->lowpassSum;
1983 16269120 : highPassSignal[i] = hMasaLfeSynth->lfeSynthRingBuffer[hMasaLfeSynth->ringBufferHiPointer] - lowPassSignal[i];
1984 16269120 : hMasaLfeSynth->lfeSynthRingBuffer[hMasaLfeSynth->ringBufferLoPointer] = data_f[separateChannelIndex][i];
1985 :
1986 16269120 : hMasaLfeSynth->ringBufferLoPointer--;
1987 16269120 : if ( hMasaLfeSynth->ringBufferLoPointer < 0 )
1988 : {
1989 81028 : hMasaLfeSynth->ringBufferLoPointer = hMasaLfeSynth->ringBufferSize - 1;
1990 : }
1991 :
1992 16269120 : hMasaLfeSynth->ringBufferHiPointer--;
1993 16269120 : if ( hMasaLfeSynth->ringBufferHiPointer < 0 )
1994 : {
1995 81028 : hMasaLfeSynth->ringBufferHiPointer = hMasaLfeSynth->ringBufferSize - 1;
1996 : }
1997 : }
1998 :
1999 : /* Synthesize the LFE signal */
2000 20257 : slotSize = output_frame / CLDFB_NO_COL_MAX;
2001 344369 : for ( slot_index = 0; slot_index < CLDFB_NO_COL_MAX; slot_index++ )
2002 : {
2003 324112 : subframe_index = slot_index / 4;
2004 :
2005 324112 : mrange[0] = slot_index * slotSize;
2006 324112 : mrange[1] = ( slot_index + 1 ) * slotSize;
2007 :
2008 324112 : transportEne = 0.0f;
2009 16593232 : for ( i = mrange[0]; i < mrange[1]; i++ )
2010 : {
2011 16269120 : transportEne += lowPassSignal[i] * lowPassSignal[i];
2012 : }
2013 :
2014 324112 : targetEneLfe = transportEne * hMasaLfeSynth->lfeToTotalEnergyRatio[subframe_index];
2015 324112 : targetEneTrans = transportEne * max( ( 1.0f - hMasaLfeSynth->lfeToTotalEnergyRatio[subframe_index] ), 0.01f );
2016 :
2017 324112 : hMasaLfeSynth->transportEneSmooth *= MCMASA_LFE_SYNTH_ALPHA;
2018 324112 : hMasaLfeSynth->targetEneLfeSmooth *= MCMASA_LFE_SYNTH_ALPHA;
2019 324112 : hMasaLfeSynth->targetEneTransSmooth *= MCMASA_LFE_SYNTH_ALPHA;
2020 :
2021 324112 : hMasaLfeSynth->transportEneSmooth += transportEne;
2022 324112 : hMasaLfeSynth->targetEneLfeSmooth += targetEneLfe;
2023 324112 : hMasaLfeSynth->targetEneTransSmooth += targetEneTrans;
2024 :
2025 324112 : lfeGain = min( 1.0f, sqrtf( hMasaLfeSynth->targetEneLfeSmooth / ( EPSILON + hMasaLfeSynth->transportEneSmooth ) ) );
2026 324112 : transportGain = min( 1.0f, sqrtf( hMasaLfeSynth->targetEneTransSmooth / ( EPSILON + hMasaLfeSynth->transportEneSmooth ) ) );
2027 :
2028 16593232 : for ( i = mrange[0], j = 0; i < mrange[1]; i++, j++ )
2029 : {
2030 16269120 : data_f[separateChannelIndex][i] = ( transportGain * hMasaLfeSynth->interpolator[j] + hMasaLfeSynth->transportGainPrev * ( 1.0f - hMasaLfeSynth->interpolator[j] ) ) * lowPassSignal[i] + highPassSignal[i];
2031 16269120 : data_f[lfeChannelIndex][i] = ( lfeGain * hMasaLfeSynth->interpolator[j] + hMasaLfeSynth->lfeGainPrev * ( 1.0f - hMasaLfeSynth->interpolator[j] ) ) * lowPassSignal[i];
2032 : }
2033 :
2034 324112 : hMasaLfeSynth->lfeGainPrev = lfeGain;
2035 324112 : hMasaLfeSynth->transportGainPrev = transportGain;
2036 : }
2037 :
2038 : /* Lowpass filter for removing remaining mid and high frequencies from the LFE signal */
2039 20257 : lowpassCoef = 1.0f / ( (float) hMasaLfeSynth->ringBufferSize2 );
2040 16289377 : for ( i = 0; i < output_frame; i++ )
2041 : {
2042 16269120 : hMasaLfeSynth->lowpassSum2 += lowpassCoef * data_f[lfeChannelIndex][i] - lowpassCoef * hMasaLfeSynth->lfeSynthRingBuffer2[hMasaLfeSynth->ringBufferLoPointer2];
2043 16269120 : hMasaLfeSynth->lfeSynthRingBuffer2[hMasaLfeSynth->ringBufferLoPointer2] = data_f[lfeChannelIndex][i];
2044 :
2045 16269120 : hMasaLfeSynth->ringBufferLoPointer2--;
2046 16269120 : if ( hMasaLfeSynth->ringBufferLoPointer2 < 0 )
2047 : {
2048 162056 : hMasaLfeSynth->ringBufferLoPointer2 = hMasaLfeSynth->ringBufferSize2 - 1;
2049 : }
2050 :
2051 16269120 : data_f[lfeChannelIndex][i] = hMasaLfeSynth->lowpassSum2;
2052 : }
2053 :
2054 : /* Delay the separated channel to match the delay of the lowpass filter */
2055 20257 : delay = hMasaLfeSynth->delayBuffer_syncLp_size;
2056 20257 : delay_signal( data_f[separateChannelIndex], output_frame, hMasaLfeSynth->delayBuffer_syncLp, delay );
2057 :
2058 20257 : return;
2059 : }
2060 :
2061 :
2062 : /*-------------------------------------------------------------------------
2063 : * Local functions
2064 : *------------------------------------------------------------------------*/
2065 :
2066 1927088 : static void computeTargetPSDs_direct(
2067 : const int16_t num_channels,
2068 : const int16_t num_freq_bands,
2069 : const float *direct_power_factor,
2070 : const float *reference_power,
2071 : const float *direct_responses,
2072 : const float *direct_responses_square,
2073 : float *cy_auto_dir_smooth,
2074 : float *cy_cross_dir_smooth )
2075 : {
2076 : int16_t ch_idx, cur_idx;
2077 :
2078 : /* segment auxiliary buffer */
2079 : float direct_power[CLDFB_NO_CHANNELS_MAX]; /* size: num_freq_bands. */
2080 : float aux_buffer_res[CLDFB_NO_CHANNELS_MAX]; /* size: num_freq_bands. */
2081 :
2082 : /* estimate direct and diffuse power */
2083 1927088 : v_mult( direct_power_factor, reference_power, direct_power, num_freq_bands );
2084 :
2085 : /* compute target auto and cross PSDs of current frame (smoothed) */
2086 17990832 : for ( ch_idx = 0; ch_idx < num_channels; ++ch_idx )
2087 : {
2088 16063744 : cur_idx = ch_idx * num_freq_bands;
2089 :
2090 16063744 : v_mult( direct_power, &direct_responses_square[cur_idx], aux_buffer_res, num_freq_bands );
2091 16063744 : v_add( &cy_auto_dir_smooth[cur_idx], aux_buffer_res, &cy_auto_dir_smooth[cur_idx], num_freq_bands );
2092 :
2093 16063744 : v_mult( direct_power, &direct_responses[cur_idx], aux_buffer_res, num_freq_bands );
2094 16063744 : v_add( &cy_cross_dir_smooth[cur_idx], aux_buffer_res, &cy_cross_dir_smooth[cur_idx], num_freq_bands );
2095 : }
2096 :
2097 1927088 : return;
2098 : }
2099 :
2100 :
2101 3116637 : static void computeTargetPSDs_direct_subframe(
2102 : const int16_t num_channels,
2103 : const int16_t num_freq_bands,
2104 : const float *direct_power_factor,
2105 : const float *reference_power,
2106 : const float *direct_responses,
2107 : const float *direct_responses_square,
2108 : float *cy_auto_dir_smooth,
2109 : float *cy_cross_dir_smooth )
2110 : {
2111 : int16_t ch_idx, cur_idx;
2112 :
2113 : /* segment auxiliary buffer */
2114 : float direct_power[CLDFB_NO_CHANNELS_MAX]; /* size: num_freq_bands. */
2115 :
2116 : /* estimate direct and diffuse power */
2117 3116637 : v_mult( direct_power_factor, reference_power, direct_power, num_freq_bands );
2118 :
2119 : /* compute target auto and cross PSDs of current frame (smoothed) */
2120 26830257 : for ( ch_idx = 0; ch_idx < num_channels; ++ch_idx )
2121 : {
2122 23713620 : cur_idx = ch_idx * num_freq_bands;
2123 :
2124 23713620 : v_mult( direct_power, &direct_responses_square[cur_idx], &cy_auto_dir_smooth[cur_idx], num_freq_bands );
2125 23713620 : v_mult( direct_power, &direct_responses[cur_idx], &cy_cross_dir_smooth[cur_idx], num_freq_bands );
2126 : }
2127 :
2128 3116637 : return;
2129 : }
2130 :
2131 :
2132 1927088 : static void computeTargetPSDs_diffuse(
2133 : const int16_t num_channels,
2134 : const int16_t num_freq_bands,
2135 : const int16_t start_band,
2136 : const float *diffuse_power_factor,
2137 : const float *reference_power,
2138 : const float *diffuse_responses_square,
2139 : float *cy_auto_diff_smooth )
2140 : {
2141 : int16_t ch_idx, cur_idx;
2142 :
2143 : /* segment auxiliary buffer */
2144 : float diffuse_power[CLDFB_NO_CHANNELS_MAX]; /* size: num_freq_bands. */
2145 : float aux_buffer_res[CLDFB_NO_CHANNELS_MAX]; /* size: num_freq_bands. */
2146 :
2147 : /* estimate direct and diffuse power */
2148 1927088 : v_mult( diffuse_power_factor, reference_power, diffuse_power, num_freq_bands );
2149 :
2150 : /* compute target auto and cross PSDs of current frame (smoothed) */
2151 17990832 : for ( ch_idx = 0; ch_idx < num_channels; ++ch_idx )
2152 : {
2153 16063744 : cur_idx = ch_idx * num_freq_bands;
2154 16063744 : v_multc( &diffuse_power[start_band], diffuse_responses_square[ch_idx], aux_buffer_res, num_freq_bands - start_band );
2155 16063744 : v_add( &cy_auto_diff_smooth[cur_idx + start_band], aux_buffer_res, &cy_auto_diff_smooth[cur_idx + start_band], num_freq_bands - start_band );
2156 : }
2157 :
2158 1927088 : return;
2159 : }
2160 :
2161 :
2162 3116637 : static void computeTargetPSDs_diffuse_subframe(
2163 : const int16_t num_channels,
2164 : const int16_t num_freq_bands,
2165 : const int16_t start_band,
2166 : const float *diffuse_power_factor,
2167 : const float *reference_power,
2168 : const float *diffuse_responses_square,
2169 : float *cy_auto_diff_smooth )
2170 : {
2171 : int16_t ch_idx, cur_idx;
2172 : float diffuse_power[CLDFB_NO_CHANNELS_MAX]; /* segment auxiliary buffer; size: num_freq_bands. */
2173 :
2174 : /* estimate direct and diffuse power */
2175 3116637 : v_mult( diffuse_power_factor, reference_power, diffuse_power, num_freq_bands );
2176 :
2177 : /* compute target auto and cross PSDs of current frame (smoothed) */
2178 26830257 : for ( ch_idx = 0; ch_idx < num_channels; ++ch_idx )
2179 : {
2180 23713620 : cur_idx = ch_idx * num_freq_bands;
2181 :
2182 23713620 : v_multc( &diffuse_power[start_band], diffuse_responses_square[ch_idx], &cy_auto_diff_smooth[cur_idx + start_band], num_freq_bands - start_band );
2183 : }
2184 :
2185 3116637 : return;
2186 : }
2187 :
2188 :
2189 8483623 : static void computeTargetPSDs_diffuse_with_onsets(
2190 : const int16_t num_channels,
2191 : const int16_t num_freq_bands,
2192 : const int16_t num_decorr_freq_bands,
2193 : const int16_t *proto_frame_diff_index,
2194 : const float *diffuse_power_factor,
2195 : const float *reference_power,
2196 : const float *diffuse_responses_square,
2197 : const float *onset_filter,
2198 : float *cy_auto_diff_smooth )
2199 : {
2200 : int16_t ch_idx, cur_idx, diff_idx;
2201 : float diffuse_response_p4, aux_buffer_res1[CLDFB_NO_CHANNELS_MAX];
2202 : /* segment auxiliary buffer */
2203 : float diffuse_power[CLDFB_NO_CHANNELS_MAX]; /* size: num_freq_bands. */
2204 : float aux_buffer_res[CLDFB_NO_CHANNELS_MAX]; /* size: num_freq_bands. */
2205 :
2206 : /* estimate direct and diffuse power */
2207 8483623 : v_mult( diffuse_power_factor, reference_power, diffuse_power, num_decorr_freq_bands );
2208 :
2209 : /* compute target auto and cross PSDs of current frame (smoothed) */
2210 72195116 : for ( ch_idx = 0; ch_idx < num_channels; ++ch_idx )
2211 : {
2212 63711493 : diffuse_response_p4 = diffuse_responses_square[ch_idx] * diffuse_responses_square[ch_idx];
2213 :
2214 63711493 : cur_idx = ch_idx * num_freq_bands;
2215 63711493 : diff_idx = proto_frame_diff_index[ch_idx] * num_freq_bands;
2216 :
2217 63711493 : v_multc( &onset_filter[diff_idx], diffuse_responses_square[ch_idx], aux_buffer_res1, num_decorr_freq_bands );
2218 63711493 : v_multc( &onset_filter[diff_idx], -1.0f, aux_buffer_res, num_decorr_freq_bands );
2219 63711493 : v_addc( aux_buffer_res, 1.0f, aux_buffer_res, num_decorr_freq_bands );
2220 63711493 : v_multc( aux_buffer_res, diffuse_response_p4, aux_buffer_res, num_decorr_freq_bands );
2221 63711493 : v_add( aux_buffer_res1, aux_buffer_res, aux_buffer_res, num_decorr_freq_bands );
2222 63711493 : v_mult( aux_buffer_res, diffuse_power, aux_buffer_res, num_decorr_freq_bands );
2223 63711493 : v_add( &cy_auto_diff_smooth[cur_idx], aux_buffer_res, &cy_auto_diff_smooth[cur_idx], num_decorr_freq_bands );
2224 : }
2225 :
2226 8483623 : return;
2227 : }
2228 :
2229 90140 : static void computeAlphaSynthesis(
2230 : float *alpha_synthesis,
2231 : const int16_t averaging_length_ms,
2232 : const float maxAlpha,
2233 : int16_t *numAlphas,
2234 : const int16_t slot_size,
2235 : const int16_t num_freq_bands,
2236 : const float *frequency_axis,
2237 : const int32_t output_Fs )
2238 : {
2239 : int16_t k;
2240 : float avg_length_f_ms;
2241 :
2242 : /* check input pointer */
2243 90140 : if ( alpha_synthesis == NULL )
2244 : {
2245 : #ifdef DEBUGGING
2246 : assert( !"Error: NULL pointer.\n" );
2247 : #endif
2248 0 : return;
2249 : }
2250 :
2251 90140 : if ( averaging_length_ms == 0 )
2252 : {
2253 0 : set_f( alpha_synthesis, 1.0f, num_freq_bands );
2254 : }
2255 : else
2256 : {
2257 360560 : for ( k = 0; k < num_freq_bands; k++ )
2258 : {
2259 360560 : int16_t faxis_idx = max( k, 1 );
2260 360560 : avg_length_f_ms = 1000.f * (float) averaging_length_ms / fabsf( frequency_axis[faxis_idx] );
2261 360560 : alpha_synthesis[k] = min( (float) slot_size / ( avg_length_f_ms * (float) output_Fs / 1000.f ), 1.0f );
2262 360560 : if ( alpha_synthesis[k] >= maxAlpha )
2263 : {
2264 90140 : alpha_synthesis[k] = maxAlpha;
2265 90140 : *numAlphas = k + 1;
2266 90140 : break;
2267 : }
2268 : }
2269 : }
2270 :
2271 90140 : return;
2272 : }
2273 :
2274 12017208 : static void spreadCoherencePanningHoa(
2275 : const int16_t azimuth,
2276 : const int16_t elevation,
2277 : const float spreadCoh,
2278 : float *direct_response,
2279 : const int16_t num_channels_dir,
2280 : const int16_t ambisonics_order )
2281 : {
2282 : int16_t i;
2283 : float direct_response_left[MAX_OUTPUT_CHANNELS];
2284 : float direct_response_right[MAX_OUTPUT_CHANNELS];
2285 : float gainCenter;
2286 : float gainSide;
2287 :
2288 12017208 : ivas_dirac_dec_get_response( azimuth, elevation, direct_response, ambisonics_order );
2289 :
2290 12017208 : if ( spreadCoh > 0.f )
2291 : {
2292 6586351 : ivas_dirac_dec_get_response( azimuth + 30, elevation, direct_response_left, ambisonics_order );
2293 :
2294 6586351 : ivas_dirac_dec_get_response( azimuth + 330, elevation, direct_response_right, ambisonics_order );
2295 :
2296 6586351 : if ( spreadCoh < 0.5f )
2297 : {
2298 6109730 : gainCenter = ( 1.0f - 2.0f * spreadCoh ) + 2.0f * spreadCoh / 3.0f;
2299 6109730 : gainSide = 2.0f * spreadCoh / 3.0f;
2300 : }
2301 : else
2302 : {
2303 476621 : gainSide = 1.0f / ( 4.0f - 2.0f * spreadCoh );
2304 476621 : gainCenter = ( 2.0f - 2.0f * spreadCoh ) * gainSide;
2305 : }
2306 :
2307 60169223 : for ( i = 0; i < num_channels_dir; i++ )
2308 : {
2309 53582872 : direct_response[i] = direct_response[i] * gainCenter + ( direct_response_left[i] + direct_response_right[i] ) * gainSide;
2310 : }
2311 : }
2312 :
2313 12017208 : return;
2314 : }
2315 :
2316 110931277 : static void spreadCoherencePanningVbap(
2317 : const int16_t azimuth,
2318 : const int16_t elevation,
2319 : const float spreadCoh,
2320 : float *direct_response,
2321 : const int16_t num_channels_dir,
2322 : const VBAP_HANDLE hVBAPdata )
2323 : {
2324 : int16_t i;
2325 : float direct_response_left[MAX_OUTPUT_CHANNELS];
2326 : float direct_response_right[MAX_OUTPUT_CHANNELS];
2327 : float gainCenter;
2328 : float gainSide;
2329 :
2330 110931277 : if ( hVBAPdata == NULL )
2331 : {
2332 : /* Distribute signal to all channels if VBAP is not properly initialized. */
2333 0 : set_f( direct_response, inv_sqrt( num_channels_dir ), num_channels_dir );
2334 :
2335 0 : return;
2336 : }
2337 :
2338 110931277 : vbap_determine_gains( hVBAPdata, direct_response, azimuth, elevation, 0 );
2339 :
2340 110931277 : if ( spreadCoh > 0.f )
2341 : {
2342 11955698 : vbap_determine_gains( hVBAPdata, direct_response_left, azimuth + 30, elevation, 0 );
2343 11955698 : vbap_determine_gains( hVBAPdata, direct_response_right, azimuth - 30, elevation, 0 );
2344 :
2345 11955698 : if ( spreadCoh < 0.5f )
2346 : {
2347 11031926 : gainCenter = ( 1.0f - 2.0f * spreadCoh ) + 2.0f * spreadCoh * INV_SQRT3;
2348 11031926 : gainSide = 2.0f * spreadCoh * INV_SQRT3;
2349 : }
2350 : else
2351 : {
2352 923772 : gainCenter = 2.0f - 2.0f * spreadCoh;
2353 923772 : gainSide = 1.0f;
2354 : }
2355 :
2356 103183775 : for ( i = 0; i < num_channels_dir; i++ )
2357 : {
2358 91228077 : direct_response[i] = direct_response[i] * gainCenter + ( direct_response_left[i] + direct_response_right[i] ) * gainSide;
2359 : }
2360 : }
2361 :
2362 110931277 : return;
2363 : }
2364 :
2365 :
2366 223275246 : static void normalizePanningGains(
2367 : float *direct_response,
2368 : const int16_t num_channels_dir )
2369 : {
2370 : float energySum;
2371 : float normVal;
2372 : int16_t i;
2373 :
2374 223275246 : energySum = sum2_f( direct_response, num_channels_dir ) + 1e-12f;
2375 223275246 : normVal = sqrtf( 1.0f / energySum );
2376 2079799288 : for ( i = 0; i < num_channels_dir; i++ )
2377 : {
2378 1856524042 : direct_response[i] *= normVal;
2379 : }
2380 :
2381 223275246 : return;
2382 : }
|