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 : #ifdef OPT_SBA_ENC_V1_BE
763 157500 : Word16 total_guard = find_guarded_bits_fx( num_bands );
764 157500 : Word16 total_guard_2 = find_guarded_bits_fx( shl( frame_len, 1 ) );
765 157500 : Word16 tmp_q = sub( sub( *q_mixer_mat_fx, total_guard ), 32 ); // Q30 + hFbMixer->q_prior_mixer_fx - 31 - total_guard - 31
766 157500 : Word16 len = shl( frame_len, 1 );
767 : Word16 res_q, q_check;
768 : #endif
769 429399 : FOR( ch = ( hFbMixer->fb_cfg->active_w_mixing == 0 ); ch < hFbMixer->fb_cfg->num_out_chans; ch++ )
770 : {
771 : /* Run a loop of 2 to calculate current frame's filterbank output and prev frame's output */
772 815697 : FOR( hist = 0; hist < 2; hist++ )
773 : {
774 543798 : set_zero_fx( pOut_fr_re_fx, frame_len );
775 543798 : set_zero_fx( pOut_fr_im_fx, frame_len );
776 543798 : q_pOut_fr_fx = 31;
777 543798 : move16();
778 3332190 : FOR( j = 0; j < hFbMixer->fb_cfg->num_in_chans; j++ )
779 : {
780 2788392 : IF( in_out_mixer_map[ch][j] != 0 )
781 : {
782 :
783 : #ifdef OPT_SBA_ENC_V1_BE
784 807144 : res_q = add( tmp_q, hFbMixer->q_ppFilterbank_inFR[j] );
785 807144 : q_check = s_min( q_pOut_fr_fx, res_q );
786 807144 : scale_sig32( pOut_fr_re_fx, frame_len, sub( q_check, q_pOut_fr_fx ) );
787 807144 : scale_sig32( pOut_fr_im_fx, frame_len, sub( q_check, q_pOut_fr_fx ) );
788 : #endif
789 : Word32 filterbank_mixer_bins_re_fx[L_FRAME48k];
790 : Word32 filterbank_mixer_bins_im_fx[L_FRAME48k];
791 807144 : Word32 *pFb_inFR_re_fx = hFbMixer->ppFilterbank_inFR_re_fx[j]; // Q(hFbMixer->q_ppFilterbank_inFR_re_fx)
792 807144 : Word32 *pFb_inFR_im_fx = hFbMixer->ppFilterbank_inFR_im_fx[j]; // Q(hFbMixer->q_ppFilterbank_inFR_im_fx)
793 :
794 807144 : set_zero_fx( filterbank_mixer_bins_re_fx, frame_len );
795 807144 : set_zero_fx( filterbank_mixer_bins_im_fx, frame_len );
796 :
797 : #ifndef OPT_SBA_ENC_V1_BE
798 : Word16 total_guard = find_guarded_bits_fx( num_bands );
799 : move16();
800 : #endif
801 10353872 : FOR( i = 0; i < num_bands; i++ )
802 : {
803 9546728 : Word16 start_offset = pFb->fb_consts.pFilterbank_bins_start_offset[i];
804 9546728 : move16();
805 9546728 : Word16 num_bins = pFb->fb_consts.pFilterbank_bins_per_band[i];
806 9546728 : move16();
807 9546728 : Word32 mixer_const_fx = hFbMixer->prior_mixer_fx[ch][j][i]; // Q(hFbMixer->q_prior_mixer_fx)
808 9546728 : move32();
809 9546728 : pFilterbank_bin_to_band_re_fx = pFb->fb_consts.ppFilterbank_FRs_fx[0][i]; // Q30
810 9546728 : pFilterbank_bin_to_band_im_fx = pFb->fb_consts.ppFilterbank_FRs_fx[1][i]; // Q30
811 :
812 2942784180 : FOR( k = start_offset; k < num_bins + start_offset; k++ )
813 : {
814 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
815 2933237452 : move32();
816 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
817 2933237452 : move32();
818 : /*filterbank_mixer_bins_im_fx q 30 */
819 : /*mixer_const_fx q q_ppOut_pcm_fx */
820 2933237452 : pFilterbank_bin_to_band_re_fx++;
821 2933237452 : pFilterbank_bin_to_band_im_fx++;
822 : }
823 9546728 : hFbMixer->prior_mixer_fx[ch][j][i] = mixer_mat_fx[ch][j][i]; // Q(q_mixer_mat_fx)
824 9546728 : move32();
825 : }
826 : #ifndef OPT_SBA_ENC_V1_BE
827 : Word16 res_q = 0;
828 : move16();
829 : #endif
830 622020584 : FOR( k = 0; k < frame_len; k++ )
831 : {
832 : Word32 temp_out_re_fx, temp_out_im_fx;
833 :
834 621213440 : ivas_cmult_fix( filterbank_mixer_bins_re_fx[k], filterbank_mixer_bins_im_fx[k], pFb_inFR_re_fx[k],
835 621213440 : pFb_inFR_im_fx[k], &temp_out_re_fx, &temp_out_im_fx );
836 : #ifndef OPT_SBA_ENC_V1_BE
837 : res_q = sub( add( sub( sub( add( 30, *q_mixer_mat_fx ), 31 ), total_guard ), hFbMixer->q_ppFilterbank_inFR[j] ), 31 );
838 :
839 : Word16 q_check = s_min( q_pOut_fr_fx, res_q );
840 : IF( NE_16( q_check, q_pOut_fr_fx ) )
841 : {
842 : 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
843 : move32();
844 : 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
845 : move32();
846 : }
847 : #endif
848 621213440 : IF( NE_16( q_check, res_q ) )
849 : {
850 149251840 : temp_out_re_fx = L_shr( temp_out_re_fx, sub( res_q, q_check ) ); // res_q -> q_check
851 149251840 : temp_out_im_fx = L_shr( temp_out_im_fx, sub( res_q, q_check ) ); // res_q -> q_check
852 : }
853 : #ifndef OPT_SBA_ENC_V1_BE
854 : res_q = q_check;
855 : move16();
856 : #endif
857 :
858 621213440 : pOut_fr_re_fx[k] = L_add_sat( pOut_fr_re_fx[k], temp_out_re_fx ); // res_q
859 621213440 : move32();
860 621213440 : pOut_fr_im_fx[k] = L_add_sat( pOut_fr_im_fx[k], temp_out_im_fx ); // res_q
861 621213440 : move32();
862 : }
863 : #ifdef OPT_SBA_ENC_V1_BE
864 807144 : q_pOut_fr_fx = q_check;
865 : #else
866 : q_pOut_fr_fx = res_q;
867 : move16();
868 : #endif
869 : }
870 : }
871 : #ifndef OPT_SBA_ENC_V1_BE
872 : 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 ) ) );
873 : #else
874 543798 : Word16 scale = sub( s_min( L_norm_arr( pOut_fr_re_fx, frame_len ), L_norm_arr( pOut_fr_im_fx, frame_len ) ), total_guard_2 );
875 : #endif
876 543798 : scale_sig32( pOut_fr_re_fx, frame_len, scale );
877 543798 : scale_sig32( pOut_fr_im_fx, frame_len, scale );
878 543798 : ivas_imdft_fx( pOut_fr_re_fx, pOut_fr_im_fx, pMdft_out_fx[hist], frame_len );
879 543798 : q_pMdft_out_fx[hist] = add( q_pOut_fr_fx, scale );
880 543798 : move16();
881 : }
882 : #ifdef OPT_SBA_ENC_V1_BE
883 271899 : scale_sig32( pMdft_out_fx[0], len, sub( s_min( q_pMdft_out_fx[0], q_pMdft_out_fx[1] ), q_pMdft_out_fx[0] ) );
884 271899 : scale_sig32( pMdft_out_fx[1], len, sub( s_min( q_pMdft_out_fx[0], q_pMdft_out_fx[1] ), q_pMdft_out_fx[1] ) );
885 : #else
886 : 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] ) );
887 : 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] ) );
888 : #endif
889 271899 : ivas_fb_mixer_cross_fading_fx( hFbMixer, ppOut_pcm_fx, pMdft_out_fx[0], pMdft_out_fx[1], ch, frame_len, frame_len );
890 271899 : q_ppOut_pcm_fx[ch] = s_min( q_pMdft_out_fx[0], q_pMdft_out_fx[1] );
891 271899 : move16();
892 : }
893 :
894 157500 : return;
895 : }
896 :
897 : /*-----------------------------------------------------------------------------------------*
898 : * Function ivas_fb_mixer_get_in_out_mapping()
899 : *
900 : *
901 : *-----------------------------------------------------------------------------------------*/
902 157500 : void ivas_fb_mixer_get_in_out_mapping_fx(
903 : const IVAS_FB_CFG *fb_cfg, /* i : FB config. handle */
904 : Word16 in_out_mixer_map[IVAS_MAX_FB_MIXER_OUT_CH][IVAS_MAX_SPAR_FB_MIXER_IN_CH] /* i/o: mixing mapping */
905 : )
906 : {
907 : Word16 i, j;
908 :
909 157500 : set_s( (Word16 *) in_out_mixer_map, 0, IVAS_MAX_FB_MIXER_OUT_CH * IVAS_MAX_SPAR_FB_MIXER_IN_CH );
910 :
911 157500 : IF( fb_cfg->active_w_mixing )
912 : {
913 87782 : FOR( i = 0; i < fb_cfg->num_out_chans; i++ )
914 : {
915 219455 : FOR( j = 0; j < fb_cfg->num_in_chans; j++ )
916 : {
917 175564 : in_out_mixer_map[i][j] = 1;
918 175564 : move16();
919 : }
920 : }
921 : }
922 : ELSE
923 : {
924 113609 : in_out_mixer_map[0][0] = 1; /* W depends on only W input*/
925 113609 : move16();
926 341617 : FOR( i = 1; i < fb_cfg->num_out_chans; i++ )
927 : {
928 228008 : in_out_mixer_map[i][0] = 1;
929 228008 : move16();
930 : }
931 : }
932 :
933 157500 : return;
934 : }
935 :
936 : /*-----------------------------------------------------------------------------------------*
937 : * Function ivas_calculate_abs_fr()
938 : *
939 : * Function to calculate number of active bands
940 : *-----------------------------------------------------------------------------------------*/
941 :
942 564 : static Word16 ivas_calculate_abs_fr_fx(
943 : ivas_filterbank_t *pFb,
944 : const Word32 sampling_rate,
945 : const Word16 alloc_fb_resp,
946 : Word16 *index )
947 : {
948 : Word16 frame_len;
949 : Word32 ppFilterbank_FRs_s_fx[L_FRAME48k];
950 564 : Word16 bands = pFb->filterbank_num_bands;
951 564 : move16();
952 564 : Word16 i, j, num_active_bands = 0;
953 564 : move16();
954 564 : Word16 idx_short_stride_bin_to_band = 0;
955 564 : move16();
956 : Word16 quo, tmp, exp_diff;
957 :
958 564 : Word32 temp = Mpy_32_32( sampling_rate, 42949673 /* FRAMES_PER_SEC in Q31 */ );
959 564 : frame_len = extract_l( temp );
960 :
961 7174 : FOR( i = 0; i < bands; i++ )
962 : {
963 6610 : const Word32 *long_mdft_ptr_re_fx = pFb->fb_consts.ppFilterbank_FRs_fx[0][i]; // Q30
964 6610 : const Word32 *long_mdft_ptr_im_fx = pFb->fb_consts.ppFilterbank_FRs_fx[1][i]; // Q30
965 :
966 6610 : Word16 start_offset = pFb->fb_consts.pFilterbank_bins_start_offset[i];
967 6610 : move16();
968 6610 : Word16 num_bins = pFb->fb_consts.pFilterbank_bins_per_band[i];
969 6610 : move16();
970 6610 : Word16 short_mdft_start_bin = -1;
971 6610 : move16();
972 :
973 : Word32 short_stride_pow_spec_fx[MDFT_FB_BANDS_240];
974 6610 : Word32 short_stride_nrg_fx = 0;
975 6610 : move16();
976 6610 : exp_diff = 0;
977 6610 : move16();
978 :
979 6610 : Word64 cldfb_nrg_fx = 0;
980 6610 : move64();
981 6610 : Word16 short_stride = pFb->fb_bin_to_band.short_stride;
982 6610 : move16();
983 : Word32 res_dec1, res_frac, res_dec2;
984 6610 : iDiv_and_mod_32( sampling_rate, FRAMES_PER_SEC, &res_dec1, &res_frac, 0 );
985 6610 : iDiv_and_mod_32( res_dec1, short_stride, &res_dec2, &res_frac, 0 );
986 6610 : const Word16 num_bins_per_short_stride_bin = extract_l( res_dec2 );
987 6610 : iDiv_and_mod_32( res_dec1, pFb->fb_bin_to_band.num_cldfb_bands, &res_dec2, &res_frac, 0 );
988 6610 : const Word16 num_bins_per_cldfb_band = extract_l( res_dec2 );
989 :
990 6610 : Word32 short_stride_max_per_spar_band_fx = 1;
991 6610 : move32();
992 :
993 : /*loop over all stored Filter Bank Response MDFT coefficients*/
994 :
995 6610 : set32_fx( short_stride_pow_spec_fx, 0, MDFT_FB_BANDS_240 );
996 :
997 2006677 : FOR( j = start_offset; j < num_bins + start_offset; j++ )
998 : {
999 :
1000 : Word32 sq_abs_fx;
1001 :
1002 : // Word32 real = L_shr( *long_mdft_ptr_re_fx, 3 ); // Q27
1003 2000067 : Word32 real = *long_mdft_ptr_re_fx; // Q30
1004 2000067 : move32();
1005 : // Word32 imag = L_shr( *long_mdft_ptr_im_fx, 3 ); // Q27
1006 2000067 : Word32 imag = *long_mdft_ptr_im_fx; // Q30
1007 2000067 : move32();
1008 2000067 : Word64 acc = W_mac_32_32( W_mult_32_32( real, real ), imag, imag ); // Q61
1009 2000067 : sq_abs_fx = W_extract_h( acc ); // Q28
1010 2000067 : long_mdft_ptr_re_fx++;
1011 2000067 : long_mdft_ptr_im_fx++;
1012 :
1013 : /* accumulate bin energies within a short stride bin */
1014 :
1015 2000067 : short_stride_nrg_fx = L_add( short_stride_nrg_fx, L_shr( sq_abs_fx, 6 ) ); // Q22
1016 2000067 : move32();
1017 :
1018 2000067 : IF( !( add( j, 1 ) % num_bins_per_short_stride_bin ) )
1019 : {
1020 : /* new short stride bin */
1021 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*/
1022 498948 : move32();
1023 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*/
1024 498948 : short_stride_nrg_fx = 0;
1025 498948 : move32();
1026 : }
1027 :
1028 : /* accumulate bin energies within a CLDFB band */
1029 2000067 : cldfb_nrg_fx = W_mac_32_32( cldfb_nrg_fx, sq_abs_fx, 1 ); // Q29
1030 :
1031 2000067 : IF( !( add( j, 1 ) % num_bins_per_cldfb_band ) )
1032 : {
1033 123740 : Word16 exp = W_norm( cldfb_nrg_fx );
1034 123740 : cldfb_nrg_fx = W_shl( cldfb_nrg_fx, exp );
1035 123740 : exp = sub( 34, exp ); // 31 - (Q29 + exp -32)
1036 123740 : temp = Sqrt32( W_extract_h( cldfb_nrg_fx ), &exp );
1037 123740 : temp = L_shl( temp, sub( exp, Q9 ) ); // Q22
1038 123740 : pFb->fb_bin_to_band.pp_cldfb_weights_per_spar_band_fx[j / num_bins_per_cldfb_band][i] = temp; // Q22
1039 123740 : move32();
1040 123740 : cldfb_nrg_fx = 0;
1041 123740 : move32();
1042 : }
1043 : }
1044 :
1045 6610 : quo = BASOP_Util_Divide3232_Scale( ONE_IN_Q30, short_stride_max_per_spar_band_fx, &exp_diff );
1046 : /* Q of quo = Q30 - Q22 + (15 - exp_diff) --> Q23 - exp_diff.
1047 : With Mult_32_16, Q23 - exp_diff - 15 --> Q8 - exp_diff */
1048 6610 : exp_diff = sub( Q8, exp_diff );
1049 :
1050 : /*loop over the short MDFT bins*/
1051 1244850 : FOR( j = 0; j < short_stride; j++ )
1052 : {
1053 1238240 : short_stride_pow_spec_fx[j] = L_shr( Mult_32_16( short_stride_pow_spec_fx[j], quo ), exp_diff ); // Q22
1054 1238240 : move32();
1055 1238240 : short_stride_pow_spec_fx[j] = L_max( L_sub( short_stride_pow_spec_fx[j], 1258291 ), 0 ); // 0.3f * ONE_IN_Q22
1056 1238240 : move32();
1057 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
1058 1238240 : move32();
1059 :
1060 :
1061 1238240 : IF( short_stride_pow_spec_fx[j] > 0 )
1062 : {
1063 111998 : assert( idx_short_stride_bin_to_band < 2 * MDFT_FB_BANDS_240 ); /* array size of p_short_stride_bin_to_band */
1064 111998 : IF( EQ_16( short_mdft_start_bin, -1 ) )
1065 : {
1066 6610 : short_mdft_start_bin = j;
1067 6610 : move16();
1068 6610 : pFb->fb_bin_to_band.p_short_stride_start_bin_per_band[i] = j;
1069 6610 : move16();
1070 :
1071 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
1072 6610 : index[i] = idx_short_stride_bin_to_band;
1073 6610 : move16();
1074 : }
1075 :
1076 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
1077 111998 : move32();
1078 111998 : idx_short_stride_bin_to_band = add( idx_short_stride_bin_to_band, 1 );
1079 :
1080 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 );
1081 111998 : move16();
1082 : }
1083 : }
1084 : }
1085 :
1086 : /*loop over CLDFB bands*/
1087 26624 : FOR( j = 0; j < pFb->fb_bin_to_band.num_cldfb_bands; j++ )
1088 : {
1089 26060 : Word32 sum_over_spar_bands_fx = 0;
1090 26060 : move32();
1091 26060 : Word32 max_spar_band_contribution_fx = 0;
1092 26060 : move32();
1093 :
1094 26060 : Word16 spar_start = 0;
1095 26060 : move16();
1096 26060 : Word16 any_non_zero = 0;
1097 26060 : move16();
1098 :
1099 335620 : FOR( i = 0; i < bands; i++ )
1100 : {
1101 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
1102 309560 : move32();
1103 :
1104 309560 : IF( pFb->fb_bin_to_band.pp_cldfb_weights_per_spar_band_fx[j][i] > max_spar_band_contribution_fx )
1105 : {
1106 76715 : max_spar_band_contribution_fx = pFb->fb_bin_to_band.pp_cldfb_weights_per_spar_band_fx[j][i]; // Q22
1107 76715 : move32();
1108 76715 : pFb->fb_bin_to_band.p_cldfb_map_to_spar_band[j] = i;
1109 76715 : move16();
1110 : }
1111 : }
1112 :
1113 26060 : sum_over_spar_bands_fx = L_max( sum_over_spar_bands_fx, EPSILON_FX ); // Q22
1114 26060 : move32();
1115 :
1116 26060 : exp_diff = 0;
1117 26060 : move16();
1118 26060 : tmp = BASOP_Util_Divide3232_Scale( ONE_IN_Q30, sum_over_spar_bands_fx, &exp_diff );
1119 : /* Q of quo = Q30 - Q22 + (15 - exp_diff) --> Q23 - exp_diff.
1120 : With Mult_32_16, Q23 - exp_diff - 15 --> Q8 - exp_diff */
1121 26060 : exp_diff = sub( Q8, exp_diff );
1122 :
1123 335620 : FOR( i = 0; i < bands; i++ )
1124 : {
1125 309560 : test();
1126 309560 : IF( pFb->fb_bin_to_band.pp_cldfb_weights_per_spar_band_fx[j][i] == 0 && !any_non_zero )
1127 : {
1128 165303 : spar_start = add( spar_start, 1 );
1129 : }
1130 : ELSE
1131 : {
1132 144257 : any_non_zero = 1;
1133 144257 : move16();
1134 : }
1135 :
1136 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 );
1137 309560 : move32();
1138 : }
1139 26060 : pFb->fb_bin_to_band.p_spar_start_bands[j] = spar_start;
1140 26060 : move16();
1141 : }
1142 :
1143 564 : set32_fx( ppFilterbank_FRs_s_fx, 0, frame_len );
1144 :
1145 : /*Commented logic is for calculating number of active bands, can be removed if not needed */
1146 7174 : FOR( i = 0; i < bands; i++ )
1147 : {
1148 6610 : const Word32 *pFilterbank_bin_to_band_re_fx = pFb->fb_consts.ppFilterbank_FRs_fx[0][i]; // Q30
1149 6610 : move32();
1150 6610 : const Word32 *pFilterbank_bin_to_band_im_fx = pFb->fb_consts.ppFilterbank_FRs_fx[1][i]; // Q30
1151 6610 : move32();
1152 :
1153 6610 : Word16 start_offset = pFb->fb_consts.pFilterbank_bins_start_offset[i];
1154 6610 : move16();
1155 6610 : Word16 num_bins = pFb->fb_consts.pFilterbank_bins_per_band[i];
1156 6610 : move16();
1157 6610 : Word16 idx = 0;
1158 6610 : move16();
1159 6610 : Word16 abs_active_bins = pFb->fb_bin_to_band.pFb_active_bins_per_band[i];
1160 6610 : move16();
1161 6610 : Word16 abs_start_offset = pFb->fb_bin_to_band.pFb_start_bin_per_band[i];
1162 6610 : move16();
1163 :
1164 2006677 : FOR( j = start_offset; j < num_bins + start_offset; j++ )
1165 : {
1166 2000067 : Word32 temp_fx = 0;
1167 2000067 : move32();
1168 :
1169 2000067 : exp_diff = 0;
1170 2000067 : move16();
1171 2000067 : Word32 real = L_shr( *pFilterbank_bin_to_band_re_fx, 3 ); // Q27
1172 2000067 : Word32 imag = L_shr( *pFilterbank_bin_to_band_im_fx, 3 ); // Q27
1173 :
1174 : Word32 real_sq, imag_sq;
1175 2000067 : real_sq = Mpy_32_32( real, real ); // Q27 + Q27 - 31 = Q23
1176 2000067 : imag_sq = Mpy_32_32( imag, imag ); // Q27 + Q27 - 31 = Q23
1177 :
1178 2000067 : temp_fx = L_add( L_shr( real_sq, 1 ), L_shr( imag_sq, 1 ) ); // Q22
1179 :
1180 2000067 : exp_diff = 9;
1181 2000067 : move16();
1182 2000067 : temp_fx = Sqrt32( temp_fx, &exp_diff );
1183 2000067 : temp_fx = L_shl( temp_fx, sub( exp_diff, Q9 ) ); // Q22
1184 :
1185 :
1186 2000067 : pFilterbank_bin_to_band_re_fx++;
1187 2000067 : pFilterbank_bin_to_band_im_fx++;
1188 :
1189 2000067 : temp_fx = L_sub( temp_fx, 1258291 ); // 0.3 in Q22
1190 2000067 : move32();
1191 :
1192 2000067 : if ( temp_fx < 0 )
1193 : {
1194 1433594 : temp_fx = 0;
1195 1433594 : move32();
1196 : }
1197 :
1198 2000067 : test();
1199 2000067 : test();
1200 2000067 : IF( LT_16( j, add( abs_active_bins, abs_start_offset ) ) && GE_16( j, abs_start_offset ) && NE_16( alloc_fb_resp, -1 ) )
1201 : {
1202 294399 : pFb->fb_bin_to_band.pFb_bin_to_band_fx[i][idx] = temp_fx; // Q22
1203 294399 : move32();
1204 294399 : idx = add( idx, 1 );
1205 : }
1206 :
1207 :
1208 2000067 : ppFilterbank_FRs_s_fx[j] = L_add( ppFilterbank_FRs_s_fx[j], temp_fx ); // Q22
1209 2000067 : move32();
1210 : }
1211 : }
1212 :
1213 417524 : FOR( i = 0; i < frame_len; i++ )
1214 : {
1215 416960 : if ( ppFilterbank_FRs_s_fx[i] < 0 )
1216 : {
1217 0 : ppFilterbank_FRs_s_fx[i] = 419430; // 0.1 in Q22
1218 0 : move32();
1219 : }
1220 : }
1221 :
1222 564 : IF( NE_16( alloc_fb_resp, -1 ) )
1223 : {
1224 3705 : FOR( j = 0; j < bands; j++ )
1225 : {
1226 3414 : Word16 abs_active_bins = pFb->fb_bin_to_band.pFb_active_bins_per_band[j];
1227 3414 : Word16 abs_start_offset = pFb->fb_bin_to_band.pFb_start_bin_per_band[j];
1228 3414 : exp_diff = 0;
1229 :
1230 3414 : move16();
1231 3414 : move16();
1232 3414 : move16();
1233 :
1234 297813 : FOR( i = 0; i < abs_active_bins; i++ )
1235 : {
1236 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 );
1237 294399 : pFb->fb_bin_to_band.pFb_bin_to_band_fx[j][i] = L_shl( L_deposit_l( tmp ), add( Q7, exp_diff ) ); // Q22
1238 294399 : move32();
1239 : /*if(pFb->fb_bin_to_band.pFb_bin_to_band[j][i] > 0.5f)
1240 : {
1241 : num_active_bands = j + 1;
1242 : break;
1243 : }*/
1244 : }
1245 : }
1246 : }
1247 :
1248 564 : return num_active_bands;
1249 : }
1250 :
1251 : /*-----------------------------------------------------------------------------------------*
1252 : * Function ivas_get_active_bins()
1253 : *
1254 : *
1255 : *-----------------------------------------------------------------------------------------*/
1256 :
1257 1128 : static void ivas_get_active_bins_fx(
1258 : const Word16 **pActive_bins,
1259 : const Word16 **pActive_bins_abs,
1260 : const Word16 **pStart_offset,
1261 : const Word16 **pStart_offset_abs,
1262 : const Word32 sampling_rate )
1263 : {
1264 : Word16 sr_idx;
1265 :
1266 1128 : IF( EQ_32( sampling_rate, 32000 ) )
1267 : {
1268 462 : sr_idx = 1;
1269 462 : move16();
1270 : }
1271 666 : ELSE IF( EQ_32( sampling_rate, 16000 ) )
1272 : {
1273 158 : sr_idx = 2;
1274 158 : move16();
1275 : }
1276 : ELSE
1277 : {
1278 508 : sr_idx = 0;
1279 508 : move16();
1280 : }
1281 :
1282 1128 : *pActive_bins_abs = ivas_fb_abs_bins_per_band_12band_1ms[sr_idx];
1283 1128 : move16();
1284 1128 : *pActive_bins = ivas_fb_bins_per_band_12band_1ms[sr_idx];
1285 1128 : move16();
1286 1128 : *pStart_offset_abs = ivas_fb_abs_bins_start_offset_12band_1ms[sr_idx];
1287 1128 : move16();
1288 1128 : *pStart_offset = ivas_fb_bins_start_offset_12band_1ms[sr_idx];
1289 1128 : move16();
1290 :
1291 1128 : return;
1292 : }
1293 :
1294 :
1295 : /*-----------------------------------------------------------------------------------------*
1296 : * Function ivas_filterbank_setup()
1297 : *
1298 : * Filterbank setup, initialization
1299 : *-----------------------------------------------------------------------------------------*/
1300 :
1301 1668 : static ivas_error ivas_filterbank_setup_fx(
1302 : IVAS_FB_MIXER_HANDLE hFbMixer,
1303 : const Word32 sampling_rate,
1304 : Word16 *index )
1305 : {
1306 : Word16 i, j, exp, tmp;
1307 : const Word32 *pAll_fb_fr_fx[2];
1308 1668 : const Word16 *pAll_bins_start_offset = NULL;
1309 1668 : const Word16 *pAll_bins_per_band = NULL;
1310 1668 : const Word16 *pAll_bins_start_offset_abs = NULL;
1311 1668 : const Word16 *pAll_bins_per_band_abs = NULL;
1312 1668 : const Word16 *pAll_bins_per_band_48k = NULL;
1313 : ivas_error error;
1314 1668 : IVAS_FB_CFG *pCfg = hFbMixer->fb_cfg;
1315 :
1316 1668 : error = IVAS_ERR_OK;
1317 1668 : move32();
1318 :
1319 1668 : IF( pCfg->num_out_chans > 0 )
1320 : {
1321 564 : hFbMixer->pFb->filterbank_num_bands = ivas_get_num_bands( sampling_rate );
1322 564 : move16();
1323 :
1324 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 );
1325 :
1326 564 : IF( EQ_16( pCfg->fb_latency, NS2SA_FX2( sampling_rate, DELAY_FB_1_NS ) ) )
1327 : {
1328 564 : pAll_fb_fr_fx[0] = ivas_fb_fr_12band_1ms_re_fx; // Q30
1329 564 : move32();
1330 564 : pAll_fb_fr_fx[1] = ivas_fb_fr_12band_1ms_im_fx; // Q30
1331 564 : move32();
1332 :
1333 564 : pAll_bins_per_band_48k = ivas_fb_bins_per_band_12band_1ms[0];
1334 564 : move16();
1335 : }
1336 : ELSE
1337 : {
1338 0 : return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Wrong FB in ivas_filterbank_setup()!" );
1339 : }
1340 : }
1341 :
1342 1668 : hFbMixer->cross_fade_end_offset = add( pCfg->fade_len, pCfg->pcm_offset );
1343 1668 : move16();
1344 1668 : hFbMixer->cross_fade_start_offset = sub( hFbMixer->cross_fade_end_offset, pCfg->fade_len );
1345 1668 : move16();
1346 1668 : hFbMixer->ana_window_offset = add( pCfg->fb_latency, pCfg->pcm_offset );
1347 1668 : move16();
1348 :
1349 1668 : IF( NE_32( ( error = ivas_fb_mixer_get_window_fx( pCfg->fb_latency, sampling_rate, &( hFbMixer->pAna_window_fx ) ) ), IVAS_ERR_OK ) )
1350 : {
1351 0 : return error;
1352 : }
1353 :
1354 1668 : IF( NE_32( ( error = ivas_fb_mixer_get_window_fx( pCfg->fade_len, sampling_rate, &( hFbMixer->pFilterbank_cross_fade_fx ) ) ), IVAS_ERR_OK ) )
1355 : {
1356 0 : return error;
1357 : }
1358 :
1359 1668 : IF( pCfg->num_out_chans > 0 )
1360 : {
1361 564 : ivas_filterbank_t *pFb = hFbMixer->pFb;
1362 564 : Word16 offset = 0;
1363 564 : move16();
1364 :
1365 564 : pFb->fb_consts.pFilterbank_bins_per_band = pAll_bins_per_band;
1366 564 : pFb->fb_consts.pFilterbank_bins_start_offset = pAll_bins_start_offset;
1367 564 : pFb->fb_bin_to_band.pFb_active_bins_per_band = pAll_bins_per_band_abs;
1368 564 : pFb->fb_bin_to_band.pFb_start_bin_per_band = pAll_bins_start_offset_abs;
1369 :
1370 : /* Initialization for short stride Parameter calculation and SPAR CLDFB reconstruction */
1371 564 : SWITCH( sampling_rate )
1372 : {
1373 254 : case 48000:
1374 254 : pFb->fb_bin_to_band.num_cldfb_bands = 60; /* sampling_rate * 1.0f / 800.0f */
1375 254 : move16();
1376 254 : BREAK;
1377 231 : case 32000:
1378 231 : pFb->fb_bin_to_band.num_cldfb_bands = 40;
1379 231 : move16();
1380 231 : BREAK;
1381 79 : case 16000:
1382 79 : pFb->fb_bin_to_band.num_cldfb_bands = 20;
1383 79 : move16();
1384 79 : BREAK;
1385 : }
1386 :
1387 : /*pFb->fb_bin_to_band.cldfb_stride = ( int16_t )( ( sampling_rate / FRAMES_PER_SEC ) / CLDFB_NO_COL_MAX );*/ /* equals num_cldfb_bands*/
1388 : // pFb->fb_bin_to_band.short_stride = extract_l( ( sampling_rate / FRAMES_PER_SEC ) / 4 );
1389 564 : tmp = BASOP_Util_Divide3232_Scale( sampling_rate, FRAMES_PER_SEC, &exp );
1390 564 : pFb->fb_bin_to_band.short_stride = shr( tmp, add( sub( 15, exp ), 2 ) );
1391 :
1392 564 : move16();
1393 :
1394 564 : set32_fx( pFb->fb_bin_to_band.p_short_stride_bin_to_band_fx, 0, 2 * MDFT_FB_BANDS_240 );
1395 :
1396 564 : set16_fx( pFb->fb_bin_to_band.p_cldfb_map_to_spar_band, 0, CLDFB_NO_CHANNELS_MAX );
1397 564 : set16_fx( pFb->fb_bin_to_band.p_spar_start_bands, 0, CLDFB_NO_CHANNELS_MAX );
1398 :
1399 11844 : FOR( j = 0; j < IVAS_MAX_NUM_FB_BANDS; j++ )
1400 : {
1401 11280 : pFb->fb_bin_to_band.p_short_stride_num_bins_per_band[j] = 0; /* aka num_active_bins per SPAR band */
1402 11280 : move16();
1403 11280 : pFb->fb_bin_to_band.p_short_stride_start_bin_per_band[j] = 0; /* first considered bin index per SPAR band */
1404 11280 : move16();
1405 :
1406 11280 : pFb->fb_bin_to_band.pp_short_stride_bin_to_band_fx[j] = NULL;
1407 :
1408 688080 : FOR( i = 0; i < CLDFB_NO_CHANNELS_MAX; i++ )
1409 : {
1410 :
1411 676800 : pFb->fb_bin_to_band.pp_cldfb_weights_per_spar_band_fx[i][j] = 0;
1412 676800 : move32();
1413 : }
1414 : }
1415 564 : IF( EQ_32( sampling_rate, 48000 ) )
1416 : {
1417 3302 : FOR( j = 0; j < pFb->filterbank_num_bands; j++ )
1418 : {
1419 :
1420 3048 : pFb->fb_consts.ppFilterbank_FRs_fx[0][j] = &pAll_fb_fr_fx[0][offset]; // Q30
1421 3048 : pFb->fb_consts.ppFilterbank_FRs_fx[1][j] = &pAll_fb_fr_fx[1][offset]; // Q30
1422 :
1423 3048 : offset = add( offset, pFb->fb_consts.pFilterbank_bins_per_band[j] );
1424 : }
1425 :
1426 : /****************************************Calculate abs fr ***************************/
1427 :
1428 254 : ivas_calculate_abs_fr_fx( pFb, sampling_rate, pCfg->active_w_mixing, index );
1429 : }
1430 : ELSE
1431 : {
1432 :
1433 : Word32 *ppFilterbank_FRs_re_temp_fx[MAX_NUM_BANDS_DIFF_NON48K];
1434 : Word32 *ppFilterbank_FRs_im_temp_fx[MAX_NUM_BANDS_DIFF_NON48K];
1435 : Word16 active_bins_temp[MAX_NUM_BANDS_DIFF_NON48K];
1436 : Word16 start_offset_temp[MAX_NUM_BANDS_DIFF_NON48K];
1437 : Word16 num_diff_bands, start_diff_band_non48k;
1438 :
1439 310 : num_diff_bands = MAX_NUM_BANDS_DIFF_NON48K;
1440 310 : start_diff_band_non48k = sub( pFb->filterbank_num_bands, num_diff_bands );
1441 310 : move16();
1442 :
1443 310 : pFb->fb_consts.pFilterbank_bins_per_band = pAll_bins_per_band;
1444 310 : pFb->fb_consts.pFilterbank_bins_start_offset = pAll_bins_start_offset;
1445 :
1446 3872 : FOR( j = 0; j < pFb->filterbank_num_bands; j++ )
1447 : {
1448 3562 : Word16 num_active_bins = pFb->fb_consts.pFilterbank_bins_per_band[j];
1449 3562 : move16();
1450 :
1451 3562 : IF( j < start_diff_band_non48k )
1452 : {
1453 :
1454 2632 : pFb->fb_consts.ppFilterbank_FRs_fx[0][j] = &pAll_fb_fr_fx[0][offset]; // Q30
1455 2632 : pFb->fb_consts.ppFilterbank_FRs_fx[1][j] = &pAll_fb_fr_fx[1][offset]; // Q30
1456 : }
1457 : ELSE
1458 : {
1459 930 : Copy32( &pAll_fb_fr_fx[0][offset], pFb->fb_consts.ppFilterbank_FRs_non48k_fx[0][j], num_active_bins ); // Q30
1460 930 : Copy32( &pAll_fb_fr_fx[1][offset], pFb->fb_consts.ppFilterbank_FRs_non48k_fx[1][j], num_active_bins ); // Q30
1461 : }
1462 :
1463 3562 : offset = add( offset, pAll_bins_per_band_48k[j] );
1464 : }
1465 :
1466 1240 : FOR( j = start_diff_band_non48k; j < pFb->filterbank_num_bands; j++ )
1467 : {
1468 :
1469 930 : ppFilterbank_FRs_re_temp_fx[j - start_diff_band_non48k] = pFb->fb_consts.ppFilterbank_FRs_non48k_fx[0][j]; // Q30
1470 930 : ppFilterbank_FRs_im_temp_fx[j - start_diff_band_non48k] = pFb->fb_consts.ppFilterbank_FRs_non48k_fx[1][j]; // Q30
1471 :
1472 930 : active_bins_temp[j - start_diff_band_non48k] = pFb->fb_consts.pFilterbank_bins_per_band[j];
1473 930 : start_offset_temp[j - start_diff_band_non48k] = pFb->fb_consts.pFilterbank_bins_start_offset[j];
1474 930 : move16();
1475 930 : move16();
1476 : }
1477 :
1478 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,
1479 310 : active_bins_temp, start_offset_temp, num_diff_bands, pCfg->fb_latency, sampling_rate );
1480 :
1481 :
1482 1240 : FOR( j = start_diff_band_non48k; j < pFb->filterbank_num_bands; j++ )
1483 : {
1484 :
1485 930 : pFb->fb_consts.ppFilterbank_FRs_fx[0][j] = (const Word32 *) pFb->fb_consts.ppFilterbank_FRs_non48k_fx[0][j]; // Q30
1486 930 : pFb->fb_consts.ppFilterbank_FRs_fx[1][j] = (const Word32 *) pFb->fb_consts.ppFilterbank_FRs_non48k_fx[1][j]; // Q30
1487 : }
1488 :
1489 : /******************************************** Calculate abs fr ****************************************************/
1490 :
1491 310 : ivas_calculate_abs_fr_fx( pFb, sampling_rate, pCfg->active_w_mixing, index );
1492 : }
1493 : }
1494 :
1495 1668 : return error;
1496 : }
1497 :
1498 : /*-----------------------------------------------------------------------------------------*
1499 : * Function ivas_fb_mixer_get_window()
1500 : *
1501 : *
1502 : *-----------------------------------------------------------------------------------------*/
1503 :
1504 3336 : static ivas_error ivas_fb_mixer_get_window_fx(
1505 : const Word16 fade_len, /* i : window fading length in samples */
1506 : const Word32 sampling_rate, /* i : sampling rate */
1507 : const Word16 **pWindow /* o : pointer to the window coefficents */
1508 : )
1509 : {
1510 : ivas_error error;
1511 :
1512 3336 : error = IVAS_ERR_OK;
1513 3336 : move32();
1514 :
1515 3336 : IF( EQ_16( fade_len, NS2SA_FX2( sampling_rate, DELAY_FB_4_NS ) ) )
1516 : {
1517 1192 : SWITCH( sampling_rate )
1518 : {
1519 882 : case 48000:
1520 882 : *pWindow = ivas_fb_cf_4ms_48k_fx;
1521 882 : BREAK;
1522 231 : case 32000:
1523 231 : *pWindow = ivas_fb_cf_4ms_32k_fx;
1524 231 : BREAK;
1525 79 : case 16000:
1526 79 : *pWindow = ivas_fb_cf_4ms_16k_fx;
1527 79 : BREAK;
1528 0 : default:
1529 0 : return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Unsupported Sampling frequency!" );
1530 : }
1531 : }
1532 2144 : ELSE IF( EQ_16( fade_len, NS2SA_FX2( sampling_rate, DELAY_FB_1_NS ) ) )
1533 : {
1534 2144 : SWITCH( sampling_rate )
1535 : {
1536 1566 : case 48000:
1537 1566 : *pWindow = ivas_fb_cf_1ms_48k_fx;
1538 1566 : BREAK;
1539 499 : case 32000:
1540 499 : *pWindow = ivas_fb_cf_1ms_32k_fx;
1541 499 : BREAK;
1542 79 : case 16000:
1543 79 : *pWindow = ivas_fb_cf_1ms_16k_fx;
1544 79 : BREAK;
1545 0 : default:
1546 0 : return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Unsupported Sampling frequency!" );
1547 : }
1548 : }
1549 : ELSE
1550 : {
1551 0 : IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Error: Incorrect FB window fade len (%f ms)\n", ( fade_len / 1000000.f ) );
1552 : }
1553 :
1554 3336 : return error;
1555 : }
1556 :
1557 :
1558 310 : static const Word32 *ivas_get_cheby_ramp_fx(
1559 : const Word16 delay )
1560 : {
1561 310 : const Word32 *pCheby_fx = NULL;
1562 :
1563 310 : SWITCH( delay )
1564 : {
1565 231 : case IVAS_FB_1MS_32K_SAMP:
1566 231 : pCheby_fx = ivas_fb_resp_cheby_ramp_32del_fx;
1567 231 : BREAK;
1568 79 : case IVAS_FB_1MS_16K_SAMP:
1569 79 : pCheby_fx = ivas_fb_resp_cheby_ramp_16del_fx;
1570 79 : BREAK;
1571 0 : default:
1572 0 : assert( !"Unsupported cheby ramp length!" );
1573 : }
1574 :
1575 310 : return pCheby_fx;
1576 : }
1577 :
1578 310 : static void ivas_get_ld_fb_resp_fx(
1579 : Word32 **ppIdeal_FRs_re_fx, // i: Q30
1580 : Word32 **ppIdeal_FRs_im_fx, // i: Q30
1581 : Word32 **ppNew_FRs_re_fx, // o: Q30
1582 : Word32 **ppNew_FRs_im_fx, // o: Q30
1583 : const Word16 *pActive_bins,
1584 : const Word16 *pStart_offset,
1585 : const Word16 num_bands,
1586 : const Word16 delay,
1587 : const Word32 sampling_rate )
1588 : {
1589 : Word16 b, s, frame_len;
1590 : const Word32 *pCheby_fx;
1591 310 : frame_len = 0;
1592 310 : move16();
1593 : /*common scratch buffers for computing impulse/frequency responses,
1594 : pre-ring, post-ring and circular shifted outputs to optimize stack*/
1595 : Word32 scratch1_fx[L_FRAME32k * 2];
1596 : Word32 scratch2_fx[L_FRAME32k * 2];
1597 :
1598 310 : set32_fx( scratch1_fx, 0, L_FRAME32k * 2 );
1599 310 : set32_fx( scratch2_fx, 0, L_FRAME32k * 2 );
1600 :
1601 310 : const Word32 *han_win_fx = NULL;
1602 :
1603 310 : SWITCH( sampling_rate )
1604 : {
1605 0 : case 48000:
1606 0 : frame_len = 960;
1607 0 : move16();
1608 0 : han_win_fx = ivas_han_win_48k_fx; // Q31
1609 0 : BREAK;
1610 231 : case 32000:
1611 231 : frame_len = 640;
1612 231 : move16();
1613 231 : han_win_fx = ivas_han_win_32k_fx; // Q31
1614 231 : BREAK;
1615 79 : case 16000:
1616 79 : frame_len = 320;
1617 79 : move16();
1618 79 : han_win_fx = ivas_han_win_16k_fx; // Q31
1619 79 : BREAK;
1620 : }
1621 :
1622 310 : pCheby_fx = ivas_get_cheby_ramp_fx( delay ); // Q31
1623 :
1624 310 : b = 0;
1625 310 : s = 0;
1626 310 : move16();
1627 310 : move16();
1628 :
1629 310 : assert( sampling_rate == 32000 || sampling_rate == 16000 );
1630 :
1631 1240 : FOR( b = 0; b < num_bands; b++ )
1632 : {
1633 :
1634 930 : set32_fx( scratch2_fx, 0, shl( frame_len, 1 ) );
1635 930 : Copy32( ppIdeal_FRs_re_fx[b], &scratch2_fx[pStart_offset[b]], pActive_bins[b] ); // Q30
1636 930 : Copy32( ppIdeal_FRs_im_fx[b], &scratch2_fx[frame_len + pStart_offset[b]], pActive_bins[b] ); // Q30
1637 :
1638 930 : Word16 guard_bits = sub( L_norm_arr( scratch2_fx, shl( L_FRAME32k, 1 ) ), find_guarded_bits_fx( shl( frame_len, 1 ) ) );
1639 930 : Scale_sig32( scratch2_fx, shl( L_FRAME32k, 1 ), guard_bits ); // Q30 + guard_bits
1640 :
1641 930 : ivas_imdft_fx( scratch2_fx, &scratch2_fx[frame_len], scratch1_fx, frame_len );
1642 :
1643 1191330 : FOR( Word16 x = 0; x < shl( L_FRAME32k, 1 ); x++ )
1644 : {
1645 1190400 : scratch2_fx[x] = L_shr( scratch2_fx[x], guard_bits ); // (Q30 + guard_bits) - guard_bits = Q30
1646 1190400 : scratch1_fx[x] = L_shr( scratch1_fx[x], guard_bits ); // (Q30 + guard_bits) - guard_bits = Q30
1647 :
1648 1190400 : move32();
1649 1190400 : move32();
1650 : }
1651 :
1652 : /*apply circular shift and hanning window*/
1653 :
1654 520290 : FOR( s = delay; s < frame_len + delay; s++ )
1655 : {
1656 :
1657 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
1658 519360 : move32();
1659 : }
1660 :
1661 494322 : FOR( ; s < 2 * frame_len; s++ )
1662 : {
1663 :
1664 493392 : scratch2_fx[s - delay] = Mpy_32_32( scratch1_fx[s], han_win_fx[s - ( frame_len + delay )] ); // Q30
1665 493392 : move32();
1666 : }
1667 :
1668 26898 : FOR( s = 0; s < delay; s++ )
1669 : {
1670 :
1671 25968 : scratch2_fx[( ( ( frame_len * 2 ) - delay ) + s )] = L_negate( Mpy_32_32( scratch1_fx[s], han_win_fx[( frame_len - delay ) + s] ) ); // Q30
1672 25968 : move32();
1673 : }
1674 :
1675 : /*apply heavy/cheby ramp window and compute pre ring*/
1676 :
1677 27828 : FOR( s = 0; s < delay + 1; s++ )
1678 : {
1679 26898 : scratch1_fx[s] = Mpy_32_32( scratch2_fx[s], pCheby_fx[delay - s] ); // Q30
1680 26898 : move32();
1681 : }
1682 :
1683 493392 : FOR( ; s < frame_len; s++ )
1684 : {
1685 492462 : scratch1_fx[s] = 0;
1686 492462 : move32();
1687 : }
1688 :
1689 494322 : FOR( ; s < 2 * frame_len - delay; s++ )
1690 : {
1691 493392 : scratch1_fx[s] = scratch2_fx[s];
1692 493392 : move32();
1693 : }
1694 :
1695 26898 : FOR( ; s < 2 * frame_len; s++ )
1696 : {
1697 25968 : scratch1_fx[s] = Mpy_32_32( scratch2_fx[s], L_sub( ONE_IN_Q31, pCheby_fx[s - ( 2 * frame_len - delay )] ) ); // Q30
1698 25968 : move32();
1699 : }
1700 :
1701 : /*IR - pre ring + post ring*/
1702 1038720 : FOR( s = 1; s < 2 * frame_len; s++ )
1703 : {
1704 1037790 : scratch2_fx[s] = L_sub( L_sub( scratch2_fx[s] /*pre ring*/, scratch1_fx[s] /*post ring*/ ), scratch1_fx[frame_len * 2 - s] );
1705 1037790 : move32();
1706 : }
1707 :
1708 1013682 : FOR( s = 0; s < 2 * frame_len - delay; s++ )
1709 : {
1710 1012752 : scratch1_fx[s + delay] = scratch2_fx[s];
1711 1012752 : move32();
1712 : }
1713 :
1714 26898 : FOR( ; s < 2 * frame_len; s++ )
1715 : {
1716 25968 : scratch1_fx[( s - ( ( frame_len * 2 ) - delay ) )] = L_negate( scratch2_fx[s] );
1717 25968 : move32();
1718 : }
1719 :
1720 : /* apply final window*/
1721 930 : const Word32 *sine_till_delay = ivas_sine_delay_32_fx; // Q30
1722 930 : Word16 offset = 1;
1723 930 : Word16 delay_16 = 0;
1724 :
1725 930 : move16();
1726 930 : move16();
1727 :
1728 930 : if ( EQ_16( delay, IVAS_FB_1MS_16K_SAMP ) )
1729 : {
1730 237 : delay_16 = 1;
1731 237 : move16();
1732 : }
1733 :
1734 26898 : FOR( s = 0; s < delay; s++ )
1735 : {
1736 25968 : scratch1_fx[s] = Mpy_32_32( scratch1_fx[s], sine_till_delay[s + offset * delay_16] ); // Q30 + Q30 - 31 = Q29
1737 25968 : offset = add( offset, 1 );
1738 25968 : scratch1_fx[s] = L_shl( scratch1_fx[s], 1 ); // Q30
1739 :
1740 25968 : move32();
1741 25968 : move32();
1742 : }
1743 :
1744 930 : const Word32 *sine_till_frame_len = NULL;
1745 :
1746 930 : IF( EQ_16( delay, IVAS_FB_1MS_16K_SAMP ) )
1747 : {
1748 237 : sine_till_frame_len = ivas_sine_frame_len_640_del_16_fx; // Q30
1749 237 : move32();
1750 : }
1751 : ELSE
1752 : {
1753 693 : sine_till_frame_len = ivas_sine_frame_len_640_del_32_fx; // Q30
1754 693 : move32();
1755 : }
1756 930 : Word16 iterator = 0;
1757 930 : move16();
1758 469284 : FOR( s = 2 * delay; s < frame_len + 1; s++ )
1759 : {
1760 468354 : scratch1_fx[s] = Mpy_32_32( scratch1_fx[s], sine_till_frame_len[iterator] ); // Q30 + Q30 - 31 = Q29
1761 468354 : iterator = add( iterator, 1 );
1762 468354 : scratch1_fx[s] = L_shl( scratch1_fx[s], 1 ); // Q30
1763 :
1764 468354 : move32();
1765 468354 : move32();
1766 : }
1767 :
1768 519360 : FOR( ; s < 2 * frame_len; s++ )
1769 : {
1770 518430 : scratch1_fx[s] = 0;
1771 :
1772 518430 : move32();
1773 : }
1774 :
1775 : /*compute frequency response*/
1776 930 : ivas_mdft_fx( scratch1_fx, scratch2_fx, &scratch2_fx[frame_len], shl( frame_len, 1 ), frame_len );
1777 :
1778 930 : Copy32( &scratch2_fx[pStart_offset[b]], ppNew_FRs_re_fx[b], pActive_bins[b] ); // Q30
1779 930 : Copy32( &scratch2_fx[( frame_len + pStart_offset[b] )], ppNew_FRs_im_fx[b], pActive_bins[b] ); // Q30
1780 : }
1781 :
1782 310 : return;
1783 : }
|