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 6878 : 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 6878 : DIRAC_OUTPUT_SYNTHESIS_PARAMS *dirac_output_synthesis_params = &( hDirACRend->h_output_synthesis_psd_params );
107 6878 : DIRAC_OUTPUT_SYNTHESIS_STATE *dirac_output_synthesis_state = &( hDirACRend->h_output_synthesis_psd_state );
108 :
109 : /* check / set input parameters */
110 6878 : assert( hSpatParamRendCom->num_freq_bands > 0 && "Error: Number of frequency bands <= 0!" );
111 6878 : assert( hDirACRend->hOutSetup.nchan_out_woLFE > 0 && "Error: Number of output channels > 0!" );
112 6878 : assert( hDirACRend->num_outputs_diff > 0 );
113 6878 : assert( hSpatParamRendCom->slot_size > 0 );
114 6878 : assert( hDirACRend->hOutSetup.is_loudspeaker_setup == 0 || hDirACRend->hOutSetup.is_loudspeaker_setup == 1 );
115 6878 : assert( hDirACRend->diffuse_response_function != NULL );
116 :
117 6878 : if ( hDirACRend->proto_signal_decorr_on )
118 : {
119 6409 : dirac_output_synthesis_params->max_band_decorr = hDirACRend->h_freq_domain_decorr_ap_params->max_band_decorr;
120 : }
121 : else
122 : {
123 469 : dirac_output_synthesis_params->max_band_decorr = 0;
124 : }
125 :
126 : /*-----------------------------------------------------------------*
127 : * memory allocation
128 : *-----------------------------------------------------------------*/
129 :
130 6878 : dirac_output_synthesis_state->diffuse_responses_square = NULL;
131 6878 : if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_MONO )
132 : {
133 331 : 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 6547 : else if ( hDirACRend->synthesisConf != DIRAC_SYNTHESIS_GAIN_SHD )
139 : {
140 3919 : 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 6878 : dirac_output_synthesis_state->proto_power_smooth_prev = NULL;
148 6878 : if ( hDirACRend->synthesisConf != DIRAC_SYNTHESIS_GAIN_SHD )
149 : {
150 4250 : 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 6878 : if ( dirac_output_synthesis_params->max_band_decorr > 0 && ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_PSD_LS || hDirACRend->synthesisConf == DIRAC_SYNTHESIS_PSD_SHD ) )
156 : {
157 3781 : 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 3097 : dirac_output_synthesis_state->proto_power_diff_smooth_prev = NULL;
165 : }
166 :
167 : /* buffer length and interpolator */
168 6878 : 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 6878 : if ( hodirac_flag )
175 : {
176 378 : size = hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_dir * DIRAC_HO_NUMSECTORS;
177 : }
178 : else
179 : {
180 6500 : size = hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_dir;
181 : }
182 6878 : 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 6878 : if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD )
188 : {
189 2628 : dirac_output_synthesis_state->cy_auto_dir_smooth_prev = NULL;
190 2628 : 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 4250 : 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 4250 : if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_PSD_SHD )
203 : {
204 1239 : 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 3011 : 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 6878 : 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 6878 : if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD )
225 : {
226 2628 : 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 4250 : else if ( hDirACRend->synthesisConf != DIRAC_SYNTHESIS_PSD_SHD && hDirACRend->synthesisConf != DIRAC_SYNTHESIS_MONO )
232 : {
233 2680 : 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 1570 : 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 6878 : if ( !( renderer_type == RENDERER_BINAURAL_PARAMETRIC || renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) )
252 : {
253 4250 : 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 4250 : 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 4250 : mvr2r( temp_alpha_synthesis, dirac_output_synthesis_params->alpha_synthesis, dirac_output_synthesis_params->numAlphas );
259 :
260 4250 : 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 4250 : 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 4250 : mvr2r( temp_alpha_synthesis, dirac_output_synthesis_params->alpha_synthesis_fast, dirac_output_synthesis_params->numAlphasFast );
266 :
267 4250 : 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 4250 : 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 4250 : set_zero( dirac_output_synthesis_state->reference_power_smooth_prev, hSpatParamRendCom->num_freq_bands );
276 4250 : set_zero( dirac_output_synthesis_state->direction_smoothness_prev, hSpatParamRendCom->num_freq_bands );
277 : }
278 : else
279 : {
280 2628 : dirac_output_synthesis_params->alpha_synthesis = NULL;
281 2628 : dirac_output_synthesis_params->alpha_synthesis_fast = NULL;
282 2628 : dirac_output_synthesis_state->reference_power_smooth_prev = NULL;
283 2628 : dirac_output_synthesis_state->direction_smoothness_prev = NULL;
284 : }
285 :
286 : /* compute interpolator */
287 34390 : for ( idx = 1; idx <= JBM_CLDFB_SLOTS_IN_SUBFRAME; ++idx )
288 : {
289 27512 : dirac_output_synthesis_params->interpolator[idx - 1] = (float) idx / (float) JBM_CLDFB_SLOTS_IN_SUBFRAME;
290 : }
291 :
292 : /* prepare diffuse response function */
293 6878 : if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_MONO )
294 : {
295 331 : num_diffuse_responses = 2;
296 : }
297 : else
298 : {
299 6547 : num_diffuse_responses = hDirACRend->hOutSetup.nchan_out_woLFE;
300 : }
301 :
302 6878 : if ( dirac_output_synthesis_state->diffuse_responses_square != NULL )
303 : {
304 39105 : 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 34855 : tmp = hDirACRend->diffuse_response_function[ch_idx];
308 :
309 34855 : dirac_output_synthesis_state->diffuse_responses_square[ch_idx] = tmp * tmp;
310 : }
311 : }
312 :
313 6878 : 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 2628 : diff_compensation_order = nchan_transport >= 3 ? 3 : 2; /* compensate missing diffuseness modelling up order 2, except for HR*/
319 2628 : diff_compensation_order = min( diff_compensation_order, hDirACRend->hOutSetup.ambisonics_order );
320 :
321 2628 : diff_nrg_total = 0;
322 2628 : diff_nrg_trans = 0;
323 2628 : diff_nrg_decorr = 0;
324 39136 : for ( ch_idx = 0; ch_idx < ( diff_compensation_order + 1 ) * ( diff_compensation_order + 1 ); ch_idx++ )
325 : {
326 36508 : diff_nrg = hDirACRend->diffuse_response_function[ch_idx] * hDirACRend->diffuse_response_function[ch_idx];
327 36508 : diff_nrg_total += diff_nrg;
328 : /* is it a transport channel?*/
329 36508 : if ( ch_idx == 0 || hDirACRend->proto_index_dir[ch_idx] != 0 )
330 : {
331 12819 : diff_nrg_trans += diff_nrg;
332 : }
333 : /* is it a decorrelated or transport channel?*/
334 36508 : if ( ch_idx < hDirACRend->num_outputs_diff )
335 : {
336 10512 : diff_nrg_decorr += diff_nrg;
337 : }
338 : }
339 2628 : dirac_output_synthesis_params->diffuse_compensation_factor = diff_nrg_total / diff_nrg_trans;
340 2628 : dirac_output_synthesis_params->diffuse_compensation_factor_decorr = diff_nrg_total / diff_nrg_decorr;
341 : }
342 : else
343 : {
344 4250 : dirac_output_synthesis_params->diffuse_compensation_factor = 0.f;
345 4250 : dirac_output_synthesis_params->diffuse_compensation_factor_decorr = 0.f;
346 : }
347 :
348 6878 : return IVAS_ERR_OK;
349 : }
350 :
351 :
352 : /*-------------------------------------------------------------------------
353 : * ivas_dirac_dec_output_synthesis_init()
354 : *
355 : *
356 : *------------------------------------------------------------------------*/
357 :
358 6947 : 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 6947 : h_dirac_output_synthesis_params = &( hDirACRend->h_output_synthesis_psd_params );
371 6947 : h_dirac_output_synthesis_state = &( hDirACRend->h_output_synthesis_psd_state );
372 :
373 : /*-----------------------------------------------------------------*
374 : * init outputSynthesisPSD_Init
375 : *-----------------------------------------------------------------*/
376 :
377 : /* initialize buffers */
378 6947 : if ( h_dirac_output_synthesis_state->cy_auto_dir_smooth_prev != NULL )
379 : {
380 4250 : set_zero( h_dirac_output_synthesis_state->cy_auto_dir_smooth_prev, hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_dir );
381 : }
382 :
383 6947 : if ( hodirac_flag )
384 : {
385 378 : size = hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_dir * DIRAC_HO_NUMSECTORS;
386 : }
387 : else
388 : {
389 6569 : size = hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_dir;
390 : }
391 6947 : set_zero( h_dirac_output_synthesis_state->cy_cross_dir_smooth_prev, size );
392 :
393 6947 : if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD )
394 : {
395 2697 : 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 4250 : else if ( hDirACRend->synthesisConf != DIRAC_SYNTHESIS_PSD_SHD )
398 : {
399 3011 : 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 1239 : set_zero( h_dirac_output_synthesis_state->cy_auto_diff_smooth_prev, hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_dir );
404 : }
405 :
406 6947 : if ( h_dirac_output_synthesis_state->proto_power_smooth_prev != NULL )
407 : {
408 4250 : set_zero( h_dirac_output_synthesis_state->proto_power_smooth_prev, hSpatParamRendCom->num_freq_bands * hDirACRend->num_protos_dir );
409 : }
410 6947 : set_zero( h_dirac_output_synthesis_state->gains_dir_prev, size );
411 :
412 6947 : if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD )
413 : {
414 2697 : 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 4250 : set_zero( h_dirac_output_synthesis_state->gains_diff_prev, hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_dir );
419 : }
420 :
421 6947 : if ( h_dirac_output_synthesis_state->proto_power_diff_smooth_prev != NULL )
422 : {
423 3781 : 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 6947 : return;
427 : }
428 :
429 :
430 : /*-------------------------------------------------------------------------
431 : * ivas_dirac_dec_output_synthesis_close()
432 : *
433 : * Memory deallocation of Output synthesis sub-module
434 : *------------------------------------------------------------------------*/
435 :
436 6878 : 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 6878 : DIRAC_OUTPUT_SYNTHESIS_PARAMS *dirac_output_synthesis_params = &( hDirACRend->h_output_synthesis_psd_params );
442 6878 : 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 6878 : if ( ( dirac_output_synthesis_params )->interpolator != NULL )
450 : {
451 6878 : free( ( dirac_output_synthesis_params )->interpolator );
452 6878 : ( dirac_output_synthesis_params )->interpolator = NULL;
453 : }
454 :
455 : /* free alpha */
456 6878 : if ( ( dirac_output_synthesis_params )->alpha_synthesis != NULL )
457 : {
458 4250 : free( ( dirac_output_synthesis_params )->alpha_synthesis );
459 4250 : ( dirac_output_synthesis_params )->alpha_synthesis = NULL;
460 : }
461 6878 : if ( ( dirac_output_synthesis_params )->alpha_synthesis_fast != NULL )
462 : {
463 4250 : free( ( dirac_output_synthesis_params )->alpha_synthesis_fast );
464 4250 : ( dirac_output_synthesis_params )->alpha_synthesis_fast = NULL;
465 : }
466 :
467 6878 : if ( ( dirac_output_synthesis_state )->reference_power_smooth_prev != NULL )
468 : {
469 4250 : free( ( dirac_output_synthesis_state )->reference_power_smooth_prev );
470 4250 : ( dirac_output_synthesis_state )->reference_power_smooth_prev = NULL;
471 : }
472 :
473 6878 : if ( ( dirac_output_synthesis_state )->direction_smoothness_prev != NULL )
474 : {
475 4250 : free( ( dirac_output_synthesis_state )->direction_smoothness_prev );
476 4250 : ( dirac_output_synthesis_state )->direction_smoothness_prev = NULL;
477 : }
478 :
479 6878 : if ( ( dirac_output_synthesis_state )->diffuse_responses_square != NULL )
480 : {
481 4250 : free( ( dirac_output_synthesis_state )->diffuse_responses_square );
482 4250 : ( dirac_output_synthesis_state )->diffuse_responses_square = NULL;
483 : }
484 :
485 : /* free power buffers */
486 6878 : if ( ( dirac_output_synthesis_state )->proto_power_smooth_prev != NULL )
487 : {
488 4250 : free( ( dirac_output_synthesis_state )->proto_power_smooth_prev );
489 4250 : ( dirac_output_synthesis_state )->proto_power_smooth_prev = NULL;
490 : }
491 :
492 6878 : if ( ( dirac_output_synthesis_state )->proto_power_diff_smooth_prev != NULL )
493 : {
494 3781 : free( ( dirac_output_synthesis_state )->proto_power_diff_smooth_prev );
495 3781 : ( dirac_output_synthesis_state )->proto_power_diff_smooth_prev = NULL;
496 : }
497 :
498 : /* free target power buffers */
499 6878 : if ( ( dirac_output_synthesis_state )->cy_auto_dir_smooth_prev != NULL )
500 : {
501 4250 : free( ( dirac_output_synthesis_state )->cy_auto_dir_smooth_prev );
502 4250 : ( dirac_output_synthesis_state )->cy_auto_dir_smooth_prev = NULL;
503 : }
504 6878 : if ( ( dirac_output_synthesis_state )->cy_cross_dir_smooth_prev != NULL )
505 : {
506 6878 : free( ( dirac_output_synthesis_state )->cy_cross_dir_smooth_prev );
507 6878 : ( dirac_output_synthesis_state )->cy_cross_dir_smooth_prev = NULL;
508 : }
509 6878 : if ( ( dirac_output_synthesis_state )->cy_auto_diff_smooth_prev != NULL )
510 : {
511 6878 : free( ( dirac_output_synthesis_state )->cy_auto_diff_smooth_prev );
512 6878 : ( dirac_output_synthesis_state )->cy_auto_diff_smooth_prev = NULL;
513 : }
514 :
515 : /* free gain buffers */
516 6878 : if ( ( dirac_output_synthesis_state )->gains_dir_prev != NULL )
517 : {
518 6878 : free( ( dirac_output_synthesis_state )->gains_dir_prev );
519 6878 : ( dirac_output_synthesis_state )->gains_dir_prev = NULL;
520 : }
521 6878 : if ( ( dirac_output_synthesis_state )->gains_diff_prev != NULL )
522 : {
523 6878 : free( ( dirac_output_synthesis_state )->gains_diff_prev );
524 6878 : ( dirac_output_synthesis_state )->gains_diff_prev = NULL;
525 : }
526 :
527 6878 : return;
528 : }
529 :
530 :
531 : /*-------------------------------------------------------------------------
532 : * ivas_dirac_dec_output_synthesis_process_slot()
533 : *
534 : *
535 : *------------------------------------------------------------------------*/
536 :
537 3938643 : 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 3938643 : h_dirac_output_synthesis_params = &( hDirACRend->h_output_synthesis_psd_params );
561 3938643 : h_dirac_output_synthesis_state = &( hDirACRend->h_output_synthesis_psd_state );
562 :
563 3938643 : h_dirac_output_synthesis_state->onset_filter = onset;
564 :
565 : /*-----------------------------------------------------------------*
566 : * processing
567 : *-----------------------------------------------------------------*/
568 :
569 : /* collect some often used parameters */
570 3938643 : num_freq_bands = hSpatParamRendCom->num_freq_bands;
571 3938643 : num_channels_dir = hDirACRend->num_outputs_dir;
572 3938643 : num_channels_diff = hDirACRend->num_outputs_diff;
573 3938643 : num_freq_bands_diff = h_dirac_output_synthesis_params->max_band_decorr;
574 :
575 3938643 : if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_PSD_LS )
576 : {
577 789891 : num_channels_dir = hOutSetup.nchan_out_woLFE;
578 : }
579 :
580 3938643 : if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD && hodirac_flag )
581 : {
582 646080 : 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 3938643 : if ( dec_param_estim == FALSE && hodirac_flag )
595 : {
596 646080 : if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD )
597 : {
598 646080 : v_multc( hSpatParamRendCom->energy_ratio1[md_idx], -1.f, aux_buf, num_freq_bands );
599 646080 : v_addc( aux_buf, 1.f, aux_buf, num_freq_bands );
600 646080 : mvr2r( hSpatParamRendCom->energy_ratio1[md_idx],
601 : h_dirac_output_synthesis_state->direct_power_factor,
602 : num_freq_bands );
603 646080 : mvr2r( aux_buf,
604 : h_dirac_output_synthesis_state->diffuse_power_factor,
605 : num_freq_bands );
606 :
607 646080 : v_multc( hSpatParamRendCom->energy_ratio2[md_idx], -1.f, aux_buf, num_freq_bands );
608 646080 : v_addc( aux_buf, 1.f, aux_buf, num_freq_bands );
609 646080 : mvr2r( hSpatParamRendCom->energy_ratio2[md_idx],
610 646080 : &h_dirac_output_synthesis_state->direct_power_factor[hSpatParamRendCom->num_freq_bands],
611 : num_freq_bands );
612 646080 : mvr2r( aux_buf,
613 646080 : &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 3292563 : else if ( dec_param_estim == TRUE )
626 : {
627 : /* compute direct responses */
628 2253249 : 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 2253249 : if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD )
640 : {
641 2085297 : ivas_dirac_dec_compute_gain_factors( num_freq_bands,
642 : diffuseness,
643 2085297 : 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 2085297 : 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 2085297 : 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 10426485 : for ( ch_idx = 0; ch_idx < min( 4, nchan_transport ); ch_idx++ )
658 : {
659 : int16_t k;
660 8341188 : if ( ch_idx != 0 )
661 : {
662 : float a, b, c;
663 :
664 : /*Directonal sound gain nrg compensation*/
665 37535346 : for ( k = 0; k < num_freq_bands_diff; k++ )
666 : {
667 31279455 : a = h_dirac_output_synthesis_state->direct_responses[ch_idx * num_freq_bands + k];
668 31279455 : b = reference_power[k + num_freq_bands] / ( reference_power[k + ( ch_idx + 1 ) * num_freq_bands] + EPSILON );
669 31279455 : c = 1.f + ( 1.f / 6.f ) * ( h_dirac_output_synthesis_params->diffuse_compensation_factor_decorr - 1.f ); /*Diffuseness modellling nrg compensation*/
670 31279455 : 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 293965596 : for ( ; k < num_freq_bands; k++ )
673 : {
674 287709705 : a = h_dirac_output_synthesis_state->direct_responses[ch_idx * num_freq_bands + k];
675 287709705 : b = reference_power[k + num_freq_bands] / ( reference_power[k + ( ch_idx + 1 ) * num_freq_bands] + EPSILON );
676 287709705 : c = 1.f + ( 1.f / 6.f ) * ( h_dirac_output_synthesis_params->diffuse_compensation_factor - 1.f ); /*Diffuseness modellling nrg compensation*/
677 287709705 : 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 12511782 : for ( k = 0; k < num_freq_bands_diff; k++ )
684 : {
685 10426485 : 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 97988532 : for ( ; k < num_freq_bands; k++ )
688 : {
689 95903235 : 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 26074317 : for ( ch_idx = min( 4, nchan_transport ); ch_idx < num_channels_dir; ch_idx++ )
696 : {
697 23989020 : v_mult( h_dirac_output_synthesis_state->direct_power_factor,
698 23989020 : &h_dirac_output_synthesis_state->direct_responses[ch_idx * num_freq_bands],
699 : aux_buf,
700 : num_freq_bands );
701 :
702 23989020 : v_add( aux_buf,
703 23989020 : &h_dirac_output_synthesis_state->cy_cross_dir_smooth[ch_idx * num_freq_bands],
704 23989020 : &h_dirac_output_synthesis_state->cy_cross_dir_smooth[ch_idx * num_freq_bands],
705 : num_freq_bands );
706 : }
707 :
708 : /*Diffuse gain*/
709 2085297 : 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 2085297 : return;
723 : }
724 : else
725 : {
726 : /* compute reference and diffuse power factor for this frame */
727 167952 : ivas_dirac_dec_compute_power_factors( num_freq_bands,
728 : diffuseness,
729 167952 : 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 1853346 : diff_start_band = 0;
736 1853346 : if ( h_dirac_output_synthesis_params->use_onset_filters )
737 : {
738 621939 : computeTargetPSDs_diffuse_with_onsets( num_channels_dir,
739 621939 : num_freq_bands, h_dirac_output_synthesis_params->max_band_decorr,
740 621939 : hDirACRend->proto_index_diff,
741 621939 : h_dirac_output_synthesis_state->diffuse_power_factor,
742 : reference_power,
743 621939 : h_dirac_output_synthesis_state->diffuse_responses_square,
744 : onset,
745 : h_dirac_output_synthesis_state->cy_auto_diff_smooth );
746 :
747 621939 : 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 1853346 : if ( dec_param_estim == TRUE )
752 : {
753 167952 : 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 167952 : 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 1853346 : return;
759 : }
760 :
761 :
762 : /*-------------------------------------------------------------------------
763 : * ivas_dirac_dec_output_synthesis_process_subframe_gain_shd()
764 : *
765 : *
766 : *------------------------------------------------------------------------*/
767 :
768 719139 : 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 719139 : h_dirac_output_synthesis_params = hDirACRend->h_output_synthesis_psd_params;
802 719139 : h_dirac_output_synthesis_state = hDirACRend->h_output_synthesis_psd_state;
803 719139 : proto_direct_index = hDirACRend->proto_index_dir;
804 :
805 719139 : num_protos_dir = hDirACRend->num_protos_dir;
806 719139 : num_freq_bands = hSpatParamRendCom->num_freq_bands;
807 719139 : num_freq_bands_diff = h_dirac_output_synthesis_params.max_band_decorr;
808 719139 : num_channels_dir = hDirACRend->num_outputs_dir;
809 719139 : num_channels_diff = hDirACRend->num_outputs_diff;
810 719139 : nchan_transport_foa = min( 4, nchan_transport );
811 :
812 :
813 : /*-----------------------------------------------------------------*
814 : * comput target Gains
815 : *-----------------------------------------------------------------*/
816 :
817 719139 : if ( hodirac_flag )
818 : {
819 : /*Direct gain*/
820 807600 : for ( ch_idx = 0; ch_idx < nchan_transport_foa; ch_idx++ )
821 : {
822 646080 : v_multc( diffuseness,
823 : 1.f,
824 646080 : &h_dirac_output_synthesis_state.cy_cross_dir_smooth[ch_idx * num_freq_bands],
825 : num_freq_bands );
826 646080 : v_multc( &h_dirac_output_synthesis_state.cy_cross_dir_smooth[ch_idx * num_freq_bands],
827 646080 : h_dirac_output_synthesis_params.diffuse_compensation_factor - 1.f,
828 646080 : &h_dirac_output_synthesis_state.cy_cross_dir_smooth[ch_idx * num_freq_bands],
829 : num_freq_bands );
830 :
831 39084480 : for ( l = 0; l < num_freq_bands; l++ )
832 : {
833 38438400 : 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 1917480 : for ( ch_idx = nchan_transport_foa; ch_idx < num_channels_dir; ch_idx++ )
839 : {
840 106419960 : for ( l = 0; l < num_freq_bands; l++ )
841 : {
842 104664000 : aux_buf[l] = 1.f - diffuseness[l];
843 104664000 : ratio[l] = 1.f - h_dirac_output_synthesis_state.direct_power_factor[hSpatParamRendCom->num_freq_bands + l];
844 104664000 : ratio[l + num_freq_bands] = 1.f - ratio[l];
845 : }
846 :
847 1755960 : v_mult( aux_buf, ratio, ratio, num_freq_bands );
848 1755960 : v_mult( aux_buf, &ratio[num_freq_bands], &ratio[num_freq_bands], num_freq_bands );
849 :
850 1755960 : v_mult( ratio,
851 1755960 : &h_dirac_output_synthesis_state.direct_responses[ch_idx * num_freq_bands],
852 1755960 : &h_dirac_output_synthesis_state.cy_cross_dir_smooth[ch_idx * num_freq_bands],
853 : num_freq_bands );
854 1755960 : v_mult( &ratio[num_freq_bands],
855 1755960 : &h_dirac_output_synthesis_state.direct_responses[ch_idx * num_freq_bands + num_freq_bands * num_channels_dir],
856 1755960 : &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 161520 : 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 557619 : else if ( dec_param_estim == FALSE )
870 : {
871 : /*Direct gain*/
872 66282 : for ( ch_idx = 0; ch_idx < nchan_transport_foa; ch_idx++ )
873 : {
874 33141 : v_mult( h_dirac_output_synthesis_state.diffuse_power_factor,
875 33141 : h_dirac_output_synthesis_state.diffuse_power_factor,
876 33141 : &h_dirac_output_synthesis_state.cy_cross_dir_smooth[ch_idx * num_freq_bands],
877 : num_freq_bands );
878 33141 : v_multc( &h_dirac_output_synthesis_state.cy_cross_dir_smooth[ch_idx * num_freq_bands],
879 33141 : h_dirac_output_synthesis_params.diffuse_compensation_factor_decorr - 1.f,
880 33141 : &h_dirac_output_synthesis_state.cy_cross_dir_smooth[ch_idx * num_freq_bands],
881 : num_freq_bands_diff );
882 33141 : v_multc( &h_dirac_output_synthesis_state.cy_cross_dir_smooth[ch_idx * num_freq_bands + num_freq_bands_diff],
883 33141 : h_dirac_output_synthesis_params.diffuse_compensation_factor - 1.f,
884 33141 : &h_dirac_output_synthesis_state.cy_cross_dir_smooth[ch_idx * num_freq_bands + num_freq_bands_diff],
885 33141 : num_freq_bands - num_freq_bands_diff );
886 :
887 2021601 : for ( l = 0; l < num_freq_bands; l++ )
888 : {
889 1988460 : 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 194820 : for ( ch_idx = nchan_transport_foa; ch_idx < num_channels_dir; ch_idx++ )
895 : {
896 161679 : v_mult( h_dirac_output_synthesis_state.direct_power_factor,
897 161679 : &h_dirac_output_synthesis_state.direct_responses[ch_idx * num_freq_bands],
898 161679 : &h_dirac_output_synthesis_state.cy_cross_dir_smooth[ch_idx * num_freq_bands], num_freq_bands );
899 : }
900 :
901 : /*Diffuse gain*/
902 132564 : for ( ch_idx = nchan_transport_foa; ch_idx < num_channels_diff; ch_idx++ )
903 : {
904 99423 : 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 719139 : p_cy_cross_dir_smooth = h_dirac_output_synthesis_state.cy_cross_dir_smooth;
913 719139 : p_gains_dir = h_dirac_output_synthesis_state.cy_cross_dir_smooth_prev;
914 :
915 : /* Direct gains */
916 719139 : if ( hodirac_flag )
917 : {
918 807600 : for ( ch_idx = 0; ch_idx < nchan_transport_foa; ch_idx++ )
919 : {
920 39084480 : for ( l = 0; l < num_freq_bands; l++ )
921 : {
922 38438400 : g1 = 0.3679f + onset_filter[l] * ( 0.1175f - 0.3679f );
923 38438400 : g2 = ( 1.f - g1 ) * *( p_gains_dir );
924 38438400 : g2 += g1 * ( *( p_cy_cross_dir_smooth++ ) );
925 38438400 : g2 = max( g2, 0.99f );
926 38438400 : g2 = min( g2, 2.0f );
927 38438400 : *( p_gains_dir++ ) = g2;
928 : }
929 : }
930 : }
931 : else
932 : {
933 2688672 : for ( ch_idx = 0; ch_idx < nchan_transport_foa; ch_idx++ )
934 : {
935 110982633 : for ( l = 0; l < num_freq_bands; l++ )
936 : {
937 108851580 : g1 = 0.3679f + onset_filter[l] * ( 0.1175f - 0.3679f );
938 108851580 : g2 = ( 1.f - g1 ) * *( p_gains_dir );
939 108851580 : g2 += g1 * ( *( p_cy_cross_dir_smooth++ ) );
940 108851580 : g2 = max( g2, 0.85f );
941 108851580 : g2 = min( g2, 1.15f );
942 108851580 : *( p_gains_dir++ ) = g2;
943 : }
944 : }
945 : }
946 :
947 : /*Directional gains*/
948 8671878 : for ( ch_idx = nchan_transport_foa; ch_idx < num_channels_dir; ch_idx++ )
949 : {
950 429203079 : for ( l = 0; l < num_freq_bands; l++ )
951 : {
952 421250340 : g1 = 0.3679f + onset_filter[l] * ( 0.1175f - 0.3679f );
953 421250340 : g2 = ( 1.f - g1 ) * *( p_gains_dir );
954 421250340 : g2 += g1 * ( *( p_cy_cross_dir_smooth++ ) );
955 421250340 : g2 = max( g2, -DIRAC_GAIN_LIMIT );
956 421250340 : g2 = min( g2, DIRAC_GAIN_LIMIT );
957 421250340 : *( p_gains_dir++ ) = g2;
958 : }
959 : }
960 :
961 719139 : if ( hodirac_flag )
962 : {
963 161520 : p_cy_cross_dir_smooth = h_dirac_output_synthesis_state.cy_cross_dir_smooth + num_freq_bands * num_channels_dir;
964 161520 : p_gains_dir = h_dirac_output_synthesis_state.cy_cross_dir_smooth_prev + num_freq_bands * num_channels_dir;
965 :
966 : /*Direct gains*/
967 807600 : for ( ch_idx = 0; ch_idx < nchan_transport_foa; ch_idx++ )
968 : {
969 39084480 : for ( l = 0; l < num_freq_bands; l++ )
970 : {
971 38438400 : p_cy_cross_dir_smooth++;
972 38438400 : p_gains_dir++;
973 : }
974 : }
975 :
976 : /*Directional gains*/
977 1917480 : for ( ch_idx = nchan_transport_foa; ch_idx < num_channels_dir; ch_idx++ )
978 : {
979 106419960 : for ( l = 0; l < num_freq_bands; l++ )
980 : {
981 104664000 : g1 = 0.3679f + onset_filter[l] * ( 0.1175f - 0.3679f );
982 104664000 : g2 = ( 1.f - g1 ) * *( p_gains_dir );
983 104664000 : g2 += g1 * ( *( p_cy_cross_dir_smooth++ ) );
984 104664000 : g2 = max( g2, -DIRAC_GAIN_LIMIT );
985 104664000 : g2 = min( g2, DIRAC_GAIN_LIMIT );
986 104664000 : *( p_gains_dir++ ) = g2;
987 : }
988 : }
989 : }
990 :
991 : /*Diffuse gains*/
992 719139 : p_cy_auto_diff_smooth = h_dirac_output_synthesis_state.cy_auto_diff_smooth + nchan_transport_foa * num_freq_bands_diff;
993 719139 : p_gains_diff = h_dirac_output_synthesis_state.cy_auto_diff_smooth_prev + nchan_transport_foa * num_freq_bands_diff;
994 818562 : for ( ch_idx = nchan_transport_foa; ch_idx < num_channels_diff; ch_idx++ )
995 : {
996 2286729 : for ( l = 0; l < num_freq_bands_diff; l++ )
997 : {
998 2187306 : g1 = 0.1175f;
999 2187306 : g2 = ( 1.f - g1 ) * *( p_gains_diff );
1000 2187306 : g2 += g1 * ( *( p_cy_auto_diff_smooth++ ) );
1001 2187306 : g2 = max( g2, 0.f );
1002 2187306 : g2 = min( g2, DIRAC_GAIN_LIMIT );
1003 2187306 : *( p_gains_diff++ ) = g2;
1004 : }
1005 : }
1006 :
1007 : /*-----------------------------------------------------------------*
1008 : * gain interpolation and output streams
1009 : *-----------------------------------------------------------------*/
1010 :
1011 3583080 : for ( buf_idx = 0; buf_idx < nbslots; ++buf_idx )
1012 : {
1013 2863941 : g1 = h_dirac_output_synthesis_params.interpolator[buf_idx];
1014 2863941 : g2 = 1.f - g1;
1015 :
1016 : /*Direct input->output*/
1017 2863941 : p_gains_dir = h_dirac_output_synthesis_state.cy_cross_dir_smooth_prev;
1018 2863941 : p_gains_dir_prev = h_dirac_output_synthesis_state.gains_dir_prev;
1019 13922013 : for ( ch_idx = 0; ch_idx < nchan_transport_foa; ch_idx++ )
1020 : {
1021 11058072 : 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 598084392 : for ( l = 0; l < num_freq_bands; l++ )
1023 : {
1024 587026320 : g = g1 * ( *( p_gains_dir++ ) ) + g2 * ( *( p_gains_dir_prev++ ) );
1025 587026320 : output_real[l * num_channels_dir + ch_idx] = g * ( *( p_proto_diff++ ) );
1026 587026320 : output_imag[l * num_channels_dir + ch_idx] = g * ( *( p_proto_diff++ ) );
1027 : }
1028 : }
1029 :
1030 : /*Directional stream*/
1031 34523517 : for ( ch_idx = nchan_transport_foa; ch_idx < num_channels_dir; ch_idx++ )
1032 : {
1033 31659576 : if ( hodirac_flag )
1034 : {
1035 7023840 : if ( proto_direct_index[ch_idx] == 0 )
1036 : {
1037 : float *p_proto2;
1038 : float gs1, gs2;
1039 3472320 : p_proto = h_dirac_output_synthesis_state.proto_direct_buffer_f +
1040 3472320 : buf_idx * 2 * num_freq_bands * num_protos_dir +
1041 3472320 : proto_direct_index[0] * 2 * num_freq_bands;
1042 3472320 : p_proto2 = h_dirac_output_synthesis_state.proto_direct_buffer_f +
1043 3472320 : buf_idx * 2 * num_freq_bands * num_protos_dir +
1044 3472320 : proto_direct_index[1] * 2 * num_freq_bands;
1045 210419520 : for ( l = 0; l < num_freq_bands; l++ )
1046 : {
1047 206947200 : gs1 = g1 * ( *( p_gains_dir ) ) + g2 * ( *( p_gains_dir_prev ) );
1048 206947200 : gs2 = g1 * ( *( p_gains_dir + num_freq_bands * num_channels_dir ) ) + g2 * ( *( p_gains_dir_prev + num_freq_bands * num_channels_dir ) );
1049 206947200 : p_gains_dir++;
1050 206947200 : p_gains_dir_prev++;
1051 :
1052 206947200 : output_real[l * num_channels_dir + ch_idx] = 0.5f * gs1 * ( 1.772454e+00f * ( *p_proto ) + 1.023327e+00f * ( *p_proto2 ) ) + /* s1 */
1053 206947200 : 0.5f * gs2 * ( 1.772454e+00f * ( *p_proto ) - 1.023327e+00f * ( *p_proto2 ) ); /* s2 */
1054 206947200 : p_proto++;
1055 206947200 : p_proto2++;
1056 206947200 : output_imag[l * num_channels_dir + ch_idx] = 0.5f * gs1 * ( 1.772454e+00f * ( *p_proto ) + 1.023327e+00f * ( *p_proto2 ) ) +
1057 206947200 : 0.5f * gs2 * ( 1.772454e+00f * ( *p_proto ) - 1.023327e+00f * ( *p_proto2 ) );
1058 206947200 : p_proto++;
1059 206947200 : p_proto2++;
1060 : }
1061 : }
1062 : else
1063 : {
1064 3551520 : p_proto = h_dirac_output_synthesis_state.proto_direct_buffer_f +
1065 3551520 : buf_idx * 2 * num_freq_bands * num_protos_dir +
1066 3551520 : proto_direct_index[ch_idx] * 2 * num_freq_bands;
1067 215260320 : for ( l = 0; l < num_freq_bands; l++ )
1068 : {
1069 211708800 : p_gains_dir++;
1070 211708800 : p_gains_dir_prev++;
1071 :
1072 :
1073 211708800 : output_real[l * num_channels_dir + ch_idx] = *( p_proto++ );
1074 211708800 : output_imag[l * num_channels_dir + ch_idx] = *( p_proto++ );
1075 : }
1076 : }
1077 : }
1078 : else
1079 : {
1080 24635736 : p_proto = h_dirac_output_synthesis_state.proto_direct_buffer_f +
1081 24635736 : buf_idx * 2 * num_freq_bands * num_protos_dir +
1082 24635736 : proto_direct_index[ch_idx] * 2 * num_freq_bands;
1083 24635736 : if ( proto_direct_index[ch_idx] == 0 )
1084 : {
1085 1231428792 : for ( l = 0; l < num_freq_bands; l++ )
1086 : {
1087 1207731120 : g = g1 * ( *( p_gains_dir++ ) ) + g2 * ( *( p_gains_dir_prev++ ) );
1088 1207731120 : output_real[l * num_channels_dir + ch_idx] = g * ( *( p_proto++ ) );
1089 1207731120 : output_imag[l * num_channels_dir + ch_idx] = g * ( *( p_proto++ ) );
1090 : }
1091 : }
1092 : else
1093 : {
1094 53151504 : for ( l = 0; l < num_freq_bands; l++ )
1095 : {
1096 52213440 : p_gains_dir++;
1097 52213440 : p_gains_dir_prev++;
1098 52213440 : output_real[l * num_channels_dir + ch_idx] = *( p_proto++ );
1099 52213440 : output_imag[l * num_channels_dir + ch_idx] = *( p_proto++ );
1100 : }
1101 : }
1102 : }
1103 : }
1104 :
1105 : /*Diffuse stream*/
1106 2863941 : p_gains_diff = h_dirac_output_synthesis_state.cy_auto_diff_smooth_prev + nchan_transport_foa * num_freq_bands_diff;
1107 2863941 : p_gains_diff_prev = h_dirac_output_synthesis_state.gains_diff_prev + nchan_transport_foa * num_freq_bands_diff;
1108 2863941 : ch_idx_diff = nchan_transport_foa;
1109 3261633 : for ( ch_idx = nchan_transport_foa; ch_idx < num_channels_diff; ch_idx++ )
1110 : {
1111 397692 : if ( proto_direct_index[ch_idx] == 0 )
1112 : {
1113 397692 : 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 397692 : ch_idx_diff++;
1115 9146916 : for ( l = 0; l < num_freq_bands_diff; l++ )
1116 : {
1117 8749224 : g = g1 * ( *( p_gains_diff++ ) ) + g2 * ( *( p_gains_diff_prev++ ) );
1118 8749224 : output_real[l * num_channels_dir + hDirACRend->sba_map_tc[ch_idx]] += g * ( *( p_proto++ ) ); /* maps ch_idx 5 to 8 */
1119 8749224 : 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 2863941 : if ( hDirACRend->hOutSetup.is_loudspeaker_setup && hDirACRend->hoa_decoder != NULL )
1137 516000 : {
1138 : float *p_real, *p_imag;
1139 : const float *hoa_decoder;
1140 :
1141 516000 : hoa_decoder = hDirACRend->hoa_decoder;
1142 :
1143 5352000 : for ( ch_idx = 0; ch_idx < hDirACRend->hOutSetup.nchan_out_woLFE; ch_idx++ )
1144 : {
1145 4836000 : p_real = RealBuffer[ch_idx][buf_idx];
1146 4836000 : p_imag = ImagBuffer[ch_idx][buf_idx];
1147 :
1148 273876000 : for ( l = 0; l < num_freq_bands; l++ )
1149 : {
1150 269040000 : p_out_real = output_real + l * num_channels_dir;
1151 269040000 : p_out_imag = output_imag + l * num_channels_dir;
1152 269040000 : p_real[l] = *( p_out_real++ ) * hoa_decoder[0];
1153 269040000 : p_imag[l] = *( p_out_imag++ ) * hoa_decoder[0];
1154 4304640000 : for ( i = 1; i < num_channels_dir; i++ )
1155 : {
1156 4035600000 : p_real[l] += *( p_out_real++ ) * hoa_decoder[i];
1157 4035600000 : p_imag[l] += *( p_out_imag++ ) * hoa_decoder[i];
1158 : }
1159 : }
1160 4836000 : hoa_decoder += 16;
1161 : }
1162 : }
1163 : else
1164 : {
1165 36809589 : for ( ch_idx = 0; ch_idx < num_channels_dir; ch_idx++ )
1166 : {
1167 1835448528 : for ( l = 0; l < num_freq_bands; l++ )
1168 : {
1169 1800986880 : RealBuffer[ch_idx][buf_idx][l] = output_real[l * num_channels_dir + ch_idx];
1170 1800986880 : 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 719139 : if ( hodirac_flag )
1182 : {
1183 161520 : 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 557619 : 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 719139 : 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 719139 : if ( hodirac_flag )
1194 : {
1195 161520 : 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 557619 : set_zero( h_dirac_output_synthesis_state.cy_cross_dir_smooth, num_freq_bands * num_channels_dir );
1200 : }
1201 :
1202 719139 : set_zero( h_dirac_output_synthesis_state.cy_auto_diff_smooth, num_freq_bands_diff * num_channels_diff );
1203 :
1204 719139 : return;
1205 : }
1206 :
1207 :
1208 : /*-------------------------------------------------------------------------
1209 : * ivas_dirac_dec_output_synthesis_process_subframe_psd_ls()
1210 : *
1211 : *
1212 : *------------------------------------------------------------------------*/
1213 :
1214 272022 : 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 272022 : push_wmops( "dirac_out_synth_sfr" );
1255 :
1256 272022 : h_dirac_output_synthesis_params = &( hDirACRend->h_output_synthesis_psd_params );
1257 272022 : h_dirac_output_synthesis_state = &( hDirACRend->h_output_synthesis_psd_state );
1258 272022 : proto_direct_index = hDirACRend->proto_index_dir;
1259 272022 : num_protos_dir = hDirACRend->num_protos_dir;
1260 272022 : nchan_out_woLFE = hDirACRend->hOutSetup.nchan_out_woLFE;
1261 :
1262 : /* collect some often used parameters */
1263 272022 : num_freq_bands = hSpatParamRendCom->num_freq_bands;
1264 :
1265 : /*-----------------------------------------------------------------*
1266 : * compute target PSDs
1267 : *-----------------------------------------------------------------*/
1268 :
1269 272022 : if ( enc_param_start_band == 0 )
1270 : {
1271 230034 : diff_start_band = h_dirac_output_synthesis_params->use_onset_filters == 1 ? h_dirac_output_synthesis_params->max_band_decorr : 0;
1272 :
1273 230034 : if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_MONO )
1274 : {
1275 27081 : nchan_target_psds = 2;
1276 : }
1277 : else
1278 : {
1279 202953 : nchan_target_psds = nchan_out_woLFE;
1280 : }
1281 :
1282 230034 : computeTargetPSDs_direct_subframe( nchan_target_psds, num_freq_bands,
1283 230034 : h_dirac_output_synthesis_state->direct_power_factor,
1284 : reference_power_smooth,
1285 230034 : h_dirac_output_synthesis_state->direct_responses,
1286 230034 : 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 230034 : computeTargetPSDs_diffuse_subframe( nchan_target_psds, num_freq_bands, diff_start_band,
1291 230034 : h_dirac_output_synthesis_state->diffuse_power_factor,
1292 : reference_power_smooth,
1293 230034 : 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 272022 : if ( hDirACRend->masa_stereo_type_detect != NULL )
1302 : {
1303 43899 : MASA_STEREO_TYPE_DETECT *masa_stereo_type_detect = hDirACRend->masa_stereo_type_detect;
1304 :
1305 43899 : p_cy_auto_dir_smooth = h_dirac_output_synthesis_state->cy_auto_dir_smooth;
1306 43899 : p_cy_auto_diff_smooth = h_dirac_output_synthesis_state->cy_auto_diff_smooth;
1307 43899 : if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_MONO )
1308 : {
1309 27081 : target_power_y = p_cy_auto_dir_smooth[num_freq_bands] / ( sqrtf( h_dirac_output_synthesis_state->direct_power_factor[0] ) + EPSILON );
1310 27081 : 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 16818 : target_power_y = p_cy_auto_dir_smooth[num_freq_bands] + p_cy_auto_diff_smooth[num_freq_bands];
1315 : }
1316 43899 : subtract_power_y = masa_stereo_type_detect->subtract_power_y;
1317 :
1318 43899 : a = 0.0004f; /* Temporal smoothing coefficient */
1319 43899 : b = 1.0f - a; /* Temporal smoothing coefficient */
1320 :
1321 43899 : masa_stereo_type_detect->target_power_y_smooth = a * target_power_y + b * masa_stereo_type_detect->target_power_y_smooth;
1322 43899 : masa_stereo_type_detect->subtract_power_y_smooth = a * subtract_power_y + b * masa_stereo_type_detect->subtract_power_y_smooth;
1323 :
1324 43899 : subtract_target_ratio = masa_stereo_type_detect->subtract_power_y_smooth / ( masa_stereo_type_detect->target_power_y_smooth + EPSILON );
1325 43899 : subtract_target_ratio_db = 10.0f * log10f( subtract_target_ratio );
1326 43899 : masa_stereo_type_detect->subtract_target_ratio_db = subtract_target_ratio_db;
1327 :
1328 43899 : masa_stereo_type_detect->subtract_power_y = 0.0f;
1329 : }
1330 :
1331 : /*-----------------------------------------------------------------*
1332 : * compute smoothing coefficients
1333 : *-----------------------------------------------------------------*/
1334 :
1335 272022 : alpha_synthesis = h_dirac_output_synthesis_params->alpha_synthesis;
1336 272022 : alpha_synthesis_fast = h_dirac_output_synthesis_params->alpha_synthesis_fast;
1337 272022 : alphaMaxBin = h_dirac_output_synthesis_params->numAlphas - 1;
1338 272022 : alphaMaxBinFast = h_dirac_output_synthesis_params->numAlphasFast - 1;
1339 :
1340 15797742 : 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 15525720 : float alpha_quality_based = 0.02f;
1346 :
1347 15525720 : indexSlow = min( l, alphaMaxBin );
1348 15525720 : indexFast = min( l, alphaMaxBinFast );
1349 :
1350 : /* Estimate the smoothness of the directions based on the diffuseness parameter */
1351 15525720 : instDirectionSmoothness = 1.0f - diffuseness_vector[l];
1352 15525720 : instDirectionSmoothness = min( max( instDirectionSmoothness, 0.0f ), 1.0f );
1353 :
1354 : /* Average the direction smoothness parameter over time */
1355 15525720 : currWeight = DIRECTION_SMOOTHNESS_ALPHA * reference_power_smooth[l];
1356 15525720 : prevWeight = ( 1.0f - DIRECTION_SMOOTHNESS_ALPHA ) * h_dirac_output_synthesis_state->reference_power_smooth_prev[l];
1357 :
1358 15525720 : weightedDirectionSmoothness = currWeight * instDirectionSmoothness + prevWeight * h_dirac_output_synthesis_state->direction_smoothness_prev[l];
1359 15525720 : sumWeight = currWeight + prevWeight;
1360 15525720 : smoothedDirectionSmoothness = weightedDirectionSmoothness / ( sumWeight + EPSILON );
1361 :
1362 15525720 : h_dirac_output_synthesis_state->direction_smoothness_prev[l] = smoothedDirectionSmoothness;
1363 15525720 : 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 15525720 : alpha[l] = smoothedDirectionSmoothness * alpha_synthesis_fast[indexFast] + ( 1.0f - smoothedDirectionSmoothness ) * alpha_synthesis[indexSlow];
1367 :
1368 : /* Adjust smoothing parameter based on encoding quality */
1369 15525720 : 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 272022 : p_power_smooth_prev = h_dirac_output_synthesis_state->proto_power_smooth_prev;
1378 272022 : p_power_smooth = h_dirac_output_synthesis_state->proto_power_smooth;
1379 :
1380 1103223 : for ( k = 0; k < num_protos_dir; k++ )
1381 : {
1382 49303761 : for ( l = 0; l < num_freq_bands; l++ )
1383 : {
1384 48472560 : g1 = alpha[l];
1385 48472560 : g2 = ( 1.f - g1 );
1386 48472560 : *p_power_smooth_prev = EPSILON + g2 * ( *p_power_smooth_prev );
1387 48472560 : *( p_power_smooth_prev ) += g1 * ( *p_power_smooth );
1388 48472560 : *( p_power_smooth++ ) = 1.f / ( *( p_power_smooth_prev++ ) );
1389 : }
1390 : }
1391 :
1392 : /*Direct gains and diffuse gains on number of output channels*/
1393 272022 : p_power_diff_smooth_prev = h_dirac_output_synthesis_state->proto_power_diff_smooth_prev;
1394 272022 : p_power_smooth_diff = h_dirac_output_synthesis_state->proto_power_diff_smooth;
1395 :
1396 272022 : p_gains_diff = gains_diff;
1397 272022 : p_gains_dir = gains_dir;
1398 :
1399 272022 : p_cy_auto_dir_smooth = h_dirac_output_synthesis_state->cy_auto_dir_smooth;
1400 272022 : p_cy_auto_dir_smooth_prev = h_dirac_output_synthesis_state->cy_auto_dir_smooth_prev;
1401 272022 : p_cy_cross_dir_smooth = h_dirac_output_synthesis_state->cy_cross_dir_smooth;
1402 272022 : p_cy_cross_dir_smooth_prev = h_dirac_output_synthesis_state->cy_cross_dir_smooth_prev;
1403 :
1404 272022 : p_cy_auto_diff_smooth = h_dirac_output_synthesis_state->cy_auto_diff_smooth;
1405 272022 : p_cy_auto_diff_smooth_prev = h_dirac_output_synthesis_state->cy_auto_diff_smooth_prev;
1406 2193519 : for ( k = 0; k < nchan_out_woLFE; k++ )
1407 : {
1408 1921497 : p_power_smooth = h_dirac_output_synthesis_state->proto_power_smooth + proto_direct_index[k] * num_freq_bands;
1409 24308997 : for ( l = 0; l < h_dirac_output_synthesis_params->max_band_decorr; l++ )
1410 : {
1411 : /*Direct*/
1412 22387500 : g1 = alpha[l];
1413 22387500 : g2 = 1.f - g1;
1414 22387500 : *( p_cy_auto_dir_smooth_prev ) = g1 * ( *( p_cy_auto_dir_smooth++ ) ) + g2 * ( *( p_cy_auto_dir_smooth_prev ) );
1415 22387500 : *( p_cy_cross_dir_smooth_prev ) = g1 * ( *( p_cy_cross_dir_smooth++ ) ) + g2 * ( *( p_cy_cross_dir_smooth_prev ) );
1416 :
1417 22387500 : *( p_gains_dir ) = sqrtf( *( p_power_smooth++ ) * ( *( p_cy_auto_dir_smooth_prev++ ) ) );
1418 :
1419 22387500 : if ( *( p_gains_dir ) < 0.f )
1420 : {
1421 0 : *( p_gains_dir ) = 0.f;
1422 : }
1423 22387500 : else if ( *( p_gains_dir ) > DIRAC_GAIN_LIMIT )
1424 : {
1425 56886 : *( p_gains_dir ) = DIRAC_GAIN_LIMIT;
1426 : }
1427 :
1428 22387500 : if ( *( p_cy_cross_dir_smooth_prev++ ) < 0 )
1429 : {
1430 2416618 : *( p_gains_dir ) *= -1.f;
1431 : }
1432 22387500 : p_gains_dir++;
1433 :
1434 : /*diffuse*/
1435 22387500 : *p_power_diff_smooth_prev = g1 * ( *p_power_smooth_diff++ ) + g2 * ( *p_power_diff_smooth_prev ) + EPSILON;
1436 22387500 : *( p_cy_auto_diff_smooth_prev ) = g1 * ( *( p_cy_auto_diff_smooth++ ) ) + g2 * ( *( p_cy_auto_diff_smooth_prev ) );
1437 :
1438 22387500 : *( p_gains_diff ) = sqrtf( *( p_cy_auto_diff_smooth_prev++ ) / ( *( p_power_diff_smooth_prev++ ) ) );
1439 :
1440 22387500 : if ( *( p_gains_diff ) < 0.f )
1441 : {
1442 0 : *( p_gains_diff ) = 0.f;
1443 : }
1444 22387500 : else if ( *( p_gains_diff ) > DIRAC_GAIN_LIMIT )
1445 : {
1446 516467 : *( p_gains_diff ) = DIRAC_GAIN_LIMIT;
1447 : }
1448 22387500 : p_gains_diff++;
1449 : }
1450 :
1451 : /*Only direct prototype*/
1452 90717417 : for ( ; l < num_freq_bands; l++ )
1453 : {
1454 : /*Direct*/
1455 88795920 : g1 = alpha[l];
1456 88795920 : g2 = 1.f - g1;
1457 88795920 : *( p_cy_auto_dir_smooth_prev ) = g1 * ( *( p_cy_auto_dir_smooth++ ) ) + g2 * ( *( p_cy_auto_dir_smooth_prev ) );
1458 88795920 : *( p_cy_cross_dir_smooth_prev ) = g1 * ( *( p_cy_cross_dir_smooth++ ) ) + g2 * ( *( p_cy_cross_dir_smooth_prev ) );
1459 :
1460 88795920 : *( p_gains_dir ) = sqrtf( *( p_power_smooth ) * ( *( p_cy_auto_dir_smooth_prev++ ) ) );
1461 :
1462 88795920 : if ( *( p_gains_dir ) < 0.f )
1463 : {
1464 0 : *( p_gains_dir ) = 0.f;
1465 : }
1466 88795920 : else if ( *( p_gains_dir ) > DIRAC_GAIN_LIMIT )
1467 : {
1468 172134 : *( p_gains_dir ) = DIRAC_GAIN_LIMIT;
1469 : }
1470 :
1471 88795920 : if ( *( p_cy_cross_dir_smooth_prev++ ) < 0 )
1472 : {
1473 6310485 : *( p_gains_dir ) *= -1.f;
1474 : }
1475 88795920 : p_gains_dir++;
1476 :
1477 : /*diffuse*/
1478 88795920 : *( p_cy_auto_diff_smooth_prev ) = g1 * ( *( p_cy_auto_diff_smooth++ ) ) + g2 * ( *( p_cy_auto_diff_smooth_prev ) );
1479 88795920 : *( p_gains_diff ) = sqrtf( *( p_power_smooth++ ) * ( *( p_cy_auto_diff_smooth_prev++ ) ) );
1480 88795920 : if ( *( p_gains_diff ) < 0.f )
1481 : {
1482 0 : *( p_gains_diff ) = 0.f;
1483 : }
1484 88795920 : else if ( *( p_gains_diff ) > DIRAC_GAIN_LIMIT )
1485 : {
1486 184695 : *( p_gains_diff ) = DIRAC_GAIN_LIMIT;
1487 : }
1488 88795920 : p_gains_diff++;
1489 : }
1490 : }
1491 :
1492 : /*-----------------------------------------------------------------*
1493 : * gain interpolation and output streams
1494 : *-----------------------------------------------------------------*/
1495 :
1496 1346724 : for ( buf_idx = 0; buf_idx < nbslots; ++buf_idx )
1497 : {
1498 1074702 : g1 = h_dirac_output_synthesis_params->interpolator[buf_idx];
1499 1074702 : g2 = 1.f - g1;
1500 :
1501 : /*Direct stream*/
1502 1074702 : p_gain_1 = gains_dir;
1503 1074702 : p_gain_2 = h_dirac_output_synthesis_state->gains_dir_prev;
1504 8730600 : for ( k = 0; k < nchan_out_woLFE; k++ )
1505 : {
1506 7655898 : 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 450757758 : for ( l = 0; l < num_freq_bands; l++ )
1508 : {
1509 443101860 : g = g1 * ( *( p_gain_1++ ) ) + g2 * ( *( p_gain_2++ ) );
1510 443101860 : RealBuffer[k][buf_idx][l] = g * ( *( p_power_smooth++ ) );
1511 443101860 : ImagBuffer[k][buf_idx][l] = g * ( *( p_power_smooth++ ) );
1512 : }
1513 : }
1514 :
1515 : /*Diffuse stream*/
1516 1074702 : if ( h_dirac_output_synthesis_params->max_band_decorr != 0 )
1517 : {
1518 807225 : 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 1074702 : p_gain_1 = gains_diff;
1521 1074702 : p_gain_2 = h_dirac_output_synthesis_state->gains_diff_prev;
1522 8730600 : for ( k = 0; k < nchan_out_woLFE; k++ )
1523 : {
1524 96886533 : for ( l = 0; l < h_dirac_output_synthesis_params->max_band_decorr; l++ )
1525 : {
1526 89230635 : g = g1 * ( *( p_gain_1++ ) ) + g2 * ( *( p_gain_2++ ) );
1527 89230635 : RealBuffer[k][buf_idx][l] += g * ( *( p_power_smooth_diff++ ) );
1528 89230635 : ImagBuffer[k][buf_idx][l] += g * ( *( p_power_smooth_diff++ ) );
1529 : }
1530 :
1531 : /*Direct proto*/
1532 7655898 : 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 361527123 : for ( ; l < num_freq_bands; l++ )
1534 : {
1535 353871225 : g = g1 * ( *( p_gain_1++ ) ) + g2 * ( *( p_gain_2++ ) );
1536 353871225 : RealBuffer[k][buf_idx][l] += g * ( *( p_power_smooth++ ) );
1537 353871225 : 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 272022 : mvr2r( gains_dir, h_dirac_output_synthesis_state->gains_dir_prev, num_freq_bands * nchan_out_woLFE );
1548 272022 : mvr2r( gains_diff, h_dirac_output_synthesis_state->gains_diff_prev, num_freq_bands * nchan_out_woLFE );
1549 :
1550 : /* reset values */
1551 272022 : set_zero( h_dirac_output_synthesis_state->proto_power_smooth, num_freq_bands * num_protos_dir );
1552 :
1553 272022 : if ( h_dirac_output_synthesis_state->proto_power_diff_smooth != NULL )
1554 : {
1555 272022 : 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 272022 : set_zero( h_dirac_output_synthesis_state->cy_auto_dir_smooth, num_freq_bands * nchan_out_woLFE );
1559 272022 : set_zero( h_dirac_output_synthesis_state->cy_cross_dir_smooth, num_freq_bands * nchan_out_woLFE );
1560 272022 : set_zero( h_dirac_output_synthesis_state->cy_auto_diff_smooth, num_freq_bands * nchan_out_woLFE );
1561 :
1562 272022 : pop_wmops();
1563 :
1564 272022 : return;
1565 : }
1566 :
1567 :
1568 : /*-------------------------------------------------------------------------
1569 : * ivas_dirac_dec_compute_directional_responses()
1570 : *
1571 : *
1572 : *------------------------------------------------------------------------*/
1573 :
1574 3324024 : 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 3324024 : azimuth2 = NULL;
1602 3324024 : elevation2 = NULL;
1603 3324024 : transport_signal_type = MASA_STEREO_NOT_DEFINED;
1604 :
1605 3324024 : if ( hDirACRend->masa_stereo_type_detect != NULL )
1606 : {
1607 43899 : dipole_freq_range[0] = hDirACRend->masa_stereo_type_detect->dipole_freq_range[0];
1608 43899 : dipole_freq_range[1] = hDirACRend->masa_stereo_type_detect->dipole_freq_range[1];
1609 43899 : transport_signal_type = hDirACRend->masa_stereo_type_detect->masa_stereo_type;
1610 : }
1611 :
1612 3324024 : num_channels_dir = hDirACRend->num_outputs_dir;
1613 3324024 : if ( hSpatParamRendCom->numParametricDirections == 2 )
1614 : {
1615 847032 : azimuth2 = hSpatParamRendCom->azimuth2[md_idx];
1616 847032 : elevation2 = hSpatParamRendCom->elevation2[md_idx];
1617 : }
1618 :
1619 3324024 : codingBand = -1;
1620 :
1621 3324024 : assert( num_channels_dir <= MAX_OUTPUT_CHANNELS && "Number of channels is too high" );
1622 :
1623 182773764 : for ( k = 0; k < hSpatParamRendCom->num_freq_bands; ++k )
1624 : {
1625 179449740 : if ( masa_band_mapping != NULL && k == MASA_band_grouping_24[masa_band_mapping[codingBand + 1]] )
1626 : {
1627 2796219 : codingBand++;
1628 : }
1629 :
1630 179449740 : if ( masa_band_mapping != NULL && k > MASA_band_grouping_24[masa_band_mapping[codingBand]] &&
1631 12198681 : k < MASA_band_grouping_24[masa_band_mapping[codingBand + 1]] &&
1632 12198681 : 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 12154695 : if ( hDirACRend->synthesisConf != DIRAC_SYNTHESIS_GAIN_SHD )
1636 : {
1637 10509828 : mvr2r_inc( &hDirACRend->h_output_synthesis_psd_state.direct_responses_square[k - 1],
1638 10509828 : hSpatParamRendCom->num_freq_bands, &hDirACRend->h_output_synthesis_psd_state.direct_responses_square[k],
1639 10509828 : hSpatParamRendCom->num_freq_bands, num_channels_dir );
1640 : }
1641 12154695 : mvr2r_inc( &hDirACRend->h_output_synthesis_psd_state.direct_responses[k - 1],
1642 12154695 : hSpatParamRendCom->num_freq_bands,
1643 12154695 : &hDirACRend->h_output_synthesis_psd_state.direct_responses[k],
1644 12154695 : hSpatParamRendCom->num_freq_bands, num_channels_dir );
1645 : }
1646 : else
1647 : {
1648 : /* HOA3 PANNING */
1649 167295045 : if ( hDirACRend->panningConf == DIRAC_PANNING_HOA3 )
1650 : {
1651 155533407 : set_f( direct_response_hoa, 1.0f, MAX_OUTPUT_CHANNELS );
1652 155533407 : set_f( direct_response_dir2, 1.0f, MAX_OUTPUT_CHANNELS );
1653 :
1654 155533407 : ivas_dirac_dec_get_response( azimuth[k], elevation[k], direct_response_hoa, hDirACRend->hOutSetup.ambisonics_order );
1655 :
1656 155533407 : if ( hodirac_flag )
1657 : {
1658 48048000 : ivas_dirac_dec_get_response( azimuth2[k], elevation2[k], direct_response_dir2, hDirACRend->hOutSetup.ambisonics_order );
1659 : }
1660 :
1661 155533407 : if ( masa_band_mapping == NULL && hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD )
1662 : {
1663 154377720 : mvr2r_inc( direct_response_hoa, 1, &hDirACRend->h_output_synthesis_psd_state.direct_responses[k], hSpatParamRendCom->num_freq_bands, num_channels_dir );
1664 :
1665 154377720 : if ( hodirac_flag )
1666 : {
1667 48048000 : 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 1155687 : else if ( ( ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) && ( masa_band_mapping != NULL ) ) ||
1671 812094 : hDirACRend->synthesisConf == DIRAC_SYNTHESIS_PSD_SHD || hDirACRend->synthesisConf == DIRAC_SYNTHESIS_MONO )
1672 : {
1673 : /* Synthesize the first direction */
1674 1155687 : 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 1155687 : if ( hSpatParamRendCom->numParametricDirections == 2 )
1678 : {
1679 249900 : 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 249900 : totalDirect = hSpatParamRendCom->energy_ratio1[md_idx][k] + hSpatParamRendCom->energy_ratio2[md_idx][k] + EPSILON;
1682 249900 : directRatio[0] = hSpatParamRendCom->energy_ratio1[md_idx][k] / totalDirect;
1683 249900 : directRatio[1] = hSpatParamRendCom->energy_ratio2[md_idx][k] / totalDirect;
1684 2113500 : for ( l = 0; l < num_channels_dir; l++ )
1685 : {
1686 1863600 : direct_response_hoa[l] *= directRatio[0];
1687 1863600 : direct_response_hoa[l] += directRatio[1] * direct_response_dir2[l];
1688 : }
1689 : }
1690 :
1691 1155687 : 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 25992 : set_zero( direct_response_ism, num_channels_dir );
1700 :
1701 129960 : for ( dir = 0; dir < hSpatParamRendCom->numIsmDirections; dir++ )
1702 : {
1703 103968 : 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 103968 : 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 1077696 : for ( l = 0; l < num_channels_dir; l++ )
1713 : {
1714 973728 : direct_response_ism[l] += direct_response_temp[l] * hMasaIsm->energy_ratio_ism[dir][md_idx][k];
1715 : }
1716 : }
1717 :
1718 25992 : masaDirect = hSpatParamRendCom->energy_ratio1[md_idx][k] + EPSILON;
1719 25992 : if ( hSpatParamRendCom->numParametricDirections == 2 )
1720 : {
1721 0 : masaDirect += hSpatParamRendCom->energy_ratio2[md_idx][k];
1722 : }
1723 :
1724 25992 : ismDirect = hMasaIsm->energy_ratio_ism[0][md_idx][k];
1725 103968 : for ( dir = 1; dir < hSpatParamRendCom->numIsmDirections; dir++ )
1726 : {
1727 77976 : ismDirect += hMasaIsm->energy_ratio_ism[dir][md_idx][k];
1728 : }
1729 :
1730 25992 : totalDirect = masaDirect + ismDirect;
1731 25992 : directRatio[0] = masaDirect / totalDirect;
1732 25992 : directRatio[1] = ismDirect / totalDirect;
1733 269424 : for ( l = 0; l < num_channels_dir; l++ )
1734 : {
1735 243432 : direct_response_hoa[l] *= directRatio[0];
1736 243432 : direct_response_hoa[l] += directRatio[1] * direct_response_ism[l];
1737 : }
1738 : }
1739 :
1740 : /* Synthesize surrounding coherence */
1741 1155687 : if ( surCohRatio != NULL && surCohRatio[k] > 0.f )
1742 : {
1743 4509667 : for ( l = 1; l < num_channels_dir; l++ )
1744 : {
1745 3791041 : direct_response_hoa[l] *= sqrtf( 1.0f - surCohRatio[k] );
1746 : }
1747 : }
1748 :
1749 : /* Set computed gains */
1750 1155687 : direct_response = direct_response_hoa;
1751 1155687 : if ( hDirACRend->synthesisConf != DIRAC_SYNTHESIS_GAIN_SHD )
1752 : {
1753 812094 : v_mult( direct_response, direct_response, direct_response_square, num_channels_dir );
1754 812094 : 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 812094 : if ( transport_signal_type == MASA_STEREO_SPACED_MICS )
1757 : {
1758 91905 : direct_response[0] = 1.0f;
1759 91905 : if ( k >= dipole_freq_range[0] && k < dipole_freq_range[1] )
1760 : {
1761 11667 : direct_response[1] = 1.0f;
1762 : }
1763 : }
1764 : else
1765 : {
1766 720189 : set_f( direct_response, 1.0f, hDirACRend->num_protos_ambi );
1767 : }
1768 : }
1769 :
1770 1155687 : 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 11761638 : else if ( hDirACRend->panningConf == DIRAC_PANNING_VBAP ) /*VBAP*/
1778 : {
1779 : /* Synthesize the first direction */
1780 11761638 : spreadCoherencePanningVbap( azimuth[k], elevation[k], hSpatParamRendCom->spreadCoherence[md_idx][k], direct_response_ls, num_channels_dir, hVBAPdata );
1781 11761638 : normalizePanningGains( direct_response_ls, num_channels_dir );
1782 :
1783 : /* Synthesize the second direction and combine the gains */
1784 11761638 : if ( hSpatParamRendCom->numParametricDirections == 2 )
1785 : {
1786 555168 : spreadCoherencePanningVbap( azimuth2[k], elevation2[k], hSpatParamRendCom->spreadCoherence2[md_idx][k], direct_response_dir2, num_channels_dir, hVBAPdata );
1787 555168 : normalizePanningGains( direct_response_dir2, num_channels_dir );
1788 :
1789 : /* Combine gains from the two directions */
1790 555168 : totalDirect = hSpatParamRendCom->energy_ratio1[md_idx][k] + hSpatParamRendCom->energy_ratio2[md_idx][k] + EPSILON;
1791 555168 : directRatio[0] = hSpatParamRendCom->energy_ratio1[md_idx][k] / totalDirect;
1792 555168 : directRatio[1] = hSpatParamRendCom->energy_ratio2[md_idx][k] / totalDirect;
1793 5422704 : for ( l = 0; l < num_channels_dir; l++ )
1794 : {
1795 4867536 : direct_response_ls[l] *= directRatio[0];
1796 4867536 : direct_response_ls[l] += directRatio[1] * direct_response_dir2[l];
1797 : }
1798 555168 : normalizePanningGains( direct_response_ls, num_channels_dir );
1799 : }
1800 :
1801 11761638 : 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 27915 : set_zero( direct_response_ism, num_channels_dir );
1810 :
1811 108075 : for ( dir = 0; dir < hSpatParamRendCom->numIsmDirections; dir++ )
1812 : {
1813 80160 : 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 80160 : vbap_determine_gains( hVBAPdata, direct_response_temp, hMasaIsm->azimuth_ism[dir][md_idx], hMasaIsm->elevation_ism[dir][md_idx], 1 );
1820 : }
1821 :
1822 741072 : for ( l = 0; l < num_channels_dir; l++ )
1823 : {
1824 660912 : direct_response_ism[l] += direct_response_temp[l] * hMasaIsm->energy_ratio_ism[dir][md_idx][k];
1825 : }
1826 : }
1827 27915 : normalizePanningGains( direct_response_ism, num_channels_dir );
1828 :
1829 27915 : masaDirect = hSpatParamRendCom->energy_ratio1[md_idx][k] + EPSILON;
1830 27915 : if ( hSpatParamRendCom->numParametricDirections == 2 )
1831 : {
1832 9000 : masaDirect += hSpatParamRendCom->energy_ratio2[md_idx][k];
1833 : }
1834 :
1835 27915 : ismDirect = hMasaIsm->energy_ratio_ism[0][md_idx][k];
1836 80160 : for ( dir = 1; dir < hSpatParamRendCom->numIsmDirections; dir++ )
1837 : {
1838 52245 : ismDirect += hMasaIsm->energy_ratio_ism[dir][md_idx][k];
1839 : }
1840 :
1841 27915 : totalDirect = masaDirect + ismDirect;
1842 27915 : directRatio[0] = masaDirect / totalDirect;
1843 27915 : directRatio[1] = ismDirect / totalDirect;
1844 256584 : for ( l = 0; l < num_channels_dir; l++ )
1845 : {
1846 228669 : direct_response_ls[l] *= directRatio[0];
1847 228669 : direct_response_ls[l] += directRatio[1] * direct_response_ism[l];
1848 : }
1849 27915 : normalizePanningGains( direct_response_ls, num_channels_dir );
1850 : }
1851 :
1852 : /* Synthesize surrounding coherence */
1853 11761638 : if ( surCohRatio != NULL && surCohRatio[k] > 0.f )
1854 : {
1855 : int16_t num_channels_surrCoh;
1856 :
1857 985315 : num_channels_surrCoh = num_channels_dir;
1858 985315 : num_channels_surrCoh -= hDirACRend->num_ele_spk_no_diffuse_rendering;
1859 :
1860 8865994 : for ( l = 0; l < num_channels_dir; l++ )
1861 : {
1862 7880679 : direct_response_ls[l] *= sqrtf( 1.0f - surCohRatio[k] );
1863 7880679 : if ( hDirACRend->diffuse_response_function[l] > 0.f )
1864 : {
1865 7847079 : direct_response_ls[l] += sqrtf( surCohRatio[k] / (float) num_channels_surrCoh );
1866 : }
1867 : }
1868 : }
1869 :
1870 11761638 : normalizePanningGains( direct_response_ls, num_channels_dir );
1871 :
1872 : /* Set computed gains */
1873 11761638 : direct_response = direct_response_ls;
1874 11761638 : v_mult( direct_response, direct_response, direct_response_square, num_channels_dir );
1875 11761638 : mvr2r_inc( direct_response_square, 1, &hDirACRend->h_output_synthesis_psd_state.direct_responses_square[k], hSpatParamRendCom->num_freq_bands, num_channels_dir );
1876 11761638 : 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 3324024 : return;
1886 : }
1887 :
1888 :
1889 : /*-------------------------------------------------------------------------
1890 : * ivas_dirac_dec_compute_gain_factors()
1891 : *
1892 : *
1893 : *------------------------------------------------------------------------*/
1894 :
1895 2279958 : 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 14243145 : for ( i = 0; i < max_band_decorr; i++ )
1905 : {
1906 11963187 : direct_gain_factor[i] = sqrtf( 1.f - diffuseness[i] );
1907 11963187 : diffuse_gain_factor[i] = sqrtf( diffuseness[i] );
1908 : }
1909 108244551 : for ( ; i < num_freq_bands; i++ )
1910 : {
1911 105964593 : direct_gain_factor[i] = sqrtf( 1.f - diffuseness[i] );
1912 105964593 : diffuse_gain_factor[i] = sqrtf( diffuseness[i] );
1913 : }
1914 :
1915 2279958 : return;
1916 : }
1917 :
1918 :
1919 : /*-------------------------------------------------------------------------
1920 : * ivas_dirac_dec_compute_power_factors()
1921 : *
1922 : *
1923 : *------------------------------------------------------------------------*/
1924 :
1925 397986 : 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 397986 : v_multc( diffuseness, -1.0f, direct_power_factor, num_freq_bands );
1933 :
1934 397986 : v_addc( direct_power_factor, 1.0f, direct_power_factor, num_freq_bands );
1935 :
1936 397986 : mvr2r( diffuseness, diffuse_power_factor, num_freq_bands );
1937 :
1938 397986 : 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 397986 : 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 397986 : return;
1943 : }
1944 :
1945 :
1946 : /*-------------------------------------------------------------------------
1947 : * ivas_lfe_synth_with_filters()
1948 : *
1949 : *
1950 : *------------------------------------------------------------------------*/
1951 :
1952 582 : 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 582 : delay = hMasaLfeSynth->delayBuffer_syncDirAC_size;
1975 582 : 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 582 : lowpassCoef = 1.0f / ( (float) hMasaLfeSynth->ringBufferSize );
1979 540102 : for ( i = 0; i < output_frame; i++ )
1980 : {
1981 539520 : hMasaLfeSynth->lowpassSum += lowpassCoef * data_f[separateChannelIndex][i] - lowpassCoef * hMasaLfeSynth->lfeSynthRingBuffer[hMasaLfeSynth->ringBufferLoPointer];
1982 539520 : lowPassSignal[i] = hMasaLfeSynth->lowpassSum;
1983 539520 : highPassSignal[i] = hMasaLfeSynth->lfeSynthRingBuffer[hMasaLfeSynth->ringBufferHiPointer] - lowPassSignal[i];
1984 539520 : hMasaLfeSynth->lfeSynthRingBuffer[hMasaLfeSynth->ringBufferLoPointer] = data_f[separateChannelIndex][i];
1985 :
1986 539520 : hMasaLfeSynth->ringBufferLoPointer--;
1987 539520 : if ( hMasaLfeSynth->ringBufferLoPointer < 0 )
1988 : {
1989 2328 : hMasaLfeSynth->ringBufferLoPointer = hMasaLfeSynth->ringBufferSize - 1;
1990 : }
1991 :
1992 539520 : hMasaLfeSynth->ringBufferHiPointer--;
1993 539520 : if ( hMasaLfeSynth->ringBufferHiPointer < 0 )
1994 : {
1995 2328 : hMasaLfeSynth->ringBufferHiPointer = hMasaLfeSynth->ringBufferSize - 1;
1996 : }
1997 : }
1998 :
1999 : /* Synthesize the LFE signal */
2000 582 : slotSize = output_frame / CLDFB_NO_COL_MAX;
2001 9894 : for ( slot_index = 0; slot_index < CLDFB_NO_COL_MAX; slot_index++ )
2002 : {
2003 9312 : subframe_index = slot_index / 4;
2004 :
2005 9312 : mrange[0] = slot_index * slotSize;
2006 9312 : mrange[1] = ( slot_index + 1 ) * slotSize;
2007 :
2008 9312 : transportEne = 0.0f;
2009 548832 : for ( i = mrange[0]; i < mrange[1]; i++ )
2010 : {
2011 539520 : transportEne += lowPassSignal[i] * lowPassSignal[i];
2012 : }
2013 :
2014 9312 : targetEneLfe = transportEne * hMasaLfeSynth->lfeToTotalEnergyRatio[subframe_index];
2015 9312 : targetEneTrans = transportEne * max( ( 1.0f - hMasaLfeSynth->lfeToTotalEnergyRatio[subframe_index] ), 0.01f );
2016 :
2017 9312 : hMasaLfeSynth->transportEneSmooth *= MCMASA_LFE_SYNTH_ALPHA;
2018 9312 : hMasaLfeSynth->targetEneLfeSmooth *= MCMASA_LFE_SYNTH_ALPHA;
2019 9312 : hMasaLfeSynth->targetEneTransSmooth *= MCMASA_LFE_SYNTH_ALPHA;
2020 :
2021 9312 : hMasaLfeSynth->transportEneSmooth += transportEne;
2022 9312 : hMasaLfeSynth->targetEneLfeSmooth += targetEneLfe;
2023 9312 : hMasaLfeSynth->targetEneTransSmooth += targetEneTrans;
2024 :
2025 9312 : lfeGain = min( 1.0f, sqrtf( hMasaLfeSynth->targetEneLfeSmooth / ( EPSILON + hMasaLfeSynth->transportEneSmooth ) ) );
2026 9312 : transportGain = min( 1.0f, sqrtf( hMasaLfeSynth->targetEneTransSmooth / ( EPSILON + hMasaLfeSynth->transportEneSmooth ) ) );
2027 :
2028 548832 : for ( i = mrange[0], j = 0; i < mrange[1]; i++, j++ )
2029 : {
2030 539520 : data_f[separateChannelIndex][i] = ( transportGain * hMasaLfeSynth->interpolator[j] + hMasaLfeSynth->transportGainPrev * ( 1.0f - hMasaLfeSynth->interpolator[j] ) ) * lowPassSignal[i] + highPassSignal[i];
2031 539520 : data_f[lfeChannelIndex][i] = ( lfeGain * hMasaLfeSynth->interpolator[j] + hMasaLfeSynth->lfeGainPrev * ( 1.0f - hMasaLfeSynth->interpolator[j] ) ) * lowPassSignal[i];
2032 : }
2033 :
2034 9312 : hMasaLfeSynth->lfeGainPrev = lfeGain;
2035 9312 : hMasaLfeSynth->transportGainPrev = transportGain;
2036 : }
2037 :
2038 : /* Lowpass filter for removing remaining mid and high frequencies from the LFE signal */
2039 582 : lowpassCoef = 1.0f / ( (float) hMasaLfeSynth->ringBufferSize2 );
2040 540102 : for ( i = 0; i < output_frame; i++ )
2041 : {
2042 539520 : hMasaLfeSynth->lowpassSum2 += lowpassCoef * data_f[lfeChannelIndex][i] - lowpassCoef * hMasaLfeSynth->lfeSynthRingBuffer2[hMasaLfeSynth->ringBufferLoPointer2];
2043 539520 : hMasaLfeSynth->lfeSynthRingBuffer2[hMasaLfeSynth->ringBufferLoPointer2] = data_f[lfeChannelIndex][i];
2044 :
2045 539520 : hMasaLfeSynth->ringBufferLoPointer2--;
2046 539520 : if ( hMasaLfeSynth->ringBufferLoPointer2 < 0 )
2047 : {
2048 4656 : hMasaLfeSynth->ringBufferLoPointer2 = hMasaLfeSynth->ringBufferSize2 - 1;
2049 : }
2050 :
2051 539520 : data_f[lfeChannelIndex][i] = hMasaLfeSynth->lowpassSum2;
2052 : }
2053 :
2054 : /* Delay the separated channel to match the delay of the lowpass filter */
2055 582 : delay = hMasaLfeSynth->delayBuffer_syncLp_size;
2056 582 : delay_signal( data_f[separateChannelIndex], output_frame, hMasaLfeSynth->delayBuffer_syncLp, delay );
2057 :
2058 582 : return;
2059 : }
2060 :
2061 :
2062 : /*-------------------------------------------------------------------------
2063 : * Local functions
2064 : *------------------------------------------------------------------------*/
2065 :
2066 167952 : 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 167952 : 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 1775616 : for ( ch_idx = 0; ch_idx < num_channels; ++ch_idx )
2087 : {
2088 1607664 : cur_idx = ch_idx * num_freq_bands;
2089 :
2090 1607664 : v_mult( direct_power, &direct_responses_square[cur_idx], aux_buffer_res, num_freq_bands );
2091 1607664 : v_add( &cy_auto_dir_smooth[cur_idx], aux_buffer_res, &cy_auto_dir_smooth[cur_idx], num_freq_bands );
2092 :
2093 1607664 : v_mult( direct_power, &direct_responses[cur_idx], aux_buffer_res, num_freq_bands );
2094 1607664 : v_add( &cy_cross_dir_smooth[cur_idx], aux_buffer_res, &cy_cross_dir_smooth[cur_idx], num_freq_bands );
2095 : }
2096 :
2097 167952 : return;
2098 : }
2099 :
2100 :
2101 230034 : 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 230034 : 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 1776696 : for ( ch_idx = 0; ch_idx < num_channels; ++ch_idx )
2121 : {
2122 1546662 : cur_idx = ch_idx * num_freq_bands;
2123 :
2124 1546662 : v_mult( direct_power, &direct_responses_square[cur_idx], &cy_auto_dir_smooth[cur_idx], num_freq_bands );
2125 1546662 : v_mult( direct_power, &direct_responses[cur_idx], &cy_cross_dir_smooth[cur_idx], num_freq_bands );
2126 : }
2127 :
2128 230034 : return;
2129 : }
2130 :
2131 :
2132 167952 : 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 167952 : 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 1775616 : for ( ch_idx = 0; ch_idx < num_channels; ++ch_idx )
2152 : {
2153 1607664 : cur_idx = ch_idx * num_freq_bands;
2154 1607664 : v_multc( &diffuse_power[start_band], diffuse_responses_square[ch_idx], aux_buffer_res, num_freq_bands - start_band );
2155 1607664 : 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 167952 : return;
2159 : }
2160 :
2161 :
2162 230034 : 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 230034 : 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 1776696 : for ( ch_idx = 0; ch_idx < num_channels; ++ch_idx )
2179 : {
2180 1546662 : cur_idx = ch_idx * num_freq_bands;
2181 :
2182 1546662 : 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 230034 : return;
2186 : }
2187 :
2188 :
2189 621939 : 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 621939 : 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 5112480 : for ( ch_idx = 0; ch_idx < num_channels; ++ch_idx )
2211 : {
2212 4490541 : diffuse_response_p4 = diffuse_responses_square[ch_idx] * diffuse_responses_square[ch_idx];
2213 :
2214 4490541 : cur_idx = ch_idx * num_freq_bands;
2215 4490541 : diff_idx = proto_frame_diff_index[ch_idx] * num_freq_bands;
2216 :
2217 4490541 : v_multc( &onset_filter[diff_idx], diffuse_responses_square[ch_idx], aux_buffer_res1, num_decorr_freq_bands );
2218 4490541 : v_multc( &onset_filter[diff_idx], -1.0f, aux_buffer_res, num_decorr_freq_bands );
2219 4490541 : v_addc( aux_buffer_res, 1.0f, aux_buffer_res, num_decorr_freq_bands );
2220 4490541 : v_multc( aux_buffer_res, diffuse_response_p4, aux_buffer_res, num_decorr_freq_bands );
2221 4490541 : v_add( aux_buffer_res1, aux_buffer_res, aux_buffer_res, num_decorr_freq_bands );
2222 4490541 : v_mult( aux_buffer_res, diffuse_power, aux_buffer_res, num_decorr_freq_bands );
2223 4490541 : v_add( &cy_auto_diff_smooth[cur_idx], aux_buffer_res, &cy_auto_diff_smooth[cur_idx], num_decorr_freq_bands );
2224 : }
2225 :
2226 621939 : return;
2227 : }
2228 :
2229 8500 : 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 8500 : if ( alpha_synthesis == NULL )
2244 : {
2245 : #ifdef DEBUGGING
2246 : assert( !"Error: NULL pointer.\n" );
2247 : #endif
2248 0 : return;
2249 : }
2250 :
2251 8500 : if ( averaging_length_ms == 0 )
2252 : {
2253 0 : set_f( alpha_synthesis, 1.0f, num_freq_bands );
2254 : }
2255 : else
2256 : {
2257 34000 : for ( k = 0; k < num_freq_bands; k++ )
2258 : {
2259 34000 : int16_t faxis_idx = max( k, 1 );
2260 34000 : avg_length_f_ms = 1000.f * (float) averaging_length_ms / fabsf( frequency_axis[faxis_idx] );
2261 34000 : alpha_synthesis[k] = min( (float) slot_size / ( avg_length_f_ms * (float) output_Fs / 1000.f ), 1.0f );
2262 34000 : if ( alpha_synthesis[k] >= maxAlpha )
2263 : {
2264 8500 : alpha_synthesis[k] = maxAlpha;
2265 8500 : *numAlphas = k + 1;
2266 8500 : break;
2267 : }
2268 : }
2269 : }
2270 :
2271 8500 : return;
2272 : }
2273 :
2274 1405587 : 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 1405587 : ivas_dirac_dec_get_response( azimuth, elevation, direct_response, ambisonics_order );
2289 :
2290 1405587 : if ( spreadCoh > 0.f )
2291 : {
2292 763985 : ivas_dirac_dec_get_response( azimuth + 30, elevation, direct_response_left, ambisonics_order );
2293 :
2294 763985 : ivas_dirac_dec_get_response( azimuth + 330, elevation, direct_response_right, ambisonics_order );
2295 :
2296 763985 : if ( spreadCoh < 0.5f )
2297 : {
2298 753727 : gainCenter = ( 1.0f - 2.0f * spreadCoh ) + 2.0f * spreadCoh / 3.0f;
2299 753727 : gainSide = 2.0f * spreadCoh / 3.0f;
2300 : }
2301 : else
2302 : {
2303 10258 : gainSide = 1.0f / ( 4.0f - 2.0f * spreadCoh );
2304 10258 : gainCenter = ( 2.0f - 2.0f * spreadCoh ) * gainSide;
2305 : }
2306 :
2307 5820536 : for ( i = 0; i < num_channels_dir; i++ )
2308 : {
2309 5056551 : direct_response[i] = direct_response[i] * gainCenter + ( direct_response_left[i] + direct_response_right[i] ) * gainSide;
2310 : }
2311 : }
2312 :
2313 1405587 : return;
2314 : }
2315 :
2316 12316806 : 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 12316806 : 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 12316806 : vbap_determine_gains( hVBAPdata, direct_response, azimuth, elevation, 0 );
2339 :
2340 12316806 : if ( spreadCoh > 0.f )
2341 : {
2342 1270616 : vbap_determine_gains( hVBAPdata, direct_response_left, azimuth + 30, elevation, 0 );
2343 1270616 : vbap_determine_gains( hVBAPdata, direct_response_right, azimuth - 30, elevation, 0 );
2344 :
2345 1270616 : if ( spreadCoh < 0.5f )
2346 : {
2347 1239245 : gainCenter = ( 1.0f - 2.0f * spreadCoh ) + 2.0f * spreadCoh * INV_SQRT3;
2348 1239245 : gainSide = 2.0f * spreadCoh * INV_SQRT3;
2349 : }
2350 : else
2351 : {
2352 31371 : gainCenter = 2.0f - 2.0f * spreadCoh;
2353 31371 : gainSide = 1.0f;
2354 : }
2355 :
2356 11745980 : for ( i = 0; i < num_channels_dir; i++ )
2357 : {
2358 10475364 : direct_response[i] = direct_response[i] * gainCenter + ( direct_response_left[i] + direct_response_right[i] ) * gainSide;
2359 : }
2360 : }
2361 :
2362 12316806 : return;
2363 : }
2364 :
2365 :
2366 24689442 : 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 24689442 : energySum = sum2_f( direct_response, num_channels_dir ) + 1e-12f;
2375 24689442 : normVal = sqrtf( 1.0f / energySum );
2376 254113092 : for ( i = 0; i < num_channels_dir; i++ )
2377 : {
2378 229423650 : direct_response[i] *= normVal;
2379 : }
2380 :
2381 24689442 : return;
2382 : }
|