From 45bf8fe1d6e5d4b57a27b06f9f152f35c5c7fc24 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 30 Aug 2024 19:39:44 +0530 Subject: [PATCH] Precision improvements in shoebox, apa_exec float cleanup, SBA PLC high MLD fixes --- lib_com/cnst.h | 1 + lib_com/ivas_sns_com_fx.c | 2 +- lib_dec/er_dec_tcx_fx.c | 2 + lib_dec/ivas_mdct_core_dec.c | 11 +- lib_dec/jbm_pcmdsp_apa.c | 1206 +------------------------- lib_dec/jbm_pcmdsp_apa.h | 2 +- lib_dec/lib_dec_fx.c | 4 +- lib_dec/tonalMDCTconcealment_fx.c | 21 +- lib_rend/ivas_reverb.c | 18 - lib_rend/ivas_reverb_filter_design.c | 92 +- lib_rend/ivas_shoebox.c | 58 +- 11 files changed, 121 insertions(+), 1296 deletions(-) diff --git a/lib_com/cnst.h b/lib_com/cnst.h index 81e1647ca..e7c27f942 100644 --- a/lib_com/cnst.h +++ b/lib_com/cnst.h @@ -2749,6 +2749,7 @@ enum #define LG10 24660 /* 10*log10(2) in Q13 */ #define LG10_s3_0 16440 /* 10*log10(2)/1.55 = 1.00343331 in Q14 */ #define LOG2_10 27213 /* log base 2 of 10 in Q12 */ +#define LOG2_10_Q29 1783446566 /* log base 2 of 10 in Q12 */ #define LOG10_2_Q31 646456993 /* inverse log base 10 of 2 in Q31 */ #define MU_MA_FX 10923 /* original prediction factor for the AMR WB tables (Q15) */ diff --git a/lib_com/ivas_sns_com_fx.c b/lib_com/ivas_sns_com_fx.c index ed19a8613..e215c00ff 100644 --- a/lib_com/ivas_sns_com_fx.c +++ b/lib_com/ivas_sns_com_fx.c @@ -197,7 +197,7 @@ void sns_compute_scf_fx( { Word16 e_tmp = norm_l( xs[i] ); Word16 f_tmp = Log2_norm_lc( L_shl( xs[i], e_tmp ) ); - e_tmp = sub( sub( 30, e_tmp ), q ); + e_tmp = sub( sub( 34, e_tmp ), q ); /* Note: Mpy_32_16 is used temporarily for this computation, It needs to be replaced with appropriate BASOP. */ xl[i] = Mpy_32_16( e_tmp, f_tmp, 16384 ); /* Q16 */ move32(); diff --git a/lib_dec/er_dec_tcx_fx.c b/lib_dec/er_dec_tcx_fx.c index bcd91a65f..48299ed32 100644 --- a/lib_dec/er_dec_tcx_fx.c +++ b/lib_dec/er_dec_tcx_fx.c @@ -2143,6 +2143,8 @@ void con_tcx_ivas_fx( move16(); /* update memory for low band */ + st->Q_syn = 0; + move16(); Scale_sig( hTcxDec->old_syn_Overl, shr( st->L_frame, 1 ), sub( -1, Q_syn ) ); lerp( hTcxDec->syn_OverlFB, hTcxDec->syn_Overl, shr( st->L_frame, 1 ), shr( L_frame, 1 ) ); lerp( hTcxDec->syn_Overl_TDACFB, hTcxDec->syn_Overl_TDAC, shr( st->L_frame, 1 ), shr( L_frame, 1 ) ); diff --git a/lib_dec/ivas_mdct_core_dec.c b/lib_dec/ivas_mdct_core_dec.c index 9e5c08937..608fc9987 100644 --- a/lib_dec/ivas_mdct_core_dec.c +++ b/lib_dec/ivas_mdct_core_dec.c @@ -2130,6 +2130,10 @@ void ivas_mdct_core_reconstruct_fx( Scale_sig( st->hTcxDec->syn_Overl, L_FRAME32k / 2, sub( st->Q_syn, q_win ) ); Scale_sig( st->hHQ_core->old_out_LB_fx, L_FRAME32k, sub( st->Q_syn, q_win ) ); Scale_sig( st->hHQ_core->old_out_fx, L_FRAME48k, sub( st->Q_syn, q_win ) ); + st->hHQ_core->Q_old_wtda = st->Q_syn; + move16(); + st->hHQ_core->Q_old_wtda_LB = st->Q_syn; + move16(); } ELSE /*ACELP core for ACELP-PLC */ { @@ -2137,7 +2141,6 @@ void ivas_mdct_core_reconstruct_fx( Scale_sig( synth_buf_fx, add( add( st->hTcxDec->old_synth_len, L_FRAME_PLUS ), M ), negate( q_syn ) ); Scale_sig( synth_bufFB_fx, add( add( st->hTcxDec->old_synth_lenFB, L_FRAME_PLUS ), M ), negate( q_syn ) ); q_syn = 0; - st->Q_syn = 0; move16(); move16(); /* PLC: [TCX: TD PLC] */ @@ -2181,10 +2184,6 @@ void ivas_mdct_core_reconstruct_fx( Scale_sig( st->mem_syn2_fx, M, st->Q_syn ); Scale_sig( st->mem_syn_r, M, st->Q_syn ); } - st->hHQ_core->Q_old_wtda = st->Q_syn; - move16(); - st->hHQ_core->Q_old_wtda_LB = st->Q_syn; - move16(); /*--------------------------------------------------------------------------------* * Updates *--------------------------------------------------------------------------------*/ @@ -2568,7 +2567,7 @@ void ivas_mdct_core_tns_ns_fx( FOR( Word16 i = 0; i < st->hTonalMDCTConc->nScaleFactors; i++ ) { - sns_int_scf_fx[i] = Madd_32_16( Mpy_32_16_1( L_shl( scf_last_m[i], add( 1, scf_last_e[i] ) ), fade_out ), L_shl( scf_bg[i], 1 ), fade_in ); + sns_int_scf_fx[i] = Madd_32_16( Mpy_32_16_1( L_shl( scf_last_m[i], add( 1, scf_last_e[i] ) ), fade_out ), scf_bg[i], fade_in ); move32(); } } diff --git a/lib_dec/jbm_pcmdsp_apa.c b/lib_dec/jbm_pcmdsp_apa.c index c05aa34d7..e5fc42d8d 100644 --- a/lib_dec/jbm_pcmdsp_apa.c +++ b/lib_dec/jbm_pcmdsp_apa.c @@ -53,13 +53,10 @@ #include "rom_dec.h" -#ifdef IVAS_FLOAT_FIXED #include "prot_fx.h" #define INV_100_Q15 328 #define INV_400_Q15 82 #define INV_80_Q15 410 -#define IVAS_FLOAT_FIXED_TO_BE_REMOVED -#endif /*---------------------------------------------------------------------* @@ -78,13 +75,11 @@ struct apa_state_t /* output buffer */ bool evs_compat_mode; - float *buf_out; Word16 *buf_out_fx; UWord16 buf_out_capacity; UWord16 l_buf_out; /* Hann window */ - float win[APA_BUF_PER_CHANNEL]; const Word16 *win_fx; // const Word16 *win_fx; UWord16 l_halfwin; @@ -126,7 +121,6 @@ struct apa_state_t UWord16 wss; /* waveform subsampling per channel */ UWord16 css; /* correlation subsampling per channel */ - float targetQuality; Word32 targetQuality_fx; /* Q16 */ UWord16 qualityred; /* quality reduction threshold */ UWord16 qualityrise; /* quality rising for adaptive quality thresholds */ @@ -143,21 +137,6 @@ struct apa_state_t * Local function prototypes *---------------------------------------------------------------------*/ -#ifndef IVAS_FLOAT_FIXED -static float apa_corrEnergy2dB( float energy, uint16_t corr_len ); - -static float apa_getQualityIncreaseForLowEnergy( float energydB ); - -static bool logarithmic_search( const apa_state_t *ps, const float *signal, int16_t s_start, uint16_t inlen, uint16_t offset, uint16_t fixed_pos, uint16_t corr_len, uint16_t wss, uint16_t css, int16_t *synchpos ); - -static bool find_synch( apa_state_t *ps, const float *in, uint16_t l_in, int16_t s_start, uint16_t s_len, int16_t fixed_pos, uint16_t corr_len, uint16_t offset, float *energy, float *quality, int16_t *synch_pos ); - -static bool copy_frm( apa_state_t *ps, const float frm_in[], float frm_out[], uint16_t *l_frm_out ); - -static bool shrink_frm( apa_state_t *ps, const float frm_in[], uint16_t maxScaling, float frm_out[], uint16_t *l_frm_out ); - -static bool extend_frm( apa_state_t *ps, const float frm_in[], float frm_out[], uint16_t *l_frm_out ); -#else Word16 apa_corrEnergy2dB_fx( Word32 energy, Word16 energyExp, Word16 corr_len ); Word16 apa_getQualityIncreaseForLowEnergy_fx( Word16 energydB ); @@ -171,14 +150,12 @@ static bool copy_frm_fx( apa_state_t *ps, const Word16 frm_in[], Word16 frm_out[ static bool shrink_frm_fx( apa_state_t *ps, const Word16 frm_in[], UWord16 maxScaling, Word16 frm_out[], UWord16 *l_frm_out ); static bool extend_frm_fx( apa_state_t *ps, const Word16 frm_in[], Word16 frm_out[], UWord16 *l_frm_out ); -#endif /*---------------------------------------------------------------------* * Public functions *---------------------------------------------------------------------*/ /* Allocates memory for state struct and initializes elements. */ -#ifdef IVAS_FLOAT_FIXED ivas_error apa_init( apa_state_t **pps, const Word32 num_channels ) @@ -202,13 +179,6 @@ ivas_error apa_init( ps->buf_out_capacity = (UWord16) L_mult0( APA_BUF_PER_CHANNEL, (Word16) num_channels ); move16(); -#ifdef IVAS_FLOAT_FIXED_TO_BE_REMOVED - IF( ( ps->buf_out = malloc( sizeof( float ) * ps->buf_out_capacity ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for JBM\n" ) ); - } -#endif - IF( ( ps->buf_out_fx = malloc( sizeof( Word16 ) * ps->buf_out_capacity ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for JBM\n" ) ); @@ -222,45 +192,9 @@ ivas_error apa_init( return IVAS_ERR_OK; } -#else -ivas_error apa_init( - apa_state_t **pps, - const int32_t num_channels ) -{ - apa_state_t *ps = NULL; - - /* make sure pointer is valid */ - if ( !pps ) - { - return 1; - } - - /* allocate state struct */ - if ( ( ps = (apa_state_t *) malloc( sizeof( apa_state_t ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for JBM\n" ) ); - } - - ps->num_channels = (uint16_t) num_channels; - ps->buf_out_capacity = (uint16_t) ( APA_BUF_PER_CHANNEL * num_channels ); - if ( ( ps->buf_out = malloc( sizeof( float ) * ps->buf_out_capacity ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for JBM\n" ) ); - } - - ps->evs_compat_mode = false; - - apa_reset( ps ); - *pps = ps; - - return IVAS_ERR_OK; -} - -#endif /* Sets state variables to initial value. */ -#ifdef IVAS_FLOAT_FIXED void apa_reset( apa_state_t *ps ) { @@ -293,7 +227,6 @@ void apa_reset( move16(); ps->css = 1; move16(); - ps->targetQuality = 0.0f; ps->targetQuality_fx = 0; move32(); @@ -314,41 +247,7 @@ void apa_reset( move16(); return; } -#else -void apa_reset( - apa_state_t *ps ) -{ - ps->signalScaleForCorrelation = 0; - /* init state struct */ - ps->win_fx = NULL; - ps->win_incrementor = 0; - ps->l_buf_out = 0; - ps->l_halfwin = 0; - ps->rate = 0; - ps->l_seg = 0; - ps->l_frm = 0; - ps->l_in_total = 0; - ps->diffSinceSetScale = 0; - ps->nFramesSinceSetScale = 0; - ps->scale = 100; - ps->p_min = 0; - ps->l_search = 0; - ps->wss = 1; - ps->css = 1; - ps->targetQuality = 0.0f; - ps->qualityred = 0; - ps->qualityrise = 0; - ps->last_pitch = 0; - ps->bad_frame_count = 0; - ps->good_frame_count = 0; - - ps->l_ts = 1; - ps->l_r_buf = 0; - return; -} -#endif -#ifdef IVAS_FLOAT_FIXED UWord8 apa_reconfigure( apa_state_t *ps, UWord16 num_channels, @@ -361,15 +260,6 @@ UWord8 apa_reconfigure( ps->buf_out_capacity = (UWord16) L_mult0( APA_BUF_PER_CHANNEL, (Word16) num_channels ); move16(); -#ifdef IVAS_FLOAT_FIXED_TO_BE_REMOVED - free( ps->buf_out ); - ps->buf_out = (float *) malloc( sizeof( float ) * ps->buf_out_capacity ); - IF( !ps->buf_out ) - { - return 2; - } -#endif - free( ps->buf_out_fx ); ps->buf_out_fx = (Word16 *) malloc( sizeof( float ) * ps->buf_out_capacity ); IF( !ps->buf_out_fx ) @@ -411,119 +301,8 @@ UWord8 apa_reconfigure( return 0; } -#else -uint8_t apa_reconfigure( - apa_state_t *ps, - uint16_t num_channels, - uint16_t l_ts ) -{ - - /* realloc buffer */ - free( ps->buf_out ); - ps->num_channels = (uint16_t) num_channels; - ps->buf_out_capacity = (uint16_t) ( APA_BUF_PER_CHANNEL * num_channels ); - ps->buf_out = (float *) malloc( sizeof( float ) * ps->buf_out_capacity ); - if ( !ps->buf_out ) - { - return 2; - } - ps->l_buf_out = 0; - ps->l_in_total = 0; - ps->l_ts = ps->num_channels * l_ts; - - /* set everything else dependent on the number of channels */ - /* set segment size */ - /* in the order of a pitch, set to 160 samples at 16 kHz */ - /* used for windowing and as the correlation length, i.e., */ - /* the size of the template segment. */ - ps->l_seg = ( ps->rate / 100 ) * ps->num_channels; - - /* set frame size */ - /* set to 320 samples at 16 kHz */ - ps->l_frm = ( ps->rate / FRAMES_PER_SEC ) * ps->num_channels; - - /* set minimum pitch */ - /* set to 40 samples at 16 kHz */ - /* (defines min change in number of samples, i.e., abs(l_in-l_out) >= p_min) */ - ps->p_min = ( ps->rate / 400 ) * ps->num_channels; - - /* set search length */ - /* must cover one pitch, set to 200 samples at 16 kHz */ - /* (the resulting maximum pitch is then p_min+l_search = 240 samples at 16 kHz) */ - ps->l_search = ( ps->rate / 80 ) * ps->num_channels; - - return 0; -} -#endif /* Sets the audio configuration. */ -#ifndef IVAS_FLOAT_FIXED -bool apa_set_rate( - apa_state_t *ps, - const int32_t output_Fs ) -{ - /* make sure pointer is valid */ - if ( ps == NULL ) - { - return 1; - } - - /* check range */ - if ( ( output_Fs < APA_MIN_RATE ) || ( output_Fs > APA_MAX_RATE ) ) - { - return 1; - } - - /* reset state struct */ - apa_reset( ps ); - - /* copy rate to state struct */ - ps->rate = (uint16_t) output_Fs; - - if ( ps->num_channels > APA_MAX_NUM_CHANNELS ) - { - return 1; - } - - /* - * several other parameters depend on the sampling rate - * and are set below. Some "magic numbers" are used here - * which are based on typical values of a "pitch" in - * human voice. The pitch length is the period of the - * base frequency and is usually assumed to be 40-240 - * samples at 16 kHz. - */ - - /* set segment size */ - /* in the order of a pitch, set to 160 samples at 16 kHz */ - /* used for windowing and as the correlation length, i.e., */ - /* the size of the template segment. */ - ps->l_seg = ( ps->rate / 100 ) * ps->num_channels; - - /* init Hann window */ - /* Note: l_win < APA_BUF_PER_CHANNEL is required */ - /* Length of Hann window should be independent of - * number of channels - same window applied to all channels */ - ps->l_halfwin = ps->rate / 100; - hannWindow( ps->l_halfwin * 2, ps->win ); - - /* set frame size */ - /* set to 320 samples at 16 kHz */ - ps->l_frm = ( ps->rate / FRAMES_PER_SEC ) * ps->num_channels; - - /* set minimum pitch */ - /* set to 40 samples at 16 kHz */ - /* (defines min change in number of samples, i.e., abs(l_in-l_out) >= p_min) */ - ps->p_min = ( ps->rate / 400 ) * ps->num_channels; - - /* set search length */ - /* must cover one pitch, set to 200 samples at 16 kHz */ - /* (the resulting maximum pitch is then p_min+l_search = 240 samples at 16 kHz) */ - ps->l_search = ( ps->rate / 80 ) * ps->num_channels; - - return 0; -} -#else bool apa_set_rate( apa_state_t *ps, const Word32 output_Fs ) @@ -574,7 +353,6 @@ bool apa_set_rate( /* Length of Hann window should be independent of * number of channels - same window applied to all channels */ ps->l_halfwin = (UWord16) Mult_32_16( ps->rate, INV_100_Q15 ); - hannWindow( (UWord16) L_shl( ps->l_halfwin, 1 ), ps->win ); move16(); move16(); @@ -639,10 +417,8 @@ bool apa_set_rate( move16(); return 0; } -#endif /* Set scaling. */ -#ifdef IVAS_FLOAT_FIXED bool apa_set_scale_fx( apa_state_t *ps, UWord16 scale ) @@ -679,42 +455,7 @@ bool apa_set_scale_fx( return 0; } -#else -bool apa_set_scale( - apa_state_t *ps, - uint16_t scale ) -{ - /* make sure pointer is valid */ - if ( ps == NULL ) - { - return 1; - } - - /* check range */ - if ( ( scale < APA_MIN_SCALE ) || ( scale > APA_MAX_SCALE ) ) - { - return 1; - } - - /* do nothing if same scale is set multiple times */ - /* (otherwise scale control is confused) */ - if ( ps->scale == scale ) - { - return 0; - } - - /* copy to state struct */ - ps->scale = scale; - - /* reset scaling statistics */ - ps->diffSinceSetScale = 0; - ps->nFramesSinceSetScale = 0; - - return 0; -} -#endif -#ifdef IVAS_FLOAT_FIXED bool apa_set_renderer_granularity( apa_state_t *ps, UWord16 l_ts ) @@ -731,25 +472,7 @@ bool apa_set_renderer_granularity( move16(); return 0; } -#else -bool apa_set_renderer_granularity( - apa_state_t *ps, - uint16_t l_ts ) -{ - /* make sure pointer is valid */ - if ( ps == NULL ) - { - return 1; - } - - - /* copy to state struct */ - ps->l_ts = l_ts * ps->num_channels; - return 0; -} -#endif -#ifdef IVAS_FLOAT_FIXED bool apa_set_renderer_residual_samples( apa_state_t *ps, UWord16 l_r_buf ) @@ -766,25 +489,8 @@ bool apa_set_renderer_residual_samples( move16(); return 0; } -#else -bool apa_set_renderer_residual_samples( - apa_state_t *ps, - uint16_t l_r_buf ) -{ - /* make sure pointer is valid */ - if ( ps == NULL ) - { - return 1; - } - /* copy to state struct */ - ps->l_r_buf = l_r_buf * ps->num_channels; - return 0; -} -#endif - -#ifdef IVAS_FLOAT_FIXED bool apa_set_evs_compat_mode( apa_state_t *ps, bool mode ) @@ -800,23 +506,7 @@ bool apa_set_evs_compat_mode( return 0; } -#else -bool apa_set_evs_compat_mode( - apa_state_t *ps, - bool mode ) -{ - /* make sure pointer is valid */ - if ( ps == NULL ) - { - return 1; - } - ps->evs_compat_mode = mode; - - return 0; -} - -#endif /* ******************************************************************************** @@ -843,23 +533,25 @@ bool apa_set_evs_compat_mode( */ bool apa_set_quality( apa_state_t *ps, - float quality, - uint16_t qualityred, - uint16_t qualityrise ) + Word32 quality, + UWord16 qualityred, + UWord16 qualityrise ) { assert( ps != NULL ); - assert( -2.0f <= quality && quality <= 3.1f ); + assert( -131072 <= quality && quality <= 203161 ); assert( qualityred > 0 && qualityred <= 20 ); assert( qualityrise > 0 && qualityrise <= 20 ); - ps->targetQuality = quality; -#ifdef IVAS_FLOAT_FIXED - ps->targetQuality_fx = float_to_fix( quality, Q16 ); -#endif + ps->targetQuality_fx = quality; + move32(); ps->qualityred = qualityred; + move16(); ps->qualityrise = qualityrise; + move16(); ps->bad_frame_count = 0; + move16(); ps->good_frame_count = 0; + move16(); return 0; } @@ -879,7 +571,6 @@ bool apa_set_quality( * ******************************************************************************** */ -#ifdef IVAS_FLOAT_FIXED bool apa_set_complexity_options( apa_state_t *ps, UWord16 wss, @@ -910,34 +601,7 @@ bool apa_set_complexity_options( return 0; } -#else -bool apa_set_complexity_options( - apa_state_t *ps, - uint16_t wss, - uint16_t css ) -{ - /* make sure pointer is valid */ - if ( ps == NULL ) - { - return 1; - } - if ( wss == 0 || wss > 1000 ) - { - return 1; - } - - if ( css == 0 || css > 1000 ) - { - return 1; - } - - ps->wss = wss; - ps->css = css; - - return 0; -} -#endif /* ******************************************************************************** @@ -951,7 +615,6 @@ bool apa_set_complexity_options( * ******************************************************************************** */ -#ifdef IVAS_FLOAT_FIXED bool apa_exit( apa_state_t **pps ) { @@ -962,9 +625,6 @@ bool apa_exit( } /* deallocate state struct members */ -#ifdef IVAS_FLOAT_FIXED_TO_BE_REMOVED - free( ( *pps )->buf_out ); -#endif free( ( *pps )->buf_out_fx ); /* deallocate state struct */ @@ -975,28 +635,6 @@ bool apa_exit( return 0; } -#else -bool apa_exit( - apa_state_t **pps ) -{ - /* ignore NULL pointer input */ - if ( *pps == NULL ) - { - return 0; - } - - /* deallocate state struct members */ - free( ( *pps )->buf_out ); - - /* deallocate state struct */ - free( *pps ); - - /* set pointer to NULL */ - *pps = NULL; - - return 0; -} -#endif /* ******************************************************************************** @@ -1030,7 +668,6 @@ bool apa_exit( * ******************************************************************************** */ -#ifdef IVAS_FLOAT_FIXED UWord8 apa_exec_fx( apa_state_t *ps, /* i/o: state struct */ const Word16 a_in[], /* i : input samples */ @@ -1437,184 +1074,6 @@ UWord8 apa_exec_ivas_fx( return 0; } -#else -uint8_t apa_exec( - apa_state_t *ps, /* i/o: state struct */ - const float a_in[], /* i : input samples */ - uint16_t l_in, /* i : number of input samples */ - uint16_t maxScaling, /* i : allowed number of inserted/removed samples */ - float a_out[], /* o : output samples */ - uint16_t *l_out /* o : number of output samples */ -) -{ - uint16_t i; - float frm_in[APA_BUF]; /* TODO(mcjbm): this buffer could be smaller - always allocates space for 16 channels */ - uint16_t l_frm_out; - int16_t l_rem; - int32_t dl_scaled, dl_copied, l_frm_out_target; - int32_t expScaling, actScaling; - uint32_t statsResetThreshold, statsResetShift; - - statsResetThreshold = 1637; - statsResetShift = 2; - - /* Convert max_scaling from "per channel" to total */ - maxScaling *= ps->num_channels; - - /* make sure no invalid output is used */ - *l_out = 0; - l_frm_out = 0; - - /* make sure pointer is valid */ - if ( ps == NULL ) - { - return 1; - } - /* check available rate */ - if ( ps->rate == 0 ) - { - return 2; - } - /* check size of input */ - if ( l_in != ps->l_frm ) - { - return 3; - } - - /* get target length */ - if ( ps->scale > 100 ) - { - expScaling = (int32_t) ( ( ps->l_frm * ( ps->scale - 100.0f ) / 100.0f ) * ( ps->nFramesSinceSetScale + 1 ) + 0.5f ); - } - else if ( ps->scale < 100 ) - { - expScaling = (int32_t) ( ( ps->l_frm * ( ps->scale - 100.0f ) / 100.0f ) * ( ps->nFramesSinceSetScale + 1 ) - 0.5f ); - } - else - { - expScaling = 0; - } - actScaling = ps->diffSinceSetScale - ps->l_frm; - l_frm_out_target = expScaling - actScaling; - - /* Wait until we have l_frm outputs samples */ - /* (required to search for correlation in the past). */ - /* If we don't have enough samples, simply copy input to output */ - if ( ps->l_buf_out < ps->l_frm ) - { - for ( i = 0; i < ps->l_frm; i++ ) - { - a_out[i] = a_in[i]; - } - l_frm_out = ps->l_frm; - } - else - { - float *buf_out_ptr = &( ps->buf_out[ps->l_buf_out - ps->l_frm] ); - float *frm_in_ptr = &( frm_in[ps->l_frm] ); - - /* fill input frame */ - /* 1st input frame: previous output samples */ - for ( i = 0; i < ps->l_frm; i++ ) - { - frm_in[i] = buf_out_ptr[i]; - } - /* 2nd input frame: new input samples */ - for ( i = 0; i < ps->l_frm; i++ ) - { - frm_in_ptr[i] = a_in[i]; - } - /* no scaling */ - if ( ps->scale == 100 ) - { - copy_frm( ps, frm_in, a_out, &l_frm_out ); - } - /* shrink */ - else if ( ps->scale < 100 ) - { - shrink_frm( ps, frm_in, maxScaling, a_out, &l_frm_out ); - } - /* extend */ - else - { - extend_frm( ps, frm_in, a_out, &l_frm_out ); - } - /* control the amount/frequency of scaling */ - if ( l_frm_out != ps->l_frm ) - { - if ( maxScaling != 0U && - abs( (int16_t) ( ps->l_frm - l_frm_out ) ) > maxScaling ) - { - /* maxScaling exceeded -> discard scaled frame */ - copy_frm( ps, frm_in, a_out, &l_frm_out ); - } - else if ( abs( l_frm_out_target ) > ps->l_frm ) /* ignore small difference */ - { - dl_copied = l_frm_out_target - (int32_t) ps->l_frm; - dl_scaled = l_frm_out_target - (int32_t) l_frm_out; - /* discard scaled frame if copied frame is closer to target length */ - if ( abs( dl_copied ) < abs( dl_scaled ) ) - { - copy_frm( ps, frm_in, a_out, &l_frm_out ); - } - } - } - } - - /* copy output to internal buffer */ - /* avoid buffer overflow: */ - /* discard old samples; always keep at least most recent l_frm samples */ - if ( ( ps->l_buf_out + l_frm_out ) > ps->buf_out_capacity ) - { - float *buf_out_ptr1 = ps->buf_out; - float *buf_out_ptr2; - - l_rem = ( ps->l_frm - l_frm_out ); - if ( l_rem < 0 ) - { - l_rem = 0; - } - buf_out_ptr2 = &( ps->buf_out[ps->l_buf_out - l_rem] ); - for ( i = 0; i < l_rem; i++ ) - { - buf_out_ptr1[i] = buf_out_ptr2[i]; - } - ps->l_buf_out = l_rem; - } - /* append new output samples */ - if ( ( ps->l_buf_out + l_frm_out ) > ps->buf_out_capacity ) - { - return 5; - } - { - float *buf_out_ptr = &( ps->buf_out[ps->l_buf_out] ); - for ( i = 0; i < l_frm_out; i++ ) - { - buf_out_ptr[i] = a_out[i]; - } - } - ps->l_buf_out += l_frm_out; - - *l_out = l_frm_out; - /* update time */ - ps->l_in_total += ps->l_frm; - - if ( abs( ps->diffSinceSetScale ) < ( 0x7FFFFF - ( l_frm_out - ps->l_frm ) ) && - ps->nFramesSinceSetScale < statsResetThreshold ) - { - ps->diffSinceSetScale += l_frm_out - ps->l_frm; - ++ps->nFramesSinceSetScale; - } - else /* scale statistics down to avoid overflow */ - { - ps->diffSinceSetScale >>= statsResetShift; - ps->nFramesSinceSetScale >>= statsResetShift; - } - - return 0; -} -#endif - /*---------------------------------------------------------------------* * Local functions @@ -1644,101 +1103,6 @@ uint8_t apa_exec( * ******************************************************************************** */ -#ifndef IVAS_FLOAT_FIXED -static void get_scaling_quality( - const apa_state_t *ps, - const float *signal, - uint16_t s_len, - uint16_t offset, - uint16_t corr_len, - uint16_t pitch, - float *energydB, - float *quality ) -{ - float maxEnergy = 0.0f; - float qualityOfMaxEnergy = 0.0f; /* we measure the quality for all channels and select the one with highest energy */ - - float half_pitch_cn = 0.0f; - float pitch_cn = 0.0f; - float three_halves_pitch_cn = 0.0f; - float double_pitch_cn = 0.0f; - - float pitch_energy = 0.0f; - float half_pitch_energy = 0.0f; - float three_halves_pitch_energy = 0.0f; - float double_pitch_energy = 0.0f; - - uint16_t i = 0; - - for ( i = 0; i < ps->num_channels; i++ ) - { - float energy; - offset = 0; - - pitch_cn = normalized_cross_correlation_self( signal, pitch + offset, offset, corr_len, ps->num_channels * 2, &pitch_energy ); - - if ( pitch_cn > 0.0f ) - { - /* calculate correlation for double pitch */ - if ( 2 * pitch + offset + corr_len <= s_len ) - { - double_pitch_cn = normalized_cross_correlation_self( signal, 2 * pitch + offset, offset, corr_len, ps->num_channels * 2, &double_pitch_energy ); - } - else - { - double_pitch_cn = pitch_cn; - double_pitch_energy = pitch_energy; - } - /* calculate correlation for three/half pitch */ - if ( ( 3 * pitch ) / 2 + offset + corr_len <= s_len ) - { - three_halves_pitch_cn = normalized_cross_correlation_self( signal, ( 3 * pitch ) / 2 + offset, offset, corr_len, ps->num_channels * 2, &three_halves_pitch_energy ); - } - else - { - three_halves_pitch_cn = pitch_cn; - three_halves_pitch_energy = pitch_energy; - } - /* calculate correlation for half pitch */ - if ( pitch / 2 + offset + corr_len <= s_len ) - { - half_pitch_cn = normalized_cross_correlation_self( signal, pitch / 2 + offset, offset, corr_len, ps->num_channels * 2, &half_pitch_energy ); - } - else - { - half_pitch_cn = pitch_cn; - half_pitch_energy = pitch_energy; - } - - /* combine correlation results */ - *quality = ( half_pitch_cn * three_halves_pitch_cn ) + ( pitch_cn * double_pitch_cn ); - energy = pitch_energy + half_pitch_energy + three_halves_pitch_energy + double_pitch_energy; - } - else - { - *quality = pitch_cn; /* value is negative, thus pass it */ - energy = pitch_energy; - } - - /* update the quality by the quality of the signal with the highest energy */ - if ( energy > maxEnergy ) - { - qualityOfMaxEnergy = *quality; - maxEnergy = energy; - } - - /* go to next channel */ - ++signal; - } - *quality = qualityOfMaxEnergy; - - /* increase calculated quality of signals with low energy */ - *energydB = apa_corrEnergy2dB( maxEnergy, corr_len ); - *quality += apa_getQualityIncreaseForLowEnergy( *energydB ); - - return; -} -#else static void get_scaling_quality_fx( const apa_state_t *ps, const Word16 *signal, Word16 s_len, @@ -1843,11 +1207,7 @@ static void get_scaling_quality_fx( const apa_state_t *ps, move32(); } -#endif - - /* Converts the correlation energy to dB. */ -#ifdef IVAS_FLOAT_FIXED Word16 apa_corrEnergy2dB_fx( Word32 energy, Word16 energyExp, Word16 corr_len ) { @@ -1865,46 +1225,8 @@ Word16 apa_corrEnergy2dB_fx( Word32 energy, Word16 energyExp, Word16 corr_len ) result = BASOP_Util_lin2dB( L_deposit_l( result ), energyExp, 1 ); return result; } -#else -static float apa_corrEnergy2dB( - float energy, - uint16_t corr_len ) -{ - float energydB = 10.0f * (float) log10( energy / ( PCM16_TO_FLT_FAC * PCM16_TO_FLT_FAC * corr_len * 4.0f ) ); - - return energydB; -} -#endif - /* Increases the calculated quality of signals with low energy. */ -#ifndef IVAS_FLOAT_FIXED -static float apa_getQualityIncreaseForLowEnergy( - float energydB ) -{ - const float qualIncreaseMinEnergy = -65; - const float qualIncreaseMaxEnergy = -40; - float qualIncForLowEnergy = 0; - - if ( energydB < qualIncreaseMaxEnergy ) - { - qualIncForLowEnergy = energydB; - if ( qualIncForLowEnergy < qualIncreaseMinEnergy ) - { - qualIncForLowEnergy = qualIncreaseMinEnergy; - } - if ( qualIncForLowEnergy > qualIncreaseMaxEnergy ) - { - qualIncForLowEnergy = qualIncreaseMaxEnergy; - } - qualIncForLowEnergy = ( qualIncForLowEnergy - qualIncreaseMaxEnergy ) / - ( qualIncreaseMinEnergy - qualIncreaseMaxEnergy ) * 2; - assert( qualIncForLowEnergy >= 0 && qualIncForLowEnergy <= 2 ); - } - - return qualIncForLowEnergy; -} -#else Word16 apa_getQualityIncreaseForLowEnergy_fx( Word16 energydBQ8 ) { Word16 qualIncreaseMinEnergy, qualIncreaseMaxEnergy, qualIncForLowEnergy; /* Q8 */ @@ -1943,7 +1265,6 @@ Word16 apa_getQualityIncreaseForLowEnergy_fx( Word16 energydBQ8 ) } return qualIncForLowEnergy; } -#endif /* @@ -1966,79 +1287,6 @@ Word16 apa_getQualityIncreaseForLowEnergy_fx( Word16 energydBQ8 ) * ******************************************************************************** */ -#ifndef IVAS_FLOAT_FIXED -static bool logarithmic_search( - const apa_state_t *ps, - const float *signal, - int16_t s_start, - uint16_t inlen, - uint16_t offset, - uint16_t fixed_pos, - uint16_t corr_len, - uint16_t wss, - uint16_t css, - int16_t *synchpos ) -{ - int16_t i; - float coeff; - float coeff_max; - int16_t s_start_old = 0; - uint16_t s_len_old = 0; - - do - { - coeff_max = -FLT_MAX; /* will always be overwritten with result of first correlation */ - for ( i = s_start; i < s_start + inlen; i += css * ps->num_channels ) - { - if ( ( wss == 1 ) && ( ps->num_channels == 1 ) ) - { - coeff = cross_correlation_self( signal, i + offset, fixed_pos + offset, corr_len ); - } - else - { - coeff = cross_correlation_subsampled_self( signal, i + offset, fixed_pos + offset, corr_len, wss * ps->num_channels ); - } - - /* update max corr */ - if ( ps->scale < 100 ) - { - /* shrinking: prefer greater synchpos for equal coeff */ - if ( coeff >= coeff_max ) - { - coeff_max = coeff; - *synchpos = i; - } - } - else - { - /* extending: prefer smaller synchpos for equal coeff */ - if ( coeff > coeff_max ) - { - coeff_max = coeff; - *synchpos = i; - } - } - } - /* backup old search range */ - s_start_old = s_start; - s_len_old = inlen; - - css = css / 2; - inlen = inlen / 2; - s_start = *synchpos - inlen / 2; - if ( s_start < s_start_old ) - { - s_start = s_start_old; - } - if ( ( s_start + inlen ) > ( s_start_old + s_len_old ) ) - { - inlen = s_start_old - s_start + s_len_old; - } - } while ( css > 2 ); - - return 0; -} -#else static Word8 logarithmic_search_fx( const apa_state_t *ps, const Word16 *signal, Word16 s_start, @@ -2125,8 +1373,6 @@ static Word8 logarithmic_search_fx( const apa_state_t *ps, WHILE( GT_16( css, 2 ) ); return 0; } -#endif - /* ******************************************************************************** @@ -2159,48 +1405,15 @@ static Word8 logarithmic_search_fx( const apa_state_t *ps, * offset+fixed_pos+corr_len. For correlation, the * template segment (EFGHIJ) is matched against the * segment in the search region, e.g., against (k_abcd) -* in the first search position. The search position -* with the best match (-14: EFGHIJ <-> efghij) is -* returned. -* -* 19-JUN-03 N.Faerber initial version -* 23-APR-04 S.Doehla added subsampling -* -******************************************************************************** -*/ -#ifndef IVAS_FLOAT_FIXED -static bool find_synch( - apa_state_t *ps, - const float *in, - uint16_t l_in, - int16_t s_start, - uint16_t s_len, - int16_t fixed_pos, - uint16_t corr_len, - uint16_t offset, - float *energy, - float *quality, - int16_t *synch_pos ) -{ - assert( ( corr_len - 1 + s_start + s_len - 1 + offset ) < l_in ); - assert( ( corr_len - 1 + fixed_pos + offset ) < l_in ); - - /* pass last pitch to search function as prediction value */ - *synch_pos = ps->last_pitch; - - logarithmic_search( ps, in, s_start, s_len, offset, fixed_pos, corr_len, ps->wss, ps->css, synch_pos ); - - /* assert synch_pos is cleanly divisible by number of channels */ - assert( *synch_pos % ps->num_channels == 0 ); - - *quality = 0; - get_scaling_quality( ps, in, l_in, offset, corr_len, (uint16_t) abs( fixed_pos - *synch_pos ), energy, quality ); - - ps->last_pitch = *synch_pos; - - return 0; -} -#else +* in the first search position. The search position +* with the best match (-14: EFGHIJ <-> efghij) is +* returned. +* +* 19-JUN-03 N.Faerber initial version +* 23-APR-04 S.Doehla added subsampling +* +******************************************************************************** +*/ static Word16 find_synch_fx( apa_state_t *ps, const Word16 *in, Word16 l_in, @@ -2242,8 +1455,6 @@ static Word16 find_synch_fx( apa_state_t *ps, return 0; } -#endif - /* ******************************************************************************** @@ -2267,7 +1478,6 @@ static Word16 find_synch_fx( apa_state_t *ps, * ******************************************************************************** */ -#ifdef IVAS_FLOAT_FIXED static bool copy_frm_fx( apa_state_t *ps, const Word16 frm_in_fx[], @@ -2292,30 +1502,6 @@ static bool copy_frm_fx( return 0; } -#else -static bool copy_frm( - apa_state_t *ps, - const float frm_in[], - float frm_out[], - uint16_t *l_frm_out ) -{ - uint16_t i; - - /* only 2nd input frame is used */ - frm_in += ps->l_frm; - - /* copy frame */ - for ( i = 0; i < ps->l_frm; i++ ) - { - frm_out[i] = frm_in[i]; - } - - /* set output length */ - *l_frm_out = ps->l_frm; - - return 0; -} -#endif /* @@ -2342,7 +1528,6 @@ static bool copy_frm( * ******************************************************************************** */ -#ifdef IVAS_FLOAT_FIXED static bool shrink_frm_fx( apa_state_t *ps, const Word16 frm_in_fx[], @@ -2506,148 +1691,6 @@ static bool shrink_frm_fx( return 0; } -#else -static bool shrink_frm( - apa_state_t *ps, - const float frm_in[], - uint16_t maxScaling, - float frm_out[], - uint16_t *l_frm_out ) -{ - bool findSynchResult = 0; - int16_t xtract, l_rem, s_start, s_end; - uint16_t i; - uint16_t over; - float energy, quality = 0.0f; - uint16_t l_frm; - uint16_t l_seg; - - l_frm = ps->l_frm; - l_seg = ps->l_seg; - - /* only 2nd input frame is used */ - frm_in += l_frm; - - /* set search range */ - s_start = ( ps->p_min / ps->num_channels ) * ps->num_channels; - s_end = s_start + ps->l_search; - if ( ( s_end + l_seg ) >= l_frm ) - { - s_end = ( l_frm - l_seg ); - } - - /* calculate overlap position */ - if ( isSilence( frm_in, l_seg, 10 ) ) - { - /* maximum scaling */ - energy = -65; - quality = 5; - if ( ps->evs_compat_mode == false ) - { - - xtract = maxScaling; - /* take samples already in the renderer buf into account */ - xtract += ps->l_r_buf; - /* snap to renderer time slot borders */ - xtract -= ( ps->l_ts - ( l_frm - xtract + ps->l_r_buf ) % ps->l_ts ); - while ( xtract < 0 ) - { - xtract += ps->l_ts; - } - while ( xtract > ( s_end - ps->num_channels ) ) - { - /* exceeded the possible shrinking, go back one renderer ts*/ - xtract -= ps->l_ts; - } - } - else if ( maxScaling != 0U && s_end > maxScaling + 1 ) - { - xtract = maxScaling; - } - else - { - /* set to last valid element (i.e. element[len - 1] but note for stereo last element is last pair of samples) */ - xtract = s_end - ps->num_channels; - } - } - else - { - /* find synch */ - findSynchResult = find_synch( ps, frm_in, l_frm, s_start, (uint16_t) ( s_end - s_start ), 0, l_seg, 0, &energy, &quality, &xtract ); - } - - /* assert synch_pos is cleanly divisible by number of channels */ - assert( xtract % ps->num_channels == 0 ); - - /* set frame overlappable - reset if necessary */ - over = 1; - - /* test whether frame has sufficient quality */ - if ( quality < ( ps->targetQuality - ( ps->bad_frame_count * 0.1f ) + ( ps->good_frame_count * 0.2f ) ) ) - { - /* not sufficient */ - over = 0; - if ( ps->bad_frame_count < ps->qualityred ) - { - ++ps->bad_frame_count; - } - if ( ps->good_frame_count > 0U ) - { - --ps->good_frame_count; - } - } - else - { - /* sufficient quality */ - if ( ps->bad_frame_count > 0U ) - { - --ps->bad_frame_count; - } - if ( ps->good_frame_count < ps->qualityrise ) - { - ++ps->good_frame_count; - } - } - - /* Calculate output data */ - if ( over && xtract ) - { - if ( findSynchResult == 1 ) - { - return 1; - } - if ( ps->evs_compat_mode == true ) - { - overlapAddEvs( frm_in, frm_in + xtract, frm_out, l_seg, ps->num_channels, ps->win + ps->l_halfwin, ps->win ); - } - else - { - overlapAdd( frm_in, frm_in + xtract, frm_out, l_seg, ps->num_channels, ps->win + ps->l_halfwin, ps->win ); - } - } - else - { - xtract = 0; - for ( i = 0; i < l_seg; i++ ) - { - frm_out[i] = frm_in[i]; - } - } - - /* append remaining samples */ - l_rem = l_frm - xtract - l_seg; - for ( i = 0; i < l_rem; i++ ) - { - frm_out[l_seg + i] = frm_in[l_frm - l_rem + i]; - } - - /* set output length */ - *l_frm_out = l_seg + l_rem; - - return 0; -} -#endif - /* ******************************************************************************** @@ -2669,7 +1712,6 @@ static bool shrink_frm( * ******************************************************************************** */ -#ifdef IVAS_FLOAT_FIXED static bool extend_frm_fx( apa_state_t *ps, const Word16 frm_in_fx[], @@ -2895,213 +1937,3 @@ static bool extend_frm_fx( return 0; } -#else -static bool extend_frm( - apa_state_t *ps, - const float frm_in[], - float frm_out[], - uint16_t *l_frm_out ) -{ - bool findSynchResult = 0; - uint16_t l_frm_out_target; - uint16_t n, i; - int16_t N; - int16_t s[MAXN + 2], s_max, s_min; - int16_t xtract[MAXN + 2], sync_start, s_end; - uint16_t over[MAXN + 2]; - int16_t l_rem; - int16_t s_start = 0; - float energy, quality = 0.0f; - uint16_t l_frm, l_seg; - const float *fadeOut, *fadeIn; - float *out; - - - l_frm = ps->l_frm; - l_seg = ps->l_seg; - - /* number of segments/iterations */ - l_frm_out_target = (uint16_t) ( (float) l_frm * 1.5f ); - N = ( l_frm_out_target / l_seg ) - 1; - if ( N < 1 ) - { - N = 1; - } - if ( N > MAXN ) - { - return 1; - } - /* calculate equally spaced search regions */ - /* s[n] are given relative to 2nd frame and point to the start of */ - /* the search region. The first segment (n=1) will not be moved. */ - /* Hence, the iterations will start with n=2. */ - s_min = -( ps->l_search ) - ( ps->p_min ); - /* (make sure not to exceed array dimension) */ - if ( l_frm + s_min < 0 ) - { - s_min = -( l_frm ); - } - s_max = l_frm - 2 * l_seg - ps->l_search; - if ( s_max < s_min ) - { - N = 1; - } - /* for just one segment start at s_min */ - if ( N == 1 ) - { - s[2] = s_min; - } - /* else, spread linear in between s_min and s_max */ - /* (including s_min and s_max) */ - else - { - for ( n = 2; n <= ( N + 1 ); n++ ) - { - s[n] = s_min + ( ( s_max - s_min ) * ( n - 2 ) ) / ( N - 1 ); - } - } - - /* - * Planning Phase - */ - - xtract[1] = -( l_seg ); /* make sync_start=0 in 1st iteration */ - n = 2; - - /* define synch segment (to be correlated with search region) */ - sync_start = xtract[n - 1] + l_seg; - over[n] = 1; /* will be reset if overlap is not required */ - /* check end of search region: should be at least p_min */ - /* samples on the left of synch_start */ - if ( ( s[n] + ps->l_search ) < ( sync_start - ( ps->p_min ) ) ) - { - s_start = s[n]; - s_end = s_start + ps->l_search; - } - else - { - /* shrink search region to enforce minimum shift */ - s_end = sync_start - ( ps->p_min ); - if ( s[n] + ps->l_search < sync_start ) - { - s_start = s[n]; /* just do it with normal start position */ - } - else if ( n == ( N + 1 ) ) /* move search region left for last segment */ - { - s_start = s_end - ( ps->l_search - ps->p_min ); - } - else - { - over[n] = 0; /* don't search/overlap (just copy down) */ - } - } - - if ( over[n] ) - { - /* calculate overlap position */ - if ( isSilence( frm_in, l_seg, 10 ) ) - { - /* maximum scaling */ - energy = -65; - quality = 5; - xtract[n] = s_start + ps->num_channels; - if ( ps->evs_compat_mode == false ) - { - /* take renderer buffer samples into accout */ - xtract[n] += ps->l_r_buf; - /* snap to next renderer time slot border to resynchronize */ - xtract[n] -= ( ( N - 1 ) * l_seg - xtract[n] + ps->l_r_buf ) % ps->l_ts; - } - } - else - { - /* find synch */ - findSynchResult = find_synch( ps, frm_in, 2 * l_frm, s_start, s_end - s_start, sync_start, l_seg, l_frm, &energy, &quality, &xtract[n] ); - } - /* assert synch_pos is cleanly divisible by number of channels */ - assert( xtract[n] % ps->num_channels == 0 ); - - /* test for sufficient quality */ - if ( quality < ( ps->targetQuality - ( ps->bad_frame_count * 0.1f ) + ( ps->good_frame_count * 0.2f ) ) ) - { - /* not sufficient */ - over[n] = 0; - xtract[n] = sync_start; - if ( ps->bad_frame_count < ps->qualityred ) - { - ++ps->bad_frame_count; - } - if ( ps->good_frame_count > 0U ) - { - --ps->good_frame_count; - } - } - else - { - /* sufficient quality */ - if ( ps->bad_frame_count > 0U ) - { - --ps->bad_frame_count; - } - if ( ps->good_frame_count < ps->qualityrise ) - { - ++ps->good_frame_count; - } - } - if ( findSynchResult ) - { - return 1; - } - } - else - { - xtract[n] = sync_start; - } - - - /* Calculate output data */ - for ( n = 2; n <= N; n++ ) - { - if ( over[n] && xtract[n - 1] + l_seg != xtract[n] ) - { - /* mix 2nd half of previous segment with 1st half of current segment */ - fadeOut = frm_in + l_frm + xtract[n - 1] + l_seg; - fadeIn = frm_in + l_frm + xtract[n]; - out = frm_out + ( n - 2 ) * l_seg; - if ( ps->evs_compat_mode == true ) - { - overlapAddEvs( fadeOut, fadeIn, out, l_seg, ps->num_channels, ps->win + ps->l_halfwin, ps->win ); - } - else - { - overlapAdd( fadeOut, fadeIn, out, l_seg, ps->num_channels, ps->win + ps->l_halfwin, ps->win ); - } - } - else - { - /* just copy down 1st half of current segment (= 2nd half of previous segment) */ - float *frm_out_ptr; - const float *frm_in_ptr; - frm_out_ptr = &( frm_out[( n - 2 ) * l_seg] ); - frm_in_ptr = &( frm_in[l_frm + xtract[n]] ); - for ( i = 0; i < l_seg; i++ ) - { - frm_out_ptr[i] = frm_in_ptr[i]; - } - } - } - - /* append remaining samples */ - l_rem = l_frm - ( xtract[N] + l_seg ); - for ( i = 0; i < l_rem; i++ ) - { - frm_out[( N - 1 ) * l_seg + i] = frm_in[2 * l_frm - l_rem + i]; - } - - /* set output length */ - *l_frm_out = ( N - 1 ) * l_seg + l_rem; - - return 0; -} - -#endif diff --git a/lib_dec/jbm_pcmdsp_apa.h b/lib_dec/jbm_pcmdsp_apa.h index d0de5ea15..c1654407c 100644 --- a/lib_dec/jbm_pcmdsp_apa.h +++ b/lib_dec/jbm_pcmdsp_apa.h @@ -140,7 +140,7 @@ bool apa_set_complexity_options( apa_state_t *s, UWord16 wss, UWord16 css ); bool apa_set_complexity_options( apa_state_t *s, uint16_t wss, uint16_t css ); #endif -bool apa_set_quality( apa_state_t *s, float quality, uint16_t qualityred, uint16_t qualityrise ); +bool apa_set_quality( apa_state_t *s, Word32 quality, UWord16 qualityred, UWord16 qualityrise ); bool apa_exit( apa_state_t **s ); diff --git a/lib_dec/lib_dec_fx.c b/lib_dec/lib_dec_fx.c index 018771d4a..d59ddcfc4 100644 --- a/lib_dec/lib_dec_fx.c +++ b/lib_dec/lib_dec_fx.c @@ -3649,9 +3649,9 @@ static ivas_error IVAS_DEC_VoIP_reconfigure( IF( hIvasDec->st_ivas->hDecoderConfig->Opt_tsm ) { UWord16 wss, css; - float startQuality; + Word32 startQuality; - startQuality = fixedToFloat( hIvasDec->tsm_quality, Q14 ); + startQuality = L_shl( L_deposit_l( hIvasDec->tsm_quality ), Q2 ); /* Q14 --> Q16*/ apa_buffer_size = APA_BUF_PER_CHANNEL; move16(); diff --git a/lib_dec/tonalMDCTconcealment_fx.c b/lib_dec/tonalMDCTconcealment_fx.c index 1b96b3b8f..22d278f91 100644 --- a/lib_dec/tonalMDCTconcealment_fx.c +++ b/lib_dec/tonalMDCTconcealment_fx.c @@ -1391,7 +1391,7 @@ void TonalMDCTConceal_InsertNoise_ivas_fx( Word16 i, l, ld, fac; Word16 rnd; - Word16 tmp, g, tilt, exp_last, exp_noise, tiltFactor, crossfadeGain; + Word16 tmp, g, tilt, exp_last, exp_noise, tiltFactor, crossfadeGain, e_crossfadeGain; Word32 L_tmp, L_tmp2, nrgNoiseInLastFrame, nrgWhiteNoise; Word16 inv_exp, inv_samples, exp; Word32 last_block_nrg_correct; @@ -1401,6 +1401,8 @@ void TonalMDCTConceal_InsertNoise_ivas_fx( crossfadeGain = crossfadeGain_const; move16(); + e_crossfadeGain = 0; + move16(); push_wmops( "InsertNoise" ); g = sub( MAX16B, crossfadeGain ); @@ -1455,7 +1457,7 @@ void TonalMDCTConceal_InsertNoise_ivas_fx( IF( !tonalConcealmentActive ) { /* if fadeout has not started yet, only apply sign scrambling */ - IF( GE_16( crossfadeGain, CROSSFADE_THRESHOLD ) ) + IF( GE_16( crossfadeGain_const, CROSSFADE_THRESHOLD ) ) { FOR( i = 0; i < crossOverFreq; i++ ) { @@ -1527,6 +1529,7 @@ void TonalMDCTConceal_InsertNoise_ivas_fx( ELSE { crossfadeGain = shl( crossfadeGain, exp ); + e_crossfadeGain = sub( e_crossfadeGain, exp ); *mdctSpectrum_exp = sub( hTonalMDCTConc->lastBlockData.spectralData_exp, exp ); move16(); } @@ -1580,7 +1583,7 @@ void TonalMDCTConceal_InsertNoise_ivas_fx( mdctSpectrum[i] = 0; move32(); } - *mdctSpectrum_exp = sub( hTonalMDCTConc->lastBlockData.spectralData_exp, exp ); + *mdctSpectrum_exp = sub( add( e_crossfadeGain, hTonalMDCTConc->lastBlockData.spectralData_exp ), exp ); move16(); hTonalMDCTConc->faded_signal_nrg_exp = shl( *mdctSpectrum_exp, 1 ); move16(); @@ -1619,7 +1622,7 @@ void TonalMDCTConceal_InsertNoise_ivas_fx( last_block_nrg_correct_e = add( shl( hTonalMDCTConc->lastBlockData.spectralData_exp, 1 ), ld ); /* if fadeout has not started yet, only apply sign scrambling */ - IF( GE_16( crossfadeGain, CROSSFADE_THRESHOLD ) ) + IF( GE_16( crossfadeGain_const, CROSSFADE_THRESHOLD ) ) { FOR( l = 0; l < hTonalMDCTConc->pTCI->lowerIndex[0]; l++ ) { @@ -1718,7 +1721,8 @@ void TonalMDCTConceal_InsertNoise_ivas_fx( ELSE { crossfadeGain = shl( crossfadeGain, exp ); - *mdctSpectrum_exp = sub( hTonalMDCTConc->lastBlockData.spectralData_exp, exp ); + e_crossfadeGain = sub( e_crossfadeGain, exp ); + *mdctSpectrum_exp = add( e_crossfadeGain, hTonalMDCTConc->lastBlockData.spectralData_exp ); move16(); } /*make a headroom for mdct_shaping*/ @@ -1929,7 +1933,8 @@ void TonalMDCTConceal_InsertNoise_ivas_fx( ELSE { crossfadeGain = shl( crossfadeGain, exp ); - *mdctSpectrum_exp = sub( hTonalMDCTConc->lastBlockData.spectralData_exp, exp ); + e_crossfadeGain = sub( e_crossfadeGain, exp ); + *mdctSpectrum_exp = add( e_crossfadeGain, hTonalMDCTConc->lastBlockData.spectralData_exp ); move16(); } /*make a headroom for mdct_shaping*/ @@ -2104,7 +2109,9 @@ ELSE ELSE { crossfadeGain = shl( crossfadeGain, exp ); - *mdctSpectrum_exp = sub( hTonalMDCTConc->lastBlockData.spectralData_exp, exp ); + e_crossfadeGain = sub( e_crossfadeGain, exp ); + *mdctSpectrum_exp = add( e_crossfadeGain, hTonalMDCTConc->lastBlockData.spectralData_exp ); + move16(); } /*make a headroom for mdct_shaping*/ exp = sub( *mdctSpectrum_exp, SPEC_EXP_DEC ); diff --git a/lib_rend/ivas_reverb.c b/lib_rend/ivas_reverb.c index 42d48598a..73de5a7e6 100644 --- a/lib_rend/ivas_reverb.c +++ b/lib_rend/ivas_reverb.c @@ -2603,25 +2603,7 @@ ivas_error ivas_reverb_open_fx( move16(); IF( pState->do_corr_filter ) { - q_pFft_wf_filter_ch0_fx = 31; - move16(); - q_pFft_wf_filter_ch1_fx = 31; - move16(); /* Computing correlation filters on the basis of target IA coherence */ - FOR( int i = 0; i < nr_fc_fft_filter; i++ ) - { - pFft_wf_filter_ch0_fx[i][0] = L_shl_sat( pFft_wf_filter_ch0_fx[i][0], 8 ); - move32(); - pFft_wf_filter_ch0_fx[i][1] = L_shl_sat( pFft_wf_filter_ch0_fx[i][1], 8 ); - move32(); - } - FOR( int i = 0; i < nr_fc_fft_filter; i++ ) - { - pFft_wf_filter_ch1_fx[i][0] = L_shl_sat( pFft_wf_filter_ch1_fx[i][0], 8 ); - move32(); - pFft_wf_filter_ch1_fx[i][1] = L_shl_sat( pFft_wf_filter_ch1_fx[i][1], 8 ); - move32(); - } #ifdef MSAN_FIX FOR( int i = 0; i < shl( sub( nr_fc_fft_filter, 1 ), 1 ); i++ ) { diff --git a/lib_rend/ivas_reverb_filter_design.c b/lib_rend/ivas_reverb_filter_design.c index f34cbfde7..79ad2c151 100644 --- a/lib_rend/ivas_reverb_filter_design.c +++ b/lib_rend/ivas_reverb_filter_design.c @@ -212,6 +212,8 @@ static void calc_min_phase_fx( Word16 angle_increment; Word16 initial_angle; Word32 scale_factor; + Word64 W_tmp0, W_tmp1; + Word16 W_shift; IF( EQ_16( fft_size, 512 ) ) { @@ -235,12 +237,10 @@ static void calc_min_phase_fx( } /* Adding Hann half-window for smooth transition */ - - Word16 s1 = sub( norm_s( shr( EVS_PI_FX, 1 ) ), 1 ); - Word16 s2 = norm_s( sub( shl( cepstrum_smoothing_extent, 1 ), 1 ) ); - Word16 var1 = shl( EVS_PI_FX, s1 ); - Word16 var2 = shl( sub( shl( cepstrum_smoothing_extent, 1 ), 1 ), s2 ); - angle_increment = div_s( shr( var1, 5 ), var2 ); // q = 15 + Word16 e_tmp; + angle_increment = BASOP_Util_Divide1616_Scale( EVS_PI_FX, sub( shl( cepstrum_smoothing_extent, 1 ), 1 ), &e_tmp ); + e_tmp = add( e_tmp, 2 - 15 ); + angle_increment = shl( angle_increment, e_tmp ); /* Initial angle set to match Hann window alignment in Matlab */ @@ -248,7 +248,7 @@ static void calc_min_phase_fx( FOR( idx = 0; idx < cepstrum_smoothing_extent; idx++ ) { - const Word16 sine_value = getSineWord16R2( mult( add( initial_angle, shl( mult( shl( idx, 8 ), angle_increment ), 5 ) ), 20858 ) ); + const Word16 sine_value = getSinWord16( add( initial_angle, shl( mult( shl( idx, 8 ), angle_increment ), 5 ) ) ); // q15 pFolded_cepstrum_smoothing_win[add( idx, sub( half_fft_size, cepstrum_smoothing_extent ) )] = L_mult( sine_value, sine_value ); // q31 move32(); @@ -264,7 +264,11 @@ static void calc_min_phase_fx( /* Compute the log amplitude spectrum */ FOR( idx = 0; idx < spectrum_size; idx++ ) { - pCepstrum[idx] = Mpy_32_32( L_add( BASOP_Util_Log2( L_add( Mpy_32_32( pSpectrum[idx][0], pSpectrum[idx][0] ), Mpy_32_32( pSpectrum[idx][1], pSpectrum[idx][1] ) ) ), L_shl( 0, 25 ) ), LN_2_Q31 ); /* log2 = 0.693147, q = 31, value = 1488521848 */ // q =26 + W_tmp0 = W_mult_32_32( pSpectrum[idx][0], pSpectrum[idx][0] ); + W_tmp1 = W_mult_32_32( pSpectrum[idx][1], pSpectrum[idx][1] ); + W_tmp0 = W_add( W_tmp0, W_tmp1 ); + W_shift = W_norm( W_tmp0 ); + pCepstrum[idx] = Mpy_32_32( L_add( BASOP_Util_Log2( W_extract_h( W_shl( W_tmp0, W_shift ) ) ), L_shl( negate( W_shift ), 25 ) ), LN_2_Q31 ); /* log2 = 0.693147, q = 31, value = 1488521848 */ // q =26 move32(); } @@ -416,6 +420,9 @@ static void calc_min_phase_filter_fx( const Word16 spectrum_size = add( shr( fft_size, 1 ), 1 ); Word16 idx; Word32 pMin_phase[RV_FILTER_MAX_FFT_SIZE]; + Word64 W_tmp1, W_tmp2; + Word16 W_shift; + Word32 L_tmp; move16(); Word16 q_pMin_phase; @@ -425,16 +432,22 @@ static void calc_min_phase_filter_fx( { /* Cancel out initial phase by computing amplitude */ /* Note: slightly different (but mathematically equivalent) approach used for better efficiency */ - Word16 exp = 0; // 31-31 move16(); - Word32 current_ampl = Sqrt32( L_add( Mpy_32_32( pH_flt[idx][0], pH_flt[idx][0] ), Mpy_32_32( pH_flt[idx][1], pH_flt[idx][1] ) ), &exp ); // q = 31 -exp == 31 + W_tmp1 = W_mult_32_32( pH_flt[idx][0], pH_flt[idx][0] ); + W_tmp2 = W_mult_32_32( pH_flt[idx][1], pH_flt[idx][1] ); + W_tmp1 = W_add( W_tmp1, W_tmp2 ); + W_shift = W_norm( W_tmp1 ); + L_tmp = W_extract_h( W_shl( W_tmp1, W_shift ) ); + Word16 exp = negate( W_shift ); // 31-31-W_shift + + Word32 current_ampl = Sqrt32( L_tmp, &exp ); // q = 31 -exp == 31 current_ampl = L_shl( current_ampl, exp ); /* Using the phase computed by calc_min_phase() + additional delay */ /* Apply the computed phase */ - pH_flt[idx][0] = Mpy_32_16_1( current_ampl, getCosWord16R2( mult( abs_s( (Word16) L_shr( pMin_phase[idx], sub( q_pMin_phase, 13 ) ) ), 20858 ) ) ); // shifting right for next function. + pH_flt[idx][0] = Mpy_32_16_1( current_ampl, shl_sat( getCosWord16( abs_s( (Word16) L_shr( pMin_phase[idx], sub( q_pMin_phase, 13 ) ) ) ), 1 ) ); // shifting right for next function. move32(); - pH_flt[idx][1] = Mpy_32_16_1( current_ampl, getSineWord16R2( mult( (Word16) L_shr( pMin_phase[idx], sub( q_pMin_phase, 13 ) ), 20858 ) ) ); + pH_flt[idx][1] = Mpy_32_16_1( current_ampl, getSinWord16( (Word16) L_shr( pMin_phase[idx], sub( q_pMin_phase, 13 ) ) ) ); move32(); } @@ -668,7 +681,7 @@ static void response_step_limit_fx( FOR( i = add( pivot_bin_idx, 1 ); i < dim_x; i++ ) { Word16 div_e; - Word32 desiredChange = L_deposit_h( ( BASOP_Util_Divide3232_Scale( X[i], X[i - 1], &div_e ) ) ); + Word32 desiredChange = BASOP_Util_Divide3232_Scale_cadence( X[i], X[i - 1], &div_e ); Word16 desiredChange_q = sub( 31, ( div_e ) ); Word64 temp; IF( GT_16( desiredChange_q, 30 ) ) @@ -707,7 +720,7 @@ static void response_step_limit_fx( FOR( i = sub( pivot_bin_idx, 1 ); i >= 0; i-- ) { Word16 div_e; - Word32 desiredChange = L_deposit_h( ( BASOP_Util_Divide3232_Scale( X[i], X[i + 1], &div_e ) ) ); + Word32 desiredChange = BASOP_Util_Divide3232_Scale_cadence( X[i], X[i + 1], &div_e ); Word16 desiredChange_q = sub( 31, ( div_e ) ); Word64 temp; IF( GT_16( desiredChange_q, 30 ) ) @@ -1159,6 +1172,9 @@ void ivas_reverb_calc_color_levels_fx( Word16 i, freq_idx, idx_pivot, nrcoefs, loop_idx; Word32 t60[RV_LENGTH_NR_FC]; Word16 t60_e[RV_LENGTH_NR_FC + 1]; + Word64 W_tmp1, W_tmp2; + Word16 W_shift; + Word32 L_tmp; /* Pre-computing inverse values for optimisation (to avoid divisions in inner loops) */ Word16 fs_inverted_q; @@ -1215,10 +1231,9 @@ void ivas_reverb_calc_color_levels_fx( move16(); cos_w = getCosWord16R2( (Word16) abs( L_shl( Mpy_32_32( pFc[freq_idx], fs_inverted ), 3 ) ) ); // q = 15 H_filter = L_add( L_shr( L_add( L_shr( Mpy_32_32( coefB[0], coefB[0] ), 1 ), L_shr( Mpy_32_32( coefB[1], coefB[1] ), 1 ) ), 2 ), L_shr( Mpy_32_32( coefB[0], Mpy_32_32( coefB[1], L_shl( cos_w, 15 ) ) ), 1 ) ); // q = 28 - H_filter = BASOP_Util_Divide3232_Scale( H_filter, L_add( ONE_IN_Q28, L_shr( L_add( L_shr( Mpy_32_32( coefA[1], coefA[1] ), 2 ), Mpy_32_32( coefA[1], L_shl( cos_w, 15 ) ) ), 1 ) ), &temp ); - H_filter = Sqrt32( L_shl( H_filter, 16 ), &temp ); - T60_est = BASOP_Util_Divide3232_Scale( L_shl( i_mult( -3, pLoop_delays[loop_idx] ), 2 ), Mpy_32_32( Mpy_32_32( L_add( BASOP_Util_Log2( H_filter ), L_shl( temp, 25 ) ), LOG10_2_Q31 ), L_shl( output_Fs, 8 ) ), &temp ); // conversion of log2 to log10. - T60_est = L_shl( T60_est, 16 ); + H_filter = BASOP_Util_Divide3232_Scale_cadence( H_filter, L_add( ONE_IN_Q28, L_shr( L_add( L_shr( Mpy_32_32( coefA[1], coefA[1] ), 2 ), Mpy_32_32( coefA[1], L_shl( cos_w, 15 ) ) ), 1 ) ), &temp ); + H_filter = Sqrt32( H_filter, &temp ); + T60_est = BASOP_Util_Divide3232_Scale_cadence( L_shl( i_mult( -3, pLoop_delays[loop_idx] ), 2 ), Mpy_32_32( Mpy_32_32( L_add( BASOP_Util_Log2( H_filter ), L_shl( temp, 25 ) ), LOG10_2_Q31 ), L_shl( output_Fs, 8 ) ), &temp ); // conversion of log2 to log10. t60[freq_idx] = BASOP_Util_Add_Mant32Exp( T60_est, temp, t60[freq_idx], t60_e[freq_idx], &result_e ); move16(); t60_e[freq_idx] = result_e; @@ -1249,23 +1264,26 @@ void ivas_reverb_calc_color_levels_fx( { Word16 temp, temp1, temp2, temp3 = 0, temp4, temp5; move16(); - Word32 var1 = divide3232( (Word32) i_mult( -6, minDelay ), L_shr( Mpy_32_32( t60[freq_idx], L_shl( output_Fs, 11 ) ), sub( 11, t60_e[freq_idx] ) ) ); - var1 = L_mult( (Word16) var1, LOG2_10 ); // q = 29 - Word32 A0_square_est = BASOP_util_Pow2( var1, 31 - 29, &temp ); + Word32 var1 = BASOP_Util_Divide3232_Scale_cadence( (Word32) i_mult( -6, minDelay ), L_shr( Mpy_32_32( t60[freq_idx], L_shl( output_Fs, 11 ) ), sub( 11, t60_e[freq_idx] ) ), &temp ); + var1 = Mpy_32_32( var1, LOG2_10_Q29 ); // e = temp + (31 - 29) + Word32 A0_square_est = BASOP_util_Pow2( var1, add( temp, 31 - 29 ), &temp ); Word16 alpha_e; - Word16 alpha = BASOP_Util_Divide3232_Scale( -log__0_001, t60[freq_idx], &alpha_e ); // alpha_e = 1 + alpha_e + (3 - t60_e[257]) + Word32 alpha = BASOP_Util_Divide3232_Scale_cadence( -log__0_001, t60[freq_idx], &alpha_e ); // alpha_e = 1 + alpha_e + (3 - t60_e[257]) - Word16 div11 = BASOP_Util_Divide3216_Scale( A0_square_est, alpha, &temp1 ); // e = temp1 + (temp - alpha_e) - Word32 div2 = BASOP_Util_Divide3232_Scale( L_shl( output_Fs, 11 ), L_shr( L_add( Mpy_32_16_1( 1884631649, shl( minDelayDiff, 3 ) ), 14037339 ), 8 ), &temp2 ); // e = temp2, 26.7741 in Q19, 0.8776 in Q31 + Word32 div11 = BASOP_Util_Divide3232_Scale_cadence( A0_square_est, alpha, &temp1 ); // e = temp1 + (temp - alpha_e) + Word32 div2 = BASOP_Util_Divide3232_Scale_cadence( L_shl( output_Fs, 11 ), L_shr( L_add( Mpy_32_16_1( 1884631649, shl( minDelayDiff, 3 ) ), 14037339 ), 8 ), &temp2 ); // e = temp2, 26.7741 in Q19, 0.8776 in Q31 - const Word32 revPredNormEnergy = Mpy_32_16_1( L_shl( div2, 16 ), div11 ); // q = (15 - temp2) + (15 - temp1) - 15 + 1 + const Word32 revPredNormEnergy = Mpy_32_32( div2, div11 ); // q = (15 - temp2) + (15 - temp1) - 15 + 1 // L_max Word32 div1; temp3 = add( add( temp1, sub( temp, add( 1, add( alpha_e, sub( 3, t60_e[freq_count] ) ) ) ) ), temp2 ); div1 = L_max( Sqrt32( revPredNormEnergy, &temp3 ), 1 ); - temp4 = 3; - div2 = Sqrt32( Mpy_32_32( pAcoustic_dsr[freq_idx], pHrtf_avg_pwr_L[freq_idx] ), &temp4 ); - pTarget_color_L[freq_idx] = (Word32) BASOP_Util_Divide3232_Scale( div2, div1, &temp5 ); + W_tmp1 = W_mult_32_32( pAcoustic_dsr[freq_idx], pHrtf_avg_pwr_L[freq_idx] ); + W_shift = W_norm( W_tmp1 ); + L_tmp = W_extract_h( W_shl( W_tmp1, W_shift ) ); + temp4 = sub( 3, W_shift ); + div2 = Sqrt32( L_tmp, &temp4 ); + pTarget_color_L[freq_idx] = BASOP_Util_Divide3232_Scale_cadence( div2, div1, &temp5 ); move32(); temp5 = add( temp5, sub( temp4, temp3 ) ); pTarget_color_L_e[freq_idx] = temp5; @@ -1273,10 +1291,12 @@ void ivas_reverb_calc_color_levels_fx( temp3 = add( add( temp1, sub( temp, add( 1, add( alpha_e, sub( 3, t60_e[freq_count] ) ) ) ) ), temp2 ); div1 = L_max( Sqrt32( revPredNormEnergy, &temp3 ), 1 ); - temp4 = 3; - move16(); - div2 = Sqrt32( Mpy_32_32( pAcoustic_dsr[freq_idx], pHrtf_avg_pwr_R[freq_idx] ), &temp4 ); - pTarget_color_R[freq_idx] = BASOP_Util_Divide3232_Scale( div2, div1, &temp5 ); + W_tmp2 = W_mult_32_32( pAcoustic_dsr[freq_idx], pHrtf_avg_pwr_R[freq_idx] ); + W_shift = W_norm( W_tmp2 ); + L_tmp = W_extract_h( W_shl( W_tmp2, W_shift ) ); + temp4 = sub( 3, W_shift ); + div2 = Sqrt32( L_tmp, &temp4 ); + pTarget_color_R[freq_idx] = BASOP_Util_Divide3232_Scale_cadence( div2, div1, &temp5 ); move32(); temp5 = add( temp5, sub( temp4, temp3 ) ); pTarget_color_R_e[freq_idx] = temp5; @@ -1284,9 +1304,9 @@ void ivas_reverb_calc_color_levels_fx( } FOR( freq_idx = 0; freq_idx < freq_count; freq_idx++ ) { - pTarget_color_R[freq_idx] = L_shr( L_shl( pTarget_color_R[freq_idx], 16 ), sub( 1, pTarget_color_R_e[freq_idx] ) ); // (31 - pTarget_color_R_e[freq_idx]) - 30 + pTarget_color_R[freq_idx] = L_shr( pTarget_color_R[freq_idx], sub( 1, pTarget_color_R_e[freq_idx] ) ); // (31 - pTarget_color_R_e[freq_idx]) - 30 move32(); - pTarget_color_L[freq_idx] = L_shr( L_shl( pTarget_color_L[freq_idx], 16 ), sub( 1, pTarget_color_L_e[freq_idx] ) ); // (31 - pTarget_color_L_e[freq_idx]) - 30 + pTarget_color_L[freq_idx] = L_shr( pTarget_color_L[freq_idx], sub( 1, pTarget_color_L_e[freq_idx] ) ); // (31 - pTarget_color_L_e[freq_idx]) - 30 move32(); } /* Limiting the frequency response gradients @@ -1294,8 +1314,8 @@ void ivas_reverb_calc_color_levels_fx( Word32 div1; Word16 temp = 0; move16(); - div1 = BASOP_Util_Divide3232_Scale( L_mult0( 1000, sub( freq_count, 1 ) ), L_shr( output_Fs, 1 ), &temp ); - div1 = BASOP_Util_Add_Mant32Exp( L_shl( div1, 16 ), temp, ONE_IN_Q30, 1, &temp ); + div1 = BASOP_Util_Divide3232_Scale_cadence( L_mult0( 1000, sub( freq_count, 1 ) ), L_shr( output_Fs, 1 ), &temp ); + div1 = BASOP_Util_Add_Mant32Exp( div1, temp, ONE_IN_Q30, 1, &temp ); idx_pivot = extract_l( L_shr( div1, sub( 31, temp ) ) ); /* Perform step limiting */ diff --git a/lib_rend/ivas_shoebox.c b/lib_rend/ivas_shoebox.c index 6d6b685a8..585696760 100644 --- a/lib_rend/ivas_shoebox.c +++ b/lib_rend/ivas_shoebox.c @@ -645,8 +645,7 @@ static Word32 shoebox_get_euclidian_distance_internal_fx( ELSE { t = (Word32) W_mult0_32_32( absxk, ER_RECIPROCAL_EUCLIDEAN_SCALE_FX ); // Q22 - out_tmp = Mpy_32_32( t, t ); // Q13 - out_tmp = L_shl( out_tmp, 9 ); // Q22 + out_tmp = W_extract_h( W_shl( W_mult_32_32( t, t ), 9 ) ); // Q22 + Q22 + Q1 + Q9 - 32 = Q22 } absxk = L_abs( L_sub( obj->list_pos_fx[1], tmp_pos[1] ) ); @@ -655,27 +654,19 @@ static Word32 shoebox_get_euclidian_distance_internal_fx( { q = Q22; move16(); - t = (Word32) BASOP_Util_Divide3232_Scale( *scale, absxk, &q ); - q = sub( Q22, sub( Q15, q ) ); - t = L_shl( t, q ); - - out_tmp = Mpy_32_32( out_tmp, t ); // Q13 - out_tmp = L_shl( out_tmp, 9 ); - out_tmp = Mpy_32_32( out_tmp, t ); // Q13 - out_tmp = L_add( L_shl( out_tmp, 9 ), ONE_IN_Q22 ); //.22 - *scale = absxk; // Q.22 + t = (Word32) BASOP_Util_Divide3232_Scale_cadence( *scale, absxk, &q ); + + out_tmp = W_extract_h( W_shl( W_mult_32_32( out_tmp, t ), q ) ); // Q22 + Q31 + Q1 - 32 = Q22 + out_tmp = W_extract_h( W_shl( W_mult_32_32( out_tmp, t ), q ) ); // Q22 + Q31 + Q1 - 32 = Q22 + out_tmp = L_add( out_tmp, ONE_IN_Q22 ); //.22 + *scale = absxk; // Q.22 move32(); } ELSE { - q = Q22; - move16(); - t = (Word32) BASOP_Util_Divide3232_Scale( absxk, *scale, &q ); - q = sub( Q22, sub( Q15, q ) ); - t = L_shl( t, q ); - t = Mpy_32_32( t, t ); // Q.13 - t = L_shl( t, 9 ); - out_tmp = L_add( out_tmp, t ); //.22 + t = (Word32) BASOP_Util_Divide3232_Scale_cadence( absxk, *scale, &q ); + t = W_extract_h( W_shl( W_mult_32_32( t, t ), sub( shl( q, 1 ), 9 ) ) ); // Q31 + Q31 + Q1 - 9 - 32 = Q22 + out_tmp = L_add( out_tmp, t ); //.22 move32(); } @@ -683,34 +674,25 @@ static Word32 shoebox_get_euclidian_distance_internal_fx( IF( GE_32( absxk, *scale ) ) { - q = Q22; - move16(); - t = (Word32) BASOP_Util_Divide3232_Scale( *scale, absxk, &q ); - q = sub( Q22, sub( Q15, q ) ); - t = L_shl( t, q ); - - out_tmp = Mpy_32_32( out_tmp, t ); // Q13 - out_tmp = L_shl( out_tmp, 9 ); - out_tmp = Mpy_32_32( out_tmp, t ); // Q13 - out_tmp = L_add( L_shl( out_tmp, 9 ), ONE_IN_Q22 ); //.22 - *scale = absxk; // Q.22 + t = (Word32) BASOP_Util_Divide3232_Scale_cadence( *scale, absxk, &q ); + + out_tmp = W_extract_h( W_shl( W_mult_32_32( out_tmp, t ), q ) ); // Q22 + Q31 + Q1 - 32 = Q22 + out_tmp = W_extract_h( W_shl( W_mult_32_32( out_tmp, t ), q ) ); // Q22 + Q31 + Q1 - 32 = Q22 + out_tmp = L_add( out_tmp, ONE_IN_Q22 ); //.22 + *scale = absxk; // Q.22 move32(); } ELSE { - q = Q22; - move16(); - t = (Word32) BASOP_Util_Divide3232_Scale( absxk, *scale, &q ); - q = sub( Q22, sub( Q15, q ) ); - t = L_shl( t, q ); // Q22 - t = Mpy_32_32( t, t ); // Q.13 - t = L_shl( t, 9 ); - out_tmp = L_add( out_tmp, t ); //.22 + t = (Word32) BASOP_Util_Divide3232_Scale_cadence( absxk, *scale, &q ); + t = W_extract_h( W_shl( W_mult_32_32( t, t ), sub( shl( q, 1 ), 9 ) ) ); // Q31 + Q31 + Q1 - 9 - 32 = Q22 + out_tmp = L_add( out_tmp, t ); //.22 } return out_tmp; } + #endif -- GitLab