diff --git a/lib_com/fd_cng_com_fx.c b/lib_com/fd_cng_com_fx.c index 630eca54b23f81894cd19438e80bf37bb74c9f4e..0120c48dcbb4cf6d7c3187b9ac7dd778381c91bb 100644 --- a/lib_com/fd_cng_com_fx.c +++ b/lib_com/fd_cng_com_fx.c @@ -363,6 +363,62 @@ void expand_range( } +/*------------------------------------------------------------------- + * expand_range_var_e() + * + * Apply some dynamic range expansion to undo the compression. Similar + * to expand_range but has variable input exponent. + * + *-------------------------------------------------------------------*/ +void expand_range_var_exp( + Word16 *in, + Word16 in_exp, + Word32 *out, + Word16 *out_exp, + const Word16 len ) +{ + Word16 i, tmp_e; + Word32 tmp32; + Word16 maxVal, maxOutExp; + + const Word32 low_lim = 726940; /* 0.0003385080526823181f in Q31 */ + move32(); + + /* Find max possible output exponent. */ + maxVal = 0; + move16(); + FOR( i = 0; i < len; i++ ) + { + maxVal = s_max( maxVal, in[i] ); + } + tmp32 = BASOP_util_Pow2( L_deposit_h( maxVal ), in_exp, &tmp_e ); + maxOutExp = tmp_e; + move16(); + + /* out = (2^(in) - 1) */ + FOR( i = 0; i < len; i++ ) + { + tmp32 = BASOP_util_Pow2( L_deposit_h( in[i] ), in_exp, &tmp_e ); // 2^x + tmp32 = L_sub( tmp32, L_shl( 1, sub( 31, tmp_e ) ) ); // 2^x - 1 + tmp32 = L_shr( tmp32, sub( maxOutExp, tmp_e ) ); // make exp same as maxExpOut + + out[i] = tmp32; + move32(); + + Word32 tmp_low_lim = L_shr( low_lim, maxOutExp ); + IF( LT_32( out[i], tmp_low_lim ) ) + { + out[i] = tmp_low_lim; + move32(); + } + } + + *out_exp = maxOutExp; + move16(); + + return; +} + /*------------------------------------------------------------------- * minimum_statistics() * diff --git a/lib_com/prot_fx2.h b/lib_com/prot_fx2.h index 092a2e9963cd7c250a9c9979a3ed46a9fa60c6c6..e2de993c3149caba4ebb1c53f7d24c246f13c384 100644 --- a/lib_com/prot_fx2.h +++ b/lib_com/prot_fx2.h @@ -4417,6 +4417,14 @@ void expand_range( const Word16 len ); +void expand_range_var_exp( + Word16 *in, + Word16 in_exp, + Word32 *out, + Word16 *out_exp, + const Word16 len +); + void minimum_statistics(Word16 len, /* i : Total number of partitions (CLDFB or FFT) */ Word16 lenFFT, /* i : Number of FFT partitions */ Word16 *psize, /* i : Partition sizes, fractional */ diff --git a/lib_dec/ivas_tcx_core_dec.c b/lib_dec/ivas_tcx_core_dec.c index 796b38176845596761aeeea1bc5c178851389ce4..660b70d6812bcee8f9d13c86ea53294f2febf479 100644 --- a/lib_dec/ivas_tcx_core_dec.c +++ b/lib_dec/ivas_tcx_core_dec.c @@ -753,18 +753,15 @@ void stereo_tcx_core_dec( } #ifdef IVAS_FLOAT_FIXED Word16 msPsd_fx[NPART_SHAPING]; + Word16 msPsd_e; Word32 psd_part_fx[NPART_SHAPING]; - Word16 psd_part_q; - for (int ii = 0; ii < st->hFdCngDec->nFFTpart_shaping; ii++) - { - msPsd_fx[ii] = (Word16)(st->hFdCngDec->msPsd_float[ii] * pow(2, Q9)); - } - expand_range(msPsd_fx, psd_part_fx, &psd_part_q, st->hFdCngDec->nFFTpart_shaping); - for (int ii = 0; ii < st->hFdCngDec->nFFTpart_shaping; ii++) - { - /* converting back to float */ - st->hFdCngDec->msPsd_float[ii] = (float)(psd_part_fx[ii] * pow(2, psd_part_q - 31)); - } + Word16 psd_part_e; + + f2me_buf_16(st->hFdCngDec->msPsd_float, msPsd_fx, &msPsd_e, st->hFdCngDec->nFFTpart_shaping); + + expand_range_var_exp(msPsd_fx, msPsd_e, psd_part_fx, &psd_part_e, st->hFdCngDec->nFFTpart_shaping); + + me2f_buf(psd_part_fx, psd_part_e, psd_part, st->hFdCngDec->nFFTpart_shaping); #else expand_range_flt( st->hFdCngDec->msPsd_float, psd_part, st->hFdCngDec->nFFTpart_shaping ); #endif