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 <stdint.h>
34 : #include <assert.h>
35 : #include <math.h>
36 : #include "options.h"
37 : #include "prot_fx.h"
38 : #include "rom_com.h"
39 : #include "ivas_rom_com.h"
40 : #include "wmc_auto.h"
41 : #include "ivas_prot_fx.h"
42 : #include "ivas_rom_com_fx.h"
43 :
44 :
45 : /*------------------------------------------------------------------------------------------*
46 : * Static functions declarations
47 : *------------------------------------------------------------------------------------------*/
48 : static void ivas_cmult_fix(
49 : Word32 in1_re, // i: Qx
50 : Word32 in1_im, // i: Qx
51 : Word32 in2_re, // i: Qx
52 : Word32 in2_im, // i: Qx
53 : Word32 *out1_re, // o: 2 * Qx - 31
54 : Word32 *out1_im // o: 2 * Qx - 31
55 : );
56 : static void ivas_get_active_bins_fx( const Word16 **pActive_bins, const Word16 **pActive_bins_abs, const Word16 **pStart_offset, const Word16 **pStart_offset_ab, const Word32 sampling_rate );
57 : static void ivas_get_ld_fb_resp_fx( Word32 **ppIdeal_FRs_re_fx, Word32 **ppIdeal_FRs_im_fx, Word32 **ppNew_FRs_re_fx, Word32 **ppNew_FRs_im_fx, const Word16 *pActive_bins, const Word16 *pStart_offset, const Word16 num_bands, const Word16 delay, const Word32 sampling_rate );
58 : static ivas_error ivas_filterbank_setup_fx( IVAS_FB_MIXER_HANDLE hFbMixer, const Word32 sampling_rate, Word16 *index );
59 : static ivas_error ivas_fb_mixer_get_window_fx( const Word16 fade_len, const Word32 sampling_rate, const Word16 **pWindow );
60 :
61 : /*-----------------------------------------------------------------------------------------*
62 : * Function ivas_get_num_bands_from_bw_idx()
63 : *
64 : * Get number of bands from BW index
65 : *-----------------------------------------------------------------------------------------*/
66 :
67 : /*! r: number of spectral bands */
68 388777 : Word16 ivas_get_num_bands_from_bw_idx(
69 : const Word16 bwidth /* i : audio bandwidth */
70 : )
71 : {
72 : Word16 num_active_bands;
73 :
74 388777 : assert( bwidth > 0 ); /*NB BW is not supported*/
75 388777 : num_active_bands = ivas_num_active_bands[sub( bwidth, 1 )];
76 388777 : move16();
77 :
78 388777 : return num_active_bands;
79 : }
80 :
81 :
82 : /*-----------------------------------------------------------------------------------------*
83 : * Function ivas_get_num_bands()
84 : *
85 : * Get number of bands depending on the sampling rates
86 : *-----------------------------------------------------------------------------------------*/
87 :
88 1128 : static Word16 ivas_get_num_bands(
89 : const Word32 sampling_rate )
90 : {
91 1128 : Word16 bwidth = ivas_get_bw_idx_from_sample_rate_fx( sampling_rate );
92 1128 : Word16 num_active_bands = ivas_get_num_bands_from_bw_idx( bwidth );
93 :
94 1128 : return num_active_bands;
95 : }
96 :
97 :
98 : /*---------------------------------------------------------------------*
99 : * Function ivas_fb_set_cfg()
100 : *
101 : * Set default configs for FB mixer
102 : *---------------------------------------------------------------------*/
103 :
104 4150 : ivas_error ivas_fb_set_cfg(
105 : IVAS_FB_CFG **pFb_cfg_out, /* o : FB config. handle */
106 : const Word16 ivas_format, /* i : IVAS format */
107 : const Word16 num_in_chans, /* i : number of FB input channels */
108 : const Word16 num_out_chans, /* i : number of FB output channels */
109 : const Word16 active_w_mixing, /* i : active_w_mixing flag */
110 : const Word32 sampling_rate, /* i : sampling rate */
111 : const Word16 nchan_fb_in /* i : number of dirAC analysis channels*/
112 : )
113 : {
114 : IVAS_FB_CFG *pFb_cfg;
115 :
116 4150 : IF( ( pFb_cfg = (IVAS_FB_CFG *) malloc( sizeof( IVAS_FB_CFG ) ) ) == NULL )
117 : {
118 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for FB mixer config" );
119 : }
120 :
121 4150 : pFb_cfg->num_in_chans = num_in_chans;
122 4150 : pFb_cfg->num_out_chans = num_out_chans;
123 4150 : pFb_cfg->nchan_fb_in = nchan_fb_in;
124 :
125 4150 : pFb_cfg->pcm_offset = 0; /* note: in SPAR decoder, this parameter is overwritten later */
126 4150 : pFb_cfg->active_w_mixing = active_w_mixing;
127 4150 : pFb_cfg->windowed_fr_offset = 0;
128 :
129 4150 : move16();
130 4150 : move16();
131 4150 : move16();
132 4150 : move16();
133 4150 : move16();
134 4150 : move16();
135 :
136 4150 : IF( EQ_16( ivas_format, ISM_FORMAT ) )
137 : {
138 320 : pFb_cfg->fb_latency = NS2SA_FX2( sampling_rate, DELAY_FB_4_NS );
139 320 : pFb_cfg->fade_len = NS2SA_FX2( sampling_rate, DELAY_FB_4_NS );
140 320 : pFb_cfg->prior_input_length = add( NS2SA_FX2( sampling_rate, DELAY_DIRAC_ENC_CMP_NS_PARAM_ISM ), NS2SA_FX2( sampling_rate, DIRAC_SLOT_ENC_NS ) );
141 :
142 320 : move16();
143 320 : move16();
144 320 : move16();
145 : }
146 3830 : ELSE IF( EQ_16( ivas_format, SBA_FORMAT ) )
147 : {
148 3034 : pFb_cfg->fb_latency = NS2SA_FX2( sampling_rate, DELAY_FB_1_NS );
149 :
150 3034 : pFb_cfg->fade_len = NS2SA_FX2( sampling_rate, DELAY_FB_4_NS );
151 3034 : pFb_cfg->prior_input_length = NS2SA_FX2( sampling_rate, FRAME_SIZE_NS );
152 3034 : Word16 tmp = shl( div_l( sampling_rate, FRAMES_PER_SEC ), 1 ); // Q0
153 3034 : tmp = mult0( tmp, 3 ); // Q0
154 3034 : tmp = shr( tmp, 2 ); // Q0
155 3034 : pFb_cfg->windowed_fr_offset = sub( tmp, NS2SA_FX2( sampling_rate, DELAY_DIRAC_SPAR_ENC_CMP_NS ) );
156 3034 : move16();
157 3034 : move16();
158 3034 : move16();
159 3034 : move16();
160 : }
161 796 : ELSE IF( EQ_16( ivas_format, MASA_FORMAT ) )
162 : {
163 526 : pFb_cfg->fb_latency = NS2SA_FX2( sampling_rate, DELAY_FB_1_NS );
164 526 : pFb_cfg->fade_len = NS2SA_FX2( sampling_rate, DELAY_FB_1_NS );
165 526 : pFb_cfg->prior_input_length = add( NS2SA_FX2( sampling_rate, DELAY_DIRAC_ENC_CMP_NS ), NS2SA_FX2( sampling_rate, DIRAC_SLOT_ENC_NS ) );
166 :
167 526 : move16();
168 526 : move16();
169 526 : move16();
170 : }
171 270 : ELSE IF( EQ_16( ivas_format, MC_FORMAT ) )
172 : {
173 270 : pFb_cfg->fb_latency = NS2SA_FX2( sampling_rate, DELAY_FB_1_NS );
174 270 : pFb_cfg->fade_len = NS2SA_FX2( sampling_rate, DELAY_FB_1_NS );
175 270 : pFb_cfg->prior_input_length = add( NS2SA_FX2( sampling_rate, DELAY_DIRAC_ENC_CMP_NS ), NS2SA_FX2( sampling_rate, PARAM_MC_SLOT_ENC_NS ) );
176 :
177 270 : move16();
178 270 : move16();
179 270 : move16();
180 : }
181 :
182 4150 : *pFb_cfg_out = pFb_cfg;
183 :
184 4150 : return IVAS_ERR_OK;
185 : }
186 :
187 :
188 : /*-------------------------------------------------------------------------
189 : * ivas_FB_mixer_open()
190 : *
191 : * Allocate and initialize FB mixer handle
192 : *------------------------------------------------------------------------*/
193 4150 : ivas_error ivas_FB_mixer_open_fx(
194 : IVAS_FB_MIXER_HANDLE *hFbMixer_out, /* i/o: FB mixer handle */
195 : const Word32 sampling_rate, /* i : sampling rate */
196 : IVAS_FB_CFG *fb_cfg, /* i : FB config. handle */
197 : const Word16 spar_reconfig_flag /* i : SPAR reconfiguration flag */
198 : )
199 : {
200 : IVAS_FB_MIXER_HANDLE hFbMixer;
201 : Word16 i, j, frame_len, num_bands;
202 : Word16 num_chs_alloc, exp;
203 : ivas_error error;
204 :
205 4150 : error = IVAS_ERR_OK;
206 4150 : move32();
207 :
208 4150 : frame_len = BASOP_Util_Divide3232_Scale( sampling_rate, FRAMES_PER_SEC, &exp );
209 4150 : frame_len = shr( frame_len, sub( 15, exp ) );
210 :
211 4150 : hFbMixer = *hFbMixer_out;
212 :
213 4150 : IF( !spar_reconfig_flag )
214 : {
215 1668 : IF( ( hFbMixer = (IVAS_FB_MIXER_HANDLE) malloc( sizeof( IVAS_FB_MIXER_DATA ) ) ) == NULL )
216 : {
217 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for FB mixer encoder" );
218 : }
219 :
220 1668 : IF( fb_cfg->num_out_chans > 0 )
221 : {
222 564 : IF( ( hFbMixer->pFb = (ivas_filterbank_t *) malloc( sizeof( ivas_filterbank_t ) ) ) == NULL )
223 : {
224 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for FB mixer encoder" );
225 : }
226 : }
227 : ELSE
228 : {
229 1104 : hFbMixer->pFb = NULL;
230 : }
231 : }
232 :
233 4150 : IF( EQ_16( fb_cfg->active_w_mixing, -1 ) )
234 : {
235 1476 : num_chs_alloc = 0;
236 1476 : move16();
237 : }
238 2674 : ELSE IF( fb_cfg->active_w_mixing )
239 : {
240 540 : num_chs_alloc = s_max( fb_cfg->num_in_chans, fb_cfg->nchan_fb_in );
241 : }
242 : ELSE
243 : {
244 2134 : num_chs_alloc = 1; /* only W channel processed for predicting YZX */
245 2134 : move16();
246 : }
247 :
248 8444 : FOR( i = 0; i < num_chs_alloc; i++ )
249 : {
250 4294 : IF( fb_cfg->num_out_chans == 0 )
251 : {
252 1104 : hFbMixer->ppFilterbank_inFR_re_fx[i] = NULL;
253 1104 : hFbMixer->ppFilterbank_inFR_im_fx[i] = NULL;
254 : }
255 : ELSE
256 : {
257 3190 : j = fb_cfg->remix_order[i];
258 3190 : move16();
259 :
260 3190 : IF( ( hFbMixer->ppFilterbank_inFR_re_fx[j] = (Word32 *) malloc( sizeof( Word32 ) * frame_len ) ) == NULL )
261 : {
262 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for FB mixer encoder" );
263 : }
264 :
265 3190 : IF( ( hFbMixer->ppFilterbank_inFR_im_fx[j] = (Word32 *) malloc( sizeof( Word32 ) * frame_len ) ) == NULL )
266 : {
267 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for FB mixer encoder" );
268 : }
269 : }
270 : }
271 :
272 4150 : IF( EQ_16( fb_cfg->active_w_mixing, -1 ) )
273 : {
274 1476 : num_chs_alloc = 0;
275 1476 : move16();
276 : }
277 : ELSE
278 : {
279 2674 : num_chs_alloc = s_max( fb_cfg->num_in_chans, fb_cfg->nchan_fb_in );
280 : }
281 :
282 17160 : FOR( i = 0; i < num_chs_alloc; i++ )
283 : {
284 13010 : IF( ( hFbMixer->ppFilterbank_prior_input_fx[i] = (Word32 *) malloc( sizeof( Word32 ) * fb_cfg->prior_input_length ) ) == NULL )
285 : {
286 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for FB mixer encoder" );
287 : }
288 13010 : set32_fx( hFbMixer->ppFilterbank_prior_input_fx[i], 0, fb_cfg->prior_input_length );
289 : }
290 :
291 4150 : test();
292 4150 : IF( ( NE_16( fb_cfg->active_w_mixing, -1 ) ) && ( fb_cfg->num_out_chans > 0 ) )
293 : {
294 : Word32 *pTemp_mem_fx;
295 1570 : IF( ( pTemp_mem_fx = (Word32 *) malloc( sizeof( Word32 ) * fb_cfg->num_out_chans * s_max( fb_cfg->num_in_chans, fb_cfg->nchan_fb_in ) * IVAS_MAX_NUM_BANDS ) ) == NULL )
296 : {
297 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for FB mixer" );
298 : }
299 5227 : FOR( i = 0; i < fb_cfg->num_out_chans; i++ )
300 : {
301 23177 : FOR( j = 0; j < fb_cfg->num_in_chans; j++ )
302 : {
303 19520 : hFbMixer->prior_mixer_fx[i][j] = pTemp_mem_fx;
304 19520 : pTemp_mem_fx += IVAS_MAX_NUM_BANDS;
305 19520 : set32_fx( hFbMixer->prior_mixer_fx[i][j], 0, IVAS_MAX_NUM_BANDS );
306 : }
307 : }
308 1570 : hFbMixer->q_prior_mixer_fx = Q31;
309 1570 : move16();
310 : }
311 :
312 4150 : IF( !spar_reconfig_flag )
313 : {
314 1668 : IF( fb_cfg->num_out_chans > 0 )
315 : {
316 : const Word16 *pActive_bins_per_band, *pActive_bins_per_band_abs, *pStart_offset, *pStart_offset_abs;
317 :
318 564 : num_bands = ivas_get_num_bands( sampling_rate );
319 :
320 564 : ivas_get_active_bins_fx( &pActive_bins_per_band, &pActive_bins_per_band_abs, &pStart_offset, &pStart_offset_abs, sampling_rate );
321 :
322 564 : IF( NE_16( fb_cfg->active_w_mixing, -1 ) )
323 : {
324 3705 : FOR( i = 0; i < num_bands; i++ )
325 : {
326 3414 : IF( ( hFbMixer->pFb->fb_bin_to_band.pFb_bin_to_band_fx[i] = (Word32 *) malloc( sizeof( Word32 ) * pActive_bins_per_band_abs[i] ) ) == NULL )
327 : {
328 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for FB mixer encoder fixed" );
329 : }
330 : }
331 : }
332 :
333 564 : IF( NE_32( sampling_rate, 48000 ) )
334 : {
335 : Word16 num_diff_bands, start_diff_band_non48k;
336 :
337 310 : num_diff_bands = MAX_NUM_BANDS_DIFF_NON48K;
338 310 : move16();
339 310 : start_diff_band_non48k = sub( num_bands, num_diff_bands );
340 :
341 310 : hFbMixer->num_diff_bands = num_diff_bands;
342 310 : move16();
343 :
344 1240 : FOR( j = start_diff_band_non48k; j < num_bands; j++ )
345 : {
346 930 : IF( ( hFbMixer->pFb->fb_consts.ppFilterbank_FRs_non48k_fx[0][j] = (Word32 *) malloc( sizeof( Word32 ) * pActive_bins_per_band[j] ) ) == NULL )
347 : {
348 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for FB mixer encoder" );
349 : }
350 :
351 930 : IF( ( hFbMixer->pFb->fb_consts.ppFilterbank_FRs_non48k_fx[1][j] = (Word32 *) malloc( sizeof( Word32 ) * pActive_bins_per_band[j] ) ) == NULL )
352 : {
353 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for FB mixer encoder" );
354 : }
355 : }
356 : }
357 : }
358 : ELSE
359 : {
360 : /* ignore all the deeper filter bank stuff for now */
361 1104 : hFbMixer->num_diff_bands = 0;
362 1104 : move16();
363 : }
364 : }
365 :
366 4150 : hFbMixer->fb_cfg = fb_cfg;
367 4150 : set16_fx( hFbMixer->first_frame, 1, hFbMixer->fb_cfg->num_out_chans );
368 4150 : set16_fx( hFbMixer->first_frame + hFbMixer->fb_cfg->num_out_chans, 0, sub( IVAS_SPAR_MAX_CH, hFbMixer->fb_cfg->num_out_chans ) );
369 :
370 4150 : IF( !spar_reconfig_flag )
371 : {
372 : Word16 index[IVAS_MAX_NUM_FB_BANDS];
373 1668 : set16_fx( index, 0, IVAS_MAX_NUM_FB_BANDS );
374 1668 : IF( NE_32( ( error = ivas_filterbank_setup_fx( hFbMixer, sampling_rate, index ) ), IVAS_ERR_OK ) )
375 : {
376 0 : return error;
377 : }
378 : }
379 :
380 4150 : *hFbMixer_out = hFbMixer;
381 :
382 4150 : return error;
383 : }
384 :
385 : /*-------------------------------------------------------------------------
386 : * ivas_FB_mixer_close()
387 : *
388 : * Deallocate FB mixer handle
389 : *------------------------------------------------------------------------*/
390 :
391 4150 : void ivas_FB_mixer_close_fx(
392 : IVAS_FB_MIXER_HANDLE *hFbMixer_in, /* i/o: FB mixer handle */
393 : const Word32 sampling_rate, /* i : sampling rate in Hz */
394 : const Word16 spar_reconfig_flag /* i : SPAR reconfiguration flag */
395 : )
396 : {
397 : IVAS_FB_MIXER_HANDLE hFbMixer;
398 : IVAS_FB_CFG *fb_cfg;
399 : Word16 i, j, num_bands;
400 : Word16 num_chs_alloc;
401 :
402 4150 : hFbMixer = *hFbMixer_in;
403 4150 : fb_cfg = hFbMixer->fb_cfg;
404 :
405 4150 : IF( EQ_16( fb_cfg->active_w_mixing, -1 ) )
406 : {
407 1476 : num_chs_alloc = 0;
408 1476 : move16();
409 : }
410 2674 : ELSE IF( fb_cfg->active_w_mixing )
411 : {
412 540 : num_chs_alloc = s_max( fb_cfg->num_in_chans, fb_cfg->nchan_fb_in );
413 : }
414 : ELSE
415 : {
416 2134 : num_chs_alloc = 1; /* only W channel processed for predicting YZX */
417 2134 : move16();
418 : }
419 :
420 4150 : IF( hFbMixer != NULL )
421 : {
422 8444 : FOR( i = 0; i < num_chs_alloc; i++ )
423 : {
424 4294 : IF( fb_cfg->num_out_chans > 0 )
425 : {
426 3190 : j = fb_cfg->remix_order[i];
427 3190 : move16();
428 :
429 3190 : free( hFbMixer->ppFilterbank_inFR_re_fx[j] );
430 3190 : hFbMixer->ppFilterbank_inFR_re_fx[j] = NULL;
431 :
432 3190 : free( hFbMixer->ppFilterbank_inFR_im_fx[j] );
433 3190 : hFbMixer->ppFilterbank_inFR_im_fx[j] = NULL;
434 : }
435 : }
436 :
437 4150 : IF( EQ_16( fb_cfg->active_w_mixing, -1 ) )
438 : {
439 1476 : num_chs_alloc = 0;
440 1476 : move16();
441 : }
442 : ELSE
443 : {
444 2674 : num_chs_alloc = s_max( fb_cfg->num_in_chans, fb_cfg->nchan_fb_in );
445 : }
446 :
447 17160 : FOR( i = 0; i < num_chs_alloc; i++ )
448 : {
449 13010 : free( hFbMixer->ppFilterbank_prior_input_fx[i] );
450 13010 : hFbMixer->ppFilterbank_prior_input_fx[i] = NULL;
451 : }
452 :
453 4150 : test();
454 4150 : IF( NE_16( fb_cfg->active_w_mixing, -1 ) && ( fb_cfg->num_out_chans > 0 ) )
455 : {
456 1570 : free( hFbMixer->prior_mixer_fx[0][0] );
457 1570 : hFbMixer->prior_mixer_fx[0][0] = NULL;
458 : }
459 :
460 4150 : IF( !spar_reconfig_flag )
461 : {
462 1668 : IF( fb_cfg->num_out_chans > 0 )
463 : {
464 564 : num_bands = hFbMixer->pFb->filterbank_num_bands;
465 564 : move16();
466 :
467 564 : IF( NE_16( fb_cfg->active_w_mixing, -1 ) )
468 : {
469 3705 : FOR( i = 0; i < num_bands; i++ )
470 : {
471 3414 : free( hFbMixer->pFb->fb_bin_to_band.pFb_bin_to_band_fx[i] );
472 3414 : hFbMixer->pFb->fb_bin_to_band.pFb_bin_to_band_fx[i] = NULL;
473 : }
474 : }
475 :
476 564 : IF( NE_32( sampling_rate, 48000 ) )
477 : {
478 : Word16 start_diff_band_non48k;
479 310 : start_diff_band_non48k = sub( num_bands, hFbMixer->num_diff_bands );
480 :
481 1240 : FOR( j = start_diff_band_non48k; j < num_bands; j++ )
482 : {
483 930 : free( hFbMixer->pFb->fb_consts.ppFilterbank_FRs_non48k_fx[0][j] );
484 930 : hFbMixer->pFb->fb_consts.ppFilterbank_FRs_non48k_fx[0][j] = NULL;
485 :
486 930 : free( hFbMixer->pFb->fb_consts.ppFilterbank_FRs_non48k_fx[1][j] );
487 930 : hFbMixer->pFb->fb_consts.ppFilterbank_FRs_non48k_fx[1][j] = NULL;
488 : }
489 : }
490 : }
491 1668 : IF( hFbMixer->pFb != NULL )
492 : {
493 564 : free( hFbMixer->pFb );
494 564 : hFbMixer->pFb = NULL;
495 : }
496 : }
497 :
498 4150 : IF( hFbMixer->fb_cfg != NULL )
499 : {
500 4150 : free( hFbMixer->fb_cfg );
501 4150 : hFbMixer->fb_cfg = NULL;
502 : }
503 :
504 4150 : IF( !spar_reconfig_flag )
505 : {
506 1668 : free( hFbMixer );
507 1668 : hFbMixer = NULL;
508 : }
509 : }
510 :
511 4150 : return;
512 : }
513 : /*-----------------------------------------------------------------------------------------*
514 : * Function ivas_fb_mixer_pcm_ingest()
515 : *
516 : * PCM ingest block
517 : *-----------------------------------------------------------------------------------------*/
518 157500 : void ivas_fb_mixer_pcm_ingest_fx(
519 : IVAS_FB_MIXER_HANDLE hFbMixer, /* i/o: FB mixer handle */
520 : Word32 *pcm_in[], /* i : input audio channels Qq_data_fix[] */
521 : Word32 **ppOut_pcm, /* o : output audio channels Qq_ppOut_pcm[] */
522 : const Word16 frame_len, /* i : frame length */
523 : const Word16 HOA_md_ind[IVAS_SPAR_MAX_CH],
524 : Word16 q_data_fix,
525 : Word16 *q_ppOut_pcm )
526 : {
527 : Word16 i;
528 : Word16 num_chs_ingest;
529 157500 : IVAS_FB_CFG *fb_cfg = hFbMixer->fb_cfg;
530 :
531 157500 : IF( fb_cfg->active_w_mixing )
532 : {
533 43891 : num_chs_ingest = fb_cfg->num_in_chans;
534 43891 : move16();
535 : }
536 : ELSE
537 : {
538 113609 : num_chs_ingest = 1; /* forward Filterbank MDFT only on W */
539 113609 : move16();
540 : }
541 :
542 :
543 889700 : FOR( i = 0; i < fb_cfg->num_in_chans; i++ )
544 : {
545 732200 : Copy32( &hFbMixer->ppFilterbank_prior_input_fx[i][fb_cfg->prior_input_length - frame_len], ppOut_pcm[i], frame_len );
546 732200 : Copy32( pcm_in[HOA_md_ind[i]], &ppOut_pcm[i][frame_len], frame_len );
547 732200 : q_ppOut_pcm[i] = q_data_fix;
548 732200 : move16();
549 : }
550 :
551 157500 : Word16 guard_bits = find_guarded_bits_fx( shl( frame_len, 1 ) );
552 :
553 446673 : FOR( i = 0; i < num_chs_ingest; i++ )
554 : {
555 289173 : Word16 q_shift = sub( L_norm_arr( ppOut_pcm[fb_cfg->remix_order[i]], shl( frame_len, 1 ) ), guard_bits );
556 289173 : Scale_sig32( ppOut_pcm[fb_cfg->remix_order[i]], shl( frame_len, 1 ), q_shift ); // Qq_ppOut_pcm -> Qq_ppOut_pcm + q_shift
557 289173 : q_ppOut_pcm[fb_cfg->remix_order[i]] = add( q_ppOut_pcm[fb_cfg->remix_order[i]], q_shift );
558 289173 : move16();
559 :
560 289173 : ivas_mdft_fx( ppOut_pcm[fb_cfg->remix_order[i]], hFbMixer->ppFilterbank_inFR_re_fx[fb_cfg->remix_order[i]], hFbMixer->ppFilterbank_inFR_im_fx[fb_cfg->remix_order[i]], shl( frame_len, 1 ), frame_len );
561 289173 : q_shift = L_norm_arr( hFbMixer->ppFilterbank_inFR_re_fx[fb_cfg->remix_order[i]], frame_len );
562 289173 : q_shift = s_min( q_shift, L_norm_arr( hFbMixer->ppFilterbank_inFR_im_fx[fb_cfg->remix_order[i]], frame_len ) );
563 289173 : scale_sig32( hFbMixer->ppFilterbank_inFR_re_fx[fb_cfg->remix_order[i]], frame_len, q_shift );
564 289173 : scale_sig32( hFbMixer->ppFilterbank_inFR_im_fx[fb_cfg->remix_order[i]], frame_len, q_shift );
565 289173 : hFbMixer->q_ppFilterbank_inFR[fb_cfg->remix_order[i]] = add( q_shift, q_ppOut_pcm[fb_cfg->remix_order[i]] );
566 289173 : move16();
567 : }
568 :
569 157500 : return;
570 : }
571 :
572 : /*-----------------------------------------------------------------------------------------*
573 : * Function ivas_fb_mixer_update_prior_input()
574 : *
575 : *
576 : *-----------------------------------------------------------------------------------------*/
577 884980 : void ivas_fb_mixer_update_prior_input_fx(
578 : IVAS_FB_MIXER_HANDLE hFbMixer, /* i/o: FB mixer handle */
579 : Word32 *pcm_in_fx[], /* i : input audio channels */
580 : const Word16 length, /* i : length of time slot */
581 : const Word16 nchan_fb_in /* i : number of analysis channels */
582 : )
583 : {
584 : Word16 i;
585 :
586 5081380 : FOR( i = 0; i < nchan_fb_in; i++ )
587 : {
588 4196400 : Copy32( &hFbMixer->ppFilterbank_prior_input_fx[i][length], hFbMixer->ppFilterbank_prior_input_fx[i], hFbMixer->fb_cfg->prior_input_length - length );
589 4196400 : Copy32( pcm_in_fx[i], &hFbMixer->ppFilterbank_prior_input_fx[i][hFbMixer->fb_cfg->prior_input_length - length], length );
590 : }
591 :
592 884980 : return;
593 : }
594 :
595 :
596 : /*-----------------------------------------------------------------------------------------*
597 : * Function ivas_fb_mixer_get_windowed_fr()
598 : *
599 : *
600 : *-----------------------------------------------------------------------------------------*/
601 :
602 883395 : void ivas_fb_mixer_get_windowed_fr_fx(
603 : IVAS_FB_MIXER_HANDLE hFbMixer, /* i/o: FB mixer handle */
604 : Word32 *pcm_in_fx[], // i: Qx
605 : Word32 *frame_f_real_fx[],
606 : Word32 *frame_f_imag_fx[],
607 : const Word16 length, /* i : number of new samples in time slot */
608 : const Word16 mdft_len, /* i : MDFT frame length */
609 : const Word16 nchan_fb_in, /* i : number of analysis channels */
610 : Word16 gb )
611 : {
612 : Word16 ch_idx, j, offset, rev_offset;
613 : Word16 n_old_samples;
614 : Word16 n_new_samples;
615 : Word32 fr_in_block_fx[L_FRAME48k * 2];
616 : const Word16 *win_ptr_fx;
617 :
618 883395 : n_old_samples = s_min( ( sub( hFbMixer->fb_cfg->prior_input_length, hFbMixer->fb_cfg->windowed_fr_offset ) ), ( shl( mdft_len, 1 ) ) );
619 883395 : n_new_samples = s_max( 0, sub( shl( length, 1 ), n_old_samples ) );
620 883395 : offset = sub( sub( shl( mdft_len, 1 ), length ), hFbMixer->ana_window_offset );
621 883395 : rev_offset = sub( shl( mdft_len, 1 ), hFbMixer->ana_window_offset );
622 883395 : set32_fx( fr_in_block_fx, 0, offset );
623 :
624 5069431 : FOR( ch_idx = 0; ch_idx < nchan_fb_in; ch_idx++ )
625 : {
626 4186036 : Copy32( &hFbMixer->ppFilterbank_prior_input_fx[ch_idx][offset + hFbMixer->fb_cfg->windowed_fr_offset], &fr_in_block_fx[offset], sub( n_old_samples, offset ) ); // Qx
627 4186036 : Copy32( pcm_in_fx[ch_idx], &fr_in_block_fx[n_old_samples], n_new_samples ); // Qx
628 :
629 4186036 : win_ptr_fx = hFbMixer->pAna_window_fx; /*Q15*/
630 :
631 222847892 : FOR( j = offset; j < sub( shl( mdft_len, 1 ), length ); j++ )
632 : {
633 218661856 : fr_in_block_fx[j] = Mpy_32_16_1( fr_in_block_fx[j], ( *( win_ptr_fx++ ) ) ); // Qx + 15 - 15 = Qx
634 218661856 : move32();
635 : }
636 :
637 222847892 : FOR( j = rev_offset; j < shl( mdft_len, 1 ); j++ )
638 : {
639 218661856 : fr_in_block_fx[j] = Mpy_32_16_1( fr_in_block_fx[j], ( *( --win_ptr_fx ) ) ); // Qx + 15 - 15 = Qx
640 218661856 : move32();
641 : }
642 :
643 1638352916 : FOR( Word16 i = 0; i < shl( mdft_len, 1 ); i++ )
644 : {
645 1634166880 : fr_in_block_fx[i] = L_shr( fr_in_block_fx[i], gb ); // Qx - gb
646 1634166880 : move32();
647 : }
648 :
649 4186036 : ivas_mdft_fx( fr_in_block_fx, frame_f_real_fx[ch_idx], frame_f_imag_fx[ch_idx], shl( mdft_len, 1 ), mdft_len );
650 : }
651 :
652 883395 : return;
653 : }
654 :
655 : /*-----------------------------------------------------------------------------------------*
656 : * Function ivas_fb_mixer_cross_fading()
657 : *
658 : * FB Mixer cross fading
659 : *-----------------------------------------------------------------------------------------*/
660 :
661 271899 : void ivas_fb_mixer_cross_fading_fx(
662 : IVAS_FB_MIXER_HANDLE hFbMixer,
663 : Word32 **ppOut_pcm_fx, // o: Qx
664 : Word32 *pMdft_out_old_fx, // i: Qx
665 : Word32 *pMdft_out_new_fx, // i: Qx
666 : const Word16 ch,
667 : const Word16 frame_len,
668 : const Word16 cf_offset )
669 : {
670 : Word16 k, fade_start_offset, fade_end_offset;
671 :
672 271899 : IF( hFbMixer->first_frame[ch] == 0 )
673 : {
674 269308 : fade_start_offset = hFbMixer->cross_fade_start_offset;
675 269308 : fade_end_offset = hFbMixer->cross_fade_end_offset;
676 269308 : move16();
677 269308 : move16();
678 :
679 269308 : FOR( k = 0; k < fade_start_offset; k++ )
680 : {
681 0 : ppOut_pcm_fx[ch][k] = pMdft_out_old_fx[k + cf_offset]; // Qx
682 0 : move32();
683 : }
684 :
685 42906108 : FOR( k = fade_start_offset; k < fade_end_offset; k++ )
686 : {
687 42636800 : ppOut_pcm_fx[ch][k] = L_add( Mpy_32_16_1( pMdft_out_new_fx[k + cf_offset], hFbMixer->pFilterbank_cross_fade_fx[k - fade_start_offset] ), Mpy_32_16_1( pMdft_out_old_fx[k + cf_offset], sub( 32767, hFbMixer->pFilterbank_cross_fade_fx[k - fade_start_offset] ) ) ); // Qx + Q15 - 15 = Qx
688 42636800 : move32();
689 : }
690 :
691 170816508 : FOR( k = fade_end_offset; k < frame_len; k++ )
692 : {
693 170547200 : ppOut_pcm_fx[ch][k] = pMdft_out_new_fx[k + cf_offset]; // Qx
694 170547200 : move32();
695 : }
696 : }
697 : ELSE
698 : {
699 2591 : hFbMixer->first_frame[ch] = 0;
700 2591 : move32();
701 :
702 2228831 : FOR( k = 0; k < frame_len; k++ )
703 : {
704 2226240 : ppOut_pcm_fx[ch][k] = pMdft_out_new_fx[k + cf_offset]; // Qx
705 2226240 : move32();
706 : }
707 : }
708 :
709 271899 : return;
710 : }
711 :
712 : /*-----------------------------------------------------------------------------------------*
713 : * Function ivas_fb_mixer_process()
714 : *
715 : * Filter bank process
716 : *-----------------------------------------------------------------------------------------*/
717 621213440 : void ivas_cmult_fix(
718 : Word32 in1_re, // i: Qx
719 : Word32 in1_im, // i: Qx
720 : Word32 in2_re, // i: Qx
721 : Word32 in2_im, // i: Qx
722 : Word32 *out1_re, // o: 2 * Qx - 31
723 : Word32 *out1_im // o: 2 * Qx - 31
724 : )
725 : {
726 621213440 : *out1_re = L_sub_sat( Mpy_32_32( in1_re, in2_re ), Mpy_32_32( in1_im, in2_im ) );
727 621213440 : move32();
728 621213440 : *out1_im = L_add_sat( Mpy_32_32( in1_re, in2_im ), Mpy_32_32( in2_re, in1_im ) );
729 621213440 : move32();
730 621213440 : }
731 :
732 157500 : void ivas_fb_mixer_process_fx(
733 : IVAS_FB_MIXER_HANDLE hFbMixer, /* i/o: FB mixer handle */
734 : Word32 ***mixer_mat_fx, /* i : mixer matrix */
735 : Word16 *q_mixer_mat_fx, /* i : mixer matrix Q-factor */
736 : Word32 **ppOut_pcm_fx, /* o : output audio channels */
737 : Word16 *q_ppOut_pcm_fx, /* o : output audio channels Q-factor */
738 : const Word16 frame_len, /* i : frame length in samples */
739 : Word16 in_out_mixer_map[IVAS_MAX_FB_MIXER_OUT_CH][IVAS_MAX_SPAR_FB_MIXER_IN_CH] /* i/o: mixing mapping */
740 : )
741 : {
742 157500 : ivas_filterbank_t *pFb = hFbMixer->pFb;
743 157500 : Word16 num_bands = pFb->filterbank_num_bands;
744 157500 : move16();
745 : Word16 i, j, k, ch, hist;
746 :
747 : const Word32 *pFilterbank_bin_to_band_re_fx;
748 : const Word32 *pFilterbank_bin_to_band_im_fx;
749 : Word16 q_pMdft_out_fx[2];
750 : Word32 *pMdft_out_fx[2];
751 : Word32 *pOut_fr_re_fx, *pOut_fr_im_fx;
752 157500 : Word16 q_pOut_fr_fx = 31;
753 157500 : move16();
754 : Word32 Out_fr_re_fx[L_FRAME48k], Out_fr_im_fx[L_FRAME48k];
755 : Word32 Mdft_out_0_fx[L_FRAME48k * 2], Mdft_out_1_fx[L_FRAME48k * 2];
756 :
757 157500 : pOut_fr_re_fx = Out_fr_re_fx;
758 157500 : pOut_fr_im_fx = Out_fr_im_fx;
759 157500 : pMdft_out_fx[0] = Mdft_out_0_fx;
760 157500 : pMdft_out_fx[1] = Mdft_out_1_fx;
761 :
762 429399 : FOR( ch = ( hFbMixer->fb_cfg->active_w_mixing == 0 ); ch < hFbMixer->fb_cfg->num_out_chans; ch++ )
763 : {
764 : /* Run a loop of 2 to calculate current frame's filterbank output and prev frame's output */
765 815697 : FOR( hist = 0; hist < 2; hist++ )
766 : {
767 543798 : set_zero_fx( pOut_fr_re_fx, frame_len );
768 543798 : set_zero_fx( pOut_fr_im_fx, frame_len );
769 543798 : q_pOut_fr_fx = 31;
770 543798 : move16();
771 3332190 : FOR( j = 0; j < hFbMixer->fb_cfg->num_in_chans; j++ )
772 : {
773 2788392 : IF( in_out_mixer_map[ch][j] != 0 )
774 : {
775 :
776 : Word32 filterbank_mixer_bins_re_fx[L_FRAME48k];
777 : Word32 filterbank_mixer_bins_im_fx[L_FRAME48k];
778 807144 : Word32 *pFb_inFR_re_fx = hFbMixer->ppFilterbank_inFR_re_fx[j]; // Q(hFbMixer->q_ppFilterbank_inFR_re_fx)
779 807144 : Word32 *pFb_inFR_im_fx = hFbMixer->ppFilterbank_inFR_im_fx[j]; // Q(hFbMixer->q_ppFilterbank_inFR_im_fx)
780 :
781 807144 : set_zero_fx( filterbank_mixer_bins_re_fx, frame_len );
782 807144 : set_zero_fx( filterbank_mixer_bins_im_fx, frame_len );
783 :
784 807144 : Word16 total_guard = find_guarded_bits_fx( num_bands );
785 807144 : move16();
786 10353872 : FOR( i = 0; i < num_bands; i++ )
787 : {
788 9546728 : Word16 start_offset = pFb->fb_consts.pFilterbank_bins_start_offset[i];
789 9546728 : move16();
790 9546728 : Word16 num_bins = pFb->fb_consts.pFilterbank_bins_per_band[i];
791 9546728 : move16();
792 9546728 : Word32 mixer_const_fx = hFbMixer->prior_mixer_fx[ch][j][i]; // Q(hFbMixer->q_prior_mixer_fx)
793 9546728 : move32();
794 9546728 : pFilterbank_bin_to_band_re_fx = pFb->fb_consts.ppFilterbank_FRs_fx[0][i]; // Q30
795 9546728 : pFilterbank_bin_to_band_im_fx = pFb->fb_consts.ppFilterbank_FRs_fx[1][i]; // Q30
796 :
797 2942784180 : FOR( k = start_offset; k < num_bins + start_offset; k++ )
798 : {
799 2933237452 : filterbank_mixer_bins_re_fx[k] = L_add_sat( filterbank_mixer_bins_re_fx[k], L_shr( Mpy_32_32( *pFilterbank_bin_to_band_re_fx, mixer_const_fx ), total_guard ) ); // Q30 + hFbMixer->q_prior_mixer_fx - 31 - total_guard
800 2933237452 : move32();
801 2933237452 : filterbank_mixer_bins_im_fx[k] = L_add_sat( filterbank_mixer_bins_im_fx[k], L_shr( Mpy_32_32( *pFilterbank_bin_to_band_im_fx, mixer_const_fx ), total_guard ) ); // Q30 + hFbMixer->q_prior_mixer_fx - 31 - total_guard
802 2933237452 : move32();
803 : /*filterbank_mixer_bins_im_fx q 30 */
804 : /*mixer_const_fx q q_ppOut_pcm_fx */
805 2933237452 : pFilterbank_bin_to_band_re_fx++;
806 2933237452 : pFilterbank_bin_to_band_im_fx++;
807 : }
808 9546728 : hFbMixer->prior_mixer_fx[ch][j][i] = mixer_mat_fx[ch][j][i]; // Q(q_mixer_mat_fx)
809 9546728 : move32();
810 : }
811 807144 : Word16 res_q = 0;
812 807144 : move16();
813 622020584 : FOR( k = 0; k < frame_len; k++ )
814 : {
815 : Word32 temp_out_re_fx, temp_out_im_fx;
816 :
817 621213440 : ivas_cmult_fix( filterbank_mixer_bins_re_fx[k], filterbank_mixer_bins_im_fx[k], pFb_inFR_re_fx[k],
818 621213440 : pFb_inFR_im_fx[k], &temp_out_re_fx, &temp_out_im_fx );
819 621213440 : res_q = sub( add( sub( sub( add( 30, *q_mixer_mat_fx ), 31 ), total_guard ), hFbMixer->q_ppFilterbank_inFR[j] ), 31 );
820 621213440 : Word16 q_check = s_min( q_pOut_fr_fx, res_q );
821 621213440 : IF( NE_16( q_check, q_pOut_fr_fx ) )
822 : {
823 434008960 : pOut_fr_re_fx[k] = L_shr( pOut_fr_re_fx[k], sub( q_pOut_fr_fx, q_check ) ); // q_pOut_fr_fx -> q_check
824 434008960 : move32();
825 434008960 : pOut_fr_im_fx[k] = L_shr( pOut_fr_im_fx[k], sub( q_pOut_fr_fx, q_check ) ); // q_pOut_fr_fx -> q_check
826 434008960 : move32();
827 : }
828 621213440 : IF( NE_16( q_check, res_q ) )
829 : {
830 149251840 : temp_out_re_fx = L_shr( temp_out_re_fx, sub( res_q, q_check ) ); // res_q -> q_check
831 149251840 : temp_out_im_fx = L_shr( temp_out_im_fx, sub( res_q, q_check ) ); // res_q -> q_check
832 : }
833 621213440 : res_q = q_check;
834 621213440 : move16();
835 621213440 : pOut_fr_re_fx[k] = L_add_sat( pOut_fr_re_fx[k], temp_out_re_fx ); // res_q
836 621213440 : move32();
837 621213440 : pOut_fr_im_fx[k] = L_add_sat( pOut_fr_im_fx[k], temp_out_im_fx ); // res_q
838 621213440 : move32();
839 : }
840 807144 : q_pOut_fr_fx = res_q;
841 807144 : move16();
842 : }
843 : }
844 543798 : Word16 scale = sub( s_min( L_norm_arr( pOut_fr_re_fx, frame_len ), L_norm_arr( pOut_fr_im_fx, frame_len ) ), find_guarded_bits_fx( shl( frame_len, 1 ) ) );
845 543798 : scale_sig32( pOut_fr_re_fx, frame_len, scale );
846 543798 : scale_sig32( pOut_fr_im_fx, frame_len, scale );
847 543798 : ivas_imdft_fx( pOut_fr_re_fx, pOut_fr_im_fx, pMdft_out_fx[hist], frame_len );
848 543798 : q_pMdft_out_fx[hist] = add( q_pOut_fr_fx, scale );
849 543798 : move16();
850 : }
851 271899 : scale_sig32( pMdft_out_fx[0], shl( frame_len, 1 ), sub( s_min( q_pMdft_out_fx[0], q_pMdft_out_fx[1] ), q_pMdft_out_fx[0] ) );
852 271899 : scale_sig32( pMdft_out_fx[1], shl( frame_len, 1 ), sub( s_min( q_pMdft_out_fx[0], q_pMdft_out_fx[1] ), q_pMdft_out_fx[1] ) );
853 271899 : ivas_fb_mixer_cross_fading_fx( hFbMixer, ppOut_pcm_fx, pMdft_out_fx[0], pMdft_out_fx[1], ch, frame_len, frame_len );
854 271899 : q_ppOut_pcm_fx[ch] = s_min( q_pMdft_out_fx[0], q_pMdft_out_fx[1] );
855 271899 : move16();
856 : }
857 :
858 157500 : return;
859 : }
860 :
861 : /*-----------------------------------------------------------------------------------------*
862 : * Function ivas_fb_mixer_get_in_out_mapping()
863 : *
864 : *
865 : *-----------------------------------------------------------------------------------------*/
866 157500 : void ivas_fb_mixer_get_in_out_mapping_fx(
867 : const IVAS_FB_CFG *fb_cfg, /* i : FB config. handle */
868 : Word16 in_out_mixer_map[IVAS_MAX_FB_MIXER_OUT_CH][IVAS_MAX_SPAR_FB_MIXER_IN_CH] /* i/o: mixing mapping */
869 : )
870 : {
871 : Word16 i, j;
872 :
873 157500 : set_s( (Word16 *) in_out_mixer_map, 0, IVAS_MAX_FB_MIXER_OUT_CH * IVAS_MAX_SPAR_FB_MIXER_IN_CH );
874 :
875 157500 : IF( fb_cfg->active_w_mixing )
876 : {
877 87782 : FOR( i = 0; i < fb_cfg->num_out_chans; i++ )
878 : {
879 219455 : FOR( j = 0; j < fb_cfg->num_in_chans; j++ )
880 : {
881 175564 : in_out_mixer_map[i][j] = 1;
882 175564 : move16();
883 : }
884 : }
885 : }
886 : ELSE
887 : {
888 113609 : in_out_mixer_map[0][0] = 1; /* W depends on only W input*/
889 113609 : move16();
890 341617 : FOR( i = 1; i < fb_cfg->num_out_chans; i++ )
891 : {
892 228008 : in_out_mixer_map[i][0] = 1;
893 228008 : move16();
894 : }
895 : }
896 :
897 157500 : return;
898 : }
899 :
900 : /*-----------------------------------------------------------------------------------------*
901 : * Function ivas_calculate_abs_fr()
902 : *
903 : * Function to calculate number of active bands
904 : *-----------------------------------------------------------------------------------------*/
905 :
906 564 : static Word16 ivas_calculate_abs_fr_fx(
907 : ivas_filterbank_t *pFb,
908 : const Word32 sampling_rate,
909 : const Word16 alloc_fb_resp,
910 : Word16 *index )
911 : {
912 : Word16 frame_len;
913 : Word32 ppFilterbank_FRs_s_fx[L_FRAME48k];
914 564 : Word16 bands = pFb->filterbank_num_bands;
915 564 : move16();
916 564 : Word16 i, j, num_active_bands = 0;
917 564 : move16();
918 564 : Word16 idx_short_stride_bin_to_band = 0;
919 564 : move16();
920 : Word16 quo, tmp, exp_diff;
921 :
922 564 : Word32 temp = Mpy_32_32( sampling_rate, 42949673 /* FRAMES_PER_SEC in Q31 */ );
923 564 : frame_len = extract_l( temp );
924 :
925 7174 : FOR( i = 0; i < bands; i++ )
926 : {
927 6610 : const Word32 *long_mdft_ptr_re_fx = pFb->fb_consts.ppFilterbank_FRs_fx[0][i]; // Q30
928 6610 : const Word32 *long_mdft_ptr_im_fx = pFb->fb_consts.ppFilterbank_FRs_fx[1][i]; // Q30
929 :
930 6610 : Word16 start_offset = pFb->fb_consts.pFilterbank_bins_start_offset[i];
931 6610 : move16();
932 6610 : Word16 num_bins = pFb->fb_consts.pFilterbank_bins_per_band[i];
933 6610 : move16();
934 6610 : Word16 short_mdft_start_bin = -1;
935 6610 : move16();
936 :
937 : Word32 short_stride_pow_spec_fx[MDFT_FB_BANDS_240];
938 6610 : Word32 short_stride_nrg_fx = 0;
939 6610 : move16();
940 6610 : exp_diff = 0;
941 6610 : move16();
942 :
943 6610 : Word64 cldfb_nrg_fx = 0;
944 6610 : move64();
945 6610 : Word16 short_stride = pFb->fb_bin_to_band.short_stride;
946 6610 : move16();
947 : Word32 res_dec1, res_frac, res_dec2;
948 6610 : iDiv_and_mod_32( sampling_rate, FRAMES_PER_SEC, &res_dec1, &res_frac, 0 );
949 6610 : iDiv_and_mod_32( res_dec1, short_stride, &res_dec2, &res_frac, 0 );
950 6610 : const Word16 num_bins_per_short_stride_bin = extract_l( res_dec2 );
951 6610 : iDiv_and_mod_32( res_dec1, pFb->fb_bin_to_band.num_cldfb_bands, &res_dec2, &res_frac, 0 );
952 6610 : const Word16 num_bins_per_cldfb_band = extract_l( res_dec2 );
953 :
954 6610 : Word32 short_stride_max_per_spar_band_fx = 1;
955 6610 : move32();
956 :
957 : /*loop over all stored Filter Bank Response MDFT coefficients*/
958 :
959 6610 : set32_fx( short_stride_pow_spec_fx, 0, MDFT_FB_BANDS_240 );
960 :
961 2006677 : FOR( j = start_offset; j < num_bins + start_offset; j++ )
962 : {
963 :
964 : Word32 sq_abs_fx;
965 :
966 : // Word32 real = L_shr( *long_mdft_ptr_re_fx, 3 ); // Q27
967 2000067 : Word32 real = *long_mdft_ptr_re_fx; // Q30
968 2000067 : move32();
969 : // Word32 imag = L_shr( *long_mdft_ptr_im_fx, 3 ); // Q27
970 2000067 : Word32 imag = *long_mdft_ptr_im_fx; // Q30
971 2000067 : move32();
972 2000067 : Word64 acc = W_mac_32_32( W_mult_32_32( real, real ), imag, imag ); // Q61
973 2000067 : sq_abs_fx = W_extract_h( acc ); // Q28
974 2000067 : long_mdft_ptr_re_fx++;
975 2000067 : long_mdft_ptr_im_fx++;
976 :
977 : /* accumulate bin energies within a short stride bin */
978 :
979 2000067 : short_stride_nrg_fx = L_add( short_stride_nrg_fx, L_shr( sq_abs_fx, 6 ) ); // Q22
980 2000067 : move32();
981 :
982 2000067 : IF( !( add( j, 1 ) % num_bins_per_short_stride_bin ) )
983 : {
984 : /* new short stride bin */
985 498948 : short_stride_pow_spec_fx[j / num_bins_per_short_stride_bin] = short_stride_nrg_fx; /* energy rather than magnitude works better for covariance weighting*/
986 498948 : move32();
987 498948 : short_stride_max_per_spar_band_fx = L_max( short_stride_nrg_fx, short_stride_max_per_spar_band_fx ); /*compute highest magnitude per band*/
988 498948 : short_stride_nrg_fx = 0;
989 498948 : move32();
990 : }
991 :
992 : /* accumulate bin energies within a CLDFB band */
993 2000067 : cldfb_nrg_fx = W_mac_32_32( cldfb_nrg_fx, sq_abs_fx, 1 ); // Q29
994 :
995 2000067 : IF( !( add( j, 1 ) % num_bins_per_cldfb_band ) )
996 : {
997 123740 : Word16 exp = W_norm( cldfb_nrg_fx );
998 123740 : cldfb_nrg_fx = W_shl( cldfb_nrg_fx, exp );
999 123740 : exp = sub( 34, exp ); // 31 - (Q29 + exp -32)
1000 123740 : temp = Sqrt32( W_extract_h( cldfb_nrg_fx ), &exp );
1001 123740 : temp = L_shl( temp, sub( exp, Q9 ) ); // Q22
1002 123740 : pFb->fb_bin_to_band.pp_cldfb_weights_per_spar_band_fx[j / num_bins_per_cldfb_band][i] = temp; // Q22
1003 123740 : move32();
1004 123740 : cldfb_nrg_fx = 0;
1005 123740 : move32();
1006 : }
1007 : }
1008 :
1009 6610 : quo = BASOP_Util_Divide3232_Scale( ONE_IN_Q30, short_stride_max_per_spar_band_fx, &exp_diff );
1010 : /* Q of quo = Q30 - Q22 + (15 - exp_diff) --> Q23 - exp_diff.
1011 : With Mult_32_16, Q23 - exp_diff - 15 --> Q8 - exp_diff */
1012 6610 : exp_diff = sub( Q8, exp_diff );
1013 :
1014 : /*loop over the short MDFT bins*/
1015 1244850 : FOR( j = 0; j < short_stride; j++ )
1016 : {
1017 1238240 : short_stride_pow_spec_fx[j] = L_shr( Mult_32_16( short_stride_pow_spec_fx[j], quo ), exp_diff ); // Q22
1018 1238240 : move32();
1019 1238240 : short_stride_pow_spec_fx[j] = L_max( L_sub( short_stride_pow_spec_fx[j], 1258291 ), 0 ); // 0.3f * ONE_IN_Q22
1020 1238240 : move32();
1021 1238240 : short_stride_pow_spec_fx[j] = L_shl( Mpy_32_32( short_stride_pow_spec_fx[j], 1533916891 /* 1/0.7 in Q30 */ ), 1 ); // Q22
1022 1238240 : move32();
1023 :
1024 :
1025 1238240 : IF( short_stride_pow_spec_fx[j] > 0 )
1026 : {
1027 111998 : assert( idx_short_stride_bin_to_band < 2 * MDFT_FB_BANDS_240 ); /* array size of p_short_stride_bin_to_band */
1028 111998 : IF( EQ_16( short_mdft_start_bin, -1 ) )
1029 : {
1030 6610 : short_mdft_start_bin = j;
1031 6610 : move16();
1032 6610 : pFb->fb_bin_to_band.p_short_stride_start_bin_per_band[i] = j;
1033 6610 : move16();
1034 :
1035 6610 : pFb->fb_bin_to_band.pp_short_stride_bin_to_band_fx[i] = &pFb->fb_bin_to_band.p_short_stride_bin_to_band_fx[idx_short_stride_bin_to_band]; // Q22
1036 6610 : index[i] = idx_short_stride_bin_to_band;
1037 6610 : move16();
1038 : }
1039 :
1040 111998 : pFb->fb_bin_to_band.p_short_stride_bin_to_band_fx[idx_short_stride_bin_to_band] = short_stride_pow_spec_fx[j]; // Q22
1041 111998 : move32();
1042 111998 : idx_short_stride_bin_to_band = add( idx_short_stride_bin_to_band, 1 );
1043 :
1044 111998 : pFb->fb_bin_to_band.p_short_stride_num_bins_per_band[i] = add( pFb->fb_bin_to_band.p_short_stride_num_bins_per_band[i], 1 );
1045 111998 : move16();
1046 : }
1047 : }
1048 : }
1049 :
1050 : /*loop over CLDFB bands*/
1051 26624 : FOR( j = 0; j < pFb->fb_bin_to_band.num_cldfb_bands; j++ )
1052 : {
1053 26060 : Word32 sum_over_spar_bands_fx = 0;
1054 26060 : move32();
1055 26060 : Word32 max_spar_band_contribution_fx = 0;
1056 26060 : move32();
1057 :
1058 26060 : Word16 spar_start = 0;
1059 26060 : move16();
1060 26060 : Word16 any_non_zero = 0;
1061 26060 : move16();
1062 :
1063 335620 : FOR( i = 0; i < bands; i++ )
1064 : {
1065 309560 : sum_over_spar_bands_fx = L_add( sum_over_spar_bands_fx, pFb->fb_bin_to_band.pp_cldfb_weights_per_spar_band_fx[j][i] ); // Q22
1066 309560 : move32();
1067 :
1068 309560 : IF( pFb->fb_bin_to_band.pp_cldfb_weights_per_spar_band_fx[j][i] > max_spar_band_contribution_fx )
1069 : {
1070 76715 : max_spar_band_contribution_fx = pFb->fb_bin_to_band.pp_cldfb_weights_per_spar_band_fx[j][i]; // Q22
1071 76715 : move32();
1072 76715 : pFb->fb_bin_to_band.p_cldfb_map_to_spar_band[j] = i;
1073 76715 : move16();
1074 : }
1075 : }
1076 :
1077 26060 : sum_over_spar_bands_fx = L_max( sum_over_spar_bands_fx, EPSILON_FX ); // Q22
1078 26060 : move32();
1079 :
1080 26060 : exp_diff = 0;
1081 26060 : move16();
1082 26060 : tmp = BASOP_Util_Divide3232_Scale( ONE_IN_Q30, sum_over_spar_bands_fx, &exp_diff );
1083 : /* Q of quo = Q30 - Q22 + (15 - exp_diff) --> Q23 - exp_diff.
1084 : With Mult_32_16, Q23 - exp_diff - 15 --> Q8 - exp_diff */
1085 26060 : exp_diff = sub( Q8, exp_diff );
1086 :
1087 335620 : FOR( i = 0; i < bands; i++ )
1088 : {
1089 309560 : test();
1090 309560 : IF( pFb->fb_bin_to_band.pp_cldfb_weights_per_spar_band_fx[j][i] == 0 && !any_non_zero )
1091 : {
1092 165303 : spar_start = add( spar_start, 1 );
1093 : }
1094 : ELSE
1095 : {
1096 144257 : any_non_zero = 1;
1097 144257 : move16();
1098 : }
1099 :
1100 309560 : pFb->fb_bin_to_band.pp_cldfb_weights_per_spar_band_fx[j][i] = L_shr( Mult_32_16( pFb->fb_bin_to_band.pp_cldfb_weights_per_spar_band_fx[j][i], tmp ), exp_diff );
1101 309560 : move32();
1102 : }
1103 26060 : pFb->fb_bin_to_band.p_spar_start_bands[j] = spar_start;
1104 26060 : move16();
1105 : }
1106 :
1107 564 : set32_fx( ppFilterbank_FRs_s_fx, 0, frame_len );
1108 :
1109 : /*Commented logic is for calculating number of active bands, can be removed if not needed */
1110 7174 : FOR( i = 0; i < bands; i++ )
1111 : {
1112 6610 : const Word32 *pFilterbank_bin_to_band_re_fx = pFb->fb_consts.ppFilterbank_FRs_fx[0][i]; // Q30
1113 6610 : move32();
1114 6610 : const Word32 *pFilterbank_bin_to_band_im_fx = pFb->fb_consts.ppFilterbank_FRs_fx[1][i]; // Q30
1115 6610 : move32();
1116 :
1117 6610 : Word16 start_offset = pFb->fb_consts.pFilterbank_bins_start_offset[i];
1118 6610 : move16();
1119 6610 : Word16 num_bins = pFb->fb_consts.pFilterbank_bins_per_band[i];
1120 6610 : move16();
1121 6610 : Word16 idx = 0;
1122 6610 : move16();
1123 6610 : Word16 abs_active_bins = pFb->fb_bin_to_band.pFb_active_bins_per_band[i];
1124 6610 : move16();
1125 6610 : Word16 abs_start_offset = pFb->fb_bin_to_band.pFb_start_bin_per_band[i];
1126 6610 : move16();
1127 :
1128 2006677 : FOR( j = start_offset; j < num_bins + start_offset; j++ )
1129 : {
1130 2000067 : Word32 temp_fx = 0;
1131 2000067 : move32();
1132 :
1133 2000067 : exp_diff = 0;
1134 2000067 : move16();
1135 2000067 : Word32 real = L_shr( *pFilterbank_bin_to_band_re_fx, 3 ); // Q27
1136 2000067 : Word32 imag = L_shr( *pFilterbank_bin_to_band_im_fx, 3 ); // Q27
1137 :
1138 : Word32 real_sq, imag_sq;
1139 2000067 : real_sq = Mpy_32_32( real, real ); // Q27 + Q27 - 31 = Q23
1140 2000067 : imag_sq = Mpy_32_32( imag, imag ); // Q27 + Q27 - 31 = Q23
1141 :
1142 2000067 : temp_fx = L_add( L_shr( real_sq, 1 ), L_shr( imag_sq, 1 ) ); // Q22
1143 :
1144 2000067 : exp_diff = 9;
1145 2000067 : move16();
1146 2000067 : temp_fx = Sqrt32( temp_fx, &exp_diff );
1147 2000067 : temp_fx = L_shl( temp_fx, sub( exp_diff, Q9 ) ); // Q22
1148 :
1149 :
1150 2000067 : pFilterbank_bin_to_band_re_fx++;
1151 2000067 : pFilterbank_bin_to_band_im_fx++;
1152 :
1153 2000067 : temp_fx = L_sub( temp_fx, 1258291 ); // 0.3 in Q22
1154 2000067 : move32();
1155 :
1156 2000067 : if ( temp_fx < 0 )
1157 : {
1158 1433594 : temp_fx = 0;
1159 1433594 : move32();
1160 : }
1161 :
1162 2000067 : test();
1163 2000067 : test();
1164 2000067 : IF( LT_16( j, add( abs_active_bins, abs_start_offset ) ) && GE_16( j, abs_start_offset ) && NE_16( alloc_fb_resp, -1 ) )
1165 : {
1166 294399 : pFb->fb_bin_to_band.pFb_bin_to_band_fx[i][idx] = temp_fx; // Q22
1167 294399 : move32();
1168 294399 : idx = add( idx, 1 );
1169 : }
1170 :
1171 :
1172 2000067 : ppFilterbank_FRs_s_fx[j] = L_add( ppFilterbank_FRs_s_fx[j], temp_fx ); // Q22
1173 2000067 : move32();
1174 : }
1175 : }
1176 :
1177 417524 : FOR( i = 0; i < frame_len; i++ )
1178 : {
1179 416960 : if ( ppFilterbank_FRs_s_fx[i] < 0 )
1180 : {
1181 0 : ppFilterbank_FRs_s_fx[i] = 419430; // 0.1 in Q22
1182 0 : move32();
1183 : }
1184 : }
1185 :
1186 564 : IF( NE_16( alloc_fb_resp, -1 ) )
1187 : {
1188 3705 : FOR( j = 0; j < bands; j++ )
1189 : {
1190 3414 : Word16 abs_active_bins = pFb->fb_bin_to_band.pFb_active_bins_per_band[j];
1191 3414 : Word16 abs_start_offset = pFb->fb_bin_to_band.pFb_start_bin_per_band[j];
1192 3414 : exp_diff = 0;
1193 :
1194 3414 : move16();
1195 3414 : move16();
1196 3414 : move16();
1197 :
1198 297813 : FOR( i = 0; i < abs_active_bins; i++ )
1199 : {
1200 294399 : tmp = BASOP_Util_Divide3232_Scale( pFb->fb_bin_to_band.pFb_bin_to_band_fx[j][i], ppFilterbank_FRs_s_fx[i + abs_start_offset], &exp_diff );
1201 294399 : pFb->fb_bin_to_band.pFb_bin_to_band_fx[j][i] = L_shl( L_deposit_l( tmp ), add( Q7, exp_diff ) ); // Q22
1202 294399 : move32();
1203 : /*if(pFb->fb_bin_to_band.pFb_bin_to_band[j][i] > 0.5f)
1204 : {
1205 : num_active_bands = j + 1;
1206 : break;
1207 : }*/
1208 : }
1209 : }
1210 : }
1211 :
1212 564 : return num_active_bands;
1213 : }
1214 :
1215 : /*-----------------------------------------------------------------------------------------*
1216 : * Function ivas_get_active_bins()
1217 : *
1218 : *
1219 : *-----------------------------------------------------------------------------------------*/
1220 :
1221 1128 : static void ivas_get_active_bins_fx(
1222 : const Word16 **pActive_bins,
1223 : const Word16 **pActive_bins_abs,
1224 : const Word16 **pStart_offset,
1225 : const Word16 **pStart_offset_abs,
1226 : const Word32 sampling_rate )
1227 : {
1228 : Word16 sr_idx;
1229 :
1230 1128 : IF( EQ_32( sampling_rate, 32000 ) )
1231 : {
1232 462 : sr_idx = 1;
1233 462 : move16();
1234 : }
1235 666 : ELSE IF( EQ_32( sampling_rate, 16000 ) )
1236 : {
1237 158 : sr_idx = 2;
1238 158 : move16();
1239 : }
1240 : ELSE
1241 : {
1242 508 : sr_idx = 0;
1243 508 : move16();
1244 : }
1245 :
1246 1128 : *pActive_bins_abs = ivas_fb_abs_bins_per_band_12band_1ms[sr_idx];
1247 1128 : move16();
1248 1128 : *pActive_bins = ivas_fb_bins_per_band_12band_1ms[sr_idx];
1249 1128 : move16();
1250 1128 : *pStart_offset_abs = ivas_fb_abs_bins_start_offset_12band_1ms[sr_idx];
1251 1128 : move16();
1252 1128 : *pStart_offset = ivas_fb_bins_start_offset_12band_1ms[sr_idx];
1253 1128 : move16();
1254 :
1255 1128 : return;
1256 : }
1257 :
1258 :
1259 : /*-----------------------------------------------------------------------------------------*
1260 : * Function ivas_filterbank_setup()
1261 : *
1262 : * Filterbank setup, initialization
1263 : *-----------------------------------------------------------------------------------------*/
1264 :
1265 1668 : static ivas_error ivas_filterbank_setup_fx(
1266 : IVAS_FB_MIXER_HANDLE hFbMixer,
1267 : const Word32 sampling_rate,
1268 : Word16 *index )
1269 : {
1270 : Word16 i, j, exp, tmp;
1271 : const Word32 *pAll_fb_fr_fx[2];
1272 1668 : const Word16 *pAll_bins_start_offset = NULL;
1273 1668 : const Word16 *pAll_bins_per_band = NULL;
1274 1668 : const Word16 *pAll_bins_start_offset_abs = NULL;
1275 1668 : const Word16 *pAll_bins_per_band_abs = NULL;
1276 1668 : const Word16 *pAll_bins_per_band_48k = NULL;
1277 : ivas_error error;
1278 1668 : IVAS_FB_CFG *pCfg = hFbMixer->fb_cfg;
1279 :
1280 1668 : error = IVAS_ERR_OK;
1281 1668 : move32();
1282 :
1283 1668 : IF( pCfg->num_out_chans > 0 )
1284 : {
1285 564 : hFbMixer->pFb->filterbank_num_bands = ivas_get_num_bands( sampling_rate );
1286 564 : move16();
1287 :
1288 564 : ivas_get_active_bins_fx( &pAll_bins_per_band, &pAll_bins_per_band_abs, &pAll_bins_start_offset, &pAll_bins_start_offset_abs, sampling_rate );
1289 :
1290 564 : IF( EQ_16( pCfg->fb_latency, NS2SA_FX2( sampling_rate, DELAY_FB_1_NS ) ) )
1291 : {
1292 564 : pAll_fb_fr_fx[0] = ivas_fb_fr_12band_1ms_re_fx; // Q30
1293 564 : move32();
1294 564 : pAll_fb_fr_fx[1] = ivas_fb_fr_12band_1ms_im_fx; // Q30
1295 564 : move32();
1296 :
1297 564 : pAll_bins_per_band_48k = ivas_fb_bins_per_band_12band_1ms[0];
1298 564 : move16();
1299 : }
1300 : ELSE
1301 : {
1302 0 : return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Wrong FB in ivas_filterbank_setup()!" );
1303 : }
1304 : }
1305 :
1306 1668 : hFbMixer->cross_fade_end_offset = add( pCfg->fade_len, pCfg->pcm_offset );
1307 1668 : move16();
1308 1668 : hFbMixer->cross_fade_start_offset = sub( hFbMixer->cross_fade_end_offset, pCfg->fade_len );
1309 1668 : move16();
1310 1668 : hFbMixer->ana_window_offset = add( pCfg->fb_latency, pCfg->pcm_offset );
1311 1668 : move16();
1312 :
1313 1668 : IF( NE_32( ( error = ivas_fb_mixer_get_window_fx( pCfg->fb_latency, sampling_rate, &( hFbMixer->pAna_window_fx ) ) ), IVAS_ERR_OK ) )
1314 : {
1315 0 : return error;
1316 : }
1317 :
1318 1668 : IF( NE_32( ( error = ivas_fb_mixer_get_window_fx( pCfg->fade_len, sampling_rate, &( hFbMixer->pFilterbank_cross_fade_fx ) ) ), IVAS_ERR_OK ) )
1319 : {
1320 0 : return error;
1321 : }
1322 :
1323 1668 : IF( pCfg->num_out_chans > 0 )
1324 : {
1325 564 : ivas_filterbank_t *pFb = hFbMixer->pFb;
1326 564 : Word16 offset = 0;
1327 564 : move16();
1328 :
1329 564 : pFb->fb_consts.pFilterbank_bins_per_band = pAll_bins_per_band;
1330 564 : pFb->fb_consts.pFilterbank_bins_start_offset = pAll_bins_start_offset;
1331 564 : pFb->fb_bin_to_band.pFb_active_bins_per_band = pAll_bins_per_band_abs;
1332 564 : pFb->fb_bin_to_band.pFb_start_bin_per_band = pAll_bins_start_offset_abs;
1333 :
1334 : /* Initialization for short stride Parameter calculation and SPAR CLDFB reconstruction */
1335 564 : SWITCH( sampling_rate )
1336 : {
1337 254 : case 48000:
1338 254 : pFb->fb_bin_to_band.num_cldfb_bands = 60; /* sampling_rate * 1.0f / 800.0f */
1339 254 : move16();
1340 254 : BREAK;
1341 231 : case 32000:
1342 231 : pFb->fb_bin_to_band.num_cldfb_bands = 40;
1343 231 : move16();
1344 231 : BREAK;
1345 79 : case 16000:
1346 79 : pFb->fb_bin_to_band.num_cldfb_bands = 20;
1347 79 : move16();
1348 79 : BREAK;
1349 : }
1350 :
1351 : /*pFb->fb_bin_to_band.cldfb_stride = ( int16_t )( ( sampling_rate / FRAMES_PER_SEC ) / CLDFB_NO_COL_MAX );*/ /* equals num_cldfb_bands*/
1352 : // pFb->fb_bin_to_band.short_stride = extract_l( ( sampling_rate / FRAMES_PER_SEC ) / 4 );
1353 564 : tmp = BASOP_Util_Divide3232_Scale( sampling_rate, FRAMES_PER_SEC, &exp );
1354 564 : pFb->fb_bin_to_band.short_stride = shr( tmp, add( sub( 15, exp ), 2 ) );
1355 :
1356 564 : move16();
1357 :
1358 564 : set32_fx( pFb->fb_bin_to_band.p_short_stride_bin_to_band_fx, 0, 2 * MDFT_FB_BANDS_240 );
1359 :
1360 564 : set16_fx( pFb->fb_bin_to_band.p_cldfb_map_to_spar_band, 0, CLDFB_NO_CHANNELS_MAX );
1361 564 : set16_fx( pFb->fb_bin_to_band.p_spar_start_bands, 0, CLDFB_NO_CHANNELS_MAX );
1362 :
1363 11844 : FOR( j = 0; j < IVAS_MAX_NUM_FB_BANDS; j++ )
1364 : {
1365 11280 : pFb->fb_bin_to_band.p_short_stride_num_bins_per_band[j] = 0; /* aka num_active_bins per SPAR band */
1366 11280 : move16();
1367 11280 : pFb->fb_bin_to_band.p_short_stride_start_bin_per_band[j] = 0; /* first considered bin index per SPAR band */
1368 11280 : move16();
1369 :
1370 11280 : pFb->fb_bin_to_band.pp_short_stride_bin_to_band_fx[j] = NULL;
1371 :
1372 688080 : FOR( i = 0; i < CLDFB_NO_CHANNELS_MAX; i++ )
1373 : {
1374 :
1375 676800 : pFb->fb_bin_to_band.pp_cldfb_weights_per_spar_band_fx[i][j] = 0;
1376 676800 : move32();
1377 : }
1378 : }
1379 564 : IF( EQ_32( sampling_rate, 48000 ) )
1380 : {
1381 3302 : FOR( j = 0; j < pFb->filterbank_num_bands; j++ )
1382 : {
1383 :
1384 3048 : pFb->fb_consts.ppFilterbank_FRs_fx[0][j] = &pAll_fb_fr_fx[0][offset]; // Q30
1385 3048 : pFb->fb_consts.ppFilterbank_FRs_fx[1][j] = &pAll_fb_fr_fx[1][offset]; // Q30
1386 :
1387 3048 : offset = add( offset, pFb->fb_consts.pFilterbank_bins_per_band[j] );
1388 : }
1389 :
1390 : /****************************************Calculate abs fr ***************************/
1391 :
1392 254 : ivas_calculate_abs_fr_fx( pFb, sampling_rate, pCfg->active_w_mixing, index );
1393 : }
1394 : ELSE
1395 : {
1396 :
1397 : Word32 *ppFilterbank_FRs_re_temp_fx[MAX_NUM_BANDS_DIFF_NON48K];
1398 : Word32 *ppFilterbank_FRs_im_temp_fx[MAX_NUM_BANDS_DIFF_NON48K];
1399 : Word16 active_bins_temp[MAX_NUM_BANDS_DIFF_NON48K];
1400 : Word16 start_offset_temp[MAX_NUM_BANDS_DIFF_NON48K];
1401 : Word16 num_diff_bands, start_diff_band_non48k;
1402 :
1403 310 : num_diff_bands = MAX_NUM_BANDS_DIFF_NON48K;
1404 310 : start_diff_band_non48k = sub( pFb->filterbank_num_bands, num_diff_bands );
1405 310 : move16();
1406 :
1407 310 : pFb->fb_consts.pFilterbank_bins_per_band = pAll_bins_per_band;
1408 310 : pFb->fb_consts.pFilterbank_bins_start_offset = pAll_bins_start_offset;
1409 :
1410 3872 : FOR( j = 0; j < pFb->filterbank_num_bands; j++ )
1411 : {
1412 3562 : Word16 num_active_bins = pFb->fb_consts.pFilterbank_bins_per_band[j];
1413 3562 : move16();
1414 :
1415 3562 : IF( j < start_diff_band_non48k )
1416 : {
1417 :
1418 2632 : pFb->fb_consts.ppFilterbank_FRs_fx[0][j] = &pAll_fb_fr_fx[0][offset]; // Q30
1419 2632 : pFb->fb_consts.ppFilterbank_FRs_fx[1][j] = &pAll_fb_fr_fx[1][offset]; // Q30
1420 : }
1421 : ELSE
1422 : {
1423 930 : Copy32( &pAll_fb_fr_fx[0][offset], pFb->fb_consts.ppFilterbank_FRs_non48k_fx[0][j], num_active_bins ); // Q30
1424 930 : Copy32( &pAll_fb_fr_fx[1][offset], pFb->fb_consts.ppFilterbank_FRs_non48k_fx[1][j], num_active_bins ); // Q30
1425 : }
1426 :
1427 3562 : offset = add( offset, pAll_bins_per_band_48k[j] );
1428 : }
1429 :
1430 1240 : FOR( j = start_diff_band_non48k; j < pFb->filterbank_num_bands; j++ )
1431 : {
1432 :
1433 930 : ppFilterbank_FRs_re_temp_fx[j - start_diff_band_non48k] = pFb->fb_consts.ppFilterbank_FRs_non48k_fx[0][j]; // Q30
1434 930 : ppFilterbank_FRs_im_temp_fx[j - start_diff_band_non48k] = pFb->fb_consts.ppFilterbank_FRs_non48k_fx[1][j]; // Q30
1435 :
1436 930 : active_bins_temp[j - start_diff_band_non48k] = pFb->fb_consts.pFilterbank_bins_per_band[j];
1437 930 : start_offset_temp[j - start_diff_band_non48k] = pFb->fb_consts.pFilterbank_bins_start_offset[j];
1438 930 : move16();
1439 930 : move16();
1440 : }
1441 :
1442 310 : ivas_get_ld_fb_resp_fx( ppFilterbank_FRs_re_temp_fx, ppFilterbank_FRs_im_temp_fx, ppFilterbank_FRs_re_temp_fx, ppFilterbank_FRs_im_temp_fx,
1443 310 : active_bins_temp, start_offset_temp, num_diff_bands, pCfg->fb_latency, sampling_rate );
1444 :
1445 :
1446 1240 : FOR( j = start_diff_band_non48k; j < pFb->filterbank_num_bands; j++ )
1447 : {
1448 :
1449 930 : pFb->fb_consts.ppFilterbank_FRs_fx[0][j] = (const Word32 *) pFb->fb_consts.ppFilterbank_FRs_non48k_fx[0][j]; // Q30
1450 930 : pFb->fb_consts.ppFilterbank_FRs_fx[1][j] = (const Word32 *) pFb->fb_consts.ppFilterbank_FRs_non48k_fx[1][j]; // Q30
1451 : }
1452 :
1453 : /******************************************** Calculate abs fr ****************************************************/
1454 :
1455 310 : ivas_calculate_abs_fr_fx( pFb, sampling_rate, pCfg->active_w_mixing, index );
1456 : }
1457 : }
1458 :
1459 1668 : return error;
1460 : }
1461 :
1462 : /*-----------------------------------------------------------------------------------------*
1463 : * Function ivas_fb_mixer_get_window()
1464 : *
1465 : *
1466 : *-----------------------------------------------------------------------------------------*/
1467 :
1468 3336 : static ivas_error ivas_fb_mixer_get_window_fx(
1469 : const Word16 fade_len, /* i : window fading length in samples */
1470 : const Word32 sampling_rate, /* i : sampling rate */
1471 : const Word16 **pWindow /* o : pointer to the window coefficents */
1472 : )
1473 : {
1474 : ivas_error error;
1475 :
1476 3336 : error = IVAS_ERR_OK;
1477 3336 : move32();
1478 :
1479 3336 : IF( EQ_16( fade_len, NS2SA_FX2( sampling_rate, DELAY_FB_4_NS ) ) )
1480 : {
1481 1192 : SWITCH( sampling_rate )
1482 : {
1483 882 : case 48000:
1484 882 : *pWindow = ivas_fb_cf_4ms_48k_fx;
1485 882 : BREAK;
1486 231 : case 32000:
1487 231 : *pWindow = ivas_fb_cf_4ms_32k_fx;
1488 231 : BREAK;
1489 79 : case 16000:
1490 79 : *pWindow = ivas_fb_cf_4ms_16k_fx;
1491 79 : BREAK;
1492 0 : default:
1493 0 : return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Unsupported Sampling frequency!" );
1494 : }
1495 : }
1496 2144 : ELSE IF( EQ_16( fade_len, NS2SA_FX2( sampling_rate, DELAY_FB_1_NS ) ) )
1497 : {
1498 2144 : SWITCH( sampling_rate )
1499 : {
1500 1566 : case 48000:
1501 1566 : *pWindow = ivas_fb_cf_1ms_48k_fx;
1502 1566 : BREAK;
1503 499 : case 32000:
1504 499 : *pWindow = ivas_fb_cf_1ms_32k_fx;
1505 499 : BREAK;
1506 79 : case 16000:
1507 79 : *pWindow = ivas_fb_cf_1ms_16k_fx;
1508 79 : BREAK;
1509 0 : default:
1510 0 : return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Unsupported Sampling frequency!" );
1511 : }
1512 : }
1513 : ELSE
1514 : {
1515 0 : IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Error: Incorrect FB window fade len (%f ms)\n", ( fade_len / 1000000.f ) );
1516 : }
1517 :
1518 3336 : return error;
1519 : }
1520 :
1521 :
1522 310 : static const Word32 *ivas_get_cheby_ramp_fx(
1523 : const Word16 delay )
1524 : {
1525 310 : const Word32 *pCheby_fx = NULL;
1526 :
1527 310 : SWITCH( delay )
1528 : {
1529 231 : case IVAS_FB_1MS_32K_SAMP:
1530 231 : pCheby_fx = ivas_fb_resp_cheby_ramp_32del_fx;
1531 231 : BREAK;
1532 79 : case IVAS_FB_1MS_16K_SAMP:
1533 79 : pCheby_fx = ivas_fb_resp_cheby_ramp_16del_fx;
1534 79 : BREAK;
1535 0 : default:
1536 0 : assert( !"Unsupported cheby ramp length!" );
1537 : }
1538 :
1539 310 : return pCheby_fx;
1540 : }
1541 :
1542 310 : static void ivas_get_ld_fb_resp_fx(
1543 : Word32 **ppIdeal_FRs_re_fx, // i: Q30
1544 : Word32 **ppIdeal_FRs_im_fx, // i: Q30
1545 : Word32 **ppNew_FRs_re_fx, // o: Q30
1546 : Word32 **ppNew_FRs_im_fx, // o: Q30
1547 : const Word16 *pActive_bins,
1548 : const Word16 *pStart_offset,
1549 : const Word16 num_bands,
1550 : const Word16 delay,
1551 : const Word32 sampling_rate )
1552 : {
1553 : Word16 b, s, frame_len;
1554 : const Word32 *pCheby_fx;
1555 310 : frame_len = 0;
1556 310 : move16();
1557 : /*common scratch buffers for computing impulse/frequency responses,
1558 : pre-ring, post-ring and circular shifted outputs to optimize stack*/
1559 : Word32 scratch1_fx[L_FRAME32k * 2];
1560 : Word32 scratch2_fx[L_FRAME32k * 2];
1561 :
1562 310 : set32_fx( scratch1_fx, 0, L_FRAME32k * 2 );
1563 310 : set32_fx( scratch2_fx, 0, L_FRAME32k * 2 );
1564 :
1565 310 : const Word32 *han_win_fx = NULL;
1566 :
1567 310 : SWITCH( sampling_rate )
1568 : {
1569 0 : case 48000:
1570 0 : frame_len = 960;
1571 0 : move16();
1572 0 : han_win_fx = ivas_han_win_48k_fx; // Q31
1573 0 : BREAK;
1574 231 : case 32000:
1575 231 : frame_len = 640;
1576 231 : move16();
1577 231 : han_win_fx = ivas_han_win_32k_fx; // Q31
1578 231 : BREAK;
1579 79 : case 16000:
1580 79 : frame_len = 320;
1581 79 : move16();
1582 79 : han_win_fx = ivas_han_win_16k_fx; // Q31
1583 79 : BREAK;
1584 : }
1585 :
1586 310 : pCheby_fx = ivas_get_cheby_ramp_fx( delay ); // Q31
1587 :
1588 310 : b = 0;
1589 310 : s = 0;
1590 310 : move16();
1591 310 : move16();
1592 :
1593 310 : assert( sampling_rate == 32000 || sampling_rate == 16000 );
1594 :
1595 1240 : FOR( b = 0; b < num_bands; b++ )
1596 : {
1597 :
1598 930 : set32_fx( scratch2_fx, 0, shl( frame_len, 1 ) );
1599 930 : Copy32( ppIdeal_FRs_re_fx[b], &scratch2_fx[pStart_offset[b]], pActive_bins[b] ); // Q30
1600 930 : Copy32( ppIdeal_FRs_im_fx[b], &scratch2_fx[frame_len + pStart_offset[b]], pActive_bins[b] ); // Q30
1601 :
1602 930 : Word16 guard_bits = sub( L_norm_arr( scratch2_fx, shl( L_FRAME32k, 1 ) ), find_guarded_bits_fx( shl( frame_len, 1 ) ) );
1603 930 : Scale_sig32( scratch2_fx, shl( L_FRAME32k, 1 ), guard_bits ); // Q30 + guard_bits
1604 :
1605 930 : ivas_imdft_fx( scratch2_fx, &scratch2_fx[frame_len], scratch1_fx, frame_len );
1606 :
1607 1191330 : FOR( Word16 x = 0; x < shl( L_FRAME32k, 1 ); x++ )
1608 : {
1609 1190400 : scratch2_fx[x] = L_shr( scratch2_fx[x], guard_bits ); // (Q30 + guard_bits) - guard_bits = Q30
1610 1190400 : scratch1_fx[x] = L_shr( scratch1_fx[x], guard_bits ); // (Q30 + guard_bits) - guard_bits = Q30
1611 :
1612 1190400 : move32();
1613 1190400 : move32();
1614 : }
1615 :
1616 : /*apply circular shift and hanning window*/
1617 :
1618 520290 : FOR( s = delay; s < frame_len + delay; s++ )
1619 : {
1620 :
1621 519360 : scratch2_fx[s - delay] = Mpy_32_32( scratch1_fx[s], L_sub( ONE_IN_Q31, han_win_fx[s - delay] ) ); // Q(30 + 31 - 31) == Q30
1622 519360 : move32();
1623 : }
1624 :
1625 494322 : FOR( ; s < 2 * frame_len; s++ )
1626 : {
1627 :
1628 493392 : scratch2_fx[s - delay] = Mpy_32_32( scratch1_fx[s], han_win_fx[s - ( frame_len + delay )] ); // Q30
1629 493392 : move32();
1630 : }
1631 :
1632 26898 : FOR( s = 0; s < delay; s++ )
1633 : {
1634 :
1635 25968 : scratch2_fx[( ( ( frame_len * 2 ) - delay ) + s )] = L_negate( Mpy_32_32( scratch1_fx[s], han_win_fx[( frame_len - delay ) + s] ) ); // Q30
1636 25968 : move32();
1637 : }
1638 :
1639 : /*apply heavy/cheby ramp window and compute pre ring*/
1640 :
1641 27828 : FOR( s = 0; s < delay + 1; s++ )
1642 : {
1643 26898 : scratch1_fx[s] = Mpy_32_32( scratch2_fx[s], pCheby_fx[delay - s] ); // Q30
1644 26898 : move32();
1645 : }
1646 :
1647 493392 : FOR( ; s < frame_len; s++ )
1648 : {
1649 492462 : scratch1_fx[s] = 0;
1650 492462 : move32();
1651 : }
1652 :
1653 494322 : FOR( ; s < 2 * frame_len - delay; s++ )
1654 : {
1655 493392 : scratch1_fx[s] = scratch2_fx[s];
1656 493392 : move32();
1657 : }
1658 :
1659 26898 : FOR( ; s < 2 * frame_len; s++ )
1660 : {
1661 25968 : scratch1_fx[s] = Mpy_32_32( scratch2_fx[s], L_sub( ONE_IN_Q31, pCheby_fx[s - ( 2 * frame_len - delay )] ) ); // Q30
1662 25968 : move32();
1663 : }
1664 :
1665 : /*IR - pre ring + post ring*/
1666 1038720 : FOR( s = 1; s < 2 * frame_len; s++ )
1667 : {
1668 1037790 : scratch2_fx[s] = L_sub( L_sub( scratch2_fx[s] /*pre ring*/, scratch1_fx[s] /*post ring*/ ), scratch1_fx[frame_len * 2 - s] );
1669 1037790 : move32();
1670 : }
1671 :
1672 1013682 : FOR( s = 0; s < 2 * frame_len - delay; s++ )
1673 : {
1674 1012752 : scratch1_fx[s + delay] = scratch2_fx[s];
1675 1012752 : move32();
1676 : }
1677 :
1678 26898 : FOR( ; s < 2 * frame_len; s++ )
1679 : {
1680 25968 : scratch1_fx[( s - ( ( frame_len * 2 ) - delay ) )] = L_negate( scratch2_fx[s] );
1681 25968 : move32();
1682 : }
1683 :
1684 : /* apply final window*/
1685 930 : const Word32 *sine_till_delay = ivas_sine_delay_32_fx; // Q30
1686 930 : Word16 offset = 1;
1687 930 : Word16 delay_16 = 0;
1688 :
1689 930 : move16();
1690 930 : move16();
1691 :
1692 930 : if ( EQ_16( delay, IVAS_FB_1MS_16K_SAMP ) )
1693 : {
1694 237 : delay_16 = 1;
1695 237 : move16();
1696 : }
1697 :
1698 26898 : FOR( s = 0; s < delay; s++ )
1699 : {
1700 25968 : scratch1_fx[s] = Mpy_32_32( scratch1_fx[s], sine_till_delay[s + offset * delay_16] ); // Q30 + Q30 - 31 = Q29
1701 25968 : offset = add( offset, 1 );
1702 25968 : scratch1_fx[s] = L_shl( scratch1_fx[s], 1 ); // Q30
1703 :
1704 25968 : move32();
1705 25968 : move32();
1706 : }
1707 :
1708 930 : const Word32 *sine_till_frame_len = NULL;
1709 :
1710 930 : IF( EQ_16( delay, IVAS_FB_1MS_16K_SAMP ) )
1711 : {
1712 237 : sine_till_frame_len = ivas_sine_frame_len_640_del_16_fx; // Q30
1713 237 : move32();
1714 : }
1715 : ELSE
1716 : {
1717 693 : sine_till_frame_len = ivas_sine_frame_len_640_del_32_fx; // Q30
1718 693 : move32();
1719 : }
1720 930 : Word16 iterator = 0;
1721 930 : move16();
1722 469284 : FOR( s = 2 * delay; s < frame_len + 1; s++ )
1723 : {
1724 468354 : scratch1_fx[s] = Mpy_32_32( scratch1_fx[s], sine_till_frame_len[iterator] ); // Q30 + Q30 - 31 = Q29
1725 468354 : iterator = add( iterator, 1 );
1726 468354 : scratch1_fx[s] = L_shl( scratch1_fx[s], 1 ); // Q30
1727 :
1728 468354 : move32();
1729 468354 : move32();
1730 : }
1731 :
1732 519360 : FOR( ; s < 2 * frame_len; s++ )
1733 : {
1734 518430 : scratch1_fx[s] = 0;
1735 :
1736 518430 : move32();
1737 : }
1738 :
1739 : /*compute frequency response*/
1740 930 : ivas_mdft_fx( scratch1_fx, scratch2_fx, &scratch2_fx[frame_len], shl( frame_len, 1 ), frame_len );
1741 :
1742 930 : Copy32( &scratch2_fx[pStart_offset[b]], ppNew_FRs_re_fx[b], pActive_bins[b] ); // Q30
1743 930 : Copy32( &scratch2_fx[( frame_len + pStart_offset[b] )], ppNew_FRs_im_fx[b], pActive_bins[b] ); // Q30
1744 : }
1745 :
1746 310 : return;
1747 : }
|