diff --git a/Workspace_msvc/lib_com.vcxproj b/Workspace_msvc/lib_com.vcxproj index 2fc3f8f56b52037d6dbdf544b46d78d338dbdbee..eeb61b2d94a7ab0fd8506de8ad4701e8f18e7f93 100644 --- a/Workspace_msvc/lib_com.vcxproj +++ b/Workspace_msvc/lib_com.vcxproj @@ -122,9 +122,13 @@ + + + + @@ -132,49 +136,71 @@ + + + + + + + + + + + + + + + + + + + + + + @@ -183,12 +209,16 @@ + + + + @@ -234,19 +264,24 @@ + + + + + @@ -256,9 +291,11 @@ + + @@ -266,9 +303,12 @@ + + + @@ -280,35 +320,49 @@ + + + + + + + + + + + + + + diff --git a/Workspace_msvc/lib_com.vcxproj.filters b/Workspace_msvc/lib_com.vcxproj.filters index 2d8a6c550c1ed1b3403129496bb3ea27d236b73d..8eac6b783caeabfbf62e0a8b1af1bf0ab3e2f361 100644 --- a/Workspace_msvc/lib_com.vcxproj.filters +++ b/Workspace_msvc/lib_com.vcxproj.filters @@ -469,210 +469,281 @@ common_all_c + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_evs_c - - - common_all_c - + + + + + + + + + + + + + + + + + + + - - common_evs_c - - - common_evs_c - - - common_evs_c - - - common_evs_c - - - common_evs_c - - - common_evs_c - - - common_evs_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - common_h - - - common_h - - - common_h - - - common_h - - - common_h - - - common_h - - - common_h - - - common_h - - - common_h - - - common_h - - - common_h - - - common_h - - - common_h - - - common_h - - - common_h - - - common_h - - - common_h - - - common_h - - - common_h - - - - common_h - + + + + + - - common_h - - - common_h - + + + + + + + + + + + + + + + + + + - - - {890c2f45-9385-4fce-859b-6a65469e8dc0} - - - {201ea764-9626-4dca-9cc4-5b4106f8b8b2} - - - {fbb860e2-79d0-45b1-ada1-c3a0a369ce2c} - - - {b95b7bed-a666-4a00-9332-2b528638503e} - - - \ No newline at end of file + diff --git a/Workspace_msvc/lib_dec.vcxproj b/Workspace_msvc/lib_dec.vcxproj index 1ca72d992a147a38364ff6521863649bc4dd84ce..4a011c45491e6c6291184c76dba8f48657aec049 100644 --- a/Workspace_msvc/lib_dec.vcxproj +++ b/Workspace_msvc/lib_dec.vcxproj @@ -137,71 +137,142 @@ + + false + + + false + + + + + + + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -273,41 +344,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Workspace_msvc/lib_dec.vcxproj.filters b/Workspace_msvc/lib_dec.vcxproj.filters index 0daba65c395102fc984878c7c5b7e7a23dea4161..010c41fafa68ecd8ee6d9e4bec2b17a4aaf60779 100644 --- a/Workspace_msvc/lib_dec.vcxproj.filters +++ b/Workspace_msvc/lib_dec.vcxproj.filters @@ -496,9 +496,6 @@ decoder_all_c - - decoder_all_c - decoder_all_c @@ -514,9 +511,306 @@ decoder_all_c + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_evs_c + decoder_all_c + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_evs_c + + + decoder_all_c + + + decoder_all_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_evs_c + + + decoder_all_c + + + decoder_all_c + + + decoder_evs_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_all_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_evs_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_all_c + + + decoder_evs_c + diff --git a/lib_com/ACcontextMapping.c b/lib_com/ACcontextMapping.c index 13cbe8482ba51ad3f2768d9e29d66198cd01810a..b83cccdb565482d28b2c07a341585fb74a3fe655 100644 --- a/lib_com/ACcontextMapping.c +++ b/lib_com/ACcontextMapping.c @@ -41,13 +41,13 @@ #include "wmc_auto.h" /*-------------------------------------------------------------------* - * get_next_coeff_mapped() + * get_next_coeff_mapped_ivas() * * *-------------------------------------------------------------------*/ /*! r: index of next coefficient */ -int16_t get_next_coeff_mapped( +int16_t get_next_coeff_mapped_ivas( int16_t ii[2], /* i/o: coefficient indexes */ int32_t *pp, /* o : peak(1)/hole(0) indicator */ int16_t *idx, /* o : index in unmapped domain */ @@ -67,13 +67,13 @@ int16_t get_next_coeff_mapped( /*-------------------------------------------------------------------* - * get_next_coeff_unmapped() + * get_next_coeff_unmapped_ivas() * * *-------------------------------------------------------------------*/ /*! r: index of next coefficient */ -int16_t get_next_coeff_unmapped( +int16_t get_next_coeff_unmapped_ivas( int16_t *ii, /* i/o: coefficient indexes */ int16_t *idx /* o : index in unmapped domain */ ) @@ -85,12 +85,12 @@ int16_t get_next_coeff_unmapped( } /*-------------------------------------------------------------------* - * update_mixed_context() + * update_mixed_context_ivas() * * *-------------------------------------------------------------------*/ -int32_t update_mixed_context( +int32_t update_mixed_context_ivas( int32_t ctx, int16_t a ) { diff --git a/lib_com/ACcontextMapping_fx.c b/lib_com/ACcontextMapping_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..4aec733478d7f2618cab70468acc715ac8f187a4 --- /dev/null +++ b/lib_com/ACcontextMapping_fx.c @@ -0,0 +1,78 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include +#include "options.h" +#include "basop_util.h" +#include "cnst.h" +#include "prot_fx1.h" +#include "prot_fx2.h" +#include "rom_com.h" + +/* Returns: index of next coefficient */ +Word16 get_next_coeff_mapped( + Word16 ii[2], /* i/o: coefficient indexes */ + Word16 *pp, /* o : peak(1)/hole(0) indicator */ + Word16 *idx, /* o : index in unmapped domain */ + CONTEXT_HM_CONFIG *hm_cfg /* i : HM configuration */ +) +{ + Word16 p; + + p = s_and(sub(ii[1], hm_cfg->numPeakIndices), sub(hm_cfg->indexBuffer[ii[1]], hm_cfg->indexBuffer[ii[0]])); + if (p > 0) + { + p = 0; + move16(); + } + if (p < 0) + { + p = 1; + move16(); + } + *pp = p; + move16(); + *idx = ii[p]; + move16(); + ii[p] = add(ii[p], 1); + move16(); + return hm_cfg->indexBuffer[*idx]; +} + +/* Returns: index of next coefficient */ +Word16 get_next_coeff_unmapped( + Word16 ii[2], /* i/o: coefficient indexes */ + Word16 *pp, /* o : peak(1)/hole(0) indicator */ + Word16 *idx, /* o : index in unmapped domain */ + CONTEXT_HM_CONFIG *hm_cfg /* i : HM configuration */ +) +{ + (void)pp; + (void)hm_cfg; + + *idx = ii[0]; + move16(); + ii[0] = add(ii[0], 1); + move16(); + return *idx; +} + +Word16 update_mixed_context(Word16 ctx, Word16 a) +{ + Word32 t32; + Word16 t=0; /* initialize just to avoid compiler warning */ + + t32 = L_mac0(1-13, s_and(a, ~1), add(shr(a, 2), 1)); + if (t32 <= 0) + { + t = extract_l(t32); + } + a = shr(a, 3); + if (t32 > 0) + { + t = s_min(a, 2); + } + return add(shl(s_and(ctx, 0xf), 4), add(t, 13)); +} + diff --git a/lib_com/ari.c b/lib_com/ari.c index 2ee0be62310edc98d315593d6f269ca2529a6423..af760b378c11ef2845784cddfaf84d6d9d6103a3 100644 --- a/lib_com/ari.c +++ b/lib_com/ari.c @@ -54,7 +54,7 @@ * * \return r*c */ -int32_t mul_sbc_14bits( +int32_t mul_sbc_14bits_ivas( int32_t r, int32_t c ) { diff --git a/lib_com/ari_fx.c b/lib_com/ari_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..d8c17c7e7996a25c3c887220cad5d109c18d3962 --- /dev/null +++ b/lib_com/ari_fx.c @@ -0,0 +1,57 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include +#include "assert.h" +#include "options.h" +#include "prot_fx1.h" +#include "prot_fx2.h" +#include "cnst.h" + +/** + * \brief 31x16 Bit multiply (x*y) + * + * \param[i] xh high part, bit [30..15] + * \param[i] xl low part, 15 LSBits + * \param[i] y + * + * \return x*y + */ +Word32 L_multi31x16_X2(Word16 xh, Word16 xl, Word16 y) +{ + Word32 z; + + z = L_shl(L_mult0(xh,y),15); + z = L_mac0(z,xl,y); + + return z; +} + +/*--------------------------------------------------------------- + Ari 14 bits common routines + -------------------------------------------------------------*/ + +/** + * \brief Integer Multiply + * + * \param[i] r + * \param[i] c + * + * \return r*c + */ +Word32 mul_sbc_14bits(Word32 r, Word16 c) +{ + Word32 ret; + + + /* + temp = (((int32) r)*((int32) c))>>stat_bitsnew; + */ + assert(stat_bitsnew == 14); + ret = Mpy_32_16_1(L_shl(r,15-stat_bitsnew), c); + + /*assert( (((int) r)*((int) c))>>stat_bitsnew == ret);*/ + + return (ret); +} diff --git a/lib_com/ari_hm.c b/lib_com/ari_hm.c index 411ebe01671f09b3e9160a46c673868217f9f274..a229cdbb9bfe3f4429300a701820543f9a5a691c 100644 --- a/lib_com/ari_hm.c +++ b/lib_com/ari_hm.c @@ -45,12 +45,12 @@ #include "wmc_auto.h" /*-------------------------------------------------------------------* - * UnmapIndex() + * UnmapIndex_ivas() * * *-------------------------------------------------------------------*/ -void UnmapIndex( +void UnmapIndex_ivas( const int16_t PeriodicityIndex, const int16_t Bandwidth, const int16_t LtpPitchLag, @@ -166,12 +166,12 @@ void UnmapIndex_fx( /*-------------------------------------------------------------------* - * ConfigureContextHm() + * ConfigureContextHm_ivas() * * *-------------------------------------------------------------------*/ -void ConfigureContextHm( +void ConfigureContextHm_ivas( const int16_t NumCoeffs, /* (I) Number of coefficients */ const int16_t TargetBits, /* (I) Target bit budget (excl. Done flag) */ const int16_t PeriodicityIndex, /* (I) Pitch related index */ @@ -199,7 +199,7 @@ void ConfigureContextHm( SmallerLags = 1; } - UnmapIndex( PeriodicityIndex, Bandwidth, LtpPitchLag, SmallerLags, &FractionalResolution, &Lag ); + UnmapIndex_ivas( PeriodicityIndex, Bandwidth, LtpPitchLag, SmallerLags, &FractionalResolution, &Lag ); /* Set up and fill peakIndices */ hm_cfg->peakIndices = hm_cfg->indexBuffer; @@ -242,12 +242,12 @@ void ConfigureContextHm( /*-------------------------------------------------------------------* - * CountIndexBits() + * CountIndexBits_ivas() * * *-------------------------------------------------------------------*/ -int16_t CountIndexBits( +int16_t CountIndexBits_ivas( const int16_t Bandwidth, const int16_t PeriodicityIndex ) { @@ -284,12 +284,12 @@ Word16 CountIndexBits_fx( #define WMC_TOOL_SKIP /*-------------------------------------------------------------------* - * tcx_hm_render() + * tcx_hm_render_ivas() * * *-------------------------------------------------------------------*/ -int16_t tcx_hm_render( +int16_t tcx_hm_render_ivas( const int16_t lag, /* i : pitch lag */ const int16_t fract_res, /* i : fractional resolution of the lag */ Word16 p[] /* o : harmonic model (Q13) */ @@ -398,12 +398,12 @@ Word32 tcx_hm_render_fx( } /*-------------------------------------------------------------------* - * tcx_hm_modify_envelope() + * tcx_hm_modify_envelope_ivas() * * *-------------------------------------------------------------------*/ -void tcx_hm_modify_envelope( +void tcx_hm_modify_envelope_ivas( const Word16 gain, /* i : HM gain (Q11) */ const int16_t lag, const int16_t fract_res, diff --git a/lib_com/ari_hm_fx.c b/lib_com/ari_hm_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..6d2f725f98ef0c7e4b58f488b46e6d636543b1f0 --- /dev/null +++ b/lib_com/ari_hm_fx.c @@ -0,0 +1,294 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + + +#include +#include +#include "options.h" +#include "cnst.h" +#include "basop_util.h" +#include "rom_com.h" +#include "prot_fx1.h" +#include "prot_fx2.h" + +#define GET_ADJ2(T,L,F) (((L) << (F)) - (T)) +void UnmapIndex( + Word16 PeriodicityIndex, + Word16 Bandwidth, + Word16 LtpPitchLag, + Word8 SmallerLags, + Word16 *FractionalResolution, + Word32 *Lag +) +{ + Word16 LtpPitchIndex, Multiplier; + Word16 Lag16; + + test(); + IF ((LtpPitchLag > 0) && (s_and(PeriodicityIndex, kLtpHmFlag) != 0)) + { + LtpPitchIndex = shr(PeriodicityIndex, 9); + Multiplier = s_and(PeriodicityIndex, 0xff); + + assert(0 <= LtpPitchIndex && LtpPitchIndex <= 16); + assert(1 <= Multiplier && Multiplier <= (1 << NumRatioBits[Bandwidth][LtpPitchIndex])); + + *FractionalResolution = kLtpHmFractionalResolution; + move16(); + *Lag = L_shr(L_mult0(LtpPitchLag, Ratios_fx[Bandwidth][LtpPitchIndex][Multiplier-1]), 8); + move32(); + } + ELSE + { + IF (LT_16(PeriodicityIndex, 16)) + { + *FractionalResolution = 3; + move16(); + Lag16 = add(PeriodicityIndex, GET_ADJ2(0, 6, 3)); + } + ELSE IF (LT_16(PeriodicityIndex, 80)) + { + *FractionalResolution = 4; + move16(); + Lag16 = add(PeriodicityIndex, GET_ADJ2(16, 8, 4)); + } + ELSE IF (LT_16(PeriodicityIndex, 208)) + { + *FractionalResolution = 3; + move16(); + Lag16 = add(PeriodicityIndex, GET_ADJ2(80, 12, 3)); + } + ELSE { + test(); + IF (LT_16(PeriodicityIndex, 224)||SmallerLags!=0) + { + *FractionalResolution = 1; + move16(); + Lag16 = add(PeriodicityIndex, GET_ADJ2(208, 28, 1)); + } + ELSE { + *FractionalResolution = 0; + move16(); + Lag16 = add(PeriodicityIndex, GET_ADJ2(224, 188, 0)); + } + } + *Lag = L_deposit_l(Lag16); + } +} + + +void ConfigureContextHm( + Word16 NumCoeffs, /* (I) Number of coefficients */ + Word16 TargetBits, /* (I) Target bit budget (excl. Done flag) */ + Word16 PeriodicityIndex, /* (I) Pitch related index */ + Word16 LtpPitchLag, /* (I) TCX-LTP pitch in F.D. */ + CONTEXT_HM_CONFIG *hm_cfg /* (O) Context-based harmonic model configuration */ +) +{ + Word8 Bandwidth, SmallerLags; + Word32 i, Limit, Lag; + Word16 j, Index, FractionalResolution; + Word16 *tmp; + + + Bandwidth = 0; + move16(); + if (GE_16(NumCoeffs, 256)) + { + Bandwidth = 1; + move16(); + } + + SmallerLags = 0; + move16(); + test(); + if ((LE_16(TargetBits, kSmallerLagsTargetBitsThreshold))||(Bandwidth==0)) + { + SmallerLags = 1; + move16(); + } + + UnmapIndex(PeriodicityIndex, + Bandwidth, + LtpPitchLag, + SmallerLags, + &FractionalResolution, &Lag); + + /* Set up and fill peakIndices */ + hm_cfg->peakIndices = hm_cfg->indexBuffer; + tmp = hm_cfg->peakIndices; + Limit = L_shl(L_deposit_l(sub(NumCoeffs, 1)), FractionalResolution); + IF (LT_32(Lag, Limit)) + { + FOR (i=Lag; inumPeakIndices = (Word16)(tmp - hm_cfg->indexBuffer); + + /* Set up and fill holeIndices */ + hm_cfg->holeIndices = hm_cfg->indexBuffer + hm_cfg->numPeakIndices; + tmp = hm_cfg->holeIndices; + Index = 0; + move16(); + IF (hm_cfg->numPeakIndices > 0) + { + FOR (j=0; jnumPeakIndices; j+=3) + { + FOR (; IndexpeakIndices[j]; ++Index) + { + *tmp++ = Index; + move16(); + } + Index = add(Index, 3); /* Skip the peak */ + } + } + IF (LT_16(Index, NumCoeffs)) + { + FOR (; IndexnumHoleIndices = (Word16)(tmp - hm_cfg->holeIndices); + *tmp++ = NumCoeffs; + move16(); /* Add extremal element signaling the end of the buffer */ + +} + +Word16 CountIndexBits( + Word16 Bandwidth, + Word16 PeriodicityIndex +) +{ + Word16 result; + Word16 PeriodicityIndexS; + + result = 8; + move16(); + PeriodicityIndexS = shr(PeriodicityIndex, 9); + + if (s_and(PeriodicityIndex, kLtpHmFlag) != 0) + { + result = NumRatioBits[Bandwidth][PeriodicityIndexS]; + move16(); + } + + return result; +} + + + +int tcx_hm_render( + Word32 lag, /* i: pitch lag Q0 */ + Word16 fract_res, /* i: fractional resolution of the lag Q0 */ + Word16 p[] /* o: harmonic model Q13 */ +) +{ + Word16 k, tmp, height; + Word16 PeakDeviation; + Word32 f0, tmp32; + + /* Set up overall shape */ + f0 = L_shl(lag, sub(15, fract_res)); /* Q31 */ + + tmp32 = Mpy_32_16_1(f0, -26474); + tmp32 = L_shr_r(BASOP_Util_InvLog2(L_shl(tmp32, 7)), 2); + tmp32 = L_sub(603979776L, tmp32); + tmp32 = L_add(L_add(tmp32, tmp32), Mpy_32_16_1(tmp32, 26214)); + height = round_fx(tmp32); /* Q13 */ + + tmp32 = Mpy_32_16_1(f0, -18910); + tmp32 = L_shr_r(BASOP_Util_InvLog2(L_shl(tmp32, 7)), 2); + tmp32 = L_sub(1395864371L, tmp32); + PeakDeviation = round_fx(tmp32); /* Q14 */ + + IF( GT_16(13915,PeakDeviation)) + { + /* A bit error was encountered */ + return 1; + } + ELSE + { + tmp = div_s(13915, PeakDeviation); + tmp = mult_r(tmp, tmp); /* Q15 */ + } + + tmp = div_s(13915, PeakDeviation); + tmp = mult_r(tmp, tmp); /* Q15 */ + + /* Render the prototype peak */ + p[kTcxHmParabolaHalfWidth] = height; + move16(); + + FOR (k=1; k<=kTcxHmParabolaHalfWidth; ++k) + { + p[kTcxHmParabolaHalfWidth+k] = round_fx(Mpy_32_16_1(BASOP_Util_InvLog2(L_shl(L_mult0(i_mult2(negate(k),k), tmp),10)), height)); + } + /* Mirror */ + FOR (k=-kTcxHmParabolaHalfWidth; k<0; ++k) + { + p[kTcxHmParabolaHalfWidth+k] = p[kTcxHmParabolaHalfWidth-k]; + move16(); + } + + return 0; +} + +void tcx_hm_modify_envelope( + Word16 gain, /* i: HM gain Q11 */ + Word32 lag, /* i: pitch lag Q0 */ + Word16 fract_res, /* i: fractional resolution of the lag Q0 */ + Word16 p[], /* i: harmonic model Q13 */ + Word32 env[], /* i/o: envelope Q16 */ + Word16 L_frame /* i: number of spectral lines Q0 */ +) +{ + Word16 k, h, x, l1,l2, L_frame_m1, L_frame_for_loop; + Word16 inv_shape[2*kTcxHmParabolaHalfWidth+1]; + + IF ( gain == 0 ) + { + return; + } + + FOR (k=0; k<2*kTcxHmParabolaHalfWidth+1; ++k) + { + /* Q24 = Q11 * Q13; 512 = 1.0 in Q24 format */ + inv_shape[k] = div_s(512, add(512, mult_r(gain, p[k]))); + move16(); + } + + h = 1; + move16(); + k = extract_l(L_shr(lag,fract_res)); + + L_frame_m1 = sub(L_frame,1); + L_frame_for_loop = add(L_frame,kTcxHmParabolaHalfWidth - 1); + + WHILE ( LE_16(k,L_frame_for_loop)) + { + l1 = s_max(0, sub(k,kTcxHmParabolaHalfWidth)); + l2 = s_min(add(k,kTcxHmParabolaHalfWidth), L_frame_m1); + FOR (x=l1; x<=l2; ++x) + { + env[x] = Mpy_32_16_1(env[x], inv_shape[x-k+kTcxHmParabolaHalfWidth]); + move32(); + } + + h = add(h,1); + k = extract_l(L_shr(imult3216(lag,h),fract_res)); + } + +} + + diff --git a/lib_com/arith_coder.c b/lib_com/arith_coder.c index 9ebe095927632ce5e20a48b249ccbe6ebdeb5efe..00ea7af480e798840ee7c3d5a7f7e840c92fd28f 100644 --- a/lib_com/arith_coder.c +++ b/lib_com/arith_coder.c @@ -48,13 +48,13 @@ #define WMC_TOOL_SKIP /*-------------------------------------------------------* - * expfp() + * expfp_evs() * * Fixed point implementation of exp() *-------------------------------------------------------*/ /*! r: Q15 */ -Word16 expfp( +Word16 expfp_evs( const Word16 x, /* i : mantissa Q15-e */ const Word16 x_e /* i : exponent Q0 */ ) @@ -119,7 +119,7 @@ Word16 expfp( /*-------------------------------------------------------* - * powfp_odd2() + * powfp_odd2_evs() * * Fixed point implementation of pow(), where base is fixed point (16/16) and exponent a small *odd* integer *-------------------------------------------------------*/ @@ -128,9 +128,9 @@ Word16 expfp( * Returns: *pout1 = ( (base/65536)^(2*exp - 1) ) * 65536 * *pout2 = ( (base/65536)^(2*exp + 1) ) * 65536 * - * NOTE: This function must be in sync with ari_decode_14bits_pow() */ + * NOTE: This function must be in sync with ari_decode_14bits_pow_ivas() */ -void powfp_odd2( +void powfp_odd2_evs( const Word16 base, /* Q15 */ const Word16 exp, /* Q0 */ Word16 *pout1, /* Q15 */ @@ -202,7 +202,7 @@ void powfp_odd2( /*------------------------------------------------------------------------ - * Function: tcx_arith_scale_envelope + * Function: tcx_arith_scale_envelope_flt * * For optimal performance of the arithmetic coder, the envelope shape must * be scaled such that the expected bit-consumption of a signal that @@ -223,7 +223,7 @@ void powfp_odd2( * and decoder remain synchronized. *-------------------------------------------------------------------------*/ -void tcx_arith_scale_envelope( +void tcx_arith_scale_envelope_flt( const Word16 L_spec_core, /* i : number of lines to scale Q0 */ Word16 L_frame, /* i : number of lines Q0 */ const Word32 env[], /* i : unscaled envelope Q16 */ @@ -506,7 +506,7 @@ void tcx_arith_scale_envelope( /*------------------------------------------------------------------------ - * Function: tcx_arith_render_envelope + * Function: tcx_arith_render_envelope_flt * * Calculate the envelope of the spectrum based on the LPC shape. The * envelope is used in a perceptual domain, whereby the LPC shape has to @@ -518,7 +518,7 @@ void tcx_arith_scale_envelope( * and decoder remain synchronized. *-------------------------------------------------------------------------*/ -void tcx_arith_render_envelope( +void tcx_arith_render_envelope_flt( const Word16 A_ind[], /* i : LPC coefficients of signal envelope */ const Word16 L_frame, /* i : number of spectral lines */ const Word16 L_spec, /* i : length of the coded spectrum */ diff --git a/lib_com/arith_coder_fx.c b/lib_com/arith_coder_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..5fd4b472ea59005fd821661a2d48d5aa0705c583 --- /dev/null +++ b/lib_com/arith_coder_fx.c @@ -0,0 +1,497 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include +#include +#include "options.h" +#include "prot_fx1.h" +#include "prot_fx2.h" +#include "basop_util.h" +#include "cnst.h" + +/* Fixed point implementation of exp(negate()) */ +Word32 expfp( /* o: Q31 */ + const Word16 x, /* i: mantissa Q-e */ + const Word16 x_e) /* i: exponent Q0 */ +{ + Word16 xi, xf, tmp; + Word16 b0, b1, b2, b3; + Word32 y, L_tmp; + + + assert(x > 0); + + L_tmp = L_shl(L_deposit_h(x), x_e); + + /* split into integer and fractional parts */ + xi = round_fx(L_tmp); + xf = extract_l(L_tmp); + + BASOP_SATURATE_WARNING_OFF_EVS; + xf = negate(xf); + BASOP_SATURATE_WARNING_ON_EVS; + + /* Fractional part */ + /* y = 65536 + + xf + + ((xf*xf) / (2*65536)) + + ((((((xf*xf) / (2*65536))*xf) / 65536)*65536/3) / 65536) + + ((((((((xf*xf) / (2*65536))*xf) / 65536)*65536/3) / 65536)*xf) / (4*65536)); */ + y = L_mac0(65536, xf, 1); + tmp = shr(mult(xf, xf), 2); + y = L_mac0(y, tmp, 1); + tmp = shr(mult(shr(mult(tmp, xf), 1), 65536/3), 1); + y = L_mac0(y, tmp, 1); + tmp = shr(mult(tmp, xf), 3); + y = L_mac0(y, tmp, 1); + + /* Integer part */ + b0 = s_and(xi, 1); + b1 = s_and(xi, 2); + b2 = s_and(xi, 4); + b3 = s_and(xi, 8); + + if (b0 != 0) + { + y = Mpy_32_16_1(y, 24109); /* exp(-1) in -1Q16 */ + } + if (b1 != 0) + { + y = Mpy_32_16_1(y, 17739); /* exp(-2) in -2Q17 */ + } + if (b2 != 0) + { + y = Mpy_32_16_1(y, 19205); /* exp(-4) in -5Q20 */ + } + if (b3 != 0) + { + y = Mpy_32_16_1(y, 22513); /* exp(-8) in -11Q26 */ + } + + /* scaling: -1*b0 - 2*b1 -5*b2 -11*b3 */ + y = L_shr(y, add(add(xi, shr(xi, 2)), shr(b3, 3))); + + /* zero for xi >= 16 */ + if (shr(xi, 4) > 0) + { + y = L_deposit_l(0); + } + + + return L_shl(y, 15); +} + +/* Fixed point implementation of pow(), where base is fixed point (16/16) and exponent a small *odd* integer + * + * Returns: *pout1 = ( (base/65536)^(2*exp - 1) ) * 65536 + * *pout2 = ( (base/65536)^(2*exp + 1) ) * 65536 + * + * NOTE: This function must be in sync with ari_decode_14bits_pow() */ +void powfp_odd2( + const Word16 base, /* Q15 */ + const Word16 exp, /* Q0 */ + Word16 *pout1, /* Q15 */ + Word16 *pout2 /* Q15 */ +) +{ + /* this version is in sync with ari_enc_14bits_pow() + * that is, we have to start multiplication from the largest power-of-two, in order to + * get the rounding errors to appear at the same places */ + Word16 pows[12]; /* powers of two exponents*/ + Word16 exp2; + Word16 out, out2; + Word16 k, h, maxk; + + assert(exp >= 0); + + out = base; + move16(); + out2 = 0x7FFF; + move16(); + IF (exp != 0) + { + exp2 = sub(exp, 1); + maxk = sub(15, norm_s(exp)); + assert(maxk < 12); + + pows[0] = base; + move16(); + FOR (k = 0; k < maxk; k++) + { + pows[k+1] = mult_r(pows[k], pows[k]); + move16(); + } + k = sub(k, 1); + h = shl(1, k); /* highest bit of exp2 */ + out2 = base; + move16(); + out = mult_r(out, pows[k+1]); /* we already know that "exp" has the highest bit set to one since we calculated .. */ + /* .. the effective length of "exp" earlier on, thus we omit the branch for out2 */ + if (s_and(exp2, h) != 0) + { + out2 = mult_r(out2, pows[k+1]); + } + + h = shr(h, 1); + FOR (k = sub(k, 1); k >= 0; k--) + { + if (s_and(exp, h) != 0) + { + out = mult_r(out, pows[k+1]); + } + + if (s_and(exp2, h) != 0) + { + out2 = mult_r(out2, pows[k+1]); + } + + h = shr(h, 1); + } + } + + *pout1 = out2; + move16(); + *pout2 = out; + move16(); + +} + +/*------------------------------------------------------------------------ + * Function: tcx_arith_scale_envelope + * + * For optimal performance of the arithmetic coder, the envelope shape must + * be scaled such that the expected bit-consumption of a signal that + * follows the scaled shape coincides with the target bitrate. + * This function calculates a first-guess scaling and then uses the bi-section + * search to find the optimal scaling. + * + * We assume that lines follow the Laplacian distribution, whereby the expected + * bit-consumption would be log2(2*e*s[k]), where s[k] is the envelope value + * for the line in question. However, this theoretical formula assumes that + * all lines are encoded with magnitude+sign. Since the sign is unnecessary + * for 0-values, that estimate of bit-consumption is biased when s[k] is small. + * Analytical solution of the expectation for small s[k] is difficult, whereby + * we use the approximation log2(2*e*s[k] + 0.15 + 0.035 / s[k]) which is accurate + * on the range 0.08 to 1.0. + * + * NOTE: This function must be bit-exact on all platforms such that encoder + * and decoder remain synchronized. + *-------------------------------------------------------------------------*/ +void tcx_arith_scale_envelope( + const Word16 L_spec_core, /* i: number of lines to scale Q0 */ + Word16 L_frame, /* i: number of lines Q0 */ + const Word32 env[], /* i: unscaled envelope Q16 */ + Word16 target_bits, /* i: number of available bits Q0 */ + const Word16 low_complexity,/* i: low-complexity flag Q0 */ + Word16 s_env[], /* o: scaled envelope Q15-e */ + Word16 *s_env_e /* o: scaled envelope exponent Q0 */ +) +{ + Word32 ienv[N_MAX_ARI]; + Word16 scale, iscale, iscale_e, a_e, b, b_e; + Word16 lob, hib, adjust; + Word16 k, iter, max_iter, lob_bits, hib_bits; + Word16 statesi, bits; + Word32 mean, a, s, L_tmp; + Word16 mean_e, tmp, tmp2; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + + + + lob_bits = 0; + move16(); + hib_bits = 0; + move16(); + + /* Boosting to account for expected spectrum truncation (kMax) */ + /* target_bits = (int)(target_bits * (1.2f - 0.00045f * target_bits + 0.00000025f * target_bits * target_bits)); */ + L_tmp = L_shr(Mpy_32_16_1(L_mult0(target_bits, target_bits), 17180), 6); /* Q15; 17180 -> 0.00000025f (Q36) */ + L_tmp = L_sub(L_tmp, L_shr(L_mult0(target_bits, 30199), 11)); /* Q15; 30199 -> 0.00045f (Q26) */ + L_tmp = L_add(L_tmp, 39322); /* Q15; 39322 -> 1.2f (Q15) */ + L_tmp = Mpy_32_16_1(L_tmp, target_bits); /* Q0 */ + assert(L_tmp < 32768); + target_bits = extract_l(L_tmp); + + /* Calculate inverse envelope and find initial scale guess based on mean */ + mean = L_deposit_l(0); + FOR (k = 0; k < L_frame; k++) + { + /* ienv[k] = 1.0f / env[k]; + mean += ienv[k]; */ + + tmp = norm_l(env[k]); + tmp2 = sub(15, tmp); +#ifdef BASOP_NOGLOB + tmp = Inv16(round_fx_o(L_shl_o(env[k], tmp, &Overflow), &Overflow), &tmp2); +#else + tmp = Inv16(round_fx(L_shl(env[k], tmp)), &tmp2); +#endif + ienv[k] = L_shl(L_deposit_h(tmp), sub(tmp2, 15)); /* Q16 */ move32(); + mean = L_add(mean, ienv[k]); + } + tmp = norm_s(L_frame); + tmp = shl(div_s(8192, shl(L_frame, tmp)), sub(tmp, 7)); + mean = L_shr(Mpy_32_16_1(mean, tmp), 6); /* Q16 */ + + /* Rate dependent compensation to get closer to the target on average */ + /* mean = (float)pow(mean, (float)L_frame / (float)target_bits * 0.357f); */ + tmp = BASOP_Util_Divide1616_Scale(L_frame, target_bits, &tmp2); + tmp = mult_r(tmp, 11698/*0.357f Q15*/); + mean = BASOP_Util_fPow(mean, 15, L_deposit_h(tmp), tmp2, &mean_e); + + /* Find first-guess scaling coefficient "scale" such that if "mean" is the + * mean of the envelope, then the mean bit-consumption is approximately + * + * log2(2*e*mean*scale + 0.15 + 0.035/(mean*scale)) * L_frame = target_bits + */ + /* a = 2*2.71828183f*mean*mean; */ + tmp = round_fx(mean); + a = L_mult(mult_r(tmp, 22268/*2.71828183f Q13*/), tmp); + a_e = add(shl(mean_e, 1), 3); + + /* b = (0.15f - (float)pow(2.0f, target_bits/(float)L_frame)) * mean; */ + tmp = BASOP_Util_Divide1616_Scale(target_bits, L_frame, &tmp2); + tmp = round_fx(BASOP_util_Pow2(L_deposit_h(tmp), tmp2, &tmp2)); + b_e = BASOP_Util_Add_MantExp(4915/*0.15f Q15*/, 0, negate(tmp), tmp2, &b); + b = mult_r(b, round_fx(mean)); + b_e = add(b_e, mean_e); + + /* scale = (-b + (float)sqrt(b*b - 4.0f*a*0.035f)) / (2.0f * a); */ + tmp = round_fx(BASOP_Util_Add_Mant32Exp(L_mult(b, b), shl(b_e, 1), Mpy_32_16_1(a, -4588/*-4.0f*0.035f Q15*/), a_e, &tmp2)); + + IF( tmp <= 0 ) + { + tmp = 0; + set16_fx(s_env, 0, L_frame); + } + ELSE + { + tmp = Sqrt16(tmp, &tmp2); + } + + tmp2 = BASOP_Util_Add_MantExp(negate(b), b_e, tmp, tmp2, &scale); + scale = BASOP_Util_Divide1616_Scale(scale, round_fx(a), &tmp); + scale = shl(scale, sub(sub(add(tmp, tmp2), a_e), 1)); /* Q15 */ + + /* iscale = 1.0f / scale; */ + iscale_e = 0; + move16(); + iscale = Inv16(s_max(1, scale), &iscale_e); + + lob = 0; + move16(); + hib = 0; + move16(); + + max_iter = 2; + move16(); + if(low_complexity) + { + max_iter = 1; + move16(); + } + + FOR (iter = 0; iter < max_iter; iter++) + { + statesi = 0x7FFF; + move16(); + bits = 0; + move16(); + + FOR (k = 0; k < L_frame; k++) + { + s = Mpy_32_16_1(ienv[k], scale); /* Q16 */ + + IF (LE_32(s, 5243l/*0.08f Q16*/)) + { + /* If s = 0.08, the expected bit-consumption is log2(1.0224). Below 0.08, the bit-consumption + estimate function becomes inaccurate, so use log2(1.0224) for all values below 0.08. */ + /* round(state * 1.0224 * 32768) */ + statesi = mult_r(statesi, 16751/*1.0224 Q14*/); + tmp = norm_s(statesi); + statesi = shl(statesi, tmp); + bits = add(bits, sub(1, tmp)); + } + ELSE IF (LE_32(s, 16711680l/*255.0 Q16*/)) + { + /* a = 5.436564f * s + 0.15f + 0.035f * env[k] * iscale; */ + L_tmp = L_shl(Mpy_32_16_1(s, 22268/*5.436564f Q12*/), 3); + L_tmp = L_add(L_tmp, 9830l/*0.15f Q16*/); + L_tmp = L_add(L_tmp, L_shl(Mpy_32_16_1(env[k], mult_r(1147/*0.035f Q15*/, iscale)), iscale_e)); + + tmp = norm_l(L_tmp); +#ifdef BASOP_NOGLOB + statesi = mult_r(statesi, round_fx_o(L_shl_o(L_tmp, tmp, &Overflow), &Overflow)); +#else + statesi = mult_r(statesi, round_fx(L_shl(L_tmp, tmp))); +#endif + bits = add(bits, sub(15, tmp)); + + tmp = norm_s(statesi); + statesi = shl(statesi, tmp); + bits = sub(bits, tmp); + } + ELSE + { + /* for large envelope values, s > 255, bit consumption is approx log2(2*e*s) + * further, we use round(log2(x)) = floor(log2(x)+0.5) = floor(log2(x*sqrt(2))) */ + /* a = 5.436564f * s; */ + L_tmp = Mpy_32_16_1(s, 31492/*5.436564f * 1.4142f Q12*/); /* Q13 */ + bits = add(bits, sub(17, norm_l(L_tmp))); + } + } + + IF (LE_16(bits, target_bits)) /* Bits leftover => scale is too small */ + { + lob = scale; + move16(); + lob_bits = bits; + move16(); + + IF (hib > 0) /* Bisection search */ + { + adjust = div_s(sub(hib_bits, target_bits), sub(hib_bits, lob_bits)); + scale = add(mult_r(sub(lob, hib), adjust), hib); + } + ELSE /* Initial scale adaptation */ + { + /* adjust = 1.05f * target_bits / (float)bits; + scale *= adjust; */ + adjust = mult_r(17203/*1.05f Q14*/, target_bits); + adjust = BASOP_Util_Divide1616_Scale(adjust, bits, &tmp); + scale = shl(mult_r(scale, adjust), add(1, tmp)); + } + } + ELSE /* Ran out of bits => scale is too large */ + { + hib = scale; + move16(); + hib_bits = bits; + move16(); + + IF (lob > 0) /* Bisection search */ + { + adjust = div_s(sub(hib_bits, target_bits), sub(hib_bits, lob_bits)); + scale = add(mult_r(sub(lob, hib), adjust), hib); + } + ELSE { /* Initial scale adaptation */ + test(); + IF( target_bits <= 0 || bits <= 0 ) /* safety check in case of bit errors */ + { + adjust = 0; + move16(); + set16_fx( s_env, 0, L_frame ); + } + ELSE + { + adjust = div_s(mult_r(31130/*0.95f Q15*/, target_bits), bits); + } + scale = mult_r(scale, adjust); + } + } + iscale_e = 0; + move16(); + + IF( scale == 0 ) /* safety check in case of bit errors */ + { + iscale = 0; + move16(); + set16_fx( s_env, 0, L_frame ); + } + ELSE + { + iscale = Inv16(scale, &iscale_e); + } + } + L_frame = L_spec_core; + move16(); + + tmp = getScaleFactor32(env, L_frame); + *s_env_e = sub(add(15, iscale_e), tmp); + move16(); + BASOP_SATURATE_WARNING_OFF_EVS; +#ifdef BASOP_NOGLOB + a = L_shl_o(1265000, sub(15, *s_env_e), &Overflow); +#else /* BASOP_NOGLOB */ + a = L_shl(1265000, sub(15, *s_env_e)); +#endif + BASOP_SATURATE_WARNING_ON_EVS; + + FOR (k = 0; k < L_frame; k++) + { + L_tmp = Mpy_32_16_1(L_shl(env[k], tmp), iscale); + L_tmp = L_min(L_tmp, a); + s_env[k] = round_fx(L_tmp); + } + +} + +/*------------------------------------------------------------------------ + * Function: tcx_arith_render_envelope + * + * Calculate the envelope of the spectrum based on the LPC shape. The + * envelope is used in a perceptual domain, whereby the LPC shape has to + * be multiplied by the perceptual model. + * Operations that are performed on the spectrum, which change the magnitude + * expectation of lines, such as low-frequency emphasis, are included in the + * envelope shape. + * NOTE: This function must be bit-exact on all platforms such that encoder + * and decoder remain synchronized. + *-------------------------------------------------------------------------*/ +void tcx_arith_render_envelope( + const Word16 A_ind[], /* i: LPC coefficients of signal envelope */ + const Word16 L_frame, /* i: number of spectral lines */ + const Word16 L_spec, + const Word16 preemph_fac, /* i: pre-emphasis factor */ + const Word16 gamma_w, /* i: A_ind -> weighted envelope factor */ + const Word16 gamma_uw, /* i: A_ind -> non-weighted envelope factor */ + Word32 env[] /* o: shaped signal envelope */ +) +{ + Word16 k; + Word16 tmpA[M+2]; + Word16 signal_env[FDNS_NPTS], signal_env_e[FDNS_NPTS]; + Word16 gainlpc[FDNS_NPTS], gainlpc_e[FDNS_NPTS]; + + + + /* Compute perceptual LPC envelope, transform it into freq.-domain gains */ + weight_a_fx( A_ind, tmpA, gamma_w, M ); + lpc2mdct( tmpA, M, NULL, NULL, gainlpc, gainlpc_e, FDNS_NPTS, 0); + + /* Add pre-emphasis tilt to LPC envelope, transform LPC into MDCT gains */ + E_LPC_a_weight_inv(A_ind, signal_env, gamma_uw, M); + E_LPC_a_add_tilt(signal_env, tmpA, preemph_fac, M); + lpc2mdct(tmpA, M+1, signal_env, signal_env_e, NULL, NULL, FDNS_NPTS, 0); + + /* Compute weighted signal envelope in perceptual domain */ + FOR (k = 0; k < FDNS_NPTS; k++) + { + signal_env[k] = mult_r(signal_env[k], gainlpc[k]); + move16(); + signal_env_e[k] = add(signal_env_e[k], gainlpc_e[k]); + move16(); + } + + /* Adaptive low frequency emphasis */ + set32_fx(env, 0x10000, L_frame); + + AdaptLowFreqDeemph(env, 15, + 1, + gainlpc, gainlpc_e, + L_frame, NULL); + + /* Scale from FDNS_NPTS to L_frame and multiply LFE gains */ + mdct_noiseShaping_interp(env, L_frame, signal_env, signal_env_e); + + FOR (k=L_frame; k= 0 ); - if ( x == 0 ) - { - return ( (Word32) MIN_32 ); - } - /* normalize input, calculate integer part */ - exp_e = norm_l( x ); - x = L_shl( x, exp_e ); - exp = L_deposit_l( exp_e ); + assert(x >= 0); + + if (x == 0) + { - /* calculate (1-normalized_input) */ - nIn = extract_h( L_sub( MAX_32, x ) ); + return ((Word32)MIN_32); + } - /* approximate ln() for fractional part (nIn *c0 + nIn^2*c1 + nIn^3*c2 + ... + nIn^8 *c7) */ + /* normalize input, calculate integer part */ + exp_e = norm_l(x); + x = L_shl(x, exp_e); + exp = L_deposit_l(exp_e); - /* iteration 1, no need for accumulation */ - accuRes = L_mult( nIn, ldCoeff[0] ); /* nIn^i * coeff[0] */ - accuSqr = mult( nIn, nIn ); /* nIn^2, nIn^3 .... */ + /* calculate (1-normalized_input) */ + nIn = extract_h(L_sub(MAX_32, x)); - /* iteration 2 */ - accuRes = L_mac( accuRes, accuSqr, ldCoeff[1] ); /* nIn^i * coeff[1] */ - accuSqr = mult( accuSqr, nIn ); /* nIn^2, nIn^3 .... */ + /* approximate ln() for fractional part (nIn *c0 + nIn^2*c1 + nIn^3*c2 + ... + nIn^8 *c7) */ - /* iteration 3 */ - accuRes = L_mac( accuRes, accuSqr, ldCoeff[2] ); /* nIn^i * coeff[2] */ - accuSqr = mult( accuSqr, nIn ); /* nIn^2, nIn^3 .... */ + /* iteration 1, no need for accumulation */ + accuRes = L_mult(nIn, ldCoeff[0]); /* nIn^i * coeff[0] */ + accuSqr = mult(nIn, nIn); /* nIn^2, nIn^3 .... */ - /* iteration 4 */ - accuRes = L_mac( accuRes, accuSqr, ldCoeff[3] ); /* nIn^i * coeff[3] */ - accuSqr = mult( accuSqr, nIn ); /* nIn^2, nIn^3 .... */ + /* iteration 2 */ + accuRes = L_mac(accuRes, accuSqr, ldCoeff[1]); /* nIn^i * coeff[1] */ + accuSqr = mult(accuSqr, nIn); /* nIn^2, nIn^3 .... */ - /* iteration 5 */ - accuRes = L_mac( accuRes, accuSqr, ldCoeff[4] ); /* nIn^i * coeff[4] */ - accuSqr = mult( accuSqr, nIn ); /* nIn^2, nIn^3 .... */ + /* iteration 3 */ + accuRes = L_mac(accuRes, accuSqr, ldCoeff[2]); /* nIn^i * coeff[2] */ + accuSqr = mult(accuSqr, nIn); /* nIn^2, nIn^3 .... */ - /* iteration 6 */ - accuRes = L_mac( accuRes, accuSqr, ldCoeff[5] ); /* nIn^i * coeff[5] */ - accuSqr = mult( accuSqr, nIn ); /* nIn^2, nIn^3 .... */ + /* iteration 4 */ + accuRes = L_mac(accuRes, accuSqr, ldCoeff[3]); /* nIn^i * coeff[3] */ + accuSqr = mult(accuSqr, nIn); /* nIn^2, nIn^3 .... */ - /* iteration 7, no need to calculate accuSqr any more */ - accuRes = L_mac( accuRes, accuSqr, ldCoeff[6] ); /* nIn^i * coeff[6] */ + /* iteration 5 */ + accuRes = L_mac(accuRes, accuSqr, ldCoeff[4]); /* nIn^i * coeff[4] */ + accuSqr = mult(accuSqr, nIn); /* nIn^2, nIn^3 .... */ - /* ld(fractional part) = ln(fractional part)/ln(2), 1/ln(2) = (1 + 0.44269504) */ - accuRes = L_mac0( L_shr( accuRes, 1 ), extract_h( accuRes ), 14506 ); + /* iteration 6 */ + accuRes = L_mac(accuRes, accuSqr, ldCoeff[5]); /* nIn^i * coeff[5] */ + accuSqr = mult(accuSqr, nIn); /* nIn^2, nIn^3 .... */ - accuRes = L_shr( accuRes, LD_DATA_SCALE - 1 ); /* fractional part/LD_DATA_SCALE */ - exp = L_shl( exp, ( 31 - LD_DATA_SCALE ) ); /* integer part/LD_DATA_SCALE */ - accuRes = L_sub( accuRes, exp ); /* result = integer part + fractional part */ + /* iteration 7, no need to calculate accuSqr any more */ + accuRes = L_mac(accuRes, accuSqr, ldCoeff[6]); /* nIn^i * coeff[6] */ - return ( accuRes ); -} + /* ld(fractional part) = ln(fractional part)/ln(2), 1/ln(2) = (1 + 0.44269504) */ + accuRes = L_mac0(L_shr(accuRes, 1), extract_h(accuRes), 14506); + accuRes = L_shr(accuRes, LD_DATA_SCALE - 1); /* fractional part/LD_DATA_SCALE */ + exp = L_shl(exp, (31 - LD_DATA_SCALE)); /* integer part/LD_DATA_SCALE */ + accuRes = L_sub(accuRes, exp); /* result = integer part + fractional part */ -Word32 BASOP_Util_InvLog2( - Word32 x ) + + return (accuRes); +} + +Word32 BASOP_Util_InvLog2(Word32 x) { - Word16 frac; - Word16 exp; - Word32 retVal; - UWord32 index3; - UWord32 index2; - UWord32 index1; - UWord32 lookup3f; - UWord32 lookup12; - UWord32 lookup; + Word16 frac; + Word16 exp; + Word32 retVal; + UWord32 index3; + UWord32 index2; + UWord32 index1; + UWord32 lookup3f; + UWord32 lookup12; + UWord32 lookup; - if ( x < FL2WORD32( -31.0 / 64.0 ) ) - { - return 0; - } - test(); - if ( ( L_sub( x, FL2WORD32( 31.0 / 64.0 ) ) >= 0 ) || ( x == 0 ) ) - { - return 0x7FFFFFFF; - } - frac = extract_l( L_and( x, 0x3FF ) ); - index3 = L_and( L_shr( x, 10 ), 0x1F ); - index2 = L_and( L_shr( x, 15 ), 0x1F ); - index1 = L_and( L_shr( x, 20 ), 0x1F ); + if (x < -1040187392l/*-31.0/64.0 Q31*/) + { - exp = extract_l( L_shr( x, 25 ) ); - if ( x > 0 ) - { - exp = sub( 31, exp ); - } - if ( x < 0 ) - { - exp = negate( exp ); - } + return 0; + } + test(); + if ((GE_32(x, 1040187392l/*31.0/64.0 Q31*/)) || (x == 0)) + { - lookup3f = L_add( exp2x_tab_long[index3], L_shr( Mpy_32_16_1( 0x0016302F, frac ), 1 ) ); - lookup12 = Mpy_32_32( exp2_tab_long[index1], exp2w_tab_long[index2] ); - lookup = Mpy_32_32( lookup12, lookup3f ); + return 0x7FFFFFFF; + } - retVal = L_shr( lookup, sub( exp, 3 ) ); + frac = extract_l(L_and(x, 0x3FF)); - return retVal; + index3 = L_and(L_shr(x, 10), 0x1F); + index2 = L_and(L_shr(x, 15), 0x1F); + index1 = L_and(L_shr(x, 20), 0x1F); + + exp = extract_l(L_shr(x, 25)); + if (x > 0) + { + exp = sub(31, exp); + } + if (x < 0) + { + exp = negate(exp); + } + + lookup3f = L_add(exp2x_tab_long[index3], L_shr(Mpy_32_16_1(0x0016302F, frac), 1)); + lookup12 = Mpy_32_32(exp2_tab_long[index1], exp2w_tab_long[index2]); + lookup = Mpy_32_32(lookup12, lookup3f); + + retVal = L_shr(lookup, sub(exp, 3)); + + + return retVal; } -Word16 BASOP_Util_Add_MantExp /*!< Exponent of result */ - ( Word16 a_m, /*!< Mantissa of 1st operand a */ - Word16 a_e, /*!< Exponent of 1st operand a */ - Word16 b_m, /*!< Mantissa of 2nd operand b */ - Word16 b_e, /*!< Exponent of 2nd operand b */ - Word16 *ptrSum_m ) /*!< Mantissa of result */ +Word16 BASOP_Util_Add_MantExp /*!< Exponent of result */ +(Word16 a_m, /*!< Mantissa of 1st operand a */ + Word16 a_e, /*!< Exponent of 1st operand a */ + Word16 b_m, /*!< Mantissa of 2nd operand b */ + Word16 b_e, /*!< Exponent of 2nd operand b */ + Word16 *ptrSum_m) /*!< Mantissa of result */ { - Word32 L_lm, L_hm; - Word16 shift; + Word32 L_lm, L_hm; + Word16 shift; - /* Compare exponents: the difference is limited to +/- 15 - The Word16 mantissa of the operand with higher exponent is moved into the low - part of a Word32 and shifted left by the exponent difference. Then, the - unshifted mantissa of the operand with the lower exponent is added to the lower - 16 bits. The addition result is normalized and the upper Word16 of the result represents - the mantissa to return. The returned exponent takes into account all shift operations - including the final 16-bit extraction. - Note: The resulting mantissa may be inaccurate in the case, where the mantissa of the operand - with higher exponent is not really left-aligned, while the mantissa of the operand with - lower exponent is so. If in such a case, the difference in exponents is more than 15, - an inaccuracy is introduced. - Example: - A: a_e = 20, a_m = 0x0001 - B: b_e = 0, b_m = 0x4000 - correct: A+B=1*2^20+1*2^14=0x0010.0000+0x0000.4000=0x0010.4000=0x4100*2^6 - previously: A+B=1*2^20+1*2^14=0x0001+0x0000=0x0001*2^20 - this version: A+B=1*2^20+1*2^14=0x0000.8000+0x0000.4000=0x6000*2^6 - */ - shift = sub( a_e, b_e ); - if ( shift >= 0 ) - shift = s_min( 15, shift ); - if ( shift < 0 ) - shift = s_max( -15, shift ); - a_e = s_max( a_e, b_e ); - L_hm = L_deposit_l( a_m ); /* mantissa belonging to higher exponent */ - L_lm = L_deposit_l( a_m ); /* mantissa belonging to lower exponent */ - if ( shift >= 0 ) - L_lm = L_deposit_l( b_m ); - if ( shift < 0 ) - L_hm = L_deposit_l( b_m ); - - if ( shift > 0 ) - shift = negate( shift ); - - L_hm = L_shr( L_hm, shift ); /* shift left due to negative shift parameter */ - a_e = add( a_e, shift ); - L_hm = L_add( L_hm, L_lm ); - shift = norm_l( L_hm ); - L_hm = L_shl( L_hm, shift ); - *ptrSum_m = extract_h( L_hm ); - move16(); + /* Compare exponents: the difference is limited to +/- 15 + The Word16 mantissa of the operand with higher exponent is moved into the low + part of a Word32 and shifted left by the exponent difference. Then, the + unshifted mantissa of the operand with the lower exponent is added to the lower + 16 bits. The addition result is normalized and the upper Word16 of the result represents + the mantissa to return. The returned exponent takes into account all shift operations + including the final 16-bit extraction. + Note: The resulting mantissa may be inaccurate in the case, where the mantissa of the operand + with higher exponent is not really left-aligned, while the mantissa of the operand with + lower exponent is so. If in such a case, the difference in exponents is more than 15, + an inaccuracy is introduced. + Example: + A: a_e = 20, a_m = 0x0001 + B: b_e = 0, b_m = 0x4000 + correct: A+B=1*2^20+1*2^14=0x0010.0000+0x0000.4000=0x0010.4000=0x4100*2^6 + previously: A+B=1*2^20+1*2^14=0x0001+0x0000=0x0001*2^20 + this version: A+B=1*2^20+1*2^14=0x0000.8000+0x0000.4000=0x6000*2^6 + */ - a_e = sub( a_e, shift ); - if ( L_hm ) - a_e = add( a_e, 16 ); + shift = sub(a_e, b_e); + if (shift >= 0) + shift = s_min(15, shift); + + if (shift < 0) + shift = s_max(-15, shift); + a_e = s_max(a_e, b_e); + L_hm = L_deposit_l(a_m); /* mantissa belonging to higher exponent */ + L_lm = L_deposit_l(a_m); /* mantissa belonging to lower exponent */ + if (shift >= 0) + L_lm = L_deposit_l(b_m); + if (shift < 0) + L_hm = L_deposit_l(b_m); + + if (shift > 0) + shift = negate(shift); + + L_hm = L_shr(L_hm, shift); /* shift left due to negative shift parameter */ + a_e = add(a_e, shift); + L_hm = L_add(L_hm, L_lm); + shift = norm_l(L_hm); + L_hm = L_shl(L_hm, shift); + *ptrSum_m = extract_h(L_hm); + move16(); - return ( a_e ); + a_e = sub(a_e, shift); + if (L_hm) + a_e = add(a_e, 16); + return (a_e); } @@ -297,43 +305,43 @@ void BASOP_Util_Divide_MantExp(Word16 a_m, /*!< Mantissa of dividend /* local function for Sqrt16 */ -static Word16 Sqrt16_common( - Word16 m, - Word16 e ) +static Word16 Sqrt16_common(Word16 m, + Word16 e) { - Word16 index, frac; + Word16 index, frac; #ifdef BASOP_NOGLOB - Flag Overflow; -#endif /* BASOP_NOGLOB */ + Flag Overflow; +#endif - assert( ( m >= 0x4000 ) || ( m == 0 ) ); - /* get table index (upper 6 bits minus 32) */ - /* index = (m >> 9) - 32; */ - index = mac_r( -32768 - ( 32 << 16 ), m, 1 << 6 ); + assert((m >= 0x4000) || (m == 0)); - /* get fractional part for interpolation (lower 9 bits) */ - frac = s_and( m, 0x1FF ); /* Q9 */ + /* get table index (upper 6 bits minus 32) */ + /* index = (m >> 9) - 32; */ + index = mac_r(-32768 - (32 << 16), m, 1 << 6); - /* interpolate */ - if ( m != 0 ) - { - BASOP_SATURATE_WARNING_OFF; -#ifndef BASOP_NOGLOB - m = mac_r( SqrtTable[index], SqrtDiffTable[index], frac ); -#else /* BASOP_NOGLOB */ - m = mac_ro( SqrtTable[index], SqrtDiffTable[index], frac, &Overflow ); -#endif /* BASOP_NOGLOB */ - BASOP_SATURATE_WARNING_ON; - } + /* get fractional part for interpolation (lower 9 bits) */ + frac = s_and(m, 0x1FF); /* Q9 */ - /* handle odd exponents */ - if ( s_and( e, 1 ) != 0 ) - m = mult_r( m, 0x5a82 ); + /* interpolate */ + if (m != 0) + { + BASOP_SATURATE_WARNING_OFF_EVS; +#ifdef BASOP_NOGLOB + m = mac_ro(SqrtTable[index], SqrtDiffTable[index], frac, &Overflow); +#else + m = mac_r(SqrtTable[index], SqrtDiffTable[index], frac); +#endif + BASOP_SATURATE_WARNING_ON_EVS; + } + + /* handle odd exponents */ + if (s_and(e, 1) != 0) m = mult_r(m, 0x5a82); - return m; + return m; } + /* local function for Sqrt32 and Sqrt32norm */ static Word32 Sqrt32_common(Word32 m, Word16 e) @@ -430,31 +438,32 @@ static Word32 ISqrt32_common(Word32 m, } Word16 Sqrt16( /*!< output mantissa */ - Word16 mantissa, /*!< input mantissa */ - Word16 *exponent /*!< pointer to exponent */ + Word16 mantissa, /*!< input mantissa */ + Word16 *exponent /*!< pointer to exponent */ ) { - Word16 preShift, e; + Word16 preShift, e; - assert( mantissa >= 0 ); + assert(mantissa >= 0); - /* normalize */ - preShift = norm_s( mantissa ); + /* normalize */ + preShift = norm_s(mantissa); - e = sub( *exponent, preShift ); - mantissa = shl( mantissa, preShift ); + e = sub(*exponent, preShift); + mantissa = shl(mantissa, preShift); - /* calc mantissa */ - mantissa = Sqrt16_common( mantissa, e ); + /* calc mantissa */ + mantissa = Sqrt16_common(mantissa, e); - /* e = (e + 1) >> 1 */ - *exponent = mult_r( e, 1 << 14 ); - move16(); + /* e = (e + 1) >> 1 */ + *exponent = mult_r(e, 1 << 14); + move16(); - return mantissa; + return mantissa; } + Word16 Sqrt16norm( /*!< output mantissa */ Word16 mantissa, /*!< normalized input mantissa */ Word16 *exponent /*!< pointer to exponent */ @@ -474,6 +483,7 @@ Word16 Sqrt16norm( /*!< output mantissa */ } + Word16 ISqrt16( /*!< output mantissa */ Word16 mantissa, /*!< input mantissa */ Word16 *exponent /*!< pointer to exponent */ @@ -499,7 +509,6 @@ Word16 ISqrt16( /*!< output mantissa */ return mantissa; } - Word32 Sqrt32( /*!< output mantissa */ Word32 mantissa, /*!< input mantissa */ Word16 *exponent /*!< pointer to exponent */ @@ -570,105 +579,107 @@ Word32 ISqrt32norm( /*!< output mantissa */ } Word16 Inv16( /*!< output mantissa */ - Word16 mantissa, /*!< input mantissa */ - Word16 *exponent /*!< pointer to exponent */ + Word16 mantissa, /*!< input mantissa */ + Word16 *exponent /*!< pointer to exponent */ ) { - Word16 index, frac; - Word16 preShift; - Word16 m, e; + Word16 index, frac; + Word16 preShift; + Word16 m, e; - assert( mantissa != 0 ); - /* absolute */ - BASOP_SATURATE_WARNING_OFF; - m = abs_s( mantissa ); - BASOP_SATURATE_WARNING_ON; - /* normalize */ - preShift = norm_s( m ); + assert(mantissa != 0); - e = sub( *exponent, preShift ); - m = shl( m, preShift ); + /* absolute */ + BASOP_SATURATE_WARNING_OFF_EVS; + m = abs_s(mantissa); + BASOP_SATURATE_WARNING_ON_EVS; - /* get table index (upper 6 bits minus 32) */ - /* index = (m >> 9) - 32; */ - index = mac_r( -32768 - ( 32 << 16 ), m, 1 << 6 ); + /* normalize */ + preShift = norm_s(m); - /* get fractional part for interpolation (lower 9 bits) */ - frac = shl( s_and( m, 0x1FF ), 1 ); /* Q10 */ + e = sub(*exponent, preShift); + m = shl(m, preShift); - /* interpolate */ - m = msu_r( InvTable[index], InvDiffTable[index], frac ); + /* get table index (upper 6 bits minus 32) */ + /* index = (m >> 9) - 32; */ + index = mac_r(-32768 - (32 << 16), m, 1 << 6); - /* restore sign */ - if ( mantissa < 0 ) - m = negate( m ); + /* get fractional part for interpolation (lower 9 bits) */ + frac = shl(s_and(m, 0x1FF), 1); /* Q10 */ - /* e = 1 - e */ - *exponent = sub( 1, e ); - move16(); + /* interpolate */ + m = msu_r(InvTable[index], InvDiffTable[index], frac); + + /* restore sign */ + if (mantissa < 0) m = negate(m); + + /* e = 1 - e */ + *exponent = sub(1, e); + move16(); - return m; + return m; } -void BASOP_Util_Sqrt_InvSqrt_MantExp( - Word16 mantissa, /*!< mantissa */ - Word16 exponent, /*!< expoinent */ - Word16 *sqrt_mant, /*!< Pointer to sqrt mantissa */ - Word16 *sqrt_exp, /*!< Pointer to sqrt exponent */ - Word16 *isqrt_mant, /*!< Pointer to 1/sqrt mantissa */ - Word16 *isqrt_exp /*!< Pointer to 1/sqrt exponent */ +void BASOP_Util_Sqrt_InvSqrt_MantExp(Word16 mantissa, /*!< mantissa */ + Word16 exponent, /*!< expoinent */ + Word16 *sqrt_mant, /*!< Pointer to sqrt mantissa */ + Word16 *sqrt_exp, /*!< Pointer to sqrt exponent */ + Word16 *isqrt_mant, /*!< Pointer to 1/sqrt mantissa */ + Word16 *isqrt_exp /*!< Pointer to 1/sqrt exponent */ ) { - Word16 index, frac; - Word16 preShift; - Word16 m, mi, e_odd; + Word16 index, frac; + Word16 preShift; + Word16 m, mi, e_odd; + + + + assert(mantissa > 0); - assert( mantissa > 0 ); + /* normalize */ + preShift = norm_s(mantissa); - /* normalize */ - preShift = norm_s( mantissa ); + exponent = sub(exponent, preShift); + mantissa = shl(mantissa, preShift); - exponent = sub( exponent, preShift ); - mantissa = shl( mantissa, preShift ); + /* get table index (upper 6 bits minus 32) */ + /* index = (m >> 9) - 32; */ + index = mac_r(-32768 - (32 << 16), mantissa, 1 << 6); - /* get table index (upper 6 bits minus 32) */ - /* index = (m >> 9) - 32; */ - index = mac_r( -32768 - ( 32 << 16 ), mantissa, 1 << 6 ); + /* get fractional part for interpolation (lower 9 bits) */ + frac = s_and(mantissa, 0x1FF); /* Q9 */ - /* get fractional part for interpolation (lower 9 bits) */ - frac = s_and( mantissa, 0x1FF ); /* Q9 */ + /* interpolate */ + BASOP_SATURATE_WARNING_OFF_EVS; + m = mac_r(SqrtTable[index], SqrtDiffTable[index], frac); + mi = msu_r(ISqrtTable[index], ISqrtDiffTable[index], frac); + BASOP_SATURATE_WARNING_ON_EVS; - /* interpolate */ - BASOP_SATURATE_WARNING_OFF; - m = mac_r( SqrtTable[index], SqrtDiffTable[index], frac ); - mi = msu_r( ISqrtTable[index], ISqrtDiffTable[index], frac ); - BASOP_SATURATE_WARNING_ON; + /* handle even/odd exponents */ + e_odd = s_and(exponent, 1); + if (e_odd != 0) m = mult_r(m, 0x5a82); + if (e_odd == 0) mi = mult_r(mi, 0x5a82); - /* handle even/odd exponents */ - e_odd = s_and( exponent, 1 ); - if ( e_odd != 0 ) - m = mult_r( m, 0x5a82 ); - if ( e_odd == 0 ) - mi = mult_r( mi, 0x5a82 ); + /* e = (e + 1) >> 1 */ + *sqrt_exp = mult_r(exponent, 1 << 14); + move16(); - /* e = (e + 1) >> 1 */ - *sqrt_exp = mult_r( exponent, 1 << 14 ); - move16(); + /* e = (2 - e) >> 1 */ + *isqrt_exp = msu_r(1L << 15, exponent, 1 << 14); + move16(); - /* e = (2 - e) >> 1 */ - *isqrt_exp = msu_r( 1L << 15, exponent, 1 << 14 ); - move16(); + /* Write result */ + *sqrt_mant = m; + move16(); + *isqrt_mant = mi; + move16(); - /* Write result */ - *sqrt_mant = m; - move16(); - *isqrt_mant = mi; - move16(); } + /********************************************************************/ /*! \brief Calculates the scalefactor needed to normalize input array @@ -728,38 +739,40 @@ Word16 getScaleFactor16( /* o: measured headroom in range [0..15 and -2147483648 <= x <= -1073741824 for negative x */ -/*! r: measured headroom in range [0..31], 0 if all x[i] == 0 */ -Word16 getScaleFactor32( - const Word32 *x, /* i : array containing 32-bit data */ - const Word16 len_x ) /* i : length of the array to scan */ +Word16 getScaleFactor32( /* o: measured headroom in range [0..31], 0 if all x[i] == 0 */ + const Word32 *x, /* i: array containing 32-bit data */ + const Word16 len_x) /* i: length of the array to scan */ { - Word16 i, i_min, i_max; - Word32 x_min, x_max; + Word16 i, i_min, i_max; + Word32 x_min, x_max; - x_max = L_add( 0, 0 ); - x_min = L_add( 0, 0 ); - FOR( i = 0; i < len_x; i++ ) - { - if ( x[i] >= 0 ) - x_max = L_max( x_max, x[i] ); - if ( x[i] < 0 ) - x_min = L_min( x_min, x[i] ); - } - i_max = 0x20; - move16(); - i_min = 0x20; - move16(); - if ( x_max != 0 ) - i_max = norm_l( x_max ); + x_max = 0; move32(); + x_min = 0; move32(); + FOR(i = 0; i < len_x; i++) + { + if (x[i] >= 0) + x_max = L_max(x_max, x[i]); + if (x[i] < 0) + x_min = L_min(x_min, x[i]); + } + + i_max = 0x20; + move16(); + i_min = 0x20; + move16(); + + if (x_max != 0) + i_max = norm_l(x_max); + + if (x_min != 0) + i_min = norm_l(x_min); - if ( x_min != 0 ) - i_min = norm_l( x_min ); + i = s_and(s_min(i_max, i_min), 0x1F); - i = s_and( s_min( i_max, i_min ), 0x1F ); - return i; + return i; } Word16 normalize16(Word16 mantissa, Word16 *pexponent) @@ -933,61 +946,63 @@ Word16 BASOP_Util_Divide3232_Scale(Word32 x, Word32 y, Word16 *s) return (z); } -Word16 BASOP_Util_Divide1616_Scale( - Word16 x, - Word16 y, - Word16 *s ) + +Word16 BASOP_Util_Divide1616_Scale(Word16 x, Word16 y, Word16 *s) { - Word16 z; - Word16 sx; - Word16 sy; - Word16 sign; + Word16 z; + Word16 sx; + Word16 sy; + Word16 sign; - /* assert (x >= (Word16)0); */ - assert( y != (Word16) 0 ); - sign = 0; - move16(); - IF( x < 0 ) - { - x = negate( x ); - sign = s_xor( sign, 1 ); - } + /* assert (x >= (Word16)0); */ + assert(y != (Word16)0); - IF( y < 0 ) - { - y = negate( y ); - sign = s_xor( sign, 1 ); - } + sign = 0; + move16(); - IF( x == (Word16) 0 ) - { - move16(); - *s = 0; + IF(x < 0) + { + x = negate(x); + sign = s_xor(sign, 1); + } - return ( (Word16) 0 ); - } + IF(y < 0) + { + y = negate(y); + sign = s_xor(sign, 1); + } - sx = norm_s( x ); - x = shl( x, sx ); - x = shr( x, 1 ); + IF(x == (Word16)0) + { move16(); - *s = sub( 1, sx ); + *s = 0; - sy = norm_s( y ); - y = shl( y, sy ); - move16(); - *s = add( *s, sy ); - z = div_s( x, y ); + return ((Word16)0); + } - if ( sign != 0 ) - { - z = negate( z ); - } + sx = norm_s(x); + x = shl(x, sx); + x = shr(x, 1); + move16(); + *s = sub(1, sx); - return z; + sy = norm_s(y); + y = shl(y, sy); + move16(); + *s = add(*s, sy); + + z = div_s(x, y); + + if (sign != 0) + { + z = negate(z); + } + + + return z; } @@ -1352,7 +1367,7 @@ Word32 imult3216(Word32 x, Word16 y) -Word16 idiv1616U( +Word16 idiv1616U_IVAS( Word16 x, Word16 y ) { @@ -1373,6 +1388,28 @@ Word16 idiv1616U( return y; } +Word16 idiv1616U(Word16 x, Word16 y) +{ + Word16 sx, sy; + + /* make y > x to meet the requirements for div_s parameters */ + sx = norm_s(x); + sy = norm_s(y); + x = shl(x, sx); + y = shl(y, sy); + + if (x >= y) + { + x = shr(x, 1); + sx = sub(sx, 1); + } + + /* divide and shift */ + y = shr(div_s(x, y), sub(15, sub(sy, sx))); + + return y; +} + Word16 idiv1616(Word16 x, Word16 y) { @@ -1585,73 +1622,76 @@ Word32 dotp_s_fx(const Word16 *x, const Word16 *y, const Word16 n, Word16 s) Word32 BASOP_util_Pow2( - const Word32 exp_m, - const Word16 exp_e, - Word16 *result_e ) + const Word32 exp_m, const Word16 exp_e, + Word16 *result_e +) { - static const Word16 pow2Coeff[8] = { - FL2WORD16( 0.693147180559945309417232121458177 ), /* ln(2)^1 /1! */ - FL2WORD16( 0.240226506959100712333551263163332 ), /* ln(2)^2 /2! */ - FL2WORD16( 0.0555041086648215799531422637686218 ), /* ln(2)^3 /3! */ - FL2WORD16( 0.00961812910762847716197907157365887 ), /* ln(2)^4 /4! */ - FL2WORD16( 0.00133335581464284434234122219879962 ), /* ln(2)^5 /5! */ - FL2WORD16( 1.54035303933816099544370973327423e-4 ), /* ln(2)^6 /6! */ - FL2WORD16( 1.52527338040598402800254390120096e-5 ), /* ln(2)^7 /7! */ - FL2WORD16( 1.32154867901443094884037582282884e-6 ) /* ln(2)^8 /8! */ - }; - - Word32 frac_part = 0, tmp_frac, result_m; - Word16 int_part = 0; - - IF( exp_e > 0 ) - { - /* "+ 1" compensates L_shr(,1) of the polynomial evaluation at the loop end. */ + static const Word16 pow2Coeff[8] = + { + 22713/*0.693147180559945309417232121458177 Q15*/, /* ln(2)^1 /1! */ + 7872/*0.240226506959100712333551263163332 Q15*/, /* ln(2)^2 /2! */ + 1819/*0.0555041086648215799531422637686218 Q15*/, /* ln(2)^3 /3! */ + 315/*0.00961812910762847716197907157365887 Q15*/, /* ln(2)^4 /4! */ + 44/*0.00133335581464284434234122219879962 Q15*/, /* ln(2)^5 /5! */ + 5/*1.54035303933816099544370973327423e-4 Q15*/, /* ln(2)^6 /6! */ + 0/*1.52527338040598402800254390120096e-5 Q15*/, /* ln(2)^7 /7! */ + 0/*1.32154867901443094884037582282884e-6 Q15*/ /* ln(2)^8 /8! */ + }; + + Word32 frac_part, tmp_frac, result_m; + Word16 int_part; + + int_part = 0; /* to avoid compilation warnings */ + frac_part = 0; /* to avoid compilation warnings */ + + IF(exp_e > 0) + { + /* "+ 1" compensates L_shr(,1) of the polynomial evaluation at the loop end. */ - int_part = add( 1, extract_l( L_shr( exp_m, sub( 31, exp_e ) ) ) ); - frac_part = L_lshl( exp_m, exp_e ); - frac_part = L_and( 0x7FFFFFFF, frac_part ); - } - if ( exp_e <= 0 ) - frac_part = L_shl( exp_m, exp_e ); - if ( exp_e <= 0 ) - { - int_part = 1; - move16(); - } + int_part = add(1, extract_l(L_shr(exp_m, sub(31, exp_e)))); + frac_part = L_lshl(exp_m, exp_e); + frac_part = L_and(0x7FFFFFFF, frac_part); + } + if (exp_e <= 0) + frac_part = L_shl(exp_m, exp_e); + if (exp_e <= 0) + { + int_part = 1; + move16(); + } - /* Best accuracy is around 0, so try to get there with the fractional part. */ - IF( ( tmp_frac = L_sub( frac_part, FL2WORD32( 0.5 ) ) ) >= 0 ) - { - int_part = add( int_part, 1 ); - frac_part = L_sub( tmp_frac, FL2WORD32( 0.5 ) ); - } - ELSE IF( ( tmp_frac = L_add( frac_part, FL2WORD32( 0.5 ) ) ) < 0 ) - { - int_part = sub( int_part, 1 ); - frac_part = L_add( tmp_frac, FL2WORD32( 0.5 ) ); - } + /* Best accuracy is around 0, so try to get there with the fractional part. */ + IF((tmp_frac = L_sub(frac_part, 1073741824l/*0.5 Q31*/)) >= 0) + { + int_part = add(int_part, 1); + frac_part = L_sub(tmp_frac, 1073741824l/*0.5 Q31*/); + } + ELSE IF((tmp_frac = L_add(frac_part, 1073741824l/*0.5 Q31*/)) < 0) + { + int_part = sub(int_part, 1); + frac_part = L_add(tmp_frac, 1073741824l/*0.5 Q31*/); + } - /* Evaluate taylor polynomial which approximates 2^x */ - { - Word32 p; - Word16 i; + /* Evaluate taylor polynomial which approximates 2^x */ + { + Word32 p; + Word16 i; - /* First taylor series coefficient a_0 = 1.0, scaled by 0.5 due to L_shr(,1). */ - result_m = L_add( FL2WORD32( 1.0 / 2.0 ), L_shr( Mpy_32_16_1( frac_part, pow2Coeff[0] ), 1 ) ); - p = Mpy_32_32( frac_part, frac_part ); - FOR( i = 1; i < 7; i++ ) - { - /* next taylor series term: a_i * x^i, x=0 */ - result_m = L_add( result_m, L_shr( Mpy_32_16_1( p, pow2Coeff[i] ), 1 ) ); - p = Mpy_32_32( p, frac_part ); - } - result_m = L_add( result_m, L_shr( Mpy_32_16_1( p, pow2Coeff[i] ), 1 ) ); + /* First taylor series coefficient a_0 = 1.0, scaled by 0.5 due to L_shr(,1). */ + result_m = L_add(1073741824l/*1.0/2.0 Q31*/, L_shr(Mpy_32_16_1(frac_part, pow2Coeff[0]), 1)); + p = Mpy_32_32(frac_part, frac_part); + FOR(i = 1; i < 7; i++) + { + /* next taylor series term: a_i * x^i, x=0 */ + result_m = L_add(result_m, L_shr(Mpy_32_16_1(p, pow2Coeff[i]), 1)); + p = Mpy_32_32(p, frac_part); } - *result_e = int_part; - move16(); - - return result_m; + result_m = L_add(result_m, L_shr(Mpy_32_16_1(p, pow2Coeff[i]), 1)); + } + *result_e = int_part; + move16(); + return result_m; } Word16 findIndexOfMaxWord32(Word32 *x, const Word16 len) @@ -1736,27 +1776,6 @@ Word16 BASOP_Util_Divide3216_Scale( } -Word32 Pow2( /* o Q0 : result (range: 0<=val<=0x7fffffff) */ - Word16 exponant, /* i Q0 : Integer part. (range: 0<=val<=30) */ - Word16 fraction /* i Q15 : Fractional part. (range: 0.0<=val<1.0) */ -) -{ - Word16 exp, i, a; - Word32 L_x; - - i = mac_r( -32768, fraction, 32 ); /* Extract b10-b16 of fraction */ - a = s_and( fraction, 0x3ff ); /* Extract b0-b9 of fraction */ - - L_x = L_deposit_h( table_pow2[i] ); /* table[i] << 16 */ - L_x = L_mac( L_x, table_pow2_diff_x32[i], a ); /* L_x -= diff*a*2 */ - - exp = sub( 30, exponant ); - - L_x = L_shr_r( L_x, exp ); - - return L_x; -} - /************************************************************************* * * FUNCTION: Log2_norm() @@ -2118,58 +2137,6 @@ Word32 Isqrt_lc1( } -/*! r: output value, Q31 */ -Word32 Sqrt_l( - Word32 L_x, /* i : input value, Q31 */ - Word16 *exp /* o : right shift to be applied to result, Q1 */ -) -{ - /* - y = sqrt(x) - - x = f * 2^-e, 0.5 <= f < 1 (normalization) - - y = sqrt(f) * 2^(-e/2) - - a) e = 2k --> y = sqrt(f) * 2^-k (k = e div 2, - 0.707 <= sqrt(f) < 1) - b) e = 2k+1 --> y = sqrt(f/2) * 2^-k (k = e div 2, - 0.5 <= sqrt(f/2) < 0.707) - */ - - Word16 e, i, a, tmp; - Word32 L_y; - - if ( L_x <= 0 ) - { - *exp = 0; - move16(); - return L_deposit_l( 0 ); - } - -#if 0 /* original version creates an overflow warning */ - e = s_and(norm_l(L_x), 0xFFFE); /* get next lower EVEN norm. exp */ -#else - e = s_and( norm_l( L_x ), 0x7FFE ); /* get next lower EVEN norm. exp */ -#endif - L_x = L_shl( L_x, e ); /* L_x is normalized to [0.25..1) */ - *exp = e; - move16(); /* return 2*exponent (or Q1) */ - - L_x = L_shr( L_x, 9 ); - a = extract_l( L_x ); /* Extract b10-b24 */ - a = lshr( a, 1 ); - - i = mac_r( L_x, -16 * 2 - 1, 16384 ); /* Extract b25-b31 minus 16 */ - - L_y = L_deposit_h( sqrt_table[i] ); /* table[i] << 16 */ - tmp = sub( sqrt_table[i], sqrt_table[i + 1] ); /* table[i] - table[i+1]) */ - L_y = L_msu( L_y, tmp, a ); /* L_y -= tmp*a*2 */ - - /* L_y = L_shr (L_y, *exp); */ /* denormalization done by caller */ - - return ( L_y ); -} void bufferCopyFx( Word16* src, /*>1) | - | 3- i = bit25-b30 of fraction, 16 <= i <= 63 ->because of normalization. | - | 4- a = bit10-b24 | - | 5- i -=16 | - | 6- fraction = table[i]<<16 - (table[i] - table[i+1]) * a * 2 | - |___________________________________________________________________________| -*/ -Word32 Isqrt_lc( - Word32 frac, /* (i) Q31: normalized value (1.0 < frac <= 0.5) */ - Word16 * exp /* (i/o) : exponent (value = frac x 2^exponent) */ -) -{ - Word16 i, a; - Word32 L_tmp; - - IF(frac <= (Word32)0) - { - *exp = 0; move16(); - return 0x7fffffff; /*0x7fffffff*/ - } - - /* If exponant odd -> shift right by 10 (otherwise 9) */ - L_tmp = L_shr(frac, shift_Isqrt_lc[s_and(*exp, 1)]); - - /* 1) -16384 to shift left and change sign */ - /* 2) 32768 to Add 1 to Exponent like it was divided by 2 */ - /* 3) We let the mac_r add another 0.5 because it imitates */ - /* the behavior of shr on negative number that should */ - /* not be rounded towards negative infinity. */ - /* It replaces: */ - /* *exp = negate(shr(sub(*exp, 1), 1)); move16(); */ - *exp = mac_r(32768, *exp, -16384); move16(); - - a = extract_l(L_tmp); /* Extract b10-b24 */ - a = lshr(a, 1); - - i = mac_r(L_tmp, -16 * 2 - 1, 16384); /* Extract b25-b31 minus 16 */ - - L_tmp = L_msu(L_table_isqrt[i], table_isqrt_diff[i], a);/* table[i] << 16 - diff*a*2 */ - - return L_tmp; -} - -Word32 Isqrt( /* (o) Q31 : output value (range: 0<=val<1) */ - Word32 L_x /* (i) Q0 : input value (range: 0<=val<=7fffffff) */ -) -{ - Word16 exp; - Word32 L_y; - - exp = norm_l(L_x); - L_x = L_shl(L_x, exp); /* L_x is normalized */ - exp = sub(31, exp); - - L_x = Isqrt_lc(L_x, &exp); - - L_y = L_shl(L_x, exp); /* denormalization */ - - return (L_y); -} - -#ifdef BASOP_NOGLOB -Word32 Dot_product12_o( /* (o) Q31: normalized result (1 < val <= -1) */ - const Word16 x[], /* (i) 12bits: x vector */ - const Word16 y[], /* (i) 12bits: y vector */ - const Word16 lg, /* (i) : vector length */ - Word16* exp, /* (o) : exponent of result (0..+30) */ - Flag* Overflow_out /* o : propagating the Overflow flag to upper level, set to NULL to ignore internal overflows */ -) -#else /* BASOP_NOGLOB */ -Word32 Dot_product12( /* (o) Q31: normalized result (1 < val <= -1) */ - const Word16 x[], /* (i) 12bits: x vector */ - const Word16 y[], /* (i) 12bits: y vector */ - const Word16 lg, /* (i) : vector length */ - Word16 * exp /* (o) : exponent of result (0..+30) */ -) -#endif /* BASOP_NOGLOB */ -{ - Word16 i, sft; - Word32 L_sum; -#ifdef BASOP_NOGLOB - Flag Overflow_ignored = 0; -#endif /* BASOP_NOGLOB */ - -#ifdef BASOP_NOGLOB - L_sum = L_mac_o(1, x[0], y[0], &Overflow_ignored); -#else - L_sum = L_mac(1, x[0], y[0]); -#endif - FOR(i = 1; i < lg; i++) - { -#ifdef BASOP_NOGLOB - L_sum = L_mac_o(L_sum, x[i], y[i], Overflow_out ? Overflow_out : &Overflow_ignored); -#else /* BASOP_NOGLOB */ - L_sum = L_mac(L_sum, x[i], y[i]); -#endif /* BASOP_NOGLOB */ - } - - /* Normalize acc in Q31 */ - - sft = norm_l(L_sum); - L_sum = L_shl(L_sum, sft); - - *exp = sub(30, sft); move16(); /* exponent = 0..30 */ - - return L_sum; -} - -#ifdef BASOP_NOGLOB -Word32 Dot_product12( /* (o) Q31: normalized result (1 < val <= -1) */ - const Word16 x[], /* (i) 12bits: x vector */ - const Word16 y[], /* (i) 12bits: y vector */ - const Word16 lg, /* (i) : vector length */ - Word16 * exp /* (o) : exponent of result (0..+30) */ -) -{ - /* Ignore internal overflows */ - return Dot_product12_o(x, y, lg, exp, NULL); -} -#endif /* BASOP_NOGLOB */ - -Word32 Energy_scale( /* (o) : Q31: normalized result (1 < val <= -1) */ - const Word16 x[], /* (i) : input vector x */ - const Word16 lg, /* (i) : vector length */ - Word16 expi, /* (i) : exponent of input */ - Word16 *exp /* (o) : exponent of result (0..+30) */ -) -{ - Word16 i, sft, tmp; - Word32 L_sum; -#ifdef BASOP_NOGLOB_DECLARE_LOCAL - Flag Overflow = 0; -#endif - - - L_sum = 0; /* just to avoid superflous compiler warning about uninitialized use of L_sum */ - - IF(expi == 0) - { -#ifdef BASOP_NOGLOB - L_sum = L_mac_o(1, x[0], x[0], &Overflow); -#else - L_sum = L_mac(1, x[0], x[0]); -#endif - FOR(i = 1; i < lg; i++) - { -#ifdef BASOP_NOGLOB - L_sum = L_mac_o(L_sum, x[i], x[i], &Overflow); -#else /* BASOP_NOGLOB */ - L_sum = L_mac(L_sum, x[i], x[i]); -#endif - } - } - IF(expi < 0) - { - sft = lshl(-32768 /* 0x8000 */, expi); - tmp = mult_r(x[0], sft); - L_sum = L_mac(1, tmp, tmp); - FOR(i = 1; i < lg; i++) - { - tmp = mult_r(x[i], sft); -#ifdef BASOP_NOGLOB - L_sum = L_mac_o(L_sum, tmp, tmp, &Overflow); -#else - L_sum = L_mac(L_sum, tmp, tmp); -#endif - } - } - IF(expi > 0) - { -#ifdef BASOP_NOGLOB - tmp = shl_o(x[0], expi, &Overflow); - L_sum = L_mac_o(1, tmp, tmp, &Overflow); - FOR(i = 1; i < lg; i++) - { - tmp = shl_o(x[i], expi, &Overflow); - L_sum = L_mac_o(L_sum, tmp, tmp, &Overflow); - } -#else - tmp = shl(x[0], expi); - L_sum = L_mac(1, tmp, tmp); - FOR(i = 1; i < lg; i++) - { - tmp = shl(x[i], expi); - L_sum = L_mac(L_sum, tmp, tmp); - } -#endif - } - - /* Normalize acc in Q31 */ - - sft = norm_l(L_sum); - L_sum = L_shl(L_sum, sft); - - *exp = sub(30, sft); move16(); /* exponent = 0..30 */ - - - return L_sum; -} - -Word32 L_Frac_sqrtQ31( /* o : Square root if input */ - const Word32 x /* i : Input */ -) -{ - Word32 log2_work; - Word16 log2_int, log2_frac; - - test(); - if (x > 0) - { - log2_int = norm_l(x); - log2_frac = Log2_norm_lc(L_shl(x, log2_int)); - - log2_work = L_msu((31 + 30) * 65536L / 2, 16384, log2_int); - log2_work = L_mac0(log2_work, log2_frac, 1); - - log2_frac = L_Extract_lc(log2_work, &log2_int); - - return Pow2(log2_int, log2_frac); - } - return 0; -} - -Word16 Frac_sqrt( /* o : Square root if input */ - const Word16 x /* i : Input */ -) -{ - return round_fx(L_Frac_sqrtQ31(L_deposit_h(x))); -} - -Word16 i_mult2(Word16 a, Word16 b) -{ - return extract_l(L_mult0(a, b)); - -} - -UWord32 UL_deposit_l(UWord16 uvar) { - UWord32 UL_result; - UL_result = (UWord32)uvar; /* no sign extension*/ - return (UL_result); -} - -UWord32 UL_addNs(UWord32 UL_var1, UWord32 UL_var2, UWord16 * wrap) { - UWord32 UL_var3; - - /* STL Overflow flag is not updated */ - UL_var3 = UL_var1 + UL_var2; /* 32-bit wrap may occur, like in C */ - - if (((UWord64)UL_var1 + (UWord64)UL_var2) > 0xFFFFFFFFU) { - *wrap = 1; /* wrapped output */ - } - else { - *wrap = 0; - } - - return UL_var3; -} - -UWord32 UL_subNs(UWord32 UL_var1, UWord32 UL_var2, UWord16 * sgn) { - UWord32 UL_var3; - - UL_var3 = UL_var1 - UL_var2; /*wrap may occur, like in C */ - if (UL_var1 >= UL_var2) { - *sgn = 0; - } - else { - *sgn = 1; /* "negative", wrapped output */ - } - return UL_var3; -} - -void Mpy_32_16_uu(UWord32 UL_var1, UWord16 uvar2, UWord32 *UL_varout_h, UWord16 *varout_l) { - UWord64 UL64_var1; - - /* 4294967295 * 65535 < 281474976710655 */ - /* (uint64(2)^16-1 )*(uint64(2)^32-1) < (uint64(2)^(16+32)-1) */ - UL64_var1 = ((UWord64)UL_var1)*((UWord64)uvar2); - *varout_l = (UWord16)UL64_var1; - *UL_varout_h = (UWord32)(UL64_var1 >> 16); - - - return; -} - -void Mpy_32_32_uu(UWord32 UL_var1, UWord32 UL_var2, UWord32 *UL_varout_h, UWord32 *UL_varout_l) { - UWord64 UL64_var1; - /* (uint64(2)^32-1 )*(uint64(2)^32-1) < (uint64(2)^(32+32)-1) */ - UL64_var1 = ((UWord64)UL_var1)*((UWord64)UL_var2); - *UL_varout_h = (UWord32)(UL64_var1 >> 32); - *UL_varout_l = (UWord32)(UL64_var1); - - - return; - -} - -UWord32 UL_Mpy_32_32(UWord32 UL_var1, UWord32 UL_var2) { - UWord32 UL_varout_l; - -#define MASK32 0xFFFFFFFFU - /* MASK32 may be needed in case Hardware is using larger than 32 bits for UWord32 type */ - UL_varout_l = (UL_var1&MASK32)*(UL_var2&MASK32); - UL_varout_l = UL_varout_l & MASK32; -#undef MASK32 - - - return UL_varout_l; -} - -/* (Reuse of existing signed STL "L" operators) with - typecasting to make the resulting "UL" code a lot cleaner and more readable. */ - -UWord32 UL_lshl(UWord32 UL_var1, Word16 var2) { - return((UWord32)L_lshl((Word32)UL_var1, var2)); -} - -UWord32 UL_lshr(UWord32 UL_var1, Word16 var2) { - return((UWord32)L_lshr((Word32)UL_var1, var2)); -} - -UWord32 UL_and(UWord32 UL_var1, UWord32 UL_var2) -{ - return (UWord32)L_and((Word32)UL_var1, (Word32)UL_var2); -} - -UWord32 UL_or(UWord32 UL_var1, UWord32 UL_var2) -{ - return (UWord32)L_or((Word32)UL_var1, (Word32)UL_var2); -} - -UWord32 UL_xor(UWord32 UL_var1, UWord32 UL_var2) -{ - return (UWord32)L_xor((Word32)UL_var1, (Word32)UL_var2); -} - -UWord32 UL_deposit_h(UWord16 uvar1) -{ - return (UWord32)L_deposit_h((Word32)uvar1); -} - -UWord16 u_extract_h(UWord32 UL_var1) -{ - return (UWord16)extract_h((Word32)UL_var1); -} - -UWord16 u_extract_l(UWord32 UL_var1) -{ - return (UWord32)extract_l((Word32)UL_var1); -} - -/* enable convenient reuse of Non-saturating UL_subNs , UL_addNs while "D"iscarding the sgn/wrap output flags */ -UWord32 UL_subNsD(UWord32 UL_var1, UWord32 UL_var2) -{ - UWord16 dummy_sign; - return UL_subNs(UL_var1, UL_var2, &dummy_sign); -} - -UWord32 UL_addNsD(UWord32 UL_var1, UWord32 UL_var2) -{ - UWord16 dummy_wrap; - return UL_addNs(UL_var1, UL_var2, &dummy_wrap); -} #undef WMC_TOOL_SKIP diff --git a/lib_com/basop_util.h b/lib_com/basop_util.h index 0a406bf01514b8910914e84ea0c6e0c428bd7c13..e77a643f4ff28e984d05e228bbd480e45728ac54 100644 --- a/lib_com/basop_util.h +++ b/lib_com/basop_util.h @@ -559,7 +559,8 @@ Word32 imult3216(Word32 x, Word16 y); \return 16/16->16 integer */ -Word16 idiv1616U( Word16 x, Word16 y ); +Word16 idiv1616U_IVAS( Word16 x, Word16 y ); +Word16 idiv1616U(Word16 x, Word16 y); /****************************************************************************/ /*! @@ -630,6 +631,19 @@ Word32 Dot_productSq16HQ( /* using 64-bit accumulator. + * + * Performs no normalization of the result + *------------------------------------------------------------------*/ +Word32 dotp_s_fx( /*> (30-exponant) (with rounding) | - |___________________________________________________________________________| -*/ -Word32 Pow2( /* o : Q0 : result (range: 0<=val<=0x7fffffff) */ - Word16 exponant, /* i : Q0 : Integer part. (range: 0<=val<=30) */ - Word16 fraction /* i : Q15 : Fractionnal part. (range: 0.0<=val<1.0) */ -); /************************************************************************* * @@ -867,84 +850,11 @@ Word16 BASOP_util_atan2( /*!< o: atan2(y,x) [-pi,pi] Q13 */ Word32 dotWord32_16_guards( const Word32 *X, const Word16 *Y, Word16 n, Word16 hr, Word16 *shift ); -Word32 Sqrt_l( Word32 L_x, Word16 *exp ); - -Word32 Isqrt( /* (o) Q31 : output value (range: 0<=val<1) */ - Word32 L_x /* (i) Q0 : input value (range: 0<=val<=7fffffff) */ -); - -#ifdef BASOP_NOGLOB -Word32 Dot_product12_o( /* (o) Q31: normalized result (1 < val <= -1) */ - const Word16 x[], /* (i) 12bits: x vector */ - const Word16 y[], /* (i) 12bits: y vector */ - const Word16 lg, /* (i) : vector length */ - Word16* exp, /* (o) : exponent of result (0..+30) */ - Flag* Overflow_out /* o : propagating the Overflow flag to upper level, set to NULL to ignore internal overflows */ -); -#else /* BASOP_NOGLOB */ -Word32 Dot_product12( /* (o) Q31: normalized result (1 < val <= -1) */ - const Word16 x[], /* (i) 12bits: x vector */ - const Word16 y[], /* (i) 12bits: y vector */ - const Word16 lg, /* (i) : vector length */ - Word16 * exp /* (o) : exponent of result (0..+30) */ -); -#endif /* BASOP_NOGLOB */ - -#ifdef BASOP_NOGLOB -Word32 Dot_product12( /* (o) Q31: normalized result (1 < val <= -1) */ - const Word16 x[], /* (i) 12bits: x vector */ - const Word16 y[], /* (i) 12bits: y vector */ - const Word16 lg, /* (i) : vector length */ - Word16 * exp /* (o) : exponent of result (0..+30) */ -); -#endif - -Word32 Energy_scale( /* (o) : Q31: normalized result (1 < val <= -1) */ - const Word16 x[], /* (i) : input vector x */ - const Word16 lg, /* (i) : vector length */ - Word16 expi, /* (i) : exponent of input */ - Word16 *exp /* (o) : exponent of result (0..+30) */ -); - -Word32 L_Frac_sqrtQ31( /* o : Square root if input */ - const Word32 x /* i : Input */ -); - -Word16 Frac_sqrt( /* o : Square root if input */ - const Word16 x /* i : Input */ -); - - -Word16 i_mult2(Word16 a, Word16 b); - -UWord32 UL_deposit_l(UWord16 uvar); - -UWord32 UL_addNs(UWord32 UL_var1, UWord32 UL_var2, UWord16 * wrap); - -UWord32 UL_subNs(UWord32 UL_var1, UWord32 UL_var2, UWord16 * sgn); - -void Mpy_32_16_uu(UWord32 UL_var1, UWord16 uvar2, UWord32 *UL_varout_h, UWord16 *varout_l); - -void Mpy_32_32_uu(UWord32 UL_var1, UWord32 UL_var2, UWord32 *UL_varout_h, UWord32 *UL_varout_l); - -UWord32 UL_Mpy_32_32(UWord32 UL_var1, UWord32 UL_var2); - -UWord32 UL_lshl(UWord32 UL_var1, Word16 var2); -UWord32 UL_lshr(UWord32 UL_var1, Word16 var2); -UWord32 UL_and(UWord32 UL_var1, UWord32 UL_var2); -UWord32 UL_or(UWord32 UL_var1, UWord32 UL_var2); -UWord32 UL_xor(UWord32 UL_var1, UWord32 UL_var2); -UWord32 UL_deposit_h(UWord16 uvar1); -UWord16 u_extract_h(UWord32 UL_var1); -UWord16 u_extract_l(UWord32 UL_var1); - -/* enable convenient reuse of Non-saturating UL_subNs , UL_addNs - while "D"iscarding the sgn/wrap output flags */ -UWord32 UL_subNsD(UWord32 UL_var1, UWord32 UL_var2); -UWord32 UL_addNsD(UWord32 UL_var1, UWord32 UL_var2); - - //function defined in basop_util commented from basop_tcx_utils.c Word16 compMantExp16Unorm(Word16 m1, Word16 e1, Word16 m2, Word16 e2); +cmplx CL_scale_t(cmplx x, Word16 y); +cmplx CL_dscale_t(cmplx x, Word16 y1, Word16 y2); +cmplx CL_mult_32x16(cmplx input, cmplx_s coeff); + #endif /* __BASOP_UTIL_H__ */ diff --git a/lib_com/bitalloc_fx.c b/lib_com/bitalloc_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..f276062739c8ae7a1818a2b6bcaa8e81374b1d82 --- /dev/null +++ b/lib_com/bitalloc_fx.c @@ -0,0 +1,1043 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include +#include "options.h" /* Compilation switches */ +#include "cnst.h" /* Common constants */ +#include "rom_com.h" /* Static table prototypes */ +#include "prot_fx1.h" /* Function prototypes */ +#include "prot_fx2.h" /* Function prototypes */ + +void bitalloc_fx ( + Word16 *y, /* i : reordered norm of sub-vectors Q0 */ + Word16 *idx, /* i : reordered sub-vector indices Q0 */ + Word16 sum, /* i : number of available bits Q0 */ + Word16 N, /* i : number of norms Q0 */ + Word16 K, /* i : maximum number of bits per dimension Q0 */ + Word16 *r, /* o : bit-allacation vector Q0 */ + const Word16 *sfmsize, /* i : band length Q0 */ + const Word16 hqswb_clas /* i : signal classification flag Q0 */ +) +{ + Word16 i, j, k, n, m, v, im; + Word16 diff, temp; + Word16 fac; + Word16 ii; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + Word16 SFM_thr = SFM_G1G2; + move16(); + + N = sub(N, 1); + + if ( EQ_16(hqswb_clas, HQ_HARMONIC)) + { + SFM_thr = 22; + move16(); + } + + fac = 3; + move16(); + K = sub(K,2); + im = 1; + move16(); + diff = sum; + move16(); + n = shr(sum,3); + FOR ( i=0; iHQ switching. */ + { + BREAK; + } + + diff = sum; + move16(); + v = sub(N, 1); + + IF ( GT_16(k, v)) + { + FOR ( ii=0; ii<=N; ii++ ) + { + IF ( GT_16(y[ii], -32768)) + { + if ( LT_16(ii, N)) + { + im = add(ii, 1); + } + BREAK; + } + } + } + } + + + IF ( GE_16(sum, sfmsize[SFM_G1])) /* sfmsize[SFM_G1] matches WID_G2, but also allows for extended BWs used in ACELP->HQ switching. */ + { + FOR (i=0; i<=N; i++) + { + j = idx[i]; + move16(); + test(); + test(); + IF ( GE_16(j, SFM_G1)&<_16(j,SFM_thr)&&r[j]==0) + { + r[j] = 1; + move16(); + sum = sub(sum, sfmsize[j]); + IF (LT_16(sum, sfmsize[SFM_G1])) + { + BREAK; + } + } + } + } + + IF ( GE_16(sum, sfmsize[SFM_G1])) + { + FOR (i=0; i<=N; i++) + { + j = idx[i]; + move16(); + test(); + test(); + IF ( GE_16(j,SFM_G1)&<_16(j,SFM_thr)&&EQ_16(r[j],1)) + { + r[j] = 2; + move16(); + sum = sub(sum, sfmsize[j]); + IF ( LT_16(sum, sfmsize[SFM_G1])) + { + BREAK; + } + } + } + } + + IF ( GE_16(sum, sfmsize[SFM_G1-1])) + { + FOR (i=0; i<=N; i++) + { + j = idx[i]; + move16(); + test(); + IF ( LT_16(j, SFM_G1)&&r[j]==0) + { + r[j] = 1; + move16(); + sum = sub(sum, sfmsize[j]); + IF ( LT_16(sum, sfmsize[SFM_G1-1])) + { + BREAK; + } + } + } + } + + IF ( GE_16(sum, sfmsize[SFM_G1-1])) + { + FOR (i=0; i<=N; i++) + { + j = idx[i]; + move16(); + test(); + IF ( LT_16(j, SFM_G1)&&EQ_16(r[j],1)) + { + r[j] = 2; + move16(); + sum = sub(sum, sfmsize[j]); + IF ( LT_16(sum, sfmsize[SFM_G1-1])) + { + BREAK; + } + } + } + } + + return; +} + +/*-------------------------------------------------------------------* + * BitAllocF() + * + * Fractional bit allocation + *-------------------------------------------------------------------*/ + +Word16 BitAllocF_fx ( + Word16 *y, /* i : norm of sub-vectors :Q0 */ + Word32 bit_rate, /* i : bitrate :Q0 */ + Word16 B, /* i : number of available bits :Q0 */ + Word16 N, /* i : number of sub-vectors :Q0 */ + Word16 *R, /* o : bit-allocation indicator :Q0 */ + Word16 *Rsubband_fx /* o : sub-band bit-allocation vector :Q3 */ + ,const Word16 hqswb_clas, /* i : hq swb class :Q0 */ + const Word16 num_env_bands/* i : Number sub bands to be encoded for HF GNERIC :Q0 */ +) +{ + Word16 fac; + Word16 i, n, Nmin, Bits, bs, low_rate = 0; + + Word16 m_fx; + Word32 t_fx, B_fx; + Word32 L_tmp1, L_tmp2, L_tmp3; + Word16 tmp, exp1, exp2; + Word32 Rsubband_w32_fx[NB_SFM]; /* Q15 */ + Word16 B_w16_fx; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + + set32_fx( Rsubband_w32_fx, 0, NB_SFM); + + fac = 3; + move16(); + + IF (LT_32(bit_rate, 32000)) + { + bs = 2; + move16(); + } + ELSE + { + bs = 3; + move16(); + } + low_rate = 1; + move16(); + + Nmin = N; + move16(); + if ( GT_16(Nmin,SFM_N)) + { + Nmin = SFM_N; + move16(); + } + + /* Initial bits distribution */ + test(); + IF (EQ_16(hqswb_clas , HQ_GEN_SWB)||EQ_16(hqswb_clas,HQ_GEN_FB)) + { + /* Initial bits distribution */ + L_tmp1 = 0; + move16(); + m_fx = 0; + move16(); + FOR ( i = 0; i < num_env_bands ; i++) + { + L_tmp1 = L_mac0(L_tmp1, Nb[i], y[i]); + } + L_tmp1 = L_msu0(L_tmp1, fac, B); + + t_fx = L_deposit_l(0); + n = 0; + move16(); + tmp = add(band_end_HQ[num_env_bands-1], shl(band_end_HQ[num_env_bands-1], 1)); + exp1 = norm_s(tmp); + tmp = div_s(16384, shl(tmp, exp1));/*15 + 14 - exp1*/ + exp2 = norm_s(tmp); + tmp = shl(tmp, exp2); + exp1 = add(29, sub(exp2, exp1)); + + FOR ( i = 0; i < N; i++) + { + L_tmp2 = L_sub(L_mult0(y[i], band_end_HQ[num_env_bands-1]), L_tmp1); + Rsubband_w32_fx[i] = L_mult0(extract_l(L_tmp2), Nb[i]); + move32();/*Q0*/ + IF (Rsubband_w32_fx[i] > 0) + { + n = add(n,Nb[i]); + Rsubband_w32_fx[i] = Mult_32_16(Rsubband_w32_fx[i], tmp); + move32();/*exp1 - 15*/ + Rsubband_w32_fx[i] = L_shl(Rsubband_w32_fx[i], sub(30, exp1));/*Q15*/ + + t_fx = L_add(t_fx, Rsubband_w32_fx[i]);/*Q0*/ + } + ELSE + { + Rsubband_w32_fx[i] = L_deposit_l(0); + } + } + } + ELSE + { + /* Initial bits distribution */ + L_tmp1 = 0; + move16(); + m_fx = 0; + move16(); + FOR ( i = 0; i < N ; i++) + { + L_tmp1 = L_mac0(L_tmp1, Nb[i], y[i]); + } + L_tmp1 = L_msu0(L_tmp1, fac, B); + + + t_fx = L_deposit_l(0); + n = 0; + move16(); + tmp = add(band_end_HQ[N-1], shl(band_end_HQ[N-1], 1)); + exp1 = norm_s(tmp); + tmp = div_s(16384, shl(tmp, exp1));/*15 + 14 - exp1*/ + exp2 = norm_s(tmp); + tmp = shl(tmp, exp2); + exp1 = add(29, sub(exp2, exp1)); + FOR ( i = 0; i < N; i++) + { + L_tmp2 = L_sub(L_mult0(y[i], band_end_HQ[N-1]), L_tmp1); + Rsubband_w32_fx[i] = L_mult0(extract_l(L_tmp2), Nb[i]); + move32();/*Q0*/ + IF (Rsubband_w32_fx[i] > 0) + { + n = add(n,Nb[i]); + L_tmp3 = Mult_32_16(Rsubband_w32_fx[i], tmp); /*exp1 - 15*/ + Rsubband_w32_fx[i] = L_shl(L_tmp3, sub(30, exp1)); /*Q15*/ move32(); + + t_fx = L_add(t_fx, Rsubband_w32_fx[i]);/*Q0*/ + } + ELSE + { + Rsubband_w32_fx[i] = L_deposit_l(0); + } + } + } + + /* Distribute the remaining bits to subbands with non-zero bits */ + B_fx = L_shl(B, 15); + WHILE (NE_32(L_shr(L_add(t_fx, 16384), 15) , B)) + { + L_tmp1 = L_sub(t_fx, B_fx); + exp1 = sub(norm_l(L_tmp1), 1); + exp2 = norm_s(n); + tmp = div_s(extract_h(L_shl(L_tmp1, exp1)), shl(n, exp2));/*15 + 15 + exp1 - 16 - exp2*/ + m_fx = shl(tmp, sub(exp2, exp1));/*Q14*/ + + t_fx = L_deposit_l(0); + n = 0; + move16(); + FOR ( i = 0; i < N; i++) + { + IF (Rsubband_w32_fx[i] > 0) + { + Rsubband_w32_fx[i] = L_msu(Rsubband_w32_fx[i], m_fx, Nb[i]); + move32(); + + IF (Rsubband_w32_fx[i] > 0) + { + n = add(n,Nb[i]); + + t_fx = L_add(t_fx, Rsubband_w32_fx[i]); + } + ELSE + { + Rsubband_w32_fx[i] = L_deposit_l(0); + } + } + } + } + Bits = B; + move16(); + + /* Impose bit-constraints to subbands with less than minimum bits*/ + t_fx = L_deposit_l(0); + n = 0; + move16(); + FOR ( i = 0; i < N; i++) + { + IF (Rsubband_w32_fx[i] > 0) + { + test(); + IF ((LT_32(Rsubband_w32_fx[i] , L_shl(add(bs, LNb[i]), 15)))&&(EQ_16(low_rate,1))) + { + Rsubband_w32_fx[i] = L_deposit_l(0); + } + ELSE IF ( LE_32(Rsubband_w32_fx[i] , L_shl(Nb[i], 15))) + { + B = sub(B,Nb[i]); + Rsubband_w32_fx[i] = L_shl(Nb[i], 15); + move32(); + } + ELSE + { + n = add(n,Nb[i]); + t_fx = L_add(t_fx, Rsubband_w32_fx[i]); + } + } + } + + /* Distribute the remaining bits to subbands with more than 1-bit per sample */ + WHILE (NE_32(L_shr(L_add(t_fx, 16384), 15) ,B)) + { + L_tmp1 = L_sub(t_fx, L_shl(B, 15)); + L_tmp2 = L_abs(L_tmp1); + + if (n>0) + { + exp1 = sub(norm_l(L_tmp2), 1); + exp2 = norm_s(n); + tmp = div_s(extract_h(L_shl(L_tmp2, exp1)), shl(n, exp2));/*15 + 15 + exp1 - 16 - exp2*/ +#ifdef BASOP_NOGLOB + m_fx = shl_o(tmp, sub(exp2, exp1), &Overflow);/*Q14*/ +#else + m_fx = shl(tmp, sub(exp2, exp1));/*Q14*/ +#endif + if (L_tmp1 < 0) + { + m_fx = negate(m_fx); + } + + t_fx = L_deposit_l(0); + n = 0; + move16(); + FOR( i = 0; i < N; i++) + { + IF (GT_32(Rsubband_w32_fx[i] , L_shl(Nb[i], 15))) + { + Rsubband_w32_fx[i] = L_msu(Rsubband_w32_fx[i], m_fx, Nb[i]); + move32(); + IF (GT_32(Rsubband_w32_fx[i] ,L_shl(Nb[i], 15))) + { + n = add(n,Nb[i]); + + t_fx = L_add(t_fx, Rsubband_w32_fx[i]); + } + ELSE + { + B = sub(B,Nb[i]); + + Rsubband_w32_fx[i] = L_shl(Nb[i], 15); + move32(); + } + } + } + } + /*In case no subband has enough bits more than 1-bit per sample, take bits off the higher subbands */ + IF (t_fx == 0) + { + FOR ( i = N-1; i >= 0; i--) + { + IF (Rsubband_w32_fx[i] > 0) + { + B = add( B, Nb[i] ); + Rsubband_w32_fx[i] = L_deposit_l(0); + IF ( B >= 0) + { + BREAK; + } + } + } + BREAK; + } + } + + /* fine redistribution of over-allocated or under-allocated bits */ + tmp = 0; + move16(); + FOR ( i = 0; i < N; i++) + { + Rsubband_fx[i] = extract_l(L_shr(Rsubband_w32_fx[i], 12)); + tmp = add(tmp, Rsubband_fx[i]); + } + + B = Bits; + B_w16_fx = shl(B, 3); + IF (GT_16(tmp ,B_w16_fx)) + { + tmp = sub(tmp, B_w16_fx); + FOR ( i = 0; i < N; i++) + { + IF (GE_16(Rsubband_fx[i], add(shl(Nb[i], 3), tmp))) + { + Rsubband_fx[i] = sub(Rsubband_fx[i], tmp); + move16(); + BREAK; + } + } + } + ELSE + { + tmp = sub(tmp, B_w16_fx); + FOR ( i = 0; i < N; i++) + { + IF (Rsubband_fx[i] > 0) + { + Rsubband_fx[i] = sub(Rsubband_fx[i], tmp); + move16(); + BREAK; + } + } + } + + /* Calcuate total used bits and initialize R to be used for Noise Filling */ + tmp = 0; + move16(); + FOR ( i = 0; i < N; i++) + { + tmp = add(tmp, Rsubband_fx[i]); + R[i] = shr(Rsubband_fx[i], 3); + move16(); + } + return shr(tmp, 3); +} +/*-------------------------------------------------------------------* + * Bit_group() + * + * bit allocation in group + *-------------------------------------------------------------------*/ +static +void Bit_group_fx ( + Word16 *y, /* i : norm of sub-band Q0*/ + Word16 start_band, /* i : start band indices Q0*/ + Word16 end_band, /* i : end band indices Q0*/ + Word16 Bits, /* i : number of allocation bits in group Q0*/ + Word16 thr, /* i : smallest bit number for allocation in group Q0*/ + Word32 *Rsubband_fx, /* o : bit allocation of sub-band Q21*/ + Word16 *fac_fx /* i : weight factor for norm of sub-band Q13*/ +) +{ + Word16 i, j, k, m, y_index[16], index[16], bit_band, band_num, norm_sum; + Word16 tmp,exp; + Word16 factor_fx; + Word32 R_temp_fx[16], R_sum_fx = 0, R_sum_org_fx = 0, Bits_avg_fx = 0; + Word32 L_tmp; + + /* initialization for bit allocation in one group*/ + tmp = 6554; + move16(); /*Q15 1/5 */ + if(EQ_16(thr,5)) + { + tmp = 6554; + move16(); /*Q15 1/5 */ + } + if(EQ_16(thr,6)) + { + tmp = 5462; + move16();/*Q15 1/6 */ + } + if(EQ_16(thr,7)) + { + tmp = 4682; + move16();/*Q15 1/7 */ + } + bit_band = mult(tmp, Bits); /*0+15-15=0, Q0 */ + band_num = sub(end_band,start_band); + + FOR( i = 0; i < band_num; i++ ) + { + y_index[i] = y[add(i,start_band)]; + move16(); + index[i] = i; + move16(); + } + + /* Rearrange norm vector in decreasing order */ + reordvct_fx(y_index, band_num, index); + /* norm vector modification */ + + factor_fx = div_s(1, band_num);/*Q15 */ + IF ( GT_16(thr,5)) + { + FOR ( i = 0; i < band_num; i++ ) + { + L_tmp = L_mult(i,factor_fx);/*Q16 */ + tmp = extract_h(L_shl(L_tmp, 13)); /*Q13 */ + tmp = sub(fac_fx[1],tmp);/*Q13 */ + L_tmp = L_mult(y_index[i],tmp);/*Q14 */ + y_index[i] = extract_h(L_shl(L_tmp, 2));/*Q0 */ + } + } + ELSE + { + FOR ( i = 0; i < band_num; i++ ) + { + L_tmp = L_mult(i,factor_fx);/*Q16 */ + tmp = extract_h(L_shl(L_tmp, 13)); /*Q13 */ + tmp = sub(fac_fx[0],tmp);/*Q13 */ + L_tmp = L_mult(y_index[i],tmp);/*Q14 */ + y_index[i] = extract_h(L_shl(L_tmp, 2));/*Q0 */ + } + } + + /* bit allocation based on modified norm */ + L_tmp = L_mult(band_num,24576);/*Q16 */ + tmp = extract_h(L_shl(L_tmp,7));/*Q7 */ + IF ( GE_16(shl(bit_band,7),tmp)) + { + FOR ( j = 0; j < band_num; j++) + { + if ( y_index[j] < 0 ) + { + y_index[j] = 0; + move16(); + } + R_temp_fx[j] = 2097152; + move16();/*Q21 = 1 move16(); */ + } + + i = sub(band_num,1); + norm_sum = 0;/*Q0 */ + FOR (k = 0; k <= i; k++) + { + norm_sum = add(norm_sum,y_index[k]); + } + + FOR (j = 0; j < band_num; j++) + { + IF(norm_sum == 0) + { + FOR (k = 0; k <= i; k++) + { + R_temp_fx[k] = L_deposit_h(0);/*Q21 */ + } + } + ELSE + { + exp = norm_s(norm_sum); + tmp = shl(norm_sum, exp);/*Q(exp) */ + tmp = div_s(16384,tmp); /*Q(15+14-exp) */ + Bits_avg_fx = L_mult(tmp, Bits);/*Q(30-exp) */ + + FOR (k = 0; k <= i; k++) + { + L_tmp = L_shl(L_deposit_l(y_index[k]),24); + L_tmp = Mult_32_32(Bits_avg_fx,L_tmp);/*Q(23-exp) */ + + R_temp_fx[k] = L_shl(L_tmp,sub(exp,2)); + move32();/*Q21 */ + } + } + + L_tmp = L_shl(L_deposit_l(thr),21);/*Q21 */ + IF ( LT_32(R_temp_fx[i],L_tmp)) + { + R_temp_fx[i] = L_deposit_h(0); + norm_sum = sub(norm_sum,y_index[i]); + i--; + } + ELSE + { + BREAK; + } + } + } + ELSE + { + FOR ( j = 0; j < bit_band; j++ ) + { + if ( y_index[j] < 0 ) + { + y_index[j] = 0; + move16(); + } + R_temp_fx[j] = 2097152; + move32();/*Q21 = 1 */ + } + + FOR ( j = bit_band; j < band_num; j++ ) + { + R_temp_fx[j] = L_deposit_l(0); + } + + norm_sum = 0; + FOR (k = 0; k < bit_band; k++) + { + norm_sum = add(norm_sum,y_index[k]); + } + + i = bit_band; + FOR (j = 0; j < bit_band; j++) + { + IF(norm_sum == 0) + { + FOR (k = 0; k < i; k++) + { + R_temp_fx[k] = L_deposit_l(0); /*Q21 */ + } + } + ELSE + { + exp = norm_s(norm_sum); + tmp = shl(norm_sum, exp);/*Q(exp) */ + tmp = div_s(16384,tmp); /*Q(15+14-exp) */ + Bits_avg_fx = L_mult(tmp, Bits);/*Q(30-exp) */ + FOR (k = 0; k < i; k++) + { + L_tmp = L_shl(L_deposit_l(y_index[k]),24); + L_tmp = Mult_32_32(Bits_avg_fx,L_tmp);/*Q(23-exp) */ + + R_temp_fx[k] = L_shl(L_tmp,sub(exp,2)); + move32();/*Q21 */ + } + } + R_sum_fx = 0; + L_tmp = L_shl(L_deposit_l(thr),21);/*Q21 */ + FOR (k = 0; k < i; k++) + { + IF (LT_32(R_temp_fx[k],L_tmp)) + { + FOR(m = k; m < i; m++) + { + norm_sum = sub(norm_sum,y_index[m]); + R_temp_fx[m] = L_deposit_l(0); /*Q21 */ + } + i = k; + BREAK; + } + ELSE + { + R_sum_fx = L_add(R_sum_fx,R_temp_fx[k]); + } + } + IF (EQ_32(R_sum_fx,R_sum_org_fx)) + { + BREAK; + } + + R_sum_org_fx = R_sum_fx; + } + } + + /* index comeback */ + FOR ( k = 0 ; k < band_num; k++ ) + { + j = index[k]; + move16(); + Rsubband_fx[add(j,start_band)] = R_temp_fx[k]; + move32(); + } + + return; + +} + +/*-------------------------------------------------------------------* + * BitAllocWB() + * + * WB bit allocation + *-------------------------------------------------------------------*/ + +Word16 BitAllocWB_fx( /* o : t Q0*/ + Word16 *y, /* i : norm of sub-vectors Q0*/ + Word16 B, /* i : number of available bits Q0*/ + Word16 N, /* i : number of sub-vectors Q0*/ + Word16 *R, /* o : bit-allocation indicator Q0*/ + Word16 *Rsubband_fx /* o : sub-band bit-allocation vector Q3*/ +) +{ + Word16 t_fx; + Word16 i, j, k, B1, B2, B3, B_saved; + Word16 Rsum_fx, Rsum_sub_fx[3]; + Word32 Ravg_sub_32_fx[3], R_diff_32_fx[2]; + Word16 factor_fx[2];/*Q13 */ + Word16 BANDS; + Word16 tmp,exp; + Word16 Rsum_sub_fx_tmp=0; /* initialize just to avoid compiler warning */ + Word32 L_tmp,L_tmp1; + Word32 Rsubband_buf[NB_SFM]; + + BANDS = N; + move16(); + if( GT_16(BANDS,SFM_N)) + { + BANDS = SFM_N; + move16(); + } + /* Init Rsubband to non-zero values for bands to be allocated bits */ + FOR (k = 0; k < BANDS; k++) + { + Rsubband_buf[k] = 2097152; + move32();/*Q21 */ + } + /* Calculate the norm sum and average of sub-band */ + Rsum_sub_fx[0] = 0; + move16(); + FOR ( j = 0; j < SFM_G1; j++ ) + { + if ( y[j] > 0 ) + { + Rsum_sub_fx_tmp = add(Rsum_sub_fx[0],y[j]); /*Q0 */ + } + if (y[j] > 0) + { + Rsum_sub_fx[0] = Rsum_sub_fx_tmp; + move16(); /*Q0 */ + } + } + Ravg_sub_32_fx[0] = L_mult(Rsum_sub_fx[0], 2048); + move32();/*Q16 0+15+1 //q15 1/16 =2048 */ + + Rsum_sub_fx[1] = 0; + move16(); + FOR ( j = SFM_G1; j < SFM_G1G2; j++ ) + { + if ( y[j] > 0 ) + { + Rsum_sub_fx_tmp = add(Rsum_sub_fx[1],y[j]); /*Q0 */ + } + if ( y[j] > 0 ) + { + Rsum_sub_fx[1] = Rsum_sub_fx_tmp; + move16();/*Q0 */ + } + } + Ravg_sub_32_fx[1] = L_mult(Rsum_sub_fx[1], 4096); /*16 0+15+1 //q15 1/8 =4096 */ + + Rsum_sub_fx[2] = 0; + move16(); + FOR ( j = SFM_G1G2; j < BANDS; j++ ) + { + if ( y[j] > 0 ) + { + Rsum_sub_fx_tmp = add(Rsum_sub_fx[2],y[j]); /*Q0 */ + } + if ( y[j] > 0 ) + { + Rsum_sub_fx[2] = Rsum_sub_fx_tmp; + move16();/*Q0 */ + } + } + tmp = div_s(1, BANDS-SFM_G1G2); /*Q15 */ + Ravg_sub_32_fx[2] = L_mult(Rsum_sub_fx[2], tmp); + move32();/*Q16 */ + + /* Bit allocation for every group */ + tmp = add(Rsum_sub_fx[0],Rsum_sub_fx[1]); + Rsum_fx = add(tmp,Rsum_sub_fx[2]);/*Q0 */ + + factor_fx[0] = 16384;/*Q13 move16(); */ + factor_fx[1] = 24576;/*Q13 move16(); */ + { + R_diff_32_fx[0] = L_sub(Ravg_sub_32_fx[0], Ravg_sub_32_fx[1]); + move32();/*Q16 */ + R_diff_32_fx[1] = L_sub(Ravg_sub_32_fx[1], Ravg_sub_32_fx[2]); + move32();/*Q16 */ + + test(); + IF ( LT_32(R_diff_32_fx[0],393216)&<_32(R_diff_32_fx[1],245760)) + { + IF(Rsum_fx == 0) + { + B1 = 0; + move16(); + B2 = 0; + move16(); + B3 = 0; + move16(); + } + ELSE + { + exp = norm_s(Rsum_fx); + tmp = shl(Rsum_fx,exp);/*Q(exp) */ + tmp = div_s(16384,tmp);/*Q(15+14-exp) */ + L_tmp1 = L_mult(B,Rsum_sub_fx[0]);/*Q1 */ + L_tmp = Mult_32_16(L_tmp1,tmp);/*Q(15-exp) */ + B1 = extract_h(L_shl(L_tmp,add(exp,1)));/*Q0 */ + test(); + if(GT_32(L_tmp1,L_mult(B1,Rsum_fx))&&GE_32(L_tmp1,L_mult(add(B1,1),Rsum_fx))) + { + B1 = add(B1,1); + } + L_tmp1 = L_mult(B,Rsum_sub_fx[1]);/*Q1 */ + L_tmp = Mult_32_16(L_tmp1,tmp);/*Q(15-exp) */ + B2 = extract_h(L_shl(L_tmp,add(exp,1)));/*Q0 */ + test(); + if(GT_32(L_tmp1,L_mult(B2,Rsum_fx))&&GE_32(L_tmp1,L_mult(add(B2,1),Rsum_fx))) + { + B2 = add(B2,1); + } + L_tmp1 = L_mult(B,Rsum_sub_fx[2]);/*Q1 */ + L_tmp = Mult_32_16(L_tmp1,tmp);/*Q(15-exp) */ + B3 = extract_h(L_shl(L_tmp,add(exp,1)));/*Q0 */ + test(); + if(GT_32(L_tmp1,L_mult(B3,Rsum_fx))&&GE_32(L_tmp1,L_mult(add(B3,1),Rsum_fx))) + { + B3 = add(B3,1); + } + } + IF ( GT_32(Ravg_sub_32_fx[2],786432)) + { + B_saved = 0; + move16(); + IF ( GT_16(B1,288)) + { + B_saved = sub(B1,288); + B1 = 288; + move16(); + } + + IF ( GT_16(B2,256)) + { + tmp = sub(B2,256); + B_saved = add(B_saved,tmp); + B2 = 256; + move16(); + } + + IF ( GT_16(B3,96)) + { + tmp = sub(B3,96); + B_saved = add(B_saved,tmp); + B3 = 96; + move16(); + } + + IF ( B_saved > 0 ) + { + IF ( EQ_16(B1,288)) + { + tmp = shr(B_saved,1); + B2 = add(B2,tmp); + tmp = sub(B,B1); + B3 = sub(tmp,B2); + } + ELSE + { + tmp = shr(B_saved,1); + B1 = add(B1,tmp); + IF ( EQ_16(B2,256)) + { + tmp = sub(B,B1); + B3 = sub(tmp,B2); + } + ELSE + { + tmp = sub(B,B1); + B2 = sub(tmp,B3); + } + } + } + } + + factor_fx[0] = 16384; + move16();/*Q13 */ + factor_fx[1] = 12288; + move16();/*Q13 */ + } + ELSE + { + IF(Rsum_fx == 0) + { + B1 = 0; + move16(); + B2 = 0; + move16(); + B3 = B; + move16(); + } + ELSE + { + exp = norm_s(Rsum_fx); + tmp = shl(Rsum_fx,exp);/*Q(exp) */ + tmp = div_s(16384,tmp);/*Q(15+14-exp) */ + L_tmp1 = L_mult(B,Rsum_sub_fx[0]);/*Q1 */ + L_tmp = Mult_32_16(L_tmp1,tmp);/*Q(15-exp) */ + B1 = extract_h(L_shl(L_tmp,add(exp,1)));/*Q0 */ + test(); + if(GT_32(L_tmp1,L_mult(B1,Rsum_fx))&&GE_32(L_tmp1,L_mult(add(B1,1),Rsum_fx))) + { + B1 = add(B1,1); + } + L_tmp1 = Mult_32_16(1975684956,shl(B,5));/*Q(31+5-15=21) */ + L_tmp1 = Mult_32_16(L_tmp1,shl(Rsum_sub_fx[1],7));/*Q(21+7-15=13) */ + L_tmp = Mult_32_16(L_tmp1,tmp);/*Q(27-exp) */ + B2 = extract_h(L_shl(L_tmp,sub(exp,11)));/*Q0 */ + test(); + if(GT_32(L_tmp1,L_shl(L_mult(B2,Rsum_fx),12))&&GE_32(L_add(L_tmp1,2),L_shl(L_mult(add(B2,1),Rsum_fx),12))) + { + B2 = add(B2,1); + } + tmp = sub(B,B1); + B3 = sub(tmp,B2); + } + } + } + + IF ( LT_16(Rsum_sub_fx[2],3)) + { + B2 = add(B2,B3); + B3 = 0; + move16(); + } + + /* Bit allocation in group */ + Bit_group_fx( y, 0, SFM_G1, B1, 5, Rsubband_buf, factor_fx); + Bit_group_fx( y, SFM_G1, SFM_G1G2, B2, 6, Rsubband_buf, factor_fx); + Bit_group_fx( y, SFM_G1G2, BANDS, B3, 7, Rsubband_buf, factor_fx); + FOR (i = 0; i < BANDS; i++) + { + Rsubband_fx[i] = extract_l(L_shr(Rsubband_buf[i], 18)); + } + + /* Calcuate total used bits and initialize R to be used for Noise Filling */ + L_tmp = L_deposit_l(0); + FOR( i = 0; i < N; i++) + { + L_tmp = L_add(L_tmp,Rsubband_buf[i]);/*Q21 */ + R[i] = extract_h(L_shr(Rsubband_buf[i],5));/*Q0 */ + } + t_fx = extract_h(L_shr(L_tmp, 5)); /*Q0 */ + + return (Word16)t_fx; + +} diff --git a/lib_com/bitallocsum_fx.c b/lib_com/bitallocsum_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..73dd2ef743f79d72653d11059624a7feeb2b34f6 --- /dev/null +++ b/lib_com/bitallocsum_fx.c @@ -0,0 +1,63 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ +#include +#include "options.h" /* Compilation switches */ +#include "cnst.h" /* Common constants */ +#include "prot_fx1.h" /* Function prototypes */ +#include "prot_fx2.h" /* Function prototypes */ + +/*-------------------------------------------------------------------------- + * bitallocsum_fx() + * + * Calculate the total number of bits allocated over frame + *--------------------------------------------------------------------------*/ +void bitallocsum_fx( + Word16 *R, /* i : bit-allocation vector Q0 */ + const Word16 nb_sfm, /* i : number of sub-vectors Q0 */ + Word16 *sum, /* o : total number of bits allocated Q0 */ + Word16 *Rsubband, /* o : rate per subband Q3 */ + const Word16 num_bits,/* i : number of bits Q0 */ + const Word16 length, /* i : length of spectrum (32 or 48 kHz samplerate) Q0 */ + const Word16 *sfmsize /* i : band length Q0 */ +) +{ + Word16 i; + Word16 total, tmp; + Word16 diff; + + total = (Word16)0; + move16(); + FOR (i = 0; i < nb_sfm; i++) + { + tmp = extract_l(L_mult0(R[i], sfmsize[i])); + Rsubband[i] = shl(tmp, 3); + move16(); + total = add(total, tmp); + } + *sum = total; + + IF ( LE_16(length, L_FRAME32k)) + { + diff = sub(num_bits, *sum); + i = (Word16)0; + move16(); + WHILE ( diff > 0 ) + { + IF ( R[i] > 0 ) + { + Rsubband[i] = add(Rsubband[i], 8); + move16(); + diff = sub(diff, 1); + *sum = add(*sum, 1); + } + i = add(i, 1); + if ( GE_16(i, nb_sfm)) + { + i = (Word16)0; + move16(); + } + } + } + return; +} diff --git a/lib_com/bits_alloc.c b/lib_com/bits_alloc.c index ec251f1870803ffde90824fc074ab3ae83594609..02cd297cdd139844417d5711c1a873349697a9ff 100644 --- a/lib_com/bits_alloc.c +++ b/lib_com/bits_alloc.c @@ -59,12 +59,12 @@ typedef enum } PRM_TYPES; /*-------------------------------------------------------------------* - * BITS_ALLOC_init_config_acelp() + * BITS_ALLOC_init_config_acelp_IVAS() * * initial configuration for Mode 2 ACELP *--------------------------------------------------------------------*/ -void BITS_ALLOC_init_config_acelp( +void BITS_ALLOC_init_config_acelp_IVAS( const int32_t bit_rate, const int16_t narrowBand, const int16_t nb_subfr, @@ -122,12 +122,12 @@ void BITS_ALLOC_init_config_acelp( } /*-------------------------------------------------------------------* - * BITS_ALLOC_config_acelp() + * BITS_ALLOC_config_acelp_IVAS() * * configure all Mode 2 ACELP coder types and allocate the bits *--------------------------------------------------------------------*/ -int16_t BITS_ALLOC_config_acelp( +int16_t BITS_ALLOC_config_acelp_IVAS( const int16_t bits_frame, /* i : remaining bit budget for the frame */ const int16_t coder_type, /* i : acelp coder type */ ACELP_config *acelp_cfg, /* i/o: configuration structure of ACELP */ @@ -510,14 +510,14 @@ static ivas_error acelp_FCB_allocator( /*-------------------------------------------------------------------* - * config_acelp1() + * config_acelp1_IVAS() * * Configure ACELP bit allocation * - should be in range of <6700; 24350> for ACELP@12.8kHz * - per channel bitrate minimum is 13250 kbps for ACELP@16kHz *--------------------------------------------------------------------*/ -ivas_error config_acelp1( +ivas_error config_acelp1_IVAS( const int16_t enc_dec, /* i : encoder/decoder flag */ const int32_t total_brate, /* i : total bitrate */ const int32_t core_brate_inp, /* i : core bitrate */ @@ -1422,13 +1422,13 @@ static int16_t allocate_unused( /*-------------------------------------------------------------------* - * set_ACELP_flag() + * set_ACELP_flag_IVAS() * * set ACELP@16kHz flag *--------------------------------------------------------------------*/ /*! r: ACELP16k flag */ -int16_t set_ACELP_flag( +int16_t set_ACELP_flag_IVAS( const int16_t element_mode, /* i : element mode */ const int32_t element_brate, /* i : element bitrate */ const int32_t total_brate, /* i : total bitrate per channel */ diff --git a/lib_com/bits_alloc_fx.c b/lib_com/bits_alloc_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..6e7e49ed0bd251d6b2899ebaab0a0df3edbd7438 --- /dev/null +++ b/lib_com/bits_alloc_fx.c @@ -0,0 +1,1636 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ +#include +#include +#include +#include "options.h" +#include "prot_fx1.h" +#include "prot_fx2.h" +#include "basop_util.h" +#include "rom_com.h" + +#include "ivas_cnst.h" +#include "ivas_rom_com.h" +#ifndef SWAP +#define SWAP( a, b ) \ + { \ + tempr = ( a ); \ + ( a ) = ( b ); \ + ( b ) = tempr; \ + } +#endif + /*-------------------------------------------------------------------* + * Local function prototypes + *--------------------------------------------------------------------*/ +static Word16 BITS_ALLOC_adjust_acelp_fixed_cdk(const Word16 bits_frame, Word16* fixed_cdk_index, const Word16 nb_subfr ); +static Word16 BITS_ALLOC_adjust_generic(const Word16 bits_frame, Word16* fixed_cdk_index, const Word16 nb_subfr, const Word16* pulseconfigbits, const Word16 pulseconfig_size); +static Word16 allocate_unused(const Word32 core_brate, const Word16 coder_type, const Word16 unused_bits, const Word16 nb_prm, const Word16 subfr, const Word16 prm_type, Word16* prm_bit_mode); + +typedef enum +{ + GAINSPRM = 0x0, + PITCHPRM = 0x1, + MID_LSFSPRM = 0x3, + LSFPRM = 0x4 +} PRM_TYPES; + +/* + * function BITS_ALLOC_init_config_acelp() + * + * description: initial configuration for ACELP + * + * return: void + */ +void BITS_ALLOC_init_config_acelp( + const Word32 bit_rate, + const Word8 narrowBand, + const Word16 nb_subfr, + ACELP_config *pConfigAcelp /*o: configuration structure of ACELP*/ +) +{ + Word8 rate_mode_index; + + + move16(); + move16(); + move16(); + rate_mode_index=(bit_rate > ACELP_9k60); + + pConfigAcelp->mode_index=rate_mode_index; + + + /*LPC: midLpc should be swithced off?*/ + pConfigAcelp->midLpc_enable = 1; + move16(); + + /*ACELP ICB config*/ + test(); + IF( (rate_mode_index==0) || narrowBand != 0 ) + { + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + pConfigAcelp->pre_emphasis = 1; + pConfigAcelp->formant_enh = 1; + pConfigAcelp->formant_enh_num = FORMANT_SHARPENING_G1; + pConfigAcelp->formant_enh_den = FORMANT_SHARPENING_G2; + pConfigAcelp->formant_tilt = 0; + pConfigAcelp->voice_tilt = 0; + } + ELSE + { + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + pConfigAcelp->pre_emphasis = 0; + pConfigAcelp->formant_enh = 1; + pConfigAcelp->formant_enh_num = FORMANT_SHARPENING_G1; + pConfigAcelp->formant_enh_den = FORMANT_SHARPENING_G2; + pConfigAcelp->formant_tilt = 1; + pConfigAcelp->voice_tilt = 1; + } + + /*Wide band @ 16kHz*/ + IF ( EQ_16(nb_subfr,NB_SUBFR16k)) + { + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + pConfigAcelp->pre_emphasis = 1; + pConfigAcelp->formant_enh = 1; + pConfigAcelp->formant_enh_num = FORMANT_SHARPENING_G1_16k; + pConfigAcelp->formant_enh_den = FORMANT_SHARPENING_G2_16k; + pConfigAcelp->formant_tilt = 0; + pConfigAcelp->voice_tilt = 2; + } + +} + + +/* + * function BITS_ALLOC_config_acelp() + * + * description: configure all Mode 2 ACELP coder types and allocate the bits + * + * return: bit demand + */ +Word16 BITS_ALLOC_config_acelp( + const Word16 bits_frame, /* i: remaining bit budget for the frame*/ + const Word16 coder_type, /* i: acelp coder type*/ + ACELP_config *pConfigAcelp, /* i/o: configuration structure of ACELP*/ + const Word16 narrowBand, /* i : narrowband flag */ + const Word16 nb_subfr /* i : number of subframes */ +) +{ + Word16 mode_index; + Word16 band_index; + Word16 i; + Word16 remaining_bits, bits; + + + + move16(); + move16(); + move16(); + mode_index = pConfigAcelp->mode_index; + band_index = (narrowBand==0); + bits=0; + + IF ( band_index==0 ) + { + move16(); + pConfigAcelp->formant_enh = 1; + if(EQ_16(coder_type,INACTIVE)) + { + move16(); + pConfigAcelp->formant_enh = 0; + } + } + + IF ( s_and((Word16)EQ_16(band_index,1),(Word16)EQ_16(nb_subfr,4))) + { + IF(EQ_16(coder_type,INACTIVE)) + { + pConfigAcelp->pre_emphasis = 0; + move16(); + pConfigAcelp->formant_enh = 0; + move16(); + pConfigAcelp->formant_enh_num = FORMANT_SHARPENING_G1_16k; + move16(); + pConfigAcelp->voice_tilt = 1; + move16(); + pConfigAcelp->formant_tilt = 1; + move16(); + } + ELSE + { + pConfigAcelp->pre_emphasis = 1; + move16(); + pConfigAcelp->formant_enh = 1; + move16(); + pConfigAcelp->formant_enh_num = FORMANT_SHARPENING_G1; + move16(); + pConfigAcelp->voice_tilt = 0; + move16(); + pConfigAcelp->formant_tilt = 0; + move16(); + } + } + IF (EQ_16(coder_type,UNVOICED)) + { + IF(EQ_16(ACELP_GAINS_MODE[mode_index][band_index][coder_type], 6)) + { + pConfigAcelp->pitch_sharpening = 0; + move16(); + pConfigAcelp->phase_scrambling = 1; + move16(); + } + ELSE + { + pConfigAcelp->pitch_sharpening = 0; + move16(); + pConfigAcelp->phase_scrambling = 0; + move16(); + } + } + ELSE + { + pConfigAcelp->pitch_sharpening = 1; + move16(); + pConfigAcelp->phase_scrambling = 0; + move16(); + } + + IF(GT_16(coder_type,ACELP_MODE_MAX)) /* keep pitch sharpening for RF_ALLPRED mode */ + { + pConfigAcelp->pitch_sharpening = 0; + pConfigAcelp->phase_scrambling = 0; + } + + /*Allocate bits and different modes*/ + move16(); + pConfigAcelp->bpf_mode=ACELP_BPF_MODE[mode_index][band_index][coder_type]; + bits = add(bits, ACELP_BPF_BITS[pConfigAcelp->bpf_mode]); + + move16(); + move16(); + pConfigAcelp->nrg_mode=ACELP_NRG_MODE[mode_index][band_index][coder_type]; + pConfigAcelp->nrg_bits=ACELP_NRG_BITS[pConfigAcelp->nrg_mode]; + bits = add(bits, pConfigAcelp->nrg_bits); + + move16(); + pConfigAcelp->ltp_mode=ACELP_LTP_MODE[mode_index][band_index][coder_type]; + + move16(); + pConfigAcelp->ltp_bits=0; + + move16(); + pConfigAcelp->ltf_mode=ACELP_LTF_MODE[mode_index][band_index][coder_type]; + + move16(); + pConfigAcelp->ltf_bits=ACELP_LTF_BITS[pConfigAcelp->ltf_mode]; + if ( s_and((Word16)EQ_16(nb_subfr,5),(Word16)EQ_16(pConfigAcelp->ltf_bits,4))) + { + pConfigAcelp->ltf_bits = add(pConfigAcelp->ltf_bits,1); + } + bits = add(bits,pConfigAcelp->ltf_bits); + + + FOR ( i=0; igains_mode[i] = ACELP_GAINS_MODE[mode_index][band_index][coder_type]; + move16(); + + /* skip subframe 1, 3 gain encoding, and use from subframe 0, and 3, respectively */ + test(); + test(); + IF(GE_16(coder_type,ACELP_MODE_MAX)&&(EQ_16(i,1)||EQ_16(i,3))) + { + pConfigAcelp->gains_mode[i] = 0; + } + + bits = add(bits, ACELP_GAINS_BITS[pConfigAcelp->gains_mode[i]]); + + move16(); + bits = add(bits, ACELP_LTP_BITS_SFR[pConfigAcelp->ltp_mode][i]); + pConfigAcelp->ltp_bits= add( pConfigAcelp->ltp_bits,ACELP_LTP_BITS_SFR[pConfigAcelp->ltp_mode][i]); + } + + /*Innovation*/ + + if ( LT_16(bits_frame,bits)) + { + printf("Warning: bits per frame too low\n"); + return -1; + } + + IF( EQ_16(coder_type,RF_ALLPRED)) + { + set16_fx(pConfigAcelp->fixed_cdk_index, -1, nb_subfr); + } + ELSE IF ( EQ_16(coder_type,RF_GENPRED)) + { + pConfigAcelp->fixed_cdk_index[0] = 0; /* 7 bits */ + pConfigAcelp->fixed_cdk_index[1] = -1; + pConfigAcelp->fixed_cdk_index[2] = 0; /* 7 bits */ + pConfigAcelp->fixed_cdk_index[3] = -1; + pConfigAcelp->fixed_cdk_index[4] = -1; + bits = add(bits,14); + } + ELSE IF( EQ_16(coder_type,RF_NOPRED)) + { + set16_fx(pConfigAcelp->fixed_cdk_index, 0, nb_subfr); + bits = add(bits,28); + } + ELSE + { + bits = add(bits, BITS_ALLOC_adjust_acelp_fixed_cdk(sub(bits_frame,bits), pConfigAcelp->fixed_cdk_index, nb_subfr )); + } + + remaining_bits = sub(bits_frame, bits); + + /*Sanity check*/ + if (remaining_bits<0) + { + move16(); + bits = -1; + } + + + return(bits); +} + + +static Word16 BITS_ALLOC_adjust_generic( + const Word16 bits_frame, /*i: bit budget*/ + Word16 *fixed_cdk_index, + const Word16 nb_subfr, + const Word16 *pulseconfigbits, + const Word16 pulseconfig_size +) +{ + Word16 bits_subframe2, inb_subfr; + Word16 sfr, k, bitsused, bits_currsubframe; + + bits_subframe2 = bits_frame; + move16(); + inb_subfr = 8192/*1.0f/NB_SUBFR Q15*/; + move16(); + if ( EQ_16(nb_subfr,NB_SUBFR16k)) + { + inb_subfr = 6554/*1.0f/NB_SUBFR16k Q15*/; + move16(); + } + + IF ( LT_16(bits_subframe2, i_mult2(pulseconfigbits[0], nb_subfr))) /* not in final code - not instrumented */ + { + return add(bits_frame,1); /* Not enough bits for lowest mode. -> trigger alarm*/ + } + + /* search cdk-index for first subframe */ + FOR (k=0; k bits_subframe2) + { + k = sub(k,1); /* previous mode did not exceed bit-budget */ + BREAK; + } + } + + if (i_mult2(pulseconfigbits[k], nb_subfr) > bits_subframe2) + { + k = sub(k,1); /* previous mode did not exceed bit-budget */ + } + + move16(); + fixed_cdk_index[0] = k; + bitsused = i_mult2(pulseconfigbits[k], nb_subfr); + + FOR (sfr=1; sfr < nb_subfr; sfr++) + { + /*bits_currsubframe = (int)(((float)sfr+1.0f)*bits_subframe) - bitsused;*/ + bits_currsubframe = sub(add(i_mult2(sfr, bits_subframe2), bits_subframe2), bitsused); + + /* try increasing mode while below threshold */ + WHILE ( (LT_16(k, pulseconfig_size-1))&&(LE_16(i_mult2(pulseconfigbits[add(k,1)],nb_subfr),bits_currsubframe))) + { + test(); + k = add(k,1); + } + + /* try decreasing mode until below threshold */ + WHILE (i_mult2(pulseconfigbits[k], nb_subfr) > bits_currsubframe) + { + k = sub(k,1); + + IF (k == 0) + { + BREAK; + } + } + + /* store mode */ + move16(); + fixed_cdk_index[sfr] = k; + bitsused = add(bitsused, i_mult2(pulseconfigbits[k], nb_subfr)); + } + + return mult_r(bitsused, inb_subfr); +} + +static Word16 BITS_ALLOC_adjust_acelp_fixed_cdk( + const Word16 bits_frame, /*i: bit budget*/ + Word16 *fixed_cdk_index, + const Word16 nb_subfr +) +{ + Word16 bitsused; + + + bitsused = BITS_ALLOC_adjust_generic(bits_frame, fixed_cdk_index, nb_subfr, ACELP_CDK_BITS, ACELP_FIXED_CDK_NB); + + + return bitsused; +} + +/*#ifdef IVAS_CODE Below basop operators are missing */ +/*-------------------------------------------------------------------* + * fcb_table() + * + * Selection of fixed innovation codebook bitbudget table + *--------------------------------------------------------------------*/ + +static Word16 fcb_table( + const Word16 n, + const Word16 L_subfr) +{ + Word16 out; + //PMT("Not floating point computation, but fixed point operator are still missing ") + + out = PulseConfTable[n].bits; + if (L_subfr > L_SUBFR) + { + out = fast_FCB_bits_2sfr[n]; + } + + return (out); +} + +/*-------------------------------------------------------------------* + * acelp_FCB_allocator() + * + * Routine to allocate fixed innovation codebook bit-budget + *--------------------------------------------------------------------*/ + +static ivas_error acelp_FCB_allocator( + Word16* nBits, /* i/o: available bit-budget */ + Word16 fixed_cdk_index[], /* o : codebook index */ + Word16 nb_subfr, /* i : number of subframes */ + const Word16 L_subfr, /* i : subframe length */ + const Word16 coder_type, /* i : coder type */ + const Word16 tc_subfr, /* i : TC subframe index */ + const Word16 fix_first /* i : flag to indicate whether the first subframe bit-budget was fixed */ +) +{ + Word16 cdbk, sfr, step; + Word16 nBits_tmp; + Word16* p_fixed_cdk_index; + Word16 max_n; + ivas_error error; + //PMT("Not floating point computation, but fixed point operator are still missing ") + + error = IVAS_ERR_OK; + + cdbk = coder_type; /* just to avoid warning when DEBUGGING is deactivated */ + + p_fixed_cdk_index = fixed_cdk_index; + + /* TRANSITION coding: first subframe bit-budget was already fixed, glottal pulse not in the first subframe */ + if (tc_subfr >= L_SUBFR && fix_first) + { + Word16 i; + + for (i = 0; i < nb_subfr; i++) + { + *nBits -= ACELP_FIXED_CDK_BITS(fixed_cdk_index[i]); + } + return error; + } + + /* TRANSITION coding: first subframe bit-budget was already fixed, glottal pulse in the first subframe */ + sfr = 0; + if (fix_first) + { + *nBits -= ACELP_FIXED_CDK_BITS(fixed_cdk_index[0]); + sfr = 1; + p_fixed_cdk_index++; + nb_subfr = 3; + } + + /* distribute the bit-budget equally between subframes */ + if (L_subfr > L_SUBFR) /* access fast_FCB_bits_2sfr */ + { + max_n = 6; + } + else + { + max_n = ACELP_FIXED_CDK_NB; + } + for (cdbk = 0; cdbk < max_n; cdbk++) + { + if (fcb_table(cdbk, L_subfr) * nb_subfr > *nBits) + { + break; + } + } + cdbk--; + +#if defined DEBUGGING + if (cdbk < 0 && coder_type != TRANSITION) + { + return IVAS_ERROR(IVAS_ERR_INTERNAL_FATAL, "Error: Too low bit-budget for fixed innovation codebook (frame = %d). Exiting! \n", frame); + } + if ((L_subfr == L_SUBFR && cdbk >= ACELP_FIXED_CDK_NB) || (L_subfr == 2 * L_SUBFR && fcb_table(cdbk, L_subfr) == 128 /*stop value*/)) + { + return IVAS_ERROR(IVAS_ERR_INTERNAL_FATAL, "Error: Too high bit-budget for fixed innovation codebook (frame = %d). Exiting! \n", frame); + } +#endif + + set16_fx(p_fixed_cdk_index, cdbk, nb_subfr); + nBits_tmp = 0; + if (cdbk >= 0) + { + nBits_tmp = fcb_table(cdbk, L_subfr); + } + else + { + nBits_tmp = 0; + } + *nBits -= nBits_tmp * nb_subfr; + + /* try to increase the FCB bit-budget of the first subframe(s) */ + if (cdbk < ACELP_FIXED_CDK_NB - 1) + { + step = fcb_table(cdbk + 1, L_subfr) - nBits_tmp; + while (*nBits >= step) + { + (*p_fixed_cdk_index)++; + *nBits -= step; + p_fixed_cdk_index++; + } + + /* try to increase the FCB of the first subframe in cases when the next step is lower than the current step */ + step = fcb_table(fixed_cdk_index[sfr] + 1, L_subfr) - fcb_table(fixed_cdk_index[sfr], L_subfr); + if (*nBits >= step && cdbk >= 0) + { + fixed_cdk_index[sfr]++; + *nBits -= step; + + if (*nBits >= step && fixed_cdk_index[sfr + 1] == fixed_cdk_index[sfr] - 1) + { + sfr++; + fixed_cdk_index[sfr]++; + *nBits -= step; + } + } + } + /* TRANSITION coding: allocate highest FCBQ bit-budget to the subframe with the glottal-shape codebook */ + if (tc_subfr >= L_SUBFR) + { + Word16 tempr; + + SWAP(fixed_cdk_index[0], fixed_cdk_index[tc_subfr / L_SUBFR]); + + /* TRANSITION coding: allocate second highest FCBQ bit-budget to the last subframe */ + if (tc_subfr / L_SUBFR < nb_subfr - 1) + { + SWAP(fixed_cdk_index[(tc_subfr - L_SUBFR) / L_SUBFR], fixed_cdk_index[nb_subfr - 1]); + } + } + + /* when subframe length > L_SUBFR, number of bits instead of codebook index is signalled */ + if (L_subfr > L_SUBFR) + { + Word16 i, j; + for (i = 0; i < nb_subfr; i++) + { + j = fixed_cdk_index[i]; + fixed_cdk_index[i] = fast_FCB_bits_2sfr[j]; + } + } + + return error; +} + + +/*-------------------------------------------------------------------* + * config_acelp1() + * + * Configure ACELP bit allocation + * - should be in range of <6700; 24350> for ACELP@12.8kHz + * - per channel bitrate minimum is 13250 kbps for ACELP@16kHz + *--------------------------------------------------------------------*/ + +ivas_error config_acelp1( + const Word16 enc_dec, /* i : encoder/decoder flag */ + const Word32 total_brate, /* i : total bitrate */ + const Word32 core_brate_inp, /* i : core bitrate */ + const Word16 core, /* i : core */ + const Word16 extl, /* i : extension layer */ + const Word32 extl_brate, /* i : extension layer bitrate */ + const Word16 L_frame, /* i : frame length at internal Fs */ + const Word16 GSC_noisy_speech, /* i : GSC on SWB noisy speech flag */ + ACELP_config* acelp_cfg, /* i : ACELP bit-allocation */ + const Word16 signalling_bits, /* i : number of signalling bits */ + const Word16 coder_type, /* i : coder type */ + const Word16 tc_subfr, /* i : TC subfr ID */ + const Word16 tc_call, /* i : TC call number (0,1,2,3,5(DEC)) */ + Word16* nBits_es_Pred, /* o : number of bits for Es_pred Q */ + Word16* unbits, /* o : number of unused bits */ + const Word16 element_mode, /* i : element mode */ + Word16* uc_two_stage_flag, /* o : flag undicating two-stage UC */ + const Word16 tdm_lp_reuse_flag, /* i : LPC reuse flag (can be 1 only with secondary channel */ + const Word16 tdm_low_rate_mode, /* i : secondary channel low rate mode flag */ + const Word16 idchan, /* i : stereo channel ID */ + const Word16 active_cnt, /* i : Active frame counter */ + const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag*/ + const Word16 tdm_LRTD_flag, /* i : LRTD stereo mode flag */ + const Word16 GSC_IVAS_mode /* i : GSC IVAS mode */ +) +{ + Word16 i, bits, nb_subfr; + Word16 flag_hardcoded, coder_type_sw, fix_first; + Word32 core_brate; +#ifdef DEBUGGING + Word32 core_brate_inpI = core_brate_inp; +#ifdef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING + (void)active_cnt; +#endif +#endif + ivas_error error; + + error = IVAS_ERR_OK; + //PMT("Not floating point computation, but fixed point operator are still missing ") + /*-----------------------------------------------------------------* + * Set the flag indicating two-stage Unvoiced (UC) frame + *-----------------------------------------------------------------*/ + + *uc_two_stage_flag = 0; + if (coder_type == UNVOICED) + { + if (total_brate >= MIN_UNVOICED_TWO_STAGE_BRATE && element_mode > EVS_MONO && (idchan == 0 || ((total_brate >= 8500 || extl_brate == 0) && tdm_LRTD_flag == 1))) + { + *uc_two_stage_flag = 1; + } + } + + /*-----------------------------------------------------------------* + * Set the number of subframes + *-----------------------------------------------------------------*/ + + if (L_frame == L_FRAME) + { + nb_subfr = NB_SUBFR; + +#if defined DEBUGGING + if (((core_brate_inp < 5900 && coder_type > UNVOICED) && !(core_brate_inp < MIN_TC_BRATE && coder_type == TRANSITION)) && !(idchan > 0 && element_mode == IVAS_CPE_TD) && !(element_mode == IVAS_SCE && tdm_low_rate_mode)) + { + return IVAS_ERROR(IVAS_ERR_INTERNAL_FATAL, "Error: Too low bitrate (%d bps) for ACELP@12k8 in frame %d. Exiting!\n", core_brate_inpI, frame); + } + + if (core_brate_inp > ACELP_12k8_HIGH_LIMIT && core == ACELP_CORE) + { + return IVAS_ERROR(IVAS_ERR_INTERNAL_FATAL, "Error: Too high bitrate (%d bps) for ACELP@12k8 in frame %d. Exiting!\n", core_brate_inpI, frame); + } +#endif + } + else /* L_frame == L_FRAME16k */ + { + nb_subfr = NB_SUBFR16k; + +#if defined DEBUGGING + if (core_brate_inp < ACELP_16k_LOW_LIMIT && core == ACELP_CORE) + { + return IVAS_ERROR(IVAS_ERR_INTERNAL_FATAL, "Error: Too low bitrate (%d bps) for ACELP@16k in frame %d. Exiting!\n", core_brate_inpI, frame); + } +#endif + } + + coder_type_sw = coder_type; + if (core != ACELP_CORE) + { + /* used in acelp_core_switch_enc() */ + nb_subfr = 1; + if (L_frame == L_FRAME) + { + coder_type_sw = TRANSITION; + } + } + + /*-----------------------------------------------------------------* + * Check if the core_brate is hard coded (to keep BE for mono core) or not + *-----------------------------------------------------------------*/ + + flag_hardcoded = 0; + i = 0; + + while (i < SIZE_BRATE_INTERMED_TBL) + { + if (core_brate_inp == brate_intermed_tbl[i]) + { + flag_hardcoded = 1; + break; + } + + if (core_brate_inp < brate_intermed_tbl[i]) + { + flag_hardcoded = 0; + break; + } + + i++; + } + + if (element_mode == IVAS_CPE_TD && coder_type == AUDIO && + core_brate_inp <= STEREO_GSC_BIT_RATE_ALLOC && brate_intermed_tbl[i] == ACELP_9k60) /* Bit allocation should be mapped to 8 kb/s instead of 9.6 kb/s in this case */ + { + i--; + } + + core_brate = brate_intermed_tbl[i]; + + if (element_mode > EVS_MONO) + { + flag_hardcoded = 0; /* use automatic and flexible ACELP bit-budget allocation */ + } + + if (core != ACELP_CORE && element_mode == EVS_MONO) /* needed for mode1 core switching in EVS mono */ + { + flag_hardcoded = 1; + } + + /*-----------------------------------------------------------------* + * ACELP bit allocation + *-----------------------------------------------------------------*/ + + if (!(coder_type == TRANSITION && tc_subfr != -1) || enc_dec == DEC) + { + /* Set the bit-budget */ + bits = (Word16)(core_brate_inp / FRAMES_PER_SEC); + + if (coder_type == TRANSITION && enc_dec == DEC && tc_call == 1) + { + bits += *nBits_es_Pred; /* equalize for 4th signaling bit estimated at the encoder in TC_0_192 */ + } + + /* Subtract signalling bits */ + if (enc_dec == DEC && idchan == 1 && element_mode > EVS_MONO) + { + bits -= TDM_SIGNAL_BITS_READ_FROM_THE_END_OF_BS; + + if (tdm_LRTD_flag == 1) + { + bits += STEREO_BITS_TCA; + } + + /* subtract TBE/BWE flag */ + if (extl_brate > 0 && (extl == WB_TBE || extl == SWB_TBE || extl == FB_TBE || extl == WB_BWE || extl == SWB_BWE || extl == FB_BWE)) + { + bits--; + } + } + else + { + /* Subtract signalling bits */ + bits -= signalling_bits; + } + + if (extl_brate > 0 && (extl == WB_TBE || extl == SWB_TBE || extl == FB_TBE || extl == WB_BWE || extl == SWB_BWE || extl == FB_BWE)) + { + /* extension layer signalling bit is counted in the extension layer bitbudget */ + bits++; + } + + /*-----------------------------------------------------------------* + * LSF Q bit-budget + *-----------------------------------------------------------------*/ + + if (!tdm_lp_reuse_flag || idchan == 0) + { + /* LSF Q bit-budget */ + acelp_cfg->lsf_bits = LSF_bits_tbl[LSF_BIT_ALLOC_IDX_fx(core_brate, coder_type)]; + + if (!flag_hardcoded) + { + if (L_frame == L_FRAME) + { + if (element_mode == IVAS_SCE && tdm_low_rate_mode) + { + acelp_cfg->lsf_bits = LSF_bits_tbl[LSF_BIT_ALLOC_IDX_fx(core_brate, coder_type)]; + } + else if ((total_brate < 7200 || coder_type == INACTIVE || coder_type == AUDIO) && idchan == 1) + { + /* TD stereo, secondary channel: do nothing */ + acelp_cfg->lsf_bits = LSF_bits_tbl[LSF_BIT_ALLOC_IDX_fx(core_brate, coder_type)]; + } + else if (element_mode > EVS_MONO && coder_type == AUDIO && brate_intermed_tbl[i] < ACELP_9k60) + { + /* primary channel: do nothing */ + } + else if (element_mode > EVS_MONO && coder_type == AUDIO /*&& brate_intermed_tbl[i] >= ACELP_9k60*/) + { + acelp_cfg->lsf_bits = 42; + } + else if (total_brate <= 9600 || coder_type == UNVOICED) + { + acelp_cfg->lsf_bits = 31; + } + else if (total_brate <= 20000) + { + acelp_cfg->lsf_bits = 36; + } + else + { + acelp_cfg->lsf_bits = 41; + } + } + else /* L_frame == L_FRAME16k */ + { + acelp_cfg->lsf_bits = 41; + } + } + + bits -= acelp_cfg->lsf_bits; + + /* mid-LSF Q bit-budget */ + acelp_cfg->mid_lsf_bits = mid_LSF_bits_tbl[LSF_BIT_ALLOC_IDX_fx(core_brate, coder_type)]; + + if (element_mode > EVS_MONO && coder_type == AUDIO /*&& brate_intermed_tbl[i] < ACELP_9k60*/) + { + acelp_cfg->mid_lsf_bits = 5; + /* primary channel: do nothing */ + } + + bits -= acelp_cfg->mid_lsf_bits; + } +#ifdef LSF_RE_USE_SECONDARY_CHANNEL + else if (tdm_lp_reuse_flag == 1 && idchan == 1 && active_cnt != 1 ) + { + bits -= TDM_IC_LSF_PRED_BITS; + } +#endif + /* gain Q bit-budget - part 1 */ + if ((coder_type != UNVOICED && coder_type != AUDIO && coder_type != INACTIVE && !(core_brate <= ACELP_8k00 && coder_type != TRANSITION)) || (coder_type == INACTIVE && total_brate > MAX_GSC_INACTIVE_BRATE)) + { + *nBits_es_Pred = Es_pred_bits_tbl[BIT_ALLOC_IDX_fx(core_brate, coder_type, -1, -1)]; + bits -= *nBits_es_Pred; + } + else if (*uc_two_stage_flag) + { + *nBits_es_Pred = 4; + bits -= *nBits_es_Pred; + } + } + else + { + bits = *unbits; + } + + if (coder_type == TRANSITION && tc_call == 0) + { + *unbits = bits; + return error; + } + + /*-----------------------------------------------------------------* + * Low-rate mode - bits are allocated in tdm_low_rate_enc() + *-----------------------------------------------------------------*/ + + if (element_mode == IVAS_SCE && tdm_low_rate_mode) + { + acelp_cfg->FEC_mode = 0; + acelp_cfg->ltf_mode = FULL_BAND; + *nBits_es_Pred = 0; + *unbits = 0; + acelp_cfg->ubits = 0; + + return error; + } + + /*-----------------------------------------------------------------* + * Supplementary information for FEC + *-----------------------------------------------------------------*/ + + acelp_cfg->FEC_mode = 0; + if (core_brate >= ACELP_11k60 && (idchan == 0 || element_mode == EVS_MONO)) + { + acelp_cfg->FEC_mode = 1; + + if (coder_type > UNVOICED && coder_type < AUDIO && coder_type != VOICED) + { + bits -= FEC_BITS_CLS; + } + + if (coder_type != TRANSITION) + { + if (total_brate >= ACELP_16k40) + { + acelp_cfg->FEC_mode = 2; + + if (coder_type > UNVOICED && coder_type < AUDIO) + { + bits -= FEC_BITS_ENR; + } + } + + if (total_brate >= ACELP_32k) + { + acelp_cfg->FEC_mode = 3; + + if (coder_type > UNVOICED && coder_type < AUDIO) + { + bits -= FEC_BITS_POS; + } + } + } + } + + /*-----------------------------------------------------------------* + * LP filtering of the adaptive excitation + *-----------------------------------------------------------------*/ + + if (idchan > 0 && element_mode > EVS_MONO) + { + acelp_cfg->ltf_mode = FULL_BAND; + } + else if (coder_type == UNVOICED) + { + acelp_cfg->ltf_mode = FULL_BAND; + } + else if ((coder_type == GENERIC || coder_type == TRANSITION) && core_brate < ACELP_11k60) + { + acelp_cfg->ltf_mode = LOW_PASS; + } + else if (core_brate >= ACELP_11k60 && (coder_type != AUDIO && !(coder_type == INACTIVE && L_frame == L_FRAME))) + { + if (coder_type == INACTIVE && L_frame == L_FRAME16k && total_brate <= MAX_GSC_INACTIVE_BRATE) /* GSC Inactive @16kHz */ + { + acelp_cfg->ltf_mode = FULL_BAND; + } + else + { + acelp_cfg->ltf_mode = NORMAL_OPERATION; + if (coder_type != TRANSITION) + { + bits -= nb_subfr; + } + } + } + else + { + acelp_cfg->ltf_mode = FULL_BAND; + } + + /*-----------------------------------------------------------------* + * UC bit-budget + *-----------------------------------------------------------------*/ + + if (((coder_type == UNVOICED && !(*uc_two_stage_flag)) || (coder_type == INACTIVE && core_brate <= ACELP_9k60)) && (idchan == 0 || element_mode == EVS_MONO)) + { + bits -= NBITS_NOISENESS; /* noiseness */ + } + if (coder_type == UNVOICED && !(*uc_two_stage_flag)) + { + bits -= (3 * NB_SUBFR); /* tilt factor */ + } + + /*-----------------------------------------------------------------* + * TC bit-budget + *-----------------------------------------------------------------*/ + + fix_first = 0; + if (coder_type == TRANSITION) + { + if (tc_call == 2) + { + fix_first = 1; + } + + /* TC signalling */ + if (L_frame == L_FRAME) + { + if (tc_subfr == TC_0_0) + { + if (enc_dec == ENC) + { + bits -= 1; /* TC signalling */ + } + + if (acelp_cfg->ltf_mode == NORMAL_OPERATION) + { + bits -= 3; /* LP filtering flag */ + } + } + else if (tc_subfr == TC_0_64) + { + if (enc_dec == ENC) + { + bits -= 4; /* TC signalling */ + } + + if (acelp_cfg->ltf_mode == NORMAL_OPERATION) + { + bits -= 3; /* LP filtering flag */ + } + } + else if (tc_subfr == TC_0_128) + { + if (enc_dec == ENC) + { + bits -= 4; /* TC signalling */ + } + + if (acelp_cfg->ltf_mode == NORMAL_OPERATION) + { + bits -= 2; /* LP filtering flag */ + } + } + else if (tc_subfr == TC_0_192) + { + if (enc_dec == ENC) + { + bits -= 3; /* TC signalling */ + } + + if (acelp_cfg->ltf_mode == NORMAL_OPERATION) + { + bits -= 1; /* LP filtering flag */ + } + } + else if (tc_subfr == L_SUBFR) + { + if (enc_dec == ENC) + { + bits -= 3; /* TC signalling */ + } + + if (acelp_cfg->ltf_mode == NORMAL_OPERATION) + { + bits -= (L_FRAME - tc_subfr - L_SUBFR) / L_SUBFR; /* LP filtering flag */ + } + } + else + { + if (enc_dec == ENC) + { + bits -= 4; /* TC signalling */ + } + + if (acelp_cfg->ltf_mode == NORMAL_OPERATION) + { + bits -= (L_FRAME - tc_subfr - L_SUBFR) / L_SUBFR; /* LP filtering flag */ + } + } + } + else /* L_frame == L_FRAME16k */ + { + if (enc_dec == ENC) + { + if (tc_subfr <= 2 * L_SUBFR) + { + bits -= 2; /* TC signalling */ + } + else + { + bits -= 3; /* TC signalling */ + } + } + + bits -= (L_FRAME16k - tc_subfr - L_SUBFR) / L_SUBFR; /* LP filtering flag */ + } + + /* glottal-shape codebook bits */ + bits -= (3 + 6 + 1 + 3); + } + + /*-----------------------------------------------------------------* + * pitch, innovation, gains bit-budget + *-----------------------------------------------------------------*/ + + acelp_cfg->fcb_mode = 0; + + if (element_mode == IVAS_CPE_TD && tdm_low_rate_mode == 1 && coder_type != INACTIVE && coder_type != UNVOICED) /* GENERIC low rate mode for secondary channel */ + { + set16_fx(acelp_cfg->pitch_bits, 0, NB_SUBFR16k); + set16_fx(acelp_cfg->gains_mode, 0, NB_SUBFR16k); + + for (i = 0; i < 2; i++) + { + acelp_cfg->pitch_bits[i] = 0; + if (tdm_Pitch_reuse_flag == 0) + { + acelp_cfg->pitch_bits[i] = ACB_bits_tbl[BIT_ALLOC_IDX_fx(ACELP_7k20, GENERIC, 2 * i * L_SUBFR, TC_SUBFR2IDX_fx(tc_subfr))]; + bits -= acelp_cfg->pitch_bits[i]; + } + acelp_cfg->gains_mode[i] = gain_bits_tbl[BIT_ALLOC_IDX_fx(ACELP_7k20, GENERIC, i * L_SUBFR, TC_SUBFR2IDX_fx(tc_subfr))]; + bits -= acelp_cfg->gains_mode[i]; + } + acelp_cfg->fcb_mode = 1; + +#ifdef DEBUGGING + if (bits >= 55) + { + printf("too much bits -> %d, LPC = %d and pitch = %d\n", bits, tdm_lp_reuse_flag, tdm_Pitch_reuse_flag); + acelp_FCB_allocator(&bits, acelp_cfg->fixed_cdk_index, 2, 2 * L_SUBFR, GENERIC, -1, 0); + } + else +#endif + if (bits >= 16) + { + acelp_FCB_allocator(&bits, acelp_cfg->fixed_cdk_index, 2, 2 * L_SUBFR, GENERIC, -1, 0); + } + else + { + acelp_FCB_allocator(&bits, acelp_cfg->fixed_cdk_index, 2, 2 * L_SUBFR, GENERIC, -1, 0); + acelp_cfg->fixed_cdk_index[1] = -1; + } + acelp_cfg->fixed_cdk_index[2] = -1; + acelp_cfg->fixed_cdk_index[3] = -1; + } + else if ((coder_type != INACTIVE && nb_subfr == NB_SUBFR && coder_type != AUDIO) || (nb_subfr == NB_SUBFR16k && (total_brate > MAX_GSC_INACTIVE_BRATE || coder_type != INACTIVE)) || core == HQ_CORE) + { + /* pitch Q & gain Q bit-budget - part 2*/ + for (i = 0; i < nb_subfr; i++) + { + if (L_frame == L_FRAME) + { + if (tdm_Pitch_reuse_flag == 1 && idchan == 1) + { + acelp_cfg->pitch_bits[i] = 0; + } + else + { + acelp_cfg->pitch_bits[i] = ACB_bits_tbl[BIT_ALLOC_IDX_fx(core_brate, coder_type, i * L_SUBFR, TC_SUBFR2IDX_fx(tc_subfr))]; + } + acelp_cfg->gains_mode[i] = gain_bits_tbl[BIT_ALLOC_IDX_fx(core_brate, coder_type_sw, i * L_SUBFR, TC_SUBFR2IDX_fx(tc_subfr))]; + } + else /* L_frame == L_FRAME16k */ + { + if (tdm_Pitch_reuse_flag == 1 && idchan == 1) + { + acelp_cfg->pitch_bits[i] = 0; + } + else + { + acelp_cfg->pitch_bits[i] = ACB_bits_16kHz_tbl[BIT_ALLOC_IDX_16KHZ_fx(core_brate, coder_type, i * L_SUBFR, TC_SUBFR2IDX_16KHZ_fx(tc_subfr))]; + } + acelp_cfg->gains_mode[i] = gain_bits_16kHz_tbl[BIT_ALLOC_IDX_16KHZ_fx(core_brate, coder_type_sw, i * L_SUBFR, TC_SUBFR2IDX_16KHZ_fx(tc_subfr))]; + } + + bits -= acelp_cfg->pitch_bits[i]; + + if (coder_type == INACTIVE && acelp_cfg->gains_mode[i] == 6 /* VQ vs. SQ threshold @32 kbps */) + { + bits -= 5; + } + else + { + if (*uc_two_stage_flag == 1) + { + acelp_cfg->gains_mode[i] = 7; + } + + bits -= acelp_cfg->gains_mode[i]; + } + } + + /* algebraic codebook bit-budget */ + if (flag_hardcoded || (core_brate_inp >= MIN_BRATE_AVQ_EXC && coder_type != INACTIVE) || (total_brate > MAX_GSC_INACTIVE_BRATE && coder_type == INACTIVE)) + { + for (i = 0; i < nb_subfr; i++) + { + if (L_frame == L_FRAME) + { + acelp_cfg->fixed_cdk_index[i] = FCB_bits_tbl[BIT_ALLOC_IDX_fx(core_brate, coder_type, i * L_SUBFR, TC_SUBFR2IDX_fx(tc_subfr))]; + } + else /* L_frame == L_FRAME16k */ + { + acelp_cfg->fixed_cdk_index[i] = FCB_bits_16kHz_tbl[BIT_ALLOC_IDX_16KHZ_fx(core_brate, coder_type, i * L_SUBFR, TC_SUBFR2IDX_16KHZ_fx(tc_subfr))]; + } + bits -= acelp_cfg->fixed_cdk_index[i]; + } + } + else if (!(coder_type == UNVOICED && tdm_low_rate_mode == 1 && element_mode == IVAS_CPE_TD)) + { + if (coder_type == UNVOICED && !(*uc_two_stage_flag)) + { + i = bits / NB_SUBFR; + if (i % 2 == 0) + { + i--; /* must be odd */ + } + i = s_min(i, 13); +#ifdef DEBUG_MODE_TD + if (i < 0) + IVAS_ERROR(IVAS_ERR_INTERNAL, "ERROR::: UC negative index should not happen at frame %d\n", frame); +#endif + i = s_max(i, 0); /* If i == 0-> random noise generator will be used as FCB */ + set16_fx(acelp_cfg->fixed_cdk_index, i, NB_SUBFR); + bits -= (i * NB_SUBFR); + } + else + { + + acelp_cfg->fcb_mode = 1; + if (element_mode == IVAS_CPE_TD) + { + if (bits >= ACELP_FIXED_CDK_BITS(0) * (nb_subfr)) /* enough bits for all fcb */ + { + acelp_FCB_allocator(&bits, acelp_cfg->fixed_cdk_index, nb_subfr, L_SUBFR, coder_type, tc_subfr, fix_first); + } + else if (bits >= ACELP_FIXED_CDK_BITS(0) * (nb_subfr - 1)) + { + acelp_FCB_allocator(&bits, acelp_cfg->fixed_cdk_index, nb_subfr - 1, L_SUBFR, coder_type, tc_subfr, fix_first); + acelp_cfg->fixed_cdk_index[3] = -1; + } + else if (bits >= ACELP_FIXED_CDK_BITS(0) * (nb_subfr - 2)) + { + acelp_FCB_allocator(&bits, acelp_cfg->fixed_cdk_index, nb_subfr - 2, L_SUBFR, coder_type, tc_subfr, fix_first); + acelp_cfg->fixed_cdk_index[2] = acelp_cfg->fixed_cdk_index[1]; + acelp_cfg->fixed_cdk_index[1] = -1; + acelp_cfg->fixed_cdk_index[3] = -1; + } + else if (bits >= ACELP_FIXED_CDK_BITS(0)) + { + acelp_FCB_allocator(&bits, acelp_cfg->fixed_cdk_index, 1, L_SUBFR, coder_type, tc_subfr, fix_first); + acelp_cfg->fixed_cdk_index[1] = acelp_cfg->fixed_cdk_index[0]; + acelp_cfg->fixed_cdk_index[0] = -1; + acelp_cfg->fixed_cdk_index[2] = -1; + acelp_cfg->fixed_cdk_index[3] = -1; + } + else /* No FCB */ + { +#if defined DEBUGGING + IVAS_ERROR(IVAS_ERR_INTERNAL, "WARNING!!!, No bit allocated to FCB, check frame %d\n", frame); +#endif + acelp_cfg->fixed_cdk_index[0] = -1; + acelp_cfg->fixed_cdk_index[1] = -1; + acelp_cfg->fixed_cdk_index[2] = -1; + acelp_cfg->fixed_cdk_index[3] = -1; + } + } + else if (element_mode != IVAS_CPE_TD && GSC_IVAS_mode > 0 && L_frame == L_FRAME16k) + { + bits = 100; /* 9 kbps for fcb */ + acelp_FCB_allocator(&bits, acelp_cfg->fixed_cdk_index, nb_subfr, L_SUBFR, coder_type, tc_subfr, fix_first); + } + else + { + acelp_FCB_allocator(&bits, acelp_cfg->fixed_cdk_index, nb_subfr, L_SUBFR, coder_type, tc_subfr, fix_first); + } + } + } + + /* AVQ codebook */ + if ((core_brate_inp >= MIN_BRATE_AVQ_EXC && coder_type != INACTIVE) || (total_brate > MAX_GSC_INACTIVE_BRATE && coder_type == INACTIVE)) + { + for (i = 0; i < nb_subfr; i++) + { + if (flag_hardcoded) + { + acelp_cfg->AVQ_cdk_bits[i] = AVQ_bits_16kHz_tbl[BIT_ALLOC_IDX_16KHZ_fx(core_brate, coder_type, i * L_SUBFR, TC_SUBFR2IDX_16KHZ_fx(tc_subfr))]; + { + bits -= acelp_cfg->AVQ_cdk_bits[i]; + } + } + + bits -= G_AVQ_BITS; + } + + if (core_brate_inp >= MIN_BRATE_AVQ_EXC && core_brate_inp <= MAX_BRATE_AVQ_EXC_TD && coder_type == GENERIC) + { + /* harm. flag ACELP AVQ */ + bits--; + } + + if (!flag_hardcoded) + { + Word16 bit_tmp; + + bit_tmp = bits / nb_subfr; + set16_fx(acelp_cfg->AVQ_cdk_bits, bit_tmp, nb_subfr); + bits -= bit_tmp * nb_subfr; + + bit_tmp = bits % nb_subfr; + acelp_cfg->AVQ_cdk_bits[0] += bit_tmp; + bits -= bit_tmp; + } + } + } + else if ((coder_type == UNVOICED && tdm_low_rate_mode == 1 && element_mode == IVAS_CPE_TD) || ((coder_type == INACTIVE || coder_type == AUDIO) && nb_subfr == NB_SUBFR) || (coder_type == INACTIVE && total_brate <= MAX_GSC_INACTIVE_BRATE)) + { + Word32 Local_BR, Pitch_BR; + Word16 Pitch_CT; + + /* as defined at the beginning of [enc,dec]_pit_exc() */ + if (GSC_IVAS_mode > 0 && (GSC_noisy_speech || core_brate > GSC_H_RATE_STG)) + { + Local_BR = ACELP_8k00; + Pitch_CT = GENERIC; + Pitch_BR = ACELP_8k00; + if (L_frame == L_FRAME16k) + { + Local_BR = ACELP_14k80; + if (GSC_IVAS_mode > 0 && core_brate < IVAS_24k4) + { + Local_BR = ACELP_9k60; + } + Pitch_BR = core_brate; + } + } + else if (GSC_noisy_speech) + { + Local_BR = ACELP_7k20; + Pitch_CT = GENERIC; + Pitch_BR = ACELP_7k20; + if (L_frame == L_FRAME16k) + { + Pitch_BR = core_brate; + } + } + else + { + Local_BR = ACELP_7k20; + Pitch_CT = AUDIO; + Pitch_BR = core_brate; + + if (L_frame == L_FRAME16k) + { + Local_BR = ACELP_13k20; + Pitch_CT = GENERIC; + } + } + + for (i = 0; i < nb_subfr; i++) + { + if (L_frame == L_FRAME16k) + { + acelp_cfg->pitch_bits[i] = ACB_bits_16kHz_tbl[BIT_ALLOC_IDX_16KHZ_fx(Pitch_BR, Pitch_CT, i * L_SUBFR, 0)]; + acelp_cfg->fixed_cdk_index[i] = FCB_bits_tbl[BIT_ALLOC_IDX_fx(Local_BR, LOCAL_CT, i * L_SUBFR, 0)]; + } + else + { + acelp_cfg->pitch_bits[i] = ACB_bits_tbl[BIT_ALLOC_IDX_fx(Pitch_BR, Pitch_CT, i * L_SUBFR, 0)]; + acelp_cfg->fixed_cdk_index[i] = FCB_bits_tbl[BIT_ALLOC_IDX_fx(Local_BR, LOCAL_CT, i * L_SUBFR, 0)]; + acelp_cfg->gains_mode[i] = gain_bits_tbl[BIT_ALLOC_IDX_fx(ACELP_7k20, LOCAL_CT, i * L_SUBFR, 0)]; + } + } + } + + if (coder_type == TRANSITION && (tc_call == 1 && tc_subfr == 0 && L_frame == L_FRAME)) + { + return error; + } + + /*-----------------------------------------------------------------* + * unused bits handling + *-----------------------------------------------------------------*/ + + acelp_cfg->ubits = 0; /* these bits could be reused for something else */ + + if (flag_hardcoded && core_brate != PPP_NELP_2k80) + { + /* unused bits */ + if (coder_type == AUDIO || (coder_type == INACTIVE && core_brate <= ACELP_24k40)) + { + acelp_cfg->ubits = 0; + } + else if (L_frame == L_FRAME) + { + acelp_cfg->ubits = reserved_bits_tbl[BIT_ALLOC_IDX_fx(core_brate, coder_type, -1, TC_SUBFR2IDX_fx(tc_subfr))]; + } + else + { + acelp_cfg->ubits = 0; + } + + bits -= acelp_cfg->ubits; + } + + /* sanity check */ + if ((coder_type != INACTIVE && nb_subfr == NB_SUBFR && coder_type != AUDIO) || nb_subfr == NB_SUBFR16k) + { + if ((L_frame == L_FRAME16k && coder_type == INACTIVE && total_brate <= MAX_GSC_INACTIVE_BRATE) || (GSC_IVAS_mode > 0 && L_frame == L_FRAME16k)) /* GSC Inactive @16kHz */ + { + acelp_cfg->ubits = 0; + } + else if (flag_hardcoded && core == ACELP_CORE && bits != 0) + { +#if defined DEBUGGING + IVAS_ERROR(IVAS_ERR_INTERNAL, "ERROR: bit-budget incorrect (%d bits) in frame %d.\n", (Word32)bits, frame); +#endif + } + else if (bits > 0 && !(coder_type == UNVOICED && tdm_low_rate_mode == 1 && element_mode == IVAS_CPE_TD)) + { + if (idchan > 0 && element_mode == IVAS_CPE_TD) + { +#ifdef LSF_RE_USE_SECONDARY_CHANNEL + if (!tdm_lp_reuse_flag) + { + acelp_cfg->lsf_bits += bits; /* increase LSF Q bits */ + bits = 0; + } + else + { + Word16 nb_prm = 4; + if (tdm_low_rate_mode == 1) + { + nb_prm = 2; + } + /* First add remaining bits on gains */ + bits -= allocate_unused(core_brate, coder_type, bits, nb_prm, 0, GAINSPRM, acelp_cfg->gains_mode); + + /* Then, Increase pitch bit budget */ + if (tdm_Pitch_reuse_flag == 0 && bits > 0) + { + bits -= allocate_unused(core_brate, coder_type, bits, nb_prm, 0, PITCHPRM, acelp_cfg->pitch_bits); + } + + /* Increase mid-lsf bit budget */ + if (tdm_lp_reuse_flag == 0 && bits > 0) + { + bits -= allocate_unused(core_brate, coder_type, bits, 1, 0, MID_LSFSPRM, &acelp_cfg->mid_lsf_bits); + bits -= allocate_unused(core_brate, coder_type, bits, 1, 0, LSFPRM, &acelp_cfg->lsf_bits); + } + } +#else + Word16 nb_prm = 4; + + if (tdm_low_rate_mode == 1) + { + nb_prm = 2; + } + + /* First add remaining bits on gains */ + if (!(*uc_two_stage_flag)) + { + bits -= allocate_unused(core_brate, coder_type, bits, nb_prm, 0, GAINSPRM, acelp_cfg->gains_mode); + } + + /* Then, Increase pitch bit budget */ + if (tdm_Pitch_reuse_flag == 0 && bits > 0) + { + bits -= allocate_unused(core_brate, coder_type, bits, nb_prm, 0, PITCHPRM, acelp_cfg->pitch_bits); + } + + /* Increase mid-lsf bit budget */ + if (tdm_lp_reuse_flag == 0 && bits > 0) + { + bits -= allocate_unused(core_brate, coder_type, bits, 1, 0, MID_LSFSPRM, &acelp_cfg->mid_lsf_bits); + bits -= allocate_unused(core_brate, coder_type, bits, 1, 0, LSFPRM, &acelp_cfg->lsf_bits); + } +#endif +#if defined DEBUGGING + if (idchan > 0 && bits > 0 && (coder_type > UNVOICED || tdm_low_rate_mode == 0)) + { + IVAS_ERROR(IVAS_ERR_INTERNAL, "WARNING !! Unused bits in secondary channel at frame %d\n", frame); + } +#endif + } + + else if (core == ACELP_CORE && coder_type >= UNVOICED && coder_type <= GENERIC && L_frame == L_FRAME) + { + acelp_cfg->lsf_bits += bits; /* increase LSF Q bits */ + + if (acelp_cfg->lsf_bits > 46) + { + acelp_cfg->ubits = acelp_cfg->lsf_bits - 46; + acelp_cfg->lsf_bits = 46; + } + else if (acelp_cfg->lsf_bits > 42 && L_frame == L_FRAME) + { + acelp_cfg->ubits = acelp_cfg->lsf_bits - 42; + acelp_cfg->lsf_bits = 42; + } + } + else + { + acelp_cfg->ubits = bits; + } + } + else if (bits < 0 && !(coder_type == UNVOICED && tdm_low_rate_mode == 1 && element_mode == IVAS_CPE_TD)) + { +#if defined DEBUGGING + IVAS_ERROR(IVAS_ERR_INTERNAL, "ERROR: bit-budget incorrect (%d bits) in frame %d.\n", (Word32)bits, frame); +#endif + } + } + + return error; +} + +/*-------------------------------------------------------------------* + * allocate_unused() + * + * Allocate unused bits + *--------------------------------------------------------------------*/ + +static Word16 allocate_unused( + const Word32 core_brate, + const Word16 coder_type, + const Word16 unused_bits, + const Word16 nb_prm, + const Word16 subfr, + const Word16 prm_type, + Word16* prm_bit_mode) +{ + Word16 max_bit_per_pos = 0, bit_added = 0; + //PMT("Not floating point computation, but fixed point operator are still missing ") + + if (prm_type == GAINSPRM) + { + max_bit_per_pos = 6; + if (core_brate > ACELP_8k00) + { + max_bit_per_pos = 7; + } + else if (coder_type != UNVOICED) + { + if (subfr >= 1) + { + max_bit_per_pos = 7; + } + else if (subfr == 0) + { + max_bit_per_pos = 8; + } + } + else if (coder_type == UNVOICED) + { + max_bit_per_pos = 9; /* No real limit on UC gain bit budget of the secondary channel */ + } + } + else if (prm_type == PITCHPRM) + { + max_bit_per_pos = 6; + if (subfr == 0 || subfr == 2 || nb_prm == 2) + { + max_bit_per_pos = 10; + } + + if (coder_type == UNVOICED) + { + max_bit_per_pos = 0; /* Should not allocate bits in case of unvoiced coder type */ + } + } + else if (prm_type == MID_LSFSPRM) + { + max_bit_per_pos = 5; + } + else if (prm_type == LSFPRM) + { + max_bit_per_pos = 42; + } + else + { +#ifdef DEBUG_MODE_TD + IVAS_ERROR(IVAS_ERR_WRONG_MODE, "unknown mode in bit_alloc.c"); +#endif + } + + max_bit_per_pos = s_min(unused_bits, max_bit_per_pos - prm_bit_mode[subfr]); + if (max_bit_per_pos < 0) + { + return 0; + } + else if (max_bit_per_pos >= 0 && subfr == (nb_prm - 1)) + { + prm_bit_mode[subfr] += max_bit_per_pos; + } + else + { + prm_bit_mode[subfr] += max_bit_per_pos; + bit_added += allocate_unused(core_brate, coder_type, unused_bits - max_bit_per_pos, nb_prm, subfr + 1, prm_type, &prm_bit_mode[0]); + } + + return bit_added + max_bit_per_pos; +} + + +/*-------------------------------------------------------------------* + * set_ACELP_flag() + * + * set ACELP@16kHz flag + *--------------------------------------------------------------------*/ + + /*! r: ACELP16k flag */ +Word16 set_ACELP_flag( + const Word16 element_mode, /* i : element mode */ + const Word32 element_brate, /* i : element bitrate */ + const Word32 total_brate, /* i : total bitrate per channel */ + const Word16 idchan, /* i : Channel id */ + const Word16 tdm_LRTD_flag, /* i : LRTD stereo mode flag */ + const Word16 bwidth, /* i : audio bandwidth */ + const Word16 cng_type /* i : CNG type */ +) +{ + //PMT("Not floating point computation, but fixed point operator are still missing ") + if (element_mode == IVAS_CPE_DFT && idchan == 0 && total_brate <= SID_2k40 && bwidth == WB && cng_type == LP_CNG) + { + + return 1; + } + else if (element_mode == IVAS_CPE_TD) + { + if (element_brate >= IVAS_24k4 && idchan == 0 && (tdm_LRTD_flag == 0 || element_brate > IVAS_24k4)) + { + return 1; + } + else + { + return 0; + } + } + else if (element_mode == IVAS_CPE_DFT) + { + if (element_brate >= IVAS_24k4) + { + return 1; + } + else + { + return 0; + } + } + else if (element_mode == IVAS_SCE) + { + if (element_brate >= SCE_CORE_16k_LOW_LIMIT) + { + return 1; + } + else + { + return 0; + } + } + else if (total_brate >= ACELP_16k_LOW_LIMIT) /* EVS_MONO */ + { + return 1; + } + else + { + return 0; + } +} +/*#endif IVAS_CODE*/ \ No newline at end of file diff --git a/lib_com/bitstream.c b/lib_com/bitstream.c index 99b31f30bf7ac120e628ef4b51671b27daca81dc..e99454c930d5f9c4a5df1600eeb5151a6e09b41a 100644 --- a/lib_com/bitstream.c +++ b/lib_com/bitstream.c @@ -2091,6 +2091,7 @@ ivas_error read_indices( error = IVAS_ERR_OK; st_ivas->BER_detect = 0; + st_ivas->num_bits = num_bits; sts = reset_elements( st_ivas ); st_ivas->bfi = bfi; diff --git a/lib_com/bitstream_fx.c b/lib_com/bitstream_fx.c index 4f848c31a2da61db1d9a6c758b1cd8f326e5a2f1..9cb1518bbf7e8d122f6acf03ec34971ff8ca262b 100644 --- a/lib_com/bitstream_fx.c +++ b/lib_com/bitstream_fx.c @@ -395,7 +395,7 @@ UWord16 get_next_indice_fx( /* o : value of the indice */ move16(); /* detect corrupted bitstream */ - IF(GT_16(add(st_fx->next_bit_pos_fx, nb_bits), st_fx->total_num_bits)) + IF(GT_16(add(st_fx->next_bit_pos, nb_bits), st_fx->total_num_bits)) { st_fx->BER_detect = 1; move16(); @@ -405,11 +405,11 @@ UWord16 get_next_indice_fx( /* o : value of the indice */ FOR(i = 0; i < nb_bits; i++) { value = lshl(value, 1); - value = add(value, st_fx->bit_stream_fx[st_fx->next_bit_pos_fx + i]); + value = add(value, st_fx->bit_stream[st_fx->next_bit_pos + i]); } /* update the position in the bitstream */ - st_fx->next_bit_pos_fx = add(st_fx->next_bit_pos_fx, nb_bits); + st_fx->next_bit_pos = add(st_fx->next_bit_pos, nb_bits); return value; } @@ -427,8 +427,8 @@ UWord16 get_next_indice_1_fx( /* o : value of the indice */ test(); test(); test(); - IF((GT_16(add(st_fx->next_bit_pos_fx, 1), st_fx->total_num_bits) && EQ_16(st_fx->codec_mode, MODE1)) || - (GT_16(add(st_fx->next_bit_pos_fx, 1), add(st_fx->total_num_bits, 2 * 8)) && EQ_16(st_fx->codec_mode, MODE2)) /* add two zero bytes for arithmetic coder flush */ + IF((GT_16(add(st_fx->next_bit_pos, 1), st_fx->total_num_bits) && EQ_16(st_fx->codec_mode, MODE1)) || + (GT_16(add(st_fx->next_bit_pos, 1), add(st_fx->total_num_bits, 2 * 8)) && EQ_16(st_fx->codec_mode, MODE2)) /* add two zero bytes for arithmetic coder flush */ ) { st_fx->BER_detect = 1; @@ -436,7 +436,7 @@ UWord16 get_next_indice_1_fx( /* o : value of the indice */ return(0); } - return st_fx->bit_stream_fx[st_fx->next_bit_pos_fx++]; + return st_fx->bit_stream[st_fx->next_bit_pos++]; } /*-------------------------------------------------------------------* @@ -451,7 +451,7 @@ void get_next_indice_tmp_fx( ) { /* update the position in the bitstream */ - st_fx->next_bit_pos_fx = add(st_fx->next_bit_pos_fx, nb_bits); + st_fx->next_bit_pos = add(st_fx->next_bit_pos, nb_bits); } /*-------------------------------------------------------------------* @@ -484,7 +484,7 @@ UWord16 get_indice_fx( /* o : value of the indice */ FOR(i = 0; i < nb_bits; i++) { value = lshl(value, 1); - value = add(value, st_fx->bit_stream_fx[pos + i]); + value = add(value, st_fx->bit_stream[pos + i]); } return value; @@ -509,7 +509,7 @@ UWord16 get_indice_1_fx( /* o : value of the indice */ return(0); } - return st_fx->bit_stream_fx[pos]; + return st_fx->bit_stream[pos]; } /*-------------------------------------------------------------------* @@ -550,7 +550,7 @@ void reset_indices_dec_fx( Decoder_State *st_fx ) { - st_fx->next_bit_pos_fx = 0; + st_fx->next_bit_pos = 0; move16(); return; @@ -811,17 +811,17 @@ static void decoder_selectCodec( EQ_32(total_brate, ACELP_14k25) || EQ_32(total_brate, ACELP_15k85) || EQ_32(total_brate, ACELP_18k25) || EQ_32(total_brate, ACELP_19k85) || EQ_32(total_brate, ACELP_23k05) || EQ_32(total_brate, ACELP_23k85)) { - st->Opt_AMR_WB_fx = 1; + st->Opt_AMR_WB = 1; move16(); } ELSE IF(NE_32(total_brate, FRAME_NO_DATA)) { - st->Opt_AMR_WB_fx = 0; + st->Opt_AMR_WB = 0; move16(); } /* select MODE1 or MODE2 */ - IF(st->Opt_AMR_WB_fx) + IF(st->Opt_AMR_WB) { st->codec_mode = MODE1; move16();/**/ @@ -889,14 +889,14 @@ static void decoder_selectCodec( default: /* validate that total_brate (derived from RTP packet or a file header) is one of the defined bit rates */ st->codec_mode = st->last_codec_mode; - st->bfi_fx = 1; + st->bfi = 1; move16(); move16(); BREAK; } } - IF(st->ini_frame_fx == 0) + IF(st->ini_frame == 0) { IF(EQ_16(st->codec_mode, -1)) { @@ -912,7 +912,7 @@ static void decoder_selectCodec( { IF(bit0 == G192_BIN0) { - st->cng_type_fx = LP_CNG; + st->cng_type = LP_CNG; move16(); /* force MODE1 when selecting LP_CNG */ @@ -921,15 +921,15 @@ static void decoder_selectCodec( } ELSE { - st->cng_type_fx = FD_CNG; + st->cng_type = FD_CNG; test(); - if (EQ_16(st->last_codec_mode, MODE2) && EQ_32(st->last_total_brate_fx,13200)) + if (EQ_16(st->last_codec_mode, MODE2) && EQ_32(st->last_total_brate,13200)) { st->codec_mode = MODE1; move16(); } } - st->hTdCngDec->last_cng_type_fx = st->cng_type_fx; /* CNG type switching at the first correctly received SID frame */ + st->hTdCngDec->last_cng_type_fx = st->cng_type; /* CNG type switching at the first correctly received SID frame */ } @@ -947,15 +947,15 @@ void dec_prm_core(Decoder_State *st) frame_size_index = -1; move16(); - st->core_fx = -1; + st->core = -1; move16(); - IF(EQ_32(st->total_brate_fx, FRAME_NO_DATA)) + IF(EQ_32(st->total_brate, FRAME_NO_DATA)) { st->m_frame_type = ZERO_FRAME; move16(); } - ELSE IF(EQ_32(st->total_brate_fx, SID_2k40)) + ELSE IF(EQ_32(st->total_brate, SID_2k40)) { st->m_frame_type = SID_FRAME; move16(); @@ -964,9 +964,9 @@ void dec_prm_core(Decoder_State *st) { st->m_frame_type = ACTIVE_FRAME; move16(); - Mpy_32_16_ss(st->total_brate_fx, 5243, &L_tmp, &lsb); /* 5243 is 1/50 in Q18. (0+18-15=3) */ + Mpy_32_16_ss(st->total_brate, 5243, &L_tmp, &lsb); /* 5243 is 1/50 in Q18. (0+18-15=3) */ num_bits = extract_l(L_shr(L_tmp, 3)); /* Q0 */ - assert(num_bits == st->total_brate_fx / 50); + assert(num_bits == st->total_brate / 50); FOR(n = 0; n < FRAME_SIZE_NB; ++n) { IF(EQ_16(FrameSizeConfig[n].frame_bits, num_bits)) @@ -978,21 +978,21 @@ void dec_prm_core(Decoder_State *st) } /* Get bandwidth mode */ - st->bwidth_fx = get_next_indice_fx(st, FrameSizeConfig[frame_size_index].bandwidth_bits); + st->bwidth = get_next_indice(st, FrameSizeConfig[frame_size_index].bandwidth_bits); - st->bwidth_fx = add(st->bwidth_fx, FrameSizeConfig[frame_size_index].bandwidth_min); + st->bwidth = add(st->bwidth, FrameSizeConfig[frame_size_index].bandwidth_min); - if (GT_16(st->bwidth_fx, FB)) + if (GT_16(st->bwidth, FB)) { - st->bwidth_fx = FB; + st->bwidth = FB; move16(); st->BER_detect = 1; move16(); } - if (GT_16(st->bwidth_fx, SWB) && LT_32(st->total_brate_fx,ACELP_16k40)) + if (GT_16(st->bwidth, SWB) && LT_32(st->total_brate,ACELP_16k40)) { - st->bwidth_fx = SWB; + st->bwidth = SWB; move16(); st->BER_detect = 1; move16(); @@ -1001,19 +1001,19 @@ void dec_prm_core(Decoder_State *st) /* Skip reserved bit */ get_next_indice_tmp_fx(st, FrameSizeConfig[frame_size_index].reserved_bits); - IF(get_next_indice_1_fx(st) != 0) /* TCX */ + IF(get_next_indice_1(st) != 0) /* TCX */ { - st->core_fx = TCX_20_CORE; + st->core = TCX_20_CORE; move16(); - if (get_next_indice_1_fx(st) != 0) + if (get_next_indice_1(st) != 0) { - st->core_fx = HQ_CORE; + st->core = HQ_CORE; move16(); } } ELSE /* ACELP */ { - st->core_fx = ACELP_CORE; + st->core = ACELP_CORE; move16(); } } @@ -1034,23 +1034,23 @@ void decision_matrix_core_dec( Word32 ind; Word16 nBits; - assert(st->bfi_fx != 1); + assert(st->bfi != 1); - st->core_fx = -1; + st->core = -1; move16(); - st->bwidth_fx = -1; + st->bwidth = -1; move16(); test(); - IF(EQ_32(st->total_brate_fx, FRAME_NO_DATA) || EQ_32(st->total_brate_fx, SID_2k40)) + IF(EQ_32(st->total_brate, FRAME_NO_DATA) || EQ_32(st->total_brate, SID_2k40)) { - st->core_fx = ACELP_CORE; + st->core = ACELP_CORE; move16(); } /* SC-VBR */ - ELSE IF(st->total_brate_fx == PPP_NELP_2k80) + ELSE IF(st->total_brate == PPP_NELP_2k80) { - st->core_fx = ACELP_CORE; + st->core = ACELP_CORE; move16(); return; } @@ -1060,19 +1060,19 @@ void decision_matrix_core_dec( *---------------------------------------------------------------------*/ test(); - IF(LT_32(st->total_brate_fx, ACELP_24k40)) + IF(LT_32(st->total_brate, ACELP_24k40)) { - st->core_fx = ACELP_CORE; + st->core = ACELP_CORE; move16(); } - ELSE IF(GE_32(st->total_brate_fx, ACELP_24k40) && LE_32(st->total_brate_fx, ACELP_64k)) + ELSE IF(GE_32(st->total_brate, ACELP_24k40) && LE_32(st->total_brate, ACELP_64k)) { /* read the ACELP/HQ core selection bit */ - st->core_fx = imult1616(get_next_indice_fx(st, 1), HQ_CORE); + st->core = imult1616(get_next_indice(st, 1), HQ_CORE); } ELSE { - st->core_fx = HQ_CORE; + st->core = HQ_CORE; move16(); } @@ -1080,12 +1080,12 @@ void decision_matrix_core_dec( * Read ACELP signalling bits from the bitstream *-----------------------------------------------------------------*/ - IF(EQ_16(st->core_fx, ACELP_CORE)) + IF(EQ_16(st->core, ACELP_CORE)) { /* find the section in the ACELP signalling table corresponding to bitrate */ start_idx = 0; move16(); - WHILE(NE_32(acelp_sig_tbl[start_idx], st->total_brate_fx)) + WHILE(NE_32(acelp_sig_tbl[start_idx], st->total_brate)) { start_idx = add(start_idx, 1); } @@ -1098,13 +1098,13 @@ void decision_matrix_core_dec( start_idx = add(start_idx, 1); /* retrieve the signalling indice */ - ind = acelp_sig_tbl[add(start_idx, get_next_indice_fx(st, nBits))]; - st->bwidth_fx = extract_l(L_and(L_shr(ind, 3), 0x7)); + ind = acelp_sig_tbl[add(start_idx, get_next_indice(st, nBits))]; + st->bwidth = extract_l(L_and(L_shr(ind, 3), 0x7)); /* convert signalling indice into signalling information */ if (EQ_32(L_and(ind, 0x7), LR_MDCT)) { - st->core_fx = HQ_CORE; + st->core = HQ_CORE; move16(); } } @@ -1114,39 +1114,39 @@ void decision_matrix_core_dec( * Set HQ core type *-----------------------------------------------------------------*/ - IF(EQ_16(st->core_fx, HQ_CORE)) + IF(EQ_16(st->core, HQ_CORE)) { /* read the HQ/TCX core switching flag */ - if (get_next_indice_fx(st, 1) != 0) + if (get_next_indice(st, 1) != 0) { - st->core_fx = TCX_20_CORE; + st->core = TCX_20_CORE; move16(); } /* For TCX: read/set band-width (needed for different I/O sampling rate support) */ test(); - IF(EQ_16(st->core_fx, TCX_20_CORE) && GT_32(st->total_brate_fx, ACELP_16k40)) + IF(EQ_16(st->core, TCX_20_CORE) && GT_32(st->total_brate, ACELP_16k40)) { - ind = get_next_indice_fx(st, 2); + ind = get_next_indice(st, 2); IF(ind == 0) { - st->bwidth_fx = NB; + st->bwidth = NB; move16(); } ELSE IF(EQ_32(ind, 1)) { - st->bwidth_fx = WB; + st->bwidth = WB; move16(); } ELSE IF(EQ_32(ind, 2)) { - st->bwidth_fx = SWB; + st->bwidth = SWB; move16(); } ELSE { - st->bwidth_fx = FB; + st->bwidth = FB; move16(); } } @@ -1165,19 +1165,19 @@ static void mdct_switching_dec( Decoder_State *st /* i/o: decoder state structure */ ) { - IF(st->Opt_AMR_WB_fx != 0) + IF(st->Opt_AMR_WB != 0) { return; } test(); test(); - IF(EQ_32(st->total_brate_fx, ACELP_13k20) || EQ_32(st->total_brate_fx, ACELP_32k)) + IF(EQ_32(st->total_brate, ACELP_13k20) || EQ_32(st->total_brate, ACELP_32k)) { st->mdct_sw_enable = MODE1; move16(); } - ELSE IF(LE_32(ACELP_16k40, st->total_brate_fx) && LE_32(st->total_brate_fx, ACELP_24k40)) + ELSE IF(LE_32(ACELP_16k40, st->total_brate) && LE_32(st->total_brate, ACELP_24k40)) { st->mdct_sw_enable = MODE2; move16(); @@ -1192,16 +1192,16 @@ static void mdct_switching_dec( Word16 core_save; Word16 bwidth_save; - next_bit_pos_save = st->next_bit_pos_fx; + next_bit_pos_save = st->next_bit_pos; move16(); - core_save = st->core_fx; + core_save = st->core; move16(); - bwidth_save = st->bwidth_fx; + bwidth_save = st->bwidth; move16(); decision_matrix_core_dec(st); /* sets st->core */ - IF(EQ_16(st->core_fx, TCX_20_CORE)) + IF(EQ_16(st->core, TCX_20_CORE)) { /* Trigger TCX */ st->codec_mode = MODE2; @@ -1212,13 +1212,13 @@ static void mdct_switching_dec( ELSE { /* Rewind bitstream */ - st->next_bit_pos_fx = next_bit_pos_save; + st->next_bit_pos = next_bit_pos_save; move16(); - IF(st->bfi_fx != 0) + IF(st->bfi != 0) { - st->core_fx = core_save; + st->core = core_save; move16(); - st->bwidth_fx = bwidth_save; + st->bwidth = bwidth_save; move16(); } } @@ -1230,16 +1230,16 @@ static void mdct_switching_dec( Word16 core_save; Word16 bwidth_save; - next_bit_pos_save = st->next_bit_pos_fx; + next_bit_pos_save = st->next_bit_pos; move16(); - core_save = st->core_fx; + core_save = st->core; move16(); - bwidth_save = st->bwidth_fx; + bwidth_save = st->bwidth; move16(); dec_prm_core(st); /* sets st->core */ - IF(EQ_16(st->core_fx, HQ_CORE)) + IF(EQ_16(st->core, HQ_CORE)) { /* Trigger HQ_CORE */ st->codec_mode = MODE1; @@ -1250,15 +1250,15 @@ static void mdct_switching_dec( ELSE { /* Rewind bitstream */ - st->next_bit_pos_fx = next_bit_pos_save; + st->next_bit_pos = next_bit_pos_save; move16(); - IF(st->bfi_fx != 0) + IF(st->bfi != 0) { - st->core_fx = core_save; + st->core = core_save; move16(); } /* always reset bwidth, to not interfere with BER logic */ - st->bwidth_fx = bwidth_save; + st->bwidth = bwidth_save; move16(); } } @@ -1411,7 +1411,7 @@ Word16 read_indices_fx( /* o : 1 = reading OK, 0 = problem Word16 speech_bad, speech_lost; Word16 num_bits_read; - st->bfi_fx = 0; + st->bfi = 0; st->BER_detect = 0; st->mdct_sw_enable = 0; st->mdct_sw = 0; @@ -1440,13 +1440,13 @@ Word16 read_indices_fx( /* o : 1 = reading OK, 0 = problem /* set the BFI indicator according the value of Sync Header */ if (EQ_16(utmp, SYNC_BAD_FRAME)) { - st->bfi_fx = 1; + st->bfi = 1; } else { - st->bfi_fx = 0; + st->bfi = 0; } /* read the Frame Length field from the bitstream */ @@ -1493,7 +1493,7 @@ Word16 read_indices_fx( /* o : 1 = reading OK, 0 = problem exit(-1); } - } while (rew_flag && (st->bfi_fx || LT_32(total_brate, 2800))); + } while (rew_flag && (st->bfi || LT_32(total_brate, 2800))); /* G.192 RX DTX handler*/ if (!rew_flag) @@ -1506,7 +1506,7 @@ Word16 read_indices_fx( /* o : 1 = reading OK, 0 = problem if (total_brate > SID_2k40) { - if (st->bfi_fx == 0) + if (st->bfi == 0) { curr_ft_good_sp = 1; } @@ -1520,7 +1520,7 @@ Word16 read_indices_fx( /* o : 1 = reading OK, 0 = problem if (total_brate == SID_1k75 || total_brate == SID_2k40) { - if (st->bfi_fx == 0) + if (st->bfi == 0) { sid_update = 1; } @@ -1561,7 +1561,7 @@ Word16 read_indices_fx( /* o : 1 = reading OK, 0 = problem } g192_sid_first = 0; - if (st->core_fx == AMR_WB_CORE && st->prev_ft_speech_fx && total_brate == FRAME_NO_DATA && st->bfi_fx == 0) + if (st->core == AMR_WB_CORE && st->prev_ft_speech_fx && total_brate == FRAME_NO_DATA && st->bfi == 0) { g192_sid_first = 1; /* SID_FIRST detected for previous AMRWB/AMRWBIO active frames only */ /* @@ -1573,13 +1573,13 @@ Word16 read_indices_fx( /* o : 1 = reading OK, 0 = problem } speech_bad = 0; - if (total_brate > SID_2k40 && st->bfi_fx != 0) /* CS-type of CRC failure frame */ + if (total_brate > SID_2k40 && st->bfi != 0) /* CS-type of CRC failure frame */ { speech_bad = 1; /* initial assumption, CNG_state decides what to do */ } speech_lost = 0; - if (total_brate == 0 && st->bfi_fx != 0) /* unsent NO_DATA or stolen NO_DATA/signaling frame */ + if (total_brate == 0 && st->bfi != 0) /* unsent NO_DATA or stolen NO_DATA/signaling frame */ { speech_lost = 1; /* initial assumption, CNG_state decides what to do */ } @@ -1607,9 +1607,9 @@ Word16 read_indices_fx( /* o : 1 = reading OK, 0 = problem } /* handle the g.192 _simulated_ untransmitted frame, setting for decoder SPEECH synthesis */ - if ((st->CNG_fx == 0) && (total_brate == 0 && st->bfi_fx == 0)) + if ((st->CNG_fx == 0) && (total_brate == 0 && st->bfi == 0)) { - st->bfi_fx = 1; + st->bfi = 1; move16(); /* SPEECH PLC code will now become active as in a real system */ /* total_brate= 0 */ } @@ -1618,7 +1618,7 @@ Word16 read_indices_fx( /* o : 1 = reading OK, 0 = problem if (((st->CNG_fx != 0) && ((speech_bad != 0) || (speech_lost != 0))) || /* SP_BAD or SPEECH_LOST) --> stay in CNG */ (sid_upd_bad != 0)) /* SID_UPD_BAD --> start CNG */ { - st->bfi_fx = 0; + st->bfi = 0; total_brate = 0; } /* update for next frame's G.192 file format's SID_FIRST detection (primarily for AMRWBIO) */ @@ -1629,9 +1629,9 @@ Word16 read_indices_fx( /* o : 1 = reading OK, 0 = problem /* get total bit-rate */ #ifdef DEBUGGING - st->bfi_fx |= file_read_FECpattern(); + st->bfi |= file_read_FECpattern(); #endif - if (st->bfi_fx == 0 && !rew_flag) + if (st->bfi == 0 && !rew_flag) { /* select MODE1 or MODE2 */ decoder_selectCodec(st, total_brate, *pt_stream); @@ -1645,16 +1645,16 @@ Word16 read_indices_fx( /* o : 1 = reading OK, 0 = problem if (rew_flag) { rewind(file); - st->total_brate_fx = total_brate; + st->total_brate = total_brate; move16(); return 1; } /* GOOD frame */ - if (st->bfi_fx == 0) + if (st->bfi == 0) { /* GOOD frame - convert ITU-T G.192 words to short values */ - bit_stream_ptr = st->bit_stream_fx; + bit_stream_ptr = st->bit_stream; for (k = 0; k < num_bits; ++k) { @@ -1668,14 +1668,14 @@ Word16 read_indices_fx( /* o : 1 = reading OK, 0 = problem } /*a change of the total bitrate should not be known to the decoder, if the received frame was lost*/ - st->total_brate_fx = total_brate; + st->total_brate = total_brate; mdct_switching_dec(st); } #ifdef DEBUGGING else { - bit_stream_ptr = st->bit_stream_fx; + bit_stream_ptr = st->bit_stream; for (k = 0; k < num_bits + 2 * 8; ++k) { @@ -1713,7 +1713,7 @@ static Word32 read_indices_mime_handle_dtx( /* keep st->CNG , st_bfi and total_brate updated for proper synthesis in DTX and FER */ if (GT_32(total_brate, SID_2k40)) { - if (st->bfi_fx != 1) /* so far derived from q bit in AMRWB/AMRWBIO cases */ + if (st->bfi != 1) /* so far derived from q bit in AMRWB/AMRWBIO cases */ { curr_ft_good_sp = 1; } @@ -1723,7 +1723,7 @@ static Word32 read_indices_mime_handle_dtx( if (speech_lost != 0) /* overrides a good q_bit */ { curr_ft_good_sp = 0; - st->bfi_fx = 1; /* override qbit */ + st->bfi = 1; /* override qbit */ } /* now_bfi_fx has been set based on q_bit and ToC fields */ @@ -1732,7 +1732,7 @@ static Word32 read_indices_mime_handle_dtx( /* SID_UPDATE check */ if (total_brate == SID_1k75 || total_brate == SID_2k40) { - if (st->bfi_fx == 0) + if (st->bfi == 0) { /* typically from q bit */ sid_update = 1; @@ -1745,7 +1745,7 @@ static Word32 read_indices_mime_handle_dtx( if (isAMRWB_IOmode && total_brate == 0 && sti == 0) { - if (st->bfi_fx) + if (st->bfi) { sid_upd_bad = 1; /* corrupt sid_first, signaled as bad sid */ } @@ -1756,18 +1756,18 @@ static Word32 read_indices_mime_handle_dtx( } if (sid_upd_bad != 0 && ( - (isAMRWB_IOmode != 0 && st->Opt_AMR_WB_fx == 0) || /* switch to AMRWBIO */ - (isAMRWB_IOmode != 1 && st->Opt_AMR_WB_fx == 1) /* switch from AMRWBIO */ + (isAMRWB_IOmode != 0 && st->Opt_AMR_WB == 0) || /* switch to AMRWBIO */ + (isAMRWB_IOmode != 1 && st->Opt_AMR_WB == 1) /* switch from AMRWBIO */ )) { /* do not allow a normal start of CNG synthesis if this SID(with BER or FER) is a switch to/from AMRWBIO */ sid_upd_bad = 0; /* revert this detection due to AMRWBIO/EVS mode switch */ total_brate = 0; no_data = 1; - assert(st->bfi_fx == 1); /* bfi stays 1 */ + assert(st->bfi == 1); /* bfi stays 1 */ } - if (GT_32(total_brate, SID_2k40) && st->bfi_fx == 1) /* typically from q bit */ + if (GT_32(total_brate, SID_2k40) && st->bfi == 1) /* typically from q bit */ { speech_bad = 1; /* initial assumption, CNG synt state decides what to actually do */ } @@ -1801,7 +1801,7 @@ static Word32 read_indices_mime_handle_dtx( if ((st->CNG_fx == 0) && (no_data != 0)) { /* treat no_data received in speech synthesis as SP_LOST frames, SPEECH PLC code will now become active */ - st->bfi_fx = 1; + st->bfi = 1; /* total_brate= 0; always zero for no_data */ } @@ -1810,7 +1810,7 @@ static Word32 read_indices_mime_handle_dtx( if ((st->CNG_fx != 0 && (speech_bad || speech_lost || no_data)) || /* SP_BAD or SPEECH_LOST) --> stay in CNG */ sid_upd_bad) /* SID_UPD_BAD --> start/stay CNG */ { - st->bfi_fx = 0; /* mark as good to not start speech PLC */ + st->bfi = 0; /* mark as good to not start speech PLC */ total_brate = 0; /* this zeroing needed for speech_bad, sid_bad frames */ } @@ -1824,7 +1824,7 @@ static Word32 read_indices_mime_handle_dtx( /* handle available AMRWB/AMRWBIO MIME header ToC rate-info at startup */ - if ((st->bfi_fx == 1 && st->ini_frame_fx == 0) && + if ((st->bfi == 1 && st->ini_frame == 0) && ((st->amrwb_rfc4867_flag != 0) || (st->amrwb_rfc4867_flag == 0 && isAMRWB_IOmode != 0))) /*AMRWB ToC */ { Word32 init_rate; @@ -1838,8 +1838,8 @@ static Word32 read_indices_mime_handle_dtx( { init_rate = AMRWB_IOmode2rate[core_mode]; /* read from from ToC */ } - st->total_brate_fx = init_rate; /* not updated on bfi as decoderSelectCodec is not called below */ - st->core_brate_fx = init_rate; + st->total_brate = init_rate; /* not updated on bfi as decoderSelectCodec is not called below */ + st->core_brate = init_rate; } return total_brate; @@ -1865,7 +1865,7 @@ static void read_indices_mime_handle_sti_and_all_zero_bits( *total_brate = 0; /* signal received SID_FIRST as a good frame with no bits */ for (k = 0; k < 35; k++) { - st->bfi_fx |= st->bit_stream_fx[k]; /* partity check of 35 zeroes, any single 1 gives BFI */ + st->bfi |= st->bit_stream[k]; /* partity check of 35 zeroes, any single 1 gives BFI */ } } /* all zero bit SID_update results in a valid LP filter with extremely high LP-filter-gain */ @@ -1875,12 +1875,12 @@ static void read_indices_mime_handle_sti_and_all_zero_bits( Word16 sum = 0; for (k = 0; k < 35; k++) { - sum += st->bit_stream_fx[k]; /* check of 35 zeroes */ + sum += st->bit_stream[k]; /* check of 35 zeroes */ } if (sum == 0) { - st->bfi_fx = 1; /* eventually becomes SID_UPD_BAD */ + st->bfi = 1; /* eventually becomes SID_UPD_BAD */ } } } @@ -1912,7 +1912,7 @@ Word16 read_indices_mime( /* o : 1 = reading OK, 0 = problem Word16 num_bytes_read; st->BER_detect = 0; - st->bfi_fx = 0; + st->bfi = 0; st->mdct_sw_enable = 0; st->mdct_sw = 0; reset_indices_dec_fx(st); @@ -1951,7 +1951,7 @@ Word16 read_indices_mime( /* o : 1 = reading OK, 0 = problem isAMRWB_IOmode = 1; qbit = (header >> 2) & 0x01; /* b2 bit (b7 is the F bit ) */ - st->bfi_fx = !qbit; + st->bfi = !qbit; core_mode = ((header >> 3) & 0x0F); /* b6..b3 */ total_brate = AMRWB_IOmode2rate[core_mode]; /* get the frame length from the header */ } @@ -1980,7 +1980,7 @@ Word16 read_indices_mime( /* o : 1 = reading OK, 0 = problem qbit = 1; /* assume good q_bit for the unused EVS-mode bit, complete ToC validity checked later */ total_brate = PRIMARYmode2rate[core_mode]; } - st->bfi_fx = !qbit; + st->bfi = !qbit; } @@ -2049,8 +2049,8 @@ Word16 read_indices_mime( /* o : 1 = reading OK, 0 = problem /* (used in io_dec() to attempt print out info about technologies and to initialize the codec ) */ if (rew_flag) { - st->total_brate_fx = total_brate; /* used for the codec banner output */ - if (st->bfi_fx == 0 && speech_lost == 0 && no_data == 0) + st->total_brate = total_brate; /* used for the codec banner output */ + if (st->bfi == 0 && speech_lost == 0 && no_data == 0) { decoder_selectCodec(st, total_brate, unpack_bit(&pt_pFrame, &mask) ? G192_BIN1 : G192_BIN0); } @@ -2060,12 +2060,12 @@ Word16 read_indices_mime( /* o : 1 = reading OK, 0 = problem /* unpack speech data */ - bit_stream_ptr = st->bit_stream_fx; + bit_stream_ptr = st->bit_stream; for (k = 0; k < num_bits; k++) { if (isAMRWB_IOmode) { - st->bit_stream_fx[sort_ptr[core_mode][k]] = unpack_bit(&pt_pFrame, &mask); + st->bit_stream[sort_ptr[core_mode][k]] = unpack_bit(&pt_pFrame, &mask); bit_stream_ptr++; } else @@ -2099,13 +2099,13 @@ Word16 read_indices_mime( /* o : 1 = reading OK, 0 = problem total_brate = read_indices_mime_handle_dtx(st, isAMRWB_IOmode, core_mode, total_brate, sti, speech_lost, no_data); } - if (st->bfi_fx == 0) + if (st->bfi == 0) { /* select MODE1 or MODE2 in MIME */ - decoder_selectCodec(st, total_brate, *st->bit_stream_fx ? G192_BIN1 : G192_BIN0); + decoder_selectCodec(st, total_brate, *st->bit_stream ? G192_BIN1 : G192_BIN0); /* a change of the total bitrate should not be known to the decoder, if the received frame was truly lost */ - st->total_brate_fx = total_brate; + st->total_brate = total_brate; mdct_switching_dec(st); } /* else{ bfi stay in past synthesis mode(SP,CNG) } */ @@ -2125,7 +2125,7 @@ static void berCheck( ) { /* In case of RF flag = 1, and valid RF packet with primary and partial copy */ - if ((EQ_16(st->bwidth_fx, NB) || EQ_16(st->bwidth_fx, FB)) + if ((EQ_16(st->bwidth, NB) || EQ_16(st->bwidth, FB)) || (GE_16(*coder_type, TRANSITION)) ) { @@ -2135,9 +2135,9 @@ static void berCheck( move16(); } - st->bfi_fx = 1; + st->bfi = 1; move16(); - st->bwidth_fx = st->last_bwidth_fx; + st->bwidth = st->last_bwidth; move16(); st->BER_detect = 1; move16(); @@ -2178,26 +2178,26 @@ void getPartialCopyInfo( IF(EQ_16(st->rf_flag, 1)) { *coder_type = s_and(ind, 0x7); - st->bwidth_fx = s_and(shr(ind, 3), 0x7); + st->bwidth = s_and(shr(ind, 3), 0x7); *sharpFlag = s_and(shr(ind, 6), 0x1); st->codec_mode = MODE2; move16(); get_rfTargetBits(st->rf_frame_type, &(st->rf_target_bits)); - IF(EQ_16(st->bfi_fx, FRAMEMODE_FUTURE)) + IF(EQ_16(st->bfi, FRAMEMODE_FUTURE)) { st->use_partial_copy = 1; /* now set the frame mode to normal mode */ test(); IF(GE_16(st->rf_frame_type, RF_TCXFD) && LE_16(st->rf_frame_type, RF_TCXTD2)) { - st->bfi_fx = 1; - st->core_fx = 1; + st->bfi = 1; + st->core = 1; } ELSE { - st->bfi_fx = FRAMEMODE_NORMAL; - st->core_fx = 0; + st->bfi = FRAMEMODE_NORMAL; + st->core = 0; } } /* check for bit errors */ @@ -2230,11 +2230,11 @@ void get_rfFlag( /* check for rf_flag in the packet and extract the rf_frame_type and rf_fec_offset */ test(); test(); - IF(EQ_32(st->total_brate_fx, ACELP_13k20) && (EQ_16(st->bfi_fx, FRAMEMODE_NORMAL) || EQ_16(st->bfi_fx, FRAMEMODE_FUTURE))) + IF(EQ_32(st->total_brate, ACELP_13k20) && (EQ_16(st->bfi, FRAMEMODE_NORMAL) || EQ_16(st->bfi, FRAMEMODE_FUTURE))) { /* find the section in the ACELP signalling table corresponding to bitrate */ start_idx = 0; - WHILE(NE_32(acelp_sig_tbl[start_idx], st->total_brate_fx)) + WHILE(NE_32(acelp_sig_tbl[start_idx], st->total_brate)) { start_idx++; assert((start_idx < MAX_ACELP_SIG) && "ERROR: start_idx larger than acelp_sig_tbl[].\n"); @@ -2247,7 +2247,7 @@ void get_rfFlag( nBits_tmp = (Word16)acelp_sig_tbl[start_idx++]; /* retrieve the signalling indice */ - ind_tmp = (Word16)acelp_sig_tbl[start_idx + get_indice_fx(st, 0, nBits_tmp)]; + ind_tmp = (Word16)acelp_sig_tbl[start_idx + get_indice(st, 0, nBits_tmp)]; /* convert signalling indice into RF flag. */ *rf_flag = s_and(shr(ind_tmp, 7), 0x1); @@ -2279,8 +2279,8 @@ void get_rfFrameType( IF(EQ_16(st->rf_flag, 1)) { - /*num_bits = st->total_brate_fx/50;*/ - if (EQ_32(st->total_brate_fx, ACELP_13k20)) + /*num_bits = st->total_brate/50;*/ + if (EQ_32(st->total_brate, ACELP_13k20)) { num_bits = 264; move16(); /* @13.2kbps */ @@ -2289,12 +2289,12 @@ void get_rfFrameType( { UWord16 lsb; Word32 L_tmp; - Mpy_32_16_ss(st->total_brate_fx, 5243, &L_tmp, &lsb); /* 5243 is 1/50 in Q18. (0+18-15=3) */ + Mpy_32_16_ss(st->total_brate, 5243, &L_tmp, &lsb); /* 5243 is 1/50 in Q18. (0+18-15=3) */ num_bits = extract_l(L_shr(L_tmp, 3)); /* Q0 */ } /* the last three bits in a packet is the RF frame type */ - *rf_frame_type = get_indice_fx(st, num_bits - 3, 3); + *rf_frame_type = get_indice(st, num_bits - 3, 3); } ELSE { @@ -2317,8 +2317,8 @@ void get_rf_fec_offset( IF(EQ_16(st->rf_flag, 1)) { - /*num_bits = st->total_brate_fx/50;*/ - if (EQ_32(st->total_brate_fx, ACELP_13k20)) + /*num_bits = st->total_brate/50;*/ + if (EQ_32(st->total_brate, ACELP_13k20)) { num_bits = 264; move16(); /* @13.2kbps */ @@ -2327,12 +2327,12 @@ void get_rf_fec_offset( { UWord16 lsb; Word32 L_tmp; - Mpy_32_16_ss(st->total_brate_fx, 5243, &L_tmp, &lsb); /* 5243 is 1/50 in Q18. (0+18-15=3) */ + Mpy_32_16_ss(st->total_brate, 5243, &L_tmp, &lsb); /* 5243 is 1/50 in Q18. (0+18-15=3) */ num_bits = extract_l(L_shr(L_tmp, 3)); /* Q0 */ } /* the two bits before the rf frame type contain the fec offset */ - tmp = get_indice_fx(st, num_bits - 5, 2); + tmp = get_indice(st, num_bits - 5, 2); if (tmp == 0) { @@ -2468,13 +2468,13 @@ void read_indices_from_djb_fx( Word32 total_brate; Word16 speech_lost = 0; - st->bfi_fx = 0; + st->bfi = 0; st->BER_detect = 0; st->mdct_sw_enable = 0; st->mdct_sw = 0; reset_indices_dec_fx(st); - st->bfi_fx = !qbit; + st->bfi = !qbit; total_brate = (Word32)(num_bits) * 50; st->total_num_bits = num_bits; @@ -2495,17 +2495,17 @@ void read_indices_from_djb_fx( if (partialframe == 1) { - st->bfi_fx = 2; + st->bfi = 2; } /* unpack speech data */ - bit_stream_ptr = st->bit_stream_fx; + bit_stream_ptr = st->bit_stream; /* convert bitstream from compact bytes to short values and store it in decoder state */ for (k = 0; k < num_bits; k++) { if (st->bitstreamformat == VOIP_RTPDUMP && isAMRWB_IOmode) { - st->bit_stream_fx[sort_ptr[core_mode][k]] = unpack_bit(&pt_stream, &mask); + st->bit_stream[sort_ptr[core_mode][k]] = unpack_bit(&pt_stream, &mask); bit_stream_ptr++; } else @@ -2540,13 +2540,13 @@ void read_indices_from_djb_fx( total_brate = read_indices_mime_handle_dtx(st, isAMRWB_IOmode, core_mode, total_brate, sti, speech_lost, no_data); /* st->CNG_fx set inside */ - if (st->bfi_fx != 1) + if (st->bfi != 1) { /* select Mode 1 or Mode 2 */ - decoder_selectCodec(st, total_brate, *st->bit_stream_fx ? G192_BIN1 : G192_BIN0); + decoder_selectCodec(st, total_brate, *st->bit_stream ? G192_BIN1 : G192_BIN0); /* a change of the total bitrate should not be known to the decoder, if the received frame was truly lost */ - st->total_brate_fx = total_brate; + st->total_brate = total_brate; mdct_switching_dec(st); } diff --git a/lib_com/calc_st_com.c b/lib_com/calc_st_com.c index 59ceb09daf7a34f815912237997fbf61187b0d74..e50071407b12831d257fe790697970e9a66f110a 100644 --- a/lib_com/calc_st_com.c +++ b/lib_com/calc_st_com.c @@ -210,13 +210,13 @@ void filt_mu( /*---------------------------------------------------------------------------- - * scale_st() + * scale_st_ivas() * * control of the subframe gain * gain[n] = AGC_FAC_FX * gain[n-1] + (1 - AGC_FAC_FX) g_in/g_out *---------------------------------------------------------------------------*/ -void scale_st( +void scale_st_ivas( const float *sig_in, /* i : postfilter input signal */ float *sig_out, /* i/o: postfilter output signal */ float *gain_prec, /* i/o: last value of gain for subframe */ @@ -286,7 +286,7 @@ void scale_st( return; } -void blend_subfr2( +void blend_subfr2_flt( float *sigIn1, float *sigIn2, float *sigOut ) diff --git a/lib_com/cb_shape_fx.c b/lib_com/cb_shape_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..293d15ca523c9ce5ff891a8e80e641e3c3e7f980 --- /dev/null +++ b/lib_com/cb_shape_fx.c @@ -0,0 +1,135 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ +#include +#include "options.h" /* Compilation switches */ +#include "cnst.h" /* Common constants */ +#include "prot_fx1.h" /* Function prototypes */ +#include "prot_fx2.h" /* Function prototypes */ +#include "rom_com.h" /* */ + +/* + * E_GAIN_f_pitch_sharpening + * + * Parameters: + * x I/O: impulse response (or algebraic code) + * pit_lag I: pitch lag + * + * Function: + * Performs Pitch sharpening routine for one subframe. + * pitch sharpening factor is 0.85 + * + * Returns: + * void + */ +static void E_GAIN_f_pitch_sharpening(Word16 *x, Word16 pit_lag, Word16 L_subfr) +{ + Word16 i, tmp; + + FOR (i = pit_lag; i < L_subfr; i++) + { + /*x[i] += x[i - pit_lag] * F_PIT_SHARP;*/ + tmp = mult_r(x[i - pit_lag], 27853/*F_PIT_SHARP Q15*/); + x[i] = add(x[i],tmp); + move16(); + } + return; +} + +/*-------------------------------------------------------------------* + * cb_shape() + * + * pre-emphasis, pitch sharpening and formant sharpening of the algebraic codebook + *-------------------------------------------------------------------*/ + +void cb_shape_fx( + const Word16 preemphFlag, /* i : flag for pre-emphasis */ + const Word16 pitchFlag, /* i : flag for pitch sharpening */ + const Word16 scramblingFlag, /* i : flag for phase scrambling */ + const Word16 sharpFlag, /* i : flag for formant sharpening */ + const Word16 formantTiltFlag, /* i : flag for formant tilt */ + const Word16 g1, /* i : formant sharpening numerator weighting */ + const Word16 g2, /* i : formant sharpening denominator weighting */ + const Word16 *p_Aq, /* i : LP filter coefficients */ + Word16 *code, /* i/o: signal to shape */ + const Word16 tilt_code, /* i : tilt of code */ + const Word16 pt_pitch, /* i : pointer to current subframe fractional pitch */ + const Word16 shift, + const Word16 L_subfr /* i : subframe lenght */ +) +{ + Word16 tmp, buff[2*L_SUBFR + M], A_num[M + 1], A_den[M + 1]; + Word16 i; + Word32 L_tmp; + Word16 tilt, mu; + + tmp = 0; + + move16(); + + /* Pre-emphasis */ + IF( preemphFlag ) + { + preemph_copy_fx(code, code, tilt_code, L_subfr, &tmp); + } + + /* pitch sharpening */ + IF( pitchFlag ) + { + E_GAIN_f_pitch_sharpening( code, pt_pitch, L_subfr); + } + + /* phase scrambling filter */ + IF( scramblingFlag ) + { + buff[0] = code[0]; + move16(); + FOR (i = 1; i < L_subfr; i++) + { + buff[i]=code[i]; + move16(); + /*code[i] = 0.7f*buff[i] + buff[i-1] - 0.7f*code[i-1]; */ + L_tmp = L_mult(22938, buff[i]); + tmp = mac_r(L_tmp,-22938, code[i-1]); + code[i] = add(tmp,buff[i-1]); + move16(); + } + } + + test(); + IF ( sharpFlag || formantTiltFlag ) + { + weight_a_fx( p_Aq, A_num, g1, M ); + weight_a_fx( p_Aq, A_den, g2, M ); + set16_fx(buff, 0, M+ L_subfr); + IF( formantTiltFlag ) + { + Copy(A_num, buff+M, M+1); + + E_UTIL_synthesis(1, A_den, buff+M, buff+M, L_subfr, buff, 0, M); + + /*Compute tilt of formant enhancement*/ + tilt = extract_l(L_shr(get_gain(buff+M+1, buff+M, L_subfr -1),1)); + + /*Combine tilt of code and fe*/ + tmp = 0; + move16(); + /*mu = 0.5f*tilt_code-0.25f*tilt;*/ + mu = sub(shr(tilt_code,1),shr(tilt,2)); + preemph_copy_fx(code, code, mu, L_subfr, &tmp); + } + ELSE + { + Copy( code, buff, L_subfr); + + move16(); + Residu3_lc_fx(A_num, M, buff, code, L_subfr, shift); + { + syn_filt_s_lc_fx(shift, A_den, code, code, L_subfr); + } + } + } + + return; +} + diff --git a/lib_com/cldfb.c b/lib_com/cldfb.c index 6aecdb7f3bc8a039e3f68f4b75f0213539133b7f..14fcff48af21f3b087ab231f335a66a3879e7328 100644 --- a/lib_com/cldfb.c +++ b/lib_com/cldfb.c @@ -58,7 +58,7 @@ static void cldfb_init_proto_and_twiddles( HANDLE_CLDFB_FILTER_BANK hs ); -static float GetEnergyCldfb( float *energyValuesSum, float *energyLookahead, float **realValues, float **imagValues, const int16_t numberBands, int16_t numberCols, TEC_ENC_HANDLE hTecEnc ); +static float GetEnergyCldfb_ivas( float *energyValuesSum, float *energyLookahead, float **realValues, float **imagValues, const int16_t numberBands, int16_t numberCols, TEC_ENC_HANDLE hTecEnc ); /*-------------------------------------------------------------------* * cplxMult() @@ -83,12 +83,12 @@ static void cplxMult( /*-------------------------------------------------------------------* - * cldfbAnalysis() + * cldfbAnalysis_ivas() * * Conduct multiple overlap complex low delay MDCT *--------------------------------------------------------------------*/ -void cldfbAnalysis( +void cldfbAnalysis_ivas( const float *timeIn, /* i : time buffer */ float **realBuffer, /* o : real value buffer */ float **imagBuffer, /* o : imag value buffer */ @@ -257,12 +257,12 @@ void cldfbAnalysis( } /*-------------------------------------------------------------------* - * cldfbAnalysis_ts() + * cldfbAnalysis_ts_ivas() * * *--------------------------------------------------------------------*/ -void cldfbAnalysis_ts( +void cldfbAnalysis_ts_ivas( const float *timeIn, /* i : time buffer */ float realBuffer[CLDFB_NO_CHANNELS_MAX], /* o : real value buffer */ float imagBuffer[CLDFB_NO_CHANNELS_MAX], /* o : imag value buffer */ @@ -477,12 +477,12 @@ void cldfbAnalysis_ts( } /*-------------------------------------------------------------------* - * cldfbSynthesis() + * cldfbSynthesis_ivas() * * Conduct inverse multple overlap cmplex low delay MDCT *--------------------------------------------------------------------*/ -void cldfbSynthesis( +void cldfbSynthesis_ivas( float **realBuffer, /* i : real values */ float **imagBuffer, /* i : imag values */ float *timeOut, /* o : output time domain samples */ @@ -669,7 +669,7 @@ void cldfbSynthesis( * configures a CLDFB handle *--------------------------------------------------------------------*/ -void configureCldfb( +void configureCldfb_ivas( HANDLE_CLDFB_FILTER_BANK h_cldfb, /* i/o: filter bank handle */ const int32_t sampling_rate /* i : sampling rate */ ) @@ -693,7 +693,7 @@ void configureCldfb( * open and configures a CLDFB handle *--------------------------------------------------------------------*/ -ivas_error openCldfb( +ivas_error openCldfb_ivas( HANDLE_CLDFB_FILTER_BANK *h_cldfb, /* i/o: filter bank handle */ CLDFB_TYPE type, /* i : analysis or synthesis */ const int32_t sampling_rate, /* i : sampling rate */ @@ -711,7 +711,7 @@ ivas_error openCldfb( hs->type = type; hs->prototype = prototype; - configureCldfb( hs, sampling_rate ); + configureCldfb_ivas( hs, sampling_rate ); hs->memory_flt = NULL; hs->memory_length = 0; @@ -738,12 +738,12 @@ ivas_error openCldfb( /*-------------------------------------------------------------------* - * resampleCldfb() + * resampleCldfb_ivas() * * Change sample rate of filter bank *--------------------------------------------------------------------*/ -void resampleCldfb( +void resampleCldfb_ivas( HANDLE_CLDFB_FILTER_BANK hs, /* i/o: filter bank handle */ const int32_t newSamplerate ) { @@ -753,7 +753,7 @@ void resampleCldfb( int16_t timeOffsetold = hs->p_filter_length - hs->no_channels; /* new settings */ - configureCldfb( hs, newSamplerate ); + configureCldfb_ivas( hs, newSamplerate ); timeOffset = hs->p_filter_length - hs->no_channels; /*low complexity-resampling only stored previous samples that are needed for next frame modulation */ @@ -768,7 +768,7 @@ void resampleCldfb( * Encoder CLDFB analysis + energy stage *--------------------------------------------------------------------*/ -void analysisCldfbEncoder( +void analysisCldfbEncoder_ivas( Encoder_State *st, /* i/o: encoder state structure */ const float *timeIn, const int16_t samplesToProcess, @@ -786,20 +786,20 @@ void analysisCldfbEncoder( ppBuf_Imag[i] = &imagBuffer[i][0]; } - cldfbAnalysis( timeIn, ppBuf_Real, ppBuf_Imag, samplesToProcess, st->cldfbAnaEnc ); + cldfbAnalysis_ivas( timeIn, ppBuf_Real, ppBuf_Imag, samplesToProcess, st->cldfbAnaEnc ); - st->currEnergyHF = GetEnergyCldfb( ppBuf_Ener, &st->currEnergyLookAhead, ppBuf_Real, ppBuf_Imag, st->cldfbAnaEnc->no_channels, st->cldfbAnaEnc->no_col, st->hTECEnc ); + st->currEnergyHF = GetEnergyCldfb_ivas( ppBuf_Ener, &st->currEnergyLookAhead, ppBuf_Real, ppBuf_Imag, st->cldfbAnaEnc->no_channels, st->cldfbAnaEnc->no_col, st->hTECEnc ); return; } /*-------------------------------------------------------------------* - * GetEnergyCldfb() + * GetEnergyCldfb_ivas() * * Conduct energy from complex data *--------------------------------------------------------------------*/ -static float GetEnergyCldfb( +static float GetEnergyCldfb_ivas( float *energyValuesSum, /* o : the result of the operation */ float *energyLookahead, /* o : the result in the core look-ahead slot */ float **realValues, /* i : the real part of the subsamples */ @@ -869,12 +869,12 @@ static float GetEnergyCldfb( /*-------------------------------------------------------------------* - * GetEnergyCldfb() + * GetEnergyCldfb_ivas() * * Remove handle *--------------------------------------------------------------------*/ -void deleteCldfb( +void deleteCldfb_ivas( HANDLE_CLDFB_FILTER_BANK *h_cldfb /* i/o: filter bank handle */ ) { @@ -918,7 +918,7 @@ static void cldfb_init_proto_and_twiddles( if ( hs->prototype == CLDFB_PROTOTYPE_1_25MS ) { - hs->p_filter_flt = CLDFB80_10; + hs->p_filter_flt = CLDFB80_10_flt; hs->scale_flt = CLDFB80_10_SCALE; hs->ds = 10; hs->da = 10; @@ -947,7 +947,7 @@ static void cldfb_init_proto_and_twiddles( hs->rot_vec_syn_im = rot_vec_syn_im_L16; if ( hs->prototype == CLDFB_PROTOTYPE_1_25MS ) { - hs->p_filter_flt = CLDFB80_16; + hs->p_filter_flt = CLDFB80_16_flt; hs->scale_flt = CLDFB80_16_SCALE; hs->ds = 20; hs->da = 20; @@ -976,7 +976,7 @@ static void cldfb_init_proto_and_twiddles( hs->rot_vec_syn_im = rot_vec_syn_im_L20; if ( hs->prototype == CLDFB_PROTOTYPE_1_25MS ) { - hs->p_filter_flt = CLDFB80_20; + hs->p_filter_flt = CLDFB80_20_flt; hs->scale_flt = CLDFB80_20_SCALE; hs->ds = 20; hs->da = 20; @@ -1005,7 +1005,7 @@ static void cldfb_init_proto_and_twiddles( hs->rot_vec_syn_im = rot_vec_syn_im_L30; if ( hs->prototype == CLDFB_PROTOTYPE_1_25MS ) { - hs->p_filter_flt = CLDFB80_30; + hs->p_filter_flt = CLDFB80_30_flt; hs->scale_flt = CLDFB80_30_SCALE; hs->ds = 30; hs->da = 30; @@ -1034,7 +1034,7 @@ static void cldfb_init_proto_and_twiddles( hs->rot_vec_syn_im = rot_vec_syn_im_L32; if ( hs->prototype == CLDFB_PROTOTYPE_1_25MS ) { - hs->p_filter_flt = CLDFB80_32; + hs->p_filter_flt = CLDFB80_32_flt; hs->scale_flt = CLDFB80_32_SCALE; hs->ds = 32; hs->da = 32; @@ -1063,7 +1063,7 @@ static void cldfb_init_proto_and_twiddles( hs->rot_vec_syn_im = rot_vec_syn_im_L40; if ( hs->prototype == CLDFB_PROTOTYPE_1_25MS ) { - hs->p_filter_flt = CLDFB80_40; + hs->p_filter_flt = CLDFB80_40_flt; hs->scale_flt = CLDFB80_40_SCALE; hs->ds = 40; hs->da = 40; @@ -1092,7 +1092,7 @@ static void cldfb_init_proto_and_twiddles( hs->rot_vec_syn_im = rot_vec_syn_im_L60; if ( hs->prototype == CLDFB_PROTOTYPE_1_25MS ) { - hs->p_filter_flt = CLDFB80_60; + hs->p_filter_flt = CLDFB80_60_flt; hs->scale_flt = CLDFB80_60_SCALE; hs->ds = 60; hs->da = 60; @@ -1120,12 +1120,12 @@ static void cldfb_init_proto_and_twiddles( /*-------------------------------------------------------------------* - * cldfb_save_memory() + * cldfb_save_memory_ivas() * - * Save the memory of filter; to be restored with cldfb_restore_memory() + * Save the memory of filter; to be restored with cldfb_restore_memory_ivas() *--------------------------------------------------------------------*/ -ivas_error cldfb_save_memory( +ivas_error cldfb_save_memory_ivas( HANDLE_CLDFB_FILTER_BANK hs /* i/o: filter bank handle */ ) { @@ -1159,12 +1159,12 @@ ivas_error cldfb_save_memory( /*-------------------------------------------------------------------* - * cldfb_restore_memory() + * cldfb_restore_memory_ivas() * - * Restores the memory of filter; memory to be save by cldfb_save_memory() + * Restores the memory of filter; memory to be save by cldfb_save_memory_ivas() *--------------------------------------------------------------------*/ -void cldfb_restore_memory( +void cldfb_restore_memory_ivas( HANDLE_CLDFB_FILTER_BANK hs /* i/o: filter bank handle */ ) { @@ -1204,12 +1204,12 @@ void cldfb_restore_memory( /*-------------------------------------------------------------------* - * cldfb_reset_memory() + * cldfb_reset_memory_ivas() * * Resets the memory of filter. *--------------------------------------------------------------------*/ -void cldfb_reset_memory( +void cldfb_reset_memory_ivas( HANDLE_CLDFB_FILTER_BANK hs /* i/o: filter bank handle */ ) { diff --git a/lib_com/cldfb_evs.c b/lib_com/cldfb_evs.c new file mode 100644 index 0000000000000000000000000000000000000000..63b3030fae3d9ed303e39c5602988a81f839ab58 --- /dev/null +++ b/lib_com/cldfb_evs.c @@ -0,0 +1,1713 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ +/*! + \file + \brief Complex cldfb analysis/synthesis, $Revision: 1214 $ + This module contains the cldfb filterbank for analysis [ cplxAnalysisCldfbFiltering() ] and + synthesis [ cplxSynthesisCldfbFiltering() ]. It is a polyphase implementation of a complex + exponential modulated filter bank. The analysis part usually runs at half the sample rate + than the synthesis part. (So called "dual-rate" mode.) + + \anchor PolyphaseFiltering

About polyphase filtering

+ The polyphase implementation of a filterbank requires filtering at the input and output. + This is implemented as part of cplxAnalysisCldfbFiltering() and cplxSynthesisCldfbFiltering(). + +*/ + +#include "stl.h" +#include "cnst.h" +#include "stat_com.h" +#include "rom_com.h" +#include "basop_util.h" +#include "prot_fx1.h" +#include "prot_fx2.h" +#include + +#define STATE_BUFFER_SIZE ( 9+16 ) + +#define CLDFB_NO_POLY ( 5 ) +#define SYN_FILTER_HEADROOM ( 1 ) + +#define CLDFB_LDCLDFB_PFT_SCALE ( 0 ) +#define CLDFB_CLDFB80_O24_PFT_SCALE ( 1 ) +#define CLDFB_CLDFB80_O5_PFT_SCALE ( 1 ) +#define CLDFB_CLDFB80_PFT_SCALE ( 1 ) + + + +#define SYN_FILTER_HEADROOM_1MS ( 2 ) +#define SYN_FILTER_HEADROOM_2MS ( 2 ) +#define SYN_FILTER_HEADROOM_2_5MS ( 2 ) +#define SYN_FILTER_HEADROOM_8MS ( 1 ) + +#define N8 ( 4 ) +#define N10 ( 5 ) +#define N16 ( 8 ) +#define N20 ( 10 ) +#define N30 ( 15 ) +#define N32 ( 16 ) +#define N40 ( 20 ) +#define N60 ( 30 ) + +static void +cldfb_init_proto_and_twiddles(HANDLE_CLDFB_FILTER_BANK hs); + +#define cplxMpyS(yr,yi,xr,xi,cr,ci,syr,syi,sxr,sxi,CL_x,CL_z,C_c) CL_x = CL_form( *xr, *xi ); \ + C_c = C_form( *cr, *ci ); \ + CL_z = CL_mult_32x16( CL_x, C_c ); \ + *yr = CL_Extract_real( CL_z ); \ + *yi = CL_Extract_imag( CL_z ); \ + yr+=syr, yi+=syi, xr+=sxr, xi+=sxi, cr++, ci++ + +#define cplxMpy(ryr,ryi,iyr,iyi,rxr,rxi,ixr,ixi,cr,ci,g,sx,sr,CL_x,CL_ry,CL_iy,C_c) CL_x = CL_form( *rxr, *rxi ); \ + C_c = C_form( *cr, *ci ); \ + CL_ry = CL_mult_32x16( CL_x, C_c ); \ + CL_x = CL_form( *ixr, *ixi ); \ + CL_iy = CL_mult_32x16( CL_x, C_c ); \ + CL_ry = CL_scale_t( CL_ry, g ); \ + CL_iy = CL_scale_t( CL_iy, g ); \ + ryr = CL_Extract_real( CL_ry ); \ + ryi = CL_Extract_imag( CL_ry ); \ + iyr = CL_Extract_real( CL_iy ); \ + iyi = CL_Extract_imag( CL_iy ); \ + rxr+=sx, rxi+=sx, ixr+=sx, ixi+=sx, cr+=sr, ci+=sr +#ifdef BASOP_NOGLOB + +#define add1(y1,y2,y3,y4,rr12,ri12,ir12,ii12,s) *y1 = round_fx_sat(L_shl_sat(L_negate(L_add_sat(rr12,ii12)),s)); \ + *y2 = round_fx_sat(L_shl_sat(L_negate(L_add_sat(ri12,ir12)),s)); \ + *y3 = round_fx_sat(L_shl_sat(L_sub_sat(rr12,ii12),s)); \ + *y4 = round_fx_sat(L_shl_sat(L_sub_sat(ir12,ri12),s)); \ + y1+=2, y2-=2, y3-=2, y4+=2 + +#define add2(y1,y2,y3,y4,rr12,ri12,ir12,ii12,s) *y1 = round_fx_sat(L_shl_sat(L_add_sat(ri12,ir12),s)); \ + *y2 = round_fx_sat(L_shl_sat(L_add_sat(rr12,ii12),s)); \ + *y3 = round_fx_sat(L_shl_sat(L_sub_sat(ir12,ri12),s)); \ + *y4 = round_fx_sat(L_shl_sat(L_sub_sat(rr12,ii12),s)); \ + y1+=2, y2-=2, y3-=2, y4+=2 + +#else +#define add1(y1,y2,y3,y4,rr12,ri12,ir12,ii12,s) *y1 = round_fx(L_shl(L_negate(L_add(rr12,ii12)),s)); \ + *y2 = round_fx(L_shl(L_negate(L_add(ri12,ir12)),s)); \ + *y3 = round_fx(L_shl(L_sub(rr12,ii12),s)); \ + *y4 = round_fx(L_shl(L_sub(ir12,ri12),s)); \ + y1+=2, y2-=2, y3-=2, y4+=2 + +#define add2(y1,y2,y3,y4,rr12,ri12,ir12,ii12,s) *y1 = round_fx(L_shl(L_add(ri12,ir12),s)); \ + *y2 = round_fx(L_shl(L_add(rr12,ii12),s)); \ + *y3 = round_fx(L_shl(L_sub(ir12,ri12),s)); \ + *y4 = round_fx(L_shl(L_sub(rr12,ii12),s)); \ + y1+=2, y2-=2, y3-=2, y4+=2 +#endif + +#define ptrUpdate16(y11,y12,y13,y14,r11,x11,x12,x13,x14,r12,y21,y22,y23,y24,r21,x21,x22,x23,x24,r22) \ + y11 += 2*N8, y12 -= 2*N8, y13 -= 2*N8, y14 += 2*N8, r11 -= 1*N8; \ + x11 -= 2*N8, x12 -= 2*N8, x13 -= 2*N8, x14 -= 2*N8, r12 -= 1*N8; \ + y21 += 2*N8, y22 -= 2*N8, y23 -= 2*N8, y24 += 2*N8, r21 += 1*N8; \ + x21 += 2*N8, x22 += 2*N8, x23 += 2*N8, x24 += 2*N8, r22 += 1*N8 + +#define ptrUpdate20(y11,y12,y13,y14,r11,x11,x12,x13,x14,r12,y21,y22,y23,y24,r21,x21,x22,x23,x24,r22) \ + y11 += 2*N10, y12 -= 2*N10, y13 -= 2*N10, y14 += 2*N10, r11 -= 1*N10; \ + x11 -= 2*N10, x12 -= 2*N10, x13 -= 2*N10, x14 -= 2*N10, r12 -= 1*N10; \ + y21 += 2*N10, y22 -= 2*N10, y23 -= 2*N10, y24 += 2*N10, r21 += 1*N10; \ + x21 += 2*N10, x22 += 2*N10, x23 += 2*N10, x24 += 2*N10, r22 += 1*N10 + + + + +static void cplxMultAdd10_1(Word16 *rY1, Word16 *rY2, Word16 *rY3, Word16 *rY4, + Word32 *rXR, Word32 *rXI, Word32 *iXR, Word32 *iXI, + const Word16 *cr, const Word16 *ci, Word16 gv, Word16 s, + Word16 sx, Word16 sr) +{ + Word32 rr12, ri12, ir12, ii12; + cmplx CL_x,CL_ry, CL_iy; + cmplx_s C_c; + + cplxMpy(rr12, ri12, ir12, ii12, rXR, rXI, iXR, iXI, cr, ci, gv, sx, sr,CL_x,CL_ry, CL_iy,C_c); + add1(rY1, rY2, rY3, rY4, rr12, ri12, ir12, ii12, s); + cplxMpy(rr12, ri12, ir12, ii12, rXR, rXI, iXR, iXI, cr, ci, gv, sx, sr,CL_x,CL_ry, CL_iy,C_c); + add1(rY1, rY2, rY3, rY4, rr12, ri12, ir12, ii12, s); + +} + +static void cplxMultAdd10_2(Word16 *rY1, Word16 *rY2, Word16 *rY3, Word16 *rY4, + Word32 *rXR, Word32 *rXI, Word32 *iXR, Word32 *iXI, + const Word16 *cr, const Word16 *ci, Word16 gv, Word16 s, + Word16 sx, Word16 sr) +{ + Word32 rr12, ri12, ir12, ii12; + cmplx CL_x,CL_ry, CL_iy; + cmplx_s C_c; + + cplxMpy(rr12, ri12, ir12, ii12, rXR, rXI, iXR, iXI, cr, ci, gv, sx, sr, CL_x, CL_ry, CL_iy, C_c); + add2(rY1, rY2, rY3, rY4, rr12, ri12, ir12, ii12, s); + cplxMpy(rr12, ri12, ir12, ii12, rXR, rXI, iXR, iXI, cr, ci, gv, sx, sr, CL_x, CL_ry, CL_iy, C_c); + add2(rY1, rY2, rY3, rY4, rr12, ri12, ir12, ii12, s); + cplxMpy(rr12, ri12, ir12, ii12, rXR, rXI, iXR, iXI, cr, ci, gv, sx, sr, CL_x, CL_ry, CL_iy, C_c); + add2(rY1, rY2, rY3, rY4, rr12, ri12, ir12, ii12, s); + +} + + +static void cplxMultAdd20_1(Word16 *rY1, Word16 *rY2, Word16 *rY3, Word16 *rY4, + Word32 *rXR, Word32 *rXI, Word32 *iXR, Word32 *iXI, + const Word16 *cr, const Word16 *ci, Word16 gv, Word16 s, + Word16 sx, Word16 sr) +{ + Word32 rr12, ri12, ir12, ii12; + cmplx CL_x,CL_ry, CL_iy; + cmplx_s C_c; + + cplxMpy(rr12, ri12, ir12, ii12, rXR, rXI, iXR, iXI, cr, ci, gv, sx, sr, CL_x, CL_ry, CL_iy, C_c); + add1(rY1, rY2, rY3, rY4, rr12, ri12, ir12, ii12, s); + cplxMpy(rr12, ri12, ir12, ii12, rXR, rXI, iXR, iXI, cr, ci, gv, sx, sr, CL_x, CL_ry, CL_iy, C_c); + add1(rY1, rY2, rY3, rY4, rr12, ri12, ir12, ii12, s); + cplxMpy(rr12, ri12, ir12, ii12, rXR, rXI, iXR, iXI, cr, ci, gv, sx, sr, CL_x, CL_ry, CL_iy, C_c); + add1(rY1, rY2, rY3, rY4, rr12, ri12, ir12, ii12, s); + cplxMpy(rr12, ri12, ir12, ii12, rXR, rXI, iXR, iXI, cr, ci, gv, sx, sr, CL_x, CL_ry, CL_iy, C_c); + add1(rY1, rY2, rY3, rY4, rr12, ri12, ir12, ii12, s); + cplxMpy(rr12, ri12, ir12, ii12, rXR, rXI, iXR, iXI, cr, ci, gv, sx, sr, CL_x, CL_ry, CL_iy, C_c); + add1(rY1, rY2, rY3, rY4, rr12, ri12, ir12, ii12, s); + + +} + +static void cplxMultAdd20_2(Word16 *rY1, Word16 *rY2, Word16 *rY3, Word16 *rY4, + Word32 *rXR, Word32 *rXI, Word32 *iXR, Word32 *iXI, + const Word16 *cr, const Word16 *ci, Word16 gv, Word16 s, + Word16 sx, Word16 sr) +{ + Word32 rr12, ri12, ir12, ii12; + cmplx CL_x,CL_ry, CL_iy; + cmplx_s C_c; + + cplxMpy(rr12, ri12, ir12, ii12, rXR, rXI, iXR, iXI, cr, ci, gv, sx, sr, CL_x, CL_ry, CL_iy, C_c); + add2(rY1, rY2, rY3, rY4, rr12, ri12, ir12, ii12, s); + cplxMpy(rr12, ri12, ir12, ii12, rXR, rXI, iXR, iXI, cr, ci, gv, sx, sr, CL_x, CL_ry, CL_iy, C_c); + add2(rY1, rY2, rY3, rY4, rr12, ri12, ir12, ii12, s); + cplxMpy(rr12, ri12, ir12, ii12, rXR, rXI, iXR, iXI, cr, ci, gv, sx, sr, CL_x, CL_ry, CL_iy, C_c); + add2(rY1, rY2, rY3, rY4, rr12, ri12, ir12, ii12, s); + cplxMpy(rr12, ri12, ir12, ii12, rXR, rXI, iXR, iXI, cr, ci, gv, sx, sr, CL_x, CL_ry, CL_iy, C_c); + add2(rY1, rY2, rY3, rY4, rr12, ri12, ir12, ii12, s); + cplxMpy(rr12, ri12, ir12, ii12, rXR, rXI, iXR, iXI, cr, ci, gv, sx, sr, CL_x, CL_ry, CL_iy, C_c); + add2(rY1, rY2, rY3, rY4, rr12, ri12, ir12, ii12, s); + +} + +/* calcModulation + + Parameters: + *rYR O: pointer to real output samples (DST) + *rYI O: pointer to imaginary output samples (DST) + *rXR I: pointer to real input samples (DST) + *rXI I: pointer to imaginary input samples (DST) + srYR I: offset for update of pointer to real output samples (DST) + srYI I: offset for update of pointer to imaginary output samples (DST) + srXR I: offset for update of pointer to real input samples (DST) + srXI I: offset for update of pointer to imaginary input samples (DST) + *iYR O: pointer to real output samples (DCT) + *iYI O: pointer to imaginary output samples (DCT) + *iXR I: pointer to real input samples (DCT) + *iXI I: pointer to imaginary input samples (DCT) + siYR I: offset for update of pointer to real output samples (DCT) + siYI I: offset for update of pointer to imaginary output samples (DCT) + siXR I: offset for update of pointer to real input samples (DCT) + siXI I: offset for update of pointer to imaginary input samples (DCT) + m I: processed cldfb bands + + Function: + The function applies for each cldfb length a unrolled complex modulation + + Returns: + void +*/ +static void calcModulation( Word32 *rYR, + Word32 *rYI, + Word32 *rXR, + Word32 *rXI, + Word16 srYR, + Word16 srYI, + Word16 srXR, + Word16 srXI, + Word32 *iYR, + Word32 *iYI, + Word32 *iXR, + Word32 *iXI, + Word16 siYR, + Word16 siYI, + Word16 siXR, + Word16 siXI, + const Word16 *rRotVctr, + const Word16 *iRotVctr, + Word16 m + ) +{ + cmplx CL_x,CL_z; + cmplx_s C_c; + int i; + int lc = m >> 1; + + const Word16 *cr = rRotVctr; + const Word16 *ci = iRotVctr; + + for(i=0;ino_channels; + move16(); + L2 = shl(m,1); + m2 = shr(m,1); + M4 = shr(m,2); + M4 = sub(m2,M4); + + L3 = sub(L2,m2); + L4 = add(L2,m2); + + M0M2 = sub(0,m2); + M2M1 = sub(m2,1); + L3M1 = sub(L3,1); + L4M1 = sub(L4,1); + + rBuffer = &pWorkBuffer[0]; + iBuffer = &pWorkBuffer[m]; + + rRotVctr = cldfbBank->rRotVctr; + iRotVctr = cldfbBank->iRotVctr; + + pStates = cldfbBank->FilterStates; + pStates1 = &pStates[L3M1]; + pStates2 = &pStates[L3]; + pStates3 = &pStates[m2]; + pStates4 = &pStates[M2M1]; + pStates5 = &pStates[L4M1]; + pStates6 = &pStates[M0M2]; + + p_stride = CLDFB_NO_POLY; + pFilter = &cldfbBank->p_filter[p_stride - CLDFB_NO_POLY]; + pFilter1 = &pFilter[p_stride*L3M1]; + pFilter2 = &pFilter[p_stride*L3]; + pFilter3 = &pFilter[p_stride*m2]; + pFilter4 = &pFilter[p_stride*M2M1]; + pFilter5 = &pFilter[p_stride*L4M1]; + pFilter6 = &pFilter[p_stride*M0M2]; + + nSamples = i_mult(nTimeSlots, cldfbBank->no_channels); + nSamplesUpd = i_mult(cldfbBank->no_col, cldfbBank->no_channels); + offset = sub(sub(cldfbBank->p_filter_length, cldfbBank->no_channels),cldfbBank->zeros); + + /* Determine states scale */ + scale = -15; + move16(); + k = 0; + move16(); + FOR (i=0; ino_channels) + { + cldfbBank->FilterStates_e[k] = cldfbBank->FilterStates_e[k+cldfbBank->no_col]; + move16(); + assert((size_t)k < sizeof(cldfbBank->FilterStates_e)/sizeof(cldfbBank->FilterStates_e[0])); + scale = s_max(scale, cldfbBank->FilterStates_e[k]); + k = add(k,1); + } + FOR (i=0; ino_channels) + { + cldfbBank->FilterStates_e[k] = timeIn_e; + move16(); + assert((size_t)k < sizeof(cldfbBank->FilterStates_e)/sizeof(cldfbBank->FilterStates_e[0])); + scale = s_max(scale, cldfbBank->FilterStates_e[k]); + k = add(k,1); + } + i = s_max(scale, timeIn_e); + scale = sub(cldfbBank->FilterStates_eg, i); + cldfbBank->FilterStates_eg = i; + move16(); + + /* if nTimeSlots==0, make sure we have a value. */ + scaleFactor->lb_scale = add(cldfbBank->anaScalefactor, add(cldfbBank->FilterStates_eg, 5)); + move16(); + + /* move and scale filter states */ + FOR (i=0; iFilterStates_eg); + FOR (i=0; ilb_scale = add(cldfbBank->anaScalefactor, add(cldfbBank->FilterStates_eg, scale)); + move16(); + + /* FFT of DCT IV */ + BASOP_cfft((cmplx *)iBuffer, m2, &scale, workBuffer); + + /* post modulation of DST IV and DCT IV */ + calcModulation(&rAnalysis[k][m-1], &rAnalysis[k][0], &rBuffer[0], &rBuffer[1],-2, 2, 2, 2, + &iAnalysis[k][0], &iAnalysis[k][m-1], &iBuffer[0], &iBuffer[1], 2,-2, 2, 2, + rRotVctr, iRotVctr, m); + + + /* update states pointer */ + pStates1 = &pStates1[cldfbBank->no_channels]; + pStates2 = &pStates2[cldfbBank->no_channels]; + pStates3 = &pStates3[cldfbBank->no_channels]; + pStates5 = &pStates5[cldfbBank->no_channels]; + pStates4 = &pStates4[cldfbBank->no_channels]; + pStates6 = &pStates6[cldfbBank->no_channels]; + } + +} + + +/* cldfbSynthesisFiltering + + Parameters: + cldfbBank I/O: handle to analysis CLDFB filter struct + **rAnalysis I: matrix holding the real part of the subband samples + **iAnalysis I: matrix holding the imaginary part of the subband samples + *scaleFactor I: pointer to cldfb scalefactor struct + ov_len I: determines overlapping area in time slots (obsolete) + *timeOut O: pointer to time domain data + stride I: stride for time domain data + *pWorkBuffer I: pointer to scratch buffer, needed for buffer of size 2*cldfbbands*Word32 + 2*cldfbbands*Word16 + + Function: + Performs inverse complex-valued subband filtering of the subband samples in rAnalysis and iAnalysis + and stores the time domain data in timeOut + + Returns: + void +*/ +void +cldfbSynthesisFiltering( HANDLE_CLDFB_FILTER_BANK cldfbBank, + Word32 **rAnalysis, + Word32 **iAnalysis, + const CLDFB_SCALE_FACTOR *scaleFactor, + Word16 *timeOut, + const Word16 timeOut_e, + const Word16 nTimeSlots, + Word32 *pWorkBuffer + ) +{ + Word16 i; + Word16 k; + Word16 L2; + Word16 m; + Word16 m2; + Word16 Lz; + Word16 Mz; + Word32 acc; + Word16 offset1; + Word16 offset2; + Word16 channels0; + Word16 channels1; + Word16 channels2; + Word16 channels3; + Word16 channels4; + Word16 statesSizeM1; + Word16 statesSizeM2; + Word16 stride; + + Word16 scale, scaleMod; + Word16 outScale; + Word16 scaleLB; + Word16 scaleHB; + + Word32 *rAnalysisS; + Word32 *iAnalysisS; + + Word32 *rBuffer; + Word32 *iBuffer; + Word16 *nBuffer; + + Word16 *pStates; + Word16 *pStatesI; + Word16 *pStatesR; + + const Word16 *pFilterS; + const Word16 *pFilterM; + + const Word16 *rRotVctr; + const Word16 *iRotVctr; + Word32 workBuffer[2*BASOP_CFFT_MAX_LENGTH]; + + m = cldfbBank->no_channels; + move16(); + L2 = shl(m,1); + m2 = shr(m,1); + Lz = s_min(cldfbBank->lsb, sub(m,cldfbBank->bandsToZero)); + Mz = s_min(cldfbBank->usb, sub(m,cldfbBank->bandsToZero)); + stride = 1; /* constant */ + + channels0 = sub(m,cldfbBank->zeros); + channels1 = sub(m,1); + channels2 = shl(m,1); + channels3 = add(m,channels2); + channels4 = shl(channels2,1); + + statesSizeM1 = sub(shl(cldfbBank->p_filter_length,1),m); + statesSizeM2 = sub(statesSizeM1,m); + + offset1 = sub(channels1,cldfbBank->zeros); + offset2 = add(offset1,cldfbBank->no_channels); + + rBuffer = &pWorkBuffer[0]; + iBuffer = &pWorkBuffer[m]; + nBuffer = (Word16*)(&pWorkBuffer[L2]); + + rAnalysisS = &pWorkBuffer[3*m]; + iAnalysisS = &pWorkBuffer[4*m]; + + rRotVctr = cldfbBank->rRotVctr; + iRotVctr = cldfbBank->iRotVctr; + + scale = scaleFactor->lb_scale; + move16(); + if ( NE_16(Lz, Mz)) + { + scale = s_max(scale, scaleFactor->hb_scale); + } + scaleLB = limitScale32(sub(scale, scaleFactor->lb_scale)); + scaleHB = limitScale32(sub(scale, scaleFactor->hb_scale)); + + outScale = cldfbBank->synFilterHeadroom; + move16(); + + scaleMod = sub(add(scale, cldfbBank->outScalefactor), outScale); + + /* Increase CLDFB synthesis states for low level signals */ + IF ( LT_16(scale, 8)) + { + scaleMod = add(scaleMod, 2); + outScale = sub(outScale, 2); + } + scaleMod = sub(scaleMod, timeOut_e); + scale = add(outScale, timeOut_e); + IF ( NE_16(scale, cldfbBank->FilterStates_eg)) + { + Scale_sig(cldfbBank->FilterStates, statesSizeM2, sub(cldfbBank->FilterStates_eg, scale)); + cldfbBank->FilterStates_eg = scale; + move16(); + } + + FOR (k=0; k < nTimeSlots; k++) + { + { + FOR (i=0; i < Lz; i+=2) + { + rAnalysisS[i] = L_shr(rAnalysis[k][i],scaleLB); + move32(); + iAnalysisS[i] = L_negate(L_shr(iAnalysis[k][i],scaleLB)); + move32(); + } + + IF ( LT_16(i,Mz)) + { + FOR ( ; i < Mz; i+=2) + { + rAnalysisS[i] = L_shr(rAnalysis[k][i],scaleHB); + move32(); + iAnalysisS[i] = L_negate(L_shr(iAnalysis[k][i],scaleHB)); + move32(); + } + } + + IF ( LT_16(i,m)) + { + FOR ( ; i < m; i+=2) + { + rAnalysisS[i] = L_deposit_l(0); + iAnalysisS[i] = L_deposit_l(0); + } + } + + FOR (i=1; i < Lz; i+=2) + { + rAnalysisS[i] = L_shr(rAnalysis[k][i],scaleLB); + move32(); + iAnalysisS[i] = L_shr(iAnalysis[k][i],scaleLB); + move32(); + } + + IF ( LT_16(i,Mz)) + { + FOR ( ; i < Mz; i+=2) + { + rAnalysisS[i] = L_shr(rAnalysis[k][i],scaleHB); + move32(); + iAnalysisS[i] = L_shr(iAnalysis[k][i],scaleHB); + move32(); + } + } + + IF ( LT_16(i,m)) + { + FOR ( ; i < m; i+=2) + { + rAnalysisS[i] = L_deposit_l(0); + iAnalysisS[i] = L_deposit_l(0); + } + } + } + + /* pre modulation */ + calcModulation(&rBuffer[0], &rBuffer[1], &rAnalysisS[0], &rAnalysisS[m-1], 2, 2, 2,-2, + &iBuffer[0], &iBuffer[1], &iAnalysisS[0], &iAnalysisS[m-1], 2, 2, 2,-2, + rRotVctr, iRotVctr, m); + + + /* FFT of DST IV */ + scale = 0; + move16(); + BASOP_cfft((cmplx *)rBuffer, m2, &scale, workBuffer); + + /* FFT of DCT IV */ + scale = scaleMod; + move16(); + BASOP_cfft((cmplx *)iBuffer, m2, &scale, workBuffer); + + /* post modulation and folding */ + calcModulationAndFolding(nBuffer, rBuffer, iBuffer, rRotVctr, iRotVctr, cldfbBank->synGain, scale, m, m2); + + /* prototype filter */ + pStates = &cldfbBank->FilterStates[k*L2]; + pFilterS = &cldfbBank->p_filter[0]; + pFilterM = &cldfbBank->p_filter[shr(cldfbBank->p_filter_length,1)]; + + FOR (i=0; i < channels0; i++) + { + pStatesI = &pStates[i]; + pStatesR = &pStates[i+channels3]; + + acc = L_mult( *pStatesI, *pFilterS++); + acc = L_mac(acc, *pStatesR, *pFilterM++); + pStatesR += channels4; + pStatesI += channels4; + + acc = L_mac(acc, *pStatesI, *pFilterS++); + acc = L_mac(acc, *pStatesR, *pFilterM++); + pStatesR += channels4; + pStatesI += channels4; + + acc = L_mac(acc, *pStatesI, *pFilterS++); + acc = L_mac(acc, *pStatesR, *pFilterM++); + pStatesR += channels4; + pStatesI += channels4; + + acc = L_mac(acc, *pStatesI, *pFilterS++); + acc = L_mac(acc, *pStatesR, *pFilterM++); + pStatesI += channels4; + + acc = L_mac(acc, *pStatesI, *pFilterS++); + acc = L_mac(acc, nBuffer[channels1-i], *pFilterM++); + + BASOP_SATURATE_WARNING_OFF_EVS +#ifdef BASOP_NOGLOB + timeOut[(offset1-i)*stride] = round_fx_sat(L_shl_sat(acc,outScale)); +#else + timeOut[(offset1-i)*stride] = round_fx(L_shl(acc,outScale)); +#endif + BASOP_SATURATE_WARNING_ON_EVS + } + + FOR ( ; ino_channels; i++) + { + pStatesI = &pStates[i+channels2]; + pStatesR = &pStates[i+channels2+channels3]; + + acc = L_mult( *pStatesI, *pFilterS++); + acc = L_mac(acc, *pStatesR, *pFilterM++); + pStatesR += channels4; + pStatesI += channels4; + + acc = L_mac(acc, *pStatesI, *pFilterS++); + acc = L_mac(acc, *pStatesR, *pFilterM++); + pStatesR += channels4; + pStatesI += channels4; + + acc = L_mac(acc, *pStatesI, *pFilterS++); + acc = L_mac(acc, *pStatesR, *pFilterM++); + pStatesR += channels4; + pStatesI += channels4; + + acc = L_mac(acc, *pStatesI, *pFilterS++); + acc = L_mac(acc, *pStatesR, *pFilterM++); + + acc = L_mac(acc, nBuffer[channels1+m-i], *pFilterS++); + pFilterM++; + + BASOP_SATURATE_WARNING_OFF_EVS +#ifdef BASOP_NOGLOB + timeOut[(offset2-i)*stride] = round_fx_sat(L_shl_sat(acc,outScale)); +#else + timeOut[(offset2-i)*stride] = round_fx(L_shl(acc,outScale)); +#endif + BASOP_SATURATE_WARNING_ON_EVS + } + + FOR (i=0; ino_channels; i++) + { + pStates[statesSizeM1+i] = nBuffer[channels1-i]; + move16(); + pStates[statesSizeM2+i] = nBuffer[channels1+m-i]; + move16(); + } + + timeOut = &timeOut[m*stride]; + } + + /* move filter states */ + Copy(&cldfbBank->FilterStates[i_mult(nTimeSlots,L2)], cldfbBank->FilterStates, statesSizeM2); + set16_fx(&cldfbBank->FilterStates[statesSizeM2],0,L2); + +} + + +/*-------------------------------------------------------------------* + * configureClfdb() + * + * configures a CLDFB handle + *--------------------------------------------------------------------*/ + +void configureCldfb ( HANDLE_CLDFB_FILTER_BANK h_cldfb, /*!< Returns handle */ + const Word16 no_channels, /*!< Number of channels (bands) */ + const Word16 frameSize /*!< FrameSize */ + ) +{ + + h_cldfb->no_channels = no_channels; + move16(); + assert(h_cldfb->no_channels >= 10); + h_cldfb->no_col = div_l(frameSize,shr(h_cldfb->no_channels,1)); + + /* was cldfbInitFilterBank()*/ + h_cldfb->anaScalefactor = 0; + move16(); + h_cldfb->synScalefactor = 0; + move16(); + h_cldfb->bandsToZero = 0; + move16(); + h_cldfb->filtermode = 0; + move16(); + h_cldfb->memory = 0; + move16(); + h_cldfb->memory_length = 0; + move16(); + + h_cldfb->p_filter_length = i_mult(10,h_cldfb->no_channels); + move16(); + + h_cldfb->flags = s_or(h_cldfb->flags,CLDFB_FLAG_2_5MS_SETUP); + h_cldfb->filterScale = CLDFB_CLDFB80_PFT_SCALE; + move16(); + + h_cldfb->zeros = 0; + move16(); + h_cldfb->synFilterHeadroom = SYN_FILTER_HEADROOM_2_5MS; + move16(); + + cldfb_init_proto_and_twiddles (h_cldfb); + + h_cldfb->lsb = no_channels; + move16(); + h_cldfb->usb = s_min(no_channels, h_cldfb->no_channels); /* Does this make any sense? in the previous implemenatation lsb, usb and no_channels are all maxCldfbBands */ move16(); + + h_cldfb->FilterStates = (void*)h_cldfb->FilterStates; + h_cldfb->outScalefactor = h_cldfb->synScalefactor; + move16(); + + return; +} + +/*-------------------------------------------------------------------* + * openClfdb() + * + * open and configures a CLDFB handle + *--------------------------------------------------------------------*/ +ivas_error openCldfb ( + HANDLE_CLDFB_FILTER_BANK *h_cldfb, /*!< Returns handle */ + const Word16 type, /*!< analysis or synthesis */ + const Word16 maxCldfbBands, /*!< number of cldfb bands */ + const Word16 frameSize /*!< FrameSize */ +#ifdef ADD_IVAS_CLDFB + ,CLDFB_PROTOTYPE prototype /* i : CLDFB version (1.25ms/5ms delay) */ +#endif +) +{ + HANDLE_CLDFB_FILTER_BANK hs; + + hs = (HANDLE_CLDFB_FILTER_BANK)count_malloc(sizeof (CLDFB_FILTER_BANK)); + if (hs == NULL) + { + return IVAS_ERROR(IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for CLDFB"); + } + + hs->type = type; +#ifdef ADD_IVAS_CLDFB + hs->prototype = prototype; +#endif + move16(); + + IF (type == CLDFB_ANALYSIS) + { + hs->FilterStates = (Word16 *)count_malloc(STATE_BUFFER_SIZE*maxCldfbBands* sizeof (Word16)); + } + ELSE + { + hs->FilterStates = (Word16 *)count_malloc( 2 * STATE_BUFFER_SIZE * maxCldfbBands* sizeof (Word16)); + } + if (hs->FilterStates == NULL) + { + return IVAS_ERROR(IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for CLDFB"); + } + hs->flags &= ~CLDFB_FLAG_KEEP_STATES; + + configureCldfb (hs, maxCldfbBands, frameSize ); + + hs->memory = NULL; + hs->memory_length = 0; + move16(); + + IF( hs->type == CLDFB_ANALYSIS) + { + test(); + IF ( (s_and(hs->flags,CLDFB_FLAG_KEEP_STATES) == 0) && (hs->FilterStates != 0) ) + { + set16_fx(hs->FilterStates, 0, i_mult(STATE_BUFFER_SIZE,hs->no_channels)); + set16_fx(hs->FilterStates_e, 0, sizeof(hs->FilterStates_e)/sizeof(hs->FilterStates_e[0])); + + hs->FilterStates_eg = 0; + move16(); + } + } + ELSE IF (hs->type == CLDFB_SYNTHESIS ) + { + IF ( hs->FilterStates != 0 ) + { + IF ( s_and(hs->flags,CLDFB_FLAG_KEEP_STATES) == 0 ) + { + set16_fx(hs->FilterStates, 0, i_mult( shl(STATE_BUFFER_SIZE,1), hs->no_channels)); + } + } + hs->FilterStates_eg = 0; + move16(); + } + + if (h_cldfb != NULL) + { + *h_cldfb = hs; + } + + return IVAS_ERR_OK; +} + + +/*-------------------------------------------------------------------* +* resampleCldfb() +* +* Change sample rate of filter bank +*--------------------------------------------------------------------*/ +void resampleCldfb (HANDLE_CLDFB_FILTER_BANK hs, + const Word16 newCldfbBands, + const Word16 frameSize, + const Word8 firstFrame + ) + +{ + Word16 timeOffset; + Word16 timeOffsetOld; + Word16 noChannelsOld; + + noChannelsOld = hs->no_channels; + move16(); + timeOffsetOld = sub(sub(hs->p_filter_length,hs->no_channels),hs->zeros); + + /* change all CLDFB bank parameters that depend on the no of channels */ + hs->flags = s_or(hs->flags,CLDFB_FLAG_KEEP_STATES); + move16(); + + /* new settings */ + configureCldfb (hs, newCldfbBands, frameSize); + + /* resample cldfb state buffer */ + timeOffset = sub(sub(hs->p_filter_length,hs->no_channels),hs->zeros); + + IF( firstFrame == 0 ) + { + /*low complexity-resampling only stored previous samples that are needed for next frame modulation */ + lerp(hs->FilterStates+(noChannelsOld*hs->no_col), hs->FilterStates+(noChannelsOld*hs->no_col), timeOffset, timeOffsetOld); + Copy(hs->FilterStates+(noChannelsOld*hs->no_col), hs->FilterStates+frameSize, timeOffset); + } + + return; +} + +/* + AnalysisPostSpectrumScaling_Fx + + Parameters: + cldfbBank I: CLDFB handle + **rSubband32 I: matrix holding real part of the CLDFB subsamples + **iSubband32 I: matrix holding imaginary part of the CLDFB subsamples + **rSubband16 O: matrix holding real part of the CLDFB subsamples + **iSubband16 O: matrix holding imaginary part of the CLDFB subsamples + *cldfbScale O: cldfb lowband scalefactor + + Function: + performs dynamic spectrum scaling for all subband + + Returns: + headroom +*/ +Word16 +AnalysisPostSpectrumScaling_Fx (HANDLE_CLDFB_FILTER_BANK cldfbBank, /*!< Handle of cldfbBank */ + Word32 **rSubband32, /*!< Real bands */ + Word32 **iSubband32, /*!< Imaginary bands */ + Word16 **rSubband16, /*!< Real bands */ + Word16 **iSubband16, /*!< Imaginary bands */ + Word16 *cldfbScale /*!< CLDFB lowband scalefactor */ + ) +{ + Word16 i; + Word16 j; + Word16 headRoom; + + + + headRoom = BASOP_util_norm_l_dim2_cplx ( + (const Word32 * const*) rSubband32, + (const Word32 * const*) iSubband32, + 0, + cldfbBank->no_channels, + 0, + cldfbBank->no_col + ); + + FOR (i=0; i < cldfbBank->no_col; i++) + { + FOR (j=0; j < cldfbBank->no_channels; j++) + { + rSubband16[i][j] = round_fx(L_shl(rSubband32[i][j], headRoom)); + iSubband16[i][j] = round_fx(L_shl(iSubband32[i][j], headRoom)); + } + } + + *cldfbScale = add(*cldfbScale,headRoom); + move16(); + + + return headRoom; +} + + +/*-------------------------------------------------------------------* +* analysisCLDFBEncoder() +* +* Encoder CLDFB analysis + energy stage +*--------------------------------------------------------------------*/ + +void analysisCldfbEncoder_fx( + Encoder_State *st_fx, /* i/o: encoder state structure */ + const Word16 *timeIn, + Word32 realBuffer[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word32 imagBuffer[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word16 realBuffer16[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word16 imagBuffer16[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word32 enerBuffSum[CLDFB_NO_CHANNELS_MAX], + Word16 *enerBuffSum_exp, + CLDFB_SCALE_FACTOR * scale +) +{ + Word16 i; + CLDFB_SCALE_FACTOR enerScale; + Word32 *ppBuf_Real[CLDFB_NO_COL_MAX]; + Word32 *ppBuf_Imag[CLDFB_NO_COL_MAX]; + Word16 *ppBuf_Real16[CLDFB_NO_COL_MAX]; + Word16 *ppBuf_Imag16[CLDFB_NO_COL_MAX]; + Word32 workBuffer[256]; + Word16 num_slots = 1; + + FOR (i=0; icldfbAnaEnc, + ppBuf_Real, + ppBuf_Imag, + scale, + timeIn, + 0, + CLDFB_NO_COL_MAX, + workBuffer + ); + + enerScale.lb_scale = negate(scale->lb_scale); + enerScale.lb_scale16 = negate(scale->lb_scale); + + /* get 16bit respresentation */ + AnalysisPostSpectrumScaling_Fx ( + st_fx->cldfbAnaEnc, + ppBuf_Real, + ppBuf_Imag, + ppBuf_Real16, + ppBuf_Imag16, + &enerScale.lb_scale16 + ); + + /* get the energy */ + GetEnergyCldfb( &st_fx->energyCoreLookahead_Fx, + &st_fx->sf_energyCoreLookahead_Fx, + num_slots, + ppBuf_Real16, + ppBuf_Imag16, + enerScale.lb_scale16, + st_fx->cldfbAnaEnc->no_channels, + st_fx->cldfbAnaEnc->no_col, + &st_fx->currEnergyHF_fx, + &st_fx->currEnergyHF_e_fx, + enerBuffSum, + enerBuffSum_exp, + st_fx->hTECEnc + ); + + return; +} + +void +GetEnergyCldfb( Word32 *energyLookahead, /*!< o: Q(*sf_energyLookahead) | pointer to the result in the core look-ahead slot */ + Word16 *sf_energyLookahead, /*!< o: pointer to the scalefactor of the result in the core look-ahead slot */ + const Word16 numLookahead, /*!< i: Q0 the number of look-ahead time-slots */ + Word16 **realValues, /*!< i: Q(sf_Values) | the real part of the CLDFB subsamples */ + Word16 **imagValues, /*!< i: Q(sf_Values) | the imaginary part of the CLDFB subsamples */ + Word16 sf_Values, /*!< i: scalefactor of the CLDFB subcamples - apply as a negated Exponent */ + Word16 numberBands, /*!< i: Q0 | number of CLDFB bands */ + Word16 numberCols, /*!< i: Q0 | number of CLDFB subsamples */ + Word32 *energyHF, /*!< o: Q31 | pointer to HF energy */ + Word16 *energyHF_Exp, /*!< o: pointer to exponent of HF energy */ + Word32 *energyValuesSum, /*!< o: Q(2*sf_Values-4) | pointer to sum array of energy values, not initialized*/ + Word16 *energyValuesSum_Exp,/*!< o: pointer to exponents of energyValuesSum, not initialized */ + TEC_ENC_HANDLE hTecEnc + ) +{ + Word16 j; + Word16 k; + Word16 s; + Word16 sm; + Word32 nrg; + Word16 numberColsL; + Word16 numberBandsM; + Word16 numberBandsM20; + Word32 energyValues[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + Word16 energyValuesSumE[CLDFB_NO_CHANNELS_MAX]; + //Word16 freqTable[2] = {20, 40}; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + + FOR (k=0; kloBuffer, + hTecEnc->hiTempEnv, + ScaleX2 + ); + } + + FOR (j=0; j< numberBands; j++) + { + energyValuesSum[j] = L_deposit_l(0); + energyValuesSumE[j] = 31; + move16(); + FOR (k=0; k value 0x40000000, scale 44 */ + *energyLookahead = L_add(L_shr(nrg, sub(s, sm)), + L_shr(0x40000000, s_max(-31, s_min(31, sub(44, sm))))); + move32(); + BASOP_SATURATE_WARNING_ON_EVS + *sf_energyLookahead = sm; + move16(); + + return; + } + + + + *energyHF = 0x40000000; + move32(); + *energyHF_Exp = 17; + move16(); + + +} + + +Word16 +CLDFB_getNumChannels(Word32 sampleRate) +{ + + Word16 nChannels = 0; + + + SWITCH (sampleRate) + { + case 48000: + move16(); + nChannels = 60; + BREAK; + case 32000: + move16(); + nChannels = 40; + BREAK; + case 25600: + move16(); + nChannels = 32; + BREAK; + case 16000: + move16(); + nChannels = 20; + BREAK; + case 12800: + move16(); + nChannels = 16; + BREAK; + case 8000: + move16(); + nChannels = 10; + BREAK; + } + + return (nChannels); +} + +/*-------------------------------------------------------------------* +* cldfb_get_memory_length() +* +* Return length of filter state for recovery +*--------------------------------------------------------------------*/ +static Word16 +cldfb_get_memory_length (HANDLE_CLDFB_FILTER_BANK hs) +{ + IF (EQ_16(hs->type,CLDFB_ANALYSIS)) + { + return (i_mult(hs->no_channels,STATE_BUFFER_SIZE)); + } + ELSE + { + return (i_mult(hs->no_channels,(9*2)) ); + } +} + +/*-------------------------------------------------------------------* +* GetEnergyCldfb() +* +* Remove handle +*--------------------------------------------------------------------*/ +void +deleteCldfb (HANDLE_CLDFB_FILTER_BANK * h_cldfb) /* i: cldfb handle */ +{ + IF ( *h_cldfb != NULL ) + { + IF ( (*h_cldfb)->FilterStates != NULL ) + { + count_free((*h_cldfb)->FilterStates); + } + count_free(*h_cldfb); + } + *h_cldfb = NULL; +} + + +/*-------------------------------------------------------------------* +* cldfb_init_proto_and_twiddles() +* +* Initializes rom pointer +*--------------------------------------------------------------------*/ +static void +cldfb_init_proto_and_twiddles(HANDLE_CLDFB_FILTER_BANK hs) /* i: cldfb handle */ +{ + + /*find appropriate set of rotVecs*/ + SWITCH(hs->no_channels) + { + case 10: + + hs->rRotVctr = rRotVectr_10; + hs->iRotVctr = iRotVectr_10; + hs->synGain = cldfb_synGain[0]; + move16(); + hs->p_filter = cldfb_protoFilter_2_5ms[0]; + hs->scale = cldfb_scale_2_5ms[0]; + move16(); + IF (hs->type == CLDFB_SYNTHESIS ) + { + hs->synScalefactor = add(cldfb_synScale[0],hs->filterScale); + move16(); + } + ELSE + { + hs->anaScalefactor = add(cldfb_anaScale[0],hs->filterScale); + move16(); + } + break; + + case 16: + hs->rRotVctr = rRotVectr_16; + hs->iRotVctr = iRotVectr_16; + hs->synGain = cldfb_synGain[1]; + move16(); + hs->p_filter = cldfb_protoFilter_2_5ms[1]; + hs->scale = cldfb_scale_2_5ms[1]; + move16(); + { + hs->anaScalefactor = add(cldfb_anaScale[1],hs->filterScale); + move16(); + } + break; + + case 20: + hs->rRotVctr = rRotVectr_20; + hs->iRotVctr = iRotVectr_20; + hs->synGain = cldfb_synGain[2]; + move16(); + hs->p_filter = cldfb_protoFilter_2_5ms[2]; + hs->scale = cldfb_scale_2_5ms[2]; + move16(); + IF (hs->type == CLDFB_SYNTHESIS ) + { + hs->synScalefactor = add(cldfb_synScale[2],hs->filterScale); + move16(); + } + ELSE + { + hs->anaScalefactor = add(cldfb_anaScale[2],hs->filterScale); + move16(); + } + break; + + case 32: + hs->rRotVctr = rRotVectr_32; + hs->iRotVctr = iRotVectr_32; + hs->synGain = cldfb_synGain[3]; + move16(); + hs->p_filter = cldfb_protoFilter_2_5ms[3]; + hs->scale = cldfb_scale_2_5ms[3]; + move16(); + { + hs->anaScalefactor = add(cldfb_anaScale[3],hs->filterScale); + move16(); + } + break; + + case 40: + hs->rRotVctr = rRotVectr_40; + hs->iRotVctr = iRotVectr_40; + hs->synGain = cldfb_synGain[4]; + move16(); + hs->p_filter = cldfb_protoFilter_2_5ms[4]; + hs->scale = cldfb_scale_2_5ms[4]; + move16(); + IF (hs->type == CLDFB_SYNTHESIS ) + { + hs->synScalefactor = add(cldfb_synScale[4],hs->filterScale); + move16(); + } + ELSE + { + hs->anaScalefactor = add(cldfb_anaScale[4],hs->filterScale); + move16(); + } + break; + + case 60: + hs->rRotVctr = rRotVectr_60; + hs->iRotVctr = iRotVectr_60; + hs->synGain = cldfb_synGain[5]; + move16(); + hs->p_filter = cldfb_protoFilter_2_5ms[5]; + hs->scale = cldfb_scale_2_5ms[5]; + move16(); + IF (hs->type == CLDFB_SYNTHESIS ) + { + hs->synScalefactor = add(cldfb_synScale[5],hs->filterScale); + move16(); + } + ELSE + { + hs->anaScalefactor = add(cldfb_anaScale[5],hs->filterScale); + move16(); + } + break; + + } +} + + +#define CLDFB_MEM_EXPONENTS (CLDFB_NO_COL_MAX+9) + +/*-------------------------------------------------------------------* +* cldfb_save_memory() +* +* Save the memory of filter; to be restored with cldfb_restore_memory() +*--------------------------------------------------------------------*/ +ivas_error +cldfb_save_memory (HANDLE_CLDFB_FILTER_BANK hs) /* i: cldfb handle */ +{ + + if (hs->memory != NULL || hs->memory_length != 0) + { + /* memory already stored; Free memory first */ + return IVAS_ERR_OK; + } + hs->memory_length = cldfb_get_memory_length(hs); + hs->memory = (Word16 *) calloc( hs->memory_length + CLDFB_MEM_EXPONENTS + 1, sizeof (Word16)); + + /* save the memory */ + Copy (hs->FilterStates, hs->memory, hs->memory_length); + Copy (hs->FilterStates_e, hs->memory+hs->memory_length, CLDFB_MEM_EXPONENTS); + hs->memory[hs->memory_length+CLDFB_MEM_EXPONENTS] = hs->FilterStates_eg; + move16(); + if (hs->memory == NULL) + { + return IVAS_ERROR(IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for CLDFB\n"); + } + return IVAS_ERR_OK; +} + + +/*-------------------------------------------------------------------* +* cldfb_restore_memory() +* +* Restores the memory of filter; memory to be save by cldfb_save_memory() +*--------------------------------------------------------------------*/ +void +cldfb_restore_memory (HANDLE_CLDFB_FILTER_BANK hs) /* i/o: cldfb handle */ + +{ + Word16 size; + + + size = cldfb_get_memory_length(hs); + + /* read the memory */ + Copy (hs->memory, hs->FilterStates, hs->memory_length); + Copy (hs->memory+hs->memory_length, hs->FilterStates_e, CLDFB_MEM_EXPONENTS); + hs->FilterStates_eg = hs->memory[hs->memory_length+CLDFB_MEM_EXPONENTS]; + move16(); + + + /* adjust sample rate if it was changed in the meanwhile */ + IF (NE_16 (hs->memory_length,size)) + { + lerp(hs->FilterStates, hs->FilterStates, size, hs->memory_length); + } + + hs->memory_length = 0; + count_free(hs->memory); + hs->memory = NULL; + + return; +} + +/*-------------------------------------------------------------------* +* cldfb_reset_memory() +* +* Resets the memory of filter. +*--------------------------------------------------------------------*/ +void +cldfb_reset_memory (HANDLE_CLDFB_FILTER_BANK hs) /* i/o: cldfb handle */ +{ + Word16 length; + + length = cldfb_get_memory_length(hs); + /* erase the memory */ + set16_fx (hs->FilterStates, 0, length); + set16_fx (hs->FilterStates_e, 0, sizeof(hs->FilterStates_e)/sizeof(hs->FilterStates_e[0])); + hs->FilterStates_eg = 0; + move16(); + return; +} + diff --git a/lib_com/cng_exc.c b/lib_com/cng_exc.c index 8fdc68921b1a5080204f0a7b48790f986184e945..441e870e4712f7b44258491e0f79fe0a12143171 100644 --- a/lib_com/cng_exc.c +++ b/lib_com/cng_exc.c @@ -441,12 +441,12 @@ void cng_params_postupd( if ( element_mode == IVAS_SCE || element_mode == IVAS_CPE_DFT ) { att = 0.0f; - apply_scale( &att, bwidth, last_active_brate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO ); + apply_scale_flt( &att, bwidth, last_active_brate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO ); att = powf( 10, att / 10.0f ); } else { - CNG_mode = get_cng_mode( last_active_brate ); + CNG_mode = get_cng_mode_ivas( last_active_brate ); att = (float) ( 1 / pow( 2, ENR_ATT[CNG_mode] ) ); } @@ -553,12 +553,12 @@ void cng_params_upd( if ( element_mode == IVAS_SCE || element_mode == IVAS_CPE_DFT ) { att = 0.0f; - apply_scale( &att, bwidth, last_active_brate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO ); + apply_scale_flt( &att, bwidth, last_active_brate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO ); att = powf( 10, att / 10.0f ); } else { - CNG_mode = get_cng_mode( last_active_brate ); + CNG_mode = get_cng_mode_ivas( last_active_brate ); att = (float) ( 1 / pow( 2, ENR_ATT[CNG_mode] ) ); } @@ -582,12 +582,12 @@ void cng_params_upd( /*---------------------------------------------------------------------* - * get_cng_mode() + * get_cng_mode_ivas() * * *---------------------------------------------------------------------*/ -int16_t get_cng_mode( +int16_t get_cng_mode_ivas( const int32_t last_active_brate /* i : last active bitrate */ ) { diff --git a/lib_com/cng_exc_fx.c b/lib_com/cng_exc_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..e8c3e63e7da930657b67fd57ff86559103467176 --- /dev/null +++ b/lib_com/cng_exc_fx.c @@ -0,0 +1,992 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ +#include +#include "options.h" /* Compilation switches */ +#include "cnst.h" /* Common constants */ +#include "prot_fx1.h" /* Function prototypes */ +#include "prot_fx2.h" /* Function prototypes */ +#include "rom_com.h" + +/*---------------------------------------------------------------------* + * Local constants + *---------------------------------------------------------------------*/ +#define A2 6554 +#define OmA2 (32768-A2) +#define GAIN_VAR 11811 /* in Q31 divided by 2 (Q30) */ + +/*-------------------------------------------------------* + * CNG_exc() + * + * Comfort noise generation routine + *-------------------------------------------------------*/ + +void CNG_exc_fx( + const Word32 core_brate, /* i : core bitrate */ + const Word16 L_frame, /* i : length of the frame */ + Word32 *Enew, /* i/o: decoded SID energy Q6 */ + Word16 *seed, /* i/o: random generator seed */ + Word16 exc[], /* o : current non-enhanced excitation Q_new */ + Word16 exc2[], /* o : current enhanced excitation Q_new */ + Word32 *lp_ener, /* i/o: LP filtered E */ + const Word32 last_core_brate,/* i : previous frame core bitrate */ + Word16 *first_CNG, /* i/o: first CNG frame flag for energy init. */ + Word16 *cng_ener_seed, /* i/o: random generator seed for CNG energy */ + Word16 bwe_exc[], /* o : excitation for SWB TBE */ + const Word16 allow_cn_step, /* i : allow CN step */ + Word16 *last_allow_cn_step, /* i/o: last allow step */ + const Word16 OldQ_exc, /* i : Old excitation scaling */ + const Word16 Q_exc, /* i : excitation scaling */ + const Word16 num_ho, /* i : number of selected hangover frames */ + Word32 q_env[], + Word32 *lp_env, + Word32 *old_env, + Word16 *exc_mem, + Word16 *exc_mem1, + Word16 *sid_bw, + Word16 *cng_ener_seed1, + Word16 exc3[], + Word16 Opt_AMR_WB, + const int16_t element_mode /* i : IVAS Element mode */ +) +{ + Word16 i, tmp, tmp2, exp, exp2, Q_ener; + Word32 L_tmp_ener, L_tmp; + Word16 i_subfr; + Word16 pit_max; + Word16 ftmp,j; + Word16 *ptR,*ptI; + Word16 fft_io[L_FRAME16k]; + Word32 itmp[129]; + Word32 env[NUM_ENV_CNG]; + Word32 enr1; + Word32 denv[NUM_ENV_CNG]; + Word16 fra; + Word16 temp_lo_fx, temp_hi_fx; + Word16 exp_pow; + Word32 L_tmp2; + Word16 *pt_fft_io; + + /*------------------------------------------------------------------* + * Initializations + *------------------------------------------------------------------*/ + + pit_max = PIT16k_MAX; + move16(); + if( EQ_16(L_frame,L_FRAME)) + { + pit_max = PIT_MAX; + move16(); + } + + /*---------------------------------------------------------------------* + * Initialization of CNG energy for the first CNG frame + *---------------------------------------------------------------------*/ + + IF(*first_CNG == 0 ) + { + IF(EQ_32(core_brate,FRAME_NO_DATA)) + { + /* needed only in decoder when the very first SID frame was erased and this frame is FRAME_NO_DATA frame */ + /*fenew = dotp( fexc, fexc, pit_max )/pit_max;*/ + L_tmp_ener = Calc_Energy_Autoscaled(exc-pit_max, OldQ_exc, pit_max, &Q_ener); + L_tmp_ener = Mult_32_16(L_tmp_ener, 9079); /* divide by PIT_MAX (in Q15 + Q6 to get output in Q6)*/ + L_tmp_ener = L_shr(L_tmp_ener, Q_ener); /* -> If we want ener in Q6 */ + + if(EQ_16(L_frame, L_FRAME16k)) + { + L_tmp_ener = Mult_32_16(L_tmp_ener, 26214); /* Compensate for 16kHz */ + } + *Enew = L_tmp_ener; + move32(); + } + + if (EQ_16(element_mode, EVS_MONO)) + { + *lp_ener = *Enew; + move32(); + } + } + + /*---------------------------------------------------------------------* + * Update CNG energy + *---------------------------------------------------------------------*/ + test(); + test(); + IF( NE_32(last_core_brate,SID_1k75)&&NE_32(last_core_brate,FRAME_NO_DATA)&&NE_32(last_core_brate,SID_2k40)) + { + /* Partially reset CNG energy after active speech period */ + test(); + IF ( allow_cn_step == 0 && *last_allow_cn_step == 0 ) + { + test(); + IF( LT_16(num_ho,3)||LT_32(Mult_32_16(*Enew,21845/*1/1.5f, Q15*/),*lp_ener)) + { + /**lp_ener = 0.8f * *lp_ener + 0.2f * *Enew;*/ + L_tmp_ener = Mult_32_16(*lp_ener, 26214); + L_tmp_ener = Madd_32_16(L_tmp_ener, *Enew, 6554); + + } + ELSE + { + /**lp_ener = 0.95f * *lp_ener + 0.05f * *Enew;*/ + L_tmp_ener = Mult_32_16(*lp_ener, 31130); + L_tmp_ener = Madd_32_16(L_tmp_ener, *Enew, 1638); + } + } + ELSE + { + L_tmp_ener = *Enew; + move32(); + *last_allow_cn_step = 0; + move16(); + } + } + ELSE + { + /* normal CNG update */ + IF ( *last_allow_cn_step == 0 ) + { + /**lp_ener = (float)(A2 * *Enew + (1-A2) * *lp_ener);*/ + L_tmp_ener = Mult_32_16(*Enew, A2); + L_tmp_ener = Madd_32_16(L_tmp_ener, *lp_ener, OmA2); + } + ELSE + { + test(); + if ( EQ_32(core_brate,SID_1k75)||EQ_32(core_brate,SID_2k40)) + { + *last_allow_cn_step = 0; + move16(); + } + + L_tmp_ener = *Enew; + move32(); + + } + } + *lp_ener = L_max(L_tmp_ener,1); + move32(); /*To avoid / per 0*/ + + if ( EQ_16(allow_cn_step,1)) + { + *last_allow_cn_step = 1; + move16(); + } + /* If not mono, skip CNG here */ + if (GT_16(element_mode, IVAS_SCE)) + { + return; + } + /*---------------------------------------------------------------------* + * Generate white noise vector + *---------------------------------------------------------------------*/ + + /*for ( i=0; i Q_exc +16 */ +#ifdef BASOP_NOGLOB + exc2[i_subfr+i] = round_fx_sat(L_shl_sat(L_tmp, exp)); +#else + exc2[i_subfr+i] = round_fx(L_shl(L_tmp, exp)); +#endif + } + } + IF ( NE_16(Opt_AMR_WB,1)) + { + Copy( exc2, exc3, L_FRAME16k); + + /* enr1 = (float)log10( *Enew*L_frame + 0.1f ) / (float)log10( 2.0f ); */ + exp = norm_l(*Enew); + L_tmp = L_shl(*Enew,exp); /* Q(exp+6) */ + L_tmp = Mult_32_16(L_tmp,shl(L_frame,5)); /* Q(exp+6+5-15=exp-4) */ + L_tmp = L_shr(L_tmp,sub(exp,10)); /* Q6 */ + + exp = norm_l(L_tmp); + fra = Log2_norm_lc(L_shl(L_tmp,exp)); + exp = sub(sub(30,exp),6); + L_tmp = L_Comp(exp,fra); + /* enr1 = round_fx(L_shl(L_tmp,8)); */ /*Q8 */ + enr1 = L_shr(L_tmp,10);/* Q6 */ + + + IF ( EQ_32(core_brate,SID_2k40)) + { + IF ( *sid_bw == 0 ) + { + FOR ( i=0; i MAX_ACELP_BRATE_ISM) + { + tcxonly = 1; + } + } + else + { + if (total_brate > MAX_ACELP_BRATE) + { + tcxonly = 1; + } + } + break; + + case IVAS_CPE_DFT: + case IVAS_CPE_TD: + if (total_brate > MAX_ACELP_BRATE) + { + tcxonly = 1; + } + break; + case IVAS_CPE_MDCT: + if (total_brate >= (MCT_flag ? IVAS_32k : IVAS_48k)) + { + tcxonly = 1; + } + break; +#endif + return tcxonly; + } /*-------------------------------------------------------------------* * getCtxHm() @@ -344,12 +404,12 @@ int16_t sr2fscale( } /*-------------------------------------------------------------------* - * getCoreSamplerateMode2() + * getCoreSamplerateMode2_flt() * * *-------------------------------------------------------------------*/ -int32_t getCoreSamplerateMode2( +int32_t getCoreSamplerateMode2_flt( const int16_t element_mode, /* i : IVAS element mode */ const int32_t total_brate, /* i : total bitrate */ const int16_t bwidth, /* i : audio bandwidth */ @@ -400,13 +460,104 @@ int32_t getCoreSamplerateMode2( return sr_core; } +Word32 getCoreSamplerateMode2( + const Word16 element_mode, /* i : IVAS element mode */ + const Word32 total_brate, /* i : total bitrate */ + const Word16 bwidth, /* i : audio bandwidth */ + const Word16 flag_ACELP16k, /* i : ACELP@16kHz flag */ + const Word16 rf_mode, /* i : flag to signal the RF mode */ + const IVAS_FORMAT is_ism_format /* i : flag indicating ISM format */ +) +{ + + Word32 sr_core; + Word16 bwd_swb_or_fb_flag; + sr_core = -1; /* to suppress MSVC warning */ move32(); + + bwd_swb_or_fb_flag = s_or((Word16)EQ_16(bwidth, SWB), (Word16)EQ_16(bwidth, FB)); + test(); test(); test(); test(); test(); test(); test(); test(); test(); test(); + test(); test(); test(); test(); test(); test(); test(); + test(); test(); test(); test(); test(); + IF(EQ_32(bwidth, NB)) + { + sr_core = INT_FS_12k8; + move32(); + } + ELSE IF(EQ_16(element_mode, EVS_MONO) && (L_and(EQ_32(bwidth, WB), LT_32(total_brate, ACELP_13k20)) || + L_and(EQ_32(bwidth, SWB), LE_32(total_brate, ACELP_13k20)) || EQ_16(rf_mode, 1))) + + { + sr_core = INT_FS_12k8; + move32(); + } + ELSE IF(GT_16(element_mode, EVS_MONO) && flag_ACELP16k == 0) + { + sr_core = INT_FS_12k8; + move32(); + } + ELSE IF(EQ_32(bwidth, WB) || ((LE_32(total_brate, ACELP_32k)) && ((EQ_32(bwidth, SWB)) || (EQ_32(bwidth, FB))))) + { + sr_core = INT_FS_16k; + move32(); + } + ELSE IF(bwd_swb_or_fb_flag && LE_32(total_brate, MAX_ACELP_BRATE) && EQ_16(element_mode, IVAS_SCE) && !is_ism_format) + { + sr_core = INT_FS_16k; + move32(); + } + ELSE IF(bwd_swb_or_fb_flag && LE_32(total_brate, MAX_ACELP_BRATE_ISM) && EQ_16(element_mode, IVAS_SCE) && is_ism_format) + { + sr_core = INT_FS_16k; + } + else if (bwd_swb_or_fb_flag && LE_32(total_brate, MAX_ACELP_BRATE) && EQ_16(element_mode, IVAS_SCE) && is_ism_format) + { + sr_core = 25600; + } + ELSE IF((EQ_16(element_mode, EVS_MONO) && (bwd_swb_or_fb_flag && LE_32(total_brate, HQ_64k))) + || (GT_16(element_mode, IVAS_SCE) && ((EQ_16(bwidth, SWB) && LE_32(total_brate, IVAS_96k)) || (EQ_16(bwidth, FB) && LE_32(total_brate, IVAS_96k))))) + { + sr_core = 25600; + move32(); + } + ELSE IF(bwd_swb_or_fb_flag) + { + sr_core = 32000; + move32(); + } + ELSE + { + assert(0); + } + + return sr_core; +} + +Word16 getTcxBandwidth( + const Word16 bwidth /* i : audio bandwidth */ +) +{ + + Word16 tcxBandwidth; + + tcxBandwidth = 16384/*0.5f Q15*/; + move16(); + if (EQ_16(bwidth, NB)) + { + tcxBandwidth = 10240/*0.3125f Q15*/; + move16(); + + } + + return tcxBandwidth; +} + /*-------------------------------------------------------------------* - * getTcxBandwidth() + * getTcxBandwidth_flt() * * *-------------------------------------------------------------------*/ -float getTcxBandwidth( +float getTcxBandwidth_flt( const int16_t bwidth /* i : audio bandwidth */ ) { @@ -716,25 +867,25 @@ void init_tcx_window_cfg( hTcxCfg->tcx_mdct_window_length = mdctWindowLength; hTcxCfg->tcx_mdct_window_lengthFB = mdctWindowLengthFB; - mdct_window_sine( hTcxCfg->tcx_mdct_window_flt, sr_core, hTcxCfg->tcx_mdct_window_length, FULL_OVERLAP, element_mode ); + mdct_window_sine_flt( hTcxCfg->tcx_mdct_window_flt, sr_core, hTcxCfg->tcx_mdct_window_length, FULL_OVERLAP, element_mode ); if ( hTcxCfg->tcx_mdct_window_length == hTcxCfg->tcx_mdct_window_lengthFB ) { mvr2r( hTcxCfg->tcx_mdct_window_flt, hTcxCfg->tcx_mdct_windowFB_flt, hTcxCfg->tcx_mdct_window_length ); } else { - mdct_window_sine( hTcxCfg->tcx_mdct_windowFB_flt, input_Fs, hTcxCfg->tcx_mdct_window_lengthFB, FULL_OVERLAP, element_mode ); + mdct_window_sine_flt( hTcxCfg->tcx_mdct_windowFB_flt, input_Fs, hTcxCfg->tcx_mdct_window_lengthFB, FULL_OVERLAP, element_mode ); } /*ALDO windows for MODE2*/ - mdct_window_aldo( hTcxCfg->tcx_aldo_window_1_flt, hTcxCfg->tcx_aldo_window_2_flt, L_frame ); - mdct_window_aldo( hTcxCfg->tcx_aldo_window_1_FB_flt, hTcxCfg->tcx_aldo_window_2_FB_flt, NS2SA( input_Fs, FRAME_SIZE_NS ) ); + mdct_window_aldo_flt( hTcxCfg->tcx_aldo_window_1_flt, hTcxCfg->tcx_aldo_window_2_flt, L_frame ); + mdct_window_aldo_flt( hTcxCfg->tcx_aldo_window_1_FB_flt, hTcxCfg->tcx_aldo_window_2_FB_flt, NS2SA( input_Fs, FRAME_SIZE_NS ) ); hTcxCfg->tcx_aldo_window_1_trunc_flt = hTcxCfg->tcx_aldo_window_1_flt + NS2SA( sr_core, N_ZERO_MDCT_NS ); hTcxCfg->tcx_aldo_window_1_FB_trunc_flt = hTcxCfg->tcx_aldo_window_1_FB_flt + NS2SA( input_Fs, N_ZERO_MDCT_NS ); /*1.25ms transition window for ACELP->TCX*/ hTcxCfg->tcx_mdct_window_trans_length = NS2SA( sr_core, ACELP_TCX_TRANS_NS ); - mdct_window_sine( hTcxCfg->tcx_mdct_window_trans_flt, sr_core, hTcxCfg->tcx_mdct_window_trans_length, TRANSITION_OVERLAP, element_mode ); + mdct_window_sine_flt( hTcxCfg->tcx_mdct_window_trans_flt, sr_core, hTcxCfg->tcx_mdct_window_trans_length, TRANSITION_OVERLAP, element_mode ); hTcxCfg->tcx_mdct_window_trans_lengthFB = NS2SA( input_Fs, ACELP_TCX_TRANS_NS ); if ( hTcxCfg->tcx_mdct_window_trans_length == hTcxCfg->tcx_mdct_window_trans_lengthFB ) { @@ -742,7 +893,7 @@ void init_tcx_window_cfg( } else { - mdct_window_sine( hTcxCfg->tcx_mdct_window_transFB_flt, input_Fs, hTcxCfg->tcx_mdct_window_trans_lengthFB, TRANSITION_OVERLAP, element_mode ); + mdct_window_sine_flt( hTcxCfg->tcx_mdct_window_transFB_flt, input_Fs, hTcxCfg->tcx_mdct_window_trans_lengthFB, TRANSITION_OVERLAP, element_mode ); } /*Mid-OLA*/ @@ -751,14 +902,14 @@ void init_tcx_window_cfg( hTcxCfg->tcx_mdct_window_half_lengthFB = 2 * ( ( encoderLookahead_FB - (int16_t) ( 0.005f * input_Fs + 0.5f ) ) >> 1 ); assert( ( hTcxCfg->tcx_mdct_window_half_length > 16 ) && "Half window can not be large enough!" ); - mdct_window_sine( hTcxCfg->tcx_mdct_window_half_flt, sr_core, hTcxCfg->tcx_mdct_window_half_length, HALF_OVERLAP, element_mode ); + mdct_window_sine_flt( hTcxCfg->tcx_mdct_window_half_flt, sr_core, hTcxCfg->tcx_mdct_window_half_length, HALF_OVERLAP, element_mode ); if ( hTcxCfg->tcx_mdct_window_half_length == hTcxCfg->tcx_mdct_window_half_lengthFB ) { mvr2r( hTcxCfg->tcx_mdct_window_half_flt, hTcxCfg->tcx_mdct_window_halfFB_flt, hTcxCfg->tcx_mdct_window_half_length ); } else { - mdct_window_sine( hTcxCfg->tcx_mdct_window_halfFB_flt, input_Fs, hTcxCfg->tcx_mdct_window_half_lengthFB, HALF_OVERLAP, element_mode ); + mdct_window_sine_flt( hTcxCfg->tcx_mdct_window_halfFB_flt, input_Fs, hTcxCfg->tcx_mdct_window_half_lengthFB, HALF_OVERLAP, element_mode ); } /* minimum overlap 1.25 ms */ @@ -771,7 +922,7 @@ void init_tcx_window_cfg( } else { - mdct_window_sine( hTcxCfg->tcx_mdct_window_minimum_flt, sr_core, hTcxCfg->tcx_mdct_window_min_length, MIN_OVERLAP, element_mode ); + mdct_window_sine_flt( hTcxCfg->tcx_mdct_window_minimum_flt, sr_core, hTcxCfg->tcx_mdct_window_min_length, MIN_OVERLAP, element_mode ); } if ( hTcxCfg->tcx_mdct_window_min_lengthFB == hTcxCfg->tcx_mdct_window_trans_lengthFB ) @@ -784,7 +935,7 @@ void init_tcx_window_cfg( } else { - mdct_window_sine( hTcxCfg->tcx_mdct_window_minimumFB_flt, input_Fs, hTcxCfg->tcx_mdct_window_min_lengthFB, MIN_OVERLAP, element_mode ); + mdct_window_sine_flt( hTcxCfg->tcx_mdct_window_minimumFB_flt, input_Fs, hTcxCfg->tcx_mdct_window_min_lengthFB, MIN_OVERLAP, element_mode ); } /* TCX Offset */ @@ -846,7 +997,7 @@ void init_tcx_cfg( hTcxCfg->tcxRateLoopOpt = ( element_mode == IVAS_CPE_MDCT ) ? 3 : hTcxCfg->tcxRateLoopOpt; /* TCX bandwidth */ - hTcxCfg->bandwidth_flt = getTcxBandwidth( bwidth ); + hTcxCfg->bandwidth_flt = getTcxBandwidth_flt( bwidth ); /* set number of coded lines */ hTcxCfg->tcx_coded_lines = getNumTcxCodedLines( bwidth ); @@ -857,9 +1008,9 @@ void init_tcx_cfg( if ( hTcxCfg->fIsTNSAllowed ) { - InitTnsConfigs( bwidth, hTcxCfg->tcx_coded_lines, hTcxCfg->tnsConfig, infoIGFStopFreq, total_brate, element_mode, MCT_flag ); + InitTnsConfigs_flt( bwidth, hTcxCfg->tcx_coded_lines, hTcxCfg->tnsConfig, infoIGFStopFreq, total_brate, element_mode, MCT_flag ); - SetAllowTnsOnWhite( hTcxCfg->tnsConfig, element_mode == IVAS_CPE_MDCT ); + SetAllowTnsOnWhite_flt( hTcxCfg->tnsConfig, element_mode == IVAS_CPE_MDCT ); } if ( ini_frame == 0 ) diff --git a/lib_com/dlpc_bfi.c b/lib_com/dlpc_bfi.c index ea701a3fed4315e755b6055a9769d3b1e5458a08..ecb7ac645adca2aee1b63b1f2ee15dad617547f8 100644 --- a/lib_com/dlpc_bfi.c +++ b/lib_com/dlpc_bfi.c @@ -42,12 +42,12 @@ #include "wmc_auto.h" /*---------------------------------------------------------------------* - * routine: dlpc_bfi() + * routine: dlpc_bfi_flt() * * *---------------------------------------------------------------------*/ -void dlpc_bfi( +void dlpc_bfi_flt( const int16_t L_frame, float *lsf_q, /* o : quantized lsfs */ const float *lsfold, /* i : past quantized lsf */ @@ -65,12 +65,12 @@ void dlpc_bfi( const float lsfBase[] /* i : base for differential lsf coding */ ) { - lsf_dec_bfi( MODE2, &lsf_q[0], lsfold, lsf_adaptive_mean, lsfBase, mem_MA, mem_AR, *stab_fac, 0, L_frame, last_good, nbLostCmpt, plcBackgroundNoiseUpdated, lsf_q_cng, lsf_cng, old_lsf_q_cng, 0, 0, 0 ); + lsf_dec_bfi_flt( MODE2, &lsf_q[0], lsfold, lsf_adaptive_mean, lsfBase, mem_MA, mem_AR, *stab_fac, 0, L_frame, last_good, nbLostCmpt, plcBackgroundNoiseUpdated, lsf_q_cng, lsf_cng, old_lsf_q_cng, 0, 0, 0 ); if ( numlpc == 2 ) { /* Decode the second LPC */ - lsf_dec_bfi( MODE2, &lsf_q[M], &lsf_q[0], lsf_adaptive_mean, lsfBase, mem_MA, mem_AR, *stab_fac, 0, L_frame, last_good, nbLostCmpt + 1, plcBackgroundNoiseUpdated, lsf_q_cng, lsf_cng, old_lsf_q_cng, 0, 0, 0 ); + lsf_dec_bfi_flt( MODE2, &lsf_q[M], &lsf_q[0], lsf_adaptive_mean, lsfBase, mem_MA, mem_AR, *stab_fac, 0, L_frame, last_good, nbLostCmpt + 1, plcBackgroundNoiseUpdated, lsf_q_cng, lsf_cng, old_lsf_q_cng, 0, 0, 0 ); } return; diff --git a/lib_com/dlpc_bfi_fx.c b/lib_com/dlpc_bfi_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..21d7fd37c7c2621f438398c80dc14e213438b07b --- /dev/null +++ b/lib_com/dlpc_bfi_fx.c @@ -0,0 +1,43 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + + +/* Header files */ +#include +#include "options.h" +#include "prot_fx1.h" +#include "prot_fx2.h" + +void dlpc_bfi( + const Word16 L_frame, + Word16 *lsf_q, /* o : quantized LSFs */ + const Word16 *lsfold, /* i : past quantized LSF */ + const Word16 last_good, /* i : last good received frame */ + const Word16 nbLostCmpt, /* i : counter of consecutive bad frames */ + Word16 mem_MA[], /* i/o: quantizer memory for MA model */ + Word16 mem_AR[], /* i/o: quantizer memory for AR model */ + Word16 *stab_fac, /* i : LSF stability factor */ + Word16 *lsf_adaptive_mean,/* i : LSF adaptive mean, updated when BFI==0 */ + Word16 numlpc, /* i : Number of division per superframe */ + Word16 lsf_cng[], + Word8 plcBackgroundNoiseUpdated, + Word16 *lsf_q_cng, /* o : quantized LSFs */ + Word16 *old_lsf_q_cng, /* o : old quantized LSFs for background noise */ + const Word16* lsfBase, /* i : base for differential LSF coding */ + Word8 tcxonly +) +{ + + lsf_dec_bfi(MODE2, &lsf_q[0], lsfold, lsf_adaptive_mean, lsfBase, mem_MA, mem_AR, *stab_fac, + 0, L_frame, last_good, nbLostCmpt, plcBackgroundNoiseUpdated, lsf_q_cng, lsf_cng, old_lsf_q_cng, 0, 0, tcxonly, 0); + + IF ( EQ_16(numlpc,2)) + { + /* Decode the second LPC */ + lsf_dec_bfi(MODE2, &lsf_q[M], &lsf_q[0], lsf_adaptive_mean, lsfBase, mem_MA, mem_AR, *stab_fac, + 0, L_frame, last_good, nbLostCmpt+1, plcBackgroundNoiseUpdated, lsf_q_cng, lsf_cng, old_lsf_q_cng, 0, 0, tcxonly, 0); + } + /**/ /*No local variabvles defined*/ +} + diff --git a/lib_com/edct_fx.c b/lib_com/edct_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..06e1884563f4ef7798551550473ea17bb0110473 --- /dev/null +++ b/lib_com/edct_fx.c @@ -0,0 +1,457 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include +#include +#include "options.h" /* Compilation switches */ +#include "cnst.h" /* Common constants */ +#include "rom_com.h" /* Static table prototypes */ +#include "prot_fx1.h" /* Function prototypes */ +#include "prot_fx2.h" /* Function prototypes */ +#include "stl.h" + + +#include "math_32.h" + +static Word16 const * get_edct_table(Word16 length, Word16 *q) +{ + Word16 const * edct_table = NULL; + SWITCH (length) + { + case 1200: + edct_table = edct_table_600_fx; + move16(); + *q = add(*q, 2); + BREAK; + case 960 : + edct_table = edct_table_480_fx; + move16(); + BREAK; + case 640 : + edct_table = edct_table_320_fx; + move16(); + BREAK; + case 320 : + edct_table = edct_table_160_fx; + move16(); + BREAK; + case 256 : + edct_table = edct_table_128_fx; + move16(); + BREAK; + case 240 : + edct_table = edct_table_120_fx; + move16(); + BREAK; + case 200 : + edct_table = edct_table_100_fx; + move16(); + BREAK; + case 160 : + edct_table = edct_table_80_fx ; + move16(); + BREAK; + case 40 : + edct_table = edct_table_20_fx ; + move16(); + BREAK; + case 800 : + edct_table = edct_table_400_fx; + move16(); + *q = add(*q, 2); + BREAK; + case 512 : + edct_table = edct_table_256_fx; + move16(); + BREAK; + case 480 : + edct_table = edct_table_240_fx; + move16(); + BREAK; + case 400 : + edct_table = edct_table_200_fx; + move16(); + BREAK; + case 128 : + edct_table = edct_table_64_fx ; + move16(); + BREAK; + case 80 : + edct_table = edct_table_40_fx ; + move16(); + BREAK; + default: + BREAK; + } + return edct_table; +} + +/*-------------------------------------------------------------------------* + * FUNCTION : edct_fx() + * + * PURPOSE : DCT transform + * + * INPUT ARGUMENTS : + * _ (Word16) length : length + * _ (Word16*) x : input signal Qx + * _ (Word16*) edct_table_128_fx : edct table Q16 + * + * OUTPUT ARGUMENTS : + * _ (Word16[]) y : output transform Qx + *-------------------------------------------------------------------------*/ +void edct_fx( + const Word32 *x, /* i : input signal Qq */ + Word32 *y, /* o : output transform Qq */ + Word16 length, /* i : length */ + Word16 *q /* i : Q value of input signal */ +) +{ + Word16 i; + Word32 re; + Word32 im; + const Word16 *edct_table = 0; /*Q16 */ + Word32 complex_buf[2*(L_FRAME48k/2+240)]; + Word32 L_tmp; + Word16 tmp; + Word16 len1; + + edct_table = get_edct_table(length, q); + len1 = shr(length, 1); + /* Twiddling and Pre-rotate */ + FOR (i = 0; i < len1; i++) + { + L_tmp = Mult_32_16(x[2*i], edct_table[i]); /*Q(q+1) */ + complex_buf[2*i] = Madd_32_16(L_tmp, x[length-1-2*i], edct_table[len1-1-i]); /*Q(q+1) */ move32(); + + L_tmp = Mult_32_16(x[length-1-2*i], edct_table[i]); /*Q(q+1) */ + + complex_buf[2*i+1] = Msub_32_16(L_tmp, x[2*i], edct_table[len1-1-i]); /*Q(q+1) */ move32(); + } + + *q = sub(15, *q); + BASOP_cfft((cmplx *)complex_buf, len1, q, y); + + tmp = div_s(1, length); /*Q15 */ + tmp = round_fx(L_shl(L_mult(tmp, 19302), 2)); /*Q15 */ + FOR (i = 0; i < len1; i++) + { + re = Msub_32_16(complex_buf[2*i], complex_buf[2*i+1], tmp); + im = Madd_32_16(complex_buf[2*i+1], complex_buf[2*i], tmp); + y[2 * i] = L_add(Mult_32_16(re, edct_table[i]), Mult_32_16(im, edct_table[len1 - 1 - i])); + move32(); + y[length - 1 - 2 * i] = L_sub(Mult_32_16(re, edct_table[len1 - 1 - i]), Mult_32_16(im, edct_table[i])); + move32(); + } /*Q(q-2) */ + + *q = sub(15+2, *q); + return; +} + +/*-------------------------------------------------------------------------* + * FUNCTION : edst_fx() + * + * PURPOSE : DST_IV transform + * + * INPUT ARGUMENTS : + * _ (Word16) length : length + * _ (Word16*) x : input signal Qx + * _ (Word16*) edct_table_128_fx : edct table Q16 + * + * OUTPUT ARGUMENTS : + * _ (Word16[]) y : output transform Qx + *-------------------------------------------------------------------------*/ +void edst_fx( + const Word32 *x, /* i : input signal Qq */ + Word32 *y, /* o : output transform Qq */ + Word16 length, /* i : length */ + Word16 *q /* i : Q value of input signal */ +) +{ + Word16 i; + Word32 re; + Word32 im; + const Word16 *edct_table = 0; /*Q16 */ + Word32 complex_buf[2*(L_FRAME48k/2+240)]; + Word32 L_tmp; + Word16 tmp; + Word16 len1; + + edct_table = get_edct_table(length, q); + len1 = shr(length, 1); + /* Twiddling and Pre-rotate */ + FOR (i = 0; i < len1; i++) + { + L_tmp = Mult_32_16(x[length-1-2*i], edct_table[i]); + complex_buf[2*i] = Madd_32_16(L_tmp, x[2*i], edct_table[len1-1-i]); + move32(); + + L_tmp = Mult_32_16(x[2*i], edct_table[i]); + complex_buf[2*i+1] = Msub_32_16(L_tmp, x[length-1-2*i], edct_table[len1-1-i]); + move32(); + } + + *q = sub(15, *q); + BASOP_cfft((cmplx *)complex_buf, len1, q, y); + + tmp = div_s(1, length); /*Q15 */ + tmp = round_fx(L_shl(L_mult(tmp, 19302), 2)); /*Q15 */ + FOR (i = 0; i < len1; i++) + { + re = Msub_32_16(complex_buf[2*i], complex_buf[2*i+1], tmp); + im = Madd_32_16(complex_buf[2*i+1], complex_buf[2*i], tmp); + y[2 * i] = L_add(Mult_32_16(re, edct_table[i]), Mult_32_16(im, edct_table[len1 - 1 - i])); + move32(); + y[length - 1 - 2 * i] = L_sub(Mult_32_16(im, edct_table[i]), Mult_32_16(re, edct_table[len1 - 1 - i])); + move32(); + } /*Q(q) */ + + *q = sub(15+2, *q); + + return; +} +/*========================================================================*/ +/* FUNCTION : edct_fx() */ +/*------------------------------------------------------------------------*/ +/* PURPOSE : DCT transform */ +/*------------------------------------------------------------------------*/ +/* INPUT ARGUMENTS : */ +/* _ (Word16) length : length */ +/* _ (Word16*) x : input signal Qx */ +/* _ (Word16*) edct_table_128_fx : edct table Q15 */ +/*------------------------------------------------------------------------*/ +/* INPUT/OUTPUT ARGUMENTS : */ +/*------------------------------------------------------------------------*/ +/* OUTPUT ARGUMENTS : */ +/* _ (Word16[]) y : output transform Qx */ +/*------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------*/ +/* RETURN ARGUMENTS : */ +/* _ None */ +/*========================================================================*/ +void edct_16fx( + const Word16 *x, /* i : input signal Qx */ + Word16 *y, /* o : output transform Qx */ + Word16 length, /* i : length */ + Word16 bh, /* bit-headroom */ + const Word16 element_mode + +) +{ + Word16 i; + Word16 re[L_FRAME48k/2]; + Word16 im[L_FRAME48k/2]; + const Word16 *edct_table = 0; + Word16 re2[L_FRAME48k/2]; + Word16 im2[L_FRAME48k/2]; + + Word32 L_tmp, Lacc, Lmax; + Word16 tmp, fact; + Word16 Q_edct; + Word16 Len2, i2; + const Word16 *px, *pt; + Word16 *py; +#ifdef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING + (void) element_mode; +#endif +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + /*COMPLETE: some eDCT sub function are missing */ + + IF (EQ_16(length,L_FRAME32k)) + { + edct_table = &edct_table_320_16fx[0]; + move16(); + } + ELSE IF (EQ_16(length,L_FRAME)) + { + edct_table = &edct_table_128_16fx[0]; + move16(); + } + ELSE IF (EQ_16(length,L_FRAME16k)) + { + edct_table = &edct_table_160_16fx[0]; + move16(); + } + ELSE + { + } + + /* Twiddling and Pre-rotate */ + Lmax = L_deposit_l(0); + Len2 = shr(length,1); + px = x + length - 1; + pt = edct_table + Len2 - 1; + FOR (i = 0; i < Len2; i++) + { + i2 = shl(i,1); + L_tmp = L_mult(x[i2],edct_table[i]);/*Q(Qx+16) */ + + Lacc = L_mac(L_tmp,*px,*pt);/*Q(Qx+16) */ + + Lmax = L_max(Lmax, Lacc); + + L_tmp = L_mult(*px,edct_table[i]);/*Q(Qx+16) */ + Lacc = L_msu(L_tmp,x[i2],*pt);/*Q(Qx+16) */ + Lmax = L_max(Lmax, Lacc); + + px -= 2; + pt--; + } + + tmp = 31; + if( Lmax != 0 ) + { + tmp = norm_l(Lmax); + } + Q_edct = sub(tmp,bh); /*creating a bit-headroom */ + + px = x + length - 1; + pt = edct_table + Len2 - 1; + FOR (i = 0; i < Len2; i++) + { + i2 = shl(i,1); + + L_tmp = L_mult(x[i2],edct_table[i]);/*Q(Qx+16) */ +#ifdef BASOP_NOGLOB + Lacc = L_mac_o(L_tmp,*px,*pt, &Overflow);/*Q(Qx+16) */ + re2[i] = round_fx_o(L_shl_o(Lacc, Q_edct, &Overflow), &Overflow); /* Q(Qx+Q_edct) */ +#else + Lacc = L_mac(L_tmp,*px,*pt);/*Q(Qx+16) */ + re2[i] = round_fx(L_shl(Lacc, Q_edct)); /* Q(Qx+Q_edct) */ +#endif + + L_tmp = L_mult(*px,edct_table[i]);/*Q(Qx+16) */ +#ifdef BASOP_NOGLOB + Lacc = L_msu_o(L_tmp,x[i2],*pt, &Overflow);/*Q(Qx+16) */ + im2[i] = round_fx_o(L_shl_o(Lacc, Q_edct, &Overflow), &Overflow); /* Q(Qx+Q_edct) */ +#else + Lacc = L_msu(L_tmp,x[i2],*pt);/*Q(Qx+16) */ + im2[i] = round_fx(L_shl(Lacc, Q_edct)); /* Q(Qx+Q_edct) */ +#endif + px -= 2; + pt--; + } + IF (EQ_16(length,L_FRAME32k)) + { + DoRTFT320_16fx(re2, im2); + } + ELSE IF (EQ_16(length,L_FRAME )) + { + DoRTFT128_16fx(re2, im2); + } + ELSE IF (EQ_16(length,L_FRAME16k)) + { + DoRTFT160_16fx(re2, im2); + } + ELSE + { + } + tmp = div_s(1,length); /*Q15 */ + L_tmp = L_mult(tmp,19302); /*Q29, (3*PI/4) in Q13 */ + fact = round_fx(L_shl(L_tmp,2)); /*Q15 */ + FOR (i = 0; i < length/2; i++) + { + tmp = mult_r(im2[i],fact); /*Q(Qx+Q_edct) */ +#ifdef BASOP_NOGLOB + re[i] = sub_o(re2[i], tmp, &Overflow); /*Q(Qx+Q_edct) */ move16(); +#else + re[i] = sub(re2[i],tmp); /*Q(Qx+Q_edct) */ move16(); +#endif + + tmp = mult_r(re2[i],fact); /*Q(Qx+Q_edct) */ +#ifdef BASOP_NOGLOB + im[i] = add_o(im2[i],tmp, &Overflow); /*Q(Qx+Q_edct) */ move16(); +#else + im[i] = add(im2[i],tmp); /*Q(Qx+Q_edct) */ move16(); +#endif + } + + /* Post-rotate and obtain the output data */ + py = y + length - 1; + pt = edct_table + Len2 - 1; + FOR (i = 0; i < Len2; i++) + { + i2 = shl(i,1); + + L_tmp = L_mult(re[i],edct_table[i]);/*Q(Qx+Q_edct+16) */ +#ifdef BASOP_NOGLOB + Lacc = L_mac_o(L_tmp, im[i], *pt, &Overflow);/*Q(Qx+Q_edct+16) */ + y[i2] = round_fx_o(L_shr_o(Lacc,Q_edct, &Overflow), &Overflow); /* Q(Qx) */ +#else /* BASOP_NOGLOB */ + Lacc = L_mac(L_tmp, im[i], *pt);/*Q(Qx+Q_edct+16) */ + y[i2] = round_fx(L_shr(Lacc,Q_edct)); /* Q(Qx) */ +#endif /* BASOP_NOGLOB */ + + L_tmp = L_mult(re[i],edct_table[length/2-1-i]);/*Q(Qx+Q_edct+16) */ + Lacc = L_msu(L_tmp,im[i],edct_table[i]);/*Q(Qx+Q_edct+16) */ +#ifdef BASOP_NOGLOB + *py = round_fx_o(L_shr_o(Lacc,Q_edct, &Overflow), &Overflow); /* Q(Qx) */ +#else /* BASOP_NOGLOB */ + *py = round_fx(L_shr(Lacc,Q_edct)); /* Q(Qx) */ +#endif + + py -= 2; + pt--; + } + return; +} + + +/*-----------------------------------------------------------------* + * iedct_short_fx() + * + * Inverse EDCT for short frames + *-----------------------------------------------------------------*/ + +void iedct_short_fx( + const Word32 *in, /* i : input vector */ + Word16 *Q, /* i/o: Q value of input */ + Word32 *out, /* o : output vector */ + const Word16 segment_length /* i : length */ +) +{ + Word32 alias[MAX_SEGMENT_LENGTH]; + Word16 seg_len_div2, seg_len_div4, seg_len_3mul_div4; + Word16 i; + Word16 qtmp, tmp; + + qtmp = *Q; + move16(); + tmp = 0; + move16(); + seg_len_div2 = shr(segment_length, 1); + seg_len_div4 = shr(segment_length, 2); + seg_len_3mul_div4 = add(seg_len_div2, seg_len_div4); + + edct_fx(in, alias, seg_len_div2, Q); + FOR (i = 0; i < seg_len_div2; i++) + { + IF (alias[i] != 0) + { + tmp = 1; + move16(); + BREAK; + } + } + if (tmp == 0) + { + *Q = qtmp; + move16(); + } + FOR (i = 0; i < seg_len_div4; i++) + { + out[i] = alias[seg_len_div4 + i]; + move32(); + out[seg_len_div4 + i] = L_negate(alias[seg_len_div2 - 1 - i]); + move32(); + out[seg_len_div2 + i] = L_negate(alias[seg_len_div4 - 1 - i]); + move32(); + out[seg_len_3mul_div4 + i] = L_negate(alias[i]); + move32(); + } + + return; +} diff --git a/lib_com/enh1632.c b/lib_com/enh1632.c index 4e53ba695ef8685f163abaa25869a35cfb4edc5c..da8dc2d10c8eec01fc7dd8c7c33d0d7ebf1a7cc4 100644 --- a/lib_com/enh1632.c +++ b/lib_com/enh1632.c @@ -1,35 +1,3 @@ -/****************************************************************************************************** - - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - /* =========================================================================== File: ENH1632.C v.2.3 - 30.Nov.2009 @@ -41,7 +9,7 @@ History: 07 Nov 04 v2.0 Incorporation of new 32-bit / 40-bit / control - operators for the ITU-T Standard Tool Library as + operators for the ITU-T Standard Tool Library as described in Geneva, 20-30 January 2004 WP 3/16 Q10/16 TD 11 document and subsequent discussions on the wp3audio@yahoogroups.com email reflector. @@ -50,7 +18,7 @@ */ -/***************************************************************************** + /***************************************************************************** * * Enhanced 16/32 bit operators : * s_max() @@ -84,12 +52,16 @@ * Include-Files * *****************************************************************************/ - #include #include #include "stl.h" -#define WMC_TOOL_SKIP +#if (WMOPS) +extern BASIC_OP multiCounter[MAXCOUNTERS]; +extern int currCounter; +#endif /* ifdef WMOPS */ + + /***************************************************************************** * @@ -121,10 +93,10 @@ * * Inputs : * - * var1 16 bit short signed integer (Word16) whose value falls in + * var1 16 bit short signed integer (Word16) whose value falls in * the range 0xffff 8000 <= var1 <= 0x0000 7fff. * - * var2 16 bit short signed integer (Word16) whose value falls in + * var2 16 bit short signed integer (Word16) whose value falls in * the range 0xffff 8000 <= var2 <= 0x0000 7fff. * * Outputs : @@ -133,46 +105,35 @@ * * Return Value: * - * var_out 16 bit short signed integer (Word16) whose value falls in + * var_out 16 bit short signed integer (Word16) whose value falls in * the range 0xffff 8000 <= var_out <= 0x0000 7fff. * *****************************************************************************/ -Word16 lshl( Word16 var1, Word16 var2 ) -{ - Word16 var_out = 0; - - if ( var2 < 0 ) - { - var2 = -var2; - var_out = lshr( var1, var2 ); -#ifdef WMOPS - multiCounter[currCounter].lshr--; -#endif - } - else - { - if ( var2 == 0 || var1 == 0 ) - { - var_out = var1; - } - else if ( var2 >= 16 ) - { - var_out = 0; - } - else - { - var_out = var1 << var2; - } - } +Word16 lshl (Word16 var1, Word16 var2) { + Word16 var_out = 0; -#ifdef WMOPS - multiCounter[currCounter].lshl++; -#endif - - BASOP_CHECK(); + if (var2 < 0) { + var2 = -var2; + var_out = lshr (var1, var2); +#if (WMOPS) + multiCounter[currCounter].lshr--; +#endif /* ifdef WMOPS */ + + } else { + if (var2 == 0 || var1 == 0) { + var_out = var1; + } else if (var2 >= 16) { + var_out = 0; + } else { + var_out = var1 << var2; + } + } +#if (WMOPS) + multiCounter[currCounter].lshl++; +#endif /* ifdef WMOPS */ - return ( var_out ); + return (var_out); } /***************************************************************************** @@ -191,10 +152,10 @@ Word16 lshl( Word16 var1, Word16 var2 ) * * Inputs : * - * var1 16 bit short signed integer (Word16) whose value falls in + * var1 16 bit short signed integer (Word16) whose value falls in * the range 0xffff 8000 <= var1 <= 0x0000 7fff. * - * var2 16 bit short signed integer (Word16) whose value falls in + * var2 16 bit short signed integer (Word16) whose value falls in * the range 0xffff 8000 <= var2 <= 0x0000 7fff. * * Outputs : @@ -203,48 +164,37 @@ Word16 lshl( Word16 var1, Word16 var2 ) * * Return Value: * - * var_out 16 bit short signed integer (Word16) whose value falls in + * var_out 16 bit short signed integer (Word16) whose value falls in * the range 0xffff 8000 <= var_out <= 0x0000 7fff. * *****************************************************************************/ -Word16 lshr( Word16 var1, Word16 var2 ) -{ - Word16 var_out; - - if ( var2 < 0 ) - { - var2 = -var2; - var_out = lshl( var1, var2 ); -#ifdef WMOPS - multiCounter[currCounter].lshl--; -#endif - } - else - { - if ( var2 == 0 || var1 == 0 ) - { - var_out = var1; - } - else if ( var2 >= 16 ) - { - var_out = 0; - } - else - { - var_out = var1 >> 1; - var_out = var_out & 0x7fff; - var_out = var_out >> ( var2 - 1 ); - } - } - -#ifdef WMOPS - multiCounter[currCounter].lshr++; -#endif +Word16 lshr (Word16 var1, Word16 var2) { + Word16 var_out; - BASOP_CHECK(); + if (var2 < 0) { + var2 = -var2; + var_out = lshl (var1, var2); +#if (WMOPS) + multiCounter[currCounter].lshl--; +#endif /* ifdef WMOPS */ + + } else { + if (var2 == 0 || var1 == 0) { + var_out = var1; + } else if (var2 >= 16) { + var_out = 0; + } else { + var_out = var1 >> 1; + var_out = var_out & 0x7fff; + var_out = var_out >> (var2 - 1); + } + } +#if (WMOPS) + multiCounter[currCounter].lshr++; +#endif /* ifdef WMOPS */ - return ( var_out ); + return (var_out); } @@ -264,10 +214,10 @@ Word16 lshr( Word16 var1, Word16 var2 ) * * Inputs : * - * L_var1 32 bit long signed integer (Word32) whose value falls in + * L_var1 32 bit long signed integer (Word32) whose value falls in * the range 0x8000 0000 <= L_var1 <= 0x7fff ffff. * - * var2 16 bit short signed integer (Word16) whose value falls in + * var2 16 bit short signed integer (Word16) whose value falls in * the range 0xffff 8000 <= var2 <= 0x0000 7fff. * * Outputs : @@ -276,45 +226,35 @@ Word16 lshr( Word16 var1, Word16 var2 ) * * Return Value: * - * L_var_out 32 bit long signed integer (Word32) whose value falls in + * L_var_out 32 bit long signed integer (Word32) whose value falls in * the range 0x8000 0000 <= L_var_out <= 0x7fff ffff. * *****************************************************************************/ -Word32 L_lshl( Word32 L_var1, Word16 var2 ) -{ - Word32 L_var_out = 0; - - if ( var2 < 0 ) - { - var2 = -var2; - L_var_out = L_lshr( L_var1, var2 ); -#ifdef WMOPS - multiCounter[currCounter].L_lshr--; -#endif - } - else - { - if ( var2 == 0 || L_var1 == 0 ) - { - L_var_out = L_var1; - } - else if ( var2 >= 32 ) - { - L_var_out = 0; - } - else - { - L_var_out = L_var1 << var2; - } - } +Word32 L_lshl (Word32 L_var1, Word16 var2) { + Word32 L_var_out = 0; -#ifdef WMOPS - multiCounter[currCounter].L_lshl++; -#endif + if (var2 < 0) { + var2 = -var2; + L_var_out = L_lshr (L_var1, var2); - BASOP_CHECK(); +#if (WMOPS) + multiCounter[currCounter].L_lshr--; +#endif /* ifdef WMOPS */ + + } else { + if (var2 == 0 || L_var1 == 0) { + L_var_out = L_var1; + } else if (var2 >= 32) { + L_var_out = 0; + } else { + L_var_out = L_var1 << var2; + } + } +#if (WMOPS) + multiCounter[currCounter].L_lshl++; +#endif /* ifdef WMOPS */ - return ( L_var_out ); + return (L_var_out); } @@ -334,10 +274,10 @@ Word32 L_lshl( Word32 L_var1, Word16 var2 ) * * Inputs : * - * L_var1 32 bit long signed integer (Word32) whose value falls in + * L_var1 32 bit long signed integer (Word32) whose value falls in * the range 0x8000 0000 <= L_var1 <= 0x7fff ffff. * - * var2 16 bit short signed integer (Word16) whose value falls in + * var2 16 bit short signed integer (Word16) whose value falls in * the range 0xffff 8000 <= var2 <= 0x0000 7fff. * * Outputs : @@ -346,48 +286,37 @@ Word32 L_lshl( Word32 L_var1, Word16 var2 ) * * Return Value: * - * L_var_out 32 bit long signed integer (Word32) whose value falls in + * L_var_out 32 bit long signed integer (Word32) whose value falls in * the range 0x8000 0000 <= L_var_out <= 0x7fff ffff. * *****************************************************************************/ -Word32 L_lshr( Word32 L_var1, Word16 var2 ) -{ - Word32 L_var_out; - - if ( var2 < 0 ) - { - var2 = -var2; - L_var_out = L_lshl( L_var1, var2 ); -#ifdef WMOPS - multiCounter[currCounter].L_lshl--; -#endif - } - else - { - if ( var2 == 0 || L_var1 == 0 ) - { - L_var_out = L_var1; - } - else if ( var2 >= 32 ) - { - L_var_out = 0; - } - else - { - L_var_out = L_var1 >> 1; - L_var_out = L_var_out & 0x7fffffff; - L_var_out = L_var_out >> ( var2 - 1 ); - } - } - -#ifdef WMOPS - multiCounter[currCounter].L_lshr++; -#endif +Word32 L_lshr (Word32 L_var1, Word16 var2) { + Word32 L_var_out; - BASOP_CHECK(); + if (var2 < 0) { + var2 = -var2; + L_var_out = L_lshl (L_var1, var2); +#if (WMOPS) + multiCounter[currCounter].L_lshl--; +#endif /* ifdef WMOPS */ + + } else { + if (var2 == 0 || L_var1 == 0) { + L_var_out = L_var1; + } else if (var2 >= 32) { + L_var_out = 0; + } else { + L_var_out = L_var1 >> 1; + L_var_out = L_var_out & 0x7fffffff; + L_var_out = L_var_out >> (var2 - 1); + } + } +#if (WMOPS) + multiCounter[currCounter].L_lshr++; +#endif /* ifdef WMOPS */ - return ( L_var_out ); + return (L_var_out); } @@ -404,10 +333,10 @@ Word32 L_lshr( Word32 L_var1, Word16 var2 ) * * Inputs : * - * var1 16 bit short signed integer (Word16) whose value falls in + * var1 16 bit short signed integer (Word16) whose value falls in * the range : 0xffff 8000 <= var1 <= 0x0000 7fff. * - * var2 16 bit short signed integer (Word16) whose value falls in + * var2 16 bit short signed integer (Word16) whose value falls in * the range : 0xffff 8000 <= var2 <= 0x0000 7fff. * * Outputs : @@ -416,38 +345,50 @@ Word32 L_lshr( Word32 L_var1, Word16 var2 ) * * Return Value : * - * var_out 16 bit short signed integer (Word16) whose value falls in + * var_out 16 bit short signed integer (Word16) whose value falls in * the range : 0xffff 8000 <= var_out <= 0x0000 7fff. * *****************************************************************************/ -Word16 shl_r( Word16 var1, Word16 var2 ) -{ - Word16 var_out; - - if ( var2 >= 0 ) - { - var_out = shl( var1, var2 ); -#ifdef WMOPS - multiCounter[currCounter].shl--; -#endif - } - else - { - var2 = -var2; - var_out = shr_r( var1, var2 ); -#ifdef WMOPS - multiCounter[currCounter].shr_r--; +#ifdef BASOP_NOGLOB +Word16 shl_ro(Word16 var1, Word16 var2, Flag* Overflow) { +#else +Word16 shl_r (Word16 var1, Word16 var2) { #endif - } + Word16 var_out; -#ifdef WMOPS - multiCounter[currCounter].shl_r++; + if (var2 >= 0) { +#ifdef BASOP_NOGLOB + var_out = shl_o (var1, var2, Overflow); +#else + var_out = shl (var1, var2); #endif +#if (WMOPS) + multiCounter[currCounter].shl--; +#endif /* ifdef WMOPS */ + + } else { + var2 = -var2; +#ifdef BASOP_NOGLOB + var_out = shr_ro (var1, var2, Overflow); +#else + var_out = shr_r (var1, var2); +#endif +#if (WMOPS) + multiCounter[currCounter].shr_r--; +#endif /* ifdef WMOPS */ + } - return ( var_out ); -} - +#if (WMOPS) + multiCounter[currCounter].shl_r++; +#endif /* ifdef WMOPS */ + return (var_out); +} +#ifdef BASOP_NOGLOB +Word16 shl_r(Word16 var1, Word16 var2) { + return shl_ro(var1, var2, NULL); +} +#endif /***************************************************************************** * * Function Name : L_shl_r @@ -461,10 +402,10 @@ Word16 shl_r( Word16 var1, Word16 var2 ) * * Inputs : * - * L_var1 32 bit long signed integer (Word32) whose value falls in + * L_var1 32 bit long signed integer (Word32) whose value falls in * the range : 0x8000 0000 <= L_var1 <= 0x7fff ffff. * - * var2 16 bit short signed integer (Word16) whose value falls in + * var2 16 bit short signed integer (Word16) whose value falls in * the range : 0xffff 8000 <= var2 <= 0x0000 7fff. * * Outputs : @@ -473,35 +414,34 @@ Word16 shl_r( Word16 var1, Word16 var2 ) * * Return Value : * - * L_var_out 32 bit long signed integer (Word32) whose value falls in + * L_var_out 32 bit long signed integer (Word32) whose value falls in * the range : 0x8000 0000 <= var_out <= 0x7fff ffff. * *****************************************************************************/ -Word32 L_shl_r( Word32 L_var1, Word16 var2 ) -{ - Word32 var_out; - - if ( var2 >= 0 ) - { - var_out = L_shl( L_var1, var2 ); -#ifdef WMOPS - multiCounter[currCounter].L_shl--; -#endif - } - else - { - var2 = -var2; - var_out = L_shr_r( L_var1, var2 ); -#ifdef WMOPS - multiCounter[currCounter].L_shr_r--; -#endif - } +Word32 L_shl_r (Word32 L_var1, Word16 var2) { + Word32 var_out; -#ifdef WMOPS - multiCounter[currCounter].L_shl_r++; -#endif + if (var2 >= 0) { + var_out = L_shl (L_var1, var2); + +#if (WMOPS) + multiCounter[currCounter].L_shl--; +#endif /* ifdef WMOPS */ + + } else { + var2 = -var2; + var_out = L_shr_r (L_var1, var2); - return ( var_out ); +#if (WMOPS) + multiCounter[currCounter].L_shr_r--; +#endif /* ifdef WMOPS */ + } + +#if (WMOPS) + multiCounter[currCounter].L_shl_r++; +#endif /* ifdef WMOPS */ + + return (var_out); } @@ -526,7 +466,7 @@ Word32 L_shl_r( Word32 L_var1, Word16 var2 ) * * Outputs : * - * *var3 Points on a 16 bit short signed integer (Word16) whose + * *var3 Points on a 16 bit short signed integer (Word16) whose * value will be 0 or 1. * * Return Value : @@ -535,22 +475,21 @@ Word32 L_shl_r( Word32 L_var1, Word16 var2 ) * the range : 0xffff 8000 <= var_out <= 0x0000 7fff. * *****************************************************************************/ -Word16 rotr( Word16 var1, Word16 var2, Word16 *var3 ) -{ - Word16 var_out; +Word16 rotr (Word16 var1, Word16 var2, Word16 * var3) { + Word16 var_out; - *var3 = s_and( var1, 0x1 ); - var_out = s_or( lshr( var1, 1 ), lshl( var2, 15 ) ); + *var3 = s_and (var1, 0x1); + var_out = s_or (lshr (var1, 1), lshl (var2, 15)); -#ifdef WMOPS - multiCounter[currCounter].s_and--; - multiCounter[currCounter].lshl--; - multiCounter[currCounter].lshr--; - multiCounter[currCounter].s_or--; - multiCounter[currCounter].rotr++; -#endif +#if (WMOPS) + multiCounter[currCounter].s_and--; + multiCounter[currCounter].lshl--; + multiCounter[currCounter].lshr--; + multiCounter[currCounter].s_or--; + multiCounter[currCounter].rotr++; +#endif /* ifdef WMOPS */ - return ( var_out ); + return (var_out); } @@ -575,7 +514,7 @@ Word16 rotr( Word16 var1, Word16 var2, Word16 *var3 ) * * Outputs : * - * *var3 Points on a 16 bit short signed integer (Word16) whose + * *var3 Points on a 16 bit short signed integer (Word16) whose * value will be 0 or 1. * * Return Value : @@ -584,23 +523,22 @@ Word16 rotr( Word16 var1, Word16 var2, Word16 *var3 ) * the range : 0xffff 8000 <= var_out <= 0x0000 7fff. * *****************************************************************************/ -Word16 rotl( Word16 var1, Word16 var2, Word16 *var3 ) -{ - Word16 var_out; +Word16 rotl (Word16 var1, Word16 var2, Word16 * var3) { + Word16 var_out; - *var3 = lshr( var1, 15 ); + *var3 = lshr (var1, 15); - var_out = s_or( lshl( var1, 1 ), s_and( var2, 0x1 ) ); + var_out = s_or (lshl (var1, 1), s_and (var2, 0x1)); -#ifdef WMOPS - multiCounter[currCounter].lshr--; - multiCounter[currCounter].s_and--; - multiCounter[currCounter].lshl--; - multiCounter[currCounter].s_or--; - multiCounter[currCounter].rotl++; -#endif +#if (WMOPS) + multiCounter[currCounter].lshr--; + multiCounter[currCounter].s_and--; + multiCounter[currCounter].lshl--; + multiCounter[currCounter].s_or--; + multiCounter[currCounter].rotl++; +#endif /* ifdef WMOPS */ - return ( var_out ); + return (var_out); } @@ -625,7 +563,7 @@ Word16 rotl( Word16 var1, Word16 var2, Word16 *var3 ) * * Outputs : * - * *var3 Points on a 16 bit short signed integer (Word16) whose + * *var3 Points on a 16 bit short signed integer (Word16) whose * value will be 0 or 1. * * Return Value : @@ -634,25 +572,24 @@ Word16 rotl( Word16 var1, Word16 var2, Word16 *var3 ) * the range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. * *****************************************************************************/ -Word32 L_rotr( Word32 L_var1, Word16 var2, Word16 *var3 ) -{ - Word32 L_var_out; +Word32 L_rotr (Word32 L_var1, Word16 var2, Word16 * var3) { + Word32 L_var_out; - *var3 = s_and( extract_l( L_var1 ), 0x1 ); + *var3 = s_and (extract_l (L_var1), 0x1); - L_var_out = L_or( L_lshr( L_var1, 1 ), L_lshl( L_deposit_l( var2 ), 31 ) ); + L_var_out = L_or (L_lshr (L_var1, 1), L_lshl (L_deposit_l (var2), 31)); -#ifdef WMOPS - multiCounter[currCounter].extract_l--; - multiCounter[currCounter].s_and--; - multiCounter[currCounter].L_deposit_l--; - multiCounter[currCounter].L_lshl--; - multiCounter[currCounter].L_lshr--; - multiCounter[currCounter].L_or--; - multiCounter[currCounter].L_rotr++; -#endif +#if (WMOPS) + multiCounter[currCounter].extract_l--; + multiCounter[currCounter].s_and--; + multiCounter[currCounter].L_deposit_l--; + multiCounter[currCounter].L_lshl--; + multiCounter[currCounter].L_lshr--; + multiCounter[currCounter].L_or--; + multiCounter[currCounter].L_rotr++; +#endif /* ifdef WMOPS */ - return ( L_var_out ); + return (L_var_out); } @@ -677,7 +614,7 @@ Word32 L_rotr( Word32 L_var1, Word16 var2, Word16 *var3 ) * * Outputs : * - * *var3 Points on a 16 bit short signed integer (Word16) whose + * *var3 Points on a 16 bit short signed integer (Word16) whose * value will be 0 or 1. * * Return Value : @@ -686,25 +623,55 @@ Word32 L_rotr( Word32 L_var1, Word16 var2, Word16 *var3 ) * the range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. * *****************************************************************************/ -Word32 L_rotl( Word32 L_var1, Word16 var2, Word16 *var3 ) -{ - Word32 L_var_out; +Word32 L_rotl (Word32 L_var1, Word16 var2, Word16 * var3) { + Word32 L_var_out; - *var3 = extract_l( L_lshr( L_var1, 31 ) ); + *var3 = extract_l (L_lshr (L_var1, 31)); - L_var_out = L_or( L_lshl( L_var1, 1 ), L_deposit_l( s_and( var2, 0x1 ) ) ); + L_var_out = L_or (L_lshl (L_var1, 1), L_deposit_l (s_and (var2, 0x1))); -#ifdef WMOPS - multiCounter[currCounter].L_lshr--; - multiCounter[currCounter].extract_l--; - multiCounter[currCounter].s_and--; - multiCounter[currCounter].L_deposit_l--; - multiCounter[currCounter].L_lshl--; - multiCounter[currCounter].L_or--; - multiCounter[currCounter].L_rotl++; -#endif +#if (WMOPS) + multiCounter[currCounter].L_lshr--; + multiCounter[currCounter].extract_l--; + multiCounter[currCounter].s_and--; + multiCounter[currCounter].L_deposit_l--; + multiCounter[currCounter].L_lshl--; + multiCounter[currCounter].L_or--; + multiCounter[currCounter].L_rotl++; +#endif /* ifdef WMOPS */ - return ( L_var_out ); + return (L_var_out); } -#undef WMC_TOOL_SKIP + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +/* end of file */ diff --git a/lib_com/enh1632.h b/lib_com/enh1632.h index 8e943d42f07c872a607517aa3b202a4985486831..1ac51dccb786e90cc385e4634cfe02bc89e308bc 100644 --- a/lib_com/enh1632.h +++ b/lib_com/enh1632.h @@ -1,35 +1,3 @@ -/****************************************************************************************************** - - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - /* =========================================================================== File: ENH1632.H v.2.3 - 30.Nov.2009 @@ -41,13 +9,13 @@ History: 07 Nov 04 v2.0 Incorporation of new 32-bit / 40-bit / control - operators for the ITU-T Standard Tool Library as + operators for the ITU-T Standard Tool Library as described in Geneva, 20-30 January 2004 WP 3/16 Q10/16 TD 11 document and subsequent discussions on the wp3audio@yahoogroups.com email reflector. March 06 v2.1 Changed to improve portability. - Some counters incrementations were missing (s_and, - s_or, s_xor). + Some counters incrementations were missing (s_and, + s_or, s_xor). 30 Nov 09 v2.3 saturate() removed ============================================================================ @@ -68,24 +36,35 @@ #include "stl.h" +#if (WMOPS) +#include "count.h" +extern BASIC_OP multiCounter[MAXCOUNTERS]; +extern int currCounter; +#endif /* ifdef WMOPS */ + + /***************************************************************************** * * Prototypes for enhanced 16/32 bit arithmetic operators * *****************************************************************************/ -Word16 shl_r( Word16 var1, Word16 var2 ); -Word32 L_shl_r( Word32 L_var1, Word16 var2 ); +#ifdef BASOP_NOGLOB +Word16 shl_ro(Word16 var1, Word16 var2, Flag* Overflow); +#endif +Word16 shl_r (Word16 var1, Word16 var2); +Word32 L_shl_r (Word32 L_var1, Word16 var2); -Word16 lshl( Word16 var1, Word16 var2 ); -Word16 lshr( Word16 var1, Word16 var2 ); -Word32 L_lshl( Word32 L_var1, Word16 var2 ); -Word32 L_lshr( Word32 L_var1, Word16 var2 ); +Word16 lshl (Word16 var1, Word16 var2); +Word16 lshr (Word16 var1, Word16 var2); +Word32 L_lshl (Word32 L_var1, Word16 var2); +Word32 L_lshr (Word32 L_var1, Word16 var2); + +Word16 rotr (Word16 var1, Word16 var2, Word16 * var3); +Word16 rotl (Word16 var1, Word16 var2, Word16 * var3); +Word32 L_rotr (Word32 var1, Word16 var2, Word16 * var3); +Word32 L_rotl (Word32 var1, Word16 var2, Word16 * var3); -Word16 rotr( Word16 var1, Word16 var2, Word16 *var3 ); -Word16 rotl( Word16 var1, Word16 var2, Word16 *var3 ); -Word32 L_rotr( Word32 var1, Word16 var2, Word16 *var3 ); -Word32 L_rotl( Word32 var1, Word16 var2, Word16 *var3 ); /***************************************************************************** @@ -106,7 +85,7 @@ Word32 L_rotl( Word32 var1, Word16 var2, Word16 *var3 ); * * Inputs : * - * var1 16 bit short signed integer (Word16) whose value falls in + * var1 16 bit short signed integer (Word16) whose value falls in * the range : 0x8000 <= var1 <= 0x7fff. * * var2 16 bit short signed integer (Word16) whose value falls in @@ -122,20 +101,19 @@ Word32 L_rotl( Word32 var1, Word16 var2, Word16 *var3 ); * the range : 0x8000 <= L_var_out <= 0x7fff. * *****************************************************************************/ -static __inline Word16 s_max( Word16 var1, Word16 var2 ) -{ - Word16 var_out; +static __inline Word16 s_max (Word16 var1, Word16 var2) { + Word16 var_out; - if ( var1 >= var2 ) - var_out = var1; - else - var_out = var2; + if (var1 >= var2) + var_out = var1; + else + var_out = var2; -#ifdef WMOPS - multiCounter[currCounter].s_max++; -#endif +#if (WMOPS) + multiCounter[currCounter].s_max++; +#endif /* ifdef WMOPS */ - return ( var_out ); + return (var_out); } @@ -151,10 +129,10 @@ static __inline Word16 s_max( Word16 var1, Word16 var2 ) * * Inputs : * - * var1 16 bit short signed integer (Word16) whose value falls in + * var1 16 bit short signed integer (Word16) whose value falls in * the range : 0x8000 <= var1 <= 0x7fff. * - * var2 16 bit short signed integer (Word16) whose value falls in + * var2 16 bit short signed integer (Word16) whose value falls in * the range : 0x8000 <= var2 <= 0x7fff. * * Outputs : @@ -163,24 +141,23 @@ static __inline Word16 s_max( Word16 var1, Word16 var2 ) * * Return Value : * - * var_out 16 bit short signed integer (Word16) whose value falls in + * var_out 16 bit short signed integer (Word16) whose value falls in * the range : 0x8000 <= var_out <= 0x7fff. * *****************************************************************************/ -static __inline Word16 s_min( Word16 var1, Word16 var2 ) -{ - Word16 var_out; +static __inline Word16 s_min (Word16 var1, Word16 var2) { + Word16 var_out; - if ( var1 <= var2 ) - var_out = var1; - else - var_out = var2; + if (var1 <= var2) + var_out = var1; + else + var_out = var2; -#ifdef WMOPS - multiCounter[currCounter].s_min++; -#endif +#if (WMOPS) + multiCounter[currCounter].s_min++; +#endif /* ifdef WMOPS */ - return ( var_out ); + return (var_out); } @@ -212,20 +189,19 @@ static __inline Word16 s_min( Word16 var1, Word16 var2 ) * range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. * *****************************************************************************/ -static __inline Word32 L_max( Word32 L_var1, Word32 L_var2 ) -{ - Word32 L_var_out; +static __inline Word32 L_max (Word32 L_var1, Word32 L_var2) { + Word32 L_var_out; - if ( L_var1 >= L_var2 ) - L_var_out = L_var1; - else - L_var_out = L_var2; + if (L_var1 >= L_var2) + L_var_out = L_var1; + else + L_var_out = L_var2; -#ifdef WMOPS - multiCounter[currCounter].L_max++; -#endif +#if (WMOPS) + multiCounter[currCounter].L_max++; +#endif /* ifdef WMOPS */ - return ( L_var_out ); + return (L_var_out); } @@ -257,23 +233,30 @@ static __inline Word32 L_max( Word32 L_var1, Word32 L_var2 ) * range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. * *****************************************************************************/ -static __inline Word32 L_min( Word32 L_var1, Word32 L_var2 ) -{ - Word32 L_var_out; +static __inline Word32 L_min (Word32 L_var1, Word32 L_var2) { + Word32 L_var_out; - if ( L_var1 <= L_var2 ) - L_var_out = L_var1; - else - L_var_out = L_var2; + if (L_var1 <= L_var2) + L_var_out = L_var1; + else + L_var_out = L_var2; -#ifdef WMOPS - multiCounter[currCounter].L_min++; -#endif +#if (WMOPS) + multiCounter[currCounter].L_min++; +#endif /* ifdef WMOPS */ - return ( L_var_out ); + return (L_var_out); } + + + + + + + + /***************************************************************************** * * Function Name : s_and @@ -303,17 +286,16 @@ static __inline Word32 L_min( Word32 L_var1, Word32 L_var2 ) * falls in the range 0xffff 8000 <= var_out <= 0x0000 7fff. * *****************************************************************************/ -static __inline Word16 s_and( Word16 var1, Word16 var2 ) -{ - Word16 var_out; +static __inline Word16 s_and (Word16 var1, Word16 var2) { + Word16 var_out; - var_out = var1 & var2; + var_out = var1 & var2; -#ifdef WMOPS - multiCounter[currCounter].s_and++; -#endif +#if (WMOPS) + multiCounter[currCounter].s_and++; +#endif /* ifdef WMOPS */ - return ( var_out ); + return (var_out); } @@ -346,17 +328,16 @@ static __inline Word16 s_and( Word16 var1, Word16 var2 ) * falls in the range 0x8000 0000 <= L_var_out <= 0x7fff ffff. * *****************************************************************************/ -static __inline Word32 L_and( Word32 L_var1, Word32 L_var2 ) -{ - Word32 L_var_out; +static __inline Word32 L_and (Word32 L_var1, Word32 L_var2) { + Word32 L_var_out; - L_var_out = L_var1 & L_var2; + L_var_out = L_var1 & L_var2; -#ifdef WMOPS - multiCounter[currCounter].L_and++; -#endif +#if (WMOPS) + multiCounter[currCounter].L_and++; +#endif /* ifdef WMOPS */ - return ( L_var_out ); + return (L_var_out); } @@ -389,17 +370,16 @@ static __inline Word32 L_and( Word32 L_var1, Word32 L_var2 ) * falls in the range 0xffff 8000 <= var_out <= 0x0000 7fff. * *****************************************************************************/ -static __inline Word16 s_or( Word16 var1, Word16 var2 ) -{ - Word16 var_out; +static __inline Word16 s_or (Word16 var1, Word16 var2) { + Word16 var_out; - var_out = var1 | var2; + var_out = var1 | var2; -#ifdef WMOPS - multiCounter[currCounter].s_or++; -#endif +#if (WMOPS) + multiCounter[currCounter].s_or++; +#endif /* ifdef WMOPS */ - return ( var_out ); + return (var_out); } @@ -432,18 +412,17 @@ static __inline Word16 s_or( Word16 var1, Word16 var2 ) * falls in the range 0x8000 0000 <= L_var_out <= 0x7fff ffff. * *****************************************************************************/ -static __inline Word32 L_or( Word32 L_var1, Word32 L_var2 ) -{ +static __inline Word32 L_or (Word32 L_var1, Word32 L_var2) { - Word32 L_var_out; + Word32 L_var_out; - L_var_out = L_var1 | L_var2; + L_var_out = L_var1 | L_var2; -#ifdef WMOPS - multiCounter[currCounter].L_or++; -#endif +#if (WMOPS) + multiCounter[currCounter].L_or++; +#endif /* ifdef WMOPS */ - return ( L_var_out ); + return (L_var_out); } @@ -476,17 +455,16 @@ static __inline Word32 L_or( Word32 L_var1, Word32 L_var2 ) * falls in the range 0xffff 8000 <= var_out <= 0x0000 7fff. * *****************************************************************************/ -static __inline Word16 s_xor( Word16 var1, Word16 var2 ) -{ - Word16 var_out; +static __inline Word16 s_xor (Word16 var1, Word16 var2) { + Word16 var_out; - var_out = var1 ^ var2; + var_out = var1 ^ var2; -#ifdef WMOPS - multiCounter[currCounter].s_xor++; -#endif +#if (WMOPS) + multiCounter[currCounter].s_xor++; +#endif /* ifdef WMOPS */ - return ( var_out ); + return (var_out); } @@ -519,20 +497,52 @@ static __inline Word16 s_xor( Word16 var1, Word16 var2 ) * falls in the range 0x8000 0000 <= L_var_out <= 0x7fff ffff. * *****************************************************************************/ -static __inline Word32 L_xor( Word32 L_var1, Word32 L_var2 ) -{ - Word32 L_var_out; +static __inline Word32 L_xor (Word32 L_var1, Word32 L_var2) { + Word32 L_var_out; - L_var_out = L_var1 ^ L_var2; + L_var_out = L_var1 ^ L_var2; -#ifdef WMOPS - multiCounter[currCounter].L_xor++; -#endif +#if (WMOPS) + multiCounter[currCounter].L_xor++; +#endif /* ifdef WMOPS */ - return ( L_var_out ); + return (L_var_out); } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #endif /*_ENH1632_H*/ /* end of file */ diff --git a/lib_com/enhancer.c b/lib_com/enhancer.c index 407588bc3f090b07430bec7148d9921d9afb621c..6968bbed9326103a66cda10c2f4e3ecdb1c8b51f 100644 --- a/lib_com/enhancer.c +++ b/lib_com/enhancer.c @@ -124,7 +124,7 @@ void enhancer( i = 0; /* high dispersion */ } - phase_dispersion( norm_gain_code, gain_pit, code, i, dispMem ); + phase_dispersion_flt( norm_gain_code, gain_pit, code, i, dispMem ); /*------------------------------------------------------------ * Noise enhancer diff --git a/lib_com/enhancer_fx.c b/lib_com/enhancer_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..9ffcfabccd7f22800f859dbe1ed862a1e8212590 --- /dev/null +++ b/lib_com/enhancer_fx.c @@ -0,0 +1,736 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ +#include +#include "options.h" /* Compilation switches */ +#include "cnst.h" /* Common constants */ +#include "prot_fx1.h" /* Function prototypes */ +#include "prot_fx2.h" /* Function prototypes */ +#include "rom_com.h" /* Static table prototypes */ +#include "basop_util.h" + +/*---------------------------------------------------------------------* + * Local constants + *---------------------------------------------------------------------*/ +#define pitch_0_9 14746 /* 0.9 in Q14 */ +#define pitch_0_6 9830 /* 0.6 in Q14 */ +#define SIZE 64 +#define SIZE2 32 +#define NUM_STAGES 5 + +/*---------------------------------------------------------------------* + * Local functions + *---------------------------------------------------------------------*/ +static void phase_dispersion_fx(Word32 gain_code,Word16 gain_pit,Word16 code[],Word16 mode,struct dispMem_fx *dm_fx); +static void agc2_fx(const Word16 *sig_in,Word16 *sig_out,const Word16 l_trm); + +/*======================================================================================*/ +/* FUNCTION : enhancer_fx() */ +/*--------------------------------------------------------------------------------------*/ +/* PURPOSE : Enhancement of the excitation signal before synthesis */ +/*--------------------------------------------------------------------------------------*/ +/* INPUT ARGUMENTS : */ +/* _ (Word32) core_brate : decoder bitrate */ +/* _ (Word16) Opt_AMR_WB : flag indicating AMR-WB IO mode */ +/* _ (Word16) coder_type : coder type */ +/* _ (Word16) i_subfr : subframe number */ +/* _ (Word16) voice_fac : subframe voicing estimation (Q15) */ +/* _ (Word16) stab_fac : LP filter stablility measure (Q15) */ +/* _ (Word32) norm_gain_code : normalised innovative cb. gain (Q16) */ +/* _ (Word16) gain_inov : gain of the unscaled innovation (Q12) */ +/* _ (Word16) gain_pit_fx : Pitch gain (Q14) */ +/* _ (Word16) Q_exc : Q of the excitation */ +/* _ (Word16) Enc : Encoder = 1; decoder = 0 */ +/*--------------------------------------------------------------------------------------*/ +/* OUTPUT ARGUMENTS : */ +/* _ (Word16*) voice_factors_fx : TBE voicing factor (Q15) */ +/*--------------------------------------------------------------------------------------*/ +/* INPUT/OUTPUT ARGUMENTS : */ +/* _ (Word32*) gc_threshold : gain code threshold (Q16) */ +/* _ (Word16*[]) code : innovation (Q12) */ +/* _ (Word16*[]) exc2 : adapt. excitation/total exc (Q0) */ +/* _ (struct dispMem_fx*) dm_fx : phase dispersion algorithm memory */ +/* (a[0]->Q0,a[1]->Q16,a[2-7]->Q14) */ +/*--------------------------------------------------------------------------------------*/ + +/* _ None */ +/*--------------------------------------------------------------------------------------*/ +/* RETURN ARGUMENTS : */ +/* _ None */ +/*======================================================================================*/ +void enhancer_fx( + const Word32 core_brate, /* i : decoder bitrate */ + const Word16 Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ + const Word16 coder_type, /* i : coder type */ + const Word16 i_subfr, /* i : subframe number */ + const Word16 L_frame, /* i : frame size */ + const Word16 voice_fac, /* i : subframe voicing estimation Q15 */ + const Word16 stab_fac, /* i : LP filter stablility measure Q15 */ + Word32 norm_gain_code, /* i : normalised innovative cb. gain Q16 */ + const Word16 gain_inov, /* i : gain of the unscaled innovation Q12 */ + Word32 *gc_threshold,/* i/o: gain code threshold Q16 */ + Word16 *code, /* i/o: innovation Q12 */ + Word16 *exc2, /* i/o: adapt. excitation/total exc. Q_exc*/ + const Word16 gain_pit, /* i : quantized pitch gain Q14 */ + struct dispMem_fx *dm_fx, /* i/o: phase dispersion algorithm memory */ + const Word16 Q_exc /* i : Q of the excitation */ +) +{ + Word16 tmp, fac, *pt_exc2; + Word16 i; + Word32 L_tmp; + Word16 gain_code_hi; + Word16 pit_sharp, tmp16; + Word16 excp[L_SUBFR], sc; + + + + pit_sharp = gain_pit; + move16(); /* to remove gcc warning */ + pt_exc2 = exc2 + i_subfr; + move16(); + + /*------------------------------------------------------------* + * Phase dispersion to enhance noise at low bit rate + *------------------------------------------------------------*/ + + i = 2; + move16(); /* no dispersion */ + IF (Opt_AMR_WB) + { + IF ( LE_32(core_brate,ACELP_6k60)) + { + i = 0; + move16(); /* high dispersion */ + } + ELSE if ( LE_32(core_brate,ACELP_8k85)) + { + i = 1; + move16(); /* low dispersion */ + } + } + ELSE IF( NE_16(coder_type,UNVOICED)) + + { + test(); + test(); + test(); + test(); + IF ( LE_32(core_brate,ACELP_7k20)) + { + i = 0; + move16(); /* high dispersion */ + } + ELSE if ( ( EQ_16(coder_type,GENERIC)||EQ_16(coder_type,TRANSITION)||EQ_16(coder_type,AUDIO)||EQ_16(coder_type,INACTIVE))&&LE_32(core_brate,ACELP_9k60)) + { + i = 1; + move16(); /* low dispersion */ + } + } + + phase_dispersion_fx(norm_gain_code, gain_pit, code, i, dm_fx); + + /*------------------------------------------------------------ + * noise enhancer + * + * - Enhance excitation on noise. (modify gain of code) + * If signal is noisy and LPC filter is stable, move gain + * of code 1.5 dB toward gain of code threshold. + * This decreases by 3 dB noise energy variation. + *-----------------------------------------------------------*/ + + /* tmp = 0.5f * (1.0f - voice_fac) */ +#ifdef BASOP_NOGLOB + tmp = msu_r_sat(0x40000000, voice_fac, 16384); /*Q15 */ /* 1=unvoiced, 0=voiced */ +#else + tmp = msu_r(0x40000000, voice_fac, 16384); /*Q15 */ /* 1=unvoiced, 0=voiced */ +#endif + /* fac = stab_fac * tmp */ + fac = mult(stab_fac, tmp); /*Q15*/ + + IF (LT_32(norm_gain_code, *gc_threshold)) + { + L_tmp = Madd_32_16(norm_gain_code, norm_gain_code, 6226);/*Q16 */ + L_tmp = L_min(L_tmp, *gc_threshold);/*Q16 */ + } + ELSE + { + L_tmp = Mult_32_16(norm_gain_code, 27536);/*Q16 */ + L_tmp = L_max(L_tmp, *gc_threshold); /*Q16 */ + } + *gc_threshold = L_tmp; + move32(); /*Q16 */ + + /* gain_code = (fac * tmp) + (1.0 - fac) * gain_code ==> fac * (tmp - gain_code) + gain_code */ + L_tmp = L_sub(L_tmp, norm_gain_code); /*Q16 */ + norm_gain_code = Madd_32_16(norm_gain_code, L_tmp, fac);/*Q16 */ + + /* gain_code *= gain_inov - Inverse the normalization */ + L_tmp = Mult_32_16(norm_gain_code, gain_inov); /*Q13*/ /* gain_inov in Q12 */ + + sc = 6; + move16(); + + gain_code_hi = round_fx(L_shl(L_tmp, add(Q_exc, 3))); /* in Q_exc */ + + /*------------------------------------------------------------* + * pitch enhancer + * + * - Enhance excitation on voiced. (HP filtering of code) + * On voiced signal, filtering of code by a smooth fir HP + * filter to decrease energy of code at low frequency. + *------------------------------------------------------------*/ + test(); + IF( !Opt_AMR_WB && EQ_16(coder_type,UNVOICED)) + { + /* Copy(code, exc2, L_SUBFR) */ + FOR (i = 0; i < L_SUBFR; i++) + { + pt_exc2[i] = round_fx(L_shl(L_mult(gain_code_hi, code[i]), sc)); /*Q0 */ /* code in Q12 (Q9 for encoder) */ + } + } + ELSE + { + test(); + test(); + IF ( Opt_AMR_WB && ( EQ_32(core_brate,ACELP_8k85)||EQ_32(core_brate,ACELP_6k60))) + { +#ifdef BASOP_NOGLOB + pit_sharp = shl_sat(gain_pit, 1); /* saturation can occur here Q14 -> Q15 */ +#else + pit_sharp = shl(gain_pit, 1); /* saturation can occur here Q14 -> Q15 */ +#endif + /* saturation takes care of "if (pit_sharp > 1.0) { pit_sharp=1.0; }" */ + IF (GT_16(pit_sharp, 16384)) + { + tmp16 = mult(pit_sharp, 8192); + FOR (i = 0; i < L_SUBFR; i++) + { + /* excp[i] = pt_exc2[i] * pit_sharp * 0.25 */ + excp[i] = mult_r(pt_exc2[i], tmp16); + move16(); + } + } + } + + IF ( EQ_16(L_frame, L_FRAME16k)) + { + /* tmp = 0.150 * (1.0 + voice_fac) */ + /* 0.30=voiced, 0=unvoiced */ + tmp = mac_r(0x10000000L, voice_fac, 4915);/*Q15 */ + } + ELSE + { + /* tmp = 0.125 * (1.0 + voice_fac) */ + /* 0.25=voiced, 0=unvoiced */ + tmp = mac_r(0x10000000L, voice_fac, 4096);/*Q15 */ + } + + /*----------------------------------------------------------------- + * Do a simple noncasual "sharpening": effectively an FIR + * filter with coefs [-tmp 1.0 -tmp] where tmp=0...0.25. + * This is applied to code and add_fxed to exc2 + *-----------------------------------------------------------------*/ + /* pt_exc2[0] += code[0] - tmp * code[1] */ + L_tmp = L_deposit_h(code[0]); /* if Enc :Q9 * Q15 -> Q25 */ + L_tmp = L_msu(L_tmp, code[1], tmp); /* Q12 * Q15 -> Q28 */ + L_tmp = L_shl(L_mult(gain_code_hi, extract_h(L_tmp)), sc); + pt_exc2[0] = msu_r(L_tmp, -32768, pt_exc2[0]); + move16();/* in Q_exc */ + + FOR (i = 1; i < L_SUBFR-1; i++) + { + /* pt_exc2[i] += code[i] - tmp * code[i-1] - tmp * code[i+1] */ + L_tmp = L_msu(-32768, code[i], -32768); + L_tmp = L_msu(L_tmp, code[i + 1], tmp); + tmp16 = msu_r(L_tmp, code[i - 1], tmp); + L_tmp = L_shl(L_mult(gain_code_hi, tmp16), sc); + pt_exc2[i] = msu_r(L_tmp, -32768, pt_exc2[i]); + move16(); /* in Q_exc */ + } + + /* pt_exc2[L_SUBFR-1] += code[L_SUBFR-1] - tmp * code[L_SUBFR-2] */ + L_tmp = L_deposit_h(code[L_SUBFR - 1]);/*Q28 */ + L_tmp = L_msu(L_tmp, code[L_SUBFR - 2], tmp);/*Q28 */ + L_tmp = L_shl(L_mult(gain_code_hi, extract_h(L_tmp)), sc); + pt_exc2[L_SUBFR - 1] = msu_r(L_tmp, -32768, pt_exc2[L_SUBFR - 1]); + move16();/* in Q_exc */ + test(); + test(); + IF ( Opt_AMR_WB && ( EQ_32(core_brate,ACELP_8k85)||EQ_32(core_brate,ACELP_6k60))) + { + IF (GT_16(pit_sharp, 16384)) + { + FOR (i = 0; i < L_SUBFR; i++) + { + /* excp[i] += pt_exc2[i] */ + excp[i] = add(excp[i], pt_exc2[i]); + move16(); + } + agc2_fx(pt_exc2, excp, L_SUBFR); + Copy(excp, pt_exc2, L_SUBFR); + } + } + } +} + +/*---------------------------------------------------------* + * Enhancement of the excitation signal before synthesis + *---------------------------------------------------------*/ + +Word16 E_UTIL_enhancer( + Word16 voice_fac, /* i : subframe voicing estimation Q15 */ + Word16 stab_fac, /* i : LP filter stability measure Q15 */ + Word32 gain_code, /* i : innovative cb. gain 15Q16 */ + Word16 gain_inov, /* i : gain of the unscaled innovation Q11 */ + Word32 *gc_threshold, /* i/o: gain code threshold 15Q16 */ + Word16 *code, /* i/o: innovation(in: Q9) code_exp */ + Word16 *exc2, /* i/o: adapt. excitation/total exc. */ + Word16 gain_pit, /* i : Quantized pitch gain 1Q14 */ + Word32 *prev_gain_code, /* i/o: previous codebook gain 15Q16 */ + Word16 prev_gain_pit[], /* i/o: previous pitch gain, size=6 1Q14 */ + Word16 *prev_state, /* i/o: Phase dispersion algorithm memory Q0 */ + Word16 coder_type, /* i : coder type */ + Word16 cdk_index, /* i : */ + Word16 L_subfr, /* i : length of subframe */ + Word16 L_frame, /* i : frame size */ + Word16 Q_new +) +{ + Word16 disp_mode, i; + Word16 tmp, fac, gain; + Word32 L_tmp; + Word16 code_exp, exc2_exp; + Word16 max_cdk_index_uv; + + move16(); + code_exp = 15-9; + exc2_exp = 15-Q_new; + gain_inov = shr(gain_inov,1); + /*-----------------------------------------------------------------* + * Phase dispersion to enhance noise at low bit rates + *-----------------------------------------------------------------*/ + + max_cdk_index_uv = 10; + move16(); + if ( EQ_16(L_frame, L_FRAME16k)) + { + max_cdk_index_uv = 14; + move16(); + } + disp_mode = 2; /* any=off */ move16(); + test(); + test(); + test(); + test(); + IF ( ( (NE_16(coder_type, VOICED))&&(LE_16(cdk_index,2)))||((EQ_16(coder_type,UNVOICED))&&(LE_16(cdk_index,max_cdk_index_uv)))) + { + disp_mode = 0; /* high */ move16(); + } + ELSE IF ( (NE_16(coder_type, VOICED))&&(LE_16(cdk_index,7))) + { + disp_mode = 1; /* low */ move16(); + } + + phase_dispersion(gain_code, gain_pit,code, &code_exp, disp_mode, prev_gain_code, prev_gain_pit, prev_state, L_subfr); + + /*------------------------------------------------------------* + * noise enhancer * + * ~~~~~~~~~~~~~~ * + * - Enhance excitation on noise. (modify gain of code) * + * If signal is noisy and LPC filter is stable, move gain * + * of code 1.5 dB toward gain of code threshold. * + * This decrease by 3 dB noise energy variation. * + *------------------------------------------------------------*/ + fac = 0; + move16(); + + /* if gain_code is computed function of energy, noise enhancer is by-passed.*/ + BASOP_SATURATE_WARNING_OFF_EVS +#ifdef BASOP_NOGLOB + tmp = msu_r_sat(1073741824l/*0.5f Q31*/, 16384/*0.5f Q15*/, voice_fac); /* 1=unvoiced, 0=voiced */ +#else /* BASOP_NOGLOB */ + tmp = msu_r(1073741824l/*0.5f Q31*/, 16384/*0.5f Q15*/, voice_fac); /* 1=unvoiced, 0=voiced */ +#endif + BASOP_SATURATE_WARNING_ON_EVS + fac = mult_r(stab_fac, tmp); /* fac in Q15 */ + + L_tmp = gain_code; /* L_tmp in 15Q16 */ + move32(); + + IF (LT_32(L_tmp,*gc_threshold)) + { + L_tmp = L_shl(Mpy_32_32(L_tmp, 1277752832l/*1.19f/2.0f Q31*/),1); + L_tmp = L_min(L_tmp, *gc_threshold); + } + ELSE + { + L_tmp = Mpy_32_32(L_tmp, 1804608000l/*1.0f/1.19f Q31*/); + L_tmp = L_max(L_tmp, *gc_threshold); + } + move32(); + *gc_threshold = L_tmp; /* in 15Q16 */ + + /* gain = ( (fac * L_tmp) + (gain_code - fac*gain_code) ) * gain_inov */ + /* exponent of L_tmp: 31-16 + 15-11 */ + L_tmp = Mpy_32_16_1(L_add(Mpy_32_16_1(L_tmp, fac), L_sub(gain_code, Mpy_32_16_1(gain_code, fac))), gain_inov); + + /* exponent gain: 31-16 + 15-11 - tmp */ + tmp = norm_l(L_tmp); + + /* exponent of code: 31-16 + 15-11 - tmp + code_exp */ + move16(); + code_exp = sub(add(31-16 + 15-11, code_exp), tmp); + +#ifdef BASOP_NOGLOB + L_tmp = L_shl_sat(L_tmp, tmp); + gain = round_fx_sat(L_tmp); +#else + L_tmp = L_shl(L_tmp, tmp); + gain = round_fx(L_tmp); +#endif + + FOR (i=0; iQ0,a[1]->Q16,a[2-7]->Q14) */ +/*--------------------------------------------------------------------------------------*/ + +/* _ None */ +/*--------------------------------------------------------------------------------------*/ +/* RETURN ARGUMENTS : */ +/* _ None */ +/*======================================================================================*/ +static void phase_dispersion_fx( + Word32 gain_code, /* i : gain of code Q16 */ + Word16 gain_pit, /* i : gain of pitch Q14 */ + Word16 code[], /* i/o: code vector */ + Word16 mode, /* i : level, 0=hi, 1=lo, 2=off */ + struct dispMem_fx *dm_fx /* i/o: static memory (size = 8) */ +) +{ + Word16 i, j, state; + Word16 *prev_gain_pit, *prev_state; + Word32 *prev_gain_code; + Word16 *code2_real, *code2_imag; + Word16 *code_real, *code_imag; + const Word16 *h_real, *h_imag; + + Word16 code2[2 * L_SUBFR]; + + prev_state = &(dm_fx->prev_state); + prev_gain_code = &(dm_fx->prev_gain_code); + prev_gain_pit = dm_fx->prev_gain_pit; + + state = 2; + move16(); + if (LT_16(gain_pit, pitch_0_9)) + { + state = 1; + move16(); + } + + if (LT_16(gain_pit, pitch_0_6)) + { + state = 0; + move16(); + } + + FOR (i = 5; i > 0; i--) + { + prev_gain_pit[i] = prev_gain_pit[i - 1]; + move16(); + } + prev_gain_pit[0] = gain_pit; + move16(); + + IF (GT_32(L_sub(gain_code, *prev_gain_code), L_shl(*prev_gain_code, 1))) + { + state = s_min(add(state, 1), 2); + } + ELSE + { + j = 0; + move16(); + + FOR (i = 0; i < 6; i++) + { + j = sub(j, shr(sub(prev_gain_pit[i], pitch_0_6), 15)); + } + + if (GT_16(j, 2)) + { + state = 0; + move16(); + } + + if (GT_16(sub(state, *prev_state), 1)) + { + state = sub(state, 1); + } + } + + *prev_gain_code = gain_code; + move32(); + *prev_state = state; + move16(); + + /*-----------------------------------------------------------------* + * circular convolution + *-----------------------------------------------------------------*/ + + state = add(state, mode); /* level of dispersion */ + + IF (LT_16(state, 2)) + { + r_fft_fx_lc(phs_tbl_dec, SIZE, SIZE2, NUM_STAGES, code, code2, 1); + + h_real = Mid_H_phasedisp; + move16(); + if (state == 0) + { + h_real = Low_H_phasedisp; + move16(); + } + + /* FFT Coefs are in code2 */ + code2_real = code2; + move16(); + code2_imag = code2 + L_SUBFR - 1; + move16(); + + code_real = code; + move16(); + code_imag = code + L_SUBFR - 1; + move16(); + + h_imag = h_real + L_SUBFR - 1; + move16(); + + *code_real++ = mult(*code2_real++, *h_real++); + move16(); /* DC */ + + FOR (i=1; i gain_pit Q14 to Q9 */ + + ener2 = extract_h(Dot_product12(code, code, L_SUBFR, &exp2)); + + exp = norm_l(gain_code); + tmp = extract_h(L_shl(gain_code, exp)); + tmp = mult(tmp, tmp); /* energy of innovative code excitation */ + ener2 = mult(ener2, tmp); + exp2 = sub(exp2, add(exp, exp)); + + i = sub(exp1, exp2); + BASOP_SATURATE_WARNING_OFF_EVS + ener1 = shr(ener1, sub(1, s_min(i, 0))); + ener2 = shr(ener2, add(s_max(0, i), 1)); + BASOP_SATURATE_WARNING_ON_EVS + tmp = sub(ener1, ener2); + ener1 = add(add(ener1, ener2), 1); + + /* find voice factor (1=voiced, -1=unvoiced) */ + exp = div_s(abs_s(tmp), ener1); + if (tmp < 0) + { + exp = negate(exp); + } + *voice_fac = exp; + move16(); + + /* tilt of code for next subframe: 0.5=voiced, 0=unvoiced */ + + /* tilt_code = (float)(0.25*(1.0 + *voice_fac)) */ + tilt_code = mac_r(8192L*65536-0x8000, *voice_fac, 8192); /*Q15 */ + + return tilt_code; +} +/*-------------------------------------------------------------------* + * Est_tilt2: + * + * Estimate spectral tilt based on the relative E of adaptive + * and innovative excitations + *-------------------------------------------------------------------*/ +Word16 Est_tilt2( /* o : tilt of the code */ + const Word16 *exc, /* i : adaptive excitation vector Qx */ + const Word16 gain_pit, /* i : adaptive gain Q14 */ + const Word16 *code, /* i : algebraic exctitation vector Q9 */ + const Word32 gain_code, /* i : algebraic code gain Q16 */ + Word16 *voice_fac, /* o : voicing factor Q15 */ + const Word16 Q_exc /* i : Scaling factor of excitation Q0 */ +) +{ + Word16 i, tmp, exp, ener1, exp1, ener2, exp2; + Word32 L_tmp; + Word16 tilt_code; + + /* Scale exc to avoid overflow */ + ener1 = extract_h(Energy_scale(exc, L_SUBFR, Q_exc, &exp1)); + + exp1 = sub(exp1, add(Q_exc, Q_exc)); + L_tmp = L_mult(gain_pit, gain_pit); /* energy of pitch excitation */ + exp = norm_l(L_tmp); + tmp = extract_h(L_shl(L_tmp, exp)); + ener1 = mult(ener1, tmp); + exp1 = sub(sub(exp1, exp), 10); /* 10 -> gain_pit Q14 to Q9 */ + + ener2 = extract_h(Dot_product12(code, code, L_SUBFR, &exp2)); + + exp = norm_l(gain_code); + tmp = extract_h(L_shl(gain_code, exp)); + tmp = mult(tmp, tmp); /* energy of innovative code excitation */ + ener2 = mult(ener2, tmp); + exp2 = sub(exp2, add(exp, exp)); + + i = sub(exp1, exp2); + ener1 = shr(ener1, sub(1, s_min(i, 0))); + ener2 = shr(ener2, add(s_max(0, i), 1)); + + tmp = sub(ener1, ener2); + ener1 = add(add(ener1, ener2), 1); + + /* find voice factor (1=voiced, -1=unvoiced) */ + exp = div_s(abs_s(tmp), ener1); + if (tmp < 0) + { + exp = negate(exp); + } + *voice_fac = exp; + move16(); + + /* tilt of code for next subframe: 0.5=voiced, 0=unvoiced */ + + /* tilt_code = (float)(0.25*(1.0 + *voice_fac)) */ + tilt_code = mac_r(8192L*65536-0x8000, *voice_fac, 8192); + + return tilt_code; +} + +/*---------------------------------------------------------* + * Find voice factor and tilt code * + *---------------------------------------------------------*/ +void E_UTIL_voice_factor( Word16 *exc, /* i : pointer to the excitation frame Q_new */ + Word16 i_subfr, /* i : subframe index */ + Word16 *code, /* i : innovative codebook Q9 */ + Word16 gain_pit, /* i : adaptive codebook gain 1Q14 */ + Word32 gain_code, /* i : innovative cb. gain 15Q16 */ + Word16 *voice_fac, /* o : subframe voicing estimation Q15 */ + Word16 *tilt_code, /* o : tilt factor Q15 */ + Word16 L_subfr, /* i : subframe length */ + Word16 flag_tilt, /* i : Flag for triggering new voice factor tilt*/ + Word16 Q_new, /* i : excitation buffer format */ + Word16 shift /* i : scaling to get 12bit */ + ) +{ + Word16 i, e, e2, stmp, exp_ener, fac; + Word32 ener, tmp, num; + Word64 ener_64; + + BASOP_SATURATE_ERROR_ON_EVS; + + + IF(shift != 0) + { + fac = shl(0x4000,add(1,shift)); + /* energy of pitch excitation */ + stmp = mult_r(exc[0+i_subfr], fac); /* remove fac bits */ + ener_64 = W_mult0_16_16(stmp, stmp); + FOR (i=1; i exponent = (15-Q_new)*2+1 */ + } + } + ener = W_sat_l( ener_64 ); + + + /* exponent of ener: (2*(15-Q_new+shift)+1+2-exp_ener-2*e2) */ + exp_ener = norm_l(ener); + if(ener == 0) + { + exp_ener = 31; + move16(); + } + ener = L_shl(ener,exp_ener); + e2 = norm_s(gain_pit); + gain_pit = shl(gain_pit,e2); + ener = Mpy_32_16_1(ener, mult_r(gain_pit, gain_pit)); + + + /* energy of innovative code excitation */ + tmp = L_deposit_l(1); + + FOR (i=0; i 13Q18 */ + } + /* exponent of tmp: 2*(15-9)+1+2*(15-e)) */ + e = norm_l(gain_code); + gain_code = L_shl(gain_code, e); + tmp = Mpy_32_32(tmp, Mpy_32_32(gain_code,gain_code)); + + /* find voice factor (1=voiced, -1=unvoiced) */ + /*i = (2*(15-Q_new+shift)+1+2-exp_ener-2*e2) - (2*(15-9)+1 + 2*(15-e));*/ + i = sub(sub(sub(sub(sub(33,add(shift,shift)),add(Q_new,Q_new)),exp_ener),add(e2,e2)),sub(43,add(e,e))); + IF(i >= 0) + { + ener = L_shr(ener,1); + tmp = L_shr(tmp, add(1,i)); + } + ELSE + { + tmp = L_shr(tmp,1); + BASOP_SATURATE_WARNING_OFF_EVS + ener = L_shr(ener, sub(1,i)); + BASOP_SATURATE_WARNING_ON_EVS + } + + *voice_fac = 0; + move16(); + num = L_sub(ener, tmp); + IF(num != 0) + { + BASOP_SATURATE_WARNING_OFF_EVS /* Allow saturating the voice factor because if has a limited range by definition. */ + *voice_fac = divide3232(num, L_add(ener, tmp)); + move16(); + BASOP_SATURATE_WARNING_ON_EVS + } + + /* find tilt of code for next subframe */ + IF (flag_tilt==0) + { + /*Between 0 (=unvoiced) and 0.5 (=voiced)*/ + move16(); + *tilt_code = add(8192/*0.25f Q15*/, mult_r(8192/*0.25f Q15*/, *voice_fac)); + } + ELSE IF (flag_tilt==1) + { + /*Between 0.25 (=unvoiced) and 0.5 (=voiced)*/ + move16(); + *tilt_code = add(mult_r(4096/*0.125f Q15*/, *voice_fac), 12288/*0.125f+0.25f Q15*/); + } + ELSE + { + /*Between 0.28 (=unvoiced) and 0.56 (=voiced)*/ + move16(); + *tilt_code = add(mult_r(4588/*0.14f Q15*/, *voice_fac), 13763/*0.14f+0.28f Q15*/); + } + BASOP_SATURATE_ERROR_OFF_EVS; +} diff --git a/lib_com/fd_cng_com.c b/lib_com/fd_cng_com.c index 6095c75089f83cf381e46ece7721b18c244903cf..101e7b5b4b2861c60c5c097ffc63cef8ccb344cf 100644 --- a/lib_com/fd_cng_com.c +++ b/lib_com/fd_cng_com.c @@ -47,18 +47,18 @@ * Local function prototypes *-------------------------------------------------------------------*/ -static void mhvals( const int16_t d, float *m ); +static void mhvals_flt( const int16_t d, float *m ); -static void getmidbands( int16_t *part, const int16_t npart, int16_t *midband, float *psize, float *psize_inv ); +static void getmidbands( int16_t *part, const int16_t npart, int16_t *midband, float *psize_flt, float *psize_inv_flt ); /*------------------------------------------------------------------- - * createFdCngCom() + * createFdCngCom_flt() * * Create an instance of type FD_CNG_COM *-------------------------------------------------------------------*/ -ivas_error createFdCngCom( +ivas_error createFdCngCom_flt( HANDLE_FD_CNG_COM *hFdCngCom /* i/o: FD_CNG structure containing all buffers and variables */ ) { @@ -77,39 +77,39 @@ ivas_error createFdCngCom( /*------------------------------------------------------------------- - * initFdCngCom() + * initFdCngCom_flt() * * *-------------------------------------------------------------------*/ -void initFdCngCom( +void initFdCngCom_flt( HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables */ const float scale ) { /* Calculate FFT scaling factor */ - hFdCngCom->scalingFactor = 1 / ( scale * scale * 8.f ); + hFdCngCom->scalingFactor_flt = 1 / ( scale * scale * 8.f ); /* Initialize the overlap-add */ - set_f( hFdCngCom->timeDomainBuffer, 0.0f, L_FRAME16k ); - set_f( hFdCngCom->olapBufferAna, 0.0f, FFTLEN ); - set_f( hFdCngCom->olapBufferSynth, 0.0f, FFTLEN ); - set_f( hFdCngCom->olapBufferSynth2, 0.0f, FFTLEN ); + set_f( hFdCngCom->timeDomainBuffer_flt, 0.0f, L_FRAME16k ); + set_f( hFdCngCom->olapBufferAna_flt, 0.0f, FFTLEN ); + set_f( hFdCngCom->olapBufferSynth_flt, 0.0f, FFTLEN ); + set_f( hFdCngCom->olapBufferSynth2_flt, 0.0f, FFTLEN ); /* Initialize the comfort noise generation */ - set_f( hFdCngCom->fftBuffer, 0.0f, FFTLEN ); - set_f( hFdCngCom->cngNoiseLevel, 0.0f, FFTCLDFBLEN ); + set_f( hFdCngCom->fftBuffer_flt, 0.0f, FFTLEN ); + set_f( hFdCngCom->cngNoiseLevel_flt, 0.0f, FFTCLDFBLEN ); /* Initialize quantizer */ - set_f( hFdCngCom->sidNoiseEst, 0.0f, NPART ); - set_f( hFdCngCom->A_cng, 0.0f, M + 1 ); - hFdCngCom->A_cng[0] = 1.f; + set_f( hFdCngCom->sidNoiseEst_flt, 0.0f, NPART ); + set_f( hFdCngCom->A_cng_flt, 0.0f, M + 1 ); + hFdCngCom->A_cng_flt[0] = 1.f; /* Set some counters and flags */ hFdCngCom->inactive_frame_counter = 0; /* Either SID or zero frames */ hFdCngCom->active_frame_counter = 0; hFdCngCom->frame_type_previous = ACTIVE_FRAME; hFdCngCom->flag_noisy_speech = 0; - hFdCngCom->likelihood_noisy_speech = 0.f; + hFdCngCom->likelihood_noisy_speech_flt = 0.f; hFdCngCom->numCoreBands = 0; hFdCngCom->stopBand = 0; hFdCngCom->startBand = 0; @@ -122,34 +122,34 @@ void initFdCngCom( hFdCngCom->CngBitrate = -1; /* Initialize noise estimation algorithm */ - set_f( hFdCngCom->periodog, 0.0f, PERIODOGLEN ); - mhvals( MSNUMSUBFR * MSSUBFRLEN, &( hFdCngCom->msM_win ) ); - mhvals( MSSUBFRLEN, &( hFdCngCom->msM_subwin ) ); - set_f( hFdCngCom->msPeriodogSum, 0.0f, 2 ); - set_f( hFdCngCom->msPsdSum, 0.0f, 2 ); - set_f( hFdCngCom->msSlope, 0.0f, 2 ); - set_f( hFdCngCom->msQeqInvAv, 0.0f, 2 ); + set_f( hFdCngCom->periodog_flt, 0.0f, PERIODOGLEN ); + mhvals_flt( MSNUMSUBFR * MSSUBFRLEN, &( hFdCngCom->msM_win_flt ) ); + mhvals_flt( MSSUBFRLEN, &( hFdCngCom->msM_subwin_flt ) ); + set_f( hFdCngCom->msPeriodogSum_flt, 0.0f, 2 ); + set_f( hFdCngCom->msPsdSum_flt, 0.0f, 2 ); + set_f( hFdCngCom->msSlope_flt, 0.0f, 2 ); + set_f( hFdCngCom->msQeqInvAv_flt, 0.0f, 2 ); hFdCngCom->msFrCnt_init_counter = 0; hFdCngCom->msFrCnt_init_thresh = 1; - hFdCngCom->init_old = 0; + hFdCngCom->init_old_flt = 0; hFdCngCom->offsetflag = 0; hFdCngCom->msFrCnt = MSSUBFRLEN; hFdCngCom->msMinBufferPtr = 0; - set_f( hFdCngCom->msAlphaCor, 0.3f, 2 ); + set_f( hFdCngCom->msAlphaCor_flt, 0.3f, 2 ); - hFdCngCom->coherence = 0.5f; + hFdCngCom->coherence_flt = 0.5f; return; } /*------------------------------------------------------------------- - * deleteFdCngCom() + * deleteFdCngCom_flt() * * Delete an instance of type FD_CNG_COM *-------------------------------------------------------------------*/ -void deleteFdCngCom( +void deleteFdCngCom_flt( HANDLE_FD_CNG_COM *hFdCngCom /* i/o: FD_CNG structure containing all buffers and variables */ ) { @@ -166,12 +166,12 @@ void deleteFdCngCom( /*------------------------------------------------------------------- - * initPartitions() + * initPartitions_flt() * * Initialize the spectral partitioning *-------------------------------------------------------------------*/ -void initPartitions( +void initPartitions_flt( const int16_t *part_in, const int16_t npart_in, const int16_t startBand, @@ -179,8 +179,8 @@ void initPartitions( int16_t *part_out, int16_t *npart_out, int16_t *midband, - float *psize, - float *psize_inv, + float *psize_flt, + float *psize_inv_flt, const int16_t stopBandFR ) { int16_t i, j, len_out; @@ -217,19 +217,19 @@ void initPartitions( } *npart_out = len_out; - getmidbands( part_out, len_out, midband, psize, psize_inv ); + getmidbands( part_out, len_out, midband, psize_flt, psize_inv_flt ); return; } /*------------------------------------------------------------------- - * compress_range() + * compress_range_flt() * * Apply some dynamic range compression based on the log *-------------------------------------------------------------------*/ -void compress_range( +void compress_range_flt( float *in, float *out, const int16_t len ) @@ -264,12 +264,12 @@ void compress_range( /*------------------------------------------------------------------- - * expand_range() + * expand_range_flt() * * Apply some dynamic range expansion to undo the compression *-------------------------------------------------------------------*/ -void expand_range( +void expand_range_flt( float *in, float *out, const int16_t len ) @@ -295,15 +295,15 @@ void expand_range( /*------------------------------------------------------------------- - * minimum_statistics() + * minimum_statistics_flt() * * Noise estimation using Minimum Statistics (MS) *-------------------------------------------------------------------*/ -void minimum_statistics( +void minimum_statistics_flt( const int16_t len, /* i : Vector length */ const int16_t lenFFT, /* i : Length of the FFT part of the vectors */ - float *psize, + float *psize_flt, float *msPeriodog, /* i : Periodograms */ float *msNoiseFloor, float *msNoiseEst, /* o : Noise estimates */ @@ -326,10 +326,10 @@ void minimum_statistics( const int16_t element_mode /* i : IVAS element mode type */ ) { - float msM_win = hFdCngCom->msM_win; - float msM_subwin = hFdCngCom->msM_subwin; - float *msPsdSum = hFdCngCom->msPsdSum; - float *msPeriodogSum = hFdCngCom->msPeriodogSum; + float msM_win_flt = hFdCngCom->msM_win_flt; + float msM_subwin_flt = hFdCngCom->msM_subwin_flt; + float *msPsdSum_flt = hFdCngCom->msPsdSum_flt; + float *msPeriodogSum_flt = hFdCngCom->msPeriodogSum_flt; float slope; float *ptr; float msAlphaCorAlpha = MSALPHACORALPHA_FLT; @@ -354,17 +354,17 @@ void minimum_statistics( mvr2r( msPeriodog, msNoiseEst, len ); mvr2r( msPeriodog, msPsdFirstMoment, len ); set_f( msPsdSecondMoment, 0.0f, len ); - msPeriodogSum[0] = dotp( msPeriodog, psize, lenFFT ); - msPsdSum[0] = msPeriodogSum[0]; + msPeriodogSum_flt[0] = dotp( msPeriodog, psize_flt, lenFFT ); + msPsdSum_flt[0] = msPeriodogSum_flt[0]; if ( lenFFT < len ) { - msPeriodogSum[1] = dotp( msPeriodog + lenFFT, psize + lenFFT, len - lenFFT ); - msPsdSum[1] = msPeriodogSum[1]; + msPeriodogSum_flt[1] = dotp( msPeriodog + lenFFT, psize_flt + lenFFT, len - lenFFT ); + msPsdSum_flt[1] = msPeriodogSum_flt[1]; } /* Increment frame counter at initialization */ /* Some frames are sometimes zero at initialization => ignore them */ - if ( msPeriodog[0] < hFdCngCom->init_old ) + if ( msPeriodog[0] < hFdCngCom->init_old_flt ) { set_f( msCurrentMinOut, FLT_MAX, len ); set_f( msCurrentMin, FLT_MAX, len ); @@ -372,7 +372,7 @@ void minimum_statistics( set_f( msCurrentMinSubWindow, FLT_MAX, len ); hFdCngCom->msFrCnt_init_counter++; } - hFdCngCom->init_old = msPeriodog[0]; + hFdCngCom->init_old_flt = msPeriodog[0]; } else { @@ -383,24 +383,24 @@ void minimum_statistics( start = 0; stop = lenFFT; totsize = hFdCngCom->stopFFTbin - hFdCngCom->startBand; - cnt = 0; /*msAlphaCor*/ + cnt = 0; /*msAlphaCor_flt*/ while ( stop > start ) { current_len = stop - start; /* Compute smoothed correction factor for PSD smoothing */ - msPeriodogSum[cnt] = dotp( msPeriodog + start, psize + start, current_len ); - scalar = msPeriodogSum[cnt] * msPeriodogSum[cnt] + DELTA; - scalar2 = msPsdSum[cnt] - msPeriodogSum[cnt]; + msPeriodogSum_flt[cnt] = dotp( msPeriodog + start, psize_flt + start, current_len ); + scalar = msPeriodogSum_flt[cnt] * msPeriodogSum_flt[cnt] + DELTA; + scalar2 = msPsdSum_flt[cnt] - msPeriodogSum_flt[cnt]; scalar = max( scalar / ( scalar + scalar2 * scalar2 ), MSALPHACORMAX_FLT ); - hFdCngCom->msAlphaCor[cnt] = msAlphaCorAlpha * hFdCngCom->msAlphaCor[cnt] + msAlphaCorAlpha2 * scalar; + hFdCngCom->msAlphaCor_flt[cnt] = msAlphaCorAlpha * hFdCngCom->msAlphaCor_flt[cnt] + msAlphaCorAlpha2 * scalar; /* Compute SNR */ - snr = dotp( msNoiseFloor + start, psize + start, current_len ); - snr = ( msPsdSum[cnt] + DELTA ) / ( snr + DELTA ); + snr = dotp( msNoiseFloor + start, psize_flt + start, current_len ); + snr = ( msPsdSum_flt[cnt] + DELTA ) / ( snr + DELTA ); snr = (float) pow( snr, MSSNREXP_FLT ); msAlphaHatMin2 = min( MSALPHAHATMIN_FLT, snr ); - scalar = MSALPHAMAX_FLT * hFdCngCom->msAlphaCor[cnt]; /*msAlpha,msPsd,msPeriodog,msNoiseFloor*/ + scalar = MSALPHAMAX_FLT * hFdCngCom->msAlphaCor_flt[cnt]; /*msAlpha,msPsd,msPeriodog,msNoiseFloor*/ for ( j = start; j < stop; j++ ) { /* Compute optimal smoothing parameter for PSD estimation */ @@ -412,10 +412,10 @@ void minimum_statistics( /* Compute the PSD (smoothed periodogram) in each band */ msPsd[j] = msAlpha[j] * msPsd[j] + ( 1.f - msAlpha[j] ) * msPeriodog[j]; } - msPsdSum[cnt] = dotp( msPsd + start, psize + start, current_len ); + msPsdSum_flt[cnt] = dotp( msPsd + start, psize_flt + start, current_len ); QeqInvAv = 0; - scalar = ( (float) ( MSNUMSUBFR * MSSUBFRLEN ) - 1.f ) * ( 1.f - msM_win ); - scalar2 = ( (float) MSSUBFRLEN - 1.f ) * ( 1.f - msM_subwin ); /*msAlpha,msPsd,msPsdFirstMoment,msPsdSecondMoment,msNoiseFloor,msBminSubWin,msBminWin,psize*/ + scalar = ( (float) ( MSNUMSUBFR * MSSUBFRLEN ) - 1.f ) * ( 1.f - msM_win_flt ); + scalar2 = ( (float) MSSUBFRLEN - 1.f ) * ( 1.f - msM_subwin_flt ); /*msAlpha,msPsd,msPsdFirstMoment,msPsdSecondMoment,msNoiseFloor,msBminSubWin,msBminWin,psize_flt*/ for ( j = start; j < stop; j++ ) { /* Compute variance of PSD */ @@ -425,14 +425,14 @@ void minimum_statistics( msPsdSecondMoment[j] = beta * msPsdSecondMoment[j] + ( 1.f - beta ) * scalar3 * scalar3; /* Compute inverse of amount of degrees of freedom */ QeqInv = min( ( msPsdSecondMoment[j] + DELTA ) / ( 2.f * msNoiseFloor[j] * msNoiseFloor[j] + DELTA ), MSQEQINVMAX_FLT ); - QeqInvAv += QeqInv * psize[j]; + QeqInvAv += QeqInv * psize_flt[j]; /* Compute bias correction Bmin */ - msBminWin[j] = 1.f + scalar * QeqInv / ( 0.5f - msM_win * QeqInv ); - msBminSubWin[j] = 1.f + scalar2 * QeqInv / ( 0.5f - msM_subwin * QeqInv ); + msBminWin[j] = 1.f + scalar * QeqInv / ( 0.5f - msM_win_flt * QeqInv ); + msBminSubWin[j] = 1.f + scalar2 * QeqInv / ( 0.5f - msM_subwin_flt * QeqInv ); } QeqInvAv /= totsize; - hFdCngCom->msQeqInvAv[cnt] = QeqInvAv; + hFdCngCom->msQeqInvAv_flt[cnt] = QeqInvAv; /* New minimum? */ BminCorr = 1.f + MSAV_FLT * (float) sqrt( QeqInvAv ); /*msPsd,msBminWin,msNewMinFlag,msCurrentMin,msCurrentMinSubWindow*/ @@ -458,7 +458,7 @@ void minimum_statistics( i = 0; while ( i < 3 ) { - if ( hFdCngCom->msQeqInvAv[cnt] < msQeqInvAv_thresh[i] ) + if ( hFdCngCom->msQeqInvAv_flt[cnt] < msQeqInvAv_thresh_flt[i] ) { break; } @@ -467,7 +467,7 @@ void minimum_statistics( i++; } } - hFdCngCom->msSlope[cnt] = msNoiseSlopeMax[i]; + hFdCngCom->msSlope_flt[cnt] = msNoiseSlopeMax_flt[i]; } /* Consider the FFT and CLDFB bands separately */ @@ -521,12 +521,12 @@ void minimum_statistics( } /* Take over local minima */ - slope = hFdCngCom->msSlope[0]; /*msLocalMinFlag,msNewMinFlag,msCurrentMinSubWindow,msCurrentMinOut*/ + slope = hFdCngCom->msSlope_flt[0]; /*msLocalMinFlag,msNewMinFlag,msCurrentMinSubWindow,msCurrentMinOut*/ for ( j = 0; j < len; j++ ) { if ( j == lenFFT ) { - slope = hFdCngCom->msSlope[1]; + slope = hFdCngCom->msSlope_flt[1]; } if ( msLocalMinFlag[j] && !msNewMinFlag[j] && msCurrentMinSubWindow[j] < slope * msCurrentMinOut[j] && @@ -552,20 +552,20 @@ void minimum_statistics( } /* Detect sudden offsets based on the FFT bins (core bandwidth) */ - if ( msPsdSum[0] > 50.f * msPeriodogSum[0] ) + if ( msPsdSum_flt[0] > 50.f * msPeriodogSum_flt[0] ) { if ( hFdCngCom->offsetflag > 0 ) { mvr2r( msPeriodog, msPsd, len ); mvr2r( msPeriodog, msCurrentMinOut, len ); - set_f( hFdCngCom->msAlphaCor, 1.0f, cnt ); + set_f( hFdCngCom->msAlphaCor_flt, 1.0f, cnt ); set_f( msAlpha, 0.0f, len ); mvr2r( msPeriodog, msPsdFirstMoment, len ); set_f( msPsdSecondMoment, 0.0f, len ); - msPsdSum[0] = dotp( msPeriodog, psize, lenFFT ); + msPsdSum_flt[0] = dotp( msPeriodog, psize_flt, lenFFT ); if ( lenFFT < len ) { - msPsdSum[1] = dotp( msPeriodog + lenFFT, psize + lenFFT, len - lenFFT ); + msPsdSum_flt[1] = dotp( msPeriodog + lenFFT, psize_flt + lenFFT, len - lenFFT ); } } hFdCngCom->offsetflag = 1; @@ -632,12 +632,12 @@ void minimum_statistics( /*------------------------------------------------------------------- - * apply_scale() + * apply_scale_flt() * * Apply bitrate-dependent scale *-------------------------------------------------------------------*/ -void apply_scale( +void apply_scale_flt( float *scale, /* o : scalefactor */ const int16_t bwidth, /* i : audio bandwidth */ const int32_t brate, /* i : Bit rate */ @@ -666,17 +666,17 @@ void apply_scale( /*------------------------------------------------------------------- - * bandcombinepow() + * bandcombinepow_flt() * * Compute the power for each partition *-------------------------------------------------------------------*/ -void bandcombinepow( +void bandcombinepow_flt( const float *bandpow, /* i : Power for each band */ const int16_t nband, /* i : Number of bands */ int16_t *part, /* i : Partition upper boundaries (band indices starting from 0) */ const int16_t npart, /* i : Number of partitions */ - const float *psize_inv, /* i : Inverse partition sizes */ + const float *psize_inv_flt, /* i : Inverse partition sizes */ float *partpow /* o : Power for each partition */ ) { @@ -690,7 +690,7 @@ void bandcombinepow( else { /* Compute the power in each partition */ - i = 0; /*part,partpow,psize_inv*/ + i = 0; /*part,partpow,psize_inv_flt*/ for ( p = 0; p < npart; p++ ) { /* Arithmetic averaging of power for all bins in partition */ @@ -699,7 +699,7 @@ void bandcombinepow( { temp += bandpow[i]; } - partpow[p] = temp * psize_inv[p]; + partpow[p] = temp * psize_inv_flt[p]; } } @@ -708,12 +708,12 @@ void bandcombinepow( /*------------------------------------------------------------------- - * scalebands() + * scalebands_flt() * * Scale partitions (with smoothing) *-------------------------------------------------------------------*/ -void scalebands( +void scalebands_flt( const float *partpow, /* i : Power for each partition */ int16_t *part, /* i : Partition upper boundaries (band indices starting from 0) */ const int16_t npart, /* i : Number of partitions */ @@ -798,23 +798,23 @@ static void getmidbands( int16_t *part, /* i : Partition upper boundaries (band indices starting from 0) */ const int16_t npart, /* i : Number of partitions */ int16_t *midband, /* o : Central band of each partition */ - float *psize, /* o : Partition sizes */ - float *psize_inv /* o : Inverse of partition sizes */ + float *psize_flt, /* o : Partition sizes */ + float *psize_inv_flt /* o : Inverse of partition sizes */ ) { int16_t j; /* first half partition */ midband[0] = part[0]; - psize[0] = (float) part[0] + 1.f; - psize_inv[0] = normReciprocal[part[0] + 1]; + psize_flt[0] = (float) part[0] + 1.f; + psize_inv_flt[0] = normReciprocal[part[0] + 1]; - /* inner partitions */ /*part,midband,psize_inv*/ + /* inner partitions */ /*part,midband,psize_inv_flt*/ for ( j = 1; j < npart; j++ ) { midband[j] = ( part[j - 1] + 1 + part[j] ) >> 1; - psize[j] = (float) ( part[j] - part[j - 1] ); - psize_inv[j] = normReciprocal[part[j] - part[j - 1]]; + psize_flt[j] = (float) ( part[j] - part[j - 1] ); + psize_inv_flt[j] = normReciprocal[part[j] - part[j - 1]]; } return; @@ -822,19 +822,19 @@ static void getmidbands( /*------------------------------------------------------------------- - * AnalysisSTFT() + * AnalysisSTFT_flt() * * STFT analysis filterbank *-------------------------------------------------------------------*/ -void AnalysisSTFT( +void AnalysisSTFT_flt( const float *timeDomainInput, float *fftBuffer, /* o : FFT bins */ HANDLE_FD_CNG_COM hFdCngCom /* i/o: FD_CNG structure containing all buffers and variables */ ) { - float *olapBuffer = hFdCngCom->olapBufferAna; - const float *olapWin = hFdCngCom->olapWinAna; + float *olapBuffer = hFdCngCom->olapBufferAna_flt; + const float *olapWin = hFdCngCom->olapWinAna_flt; /* Shift and cascade for overlap-add */ mvr2r( olapBuffer + hFdCngCom->frameSize, olapBuffer, hFdCngCom->fftlen - hFdCngCom->frameSize ); @@ -844,19 +844,19 @@ void AnalysisSTFT( v_mult( olapBuffer, olapWin, fftBuffer, hFdCngCom->fftlen ); /* Perform FFT */ - RFFTN( fftBuffer, hFdCngCom->fftSineTab, hFdCngCom->fftlen, -1 ); + RFFTN( fftBuffer, hFdCngCom->fftSineTab_flt, hFdCngCom->fftlen, -1 ); return; } /*------------------------------------------------------------------- - * SynthesisSTFT() + * SynthesisSTFT_flt() * * STFT synthesis filterbank *-------------------------------------------------------------------*/ -void SynthesisSTFT( +void SynthesisSTFT_flt( float *fftBuffer, /* i : FFT bins */ float *timeDomainOutput, float *olapBuffer, @@ -871,7 +871,7 @@ void SynthesisSTFT( float buf[M + 1 + 320], tmp; /* Perform IFFT */ - RFFTN( fftBuffer, hFdCngCom->fftSineTab, hFdCngCom->fftlen, 1 ); + RFFTN( fftBuffer, hFdCngCom->fftSineTab_flt, hFdCngCom->fftlen, 1 ); /* Handle overlap in P/S domain for stereo */ if ( ( element_mode == IVAS_CPE_TD || element_mode == IVAS_CPE_DFT ) && nchan_out == 2 ) @@ -932,19 +932,19 @@ void SynthesisSTFT( tmp = buf[0]; preemph( buf + 1, PREEMPH_FAC_FLT, M + hFdCngCom->frameSize, &tmp ); - residu( hFdCngCom->A_cng, M, buf + 1 + M, hFdCngCom->exc_cng, hFdCngCom->frameSize ); + residu( hFdCngCom->A_cng_flt, M, buf + 1 + M, hFdCngCom->exc_cng_flt, hFdCngCom->frameSize ); return; } /*------------------------------------------------------------------- - * SynthesisSTFT_dirac() + * SynthesisSTFT_dirac_flt() * * STFT synthesis filterbank *-------------------------------------------------------------------*/ -void SynthesisSTFT_dirac( +void SynthesisSTFT_dirac_flt( float *fftBuffer, /* i : FFT bins */ float *timeDomainOutput, float *olapBuffer, @@ -957,7 +957,7 @@ void SynthesisSTFT_dirac( float buf[M + 1 + 320], tmp; /* Perform IFFT */ - RFFTN( fftBuffer, hFdCngCom->fftSineTab, hFdCngCom->fftlen, 1 ); + RFFTN( fftBuffer, hFdCngCom->fftSineTab_flt, hFdCngCom->fftlen, 1 ); /* Handle overlap in P/S domain for stereo */ mvr2r( olapBuffer + hFdCngCom->frameSize, olapBuffer, hFdCngCom->frameSize ); @@ -989,7 +989,7 @@ void SynthesisSTFT_dirac( v_multc( olapBuffer + hFdCngCom->frameSize / 4 - ( M + 1 ), (float) ( hFdCngCom->fftlen / 2 ), buf, M + 1 + hFdCngCom->frameSize ); tmp = buf[0]; preemph( buf + 1, PREEMPH_FAC_FLT, M + hFdCngCom->frameSize, &tmp ); - residu( hFdCngCom->A_cng, M, buf + 1 + M, hFdCngCom->exc_cng, hFdCngCom->frameSize ); + residu( hFdCngCom->A_cng_flt, M, buf + 1 + M, hFdCngCom->exc_cng_flt, hFdCngCom->frameSize ); /* update and window olapBuf if we have a output frame that is shorter than the default frame size...*/ if ( samples_out < hFdCngCom->frameSize ) @@ -1006,12 +1006,12 @@ void SynthesisSTFT_dirac( /*------------------------------------------------------------------- - * mhvals() + * mhvals_flt() * * Compute some values used in the bias correction of the minimum statistics algorithm *-------------------------------------------------------------------*/ -static void mhvals( +static void mhvals_flt( const int16_t d, float *m ) { @@ -1038,26 +1038,26 @@ static void mhvals( } if ( d == d_array[i] ) { - *m = m_array[i]; + *m = m_array_flt[i]; } else { qj = (float) sqrt( (float) d_array[i - 1] ); /*interpolate using sqrt(d)*/ qi = (float) sqrt( (float) d_array[i] ); q = (float) sqrt( (float) d ); - *m = m_array[i] + ( qi * qj / q - qj ) * ( m_array[j] - m_array[i] ) / ( qi - qj ); + *m = m_array_flt[i] + ( qi * qj / q - qj ) * ( m_array_flt[j] - m_array_flt[i] ) / ( qi - qj ); } return; } /*------------------------------------------------------------------- - * rand_gauss() + * rand_gauss_flt() * * Random generator with Gaussian distribution with mean 0 and std 1 *-------------------------------------------------------------------*/ -float rand_gauss( +float rand_gauss_flt( float *x, int16_t *seed ) { @@ -1075,12 +1075,12 @@ float rand_gauss( /*------------------------------------------------------------------- - * lpc_from_spectrum() + * lpc_from_spectrum_flt() * * *-------------------------------------------------------------------*/ -void lpc_from_spectrum( +void lpc_from_spectrum_flt( HANDLE_FD_CNG_COM hFdCngCom, const int16_t start, const int16_t stop, @@ -1090,10 +1090,10 @@ void lpc_from_spectrum( float r[32], nf; float fftBuffer[FFTLEN], *ptr, *pti; - float *powspec = hFdCngCom->cngNoiseLevel; + float *powspec = hFdCngCom->cngNoiseLevel_flt; int16_t fftlen = hFdCngCom->fftlen; - const float *fftSineTab = hFdCngCom->fftSineTab; - float *A = hFdCngCom->A_cng; + const float *fftSineTab = hFdCngCom->fftSineTab_flt; + float *A = hFdCngCom->A_cng_flt; /* Power Spectrum */ ptr = fftBuffer; @@ -1153,12 +1153,12 @@ void lpc_from_spectrum( /*------------------------------------------------------------------- - * FdCng_exc() + * FdCng_exc_flt() * * Generate FD-CNG as LP excitation *-------------------------------------------------------------------*/ -void FdCng_exc( +void FdCng_exc_flt( HANDLE_FD_CNG_COM hFdCngCom, int16_t *CNG_mode, const int16_t L_frame, @@ -1179,7 +1179,7 @@ void FdCng_exc( /*Get excitation */ for ( i = 0; i < L_frame / L_SUBFR; i++ ) { - mvr2r( hFdCngCom->A_cng, Aq + i * ( M + 1 ), M + 1 ); + mvr2r( hFdCngCom->A_cng_flt, Aq + i * ( M + 1 ), M + 1 ); } a2lsp_stab( Aq, lsp_new, lsp_old ); @@ -1204,8 +1204,8 @@ void FdCng_exc( lsp2lsf( lsp_new, lsf_new, M, INT_FS_12k8 ); } - mvr2r( hFdCngCom->exc_cng, exc, L_frame ); - mvr2r( hFdCngCom->exc_cng, exc2, L_frame ); + mvr2r( hFdCngCom->exc_cng_flt, exc, L_frame ); + mvr2r( hFdCngCom->exc_cng_flt, exc2, L_frame ); if ( bwe_exc ) { diff --git a/lib_com/fd_cng_com_fx.c b/lib_com/fd_cng_com_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..630eca54b23f81894cd19438e80bf37bb74c9f4e --- /dev/null +++ b/lib_com/fd_cng_com_fx.c @@ -0,0 +1,1959 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include +#include +#include "options.h" +#include "basop_util.h" +#include "options.h" +#include "rom_basop_util.h" +#include "rom_com.h" +#include "prot_fx1.h" +#include "prot_fx2.h" + +#define DELTA_SHIFT 2 +#define DELTA_SHIFT_LD64 67108864l/*DELTA_SHIFT/64.0 Q31*/ +#define CNG_HS 4 /* 4 bit headroom for dot product */ +#define CNG_S 6 /* 1 sign bit, 6 bit integer part, 9 bit frational part for input and output data */ + + /*------------------------------------------------------------------- + * Local function prototypes + *-------------------------------------------------------------------*/ +static void getmidbands(const Word16* part, const Word16 npart, Word16* midband, Word16* psize, + Word16* psize_norm, Word16* psize_norm_exp, Word16* psize_inv); + + + + /*------------------------------------------------------------------- + * createFdCngCom() + * + * Create an instance of type FD_CNG_COM + *-------------------------------------------------------------------*/ +ivas_error createFdCngCom( + HANDLE_FD_CNG_COM * hFdCngCom /* i/o: FD_CNG structure containing all buffers and variables */ +) +{ + HANDLE_FD_CNG_COM hs; + + /* Allocate memory */ + hs = (HANDLE_FD_CNG_COM)count_malloc(sizeof(FD_CNG_COM)); + + if (hs == NULL) + { + return IVAS_ERROR(IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for FD CNG COM"); + } + + *hFdCngCom = hs; + + return IVAS_ERR_OK; +} +/*------------------------------------------------------------------- + * initFdCngCom() + * + * + *-------------------------------------------------------------------*/ + +void initFdCngCom(HANDLE_FD_CNG_COM hFdCngCom, Word16 scale) +{ + /* Calculate CLDFB scaling factor */ + /* shl(i_mult2(scale, scale), 3) does not fit in 16 bit */ + /*hFdCngCom->scalingFactor = div_s(1, shl(i_mult2(scale, scale), 3));*/ + assert(2048/*1.0/(1<<4) Q15*/ < mult(scale, scale)); + /* Exponent invScalingFactor: -16 = -(2*7 (scale) + 2 (8.0) */ + hFdCngCom->invScalingFactor = shl(mult(scale,scale),1); + /* Exponent scalingFactor: -15 = -(2*7 (scale) + 2 (8.0) - 1 (1.0)) */ + hFdCngCom->scalingFactor = div_s(0x4000,hFdCngCom->invScalingFactor); + + /* Initialize the overlap-add */ + set16_fx( hFdCngCom->timeDomainBuffer, 0, L_FRAME16k ); + hFdCngCom->olapBufferAna = NULL; + move16(); + set16_fx( hFdCngCom->olapBufferSynth, 0, FFTLEN ); + hFdCngCom->olapBufferSynth2 = NULL; + move16(); + + /* Initialize the comfort noise generation */ + set32_fx( hFdCngCom->fftBuffer, 0, FFTLEN ); + set32_fx( hFdCngCom->cngNoiseLevel, 0, FFTCLDFBLEN ); + + /* Initialize quantizer */ + set32_fx( hFdCngCom->sidNoiseEst, 0, NPART ); + set16_fx( hFdCngCom->A_cng, 0, M+1 ); + hFdCngCom->A_cng[0] = 4096/*1.f Q12*/; /* 3Q12 */ move16(); + + /* Set some counters and flags */ + hFdCngCom->inactive_frame_counter = 0; /* Either SID or zero frames */ move16(); + hFdCngCom->active_frame_counter = 0; + move16(); + hFdCngCom->frame_type_previous = ACTIVE_FRAME; + move16(); + hFdCngCom->flag_noisy_speech = 0; + move16(); + hFdCngCom->likelihood_noisy_speech = 0; + move16(); + hFdCngCom->numCoreBands = 0; + move16(); + hFdCngCom->stopBand = 0; + move16(); + hFdCngCom->startBand = 0; + move16(); + hFdCngCom->stopFFTbin = 0; + move16(); + hFdCngCom->frameSize = 0; + move16(); + hFdCngCom->fftlen = 0; + move16(); + hFdCngCom->seed = 0; + move16(); + //hFdCngCom->seed2 = 1; + move16(); + //hFdCngCom->seed3 = 2; + move16(); + hFdCngCom->CngBitrate = -1; + move16(); + + /* Initialize noise estimation algorithm */ + set32_fx( hFdCngCom->periodog, 0, PERIODOGLEN ); + mhvals(MSNUMSUBFR*MSSUBFRLEN, &(hFdCngCom->msM_win)); + mhvals(MSSUBFRLEN, &(hFdCngCom->msM_subwin)); + set32_fx( hFdCngCom->msPeriodogSum, 0, 2 ); + hFdCngCom->msPeriodogSum_exp[0] = 0; + move16(); + hFdCngCom->msPeriodogSum_exp[1] = 0; + move16(); + set32_fx( hFdCngCom->msPsdSum, 0, 2 ); + set16_fx( hFdCngCom->msSlope, 0, 2 ); + set32_fx( hFdCngCom->msQeqInvAv, 0, 2 ); + hFdCngCom->msQeqInvAv_exp[0] = 0; + move16(); + hFdCngCom->msQeqInvAv_exp[1] = 0; + move16(); + hFdCngCom->msFrCnt_init_counter = 0; + move16(); + hFdCngCom->msFrCnt_init_thresh = 1; + move16(); + hFdCngCom->init_old = 0; + move16(); + hFdCngCom->offsetflag = 0; + move16(); + hFdCngCom->msFrCnt = MSSUBFRLEN; + move16(); + hFdCngCom->msMinBufferPtr = 0; + move16(); + hFdCngCom->msAlphaCor[0] = 644245120l/*0.3f Q31*/; + move16(); + hFdCngCom->msAlphaCor[1] = 644245120l/*0.3f Q31*/; + move16(); + + /* Initialize exponents */ + hFdCngCom->exp_cldfb_periodog = 0; + move16(); + + return; +} + +/*------------------------------------------------------------------- + * deleteFdCngCom() + * + * Delete an instance of type FD_CNG_COM + *-------------------------------------------------------------------*/ +void deleteFdCngCom(HANDLE_FD_CNG_COM * hFdCngCom) /* i/o: Contains the variables related to the CLDFB-based CNG process */ +{ + HANDLE_FD_CNG_COM hsCom; + hsCom = *hFdCngCom; + move16(); + IF (hsCom != NULL) + { + count_free(hsCom); + *hFdCngCom = NULL; + move16(); + } +} + +/*------------------------------------------------------------------- + * initPartitions() + * + * Initialize the spectral partitioning + *-------------------------------------------------------------------*/ +void initPartitions( + const Word16* part_in, + const Word16 npart_in, + const Word16 startBand, + const Word16 stopBand, + Word16* part_out, + Word16* npart_out, + Word16* midband, + Word16* psize, + Word16* psize_norm, + Word16* psize_norm_exp, + Word16* psize_inv, + const Word16 stopBandFR +) +{ + Word16 i, j, len_out, tmp16; + + + IF (part_in != NULL) + { + len_out = 0; + move16(); + IF (GT_16(stopBandFR, startBand)) + { + len_out = sub(stopBandFR, startBand); + FOR(i = 0 ; i < len_out; i++) + { + part_out[i] = i; + move16(); + } + } + FOR(j=0 ; j < npart_in; j++) + { + IF (GE_16(part_in[j], stopBand)) + { + BREAK; + } + tmp16 = sub(part_in[j],startBand); + test(); + if (GE_16(part_in[j],stopBandFR)&&tmp16>=0) + { + part_out[len_out++] = tmp16; + move16(); + } + } + } + ELSE + { + len_out = sub(stopBand, startBand); + FOR (i = 0 ; i < len_out; i++) + { + part_out[i] = i; + move16(); + } + } + + *npart_out = len_out; + move16(); + getmidbands(part_out, len_out, midband, psize, psize_norm, psize_norm_exp, psize_inv); + +} + + +/*------------------------------------------------------------------- + * compress_range() + * + * Apply some dynamic range compression based on the log + *-------------------------------------------------------------------*/ +void compress_range( + Word32 *in, + Word16 in_exp, + Word16 *out, + const Word16 len +) +{ + Word16 i; + Word32 in_s; + Word32 one_s; + Word32 in_exp32; + Word32 L_tmp; + + + /* out = log2( 1 + in ) */ + IF ( in_exp >= 0 ) + { + one_s = L_shr(1073741824l/*0.5 Q31*/,in_exp); + in_exp32 = L_shl(L_deposit_l(add(in_exp,1)),WORD32_BITS-1-LD_DATA_SCALE); + FOR (i=0; i < len; i++) + { + in_s = L_add(L_shr(in[i],1),one_s); + L_tmp = L_add(BASOP_Util_Log2(in_s),in_exp32); + if (in_s == 0) + { + out[i] = 0; + move16(); + } + if (in_s != 0) + { + out[i] = extract_h(L_tmp); + } + if(out[i] == 0) + { + out[i] = 1; + } + } + } + ELSE + { + in_exp = sub(in_exp,1); + in_exp32 = L_shl(L_deposit_l(1),WORD32_BITS-1-LD_DATA_SCALE); + FOR (i=0; i < len; i++) + { + L_tmp = L_add(BASOP_Util_Log2(L_add(L_shl(in[i],in_exp),1073741824l/*0.5 Q31*/)),in_exp32); + if (in[i] == 0) + { + out[i] = 0; + move16(); + } + if (in[i] != 0) + { + out[i] = extract_h(L_tmp); + } + if (out[i] == 0) + { + out[i] = 1; + } + } + } + +} + +/*------------------------------------------------------------------- + * expand_range() + * + * Apply some dynamic range expansion to undo the compression + *-------------------------------------------------------------------*/ +void expand_range( + Word16 *in, + Word32 *out, + Word16 *out_exp, + const Word16 len +) +{ + Word16 i; + Word16 s; + Word16 tmp; + Word32 one_s, tmp32; + Word16 maxVal; + Word16 maxVal2; + + + maxVal = 0; + move16(); + FOR (i=0; i < len; i++) + { + maxVal = s_max(maxVal,in[i]); + } + + maxVal2 = maxVal; + move16(); + s = 0; + move16(); + WHILE ( maxVal >= 0 ) + { + maxVal = sub(maxVal,512/*0.015625 Q15*/); + s = add(s,1); + } + tmp = sub(maxVal2,maxVal); + + one_s = L_shr(1073741824l/*0.5 Q31*/,sub(s,1)); + tmp32 = L_shr(726941l/*0.0003385080526823181 Q31*/,s); + /* out = (2^(in) - 1) */ + FOR (i=0; i < len; i++) + { + out[i] = L_sub(BASOP_Util_InvLog2(L_deposit_h(sub(in[i],tmp))),one_s); + move32(); + if ( out[i] == 0 ) + { + out[i] = tmp32; + move32(); + } + } + *out_exp = s; + move16(); + +} + +/*------------------------------------------------------------------- + * minimum_statistics() + * + * Noise estimation using Minimum Statistics (MS) + *-------------------------------------------------------------------*/ + +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 */ + Word16 *msPeriodog, /* i : Periodogram (energies) */ + Word16 *msNoiseFloor, /* i/o: Noise floors (energies) */ + Word16 *msNoiseEst, /* i/o: Noise estimates (energies) */ + Word32 *msAlpha, /* i/o: Forgetting factors */ + Word16 *msPsd, /* i/o: Power Spectral Density (smoothed periodogram => energies) */ + Word16 *msPsdFirstMoment, /* i/o: PSD statistics of 1st order (energy means) */ + Word32 *msPsdSecondMoment, /* i/o: PSD statistics of 2nd order (energy variances) */ + Word32 *msMinBuf, /* i/o: Buffer of minima (energies) */ + Word32 *msBminWin, /* o : Bias correction factors */ + Word32 *msBminSubWin, /* o : Bias correction factors */ + Word32 *msCurrentMin, /* i/o: Local minima (energies) */ + Word32 *msCurrentMinOut, /* i/o: Local minima (energies) */ + Word32 *msCurrentMinSubWindow, /* i/o: Local minima (energies) */ + Word16 *msLocalMinFlag, /* i : Binary flag */ + Word16 *msNewMinFlag, /* i : Binary flag */ + Word16 *msPeriodogBuf, /* i/o: Buffer of periodograms (energies) */ + Word16 *msPeriodogBufPtr, /* i/o: Counter */ + HANDLE_FD_CNG_COM hFdCngCom /* i/o: FD_CNG structure containing all buffers and variables */ +#ifdef IVAS_CODE_CNG + ,const Word16 enc_dec, /* i : encoder/decoder indicator */ + const Word16 element_mode /* i : IVAS element mode type */ +#endif +) +{ + Word16 i,j,k,s,s1,s2,s3; + Word16 len2; + Word16 current_len; + Word16 start, stop, cnt; + Word16 totsize; + Word16 inv_totsize; + + Word32 tmp, tmp0, tmp1; + Word32 scalar, scalar2, scalar3; + Word32 snr; + Word32 msAlphaHatMin2; + Word32 BminCorr; + Word32 QeqInvAv; + Word32 *ptr; + Word32 *msPsdSum; + Word32 *msPeriodogSum; + + Word16 tmp16, tmp16_1; + Word16 beta; + Word16 slope; + Word16 QeqInv; + Word16 scalar16; + Word16 scalar216; + Word16 scalar316; + Word16 msM_win; + Word16 msM_subwin; + Word16 msAlphaCorAlpha; + Word16 msAlphaCorAlpha2; + Word16 msPeriodogSum16; + Word16 msNoiseFloor16; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + + + len2 = i_mult(MSNUMSUBFR,len); + + msM_win = hFdCngCom->msM_win; + move16(); + msM_subwin = hFdCngCom->msM_subwin; + move16(); + + msAlphaCorAlpha = MSALPHACORALPHA; + move16(); + msAlphaCorAlpha2 = MSALPHACORALPHA2; + move16(); + + msPsdSum = hFdCngCom->msPsdSum; + msPeriodogSum = hFdCngCom->msPeriodogSum; + + /* No minimum statistics at initialization */ + IF ( LT_16(hFdCngCom->msFrCnt_init_counter,hFdCngCom->msFrCnt_init_thresh)) + { + Copy(msPeriodog, msPsd, len); /* 6Q9 */ + Copy(msPeriodog, msNoiseFloor, len); /* 6Q9 */ + Copy(msPeriodog, msNoiseEst, len); /* 6Q9 */ + Copy(msPeriodog, msPsdFirstMoment, len); /* 6Q9 */ + + set32_fx(msPsdSecondMoment, 0l/*0.0 Q31*/, len); + msPeriodogSum[0] = dotp_s_fx(msPeriodog, psize, lenFFT, CNG_HS); + move32(); + msPsdSum[0] = msPeriodogSum[0]; /* 16Q15 */ move32(); + + IF ( LT_16(lenFFT,len)) + { + msPeriodogSum[1] = dotp_s_fx(msPeriodog+lenFFT, psize+lenFFT, sub(len,lenFFT), CNG_HS); + move32(); + msPsdSum[1] = msPeriodogSum[1]; /* 16Q15 */ move32(); + } + + /* Increment frame counter at initialization */ + /* Some frames are sometimes zero at initialization => ignore them */ + IF ( LT_16(msPeriodog[0],hFdCngCom->init_old)) + { + set32_fx(msCurrentMinOut, 2147483647l/*1.0 Q31*/, len); /* 16Q15 */ + set32_fx(msCurrentMin, 2147483647l/*1.0 Q31*/, len); /* 16Q15 */ + set32_fx(msMinBuf, 2147483647l/*1.0 Q31*/, len2); /* 16Q15 */ + set32_fx(msCurrentMinSubWindow, 2147483647l/*1.0 Q31*/, len); /* 16Q15 */ + + hFdCngCom->msFrCnt_init_counter = add(hFdCngCom->msFrCnt_init_counter,1); + move16(); + } + hFdCngCom->init_old = msPeriodog[0]; /* 6Q9 */ move16(); + } + ELSE + { + /* Consider the FFT and CLDFB bands separately + - first iteration for FFT bins, + - second one for CLDFB bands in SWB mode */ + cnt = 0; + move16(); + start = 0; + move16(); + stop = lenFFT; + move16(); + totsize = sub(hFdCngCom->stopFFTbin,hFdCngCom->startBand); + WHILE ( GT_16(stop,start)) + { + current_len = sub(stop,start); + + /* Compute smoothed correction factor for PSD smoothing */ + + /* msPeriodogSum[cnt] with format 16Q15 */ + msPeriodogSum[cnt] = dotp_s_fx(msPeriodog+start, psize+start, current_len, CNG_HS); + move32(); + + IF ( msPeriodogSum[cnt] == 0 ) + { + hFdCngCom->msAlphaCor[cnt] = Mpy_32_16_1(hFdCngCom->msAlphaCor[cnt], msAlphaCorAlpha); + move32(); + } + ELSE + { + /* calculate scalar with normalized msPeriodogSum[cnt], exponent -2*s1 */ + s1 = norm_l(msPeriodogSum[cnt]); + msPeriodogSum16 = round_fx(L_shl(msPeriodogSum[cnt],s1)); + scalar = L_mult(msPeriodogSum16, msPeriodogSum16); + + /* calculate difference, both elements in 16Q15 format, use absolute value + to avoid -1.0 x -1.0 multiplications later */ + scalar2 = L_abs(L_sub(msPsdSum[cnt], msPeriodogSum[cnt])); + + s2 = WORD32_BITS-1; + move16(); + if ( scalar2 != 0 ) + { + /* use absolute value to avoid -1.0 x -1.0 multiplications */ + s2 = norm_l(scalar2); + } +#ifdef BASOP_NOGLOB + scalar216 = round_fx_o(L_shl_o(scalar2,s2, &Overflow), &Overflow); +#else + scalar216 = round_fx(L_shl(scalar2,s2)); +#endif + scalar2 = L_mult(scalar216, scalar216); + + /* find common exponent */ + tmp16_1 = sub(s1,s2); + tmp16 = s_min(shl(abs_s(tmp16_1),1),WORD32_BITS-1); + if ( tmp16_1 < 0 ) + { + scalar2 = L_shr(scalar2,tmp16); + } + if(tmp16_1 > 0) + { + scalar = L_shr(scalar,tmp16); + } + + + /* add scalar and scalar2, avoid overflows */ + scalar = L_shr(scalar,1); + scalar2 = L_shr(scalar2,1); + scalar3 = L_add(scalar,scalar2); + + /* calculate division */ + scalar16 = BASOP_Util_Divide3232_uu_1616_Scale(scalar, scalar3, &s3); + s3 = s_max(s3,-(WORD16_BITS-1)); + scalar16 = shl(scalar16,s3); + scalar16 = s_max(scalar16, MSALPHACORMAX); + + hFdCngCom->msAlphaCor[cnt] = L_add(Mpy_32_16_1(hFdCngCom->msAlphaCor[cnt], msAlphaCorAlpha), + L_mult(scalar16, msAlphaCorAlpha2)); + move32(); + } + + /* Compute SNR */ + + /* msPeriodogSum[cnt] with format 16Q15 */ + snr = dotp_s_fx(msNoiseFloor+start, psize+start, current_len, CNG_HS); + + IF ( GT_32(L_shr(Mpy_32_16_1(msPsdSum[cnt],18431/*0.56246299817 Q15*/),13),snr)) + { + tmp0 = BASOP_Util_Log2(msPsdSum[cnt]); + tmp1 = BASOP_Util_Log2(snr); + tmp1 = L_sub(tmp0, tmp1); + tmp1 = Mpy_32_16_1(tmp1, MSSNREXP); + msAlphaHatMin2 = BASOP_Util_InvLog2(tmp1); + } + ELSE + { + msAlphaHatMin2 = MSALPHAHATMIN; + move32(); + } + scalar = Mpy_32_16_1(hFdCngCom->msAlphaCor[cnt], MSALPHAMAX); + + FOR (j=start; j 0) + { + scalar2 = L_shr(scalar2,tmp16); + } + + /* add scalar2 and scalar3, avoid overflows */ + scalar2 = L_shr(scalar2,1); + scalar3 = L_shr(scalar3,1); + scalar3 = L_add(scalar2,scalar3); + + /* calculate division */ + tmp16 = BASOP_Util_Divide3232_uu_1616_Scale(scalar2, scalar3, &s3); + scalar2 = Mpy_32_16_1(scalar, tmp16); + s3 = s_max(s3,-(WORD32_BITS-1)); + scalar2 = L_shl(scalar2,s3); + msAlpha[j] = L_max(scalar2, msAlphaHatMin2); + move32(); + } + + /* Compute the PSD (smoothed periodogram) in each band */ + msPsd[j] = round_fx(L_add(Mpy_32_16_1(msAlpha[j], msPsd[j]), + Mpy_32_16_1(L_sub(2147483647l/*1.0 Q31*/,msAlpha[j]), msPeriodog[j]))); + } + msPsdSum[cnt] = dotp_s_fx(msPsd+start, psize+start, current_len, CNG_HS); + move32(); + + QeqInvAv = 0l/*0.0 Q31*/; + move32(); + + /* scalar: 7Q24 format */ + tmp = 1191182336l/*(float)(MSNUMSUBFR*MSSUBFRLEN)-1.0 Q24*/; + move32(); + scalar = L_sub(tmp, L_mult(round_fx(tmp), msM_win)); + + /* scalar2: 4Q27 format */ + tmp = 1476395008l/*(float)MSSUBFRLEN-1.0 Q27*/; + move32(); + scalar2 = L_sub(tmp, L_mult(round_fx(tmp), msM_subwin)); + + FOR (j=start; jmsQeqInvAv[cnt] = QeqInvAv; + move32(); + + /* New minimum? */ + + /* exponent QeqInvAv: CNG_S, exponent MSAV: (4>>1) */ + s = CNG_S+2*MSAV_EXP; + move16(); + BminCorr = Mpy_32_16_1(Sqrt32(QeqInvAv, &s), MSAV); + BminCorr = L_shl(BminCorr,sub(s,1)); + + /* exponent BminCorr: 1 */ + BminCorr = L_add(BminCorr, 1073741824l/*0.5 Q31*/); + + FOR (j=start; jmsFrCnt,MSSUBFRLEN)) + { + FOR ( i = 0; i < 3; i++ ) + { + IF ( LT_32(hFdCngCom->msQeqInvAv[cnt],L_shr(L_deposit_h(msQeqInvAv_thresh[i]),CNG_S))/*0.0 Q31*/) + { + BREAK; + } + } + /* format 1Q30 */ + hFdCngCom->msSlope[cnt] = msNoiseSlopeMax[i]; + move32(); + } + + /* Consider the FFT and CLDFB bands separately */ + start = stop; + move16(); + stop = len; + move16(); + totsize = sub(hFdCngCom->stopBand,hFdCngCom->stopFFTbin); + cnt = add(cnt,1); + } /*while (stop > start)*/ + + /* Update minimum between sub windows */ + test(); + IF ( GT_16(hFdCngCom->msFrCnt,1)&<_16(hFdCngCom->msFrCnt,MSSUBFRLEN)) + { + FOR (j=0; j 0 ) + { + msLocalMinFlag[j] = 1; + move16(); + } + if ( LT_32(msCurrentMinSubWindow[j],msCurrentMinOut[j])/*0.0 Q31*/) + { + /* msCurrentMinOut[j] scaled with CNG_S */ + msCurrentMinOut[j] = msCurrentMinSubWindow[j]; + move32(); + } + } + /* Get the current noise floor */ + Copy_Scale_sig_32_16(msCurrentMinOut, msNoiseFloor, len, -16); + } + ELSE /* sub window complete */ + { + IF ( GE_16(hFdCngCom->msFrCnt,MSSUBFRLEN)) + { + /* Collect buffers */ + Copy32(msCurrentMinSubWindow, msMinBuf+len*hFdCngCom->msMinBufferPtr, len); + + /* Compute minimum among all buffers */ + Copy32(msMinBuf, msCurrentMinOut, len); + ptr = msMinBuf + len; + FOR (i=1; imsSlope[0]; + move16(); + FOR (j=0; jmsSlope[1]; + move16(); + } + test(); + test(); + test(); + IF ( ( msLocalMinFlag[j] != 0 ) + && ( msNewMinFlag[j] == 0 ) + && ( LT_32(L_shr(msCurrentMinSubWindow[j],1),Mpy_32_16_1(msCurrentMinOut[j],slope)) /*0.0 Q31*/ ) + && ( GT_32(msCurrentMinSubWindow[j],msCurrentMinOut[j]) /*0.0 Q31*/ ) + ) + { + msCurrentMinOut[j] = msCurrentMinSubWindow[j]; + move32(); + i = j; + move16(); + FOR (k=0; koffsetflag > 0 ) + { + Copy(msPeriodog, msPsd, len); + FOR (j=0; j < len; j++) + { + msCurrentMinOut[j] = L_deposit_h(msPeriodog[j]); + } + set32_fx(hFdCngCom->msAlphaCor, 2147483647l/*1.0 Q31*/, cnt); + set32_fx(msAlpha, 0l/*0.0 Q31*/, len); + Copy(msPeriodog, msPsdFirstMoment, len); + set32_fx(msPsdSecondMoment, 0l/*0.0 Q31*/, len); + + msPsdSum[0] = dotp_s_fx(msPeriodog, psize, lenFFT, CNG_HS); + move32(); + IF ( LT_16(lenFFT,len)) + { + msPsdSum[1] = dotp_s_fx(msPeriodog+lenFFT, psize+lenFFT, sub(len,lenFFT), CNG_HS); + move32(); + } + } + hFdCngCom->offsetflag = 1; + move16(); + } + ELSE + { + hFdCngCom->offsetflag = 0; + move16(); + } + + + /* Increment frame counter */ + IF ( EQ_16(hFdCngCom->msFrCnt,MSSUBFRLEN)) + { + hFdCngCom->msFrCnt = 1; + move16(); + hFdCngCom->msMinBufferPtr = add(hFdCngCom->msMinBufferPtr,1); + move16(); + if ( EQ_16(hFdCngCom->msMinBufferPtr,MSNUMSUBFR)) + { + hFdCngCom->msMinBufferPtr = 0; + move16(); + } + } + ELSE + { + hFdCngCom->msFrCnt = add(hFdCngCom->msFrCnt,1); + } + + /* Smooth noise estimate during CNG phases */ + FOR (j=0; j= 0/*0.0 Q15*/); + } + +} + +/*------------------------------------------------------------------- + * apply_scale() + * + * Apply bitrate-dependent scale + *-------------------------------------------------------------------*/ +void apply_scale( + Word32 *scale, /* o : scalefactor */ + const Word16 bwmode, /* i : audio bandwidth */ + const Word32 bitrate, /* i : Bit rate */ + const SCALE_SETUP* scaleTable, /* i : Scale table */ + const Word16 scaleTableSize /* i : Size of scale table */ +) +{ + Word16 i; +//PMT("Verifiy if the basop ued are ok for stereo too") + FOR (i=0; i < scaleTableSize; i++) + { + cast16(); + IF ( s_and( (Word16)EQ_16(bwmode, (Word16)scaleTable[i].bwmode), + s_and( L_sub(bitrate,scaleTable[i].bitrateFrom) >= 0, + L_sub(bitrate,scaleTable[i].bitrateTo) < 0)) + ) + { + BREAK; + } + } + + { + *scale = L_add(*scale, L_deposit_h(scaleTable[i].scale)); + } + +} + +/*------------------------------------------------------------------- + * bandcombinepow() + * + * Compute the power for each partition + *-------------------------------------------------------------------*/ +void bandcombinepow( + const Word32* bandpow, /* i : Power for each band */ + const Word16 exp_bandpow, /* i : exponent of bandpow */ + const Word16 nband, /* i : Number of bands */ + Word16* part, /* i : Partition upper boundaries (band indices starting from 0) */ + const Word16 npart, /* i : Number of partitions */ + const Word16* psize_inv, /* i : Inverse partition sizes */ + Word32* partpow, /* o : Power for each partition */ + Word16* exp_partpow +) +{ + + Word16 i, p; + Word32 temp; + Word16 smin, len, prev_part; + Word16 facTabExp[NPART_SHAPING]; + + + + IF (EQ_16(nband, npart)) + { + Copy32(bandpow, partpow, nband); + smin = 0; + move16(); + } + ELSE + { + /* Compute the power in each partition */ + prev_part = -1; + move16(); + FOR (p=0; p < npart; p++) + { + len = sub(part[p],prev_part); + facTabExp[p] = getScaleFactor32 (&bandpow[prev_part+1], len); + move16(); + prev_part = part[p]; + move16(); + } + + smin = WORD32_BITS-1; + move16(); + FOR (p=0; p < npart; p++) + { + smin = s_min(smin,facTabExp[p]); + } + + i = 0; + move16(); + FOR (p = 0; p < npart; p++) + { + /* Arithmetic averaging of power for all bins in partition */ + temp = 0; + move32(); + FOR ( ; i <= part[p]; i++) + { + temp = L_add(temp, Mpy_32_16_1(L_shl(bandpow[i],facTabExp[p]),psize_inv[p])); + } + partpow[p] = L_shr(temp,sub(facTabExp[p],smin)); + move32(); + } + + } + + *exp_partpow = sub(exp_bandpow,smin); + move16(); +} + +/*------------------------------------------------------------------- + * scalebands() + * + * Scale partitions (with smoothing) + *-------------------------------------------------------------------*/ +void scalebands ( + const Word32 *partpow, /* i : Power for each partition */ + Word16 *part, /* i : Partition upper boundaries (band indices starting from 0) */ + const Word16 npart, /* i : Number of partitions */ + Word16 *midband, /* i : Central band of each partition */ + const Word16 nFFTpart, /* i : Number of FFT partitions */ + const Word16 nband, /* i : Number of bands */ + Word32 *bandpow, /* o : Power for each band */ + const Word16 flag_fft_en +) +{ + Word16 i, j, s, s1, nint, delta, delta_cmp, delta_s; + Word16 startBand, startPart, stopPart, stopPartM1; + Word32 tmp, val, partpowLD64, partpowLD64M1; + + + + j = 0; + move16(); + delta = 0; + move16(); + partpowLD64M1 = 0L; /* to avoid compilation warnings */ + + /* Interpolate the bin/band-wise levels from the partition levels */ + IF ( EQ_16(nband, npart)) + { + Copy32(partpow, bandpow, npart); + } + ELSE + { + startBand = 0; + move16(); + startPart = 0; + move16(); + stopPart = nFFTpart; + move16(); + + WHILE ( LT_16(startBand,nband)) + { + stopPartM1 = sub(stopPart, 1); + test(); + IF ( (flag_fft_en != 0) || (GE_16(startPart,nFFTpart))) + { + /* first half partition */ + j = startPart; + move16(); + + FOR (i=startBand; i <= midband[j]; i++) + { + bandpow[i] = partpow[j]; + move32(); + } + j = add(j, 1); + + /* inner partitions */ + IF (j < stopPart) + { + partpowLD64M1 = BASOP_Util_Log2(partpow[j-1]); + } + + /* Debug values to check this variable is set. */ + delta = 0x4000; + move16(); + delta_cmp = 0x4000; + move16(); + s1 = 1; + move16(); + s = 1; + move16(); + + FOR ( ; j < stopPart; j++) + { + nint = sub(midband[j], midband[j-1]); + + /* log-linear interpolation */ + partpowLD64 = BASOP_Util_Log2(partpow[j]); + tmp = L_sub(partpowLD64, partpowLD64M1); + tmp = Mpy_32_16_1(tmp, getNormReciprocalWord16(nint)); + + /* scale logarithmic value */ + tmp = L_sub(tmp, DELTA_SHIFT_LD64); + delta_s = DELTA_SHIFT; + move16(); + + WHILE (tmp > 0) + { + tmp = L_sub(tmp,33554432l/*0.015625 Q31*/); + delta_s = add(delta_s,1); + } + delta_cmp = shl(1, s_max(-15, sub(WORD16_BITS-1,delta_s))); + + tmp = BASOP_Util_InvLog2(tmp); + s = norm_l(tmp); + s1 = sub(delta_s, s); + +#ifdef BASOP_NOGLOB + delta = round_fx_sat(L_shl_sat(tmp, s)); +#else + delta = round_fx(L_shl(tmp, s)); +#endif + /* Choose scale such that the interpolation start and end point both are representable and add 1 additional bit hr. */ + delta_s = sub(s_min(norm_l(partpow[j-1]), norm_l(partpow[j])), 1); + val = L_shl(partpow[j-1], delta_s); + FOR ( ; i < midband[j]; i++) + { + val = L_shl(Mpy_32_16_1(val, delta), s1); + bandpow[i] = L_shr(val, delta_s); + move32(); + } + bandpow[i++] = partpow[j]; + move32(); + partpowLD64M1 = partpowLD64; + move32(); + } + + IF ( GT_16(shr(delta, s), delta_cmp)) + { + delta = 0x4000; + move16(); + s1 = 1; + move16(); + } + + /* last half partition */ + val = partpow[stopPartM1]; + move32(); + FOR ( ; i <= part[stopPartM1]; i++) + { + val = L_shl(Mpy_32_16_1(val,delta), s1); + bandpow[i] = val; + move32(); + } + + } + startBand = add(part[stopPartM1], 1); + startPart = stopPart; + move16(); + stopPart = npart; + move16(); + } + } + +} + +/*------------------------------------------------------------------- + * getmidbands() + * + * Get central band for each partition + *-------------------------------------------------------------------*/ +static void getmidbands( + const Word16* part, /* i : Partition upper boundaries (band indices starting from 0) */ + const Word16 npart, /* i : Number of partitions */ + Word16* midband, /* o : Central band of each partition */ + Word16* psize, /* o : Partition sizes */ + Word16* psize_norm, /* o : Partition sizes, fractional values */ + Word16* psize_norm_exp, /* o : Exponent for fractional partition sizes */ + Word16* psize_inv /* o : Inverse of partition sizes */ +) +{ + Word16 j, max_psize, shift; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + + + max_psize = psize[0]; + move16(); + /* first half partition */ move16(); + midband[0] = part[0]; + psize[0] = add(part[0], 1); + move16(); + psize_inv[0] = getNormReciprocalWord16(psize[0]); + move16(); + /* inner partitions */ + FOR (j = 1; j < npart; j++) + { + midband[j] = shr(add(add(part[j-1], 1), part[j]), 1); + move16(); + psize[j] = sub(part[j], part[j-1]); + move16(); + psize_inv[j] = getNormReciprocalWord16(psize[j]); + move16(); + if(GT_16(psize[j], max_psize)) + { + max_psize = psize[j]; + move16(); + } + } + + shift = 9; + move16(); + *psize_norm_exp = sub(15, shift); + move16(); + FOR(j=0; j < npart; j++) + { +#ifdef BASOP_NOGLOB + psize_norm[j] = shl_o(psize[j], shift, &Overflow); +#else /* BASOP_NOGLOB */ + psize_norm[j] = shl(psize[j], shift); +#endif + move16(); + } + /* minimum_statistics needs fixed exponent of 6 */ + assert(norm_s(-max_psize) >= 9 ); +} + +/*------------------------------------------------------------------- + * AnalysisSTFT() + * + * STFT analysis filterbank + *-------------------------------------------------------------------*/ + +void AnalysisSTFT ( + const Word16 *timeDomainInput, /* i : pointer to time signal */ + Word16 Q, + Word32 *fftBuffer, /* o : FFT bins */ + Word16 *fftBuffer_exp, /* i : exponent of FFT bins */ + HANDLE_FD_CNG_COM hFdCngCom /* i/o: FD_CNG structure containing all buffers and variables */ +) +{ + Word16 i, len; + Word16 len2; + const PWord16 *olapWin; + Word16 *olapBuffer; + + + + assert( (hFdCngCom->fftlen>>1) == hFdCngCom->frameSize); + + /* pointer inititialization */ + assert(hFdCngCom->olapBufferAna != NULL); + olapBuffer = hFdCngCom->olapBufferAna; + olapWin = hFdCngCom->olapWinAna; + + /* olapWin factor is scaled with one bit */ + *fftBuffer_exp = 1; + move16(); + len = sub(hFdCngCom->fftlen,hFdCngCom->frameSize); + assert(len <= 320); /* see size of olapBuffer */ + + /* Window the signal */ + len2 = shr(len,1); + FOR (i=0; i < len2; i++) + { + move32(); + move32(); + fftBuffer[i] = L_mult(olapBuffer[i], mult_r(olapWin[i].v.im, 23170/*1.4142135623730950488016887242097 Q14*/)); + fftBuffer[i+len2] = L_mult(olapBuffer[i+len2], mult_r(olapWin[len2-1-i].v.re, 23170/*1.4142135623730950488016887242097 Q14*/)); + } + len2 = shr(hFdCngCom->frameSize,1); + FOR (i=0; i fftlen, fftBuffer_exp, -1); + + FOR (i=0; i frameSize,len)+i], Q ); + move16(); + } + +} + + +/*------------------------------------------------------------------- + * SynthesisSTFT() + * + * STFT synthesis filterbank + *-------------------------------------------------------------------*/ + +void SynthesisSTFT ( + Word32 *fftBuffer, /* i : pointer to FFT bins */ + Word16 fftBufferExp, /* i : exponent of FFT bins */ + Word16 *timeDomainOutput, /* o : pointer to time domain signal */ + Word16 *olapBuffer, /* i/o : pointer to overlap buffer */ + const PWord16 *olapWin, /* i : pointer to overlap window */ + Word16 tcx_transition, + HANDLE_FD_CNG_COM hFdCngCom, /* i/o : pointer to FD_CNG structure containing all buffers and variables */ + Word16 gen_exc, + Word16 *Q_new, + const Word16 element_mode, /* i : element mode */ + const Word16 nchan_out /* i : number of output channels */ +) +{ + Word16 i, len, scale, tmp; + Word16 len2, len3, len4; + Word16 buf[M+1+L_FRAME16k]; + + + /* Perform IFFT */ + scale = 0; + BASOP_rfft(fftBuffer, hFdCngCom->fftlen, &scale, 1); + fftBufferExp = add(fftBufferExp, scale); + fftBufferExp = add(fftBufferExp, hFdCngCom->fftlenShift); + + /* Perform overlap-add */ + /* Handle overlap in P/S domain for stereo */ + IF ((EQ_16(element_mode, IVAS_CPE_TD) || EQ_16(element_mode, IVAS_CPE_DFT)) && EQ_16(nchan_out, 2) ) + { + Copy(olapBuffer + 3 * hFdCngCom->frameSize / 4 - (M + 1), buf, hFdCngCom->frameSize + M + 1); + set16_fx(olapBuffer, 0, hFdCngCom->fftlen); + } + ELSE + { + Copy(olapBuffer + hFdCngCom->frameSize, olapBuffer, hFdCngCom->frameSize); + set16_fx(olapBuffer + hFdCngCom->frameSize, 0, hFdCngCom->frameSize); + } + len2 = shr(hFdCngCom->fftlen,2); + len4 = shr(hFdCngCom->fftlen,3); + len3 = add(len2,len4); + len = add(hFdCngCom->frameSize,len4); + IF ( tcx_transition ) + { + FOR (i=0; i < len; i++) + { + olapBuffer[i] = round_fx(L_shl(fftBuffer[i],fftBufferExp-15)); + } + } + ELSE + { + FOR (i=0; i < len4; i++) + { + olapBuffer[i+1*len4] = add(olapBuffer[i+1*len4], mult_r(round_fx(L_shl(fftBuffer[i+1*len4],fftBufferExp-15)),olapWin[i].v.im)); + move16(); + olapBuffer[i+2*len4] = add(olapBuffer[i+2*len4], mult_r(round_fx(L_shl(fftBuffer[i+2*len4],fftBufferExp-15)),olapWin[len4-1-i].v.re)); + move16(); + } + FOR (i=len3; i < len; i++) + { + olapBuffer[i] = round_fx(L_shl(fftBuffer[i],fftBufferExp-15)); + } + } + + FOR (i=0; i < len4; i++) + { + olapBuffer[i+5*len4] = mult_r(round_fx(L_shl(fftBuffer[i+5*len4],fftBufferExp-15)),olapWin[i].v.re); + move16(); + olapBuffer[i+6*len4] = mult_r(round_fx(L_shl(fftBuffer[i+6*len4],fftBufferExp-15)),olapWin[len4-1-i].v.im); + move16(); + } + + len = add( len, len2 ); + FOR (i=len; i < hFdCngCom->fftlen ; i++) + { + olapBuffer[i] = 0; + move16(); + } + + /* Get time-domain signal */ + FOR (i=0; i < hFdCngCom->frameSize; i++) + { + timeDomainOutput[i] = mult_r( olapBuffer[i+len4], hFdCngCom->fftlenFac ); + move16(); + } + /* Generate excitation */ +#ifdef IVAS_CODE_CNG_COM + PME() + if ((element_mode == IVAS_CPE_TD || element_mode == IVAS_CPE_DFT) && nchan_out == 2) + { + for (i = 0; i < hFdCngCom->frameSize / 2; i++) + { + buf[i + (M + 1)] += olapBuffer[i + hFdCngCom->frameSize / 4]; + } + v_multc(buf, (float)(hFdCngCom->fftlen / 2), buf, M + 1 + hFdCngCom->frameSize); + } + else +#endif + { + FOR(i = 0; i < M + 1 + hFdCngCom->frameSize; i++) + { + buf[i] = mult_r(olapBuffer[i + len4 - M - 1], hFdCngCom->fftlenFac); + move16(); + } + tmp = buf[0]; + } + IF ( EQ_16( gen_exc, 1 )) + { + + E_UTIL_f_preemph2( *Q_new-1, buf+1, PREEMPH_FAC, M+hFdCngCom->frameSize, &tmp ); + Residu3_fx( hFdCngCom->A_cng, buf+1+M, hFdCngCom->exc_cng, hFdCngCom->frameSize, 1 ); + } + IF ( EQ_16( gen_exc, 2 )) + { + *Q_new = E_UTIL_f_preemph3( buf+1, PREEMPH_FAC, M+hFdCngCom->frameSize, &tmp, 1 ); + Residu3_fx( hFdCngCom->A_cng, buf+1+M, hFdCngCom->exc_cng, hFdCngCom->frameSize, 1 ); + } + +} +#ifdef IVAS_CODE_CNG_COM +/*------------------------------------------------------------------- + * SynthesisSTFT_dirac() + * + * STFT synthesis filterbank + *-------------------------------------------------------------------*/ + +void SynthesisSTFT_dirac( + float* fftBuffer, /* i : FFT bins */ + float* timeDomainOutput, + float* olapBuffer, + const float* olapWin, + const int16_t samples_out, + HANDLE_FD_CNG_COM hFdCngCom /* i/o: FD_CNG structure containing all buffers and variables */ +) +{ + int16_t i; + float buf[M + 1 + 320], tmp; + + /* Perform IFFT */ + RFFTN(fftBuffer, hFdCngCom->fftSineTab, hFdCngCom->fftlen, 1); + + /* Handle overlap in P/S domain for stereo */ + mvr2r(olapBuffer + hFdCngCom->frameSize, olapBuffer, hFdCngCom->frameSize); + set_f(olapBuffer + hFdCngCom->frameSize, 0.0f, hFdCngCom->frameSize); /*olapBuffer, fftBuffer, olapWin*/ + + for (i = hFdCngCom->frameSize / 4; i < 3 * hFdCngCom->frameSize / 4; i++) + { + olapBuffer[i] += fftBuffer[i] * olapWin[i - hFdCngCom->frameSize / 4]; + } + for (; i < 5 * hFdCngCom->frameSize / 4; i++) + { + olapBuffer[i] = fftBuffer[i]; + } + + for (; i < 7 * hFdCngCom->frameSize / 4; i++) + { + olapBuffer[i] = fftBuffer[i]; + } + + for (; i < hFdCngCom->fftlen; i++) + { + olapBuffer[i] = 0; + } + + /* Get time-domain signal */ + v_multc(olapBuffer + hFdCngCom->frameSize / 4, (float)(hFdCngCom->fftlen / 2), timeDomainOutput, samples_out); + + /* Get excitation */ + v_multc(olapBuffer + hFdCngCom->frameSize / 4 - (M + 1), (float)(hFdCngCom->fftlen / 2), buf, M + 1 + hFdCngCom->frameSize); + tmp = buf[0]; + preemph(buf + 1, PREEMPH_FAC, M + hFdCngCom->frameSize, &tmp); + residu(hFdCngCom->A_cng, M, buf + 1 + M, hFdCngCom->exc_cng, hFdCngCom->frameSize); + + /* update and window olapBuf if we have a output frame that is shorter than the default frame size...*/ + if (samples_out < hFdCngCom->frameSize) + { + mvr2r(olapBuffer + samples_out, olapBuffer + hFdCngCom->frameSize, 3 * hFdCngCom->frameSize / 4); + } + for (i = 5 * hFdCngCom->frameSize / 4; i < 7 * hFdCngCom->frameSize / 4; i++) + { + olapBuffer[i] *= olapWin[i - 3 * hFdCngCom->frameSize / 4]; + } + + return; +} +#endif + +/************************************************************************************** +* Compute some values used in the bias correction of the minimum statistics algorithm * +**************************************************************************************/ +void mhvals( + const Word16 d, + Word16 * m /*, float * h*/ +) +{ + Word16 i, j; + Word16 len = SIZE_SCALE_TABLE_CN; + move16(); + + + assert( d==72 || d==12); /* function only tested for d==72 and d==12) */ + i = 0; + move16(); + FOR (i=0 ; i < len ; i++) + { + IF (LE_16(d,d_array[i])) + { + BREAK; + } + } + IF (EQ_16(i, len)) + { + i = sub(len, 1); + j = i; + move16(); + } + ELSE + { + j = sub(i, 1); + } + IF (EQ_16(d, d_array[i])) + { + *m = m_array[i]; + move16(); + } + ELSE + { + Word32 qi_m, qj_m, q_m, tmp1_m, tmp2_m; + Word16 qi_e, qj_e, q_e, tmp1_e, tmp2_e, tmp1_w16_m, tmp1_w16_e, shift; + + + /* d_array has exponent 15 */ + qj_e = 15; + move16(); + qj_m = L_deposit_h(d_array[i-1]); + + qi_e = 15; + move16(); + qi_m = L_deposit_h(d_array[i]); + + q_e = 15; + move16(); + q_m = L_deposit_h(d); + + qj_m = Sqrt32(qj_m, &qj_e); + qi_m = Sqrt32(qi_m, &qi_e); + q_m = Sqrt32(q_m, &q_e); + + tmp1_m = Mpy_32_32(qi_m, qj_m); + tmp1_e = add(qi_e, qj_e); + tmp1_m = L_deposit_h(BASOP_Util_Divide3232_Scale(tmp1_m, q_m, &shift)); + tmp1_e = sub(tmp1_e, q_e); + tmp1_e = add(tmp1_e, shift); + tmp1_m = BASOP_Util_Add_Mant32Exp(tmp1_m, tmp1_e, L_negate(qj_m), qj_e, &tmp1_e); + + tmp2_m = BASOP_Util_Add_Mant32Exp (qi_m, qi_e, L_negate(qj_m), qj_e, &tmp2_e); + tmp1_w16_m = round_fx(tmp2_m); + tmp1_w16_e = tmp2_e; + move16(); + BASOP_Util_Divide_MantExp(sub(m_array[j], m_array[i]), 0, tmp1_w16_m, tmp1_w16_e, &tmp1_w16_m, &tmp1_w16_e); + + tmp2_m = Mpy_32_16_1(tmp1_m, tmp1_w16_m); + tmp2_e = add(tmp1_e, tmp1_w16_e); + + tmp2_m = BASOP_Util_Add_Mant32Exp (tmp2_m, tmp2_e, L_deposit_h(m_array[i]), 0, &tmp2_e); + assert(tmp2_e == 0); + *m = extract_h(tmp2_m); + } +} + +/*------------------------------------------------------------------- + * rand_gauss() + * + * Random generator with Gaussian distribution with mean 0 and std 1 + * Returns: + * random signal format Q3.29 + *-------------------------------------------------------------------*/ +Word32 rand_gauss (Word16 *seed) +{ + Word32 temp; + Word16 loc_seed; + + /* This unrolled version reduces the cycles from 17 to 10 */ + loc_seed = extract_l(L_mac0(13849, *seed, 31821)); + temp = L_deposit_l(loc_seed); + + loc_seed = extract_l(L_mac0(13849, loc_seed, 31821)); + temp = L_msu0(temp,loc_seed,-1); + + loc_seed = extract_l(L_mac0(13849, loc_seed, 31821)); + temp = L_msu0(temp,loc_seed,-1); + + *seed = loc_seed; + move16(); + return L_shl(temp,WORD16_BITS-CNG_RAND_GAUSS_SHIFT); +} + +/*------------------------------------------------------------------- + * lpc_from_spectrum() + * + * + *-------------------------------------------------------------------*/ + +void lpc_from_spectrum ( + HANDLE_FD_CNG_COM hFdCngCom, + const Word16 start, /*i : start band*/ + const Word16 stop, /*i : stop band*/ + const Word16 preemph_fac /*i : preemphase factor format Q1.15*/ +) +{ + Word16 i, s1, s2, s3, fftlen2, scale, fftlen4, fftlen8, len, step, preemph_fac2; + Word32 maxVal, r[32], fftBuffer[FFTLEN], *ptr, *pti, nf; + Word16 tmp, r_h[32], r_l[32]; + const PWord16 *table; + + Word32* powspec = hFdCngCom->cngNoiseLevel; /*i : pointer to noise levels format Q5.27*/ + Word16 powspec_exp = hFdCngCom->cngNoiseLevelExp; + Word16 fftlen = hFdCngCom->fftlen; /*i : size of fft*/ + Word16*A = hFdCngCom->A_cng; /*o : lpc coefficients format Q3.12*/ + Word16 lpcorder = M; + + scale = 0; + move16(); + fftlen2 = shr(fftlen,1); + fftlen4 = shr(fftlen,2); + fftlen8 = shr(fftlen,3); + + /* Power Spectrum */ + maxVal = 0; + move32(); + len = sub(stop, start); + FOR (i=0; i < len; i++) + { + maxVal = L_max(maxVal, L_abs(powspec[i])); + } + s1 = norm_l(maxVal); +#ifdef BASOP_NOGLOB + nf = L_shr_r_sat(1099511680l/*1e-3f Q40*/,add(sub(powspec_exp,s1),9)); +#else + nf = L_shr_r(1099511680l/*1e-3f Q40*/,add(sub(powspec_exp,s1),9)); +#endif + ptr = fftBuffer; + pti = fftBuffer+1; + + FOR (i=0; i < start; i++) + { + *ptr = nf; + move32(); + *pti = L_deposit_l(0); + ptr += 2; + pti += 2; + } + + FOR ( ; i < stop; i++ ) + { + *ptr = L_max( nf, L_shl(powspec[i-start], s1) ); + move32(); + *pti = L_deposit_l(0); + ptr += 2; + pti += 2; + } + + FOR ( ; i < fftlen2; i++ ) + { + *ptr = nf; + move32(); + *pti = L_deposit_l(0); + ptr += 2; + pti += 2; + } + + fftBuffer[1] = nf; + move32(); + + /* Pre-emphasis */ + + BASOP_getTables(&table, NULL, &step, fftlen4); + tmp = round_fx(L_shr(L_add(0x40000000, L_mult0(preemph_fac, preemph_fac)),1)); + preemph_fac2 = shr(preemph_fac,1); + ptr = fftBuffer; + *ptr = Mpy_32_16_1( *ptr, sub( tmp, preemph_fac2 ) ); + move32(); + ptr += 2; + FOR ( i = 1; i < fftlen8; i++ ) + { + move32(); + *ptr = Mpy_32_16_1( *ptr, sub( tmp, mult_r(preemph_fac2,add(shr(table[i-1].v.re,1),shr(table[i].v.re,1)) ) ) ); + ptr += 2; + } + move32(); + *ptr = Mpy_32_16_1( *ptr, sub( tmp, mult_r(preemph_fac2,add(shr(table[fftlen8-1].v.re,1),shr(table[fftlen8-1].v.im,1)) ) ) ); + ptr += 2; + FOR ( i = 1; i < fftlen8; i++ ) + { + move32(); + *ptr = Mpy_32_16_1( *ptr, sub( tmp, mult_r(preemph_fac2,add(shr(table[fftlen8-i-1].v.im,1),shr(table[fftlen8-i].v.im,1)) ) ) ); + ptr += 2; + } + move32(); + *ptr = Mpy_32_16_1( *ptr, tmp ); + ptr += 2; + FOR ( i = 1; i < fftlen8; i++ ) + { + move32(); + *ptr = Mpy_32_16_1( *ptr, add( tmp, mult_r(preemph_fac2,add(shr(table[i-1].v.im,1),shr(table[i].v.im,1)) ) ) ); + ptr += 2; + } + move32(); + *ptr = Mpy_32_16_1( *ptr, add( tmp, mult_r(preemph_fac2,add(shr(table[fftlen8-1].v.re,1),shr(table[fftlen8-1].v.im,1)) ) ) ); + ptr += 2; + FOR ( i = 1; i < fftlen8; i++ ) + { + move32(); + *ptr = Mpy_32_16_1( *ptr, add( tmp, mult_r(preemph_fac2,add(shr(table[fftlen8-i-1].v.re,1),shr(table[fftlen8-i].v.re,1)) ) ) ); + ptr += 2; + } + move32(); + fftBuffer[1] = Mpy_32_16_1( fftBuffer[1], add( tmp, preemph_fac2 ) ); + maxVal = 0; + move32(); + FOR (i=0; i < fftlen; i++) + { + maxVal = L_max(maxVal, L_abs(fftBuffer[i])); + } + s2 = norm_l(maxVal); + FOR (i=0; i < fftlen; i++) + { + fftBuffer[i] = L_shl( fftBuffer[i], s2 ); + move32(); + } + + /* Autocorrelation */ + + BASOP_rfft(fftBuffer, fftlen, &scale, 1); + + s3 = getScaleFactor32(fftBuffer, add(lpcorder,1)); + + FOR (i=0; i <= lpcorder; i++ ) + { + r[i] = L_shl(fftBuffer[i], s3); + move32(); + } + + r[0] = Mpy_32_32( r[0], 1074278656l/*1.0005f Q30*/ ); + move32(); + FOR (i=1; i <= lpcorder; i++ ) + { + r[i] = Mpy_32_32( r[i], 1073741824l/*1.f Q30*/ ); + move32(); + } + s3 = getScaleFactor32(r, add(lpcorder,1)); + + FOR (i=0; i <= lpcorder; i++ ) + { + r[i] = L_shl(r[i], s3); + move32(); + } + + FOR (i=0; i <= lpcorder; i++ ) + { + L_Extract(r[i], &r_h[i], &r_l[i]); + } + + /* LPC */ + + E_LPC_lev_dur(r_h, r_l, A, NULL, lpcorder, NULL); + +} + +/* + msvq_decoder + + Parameters: + + cb i : Codebook (indexed cb[stages][levels][p]) format Q9.7 + stages i : Number of stages + N i : Vector dimension + maxN i : Codebook vector dimension + Idx o : Indices + uq[] i : Quantized vector format Q9.7 + + + Function: + multi stage vector dequantisation + + Returns: + void +*/ +void msvq_decoder ( + const Word16 *const cb[], /* i : Codebook (indexed cb[*stages][levels][p]) */ + const Word16 stages, /* i : Number of stages */ + const Word16 N, /* i : Vector dimension */ + const Word16 maxN, /* i : Codebook vector dimension */ + const Word16 Idx[], /* i : Indices */ + Word16 *uq /* o : quantized vector */ +) +{ + Word16 s, i, offset; + +//PMT("msvq_decoder Not verified") + + offset = i_mult(Idx[0], maxN); + FOR (i=0; iA_cng, Aq+i*(M+1), M+1 ); + } + + E_LPC_a_lsp_conversion( Aq, lsp_new, lsp_old, M ); + + IF( first_CNG == 0 ) + { + Copy( lsp_old, lspCNG, M ); + } + FOR( i=0; iexc_cng, exc, L_frame ); + Copy( hFdCngCom->exc_cng, exc2, L_frame ); + IF (bwe_exc != NULL) + { + IF(EQ_16(L_frame, L_FRAME)) + { + interp_code_5over2_fx(exc2, bwe_exc, L_frame); + } + ELSE + { + interp_code_4over2_fx(exc2, bwe_exc, L_frame); + } + } +} + diff --git a/lib_com/fft.c b/lib_com/fft.c index 1558831848a41b408d247e5147c81b0dcb458769..91f460acbdea27039a3b602ccabda28be31f7ab1 100644 --- a/lib_com/fft.c +++ b/lib_com/fft.c @@ -84,7 +84,7 @@ static void bitrv2_SR( int16_t n, const int16_t *ip, float *a ); static void cftfsub( int16_t n, float *a, const float *w ); static void cft1st( int16_t n, float *a, const float *w ); static void cftmdl( int16_t n, int16_t l, float *a, const float *w ); -static void fft16( float *x, float *y, const int16_t *Idx ); +static void fft16_ivas( float *x, float *y, const int16_t *Idx ); static void fft5_shift1( int16_t n1, float *zRe, float *zIm, const int16_t *Idx ); static void fft8( float *x, float *y, const int16_t *Idx ); static void fft15_shift2( int16_t n1, float *zRe, float *zIm, const int16_t *Idx ); @@ -941,11 +941,11 @@ static void fft32_5( } /*-----------------------------------------------------------------* - * fft16() + * fft16_ivas() * 16-point FFT *-----------------------------------------------------------------*/ -static void fft16( +static void fft16_ivas( float *x, /* i/o: real part of input and output data */ float *y, /* i/o: imaginary part of input and output data */ const int16_t *Idx /* i : pointer of the address table */ @@ -1240,7 +1240,7 @@ void DoRTFT80( /* Applying 16-point FFT for 5 times based on the address table Idx_dortft80 */ for ( j = 0; j < 5; j++ ) { - fft16( x, y, Idx_dortft80 + 16 * j ); + fft16_ivas( x, y, Idx_dortft80 + 16 * j ); } /* Applying 5-point FFT for 16 times based on the address table Idx_dortft80 */ @@ -6411,65 +6411,6 @@ void rfft( /** * \brief Twiddle factors are unscaled */ -static const Word16 RotVector_256[2 * ( 256 - 32 )] = { - SHC( 0x7fff ), SHC( 0x0000 ), SHC( 0x7ff6 ), SHC( 0xfcdc ), SHC( 0x7fd9 ), SHC( 0xf9b8 ), SHC( 0x7fa7 ), SHC( 0xf695 ), - SHC( 0x7f62 ), SHC( 0xf374 ), SHC( 0x7f0a ), SHC( 0xf055 ), SHC( 0x7e9d ), SHC( 0xed38 ), SHC( 0x7e1e ), SHC( 0xea1e ), - SHC( 0x7d8a ), SHC( 0xe707 ), SHC( 0x7ce4 ), SHC( 0xe3f4 ), SHC( 0x7c2a ), SHC( 0xe0e6 ), SHC( 0x7b5d ), SHC( 0xdddc ), - SHC( 0x7a7d ), SHC( 0xdad8 ), SHC( 0x798a ), SHC( 0xd7d9 ), SHC( 0x7885 ), SHC( 0xd4e1 ), SHC( 0x776c ), SHC( 0xd1ef ), - SHC( 0x7642 ), SHC( 0xcf04 ), SHC( 0x7505 ), SHC( 0xcc21 ), SHC( 0x73b6 ), SHC( 0xc946 ), SHC( 0x7255 ), SHC( 0xc673 ), - SHC( 0x70e3 ), SHC( 0xc3a9 ), SHC( 0x6f5f ), SHC( 0xc0e9 ), SHC( 0x6dca ), SHC( 0xbe32 ), SHC( 0x6c24 ), SHC( 0xbb85 ), - SHC( 0x6a6e ), SHC( 0xb8e3 ), SHC( 0x68a7 ), SHC( 0xb64c ), SHC( 0x66d0 ), SHC( 0xb3c0 ), SHC( 0x64e9 ), SHC( 0xb140 ), - SHC( 0x62f2 ), SHC( 0xaecc ), SHC( 0x60ec ), SHC( 0xac65 ), SHC( 0x5ed7 ), SHC( 0xaa0a ), SHC( 0x5cb4 ), SHC( 0xa7bd ), - SHC( 0x7fff ), SHC( 0x0000 ), SHC( 0x7fd9 ), SHC( 0xf9b8 ), SHC( 0x7f62 ), SHC( 0xf374 ), SHC( 0x7e9d ), SHC( 0xed38 ), - SHC( 0x7d8a ), SHC( 0xe707 ), SHC( 0x7c2a ), SHC( 0xe0e6 ), SHC( 0x7a7d ), SHC( 0xdad8 ), SHC( 0x7885 ), SHC( 0xd4e1 ), - SHC( 0x7642 ), SHC( 0xcf04 ), SHC( 0x73b6 ), SHC( 0xc946 ), SHC( 0x70e3 ), SHC( 0xc3a9 ), SHC( 0x6dca ), SHC( 0xbe32 ), - SHC( 0x6a6e ), SHC( 0xb8e3 ), SHC( 0x66d0 ), SHC( 0xb3c0 ), SHC( 0x62f2 ), SHC( 0xaecc ), SHC( 0x5ed7 ), SHC( 0xaa0a ), - SHC( 0x5a82 ), SHC( 0xa57e ), SHC( 0x55f6 ), SHC( 0xa129 ), SHC( 0x5134 ), SHC( 0x9d0e ), SHC( 0x4c40 ), SHC( 0x9930 ), - SHC( 0x471d ), SHC( 0x9592 ), SHC( 0x41ce ), SHC( 0x9236 ), SHC( 0x3c57 ), SHC( 0x8f1d ), SHC( 0x36ba ), SHC( 0x8c4a ), - SHC( 0x30fc ), SHC( 0x89be ), SHC( 0x2b1f ), SHC( 0x877b ), SHC( 0x2528 ), SHC( 0x8583 ), SHC( 0x1f1a ), SHC( 0x83d6 ), - SHC( 0x18f9 ), SHC( 0x8276 ), SHC( 0x12c8 ), SHC( 0x8163 ), SHC( 0x0c8c ), SHC( 0x809e ), SHC( 0x0648 ), SHC( 0x8027 ), - SHC( 0x7fff ), SHC( 0x0000 ), SHC( 0x7fa7 ), SHC( 0xf695 ), SHC( 0x7e9d ), SHC( 0xed38 ), SHC( 0x7ce4 ), SHC( 0xe3f4 ), - SHC( 0x7a7d ), SHC( 0xdad8 ), SHC( 0x776c ), SHC( 0xd1ef ), SHC( 0x73b6 ), SHC( 0xc946 ), SHC( 0x6f5f ), SHC( 0xc0e9 ), - SHC( 0x6a6e ), SHC( 0xb8e3 ), SHC( 0x64e9 ), SHC( 0xb140 ), SHC( 0x5ed7 ), SHC( 0xaa0a ), SHC( 0x5843 ), SHC( 0xa34c ), - SHC( 0x5134 ), SHC( 0x9d0e ), SHC( 0x49b4 ), SHC( 0x9759 ), SHC( 0x41ce ), SHC( 0x9236 ), SHC( 0x398d ), SHC( 0x8dab ), - SHC( 0x30fc ), SHC( 0x89be ), SHC( 0x2827 ), SHC( 0x8676 ), SHC( 0x1f1a ), SHC( 0x83d6 ), SHC( 0x15e2 ), SHC( 0x81e2 ), - SHC( 0x0c8c ), SHC( 0x809e ), SHC( 0x0324 ), SHC( 0x800a ), SHC( 0xf9b8 ), SHC( 0x8027 ), SHC( 0xf055 ), SHC( 0x80f6 ), - SHC( 0xe707 ), SHC( 0x8276 ), SHC( 0xdddc ), SHC( 0x84a3 ), SHC( 0xd4e1 ), SHC( 0x877b ), SHC( 0xcc21 ), SHC( 0x8afb ), - SHC( 0xc3a9 ), SHC( 0x8f1d ), SHC( 0xbb85 ), SHC( 0x93dc ), SHC( 0xb3c0 ), SHC( 0x9930 ), SHC( 0xac65 ), SHC( 0x9f14 ), - SHC( 0x7fff ), SHC( 0x0000 ), SHC( 0x7f62 ), SHC( 0xf374 ), SHC( 0x7d8a ), SHC( 0xe707 ), SHC( 0x7a7d ), SHC( 0xdad8 ), - SHC( 0x7642 ), SHC( 0xcf04 ), SHC( 0x70e3 ), SHC( 0xc3a9 ), SHC( 0x6a6e ), SHC( 0xb8e3 ), SHC( 0x62f2 ), SHC( 0xaecc ), - SHC( 0x5a82 ), SHC( 0xa57e ), SHC( 0x5134 ), SHC( 0x9d0e ), SHC( 0x471d ), SHC( 0x9592 ), SHC( 0x3c57 ), SHC( 0x8f1d ), - SHC( 0x30fc ), SHC( 0x89be ), SHC( 0x2528 ), SHC( 0x8583 ), SHC( 0x18f9 ), SHC( 0x8276 ), SHC( 0x0c8c ), SHC( 0x809e ), - SHC( 0x0000 ), SHC( 0x8000 ), SHC( 0xf374 ), SHC( 0x809e ), SHC( 0xe707 ), SHC( 0x8276 ), SHC( 0xdad8 ), SHC( 0x8583 ), - SHC( 0xcf04 ), SHC( 0x89be ), SHC( 0xc3a9 ), SHC( 0x8f1d ), SHC( 0xb8e3 ), SHC( 0x9592 ), SHC( 0xaecc ), SHC( 0x9d0e ), - SHC( 0xa57e ), SHC( 0xa57e ), SHC( 0x9d0e ), SHC( 0xaecc ), SHC( 0x9592 ), SHC( 0xb8e3 ), SHC( 0x8f1d ), SHC( 0xc3a9 ), - SHC( 0x89be ), SHC( 0xcf04 ), SHC( 0x8583 ), SHC( 0xdad8 ), SHC( 0x8276 ), SHC( 0xe707 ), SHC( 0x809e ), SHC( 0xf374 ), - SHC( 0x7fff ), SHC( 0x0000 ), SHC( 0x7f0a ), SHC( 0xf055 ), SHC( 0x7c2a ), SHC( 0xe0e6 ), SHC( 0x776c ), SHC( 0xd1ef ), - SHC( 0x70e3 ), SHC( 0xc3a9 ), SHC( 0x68a7 ), SHC( 0xb64c ), SHC( 0x5ed7 ), SHC( 0xaa0a ), SHC( 0x539b ), SHC( 0x9f14 ), - SHC( 0x471d ), SHC( 0x9592 ), SHC( 0x398d ), SHC( 0x8dab ), SHC( 0x2b1f ), SHC( 0x877b ), SHC( 0x1c0c ), SHC( 0x831c ), - SHC( 0x0c8c ), SHC( 0x809e ), SHC( 0xfcdc ), SHC( 0x800a ), SHC( 0xed38 ), SHC( 0x8163 ), SHC( 0xdddc ), SHC( 0x84a3 ), - SHC( 0xcf04 ), SHC( 0x89be ), SHC( 0xc0e9 ), SHC( 0x90a1 ), SHC( 0xb3c0 ), SHC( 0x9930 ), SHC( 0xa7bd ), SHC( 0xa34c ), - SHC( 0x9d0e ), SHC( 0xaecc ), SHC( 0x93dc ), SHC( 0xbb85 ), SHC( 0x8c4a ), SHC( 0xc946 ), SHC( 0x8676 ), SHC( 0xd7d9 ), - SHC( 0x8276 ), SHC( 0xe707 ), SHC( 0x8059 ), SHC( 0xf695 ), SHC( 0x8027 ), SHC( 0x0648 ), SHC( 0x81e2 ), SHC( 0x15e2 ), - SHC( 0x8583 ), SHC( 0x2528 ), SHC( 0x8afb ), SHC( 0x33df ), SHC( 0x9236 ), SHC( 0x41ce ), SHC( 0x9b17 ), SHC( 0x4ec0 ), - SHC( 0x7fff ), SHC( 0x0000 ), SHC( 0x7e9d ), SHC( 0xed38 ), SHC( 0x7a7d ), SHC( 0xdad8 ), SHC( 0x73b6 ), SHC( 0xc946 ), - SHC( 0x6a6e ), SHC( 0xb8e3 ), SHC( 0x5ed7 ), SHC( 0xaa0a ), SHC( 0x5134 ), SHC( 0x9d0e ), SHC( 0x41ce ), SHC( 0x9236 ), - SHC( 0x30fc ), SHC( 0x89be ), SHC( 0x1f1a ), SHC( 0x83d6 ), SHC( 0x0c8c ), SHC( 0x809e ), SHC( 0xf9b8 ), SHC( 0x8027 ), - SHC( 0xe707 ), SHC( 0x8276 ), SHC( 0xd4e1 ), SHC( 0x877b ), SHC( 0xc3a9 ), SHC( 0x8f1d ), SHC( 0xb3c0 ), SHC( 0x9930 ), - SHC( 0xa57e ), SHC( 0xa57e ), SHC( 0x9930 ), SHC( 0xb3c0 ), SHC( 0x8f1d ), SHC( 0xc3a9 ), SHC( 0x877b ), SHC( 0xd4e1 ), - SHC( 0x8276 ), SHC( 0xe707 ), SHC( 0x8027 ), SHC( 0xf9b8 ), SHC( 0x809e ), SHC( 0x0c8c ), SHC( 0x83d6 ), SHC( 0x1f1a ), - SHC( 0x89be ), SHC( 0x30fc ), SHC( 0x9236 ), SHC( 0x41ce ), SHC( 0x9d0e ), SHC( 0x5134 ), SHC( 0xaa0a ), SHC( 0x5ed7 ), - SHC( 0xb8e3 ), SHC( 0x6a6e ), SHC( 0xc946 ), SHC( 0x73b6 ), SHC( 0xdad8 ), SHC( 0x7a7d ), SHC( 0xed38 ), SHC( 0x7e9d ), - SHC( 0x7fff ), SHC( 0x0000 ), SHC( 0x7e1e ), SHC( 0xea1e ), SHC( 0x7885 ), SHC( 0xd4e1 ), SHC( 0x6f5f ), SHC( 0xc0e9 ), - SHC( 0x62f2 ), SHC( 0xaecc ), SHC( 0x539b ), SHC( 0x9f14 ), SHC( 0x41ce ), SHC( 0x9236 ), SHC( 0x2e11 ), SHC( 0x8894 ), - SHC( 0x18f9 ), SHC( 0x8276 ), SHC( 0x0324 ), SHC( 0x800a ), SHC( 0xed38 ), SHC( 0x8163 ), SHC( 0xd7d9 ), SHC( 0x8676 ), - SHC( 0xc3a9 ), SHC( 0x8f1d ), SHC( 0xb140 ), SHC( 0x9b17 ), SHC( 0xa129 ), SHC( 0xaa0a ), SHC( 0x93dc ), SHC( 0xbb85 ), - SHC( 0x89be ), SHC( 0xcf04 ), SHC( 0x831c ), SHC( 0xe3f4 ), SHC( 0x8027 ), SHC( 0xf9b8 ), SHC( 0x80f6 ), SHC( 0x0fab ), - SHC( 0x8583 ), SHC( 0x2528 ), SHC( 0x8dab ), SHC( 0x398d ), SHC( 0x9930 ), SHC( 0x4c40 ), SHC( 0xa7bd ), SHC( 0x5cb4 ), - SHC( 0xb8e3 ), SHC( 0x6a6e ), SHC( 0xcc21 ), SHC( 0x7505 ), SHC( 0xe0e6 ), SHC( 0x7c2a ), SHC( 0xf695 ), SHC( 0x7fa7 ), - SHC( 0x0c8c ), SHC( 0x7f62 ), SHC( 0x2224 ), SHC( 0x7b5d ), SHC( 0x36ba ), SHC( 0x73b6 ), SHC( 0x49b4 ), SHC( 0x68a7 ) -}; - /*-----------------------------------------------------------------* * BASOP_fft8() * @@ -6737,12 +6678,12 @@ static void BASOP_fftN2( /*-----------------------------------------------------------------* - * BASOP_cfft() + * BASOP_cfft_ivas() * * Complex valued FFT *-----------------------------------------------------------------*/ -void BASOP_cfft( +void BASOP_cfft_ivas( Word32 *re, /* i/o: real part */ Word32 *im, /* i/o: imag part */ Word16 s, /* i : stride real and imag part */ diff --git a/lib_com/fft_cldfb.c b/lib_com/fft_cldfb.c index 0ea848abdbba069cd73569df5054e417386a65fa..49cf0905ad5748ae591e1405c622552df7f6ff93 100644 --- a/lib_com/fft_cldfb.c +++ b/lib_com/fft_cldfb.c @@ -52,7 +52,7 @@ static void fft8( float *vec ); static void fft10( float *vec ); -static void fft16( float *vec ); +static void fft16_ivas( float *vec ); static void fft20( float *vec ); static void fft30( float *vec ); static void fft5s( float *x, const int16_t stride ); @@ -147,7 +147,7 @@ static void fft8( float *restrict vec ) /******************************************************************************* - Functionname: fft16 + Functionname: fft16_ivas ******************************************************************************* Description: 16-point FFT. Complex-valued input takes 144 real additions and @@ -159,7 +159,7 @@ static void fft8( float *restrict vec ) *******************************************************************************/ /* fast implementation, completely unrolled and inlined */ -static void fft16( float *restrict vec ) +static void fft16_ivas( float *restrict vec ) { float temp10, temp11, temp12, temp13, temp14, temp15, temp16, temp17, temp18, temp19, temp110, temp111, temp112, temp113, temp114, temp115; @@ -1205,7 +1205,7 @@ void fft_cldfb( fft10( data ); break; case 16: - fft16( data ); + fft16_ivas( data ); break; case 20: fft20( data ); diff --git a/lib_com/fft_evs.c b/lib_com/fft_evs.c new file mode 100644 index 0000000000000000000000000000000000000000..17da7a27311c071544de5b85d0528e7c055df694 --- /dev/null +++ b/lib_com/fft_evs.c @@ -0,0 +1,2516 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include +#include "prot_fx1.h" +#include "prot_fx2.h" +#include "basop_util.h" +#include "rom_basop_util.h" +#include "rom_com.h" +#include "options.h" +#include "stl.h" + /************************************************************************/ + /* FFT */ + /************************************************************************/ + +#define SCALEFACTORN2 ( 3) +#define SCALEFACTOR2 ( 2) +#define SCALEFACTOR3 ( 3) +#define SCALEFACTOR4 ( 3) +#define SCALEFACTOR5 ( 4) +#define SCALEFACTOR8 ( 4) +#define SCALEFACTOR10 ( 5) +#define SCALEFACTOR12 ( 5) +#define SCALEFACTOR15 ( 5) +#define SCALEFACTOR16 ( 5) +#define SCALEFACTOR20 ( 5) +#define SCALEFACTOR24 ( 6) +#define SCALEFACTOR30 ( 6) +#define SCALEFACTOR30_1 ( 5) +#define SCALEFACTOR30_2 ( 1) +#define SCALEFACTOR32 ( 6) +#define SCALEFACTOR32_1 ( 5) +#define SCALEFACTOR32_2 ( 1) +#define SCALEFACTOR40 ( 7) +#define SCALEFACTOR60 ( 7) +#define SCALEFACTOR64 ( 7) +#define SCALEFACTOR80 ( 8) +#define SCALEFACTOR100 (10) +#define SCALEFACTOR120 ( 8) +#define SCALEFACTOR128 ( 8) +#define SCALEFACTOR160 ( 8) +#define SCALEFACTOR192 (10) +#define SCALEFACTOR200 (10) +#define SCALEFACTOR240 ( 9) +#define SCALEFACTOR256 ( 9) +#define SCALEFACTOR320 (10) +#define SCALEFACTOR400 (10) +#define SCALEFACTOR480 (11) +#define SCALEFACTOR600 (10) + + +void fft16_with_cmplx_data( cmplx *pInp, Word16 bsacle); + +/** + * \brief Profiling / Precision results + * + * Profiling / Precision of complex valued FFTs: BASOP_cfft() + * + * WOPS BASOP Precision BASOP + * FFT5 87 16.96 + * FFT8 108 17.04 + * FFT10 194 16.70 + * FFT15 354 16.97 + * FFT16 288 16.62 + * FFT20 368 16.06 + * FFT30 828 16.80 + * FFT32 752 15.45 (cplx mult mit 3 mult und 3 add) + * FFT32 824 16.07 (cplx mult mit 4 mult und 2 add) + * FFT64 ( 8x 8) 3.129 15.16 + * FFT80 (10x 8) 4.385 15.55 + * FFT100 (20x 5) 6.518 15.65 + * FFT120 (15x 8) 7.029 15.38 + * FFT128 (16x 8) 6.777 15.28 + * FFT160 (20x 8) 9.033 14.95 + * FFT240 (30x 8) 14.961 15.49 + * FFT256 (32x 8) 14.905 14.61 (cplx mult mit 3 mult und 3 add) + * FFT256 (32x 8) 15.265 15.04 (cplx mult mit 4 mult und 2 add) + * FFT320 (20x16) 21.517 15.21 + * + * + * Profiling / Precision of real valued FFTs / iFFTs: BASOP_rfft() + * + * WOPS BASOP Precision BASOP + * rFFT40 955 15.68 + * rFFT64 1635 16.17 + * + * irFFT40 1116 15.36 + * irFFT64 1759 15.18 + * + */ + + +#define Mpy_32_xx Mpy_32_16_1 + +#define FFTC(x) WORD322WORD16((Word32)x) + +#define C31 (FFTC(0x91261468)) /* FL2WORD32( -0.86602540) -sqrt(3)/2 */ + +#define C51 (FFTC(0x79bc3854)) /* FL2WORD32( 0.95105652) */ +#define C52 (FFTC(0x9d839db0)) /* FL2WORD32(-1.53884180/2) */ +#define C53 (FFTC(0xd18053ce)) /* FL2WORD32(-0.36327126) */ +#define C54 (FFTC(0x478dde64)) /* FL2WORD32( 0.55901699) */ +#define C55 (FFTC(0xb0000001)) /* FL2WORD32(-1.25/2) */ + +#define C81 (FFTC(0x5a82799a)) /* FL2WORD32( 7.071067811865475e-1) */ +#define C82 (FFTC(0xa57d8666)) /* FL2WORD32(-7.071067811865475e-1) */ + +#define C161 (FFTC(0x5a82799a)) /* FL2WORD32( 7.071067811865475e-1) INV_SQRT2 */ +#define C162 (FFTC(0xa57d8666)) /* FL2WORD32(-7.071067811865475e-1) -INV_SQRT2 */ + +#define C163 (FFTC(0x7641af3d)) /* FL2WORD32( 9.238795325112867e-1) COS_PI_DIV8 */ +#define C164 (FFTC(0x89be50c3)) /* FL2WORD32(-9.238795325112867e-1) -COS_PI_DIV8 */ + +#define C165 (FFTC(0x30fbc54d)) /* FL2WORD32( 3.826834323650898e-1) COS_3PI_DIV8 */ +#define C166 (FFTC(0xcf043ab3)) /* FL2WORD32(-3.826834323650898e-1) -COS_3PI_DIV8 */ + + +#define cplxMpy4_8_0(re,im,a,b,c,d) re = L_shr(L_sub(Mpy_32_xx(a,c),Mpy_32_xx(b,d)),1); \ + im = L_shr(L_add(Mpy_32_xx(a,d),Mpy_32_xx(b,c)),1); + +#define cplxMpy4_8_1(re,im,a,b) re = L_shr(a,1); \ + im = L_shr(b,1); + + + + +/** + * \brief Function performs a complex 5-point FFT + * The FFT is performed inplace. The result of the FFT + * is scaled by SCALEFACTOR5 bits. + * + * WOPS with 32x16 bit multiplications: 88 cycles + * + * \param [i/o] re real input / output + * \param [i/o] im imag input / output + * \param [i ] s stride real and imag input / output + * + * \return void + */ +static void fft5_with_cmplx_data(cmplx *inp) +{ + cmplx x0,x1,x2,x3,x4; + cmplx y1,y2,y3,y4; + cmplx t; + + x0 = CL_shr(inp[0],SCALEFACTOR5); + x1 = CL_shr(inp[1],SCALEFACTOR5); + x2 = CL_shr(inp[2],SCALEFACTOR5); + x3 = CL_shr(inp[3],SCALEFACTOR5); + x4 = CL_shr(inp[4],SCALEFACTOR5); + + y1 = CL_add(x1,x4); + y4 = CL_sub(x1,x4); + y3 = CL_add(x2,x3); + y2 = CL_sub(x2,x3); + t = CL_scale_t(CL_sub(y1,y3),C54); + y1 = CL_add(y1,y3); + inp[0] = CL_add(x0,y1); + + /* Bit shift left because of the constant C55 which was scaled with the factor 0.5 because of the representation of + the values as fracts */ + y1 = CL_add(inp[0],(CL_shl(CL_scale_t(y1,C55),1))); + y3 = CL_sub(y1,t); + y1 = CL_add(y1,t); + + t = CL_scale_t(CL_add(y4,y2),C51); + /* Bit shift left because of the constant C55 which was scaled with the factor 0.5 because of the representation of + the values as fracts */ + y4 = CL_add(t,CL_shl(CL_scale_t(y4, C52),1)); + y2 = CL_add(t,CL_scale_t(y2,C53)); + + + /* combination */ + inp[1] = CL_msu_j(y1,y2); + inp[4] = CL_mac_j(y1,y2); + + inp[2] = CL_mac_j(y3,y4); + inp[3] = CL_msu_j(y3,y4); + +#if (WMOPS) + multiCounter[currCounter].CL_move += 5; +#endif + +} + +/** + * \brief Function performs a complex 8-point FFT + * The FFT is performed inplace. The result of the FFT + * is scaled by SCALEFACTOR8 bits. + * + * WOPS with 32x16 bit multiplications: 108 cycles + * + * \param [i/o] re real input / output + * \param [i/o] im imag input / output + * \param [i ] s stride real and imag input / output + * + * \return void + */ +static void fft8_with_cmplx_data(cmplx *inp) +{ + cmplx x0, x1, x2, x3, x4, x5, x6, x7; + cmplx s0, s1, s2, s3, s4, s5, s6, s7; + cmplx t0, t1, t2, t3, t4, t5, t6, t7; + + /* Pre-additions */ + x0 = CL_shr(inp[0], SCALEFACTOR8); + x1 = CL_shr(inp[1], SCALEFACTOR8); + x2 = CL_shr(inp[2], SCALEFACTOR8); + x3 = CL_shr(inp[3], SCALEFACTOR8); + x4 = CL_shr(inp[4], SCALEFACTOR8); + x5 = CL_shr(inp[5], SCALEFACTOR8); + x6 = CL_shr(inp[6], SCALEFACTOR8); + x7 = CL_shr(inp[7], SCALEFACTOR8); + + /* loops are unrolled */ + { + t0 = CL_add(x0,x4); + t1 = CL_sub(x0,x4); + + t2 = CL_add(x1,x5); + t3 = CL_sub(x1,x5); + + t4 = CL_add(x2,x6); + t5 = CL_sub(x2,x6); + + t6 = CL_add(x3,x7); + t7 = CL_sub(x3,x7); + } + + /* Pre-additions and core multiplications */ + + s0 = CL_add(t0, t4); + s2 = CL_sub(t0, t4); + + s4 = CL_mac_j(t1, t5); + s5 = CL_msu_j(t1, t5); + + s1 = CL_add(t2, t6); + s3 = CL_sub(t2, t6); + s3 = CL_mul_j(s3); + + t0 = CL_add(t3, t7); + t1 = CL_sub(t3, t7); + + s6 = CL_scale_t(CL_msu_j(t1, t0), C81); + s7 = CL_dscale_t(CL_swap_real_imag(CL_msu_j(t0, t1)), C81, C82); + + /* Post-additions */ + + inp[0] = CL_add(s0, s1); + inp[4] = CL_sub(s0, s1); + + inp[2] = CL_sub(s2, s3); + inp[6] = CL_add(s2, s3); + + inp[3] = CL_add(s4, s7); + inp[7] = CL_sub(s4, s7); + + inp[1] = CL_add(s5, s6); + inp[5] = CL_sub(s5, s6); +#if (WMOPS) + multiCounter[currCounter].CL_move += 8; +#endif + + +} + + +/** + * \brief Function performs a complex 10-point FFT + * The FFT is performed inplace. The result of the FFT + * is scaled by SCALEFACTOR10 bits. + * + * WOPS with 32x16 bit multiplications: 196 cycles + * + * \param [i/o] re real input / output + * \param [i/o] im imag input / output + * \param [i ] s stride real and imag input / output + * + * \return void + */ + +static void fft10_with_cmplx_data(cmplx *inp_data) +{ + cmplx r1,r2,r3,r4; + cmplx x0,x1,x2,x3,x4,t; + cmplx y[10]; + + /* FOR i=0 */ + { + x0 = CL_shr(inp_data[0],SCALEFACTOR10); + x1 = CL_shr(inp_data[2],SCALEFACTOR10); + x2 = CL_shr(inp_data[4],SCALEFACTOR10); + x3 = CL_shr(inp_data[6],SCALEFACTOR10); + x4 = CL_shr(inp_data[8],SCALEFACTOR10); + + r1 = CL_add(x3,x2); + r4 = CL_sub(x3,x2); + r3 = CL_add(x1,x4); + r2 = CL_sub(x1,x4); + t = CL_scale_t(CL_sub(r1,r3),C54); + r1 = CL_add(r1,r3); + y[0] = CL_add(x0,r1); + r1 = CL_add(y[0],(CL_shl(CL_scale_t(r1,C55),1))); + r3 = CL_sub(r1,t); + r1 = CL_add(r1,t); + t = CL_scale_t((CL_add(r4,r2)),C51); + r4 = CL_add(t,CL_shl(CL_scale_t(r4, C52),1)); + r2 = CL_add(t,CL_scale_t(r2,C53)); + + + y[2] = CL_msu_j(r1,r2); + y[8] = CL_mac_j(r1,r2); + y[4] = CL_mac_j(r3,r4); + y[6] = CL_msu_j(r3,r4); + } + /* FOR i=1 */ + { + x0 = CL_shr(inp_data[5],SCALEFACTOR10); + x1 = CL_shr(inp_data[1],SCALEFACTOR10); + x2 = CL_shr(inp_data[3],SCALEFACTOR10); + x3 = CL_shr(inp_data[7],SCALEFACTOR10); + x4 = CL_shr(inp_data[9],SCALEFACTOR10); + + r1 = CL_add(x1,x4); + r4 = CL_sub(x1,x4); + r3 = CL_add(x3,x2); + r2 = CL_sub(x3,x2); + t = CL_scale_t(CL_sub(r1,r3),C54); + r1 = CL_add(r1,r3); + y[1] = CL_add(x0,r1); + r1 = CL_add(y[1],(CL_shl(CL_scale_t(r1,C55),1))); + r3 = CL_sub(r1,t); + r1 = CL_add(r1,t); + t = CL_scale_t((CL_add(r4,r2)),C51); + r4 = CL_add(t,CL_shl(CL_scale_t(r4, C52),1)); + r2 = CL_add(t,CL_scale_t(r2,C53)); + + + y[3] = CL_msu_j(r1,r2); + y[9] = CL_mac_j(r1,r2); + y[5] = CL_mac_j(r3,r4); + y[7] = CL_msu_j(r3,r4); + } + + /* FOR i=0 */ + { + inp_data[0] = CL_add(y[0],y[1]); + inp_data[5] = CL_sub(y[0],y[1]); + } + /* FOR i=2 */ + { + inp_data[2] = CL_add(y[2],y[3]); + inp_data[7] = CL_sub(y[2],y[3]); + } + /* FOR i=4 */ + { + inp_data[4] = CL_add(y[4],y[5]); + inp_data[9] = CL_sub(y[4],y[5]); + } + /* FOR i=6 */ + { + inp_data[6] = CL_add(y[6],y[7]); + inp_data[1] = CL_sub(y[6],y[7]); + } + /* FOR i=8 */ + { + inp_data[8] = CL_add(y[8],y[9]); + inp_data[3] = CL_sub(y[8],y[9]); + } + +#if (WMOPS) + multiCounter[currCounter].CL_move += 10; +#endif + +} + + +/** + * \brief Function performs a complex 15-point FFT + * The FFT is performed inplace. The result of the FFT + * is scaled by SCALEFACTOR15 bits. + * + * WOPS with 32x16 bit multiplications: 354 cycles + * + * \param [i/o] re real input / output + * \param [i/o] im imag input / output + * \param [i ] s stride real and imag input / output + * + * \return void + */ + +static void fft15_with_cmplx_data(cmplx *inp_data) +{ + cmplx c0,c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14; + cmplx c_z0,c_z1, c_z2, c_z3, c_z4, c_z5, c_z6, c_z7, c_z8, c_z9, c_z10, c_z11, c_z12, c_z13, c_z14; + cmplx c_y1,c_y2,c_y3,c_y4; + cmplx c_t; + + c0 = CL_shr(inp_data[ 0],SCALEFACTOR15); + c1 = CL_shr(inp_data[ 3],SCALEFACTOR15); + c2 = CL_shr(inp_data[ 6],SCALEFACTOR15); + c3 = CL_shr(inp_data[ 9],SCALEFACTOR15); + c4 = CL_shr(inp_data[12],SCALEFACTOR15); + c5 = CL_shr(inp_data[ 5],SCALEFACTOR15); + c6 = CL_shr(inp_data[ 8],SCALEFACTOR15); + c7 = CL_shr(inp_data[11],SCALEFACTOR15); + c8 = CL_shr(inp_data[14],SCALEFACTOR15); + c9 = CL_shr(inp_data[ 2],SCALEFACTOR15); + c10 = CL_shr(inp_data[10],SCALEFACTOR15); + c11 = CL_shr(inp_data[13],SCALEFACTOR15); + c12 = CL_shr(inp_data[ 1],SCALEFACTOR15); + c13 = CL_shr(inp_data[ 4],SCALEFACTOR15); + c14 = CL_shr(inp_data[ 7],SCALEFACTOR15); + + /* 1. FFT5 stage */ + c_y1 = CL_add(c1,c4); + c_y4 = CL_sub(c1,c4); + c_y3 = CL_add(c2,c3); + c_y2 = CL_sub(c2,c3); + c_t = CL_scale_t(CL_sub(c_y1,c_y3),C54); + c_y1 = CL_add(c_y1,c_y3); + c_z0 = CL_add(c0,c_y1); + c_y1 = CL_add(c_z0,(CL_shl(CL_scale_t(c_y1,C55),1))); + c_y3 = CL_sub(c_y1,c_t); + c_y1 = CL_add(c_y1,c_t); + c_t = CL_scale_t(CL_add(c_y4,c_y2),C51); + c_y4 = CL_add(c_t,CL_shl(CL_scale_t(c_y4,C52),1)); + c_y2 = CL_add(c_t,CL_scale_t(c_y2,C53)); + + /* combination */ + c_z1 = CL_msu_j(c_y1,c_y2); + c_z2 = CL_mac_j(c_y3,c_y4); + c_z3 = CL_msu_j(c_y3,c_y4); + c_z4 = CL_mac_j(c_y1,c_y2); + + + /* 2. FFT5 stage */ + c_y1 = CL_add(c6,c9); + c_y4 = CL_sub(c6,c9); + c_y3 = CL_add(c7,c8); + c_y2 = CL_sub(c7,c8); + c_t = CL_scale_t(CL_sub(c_y1,c_y3),C54); + c_y1 = CL_add(c_y1,c_y3); + c_z5 = CL_add(c5,c_y1); + c_y1 = CL_add(c_z5,(CL_shl(CL_scale_t(c_y1,C55),1))); + c_y3 = CL_sub(c_y1,c_t); + c_y1 = CL_add(c_y1,c_t); + c_t = CL_scale_t(CL_add(c_y4,c_y2),C51); + c_y4 = CL_add(c_t,CL_shl(CL_scale_t(c_y4,C52),1)); + c_y2 = CL_add(c_t,CL_scale_t(c_y2,C53)); + /* combination */ + c_z6 = CL_msu_j(c_y1,c_y2); + c_z7 = CL_mac_j(c_y3,c_y4); + c_z8 = CL_msu_j(c_y3,c_y4); + c_z9 = CL_mac_j(c_y1,c_y2); + + + /* 3. FFT5 stage */ + + c_y1 = CL_add(c11,c14); + c_y4 = CL_sub(c11,c14); + c_y3 = CL_add(c12,c13); + c_y2 = CL_sub(c12,c13); + c_t = CL_scale_t(CL_sub(c_y1,c_y3),C54); + c_y1 = CL_add(c_y1,c_y3); + c_z10 = CL_add(c10,c_y1); + c_y1 = CL_add(c_z10,(CL_shl(CL_scale_t(c_y1,C55),1))); + c_y3 = CL_sub(c_y1,c_t); + c_y1 = CL_add(c_y1,c_t); + c_t = CL_scale_t(CL_add(c_y4,c_y2),C51); + c_y4 = CL_add(c_t,CL_shl(CL_scale_t(c_y4,C52),1)); + c_y2 = CL_add(c_t,CL_scale_t(c_y2,C53)); + /* combination */ + c_z11 = CL_msu_j(c_y1,c_y2); + c_z12 = CL_mac_j(c_y3,c_y4); + c_z13 = CL_msu_j(c_y3,c_y4); + c_z14 = CL_mac_j(c_y1,c_y2); + + + + /* 1. FFT3 stage */ + + c_y1 = CL_add(c_z5,c_z10); + c_y2 = CL_scale_t(CL_sub(c_z5,c_z10),C31); + inp_data[0] = CL_add(c_z0,c_y1); + c_y1 = CL_sub(c_z0,CL_shr(c_y1,1)); + inp_data[10] = CL_mac_j(c_y1,c_y2); + inp_data[5] = CL_msu_j(c_y1,c_y2); + + /* 2. FFT3 stage */ + c_y1 = CL_add(c_z6,c_z11); + c_y2 = CL_scale_t(CL_sub(c_z6,c_z11),C31); + inp_data[6] = CL_add(c_z1,c_y1); + c_y1 = CL_sub(c_z1,CL_shr(c_y1,1)); + inp_data[1] = CL_mac_j(c_y1,c_y2); + inp_data[11] = CL_msu_j(c_y1,c_y2); + + /* 3. FFT3 stage */ + c_y1 = CL_add(c_z7,c_z12); + c_y2 = CL_scale_t(CL_sub(c_z7,c_z12),C31); + inp_data[12] = CL_add(c_z2,c_y1); + c_y1 = CL_sub(c_z2,CL_shr(c_y1,1)); + inp_data[7] = CL_mac_j(c_y1,c_y2); + inp_data[2] = CL_msu_j(c_y1,c_y2); + + + /* 4. FFT3 stage */ + c_y1 = CL_add(c_z8,c_z13); + c_y2 = CL_scale_t(CL_sub(c_z8,c_z13),C31); + inp_data[3] = CL_add(c_z3,c_y1); + c_y1 = CL_sub(c_z3,CL_shr(c_y1,1)); + inp_data[13] = CL_mac_j(c_y1,c_y2); + inp_data[8] = CL_msu_j(c_y1,c_y2); + + + /* 5. FFT3 stage */ + c_y1 = CL_add(c_z9,c_z14); + c_y2 = CL_scale_t(CL_sub(c_z9,c_z14),C31); + inp_data[9] = CL_add(c_z4,c_y1); + c_y1 = CL_sub(c_z4,CL_shr(c_y1,1)); + inp_data[4] = CL_mac_j(c_y1,c_y2); + inp_data[14] = CL_msu_j(c_y1,c_y2); + +#if (WMOPS) + multiCounter[currCounter].CL_move += 15; +#endif + +} + + +/** + * \brief Function performs a complex 16-point FFT + * The FFT is performed inplace. The result of the FFT + * is scaled by SCALEFACTOR16 bits. + * + * WOPS with 32x16 bit multiplications (scale on ): 288 cycles + * WOPS with 32x16 bit multiplications (scale off): 256 cycles + * + * \param [i/o] re real input / output + * \param [i/o] im imag input / output + * \param [i ] s stride real and imag input / output + * + * \return void + */ +void fft16(Word32 *re, Word32 *im, Word16 s, Word16 bScale) +{ + int i; + if ( s == 2 ) + { + fft16_with_cmplx_data( (cmplx *) re, bScale ); + } + else + { + cmplx inp_data[16]; + FOR(i=0; i<16; i++) + { + inp_data[i] = CL_form(re[s*i], im[s*i]); + } + fft16_with_cmplx_data(inp_data, bScale ); + FOR(i=0; i<16; i++) + { + re[s*i] = CL_Extract_real(inp_data[i]); + im[s*i] = CL_Extract_imag(inp_data[i]); + } + } +} + +void fft16_with_cmplx_data(cmplx *input, Word16 bScale ) +{ + cmplx x0, x1, x2, x3, temp; + cmplx t0,t2,t4,t6,t7; + cmplx y[16]; + + IF (bScale) + { + { + x0 = CL_shr(input[0],SCALEFACTOR16); + x1 = CL_shr(input[4],SCALEFACTOR16); + x2 = CL_shr(input[8],SCALEFACTOR16); + x3 = CL_shr(input[12],SCALEFACTOR16); + t0 = CL_add(x0,x2); + t2 = CL_sub(x0,x2); + t4 = CL_add(x1,x3); + t6 = CL_sub(x1,x3); + t6 = CL_mul_j(t6); + y[0] = CL_add(t0,t4); + y[1] = CL_sub(t2,t6); + y[2] = CL_sub(t0,t4); + y[3] = CL_add(t2,t6); + + + x0 = CL_shr(input[1],SCALEFACTOR16); + x1 = CL_shr(input[5],SCALEFACTOR16); + x2 = CL_shr(input[9],SCALEFACTOR16); + x3 = CL_shr(input[13],SCALEFACTOR16); + t0 = CL_add(x0,x2); + t2 = CL_sub(x0,x2); + t4 = CL_add(x1,x3); + t6 = CL_sub(x1,x3); + t6 = CL_mul_j(t6); + y[4] = CL_add(t0,t4); + y[5] = CL_sub(t2,t6); + y[6] = CL_sub(t0,t4); + y[7] = CL_add(t2,t6); + + + x0 = CL_shr(input[2],SCALEFACTOR16); + x1 = CL_shr(input[6],SCALEFACTOR16); + x2 = CL_shr(input[10],SCALEFACTOR16); + x3 = CL_shr(input[14],SCALEFACTOR16); + t0 = CL_add(x0,x2); + t2 = CL_sub(x0,x2); + t4 = CL_add(x1,x3); + t6 = CL_sub(x1,x3); + t6 = CL_mul_j(t6); + y[8] = CL_add(t0,t4); + y[9] = CL_sub(t2,t6); + y[10] = CL_sub(t4,t0); + y[10] = CL_mul_j(y[10]); + y[11] = CL_add(t2,t6); + + + x0 = CL_shr(input[3],SCALEFACTOR16); + x1 = CL_shr(input[7],SCALEFACTOR16); + x2 = CL_shr(input[11],SCALEFACTOR16); + x3 = CL_shr(input[15],SCALEFACTOR16); + t0 = CL_add(x0,x2); + t2 = CL_sub(x0,x2); + t4 = CL_add(x1,x3); + t6 = CL_sub(x1,x3); + t6 = CL_mul_j(t6); + y[12] = CL_add(t0,t4); + y[13] = CL_sub(t2,t6); + y[14] = CL_sub(t0,t4); + y[15] = CL_add(t2,t6); + } + } + else + { + { + t0 = CL_add(input[ 0],input[ 8]); + t2 = CL_sub(input[ 0],input[ 8]); + t4 = CL_add(input[ 4],input[12]); + t7 = CL_sub(input[ 4],input[12]); + + y[0] = CL_add(t0,t4); + y[1] = CL_msu_j(t2,t7); + y[2] = CL_sub(t0,t4); + y[3] = CL_mac_j(t2,t7); + } + /* i=1 */ + { + t0 = CL_add(input[ 1],input[ 9]); + t2 = CL_sub(input[ 1],input[ 9]); + t4 = CL_add(input[ 5],input[13]); + t7 = CL_sub(input[ 5],input[13]); + + y[4] = CL_add(t0,t4); + y[5] = CL_msu_j(t2,t7); + y[6] = CL_sub(t0,t4); + y[7] = CL_mac_j(t2,t7); + } + /* i=2 */ + { + t0 = CL_add(input[ 2],input[ 10]); + t2 = CL_sub(input[ 2],input[ 10]); + t4 = CL_add(input[ 6],input[14]); + t7 = CL_sub(input[ 6],input[14]); + + y[8] = CL_add(t0,t4); + y[9] = CL_msu_j(t2,t7); + temp = CL_sub(t0,t4); + y[10] = CL_negate(CL_mul_j(temp)); + y[11] = CL_mac_j(t2,t7); + } + /* i=3 */ + { + t0 = CL_add(input[ 3],input[ 11]); + t2 = CL_sub(input[ 3],input[ 11]); + t4 = CL_add(input[ 7],input[15]); + t7 = CL_sub(input[ 7],input[15]); + + y[12] = CL_add(t0,t4); + y[13] = CL_msu_j(t2,t7); + y[14] = CL_sub(t0,t4); + y[15] = CL_mac_j(t2,t7); + } + + } + + x0 = CL_scale_t(y[11],C162); + y[11] = CL_mac_j(x0,x0); + + x0 = CL_scale_t(y[14],C162); + y[14] = CL_mac_j(x0,x0); + + x0 = CL_scale_t(y[6],C161); + y[6] = CL_msu_j(x0,x0); + + x0 = CL_scale_t(y[9],C161); + y[9] = CL_msu_j(x0,x0); + + y[5] = CL_mac_j(CL_scale_t(y[5], C163), CL_scale_t(y[5], C166)); + y[7] = CL_mac_j(CL_scale_t(y[7], C165), CL_scale_t(y[7], C164)); + y[13] = CL_mac_j(CL_scale_t(y[13], C165), CL_scale_t(y[13], C164)); + y[15] = CL_mac_j(CL_scale_t(y[15], C164), CL_scale_t(y[15], C165)); + + + /* i=0 */ + { + t0 = CL_add(y[ 0],y[ 8]); + t2 = CL_sub(y[ 0],y[ 8]); + t4 = CL_add(y[ 4],y[12]); + t7 = CL_sub(y[ 4],y[12]); + + input[0] = CL_add(t0,t4); + input[4] = CL_msu_j(t2,t7); + input[8] = CL_sub(t0,t4); + input[12] = CL_mac_j(t2,t7); + } + /* i=1 */ + { + t0 = CL_add(y[ 1],y[ 9]); + t2 = CL_sub(y[ 1],y[ 9]); + t4 = CL_add(y[ 5],y[13]); + t7 = CL_sub(y[ 5],y[13]); + + input[1] = CL_add(t0,t4); + input[5] = CL_msu_j(t2,t7); + input[9] = CL_sub(t0,t4); + input[13] = CL_mac_j(t2,t7); + } + /* i=2 */ + { + t0 = CL_add(y[ 2],y[ 10]); + t2 = CL_sub(y[ 2],y[ 10]); + t4 = CL_add(y[ 6],y[14]); + t7 = CL_sub(y[ 6],y[14]); + + input[2] = CL_add(t0,t4); + input[6] = CL_msu_j(t2,t7); + input[10] = CL_sub(t0,t4); + input[14] = CL_mac_j(t2,t7); + } + /* i=3 */ + { + t0 = CL_add(y[ 3],y[ 11]); + t2 = CL_sub(y[ 3],y[ 11]); + t4 = CL_add(y[ 7],y[15]); + t7 = CL_sub(y[ 7],y[15]); + + input[3] = CL_add(t0,t4); + input[7] = CL_msu_j(t2,t7); + input[11] = CL_sub(t0,t4); + input[15] = CL_mac_j(t2,t7); + } +#if (WMOPS) + multiCounter[currCounter].CL_move += 16; +#endif + +} + + +/** + * \brief Function performs a complex 20-point FFT + * The FFT is performed inplace. The result of the FFT + * is scaled by SCALEFACTOR20 bits. + * + * WOPS with 32x16 bit multiplications: 432 cycles + * + * \param [i/o] re real input / output + * \param [i/o] im imag input / output + * \param [i ] s stride real and imag input / output + * + * \return void + */ +static void fft20_with_cmplx_data(cmplx *inp_data) +{ + cmplx r1,r2,r3,r4; + cmplx x0,x1,x2,x3,x4; + cmplx t,t0,t1,t2,t3; + cmplx y[20]; + cmplx *y0, *y1,*y2,*y3,*y4; + + y0 = y; + y1 = &y[4]; + y2 = &y[16]; + y3 = &y[8]; + y4 = &y[12]; + + { + x0 = CL_shr(inp_data[0],SCALEFACTOR20); + x1 = CL_shr(inp_data[16],SCALEFACTOR20); + x2 = CL_shr(inp_data[12],SCALEFACTOR20); + x3 = CL_shr(inp_data[8],SCALEFACTOR20); + x4 = CL_shr(inp_data[4],SCALEFACTOR20); + + r4 = CL_sub(x1,x4); + r2 = CL_sub(x2,x3); + r1 = CL_add(x1,x4); + r3 = CL_add(x2,x3); + t = CL_scale_t(CL_sub(r1,r3),C54); + r1 = CL_add(r1,r3); + y0[0] = CL_add(x0,r1); + r1 = CL_add(y0[0],(CL_shl(CL_scale_t(r1,C55),1))); + r3 = CL_sub(r1,t); + r1 = CL_add(r1,t); + t = CL_scale_t((CL_add(r4,r2)),C51); + r4 = CL_add(t,CL_shl(CL_scale_t(r4, C52),1)); + r2 = CL_add(t,CL_scale_t(r2,C53)); + + + y1[0] = CL_msu_j(r1,r2); + y2[0] = CL_mac_j(r1,r2); + y3[0] = CL_mac_j(r3,r4); + y4[0] = CL_msu_j(r3,r4); + } + { + x0 = CL_shr(inp_data[5],SCALEFACTOR20); + x1 = CL_shr(inp_data[1],SCALEFACTOR20); + x2 = CL_shr(inp_data[17],SCALEFACTOR20); + x3 = CL_shr(inp_data[13],SCALEFACTOR20); + x4 = CL_shr(inp_data[9],SCALEFACTOR20); + + r4 = CL_sub(x1,x4); + r2 = CL_sub(x2,x3); + r1 = CL_add(x1,x4); + r3 = CL_add(x2,x3); + t = CL_scale_t(CL_sub(r1,r3),C54); + r1 = CL_add(r1,r3); + y0[1] = CL_add(x0,r1); + r1 = CL_add(y0[1],(CL_shl(CL_scale_t(r1,C55),1))); + r3 = CL_sub(r1,t); + r1 = CL_add(r1,t); + t = CL_scale_t((CL_add(r4,r2)),C51); + r4 = CL_add(t,CL_shl(CL_scale_t(r4, C52),1)); + r2 = CL_add(t,CL_scale_t(r2,C53)); + + + y1[1] = CL_msu_j(r1,r2); + y2[1] = CL_mac_j(r1,r2); + y3[1] = CL_mac_j(r3,r4); + y4[1] = CL_msu_j(r3,r4); + } + { + x0 = CL_shr(inp_data[10],SCALEFACTOR20); + x1 = CL_shr(inp_data[6],SCALEFACTOR20); + x2 = CL_shr(inp_data[2],SCALEFACTOR20); + x3 = CL_shr(inp_data[18],SCALEFACTOR20); + x4 = CL_shr(inp_data[14],SCALEFACTOR20); + + r4 = CL_sub(x1,x4); + r2 = CL_sub(x2,x3); + r1 = CL_add(x1,x4); + r3 = CL_add(x2,x3); + t = CL_scale_t(CL_sub(r1,r3),C54); + r1 = CL_add(r1,r3); + y0[2] = CL_add(x0,r1); + r1 = CL_add(y0[2],(CL_shl(CL_scale_t(r1,C55),1))); + r3 = CL_sub(r1,t); + r1 = CL_add(r1,t); + t = CL_scale_t((CL_add(r4,r2)),C51); + r4 = CL_add(t,CL_shl(CL_scale_t(r4, C52),1)); + r2 = CL_add(t,CL_scale_t(r2,C53)); + + + y1[2] = CL_msu_j(r1,r2); + y2[2] = CL_mac_j(r1,r2); + y3[2] = CL_mac_j(r3,r4); + y4[2] = CL_msu_j(r3,r4); + } + { + x0 = CL_shr(inp_data[15],SCALEFACTOR20); + x1 = CL_shr(inp_data[11],SCALEFACTOR20); + x2 = CL_shr(inp_data[7],SCALEFACTOR20); + x3 = CL_shr(inp_data[3],SCALEFACTOR20); + x4 = CL_shr(inp_data[19],SCALEFACTOR20); + + r4 = CL_sub(x1,x4); + r2 = CL_sub(x2,x3); + r1 = CL_add(x1,x4); + r3 = CL_add(x2,x3); + t = CL_scale_t(CL_sub(r1,r3),C54); + r1 = CL_add(r1,r3); + y0[3] = CL_add(x0,r1); + r1 = CL_add(y0[3],(CL_shl(CL_scale_t(r1,C55),1))); + r3 = CL_sub(r1,t); + r1 = CL_add(r1,t); + t = CL_scale_t((CL_add(r4,r2)),C51); + r4 = CL_add(t,CL_shl(CL_scale_t(r4, C52),1)); + r2 = CL_add(t,CL_scale_t(r2,C53)); + + + y1[3] = CL_msu_j(r1,r2); + y2[3] = CL_mac_j(r1,r2); + y3[3] = CL_mac_j(r3,r4); + y4[3] = CL_msu_j(r3,r4); + } + + { + cmplx * ptr_y = y; + { + cmplx Cy0, Cy1, Cy2, Cy3; + + Cy0 = *ptr_y++; + Cy1 = *ptr_y++; + Cy2 = *ptr_y++; + Cy3 = *ptr_y++; + + /* Pre-additions */ + t0 = CL_add(Cy0,Cy2); + t1 = CL_sub(Cy0,Cy2); + t2 = CL_add(Cy1,Cy3); + t3 = CL_sub(Cy1,Cy3); + + + inp_data[0] = CL_add(t0,t2); + inp_data[5] = CL_msu_j(t1,t3); + inp_data[10] = CL_sub(t0,t2); + inp_data[15] = CL_mac_j(t1,t3); + } + + { + cmplx Cy0, Cy1, Cy2, Cy3; + + Cy0 = *ptr_y++; + Cy1 = *ptr_y++; + Cy2 = *ptr_y++; + Cy3 = *ptr_y++; + + /* Pre-additions */ + t0 = CL_add(Cy0,Cy2); + t1 = CL_sub(Cy0,Cy2); + t2 = CL_add(Cy1,Cy3); + t3 = CL_sub(Cy1,Cy3); + + + inp_data[4] = CL_add(t0,t2); + inp_data[9] = CL_msu_j(t1,t3); + inp_data[14] = CL_sub(t0,t2); + inp_data[19] = CL_mac_j(t1,t3); + } + + { + cmplx Cy0, Cy1, Cy2, Cy3; + + Cy0 = *ptr_y++; + Cy1 = *ptr_y++; + Cy2 = *ptr_y++; + Cy3 = *ptr_y++; + + /* Pre-additions */ + t0 = CL_add(Cy0,Cy2); + t1 = CL_sub(Cy0,Cy2); + t2 = CL_add(Cy1,Cy3); + t3 = CL_sub(Cy1,Cy3); + + + inp_data[8] = CL_add(t0,t2); + inp_data[13] = CL_msu_j(t1,t3); + inp_data[18] = CL_sub(t0,t2); + inp_data[3] = CL_mac_j(t1,t3); + } + + { + cmplx Cy0, Cy1, Cy2, Cy3; + + Cy0 = *ptr_y++; + Cy1 = *ptr_y++; + Cy2 = *ptr_y++; + Cy3 = *ptr_y++; + + /* Pre-additions */ + t0 = CL_add(Cy0,Cy2); + t1 = CL_sub(Cy0,Cy2); + t2 = CL_add(Cy1,Cy3); + t3 = CL_sub(Cy1,Cy3); + + inp_data[12] = CL_add(t0,t2); + inp_data[17] = CL_msu_j(t1,t3); + inp_data[2] = CL_sub(t0,t2); + inp_data[7] = CL_mac_j(t1,t3); + } + + { + cmplx Cy0, Cy1, Cy2, Cy3; + + Cy0 = *ptr_y++; + Cy1 = *ptr_y++; + Cy2 = *ptr_y++; + Cy3 = *ptr_y++; + + /* Pre-additions */ + t0 = CL_add(Cy0,Cy2); + t1 = CL_sub(Cy0,Cy2); + t2 = CL_add(Cy1,Cy3); + t3 = CL_sub(Cy1,Cy3); + + + inp_data[16] = CL_add(t0,t2); + inp_data[1] = CL_msu_j(t1,t3); + inp_data[6] = CL_sub(t0,t2); + inp_data[11] = CL_mac_j(t1,t3); + } + } +#if (WMOPS) + multiCounter[currCounter].CL_move += 20; +#endif + +} + + +/** + * \brief Function performs a complex 30-point FFT + * The FFT is performed inplace. The result of the FFT + * is scaled by SCALEFACTOR30 bits. + * + * WOPS with 32x16 bit multiplications: 828 cycles + * + * \param [i/o] re real input / output + * \param [i/o] im imag input / output + * \param [i ] s stride real and imag input / output + * + * \return void + */ + +static void fft30_with_cmplx_data(cmplx * inp) +{ + cmplx *l = &inp[0]; + cmplx *h = &inp[15]; + + cmplx z[30], y[15], x[15], rs1, rs2, rs3, rs4, t; + + /* 1. FFT15 stage */ + + x[0] = CL_shr(inp[0],SCALEFACTOR30_1); + x[1] = CL_shr(inp[18],SCALEFACTOR30_1); + x[2] = CL_shr(inp[6],SCALEFACTOR30_1); + x[3] = CL_shr(inp[24],SCALEFACTOR30_1); + x[4] = CL_shr(inp[12],SCALEFACTOR30_1); + + x[5] = CL_shr(inp[20],SCALEFACTOR30_1); + x[6] = CL_shr(inp[8],SCALEFACTOR30_1); + x[7] = CL_shr(inp[26],SCALEFACTOR30_1); + x[8] = CL_shr(inp[14],SCALEFACTOR30_1); + x[9] = CL_shr(inp[2],SCALEFACTOR30_1); + + x[10] = CL_shr(inp[10],SCALEFACTOR30_1); + x[11] = CL_shr(inp[28],SCALEFACTOR30_1); + x[12] = CL_shr(inp[16],SCALEFACTOR30_1); + x[13] = CL_shr(inp[4],SCALEFACTOR30_1); + x[14] = CL_shr(inp[22],SCALEFACTOR30_1); + + + /* 1. FFT5 stage */ + rs1 = CL_add(x[1],x[4]); + rs4 = CL_sub(x[1],x[4]); + rs3 = CL_add(x[2],x[3]); + rs2 = CL_sub(x[2],x[3]); + t = CL_scale_t(CL_sub(rs1,rs3),C54); + rs1 = CL_add(rs1,rs3); + y[0] = CL_add(x[0],rs1); + rs1 = CL_add(y[0],(CL_shl(CL_scale_t(rs1,C55),1))); + rs3 = CL_sub(rs1,t); + rs1 = CL_add(rs1,t); + t = CL_scale_t(CL_add(rs4,rs2),C51); + rs4 = CL_add(t,CL_shl(CL_scale_t(rs4, C52),1)); + rs2 = CL_add(t,CL_scale_t(rs2,C53)); + + /* combination */ + y[1] = CL_msu_j(rs1,rs2); + y[4] = CL_mac_j(rs1,rs2); + y[2] = CL_mac_j(rs3,rs4); + y[3] = CL_msu_j(rs3,rs4); + + + /* 2. FFT5 stage */ + rs1 = CL_add(x[6],x[9]); + rs4 = CL_sub(x[6],x[9]); + rs3 = CL_add(x[7],x[8]); + rs2 = CL_sub(x[7],x[8]); + t = CL_scale_t(CL_sub(rs1,rs3),C54); + rs1 = CL_add(rs1,rs3); + y[5] = CL_add(x[5],rs1); + rs1 = CL_add(y[5],(CL_shl(CL_scale_t(rs1,C55),1))); + rs3 = CL_sub(rs1,t); + rs1 = CL_add(rs1,t); + t = CL_scale_t(CL_add(rs4,rs2),C51); + rs4 = CL_add(t,CL_shl(CL_scale_t(rs4, C52),1)); + rs2 = CL_add(t,CL_scale_t(rs2,C53)); + + /* combination */ + y[6] = CL_msu_j(rs1,rs2); + y[9] = CL_mac_j(rs1,rs2); + y[7] = CL_mac_j(rs3,rs4); + y[8] = CL_msu_j(rs3,rs4); + + + /* 3. FFT5 stage */ + rs1 = CL_add(x[11],x[14]); + rs4 = CL_sub(x[11],x[14]); + rs3 = CL_add(x[12],x[13]); + rs2 = CL_sub(x[12],x[13]); + t = CL_scale_t(CL_sub(rs1,rs3),C54); + rs1 = CL_add(rs1,rs3); + y[10] = CL_add(x[10],rs1); + rs1 = CL_add(y[10],(CL_shl(CL_scale_t(rs1,C55),1))); + rs3 = CL_sub(rs1,t); + rs1 = CL_add(rs1,t); + t = CL_scale_t(CL_add(rs4,rs2),C51); + rs4 = CL_add(t,CL_shl(CL_scale_t(rs4, C52),1)); + rs2 = CL_add(t,CL_scale_t(rs2,C53)); + + /* combination */ + y[11] = CL_msu_j(rs1,rs2); + y[14] = CL_mac_j(rs1,rs2); + y[12] = CL_mac_j(rs3,rs4); + y[13] = CL_msu_j(rs3,rs4); + /*for (i=10; i<15; i++) + { + printf("%d,\t %d,\t",y[i].re, y[i].im); + } + printf("\n\n");*/ + + + /* 1. FFT3 stage */ + /* real part */ + rs1 = CL_add(y[5],y[10]); + rs2 = CL_scale_t(CL_sub(y[5],y[10]),C31); + z[0] = CL_add(y[0],rs1); + rs1 = CL_sub(y[0],CL_shr(rs1,1)); + + z[10] = CL_mac_j(rs1,rs2); + z[5] = CL_msu_j(rs1,rs2); + + /* 2. FFT3 stage */ + rs1 = CL_add(y[6],y[11]); + rs2 = CL_scale_t(CL_sub(y[6],y[11]),C31); + z[6] = CL_add(y[1],rs1); + rs1 = CL_sub(y[1],CL_shr(rs1,1)); + + z[1] = CL_mac_j(rs1,rs2); + z[11] = CL_msu_j(rs1,rs2); + + + /* 3. FFT3 stage */ + rs1 = CL_add(y[7],y[12]); + rs2 = CL_scale_t(CL_sub(y[7],y[12]),C31); + z[12] = CL_add(y[2],rs1); + rs1 = CL_sub(y[2],CL_shr(rs1,1)); + + z[7] = CL_mac_j(rs1,rs2); + z[2] = CL_msu_j(rs1,rs2); + + + /* 4. FFT3 stage */ + rs1 = CL_add(y[8],y[13]); + rs2 = CL_scale_t(CL_sub(y[8],y[13]),C31); + z[3] = CL_add(y[3],rs1); + rs1 = CL_sub(y[3],CL_shr(rs1,1)); + + z[13] = CL_mac_j(rs1,rs2); + z[8] = CL_msu_j(rs1,rs2); + + + /* 5. FFT3 stage */ + rs1 = CL_add(y[9],y[14]); + rs2 = CL_scale_t(CL_sub(y[9],y[14]),C31); + z[9] = CL_add(y[4],rs1); + rs1 = CL_sub(y[4],CL_shr(rs1,1)); + + z[4] = CL_mac_j(rs1,rs2); + z[14] = CL_msu_j(rs1,rs2); + + /*for (i=0; i<15; i++) + printf("%d,\t %d,\t",z[i].re, z[i].im); + printf("\n\n");*/ + + + /* 2. FFT15 stage */ + + x[0] = CL_shr(inp[15],SCALEFACTOR30_1); + x[1] = CL_shr(inp[3],SCALEFACTOR30_1); + x[2] = CL_shr(inp[21],SCALEFACTOR30_1); + x[3] = CL_shr(inp[9],SCALEFACTOR30_1); + x[4] = CL_shr(inp[27],SCALEFACTOR30_1); + + x[5] = CL_shr(inp[5],SCALEFACTOR30_1); + x[6] = CL_shr(inp[23],SCALEFACTOR30_1); + x[7] = CL_shr(inp[11],SCALEFACTOR30_1); + x[8] = CL_shr(inp[29],SCALEFACTOR30_1); + x[9] = CL_shr(inp[17],SCALEFACTOR30_1); + + x[10] = CL_shr(inp[25],SCALEFACTOR30_1); + x[11] = CL_shr(inp[13],SCALEFACTOR30_1); + x[12] = CL_shr(inp[1],SCALEFACTOR30_1); + x[13] = CL_shr(inp[19],SCALEFACTOR30_1); + x[14] = CL_shr(inp[7],SCALEFACTOR30_1); + + /* 1. FFT5 stage */ + rs1 = CL_add(x[1],x[4]); + rs4 = CL_sub(x[1],x[4]); + rs3 = CL_add(x[2],x[3]); + rs2 = CL_sub(x[2],x[3]); + t = CL_scale_t(CL_sub(rs1,rs3),C54); + rs1 = CL_add(rs1,rs3); + y[0] = CL_add(x[0],rs1); + rs1 = CL_add(y[0],(CL_shl(CL_scale_t(rs1,C55),1))); + rs3 = CL_sub(rs1,t); + rs1 = CL_add(rs1,t); + t = CL_scale_t(CL_add(rs4,rs2),C51); + rs4 = CL_add(t,CL_shl(CL_scale_t(rs4, C52),1)); + rs2 = CL_add(t,CL_scale_t(rs2,C53)); + + /* combination */ + y[1] = CL_msu_j(rs1,rs2); + y[4] = CL_mac_j(rs1,rs2); + y[2] = CL_mac_j(rs3,rs4); + y[3] = CL_msu_j(rs3,rs4); + + + /* 2. FFT5 stage */ + rs1 = CL_add(x[6],x[9]); + rs4 = CL_sub(x[6],x[9]); + rs3 = CL_add(x[7],x[8]); + rs2 = CL_sub(x[7],x[8]); + t = CL_scale_t(CL_sub(rs1,rs3),C54); + rs1 = CL_add(rs1,rs3); + y[5] = CL_add(x[5],rs1); + rs1 = CL_add(y[5],(CL_shl(CL_scale_t(rs1,C55),1))); + rs3 = CL_sub(rs1,t); + rs1 = CL_add(rs1,t); + t = CL_scale_t(CL_add(rs4,rs2),C51); + rs4 = CL_add(t,CL_shl(CL_scale_t(rs4, C52),1)); + rs2 = CL_add(t,CL_scale_t(rs2,C53)); + + /* combination */ + y[6] = CL_msu_j(rs1,rs2); + y[9] = CL_mac_j(rs1,rs2); + y[7] = CL_mac_j(rs3,rs4); + y[8] = CL_msu_j(rs3,rs4); + + + /* 3. FFT5 stage */ + rs1 = CL_add(x[11],x[14]); + rs4 = CL_sub(x[11],x[14]); + rs3 = CL_add(x[12],x[13]); + rs2 = CL_sub(x[12],x[13]); + t = CL_scale_t(CL_sub(rs1,rs3),C54); + rs1 = CL_add(rs1,rs3); + y[10] = CL_add(x[10],rs1); + rs1 = CL_add(y[10],(CL_shl(CL_scale_t(rs1,C55),1))); + rs3 = CL_sub(rs1,t); + rs1 = CL_add(rs1,t); + t = CL_scale_t(CL_add(rs4,rs2),C51); + rs4 = CL_add(t,CL_shl(CL_scale_t(rs4, C52),1)); + rs2 = CL_add(t,CL_scale_t(rs2,C53)); + + /* combination */ + y[11] = CL_msu_j(rs1,rs2); + y[14] = CL_mac_j(rs1,rs2); + y[12] = CL_mac_j(rs3,rs4); + y[13] = CL_msu_j(rs3,rs4); + /*for (i=10; i<15; i++) + { + printf("%d,\t %d,\t",y[i].re, y[i].im); + } + printf("\n\n");*/ + + + /* 1. FFT3 stage */ + /* real part */ + rs1 = CL_add(y[5],y[10]); + rs2 = CL_scale_t(CL_sub(y[5],y[10]),C31); + z[15] = CL_add(y[0],rs1); + rs1 = CL_sub(y[0],CL_shr(rs1,1)); + + z[25] = CL_mac_j(rs1,rs2); + z[20] = CL_msu_j(rs1,rs2); + + /* 2. FFT3 stage */ + rs1 = CL_add(y[6],y[11]); + rs2 = CL_scale_t(CL_sub(y[6],y[11]),C31); + z[21] = CL_add(y[1],rs1); + rs1 = CL_sub(y[1],CL_shr(rs1,1)); + + z[16] = CL_mac_j(rs1,rs2); + z[26] = CL_msu_j(rs1,rs2); + + + /* 3. FFT3 stage */ + rs1 = CL_add(y[7],y[12]); + rs2 = CL_scale_t(CL_sub(y[7],y[12]),C31); + z[27] = CL_add(y[2],rs1); + rs1 = CL_sub(y[2],CL_shr(rs1,1)); + + z[22] = CL_mac_j(rs1,rs2); + z[17] = CL_msu_j(rs1,rs2); + + + /* 4. FFT3 stage */ + rs1 = CL_add(y[8],y[13]); + rs2 = CL_scale_t(CL_sub(y[8],y[13]),C31); + z[18] = CL_add(y[3],rs1); + rs1 = CL_sub(y[3],CL_shr(rs1,1)); + + z[28] = CL_mac_j(rs1,rs2); + z[23] = CL_msu_j(rs1,rs2); + + + /* 5. FFT3 stage */ + rs1 = CL_add(y[9],y[14]); + rs2 = CL_scale_t(CL_sub(y[9],y[14]),C31); + z[24] = CL_add(y[4],rs1); + rs1 = CL_sub(y[4],CL_shr(rs1,1)); + + z[19] = CL_mac_j(rs1,rs2); + z[29] = CL_msu_j(rs1,rs2); + + /*for (i=0; i<30; i++) + printf("%d,\t %d,\t",z[i].re, z[i].im); + printf("\n\n");*/ + + + /* 1. FFT2 stage */ + rs1 = CL_shr(z[0], SCALEFACTOR30_2); + rs2 = CL_shr(z[15],SCALEFACTOR30_2); + *l = CL_add(rs1,rs2); + *h = CL_sub(rs1,rs2); + l+=1; h+=1; + + /* 2. FFT2 stage */ + rs1 = CL_shr(z[8], SCALEFACTOR30_2); + rs2 = CL_shr(z[23],SCALEFACTOR30_2); + *h = CL_add(rs1,rs2); + *l = CL_sub(rs1,rs2); + l+=1; h+=1; + + + /* 3. FFT2 stage */ + rs1 = CL_shr(z[1], SCALEFACTOR30_2); + rs2 = CL_shr(z[16],SCALEFACTOR30_2); + *l = CL_add(rs1,rs2); + *h = CL_sub(rs1,rs2); + l+=1; h+=1; + + + /* 4. FFT2 stage */ + rs1 = CL_shr(z[9], SCALEFACTOR30_2); + rs2 = CL_shr(z[24],SCALEFACTOR30_2); + *h = CL_add(rs1,rs2); + *l = CL_sub(rs1,rs2); + l+=1; h+=1; + + /* 5. FFT2 stage */ + rs1 = CL_shr(z[2], SCALEFACTOR30_2); + rs2 = CL_shr(z[17],SCALEFACTOR30_2); + *l = CL_add(rs1,rs2); + *h = CL_sub(rs1,rs2); + l+=1; h+=1; + + /* 6. FFT2 stage */ + rs1 = CL_shr(z[10], SCALEFACTOR30_2); + rs2 = CL_shr(z[25],SCALEFACTOR30_2); + *h = CL_add(rs1,rs2); + *l = CL_sub(rs1,rs2); + l+=1; h+=1; + + /* 7. FFT2 stage */ + rs1 = CL_shr(z[3], SCALEFACTOR30_2); + rs2 = CL_shr(z[18],SCALEFACTOR30_2); + *l = CL_add(rs1,rs2); + *h = CL_sub(rs1,rs2); + l+=1; h+=1; + + /* 8. FFT2 stage */ + rs1 = CL_shr(z[11], SCALEFACTOR30_2); + rs2 = CL_shr(z[26],SCALEFACTOR30_2); + *h = CL_add(rs1,rs2); + *l = CL_sub(rs1,rs2); + l+=1; h+=1; + + /* 9. FFT2 stage */ + rs1 = CL_shr(z[4], SCALEFACTOR30_2); + rs2 = CL_shr(z[19],SCALEFACTOR30_2); + *l = CL_add(rs1,rs2); + *h = CL_sub(rs1,rs2); + l+=1; h+=1; + + /* 10. FFT2 stage */ + rs1 = CL_shr(z[12], SCALEFACTOR30_2); + rs2 = CL_shr(z[27],SCALEFACTOR30_2); + *h = CL_add(rs1,rs2); + *l = CL_sub(rs1,rs2); + l+=1; h+=1; + + /* 11. FFT2 stage */ + rs1 = CL_shr(z[5], SCALEFACTOR30_2); + rs2 = CL_shr(z[20],SCALEFACTOR30_2); + *l = CL_add(rs1,rs2); + *h = CL_sub(rs1,rs2); + l+=1; h+=1; + + /* 12. FFT2 stage */ + rs1 = CL_shr(z[13], SCALEFACTOR30_2); + rs2 = CL_shr(z[28],SCALEFACTOR30_2); + *h = CL_add(rs1,rs2); + *l = CL_sub(rs1,rs2); + l+=1; h+=1; + + /* 13. FFT2 stage */ + rs1 = CL_shr(z[6], SCALEFACTOR30_2); + rs2 = CL_shr(z[21],SCALEFACTOR30_2); + *l = CL_add(rs1,rs2); + *h = CL_sub(rs1,rs2); + l+=1; h+=1; + + /* 14. FFT2 stage */ + rs1 = CL_shr(z[14], SCALEFACTOR30_2); + rs2 = CL_shr(z[29],SCALEFACTOR30_2); + *h = CL_add(rs1,rs2); + *l = CL_sub(rs1,rs2); + l+=1; h+=1; + + /* 15. FFT2 stage */ + rs1 = CL_shr(z[7], SCALEFACTOR30_2); + rs2 = CL_shr(z[22],SCALEFACTOR30_2); + *l = CL_add(rs1,rs2); + *h = CL_sub(rs1,rs2); + l+=1; h+=1; + +#if (WMOPS) + multiCounter[currCounter].CL_move += 30; +#endif + +} + +/** + * \brief Function performs a complex 32-point FFT + * The FFT is performed inplace. The result of the FFT + * is scaled by SCALEFACTOR32 bits. + * + * WOPS with 32x16 bit multiplications: 752 cycles + * + * \param [i/o] re real input / output + * \param [i/o] im imag input / output + * \param [i ] s stride real and imag input / output + * + * \return void + */ + + +static void fft32_with_cmplx_data(cmplx * inp) +{ + cmplx x[32], y[32], t[32], s[32], temp, temp1; + const cmplx_s *pRotVector_32 = ( const cmplx_s *)RotVector_32; + + /* 1. FFT8 stage */ + + x[0] = CL_shr(inp[0], SCALEFACTOR32_1); + x[1] = CL_shr(inp[4], SCALEFACTOR32_1); + x[2] = CL_shr(inp[8], SCALEFACTOR32_1); + x[3] = CL_shr(inp[12], SCALEFACTOR32_1); + x[4] = CL_shr(inp[16], SCALEFACTOR32_1); + x[5] = CL_shr(inp[20], SCALEFACTOR32_1); + x[6] = CL_shr(inp[24], SCALEFACTOR32_1); + x[7] = CL_shr(inp[28], SCALEFACTOR32_1); + + + t[0] = CL_add(x[0],x[4]); + t[1] = CL_sub(x[0],x[4]); + t[2] = CL_add(x[1],x[5]); + t[3] = CL_sub(x[1],x[5]); + t[4] = CL_add(x[2],x[6]); + t[5] = CL_sub(x[2],x[6]); + t[6] = CL_add(x[3],x[7]); + t[7] = CL_sub(x[3],x[7]); + + /* Pre-additions and core multiplications */ + + s[0] = CL_add(t[0], t[4]); + s[2] = CL_sub(t[0], t[4]); + s[4] = CL_mac_j(t[1], t[5]); + s[5] = CL_msu_j(t[1], t[5]); + s[1] = CL_add(t[2], t[6]); + s[3] = CL_sub(t[2], t[6]); + s[3] = CL_mul_j(s[3]); + + temp = CL_add(t[3], t[7]); + temp1 = CL_sub(t[3], t[7]); + s[6] = CL_scale_t(CL_msu_j(temp1, temp), C81); + s[7] = CL_dscale_t(CL_swap_real_imag( CL_msu_j(temp, temp1)), C81, C82); + + + y[0] = CL_add(s[0],s[1]); + y[4] = CL_sub(s[0],s[1]); + y[2] = CL_sub(s[2],s[3]); + y[6] = CL_add(s[2],s[3]); + y[3] = CL_add(s[4],s[7]); + y[7] = CL_sub(s[4],s[7]); + y[1] = CL_add(s[5],s[6]); + y[5] = CL_sub(s[5],s[6]); + + /* 2. FFT8 stage */ + + x[0] = CL_shr(inp[1], SCALEFACTOR32_1); + x[1] = CL_shr(inp[5], SCALEFACTOR32_1); + x[2] = CL_shr(inp[9], SCALEFACTOR32_1); + x[3] = CL_shr(inp[13], SCALEFACTOR32_1); + x[4] = CL_shr(inp[17], SCALEFACTOR32_1); + x[5] = CL_shr(inp[21], SCALEFACTOR32_1); + x[6] = CL_shr(inp[25], SCALEFACTOR32_1); + x[7] = CL_shr(inp[29], SCALEFACTOR32_1); + + + t[0] = CL_add(x[0],x[4]); + t[1] = CL_sub(x[0],x[4]); + t[2] = CL_add(x[1],x[5]); + t[3] = CL_sub(x[1],x[5]); + t[4] = CL_add(x[2],x[6]); + t[5] = CL_sub(x[2],x[6]); + t[6] = CL_add(x[3],x[7]); + t[7] = CL_sub(x[3],x[7]); + + /* Pre-additions and core multiplications */ + + s[0] = CL_add(t[0], t[4]); + s[2] = CL_sub(t[0], t[4]); + s[4] = CL_mac_j(t[1], t[5]); + s[5] = CL_msu_j(t[1], t[5]); + s[1] = CL_add(t[2], t[6]); + s[3] = CL_sub(t[2], t[6]); + s[3] = CL_mul_j(s[3]); + + temp = CL_add(t[3], t[7]); + temp1 = CL_sub(t[3], t[7]); + s[6] = CL_scale_t(CL_msu_j(temp1, temp), C81); + s[7] = CL_dscale_t(CL_swap_real_imag( CL_msu_j(temp, temp1)), C81, C82); + + /* Post-additions */ + + y[8] = CL_add(s[0],s[1]); + y[12] = CL_sub(s[0],s[1]); + y[10] = CL_sub(s[2],s[3]); + y[14] = CL_add(s[2],s[3]); + y[11] = CL_add(s[4],s[7]); + y[15] = CL_sub(s[4],s[7]); + y[9] = CL_add(s[5],s[6]); + y[13] = CL_sub(s[5],s[6]); + + /* 3. FFT8 stage */ + + x[0] = CL_shr(inp[2], SCALEFACTOR32_1); + x[1] = CL_shr(inp[6], SCALEFACTOR32_1); + x[2] = CL_shr(inp[10], SCALEFACTOR32_1); + x[3] = CL_shr(inp[14], SCALEFACTOR32_1); + x[4] = CL_shr(inp[18], SCALEFACTOR32_1); + x[5] = CL_shr(inp[22], SCALEFACTOR32_1); + x[6] = CL_shr(inp[26], SCALEFACTOR32_1); + x[7] = CL_shr(inp[30], SCALEFACTOR32_1); + + + t[0] = CL_add(x[0],x[4]); + t[1] = CL_sub(x[0],x[4]); + t[2] = CL_add(x[1],x[5]); + t[3] = CL_sub(x[1],x[5]); + t[4] = CL_add(x[2],x[6]); + t[5] = CL_sub(x[2],x[6]); + t[6] = CL_add(x[3],x[7]); + t[7] = CL_sub(x[3],x[7]); + + /* Pre-additions and core multiplications */ + + s[0] = CL_add(t[0], t[4]); + s[2] = CL_sub(t[0], t[4]); + s[4] = CL_mac_j(t[1], t[5]); + s[5] = CL_msu_j(t[1], t[5]); + s[1] = CL_add(t[2], t[6]); + s[3] = CL_sub(t[2], t[6]); + s[3] = CL_mul_j(s[3]); + + temp = CL_add(t[3], t[7]); + temp1 = CL_sub(t[3], t[7]); + s[6] = CL_scale_t(CL_msu_j(temp1, temp), C81); + s[7] = CL_dscale_t(CL_swap_real_imag( CL_msu_j(temp, temp1)), C81, C82); + + /* Post-additions */ + + y[16] = CL_add(s[0],s[1]); + y[20] = CL_sub(s[0],s[1]); + y[18] = CL_sub(s[2],s[3]); + y[22] = CL_add(s[2],s[3]); + y[19] = CL_add(s[4],s[7]); + y[23] = CL_sub(s[4],s[7]); + y[17] = CL_add(s[5],s[6]); + y[21] = CL_sub(s[5],s[6]); + + /* 4. FFT8 stage */ + + x[0] = CL_shr(inp[3], SCALEFACTOR32_1); + x[1] = CL_shr(inp[7], SCALEFACTOR32_1); + x[2] = CL_shr(inp[11], SCALEFACTOR32_1); + x[3] = CL_shr(inp[15], SCALEFACTOR32_1); + x[4] = CL_shr(inp[19], SCALEFACTOR32_1); + x[5] = CL_shr(inp[23], SCALEFACTOR32_1); + x[6] = CL_shr(inp[27], SCALEFACTOR32_1); + x[7] = CL_shr(inp[31], SCALEFACTOR32_1); + + + t[0] = CL_add(x[0],x[4]); + t[1] = CL_sub(x[0],x[4]); + t[2] = CL_add(x[1],x[5]); + t[3] = CL_sub(x[1],x[5]); + t[4] = CL_add(x[2],x[6]); + t[5] = CL_sub(x[2],x[6]); + t[6] = CL_add(x[3],x[7]); + t[7] = CL_sub(x[3],x[7]); + + + /* Pre-additions and core multiplications */ + + s[0] = CL_add(t[0], t[4]); + s[2] = CL_sub(t[0], t[4]); + s[4] = CL_mac_j(t[1], t[5]); + s[5] = CL_msu_j(t[1], t[5]); + s[1] = CL_add(t[2], t[6]); + s[3] = CL_sub(t[2], t[6]); + s[3] = CL_mul_j(s[3]); + + temp = CL_add(t[3], t[7]); + temp1 = CL_sub(t[3], t[7]); + s[6] = CL_scale_t(CL_msu_j(temp1, temp), C81); + s[7] = CL_dscale_t(CL_swap_real_imag( CL_msu_j(temp, temp1)), C81, C82); + + /* Post-additions */ + + y[24] = CL_add(s[0],s[1]); + y[28] = CL_sub(s[0],s[1]); + y[26] = CL_sub(s[2],s[3]); + y[30] = CL_add(s[2],s[3]); + y[27] = CL_add(s[4],s[7]); + y[31] = CL_sub(s[4],s[7]); + y[25] = CL_add(s[5],s[6]); + y[29] = CL_sub(s[5],s[6]); + + + /* apply twiddle factors */ + y[0] = CL_shr(y[0],SCALEFACTOR32_2); + y[1] = CL_shr(y[1],SCALEFACTOR32_2); + y[2] = CL_shr(y[2],SCALEFACTOR32_2); + y[3] = CL_shr(y[3],SCALEFACTOR32_2); + y[4] = CL_shr(y[4],SCALEFACTOR32_2); + y[5] = CL_shr(y[5],SCALEFACTOR32_2); + y[6] = CL_shr(y[6],SCALEFACTOR32_2); + y[7] = CL_shr(y[7],SCALEFACTOR32_2); + y[8] = CL_shr(y[8],SCALEFACTOR32_2); + y[16] = CL_shr(y[16],SCALEFACTOR32_2); + y[24] = CL_shr(y[24],SCALEFACTOR32_2); + y[20] = CL_shr(y[20],SCALEFACTOR32_2); + + + y[9] = CL_mult_32x16((CL_shr(y[9],1)), pRotVector_32[ 0 ]); + y[10] = CL_mult_32x16((CL_shr(y[10],1)), pRotVector_32[ 1 ]); + y[11] = CL_mult_32x16((CL_shr(y[11],1)), pRotVector_32[ 2 ]); + y[12] = CL_mult_32x16((CL_shr(y[12],1)), pRotVector_32[ 3 ]); + y[13] = CL_mult_32x16((CL_shr(y[13],1)), pRotVector_32[ 4 ]); + y[14] = CL_mult_32x16((CL_shr(y[14],1)), pRotVector_32[ 5 ]); + y[15] = CL_mult_32x16((CL_shr(y[15],1)), pRotVector_32[ 6 ]); + y[17] = CL_mult_32x16((CL_shr(y[17],1)), pRotVector_32[ 7 ]); + y[18] = CL_mult_32x16((CL_shr(y[18],1)), pRotVector_32[ 8 ]); + y[19] = CL_mult_32x16((CL_shr(y[19],1)), pRotVector_32[ 9 ]); + y[21] = CL_mult_32x16((CL_shr(y[21],1)), pRotVector_32[ 10 ]); + y[22] = CL_mult_32x16((CL_shr(y[22],1)), pRotVector_32[ 11 ]); + y[23] = CL_mult_32x16((CL_shr(y[23],1)), pRotVector_32[ 12 ]); + y[25] = CL_mult_32x16((CL_shr(y[25],1)), pRotVector_32[ 13 ]); + y[26] = CL_mult_32x16((CL_shr(y[26],1)), pRotVector_32[ 14 ]); + y[27] = CL_mult_32x16((CL_shr(y[27],1)), pRotVector_32[ 15 ]); + y[28] = CL_mult_32x16((CL_shr(y[28],1)), pRotVector_32[ 16 ]); + y[29] = CL_mult_32x16((CL_shr(y[29],1)), pRotVector_32[ 17 ]); + y[30] = CL_mult_32x16((CL_shr(y[30],1)), pRotVector_32[ 18 ]); + y[31] = CL_mult_32x16((CL_shr(y[31],1)), pRotVector_32[ 19 ]); + + /* 1. FFT4 stage */ + + /* Pre-additions */ + t[0] = CL_add(y[0],y[16]); + t[1] = CL_sub(y[0],y[16]); + t[2] = CL_add(y[8],y[24]); + t[3] = CL_mul_j(CL_sub(y[8],y[24])); + + /* Post-additions */ + inp[0] = CL_add(t[0], t[2]); + inp[8] = CL_sub(t[1], t[3]); + inp[16] = CL_sub(t[0], t[2]); + inp[24] = CL_add(t[1], t[3]); + + /* 2. FFT4 stage */ + + /* Pre-additions */ + t[0] = CL_add(y[1],y[17]); + t[1] = CL_sub(y[1],y[17]); + t[2] = CL_add(y[9],y[25]); + t[3] = CL_mul_j(CL_sub(y[9],y[25])); + + /* Post-additions */ + inp[1] = CL_add(t[0], t[2]); + inp[9] = CL_sub(t[1], t[3]); + inp[17] = CL_sub(t[0], t[2]); + inp[25] = CL_add(t[1], t[3]); + + + /* 3. FFT4 stage */ + + /* Pre-additions */ + t[0] = CL_add(y[2],y[18]); + t[1] = CL_sub(y[2],y[18]); + t[2] = CL_add(y[10],y[26]); + t[3] = CL_mul_j(CL_sub(y[10],y[26])); + + /* Post-additions */ + inp[2] = CL_add(t[0], t[2]); + inp[10] = CL_sub(t[1], t[3]); + inp[18] = CL_sub(t[0], t[2]); + inp[26] = CL_add(t[1], t[3]); + + + /* 4. FFT4 stage */ + + /* Pre-additions */ + t[0] = CL_add(y[3],y[19]); + t[1] = CL_sub(y[3],y[19]); + t[2] = CL_add(y[11],y[27]); + t[3] = CL_mul_j(CL_sub(y[11],y[27])); + + + /* Post-additions */ + inp[3] = CL_add(t[0], t[2]); + inp[11] = CL_sub(t[1], t[3]); + inp[19] = CL_sub(t[0], t[2]); + inp[27] = CL_add(t[1], t[3]); + + + /* 5. FFT4 stage */ + + /* Pre-additions */ + t[0] = CL_msu_j(y[4],y[20]); + t[1] = CL_mac_j(y[4],y[20]); + t[2] = CL_add(y[12],y[28]); + t[3] = CL_mul_j(CL_sub(y[12],y[28])); + + + /* Post-additions */ + inp[4] = CL_add(t[0], t[2]); + inp[12] = CL_sub(t[1], t[3]); + inp[20] = CL_sub(t[0], t[2]); + inp[28] = CL_add(t[1], t[3]); + + + /* 6. FFT4 stage */ + + /* Pre-additions */ + t[0] = CL_add(y[5],y[21]); + t[1] = CL_sub(y[5],y[21]); + t[2] = CL_add(y[13],y[29]); + t[3] = CL_mul_j(CL_sub(y[13],y[29])); + + + /* Post-additions */ + inp[5] = CL_add(t[0], t[2]); + inp[13] = CL_sub(t[1], t[3]); + inp[21] = CL_sub(t[0], t[2]); + inp[29] = CL_add(t[1], t[3]); + + + /* 7. FFT4 stage */ + + /* Pre-additions */ + t[0] = CL_add(y[6],y[22]); + t[1] = CL_sub(y[6],y[22]); + t[2] = CL_add(y[14],y[30]); + t[3] = CL_mul_j(CL_sub(y[14],y[30])); + + + /* Post-additions */ + inp[6] = CL_add(t[0], t[2]); + inp[14] = CL_sub(t[1], t[3]); + inp[22] = CL_sub(t[0], t[2]); + inp[30] = CL_add(t[1], t[3]); + + + /* 8. FFT4 stage */ + + /* Pre-additions */ + t[0] = CL_add(y[7],y[23]); + t[1] = CL_sub(y[7],y[23]); + t[2] = CL_add(y[15],y[31]); + t[3] = CL_mul_j(CL_sub(y[15],y[31])); + + + /* Post-additions */ + inp[7] = CL_add(t[0], t[2]); + inp[15] = CL_sub(t[1], t[3]); + inp[23] = CL_sub(t[0], t[2]); + inp[31] = CL_add(t[1], t[3]); + +#if (WMOPS) + multiCounter[currCounter].CL_move += 32; +#endif + + +} + + +/** + * \brief Combined FFT + * + * \param [i/o] re real part + * \param [i/o] im imag part + * \param [i ] W rotation factor + * \param [i ] len length of fft + * \param [i ] dim1 length of fft1 + * \param [i ] dim2 length of fft2 + * \param [i ] sx stride real and imag part + * \param [i ] sc stride phase rotation coefficients + * \param [tmp] x 32-bit workbuffer of length=2*len + * \param [i ] Woff offset for addressing the rotation vector table + * + * \return void + */ + +static void fftN2( + cmplx *__restrict pComplexBuf, + const Word16 *__restrict W, + Word16 len, + Word16 dim1, + Word16 dim2, + Word16 sc, + Word32 *x, + Word16 Woff +) +{ + Word16 i, j; + cmplx *x_cmplx = (cmplx *)x; + + assert(len == (dim1*dim2)); + assert((dim1 == 3) || (dim1 == 5) || (dim1 == 8) || (dim1 == 10) || (dim1 == 15) || (dim1 == 16) || (dim1 == 20) || (dim1 == 30) || (dim1 == 32)); + assert((dim2 == 4) || (dim2 == 8) || (dim2 == 10) || (dim2 == 12) || (dim2 == 16) || (dim2 == 20)); + + FOR(i = 0; i + +/*-----------------------------------------------------------------* +* Local functions +*-----------------------------------------------------------------*/ + +#define FFT3_ONE_THIRD 21845 /* 1/3 in Q16 */ +/* DCT related */ +#define KP559016994_16FX 1200479845 /* EDCT & EMDCT constants */ +#define KP951056516_16FX 2042378325 /* EDCT & EMDCT constants */ +#define KP587785252_16FX 1262259213 /* EDCT & EMDCT constants */ + +static void fft5_shift4_16fx( Word16 n1, Word16 *zRe, Word16 *zIm, const Word16 *Idx ); +static void fft64_16fx( Word16 *x, Word16 *y, const Word16 *Idx ); +static void fft32_5_16fx( Word16 *x, Word16 *y, const Word16 *Idx ); +static void cftmdl_16fx(Word16 n, Word16 l, Word16 *a, const Word32 *w); +static void cftfsub_16fx( Word16 n, Word16 *a, const Word32 *w ); +static void cft1st_16fx(Word16 n, Word16 *a, const Word32 *w); +static void cftmdl_16fx(Word16 n, Word16 l, Word16 *a, const Word32 *w); +static void fft5_shift4_16fx( Word16 n1, Word16 *zRe, Word16 *zIm, const Word16 *Idx ); +static void bitrv2_SR_16fx( Word16 n, const Word16 *ip, Word16 *a ); +static void fft64_16fx( Word16 *x, Word16 *y, const Word16 *Idx ); +static void fft5_32_16fx( Word16 *zRe, Word16 *zIm, const Word16 *Idx ); +static void cdftForw_16fx( Word16 n, Word16 *a, const Word16 *ip, const Word32 *w ); + +#include "math_32.h" + +/*-----------------------------------------------------------------* +* Local functions +*-----------------------------------------------------------------*/ +static void cdftForw_fx( Word16 n, Word32 *a, const Word16 *ip, const Word16 *w ); +static void bitrv2_SR_fx( Word16 n, const Word16 *ip, Word32 *a ); +static void cftfsub_fx( Word16 n, Word32 *a, const Word16 *w ); +static void cft1st_fx( Word16 n, Word32 *a, const Word16 *w ); +static void cftmdl_fx( Word16 n, Word16 l, Word32 *a, const Word16 *w ); + + +void DoRTFTn_fx( + Word32 *x, /* i/o : real part of input and output data */ + Word32 *y, /* i/o : imaginary part of input and output data */ + const Word16 n /* i : size of the FFT up to 1024 */ +) +{ + + Word16 i; + Word32 z[2048], *pt; + + pt = z; + FOR ( i=0; i=1 ; i--) + { + x[i]=*pt++; + move16(); + y[i]=*pt++; + move16(); + } + + return; +} + +/*-----------------------------------------------------------------* + * cdftForw_fx() + * Main fuction of Complex Discrete Fourier Transform + *-----------------------------------------------------------------*/ +static void cdftForw_fx( + Word16 n, /* i : data length of real and imag */ + Word32 *a, /* i/o : input/output data Q(q)*/ + const Word16 *ip, /* i : work area for bit reversal */ + const Word16 *w /* i : cos/sin table Q14*/ +) +{ + /* bit reversal */ + bitrv2_SR_fx(n, ip + 2, a); + + /* Do FFT */ + cftfsub_fx(n, a, w); +} + +/*-----------------------------------------------------------------* + * bitrv2_SR_fx() + * Bit reversal + *-----------------------------------------------------------------*/ +static void bitrv2_SR_fx( + Word16 n, /* i : data length of real and imag */ + const Word16 *ip, /* i/o : work area for bit reversal */ + Word32 *a /* i/o : input/output data Q(q)*/ +) +{ + Word16 j, j1, k, k1, m, m2; + Word16 l; + Word32 xr, xi, yr, yi; + + l = n; + move16(); + m = 1; + move16(); + + WHILE (shl(m, 3) < l) + { + l = shr(l, 1); + m = shl(m, 1); + } + + m2 = shl(m, 1); + IF (shl(m, 3) == l) + { + FOR (k = 0; k < m; k++) + { + FOR (j = 0; j < k; j++) + { + j1 = add(shl(j, 1), ip[k]); + k1 = add(shl(k, 1), ip[j]); + xr = a[j1]; move32(); + xi = a[j1 + 1]; move32(); + yr = a[k1]; move32(); + yi = a[k1 + 1]; move32(); + a[j1] = yr; + move32(); + a[j1 + 1] = yi; + move32(); + a[k1] = xr; + move32(); + a[k1 + 1] = xi; + move32(); + j1 = add(j1, m2); + k1 = add(k1, shl(m2, 1)); + xr = a[j1]; move32(); + xi = a[j1 + 1]; move32(); + yr = a[k1]; move32(); + yi = a[k1 + 1]; move32(); + a[j1] = yr; + move32(); + a[j1 + 1] = yi; + move32(); + a[k1] = xr; + move32(); + a[k1 + 1] = xi; + move32(); + j1 = add(j1, m2); + k1 = sub(k1, m2); + xr = a[j1]; move32(); + xi = a[j1 + 1]; move32(); + xi = a[j1 + 1]; move32(); + yr = a[k1]; move32(); + yi = a[k1 + 1]; move32(); + a[j1] = yr; + move32(); + a[j1 + 1] = yi; + move32(); + a[k1] = xr; + move32(); + a[k1 + 1] = xi; + move32(); + j1 = add(j1, m2); + k1 = add(k1, shl(m2, 1)); + xr = a[j1]; move32(); + xi = a[j1 + 1]; move32(); + yr = a[k1]; move32(); + yi = a[k1 + 1]; move32(); + a[j1] = yr; + move32(); + a[j1 + 1] = yi; + move32(); + a[k1] = xr; + move32(); + a[k1 + 1] = xi; + move32(); + } + + j1 = add(add(shl(k, 1), m2), ip[k]); + k1 = add(j1, m2); + xr = a[j1]; move32(); + xi = a[j1 + 1]; move32(); + yr = a[k1]; move32(); + yi = a[k1 + 1]; move32(); + a[j1] = yr; + move32(); + a[j1 + 1] = yi; + move32(); + a[k1] = xr; + move32(); + a[k1 + 1] = xi; + move32(); + } + } + ELSE + { + FOR (k = 1; k < m; k++) + { + FOR (j = 0; j < k; j++) + { + j1 = add(shl(j, 1), ip[k]); + k1 = add(shl(k, 1), ip[j]); + xr = a[j1]; move32(); + xi = a[j1 + 1]; move32(); + yr = a[k1]; move32(); + yi = a[k1 + 1]; move32(); + a[j1] = yr; + move32(); + a[j1 + 1] = yi; + move32(); + a[k1] = xr; + move32(); + a[k1 + 1] = xi; + move32(); + j1 = add(j1, m2); + k1 = add(k1, m2); + xr = a[j1]; move32(); + xi = a[j1 + 1]; move32(); + yr = a[k1]; move32(); + yi = a[k1 + 1]; move32(); + a[j1] = yr; + move32(); + a[j1 + 1] = yi; + move32(); + a[k1] = xr; + move32(); + a[k1 + 1] = xi; + move32(); + } + } + } + + return; +} + +/*-----------------------------------------------------------------* + * cftfsub_fx() + * Complex Discrete Fourier Transform + *-----------------------------------------------------------------*/ +static void cftfsub_fx( + Word16 n, /* i : data length of real and imag */ + Word32 *a, /* i/o : input/output data Q(q)*/ + const Word16 *w /* i : cos/sin table Q14*/ +) +{ + Word16 j, j1, j2, j3, l; + Word32 x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i; + + l = 2; + move16(); + + IF (n > 8) + { + cft1st_fx(n, a, w); + l = 8; + move16(); + WHILE ((shl(l, 2) < n)) + { + cftmdl_fx(n, l, a, w); + l = shl(l, 2); + } + } + IF (shl(l, 2) == n) + { + FOR (j = 0; j < l; j += 2) + { + j1 = add(j, l); + j2 = add(j1, l); + j3 = add(j2, l); + x0r = L_add(a[j], a[j1]); + x0i = L_add(a[j + 1], a[j1 + 1]); + x1r = L_sub(a[j], a[j1]); + x1i = L_sub(a[j + 1], a[j1 + 1]); + x2r = L_add(a[j2], a[j3]); + x2i = L_add(a[j2 + 1], a[j3 + 1]); + x3r = L_sub(a[j2], a[j3]); + x3i = L_sub(a[j2 + 1], a[j3 + 1]); + a[j] = L_add(x0r, x2r); + move32(); + a[j2] = L_sub(x0r, x2r); + move32(); + a[j + 1] = L_add(x0i, x2i); + move32(); + a[j2 + 1] = L_sub(x0i, x2i); + move32(); + a[j1] = L_sub(x1r, x3i); + move32(); + a[j1 + 1] = L_add(x1i, x3r); + move32(); + a[j3] = L_add(x1r, x3i); + move32(); + a[j3 + 1] = L_sub(x1i, x3r); + move32(); + } + } + ELSE + { + FOR (j = 0; j < l; j += 2) + { + j1 = add(j, l); + x0r = L_sub(a[j], a[j1]); + x0i = L_sub(a[j + 1], a[j1 + 1]); + a[j] = L_add(a[j], a[j1]); + move32(); + a[j + 1] = L_add(a[j + 1], a[j1 + 1]); + move32(); + a[j1] = x0r; + move32(); + move32(); + a[j1 + 1] = x0i; + move32(); + move32(); + } + } + + return; +} + +/*-----------------------------------------------------------------* + * cft1st_fx() + * Subfunction of Complex Discrete Fourier Transform + *-----------------------------------------------------------------*/ +static void cft1st_fx( + Word16 n, /* i : data length of real and imag */ + Word32 *a, /* i/o : input/output data Q(q)*/ + const Word16 *w /* i : cos/sin table Q14*/ +) +{ + Word16 j, k1, k2; + Word16 wk1r, wk1i, wk2r, wk2i, wk3r, wk3i; + Word32 x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i; + + x0r = L_add(a[0], a[2]); + x0i = L_add(a[1], a[3]); + x1r = L_sub(a[0], a[2]); + x1i = L_sub(a[1], a[3]); + x2r = L_add(a[4], a[6]); + x2i = L_add(a[5], a[7]); + x3r = L_sub(a[4], a[6]); + x3i = L_sub(a[5], a[7]); + a[0] = L_add(x0r, x2r); + move32(); + a[1] = L_add(x0i, x2i); + move32(); + a[4] = L_sub(x0r, x2r); + move32(); + a[5] = L_sub(x0i, x2i); + move32(); + a[2] = L_sub(x1r, x3i); + move32(); + a[3] = L_add(x1i, x3r); + move32(); + a[6] = L_add(x1r, x3i); + move32(); + a[7] = L_sub(x1i, x3r); + move32(); + + wk1r = w[2]; + move16(); + x0r = L_add(a[8], a[10]); + x0i = L_add(a[9], a[11]); + x1r = L_sub(a[8], a[10]); + x1i = L_sub(a[9], a[11]); + x2r = L_add(a[12], a[14]); + x2i = L_add(a[13], a[15]); + x3r = L_sub(a[12], a[14]); + x3i = L_sub(a[13], a[15]); + a[8] = L_add(x0r, x2r); + move32(); + a[9] = L_add(x0i, x2i); + move32(); + a[12] = L_sub(x2i, x0i); + move32(); + a[13] = L_sub(x0r, x2r); + move32(); + + x0r = L_sub(x1r, x3i); + x0i = L_add(x1i ,x3r); + a[10] = Mult_32_16(L_shl(L_sub(x0r, x0i), 1), wk1r); + move32(); + a[11] = Mult_32_16(L_shl(L_add(x0r, x0i), 1), wk1r); + move32(); + x0r = L_add(x3i, x1r); + x0i = L_sub(x3r,x1i); + a[14] = Mult_32_16(L_shl(L_sub(x0i, x0r), 1), wk1r); + move32(); + a[15] = Mult_32_16(L_shl(L_add(x0i, x0r), 1), wk1r); + move32(); + + k1 = 0; + move16(); + FOR (j = 16; j < n; j += 16) + { + k1 = add(k1, 2); + k2 = shl(k1, 1); + wk2r = w[k1]; + move16(); + wk2i = w[k1 + 1]; + move16(); + wk1r = w[k2]; + move16(); + wk1i = w[k2 + 1]; + move16(); + wk3r = extract_l(L_sub(L_deposit_l(wk1r), L_shr(L_mult(wk2i, wk1i), 14))); + wk3i = extract_l(L_msu0(L_shr(L_mult(wk2i, wk1r), 14), wk1i, 1)); + x0r = L_add(a[j], a[j + 2]); + x0i = L_add(a[j + 1], a[j + 3]); + x1r = L_sub(a[j], a[j + 2]); + x1i = L_sub(a[j + 1], a[j + 3]); + x2r = L_add(a[j + 4], a[j + 6]); + x2i = L_add(a[j + 5], a[j + 7]); + x3r = L_sub(a[j + 4], a[j + 6]); + x3i = L_sub(a[j + 5], a[j + 7]); + a[j] = L_add(x0r, x2r); + move32(); + a[j + 1] = L_add(x0i, x2i); + move32(); + x0r = L_sub(x0r, x2r); + x0i = L_sub(x0i, x2i); + a[j + 4] = L_sub(Mult_32_16(L_shl(x0r, 1), wk2r), Mult_32_16(L_shl(x0i, 1), wk2i)); + move32(); + a[j + 5] = L_add(Mult_32_16(L_shl(x0i, 1), wk2r), Mult_32_16(L_shl(x0r, 1), wk2i)); + move32(); + x0r = L_sub(x1r, x3i); + x0i = L_add(x1i, x3r); + a[j + 2] = L_sub(Mult_32_16(L_shl(x0r, 1), wk1r), Mult_32_16(L_shl(x0i, 1), wk1i)); + move32(); + a[j + 3] = L_add(Mult_32_16(L_shl(x0i, 1), wk1r), Mult_32_16(L_shl(x0r, 1), wk1i)); + move32(); + x0r = L_add(x1r, x3i); + x0i = L_sub(x1i, x3r); + a[j + 6] = L_sub(Mult_32_16(L_shl(x0r, 1), wk3r), Mult_32_16(L_shl(x0i, 1), wk3i)); + move32(); + a[j + 7] = L_add(Mult_32_16(L_shl(x0i, 1), wk3r), Mult_32_16(L_shl(x0r, 1), wk3i)); + move32(); + + wk1r = w[k2 + 2]; + move16(); + wk1i = w[k2 + 3]; + move16(); + wk3r = extract_l(L_sub(L_deposit_l(wk1r), L_shr(L_mult(wk2r, wk1i), 14))); + wk3i = extract_l(L_msu0(L_shr(L_mult(wk2r, wk1r), 14), wk1i, 1)); + x0r = L_add(a[j + 8], a[j + 10]); + x0i = L_add(a[j + 9], a[j + 11]); + x1r = L_sub(a[j + 8], a[j + 10]); + x1i = L_sub(a[j + 9], a[j + 11]); + x2r = L_add(a[j + 12], a[j + 14]); + x2i = L_add(a[j + 13], a[j + 15]); + x3r = L_sub(a[j + 12], a[j + 14]); + x3i = L_sub(a[j + 13], a[j + 15]); + a[j + 8] = L_add(x0r, x2r); + move32(); + a[j + 9] = L_add(x0i, x2i); + move32(); + x0r = L_sub(x0r, x2r); + x0i = L_sub(x0i, x2i); + a[j + 12] = L_negate(L_add(Mult_32_16(L_shl(x0r, 1), wk2i), Mult_32_16(L_shl(x0i, 1), wk2r))); + move32(); + a[j + 13] = L_sub(Mult_32_16(L_shl(x0r, 1), wk2r), Mult_32_16(L_shl(x0i, 1), wk2i)); + move32(); + x0r = L_sub(x1r, x3i); + x0i = L_add(x1i, x3r); + a[j + 10] = L_sub(Mult_32_16(L_shl(x0r, 1), wk1r), Mult_32_16(L_shl(x0i, 1), wk1i)); + move32(); + a[j + 11] = L_add(Mult_32_16(L_shl(x0i, 1), wk1r), Mult_32_16(L_shl(x0r, 1), wk1i)); + move32(); + x0r =L_add(x1r, x3i); + x0i =L_sub(x1i, x3r); + a[j + 14] = L_sub(Mult_32_16(L_shl(x0r, 1), wk3r), Mult_32_16(L_shl(x0i, 1), wk3i)); + move32(); + a[j + 15] = L_add(Mult_32_16(L_shl(x0i, 1), wk3r), Mult_32_16(L_shl(x0r, 1), wk3i)); + move32(); + } + + return; +} + +/*-----------------------------------------------------------------* + * cftmdl_fx() + * Subfunction of Complex Discrete Fourier Transform + *-----------------------------------------------------------------*/ +static void cftmdl_fx( + Word16 n, /* i : data length of real and imag */ + Word16 l, /* i : initial shift for processing */ + Word32 *a, /* i/o : input/output data Q(Qx+Q_edct)*/ + const Word16 *w /* i : cos/sin table Q30*/ +) +{ + Word16 j, j1, j2, j3, k, k1, k2, m, m2; + Word16 wk1r, wk1i, wk2r, wk2i, wk3r, wk3i; + Word32 x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i; + Word16 tmp; + + m = shl(l, 2); + FOR (j = 0; j < l; j += 2) + { + j1 = add(j, l); + j2 = add(j1, l); + j3 = add(j2, l); + x0r = L_add(a[j], a[j1]); + x0i = L_add(a[j + 1], a[j1 + 1]); + x1r = L_sub(a[j], a[j1]); + x1i = L_sub(a[j + 1], a[j1 + 1]); + x2r = L_add(a[j2], a[j3]); + x2i = L_add(a[j2 + 1], a[j3 + 1]); + x3r = L_sub(a[j2], a[j3]); + x3i = L_sub(a[j2 + 1], a[j3 + 1]); + a[j] = L_add(x0r, x2r); + move32(); + a[j + 1] = L_add(x0i, x2i); + move32(); + a[j2] = L_sub(x0r, x2r); + move32(); + a[j2 + 1] =L_sub(x0i, x2i); + move32(); + a[j1] = L_sub(x1r, x3i); + move32(); + a[j1 + 1] = L_add(x1i, x3r); + move32(); + a[j3] = L_add(x1r, x3i); + move32(); + a[j3 + 1] = L_sub(x1i, x3r); + move32(); + } + + wk1r = w[2]; + move16(); + tmp = add(l, m); + FOR (j = m; j < tmp; j += 2) + { + j1 = add(j, l); + j2 = add(j1, l); + j3 = add(j2, l); + x0r = L_add(a[j], a[j1]); + x0i = L_add(a[j + 1], a[j1 + 1]); + x1r = L_sub(a[j], a[j1]); + x1i = L_sub(a[j + 1], a[j1 + 1]); + x2r = L_add(a[j2], a[j3]); + x2i = L_add(a[j2 + 1], a[j3 + 1]); + x3r = L_sub(a[j2], a[j3]); + x3i = L_sub(a[j2 + 1], a[j3 + 1]); + a[j] = L_add(x0r, x2r); + move32(); + a[j + 1] = L_add(x0i, x2i); + move32(); + a[j2] = L_sub(x2i, x0i); + move32(); + a[j2 + 1] = L_sub(x0r, x2r); + move32(); + x0r = L_sub(x1r, x3i); + x0i = L_add(x1i, x3r); + a[j1] = Mult_32_16(L_shl(L_sub(x0r, x0i), 1), wk1r); + move32(); + a[j1 + 1] = Mult_32_16(L_shl(L_add(x0r, x0i), 1), wk1r); + move32(); + x0r = L_add(x3i, x1r); + x0i = L_sub(x3r, x1i); + a[j3] = Mult_32_16(L_shl(L_sub(x0i, x0r), 1), wk1r); + move32(); + a[j3 + 1] = Mult_32_16(L_shl(L_add(x0r, x0i), 1), wk1r); + move32(); + } + + k1 = 0; + move16(); + m2 = shl(m, 1); + FOR (k = m2; k < n; k += m2) + { + k1 = add(k1, 2); + k2 = shl(k1, 1); + wk2r = w[k1]; + move16(); + wk2i = w[k1 + 1]; + move16(); + wk1r = w[k2]; + move16(); + wk1i = w[k2 + 1]; + move16(); + wk3r = extract_l(L_sub(L_deposit_l(wk1r), L_shr(L_mult(wk2i, wk1i), 14))); + wk3i = extract_l(L_msu0(L_shr(L_mult(wk2i, wk1r), 14), wk1i, 1)); + + tmp = add(l, k) ; + FOR (j = k; j < tmp; j += 2) + { + j1 = add(j, l); + j2 = add(j1, l); + j3 = add(j2, l); + x0r = L_add(a[j], a[j1]); + x0i = L_add(a[j + 1], a[j1 + 1]); + x1r = L_sub(a[j], a[j1]); + x1i = L_sub(a[j + 1], a[j1 + 1]); + x2r = L_add(a[j2], a[j3]); + x2i = L_add(a[j2 + 1], a[j3 + 1]); + x3r = L_sub(a[j2], a[j3]); + x3i = L_sub(a[j2 + 1], a[j3 + 1]); + a[j] = L_add(x0r, x2r); + move32(); + a[j + 1] = L_add(x0i, x2i); + move32(); + x0r = L_sub(x0r, x2r); + x0i = L_sub(x0i, x2i); + a[j2] = L_sub(Mult_32_16(L_shl(x0r, 1), wk2r), Mult_32_16(L_shl(x0i, 1), wk2i)); + move32(); + a[j2 + 1] = L_add(Mult_32_16(L_shl(x0i, 1), wk2r), Mult_32_16(L_shl(x0r, 1), wk2i)); + move32(); + x0r = L_sub(x1r, x3i); + x0i = L_add(x1i, x3r); + a[j1] = L_sub(Mult_32_16(L_shl(x0r, 1), wk1r), Mult_32_16(L_shl(x0i, 1), wk1i)); + move32(); + a[j1 + 1] = L_add(Mult_32_16(L_shl(x0i, 1), wk1r), Mult_32_16(L_shl(x0r, 1), wk1i)); + move32(); + x0r = L_add(x1r, x3i); + x0i = L_sub(x1i, x3r); + a[j3] = L_sub(Mult_32_16(L_shl(x0r, 1), wk3r), Mult_32_16(L_shl(x0i, 1), wk3i)); + move32(); + a[j3 + 1] = L_add(Mult_32_16(L_shl(x0i, 1), wk3r), Mult_32_16(L_shl(x0r, 1), wk3i)); + move32(); + } + + wk1r = w[k2 + 2]; + move16(); + wk1i = w[k2 + 3]; + move16(); + wk3r = extract_l(L_sub(L_deposit_l(wk1r), L_shr(L_mult(wk2r, wk1i), 14))); + wk3i = extract_l(L_msu0(L_shr(L_mult(wk2r, wk1r), 14), wk1i, 1)); + + tmp = add(l, add(k, m)); + FOR (j = add(k, m); j < tmp; j += 2) + { + j1 = add(j, l); + j2 = add(j1, l); + j3 = add(j2, l); + x0r = L_add(a[j], a[j1]); + x0i = L_add(a[j + 1], a[j1 + 1]); + x1r = L_sub(a[j], a[j1]); + x1i = L_sub(a[j + 1], a[j1 + 1]); + x2r = L_add(a[j2], a[j3]); + x2i = L_add(a[j2 + 1], a[j3 + 1]); + x3r = L_sub(a[j2], a[j3]); + x3i = L_sub(a[j2 + 1], a[j3 + 1]); + a[j] = L_add(x0r, x2r); + move32(); + a[j + 1] = L_add(x0i, x2i); + move32(); + x0r= L_sub(x0r, x2r); + x0i=L_sub(x0i, x2i); + a[j2] = L_negate(L_add(Mult_32_16(L_shl(x0r, 1), wk2i), Mult_32_16(L_shl(x0i, 1), wk2r))); + move32(); + a[j2 + 1] = L_sub(Mult_32_16(L_shl(x0r, 1), wk2r), Mult_32_16(L_shl(x0i, 1), wk2i)); + move32(); + x0r = L_sub(x1r, x3i); + x0i = L_add(x1i, x3r); + a[j1] = L_sub(Mult_32_16(L_shl(x0r, 1), wk1r), Mult_32_16(L_shl(x0i, 1), wk1i)); + move32(); + a[j1 + 1] = L_add(Mult_32_16(L_shl(x0i, 1), wk1r), Mult_32_16(L_shl(x0r, 1), wk1i)); + move32(); + x0r = L_add(x1r, x3i); + x0i = L_sub(x1i, x3r); + a[j3] = L_sub(Mult_32_16(L_shl(x0r, 1), wk3r), Mult_32_16(L_shl(x0i, 1), wk3i)); + move32(); + a[j3 + 1] = L_add(Mult_32_16(L_shl(x0i, 1), wk3r), Mult_32_16(L_shl(x0r, 1), wk3i)); + move32(); + } + } + + return; +} + + +static void cftbsub_fx( + Word16 n, + Word32 *a, + const Word16 *w /* i : cos/sin table */ +) +{ + Word16 j, j1, j2, j3, l; + Word32 x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i; + + l = 2; + move16(); + IF (n > 8) + { + cft1st_fx(n, a, w); + l = 8; + move16(); + + WHILE (LT_16(shl(l, 2), n)) + { + cftmdl_fx(n, l, a, w); + l = shl(l, 2); + } + } + + IF (EQ_16(shl(l, 2), n)) + { + FOR (j = 0; j < l; j += 2) + { + j1 = add(j, l); + j2 = add(j1, l); + j3 = add(j2, l); + x0r = L_add(a[j], a[j1]); + x0i = L_negate(L_add(a[j + 1], a[j1 + 1])); + x1r = L_sub(a[j], a[j1]); + x1i = L_sub(a[j1 + 1], a[j + 1]); + x2r = L_add(a[j2], a[j3]); + x2i = L_add(a[j2 + 1], a[j3 + 1]); + x3r = L_sub(a[j2], a[j3]); + x3i = L_sub(a[j2 + 1], a[j3 + 1]); + a[j] = L_add(x0r, x2r); + move32(); + a[j + 1] = L_sub(x0i, x2i); + move32(); + a[j2] = L_sub(x0r, x2r); + move32(); + a[j2 + 1] = L_add(x0i, x2i); + move32(); + a[j1] = L_sub(x1r, x3i); + move32(); + a[j1 + 1] = L_sub(x1i, x3r); + move32(); + a[j3] = L_add(x1r, x3i); + move32(); + a[j3 + 1] = L_add(x1i, x3r); + move32(); + } + } + ELSE + { + FOR (j = 0; j < l; j += 2) + { + j1 = add(j, l); + x0r = L_sub(a[j], a[j1]); + x0i = L_sub(a[j1 + 1], a[j + 1]); + a[j] = L_add(a[j], a[j1]); + move32(); + a[j + 1] = L_negate(L_add(a[j + 1], a[j1 + 1])); + move32(); + a[j1] = x0r; + move32(); + move32(); + a[j1 + 1] = x0i; + move32(); + move32(); + } + } +} + +static void rftfsub_fx( + Word16 n, + Word32 *a, + Word16 nc, + const Word16 *c +) +{ + Word16 j, k, kk, ks, m, tmp; + Word32 xr, xi, yr, yi; + Word16 wkr, wki; + + m = shr(n, 1); + /*ks = 2 * nc / m; */ + tmp = shl(nc, 1); + ks = 0; + move16(); + WHILE (GE_16(tmp, m)) + { + ks = add(ks, 1); + tmp = sub(tmp, m); + } + kk = 0; + move16(); + FOR (j = 2; j < m; j += 2) + { + k = sub(n, j); + kk = add(kk, ks); + wkr = sub(8192, c[nc - kk]); + wki = c[kk]; + move16(); + xr = L_sub(a[j], a[k]); + xi = L_add(a[j + 1], a[k + 1]); + yr = L_sub(Mult_32_16(L_shl(xr, 1), wkr), Mult_32_16(L_shl(xi, 1), wki)); + yi = L_add(Mult_32_16(L_shl(xi, 1), wkr), Mult_32_16(L_shl(xr, 1), wki)); + a[j] = L_sub(a[j], yr); + move32(); + a[j + 1] = L_sub(a[j + 1], yi); + move32(); + a[k] = L_add(a[k], yr); + move32(); + a[k + 1] = L_sub(a[k + 1], yi); + move32(); + } +} + + +static void rftbsub_fx( + Word16 n, + Word32 *a, + Word16 nc, + const Word16 *c +) +{ + Word16 j, k, kk, ks, m, tmp; + Word32 xr, xi, yr, yi; + Word16 wkr, wki; + + a[1] = L_negate(a[1]); + m = shr(n, 1); + /*ks = 2 * nc / m; */ + tmp = shl(nc, 1); + ks = 0; + move16(); + WHILE (GE_16(tmp, m)) + { + ks = add(ks, 1); + tmp = sub(tmp, m); + } + kk = 0; + move16(); + FOR (j = 2; j < m; j += 2) + { + k = sub(n, j); + kk = add(kk, ks); + wkr = sub(8192, c[nc - kk]); + wki = c[kk]; + move16(); + xr = L_sub(a[j], a[k]); + xi = L_add(a[j + 1], a[k + 1]); + yr = L_add(Mult_32_16(L_shl(xr, 1), wkr), Mult_32_16(L_shl(xi, 1), wki)); + yi = L_sub(Mult_32_16(L_shl(xi, 1), wkr), Mult_32_16(L_shl(xr, 1), wki)); + a[j] = L_sub(a[j], yr); + move32(); + a[j + 1] = L_sub(yi, a[j + 1]); + move32(); + a[k] = L_add(a[k], yr); + move32(); + a[k + 1] = L_sub(yi, a[k + 1]); + move32(); + } + a[m + 1] = L_negate(a[m + 1]); + move32(); +} + + +static void dctsub_fx( + Word16 n, + Word32 *a, + Word16 nc, + const Word16 *c +) +{ + Word16 j, k, kk, ks, m, tmp; + Word16 wkr, wki; + Word32 xr; + + m = shr(n, 1); + /*ks = nc / n; */ + tmp = nc; + move16(); + ks = 0; + move16(); + WHILE (GE_16(tmp, n)) + { + ks = add(ks, 1); + tmp = sub(tmp, n); + } + kk = 0; + move16(); + FOR (j = 1; j < m; j++) + { + k = sub(n, j); + kk = add(kk, ks); + wkr = sub(c[kk], c[nc - kk]); + wki = add(c[kk], c[nc - kk]); + xr = L_sub(Mult_32_16(L_shl(a[j], 1), wki), Mult_32_16(L_shl(a[k], 1), wkr)); + a[j] = L_add(Mult_32_16(L_shl(a[j], 1), wkr), Mult_32_16(L_shl(a[k], 1), wki)); + move32(); + a[k] = xr; + move32(); + } + a[m] = Mult_32_16(L_shl(a[m], 1), c[0]); +} + +/*-----------------------------------------------------------------* + * edct2_fx() + * + * Transformation of the signal to DCT domain + * OR Inverse EDCT-II for short frames + *-----------------------------------------------------------------*/ + +void edct2_fx( + Word16 n, + Word16 isgn, + Word16 *in, + Word32 *a, + Word16 *q, + const Word16 *ip, + const Word16 *w +) +{ + Word16 j, nw, nc; + Word32 xr; + + *q = Exp16Array(n, in); + *q = add(*q, 6); + FOR (j = 0; j < n; j++) + { + a[j] = L_shl((Word32) in[j], *q); + move32(); + } + + nw = ip[0]; + move16(); + if (GT_16(n, shl(nw, 2))) + { + nw = shr(n, 2); + } + + nc = ip[1]; + move16(); + if (n > nc) + { + nc = n; + move16(); + } + + IF (isgn < 0) + { + xr = a[n - 1]; + move32(); + FOR (j = n - 2; j >= 2; j -= 2) + { + a[j + 1] = L_sub(a[j], a[j - 1]); + move32(); + a[j] = L_add(a[j], a[j - 1]); + move32(); + } + a[1] = L_sub(a[0], xr); + move32(); + a[0] = L_add(a[0], xr); + move32(); + + IF (n > 4) + { + rftbsub_fx(n, a, nc, w + nw); + bitrv2_SR_fx(n, ip + 2, a); + cftbsub_fx(n, a, w); + } + ELSE IF (n == 4) + { + cftfsub_fx(n, a, w); + } + } + + IF (isgn >= 0) + { + a[0] = L_shr(a[0], 1); + move32(); + } + + dctsub_fx(n, a, nc, w + nw); + + IF (isgn >= 0) + { + IF (n > 4) + { + bitrv2_SR_fx(n, ip + 2, a); + cftfsub_fx(n, a, w); + rftfsub_fx(n, a, nc, w + nw); + } + ELSE IF (n == 4) + { + cftfsub_fx(n, a, w); + } + xr = L_sub(a[0], a[1]); + a[0] = L_add(a[0], a[1]); + move32(); + FOR (j = 2; j < n; j += 2) + { + a[j - 1] = L_sub(a[j], a[j + 1]); + move32(); + a[j] = L_add(a[j], a[j + 1]); + move32(); + } + a[n - 1] = xr; + move32(); + + FOR (j = 0; j < n; j ++) + { + a[j] = L_shr(a[j], 5); + move32(); + } + } +} + + +/*-----------------------------------------------------------------* +* fft5_shift4() +* 5-point FFT with 4-point circular shift +*-----------------------------------------------------------------*/ + +static void fft5_shift4_16fx( + Word16 n1, /* i : length of data */ + Word16 *zRe, /* i/o : real part of input and output data */ + Word16 *zIm, /* i/o : imaginary part of input and output data */ + const Word16 *Idx /* i : pointer of the address table */ +) +{ + Word16 T1, To, T8, Tt, T9, Ts, Te, Tp, Th, Tn,T2, T3, T4, T5, T6, T7; + Word16 i0,i1,i2,i3,i4; + Word32 L_tmp; + + + i0 = Idx[0]; + move16(); + i1 = Idx[n1]; + move16(); + i2 = Idx[n1*2]; + move16(); + i3 = Idx[n1*3]; + move16(); + i4 = Idx[n1*4]; + move16(); + + T1 = zRe[i0]; + move16(); + To = zIm[i0]; + move16(); + + T2 = zRe[i1]; + move16(); + T3 = zRe[i4]; + move16(); + T4 = add(T2,T3); + T5 = zRe[i2]; + move16(); + T6 = zRe[i3]; + move16(); +#ifdef BASOP_NOGLOB + T7 = add_sat(T5,T6); + T8 = add_sat(T4,T7); + Tt = sub_sat(T5,T6); +#else + T7 = add(T5,T6); + T8 = add(T4,T7); + Tt = sub(T5,T6); +#endif + /* T9 = KP559016994 * (T4 - T7); */ +#ifdef BASOP_NOGLOB + L_tmp = Mult_32_16(KP559016994_16FX,sub_sat(T4,T7)); + T9 = round_fx_sat(L_tmp); + Ts = sub_sat(T2,T3); +#else + L_tmp = Mult_32_16(KP559016994_16FX,sub(T4,T7)); + T9 = round_fx(L_tmp); + Ts = sub(T2,T3); +#endif + + T2 = zIm[i1]; + move16(); + T3 = zIm[i4]; + move16(); + T4 = add(T2,T3); + T5 = zIm[i2]; + move16(); + T6 = zIm[i3]; + move16(); +#ifdef BASOP_NOGLOB + T7 = add_sat(T5,T6); + Te = sub_sat(T2,T3); + Tp = add_sat(T4,T7); + Th = sub_sat(T5,T6); +#else + T7 = add(T5,T6); + Te = sub(T2,T3); + Tp = add(T4,T7); + Th = sub(T5,T6); +#endif + +#ifdef BASOP_NOGLOB + /* Tn = KP559016994 * (T4 - T7); */ + L_tmp = Mult_32_16(KP559016994_16FX, sub_sat(T4, T7)); + Tn = round_fx_sat(L_tmp); + zRe[i0] = add_sat(T1, T8); + move16(); + zIm[i0] = add_sat(To, Tp); +#else + /* Tn = KP559016994 * (T4 - T7); */ + L_tmp = Mult_32_16(KP559016994_16FX, sub(T4, T7)); + Tn = round_fx(L_tmp); + zRe[i0] = add(T1,T8); + move16(); + zIm[i0] = add(To, Tp); +#endif + move16(); + + /* T2 = KP951056516*Te + KP587785252*Th; */ + L_tmp = Mult_32_16(KP951056516_16FX,Te); + L_tmp = Madd_32_16(L_tmp,KP587785252_16FX,Th); +#ifdef BASOP_NOGLOB + T2 = round_fx_sat(L_tmp); +#else + T2 = round_fx(L_tmp); +#endif + /*T3 = KP951056516*Th - KP587785252*Te; */ + L_tmp = Mult_32_16(KP951056516_16FX,Th); + L_tmp = Msub_32_16(L_tmp,KP587785252_16FX,Te); +#ifdef BASOP_NOGLOB + T3 = round_fx_sat(L_tmp); +#else + T3 = round_fx(L_tmp); +#endif +#ifdef BASOP_NOGLOB + T6 = sub_sat(T1, shr_sat(T8, 2)); + T4 = add_sat(T9, T6); + T5 = sub_sat(T6, T9); + zRe[i1] = sub_sat(T4, T2); + move16(); + zRe[i2] = add_sat(T5, T3); + move16(); + zRe[i4] = add_sat(T4, T2); + move16(); + zRe[i3] = sub_sat(T5, T3); + move16(); +#else + T6 = sub(T1, shr(T8, 2)); + T4 = add(T9, T6); + T5 = sub(T6, T9); + zRe[i1] = sub(T4, T2); + move16(); + zRe[i2] = add(T5, T3); + move16(); + zRe[i4] = add(T4,T2); + move16(); + zRe[i3] = sub(T5, T3); + move16(); +#endif + + /* T2 = KP951056516 * Ts + KP587785252 * Tt; */ + L_tmp = Mult_32_16(KP951056516_16FX,Ts); + L_tmp = Madd_32_16(L_tmp,KP587785252_16FX,Tt); + T2 = round_fx(L_tmp); + + /* T3 = KP951056516 * Tt - KP587785252 * Ts; */ + L_tmp = Mult_32_16(KP951056516_16FX,Tt); + L_tmp = Msub_32_16(L_tmp,KP587785252_16FX,Ts); + T3 = round_fx(L_tmp); + +#ifdef BASOP_NOGLOB + T6 = sub_sat(To, shr(Tp, 2)); + T4 = add_sat(Tn, T6); + T5 = sub_sat(T6, Tn); + zIm[i4] = sub_sat(T4,T2); + move16(); + zIm[i2] = sub_sat(T5,T3); + move16(); + zIm[i1] = add_sat(T2,T4); + move16(); + zIm[i3] = add_sat(T3,T5); + move16(); +#else + T6 = sub(To, shr(Tp, 2)); + T4 = add(Tn, T6); + T5 = sub(T6, Tn); + zIm[i4] = sub(T4,T2); + move16(); + zIm[i2] = sub(T5,T3); + move16(); + zIm[i1] = add(T2,T4); + move16(); + zIm[i3] = add(T3,T5); + move16(); +#endif + return; +} + +/*-----------------------------------------------------------------* +* fft5_32() +* 5-point FFT called for 32 times +*-----------------------------------------------------------------*/ +static void fft5_32_16fx( + Word16 *zRe, /* i/o : real part of input and output data */ + Word16 *zIm, /* i/o : imaginary part of input and output data */ + const Word16 *Idx /* i : pointer of the address table */ +) +{ + Word16 T1, To, T8, Tt, T9, Ts, Te, Tp, Th, Tn,T2, T3, T4, T5, T6, T7; + Word16 i0,i1,i2,i3,i4; + Word32 L_tmp; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + i0 = Idx[0]; + move16(); + i1 = Idx[32]; + move16(); + i2 = Idx[64]; + move16(); + i3 = Idx[96]; + move16(); + i4 = Idx[128]; + move16(); + + T1 = zRe[i0]; + move16(); + To = zIm[i0]; + move16(); + + T2 = zRe[i1]; + move16(); + T3 = zRe[i4]; + move16(); + +#ifdef BASOP_NOGLOB + T4 = add_sat(T2, T3); + T5 = zRe[i2]; + move16(); + T6 = zRe[i3]; + move16(); + T7 = add_o(T5,T6, &Overflow); + T8 = add_o(T4,T7, &Overflow); + Tt = sub_o(T5,T6, &Overflow); +#else + T4 = add(T2, T3); + T5 = zRe[i2]; + move16(); + T6 = zRe[i3]; + move16(); + T7 = add(T5,T6); + T8 = add(T4,T7); + Tt = sub(T5,T6); +#endif +#ifdef BASOP_NOGLOB + /* T9 = KP559016994 * (T4 - T7); */ + L_tmp = Mult_32_16(KP559016994_16FX, sub_sat(T4, T7)); + T9 = round_fx_sat(L_tmp); + Ts = sub_sat(T2, T3); + + T2 = zIm[i1]; + move16(); + T3 = zIm[i4]; + move16(); + T4 = add_sat(T2, T3); + T5 = zIm[i2]; + move16(); + T6 = zIm[i3]; + move16(); + T7 = add_sat(T5,T6); + Te = sub_sat(T2,T3); + Tp = add_sat(T4,T7); + Th = sub_sat(T5,T6); + L_tmp = Mult_32_16(KP559016994_16FX,sub_sat(T4,T7)); + Tn = round_fx_sat(L_tmp); +#else + /* T9 = KP559016994 * (T4 - T7); */ + L_tmp = Mult_32_16(KP559016994_16FX, sub(T4, T7)); + T9 = round_fx(L_tmp); + Ts = sub(T2, T3); + + T2 = zIm[i1]; + move16(); + T3 = zIm[i4]; + move16(); + T4 = add(T2, T3); + T5 = zIm[i2]; + move16(); + T6 = zIm[i3]; + move16(); + T7 = add(T5,T6); + Te = sub(T2,T3); + Tp = add(T4,T7); + Th = sub(T5,T6); + L_tmp = Mult_32_16(KP559016994_16FX,sub(T4,T7)); + Tn = round_fx(L_tmp); +#endif + + +#ifdef BASOP_NOGLOB + zRe[i0] = add_o(T1,T8, &Overflow); + move16(); + zIm[i0] = add_o(To,Tp, &Overflow); + move32(); +#else + zRe[i0] = add(T1,T8); + move16(); + zIm[i0] = add(To,Tp); + move32(); +#endif + +#ifdef BASOP_NOGLOB + /*T2 = KP951056516*Te + KP587785252*Th; */ + L_tmp = Mult_32_16(KP951056516_16FX, Te); + L_tmp = Madd_32_16(L_tmp, KP587785252_16FX, Th); + T2 = round_fx_sat(L_tmp); + + /*T3 = KP951056516*Th - KP587785252*Te; */ + L_tmp = Mult_32_16(KP951056516_16FX, Th); + L_tmp = Msub_32_16(L_tmp, KP587785252_16FX, Te); + T3 = round_fx_sat(L_tmp); + + + + T6 = sub_sat(T1, shr(T8, 2)); + T4 = add_sat(T9, T6); + T5 = sub_sat(T6, T9); + + zRe[i3] = sub_o(T4,T2, &Overflow); + move32(); + zRe[i1] = add_o(T5,T3, &Overflow); + move32(); + zRe[i2] = add_o(T4,T2, &Overflow); + move32(); + zRe[i4] = sub_o(T5,T3, &Overflow); + move32(); +#else + /*T2 = KP951056516*Te + KP587785252*Th; */ + L_tmp = Mult_32_16(KP951056516_16FX, Te); + L_tmp = Madd_32_16(L_tmp, KP587785252_16FX, Th); + T2 = round_fx(L_tmp); + + /*T3 = KP951056516*Th - KP587785252*Te; */ + L_tmp = Mult_32_16(KP951056516_16FX, Th); + L_tmp = Msub_32_16(L_tmp, KP587785252_16FX, Te); + T3 = round_fx(L_tmp); + + + + T6 = sub(T1, shr(T8, 2)); + T4 = add(T9, T6); + T5 = sub(T6, T9); + + zRe[i3] = sub(T4,T2); + move32(); + zRe[i1] = add(T5,T3); + move32(); + zRe[i2] = add(T4,T2); + move32(); + zRe[i4] = sub(T5,T3); + move32(); +#endif + + /* T2 = KP951056516 * Ts + KP587785252 * Tt; */ + L_tmp = Mult_32_16(KP951056516_16FX,Ts); + L_tmp = Madd_32_16(L_tmp,KP587785252_16FX,Tt); + T2 = round_fx(L_tmp); + + /* T3 = KP951056516 * Tt - KP587785252 * Ts; */ + L_tmp = Mult_32_16(KP951056516_16FX,Tt); + L_tmp = Msub_32_16(L_tmp,KP587785252_16FX,Ts); + +#ifdef BASOP_NOGLOB + T3 = round_fx_sat(L_tmp); + + T6 = sub_sat(To, shr(Tp, 2)); + T4 = add_sat(Tn, T6); + T5 = sub_sat(T6, Tn); + zIm[i2] = sub_sat(T4,T2); + move16(); + zIm[i1] = sub_sat(T5,T3); + move16(); + zIm[i3] = add_sat(T2,T4); + move16(); + zIm[i4] = add_sat(T3,T5); + move16(); +#else + T3 = round_fx(L_tmp); + + T6 = sub(To, shr(Tp, 2)); + T4 = add(Tn, T6); + T5 = sub(T6, Tn); + zIm[i2] = sub(T4,T2); + move16(); + zIm[i1] = sub(T5,T3); + move16(); + zIm[i3] = add(T2,T4); + move16(); + zIm[i4] = add(T3,T5); + move16(); +#endif + + return; +} + +/*-----------------------------------------------------------------* +* fft64() +* 64-point FFT +*-----------------------------------------------------------------*/ +static void fft64_16fx( + Word16 *x, /* i/o : real part of input and output data */ + Word16 *y, /* i/o : imaginary part of input and output data */ + const Word16 *Idx /* i : pointer of the address table */ +) +{ + Word16 i,id,jd; + Word16 z[128]; + move16();/*penalty for 1 ptr init */ + FOR ( i=0; i<64; i++ ) + { + id = Idx[i]; + move16(); + z[2*i] = x[id]; + move16(); + z[2*i+1] = y[id]; + move16(); + } + + cdftForw_16fx(128, z, Ip_fft64, w_fft128_16fx); + + move16();/*penalty for 1 ptr init */ + FOR( i=0; i<64 ; i++) + { + jd = Odx_fft64[i]; + move16(); + id = Idx[jd]; + move16(); + x[id]=z[2*i]; + move16(); + y[id]=z[2*i+1]; + move16(); + } + + return; +} + + +/*-----------------------------------------------------------------* +* fft32_5() +* 32-point FFT called for 5 times +*-----------------------------------------------------------------*/ +static void fft32_5_16fx( + Word16 *x, /* i/o : real part of input and output data */ + Word16 *y, /* i/o : imaginary part of input and output data */ + const Word16 *Idx /* i : pointer of the address table */ +) +{ + Word16 i,id,jd; + Word16 z[64]; + + move16();/*penalty for 1 ptr init */ + FOR( i=0; i<32; i++ ) + { + id = Idx[i]; + move16(); + z[2*i] = x[id]; + move16(); + z[2*i+1] = y[id]; + move16(); + } + + cdftForw_16fx(64,z,Ip_fft32,w_fft32_16fx); + + move16();/*penalty for 1 ptr init */ + FOR( i=0; i<32; i++ ) + { + jd = Odx_fft32_5[i]; + move16(); + id = Idx[jd]; + move16(); + x[id]=z[2*i]; + move16(); + y[id]=z[2*i+1]; + move16(); + } + + return; +} + + + +/*-----------------------------------------------------------------* +* DoRTFT160() +* a low complexity 2-dimensional DFT of 160 points +*-----------------------------------------------------------------*/ +void DoRTFT160_16fx( + Word16 x[], /* i/o : real part of input and output data */ + Word16 y[] /* i/o : imaginary part of input and output data */ +) +{ + Word16 j; + + /* Applying 32-point FFT for 5 times based on the address table Idx_dortft160 */ + FOR(j=0; j<5; j++) + { + fft32_5_16fx(x,y,Idx_dortft160+shl(j,5)/*32*j*/); + } + + /* Applying 5-point FFT for 32 times based on the address table Idx_dortft160 */ + FOR(j=0; j<32; j++) + { + fft5_32_16fx(x,y,Idx_dortft160+j); + } + + return; +} + +/*-----------------------------------------------------------------* +* DoRTFT320() +* a low complexity 2-dimensional DFT of 320 points +*-----------------------------------------------------------------*/ +void DoRTFT320_16fx( + Word16 *x, /* i/o : real part of input and output data */ + Word16 *y /* i/o : imaginary part of input and output data */ +) +{ + Word16 j; + + /* Applying 64-point FFT for 5 times based on the address table Idx_dortft160 */ + FOR(j=0; j<5; j++) + { + fft64_16fx(x,y,Idx_dortft320+shl(j,6)/*64*j*/); + } + + /* Applying 5-point FFT for 64 times based on the address table Idx_dortft160 */ + FOR(j=0; j<64; j++) + { + fft5_shift4_16fx(64,x,y,Idx_dortft320+j); + } + + return; +} + +/*-----------------------------------------------------------------* +* DoRTFT128() +* FFT with 128 points +*-----------------------------------------------------------------*/ +void DoRTFT128_16fx( + Word16 *x, /* i/o : real part of input and output data Q(Qx+Q_edct)*/ + Word16 *y /* i/o : imaginary part of input and output data Q(Qx+Q_edct)*/ +) +{ + + Word16 i; + Word16 z[256]; + + move16();/*penalty for 1 ptr init */ + FOR ( i=0; i<128; i++ ) + { + z[2*i] = x[i]; + move16(); + z[2*i+1] = y[i]; + move16(); + } + + cdftForw_16fx(256,z,Ip_fft128,w_fft128_16fx); + + x[0]=z[0]; + move16(); + y[0]=z[1]; + move16(); + move16();/*penalty for 1 ptr init */ + move16();/*penalty for 1 ptr init */ + FOR( i=1; i<128 ; i++) + { + x[128-i]=z[2*i]; + move16(); + y[128-i]=z[2*i+1]; + move16(); + } + + return; +} +/*-----------------------------------------------------------------* +* cdftForw() +* Main fuction of Complex Discrete Fourier Transform +*-----------------------------------------------------------------*/ +static void cdftForw_16fx( + Word16 n, /* i : data length of real and imag */ + Word16 *a, /* i/o : input/output data Q(Qx+Q_edct)*/ + const Word16 *ip, /* i : work area for bit reversal */ + const Word32 *w /* i : cos/sin table Q30*/ +) +{ + /* bit reversal */ + bitrv2_SR_16fx(n, ip + 2, a); + + /* Do FFT */ + cftfsub_16fx(n, a, w); +} + +/*-----------------------------------------------------------------* +* bitrv2_SR() +* Bit reversal +*-----------------------------------------------------------------*/ +static void bitrv2_SR_16fx( + Word16 n, /* i : data length of real and imag */ + const Word16 *ip, /* i/o : work area for bit reversal */ + Word16 *a /* i/o : input/output data Q(Qx+Q_edct)*/ +) +{ + Word16 j, j1, k, k1, m, m2; + Word16 l; + Word16 xr, xi, yr, yi; + + l = n; + move16(); + m = 1; + move16(); + + WHILE (LT_16(shl(m,3),l)) + { + l = shr(l,1); + m = shl(m,1); + } + + m2 = shl(m,1); + IF (EQ_16(shl(m, 3),l)) + { + FOR (k = 0; k < m; k++) + { + FOR (j = 0; j < k; j++) + { + j1 = add(shl(j,1),ip[k]); + k1 = add(shl(k,1),ip[j]); + xr = a[j1]; + move16(); + xi = a[j1 + 1]; + move16(); + yr = a[k1]; + move16(); + yi = a[k1 + 1]; + move16(); + a[j1] = yr; + move16(); + a[j1 + 1] = yi; + move16(); + a[k1] = xr; + move16(); + a[k1 + 1] = xi; + move16(); + j1 = add(j1,m2); + k1 = add(k1,shl(m2,1)); + xr = a[j1]; + move16(); + xi = a[j1 + 1]; + move16(); + yr = a[k1]; + move16(); + yi = a[k1 + 1]; + move16(); + a[j1] = yr; + move16(); + a[j1 + 1] = yi; + move16(); + a[k1] = xr; + move16(); + a[k1 + 1] = xi; + move16(); + j1 = add(j1,m2); + k1 = sub(k1,m2); + xr = a[j1]; + move16(); + xi = a[j1 + 1]; + move16(); + xi = a[j1 + 1]; + move16(); + yr = a[k1]; + move16(); + yi = a[k1 + 1]; + move16(); + a[j1] = yr; + move16(); + a[j1 + 1] = yi; + move16(); + a[k1] = xr; + move16(); + a[k1 + 1] = xi; + move16(); + j1 = add(j1,m2); + k1 = add(k1,shl(m2,1)); + xr = a[j1]; + move16(); + xi = a[j1 + 1]; + move16(); + yr = a[k1]; + move16(); + yi = a[k1 + 1]; + move16(); + a[j1] = yr; + move16(); + a[j1 + 1] = yi; + move16(); + a[k1] = xr; + move16(); + a[k1 + 1] = xi; + move16(); + } + + j1 = add(add(shl(k,1),m2),ip[k]); + k1 = add(j1,m2); + xr = a[j1]; + move16(); + xi = a[j1 + 1]; + move16(); + yr = a[k1]; + move16(); + yi = a[k1 + 1]; + move16(); + a[j1] = yr; + move16(); + a[j1 + 1] = yi; + move16(); + a[k1] = xr; + move16(); + a[k1 + 1] = xi; + move16(); + } + } + ELSE + { + FOR (k = 1; k < m; k++) + { + FOR (j = 0; j < k; j++) + { + j1 = add(shl(j,1),ip[k]); + k1 = add(shl(k,1),ip[j]); + xr = a[j1]; + move16(); + xi = a[j1 + 1]; + move16(); + yr = a[k1]; + move16(); + yi = a[k1 + 1]; + move16(); + a[j1] = yr; + move16(); + a[j1 + 1] = yi; + move16(); + a[k1] = xr; + move16(); + a[k1 + 1] = xi; + move16(); + j1 = add(j1,m2); + k1 = add(k1,m2); + xr = a[j1]; + move16(); + xi = a[j1 + 1]; + move16(); + yr = a[k1]; + move16(); + yi = a[k1 + 1]; + move16(); + a[j1] = yr; + move16(); + a[j1 + 1] = yi; + move16(); + a[k1] = xr; + move16(); + a[k1 + 1] = xi; + move16(); + } + } + } + + return; +} + +/*-----------------------------------------------------------------* +* cftfsub() +* Complex Discrete Fourier Transform +*-----------------------------------------------------------------*/ +static void cftfsub_16fx( + Word16 n, /* i : data length of real and imag */ + Word16 *a, /* i/o : input/output data Q(Qx+Q_edct)*/ + const Word32 *w /* i : cos/sin table Q30*/ +) +{ + Word16 j, j1, j2, j3, l; + Word16 x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + + l = 2; + move16(); + IF (GT_16(n,8)) + { + cft1st_16fx(n, a, w); + l = 8; + move16(); + WHILE (LT_16(shl(l, 2),n)) + { + cftmdl_16fx(n, l, a, w); + l = shl(l,2); + } + } + + IF (EQ_16(shl(l,2),n)) + { + FOR (j = 0; j < l; j += 2) + { + j1 = add(j,l); + j2 = add(j1,l); + j3 = add(j2,l); + x0r = add(a[j],a[j1]); + x0i = add(a[j + 1],a[j1 + 1]); + x1r = sub(a[j],a[j1]); + x1i = sub(a[j + 1],a[j1 + 1]); + x2r = add(a[j2],a[j3]); + x2i = add(a[j2 + 1],a[j3 + 1]); + x3r = sub(a[j2],a[j3]); + x3i = sub(a[j2 + 1],a[j3 + 1]); + a[j] = add(x0r,x2r); + move16(); + a[j + 1] = add(x0i,x2i); + move16(); + a[j2] = sub(x0r,x2r); + move16(); + a[j2 + 1] = sub(x0i,x2i); + move16(); + a[j1] = sub(x1r,x3i); + move16(); + a[j1 + 1] = add(x1i,x3r); + move16(); + a[j3] = add(x1r,x3i); + move16(); + a[j3 + 1] = sub(x1i,x3r); + move16(); + } + } + ELSE + { + FOR (j = 0; j < l; j += 2) + { +#ifdef BASOP_NOGLOB + j1 = add_o(j,l, &Overflow); + x0r = sub_o(a[j],a[j1], &Overflow); + x0i = sub_o(a[j + 1],a[j1 + 1], &Overflow); + a[j] = add_o(a[j],a[j1], &Overflow); + move16(); + a[j + 1] = add_o(a[j + 1],a[j1 + 1], &Overflow); + move16(); + a[j1] = x0r; + move16(); + a[j1 + 1] = x0i; + move16(); +#else + j1 = add(j,l); + x0r = sub(a[j],a[j1]); + x0i = sub(a[j + 1],a[j1 + 1]); + a[j] = add(a[j],a[j1]); + move16(); + a[j + 1] = add(a[j + 1],a[j1 + 1]); + move16(); + a[j1] = x0r; + move16(); + a[j1 + 1] = x0i; + move16(); +#endif + } + } + return; +} + +/*-----------------------------------------------------------------* +* cft1st() +* Subfunction of Complex Discrete Fourier Transform +*-----------------------------------------------------------------*/ +static void cft1st_16fx( + Word16 n, /* i : data length of real and imag */ + Word16 *a, /* i/o : input/output data Q(Qx+Q_edct)*/ + const Word32 *w /* i : cos/sin table Q30*/ +) +{ + Word16 j, k1, k2; + Word32 wk1r, wk1i, wk2r, wk2i, wk3r, wk3i; + Word16 x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i; + Word16 tmp; + Word32 L_tmp; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + +#ifdef BASOP_NOGLOB + x0r = add_o(a[0],a[2], &Overflow); + x0i = add_o(a[1],a[3], &Overflow); + x1r = sub_o(a[0],a[2], &Overflow); + x1i = sub_o(a[1],a[3], &Overflow); + x2r = add_o(a[4],a[6], &Overflow); + x2i = add_o(a[5],a[7], &Overflow); + x3r = sub_o(a[4],a[6], &Overflow); + x3i = sub_o(a[5],a[7], &Overflow); + a[0] = add_o(x0r,x2r, &Overflow); + move16(); + a[1] = add_o(x0i,x2i, &Overflow); + move16(); + a[4] = sub_o(x0r,x2r, &Overflow); + move16(); + a[5] = sub_o(x0i,x2i, &Overflow); + move16(); + a[2] = sub_o(x1r,x3i, &Overflow); + move16(); + a[3] = add_o(x1i,x3r, &Overflow); + move16(); + a[6] = add_o(x1r,x3i, &Overflow); + move16(); + a[7] = sub_o(x1i,x3r, &Overflow); +#else + x0r = add(a[0],a[2]); + x0i = add(a[1],a[3]); + x1r = sub(a[0],a[2]); + x1i = sub(a[1],a[3]); + x2r = add(a[4],a[6]); + x2i = add(a[5],a[7]); + x3r = sub(a[4],a[6]); + x3i = sub(a[5],a[7]); + a[0] = add(x0r,x2r); + move16(); + a[1] = add(x0i,x2i); + move16(); + a[4] = sub(x0r,x2r); + move16(); + a[5] = sub(x0i,x2i); + move16(); + a[2] = sub(x1r,x3i); + move16(); + a[3] = add(x1i,x3r); + move16(); + a[6] = add(x1r,x3i); + move16(); + a[7] = sub(x1i,x3r); + move16(); +#endif + wk1r = w[2]; + move32(); + +#ifdef BASOP_NOGLOB + x0r = add_o(a[8],a[10], &Overflow); + x0i = add_o(a[9],a[11], &Overflow); + x1r = sub_o(a[8],a[10], &Overflow); + x1i = sub_o(a[9],a[11], &Overflow); + x2r = add_o(a[12],a[14], &Overflow); + x2i = add_o(a[13],a[15], &Overflow); + x3r = sub_o(a[12],a[14], &Overflow); + x3i = sub_o(a[13],a[15], &Overflow); + a[8] = add_o(x0r,x2r, &Overflow); + move16(); + a[9] = add_o(x0i,x2i, &Overflow); + move16(); + a[12] = sub_o(x2i,x0i, &Overflow); + move16(); + a[13] = sub_o(x0r,x2r, &Overflow); + move16(); + + x0r = sub_o(x1r,x3i, &Overflow); + x0i = add_o(x1i,x3r, &Overflow); + tmp = sub_o(x0r,x0i, &Overflow); +#else + x0r = add(a[8],a[10]); + x0i = add(a[9],a[11]); + x1r = sub(a[8],a[10]); + x1i = sub(a[9],a[11]); + x2r = add(a[12],a[14]); + x2i = add(a[13],a[15]); + x3r = sub(a[12],a[14]); + x3i = sub(a[13],a[15]); + a[8] = add(x0r,x2r); + move16(); + a[9] = add(x0i,x2i); + move16(); + a[12] = sub(x2i,x0i); + move16(); + a[13] = sub(x0r,x2r); + move16(); + + x0r = sub(x1r,x3i); + x0i = add(x1i,x3r); + tmp = sub(x0r,x0i); +#endif + L_tmp = Mult_32_16(wk1r,tmp); /*Q(15+Qx+Q_edct) */ + +#ifdef BASOP_NOGLOB + a[10] = round_fx_o(L_shl_o(L_tmp,1, &Overflow), &Overflow); /*Q(Qx+Q_edct) */ + + tmp = add_o(x0r,x0i, &Overflow); + L_tmp = Mult_32_16(wk1r,tmp); /*Q(15+Qx+Q_edct) */ + a[11] = round_fx_o(L_shl_o(L_tmp,1, &Overflow), &Overflow); /* Q(Qx+Q_edct) */ + + x0r = add_o(x3i,x1r, &Overflow); + x0i = sub_o(x3r,x1i, &Overflow); + tmp = sub_o(x0i,x0r, &Overflow); + L_tmp = Mult_32_16(wk1r,tmp); /*Q(15+Qx+Q_edct) */ + a[14] = round_fx_o(L_shl_o(L_tmp,1, &Overflow), &Overflow); /*Q(Qx+Q_edct) */ + + tmp = add_o(x0i,x0r, &Overflow); + L_tmp = Mult_32_16(wk1r,tmp); /*Q(15+Qx+Q_edct) */ + a[15] = round_fx_o(L_shl_o(L_tmp,1, &Overflow), &Overflow); /*Q(Qx+Q_edct) */ +#else + a[10] = round_fx(L_shl(L_tmp,1)); /*Q(Qx+Q_edct) */ + + tmp = add(x0r,x0i); + L_tmp = Mult_32_16(wk1r,tmp); /*Q(15+Qx+Q_edct) */ + a[11] = round_fx(L_shl(L_tmp,1)); /* Q(Qx+Q_edct) */ + + x0r = add(x3i,x1r); + x0i = sub(x3r,x1i); + tmp = sub(x0i,x0r); + L_tmp = Mult_32_16(wk1r,tmp); /*Q(15+Qx+Q_edct) */ + a[14] = round_fx(L_shl(L_tmp,1)); /*Q(Qx+Q_edct) */ + + tmp = add(x0i,x0r); + L_tmp = Mult_32_16(wk1r,tmp); /*Q(15+Qx+Q_edct) */ + a[15] = round_fx(L_shl(L_tmp,1)); /*Q(Qx+Q_edct) */ +#endif + k1 = 0; + move16(); + + FOR (j = 16; j < n; j += 16) + { + k1 = add(k1,2); + k2 = shl(k1,1); + + wk2r = w[k1]; move32(); + wk2i = w[k1 + 1]; move32(); + wk1r = w[k2]; move32(); + wk1i = w[k2 + 1]; move32(); + + L_tmp = L_shl(Mult_32_32(wk2i,wk1i),1);/*Q29 */ + wk3r = L_sub(wk1r,L_shl(L_tmp,1));/*Q30 */ + + L_tmp = L_shl(Mult_32_32(wk2i,wk1r),1);/*Q29 */ + wk3i = L_sub(L_shl(L_tmp,1),wk1i);/*Q30 */ +#ifdef BASOP_NOGLOB + x0r = add_o(a[j], a[j + 2], &Overflow); + x0i = add_o(a[j + 1], a[j + 3], &Overflow); + x1r = sub_o(a[j], a[j + 2], &Overflow); + x1i = sub_o(a[j + 1], a[j + 3], &Overflow); + x2r = add_o(a[j + 4], a[j + 6], &Overflow); + x2i = add_o(a[j + 5], a[j + 7], &Overflow); + x3r = sub_o(a[j + 4], a[j + 6], &Overflow); + x3i = sub_o(a[j + 5], a[j + 7], &Overflow); + a[j] = add_o(x0r, x2r, &Overflow); + move16(); + a[j + 1] = add_o(x0i, x2i, &Overflow); + move16(); + + x0r = sub_o(x0r, x2r, &Overflow); + x0i = sub_o(x0i, x2i, &Overflow); + L_tmp = Mult_32_16(wk2r, x0r);/*Q(15+Qx+Q_edct) */ + L_tmp = Msub_32_16(L_tmp, wk2i, x0i); /*Q(15+Qx+Q_edct) */ + a[j + 4] = round_fx_o(L_shl_o(L_tmp, 1, &Overflow), &Overflow); /*Q(Qx+Q_edct) */ + + L_tmp = Mult_32_16(wk2r, x0i);/*Q(15+Qx+Q_edct) */ + L_tmp = Madd_32_16(L_tmp, wk2i, x0r); /*Q(15+Qx+Q_edct) */ + a[j + 5] = round_fx_o(L_shl_o(L_tmp, 1, &Overflow), &Overflow); /*Q(Qx+Q_edct) */ + + x0r = sub_o(x1r, x3i, &Overflow); + x0i = add_o(x1i, x3r, &Overflow); + L_tmp = Mult_32_16(wk1r, x0r);/*Q(15+Qx+Q_edct) */ + L_tmp = Msub_32_16(L_tmp, wk1i, x0i); /*Q(15+Qx+Q_edct) */ + a[j + 2] = round_fx_o(L_shl_o(L_tmp, 1, &Overflow), &Overflow); /*Q(Qx+Q_edct) */ + + L_tmp = Mult_32_16(wk1r, x0i);/*Q(15+Qx+Q_edct) */ + L_tmp = Madd_32_16(L_tmp, wk1i, x0r); /*Q(15+Qx+Q_edct) */ + a[j + 3] = round_fx_o(L_shl_o(L_tmp, 1, &Overflow), &Overflow); /*Q(Qx+Q_edct) */ + + x0r = add_o(x1r, x3i, &Overflow); + x0i = sub_o(x1i, x3r, &Overflow); + L_tmp = Mult_32_16(wk3r, x0r); /*Q(15+Qx+Q_edct) */ + L_tmp = Msub_32_16(L_tmp, wk3i, x0i); /*Q(15+Qx+Q_edct) */ + a[j + 6] = round_fx_o(L_shl_o(L_tmp, 1, &Overflow), &Overflow); /*Q(Qx+Q_edct) */ + + L_tmp = Mult_32_16(wk3r, x0i); /*Q(15+Qx+Q_edct) */ + L_tmp = Madd_32_16(L_tmp, wk3i, x0r); /*Q(15+Qx+Q_edct) */ + a[j + 7] = round_fx_o(L_shl_o(L_tmp, 1, &Overflow), &Overflow); /*Q(Qx+Q_edct) */ + + wk1r = w[k2 + 2]; move32(); + wk1i = w[k2 + 3]; move32(); + L_tmp = L_shl(Mult_32_32(wk2r, wk1i), 1);/*Q29 */ + wk3r = L_sub(wk1r, L_shl(L_tmp, 1)); /*Q30 */ + + L_tmp = L_shl(Mult_32_32(wk2r, wk1r), 1);/*Q29 */ + wk3i = L_sub(L_shl(L_tmp, 1), wk1i); /*Q30 */ + + x0r = add_o(a[j + 8], a[j + 10], &Overflow); + x0i = add_o(a[j + 9], a[j + 11], &Overflow); + x1r = sub_o(a[j + 8], a[j + 10], &Overflow); + x1i = sub_o(a[j + 9], a[j + 11], &Overflow); + x2r = add_o(a[j + 12], a[j + 14], &Overflow); + x2i = add_o(a[j + 13], a[j + 15], &Overflow); + x3r = sub_o(a[j + 12], a[j + 14], &Overflow); + x3i = sub_o(a[j + 13], a[j + 15], &Overflow); + a[j + 8] = add_o(x0r, x2r, &Overflow); + move16(); + a[j + 9] = add_o(x0i, x2i, &Overflow); + move16(); + + x0r = sub_o(x0r, x2r, &Overflow); + x0i = sub_o(x0i, x2i, &Overflow); + tmp = negate(x0r); + L_tmp = Mult_32_16(wk2i, tmp);/*Q(15+Qx+Q_edct) */ + L_tmp = Msub_32_16(L_tmp, wk2r, x0i); /*Q(15+Qx+Q_edct) */ + a[j + 12] = round_fx_o(L_shl_o(L_tmp, 1, &Overflow), &Overflow); /*Q(Qx+Q_edct) */ + + tmp = negate(x0i); + L_tmp = Mult_32_16(wk2i, tmp);/*Q(15+Qx+Q_edct) */ + L_tmp = Madd_32_16(L_tmp, wk2r, x0r); /*Q(15+Qx+Q_edct) */ + a[j + 13] = round_fx_o(L_shl_o(L_tmp, 1, &Overflow), &Overflow); /*Q(Qx+Q_edct) */ + + x0r = sub_o(x1r, x3i, &Overflow); + x0i = add_o(x1i, x3r, &Overflow); + L_tmp = Mult_32_16(wk1r, x0r);/*Q(15+Qx+Q_edct) */ + L_tmp = Msub_32_16(L_tmp, wk1i, x0i); /*Q(15+Qx+Q_edct) */ + a[j + 10] = round_fx_o(L_shl_o(L_tmp, 1, &Overflow), &Overflow); /*Q(Qx+Q_edct) */ + + L_tmp = Mult_32_16(wk1r, x0i);/*Q(15+Qx+Q_edct) */ + L_tmp = Madd_32_16(L_tmp, wk1i, x0r); /*Q(15+Qx+Q_edct) */ + a[j + 11] = round_fx_o(L_shl_o(L_tmp, 1, &Overflow), &Overflow); /*Q(Qx+Q_edct) */ + + x0r = add_o(x1r, x3i, &Overflow); + x0i = sub_o(x1i, x3r, &Overflow); + + L_tmp = Mult_32_16(wk3r, x0r); /*Q(15+Qx+Q_edct) */ + L_tmp = Msub_32_16(L_tmp, wk3i, x0i); /*Q(15+Qx+Q_edct) */ + a[j + 14] = round_fx_o(L_shl_o(L_tmp, 1, &Overflow), &Overflow); /*Q(Qx+Q_edct) */ + + L_tmp = Mult_32_16(wk3r, x0i); /*Q(15+Qx+Q_edct) */ + L_tmp = Madd_32_16(L_tmp, wk3i, x0r); /*Q(15+Qx+Q_edct) */ + a[j + 15] = round_fx_o(L_shl_o(L_tmp, 1, &Overflow), &Overflow); /*Q(Qx+Q_edct) */ +#else + x0r = add(a[j],a[j + 2]); + x0i = add(a[j + 1],a[j + 3]); + x1r = sub(a[j],a[j + 2]); + x1i = sub(a[j + 1],a[j + 3]); + x2r = add(a[j + 4],a[j + 6]); + x2i = add(a[j + 5],a[j + 7]); + x3r = sub(a[j + 4],a[j + 6]); + x3i = sub(a[j + 5],a[j + 7]); + a[j] = add(x0r,x2r); + move16(); + a[j + 1] = add(x0i,x2i); + move16(); + + x0r = sub(x0r,x2r); + x0i = sub(x0i,x2i); + L_tmp = Mult_32_16(wk2r,x0r);/*Q(15+Qx+Q_edct) */ + L_tmp = Msub_32_16(L_tmp,wk2i,x0i); /*Q(15+Qx+Q_edct) */ + a[j + 4] = round_fx(L_shl(L_tmp,1)); /*Q(Qx+Q_edct) */ + + L_tmp = Mult_32_16(wk2r,x0i);/*Q(15+Qx+Q_edct) */ + L_tmp = Madd_32_16(L_tmp,wk2i,x0r); /*Q(15+Qx+Q_edct) */ + a[j + 5] = round_fx(L_shl(L_tmp,1)); /*Q(Qx+Q_edct) */ + + x0r = sub(x1r,x3i); + x0i = add(x1i,x3r); + L_tmp = Mult_32_16(wk1r,x0r);/*Q(15+Qx+Q_edct) */ + L_tmp = Msub_32_16(L_tmp,wk1i,x0i); /*Q(15+Qx+Q_edct) */ + a[j + 2] = round_fx(L_shl(L_tmp,1)); /*Q(Qx+Q_edct) */ + + L_tmp = Mult_32_16(wk1r,x0i);/*Q(15+Qx+Q_edct) */ + L_tmp = Madd_32_16(L_tmp,wk1i,x0r); /*Q(15+Qx+Q_edct) */ + a[j + 3] = round_fx(L_shl(L_tmp,1)); /*Q(Qx+Q_edct) */ + + x0r = add(x1r,x3i); + x0i = sub(x1i,x3r); + L_tmp = Mult_32_16(wk3r,x0r); /*Q(15+Qx+Q_edct) */ + L_tmp = Msub_32_16(L_tmp,wk3i,x0i); /*Q(15+Qx+Q_edct) */ + a[j + 6] = round_fx(L_shl(L_tmp,1)); /*Q(Qx+Q_edct) */ + + L_tmp = Mult_32_16(wk3r,x0i); /*Q(15+Qx+Q_edct) */ + L_tmp = Madd_32_16(L_tmp,wk3i,x0r); /*Q(15+Qx+Q_edct) */ + a[j + 7] = round_fx(L_shl(L_tmp,1)); /*Q(Qx+Q_edct) */ + + wk1r = w[k2 + 2]; move32(); + wk1i = w[k2 + 3]; move32(); + L_tmp = L_shl(Mult_32_32(wk2r,wk1i),1);/*Q29 */ + wk3r = L_sub(wk1r,L_shl(L_tmp,1)); /*Q30 */ + + L_tmp = L_shl(Mult_32_32(wk2r,wk1r),1);/*Q29 */ + wk3i = L_sub(L_shl(L_tmp,1),wk1i); /*Q30 */ + + x0r = add(a[j + 8],a[j + 10]); + x0i = add(a[j + 9],a[j + 11]); + x1r = sub(a[j + 8],a[j + 10]); + x1i = sub(a[j + 9],a[j + 11]); + x2r = add(a[j + 12],a[j + 14]); + x2i = add(a[j + 13],a[j + 15]); + x3r = sub(a[j + 12],a[j + 14]); + x3i = sub(a[j + 13],a[j + 15]); + a[j + 8] = add(x0r,x2r); + move16(); + a[j + 9] = add(x0i,x2i); + move16(); + + x0r = sub(x0r,x2r); + x0i = sub(x0i,x2i); + tmp = negate(x0r); + L_tmp = Mult_32_16(wk2i,tmp);/*Q(15+Qx+Q_edct) */ + L_tmp = Msub_32_16(L_tmp,wk2r,x0i); /*Q(15+Qx+Q_edct) */ + a[j + 12] = round_fx(L_shl(L_tmp,1)); /*Q(Qx+Q_edct) */ + + tmp = negate(x0i); + L_tmp = Mult_32_16(wk2i,tmp);/*Q(15+Qx+Q_edct) */ + L_tmp = Madd_32_16(L_tmp,wk2r,x0r); /*Q(15+Qx+Q_edct) */ + a[j + 13] = round_fx(L_shl(L_tmp,1)); /*Q(Qx+Q_edct) */ + + x0r = sub(x1r,x3i); + x0i = add(x1i,x3r); + L_tmp = Mult_32_16(wk1r,x0r);/*Q(15+Qx+Q_edct) */ + L_tmp = Msub_32_16(L_tmp,wk1i,x0i); /*Q(15+Qx+Q_edct) */ + a[j + 10] = round_fx(L_shl(L_tmp,1)); /*Q(Qx+Q_edct) */ + + L_tmp = Mult_32_16(wk1r,x0i);/*Q(15+Qx+Q_edct) */ + L_tmp = Madd_32_16(L_tmp,wk1i,x0r); /*Q(15+Qx+Q_edct) */ + a[j + 11] = round_fx(L_shl(L_tmp,1)); /*Q(Qx+Q_edct) */ + + x0r = add(x1r,x3i); + x0i = sub(x1i,x3r); + + L_tmp = Mult_32_16(wk3r,x0r); /*Q(15+Qx+Q_edct) */ + L_tmp = Msub_32_16(L_tmp,wk3i,x0i); /*Q(15+Qx+Q_edct) */ + a[j + 14] = round_fx(L_shl(L_tmp,1)); /*Q(Qx+Q_edct) */ + + L_tmp = Mult_32_16(wk3r,x0i); /*Q(15+Qx+Q_edct) */ + L_tmp = Madd_32_16(L_tmp,wk3i,x0r); /*Q(15+Qx+Q_edct) */ + a[j + 15] = round_fx(L_shl(L_tmp,1)); /*Q(Qx+Q_edct) */ +#endif + } + + return; +} + +/*-----------------------------------------------------------------* +* cftmdl() +* Subfunction of Complex Discrete Fourier Transform +*-----------------------------------------------------------------*/ +static void cftmdl_16fx( + Word16 n, /* i : data length of real and imag */ + Word16 l, /* i : initial shift for processing */ + Word16 *a, /* i/o : input/output data Q(Qx+Q_edct)*/ + const Word32 *w /* i : cos/sin table Q30*/ +) +{ + Word16 j, j1, j2, j3, k, k1, k2, m, m2; + Word32 wk1r, wk1i, wk2r, wk2i, wk3r, wk3i; + Word16 x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i; + Word16 tmp, tmp2; + Word32 L_tmp; + Word32 L_x0r, L_x0i; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + m = shl(l, 2); + move16(); + FOR (j = 0; j < l; j += 2) + { +#ifdef BASOP_NOGLOB + j1 = add_o(j, l, &Overflow); + j2 = add_o(j1, l, &Overflow); + j3 = add_o(j2, l, &Overflow); + x0r = add_o(a[j], a[j1], &Overflow); + x0i = add_o(a[j + 1], a[j1 + 1], &Overflow); + x1r = sub_o(a[j], a[j1], &Overflow); + x1i = sub_o(a[j + 1], a[j1 + 1], &Overflow); + x2r = add_o(a[j2], a[j3], &Overflow); + x2i = add_o(a[j2 + 1], a[j3 + 1], &Overflow); + x3r = sub_o(a[j2], a[j3], &Overflow); + x3i = sub_o(a[j2 + 1], a[j3 + 1], &Overflow); + a[j] = add_o(x0r, x2r, &Overflow); + move16(); + a[j + 1] = add_o(x0i, x2i, &Overflow); + move16(); + a[j2] = sub_o(x0r, x2r, &Overflow); + move16(); + a[j2 + 1] = sub_o(x0i, x2i, &Overflow); + move16(); + a[j1] = sub_o(x1r, x3i, &Overflow); + move16(); + a[j1 + 1] = add_o(x1i, x3r, &Overflow); + move16(); + a[j3] = add_o(x1r, x3i, &Overflow); + move16(); + a[j3 + 1] = sub_o(x1i, x3r, &Overflow); + move16(); +#else + j1 = add(j,l); + j2 = add(j1,l); + j3 = add(j2,l); + x0r = add(a[j],a[j1]); + x0i = add(a[j + 1],a[j1 + 1]); + x1r = sub(a[j],a[j1]); + x1i = sub(a[j + 1],a[j1 + 1]); + x2r = add(a[j2],a[j3]); + x2i = add(a[j2 + 1],a[j3 + 1]); + x3r = sub(a[j2],a[j3]); + x3i = sub(a[j2 + 1],a[j3 + 1]); + a[j] = add(x0r,x2r); + move16(); + a[j + 1] = add(x0i,x2i); + move16(); + a[j2] = sub(x0r,x2r); + move16(); + a[j2 + 1] = sub(x0i,x2i); + move16(); + a[j1] = sub(x1r,x3i); + move16(); + a[j1 + 1] = add(x1i,x3r); + move16(); + a[j3] = add(x1r,x3i); + move16(); + a[j3 + 1] = sub(x1i,x3r); + move16(); +#endif + } + + wk1r = w[2]; + move32(); + tmp2 = add(l,m); + FOR (j = m; j < tmp2; j += 2) + { +#ifdef BASOP_NOGLOB + j1 = add_o(j, l, &Overflow); + j2 = add_o(j1, l, &Overflow); + j3 = add_o(j2, l, &Overflow); + x0r = add_o(a[j], a[j1], &Overflow); + x0i = add_o(a[j + 1], a[j1 + 1], &Overflow); + x1r = sub_o(a[j], a[j1], &Overflow); + x1i = sub_o(a[j + 1], a[j1 + 1], &Overflow); + x2r = add_o(a[j2], a[j3], &Overflow); + x2i = add_o(a[j2 + 1], a[j3 + 1], &Overflow); + x3r = sub_o(a[j2], a[j3], &Overflow); + x3i = sub_o(a[j2 + 1], a[j3 + 1], &Overflow); + a[j] = add_o(x0r, x2r, &Overflow); + move16(); + a[j + 1] = add_o(x0i, x2i, &Overflow); + move16(); + a[j2] = sub_o(x2i, x0i, &Overflow); + move16(); + a[j2 + 1] = sub_o(x0r, x2r, &Overflow); + move16(); + + x0r = sub_o(x1r, x3i, &Overflow); + x0i = add_o(x1i, x3r, &Overflow); + tmp = sub_o(x0r, x0i, &Overflow); + L_tmp = Mult_32_16(wk1r, tmp);/*Q(15+Qx+Q_edct) */ + a[j1] = round_fx_o(L_shl_o(L_tmp, 1, &Overflow), &Overflow); /*Q(Qx+Q_edct) */ + + tmp = add_o(x0r, x0i, &Overflow); + L_tmp = Mult_32_16(wk1r, tmp); /*Q(15+Qx+Q_edct) */ + a[j1 + 1] = round_fx_o(L_shl_o(L_tmp, 1, &Overflow), &Overflow); /*Q(Qx+Q_edct) */ + + x0r = add_o(x3i, x1r, &Overflow); + x0i = sub_o(x3r, x1i, &Overflow); + tmp = sub_o(x0i, x0r, &Overflow); + L_tmp = Mult_32_16(wk1r, tmp);/*Q(15+Qx+Q_edct) */ + a[j3] = round_fx_o(L_shl_o(L_tmp, 1, &Overflow), &Overflow); /*Q(Qx+Q_edct) */ + + tmp = add_o(x0i, x0r, &Overflow); + L_tmp = Mult_32_16(wk1r, tmp); /*Q(15+Qx+Q_edct) */ + a[j3 + 1] = round_fx_o(L_shl_o(L_tmp, 1, &Overflow), &Overflow); /*Q(Qx+Q_edct) */ +#else + j1 = add(j,l); + j2 = add(j1,l); + j3 = add(j2,l); + x0r = add(a[j],a[j1]); + x0i = add(a[j + 1],a[j1 + 1]); + x1r = sub(a[j],a[j1]); + x1i = sub(a[j + 1],a[j1 + 1]); + x2r = add(a[j2],a[j3]); + x2i = add(a[j2 + 1],a[j3 + 1]); + x3r = sub(a[j2],a[j3]); + x3i = sub(a[j2 + 1],a[j3 + 1]); + a[j] = add(x0r,x2r); + move16(); + a[j + 1] = add(x0i,x2i); + move16(); + a[j2] = sub(x2i,x0i); + move16(); + a[j2 + 1] = sub(x0r,x2r); + move16(); + + x0r = sub(x1r,x3i); + x0i = add(x1i,x3r); + tmp = sub(x0r,x0i); + L_tmp = Mult_32_16(wk1r,tmp);/*Q(15+Qx+Q_edct) */ + a[j1] = round_fx(L_shl(L_tmp,1)); /*Q(Qx+Q_edct) */ + + tmp = add(x0r,x0i); + L_tmp = Mult_32_16(wk1r,tmp); /*Q(15+Qx+Q_edct) */ + a[j1 + 1] = round_fx(L_shl(L_tmp,1)); /*Q(Qx+Q_edct) */ + + x0r = add(x3i,x1r); + x0i = sub(x3r,x1i); + tmp = sub(x0i,x0r); + L_tmp = Mult_32_16(wk1r,tmp);/*Q(15+Qx+Q_edct) */ + a[j3] = round_fx(L_shl(L_tmp,1)); /*Q(Qx+Q_edct) */ + + tmp = add(x0i,x0r); + L_tmp = Mult_32_16(wk1r,tmp); /*Q(15+Qx+Q_edct) */ + a[j3 + 1] = round_fx(L_shl(L_tmp,1)); /*Q(Qx+Q_edct) */ +#endif + } + + k1 = 0; + move16(); + m2 = shl(m,1); + FOR (k = m2; k < n; k += m2) + { + k1 = add(k1,2); + k2 = shl(k1,1); + wk2r = w[k1]; move32(); + wk2i = w[k1 + 1]; move32(); + wk1r = w[k2]; move32(); + wk1i = w[k2 + 1]; move32(); + L_tmp = L_shl(Mult_32_32(wk2i,wk1i),1);/*Q29 */ + wk3r = L_sub(wk1r,L_shl(L_tmp,1));/*Q30 */ + + L_tmp = L_shl(Mult_32_32(wk2i,wk1r),1);/*Q29 */ + wk3i = L_sub(L_shl(L_tmp,1),wk1i);/*Q30 */ + + tmp2 = add(l,k); + FOR (j = k; j < tmp2; j += 2) + { +#ifdef BASOP_NOGLOB + j1 = add_o(j, l, &Overflow); + j2 = add_o(j1, l, &Overflow); + j3 = add_o(j2, l, &Overflow); + x0r = add_o(a[j], a[j1], &Overflow); + x0i = add_o(a[j + 1], a[j1 + 1], &Overflow); + x1r = sub_o(a[j], a[j1], &Overflow); + x1i = sub_o(a[j + 1], a[j1 + 1], &Overflow); + x2r = add_o(a[j2], a[j3], &Overflow); + x2i = add_o(a[j2 + 1], a[j3 + 1], &Overflow); + x3r = sub_o(a[j2], a[j3], &Overflow); + x3i = sub_o(a[j2 + 1], a[j3 + 1], &Overflow); + a[j] = add_o(x0r, x2r, &Overflow); + move16(); + a[j + 1] = add_o(x0i, x2i, &Overflow); + move16(); + + x0r = sub_o(x0r, x2r, &Overflow); + x0i = sub_o(x0i, x2i, &Overflow); + + L_tmp = Mult_32_16(wk2r, x0r); /*Q(15+Qx+Q_edct) */ + L_tmp = Msub_32_16(L_tmp, wk2i, x0i); /*Q(15+Qx+Q_edct) */ + a[j2] = round_fx_o(L_shl_o(L_tmp, 1, &Overflow), &Overflow); /*Q(Qx+Q_edct) */ + + L_tmp = Mult_32_16(wk2r, x0i); /*Q(15+Qx+Q_edct) */ + L_tmp = Madd_32_16(L_tmp, wk2i, x0r); /*Q(15+Qx+Q_edct) */ + a[j2 + 1] = round_fx_o(L_shl_o(L_tmp, 1, &Overflow), &Overflow); /*Q(Qx+Q_edct) */ + + x0r = sub_o(x1r, x3i, &Overflow); + x0i = add_o(x1i, x3r, &Overflow); + + L_tmp = Mult_32_16(wk1r, x0r); /*Q(15+Qx+Q_edct) */ + L_tmp = Msub_32_16(L_tmp, wk1i, x0i); /*Q(15+Qx+Q_edct) */ + a[j1] = round_fx_o(L_shl_o(L_tmp, 1, &Overflow), &Overflow); /*Q(Qx+Q_edct) */ + + L_tmp = Mult_32_16(wk1r, x0i); /*Q(15+Qx+Q_edct) */ + L_tmp = Madd_32_16(L_tmp, wk1i, x0r); /*Q(15+Qx+Q_edct) */ + a[j1 + 1] = round_fx_o(L_shl_o(L_tmp, 1, &Overflow), &Overflow); /*Q(Qx+Q_edct) */ + + L_x0r = L_add((Word32)x1r, (Word32)x3i); + L_x0i = L_sub((Word32)x1i, (Word32)x3r); + x0r = extract_l(L_x0r); + x0i = extract_l(L_x0i); + L_tmp = Mult_32_16(wk3r, x0r); /*Q(15+Qx+Q_edct) */ + L_tmp = Msub_32_16(L_tmp, wk3i, x0i); /*Q(15+Qx+Q_edct) */ + a[j3] = round_fx_o(L_shl_o(L_tmp, 1, &Overflow), &Overflow); /*Q(Qx+Q_edct) */ + + L_tmp = Mult_32_16(wk3r, x0i); /*Q(15+Qx+Q_edct) */ + L_tmp = Madd_32_16(L_tmp, wk3i, x0r); /*Q(15+Qx+Q_edct) */ + a[j3 + 1] = round_fx_o(L_shl_o(L_tmp, 1, &Overflow), &Overflow); /*Q(Qx+Q_edct) */ +#else + j1 = add(j,l); + j2 = add(j1,l); + j3 = add(j2,l); + x0r = add(a[j],a[j1]); + x0i = add(a[j + 1],a[j1 + 1]); + x1r = sub(a[j],a[j1]); + x1i = sub(a[j + 1],a[j1 + 1]); + x2r = add(a[j2],a[j3]); + x2i = add(a[j2 + 1],a[j3 + 1]); + x3r = sub(a[j2],a[j3]); + x3i = sub(a[j2 + 1],a[j3 + 1]); + a[j] = add(x0r,x2r); + move16(); + a[j + 1] = add(x0i,x2i); + move16(); + + x0r = sub(x0r,x2r); + x0i = sub(x0i,x2i); + + L_tmp = Mult_32_16(wk2r,x0r); /*Q(15+Qx+Q_edct) */ + L_tmp = Msub_32_16(L_tmp,wk2i,x0i); /*Q(15+Qx+Q_edct) */ + a[j2] = round_fx(L_shl(L_tmp,1)); /*Q(Qx+Q_edct) */ + + L_tmp = Mult_32_16(wk2r,x0i); /*Q(15+Qx+Q_edct) */ + L_tmp = Madd_32_16(L_tmp,wk2i,x0r); /*Q(15+Qx+Q_edct) */ + a[j2 + 1] = round_fx(L_shl(L_tmp,1)); /*Q(Qx+Q_edct) */ + + x0r = sub(x1r,x3i); + x0i = add(x1i,x3r); + + L_tmp = Mult_32_16(wk1r,x0r); /*Q(15+Qx+Q_edct) */ + L_tmp = Msub_32_16(L_tmp,wk1i,x0i); /*Q(15+Qx+Q_edct) */ + a[j1] = round_fx(L_shl(L_tmp,1)); /*Q(Qx+Q_edct) */ + + L_tmp = Mult_32_16(wk1r,x0i); /*Q(15+Qx+Q_edct) */ + L_tmp = Madd_32_16(L_tmp,wk1i,x0r); /*Q(15+Qx+Q_edct) */ + a[j1 + 1] = round_fx(L_shl(L_tmp,1)); /*Q(Qx+Q_edct) */ + + L_x0r = L_add((Word32) x1r, (Word32) x3i); + L_x0i = L_sub((Word32) x1i, (Word32) x3r); + x0r = extract_l(L_x0r); + x0i = extract_l(L_x0i); + L_tmp = Mult_32_16(wk3r,x0r); /*Q(15+Qx+Q_edct) */ + L_tmp = Msub_32_16(L_tmp,wk3i,x0i); /*Q(15+Qx+Q_edct) */ + a[j3] = round_fx(L_shl(L_tmp,1)); /*Q(Qx+Q_edct) */ + + L_tmp = Mult_32_16(wk3r,x0i); /*Q(15+Qx+Q_edct) */ + L_tmp = Madd_32_16(L_tmp,wk3i,x0r); /*Q(15+Qx+Q_edct) */ + a[j3 + 1] = round_fx(L_shl(L_tmp,1)); /*Q(Qx+Q_edct) */ +#endif + } + + wk1r = w[k2 + 2]; + move32(); + wk1i = w[k2 + 3]; + move32(); +#ifdef BASOP_NOGLOB + L_tmp = L_shl_o(Mult_32_32(wk2r,wk1i),1, &Overflow);/*Q29 */ + wk3r = L_sub_o(wk1r,L_shl_o(L_tmp,1, &Overflow), &Overflow); /*Q30 */ + + L_tmp = L_shl_o(Mult_32_32(wk2r,wk1r),1, &Overflow);/*Q29 */ + wk3i = L_sub_o(L_shl_o(L_tmp,1, &Overflow),wk1i, &Overflow); /*Q30 */ +#else + L_tmp = L_shl(Mult_32_32(wk2r,wk1i),1);/*Q29 */ + wk3r = L_sub(wk1r,L_shl(L_tmp,1)); /*Q30 */ + + L_tmp = L_shl(Mult_32_32(wk2r,wk1r),1);/*Q29 */ + wk3i = L_sub(L_shl(L_tmp,1),wk1i); /*Q30 */ +#endif + tmp2 = add(l,add(k,m)); + FOR (j = add(k,m); j < tmp2; j += 2) + { +#ifdef BASOP_NOGLOB + j1 = add_o(j, l, &Overflow); + j2 = add_o(j1, l, &Overflow); + j3 = add_o(j2, l, &Overflow); + x0r = add_o(a[j], a[j1], &Overflow); + x0i = add_o(a[j + 1], a[j1 + 1], &Overflow); + x1r = sub_o(a[j], a[j1], &Overflow); + x1i = sub_o(a[j + 1], a[j1 + 1], &Overflow); + x2r = add_o(a[j2], a[j3], &Overflow); + x2i = add_o(a[j2 + 1], a[j3 + 1], &Overflow); + x3r = sub_o(a[j2], a[j3], &Overflow); + x3i = sub_o(a[j2 + 1], a[j3 + 1], &Overflow); + a[j] = add_o(x0r, x2r, &Overflow); + move16(); + a[j + 1] = add_o(x0i, x2i, &Overflow); + move16(); + + x0r = sub_o(x0r, x2r, &Overflow); + x0i = sub_o(x0i, x2i, &Overflow); + + tmp = negate(x0r); + L_tmp = Mult_32_16(wk2i, tmp);/*Q(15+Qx+Q_edct) */ + L_tmp = Msub_32_16(L_tmp, wk2r, x0i); /*Q(15+Qx+Q_edct) */ + a[j2] = round_fx_o(L_shl_o(L_tmp, 1, &Overflow), &Overflow); /*Q(Qx+Q_edct) */ + + tmp = negate(x0i); + L_tmp = Mult_32_16(wk2i, tmp);/*Q(15+Qx+Q_edct) */ + L_tmp = Madd_32_16(L_tmp, wk2r, x0r); /*Q(15+Qx+Q_edct) */ + a[j2 + 1] = round_fx_o(L_shl_o(L_tmp, 1, &Overflow), &Overflow); /*Q(Qx+Q_edct) */ + + x0r = sub_o(x1r, x3i, &Overflow); + x0i = add_o(x1i, x3r, &Overflow); + + L_tmp = Mult_32_16(wk1r, x0r);/*Q(15+Qx+Q_edct) */ + L_tmp = Msub_32_16(L_tmp, wk1i, x0i); /*Q(15+Qx+Q_edct) */ + a[j1] = round_fx_o(L_shl_o(L_tmp, 1, &Overflow), &Overflow); /*Q(Qx+Q_edct) */ + + L_tmp = Mult_32_16(wk1r, x0i);/*Q(15+Qx+Q_edct) */ + L_tmp = Madd_32_16(L_tmp, wk1i, x0r); /*Q(15+Qx+Q_edct) */ + a[j1 + 1] = round_fx_o(L_shl_o(L_tmp, 1, &Overflow), &Overflow); /*Q(Qx+Q_edct) */ + + x0r = add_o(x1r, x3i, &Overflow); + x0i = sub_o(x1i, x3r, &Overflow); + + L_tmp = Mult_32_16(wk3r, x0r); /*Q(15+Qx+Q_edct) */ + L_tmp = Msub_32_16(L_tmp, wk3i, x0i); /*Q(15+Qx+Q_edct) */ + a[j3] = round_fx_o(L_shl_o(L_tmp, 1, &Overflow), &Overflow); /*Q(Qx+Q_edct) */ + + L_tmp = Mult_32_16(wk3r, x0i); /*Q(15+Qx+Q_edct) */ + L_tmp = Madd_32_16(L_tmp, wk3i, x0r); /*Q(15+Qx+Q_edct) */ + a[j3 + 1] = round_fx_o(L_shl_o(L_tmp, 1, &Overflow), &Overflow); /*Q(Qx+Q_edct) */ +#else + j1 = add(j,l); + j2 = add(j1,l); + j3 = add(j2,l); + x0r = add(a[j],a[j1]); + x0i = add(a[j + 1],a[j1 + 1]); + x1r = sub(a[j],a[j1]); + x1i = sub(a[j + 1],a[j1 + 1]); + x2r = add(a[j2],a[j3]); + x2i = add(a[j2 + 1],a[j3 + 1]); + x3r = sub(a[j2],a[j3]); + x3i = sub(a[j2 + 1],a[j3 + 1]); + a[j] = add(x0r,x2r); + move16(); + a[j + 1] = add(x0i,x2i); + move16(); + + x0r = sub(x0r,x2r); + x0i = sub(x0i,x2i); + + tmp = negate(x0r); + L_tmp = Mult_32_16(wk2i,tmp);/*Q(15+Qx+Q_edct) */ + L_tmp = Msub_32_16(L_tmp,wk2r,x0i); /*Q(15+Qx+Q_edct) */ + a[j2] = round_fx(L_shl(L_tmp,1)); /*Q(Qx+Q_edct) */ + + tmp = negate(x0i); + L_tmp = Mult_32_16(wk2i,tmp);/*Q(15+Qx+Q_edct) */ + L_tmp = Madd_32_16(L_tmp,wk2r,x0r); /*Q(15+Qx+Q_edct) */ + a[j2 + 1] = round_fx(L_shl(L_tmp,1)); /*Q(Qx+Q_edct) */ + + x0r = sub(x1r,x3i); + x0i = add(x1i,x3r); + + L_tmp = Mult_32_16(wk1r,x0r);/*Q(15+Qx+Q_edct) */ + L_tmp = Msub_32_16(L_tmp,wk1i,x0i); /*Q(15+Qx+Q_edct) */ + a[j1] = round_fx(L_shl(L_tmp,1)); /*Q(Qx+Q_edct) */ + + L_tmp = Mult_32_16(wk1r,x0i);/*Q(15+Qx+Q_edct) */ + L_tmp = Madd_32_16(L_tmp,wk1i,x0r); /*Q(15+Qx+Q_edct) */ + a[j1 + 1] = round_fx(L_shl(L_tmp,1)); /*Q(Qx+Q_edct) */ + + x0r = add(x1r,x3i); + x0i = sub(x1i,x3r); + + L_tmp = Mult_32_16(wk3r,x0r); /*Q(15+Qx+Q_edct) */ + L_tmp = Msub_32_16(L_tmp,wk3i,x0i); /*Q(15+Qx+Q_edct) */ + a[j3] = round_fx(L_shl(L_tmp,1)); /*Q(Qx+Q_edct) */ + + L_tmp = Mult_32_16(wk3r,x0i); /*Q(15+Qx+Q_edct) */ + L_tmp = Madd_32_16(L_tmp,wk3i,x0r); /*Q(15+Qx+Q_edct) */ + a[j3 + 1] = round_fx(L_shl(L_tmp,1)); /*Q(Qx+Q_edct) */ +#endif + } + } + + return; +} + +void fft3_fx(const Word16 X[], Word16 Y[], const Word16 n) +{ + Word16 Z[PH_ECU_SPEC_SIZE]; + Word16 *Z0, *Z1, *Z2; + Word16 *z0, *z1, *z2; + const Word16 *x; + const Word16 *t_sin = sincos_t_rad3_fx; + Word16 m, mMinus1, step; + Word16 i, l; + Word16 c1_ind, s1_ind, c2_ind, s2_ind; + Word16 c1_step, s1_step, c2_step, s2_step; + Word16 *RY, *IY, *RZ0, *IZ0, *RZ1, *IZ1, *RZ2, *IZ2; + Word32 acc; + Word16 mBy2, orderMinus1; + const Word16 *pPhaseTbl; + + /* Determine the order of the transform, the length of decimated */ + /* transforms m, and the step for the sine and cosine tables. */ + SWITCH(n) + { + case 1536: + orderMinus1 = 9-1; + move16(); + m = 512; + move16(); + step = 1; + move16(); + pPhaseTbl = FFT_W256; + BREAK; + case 384: + orderMinus1 = 7-1; + move16(); + m = 128; + move16(); + step = 4; + move16(); + pPhaseTbl = FFT_W64; + BREAK; + default: + orderMinus1 = 7-1; + move16(); + m = 128; + move16(); + step = 4; + move16(); + pPhaseTbl = FFT_W64; + BREAK; + } + + /* Compose decimated sequences X[3i], X[3i+1],X[3i+2] */ + /* compute their FFT of length m. */ + Z0 = &Z[0]; + z0 = &Z0[0]; + Z1 = &Z0[m]; + z1 = &Z1[0]; /* Z1 = &Z[ m]; */ + Z2 = &Z1[m]; + z2 = &Z2[0]; /* Z2 = &Z[2m]; */ + x = &X[0]; + FOR (i = 0; i < m; i++) + { + *z0++ = *x++; /* Z0[i] = X[3i]; */ move16(); + *z1++ = *x++; /* Z1[i] = X[3i+1]; */ move16(); + *z2++ = *x++; /* Z2[i] = X[3i+2]; */ move16(); + } + mBy2 = shr(m,1); + r_fft_fx_lc(pPhaseTbl, m, mBy2, orderMinus1, Z0, Z0, 1); + r_fft_fx_lc(pPhaseTbl, m, mBy2, orderMinus1, Z1, Z1, 1); + r_fft_fx_lc(pPhaseTbl, m, mBy2, orderMinus1, Z2, Z2, 1); + + /* Butterflies of order 3. */ + /* pointer initialization */ + mMinus1 = sub(m,1); + RY = &Y[0]; + IY = &Y[n]; + IY--; /* Decrement the address counter.*/ + RZ0 = &Z0[0]; + IZ0 = &Z0[mMinus1]; + RZ1 = &Z1[0]; + IZ1 = &Z1[mMinus1]; + RZ2 = &Z2[0]; + IZ2 = &Z2[mMinus1]; + + c1_step = negate(step); + s1_step = step; + move16(); + c2_step = shl(c1_step,1); + s2_step = shl(s1_step,1); + c1_ind = add(T_SIN_PI_2, c1_step); + s1_ind = s1_step; + move16(); + c2_ind = add(T_SIN_PI_2, c2_step); + s2_ind = s2_step; + move16(); + + /* special case: i = 0 */ + acc = L_mult(*RZ0++, 0x4000); + acc = L_mac(acc, *RZ1++, 0x4000); + *RY++ = mac_r(acc, *RZ2++, 0x4000); + move16(); + + /* first 3/12-- from 1 to (3*m/8)-1 */ + l = sub(shr(n, 3),1); /* (3*m/8) - 1 = (n/8) - 1 */ + FOR (i = 0; i < l; i++) + { + acc = L_shl(*RZ0++, 15); /* Align with the following non-fractional mode so as to gain 1 more bit headroom. */ + acc = L_mac0(acc, *RZ1, t_sin[c1_ind]); /* Non-fractional mode gains 1 more bit headroom. */ + acc = L_mac0(acc, *IZ1, t_sin[s1_ind]); + acc = L_mac0(acc, *RZ2, t_sin[c2_ind]); + acc = L_mac0(acc, *IZ2, t_sin[s2_ind]); + *RY++ = round_fx(acc); /* bit growth = 1 (compensated by non-fractional mode MAC). */ + + acc = L_shl(*IZ0--, 15); + acc = L_msu0(acc, *RZ1++, t_sin[s1_ind]); + acc = L_mac0(acc, *IZ1--, t_sin[c1_ind]); + acc = L_msu0(acc, *RZ2++, t_sin[s2_ind]); + acc = L_mac0(acc, *IZ2--, t_sin[c2_ind]); + *IY-- = round_fx(acc); + + c1_ind = add(c1_ind, c1_step); + s1_ind = add(s1_ind, s1_step); + c2_ind = add(c2_ind, c2_step); + s2_ind = add(s2_ind, s2_step); + } + + /* next 1/12-- from (3*m/8) to (4*m/8)-1 */ + l = shr(m,3); /* (4*m/8) - (3*m/8) = m/8 */ + FOR (i = 0; i < l; i++) + { + acc = L_shl(*RZ0++, 15); + acc = L_mac0(acc, *RZ1, t_sin[c1_ind]); /* Non-fractional mode gains 1 more bit headroom. */ + acc = L_mac0(acc, *IZ1, t_sin[s1_ind]); + acc = L_msu0(acc, *RZ2, t_sin[c2_ind]); + acc = L_mac0(acc, *IZ2, t_sin[s2_ind]); + *RY++ = round_fx(acc); + + acc = L_shl(*IZ0--, 15); + acc = L_msu0(acc, *RZ1++, t_sin[s1_ind]); + acc = L_mac0(acc, *IZ1--, t_sin[c1_ind]); + acc = L_msu0(acc, *RZ2++, t_sin[s2_ind]); + acc = L_msu0(acc, *IZ2--, t_sin[c2_ind]); + *IY-- = round_fx(acc); + + c1_ind = add(c1_ind, c1_step); + s1_ind = add(s1_ind, s1_step); + c2_ind = sub(c2_ind, c2_step); + s2_ind = sub(s2_ind, s2_step); + } + + /* special case: i = m/2 i.e. 1/3 */ + acc = L_shl(*RZ0--, 15); + acc = L_mac0(acc, *RZ1, t_sin[c1_ind]); + acc = L_msu0(acc, *RZ2, t_sin[c2_ind]); + *RY++ = round_fx(acc); + + acc = 0; + acc = L_msu0(acc, *RZ1--, t_sin[s1_ind]); + acc = L_msu0(acc, *RZ2--, t_sin[s2_ind]); + *IY-- = round_fx(acc); + IZ0++; + IZ1++; + IZ2++; + + c1_ind = add(c1_ind, c1_step); + s1_ind = add(s1_ind, s1_step); + c2_ind = sub(c2_ind, c2_step); + s2_ind = sub(s2_ind, s2_step); + + /* next 2/12-- from ((m/2)+1) to (6*m/8)-1 */ + l = sub(shr(m,2), 1); /* (6*m/8) - ((m/2)+1) = m/4 - 1 */ + FOR (i = 0; i < l; i++) + { + acc = L_shl(*RZ0--, 15); + acc = L_mac0(acc, *RZ1, t_sin[c1_ind]); /* Non-fractional mode gains 1 more bit headroom. */ + acc = L_msu0(acc, *IZ1, t_sin[s1_ind]); + acc = L_msu0(acc, *RZ2, t_sin[c2_ind]); + acc = L_msu0(acc, *IZ2, t_sin[s2_ind]); + *RY++ = round_fx(acc); + + acc = L_mult0(*IZ0++, -32768); + acc = L_msu0(acc, *RZ1--, t_sin[s1_ind]); + acc = L_msu0(acc, *IZ1++, t_sin[c1_ind]); + acc = L_msu0(acc, *RZ2--, t_sin[s2_ind]); + acc = L_mac0(acc, *IZ2++, t_sin[c2_ind]); + *IY-- = round_fx(acc); + + c1_ind = add(c1_ind, c1_step); + s1_ind = add(s1_ind, s1_step); + c2_ind = sub(c2_ind, c2_step); + s2_ind = sub(s2_ind, s2_step); + } + + /*--------------------------half--------------------------// */ + /* next 2/12-- from (6*m/8) to (8*m/8) - 1 */ + l = shr(m,2); + FOR (i = 0; i < l; i++) + { + acc = L_shl(*RZ0--, 15); + acc = L_msu0(acc, *RZ1, t_sin[c1_ind]); /* Non-fractional mode gains 1 more bit headroom. */ + acc = L_msu0(acc, *IZ1, t_sin[s1_ind]); + acc = L_msu0(acc, *RZ2, t_sin[c2_ind]); + acc = L_mac0(acc, *IZ2, t_sin[s2_ind]); + *RY++ = round_fx(acc); + + acc = L_mult0(*IZ0++, -32768); + acc = L_msu0(acc, *RZ1--, t_sin[s1_ind]); + acc = L_mac0(acc, *IZ1++, t_sin[c1_ind]); + acc = L_mac0(acc, *RZ2--, t_sin[s2_ind]); + acc = L_mac0(acc, *IZ2++, t_sin[c2_ind]); + *IY-- = round_fx(acc); + + c1_ind = sub(c1_ind, c1_step); + s1_ind = sub(s1_ind, s1_step); + c2_ind = add(c2_ind, c2_step); + s2_ind = add(s2_ind, s2_step); + } + + /* special case: i = m, i.e 2/3 */ + acc = L_shl(*RZ0++, 15); + acc = L_msu0(acc, *RZ1, t_sin[c1_ind]); + acc = L_msu0(acc, *RZ2, t_sin[c2_ind]); + *RY++ = round_fx(acc); + + acc = L_deposit_l(0); + acc = L_msu0(acc, *RZ1++, t_sin[s1_ind]); + acc = L_mac0(acc, *RZ2++, t_sin[s2_ind]); + *IY-- = round_fx(acc); + IZ0--; /* Just decrement the address counter */ + IZ1--; + IZ2--; + + c1_ind = sub(c1_ind, c1_step); + s1_ind = sub(s1_ind, s1_step); + c2_ind = add(c2_ind, c2_step); + s2_ind = add(s2_ind, s2_step); + + /* next 1/12-- from (m + 1) to (9*m/8) - 1 */ + l = sub(shr(m, 3), 1); /* (9*m/8) - (m +1) = m/8 - 1 */ + FOR (i = 0; i < l; i++) + { + acc = L_shl(*RZ0++, 15); + acc = L_msu0(acc, *RZ1, t_sin[c1_ind]); /* Non-fractional mode gains 1 more bit headroom. */ + acc = L_mac0(acc, *IZ1, t_sin[s1_ind]); + acc = L_msu0(acc, *RZ2, t_sin[c2_ind]); + acc = L_msu0(acc, *IZ2, t_sin[s2_ind]); + *RY++ = round_fx(acc); + + acc = L_shl(*IZ0--, 15); + acc = L_msu0(acc, *RZ1++, t_sin[s1_ind]); + acc = L_msu0(acc, *IZ1--, t_sin[c1_ind]); + acc = L_mac0(acc, *RZ2++, t_sin[s2_ind]); + acc = L_msu0(acc, *IZ2--, t_sin[c2_ind]); + *IY-- = round_fx(acc); + + c1_ind = sub(c1_ind, c1_step); + s1_ind = sub(s1_ind, s1_step); + c2_ind = add(c2_ind, c2_step); + s2_ind = add(s2_ind, s2_step); + } + + /* last 3/12-- from (9*m/8) to (12*m/8) - 1 */ + l = shr(n,3); /* (12*m/8) - (9*m/8) = 3*m/8 = n/8 */ + FOR (i = 0; i < l; i++) + { + acc = L_shl(*RZ0++, 15); + acc = L_msu0(acc, *RZ1, t_sin[c1_ind]); /* Non-fractional mode gains 1 more bit headroom. */ + acc = L_mac0(acc, *IZ1, t_sin[s1_ind]); + acc = L_mac0(acc, *RZ2, t_sin[c2_ind]); + acc = L_msu0(acc, *IZ2, t_sin[s2_ind]); + *RY++ = round_fx(acc); + + acc = L_shl(*IZ0--, 15); + acc = L_msu0(acc, *RZ1++, t_sin[s1_ind]); + acc = L_msu0(acc, *IZ1--, t_sin[c1_ind]); + acc = L_mac0(acc, *RZ2++, t_sin[s2_ind]); + acc = L_mac0(acc, *IZ2--, t_sin[c2_ind]); + *IY-- = round_fx(acc); + + c1_ind = sub(c1_ind, c1_step); + s1_ind = sub(s1_ind, s1_step); + c2_ind = sub(c2_ind, c2_step); + s2_ind = sub(s2_ind, s2_step); + } + + /* special case: i = 3*m/2 */ + acc = L_shl(*RZ0, 15); + acc = L_msu0(acc, *RZ1, t_sin[c1_ind]); + acc = L_mac0(acc, *RZ2, t_sin[c2_ind]); + *RY = round_fx(acc); + + return; +} + + +void ifft3_fx(const Word16 Z[], Word16 X[], const Word16 n) +{ + Word16 Y[PH_ECU_SPEC_SIZE]; + const Word16 *t_sin = sincos_t_rad3_fx; + Word16 m, mMinus1, step, step2; + Word16 i, l; + Word16 c0_ind, s0_ind, c1_ind, s1_ind, c2_ind, s2_ind; + const Word16 *RZ0, *IZ0, *RZ1, *IZ1, *RZ2, *IZ2; + const Word16 *RZ00, *IZ00, *RZ10, *IZ10, *RZ20, *IZ20; + Word16 *RY0, *IY0, *RY1, *IY1, *RY2, *IY2, *y0, *y1, *y2, *pX; + Word32 acc; + Word16 mBy2, orderMinus1, nMinusMBy2; + const Word16 *pPhaseTbl; + + /* Determine the order of the transform, the length of decimated */ + /* transforms m, and the step for the sine and cosine tables. */ + SWITCH(n) + { + case 1536: + orderMinus1 = 9-1; + move16(); + m = 512; + move16(); + step = 1; + move16(); + pPhaseTbl = FFT_W256; + BREAK; + case 384: + orderMinus1 = 7-1; + move16(); + m = 128; + move16(); + step = 4; + move16(); + pPhaseTbl = FFT_W64; + BREAK; + default: + orderMinus1 = 7-1; + move16(); + m = 128; + move16(); + step = 4; + move16(); + pPhaseTbl = FFT_W64; + BREAK; + } + + nMinusMBy2 = shr(sub(n, m),1); + mMinus1 = sub(m,1); + /* pointer initialization */ + RY0 = &Y[0]; + IY0 = &Y[m]; + RY1 = &RY0[m]; + IY1 = &RY1[mMinus1]; + RY2 = &RY1[m]; + IY2 = &RY2[mMinus1]; + + RZ00 = &Z[0]; /* The zero positions of the pointers */ + RZ10 = &RZ00[m]; + RZ20 = &RZ00[nMinusMBy2]; + IZ00 = &Z[n]; + IZ10 = &IZ00[-m]; + IZ20 = &IZ00[-nMinusMBy2]; + + RZ0 = RZ00; /* Reset the pointers to zero positions. */ + RZ1 = RZ10; + RZ2 = RZ20; + IZ0 = IZ00; + IZ1 = IZ10; + IZ2 = IZ20; + + /* Inverse butterflies of order 3. */ + + /* Construction of Y0 */ + acc = L_mult(*RZ0++, 0x4000); + acc = L_mac(acc, *RZ1++, 0x4000); + *RY0++ = mac_r(acc, *RZ2--, 0x4000); + move16(); + IZ0--; + IZ1--; + IZ2++; + IY0--; + + l = sub(shr(m, 1), 1); + FOR (i = 0; i < l; i++) + { + acc = L_mult(*RZ0++, 0x4000); + acc = L_mac(acc, *RZ1++, 0x4000); + *RY0++ = mac_r(acc, *RZ2--, 0x4000); + move16(); + + acc = L_mult(*IZ0--, 0x4000); + acc = L_mac(acc, *IZ1--, 0x4000); + *IY0-- = msu_r(acc, *IZ2++, 0x4000); + move16(); + } + + /* m/2 */ + acc = L_mult(*RZ0, 0x4000); + acc = L_mac(acc, *RZ1, 0x4000); + *RY0++ = mac_r(acc, *RZ2, 0x4000); + move16(); + + + /* Construction of Y1 */ + c0_ind=T_SIN_PI_2; + s0_ind=0; + c1_ind=T_SIN_PI_2*1/3; + s1_ind=T_SIN_PI_2*2/3; + c2_ind=T_SIN_PI_2*1/3; + s2_ind=T_SIN_PI_2*2/3; + + RZ0 = RZ00; /* Reset pointers to zero positions. */ + RZ1 = RZ10; + RZ2 = RZ20; + IZ0 = IZ00; + IZ1 = IZ10; + IZ2 = IZ20; + acc = L_mult0(*RZ0++, t_sin[c0_ind]); + acc = L_msu0(acc, *RZ1++, t_sin[c1_ind]); + acc = L_msu0(acc, *RZ2--, t_sin[c2_ind]); + IZ0--; + acc = L_msu0(acc, *IZ1--, t_sin[s1_ind]); + acc = L_msu0(acc, *IZ2++, t_sin[s2_ind]); + *RY1++ = round_fx(acc); + + c0_ind=sub(c0_ind,step); + s0_ind=add(s0_ind,step); + c1_ind=add(c1_ind,step); + s1_ind=sub(s1_ind,step); + c2_ind=sub(c2_ind,step); + s2_ind=add(s2_ind,step); + + /* From 1 to (m/4) - 1. */ + l = sub(shr(m,2),1); + FOR (i = 0; i < l; i++) + { + acc = L_mult0(*RZ0, t_sin[c0_ind]); + acc = L_msu0(acc, *RZ1, t_sin[c1_ind]); + acc = L_msu0(acc, *RZ2, t_sin[c2_ind]); + acc = L_msu0(acc, *IZ0, t_sin[s0_ind]); + acc = L_msu0(acc, *IZ1, t_sin[s1_ind]); + acc = L_msu0(acc, *IZ2, t_sin[s2_ind]); + *RY1++ = round_fx(acc); + + acc = L_mult0(*IZ0--, t_sin[c0_ind]); + acc = L_msu0(acc, *IZ1--, t_sin[c1_ind]); + acc = L_mac0(acc, *IZ2++, t_sin[c2_ind]); + acc = L_mac0(acc, *RZ0++, t_sin[s0_ind]); + acc = L_mac0(acc, *RZ1++, t_sin[s1_ind]); + acc = L_msu0(acc, *RZ2--, t_sin[s2_ind]); + *IY1-- = round_fx(acc); + + c0_ind=sub(c0_ind,step); + s0_ind=add(s0_ind,step); + c1_ind=add(c1_ind,step); + s1_ind=sub(s1_ind,step); + c2_ind=sub(c2_ind,step); + s2_ind=add(s2_ind,step); + } + + /* From m/4 to m/2 -1. */ + l = shr(m, 2); /* m/2 - m/4 = m/4 */ + FOR (i = 0; i < l; i++) + { + acc = L_mult0(*RZ0, t_sin[c0_ind]); + acc = L_msu0(acc, *RZ1, t_sin[c1_ind]); + acc = L_mac0(acc, *RZ2, t_sin[c2_ind]); + acc = L_msu0(acc, *IZ0, t_sin[s0_ind]); + acc = L_msu0(acc, *IZ1, t_sin[s1_ind]); + acc = L_msu0(acc, *IZ2, t_sin[s2_ind]); + *RY1++ = round_fx(acc); + + acc = L_mult0(*IZ0--, t_sin[c0_ind]); + acc = L_msu0(acc, *IZ1--, t_sin[c1_ind]); + acc = L_msu0(acc, *IZ2++, t_sin[c2_ind]); + acc = L_mac0(acc, *RZ0++, t_sin[s0_ind]); + acc = L_mac0(acc, *RZ1++, t_sin[s1_ind]); + acc = L_msu0(acc, *RZ2--, t_sin[s2_ind]); + *IY1-- = round_fx(acc); + + c0_ind=sub(c0_ind,step); + s0_ind=add(s0_ind,step); + c1_ind=add(c1_ind,step); + s1_ind=sub(s1_ind,step); + c2_ind=add(c2_ind,step); + s2_ind=sub(s2_ind,step); + } + + /* m/2 */ + acc = L_mult0(*RZ0, t_sin[c0_ind]); + acc = L_msu0(acc, *RZ1, t_sin[c1_ind]); + acc = L_mac0(acc, *RZ2, t_sin[c2_ind]); + acc = L_msu0(acc, *IZ0, t_sin[s0_ind]); + acc = L_msu0(acc, *IZ1, t_sin[s1_ind]); + acc = L_msu0(acc, *IZ2, t_sin[s2_ind]); + *RY1++ = round_fx(acc); + + /* Construction of Y2 */ + c0_ind=T_SIN_PI_2; + s0_ind=0; + c1_ind=T_SIN_PI_2*1/3; + s1_ind=T_SIN_PI_2*2/3; + c2_ind=T_SIN_PI_2*1/3; + s2_ind=T_SIN_PI_2*2/3; + step2 = shl(step,1); + + RZ0 = RZ00; /* Reset pointers to zero positions. */ + RZ1 = RZ10; + RZ2 = RZ20; + IZ0 = IZ00; + IZ1 = IZ10; + IZ2 = IZ20; + acc = L_mult0(*RZ0++, t_sin[c0_ind]); + acc = L_msu0(acc, *RZ1++, t_sin[c1_ind]); + acc = L_msu0(acc, *RZ2--, t_sin[c2_ind]); + IZ0--; + acc = L_mac0(acc, *IZ1--, t_sin[s1_ind]); + acc = L_mac0(acc, *IZ2++, t_sin[s2_ind]); + *RY2++ = round_fx(acc); + + c0_ind=sub(c0_ind,step2); + s0_ind=add(s0_ind,step2); + c1_ind=sub(c1_ind,step2); + s1_ind=add(s1_ind,step2); + c2_ind=add(c2_ind,step2); + s2_ind=sub(s2_ind,step2); + + /* From 1 to (m/8) - 1. */ + l = sub(shr(m, 3),1); /* m/8 - 1. */ + FOR (i = 0; i < l; i++) + { + acc = L_mult0(*RZ0, t_sin[c0_ind]); + acc = L_msu0(acc, *RZ1, t_sin[c1_ind]); + acc = L_msu0(acc, *RZ2, t_sin[c2_ind]); + acc = L_msu0(acc, *IZ0, t_sin[s0_ind]); + acc = L_mac0(acc, *IZ1, t_sin[s1_ind]); + acc = L_mac0(acc, *IZ2, t_sin[s2_ind]); + *RY2++ = round_fx(acc); + + acc = L_mult0(*IZ0--, t_sin[c0_ind]); + acc = L_msu0(acc, *IZ1--, t_sin[c1_ind]); + acc = L_mac0(acc, *IZ2++, t_sin[c2_ind]); + acc = L_mac0(acc, *RZ0++, t_sin[s0_ind]); + acc = L_msu0(acc, *RZ1++, t_sin[s1_ind]); + acc = L_mac0(acc, *RZ2--, t_sin[s2_ind]); + *IY2-- = round_fx(acc); + + c0_ind=sub(c0_ind,step2); + s0_ind=add(s0_ind,step2); + c1_ind=sub(c1_ind,step2); + s1_ind=add(s1_ind,step2); + c2_ind=add(c2_ind,step2); + s2_ind=sub(s2_ind,step2); + } + + /* From (m/8) to (m/4) - 1. */ + l = shr(m, 3); /* m/4 - m/8 = m/8 */ + FOR (i = 0; i < l; i++) + { + acc = L_mult0(*RZ0, t_sin[c0_ind]); + acc = L_mac0(acc, *RZ1, t_sin[c1_ind]); + acc = L_msu0(acc, *RZ2, t_sin[c2_ind]); + acc = L_msu0(acc, *IZ0, t_sin[s0_ind]); + acc = L_mac0(acc, *IZ1, t_sin[s1_ind]); + acc = L_mac0(acc, *IZ2, t_sin[s2_ind]); + *RY2++ = round_fx(acc); + + acc = L_mult0(*IZ0--, t_sin[c0_ind]); + acc = L_mac0(acc, *IZ1--, t_sin[c1_ind]); + acc = L_mac0(acc, *IZ2++, t_sin[c2_ind]); + acc = L_mac0(acc, *RZ0++, t_sin[s0_ind]); + acc = L_msu0(acc, *RZ1++, t_sin[s1_ind]); + acc = L_mac0(acc, *RZ2--, t_sin[s2_ind]); + *IY2-- = round_fx(acc); + + c0_ind=sub(c0_ind,step2); + s0_ind=add(s0_ind,step2); + c1_ind=add(c1_ind,step2); + s1_ind=sub(s1_ind,step2); + c2_ind=add(c2_ind,step2); + s2_ind=sub(s2_ind,step2); + } + + /* From m/4 to 3*m/8 - 1. */ + l = shr(m, 3); /* 3*m/8 - m/4 = m/8 */ + FOR (i = 0; i < l; i++) + { + acc = L_mult0(*RZ0, t_sin[c0_ind]); + acc = L_mac0(acc, *RZ1, t_sin[c1_ind]); + acc = L_msu0(acc, *RZ2, t_sin[c2_ind]); + acc = L_msu0(acc, *IZ0, t_sin[s0_ind]); + acc = L_mac0(acc, *IZ1, t_sin[s1_ind]); + acc = L_msu0(acc, *IZ2, t_sin[s2_ind]); + *RY2++ = round_fx(acc); + + acc = L_mult0(*IZ0--, t_sin[c0_ind]); + acc = L_mac0(acc, *IZ1--, t_sin[c1_ind]); + acc = L_mac0(acc, *IZ2++, t_sin[c2_ind]); + acc = L_mac0(acc, *RZ0++, t_sin[s0_ind]); + acc = L_msu0(acc, *RZ1++, t_sin[s1_ind]); + acc = L_msu0(acc, *RZ2--, t_sin[s2_ind]); + *IY2-- = round_fx(acc); + + c0_ind=sub(c0_ind,step2); + s0_ind=add(s0_ind,step2); + c1_ind=add(c1_ind,step2); + s1_ind=sub(s1_ind,step2); + c2_ind=sub(c2_ind,step2); + s2_ind=add(s2_ind,step2); + } + + /* From 3*m/8 to m/2 - 1*/ + l = shr(m, 3); /* m/2 - 3*m/8 = m/8 */ + FOR (i = 0; i < l; i++) + { + acc = L_mult0(*RZ1, t_sin[c1_ind]); + acc = L_msu0(acc, *RZ0, t_sin[c0_ind]); + acc = L_msu0(acc, *RZ2, t_sin[c2_ind]); + acc = L_msu0(acc, *IZ0, t_sin[s0_ind]); + acc = L_mac0(acc, *IZ1, t_sin[s1_ind]); + acc = L_msu0(acc, *IZ2, t_sin[s2_ind]); + *RY2++ = round_fx(acc); + + acc = L_mult0(*IZ1--, t_sin[c1_ind]); + acc = L_msu0(acc, *IZ0--, t_sin[c0_ind]); + acc = L_mac0(acc, *IZ2++, t_sin[c2_ind]); + acc = L_mac0(acc, *RZ0++, t_sin[s0_ind]); + acc = L_msu0(acc, *RZ1++, t_sin[s1_ind]); + acc = L_msu0(acc, *RZ2--, t_sin[s2_ind]); + *IY2-- = round_fx(acc); + + c0_ind=add(c0_ind,step2); + s0_ind=sub(s0_ind,step2); + c1_ind=add(c1_ind,step2); + s1_ind=sub(s1_ind,step2); + c2_ind=sub(c2_ind,step2); + s2_ind=add(s2_ind,step2); + } + + /* m/2 */ + acc = L_mult0(*RZ1, t_sin[c1_ind]); + acc = L_msu0(acc, *RZ0, t_sin[c0_ind]); + acc = L_msu0(acc, *RZ2, t_sin[c2_ind]); + acc = L_msu0(acc, *IZ0, t_sin[s0_ind]); + acc = L_mac0(acc, *IZ1, t_sin[s1_ind]); + acc = L_msu0(acc, *IZ2, t_sin[s2_ind]); + *RY2++ = round_fx(acc); + + /* Compute the inverse FFT for all 3 blocks. */ + RY0 = &Y[0]; /* Rewind the pointers. */ + RY1 = &Y[m]; + RY2 = &RY1[m]; + mBy2 = shr(m,1); + r_fft_fx_lc(pPhaseTbl, m, mBy2, orderMinus1, RY0, RY0, 0); /* inverse FFT */ + r_fft_fx_lc(pPhaseTbl, m, mBy2, orderMinus1, RY1, RY1, 0); /* inverse FFT */ + r_fft_fx_lc(pPhaseTbl, m, mBy2, orderMinus1, RY2, RY2, 0); /* inverse FFT */ + + y0 = RY0; + y1 = RY1; + y2 = RY2; + + /* Interlacing and scaling, scale = 1/3 */ + pX = X; + FOR (i = 0; i < m; i++) + { + *pX++ = shl(mult_r(*y0++, FFT3_ONE_THIRD), 1); + move16(); + *pX++ = shl(mult_r(*y1++, FFT3_ONE_THIRD), 1); + move16(); + *pX++ = shl(mult_r(*y2++, FFT3_ONE_THIRD), 1); + move16(); + } + + return; +} diff --git a/lib_com/fft_rel_fx.c b/lib_com/fft_rel_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..49ae18103101735700607077270b7691047e145f --- /dev/null +++ b/lib_com/fft_rel_fx.c @@ -0,0 +1,449 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include "options.h" /* Compilation switches */ +#include "prot_fx1.h" /* Function prototypes */ +#include "prot_fx2.h" /* Function prototypes */ +#include "rom_com.h" /* Static table prototypes */ +#include "stl.h" + +#include "stdint.h" +/*------------------------------------------------------------------ + * + * This is an implementation of decimation-in-time FFT algorithm for + * real sequences. The techniques used here can be found in several + * books, e.g., i) Proakis and Manolakis, "Digital Signal Processing", + * 2nd Edition, Chapter 9, and ii) W.H. Press et. al., "Numerical + * Recipes in C", 2nd Edition, Chapter 12. + * + * Input - There are two inputs to this function: + * + * 1) An integer pointer to the input data array + * 2) An integer value which should be set as +1 for FFT + * and some other value, e.g., -1 for ifFT + * + * Output - There is no return value. + * The input data are replaced with transformed data. if the + * input is a real time domain sequence, it is replaced with + * the complex FFT for positive frequencies. The FFT value + * for DC and the foldover frequency are combined to form the + * first complex number in the array. The remaining complex + * numbers correspond to increasing frequencies. if the input + * is a complex frequency domain sequence arranged as above, + * it is replaced with the corresponding time domain sequence. + * + * Notes: + * + * 1) This function is designed to be a part of a noise supp- + * ression algorithm that requires 128-point FFT of real + * sequences. This is achieved here through a 64-point + * complex FFT. Consequently, the FFT size information is + * not transmitted explicitly. However, some flexibility + * is provided in the function to change the size of the + * FFT by specifying the size information through "define" + * statements. + * + * 2) The values of the complex sinusoids used in the FFT + * algorithm are computed once (i.e., the first time the + * r_fft function is called) and stored in a table. To + * further speed up the algorithm, these values can be + * precomputed and stored in a ROM table in actual DSP + * based implementations. + * + * 3) In the c_fft function, the FFT values are divided by + * 2 after each stage of computation thus dividing the + * final FFT values by 64. No multiplying factor is used + * for the ifFT. This is somewhat different from the usual + * definition of FFT where the factor 1/N, i.e., 1/64, is + * used for the ifFT and not the FFT. No factor is used in + * the r_fft function. + * + * 4) Much of the code for the FFT and ifFT parts in r_fft + * and c_fft functions are similar and can be combined. + * They are, however, kept separate here to speed up the + * execution. + *------------------------------------------------------------------------*/ +/*------------------------------------------------------------------------* + * c_fft_fx: + * + * Computes the complex part of the split-radix FFT + *------------------------------------------------------------------------*/ + +static void c_fft_fx( + const Word16 *phs_tbl, /* i : Table of phases */ + Word16 SIZE, /* i : Size of the FFT */ + Word16 NUM_STAGE, /* i : Number of stages */ + const Word16 *in_ptr, /* i : coefficients in the order re[0], re[n/2], re[1], im[1], ..., re[n/2-1], im[n/2-1] */ + Word16 *out_ptr, /* o : coefficients in the order re[0], re[n/2], re[1], im[1], ..., re[n/2-1], im[n/2-1] */ + /* in_ptr & out_ptr must not overlap! */ + const Word16 isign) /* i : 1=fft, otherwise it is ifft*/ +{ + Word16 i, j, k, ii, jj, kk, ji, kj; + Word32 L_tmp1, L_tmp2; + Word16 tmp1,tmp2,tmp3,tmp4; + const Word16 *table_ptr; + const Word16 *input_ptr1,*input_ptr2,*input_ptr3,*input_ptr4; + Word16 shift=0; + /* Setup Reorder Variables */ + table_ptr = NULL; + table_ptr = FFT_REORDER_1024; + SWITCH(SIZE) + { + case 1024: + shift = 0; + BREAK; + case 512: + shift = 1; + BREAK; + case 256: + shift = 2; + BREAK; + case 128: + shift = 3; + BREAK; + case 64: + shift = 4; + BREAK; + } + /* The FFT part */ + IF (isign != 0) + { + /* Unrolled 1st/2nd Stage + * 1) to take advantage of Table Values (0 & +/- 16384) + * 2) to perform reordering of Input Values + */ + FOR (k = 0; k < SIZE; k += 8) + { + /* + * This loop use: + * 4 Word16 (tmp1...tmp4) + * 2 Word32 (L_tmp1 & L_tmp2) + * 4 Pointers (table_ptr, input_ptr1, input_ptr2, input_ptr3) + * + * The addition of 'in_ptr' + and index value from 'reorder_ptr' + * is counted as a move16() + */ + + input_ptr1 = in_ptr + (const Word16 ) ((uintptr_t)(*table_ptr++)>>(uintptr_t)shift); + + L_tmp1 = L_mult(*input_ptr1++, 16384); + L_tmp2 = L_mult(*input_ptr1, 16384); + + input_ptr1 = in_ptr + (const Word16)((uintptr_t)(*table_ptr++) >> (uintptr_t)shift); + + tmp1 = msu_r(L_tmp1, *input_ptr1, 16384); + tmp3 = mac_r(L_tmp1, *input_ptr1++, 16384); + + input_ptr2 = in_ptr + (const Word16)((uintptr_t)(*table_ptr++) >> (uintptr_t)shift); + input_ptr3 = in_ptr + (const Word16)((uintptr_t)(*table_ptr++) >> (uintptr_t)shift); + + L_tmp1 = L_mult(*input_ptr2++, 16384); + tmp2 = mac_r(L_tmp1, *input_ptr3, 16384); + tmp4 = msu_r(L_tmp1, *input_ptr3++, 16384); + + L_tmp1 = L_mult(tmp3, 16384); + out_ptr[k] = mac_r(L_tmp1, tmp2, 16384); + move16(); + out_ptr[k+4] = msu_r(L_tmp1, tmp2, 16384); + move16(); + + tmp2 = mac_r(L_tmp2, *input_ptr1, 16384); + tmp3 = msu_r(L_tmp2, *input_ptr1, 16384); + + L_tmp2 = L_mult(*input_ptr2, 16384); + + L_tmp1 = L_mult(tmp1, 16384); + tmp1 = msu_r(L_tmp2, *input_ptr3, 16384); + out_ptr[k+2] = mac_r(L_tmp1, tmp1, 16384); + move16(); + out_ptr[k+6] = msu_r(L_tmp1, tmp1, 16384); + move16(); + + L_tmp1 = L_mult(tmp2, 16384); + tmp2 = mac_r(L_tmp2, *input_ptr3, 16384); + out_ptr[k+1] = mac_r(L_tmp1, tmp2, 16384); + move16(); + out_ptr[k+5] = msu_r(L_tmp1, tmp2, 16384); + move16(); + + L_tmp1 = L_mult(tmp3, 16384); + out_ptr[k+3] = msu_r(L_tmp1, tmp4, 16384); + move16(); + out_ptr[k+7] = mac_r(L_tmp1, tmp4, 16384); + move16(); + } + + /* Remaining Stages */ + FOR (i = 2; i < NUM_STAGE; i++) + { + /* i is stage counter */ + jj = shl(2, i); /* FFT size */ + kk = shl(jj, 1); /* 2 * FFT size */ + ii = shr(SIZE, i); + ji = 0; + move16(); /* ji is phase table index */ + + FOR (j = 0; j < jj; j += 2) + { + /* j is sample counter */ + FOR (k = j; k < SIZE; k += kk) + { + /* k is butterfly top */ + kj = add(k, jj); /* kj is butterfly bottom */ + + /* Butterfly computations */ + L_tmp1 = L_msu(L_mult(*(out_ptr + kj), phs_tbl[ji]), + *(out_ptr + kj + 1), phs_tbl[ji + 1]); + L_tmp2 = L_mac(L_mult(*(out_ptr + kj + 1), phs_tbl[ji]), + *(out_ptr + kj), phs_tbl[ji + 1]); + + out_ptr[kj] = mac_r(L_negate(L_tmp1), out_ptr[k], 16384); + move16(); + out_ptr[kj+1] = mac_r(L_negate(L_tmp2), out_ptr[k+1], 16384); + move16(); + out_ptr[k] = mac_r(L_tmp1, out_ptr[k], 16384); + move16(); + out_ptr[k+1] = mac_r(L_tmp2, out_ptr[k+1], 16384); + move16(); + } + ji = add(ji, ii); + } + } + } + ELSE /* The ifFT part */ + { + /* Unrolled 1st/2nd Stage + * 1) to take advantage of Table Values (0 & +/- 16384) + * 2) to perform reordering of Input Values + */ + FOR (k = 0; k < SIZE; k += 8) + { + /* + * This loop use: + * 4 Word16 (tmp1...tmp4) + * 2 Word32 (L_tmp1 & L_tmp2) + * 5 Pointers (reorder_ptr, input_ptr1...input_ptr4) + * + * The addition of 'in_ptr' + and index value from 'reorder_ptr' + * is counted as a move16() + */ + input_ptr1= in_ptr + (const Word16)((uintptr_t)(*table_ptr++) >> (uintptr_t)shift); + input_ptr2 = in_ptr + (const Word16)((uintptr_t)(*table_ptr++) >> (uintptr_t)shift); + + input_ptr3 = in_ptr + (const Word16)((uintptr_t)(*table_ptr++) >> (uintptr_t)shift); + input_ptr4 = in_ptr + (const Word16)((uintptr_t)(*table_ptr++) >> (uintptr_t)shift); + + + tmp3 = sub(*input_ptr1, *input_ptr2); + tmp4 = add(*input_ptr1++, *input_ptr2++); + + tmp2 = sub(input_ptr3[0], input_ptr4[0]); + tmp1 = sub(input_ptr3[1], input_ptr4[1]); + + out_ptr[k+2] = sub(tmp3, tmp1); + move16(); + out_ptr[k+6] = add(tmp3, tmp1); + move16(); + + tmp1 = sub(*input_ptr1, *input_ptr2); + out_ptr[k+3] = add(tmp1, tmp2); + move16(); + out_ptr[k+7] = sub(tmp1, tmp2); + move16(); + + tmp1 = add(input_ptr3[0], input_ptr4[0]); + tmp3 = add(input_ptr3[1], input_ptr4[1]); + + out_ptr[k] = add(tmp4, tmp1); + move16(); + out_ptr[k+4] = sub(tmp4, tmp1); + move16(); + + tmp4 = add(*input_ptr1, *input_ptr2); + out_ptr[k+1] = add(tmp4, tmp3); + move16(); + out_ptr[k+5] = sub(tmp4, tmp3); + move16(); + } + + table_ptr = phs_tbl + SIZE; /* access part of table that is scaled by 2 */ + + /* Remaining Stages */ + FOR (i = 2; i < NUM_STAGE; i++) + { + /* i is stage counter */ + jj = shl(2, i); /* FFT size */ + kk = shl(jj, 1); /* 2 * FFT size */ + ii = shr(SIZE, i); + ji = 0; + move16(); /* ji is phase table index */ + + FOR (j = 0; j < jj; j += 2) + { + /* j is sample counter */ + /* This can be computed by successive add_fxitions of ii to ji, starting from 0 + hence line-count it as a one-line add (still need to increment op count!!) */ + + FOR (k = j; k < SIZE; k += kk) + { + /* k is butterfly top */ + kj = add(k, jj); /* kj is butterfly bottom */ + + /* Butterfly computations */ +#ifdef BASOP_NOGLOB + tmp1 = mac_r_sat(L_mult_sat(out_ptr[kj], table_ptr[ji]), out_ptr[kj+1], table_ptr[ji + 1]); + + tmp2 = msu_r_sat(L_mult_sat(out_ptr[kj+1], table_ptr[ji]), out_ptr[kj], table_ptr[ji+1]); + + out_ptr[kj] = sub_sat(out_ptr[k], tmp1); + move16(); + out_ptr[kj+1] = sub_sat(out_ptr[k+1], tmp2); + move16(); + out_ptr[k] = add_sat(out_ptr[k], tmp1); + move16(); + out_ptr[k+1] = add_sat(out_ptr[k+1], tmp2); + move16(); +#else + tmp1 = mac_r(L_mult(out_ptr[kj], table_ptr[ji]), + out_ptr[kj+1], table_ptr[ji + 1]); + + tmp2 = msu_r(L_mult(out_ptr[kj+1], table_ptr[ji]), + out_ptr[kj], table_ptr[ji+1]); + + out_ptr[kj] = sub(out_ptr[k], tmp1); + move16(); + out_ptr[kj+1] = sub(out_ptr[k+1], tmp2); + move16(); + out_ptr[k] = add(out_ptr[k], tmp1); + move16(); + out_ptr[k+1] = add(out_ptr[k+1], tmp2); + move16(); +#endif + } + ji = add(ji, ii); + } + } + } +} + +/*--------------------------------------------------------------------------------* + * r_fft_fx: + * + * Perform FFT fixed-point for real-valued sequences of length 32, 64 or 128 + *--------------------------------------------------------------------------------*/ +void r_fft_fx_lc( + const Word16 *phs_tbl, /* i : Table of phase */ + const Word16 SIZE, /* i : Size of the FFT */ + const Word16 SIZE2, /* i : Size / 2 */ + const Word16 NUM_STAGE, /* i : Number of stage */ + const Word16 *in_ptr, /* i : coefficients in the order re[0], re[1], ... re[n/2], im[n/2-1], im[n/2-2], ..., im[1] */ + Word16 *out_ptr, /* o : coefficients in the order re[0], re[1], ... re[n/2], im[n/2-1], im[n/2-2], ..., im[1] */ + const Word16 isign /* i : 1=fft, otherwize it's ifft */ +) +{ + Word16 tmp2_real, tmp2_imag; + Word32 Ltmp1_real, Ltmp1_imag; + Word16 i; + Word32 Ltmp1; + const Word16 *phstbl_ptrDn; + Word16 *ptrDn; + Word16 temp[1024]; /* Accommodates real input FFT size up to 1024. */ + + /* Setup Pointers */ + phstbl_ptrDn = &phs_tbl[SIZE-1]; + + /* The FFT part */ + IF (isign != 0) + { + Word16 *ptRealUp, *ptRealDn, *ptImaUp, *ptImaDn; + + /* Perform the complex FFT */ + c_fft_fx(phs_tbl, SIZE, NUM_STAGE, in_ptr, temp, isign); + + /* First, handle the DC and foldover frequencies */ + out_ptr[SIZE2] = sub(temp[0], temp[1]); + move16(); + out_ptr[0] = sub(add(temp[0], temp[1]), shr(NUM_STAGE, 1)); + move16();/* DC have a small offset */ + + ptrDn = &temp[SIZE-1]; + + ptImaDn = &out_ptr[SIZE-1]; + ptRealUp = &out_ptr[1]; + ptImaUp = &out_ptr[SIZE2+1]; + ptRealDn = &out_ptr[SIZE2-1]; + + /* Now, handle the remaining positive frequencies */ + FOR (i = 2; i <= SIZE2; i += 2) + { + Ltmp1_imag = L_mult(temp[i+1], 16384); + Ltmp1_imag = L_msu(Ltmp1_imag, *ptrDn, 16384); + tmp2_real = add(temp[i+1], *ptrDn--); + + Ltmp1_real = L_mult(temp[i], 16384); + Ltmp1_real = L_mac(Ltmp1_real, *ptrDn, 16384); + tmp2_imag = sub(*ptrDn--, temp[i]); + + + *ptRealUp++ = msu_r(L_mac(Ltmp1_real, tmp2_real, phs_tbl[i]), tmp2_imag, phs_tbl[i+1]); + move16(); + *ptImaDn-- = mac_r(L_mac(Ltmp1_imag, tmp2_imag, phs_tbl[i]), tmp2_real, phs_tbl[i+1]); + move16(); + Ltmp1 = L_mac(L_negate(Ltmp1_imag), tmp2_real, *phstbl_ptrDn); + Ltmp1_real = L_mac(Ltmp1_real, tmp2_imag, *phstbl_ptrDn--); + *ptImaUp++ = msu_r(Ltmp1, tmp2_imag, *phstbl_ptrDn); + move16(); + *ptRealDn-- = mac_r(Ltmp1_real, tmp2_real, *phstbl_ptrDn--); + move16(); + } + } + ELSE /* The ifFT part */ + { + const Word16 *ptRealUp, *ptRealDn, *ptImaUp, *ptImaDn; + + /* First, handle the DC and foldover frequencies */ + Ltmp1 = L_mult(in_ptr[0], 16384); + temp[0] = mac_r(Ltmp1, in_ptr[SIZE2], 16384); + move16(); + temp[1] = msu_r(Ltmp1, in_ptr[SIZE2], 16384); + move16(); + + ptrDn = &temp[SIZE-1]; + + /* Here we cast to Word16 * from a const Word16 *. */ + /* This is ok because we use these pointers for */ + /* reading only. This is just to avoid declaring a */ + /* bunch of 4 other pointer with const Word16 *. */ + ptImaDn = &in_ptr[SIZE-1]; + ptRealUp = &in_ptr[1]; + ptImaUp = &in_ptr[SIZE2+1]; + ptRealDn = &in_ptr[SIZE2-1]; + + /* Now, handle the remaining positive frequencies */ + FOR (i = 2; i <= SIZE2; i += 2) + { + Ltmp1_imag = L_mult(*ptImaDn, 16384); + Ltmp1_imag = L_msu(Ltmp1_imag, *ptImaUp, 16384); + tmp2_real = add(*ptImaDn--, *ptImaUp++); + Ltmp1_real = L_mult(*ptRealUp, 16384); + Ltmp1_real = L_mac(Ltmp1_real, *ptRealDn, 16384); + tmp2_imag = sub(*ptRealUp++, *ptRealDn--); + + + temp[i] = mac_r(L_msu(Ltmp1_real, tmp2_real, phs_tbl[i]), tmp2_imag, phs_tbl[i+1]); + move16(); + temp[i+1] = mac_r(L_mac(Ltmp1_imag, tmp2_imag, phs_tbl[i]), tmp2_real, phs_tbl[i+1]); + move16(); + Ltmp1 = L_mac(L_negate(Ltmp1_imag), tmp2_real, *phstbl_ptrDn); + Ltmp1_real = L_msu(Ltmp1_real, tmp2_imag, *phstbl_ptrDn--); + *ptrDn-- = msu_r(Ltmp1, tmp2_imag, *phstbl_ptrDn); + move16(); + *ptrDn-- = msu_r(Ltmp1_real, tmp2_real, *phstbl_ptrDn--); + move16(); + } + + /* Perform the complex ifFT */ + c_fft_fx(phs_tbl, SIZE, NUM_STAGE, temp, out_ptr, isign); + } +} diff --git a/lib_com/fine_gain_bits_fx.c b/lib_com/fine_gain_bits_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..440517657ec56ff45882ee5300043265f550ebc2 --- /dev/null +++ b/lib_com/fine_gain_bits_fx.c @@ -0,0 +1,105 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include +#include "options.h" /* Compilation switches */ +#include "rom_com.h" /* Static table prototypes */ +#include "prot_fx1.h" /* Function prototypes */ +#include "prot_fx2.h" /* Function prototypes */ + + +/*-------------------------------------------------------------------------- + * subband_gain_bits() + * + * HQ core encoder + *--------------------------------------------------------------------------*/ + +static void subband_gain_bits_fx( + const Word16 *Rk, /* i : bit allocation per band Q3 */ + const Word16 N, /* i : number of bands */ + Word16 *bits, /* o : gain bits per band */ + const Word16 *sfmsize /* i : Size of bands */ +) +{ + Word16 i,b,tot; + Word16 bps; + + tot = 0; + move16(); + + FOR ( i = 0; i < N; i++ ) + { + /*bps = (short)(Rk[i]*((word16)min(32767, ceil(32767.0f/sfmsize[i]); inexact C-integer division approx. */ + bps = extract_l(L_shr(L_mult0(Rk[i], inv_tbl_fx[sfmsize[i]]), 18)); /* 3+15 */ + if (EQ_32(L_shl(L_mult0(sfmsize[i], add(bps, 1)), 3), Rk[i])) + { + bps = add(bps, 1); + } + + bps = s_min(7, bps); + b = fine_gain_bits[bps]; + move16(); + bits[i] = b; + move16(); + tot = add(tot, b); + } + + if ( tot == 0) + { + /* If no gain bits were assigned, use one bit anyway for potential PVQ overage */ + bits[0] = 1; + move16(); + } + + return; +} + +/*--------------------------------------------------------------------------* + * assign_gain_bits() + * + * Assign gain adjustment bits and update bit budget + *--------------------------------------------------------------------------*/ + +Word16 assign_gain_bits_fx( /* o : Number of assigned gain bits */ + const Word16 core, /* i : HQ core */ + const Word16 BANDS, /* i : Number of bands */ + const Word16 *band_width, /* i : Sub band bandwidth */ + Word16 *Rk, /* i/o: Bit allocation/Adjusted bit alloc. Q3 */ + Word16 *gain_bits_array, /* o : Assigned gain bits */ + Word16 *Rcalc /* o : Bit budget for shape quantizer Q3 */ +) +{ + Word16 gain_bits_tot; + Word16 i; + + /* Allocate gain bits for every subband used, based on bit rate and bandwidth */ + IF( EQ_16(core, HQ_CORE)) + { + subband_gain_bits_fx(Rk, BANDS, gain_bits_array, band_width); + } + ELSE + { + set16_fx( gain_bits_array, 0, BANDS ); + } + + /* Re-adjust bit budget for gain quantization */ + move16(); + gain_bits_tot = 0; + move16(); + *Rcalc = 0; + move16(); + FOR (i = 0; i < BANDS; i++) + { + IF (Rk[i] > 0) + { + Rk[i] = sub(Rk[i], shl(gain_bits_array[i], 3)); + move16(); + gain_bits_tot = add(gain_bits_tot, gain_bits_array[i]); + *Rcalc = add(*Rcalc, Rk[i]); + move16(); + } + } + + return gain_bits_tot; +} diff --git a/lib_com/gain_inov_fx.c b/lib_com/gain_inov_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..5f4232f40c79b041ba92587dedcbac3d7ecf757d --- /dev/null +++ b/lib_com/gain_inov_fx.c @@ -0,0 +1,56 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include +#include +#include "options.h" +#include "prot_fx1.h" +#include "prot_fx2.h" +#include "basop_util.h" +#include "rom_com.h" + + +Word32 calc_gain_inov( /* returns innovation gain Q16 */ + const Word16 *code, /* i : algebraic excitation Q9 */ + const Word16 lcode, /* i : Subframe size Q0 */ + Word32 *dotp, /* o : intermediate result Q31-e */ + Word16 *dotp_e /* o : intermediate result exponent Q0 */ +) +{ + Word32 L_tmp; + Word16 exp_L_tmp, i; + + /* L_tmp = dot_product(code, code, lcode) + 0.01 */ + L_tmp = Dot_product12_offs(code, code, lcode, &exp_L_tmp, 2621l/*0.01f/2.0f Q19*/); + exp_L_tmp = sub(exp_L_tmp, 18); + + /* gain_inov = 1.0f / sqrt((dot_product(code, code, lcode) + 0.01) / lcode) */ + /* Note: lcode is in range: 32,40,64,80 */ + assert((lcode == 32) || (lcode == 40) || (lcode == 64) || (lcode == 80)); + if (s_and(lcode, sub(lcode, 1)) != 0) + { + L_tmp = Mpy_32_32(L_tmp, 1717986918l/*64.0/80.0 Q31*/); + } + exp_L_tmp = sub(exp_L_tmp, sub(14, norm_s(lcode))); + + i = norm_l(L_tmp); + L_tmp = L_shl(L_tmp, i); + exp_L_tmp = sub(exp_L_tmp, i); + + if (dotp != NULL) + { + *dotp = L_tmp; + move32(); + } + if (dotp_e != NULL) + { + *dotp_e = exp_L_tmp; + move16(); + } + + L_tmp = ISqrt32norm(L_tmp, &exp_L_tmp); + + return L_shl(L_tmp, sub(exp_L_tmp, 15)); /* 15Q16 */ +} + diff --git a/lib_com/gs_bitallocation_fx.c b/lib_com/gs_bitallocation_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..01466f24f138712c932cb9607efb61f725bb29c1 --- /dev/null +++ b/lib_com/gs_bitallocation_fx.c @@ -0,0 +1,952 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ +#include +#include "options.h" /* Compilation switches */ +#include "cnst.h" /* Common constants */ +#include "rom_com.h" /* Static table prototypes */ +#include "prot_fx1.h" /* Function prototypes */ +#include "prot_fx2.h" /* Function prototypes */ +#include "assert.h" /* Debug prototypes */ +#include "stl.h" + +/*==================================================================================*/ +/* FUNCTION : void bands_and_bit_alloc_fx(); */ +/*----------------------------------------------------------------------------------*/ +/* PURPOSE : AC mode (GSC) bands and bits allocation */ +/*----------------------------------------------------------------------------------*/ +/* INPUT ARGUMENTS : */ +/* _ (Word16) cor_strong_limit : HF correlation */ +/* _ (Word16) noise_lev : dwn scaling factor Q0 */ +/* _ (Word32) core_brate : core codec used Q0 */ +/* _ (Word16) Diff_len : Lenght of the difference signal Q0 */ +/* _ (Word16) bits_used : Number of bit used before frequency Q0 */ +/* _ (Word16) idx : Energy band 14 Q0 */ +/* _ (Word16*) exc_diff : Difference signal to quantize (Encoder only) */ +/* _ (Word16) coder_type : coding type Q0 */ +/* _ (Word16) bwidth : input signal bandwidth Q0 */ +/*----------------------------------------------------------------------------------*/ +/* OUTPUT ARGUMENTS : */ +/* _ (Word16*) max_ener_band : Sorted order */ +/* _ (Word16*) nb_subbands : Number of subband allowed Q0 */ +/* _ (Word16*) concat_in : Concatened PVQ's input vector (Encoder Only) */ +/* _ (Word16*) pvq_len : Number of bin covered with the PVQ Q0 */ +/*----------------------------------------------------------------------------------*/ +/* INPUT/OUTPUT ARGUMENTS : */ +/* _ (Word16*) bit :Number of bit allowed for frequency quantization */ +/* _ (Word16*) Ener_per_bd_iQ : Quantized energy vector Q13 */ +/* _ (Word32*) bits_per_bands : Number of bit allowed per allowed subband Q18 */ +/*----------------------------------------------------------------------------------*/ +/* RETURN ARGUMENTS : */ +/* _ None */ +/*==================================================================================*/ +void bands_and_bit_alloc_fx( + const Word16 cor_strong_limit, /* i : HF correlation */ + const Word16 noise_lev, /* i : dwn scaling factor */ + const Word32 core_brate, /* i : core bit rate */ + const Word16 Diff_len, /* i : Lenght of the difference signal (before pure spectral)*/ + const Word16 bits_used, /* i : Number of bit used before frequency Q */ + Word16 *bit, /* i/o: Number of bit allowed for frequency quantization */ + const Word16 *Ener_per_bd_iQ, /* i/o: Quantized energy vector */ + Word16 *max_ener_band, /* o : Sorted order */ + Word16 *out_bits_per_bands, /* i/o: Number of bit allowed per allowed subband Q3 */ + Word16 *nb_subbands, /* o : Number of subband allowed */ + const Word16 *exc_diff, /* i : Difference signal to quantize (encoder side only) */ + Word16 *concat_in, /* o : Concatened PVQ's input vector (encoder side only) */ + Word16 *pvq_len, /* o : Number of bin covered with the PVQ */ + const Word16 coder_type, /* i : coding type */ + const Word16 bwidth, /* i : input signal bandwidth */ + const Word16 GSC_noisy_speech, /* i : GSC noisy speech flag */ + const Word16 L_frame, /* i : frame length */ + const Word16 element_mode, /* i : element mode */ + const Word16 GSC_IVAS_mode /* i : GSC IVAS mode */ +) +{ + + Word16 bandoffset, i, j, nb_bands_max, bit_new_bands, bit_tmp, st_band, nb_bands; + Word16 ener_vec[MBANDS_GN_BITALLOC16k]; /*Q12 */ + Word16 nb_tot_bands = 16; + Word16 bit_index, bit_index_mem, imax; + Word32 L_tmp; + Word32 sum_bit, bit_fracf; + Word16 etmp; + Word16 tmp; + Word16 Ener_per_bd_iQ_tmp[MBANDS_GN_BITALLOC16k]; + Word16 pos, band; + Word16 SWB_bit_budget; + Word32 bits_per_bands[MBANDS_GN_BITALLOC16k]; + Word16 w_sum_bit; +#ifdef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING + (void)GSC_IVAS_mode; + (void)element_mode; +#endif +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + nb_tot_bands = MBANDS_GN; + move16(); + if (EQ_16(L_frame, L_FRAME16k)) + { + nb_tot_bands = MBANDS_GN_BITALLOC16k; + move16(); + } + Copy( Ener_per_bd_iQ, Ener_per_bd_iQ_tmp, nb_tot_bands); + + set32_fx( bits_per_bands, 0, MBANDS_GN_BITALLOC16k); + set16_fx( out_bits_per_bands, 0, MBANDS_GN_BITALLOC16k); + + /* To adapt current energy band to PVQ freq band for sorting*/ +#ifdef BASOP_NOGLOB + ener_vec[0] = add_o(Ener_per_bd_iQ[0],Ener_per_bd_iQ[1], &Overflow); /*Q12 */ +#else /* BASOP_NOGLOB */ + ener_vec[0] = add(Ener_per_bd_iQ[0],Ener_per_bd_iQ[1]); /*Q12 */ +#endif + Copy( Ener_per_bd_iQ_tmp+1, ener_vec, MBANDS_GN-1); /*Q12 */ + ener_vec[MBANDS_GN-1] = ener_vec[MBANDS_GN-2]; + move16(); + IF (EQ_16(L_frame, L_FRAME16k)) + { + ener_vec[16] = Ener_per_bd_iQ[16]; + ener_vec[17] = mac_r(L_mult(Ener_per_bd_iQ[16], 16384), Ener_per_bd_iQ[17],16384); + ener_vec[18] = Ener_per_bd_iQ[17]; + ener_vec[19] = mult_r(Ener_per_bd_iQ[17], 26214); + move16(); move16(); move16(); move16(); + } + + /*------------------------------------------------------------------------ + * Determination of the number of bits available to the frequency domain + * Allocation of a maximum number of band to be encoded + *-----------------------------------------------------------------------*/ + + nb_bands_max = nb_tot_bands; + move16(); + bit_new_bands = 5; + move16(); +#ifdef ADD_LRTD + if (GT_32(core_brate, ACELP_16k40) && EQ_16(L_frame, L_FRAME16k)) + { + bit_new_bands = 7; + move16(); + } + + i = 0; + move16(); + WHILE (LT_16(i, SIZE_BRATE_INTERMED_TBL)) + { + IF (LE_32(core_brate, brate_intermed_tbl[i])) + { + BREAK; + } + + IF (EQ_32(brate_intermed_tbl[i], ACELP_24k40)) + { + BREAK; + } + + i = add(i,1); + } + + if (GT_16(element_mode, EVS_MONO) && EQ_16(coder_type, AUDIO) && + LE_32(core_brate, STEREO_GSC_BIT_RATE_ALLOC) && EQ_32(brate_intermed_tbl[i], ACELP_9k60)) /* Bit allocation should be mapped to 8 kb/s instead of 9.6 kb/s in this case */ + { + i = sub(i,1); + } + + bit_index = i_mult2( BRATE2IDX_fx(brate_intermed_tbl[i]), 17); +#else + bit_index = i_mult2(BRATE2IDX_fx(core_brate),17); +#endif + bit_index_mem = bit_index; + move16(); + + test(); + test(); + IF( (EQ_16(coder_type,AUDIO)||EQ_16(coder_type,INACTIVE))&&EQ_16(bwidth,NB)) + { + IF(GE_32(core_brate,ACELP_9k60)) + { + /* *bit = (short)(core_brate*(1.0f/50) + 0.5f) - bits_used - 25; */ + L_tmp = Mult_32_16(core_brate,20971); + tmp = extract_l(L_shr_r(L_tmp,5)); + *bit = sub(sub(tmp,bits_used), 25); + move16(); + } + ELSE + { + L_tmp = Mult_32_16(core_brate,20971); + tmp = extract_l(L_shr_r(L_tmp,5)); + *bit = sub(sub(tmp,bits_used), 21); + move16(); + } + nb_tot_bands = 10; + move16(); + } + ELSE + { + /* *bit = (short)(core_brate*(1.0f/50) + 0.5f) - bits_used - GSC_freq_bits[bit_index]; */ + + L_tmp = Mult_32_16(core_brate,20971); + tmp = extract_l(L_shr_r(L_tmp,5)); + *bit = sub(sub(tmp,bits_used),GSC_freq_bits[bit_index]); + move16(); + } + +#ifdef ADD_LRTD + if (L_frame == L_FRAME16k) + { + *bit -= 8; + } + + if (coder_type == INACTIVE && core_brate <= GSC_LRES_GAINQ_LIMIT) /* can happen only for 2nd channel inactive */ + { + *bit += GSC_LRES_NB_NITS; + } + + if (*bit > 0) + { + if (GSC_IVAS_mode > 0) + { + SWB_bit_budget = *bit; + st_band = 5; + + set_f(bits_per_bands, 0, MBANDS_GN_BITALLOC16k); + + /* 2- Decide the pourcentage of bits allocated to LF (between 50-75%) depending of the temporal contribution in GSC */ + bit_fracf = (-0.125f * Diff_len + 76.0f) / 100; + bit_fracf = check_bounds(bit_fracf, 0.50f, 0.75f); + + /* Adjusment of the bitrate between LF and HF base on the content type */ + /* 1 = new GSC bit alloc + 2 = GSC bit alloc for tc frame + 3 = more music like (should not happen often given music is coded with dft) */ + + if (GSC_IVAS_mode <= 3) + { + nb_bands_max -= 6; + } + + if (GSC_IVAS_mode == 2) + { + bit_fracf += 0.1f; + nb_bands_max--; + } + + if (GSC_IVAS_mode == 3) + { + bit_fracf -= 0.1f; + nb_bands_max += 3; + } + + /* First find how much we want to share between LF and HF, at low bitrate, a miminum of bits is needed in LF by limitating the number of bands*/ + /* Adjust the number of band based on the content type and bitrate */ + nb_bands_adj = 1.0f; + if (GSC_IVAS_mode == 1 && core_brate < GSC_L_RATE_STG) + { + nb_bands_adj = 0.0125f * SWB_bit_budget - 0.75f; + } + else if (GSC_IVAS_mode != 2 && core_brate > GSC_H_RATE_STG) + { + nb_bands_adj = 0.02f * SWB_bit_budget - 1.2f; + } + nb_bands_max = (int16_t)(nb_bands_max * nb_bands_adj + 0.5f); + nb_bands_max = check_bounds_s(nb_bands_max, 5, nb_tot_bands); + + bit_fracf *= SWB_bit_budget; + + /* Estimation of the number of bit used in HF */ + /* with only the first weigthing The number of bits in max_ener_band[st_band-1] = 17% of bit_fracf */ + mb = .17f * bit_fracf; + mp = (2.0f * DSR_NB_PULSE); + if (core_brate < GSC_L_RATE_STG && GSC_IVAS_mode == 3) + { + mp = 1.5f * DSR_NB_PULSE; + } + else if (core_brate < GSC_L_RATE_STG) + { + mp = DSR_NB_PULSE; + } + + /* We want max_ener_band[st_band] <= max_ener_band[st_band-1] and max_ener_band[nb_bands_max-1] <= max_ener_band[st_band]*/ + /* We will estimate the number of bits to allocate of HF and put the remaining bits, if any, back on LF */ + /* compute the total possible number of band to be coded */ + nb_tot_bands = (int16_t)((SWB_bit_budget - bit_fracf) / (mp + (mb - mp) / 2.0f)); + mp = min(mp, mb); + if (nb_tot_bands + st_band > nb_bands_max) + { + bit_adj = ((mb + mp) / 2) * (nb_tot_bands + st_band - nb_bands_max); + bit_adj = max(0, bit_adj); + nb_tot_bands = nb_bands_max - st_band; + bit_fracf += bit_adj; + } + nb_tot_bands += st_band; + + /* Allocate bits to LF */ + etmp = 0.23f; + for (j = 0; j < st_band; j++) + { + i = j; + max_ener_band[j] = i; + ener_vec[i] = MIN16B; + bits_per_bands[j] = etmp * bit_fracf; + etmp -= 0.015f; + } + + SWB_bit_budget -= bit_fracf; + + /* Find low energy band in HF */ + set_s(nb_pulse_per_band, 2, MBANDS_GN_BITALLOC16k); + for (i = st_band + 2; i < nb_tot_bands - 1; i++) + { + if (ener_vec[i] < ener_vec[i - 1] && ener_vec[i] < ener_vec[i + 1]) + { + nb_pulse_per_band[i] = 1; + } + } + for (j = st_band; j < nb_tot_bands; j++) + { + if (j > 6) + { + i = maximum(ener_vec, nb_tot_bands, &etmp); + } + else + { + i = j; + } + + max_ener_band[j] = i; + ener_vec[i] = MIN16B; + } + + /* Recompute the final bit distribution for HF */ + if (nb_tot_bands > st_band) + { + bit_fracf = DSR_NB_PULSE; + mb = (SWB_bit_budget * 2 / (nb_tot_bands - st_band)) - mp; + bit_fracf = (mb - mp) / (nb_tot_bands - st_band); + mb -= bit_fracf; + /* Do the distribution */ + for (j = st_band; j < nb_tot_bands; j++) + { + if (nb_pulse_per_band[max_ener_band[j]] > 1) + { + bits_per_bands[max_ener_band[j]] = mb; + } + else + { + bits_per_bands[max_ener_band[j]] = 4.5f; + } + mb -= bit_fracf; + SWB_bit_budget -= bits_per_bands[max_ener_band[j]]; + } + } + + /* Series of verification in case bit allocated != the budget */ + if (SWB_bit_budget > 0) + { + i = st_band - 1; + while (SWB_bit_budget > 0) + { + bits_per_bands[i]++; + SWB_bit_budget--; + i--; + if (i == -1) + { + i = st_band - 1; + } + } + } + + nb_bands = nb_tot_bands; + + sum_bit = 0; + j = 0; + for (i = 0; i < nb_bands; i++) + { + if (bits_per_bands[i] > 112) + { + sum_bit += bits_per_bands[i] - 112; + bits_per_bands[i] = 112; + j = i + 1; + } + + /* safety check for overage bit reallocation */ + else if (bits_per_bands[i] + sum_bit / 3 > 112) + { + j = i + 1; + } + } + + if (sum_bit != 0) + { + sum_bit /= (nb_bands - j); + for (i = j; i < nb_bands; i++) + { + bits_per_bands[i] += sum_bit; + } + } + } + else +#endif + IF(EQ_16(GSC_noisy_speech, 1)) + { + SWB_bit_budget = *bit; + move16(); + nb_bands = 5; + move16(); + +#ifdef ADD_LRTD + + fzero_val = 0.0f; + if (element_mode > EVS_MONO) + { + fzero_val = MIN16B_FLT; + } + + if (coder_type == UNVOICED && element_mode > EVS_MONO) + { + nb_bands = 3; + if (SWB_bit_budget > 20) + { + nb_bands = 5; + } + } + else if (bwidth < SWB) + { + nb_bands = 7; + } + +#endif + + st_band = nb_bands; + move16(); + + set32_fx(bits_per_bands, 0, MBANDS_GN); + /*bit_fracf = (1.0f/nb_bands)*(SWB_bit_budget); */ + bit_fracf = L_mult(div_s(1, nb_bands), shl(SWB_bit_budget, 2)); /* Q18 */ + + nb_tot_bands = sub(nb_bands_max, 6); + nb_tot_bands = s_min(nb_tot_bands, 16); + + FOR(j = 0; j < 2; j++) + { + i = j; + move16(); + max_ener_band[j] = i; + move16(); + ener_vec[i] = 0; + move16(); + } +#ifdef ADD_LRTD + if (bwidth < SWB) + { + if (coder_type == UNVOICED && element_mode > EVS_MONO) + { + nb_tot_bands = 5; + } +#endif + FOR(; j < nb_bands; j++) + { + i = maximum_fx(ener_vec, nb_tot_bands, &etmp); + max_ener_band[j] = i; + move16(); + ener_vec[i] = 0; + move16(); + } +#ifdef ADD_LRTD + } + else + { + for (; j < nb_bands; j++) + { + i = maximum(ener_vec, nb_tot_bands, &etmp); + max_ener_band[j] = i; + ener_vec[i] = fzero_val; + } + } +#endif + set32_fx(bits_per_bands, bit_fracf, nb_bands); + } + ELSE + { + bit_index++; + bit_tmp = sub(*bit,GSC_freq_bits[bit_index]); + bit_index++; + nb_bands_max = add(nb_bands_max,GSC_freq_bits[bit_index]); + bit_index++; + + *pvq_len = 112; + move16(); + st_band = 7; + move16(); +#ifdef ADD_LRTD + if (L_frame == L_FRAME16k && core_brate > ACELP_16k40) + { + *pvq_len = 160; + st_band = 10; + nb_bands = *pvq_len / 16; + bit_tmp -= 35; + bit_new_bands = 5; + } +#endif + IF(LE_32(core_brate,ACELP_9k60)) + { + *pvq_len = 80; + move16(); + st_band = 5; + move16(); + + IF(Diff_len == 0) + { + nb_bands_max = add(nb_bands_max,2); + bit_tmp = sub(bit_tmp,13); + } + } + + ELSE IF(Diff_len == 0) + { + nb_bands_max = add(nb_bands_max,2); + bit_tmp = sub(bit_tmp,17); + } + + nb_bands = shr(*pvq_len,4); +#ifdef ADD_LRTD + nb_bands_max = min(nb_bands_max, MBANDS_GN_BITALLOC16k); +#endif + /*------------------------------------------------------------------------ + * Ajustement of the maximum number of bands in function of the + * dynamics of the spectrum (more or less speech like) + *-----------------------------------------------------------------------*/ + test(); + test(); + test(); + test(); + IF(EQ_16(coder_type,INACTIVE) || GE_16(noise_lev,NOISE_LEVEL_SP3)) + { + /* Probably classification error -> concentrate bits on LF */ +#ifdef ADD_LRTD + if (L_frame == L_FRAME16k && core_brate >= ACELP_24k40) + { + nb_bands_max = nb_tot_bands - 2; + } + else if (core_brate >= ACELP_16k40) + { + nb_bands_max = nb_bands + 2; + } + else +#endif + if (GE_32(core_brate,ACELP_8k00)) + { + nb_bands_max = add(nb_bands,1); + } + else + { + nb_bands_max = nb_bands; + move16(); + } + } + ELSE IF(GE_16(noise_lev,NOISE_LEVEL_SP2) || + (LE_32(core_brate,ACELP_13k20) && GE_32(core_brate,ACELP_9k60) && cor_strong_limit == 0)) /* Very low dynamic, tend to speech, do not try to code HF at all */ + { + nb_bands_max = sub(nb_bands_max,2); + } + ELSE if (GE_16(noise_lev,NOISE_LEVEL_SP1)) /* Very low dynamic, tend to speech, code less HF */ + { + nb_bands_max = sub(nb_bands_max,1); + } + #ifdef ADD_LRTD + if (L_frame == L_FRAME16k) + { + if (core_brate < ACELP_24k40) + { + nb_bands_max -= 4; + } + else if (core_brate < ACELP_32k) + { + if (Diff_len > 0 || noise_lev >= NOISE_LEVEL_SP2) + { + nb_bands_max -= 2; + bit_new_bands *= 2; + } + } + else if (core_brate >= ACELP_32k) + { + bit_new_bands *= 2; + } + } + +#endif + test(); + if (EQ_16(bwidth,NB) && GT_16(nb_bands_max,10)) + { + nb_bands_max = 10; + move16(); + } + + /*------------------------------------------------------------------------ + * Find extra number of band to code according to bit rate availables + *-----------------------------------------------------------------------*/ + WHILE(GE_16(bit_tmp,bit_new_bands) && LE_16(nb_bands,sub(nb_bands_max,1))) + { + bit_tmp = sub(bit_tmp,bit_new_bands); + nb_bands = add(nb_bands,1); + } + + /*------------------------------------------------------------------------ + * Fractional bits to distribute on the first x bands + *-----------------------------------------------------------------------*/ +#ifdef ADD_LRTD + if (L_frame == L_FRAME16k && core_brate > ACELP_32k) + { + bit_fracf = 0; + } + else +#endif + { + bit_fracf = L_mult(div_s(1, st_band), shl(bit_tmp, 2)); /* Q18 */ + } + /*------------------------------------------------------------------------ + * Complete the bit allocation per frequency band + *-----------------------------------------------------------------------*/ + imax = 5; + move16(); + + if (GT_32(core_brate,ACELP_9k60)) + { + imax = 7; + move16(); + } + FOR(i = 0; i < imax; i++) + { + bits_per_bands[i] = L_add(GSC_freq_bits_fx[bit_index],bit_fracf); + move32();/* Q18 */ + bit_index = add(bit_index,1); + } +#ifdef ADD_LRTD + if (L_frame == L_FRAME16k && core_brate > ACELP_16k40) + { + bit_index = 0; + i = imax - 1; + bits_per_bands[i] += Compl_GSC_freq_bits[bit_index]; + i++; + bit_index++; + + for (; i < 10; i++) + { + bits_per_bands[i] += Compl_GSC_freq_bits[bit_index] + bit_fracf; + bit_index++; + } + } +#endif + IF(Diff_len == 0) + { + bit_index = add(bit_index_mem,10); + FOR(i = 0; i < 7; i++) + { + bits_per_bands[i] = L_add(bits_per_bands[i],GSC_freq_bits_fx[bit_index]); + move32();/*chk Q18 */ + bit_index = add(bit_index,1); + } + } +#ifdef ADD_LRTD + if (bit_fracf < 0) + { + for (j = 0; j < nb_tot_bands; j++) + { + bits_per_bands[j] = max(bits_per_bands[j], 0); + } + } + +#endif + /*-------------------------------------------------------------------------- + * Complete the bit allocation per frequency band for 16kHz high brate mode + *--------------------------------------------------------------------------*/ +#ifdef ADD_LRTD + if (L_frame == L_FRAME16k && core_brate > ACELP_32k) + { + for (j = st_band; j < nb_bands; j++) + { + bits_per_bands[j] = bit_new_bands; + } + + bit_fracf = (1.0f / nb_bands) * (bit_tmp); + + etmp = 2.0f * bit_fracf / (nb_bands + 1); + bit_fracf = etmp; + for (j = nb_bands - 1; j >= 0; j--) + { + bits_per_bands[j] += etmp; + etmp += bit_fracf; + } + } + else +#endif + { + FOR(j = st_band; j < nb_bands; j++) + { + bits_per_bands[j] = L_shl(bit_new_bands, 18); + move32(); /*chk Q18 */ + } + } + + /*-------------------------------------------------------------------------- + * Compute a maximum band (band offset) for the search on maximal energy + * This is function of the spectral dynamic and the bitrate + *--------------------------------------------------------------------------*/ + + bandoffset = sub(nb_tot_bands,add(nb_bands,2)); + + test(); + test(); + test(); + test(); + test(); + IF(LE_16(noise_lev,NOISE_LEVEL_SP1a)) + { + bandoffset = sub(bandoffset,1); + } + ELSE if ((LE_32(core_brate,ACELP_13k20) && (EQ_16(coder_type,INACTIVE) || GE_16(noise_lev,NOISE_LEVEL_SP3))) || + (LE_32(core_brate,ACELP_13k20) && GE_32(core_brate,ACELP_9k60) && cor_strong_limit == 0)) + { + bandoffset = add(bandoffset,1); + } + + bandoffset = s_max(bandoffset ,0); + + /*-------------------------------------------------------------------------- + * Initiazed sorted vector + * For the first x bands to be included in th final sorted vector + * Sort the remaining bands in decrease energy order + *--------------------------------------------------------------------------*/ + FOR(j = 0; j < nb_tot_bands; j++) + { + max_ener_band[j] = -10; + move16(); + } + FOR(j = 0; j < st_band; j++) + { + max_ener_band[j] = j; + move16(); + ener_vec[j] = -10; + move16(); + } + pos = st_band; + move16(); + FOR(; j < nb_bands; j++) + { + i = maximum_fx(ener_vec, sub(nb_tot_bands,bandoffset), &etmp); + pos = s_max(pos,i); + max_ener_band[j] = i; + move16(); + ener_vec[i] = -10; + move16(); + } + + /* re-allocate bits to the frames such that the highest band with allocated bits is higher than the threshold */ + test(); + test(); + test(); + IF(GT_16(sub(nb_tot_bands, bandoffset),nb_bands) && (GT_16(pos,7) && EQ_32(core_brate,ACELP_8k00)) && EQ_16(bwidth,WB)) + { + band = sub(nb_tot_bands, add(bandoffset,nb_bands)); + FOR(j = 0; j < band; j++) + { + i = maximum_fx(ener_vec, sub(nb_tot_bands,bandoffset), &etmp); + max_ener_band[add(nb_bands,j)] = i; + move16(); + ener_vec[i] = -10; + move16(); + bits_per_bands[add(nb_bands,j)] = 1310720; + move32(); /*Q18 */ + } + nb_bands = add(nb_bands,band); + + bit_tmp = i_mult2(band,5); + + IF(LE_16(band,2)) + { + FOR(j = sub(st_band,1); j < nb_bands; j++) + { + bits_per_bands[j] = L_add(bits_per_bands[j],262144); /*Q18 */ move32(); + } + bit_tmp = add(bit_tmp, add(sub(nb_bands, st_band) , 1)); + } + + i = 0; + move16(); + j = 0; + move16(); + FOR(; bit_tmp > 0; bit_tmp--) + { + bits_per_bands[j] = L_sub(bits_per_bands[j],262144); /*Q18 */ + j = add(j,1); + if (EQ_16(j,sub(st_band, i))) + { + j = 0; + move16(); + } + test(); + if (j == 0 && LT_16(i,sub(st_band, 1))) + { + i = add(i,1); + } + } + } + } + /*-------------------------------------------------------------------------- + * Bit sum verification for GSC inactive at very high rate + * The maximum number of bits per band of length 16 is 112 + * Redistribute the overage bits if needed + *--------------------------------------------------------------------------*/ + sum_bit = 0; + move16(); + j = 0; + move16(); + FOR(i = 0; i < nb_bands; i++) + { + L_tmp = Mult_32_16(sum_bit, 10923); + + IF(GT_32(bits_per_bands[i], 29360128)) /* 112 in Q18 */ + { + sum_bit = L_add(sum_bit, L_sub(bits_per_bands[i], 29360128)); /* Q18 */ + bits_per_bands[i] = 29360128; + move32(); + j = add(i, 1); + } + ELSE if (GT_32(L_add(bits_per_bands[i], L_tmp), 29360128)) /* Q18 */ + { + j = add(i, 1); + } + } + + IF(sum_bit != 0) + { + tmp = sub(nb_bands, j); + sum_bit = Mult_32_16(sum_bit, div_s(1, tmp)); /* Q18 */ + FOR(i = j; i < nb_bands; i++) + { + bits_per_bands[i] = L_add(bits_per_bands[i], sum_bit); + move32();/* Q18 */ + } + } + /*-------------------------------------------------------------------------- + * second step of bit sum verification, normally sum_bit == *bit + *--------------------------------------------------------------------------*/ + w_sum_bit = 0; + move16(); + FOR(i = 0; i < nb_bands; i++) + { + out_bits_per_bands[i] = shl(extract_l(L_shr(bits_per_bands[i], 18)), 3); + move16(); + w_sum_bit = add(w_sum_bit, out_bits_per_bands[i]); /* Q3 */ + } + tmp = shl(*bit, 3); +#ifdef ADD_LRTD + if (GSC_IVAS_mode != 0 && sum_bit < *bit) /* If we need to add bits, we are doing it on the LF */ + { + reajust_bits(bits_per_bands, 0, nb_bands, (int16_t)sum_bit, *bit); + } + else + { + reajust_bits(bits_per_bands, nb_bands - 1, 0, (int16_t)sum_bit, *bit); + } +#else + IF(GT_16(tmp, w_sum_bit)) + { + i = sub(nb_bands, 1); + move16(); + FOR(; tmp > w_sum_bit; w_sum_bit += (1 << 3)) + { + out_bits_per_bands[i] = add(out_bits_per_bands[i], 1 << 3); + move16(); + i = sub(i, 1); + if (i == 0) + { + i = sub(nb_bands, 1); + } + } + } +#endif + /*-------------------------------------------------------------------------- + * Recompute the real number/length of frequency bands to encode + *--------------------------------------------------------------------------*/ + * nb_subbands = nb_bands; + move16(); + *pvq_len = shl(*nb_subbands, 4); + + /*-------------------------------------------------------------------------- + * Concatenate bands (encoder only) + *--------------------------------------------------------------------------*/ + IF(exc_diff != NULL) + { + FOR(j = 0; j < nb_bands; j++) + { + Copy(exc_diff + shl(max_ener_band[j], 4), concat_in + shl(j, 4), 16); + } + } +#ifdef ADD_LRTD + } + else /* *bit == 0 */ + { + set_s(bits_per_bands_s, 0, nb_tot_bands); + *nb_subbands = 0; + *pvq_len = 0; + } +#endif + return; +} +#ifdef ADD_LRTD +/*-------------------------------------------------------------------* + * reajust_bits() + * + * + *-------------------------------------------------------------------*/ + +static void reajust_bits( + float* bits_per_bands, + const int16_t st_band, + const int16_t end_band, + const int16_t sum_bit_in, + const int16_t bit_bdgt_in) +{ + int16_t i, amount_to_add, incr; + int16_t bit_bdgt, sum_bit; + + incr = 1; + if (end_band < st_band) + { + incr = -1; + } + + if (bit_bdgt_in < sum_bit_in) + { + amount_to_add = -1; + bit_bdgt = sum_bit_in; + sum_bit = bit_bdgt_in; + } + else + { + bit_bdgt = bit_bdgt_in; + sum_bit = sum_bit_in; + amount_to_add = 1; + } + + i = st_band; + while (bit_bdgt > sum_bit) + { + if (amount_to_add > 0 || (amount_to_add < 0 && bits_per_bands[i] > 1)) + { + bits_per_bands[i] += amount_to_add; + sum_bit += (int16_t)abs(amount_to_add); + } + + i += incr; + if (i == end_band) + { + i = st_band; + } + } + + return; +} + +#endif \ No newline at end of file diff --git a/lib_com/gs_gains_fx.c b/lib_com/gs_gains_fx.c index 5898093c0e560ab4f20c88e2e6f9d00fab58b2d1..3fdcf4fe5e80fb9d8cb4d8c408744f755f362cc5 100644 --- a/lib_com/gs_gains_fx.c +++ b/lib_com/gs_gains_fx.c @@ -340,27 +340,27 @@ Word16 gsc_gaindec_fx( /* o : average frequency gain */ test(); IF( (EQ_16(coder_type_fx,AUDIO)||EQ_16(coder_type_fx,INACTIVE))&&EQ_16(bwidth_fx,NB)) { - idx_g_fx = (Word16) get_next_indice_fx( st_fx, 6 ); + idx_g_fx = (Word16) get_next_indice( st_fx, 6 ); VDQ_vec_fx(&mean_4g_fx, Gain_meanNB_fx, Gain_mean_dicNB_fx, idx_g_fx, 1 ); - idx_g_fx = (Word16) get_next_indice_fx( st_fx, 6 ); + idx_g_fx = (Word16) get_next_indice( st_fx, 6 ); move16(); VDQ_vec_fx(y_gainQ_fx, Mean_dic_NB_fx, Gain_dic1_NB_fx, idx_g_fx, 3 ); IF(LT_32(core_brate_fx,ACELP_9k60)) { - idx_g_fx = (Word16) get_next_indice_fx( st_fx, 5 ); + idx_g_fx = (Word16) get_next_indice( st_fx, 5 ); VDQ_vec_fx(y_gainQ_fx+3, Mean_dic_NB_fx+3, Gain_dic2_NB_fx, idx_g_fx, 3 ); - idx_g_fx = (Word16) get_next_indice_fx( st_fx, 4 ); + idx_g_fx = (Word16) get_next_indice( st_fx, 4 ); VDQ_vec_fx(y_gainQ_fx+6, Mean_dic_NB_fx+6, Gain_dic3_NB_fx, idx_g_fx, 4 ); } ELSE { - idx_g_fx = (Word16) get_next_indice_fx( st_fx, 6 ); + idx_g_fx = (Word16) get_next_indice( st_fx, 6 ); VDQ_vec_fx(y_gainQ_fx+3, Mean_dic_NB_fx+3, Gain_dic2_NBHR_fx, idx_g_fx, 3 ); - idx_g_fx = (Word16) get_next_indice_fx( st_fx, 7 ); + idx_g_fx = (Word16) get_next_indice( st_fx, 7 ); VDQ_vec_fx(y_gainQ_fx+6, Mean_dic_NB_fx+6, Gain_dic3_NBHR_fx, idx_g_fx, 4 ); } test(); @@ -388,7 +388,7 @@ Word16 gsc_gaindec_fx( /* o : average frequency gain */ } ELSE { - idx_g_fx = (Word16) get_next_indice_fx( st_fx, 6 ); + idx_g_fx = (Word16) get_next_indice( st_fx, 6 ); VDQ_vec_fx(&mean_4g_fx, mean_m_fx, mean_gain_dic_fx, idx_g_fx, 1 ); @@ -397,10 +397,10 @@ Word16 gsc_gaindec_fx( /* o : average frequency gain */ /*--------------------------------------------------------------------------------------* * UQ of the first 8 bands and half of the last 8 bands *--------------------------------------------------------------------------------------*/ - idx_g_fx = (Word16) get_next_indice_fx( st_fx, 5 ); + idx_g_fx = (Word16) get_next_indice( st_fx, 5 ); VDQ_vec_fx(y_gainQ_fx, YGain_mean_LR_fx, YGain_dic1_LR_fx, idx_g_fx, 3 ); - idx_g_fx = (Word16) get_next_indice_fx( st_fx, 5 ); + idx_g_fx = (Word16) get_next_indice( st_fx, 5 ); VDQ_vec_fx(y_gainQ_fx+3, YGain_mean_LR_fx+3, YGain_dic2_LR_fx, idx_g_fx, 4 ); /*----------------------------------------------------------------------* @@ -408,7 +408,7 @@ Word16 gsc_gaindec_fx( /* o : average frequency gain */ * And scaling *----------------------------------------------------------------------*/ - idx_g_fx = (Word16) get_next_indice_fx( st_fx, 5 ); + idx_g_fx = (Word16) get_next_indice( st_fx, 5 ); VDQ_vec_fx(y_gainQ_fx+7, YGain_mean_LR_fx+7, YGain_dic3_LR_fx, idx_g_fx, 5 ); @@ -441,16 +441,16 @@ Word16 gsc_gaindec_fx( /* o : average frequency gain */ } ELSE { - idx_g_fx = (Word16) get_next_indice_fx( st_fx, 6 ); + idx_g_fx = (Word16) get_next_indice( st_fx, 6 ); VDQ_vec_fx(y_gainQ_fx, YG_mean16_fx, YG_dicMR_1_fx, idx_g_fx, 4 ); - idx_g_fx = (Word16) get_next_indice_fx( st_fx, 5 ); + idx_g_fx = (Word16) get_next_indice( st_fx, 5 ); VDQ_vec_fx(y_gainQ_fx+4, YG_mean16_fx+4, YG_dicMR_2_fx, idx_g_fx, 4 ); - idx_g_fx = (Word16) get_next_indice_fx( st_fx, 5 ); + idx_g_fx = (Word16) get_next_indice( st_fx, 5 ); VDQ_vec_fx(y_gainQ_fx+8, YG_mean16_fx+8, YG_dicMR_3_fx, idx_g_fx, 4 ); - idx_g_fx = (Word16) get_next_indice_fx( st_fx, 4 ); + idx_g_fx = (Word16) get_next_indice( st_fx, 4 ); VDQ_vec_fx(y_gainQ_fx+12, YG_mean16_fx+12, YG_dicMR_4_fx, idx_g_fx, 4 ); } } diff --git a/lib_com/gs_inact_switching_fx.c b/lib_com/gs_inact_switching_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..2602902d75a8ceecd0f7d6d2c9dec009610f4a39 --- /dev/null +++ b/lib_com/gs_inact_switching_fx.c @@ -0,0 +1,154 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include "options.h" /* Compilation switches */ +#include "cnst.h" /* Common constants */ +#include "rom_com.h" /* Static table prototypes */ +#include "prot_fx1.h" /* Function prototypes */ +#include "prot_fx2.h" /* Function prototypes */ +#include "stl.h" + +/*-------------------------------------------------------------------* + * Local constants + *-------------------------------------------------------------------*/ + +#define ALPHA0_FX 13107 +#define BETA0_FX (32768-ALPHA0_FX) + +/*========================================================================*/ +/* FUNCTION : Inac_swtch_ematch_fx() */ +/*------------------------------------------------------------------------*/ +/* PURPOSE : Apply energy matching when swithcing to INACTIVE frame coded */ +/* by the GSC technology */ +/*------------------------------------------------------------------------*/ +/* INPUT ARGUMENTS : */ +/* _ (Word16) coder_type : Coding mode */ +/* _ (Word16) L_frame : Frame lenght */ +/* _ (Word32) core_brate : core bitrate */ +/*------------------------------------------------------------------------*/ +/* INPUT/OUTPUT ARGUMENTS : */ +/* _ (Word16[]) exc2 : CELP/GSC excitation buffer Q_exc */ +/* _ (Word16[]) lt_ener_per_band : Long term energy per band Q12 */ +/* _ (Word16*) Q_exc : input and output format of exc2 */ +/*------------------------------------------------------------------------*/ +/* OUTPUT ARGUMENTS : */ +/*------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------*/ +/* RETURN ARGUMENTS : */ +/* _ None */ +/*========================================================================*/ +void Inac_swtch_ematch_fx( + Word16 exc2[], /* i/o: CELP/GSC excitation buffer Q_exc*/ + Word16 dct_exc_tmp[], /* i : GSC excitation in DCT domain */ + Word16 lt_ener_per_band[], /* i/o: Long term energy per band Q12 */ + const Word16 coder_type, /* i : Coding mode */ + const Word16 L_frame, /* i : Frame lenght */ + const Word32 core_brate, /* i : Core bit rate */ + const Word16 Q_exc /* i : input and output format of exc2 */ + ,const Word16 bfi /* i : frame lost indicator */ + ,const Word16 last_core, /* i : Last core used */ + const Word16 last_codec_mode /* i : Last codec mode */ +) +{ + Word16 Ener_per_bd[MBANDS_GN]; + Word16 ftmp; + Word16 *pt_exc; + Word16 j, i; + + Word16 exp,frac; + Word32 L_tmp; + + /*-------------------------------------------------------------------------- + * average energy per band + *--------------------------------------------------------------------------*/ + + test(); + test(); + test(); + test(); + test(); + test(); + IF(EQ_16(coder_type,AUDIO)&&bfi==0) + { + Ener_per_band_comp_fx( dct_exc_tmp, Ener_per_bd, Q_exc, MBANDS_GN, 1); + + /* reset long-term energy per band */ + FOR(i = 0; i < MBANDS_GN; i++) + { + lt_ener_per_band[i] = Ener_per_bd[i]; + move16(); + } + + } + ELSE IF( EQ_16(coder_type,VOICED)||EQ_16(coder_type,GENERIC)||EQ_16(coder_type,TRANSITION)||NE_16(last_core,ACELP_CORE)||NE_16(last_codec_mode,MODE1)) + { + /* Find spectrum and energy per band for GC and VC frames */ + edct_16fx( exc2, dct_exc_tmp, L_frame, 5, EVS_MONO); + + Ener_per_band_comp_fx( dct_exc_tmp, Ener_per_bd, Q_exc, MBANDS_GN, 1); + + /* reset long-term energy per band */ + FOR(i = 0; i < MBANDS_GN; i++) + { + lt_ener_per_band[i] = Ener_per_bd[i]; + move16(); + } + } + ELSE IF( EQ_16(coder_type,INACTIVE)&&LE_32(core_brate,ACELP_24k40)) + { + /* Find spectrum and energy per band for inactive frames */ + edct_16fx( exc2, dct_exc_tmp, L_frame, 5, EVS_MONO); + Ener_per_band_comp_fx( dct_exc_tmp, Ener_per_bd, Q_exc, MBANDS_GN, 1 ); + + /* More agressive smoothing in the first 50 frames */ + pt_exc = dct_exc_tmp; + move16(); + FOR(i = 0; i < MBANDS_GN; i++) + { + /* Compute smoothing gain to apply with gain limitation */ + L_tmp = L_mult(ALPHA0_FX,lt_ener_per_band[i]); /*Q(15+12+1)=Q(28) */ + L_tmp = L_mac(L_tmp,BETA0_FX,Ener_per_bd[i]); /*Q28 */ + lt_ener_per_band[i] = round_fx(L_tmp); /*Q12 */ + + ftmp = sub(lt_ener_per_band[i],Ener_per_bd[i]); /*Q12 */ + + /* ftmp = (float)pow(10, ftmp);= pow(2,3.321928*ftmp);*/ + + L_tmp = L_mult(27213,ftmp); /*Q(13+12+1)=Q26 ; 27213=3.321928 in Q13 */ + L_tmp = L_shr(L_tmp, 10); /* From Q26 to Q16 */ + frac = L_Extract_lc(L_tmp, &exp); /* Extract exponent of ftmp */ + ftmp = extract_l(Pow2(14, frac));/* Put 14 as exponent so that */ + /* output of Pow2() will be: */ + /* 16384 < Pow2() <= 32767 */ + + exp = sub(exp,14); + IF( LT_16(i,2)) + { + FOR (j = 0; j < 8; j ++) + { + L_tmp = L_mult(*pt_exc,ftmp); /* Q_exc*Q0 -> Q(Q_exc+1) */ + L_tmp = L_shl(L_tmp, add(exp,15)); /* Q(Q_exc+1) -> Q(16+Q_exc)*/ + *pt_exc = round_fx(L_tmp); + pt_exc++; + } + } + ELSE + { + FOR (j = 0; j < 16; j ++) + { + L_tmp = L_mult(*pt_exc,ftmp); /* Q_exc*Q0 -> Q(Q_exc+1) */ + L_tmp = L_shl(L_tmp, add(exp,15)); /* Q(Q_exc+1) -> Q(16+Q_exc)*/ + *pt_exc = round_fx(L_tmp); /*Q_exc*/ + pt_exc++; + } + } + } + + /* Going back to time */ + edct_16fx( dct_exc_tmp, exc2, L_frame, 5 , EVS_MONO); + } + + return; +} diff --git a/lib_com/gs_noisefill.c b/lib_com/gs_noisefill.c index 97223b53585c5b8e676eaa5b7bfacfee00bd3556..320d92d7ad333bd3c2af205cd0c61a783c330509 100644 --- a/lib_com/gs_noisefill.c +++ b/lib_com/gs_noisefill.c @@ -41,8 +41,6 @@ #include "rom_com.h" #include "prot.h" #include "wmc_auto.h" -#include "prot_fx1.h" -#include "prot_fx2.h" /*-------------------------------------------------------------------* * gs_noisf() @@ -103,72 +101,6 @@ static void gs_noisf( return; } -static void gs_noisf_fx( - const Word16 Start_BIN, /* i : First bin for noise fill */ - const Word16 NB_Qbins, /* i : Number of bin per band */ - const Word16 Noise_fac, /* i : Noise level Q15 */ - const Word16 *y_norm, /* i : Quantized pulses Qn */ - Word16 *exc_diffQ, /* o : Quantized pulses with noise added Qn */ - Word16 *seed_tcx, /* i : Random generator seed */ - const Word16 coder_type, /* i : coder type */ - Word16 qNoise_fac -) -{ - Word32 ftmp; - Word16 i, k; - Word16 NB_zer; - Word32 const_1 = 1; - Word16 tmp; - - NB_zer = shr(NB_Qbins, 1); - - const_1 = L_shl(const_1, add(qNoise_fac, qNoise_fac)); - if (EQ_16(coder_type, INACTIVE)) - { - NB_zer = 2; - move16(); - } - - /*----------------------------------------------* - * noise fill-in on unquantized subvector * - * injected only from 1066Hz to 6400Hz. * - *----------------------------------------------*/ - - FOR(k = Start_BIN; k < NB_Qbins + Start_BIN; k += NB_zer) - { - ftmp = L_deposit_l(0); - FOR(i = k; i < k + NB_zer; i++) - { - exc_diffQ[i] = y_norm[i]; - move16(); - ftmp = L_mac0(ftmp, exc_diffQ[i], exc_diffQ[i]); - } - - IF(LT_32(L_shl(ftmp, 1), const_1)) - { - FOR(i = k; i < k + NB_zer; i++) - { - /*exc_diffQ[i] += Noise_fac*((float)own_random(seed_tcx)/32768.0f);*/ - tmp = mult(Noise_fac, Random(seed_tcx));/*Q15 */ - tmp = shr(tmp, sub(15, qNoise_fac));/*qNoise_fac */ - exc_diffQ[i] = add(exc_diffQ[i], tmp); - move16();/*Q */ - } - } - ELSE - { - /* This is added only to keep the seed in sync between different compilers */ - FOR(i = k; i < k + NB_zer; i++) - { - Random(seed_tcx); - } - } - - } - - return; -} - /*-------------------------------------------------------------------* * EstimateNoiseLevel_inner() * @@ -216,50 +148,6 @@ static void EstimateNoiseLevel_inner( return; } -static void EstimateNoiseLevel_inner_fx( - Word16 *noisepb, /* o : Noise per band Q15 */ - const long bitrate, /* i : Bitrate of the codec */ - const Word16 i_band, /* i : First band to compute the noise */ - const Word16 Mbands_gn /* i : number of bands */ -) -{ - Word16 i; - Word16 noise_offset; - - noise_offset = 8192; - move16(); - /*0.25f * 32768 */ - IF(bitrate > ACELP_24k40) - { - noise_offset = 6554; - move16(); /*.2f * 32768 */ - } - ELSE IF(bitrate >= ACELP_22k60) - { - noise_offset = 9830; - move16();/*.3f * 32768 */ - } - ELSE IF(bitrate >= ACELP_9k60) - { - noise_offset = 11469; - move16(); /*0.35f * 32768 */ - } - ELSE - { - noise_offset = 13107; - move16(); /*.4f * 32768 */ - } - - set16_fx(noisepb + i_band, noise_offset, sub(Mbands_gn, i_band)); - - FOR(i = i_band; i < 5; i++) - { - noisepb[i] = s_min(noisepb[i], 6554); - move16(); - } - - return; -} /*-------------------------------------------------------------------* * EstimateNoiseLevel() * @@ -348,95 +236,6 @@ static void EstimateNoiseLevel( return; } -static void EstimateNoiseLevel_fx( - Word16 *noisepb, /* o : Noise per band */ - const Word32 bitrate, /* i : Bitrate of the codec */ - const Word16 Diff_len, /* i : number of bin before cut-off frequency */ - const Word16 Mbands_gn, /* i : number of bands */ - const Word16 coder_type, /* i : coder type */ - const Word16 noise_lev, /* i : pulses dynamic */ - const Word16 pit_band_idx, /* i : bin position of the cut-off frequency */ - Word16 last_bin, /* i : the last bin of bit allocation */ - Word16 bwidth, - const int16_t L_frame /* i : frame length */ -) -{ - Word16 i_band; - - i_band = 0; - move16(); - - IF(LT_16(Diff_len, L_frame)) - { - EstimateNoiseLevel_inner_fx(noisepb, bitrate, i_band, MBANDS_GN); - IF(coder_type != INACTIVE) - { - test(); - test(); - IF((EQ_32(bitrate, ACELP_8k00) && GT_16(last_bin, 8)) && NE_16(bwidth, NB)) - { - FOR(; Mbands_gn > i_band; i_band++) - { - noisepb[i_band] = add(noisepb[i_band], noisepb[i_band]); - move16(); - } - } - ELSE - { - FOR(; pit_band_idx > i_band; i_band++) - { - noisepb[i_band] = mult_r(noisepb[i_band], 16384); - move16();/* 1/2=0.5 in Q15 */ - } - } - } - } - test(); - IF((EQ_16(coder_type, INACTIVE) || GE_16(noise_lev, NOISE_LEVEL_SP3)) && EQ_16(L_frame, L_FRAME)) - { - FOR(i_band = 9; i_band < Mbands_gn; i_band++) - { - noisepb[i_band] = add(noisepb[i_band], mult_r(noisepb[i_band], 4915)); - move16();/*noisepb[i_band]*1.15=noisepb[i_band] *(1 + 0.15) */ - } - } - ELSE IF(EQ_16(L_frame, L_FRAME16k)) - { - IF(EQ_32(bitrate, ACELP_13k20)) - { - set16_fx(noisepb, 14746/*0.45*/, Mbands_gn); - } - - IF(EQ_16(coder_type, INACTIVE)) - { - FOR(; i_band < Mbands_gn; i_band++) - { - noisepb[i_band] = 13107/*.4f*/; - move16(); - } - } - ELSE IF(LE_16(noise_lev, NOISE_LEVEL_SP1) && GT_32(bitrate, ACELP_16k40)) - { - FOR(; i_band < sub(Mbands_gn, 4); i_band++) - { - noisepb[i_band] = mult_r(noisepb[i_band], 19661)/*.6f*/; - move16(); - } - } - ELSE IF(LE_16(noise_lev, NOISE_LEVEL_SP2) && GT_32(bitrate, ACELP_16k40)) - { - FOR(; i_band < sub(Mbands_gn, 4); i_band++) - { - noisepb[i_band] = mult_r(noisepb[i_band], 26214)/*.8f*/; - move16(); - } - } - } - - - return; -} - /*-------------------------------------------------------------------* * Apply_NoiseFill() * @@ -471,40 +270,6 @@ static void Apply_NoiseFill( return; } -static void Apply_NoiseFill_fx( - Word16 *exc_diffQ, /* i/o: Noise per band qexc_diffQ */ - Word16 *seed_tcx, /* i : Seed for noise */ - const Word16 *noisepb, /* i : Noise per band Q15 */ - const Word16 Diff_len, /* i : number of bin before cut-off frequency */ - const Word16 Mbands_gn, /* i : number of bands */ - const Word16 coder_type, /* i : coder type */ - const Word16 *freq_nsbin_per_band, /* i : bin per bands tables */ - Word16 qexc_diffQ -) -{ - Word16 StartBin, NB_Qbins, i_band; - StartBin = 0; - move16(); - NB_Qbins = 0; - move16(); - - FOR(i_band = 0; i_band < Mbands_gn; i_band++) - { - StartBin += NB_Qbins; - move16(); - NB_Qbins = freq_nsbin_per_band[i_band]; - move16(); - - IF(LT_16(Diff_len, L_FRAME)) - { - gs_noisf_fx(StartBin, NB_Qbins, noisepb[i_band], exc_diffQ, exc_diffQ, seed_tcx, coder_type, qexc_diffQ); - } - } - - return; -} - - /*-------------------------------------------------------------------* * freq_dnw_scaling() * @@ -595,88 +360,6 @@ void freq_dnw_scaling( return; } -void freq_dnw_scaling_fx( - const Word16 cor_strong_limit, /* i : HF correlation */ - const Word16 coder_type, /* i : coder type */ - const Word16 noise_lev, /* i : Noise level */ - const Word32 core_brate, /* i : Core bitrate */ - Word16 fy_norm[], /* i/o: Frequency quantized parameter */ - Word16 Qx, /* Q format of fy_norm*/ - const int16_t L_frame /* i : frame length */ - -) -{ - Word16 sc_dyn; - Word16 start_sc, i; - - sc_dyn = 32767; - move16(); /*Q15 */ - start_sc = L_frame; - move16(); - test(); - IF(LE_32(core_brate, ACELP_8k00) && EQ_16(coder_type, INACTIVE)) - { - sc_dyn = mult_r(sc_dyn, 4915); /*Q15 (0.15 in Q15) */ - start_sc = 64; - move16(); - } - ELSE IF(EQ_16(coder_type, INACTIVE)) - { - sc_dyn = mult_r(sc_dyn, 8192); /*Q15 (0.25 in Q15) */ - start_sc = 80; - move16(); - } - ELSE - { - /*sc_dyn = (float)(NOISE_LEVEL_SP3 - noise_lev)/10.0f + 0.4f;*/ - sc_dyn = extract_l(L_mac(13107, sub(NOISE_LEVEL_SP3, noise_lev), 1638)); /*Q0*Q14x2+Q15 =Q15*/ - start_sc = add(112, shl(sub(NOISE_LEVEL_SP3, noise_lev), 4)); - if (EQ_16(noise_lev,NOISE_LEVEL_SP0)) - { - start_sc = L_FRAME; - move16(); - } - } - - IF(EQ_16(L_frame, L_FRAME16k) && LE_32(core_brate, ACELP_24k40)) - { - /*sc_dyn += 0.125f;*/ - sc_dyn = add(sc_dyn, 4096); /* Saturates to 1.0 */ - } - - FOR(i = start_sc; i < L_frame; i++) - { - fy_norm[i] = mult_r(fy_norm[i], sc_dyn); - move16();/*Qx */ - } - - test(); - test(); - IF((LT_32(core_brate, ACELP_13k20) && cor_strong_limit == 0) || LT_32(core_brate, ACELP_9k60)) - { - FOR(i = 160; i < L_frame; i++) - { - fy_norm[i] = s_min(fy_norm[i], shl(1, Qx)); - move16(); - fy_norm[i] = s_max(fy_norm[i], shl(-1, Qx)); - move16(); - } - } - ELSE IF(LT_32(core_brate, ACELP_22k60)) - { - FOR(i = 160; i < L_frame; i++) - { - fy_norm[i] = s_min(fy_norm[i], shr_r(1536, sub(10, Qx))); - move16(); - fy_norm[i] = s_max(fy_norm[i], shr_r(-1536, sub(10, Qx))); - move16(); - } - } - - return; - -} - /*-------------------------------------------------------------------* * Decreas_freqPeak() @@ -758,119 +441,6 @@ static void Decreas_freqPeak( return; } -static void Decreas_freqPeak_fx( - const Word16 *lsf_new, /* i : ISFs at the end of the frame */ - Word16 *exc_diffQ, /* i/o: frequency coefficients of per band */ - Word16 rat /* i : threshold of ratio between consecutive lsf_new_diff */ -) -{ - Word16 i, j, k; - Word16 last_bin = 0; - Word16 pos = 0; - Word16 *src, max_val, avrg; - Word32 L_avrg, L_tmp; - Word16 lsf_new_diff[M]; - Word16 tmp, tmp1, exp; - Word16 tmp2; -#ifdef BASOP_NOGLOB_DECLARE_LOCAL - Flag Overflow = 0; -#endif - move16(); /*ptr init*/ - lsf_new_diff[0] = 0; /* prevent unitialized value */ - FOR(j = 1; j < (M - 1); j++) - { - lsf_new_diff[j] = sub(lsf_new[j], lsf_new[j - 1]);/*Qx2.56 */ - } - - avrg = 0; - move16(); - L_avrg = L_deposit_l(0); - max_val = 1; - move16(); - FOR(i = 160; i < L_FRAME; i++) - { - IF(GT_16(abs_s(exc_diffQ[i]), max_val)) - { - max_val = abs_s(exc_diffQ[i]); - pos = i; - move16(); - } - L_avrg = L_add(L_avrg, abs_s(exc_diffQ[i])); - } - /* avrg /= 96; */ - L_avrg = Mult_32_16(L_avrg, 21845);/*Q_exc+21 -15 ->Q_exc + 6 */ - avrg = round_fx(L_shl(L_avrg, 10));/*Q_exc */ - last_bin = M - 1; - move16(); /* When the search is false, should equate the end of the vector, not the beginning */ - FOR(i = 0; i < (M - 1); i++) - { - if (GT_16(lsf_new[i], 10240)) - { - last_bin = i; - move16(); - BREAK; - } - } - - FOR(i = last_bin; i < 14; i++) - { - tmp = mult_r(rat, lsf_new_diff[i - 1]);/*Qx2.56 */ - IF(GT_16(tmp, lsf_new_diff[i])) - { - src = &exc_diffQ[shl(sub(i, 1), 4)]; - move16(); - FOR(j = 0; j < 2; j++) - { - FOR(k = 0; k < 16; k++) - { - tmp = mult_r(16384, abs_s(*src)); - IF(GT_16(tmp, avrg)) - { - tmp = abs_s(*src); - exp = norm_s(max_val); - tmp1 = div_s(shl(1, sub(14, exp)), max_val);/*Q(29 - exp - Q_exc) */ - L_tmp = L_mult(tmp, tmp1);/*Q(30 - exp) */ -#ifdef BASOP_NOGLOB - tmp = round_fx_o(L_shl_o(L_tmp, exp, &Overflow), &Overflow);/*Q14 */ -#else - tmp = round_fx(L_shl(L_tmp, exp));/*Q14 */ -#endif - tmp = sub(32767, tmp);/*Q14 */ - L_tmp = L_mult(avrg, tmp);/*Q_exc +15 */ - - tmp = round_fx(L_shl(L_tmp, 1)); - tmp1 = negate(tmp); - - tmp2 = *src; - *(src) = tmp1; - move16(); - if (tmp2 > 0) - { - *(src) = tmp; - move16(); - } - - } - src++; - } - } - } - } - - tmp = mult_r(8192, max_val);/*Q_exc */ - test(); - IF(EQ_16(abs_s(exc_diffQ[pos]), max_val) && GT_16(tmp, avrg)) - { - FOR(i = pos - 1; i < pos + 2; i++) - { - exc_diffQ[pos] = mult_r(16384, exc_diffQ[pos]); - move16(); - } - } - - return; -} - /*-------------------------------------------------------------------* * envelop_modify() @@ -922,146 +492,6 @@ static void envelop_modify( return; } -static void envelop_modify_fx( - Word16 *exc_diffQ_fx, /* i/o: frequency coefficients of per band */ - Word16 *seed_tcx, /* i : Seed for noise */ - Word16 last_bin, /* i : last bin of bit allocation */ - Word16 *Ener_per_bd_iQ_fx, /* i : Quantized energy of targeted vector */ - Word16 Q_exc, - Word16 *Q_hb_exc -) -{ - Word16 i, j, end_band; - Word16 start_band; - Word32 Ener_fx; - Word16 Ener1_fx; - Word16 tmp, tmp1; - Word32 L_tmp; - Word16 exp, exp1, frac; - Word16 *src_fx; - Word16 weight_fx; - Word32 L_exc_diffQ_fx[L_FRAME16k], exc_diffQ_max; - Word16 Q_tmp; -#ifdef BASOP_NOGLOB_DECLARE_LOCAL - Flag Overflow = 0; -#endif - - start_band = i_mult(last_bin, 16); - end_band = L_FRAME; - move16(); - Ener_fx = L_deposit_l(0); - FOR(i = start_band; i < end_band; i++) - { - L_tmp = L_mult0(exc_diffQ_fx[i], exc_diffQ_fx[i]); /*2*Q_exc */ - Ener_fx = L_add(Ener_fx, L_shr(L_tmp, 7)); /*2*Q_exc-7 */ - } - - tmp = sub(end_band, start_band); - tmp = div_s(1, tmp);/*Q15 */ - Ener_fx = Mult_32_16(Ener_fx, tmp); /*Q(2*Q_exc-7+15)->Q(2*Q_exc-7) */ - - exp1 = norm_l(Ener_fx); - Ener_fx = L_shl(Ener_fx, exp1); - exp1 = 31 - exp1 - sub(shl(Q_exc, 1), 7); - move16(); - Ener_fx = Isqrt_lc(Ener_fx, &exp1); /*Q(31-exp1) */ - - weight_fx = 16384; /*Q15 */ - src_fx = &exc_diffQ_fx[start_band]; /*Q_exc */ - FOR(i = last_bin; i < last_bin + 4; i++) - { - /*Ener1 = (float)(0.4f*pow(10, Ener_per_bd_iQ[i+1])); */ - L_tmp = L_shr(L_mult0(Ener_per_bd_iQ_fx[i + 1], 27213), 9); /* 3.321928 in Q13 -> Q16 */ - - frac = L_Extract_lc(L_tmp, &exp); /* Extract exponent of L_tmp */ - tmp = extract_l(Pow2(14, frac));/* Put 14 as exponent so that */ - /* output of Pow2() will be: */ - /* 16384 < Pow2() <= 32767 */ - exp = sub(exp, 14); -#ifdef BASOP_NOGLOB - Ener1_fx = mult_ro(13107, shl_o(tmp, exp, &Overflow), &Overflow); /*Q0 */ -#else /* BASOP_NOGLOB */ - Ener1_fx = mult_r(13107, shl(tmp, exp)); /*Q0 */ -#endif /* BASOP_NOGLOB */ - - FOR(j = 0; j < 16; j++) - { - /**src = Ener1*(weight*(*src)*Ener + (1.0f-weight)*own_random(seed_tcx)/32768.0f); */ - L_tmp = Mult_32_16(Ener_fx, *src_fx); /*Q(31-exp+Q_exc-15) -> Q(16-exp+Q_exc) */ - tmp = extract_l(L_shr(L_tmp, add(4, sub(Q_exc, exp1)))); /*Q12 */ - tmp = mult_r(weight_fx, tmp); /*Q12 */ - - L_tmp = L_mult0(sub(32767, weight_fx), Random(seed_tcx)); /*Q30 */ - tmp1 = round_fx(L_shr(L_tmp, 2)); - - L_exc_diffQ_fx[16 * i + j] = L_mult0(Ener1_fx, add(tmp, tmp1)); /*Q12 */ move32(); - src_fx++; - } - } - - /*Ener1 = (float)(0.4f*pow(10, Ener_per_bd_iQ[15])); */ - L_tmp = L_shr(L_mult0(Ener_per_bd_iQ_fx[15], 27213), 9); /* 3.321928 in Q13 -> Q16 */ - - frac = L_Extract_lc(L_tmp, &exp); /* Extract exponent of L_tmp */ - tmp = extract_l(Pow2(14, frac));/* Put 14 as exponent so that */ - /* output of Pow2() will be: */ - /* 16384 < Pow2() <= 32767 */ - exp = sub(exp, 14); -#ifdef BASOP_NOGLOB - Ener1_fx = mult_r(13107, shl_o(tmp, exp, &Overflow)); /*Q0 */ -#else /* BASOP_NOGLOB */ - Ener1_fx = mult_r(13107, shl(tmp, exp)); /*Q0 */ -#endif /* BASOP_NOGLOB */ - - src_fx = &exc_diffQ_fx[224]; - FOR(j = 0; j < 32; j++) - { - /**src = Ener1*(weight*(*src)*Ener + (1.0f-weight)*own_random(seed_tcx)/32768.0f); */ - L_tmp = Mult_32_16(Ener_fx, *src_fx); /*Q(31-exp+Q_exc-15) -> Q(16-exp+Q_exc) */ - tmp = extract_l(L_shr(L_tmp, add(4, sub(Q_exc, exp1)))); /*Q12 */ - tmp = mult_r(weight_fx, tmp); /*Q12 */ - - L_tmp = L_mult0(sub(32767, weight_fx), Random(seed_tcx)); /*Q30 */ - tmp1 = round_fx(L_shr(L_tmp, 2)); /*Q12 */ - - L_exc_diffQ_fx[16 * i + j] = L_mult0(Ener1_fx, add(tmp, tmp1)); /*Q12 */ move32(); - src_fx++; - } - - exc_diffQ_max = 0; - move16(); - FOR(i = start_band; i < L_FRAME; i++) - { - IF(GT_32(L_abs(L_exc_diffQ_fx[i]), exc_diffQ_max)) - { - exc_diffQ_max = L_abs(L_exc_diffQ_fx[i]); - } - } - exp = norm_l(exc_diffQ_max); - - IF(GT_16(exp, 16)) - { - *Q_hb_exc = 12; - move16(); - FOR(i = start_band; i < L_FRAME; i++) - { - exc_diffQ_fx[i] = extract_l(L_exc_diffQ_fx[i]); - } - } - ELSE - { - Q_tmp = sub(16, exp); - *Q_hb_exc = sub(12, Q_tmp); - FOR(i = start_band; i < L_FRAME; i++) - { - exc_diffQ_fx[i] = extract_l(L_shr(L_exc_diffQ_fx[i], Q_tmp)); - } - } - - return; -} - - /*-------------------------------------------------------------------* * highband_exc_dct_in() * @@ -1407,445 +837,3 @@ void highband_exc_dct_in( return; } - -void highband_exc_dct_in_fx( - const Word32 core_brate, /* i : core bitrate */ - const Word16 *mfreq_bindiv, /* i : bin per bands tables */ - Word16 last_bin, /* i : last bin of bit allocation */ - Word16 Diff_len, /* i : number of bin before cut-off frequency */ - Word16 noise_lev, /* i : pulses dynamic */ - Word16 pit_band_idx, /* i : bin position of the cut-off frequency */ - Word16 *exc_diffQ, /* i : frequency coefficients of per band */ - Word16 *seed_tcx, /* i : Seed for noise */ - Word16 *Ener_per_bd_iQ, /* i : Quantized energy of targeted vector */ - Word16 nb_subfr, /* i : Number of subframe considered */ - Word16 *exc_dct_in, /* o : dct of residual signal */ - Word16 last_coder_type, /* i : coding type of last frame */ - Word16 *bitallocation_band, /* i : bit allocation flag of each band */ - const Word16 *lsf_new, /* i : LSFs at the end of the frame */ - Word16 *last_exc_dct_in, /* i : dct of residual signal of last frame */ - Word16 *last_ener, /* i : frequency energy of last frame */ - Word16 *last_bitallocation_band, /* i : bit allocation flag of each band of last frame */ - Word16 *bitallocation_exc, /* i : flag of decoded coefficients */ - Word16 bfi, /* i : bad frame indicator */ - const Word16 coder_type, /* i : coder type */ - Word16 bwidth, - Word16 *exc_wo_nf, /* o : temporal excitation (in f domain) without noisefill */ - Word16 Qexc_diffQ, - Word16 Q_exc, - const Word16 GSC_noisy_speech - , Word16 *lt_ener_per_band_fx, /* i/o: Average per band energy */ - const int16_t L_frame, /* i : frame length */ - const int16_t element_mode, /* i : IVAS element mode */ - const int16_t GSC_IVAS_mode /* i : GSC IVAS mode */ -) -{ - Word16 i, j, k; - Word16 MAX_Bin = 0; - Word16 last_bin_tmp, ener = 0; - Word16 noisepb[MBANDS_GN16k]; - Word16 Ener_per_bd_yQ[MBANDS_GN16k]; - Word16 *src, *dst; - Word32 L_tmp; - Word16 length_bin, bwe_flag = 0, tmp; - Word16 frac, exp, tmp1; - Word16 tmp2; - Word16 *end, Q_hb_exc; -#ifdef BASOP_NOGLOB_DECLARE_LOCAL - Flag Overflow = 0; -#endif - - FOR(j = 10; j < MBANDS_GN; j++) - { - /* ener += (float)pow(10, Ener_per_bd_iQ[j]); - ener += (float)pow(2, 3.321928*Ener_per_bd_iQ[j]); */ - - L_tmp = L_mult(Ener_per_bd_iQ[j], 27213); /* 3.321928 in Q13 -> Q27 */ - L_tmp = L_shr(L_tmp, 10); /* From Q27 to Q16 */ - - frac = L_Extract_lc(L_tmp, &exp); /* Extract exponent of L_tmp */ - tmp = extract_l(Pow2(14, frac));/* Put 14 as exponent so that */ - /* output of Pow2() will be: */ - /* 16384 < Pow2() <= 32767 */ - exp = sub(exp, 14); -#ifdef BASOP_NOGLOB - tmp1 = shl_o(tmp, exp, &Overflow); -#else /* BASOP_NOGLOB */ - tmp1 = shl(tmp, exp); -#endif /* BASOP_NOGLOB */ - move16(); -#ifdef BASOP_NOGLOB - ener = add_o(tmp1, ener, &Overflow);/*Q0 */ -#else /* BASOP_NOGLOB */ - ener = add(tmp1, ener);/*Q0 */ -#endif /* BASOP_NOGLOB */ - } - - test(); - IF(EQ_32(core_brate, ACELP_8k00) && NE_16(bwidth, NB)) - { - if (NE_16(last_coder_type, AUDIO)) - { - *last_ener = ener; - move16(); - } - test(); - test(); - IF((GT_16(last_bin, 8) || Diff_len != 0) && EQ_16(last_coder_type, AUDIO)) - { - MAX_Bin = 10; - move16(); - bwe_flag = 1; - move16(); - } - ELSE - { - MAX_Bin = 15; - move16(); - } - - last_bin_tmp = last_bin; - move16(); - last_bin = s_max(last_bin, MAX_Bin); - last_bin = add(last_bin, 1); - } - ELSE - { - IF(EQ_16(L_frame, L_FRAME16k)) - { - last_bin = MBANDS_GN16k; - move16(); - } - ELSE - { - last_bin = MBANDS_GN; - move16(); - } - last_bin_tmp = last_bin; - move16(); - } - - IF(bfi || LT_32(core_brate, 6000) || (LT_32(core_brate, 8600) && EQ_16(coder_type, UNVOICED))) - { - set16_fx(noisepb, 13107, MBANDS_GN); /*0.4 in Q15 */ - } - ELSE IF(EQ_16(GSC_IVAS_mode, 3) || (GSC_IVAS_mode > 0 && EQ_16(GSC_noisy_speech, 1))) - { - set16_fx(noisepb, 13107/*0.4f*/, MBANDS_GN16k); - } - ELSE - { - EstimateNoiseLevel_fx(noisepb, core_brate, Diff_len, last_bin, coder_type, noise_lev, pit_band_idx, last_bin_tmp, bwidth, L_frame); - } - - IF(exc_wo_nf != NULL) - { - Copy(exc_diffQ, exc_wo_nf, L_frame); - } - - test(); - - IF(GSC_IVAS_mode == 0 && GSC_noisy_speech && !bfi && LE_16(element_mode, IVAS_SCE)) - { - set16_fx(noisepb, 3277, MBANDS_GN); - } - IF(LT_32(core_brate, 6000) && LE_16(coder_type, UNVOICED)) - { - FOR(i = 0; i < L_frame; i++) - { - IF(exc_diffQ[i] == 0) - { - //PMT("code below to be validated for IVAS use") - /* exc_diffQ[i] += 2.0f * noisepb[0] * ((float)own_random(seed_tcx) / PCM16_TO_FLT_FAC);*/ - tmp = mult(shl(noisepb[0], 1), Random(seed_tcx));/*Q15 */ - tmp = shr(tmp, sub(15, Qexc_diffQ));/*qNoise_fac */ - exc_diffQ[i] = add(exc_diffQ[i], tmp); - move16();/*Q */ - } - } - } - ELSE - { - Apply_NoiseFill_fx(exc_diffQ, seed_tcx, noisepb, Diff_len, last_bin, coder_type, mfreq_bindiv, Qexc_diffQ); - } - /*--------------------------------------------------------------------------------------* - * Quantize average gain - * Subtract Q averaged gain - * VQ of remaining gain per band - *--------------------------------------------------------------------------------------*/ - test(); - IF(EQ_32(core_brate, ACELP_8k00) && NE_16(bwidth, NB)) - { - Ener_per_band_comp_fx(exc_diffQ, Ener_per_bd_yQ, Qexc_diffQ, add(last_bin, 1), 0); - } - ELSE - { - Ener_per_band_comp_fx(exc_diffQ, Ener_per_bd_yQ, Qexc_diffQ, MBANDS_GN, 1); - - IF(LT_16(nb_subfr, 4) && LT_16(L_frame, L_FRAME16k)) - { - FOR(i = L_FRAME - 16; i < L_FRAME; i++) - { - /*exc_diffQ[i] *= 0.067f * i - 15.0f; = -15 - (-0.067f * i) */ - tmp = msu_r(-7680 * 65536, -17564, shl(i,6));/*-15 in Q9; -0.067 in Q18 and i in Q6= Q9 */ - L_tmp = L_mult(exc_diffQ[i],tmp); /*Q(Qexc_diffQ+10) */ - exc_diffQ[i] = round_fx(L_shl(L_tmp,16 - 10));/*Qexc_diffQ */ - } - } - } - /*--------------------------------------------------------------------------------------* - * Check potential energy excitation overshoot - *--------------------------------------------------------------------------------------*/ - IF(bfi) - { - test(); - IF(GSC_noisy_speech == 0 && GT_16(coder_type, UNVOICED)) /* Here coder_type == last_coder_type because of the bfi */ - { - FOR(i = 0; i < last_bin; i++) - { - Ener_per_bd_iQ[i] = s_min(Ener_per_bd_iQ[i], sub(sub(lt_ener_per_band_fx[i], 154), Ener_per_bd_yQ[i])); - move16(); - lt_ener_per_band_fx[i] = sub(lt_ener_per_band_fx[i], 77); - move16(); - } - FOR(; i < MBANDS_GN; i++) - { - Ener_per_bd_iQ[i] = s_min(Ener_per_bd_iQ[i], sub(lt_ener_per_band_fx[i], 154)); - move16(); - lt_ener_per_band_fx[i] = sub(lt_ener_per_band_fx[i], 77); - move16(); - } - } - ELSE - { - FOR(i = 0; i < last_bin; i++) - { - Ener_per_bd_iQ[i] = s_min(Ener_per_bd_iQ[i], sub(add(lt_ener_per_band_fx[i],1229), Ener_per_bd_yQ[i])); - move16(); - lt_ener_per_band_fx[i] = sub(lt_ener_per_band_fx[i], 77); - move16(); - } - FOR(; i < MBANDS_GN; i++) - { - Ener_per_bd_iQ[i] = s_min(Ener_per_bd_iQ[i], add(lt_ener_per_band_fx[i],1229)); - move16(); - lt_ener_per_band_fx[i] = sub(lt_ener_per_band_fx[i], 77); - move16(); - } - } - } - /*--------------------------------------------------------------------------------------* - * Apply decoded gain onto the difference signal - *--------------------------------------------------------------------------------------*/ -#ifdef ADD_LRTD - if (GSC_IVAS_mode >= 1) - { - float scale_factLF = 0.9f; - float scale_factHF = 0.9f; - - if (GSC_IVAS_mode == 1 && GSC_noisy_speech == 0) - { - scale_factHF = 0.8f; - } - else if (GSC_IVAS_mode == 2 || GSC_noisy_speech == 1) - { - scale_factHF = 0.71f; - } - else if (GSC_IVAS_mode == 3) - { - scale_factHF = 0.9f; - } - for (i = 0; i < pit_band_idx * 16; i++) - { - exc_diffQ[i] *= scale_factLF; - } - for (; i < L_frame; i++) - { - exc_diffQ[i] *= scale_factHF; - } - } - else if (GSC_noisy_speech) - { - float scale_fact = 0.9f; - - if (element_mode == IVAS_CPE_TD) - { - if (coder_type == INACTIVE) - { - scale_fact = 1.0f; - } - else - { - scale_fact = 0.95f; - } - } - else if (element_mode > IVAS_SCE) - { - scale_fact = 0.71f; - } - - for (i = 0; i < L_frame; i++) - { - exc_diffQ[i] *= scale_fact; - } - } - if (GSC_noisy_speech && element_mode > IVAS_SCE && core_brate < ACELP_7k20) - { - for (i = 80; i < L_frame; i++) - { - exc_diffQ[i] *= (+0.0024f * (float)i + 1.192f); - } - } -#else - IF(GSC_noisy_speech) - { - FOR(i = 0; i < L_frame; i++) - { - exc_diffQ[i] = mult_r(exc_diffQ[i], 29491); - move16(); - } - } -#endif - Comp_and_apply_gain_fx(exc_diffQ, Ener_per_bd_iQ, Ener_per_bd_yQ, last_bin, 0, Qexc_diffQ, Q_exc); - - IF(exc_wo_nf != NULL) - { - Comp_and_apply_gain_fx(exc_wo_nf, Ener_per_bd_iQ, Ener_per_bd_yQ, last_bin, 1, Qexc_diffQ, Q_exc); - Vr_add(exc_dct_in, exc_wo_nf, exc_wo_nf, L_frame); - } - /*--------------------------------------------------------------------------------------* - * add the correction layer to the LF bins, - * and add the quantized pulses or the noise for the higher part of the spectrum - * (non valuable temporal content already zeroed) - * DC is Zeroed - *--------------------------------------------------------------------------------------*/ - - Vr_add(exc_dct_in, exc_diffQ, exc_dct_in, L_frame); - test(); - IF(core_brate == ACELP_8k00 && bwidth != NB) - { - IF(EQ_16(bwe_flag, 1)) - { - last_bin = sub(last_bin, 1); - tmp = i_mult(MAX_Bin, 16); - tmp1 = i_mult(last_bin, 16); - src = &exc_diffQ[sub(L_FRAME, 1)]; - move16(); - dst = &exc_dct_in[sub(tmp, 1)]; - move16(); - end = &exc_diffQ[sub(tmp1, 1)]; - move16(); - - WHILE(src > end) - { - *src-- = *dst--; - move16(); - } - test(); - test(); - if ((bitallocation_exc[0] != 0 || bitallocation_exc[1] != 0) && EQ_32(core_brate, ACELP_8k00)) - { - exc_diffQ[160] = 0; - move16(); - } - - Q_hb_exc = 0; - move16(); - envelop_modify_fx(exc_diffQ, seed_tcx, last_bin, Ener_per_bd_iQ, Q_exc, &Q_hb_exc); - Copy_Scale_sig(&exc_diffQ[tmp1], &exc_dct_in[tmp1], sub(L_FRAME, tmp1), sub(Q_exc, Q_hb_exc)); /* from Q_hb_exc -> Q_exc as expected */ - } - - IF(LT_16(nb_subfr, 4)) - { - FOR(i = sub(L_FRAME, 16); i < L_FRAME; i++) - { - /*exc_dct_in[i] *= (0.067f*i-15.f); */ - tmp = mult_r(17564, shl(i, 6)); /*0.067 in Q18 and i in Q6= Q9 */ - tmp = sub(tmp, 7680); /*15 in Q9 = Q9 */ - L_tmp = L_mult(exc_dct_in[i], tmp);/*Q(Q_exc+10) */ -#ifdef BASOP_NOGLOB - exc_dct_in[i] = round_fx_o(L_shl_o(L_tmp, 6, &Overflow), &Overflow);/*Q_exc */ -#else /* BASOP_NOGLOB */ - exc_dct_in[i] = round_fx(L_shl(L_tmp, 6));/*Q_exc */ -#endif /* BASOP_NOGLOB */ - } - } - - tmp1 = mult_r(ener, 16384); - tmp1 = sub(*last_ener, tmp1); - tmp = mult_r(*last_ener, 16384); - tmp = sub(ener, tmp); - test(); - IF(tmp > 0 && tmp1 > 0) - { - length_bin = 6; - move16(); - IF(last_coder_type != AUDIO) - { - set16_fx(last_bitallocation_band, 0, 6); - Copy(&exc_dct_in[(4 + length_bin) * 16], &last_exc_dct_in[(4 + length_bin) * 16], length_bin * 16); - } - - FOR(i = 4; i < (4 + length_bin); i++) - { - test(); - IF(!(bitallocation_band[i] == 0 && last_bitallocation_band[i - 4] == 0)) - { - k = shl(add(i, length_bin), 4); - src = &exc_dct_in[k]; /*(i+length_bin)*16*/ - dst = &last_exc_dct_in[k]; - FOR(j = 0; j < 16; j++) - { - tmp = mult_r(10923, abs_s(*src)); - tmp1 = mult_r(10923, abs_s(*dst)); - - IF(GT_16(tmp, abs_s(*dst))) - { - tmp2 = *src; -#ifdef BASOP_NOGLOB - * src = mult_r(16384, sub_o(*src, abs_s(*dst), &Overflow)); /*Q_exc */ move16(); - tmp = mult_r(16384, add_o(tmp2, abs_s(*dst), &Overflow)); /*Q_exc */ -#else /* BASOP_NOGLOB */ - * src = mult_r(16384, sub(*src, abs_s(*dst))); /*Q_exc */ move16(); - tmp = mult_r(16384, add(tmp2, abs_s(*dst))); /*Q_exc */ -#endif - if (tmp2 > 0) - { - *src = tmp; - move16(); - } - } - ELSE IF(GT_16(tmp1, abs_s(*src))) - { - tmp = mult_r(*src, 22938); - tmp1 = mult_r(9830, abs_s(*dst)); - tmp2 = *src; - *src = sub(tmp, tmp1); /*Q_exc */ move16(); - if (tmp2 > 0) - { - *src = add(tmp, tmp1); /*Q_exc */ move16(); - } - } - src++; - dst++; - } - } - } - } - IF(EQ_16(bwe_flag, 1)) - { - Decreas_freqPeak_fx(lsf_new, exc_dct_in, 9830); - } - ELSE - { - Decreas_freqPeak_fx(lsf_new, exc_dct_in, 16384); - } - } - - Copy(&exc_dct_in[64], &last_exc_dct_in[64], L_frame - 64); - Copy(&bitallocation_band[4], last_bitallocation_band, 6); - *last_ener = ener; - move16(); - - return; -} diff --git a/lib_com/gs_noisefill_fx.c b/lib_com/gs_noisefill_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..cc8996e5c2c459a78388540e795f3bf5bce079d0 --- /dev/null +++ b/lib_com/gs_noisefill_fx.c @@ -0,0 +1,1094 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ +#include +#include "options.h" +#include "rom_com.h" +#include "prot_fx1.h" +#include "prot_fx2.h" + +/*-------------------------------------------------------------------* + * gs_noisf() + * + * Noise fill-in function + *-------------------------------------------------------------------*/ + +static void gs_noisf_fx( + const Word16 Start_BIN, /* i : First bin for noise fill */ + const Word16 NB_Qbins, /* i : Number of bin per band */ + const Word16 Noise_fac, /* i : Noise level Q15 */ + const Word16 *y_norm, /* i : Quantized pulses Qn */ + Word16 *exc_diffQ, /* o : Quantized pulses with noise added Qn */ + Word16 *seed_tcx, /* i : Random generator seed */ + const Word16 coder_type, /* i : coder type */ + Word16 qNoise_fac +) +{ + Word32 ftmp; + Word16 i, k; + Word16 NB_zer; + Word32 const_1=1; + Word16 tmp; + + NB_zer = shr(NB_Qbins,1); + + const_1 = L_shl(const_1, add(qNoise_fac, qNoise_fac)); + if( EQ_16(coder_type,INACTIVE)) + { + NB_zer = 2; + move16(); + } + + /*----------------------------------------------* + * noise fill-in on unquantized subvector * + * injected only from 1066Hz to 6400Hz. * + *----------------------------------------------*/ + + FOR( k=Start_BIN; k ACELP_24k40 ) + { + noise_offset = 6554; + move16(); /*.2f * 32768 */ + } + ELSE IF ( bitrate >= ACELP_22k60 ) + { + noise_offset = 9830; + move16();/*.3f * 32768 */ + } + ELSE IF ( bitrate >= ACELP_9k60 ) + { + noise_offset = 11469; + move16(); /*0.35f * 32768 */ + } + ELSE + { + noise_offset = 13107; + move16(); /*.4f * 32768 */ + } + + set16_fx( noisepb + i_band, noise_offset, sub(Mbands_gn, i_band) ); + + FOR( i = i_band; i < 5; i++ ) + { + noisepb[i] = s_min(noisepb[i], 6554); + move16(); + } + + return; +} +/*==========================================================================*/ +/* FUNCTION : void EstimateNoiseLevel_fx() */ +/*--------------------------------------------------------------------------*/ +/* PURPOSE : */ +/*--------------------------------------------------------------------------*/ +/* INPUT ARGUMENTS : */ +/* _ (Word32) bitrate : Bitrate of the codec Q0 */ +/* _ (Word16) Diff_len : number of bin before cut-off frequency */ +/* _ (Word16) Mbands_gn : number of bands Q0 */ +/* _ (Word16) coder_type : coder type Q0 */ +/* _ (Word16) noise_lev : pulses dynamic Q0 */ +/* _ (Word16) pit_band_idx : bin position of the cut-off frequency */ +/* _ (Word16*) freq_nsbin_per_band : bin per bands tables Q0 */ +/*--------------------------------------------------------------------------*/ +/* OUTPUT ARGUMENTS : */ +/* _ (Word16*) noisepb : Noise per band Q15 */ +/*--------------------------------------------------------------------------*/ +/* INPUT/OUTPUT ARGUMENTS : */ +/* None */ +/*--------------------------------------------------------------------------*/ +/* RETURN ARGUMENTS : */ +/* _ None */ +/*==========================================================================*/ +static void EstimateNoiseLevel_fx( + Word16 *noisepb, /* o : Noise per band */ + const Word32 bitrate, /* i : Bitrate of the codec */ + const Word16 Diff_len, /* i : number of bin before cut-off frequency */ + const Word16 Mbands_gn, /* i : number of bands */ + const Word16 coder_type, /* i : coder type */ + const Word16 noise_lev, /* i : pulses dynamic */ + const Word16 pit_band_idx, /* i : bin position of the cut-off frequency */ + Word16 last_bin, /* i : the last bin of bit allocation */ + Word16 bwidth, + const int16_t L_frame /* i : frame length */ +) +{ + Word16 i_band; + + i_band = 0; + move16(); + + IF( LT_16(Diff_len, L_frame)) + { + EstimateNoiseLevel_inner_fx(noisepb, bitrate, i_band, MBANDS_GN); + IF( coder_type != INACTIVE ) + { + test(); + test(); + IF( (EQ_32(bitrate,ACELP_8k00)&>_16(last_bin,8))&&NE_16(bwidth,NB)) + { + FOR( ; Mbands_gn > i_band; i_band++) + { + noisepb[i_band] = add(noisepb[i_band],noisepb[i_band]); + move16(); + } + } + ELSE + { + FOR( ; pit_band_idx > i_band; i_band++ ) + { + noisepb[i_band] = mult_r(noisepb[i_band], 16384); + move16();/* 1/2=0.5 in Q15 */ + } + } + } + } + test(); + IF ( (EQ_16(coder_type,INACTIVE)||GE_16(noise_lev,NOISE_LEVEL_SP3)) && EQ_16(L_frame, L_FRAME)) + { + FOR( i_band = 9; i_band < Mbands_gn; i_band++ ) + { + noisepb[i_band] = add(noisepb[i_band], mult_r(noisepb[i_band], 4915)); + move16();/*noisepb[i_band]*1.15=noisepb[i_band] *(1 + 0.15) */ + } + } + ELSE IF(EQ_16(L_frame, L_FRAME16k)) + { + IF (EQ_32(bitrate, ACELP_13k20)) + { + set16_fx(noisepb, 14746/*0.45*/, Mbands_gn); + } + + IF (EQ_16(coder_type, INACTIVE)) + { + FOR (; i_band < Mbands_gn; i_band++) + { + noisepb[i_band] = 13107/*.4f*/; + move16(); + } + } + ELSE IF (LE_16(noise_lev, NOISE_LEVEL_SP1) && GT_32(bitrate, ACELP_16k40)) + { + FOR (; i_band < sub(Mbands_gn, 4); i_band++) + { + noisepb[i_band] = mult_r(noisepb[i_band], 19661)/*.6f*/; + move16(); + } + } + ELSE IF (LE_16(noise_lev, NOISE_LEVEL_SP2) && GT_32(bitrate, ACELP_16k40)) + { + FOR (; i_band < sub(Mbands_gn, 4); i_band++) + { + noisepb[i_band] = mult_r(noisepb[i_band], 26214)/*.8f*/; + move16(); + } + } + } + + + return; +} + +/*============================================================================*/ +/* FUNCTION : void Appy_NoiseFill_fx() */ +/*----------------------------------------------------------------------------*/ +/* PURPOSE : */ +/*----------------------------------------------------------------------------*/ +/* INPUT ARGUMENTS : */ +/* _ (Word16*) seed_tcx : Seed for noise Q0 */ +/* _ (Word16*) noisepb : Noise per band Q15 */ +/* _ (Word16) Diff_len : number of bin before cut-off frequency Q0 */ +/* _ (Word16) Mbands_gn : number of bands Q0 */ +/* _ (Word16) coder_type : pulses dynamic Q0 */ +/* _ (Word16*) freq_nsbin_per_band: bin per bands tables Q0 */ +/* _ (Word16) qexc_diffQ : Q format of exc_diffQ */ +/*----------------------------------------------------------------------------*/ +/* OUTPUT ARGUMENTS : */ +/* _ (Word16*) exc_diffQ : Noise per band qexc_diffQ */ +/*----------------------------------------------------------------------------*/ +/* INPUT/OUTPUT ARGUMENTS : */ +/* None */ +/*----------------------------------------------------------------------------*/ +/* RETURN ARGUMENTS : */ +/* _ None */ +/*============================================================================*/ +static void Apply_NoiseFill_fx( + Word16 *exc_diffQ, /* i/o: Noise per band qexc_diffQ */ + Word16 *seed_tcx, /* i : Seed for noise */ + const Word16 *noisepb, /* i : Noise per band Q15 */ + const Word16 Diff_len, /* i : number of bin before cut-off frequency */ + const Word16 Mbands_gn, /* i : number of bands */ + const Word16 coder_type, /* i : coder type */ + const Word16 *freq_nsbin_per_band, /* i : bin per bands tables */ + Word16 qexc_diffQ +) +{ + Word16 StartBin, NB_Qbins, i_band; + StartBin = 0; + move16(); + NB_Qbins = 0; + move16(); + + FOR( i_band = 0; i_band < Mbands_gn; i_band++ ) + { + StartBin += NB_Qbins; + move16(); + NB_Qbins = freq_nsbin_per_band[i_band]; + move16(); + + IF( LT_16(Diff_len,L_FRAME)) + { + gs_noisf_fx( StartBin , NB_Qbins, noisepb[i_band], exc_diffQ, exc_diffQ, seed_tcx, coder_type, qexc_diffQ); + } + } + + return; +} +/*==========================================================================*/ +/* FUNCTION :void freq_dnw_scaling_fx () */ +/*--------------------------------------------------------------------------*/ +/* PURPOSE : */ +/*--------------------------------------------------------------------------*/ +/* INPUT ARGUMENTS : */ +/* _ (Word16) cor_strong_limit : HF correlation Q0 */ +/* _ (Word16) coder_type : coder type Q0 */ +/* _ (Word16) noise_lev : Noise level Q0 */ +/* _ (Word32) core_brate : Core bitrate Q0 */ +/* _ (Word16) Qx : Q format of fy_norm */ +/*--------------------------------------------------------------------------*/ +/* OUTPUT ARGUMENTS : */ +/* _ None */ +/*--------------------------------------------------------------------------*/ +/* INPUT/OUTPUT ARGUMENTS : */ +/* _ (Word16[]) fy_norm : Frequency quantized parameter Qx */ +/*--------------------------------------------------------------------------*/ +/* RETURN ARGUMENTS : */ +/* _None */ +/*==========================================================================*/ +void freq_dnw_scaling_fx( + const Word16 cor_strong_limit, /* i : HF correlation */ + const Word16 coder_type, /* i : coder type */ + const Word16 noise_lev, /* i : Noise level */ + const Word32 core_brate, /* i : Core bitrate */ + Word16 fy_norm[], /* i/o: Frequency quantized parameter */ + Word16 Qx, /* Q format of fy_norm*/ + const int16_t L_frame /* i : frame length */ + +) +{ + Word16 sc_dyn; + Word16 start_sc, i; + + sc_dyn = 32767; + move16(); /*Q15 */ + start_sc = L_frame; + move16(); + test(); + IF( LE_32(core_brate,ACELP_8k00)&&EQ_16(coder_type,INACTIVE)) + { + sc_dyn = mult_r(sc_dyn,4915); /*Q15 (0.15 in Q15) */ + start_sc = 64; + move16(); + } + ELSE IF ( EQ_16(coder_type,INACTIVE)) + { + sc_dyn = mult_r(sc_dyn,8192); /*Q15 (0.25 in Q15) */ + start_sc = 80; + move16(); + } + ELSE + { + /*sc_dyn = (float)(NOISE_LEVEL_SP3 - noise_lev)/10.0f + 0.4f;*/ + sc_dyn = extract_l(L_mac(13107, sub(NOISE_LEVEL_SP3, noise_lev), 1638)); /*Q0*Q14x2+Q15 =Q15*/ + start_sc = add(112, shl(sub(NOISE_LEVEL_SP3, noise_lev), 4)); + if( EQ_16(noise_lev,NOISE_LEVEL_SP0)) + { + start_sc = L_FRAME; + move16(); + } + } + + IF (EQ_16(L_frame, L_FRAME16k) && LE_32(core_brate, ACELP_24k40)) + { + /*sc_dyn += 0.125f;*/ + sc_dyn = add(sc_dyn, 4096); /* Saturates to 1.0 */ + } + + FOR(i = start_sc; i < L_frame; i++) + { + fy_norm[i] = mult_r(fy_norm[i],sc_dyn); + move16();/*Qx */ + } + + test(); + test(); + IF( (LT_32(core_brate,ACELP_13k20)&&cor_strong_limit==0)||LT_32(core_brate,ACELP_9k60)) + { + FOR(i = 160; i < L_frame; i++) + { + fy_norm[i] = s_min(fy_norm[i],shl(1,Qx)); + move16(); + fy_norm[i] = s_max(fy_norm[i],shl(-1,Qx)); + move16(); + } + } + ELSE IF ( LT_32(core_brate,ACELP_22k60)) + { + FOR(i = 160; i < L_frame; i++) + { + fy_norm[i] = s_min(fy_norm[i],shr_r(1536,sub(10,Qx))); + move16(); + fy_norm[i] = s_max(fy_norm[i],shr_r(-1536,sub(10,Qx))); + move16(); + } + } + + return; + +} + +static void Decreas_freqPeak_fx( + const Word16 *lsf_new, /* i : ISFs at the end of the frame */ + Word16 *exc_diffQ, /* i/o: frequency coefficients of per band */ + Word16 rat /* i : threshold of ratio between consecutive lsf_new_diff */ +) +{ + Word16 i, j, k; + Word16 last_bin = 0; + Word16 pos = 0; + Word16 *src, max_val,avrg; + Word32 L_avrg,L_tmp; + Word16 lsf_new_diff[M]; + Word16 tmp,tmp1,exp; + Word16 tmp2; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + move16(); /*ptr init*/ + lsf_new_diff[0] = 0; /* prevent unitialized value */ + FOR(j=1; j<(M-1); j++) + { + lsf_new_diff[j] =sub( lsf_new[j] , lsf_new[j-1]);/*Qx2.56 */ + } + + avrg = 0; + move16(); + L_avrg = L_deposit_l(0); + max_val = 1; + move16(); + FOR(i=160; iQ_exc + 6 */ + avrg = round_fx(L_shl(L_avrg,10));/*Q_exc */ + last_bin = M-1; + move16(); /* When the search is false, should equate the end of the vector, not the beginning */ + FOR(i=0; i<(M-1); i++) + { + if(GT_16(lsf_new[i],10240)) + { + last_bin = i; + move16(); + BREAK; + } + } + + FOR(i=last_bin; i<14; i++) + { + tmp = mult_r(rat,lsf_new_diff[i-1] );/*Qx2.56 */ + IF(GT_16(tmp , lsf_new_diff[i])) + { + src = &exc_diffQ[shl(sub(i,1),4)]; + move16(); + FOR(j=0; j<2; j++) + { + FOR(k=0; k<16; k++) + { + tmp = mult_r(16384,abs_s(*src)); + IF(GT_16(tmp,avrg)) + { + tmp = abs_s(*src) ; + exp = norm_s(max_val); + tmp1 = div_s(shl(1,sub(14,exp)),max_val);/*Q(29 - exp - Q_exc) */ + L_tmp = L_mult(tmp,tmp1);/*Q(30 - exp) */ +#ifdef BASOP_NOGLOB + tmp = round_fx_o(L_shl_o(L_tmp,exp, &Overflow), &Overflow);/*Q14 */ +#else + tmp = round_fx(L_shl(L_tmp,exp));/*Q14 */ +#endif + tmp = sub(32767,tmp);/*Q14 */ + L_tmp = L_mult(avrg,tmp);/*Q_exc +15 */ + + tmp = round_fx(L_shl(L_tmp,1)); + tmp1 = negate(tmp); + + tmp2 = *src; + *(src) = tmp1; + move16(); + if( tmp2 > 0 ) + { + *(src) = tmp; + move16(); + } + + } + src++; + } + } + } + } + + tmp = mult_r(8192,max_val);/*Q_exc */ + test(); + IF(EQ_16(abs_s(exc_diffQ[pos]),max_val)&>_16(tmp,avrg)) + { + FOR(i=pos-1; iQ(2*Q_exc-7) */ + + exp1 = norm_l(Ener_fx); + Ener_fx = L_shl(Ener_fx, exp1); + exp1 = 31-exp1-sub(shl(Q_exc,1),7); + move16(); + Ener_fx = Isqrt_lc(Ener_fx, &exp1); /*Q(31-exp1) */ + + weight_fx = 16384; /*Q15 */ + src_fx = &exc_diffQ_fx[start_band]; /*Q_exc */ + FOR(i=last_bin; i Q16 */ + + frac = L_Extract_lc(L_tmp, &exp); /* Extract exponent of L_tmp */ + tmp = extract_l(Pow2(14, frac));/* Put 14 as exponent so that */ + /* output of Pow2() will be: */ + /* 16384 < Pow2() <= 32767 */ + exp = sub(exp, 14); +#ifdef BASOP_NOGLOB + Ener1_fx = mult_ro(13107, shl_o(tmp, exp, &Overflow), &Overflow); /*Q0 */ +#else /* BASOP_NOGLOB */ + Ener1_fx = mult_r(13107, shl(tmp, exp)); /*Q0 */ +#endif /* BASOP_NOGLOB */ + + FOR(j=0; j<16; j++) + { + /**src = Ener1*(weight*(*src)*Ener + (1.0f-weight)*own_random(seed_tcx)/32768.0f); */ + L_tmp = Mult_32_16(Ener_fx, *src_fx); /*Q(31-exp+Q_exc-15) -> Q(16-exp+Q_exc) */ + tmp = extract_l(L_shr(L_tmp, add(4, sub(Q_exc, exp1)))); /*Q12 */ + tmp = mult_r(weight_fx, tmp); /*Q12 */ + + L_tmp = L_mult0(sub(32767, weight_fx), Random(seed_tcx)); /*Q30 */ + tmp1 = round_fx(L_shr(L_tmp, 2)); + + L_exc_diffQ_fx[16*i+j] = L_mult0(Ener1_fx, add(tmp, tmp1)); /*Q12 */ move32(); + src_fx++; + } + } + + /*Ener1 = (float)(0.4f*pow(10, Ener_per_bd_iQ[15])); */ + L_tmp = L_shr(L_mult0(Ener_per_bd_iQ_fx[15], 27213), 9); /* 3.321928 in Q13 -> Q16 */ + + frac = L_Extract_lc(L_tmp, &exp); /* Extract exponent of L_tmp */ + tmp = extract_l(Pow2(14, frac));/* Put 14 as exponent so that */ + /* output of Pow2() will be: */ + /* 16384 < Pow2() <= 32767 */ + exp = sub(exp, 14); +#ifdef BASOP_NOGLOB + Ener1_fx = mult_r(13107, shl_o(tmp, exp, &Overflow)); /*Q0 */ +#else /* BASOP_NOGLOB */ + Ener1_fx = mult_r(13107, shl(tmp, exp)); /*Q0 */ +#endif /* BASOP_NOGLOB */ + + src_fx = &exc_diffQ_fx[224]; + FOR(j=0; j<32; j++) + { + /**src = Ener1*(weight*(*src)*Ener + (1.0f-weight)*own_random(seed_tcx)/32768.0f); */ + L_tmp = Mult_32_16(Ener_fx, *src_fx); /*Q(31-exp+Q_exc-15) -> Q(16-exp+Q_exc) */ + tmp = extract_l(L_shr(L_tmp, add(4, sub(Q_exc, exp1)))); /*Q12 */ + tmp = mult_r(weight_fx, tmp); /*Q12 */ + + L_tmp = L_mult0(sub(32767, weight_fx), Random(seed_tcx)); /*Q30 */ + tmp1 = round_fx(L_shr(L_tmp, 2)); /*Q12 */ + + L_exc_diffQ_fx[16*i+j] = L_mult0(Ener1_fx, add(tmp, tmp1)); /*Q12 */ move32(); + src_fx++; + } + + exc_diffQ_max = 0; + move16(); + FOR(i=start_band; i Q27 */ + L_tmp = L_shr(L_tmp, 10); /* From Q27 to Q16 */ + + frac = L_Extract_lc(L_tmp, &exp); /* Extract exponent of L_tmp */ + tmp = extract_l(Pow2(14, frac));/* Put 14 as exponent so that */ + /* output of Pow2() will be: */ + /* 16384 < Pow2() <= 32767 */ + exp = sub(exp, 14); +#ifdef BASOP_NOGLOB + tmp1 = shl_o(tmp,exp, &Overflow); +#else /* BASOP_NOGLOB */ + tmp1 = shl(tmp,exp); +#endif /* BASOP_NOGLOB */ + move16(); +#ifdef BASOP_NOGLOB + ener = add_o (tmp1,ener, &Overflow);/*Q0 */ +#else /* BASOP_NOGLOB */ + ener = add (tmp1,ener);/*Q0 */ +#endif /* BASOP_NOGLOB */ + } + + test(); + IF( EQ_32(core_brate,ACELP_8k00)&&NE_16(bwidth,NB)) + { + if(NE_16(last_coder_type,AUDIO)) + { + *last_ener = ener; + move16(); + } + test(); + test(); + IF((GT_16(last_bin,8)||Diff_len!=0)&&EQ_16(last_coder_type,AUDIO)) + { + MAX_Bin = 10; + move16(); + bwe_flag = 1; + move16(); + } + ELSE + { + MAX_Bin = 15; + move16(); + } + + last_bin_tmp = last_bin; + move16(); + last_bin = s_max(last_bin , MAX_Bin); + last_bin = add(last_bin, 1); + } + ELSE + { + IF (EQ_16(L_frame, L_FRAME16k)) + { + last_bin = MBANDS_GN16k; + move16(); + } + ELSE + { + last_bin = MBANDS_GN; + move16(); + } + last_bin_tmp = last_bin; + move16(); + } + + IF( bfi || LT_32(core_brate, 6000) || (LT_32(core_brate, 8600) && EQ_16(coder_type, UNVOICED))) + { + set16_fx( noisepb, 13107, MBANDS_GN ); /*0.4 in Q15 */ + } + ELSE IF (EQ_16(GSC_IVAS_mode, 3) || (GSC_IVAS_mode > 0 && EQ_16(GSC_noisy_speech, 1))) + { + set16_fx(noisepb, 13107/*0.4f*/, MBANDS_GN16k); + } + ELSE + { + EstimateNoiseLevel_fx( noisepb, core_brate, Diff_len, last_bin, coder_type, noise_lev, pit_band_idx, last_bin_tmp, bwidth, L_frame ); + } + + IF( exc_wo_nf != NULL ) + { + Copy( exc_diffQ, exc_wo_nf, L_frame); + } + + test(); + + IF(GSC_IVAS_mode == 0 && GSC_noisy_speech && !bfi && LE_16(element_mode, IVAS_SCE)) + { + set16_fx( noisepb, 3277, MBANDS_GN ); + } + IF (LT_32(core_brate, 6000) && LE_16(coder_type, UNVOICED)) + { + FOR (i = 0; i < L_frame; i++) + { + IF (exc_diffQ[i] == 0) + { + //PMT("code below to be validated for IVAS use") + /* exc_diffQ[i] += 2.0f * noisepb[0] * ((float)own_random(seed_tcx) / PCM16_TO_FLT_FAC);*/ + tmp = mult(shl(noisepb[0],1), Random(seed_tcx));/*Q15 */ + tmp = shr(tmp, sub(15, Qexc_diffQ));/*qNoise_fac */ + exc_diffQ[i] = add(exc_diffQ[i], tmp); + move16();/*Q */ + } + } + } + ELSE + { + Apply_NoiseFill_fx(exc_diffQ, seed_tcx, noisepb, Diff_len, last_bin, coder_type, mfreq_bindiv, Qexc_diffQ); + } + /*--------------------------------------------------------------------------------------* + * Quantize average gain + * Subtract Q averaged gain + * VQ of remaining gain per band + *--------------------------------------------------------------------------------------*/ + test(); + IF( EQ_32(core_brate,ACELP_8k00)&&NE_16(bwidth,NB)) + { + Ener_per_band_comp_fx(exc_diffQ, Ener_per_bd_yQ, Qexc_diffQ, add(last_bin,1), 0); + } + ELSE + { + Ener_per_band_comp_fx(exc_diffQ, Ener_per_bd_yQ, Qexc_diffQ, MBANDS_GN, 1 ); + + IF( LT_16(nb_subfr, 4) && LT_16(L_frame, L_FRAME16k)) + { + FOR(i = L_FRAME-16; i < L_FRAME; i++) + { + /*exc_diffQ[i] *= 0.067f * i - 15.0f; = -15 - (-0.067f * i) */ + tmp = msu_r(-7680*65536, -17564, shl(i,6));/*-15 in Q9; -0.067 in Q18 and i in Q6= Q9 */ + L_tmp = L_mult(exc_diffQ[i],tmp); /*Q(Qexc_diffQ+10) */ + exc_diffQ[i] = round_fx(L_shl(L_tmp,16-10));/*Qexc_diffQ */ + } + } + } + /*--------------------------------------------------------------------------------------* + * Check potential energy excitation overshoot + *--------------------------------------------------------------------------------------*/ + IF( bfi ) + { + test(); + IF (GSC_noisy_speech == 0 && GT_16(coder_type,UNVOICED)) /* Here coder_type == last_coder_type because of the bfi */ + { + FOR( i=0; i= 1) + { + float scale_factLF = 0.9f; + float scale_factHF = 0.9f; + + if (GSC_IVAS_mode == 1 && GSC_noisy_speech == 0) + { + scale_factHF = 0.8f; + } + else if (GSC_IVAS_mode == 2 || GSC_noisy_speech == 1) + { + scale_factHF = 0.71f; + } + else if (GSC_IVAS_mode == 3) + { + scale_factHF = 0.9f; + } + for (i = 0; i < pit_band_idx * 16; i++) + { + exc_diffQ[i] *= scale_factLF; + } + for (; i < L_frame; i++) + { + exc_diffQ[i] *= scale_factHF; + } + } + else if (GSC_noisy_speech) + { + float scale_fact = 0.9f; + + if (element_mode == IVAS_CPE_TD) + { + if (coder_type == INACTIVE) + { + scale_fact = 1.0f; + } + else + { + scale_fact = 0.95f; + } + } + else if (element_mode > IVAS_SCE) + { + scale_fact = 0.71f; + } + + for (i = 0; i < L_frame; i++) + { + exc_diffQ[i] *= scale_fact; + } + } + if (GSC_noisy_speech && element_mode > IVAS_SCE && core_brate < ACELP_7k20) + { + for (i = 80; i < L_frame; i++) + { + exc_diffQ[i] *= (+0.0024f * (float)i + 1.192f); + } + } +#else + IF( GSC_noisy_speech ) + { + FOR( i= 0; i < L_frame; i++ ) + { + exc_diffQ[i] = mult_r(exc_diffQ[i], 29491); + move16(); + } + } +#endif + Comp_and_apply_gain_fx( exc_diffQ, Ener_per_bd_iQ, Ener_per_bd_yQ, last_bin, 0, Qexc_diffQ, Q_exc ); + + IF( exc_wo_nf != NULL ) + { + Comp_and_apply_gain_fx( exc_wo_nf, Ener_per_bd_iQ, Ener_per_bd_yQ, last_bin, 1 , Qexc_diffQ, Q_exc); + Vr_add( exc_dct_in, exc_wo_nf, exc_wo_nf, L_frame ); + } + /*--------------------------------------------------------------------------------------* + * add the correction layer to the LF bins, + * and add the quantized pulses or the noise for the higher part of the spectrum + * (non valuable temporal content already zeroed) + * DC is Zeroed + *--------------------------------------------------------------------------------------*/ + + Vr_add( exc_dct_in, exc_diffQ, exc_dct_in, L_frame ); + test(); + IF( core_brate == ACELP_8k00 && bwidth != NB ) + { + IF( EQ_16(bwe_flag,1)) + { + last_bin = sub(last_bin, 1); + tmp = i_mult(MAX_Bin, 16); + tmp1 = i_mult(last_bin, 16); + src = &exc_diffQ[sub(L_FRAME,1)]; + move16(); + dst = &exc_dct_in[sub(tmp,1)]; + move16(); + end = &exc_diffQ[sub(tmp1,1)]; + move16(); + + WHILE (src> end) + { + *src-- = *dst--; + move16(); + } + test(); + test(); + if( (bitallocation_exc[0] != 0 || bitallocation_exc[1] != 0) && EQ_32(core_brate, ACELP_8k00)) + { + exc_diffQ[160] = 0; + move16(); + } + + Q_hb_exc = 0; + move16(); + envelop_modify_fx( exc_diffQ, seed_tcx, last_bin, Ener_per_bd_iQ, Q_exc, &Q_hb_exc); + Copy_Scale_sig( &exc_diffQ[tmp1], &exc_dct_in[tmp1], sub(L_FRAME,tmp1), sub(Q_exc, Q_hb_exc)); /* from Q_hb_exc -> Q_exc as expected */ + } + + IF( LT_16(nb_subfr,4)) + { + FOR( i = sub(L_FRAME,16); i < L_FRAME; i++ ) + { + /*exc_dct_in[i] *= (0.067f*i-15.f); */ + tmp = mult_r(17564,shl(i,6)); /*0.067 in Q18 and i in Q6= Q9 */ + tmp = sub(tmp,7680); /*15 in Q9 = Q9 */ + L_tmp = L_mult(exc_dct_in[i],tmp);/*Q(Q_exc+10) */ +#ifdef BASOP_NOGLOB + exc_dct_in[i] = round_fx_o(L_shl_o(L_tmp,6, &Overflow), &Overflow);/*Q_exc */ +#else /* BASOP_NOGLOB */ + exc_dct_in[i] = round_fx(L_shl(L_tmp,6));/*Q_exc */ +#endif /* BASOP_NOGLOB */ + } + } + + tmp1 = mult_r(ener,16384); + tmp1 = sub(*last_ener,tmp1); + tmp = mult_r(*last_ener,16384); + tmp = sub(ener,tmp); + test(); + IF( tmp>0 && tmp1>0 ) + { + length_bin = 6; + move16(); + IF(last_coder_type != AUDIO) + { + set16_fx( last_bitallocation_band, 0, 6 ); + Copy( &exc_dct_in[(4+length_bin)*16], &last_exc_dct_in[(4+length_bin)*16], length_bin*16 ); + } + + FOR(i=4; i<(4+length_bin); i++) + { + test(); + IF( !(bitallocation_band[i] == 0 && last_bitallocation_band[i-4] == 0)) + { + k = shl(add(i,length_bin),4); + src = &exc_dct_in[k]; /*(i+length_bin)*16*/ + dst = &last_exc_dct_in[k]; + FOR(j=0; j<16; j++) + { + tmp= mult_r(10923,abs_s(*src)); + tmp1 =mult_r(10923,abs_s(*dst)); + + IF(GT_16(tmp,abs_s(*dst))) + { + tmp2 = *src; +#ifdef BASOP_NOGLOB + * src = mult_r(16384, sub_o(*src, abs_s(*dst), &Overflow)); /*Q_exc */ move16(); + tmp = mult_r(16384,add_o(tmp2 , abs_s(*dst), &Overflow)); /*Q_exc */ +#else /* BASOP_NOGLOB */ + * src = mult_r(16384, sub(*src, abs_s(*dst))); /*Q_exc */ move16(); + tmp = mult_r(16384,add(tmp2 , abs_s(*dst))); /*Q_exc */ +#endif + if( tmp2 > 0 ) + { + *src = tmp; + move16(); + } + } + ELSE IF (GT_16(tmp1,abs_s(*src))) + { + tmp = mult_r(*src,22938); + tmp1 = mult_r(9830,abs_s(*dst)); + tmp2 = *src; + *src = sub(tmp,tmp1); /*Q_exc */ move16(); + if( tmp2 > 0 ) + { + *src = add(tmp,tmp1); /*Q_exc */ move16(); + } + } + src++; + dst++; + } + } + } + } + IF(EQ_16(bwe_flag,1)) + { + Decreas_freqPeak_fx( lsf_new, exc_dct_in, 9830 ); + } + ELSE + { + Decreas_freqPeak_fx( lsf_new, exc_dct_in, 16384 ); + } + } + + Copy( &exc_dct_in[64], &last_exc_dct_in[64], L_frame-64 ); + Copy(&bitallocation_band[4], last_bitallocation_band, 6); + *last_ener = ener; + move16(); + + return; +} diff --git a/lib_com/guided_plc_util.c b/lib_com/guided_plc_util.c index e638d0131b5509f8ccc8d659b2535cc3024686e9..cdc4b853b7508b4d066bf8c5575203570de2e5e2 100644 --- a/lib_com/guided_plc_util.c +++ b/lib_com/guided_plc_util.c @@ -44,16 +44,16 @@ * Local function prototypes *-------------------------------------------------------------------*/ -static void reorder_lsfs( float *lsf, float min_dist, const int16_t n, const int32_t sr_core ); +static void reorder_lsfs_flt( float *lsf, float min_dist, const int16_t n, const int32_t sr_core ); /*-------------------------------------------------------------------* - * getLookAheadResSig() + * getLookAheadResSig_flt() * * *-------------------------------------------------------------------*/ -void getLookAheadResSig( +void getLookAheadResSig_flt( float *speechLookAhead, const float *A, float *res, @@ -80,12 +80,12 @@ void getLookAheadResSig( } /*-------------------------------------------------------------------* - * updatelsfForConcealment() + * updatelsfForConcealment_flt() * * *-------------------------------------------------------------------*/ -void updatelsfForConcealment( +void updatelsfForConcealment_flt( PLC_ENC_EVS_HANDLE decState, float *lsf ) { @@ -103,12 +103,12 @@ void updatelsfForConcealment( /*-------------------------------------------------------------------* - * getConcealedLP() + * getConcealedLP_flt() * * *-------------------------------------------------------------------*/ -void getConcealedLP( +void getConcealedLP_flt( PLC_ENC_EVS_HANDLE memDecState, float *AqCon, const float lsfBase[], @@ -120,7 +120,7 @@ void getConcealedLP( float lsp[( NB_DIV + 1 ) * M]; int16_t k; - dlpc_bfi( L_frame, &lsf[0], memDecState->lsfold, last_good, 1 /* assumes packet loss */, memDecState->mem_MA, memDecState->mem_AR_flt, &( memDecState->stab_fac ), memDecState->lsf_adaptive_mean, 1, NULL, 0, NULL, NULL, lsfBase ); + dlpc_bfi_flt( L_frame, &lsf[0], memDecState->lsfold, last_good, 1 /* assumes packet loss */, memDecState->mem_MA, memDecState->mem_AR_flt, &( memDecState->stab_fac ), memDecState->lsf_adaptive_mean, 1, NULL, 0, NULL, NULL, lsfBase ); mvr2r( memDecState->lspold, lsp, M ); @@ -135,12 +135,12 @@ void getConcealedLP( } /*-------------------------------------------------------------------* - * RecLpcSpecPowDiffuseLc() + * RecLpcSpecPowDiffuseLc_flt() * * *-------------------------------------------------------------------*/ -void RecLpcSpecPowDiffuseLc( +void RecLpcSpecPowDiffuseLc_flt( float *lspq, float *lsp_old, float *lsfq, @@ -151,11 +151,11 @@ void RecLpcSpecPowDiffuseLc( float lsf_old[M]; int16_t i; - means = PlcGetlsfBase( st->lpcQuantization, st->narrowBand, st->sr_core ); + means = PlcGetlsfBase_flt( st->lpcQuantization, st->narrowBand, st->sr_core ); mvr2r( st->lsf_old, lsf_old, M ); - modify_lsf( lsf_old, M, st->sr_core, reset_q ); + modify_lsf_flt( lsf_old, M, st->sr_core, reset_q ); lsf2lsp( lsf_old, lsp_old, M, st->sr_core ); @@ -168,13 +168,13 @@ void RecLpcSpecPowDiffuseLc( v_sort_float( lsfq, 0, M - 1 ); - reorder_lsfs( lsfq, LSF_GAP, M, st->sr_core ); + reorder_lsfs_flt( lsfq, LSF_GAP, M, st->sr_core ); lsf2lsp( lsfq, lspq, M, st->sr_core ); } else { - modify_lsf( lsfq, M, st->sr_core, reset_q ); + modify_lsf_flt( lsfq, M, st->sr_core, reset_q ); lsf2lsp( lsfq, lspq, M, st->sr_core ); } @@ -185,12 +185,12 @@ void RecLpcSpecPowDiffuseLc( /*-------------------------------------------------------------------* - * modify_lsf() + * modify_lsf_flt() * * *-------------------------------------------------------------------*/ -void modify_lsf( +void modify_lsf_flt( float *lsf, const int16_t n, const int32_t sr_core, @@ -231,12 +231,12 @@ void modify_lsf( /*-------------------------------------------------------------------* - * reorder_lsfs() + * reorder_lsfs_flt() * * *-------------------------------------------------------------------*/ -static void reorder_lsfs( +static void reorder_lsfs_flt( float *lsf, /* i/o: vector of lsfs in the frequency domain (0..0.5)*/ float min_dist, /* i : minimum required distance */ const int16_t n, /* i : LPC order */ diff --git a/lib_com/guided_plc_util_fx.c b/lib_com/guided_plc_util_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..11d5c7108ad9074ae89e692ac565fccaac737c1d --- /dev/null +++ b/lib_com/guided_plc_util_fx.c @@ -0,0 +1,367 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include +#include "options.h" +#include "prot_fx1.h" +#include "prot_fx2.h" +#include "rom_com.h" +#include "basop_util.h" +#include "rom_basop_util.h" + + /*-------------------------------------------------------------------* + * Local function prototypes + *-------------------------------------------------------------------*/ +static void reorder_lsfs(Word16* lsf, const Word16 min_dist, const Word16 n, const Word32 sr_core); + + +/*-------------------------------------------------------------------* + * getLookAheadResSig() + * + * + *-------------------------------------------------------------------*/ +void getLookAheadResSig( + Word16 *speechLookAhead, + Word16 *A_3Q12, + Word16 *res, + const Word16 L_frame, + const Word16 numSubFrame +) +{ + Word16 *p_A; + Word16 i_subfr; + Word16 subfr_len[2] = { L_SUBFR, L_SUBFR }; + + if( GT_16( L_FRAME16k, L_frame )) + { + subfr_len[1] = 48; + move16(); /* 0.75 * L_SUBFR(64) */ + } + + p_A = A_3Q12; + FOR(i_subfr=0; i_subfrlsfoldbfi1_14Q1[i] ); + L_tmp = L_mac( L_tmp, divide_by_3_Q15, decState->lsfoldbfi0_14Q1[i] ); + decState->lsf_adaptive_mean_14Q1[i] = mac_r( L_tmp, divide_by_3_Q15, lsf_14Q1[i] ); + decState->lsfoldbfi1_14Q1[i] = decState->lsfoldbfi0_14Q1[i]; + move16(); + decState->lsfoldbfi0_14Q1[i] = lsf_14Q1[i]; + move16(); + } + + return; +} +/*-------------------------------------------------------------------* + * getConcealedLP() + * + * + *-------------------------------------------------------------------*/ + +void getConcealedLP( + PLC_ENC_EVS_HANDLE memDecState, + Word16 *AqCon, + const Word16 lsfBase[], + const Word16 last_good, + const Word16 L_frame +) +{ + Word16 *lsf; + Word16 lsp[(NB_DIV+1)*M]; + Word32 int_fs; + + move16(); + lsf = memDecState->lsf_con; + + + dlpc_bfi( L_frame, &lsf[0], memDecState->lsfold_14Q1, last_good, + 1, memDecState->mem_MA_14Q1, memDecState->mem_AR, &(memDecState->stab_fac_Q15), memDecState->lsf_adaptive_mean_14Q1, + 1, NULL, 0, NULL, NULL, lsfBase, 0); + + Copy( memDecState->lspold_Q15, lsp, M ); + + int_fs = INT_FS_FX; + move32(); + if( EQ_16(L_frame,L_FRAME_16k)) + { + int_fs = INT_FS_16k_FX; + move32(); + } + lsf2lsp_fx( lsf, &lsp[M], M, int_fs ); + + int_lsp_fx( L_frame, &lsp[0], &lsp[M], AqCon, M, interpol_frac_fx, 0 ); + + return; +} +/*-------------------------------------------------------------------* + * getConcealedLSF() + * + * + *-------------------------------------------------------------------*/ +void getConcealedLSF( + PLC_ENC_EVS_HANDLE memDecState, + const Word16 lsfBase[], + const Word16 last_good, + const Word16 L_frame +) +{ + Word16 *lsf = memDecState->lsf_con; + + + dlpc_bfi( L_frame, &lsf[0], memDecState->lsfold_14Q1, last_good, + 1, memDecState->mem_MA_14Q1, memDecState->mem_AR, &(memDecState->stab_fac_Q15), memDecState->lsf_adaptive_mean_14Q1, + 1, NULL, 0, NULL, NULL, lsfBase, 0); + + return; +} + +/*-------------------------------------------------------------------* + * RecLpcSpecPowDiffuseLc() + * + * + *-------------------------------------------------------------------*/ + +void RecLpcSpecPowDiffuseLc( + Word16 *lspq, + Word16 *lsp_old, + Word16 *lsfq, + Decoder_State *st, + const Word16 reset_q +) +{ + const Word16 *means; + Word16 lsf_old[M]; + Word16 i; + + means = PlcGetLsfBase ( st->lpcQuantization, + st->narrowBand, + st->sr_core ); + + Copy( st->lsf_old_fx, lsf_old, M ); + + modify_lsf( lsf_old, M, st->sr_core, reset_q ); + + lsf2lsp_fx( lsf_old, lsp_old, M, st->sr_core ); + + IF( reset_q ) + { + FOR ( i=0; imem_MA_fx[i], means[i]); + move16(); + } + sort_fx( lsfq, 0, sub(M, 1) ); + + reorder_lsfs( lsfq, LSF_GAP_FX, M, st->sr_core ); + lsf2lsp_fx( lsfq, lspq, M, st->sr_core ); + } + ELSE + { + modify_lsf( lsfq, M, st->sr_core, reset_q ); + lsf2lsp_fx(lsfq, lspq, M, st->sr_core); + } + + return; +} +/*-------------------------------------------------------------------* + * modify_lsf() + * + * + *-------------------------------------------------------------------*/ +void modify_lsf( + Word16 *lsf, + const Word16 n, + const Word32 sr_core, + const Word16 reset_q +) +{ + Word16 i, k, th_x1p28_Q14; + Word16 gap, gap_sum; + + + th_x1p28_Q14 = 4864/*1900.0f*1.28f Q1*/; + move16(); + if( EQ_32( sr_core, INT_FS_16k)) + { + th_x1p28_Q14 = 6080/*2375.0f*1.28f Q1*/; + move16(); + } + + IF( reset_q == 0 ) + { + th_x1p28_Q14 = 2048; /* 800.0f*1.28f Q1*/ move16(); + if( EQ_32( sr_core, INT_FS_16k)) + { + th_x1p28_Q14 = 2560; /*1000.0f*1.28f Q1*/ move16(); + } + } + + FOR ( i=1; i= 0; i--) /* Reverify the minimum ISF gap in the reverse direction */ + { + IF (LE_16(lsf[i], th2)) + { + curr_min_dist = min_dist_fac2; + move16(); + } + ELSE + { + if (LE_16(lsf[i], th1)) + { + curr_min_dist = min_dist_fac3; + move16(); + } + } + + if (GT_16(lsf[i], lsf_max)) + { + lsf[i] = lsf_max; + move16(); + } + lsf_max = sub(lsf[i], curr_min_dist); + } + } + + return; +} + diff --git a/lib_com/hq_bit_allocation_fx.c b/lib_com/hq_bit_allocation_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..447ec250ef4da5d6541247369e5863956d38a6ae --- /dev/null +++ b/lib_com/hq_bit_allocation_fx.c @@ -0,0 +1,218 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include "options.h" /* Compilation switches */ +#include "stl.h" /* required for wmc_tool */ +#include "prot_fx1.h" /* Function prototypes */ +#include "prot_fx2.h" /* Function prototypes */ +#include "cnst.h" /* Common constants */ + +/*--------------------------------------------------------------------------* + * hq_bit_allocation_fx() + * + * Assign bits for HQ fine structure coding with PVQ + *--------------------------------------------------------------------------*/ + +void hq_bit_allocation_fx( + const Word32 core_brate, /* i : Core bit-rate Q0 */ + const Word16 length, /* i : Frame length Q0 */ + const Word16 hqswb_clas, /* i : HQ class Q0 */ + Word16 *num_bits, /* i/o: Remaining bit budget Q0 */ + const Word16 *normqlg2, /* i : Quantized norms Q0 */ + const Word16 nb_sfm, /* i : Number sub bands to be encoded Q0 */ + const Word16 *sfmsize, /* i : Sub band bandwidths Q0 */ + Word16 *noise_level, /* o : HVQ noise level */ + Word16 *R, /* o : Bit allocation per sub band Q0 */ + Word16 *Rsubband, /* o : Fractional bit allocation Q3 */ + Word16 *sum, /* o : Sum of allocated shape bits Q0 */ + Word16 *core_sfm, /* o : Last coded band in core Q0 */ + const Word16 num_env_bands /* i : Number sub bands to be encoded for HQ_GEN Q0 */ +) +{ + Word16 i; + Word16 idx[NB_SFM]; + Word16 wnorm[NB_SFM]; + Word16 avrg_wnorm; + Word16 tmp, tmp2; + Word16 E_low; + Word16 E_hb_mean; + Word16 E_max; + Word16 i_max; + /* Temp */ + + Word16 sfm_limit = nb_sfm; + move16(); + + set16_fx( R, 0, NB_SFM); + FOR( i = 0; i < nb_sfm; i++ ) + { + idx[i] = i; + move16(); + } + test(); + test(); + test(); + if( NE_16(hqswb_clas, HQ_TRANSIENT)&&NE_16(hqswb_clas,HQ_HVQ)&&!(EQ_16(length,L_FRAME16k)&&EQ_32(core_brate,HQ_32k))) + { + /* 'nf_idx' 2-bits index written later */ + *num_bits = sub(*num_bits, 2); + } + + test(); + IF ( EQ_16(hqswb_clas, HQ_GEN_SWB)||EQ_16(hqswb_clas,HQ_GEN_FB)) + { + IF ( EQ_32(core_brate, HQ_32k)) + { + *num_bits = sub(*num_bits, HQ_GENERIC_SWB_NBITS2 ); + } + ELSE + { + *num_bits = sub(*num_bits, HQ_GENERIC_SWB_NBITS ); + } + + if ( EQ_16(hqswb_clas, HQ_GEN_FB)) + { + *num_bits = sub(*num_bits, HQ_GENERIC_FB_NBITS ); + } + } + + IF( ( EQ_16(length, L_FRAME48k))&&(NE_16(hqswb_clas,HQ_HARMONIC))&&(NE_16(hqswb_clas,HQ_HVQ))) + { + tmp = 0; + move16(); + if( EQ_16(hqswb_clas,HQ_TRANSIENT)) + { + tmp = 1; + move16(); + } + map_quant_weight_fx( normqlg2, wnorm, tmp ); + } + ELSE + { + Copy( normqlg2, wnorm, nb_sfm ); + } + + IF( EQ_16(hqswb_clas, HQ_HARMONIC)) + { + /* classification and limit bandwidth for bit allocation */ + sfm_limit = sub(sfm_limit, 2); + limit_band_noise_level_calc_fx( wnorm, &sfm_limit, core_brate, noise_level ); + + /* Detect important band in high frequency region */ + E_low = sum16_fx(wnorm, SFM_G1); + i_max = 0; + move16(); + E_max = MIN16B; + move16(); + E_hb_mean = 0; + move16(); + FOR( i = SFM_G1; i < nb_sfm; i++) + { + E_hb_mean = add(E_hb_mean, wnorm[i]); + IF( GT_16(wnorm[i], E_max)) + { + E_max = wnorm[i]; + move16(); + i_max = i; + move16(); + } + } + E_hb_mean = shr(E_hb_mean, 4); /* Truncated division by SFM_G1 */ + set16_fx( wnorm + sfm_limit, -20, sub(nb_sfm, sfm_limit) ); + IF (L_msu0(L_deposit_l(E_low), E_max, 15) <= 0) + { + IF (L_msu(L_deposit_h(E_hb_mean), E_max, 21955) <= 0) /* 21955 = 0.67 (Q15) */ + { + if (GE_16(i_max, sfm_limit)) + { + wnorm[i_max] = E_max; + move16(); + } + } + } + } + test(); + test(); + test(); + test(); + IF( EQ_16(hqswb_clas, HQ_HVQ)) + { + *sum = 0; + move16(); + } + ELSE IF ( EQ_16(hqswb_clas, HQ_GEN_SWB)||(EQ_16(hqswb_clas,HQ_TRANSIENT)&&EQ_16(length,L_FRAME32k)&&LE_32(core_brate,HQ_32k))) + { + *sum = BitAllocF_fx( wnorm, core_brate, *num_bits, nb_sfm, R, Rsubband, hqswb_clas, num_env_bands ); + } + ELSE IF( EQ_16(length, L_FRAME16k)&&EQ_32(core_brate,HQ_32k)) + { + IF( NE_16(hqswb_clas, HQ_TRANSIENT)) + { + avrg_wnorm = wnorm[10]; + move16(); + FOR( i=11; i<18; i++ ) + { + avrg_wnorm = add(avrg_wnorm, wnorm[i]); + } + + avrg_wnorm = shr(avrg_wnorm, 3); + FOR( i=0; i<4; i++ ) + { + if( LT_16(wnorm[i], avrg_wnorm)) + { + wnorm[i] = avrg_wnorm; + move16(); + } + } + + /* Estimate number of bits per band */ + *sum = BitAllocWB_fx( wnorm, *num_bits, nb_sfm, R, Rsubband ); + } + ELSE + { + reordvct_fx(wnorm, nb_sfm, idx); + bitalloc_fx( wnorm, idx, *num_bits, nb_sfm, QBIT_MAX2, R, sfmsize, hqswb_clas ); + bitallocsum_fx( R, nb_sfm, sum, Rsubband, *num_bits, length, sfmsize ); + } + } + ELSE + { + reordvct_fx(wnorm, nb_sfm, idx); + + /* enlarge the wnorm value so that more bits can be allocated to (sfm_limit/2 ~ sfm_limit) range */ + IF( EQ_16(hqswb_clas, HQ_HARMONIC)) + { + tmp = shr(sfm_limit,1); + tmp2 = sub(tmp,1); + FOR( i=tmp; i +#include "options.h" +#include "cnst.h" /* Audio core constants */ +#include "rom_com.h" /* Static table prototypes */ +#include "prot_fx1.h" /* Function prototypes */ +#include "prot_fx2.h" /* Function prototypes */ + +/*--------------------------------------------------------------------------* + * hq_configure() + * + * Configuration routine for HQ mode + *--------------------------------------------------------------------------*/ + +void hq_configure_evs_fx( + const Word16 length, /* i : Frame length Q0 */ + const Word16 hqswb_clas, /* i : HQ SWB class Q0 */ + const Word32 core_brate, /* i : Codec bitrate Q0 */ + Word16 *num_sfm, /* o : Total number of subbands Q0 */ + Word16 *nb_sfm, /* o : Total number of coded bands Q0 */ + Word16 *start_norm, /* o : First norm to be SDE encoded Q0 */ + Word16 *num_env_bands, /* o : Number coded envelope bands Q0 */ + Word16 *numnrmibits, /* o : Number of bits in fall-back norm encoding Q0 */ + Word16 *hq_generic_offset, /* o : Freq offset for HQ GENERIC Q0 */ + Word16 *sfmsize, /* o : Subband bandwidths Q0 */ + Word16 *sfm_start, /* o : Subband start coefficients Q0 */ + Word16 *sfm_end /* o : Subband end coefficients Q0 */ +) +{ + const Word16* p_sfmsize; + const Word16* p_sfm_start; + const Word16* p_sfm_end; + Word16 i, bw_ext; + + bw_ext = 0; + + *start_norm = 0; + move16(); + +#ifndef SOLVED_COMP_ENC_DEC + IF(EQ_16(length, L_FRAME48k)) /*tbv SOLVED_COMP_ENC_DEC*/ +#else + IF ( EQ_16(length, L_SPEC48k)) +#endif + { + IF ( EQ_16(hqswb_clas, HQ_GEN_FB)) + { + *num_sfm = NB_SFM; + move16(); + p_sfmsize = band_len_HQ; + move16(); + p_sfm_start = band_start_HQ; + move16(); + p_sfm_end = band_end_HQ; + move16(); + + test(); + IF ( GE_32(core_brate, HQ_32k)) + { + *hq_generic_offset = HQ_GENERIC_FOFFSET_32K; + move16(); + *num_env_bands = SFM_N_STA_10k; + move16(); + } + ELSE /*IF(EQ_32(core_brate, HQ_16k40) || EQ_32(core_brate, HQ_24k40))*/ + { + *hq_generic_offset = HQ_GENERIC_FOFFSET_24K4; + *num_env_bands = SFM_N_STA_8k; + move16(); + move16(); + } + *nb_sfm = *num_sfm; + move16(); + } + ELSE + { + IF(EQ_16(hqswb_clas, HQ_HARMONIC)) + { + *num_sfm = SFM_N_HARM_FB; + move16(); + *nb_sfm = SFM_N_HARM_FB; + move16(); + *num_env_bands = SFM_N_HARM_FB; + move16(); + + p_sfmsize = band_len_harm; + move16(); + p_sfm_start = band_start_harm; + move16(); + p_sfm_end = band_end_harm; + move16(); + } + ELSE IF ( EQ_16(hqswb_clas, HQ_HVQ)) + { + IF ( LT_32(core_brate, HQ_BWE_CROSSOVER_BRATE)) + { + *num_sfm = SFM_N_HARM_FB; + move16(); + *nb_sfm = HVQ_THRES_SFM_24k; + move16(); + *num_env_bands = sub(*num_sfm, *nb_sfm); + move16(); + *start_norm = HVQ_THRES_SFM_24k; + move16(); + } + ELSE + { + *num_sfm = SFM_N_HARM_FB; + move16(); + *nb_sfm = HVQ_THRES_SFM_32k; + move16(); + *num_env_bands = sub(*num_sfm, *nb_sfm); + move16(); + *start_norm = HVQ_THRES_SFM_32k; + move16(); + } + p_sfmsize = band_len_harm; + p_sfm_start = band_start_harm; + p_sfm_end = band_end_harm; + move16();move16();move16(); + } + ELSE + { + *num_sfm = NB_SFM; + move16(); + *nb_sfm = *num_sfm; + move16(); + *num_env_bands = NB_SFM; + move16(); + + p_sfmsize = band_len_HQ; + move16(); + p_sfm_start = band_start_HQ; + move16(); + p_sfm_end = band_end_HQ; + move16(); + } + } + } + ELSE IF( EQ_16(length, L_SPEC32k)) + { + IF ( EQ_16(hqswb_clas, HQ_HARMONIC)) + { + *num_sfm = SFM_N_HARM; + move16(); + *nb_sfm = SFM_N_HARM; + move16(); + *num_env_bands = SFM_N_HARM; + move16(); + + p_sfmsize = band_len_harm; + move16(); + p_sfm_start = band_start_harm; + move16(); + p_sfm_end = band_end_harm; + move16(); + } + ELSE IF ( EQ_16(hqswb_clas, HQ_HVQ)) + { + IF ( LT_32(core_brate, HQ_BWE_CROSSOVER_BRATE)) + { + *num_sfm = SFM_N_HARM; + move16(); + *nb_sfm = HVQ_THRES_SFM_24k; + move16(); + *num_env_bands = sub(*num_sfm, *nb_sfm); + + *start_norm = HVQ_THRES_SFM_24k; + move16(); + } + ELSE + { + *num_sfm = SFM_N_HARM; + move16(); + *nb_sfm = HVQ_THRES_SFM_32k; + move16(); + *num_env_bands = sub(*num_sfm, *nb_sfm); + + *start_norm = HVQ_THRES_SFM_32k; + move16(); + } + p_sfmsize = band_len_harm; + move16(); + p_sfm_start = band_start_harm; + move16(); + p_sfm_end = band_end_harm; + move16(); + + } + ELSE IF ( EQ_16(hqswb_clas, HQ_GEN_SWB)) + { + *num_sfm = SFM_N_SWB; + move16(); + p_sfmsize = band_len_HQ; + move16(); + p_sfm_start = band_start_HQ; + move16(); + p_sfm_end = band_end_HQ; + move16(); + + IF ( GE_32(core_brate, HQ_32k)) + { + *hq_generic_offset = HQ_GENERIC_FOFFSET_32K; + move16(); + *num_env_bands = SFM_N_STA_10k; + move16(); + } + ELSE /*if( EQ_32(core_brate, HQ_24k40))*/ + { + *hq_generic_offset = HQ_GENERIC_FOFFSET_24K4; + move16(); + *num_env_bands = SFM_N_STA_8k; + move16(); + } + + *nb_sfm = *num_sfm; + move16(); + } + ELSE + { + /* HQ_NORMAL and HQ_TRANSIENT */ + *num_sfm = SFM_N_SWB; + move16(); + *nb_sfm = *num_sfm; + move16(); + *num_env_bands = SFM_N_SWB; + move16(); + + p_sfmsize = band_len_HQ; + move16(); + p_sfm_start = band_start_HQ; + move16(); + p_sfm_end = band_end_HQ; + move16(); + } + } + ELSE IF (EQ_16(length, L_SPEC48k_EXT ) ) + { + bw_ext = 1; + p_sfmsize = band_len_HQ; + p_sfm_start = band_start_HQ; + p_sfm_end = band_end_HQ; + *num_sfm = NB_SFM; + move16(); move16(); move16(); move16(); + } + ELSE IF (EQ_16(length, L_SPEC16k_EXT)) + { + bw_ext = 1; + p_sfmsize = band_len_wb; + p_sfm_start = band_start_wb; + p_sfm_end = band_end_wb; + *num_sfm = SFM_N_WB; + move16();move16();move16();move16(); + } + ELSE + { + *num_sfm = SFM_N_WB; + move16(); + *nb_sfm = *num_sfm; + move16(); + *num_env_bands = SFM_N_WB; + move16(); + + p_sfmsize = band_len_wb; + move16(); + p_sfm_start = band_start_wb; + move16(); + p_sfm_end = band_end_wb; + move16(); + } + IF (bw_ext) + { + FOR (i = 0; i < *num_sfm; i++) + { + /*sfmsize[i] = (int16_t)(1.25f * p_sfmsize[i]);*/ + sfmsize[i] = mult_r(shl(p_sfmsize[i],1),20480); + /*sfm_start[i] = (int16_t)(1.25f * p_sfm_start[i]);*/ + sfm_start[i] = mult_r(shl(p_sfm_start[i], 1), 20480); + /*sfm_end[i] = (int16_t)(1.25f * p_sfm_end[i]);*/ + sfm_end[i] = mult_r(shl(p_sfm_end[i], 1), 20480); + } + *nb_sfm = *num_sfm; + *num_env_bands = *num_sfm; + move16();move16(); + } + else + { + Copy(p_sfmsize, sfmsize, *num_sfm); + Copy(p_sfm_start, sfm_start, *num_sfm); + Copy(p_sfm_end, sfm_end, *num_sfm); + } + + *numnrmibits = extract_l(L_mult0(sub(*num_env_bands, 1), NORMI_BITS)); + + return; +} diff --git a/lib_com/hq_tools_fx.c b/lib_com/hq_tools_fx.c index fe8902a9a1c3e15fbe24129144392e49d2d0abea..f4154c3ed560f152e7ef70c8d10cd71f8401bf64 100644 --- a/lib_com/hq_tools_fx.c +++ b/lib_com/hq_tools_fx.c @@ -1682,7 +1682,7 @@ Word16 get_nor_delta_hf_fx( move16(); IF(GE_16(core_sfm, num_env_bands)) { - bitsforDelta = (Word16)get_next_indice_fx(st, 2); + bitsforDelta = (Word16)get_next_indice(st, 2); bitsforDelta = add(bitsforDelta, 2); add_bits_denv = add(add_bits_denv, 2); @@ -1690,7 +1690,7 @@ Word16 get_nor_delta_hf_fx( { IF(Rsubband[i] != 0) { - delta = (Word16)get_next_indice_fx(st, bitsforDelta); + delta = (Word16)get_next_indice(st, bitsforDelta); ynrm[i] = add(ynrm[i], sub(delta, (shl(1, sub(bitsforDelta, 1))))); move16(); diff --git a/lib_com/hvq_pvq_bitalloc_fx.c b/lib_com/hvq_pvq_bitalloc_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..47cd6eba24b5367e1dfd98b8cd1cbdde9586665e --- /dev/null +++ b/lib_com/hvq_pvq_bitalloc_fx.c @@ -0,0 +1,190 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ +#include +#include "options.h" /* Compilation switches */ +#include "rom_com.h" + +#include "prot_fx1.h" /* Function prototypes */ +#include "prot_fx2.h" /* Function prototypes */ +#include "cnst.h" /* Common constants */ + +/*--------------------------------------------------------------------------*/ +/* Function hvq_pvq_bitalloc */ +/* ~~~~~~~~~~~~~~~~~~~~~~~~ */ +/* */ +/* Calculate the number of PVQ bands to code and allocate bits based on */ +/* the number of available bits. */ +/*--------------------------------------------------------------------------*/ + +Word16 hvq_pvq_bitalloc_fx( + Word16 num_bits, /* i/o: Number of available bits (including gain bits) */ + const Word32 core_brate, /* i : core bitrate */ + const Word16 bwidth_fx, /* i : Encoded bandwidth */ + const Word16 *ynrm, /* i : Envelope coefficients */ + const Word32 manE_peak, /* i : Peak energy mantissa */ + const Word16 expE_peak, /* i : Peak energy exponent */ + Word16 *Rk, /* o : bit allocation for concatenated vector */ + Word16 *R, /* i/o: Global bit allocation */ + Word16 *sel_bands, /* o : Selected bands for encoding */ + Word16 *n_sel_bands /* o : No. of selected bands for encoding */ +) +{ + Word16 num_bands, band_max_bits; + Word16 one_over_band_max_bits; + Word16 k; + Word16 reciprocal, envSum, expo, align, m, n, indx; + Word16 k_max; + Word16 k_start; + Word32 E_max, E_max5; + Word32 tmp, acc; + Word32 env_mean; + UWord16 lsb; + Word16 num_sfm; + + IF (EQ_16(bwidth_fx, FB)) + { + num_sfm = SFM_N_HARM_FB; + } + ELSE + { + num_sfm = SFM_N_HARM; + } + + IF ( LT_32(core_brate, HQ_BWE_CROSSOVER_BRATE)) + { + band_max_bits = HVQ_BAND_MAX_BITS_24k; + move16(); + one_over_band_max_bits = ONE_OVER_HVQ_BAND_MAX_BITS_24k_FX; + move16(); + k_start = HVQ_THRES_SFM_24k; + move16(); + IF (EQ_16(bwidth_fx, FB)) + { + reciprocal = 2731; /* Q15, 1/(SFM_N_HARM_FB + 1 - k_start) */ move16(); + } + ELSE + { + reciprocal = 3277; /* Q15, 1/(SFM_N_HARM + 1 - k_start) */ move16(); + } + } + ELSE + { + band_max_bits = HVQ_BAND_MAX_BITS_32k; + move16(); + one_over_band_max_bits = ONE_OVER_HVQ_BAND_MAX_BITS_32k_FX; + move16(); + k_start = HVQ_THRES_SFM_32k; + move16(); + IF (EQ_16(bwidth_fx, FB)) + { + reciprocal = 3641; /* Q15, 1/(SFM_N_HARM_FB + 1 - k_start) */ move16(); + } + ELSE + { + reciprocal = 4681; /* Q15, 1/(SFM_N_HARM + 1 - k_start) */ move16(); + } + } + + num_bands = mult( num_bits, one_over_band_max_bits ); /* Q0 */ + num_bits = sub( num_bits, i_mult(num_bands, band_max_bits) ); /* Q0 */ + + IF ( GE_16(num_bits, HVQ_NEW_BAND_BIT_THR)) + { + num_bands = add(num_bands, 1); + } + ELSE + { + num_bits = add(num_bits, band_max_bits); + } + + /* safety check in case of bit errors */ + if (LT_16(num_bands, 1)) + { + return 0; + } + + *n_sel_bands = 0; + move16(); + envSum = 0; + move16(); + E_max = L_deposit_l(0); + k_max = k_start; + move16(); + FOR ( k = k_start; k < num_sfm; k++ ) + { + indx = ynrm[k]; + move16(); + tmp = dicn_fx[indx]; /* Q14 */ + move32(); + envSum = add(envSum, indx); /* Since the size of dicn_fx = 40, ynrm[k] must be less than 41. 16 bits are enough for envSum.*/ + IF (GT_32(tmp, E_max)) + { + E_max = tmp; + move32(); + k_max = k; + move16(); + } + } + env_mean = L_mult(envSum, reciprocal); /* env_mean in Q16 */ + IF (GT_32(L_sub(env_mean, L_deposit_h(ynrm[k_max])), 0x30000L)) /* condition: env_mean - ynrm[k_max] > 3 */ + { + expo = norm_l(E_max); + E_max = L_shl(E_max, expo); + Mpy_32_16_ss(E_max, 0x7a12, &E_max5, &lsb); /* NB: 5.0e5 = 0x7a12(Q15) x 2^19. */ + /* True floating point value of E_max*5e5 = E_max5 x 2^(19 - expo - 14). + * In this context, the 32-bit E_max5 is in Q0, and + * -14 is due to Emax in Q14. + * True floating point value of E_peak = manE_peak x 2^(31 - expE_peak - 2*12). See peak_vq_enc_fx(). + */ + + /* Align the Q-points of the floating point Emax*5e5 and E_peak. */ + align = sub(expo, expE_peak); + align = add(align, (19 - 14) - (31 - 2*12)); + IF (align < 0) + { + acc = L_sub(E_max5, L_shl(manE_peak, align)); + } + ELSE + { + acc = L_sub(L_shr(E_max5, align), manE_peak); + } + + IF (acc > 0) /* condition: E_max*5.e5 > E_peak */ + { + IF ( EQ_16(band_len_harm[k_max], 96)) + { + n = 61; + } + ELSE + { + QuantaPerDsDirac_fx(band_len_harm[k_max], 1, hBitsN, &n); + } + m = shl(sub(num_bits, HVQ_PVQ_GAIN_BITS), 3); + IF (GE_16(m, n)) + { + IF (GT_16(num_bands, 1)) /* condition: num_bands > 1 */ + { + sel_bands[*n_sel_bands] = k_max; + move16(); + *n_sel_bands = add(*n_sel_bands, 1); + R[k_max] = 1; /* Mark that the band has been encoded for fill_spectrum */ move16(); + } + } + } + } + + /* Allocate bits */ + tmp = sub(num_bands,1); + FOR (k = 0; k < tmp; k++) + { + Rk[k] = shl(sub(band_max_bits, HVQ_PVQ_GAIN_BITS), 3); + move16(); + } + /* NB: When it exits the above loop, k = num_bands - 1. */ + Rk[k] = shl(sub(num_bits, HVQ_PVQ_GAIN_BITS), 3); + move16(); + + return num_bands; +} + diff --git a/lib_com/igf_base.c b/lib_com/igf_base.c index 8ce76a9add8b4db53490a831839fd5be4ace894f..c90f7bf973d9e83249610d898cbb730b45fe6bd9 100644 --- a/lib_com/igf_base.c +++ b/lib_com/igf_base.c @@ -42,13 +42,13 @@ #include "wmc_auto.h" /*---------------------------------------------------------------------* - * IGF_ApplyTransFac() + * IGF_ApplyTransFac_flt() * * *---------------------------------------------------------------------*/ /*! r: | multiplication factor */ -int16_t IGF_ApplyTransFac( +int16_t IGF_ApplyTransFac_flt( const int16_t val, /* i : Q15 | input value for multiplication, Q15 */ const float transFac /* i : Q14 | multiplicator for variable val, Q14: 1.25f=0x5000, 1.0f=0x4000, 0.5f=0x2000 */ ) @@ -66,13 +66,13 @@ int16_t IGF_ApplyTransFac( /*---------------------------------------------------------------------* - * IGF_MapBitRateToIndex() + * IGF_MapBitRateToIndex_flt() * * maps a given bitrate to the IGF_BITRATE index *---------------------------------------------------------------------*/ /*! r: bitrate index */ -int16_t IGF_MapBitRateToIndex( +int16_t IGF_MapBitRateToIndex_flt( const int32_t brate, /* i : bitrate */ const int16_t bwidth, /* i : audio bandwidth */ const int16_t element_mode, /* i : element mode */ @@ -359,12 +359,12 @@ int16_t IGF_MapBitRateToIndex( /*---------------------------------------------------------------------* - * IGF_gridSetUp() + * IGF_gridSetUp_flt() * * IGF grid setup *---------------------------------------------------------------------*/ -static void IGF_gridSetUp( +static void IGF_gridSetUp_flt( H_IGF_GRID hGrid, /* o : IGF grid handle */ int16_t bitRateIndex, /* i : IGF bitrate index */ const int32_t sampleRate, /* i : sample rate */ @@ -396,7 +396,7 @@ static void IGF_gridSetUp( { swb_offset = &swb_offset_LB_new[bitRateIndex][1]; swb_offset_len = swb_offset_LB_new[bitRateIndex][0]; - mvr2r( &igf_whitening_TH[bitRateIndex][0][0], &hGrid->whiteningThreshold[0][0], IGF_MAX_TILES * 2 ); + mvr2r( &igf_whitening_TH_flt[bitRateIndex][0][0], &hGrid->whiteningThreshold_flt[0][0], IGF_MAX_TILES * 2 ); } else { @@ -405,7 +405,7 @@ static void IGF_gridSetUp( for ( sfb = 0; sfb < swb_offset_len; sfb++ ) { - hGrid->swb_offset[sfb] = IGF_ApplyTransFac( swb_offset[sfb], transFac ); + hGrid->swb_offset[sfb] = IGF_ApplyTransFac_flt( swb_offset[sfb], transFac ); } for ( sfb = swb_offset_len; sfb < IGF_MAX_SFB; sfb++ ) { @@ -413,7 +413,7 @@ static void IGF_gridSetUp( } hGrid->infoIsRefined = 0; - frameLength = IGF_ApplyTransFac( frameLength, transFac ); + frameLength = IGF_ApplyTransFac_flt( frameLength, transFac ); bandwidth = (float) sampleRate / 2.0f / (float) frameLength; hGrid->swb_offset_len = swb_offset_len; hGrid->startSfb = 0; @@ -436,7 +436,7 @@ static void IGF_gridSetUp( for ( k = 0; k < hGrid->nTiles; k++ ) { hGrid->sfbWrap[k + 1] = igf_tile_offset[2 * k]; - hGrid->sbWrap[k] = hGrid->minSrcSubband + IGF_ApplyTransFac( igf_tile_offset[2 * k + 1], transFac ); + hGrid->sbWrap[k] = hGrid->minSrcSubband + IGF_ApplyTransFac_flt( igf_tile_offset[2 * k + 1], transFac ); hGrid->tile[k + 1] = hGrid->swb_offset[igf_tile_offset[2 * k]]; } for ( t = hGrid->nTiles + 1; t < IGF_MAX_TILES; t++ ) @@ -510,13 +510,13 @@ static void IGF_gridSetUp( /*---------------------------------------------------------------------* - * IGFCommonFuncsIGFConfiguration() + * IGFCommonFuncsIGFConfiguration_flt() * * changes the IGF configuration *---------------------------------------------------------------------*/ /*! r: error value: 0 -> error, 1 -> ok */ -int16_t IGFCommonFuncsIGFConfiguration( +int16_t IGFCommonFuncsIGFConfiguration_flt( const int32_t total_brate, /* i : bitrate in bs e.g. 9600 for 9.6kbs */ const int16_t bwidth, /* i : audio bandwidth */ const int16_t element_mode, /* i : element mode */ @@ -534,7 +534,7 @@ int16_t IGFCommonFuncsIGFConfiguration( retValue = 0; /* bitrate index is unknown -> error! */ /* interface call for reading in settings */ - hIGFInfo->bitRateIndex = IGF_MapBitRateToIndex( total_brate, bwidth, element_mode, rf_mode ); + hIGFInfo->bitRateIndex = IGF_MapBitRateToIndex_flt( total_brate, bwidth, element_mode, rf_mode ); if ( hIGFInfo->bitRateIndex != IGF_BITRATE_UNKNOWN ) { @@ -556,15 +556,15 @@ int16_t IGFCommonFuncsIGFConfiguration( /* set up regular IGF grid for TCX 20 (transfac = 1.f) */ hGrid = &hIGFInfo->grid[IGF_GRID_LB_NORM]; - IGF_gridSetUp( hGrid, hIGFInfo->bitRateIndex, sampleRate, frameLength, 1.00f, igfMinFq ); + IGF_gridSetUp_flt( hGrid, hIGFInfo->bitRateIndex, sampleRate, frameLength, 1.00f, igfMinFq ); /* set up IGF grid for CELP->TCX 20 transitions (transfac = 1.25) */ hGrid = &hIGFInfo->grid[IGF_GRID_LB_TRAN]; - IGF_gridSetUp( hGrid, hIGFInfo->bitRateIndex, sampleRate, frameLength, 1.25f, igfMinFq ); + IGF_gridSetUp_flt( hGrid, hIGFInfo->bitRateIndex, sampleRate, frameLength, 1.25f, igfMinFq ); /* set up IGF grid for TCX 10 (transfac = 0.5) */ hGrid = &hIGFInfo->grid[IGF_GRID_LB_SHORT]; - IGF_gridSetUp( hGrid, hIGFInfo->bitRateIndex, sampleRate, frameLength, 0.50f, igfMinFq ); + IGF_gridSetUp_flt( hGrid, hIGFInfo->bitRateIndex, sampleRate, frameLength, 0.50f, igfMinFq ); } return retValue; @@ -572,13 +572,13 @@ int16_t IGFCommonFuncsIGFConfiguration( /*---------------------------------------------------------------------* - * IGFCommonFuncsIGFGetCFTables() + * IGFCommonFuncsIGFGetCFTables_flt() * * selects cumulative frequency tables and offsets for the IGF SCF arithmetic coder *---------------------------------------------------------------------*/ /*! r: error value: 0 -> error, 1 -> ok */ -int16_t IGFCommonFuncsIGFGetCFTables( +int16_t IGFCommonFuncsIGFGetCFTables_flt( const int32_t total_brate, /* i : bitrate in bs e.g. 9600 for 9.6kbs */ const int16_t bwidth, /* i : audio bandwidth */ const int16_t element_mode, /* i : element mode */ @@ -599,7 +599,7 @@ int16_t IGFCommonFuncsIGFGetCFTables( retValue = 0; /* bitrate index is unknown -> error! */ - bitRateIndex = IGF_MapBitRateToIndex( total_brate, bwidth, element_mode, rf_mode ); + bitRateIndex = IGF_MapBitRateToIndex_flt( total_brate, bwidth, element_mode, rf_mode ); if ( bitRateIndex != IGF_BITRATE_UNKNOWN ) { diff --git a/lib_com/igf_base_fx.c b/lib_com/igf_base_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..4bd7ec7a476009924f24ca30bb5a10d78a80bed6 --- /dev/null +++ b/lib_com/igf_base_fx.c @@ -0,0 +1,1226 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include +#include +#include +#include +#include "options.h" +#include "stl.h" +#include "prot_fx1.h" +#include "prot_fx2.h" +#include "rom_com.h" +#include "basop_util.h" + +/**********************************************************************/ /* +returns an int val, multiplied with transFac +**************************************************************************/ +static Word16 IGF_ApplyTransFac( /**< out: Q0 | multiplication factor */ + const Word16 val, /**< in: Q15 | input value for multiplication, Q15 */ + const Word16 transFac /**< in: Q14 | multiplicator for variable val, Q14: 1.25f=0x5000, 1.0f=0x4000, 0.5f=0x2000 */ +) +{ + Word16 ret; + + if(EQ_16(transFac, 0x4000)) + { + return val; + } + + ret = shl(val, 1); + ret = mac_r(0x00000000, ret, transFac); + ret = add(ret, s_and(ret, 1)); + + + return ret; +} + +/**********************************************************************/ /* +maps a given bitrate to the IGF_BITRATE index +**************************************************************************/ +static Word16 IGF_MapBitRateToIndex( + const Word32 brate, /* i : bitrate */ + const Word16 bwidth, /* i : audio bandwidth */ + const Word16 element_mode, /* i : element mode */ + const Word16 rf_mode /* i : flag to signal the RF mode */ +) +{ + Word16 bitRateIndex = IGF_BITRATE_UNKNOWN; + move16(); + /* Stereo/CPE modes */ + IF(GT_16(element_mode, IVAS_SCE)) + { + switch (bwidth) + { + case IGF_MODE_WB: + IF(LE_32(brate, IVAS_13k2) && EQ_16(rf_mode, 1)) + { + bitRateIndex = IGF_BITRATE_RF_WB_13200; + move16(); + } + ELSE IF(LE_32(brate, ACELP_9k60)) + { + bitRateIndex = IGF_BITRATE_WB_13200_CPE; + move16(); + } + ELSE IF(LE_32(brate, IVAS_13k2)) + { + bitRateIndex = IGF_BITRATE_WB_16400_CPE; + move16(); + } + BREAK; + case IGF_MODE_SWB: + /* DFT and TD Stereo bitrates */ + IF(LE_32(brate, ACELP_9k60)) + { + bitRateIndex = IGF_BITRATE_SWB_13200_CPE; + move16(); + } + ELSE IF(LE_32(brate, IVAS_13k2)) + { + IF(EQ_16(rf_mode, 1)) + { + bitRateIndex = IGF_BITRATE_RF_SWB_13200; + move16(); + } + ELSE + { + bitRateIndex = IGF_BITRATE_SWB_16400_CPE; + move16(); + } + } + ELSE IF(LE_32(brate, IVAS_16k4)) + { + bitRateIndex = IGF_BITRATE_SWB_24400_CPE; + move16(); + } + ELSE IF(LE_32(brate, IVAS_24k4) ) + { + bitRateIndex = IGF_BITRATE_SWB_32000_CPE; + move16(); + } + ELSE IF(LE_32(brate, IVAS_32k) ) + { + bitRateIndex = IGF_BITRATE_SWB_32000; + move16(); + } + /* MDCT Stereo bitrates */ + ELSE IF(LE_32(brate, IVAS_48k) ) + { + bitRateIndex = IGF_BITRATE_SWB_48000_CPE; + move16(); + } + ELSE IF(LE_32(brate, IVAS_64k) ) + { + bitRateIndex = IGF_BITRATE_SWB_64000_CPE; + move16(); + } + ELSE IF(LE_32(brate, IVAS_80k) ) + { + bitRateIndex = IGF_BITRATE_SWB_80000_CPE; + move16(); + } + ELSE IF(LE_32(brate, IVAS_96k)) + { + bitRateIndex = IGF_BITRATE_SWB_96000_CPE; + move16(); + } + BREAK; + case IGF_MODE_FB: + /* DFT and TD Stereo bitrates */ + IF(LE_32(brate, IVAS_16k4) ) + { + bitRateIndex = IGF_BITRATE_FB_24400_CPE; + move16(); + } + ELSE IF(LE_32(brate, IVAS_24k4) ) + { + bitRateIndex = IGF_BITRATE_FB_32000_CPE; + move16(); + } + ELSE IF(LE_32(brate, IVAS_32k)) + { + bitRateIndex = IGF_BITRATE_FB_32000; + move16(); + } + /* MDCT Stereo bitrates */ + ELSE IF(LE_32(brate, IVAS_48k)) + { + bitRateIndex = IGF_BITRATE_FB_48000_CPE; + move16(); + } + ELSE IF(LE_32(brate, IVAS_64k) ) + { + bitRateIndex = IGF_BITRATE_FB_64000_CPE; + move16(); + } + ELSE IF(LE_32(brate, IVAS_80k) ) + { + bitRateIndex = IGF_BITRATE_FB_80000_CPE; + move16(); + } + ELSE IF(LE_32(brate, IVAS_96k) ) + { + bitRateIndex = IGF_BITRATE_FB_96000_CPE; + move16(); + } + ELSE IF(LE_32(brate, IVAS_128k)) + { + bitRateIndex = IGF_BITRATE_FB_128000_CPE; + move16(); + } + BREAK; + } + } + /* SCE modes: use tunings done for DFT stereo bitrates also for according SCE bitrates, otherwise same config as mono modes */ + ELSE IF(EQ_16(element_mode, IVAS_SCE)) + { + switch (bwidth) + { + case IGF_MODE_WB: + IF(LE_32(brate, IVAS_13k2) && EQ_16(rf_mode, 1) ) + { + bitRateIndex = IGF_BITRATE_RF_WB_13200; + move16(); + } + ELSE IF(LE_32(brate, ACELP_9k60)) /* bitrates 8000 and 9600 */ + { + bitRateIndex = IGF_BITRATE_WB_9600; + move16(); + } + BREAK; + case IGF_MODE_SWB: + IF(LE_32(brate, ACELP_9k60) ) + { + bitRateIndex = IGF_BITRATE_SWB_13200_CPE; + move16(); + } + ELSE IF(LE_32(brate, IVAS_13k2) ) + { + IF(EQ_16(rf_mode, 1)) + { + bitRateIndex = IGF_BITRATE_RF_SWB_13200; + move16(); + } + ELSE + { + bitRateIndex = IGF_BITRATE_SWB_16400_CPE; + move16(); + } + } + ELSE IF(LE_32(brate, IVAS_16k4) ) + { + bitRateIndex = IGF_BITRATE_SWB_24400_CPE; + move16(); + } + ELSE IF(LE_32(brate, IVAS_24k4)) + { + move16(); + bitRateIndex = IGF_BITRATE_SWB_32000_CPE; + } + ELSE IF(LE_32(brate, IVAS_32k) ) + { + bitRateIndex = IGF_BITRATE_SWB_32000; + move16(); + } + ELSE IF(LE_32(brate, IVAS_48k)) + { + bitRateIndex = IGF_BITRATE_SWB_48000; + move16(); + } + ELSE IF(LE_32(brate, IVAS_64k)) + { + bitRateIndex = IGF_BITRATE_SWB_64000; + move16(); + } + BREAK; + case IGF_MODE_FB: + IF(LE_32(brate, IVAS_16k4) ) + { + bitRateIndex = IGF_BITRATE_FB_24400_CPE; + move16(); + } + ELSE IF(LE_32(brate, IVAS_24k4)) + { + bitRateIndex = IGF_BITRATE_FB_32000_CPE; + move16(); + } + ELSE IF(LE_32(brate, IVAS_32k) ) + { + bitRateIndex = IGF_BITRATE_FB_32000; + move16(); + } + ELSE IF(LE_32(brate, IVAS_48k)) + { + bitRateIndex = IGF_BITRATE_FB_48000; + move16(); + } + ELSE IF(LE_32(brate, IVAS_64k)) + { + bitRateIndex = IGF_BITRATE_FB_64000; + move16(); + } + ELSE IF(LE_32(brate, IVAS_96k)) + { + bitRateIndex = IGF_BITRATE_FB_96000; + move16(); + } + ELSE IF(LE_32(brate, IVAS_128k)) + { + bitRateIndex = IGF_BITRATE_FB_128000; + move16(); + } + BREAK; + } + } + /* EVS mono */ + else + { + switch (bwidth) + { + case IGF_MODE_WB: + IF(LE_32(brate, ACELP_13k20) && EQ_16(rf_mode, 1)) + { + bitRateIndex = IGF_BITRATE_RF_WB_13200; + move16(); + } + ELSE IF(LE_32(brate, ACELP_9k60)) /* bitrates 8000 and 9600 */ + { + bitRateIndex = IGF_BITRATE_WB_9600; + move16(); + } + BREAK; + case IGF_MODE_SWB: + IF(LE_32(brate, ACELP_9k60)) + { + move16(); + bitRateIndex = IGF_BITRATE_SWB_9600; + } + ELSE IF(LE_32(brate, ACELP_13k20) ) + { + IF(EQ_16(rf_mode, 1)) + { + bitRateIndex = IGF_BITRATE_RF_SWB_13200; + move16(); + } + ELSE + { + bitRateIndex = IGF_BITRATE_SWB_13200; + move16(); + } + } + ELSE IF(LE_32(brate, ACELP_16k40) ) + { + bitRateIndex = IGF_BITRATE_SWB_16400; + move16(); + } + ELSE IF(LE_32(brate, ACELP_24k40)) + { + bitRateIndex = IGF_BITRATE_SWB_24400; + move16(); + } + ELSE IF(LE_32(brate, ACELP_32k)) + { + bitRateIndex = IGF_BITRATE_SWB_32000; + move16(); + } + ELSE IF(LE_32(brate, ACELP_48k)) + { + bitRateIndex = IGF_BITRATE_SWB_48000; + move16(); + } + ELSE IF(LE_32(brate, ACELP_64k) ) + { + bitRateIndex = IGF_BITRATE_SWB_64000; + move16(); + } + BREAK; + case IGF_MODE_FB: + IF(LE_32(brate, ACELP_16k40) ) + { + bitRateIndex = IGF_BITRATE_FB_16400; + move16(); + } + ELSE IF(LE_32(brate, ACELP_24k40)) + { + bitRateIndex = IGF_BITRATE_FB_24400; + move16(); + } + ELSE IF(LE_32(brate, ACELP_32k) ) + { + bitRateIndex = IGF_BITRATE_FB_32000; + move16(); + } + ELSE IF(LE_32(brate, ACELP_48k) ) + { + bitRateIndex = IGF_BITRATE_FB_48000; + move16(); + } + ELSE IF(LE_32(brate, ACELP_64k)) + { + bitRateIndex = IGF_BITRATE_FB_64000; + move16(); + } + ELSE IF(LE_32(brate, HQ_96k) ) + { + bitRateIndex = IGF_BITRATE_FB_96000; + move16(); + } + ELSE IF(LE_32(brate, HQ_128k)) + { + bitRateIndex = IGF_BITRATE_FB_128000; + move16(); + } + BREAK; + } + } + + return bitRateIndex; +} + +/**********************************************************************/ /* +IGF grid setup +**************************************************************************/ +static void IGF_gridSetUp(H_IGF_GRID hGrid, /**< out: | IGF grid handle */ + Word16 bitRateIndex, /**< in: Q0 | IGF bitrate index */ + Word32 sampleRate, /**< in: | sample rate */ + Word16 frameLength, /**< in: | frame length */ + Word16 transFac, /**< in: | transFac */ + Word16 igfMinFq /**< in: | IGF minimum frequency indicating lower start frequency for copy up */ + ) +{ + Word16 t; + Word16 sfb; + const Word16 *swb_offset; + Word16 swb_offset_len; + Word16 bandwidth; + Word16 wrp_sfb; + Word16 tmp1; + Word16 tmp2; + Word32 L_tmp1; + Word32 L_tmp2; + + swb_offset = NULL; + move16(); + swb_offset_len = 0; + move16(); + + SWITCH (bitRateIndex) + { + case IGF_BITRATE_WB_9600: + case IGF_BITRATE_SWB_9600: + case IGF_BITRATE_RF_WB_13200: + case IGF_BITRATE_RF_SWB_13200: + case IGF_BITRATE_SWB_13200: + case IGF_BITRATE_SWB_16400: + case IGF_BITRATE_SWB_24400: + case IGF_BITRATE_SWB_32000: + case IGF_BITRATE_SWB_48000: + swb_offset = &swb_offset_LB_new[bitRateIndex][1]; + swb_offset_len = swb_offset_LB_new[bitRateIndex][0]; + move16(); + Copy(&igf_whitening_TH[bitRateIndex][0][0], &hGrid->whiteningThreshold[0][0], IGF_MAX_TILES * 2); + BREAK; + case IGF_BITRATE_FB_16400: + case IGF_BITRATE_FB_24400: + case IGF_BITRATE_FB_32000: + swb_offset = &swb_offset_LB_new[bitRateIndex][1]; + swb_offset_len = swb_offset_LB_new[bitRateIndex][0]; + move16(); + Copy(&igf_whitening_TH[bitRateIndex][0][0], &hGrid->whiteningThreshold[0][0], IGF_MAX_TILES * 2); + BREAK; + case IGF_BITRATE_FB_48000: + case IGF_BITRATE_FB_96000: + case IGF_BITRATE_FB_128000: + swb_offset = &swb_offset_LB_new[bitRateIndex][1]; + swb_offset_len = swb_offset_LB_new[bitRateIndex][0]; + move16(); + Copy(&igf_whitening_TH[bitRateIndex][0][0], &hGrid->whiteningThreshold[0][0], IGF_MAX_TILES * 2); + BREAK; + case IGF_BITRATE_UNKNOWN: + default: + assert(0); + } + + FOR(sfb = 0; sfb < swb_offset_len; sfb++) + { + hGrid->swb_offset[sfb] = IGF_ApplyTransFac(swb_offset[sfb], transFac); + move16(); + } + + hGrid->infoIsRefined = 0; + move16(); + frameLength = IGF_ApplyTransFac(frameLength, transFac); + tmp2 = norm_s(frameLength); + bandwidth = shl(frameLength,tmp2); + hGrid->swb_offset_len = extract_l(L_shr(sampleRate, 2)); + tmp1 = sub(norm_s(hGrid->swb_offset_len), 1); + hGrid->swb_offset_len = shl(hGrid->swb_offset_len, tmp1); + bandwidth = div_s(hGrid->swb_offset_len, bandwidth); + tmp2 = sub(add(tmp2, 1), tmp1); + bandwidth = shr(bandwidth, sub(15, tmp2)); + + + hGrid->swb_offset_len = swb_offset_len; + move16(); + hGrid->startSfb = 0; + move16(); + hGrid->stopSfb = sub(hGrid->swb_offset_len, 1); + hGrid->startLine = hGrid->swb_offset[ hGrid->startSfb ]; + move16(); + hGrid->stopLine = hGrid->swb_offset[ hGrid->stopSfb ]; + move16(); + hGrid->startFrequency = imult1616(bandwidth, hGrid->startLine); + hGrid->stopFrequency = imult1616(bandwidth, hGrid->stopLine); + + L_tmp1 = L_mult0(igfMinFq, frameLength); + tmp1 = sub(norm_l(L_tmp1), 1); + L_tmp1 = L_shl(L_tmp1, tmp1); + + tmp2 = norm_l(sampleRate); + L_tmp2 = L_shl(sampleRate, tmp2); + tmp1 = add(WORD16_BITS-1, sub(tmp1, add(tmp2, 1))); /* takes into account sampleRate >> 1 */ + + hGrid->minSrcSubband = div_s(extract_h(L_tmp1), extract_h(L_tmp2)); + hGrid->minSrcSubband = shr(hGrid->minSrcSubband, tmp1); + + + hGrid->minSrcSubband = add(hGrid->minSrcSubband, s_and(hGrid->minSrcSubband, 1)); + hGrid->minSrcFrequency = imult1616(bandwidth, hGrid->minSrcSubband); + hGrid->infoGranuleLen = frameLength; + move16(); + hGrid->infoTransFac = transFac; + move16(); + + hGrid->sfbWrap[0] = 0; + move16(); + hGrid->tile[0] = hGrid->startLine; + move16(); + + + /*************************************************************************/ + SWITCH (bitRateIndex) + { + /* SWB 13200 */ + case IGF_BITRATE_WB_9600: + hGrid->nTiles = 2; + move16(); + wrp_sfb = 2; + move16(); + + /*1st*/ + hGrid->sfbWrap[0+1] = wrp_sfb; + move16(); + hGrid->sbWrap[0] = hGrid->minSrcSubband; + move16(); + hGrid->tile[0+1] = hGrid->swb_offset[wrp_sfb]; + move16(); + + /*2nd*/ + hGrid->sfbWrap[1+1] = hGrid->stopSfb; + move16(); + hGrid->sbWrap[1] = hGrid->minSrcSubband; + move16(); + hGrid->tile[1+1] = hGrid->swb_offset[hGrid->stopSfb]; + move16(); + BREAK; + + case IGF_BITRATE_RF_WB_13200: + hGrid->nTiles = 2; + wrp_sfb = 2; + + /*1st*/ + hGrid->sfbWrap[0+1] = wrp_sfb; + hGrid->sbWrap[0] = hGrid->minSrcSubband; + hGrid->tile[0+1] = hGrid->swb_offset[wrp_sfb]; + + /*2nd*/ + hGrid->sfbWrap[1+1] = hGrid->stopSfb; + hGrid->sbWrap[1] = hGrid->minSrcSubband; + hGrid->tile[1+1] = hGrid->swb_offset[hGrid->stopSfb]; + + BREAK; + case IGF_BITRATE_SWB_9600: + hGrid->nTiles = 3; + wrp_sfb = 1; + + /*1st*/ + hGrid->sfbWrap[0+1] = wrp_sfb; + hGrid->sbWrap[0] = hGrid->minSrcSubband; + hGrid->tile[0+1] = hGrid->swb_offset[wrp_sfb]; + + /*2nd*/ + wrp_sfb = 2; + hGrid->sfbWrap[1+1] = wrp_sfb; + hGrid->sbWrap[1] = hGrid->minSrcSubband + IGF_ApplyTransFac(32, transFac); + hGrid->tile[1+1] = hGrid->swb_offset[wrp_sfb]; + + /*3rd*/ + hGrid->sfbWrap[2+1] = hGrid->stopSfb; + hGrid->sbWrap[2] = hGrid->minSrcSubband + IGF_ApplyTransFac(46, transFac); + hGrid->tile[2+1] = hGrid->swb_offset[hGrid->stopSfb]; + + BREAK; + case IGF_BITRATE_RF_SWB_13200: + hGrid->nTiles = 3; + wrp_sfb = 1; + + /*1st*/ + hGrid->sfbWrap[0+1] = wrp_sfb; + hGrid->sbWrap[0] = hGrid->minSrcSubband; + hGrid->tile[0+1] = hGrid->swb_offset[wrp_sfb]; + + /*2nd*/ + wrp_sfb = 2; + hGrid->sfbWrap[1+1] = wrp_sfb; + hGrid->sbWrap[1] = hGrid->minSrcSubband + IGF_ApplyTransFac(32, transFac); + hGrid->tile[1+1] = hGrid->swb_offset[wrp_sfb]; + + /*3rd*/ + hGrid->sfbWrap[2+1] = hGrid->stopSfb; + hGrid->sbWrap[2] = hGrid->minSrcSubband + IGF_ApplyTransFac(46, transFac); + hGrid->tile[2+1] = hGrid->swb_offset[hGrid->stopSfb]; + + BREAK; + + case IGF_BITRATE_SWB_13200: + hGrid->nTiles = 2; + move16(); + wrp_sfb = 4; + move16(); + + /*1st*/ + hGrid->sfbWrap[0+1] = wrp_sfb; + move16(); + hGrid->sbWrap[0] = hGrid->minSrcSubband; + move16(); + hGrid->tile[0+1] = hGrid->swb_offset[wrp_sfb]; + move16(); + + /*2nd*/ + hGrid->sfbWrap[1+1] = hGrid->stopSfb; + move16(); + hGrid->sbWrap[1] = add(hGrid->minSrcSubband, IGF_ApplyTransFac(32, transFac)); + move16(); + hGrid->tile[1+1] = hGrid->swb_offset[hGrid->stopSfb]; + move16(); + BREAK; + + case IGF_BITRATE_SWB_16400: + hGrid->nTiles = 3; + move16(); + wrp_sfb = 4; + move16(); + + /*1st*/ + hGrid->sfbWrap[0+1] = wrp_sfb; + move16(); + hGrid->sbWrap[0] = hGrid->minSrcSubband; + move16(); + hGrid->tile[0+1] = hGrid->swb_offset[wrp_sfb]; + move16(); + + /*2nd*/ + hGrid->sfbWrap[1+1] = 6; + move16(); + hGrid->sbWrap[1] = add(hGrid->minSrcSubband, IGF_ApplyTransFac(48, transFac)); + move16(); + hGrid->tile[1+1] = hGrid->swb_offset[6]; + move16(); + + /*3nd*/ + hGrid->sfbWrap[2+1] = hGrid->stopSfb; + move16(); + hGrid->sbWrap[2] = add(hGrid->minSrcSubband, IGF_ApplyTransFac(64, transFac)); + move16(); + hGrid->tile[2+1] = hGrid->swb_offset[hGrid->stopSfb]; + move16(); + BREAK; + + case IGF_BITRATE_SWB_24400: + case IGF_BITRATE_SWB_32000: + hGrid->nTiles = 3; + move16(); + wrp_sfb = 4; + move16(); + + /*1st*/ + hGrid->sfbWrap[0+1] = wrp_sfb; + move16(); + hGrid->sbWrap[0] = hGrid->minSrcSubband; + move16(); + hGrid->tile[0+1] = hGrid->swb_offset[wrp_sfb]; + move16(); + + /*2nd*/ + hGrid->sfbWrap[1+1] = 7; + move16(); + hGrid->sbWrap[1] = add(hGrid->minSrcSubband, IGF_ApplyTransFac(32, transFac)); + move16(); + hGrid->tile[1+1] = hGrid->swb_offset[7]; + move16(); + + /*3nd*/ + hGrid->sfbWrap[2+1] = hGrid->stopSfb; + move16(); + hGrid->sbWrap[2] = add(hGrid->minSrcSubband, IGF_ApplyTransFac(64, transFac)); + move16(); + hGrid->tile[2+1] = hGrid->swb_offset[hGrid->stopSfb]; + move16(); + BREAK; + case IGF_BITRATE_SWB_48000: + hGrid->nTiles = 1; + move16(); + wrp_sfb = hGrid->stopSfb; + move16(); + + /*1st*/ + hGrid->sfbWrap[0+1] = hGrid->stopSfb; + move16(); + hGrid->sbWrap[0] = sub(shl(hGrid->startLine, 1), hGrid->stopLine); + move16(); + hGrid->tile[0+1] = hGrid->swb_offset[hGrid->stopSfb]; + move16(); + + BREAK; + case IGF_BITRATE_FB_16400: + hGrid->nTiles = 3; + move16(); + wrp_sfb = 4; + move16(); + + /*1st*/ + hGrid->sfbWrap[0+1] = wrp_sfb; + move16(); + hGrid->sbWrap[0] = hGrid->minSrcSubband; + move16(); + hGrid->tile[0+1] = hGrid->swb_offset[wrp_sfb]; + move16(); + wrp_sfb = 7; + move16(); + + /*2nd*/ + hGrid->sfbWrap[1+1] = wrp_sfb; + move16(); + hGrid->sbWrap[1] = hGrid->minSrcSubband; + move16(); + hGrid->tile[1+1] = hGrid->swb_offset[wrp_sfb]; + move16(); + + /*3nd*/ + hGrid->sfbWrap[2+1] = hGrid->stopSfb; + move16(); + hGrid->sbWrap[2] = hGrid->minSrcSubband; + move16(); + hGrid->tile[2+1] = hGrid->swb_offset[hGrid->stopSfb]; + move16(); + + BREAK; + + case IGF_BITRATE_FB_24400: + case IGF_BITRATE_FB_32000: + hGrid->nTiles = 4; + move16(); + wrp_sfb = 4; + move16(); + + /*1st*/ + hGrid->sfbWrap[0+1] = wrp_sfb; + move16(); + hGrid->sbWrap[0] = hGrid->minSrcSubband; + move16(); + hGrid->tile[0+1] = hGrid->swb_offset[wrp_sfb]; + move16(); + wrp_sfb = 6; + move16(); + + /*2nd*/ + hGrid->sfbWrap[1+1] = wrp_sfb; + move16(); + hGrid->sbWrap[1] = add(hGrid->minSrcSubband, IGF_ApplyTransFac(32, transFac)); + move16(); + hGrid->tile[1+1] = hGrid->swb_offset[wrp_sfb]; + move16(); + wrp_sfb = 9; + move16(); + + /*3nd*/ + hGrid->sfbWrap[2+1] = wrp_sfb; + move16(); + hGrid->sbWrap[2] = hGrid->minSrcSubband; + move16(); + hGrid->tile[2+1] = hGrid->swb_offset[wrp_sfb]; + move16(); + + /*4nd*/ + hGrid->sfbWrap[3+1] = hGrid->stopSfb; + move16(); + hGrid->sbWrap[3] = add(hGrid->minSrcSubband, sub(hGrid->swb_offset[9], hGrid->swb_offset[8])); + move16(); + hGrid->tile[3+1] = hGrid->swb_offset[hGrid->stopSfb]; + move16(); + BREAK; + case IGF_BITRATE_FB_48000: + case IGF_BITRATE_FB_96000: + case IGF_BITRATE_FB_128000: + hGrid->nTiles = 1; + move16(); + + /*1st*/ + hGrid->sfbWrap[0+1] = hGrid->stopSfb; + move16(); + hGrid->sbWrap[0] = sub(shl(hGrid->startLine, 1), hGrid->stopLine); + move16(); + hGrid->tile[0+1] = hGrid->swb_offset[hGrid->stopSfb]; + move16(); + + BREAK; + default: + assert(0); + }/*switch*/ + + /*************************************************************************/ + /*************************************************************************/ + + + /* adapt level envelope: */ + SWITCH (bitRateIndex) + { + case IGF_BITRATE_RF_WB_13200: + case IGF_BITRATE_WB_9600: + hGrid->gFactor = 13107/*0.80f Q14*/; + move16(); + hGrid->fFactor = 11469/*0.70f Q14*/; + move16(); + hGrid->lFactor = 9830/*0.60f Q14*/; + move16(); + BREAK; + case IGF_BITRATE_SWB_13200: + case IGF_BITRATE_FB_16400: + case IGF_BITRATE_SWB_16400: + hGrid->gFactor = 15237/*0.93f Q14*/; + move16(); + hGrid->fFactor = 3277/*0.20f Q14*/; + move16(); + hGrid->lFactor = 13926/*0.85f Q14*/; + move16(); + BREAK; + case IGF_BITRATE_FB_24400: + case IGF_BITRATE_SWB_24400: + case IGF_BITRATE_FB_32000: + case IGF_BITRATE_SWB_32000: + hGrid->gFactor = 15811/*0.965f Q14*/; + move16(); + hGrid->fFactor = 3277/*0.20f Q14*/; + move16(); + hGrid->lFactor = 13926/*0.85f Q14*/; + move16(); + BREAK; + case IGF_BITRATE_FB_48000: + case IGF_BITRATE_SWB_48000: + hGrid->gFactor = 16384/*1.00f Q14*/; + move16(); + hGrid->fFactor = 3277/*0.20f Q14*/; + move16(); + hGrid->lFactor = 16384/*1.00f Q14*/; + move16(); + BREAK; + case IGF_BITRATE_SWB_9600: + case IGF_BITRATE_RF_SWB_13200: + default: + hGrid->gFactor = 16384/*1.00f Q14*/; + move16(); + hGrid->fFactor = 0/*0.00f Q14*/; + move16(); + hGrid->lFactor = 16384/*1.00f Q14*/; + move16(); + } + + FOR (t = add(hGrid->nTiles, 1); t < IGF_MAX_TILES; t++) + { + hGrid->tile[t] = 0; + move16(); + hGrid->sbWrap[t - 1] = 0; + move16(); + hGrid->sfbWrap[t] = 0; + move16(); + } + +} + +/**********************************************************************/ /* +calculates energy per sfb via power spectrum +**************************************************************************/ +void IGFCommonFuncsCalcSfbEnergyPowerSpec(const Word16 startSfb, /**< in: Q0 | start sfb index */ + const Word16 stopSfb, /**< in: Q0 | stop sfb index */ + const Word16 *swb_offset, /**< in: Q0 | IGF swb offset table */ + Word32 *pPowerSpectrum, /**< in: Q31 | power spectrum */ + Word16 *pPowerSpectrum_exp, /**< in: | Exponent of PowerSpectrum */ + Word32 *sfbEnergy, /**< out:Q31 | SFB energies , will be initialized inside this function */ + Word16 *sfbEnergy_exp /**< out: | Exponent of PowerSpectrum */ + ) +{ + Word16/*Q0*/ sfb; + Word16/*Q0*/ line; + Word32 L_c; + +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; + Flag Carry = 0; +#endif + + FOR (sfb = startSfb; sfb < stopSfb; sfb++) + { + sfbEnergy[sfb] = L_deposit_l(0); + } + IF (NULL == pPowerSpectrum) + { + return; + } + + FOR (sfb = startSfb; sfb < stopSfb; sfb++) + { + L_c = L_deposit_l(0); + FOR (line = swb_offset[sfb]; line < swb_offset[sfb+1]; line++) + { + Carry = 0; +#ifdef BASOP_NOGLOB + sfbEnergy[sfb] = L_add_co(sfbEnergy[sfb], pPowerSpectrum[line], &Carry, &Overflow); +#else /* BASOP_NOGLOB */ + sfbEnergy[sfb] = L_add_c(sfbEnergy[sfb], pPowerSpectrum[line]); +#endif /* BASOP_NOGLOB */ + move32(); + Overflow = 0; +#ifdef BASOP_NOGLOB + L_c = L_macNs_co(L_c,0,0, &Carry, &Overflow); +#else /* BASOP_NOGLOB */ + L_c = L_macNs(L_c,0,0); +#endif + } + sfbEnergy[sfb] = norm_llQ31(L_c,sfbEnergy[sfb],&(sfbEnergy_exp[sfb])); + move32(); + sfbEnergy_exp[sfb] = add(sfbEnergy_exp[sfb],*pPowerSpectrum_exp); + move16(); + } +} + +/**********************************************************************/ /* +calculate the MDCT square spectrum in the IGF range +**************************************************************************/ +void IGFCommonFuncsMDCTSquareSpec(const Word16 sqrtBgn, /**< in: Q0 | start MDCT subband index */ + const Word16 sqrtEnd, /**< in: Q0 | stop MDCT subband index */ + const Word32 *mdctSpec, /**< in: Q31 | MDCT spectrum to square */ + const Word16 mdctSpec_e, /**< in: | exponent of mdctSpectrum */ + Word32 *mdctSquareSpec, /**< out:Q31 | MDCT square spectrum */ + Word16 *mdctSquareSpec_e, /**< out: | exponent of mdctSquareSpec */ + Word16 indexOffset /**< in: Q0 | index offset */ + ) +{ + Word16 i; + Word16 j; + Word16 s1; + Word16 tmp; + + + /* get headroom, only in IGF range */ + s1 = getScaleFactor32(mdctSpec + sqrtBgn, sub(sqrtEnd, sqrtBgn)); + + /* set new exponent */ + *mdctSquareSpec_e = add(shl(sub(mdctSpec_e, s1), 1), 1); + move16(); + + /* MDCT square spectrum: MDCT^2 */ + j = add(sqrtBgn, indexOffset); /* handle indexOffset with care, otherwise memory overruns may occur! */ + + + FOR (i = sqrtBgn; i < sqrtEnd; i++) + { + tmp = round_fx(L_shl(mdctSpec[i], s1)); + mdctSquareSpec[j++] = L_mult0(tmp, tmp); + move32(); + } + + +} + +/**********************************************************************/ /* +write bits to stream +**************************************************************************/ +void IGFCommonFuncsWriteSerialBit( + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + Word16 *pBitOffset, /**< out: Q0 | bit offset */ + Word16 bit /**< in: Q0 | value of bit */ +) +{ + + IF (hBstr) + { + push_next_indice_fx(hBstr, bit, 1); + } + *pBitOffset = add(*pBitOffset, 1); + move16(); + + return; +} + +/**********************************************************************/ /* +changes the IGF configuration +**************************************************************************/ +Word16 IGFCommonFuncsIGFConfiguration( + const Word32 total_brate, /* i : bitrate in bs e.g. 9600 for 9.6kbs */ + const Word16 bwidth, /* i : audio bandwidth */ + const Word16 element_mode, /* i : element mode */ + H_IGF_INFO hIGFInfo, /* o : IGF info handle */ + const Word16 rf_mode /* i : flag to signal the RF mode */ +) +{ + H_IGF_GRID hGrid; + Word16 retValue; + Word32 sampleRate; + Word16 frameLength; + Word16 igfMinFq; + Word16 maxHopsize; + + retValue = 0; /* bitrate index is unknown -> error! */ move16(); + + /* interface call for reading in settings */ + hIGFInfo->bitRateIndex = IGF_MapBitRateToIndex(total_brate, bwidth, element_mode, rf_mode); + + IF (NE_16(hIGFInfo->bitRateIndex, IGF_BITRATE_UNKNOWN)) + { + retValue = 1; /* no error */ move16(); + + /* mapping to local values */ + sampleRate = igfMode[hIGFInfo->bitRateIndex].sampleRate; + move32(); + frameLength = igfMode[hIGFInfo->bitRateIndex].frameLength; + move16(); + igfMinFq = igfMode[hIGFInfo->bitRateIndex].igfMinFq; + move16(); + maxHopsize = igfMode[hIGFInfo->bitRateIndex].maxHopsize; + move16(); + + /* basic information */ + hIGFInfo->sampleRate = sampleRate; + move32(); + hIGFInfo->frameLength = frameLength; + move16(); + hIGFInfo->maxHopsize = maxHopsize; + move16(); +#if 0 + //100820 temp fix +#endif + hIGFInfo->nfSeedBuf[0] = 0; + hIGFInfo->nfSeedBuf[1] = 0; + hIGFInfo->nfSeed = &hIGFInfo->nfSeedBuf[0]; + move16(); + + /* set up regular IGF grid for TCX 20 (transfac = 1.f) */ + hGrid = &hIGFInfo->grid[IGF_GRID_LB_NORM]; + IGF_gridSetUp(hGrid, + hIGFInfo->bitRateIndex, + sampleRate, + frameLength, + 16384/*1 Q14*/, + igfMinFq); + + /* set up IGF grid for CELP->TCX 20 transitions (transfac = 1.25) */ + hGrid = &hIGFInfo->grid[IGF_GRID_LB_TRAN]; + IGF_gridSetUp(hGrid, + hIGFInfo->bitRateIndex, + sampleRate, + frameLength, + 20480/*1.25 Q14*/, + igfMinFq); + /* set up IGF grid for TCX 10 (transfac = 0.5) */ + hGrid = &hIGFInfo->grid[IGF_GRID_LB_SHORT]; + IGF_gridSetUp(hGrid, + hIGFInfo->bitRateIndex, + sampleRate, + frameLength, + 8192/*0.50f Q14*/, + igfMinFq); + } + + return retValue; +} + +/**********************************************************************/ /* +selects cumulative frequency tables and offsets for the IGF SCF arithmetic coder +**************************************************************************/ +Word16 IGFCommonFuncsIGFGetCFTables( + const Word32 total_brate, /* i : bitrate in bs e.g. 9600 for 9.6kbs */ + const Word16 bwidth, /* i : audio bandwidth */ + const Word16 element_mode, /* i : element mode */ + const Word16 rf_mode, /* i : flag to signal the RF mode */ + const Word16** cf_se00, /* o : CF table for t == 0 and f == 0 */ + const Word16** cf_se01, /* o : CF table for t == 0 and f == 1 */ + Word16* cf_off_se01, /* o : offset for CF table above */ + const Word16** cf_se02, /* o : CF tables for t == 0 and f >= 2 */ + const Word16** cf_off_se02, /* o : offsets for CF tables above */ + const Word16** cf_se10, /* o : CF table for t == 1 and f == 0 */ + Word16* cf_off_se10, /* o : offset for CF table above */ + const Word16** cf_se11, /* o : CF tables for t == 1 and f >= 1 */ + const Word16** cf_off_se11 /* o : offsets for CF tables above */ +) +{ + Word16 retValue; + Word16 bitRateIndex; + + retValue = 0; /* bitrate index is unknown -> error! */ + + bitRateIndex = IGF_MapBitRateToIndex(total_brate, bwidth, element_mode, rf_mode); + + IF (bitRateIndex != IGF_BITRATE_UNKNOWN) + { + retValue = 1; /* no error */ + + SWITCH (bitRateIndex) + { + case IGF_BITRATE_WB_13200_CPE: + bitRateIndex = IGF_BITRATE_WB_9600; + move16(); + BREAK; + case IGF_BITRATE_WB_16400_CPE: + bitRateIndex = IGF_BITRATE_WB_9600; + move16(); + BREAK; + case IGF_BITRATE_SWB_13200_CPE: + bitRateIndex = IGF_BITRATE_SWB_9600; + move16(); + BREAK; + case IGF_BITRATE_SWB_16400_CPE: + bitRateIndex = IGF_BITRATE_SWB_13200; + move16(); + BREAK; + case IGF_BITRATE_SWB_24400_CPE: + bitRateIndex = IGF_BITRATE_SWB_16400; + move16(); + BREAK; + case IGF_BITRATE_FB_24400_CPE: + bitRateIndex = IGF_BITRATE_FB_16400; + move16(); + BREAK; + case IGF_BITRATE_SWB_32000_CPE: + bitRateIndex = IGF_BITRATE_SWB_24400; + move16(); + BREAK; + case IGF_BITRATE_FB_32000_CPE: + bitRateIndex = IGF_BITRATE_FB_24400; + move16(); + BREAK; + case IGF_BITRATE_FB_48000_CPE: + case IGF_BITRATE_FB_64000_CPE: + bitRateIndex = IGF_BITRATE_FB_32000; + move16(); + BREAK; + } + + switch (bitRateIndex) + { + case IGF_BITRATE_WB_9600: + case IGF_BITRATE_RF_WB_13200: + case IGF_BITRATE_SWB_9600: + case IGF_BITRATE_SWB_13200: + case IGF_BITRATE_RF_SWB_13200: + case IGF_BITRATE_SWB_16400: + case IGF_BITRATE_SWB_24400: + case IGF_BITRATE_SWB_32000: + case IGF_BITRATE_SWB_48000: + case IGF_BITRATE_SWB_64000: + *cf_se00 = cf_se00_tab; + *cf_se01 = cf_se01_tab[bitRateIndex]; + *cf_off_se01 = cf_off_se01_tab[bitRateIndex]; + *cf_se02 = &cf_se02_tab[bitRateIndex][0][0]; + *cf_off_se02 = &cf_off_se02_tab[bitRateIndex][0]; + *cf_se10 = &cf_se10_tab[0]; + *cf_off_se10 = cf_off_se10_tab; + *cf_se11 = &cf_se11_tab[0][0][0]; + *cf_off_se11 = &cf_off_se11_tab[0][0]; + move16();move16();move16();move16();move16();move16();move16();move16();move16(); + + BREAK; + case IGF_BITRATE_FB_16400: + case IGF_BITRATE_FB_24400: + case IGF_BITRATE_FB_32000: + bitRateIndex = bitRateIndex - IGF_BITRATE_FB_16400 + IGF_BITRATE_SWB_16400; + *cf_se00 = cf_se00_tab; + *cf_se01 = cf_se01_tab[bitRateIndex]; + *cf_off_se01 = cf_off_se01_tab[bitRateIndex]; + *cf_se02 = &cf_se02_tab[bitRateIndex][0][0]; + *cf_off_se02 = &cf_off_se02_tab[bitRateIndex][0]; + *cf_se10 = &cf_se10_tab[0]; + *cf_off_se10 = cf_off_se10_tab; + *cf_se11 = &cf_se11_tab[0][0][0]; + *cf_off_se11 = &cf_off_se11_tab[0][0]; + move16(); move16(); move16(); move16(); move16(); move16(); move16(); move16(); move16(); + BREAK; + case IGF_BITRATE_FB_48000: + case IGF_BITRATE_FB_64000: + bitRateIndex = bitRateIndex - IGF_BITRATE_FB_48000 + IGF_BITRATE_SWB_48000; + *cf_se00 = cf_se00_tab; + *cf_se01 = cf_se01_tab[bitRateIndex]; + *cf_off_se01 = cf_off_se01_tab[bitRateIndex]; + *cf_se02 = &cf_se02_tab[bitRateIndex][0][0]; + *cf_off_se02 = &cf_off_se02_tab[bitRateIndex][0]; + *cf_se10 = &cf_se10_tab[0]; + *cf_off_se10 = cf_off_se10_tab; + *cf_se11 = &cf_se11_tab[0][0][0]; + *cf_off_se11 = &cf_off_se11_tab[0][0]; + move16(); move16(); move16(); move16(); move16(); move16(); move16(); move16(); move16(); + BREAK; + case IGF_BITRATE_FB_96000: + case IGF_BITRATE_FB_128000: + case IGF_BITRATE_FB_80000_CPE: + case IGF_BITRATE_FB_96000_CPE: + case IGF_BITRATE_FB_128000_CPE: + bitRateIndex = IGF_BITRATE_SWB_48000; + *cf_se00 = cf_se00_tab; + *cf_se01 = cf_se01_tab[bitRateIndex]; + *cf_off_se01 = cf_off_se01_tab[bitRateIndex]; + *cf_se02 = &cf_se02_tab[bitRateIndex][0][0]; + *cf_off_se02 = &cf_off_se02_tab[bitRateIndex][0]; + *cf_se10 = &cf_se10_tab[0]; + *cf_off_se10 = cf_off_se10_tab; + *cf_se11 = &cf_se11_tab[0][0][0]; + *cf_off_se11 = &cf_off_se11_tab[0][0]; + move16(); move16(); move16(); move16(); move16(); move16(); move16(); move16(); move16(); + BREAK; + case IGF_BITRATE_SWB_48000_CPE: + bitRateIndex = IGF_BITRATE_SWB_16400; + *cf_se00 = cf_se00_tab; + *cf_se01 = cf_se01_tab[bitRateIndex]; + *cf_off_se01 = cf_off_se01_tab[bitRateIndex]; + *cf_se02 = &cf_se02_tab[bitRateIndex][0][0]; + *cf_off_se02 = &cf_off_se02_tab[bitRateIndex][0]; + *cf_se10 = &cf_se10_tab[0]; + *cf_off_se10 = cf_off_se10_tab; + *cf_se11 = &cf_se11_tab[0][0][0]; + *cf_off_se11 = &cf_off_se11_tab[0][0]; + move16(); move16(); move16(); move16(); move16(); move16(); move16(); move16(); move16(); + BREAK; + case IGF_BITRATE_SWB_64000_CPE: + case IGF_BITRATE_SWB_80000_CPE: + case IGF_BITRATE_SWB_96000_CPE: + bitRateIndex = IGF_BITRATE_SWB_48000; /*bitRateIndex-IGF_BITRATE_SWB_56000+IGF_BITRATE_SWB_48000;*/ + *cf_se00 = cf_se00_tab; + *cf_se01 = cf_se01_tab[bitRateIndex]; + *cf_off_se01 = cf_off_se01_tab[bitRateIndex]; + *cf_se02 = &cf_se02_tab[bitRateIndex][0][0]; + *cf_off_se02 = &cf_off_se02_tab[bitRateIndex][0]; + *cf_se10 = &cf_se10_tab[0]; + *cf_off_se10 = cf_off_se10_tab; + *cf_se11 = &cf_se11_tab[0][0][0]; + *cf_off_se11 = &cf_off_se11_tab[0][0]; + move16(); move16(); move16(); move16(); move16(); move16(); move16(); move16(); move16(); + BREAK; + case IGF_BITRATE_UNKNOWN: + default: + assert(0); + } + } + + return retValue; +} + diff --git a/lib_com/isf_dec_amr_wb_fx.c b/lib_com/isf_dec_amr_wb_fx.c index 0c1f66031b1866fc0e828b259ac2fbbf3797ca5e..a5db582e77c216728f5833f60fbc6f6100c3df72 100644 --- a/lib_com/isf_dec_amr_wb_fx.c +++ b/lib_com/isf_dec_amr_wb_fx.c @@ -64,18 +64,18 @@ void isf_dec_amr_wb_fx( * ISF de-quantization of SID frames *---------------------------------*/ - IF(EQ_32(st->core_brate_fx, SID_1k75)) + IF(EQ_32(st->core_brate, SID_1k75)) { - indice[0] = (Word16)get_next_indice_fx(st, 6); + indice[0] = (Word16)get_next_indice(st, 6); move16(); - indice[1] = (Word16)get_next_indice_fx(st, 6); + indice[1] = (Word16)get_next_indice(st, 6); move16(); - indice[2] = (Word16)get_next_indice_fx(st, 6); + indice[2] = (Word16)get_next_indice(st, 6); move16(); - indice[3] = (Word16)get_next_indice_fx(st, 5); + indice[3] = (Word16)get_next_indice(st, 5); move16(); - indice[4] = (Word16)get_next_indice_fx(st, 5); + indice[4] = (Word16)get_next_indice(st, 5); move16(); disf_ns_28b_fx(indice, isf_new); @@ -91,36 +91,36 @@ void isf_dec_amr_wb_fx( * ISF de-quantization of all other frames *-----------------------------------------------------------------*/ - IF(EQ_32(st->core_brate_fx, ACELP_6k60)) + IF(EQ_32(st->core_brate, ACELP_6k60)) { - indice[0] = (Word16)get_next_indice_fx(st, 8); + indice[0] = (Word16)get_next_indice(st, 8); move16(); - indice[1] = (Word16)get_next_indice_fx(st, 8); + indice[1] = (Word16)get_next_indice(st, 8); move16(); - indice[2] = (Word16)get_next_indice_fx(st, 7); + indice[2] = (Word16)get_next_indice(st, 7); move16(); - indice[3] = (Word16)get_next_indice_fx(st, 7); + indice[3] = (Word16)get_next_indice(st, 7); move16(); - indice[4] = (Word16)get_next_indice_fx(st, 6); + indice[4] = (Word16)get_next_indice(st, 6); move16(); disf_2s_36b_fx(indice, isf_new, st->mem_AR_fx, st->mem_MA_fx, 1); } ELSE { - indice[0] = (Word16)get_next_indice_fx(st, 8); + indice[0] = (Word16)get_next_indice(st, 8); move16(); - indice[1] = (Word16)get_next_indice_fx(st, 8); + indice[1] = (Word16)get_next_indice(st, 8); move16(); - indice[2] = (Word16)get_next_indice_fx(st, 6); + indice[2] = (Word16)get_next_indice(st, 6); move16(); - indice[3] = (Word16)get_next_indice_fx(st, 7); + indice[3] = (Word16)get_next_indice(st, 7); move16(); - indice[4] = (Word16)get_next_indice_fx(st, 7); + indice[4] = (Word16)get_next_indice(st, 7); move16(); - indice[5] = (Word16)get_next_indice_fx(st, 5); + indice[5] = (Word16)get_next_indice(st, 5); move16(); - indice[6] = (Word16)get_next_indice_fx(st, 5); + indice[6] = (Word16)get_next_indice(st, 5); move16(); disf_2s_46b_fx(indice, isf_new, st->mem_AR_fx, st->mem_MA_fx,1); @@ -160,7 +160,7 @@ void isf_dec_amr_wb_fx( * Check ISF stability : distance between old ISF and current ISF *------------------------------------------------------------------*/ - st->stab_fac_fx = lsf_stab_fx(isf_new, st->lsf_old_fx, 1, st->L_frame_fx); + st->stab_fac_fx = lsf_stab_fx(isf_new, st->lsf_old_fx, 1, st->L_frame); return; } diff --git a/lib_com/ivas_arith.c b/lib_com/ivas_arith.c index 98243b0f4addacfbc7d4efb5277ac8568c96cb37..9c48c0c967a5b6932d897948acfca6baf217285a 100644 --- a/lib_com/ivas_arith.c +++ b/lib_com/ivas_arith.c @@ -118,8 +118,8 @@ uint16_t ivas_ari_decode_14bits_bit_ext_1_lfe( symbol = ivas_ari_get_symbol( cum_freq, range, cum ); - high = low + mul_sbc_14bits( range, cum_freq[symbol] ) - 1; - low += mul_sbc_14bits( range, cum_freq[symbol + 1] ); + high = low + mul_sbc_14bits_ivas( range, cum_freq[symbol] ) - 1; + low += mul_sbc_14bits_ivas( range, cum_freq[symbol + 1] ); for ( ;; ) { @@ -247,8 +247,8 @@ void ivas_ari_encode_14bits_ext( low = s->low; range = high - low + 1; - high = low + mul_sbc_14bits( range, cum_freq[symbol] ) - 1; - low += mul_sbc_14bits( range, cum_freq[symbol + 1] ); + high = low + mul_sbc_14bits_ivas( range, cum_freq[symbol] ) - 1; + low += mul_sbc_14bits_ivas( range, cum_freq[symbol + 1] ); bits_to_follow = s->bits_to_follow; diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index 12179e153a26e9da2ecf649cc626c29e90e6821d..c36c8207eea6351aee5c7201073eaf8d2e5a6f69 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -717,7 +717,7 @@ void ivas_imdft( const int16_t length /* i : signal length */ ); -void TonalMdctConceal_create_concealment_noise( +void TonalMdctConceal_create_concealment_noise_ivas( float concealment_noise[L_FRAME48k], CPE_DEC_HANDLE hCPE, const int16_t L_frameTCX, @@ -729,14 +729,14 @@ void TonalMdctConceal_create_concealment_noise( const TONALMDCTCONC_NOISE_GEN_MODE noise_gen_mode ); -void TonalMdctConceal_whiten_noise_shape( +void TonalMdctConceal_whiten_noise_shape_ivas( Decoder_State *st, const int16_t L_frame, const TONALMDCTCONC_NOISE_SHAPE_WHITENING_MODE ); /*! r: IGF start line */ -int16_t get_igf_startline( +int16_t get_igf_startline_flt( Decoder_State *st, /* i : decoder state */ const int16_t L_frame, /* i : length of the frame */ const int16_t L_frameTCX /* i : full band frame length */ @@ -2444,7 +2444,7 @@ void ms_inv_mask_processing( int16_t maxSfb /* i : number of stereo frequency bands */ ); -void IGFDecApplyStereo( +void IGFDecApplyStereo_flt( const IGF_DEC_INSTANCE_HANDLE hIGFDecL, /* i : instance handle of IGF Decoder */ const IGF_DEC_INSTANCE_HANDLE hIGFDecR, /* i : instance handle of IGF Decoder */ float *spectrumL, /* i/o: L MDCT spectrum */ @@ -2468,7 +2468,7 @@ void IGFEncStereoEncoder( const int16_t isTransition /* i : flag for transtition */ ); -void IGFDecReplicateTCX10State( +void IGFDecReplicateTCX10State_flt( IGF_DEC_INSTANCE_HANDLE hIGFDec /* i/o: instance handle of IGF Decoder */ ); diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h new file mode 100644 index 0000000000000000000000000000000000000000..0f25cadb609aa15dff7b673b71e118d707e01ea5 --- /dev/null +++ b/lib_com/ivas_prot_fx.h @@ -0,0 +1,59 @@ +/****************************************************************************************************** + + (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#ifndef IVAS_PROT_FX_H +#define IVAS_PROT_FX_H + +#include +#include "options.h" +#include +#include "typedef.h" +#include "stat_enc.h" +#include "stat_dec.h" +#include "stat_com.h" +#include "ivas_stat_enc.h" +#include "ivas_stat_dec.h" +#include "ivas_stat_com.h" +#include "ivas_error_utils.h" + + + + + + + + + + + + +#endif \ No newline at end of file diff --git a/lib_com/ivas_stereo_mdct_bands_com.c b/lib_com/ivas_stereo_mdct_bands_com.c index 35524a20a1a5c6c16675e86f1a869866e718a395..eafac4193009fe733c71569edf958d1be8bf655c 100644 --- a/lib_com/ivas_stereo_mdct_bands_com.c +++ b/lib_com/ivas_stereo_mdct_bands_com.c @@ -226,9 +226,9 @@ void stereo_mdct_init_igf_start_band( int16_t i, bitRateIndex, igfStartLine; const int16_t *swb_offset; - bitRateIndex = IGF_MapBitRateToIndex( element_brate, bwidth, IVAS_CPE_MDCT, 0 ); + bitRateIndex = IGF_MapBitRateToIndex_flt( element_brate, bwidth, IVAS_CPE_MDCT, 0 ); swb_offset = &swb_offset_LB_new[bitRateIndex][1]; - igfStartLine = IGF_ApplyTransFac( swb_offset[0], transFac ); + igfStartLine = IGF_ApplyTransFac_flt( swb_offset[0], transFac ); for ( i = 0; i < stbParams->sfbCnt; i++ ) { diff --git a/lib_com/limit_t0.c b/lib_com/limit_t0.c index 1176a81327346e47cc8de90872fd86a57215aecf..6b9f38588dc7f7ee6b7a41773afa466f8c8d70b2 100644 --- a/lib_com/limit_t0.c +++ b/lib_com/limit_t0.c @@ -173,12 +173,12 @@ void limit_T0( /*-------------------------------------------------* - * Routine limit_T0_voiced() + * Routine limit_T0_voiced_ivas() * * Close-loop pitch lag search limitation *-------------------------------------------------*/ -void limit_T0_voiced( +void limit_T0_voiced_ivas( const int16_t nbits, const int16_t res, const int16_t T0, /* i : rough pitch estimate around which the search is done */ diff --git a/lib_com/limit_t0_fx.c b/lib_com/limit_t0_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..462bc6c66ce1809d0e61db51ffe412e73bdf1141 --- /dev/null +++ b/lib_com/limit_t0_fx.c @@ -0,0 +1,259 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include +#include "options.h" /* Compilation switches */ +#include "cnst.h" /* Common constants */ +#include "prot_fx1.h" /* Function prototypes */ +#include "prot_fx2.h" /* Function prototypes */ +#include "rom_com.h" + + +/*-------------------------------------------------* + * Local constants + *-------------------------------------------------*/ + +#define LIMIT_PIT_REL_LOWER 2 /* delta interval to extend pitch coding in relative Q */ +#define LIMIT_PIT_REL_UPPER 0 + +/*-------------------------------------------------* + * limit_T0() + * + * Close-loop pitch lag search limitation + *-------------------------------------------------*/ + + +void limit_T0_fx( + const Word16 L_frame, /* i : length of the frame */ + const Word16 delta, /* i : Half the close-loop searched interval */ + const Word16 pit_flag, /* i : selecting absolute(0) or delta(1) pitch quantization */ + const Word16 limit_flag, /* i : flag for Q limits (0=restrained, 1=extended) */ + const Word16 T0, /* i : rough pitch estimate around which the search is done */ + const Word16 T0_frac, /* i : pitch estimate fractional part */ + Word16 *T0_min, /* o : lower pitch limit */ + Word16 *T0_max /* o : higher pitch limit */ +) +{ + + Word16 delta2,T1; + Word16 pit_min, pit_max; + + IF( limit_flag == 0 ) /* restrained Q limits */ + { + /* set limits */ + IF( EQ_16(L_frame,L_FRAME)) + { + pit_max = PIT_MAX; + move16(); + pit_min = PIT_MIN; + move16(); + } + ELSE /* L_frame == L_FRAME16k */ + { + pit_max = PIT16k_MAX; + move16(); + pit_min = PIT16k_MIN; + move16(); + } + + delta2 = sub(shl(delta,1),1); + T1 = T0; + move16(); + + if( GE_16(T0_frac,2)) + { + T1 = add(T1,1); + } + + *T0_min = sub(T1,delta); + move16(); + + *T0_min = s_max(*T0_min,pit_min); + + *T0_max = add(*T0_min,delta2); + move16(); + + IF( GT_16(*T0_max,pit_max)) + { + *T0_max = pit_max; + move16(); + *T0_min = sub(*T0_max,delta2); + move16(); + } + } + ELSE /* extended Q limits */ + { + /* set limits */ + IF( EQ_16(L_frame, L_FRAME)) + { + pit_max = PIT_MAX; + move16(); + pit_min = PIT_MIN_EXTEND; + move16(); + if( EQ_16(limit_flag, 2)) + { + pit_min = PIT_MIN_DOUBLEEXTEND; + move16(); + } + } + ELSE /* L_frame == L_FRAME16k */ + { + pit_max = PIT16k_MAX; + move16(); + pit_min = PIT16k_MIN_EXTEND; + move16(); + } + + delta2 = sub(shl(delta,1),1) ; + move16(); + T1 = T0; + move16(); + if( GE_16(T0_frac,2)) + { + T1 = add(T1,1); + } + *T0_min = sub(T1, delta); + move16(); + IF( pit_flag == 0 ) + { + /* subframes with absolute search: keep Q range */ + *T0_min = s_max(*T0_min,pit_min); + + *T0_max = add(*T0_min, delta2); + move16(); + IF( GT_16(*T0_max,pit_max)) + { + *T0_max = pit_max; + move16(); + *T0_min = sub(*T0_max, delta2); + move16(); + } + } + ELSE + { + /* subframes with relative search: extend Q range */ + *T0_min = s_max(*T0_min,sub(pit_min, LIMIT_PIT_REL_LOWER)); + move16(); + + *T0_min = s_max(*T0_min,L_INTERPOL); + *T0_max = *T0_min + delta2; + move16(); + + IF( GT_16(*T0_max, add(pit_max, LIMIT_PIT_REL_UPPER))) + { + *T0_max = add(pit_max, LIMIT_PIT_REL_UPPER); + move16(); + *T0_min = sub(*T0_max, delta2); + move16(); + } + } + } + return; +} + + +#define inv_T0_res InvIntTable + +/*-------------------------------------------------* +* Routine limit_T0_voiced() +* +* Close-loop pitch lag search limitation +*-------------------------------------------------*/ +void limit_T0_voiced( + const Word16 nbits, + const Word16 res, + const Word16 T0, /* i : rough pitch estimate around which the search is done */ + const Word16 T0_frac, /* i : pitch estimate fractional part */ + const Word16 T0_res, /* i : pitch resolution */ + Word16 *T0_min, /* o : lower pitch limit */ + Word16 *T0_min_frac, /* o : lower pitch limit */ + Word16 *T0_max, /* o : higher pitch limit */ + Word16 *T0_max_frac, /* o : higher pitch limit */ + const Word16 pit_min, /* i : Minimum pitch lag */ + const Word16 pit_max /* i : Maximum pitch lag */ +) +{ + Word16 T1, temp1, temp2, res2; + + + assert(res > 1 && res<=6); + + res2 = res; + move16(); + if(EQ_16(res,6)) + { + res2 = shr(res2,1); + } + + /* Mid-point */ + T1 = T0; + test(); + if( GT_16(T0_res,1)&&GE_16(T0_frac,(shr(T0_res,1)))) + { + T1 = add(T1,1); + } + + /* Lower-bound */ + temp1 = sub(i_mult(T1,res),shl(1,sub(nbits,1))); + + temp2 = mult(temp1,inv_T0_res[res2]); + if(EQ_16(res,6)) + { + temp2 = shr(temp2,1); + } + + *T0_min = temp2; + move16(); + + *T0_min_frac = sub(temp1,i_mult(temp2,res)); + move16(); + + IF ( LT_16(*T0_min,pit_min)) + { + *T0_min = pit_min; + move16(); + *T0_min_frac = 0; + move16(); + } + + /* Higher-bound */ + temp1 = add(i_mult(*T0_min,res),add(*T0_min_frac,sub(shl(1,nbits),1))); + + temp2 = mult(temp1,inv_T0_res[res2]); + if(EQ_16(res,6)) + { + temp2 = shr(temp2,1); + } + + *T0_max = temp2; + move16(); + + *T0_max_frac = sub(temp1,i_mult(temp2,res)); + move16(); + + IF ( GT_16(*T0_max,pit_max)) + { + *T0_max = pit_max; + move16(); + + *T0_max_frac = sub(res,1); + move16(); + + temp1 = add(i_mult(*T0_max,res),sub(*T0_max_frac,sub(shl(1,nbits),1))); + + temp2 = mult(temp1,inv_T0_res[res2]); + if(EQ_16(res,6)) + { + temp2 = shr(temp2,1); + } + move16(); + *T0_min = temp2; + + *T0_min_frac = sub(temp1, i_mult(temp2,res)); + move16(); + } + + + return; +} diff --git a/lib_com/longarith.c b/lib_com/longarith.c index 01a20c8417ea0091294f13b06829e567afcba36f..b138d3b95125a9080b50576d5df62823c9a5b4d3 100644 --- a/lib_com/longarith.c +++ b/lib_com/longarith.c @@ -132,6 +132,28 @@ void longshiftright( return; } +void longshr( + UWord32 a[], + Word16 bits, + Word16 len +) +{ + Word16 fracb_u, k; + + assert((bits > 0) && (bits < 32)); + + fracb_u = sub(32, bits); + len = sub(len, 1); + FOR(k = 0; k < len; k++) + { + a[k] = L_or(L_lshr(a[k], bits), L_lshl(a[k + 1], fracb_u)); + move32(); + } + a[k] = L_lshr(a[k], bits); + move32(); + + return; +} /*-------------------------------------------------------------------* * longshiftleft() diff --git a/lib_com/low_rate_band_att_fx.c b/lib_com/low_rate_band_att_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..5b0e3c482a7341f7ad1ab396ab8d6ae9298cd273 --- /dev/null +++ b/lib_com/low_rate_band_att_fx.c @@ -0,0 +1,229 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include +#include "options.h" /* Compilation switches */ +#include "rom_com.h" /* Static table prototypes */ +#include "prot_fx1.h" +#include "prot_fx2.h" + + +/*--------------------------------------------------------------------------* + * fine_gain_pred() + * + * Fine gain prediction + *--------------------------------------------------------------------------*/ + +void fine_gain_pred_fx( + const Word16 *sfm_start, /* i : Sub band start indices */ + const Word16 *sfm_end, /* i : Sub band end indices */ + const Word16 *sfm_size, /* i : Sub band bandwidths */ + const Word16 *i_sort, /* i : Energy sorting indices */ + const Word16 *K, /* i : Number of pulses per band */ + const Word16 *maxpulse, /* i : Maximum pulse per band */ + const Word16 *R, /* i : Bits per sub band Q3 */ + const Word16 num_sfm, /* i : Number of sub bands */ + Word16 *xq, /* i/o: Quantized vector /quantized vector with finegain adj Q15*/ + Word16 *y, /* i/o: Quantized vector (int) */ + Word16 *fg_pred, /* o : Predicted fine gains Q12 */ + const Word16 core /* i : Core */ +) +{ + Word16 i, band; + Word16 gp; + Word32 xx; + Word16 accuracy; + Word16 k, bw; + + Word16 shift, bw_idx; + Word16 tmp, exp, exp2; + Word32 L_tmp; + UWord16 lsb; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + + FOR( band = 0; band < num_sfm; band++) + { + k = K[i_sort[band]]; + move16(); + + IF( k > 0) + { + /* bw, bw_idx only used if k>0 */ + bw = sfm_size[i_sort[band]]; + move16(); /* allowed. 8, 16, 24,32,48,64,80,96 */ + bw_idx = band_len_idx[ shr(bw,3) ]; + move16(); /* bw_idx= 0: 7 */ + xx = L_deposit_l(0); + shift = band_len_ener_shift[bw_idx]; + FOR(i = sfm_start[i_sort[band]]; i < sfm_end[i_sort[band]]; i++) + { + /*xx += xq[i] * xq[i]; */ + tmp = shr(xq[i], shift); /*15-shift */ + xx = L_mac0(xx, tmp, tmp); /*30-2*shift */ + } + + IF ( xx > 0) + { + /* Normalize synthesis to RMS=1.0 */ + /*gp = (float) sqrt(bw / xx); */ + exp = norm_l(xx); + L_tmp = L_shl(xx, exp); /*2*(15-shift)+exp */ + exp = sub(31, add(exp, sub(30, shl(shift,1)))); + L_tmp = Isqrt_lc(L_tmp, &exp); /*31 - exp */ + Mpy_32_16_ss(L_tmp, fine_gain_pred_sqrt_bw[bw_idx], &L_tmp, &lsb); /*31-exp+11-15=27-exp */ +#ifdef BASOP_NOGLOB + gp = round_fx_o(L_shl_o(L_tmp, add(1, exp), &Overflow), &Overflow); /*27-exp+1+exp-16=12 */ +#else + gp = round_fx(L_shl(L_tmp, add(1, exp))); /*27-exp+1+exp-16=12 */ +#endif + test(); + test(); + IF (EQ_16(core, HQ_CORE)&&R!=NULL&&LE_16(R[i_sort[band]],256)) /* 256 is 32 in Q3 */ + { + /*accuracy = ((float)k/(float)bw)*maxpulse[i_sort[band]]; */ + L_tmp = L_mult(k, inv_tbl_fx[bw]); /*0+15+1 */ + exp2 = norm_l(L_tmp); + tmp = round_fx(L_shl(L_tmp, exp2)); /*16+exp2-16 */ + L_tmp = L_mult0(maxpulse[i_sort[band]], tmp); /*0+exp2 */ + exp = norm_l(L_tmp); + accuracy = round_fx(L_shl(L_tmp, exp)); /*exp2+exp-16=exp-16 */ + exp = add(exp, exp2); + + /*gp *= 1.0f - 0.05f / accuracy; */ + tmp = div_s(13107, accuracy); /* 0.05 in Q18 */ +#ifdef BASOP_NOGLOB + tmp = shr_o(tmp, sub(34, exp), &Overflow); /*15+18-exp+16-15=34-exp */ +#else /* BASOP_NOGLOB */ + tmp = shr(tmp, sub(34, exp)); /*15+18-exp+16-15=34-exp */ +#endif + tmp = sub(32767, tmp); + tmp = s_max(27554, tmp); /* Limit attenuation to norm quantizer error, 2^-0.25 in Q15 */ + gp = mult_r(tmp, gp); /*15+12+1-16=12 */ + } + + fg_pred[band] = gp; + move16(); + } + ELSE + { + fg_pred[band] = 0; + move16(); + } + } + ELSE + { + fg_pred[band] = 0; + move16(); + FOR(i = sfm_start[i_sort[band]]; i < sfm_end[i_sort[band]]; i++) + { + y[i] = 0; + move16(); + xq[i] = 0; + move16(); + } + } + } + + return; +} + +/*--------------------------------------------------------------------------* + * get_max_pulses() + * + * Find the maximum pulse height (in unit pulses) in each band + *--------------------------------------------------------------------------*/ + +void get_max_pulses_fx( + const Word16 *band_start, /* i : Sub band start indices */ + const Word16 *band_end, /* i : Sub band end indices */ + const Word16 *k_sort, /* i : Indices for sorting by energy */ + const Word16 *npulses, /* i : Pulses per sub band */ + const Word16 BANDS, /* i : Number of bands */ + Word16 *inp_vector, /* i/o: Encoded shape vectors (int)*/ + Word16 *maxpulse /* o : Maximum pulse height per band */ +) +{ + Word16 i, k; + Word16 npul; + Word16 maxp; + Word16 tmp; + + FOR (k = 0; k < BANDS; k++) + { + npul = npulses[k_sort[k]]; + move16(); + maxp = 0; + move16(); + IF (npul > 0) + { + FOR (i = band_start[k_sort[k]]; i < band_end[k_sort[k]]; i++) + { + tmp = abs_s(inp_vector[i]); + if (GT_16(tmp, maxp)) + { + maxp = tmp; + move16(); + } + } + } + maxpulse[k_sort[k]] = maxp; + move16(); + } + + return; +} + +/*--------------------------------------------------------------------------* + * fine_gain_dec() + * + * Fine gain decoder. Decodes fine gain adjustments and applies correction to + * predicted fine gains + *--------------------------------------------------------------------------*/ + +void fine_gain_dec_fx +( + Decoder_State *st, + const Word16 *ord, /* i : Indices for energy order */ + const Word16 num_sfm, /* i : Number of bands */ + const Word16 *gain_bits, /* i : Gain adjustment bits per sub band */ + Word16 *fg_pred /* i/o: Predicted gains / Corrected gains */ +) +{ + Word16 band; + Word16 gbits; + Word16 idx, tmp1, exp1; + Word16 gain_dbq; + Word32 L_tmp; + + + FOR ( band = 0; band < num_sfm; band++) + { + gbits = gain_bits[ord[band]]; + IF (gbits > 0) + { + IF (fg_pred[band] != 0) + { + idx = get_next_indice( st, gbits ); + gain_dbq = finegain_fx[gbits-1][idx]; + + /* Update predicted gain with quantized correction */ + L_tmp = L_mult0(gain_dbq, 21771); /* 21771=0.05*log2(10) */ /* 14+17=31 */ + L_tmp = L_shr(L_tmp, 15); + tmp1 = L_Extract_lc(L_tmp, &exp1); + tmp1 = abs_s(tmp1); + tmp1 = extract_l(Pow2(14, tmp1)); + exp1 = sub(14, exp1); + + L_tmp = L_mult0(fg_pred[band], tmp1); /*12+exp1 */ + fg_pred[band] = round_fx(L_shl(L_tmp, sub(16, exp1))); /*12+exp1+16-exp1-16=12 */ + } + } + } + + return; +} + + diff --git a/lib_com/lpc_tools_fx.c b/lib_com/lpc_tools_fx.c index c423f284fd768c5c8c70e711db9b2e40fd777556..188407cb27b996f60554b2201347e639dc50847e 100644 --- a/lib_com/lpc_tools_fx.c +++ b/lib_com/lpc_tools_fx.c @@ -925,7 +925,7 @@ void E_LPC_a_lsf_isf_conversion(Word16 *lpcCoeffs, Word16 *lsf, const Word16 * ptrImag[j*8] = L_deposit_h(0); } - //fft16(ptrReal, ptrImag, 8, 0); + fft16(ptrReal, ptrImag, 8, 0); ptrReal++; ptrImag++; @@ -959,7 +959,7 @@ void E_LPC_a_lsf_isf_conversion(Word16 *lpcCoeffs, Word16 *lsf, const Word16 * ptwiddle++; } - //fft16(ptrReal, ptrImag, 8, 0); + fft16(ptrReal, ptrImag, 8, 0); ptrReal++; ptrImag++; diff --git a/lib_com/lsf_dec_bfi.c b/lib_com/lsf_dec_bfi.c index 70506b293c18856de3fad6c631b25648dc8fb9d5..ec58ff17e4c70e4103f14997923066062c736e28 100644 --- a/lib_com/lsf_dec_bfi.c +++ b/lib_com/lsf_dec_bfi.c @@ -43,13 +43,13 @@ #include "wmc_auto.h" /*---------------------------------------------------------------------* - * routine: lsf_dec_bfi() + * routine: lsf_dec_bfi_flt() * * Estimate the lsfs in case of FER * Bad frame, all active speech coders *---------------------------------------------------------------------*/ -void lsf_dec_bfi( +void lsf_dec_bfi_flt( const int16_t codec_mode, /* i : codec mode: MODE1 | MODE2 */ float *lsf, /* o : estimated LSF vector */ const float *lsfold, /* i : past quantized lsf */ @@ -247,12 +247,12 @@ void lsf_dec_bfi( } /*---------------------------------------------------------------------* - * routine: PlcGetlsfBase() + * routine: PlcGetlsfBase_flt() * * *---------------------------------------------------------------------*/ -const float *PlcGetlsfBase( +const float *PlcGetlsfBase_flt( const int16_t lpcQuantization, const int16_t narrowBand, const int32_t sr_core ) @@ -262,20 +262,20 @@ const float *PlcGetlsfBase( /* high rates, return value is never used; the correct value changes dynamically and is not available during PLC; therefore, the setting is kept as before (without the define PLC_FIX_XSF_HANDLING); the - correct value would be isf[m] as returned by lpc_unquantize() + correct value would be isf[m] as returned by lpc_unquantize_flt() during normal decoding */ if ( sr_core == 32000 ) { - return means_swb_cleanspeech_lsf32k0; + return means_swb_cleanspeech_lsf32k0_flt; } else if ( sr_core == 25600 ) { - return means_swb_cleanspeech_lsf25k6; + return means_swb_cleanspeech_lsf25k6_flt; } else { - return means_wb_cleanspeech_lsf16k0; + return means_wb_cleanspeech_lsf16k0_flt; } } diff --git a/lib_com/lsf_dec_bfi_fx.c b/lib_com/lsf_dec_bfi_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..a8012671e6b1add6838db18fea3466ccfa11df0b --- /dev/null +++ b/lib_com/lsf_dec_bfi_fx.c @@ -0,0 +1,302 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + + +#include +#include "options.h" +#include "basop_util.h" +#include "rom_com.h" +#include "cnst.h" +#include "prot_fx1.h" +#include "prot_fx2.h" + + +/*---------------------------------------------------------------------* +* routine: lsf_dec_bfi() +* +* Estimate the LSFs in case of FER +* Bad frame, all active speech coders +*---------------------------------------------------------------------*/ +void lsf_dec_bfi( + const Word16 codec_mode, /* i: : codec mode: MODE1 | MODE2 */ + Word16*lsf, /*!< o : 14Q1*1.28 quantized ISFs */ + const Word16*lsfold, /*!< i : 14Q1*1.28 past quantized ISF */ + Word16*lsf_adaptive_mean, /*!< i : 14Q1*1.28 ISF adaptive mean, updated when BFI==0 */ + const Word16 lsfBase[], /* i : base for differential lsf coding */ + Word16*mem_MA, /*!< i/o: 14Q1*1.28 quantizer memory for MA model */ + Word16*mem_AR, /*!< i/o: 14Q1*1.28 quantizer memory for MA model */ + Word16 stab_fac, /*!< i : ISF stability factor (shifted right by 1) */ + const Word16 last_coder_type,/*!< i : coding type in last good received fr. */ + Word16 L_frame, + const Word16 last_good, /*!< i : last good received frame */ + const Word16 nbLostCmpt, /*!< i : counter of consecutive bad frames */ + const Word8 plcBackgroundNoiseUpdated, /* i : background noise already updated?*/ + Word16 *lsf_q_cng, /* o : quantized ISFs for background noise (14Q1*1.28) */ + Word16 *lsf_cng, + Word16 *old_lsf_q_cng, /* o : old quantized ISFs for background noise */ + const Word16 Last_GSC_pit_band_idx, + const Word16 Opt_AMR_WB, /* i : IO flag */ + const Word8 tcxonly, + const short bwidth /* i: coded bandwidth */ +) +{ + Word16 i; + Word16 alpha; + Word32 tmp; + Word16 lsf_mean[M]; + const Word16* pt_meansForFading; + const Word16* pt_meansForMemUpdate; + Word16 beta; + Word16 gap; + + IF (EQ_16(codec_mode,MODE1)) + { + pt_meansForMemUpdate = lsf_mean; + /* Update inital guess to something stable, with proper sampling frequency and format (ISF/LSF)*/ + IF ( Opt_AMR_WB) + { + pt_meansForFading = Mean_isf_wb; + } + ELSE + { + /* 12.8kHz ACELP sampling */ + IF( EQ_16(L_frame,L_FRAME)) + { + pt_meansForFading = GEWB_Ave_fx; + + if (EQ_16(bwidth,NB)) + { + pt_meansForFading = GENB_Ave_fx; + } + } + /* 16kHz ACELP sampling */ + ELSE + { + pt_meansForFading = GEWB2_Ave_fx; + } + } + } + ELSE + { + pt_meansForFading = pt_meansForMemUpdate = lsfBase; + test(); + if (lsf_cng != NULL && plcBackgroundNoiseUpdated) + { + pt_meansForFading = lsf_cng; + } + } + IF( LE_16(nbLostCmpt, 3)) + { + test(); + test(); + IF( (EQ_16(last_coder_type, UNVOICED))) /* Clear unvoiced last good frame */ + { + move16(); + alpha = _ALPHA_UU_FX; + } + ELSE IF( EQ_16(last_coder_type,AUDIO)||EQ_16(last_good,INACTIVE_CLAS)) + { + alpha = 32604/*0.995f Q15*/; + move16(); + test(); + if( Last_GSC_pit_band_idx > 0 && GT_16(nbLostCmpt, 1)) + { + alpha = 26214/*0.8f Q15*/; + move16(); + } + } + ELSE IF( EQ_16(last_good,UNVOICED_CLAS)) + { + IF( LE_16(nbLostCmpt,1)) + { + /* If stable, do not flatten the spectrum in the 1st erased frame */ + alpha = add(mult(stab_fac, 32768 - _ALPHA_U_FX_X_2), _ALPHA_U_FX_X_2); + } + ELSE IF(EQ_16(nbLostCmpt,2)) + { + alpha = sub(_ALPHA_U_FX_X_2,shr(_ALPHA_U_FX,1)); /* 0.6 */ + } + ELSE + { + alpha = _ALPHA_U_FX; + move16(); /* go rapidly to CNG spectrum */ + } + } + ELSE IF( EQ_16(last_good ,UNVOICED_TRANSITION)) + { + alpha = _ALPHA_UT_FX; + move16(); + } + ELSE IF( (EQ_16(last_good,VOICED_CLAS))||(EQ_16(last_good,ONSET))) + { + /* clearly voiced - mild convergence to the CNG spectrum for the first 3 erased frames */ + move16(); + alpha = _ALPHA_V_FX; + } + ELSE IF( EQ_16(last_good ,SIN_ONSET)) + { + alpha = _ALPHA_S_FX; + move16(); + } + ELSE + { + alpha = _ALPHA_VT_FX; /* rapid convergence to the CNG spectrum (long erasure, ONSETS) */ + } + } + ELSE + { + Word16 exp = 15; + alpha = Inv16(nbLostCmpt, &exp); /*1.f/bfi_cnt;*/ + alpha = shl(alpha,exp); + } + IF(EQ_16(codec_mode,MODE1)) + { + beta = BETA_FEC_FX; + move16(); + } + ELSE + { + beta = 8192/*0.25f Q15*/; + move16(); + if (plcBackgroundNoiseUpdated) + { + beta = 0/*0.f Q15*/; + move16(); + } + } + FOR (i=0; i +#include "cnst.h" +#include "options.h" +#include "rom_com.h" +#include "prot_fx1.h" +#include "prot_fx2.h" +#include "basop_util.h" + +#ifndef swap +#define swap(x,y,type) {type u__p; u__p=x; x=y; y=u__p;} +#endif +/*---------------------------------------------------------------------* + * midlsf_dec() + * + * + *---------------------------------------------------------------------*/ +void midlsf_dec( + const Word16 qlsf0[], /* i: quantized lsf coefficients (3Q12) */ + const Word16 qlsf1[], /* i: quantized lsf coefficients (3Q12) */ + const Word16 idx, /* i: codebook index */ + Word16 qlsf[], /* o: decoded lsf coefficients (3Q12) */ + const Word16 coder_type, + Word16 *mid_lsf_int, + const Word16 prev_bfi, + const Word16 safety_net +) +{ + const Word16 *ratio=NULL; + Word16 j; + Word32 L_tmp; + Word16 bad_spacing = 0; + + move16(); + /* Select codebook */ + IF ( EQ_16(coder_type, UNVOICED)) + { + ratio = tbl_mid_unv_wb_5b_fx; + } + ELSE + { + ratio = tbl_mid_gen_wb_5b_fx; + } + FOR (j=0; jQ(x2.56+14)*/ + L_tmp = L_mac(L_tmp, ratio[idx*M+j], qlsf1[j]); /*Q(x2.56+14)*/ + qlsf[j] = round_fx(L_shl(L_tmp,2)); /*Q(x2.56)*/ + } + + + IF(mid_lsf_int != NULL) /*at the decoder*/ + { + /* check for incorrect LSF ordering */ + IF ( EQ_16(*mid_lsf_int, 1)) + { + FOR (j=1; j 0 && LT_16(j, M)&<_16(qlsf[j],add(qlsf[j-1],LSF_GAP_MID_FX))) + { + qlsf[j] = add(qlsf[j-1], LSF_GAP_MID_FX); + move16(); + } + + } + } + ELSE + { + /* otherwise, use regular LSF spacing and ordering as in the encoder */ + FOR (j=0; j 0 && LT_16(j, M)&<_16(qlsf[j],add(qlsf[j-1],LSF_GAP_MID_FX))) + { + qlsf[j] = add(qlsf[j-1], LSF_GAP_MID_FX); + move16(); + } + } + } + if ( prev_bfi ) + { + /* continue redoing mid-LSF interpolation with 0.4 in order not to propagate the error */ + *mid_lsf_int = 1; + move16(); + } + if ( safety_net ) + { + /* safety-net encountered -> stop redoing mid-LSF interpolation with 0.4 */ + *mid_lsf_int = 0; + move16(); + } + } + ELSE + { + /* use regular LSF spacing */ + FOR (j=0; j 0 && LT_16(j, M)&<_16(qlsf[j],add(qlsf[j-1],LSF_GAP_MID_FX))) + { + qlsf[j] = add(qlsf[j-1], LSF_GAP_MID_FX); + move16(); + } + } + } + + return; +} +Word16 lsf_ind_is_active( + const Word16 lsf_q_ind[], + const Word16 means[], + const Word16 narrowband, + const Word16 cdk +) +{ + Word16 lsf[2], min_distance; + + lsf[0] = add(lsf_q_ind[0], means[0]); + move16(); + lsf[1] = add(lsf_q_ind[1], means[1]); + move16(); + + min_distance = lsf[0]; + move16(); + min_distance = s_min(min_distance, sub(lsf[1], lsf[0])); + + assert(narrowband == 0 || narrowband == 1); + assert(cdk == 0 || cdk == 1); + + return sub(min_distance, min_distance_thr[narrowband][cdk]) < 0; +} + diff --git a/lib_com/lsf_tools_fx.c b/lib_com/lsf_tools_fx.c index 84f43d3cceaaf13ab5ed2b851241e45a048c1bec..99171912ddfe3d37424ed6b8c8aab6c7b4a8390e 100644 --- a/lib_com/lsf_tools_fx.c +++ b/lib_com/lsf_tools_fx.c @@ -2993,7 +2993,8 @@ void msvq_dec maxn = n; move16(); } - + if(maxn % 4) + {n = n; } assert((maxn % 4) == 0); N34 = mult(maxn, 24576/*0.75 Q15*/); diff --git a/lib_com/math_op.c b/lib_com/math_op.c new file mode 100644 index 0000000000000000000000000000000000000000..1ad5a328a597a2d9c7a4424cf62926dba89c523c --- /dev/null +++ b/lib_com/math_op.c @@ -0,0 +1,420 @@ +/*___________________________________________________________________________ + | | + | This file contains mathematic operations in fixed point. | + | | + | Isqrt() : inverse square root (16 bits precision). | + | Pow2() : 2^x (16 bits precision). | + | Log2() : log2 (16 bits precision). | + | Dot_product() : scalar product of | + | | + | In this file, the values use theses representations: | + | | + | Word32 L_32 : standard signed 32 bits format | + | Word16 hi, lo : L_32 = hi<<16 + lo<<1 (DPF - Double Precision Format) | + | Word32 frac, Word16 exp : L_32 = frac << exp-31 (normalised format) | + | Word16 int, frac : L_32 = int.frac (fractional format) | + |___________________________________________________________________________| +*/ + +#include "stl.h" +#include "math_op.h" +#include "rom_basic_math.h" + +#include +#include + +/*___________________________________________________________________________ + | | + | Function Name : Isqrt | + | | + | Compute 1/sqrt(L_x). | + | if L_x is negative or zero, result is 1 (7fffffff). | + |---------------------------------------------------------------------------| + | Algorithm: | + | | + | 1- Normalization of L_x. | + | 2- call Isqrt_lc(L_x, exponant) | + | 3- L_y = L_x << exponant | + |___________________________________________________________________________| +*/ +Word32 Isqrt( /* (o) Q31 : output value (range: 0<=val<1) */ + Word32 L_x /* (i) Q0 : input value (range: 0<=val<=7fffffff) */ +) +{ + Word16 exp; + Word32 L_y; + + exp = norm_l(L_x); + L_x = L_shl(L_x, exp); /* L_x is normalized */ + exp = sub(31, exp); + + L_x = Isqrt_lc(L_x, &exp); + + L_y = L_shl(L_x, exp); /* denormalization */ + + return (L_y); +} + +/*___________________________________________________________________________ + | | + | Function Name : Isqrt_lc | + | | + | Compute 1/sqrt(value). | + | if value is negative or zero, result is 1 (frac=7fffffff, exp=0). | + |---------------------------------------------------------------------------| + | Algorithm: | + | | + | The function 1/sqrt(value) is approximated by a table and linear | + | interpolation. | + | | + | 1- If exponant is odd then shift fraction right once. | + | 2- exponant = -((exponant-1)>>1) | + | 3- i = bit25-b30 of fraction, 16 <= i <= 63 ->because of normalization. | + | 4- a = bit10-b24 | + | 5- i -=16 | + | 6- fraction = table[i]<<16 - (table[i] - table[i+1]) * a * 2 | + |___________________________________________________________________________| +*/ +Word32 Isqrt_lc( + Word32 frac, /* (i) Q31: normalized value (1.0 < frac <= 0.5) */ + Word16 * exp /* (i/o) : exponent (value = frac x 2^exponent) */ +) +{ + Word16 i, a; + Word32 L_tmp; + + IF (frac <= (Word32) 0) + { + *exp = 0; move16(); + return 0x7fffffff; /*0x7fffffff*/ + } + + /* If exponant odd -> shift right by 10 (otherwise 9) */ + L_tmp = L_shr(frac, shift_Isqrt_lc[s_and(*exp, 1)]); + + /* 1) -16384 to shift left and change sign */ + /* 2) 32768 to Add 1 to Exponent like it was divided by 2 */ + /* 3) We let the mac_r add another 0.5 because it imitates */ + /* the behavior of shr on negative number that should */ + /* not be rounded towards negative infinity. */ + /* It replaces: */ + /* *exp = negate(shr(sub(*exp, 1), 1)); move16(); */ + *exp = mac_r(32768, *exp, -16384); move16(); + + a = extract_l(L_tmp); /* Extract b10-b24 */ + a = lshr(a, 1); + + i = mac_r(L_tmp, -16*2-1, 16384); /* Extract b25-b31 minus 16 */ + + L_tmp = L_msu(L_table_isqrt[i], table_isqrt_diff[i], a);/* table[i] << 16 - diff*a*2 */ + + return L_tmp; +} + +/*___________________________________________________________________________ + | | + | Function Name : Pow2() | + | | + | L_x = pow(2.0, exponant.fraction) (exponant = interger part) | + | = pow(2.0, 0.fraction) << exponant | + |---------------------------------------------------------------------------| + | Algorithm: | + | | + | The function Pow2(L_x) is approximated by a table and linear | + | interpolation. | + | | + | 1- i = bit10-b15 of fraction, 0 <= i <= 31 | + | 2- a = bit0-b9 of fraction | + | 3- L_x = table[i]<<16 - (table[i] - table[i+1]) * a * 2 | + | 4- L_x = L_x >> (30-exponant) (with rounding) | + |___________________________________________________________________________| +*/ + +Word32 Pow2( /* (o) Q0 : result (range: 0<=val<=0x7fffffff) */ + Word16 exponant, /* (i) Q0 : Integer part. (range: 0<=val<=30) */ + Word16 fraction /* (i) Q15 : Fractionnal part. (range: 0.0<=val<1.0) */ +) +{ + Word16 exp, i, a; + Word32 L_x; + + + + i = mac_r(-32768, fraction, 32); /* Extract b10-b16 of fraction */ + a = s_and(fraction, 0x3ff); /* Extract b0-b9 of fraction */ + + L_x = L_deposit_h(table_pow2[i]); /* table[i] << 16 */ + L_x = L_mac(L_x, table_pow2_diff_x32[i], a);/* L_x -= diff*a*2 */ + + exp = sub(30, exponant); + + L_x = L_shr_r(L_x, exp); + + + return L_x; +} + +/*___________________________________________________________________________ + | | + | Function Name : Dot_product12() | + | | + | Compute scalar product of using accumulator. | + | | + | The result is normalized (in Q31) with exponent (0..30). | + |---------------------------------------------------------------------------| + | Algorithm: | + | | + | dot_product = sum(x[i]*y[i]) i=0..N-1 | + |___________________________________________________________________________| +*/ + +#ifdef BASOP_NOGLOB +Word32 Dot_product12_o( /* (o) Q31: normalized result (1 < val <= -1) */ + const Word16 x[], /* (i) 12bits: x vector */ + const Word16 y[], /* (i) 12bits: y vector */ + const Word16 lg, /* (i) : vector length */ + Word16* exp, /* (o) : exponent of result (0..+30) */ + Flag* Overflow_out /* o : propagating the Overflow flag to upper level, set to NULL to ignore internal overflows */ +) +#else /* BASOP_NOGLOB */ +Word32 Dot_product12( /* (o) Q31: normalized result (1 < val <= -1) */ + const Word16 x[], /* (i) 12bits: x vector */ + const Word16 y[], /* (i) 12bits: y vector */ + const Word16 lg, /* (i) : vector length */ + Word16 * exp /* (o) : exponent of result (0..+30) */ +) +#endif /* BASOP_NOGLOB */ +{ + Word16 i, sft; + Word32 L_sum; +#ifdef BASOP_NOGLOB + Flag Overflow_ignored = 0; +#endif /* BASOP_NOGLOB */ + +#ifdef BASOP_NOGLOB + L_sum = L_mac_o(1, x[0], y[0], &Overflow_ignored); +#else + L_sum = L_mac(1, x[0], y[0]); +#endif + FOR (i = 1; i < lg; i++) + { +#ifdef BASOP_NOGLOB + L_sum = L_mac_o(L_sum, x[i], y[i], Overflow_out ? Overflow_out : &Overflow_ignored); +#else /* BASOP_NOGLOB */ + L_sum = L_mac(L_sum, x[i], y[i]); +#endif /* BASOP_NOGLOB */ + } + + /* Normalize acc in Q31 */ + + sft = norm_l(L_sum); + L_sum = L_shl(L_sum, sft); + + *exp = sub(30, sft); move16(); /* exponent = 0..30 */ + + return L_sum; +} + +#ifdef BASOP_NOGLOB +Word32 Dot_product12( /* (o) Q31: normalized result (1 < val <= -1) */ + const Word16 x[], /* (i) 12bits: x vector */ + const Word16 y[], /* (i) 12bits: y vector */ + const Word16 lg, /* (i) : vector length */ + Word16 * exp /* (o) : exponent of result (0..+30) */ +) +{ + /* Ignore internal overflows */ + return Dot_product12_o(x, y, lg, exp, NULL); +} +#endif /* BASOP_NOGLOB */ + +/*___________________________________________________________________________ + | | + | Function Name : Energy_scale() | + | | + | Compute energy of signal (scaling the input if specified) | + | | + | The result is normalized (in Q31) with exponent (0..30). | + |___________________________________________________________________________| +*/ + +Word32 Energy_scale( /* (o) : Q31: normalized result (1 < val <= -1) */ + const Word16 x[], /* (i) : input vector x */ + const Word16 lg, /* (i) : vector length */ + Word16 expi, /* (i) : exponent of input */ + Word16 *exp /* (o) : exponent of result (0..+30) */ +) +{ + Word16 i, sft, tmp; + Word32 L_sum; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + + + L_sum = 0; /* just to avoid superflous compiler warning about uninitialized use of L_sum */ + + IF (expi == 0) + { +#ifdef BASOP_NOGLOB + L_sum = L_mac_o(1, x[0], x[0], &Overflow); +#else + L_sum = L_mac(1, x[0], x[0]); +#endif + FOR (i = 1; i < lg; i++) + { +#ifdef BASOP_NOGLOB + L_sum = L_mac_o(L_sum, x[i], x[i], &Overflow); +#else /* BASOP_NOGLOB */ + L_sum = L_mac(L_sum, x[i], x[i]); +#endif + } + } + IF (expi < 0) + { + sft = lshl(-32768 /* 0x8000 */, expi); + tmp = mult_r(x[0], sft); + L_sum = L_mac(1, tmp, tmp); + FOR (i = 1; i < lg; i++) + { + tmp = mult_r(x[i], sft); +#ifdef BASOP_NOGLOB + L_sum = L_mac_o(L_sum, tmp, tmp, &Overflow); +#else + L_sum = L_mac(L_sum, tmp, tmp); +#endif + } + } + IF (expi > 0) + { +#ifdef BASOP_NOGLOB + tmp = shl_o(x[0], expi, &Overflow); + L_sum = L_mac_o(1, tmp, tmp, &Overflow); + FOR (i = 1; i < lg; i++) + { + tmp = shl_o(x[i], expi, &Overflow); + L_sum = L_mac_o(L_sum, tmp, tmp, &Overflow); + } +#else + tmp = shl(x[0], expi); + L_sum = L_mac(1, tmp, tmp); + FOR (i = 1; i < lg; i++) + { + tmp = shl(x[i], expi); + L_sum = L_mac(L_sum, tmp, tmp); + } +#endif + } + + /* Normalize acc in Q31 */ + + sft = norm_l(L_sum); + L_sum = L_shl(L_sum, sft); + + *exp = sub(30, sft); move16(); /* exponent = 0..30 */ + + + return L_sum; +} + +Word32 Sqrt_l( /* o : output value, Q31 */ + Word32 L_x, /* i : input value, Q31 */ + Word16 *exp /* o : right shift to be applied to result, Q1 */ +) +{ + /* + y = sqrt(x) + + x = f * 2^-e, 0.5 <= f < 1 (normalization) + + y = sqrt(f) * 2^(-e/2) + + a) e = 2k --> y = sqrt(f) * 2^-k (k = e div 2, + 0.707 <= sqrt(f) < 1) + b) e = 2k+1 --> y = sqrt(f/2) * 2^-k (k = e div 2, + 0.5 <= sqrt(f/2) < 0.707) + */ + + Word16 e, i, a, tmp; + Word32 L_y; + + if (L_x <= 0) + { + *exp = 0; move16 (); + return L_deposit_l(0); + } + + e = s_and(norm_l(L_x), 0x7FFE); /* get next lower EVEN norm. exp */ + L_x = L_shl(L_x, e); /* L_x is normalized to [0.25..1) */ + *exp = e; move16 (); /* return 2*exponent (or Q1) */ + + L_x = L_shr(L_x, 9); + a = extract_l(L_x); /* Extract b10-b24 */ + a = lshr(a, 1); + + i = mac_r(L_x, -16*2-1, 16384); /* Extract b25-b31 minus 16 */ + + L_y = L_deposit_h(sqrt_table[i]); /* table[i] << 16 */ + tmp = sub(sqrt_table[i], sqrt_table[i + 1]); /* table[i] - table[i+1]) */ + L_y = L_msu(L_y, tmp, a); /* L_y -= tmp*a*2 */ + + /* L_y = L_shr (L_y, *exp); */ /* denormalization done by caller */ + + return (L_y); +} + +/*---------------------------------------------------------------------------* + * L_Frac_sqrtQ31 + * + * Calculate square root from fractional values (Q31 -> Q31) + * Uses 32 bit internal representation for precision + *---------------------------------------------------------------------------*/ +Word32 L_Frac_sqrtQ31( /* o : Square root if input */ + const Word32 x /* i : Input */ +) +{ + Word32 log2_work; + Word16 log2_int, log2_frac; + + test(); + if (x > 0) + { + log2_int = norm_l(x); + log2_frac = Log2_norm_lc(L_shl(x, log2_int)); + + log2_work = L_msu((31+30)*65536L/2, 16384, log2_int); + log2_work = L_mac0(log2_work, log2_frac, 1); + + log2_frac = L_Extract_lc(log2_work, &log2_int); + + return Pow2(log2_int, log2_frac); + } + return 0; +} + +/*----------------------------------------------------------------------------------* + * Frac_sqrt + * + * Calculate square root from fractional values (Q15 -> Q15) + *----------------------------------------------------------------------------------*/ +Word16 Frac_sqrt( /* o : Square root if input */ + const Word16 x /* i : Input */ +) +{ + return round_fx(L_Frac_sqrtQ31(L_deposit_h(x))); +} + + +/*----------------------------------------------------------------------------------* + * i_mult2 + * + * Faster Integer Multiplication + *----------------------------------------------------------------------------------*/ + +Word16 i_mult2 (Word16 a, Word16 b) +{ + return extract_l(L_mult0(a, b)); +} + + + diff --git a/lib_com/modif_fs_fx.c b/lib_com/modif_fs_fx.c index 3c0de0a191a7b4f3b1cd77f05fc09757e12aa896..717c8bbb233ff73aac81da52e53d7adfc4384668 100644 --- a/lib_com/modif_fs_fx.c +++ b/lib_com/modif_fs_fx.c @@ -446,7 +446,7 @@ Word16 modify_Fs_intcub3m_sup_fx( /* o : length of output */ } } - ctptr = &(ct2[cind][0]); + ctptr = &(ct2_fx[cind][0]); lg_out = mult_r(shl(lg,2),ctptr[13]); *delayout = ctptr[9]; move16(); diff --git a/lib_com/mslvq_com.c b/lib_com/mslvq_com.c index 48384794aa4f882d3d0eaaa861ca9de8c66cd931..e52c137f27042933522b4c33eff584c5e2e098cc 100644 --- a/lib_com/mslvq_com.c +++ b/lib_com/mslvq_com.c @@ -327,7 +327,7 @@ int16_t deindex_lvq_cng( int16_t mode_glb, mode; int16_t ber_flag; - mode_glb = START_CNG + idx_cv; + mode_glb = START_CNG_IVAS + idx_cv; mode = LVQ_COD_MODES + idx_cv; p_scales = &scales[0][0]; diff --git a/lib_com/options.h b/lib_com/options.h index 179fd9aeba3d78d5a9fb5d543136a70c003927d3..13c4c11a1a091b308021a5a7d153e75f242eec70 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -87,7 +87,16 @@ #define NONBE_FIX_849_OMASA_BFI_CRASH /* VA: issue 849: fix OMASA 2TC and FEC crashes */ #define IVAS_FLOAT_FIXED +#define EVS_FLOAT //#define DUMPS_ENABLED +#define IVAS_CNST +#define REMOVE_IVAS_UNUSED_PARAMETERS_WARNING /*temporary operation on unused EVS parameters to remove warnings, these parameters will be used in IVAS */ + +#define MOD_BIT_ALLOC_ROM_TABLE // Just to highlight modification in bit allocation table and to ensure these modifications doesn't affect EVS modes*/ +#define SIMPLIFY_CODE_BE // Simplify synthesis loop + +#define CR_2109_to_2112_cd0_ce0 /* This is related to the CRs include in the 26.444 package of 21-12. Concerns lead_deindexing and */ + /* ##################### End NON-BE switches ########################### */ /* ################## End DEVELOPMENT switches ######################### */ diff --git a/lib_com/phase_dispersion.c b/lib_com/phase_dispersion.c index eeecc7aaa0d8b61882138313c33ae775fb059811..550c877e1837cf0bc08ba311cd1aa39805bdda88 100644 --- a/lib_com/phase_dispersion.c +++ b/lib_com/phase_dispersion.c @@ -42,12 +42,12 @@ #include "wmc_auto.h" /*-----------------------------------------------------------------------* - * phase_dispersion() + * phase_dispersion_flt() * * Post-processing to enhance noise at low bitrate *-----------------------------------------------------------------------*/ -void phase_dispersion( +void phase_dispersion_flt( const float gain_code, /* i : gain of code */ const float gain_pit, /* i : gain of pitch */ float code[], /* i/o: code vector */ @@ -123,12 +123,12 @@ void phase_dispersion( if ( state == 0 ) { - mvr2r( low_H, h_disp, L_SUBFR ); + mvr2r( low_H_flt, h_disp, L_SUBFR ); } if ( state == 1 ) { - mvr2r( mid_H, h_disp, L_SUBFR ); + mvr2r( mid_H_flt, h_disp, L_SUBFR ); } code2_real = code2; diff --git a/lib_com/phase_dispersion_fx.c b/lib_com/phase_dispersion_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..6874b790ca1b9c366f61d25b8037b9d9d8b92e12 --- /dev/null +++ b/lib_com/phase_dispersion_fx.c @@ -0,0 +1,186 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include +#include "options.h" /* EV-VBR compilation switches */ +#include "prot_fx1.h" +#include "prot_fx2.h" +#include "basop_util.h" +#include "rom_com.h" + +/*-----------------------------------------------------------------------* + * phase_dispersion: + * + * post-processing to enhance noise at low bit rate. + *-----------------------------------------------------------------------*/ + +void phase_dispersion( + const Word32 gain_code, /* i : gain of code 15Q16 */ + const Word16 gain_pit, /* i : gain of pitch Q14 */ + Word16 code[], /* i/o: code vector */ + Word16 *code_exp, /* i/o: exponent of code */ + const Word16 mode, /* i : level, 0=hi, 1=lo, 2=off */ + Word32 *prev_gain_code, /* i/o: static memory 15Q16 */ + Word16 prev_gain_pit[], /* i/o: static memory Q14, size=6 */ + Word16 *prev_state, /* i/o: static memory Q0 */ + Word16 L_subfr /* i : subframe length [40,64,80]*/ +) +{ + Word16 i, j, state, scale2; + Word32 x32[2*L_SUBFR]; + Word16 *code_real, *code_imag; + const Word16 *h_real, *h_imag; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + + + move16(); + state = 2; + + if ( LT_16(gain_pit,14746/*0.9f Q14*/)) + { + move16(); + state = 1; + } + if ( LT_16(gain_pit, 9830/*0.6f Q14*/)) + { + move16(); + state = 0; + } + + FOR (i=5; i>0; i--) + { + move16(); + prev_gain_pit[i] = prev_gain_pit[i-1]; + } + move16(); + prev_gain_pit[0] = gain_pit; + +#ifdef BASOP_NOGLOB + IF ( GT_32(gain_code, L_add_o(*prev_gain_code, L_shl_o(*prev_gain_code,1, &Overflow), &Overflow))) +#else + IF ( GT_32(gain_code, L_add(*prev_gain_code, L_shl(*prev_gain_code,1)))) +#endif + { + if (LT_16(state,2)) + { + state = add(state, 1); + } + } + ELSE + { + j=0; + FOR (i=0; i<6; i++) + { + + if ( LT_32(prev_gain_pit[i], 9830/*0.6f Q14*/)) + { + j = add(j,1); + } + } + + if (GT_16(j,2)) + { + move16(); + state = 0; + } + + if ( GT_16(sub(state, *prev_state),1)) + { + state = sub(state,1); + } + } + + move32(); + move16(); + *prev_gain_code = gain_code; + *prev_state = state; + + /*-----------------------------------------------------------------* + * circular convolution + *-----------------------------------------------------------------*/ + + state = add(state, mode); /* level of dispersion */ + j = *code_exp; + move16(); + IF( LT_16(state,2)) + { + FOR(i=0; i +#include "options.h" /* Compilation switches */ +#include "cnst.h" /* Common constants */ +#include "rom_com.h" /* Static table prototypes */ +#include "prot_fx1.h" /* Function prototypes */ +#include "prot_fx2.h" /* Function prototypes */ + + +/*-------------------------------------------------------------------* + * Function pred_lt4: * + * ~~~~~~~~~ * + *-------------------------------------------------------------------* + * Compute the result of long term prediction with fractional * + * interpolation of resolution 1/4. * + * * + * On return exc[0..L_subfr-1] contains the interpolated signal * + * (adaptive codebook excitation) * + *-------------------------------------------------------------------*/ + +void pred_lt4( + const Word16 excI[], /* in : excitation buffer */ + Word16 excO[], /* out: excitation buffer */ + const Word16 T0, /* input : integer pitch lag */ + Word16 frac, /* input : fraction of lag */ + const Word16 L_subfr, /* input : subframe size */ + const Word16 *win, /* i : interpolation window */ + const Word16 nb_coef, /* i : nb of filter coef */ + const Word16 up_sample /* i : up_sample */ +) +{ + Word16 i, j; + Word32 s; + const Word16 *x0, *x1, *x2, *c1, *c2; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + x0 = &excI[-T0]; + + + frac = negate(frac); + + IF ( frac < 0 ) + { + frac = add(frac,up_sample); + x0--; + } + + FOR (j=0; j 0) + { + frac = sub(frac,UP_SAMP); + x0--; + } + + l = add(UP_SAMP-1, frac); + FOR (j = T0; j < L_SUBFR+1; j++) + { + k = l; + move16(); + L_sum = L_mult(x0[0], win[k]); + FOR (i = 1; i < 2 * L_INTERPOL2; i++) + { + /* + * Here, additions with UP_SAMP are not counted + ki* because, the window could easily be modified + * so that the values needed are contiguous. + */ + k += UP_SAMP; + L_sum = L_mac(L_sum, x0[i], win[k]); /*Q1 */ + } +#ifdef BASOP_NOGLOB + L_sum = L_shl_o(L_sum, 1, &Overflow); /*Q0h */ + excO[j] = round_fx_o(L_sum, &Overflow); +#else + L_sum = L_shl(L_sum, 1); /*Q0h */ + + excO[j] = round_fx(L_sum); +#endif + + x0++; + } + FOR (i = T0; i < L_SUBFR; i++) + { +#ifdef BASOP_NOGLOB + exc[i+i_subfr] = add_o(exc[i+i_subfr], mult_r(PIT_SHARP_fx, excO[i]), &Overflow); +#else + exc[i+i_subfr] = add(exc[i+i_subfr], mult_r(PIT_SHARP_fx, excO[i])); +#endif + move16(); + } + } + + return; + +} diff --git a/lib_com/prot.h b/lib_com/prot.h index 3a787397cc62c7be6714dccbb999b2a0f6c53ee3..01a76d256816dbb03a7d56a5c9e4dde528f77e30 100644 --- a/lib_com/prot.h +++ b/lib_com/prot.h @@ -686,7 +686,7 @@ float lsf_stab( const int16_t L_frame /* i : frame length */ ); -void amr_wb_dec_init( +void amr_wb_dec_init_flt( AMRWB_IO_DEC_HANDLE hAmrwb_IO /* i/o: AMR-WB IO data handle */ ); @@ -764,15 +764,6 @@ int16_t lsp_convert_poly( const int16_t L_frame, /* i : flag for up or down conversion */ const int16_t Opt_AMRWB /* i : flag for the AMR-WB IO mode */ ); - -#ifdef IVAS_FLOAT_FIXED -Word16 lsp_convert_poly_fx( - Word16 w[], /* i/o: LSP or ISP parameters */ - const Word16 L_frame, /* i : flag for up or down conversion */ - const Word16 Opt_AMRWB /* i : flag for the AMR-WB IO mode */ -); -#endif - /*! r: pulse position */ int16_t findpulse( const int16_t L_frame, /* i : length of the frame */ @@ -939,7 +930,7 @@ void calculate_hangover_attenuation_gain( const int16_t vad_hover_flag /* i : VAD hangover flag */ ); -int16_t get_cng_mode( +int16_t get_cng_mode_ivas( const int32_t last_active_brate /* i : last active bitrate */ ); @@ -1061,7 +1052,7 @@ int16_t modify_Fs( const int16_t nblp /* i : flag indicating if NB low-pass is applied */ ); -void pred_lt4( +void pred_lt4_flt( const float excI[], /* i : input excitation buffer */ float excO[], /* o : output excitation buffer */ const int16_t T0, /* i : integer pitch lag */ @@ -1072,7 +1063,7 @@ void pred_lt4( const int16_t up_sample /* i : up_sample */ ); -void pred_lt4_tc( +void pred_lt4_tc_flt( float exc[], /* i : excitation buffer */ const int16_t T0, /* i : integer pitch lag */ int16_t frac, /* i : fraction of lag */ @@ -1203,7 +1194,7 @@ int16_t lsf_bctcvq_encprm( const int16_t *bits_param_lpc, const int16_t no_indices ); -int16_t lsf_bctcvq_decprm( +int16_t lsf_bctcvq_decprm_ivas( Decoder_State *st, int16_t *param_lpc ); @@ -1262,7 +1253,7 @@ void enhancer( float *dispMem /* i/o: Phase dispersion algorithm memory */ ); -void phase_dispersion( +void phase_dispersion_flt( const float gain_code, /* i : gain of code */ const float gain_pit, /* i : gain of pitch */ float code[], /* i/o: code vector */ @@ -1353,7 +1344,7 @@ void DoRTFTn( const int16_t n /* i : size of the FFT n=(2^k) up to 1024 */ ); -void BASOP_cfft( +void BASOP_cfft_ivas( Word32 *re, /* i/o: real part */ Word32 *im, /* i/o: imag part */ Word16 s, /* i : stride real and imag part */ @@ -1935,7 +1926,7 @@ void get_max_pulses( int16_t *maxpulse /* o : Maximum pulse height per band */ ); -Word32 ar_div( +Word32 ar_div_ivas( Word32 num, Word32 denum ); @@ -1978,14 +1969,14 @@ Word32 Mult_32_32( Word32 a, Word32 b ); -void decode_position_ari_fx( +void decode_position_ari_fx_ivas( PARCODEC pardec, Word16 size, Word16 npulses, Word16 *nz, Word32 *position ); -void decode_magnitude_usq_fx( +void decode_magnitude_usq_fx_ivas( ARCODEC *pardec, Word16 size, Word16 npulses, @@ -1993,7 +1984,7 @@ void decode_magnitude_usq_fx( Word32 *positions, Word32 *out ); -void decode_mangitude_tcq_fx( +void decode_mangitude_tcq_fx_ivas( ARCODEC *pardec, Word16 size, Word16 npulses, @@ -2002,18 +1993,18 @@ void decode_mangitude_tcq_fx( Word32 *out, Word32 *surplus_fx ); -void decode_signs_fx( +void decode_signs_fx_ivas( ARCODEC *pardec, Word16 size, Word32 *out ); -void srt_vec_ind_fx( +void srt_vec_ind_fx_ivas( const Word32 *linear, Word32 *srt, Word16 *I, Word16 length ); -Word16 GetScale_fx( +Word16 GetScale_fx_ivas( Word16 blen, Word32 bits_fx /*Q16*/, Word32 *surplus_fx /*Q16*/ @@ -2031,13 +2022,13 @@ void bit_allocation_second_fx2( const Word16 *last_bitalloc, const Word16 input_frame ); -Word32 encode_position_ari_fx( +Word32 encode_position_ari_fx_ivas( PARCODEC parenc, float *quants, Word16 size, Word32 *est_bits_frame_fx ); -Word32 encode_magnitude_tcq_fx( +Word32 encode_magnitude_tcq_fx_ivas( ARCODEC *parenc, float *magn_fx, Word16 size, @@ -2046,14 +2037,14 @@ Word32 encode_magnitude_tcq_fx( Word32 *savedstates, Word32 *est_frame_bits_fx ); -Word32 encode_signs_fx( +Word32 encode_signs_fx_ivas( ARCODEC *parenc, float *magn, Word16 size, Word16 npos, Word32 *est_frame_bits_fx ); -Word32 encode_magnitude_usq_fx( +Word32 encode_magnitude_usq_fx_ivas( ARCODEC *parenc, float *magn_fx, Word16 size, @@ -2421,7 +2412,7 @@ void calc_st_filt( const int16_t extl /* i : extension layer info */ ); -void scale_st( +void scale_st_ivas( const float *sig_in, /* i : postfilter input signal */ float *sig_out, /* i/o: postfilter output signal */ float *gain_prec, /* i/o: last value of gain for subframe */ @@ -2745,7 +2736,7 @@ void wb_bwe_enc( const float *new_wb_speech /* i : original input signal at 16kHz */ ); -void wb_bwe_dec( +void wb_bwe_dec_flt( Decoder_State *st, /* i/o: decoder state structure */ const float output[], /* i : synthesis @internal Fs */ float *synth, /* i/o: ACELP core synthesis/final synthesis */ @@ -2773,11 +2764,11 @@ void swb_bwe_enc_hr( const int16_t unbits /* i : number of core unused bits */ ); -void fd_bwe_dec_init( +void fd_bwe_dec_init_flt( FD_BWE_DEC_HANDLE hBWE_FD /* i/o: FD BWE data handle */ ); -void swb_bwe_dec( +void swb_bwe_dec_flt( Decoder_State *st, /* i/o: decoder state structure */ const float output[], /* i : synthesis @internal Fs */ const float *synth, /* i : ACELP core synthesis/final synthesis */ @@ -2786,7 +2777,7 @@ void swb_bwe_dec( const int16_t output_frame /* i : frame length */ ); -void hr_bwe_dec_init( +void hr_bwe_dec_init_flt( HR_BWE_DEC_HANDLE hBWE_FD_HR /* i/o: HR BWE data handle */ ); @@ -3388,7 +3379,7 @@ void freq_dnw_scaling( const int16_t L_frame /* i : frame length */ ); -void GSC_dec_init( +void GSC_dec_init_ivas( GSC_DEC_HANDLE hGSCDec /* i/o: GSC data handle */ ); @@ -3482,7 +3473,7 @@ void inact_switch_ematch( const int16_t element_mode /* i : element mode */ ); -void music_postfilt_init( +void music_postfilt_init_flt( MUSIC_POSTFILT_HANDLE hMusicPF /* i/o: LD music postfilter handle */ ); @@ -4514,7 +4505,7 @@ void updt_dec_common( const float *synth /* i : decoded synthesis */ ); -void td_cng_dec_init( +void td_cng_dec_init_flt( DEC_CORE_HANDLE st /* i/o: decoder state structure */ ); @@ -4638,7 +4629,7 @@ float gain_dec_gaus( ); /*! r: floating pitch value */ -float pit_decode( +float pit_decode_flt( Decoder_State *st, /* i/o: decoder state structure */ const int32_t core_brate, /* i : core bitrate */ const int16_t Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ @@ -4655,7 +4646,7 @@ float pit_decode( const float tdm_Pri_pitch_buf[] /* i : primary channel pitch buffer */ ); -void abs_pit_dec( +void abs_pit_dec_flt( const int16_t fr_steps, /* i : fractional resolution steps (0, 2, 4) */ int16_t pitch_index, /* i : pitch index */ const int16_t limit_flag, /* i : restrained(0) or extended(1) Q limits */ @@ -4663,7 +4654,7 @@ void abs_pit_dec( int16_t *T0_frac /* o : pitch fraction */ ); -void delta_pit_dec( +void delta_pit_dec_flt( const int16_t fr_steps, /* i : fractional resolution steps (0, 2, 4) */ const int16_t pitch_index, /* i : pitch index */ int16_t *T0, /* o : integer pitch lag */ @@ -4671,7 +4662,7 @@ void delta_pit_dec( const int16_t T0_min /* i : delta search min */ ); -void pit_Q_dec( +void pit_Q_dec_flt( const int16_t Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ const int16_t pitch_index, /* i : pitch index */ const int16_t nBits, /* i : # of Q bits */ @@ -4685,7 +4676,7 @@ void pit_Q_dec( int16_t *BER_detect /* o : BER detect flag */ ); -void pit16k_Q_dec( +void pit16k_Q_dec_flt( const int16_t pitch_index, /* i : pitch index */ const int16_t nBits, /* i : # of Q bits */ const int16_t limit_flag, /* i : restrained(0) or extended(1) Q limits */ @@ -4758,7 +4749,7 @@ void FEC_exc_estim( float *tmp_noise /* o : long-term noise energy */ ); -void FEC_lsf2lsp_interp( +void FEC_lsf2lsp_interp_flt( Decoder_State *st, /* i/o: Decoder static memory */ const int16_t L_frame, /* i : length of the frame */ float *Aq, /* o : calculated A(z) for 4 subframes */ @@ -4917,7 +4908,7 @@ void stat_noise_uv_dec( const int16_t uc_two_stage_flag /* 1 : flag undicating two-stage UC */ ); -void sc_vbr_dec_init( +void sc_vbr_dec_init_flt( SC_VBR_DEC_HANDLE hSC_VBR /* i/o: SC-VBR decoder handle */ ); @@ -4997,11 +4988,11 @@ void re8_decode_base_index( int16_t *x /* o : point in RE8 (8-dimensional integer vector) */ ); -void Init_post_filter( +void Init_post_filter_ivas( PFSTAT_HANDLE hPFstat /* i : post-filter state memories */ ); -void nb_post_filt( +void nb_post_filt_ivas( const int16_t L_frame, /* i : frame length */ const int16_t L_subfr, /* i : sub-frame length */ PFSTAT_HANDLE hPFstat, /* i/o: Post filter related memories */ @@ -5080,19 +5071,19 @@ ivas_error init_decoder( const MC_MODE mc_mode /* i : MC mode */ ); -void destroy_cldfb_decoder( +void destroy_cldfb_decoder_flt( Decoder_State *st /* o : Decoder static variables structure */ ); -void HQ_core_dec_init( +void HQ_core_dec_init_flt( HQ_DEC_HANDLE hHQ_core /* i/o: HQ core data handle */ ); -void HQ_nbfec_init( +void HQ_nbfec_init_flt( HQ_NBFEC_HANDLE hHQ_nbfec /* i/o: HQ NB FEC data handle */ ); -ivas_error evs_dec( +ivas_error evs_dec_flt( Decoder_State *st, /* i/o: Decoder state structure */ float mem_hp20_out[L_HP20_MEM], /* i/o: HP filter memory for synthesis */ float *output, /* o : output synthesis signal */ @@ -5103,7 +5094,7 @@ void get_next_frame_parameters( Decoder_State *st /* i/o: Decoder state structure */ ); -ivas_error amr_wb_dec( +ivas_error amr_wb_dec_flt( Decoder_State *st, /* i/o: decoder state structure */ float mem_hp20_out[L_HP20_MEM], /* i/o: HP filter memory for synthesis */ float *output /* o : synthesis output */ @@ -5285,7 +5276,7 @@ void hq_generic_hf_encoding( ); /*! r: BWE class */ -int16_t swb_bwe_gain_deq( +int16_t swb_bwe_gain_deq_flt( Decoder_State *st, /* i/o: decoder state structure */ const int16_t core, /* i : core */ float *SWB_tenv, /* o : time-domain BWE envelope */ @@ -5322,7 +5313,7 @@ void hq_core_dec( float *output /* o : LB synthesis in case of ACELP-HQ switch */ ); -void IMDCT( +void IMDCT_flt( float *x, float *old_syn_overl, float *syn_Overl_TDAC, @@ -6495,7 +6486,7 @@ void ifft3( ); /*! r: updated estimate of background noise */ -void minimumStatistics( +void minimumStatistics_flt( float *noiseLevelMemory, /* i/o: internal state */ int16_t *noiseLevelIndex, /* i/o: internal state */ int16_t *currLevelIndex, /* i/o: internal state (circular buffer) */ @@ -6624,19 +6615,19 @@ void fcb_pulse_track_joint( const int16_t *pulse_num, const int16_t track_num ); -void D_ACELP_indexing( +void D_ACELP_indexing_ivas( float code[], PulseConfig config, const int16_t num_tracks, int16_t prm[], int16_t *BER_detect ); -void D_ACELP_decode_43bit( +void D_ACELP_decode_43bit_flt( uint16_t idxs[], float code[], int16_t *pulsestrack ); -void fcb_pulse_track_joint_decode( +void fcb_pulse_track_joint_decode_ivas( uint16_t *idxs, const int16_t wordcnt, uint32_t *index_n, @@ -6664,7 +6655,7 @@ void hp20_flt( Float32 mem[], const Word32 Fs ); -void ham_cos_window( +void ham_cos_window_flt( float *fh, const int16_t n1, const int16_t n2 ); @@ -6703,13 +6694,13 @@ void enc_acelp_tcx_main( const int16_t vad_hover_flag /* i : VAD hangover flag */ ); -void getTCXMode( +void getTCXMode_ivas( Decoder_State *st, /* i/o: decoder memory state */ Decoder_State *st0, /* i : bitstream */ const int16_t MCT_flag /* i : hMCT handle allocated (1) or not (0)*/ ); -void getTCXWindowing( +void getTCXWindowing_ivas( const int16_t core, /* i : current frame mode */ const int16_t last_core, /* i : last frame mode */ const int16_t element_mode, /* i : element mode */ @@ -6717,7 +6708,7 @@ void getTCXWindowing( Decoder_State *st0 /* i : bitstream */ ); -void getLPCparam( +void getLPCparam_ivas( Decoder_State *st, /* i/o: decoder memory state */ int16_t param_lpc[], /* o : LTP parameters */ Decoder_State *st0, /* i : bitstream */ @@ -6725,7 +6716,7 @@ void getLPCparam( const int16_t sns_low_br_mode /* i : SNS low-bitrate mode */ ); -void getTCXparam( +void getTCXparam_ivas( Decoder_State *st, /* i/o: Decoder State handle */ Decoder_State *st0, /* i : bitstream */ CONTEXT_HM_CONFIG hm_cfg, /* i/o: HM config */ @@ -6737,7 +6728,7 @@ void getTCXparam( int16_t nTnsBitsTCX10[2], const int16_t pre_past_flag ); -void pitch_pred_linear_fit( +void pitch_pred_linear_fit_flt( const int16_t nbLostCmpt, /* i : bfi counter */ const int16_t last_good, /* i : last classification type */ float *old_pitch_buf, /* i : pitch lag buffer */ @@ -6752,7 +6743,7 @@ void pitch_pred_linear_fit( const int16_t nb_subfr /* i : number of ACELP subframes */ ); -void get_subframe_pitch( +void get_subframe_pitch_flt( const int16_t nSubframes, /* i : number of subframes */ float pitchStart, /* i : starting pitch lag (in subframe -1) */ float pitchEnd, /* i : ending pitch lag (in subframe nSubframes-1) */ @@ -6867,7 +6858,7 @@ int16_t Mode2_gain_enc_mless( const int16_t coder_type /* i : type of coder */ ); -void decode_acelp_gains( +void decode_acelp_gains_flt( const float *code, const int16_t gains_mode, const float mean_ener_code, @@ -6881,7 +6872,7 @@ void decode_acelp_gains( float *code2, float *gain_code2 ); -void gain_dec_gacelp_uv( +void gain_dec_gacelp_uv_flt( int16_t index, /* i/o: Quantization index vector */ const float *code, /* i : algebraic code excitation */ const float *code2, /* i : algebraic code excitation */ @@ -6917,7 +6908,7 @@ void Mode2_pit_encode( const int16_t pit_max, const int16_t pit_res_max ); -void limit_T0_voiced( +void limit_T0_voiced_ivas( const int16_t nbits, const int16_t res, const int16_t T0, /* i : rough pitch estimate around which the search is done */ @@ -6950,7 +6941,7 @@ void Mode2_delta_pit_enc( ); /*! r: floating pitch value */ -float Mode2_pit_decode( +float Mode2_pit_decode_flt( const int16_t coder_type, /* i : coding model */ const int16_t i_subfr, /* i : subframe index */ const int16_t L_subfr, /* i : sub-frame length */ @@ -6969,7 +6960,7 @@ float Mode2_pit_decode( const int16_t pit_max, const int16_t pit_res_max ); -void Mode2_abs_pit_dec( +void Mode2_abs_pit_dec_flt( int16_t *T0, /* o : integer pitch lag */ int16_t *T0_frac, /* o : pitch fraction */ int16_t *T0_res, /* o : pitch resolution */ @@ -6979,7 +6970,7 @@ void Mode2_abs_pit_dec( const int16_t pit_fr2, const int16_t pit_res_max ); -void Mode2_delta_pit_dec( +void Mode2_delta_pit_dec_flt( int16_t *T0, /* o : integer pitch lag */ int16_t *T0_frac, /* o : pitch fraction */ int16_t T0_res, /* i : pitch resolution */ @@ -6988,7 +6979,7 @@ void Mode2_delta_pit_dec( int16_t **pt_indice /* i/o: pointer to Vector of Q indexes */ ); -void formant_post_filt( +void formant_post_filt_ivas( PFSTAT_HANDLE hPFstat, /* i/o: Post filter related memories */ float *synth_in, /* i : 12k8 synthesis */ const float *Aq, /* i : LP filter coefficient */ @@ -7020,14 +7011,14 @@ int16_t encode_lpc_avq( const int16_t element_mode /* i : element mode */ ); -int16_t dlpc_avq( +int16_t dlpc_avq_flt( int16_t *index, /* i : Quantization indices */ float *LSF_Q, /* o : Quantized LSF vectors */ const int16_t numlpc, /* i : Number of sets of lpc */ const int32_t sr_core /* i : internal sampling rate */ ); -int16_t decode_lpc_avq( +int16_t decode_lpc_avq_flt( Decoder_State *st, /* i/o: decoder state structure */ const int16_t numlpc, /* i : Number of sets of lpc */ int16_t *param_lpc, /* o : lpc parameters */ @@ -7053,27 +7044,27 @@ int16_t vlpc_2st_cod( const int32_t sr_core /* i : internal sampling rate */ ); -void vlpc_2st_dec( +void vlpc_2st_dec_flt( float *lsfq, /* i/o: i:1st stage o:1st+2nd stage */ int16_t *indx, /* i : index[] (4 bits per words) */ const int16_t mode, /* i : 0=abs, >0=rel */ const int32_t sr_core /* i : internal sampling rate */ ); -void lsf_weight_2st( +void lsf_weight_2st_flt( const float *lsfq, float *w, const int16_t mode, const int32_t sr_core ); -void mdct_window_sine( +void mdct_window_sine_flt( float *window, const int32_t Fs, const int16_t n, const int16_t window_type, const int16_t element_mode ); -void mdct_window_aldo( +void mdct_window_aldo_flt( float *window1, float *window2, const int16_t n ); @@ -7085,18 +7076,18 @@ void AVQ_cod_lpc( const int16_t Nsv /* i : number of subvectors (lg=Nsv*8) */ ); -void AVQ_dec_lpc( +void AVQ_dec_lpc_ivas( const int16_t indx[], /* i : index[] (4 bits per words) */ int16_t nvecq[], /* o : vector quantized */ const int16_t Nsv /* i : number of subvectors (lg=Nsv*8) */ ); -void vlpc_1st_dec( +void vlpc_1st_dec_flt( const int16_t index, /* i : codebook index */ float *lsfq, /* i/o: i:prediction o:quantized lsf */ const int32_t sr_core ); -void WindowSignal( +void WindowSignal_flt( TCX_CONFIG_HANDLE hTcxCfg, /* i : configuration of TCX */ int16_t offset, /* i : left folding point offset relative to the input signal pointer */ const int16_t left_overlap_mode, /* i : overlap mode of left window half */ @@ -7167,7 +7158,7 @@ void QuantizeSpectrum( ); /*! r: index of next coefficient */ -int16_t get_next_coeff_mapped( +int16_t get_next_coeff_mapped_ivas( int16_t ii[2], /* i/o: coefficient indexes */ int32_t *pp, /* o : peak(1)/hole(0) indicator */ int16_t *idx, /* o : index in unmapped domain */ @@ -7175,12 +7166,12 @@ int16_t get_next_coeff_mapped( ); /*! r: index of next coefficient */ -int16_t get_next_coeff_unmapped( +int16_t get_next_coeff_unmapped_ivas( int16_t *ii, /* i/o: coefficient index */ int16_t *idx /* o : index in unmapped domain */ ); -int32_t update_mixed_context( +int32_t update_mixed_context_ivas( int32_t ctx, int16_t a ); @@ -7193,7 +7184,7 @@ void ACcontextMapping_encode2_no_mem_s17_LC( int16_t resQMaxBits, CONTEXT_HM_CONFIG *hm_cfg ); -int16_t ACcontextMapping_decode2_no_mem_s17_LC( +int16_t ACcontextMapping_decode2_no_mem_s17_LC_ivas( Decoder_State *st, /* i/o: decoder state */ int16_t *x, /* o : decoded spectrum */ int16_t nt, /* i : size of spectrum */ @@ -7252,7 +7243,7 @@ int16_t RCcontextMapping_encode2_estimate_bandWise( const int16_t end_line, HANDLE_RC_CONTEXT_MEM hContextMem ); -void tcx_get_windows( +void tcx_get_windows_flt( TCX_CONFIG_HANDLE hTcxCfg, /* i : TCX configuration */ const int16_t left_mode, /* i : overlap mode of left window half */ const int16_t right_mode, /* i : overlap mode of right window half */ @@ -7263,7 +7254,7 @@ void tcx_get_windows( const int16_t fullband /* i : fullband flag */ ); -void tcx_windowing_analysis( +void tcx_windowing_analysis_flt( const float *signal, /* i : signal vector */ const int16_t L_frame, /* i : frame length */ const int16_t left_overlap, /* i : left overlap length */ @@ -7273,7 +7264,7 @@ void tcx_windowing_analysis( float *output /* o : windowed signal vector */ ); -void tcx_windowing_synthesis_current_frame( +void tcx_windowing_synthesis_current_frame_flt( float *signal, /* i/o: signal vector */ const float *window, /* i : TCX window vector */ const float *window_half, /* i : TCX window vector for half-overlap window */ @@ -7294,7 +7285,7 @@ void tcx_windowing_synthesis_current_frame( const int16_t last_is_cng, const int16_t fullbandScale ); -void tcx_windowing_synthesis_past_frame( +void tcx_windowing_synthesis_past_frame_flt( float *signal, /* i/o: signal vector */ const float *window, /* i : TCX window vector */ const float *window_half, /* i : TCX window vector for half-overlap window */ @@ -7341,7 +7332,7 @@ void AnalyzePowerSpectrum( float powerSpec[] /* o : Power spectrum */ ); -void lpc2mdct( +void lpc2mdct_flt( float *lpcCoeffs, const int16_t lpcOrder, float mdct_gains[], @@ -7353,7 +7344,7 @@ void mdct_preShaping( const int16_t lg, const float gains[] ); -void mdct_noiseShaping( +void mdct_noiseShaping_flt( float x[], const int16_t lg, const float gains[], @@ -7371,12 +7362,12 @@ void PsychAdaptLowFreqEmph( float x[], const float lpcGains[] ); -void PsychAdaptLowFreqDeemph( +void PsychAdaptLowFreqDeemph_flt( float x[], const float lpcGains[], float lf_deemph_factors[] ); -void AdaptLowFreqDeemph( +void AdaptLowFreqDeemph_flt( float x[], int16_t tcx_lpc_shaped_ari, const float lpcGains[], @@ -7445,7 +7436,7 @@ void tcx_noise_factor( const int16_t element_mode /* i : IVAS element mode */ ); -void tcx_noise_filling( +void tcx_noise_filling_flt( float *Q, const int16_t noiseFillSeed, const int16_t iFirstLine, @@ -7465,7 +7456,7 @@ void tcx_encoder_memory_update( const float *A /* i : Quantized LPC coefficients */ ); -void tcx_decoder_memory_update( +void tcx_decoder_memory_update_flt( Decoder_State *st, /* i/o: decoder memory state */ const float *xn_buf, /* i : mdct output buffer */ float *synth, /* i/o: synth */ @@ -7487,7 +7478,7 @@ int16_t tcx_ari_res_Q_spec( ); /*! r: number of bits used (including "bits") */ -int16_t tcx_ari_res_invQ_spec( +int16_t tcx_ari_res_invQ_spec_flt( float x_Q[], /* i/o: quantized spectrum */ const int16_t L_frame, /* i : number of lines */ const int16_t prm[], /* i : bitstream */ @@ -7514,12 +7505,12 @@ int16_t tcx_res_Q_spec( const float sq_round, const float lf_deemph_factors[] ); -int16_t tcx_res_invQ_gain( +int16_t tcx_res_invQ_gain_flt( float *gain_tcx, const int16_t *prm, const int16_t resQBits ); -int16_t tcx_res_invQ_spec( +int16_t tcx_res_invQ_spec_flt( float *x, const int16_t L_frame, const int16_t *prm, @@ -7528,7 +7519,7 @@ int16_t tcx_res_invQ_spec( const float sq_round, const float lf_deemph_factors[] ); -void InitTnsConfigs( +void InitTnsConfigs_flt( const int16_t bwidth, const int16_t L_frame, STnsConfig tnsConfig[2][2], @@ -7537,11 +7528,11 @@ void InitTnsConfigs( const int16_t element_mode, const int16_t MCT_flag ); -void SetAllowTnsOnWhite( +void SetAllowTnsOnWhite_flt( STnsConfig tnsConfig[2][2], const int8_t allowTnsOnWhite ); -void SetTnsConfig( +void SetTnsConfig_flt( TCX_CONFIG_HANDLE hTcxCfg, const int16_t isTCX20, const int16_t isAfterACELP ); @@ -7550,7 +7541,7 @@ void ari_copy_states( Tastat *source, Tastat *dest ); -int32_t mul_sbc_14bits( +int32_t mul_sbc_14bits_ivas( int32_t r, int32_t c ); @@ -7569,52 +7560,52 @@ int16_t ari_done_encoding_14bits( int16_t bp, Tastat *s ); -void ari_start_decoding_14bits( +void ari_start_decoding_14bits_ivas( Decoder_State *st, Tastat *s ); -int16_t ari_start_decoding_14bits_prm( +int16_t ari_start_decoding_14bits_prm_ivas( const int16_t *ptr, int16_t bp, Tastat *s ); -Word16 ari_start_decoding_14bits_prm_fx( +Word16 ari_start_decoding_14bits_prm_fx_ivas( const Word16 *ptr, Word16 bp, Tastat *s ); -void ari_decode_14bits_s17_ext( +void ari_decode_14bits_s17_ext_ivas( Decoder_State *st, uint16_t *res, Tastat *s, const uint16_t *cum_freq ); -void ari_decode_14bits_s27_ext( +void ari_decode_14bits_s27_ext_ivas( Decoder_State *st, uint16_t *res, Tastat *s, const uint16_t *cum_freq ); -void ari_decode_14bits_bit_ext( +void ari_decode_14bits_bit_ext_ivas( Decoder_State *st, uint16_t *res, Tastat *s ); /*! r: Q15 */ -Word16 expfp( +Word16 expfp_evs( const Word16 x, /* i : mantissa Q15-e */ const Word16 x_e /* i : exponent Q0 */ ); -void powfp_odd2( +void powfp_odd2_evs( const Word16 base, /* Q15 */ const Word16 exp, /* Q0 */ Word16 *pout1, /* Q15 */ Word16 *pout2 /* Q15 */ ); -void tcx_arith_scale_envelope( +void tcx_arith_scale_envelope_flt( const Word16 L_spec_core, /* i : number of lines to scale Q0 */ Word16 L_frame, /* i : number of lines Q0 */ const Word32 env[], /* i : unscaled envelope Q16 */ @@ -7624,7 +7615,7 @@ void tcx_arith_scale_envelope( Word16 *s_env_e /* o : scaled envelope exponent Q0 */ ); -void tcx_arith_render_envelope( +void tcx_arith_render_envelope_flt( const Word16 A_ind[], /* i : LPC coefficients of signal envelope */ const Word16 L_frame, /* i : number of spectral lines */ const Word16 L_spec, /* i : length of the coded spectrum */ @@ -7655,7 +7646,7 @@ int16_t ari_done_cbr_encoding_14bits( int32_t bits, Tastat *s ); -int16_t ari_decode_14bits_pow( +int16_t ari_decode_14bits_pow_ivas( const int16_t *ptr, int16_t bp, int16_t bits, @@ -7663,7 +7654,7 @@ int16_t ari_decode_14bits_pow( Tastat *s, uint16_t base ); -int16_t ari_decode_14bits_sign( +int16_t ari_decode_14bits_sign_ivas( const int16_t *ptr, int16_t bp, int16_t bits, @@ -7687,7 +7678,7 @@ void tcx_arith_encode_envelope( const int16_t low_complexity /* i : low-complexity flag */ ); -void tcx_arith_decode_envelope( +void tcx_arith_decode_envelope_flt( Decoder_State *st, /* i/o: coder state */ float q_spectrum[], /* o : quantised MDCT coefficients */ const int16_t L_frame, /* i : frame or MDCT length */ @@ -7720,7 +7711,7 @@ void tcx_arith_decode_envelope_fx( const Word16 low_complexity /* i : low-complexity flag */ ); -void UnmapIndex( +void UnmapIndex_ivas( const int16_t PeriodicityIndex, const int16_t Bandwidth, const int16_t LtpPitchLag, @@ -7747,7 +7738,7 @@ int16_t SearchPeriodicityIndex( float *RelativeScore /* o : Energy concentration factor */ ); -void ConfigureContextHm( +void ConfigureContextHm_ivas( const int16_t NumCoeffs, /* i : Number of coefficients */ const int16_t TargetBits, /* i : Target bit budget (excl. Done flag) */ const int16_t PeriodicityIndex, /* i : Pitch related index */ @@ -7760,7 +7751,7 @@ int16_t EncodeIndex( int16_t PeriodicityIndex, BSTR_ENC_HANDLE hBstr ); -int16_t CountIndexBits( +int16_t CountIndexBits_ivas( const int16_t Bandwidth, /* o : NB, 1: (S)WB */ const int16_t PeriodicityIndex ); @@ -7776,7 +7767,7 @@ int16_t DecodeIndex( #define GET_ADJ( T, L ) GET_ADJ2( T, L, *FractionalResolution ) #define GET_ADJ2( T, L, F ) ( ( ( L ) << ( F ) ) - ( T ) ) -int16_t tcx_hm_render( +int16_t tcx_hm_render_ivas( const int16_t lag, /* i : pitch lag */ const int16_t fract_res, /* i : fractional resolution of the lag */ Word16 p[] /* o : harmonic model (Q13) */ @@ -7788,7 +7779,7 @@ Word32 tcx_hm_render_fx( Word16 p[] /* o: harmonic model Q13 */ ); -void tcx_hm_modify_envelope( +void tcx_hm_modify_envelope_ivas( const Word16 gain, /* i : HM gain (Q11) */ const int16_t lag, const int16_t fract_res, @@ -7818,7 +7809,7 @@ void tcx_hm_analyse( int16_t *hm_bits /* o : bit consumption */ ); -void tcx_hm_decode( +void tcx_hm_decode_ivas( const int16_t L_frame, /* i : number of spectral lines */ Word32 env[], /* i/o: envelope shape (Q16) */ const int16_t targetBits, /* i : target bit budget */ @@ -7828,7 +7819,7 @@ void tcx_hm_decode( int16_t *hm_bits /* o : bit consumption */ ); -void tcx_hm_decode_fx( +void tcx_hm_decode( const Word16 L_frame, /* i : number of spectral lines */ Word32 env[], /* i/o: envelope shape (Q16) */ const Word16 targetBits, /* i : target bit budget */ @@ -7860,7 +7851,7 @@ void coder_tcx_post( const float *Ai /* i : Unquantized (interpolated) LPC coefficients */ ); -void decoder_tcx( +void decoder_tcx_flt( Decoder_State *st, /* i/o: coder memory state */ int16_t prm[], /* i : parameters */ float A[], /* i : coefficients NxAz[M+1] */ @@ -7872,7 +7863,7 @@ void decoder_tcx( const int16_t sba_dirac_stereo_flag /* i : signal stereo output for SBA DirAC */ ); -void decoder_tcx_post( +void decoder_tcx_post_flt( Decoder_State *st, /* i/o: decoder memory state */ float *synth, float *synthFB, @@ -7912,7 +7903,7 @@ void coder_acelp_rf( float *syn_rf /* i/o: pointer to RF synthesis */ ); -void decoder_acelp( +void decoder_acelp_flt( Decoder_State *st, /* i/o: coder memory state */ int16_t prm[], /* i : parameters */ const float A[], /* i : coefficients NxAz[M+1] */ @@ -7974,12 +7965,12 @@ void enc_prm_rf( const int16_t rf_frame_type, const int16_t fec_offset ); -void dec_prm_hm( +void dec_prm_hm_ivas( Decoder_State *st, /* i/o: decoder memory state */ int16_t *prm_hm, const int16_t hm_size ); -void dec_prm( +void dec_prm_ivas( Decoder_State *st, /* i/o: decoder memory state */ int16_t param[], /* o : decoded parameters */ int16_t param_lpc[], /* i : LPC parameters */ @@ -7999,7 +7990,7 @@ void gauss_L2( int16_t *seed_acelp /* i/o: random seed */ ); -void gaus_L2_dec( +void gaus_L2_dec_flt( float *code, /* o : decoded gaussian codevector */ float tilt_code, const float *A, @@ -8016,7 +8007,7 @@ float interpolation( const int16_t nb_coef /* i : nb of filter coef */ ); -void predict_signal( +void predict_signal_flt( const float excI[], /* i : input excitation buffer */ float excO[], /* o : output excitation buffer */ const int16_t T0, /* i : integer pitch lag */ @@ -8039,7 +8030,7 @@ void tcx_ltp_encode( const int16_t disable_ltp, const int16_t element_mode ); -void tcx_ltp_post( +void tcx_ltp_post_flt( Decoder_State *st, TCX_LTP_DEC_HANDLE hTcxLtpDec, const int16_t core, @@ -8048,7 +8039,7 @@ void tcx_ltp_post( float sig[], const float tcx_buf[] ); -int16_t tcx_ltp_decode_params( +int16_t tcx_ltp_decode_params_flt( int16_t *ltp_param, int16_t *pitch_int, int16_t *pitch_fr, @@ -8167,7 +8158,7 @@ int16_t msvq_stage1_dct_recalc_candidates_fdcng_wb( float *dist_ptr /* i/o: updated MSE vector for stage1 */ ); -void PulseResynchronization( +void PulseResynchronization_flt( const float *src_exc, /* i : Input excitation buffer */ float *dst_exc, /* o : output excitation buffer */ const int16_t nFrameLength, /* i : frame length */ @@ -8176,7 +8167,7 @@ void PulseResynchronization( const float pitchEnd /* i : Pitch at the end of the current frame */ ); -void con_acelp( +void con_acelp_flt( float A[], /* i : coefficients NxAz[M+1] */ const int16_t coder_type, /* i : ACELP coder type */ float synth[], /* i/o: synthesis */ @@ -8189,7 +8180,7 @@ void con_acelp( float *bwe_exc /* o : excitation for SWB TBE */ ); -void con_tcx( +void con_tcx_flt( Decoder_State *st, /* i/o: coder memory state */ float synth[], /* i/o: synth[] */ const float coh, /* i : coherence of stereo signal */ @@ -8212,18 +8203,18 @@ int16_t lsf_msvq_ma_encprm( const int16_t bits_param_lpc[], const int16_t no_indices ); -int16_t lsf_msvq_ma_decprm( +int16_t lsf_msvq_ma_decprm_ivas( Decoder_State *st, int16_t *param_lpc ); -int16_t dec_lsf_tcxlpc( +int16_t dec_lsf_tcxlpc_ivas( Decoder_State *st, /* i : Decoder state */ int16_t **indices, /* o : Ptr to VQ indices */ const int16_t narrowband, /* i : narrowband flag */ const int16_t cdk /* i : codebook selector */ ); -int16_t D_lsf_tcxlpc( +int16_t D_lsf_tcxlpc_ivas( const int16_t indices[], /* i : VQ indices */ float lsf_q[], /* o : quantized lsf */ Word16 lsp_q_ind[], /* o : quantized lsp (w/o MA prediction) */ @@ -8258,7 +8249,7 @@ int16_t E_LPC_lsp_unweight_float( const float inv_gamma /* i : inverse weighting factor */ ); -int16_t lsf_ind_is_active( +int16_t lsf_ind_is_active_flt( const Word16 lsf_q_ind[], const float means[], const int16_t narrowband, @@ -8275,7 +8266,7 @@ void midlsf_enc( const int32_t sr_core, const int16_t coder_type ); -void midlsf_dec( +void midlsf_dec_flt( const float qlsf0[], const float qlsf1[], const int16_t idx, @@ -8335,7 +8326,7 @@ void lpc_quantization( int16_t *bits_param_lpc, int16_t *no_param_lpc ); -void lpc_unquantize( +void lpc_unquantize_flt( Decoder_State *st, float *lsf, float *lsp, @@ -8346,7 +8337,7 @@ void lpc_unquantize( int16_t *LSF_Q_prediction /* o : LSF prediction mode */ ); -void dlpc_bfi( +void dlpc_bfi_flt( const int16_t L_frame, float *lsf_q, /* o : quantized lsfs */ const float *lsfold, /* i : past quantized lsf */ @@ -8364,7 +8355,7 @@ void dlpc_bfi( const float lsfBase[] /* i : base for differential lsf coding */ ); -void lsf_dec_bfi( +void lsf_dec_bfi_flt( const int16_t codec_mode, /* i : codec_mode: MODE1 | MODE2 */ float *lsf, /* o : estimated LSF vector */ const float *lsfold, /* i : past quantized lsf */ @@ -8386,7 +8377,7 @@ void lsf_dec_bfi( const int16_t bwidth /* i : coded bandwidth */ ); -const float *PlcGetlsfBase( +const float *PlcGetlsfBase_flt( const int16_t pcQuantization, const int16_t narrowBand, const int32_t sr_core ); @@ -8542,19 +8533,19 @@ float construct_snr_thresh( const int16_t bw_index /* i : band width index */ ); -ivas_error createFdCngCom( +ivas_error createFdCngCom_flt( HANDLE_FD_CNG_COM *hFdCngCom /* i/o: FD_CNG structure containing all buffers and variables */ ); -void deleteFdCngCom( +void deleteFdCngCom_flt( HANDLE_FD_CNG_COM *hFdCngCom /* i/o: FD_CNG structure containing all buffers and variables */ ); -void initFdCngCom( +void initFdCngCom_flt( HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables */ const float scale ); -void initPartitions( +void initPartitions_flt( const int16_t *part_in, const int16_t npart_in, const int16_t startBand, @@ -8562,14 +8553,14 @@ void initPartitions( int16_t *part_out, int16_t *npart_out, int16_t *midband, - float *psize, - float *psize_inv, + float *psize_flt, + float *psize_inv_flt, const int16_t stopBandFR ); -void minimum_statistics( +void minimum_statistics_flt( const int16_t len, /* i : Vector length */ const int16_t lenFFT, /* i : Length of the FFT part of the vectors */ - float *psize, + float *psize_flt, float *msPeriodog, /* i : Periodograms */ float *msNoiseFloor, float *msNoiseEst, /* o : Noise estimates */ @@ -8596,21 +8587,21 @@ void generate_comfort_noise_enc( Encoder_State *st /* i/o: encoder state structure */ ); -void generate_comfort_noise_dec( +void generate_comfort_noise_dec_flt( float **bufferReal, /* o : Real part of input bands */ float **bufferImag, /* o : Imaginary part of input bands */ Decoder_State *st, /* i/o: decoder state structure */ const int16_t nchan_out /* i : number of output channels */ ); -void generate_comfort_noise_dec_hf( +void generate_comfort_noise_dec_hf_flt( float **bufferReal, /* o : Real part of input bands */ float **bufferImag, /* o : Imaginary part of input bands */ HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables */ const int16_t cng_flag /* i : CNG Flag */ ); -void generate_masking_noise( +void generate_masking_noise_flt( float *timeDomainBuffer, /* i/o: time-domain signal */ HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables */ const int16_t length, /* i : frame size */ @@ -8622,16 +8613,16 @@ void generate_masking_noise( const int16_t nchan_out /* i : number of output channels */ ); -void generate_masking_noise_update_seed( +void generate_masking_noise_update_seed_flt( HANDLE_FD_CNG_COM hFdCngCom /* i/o: FD_CNG structure containing all buffers and variables */ ); -void generate_masking_noise_mdct( +void generate_masking_noise_mdct_flt( float *mdctBuffer, /* i/o: time-domain signal */ HANDLE_FD_CNG_COM hFdCngCom /* i/o: FD_CNG structure containing all buffers and variables */ ); -void SynthesisSTFT_dirac( +void SynthesisSTFT_dirac_flt( float *fftBuffer, /* i : FFT bins */ float *timeDomainOutput, float *olapBuffer, @@ -8661,7 +8652,7 @@ void generate_stereo_masking_noise( const int16_t nchan_out /* i : number of output channels */ ); -void apply_scale( +void apply_scale_flt( float *scale, /* i : scale factor */ const int16_t bwidth, /* i : audio bandwidth */ const int32_t brate, /* i : Bit rate */ @@ -8669,26 +8660,26 @@ void apply_scale( const int16_t scaleTableSize /* i : Size of scale table */ ); -void compress_range( +void compress_range_flt( float *in, float *out, const int16_t len ); -void expand_range( +void expand_range_flt( float *in, float *out, const int16_t len ); -void bandcombinepow( +void bandcombinepow_flt( const float *bandpow, /* i : Power for each band */ const int16_t nband, /* i : Number of bands */ int16_t *part, /* i : Partition upper boundaries (band indices starting from 0) */ const int16_t npart, /* i : Number of partitions */ - const float *psize_inv, /* i : Inverse partition sizes */ + const float *psize_inv_flt, /* i : Inverse partition sizes */ float *partpow /* o : Power for each partition */ ); -void scalebands( +void scalebands_flt( const float *partpow, /* i : Power for each partition */ int16_t *part, /* i : Partition upper boundaries (band indices starting from 0) */ const int16_t npart, /* i : Number of partitions */ @@ -8698,13 +8689,13 @@ void scalebands( float *bandpow, /* o : Power for each band */ const int16_t flag_fft_en ); -void AnalysisSTFT( +void AnalysisSTFT_flt( const float *timeDomainInput, float *fftBuffer, /* o : FFT bins */ HANDLE_FD_CNG_COM st /* i/o: FD_CNG structure containing all buffers and variables */ ); -void SynthesisSTFT( +void SynthesisSTFT_flt( float *fftBuffer, float *timeDomainOutput, float *olapBuffer, @@ -8715,27 +8706,27 @@ void SynthesisSTFT( const int16_t nchan_out /* i : number of output channels */ ); -float rand_gauss( +float rand_gauss_flt( float *x, int16_t *seed ); -void lpc_from_spectrum( +void lpc_from_spectrum_flt( HANDLE_FD_CNG_COM hFdCngCom, const int16_t start, const int16_t stop, const float preemph_fac ); -ivas_error createFdCngDec( +ivas_error createFdCngDec_flt( HANDLE_FD_CNG_DEC *hFdCngDec ); -void deleteFdCngDec( +void deleteFdCngDec_flt( HANDLE_FD_CNG_DEC *hFdCngDec ); -void initFdCngDec( +void initFdCngDec_flt( DEC_CORE_HANDLE st /* i/o: decoder state structure */ ); -void configureFdCngDec( +void configureFdCngDec_flt( HANDLE_FD_CNG_DEC hFdCngDec, /* i/o: Contains the variables related to the FD-based CNG process */ const int16_t bwidth, const int32_t total_brate, @@ -8743,7 +8734,7 @@ void configureFdCngDec( const int16_t last_L_frame, const int16_t element_mode ); -void ApplyFdCng( +void ApplyFdCng_flt( float *timeDomainInput, float *powerSpectrum, float **realBuffer, /* i/o: Real part of the buffer */ @@ -8752,7 +8743,7 @@ void ApplyFdCng( const int16_t concealWholeFrame, /* i : binary flag indicating frame loss */ const int16_t is_music ); -void generate_comfort_noise_dec( +void generate_comfort_noise_dec_flt( float **bufferReal, /* o : Real part of input bands */ float **bufferImag, /* o : Imaginary part of input bands */ Decoder_State *st, /* i/o: decoder state structure */ @@ -8769,11 +8760,11 @@ float cng_energy( const int16_t len /* i : vector length */ ); -void FdCng_decodeSID( +void FdCng_decodeSID_flt( Decoder_State *st /* i/o: decoder state structure */ ); -void FdCng_exc( +void FdCng_exc_flt( HANDLE_FD_CNG_COM hFdCngCom, int16_t *CNG_mode, const int16_t L_frame, @@ -8788,7 +8779,7 @@ void FdCng_exc( float *bwe_exc /* o : LP excitation for BWE */ ); -void noisy_speech_detection( +void noisy_speech_detection_flt( HANDLE_FD_CNG_DEC hFdCngDec, /* i/o: FD_CNG structure */ const int16_t vad, /* i : VAD flag */ const float syn[] /* i : input time-domain frame */ @@ -8952,7 +8943,7 @@ void EncodeTnsData( int16_t *pnBits /* o : number of written bits */ ); -int16_t DecodeTnsData( +int16_t DecodeTnsData_ivas( STnsConfig const *pTnsConfig, const int16_t *stream, int16_t *pnSize, @@ -8966,14 +8957,14 @@ void WriteTnsData( int16_t *pnBits /* o : number of written bits */ ); -void ReadTnsData( +void ReadTnsData_ivas( STnsConfig const *pTnsConfig, Decoder_State *st, int16_t *pnBits, int16_t *stream, int16_t *pnSize ); -void cldfbAnalysis( +void cldfbAnalysis_ivas( const float *timeIn, /* i : time buffer */ float **realBuffer, /* o : real value buffer */ float **imagBuffer, /* o : imag value buffer */ @@ -8981,7 +8972,7 @@ void cldfbAnalysis( HANDLE_CLDFB_FILTER_BANK h_cldfb /* i : filterbank state */ ); -void cldfbAnalysis_ts( +void cldfbAnalysis_ts_ivas( const float *timeIn, /* i : time buffer */ float realBuffer[CLDFB_NO_CHANNELS_MAX], /* o : real value buffer */ float imagBuffer[CLDFB_NO_CHANNELS_MAX], /* o : imag value buffer */ @@ -8989,7 +8980,7 @@ void cldfbAnalysis_ts( HANDLE_CLDFB_FILTER_BANK h_cldfb /* i : filterbank state */ ); -void cldfbSynthesis( +void cldfbSynthesis_ivas( float **realBuffer, /* i : real values */ float **imagBuffer, /* i : imag values */ float *timeOut, /* o : synthesized output */ @@ -8997,12 +8988,12 @@ void cldfbSynthesis( HANDLE_CLDFB_FILTER_BANK h_cldfb /* i : filter bank state */ ); -void configureCldfb( +void configureCldfb_ivas( HANDLE_CLDFB_FILTER_BANK h_cldfb, /* i/o: filter bank handle */ const int32_t sampling_rate /* i : sampling rate */ ); -void analysisCldfbEncoder( +void analysisCldfbEncoder_ivas( Encoder_State *st, /* i/o: encoder state structure */ const float *timeIn, const int16_t samplesToProcess, @@ -9010,31 +9001,31 @@ void analysisCldfbEncoder( float imagBuffer[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], float *ppBuf_Ener ); -ivas_error openCldfb( +ivas_error openCldfb_ivas( HANDLE_CLDFB_FILTER_BANK *h_cldfb, /* i/o: filter bank handle */ CLDFB_TYPE type, /* i : analysis or synthesis */ const int32_t sampling_rate, /* i : sampling rate */ CLDFB_PROTOTYPE prototype /* i : CLDFB version (1.25ms/5ms delay) */ ); -void resampleCldfb( +void resampleCldfb_ivas( HANDLE_CLDFB_FILTER_BANK hs, /* i/o: filter bank handle */ const int32_t newSamplerate /* i : new samplerate to operate */ ); -ivas_error cldfb_save_memory( +ivas_error cldfb_save_memory_ivas( HANDLE_CLDFB_FILTER_BANK hs /* i/o: filter bank handle */ ); -void cldfb_restore_memory( +void cldfb_restore_memory_ivas( HANDLE_CLDFB_FILTER_BANK hs /* i/o: filter bank handle */ ); -void cldfb_reset_memory( +void cldfb_reset_memory_ivas( HANDLE_CLDFB_FILTER_BANK hs /* i/o: filter bank handle */ ); -void deleteCldfb( +void deleteCldfb_ivas( HANDLE_CLDFB_FILTER_BANK *h_cldfb /* i/o: filter bank handle */ ); @@ -9043,14 +9034,14 @@ void fft_cldfb( const int16_t size /* i : size of fft operation */ ); -void BITS_ALLOC_init_config_acelp( +void BITS_ALLOC_init_config_acelp_IVAS( const int32_t bit_rate, const int16_t narrowBand, const int16_t nb_subfr, ACELP_config *acelp_cfg /* o : configuration structure of ACELP */ ); -int16_t BITS_ALLOC_config_acelp( +int16_t BITS_ALLOC_config_acelp_IVAS( const int16_t bits_frame, /* i : remaining bit budget for the frame */ const int16_t coder_type, /* i : acelp coder type */ ACELP_config *acelp_cfg, /* i/o: configuration structure of ACELP */ @@ -9058,7 +9049,7 @@ int16_t BITS_ALLOC_config_acelp( const int16_t nb_subfr /* i : number of subframes */ ); -ivas_error config_acelp1( +ivas_error config_acelp1_IVAS( const int16_t enc_dec, /* i : encoder/decoder flag */ const int32_t total_brate, /* i : total bitrate */ const int32_t core_brate_inp, /* i : core bitrate */ @@ -9086,7 +9077,7 @@ ivas_error config_acelp1( ); /*! r: ACELP16k flag */ -int16_t set_ACELP_flag( +int16_t set_ACELP_flag_IVAS( const int16_t element_mode, /* i : element mode */ const int32_t element_brate, /* i : element bitrate */ const int32_t total_brate, /* i : total bitrate per channel */ @@ -9153,7 +9144,7 @@ void SetTCXModeInfo( int16_t *tcxModeOverlap /* o : window overlap of current frame */ ); -void TCX_MDCT( +void TCX_MDCT_flt( const float *x, float *y, const int16_t l, @@ -9161,7 +9152,7 @@ void TCX_MDCT( const int16_t r, const int16_t element_mode ); -void TCX_MDST( +void TCX_MDST_flt( const float *x, float *y, const int16_t l, @@ -9169,7 +9160,7 @@ void TCX_MDST( const int16_t r, const int16_t element_mode ); -void TCX_MDCT_Inverse( +void TCX_MDCT_Inverse_flt( const float *x, float *y, const int16_t l, @@ -9177,7 +9168,7 @@ void TCX_MDCT_Inverse( const int16_t r, const int16_t element_mode ); -void TCX_MDST_Inverse( +void TCX_MDST_Inverse_flt( const float *x, float *y, const int16_t l, @@ -9185,7 +9176,7 @@ void TCX_MDST_Inverse( const int16_t r, const int16_t element_mode ); -void TCX_MDXT_Inverse( +void TCX_MDXT_Inverse_flt( const float *x, float *y, const int16_t l, @@ -9193,7 +9184,7 @@ void TCX_MDXT_Inverse( const int16_t r, const uint16_t kernel_type ); -void post_decoder( +void post_decoder_flt( Decoder_State *st, float synth_buf[], const float pit_gain[], @@ -9216,7 +9207,7 @@ float bass_pf_enc( float *lp_ener /* i/o: long_term error signal energy */ ); -void cldfb_synth_set_bandsToZero( +void cldfb_synth_set_bandsToZero_flt( Decoder_State *st, /* i/o: decoder state structure */ float **rAnalysis, float **iAnalysis, @@ -9244,7 +9235,7 @@ void longshiftleft( const int16_t len /* i : length of vector a[] and d[] */ ); -void open_decoder_LPD( +void open_decoder_LPD_flt( Decoder_State *st, /* i/o: decoder state structure */ const int32_t total_brate, /* i : total bitrate */ const int32_t last_total_brate, /* i : last total bitrate */ @@ -9270,13 +9261,13 @@ void reset_tcx_overl_buf( TCX_DEC_HANDLE hTcxDec /* i/o: TCX decoder handle */ ); -void update_decoder_LPD_cng( +void update_decoder_LPD_cng_flt( Decoder_State *st, /* i/o: decoder state structure */ float *timeDomainBuffer, float *A, float *bpf_noise_buf ); -void reconfig_decoder_LPD( +void reconfig_decoder_LPD_ivas( Decoder_State *st, /* i/o: decoder state structure */ const int16_t bits_frame, /* i : bit budget */ const int16_t bwidth, /* i : audio bandwidth */ @@ -9284,7 +9275,7 @@ void reconfig_decoder_LPD( const int16_t L_frame_old /* i : frame length */ ); -void mode_switch_decoder_LPD( +void mode_switch_decoder_LPD_flt( Decoder_State *st, /* i/o: decoder state structure */ const int16_t bwidth, /* i : audio bandwidth */ const int32_t total_brate, /* i : total bitrate */ @@ -9294,7 +9285,7 @@ void mode_switch_decoder_LPD( const int16_t last_element_mode /* i : last element mode */ ); -void dec_acelp_tcx_frame( +void dec_acelp_tcx_frame_flt( Decoder_State *st, /* i/o: decoder state structure */ int16_t *concealWholeFrame, /* i/o: concealment flag */ float *output, /* o : synthesis */ @@ -9306,7 +9297,7 @@ void dec_acelp_tcx_frame( STEREO_CNG_DEC_HANDLE hStereoCng /* i : stereo CNG handle */ ); -void decoder_LPD( +void decoder_LPD_flt( Decoder_State *st, /* i/o: decoder memory state pointer */ float signal_out[], /* o : signal with LPD delay (7 subfrs) */ float signal_outFB[], /* o : synthesis @output_FS */ @@ -9399,7 +9390,7 @@ void updateSpecPowDiffuseIdx( float mean_gc[2] /* o : */ ); -void getLookAheadResSig( +void getLookAheadResSig_flt( float *speechLookAhead, const float *A, float *res, @@ -9408,11 +9399,11 @@ void getLookAheadResSig( const int16_t m, const int16_t numSubFrame ); -void updatelsfForConcealment( +void updatelsfForConcealment_flt( PLC_ENC_EVS_HANDLE decState, float *lsf ); -void getConcealedLP( +void getConcealedLP_flt( PLC_ENC_EVS_HANDLE memDecState, float *AqCon, const float xsfBase[], @@ -9420,14 +9411,14 @@ void getConcealedLP( const int16_t last_good, const int16_t L_frame ); -void RecLpcSpecPowDiffuseLc( +void RecLpcSpecPowDiffuseLc_flt( float *ispq, float *isp_old, float *isfq, Decoder_State *st, const int16_t reset_q ); -void modify_lsf( +void modify_lsf_flt( float *lsf, const int16_t n, const int32_t sr_core, @@ -9507,7 +9498,7 @@ void set_TEC_TFA_code( int16_t *tec_flag, int16_t *tfa_flag ); -float Damping_fact( +float Damping_fact_flt( const int16_t coder_type, /* i : ACELP core coder type */ const int16_t nbLostCmpt, /* i : compt for number of consecutive lost frame */ int16_t last_good, /* i : class of last good received frame */ @@ -9525,7 +9516,7 @@ void fer_energy( const int16_t useOffset /* i : speech pointer offset (0 or L_FRAME) */ ); -float getLevelSynDeemph( +float getLevelSynDeemph_flt( const float h1Init[], /* i : input value or vector to be processed */ const float A[], /* i : LPC coefficients */ const int16_t lenLpcExc, /* i : length of the LPC excitation buffer */ @@ -9533,14 +9524,14 @@ float getLevelSynDeemph( const int16_t numLoops /* i : number of loops */ ); -void genPlcFiltBWAdap( +void genPlcFiltBWAdap_flt( const int32_t sr_core, /* i : core sampling rate */ float *lpFiltAdapt, /* o : filter coefficients for filtering codebooks in case of flc */ const int16_t type, /* i : type of filter, either 0 : lowpass or 1 : highpass */ const float alpha /* i : fade out factor [0 1) used decrease filter tilt */ ); -void highPassFiltering( +void highPassFiltering_flt( const int16_t last_good, /* i : last classification type */ const int16_t L_buffer, /* i : buffer length */ float exc2[], /* i/o: unvoiced excitation before the high pass filtering */ @@ -9548,7 +9539,7 @@ void highPassFiltering( const int16_t l_fir_fer /* i : high pass filter length */ ); -int16_t GetPLCModeDecision( +int16_t GetPLCModeDecision_flt( Decoder_State *st /* i/o: decoder memory state pointer */ ); @@ -9559,14 +9550,14 @@ void addBassPostFilter( float **iAnalysis, HANDLE_CLDFB_FILTER_BANK cldfb ); -ivas_error TonalMDCTConceal_Init( +ivas_error TonalMDCTConceal_Init_ivas( TonalMDCTConcealPtr hTonalMDCTConc, const uint16_t samplesPerBlock, const uint16_t nSamplesCore, const uint16_t nScaleFactors, TCX_CONFIG_HANDLE hTcxCfg ); -void TonalMDCTConceal_SaveFreqSignal( +void TonalMDCTConceal_SaveFreqSignal_ivas( TonalMDCTConcealPtr hTonalMDCTConc, const float *mdctSpectrum, const uint16_t numSamples, @@ -9574,32 +9565,32 @@ void TonalMDCTConceal_SaveFreqSignal( const float *scaleFactors, const int16_t infoIGFStartLine ); -void TonalMDCTConceal_UpdateState( +void TonalMDCTConceal_UpdateState_ivas( TonalMDCTConcealPtr hTonalMDCTConc, const int16_t numSamples, const float pitchLag, const int16_t badBlock, const int16_t tonalConcealmentActive ); -void TonalMDCTConceal_SaveTimeSignal( +void TonalMDCTConceal_SaveTimeSignal_ivas( TonalMDCTConcealPtr hTonalMDCTConc, float *timeSignal, const int16_t numSamples ); -void TonalMDCTConceal_Detect( +void TonalMDCTConceal_Detect_ivas( const TonalMDCTConcealPtr hTonalMDCTConc, /*IN */ const float pitchLag, /*IN */ int16_t *umIndices, /*OUT*/ const PsychoacousticParameters *psychParamsCurrent /*IN*/ ); -void TonalMDCTConceal_Apply( +void TonalMDCTConceal_Apply_ivas( TonalMDCTConcealPtr hTonalMDCTConc, /*IN */ float *mdctSpectrum, /*OUT*/ const PsychoacousticParameters *psychParamsCurrent /*IN*/ ); -void TonalMDCTConceal_InsertNoise( +void TonalMDCTConceal_InsertNoise_ivas( const TonalMDCTConcealPtr hTonalMDCTConc, /*IN */ float *mdctSpectrum, /*OUT*/ const int16_t tonalConcealmentActive, @@ -9610,7 +9601,7 @@ void TonalMDCTConceal_InsertNoise( const float cngLevelBackgroundTrace_bfi, const int16_t crossOverFreq ); -void DetectTonalComponents( +void DetectTonalComponents_flt( uint16_t indexOfTonalPeak[], uint16_t lowerIndex[], uint16_t upperIndex[], @@ -9625,7 +9616,7 @@ void DetectTonalComponents( float floorPowerSpectrum, const PsychoacousticParameters *psychParamsCurrent ); -void RefineTonalComponents( +void RefineTonalComponents_flt( uint16_t indexOfTonalPeak[], uint16_t lowerIndex[], uint16_t upperIndex[], @@ -9689,7 +9680,7 @@ float SFM_Cal( const float fcoef[], const int16_t n ); -void set_state( +void set_state_ivas( int16_t *state, const int16_t num, const int16_t N ); @@ -9716,7 +9707,7 @@ int16_t get_codec_mode( const int32_t total_brate /* i : total bitrate */ ); -int16_t getTcxonly( +int16_t getTcxonly_ivas( const int16_t element_mode, /* i : IVAS element mode */ const int32_t total_brate, /* i : total bitrate */ const int16_t MCT_flag, /* i : hMCT handle allocated (1) or not (0)*/ @@ -9752,7 +9743,7 @@ int16_t sr2fscale( const int32_t sr_core /* i : internal sampling rate */ ); -int32_t getCoreSamplerateMode2( +int32_t getCoreSamplerateMode2_flt( const int16_t element_mode, /* i : IVAS element mode */ const int32_t total_brate, /* i : total bitrate */ const int16_t bwidth, /* i : audio bandwidth */ @@ -9761,7 +9752,7 @@ int32_t getCoreSamplerateMode2( const IVAS_FORMAT is_ism_format /* i : flag indicating ISM format */ ); -float getTcxBandwidth( +float getTcxBandwidth_flt( const int16_t bwidth /* i : audio bandwidth */ ); @@ -9881,7 +9872,7 @@ int16_t IGFEncWriteConcatenatedBitstream( BSTR_ENC_HANDLE hBstr /* i/o: encoder bitstream handle */ ); -void IGFDecApplyMono( +void IGFDecApplyMono_flt( const IGF_DEC_INSTANCE_HANDLE hIGFDec, /* i : instance handle of IGF Decoder */ float *spectrum, /* i/o: MDCT spectrum */ const int16_t igfGridIdx, /* i : in case of CELP->TCX switching, use 1.25 framelength */ @@ -9889,13 +9880,13 @@ void IGFDecApplyMono( const int16_t element_mode /* i : IVAS element mode */ ); -void IGFDecCopyLPCFlatSpectrum( +void IGFDecCopyLPCFlatSpectrum_flt( const IGF_DEC_INSTANCE_HANDLE hIGFDec, /* i/o: instance handle of IGF Decoder */ const float *pSpectrumFlat, /* i : LPC flattend spectrum from TCX dec */ const int16_t igfGridIdx /* i : IGF grid index */ ); -void IGFDecReadData( +void IGFDecReadData_flt( const IGF_DEC_INSTANCE_HANDLE hIGFDec, /* i/o: instance handle of IGF Deccoder */ Decoder_State *st, /* i : decoder state */ const int16_t igfGridIdx, /* i : in case of CELP->TCX switching, use 1.25 framelength */ @@ -9903,23 +9894,23 @@ void IGFDecReadData( ); /*! r: return igfAllZero flag indicating if no envelope is transmitted */ -int16_t IGFDecReadLevel( +int16_t IGFDecReadLevel_flt( const IGF_DEC_INSTANCE_HANDLE hIGFDec, /* i/o: instance handle of IGF Deccoder */ Decoder_State *st, /* i : decoder state */ const int16_t igfGridIdx, /* i : in case of CELP->TCX switching, use 1.25 framelength */ const int16_t isIndepFrame /* i : if 1: arith dec force reset, if 0: no reset */ ); -void IGFDecRestoreTCX10SubFrameData( +void IGFDecRestoreTCX10SubFrameData_flt( const IGF_DEC_INSTANCE_HANDLE hIGFDec, /* o : instance handle of IGF Decoder */ const int16_t subFrameIdx /* i : index of subframe */ ); -void init_igf_dec( +void init_igf_dec_flt( IGF_DEC_INSTANCE_HANDLE hIGFDec /* i/o: IGF decoder handle */ ); -void IGFDecSetMode( +void IGFDecSetMode_flt( const IGF_DEC_INSTANCE_HANDLE hIGFDec, /* o : instance handle of IGF Decoder */ const int32_t total_brate, /* i : bitrate */ const int16_t bwidth, /* i : audio bandwidth */ @@ -9929,19 +9920,19 @@ void IGFDecSetMode( const int16_t rf_mode /* i : flag to signal the RF mode */ ); -void IGFDecStoreTCX10SubFrameData( +void IGFDecStoreTCX10SubFrameData_flt( const IGF_DEC_INSTANCE_HANDLE hIGFDec, /* i/o: instance handle of IGF Decoder */ const int16_t subFrameIdx /* i : index of subframe */ ); -void IGFDecUpdateInfo( +void IGFDecUpdateInfo_flt( const IGF_DEC_INSTANCE_HANDLE hIGFDec, /* i/o: instance handle of IGF Decoder */ const int16_t subFrameIdx, /* i : subframe index */ const int16_t igfGridIdx /* i : IGF grid index */ ); /*! r: error value: 0 -> error, 1 -> ok */ -int16_t IGFCommonFuncsIGFConfiguration( +int16_t IGFCommonFuncsIGFConfiguration_flt( const int32_t total_brate, /* i : bitrate in bs e.g. 9600 for 9.6kbs */ const int16_t bwidth, /* i : audio bandwidth */ const int16_t element_mode, /* i : IVAS element mode */ @@ -9950,7 +9941,7 @@ int16_t IGFCommonFuncsIGFConfiguration( ); /*! r: error value: 0 -> error, 1 -> ok */ -int16_t IGFCommonFuncsIGFGetCFTables( +int16_t IGFCommonFuncsIGFGetCFTables_flt( const int32_t total_brate, /* i : bitrate in bs e.g. 9600 for 9.6kbs */ const int16_t bwidth, /* i : audio bandwidth */ const int16_t element_mode, /* i : element mode */ @@ -9967,13 +9958,13 @@ int16_t IGFCommonFuncsIGFGetCFTables( ); /*! r: multiplication factor */ -int16_t IGF_ApplyTransFac( +int16_t IGF_ApplyTransFac_flt( const int16_t val, /* i : input value for multiplication, Q15 */ const float transFac /* i : multiplicator for variable val, Q14: 1.25f=0x5000, 1.0f=0x4000, 0.5f=0x2000 */ ); /*! r: return bitrate index */ -int16_t IGF_MapBitRateToIndex( +int16_t IGF_MapBitRateToIndex_flt( const int32_t brate, /* i : bitrate */ const int16_t bwidth, /* i : audio bandwidth */ const int16_t element_mode, /* i : IVAS element mode */ @@ -10012,7 +10003,7 @@ void IGFSCFEncoderRestoreContextState( const int16_t igfGridIdx /* i : igf grid index see declaration of IGF_GRID_IDX for details */ ); -void IGFSCFDecoderOpen( +void IGFSCFDecoderOpen_ivas( IGFSCFDEC_INSTANCE_HANDLE hPublicData, /* i : handle to public data */ H_IGF_INFO hIgfInfo, /* i : IGF info handle */ const int32_t total_brate, @@ -10020,11 +10011,11 @@ void IGFSCFDecoderOpen( const int16_t element_mode, const int16_t rf_mode ); -void IGFSCFDecoderReset( +void IGFSCFDecoderReset_ivas( IGFSCFDEC_INSTANCE_HANDLE hPublicData /* i : handle to public data or NULL in case there was no instance created */ ); -void IGFSCFDecoderDecode( +void IGFSCFDecoderDecode_ivas( IGFSCFDEC_INSTANCE_HANDLE hPublicData, /* i : handle to public data or NULL in case there was no instance created */ Decoder_State *st, /* i/o: pointer to decoder state */ int16_t *sfe, /* o : ptr to an array which will contain the decoded quantized coefficients */ @@ -10039,7 +10030,7 @@ int16_t tbe_celp_exc_offset_flt( const int16_t T0_frac /* i : Fractional part of the pitch */ ); -void blend_subfr2( +void blend_subfr2_flt( float *sigIn1, /* i : input signal for fade-out */ float *sigIn2, /* i : input signal for fade-in */ float *sigOut /* o : output signal */ diff --git a/lib_com/prot_fx1.h b/lib_com/prot_fx1.h index b948a78b7d6c1e1422ffc7de33f8a5278f8ca058..e885188a9cc16e20abb8da733b0268d58907d5fd 100644 --- a/lib_com/prot_fx1.h +++ b/lib_com/prot_fx1.h @@ -40,6 +40,8 @@ #include "typedef.h" #include "cnst.h" #include "stl.h" +#define mvr2r_Word32(x,y,n) Copy32(x,y,n) +#define mvr2r_Word16(x,y,n) Copy(x,y,n) int16_t norm_ul(uint32_t UL_var1); Word16 usdequant_fx( /* Qx*/ diff --git a/lib_com/prot_fx2.h b/lib_com/prot_fx2.h index aa7563a4ffeadd1c4a434d6e04c689deb777a2b8..56b80d1a5ca76274ee6332621c5175b3dbb6be37 100644 --- a/lib_com/prot_fx2.h +++ b/lib_com/prot_fx2.h @@ -53,9 +53,12 @@ #include "ivas_cnst.h" #include "stat_enc.h" #include "stat_dec.h" +#include "ivas_stat_dec.h" #include "ivas_error.h" #include "ivas_error_utils.h" - +#include "complex_basop.h" +#define TCX_IMDCT_SCALE 15 +#define TCX_IMDCT_HEADROOM 1 Word32 Mult_32_16( Word32 a, @@ -912,11 +915,16 @@ void E_LPC_a_lsf_isf_conversion(Word16 *lpcCoeffs, Word16 *lsf, const Word16 *ol bitstream_fx.c /========================================================================================================*/ -UWord16 get_next_indice_fx( /* o : value of the indice */ +UWord16 get_next_indice( /* o : value of the indice */ Decoder_State *st_fx, /* i/o: decoder state structure */ Word16 nb_bits /* i : number of bits that were used to quantize the indice */ ); +UWord16 get_next_indice_fx( /* o : value of the indice */ + Decoder_State *st_fx, /* i/o: decoder state structure */ + Word16 nb_bits /* i : number of bits that were used to quantize the indice */ +); + void push_indice_fx( BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ Word16 id, /* i : ID of the indice */ @@ -941,12 +949,12 @@ void push_next_bits_fx( Word16 nb_bits /* i : number of bits to pack */ ); -UWord16 get_next_indice_fx( /* o : value of the indice */ - Decoder_State *st_fx, /* i/o: decoder state structure */ - Word16 nb_bits /* i : number of bits that were used to quantize the indice */ -); +//UWord16 get_next_indice( /* o : value of the indice */ +// Decoder_State *st_fx, /* i/o: decoder state structure */ +// Word16 nb_bits /* i : number of bits that were used to quantize the indice */ +//); -UWord16 get_next_indice_1_fx( /* o : value of the indice */ +UWord16 get_next_indice_1( /* o : value of the indice */ Decoder_State *st_fx /* i/o: decoder state structure */ ); @@ -955,7 +963,7 @@ void get_next_indice_tmp_fx( Word16 nb_bits /* i : number of bits that were used to quantize the indice */ ); -UWord16 get_indice_fx( /* o : value of the indice */ +UWord16 get_indice( /* o : value of the indice */ Decoder_State *st_fx, /* i/o: decoder state structure */ Word16 pos, /* i : absolute position in the bitstream */ Word16 nb_bits /* i : number of bits that were used to quantize the indice */ @@ -1141,6 +1149,20 @@ void hq_configure_fx( Word16 *sfm_end /* o : Subband end coefficients Q0 */ ); +void hq_configure_evs_fx( + const Word16 length, /* i : Frame length Q0 */ + const Word16 hqswb_clas, /* i : HQ SWB class Q0 */ + const Word32 core_brate, /* i : Codec bitrate Q0 */ + Word16 *num_sfm, /* o : Total number of subbands Q0 */ + Word16 *nb_sfm, /* o : Total number of coded bands Q0 */ + Word16 *start_norm, /* o : First norm to be SDE encoded Q0 */ + Word16 *num_env_bands, /* o : Number coded envelope bands Q0 */ + Word16 *numnrmibits, /* o : Number of bits in fall-back norm encoding Q0 */ + Word16 *hq_generic_offset, /* o : Freq offset for HQ GENERIC Q0 */ + Word16 *sfmsize, /* o : Subband bandwidths Q0 */ + Word16 *sfm_start, /* o : Subband start coefficients Q0 */ + Word16 *sfm_end /* o : Subband end coefficients Q0 */ +); //hp50.c void hp20(Word16 signal[], /* i/o: signal to filter any */ @@ -1376,20 +1398,7 @@ void pre_echo_att_fx( const Word16 L_frame /* i : Frame length*/ ); - -void window_ola_fx( - Word32 *ImdctOut, - Word16 *auOut, - Word16 *Q_sig, - Word16 *OldauOut, - Word16 *Q_old, - const Word16 L, - const Word16 right_mode, - const Word16 left_mode, - const Word16 old_bfi, - const Word16 oldHqVoicing, - Word16 *oldgapsynth ); - +//wtda_fx.c void tcx_get_windows_mode1( const Word16 left_mode, /* i: overlap mode of left window half */ const Word16 right_mode, /* i: overlap mode of right window half */ @@ -1400,11 +1409,15 @@ void tcx_get_windows_mode1( const Word16 L /* i : length */ ); -void sinq_fx( - const Word16 tmp, /* i : sinus factor cos(tmp*i+phi) Q15*/ - const Word16 phi, /* i : sinus phase cos(tmp*i+phi) Q15*/ - const Word16 N, /* i : size of output */ - Word16 x[] /* o : output vector Q15*/ +void wtda_fx( + Word16* new_audio, /* i : i audio Q0 */ + Word16* Q, /* i/o : Q of i /Output Audio */ + Word32* wtda_audio, /* o : windowed audio Qout */ + Word16* old_wtda, /* i/o: windowed audio from previous frame Qout */ + Word16* Qold_wtda, + const Word16 left_mode, /* i : window overlap of previous frame (0: full, 2: none, or 3: half) */ + const Word16 right_mode, /* i : window overlap of current frame (0: full, 2: none, or 3: half) */ + const Word16 L /* i : length */ ); /*========================================================================================================/ @@ -2000,6 +2013,16 @@ PvqEntry mpvq_encode_vec_fx( /* o : leading_sign_index, index, size, k_val Word16 dim_in, /* i : dimension */ Word16 k_val_local /* i : nb unit pulses */ ); +PvqEntry get_size_mpvq_calc_offset_fx( /* o : size, dim, k_val */ + Word16 dim_in, /* i : dimension */ + Word16 k_val_in, /* i : nb unit pulses */ + UWord32* h_mem /* o : offsets */ +); +void mpvq_decode_vec_fx( /* o : void */ + const PvqEntry* entry, /* i : sign_ind, index, dim, k_val */ + UWord32* h_mem, /* i : A/U offsets */ + Word16* vec_out /* o : pulse train */ +); //weight_a_fx.c void weight_a_subfr_fx( @@ -2023,6 +2046,7 @@ void weight_a_fx( const Word16 gamma, /* i: weighting factor Q15 */ const Word16 m /* i: order of LP filter Q0 */ ); +void E_LPC_a_weight_inv(const Word16 *a, Word16 *ap, const Word16 gamma, const Word16 m); //residu_fx.c void Residu3_lc_fx( @@ -2169,7 +2193,137 @@ void preemph_copy_fx( void E_UTIL_f_preemph2(Word16 shift, Word16 *signal, const Word16 mu, const Word16 lg, Word16 *mem); Word16 E_UTIL_f_preemph3(Word16 *signal, const Word16 mu, const Word16 lg, Word16 *mem, Word16 bits); +//swb_bwe_com_fx.c +Word16 WB_BWE_gain_pred_fx( + Word16 *WB_fenv, /* o : WB frequency envelopes */ + const Word16 *core_dec_freq, /* i : Frequency domain core decoded signal */ + const Word16 coder_type, /* i : coding type */ + Word16 prev_coder_type, /* i : coding type of last frame */ + Word16 prev_WB_fenv, /* i : envelope for last frame */ + Word16 *voice_factors, /* i : voicing factors Q15 */ + const Word16 pitch_buf[], /* i : pitch buffer Q6 */ + Word32 last_core_brate, /* i : previous frame core bitrate */ + Word16 last_wb_bwe_ener, /* i : previous frame wb bwe signal energy */ + Word16 Q_syn + , Word16 last_extl_fx, + Word16 tilt_wb_fx +); + +void calc_normal_length_fx( + const Word16 core, /* i : core */ + const Word16 *sp, /* i : i signal */ + const Word16 mode, /* i : i mode */ + const Word16 extl, /* i : extension layer */ + Word16 *L_swb_norm, /* o : normalize length */ + Word16 *prev_L_swb_norm, /*i/o : last normalize length */ + Word16 Q_syn +); +Word32 calc_tilt_bwe_fx( /* o : Tilt in Q24 */ + const Word16 *sp0, /* i : i signal */ + const Word16 exp, /* i : Exp of inp signal */ + const Word16 N /* i : signal length */ +); + +void calc_norm_envelop_fx( + const Word16 SWB_signal[], /* i : SWB spectrum Q_syn*/ + Word32 *envelope, /* o : normalized envelope Q_syn*/ + const Word16 L_swb_norm, /* i : length of envelope Q0 */ + const Word16 SWB_flength, /* i : Length of i /output */ + const Word16 st_offset /* i : offset */ +); + +void WB_BWE_decoding_fx( + const Word16 *core_dec_freq, /* i : Frequency domain core decoded signal */ + Word16 *WB_fenv, /* i : WB frequency envelopes */ + Word32 *WB_signal32, /* o : WB signal in MDCT domain */ + const Word16 WB_flength, /* i : Length of i /output */ + const Word16 mode, /* i : classification for WB signal */ + const Word16 last_extl, /* i : extl. layer for last frame */ + Word32 *prev_Energy, /* i/o: energy for last frame */ + Word16 *prev_WB_fenv, /* i/o: envelope for last frame */ + Word16 *prev_L_wb_norm, /* i/o: length for last frame wb norm */ + const Word16 extl, /* i : extension layer */ + const Word16 coder_type, /* i : coding type */ + const Word32 total_brate, /* i : core layer bitrate */ + Word16 *Seed, /* i/o: random generator seed */ + Word16 *prev_flag, /* i/o: attenu flag of last frame */ + Word16 prev_coder_type, /* i : coding type of last frame */ + Word16 Q_syn, + Word16 *Q_syn_hb /*o : Q value of WB_signal_32 */ +); + +void SWB_BWE_decoding_fx( + const Word16 *core_dec_freq, /* i : Frequency domain core decoded signal */ + Word16 *SWB_fenv, /* i/o: SWB frequency envelopes */ + Word32 *SWB_signal, /* o : SWB signal in MDCT domain */ + const Word16 SWB_flength, /* i : Length of i /output */ + const Word16 mode, /* i : classification for SWB signal */ + Word16 *frica_flag, /* o : fricative signal flag */ + Word16 *prev_Energy, /* i/o: energy for last frame */ + Word16 *prev_SWB_fenv, /* i/o: envelope for last frame */ + Word16 *prev_L_swb_norm, /* i/o: length for last frame wb norm */ + const Word16 tilt_nb, /* i : tilt of synthesis wb signal */ + Word16 *Seed, /* i/o: random generator seed */ + const Word16 st_offset, /* i : offset value due to different core */ + Word16 *prev_weight, /* i/o: excitation weight value of last frame */ + const Word16 extl, /* i : extension layer */ + Word16 Q_syn + , const Word16 last_extl /* i : extension layer of last frame */ +); + +void time_envelop_shaping_fx( + Word16 werr[], /* i/o: SHB synthesis Q_synth*/ + Word32 SWB_tenv[], /* i/o: frequency envelope Q15*/ + const Word16 L, /* i : frame length */ + Word16 *Q_synth +); + +void time_reduce_pre_echo_fx( + const Word16 *synth, /* i : ACELP core synthesis Q_syn*/ + Word16 *error, /* i/o: SHB BWE synthesis Q0*/ + Word16 prev_td_energy, /* o : last td energy Q0*/ + const Word16 L, /* i : subframe length */ + Word16 Q_syn, + Word16 Q_synth +); + +void calc_normal_length_fx_32( + const Word16 core, /* i : core : Q0 */ + const Word32 *sp, /* i : i signal : Q12 */ + const Word16 mode, /* i : i mode : Q0 */ + const Word16 extl, /* i : extension layer : Q0 */ + Word16 *L_swb_norm, /* o : normalize length : Q0 */ + Word16 *prev_L_swb_norm /*i/o : last normalize length : Q0 */ +); + +void calc_norm_envelop_fx_32( + const Word32 SWB_signal_fx[], /* i : SWB spectrum : Q12 */ + Word32 *envelope_fx, /* o : normalized envelope : Q16 */ + const Word16 L_swb_norm, /* i : length of envelope : Q0 */ + const Word16 SWB_flength, /* i : Length of i /output : Q0 */ + const Word16 st_offset /* i : offset : Q0 */ +); + +void hq_generic_decoding_fx( + const Word16 HQ_mode, /* i : HQ mode */ + Word32 *coeff_out1_fx, /* i/o: BWE i & temporary buffer */ + const Word16 *hq_generic_fenv_fx, /* i : SWB frequency envelopes */ + Word32 *coeff_out_fx, /* o : SWB signal in MDCT domain */ + const Word16 hq_generic_offset, /* i : frequency offset for representing hq generic*/ + Word16 *prev_L_swb_norm, /* i/o: last normalize length */ + const Word16 hq_generic_exc_clas, /* i : bwe excitation class */ + const Word16 *R +); + +void save_old_syn_fx( + const Word16 L_frame, /* i : frame length */ + const Word16 syn[], /* i : ACELP synthesis */ + Word16 old_syn[], /* o : old synthesis buffer */ + Word16 old_syn_mem[], /* i/o: old synthesis buffer memory */ + const Word16 preemph_fac, /* i : preemphasis factor */ + Word16 *mem_deemph /* i/o: deemphasis filter memory */ +); //swb_tbe_com_fx.c @@ -3031,14 +3185,4339 @@ void tcxInvertWindowGrouping( const Word16 bfi ); +//mslvq_com +void permute_fx( + Word16 *pTmp1, /* i/o: vector whose components are to be permuted */ + const Word16 *perm /* i : permutation info (indexes that should be interchanged), max two perms */ +); + +void init_lvq_fx( + Word32 offset_scale1[][MAX_NO_SCALES + 1], + Word32 offset_scale2[][MAX_NO_SCALES + 1], + Word32 offset_scale1_p[][MAX_NO_SCALES + 1], + Word32 offset_scale2_p[][MAX_NO_SCALES + 1], + Word16 no_scales[][2], + Word16 no_scales_p[][2] +); + +Word16 deindex_lvq_fx( + Word16 *index, /* i : index to be decoded, as an array of 3 short */ + Word16 *x_lvq, /* o : decoded codevector Q(x2.56)*/ + Word16 mode, /* i : LVQ coding mode (select scales & no_lead ), or idx_cv */ + Word16 sf_flag, /* i : safety net flag */ + Word16 no_bits, /* i : number of bits for lattice */ + Word32 *p_offset_scale1, /* i : offset for first subvector */ + Word32 *p_offset_scale2, /* i : offset for the second subvector */ + Word16 *p_no_scales +); + +Word16 deindex_lvq_cng_fx( + Word16 *index, /* i : index to be decoded, as an array of 3 short */ + Word16 *x_lvq, /* o : decoded codevector Q9*/ + Word16 idx_cv, /* i : relative mode_lvq, wrt START_CNG */ + Word16 no_bits, /* i : number of bits for lattice */ + Word32 * p_offset_scale1, + Word32 * p_offset_scale2, + Word16 * p_no_scales +); + + +//lsp_convert_poly_fx.c +Word16 lsp_convert_poly_fx( + Word16 w[], /* i/o: LSP or ISP parameters */ + const Word16 L_frame, /* i : flag for up or down conversion */ + const Word16 Opt_AMRWB /* i : flag for the AMR-WB IO mode */ +); + + +//cng_exe.c +void CNG_exc_fx( + const Word32 core_brate, /* i : core bitrate */ + const Word16 L_frame, /* i : length of the frame */ + Word32* Enew, /* i/o: decoded SID energy Q6 */ + Word16* seed, /* i/o: random generator seed */ + Word16 exc[], /* o : current non-enhanced excitation Q_new */ + Word16 exc2[], /* o : current enhanced excitation Q_new */ + Word32* lp_ener, /* i/o: LP filtered E */ + const Word32 last_core_brate,/* i : previous frame core bitrate */ + Word16* first_CNG, /* i/o: first CNG frame flag for energy init. */ + Word16* cng_ener_seed, /* i/o: random generator seed for CNG energy */ + Word16 bwe_exc[], /* o : excitation for SWB TBE */ + const Word16 allow_cn_step, /* i : allow CN step */ + Word16* last_allow_cn_step, /* i/o: last allow step */ + const Word16 OldQ_exc, /* i : Old excitation scaling */ + const Word16 Q_exc, /* i : excitation scaling */ + const Word16 num_ho, /* i : number of selected hangover frames */ + Word32 q_env[], + Word32* lp_env, + Word32* old_env, + Word16* exc_mem, + Word16* exc_mem1, + Word16* sid_bw, + Word16* cng_ener_seed1, + Word16 exc3[], + Word16 Opt_AMR_WB, + const Word16 element_mode /* i : IVAS Element mode */ +); + +void cng_params_postupd_fx( + const Word16 ho_circ_ptr, /* i : pointer for CNG averaging buffers Q0 */ + Word16 *cng_buf_cnt, /* i/o: counter for CNG store buffers Q0 */ + const Word16 *const cng_exc2_buf, /* i : Excitation buffer Q_exc */ + const Word16 *const cng_Qexc_buf, /* i : Q_exc buffer Q0 */ + const Word32 *const cng_brate_buf, /* i : bit rate buffer Q0 */ + Word32 ho_env_circ[] /* i/o: Envelope buffer */ +); + +void cng_params_upd_fx( + const Word16 lsp_new[], /* i : LSP parameters Q15 */ + const Word16 exc2[], /* i : current enhanced excitation Q_exc */ + const Word16 L_frame, /* i : frame length Q0 */ + Word16 *ho_circ_ptr, /* i/o: pointer for CNG averaging buffers Q0 */ + Word32 ho_ener_circ[], /* o : energy buffer for CNG averaging Q6 */ + Word16 *ho_circ_size, /* i/o: size of DTX hangover history buffer for averaging Q0 */ + Word16 ho_lsp_circ[], /* o : old LSP buffer for CNG averaging Q15 */ + const Word16 Q_exc, /* i : Q value of excitation */ + const Word16 enc_dec_flag, /* i : Flag indicating encoder or decoder (ENC,DEC) */ + Word32 ho_env_circ[], /* i/o: Envelope buffer */ + Word16 *cng_buf_cnt, /* i/o: Counter of postponed FFT-processing instances */ + Word16 cng_exc2_buf[], /* i/o: Excitation buffer Q_exc */ + Word16 cng_Qexc_buf[], /* i/o: Q_exc buffer Q0 */ + Word32 cng_brate_buf[], /* i/o: last_active_brate buffer Q0 */ + const Word32 last_active_brate /* i : Last active bit rate Q0 */ +); + +int16_t get_cng_mode( + const int32_t last_active_brate /* i : last active bitrate */ +); + +//core_com_config.c +Word16 get_codec_mode( + const Word32 total_brate /* i : total bitrate */ +); + +Word16 getTcxonly( +#ifdef IVAS_CODE_SWITCHING + const Word16 element_mode, /* i : IVAS element mode */ +#endif + const Word32 total_brate /* i : total bitrate */ +#ifdef IVAS_CODE_SWITCHING + , const Word16 MCT_flag, /* i : hMCT handle allocated (1) or not (0)*/ + const int16_t is_ism_format /* i : flag indicating ISM format */ +#endif +); + +int16_t getCtxHm( + const int16_t element_mode, /* i : IVAS element mode */ + const int32_t total_brate, /* i : total bitrate */ + const int16_t rf_flag /* i : flag to signal the RF mode */ +); + + +int16_t getResq( + const int32_t total_brate /* i : total bitrate */ +); + +Word16 getTnsAllowed( + const Word32 total_brate, /* i : total bitrate */ + const Word16 igf, /* i : flag indicating IGF activity*/ + const Word16 element_mode /* i : IVAS element mode */ +); + +int16_t getRestrictedMode( + const int16_t element_mode, /* i : IVAS element mode */ + const int32_t total_brate, /* i : total bitrate */ + const int16_t Opt_AMR_WB /* i : flag indicating AMR-WB IO mode */ +); + +Word16 sr2fscale(const Word32 sr); + +Word32 getCoreSamplerateMode2( + const Word16 element_mode, /* i : IVAS element mode */ + const Word32 total_brate, /* i : total bitrate */ + const Word16 bwidth, /* i : audio bandwidth */ + const Word16 flag_ACELP16k, /* i : ACELP@16kHz flag */ + const Word16 rf_mode, /* i : flag to signal the RF mode */ + const IVAS_FORMAT is_ism_format /* i : flag indicating ISM format */ +); + +Word16 getTcxBandwidth(const Word16 bandwidth); + +Word16 getIgfPresent( + const Word16 element_mode, /* i : IVAS element mode */ + const Word32 total_brate, /* i : total bitrate */ + const Word16 bwidth, /* i : audio bandwidth */ + const Word16 rf_mode /* i : flag to signal the RF mode */ +); + +Word16 getCnaPresent( + const Word16 element_mode, /* i : element mode */ + const Word32 element_brate, /* i : element bitrate */ + const Word32 total_brate, /* i : total bitrate */ + const Word16 bwidth /* i : audio bandwidth */ +); + +int16_t getTcxLtp( + const int32_t sr_core /* i : internal sampling rate */ +); + +Word16 initPitchLagParameters( + const Word32 sr_core, + Word16 *pit_min, + Word16 *pit_fr1, + Word16 *pit_fr1b, + Word16 *pit_fr2, + Word16 *pit_max +); + +Word16 getNumTcxCodedLines(const Word16 bwidth); + +Word16 getTcxLpcShapedAri( + const Word32 total_brate, /* i : total bitrate */ + const Word16 rf_mode, /* i : flag to signal the RF mode */ + const Word16 element_mode /* i : IVAS element mode */ +); + +//tcx_mdct_window.c +void mdct_window_sine(PWord16 *window, Word16 n); + +void mdct_window_sine_IVAS_updated( + PWord16 *window, + const int32_t Fs, + const int16_t n, + const int16_t window_type, + const int16_t element_mode); + +void mdct_window_aldo( + Word16 *window1, + PWord16 *window1_trunc, + PWord16 *window2, + Word16 n +); + +//tcx_utils.c +Word16 getInvFrameLen(const Word16 L_frame); /* returns 1/L_frame in Q21 format */ + +void WindowSignal( + TCX_CONFIG_HANDLE hTcxCfg, /* i : configuration of TCX */ + Word16 offset, /* i : left folding point offset relative to the i signal pointer */ + const Word16 left_overlap_mode, /* i : overlap mode of left window half */ + Word16 right_overlap_mode, /* i : overlap mode of right window half */ + Word16* left_overlap_length, /* o : TCX window left overlap length */ + Word16* right_overlap_length, /* o : TCX window right overlap length */ + const Word16 in[], /* i : i signal */ + Word16* L_frame, /* i/o: frame length */ + Word16 out[], /* o : output windowed signal */ + const Word16 truncate_aldo, /* i : nonzero to truncate long ALDO slope */ + const Word8 fullband /* i : fullband flag */ +); + +void tcx_windowing_synthesis_current_frame( + Word16* signal, /* i/o: signal vector */ + const PWord16* window, /* i: TCX window vector */ + const PWord16* window_half, /* i: TCX window vector for half-overlap window */ + const PWord16* window_min, /* i: TCX minimum overlap window */ + const Word16 window_length, /* i: TCX window length */ + const Word16 window_half_length, /* i: TCX half window length */ + const Word16 window_min_length, /* i: TCX minimum overlap length */ + const Word16 left_rect, /* i: left part is rectangular */ + const Word16 left_mode, /* i: overlap mode of left window half */ + Word16* acelp_zir, /* i: acelp ZIR */ + const Word16* old_syn, + const Word16* syn_overl, + const Word16* A_zir, + const PWord16* window_trans, + Word16 acelp_zir_len, + const Word16 acelp_mem_len, + const Word16 last_core_bfi, /* i : last core */ + const Word8 last_is_cng, + const Word16 fullbandScale +); + +void tcx_windowing_synthesis_past_frame( + Word16 *signal, /* i/o: signal vector */ + const PWord16 *window, /* i: TCX window vector */ + const PWord16 *window_half, /* i: TCX window vector for half-overlap window */ + const PWord16 *window_min, /* i: TCX minimum overlap window */ + const Word16 window_length, /* i: TCX window length */ + const Word16 window_half_length, /* i: TCX half window length */ + const Word16 window_min_length, /* i: TCX minimum overlap length */ + const Word16 right_mode /* i: overlap mode (left_mode of current frame) */ +); + +void lpc2mdct( + Word16* lpcCoeffs, + const Word16 lpcOrder, + Word16* mdct_gains, + Word16* mdct_gains_exp, + Word16* mdct_inv_gains, + Word16* mdct_inv_gains_exp, + const Word16 length, + const Word16 noInverse +); + +void mdct_shaping( + Word32 x[], + const Word16 lg, + const Word16 gains[], + const Word16 gains_exp[] +); + +void mdct_shaping_16( + const Word16 x[], + const Word16 lg, + const Word16 lg_total, + const Word16 gains[], + const Word16 gains_exp[], + Word16 gains_max_exp, Word32 y[] +); + +void mdct_noiseShaping_interp( + Word32 x[], + const Word16 lg, + Word16 gains[], + Word16 gains_exp[] +); + +void PsychAdaptLowFreqDeemph(Word32 x[], + const Word16 lpcGains[], const Word16 lpcGains_e[], + Word16 lf_deemph_factors[] +); + +void AdaptLowFreqDeemph(Word32 x[], Word16 x_e, + Word16 tcx_lpc_shaped_ari, + Word16 lpcGains[], Word16 lpcGains_e[], + const Word16 lg, + Word16 lf_deemph_factors[] +); + +void tcx_noise_filling( + Word32* Q, + Word16 Q_e, + Word16 seed, + const Word16 iFirstLine, + const Word16 lowpassLine, + const Word16 nTransWidth, + const Word16 L_frame, + const Word16 tiltCompFactor, + Word16 fac_ns, + Word16* infoTCXNoise, + const Word16 element_mode /* i : IVAS element mode */ +); + +void InitTnsConfigs( + const Word16 bwidth, + const Word16 L_frame, + STnsConfig tnsConfig[2][2], + const Word16 igfStopFreq, + const Word32 total_brate, + const Word16 element_mode, + const Word16 is_mct +); + +void SetTnsConfig( + TCX_CONFIG_HANDLE hTcxCfg, /* i : configuration of TCX */ + Word8 isTCX20, + Word8 isAfterACELP +); + +void tcx_get_gain(Word32 *x, /* i: spectrum 1 */ + Word16 x_e, /* i: spectrum 1 exponent */ + Word32 *y, /* i: spectrum 2 */ + Word16 y_e, /* i: spectrum 2 exponent */ + Word16 n, /* i: length */ + Word16 *gain, /* o: gain */ + Word16 *gain_e, /* o: gain exponent */ + Word32 *en_y, /* o: energy of y (optional) */ + Word16 *en_y_e /* o: energy of y exponent (optional) */ +); + +void init_TCX_config( + TCX_CONFIG_HANDLE hTcxCfg, + Word16 L_frame, + Word16 fscale + , Word16 L_frameTCX + , Word16 fscaleFB +); + +//tec_com.c +void +resetTecDec_Fx( + TEC_DEC_HANDLE hTecDec +); + + +void resetTecEnc_Fx( + TEC_ENC_HANDLE hTECEnc, + Word16 flag +); + +void calcGainTemp_TBE_Fx( + Word32** pCldfbRealSrc_Fx, + Word32** pCldfbImagSrc_Fx, + Word16 cldfb_exp, + Word16* loBuffer_Fx, + const Word16 startPos, /*!< Start position of the current envelope. */ + const Word16 stopPos, /*!< Stop position of the current envelope. */ + const Word16 lowSubband, /* lowSubband */ + Word16* pGainTemp_m, + Word16* pGainTemp_e, + const Word16 code +); + +Word16 procTecTfa_TBE_Fx(Word16 *hb_synth_Fx, + Word16 hb_synth_fx_exp, + Word16 *gain_m, + Word16 *gain_e, + Word16 flat_flag, + Word16 last_core + , Word16 l_subfr + , Word16 code +); + +void calcHiEnvLoBuff_Fix( + const Word16 noCols, + const Word16* pFreqBandTable, /*!< freqbandTable. */ + const Word16 nSfb, /*!< Number of scalefactors. */ + Word32** pCldfbPow_Fix /*float** pCldfbPow*/, + Word16* loBuffer_Fix /*float* loBuffer Q8*/, + Word16* hiTempEnvOrig_Fix /*float* hiTempEnvOrig*/, + Word16 pCldfbPow_FixScale +); + +void calcLoEnvCheckCorrHiLo_Fix( + const Word16 noCols, + const Word16* pFreqBandTable, /*!< freqbandTable. */ + Word16* loBuffer_Fix /*float* loBuffer Q8*/, + Word16* loTempEnv_Fix /*float* loTempEnv Q7*/, + Word16* loTempEnv_ns_Fix /* float* loTempEnv_ns*/, + Word16* hiTempEnvOrig_Fix /*float* hiTempEnvOrig*/, + Word16* corrFlag /*int* corrFlag*/ +); + +void tecEnc_TBE_fx( + Word16* corrFlag, + const Word16* voicing, + const Word16 coder_type +); + +void set_TEC_TFA_code_fx(const Word16 corrFlag, Word16* tec_flag, Word16* tfa_flag); + +//tcx_mdct_fx.c +void TCX_MDCT( + const Word16* x, + Word32* y, + Word16* y_e, + const Word16 l, + const Word16 m, + const Word16 r, + const Word16 element_mode +); + +void TCX_MDST( + const Word16* x, + Word32* y, + Word16* y_e, + const Word16 l, + const Word16 m, + const Word16 r, + const Word16 element_mode +); + +void TCX_MDCT_Inverse( + Word32* x, + Word16 x_e, + Word16* y, + const Word16 l, + const Word16 m, + const Word16 r, + const Word16 element_mode +); +//edct_fx.c +#define EDCT_FACTOR_SCALE 2 +void edct_fx( + const Word32 *x, /* i : i signal Qq */ + Word32 *y, /* o : output transform Qq */ + Word16 length, /* i : length */ + Word16 *q /* i : Q value of i signal */ +); + +void edst_fx( + const Word32 *x, /* i : i signal Qq */ + Word32 *y, /* o : output transform Qq */ + Word16 length, /* i : length */ + Word16 *q /* i : Q value of i signal */ +); + +void edct_16fx( + const Word16 *x, /* i : i signal Qx */ + Word16 *y, /* o : output transform Qx */ + Word16 length, /* i : length */ + Word16 bh, /* bit-headroom */ + const Word16 element_mode +); + +void iedct_short_fx( + const Word32 *in, /* i : i vector */ + Word16 *Q, /* i/o: Q value of i */ + Word32 *out, /* o : output vector */ + const Word16 segment_length /* i : length */ +); + +//fft_evs.c +void fft16(Word32 *re, Word32 *im, Word16 s, Word16 bScale); +void BASOP_cfft(cmplx *pComplexBuf, Word16 sizeOfFft, Word16 *scale, Word32 workBuffer[2 * BASOP_CFFT_MAX_LENGTH]); +void BASOP_rfft(Word32 *x, Word16 sizeOfFft, Word16 *scale, Word16 isign); + +//fft_fx_evs.c +void DoRTFTn_fx( + Word32 *x, /* i/o : real part of i and output data */ + Word32 *y, /* i/o : imaginary part of i and output data */ + const Word16 n /* i : size of the FFT up to 1024 */ +); +void edct2_fx( + Word16 n, + Word16 isgn, + Word16 *in, + Word32 *a, + Word16 *q, + const Word16 *ip, + const Word16 *w +); +void DoRTFT160_16fx( + Word16 x[], /* i/o : real part of i and output data */ + Word16 y[] /* i/o : imaginary part of i and output data */ +); + +void DoRTFT320_16fx( + Word16 *x, /* i/o : real part of i and output data */ + Word16 *y /* i/o : imaginary part of i and output data */ +); +void DoRTFT128_16fx( + Word16 *x, /* i/o : real part of i and output data Q(Qx+Q_edct)*/ + Word16 *y /* i/o : imaginary part of i and output data Q(Qx+Q_edct)*/ +); +void fft3_fx(const Word16[], Word16[], const Word16); +void ifft3_fx(const Word16[], Word16[], const Word16); + +//fft_rel_fx.c +void r_fft_fx_lc( + const Word16 *phs_tbl, /* i : Table of phase */ + const Word16 SIZE, /* i : Size of the FFT */ + const Word16 SIZE2, /* i : Size / 2 */ + const Word16 NUM_STAGE, /* i : Number of stage */ + const Word16 *in_ptr, /* i : coeffients in the order re[0], re[1], ... re[n/2], im[1], im[2], ..., im[n/2-1] */ + Word16 *out_ptr, /* o : coeffients in the order re[0], re[1], ... re[n/2], im[1], im[2], ..., im[n/2-1] */ + const Word16 isign /* i : 1=fft, otherwize it's ifft */ +); + +//cldfb_evs +void +cldfbAnalysisFiltering(HANDLE_CLDFB_FILTER_BANK anaCldfb, /*!< Handle of Cldfb Analysis Bank */ + Word32 **cldfbReal, /*!< Pointer to real subband slots */ + Word32 **cldfbImag, /*!< Pointer to imag subband slots */ + CLDFB_SCALE_FACTOR *scaleFactor, /*!< Scale factors of CLDFB data */ + const Word16 *timeIn, /*!< Time signal */ + const Word16 timeIn_e, /*!< Time signal */ + const Word16 nTimeSlots, /*!< Time slots to be processed */ + Word32 *pWorkBuffer /*!< pointer to temporal working buffer */ +); + +void +cldfbSynthesisFiltering(HANDLE_CLDFB_FILTER_BANK synCldfb, /*!< Handle of Cldfb Synthesis Bank */ + Word32 **CldfbBufferReal, /*!< Pointer to 32 bit real subband slots */ + Word32 **CldfbBufferImag, /*!< Pointer to 32 bit imag subband slots */ + const CLDFB_SCALE_FACTOR *scaleFactor, /*!< Scale factors of CLDFB data */ + Word16 *timeOut, /*!< Time signal */ + const Word16 timeOut_e, /*!< Target exponent for output signal */ + const Word16 nTimeSlots, /*!< number of time slots to be processed */ + Word32 *pWorkBuffer /*!< pointer to temporal working buffer */ +); + +void configureCldfb(HANDLE_CLDFB_FILTER_BANK h_cldfb, /*!< CLDFB Handle */ + const Word16 no_channels, /*!< Number of critically sampled bands */ + const Word16 frameSize /*!< FrameSize */ +); + +ivas_error openCldfb(HANDLE_CLDFB_FILTER_BANK *h_cldfb, /*!< CLDFB Handle */ + const Word16 type, /*!< analysis or synthesis */ + const Word16 maxCldfbBands, /*!< number of cldfb bands */ + const Word16 frameSize /*!< FrameSize */ +); +void resampleCldfb( + HANDLE_CLDFB_FILTER_BANK hs, /*!< CLDFB Handle */ + const Word16 newCldfbBands, /*!< number of cldfb bands */ + const Word16 frameSize, /*!< FrameSize */ + const Word8 firstFrame +); +Word16 +AnalysisPostSpectrumScaling_Fx(HANDLE_CLDFB_FILTER_BANK cldfbBank, + Word32 **rSubband32, + Word32 **iSubband32, + Word16 **rSubband16, + Word16 **iSubband16, + Word16 *cldfbScale +); + +void analysisCldfbEncoder_fx( + Encoder_State *st_fx, /* i/o: encoder state structure */ + const Word16 *timeIn, + Word32 realBuffer[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word32 imagBuffer[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word16 realBuffer16[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word16 imagBuffer16[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word32 enerBuffSum[CLDFB_NO_CHANNELS_MAX], + Word16 *enerBuffSum_exp, + CLDFB_SCALE_FACTOR * scale +); + +void +GetEnergyCldfb(Word32 *energyLookahead, /*!< o: Q31 | pointer to the result in the core look-ahead slot */ + Word16 *sf_energyLookahead, /*!< o: pointer to the scalefactor of the result in the core look-ahead slot - apply as negative exponent*/ + const Word16 numLookahead, /*!< i: Q0 the number of look-ahead time-slots */ + Word16 **realValues, /*!< i: Q15 | the real part of the CLDFB subsamples */ + Word16 **imagValues, /*!< i: Q15 | the imaginary part of the CLDFB subsamples */ + Word16 sf_Values, /*!< i: scalefactor of the CLDFB subcamples - apply as a negated Exponent */ + Word16 numberBands, /*!< i: Q0 | number of CLDFB bands */ + Word16 numberCols, /*!< i: Q0 | number of CLDFB subsamples */ + Word32 *energyHF, /*!< o: Q31 | pointer to HF energy */ + Word16 *energyHF_Exp, /*!< o: pointer to exponent of HF energy */ + Word32 *energyValuesSum, /*!< o: Q31 | pointer to sum array of energy values, not initialized*/ + Word16 *energyValuesSum_Exp, /*!< o: pointer to exponents of energyValuesSum, not initialized */ + TEC_ENC_HANDLE hTECEnc +); + +Word16 +CLDFB_getNumChannels(Word32 sampleRate); + +void +deleteCldfb(HANDLE_CLDFB_FILTER_BANK * h_cldfb); /*!< CLDFB Handle */ + +ivas_error cldfb_save_memory(HANDLE_CLDFB_FILTER_BANK hs); /* i/o: cldfb handle */ +void cldfb_restore_memory(HANDLE_CLDFB_FILTER_BANK hs); /* i/o: cldfb handle */ +void cldfb_reset_memory(HANDLE_CLDFB_FILTER_BANK hs); /* i/o: cldfb handle */ + +//bits_alloc.c from IVAS +void BITS_ALLOC_init_config_acelp( + const Word32 bit_rate, + const Word8 narrowBand, + const Word16 nb_subfr, + ACELP_config *pConfigAcelp /*o: configuration structure of ACELP*/ +); + +Word16 BITS_ALLOC_config_acelp( + const Word16 bits_frame, /*i: remaining bit budget for the frame */ + const Word16 coder_type, /*i: coder type */ + ACELP_config *pConfigAcelp, /*i/o: configuration structure of ACELP*/ + const Word16 narrowband, + const Word16 nb_subfr +); + +ivas_error config_acelp1( + const Word16 enc_dec, /* i : encoder/decoder flag */ + const Word32 total_brate, /* i : total bitrate */ + const Word32 core_brate_inp, /* i : core bitrate */ + const Word16 core, /* i : core */ + const Word16 extl, /* i : extension layer */ + const Word32 extl_brate, /* i : extension layer bitrate */ + const Word16 L_frame, /* i : frame length at internal Fs */ + const Word16 GSC_noisy_speech, /* i : GSC on SWB noisy speech flag */ + ACELP_config* acelp_cfg, /* i : ACELP bit-allocation */ + const Word16 signalling_bits, /* i : number of signalling bits */ + const Word16 coder_type, /* i : coder type */ + const Word16 tc_subfr, /* i : TC subfr ID */ + const Word16 tc_call, /* i : TC call number (0,1,2,3,5(DEC)) */ + Word16* nBits_es_Pred, /* o : number of bits for Es_pred Q */ + Word16* unbits, /* o : number of unused bits */ + const Word16 element_mode, /* i : element mode */ + Word16* uc_two_stage_flag, /* o : flag undicating two-stage UC */ + const Word16 tdm_lp_reuse_flag, /* i : LPC reuse flag (can be 1 only with secondary channel */ + const Word16 tdm_low_rate_mode, /* i : secondary channel low rate mode flag */ + const Word16 idchan, /* i : stereo channel ID */ + const Word16 active_cnt, /* i : Active frame counter */ + const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag*/ + const Word16 tdm_LRTD_flag, /* i : LRTD stereo mode flag */ + const Word16 GSC_IVAS_mode /* i : GSC IVAS mode */ +); + +Word16 set_ACELP_flag( + const Word16 element_mode, /* i : element mode */ + const Word32 element_brate, /* i : element bitrate */ + const Word32 total_brate, /* i : total bitrate per channel */ + const Word16 idchan, /* i : Channel id */ + const Word16 tdm_LRTD_flag, /* i : LRTD stereo mode flag */ + const Word16 bwidth, /* i : audio bandwidth */ + const Word16 cng_type /* i : CNG type */ +); +//syn_128_fx.c +void syn_12k8_fx( + Word16 L_frame, + const Word16 *Aq, /* i : LP filter coefficients Q12 */ + const Word16 *exc, /* i : i signal Q_exc */ + Word16 *synth, /* o : output signal Q_syn */ + Word16 *mem, /* i/o: initial filter states Q_syn */ + const Word16 update_m, /* i : update memory flag: 0 --> no memory update Q0 */ + /* 1 --> update of memory */ + const Word16 Q_exc, /* i : Excitation scaling Q0 */ + const Word16 Q_syn /* i : Synthesis scaling Q0 */ +); +//est_tilt_fx.c +Word16 est_tilt_fx( /* o : tilt of the code Q15 */ + const Word16 *exc, /* i : adaptive excitation vector Qx */ + const Word16 gain_pit, /* i : adaptive gain Q14 */ + const Word16 *code, /* i : algebraic exctitation vector Q9 */ + const Word32 gain_code, /* i : algebraic code gain Q16 */ + Word16 *voice_fac, /* o : voicing factor Q15 */ + const Word16 Q_exc /* i : Scaling factor of excitation Q0 */ +#ifdef ADD_LRTD + , const Word16 L_subfr /* i : Sub frame lenght */ +#endif +); +Word16 Est_tilt2( /* o : tilt of the code */ + const Word16 *exc, /* i : adaptive excitation vector Qx */ + const Word16 gain_pit, /* i : adaptive gain Q14 */ + const Word16 *code, /* i : algebraic exctitation vector Q9 */ + const Word32 gain_code, /* i : algebraic code gain Q16 */ + Word16 *voice_fac, /* o : voicing factor Q15 */ + const Word16 Q_exc /* i : Scaling factor of excitation Q0 */ +); + +void E_UTIL_voice_factor(Word16 *exc, /* i : pointer to the excitation frame Q_new */ + Word16 i_subfr, /* i : subframe index */ + Word16 *code, /* i : innovative codebook Q9 */ + Word16 gain_pit, /* i : adaptive codebook gain 1Q14 */ + Word32 gain_code, /* i : innovative cb. gain 15Q16 */ + Word16 *voice_fac, /* o : subframe voicing estimation Q15 */ + Word16 *tilt_code, /* o : tilt factor Q15 */ + Word16 L_subfr, /* i : subframe length */ + Word16 flag_tilt, /* i : Flag for triggering new voice factor tilt*/ + Word16 Q_new, /* i : excitation buffer format */ + Word16 shift /* i : scaling to get 12bit */ +); + +//window_ola_fx.c +void sinq_fx( + const Word16 tmp, /* i : sinus factor cos(tmp*i+phi) Q15*/ + const Word16 phi, /* i : sinus phase cos(tmp*i+phi) Q15*/ + const Word16 N, /* i : size of output */ + Word16 x[] /* o : output vector Q15*/ +); + +void window_ola_fx( + Word32 *ImdctOut, + Word16 *auOut, + Word16 *Q_sig, + Word16 *OldauOut, + Word16 *Q_old, + const Word16 L, + const Word16 right_mode, + const Word16 left_mode, + const Word16 old_bfi, + const Word16 oldHqVoicing, + Word16 *oldgapsynth); + +void core_switching_OLA_fx( + Word16 *mem_over_hp, /* i : upsampling filter memory Q0 */ + const Word16 last_L_frame, /* i : last L_frame lengthture */ + const Word32 output_Fs, /* i : output sampling rate */ + Word16 *synth, /* i/o: synthesized signal from HQ core Q0 */ + Word16 *synth_subfr_out, /* i : synthesized signal from ACELP core Q0 */ + Word16 *synth_subfr_bwe, /* i : synthesized BWE from ACELP core Q0 */ + const Word16 output_frame, /* i : output frame length */ + const Word16 bwidth, /* i : output bandwidth */ + Word16* Qsynth, + Word16* Qsubfr +); + void window_ola_ext_fx( - const Word32 *ImdstOut, /* i : input */ - Word32 *auOut, /* o : output audio */ - Word32 *OldauOut, /* i/o: audio from previous frame */ - const Word16 L, /* i : length */ - const Word16 right_mode, - const Word16 left_mode, /* i : window overlap of current frame (0: full, 2: none, or 3: half) */ - const UWord16 kernel_type /* i : transform kernel type */ + const Word32 *ImdstOut, /* i : input */ + Word32 *auOut, /* o : output audio */ + Word32 *OldauOut, /* i/o: audio from previous frame */ + const Word16 L, /* i : length */ + const Word16 right_mode, + const Word16 left_mode, /* i : window overlap of current frame (0: full, 2: none, or 3: half) */ + const UWord16 kernel_type /* i : transform kernel type */ +); + +//cb_shape_fx.c +void cb_shape_fx( + const Word16 preemphFlag, /* i : flag for pre-emphasis */ + const Word16 pitchFlag, /* i : flag for pitch sharpening */ + const Word16 scramblingFlag, /* i : flag for phase scrambling */ + const Word16 sharpFlag, /* i : flag for formant sharpening */ + const Word16 formantTiltFlag, /* i : flag for formant tilt */ + const Word16 g1, /* i : formant sharpening numerator weighting */ + const Word16 g2, /* i : formant sharpening denominator weighting */ + const Word16 *p_Aq, /* i : LP filter coefficients */ + Word16 *code, /* i/o: signal to shape */ + const Word16 tilt_code, /* i : tilt of code */ + const Word16 pt_pitch, /* i : pointer to current subframe fractional pitch */ + const Word16 shift + , const Word16 L_subfr /* i : subframe lenght */ +); + +//longarith.c +void longadd( + uint16_t a[], /* i/o: vector of the length lena */ + const uint16_t b[], /* i/o: vector of the length lenb */ + const int16_t lena, /* i/o: length of vector a[] */ + const int16_t lenb /* i/o: length of vector b[] */ +); + +void longshiftright( + uint16_t a[], /* i : vector of the length lena */ + const int16_t b, /* i : number of bit positions to shift right */ + uint16_t d[], /* o : vector of the length lend */ + int16_t lena, /* i : length of vector a[] */ + const int16_t lend /* i : length of vector d[] */ +); + +void longshiftleft( + const uint16_t a[], /* i : vector of the length len */ + const int16_t b, /* i : number of bit positions to shift left */ + uint16_t d[], /* o : vector of the length len */ + const int16_t len /* i : length of vector a[] and d[] */ +); + +void longshr( + UWord32 a[], + Word16 bits, + Word16 len +); + +//gs_bitallocation.c +void bands_and_bit_alloc_fx( + const Word16 cor_strong_limit, /* i : HF correlation */ + const Word16 noise_lev, /* i : dwn scaling factor */ + const Word32 core_brate, /* i : core bit rate */ + const Word16 Diff_len, /* i : Lenght of the difference signal (before pure spectral)*/ + const Word16 bits_used, /* i : Number of bit used before frequency Q */ + Word16* bit, /* i/o: Number of bit allowed for frequency quantization */ + const Word16* Ener_per_bd_iQ, /* i/o: Quantized energy vector */ + Word16* max_ener_band, /* o : Sorted order */ + Word16* out_bits_per_bands, /* i/o: Number of bit allowed per allowed subband Q3 */ + Word16* nb_subbands, /* o : Number of subband allowed */ + const Word16* exc_diff, /* i : Difference signal to quantize (encoder side only) */ + Word16* concat_in, /* o : Concatened PVQ's i vector (encoder side only) */ + Word16* pvq_len, /* o : Number of bin covered with the PVQ */ + const Word16 coder_type, /* i : coding type */ + const Word16 bwidth, /* i : i signal bandwidth */ + const Word16 GSC_noisy_speech, /* i : GSC noisy speech flag */ + const Word16 L_frame, /* i : frame length */ + const Word16 element_mode, /* i : element mode */ + const Word16 GSC_IVAS_mode /* i : GSC IVAS mode */ +); + +//low_rate_band_att_fx.c +void fine_gain_pred_fx( + const Word16 *sfm_start, /* i : Sub band start indices */ + const Word16 *sfm_end, /* i : Sub band end indices */ + const Word16 *sfm_size, /* i : Sub band bandwidths */ + const Word16 *i_sort, /* i : Energy sorting indices */ + const Word16 *K, /* i : Number of pulses per band */ + const Word16 *maxpulse, /* i : Maximum pulse per band */ + const Word16 *R, /* i : Bits per sub band Q3 */ + const Word16 num_sfm, /* i : Number of sub bands */ + Word16 *xq, /* i/o: Quantized vector /quantized vector with finegain adj Q15*/ + Word16 *y, /* i/o: Quantized vector (int) */ + Word16 *fg_pred, /* o : Predicted fine gains Q12 */ + const Word16 core /* i : Core */ ); +void fine_gain_quant_fx( + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + const Word16 *ord, /* i : Indices for energy order */ + const Word16 num_sfm, /* i : Number of bands */ + const Word16 *gain_bits, /* i : Gain adjustment bits per sub band */ + Word16 *fg_pred, /* i/o: Predicted gains / Corrected gains Q12 */ + const Word16 *gopt /* i : Optimal gains Q12 */ +); + +void get_max_pulses_fx( + const Word16 *band_start, /* i : Sub band start indices */ + const Word16 *band_end, /* i : Sub band end indices */ + const Word16 *k_sort, /* i : Indices for sorting by energy */ + const Word16 *npulses, /* i : Pulses per sub band */ + const Word16 BANDS, /* i : Number of bands */ + Word16 *inp_vector, /* i/o: Encoded shape vectors (int)*/ + Word16 *maxpulse /* o : Maximum pulse height per band */ +); +void fine_gain_dec_fx +( + Decoder_State *st, + const Word16 *ord, /* i : Indices for energy order */ + const Word16 num_sfm, /* i : Number of bands */ + const Word16 *gain_bits, /* i : Gain adjustment bits per sub band */ + Word16 *fg_pred /* i/o: Predicted gains / Corrected gains */ +); + +//fine_gain_bits_fx.c +Word16 assign_gain_bits_fx( /* o : Number of assigned gain bits */ + const Word16 core, /* i : HQ core */ + const Word16 BANDS, /* i : Number of bands */ + const Word16 *band_width, /* i : Sub band bandwidth */ + Word16 *Rk, /* i/o: Bit allocation/Adjusted bit alloc. Q3 */ + Word16 *gain_bits_array, /* o : Assigned gain bits */ + Word16 *Rcalc /* o : Bit budget for shape quantizer Q3 */ +); + +//gs_noisefill.c +void freq_dnw_scaling_fx( + const Word16 cor_strong_limit, /* i : HF correlation */ + const Word16 coder_type, /* i : coder type */ + const Word16 noise_lev, /* i : Noise level */ + const Word32 core_brate, /* i : Core bitrate */ + Word16 fy_norm[], /* i/o: Frequency quantized parameter */ + Word16 Qx, /* Q format of fy_norm*/ + const Word16 L_frame /* i : frame length */ +); + +void highband_exc_dct_in_fx( + const Word32 core_brate, /* i : core bitrate */ + const Word16* mfreq_bindiv, /* i : bin per bands tables */ + Word16 last_bin, /* i : last bin of bit allocation */ + Word16 Diff_len, /* i : number of bin before cut-off frequency */ + Word16 noise_lev, /* i : pulses dynamic */ + Word16 pit_band_idx, /* i : bin position of the cut-off frequency */ + Word16* exc_diffQ, /* i : frequency coefficients of per band */ + Word16* seed_tcx, /* i : Seed for noise */ + Word16* Ener_per_bd_iQ, /* i : Quantized energy of targeted vector */ + Word16 nb_subfr, /* i : Number of subframe considered */ + Word16* exc_dct_in, /* o : dct of residual signal */ + Word16 last_coder_type, /* i : coding type of last frame */ + Word16* bitallocation_band, /* i : bit allocation flag of each band */ + const Word16* lsf_new, /* i : LSFs at the end of the frame */ + Word16* last_exc_dct_in, /* i : dct of residual signal of last frame */ + Word16* last_ener, /* i : frequency energy of last frame */ + Word16* last_bitallocation_band, /* i : bit allocation flag of each band of last frame */ + Word16* bitallocation_exc, /* i : flag of decoded coefficients */ + Word16 bfi, /* i : bad frame indicator */ + const Word16 coder_type, /* i : coder type */ + Word16 bwidth, + Word16* exc_wo_nf, /* o : temporal excitation (in f domain) without noisefill */ + Word16 Qexc_diffQ, + Word16 Q_exc, + const Word16 GSC_noisy_speech + , Word16* lt_ener_per_band_fx, /* i/o: Average per band energy */ + const Word16 L_frame, /* i : frame length */ + const Word16 element_mode, /* i : IVAS element mode */ + const Word16 GSC_IVAS_mode /* i : GSC IVAS mode */ +); + +//lsf_dec_bfi_fx.c +void lsf_dec_bfi( + const Word16 codec_mode, /* i: : codec mode: MODE1 | MODE2 */ + Word16* lsf, /*!< o : 14Q1*1.28 quantized ISFs */ + const Word16* lsfold, /*!< i : 14Q1*1.28 past quantized ISF */ + Word16* lsf_adaptive_mean, /*!< i : 14Q1*1.28 ISF adaptive mean, updated when BFI==0 */ + const Word16 lsfBase[], /* i : base for differential lsf coding */ + Word16* mem_MA, /*!< i/o: 14Q1*1.28 quantizer memory for MA model */ + Word16* mem_AR, /*!< i/o: 14Q1*1.28 quantizer memory for MA model */ + Word16 stab_fac, /*!< i : ISF stability factor (shifted right by 1) */ + const Word16 last_coder_type,/*!< i : coding type in last good received fr. */ + Word16 L_frame, + const Word16 last_good, /*!< i : last good received frame */ + const Word16 nbLostCmpt, /*!< i : counter of consecutive bad frames */ + const Word8 plcBackgroundNoiseUpdated, /* i : background noise already updated?*/ + Word16* lsf_q_cng, /* o : quantized ISFs for background noise (14Q1*1.28) */ + Word16* lsf_cng, + Word16* old_lsf_q_cng, /* o : old quantized ISFs for background noise */ + const Word16 Last_GSC_pit_band_idx, + const Word16 Opt_AMR_WB, /* i : IO flag */ + const Word8 tcxonly, + const short bwidth /* i: coded bandwidth */ +); + +Word16 const * PlcGetLsfBase(Word16 const lpcQuantization, + Word16 const narrowBand, + Word32 const sr_core); + +//fd_cng_com.c +/* Create an instance of type FD_CNG */ +ivas_error createFdCngCom(HANDLE_FD_CNG_COM* hFdCngCom); + +void initFdCngCom(HANDLE_FD_CNG_COM hFdCngCom, Word16 scale); + +/* Delete the instance of type FD_CNG */ +void deleteFdCngCom(HANDLE_FD_CNG_COM * hFdCngCom); + +/* Initialize the spectral partitioning */ +void initPartitions( + const Word16* part_in, + const Word16 npart_in, + const Word16 startBand, + const Word16 stopBand, + Word16* part_out, + Word16* npart_out, + Word16* midband, + Word16* psize, + Word16* psize_norm, + Word16* psize_norm_exp, + Word16* psize_inv, + const Word16 stopBandFR +); + +/* Noise estimation using Minimum Statistics (MS) */ +void compress_range( + Word32* in, + Word16 in_exp, + Word16* out, + const Word16 len +); + +void expand_range( + Word16* in, + 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 */ + Word16 *msPeriodog, /* i : Periodogram (energies) */ + Word16 *msNoiseFloor, /* i/o: Noise floors (energies) */ + Word16 *msNoiseEst, /* i/o: Noise estimates (energies) */ + Word32 *msAlpha, /* i/o: Forgetting factors */ + Word16 *msPsd, /* i/o: Power Spectral Density (smoothed periodogram => energies) */ + Word16 *msPsdFirstMoment, /* i/o: PSD statistics of 1st order (energy means) */ + Word32 *msPsdSecondMoment, /* i/o: PSD statistics of 2nd order (energy variances) */ + Word32 *msMinBuf, /* i/o: Buffer of minima (energies) */ + Word32 *msBminWin, /* o : Bias correction factors */ + Word32 *msBminSubWin, /* o : Bias correction factors */ + Word32 *msCurrentMin, /* i/o: Local minima (energies) */ + Word32 *msCurrentMinOut, /* i/o: Local minima (energies) */ + Word32 *msCurrentMinSubWindow, /* i/o: Local minima (energies) */ + Word16 *msLocalMinFlag, /* i : Binary flag */ + Word16 *msNewMinFlag, /* i : Binary flag */ + Word16 *msPeriodogBuf, /* i/o: Buffer of periodograms (energies) */ + Word16 *msPeriodogBufPtr, /* i/o: Counter */ + HANDLE_FD_CNG_COM st /* i/o: FD_CNG structure containing buffers and variables */ +); +/* Apply bitrate-dependant scale */ +void apply_scale( + Word32* scale, /* o : scalefactor */ + const Word16 bwmode, /* i : audio bandwidth */ + const Word32 bitrate, /* i : Bit rate */ + const SCALE_SETUP* scaleTable, /* i : Scale table */ + const Word16 scaleTableSize /* i : Size of scale table */ +); + +/* Compute the power for each partition */ +void bandcombinepow( + const Word32* bandpow, /* i : Power for each band */ + const Word16 exp_bandpow, /* i : exponent of bandpow */ + const Word16 nband, /* i : Number of bands */ + Word16* part, /* i : Partition upper boundaries (band indices starting from 0) */ + const Word16 npart, /* i : Number of partitions */ + const Word16* psize_inv, /* i : Inverse partition sizes */ + Word32* partpow, /* o : Power for each partition */ + Word16* exp_partpow +); + +/* Scale partitions (with smoothing) */ +void scalebands( + const Word32* partpow, /* i : Power for each partition */ + Word16* part, /* i : Partition upper boundaries (band indices starting from 0) */ + const Word16 npart, /* i : Number of partitions */ + Word16* midband, /* i : Central band of each partition */ + const Word16 nFFTpart, /* i : Number of FFT partitions */ + const Word16 nband, /* i : Number of bands */ + Word32* bandpow, /* o : Power for each band */ + const Word16 flag_fft_en +); +/* STFT analysis filterbank */ +void AnalysisSTFT( + const Word16* timeDomainInput, /* i : pointer to time signal */ + Word16 Q, + Word32* fftBuffer, /* o : FFT bins */ + Word16* fftBuffer_exp, /* i : exponent of FFT bins */ + HANDLE_FD_CNG_COM hFdCngCom /* i/o: FD_CNG structure containing all buffers and variables */ +); + +/* STFT synthesis filterbank */ +void SynthesisSTFT( + Word32* fftBuffer, /* i : pointer to FFT bins */ + Word16 fftBufferExp, /* i : exponent of FFT bins */ + Word16* timeDomainOutput, /* o : pointer to time domain signal */ + Word16* olapBuffer, /* i/o : pointer to overlap buffer */ + const PWord16* olapWin, /* i : pointer to overlap window */ + Word16 tcx_transition, + HANDLE_FD_CNG_COM hFdCngCom, /* i/o : pointer to FD_CNG structure containing all buffers and variables */ + Word16 gen_exc, + Word16* Q_new, + const Word16 element_mode, /* i : element mode */ + const Word16 nchan_out /* i : number of output channels */ +); + +void mhvals( + const Word16 d, + Word16* m /*, float * h*/ +); + +/* Random generator with Gaussian distribution with mean 0 and std 1 */ +Word32 rand_gauss(Word16 *seed); + +void lpc_from_spectrum( + HANDLE_FD_CNG_COM hFdCngCom, + const Word16 start, /*i : start band*/ + const Word16 stop, /*i : stop band*/ + const Word16 preemph_fac /*i : preemphase factor format Q1.15*/ +); + +void msvq_decoder( + const Word16* const cb[], /* i : Codebook (indexed cb[*stages][levels][p]) */ + const Word16 stages, /* i : Number of stages */ + const Word16 N, /* i : Vector dimension */ + const Word16 maxN, /* i : Codebook vector dimension */ + const Word16 Idx[], /* i : Indices */ + Word16* uq /* o : quantized vector */ +); + +void FdCng_exc( + HANDLE_FD_CNG_COM hs, + Word16 *CNG_mode, + Word16 L_frame, + Word16 *lsp_old, + Word16 first_CNG, + Word16 *lsp_CNG, + Word16 *Aq, /* o: LPC coeffs */ + Word16 *lsp_new, /* o: lsp */ + Word16 *lsf_new, /* o: lsf */ + Word16 *exc, /* o: LP excitation */ + Word16 *exc2, /* o: LP excitation */ + Word16 *bwe_exc /* o: LP excitation for BWE */ +); + +//trans_direct +void direct_transform_fx( + const Word32 in32_fx[], + Word32 out32_fx[], + const Word16 is_transient, + const Word16 L, + Word16 *Q, + const Word16 element_mode +); + +//trans_inv_fx.c +void preecho_sb_fx( + const Word32 brate, /* i Q0 : core bit-rate */ + Word32 *wtda_audio_fx, /* i q_sig32 : imdct signal */ + Word16 q_sig32, /* i Q value for wtda_audio_fx */ + Word16 *rec_sig_fx, /* i q_sig16 : reconstructed signal, output of the imdct transform */ + Word16 q_sig16, /* i Q value for rec_sig_fx and imdct_mem_fx */ + const Word16 framelength, /* i Q0 : frame length */ + Word16 *memfilt_lb_fx, /* i/o Q0 : memory */ + Word32 *mean_prev_hb_fx, /* i/o Q0 : memory */ + Word16 *smoothmem_fx, /* i/o Q15 : memory */ + Word32 *mean_prev_fx, /* i/o Q0 : memory */ + Word32 *mean_prev_nc_fx, /* i/o Q0 : memory */ + Word16 *wmold_hb_fx, /* i/o Q15 : memory */ + Word16 *prevflag, /* i/o Q0 : flag */ + Word16 *pastpre, /* i/o Q0 : flag */ + const Word16 bwidth /* i Q0 : bandwidth */ +); + +void Inverse_Transform( + const Word32 *in_mdct, /* i : i MDCT vector */ + Word16 *Q, /* i/o: Q value of i */ + Word32 *out, /* o : output vector */ + const Word16 is_transient, /* i : transient flag */ + const Word16 L, /* i : output frame length */ + const Word16 L_inner, /* i : length of the transform */ + const Word16 element_mode /* i : IVAS element mode */ +); + +//recovernorm +void recovernorm_fx( + const Word16* idxbuf, /* i : reordered quantization indices */ + Word16* ynrm, /* o : recovered quantization indices */ + Word16* normqlg2, /* o : recovered quantized norms */ + const Word16 nb_sfm /* i : number of SFMs */ +); + +//tcq_poition_qeith.c +Word32 ar_div(Word32 num, Word32 denum); + +void ar_encoder_start_fx(PARCODEC arInst, TCQ_PBITSTREAM bsInst, const Word32 max_bits); +void ar_encoder_done_fx(PARCODEC arInst); +void ar_decoder_start_fx(PARCODEC arInst, TCQ_PBITSTREAM bsInst); +void ar_decoder_done_fx(PARCODEC arInst); +Word32 GetISCScale_fx(Word32 *quants_fx, Word16 size, Word32 bits_fx, Word16 *magn_fx, Word32 *qscale_fx, Word32 *surplus_fx, Word16 *pulses, Word32* savedstates, Word32 noTCQ, Word16 *nzpout + , Word16 *bcount, Word32 *abuffer, Word16 *mbuffer, Word32 *sbuffer); + +void TCQLSB_fx( + Word16 bcount, + Word32 *abuffer_fx, + Word16 *mbuffer_fx, + Word32 *sbuffer_fx, + Word16 *dpath +); + +void TCQLSBdec_fx( + Word16 *dpath, + Word16 *mbuffer, + Word16 bcount +); + +void RestoreTCQ_fx( + Word16 * magn, + Word16 size, + Word16 *bcount, + Word16 *mbuffer +); + +void RestoreTCQdec_fx( + Word16 * magn, + Word16 size, + Word16 *bcount, + Word16 *mbuffer +); + +void InitLSBTCQ_fx( + Word16 *bcount +); + +void SaveTCQdata_fx( + PARCODEC arInst, + Word16 *dpath, + Word16 bcount +); + +void LoadTCQdata_fx( + PARCODEC arInst, + Word16 *dpath, + Word16 bcount +); + +Word32 encode_position_ari_fx(PARCODEC parenc, Word16* quants, Word16 size, Word32* est_bits_frame_fx); +Word32 encode_magnitude_usq_fx(ARCODEC* parenc, Word16* magn, Word16 size, Word16 npulses, Word16 nzpos, Word32* est_frame_bits_fx); +Word32 encode_magnitude_tcq_fx(ARCODEC* parenc, Word16* magn, Word16 size, Word16 npulses, Word16 nzpos, Word32* savedstates, Word32* est_frame_bits_fx); + +Word32 encode_signs_fx(ARCODEC* parenc, Word16* magn, Word16 size, Word16 npos, Word32* est_frame_bits_fx); + +void decode_position_ari_fx(PARCODEC pardec, Word16 size, Word16 npulses, Word16* nz, Word16* position); +void decode_magnitude_usq_fx(ARCODEC* pardec, Word16 size, Word16 npulses, Word16 nzpos, Word16* positions, Word16* out); +void decode_mangitude_tcq_fx(ARCODEC* pardec, Word16 size, Word16 npulses, Word16 nzpos, Word16* positions, Word16* out, Word32* surplus_fx); +void decode_signs_fx(ARCODEC* pardec, Word16 size, Word16* out); + +Word16 GetScale_fx(Word16 blen, Word32 bits_fx, Word32 *surplus_fx); + +void srt_vec_ind_fx(const Word32 *linear, Word32 *srt, Word16 *I, Word16 length); + +//fill_spectrum +void fill_spectrum_fx( + Word16 *coeff, /* i/o: normalized MLT spectrum / nf spectrum Q12 */ + Word32 *L_coeff_out, /* i/o: Noisefilled MLT spectrum Q12 */ + const Word16 *R, /* i : number of pulses per band Q0 */ + const Word16 is_transient, /* i : transient flag Q0 */ + Word16 norm[], /* i : quantization indices for norms Q0 */ + const Word16 *hq_generic_fenv, /* i : HQ GENERIC envelope Q1 */ + const Word16 hq_generic_offset, /* i : HQ GENERIC offset Q0 */ + const Word16 nf_idx, /* i : noise fill index Q0 */ + const Word16 length, /* i : Length of spectrum (32 or 48 kHz) Q0 */ + const Word16 env_stab, /* i : Envelope stability measure [0..1] Q15 */ + Word16 *no_att_hangover, /* i/o: Frame counter for attenuation hangover Q0 */ + Word32 *L_energy_lt, /* i/o: Long-term energy measure for transient detection Q13 */ + Word16 *bwe_seed, /* i/o: random seed for generating BWE i Q0 */ + const Word16 hq_generic_exc_clas, /* i : BWE excitation class Q0 */ + const Word16 core_sfm, /* i : index of the end band for core Q0 */ + const Word16 HQ_mode, /* i : HQ mode Q0 */ + Word16 noise_level[], /* i : noise levels for harmonic modes Q15 */ + const Word32 L_core_brate, /* i : target bit-rate Q0 */ + Word16 prev_noise_level[], /* i/o: noise factor in previous frame Q15 */ + Word16 *prev_R, /* i/o: bit allocation info. in previous frame Q0 */ + Word32 *prev_coeff_out, /* i/o: decoded spectrum in previous frame Q12 */ + const Word16 *peak_idx, /* i : peak indices for hvq Q0 */ + const Word16 Npeaks, /* i : number of peaks in hvq Q0 */ + const Word16 *npulses, /* i : number of pulses per band Q0 */ + const Word16 prev_is_transient, /* i : previous transient flag Q0 */ + Word32 *prev_normq, /* i/o: previous norms Q14 */ + Word32 *prev_env, /* i/o: previous noise envelopes Q(prev_env_Q) */ + const Word16 prev_bfi, /* i : previous bad frame indicator Q0 */ + const Word16 *sfmsize, /* i : Length of bands Q0 */ + const Word16 *sfm_start, /* i : Start of bands Q0 */ + const Word16 *sfm_end, /* i : End of bands Q0 */ + Word16 *prev_L_swb_norm, /* i/o: HVQ/Harmonic mode normalization length Q0 */ + const Word16 prev_hq_mode, /* i : Previous HQ mode Q0 */ + const Word16 num_sfm, /* i : Total number of bands Q0 */ + Word16 *prev_env_Q, + const Word16 num_env_bands, + const Word16 element_mode +); +//hq_bit_allocation_fx.c" +void hq_bit_allocation_fx( + const Word32 core_brate, /* i : Core bit-rate */ + const Word16 length, /* i : Frame length */ + const Word16 hqswb_clas, /* i : HQ class */ + Word16 *num_bits, /* i/o: Remaining bit budget */ + const Word16 *normqlg2, /* i : Quantized norms */ + const Word16 nb_sfm, /* i : Number sub bands to be encoded */ + const Word16 *sfmsize, /* i : Sub band bandwidths */ + Word16 *noise_level, /* o : HVQ noise level */ + Word16 *R, /* o : Bit allocation per sub band */ + Word16 *Rsubband, /* o : Fractional bit allocation */ + Word16 *sum, /* o : Sum of allocated shape bits */ + Word16 *core_sfm, /* o : Last coded band in core */ + const Word16 num_env_bands /* i : Number sub bands to be encoded for HQ_SWB_BWE */ +); + +//weight_fx.c +void map_quant_weight_fx( + const Word16 normqlg2[], /* i : quantized norms */ + Word16 wnorm[], /* o : weighted norm */ + const Word16 is_transient /* i : transient flag */ +); + +//bitalloc_fx.c +void bitalloc_fx( + Word16 *y, /* i : reordered norm of sub-vectors Q0 */ + Word16 *idx, /* i : reordered sub-vector indices Q0 */ + Word16 sum, /* i : number of available bits Q0 */ + Word16 N, /* i : number of norms Q0 */ + Word16 K, /* i : maximum number of bits per dimension Q0 */ + Word16 *r, /* o : bit-allacation vector Q0 */ + const Word16 *sfmsize, /* i : band length Q0 */ + const Word16 hqswb_clas /* i : signal classification flag Q0 */ +); +Word16 BitAllocF_fx( + Word16 *y, /* i : norm of sub-vectors :Q0 */ + Word32 bit_rate, /* i : bitrate :Q0 */ + Word16 B, /* i : number of available bits :Q0 */ + Word16 N, /* i : number of sub-vectors :Q0 */ + Word16 *R, /* o : bit-allocation indicator :Q0 */ + Word16 *Rsubband_fx, /* o : sub-band bit-allocation vector :Q3 */ + const Word16 hqswb_clas, /* i : hq swb class */ + const Word16 num_env_bands /* i : Number sub bands to be encoded for HQ_SWB_BWE */ +); +Word16 BitAllocWB_fx( /* o : t Q0*/ + Word16 *y, /* i : norm of sub-vectors Q0*/ + Word16 B, /* i : number of available bits Q0*/ + Word16 N, /* i : number of sub-vectors Q0*/ + Word16 *R, /* o : bit-allocation indicator Q0*/ + Word16 *Rsubband_fx /* o : sub-band bit-allocation vector Q3*/ +); +//bitallocsum_fx.c +void bitallocsum_fx( + Word16 *R, /* i : bit-allocation vector Q0 */ + const Word16 nb_sfm, /* i : number of sub-vectors Q0 */ + Word16 *sum, /* o : total number of bits allocated Q0 */ + Word16 *Rsubband, /* o : rate per subband Q3 */ + const Word16 num_bits,/* i : number of bits Q0 */ + const Word16 length, /* i : length of spectrum (32 or 48 kHz samplerate) Q0 */ + const Word16 *sfmsize /* i : band length Q0 */ +); + + +//stab_est_fx.c +Word16 stab_est_fx( + Word16 etot, /* i : Total energy of the current frame */ + Word16 *lt_diff_etot, /* i/o : Long term total energy variation */ + Word16 *mem_etot, /* i/o : Total energy memory */ + Word16 *nb_thr_3, /* i/o : Number of consecutives frames of level 3 */ + Word16 *nb_thr_1, /* i/o : Number of consecutives frames of level 1 */ + Word16 *thresh, /* i/o : Detection thresold */ + Word16 *last_music_flag,/* i/o : Previous music detection ouptut */ + const Word16 vad_flag /* i : VAD flag */ +); + +//enhancer_fx.c +void enhancer_fx( + const Word32 core_brate, /* i : decoder bitrate */ + const Word16 Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ + const Word16 coder_type, /* i : coder type */ + const Word16 i_subfr, /* i : subframe number */ + const Word16 L_frame, /* i : frame size */ + const Word16 voice_fac, /* i : subframe voicing estimation Q15 */ + const Word16 stab_fac, /* i : LP filter stablility measure Q15 */ + Word32 norm_gain_code,/* i : normalised innovative cb. gain Q16 */ + const Word16 gain_inov, /* i : gain of the unscaled innovation Q12 */ + Word32 *gc_threshold, /* i/o: gain code threshold Q16 */ + Word16 *code, /* i/o: innovation Q12 */ + Word16 *exc2, /* i/o: adapt. excitation/total exc. Q_exc*/ + const Word16 gain_pit, /* i : quantized pitch gain Q14 */ + struct dispMem_fx *dm_fx, /* i/o: phase dispersion algorithm memory */ + const Word16 Q_exc /* i : Q of the excitation */ +); + +Word16 E_UTIL_enhancer( + Word16 voice_fac, /* i : subframe voicing estimation Q15 */ + Word16 stab_fac, /* i : LP filter stability measure Q15 */ + Word32 gain_code, /* i : innovative cb. gain 15Q16 */ + Word16 gain_inov, /* i : gain of the unscaled innovation Q12 */ + Word32 *gc_threshold, /* i/o: gain code threshold 15Q16 */ + Word16 *code, /* i/o: innovation(in: Q9) code_exp */ + Word16 *exc2, /* i/o: adapt. excitation/total exc. Q15 */ + Word16 gain_pit, /* i : Quantized pitch gain 1Q14 */ + Word32 *prev_gain_code, /* i/o: previous codebook gain 15Q16 */ + Word16 prev_gain_pit[], /* i/o: previous pitch gain, size=6 1Q14 */ + Word16 *prev_state, /* i/o: Phase dispersion algorithm memory Q0 */ + Word16 coder_type, /* i : coder type */ + Word16 cdk_index, /* i : */ + Word16 L_subfr, /* i : */ + Word16 L_frame, /* i : frame size */ + Word16 Q_new +); + + +//phase_dispersion_fx.c +void phase_dispersion( + const Word32 gain_code, /* i : gain of code 15Q16 */ + const Word16 gain_pit, /* i : gain of pitch Q14 */ + Word16 code[], /* i/o: code vector */ + Word16 *code_e, /* i/o: exponent of code */ + const Word16 mode, /* i : level, 0=hi, 1=lo, 2=off */ + Word32 *prev_gain_code, /* i/o: static memory 15Q16 */ + Word16 prev_gain_pit[], /* i/o: static memory Q14, size=6 */ + Word16 *prev_state, /* i/o: static memory Q0 */ + Word16 L_subfr /* i : subframe length [40,64] */ +); + +//tcx_ltp_fx.c +void tcx_ltp_get_lpc( + Word16* x, + const Word16 L, + Word16* A, + const Word16 order +); + +void predict_signal( + const Word16 excI[], /* i : i excitation buffer */ + Word16 excO[], /* o : output excitation buffer */ + const Word16 T0, /* i : integer pitch lag */ + Word16 frac, /* i : fraction of lag */ + const Word16 frac_max, /* i : max fraction */ + const Word16 L_subfr /* i : subframe size */ +); + +Word16 tcx_ltp_decode_params(Word16 *ltp_param, + Word16 *pitch_int, + Word16 *pitch_fr, + Word16 *gain, + Word16 pitmin, + Word16 pitfr1, + Word16 pitfr2, + Word16 pitmax, + Word16 pitres +); + +void tcx_ltp_post( + Decoder_State* st, + TCX_LTP_DEC_HANDLE hTcxLtpDec, + Word16 core, + Word16 output_frame, + Word16 delay, + Word16* sig, + Word16* tcx_buf +); + +//gs_inact_switching_fx.c +void Inac_swtch_ematch_fx( + Word16 exc2[], /* i/o: CELP/GSC excitation buffer Q_exc*/ + Word16 dct_exc_tmp[], /* i : GSC excitation in DCT domain */ + Word16 lt_ener_per_band[], /* i/o: Long term energy per band Q12 */ + const Word16 coder_type, /* i : Coding mode */ + const Word16 L_frame, /* i : Frame lenght */ + const Word32 core_brate, /* i : Core bit rate */ + const Word16 Q_exc /* i : i and output format of exc2 */ + , const Word16 bfi /* i : frame lost indicator */ + , const short last_core, /* i : Last core used */ + const short last_codec_mode /* i : Last codec mode */ +); +//igf_base_fx.c +void IGFCommonFuncsCalcSfbEnergyPowerSpec(const Word16 startSfb, /**< in: Q0 | start sfb index */ + const Word16 stopSfb, /**< in: Q0 | stop sfb index */ + const Word16 *swb_offset, /**< in: Q0 | IGF swb offset table */ + Word32 *pPowerSpectrum, /**< in: Q31 | power spectrum */ + Word16 *pPowerSpectrum_exp, /**< in: | Exponent of PowerSpectrum */ + Word32 *sfbEnergy, /**< out:Q31 | SFB energies , will be initialized inside this function */ + Word16 *sfbEnergy_exp /**< out: | Exponent of PowerSpectrum */ +); + +void IGFCommonFuncsMDCTSquareSpec(const Word16 sqrtBgn, /**< in: Q0 | start MDCT subband index */ + const Word16 sqrtEnd, /**< in: Q0 | stop MDCT subband index */ + const Word32 *mdctSpec, /**< in: Q31 | MDCT spectrum to square */ + const Word16 mdctSpec_e, /**< in: | exponent of mdctSpectrum */ + Word32 *mdctSquareSpec, /**< out:Q31 | MDCT square spectrum */ + Word16 *mdctSquareSpec_e, /**< out: | exponent of mdctSquareSpec */ + Word16 indexOffset /**< in: Q0 | index offset */ +); + +void IGFCommonFuncsWriteSerialBit( + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + Word16* pBitOffset, /**< out: Q0 | bit offset */ + Word16 bit /**< in: Q0 | value of bit */ +); + +Word16 IGFCommonFuncsIGFConfiguration( + const Word32 total_brate, /* i : bitrate in bs e.g. 9600 for 9.6kbs */ + const Word16 bwidth, /* i : audio bandwidth */ + const Word16 element_mode, /* i : element mode */ + H_IGF_INFO hIGFInfo, /* o : IGF info handle */ + const Word16 rf_mode /* i : flag to signal the RF mode */ +); +Word16 IGFCommonFuncsIGFGetCFTables( + const Word32 total_brate, /* i : bitrate in bs e.g. 9600 for 9.6kbs */ + const Word16 bwidth, /* i : audio bandwidth */ + const Word16 element_mode, /* i : element mode */ + const Word16 rf_mode, /* i : flag to signal the RF mode */ + const Word16** cf_se00, /* o : CF table for t == 0 and f == 0 */ + const Word16** cf_se01, /* o : CF table for t == 0 and f == 1 */ + Word16* cf_off_se01, /* o : offset for CF table above */ + const Word16** cf_se02, /* o : CF tables for t == 0 and f >= 2 */ + const Word16** cf_off_se02, /* o : offsets for CF tables above */ + const Word16** cf_se10, /* o : CF table for t == 1 and f == 0 */ + Word16* cf_off_se10, /* o : offset for CF table above */ + const Word16** cf_se11, /* o : CF tables for t == 1 and f >= 1 */ + const Word16** cf_off_se11 /* o : offsets for CF tables above */ +); +//ari_fx.c +Word32 L_multi31x16_X2(Word16 xh, Word16 xl, Word16 y); +Word32 mul_sbc_14bits(Word32 r, Word16 c); + +//window.c +void ham_cos_window(Word16 *fh, const Word16 n1, const Word16 n2); + +//arith_coder_fx.c +Word32 expfp( /* o: Q31 */ + const Word16 x, /* i: mantissa Q-e */ + const Word16 x_e); /* i: exponent Q0 */ + +void powfp_odd2( + const Word16 base, /* Q15 */ + const Word16 exp, /* Q0 */ + Word16 *pout1, /* Q15 */ + Word16 *pout2); /* Q15 */ + +void tcx_arith_scale_envelope( + const Word16 L_spec_core, /* i: number of lines to scale Q0 */ + Word16 L_frame, /* i: number of lines Q0 */ + const Word32 env[], /* i: unscaled envelope Q16 */ + Word16 target_bits, /* i: number of available bits Q0 */ + const Word16 low_complexity,/* i: low-complexity flag Q0 */ + Word16 s_env[], /* o: scaled envelope Q15-e */ + Word16 *s_env_e /* o: scaled envelope exponent Q0 */ +); + +void tcx_arith_render_envelope( + const Word16 A_ind[], /* i: LPC coefficients of signal envelope */ + const Word16 L_frame, /* i: number of spectral lines */ + const Word16 L_spec, + const Word16 preemph_fac, /* i: pre-emphasis factor */ + const Word16 gamma_w, /* i: A_ind -> weighted envelope factor */ + const Word16 gamma_uw, /* i: A_ind -> non-weighted envelope factor */ + Word32 env[] /* o: shaped signal envelope */ +); + + +//gain_inov_fx.c +Word32 calc_gain_inov( /* returns innovation gain Q16 */ + const Word16 *code, /* i : algebraic excitation Q9 */ + const Word16 lcode, /* i : Subframe size Q0 */ + Word32 *dotp, /* o : intermediate result Q31-e */ + Word16 *dotp_e /* o : intermediate result exponent Q0 */ +); + +/////////////////////////////////// +/* Lib_dec */ +////////////////////////////////// +//swb_tbe_dec.c + +void InitSWBdecBuffer_fx( + Decoder_State *swb_dnc_fx /* i/o: SHB decoder structure */ +); + +void ResetSHBbuffer_Dec_fx( + Decoder_State *st_fx /* i/o: decoder state structure */ +); +void wb_tbe_dec_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + const Word16 coder_type, /* i : coding type */ + Word32 *bwe_exc_extended, /* i : bandwidth extended exciatation */ + const Word16 Q_exc, + const Word16 voice_factors[], /* i : voicing factors */ + Word16 *synth, /* i/o: ACELP core synthesis/final synthesis */ + Word16 *Q_synth +); + +void swb_tbe_dec_fx( + Decoder_State* st_fx, /* i/o: decoder state structure */ + const Word16 coder_type, /* i : coding type */ + Word32* bwe_exc_extended, /* i : bandwidth extended exciatation 2*Q_exc*/ + Word16 Q_exc, + const Word16 voice_factors[], /* i : voicing factors */ + const Word16 old_syn_12k8_16k[], /* i : low band synthesis*/ + Word16* White_exc16k, /* o : shaped white excitation for the FB TBE */ + Word16* Q_white_exc, + Word16* synth, /* o : SHB synthesis/final synthesis */ + Word16* Q_synth, + Word16* pitch_buf +); + +void fb_tbe_dec_fx( + Decoder_State *st, /* i/o: encoder state structure */ + const Word16 fb_exc[], /* i : FB excitation from the SWB part */ + Word16 Q_fb_exc, + Word16 *hb_synth, /* o : high-band synthesis */ + Word16 hb_synth_exp +); + +void tbe_read_bitstream_fx( + Decoder_State *st_fx /* i/o: encoder state structure */ +); + +void GenTransition_fx( + const Word16 *i, /* i : gain shape overlap buffer */ + const Word16 *old_hb_synth, /* i : synthesized HB from previous frame */ + Word16 length, /* i : targeted length of transition signal */ + Word16 *output, /* o : synthesized transitions signal */ + Word32 Hilbert_Mem[], /* i/o: memory */ + Word16 state_lsyn_filt_shb_local[],/* i/o: memory */ + Word16 mem_resamp_HB_32k[], /* i/o: memory */ + Word16 *syn_dm_phase, + Word32 output_Fs, + Word16 *up_mem, + Word16 rf_flag + , Word32 bitrate +); + +void GenTransition_WB_fx( + const Word16 *i, /* i : gain shape overlap buffer */ + const Word16 *old_hb_synth, /* i : synthesized HB from previous frame */ + const Word16 prev_Qx, /* i : scaling of old_hb_synth */ + Word16 length, /* i : targeted length of transition signal */ + Word16 *output, /* o : synthesized transitions signal */ + Word16 state_lsyn_filt_shb1[], + Word16 state_lsyn_filt_shb2[], + Word32 output_Fs, + Word16 *up_mem +); + +void TBEreset_dec_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + Word16 bandwidth /* i : bandwidth mode */ +); + +void td_bwe_dec_init_fx( + Decoder_State* st_fx, /* i/o: SHB decoder structure */ + TD_BWE_DEC_HANDLE hBWE_TD, /* i/o: TD BWE data handle */ +#ifdef ADD_IVAS_BWE + const Word16 extl, /* i : BWE extension layer */ +#endif + const Word32 output_Fs /* i : output sampling rate */ +); + +//lsf_dec_fx.c +void lsf_dec_fx( + Decoder_State* st_fx, /* i/o: State structure */ + const Word16 tc_subfr, /* i : TC subframe index */ + Word16* Aq, /* o : quantized A(z) for 4 subframes */ + Word16* LSF_Q_prediction, /* o : LSF prediction mode */ + Word16* lsf_new, /* o : de-quantized LSF vector */ + Word16* lsp_new, /* o : de-quantized LSP vector */ + Word16* lsp_mid, /* o : de-quantized mid-frame LSP vector */ + const Word16 tdm_low_rate_mode /* i : secondary channel low rate mode flag */ +#ifdef LSF_RE_USE_SECONDARY_CHANNEL + , const Word16 tdm_lsfQ_PCh[M] /* i : Q LSFs for primary channel */ +#endif +); + +void lsf_end_dec_fx( + Decoder_State* st, /* i/o: decoder state structure */ + Word16 mode2_flag, + const Word16 coder_type_org, /* i : coding type */ + const Word16 bwidth, /* i : i signal bandwidth */ + const Word16 nBits_in, /* i : number of bits used for ISF quantization*/ + Word16* qlsf, /* o : quantized LSFs in the cosine domain */ + Word16* lpc_param, + Word16* LSF_Q_prediction, /* o : LSF prediction mode */ + Word16* nb_indices +#ifdef LSF_RE_USE_SECONDARY_CHANNEL + , const float tdm_lsfQ_PCh[M] +#endif +); + +void lsf_mid_dec_fx( + Decoder_State* st_fx, /* i/o: decoder state structure */ + Word16 lsp_new[], /* i : quantized LSPs from frame endSQ15*/ + Word16 coder_type, /* i : Coder type */ + Word16 lsp_mid[] /* o : quantized LSPs Q15*/ +); + +//cng_dec_fx.c +void CNG_dec_fx( + Decoder_State* st_fx, /* i/o: State structure */ + const Word16 last_element_mode, /* i : last element mode Q0 */ + Word16 Aq[], /* o : LP coefficients Q12 */ + Word16* lsp_new, /* i/o: current frame LSPs Q15 */ + Word16* lsf_new, /* i/o: current frame LSFs Qlog2(2.56) */ + Word16* allow_cn_step, /* o : allow CN step Q0 */ + Word16* sid_bw /* i : 0-NB/WB, 1-SWB SID */ + , Word32* q_env +); + +void swb_CNG_dec_fx( + Decoder_State *st_fx, /* i/o: State structure */ + const Word16 *synth_fx, /* i : ACELP core synthesis at 32kHz */ + Word16 *shb_synth_fx, /* o : high-band CNG synthesis */ + const Word16 sid_bw, /* i : 0-NB/WB, 1-SWB SID */ + const Word16 Qsyn /* i : Q value of ACELP core synthesis */ +); + +void td_cng_dec_init( + DEC_CORE_HANDLE st /* i/o: decoder state structure */ +); + +//wavadjust_fec_dec_fx.c +void set_state(Word16 *state, Word16 num, Word16 N); +void concealment_init_x(Word16 N, void *_plcInfo); +void concealment_update_x(Word16 bfi, Word16 curr_mode, Word16 harmonic, Word32 *invkoef, Word16 *invkoef_scale, void *_plcInfo); +Word16 Sqrt_x_fast(Word32 value); + +Word32 dot_w32_accuracy_x(Word16 *s1, Word16 *s2, Word16 nbits, Word16 N); + +Word16 int_div_s_x(Word16 a, Word16 b); + +Word16 GetW32Norm_x(Word32 *s, Word16 N); + +Word16 harmo_x(Word32 *X, Word16 Framesize, Word16 pitch); + +void LpFilter2_x(Word16 *x, Word16 *y, Word16 N); + +void sig_tilt_x(Word16 *s, Word16 FrameSize, Word32 *enr1, Word32 *enr2); + +void get_maxConv_and_pitch_x(Word16 *s_LP, Word16 s, Word16 e, Word16 N, + Word32 *maxConv, Word16 *maxConv_bits, Word16 *pitch); + +Word16 get_voicing_x(Word16 *s_LP, Word16 pitch, Word32 covMax, Word16 maxConv_bits, Word16 Framesize); + +void pitch_modify_x(Word16 *s_LP, Word16 *voicing, Word16 *pitch, Word16 FrameSize); + +Word16 Is_Periodic_x(Word32 *mdct_data, Word16 cov_max, Word16 zp, Word32 ener, + Word32 ener_mean, Word16 pitch, Word16 Framesize); + +Word16 get_conv_relation_x(Word16 *s_LP, Word16 shift, Word16 N); + +void concealment_decode_fix(Word16 curr_mode, Word32 *invkoef, Word16 *invkoef_scale, void *_plcInfo); + +Word32 Spl_Energy_x(const Word16* vector, const Word16 vector_length, Word16* scale_factor); + +void Log10OfEnergy_x(const Word16 *s, Word32 *enerlogval, const Word16 len); + +void concealment_update2_x(const Word16 *outx_new, void *_plcInfo, const Word16 FrameSize); + +Word16 ffr_getSfWord16(Word16 *vector, /*!< Pointer to i vector */ + Word16 len); + +void waveform_adj2_fix(Word16 *overlapbuf, + Word16 *outx_new, + Word16 *data_noise, + Word16 *outx_new_n1, + Word16 *nsapp_gain, + Word16 *nsapp_gain_n, + Word16 *recovery_gain, + Word16 step_concealgain, + Word16 pitch, + Word16 Framesize, + Word16 delay, + Word16 bfi_cnt, + Word16 bfi +); + +void concealment_signal_tuning_fx(Word16 bfi, + Word16 curr_mode, + Word16 *outx_new_fx, + void *_plcInfo, + Word16 nbLostCmpt, + Word16 pre_bfi, + Word16 *OverlapBuf_fx, + Word16 past_core_mode, + Word16 *outdata2_fx, + Decoder_State *st); + +//TonalComponentDetect.c +/* Detect tonal components in the lastMDCTSpectrum, use + * secondLastPowerSpectrum for the precise location of the peaks and + * store them in indexOfTonalPeak. Updates lowerIndex, upperIndex, + * pNumIndexes accordingly. */ +void DetectTonalComponents( + Word16 indexOfTonalPeak[], + Word16 lowerIndex[], + Word16 upperIndex[], + Word16* pNumIndexes, + const Word32 lastPitchLag, + const Word32 currentPitchLag, + const Word16 lastMDCTSpectrum[], + const Word16 lastMDCTSpectrum_exp, + const Word16 scaleFactors[], + const Word16 scaleFactors_exp[], + const Word16 scaleFactors_max_e, + const Word32 secondLastPowerSpectrum[], + const Word16 nSamples, + const Word16 nSamplesCore, + Word16 floorPowerSpectrum /* i: lower limit for power spectrum bins */ +#ifdef IVAS_CODE_MDCT_GSHAPE + , const PsychoacousticParameters* psychParamsCurrent +#endif +); + +/* When called, the tonal components are already stored in + * indexOfTonalPeak. Detect tonal components in the lastMDCTSpectrum, + * use secondLastPowerSpectrum for the precise location of the peaks and + * then keep in indexOfTonalPeak only the tonal components that are + * again detected Updates indexOfTonalPeak, lowerIndex, upperIndex, + * phaseDiff, phases, pNumIndexes accordingly. */ +void RefineTonalComponents( + Word16 indexOfTonalPeak[], + Word16 lowerIndex[], + Word16 upperIndex[], + Word16 phaseDiff[], + Word16 phases[], + Word16* pNumIndexes, + const Word32 lastPitchLag, + const Word32 currentPitchLag, + const Word16 lastMDCTSpectrum[], + const Word16 lastMDCTSpectrum_exp, + const Word16 scaleFactors[], + const Word16 scaleFactors_exp[], + const Word16 scaleFactors_max_e, + const Word32 secondLastPowerSpectrum[], + const Word16 nSamples, + const Word16 nSamplesCore, + const Word16 floorPowerSpectrum /* i: lower limit for power spectrum bins */ +#ifdef IVAS_CODE_MDCT_GSHAPE + , const PsychoacousticParameters* psychParamsCurrent +#endif +); + + +//TonalIMDCTconcealment_fx.c +ivas_error TonalMDCTConceal_Init( + TonalMDCTConcealPtr self, + const Word16 nSamples, + const Word16 nSamplesCore, + const Word16 nScaleFactors, + TCX_CONFIG_HANDLE hTcxCfg /* TCX config */ +); + +/* Must be called only when a good frame is recieved - concealment is inactive */ +void TonalMDCTConceal_SaveFreqSignal( + TonalMDCTConcealPtr self, + const Word32* mdctSpectrum, + const Word16 mdctSpectrum_exp, + Word16 nNewSamples, + Word16 nNewSamplesCore, + const Word16* scaleFactors, + const Word16* scaleFactors_exp, + const Word16 gain_tcx_exp +#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT + ,const Word16 infoIGFStartLine +#endif +); + +/* The call to TonalMDCTConceal_UpdateState() should be called after TonalMDCTConceal_Apply. */ +TONALMDCTCONCEAL_ERROR TonalMDCTConceal_UpdateState(TonalMDCTConcealPtr self, + Word16 nNewSamples, + Word32 pitchLag, + Word16 badBlock, + Word8 tonalConcealmentActive + ); + +/* The call to TonalMDCTConceal_SaveTimeSignal() should be at the + * place where the TD signal corresponds to the FD signal stored with TonalMDCTConceal_SaveFreqSignal. */ +void TonalMDCTConceal_SaveTimeSignal( + TonalMDCTConcealPtr hTonalMDCTConc, + Word16 * timeSignal, + Word16 nNewSamples +); + +/* Calculates MDST, power spectrum and performs peak detection. + * Uses the TD signal in pastTimeSignal; if pastTimeSignal is NULL, uses the + * TD signal stored using TonalMDCTConceal_SaveTimeSignal. If the + * second last frame was also lost, it is expected that pastTimeSignal + * could hold a signal somewhat different from the one stored in + * TonalMDCTConceal_SaveTimeSignal (e.g. including fade-out).*/ +void TonalMDCTConceal_Detect( + const TonalMDCTConcealPtr self, /*IN */ + const Word32 pitchLag, /*IN */ + Word16 * umIndices /*OUT*/ +#ifdef IVAS_CODE_MDCT_GSHAPE + , const PsychoacousticParameters* psychParamsCurrent +#endif +); + +/* Conceals the lost frame using the FD signal previously stored using + * TonalMDCTConceal_SaveFreqSignal. Stores the concealed harmonic part of + * the signal in mdctSpectrum, the rest of the spectrum is unchanged. */ +void TonalMDCTConceal_Apply( + const TonalMDCTConcealPtr hTonalMDCTConc, /*IN */ + Word32* mdctSpectrum, /*IN/OUT*/ + Word16* mdctSpectrum_exp /*IN */ +#ifdef IVAS_CODE_MDCT_GSHAPE + , const PsychoacousticParameters* psychParamsCurrent) +#endif + ); + +/* Conceals the lost frame using the FD signal previously stored using + * TonalMDCTConceal_SaveFreqSignal. Stores the concealed noise part of + * the signal in mdctSpectrum, the rest of the spectrum is unchanged. */ +void TonalMDCTConceal_InsertNoise( + const TonalMDCTConcealPtr hTonalMDCTConc, /*IN */ + Word32* mdctSpectrum, /*OUT*/ + Word16* mdctSpectrum_exp, /*OUT*/ + const Word8 tonalConcealmentActive, + Word16* pSeed, /*IN/OUT*/ + const Word16 tiltCompFactor, + Word16 crossfadeGain, +#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT + const Word16concealment_noise[L_FRAME48k], +#endif + const Word16 crossOverFreq +); +/* Conceals the lost frame using the FD signal previously stored using + * TonalMDCTConceal_SaveFreqSignal. Stores the concealed harmonic part of + * the signal in mdctSpectrum, the rest of the spectrum is unchanged. */ +void TonalMDCTConceal_Apply( + const TonalMDCTConcealPtr hTonalMDCTConc, /*IN */ + Word32* mdctSpectrum, /*IN/OUT*/ + Word16* mdctSpectrum_exp /*IN */ +#ifdef IVAS_CODE_MDCT_GSHAPE + , const PsychoacousticParameters* psychParamsCurrent) +#endif + ); + + /* The call to TonalMDCTConceal_SaveTimeSignal() should be at the + * place where the TD signal corresponds to the FD signal stored with TonalMDCTConceal_SaveFreqSignal. */ + void TonalMDCTConceal_SaveTimeSignal( + TonalMDCTConcealPtr hTonalMDCTConc, + Word16 * timeSignal, + Word16 nNewSamples + ); + + + //decision_matrix_dec_fx.c + void decision_matrix_dec_fx( + Decoder_State *st, /* i/o: decoder state structure */ + Word16 *sharpFlag, /* o : formant sharpening flag */ + Word16 *hq_core_type, /* o : HQ core type */ + Word16 *core_switching_flag/* o : ACELP->HQ switching frame flag */ + ); + + //hf_synth_fx.c + void hf_synth_init_fx( + ZERO_BWE_DEC_HANDLE hBWE_zero /* o : zero BWE decoder handle */ + ); + void hf_synth_reset_fx( + ZERO_BWE_DEC_HANDLE hBWE_zero /* o : zero BWE decoder handle */ + ); + + void hf_synth_fx( + ZERO_BWE_DEC_HANDLE hBWE_zero, /* i/o: handle to 0 bit BWE parameters */ + const Word32 core_brate, /* i : core bitrate */ + const Word16 output_frame, /* i : output frame length */ + const Word16* Aq, /* i : quantized Az */ + const Word16* exc, /* i : excitation at 12.8 kHz */ + Word16* synth, /* i : 12.8kHz synthesis signal */ + Word16* synth16k, /* o : 16kHz synthesis signal */ + const Word16 Q_exc, /* i : excitation scaling */ + const Word16 Q_syn2, /* i : synthesis scaling */ + Word16* delay_syn_hf, /*i/o: HF synthesis memory */ + Word16* memExp1, /* o : HF excitation exponent */ + Word16* mem_hp_interp, /* i/o: interpol. memory */ + const Word16 extl, /* i : flag indicating BWE */ + const Word16 CNG_mode /* i : CNG_mode */ + ); + + void hf_synth_amr_wb_init_fx( + AMRWB_IO_DEC_HANDLE hAmrwb_IO /* i/o: AMR-WB IO data handle */ + ); + + void hf_synth_amr_wb_reset_fx( + ZERO_BWE_DEC_HANDLE hBWE_zero, /* o : zero BWE decoder handle */ + AMRWB_IO_DEC_HANDLE hAmrwb_IO /* i/o: AMR-WB IO data handle */ + ); + + void hf_synth_amr_wb_fx( + AMRWB_IO_DEC_HANDLE hAmrwb_IO, /* i/o: AMR-WB IO data handle */ + ZERO_BWE_DEC_HANDLE hBWE_zero, /* o : zero BWE decoder handle */ + const Word32 core_brate, /* i : core bitrate */ + const Word16 output_frame, /* i : output frame length */ + const Word16* Aq, /* i : quantized Az : Q12 */ + const Word16* exc, /* i : excitation at 12.8 kHz : Q_exc */ + Word16* synth, /* i/o: synthesis signal at 12.8k : Q_syn */ + Word16* amr_io_class, /* i : signal class (determined by FEC algorithm) */ + Word16* synth_out, /* i/o: output signal at output Fs : Q_out */ + Word16 fmerit, /* i : classify parameter from FEC : Q14 */ + const Word16* hf_gain, /* i : decoded HF gain */ + const Word16* voice_factors, /* i : voicing factors : Q15 */ + const Word16 pitch_buf[], /* i : pitch buffer : Q5 */ + const Word16 ng_ener_ST, /* i : Noise gate - short-term energy : Q8 */ + const Word16* lsf_new, /* i : ISF vector : Q2 */ + const Word16 Q_exc, /* i : exc scaling */ + const Word16 Q_out /* i : Q_syn2-1 */ + ); + + //dec_post_fx + void Init_post_filter( + PFSTAT_HANDLE hPFstat /* i : core decoder parameters */ + ); /* (i) : core decoder parameters */ + + + void nb_post_filt( + const Word16 L_frame, /* i : frame length */ + PFSTAT_HANDLE hPFstat, /* i : core decoder parameters */ + Word16* psf_lp_noise, /* i : Long term noise Q8 */ + const Word16 tmp_noise, /* i : noise energy Q0 */ + Word16* Synth, /* i : 12k8 synthesis Qsyn */ + const Word16* Aq, /* i : LP filter coefficient Q12 */ + const Word16* Pitch_buf, /* i : Fractionnal subframe pitch buffer Q6 */ + const Word16 coder_type, /* i : coder_type */ + const Word16 BER_detect, /* i : BER detect flag */ + const Word16 disable_hpf /* i : flag to diabled HPF */ + ); + + void formant_post_filt( + PFSTAT_HANDLE hPFstat, /* i : core decoder parameters */ + Word16 *synth_in, /* i : 12k8 synthesis */ + Word16 *Aq, /* i : LP filter coefficient */ + Word16 *synth_out, /* i/o: i signal */ + Word16 L_frame, + Word32 lp_noise, /* (i) : background noise energy (15Q16) */ + Word32 rate, /* (i) : bit-rate */ + const Word16 off_flag /* i : off flag */ + ); + + void Filt_mu( + Word16 * sig_in, /* i : signal (beginning at sample -1) */ + Word16 * sig_out, /* o : signal with tilt */ + Word16 parcor0, /* i : parcor0 (mu = parcor0 * gamma3) */ + Word16 L_subfr /* i : the length of subframe */ + ); + + void scale_st( + const Word16 * sig_in, /* i : postfilter i signal */ + Word16 * sig_out, /* i/o: postfilter o signal */ + Word16 * gain_prec, /* i/o: last value of gain for subframe */ + Word16 L_subfr + ); + + void blend_subfr2( + Word16 *sigIn1, /* i : i signal for fade-out */ + Word16 *sigIn2, /* i : i signal for fade-in */ + Word16 *sigOut /* o : output signal */ + ); + + //syn_outp_fx.c + + void syn_output_fx( + const Word16 codec_mode, /* i : MODE1 or MODE2 */ + Word16 *synth, /* i/o: float synthesis signal */ + const Word16 output_frame, /* i : output frame length */ + Word16 *synth_out, /* o : integer 16 bits synthesis signal */ + const Word16 Q_syn2 /* i : Synthesis scaling factor */ + ); + + void unscale_AGC( + const Word16 x[], + const Word16 Qx, + Word16 y[], + Word16 mem[], + const Word16 n + ); + + //bass_psfilter_fx.c + void bass_psfilter_init_fx( + BPF_DEC_HANDLE hBPF /* o : BPF data handle */ + ); + + void bass_psfilter_fx( + BPF_DEC_HANDLE hBPF, /* i/o: BPF data handle */ + const Word16 Opt_AMR_WB, /* i : AMR-WB IO flag */ + Word16 synth_in_fx[], /* i : i synthesis (at 16kHz) */ + const Word16 L_frame, /* i : length of the last frame */ + Word16 pitch_buf_fx[], /* i : pitch for every subfr [0,1,2,3] */ + const Word16 bpf_off, /* i : do not use BPF when set to 1 */ + Word16 v_stab_fx, /* i : stability factor */ + Word16* v_stab_smooth_fx, /* i/o: smoothed stability factor */ + const Word16 coder_type, /* i : coder_type */ + Word16 Q_syn, + Word16 bpf_noise_buf[] /* o : BPF error signal (at int_fs) */ + ); + void addBassPostFilterFx( + const Word16 *harm_timeIn_Fx, + Word32 **rAnalysis_Fx, + Word32 **iAnalysis_Fx, + HANDLE_CLDFB_FILTER_BANK cldfbBank_bpf_Fx, + Word32 *workBuffer, + const Word16 timeIn_e, + const Word16 nTimeSlots, + const Word16 nTimeSlotsTotal, + const Word16 nBandsTotal, + CLDFB_SCALE_FACTOR *cldfb_scale + ); + + //FEC_fx.c + void FEC_exc_estim_fx( + Decoder_State *st_fx, /* i/o: Decoder static memory */ + const Word16 L_frame, /* i : length of the frame */ + Word16 *exc, /* o : pointer to excitation buffer (with past) */ + Word16 *exc2, /* o : total excitation (for synthesis) */ + Word16 dct_exc_tmp[], /* o : GSC excitation in DCT domain */ + Word16 *pitch_buf, /* o : Floating pitch for each subframe */ + Word16 *voice_factors, /* o : voicing factors */ + Word16 *tmp_tc, /* o : FEC pitch Q6 */ + Word16 *bwe_exc, /* o : excitation for SWB TBE */ + Word16 *lsf_new, /* i : ISFs at the end of the frame */ + Word16 *Q_exc, + Word16 *tmp_noise /* o : long-term noise energy Q0 */ + ); + + //pitch_extr_fx.c + void pitch_pred_linear_fit( + const Word16 /*short*/ bfi_cnt, /* i: bfi counter */ /*Q0 */ + const Word16 /*short*/ last_good, /* i: last classification type */ /*Q0 */ + Word32 /*float*/ *old_pitch_buf, /* i: pitch lag buffer */ /*Q16*/ + Word32 /*float*/ *old_fpitch, /* i: */ /*Q16*/ + Word32 /*float*/ *T0_out, /* o: estimated close loop pitch */ /*Q16*/ + Word16 /* int*/ pit_min, /* i: Minimum pitch lag */ /*Q0 */ + Word16 /* int*/ pit_max, /* i: Maximum pitch lag */ /*Q0 */ + Word16 /*float*/ *mem_pitch_gain, /* i: pitch gain [0] is the most recent subfr gain */ /*Q0*/ + Word16 /* int*/ limitation, + Word8 /*short*/ plc_use_future_lag, /* i: */ /*Q0 */ + Word16 /*short*/ *extrapolationFailed, /* o: flag if extrap decides not to change the pitch *//*Q0 */ + Word16 nb_subfr /* i: number of ACELP subframes */ + ); + + void get_subframe_pitch( + Word16 nSubframes, /* i: number of subframes */ /* Q0 */ + Word32 pitchStart, /* i: starting pitch lag (in subframe -1) */ /*15Q16*/ + Word32 pitchEnd, /* i: ending pitch lag (in subframe nSubframes-1) */ /*15Q16*/ + Word32 *pitchBuf /* o: interpolated pitch lag per subframe */ /*15Q16*/ + ); + + //er_sync_exc_fx.c + void PulseResynchronization( + Word16 /*float*/ const * const src_exc, /*i Q15*/ + Word16 /*float*/ * const dst_exc, /*o Q15*/ + Word16 /*int*/ const nFrameLength, /*i Q0 */ + Word16 /*int*/ const nSubframes, /*i Q0 */ + Word32 /*float*/ const pitchStart, /*i Q16*/ + Word32 /*float*/ const pitchEnd /*i Q16*/ + ); + + //gs_dec_fx.c + void decod_audio_fx( + Decoder_State *st_fx, /* i/o: decoder static memory */ + Word16 dct_epit[], /* o : GSC excitation in DCT domain */ + const Word16 *Aq, /* i : LP filter coefficient */ + Word16 *pitch_buf, /* o : floating pitch values for each subframe */ + Word16 *voice_factors, /* o : voicing factors */ + Word16 *exc, /* i/o: adapt. excitation exc */ + Word16 *exc2, /* i/o: adapt. excitation/total exc */ + Word16 *bwe_exc, /* o : excitation for SWB TBE */ + Word16 *lsf_new /* i : ISFs at the end of the frame */ + , Word16 *gain_buf /*Q14*/ + ); + + void gsc_dec_fx( + Decoder_State *st_fx, /* i/o: State structure */ + Word16 exc_dct_in[], /* i/o: dct of pitch-only excitation / total excitation */ + const Word16 pit_band_idx, /* i : bin position of the cut-off frequency */ + const Word16 Diff_len, /* i : Lenght of the difference signal (before pure spectral)*/ + const Word16 bits_used, /* i : Number of bit used before frequency Q */ + const Word16 nb_subfr, /* i : Number of subframe considered */ + const Word16 coder_type, /* i : coding type */ + Word16 *last_bin, /* i : last bin of bit allocation */ + const Word16 *lsf_new, /* i : ISFs at the end of the frame */ + Word16 *exc_wo_nf, /* o : excitation (in f domain) without noisefill */ + Word16 Q_exc + ); + + void GSC_dec_init( + GSC_DEC_HANDLE hGSCDec /* i/o: GSC data handle */ + ); + + //gain_dec_fx.c + + void Es_pred_dec_fx( + Word16* Es_pred, /* o : predicited scaled innovation energy Q8*/ + const Word16 enr_idx, /* i : indice */ + const Word16 nb_bits, /* i : number of bits */ + const Word16 no_ltp /* i : no LTP flag */ + ); + + void gain_dec_tc_fx( + Decoder_State* st_fx, /* i/o: decoder state structure */ + const Word16* code_fx, /* i : algebraic code excitation */ + const Word16 i_subfr_fx, /* i : subframe number */ + const Word16 Es_pred_fx, /* i : predicted scaled innov. energy */ + Word16* gain_pit_fx, /* o : pitch gain */ + Word32* gain_code_fx, /* o : Quantized codeebook gain */ + Word16* gain_inov_fx, /* o : unscaled innovation gain */ + Word32* norm_gain_code_fx /* o : norm. gain of the codebook excit. */ + ); + + void gain_dec_mless_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + const Word16 L_frame_fx, /* i : length of the frame */ + const Word16 coder_type_fx, /* i : coding type */ + const Word16 i_subfr_fx, /* i : subframe number */ + const Word16 tc_subfr_fx, /* i : TC subframe index */ + const Word16 *code_fx, /* i : algebraic code excitation */ + const Word16 Es_pred_fx, /* i : predicted scaled innov. energy */ + Word16 *gain_pit_fx, /* o : Quantized pitch gain Q14*/ + Word32 *gain_code_fx, /* o : Quantized codeebook gain Q16*/ + Word16 *gain_inov_fx, /* o : unscaled innovation gain Q12*/ + Word32 *norm_gain_code_fx /* o : norm. gain of the codebook excitation Q16*/ + ); + + void gain_dec_lbr_fx( + Decoder_State* st_fx, /* i/o: decoder state structure */ + const Word16 coder_type, /* i : coding type */ + const Word16 i_subfr, /* i : subframe index */ + const Word16* code_fx, /* i : algebraic excitation Q9 */ + Word16* gain_pit_fx, /* o : quantized pitch gain Q14*/ + Word32* gain_code_fx, /* o : quantized codebook gain Q16*/ + Word16* gain_inov_fx, /* o : gain of the innovation (used for normalization) Q12*/ + Word32* norm_gain_code_fx, /* o : norm. gain of the codebook excitation Q16*/ + Word32 gc_mem[], /* i/o: gain_code from previous subframes */ + Word16 gp_mem[] /* i/o: gain_pitch from previous subframes */ + , const Word16 L_subfr /* i : subfr lenght */ + ); + + void lp_gain_updt_fx( + const Word16 i_subfr, /* i : subframe number Q0 */ + const Word16 gain_pit, /* i : Decoded gain pitch Q14 */ + const Word32 norm_gain_code, /* i : Normalised gain code Q16 */ + Word16 *lp_gainp, /* i/o: LP-filtered pitch gain(FEC) Q14 */ + Word16 *lp_gainc, /* i/o: LP-filtered code gain (FEC) Q3 */ + const Word16 L_frame /* i : length of the frame */ + ); + Word32 gain_dec_gaus_fx( /* o : quantized codebook gain Q16 */ + Word16 index, /* i : quantization index */ + const Word16 bits, /* i : number of bits to quantize */ + const Word16 lowBound, /* i : lower bound of quantizer (dB) */ + const Word16 topBound, /* i : upper bound of quantizer (dB) */ + const Word16 inv_gain_inov, /* o : unscaled innovation gain Q12 */ + Word32 *L_norm_gain_code /* o : gain of normalized gaussian excitation Q16 */ + ); + + void gain_dec_SQ_fx( + Decoder_State* st_fx, /* i/o: decoder state structure */ + const Word16 i_subfr, /* i : subframe number */ + const Word16* code, /* i : algebraic code excitation Q9*/ + const Word16 Es_pred, /* i : predicted scaled innov. energy Q8 */ + Word16* gain_pit, /* o : Quantized pitch gain Q14*/ + Word32* gain_code, /* o : Quantized codeebook gain Q16*/ + Word16* gain_inov, /* o : unscaled innovation gain Q12*/ + Word32* norm_gain_code /* o : norm. gain of the codebook excitation Q16*/ + ); + + void gain_dec_amr_wb_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + const Word32 core_brate, /* i : core bitrate */ + Word16 *gain_pit, /* o : Quantized pitch gain */ + Word32 *gain_code, /* o : Quantized codeebook gain */ + Word16 *past_qua_en, /* i/o: gain quantization memory (4 words) */ + Word16 *gain_inov, /* o : unscaled innovation gain */ + const Word16 *code, /* i : algebraic code excitation */ + Word32 *norm_gain_code /* o : norm. gain of the codebook excitation */ + ); + + //dec_higher_acelp_fx.c + void transf_cdbk_dec_fx( + Decoder_State* st_fx, /* i/o: decoder state structure */ + const Word16 harm_flag_acelp,/* i : harmonic flag for higher rates ACELP */ + const Word16 i_subfr, /* i : subframe index */ + const Word16 Es_pred, /* i : predicited scaled innovation energy (Q8) */ + const Word32 gain_code, /* i : innovative excitation gain (Q16) */ + Word16* gain_preQ, /* o : prequantizer excitation gain (Q2) */ + Word32* norm_gain_preQ,/* o : normalized prequantizer excitation gain (Q16) */ + Word16 code_preQ[], /* o : prequantizer excitation (Q8) */ + Word16* unbits /* o : number of AVQ unused bits */ + ); + Word16 gain_dequant_fx( /* o: decoded gain */ + Word16 index, /* i: quantization index */ + const Word16 min, /* i: value of lower limit */ + const Word16 max, /* i: value of upper limit */ + const Word16 bits, /* i: number of bits to dequantize */ + Word16 *expg + ); + + //avq_dec_fx.c + void AVQ_demuxdec_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + Word16 xriq[], /* o: decoded subvectors [0..8*Nsv-1] */ + Word16 *nb_bits, /* i/o: number of allocated bits */ + const Word16 Nsv, /* i: number of subvectors */ + Word16 nq_out[] /* i/o: AVQ nq index */ + ); + + void AVQ_dec_lpc( + Word16 *indx, /* i : index[] (4 bits per words) */ + Word16 *nvecq, /* o : vector quantized */ + Word16 Nsv); /* i : number of subvectors (lg=Nsv*8) */ + + + //re8_dec_fx.c + void re8_dec_fx( + Word16 n, /* i : codebook number (*n is an integer defined in {0,2,3,4,..,n_max}) */ + const UWord16 I, /* i : index of c (pointer to unsigned 16-bit word) */ + const Word16 k[], /* i : index of v (8-dimensional vector of binary indices) = Voronoi index */ + Word16 y[] /* o : point in RE8 (8-dimensional integer vector) */ + ); + + //lead_deindexing_fx.c + + void re8_decode_base_index_fx(const Word16 n, UWord16 I, Word16 *x); + + //re8_utils_fx.c + void re8_k2y_fx( + const Word16 *k, /* i : Voronoi index k[0..7] */ + const Word16 m, /* i : Voronoi modulo (m = 2^r = 1<=2) */ + Word16 *y /* o : 8-dimensional point y[0..7] in RE8 */ + ); + + void re8_vor_fx( + const Word16 y[], /* i : point in RE8 (8-dimensional integer vector) */ + Word16 *n, /* o : codebook number n=0,2,3,4,... (scalar integer) */ + Word16 k[], /* o : Voronoi index (integer vector of dimension 8) used only if n>4*/ + Word16 c[], /* o : codevector in Q0, Q2, Q3, or Q4 if n<=4, y=c */ + Word16 *ka /* o : identifier of absolute leader (to index c) */ + ); + + //re8_PPV_fx.c + void re8_PPV_fx( + const Word32 x[], /* i : point in R^8Q15 */ + Word16 y[] /* o : point in RE8 (8-dimensional integer vector) */ + ); + + //dec_pit_exc_fx.c + void dec_pit_exc_fx( + Decoder_State* st_fx, /* i/o: decoder static memory */ + const Word16* Aq_fx, /* i : LP filter coefficient */ + const Word16 coder_type_fx, /* i : coding type */ + const Word16 Es_pred_fx, /* i : predicted scaled innov. energy */ + Word16* pitch_buf_fx, /* o : floating pitch values for each subframe */ + Word16* code_fx, /* o : innovation */ + Word16* exc_fx, /* i/o: adapt. excitation exc */ + Word16* bwe_exc_fx, /* o : excitation for SWB TBE */ + const Word16 nb_subfr_fx /* i : Number of subframe considered */ + , Word16* gain_buf /*Q14*/ +#ifdef ADD_LRTD + , const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ + const Word16 tdm_Pri_pitch_buf[] /* i : primary channel pitch buffer */ +#endif + ); + + //pit_dec_fx.c + + Word32 Mode2_pit_decode( /* o: floating pitch value */ + const Word16 coder_type, /* i: coding model */ + Word16 i_subfr, /* i: subframe index */ + Word16 L_subfr, + Word16 **pt_indice, /* i/o: quantization indices pointer */ + Word16 *T0, /* i/o: close loop integer pitch */ + Word16 *T0_frac, /* o: close loop fractional part of the pitch */ + Word16 *T0_res, /* i/o: pitch resolution */ + Word16 *T0_min, /* i/o: lower limit for close-loop search */ + Word16 *T0_min_frac, /* i/o: lower limit for close-loop search */ + Word16 *T0_max, /* i/o: higher limit for close-loop search */ + Word16 *T0_max_frac, /* i/o: higher limit for close-loop search */ + Word16 pit_min, + Word16 pit_fr1, + Word16 pit_fr1b, + Word16 pit_fr2, + Word16 pit_max, + Word16 pit_res_max + ); + + void Mode2_abs_pit_dec( + Word16 *T0, /* o: integer pitch lag */ + Word16 *T0_frac, /* o: pitch fraction */ + Word16 *T0_res, /* o: pitch resolution */ + Word16 **pt_indice, /* i/o: pointer to Vector of Q indexes */ + Word16 pit_min, + Word16 pit_fr1, + Word16 pit_fr2, + Word16 pit_res_max + ); + + void Mode2_delta_pit_dec( + Word16 *T0, /* o: integer pitch lag */ + Word16 *T0_frac, /* o: pitch fraction */ + Word16 T0_res, /* i: pitch resolution */ + Word16 *T0_min, /* i: delta search min */ + Word16 *T0_min_frac, /* i: delta search min */ + Word16 **pt_indice /* i/o: pointer to Vector of Q indexes */ + ); + + Word16 pit_decode_fx( /* o : floating pitch value */ + Decoder_State *st_fx, /* i/o: decoder state structure */ + const Word32 core_brate, /* i : core bitrate */ + const Word16 Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ + const Word16 L_frame, /* i : length of the frame */ + Word16 i_subfr, /* i : subframe index */ + const Word16 coder_type, /* i : coding type */ + Word16 *limit_flag, /* i/o: restrained(0) or extended(1) Q limits */ + Word16 *T0, /* o : close loop integer pitch */ + Word16 *T0_frac, /* o : close loop fractional part of the pitch */ + Word16 *T0_min, /* i/o: delta search min for sf 2 & 4 */ + Word16 *T0_max, /* i/o: delta search max for sf 2 & 4 */ + const Word16 L_subfr /* i : subframe length */ +#ifdef ADD_LRTD + , const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ + const Word16 tdm_Pri_pitch_buf[] /* i : primary channel pitch buffer */ +#endif + ); + + void pit_Q_dec_fx( + const Word16 Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ + const Word16 pitch_index, /* i : pitch index */ + const Word16 nBits, /* i : # of Q bits */ + const Word16 delta, /* i : Half the CL searched interval */ + const Word16 pit_flag, /* i : absolute(0) or delta(1) pitch Q */ + const Word16 limit_flag, /* i : restrained(0) or extended(1) Q limits */ + Word16 *T0, /* o : integer pitch lag */ + Word16 *T0_frac, /* o : pitch fraction */ + Word16 *T0_min, /* i/o: delta search min */ + Word16 *T0_max /* i/o: delta search max */ + , Word16 *BER_detect /* o : BER detect flag */ + ); + + void pit16k_Q_dec_fx( + const Word16 pitch_index, /* i : pitch index */ + const Word16 nBits, /* i : # of Q bits */ + const Word16 limit_flag, /* i : restrained(0) or extended(1) limits */ + Word16 *T0, /* o : integer pitch lag */ + Word16 *T0_frac, /* o : pitch fraction */ + Word16 *T0_min, /* i/o: delta search min */ + Word16 *T0_max /* i/o: delta search max */ + , Word16 *BER_detect /* o : BER detect flag */ + ); + + void abs_pit_dec_fx( + const Word16 fr_steps, /* i: fractional resolution steps (0, 2, 4) */ + Word16 pitch_index, /* i: pitch index */ + const Word16 limit_flag, /* i : restrained(0) or extended(1) limits */ + Word16 *T0, /* o: integer pitch lag */ + Word16 *T0_frac /* o: pitch fraction */ + ); + + void delta_pit_dec_fx( + const Word16 fr_steps, /* i : fractional resolution steps (0, 2, 4) */ + const Word16 pitch_index, /* i : pitch index */ + Word16 *T0, /* o : integer pitch lag */ + Word16 *T0_frac, /* o : pitch fraction */ + const Word16 T0_min /* i : delta search min */ + ); + + //limit_t0_fx.c + void limit_T0_fx( + const Word16 L_frame, /* i : length of the frame */ + const Word16 delta, /* i : Half the close-loop searched interval */ + const Word16 pit_flag, /* i : selecting absolute(0) or delta(1) pitch quantization */ + const Word16 limit_flag, /* i : flag for Q limits (0=restrained, 1=extended) */ + const Word16 T0, /* i : rough pitch estimate around which the search is done */ + const Word16 T0_frac, /* i : pitch estimate fractional part */ + Word16 *T0_min, /* o : lower pitch limit */ + Word16 *T0_max /* o : higher pitch limit */ + ); + + void limit_T0_voiced( + const Word16 nbits, + const Word16 res, + const Word16 T0, /* i : rough pitch estimate around which the search is done */ + const Word16 T0_frac, /* i : pitch estimate fractional part */ + const Word16 T0_res, /* i : pitch resolution */ + Word16 *T0_min, /* o : lower pitch limit */ + Word16 *T0_min_frac, /* o : lower pitch limit */ + Word16 *T0_max, /* o : higher pitch limit */ + Word16 *T0_max_frac, /* o : higher pitch limit */ + const Word16 pit_min, /* i : Minimum pitch lag */ + const Word16 pit_max /* i : Maximum pitch lag */ + ); + + //inov_dec.c + void inov_decode_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + const Word32 core_brate, /* i : core bitrate */ + const Word16 Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ + const Word16 L_frame, /* i : length of the frame */ + const Word16 sharpFlag, /* i : formant sharpening flag */ + const Word16 i_subfr, /* i : subframe index */ + const Word16 *p_Aq, /* i : LP filter coefficients Q12 */ + const Word16 tilt_code, /* i : tilt of the excitation of previous subframe Q15 */ + const Word16 pt_pitch, /* i : pointer to current subframe fractional pitch Q6*/ + Word16 *code /* o : algebraic excitation */ + , const Word16 L_subfr /* i : subframe length */ + ); + + //dec4t64_fx.c + void dec_acelp_4t64_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + Word16 nbbits, /* i : number of bits per codebook */ + Word16 code[], /* o : algebraic (fixed) codebook excitation Q9*/ + const Word16 Opt_AMR_WB + ); + + void D_ACELP_decode_43bit(UWord16 idxs[], Word16 code[], Word16 *pulsestrack); + + //dec_acelp_fx.c + void D_ACELP_indexing( + Word16 code[], + PulseConfig config, + Word16 num_tracks, + Word16 index[] + , Word16 *BER_detect + ); + + void fcb_pulse_track_joint_decode(UWord16 *idxs, Word16 wordcnt, UWord32 *index_n, Word16 *pulse_num, Word16 track_num); + + + //dec2t32_fx.c + void dec_acelp_2t32_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + Word16 code[] /* o: algebraic (fixed) codebook excitation */ + ); + + void dec_acelp_1t64_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + Word16 code[] /* o: algebraic (fixed) codebook excitation Q12*/ + , const Word16 L_subfr /* i : sub frame lenght*/ + ); + + //acelp_core_switch)dec_fx.c + ivas_error acelp_core_switch_dec_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + Word16 *synth_subfr_out, /* o : synthesized ACELP subframe Q_syn*/ + Word16 *tmp_synth_bwe, /* o : synthesized ACELP subframe BWE Q_syn*/ + const Word16 output_frame, /* i : input frame length */ + const Word16 core_switching_flag, /* i : core switching flag */ + Word16 *mem_synth, /* o : synthesis to overlap */ + Word16 *Q_syn + ); + + ivas_error acelp_core_switch_dec_bfi_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + Word16 synth_out[], /* o : synthesis Q_syn */ + const Word16 coder_type /* i : coder type */ + ); + + //pred_lt4_fx.c + void pred_lt4( + const Word16 excI[], /* in : excitation buffer */ + Word16 excO[], /* out: excitation buffer */ + const Word16 T0, /* i : integer pitch lag */ + Word16 frac, /* i : fraction of lag */ + const Word16 L_subfr, /* i : subframe size */ + const Word16* win, /* i : interpolation window */ + const Word16 nb_coef, /* i : nb of filter coef */ + const Word16 up_sample /* i : up_sample */ + ); + + + void pred_lt4_tc_fx( + Word16 exc[], /* i/o: excitation buffer */ + const Word16 T0, /* i : integer pitch lag */ + Word16 frac, /* i: fraction of lag */ + const Word16 *win, /* i : interpolation window */ + const Word16 imp_pos, /* i : glottal impulse position */ + const Word16 i_subfr /* i : subframe index */ + ); + + //pvq_cored_dec + void pvq_decode_frame_fx( + Decoder_State *st_fx, + Word16 *coefs_quant, /* o : quantized coefficients */ + Word16 *npulses, /* o : number of pulses per band */ + Word16 *pulse_vector, /* o : non-normalized pulse shapes */ + const Word16 *sfm_start, /* i : indices of first coefficients in the bands */ + const Word16 *sfm_end, /* i : indices of last coefficients in the bands */ + const Word16 *sfmsize, /* i : band sizes */ + const Word16 nb_sfm, /* i : total number of bands */ + const Word16 *R, /* i : bitallocation per band */ + const Word16 pvq_bits, /* i : number of bits avaiable */ + const Word16 core /* i : core */ + ); + + Word16 pvq_core_dec_fx( + Decoder_State *st_fx, + const Word16 *sfm_start, + const Word16 *sfm_end, + const Word16 *sfmsize, + Word16 coefs_quant[], /* o : output MDCT */ + Word16 *Q_coefs, + Word16 bits_tot, + Word16 nb_sfm, + Word16 *R, + Word16 *Rs, + Word16 *npulses, + Word16 *maxpulse, + const Word16 core + ); + + void decode_energies_fx( + Decoder_State *st_fx, + PVQ_DEC_HANDLE hPVQ, /* i/o: PVQ decoder handle */ + Word16 Np, + Word16 *dim_part, + Word16 *bits_part, + Word16 *g_part, /* Q15 */ + Word16 qband, + Word16 *bits_left, + Word16 dim, + const Word16 strict_bits + ); + + //range_drc_fx.c + void rc_dec_init_fx( + Decoder_State *st_fx, /* i/o: Decoder State */ + PVQ_DEC_HANDLE hPVQ, /* i/o: PVQ decoder handle */ + Word16 tot_bits /* i : Total bit budget */ + ); + + UWord32 rc_decode_fx( /* o : Decoded cumulative frequency */ + Word16* BER_detect, /* o : Bit error detection flag */ + PVQ_DEC_HANDLE hPVQ, /* i/o: PVQ decoder handle */ + UWord32 tot /* i : Total cumulative frequency */ + ); + + void rc_dec_update_fx( + Decoder_State *st_fx, /* i/o: Decoder State */ + PVQ_DEC_HANDLE hPVQ, /* i/o: PVQ decoder handle */ + + UWord32 cum_freq, /* i : Cumulative frequency */ + UWord32 sym_freq /* i : Symbol frequency */ + ); + + Word32 rc_dec_bits_fx( /* i : Decoded value */ + Decoder_State *st_fx, /* i/o: Decoder State */ + PVQ_DEC_HANDLE hPVQ, /* i/o: PVQ decoder handle */ + Word16 bits /* i : Number of bits */ + ); + + UWord32 rc_dec_uniform_fx( /* i : Decoded value */ + Decoder_State *st_fx, /* i/o: Decoder State */ + PVQ_DEC_HANDLE hPVQ, /* i/o: PVQ decoder handle */ + + UWord32 tot /* i : Maximum value */ + ); + + void rc_dec_finish_fx( + Decoder_State *st_fx, + PVQ_DEC_HANDLE hPVQ /* i/o: PVQ decoder handle */ + ); + + //pvq_decode_fx.c + void pvq_decode_fx( + Decoder_State *st_fx, + PVQ_DEC_HANDLE hPVQ, /* i/o: PVQ decoder handle */ + Word16 *xq, /* o: decoded vector (Q15) */ + Word16 *y, /* o: decoded vector (non-scaled int) */ + const Word16 k_val, /* i: number of allocated pulses */ + const Word16 dim, /* i: Length of vector */ + const Word16 neg_gain /* i: Gain (negated to fit 1.0 in Q15 as -1.0) */ + ); + + //nelp_dec_fx.c + void nelp_decoder_fx( + Decoder_State *st, /* i/o: decoder static memory */ + Word16 *exc_nelp, /* o : adapt. excitation/total exc */ + Word16 *exc, /* o : adapt. excitation exc */ + Word16 *Q_exc, + Word16 bfi, /* i : frame error rate */ + const Word16 coder_type /* i : coding type */ + , Word16 *gain_buf /*Q14*/ + ); + + //dec_nelp_fx.c + void decod_nelp_fx( + Decoder_State *st_fx, /* i/o: decoder static memory */ + Word16 *tmp_noise_fx, /* o : long term temporary noise energy */ + Word16 *pitch_buf_fx, /* o : floating pitch values for each subframe*/ + Word16 *exc_fx, /* o : adapt. excitation exc */ + Word16 *exc2_fx, /* o : adapt. excitation/total exc */ + Word16 *voice_factors, /* o : Voice factor */ + Word16 *bwe_exc, + Word16 *Q_exc, + Word16 bfi /* i : frame error rate */ + , Word16 *gain_buf /*Q14*/ + ); + + //lp_filt_exc_dec_fx + void lp_filt_exc_dec_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + const Word16 codec_mode, /* i : coder mode */ + const Word16 i_subfr, /* i : subframe index */ + const Word16 L_subfr, /* i : subframe size */ + const Word16 L_frame, /* i : frame size */ + Word16 lp_flag, /* i : operation mode signalling */ + Word16 *exc + ); + + //FEC_lsf_estim_fx.c + void FEC_lsf2lsp_interp( + Decoder_State *st, /* i/o: Decoder static memory */ + const Word16 L_frame, /* i : length of the frame */ + Word16 *Aq, /* o : calculated A(z) for 4 subframes */ + Word16 *lsf, /* o : estimated LSF vector */ + Word16 *lsp /* o : estimated LSP vector */ + ); + + + //fd_cng_dec_fx.c + ivas_error createFdCngDec(HANDLE_FD_CNG_DEC* hFdCngDec); + + void initFdCngDec( + DEC_CORE_HANDLE st, /* i/o: decoder state structure */ + Word16 scale + ); + + /* Delete the instance of type FD_CNG */ + void deleteFdCngDec(HANDLE_FD_CNG_DEC* hFdCngDec); + + /* Configure CLDFB-CNG */ + void configureFdCngDec( + HANDLE_FD_CNG_DEC hFdCngDec, /* i/o: Contains the variables related to the CLDFB-based CNG process */ + Word16 bandwidth, + Word32 bitrate, + Word16 L_frame, + const Word16 Last_L_frame, + const Word16 element_mode + ); + + /* Apply the CLDFB-based CNG */ + Word16 ApplyFdCng( + Word16* timeDomainInput, /* i : pointer to time domain i */ + Word16 Q, +#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT + Word16* powerSpectrum, +#endif + Word32** cldfbBufferReal, /* i/o: real part of the CLDFB buffer */ + Word32** cldfbBufferImag, /* i/o: imaginary part of the CLDFB buffer */ + Word16* cldfbBufferScale, /* o : pointer to the scalefactor for real and imaginary part of the CLDFB buffer */ + Decoder_State* st, + const Word16 concealWholeFrame, /* i : binary flag indicating frame loss */ + Word16 is_music + ); + + /* Perform noise estimation */ + void perform_noise_estimation_dec( + const Word16* timeDomainInput, /* i: pointer to time domain i */ + const Word16 Q, +#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT + float* power_spectrum, +#endif + HANDLE_FD_CNG_DEC hFdCngDec /* i/o: FD_CNG structure containing all buffers and variables */ +#ifdef IVAS_CODE_CNG + , const Word16 element_mode, /* i : element mode */ + const Word16 bwidth, /* i : audio bandwidth */ + const Word16 L_frame, /* i : frame length at internal Fs */ + const Word16 last_L_frame, /* i : frame length of the last frame at internal Fs */ + const Word32 last_core_brate, /* i : previous frame core bitrate */ + const Word16 VAD /* i : VAD flag in the decoder */ +#endif + ); + + /* Decode the CLDFB-CNG bitstream */ + void FdCng_decodeSID(HANDLE_FD_CNG_COM st, /* i/o: FD_CNG structure containing all buffers and variables */ + Decoder_State *corest); /* i/o: decoder state structure */ + + void noisy_speech_detection( + HANDLE_FD_CNG_DEC hFdCngDec,/* i/o: FD_CNG structure */ + const Word16 vad, /* i : VAD flag */ + const Word16* syn, /* i : i time-domain frame */ + const Word16 Q + ); + + void generate_comfort_noise_dec( + Word32 **bufferReal, /* o : matrix to real part of i bands */ + Word32 **bufferImag, /* o : matrix to imaginary part of i bands */ + Word16 *bufferScale, /* o : pointer to scalefactor for real and imaginary part of i bands */ + Decoder_State *stdec, + Word16 *Q_new, + Word16 gen_exc + , const Word16 nchan_out /* i : number of output channels */ + ); + + void + generate_comfort_noise_dec_hf(Word32 **bufferReal, /* o : matrix to real part of i bands */ + Word32 **bufferImag, /* o : matrix to imaginary part of i bands */ + Word16 *bufferScale, /* o : pointer to scalefactor for real and imaginary part of i bands */ + Decoder_State *stdec + ); + + /* Generate the comfort noise based on the target noise level */ + void generate_masking_noise(Word16 *timeDomainBuffer, /* i/o: time-domain signal */ + Word16 Q, + HANDLE_FD_CNG_COM st /* i/o: FD_CNG structure containing all buffers and variables */ + , Word16 length + , Word16 core + ); + + void generate_masking_noise_update_seed( + HANDLE_FD_CNG_COM st /* i/o : pointer to FD_CNG_COM structure */ + ); + + void generate_masking_noise_mdct(Word32 *mdctBuffer, /* i/o: time-domain signal */ + Word16 *mdctBuffer_e, /* i/o: exponent time-domain signal */ + HANDLE_FD_CNG_COM st /* i/o: FD_CNG structure containing all buffers and variables */ + , Word16 L_frame + ); + +//init_dec_fx.c + ivas_error init_decoder_fx( + Decoder_State *st_fx, /* o: Decoder static variables structure */ + const Word16 idchan /* i : channel ID */ + ); + + void reset_preecho_dec_fx( + HQ_DEC_HANDLE hHQ_core /* i/o: HQ core data handle */ + ); + + void destroy_cldfb_decoder( + Decoder_State *st_fx /* o: Decoder static variables structure */ + ); + + //swb_bwe_dec_fx.c + Word16 WB_BWE_gain_deq_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + Word16 *WB_fenv + ); + + + Word16 wb_bwe_dec_fx( +#ifdef ADD_IVAS_BWE + const Word16 output[], /* i : suntehsis @ internal Fs */ +#endif + Word16 *synth_fx, /* i/o: ACELP core synthesis/final synthesis */ + Word16 *hb_synth_fx, /* o : SHB synthesis/final synthesis */ +#ifdef ADD_IVAS_BWE + const Word16 use_cldfb_for_dft, /* i : flag to use of CLDFB for DFT Stereo */ +#endif + const Word16 output_frame, /* i : frame length */ + Word16 *voice_factors_fx, /* i : voicing factors */ + const Word16 pitch_buf_fx[],/* i : pitch buffer */ + Decoder_State *st_fx /* i/o: decoder state structure */ + , Word16 * Qpost + ); + + Word16 swb_bwe_gain_deq_fx( /* o : BWE class */ + Decoder_State *st_fx, /* i/o: decoder state structure */ + const Word16 core, /* i : core */ + Word16 *SWB_tenv, /* o : Q0, time-domain BWE envelope */ + Word16 *SWB_fenv, /* o : Q1, frequency-domain BWE envelope */ + const Word16 hr_flag, /* i : high rate flag */ + const Word16 hqswb_clas /* i : HQ BWE class */ + ); + + Word16 swb_bwe_dec_fx( +#ifdef ADD_IVAS_BWE + const Word16 output[], /* i : suntehsis @ internal Fs */ +#endif + Decoder_State *st_fx, /* i/o: decoder state structure */ + Word16 *synth_fx, /* i : ACELP core synthesis/final synthesis */ + Word16 *hb_synth, /* o : SHB synthesis/final synthesis */ +#ifdef ADD_IVAS_BWE + const Word16 use_cldfb_for_dft, /* i : flag to use of CLDFB for DFT Stereo */ +#endif + const Word16 output_frame /* i : frame length */ + , Word16 * Qpost + ); + + void fd_bwe_dec_init( + Decoder_State* st_fx, /* i/o: decoder state structure */ + FD_BWE_DEC_HANDLE hBWE_FD /* i/o: FD BWE data handle */ + ); + + //hq_core_dec_fx.c + void hq_core_dec_fx( + Decoder_State *st_fx, /* i/o: decoder state structure fx */ + Word16 synth[], /* o : output synthesis */ + Word16 *Q_synth, /* o : Q value of synth */ + const Word16 output_frame, /* i : output frame length */ + const Word16 hq_core_type, /* i : HQ core type */ + const Word16 core_switching_flag /* i : ACELP->HQ switching frame flag */ + ); + void HQ_core_dec_init( + HQ_DEC_HANDLE hHQ_core /* i/o: HQ core data handle */ + ); + void HQ_nbfec_init( + HQ_NBFEC_HANDLE hHQ_nbfec /* i/o: HQ NB FEC data handle */ + ); + + + //FEC_HQ_phase_ecu_fx.c + void hq_ecu_fx( + const Word16 *prevsynth, /* i : buffer of previously synthesized signal */ + Word32 *ecu_rec, /* o : reconstructed frame in tda domain */ + Word16 *time_offs, + Word16 *X_sav, + Word16 *Q_spec, /* i/o : Q value of stored spectrum */ + Word16 *num_p, + Word16 *plocs, + Word32 *plocsi, /* o : Interpolated positions of the identified peaks (Q16) */ + const Word16 env_stab, + Word16 *last_fec, + const Word16 ph_ecu_HqVoicing, + Word16 *ph_ecu_active, /* i : Phase ECU active flag */ + Word16 *gapsynth, + const Word16 prev_bfi, /* i : indicating burst frame error */ + const Word16 old_is_transient[2], /* i : flags indicating previous transient frames */ + Word16 *mag_chg_1st, /* i/o: per band magnitude modifier for transients*/ + Word16 *Xavg, /* i/o: Frequency group average gain to fade to */ + Word16 *beta_mute, /* o : Factor for long-term mute */ + const Word16 output_frame, /* i : frame length */ + Decoder_State *st_fx /* i/o: decoder state structure */ + ); + + + //hq_lr_dec_fx.c + void hq_lr_dec_fx( + Decoder_State *st_fx, /* i/o: : decoder state structure */ + Word32 L_yout[], /* o : Q12 : transform-domain output coefs. */ + const Word16 inner_frame, /* i : Q0 : inner frame length */ + Word16 num_bits, /* i : Q0 : number of available bits */ + Word16 *is_transient_fx /* o : Q0 : transient flag */ + ); + + //gq_env_dec_fx.c + Word16 decode_envelope_indices_fx( /* o : Number of bits */ + Decoder_State *st_fx, /* i/o: decoder state structure */ + const Word16 start_norm, /* i : starting band index */ + const Word16 num_sfm, /* i : Number of subbands */ + const Word16 numnrmibits, /* i : Bitrate of fall-back coding mode */ + Word16 *difidx, /* o : Diff indices/encoded diff indices */ + const Word16 flag_HQ2 /* i : indicator of HQ2 core */ + , + const Word16 is_transient /* i : indicator of HQ_TRANSIENT */ + ); + + void dequantize_norms_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + const Word16 start_norm, /* i : First SDE encoded norm */ + const Word16 num_sfm, /* i : Number of norms */ + const Word16 is_transient, /* i : Transient flag */ + Word16 *ynrm, /* o : Decoded norm indices */ + Word16 *normqlg2 /* o : Log2 of decoded norms */ + ); + + //hdecnrm_fx.c + void hdecnrm_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + const Word16 numNorms, /* (i) number of norms */ + Word16 *index); /* (o) indices of quantized norms */ + + + Word16 decode_huff_context_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + const Word16 *hufftab, + Word16 *rbits + ); + + void hdecnrm_context_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + const Word16 N, + Word16 *index, + Word16 *n_length + ); + + void hdecnrm_resize_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + const Word16 N, /* (i) number of SFMs */ + Word16 *index /* (o) norm quantization index vector */ + ); + + void huff_dec_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + const Word16 N, /* i : Number of codewords to decode */ + const Word16 buffer_len, /* i : Number of bits to read */ + const Word16 num_lengths, /* i : Number of different huffman codeword lengths */ + const Word16 *thres, /* i : Threshold of first codeword of each length */ + const Word16 *offset, /* i : Offset for first codeword */ + const Word16 *huff_tab, /* i : Huffman table order by codeword lengths */ + Word16 *index /* o : Decoded index */ + ); + + void hdecnrm_tran_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + const Word16 N, /* i : number of norms */ + Word16 *index /* o : indices of quantized norms */ + ); + + //tcq_core_dec_fx.c + void tcq_core_LR_dec_fx( + Decoder_State *st_fx, + Word16 *inp_vector_fx, + const Word16 bit_budget, + const Word16 bands, + const Word16 *band_start, + const Word16 *band_width, + Word32 *Rk_fx, + Word16 *npulses, + Word16 *k_sort, + const Word16 *p2a_flags, + const Word16 p2a_bands, + const Word16 *last_bitalloc, + const Word16 input_frame, + const Word16 adjustFlag, + const Word16 *is_transient + ); + + //FEC_HQ_core_fx.c + void HQ_FEC_processing_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + Word32 *t_audio_q_fx, /* o : MDCT coeffs. (for synthesis) Q12 */ + Word16 is_transient, /* i : Old flag for transient */ + Word32 ynrm_values_fx[][MAX_PGF], /* i : Old average Norm values for each group of bands Q12 */ + Word32 r_p_values_fx[][MAX_ROW], /* i : Computed y-intercept and slope by Regression Q5 */ + Word16 num_Sb, /* i : Number of sub-band group */ + Word16 nb_sfm, /* i : Number of sub-band */ + Word16 *Num_bands_p, /* i : Number of coeffs. for each sub-band */ + Word16 output_frame, /* i : Frame size */ + const Word16 *sfm_start, /* i : Start of bands */ + const Word16 *sfm_end /* i : End of bands */ + ); + + void HQ_FEC_Mem_update_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + Word32 *t_audio_q_fx, /*Q12*/ + Word32 *normq_fx, /*Q14*/ + Word16 *ynrm, + Word16 *Num_bands_p, + Word16 is_transient, + Word16 hqswb_clas, + Word16 c_switching_flag, + Word16 nb_sfm, + Word16 num_Sb, + Word16 *mean_en_high_fx, /*Q5*/ + Word16 hq_core_type, /* i : normal or low-rate MDCT(HQ) core */ + Word16 output_frame + ); + + void time_domain_FEC_HQ_fx( + Decoder_State *st_fx, /* i : Decoder State */ + Word32 *wtda_audio_fx, /* i : i */ + Word16 *out_fx, /* o : output audio */ + Word16 mean_en_high_fx, /* i : transient flag */ + const Word16 output_frame, + Word16 *Q_synth + ); + + //hq_hr_dec_fx.c + void hq_pred_hb_bws_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + const Word16 *ynrm, /* i : norm quantization index vector */ + const Word16 length, /* i : frame length */ + const Word16 hqswb_clas, /* i : HQ SWB class */ + const Word16 *SWB_fenv /* i : SWB frequency envelopes Q1 */ + ); + + void hq_hr_dec_fx( + Decoder_State *st_fx, /* i/o: decoder state structure fx */ + Word32 *L_coefsq, /* o : transform-domain coefficients Q12 */ + const Word16 length, /* i : frame length Q0 */ + Word16 num_bits, /* i : number of available bits Q0 */ + Word16 *ynrm, /* o : norm quantization index vector Q0 */ + Word16 *is_transient, /* o : transient flag Q0 */ + Word16 *hqswb_clas, /* o : HQ SWB class Q0 */ + Word16 *SWB_fenv, /* o : SWB frequency envelopes Q1 */ + const Word16 core_switching_flag /* i : Core switching flag */ + ); + + //hq_classifier_dec_fx.c + Word16 hq_classifier_dec_fx( /* o : Consumed bits Q0 */ + Decoder_State *st_fx, /* i/o: decoder state structure */ + const Word32 core_brate, /* i : Core bit rate Q0 */ + const Word16 length, /* i : Frame length Q0 */ + Word16 *is_transient, /* o : Transient flag Q0 */ + Word16 *hqswb_clas /* o : HQ class Q0 */ + ); + + //peak_vq_dec_fx.c + void hvq_dec_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + const Word16 num_bits, /* i : Number of available bits */ + const Word32 core_brate, /* i : Core bit-rate */ + const Word16 *ynrm, /* i : Envelope coefficients */ + Word16 *R, /* i/o: Bit allocation/updated bit allocation */ + Word16 *noise_level, /* o : Noise level in Q15 */ + Word16 *peak_idx, /* o : Peak position vector */ + Word16 *Npeaks, /* o : Total number of peaks */ + Word32 *coefsq_norm, /* o : Output vector in Q12 */ + const Word16 core + ); + + //hvq_pvq_bitalloc_fx.c + Word16 hvq_pvq_bitalloc_fx( + Word16 num_bits, /* i/o: Number of available bits (including gain bits) */ + const Word32 brate, /* i : bitrate */ + const Word16 bwidth_fx, /* i : Encoded bandwidth */ + const Word16 *ynrm, /* i : Envelope coefficients */ + const Word32 manE_peak, /* i : Peak energy mantissa */ + const Word16 expE_peak, /* i : Peak energy exponent */ + Word16 *Rk, /* o : bit allocation for concatenated vector */ + Word16 *R, /* i/o: Global bit allocation */ + Word16 *sel_bands, /* o : Selected bands for encoding */ + Word16 *n_sel_bands /* o : No. of selected bands for encoding */ + ); + + //hq_conf_fec_fx.c + void hq_configure_bfi_fx( + Word16* nb_sfm, /* o : Number of sub bands Q0 */ + Word16* num_Sb, /* o : Number of FEC sub bands ? Q0 */ + Word16* num_bands_p, /* o : FEC sub bands Q0 */ + const Word16** sfmsize, /* o : Subband bandwidths */ + const Word16** sfm_start, /* o : Subband start coefficients */ + const Word16** sfm_end /* o : Subband end coefficients */ + ); + + //core_switching_dec_fx.c + void bandwidth_switching_detect_fx( + Decoder_State *st_fx /* i/o: encoder state structure */ + ); + + void bw_switching_pre_proc_fx( + const Word16 *old_syn_12k8_16k_fx, /* i : ACELP core synthesis at 12.8kHz or 16kHz */ + Decoder_State *st_fx /* i/o: decoder state structure */ + ); + + ivas_error core_switching_pre_dec_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + const Word16 output_frame /* i : frame length */ + ); + + ivas_error core_switching_post_dec_fx( + Decoder_State * st_fx, /* i/o: decoder state structure */ + Word16* synth, /* i/o: output synthesis Qsynth */ +#ifdef IVAS_CODE_SWITCHING + float* output, /* i/o: LB synth/upsampled LB synth */ + float output_mem[], /* i : OLA memory from last TCX/HQ frame */ + const IVAS_FORMAT ivas_format, /* i : IVAS format */ + const Word16 use_cldfb_for_dft, /* i : flag to use of CLDFB for DFT Stereo */ +#endif + const Word16 output_frame, /* i : frame length */ + const Word16 core_switching_flag, /* i : ACELP->HQ switching flag */ +#ifdef IVAS_CODE_SWITCHING + const Word16 sba_dirac_stereo_flag, /* i : signal stereo output for SBA DirAC */ + const Word16 nchan_out, /* i : number of output channels */ +#endif + const Word16 last_element_mode, /* i : element mode of previous frame */ + Word16* Qsynth /* i/o: Scaling of ACELP exit (Q_syn2-1) or HQ exit (Qsynth); changes after this function */ + ); + + void core_switching_hq_prepare_dec_fx( + Decoder_State *st_fx, /* i/o: encoder state structure */ + Word16 *num_bits, /* i/o: bit budget update */ + const Word16 output_frame /* i : output frame length */ + ); + + //amr_wb_dec_fx.c + ivas_error amr_wb_dec_fx( + Word16 output_sp[], /* o : synthesis output */ + Decoder_State *st_fx /* o : Decoder static variables structure */ + ); + + void amr_wb_dec_init( + AMRWB_IO_DEC_HANDLE hAmrwb_IO /* i/o: AMR-WB IO data handle */ + ); + + //updt_dec_fx.c + void updt_dec_fx( + Decoder_State *st_fx, /* i/o: state structure */ + const Word16 *old_exc_fx, /* i : buffer of excitation */ + const Word16 *pitch_buf_fx, /* i : floating pitch values for each subframe */ + const Word16 Es_pred, /* i : predicited scaled innovation energy */ + const Word16 *Aq, /* i : A(z) quantized for all subframes */ + const Word16 *lsf_new_fx, /* i : current frame LSF vector */ + const Word16 *lsp_new_fx, /* i : current frame LSP vector */ + const Word16 voice_factors[], /* i : voicing factors */ + const Word16 *old_bwe_exc_fx /* i : buffer of excitation */ + , const Word16 *gain_buf /*Q14*/ + ); + + void updt_IO_switch_dec_fx( + const Word16 output_frame, /* i : output frame length */ + Decoder_State *st_fx /* o : Decoder static variables structure */ + ); + + void updt_bw_switching_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + const Word16 *synth, /* i : float synthesis signal */ + const Word16 Qpost + ); + + void updt_dec_common_fx( + Decoder_State* st_fx, /* i/o: decoder state structure */ + Word16 hq_core_type_fx, /* i : HQ core type */ + const Word16 concealWholeFrameTmp, /* i : concealWholeFrameTmp flag */ + const Word16* synth, /* i : decoded synthesis */ + const Word16 Qpostd /* i : Synthesis Q value */ + ); + + void update_decoder_LPD_cng( + Decoder_State *st, + Word16 coder_type, + Word16 *timeDomainBuffer, + Word16 *A, + Word16 *bpf_noise_buf + ); + + //FEC_clas_estim_fx + void FEC_clas_estim_fx( + Decoder_State *st_fx, /* i/o: decoder state handle */ + const Word16 Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ /*A*/ + const Word16 L_frame, /* i : length of the frame */ + Word16 *clas, /* i/o: frame classification */ + const Word16 coder_type, /* i : coder type */ + const Word16 *pitch, /* i : pitch values for each subframe (Q6) */ + Word16 *syn, /* i : synthesis buffer */ + Word16 *lp_speech, /* i/o: long term active speech energy average Q8 */ + Word16 *decision_hyst, /* i/o: hysteresis of the music/speech decision */ /*A*/ + Word16 *UV_cnt, /* i/o: number of consecutives frames classified as UV */ /*A*/ + Word16 *LT_UV_cnt, /* i/o: long term consecutives frames classified as UV */ /*A*/ + Word16 *Last_ener, /* i/o: last_energy frame */ /*A*/ + Word16 *locattack, /* i/o: detection of attack (mainly to localized speech burst) */ /*A*/ + Word16 *lt_diff_etot, /* i/o: long-term total energy variation */ /*A*/ + Word16 *amr_io_class, /* i/o: classification for AMR-WB IO mode */ /*A*/ + const Word32 bitrate, /* i : Decoded bitrate */ /*A*/ + Word16 Q_syn, /* i : Synthesis scaling */ + Word16 *class_para, /* o : classification para. fmerit1 */ /*A*/ + Word16 *mem_syn_clas_estim, /* i/o: memory of the synthesis signal for frame class estimation */ + Word16 *Q_mem_syn, /*i/o : exponent for memory of synthesis signal for frame class estimation */ /*B*/ + Word16 LTP_Gain, /* i : LTP gain is 0..0.6 or negative Q15*/ /*B*/ + Word16 mode, /* i : signal classifier mode *//*B*/ + Word16 bfi, /* i : bad frame indicator *//*B*/ + Word32 last_core_brate, /* i : bitrate of previous frame */ + const Word16 FEC_mode /* i : ACELP FEC mode */ + ); + + Word16 FEC_pos_dec_fx( + Decoder_State* st_fx, /* i/o: decoder state structure */ + Word16* last_pulse_pos, /* o : last glotal pulse position in the lost ACB */ + Word32* enr_q, /* o : decoded energy in Q0 */ + const Word16 nBits_es_Pred /* i : number of bits for Es_pred Q */ + ); + + // post_dec.h + void post_decoder( + Decoder_State *st, + Word16 synth_buf[], + Word16 pit_gain[], + Word16 pitch[], + Word16 signal_out[], + Word16 * bpf_noise_buf + ); + + void cldfb_synth_set_bandsToZero( + Decoder_State *st, + Word32 **rAnalysis, + Word32 **iAnalysis, + const Word16 nTimeSlots, + const CLDFB_SCALE_FACTOR scaleFactor + ); + + //FEC_pitch_estim_fx.c + void FEC_pitch_estim_fx( + const Word16 Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ + const Word16 last_core, /* i : last core */ + const Word16 L_frame, /* i : length of the frame */ + const Word16 clas, /* i : current frame classification */ + const Word16 last_good, /* i : last good clas information */ + const Word16 pitch_buf[], /* i : Floating pitch for each subframe */ + const Word32 old_pitch_buf[], /* i : buffer of old subframe pitch values 15Q16 */ + Word16 *bfi_pitch, /* i/o: update of the estimated pitch for FEC */ + Word16 *bfi_pitch_frame, /* o : frame length when pitch was updated */ + Word16 *upd_cnt /* i/o: update counter */ + , const Word16 coder_type /* i : coder_type */ + ); + + //FEC_scale_sync_fx.c + void FEC_scale_syn_fx( + const Word16 L_frame, /* i : length of the frame */ + Word16* update_flg, /* o: flag indicating re-synthesis after scaling*/ + Word16 clas, /* i/o: frame classification */ + const Word16 last_good, /* i: last good frame classification */ + Word16* synth, /* i/o: synthesized speech at Fs = 12k8 Hz */ + const Word16* pitch, /* i: pitch values for each subframe */ + Word32 L_enr_old, /* i: energy at the end of previous frame */ + Word32 L_enr_q, /* i: transmitted energy for current frame */ + const Word16 coder_type, /* i: coder type */ + const Word16 LSF_Q_prediction, /* i : LSF prediction mode */ + Word16* scaling_flag, /* i/o: flag to indicate energy control of syn */ + Word32* lp_ener_FEC_av, /* i/o: averaged voiced signal energy */ + Word32* lp_ener_FEC_max, /* i/o: averaged voiced signal energy */ + const Word16 bfi, /* i: current frame BFI */ + const Word32 total_brate, /* i: total bitrate */ + const Word16 prev_bfi, /* i: previous frame BFI */ + const Word32 last_core_brate, /* i: previous frame core bitrate */ + Word16* exc, /* i/o: excitation signal without enhancement */ + Word16* exc2, /* i/o: excitation signal with enhancement */ + Word16 Aq[], /* i/o: LP filter coefs (can be modified if BR) */ + Word16* old_enr_LP, /* i/o: LP filter E of last good voiced frame */ + const Word16* mem_tmp, /* i: temp. initial synthesis filter states */ + Word16* mem_syn, /* o: initial synthesis filter states */ + Word16 Q_exc, + Word16 Q_syn, + const Word16 avoid_lpc_burst_on_recovery, /* i : if true the excitation energy is limited if LP has big gain */ + const Word16 force_scaling /* i: force scaling */ + ); + + //LD_music_post_filter_fx.c + void LD_music_post_filter_fx + ( + MUSIC_POSTFILT_HANDLE hMusicPF, /* i/o: LD music postfilter handle */ + const Word16 dtc_in[], /* i : i synthesis Qdct */ + Word16 dtc_out[], /* o : output synthesis Qdct */ + const Word32 core_brate, /* i : core bitrate Q0 */ + Word16* Old_ener_Q, /* i/o : Old energy scaling factor */ + const Word16 coder_type, /* i : Coder type : -1 in case of IO Q0 */ + const Word16 Last_coder_type, /* i : i scaling Q0 */ + const Word16 Qdct /* i : i scaling Q0 */ + ); + + void Prep_music_postP_fx( + Word16 exc_buffer_in[], /* i/o: excitation buffer Q_exc*/ + Word16 dct_buffer_out[], /* o : DCT output buffer (qdct)*/ + Word16 filt_lfE[], /* i/o: long term spectrum energy Q15 */ + const Word16 last_core, /* i : last core */ + const Word16 *pitch_buf, /* i : current frame pitch information Q6*/ + Word16 *LDm_enh_lp_gbin, /* o : smoothed suppression gain, per bin FFT Q15*/ + const Word16 Q_exc, /* i : excitation scaling */ + Word16 *qdct /* o : Scaling factor of dct coefficient */ + ); + + void Post_music_postP_fx( + Word16 dct_buffer_in[], /* i/o: excitation buffer */ + Word16 *exc2, /* i/o: Current excitation to be overwriten */ + const Word16 *mem_tmp, /* i : previous frame synthesis memory */ + Word16 *st_mem_syn2, /* i/o: current frame synthesis memory */ + const Word16 *Aq, /* i : LPC filter coefficients */ + Word16 *syn, /* i/o: 12k8 synthesis */ + Word16 *Q_exc, /* i : excitation scaling */ + Word16 *prev_Q_syn, /* i : previsous frame synthesis scaling */ + Word16 *Q_syn, /* i : Current frame synthesis scaling */ + Word16 *mem_syn_clas_estim_fx, /* i : old 12k8 synthesis used for frame classification*/ + const Word16 IsIO, /* i: Flag to indicate IO mode */ + Word16 *mem_deemph, /* i/o: speech deemph filter memory */ + Word16 *st_pst_old_syn_fx, /* i/o: psfiler */ + Word16 *st_pst_mem_deemp_err_fx, /* i/o: psfiler */ + Word16 *mem_agc, + PFSTAT *pf_stat, /* i/o: All memories related to NB post filter */ + const Word16 *tmp_buffer /* tmp_buffer in Q-1 */ + , Word16 *mem_tmp2 /* Temporary memory used with scale_syn */ + ); + + void music_postfilt_init( + MUSIC_POSTFILT_HANDLE hMusicPF /* i/o: LD music postfilter handle */ + ); + + //gs_dec_amr_wb.c + void improv_amr_wb_gs_fx( + const Word16 clas, /* i : signal frame class */ + const Word16 coder_type, /* i : coder type */ + const Word32 core_brate, /* i : bitrate allocated to the core */ + Word16 *seed_tcx, /* i/o: Seed used for noise generation */ + Word16 *old_Aq_fx, /* i/o: old LPC filter coefficient */ + Word16 *mem_syn2_fx, /* i/o: synthesis memory */ + const Word16 lt_voice_fac_fx, /* i/o: long term voice factor Q15 */ + const Word16 locattack, /* i : Flag for a detected attack */ + Word16 *Aq_fx, /* i/o: Decoded LP filter coefficient */ + Word16 *exc2_fx, /* i/o: Decoded complete excitation */ + const Word16 Q_exc2, /* i : Exponent of Exc2 */ + Word16 *mem_tmp_fx, /* i/o: synthesis temporary memory */ + Word16 *syn_fx, /* o: Decoded synthesis to be updated */ + const Word16 Q_syn, /* i : Synthesis scaling Q0 */ + const Word16 *pitch_buf_fx, /* i : Decoded pitch buffer */ + const Word16 Last_ener_fx, /* i : Last energy (Q8) */ + const Word16 rate_switching_reset, /* i : rate switching reset flag */ + const Word16 last_coder_type_fx /* i : Last coder_type */ +#ifdef ADD_IVAS_GS_DEC_IMPR + , const Word16 VeryLowRateSTflag /* i : Enable the noise enhancement for very low rate stereo generic mode */ +#endif + ); + + //dec_amr_wb_fx.c + void decod_amr_wb_fx( + Decoder_State *st_fx, /* i/o: decoder static memory */ + const Word16 *Aq_fx, /* i : LP filter coefficients */ + Word16 *pitch_buf_fx, /* o : floating pitch values for each subframe */ + Word16 *exc_fx, /* i/o: adapt. excitation exc */ + Word16 *exc2_fx, /* i/o: adapt. excitation/total exc */ + Word16 hf_gain_fx[NB_SUBFR], /* o : decoded HF gain */ + Word16 *voice_factors_fx, /* o : voicing factors */ + Word16 *gain_buf /* o : floating pitch gain for each subframe Q14 */ + ); + + //rst_dec_fx.c + void CNG_reset_dec_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + Word16 *pitch_buf, /* o : floating pitch for each subframe */ + Word16 *voice_factors /* o : voicing factors */ + ); + + //voiced_dec_fx.c + ivas_error ppp_voiced_decoder_fx( + Decoder_State *st_fx, /* i/o: state structure */ + Word16 *out_fx, /* o : residual signal */ + const Word16 *lpc2_fx, /* i : current frame LPC */ + Word16 *exc_fx, /* i : previous frame excitation */ + Word16 *pitch, /* o : floating pitch values for each subframe */ + Word16 bfi /* i : Frame error rate */ + ); + void sc_vbr_dec_init( + SC_VBR_DEC_HANDLE hSC_VBR /* i/o: SC-VBR decoder handle */ + ); + +//ppp_dec_fx.c + ivas_error ppp_quarter_decoder_fx( + DTFS_STRUCTURE *CURRCW_Q_DTFS_FX, /* i/o: Current CW DTFS */ + Word16 prevCW_lag_fx, /* i : Previous lag */ + Word16 *lastLgainD_fx, /* i/o: Last gain lowband Q11 */ + Word16 *lastHgainD_fx, /* i/o: Last gain highwband Q11 */ + Word16 *lasterbD_fx, /* i/o: Last ERB vector Q13 */ + Word16 bfi, /* i : FER flag */ + Word16 *S_fx, /* i : sine table, Q15 */ + Word16 *C_fx, /* i : cosine table, Q15 */ + DTFS_STRUCTURE PREV_CW_D_FX, /* i : Previous DTFS */ + Decoder_State *st_fx + ); + + //core_dec_init_fx.c + void open_decoder_LPD( + Decoder_State* st, + const Word32 total_brate, +#ifdef NEW_IVAS_OPEN_DEC + const Word32 last_total_brate, +#endif + const Word16 bwidth +#ifdef NEW_IVAS_OPEN_DEC + , const Word16 is_mct, /* i : MCT mode flag */ +#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT + const Word16 last_element_mode, +#endif + const Word16 is_init /* i : indicate call from init_decoder() to avoid double TC initialization */ +#endif + ); + + //swb_bwe_dec_hr_fx.c + + Word16 swb_bwe_dec_hr_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + const Word16 *syn_12k8_16k_fx, /* i : ACELP core synthesis @16kHz */ + const Word16 old_syn_exp, /* i : Exponent of core synthesis */ + Word16 *hb_synth_fx, /* o : SHB synthesis */ + const Word16 output_frame, /* i : frame length */ + const Word16 unbits, /* i : number of core unused bits */ + const Word16 pitch_buf[] /* i : pitch buffer */ + ); + + void hr_bwe_dec_init( + HR_BWE_DEC_HANDLE hBWE_FD_HR /* i/o: HR BWE data handle */ + ); + + //swb_bwe_com_hr_fx.c + void swb_hr_noise_fill_fx( + const Word16 is_transient, /* i : transient flag */ + const Word16 spect_start, /* i : spectrum start point */ + const Word16 spect_end, /* i : spectrum end point */ + const Word16 tilt_wb, /* i : tilt of wideband signal */ + const Word16 pitch, /* i : pitch value */ + const Word16 nq[], /* i : AVQ nq index */ + Word16 Nsv, /* i : number of subband */ + Word16 *bwe_highrate_seed, /* i/o: seed of random noise */ + Word16 *t_audio, /* i/o: mdct spectrum */ + Word16 Q_audio + ); + + //stat_noise_uv_dec_fx.c + void stat_noise_uv_dec_fx( + Decoder_State *st_fx, /* i/o: Decoder static memory */ + Word16 *lsp_new, /* i : end-frame LSP vector */ + Word16 *lsp_mid, /* i : mid-frame LSP vector */ + Word16 *Aq, /* o : A(z) quantized for the 4 subframes */ + Word16 *exc2 /* i/o: excitation buffer */ + , const Word16 uc_two_stage_flag /* i : flag indicating two-stage UC */ + ); + + //stat_noise_uv_mod_fx.c + void stat_noise_uv_mod_fx( + const Word16 coder_type, /* i : Coder type */ + Word16 noisiness, /* i : noisiness parameter */ + const Word16 *lsp_old, /* i : old LSP vector at 4th sfr */ + const Word16 *lsp_new, /* i : LSP vector at 4th sfr */ + const Word16 *lsp_mid, /* i : LSP vector at 2nd sfr */ + Word16 *Aq, /* o : A(z) quantized for the 4 subframes */ + Word16 *exc2, /* i/o: excitation buffer */ + Word16 Q_exc, /* i : Q of exc2 excitation buffer [11..-1] expected */ + const Word16 bfi, /* i : Bad frame indicator */ + Word32 *ge_sm, /* i/o: smoothed excitation gain */ + Word16 *uv_count, /* i/o: unvoiced counter */ + Word16 *act_count, /* i/o: activation counter */ + Word16 lspold_s[], /* i/o: old LSP */ + Word16 *noimix_seed, /* i/o: mixture seed */ + Word16 *st_min_alpha, /* i/o: minimum alpha */ + Word16 *exc_pe, /* i/o: scale Q_stat_noise */ + const Word32 bitrate, /* i : core bitrate */ + const Word16 bwidth_fx, /* i : i bandwidth */ + Word16 *Q_stat_noise, /* i/o: noise scaling */ + Word16 *Q_stat_noise_ge /* i/o: noise scaling */ + ); + + //FEC_adao_codebook_fx.c + Word16 FEC_SinOnset_fx( + Word16 *exc, /* i/o : exc vector to modify */ + Word16 puls_pos, /* i : last pulse position desired */ + const Word16 T0, /* i : Pitch information of the 1 subfr */ + Word32 enr_q, /* i : energy provide by the encoder */ + Word16 *Aq, /* i : A(z) filter Q12 */ + const Word16 L_frame /* i : frame length */ + , const Word16 Qold + ); + + Word16 FEC_enhACB_fx( + const Word16 L_frame, /* i : frame length */ + const Word16 last_L_frame, /* i : frame length of previous frame */ + Word16 *exc_io, /* i/o : adaptive codebook memory */ + const Word16 new_pit, /* i : decoded first frame pitch */ + const Word16 puls_pos, /* i : decoder position of the last glottal pulses decoded in the previous frame */ + const Word16 bfi_pitch /* i : Q6 pitch used for concealment */ + ); + Word16 FEC_synchro_exc_fx( /* o : do_WI flag */ + const Word16 L_frame, /* i : length of the frame */ + Word16 *exc, /* i/o: exc vector to modify */ + const Word16 desire_puls_pos, /* i : Pulse position send by the encoder */ + const Word16 true_puls_pos, /* i : Present pulse location */ + const Word16 Old_pitch /* i : Pitch use to create temporary adaptive codebook */ + ); + + //dec_uv_fx.c + void decod_unvoiced_fx( + Decoder_State *st_fx, /* i/o: decoder static memory */ + const Word16 *Aq_fx, /* Q12 i : LP filter coefficient */ + const Word16 coder_type_fx, /* Q0 i : coding type */ + Word16 *tmp_noise_fx, /* Q5 o : long term temporary noise energy */ + Word16 *pitch_buf_fx, /* Q6 o : floating pitch values for each subframe */ + Word16 *voice_factors_fx, /* Q15 o : voicing factors */ + Word16 *exc_fx, /* Q_X o : adapt. excitation exc */ + Word16 *exc2_fx, /* Q_X o : adapt. excitation/total exc */ + Word16 *bwe_exc_fx, /* Q_X i/o: excitation for SWB TBE */ + Word16 *gain_buf + ); + + //gaus_dec_fx.c + void gaus_dec_fx( + Decoder_State* st_fx, /* i/o: decoder static memory */ + const Word16 i_subfr, /* i : subframe index */ + Word16* code, /* o : unvoiced excitation Q12 */ + Word32* L_norm_gain_code, /* o : gain of normalized gaussian excitation Q16 */ + Word16* lp_gainp, /* i/o : lp filtered pitch gain(FER) Q14 */ + Word16* lp_gainc, /* i/o : lp filtered code gain (FER) Q3 */ + Word16* inv_gain_inov, /* o : unscaled innovation gain Q12 */ + Word16* tilt_code, /* o : synthesis excitation spectrum tilt Q15 */ + Word16* voice_fac, /* o : estimated voicing factor Q15 */ + Word16* gain_pit, /* o : pitch gain Q14 */ + Word16* pt_pitch_1, /* o : floating pitch buffer Q6 */ + Word16* exc, /* o : excitation signal frame */ + Word32* L_gain_code, /* o : gain of the gaussian excitation Q16 */ + Word16* exc2, /* o : Scaled excitation signal frame */ + Word16* bwe_exc_fx, + Word16* sQ_exc, /* i/o : Excitation scaling factor (Decoder state) */ + Word16* sQsubfr /* i/o : Past excitation scaling factors (Decoder State) */ + ); + + void gaus_L2_dec( + Word16 *code, /* o : decoded gaussian codevector Q9 */ + Word16 tilt_code, /* i : tilt of code Q15 */ + const Word16 *A, /* i : quantized LPCs Q12 */ + Word16 formant_enh, /* i : formant enhancement factor Q15 */ + Word16 *seed_acelp /*i/o : random seed Q0 */ + ); + + //dec_gen_voic_fx.c + ivas_error decod_gen_voic_fx( + Decoder_State *st_fx, /* i/o: decoder static memory */ + const Word16 L_frame_fx, /* i : length of the frame */ + const Word16 sharpFlag_fx, /* i : formant sharpening flag */ + const Word16 *Aq_fx, /* i : LP filter coefficient */ + const Word16 Es_pred_fx, /* i : predicted scaled innov. energy */ + const Word16 do_WI_fx, /* i : do interpolation after a FER */ + Word16 *pitch_buf_fx, /* o : floating pitch values for each subframe */ + Word16 *voice_factors_fx, /* o : voicing factors */ + Word16 *exc_fx, /* i/o: adapt. excitation exc */ + Word16 *exc2_fx, /* i/o: adapt. excitation/total exc */ + Word16 *bwe_exc_fx, /* o : excitation for SWB TBE */ + Word16 *unbits, /* number of unused bits */ + Word16* gain_buf /*Q14*/ + ); + + //dec_tran_fx.c + void decod_tran_fx( + Decoder_State *st_fx, /* i/o: decoder static memory */ + const Word16 L_frame_fx, /* i : length of the frame */ + const Word16 tc_subfr_fx, /* i : TC subframe index */ + const Word16 *Aq_fx, /* i : LP filter coefficient */ + const Word16 Es_pred_fx, /* i : predicted scaled innov. energy */ + Word16 *pitch_buf_fx, /* o : floating pitch values for each subframe */ + Word16 *voice_factors_fx, /* o : voicing factors */ + Word16 *exc_fx, /* i/o: adapt. excitation exc */ + Word16 *exc2_fx, /* i/o: adapt. excitation/total exc */ + Word16 *bwe_exc_fx, /* i/o: excitation for SWB TBE */ + Word16 *unbits, /* i/o: number of unused bits */ + const Word16 sharpFlag, /* i : formant sharpening flag */ + Word16 *gain_buf /*Q14*/ + ); + + //transition_dec_fx.c + void transition_dec_fx( + Decoder_State* st_fx, /* i/o: decoder state structure */ + const Word16 Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ + const Word16 L_frame, /* i : length of the frame */ + const Word16 i_subfr, /* i : subframe index */ + const Word16 tc_subfr, /* i : TC subframe index */ + Word16* Jopt_flag, /* i : joint optimization flag */ + Word16* exc, /* o : excitation signal */ + Word16* T0, /* o : close loop integer pitch */ + Word16* T0_frac, /* o : close loop fractional part of the pitch */ + Word16* T0_min, /* i/o: delta search min for sf 2 & 4 */ + Word16* T0_max, /* i/o: delta search max for sf 2 & 4 */ + Word16** pt_pitch, /* o : floating pitch values */ + Word16* position, /* i/o: first glottal impulse position in frame */ + Word16* bwe_exc, /* o : excitation for SWB TBE */ + Word16* Q_exc /*i/o : scaling of excitation */ + ); + + Word16 tc_classif_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + const Word16 L_frame /* i : length of the frame */ + ); + + //dec_ppp_fx.c + ivas_error decod_ppp_fx( + Decoder_State *st_fx, /* i/o: state structure */ + const Word16 Aq_fx[], /* i : 12k8 Lp coefficient */ + Word16 *pitch_buf_fx, /* i/o: fixed pitch values for each subframe */ + Word16 *exc_fx, /* i/o: current non-enhanced excitation */ + Word16 *exc2_fx, /* i/o: current enhanced excitation */ + Word16 bfi /* i : bad frame indicator */ + , Word16 *gain_buf /*Q14*/ + , Word16 *voice_factors, /* o : voicing factors */ + Word16 *bwe_exc_fx /* o : excitation for SWB TBE */ + ); + + //swb_bwe_dec_lr_fx.c + void swb_bwe_dec_lr_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + const Word32 L_m_core[], /* i : lowband synthesis */ + const Word16 QsL, /* i : Q value of m_core */ + Word32 L_m[], /* o : highband synthesis with lowband zeroed */ + const Word32 L_total_brate, /* i : total bitrate for selecting subband pattern */ + Word16 BANDS_fx, /* i : Number subbands/Frame */ + Word16 *band_start_fx, /* i : Band Start of each SB */ + Word16 *band_end_fx, /* i : Band end of each SB */ + Word32 *L_band_energy, /* i : Band energy of each SB : Qbe */ + Word16 Qbe, /* i : Q value of band energy */ + Word16 *p2a_flags_fx, /* i : HF tonal Indicator */ + const Word16 hqswb_clas_fx, /* i : class information */ + Word16 lowlength_fx, /* i : Lowband Length */ + Word16 highlength_fx, /* i : Highband Length */ + const Word16 har_bands_fx, /* i : Number of LF harmonic bands */ + Word16 *prev_frm_hfe2_fx, /* i/o: */ + Word16 *prev_stab_hfe2_fx, /* i/o: */ + Word16 band_width_fx[], /* i : subband bandwidth */ + const Word32 L_y2_ni[], /* i/o: Sparse filled corecoder */ + Word16 *ni_seed_fx /* i/o: random seed */ + ); + + //dec_acelp_tck_main_fx.c + Word16 dec_acelp_tcx_frame( + Decoder_State* st, /* i/o: decoder state structure */ + Word16* concealWholeFrame, /* i/o: concealment flag */ + Word16* pcmBuf, /* o : synthesis */ + Word16* bpf_noise_buf, /* i/o: BPF noise buffer */ + Word16* pcmbufFB, /* o : synthesis @output_FS */ + Word32 bwe_exc_extended[], /* i/o: bandwidth extended excitation */ + Word16* voice_factors, /* o : voicing factors */ + Word16 pitch_buf[] /* o : floating pitch for each subframe */ +#ifdef IVAS_CODE_CNG + , STEREO_CNG_DEC_HANDLE hStereoCng /* i : stereo CNG handle */ +#endif + ); + + //dec_LPD_fx.c + void decoder_LPD( + Word16 signal_out[], /* o : signal with LPD delay (7 subfrs) */ + Word16 signal_outFB[], /* o : synthesis @output_FS */ + Word16* total_nbbits, /* i/o: number of bits / decoded bits */ + Decoder_State* st, /* i/o: decoder memory state pointer */ + Word16* bpf_noise_buf, /* i/o: BPF noise buffer */ + Word16 bfi, /* i : BFI flag */ + Word16* bitsRead, /* o : number of read bits */ + Word16 param[], /* o : buffer of parameters */ + Word16* pitch_buf, /* i/o: floating pitch values for each subfr*/ + Word16* voice_factors, /* o : voicing factors */ + Word16* ptr_bwe_exc /* o : excitation for SWB TBE */ + ); + + //core_dec_switch_fx.c + void mode_switch_decoder_LPD(Decoder_State *st, Word16 bandwidth_in, Word32 bitrate, Word16 frame_size_index + ); + + + //ari_hm_dec.c + + int16_t DecodeIndex( + Decoder_State *st, + const int16_t Bandwidth, /* o : NB, 1: (S)WB */ + int16_t *PeriodicityIndex); + Word16 + DecodeIndex_fx( + Decoder_State *st, + Word16 Bandwidth, + Word16 *PeriodicityIndex); + void tcx_hm_decode( + const Word16 L_frame, /* i : number of spectral lines */ + Word32 env[], /* i/o: envelope shape (Q16) */ + const Word16 targetBits, /* i : target bit budget */ + const Word16 coder_type, /* i : GC/VC coder type */ + const Word16 prm_hm[], /* i : HM parameters */ + const Word16 LtpPitchLag, /* i : LTP pitch lag or -1 if none */ + Word16 *hm_bits /* o : bit consumption */ + ); + + //lsf_msvq_ma_dec_fx.c + Word16 lsf_msvq_ma_decprm(Decoder_State *st, Word16 *param_lpc); + + Word16 lsf_bctcvq_decprm( + Decoder_State * st, + Word16 *param_lpc + + ); + Word16 D_lsf_tcxlpc( + const Word16 indices[], /* (I) VQ indices */ + Word16 xsf_q[], /* (O) quantized xSF */ + Word16 xsf_q_ind[], /* (O) quantized xSF (w/o MA prediction) */ + Word16 narrowband, /* (I) narrowband flag */ + Word16 cdk, /* (I) codebook selector */ + Word16 mem_MA[] /* (I) MA memory */ + ); + + Word16 dec_lsf_tcxlpc( + Decoder_State *st, /* (I/O) Decoder state */ + Word16 **indices, /* (O) Ptr to VQ indices */ + Word16 narrowband, /* (I) narrowband flag */ + Word16 cdk /* (I) codebook selector */ + ); + + //lsf_msvq_ma_fx.c +void midlsf_dec( + const Word16 qlsf0[], /* i: quantized lsf coefficients (3Q12) */ + const Word16 qlsf1[], /* i: quantized lsf coefficients (3Q12) */ + const Word16 idx, /* i: codebook index */ + Word16 qlsf[], /* o: decoded lsf coefficients (3Q12) */ + const Word16 coder_type, + Word16 *mid_lsf_int, + const Word16 prev_bfi, + const Word16 safety_net +); + +Word16 lsf_ind_is_active( + const Word16 lsf_q_ind[], + const Word16 means[], + const Word16 narrowband, + const Word16 cdk + ); + + +// IGFSCFDecoder.c +void IGFSCFDecoderOpen( + IGFSCFDEC_INSTANCE_HANDLE hPublicData, /* i : handle to public data */ + H_IGF_INFO hIgfInfo, /* i : IGF info handle */ + const Word32 total_brate, + const Word16 bwidth, + const Word16 element_mode, + const Word16 rf_mode +); + +void IGFSCFDecoderReset( + IGFSCFDEC_INSTANCE_HANDLE hPublicData /* i/o: handle to public data */ +); + +void IGFSCFDecoderDecode( + IGFSCFDEC_INSTANCE_HANDLE hPublicData, /* i/o: handle to public data or NULL in case there was no instance created */ + Decoder_State* st, /* i/o: pointer to decoder state */ + int16_t* sfe, /* o : ptr to an array which will contain the decoded quantized coefficients */ + const Word16 igfGridIdx, /* i : igf grid index see declaration of IGF_GRID_IDX for details */ + const Word16 indepFlag /* i : if 1 on input the decoder will be forced to reset, + if 0 on input the decoder will be forced to encode without a reset */ +); + +//ari_dec_fx.c +Word16 ari_decode_overflow(Tastat *s); + +void ari_start_decoding_14bits( + Decoder_State *st, + Tastat *s +); + +Word16 ari_start_decoding_14bits_prm(const Word16 *ptr, Word16 bp, Tastat *s); + +Word16 ari_decode_14bits_s17_ext( + Decoder_State *st, + Tastat *s, + UWord16 const *cum_freq +); + +Word16 ari_decode_14bits_s27_ext( + Decoder_State *st, + Tastat *s, + UWord16 const *cum_freq +); + +Word16 ari_decode_14bits_bit_ext( + Decoder_State *st, + Tastat *s +); + +Word16 ari_decode_14bits_pow(Word16 *ptr, Word16 bp, Word16 bits, Word16 *res, Tastat *s, Word16 base); + +Word16 ari_decode_14bits_sign(Word16 *ptr, Word16 bp, Word16 bits, Word16 *res, Tastat *s); + +//dec_prm_fx.c +void dec_prm( + Word16 *coder_type, + Word16 param[], /* (o) : decoded parameters */ + Word16 param_lpc[], /* (o) : LPC parameters */ + Word16 *total_nbbits, /* i/o : number of bits / decoded bits */ + Decoder_State *st, + Word16 L_frame, + Word16 *bitsRead +); + +//ari_hm_fx.c + +void UnmapIndex( + Word16 PeriodicityIndex, + Word16 Bandwidth, + Word16 LtpPitchLag, + Word8 SmallerLags, + Word16 *FractionalResolution, + Word32 *Lag); + +void ConfigureContextHm( + Word16 NumCoeffs, /* (I) Number of coefficients */ + Word16 TargetBits, /* (I) Target bit budget (excl. Done flag) */ + Word16 PeriodicityIndex, /* (I) Pitch related index */ + Word16 LtpPitchLag, /* (I) TCX-LTP pitch in F.D. */ + CONTEXT_HM_CONFIG *hm_cfg /* (O) Context-based harmonic model configuration */ +); + +Word16 CountIndexBits( + Word16 Bandwidth, /* 0: NB, 1: (S)WB */ + Word16 PeriodicityIndex); + +int tcx_hm_render( + Word32 lag, /* i: pitch lag Q0 */ + Word16 fract_res, /* i: fractional resolution of the lag Q0 */ + Word16 p[] /* o: harmonic model Q13 */ +); + +void tcx_hm_modify_envelope( + Word16 gain, /* i: HM gain Q11 */ + Word32 lag, /* i: pitch lag Q0 */ + Word16 fract_res, /* i: fractional resolution of the lag Q0 */ + Word16 p[], /* i: harmonic model Q13 */ + Word32 env[], /* i/o: envelope Q16 */ + Word16 L_frame /* i: number of spectral lines Q0 */ +); + +//tns_base_dec_fx.c +#ifdef IVAS_CODE +void +#else +Word16 +#endif +ReadTnsData(STnsConfig const * pTnsConfig, + Decoder_State *st, + Word16 * pnBits, + Word16 * stream, + Word16 * pnSize); + +Word16 DecodeTnsData(STnsConfig const * pTnsConfig, + Word16 const * stream, + Word16 * pnSize, + STnsData * pTnsData); + +//parametr_bitmapping.c using ivas +void GetParameters( + ParamsBitMap const *paramsBitMap, + const int16_t nParams, + void const *pParameter, + int16_t **pStream, + int16_t *pnSize, + int16_t *pnBits); + +void SetParameters( + ParamsBitMap const *paramsBitMap, + const int16_t nParams, + void *pParameter, + const int16_t **pStream, + int16_t *pnSize); + +void WriteToBitstream( + ParamsBitMap const *paramsBitMap, + const int16_t nParams, + const int16_t **pStream, + int16_t *pnSize, + BSTR_ENC_HANDLE hBstr, + int16_t *pnBits); + +void ReadFromBitstream( + ParamsBitMap const *paramsBitMap, + const int16_t nArrayLength, + Decoder_State *st, + int16_t **pStream, + int16_t *pnSize); + +//igf_dec_fx.c +void IGFDecReadData(const IGF_DEC_INSTANCE_HANDLE hInstance, /**< in: | instance handle of IGF Deccoder */ + Decoder_State *st, /**< in: | decoder state */ + const Word16 igfGridIdx, /**< in: Q0 | in case of CELP->TCX switching, use 1.25 framelength */ + const Word16 isIndepFrame /**< in: Q0 | if 1: arith dec force reset, if 0: no reset */ +); + +void IGFDecReadLevel(const IGF_DEC_INSTANCE_HANDLE hInstance, /**< in: | instance handle of IGF Deccoder */ + Decoder_State *st, /**< in: | decoder state */ + const Word16 igfGridIdx, /**< in: Q0 | in case of CELP->TCX switching, use 1.25 framelength */ + const Word16 isIndepFrame /**< in: Q0 | if 1: arith dec force reset, if 0: no reset */ +); + +void IGFDecApplyMono(const IGF_DEC_INSTANCE_HANDLE hInstance, /**< in: | instance handle of IGF Decoder */ + Word32 *spectrum, /**< in/out: | MDCT spectrum */ + Word16 *spectrum_e, /**< in/out: | exponent of spectrum */ + const Word16 igfGridIdx, /**< in: | in case of CELP->TCX switching, use 1.25 framelength */ + Word16 bfi /**< in: | frame loss == 1, frame good == 0 */ + +); +void IGFDecSetMode( + const IGF_DEC_INSTANCE_HANDLE hIGFDec, /* o : instance handle of IGF Decoder */ + const Word32 total_brate, /* i : bitrate */ + const Word16 bwidth, /* i : audio bandwidth */ + const Word16 element_mode, /* i : IVAS element mode */ + const Word16 defaultStartLine, /* i : default start subband index */ + const Word16 defaultStopLine, /* i : default stop subband index */ + const Word16 rf_mode /* i : flag to signal the RF mode */ +); + +void IGFDecUpdateInfo(const IGF_DEC_INSTANCE_HANDLE hInstance, /**< in: | instance handle of IGF Decoder */ + const Word16 igfGridIdx /**< in: | IGF grid index */ +); + +void IGFDecCopyLPCFlatSpectrum(const IGF_DEC_INSTANCE_HANDLE hInstance, /**< in: | instance handle of IGF Decoder */ + const Word32 *pSpectrumFlat, /**< in: Q31 | LPC flattend spectrum from TCX dec */ + const Word16 pSpectrumFlat_exp, /**< in: | exponent of pSpectrumFlat */ + const Word16 igfGridIdx /**< in: Q0 | IGF grid index */ +); + +void IGFDecStoreTCX10SubFrameData(const IGF_DEC_INSTANCE_HANDLE hInstance, /**< in: | instance handle of IGF Decoder */ + const Word16 subFrameIdx /**< in: Q0 | index of subframe */ +); + +void IGFDecRestoreTCX10SubFrameData(const IGF_DEC_INSTANCE_HANDLE hInstance, /**< in: | instance handle of IGF Decoder */ + const Word16 subFrameIdx /**< in: Q0 | index of subframe */ +); + +void init_igf_dec( + IGF_DEC_INSTANCE_HANDLE hIGFDec /* i/o: IGF decoder handle */ +); + +//dlpc_avq_fx.c +Word16 dlpc_avq( + Word16 *index, /* (i) Quantization indices */ + Word16 *LSF_Q, /* (o) Quantized LSF vectors */ + Word16 numlpc, /* (i) Number of sets of lpc */ + Word32 sr_core +); +Word16 decode_lpc_avq( + Decoder_State* st, /* i/o: decoder state structure */ + const Word16 numlpc, /* i : Number of sets of lpc */ + Word16* param_lpc /* o : lpc parameters */ +#ifdef IVAS_CODE_AVQ_LPC + , const Word16 ch, /* i : channel */ + const Word16 element_mode, /* i : element mode */ + const Word16 sns_low_br_mode /* i : SNS low-bitrate mode */ +#endif +); + +//vlpc_1st_dec_fx.c +void vlpc_1st_dec( + Word16 index, /* i : codebook index */ + Word16 *lsfq); /* i/o: i:prediction o:quantized lsf */ + + +//vlpc_2st_dec_fx.c +void vlpc_2st_dec( + Word16 *lsfq, /* i/o: i:1st stage o:1st+2nd stage */ + Word16 *indx, /* i : index[] (4 bits per words) */ + Word16 mode, /* i : 0=abs, >0=rel */ + Word32 sr_core); + +//vlpc_2st_com_fx.c +void lsf_weight_2st(const Word16 *lsfq, /* i : quantized lsf coefficients (3Q12) */ + Word16 *w, /* o : weighting function (0Q15) */ + const Word16 mode /* i : operational mode */ +); + +//ACcontextMapping_fx.c + +/* Returns: index of next coefficient */ +Word16 get_next_coeff_mapped( + Word16 ii[2], /* i/o: coefficient indexes */ + Word16 *pp, /* o : peak(1)/hole(0) indicator */ + Word16 *idx, /* o : index in unmapped domain */ + CONTEXT_HM_CONFIG *hm_cfg /* i : HM configuration */ +); + +/* Returns: index of next coefficient */ +Word16 get_next_coeff_unmapped( + Word16 ii[2], /* i/o: coefficient indexes */ + Word16 *pp, /* o : peak(1)/hole(0) indicator */ + Word16 *idx, /* o : index in unmapped domain */ + CONTEXT_HM_CONFIG *hm_cfg /* i : HM configuration */ +); + +Word16 update_mixed_context(Word16 ctx, Word16 a); + + + +//ACcontextMapping_dec_fx.c + +typedef Word16(*get_next_coeff_function)( + Word16 ii[2], /* i/o: coefficient indexes */ + Word16 *pp, /* o : peak(1)/hole(0) indicator */ + Word16 *idx, /* o : index in unmapped domain */ + CONTEXT_HM_CONFIG *hm_cfg /* i : HM configuration */ + ); + +Word16 ACcontextMapping_decode2_no_mem_s17_LC( + Decoder_State *st,/* i/o: decoder state */ + Word16 *x, /* o: decoded spectrum */ + Word16 nt, /* i: size of spectrum */ + Word16 nbbits, /* i: bit budget */ + Word16 resQMaxBits, /* i: residual coding maximum bits*/ + CONTEXT_HM_CONFIG *hm_cfg /* i: context-based harmonic model configuration */ +); + +//core_dec_reconf_fx.c +void reconfig_decoder_LPD(Decoder_State *st, Word16 bits_frame, Word16 bandwidth_mode, Word32 bitrate, Word16 L_frame_old); + +//er_utils_fx.c +void minimumStatistics(Word16* noiseLevelMemory, /* Q15, internal state */ + Word16* noiseLevelIndex, /* Q0, internal state */ + Word16* currLevelIndex, /* Q0, internal state (circular buffer) */ + Word16* noiseEstimate, /* Q15, previous estimate of background noise */ + Word16* lastFrameLevel, /* Q15, level of the last frame */ + Word16 currentFrameLevel, /* Q15, level of the current frame */ + Word16* noiseLevelMemory_e, /* scaling factor for noiseLevelMemory */ + Word16 const noiseEstimate_e, /* exponent of noiseEstimate */ + Word16* new_noiseEstimate_e, /* new exponent of noise Estimate*/ + Word16* const lastFrameLevel_e, /* exponent of lastFrameLevel */ + Word16 currentFrameLevel_e); /* exponent of currentFrameLevel */ + + +Word16 getLevelSynDeemph( /*10Q5*/ + Word16 h1Init[], /* i: i value or vector to be processed */ /* Q15 */ + Word16 const A[], /* i: LPC coefficients */ /* Qx */ + Word16 const lpcorder, /* i: LPC order */ /* Q0 */ + Word16 const lenLpcExc, /* i: length of the LPC excitation buffer */ /* Q0 */ + Word16 const preemph_fac, /* i: preemphasis factor */ /* Q15 */ + Word16 const numLoops, /* i: number of loops */ /* Q0 */ + Word16 *Exp /* o: exponent of return value Q15 */ +); + +void genPlcFiltBWAdap( + Word32 const sr_core, /*mem_syn >rescaling done */ + , Word16 *pitch_buffer + , Word16 *voice_factors + , Word16 *bwe_exc +); + +//dec_ace_fx.c +void decoder_acelp( + Decoder_State *st, + Word16 prm[], /* i : parameters */ + Word16 A[], /* i : coefficients NxAz[M+1] */ + ACELP_config acelp_cfg, /* i : ACELP config */ + Word16 synth[], /* i/o: synth[-2*LFAC..L_DIV] Q0 */ + Word16 *pT, /* out: pitch for all subframe Q0 */ + Word16 *pgainT, /* out: pitch gain for all subfr 1Q14 */ + Word16 stab_fac, /* i : stability of isf */ + Word16 *pitch_buffer, /* out: pitch values for each subfr.*/ + Word16 *voice_factors, /* out: voicing factors */ + const Word16 LSF_Q_prediction,/* i : LSF prediction mode */ + Word16 *bwe_exc /* out: excitation for SWB TBE */ +); + +//d_gain2p.c +void decode_acelp_gains( + Word16 *code, + Word16 gains_mode, + Word16 mean_ener_code, + Word16 *gain_pit, + Word32 *gain_code, + Word16 **pt_indice, + Word16 *past_gpit, + Word32 *past_gcode, + Word16 *gain_inov, + Word16 L_subfr, + Word16 *code2, + Word32 *gain_code2 +); + +void d_gain_pred( + Word16 nrg_mode, /* i : NRG mode */ + Word16 *Es_pred, /* o : predicited scaled innovation energy */ + Word16 **pt_indice /* i/o: pointer to the buffer of indices */ +); +//acelp_core_dec_fx.c +ivas_error acelp_core_dec_fx( + Decoder_State* st_fx, /* i/o: decoder state structure */ + Word16 output[], /* o : synthesis @internal Fs */ + Word16 synth_out[], /* o : synthesis */ + Word16 save_hb_synth[], /* o : HB synthesis */ + Word32 bwe_exc_extended[], /* i/o: bandwidth extended excitation */ + Word16* voice_factors, /* o : voicing factors */ + Word16 old_syn_12k8_16k[], /* o : intermediate ACELP synthesis for SWB BWE */ + Word16 sharpFlag, + Word16 pitch_buf_fx[NB_SUBFR16k], /* o : floating pitch for each subframe */ + Word16* unbits, /* o : number of unused bits */ + Word16* sid_bw /* o : 0-NB/WB, 1-SWB SID */ + , STEREO_TD_DEC_DATA_HANDLE hStereoTD, /* i/o: TD stereo decoder handle */ + const Word16 tdm_lspQ_PCh[M], /* i : Q LSPs for primary channel */ + const Word16 tdm_lsfQ_PCh[M], /* i : Q LSFs for primary channel */ + const Word16 use_cldfb_for_dft, /* i : flag to use of CLDFB for DFT Stereo */ + const Word16 last_element_mode, /* i : last element mode */ + const Word32 last_element_brate, /* i : last element bitrate */ + const Word16 flag_sec_CNA, /* i : CNA flag for secondary channel */ + const Word16 nchan_out, /* i : number of output channels */ + STEREO_CNG_DEC_HANDLE hStereoCng, /* i : stereo CNG handle */ + const Word16 read_sid_info /* i : read SID info flag */ +); + +//evs_dec_fx.c +ivas_error evs_dec_fx( + Decoder_State *st_fx, /* i/o : Decoder state structure */ + Word16 output_sp[], /* o : output synthesis signal */ + frameMode_fx frameMode /* i : Decoder frame mode */ +); #endif \ No newline at end of file diff --git a/lib_com/re8_ppv_fx.c b/lib_com/re8_ppv_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..aa13af059677f33bebfb869b6dce1c7395692906 --- /dev/null +++ b/lib_com/re8_ppv_fx.c @@ -0,0 +1,194 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include "options.h" /* Compilation switches */ +#include "cnst.h" /* Common constants */ +#include "prot_fx1.h" /* Function prototypes */ +#include "prot_fx2.h" /* Function prototypes */ +#include "stl.h" + +/*-------------------------------------------------------------------* + * Local function prototypes + *-------------------------------------------------------------------*/ + +static void nearest_neighbor_2D8_fx( const Word32 x[], Word16 y[] ); +static Word32 compute_error_2D8_fx( const Word32 x[], const Word16 y[] ); + +/*--------------------------------------------------------------* + * RE8_PPV: + * + * NEAREST NEIGHBOR SEARCH IN INFINITE LATTICE RE8 + * the algorithm is based on the definition of RE8 as + * RE8 = (2D8) U (2D8+[1,1,1,1,1,1,1,1]) + * it applies the coset decoding of Sloane and Conway + * --------------------------------------------------------------*/ + +void re8_PPV_fx( + const Word32 x[], /* i : point in R^8Q15 */ + Word16 y[] /* o : point in RE8 (8-dimensional integer vector) */ +) +{ + Word16 i, y0[8]; + Word32 e0, e1, x1[8]; + + /*--------------------------------------------------------------* + * find the nearest neighbor y0 of x in 2D8 + *--------------------------------------------------------------*/ + nearest_neighbor_2D8_fx( x, y0 ); + + /*--------------------------------------------------------------* + * find the nearest neighbor y1 of x in 2D8+(1,...,1) (by coset decoding) + *--------------------------------------------------------------*/ + + FOR( i=0; i<8; i++ ) + { + x1[i] = L_sub(x[i], QR); + move32(); + } + nearest_neighbor_2D8_fx( x1, y ); + + FOR ( i = 0; i < 8; i++ ) + { + y[i] = add(y[i], 1); + move16(); + } + + /*--------------------------------------------------------------* + * compute e0=||x-y0||^2 and e1=||x-y1||^2 + *--------------------------------------------------------------*/ + + e0 = compute_error_2D8_fx( x, y0 ); + e1 = compute_error_2D8_fx( x, y ); + + + /*--------------------------------------------------------------* + * select best candidate y0 or y1 to minimize distortion + *--------------------------------------------------------------*/ + IF( LT_32(e0, e1)) + { + Copy( y0, y, 8 ); + } + + return; +} + + +/*--------------------------------------------------------------* + * Nearest_neighbor_2D8(x,y) + * + * NEAREST NEIGHBOR SEARCH IN INFINITE LATTICE 2D8 + * algorithm: nn_2D8(x) = 2*nn_D8(x/2) + * nn_D8 = decoding of Z^8 with Wagner rule + * (see Conway and Sloane's paper in IT-82) + --------------------------------------------------------------*/ + +static void nearest_neighbor_2D8_fx( + const Word32 x[], /* i : point in R^8 */ + Word16 y[] /* o : point in 2D8 (8-dimensional integer vector) */ +) +{ + Word16 i,j; + Word16 sum, tmp16, tmp16b; + Word32 s, e, em; + + /*--------------------------------------------------------------* + * round x into 2Z^8 i.e. compute y=(y1,...,y8) such that yi = 2[xi/2] + * where [.] is the nearest integer operator + * in the mean time, compute sum = y1+...+y8 + *--------------------------------------------------------------*/ + sum = 0; + move16(); + + FOR( i=0; i<8; i++ ) + { + /* round to ..., -2, 0, 2, ... ([-1..1[ --> 0) */ + tmp16 = round_fx(L_add(x[i], L_shr(x[i], 31))); + y[i] = shl(tmp16, 1); + move16(); + /* sum += y[i] */ + sum = add(sum, y[i]); + } + + /*--------------------------------------------------------------* + * check if y1+...+y8 is a multiple of 4 + * if not, y is not round xj in the wrong way where j is defined by + * j = arg max_i | xi -yi| + * (this is called the Wagner rule) + *--------------------------------------------------------------*/ + IF( s_and(sum, 2) != 0 ) + { + /* find j = arg max_i | xi -yi| */ + em = L_deposit_l(0); + j = 0; + move16(); + + FOR( i=0; i<8; i++ ) + { + /* compute ei = xi-yi */ + /* e[i]=x[i]-y[i] */ + e = L_msu(x[i], y[i], QR/2); + + /* compute |ei| = | xi-yi | */ + s = L_abs(e); + + /* check if |ei| is maximal, if so, set j=i */ + if( LT_32(em, s)) + { + j = i; + move16(); + } + em = L_max(s, em); + } + + /* round xj in the "wrong way" */ + e = L_msu(x[j], y[j], QR/2); + tmp16 = extract_h(e); + tmp16b = add(y[j], 2); + + if( tmp16 < 0 ) + { + tmp16b = sub(tmp16b, 2+2); + } + y[j] = tmp16b; + move16(); + } + + return; +} + + +/*--------------------------------------------------------------* + * Compute_error_2D8(x,y) + * + * Compute mean square error between input vector and + * (quantized) point in 2D8. + --------------------------------------------------------------*/ + +static Word32 compute_error_2D8_fx( /* o : mean squared error */ + const Word32 x[], /* i : input vector */ + const Word16 y[] /* i : point in 2D8 (8-dimensional integer vector) */ +) +{ + Word16 i, hi, lo; + Word32 err, Ltmp; + + err = L_deposit_l(0); + FOR( i=0; i<8; i++ ) + { + /*tmp = x[i]-y[i];*/ + Ltmp = L_msu(x[i], y[i], 16384); + hi = extract_h(L_shl(Ltmp, 1)); + lo = extract_l(L_msu(Ltmp, hi, 16384)); + + Ltmp = L_mult(hi, hi); + Ltmp = L_shl(Ltmp, 14); + Ltmp = L_mac(Ltmp, hi, lo); + Ltmp = L_mac0(Ltmp, mult(lo, lo), 1); + + /* err+=tmp*tmp */ + err = L_add(Ltmp, err); + } + + return( err ); +} diff --git a/lib_com/re8_util_fx.c b/lib_com/re8_util_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..012441be69dba9f9496f634b0b030449990a2d15 --- /dev/null +++ b/lib_com/re8_util_fx.c @@ -0,0 +1,388 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include +#include "options.h" /* Compilation switches */ +#include "cnst.h" /* Common constants */ +#include "rom_com.h" /* Static table prototypes */ +#include "prot_fx1.h" /* Function prototypes */ +#include "prot_fx2.h" /* Function prototypes */ + + +/*-------------------------------------------------------------------* + * Local function prototypes + *-------------------------------------------------------------------*/ + +static Word16 re8_identify_absolute_leader_fx( const Word16 y[] ); +static void re8_coord_fx( const Word16 *y, Word16 *k) ; + + +/*----------------------------------------------------------------* + * re8_vor_fx() + * + * MULTI-RATE RE8 INDEXING BY VORONOI EXTENSION + *----------------------------------------------------------------*/ +void re8_vor_fx( + const Word16 y[], /* i : point in RE8 (8-dimensional integer vector) */ + Word16 *n, /* o : codebook number n=0,2,3,4,... (scalar integer) */ + Word16 k[], /* o : Voronoi index (integer vector of dimension 8) used only if n>4*/ + Word16 c[], /* o : codevector in Q0, Q2, Q3, or Q4 if n<=4, y=c */ + Word16 *ka /* o : identifier of absolute leader (to index c) */ +) +{ + Word16 i, r, iter, ka_tmp, n_tmp, mask; + Word16 k_tmp[8], v[8], c_tmp[8], k_mod[8]; + Word32 Ltmp, Lsphere; + + /*----------------------------------------------------------------* + * verify if y is in Q0, Q2, Q3 or Q4 + * (a fast search is used here: + * the codebooks Q0, Q2, Q3 or Q4 are specified in terms of RE8 absolute leaders + * (see FORinstance Xie and Adoul's paper in ICASSP 96) + * - a unique code identifying the absolute leader related to y is computed + * in re8_identify_absolute_leader() + * this code is searched FORin a pre-defined list which specifies Q0, Q2, Q3 or Q4) + * the absolute leader is identified by ka + * - a translation table maps ka to the codebook number n) + *----------------------------------------------------------------*/ + *ka = re8_identify_absolute_leader_fx( y ); + move16(); + + /*----------------------------------------------------------------* + * compute codebook number n of Qn (by table look-up) + * at this stage, n=0,2,3,4 or out=100 + *----------------------------------------------------------------*/ + *n = Da_nq[*ka]; + move16(); + + /*----------------------------------------------------------------* + * decompose y into : + * (if n<=4:) + * y = c where c is in Q0, Q2, Q3 or Q4 + * or + * (if n>4:) + * y = m c + v where c is in Q3 or Q4, v is a Voronoi codevector + * m=2^r (r integer >=2) + * + * in the latter case (if n>4), as a side-product, compute the (Voronoi) index k[] of v + * and replace n by n = n' + 2r where n' = 3 or 4 (c is in Qn') and r is defined above + *----------------------------------------------------------------*/ + + IF( LE_16(*n, 4)) + { + Copy( y, c, 8 ); + } + ELSE + { + /*------------------------------------------------------------* + * initialize r and m=2^r based on || y ||^2/8 + *------------------------------------------------------------*/ + Ltmp = L_mult(y[0], y[0]); + FOR( i = 1; i < 8; i++ ) + { + Ltmp = L_mac( Ltmp, y[i], y[i]); + } + + Lsphere = L_shr(Ltmp, 5+1); /* *0.125*0.25 / 2 to remove L_mac effect */ + + r = 1; + move16(); + FOR( ; Lsphere > 11; Lsphere >>= 2 ) + { + r = add(r, 1); + } + /*------------------------------------------------------------* + * compute the coordinates of y in the RE8 basis + *------------------------------------------------------------*/ + re8_coord_fx( y, k_mod ); + + /*------------------------------------------------------------* + * compute m and the mask needed for modulo m (for Voronoi coding) + *------------------------------------------------------------*/ + mask = sub(shl(1, r), 1); /* 0x0..011...1 */ + + /*------------------------------------------------------------* + * find the minimal value of r (or equivalently of m) in 2 iterations + *------------------------------------------------------------*/ + + FOR( iter=0; iter<2; iter++ ) + { + /*--------------------------------------------------------* + * compute v such that y is in m RE_8 +v (by Voronoi coding) + *--------------------------------------------------------*/ + FOR( i=0; i<8; i++ ) + { + k_tmp[i] = s_and( k_mod[i], mask); + move16(); + } + + re8_k2y_fx( k_tmp, r, v ); + + /*--------------------------------------------------------* + * compute c = (y-v)/m + * (y is in RE8, c is also in RE8 by definition of v) + *--------------------------------------------------------*/ + + FOR( i=0; i<8; i++ ) + { + c_tmp[i] = shr(sub(y[i], v[i]), r); + move16(); + } + + /*--------------------------------------------------------* + * verify if c_tmp is in Q2, Q3 or Q4 + *--------------------------------------------------------*/ + ka_tmp = re8_identify_absolute_leader_fx( c_tmp ); + + /*--------------------------------------------------------* + * at this stage, n_tmp=2,3,4 or out = 100 -- n=0 is not possible + *--------------------------------------------------------*/ + n_tmp = Da_nq[ka_tmp]; + move16(); + + IF( GT_16(n_tmp, 4)) + { + /*--------------------------------------------------------* + * if c is not in Q2, Q3, or Q4 (i.e. n_tmp>4), use m = 2^(r+1) instead of 2^r + *--------------------------------------------------------*/ + r = add(r, 1); + mask = add(shl(mask, 1), 1); /* mask = m-1 <- this is less complex */ + } + ELSE + { + /*--------------------------------------------------------* + * c is in Q2, Q3, or Q4 -> the decomposition of y as y = m c + v is valid + * + * since Q2 is a subset of Q3, indicate n=3 instead of n=2 (this is because + * for n>4, n=n'+2r with n'=3 or 4, so n'=2 is not valid) + *--------------------------------------------------------*/ + n_tmp = s_max(n_tmp, 3); + + /*--------------------------------------------------------* + * save current values into ka, n, k and c + *--------------------------------------------------------*/ + *ka = ka_tmp; + move16(); + *n = add(n_tmp, shl(r, 1)); + move16(); + Copy( k_tmp, k, 8 ); + Copy( c_tmp, c, 8 ); + + /*--------------------------------------------------------* + * try m = 2^(r-1) instead of 2^r to be sure that m is minimal + *--------------------------------------------------------*/ + r = sub(r, 1); + mask = shr(mask, 1); + } + } + } + + return; +} + + +/*------------------------------------------------------------------------- + * re8_k2y_fx() + * + * VORONOI INDEXING (INDEX DECODING) k -> y + -------------------------------------------------------------------------*/ +void re8_k2y_fx( + const Word16 *k, /* i : Voronoi index k[0..7] */ + const Word16 m, /* i : Voronoi modulo (m = 2^r = 1<=2) */ + Word16 *y /* o : 8-dimensional point y[0..7] in RE8 */ +) +{ + Word16 i, v[8], *ptr1, *ptr2, m_tmp, mm; + Word32 ytp[8], z[8], Ltmp, Lsum ; + + /*---------------------------------------------------------------* + * compute y = k M and z=(y-a)/m, where + * M = [4 ] + * [2 2 ] + * [| \ ] + * [2 2 ] + * [1 1 _ 1 1] + * a=(2,0,...,0) + *---------------------------------------------------------------*/ + m_tmp = sub(15, m); + + Lsum = L_deposit_l(k[7]); + ytp[7] = Lsum; + move32(); + z[7] = L_shl(Lsum, m_tmp); + move32(); /* (int)(floor(y[7]*QR+0.5))>>m */ + + FOR( i=6; i>=1; i-- ) + { + Ltmp = L_deposit_l( shl(k[i],1) ); + Lsum = L_add (Lsum, Ltmp); + ytp[i] = L_add(ytp[7], Ltmp); + move32(); + z[i] = L_shl(ytp[i], m_tmp); + move32(); /* (int)(floor(y[7]*QR+0.5))>>m */ + } + + Lsum = L_add( Lsum, L_deposit_l(shl(k[0],2) )); + ytp[0] = Lsum; + move32(); + z[0] = L_shl(L_sub(Lsum, 2), m_tmp); + move32(); /* (int)(floor(y[7]*QR+0.5))>>m */ + + /*---------------------------------------------------------------* + * find nearest neighbor v of z in infinite RE8 + *---------------------------------------------------------------*/ + re8_PPV_fx( z, v ); + + /*---------------------------------------------------------------* + * compute y -= m v + *---------------------------------------------------------------*/ + ptr1=y; + ptr2=v; + + mm = shr(shl(1, m), 1); /* shr to remove effect of L_mult in L_msu */ + + FOR( i=0; i<8; i++ ) + { + Ltmp = L_msu(ytp[i], *ptr2++, mm); + *ptr1++ = extract_l(Ltmp); + } + + return; +} + + +/*-----------------------------------------------------------------------* + * re8_identify_absolute_leader: + * + * IDENTIFY THE ABSOLUTE LEADER RELATED TO y USING A PRE-DEFINED TABLE WHICH + * SPECIFIES THE CODEBOOKS Q0, Q2, Q3 and Q4 + -----------------------------------------------------------------------*/ + +static Word16 re8_identify_absolute_leader_fx( /* o : integer indicating if y if in Q0, Q2, Q3 or Q4 (or if y is an outlier) */ + const Word16 y[] /* i : point in RE8 (8-dimensional integer vector) */ +) +{ + Word16 i,s,id,nb,pos,ka, tmp16; + Word32 Ltmp, Ls; + Word32 C; + const Word16 *ptr; + + /*-----------------------------------------------------------------------* + * compute the RE8 shell number s = (y1^2+...+y8^2)/8 and C=(y1^2, ..., y8^2) + *-----------------------------------------------------------------------*/ + Ls = L_mult(y[0], y[0]); + FOR( i = 1; i < 8; i++ ) + { + Ls = L_mac( Ls, y[i], y[i]); + } + s = extract_h(L_shl(Ls, 16-(3+1))); /* s can saturate here */ + + /*-----------------------------------------------------------------------* + * compute the index 0 <= ka <= NB_LEADER+1 which identifies an absolute leader of Q0, Q2, Q3 or Q4 + * + * by default, ka=index of last element of the table (to indicate an outlier) + *-----------------------------------------------------------------------*/ + /*-------------------------------------------------------------------* + * if s=0, y=0 i.e. y is in Q0 -> ka=index of element indicating Q0 + *-------------------------------------------------------------------*/ + ka = NB_LEADER; + move16(); + IF( s != 0 ) + { + ka = NB_LEADER+1; + move16(); + /*-------------------------------------------------------------------* + * the maximal value of s for y in Q0, Q2, Q3 or Q4 is NB_SPHERE + * if s> NB_SPHERE, y is an outlier (the value of ka is set correctly) + *-------------------------------------------------------------------*/ + IF( LE_16(s, NB_SPHERE)) + { + /*---------------------------------------------------------------* + * compute the unique identifier id of the absolute leader related to y: + * s = (y1^4 + ... + y8^4)/8 + *---------------------------------------------------------------*/ + C = L_mult(y[0], y[0]); + tmp16 = extract_h(L_shl(C, 16-1)); + Ltmp = L_mult(tmp16, tmp16); + FOR( i=1; i<8; i++ ) + { + C = L_mult(y[i], y[i]); + tmp16 = extract_h(L_shl(C, 16-1)); + Ltmp = L_mac(Ltmp, tmp16, tmp16); + } + id = extract_h(L_shl(Ltmp, 16-(3+1))); /* id can saturate to 8192 */ + + /*---------------------------------------------------------------* + * search for id in table Da_id + * (containing all possible values of id if y is in Q2, Q3 or Q4) + * this search is focused based on the shell number s so that + * only the id's related to the shell of number s are checked + *---------------------------------------------------------------*/ + + nb = Da_nb[s - 1]; /* get the number of absolute leaders used on the shell of number s */ + pos = Da_pos[s - 1]; /* get the position of the first absolute leader of shell s in Da_id */ + move16(); + move16(); + + ptr = &Da_id[pos]; + move16(); + FOR( i=0; i=1; i-- ) + { + /* apply factor 2/4 from M^-1 */ + k[i] = shr(sub(y[i], tmp), 1); + move16(); + sum = sub(sum, y[i]); + } + /* apply factor 1/4 from M^-1 */ + k[0]= shr(add(y[0], sum), 2); + move16(); + + return; +} diff --git a/lib_com/recovernorm_fx.c b/lib_com/recovernorm_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..bcce460e36faf6f6408fb8a1b84a18227f9e6ea5 --- /dev/null +++ b/lib_com/recovernorm_fx.c @@ -0,0 +1,62 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ +#include +#include "options.h" /* Compilation switches */ +#include "prot_fx1.h" /* Function prototypes */ +#include "prot_fx2.h" /* Function prototypes */ +#include "cnst.h" /* Common constants */ +#include "rom_com.h" /* Static table prototypes */ + +/*--------------------------------------------------------------------------* + * recovernorm_fx() + * + * Recover reordered quantization indices and norms + *--------------------------------------------------------------------------*/ + +void recovernorm_fx( + const Word16 *idxbuf, /* i : reordered quantization indices */ + Word16 *ynrm, /* o : recovered quantization indices */ + Word16 *normqlg2, /* o : recovered quantized norms */ + const Word16 nb_sfm /* i : number of SFMs */ +) +{ + Word16 i,j,k; + const Word16 *order = NULL; + move16(); + + SWITCH (nb_sfm) + { + case NB_SFM: + order = norm_order_48; + move16(); + BREAK; + case SFM_N_SWB: + order = norm_order_32; + move16(); + BREAK; + case SFM_N_WB: + order = norm_order_16; + move16(); + BREAK; + default: + order = norm_order_48; + move16(); + BREAK; + } + + FOR (i = 0; i < nb_sfm; i++) + { + j = order[i]; + move16(); + k = idxbuf[i]; + move16(); + ynrm[j] = k; + move16(); + normqlg2[j] = dicnlg2[k]; + move16(); + } + + return; +} + diff --git a/lib_com/rom_basop_util.c b/lib_com/rom_basop_util.c index e6b63e54a7f7c337b9a47d1f2c10d594516f4b11..c523120ca61053e5ddb1432b4a8e3947de1eecf3 100644 --- a/lib_com/rom_basop_util.c +++ b/lib_com/rom_basop_util.c @@ -814,16 +814,3 @@ const PWord16* getSineWindowTable(Word16 length) return p; } - -const Word16 InvIntTable[65] = -{ - 0x7FFF, - 0x7FFF, 0x4000, 0x2AAB, 0x2000, 0x199A, 0x1555, 0x1249, 0x1000, - 0x0E39, 0x0CCD, 0x0BA3, 0x0AAB, 0x09D9, 0x0925, 0x0889, 0x0800, - 0x0788, 0x071C, 0x06BD, 0x0666, 0x0618, 0x05D1, 0x0591, 0x0555, - 0x051F, 0x04EC, 0x04BE, 0x0492, 0x046A, 0x0444, 0x0421, 0x0400, - 0x03E1, 0x03C4, 0x03A8, 0x038E, 0x0376, 0x035E, 0x0348, 0x0333, - 0x031F, 0x030C, 0x02FA, 0x02E9, 0x02D8, 0x02C8, 0x02B9, 0x02AB, - 0x029D, 0x028F, 0x0283, 0x0276, 0x026A, 0x025F, 0x0254, 0x0249, - 0x023F, 0x0235, 0x022B, 0x0222, 0x0219, 0x0211, 0x0208, 0x0200 -}; \ No newline at end of file diff --git a/lib_com/rom_basop_util.h b/lib_com/rom_basop_util.h index 188af401324c4fedbb7a2ed8e5dba92874bcf3ba..18c4bf70114336324879b7ae986a3594e8b89233 100644 --- a/lib_com/rom_basop_util.h +++ b/lib_com/rom_basop_util.h @@ -51,6 +51,4 @@ extern const PWord16 SineTable320[161]; void BASOP_getTables(const PWord16 **ptwiddle, const PWord16 **sin_twiddle, Word16 *sin_step, Word16 length); const PWord16* getSineWindowTable(Word16 length); -extern const Word16 InvIntTable[65]; - #endif diff --git a/lib_com/rom_com.c b/lib_com/rom_com.c index ff45696775643f7c588b2d0474aafc8a64bd299b..c5fa590b446e7a0f8fc9417678b5653edf6dfc8e 100644 --- a/lib_com/rom_com.c +++ b/lib_com/rom_com.c @@ -48,6 +48,7 @@ /*----------------------------------------------------------------------------------* * Table of bitrates *----------------------------------------------------------------------------------*/ +#define W16(x) ((Word16)x) const int32_t brate_tbl[SIZE_BRATE_TBL] = { @@ -463,7 +464,12 @@ const uint8_t ACELP_BPF_MODE[RATE_MODE_MAX][BANDWIDTH_MODE_MAX][ACELP_MODE_MAX+R /* BPF bits */ const uint8_t ACELP_BPF_BITS[3] = { 0, 0, 2 }; - +const Word16 ACELP_CDK_BITS[ACELP_FIXED_CDK_NB] = +{ + 7, 10, 12, 15, 17, 20, 24, 26, 28, 30, 32, 34, 36, 40, 43, 46, + 47, 49, 50, 53, 55, 56, 58, 59, 61, 62, 65, 68, 70, 73, 75, 78, 80, 83, + 85, 87, 89, 92, 94, 96, 98 +}; /*----------------------------------------------------------------------------------* * Perceptual critical bands @@ -481,7 +487,12 @@ const float crit_bins_corr[CRIT_NOIS_BAND] = 0.9f, 0.9f, 0.85f, 0.8f, 0.775f, 0.75f, 0.725f, 0.7f, 0.675f, 0.65f, 0.625f, 0.60f, 0.6f, 0.6f, 0.6f, 0.6f, 0.6f, 0.6f, 0.6f, 0.6f, 0.6f, 0.6f, 0.6f }; - +const Word16 crit_bins_corr_fx[CRIT_NOIS_BAND] = +{ + /*.9f, .9f, .85f, .8f, .775f, .75f, .725f , .7f , .675f, .65f, .625f , .60f, .6f, .6f, .6f, .6f, .6f, .6f, .6f, .6f, .6f, .6f, .6f*/ + 29491, 29491, 27853, 26214, 25395, 24576, 23577 , 22938, 22118, 21299, 20480, + 19661, 19661, 19661, 19661, 19661, 19661, 19661, 19661, 19661, 19661, 19661, 19661 +}; const int16_t crit_bins[CRIT_NOIS_BAND] = { 4, 4, 4, 4, 4, 5, 6, 6, 6, 8, 8, 10, 11, 13, 15, 18, 22, 16, 16, 20, 20, 20, 16 @@ -492,7 +503,11 @@ const float crit_bands_loc[CRIT_NOIS_BAND] = 100.0f, 200.0f, 300.0f, 400.0f, 510.0f, 630.0f, 770.0f, 920.0f, 1080.0f, 1270.0f, 1480.0f, 1720.0f, 2000.0f, 2320.0f, 2700.0f, 3150.0f, 3700.0f, 4100.0f, 4500.0f, 5000.0f, 5500.0f, 6000.0f, 6375.0f }; - +const Word16 crit_bands_loc_fx[CRIT_NOIS_BAND] = +{ + 100, 200, 300, 400, 510, 630, 770, 920, 1080, 1270, 1480, 1720, + 2000, 2320, 2700, 3150, 3700, 4100, 4500, 5000, 5500, 6000, 6375 +}; const float inv_tbl[130] = { 0.0f, /* unused */ @@ -554,29 +569,6 @@ const Word16 inv_tbl_fx[146] = 228, 226 }; -const Word32 dicn_fx[40] = /* Q=14 */ -{ - 2147483647, 1518500224, - 1073741824, 759250112, - 536870912, 379625056, - 268435456, 189812528, - 134217728, 94906264, - 67108864, 47453132, - 33554432, 23726566, - 16777216, 11863283, - 8388608, 5931642, - 4194304, 2965821, - 2097152, 1482910, - 1048576, 741455, - 524288, 370728, - 262144, 185364, - 131072, 92682, - 65536, 46341, - 32768, 23170, - 16384, 11585, - 8192, 5793, - 4096, 2896 -}; const Word16 hvq_bwe_fac_fx[16] = /* Q15 */ { @@ -656,8 +648,16 @@ const float mfreq_loc_LD[] = { 100.0f, 200.0f, 300.0f, 400.0f, 510.0f, 630.0f, 7 1720.0f, 2000.0f, 2320.0f, 2700.0f, 3150.0f, 3700.0f, 4400.0f, 5300.0f, (6400.0f-BIN_16kdct) }; +const Word16 mfreq_loc_LD_fx[] = { 100, 200, 300, 400, 510, 630, 770, 920, 1080, 1270, 1480, + 1720, 2000, 2320, 2700, 3150, 3700, 4400, 5300, (6400 - BIN_16kdct_fx) +}; + const int16_t mfreq_bindiv_LD[] = {10, 10, 10, 10, 11, 12, 14, 15, 16, 19, 21, 24, 28, 32, 38, 45, 55, 70, 90, 110}; const float sc_qnoise[] = {0.1f,0.1f,0.1f,0.1f,0.1f,0.1f,0.09091f,0.09091f,0.09091f,0.09091f,0.09091f,0.09091f,0.09091f,0.09091f,0.09091f,0.06667f,0.06667f,0.06667f,0.06667f,0.06667f}; +const Word16 sc_qnoise_fx[] = { 3277, 3277, 3277, 3277, 3277, 3277, 2979, 2979, 2979, 2979, 2979, 2979, 2979, 2979, 2979, 2185, 2185, 2185, 2185, 2185 }; +const Word16 inv_mfreq_bindiv_LD_fx[] = { 3277, 3277, 3277, 3277, 2979, 2731, 2341, 2185, 2048, 1725, 1560, 1365, 1170, 1024, 862, 728, 596, 468, 364, 298 }; /*Q15 */ + +const Word16 inv_mfreq_bindiv_LD_M1_fx[] = { 3641, 3641, 3641, 3641, 3277, 2979, 2521, 2341, 2185, 1820, 1638, 1425, 1214, 1057, 886, 745, 607, 475, 368, 301 }; /*Q15 */ const float post_dct_wind[OFFSET2] = { @@ -686,9 +686,39 @@ const float post_dct_wind[OFFSET2] = 0.016078f, 0.014080f, 0.012212f, 0.010476f, 0.008872f, 0.007400f, 0.006060f, 0.004853f, 0.003780f, 0.002840f, 0.002034f, 0.001362f, 0.000824f, 0.000420f, 0.000151f, 0.000017f }; +const Word16 post_dct_wind_fx[OFFSET2] = /*Q15 */ +{ + 32767, 32766, 32759, 32748, 32733, 32713, 32689, 32660, + 32627, 32590, 32548, 32502, 32452, 32397, 32338, 32274, + 32207, 32135, 32059, 31979, 31894, 31805, 31712, 31615, + 31514, 31409, 31300, 31187, 31070, 30949, 30823, 30695, + 30562, 30425, 30285, 30141, 29993, 29841, 29686, 29527, + 29365, 29200, 29030, 28858, 28682, 28503, 28320, 28134, + 27945, 27753, 27558, 27360, 27159, 26955, 26749, 26539, + 26327, 26112, 25894, 25674, 25452, 25226, 24999, 24769, + 24537, 24303, 24067, 23828, 23588, 23345, 23101, 22855, + 22607, 22358, 22107, 21854, 21600, 21345, 21088, 20830, + 20570, 20310, 20049, 19786, 19523, 19258, 18993, 18728, + 18461, 18195, 17927, 17659, 17391, 17123, 16854, 16586, + 16317, 16048, 15779, 15511, 15243, 14975, 14707, 14440, + 14173, 13907, 13642, 13377, 13114, 12851, 12589, 12328, + 12068, 11809, 11552, 11296, 11041, 10787, 10536, 10285, + 10037, 9790, 9545, 9301, 9060, 8820, 8583, 8348, + 8115, 7884, 7655, 7429, 7205, 6983, 6765, 6548, + 6335, 6124, 5916, 5710, 5508, 5308, 5112, 4918, + 4728, 4540, 4356, 4175, 3998, 3824, 3653, 3485, + 3321, 3161, 3004, 2851, 2701, 2555, 2413, 2274, + 2139, 2009, 1882, 1758, 1639, 1524, 1413, 1306, + 1203, 1104, 1009, 918, 831, 749, 671, 597, + 527, 461, 400, 343, 291, 242, 199, 159, + 124, 93, 67, 45, 27, 14, 5, 1 +}; const float MAX_SNR_SNR1_tab[MBANDS_GN_LD] = { 1.026316f, 1.026316f, 1.026316f, 1.026316f, 1.026316f, 1.026316f, 1.026316f, 1.026316f, 1.026316f, 1.026316f, 1.026316f, 1.026316f, 1.026316f, 1.026316f, 1.026316f, 1.02631627f, 1.043478f, 1.043478f, 1.043478f, 1.043478f}; const float INV_MAX_SNR_tab[MBANDS_GN_LD] = { .026316f, .026316f, .026316f, .026316f, .026316f, .026316f, .026316f, .026316f, .026316f, .026316f, .026316f, .026316f, .026316f, .026316f, .026316f, .026316f, .043478f, .043478f, .043478f, .043478f}; +const Word16 MAX_SNR_SNR1_tab_FX[MBANDS_GN_LD] = { 16815, 16815, 16815, 16815, 16815, 16815, 16815, 16815, 16815, 16815, 16815, 16815, 16815, 16815, 16815, 16815, 17096, 17096, 17096, 17096 }; + +const Word16 INV_MAX_SNR_tab_FX[MBANDS_GN_LD] = { 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 1425, 1425, 1425, 1425 }; const float wind_sss[LEN_WIN_SSS] = /* window for subsampling */ { @@ -877,6 +907,103 @@ const float LP_assym_window_16k[L_LP_16k] = 0.084104f, 0.083017f, 0.082096f, 0.081342f, 0.080755f, 0.080336f, 0.080084f, 0.080000f }; +const Word16 Assym_window_W16fx[L_LP] = /*Q15*/ +{ + 2621, 2624, 2630, 2640, 2655, 2674, 2698, 2725, + 2757, 2792, 2833, 2877, 2925, 2978, 3034, 3095, + 3160, 3229, 3302, 3379, 3460, 3545, 3634, 3727, + 3824, 3925, 4029, 4138, 4250, 4366, 4486, 4609, + 4737, 4867, 5002, 5140, 5281, 5426, 5575, 5727, + 5882, 6040, 6202, 6367, 6535, 6707, 6881, 7059, + 7239, 7422, 7609, 7798, 7990, 8184, 8382, 8581, + 8784, 8989, 9196, 9406, 9618, 9832, 10049, 10268, + 10489, 10711, 10936, 11163, 11391, 11622, 11854, 12087, + 12322, 12559, 12797, 13037, 13278, 13520, 13763, 14007, + 14253, 14499, 14746, 14994, 15243, 15493, 15743, 15994, + 16245, 16496, 16748, 17000, 17253, 17505, 17758, 18010, + 18263, 18515, 18767, 19019, 19270, 19521, 19772, 20022, + 20271, 20519, 20767, 21014, 21260, 21504, 21748, 21991, + 22232, 22473, 22711, 22949, 23185, 23419, 23652, 23883, + 24113, 24340, 24566, 24790, 25012, 25231, 25449, 25664, + 25878, 26089, 26297, 26503, 26707, 26908, 27107, 27303, + 27496, 27687, 27874, 28059, 28241, 28420, 28596, 28769, + 28939, 29105, 29269, 29429, 29586, 29739, 29889, 30036, + 30179, 30319, 30455, 30588, 30717, 30842, 30964, 31082, + 31196, 31306, 31413, 31516, 31615, 31709, 31800, 31888, + 31971, 32050, 32125, 32196, 32263, 32325, 32384, 32439, + 32489, 32535, 32577, 32615, 32649, 32679, 32704, 32725, + 32742, 32755, 32763, 32767, 32767, 32758, 32741, 32715, + 32681, 32638, 32587, 32527, 32458, 32381, 32296, 32203, + 32101, 31991, 31873, 31746, 31612, 31470, 31320, 31162, + 30996, 30823, 30642, 30454, 30259, 30056, 29847, 29630, + 29407, 29177, 28940, 28697, 28448, 28193, 27931, 27664, + 27391, 27113, 26829, 26540, 26246, 25947, 25643, 25335, + 25022, 24706, 24385, 24060, 23732, 23401, 23066, 22728, + 22387, 22043, 21697, 21349, 20999, 20646, 20292, 19937, + 19580, 19223, 18864, 18505, 18145, 17785, 17425, 17065, + 16705, 16346, 15988, 15631, 15275, 14920, 14567, 14215, + 13866, 13519, 13174, 12832, 12492, 12156, 11823, 11493, + 11166, 10844, 10525, 10210, 9900, 9594, 9292, 8996, + 8704, 8418, 8137, 7861, 7591, 7327, 7068, 6816, + 6570, 6330, 6097, 5870, 5650, 5437, 5231, 5032, + 4840, 4656, 4479, 4310, 4148, 3994, 3848, 3709, + 3579, 3457, 3343, 3237, 3139, 3050, 2969, 2896, + 2832, 2776, 2729, 2690, 2660, 2639, 2626, 2621 +}; + +const Word16 assym_window_16k_fx[L_LP_16k] = /*Q15*/ +{ + 2621, 2623, 2627, 2634, 2643, 2655, 2670, 2688, + 2708, 2731, 2757, 2785, 2816, 2849, 2886, 2925, + 2966, 3011, 3058, 3107, 3159, 3214, 3271, 3331, + 3394, 3459, 3527, 3597, 3670, 3745, 3823, 3903, + 3985, 4071, 4158, 4248, 4341, 4436, 4533, 4632, + 4734, 4839, 4945, 5054, 5165, 5279, 5394, 5512, + 5632, 5754, 5879, 6005, 6134, 6264, 6397, 6531, + 6668, 6807, 6947, 7090, 7234, 7381, 7529, 7679, + 7831, 7984, 8140, 8297, 8455, 8616, 8778, 8941, + 9107, 9273, 9442, 9611, 9782, 9955, 10129, 10304, + 10481, 10659, 10838, 11019, 11200, 11383, 11567, 11752, + 11938, 12125, 12313, 12502, 12693, 12883, 13075, 13268, + 13461, 13655, 13850, 14046, 14242, 14439, 14637, 14835, + 15033, 15232, 15432, 15631, 15832, 16032, 16233, 16434, + 16635, 16837, 17039, 17240, 17442, 17644, 17846, 18048, + 18250, 18452, 18653, 18855, 19056, 19257, 19458, 19658, + 19858, 20058, 20257, 20456, 20654, 20852, 21049, 21245, + 21441, 21637, 21831, 22025, 22218, 22410, 22602, 22792, + 22982, 23170, 23358, 23545, 23730, 23915, 24098, 24280, + 24461, 24641, 24820, 24997, 25173, 25348, 25521, 25693, + 25863, 26032, 26200, 26366, 26530, 26693, 26854, 27014, + 27171, 27328, 27482, 27635, 27786, 27935, 28082, 28227, + 28371, 28513, 28652, 28790, 28926, 29059, 29191, 29320, + 29448, 29573, 29697, 29818, 29937, 30053, 30168, 30280, + 30390, 30498, 30603, 30706, 30807, 30905, 31002, 31095, + 31186, 31275, 31362, 31446, 31527, 31606, 31683, 31757, + 31828, 31897, 31963, 32027, 32088, 32147, 32203, 32257, + 32307, 32356, 32401, 32444, 32484, 32522, 32557, 32589, + 32619, 32646, 32670, 32692, 32711, 32727, 32741, 32751, + 32760, 32765, 32767, 32767, 32762, 32751, 32734, 32712, + 32685, 32652, 32614, 32570, 32521, 32466, 32406, 32341, + 32270, 32194, 32112, 32026, 31934, 31837, 31735, 31627, + 31515, 31398, 31275, 31148, 31016, 30878, 30737, 30590, + 30438, 30282, 30122, 29957, 29787, 29613, 29434, 29252, + 29065, 28874, 28679, 28480, 28277, 28070, 27859, 27644, + 27426, 27205, 26980, 26751, 26520, 26285, 26047, 25805, + 25561, 25314, 25065, 24812, 24557, 24300, 24040, 23777, + 23513, 23246, 22978, 22707, 22435, 22161, 21885, 21608, + 21329, 21049, 20768, 20485, 20202, 19918, 19632, 19347, + 19060, 18773, 18486, 18198, 17911, 17623, 17335, 17047, + 16760, 16473, 16186, 15900, 15614, 15330, 15046, 14763, + 14481, 14200, 13921, 13643, 13367, 13092, 12818, 12547, + 12277, 12010, 11744, 11481, 11220, 10961, 10705, 10451, + 10200, 9951, 9706, 9463, 9223, 8987, 8754, 8523, + 8297, 8073, 7854, 7637, 7425, 7216, 7011, 6810, + 6613, 6420, 6231, 6046, 5865, 5689, 5517, 5350, + 5187, 5028, 4875, 4726, 4581, 4442, 4307, 4177, + 4052, 3932, 3818, 3708, 3603, 3503, 3409, 3320, + 3236, 3157, 3084, 3016, 2953, 2895, 2844, 2797, + 2756, 2720, 2690, 2665, 2646, 2632, 2624, 2621 +}; /* LP analysis window for AMR-WB IO mode (length of the window is 30ms which is * 384 samples at 12.8kHz */ const float hamcos_window[L_LP_AMR_WB] = @@ -1382,6 +1509,90 @@ const float sincos_t_ext[641] = -0.639124444863776f, -0.643831542889791f, -0.648514401022112f, -0.653172842953777f, -0.657806693297079f, -0.662415777590172f, -0.666999922303637f, -0.671558954847018f, -0.676092703575316f, -0.680600997795453f, -0.685083667772700f, -0.689540544737067f, -0.693971460889654f, -0.698376249408973f, -0.702754744457225f, -0.707106781186547f }; +const Word16 sincos_t_ext_fx[641] = +{ + 0, 201, 402, 603, 804, 1005, 1206, 1407, + 1608, 1809, 2009, 2210, 2411, 2611, 2811, 3012, + 3212, 3412, 3612, 3812, 4011, 4211, 4410, 4609, + 4808, 5007, 5205, 5404, 5602, 5800, 5998, 6195, + 6393, 6590, 6787, 6983, 7180, 7376, 7571, 7767, + 7962, 8157, 8351, 8546, 8740, 8933, 9127, 9319, + 9512, 9704, 9896, 10088, 10279, 10469, 10660, 10850, + 11039, 11228, 11417, 11605, 11793, 11980, 12167, 12354, + 12540, 12725, 12910, 13095, 13279, 13463, 13646, 13828, + 14010, 14192, 14373, 14553, 14733, 14912, 15091, 15269, + 15447, 15624, 15800, 15976, 16151, 16326, 16500, 16673, + 16846, 17018, 17190, 17361, 17531, 17700, 17869, 18037, + 18205, 18372, 18538, 18703, 18868, 19032, 19195, 19358, + 19520, 19681, 19841, 20001, 20160, 20318, 20475, 20632, + 20788, 20943, 21097, 21251, 21403, 21555, 21706, 21856, + 22006, 22154, 22302, 22449, 22595, 22740, 22884, 23028, + 23170, 23312, 23453, 23593, 23732, 23870, 24008, 24144, + 24279, 24414, 24548, 24680, 24812, 24943, 25073, 25202, + 25330, 25457, 25583, 25708, 25833, 25956, 26078, 26199, + 26320, 26439, 26557, 26674, 26791, 26906, 27020, 27133, + 27246, 27357, 27467, 27576, 27684, 27791, 27897, 28002, + 28106, 28209, 28311, 28411, 28511, 28610, 28707, 28803, + 28899, 28993, 29086, 29178, 29269, 29359, 29448, 29535, + 29622, 29707, 29792, 29875, 29957, 30038, 30118, 30196, + 30274, 30350, 30425, 30499, 30572, 30644, 30715, 30784, + 30853, 30920, 30986, 31050, 31114, 31177, 31238, 31298, + 31357, 31415, 31471, 31527, 31581, 31634, 31686, 31737, + 31786, 31834, 31881, 31927, 31972, 32015, 32058, 32099, + 32138, 32177, 32214, 32251, 32286, 32319, 32352, 32383, + 32413, 32442, 32470, 32496, 32522, 32546, 32568, 32590, + 32610, 32629, 32647, 32664, 32679, 32693, 32706, 32718, + 32729, 32738, 32746, 32753, 32758, 32762, 32766, 32767, + 32767, 32767, 32766, 32762, 32758, 32753, 32746, 32738, + 32729, 32718, 32706, 32693, 32679, 32664, 32647, 32629, + 32610, 32590, 32568, 32546, 32522, 32496, 32470, 32442, + 32413, 32383, 32352, 32319, 32286, 32251, 32214, 32177, + 32138, 32099, 32058, 32015, 31972, 31927, 31881, 31834, + 31786, 31737, 31686, 31634, 31581, 31527, 31471, 31415, + 31357, 31298, 31238, 31177, 31114, 31050, 30986, 30920, + 30853, 30784, 30715, 30644, 30572, 30499, 30425, 30350, + 30274, 30196, 30118, 30038, 29957, 29875, 29792, 29707, + 29622, 29535, 29448, 29359, 29269, 29178, 29086, 28993, + 28899, 28803, 28707, 28610, 28511, 28411, 28311, 28209, + 28106, 28002, 27897, 27791, 27684, 27576, 27467, 27357, + 27246, 27133, 27020, 26906, 26791, 26674, 26557, 26439, + 26320, 26199, 26078, 25956, 25833, 25708, 25583, 25457, + 25330, 25202, 25073, 24943, 24812, 24680, 24548, 24414, + 24279, 24144, 24008, 23870, 23732, 23593, 23453, 23312, + 23170, 23028, 22884, 22740, 22595, 22449, 22302, 22154, + 22006, 21856, 21706, 21555, 21403, 21251, 21097, 20943, + 20788, 20632, 20475, 20318, 20160, 20001, 19841, 19681, + 19520, 19358, 19195, 19032, 18868, 18703, 18538, 18372, + 18205, 18037, 17869, 17700, 17531, 17361, 17190, 17018, + 16846, 16673, 16500, 16326, 16151, 15976, 15800, 15624, + 15447, 15269, 15091, 14912, 14733, 14553, 14373, 14192, + 14010, 13828, 13646, 13463, 13279, 13095, 12910, 12725, + 12540, 12354, 12167, 11980, 11793, 11605, 11417, 11228, + 11039, 10850, 10660, 10469, 10279, 10088, 9896, 9704, + 9512, 9319, 9127, 8933, 8740, 8546, 8351, 8157, + 7962, 7767, 7571, 7376, 7180, 6983, 6787, 6590, + 6393, 6195, 5998, 5800, 5602, 5404, 5205, 5007, + 4808, 4609, 4410, 4211, 4011, 3812, 3612, 3412, + 3212, 3012, 2811, 2611, 2411, 2210, 2009, 1809, + 1608, 1407, 1206, 1005, 804, 603, 402, 201, + 0, -201, -402, -603, -804, -1005, -1206, -1407, + -1608, -1809, -2009, -2210, -2411, -2611, -2811, -3012, + -3212, -3412, -3612, -3812, -4011, -4211, -4410, -4609, + -4808, -5007, -5205, -5404, -5602, -5800, -5998, -6195, + -6393, -6590, -6787, -6983, -7180, -7376, -7571, -7767, + -7962, -8157, -8351, -8546, -8740, -8933, -9127, -9319, + -9512, -9704, -9896, -10088, -10279, -10469, -10660, -10850, + -11039, -11228, -11417, -11605, -11793, -11980, -12167, -12354, + -12540, -12725, -12910, -13095, -13279, -13463, -13646, -13828, + -14010, -14192, -14373, -14553, -14733, -14912, -15091, -15269, + -15447, -15624, -15800, -15976, -16151, -16326, -16500, -16673, + -16846, -17018, -17190, -17361, -17531, -17700, -17869, -18037, + -18205, -18372, -18538, -18703, -18868, -19032, -19195, -19358, + -19520, -19681, -19841, -20001, -20160, -20318, -20475, -20632, + -20788, -20943, -21097, -21251, -21403, -21555, -21706, -21856, + -22006, -22154, -22302, -22449, -22595, -22740, -22884, -23028, + -23028 +}; const float Asr_LP32[41] = @@ -1394,7 +1605,6 @@ const float Asr_LP32[41] = 0.00000000f }; - const float Asr_LP16[21] = { 0.00000000f, 0.00336304f, -0.00000000f, -0.01307328f, 0.00000000f, 0.03519564f, -0.00000000f, -0.08642702f, @@ -1402,7 +1612,6 @@ const float Asr_LP16[21] = 0.00000000f, -0.01307328f, -0.00000000f, 0.00336304f, 0.00000000f }; - const float Asr_LP48[61] = { 0.00000000f, 0.00029287f, 0.00071673f, 0.00112101f, 0.00127506f, 0.00094416f, -0.00000000f, -0.00147233f, @@ -1415,6 +1624,37 @@ const float Asr_LP48[61] = 0.00127506f, 0.00112101f, 0.00071673f, 0.00029287f, 0.00000000f }; +const Word16 Asr_LP16_fx[21] = +{ + /*Q15 */ + 0, 110, 0, -428, 0, 1153, 0, -2832, + 0, 10199, 16384, 10199, 0, -2832, 0, 1153, + 0, -428, 0, 110, 0 +}; + +const Word16 Asr_LP32_fx[41] = +{ + /*Q15 */ + 0, 24, 55, 58, 0, -113, -214, -198, + 0, 323, 576, 510, 0, -795, -1416, -1280, + 0, 2337, 5099, 7334, 8192, 7334, 5099, 2337, + 0, -1280, -1416, -795, 0, 510, 576, 323, + 0, -198, -214, -113, 0, 58, 55, 24, + 0 +}; + +const Word16 Asr_LP48_fx[61] = +{ + /*Q17 */ + 0, 38, 93, 146, 167, 123, 0, -192, + -408, -571, -592, -407, 0, 564, 1143, 1537, + 1546, 1035, 0, -1391, -2801, -3776, -3843, -2635, + 0, 3919, 8679, 13599, 17887, 20809, 21845, 20809, + 17887, 13599, 8679, 3919, 0, -2635, -3843, -3776, + -2801, -1391, 0, 1035, 1546, 1537, 1143, 564, + 0, -407, -592, -571, -408, -192, 0, 123, + 167, 146, 93, 38, 0 +}; const int16_t fft256_read_indexes[]= { 0, 128, 64, 192, 32, 160, 96, 224, 16, 144, 80, 208, 48, 176, 112, 240, @@ -1473,7 +1713,38 @@ const float sin_table256[] = 0.999769405f, 0.999882347f, 0.999957645f, 0.999995294f }; - +const Word16 sin_table256_fx[] = +{ + 101, 302, 503, 704, 905, 1106, 1307, 1507, 1708, + 1909, 2110, 2310, 2511, 2711, 2912, 3112, 3312, 3512, + 3712, 3911, 4111, 4310, 4510, 4709, 4907, 5106, 5305, + 5503, 5701, 5899, 6097, 6294, 6491, 6688, 6885, 7081, + 7278, 7473, 7669, 7864, 8059, 8254, 8449, 8643, 8836, + 9030, 9223, 9416, 9608, 9800, 9992, 10183, 10374, 10565, + 10755, 10945, 11134, 11323, 11511, 11699, 11887, 12074, 12261, + 12447, 12633, 12818, 13003, 13187, 13371, 13554, 13737, 13919, + 14101, 14282, 14463, 14643, 14823, 15002, 15180, 15358, 15535, + 15712, 15888, 16064, 16239, 16413, 16587, 16760, 16932, 17104, + 17275, 17446, 17616, 17785, 17953, 18121, 18288, 18455, 18621, + 18786, 18950, 19114, 19277, 19439, 19601, 19761, 19921, 20081, + 20239, 20397, 20554, 20710, 20865, 21020, 21174, 21327, 21479, + 21631, 21781, 21931, 22080, 22228, 22375, 22522, 22668, 22812, + 22956, 23099, 23241, 23383, 23523, 23663, 23801, 23939, 24076, + 24212, 24347, 24481, 24614, 24746, 24878, 25008, 25138, 25266, + 25394, 25520, 25646, 25771, 25894, 26017, 26139, 26259, 26379, + 26498, 26616, 26733, 26848, 26963, 27077, 27190, 27301, 27412, + 27522, 27630, 27738, 27844, 27950, 28054, 28158, 28260, 28361, + 28461, 28560, 28658, 28755, 28851, 28946, 29040, 29132, 29224, + 29314, 29404, 29492, 29579, 29665, 29750, 29833, 29916, 29997, + 30078, 30157, 30235, 30312, 30388, 30462, 30536, 30608, 30680, + 30750, 30819, 30886, 30953, 31018, 31082, 31146, 31207, 31268, + 31328, 31386, 31443, 31499, 31554, 31608, 31660, 31711, 31761, + 31810, 31858, 31904, 31950, 31994, 32037, 32078, 32119, 32158, + 32196, 32233, 32268, 32303, 32336, 32368, 32398, 32428, 32456, + 32483, 32509, 32534, 32557, 32579, 32600, 32620, 32638, 32656, + 32672, 32686, 32700, 32712, 32723, 32733, 32742, 32749, 32756, + 32760, 32764, 32767, 32767 +}; /*----------------------------------------------------------------------------------* * 1/4 resolution interpolation filter (-3 dB at 0.913*fs/2) *----------------------------------------------------------------------------------*/ @@ -1498,7 +1769,73 @@ const float inter4_2[65] = -0.000618f, -0.000434f, -0.000133f, 0.000063f, 0.000098f, 0.000048f, 0.000007f, 0.000000f }; - +const Word16 inter4_2_fx[] = +{ + 0, 1, 2, 1, + -2, -7, -10, -7, + 4, 19, 28, 22, + -2, -33, -55, -49, + -10, 47, 91, 92, + 38, -52, -133, -153, + -88, 43, 175, 231, + 165, -9, -209, -325, + -275, -60, 226, 431, + 424, 175, -213, -544, + -619, -355, 153, 656, + 871, 626, -16, -762, + -1207, -1044, -249, 853, + 1699, 1749, 780, -923, + -2598, -3267, -2147, 968, + 5531, 10359, 14031, 15401, + 14031, 10359, 5531, 968, + -2147, -3267, -2598, -923, + 780, 1749, 1699, 853, + -249, -1044, -1207, -762, + -16, 626, 871, 656, + 153, -355, -619, -544, + -213, 175, 424, 431, + 226, -60, -275, -325, + -209, -9, 165, 231, + 175, 43, -88, -153, + -133, -52, 38, 92, + 91, 47, -10, -49, + -55, -33, -2, 22, + 28, 19, 4, -7, + -10, -7, -2, 1, + 2, 1, 0, 0 +}; + +/* 1/4 resolution interpolation filter (-3 dB at 0.856*fs/2) */ +const Word16 pitch_inter4_2[PIT_FIR_SIZE2] = +{ + /* cut-off frequency at 0.94*fs/2 */ + 30802/*0.940000f Q15*/, + 28062/*0.856390f Q15*/, 20718/*0.632268f Q15*/, 11061/*0.337560f Q15*/, 1936/*0.059072f Q15*/, + -4295/*-0.131059f Q15*/, -6534/*-0.199393f Q15*/, -5196/*-0.158569f Q15*/, -1847/*-0.056359f Q15*/, + 1560/*0.047606f Q15*/, 3498/*0.106749f Q15*/, 3398/*0.1037059f Q15*/, 1706/*0.052062f Q15*/, + -497/*-0.015182f Q15*/, -2087/*-0.063705f Q15*/, -2414/*-0.073660f Q15*/, -1524/*-0.046497f Q15*/, + -32/*-0.000983f Q15*/, 1253/*0.038227f Q15*/, 1741/*0.053143f Q15*/, 1313/*0.040059f Q15*/, + 305/*0.009308f Q15*/, -710/*-0.021674f Q15*/, -1238/*-0.037767f Q15*/, -1087/*-0.033186f Q15*/, + -427/*-0.013028f Q15*/, 351/*0.010702f Q15*/, 849/*0.025901f Q15*/, 862/*0.026318f Q15*/, + 453/*0.013821f Q15*/, -119/*-0.003645f Q15*/, -551/*-0.016813f Q15*/, -651/*-0.019855f Q15*/, + -418/*-0.012766f Q15*/, -17/*-0.000530f Q15*/, 330/*0.010080f Q15*/, 463/*0.014122f Q15*/, + 349/*0.010657f Q15*/, 85/*0.002594f Q15*/, -176/*-0.005363f Q15*/, -306/*-0.009344f Q15*/, + -265/*-0.008101f Q15*/, -104/*-0.003182f Q15*/, 76/*0.002330f Q15*/, 185/*0.005635f Q15*/, + 182/*0.005562f Q15*/, 93/*0.002844f Q15*/, -21/*-0.000627f Q15*/, -98/*-0.002993f Q15*/, + -110/*-0.003362f Q15*/, -67/*-0.002044f Q15*/, -4/*-0.000116f Q15*/, 43/*0.001315f Q15*/, + 55/*0.001692f Q15*/, 38/*0.001151f Q15*/, 8/*0.000259f Q15*/, -14/*-0.000417f Q15*/, + -20/*-0.000618f Q15*/, -14/*-0.000434f Q15*/, -4/*-0.000133f Q15*/, 2/*0.000063f Q15*/, + 3/*0.000098f Q15*/, 2/*0.000048f Q15*/, 0/*0.000007f Q15*/, 0/*0.000000f Q15*/ +}; +/* 1/4 resolution interpolation filter (-3 dB at 0.791*fs/2) */ +const Word16 pitch_inter4_1[UP_SAMP * L_INTERPOL1 + 1] = +{ + 29491/*0.900000F Q15*/, + 26836/*0.818959F Q15*/, 19820/* 0.604850F Q15*/, 10859/* 0.331379F Q15*/, 2751/* 0.083958F Q15*/, + -2484/*-0.075795F Q15*/, -4283/* -0.130717F Q15*/, -3463/*-0.105685F Q15*/, -1533/*-0.046774F Q15*/, + 146/*0.004467F Q15*/, 911/* 0.027789F Q15*/, 840/* 0.025642F Q15*/, 412/* 0.012571F Q15*/, + 63/*0.001927F Q15*/, -51/* -0.001571F Q15*/, -25/*-0.000753F Q15*/, 0/* 0.000000f Q15*/ +}; /*----------------------------------------------------------------------------------* * 1/6 resolution interpolation filter (-3 dB at 0.95*fs/2) @@ -1525,6 +1862,113 @@ const float inter6_2[PIT_FIR_SIZE6_2] = -0.000132755824518F, -0.000148377158880F, -0.000112937171810F, -0.000061132514471F, -0.000019974224468F, -0.000000460344975F, 0.000001976848453F }; +/* 1/6 resolution interpolation filter (-3 dB at 0.95*fs/2) */ +const Word16 pitch_inter6_2[PIT_FIR_SIZE6_2] = +{ + 31129/*0.949986374119862f Q15*/, + 29854/*0.911081104469830f Q15*/, + 26218/*0.800115099292852f Q15*/, + 20753/*0.633320673120883f Q15*/, + 14240/*0.434558462154083f Q15*/, + 7575/*0.231177017786780f Q15*/, + 1618/*0.049378173063717f Q15*/, + -2950/*-0.090039611811170f Q15*/, + -5727/*-0.174782560924477f Q15*/, + -6635/*-0.202477516286360f Q15*/, + -5905/*-0.180218293244902f Q15*/, + -4012/*-0.122429229978978f Q15*/, + -1558/*-0.047552067127379f Q15*/, + 843/*0.025733669494145f Q15*/, + 2687/*0.081995376731897f Q15*/, + 3656/*0.111581381838187f Q15*/, + 3663/*0.111781798292302f Q15*/, + 2834/*0.086499988914996f Q15*/, + 1462/*0.044629684447068f Q15*/, + -79/*-0.002416435594242f Q15*/, + -1423/*-0.043440027386915f Q15*/, + -2289/*-0.069857782812169f Q15*/, + -2533/*-0.077293683967992f Q15*/, + -2166/*-0.066098268486336f Q15*/, + -1336/*-0.040782649068098f Q15*/, + -282/*-0.008590773415008f Q15*/, + 734/*0.022397654632128f Q15*/, + 1480/*0.045171360007974f Q15*/, + 1811/*0.055274128677739f Q15*/, + 1690/*0.051578034020076f Q15*/, + 1187/*0.036232016917169f Q15*/, + 454/*0.013869500422767f Q15*/, + -317/*-0.009680698856947f Q15*/, + -945/*-0.028843394410080f Q15*/, + -1296/*-0.039560663181280f Q15*/, + -1314/*-0.040095747151623f Q15*/, + -1023/*-0.031231107680685f Q15*/, + -520/*-0.015866154815425f Q15*/, + 60/*0.001841532922707f Q15*/, + 575/*0.017553701334759f Q15*/, + 910/*0.027778555138199f Q15*/, + 1003/*0.030612329573745f Q15*/, + 853/*0.026046143652186f Q15*/, + 518/*0.015803012695681f Q15*/, + 91/*0.002782973481834f Q15*/, + -319/*-0.009720124055079f Q15*/, + -617/*-0.018826488463900f Q15*/, + -744/*-0.022710487805852f Q15*/, + -686/*-0.020936374578238f Q15*/, + -473/*-0.014436620433404f Q15*/, + -169/*-0.005169079181373f Q15*/, + 145/*0.004437651243491f Q15*/, + 397/*0.012100372954920f Q15*/, + 531/*0.016207075406240f Q15*/, + 529/*0.016135389123271f Q15*/, + 403/*0.012306629559665f Q15*/, + 196/*0.005986734945567f Q15*/, + -36/*-0.001094950878591f Q15*/, + -236/*-0.007200842219958f Q15*/, + -360/*-0.010998212848124f Q15*/, + -388/*-0.011835179448280f Q15*/, + -322/*-0.009826566540474f Q15*/, + -188/*-0.005747665080695f Q15*/, + -26/*-0.000780600030751f Q15*/, + 125/*0.003810613287985f Q15*/, + 229/*0.006990479233404f Q15*/, + 268/*0.008174249796791f Q15*/, + 240/*0.007317375965949f Q15*/, + 159/*0.004864690818765f Q15*/, + 52/*0.001587005259212f Q15*/, + -54/*-0.001642504305841f Q15*/, + -133/*-0.004070609517416f Q15*/, + -171/*-0.005230670504649f Q15*/, + -164/*-0.005019147682711f Q15*/, + -120/*-0.003673879223241f Q15*/, + -55/*-0.001671460853812f Q15*/, + 14/*0.000420750005150f Q15*/, + 69/*0.002095384947391f Q15*/, + 99/*0.003020513665060f Q15*/, + 101/*0.003095468528243f Q15*/, + 80/*0.002441025550729f Q15*/, + 44/*0.001335514431569f Q15*/, + 4/*0.000120805384516f Q15*/, + -29/*-0.000893340757369f Q15*/, + -49/*-0.001501610712267f Q15*/, + -54/*-0.001636887611783f Q15*/, + -45/*-0.001362571776250f Q15*/, + -27/*-0.000832126175863f Q15*/, + -8/*-0.000232033375863f Q15*/, + 9/*0.000273627139471f Q15*/, + 19/*0.000582092683087f Q15*/, + 22/*0.000666445711949f Q15*/, + 19/*0.000566088888178f Q15*/, + 12/*0.000360374058147f Q15*/, + 4/*0.000136306914913f Q15*/, + -1/*-0.000038864994777f Q15*/, + -4/*-0.000132755824518f Q15*/, + -5/*-0.000148377158880f Q15*/, + -4/*-0.000112937171810f Q15*/, + -2/*-0.000061132514471f Q15*/, + -1/*-0.000019974224468f Q15*/, + 0/*-0.000000460344975f Q15*/, + 0/*0.000001976848453f Q15*/ +}; /*----------------------------------------------------------------------------------* @@ -2088,6 +2532,7 @@ const float interpol_frac2_mid[NB_SUBFR*3] = { const float interpol_frac_12k8[NB_SUBFR] = { 0.25f, 0.5f, 0.75f, 1.0f }; +const Word16 interpol_frac_fx[NB_SUBFR] = { 8192, 16384, 24576,32767 }; const float interpol_isp_amr_wb[NB_SUBFR] = { 0.45f, 0.8f, 0.96f, 1.0f @@ -2418,7 +2863,137 @@ const float gain_qua_mless_7b[128*2] = 1.2210f, 0.7314f, 1.2298f, 1.0376f }; - +const Word16 gain_qua_mless_7b_fx[128*2] = +{ + 419, 28, + 1499, 607, + 1586, 322, + 1632, 144, + 1686, 229, + 1745, 495, + 2182, 409, + 2515, 716, + 2772, 824, + 3069, 1069, + 3211, 936, + 3218, 89, + 3477, 1244, + 3755, 272, + 3865, 549, + 3881, 348, + 4171, 181, + 4414, 627, + 4419, 472, + 4909, 1429, + 5238, 404, + 5241, 1651, + 5721, 85, + 5833, 250, + 5846, 693, + 5897, 325, + 6036, 544, + 6088, 779, + 6459, 1889, + 6650, 157, + 6678, 462, + 6798, 879, + 6922, 993, + 6929, 1130, + 7352, 620, + 7461, 386, + 7864, 232, + 7999, 314, + 8136, 536, + 8398, 712, + 8680, 459, + 8797, 1276, + 9046, 806, + 9198, 86, + 9434, 398, + 9730, 587, + 9735, 267, + 9742, 175, + 9917, 917, + 10042, 509, + 10053, 655, + 10132, 1030, + 10238, 339, + 10694, 1560, + 10817, 447, + 10964, 723, + 11405, 1149, + 11526, 549, + 11582, 386, + 11602, 791, + 11618, 286, + 11883, 862, + 11954, 607, + 12057, 214, + 12104, 496, + 12170, 1397, + 12437, 668, + 12616, 335, + 12668, 952, + 12684, 435, + 12983, 112, + 13235, 742, + 13399, 549, + 13525, 380, + 13527, 270, + 13625, 1044, + 13733, 482, + 13820, 617, + 14036, 817, + 14041, 1257, + 14295, 425, + 14346, 684, + 14367, 319, + 14416, 199, + 14644, 898, + 14944, 518, + 15090, 364, + 15154, 578, + 15309, 462, + 15360, 1933, + 15362, 756, + 15381, 262, + 15566, 1127, + 15699, 639, + 15804, 410, + 16081, 316, + 16161, 993, + 16359, 701, + 16451, 828, + 16500, 543, + 16540, 491, + 16617, 1729, + 16630, 196, + 16749, 369, + 16959, 1530, + 17028, 442, + 17139, 603, + 17369, 898, + 17393, 268, + 17972, 763, + 17985, 1361, + 18016, 333, + 18032, 667, + 18234, 406, + 18270, 105, + 18299, 554, + 18342, 488, + 18747, 1207, + 19027, 1073, + 19530, 216, + 19566, 963, + 19751, 835, + 19794, 615, + 19810, 298, + 19988, 710, + 19990, 449, + 20005, 374, + 20149, 531, +}; const float gain_qua_mless_6b_stereo[64*2]= { 0.034851F,1.358887F, @@ -2554,7 +3129,73 @@ const float gain_qua_mless_6b[64*2] = 1.1893f, 1.0872f, 1.1911f, 0.6722f }; - +const Word16 gain_qua_mless_6b_fx[64 * 2] = +{ + 1676, 71, + 2128, 198, + 2318, 491, + 2348, 339, + 2798, 625, + 2893, 785, + 3911, 1099, + 4779, 244, + 4781, 427, + 5115, 935, + 5294, 1509, + 5767, 114, + 6018, 543, + 6152, 335, + 6205, 675, + 6234, 1822, + 6740, 1251, + 7034, 802, + 7782, 434, + 8005, 230, + 9232, 622, + 9337, 336, + 9388, 520, + 9770, 1038, + 9865, 734, + 10224, 879, + 10617, 118, + 10776, 426, + 11518, 249, + 11708, 1399, + 12044, 587, + 12270, 501, + 12277, 348, + 12498, 684, + 13020, 786, + 13097, 1196, + 13530, 422, + 13818, 917, + 14123, 290, + 14500, 1039, + 14538, 636, + 14636, 556, + 14667, 484, + 14931, 362, + 15055, 210, + 15653, 1594, + 15830, 1874, + 15868, 717, + 15897, 828, + 16153, 434, + 16540, 294, + 16874, 608, + 16936, 513, + 17182, 373, + 17644, 1337, + 17696, 126, + 18342, 1122, + 18461, 944, + 18991, 242, + 19114, 795, + 19187, 674, + 19256, 449, + 19485, 557, + 19515, 344, +}; const float gain_qua_mless_5b[32*2] = { 0.1645f, 0.2137f, @@ -2590,6 +3231,41 @@ const float gain_qua_mless_5b[32*2] = 1.1376f, 0.6895f, 1.1529f, 0.9632f }; +const Word16 gain_qua_mless_5b_fx[32 * 2] = +{ + 2695, 109, + 3444, 271, + 3529, 433, + 4284, 801, + 4365, 607, + 4935, 1089, + 6896, 1407, + 7722, 324, + 7913, 146, + 8090, 468, + 9049, 913, + 9499, 600, + 9894, 741, + 9942, 1840, + 11906, 382, + 12008, 1103, + 12349, 243, + 12429, 501, + 13687, 630, + 13974, 896, + 14510, 748, + 15160, 322, + 15424, 428, + 15679, 541, + 15832, 1574, + 15999, 1281, + 17223, 211, + 17719, 1029, + 18185, 649, + 18432, 818, + 18638, 353, + 18889, 493, +}; const int16_t E_ROM_qua_gain5b_const[NB_QUA_GAIN5B * 2]= { @@ -2832,6 +3508,7 @@ const int16_t E_ROM_qua_gain7b_const[NB_QUA_GAIN7B * 2] = *----------------------------------------------------------------------------------*/ const float pred_gain[GAIN_PRED_ORDER] = { 0.5f, 0.4f, 0.3f, 0.2f }; +const Word16 pred_gain_fx[GAIN_PRED_ORDER] = { 8192, 6554, 4915, 3277 }; /*----------------------------------------------------------------------------------* * 6-bit gain quantization table (only for AMR-WB IO mode) @@ -2904,6 +3581,74 @@ const float t_qua_gain6b[64*2] = 1.187154f, 4.421983f, 1.243327f, 7.268204f }; +const Word16 t_qua_gain6b_fx[64 * 2] = +{ + 1566, 1332, + 1577, 3557, + 3071, 6490, + 4193, 10163, + 4496, 2534, + 5019, 4488, + 5586, 15614, + 5725, 1422, + 6453, 580, + 6724, 6831, + 7657, 3527, + 8072, 2099, + 8232, 5319, + 8827, 8775, + 9740, 2868, + 9856, 1465, + 10087, 12488, + 10241, 4453, + 10859, 6618, + 11321, 3587, + 11417, 1800, + 11643, 2428, + 11718, 988, + 12312, 5093, + 12523, 8413, + 12574, 26214, + 12601, 3396, + 13172, 1623, + 13285, 2423, + 13418, 6087, + 13459, 12810, + 13656, 3607, + 14111, 4521, + 14144, 1229, + 14425, 1871, + 14431, 7234, + 14445, 2834, + 14628, 10036, + 14860, 17496, + 15161, 3629, + 15209, 5819, + 15299, 2256, + 15518, 4722, + 15663, 1060, + 15759, 7972, + 15939, 11964, + 16020, 2996, + 16086, 1707, + 16521, 4254, + 16576, 6224, + 16894, 2380, + 16906, 681, + 17213, 8406, + 17610, 3418, + 17895, 5269, + 18168, 11748, + 18230, 1575, + 18607, 32767, + 18728, 21684, + 19137, 2543, + 19422, 6577, + 19446, 4097, + 19450, 9056, + 20371, 14885 +}; + /*----------------------------------------------------------------------------------* * 7-bit gain quantization table (only for AMR-WB IO mode) @@ -3040,6 +3785,137 @@ const float t_qua_gain7b[128*2] = 1.223150f, 1.387102f, 1.296012f, 9.684225f }; +const Word16 t_qua_gain7b_fx[128 * 2] = +{ + 204, 441, + 464, 1977, + 869, 1077, + 1072, 3062, + 1281, 4759, + 1647, 1539, + 1845, 7020, + 1853, 634, + 1995, 2336, + 2351, 15400, + 2661, 1165, + 2702, 3900, + 2710, 10133, + 3195, 1752, + 3498, 2624, + 3663, 849, + 3984, 5697, + 4214, 3399, + 4415, 1304, + 4695, 2056, + 5376, 4558, + 5386, 676, + 5518, 23554, + 5567, 7794, + 5644, 3061, + 5672, 1513, + 5957, 2338, + 6533, 1060, + 6804, 5998, + 6820, 1767, + 6937, 3837, + 7277, 414, + 7305, 2665, + 7466, 11304, + 7942, 794, + 8007, 1982, + 8007, 1366, + 8326, 3105, + 8336, 4810, + 8708, 7954, + 8989, 2279, + 9031, 1055, + 9247, 3568, + 9283, 1631, + 9654, 6311, + 9811, 2605, + 10120, 683, + 10143, 4179, + 10245, 1946, + 10335, 1218, + 10468, 9960, + 10651, 3000, + 10951, 1530, + 10969, 5290, + 11203, 2305, + 11325, 3562, + 11771, 6754, + 11839, 1849, + 11941, 4495, + 11954, 1298, + 11975, 15223, + 11977, 883, + 11986, 2842, + 12438, 2141, + 12593, 3665, + 12636, 8367, + 12658, 1594, + 12886, 2628, + 12984, 4942, + 13146, 1115, + 13224, 524, + 13341, 3163, + 13399, 1923, + 13549, 5961, + 13606, 1401, + 13655, 2399, + 13782, 3909, + 13868, 10923, + 14226, 1723, + 14232, 2939, + 14278, 7528, + 14439, 4598, + 14451, 984, + 14458, 2265, + 14792, 1403, + 14818, 3445, + 14899, 5709, + 15017, 15362, + 15048, 1946, + 15069, 2655, + 15405, 9591, + 15405, 4079, + 15570, 7183, + 15687, 2286, + 15691, 1624, + 15699, 3068, + 15772, 5149, + 15868, 1205, + 15970, 696, + 16249, 3584, + 16338, 1917, + 16424, 2560, + 16483, 4438, + 16529, 6410, + 16620, 11966, + 16839, 8780, + 17030, 3050, + 17033, 18325, + 17092, 1568, + 17123, 5197, + 17351, 2113, + 17374, 980, + 17566, 26214, + 17609, 3912, + 17639, 32767, + 18151, 7871, + 18197, 2516, + 18202, 5649, + 18679, 3283, + 18930, 1370, + 19271, 13757, + 19317, 4120, + 19460, 1973, + 19654, 10018, + 19764, 6792, + 19912, 5135, + 20040, 2841, + 21234, 19833 +}; /*----------------------------------------------------------------------------------* * Quantization table for scaled innovation energy prediciton @@ -3080,6 +3956,41 @@ const float Es_pred_qua_5b[32] = 59.9748f, 65.0000f }; +const Word16 Es_pred_qua_5b_fx[32] = +{ + -2048, + -525, + 642, + 1688, + 2547, + 3326, + 4026, + 4647, + 5211, + 5740, + 6221, + 6661, + 7067, + 7447, + 7815, + 8170, + 8518, + 8865, + 9204, + 9551, + 9912, + 10284, + 10669, + 11077, + 11509, + 11976, + 12486, + 13049, + 13695, + 14434, + 15354, + 16640, +}; const float Es_pred_qua_4b[16] = @@ -3101,6 +4012,27 @@ const float Es_pred_qua_4b[16] = 58.0552f, 65.0000f }; +const Word16 Es_pred_qua_4b_fx[16] = +{ + -2048, + -36, + 1828, + 3284, + 4584, + 5742, + 6821, + 7834, + /*8779, */ + 8778, + 9701, + 10610, + 11524, + 12487, + 13560, + 14862, + 16640 +}; + const float Es_pred_qua_3b[8] = { @@ -3113,6 +4045,17 @@ const float Es_pred_qua_3b[8] = 50.2442f, 58.7164f }; +const Word16 Es_pred_qua_3b_fx[8] = +{ + 1521/* 5.9422f Q8*/, + 3909/*15.2711f Q8*/, + 5987/*23.3857f Q8*/, + 7816/*30.5310f Q8*/, + 9477/*37.0190f Q8*/, + 11124/*43.4539f Q8*/, + 12863/*50.2442f Q8*/, + 15031/*58.7164f Q8*/ +}; const float Es_pred_qua_4b_no_ltp[16] = { @@ -3133,7 +4076,25 @@ const float Es_pred_qua_4b_no_ltp[16] = 65.f, 70.f }; - +const Word16 Es_pred_qua_4b_no_ltp_fx[16] = +{ + -1280/*-5.f Q8*/, + 0/* 0.f Q8*/, + 1280/* 5.f Q8*/, + 2560/*10.f Q8*/, + 3840/*15.f Q8*/, + 5120/*20.f Q8*/, + 6400/*25.f Q8*/, + 7680/*30.f Q8*/, + 8960/*35.f Q8*/, + 10240/*40.f Q8*/, + 11520/*45.f Q8*/, + 12800/*50.f Q8*/, + 14080/*55.f Q8*/, + 15360/*60.f Q8*/, + 16640/*65.f Q8*/, + 17920/*70.f Q8*/ +}; /*----------------------------------------------------------------------------------* * Gain estimation constants (for gain quantizer at 7.2 and 8.0 kbps) *----------------------------------------------------------------------------------*/ @@ -3142,22 +4103,37 @@ const float b_1sfr[2] = { 2.36736f, -0.22452f }; +const Word16 b_1sfr_fx[2] = /*Q12 */ +{ + 9697, -920 +}; const float b_2sfr[4] = { -0.00027f, 0.01703f, 0.91879f, 0.13234f }; +const Word16 b_2sfr_fx[4] = /*Q12 */ +{ + -1, 70, 3763, 542 +}; const float b_3sfr[6] = { -0.11658f, 0.02674f, 0.13513f, 0.79682f, 0.02241f, 0.17815f }; +const Word16 b_3sfr_fx[6] = +{ + -478, 110, 553, 3264, 92, 730 +}; const float b_4sfr[8] = { -0.09296f, 0.01578f, -0.06606f, 0.20416f, 0.79254f, 0.00829f, 0.03499f, 0.15859f }; - +const Word16 b_4sfr_fx[8] = +{ + -381, 65, -271, 836, 3246, 34, 143, 650 +}; /*----------------------------------------------------------------------------------* * Gain codebooks (for gain quantizer at 7.2 and 8.0 kbps) @@ -4225,6 +5201,803 @@ const float gp_gamma_4sfr_7b[2 * 128] = 1.20145f, 1.11183f, }; +const Word16 gp_gamma_1sfr_8b_fx[2 * 256] = /*Q14/Q9 */ +{ + 305, 152, + 333, 37, + 352, 556, + 573, 82, + 652, 12, + 694, 207, + 808, 389, + 915, 776, + 986, 1089, + 987, 1583, + 1055, 60, + 1202, 2779, + 1205, 20, + 1346, 127, + 1432, 332, + 1689, 6554, + 1715, 261, + 1820, 49, + 2041, 698, + 2179, 4032, + 2199, 100, + 2272, 1303, + 2317, 461, + 2340, 175, + 2562, 26, + 2574, 14814, + 2657, 2101, + 2732, 66, + 2818, 9, + 2836, 296, + 2929, 938, + 3479, 130, + 3510, 220, + 3651, 3154, + 3667, 717, + 3720, 384, + 3783, 530, + 3811, 10744, + 3883, 5385, + 3941, 1609, + 3964, 46, + 4120, 80, + 4402, 15, + 4440, 1181, + 4485, 173, + 4740, 311, + 4848, 31, + 5125, 7642, + 5147, 110, + 5167, 908, + 5237, 252, + 5323, 623, + 5376, 2514, + 5590, 7, + 5595, 4475, + 5634, 64, + 5654, 461, + 5822, 22, + 5893, 140, + 5905, 1810, + 6177, 367, + 6268, 201, + 6352, 1092, + 6567, 752, + 6626, 50, + 6734, 95, + 6758, 295, + 6882, 3085, + 6962, 1363, + 7274, 540, + 7413, 166, + 7635, 2120, + 7642, 38, + 7671, 393, + 7730, 227, + 7860, 75, + 7980, 115, + 8011, 955, + 8092, 3687, + 8120, 17, + 8146, 5902, + 8453, 672, + 8524, 1602, + 8583, 58, + 8679, 275, + 8873, 332, + 8920, 454, + 8969, 9712, + 9129, 2566, + 9159, 196, + 9193, 1127, + 9219, 142, + 9300, 9, + 9302, 828, + 9409, 91, + 9736, 26, + 9872, 574, + 10066, 246, + 10131, 1352, + 10154, 1971, + 10196, 399, + 10238, 15785, + 10255, 4254, + 10401, 67, + 10439, 43, + 10511, 116, + 10531, 7399, + 10706, 998, + 10798, 722, + 10845, 171, + 10848, 304, + 10876, 2981, + 11069, 28204, + 11139, 507, + 11280, 12, + 11427, 388, + 11459, 214, + 11647, 1174, + 11710, 5061, + 11742, 1614, + 11793, 806, + 11816, 82, + 11890, 132, + 11996, 2301, + 12000, 603, + 12060, 55, + 12232, 256, + 12299, 33, + 12438, 338, + 12452, 458, + 12627, 3563, + 12646, 9489, + 12665, 934, + 12801, 1329, + 12802, 190, + 12877, 683, + 12941, 103, + 13038, 1890, + 13209, 6209, + 13222, 12674, + 13318, 21, + 13374, 283, + 13385, 149, + 13391, 383, + 13453, 545, + 13564, 1064, + 13596, 2561, + 13771, 810, + 13834, 1481, + 13874, 69, + 14027, 226, + 14093, 4429, + 14147, 7, + 14171, 609, + 14185, 47, + 14223, 3051, + 14273, 434, + 14321, 314, + 14415, 120, + 14443, 1252, + 14500, 173, + 14557, 933, + 14616, 1696, + 14639, 8229, + 14724, 89, + 14837, 703, + 14902, 2072, + 14917, 366, + 15000, 487, + 15009, 30, + 15095, 256, + 15138, 1119, + 15228, 3580, + 15371, 1386, + 15387, 5525, + 15398, 17932, + 15462, 149, + 15471, 791, + 15551, 569, + 15554, 2467, + 15559, 201, + 15616, 14, + 15664, 319, + 15798, 401, + 15811, 974, + 15874, 41, + 15929, 1649, + 15945, 79, + 16046, 111, + 16225, 647, + 16230, 1240, + 16297, 4110, + 16328, 10499, + 16331, 278, + 16355, 3003, + 16383, 455, + 16404, 169, + 16435, 2172, + 16438, 850, + 16745, 7090, + 16776, 354, + 16801, 1063, + 16803, 62, + 16812, 223, + 16927, 530, + 16951, 721, + 17039, 1447, + 17208, 1837, + 17233, 135, + 17371, 4642, + 17570, 406, + 17608, 267, + 17696, 906, + 17702, 2529, + 17705, 23239, + 17709, 1209, + 17745, 592, + 17800, 92, + 17858, 35, + 17860, 3360, + 17866, 9, + 17978, 184, + 18035, 321, + 18255, 754, + 18274, 480, + 18320, 18, + 18406, 55, + 18582, 13017, + 18677, 1516, + 18726, 1998, + 18904, 25, + 18914, 6103, + 19020, 8567, + 19022, 1116, + 19025, 349, + 19147, 239, + 19224, 604, + 19251, 160, + 19270, 4870, + 19358, 3789, + 19394, 126, + 19394, 103, + 19433, 72, + 19444, 46, + 19448, 2842, + 19489, 430, + 19575, 815, + 19628, 1306, + 19631, 972, + 19637, 202, + 19642, 289, + 19660, 527, + 19717, 1697, + 19731, 2263, + 19754, 676, + 19854, 382, +}; + +const Word16 gp_gamma_1sfr_7b_fx[2 * 128] = /*Q14/Q9 */ +{ + 350, 85, + 428, 24, + 438, 681, + 642, 195, + 1071, 2012, + 1080, 402, + 1148, 1236, + 1159, 62, + 1424, 12, + 1662, 134, + 1985, 299, + 2100, 34, + 2163, 3168, + 2219, 538, + 2393, 6580, + 2499, 967, + 2882, 221, + 2974, 12743, + 3251, 98, + 3294, 51, + 3586, 1560, + 3711, 411, + 3721, 700, + 3862, 21, + 3947, 169, + 4001, 2249, + 4198, 4632, + 4372, 8, + 4993, 70, + 5022, 265, + 5568, 1194, + 5664, 495, + 5698, 115, + 5885, 854, + 6115, 2990, + 6266, 153, + 6376, 39, + 6432, 16, + 6601, 345, + 7108, 1957, + 7231, 660, + 7491, 202, + 7687, 93, + 8054, 3882, + 8108, 9624, + 8186, 1424, + 8243, 59, + 8354, 935, + 8358, 6401, + 8383, 439, + 8794, 285, + 8940, 124, + 9643, 25, + 9643, 581, + 9670, 2709, + 10065, 160, + 10218, 9, + 10240, 1728, + 10249, 80, + 10418, 1113, + 10497, 373, + 10650, 236, + 11095, 44, + 11095, 756, + 11284, 4978, + 11290, 16722, + 11815, 2299, + 11882, 482, + 12059, 114, + 12332, 8550, + 12363, 1394, + 12392, 186, + 12517, 336, + 12549, 3413, + 12694, 953, + 13096, 614, + 13185, 71, + 13247, 262, + 13479, 1914, + 13791, 14, + 13805, 30, + 14064, 138, + 14182, 420, + 14212, 1175, + 14477, 765, + 14605, 2745, + 14612, 6324, + 14730, 4199, + 14833, 301, + 14842, 203, + 14910, 12790, + 15171, 100, + 15191, 1625, + 15289, 532, + 15405, 52, + 15550, 985, + 16096, 357, + 16175, 2113, + 16284, 232, + 16333, 669, + 16363, 22999, + 16396, 156, + 16443, 1270, + 16455, 3482, + 16543, 8, + 16650, 5425, + 16878, 452, + 16989, 84, + 17024, 9676, + 17194, 876, + 17730, 20, + 17780, 1442, + 17864, 38, + 17874, 254, + 17929, 526, + 18011, 2403, + 18751, 7153, + 18786, 117, + 18820, 4420, + 19002, 63, + 19099, 401, + 19111, 183, + 19197, 776, + 19202, 2953, + 19236, 1052, + 19255, 301, + 19354, 1760, + 19432, 593, +}; + +const Word16 gp_gamma_1sfr_6b_fx[2 * 64] = /*Q14/Q9 */ +{ + 436, 182, + 473, 63, + 962, 16, + 992, 647, + 1258, 1582, + 1447, 351, + 1711, 125, + 1809, 46, + 2569, 4173, + 2607, 957, + 2826, 251, + 2904, 12481, + 3248, 26, + 3594, 2254, + 3664, 78, + 3715, 483, + 4232, 8, + 4681, 188, + 5066, 6623, + 5232, 1273, + 6232, 695, + 6234, 49, + 6238, 113, + 6312, 318, + 7012, 17, + 7327, 3183, + 8008, 1739, + 8692, 446, + 8769, 163, + 8923, 1019, + 9094, 81, + 10358, 286, + 10491, 28, + 10612, 9788, + 10715, 760, + 11045, 4822, + 11319, 2403, + 11684, 56, + 12314, 108, + 12460, 556, + 12580, 9, + 12716, 213, + 12821, 1336, + 14202, 374, + 14325, 16971, + 14612, 838, + 14625, 3285, + 14668, 6231, + 14919, 39, + 15131, 137, + 15476, 1847, + 16056, 255, + 16277, 494, + 16290, 66, + 16582, 1048, + 16859, 17, + 17220, 8723, + 17443, 4295, + 18069, 2499, + 18212, 176, + 18499, 91, + 18517, 1445, + 18522, 332, + 18596, 663, +}; + +const Word16 gp_gamma_2sfr_7b_fx[2 * 128] = /*Q14/Q9 */ +{ + 99, 1224, + 156, 243, + 168, 579, + 290, 355, + 437, 441, + 475, 187, + 734, 738, + 930, 93, + 1133, 153, + 1136, 298, + 1490, 508, + 1946, 401, + 1978, 16790, + 2098, 224, + 2117, 962, + 2407, 119, + 2686, 339, + 2929, 555, + 3404, 271, + 3465, 171, + 3469, 422, + 3714, 663, + 4436, 494, + 4494, 332, + 4571, 220, + 4583, 2182, + 4997, 848, + 5346, 380, + 5419, 108, + 5570, 579, + 5758, 266, + 5875, 442, + 5927, 170, + 6204, 3338, + 6394, 6435, + 6515, 328, + 6638, 730, + 6687, 1472, + 7045, 1056, + 7101, 498, + 7123, 210, + 7163, 9668, + 7345, 386, + 7598, 280, + 7853, 627, + 8462, 442, + 8648, 331, + 8822, 236, + 8887, 551, + 8953, 906, + 9317, 136, + 9587, 386, + 9651, 691, + 9796, 286, + 9852, 489, + 10005, 1215, + 10041, 192, + 10623, 576, + 10758, 329, + 10840, 425, + 10944, 792, + 11038, 257, + 11190, 1870, + 11541, 501, + 11729, 642, + 11873, 367, + 12064, 163, + 12332, 216, + 12339, 1100, + 12339, 295, + 12478, 444, + 12561, 568, + 12665, 845, + 13257, 396, + 13317, 677, + 13411, 511, + 13709, 324, + 13710, 1547, + 13711, 246, + 14054, 991, + 14112, 447, + 14246, 580, + 14355, 748, + 14394, 175, + 14453, 99, + 14604, 363, + 14887, 491, + 15074, 282, + 15110, 637, + 15242, 1292, + 15351, 413, + 15430, 843, + 15700, 541, + 15776, 204, + 15964, 335, + 15992, 688, + 16077, 453, + 16315, 4617, + 16406, 1032, + 16549, 595, + 16666, 384, + 16850, 776, + 16851, 482, + 16916, 253, + 17234, 309, + 17307, 2128, + 17469, 546, + 17666, 643, + 17699, 421, + 17852, 882, + 17870, 146, + 18146, 1244, + 18457, 489, + 18478, 346, + 18588, 723, + 18826, 208, + 19011, 1731, + 19042, 586, + 19286, 281, + 19428, 944, + 19446, 382, + 19555, 444, + 19689, 792, + 19755, 1111, + 19762, 527, + 19769, 1405, + 19774, 657, + 19780, 2675, +}; + +const Word16 gp_gamma_2sfr_6b_fx[2 * 64] = /*Q14/Q9 */ +{ + 185, 306, + 435, 519, + 458, 145, + 1000, 211, + 1217, 394, + 1241, 751, + 1788, 93, + 2026, 1234, + 2162, 265, + 2397, 158, + 2617, 472, + 3324, 340, + 3391, 623, + 3835, 207, + 4503, 17210, + 4628, 407, + 4939, 897, + 5102, 275, + 5300, 120, + 5560, 511, + 6309, 1909, + 6571, 335, + 6770, 205, + 6990, 642, + 7085, 5087, + 7500, 428, + 8357, 827, + 8452, 261, + 9079, 537, + 9289, 354, + 9854, 1176, + 9864, 165, + 10436, 8580, + 10549, 437, + 10615, 677, + 11010, 282, + 11940, 530, + 12183, 367, + 12475, 920, + 12865, 225, + 13359, 618, + 13431, 441, + 13521, 1623, + 14177, 341, + 14299, 130, + 14452, 775, + 14799, 508, + 15250, 276, + 15715, 1130, + 15757, 660, + 15879, 422, + 16355, 3256, + 16439, 187, + 16751, 562, + 16906, 331, + 17178, 827, + 17889, 471, + 18219, 2175, + 18786, 248, + 18985, 1354, + 19067, 703, + 19220, 384, + 19349, 954, + 19422, 553, +}; +const Word16 gp_gamma_3sfr_6b_fx[2 * 64] = /*Q14/Q9 */ +{ + 195, 150, + 817, 288, + 1152, 616, + 1366, 188, + 1377, 410, + 1526, 902, + 1570, 98, + 2258, 238, + 2489, 518, + 2935, 338, + 3142, 161, + 3456, 1705, + 3990, 432, + 4159, 709, + 4187, 270, + 4374, 1236, + 5283, 526, + 5431, 131, + 5507, 356, + 5762, 211, + 6792, 620, + 6842, 446, + 6969, 304, + 7671, 807, + 8362, 245, + 8448, 530, + 8610, 380, + 9314, 1088, + 9828, 170, + 9921, 7010, + 10026, 459, + 10193, 312, + 10261, 658, + 11554, 394, + 11739, 882, + 11791, 542, + 11985, 4329, + 11996, 246, + 12762, 13441, + 12844, 1512, + 13131, 465, + 13135, 339, + 13215, 740, + 14138, 608, + 14524, 417, + 14780, 1030, + 14823, 283, + 15016, 171, + 15264, 527, + 15823, 2706, + 15943, 699, + 15959, 360, + 16350, 473, + 17211, 573, + 17366, 901, + 17517, 238, + 17799, 414, + 18069, 1415, + 18630, 1920, + 18887, 634, + 19018, 318, + 19304, 495, + 19400, 1114, + 19413, 767, +}; + + +const Word16 gp_gamma_4sfr_6b_fx[2 * 64] = /*Q14/Q9 */ +{ + 153, 141, + 282, 501, + 399, 239, + 783, 369, + 1110, 744, + 1430, 183, + 1440, 1748, + 1524, 1091, + 1602, 296, + 1828, 99, + 2000, 439, + 2678, 228, + 2815, 600, + 3084, 347, + 3861, 477, + 4154, 163, + 4214, 285, + 4428, 733, + 4976, 384, + 5482, 566, + 5552, 234, + 6158, 929, + 6536, 470, + 6560, 326, + 7288, 173, + 7429, 663, + 7447, 10616, + 7871, 407, + 8457, 266, + 8559, 550, + 8679, 1421, + 9457, 356, + 9533, 785, + 9854, 471, + 10584, 5781, + 10792, 3815, + 10813, 206, + 10829, 302, + 10986, 606, + 11380, 433, + 11468, 1073, + 12485, 356, + 12726, 520, + 12783, 721, + 13554, 259, + 13763, 139, + 13884, 430, + 14060, 2592, + 14266, 599, + 14332, 925, + 14997, 337, + 15355, 485, + 15526, 712, + 16440, 587, + 16504, 395, + 16626, 204, + 17228, 1287, + 17563, 805, + 17629, 517, + 18159, 1814, + 18320, 303, + 19228, 437, + 19263, 636, + 19417, 989, +}; + + /*----------------------------------------------------------------------------------* * Transition coding - gain quantization table @@ -4241,7 +6014,17 @@ const float tbl_gain_code_tc[N_GAIN_CODE_TC] = 2.0743f, 3.3301f }; - +const Word16 tbl_gain_code_tc_fx[N_GAIN_CODE_TC] = /*q13 */ +{ + 2966, + 5930, + 7924, + 9712, + 11566, + 13754, + 16993, + 27280 +}; /*-----------------------------------------------------------------* * Transition coding - gain quantization table for g_trans *-----------------------------------------------------------------*/ @@ -4257,7 +6040,11 @@ const float tbl_gain_trans_tc[N_GAIN_TC] = 819.6746f, 1500.0f }; - +const Word16 tbl_gain_trans_tc_fx[N_GAIN_TC] = +{ + 4588, 11109, 19212, 29862,/*<- Q7 +Q4 ->*/ 5536, 8184, 13115, 24000 +}; /*-----------------------------------------------------------------* * Transition coding - table of prototype glottal impulses *-----------------------------------------------------------------*/ @@ -4297,6 +6084,48 @@ const float glottal_cdbk[L_IMPULSE*NUM_IMPULSE] = -0.3975f, 0.2925f, 0.9839f, 0.6334f, -0.0121f, -0.0045f, 0.1349f, -0.0815f, -0.1751f, -0.0072f, -0.0099f }; +const Word16 Glottal_cdbk_fx[L_IMPULSE*NUM_IMPULSE] = /*Q13*/ +{ + /* impulse 0 */ + -715, -1690, -2903, -1742, -1295, -4266, + -4893, 1725, 8192, 5812, -628, -1956, + 581, 936, -81, 831, 1517, + + /* impulse 1 */ + -2168, -1356, -404, -2715, -4469, -2164, + -2180, -8058, -9140, 1163, 10343, 6677, + -1758, -2839, 377, 326, -490, + + /* impulse 2 */ + 360, 561, 4184, 2533, -3326, -2549, + 2059, -2112, -9542, -6134, 1307, 124, + -3421, -1465, 475, -886, -1262, + + /* impulse 3 */ + -1294, -715, -184, -1544, -1638, -219, + -3503, -9409, -7955, -1407, -285, -2494, + 305, 4658, 3289, 116, 1488, + + /* impulse 4 */ + 837, 2523, 2444, 2679, 5962, 6935, + -924, -9907, -7565, 643, 1350, -2577, + -2100, -277, -1546, -2279, -882, + + /* impulse 5 */ + -418, -886, -48, -494, -2368, -2060, + -1233, -5271,-10430, -6955, 3301, 7578, + 2599, -1665, -461, 735, -181, + + /* impulse 6 */ + -467, -1865, -1455, -127, -1881, -3776, + 822, 8335, 8192, 863, -2762, -375, + 757, -558, -285, 653, 150, + + /* impulse 7 */ + 1087, 471, -618, 706, 1546, -1605, + -3256, 2396, 8060, 5189, -99, -37, + 1105, -668, -1434, -59, -81 +}; /*----------------------------------------------------------------------------------* * AMR-WB IO WB BWE - deemphasis @@ -4313,6 +6142,17 @@ const float deem_tab[56] = 0.597360736860508f, 0.597067605984399f, 0.596796395803217f, 0.596547058296428f, 0.596319549358454f, 0.596113828780239f, 0.595929860232466f, 0.595767611250409f, 0.595627053220407f, 0.595508161367956f, 0.595410914747406f, 0.595335296233253f, 0.595281292513031f, 0.595248894081778f }; +const Word16 deem_tab_fx[56] = +{ + 20668, 20625, 20583, 20541, 20501, 20462, 20423, 20385, + 20348, 20313, 20277, 20243, 20210, 20177, 20146, 20115, + 20085, 20055, 20027, 19999, 19972, 19946, 19921, 19896, + 19873, 19850, 19827, 19806, 19785, 19766, 19746, 19728, + 19710, 19693, 19677, 19662, 19647, 19633, 19620, 19607, + 19596, 19585, 19574, 19565, 19556, 19548, 19540, 19533, + 19527, 19522, 19518, 19514, 19510, 19508, 19506, 19505 +}; + const float filt_hp[56] = { @@ -4327,6 +6167,16 @@ const float filt_hp[56] = 0.899298867069991f, 0.916826276367851f, 0.933053294896263f, 0.947917712517199f, 0.961362480671352f, 0.973335999426038f, 0.983792375705577f, 0.992691651376520f }; +const Word16 filt_hp_fx[56] = +{ + 53, 153, 274, 415, 578, 765, 978, 1217, 1483, 1778, 2102, + 2457, 2843, 3261, 3710, 4192, 4706, 5252, 5829, 6438, 7077, + 7746, 8443, 9168, 9918, 10693, 11489, 12306, 13141, 13992, + 14856, 15732, 16615, 17504, 18395, 19287, 20174, 21056, 21928, + 22787, 23631, 24456, 25260, 26039, 26791, 27512, 28201, 28853, + 29468, 30043, 30574, 31061, 31502, 31894, 32237, 32529 +}; + /* table of values exp(-j*w*i) */ const float exp_tab_q[34] = @@ -4341,6 +6191,18 @@ const float exp_tab_q[34] = -0.831469612302543f, 0.707106781186542f, -0.555570233019599f, 0.382683432365084f, -0.195090322016126f, -0.000000000000005f }; +const Word16 exp_tab_q_fx[34] = /*Q14 */ +{ + 16384, -16068, 15137, -13622, + 11585, -9101, 6270, -3195, + 0, 3196, -6269, 9102, + -11584, 13623, -15136, 16069, + -16383, 0, -3195, 6270, + -9101, 11585, -13622, 15137, + -16068, 16384, -16068, 15137, + -13622, 11585, -9101, 6270, + -3195, 0 +}; const float exp_tab_p[34] = { @@ -4354,7 +6216,18 @@ const float exp_tab_p[34] = -0.707106781186548f, 0.000000000000000f, 0.707106781186549f, -1.000000000000000f, 0.707106781186547f, 0.000000000000000f }; - +const Word16 exp_tab_p_fx[34] = /*Q14 */ +{ + 16384, -11584, 0, 11585, + -16383, 11585, 0, -11584, + 16384, -11584, 0, 11585, + -16383, 11585, 0, -11584, + 16384, 0, -11584, 16384, + -11584, 0, 11585, -16383, + 11585, 0, -11584, 16384, + -11584, 0, 11585, -16383, + 11585, 0 +}; /* gains for 23k85 mode */ const float HP_gain[16] = { @@ -4364,7 +6237,11 @@ const float HP_gain[16] = 0.342102050781250f, 0.372497558593750f, 0.408660888671875f, 0.453002929687500f, 0.511779785156250f, 0.599822998046875f, 0.741241455078125f, 0.998779296875000f }; - +const Word16 HP_gain_fx[16] = +{ + 3624, 4673, 5597, 6479, 7425, 8378, 9324, 10264, + 11210, 12206, 13391, 14844, 16770, 19655, 24289, 32728 +}; /* band-pass 6-8kHz filter */ const float fir_6k_8k[31]= { @@ -4418,7 +6295,16 @@ const float fir_6k_7k[31] = 0.034231f, -0.011296f, -0.000863f, 0.000965f, 0.001428f, -0.001005f }; - +const Word16 fir_6k_7k_fx[31] = +{ + -32, 47, 32, -27, -369, + 1122, -1421, 0, 3798, -8880, + 12349, -10984, 3548, 7766, -18001, + 22118, -18001, 7766, 3548, -10984, + 12349, -8880, 3798, 0, -1421, + 1122, -369, -27, 32, 47, + -32 +}; const Word16 no_lead_fx[][MAX_NO_SCALES * 2] = { { 1, 0, 0, 1, 0, 0, }, /* 14 */ @@ -4726,7 +6612,7 @@ const Word16 no_lead_p_fx[][MAX_NO_SCALES * 2] = * Enhacer - 2.0 - 6.4 kHz impulse response with phase dispersion in freq. domain *----------------------------------------------------------------------------------*/ -const float low_H[L_SUBFR] = +const float low_H_flt[L_SUBFR] = { 1.000300f, 0.999812f, 1.000125f, 0.999868f, 0.999879f, 0.999935f, 0.999838f, 0.999992f, 1.000076f, 0.626554f, 0.619763f, 0.603882f, 0.857647f, 0.997470f, -0.032403f, 0.806652f, 0.999300f, 0.946634f, 0.574139f, 0.973425f, 0.288464f, 0.890704f, 0.635021f, 0.597882f, -0.997076f, -0.110774f, -0.648392f, 0.771888f, 0.888411f, -0.774123f, @@ -4734,12 +6620,33 @@ const float low_H[L_SUBFR] = -0.229682f, -0.818972f, -0.322274f, 0.031800f, -0.591141f, -0.999439f, -0.074385f, 0.514882f, -0.797032f, -0.784999f, -0.779712f, -0.000028f, 0.000164f, 0.000029f, -0.000135f, -0.000047f, -0.000033f, -0.000080f, 0.000099f }; +const Word16 low_H[64] = /* (1Q14) */ +{ + 16388, 16380, 16386, 16381, 16382, 16382, 16381, 16383, 16385, 10265, + 10154, 9894, 14051, 16342, -531, 13216, 16372, 15509, 9406, 15948, + 4726, 14593, 10404, 9795, -16337, -1815, -10624, 12646, 14555, -12684, + 11388, 8175, 16382, -14198, 11781, 10378, 7515, 10423, -12473, 16284, + -1200, -13137, 12658, -7446, 15683, -3764, -13419, -5281, 521, -9686, + -16375, -1219, 8435, -13059, -12862, -12775, -1, 2, 0, -3, + -1, -1, -2, 1 +}; +const Word16 low_H16k[80] = /* (1Q14) */ +{ + 16388, 16380, 16386, 16381, 16382, 16382, 16381, 16383, 16385, 10265, + 10154, 9894, 14051, 16342, -531, 13216, 16372, 15509, 9406, 15948, + 4726, 14593, 10404, 9795, -16337, -1815, -10624, 12646, 14555, -12684, + 11388, 8175, -4121, -13408, 10605, -12308, 16358, 4699, 7640, -7360, + 16382, -14639, -14494, 15695, -907, -10815, -12489, 9416, 15857, + -14198, 11781, 10378, 7515, 10423, -12473, 16284, -1200, -13137, 12658, + -7446, 15683, -3764, -13419, -5281, 521, -9686, -16375, -1219, 8435, + -13059, -12862, -12775, -1, 2, 0, -3, -1, -1, -2, 1 +}; /*----------------------------------------------------------------------------------* * Enhancer - 3.2 - 6.4 kHz impulse response with phase dispersion in freq. domain *----------------------------------------------------------------------------------*/ -const float mid_H[L_SUBFR] = +const float mid_H_flt[L_SUBFR] = { 0.999900f, 0.999848f, 1.000003f, 1.000048f, 1.000107f, 1.000242f, 1.000165f, 0.999909f, 1.000212f, 0.999933f, 1.000099f, 1.000100f, 1.000113f, 1.000018f, 0.999901f, 1.000267f, 0.906200f, 0.587715f, 0.808629f, 0.884216f, 0.671089f, 0.039238f, 0.843369f, 0.841006f, 0.394788f, 0.528863f, 0.710110f, 0.596973f, -0.893309f, -0.059908f, 0.716925f, -0.044067f, @@ -4747,6 +6654,28 @@ const float mid_H[L_SUBFR] = -0.808928f, -0.422500f, 0.000219f, -0.000261f, -0.000086f, -0.000313f, 0.000080f, 0.000406f, 0.000351f, -0.000449f, -0.000065f, 0.000214f, -0.000254f, 0.000002f, -0.000090f, -0.000198f, 0.000193f }; +const Word16 mid_H[64] = /* (1Q14) */ +{ + 16382, 16381, 16384, 16384, 16385, 16387, 16386, 16382, 16387, 16382, + 16385, 16385, 16385, 16384, 16382, 16388, 14847, 9629, 13248, 14486, + 10995, 642, 13817, 13779, 6468, 8664, 11634, 9780, -14636, -982, + 11746, -722, 16385, -16366, -11423, 16354, 7362, 13147, -11538, -13904, + -15052, -8862, 8811, -16371, -12146, 7660, -9638, -13254, -6923, 3, + -5, -2, -6, 1, 6, 5, -8, -2, 3, -5, + 0, -2, -4, 3 +}; + +const Word16 mid_H16k[80] = /* (1Q14) */ +{ + 16382, 16381, 16384, 16384, 16385, 16387, 16386, 16382, 16387, 16382, + 16385, 16385, 16385, 16384, 16382, 16388, 14847, 9629, 13248, 14486, + 10995, 642, 13817, 13779, 6468, 8664, 11634, 9780, -14636, -982, + 11746, -722, 108, -16195, -13199, -13289, 5114, 12941, 7110, 8873, + 16385, -13774, -14761, 10047, -15566, -9584, 9707, 2483, 16383, + -16366, -11423, 16354, 7362, 13147, -11538, -13904, -15052, -8862, + 8811, -16371, -12146, 7660, -9638, -13254, -6923, 3, -5, -2, -6, + 1, 6, 5, -8, -2, 3, -5, 0, -2, -4, 3 +}; /*-------------------------------------------------------------------* * Low-pass FIR filter for low-freq post-filtering @@ -5318,6 +7247,558 @@ const float edct_table_600[600] = 0.00396701f, 0.00343813f, 0.00290923f, 0.00238031f, 0.00185137f, 0.00132241f, 0.00079345f, 0.00026448f }; +//Fix +const Word16 edct_table_80_fx[80] = /*Q16 */ +{ + 21911, 21903, 21886, 21860, 21827, 21784, 21734, 21675, + 21608, 21532, 21448, 21356, 21255, 21147, 21030, 20905, + 20772, 20631, 20482, 20325, 20161, 19988, 19808, 19621, + 19425, 19222, 19012, 18795, 18570, 18338, 18099, 17853, + 17600, 17340, 17074, 16801, 16522, 16236, 15944, 15646, + 15341, 15031, 14715, 14394, 14067, 13734, 13396, 13053, + 12705, 12352, 11994, 11632, 11265, 10894, 10519, 10139, + 9756, 9369, 8978, 8584, 8186, 7786, 7382, 6975, + 6566, 6155, 5741, 5324, 4906, 4486, 4064, 3640, + 3215, 2789, 2362, 1934, 1505, 1075, 645, 215 +}; + +const Word16 edct_table_100_fx[] = +{ + 20723, 20718, 20708, 20692, 20672, 20646, 20616, 20580, + 20539, 20493, 20442, 20386, 20325, 20259, 20188, 20112, + 20031, 19946, 19855, 19759, 19658, 19553, 19443, 19328, + 19208, 19083, 18954, 18820, 18681, 18538, 18390, 18238, + 18081, 17920, 17754, 17584, 17410, 17231, 17048, 16861, + 16670, 16474, 16275, 16071, 15864, 15652, 15437, 15218, + 14995, 14768, 14538, 14304, 14067, 13826, 13582, 13335, + 13084, 12830, 12573, 12312, 12049, 11783, 11513, 11241, + 10966, 10689, 10409, 10126, 9841, 9553, 9263, 8971, + 8676, 8379, 8081, 7780, 7477, 7173, 6867, 6559, + 6249, 5938, 5625, 5311, 4996, 4679, 4362, 4043, + 3723, 3403, 3081, 2759, 2436, 2112, 1788, 1464, + 1139, 814, 488, 163 +}; + +const Word16 edct_table_120_fx[120] = /*Q16 */ +{ + 19800, 19797, 19790, 19780, 19766, 19749, 19729, 19705, + 19678, 19648, 19614, 19576, 19536, 19492, 19445, 19394, + 19340, 19283, 19223, 19159, 19092, 19021, 18948, 18871, + 18791, 18708, 18621, 18531, 18438, 18342, 18243, 18141, + 18035, 17927, 17815, 17701, 17583, 17462, 17339, 17212, + 17082, 16950, 16815, 16676, 16535, 16391, 16244, 16095, + 15942, 15787, 15629, 15469, 15306, 15140, 14972, 14801, + 14628, 14452, 14273, 14092, 13909, 13723, 13535, 13345, + 13152, 12958, 12761, 12561, 12360, 12156, 11951, 11743, + 11533, 11322, 11108, 10893, 10675, 10456, 10235, 10012, + 9788, 9562, 9334, 9104, 8874, 8641, 8407, 8172, + 7935, 7697, 7457, 7217, 6975, 6732, 6487, 6242, + 5995, 5748, 5499, 5250, 4999, 4748, 4496, 4243, + 3990, 3736, 3481, 3225, 2969, 2713, 2456, 2199, + 1941, 1683, 1424, 1166, 907, 648, 389, 130 +}; + +const Word16 edct_table_320_fx[320] = /*Q16 */ +{ + 15495, 15495, 15494, 15493, 15491, 15489, 15487, 15484, + 15481, 15478, 15474, 15470, 15466, 15461, 15456, 15450, + 15444, 15438, 15431, 15424, 15417, 15409, 15401, 15392, + 15383, 15374, 15364, 15354, 15344, 15333, 15322, 15310, + 15298, 15286, 15273, 15260, 15247, 15233, 15219, 15205, + 15190, 15175, 15159, 15143, 15127, 15110, 15093, 15076, + 15058, 15040, 15021, 15002, 14983, 14964, 14944, 14924, + 14903, 14882, 14860, 14839, 14817, 14794, 14771, 14748, + 14725, 14701, 14677, 14652, 14627, 14602, 14576, 14550, + 14524, 14497, 14470, 14443, 14415, 14387, 14359, 14330, + 14301, 14271, 14242, 14212, 14181, 14150, 14119, 14088, + 14056, 14024, 13991, 13958, 13925, 13891, 13858, 13823, + 13789, 13754, 13719, 13683, 13647, 13611, 13575, 13538, + 13501, 13463, 13425, 13387, 13349, 13310, 13271, 13231, + 13192, 13152, 13111, 13071, 13030, 12988, 12947, 12905, + 12862, 12820, 12777, 12734, 12690, 12647, 12602, 12558, + 12513, 12468, 12423, 12377, 12331, 12285, 12239, 12192, + 12145, 12098, 12050, 12002, 11954, 11905, 11856, 11807, + 11758, 11708, 11658, 11608, 11557, 11507, 11455, 11404, + 11352, 11301, 11248, 11196, 11143, 11090, 11037, 10983, + 10930, 10876, 10821, 10767, 10712, 10657, 10601, 10546, + 10490, 10434, 10378, 10321, 10264, 10207, 10150, 10092, + 10034, 9976, 9918, 9859, 9800, 9741, 9682, 9623, + 9563, 9503, 9443, 9382, 9322, 9261, 9200, 9138, + 9077, 9015, 8953, 8891, 8829, 8766, 8703, 8640, + 8577, 8513, 8450, 8386, 8322, 8258, 8193, 8129, + 8064, 7999, 7933, 7868, 7802, 7737, 7671, 7604, + 7538, 7471, 7405, 7338, 7271, 7203, 7136, 7068, + 7001, 6933, 6865, 6796, 6728, 6659, 6591, 6522, + 6453, 6383, 6314, 6244, 6175, 6105, 6035, 5965, + 5895, 5824, 5754, 5683, 5612, 5541, 5470, 5399, + 5327, 5256, 5184, 5113, 5041, 4969, 4897, 4824, + 4752, 4680, 4607, 4534, 4462, 4389, 4316, 4243, + 4169, 4096, 4023, 3949, 3876, 3802, 3728, 3654, + 3580, 3506, 3432, 3358, 3284, 3209, 3135, 3060, + 2986, 2911, 2836, 2761, 2687, 2612, 2537, 2462, + 2386, 2311, 2236, 2161, 2085, 2010, 1934, 1859, + 1783, 1708, 1632, 1557, 1481, 1405, 1329, 1254, + 1178, 1102, 1026, 950, 874, 798, 722, 646, + 570, 494, 418, 342, 266, 190, 114, 38 +}; + +const Word16 edct_table_480_fx[480] = /*Q16 */ +{ + 14001, 14001, 14001, 14000, 14000, 13999, 13998, 13997, + 13996, 13995, 13993, 13991, 13990, 13988, 13986, 13983, + 13981, 13978, 13976, 13973, 13970, 13967, 13963, 13960, + 13956, 13953, 13949, 13945, 13940, 13936, 13932, 13927, + 13922, 13917, 13912, 13907, 13902, 13896, 13890, 13885, + 13879, 13872, 13866, 13860, 13853, 13846, 13840, 13833, + 13825, 13818, 13811, 13803, 13795, 13787, 13779, 13771, + 13763, 13754, 13746, 13737, 13728, 13719, 13709, 13700, + 13691, 13681, 13671, 13661, 13651, 13641, 13630, 13620, + 13609, 13598, 13587, 13576, 13565, 13553, 13542, 13530, + 13518, 13506, 13494, 13482, 13469, 13457, 13444, 13431, + 13418, 13405, 13392, 13378, 13365, 13351, 13337, 13323, + 13309, 13295, 13280, 13266, 13251, 13236, 13221, 13206, + 13191, 13175, 13160, 13144, 13128, 13112, 13096, 13080, + 13063, 13047, 13030, 13013, 12996, 12979, 12962, 12944, + 12927, 12909, 12891, 12873, 12855, 12837, 12819, 12800, + 12782, 12763, 12744, 12725, 12706, 12686, 12667, 12647, + 12628, 12608, 12588, 12568, 12547, 12527, 12506, 12486, + 12465, 12444, 12423, 12402, 12380, 12359, 12337, 12316, + 12294, 12272, 12250, 12227, 12205, 12182, 12160, 12137, + 12114, 12091, 12068, 12045, 12021, 11998, 11974, 11950, + 11926, 11902, 11878, 11854, 11829, 11804, 11780, 11755, + 11730, 11705, 11680, 11654, 11629, 11603, 11578, 11552, + 11526, 11500, 11474, 11447, 11421, 11394, 11368, 11341, + 11314, 11287, 11260, 11232, 11205, 11177, 11150, 11122, + 11094, 11066, 11038, 11010, 10981, 10953, 10924, 10895, + 10867, 10838, 10809, 10779, 10750, 10721, 10691, 10662, + 10632, 10602, 10572, 10542, 10512, 10481, 10451, 10420, + 10390, 10359, 10328, 10297, 10266, 10235, 10203, 10172, + 10140, 10109, 10077, 10045, 10013, 9981, 9949, 9917, + 9884, 9852, 9819, 9786, 9754, 9721, 9688, 9654, + 9621, 9588, 9554, 9521, 9487, 9454, 9420, 9386, + 9352, 9318, 9283, 9249, 9214, 9180, 9145, 9111, + 9076, 9041, 9006, 8971, 8935, 8900, 8865, 8829, + 8794, 8758, 8722, 8686, 8650, 8614, 8578, 8542, + 8505, 8469, 8432, 8396, 8359, 8322, 8285, 8248, + 8211, 8174, 8137, 8099, 8062, 8025, 7987, 7949, + 7912, 7874, 7836, 7798, 7760, 7721, 7683, 7645, + 7606, 7568, 7529, 7491, 7452, 7413, 7374, 7335, + 7296, 7257, 7218, 7178, 7139, 7100, 7060, 7020, + 6981, 6941, 6901, 6861, 6821, 6781, 6741, 6701, + 6661, 6620, 6580, 6539, 6499, 6458, 6418, 6377, + 6336, 6295, 6254, 6213, 6172, 6131, 6090, 6048, + 6007, 5966, 5924, 5883, 5841, 5799, 5758, 5716, + 5674, 5632, 5590, 5548, 5506, 5464, 5422, 5379, + 5337, 5295, 5252, 5210, 5167, 5124, 5082, 5039, + 4996, 4953, 4911, 4868, 4825, 4782, 4738, 4695, + 4652, 4609, 4566, 4522, 4479, 4435, 4392, 4348, + 4305, 4261, 4218, 4174, 4130, 4086, 4042, 3999, + 3955, 3911, 3867, 3823, 3778, 3734, 3690, 3646, + 3602, 3557, 3513, 3469, 3424, 3380, 3335, 3291, + 3246, 3202, 3157, 3112, 3068, 3023, 2978, 2933, + 2889, 2844, 2799, 2754, 2709, 2664, 2619, 2574, + 2529, 2484, 2439, 2394, 2349, 2303, 2258, 2213, + 2168, 2122, 2077, 2032, 1986, 1941, 1896, 1850, + 1805, 1759, 1714, 1668, 1623, 1577, 1532, 1486, + 1441, 1395, 1350, 1304, 1258, 1213, 1167, 1121, + 1076, 1030, 984, 939, 893, 847, 801, 756, + 710, 664, 618, 573, 527, 481, 435, 389, + 344, 298, 252, 206, 160, 115, 69, 23 +}; + +const Word16 edct_table_600_fx[] = +{ + 26483, 26483, 26483, 26482, 26481, 26481, 26479, 26478, + 26477, 26475, 26473, 26471, 26469, 26467, 26464, 26461, + 26459, 26455, 26452, 26449, 26445, 26441, 26437, 26433, + 26429, 26424, 26420, 26415, 26410, 26404, 26399, 26393, + 26387, 26381, 26375, 26369, 26362, 26356, 26349, 26342, + 26335, 26327, 26320, 26312, 26304, 26296, 26287, 26279, + 26270, 26261, 26252, 26243, 26234, 26224, 26214, 26204, + 26194, 26184, 26173, 26163, 26152, 26141, 26130, 26118, + 26107, 26095, 26083, 26071, 26059, 26046, 26033, 26021, + 26008, 25994, 25981, 25968, 25954, 25940, 25926, 25912, + 25897, 25883, 25868, 25853, 25838, 25823, 25807, 25791, + 25776, 25760, 25743, 25727, 25711, 25694, 25677, 25660, + 25643, 25625, 25608, 25590, 25572, 25554, 25535, 25517, + 25498, 25480, 25461, 25441, 25422, 25403, 25383, 25363, + 25343, 25323, 25302, 25282, 25261, 25240, 25219, 25198, + 25176, 25155, 25133, 25111, 25089, 25067, 25044, 25022, + 24999, 24976, 24953, 24929, 24906, 24882, 24858, 24834, + 24810, 24786, 24761, 24737, 24712, 24687, 24662, 24636, + 24611, 24585, 24559, 24533, 24507, 24481, 24454, 24427, + 24401, 24373, 24346, 24319, 24291, 24264, 24236, 24208, + 24180, 24151, 24123, 24094, 24065, 24036, 24007, 23978, + 23948, 23918, 23888, 23858, 23828, 23798, 23767, 23737, + 23706, 23675, 23644, 23612, 23581, 23549, 23518, 23486, + 23453, 23421, 23389, 23356, 23323, 23290, 23257, 23224, + 23191, 23157, 23123, 23090, 23056, 23021, 22987, 22953, + 22918, 22883, 22848, 22813, 22778, 22742, 22707, 22671, + 22635, 22599, 22563, 22526, 22490, 22453, 22416, 22379, + 22342, 22305, 22267, 22230, 22192, 22154, 22116, 22078, + 22039, 22001, 21962, 21923, 21884, 21845, 21806, 21766, + 21727, 21687, 21647, 21607, 21567, 21527, 21486, 21446, + 21405, 21364, 21323, 21282, 21241, 21199, 21157, 21116, + 21074, 21032, 20989, 20947, 20905, 20862, 20819, 20776, + 20733, 20690, 20647, 20603, 20560, 20516, 20472, 20428, + 20384, 20339, 20295, 20250, 20205, 20161, 20116, 20070, + 20025, 19980, 19934, 19888, 19842, 19796, 19750, 19704, + 19658, 19611, 19565, 19518, 19471, 19424, 19377, 19329, + 19282, 19234, 19186, 19139, 19091, 19042, 18994, 18946, + 18897, 18849, 18800, 18751, 18702, 18653, 18604, 18554, + 18505, 18455, 18405, 18355, 18305, 18255, 18205, 18154, + 18104, 18053, 18002, 17951, 17900, 17849, 17798, 17747, + 17695, 17643, 17592, 17540, 17488, 17436, 17383, 17331, + 17278, 17226, 17173, 17120, 17067, 17014, 16961, 16908, + 16854, 16801, 16747, 16693, 16640, 16586, 16531, 16477, + 16423, 16368, 16314, 16259, 16204, 16149, 16094, 16039, + 15984, 15929, 15873, 15818, 15762, 15706, 15650, 15595, + 15538, 15482, 15426, 15370, 15313, 15256, 15200, 15143, + 15086, 15029, 14972, 14914, 14857, 14800, 14742, 14684, + 14627, 14569, 14511, 14453, 14395, 14336, 14278, 14220, + 14161, 14103, 14044, 13985, 13926, 13867, 13808, 13749, + 13689, 13630, 13570, 13511, 13451, 13391, 13332, 13272, + 13212, 13151, 13091, 13031, 12971, 12910, 12849, 12789, + 12728, 12667, 12606, 12545, 12484, 12423, 12362, 12300, + 12239, 12177, 12116, 12054, 11992, 11930, 11868, 11806, + 11744, 11682, 11620, 11558, 11495, 11433, 11370, 11307, + 11245, 11182, 11119, 11056, 10993, 10930, 10867, 10803, + 10740, 10677, 10613, 10550, 10486, 10422, 10358, 10295, + 10231, 10167, 10103, 10039, 9974, 9910, 9846, 9781, + 9717, 9652, 9588, 9523, 9458, 9394, 9329, 9264, + 9199, 9134, 9069, 9003, 8938, 8873, 8808, 8742, + 8677, 8611, 8546, 8480, 8414, 8348, 8283, 8217, + 8151, 8085, 8019, 7953, 7886, 7820, 7754, 7688, + 7621, 7555, 7488, 7422, 7355, 7289, 7222, 7155, + 7088, 7022, 6955, 6888, 6821, 6754, 6687, 6620, + 6553, 6485, 6418, 6351, 6283, 6216, 6149, 6081, + 6014, 5946, 5879, 5811, 5743, 5676, 5608, 5540, + 5472, 5404, 5337, 5269, 5201, 5133, 5065, 4997, + 4928, 4860, 4792, 4724, 4656, 4587, 4519, 4451, + 4382, 4314, 4246, 4177, 4109, 4040, 3972, 3903, + 3834, 3766, 3697, 3629, 3560, 3491, 3422, 3354, + 3285, 3216, 3147, 3078, 3009, 2941, 2872, 2803, + 2734, 2665, 2596, 2527, 2458, 2389, 2320, 2251, + 2182, 2112, 2043, 1974, 1905, 1836, 1767, 1697, + 1628, 1559, 1490, 1421, 1351, 1282, 1213, 1144, + 1074, 1005, 936, 867, 797, 728, 659, 589, + 520, 451, 381, 312, 243, 173, 104, 35 +}; + +const Word16 edct_table_128_fx[128] = /*Q16 */ +{ + 19483, 19480, 19474, 19466, 19454, 19439, 19422, 19401, + 19378, 19351, 19322, 19290, 19255, 19217, 19176, 19132, + 19086, 19036, 18984, 18928, 18870, 18809, 18746, 18679, + 18610, 18537, 18462, 18385, 18304, 18221, 18135, 18046, + 17954, 17860, 17763, 17664, 17561, 17457, 17349, 17239, + 17126, 17011, 16893, 16773, 16650, 16524, 16396, 16266, + 16133, 15998, 15860, 15720, 15578, 15433, 15286, 15137, + 14985, 14831, 14675, 14516, 14356, 14193, 14028, 13861, + 13692, 13521, 13348, 13173, 12996, 12816, 12635, 12452, + 12268, 12081, 11892, 11702, 11510, 11316, 11121, 10924, + 10725, 10524, 10322, 10119, 9914, 9707, 9499, 9290, + 9079, 8867, 8653, 8438, 8222, 8005, 7786, 7566, + 7345, 7123, 6900, 6676, 6451, 6225, 5998, 5770, + 5541, 5312, 5081, 4850, 4618, 4385, 4152, 3918, + 3684, 3449, 3213, 2977, 2741, 2504, 2266, 2029, + 1791, 1552, 1314, 1075, 837, 598, 359, 120 +}; + +const Word16 edct_table_160_fx[160] = /*Q16 */ +{ + 18426, 18425, 18421, 18416, 18409, 18400, 18389, 18377, + 18362, 18346, 18329, 18309, 18288, 18265, 18240, 18214, + 18185, 18155, 18123, 18090, 18055, 18018, 17979, 17938, + 17896, 17852, 17806, 17759, 17710, 17659, 17607, 17552, + 17497, 17439, 17380, 17319, 17256, 17192, 17126, 17058, + 16989, 16918, 16846, 16772, 16696, 16619, 16540, 16459, + 16377, 16293, 16208, 16121, 16033, 15943, 15851, 15758, + 15664, 15568, 15470, 15371, 15271, 15169, 15065, 14960, + 14854, 14746, 14637, 14527, 14415, 14301, 14186, 14070, + 13953, 13834, 13714, 13592, 13469, 13345, 13220, 13093, + 12965, 12836, 12706, 12574, 12441, 12307, 12172, 12036, + 11898, 11759, 11620, 11479, 11337, 11193, 11049, 10904, + 10758, 10610, 10462, 10312, 10162, 10011, 9858, 9705, + 9551, 9395, 9239, 9082, 8925, 8766, 8606, 8446, + 8285, 8123, 7960, 7797, 7632, 7467, 7301, 7135, + 6968, 6800, 6632, 6463, 6293, 6122, 5952, 5780, + 5608, 5435, 5262, 5089, 4915, 4740, 4565, 4389, + 4214, 4037, 3861, 3684, 3506, 3328, 3150, 2972, + 2793, 2614, 2435, 2256, 2076, 1896, 1716, 1536, + 1356, 1175, 994, 814, 633, 452, 271, 90 +}; + +const Word16 edct_table_40_fx[40] = /*Q16 */ +{ + 26049, 26009, 25928, 25808, 25648, 25448, 25210, 24932, + 24616, 24262, 23870, 23442, 22977, 22477, 21943, 21375, + 20773, 20140, 19475, 18781, 18058, 17306, 16528, 15725, + 14897, 14047, 13174, 12282, 11370, 10441, 9496, 8536, + 7563, 6578, 5584, 4580, 3570, 2554, 1534, 512 +}; + +const Word16 edct_table_20_fx[20] = /*Q16 */ +{ + 30939, 30749, 30368, 29801, 29049, 28119, 27015, 25745, + 24316, 22737, 21018, 19169, 17202, 15129, 12963, 10717, + 8405, 6041, 3639, 1216 +}; + + +const Word16 edct_table_64_fx[] = +{ + 23167, 23153, 23125, 23083, 23027, 22958, 22874, 22777, + 22666, 22542, 22403, 22252, 22087, 21908, 21717, 21512, + 21295, 21064, 20821, 20565, 20297, 20017, 19725, 19420, + 19105, 18777, 18438, 18089, 17728, 17356, 16975, 16582, + 16180, 15769, 15347, 14917, 14477, 14029, 13572, 13107, + 12634, 12154, 11666, 11171, 10670, 10162, 9648, 9128, + 8603, 8072, 7537, 6997, 6453, 5905, 5353, 4798, + 4241, 3681, 3118, 2554, 1988, 1421, 853, 284 +}; + + +const Word16 edct_table_200_fx[] = +{ + 17427, 17426, 17423, 17420, 17416, 17411, 17404, 17397, + 17388, 17378, 17368, 17356, 17343, 17329, 17314, 17298, + 17281, 17262, 17243, 17223, 17201, 17179, 17155, 17131, + 17105, 17079, 17051, 17022, 16992, 16961, 16929, 16896, + 16862, 16827, 16791, 16754, 16716, 16676, 16636, 16595, + 16553, 16509, 16465, 16420, 16373, 16326, 16278, 16228, + 16178, 16126, 16074, 16021, 15966, 15911, 15855, 15797, + 15739, 15680, 15620, 15558, 15496, 15433, 15369, 15304, + 15238, 15171, 15103, 15035, 14965, 14894, 14823, 14751, + 14677, 14603, 14528, 14452, 14375, 14297, 14218, 14139, + 14058, 13977, 13895, 13812, 13728, 13643, 13558, 13471, + 13384, 13296, 13207, 13117, 13027, 12935, 12843, 12750, + 12657, 12562, 12467, 12371, 12274, 12177, 12078, 11979, + 11880, 11779, 11678, 11576, 11473, 11370, 11266, 11161, + 11055, 10949, 10843, 10735, 10627, 10518, 10409, 10299, + 10188, 10076, 9964, 9852, 9739, 9625, 9510, 9395, + 9280, 9164, 9047, 8930, 8812, 8694, 8575, 8455, + 8335, 8215, 8094, 7973, 7851, 7728, 7605, 7482, + 7358, 7234, 7109, 6984, 6858, 6732, 6606, 6479, + 6352, 6224, 6096, 5967, 5839, 5710, 5580, 5450, + 5320, 5190, 5059, 4928, 4796, 4664, 4532, 4400, + 4268, 4135, 4002, 3868, 3735, 3601, 3467, 3333, + 3198, 3064, 2929, 2794, 2659, 2523, 2388, 2252, + 2116, 1980, 1844, 1708, 1572, 1436, 1299, 1163, + 1026, 889, 753, 616, 479, 342, 205, 68 +}; + +const Word16 edct_table_240_fx[] = +{ + 16650, 16650, 16648, 16646, 16643, 16640, 16635, 16630, + 16625, 16618, 16611, 16603, 16595, 16585, 16575, 16565, + 16553, 16541, 16528, 16515, 16501, 16486, 16470, 16454, + 16437, 16419, 16401, 16381, 16362, 16341, 16320, 16298, + 16275, 16252, 16228, 16203, 16178, 16151, 16125, 16097, + 16069, 16040, 16010, 15980, 15949, 15918, 15885, 15852, + 15819, 15784, 15749, 15713, 15677, 15640, 15602, 15564, + 15525, 15485, 15445, 15404, 15362, 15320, 15277, 15233, + 15189, 15144, 15098, 15052, 15005, 14957, 14909, 14860, + 14811, 14761, 14710, 14659, 14607, 14554, 14501, 14447, + 14392, 14337, 14282, 14225, 14168, 14111, 14053, 13994, + 13934, 13874, 13814, 13753, 13691, 13629, 13566, 13502, + 13438, 13374, 13309, 13243, 13176, 13109, 13042, 12974, + 12905, 12836, 12767, 12696, 12626, 12554, 12482, 12410, + 12337, 12264, 12190, 12115, 12040, 11965, 11889, 11812, + 11735, 11657, 11579, 11501, 11422, 11342, 11262, 11182, + 11101, 11019, 10937, 10855, 10772, 10689, 10605, 10521, + 10436, 10351, 10265, 10179, 10093, 10006, 9919, 9831, + 9743, 9654, 9565, 9476, 9386, 9296, 9205, 9114, + 9023, 8931, 8839, 8746, 8653, 8560, 8466, 8372, + 8278, 8183, 8088, 7993, 7897, 7801, 7704, 7608, + 7511, 7413, 7315, 7217, 7119, 7020, 6921, 6822, + 6723, 6623, 6523, 6422, 6321, 6221, 6119, 6018, + 5916, 5814, 5712, 5609, 5507, 5404, 5300, 5197, + 5093, 4990, 4885, 4781, 4677, 4572, 4467, 4362, + 4257, 4151, 4046, 3940, 3834, 3728, 3622, 3515, + 3408, 3302, 3195, 3088, 2981, 2873, 2766, 2658, + 2551, 2443, 2335, 2227, 2119, 2011, 1903, 1795, + 1686, 1578, 1469, 1361, 1252, 1143, 1035, 926, + 817, 708, 599, 490, 381, 272, 163, 54 +}; + +const Word16 edct_table_256_fx[] = +{ + 16384, 16383, 16382, 16380, 16378, 16375, 16371, 16367, + 16362, 16356, 16350, 16343, 16336, 16328, 16319, 16310, + 16300, 16290, 16278, 16267, 16254, 16242, 16228, 16214, + 16199, 16184, 16168, 16151, 16134, 16116, 16098, 16079, + 16059, 16039, 16018, 15997, 15975, 15952, 15929, 15905, + 15881, 15856, 15830, 15804, 15777, 15750, 15722, 15693, + 15664, 15634, 15604, 15573, 15541, 15509, 15476, 15443, + 15409, 15375, 15340, 15304, 15268, 15231, 15194, 15156, + 15117, 15078, 15039, 14999, 14958, 14917, 14875, 14832, + 14789, 14746, 14702, 14657, 14612, 14566, 14520, 14473, + 14426, 14378, 14329, 14280, 14231, 14181, 14130, 14079, + 14027, 13975, 13922, 13869, 13815, 13761, 13706, 13651, + 13595, 13538, 13481, 13424, 13366, 13308, 13249, 13190, + 13130, 13069, 13008, 12947, 12885, 12823, 12760, 12697, + 12633, 12569, 12504, 12439, 12373, 12307, 12240, 12173, + 12106, 12038, 11969, 11901, 11831, 11762, 11691, 11621, + 11550, 11478, 11406, 11334, 11261, 11188, 11114, 11040, + 10965, 10891, 10815, 10740, 10663, 10587, 10510, 10433, + 10355, 10277, 10198, 10119, 10040, 9961, 9881, 9800, + 9719, 9638, 9557, 9475, 9393, 9310, 9227, 9144, + 9061, 8977, 8892, 8808, 8723, 8638, 8552, 8466, + 8380, 8293, 8206, 8119, 8032, 7944, 7856, 7768, + 7679, 7590, 7501, 7411, 7321, 7231, 7141, 7050, + 6960, 6868, 6777, 6685, 6593, 6501, 6409, 6316, + 6223, 6130, 6037, 5943, 5850, 5756, 5661, 5567, + 5472, 5377, 5282, 5187, 5092, 4996, 4900, 4804, + 4708, 4611, 4515, 4418, 4321, 4224, 4127, 4030, + 3932, 3835, 3737, 3639, 3541, 3442, 3344, 3246, + 3147, 3048, 2949, 2851, 2751, 2652, 2553, 2454, + 2354, 2255, 2155, 2055, 1956, 1856, 1756, 1656, + 1556, 1456, 1356, 1255, 1155, 1055, 954, 854, + 754, 653, 553, 452, 352, 251, 151, 50 +}; + +const Word16 edct_table_400_fx[] = +{ + 29308, 29308, 29307, 29306, 29304, 29302, 29299, 29296, + 29292, 29288, 29284, 29279, 29273, 29267, 29261, 29254, + 29247, 29239, 29231, 29223, 29214, 29204, 29194, 29184, + 29173, 29162, 29150, 29138, 29125, 29112, 29099, 29085, + 29070, 29055, 29040, 29024, 29008, 28991, 28974, 28957, + 28939, 28920, 28901, 28882, 28862, 28842, 28821, 28800, + 28779, 28757, 28734, 28711, 28688, 28664, 28640, 28615, + 28590, 28565, 28539, 28512, 28485, 28458, 28430, 28402, + 28373, 28344, 28315, 28285, 28255, 28224, 28192, 28161, + 28129, 28096, 28063, 28030, 27996, 27962, 27927, 27892, + 27856, 27820, 27784, 27747, 27710, 27672, 27634, 27595, + 27556, 27517, 27477, 27437, 27396, 27355, 27313, 27272, + 27229, 27186, 27143, 27100, 27055, 27011, 26966, 26921, + 26875, 26829, 26782, 26736, 26688, 26640, 26592, 26544, + 26495, 26445, 26395, 26345, 26294, 26243, 26192, 26140, + 26088, 26035, 25982, 25929, 25875, 25821, 25766, 25711, + 25655, 25600, 25543, 25487, 25430, 25372, 25315, 25256, + 25198, 25139, 25079, 25020, 24960, 24899, 24838, 24777, + 24715, 24653, 24591, 24528, 24465, 24401, 24337, 24273, + 24208, 24143, 24078, 24012, 23946, 23879, 23812, 23745, + 23677, 23609, 23541, 23472, 23403, 23334, 23264, 23194, + 23123, 23052, 22981, 22909, 22837, 22765, 22692, 22619, + 22546, 22472, 22398, 22324, 22249, 22174, 22098, 22023, + 21947, 21870, 21793, 21716, 21639, 21561, 21483, 21404, + 21326, 21246, 21167, 21087, 21007, 20927, 20846, 20765, + 20684, 20602, 20520, 20437, 20355, 20272, 20189, 20105, + 20021, 19937, 19852, 19768, 19682, 19597, 19511, 19425, + 19339, 19252, 19165, 19078, 18991, 18903, 18815, 18726, + 18638, 18549, 18459, 18370, 18280, 18190, 18100, 18009, + 17918, 17827, 17735, 17643, 17551, 17459, 17366, 17274, + 17181, 17087, 16994, 16900, 16805, 16711, 16616, 16521, + 16426, 16331, 16235, 16139, 16043, 15946, 15850, 15753, + 15656, 15558, 15461, 15363, 15265, 15166, 15068, 14969, + 14870, 14770, 14671, 14571, 14471, 14371, 14271, 14170, + 14069, 13968, 13867, 13765, 13663, 13562, 13459, 13357, + 13254, 13152, 13049, 12946, 12842, 12739, 12635, 12531, + 12427, 12323, 12218, 12113, 12008, 11903, 11798, 11693, + 11587, 11481, 11375, 11269, 11163, 11056, 10950, 10843, + 10736, 10628, 10521, 10414, 10306, 10198, 10090, 9982, + 9874, 9765, 9657, 9548, 9439, 9330, 9221, 9112, + 9002, 8892, 8783, 8673, 8563, 8453, 8342, 8232, + 8122, 8011, 7900, 7789, 7678, 7567, 7456, 7344, + 7233, 7121, 7010, 6898, 6786, 6674, 6562, 6450, + 6337, 6225, 6112, 6000, 5887, 5774, 5661, 5548, + 5435, 5322, 5209, 5096, 4982, 4869, 4755, 4642, + 4528, 4414, 4300, 4187, 4073, 3959, 3845, 3730, + 3616, 3502, 3388, 3273, 3159, 3044, 2930, 2815, + 2701, 2586, 2472, 2357, 2242, 2127, 2013, 1898, + 1783, 1668, 1553, 1438, 1323, 1208, 1093, 978, + 863, 748, 633, 518, 403, 288, 173, 58 +}; + +const Word16 edct_table_320_16fx[320] = +{ + 7747, 7747, 7747, 7746, 7746, 7745, 7744, 7742, + 7741, 7739, 7737, 7735, 7733, 7730, 7728, 7725, + 7722, 7719, 7716, 7712, 7708, 7704, 7700, 7696, + 7692, 7687, 7682, 7677, 7672, 7666, 7661, 7655, + 7649, 7643, 7637, 7630, 7623, 7617, 7610, 7602, + 7595, 7587, 7580, 7572, 7563, 7555, 7547, 7538, + 7529, 7520, 7511, 7501, 7492, 7482, 7472, 7462, + 7451, 7441, 7430, 7419, 7408, 7397, 7386, 7374, + 7362, 7350, 7338, 7326, 7314, 7301, 7288, 7275, + 7262, 7249, 7235, 7221, 7208, 7194, 7179, 7165, + 7150, 7136, 7121, 7106, 7091, 7075, 7060, 7044, + 7028, 7012, 6995, 6979, 6962, 6946, 6929, 6912, + 6894, 6877, 6859, 6842, 6824, 6806, 6787, 6769, + 6750, 6732, 6713, 6694, 6674, 6655, 6635, 6616, + 6596, 6576, 6556, 6535, 6515, 6494, 6473, 6452, + 6431, 6410, 6388, 6367, 6345, 6323, 6301, 6279, + 6257, 6234, 6211, 6189, 6166, 6143, 6119, 6096, + 6072, 6049, 6025, 6001, 5977, 5953, 5928, 5904, + 5879, 5854, 5829, 5804, 5779, 5753, 5728, 5702, + 5676, 5650, 5624, 5598, 5572, 5545, 5518, 5492, + 5465, 5438, 5411, 5383, 5356, 5328, 5301, 5273, + 5245, 5217, 5189, 5160, 5132, 5104, 5075, 5046, + 5017, 4988, 4959, 4930, 4900, 4871, 4841, 4811, + 4781, 4751, 4721, 4691, 4661, 4630, 4600, 4569, + 4538, 4508, 4477, 4446, 4414, 4383, 4352, 4320, + 4288, 4257, 4225, 4193, 4161, 4129, 4097, 4064, + 4032, 3999, 3967, 3934, 3901, 3868, 3835, 3802, + 3769, 3736, 3702, 3669, 3635, 3602, 3568, 3534, + 3500, 3466, 3432, 3398, 3364, 3330, 3295, 3261, + 3226, 3192, 3157, 3122, 3087, 3052, 3017, 2982, + 2947, 2912, 2877, 2841, 2806, 2771, 2735, 2699, + 2664, 2628, 2592, 2556, 2520, 2484, 2448, 2412, + 2376, 2340, 2304, 2267, 2231, 2194, 2158, 2121, + 2085, 2048, 2011, 1975, 1938, 1901, 1864, 1827, + 1790, 1753, 1716, 1679, 1642, 1605, 1567, 1530, + 1493, 1455, 1418, 1381, 1343, 1306, 1268, 1231, + 1193, 1156, 1118, 1080, 1043, 1005, 967, 930, + 892, 854, 816, 778, 740, 703, 665, 627, + 589, 551, 513, 475, 437, 399, 361, 323, + 285, 247, 209, 171, 133, 95, 57, 19 +}; +const Word16 edct_table_128_16fx[128] = /*Q15 */ +{ + 9742, 9740, 9737, 9733, 9727, 9720, 9711, 9701, + 9689, 9676, 9661, 9645, 9627, 9608, 9588, 9566, + 9543, 9518, 9492, 9464, 9435, 9405, 9373, 9339, + 9305, 9269, 9231, 9192, 9152, 9110, 9067, 9023, + 8977, 8930, 8882, 8832, 8781, 8728, 8675, 8619, + 8563, 8505, 8447, 8386, 8325, 8262, 8198, 8133, + 8067, 7999, 7930, 7860, 7789, 7717, 7643, 7568, + 7492, 7415, 7337, 7258, 7178, 7097, 7014, 6931, + 6846, 6761, 6674, 6586, 6498, 6408, 6318, 6226, + 6134, 6040, 5946, 5851, 5755, 5658, 5560, 5462, + 5362, 5262, 5161, 5059, 4957, 4854, 4750, 4645, + 4539, 4433, 4327, 4219, 4111, 4002, 3893, 3783, + 3673, 3562, 3450, 3338, 3226, 3113, 2999, 2885, + 2771, 2656, 2541, 2425, 2309, 2193, 2076, 1959, + 1842, 1724, 1607, 1489, 1370, 1252, 1133, 1014, + 895, 776, 657, 538, 418, 299, 179, 60 +}; +const Word16 edct_table_160_16fx[160] = +{ + 9213, 9212, 9211, 9208, 9204, 9200, 9195, 9188, + 9181, 9173, 9164, 9155, 9144, 9132, 9120, 9107, + 9093, 9078, 9062, 9045, 9027, 9009, 8989, 8969, + 8948, 8926, 8903, 8880, 8855, 8830, 8803, 8776, + 8748, 8719, 8690, 8659, 8628, 8596, 8563, 8529, + 8495, 8459, 8423, 8386, 8348, 8309, 8270, 8230, + 8188, 8147, 8104, 8061, 8016, 7971, 7926, 7879, + 7832, 7784, 7735, 7686, 7635, 7584, 7533, 7480, + 7427, 7373, 7319, 7263, 7207, 7151, 7093, 7035, + 6976, 6917, 6857, 6796, 6735, 6673, 6610, 6547, + 6483, 6418, 6353, 6287, 6221, 6154, 6086, 6018, + 5949, 5880, 5810, 5739, 5668, 5597, 5525, 5452, + 5379, 5305, 5231, 5156, 5081, 5005, 4929, 4852, + 4775, 4698, 4620, 4541, 4462, 4383, 4303, 4223, + 4142, 4061, 3980, 3898, 3816, 3734, 3651, 3568, + 3484, 3400, 3316, 3231, 3146, 3061, 2976, 2890, + 2804, 2718, 2631, 2544, 2457, 2370, 2282, 2195, + 2107, 2019, 1930, 1842, 1753, 1664, 1575, 1486, + 1397, 1307, 1218, 1128, 1038, 948, 858, 768, + 678, 588, 497, 407, 317, 226, 136, 45 +}; + + /*----------------------------------------------------------------------------------* * Mean ISF vector for active signal (only for AMR-WB IO mode) *----------------------------------------------------------------------------------*/ @@ -5578,7 +8059,7 @@ const Word16 gaus_dico_swb_fx[256] = const int16_t freqTable[2] = {20, 40}; /* SNR: 109.44, PHASE: 3.500000000000000 */ -const float CLDFB80_10[100] = +const float CLDFB80_10_flt[100] = { 0.0000033382f, -0.0000023292f, -0.0000006582f, 0.0000001464f, -0.0000010899f, -0.0000009664f, -0.0000000104f, -0.0000018105f, -0.0000012856f, 0.0000017112f, 0.0000137155f, -0.0000084710f, @@ -5600,7 +8081,7 @@ const float CLDFB80_10[100] = }; /* SNR: 292.49, PHASE: 2.000000000000000 */ -const float CLDFB80_16[160] = +const float CLDFB80_16_flt[160] = { 0.0000005510f, -0.0000007674f, -0.0000002340f, 0.0000000964f, 0.0000000593f, -0.0000000017f, -0.0000000178f, 0.0000021953f, 0.0000030004f, -0.0000000167f, -0.0000000019f, 0.0000000702f, @@ -5632,7 +8113,7 @@ const float CLDFB80_16[160] = }; /* SNR: 89.77, PHASE: 1.500000000000000 */ -const float CLDFB80_20[200] = +const float CLDFB80_20_flt[200] = { 0.0000016461f, -0.0000046862f, -0.0000000815f, -0.0000001822f, 0.0000000240f, 0.0000001892f, -0.0000002365f, -0.0000007031f, -0.0000000079f, 0.0000048656f, 0.0000070490f, 0.0000000032f, @@ -5671,7 +8152,7 @@ const float CLDFB80_20[200] = }; /* SNR: 89.29, PHASE: 0.833333333333333 */ -const float CLDFB80_30[300] = +const float CLDFB80_30_flt[300] = { -0.0000002772f, 0.0000033382f, 0.0000018078f, -0.0000007965f, -0.0000023292f, -0.0000000163f, 0.0000001004f, -0.0000006582f, 0.0000000287f, 0.0000000140f, 0.0000001464f, 0.0000002826f, @@ -5726,7 +8207,7 @@ const float CLDFB80_30[300] = }; /* SNR: 85.69, PHASE: 0.750000000000000 */ -const float CLDFB80_32[320] = +const float CLDFB80_32_flt[320] = { -0.0000010182f, 0.0000018812f, -0.0000013969f, 0.0000000702f, -0.0000030351f, -0.0000001862f, 0.0000000017f, 0.0000000804f, -0.0000002859f, -0.0000000058f, -0.0000003463f, -0.0000003782f, @@ -5785,7 +8266,7 @@ const float CLDFB80_32[320] = }; /* SNR: 81.55, PHASE: 0.500000000000000 */ -const float CLDFB80_40[400] = +const float CLDFB80_40_flt[400] = { -0.0000041528f, -0.0000003900f, -0.0000033779f, 0.0000013260f, -0.0000003143f, -0.0000019348f, 0.0000002820f, 0.0000000171f, 0.0000000756f, 0.0000001478f, -0.0000006625f, 0.0000000082f, @@ -5858,7 +8339,7 @@ const float CLDFB80_40[400] = /* SNR: 85.15, PHASE: 0.166666666666667 */ -const float CLDFB80_60[600] = +const float CLDFB80_60_flt[600] = { -0.0000108386f, 0.0000016461f, -0.0000001140f, 0.0000015161f, -0.0000046862f, -0.0000001825f, 0.0000001498f, -0.0000000815f, -0.0000033014f, 0.0000001274f, -0.0000001822f, 0.0000000191f, @@ -6530,8 +9011,636 @@ const float rot_vec_ana_im_L60[30] = -1.1004973285f,-1.1172871929f,-1.1310146507f,-1.1416420760f,-1.1491403397f,-1.1534888896f, }; +/*! + * \brief CLDFB prototype filter + * + * cldfb bands: 10 + * delay[ms]: 1.00 + * abs. max Val: 1.04 + * scale: 0.50 + */ +const Word16 CLDFB80_10[] = +{ + W16(0x0000), W16(0xfffc), W16(0xffdf), W16(0x0132), W16(0x23b5), + W16(0x0000), W16(0xffff), W16(0xfff3), W16(0x018d), W16(0x2a98), + W16(0x0000), W16(0x0000), W16(0x0006), W16(0x020d), W16(0x3116), + W16(0x0000), W16(0x0000), W16(0x001a), W16(0x02bd), W16(0x36e2), + W16(0x0000), W16(0x0000), W16(0x001c), W16(0x039f), W16(0x3bb5), + W16(0x0000), W16(0xffff), W16(0x001a), W16(0x04b1), W16(0x3f51), + W16(0x0000), W16(0x0000), W16(0x0024), W16(0x05da), W16(0x419a), + W16(0x0000), W16(0x0000), W16(0x002e), W16(0x06ee), W16(0x428c), + W16(0x0000), W16(0x0000), W16(0x0032), W16(0x07bd), W16(0x4267), + W16(0x0000), W16(0xfffc), W16(0x001b), W16(0x0820), W16(0x410b), + W16(0x0000), W16(0xfff0), W16(0xffe9), W16(0x0806), W16(0x3d82), + W16(0x0000), W16(0xfffe), W16(0xffe6), W16(0x0746), W16(0x37fe), + W16(0x0000), W16(0x0000), W16(0x000d), W16(0x05ae), W16(0x31d1), + W16(0x0000), W16(0x0000), W16(0x002a), W16(0x032f), W16(0x2b60), + W16(0x0000), W16(0xfffd), W16(0x0025), W16(0xffcd), W16(0x24a3), + W16(0x0000), W16(0x0003), W16(0x0004), W16(0xfb88), W16(0x1dc0), + W16(0x0000), W16(0x0000), W16(0xffca), W16(0xf66f), W16(0x16c9), + W16(0x0000), W16(0x0000), W16(0xff95), W16(0xf09a), W16(0x0fe8), + W16(0x0000), W16(0xffff), W16(0xff64), W16(0xea2a), W16(0x08e0), + W16(0x0000), W16(0x0012), W16(0xff21), W16(0xe34c), W16(0x02aa) +}; + +/*! + * \brief CLDFB prototype filter + * + * cldfb bands: 16 + * delay[ms]: 1.00 + * abs. max Val: 1.04 + * scale: 0.50 + */ +const Word16 CLDFB80_16[] = +{ + W16(0x0000), W16(0xfffb), W16(0xffdd), W16(0x0123), W16(0x2266), + W16(0x0000), W16(0xfffe), W16(0xffe7), W16(0x0157), W16(0x26c0), + W16(0x0000), W16(0xffff), W16(0xfff4), W16(0x0194), W16(0x2b04), + W16(0x0000), W16(0xffff), W16(0xfffe), W16(0x01e0), W16(0x2f1f), + W16(0x0000), W16(0x0000), W16(0x000c), W16(0x023f), W16(0x32fc), + W16(0x0000), W16(0x0000), W16(0x0019), W16(0x02b0), W16(0x368c), + W16(0x0000), W16(0x0000), W16(0x001d), W16(0x0336), W16(0x39bc), + W16(0x0000), W16(0x0001), W16(0x0013), W16(0x03cf), W16(0x3c7b), + W16(0x0000), W16(0x0001), W16(0x001a), W16(0x047b), W16(0x3ebd), + W16(0x0000), W16(0x0000), W16(0x001e), W16(0x0532), W16(0x407c), + W16(0x0000), W16(0x0000), W16(0x0025), W16(0x05ec), W16(0x41b3), + W16(0x0000), W16(0xffff), W16(0x002d), W16(0x069d), W16(0x4262), + W16(0x0000), W16(0x0000), W16(0x0031), W16(0x0738), W16(0x429c), + W16(0x0000), W16(0x0000), W16(0x0032), W16(0x07b3), W16(0x4271), + W16(0x0000), W16(0xffff), W16(0x002a), W16(0x0804), W16(0x41d1), + W16(0x0000), W16(0xfff9), W16(0x0015), W16(0x0824), W16(0x40a3), + W16(0x0000), W16(0xffec), W16(0xffee), W16(0x0815), W16(0x3e6c), + W16(0x0000), W16(0xfff7), W16(0xffe0), W16(0x07ca), W16(0x3b3b), + W16(0x0000), W16(0xfffd), W16(0xffe8), W16(0x0734), W16(0x379e), + W16(0x0000), W16(0xfffe), W16(0x0000), W16(0x0647), W16(0x33c7), + W16(0x0000), W16(0xffff), W16(0x0018), W16(0x04ff), W16(0x2fd6), + W16(0x0000), W16(0x0000), W16(0x0029), W16(0x035e), W16(0x2bca), + W16(0x0000), W16(0xffff), W16(0x002b), W16(0x0164), W16(0x279c), + W16(0x0000), W16(0x0001), W16(0x0022), W16(0xff11), W16(0x235b), + W16(0x0000), W16(0xfffc), W16(0x000f), W16(0xfc66), W16(0x1f0d), + W16(0x0000), W16(0x0001), W16(0xffec), W16(0xf966), W16(0x1ab4), + W16(0x0000), W16(0x0000), W16(0xffc6), W16(0xf617), W16(0x165a), + W16(0x0000), W16(0x0001), W16(0xffa5), W16(0xf27f), W16(0x120e), + W16(0x0000), W16(0x0001), W16(0xff86), W16(0xeea6), W16(0x0dbd), + W16(0x0000), W16(0x0001), W16(0xff67), W16(0xea95), W16(0x0950), + W16(0x0000), W16(0x0005), W16(0xff40), W16(0xe657), W16(0x051a), + W16(0x0000), W16(0x001b), W16(0xff12), W16(0xe1fc), W16(0x01c8) +}; + +/*! + * \brief CLDFB prototype filter + * + * cldfb bands: 20 + * delay[ms]: 1.00 + * abs. max Val: 1.04 + * scale: 0.50 + */ +const Word16 CLDFB80_20[] = +{ + W16(0x0000), W16(0xfffb), W16(0xffdf), W16(0x011e), W16(0x21f7), + W16(0x0000), W16(0xfffd), W16(0xffe1), W16(0x0146), W16(0x2573), + W16(0x0000), W16(0xffff), W16(0xfff2), W16(0x0173), W16(0x28e6), + W16(0x0000), W16(0xffff), W16(0xfff6), W16(0x01a9), W16(0x2c45), + W16(0x0000), W16(0xffff), W16(0xffff), W16(0x01e9), W16(0x2f84), + W16(0x0000), W16(0x0000), W16(0x000a), W16(0x0235), W16(0x329c), + W16(0x0000), W16(0x0000), W16(0x0014), W16(0x028c), W16(0x3583), + W16(0x0000), W16(0x0000), W16(0x001b), W16(0x02f1), W16(0x3831), + W16(0x0000), W16(0x0000), W16(0x001e), W16(0x0362), W16(0x3a9c), + W16(0x0000), W16(0x0001), W16(0x000d), W16(0x03df), W16(0x3cbb), + W16(0x0000), W16(0x0000), W16(0x001b), W16(0x0469), W16(0x3e89), + W16(0x0000), W16(0x0000), W16(0x001c), W16(0x04fb), W16(0x4004), + W16(0x0000), W16(0x0000), W16(0x0020), W16(0x0590), W16(0x4129), + W16(0x0000), W16(0x0000), W16(0x0027), W16(0x0622), W16(0x41f5), + W16(0x0000), W16(0x0000), W16(0x002e), W16(0x06ad), W16(0x426d), + W16(0x0000), W16(0x0000), W16(0x0030), W16(0x072a), W16(0x429b), + W16(0x0000), W16(0x0000), W16(0x0032), W16(0x0792), W16(0x4288), + W16(0x0000), W16(0x0001), W16(0x002e), W16(0x07e1), W16(0x4232), + W16(0x0000), W16(0xfffe), W16(0x0024), W16(0x0813), W16(0x4186), + W16(0x0000), W16(0xfff8), W16(0x0011), W16(0x0825), W16(0x407d), + W16(0x0000), W16(0xffed), W16(0xfff1), W16(0x0818), W16(0x3eb8), + W16(0x0000), W16(0xfff5), W16(0xffe3), W16(0x07e8), W16(0x3c3c), + W16(0x0000), W16(0xfffe), W16(0xffe1), W16(0x0789), W16(0x3977), + W16(0x0000), W16(0xfffd), W16(0xffee), W16(0x06f6), W16(0x367b), + W16(0x0000), W16(0xfffe), W16(0x0002), W16(0x062a), W16(0x3363), + W16(0x0000), W16(0xffff), W16(0x0016), W16(0x0524), W16(0x303c), + W16(0x0000), W16(0x0000), W16(0x0026), W16(0x03e4), W16(0x2d04), + W16(0x0000), W16(0x0000), W16(0x002d), W16(0x026c), W16(0x29b7), + W16(0x0000), W16(0xfffe), W16(0x0029), W16(0x00bb), W16(0x2657), + W16(0x0000), W16(0x0005), W16(0x0021), W16(0xfed0), W16(0x22ed), + W16(0x0000), W16(0xfff8), W16(0x0014), W16(0xfcae), W16(0x1f7c), + W16(0x0000), W16(0x0002), W16(0xfff7), W16(0xfa55), W16(0x1c03), + W16(0x0000), W16(0x0000), W16(0xffd8), W16(0xf7c8), W16(0x1886), + W16(0x0000), W16(0x0001), W16(0xffbc), W16(0xf50a), W16(0x150f), + W16(0x0000), W16(0x0001), W16(0xffa2), W16(0xf21f), W16(0x11a0), + W16(0x0000), W16(0x0001), W16(0xff89), W16(0xef0b), W16(0x0e2c), + W16(0x0000), W16(0x0001), W16(0xff71), W16(0xebd2), W16(0x0aa5), + W16(0x0000), W16(0xfffe), W16(0xff55), W16(0xe87a), W16(0x0724), + W16(0x0000), W16(0x0006), W16(0xff33), W16(0xe50a), W16(0x03fd), + W16(0x0000), W16(0x001e), W16(0xff0d), W16(0xe18b), W16(0x017f) +}; + +/*! + * \brief CLDFB prototype filter + * + * cldfb bands: 32 + * delay[ms]: 1.00 + * abs. max Val: 1.04 + * scale: 0.50 + */ +const Word16 CLDFB80_32[] = +{ + W16(0x0000), W16(0xfffb), W16(0xffe2), W16(0x0115), W16(0x214f), + W16(0x0000), W16(0xfffc), W16(0xffde), W16(0x012f), W16(0x237e), + W16(0x0000), W16(0xfffd), W16(0xffe2), W16(0x0149), W16(0x25ab), + W16(0x0000), W16(0xfffe), W16(0xffec), W16(0x0165), W16(0x27d4), + W16(0x0000), W16(0xffff), W16(0xfff4), W16(0x0183), W16(0x29f6), + W16(0x0000), W16(0xffff), W16(0xfff6), W16(0x01a6), W16(0x2c10), + W16(0x0000), W16(0xffff), W16(0xfffb), W16(0x01cc), W16(0x2e1d), + W16(0x0000), W16(0xffff), W16(0x0001), W16(0x01f6), W16(0x301c), + W16(0x0000), W16(0x0000), W16(0x0009), W16(0x0226), W16(0x320b), + W16(0x0000), W16(0x0000), W16(0x000f), W16(0x025a), W16(0x33e7), + W16(0x0000), W16(0x0000), W16(0x0015), W16(0x0292), W16(0x35b0), + W16(0x0000), W16(0x0000), W16(0x001b), W16(0x02d0), W16(0x3761), + W16(0x0000), W16(0x0000), W16(0x001d), W16(0x0313), W16(0x38fa), + W16(0x0000), W16(0x0000), W16(0x001e), W16(0x035a), W16(0x3a77), + W16(0x0000), W16(0x0000), W16(0x001b), W16(0x03a7), W16(0x3bd7), + W16(0x0000), W16(0x0000), W16(0x0004), W16(0x03f7), W16(0x3d18), + W16(0x0000), W16(0xffff), W16(0x001b), W16(0x044e), W16(0x3e38), + W16(0x0000), W16(0xffff), W16(0x001a), W16(0x04a8), W16(0x3f39), + W16(0x0000), W16(0x0000), W16(0x001c), W16(0x0504), W16(0x4018), + W16(0x0000), W16(0x0001), W16(0x001f), W16(0x0561), W16(0x40d6), + W16(0x0000), W16(0x0000), W16(0x0022), W16(0x05be), W16(0x4172), + W16(0x0000), W16(0x0000), W16(0x0027), W16(0x0619), W16(0x41eb), + W16(0x0000), W16(0xffff), W16(0x002c), W16(0x0672), W16(0x4242), + W16(0x0000), W16(0x0000), W16(0x002e), W16(0x06c6), W16(0x427b), + W16(0x0000), W16(0x0000), W16(0x002f), W16(0x0714), W16(0x4297), + W16(0x0000), W16(0x0000), W16(0x0031), W16(0x075a), W16(0x429a), + W16(0x0000), W16(0x0000), W16(0x0032), W16(0x0798), W16(0x4285), + W16(0x0000), W16(0x0001), W16(0x0031), W16(0x07cb), W16(0x4255), + W16(0x0000), W16(0xffff), W16(0x002c), W16(0x07f4), W16(0x4206), + W16(0x0000), W16(0xfffe), W16(0x0025), W16(0x0811), W16(0x4193), + W16(0x0000), W16(0xfffb), W16(0x001a), W16(0x0821), W16(0x40fa), + W16(0x0000), W16(0xfff5), W16(0x000b), W16(0x0823), W16(0x404a), + W16(0x0000), W16(0xfff0), W16(0xfff6), W16(0x081b), W16(0x3f2f), + W16(0x0000), W16(0xffef), W16(0xffe9), W16(0x0809), W16(0x3daa), + W16(0x0000), W16(0xfff5), W16(0xffe2), W16(0x07e4), W16(0x3c12), + W16(0x0000), W16(0xfffa), W16(0xffe0), W16(0x07ac), W16(0x3a5c), + W16(0x0000), W16(0xffff), W16(0xffe4), W16(0x0761), W16(0x388d), + W16(0x0000), W16(0xfffd), W16(0xffed), W16(0x0701), W16(0x36ac), + W16(0x0000), W16(0xfffe), W16(0xfff9), W16(0x068a), W16(0x34c0), + W16(0x0000), W16(0xffff), W16(0x0006), W16(0x05fd), W16(0x32cd), + W16(0x0000), W16(0x0000), W16(0x0013), W16(0x0559), W16(0x30d4), + W16(0x0000), W16(0x0000), W16(0x001d), W16(0x049f), W16(0x2ed6), + W16(0x0000), W16(0x0000), W16(0x0026), W16(0x03cf), W16(0x2cd0), + W16(0x0000), W16(0x0000), W16(0x002c), W16(0x02e8), W16(0x2ac1), + W16(0x0000), W16(0x0000), W16(0x002c), W16(0x01eb), W16(0x28aa), + W16(0x0000), W16(0xfffe), W16(0x0029), W16(0x00d7), W16(0x268d), + W16(0x0000), W16(0xfffd), W16(0x0024), W16(0xffae), W16(0x246c), + W16(0x0000), W16(0x000a), W16(0x0021), W16(0xfe6e), W16(0x2248), + W16(0x0000), W16(0xfff3), W16(0x001a), W16(0xfd19), W16(0x2022), + W16(0x0000), W16(0x0003), W16(0x0006), W16(0xfbad), W16(0x1df8), + W16(0x0000), W16(0x0002), W16(0xfff5), W16(0xfa2d), W16(0x1bcb), + W16(0x0000), W16(0xffff), W16(0xffe2), W16(0xf899), W16(0x199d), + W16(0x0000), W16(0x0001), W16(0xffcf), W16(0xf6f2), W16(0x1770), + W16(0x0000), W16(0x0001), W16(0xffbd), W16(0xf537), W16(0x1546), + W16(0x0000), W16(0x0001), W16(0xffad), W16(0xf36b), W16(0x1320), + W16(0x0000), W16(0x0000), W16(0xff9d), W16(0xf18e), W16(0x10fc), + W16(0x0000), W16(0x0001), W16(0xff8e), W16(0xefa2), W16(0x0ed3), + W16(0x0000), W16(0x0001), W16(0xff7f), W16(0xeda7), W16(0x0ca3), + W16(0x0000), W16(0x0001), W16(0xff6f), W16(0xeb9e), W16(0x0a6c), + W16(0x0000), W16(0xfffd), W16(0xff5e), W16(0xe989), W16(0x0837), + W16(0x0000), W16(0x0003), W16(0xff4b), W16(0xe769), W16(0x0618), + W16(0x0000), W16(0x0006), W16(0xff35), W16(0xe542), W16(0x042a), + W16(0x0000), W16(0x0013), W16(0xff1e), W16(0xe314), W16(0x0284), + W16(0x0000), W16(0x0020), W16(0xff06), W16(0xe0e2), W16(0x010c) +}; + +/*! + * \brief CLDFB prototype filter + * + * cldfb bands: 40 + * delay[ms]: 1.00 + * abs. max Val: 1.04 + * scale: 0.50 + */ +const Word16 CLDFB80_40[] = +{ + W16(0x0000), W16(0xfffa), W16(0xffe2), W16(0x0112), W16(0x2117), + W16(0x0000), W16(0xfffb), W16(0xffdc), W16(0x0128), W16(0x22d6), + W16(0x0000), W16(0xfffc), W16(0xffe0), W16(0x013c), W16(0x2494), + W16(0x0000), W16(0xfffe), W16(0xffe5), W16(0x0151), W16(0x2651), + W16(0x0000), W16(0xffff), W16(0xffed), W16(0x0167), W16(0x280b), + W16(0x0000), W16(0xffff), W16(0xfff4), W16(0x0180), W16(0x29c0), + W16(0x0000), W16(0xffff), W16(0xfff4), W16(0x019b), W16(0x2b6f), + W16(0x0000), W16(0xffff), W16(0xfff8), W16(0x01b8), W16(0x2d18), + W16(0x0000), W16(0xffff), W16(0xfffd), W16(0x01d8), W16(0x2eb8), + W16(0x0000), W16(0xffff), W16(0x0002), W16(0x01fb), W16(0x304e), + W16(0x0000), W16(0x0000), W16(0x0008), W16(0x0221), W16(0x31da), + W16(0x0000), W16(0x0000), W16(0x000d), W16(0x0249), W16(0x335a), + W16(0x0000), W16(0x0000), W16(0x0013), W16(0x0275), W16(0x34ce), + W16(0x0000), W16(0x0000), W16(0x0017), W16(0x02a4), W16(0x3634), + W16(0x0000), W16(0x0000), W16(0x001b), W16(0x02d6), W16(0x378b), + W16(0x0000), W16(0x0000), W16(0x001d), W16(0x030c), W16(0x38d3), + W16(0x0000), W16(0x0000), W16(0x001e), W16(0x0344), W16(0x3a08), + W16(0x0000), W16(0x0000), W16(0x001e), W16(0x0380), W16(0x3b2b), + W16(0x0000), W16(0x0000), W16(0x0017), W16(0x03bf), W16(0x3c3b), + W16(0x0000), W16(0xffff), W16(0x0002), W16(0x03ff), W16(0x3d36), + W16(0x0000), W16(0xffff), W16(0x001a), W16(0x0445), W16(0x3e1d), + W16(0x0000), W16(0x0000), W16(0x001a), W16(0x048d), W16(0x3eef), + W16(0x0000), W16(0x0000), W16(0x001b), W16(0x04d6), W16(0x3fad), + W16(0x0000), W16(0x0000), W16(0x001d), W16(0x0520), W16(0x4055), + W16(0x0000), W16(0x0001), W16(0x001f), W16(0x056a), W16(0x40e8), + W16(0x0000), W16(0xffff), W16(0x0021), W16(0x05b5), W16(0x4164), + W16(0x0000), W16(0x0000), W16(0x0026), W16(0x05fe), W16(0x41ca), + W16(0x0000), W16(0x0000), W16(0x0029), W16(0x0646), W16(0x421b), + W16(0x0000), W16(0xffff), W16(0x002d), W16(0x068c), W16(0x4256), + W16(0x0000), W16(0x0000), W16(0x002e), W16(0x06ce), W16(0x427f), + W16(0x0000), W16(0x0000), W16(0x002f), W16(0x070c), W16(0x4295), + W16(0x0000), W16(0x0000), W16(0x0031), W16(0x0746), W16(0x429c), + W16(0x0000), W16(0x0000), W16(0x0032), W16(0x077a), W16(0x4293), + W16(0x0000), W16(0x0000), W16(0x0032), W16(0x07a8), W16(0x427a), + W16(0x0000), W16(0x0001), W16(0x0030), W16(0x07d0), W16(0x424f), + W16(0x0000), W16(0xffff), W16(0x002d), W16(0x07f0), W16(0x4210), + W16(0x0000), W16(0xffff), W16(0x0028), W16(0x080a), W16(0x41ba), + W16(0x0000), W16(0xfffd), W16(0x001f), W16(0x081b), W16(0x414b), + W16(0x0000), W16(0xfffa), W16(0x0018), W16(0x0824), W16(0x40c6), + W16(0x0000), W16(0xfff4), W16(0x0009), W16(0x0822), W16(0x403a), + W16(0xffff), W16(0xfff1), W16(0xfff9), W16(0x081c), W16(0x3f57), + W16(0x0000), W16(0xffed), W16(0xffec), W16(0x0810), W16(0x3e1f), + W16(0x0000), W16(0xfff3), W16(0xffe6), W16(0x07f9), W16(0x3ce2), + W16(0x0000), W16(0xfff6), W16(0xffe1), W16(0x07d5), W16(0x3b92), + W16(0x0000), W16(0xfffb), W16(0xffe0), W16(0x07a6), W16(0x3a2f), + W16(0x0000), W16(0xffff), W16(0xffe3), W16(0x076a), W16(0x38bc), + W16(0x0000), W16(0xfffd), W16(0xffea), W16(0x0720), W16(0x373e), + W16(0x0000), W16(0xfffd), W16(0xfff3), W16(0x06c8), W16(0x35b7), + W16(0x0000), W16(0xfffe), W16(0xfffd), W16(0x0662), W16(0x342a), + W16(0x0000), W16(0xffff), W16(0x0008), W16(0x05ee), W16(0x329a), + W16(0x0000), W16(0x0000), W16(0x0011), W16(0x056b), W16(0x3107), + W16(0x0000), W16(0xffff), W16(0x001a), W16(0x04d9), W16(0x2f70), + W16(0x0000), W16(0x0000), W16(0x0022), W16(0x043a), W16(0x2dd4), + W16(0x0000), W16(0x0000), W16(0x0028), W16(0x038c), W16(0x2c33), + W16(0x0000), W16(0x0000), W16(0x002c), W16(0x02cf), W16(0x2a8c), + W16(0x0000), W16(0x0001), W16(0x002d), W16(0x0205), W16(0x28e0), + W16(0x0000), W16(0xffff), W16(0x002b), W16(0x012c), W16(0x2730), + W16(0x0000), W16(0xfffd), W16(0x0027), W16(0x0045), W16(0x257d), + W16(0x0000), W16(0xffff), W16(0x0023), W16(0xff50), W16(0x23c8), + W16(0x0000), W16(0x000a), W16(0x0021), W16(0xfe4d), W16(0x2211), + W16(0x0000), W16(0xfff3), W16(0x001c), W16(0xfd3c), W16(0x2059), + W16(0x0000), W16(0x0000), W16(0x000b), W16(0xfc1c), W16(0x1e9e), + W16(0x0000), W16(0x0003), W16(0xfffd), W16(0xfaf0), W16(0x1ce2), + W16(0x0000), W16(0x0001), W16(0xffef), W16(0xf9b6), W16(0x1b24), + W16(0x0000), W16(0xfffe), W16(0xffe0), W16(0xf870), W16(0x1965), + W16(0x0000), W16(0x0001), W16(0xffd1), W16(0xf71d), W16(0x17a7), + W16(0x0000), W16(0x0000), W16(0xffc3), W16(0xf5be), W16(0x15ec), + W16(0x0000), W16(0x0001), W16(0xffb5), W16(0xf453), W16(0x1433), + W16(0x0000), W16(0x0001), W16(0xffa8), W16(0xf2de), W16(0x127c), + W16(0x0000), W16(0x0000), W16(0xff9b), W16(0xf15e), W16(0x10c5), + W16(0x0000), W16(0x0001), W16(0xff8f), W16(0xefd4), W16(0x0f0b), + W16(0x0000), W16(0x0001), W16(0xff83), W16(0xee40), W16(0x0d4c), + W16(0x0000), W16(0x0001), W16(0xff77), W16(0xeca4), W16(0x0b88), + W16(0x0000), W16(0x0001), W16(0xff6a), W16(0xeaff), W16(0x09c2), + W16(0x0000), W16(0xfffd), W16(0xff5d), W16(0xe953), W16(0x0800), + W16(0x0000), W16(0x0002), W16(0xff4d), W16(0xe7a0), W16(0x064d), + W16(0x0000), W16(0x0006), W16(0xff3c), W16(0xe5e8), W16(0x04b8), + W16(0x0000), W16(0x0009), W16(0xff2a), W16(0xe42c), W16(0x034d), + W16(0x0000), W16(0x0018), W16(0xff17), W16(0xe26c), W16(0x0212), + W16(0x0001), W16(0x0020), W16(0xff03), W16(0xe0aa), W16(0x00e3) +}; + +/*! + * \brief CLDFB prototype filter + * + * cldfb bands: 60 + * delay[ms]: 1.00 + * abs. max Val: 1.04 + * scale: 0.50 + */ +const Word16 CLDFB80_60[] = +{ + W16(0x0000), W16(0xfffa), W16(0xffe2), W16(0x010f), W16(0x20cd), + W16(0x0000), W16(0xfffb), W16(0xffdf), W16(0x011e), W16(0x21f7), + W16(0x0000), W16(0xfffb), W16(0xffdd), W16(0x012b), W16(0x2320), + W16(0x0000), W16(0xfffd), W16(0xffe0), W16(0x0138), W16(0x244a), + W16(0x0000), W16(0xfffd), W16(0xffe1), W16(0x0146), W16(0x2573), + W16(0x0000), W16(0xfffe), W16(0xffe6), W16(0x0155), W16(0x269b), + W16(0x0000), W16(0xfffe), W16(0xffec), W16(0x0164), W16(0x27c1), + W16(0x0000), W16(0xffff), W16(0xfff2), W16(0x0173), W16(0x28e6), + W16(0x0000), W16(0xffff), W16(0xfff4), W16(0x0184), W16(0x2a08), + W16(0x0000), W16(0xffff), W16(0xfff4), W16(0x0196), W16(0x2b28), + W16(0x0000), W16(0xffff), W16(0xfff6), W16(0x01a9), W16(0x2c45), + W16(0x0000), W16(0xffff), W16(0xfff9), W16(0x01bd), W16(0x2d5e), + W16(0x0000), W16(0xffff), W16(0xfffc), W16(0x01d2), W16(0x2e73), + W16(0x0000), W16(0xffff), W16(0xffff), W16(0x01e9), W16(0x2f84), + W16(0x0000), W16(0x0000), W16(0x0003), W16(0x0201), W16(0x3091), + W16(0x0000), W16(0x0000), W16(0x0008), W16(0x021a), W16(0x3199), + W16(0x0000), W16(0x0000), W16(0x000a), W16(0x0235), W16(0x329c), + W16(0x0000), W16(0x0000), W16(0x000e), W16(0x0251), W16(0x3399), + W16(0x0000), W16(0x0000), W16(0x0012), W16(0x026e), W16(0x3491), + W16(0x0000), W16(0x0000), W16(0x0014), W16(0x028c), W16(0x3583), + W16(0x0000), W16(0x0000), W16(0x0018), W16(0x02ac), W16(0x366f), + W16(0x0000), W16(0x0000), W16(0x001b), W16(0x02ce), W16(0x3753), + W16(0x0000), W16(0x0000), W16(0x001b), W16(0x02f1), W16(0x3831), + W16(0x0000), W16(0x0000), W16(0x001d), W16(0x0315), W16(0x3907), + W16(0x0000), W16(0x0000), W16(0x001e), W16(0x033b), W16(0x39d6), + W16(0x0000), W16(0x0000), W16(0x001e), W16(0x0362), W16(0x3a9c), + W16(0x0000), W16(0x0000), W16(0x001d), W16(0x038a), W16(0x3b5a), + W16(0x0000), W16(0x0000), W16(0x0019), W16(0x03b4), W16(0x3c0f), + W16(0x0000), W16(0x0001), W16(0x000d), W16(0x03df), W16(0x3cbb), + W16(0x0000), W16(0xffff), W16(0x0001), W16(0x040a), W16(0x3d5e), + W16(0x0000), W16(0xfffe), W16(0x0017), W16(0x0439), W16(0x3df8), + W16(0x0000), W16(0x0000), W16(0x001b), W16(0x0469), W16(0x3e89), + W16(0x0000), W16(0x0000), W16(0x001a), W16(0x0499), W16(0x3f10), + W16(0x0000), W16(0x0000), W16(0x001a), W16(0x04c9), W16(0x3f8f), + W16(0x0000), W16(0x0000), W16(0x001c), W16(0x04fb), W16(0x4004), + W16(0x0000), W16(0x0000), W16(0x001e), W16(0x052c), W16(0x406f), + W16(0x0000), W16(0x0001), W16(0x001f), W16(0x055e), W16(0x40d1), + W16(0x0000), W16(0x0000), W16(0x0020), W16(0x0590), W16(0x4129), + W16(0x0000), W16(0x0000), W16(0x0022), W16(0x05c1), W16(0x4177), + W16(0x0000), W16(0x0000), W16(0x0025), W16(0x05f2), W16(0x41bb), + W16(0x0000), W16(0x0000), W16(0x0027), W16(0x0622), W16(0x41f5), + W16(0x0000), W16(0xffff), W16(0x002a), W16(0x0652), W16(0x4226), + W16(0x0000), W16(0xffff), W16(0x002c), W16(0x0680), W16(0x424e), + W16(0x0000), W16(0x0000), W16(0x002e), W16(0x06ad), W16(0x426d), + W16(0x0000), W16(0x0000), W16(0x002e), W16(0x06d9), W16(0x4284), + W16(0x0000), W16(0x0000), W16(0x002f), W16(0x0702), W16(0x4293), + W16(0x0000), W16(0x0000), W16(0x0030), W16(0x072a), W16(0x429b), + W16(0x0000), W16(0x0000), W16(0x0031), W16(0x074f), W16(0x429b), + W16(0x0000), W16(0x0000), W16(0x0032), W16(0x0772), W16(0x4295), + W16(0x0000), W16(0x0000), W16(0x0032), W16(0x0792), W16(0x4288), + W16(0x0000), W16(0x0000), W16(0x0032), W16(0x07af), W16(0x4274), + W16(0x0000), W16(0x0001), W16(0x0031), W16(0x07ca), W16(0x4257), + W16(0x0000), W16(0x0001), W16(0x002e), W16(0x07e1), W16(0x4232), + W16(0x0000), W16(0xffff), W16(0x002c), W16(0x07f5), W16(0x4203), + W16(0x0000), W16(0xfffe), W16(0x0029), W16(0x0806), W16(0x41ca), + W16(0x0000), W16(0xfffe), W16(0x0024), W16(0x0813), W16(0x4186), + W16(0x0000), W16(0xfffd), W16(0x001e), W16(0x081d), W16(0x4137), + W16(0x0000), W16(0xfffa), W16(0x0019), W16(0x0823), W16(0x40de), + W16(0x0000), W16(0xfff8), W16(0x0011), W16(0x0825), W16(0x407d), + W16(0xffff), W16(0xfff3), W16(0x0006), W16(0x0821), W16(0x4023), + W16(0xffff), W16(0xfff2), W16(0xfffb), W16(0x081d), W16(0x3f8c), + W16(0x0000), W16(0xffed), W16(0xfff1), W16(0x0818), W16(0x3eb8), + W16(0x0000), W16(0xffee), W16(0xffeb), W16(0x080d), W16(0x3deb), + W16(0x0000), W16(0xfff2), W16(0xffe7), W16(0x07fd), W16(0x3d18), + W16(0x0000), W16(0xfff5), W16(0xffe3), W16(0x07e8), W16(0x3c3c), + W16(0x0000), W16(0xfff7), W16(0xffe0), W16(0x07ce), W16(0x3b58), + W16(0x0000), W16(0xfffa), W16(0xffe0), W16(0x07ae), W16(0x3a6b), + W16(0x0000), W16(0xfffe), W16(0xffe1), W16(0x0789), W16(0x3977), + W16(0x0000), W16(0xffff), W16(0xffe4), W16(0x075e), W16(0x387d), + W16(0x0000), W16(0xfffd), W16(0xffe8), W16(0x072d), W16(0x377e), + W16(0x0000), W16(0xfffd), W16(0xffee), W16(0x06f6), W16(0x367b), + W16(0x0000), W16(0xfffe), W16(0xfff4), W16(0x06b8), W16(0x3575), + W16(0x0000), W16(0xfffe), W16(0xfffb), W16(0x0674), W16(0x346d), + W16(0x0000), W16(0xfffe), W16(0x0002), W16(0x062a), W16(0x3363), + W16(0x0000), W16(0xffff), W16(0x000a), W16(0x05d9), W16(0x3257), + W16(0x0000), W16(0x0000), W16(0x0010), W16(0x0582), W16(0x314b), + W16(0x0000), W16(0xffff), W16(0x0016), W16(0x0524), W16(0x303c), + W16(0x0000), W16(0xffff), W16(0x001b), W16(0x04c0), W16(0x2f2c), + W16(0x0000), W16(0x0000), W16(0x0021), W16(0x0455), W16(0x2e19), + W16(0x0000), W16(0x0000), W16(0x0026), W16(0x03e4), W16(0x2d04), + W16(0x0000), W16(0x0000), W16(0x0029), W16(0x036d), W16(0x2bed), + W16(0x0000), W16(0x0000), W16(0x002c), W16(0x02f0), W16(0x2ad3), + W16(0x0000), W16(0x0000), W16(0x002d), W16(0x026c), W16(0x29b7), + W16(0x0000), W16(0x0000), W16(0x002c), W16(0x01e2), W16(0x2898), + W16(0x0000), W16(0xffff), W16(0x002b), W16(0x0151), W16(0x2778), + W16(0x0000), W16(0xfffe), W16(0x0029), W16(0x00bb), W16(0x2657), + W16(0x0000), W16(0xfffd), W16(0x0026), W16(0x001d), W16(0x2534), + W16(0x0000), W16(0xfffe), W16(0x0024), W16(0xff7a), W16(0x2411), + W16(0x0000), W16(0x0005), W16(0x0021), W16(0xfed0), W16(0x22ed), + W16(0x0000), W16(0x0009), W16(0x0021), W16(0xfe21), W16(0x21c8), + W16(0x0000), W16(0xfff5), W16(0x001f), W16(0xfd6b), W16(0x20a2), + W16(0x0000), W16(0xfff8), W16(0x0014), W16(0xfcae), W16(0x1f7c), + W16(0x0000), W16(0x0001), W16(0x0009), W16(0xfbeb), W16(0x1e54), + W16(0x0000), W16(0x0003), W16(0x0000), W16(0xfb23), W16(0x1d2c), + W16(0x0000), W16(0x0002), W16(0xfff7), W16(0xfa55), W16(0x1c03), + W16(0x0000), W16(0x0001), W16(0xffed), W16(0xf981), W16(0x1ad9), + W16(0x0000), W16(0xffff), W16(0xffe3), W16(0xf8a7), W16(0x19b0), + W16(0x0000), W16(0x0000), W16(0xffd8), W16(0xf7c8), W16(0x1886), + W16(0x0000), W16(0x0001), W16(0xffcf), W16(0xf6e3), W16(0x175d), + W16(0x0000), W16(0x0000), W16(0xffc5), W16(0xf5f9), W16(0x1636), + W16(0x0000), W16(0x0001), W16(0xffbc), W16(0xf50a), W16(0x150f), + W16(0x0000), W16(0x0001), W16(0xffb3), W16(0xf416), W16(0x13e9), + W16(0x0000), W16(0x0001), W16(0xffaa), W16(0xf31d), W16(0x12c5), + W16(0x0000), W16(0x0001), W16(0xffa2), W16(0xf21f), W16(0x11a0), + W16(0x0000), W16(0x0000), W16(0xff99), W16(0xf11d), W16(0x107b), + W16(0x0000), W16(0x0000), W16(0xff91), W16(0xf016), W16(0x0f55), + W16(0x0000), W16(0x0001), W16(0xff89), W16(0xef0b), W16(0x0e2c), + W16(0x0000), W16(0x0001), W16(0xff81), W16(0xedfc), W16(0x0d01), + W16(0x0000), W16(0x0001), W16(0xff79), W16(0xece9), W16(0x0bd4), + W16(0x0000), W16(0x0001), W16(0xff71), W16(0xebd2), W16(0x0aa5), + W16(0x0000), W16(0x0001), W16(0xff68), W16(0xeab8), W16(0x0976), + W16(0x0000), W16(0xfffd), W16(0xff5f), W16(0xe99b), W16(0x084a), + W16(0x0000), W16(0xfffe), W16(0xff55), W16(0xe87a), W16(0x0724), + W16(0x0000), W16(0x0003), W16(0xff4a), W16(0xe757), W16(0x0607), + W16(0x0000), W16(0x0006), W16(0xff3f), W16(0xe632), W16(0x04f9), + W16(0x0000), W16(0x0006), W16(0xff33), W16(0xe50a), W16(0x03fd), + W16(0x0000), W16(0x000c), W16(0xff27), W16(0xe3e1), W16(0x0315), + W16(0x0000), W16(0x0016), W16(0xff1a), W16(0xe2b7), W16(0x0244), + W16(0x0000), W16(0x001e), W16(0xff0d), W16(0xe18b), W16(0x017f), + W16(0x0002), W16(0x0020), W16(0xff00), W16(0xe05e), W16(0x00a9) +}; + + +/*! + * \brief CLDFB rRotVectr + * + * cldfb bands: 10 + * global gain: 8.00 + * scale: sqrt(1.0/16.00) + */ +const Word16 rRotVectr_10[] = +{ + W16(0x5a71), W16(0x54ea), W16(0x4714), W16(0x3249), W16(0x1891) +}; + +/*! + * \brief CLDFB iRotVectr + * + * cldfb bands: 10 + * global gain: 8.00 + * scale: sqrt(1.0/16.00) + */ +const Word16 iRotVectr_10[] = +{ + W16(0xfc72), W16(0xe0ac), W16(0xc7f7), W16(0xb4be), W16(0xa8e3) +}; + +/*! + * \brief CLDFB rRotVectr + * + * cldfb bands: 16 + * global gain: 5.00 + * scale: sqrt(1.0/8.00) + */ +const Word16 rRotVectr_16[] = +{ + W16(0x652a), W16(0x62bc), W16(0x5c83), W16(0x52bc), W16(0x45c7), + W16(0x3623), W16(0x246b), W16(0x114d) +}; + +/*! + * \brief CLDFB iRotVectr + * + * cldfb bands: 16 + * global gain: 5.00 + * scale: sqrt(1.0/8.00) + */ +const Word16 iRotVectr_16[] = +{ + W16(0xfd84), W16(0xe9d4), W16(0xd6fe), W16(0xc5bb), W16(0xb6b6), + W16(0xaa82), W16(0xa196), W16(0x9c4c) +}; +/*! + * \brief CLDFB rRotVectr + * + * cldfb bands: 20 + * global gain: 4.00 + * scale: sqrt(1.0/8.00) + */ +const Word16 rRotVectr_20[] = +{ + W16(0x5a7e), W16(0x591a), W16(0x5584), W16(0x4fd3), W16(0x482a), + W16(0x3ebb), W16(0x33c1), W16(0x2780), W16(0x1a46), W16(0x0c67) +}; + +/*! + * \brief CLDFB iRotVectr + * + * cldfb bands: 20 + * global gain: 4.00 + * scale: sqrt(1.0/8.00) + */ +const Word16 iRotVectr_20[] = +{ + W16(0xfe39), W16(0xf017), W16(0xe259), W16(0xd556), W16(0xc95f), + W16(0xbec1), W16(0xb5bf), W16(0xae90), W16(0xa963), W16(0xa658) +}; + +/*! + * \brief CLDFB rRotVectr + * + * cldfb bands: 32 + * global gain: 2.50 + * scale: sqrt(1.0/4.00) + */ +const Word16 rRotVectr_32[] = +{ + W16(0x652f), W16(0x6494), W16(0x6300), W16(0x6078), W16(0x5d02), + W16(0x58a7), W16(0x5371), W16(0x4d6e), W16(0x46ac), W16(0x3f3b), + W16(0x372f), W16(0x2e9a), W16(0x2593), W16(0x1c2f), W16(0x1286), + W16(0x08af) +}; +/*! + * \brief CLDFB iRotVectr + * + * cldfb bands: 32 + * global gain: 2.50 + * scale: sqrt(1.0/4.00) + */ +const Word16 iRotVectr_32[] = +{ + W16(0xfec2), W16(0xf4d9), W16(0xeb0b), W16(0xe170), W16(0xd821), + W16(0xcf35), W16(0xc6c1), W16(0xbed9), W16(0xb793), W16(0xb0ff), + W16(0xab2d), W16(0xa62d), W16(0xa20b), W16(0x9ed0), W16(0x9c84), + W16(0x9b2e) +}; + +/*! + * \brief CLDFB rRotVectr + * + * cldfb bands: 40 + * global gain: 2.00 + * scale: sqrt(1.0/4.00) + */ +const Word16 rRotVectr_40[] = +{ + W16(0x5a81), W16(0x5a28), W16(0x5941), W16(0x57cc), W16(0x55cd), + W16(0x5347), W16(0x503d), W16(0x4cb4), W16(0x48b3), W16(0x443e), + W16(0x3f5e), W16(0x3a1a), W16(0x347b), W16(0x2e88), W16(0x284c), + W16(0x21d0), W16(0x1b1f), W16(0x1444), W16(0x0d48), W16(0x0637) +}; + +/*! + * \brief CLDFB iRotVectr + * + * cldfb bands: 40 + * global gain: 2.00 + * scale: sqrt(1.0/4.00) + */ +const Word16 iRotVectr_40[] = +{ + W16(0xff1d), W16(0xf803), W16(0xf0f7), W16(0xea02), W16(0xe330), + W16(0xdc8b), W16(0xd61f), W16(0xcff4), W16(0xca15), W16(0xc48c), + W16(0xbf60), W16(0xba9a), W16(0xb642), W16(0xb25e), W16(0xaef5), + W16(0xac0b), W16(0xa9a6), W16(0xa7ca), W16(0xa678), W16(0xa5b4) +}; + +/*! + * \brief CLDFB rRotVectr + * + * cldfb bands: 60 + * global gain: 1.33 + * scale: sqrt(1.0/2.00) + */ +const Word16 rRotVectr_60[] = +{ + W16(0x6882), W16(0x6855), W16(0x67de), W16(0x671e), W16(0x6615), + W16(0x64c5), W16(0x632f), W16(0x6153), W16(0x5f32), W16(0x5ccf), + W16(0x5a2a), W16(0x5747), W16(0x5426), W16(0x50ca), W16(0x4d35), + W16(0x496a), W16(0x456c), W16(0x413d), W16(0x3ce0), W16(0x3859), + W16(0x33aa), W16(0x2ed6), W16(0x29e2), W16(0x24d0), W16(0x1fa5), + W16(0x1a63), W16(0x150f), W16(0x0fac), W16(0x0a3e), W16(0x04c9) +}; + +/*! + * \brief CLDFB iRotVectr + * + * cldfb bands: 60 + * global gain: 1.33 + * scale: sqrt(1.0/2.00) + */ +const Word16 iRotVectr_60[] = +{ + W16(0xff51), W16(0xf9d9), W16(0xf465), W16(0xeefa), W16(0xe99a), + W16(0xe44a), W16(0xdf0e), W16(0xd9e9), W16(0xd4de), W16(0xcff2), + W16(0xcb27), W16(0xc682), W16(0xc204), W16(0xbdb3), W16(0xb990), + W16(0xb59e), W16(0xb1e0), W16(0xae5a), W16(0xab0c), W16(0xa7fb), + W16(0xa526), W16(0xa292), W16(0xa03f), W16(0x9e30), W16(0x9c65), + W16(0x9ae0), W16(0x99a2), W16(0x98ac), W16(0x97fe), W16(0x9799) +}; + +const Word16 cldfb_anaScale[] = +{ + SCALE_CLDFB_ANA_10, SCALE_CLDFB_ANA_16, SCALE_CLDFB_ANA_20, SCALE_CLDFB_ANA_32, SCALE_CLDFB_ANA_40, SCALE_CLDFB_ANA_60 +}; +const Word16 cldfb_synScale[] = +{ + SCALE_CLDFB_SYN_10, SCALE_CLDFB_SYN_16, SCALE_CLDFB_SYN_20, SCALE_CLDFB_SYN_32, SCALE_CLDFB_SYN_40, SCALE_CLDFB_SYN_60 +}; +const Word16 cldfb_synGain[] = +{ + 0x6666, /* 10 bands */ + 0x51EC, /* 16 bands */ + 0x6666, /* 20 bands */ + 0x51EC, /* 32 bands */ + 0x6666, /* 40 bands */ + 0x4CCD /* 60 bands */ +}; + +const Word16 *cldfb_protoFilter_2_5ms[] = +{ + CLDFB80_10, CLDFB80_16, CLDFB80_20, CLDFB80_32, CLDFB80_40, CLDFB80_60 +}; +const Word16 cldfb_scale_2_5ms[7] = +{ + 22603/*88.293854 Q8*/, /* 10 bands */ + 22605/*88.299622 Q8*/, /* 16 bands */ + 22605/*88.300926 Q8*/, /* 20 bands */ + 22606/*88.303848 Q8*/, /* 32 bands */ + 22606/*88.304718 Q8*/, /* 40 bands */ + 22535/*88.028412 Q8*/ /* 60 bands */ +}; const float rot_vec_syn_re_L10[5] = { 0.1117172025f,0.1048929802f,0.0878011021f,0.0621146404f,0.0303479649f, @@ -6634,7 +9743,13 @@ const float bpf_weights_16[CLDFB_NO_COL_MAX] = 1.000040f, 0.702561f, 0.208838f, 0.001553f, 0.001777f, 0.001370f, 0.000926f, 0.000554f, 0.000270f, 0.000080f, 0.000030f, 0.000082f, 0.000081f, 0.000052f, 0.000017f, 0.000016f }; - +const Word16 bpf_weights_16_Fx[16] = +{ + 16385/*0.500020f Q15*/, 23022/*0.702561f Q15*/, 6843/*0.208838f Q15*/, 51/*0.001553f Q15*/, + 58/*0.001777f Q15*/, 45/*0.001370f Q15*/, 30/*0.000926f Q15*/, 18/*0.000554f Q15*/, + 9/*0.000270f Q15*/, 3/*0.000080f Q15*/, 1/*0.000030f Q15*/, 3/*0.000082f Q15*/, + 3/*0.000081f Q15*/, 2/*0.000052f Q15*/, 1/*0.000017f Q15*/, 1/*0.000016f Q15*/ +}; /*-------------------------------------------------------------------* * LP CNG excitation details code book *-------------------------------------------------------------------*/ @@ -6963,16 +10078,87 @@ const float CNG_details_codebook[64][NUM_ENV_CNG]= } }; - +const Word16 CNG_details_codebook_fx[64][NUM_ENV_CNG] = /* Q6 */ +{ + {443,547,613,547,510,471,540,479,586,535,565,611,532,500,462,551,498,463,446,484}, + {600,499,472,537,633,654,641,646,674,677,687,693,693,690,688,700,693,696,640,571}, + {529,537,501,582,537,474,505,491,521,545,561,591,566,609,570,608,636,655,649,524}, + {648,690,689,684,693,599,668,714,663,675,524,519,726,658,673,696,654,715,708,668}, + {623,630,660,656,686,688,637,666,630,555,470,468,464,445,502,583,615,545,605,592}, + {659,668,669,625,662,700,700,693,702,702,688,677,654,584,525,492,446,477,634,615}, + {634,648,656,552,520,557,662,659,572,617,691,683,684,666,673,695,682,698,680,623}, + {756,743,734,709,730,757,746,722,484,552,779,688,686,610,616,749,758,694,745,729}, + {549,568,556,625,683,619,609,667,663,684,709,649,691,668,594,511,525,617,542,684}, + {550,467,533,760,739,692,773,756,743,770,765,791,779,784,775,792,759,577,642,553}, + {658,674,656,651,670,582,593,520,467,470,522,589,600,596,587,631,652,679,645,669}, + {788,765,787,797,785,799,787,786,780,692,641,550,501,513,726,747,670,687,734,773}, + {641,654,668,673,665,682,689,684,697,665,664,593,544,494,458,537,622,650,635,635}, + {706,753,762,716,748,762,788,792,785,788,799,777,782,766,760,710,704,503,519,735}, + {748,775,784,635,717,504,539,640,764,778,681,721,791,786,787,780,780,770,774,781}, + {752,516,624,780,713,753,569,548,770,784,749,740,690,755,776,748,744,730,767,698}, + {453,471,516,517,561,653,659,616,629,608,682,698,679,681,645,587,594,522,499,469}, + {617,534,506,615,782,792,754,771,740,787,791,776,782,787,793,788,775,778,651,736}, + {661,593,490,495,491,495,554,656,658,611,628,660,680,677,698,678,673,699,687,679}, + {798,793,786,795,799,772,771,696,624,557,507,545,724,757,747,770,780,785,793,784}, + {703,695,703,714,697,701,697,631,598,498,475,451,503,611,648,664,664,683,679,688}, + {744,672,659,762,785,745,757,761,761,767,722,757,761,737,699,471,582,770,724,756}, + {775,746,535,680,541,513,697,723,743,744,769,741,741,738,769,772,779,743,714,724}, + {767,771,697,756,766,752,710,477,602,783,746,766,692,708,783,782,761,778,787,785}, + {483,588,700,665,665,640,650,717,699,707,692,698,700,692,668,650,609,610,540,484}, + {507,618,788,766,754,692,709,785,788,770,793,785,799,784,767,776,789,759,761,495}, + {709,712,706,678,661,604,503,480,653,664,664,639,621,675,695,689,704,681,711,709}, + {788,740,770,768,771,776,732,749,739,764,714,492,544,783,714,708,717,559,739,768}, + {758,771,789,779,777,799,791,785,779,779,752,675,718,510,501,600,727,750,752,758}, + {759,765,676,658,774,767,737,749,769,784,778,738,755,769,788,756,473,530,777,725}, + {669,665,721,653,499,774,780,781,767,561,690,747,722,779,757,727,764,745,770,736}, + {731,768,745,775,783,782,715,741,786,673,766,777,764,730,773,769,774,781,778,764}, + {557,505,545,604,660,672,604,596,580,612,587,556,546,597,530,494,437,480,546,555}, + {560,588,510,495,606,720,718,742,756,755,767,774,776,778,772,772,776,776,754,592}, + {680,644,620,612,516,477,471,499,502,598,664,588,656,682,689,671,668,672,682,692}, + {757,778,781,799,775,750,799,758,789,774,489,579,799,739,774,723,686,788,787,778}, + {705,685,654,680,672,680,657,579,574,619,639,518,482,545,665,587,540,599,606,651}, + {729,767,767,773,783,778,793,773,784,779,757,768,686,654,679,564,483,549,490,522}, + {725,693,715,588,522,629,721,647,697,684,614,725,708,674,715,729,717,725,689,738}, + {797,783,795,797,782,757,636,624,508,517,703,750,746,757,772,771,774,790,779,799}, + {556,591,652,692,728,712,698,688,704,718,728,717,713,693,716,558,490,540,620,678}, + {532,617,777,775,763,789,768,785,778,791,792,792,793,777,781,724,551,665,540,509}, + {710,697,706,717,673,679,620,581,546,474,562,684,680,675,660,656,702,680,701,708}, + {771,793,788,787,794,791,792,783,791,792,733,770,532,525,692,761,777,753,734,728}, + {724,695,678,652,695,735,697,712,714,721,696,710,569,581,570,522,642,704,748,726}, + {796,754,785,782,732,814,803,794,799,790,810,806,794,797,756,745,749,506,741,779}, + {793,767,785,780,724,648,488,747,784,771,793,740,759,805,794,796,795,795,801,806}, + {787,508,640,775,722,792,774,705,781,801,774,800,786,806,808,783,795,797,784,782}, + {654,649,601,597,594,667,646,662,615,623,651,671,669,674,682,653,624,484,473,665}, + {790,765,479,527,746,728,770,753,721,774,794,802,789,782,803,795,764,804,779,776}, + {738,699,642,509,515,501,466,614,702,612,683,720,687,717,704,739,714,733,721,718}, + {778,795,791,786,758,783,783,743,744,527,554,789,762,767,722,722,777,788,776,782}, + {694,696,700,696,709,710,696,689,674,662,581,538,496,637,644,681,679,671,689,704}, + {776,788,742,796,779,756,788,789,782,798,795,804,771,753,571,611,504,545,593,779}, + {799,717,747,682,487,573,766,774,775,762,711,802,799,796,790,787,802,789,773,786}, + {795,797,790,804,788,791,774,706,532,770,786,743,789,708,755,785,804,803,807,770}, + {568,722,738,680,713,703,693,749,703,705,740,720,712,631,621,727,730,722,574,612}, + {626,762,734,770,759,750,792,775,790,792,788,786,791,767,782,778,794,745,504,544}, + {774,784,779,753,654,560,530,532,555,699,742,695,716,767,770,772,778,780,779,782}, + {781,781,790,783,792,798,787,792,765,740,701,537,564,773,767,756,786,797,789,801}, + {738,717,799,794,772,784,774,790,788,748,789,769,768,763,504,587,783,751,784,732}, + {776,789,763,772,800,786,802,787,805,799,776,773,792,761,750,702,532,745,807,735}, + {765,778,764,484,607,791,757,760,700,687,789,777,779,783,768,791,778,757,784,770}, + {800,825,775,782,821,679,805,824,752,824,796,785,829,817,824,803,814,807,762,779} +}; /*-------------------------------------------------------------------* * FD CNG *-------------------------------------------------------------------*/ const int16_t d_array[SIZE_SCALE_TABLE_CN] = { 1, 2, 5, 8, 10, 15, 20, 30, 40, 60, 80, 120, 140, 160, 180, 220, 260, 300 }; -const float m_array[SIZE_SCALE_TABLE_CN] = { 0.000f, 0.260f, 0.480f, 0.580f, 0.610f, 0.668f, 0.705f, 0.762f, 0.800f, 0.841f, 0.865f, 0.890f, 0.900f, 0.910f, 0.920f, 0.930f, 0.935f, 0.940f }; +const float m_array_flt[SIZE_SCALE_TABLE_CN] = { 0.000f, 0.260f, 0.480f, 0.580f, 0.610f, 0.668f, 0.705f, 0.762f, 0.800f, 0.841f, 0.865f, 0.890f, 0.900f, 0.910f, 0.920f, 0.930f, 0.935f, 0.940f }; +const Word16 m_array[SIZE_SCALE_TABLE_CN] = { 0/*0.000f Q15*/, 8520/*0.260f Q15*/, 15729/*0.480f Q15*/, 19005/*0.580f Q15*/, 19988/*0.610f Q15*/, 21889/*0.668f Q15*/, 23101/*0.705f Q15*/, 24969/*0.762f Q15*/, 26214/*0.800f Q15*/, 27558/*0.841f Q15*/, 28344/*0.865f Q15*/, 29164/*0.890f Q15*/, 29491/*0.900f Q15*/, 29819/*0.910f Q15*/, 30147/*0.920f Q15*/, 30474/*0.930f Q15*/, 30638/*0.935f Q15*/, 30802/*0.940f Q15*/ }; + +const float msQeqInvAv_thresh_flt[3] = { 0.01f, 0.03f, 0.05f }; +const Word16 msQeqInvAv_thresh[3] = { 328/*0.01f Q15*/, 983/*0.03f Q15*/, 1638/*0.05f Q15*/ }; + +const float msNoiseSlopeMax_flt[4] = { 2.f, 1.6f, 1.3f, 1.1f }; +const Word16 msNoiseSlopeMax[4] = { 32767/*2.f Q14*/, 26214/*1.6f Q14*/, 21299/*1.3f Q14*/, 18022/*1.1f Q14*/ }; -const float msQeqInvAv_thresh[3] = { 0.01f, 0.03f, 0.05f }; -const float msNoiseSlopeMax[4] = { 2.f, 1.6f, 1.3f, 1.1f }; const SCALE_SETUP scaleTableStereo[SIZE_SCALE_TABLE_STEREO] = { @@ -7068,13 +10254,18 @@ const SCALE_SETUP scaleTable_cn_dirac[15] = { 2, 24400, 32000, -1.5f, 6759/*0.4125375748 Q14*/ /*-1.5f*/ }, { 2, 32000,512001, 0.0f, 0/*0.0000000000 Q14*/ /* 0.0f*/ } }; -const float scaleTable_cn_only_amrwbio[SIZE_SCALE_TABLE_CN_AMRWB][2] = +const float scaleTable_cn_only_amrwbio_flt[SIZE_SCALE_TABLE_CN_AMRWB][2] = { { ACELP_6k60, -4.0f }, { ACELP_8k85, -3.0f }, { ACELP_12k65, -2.0f } }; - +const Word16 scaleTable_cn_only_amrwbio[3][2] = +{ + { ACELP_6k60, 24771/*1.5118864315 Q14*/ }, + { ACELP_8k85, 16306/*0.9952622652 Q14*/ }, + { ACELP_12k65, 9583/*0.5848932266 Q14*/ }, +}; const int16_t sidparts_encoder_noise_est[SIZE_SIDPARTS_ENC_NOISE_EST] = { 4, 8, 12, 16, 20, 24, 30, 36, 42, 50, 58, 68, 80, 92, 108, 126, 148, 176, 212, 255, 259, 264, 269, 279 }; @@ -7866,11 +11057,1381 @@ const float cdk_37bits_6[1536] = 0.11622122f , 0.02224264f , 0.32680233f , 0.00674035f , -0.18269996f , -0.07149903f , -0.38216845f , 0.11519523f , 0.15289458f , 0.02026007f , 0.31202256f , 0.38286848f , 0.06066707f , -0.11169249f , -0.10677312f , -0.20147411f , 0.01167547f , 0.11246367f , -0.70525138f , -0.69991387f , 1.00946560f , 0.95344512f , -0.75251996f , 0.27342287f }; -const float * const cdk_37bits[] = { cdk_37bits_1, cdk_37bits_2, cdk_37bits_3, cdk_37bits_4, cdk_37bits_5, cdk_37bits_6 }; +const float * const cdk_37bits_flt[] = { cdk_37bits_1, cdk_37bits_2, cdk_37bits_3, cdk_37bits_4, cdk_37bits_5, cdk_37bits_6 }; const float * const cdk_37bits_ivas[] = { NULL, cdk_37bits_2, cdk_37bits_3, cdk_37bits_4, cdk_37bits_5, cdk_37bits_6 }; - +const Word16 cdk_37bits_1_fx[3072] = +{ + W16(0x017B), W16(0x0548), W16(0x068C), W16(0x058B), W16(0x0572), W16(0x0577), W16(0x04BC), W16(0x03C0), + W16(0x0399), W16(0x0237), W16(0x00A1), W16(0xFEB3), W16(0xFCFA), W16(0xFC2F), W16(0xFACB), W16(0xFA70), + W16(0xF914), W16(0xF6A8), W16(0xF439), W16(0xF145), W16(0xF02C), W16(0xEFDD), W16(0xEE63), W16(0xED8C), + W16(0x089B), W16(0x0B41), W16(0x08E4), W16(0x079C), W16(0x05CF), W16(0x03F9), W16(0x03E0), W16(0x031E), + W16(0x02E2), W16(0x0212), W16(0x0015), W16(0xFECD), W16(0xFF39), W16(0xFE3F), W16(0xFBE8), W16(0xFA04), + W16(0xF7FF), W16(0xF5BC), W16(0xF361), W16(0xF14A), W16(0xEFCE), W16(0xEDF1), W16(0xEC58), W16(0xEB8A), + W16(0x0815), W16(0x0642), W16(0x0569), W16(0x03C1), W16(0x044B), W16(0x04DB), W16(0x0474), W16(0x03DF), + W16(0x0432), W16(0x030C), W16(0x0121), W16(0xFF19), W16(0xFD1C), W16(0xFCAE), W16(0xFAF1), W16(0xF9F7), + W16(0xF85E), W16(0xF5DD), W16(0xF370), W16(0xF072), W16(0xEF52), W16(0xEF6F), W16(0xEE06), W16(0xED0C), + W16(0x10A9), W16(0x0DA2), W16(0x0C21), W16(0x0A1E), W16(0x0854), W16(0x07D7), W16(0x0690), W16(0x0658), + W16(0x043C), W16(0x036E), W16(0x00B9), W16(0xFE78), W16(0xFC8A), W16(0xFAEB), W16(0xF926), W16(0xF6C2), + W16(0xF4B5), W16(0xF2B1), W16(0xF0CD), W16(0xEED0), W16(0xEDF7), W16(0xEC97), W16(0xEBD3), W16(0xEB6E), + W16(0xFA8A), W16(0x0181), W16(0x03DF), W16(0x04A4), W16(0x0331), W16(0x0599), W16(0x04DB), W16(0x03CB), + W16(0x0005), W16(0x0161), W16(0xFF3F), W16(0xFEFE), W16(0xFEC7), W16(0xFCED), W16(0xFB97), W16(0xFBA7), + W16(0xFBFC), W16(0xFA73), W16(0xF96A), W16(0xF909), W16(0xF92B), W16(0xF7C3), W16(0xF6C5), W16(0xF5F7), + W16(0x1095), W16(0x0E41), W16(0x096C), W16(0x0813), W16(0x0652), W16(0x046A), W16(0x0423), W16(0x0350), + W16(0x034C), W16(0x023D), W16(0x0074), W16(0xFEC0), W16(0xFF76), W16(0xFE66), W16(0xFB60), W16(0xF90E), + W16(0xF6CC), W16(0xF4B3), W16(0xF27A), W16(0xF058), W16(0xEF09), W16(0xED48), W16(0xEBE3), W16(0xEB2E), + W16(0x0DA9), W16(0x0772), W16(0x056E), W16(0x041F), W16(0x039A), W16(0x0308), W16(0x02C3), W16(0x0275), + W16(0x0221), W16(0x01B5), W16(0x00ED), W16(0x0049), W16(0xFEF4), W16(0xFD31), W16(0xFC0A), W16(0xFBD5), + W16(0xFB17), W16(0xF8FF), W16(0xF705), W16(0xF603), W16(0xF494), W16(0xF2D4), W16(0xF031), W16(0xEDB6), + W16(0x14D0), W16(0x0F44), W16(0x0DF3), W16(0x0C0E), W16(0x0938), W16(0x07D3), W16(0x06C1), W16(0x0522), + W16(0x0475), W16(0x02EA), W16(0x004B), W16(0xFE88), W16(0xFC2B), W16(0xFAAC), W16(0xF8C9), W16(0xF73A), + W16(0xF605), W16(0xF554), W16(0xF3ED), W16(0xF31F), W16(0xF305), W16(0xF26A), W16(0xF225), W16(0xF1E6), + W16(0xFE9B), W16(0x0403), W16(0x0558), W16(0x0336), W16(0x0433), W16(0x02F7), W16(0x01DD), W16(0x012C), + W16(0x016C), W16(0x0124), W16(0x0041), W16(0xFFAF), W16(0xFF0E), W16(0xFE2D), W16(0xFCE7), W16(0xFC8B), + W16(0xFCA0), W16(0xFB7D), W16(0xF975), W16(0xF831), W16(0xF73E), W16(0xF582), W16(0xF394), W16(0xF20E), + W16(0x079D), W16(0x0AD6), W16(0x0B5A), W16(0x09A9), W16(0x084A), W16(0x0738), W16(0x066E), W16(0x0608), + W16(0x047C), W16(0x02E1), W16(0x0059), W16(0xFE81), W16(0xFCD0), W16(0xFABD), W16(0xF93B), W16(0xF769), + W16(0xF5A1), W16(0xF44F), W16(0xF26B), W16(0xEFCD), W16(0xEE85), W16(0xECDA), W16(0xEBE5), W16(0xEB83), + W16(0x04A1), W16(0x0509), W16(0x0556), W16(0x044A), W16(0x038A), W16(0x030A), W16(0x02B8), W16(0x0255), + W16(0x0212), W16(0x01BB), W16(0x0101), W16(0x0035), W16(0xFEEC), W16(0xFD22), W16(0xFC1D), W16(0xFBF2), + W16(0xFB3F), W16(0xF91E), W16(0xF70F), W16(0xF5E9), W16(0xF49C), W16(0xF2E0), W16(0xF02D), W16(0xEDA3), + W16(0x0D77), W16(0x0DC1), W16(0x0D75), W16(0x0AA8), W16(0x0814), W16(0x065D), W16(0x0456), W16(0x0451), + W16(0x0310), W16(0x02B3), W16(0x0134), W16(0xFEFC), W16(0xFD02), W16(0xFB55), W16(0xFA2D), W16(0xF891), + W16(0xF7E0), W16(0xF6F0), W16(0xF59C), W16(0xF425), W16(0xF3A2), W16(0xF253), W16(0xF1DF), W16(0xF188), + W16(0x0274), W16(0x04F8), W16(0x0575), W16(0x048C), W16(0x044E), W16(0x0467), W16(0x0413), W16(0x040C), + W16(0x0213), W16(0x00C8), W16(0x001D), W16(0xFEF2), W16(0xFE21), W16(0xFCF7), W16(0xFC59), W16(0xFB5C), + W16(0xFA76), W16(0xF9A5), W16(0xF914), W16(0xF8D4), W16(0xF853), W16(0xF770), W16(0xF5D5), W16(0xF40D), + W16(0x1148), W16(0x0E53), W16(0x09F3), W16(0x085C), W16(0x0711), W16(0x04CC), W16(0x0453), W16(0x03F2), + W16(0x03BA), W16(0x0278), W16(0x0090), W16(0xFF0A), W16(0xFED1), W16(0xFD92), W16(0xFA84), W16(0xF871), + W16(0xF6BA), W16(0xF489), W16(0xF23B), W16(0xEFD0), W16(0xEED3), W16(0xED71), W16(0xEC93), W16(0xEBF6), + W16(0x0AED), W16(0x075D), W16(0x05A3), W16(0x0493), W16(0x0446), W16(0x0463), W16(0x0411), W16(0x0422), + W16(0x0219), W16(0x00C6), W16(0x001A), W16(0xFF06), W16(0xFE27), W16(0xFCEF), W16(0xFC57), W16(0xFB4F), + W16(0xFA6B), W16(0xF9A0), W16(0xF90D), W16(0xF8CA), W16(0xF827), W16(0xF757), W16(0xF5C4), W16(0xF400), + W16(0x155D), W16(0x0F9F), W16(0x0C38), W16(0x09DC), W16(0x07A7), W16(0x053D), W16(0x03A9), W16(0x051C), + W16(0x04ED), W16(0x02A2), W16(0x00D4), W16(0xFF7C), W16(0xFDB2), W16(0xFBBA), W16(0xF8EA), W16(0xF824), + W16(0xF7FD), W16(0xF68C), W16(0xF3DB), W16(0xF2A3), W16(0xF27D), W16(0xF19C), W16(0xF0C9), W16(0xEFDB), + W16(0xFFCD), W16(0x038E), W16(0x0463), W16(0x037C), W16(0x0340), W16(0x02A6), W16(0x02AB), W16(0x0290), + W16(0x0288), W16(0x01E2), W16(0x00EF), W16(0x002F), W16(0xFEA6), W16(0xFDA9), W16(0xFCAC), W16(0xFBAE), + W16(0xFAAF), W16(0xF96E), W16(0xF84B), W16(0xF6F3), W16(0xF4CD), W16(0xF2DA), W16(0xF0F7), W16(0xEEFD), + W16(0x0C53), W16(0x0BF8), W16(0x0C2B), W16(0x0A1A), W16(0x077A), W16(0x0556), W16(0x03F4), W16(0x03E3), + W16(0x0259), W16(0x01FA), W16(0x0084), W16(0xFE9B), W16(0xFD34), W16(0xFBF2), W16(0xFAFB), W16(0xF9EA), + W16(0xF9DD), W16(0xF9E2), W16(0xF898), W16(0xF6CB), W16(0xF505), W16(0xF2D8), W16(0xF195), W16(0xF0B6), + W16(0x07BE), W16(0x054B), W16(0x0435), W16(0x030E), W16(0x03A2), W16(0x03DA), W16(0x0342), W16(0x026B), + W16(0x01E4), W16(0x0170), W16(0x00CE), W16(0x0009), W16(0xFDFF), W16(0xFE36), W16(0xFCBF), W16(0xFC00), + W16(0xF9B8), W16(0xF7AD), W16(0xF51D), W16(0xF180), W16(0xF15B), W16(0xF1C5), W16(0xF045), W16(0xEF23), + W16(0x0FD5), W16(0x0D41), W16(0x0B8A), W16(0x09BD), W16(0x0838), W16(0x0754), W16(0x0692), W16(0x0611), + W16(0x0487), W16(0x02ED), W16(0x0044), W16(0xFE7B), W16(0xFCBA), W16(0xFAA6), W16(0xF92D), W16(0xF773), + W16(0xF59D), W16(0xF47B), W16(0xF29E), W16(0xEFF4), W16(0xEE86), W16(0xECCF), W16(0xEBD8), W16(0xEB78), + W16(0xFDB6), W16(0x0365), W16(0x05CE), W16(0x0610), W16(0x0505), W16(0x035E), W16(0x02CE), W16(0x01CF), + W16(0x0089), W16(0x00B8), W16(0xFFD1), W16(0xFF08), W16(0xFEAA), W16(0xFE04), W16(0xFDC1), W16(0xFC29), + W16(0xFC4E), W16(0xFB7A), W16(0xFAAD), W16(0xF9D2), W16(0xF818), W16(0xF6F3), W16(0xF5A0), W16(0xF46B), + W16(0x1008), W16(0x0D2C), W16(0x08D0), W16(0x0746), W16(0x05AB), W16(0x039D), W16(0x035A), W16(0x0295), + W16(0x02A9), W16(0x01D8), W16(0x001B), W16(0xFF0D), W16(0xFF48), W16(0xFE4F), W16(0xFBEB), W16(0xFA8C), + W16(0xF912), W16(0xF65C), W16(0xF3E1), W16(0xF14F), W16(0xEF83), W16(0xED7D), W16(0xEBAE), W16(0xEACA), + W16(0x0DAD), W16(0x08AD), W16(0x075B), W16(0x059B), W16(0x04DC), W16(0x0476), W16(0x03F2), W16(0x025C), + W16(0x010B), W16(0x009F), W16(0xFFDA), W16(0xFE63), W16(0xFDF1), W16(0xFDBE), W16(0xFD7D), W16(0xFC45), + W16(0xFB08), W16(0xFA08), W16(0xF8CA), W16(0xF795), W16(0xF5B6), W16(0xF412), W16(0xF2D3), W16(0xF1F4), + W16(0x15E3), W16(0x0F2D), W16(0x0DD2), W16(0x0BB2), W16(0x0912), W16(0x080C), W16(0x06B1), W16(0x0509), + W16(0x03F9), W16(0x0210), W16(0xFF8C), W16(0xFE56), W16(0xFC61), W16(0xFAFD), W16(0xF94E), W16(0xF7D6), + W16(0xF6BB), W16(0xF61C), W16(0xF49D), W16(0xF3F1), W16(0xF3E4), W16(0xF35B), W16(0xF31D), W16(0xF2DF), + W16(0x02E6), W16(0x0643), W16(0x0700), W16(0x05A9), W16(0x04E3), W16(0x047E), W16(0x03C0), W16(0x0266), + W16(0x012B), W16(0x0098), W16(0xFFD2), W16(0xFE89), W16(0xFDF6), W16(0xFD9F), W16(0xFD4A), W16(0xFC4C), + W16(0xFB32), W16(0xFA7B), W16(0xF96E), W16(0xF878), W16(0xF743), W16(0xF5CA), W16(0xF486), W16(0xF36B), + W16(0x080C), W16(0x0B47), W16(0x0BE1), W16(0x0A0A), W16(0x086F), W16(0x079C), W16(0x06AD), W16(0x063D), + W16(0x0465), W16(0x031D), W16(0x0054), W16(0xFE68), W16(0xFCB0), W16(0xFAAD), W16(0xF917), W16(0xF735), + W16(0xF525), W16(0xF3D8), W16(0xF29D), W16(0xF191), W16(0xF0EF), W16(0xF025), W16(0xEF93), W16(0xEF3F), + W16(0x0839), W16(0x0628), W16(0x04DB), W16(0x039C), W16(0x0365), W16(0x02CB), W16(0x029E), W16(0x02A9), + W16(0x02BC), W16(0x01F6), W16(0x0101), W16(0x0026), W16(0xFEB0), W16(0xFDA0), W16(0xFC84), W16(0xFB74), + W16(0xFA68), W16(0xF932), W16(0xF804), W16(0xF691), W16(0xF46D), W16(0xF26E), W16(0xF079), W16(0xEE80), + W16(0x0AC8), W16(0x0CCE), W16(0x0DA8), W16(0x0C60), W16(0x0994), W16(0x083E), W16(0x06D0), W16(0x0529), + W16(0x03EA), W16(0x0249), W16(0xFFB9), W16(0xFE3A), W16(0xFC21), W16(0xFAFA), W16(0xF90B), W16(0xF78E), + W16(0xF65C), W16(0xF571), W16(0xF418), W16(0xF331), W16(0xF33A), W16(0xF29F), W16(0xF24C), W16(0xF219), + W16(0x05E1), W16(0x05CC), W16(0x05EE), W16(0x060D), W16(0x0517), W16(0x0357), W16(0x02C0), W16(0x01D0), + W16(0x0085), W16(0x00B0), W16(0xFFD1), W16(0xFF12), W16(0xFEAD), W16(0xFE06), W16(0xFDBA), W16(0xFC2D), + W16(0xFC50), W16(0xFB87), W16(0xFAB7), W16(0xF9DA), W16(0xF80B), W16(0xF6EC), W16(0xF59D), W16(0xF469), + W16(0x11D1), W16(0x0F70), W16(0x0A08), W16(0x087F), W16(0x068E), W16(0x04B0), W16(0x0432), W16(0x0375), + W16(0x0389), W16(0x023A), W16(0x0028), W16(0xFEB9), W16(0xFF3A), W16(0xFE36), W16(0xFAFC), W16(0xF915), + W16(0xF6F6), W16(0xF510), W16(0xF2CC), W16(0xF0F8), W16(0xEFEB), W16(0xEE83), W16(0xED84), W16(0xECD7), + W16(0x0B3B), W16(0x096D), W16(0x06CD), W16(0x050E), W16(0x04AD), W16(0x034C), W16(0x0288), W16(0x0224), + W16(0x0190), W16(0x0137), W16(0x0015), W16(0xFF8F), W16(0xFE3C), W16(0xFDD9), W16(0xFD04), W16(0xFC60), + W16(0xFB77), W16(0xFAAD), W16(0xF9FB), W16(0xF936), W16(0xF7EF), W16(0xF65B), W16(0xF5A2), W16(0xF4D2), + W16(0x16C0), W16(0x0F48), W16(0x0C90), W16(0x09AC), W16(0x0757), W16(0x058C), W16(0x03D0), W16(0x03AF), + W16(0x0284), W16(0x0249), W16(0x00FA), W16(0xFF36), W16(0xFD66), W16(0xFC00), W16(0xFB05), W16(0xF96E), + W16(0xF8C8), W16(0xF7E7), W16(0xF66D), W16(0xF49F), W16(0xF350), W16(0xF21E), W16(0xF1CA), W16(0xF174), + W16(0xFFE5), W16(0x03B4), W16(0x04C3), W16(0x0399), W16(0x0448), W16(0x049E), W16(0x0425), W16(0x035F), + W16(0x03B2), W16(0x0263), W16(0x00C3), W16(0xFED0), W16(0xFCF3), W16(0xFCDA), W16(0xFBD9), W16(0xFADE), + W16(0xF96B), W16(0xF760), W16(0xF516), W16(0xF1F5), W16(0xF126), W16(0xF0FC), W16(0xEFBB), W16(0xEE91), + W16(0x0A14), W16(0x0BD9), W16(0x0A05), W16(0x08A9), W16(0x06EE), W16(0x04E1), W16(0x0468), W16(0x03AB), + W16(0x0385), W16(0x026A), W16(0x005B), W16(0xFED5), W16(0xFECC), W16(0xFD95), W16(0xFAE2), W16(0xF8D1), + W16(0xF6EB), W16(0xF51F), W16(0xF2F7), W16(0xF0C4), W16(0xEFFB), W16(0xEEB0), W16(0xEDCF), W16(0xED30), + W16(0x0A84), W16(0x07B7), W16(0x0699), W16(0x0588), W16(0x04F8), W16(0x0512), W16(0x0439), W16(0x0387), + W16(0x0354), W16(0x01E7), W16(0x0081), W16(0xFEBF), W16(0xFD3C), W16(0xFC6A), W16(0xFB27), W16(0xFB1A), + W16(0xF9D4), W16(0xF7D3), W16(0xF57F), W16(0xF254), W16(0xF0C2), W16(0xF08D), W16(0xEF08), W16(0xEE09), + W16(0x10BB), W16(0x0E08), W16(0x0CA3), W16(0x0ABA), W16(0x0932), W16(0x0815), W16(0x0737), W16(0x0671), + W16(0x04A3), W16(0x0325), W16(0x0024), W16(0xFE61), W16(0xFC7D), W16(0xFA41), W16(0xF8AF), W16(0xF6FF), + W16(0xF459), W16(0xF2FA), W16(0xF103), W16(0xEF58), W16(0xEE8C), W16(0xED3F), W16(0xEC8D), W16(0xEC48), + W16(0xFCE7), W16(0x0381), W16(0x0337), W16(0x05B9), W16(0x054D), W16(0x01C2), W16(0x0285), W16(0x05FF), + W16(0x013C), W16(0x0143), W16(0x0019), W16(0xFFAB), W16(0xFE36), W16(0xFDDC), W16(0xFC25), W16(0xFB58), + W16(0xFA9A), W16(0xF9FC), W16(0xF8BF), W16(0xF861), W16(0xF87B), W16(0xF713), W16(0xF660), W16(0xF5C9), + W16(0x112E), W16(0x0E94), W16(0x08F3), W16(0x07FC), W16(0x0620), W16(0x044C), W16(0x0403), W16(0x035F), + W16(0x0357), W16(0x0235), W16(0x0029), W16(0xFEA5), W16(0xFF72), W16(0xFE6C), W16(0xFB9C), W16(0xF945), + W16(0xF71B), W16(0xF4FC), W16(0xF2BD), W16(0xF0CA), W16(0xEF8E), W16(0xEDBD), W16(0xEC47), W16(0xEB7F), + W16(0x0E4C), W16(0x084A), W16(0x05D9), W16(0x0481), W16(0x034C), W16(0x02CB), W16(0x0294), W16(0x0222), + W16(0x01EB), W16(0x018D), W16(0x00E0), W16(0x001B), W16(0xFED4), W16(0xFD0C), W16(0xFC56), W16(0xFC9B), + W16(0xFBEE), W16(0xF9CE), W16(0xF7CA), W16(0xF718), W16(0xF5C9), W16(0xF440), W16(0xF1F2), W16(0xEFE7), + W16(0x1518), W16(0x0FD5), W16(0x0E18), W16(0x0C03), W16(0x08E7), W16(0x072A), W16(0x0631), W16(0x04D7), + W16(0x04EC), W16(0x039D), W16(0x00F4), W16(0xFF9B), W16(0xFC59), W16(0xFA81), W16(0xF87B), W16(0xF6DF), + W16(0xF59C), W16(0xF4DC), W16(0xF365), W16(0xF2A1), W16(0xF298), W16(0xF1F8), W16(0xF1A0), W16(0xF168), + W16(0x0193), W16(0x04EA), W16(0x0536), W16(0x03C4), W16(0x0354), W16(0x02B6), W16(0x022D), W16(0x01B1), + W16(0x01AC), W16(0x011E), W16(0x007D), W16(0xFF96), W16(0xFE78), W16(0xFE21), W16(0xFD66), W16(0xFCDE), + W16(0xFC5D), W16(0xFB38), W16(0xFA40), W16(0xF988), W16(0xF86B), W16(0xF70D), W16(0xF58F), W16(0xF3DD), + W16(0x0872), W16(0x0B35), W16(0x0BE0), W16(0x0A14), W16(0x085B), W16(0x07D8), W16(0x0687), W16(0x064C), + W16(0x042E), W16(0x034F), W16(0x00AC), W16(0xFE7B), W16(0xFC91), W16(0xFAF1), W16(0xF933), W16(0xF6D6), + W16(0xF4CC), W16(0xF2CC), W16(0xF0E3), W16(0xEED3), W16(0xEE16), W16(0xECB7), W16(0xEBFA), W16(0xEB9C), + W16(0x0708), W16(0x0631), W16(0x05B1), W16(0x0338), W16(0x042E), W16(0x02E0), W16(0x01D3), W16(0x0124), + W16(0x0171), W16(0x0125), W16(0x003C), W16(0xFFB6), W16(0xFF19), W16(0xFE36), W16(0xFCDF), W16(0xFC93), + W16(0xFCB2), W16(0xFB91), W16(0xF970), W16(0xF83C), W16(0xF74E), W16(0xF596), W16(0xF399), W16(0xF20D), + W16(0x0E8A), W16(0x0F20), W16(0x0E41), W16(0x0B71), W16(0x087A), W16(0x0680), W16(0x049F), W16(0x0516), + W16(0x03B9), W16(0x02FF), W16(0x00FE), W16(0xFF01), W16(0xFCC6), W16(0xFAF5), W16(0xF9B5), W16(0xF808), + W16(0xF723), W16(0xF645), W16(0xF4AE), W16(0xF322), W16(0xF373), W16(0xF254), W16(0xF1FF), W16(0xF1A5), + W16(0x0539), W16(0x05F3), W16(0x0351), W16(0x05D6), W16(0x057A), W16(0x01D0), W16(0x02A3), W16(0x061D), + W16(0x0131), W16(0x0123), W16(0x001A), W16(0xFFA6), W16(0xFE21), W16(0xFDF1), W16(0xFC22), W16(0xFB38), + W16(0xFA75), W16(0xF9E5), W16(0xF892), W16(0xF846), W16(0xF85C), W16(0xF702), W16(0xF669), W16(0xF5E2), + W16(0x11C4), W16(0x0EE5), W16(0x09CF), W16(0x086F), W16(0x068D), W16(0x04AD), W16(0x043D), W16(0x0386), + W16(0x0384), W16(0x027C), W16(0x0077), W16(0xFED8), W16(0xFF16), W16(0xFDD4), W16(0xFB2A), W16(0xF8DE), + W16(0xF6C3), W16(0xF499), W16(0xF24C), W16(0xF02F), W16(0xEF1F), W16(0xEDB6), W16(0xECAD), W16(0xEC0A), + W16(0x09CA), W16(0x0743), W16(0x0573), W16(0x03BB), W16(0x034A), W16(0x02AD), W16(0x0229), W16(0x01B9), + W16(0x018E), W16(0x0112), W16(0x0075), W16(0xFF8F), W16(0xFE7F), W16(0xFE2A), W16(0xFD67), W16(0xFCF4), + W16(0xFC7F), W16(0xFB43), W16(0xFA39), W16(0xF989), W16(0xF871), W16(0xF721), W16(0xF598), W16(0xF3DE), + W16(0x16BC), W16(0x10D3), W16(0x0D86), W16(0x0A30), W16(0x079A), W16(0x057B), W16(0x0420), W16(0x0535), + W16(0x0495), W16(0x0281), W16(0x00C9), W16(0xFF84), W16(0xFD9F), W16(0xFB53), W16(0xF904), W16(0xF835), + W16(0xF809), W16(0xF6A4), W16(0xF4AF), W16(0xF3FE), W16(0xF3EE), W16(0xF31F), W16(0xF259), W16(0xF157), + W16(0x01AD), W16(0x053B), W16(0x0656), W16(0x0556), W16(0x046F), W16(0x03B5), W16(0x0334), W16(0x02C7), + W16(0x0264), W16(0x01B2), W16(0x00D3), W16(0xFF8F), W16(0xFE4B), W16(0xFD3C), W16(0xFC6F), W16(0xFB21), + W16(0xFA52), W16(0xF98D), W16(0xF87D), W16(0xF719), W16(0xF592), W16(0xF3B2), W16(0xF1D6), W16(0xF003), + W16(0x0C15), W16(0x0D4E), W16(0x0C6F), W16(0x09F0), W16(0x0798), W16(0x057F), W16(0x03B6), W16(0x053F), + W16(0x04D0), W16(0x027D), W16(0x00B2), W16(0xFF76), W16(0xFD90), W16(0xFB93), W16(0xF8F0), W16(0xF84F), + W16(0xF81D), W16(0xF6AC), W16(0xF3F7), W16(0xF2AC), W16(0xF2B0), W16(0xF1D0), W16(0xF0FF), W16(0xF006), + W16(0x085E), W16(0x06B3), W16(0x05AE), W16(0x0410), W16(0x0456), W16(0x04FE), W16(0x0396), W16(0x01B6), + W16(0x01EC), W16(0x01B1), W16(0x00D9), W16(0xFEC7), W16(0xFC6D), W16(0xFD63), W16(0xFD25), W16(0xFC60), + W16(0xFACF), W16(0xF9CC), W16(0xF78F), W16(0xF3CC), W16(0xF205), W16(0xF190), W16(0xF022), W16(0xEEC5), + W16(0x1269), W16(0x0F13), W16(0x0C2F), W16(0x09FB), W16(0x08A4), W16(0x07AC), W16(0x065B), W16(0x05EC), + W16(0x045F), W16(0x0299), W16(0x0050), W16(0xFE59), W16(0xFC74), W16(0xFA2F), W16(0xF8C8), W16(0xF7B8), + W16(0xF6A4), W16(0xF54D), W16(0xF3CB), W16(0xF224), W16(0xF148), W16(0xF06F), W16(0xEF7F), W16(0xEE7E), + W16(0xFFA0), W16(0xFFC1), W16(0xFFFB), W16(0x0001), W16(0xFFFD), W16(0xFFCA), W16(0xFFF1), W16(0x0006), + W16(0xFFE3), W16(0xFFCB), W16(0xFFF5), W16(0xFFD8), W16(0xFFD5), W16(0xFFFA), W16(0xFFE9), W16(0xFFCE), + W16(0xFFE8), W16(0xFFEE), W16(0xFFF6), W16(0xFFE1), W16(0x0003), W16(0xFF8C), W16(0xFFD1), W16(0xFF89), + W16(0x1069), W16(0x0D77), W16(0x08FD), W16(0x07C3), W16(0x061F), W16(0x03F0), W16(0x03F7), W16(0x0359), + W16(0x031A), W16(0x0270), W16(0x001B), W16(0xFED7), W16(0xFF68), W16(0xFE31), W16(0xFBAB), W16(0xF969), + W16(0xF779), W16(0xF559), W16(0xF2FD), W16(0xF114), W16(0xEF9C), W16(0xEDC8), W16(0xEC2D), W16(0xEB5B), + W16(0x0BD5), W16(0x0963), W16(0x07B7), W16(0x059A), W16(0x0436), W16(0x030F), W16(0x02AB), W16(0x029A), + W16(0x0257), W16(0x01D3), W16(0x00C4), W16(0xFF32), W16(0xFE18), W16(0xFDB7), W16(0xFCD5), W16(0xFBB2), + W16(0xFB00), W16(0xFA03), W16(0xF8EB), W16(0xF7B3), W16(0xF66E), W16(0xF4C1), W16(0xF341), W16(0xF1C3), + W16(0x186B), W16(0x111B), W16(0x0E20), W16(0x0BE5), W16(0x0994), W16(0x082F), W16(0x06C3), W16(0x0601), + W16(0x03CB), W16(0x0249), W16(0xFFC8), W16(0xFD34), W16(0xFB66), W16(0xFA33), W16(0xF94F), W16(0xF816), + W16(0xF76C), W16(0xF6E3), W16(0xF580), W16(0xF44A), W16(0xF3F4), W16(0xF2F1), W16(0xF2CF), W16(0xF28D), + W16(0x02D3), W16(0x06E5), W16(0x0678), W16(0x050E), W16(0x04A0), W16(0x035A), W16(0x027D), W16(0x0212), + W16(0x019A), W16(0x0120), W16(0x0016), W16(0xFF9E), W16(0xFE40), W16(0xFDCC), W16(0xFD09), W16(0xFC6A), + W16(0xFB8A), W16(0xFAC7), W16(0xFA21), W16(0xF976), W16(0xF835), W16(0xF696), W16(0xF5F2), W16(0xF50D), + W16(0x0A01), W16(0x0C87), W16(0x0BD7), W16(0x09CF), W16(0x086E), W16(0x076D), W16(0x062A), W16(0x05DD), + W16(0x0447), W16(0x0273), W16(0x0050), W16(0xFE70), W16(0xFC86), W16(0xFA57), W16(0xF910), W16(0xF7E5), + W16(0xF6D3), W16(0xF563), W16(0xF3DE), W16(0xF23B), W16(0xF17A), W16(0xF0BD), W16(0xEFBF), W16(0xEE9E), + W16(0x0A10), W16(0x079A), W16(0x06A0), W16(0x0554), W16(0x0475), W16(0x03BB), W16(0x0339), W16(0x02DB), + W16(0x0266), W16(0x01BF), W16(0x00E0), W16(0xFFA1), W16(0xFE4A), W16(0xFD45), W16(0xFC62), W16(0xFAF5), + W16(0xFA2F), W16(0xF979), W16(0xF869), W16(0xF6ED), W16(0xF555), W16(0xF37E), W16(0xF18A), W16(0xEFB7), + W16(0x0D46), W16(0x0D11), W16(0x0DEA), W16(0x0C1D), W16(0x0970), W16(0x084C), W16(0x06D2), W16(0x04E1), + W16(0x03A5), W16(0x020C), W16(0xFFA4), W16(0xFE5E), W16(0xFC58), W16(0xFB02), W16(0xF934), W16(0xF7BF), + W16(0xF692), W16(0xF5F1), W16(0xF48F), W16(0xF3D2), W16(0xF402), W16(0xF368), W16(0xF32B), W16(0xF2F2), + W16(0x0876), W16(0x07D2), W16(0x0757), W16(0x0496), W16(0x05DC), W16(0x045E), W16(0x02DF), W16(0x01A8), + W16(0x01EA), W16(0x0169), W16(0x0001), W16(0xFF2F), W16(0xFE65), W16(0xFD1C), W16(0xFBA4), W16(0xFB98), + W16(0xFBFE), W16(0xFB3B), W16(0xF953), W16(0xF821), W16(0xF7CD), W16(0xF644), W16(0xF4DD), W16(0xF399), + W16(0x10A3), W16(0x0E7E), W16(0x0943), W16(0x081D), W16(0x05EA), W16(0x0408), W16(0x037A), W16(0x031F), + W16(0x02C7), W16(0x01C3), W16(0x0046), W16(0xFEAD), W16(0xFFE1), W16(0xFEC1), W16(0xFBF2), W16(0xF9BF), + W16(0xF7A7), W16(0xF5C0), W16(0xF418), W16(0xF2DA), W16(0xF21C), W16(0xF133), W16(0xF05E), W16(0xEFBD), + W16(0x0DD5), W16(0x0AB1), W16(0x07A5), W16(0x05A6), W16(0x039F), W16(0x0209), W16(0x011E), W16(0x0100), + W16(0x010F), W16(0x012F), W16(0x008E), W16(0xFFF7), W16(0xFF30), W16(0xFE68), W16(0xFDC0), W16(0xFD5D), + W16(0xFCC0), W16(0xFB85), W16(0xFA5F), W16(0xF96C), W16(0xF839), W16(0xF71D), W16(0xF53F), W16(0xF428), + W16(0x1716), W16(0x11B9), W16(0x0DD2), W16(0x0A4B), W16(0x078C), W16(0x05AC), W16(0x042E), W16(0x0529), + W16(0x04B4), W16(0x0269), W16(0x00B9), W16(0xFF59), W16(0xFD99), W16(0xFB32), W16(0xF900), W16(0xF87D), + W16(0xF7F9), W16(0xF6CC), W16(0xF57A), W16(0xF51D), W16(0xF511), W16(0xF454), W16(0xF397), W16(0xF29F), + W16(0x02C7), W16(0x058B), W16(0x0656), W16(0x05B0), W16(0x052D), W16(0x04E3), W16(0x03C6), W16(0x02CC), + W16(0x02A2), W16(0x01CE), W16(0x00A6), W16(0xFF3B), W16(0xFD87), W16(0xFCC8), W16(0xFB6D), W16(0xFB5E), + W16(0xF9F2), W16(0xF7BA), W16(0xF574), W16(0xF25D), W16(0xF166), W16(0xF16B), W16(0xEFD8), W16(0xEF18), + W16(0x0910), W16(0x0C5A), W16(0x0967), W16(0x0839), W16(0x065E), W16(0x045E), W16(0x0412), W16(0x036E), + W16(0x0345), W16(0x0235), W16(0x006F), W16(0xFEB8), W16(0xFF3E), W16(0xFE47), W16(0xFB6E), W16(0xF930), + W16(0xF700), W16(0xF4E2), W16(0xF2AA), W16(0xF095), W16(0xEF83), W16(0xEDD9), W16(0xEC8E), W16(0xEBD7), + W16(0x09A7), W16(0x07C5), W16(0x06F4), W16(0x05C1), W16(0x05B1), W16(0x059E), W16(0x04D3), W16(0x03A8), + W16(0x037B), W16(0x022E), W16(0x00A4), W16(0xFEBE), W16(0xFCF4), W16(0xFC2C), W16(0xFAC8), W16(0xFA59), + W16(0xF8EB), W16(0xF684), W16(0xF414), W16(0xF147), W16(0xF047), W16(0xEFF3), W16(0xEE8A), W16(0xEDC3), + W16(0x106C), W16(0x0D7F), W16(0x0BFD), W16(0x0A0C), W16(0x0897), W16(0x079B), W16(0x06B6), W16(0x0638), + W16(0x0494), W16(0x0315), W16(0x005C), W16(0xFE8A), W16(0xFCCC), W16(0xFA95), W16(0xF905), W16(0xF730), + W16(0xF4BB), W16(0xF34B), W16(0xF14A), W16(0xEF4B), W16(0xEE4B), W16(0xECE3), W16(0xEC19), W16(0xEBD6), + W16(0xFB0B), W16(0x0267), W16(0x048B), W16(0x0582), W16(0x03A0), W16(0x0601), W16(0x0513), W16(0x03E6), + W16(0x0004), W16(0x019D), W16(0xFF41), W16(0xFF1D), W16(0xFD75), W16(0xFCF1), W16(0xFBE7), W16(0xFBD7), + W16(0xFB42), W16(0xFA9B), W16(0xF9D3), W16(0xF97A), W16(0xF991), W16(0xF7F4), W16(0xF72B), W16(0xF5EF), + W16(0x10F7), W16(0x0EDE), W16(0x099F), W16(0x089E), W16(0x0663), W16(0x046B), W16(0x041E), W16(0x038F), + W16(0x035D), W16(0x0207), W16(0x0097), W16(0xFEB0), W16(0xFF14), W16(0xFE44), W16(0xFB5A), W16(0xF923), + W16(0xF705), W16(0xF4FB), W16(0xF2DA), W16(0xF0DF), W16(0xEFC8), W16(0xEDFA), W16(0xEC6A), W16(0xEBA3), + W16(0x0F44), W16(0x09B4), W16(0x0661), W16(0x04A1), W16(0x035A), W16(0x02DD), W16(0x0284), W16(0x0201), + W16(0x01CE), W16(0x01CB), W16(0x012A), W16(0x0044), W16(0xFEED), W16(0xFD34), W16(0xFC6E), W16(0xFC2C), + W16(0xFB81), W16(0xF985), W16(0xF769), W16(0xF645), W16(0xF538), W16(0xF3BD), W16(0xF0F6), W16(0xEE24), + W16(0x159C), W16(0x0F76), W16(0x0E25), W16(0x0C81), W16(0x098C), W16(0x083A), W16(0x06FD), W16(0x0592), + W16(0x0447), W16(0x027F), W16(0xFF9F), W16(0xFDDE), W16(0xFBC9), W16(0xFB42), W16(0xF8E5), W16(0xF761), + W16(0xF618), W16(0xF553), W16(0xF419), W16(0xF34C), W16(0xF35C), W16(0xF2E3), W16(0xF2AB), W16(0xF27E), + W16(0xFFEE), W16(0x05AA), W16(0x071D), W16(0x048C), W16(0x05D5), W16(0x0462), W16(0x02D5), W16(0x0197), + W16(0x01EF), W16(0x0172), W16(0x000F), W16(0xFF30), W16(0xFE66), W16(0xFD1C), W16(0xFBA3), W16(0xFB95), + W16(0xFC03), W16(0xFB3B), W16(0xF952), W16(0xF821), W16(0xF7E2), W16(0xF650), W16(0xF4EB), W16(0xF3A7), + W16(0x077D), W16(0x0A1F), W16(0x0ADC), W16(0x0956), W16(0x080F), W16(0x06D7), W16(0x0609), W16(0x0562), + W16(0x03B9), W16(0x0259), W16(0x0029), W16(0xFE97), W16(0xFCE1), W16(0xFB12), W16(0xF9D3), W16(0xF82B), + W16(0xF6EC), W16(0xF63E), W16(0xF528), W16(0xF2AC), W16(0xF084), W16(0xEE88), W16(0xED6A), W16(0xECA7), + W16(0x05E5), W16(0x05FC), W16(0x05B6), W16(0x0489), W16(0x0361), W16(0x02CE), W16(0x0299), W16(0x0210), + W16(0x01D8), W16(0x018E), W16(0x00E1), W16(0x0010), W16(0xFEC5), W16(0xFD05), W16(0xFC5B), W16(0xFCA7), + W16(0xFC05), W16(0xF9DD), W16(0xF7C1), W16(0xF717), W16(0xF5EC), W16(0xF446), W16(0xF1F0), W16(0xEFE7), + W16(0x0FC3), W16(0x0E43), W16(0x0D5A), W16(0x0A7E), W16(0x07E0), W16(0x05F8), W16(0x0422), W16(0x03E4), + W16(0x02BD), W16(0x026A), W16(0x00D4), W16(0xFEEF), W16(0xFD6B), W16(0xFBF5), W16(0xFAA4), W16(0xF8FD), + W16(0xF838), W16(0xF782), W16(0xF601), W16(0xF4A9), W16(0xF44B), W16(0xF307), W16(0xF2BC), W16(0xF270), + W16(0x0367), W16(0x05CB), W16(0x063A), W16(0x0526), W16(0x0498), W16(0x043E), W16(0x03A2), W16(0x02F4), + W16(0x0231), W16(0x0138), W16(0x0059), W16(0xFF18), W16(0xFE05), W16(0xFD20), W16(0xFC74), W16(0xFB8F), + W16(0xFA94), W16(0xF9C9), W16(0xF96E), W16(0xF949), W16(0xF8F1), W16(0xF80E), W16(0xF680), W16(0xF4B2), + W16(0x1231), W16(0x0E64), W16(0x0A87), W16(0x08C5), W16(0x06FC), W16(0x05D6), W16(0x0537), W16(0x04D6), + W16(0x03A3), W16(0x02C8), W16(0x002D), W16(0xFE7A), W16(0xFE22), W16(0xFCCD), W16(0xFA62), W16(0xF84A), + W16(0xF673), W16(0xF4BD), W16(0xF2A2), W16(0xF06F), W16(0xEFA0), W16(0xEE75), W16(0xEDAD), W16(0xED15), + W16(0x0BB9), W16(0x082C), W16(0x065F), W16(0x0530), W16(0x04A2), W16(0x0450), W16(0x03A7), W16(0x02F5), + W16(0x022F), W16(0x0136), W16(0x005D), W16(0xFF10), W16(0xFE02), W16(0xFD19), W16(0xFC6E), W16(0xFB88), + W16(0xFA8F), W16(0xF9C3), W16(0xF971), W16(0xF949), W16(0xF8E5), W16(0xF80B), W16(0xF680), W16(0xF4B1), + W16(0x1535), W16(0x1077), W16(0x0D5E), W16(0x0A03), W16(0x07A1), W16(0x05C2), W16(0x03E0), W16(0x053D), + W16(0x04B8), W16(0x025C), W16(0x009E), W16(0xFF61), W16(0xFD71), W16(0xFB83), W16(0xF8EF), W16(0xF856), + W16(0xF834), W16(0xF6D9), W16(0xF455), W16(0xF335), W16(0xF312), W16(0xF22D), W16(0xF15B), W16(0xF05C), + W16(0x00C3), W16(0x0490), W16(0x052A), W16(0x0455), W16(0x038A), W16(0x02EC), W16(0x02DF), W16(0x0265), + W16(0x021F), W16(0x0177), W16(0x00B8), W16(0xFFBB), W16(0xFE77), W16(0xFD94), W16(0xFCE7), W16(0xFC16), + W16(0xFB34), W16(0xFA39), W16(0xF949), W16(0xF82F), W16(0xF630), W16(0xF481), W16(0xF32D), W16(0xF19B), + W16(0x0CC9), W16(0x0C4E), W16(0x0C59), W16(0x09DA), W16(0x0795), W16(0x05C3), W16(0x03E9), W16(0x03D1), + W16(0x02C0), W16(0x026A), W16(0x00FD), W16(0xFF2B), W16(0xFD60), W16(0xFBC8), W16(0xFABF), W16(0xF92B), + W16(0xF88B), W16(0xF7D4), W16(0xF646), W16(0xF445), W16(0xF330), W16(0xF216), W16(0xF1D4), W16(0xF19B), + W16(0x0877), W16(0x069D), W16(0x0590), W16(0x0438), W16(0x04B3), W16(0x0508), W16(0x044D), W16(0x0304), + W16(0x0374), W16(0x0231), W16(0x00AB), W16(0xFE4C), W16(0xFC8B), W16(0xFC90), W16(0xFC1E), W16(0xFB28), + W16(0xF9F8), W16(0xF821), W16(0xF5B6), W16(0xF287), W16(0xF18B), W16(0xF10C), W16(0xEFD5), W16(0xEE9B), + W16(0x0FEF), W16(0x0C87), W16(0x0AF8), W16(0x094C), W16(0x0813), W16(0x06D4), W16(0x061E), W16(0x0572), + W16(0x03C3), W16(0x0254), W16(0x001C), W16(0xFE86), W16(0xFCDC), W16(0xFB0D), W16(0xF9D8), W16(0xF82F), + W16(0xF6E0), W16(0xF631), W16(0xF519), W16(0xF2AD), W16(0xF077), W16(0xEE89), W16(0xED6C), W16(0xECA4), + W16(0xFF6F), W16(0x0439), W16(0x05C2), W16(0x0700), W16(0x069C), W16(0x036E), W16(0x02AC), W16(0x011B), + W16(0x0056), W16(0x0068), W16(0x0017), W16(0xFF54), W16(0xFE8E), W16(0xFDF1), W16(0xFD91), W16(0xFC01), + W16(0xFBF7), W16(0xFA9F), W16(0xF9FE), W16(0xF95F), W16(0xF7F6), W16(0xF6F8), W16(0xF62B), W16(0xF5CD), + W16(0x113D), W16(0x0EA0), W16(0x0982), W16(0x0790), W16(0x0603), W16(0x03FC), W16(0x03BB), W16(0x02F3), + W16(0x02B1), W16(0x0200), W16(0x0053), W16(0xFEA6), W16(0xFF21), W16(0xFE15), W16(0xFBCF), W16(0xFA70), + W16(0xF836), W16(0xF5C7), W16(0xF364), W16(0xF0FE), W16(0xEFB5), W16(0xEE15), W16(0xECF4), W16(0xEC36), + W16(0x0D80), W16(0x08AB), W16(0x06F6), W16(0x0577), W16(0x04C6), W16(0x03FE), W16(0x036A), W16(0x0269), + W16(0x011F), W16(0x007F), W16(0xFF7D), W16(0xFEDB), W16(0xFE1D), W16(0xFD6A), W16(0xFCEB), W16(0xFCE8), + W16(0xFC19), W16(0xFAD7), W16(0xF9CA), W16(0xF8EF), W16(0xF7A0), W16(0xF637), W16(0xF4E5), W16(0xF3C8), + W16(0x154E), W16(0x0F85), W16(0x0E6E), W16(0x0C99), W16(0x09C2), W16(0x089D), W16(0x06F1), W16(0x04BB), + W16(0x030D), W16(0x01D2), W16(0xFF8A), W16(0xFE83), W16(0xFC74), W16(0xFB0D), W16(0xF947), W16(0xF7B0), + W16(0xF692), W16(0xF5F4), W16(0xF492), W16(0xF3EA), W16(0xF3DB), W16(0xF344), W16(0xF300), W16(0xF2C7), + W16(0x059C), W16(0x0678), W16(0x0739), W16(0x059B), W16(0x04D3), W16(0x0434), W16(0x03C7), W16(0x029A), + W16(0x0135), W16(0x00BA), W16(0xFFCA), W16(0xFE7B), W16(0xFDE8), W16(0xFDB0), W16(0xFD54), W16(0xFC50), + W16(0xFB26), W16(0xFA10), W16(0xF8CA), W16(0xF79D), W16(0xF5E8), W16(0xF43C), W16(0xF2F5), W16(0xF200), + W16(0x0A2C), W16(0x0BF7), W16(0x0BB0), W16(0x09DA), W16(0x087D), W16(0x079C), W16(0x0640), W16(0x05D4), + W16(0x0434), W16(0x0286), W16(0x0059), W16(0xFE6B), W16(0xFC7B), W16(0xFA60), W16(0xF901), W16(0xF7CA), + W16(0xF6AE), W16(0xF583), W16(0xF462), W16(0xF368), W16(0xF2E5), W16(0xF24B), W16(0xF1B0), W16(0xF143), + W16(0x080E), W16(0x063B), W16(0x04D7), W16(0x03B5), W16(0x032F), W16(0x0286), W16(0x0297), W16(0x0258), + W16(0x01F5), W16(0x0194), W16(0x00B5), W16(0xFFEE), W16(0xFEAA), W16(0xFDBF), W16(0xFD14), W16(0xFC38), + W16(0xFB7B), W16(0xFA4B), W16(0xF95B), W16(0xF827), W16(0xF5DF), W16(0xF427), W16(0xF2A4), W16(0xF0D8), + W16(0x0BF7), W16(0x0DAE), W16(0x0E6C), W16(0x0CA8), W16(0x0988), W16(0x07CC), W16(0x06AC), W16(0x053F), + W16(0x0504), W16(0x0391), W16(0x00A8), W16(0xFEE6), W16(0xFBE1), W16(0xFA1C), W16(0xF842), W16(0xF6C8), + W16(0xF599), W16(0xF4E4), W16(0xF393), W16(0xF2CE), W16(0xF319), W16(0xF280), W16(0xF238), W16(0xF1FF), + W16(0x071A), W16(0x069C), W16(0x0603), W16(0x070B), W16(0x06A3), W16(0x0371), W16(0x02AE), W16(0x0120), + W16(0x0054), W16(0x0072), W16(0x0020), W16(0xFF5E), W16(0xFE81), W16(0xFDEB), W16(0xFD8C), W16(0xFBF4), + W16(0xFBEF), W16(0xFA96), W16(0xF9F7), W16(0xF954), W16(0xF7CB), W16(0xF6D2), W16(0xF602), W16(0xF59F), + W16(0x11C4), W16(0x0EBE), W16(0x09D4), W16(0x083C), W16(0x0610), W16(0x046E), W16(0x0439), W16(0x0387), + W16(0x035C), W16(0x0209), W16(0x00B5), W16(0xFE91), W16(0xFF44), W16(0xFE67), W16(0xFB2E), W16(0xF948), + W16(0xF6F6), W16(0xF530), W16(0xF34C), W16(0xF1B8), W16(0xF0E9), W16(0xEFBC), W16(0xEEDB), W16(0xEE5B), + W16(0x0C81), W16(0x0AAB), W16(0x082C), W16(0x06AA), W16(0x05BA), W16(0x048D), W16(0x02A0), W16(0x01BC), + W16(0x0207), W16(0x00EF), W16(0xFF91), W16(0xFE7F), W16(0xFE1E), W16(0xFD9A), W16(0xFCFD), W16(0xFC21), + W16(0xFB7F), W16(0xFB22), W16(0xFA12), W16(0xF8D4), W16(0xF79C), W16(0xF67E), W16(0xF578), W16(0xF49A), + W16(0x15E4), W16(0x0FAA), W16(0x0D3B), W16(0x0AAE), W16(0x0793), W16(0x055C), W16(0x042F), W16(0x0411), + W16(0x024D), W16(0x0223), W16(0x003E), W16(0xFE80), W16(0xFD25), W16(0xFBCD), W16(0xFAB4), W16(0xF9F2), + W16(0xFA0B), W16(0xFA0B), W16(0xF8CB), W16(0xF71B), W16(0xF541), W16(0xF318), W16(0xF1D1), W16(0xF0E5), + W16(0x00C1), W16(0x04F8), W16(0x05DF), W16(0x04A6), W16(0x04E6), W16(0x051A), W16(0x03EE), W16(0x0222), + W16(0x027D), W16(0x01C6), W16(0x00A1), W16(0xFE74), W16(0xFC93), W16(0xFD00), W16(0xFCA2), W16(0xFBD6), + W16(0xFA8F), W16(0xF921), W16(0xF6B4), W16(0xF360), W16(0xF234), W16(0xF1CC), W16(0xF098), W16(0xEF7C), + W16(0x09A6), W16(0x0B5C), W16(0x08FD), W16(0x0823), W16(0x0635), W16(0x046C), W16(0x0414), W16(0x0355), + W16(0x032D), W16(0x020B), W16(0x005C), W16(0xFE99), W16(0xFF5B), W16(0xFE74), W16(0xFB94), W16(0xF948), + W16(0xF71E), W16(0xF579), W16(0xF3B1), W16(0xF238), W16(0xF1A5), W16(0xF0B2), W16(0xEFF3), W16(0xEF8A), + W16(0x0B75), W16(0x0825), W16(0x06AA), W16(0x05E4), W16(0x058D), W16(0x04CD), W16(0x0380), W16(0x0277), + W16(0x0230), W16(0x01A7), W16(0x00CD), W16(0xFF92), W16(0xFDBE), W16(0xFCF0), W16(0xFB7E), W16(0xFB60), + W16(0xF9ED), W16(0xF79E), W16(0xF567), W16(0xF25B), W16(0xF175), W16(0xF1B3), W16(0xF00F), W16(0xEF68), + W16(0x10BA), W16(0x0DA4), W16(0x0C13), W16(0x0A09), W16(0x0881), W16(0x07B1), W16(0x0695), W16(0x0646), + W16(0x0441), W16(0x0314), W16(0x0082), W16(0xFE65), W16(0xFC91), W16(0xFAB2), W16(0xF912), W16(0xF718), + W16(0xF54B), W16(0xF40C), W16(0xF2E2), W16(0xF1EA), W16(0xF11C), W16(0xF056), W16(0xEFC2), W16(0xEF69), + W16(0xFF55), W16(0x0390), W16(0x0492), W16(0x0613), W16(0x050A), W16(0x0220), W16(0x02D3), W16(0x04A9), + W16(0x0184), W16(0x00B1), W16(0xFFC3), W16(0xFF2D), W16(0xFE4D), W16(0xFDF9), W16(0xFCC9), W16(0xFC03), + W16(0xFB22), W16(0xFAC1), W16(0xFA3B), W16(0xFA38), W16(0xFA06), W16(0xF8D8), W16(0xF7EA), W16(0xF728), + W16(0x11B5), W16(0x0EF5), W16(0x09CB), W16(0x0809), W16(0x064A), W16(0x042E), W16(0x040C), W16(0x0357), + W16(0x02F1), W16(0x024E), W16(0x0056), W16(0xFEAF), W16(0xFF65), W16(0xFE60), W16(0xFB98), W16(0xF94B), + W16(0xF73A), W16(0xF534), W16(0xF2EF), W16(0xF0CD), W16(0xEF97), W16(0xEE13), W16(0xECFC), W16(0xEC4C), + W16(0x0E1A), W16(0x07FF), W16(0x0574), W16(0x0424), W16(0x0308), W16(0x0288), W16(0x025B), W16(0x01DC), + W16(0x01A6), W16(0x0194), W16(0x00BD), W16(0xFFF1), W16(0xFED2), W16(0xFD0A), W16(0xFC7C), W16(0xFD39), + W16(0xFCBF), W16(0xFAB3), W16(0xF883), W16(0xF858), W16(0xF754), W16(0xF580), W16(0xF326), W16(0xF164), + W16(0x1578), W16(0x1060), W16(0x0F1C), W16(0x0D00), W16(0x09C6), W16(0x0813), W16(0x06DB), W16(0x056D), + W16(0x051A), W16(0x03B2), W16(0x0098), W16(0xFEA8), W16(0xFBA2), W16(0xF9EC), W16(0xF816), W16(0xF6B4), + W16(0xF57B), W16(0xF4BD), W16(0xF36B), W16(0xF2CB), W16(0xF2DA), W16(0xF255), W16(0xF211), W16(0xF1D9), + W16(0x037E), W16(0x060E), W16(0x0676), W16(0x0551), W16(0x04A6), W16(0x03E7), W16(0x0350), W16(0x0258), + W16(0x0116), W16(0x0082), W16(0xFF71), W16(0xFEE3), W16(0xFE38), W16(0xFD84), W16(0xFCFA), W16(0xFCF9), + W16(0xFC31), W16(0xFB55), W16(0xFA9A), W16(0xF9FC), W16(0xF8C4), W16(0xF77C), W16(0xF655), W16(0xF56C), + W16(0x084B), W16(0x0BA1), W16(0x0C77), W16(0x0AAE), W16(0x0923), W16(0x080C), W16(0x071E), W16(0x0665), + W16(0x04A1), W16(0x0315), W16(0x0026), W16(0xFE65), W16(0xFC85), W16(0xFA45), W16(0xF8C1), W16(0xF712), + W16(0xF46E), W16(0xF315), W16(0xF120), W16(0xEF4A), W16(0xEE87), W16(0xED2A), W16(0xEC77), W16(0xEC38), + W16(0x0999), W16(0x071B), W16(0x0556), W16(0x042B), W16(0x036A), W16(0x030C), W16(0x02F3), W16(0x0244), + W16(0x023C), W16(0x017E), W16(0x00BA), W16(0xFFC4), W16(0xFE76), W16(0xFD99), W16(0xFCD2), W16(0xFC0E), + W16(0xFB2C), W16(0xFA4D), W16(0xF98D), W16(0xF8D6), W16(0xF71A), W16(0xF57C), W16(0xF44B), W16(0xF2E6), + W16(0x0EC4), W16(0x0F57), W16(0x0DAE), W16(0x0A4B), W16(0x0792), W16(0x05B9), W16(0x042F), W16(0x052A), + W16(0x04B9), W16(0x0265), W16(0x00B7), W16(0xFF57), W16(0xFD8E), W16(0xFB34), W16(0xF8FA), W16(0xF87C), + W16(0xF7F8), W16(0xF6CD), W16(0xF574), W16(0xF502), W16(0xF522), W16(0xF458), W16(0xF39D), W16(0xF2A2), + W16(0x041B), W16(0x055C), W16(0x037A), W16(0x0524), W16(0x046C), W16(0x018B), W16(0x023A), W16(0x0577), + W16(0x011B), W16(0x014E), W16(0x000F), W16(0xFF9F), W16(0xFE98), W16(0xFE17), W16(0xFC95), W16(0xFBDD), + W16(0xFB20), W16(0xFA7B), W16(0xF99C), W16(0xF917), W16(0xF8F0), W16(0xF7A1), W16(0xF6A6), W16(0xF5EF), + W16(0x124C), W16(0x0F7E), W16(0x0A28), W16(0x07F6), W16(0x0685), W16(0x046A), W16(0x0448), W16(0x03B7), + W16(0x0369), W16(0x0234), W16(0x0091), W16(0xFE7E), W16(0xFF1D), W16(0xFE27), W16(0xFB41), W16(0xF906), + W16(0xF6DA), W16(0xF4B7), W16(0xF2AD), W16(0xF08B), W16(0xEF6C), W16(0xEDE1), W16(0xECAB), W16(0xEBFF), + W16(0x0AC7), W16(0x090A), W16(0x066E), W16(0x050B), W16(0x0486), W16(0x0345), W16(0x025D), W16(0x01DD), + W16(0x016D), W16(0x00DB), W16(0xFFF7), W16(0xFF86), W16(0xFE3F), W16(0xFDC9), W16(0xFD3F), W16(0xFCD6), + W16(0xFC18), W16(0xFB8D), W16(0xFB22), W16(0xFAA9), W16(0xF935), W16(0xF7A8), W16(0xF71D), W16(0xF5F9), + W16(0x1773), W16(0x11C9), W16(0x0E4C), W16(0x0B28), W16(0x0863), W16(0x06A2), W16(0x04C0), W16(0x04F4), + W16(0x03AC), W16(0x02F9), W16(0x00FF), W16(0xFF05), W16(0xFCDD), W16(0xFAF6), W16(0xF9B8), W16(0xF7F2), + W16(0xF720), W16(0xF63F), W16(0xF4B7), W16(0xF379), W16(0xF34D), W16(0xF22F), W16(0xF1E0), W16(0xF189), + W16(0x0386), W16(0x0768), W16(0x07CF), W16(0x05BE), W16(0x0445), W16(0x031D), W16(0x02BA), W16(0x02A4), + W16(0x0253), W16(0x01D0), W16(0x00B7), W16(0xFF23), W16(0xFE0F), W16(0xFDB2), W16(0xFCC0), W16(0xFBB3), + W16(0xFB0F), W16(0xFA0E), W16(0xF8FB), W16(0xF7BA), W16(0xF676), W16(0xF4C6), W16(0xF335), W16(0xF1B7), + W16(0x0D50), W16(0x0E22), W16(0x0D40), W16(0x0A33), W16(0x078C), W16(0x058E), W16(0x040F), W16(0x053B), + W16(0x04AC), W16(0x0277), W16(0x00BB), W16(0xFF75), W16(0xFD8E), W16(0xFB57), W16(0xF907), W16(0xF847), + W16(0xF816), W16(0xF6AD), W16(0xF47E), W16(0xF38D), W16(0xF3A2), W16(0xF2BA), W16(0xF1E9), W16(0xF0F0), + W16(0x0956), W16(0x078B), W16(0x0679), W16(0x050A), W16(0x0501), W16(0x04D6), W16(0x03A7), W16(0x0243), + W16(0x0288), W16(0x01A6), W16(0x008F), W16(0xFE95), W16(0xFD0F), W16(0xFCDF), W16(0xFC73), W16(0xFBE7), + W16(0xFAA5), W16(0xF93B), W16(0xF6D9), W16(0xF3BD), W16(0xF254), W16(0xF203), W16(0xF0F4), W16(0xEFE0), + W16(0x1206), W16(0x0EA1), W16(0x0BE4), W16(0x09D1), W16(0x0868), W16(0x0769), W16(0x0635), W16(0x05ED), + W16(0x044B), W16(0x029D), W16(0x003D), W16(0xFE68), W16(0xFC72), W16(0xFA57), W16(0xF901), W16(0xF7E0), + W16(0xF6D5), W16(0xF5A0), W16(0xF464), W16(0xF31B), W16(0xF272), W16(0xF1E0), W16(0xF13B), W16(0xF0C5), + W16(0x0030), W16(0x0026), W16(0xFFFE), W16(0x000F), W16(0x000E), W16(0x002B), W16(0x001B), W16(0xFFFA), + W16(0xFFFD), W16(0x0031), W16(0x000C), W16(0xFFF6), W16(0x0000), W16(0x0025), W16(0x000E), W16(0x0019), + W16(0x002D), W16(0x000F), W16(0xFFFA), W16(0x0019), W16(0x0004), W16(0x0009), W16(0xFFE3), W16(0x001A), + W16(0x1088), W16(0x0E1C), W16(0x0925), W16(0x0774), W16(0x05E9), W16(0x0444), W16(0x03AF), W16(0x031D), + W16(0x02ED), W16(0x01D6), W16(0x001A), W16(0xFEAB), W16(0xFF43), W16(0xFE92), W16(0xFC13), W16(0xF9E1), + W16(0xF7B9), W16(0xF5B2), W16(0xF370), W16(0xF175), W16(0xF007), W16(0xEE39), W16(0xEC85), W16(0xEBB2), + W16(0x0C41), W16(0x0B9B), W16(0x08F6), W16(0x060A), W16(0x047E), W16(0x0367), W16(0x02EB), W16(0x02B5), + W16(0x0229), W16(0x01CD), W16(0x00D1), W16(0xFF51), W16(0xFE2E), W16(0xFD6C), W16(0xFC3C), W16(0xFB9B), + W16(0xFAF3), W16(0xF9FB), W16(0xF904), W16(0xF794), W16(0xF5EB), W16(0xF448), W16(0xF297), W16(0xF112), + W16(0x1841), W16(0x1114), W16(0x0E1F), W16(0x0BC4), W16(0x0928), W16(0x07F2), W16(0x0645), W16(0x0597), + W16(0x0320), W16(0x020F), W16(0xFFBD), W16(0xFD59), W16(0xFB76), W16(0xFA6A), W16(0xF9D9), W16(0xF8B4), + W16(0xF85A), W16(0xF7E9), W16(0xF6BF), W16(0xF59E), W16(0xF4BC), W16(0xF374), W16(0xF2FA), W16(0xF28E), + W16(0x040C), W16(0x085D), W16(0x07F5), W16(0x06B2), W16(0x05B3), W16(0x0489), W16(0x02A3), W16(0x01C6), + W16(0x0210), W16(0x00FA), W16(0xFF92), W16(0xFE81), W16(0xFE16), W16(0xFD92), W16(0xFCF3), W16(0xFC22), + W16(0xFB81), W16(0xFB21), W16(0xFA10), W16(0xF8D1), W16(0xF7AE), W16(0xF682), W16(0xF57B), W16(0xF499), + W16(0x0A70), W16(0x0CC9), W16(0x0C30), W16(0x0A4C), W16(0x08C0), W16(0x07E8), W16(0x068B), W16(0x0608), + W16(0x047C), W16(0x02D7), W16(0x0045), W16(0xFE38), W16(0xFC5A), W16(0xFA03), W16(0xF87A), W16(0xF794), + W16(0xF68A), W16(0xF541), W16(0xF3C7), W16(0xF219), W16(0xF161), W16(0xF04C), W16(0xEF66), W16(0xEE85), + W16(0x09B5), W16(0x0777), W16(0x062C), W16(0x0522), W16(0x041F), W16(0x0379), W16(0x030C), W16(0x028F), + W16(0x022B), W16(0x0180), W16(0x00C3), W16(0xFF88), W16(0xFE4D), W16(0xFD43), W16(0xFCCD), W16(0xFBBF), + W16(0xFABA), W16(0xF9D8), W16(0xF8C3), W16(0xF794), W16(0xF5E1), W16(0xF440), W16(0xF2BA), W16(0xF0EB), + W16(0x0E79), W16(0x0E14), W16(0x0DAD), W16(0x0BF1), W16(0x0986), W16(0x0850), W16(0x069D), W16(0x05E7), + W16(0x0365), W16(0x01E7), W16(0xFF95), W16(0xFD26), W16(0xFB64), W16(0xFA4C), W16(0xF992), W16(0xF86A), + W16(0xF7F2), W16(0xF753), W16(0xF60A), W16(0xF4B6), W16(0xF478), W16(0xF34C), W16(0xF309), W16(0xF2C1), + W16(0x0629), W16(0x085C), W16(0x07B5), W16(0x05D5), W16(0x03A3), W16(0x0232), W16(0x01A6), W16(0x01AA), + W16(0x019D), W16(0x0164), W16(0x00B9), W16(0xFF98), W16(0xFE70), W16(0xFE08), W16(0xFDAD), W16(0xFCF3), + W16(0xFC70), W16(0xFB8D), W16(0xFA6A), W16(0xF94F), W16(0xF7E8), W16(0xF675), W16(0xF524), W16(0xF3D5), + W16(0x11B2), W16(0x0E4F), W16(0x08FA), W16(0x0833), W16(0x0622), W16(0x0493), W16(0x0451), W16(0x02EE), + W16(0x02A4), W16(0x0151), W16(0xFFDB), W16(0xFE6E), W16(0xFEA3), W16(0xFE6B), W16(0xFBEF), W16(0xFA4A), + W16(0xF887), W16(0xF696), W16(0xF461), W16(0xF27D), W16(0xF1CA), W16(0xF0EB), W16(0xF04C), W16(0xF014), + W16(0x0E96), W16(0x0B2E), W16(0x0818), W16(0x05E8), W16(0x03AA), W16(0x0250), W16(0x01F1), W16(0x01F9), + W16(0x01D1), W16(0x016C), W16(0x00CA), W16(0xFF64), W16(0xFE0D), W16(0xFDE3), W16(0xFDAE), W16(0xFCC4), + W16(0xFC4E), W16(0xFB93), W16(0xFA73), W16(0xF957), W16(0xF7B4), W16(0xF62B), W16(0xF527), W16(0xF3B7), + W16(0x17EA), W16(0x10B1), W16(0x0D83), W16(0x0A75), W16(0x07F4), W16(0x0606), W16(0x042B), W16(0x03F9), + W16(0x02B8), W16(0x027D), W16(0x00F7), W16(0xFEED), W16(0xFD61), W16(0xFBC5), W16(0xFA88), W16(0xF8F0), + W16(0xF82A), W16(0xF775), W16(0xF601), W16(0xF4EB), W16(0xF453), W16(0xF321), W16(0xF2CA), W16(0xF274) +}; + +const Word16 cdk_37bits_2_fx[1536] = +{ + W16(0xFFB3), W16(0xFFD1), W16(0xFFDB), W16(0xFFB1), W16(0xFFE5), W16(0x0002), W16(0xFFE4), W16(0xFFED), + W16(0x0018), W16(0x0058), W16(0x005D), W16(0x006D), W16(0x0055), W16(0x0018), W16(0xFFB1), W16(0xFF83), + W16(0xFF6E), W16(0xFF10), W16(0xFEBF), W16(0xFE86), W16(0xFE7C), W16(0xFE80), W16(0xFE8F), W16(0xFEB7), + W16(0xFD2D), W16(0xFEBB), W16(0x0033), W16(0x017C), W16(0xFFED), W16(0xFF59), W16(0x0125), W16(0x0143), + W16(0xFFA1), W16(0xFFB6), W16(0xFFCD), W16(0xFFD2), W16(0xFF67), W16(0x0008), W16(0x0053), W16(0xFFDB), + W16(0xFFC0), W16(0x0014), W16(0xFFC0), W16(0xFF6B), W16(0xFF62), W16(0xFF1F), W16(0xFF27), W16(0xFE5D), + W16(0xFE2D), W16(0xFF2A), W16(0xFF78), W16(0xFF50), W16(0xFF70), W16(0xFFA8), W16(0xFF9A), W16(0xFFDD), + W16(0xFFED), W16(0xFFEE), W16(0x0005), W16(0x0058), W16(0x0061), W16(0x0046), W16(0x0033), W16(0x0038), + W16(0x0028), W16(0x003C), W16(0x0034), W16(0x002D), W16(0xFFCC), W16(0xFFBE), W16(0xFF8D), W16(0xFF79), + W16(0xFEF1), W16(0xFF29), W16(0xFF4E), W16(0xFF83), W16(0xFFA8), W16(0xFFE0), W16(0x0016), W16(0x0049), + W16(0x0085), W16(0x0044), W16(0x0040), W16(0x002F), W16(0x0001), W16(0xFFF3), W16(0xFFAF), W16(0xFFB5), + W16(0xFF89), W16(0xFF71), W16(0xFF59), W16(0xFF44), W16(0xFF48), W16(0xFF52), W16(0xFF54), W16(0xFF57), + W16(0x0021), W16(0xFF57), W16(0xFFC3), W16(0xFFEF), W16(0x006E), W16(0x007D), W16(0x0042), W16(0x0015), + W16(0x0004), W16(0x0006), W16(0x0015), W16(0x000B), W16(0xFFFA), W16(0xFFB0), W16(0xFFA3), W16(0xFFB1), + W16(0xFF96), W16(0xFF7B), W16(0xFF7E), W16(0xFF93), W16(0xFF83), W16(0xFF84), W16(0xFF8F), W16(0xFFA2), + W16(0xFFDE), W16(0xFF98), W16(0xFFB5), W16(0xFF7D), W16(0xFFC8), W16(0x004A), W16(0x0095), W16(0x0118), + W16(0x0018), W16(0xFFB7), W16(0xFF95), W16(0xFF9B), W16(0xFF9D), W16(0xFF73), W16(0xFFC4), W16(0x0033), + W16(0x003B), W16(0xFFAF), W16(0xFFA1), W16(0xFF9B), W16(0x0013), W16(0x0077), W16(0x0058), W16(0x0073), + W16(0xFF2B), W16(0xFFBF), W16(0xFFFD), W16(0x003C), W16(0x0040), W16(0x0096), W16(0x0067), W16(0x0095), + W16(0x0069), W16(0x003F), W16(0x000F), W16(0xFFE4), W16(0xFFAA), W16(0xFF59), W16(0xFF7C), W16(0xFF83), + W16(0xFF92), W16(0xFF82), W16(0xFFA1), W16(0xFFCC), W16(0xFFF5), W16(0x006F), W16(0x00B8), W16(0x00D2), + W16(0x0123), W16(0xFFB5), W16(0xFFA8), W16(0xFFC4), W16(0xFFB1), W16(0xFFBE), W16(0xFFDA), W16(0x000D), + W16(0x002E), W16(0x0047), W16(0x004A), W16(0x003D), W16(0x0038), W16(0x0008), W16(0xFFE0), W16(0xFFC3), + W16(0xFFCA), W16(0xFFA9), W16(0xFFB6), W16(0xFFA2), W16(0xFF8F), W16(0xFF6E), W16(0xFF69), W16(0xFF76), + W16(0xFFDE), W16(0xFF74), W16(0xFF2C), W16(0xFEEE), W16(0xFEF8), W16(0xFF28), W16(0xFF7F), W16(0xFFD0), + W16(0xFFF8), W16(0x002D), W16(0x007E), W16(0x0075), W16(0x006F), W16(0x006B), W16(0x0068), W16(0x0031), + W16(0x0006), W16(0xFFB4), W16(0xFF96), W16(0xFF61), W16(0xFF3E), W16(0xFF33), W16(0xFF24), W16(0xFF32), + W16(0xFF74), W16(0x0009), W16(0x000A), W16(0xFF60), W16(0x000F), W16(0x0039), W16(0x002C), W16(0x0019), + W16(0xFFED), W16(0xFFF5), W16(0xFFF6), W16(0xFFE6), W16(0x0009), W16(0xFFF4), W16(0xFFFD), W16(0xFFDF), + W16(0xFFDC), W16(0xFFAD), W16(0xFFA0), W16(0xFF7E), W16(0xFF5A), W16(0xFF45), W16(0xFF42), W16(0xFF54), + W16(0xFFAD), W16(0xFF8E), W16(0xFF94), W16(0xFFD4), W16(0x002A), W16(0xFFDA), W16(0xFF38), W16(0xFF1F), + W16(0xFF4F), W16(0xFFCA), W16(0x000A), W16(0x008E), W16(0x00B2), W16(0x0058), W16(0x002B), W16(0x0062), + W16(0x005D), W16(0x000C), W16(0xFFDF), W16(0x001B), W16(0x005D), W16(0x0085), W16(0x0044), W16(0x006D), + W16(0xFFAB), W16(0xFFA3), W16(0xFF6B), W16(0xFFB2), W16(0xFFEE), W16(0xFFD1), W16(0xFFE9), W16(0xFFFE), + W16(0x000A), W16(0xFFF3), W16(0x000A), W16(0x0022), W16(0x002D), W16(0x000B), W16(0x000D), W16(0xFFFC), + W16(0xFFEF), W16(0xFFE3), W16(0xFFD6), W16(0xFFDF), W16(0xFFDE), W16(0xFFE5), W16(0xFFF3), W16(0x0003), + W16(0x0058), W16(0xFF6D), W16(0xFEDB), W16(0x0148), W16(0x002F), W16(0xFEF8), W16(0x0025), W16(0x00F8), + W16(0x007F), W16(0x001A), W16(0xFFFD), W16(0x0016), W16(0x000A), W16(0x0003), W16(0xFF8F), W16(0xFFB0), + W16(0xFFC4), W16(0xFFEC), W16(0xFFB3), W16(0xFFB1), W16(0xFF88), W16(0xFF36), W16(0xFECB), W16(0xFE30), + W16(0x000E), W16(0x0038), W16(0x00C8), W16(0x0124), W16(0x013B), W16(0x00A4), W16(0x0050), W16(0x0061), + W16(0x0053), W16(0x0022), W16(0xFFC3), W16(0xFFC8), W16(0xFFB0), W16(0xFF77), W16(0xFF89), W16(0xFF67), + W16(0xFF57), W16(0xFF51), W16(0xFF46), W16(0xFF20), W16(0xFF1B), W16(0xFF2D), W16(0xFF2F), W16(0xFF42), + W16(0xFF7C), W16(0xFF55), W16(0xFF89), W16(0xFFC7), W16(0x0030), W16(0x0076), W16(0x003C), W16(0xFFC6), + W16(0xFFAA), W16(0xFF6A), W16(0xFF99), W16(0xFFC6), W16(0x002C), W16(0x0079), W16(0x0055), W16(0x0003), + W16(0xFFE7), W16(0x0025), W16(0x0019), W16(0xFFE8), W16(0xFFE1), W16(0xFFDC), W16(0xFFEB), W16(0xFFF7), + W16(0x0065), W16(0x0005), W16(0xFFC6), W16(0x0050), W16(0x0034), W16(0x003B), W16(0x0021), W16(0xFFFF), + W16(0x0016), W16(0x0004), W16(0xFFF6), W16(0x0022), W16(0xFFE4), W16(0xFF9E), W16(0xFFC9), W16(0xFFEF), + W16(0x0003), W16(0x001B), W16(0x003A), W16(0x0053), W16(0x0047), W16(0x0049), W16(0x0050), W16(0x005C), + W16(0x001D), W16(0xFFFA), W16(0x0042), W16(0x0045), W16(0x0074), W16(0xFFC3), W16(0xFFB3), W16(0xFFCF), + W16(0x005C), W16(0x0038), W16(0x003E), W16(0x0038), W16(0x0018), W16(0x0004), W16(0xFFCD), W16(0xFFB4), + W16(0xFFA0), W16(0xFFA0), W16(0xFF9C), W16(0xFF96), W16(0xFFA3), W16(0xFF9F), W16(0xFFB6), W16(0xFFD0), + W16(0xFED6), W16(0xFFA8), W16(0xFFDC), W16(0xFFD1), W16(0xFFDB), W16(0xFFFF), W16(0x0015), W16(0x0024), + W16(0x001F), W16(0x0002), W16(0xFFD6), W16(0xFFDB), W16(0xFFE0), W16(0xFFDC), W16(0x0009), W16(0x0022), + W16(0x0036), W16(0x0040), W16(0x0047), W16(0x0068), W16(0x0035), W16(0x001B), W16(0x000A), W16(0x000E), + W16(0xFFDD), W16(0xFF6B), W16(0xFF4C), W16(0xFF80), W16(0xFF71), W16(0xFF90), W16(0xFFAF), W16(0xFFCD), + W16(0xFFCC), W16(0xFFF8), W16(0x0011), W16(0x0039), W16(0x003A), W16(0x0018), W16(0x0047), W16(0x0064), + W16(0x0079), W16(0x0081), W16(0x00DA), W16(0x0122), W16(0x013D), W16(0x014D), W16(0x0166), W16(0x0164), + W16(0xFFD7), W16(0xFF25), W16(0xFEAE), W16(0xFEAA), W16(0xFF89), W16(0x0022), W16(0xFFDF), W16(0x0003), + W16(0x002B), W16(0x0009), W16(0x0003), W16(0x0020), W16(0x0032), W16(0xFFFE), W16(0xFFE6), W16(0x0001), + W16(0x0004), W16(0x000C), W16(0x001D), W16(0x002B), W16(0x0001), W16(0x0016), W16(0x0071), W16(0x0073), + W16(0x0078), W16(0x0042), W16(0x0005), W16(0xFFA0), W16(0x003D), W16(0x0046), W16(0x0018), W16(0xFFCE), + W16(0xFFF6), W16(0xFFEF), W16(0x0010), W16(0xFFE3), W16(0x0004), W16(0x0003), W16(0xFFF9), W16(0xFFE9), + W16(0xFFD6), W16(0xFFC6), W16(0xFFCD), W16(0xFFC6), W16(0xFFB9), W16(0xFFC7), W16(0xFFCB), W16(0xFFDD), + W16(0x00A0), W16(0xFFEB), W16(0xFFE2), W16(0xFF8B), W16(0x000C), W16(0x0079), W16(0x007F), W16(0x00BD), + W16(0x0098), W16(0x002C), W16(0x000B), W16(0xFFD9), W16(0xFFD6), W16(0xFFB0), W16(0xFF62), W16(0xFF53), + W16(0xFF5C), W16(0xFF4D), W16(0xFF42), W16(0xFF63), W16(0xFFAE), W16(0xFFD8), W16(0x0007), W16(0x004E), + W16(0xFF5C), W16(0x0027), W16(0x0008), W16(0x001B), W16(0x0020), W16(0x002A), W16(0x0043), W16(0xFFE7), + W16(0x0049), W16(0x0023), W16(0x0019), W16(0xFFDB), W16(0xFFFC), W16(0xFFF1), W16(0xFFC8), W16(0xFFB7), + W16(0xFFC1), W16(0xFFEF), W16(0x0057), W16(0x00C2), W16(0x00F7), W16(0x0133), W16(0x0193), W16(0x0204), + W16(0x00E7), W16(0xFFB8), W16(0xFF59), W16(0xFF4C), W16(0xFFA9), W16(0xFF9E), W16(0xFFB3), W16(0xFFBF), + W16(0xFFA9), W16(0xFFC1), W16(0xFFEF), W16(0x001A), W16(0x0053), W16(0x0056), W16(0x0051), W16(0x0071), + W16(0x006A), W16(0x0042), W16(0x003B), W16(0x003E), W16(0x0035), W16(0x003A), W16(0x0045), W16(0x0055), + W16(0xFF39), W16(0xFFE6), W16(0xFFED), W16(0xFF80), W16(0xFF51), W16(0xFF63), W16(0xFF81), W16(0xFFC1), + W16(0x0085), W16(0x00B5), W16(0x0078), W16(0x001F), W16(0xFFFA), W16(0xFFC4), W16(0xFFF2), W16(0x0030), + W16(0x005A), W16(0x0026), W16(0x0010), W16(0x0001), W16(0xFFD9), W16(0xFFB9), W16(0xFF83), W16(0xFF55), + W16(0xFF8A), W16(0x0105), W16(0x010B), W16(0xFFD4), W16(0xFFBC), W16(0xFF9B), W16(0xFFD3), W16(0xFFFA), + W16(0xFFF9), W16(0x0026), W16(0x001B), W16(0x001B), W16(0x0020), W16(0x000A), W16(0x0021), W16(0x002E), + W16(0x000E), W16(0x0001), W16(0x0005), W16(0xFFEE), W16(0xFFEA), W16(0x0024), W16(0x0020), W16(0x0022), + W16(0xFFB2), W16(0xFFF7), W16(0xFFB1), W16(0xFF56), W16(0xFF75), W16(0xFFB1), W16(0xFFCD), W16(0xFFBF), + W16(0xFFD3), W16(0xFFD5), W16(0xFFEF), W16(0xFFF9), W16(0x0003), W16(0x0031), W16(0x0039), W16(0x008B), + W16(0x00C8), W16(0x0076), W16(0x0055), W16(0x0034), W16(0x000F), W16(0x0003), W16(0xFFEF), W16(0xFFD6), + W16(0x0028), W16(0xFFFC), W16(0xFFFA), W16(0xFFD1), W16(0xFF1C), W16(0x002B), W16(0x001E), W16(0x000D), + W16(0x0027), W16(0x0018), W16(0x001B), W16(0xFFF3), W16(0x0029), W16(0x0024), W16(0x000A), W16(0xFFFE), + W16(0xFFEB), W16(0xFFED), W16(0xFFFB), W16(0x0002), W16(0xFFFF), W16(0x0004), W16(0x0010), W16(0x001F), + W16(0x008D), W16(0x000D), W16(0xFFDE), W16(0xFFE5), W16(0x0016), W16(0xFFFB), W16(0xFFCA), W16(0xFFDE), + W16(0xFFBB), W16(0xFFA1), W16(0xFFCE), W16(0xFFD8), W16(0x0006), W16(0x0005), W16(0x000E), W16(0x0080), + W16(0x00AB), W16(0x0041), W16(0xFFDE), W16(0xFFA4), W16(0xFF6E), W16(0xFF47), W16(0xFF30), W16(0xFF31), + W16(0xFF69), W16(0xFFAC), W16(0xFF93), W16(0xFF7F), W16(0x0021), W16(0x003F), W16(0xFFD0), W16(0xFF89), + W16(0xFF75), W16(0xFF81), W16(0xFF9C), W16(0xFF4B), W16(0xFF1F), W16(0x0011), W16(0x015C), W16(0x018B), + W16(0x0053), W16(0x001B), W16(0xFF65), W16(0xFED5), W16(0x0002), W16(0x0108), W16(0x0023), W16(0x0033), + W16(0xFFC2), W16(0x0007), W16(0x0014), W16(0x008D), W16(0x0088), W16(0x0096), W16(0x00C7), W16(0x0039), + W16(0xFFCB), W16(0xFF6F), W16(0xFF89), W16(0xFF74), W16(0xFF8B), W16(0xFFC2), W16(0x000E), W16(0x0031), + W16(0x001F), W16(0x0022), W16(0x0056), W16(0x0053), W16(0x0001), W16(0xFF91), W16(0xFF5F), W16(0xFF4A), + W16(0x00C6), W16(0x00D2), W16(0x00BF), W16(0x003B), W16(0x0078), W16(0x008A), W16(0x0068), W16(0x0017), + W16(0x003D), W16(0x0026), W16(0xFFF2), W16(0xFFC0), W16(0xFFA7), W16(0xFFAB), W16(0xFF98), W16(0xFFC2), + W16(0xFFC0), W16(0xFFD2), W16(0xFFCB), W16(0xFFE4), W16(0x0019), W16(0x0033), W16(0x0060), W16(0x0080), + W16(0x000D), W16(0xFFE0), W16(0x005B), W16(0xFFFC), W16(0x0006), W16(0xFFEA), W16(0x001F), W16(0x00A3), + W16(0x00C5), W16(0x00A1), W16(0x00B4), W16(0x006A), W16(0xFFFF), W16(0xFFB6), W16(0xFF4C), W16(0xFEFA), + W16(0xFECE), W16(0xFEDC), W16(0xFF33), W16(0xFF14), W16(0xFF40), W16(0xFF57), W16(0xFF4B), W16(0xFF76), + W16(0xFE80), W16(0xFFD5), W16(0x0044), W16(0x0041), W16(0x0053), W16(0x001C), W16(0x0021), W16(0xFFF9), + W16(0x000C), W16(0xFFEE), W16(0xFFEB), W16(0x001A), W16(0x0020), W16(0xFFEE), W16(0xFFE3), W16(0xFFD5), + W16(0xFFB2), W16(0xFFB4), W16(0xFFAD), W16(0xFFB6), W16(0xFF93), W16(0xFF95), W16(0xFFA8), W16(0xFFB7), + W16(0xFF19), W16(0xFEF4), W16(0xFEC3), W16(0xFEBE), W16(0xFF0D), W16(0xFF3D), W16(0xFF49), W16(0xFF58), + W16(0xFF69), W16(0xFFA0), W16(0x0011), W16(0x0086), W16(0x0065), W16(0x00AB), W16(0x00BE), W16(0x00F6), + W16(0x00B1), W16(0x00C3), W16(0x00C5), W16(0x0089), W16(0x0043), W16(0x0072), W16(0x0060), W16(0x003E), + W16(0xFF96), W16(0xFF5F), W16(0xFFE1), W16(0xFF92), W16(0xFF57), W16(0xFF7E), W16(0xFFDA), W16(0x0008), + W16(0x00B5), W16(0x0092), W16(0x008C), W16(0x0054), W16(0x0055), W16(0x001D), W16(0xFFC1), W16(0xFF8C), + W16(0xFF63), W16(0xFF6F), W16(0xFFAD), W16(0xFFD6), W16(0xFFEE), W16(0x002A), W16(0x0067), W16(0x009F), + W16(0x0004), W16(0xFFCC), W16(0x0081), W16(0x0020), W16(0x001C), W16(0x005E), W16(0x000E), W16(0x0018), + W16(0xFFEF), W16(0xFFF6), W16(0xFFF2), W16(0xFFEB), W16(0x000F), W16(0xFFEB), W16(0xFFDE), W16(0xFFE6), + W16(0xFFE0), W16(0xFFE4), W16(0xFFE4), W16(0xFFD6), W16(0xFFD6), W16(0xFFD9), W16(0xFFED), W16(0x0007), + W16(0xFFC3), W16(0xFFB7), W16(0xFF6C), W16(0xFFF4), W16(0x0172), W16(0xFFED), W16(0xFF8F), W16(0x021C), + W16(0x00B3), W16(0xFF40), W16(0xFFC8), W16(0xFF96), W16(0xFFD8), W16(0xFF89), W16(0xFF9E), W16(0xFF4E), + W16(0xFF5A), W16(0xFFEC), W16(0x0022), W16(0x0023), W16(0x000D), W16(0x0023), W16(0x000D), W16(0xFFF1), + W16(0xFF96), W16(0x00A1), W16(0x012A), W16(0x0086), W16(0x005C), W16(0x004A), W16(0x0082), W16(0x0000), + W16(0x0052), W16(0x0017), W16(0xFFDD), W16(0xFFD8), W16(0xFFD2), W16(0xFFB4), W16(0xFFA4), W16(0xFFD0), + W16(0xFFC1), W16(0xFFE3), W16(0x001D), W16(0x004F), W16(0x0093), W16(0x00BA), W16(0x00DE), W16(0x00E2), + W16(0x01E5), W16(0x005B), W16(0x0048), W16(0x004D), W16(0x0075), W16(0x0093), W16(0x0050), W16(0x0020), + W16(0x0007), W16(0xFFEE), W16(0xFFE9), W16(0xFFED), W16(0xFFEA), W16(0xFFE8), W16(0xFFC2), W16(0xFF9C), + W16(0xFF8E), W16(0xFF89), W16(0xFF8A), W16(0xFF8B), W16(0xFFA4), W16(0xFFBB), W16(0xFFD3), W16(0xFFF3), + W16(0x00F1), W16(0x009F), W16(0xFF81), W16(0xFFA5), W16(0xFF99), W16(0xFF36), W16(0xFF3B), W16(0xFFA2), + W16(0xFFF9), W16(0x0065), W16(0x005E), W16(0x004D), W16(0x0073), W16(0x0023), W16(0x0047), W16(0x0036), + W16(0x0038), W16(0x0018), W16(0xFFD0), W16(0xFFD4), W16(0xFFC4), W16(0xFFBA), W16(0xFFC4), W16(0xFFBE), + W16(0xFFC3), W16(0x0081), W16(0x005E), W16(0x0044), W16(0xFFFE), W16(0x0004), W16(0x0034), W16(0x0057), + W16(0x005A), W16(0x004B), W16(0x001C), W16(0x0002), W16(0xFFE5), W16(0xFFBE), W16(0xFFA9), W16(0xFFBC), + W16(0xFFAA), W16(0xFFA6), W16(0xFFAD), W16(0xFFA9), W16(0xFFA6), W16(0xFF9A), W16(0xFFAE), W16(0xFFC2), + W16(0x00A3), W16(0x007B), W16(0x0032), W16(0x005C), W16(0x0084), W16(0x001C), W16(0xFFAC), W16(0xFF34), + W16(0xFF86), W16(0xFFC6), W16(0x0020), W16(0x0074), W16(0x0079), W16(0x000F), W16(0xFFEC), W16(0x0014), + W16(0x001A), W16(0x0009), W16(0x0015), W16(0x0077), W16(0x00C2), W16(0x0100), W16(0x011E), W16(0x016A), + W16(0xFFBA), W16(0x0029), W16(0x0017), W16(0xFFE0), W16(0x0015), W16(0x001F), W16(0xFFF4), W16(0xFFB0), + W16(0xFFD2), W16(0xFFBB), W16(0xFFEA), W16(0x0007), W16(0x002A), W16(0x0026), W16(0x0033), W16(0x001C), + W16(0x000B), W16(0x0018), W16(0x0029), W16(0x0034), W16(0x004C), W16(0x0079), W16(0x0090), W16(0x00AC), + W16(0xFFF1), W16(0xFFCA), W16(0x0002), W16(0x0052), W16(0xFFBE), W16(0xFF5B), W16(0xFFDD), W16(0xFFEC), + W16(0xFFDD), W16(0xFFF5), W16(0x003C), W16(0x0050), W16(0x003D), W16(0x0016), W16(0x0027), W16(0x002C), + W16(0x0019), W16(0x0017), W16(0x001F), W16(0x0030), W16(0x0021), W16(0x002C), W16(0x0020), W16(0x002B), + W16(0x000E), W16(0x0099), W16(0x0075), W16(0x0097), W16(0x009F), W16(0x007B), W16(0x003E), W16(0xFFF5), + W16(0xFF9F), W16(0xFFB1), W16(0xFFF0), W16(0xFFF9), W16(0x000F), W16(0x000A), W16(0xFFF9), W16(0xFFC0), + W16(0xFFA6), W16(0xFF93), W16(0xFF97), W16(0xFF93), W16(0xFF9E), W16(0xFFAC), W16(0xFFC2), W16(0xFFEC), + W16(0x002D), W16(0xFF24), W16(0xFEC4), W16(0x0070), W16(0xFF17), W16(0x0191), W16(0x00DD), W16(0xFFF4), + W16(0xFDFE), W16(0x00C4), W16(0xFF19), W16(0x0031), W16(0xFFB2), W16(0xFFED), W16(0xFF78), W16(0x0076), + W16(0x00EC), W16(0x00E1), W16(0x007F), W16(0x005A), W16(0x00C6), W16(0x0028), W16(0x00F2), W16(0x01B2), + W16(0x0127), W16(0x0076), W16(0x007F), W16(0x007A), W16(0x0041), W16(0x0078), W16(0x003E), W16(0xFFF5), + W16(0xFFB0), W16(0xFF89), W16(0xFFA4), W16(0xFFBC), W16(0xFFF0), W16(0x000C), W16(0x003C), W16(0x001E), + W16(0x0024), W16(0x003B), W16(0x004F), W16(0x007B), W16(0x0090), W16(0x00AB), W16(0x00B5), W16(0x00C7), + W16(0x00B0), W16(0x007D), W16(0x0076), W16(0x0068), W16(0x0056), W16(0x0050), W16(0xFFE6), W16(0x0004), + W16(0x0038), W16(0x0040), W16(0x001E), W16(0x002C), W16(0x0022), W16(0xFFC9), W16(0xFFAA), W16(0xFF9B), + W16(0xFF7D), W16(0xFF7A), W16(0xFF95), W16(0xFFCF), W16(0x0002), W16(0x0046), W16(0x00A9), W16(0x00F5), + W16(0xFF44), W16(0xFFB4), W16(0xFFDB), W16(0xFFD9), W16(0xFF9D), W16(0xFF8B), W16(0xFF71), W16(0xFF5E), + W16(0xFF8E), W16(0xFF94), W16(0xFFA9), W16(0xFFF0), W16(0x006F), W16(0x007A), W16(0x00AA), W16(0x00C5), + W16(0x00F6), W16(0x0145), W16(0x015F), W16(0x013D), W16(0x0111), W16(0x00FF), W16(0x00DC), W16(0x00C7), + W16(0xFEE8), W16(0xFEFE), W16(0xFEDE), W16(0xFF0B), W16(0xFE87), W16(0xFED9), W16(0xFEB8), W16(0xFEF7), + W16(0x0069), W16(0x0072), W16(0x00AE), W16(0x009A), W16(0x00B6), W16(0x004F), W16(0xFF68), W16(0x0035), + W16(0x022C), W16(0x0238), W16(0x020A), W16(0x0284), W16(0x01BA), W16(0xFFD5), W16(0x003F), W16(0xFF8E), + W16(0x00D0), W16(0x000F), W16(0xFFCE), W16(0xFF88), W16(0x0015), W16(0xFFFE), W16(0x003F), W16(0x001A), + W16(0x0023), W16(0x0019), W16(0x0029), W16(0xFFF1), W16(0xFFE7), W16(0xFFDC), W16(0xFFBF), W16(0xFFE4), + W16(0xFFD7), W16(0xFFDF), W16(0x000D), W16(0x0051), W16(0x0090), W16(0x00C6), W16(0x010D), W16(0x0138), + W16(0x00E7), W16(0x00AC), W16(0x0057), W16(0x0021), W16(0x0008), W16(0xFFE6), W16(0xFFE0), W16(0x0021), + W16(0x002C), W16(0xFFE0), W16(0xFFFC), W16(0x0001), W16(0x000F), W16(0xFFE8), W16(0xFFFD), W16(0x0006), + W16(0x000E), W16(0x000F), W16(0x0021), W16(0x001A), W16(0x0013), W16(0x0006), W16(0x0021), W16(0x0044), + W16(0x013C), W16(0x0128), W16(0x00CA), W16(0xFFFD), W16(0xFFC0), W16(0xFFA0), W16(0x0013), W16(0x0077), + W16(0x00E3), W16(0x00B9), W16(0x0066), W16(0xFFF7), W16(0xFFD2), W16(0xFFE0), W16(0xFF99), W16(0xFF5A), + W16(0xFF78), W16(0xFF7A), W16(0xFF80), W16(0xFF73), W16(0xFF90), W16(0xFF88), W16(0xFF86), W16(0xFF8B), + W16(0x0038), W16(0x006D), W16(0x004E), W16(0x0015), W16(0xFFF6), W16(0xFFF0), W16(0x0004), W16(0x000A), + W16(0x000E), W16(0xFFEE), W16(0xFFE1), W16(0xFFF1), W16(0xFFE5), W16(0xFFEE), W16(0xFFFA), W16(0x001B), + W16(0x0056), W16(0x00A5), W16(0x00D9), W16(0x0103), W16(0x0104), W16(0x0118), W16(0x012A), W16(0x0111), + W16(0x0299), W16(0x000F), W16(0xFFE1), W16(0xFFCC), W16(0xFFC8), W16(0xFFC3), W16(0xFFF5), W16(0xFFDB), + W16(0x0000), W16(0x0006), W16(0x0029), W16(0x001B), W16(0x001F), W16(0xFFF5), W16(0x0011), W16(0x0011), + W16(0x0023), W16(0x002A), W16(0x003B), W16(0x0046), W16(0x004F), W16(0x0049), W16(0x0058), W16(0x0053), + W16(0x004B), W16(0x0043), W16(0x0088), W16(0x00CD), W16(0x0037), W16(0xFE8A), W16(0xFEB7), W16(0xFF69), + W16(0x0019), W16(0x0084), W16(0x0058), W16(0xFFF1), W16(0xFF76), W16(0x00C5), W16(0x016A), W16(0x0028), + W16(0x006B), W16(0x004E), W16(0x001C), W16(0xFFD0), W16(0x0032), W16(0xFFB9), W16(0xFF95), W16(0xFFC6), + W16(0xFF8D), W16(0x005A), W16(0x00CB), W16(0x0100), W16(0x0056), W16(0xFFD6), W16(0x001A), W16(0xFFC6), + W16(0xFFBE), W16(0xFFE8), W16(0xFFEF), W16(0x0009), W16(0xFFF5), W16(0xFFDD), W16(0xFFF6), W16(0x003D), + W16(0x0053), W16(0x00B0), W16(0x00D2), W16(0x0092), W16(0x0050), W16(0x0023), W16(0x0014), W16(0xFFFB), + W16(0x0119), W16(0x0057), W16(0x0013), W16(0x0009), W16(0xFFF2), W16(0xFFBD), W16(0xFF9C), W16(0xFF9F), + W16(0xFFB8), W16(0xFFB1), W16(0xFFE9), W16(0xFFDE), W16(0xFFFC), W16(0x0036), W16(0x007D), W16(0x0096), + W16(0x00A1), W16(0x00CB), W16(0x00FC), W16(0x011C), W16(0x00A5), W16(0x003F), W16(0x0010), W16(0xFFE0), + W16(0x007C), W16(0x00BA), W16(0x0029), W16(0xFF86), W16(0xFF34), W16(0xFFD2), W16(0xFFB7), W16(0xFFE5), + W16(0x0033), W16(0x0041), W16(0x0035), W16(0xFFFB), W16(0x0037), W16(0x0040), W16(0x000B), W16(0x000C), + W16(0x0029), W16(0x0038), W16(0x006F), W16(0x00B3), W16(0x00C6), W16(0x00C4), W16(0x00BB), W16(0x009C), + W16(0x00E5), W16(0x00CF), W16(0x0125), W16(0x00BA), W16(0xFFFD), W16(0x0010), W16(0x0007), W16(0xFFA1), + W16(0xFFFB), W16(0xFFFE), W16(0x0005), W16(0x000E), W16(0x0004), W16(0xFFDE), W16(0x0026), W16(0x0020), + W16(0x0017), W16(0xFFE3), W16(0xFFA9), W16(0xFF84), W16(0xFF5A), W16(0xFF1B), W16(0xFEAE), W16(0xFE61), + W16(0xFD6E), W16(0x012D), W16(0x014A), W16(0x01A9), W16(0x02D2), W16(0x02CA), W16(0x01CC), W16(0xFF5B), + W16(0xFF28), W16(0xFEF0), W16(0xFE82), W16(0xFDF4), W16(0xFDFF), W16(0xFFE2), W16(0x00A4), W16(0x0063), + W16(0xFFC7), W16(0xFF44), W16(0xFEE8), W16(0xFEBA), W16(0xFE4F), W16(0xFF09), W16(0xFE6C), W16(0xFDBE), + W16(0xFFD3), W16(0x0007), W16(0x00A0), W16(0x0043), W16(0x0035), W16(0x0060), W16(0x007A), W16(0x0039), + W16(0xFFD4), W16(0xFFEE), W16(0xFFB3), W16(0xFFAD), W16(0xFFE3), W16(0x008D), W16(0x0055), W16(0xFF7B), + W16(0xFF56), W16(0x0096), W16(0x011B), W16(0x00F3), W16(0x009A), W16(0x006B), W16(0xFFBC), W16(0xFEEB), + W16(0x0298), W16(0x01D9), W16(0x0134), W16(0x0082), W16(0x0005), W16(0x002A), W16(0xFFE3), W16(0xFFB3), + W16(0xFFCA), W16(0xFFF4), W16(0x0019), W16(0x0036), W16(0x0023), W16(0x0010), W16(0x0011), W16(0xFFF2), + W16(0xFFF7), W16(0xFFF5), W16(0xFFFF), W16(0x0001), W16(0x0022), W16(0x003E), W16(0x0047), W16(0x0037) +}; + +const Word16 cdk_37bits_3_fx[1536] = +{ + W16(0xFFCD), W16(0xFFFB), W16(0xFFC7), W16(0x0024), W16(0x0000), W16(0xFFAB), W16(0x014C), W16(0xFF9A), + W16(0xFFF0), W16(0xFFF1), W16(0x0002), W16(0x0015), W16(0xFFF3), W16(0xFFDC), W16(0xFFD2), W16(0x000F), + W16(0xFFC6), W16(0xFFF3), W16(0xFFF1), W16(0x0032), W16(0x006F), W16(0x0054), W16(0x008F), W16(0x009B), + W16(0x001C), W16(0x0006), W16(0xFFFE), W16(0xFFF3), W16(0xFFDF), W16(0xFF49), W16(0xFFB0), W16(0xFFC8), + W16(0xFFFB), W16(0xFFC2), W16(0xFFE5), W16(0xFFBF), W16(0xFFFC), W16(0x00B0), W16(0x0129), W16(0x0079), + W16(0xFFB2), W16(0xFF40), W16(0xFF97), W16(0xFF9B), W16(0xFFCB), W16(0xFFB6), W16(0xFFB4), W16(0xFFBD), + W16(0xFEFA), W16(0xFFA2), W16(0xFF63), W16(0xFFB2), W16(0xFFAB), W16(0xFFAF), W16(0x000F), W16(0x0024), + W16(0x0003), W16(0xFFD1), W16(0xFFF4), W16(0xFFB4), W16(0xFFFC), W16(0x001D), W16(0x0041), W16(0x0066), + W16(0x0039), W16(0xFFE5), W16(0xFFE3), W16(0x000D), W16(0x003B), W16(0x0076), W16(0x0069), W16(0x0044), + W16(0xFF95), W16(0xFF75), W16(0xFF97), W16(0xFFE8), W16(0x0022), W16(0xFFBB), W16(0x0009), W16(0x0049), + W16(0x0046), W16(0x0004), W16(0xFFFA), W16(0x0010), W16(0x001C), W16(0xFFDB), W16(0xFFE9), W16(0xFFCA), + W16(0xFFD3), W16(0xFFAE), W16(0xFFAC), W16(0xFFA9), W16(0xFF8C), W16(0xFF7B), W16(0xFF71), W16(0xFF78), + W16(0x002E), W16(0xFF90), W16(0xFF94), W16(0xFFA4), W16(0xFFAF), W16(0xFFEF), W16(0x0000), W16(0x0076), + W16(0x001E), W16(0x0031), W16(0x0044), W16(0x0081), W16(0xFFFE), W16(0xFFA3), W16(0xFF90), W16(0xFFB4), + W16(0xFFF2), W16(0x0053), W16(0x011E), W16(0x0107), W16(0xFF79), W16(0xFFBB), W16(0xFF82), W16(0xFED6), + W16(0xFFD0), W16(0x004A), W16(0x002F), W16(0xFF34), W16(0xFF4E), W16(0x0016), W16(0x0007), W16(0x0047), + W16(0x004D), W16(0x0025), W16(0x000F), W16(0x0018), W16(0xFFF9), W16(0xFFF9), W16(0xFFDC), W16(0xFFE9), + W16(0xFFFF), W16(0xFFCE), W16(0xFFB7), W16(0xFFB8), W16(0xFFB0), W16(0xFFB4), W16(0xFFB1), W16(0xFF9A), + W16(0x006B), W16(0xFFDD), W16(0x0002), W16(0xFFE4), W16(0xFFE1), W16(0xFFE2), W16(0xFFD5), W16(0xFFC3), + W16(0xFFEC), W16(0xFFE6), W16(0x000D), W16(0xFFD7), W16(0xFF99), W16(0xFFBD), W16(0x0001), W16(0x00C4), + W16(0x00D3), W16(0xFF57), W16(0xFF8A), W16(0xFF78), W16(0xFFF6), W16(0xFFEA), W16(0xFFDC), W16(0xFFDC), + W16(0xFFD2), W16(0x001D), W16(0x0017), W16(0x0004), W16(0xFFF0), W16(0x0014), W16(0xFFF6), W16(0xFF21), + W16(0x0020), W16(0x0041), W16(0x0030), W16(0x000C), W16(0xFFCA), W16(0xFFFF), W16(0x0037), W16(0x003D), + W16(0x000A), W16(0xFFEA), W16(0xFFE0), W16(0xFFCC), W16(0xFFD4), W16(0xFFC0), W16(0xFFD0), W16(0xFFCD), + W16(0xFF6A), W16(0xFFEF), W16(0xFFFF), W16(0x002C), W16(0xFFC8), W16(0x0077), W16(0x0059), W16(0x000B), + W16(0xFFF5), W16(0xFFFA), W16(0xFFF6), W16(0xFFF1), W16(0xFFDD), W16(0xFFCF), W16(0xFFEA), W16(0xFFF1), + W16(0x0000), W16(0xFFF9), W16(0xFFE4), W16(0xFFB7), W16(0xFF96), W16(0xFF61), W16(0xFF43), W16(0xFF3C), + W16(0xFFE4), W16(0xFFE7), W16(0xFFA0), W16(0xFFA4), W16(0x003D), W16(0x00B1), W16(0x0085), W16(0xFFFC), + W16(0xFF91), W16(0xFFCD), W16(0x0002), W16(0x0011), W16(0xFFF4), W16(0x002A), W16(0xFFE1), W16(0xFF92), + W16(0xFF8F), W16(0xFF82), W16(0xFF9A), W16(0xFFB1), W16(0xFFBE), W16(0xFFEA), W16(0x0011), W16(0x002A), + W16(0xFFAC), W16(0xFFD1), W16(0xFFC2), W16(0xFF84), W16(0xFFCF), W16(0xFFFD), W16(0xFFB5), W16(0xFFA4), + W16(0xFFE6), W16(0xFFD3), W16(0x001E), W16(0x0061), W16(0x0062), W16(0xFFFA), W16(0x0023), W16(0x0016), + W16(0x000D), W16(0x000E), W16(0x000E), W16(0x0003), W16(0x0009), W16(0x0015), W16(0x000A), W16(0x0002), + W16(0xFFB7), W16(0xFFD9), W16(0xFFE4), W16(0xFFBB), W16(0x00F9), W16(0xFFCC), W16(0xFFC6), W16(0xFFA8), + W16(0x0026), W16(0x0005), W16(0x0014), W16(0x0039), W16(0x0040), W16(0xFFE4), W16(0xFF68), W16(0xFF9A), + W16(0x002F), W16(0x0058), W16(0xFFB2), W16(0x001C), W16(0xFFCC), W16(0xFF92), W16(0xFF7D), W16(0xFF60), + W16(0xFFB4), W16(0xFFA5), W16(0xFFEC), W16(0xFFF2), W16(0xFFDD), W16(0xFFF6), W16(0x0033), W16(0x00A0), + W16(0x0097), W16(0x0028), W16(0xFFB8), W16(0xFF58), W16(0xFFA8), W16(0x0024), W16(0xFFE4), W16(0xFFE0), + W16(0xFFFB), W16(0xFFEB), W16(0xFFE2), W16(0xFFD9), W16(0xFFFC), W16(0xFFF7), W16(0x000F), W16(0x0004), + W16(0x0053), W16(0x0020), W16(0x004C), W16(0xFFFC), W16(0x003C), W16(0x0052), W16(0x0027), W16(0x000E), + W16(0x0050), W16(0x0024), W16(0x001C), W16(0xFFE9), W16(0xFFDE), W16(0xFFDB), W16(0xFFBA), W16(0xFFB3), + W16(0xFF9E), W16(0xFFAD), W16(0xFFA2), W16(0xFFA3), W16(0xFFB2), W16(0xFFAA), W16(0xFFB4), W16(0xFFBC), + W16(0xFFF7), W16(0xFFF0), W16(0xFFE4), W16(0x000B), W16(0xFFDE), W16(0xFFE3), W16(0x0024), W16(0xFFB4), + W16(0x0062), W16(0x0045), W16(0xFFCB), W16(0xFFB0), W16(0x00DD), W16(0x006B), W16(0xFF74), W16(0xFF89), + W16(0x0001), W16(0xFFBB), W16(0xFFCD), W16(0xFF9D), W16(0xFF92), W16(0xFF76), W16(0xFF9F), W16(0xFFCF), + W16(0xFF91), W16(0xFF37), W16(0xFFB4), W16(0x00BC), W16(0x004A), W16(0xFFB2), W16(0x001B), W16(0xFF97), + W16(0xFF7D), W16(0x0039), W16(0x003C), W16(0xFFE1), W16(0x0007), W16(0xFFEF), W16(0x0045), W16(0x0031), + W16(0x0014), W16(0x0069), W16(0x005C), W16(0xFFF5), W16(0xFFE8), W16(0xFFD8), W16(0xFFA5), W16(0xFFCB), + W16(0x0024), W16(0x000A), W16(0xFEB4), W16(0x0002), W16(0x0003), W16(0xFFCA), W16(0x002D), W16(0xFFE3), + W16(0xFFF5), W16(0xFFE2), W16(0xFFFE), W16(0x000E), W16(0x0008), W16(0x000F), W16(0x0019), W16(0x0032), + W16(0xFFDD), W16(0xFFFB), W16(0xFFCE), W16(0xFFBA), W16(0xFFC9), W16(0xFFDE), W16(0x000E), W16(0x003D), + W16(0xFFC6), W16(0xFFDD), W16(0xFFA6), W16(0xFFB3), W16(0x0105), W16(0xFFDA), W16(0xFFD0), W16(0xFFCD), + W16(0x0000), W16(0xFFB9), W16(0x0018), W16(0xFF8C), W16(0xFFF1), W16(0xFFD9), W16(0x0030), W16(0x002F), + W16(0xFFFF), W16(0xFFF1), W16(0xFFF6), W16(0x0000), W16(0xFFFC), W16(0x0017), W16(0x003C), W16(0x004E), + W16(0xFED7), W16(0x0028), W16(0x0038), W16(0x0015), W16(0x0006), W16(0xFFF7), W16(0xFFF2), W16(0xFFEC), + W16(0xFFD4), W16(0xFFCF), W16(0xFFE3), W16(0x0024), W16(0x0022), W16(0x000D), W16(0x0027), W16(0x0014), + W16(0x0010), W16(0x0015), W16(0x0028), W16(0x001C), W16(0x0007), W16(0xFFD2), W16(0xFFBD), W16(0xFF93), + W16(0x0068), W16(0xFF90), W16(0x002E), W16(0x007D), W16(0x001B), W16(0x004E), W16(0x000D), W16(0x006E), + W16(0x0039), W16(0xFFF7), W16(0xFF97), W16(0x0018), W16(0xFFF1), W16(0xFFC5), W16(0xFF94), W16(0xFFDB), + W16(0x0018), W16(0x0003), W16(0x001A), W16(0xFFE9), W16(0xFFBC), W16(0xFF9E), W16(0xFF96), W16(0xFF88), + W16(0xFFB0), W16(0xFF7C), W16(0xFF95), W16(0x002C), W16(0xFF96), W16(0xFFB9), W16(0x005F), W16(0x0042), + W16(0xFFEA), W16(0xFFBE), W16(0xFFDC), W16(0x0030), W16(0x00AB), W16(0x006D), W16(0xFFC0), W16(0xFFA5), + W16(0xFFE0), W16(0x0098), W16(0x007B), W16(0x0017), W16(0x0040), W16(0x0079), W16(0x005B), W16(0x002E), + W16(0x0021), W16(0x001A), W16(0x0055), W16(0xFFCE), W16(0xFF7A), W16(0x0058), W16(0x001F), W16(0xFFC7), + W16(0xFFCA), W16(0x002E), W16(0x001E), W16(0x0020), W16(0x0004), W16(0x0014), W16(0x000C), W16(0xFFF8), + W16(0xFFF7), W16(0xFFE0), W16(0xFFCF), W16(0xFFEF), W16(0x00B1), W16(0x00C8), W16(0xFF9A), W16(0xFF27), + W16(0x000D), W16(0x0039), W16(0x0036), W16(0x0009), W16(0xFFC7), W16(0xFFBB), W16(0xFFE9), W16(0x0019), + W16(0x0004), W16(0x000D), W16(0x0007), W16(0xFFF6), W16(0xFFF1), W16(0x0018), W16(0x0013), W16(0x003A), + W16(0x0017), W16(0xFFAF), W16(0xFF5F), W16(0xFF23), W16(0xFF3C), W16(0xFF6D), W16(0xFFB3), W16(0x0035), + W16(0xFFAC), W16(0x0041), W16(0xFFE3), W16(0x0054), W16(0xFFCB), W16(0x003E), W16(0xFFFE), W16(0x000E), + W16(0x003A), W16(0x003C), W16(0x0018), W16(0xFFDF), W16(0xFFFB), W16(0x0012), W16(0xFFE9), W16(0xFFC7), + W16(0xFFC1), W16(0xFFE2), W16(0xFFFF), W16(0x0009), W16(0x001F), W16(0x0018), W16(0x0015), W16(0x0009), + W16(0xFFEA), W16(0xFFBD), W16(0xFFEC), W16(0xFFD1), W16(0xFFF5), W16(0x0036), W16(0x005A), W16(0x002D), + W16(0xFFD8), W16(0xFF85), W16(0xFF4D), W16(0xFFA3), W16(0xFFE4), W16(0x0015), W16(0x0097), W16(0x0050), + W16(0x0021), W16(0xFFDA), W16(0xFFB6), W16(0x003A), W16(0xFFF8), W16(0xFFD2), W16(0xFFD6), W16(0xFFD8), + W16(0x0084), W16(0xFF0B), W16(0xFFEF), W16(0xFFD7), W16(0xFFCF), W16(0x0001), W16(0xFFE0), W16(0xFFFE), + W16(0x001C), W16(0x0020), W16(0x0018), W16(0x0005), W16(0xFFF3), W16(0x0009), W16(0xFFFF), W16(0x0007), + W16(0xFFF8), W16(0xFFF2), W16(0xFFF3), W16(0x0001), W16(0x0008), W16(0x000A), W16(0x0014), W16(0x000E), + W16(0xFFD6), W16(0xFFB8), W16(0xFFC6), W16(0xFFF9), W16(0x0008), W16(0xFFFD), W16(0xFFE6), W16(0x0048), + W16(0xFF6D), W16(0x005B), W16(0x0013), W16(0x002F), W16(0xFFD8), W16(0x0003), W16(0x0002), W16(0xFFF8), + W16(0xFFEE), W16(0x0008), W16(0xFFFB), W16(0xFFF6), W16(0xFFFC), W16(0xFFFF), W16(0x0002), W16(0x0002), + W16(0x0059), W16(0x006C), W16(0xFFE7), W16(0x004C), W16(0x0074), W16(0x0086), W16(0x0037), W16(0xFFA6), + W16(0xFFD0), W16(0xFFD6), W16(0xFFC0), W16(0xFFCD), W16(0xFFC3), W16(0xFFD8), W16(0xFFFE), W16(0x0026), + W16(0x0037), W16(0x0027), W16(0x0003), W16(0xFFE9), W16(0xFFC5), W16(0xFFB8), W16(0xFFCD), W16(0xFFCF), + W16(0x0005), W16(0x0037), W16(0x001E), W16(0xFFFC), W16(0x0022), W16(0x0034), W16(0xFF0F), W16(0x002B), + W16(0x0037), W16(0x002D), W16(0x0013), W16(0x0021), W16(0x000C), W16(0x0003), W16(0x000D), W16(0xFFEE), + W16(0xFFCF), W16(0xFFE6), W16(0xFFF6), W16(0xFFEC), W16(0xFFDB), W16(0xFFDB), W16(0xFFDC), W16(0xFFCF), + W16(0xFF53), W16(0x0078), W16(0x00C4), W16(0xFFC3), W16(0x0051), W16(0x0005), W16(0x0002), W16(0x0022), + W16(0x001C), W16(0x0028), W16(0xFFF9), W16(0xFFE4), W16(0xFFF7), W16(0xFFE5), W16(0xFFC9), W16(0xFFE1), + W16(0xFFDF), W16(0xFFE1), W16(0xFFE8), W16(0x0007), W16(0x003C), W16(0x005F), W16(0x0083), W16(0x0089), + W16(0x00EB), W16(0x0009), W16(0xFFB7), W16(0xFF7B), W16(0xFFD0), W16(0x0024), W16(0xFFC8), W16(0xFFBD), + W16(0xFFDF), W16(0xFFE4), W16(0xFFF5), W16(0x002E), W16(0x0023), W16(0x001D), W16(0x002C), W16(0x001B), + W16(0x001A), W16(0xFFF8), W16(0xFFEA), W16(0xFFD5), W16(0xFFE9), W16(0xFFD1), W16(0xFFC9), W16(0xFFC1), + W16(0xFFE3), W16(0xFFB1), W16(0x0009), W16(0x0096), W16(0x0111), W16(0x00E2), W16(0xFFEA), W16(0xFFBB), + W16(0x000E), W16(0xFFF0), W16(0xFFBC), W16(0xFFF9), W16(0xFFC7), W16(0xFF9E), W16(0xFFA3), W16(0xFFBD), + W16(0xFFEE), W16(0x001E), W16(0x0002), W16(0x0020), W16(0x0032), W16(0x0051), W16(0x0052), W16(0x0062), + W16(0x0032), W16(0x0041), W16(0xFFE4), W16(0xFF9B), W16(0x001C), W16(0xFF48), W16(0x0000), W16(0x002F), + W16(0x0015), W16(0x0014), W16(0x003D), W16(0x0026), W16(0xFFF1), W16(0x0015), W16(0xFFF1), W16(0xFFF9), + W16(0xFFF0), W16(0xFFF4), W16(0xFFED), W16(0xFFFA), W16(0x000D), W16(0x001C), W16(0x002B), W16(0x0023), + W16(0xFFEB), W16(0xFFCF), W16(0x0049), W16(0x0037), W16(0x0039), W16(0xFFBA), W16(0xFFF9), W16(0xFFFD), + W16(0x0045), W16(0x0021), W16(0xFF72), W16(0x0033), W16(0x0010), W16(0x0017), W16(0xFFF6), W16(0x0002), + W16(0xFFEC), W16(0xFFDB), W16(0xFFD4), W16(0xFFC8), W16(0xFFE3), W16(0xFFF4), W16(0x0015), W16(0x0019), + W16(0xFFAC), W16(0xFFB9), W16(0x000E), W16(0xFFA3), W16(0xFF88), W16(0xFFB0), W16(0xFFF1), W16(0xFFEA), + W16(0xFFED), W16(0xFFD8), W16(0x0009), W16(0x0004), W16(0xFFEF), W16(0x002C), W16(0x0051), W16(0x004E), + W16(0x0062), W16(0x0074), W16(0x0075), W16(0x0055), W16(0x0027), W16(0x000F), W16(0xFFF2), W16(0xFFDA), + W16(0xFF96), W16(0xFFB4), W16(0x0033), W16(0x001C), W16(0xFF5C), W16(0xFFC5), W16(0xFFC8), W16(0xFFD7), + W16(0x000D), W16(0x0059), W16(0x0077), W16(0x006A), W16(0x002C), W16(0x002D), W16(0x0003), W16(0xFFD2), + W16(0xFFCD), W16(0xFFD8), W16(0xFFD0), W16(0xFFED), W16(0xFFEA), W16(0xFFE8), W16(0xFFF9), W16(0xFFF6), + W16(0x0052), W16(0xFFD4), W16(0xFF5B), W16(0xFF8B), W16(0xFFA9), W16(0x003F), W16(0x007C), W16(0x0028), + W16(0x001B), W16(0x0010), W16(0xFFD1), W16(0xFFCD), W16(0x0004), W16(0xFFCA), W16(0xFFEE), W16(0xFFE7), + W16(0x0008), W16(0x0047), W16(0x0086), W16(0x0087), W16(0x0064), W16(0x0024), W16(0x000C), W16(0xFFD7), + W16(0x00A6), W16(0x008E), W16(0x0077), W16(0xFFD8), W16(0xFF6A), W16(0x003A), W16(0x003B), W16(0x0017), + W16(0x0028), W16(0x0010), W16(0xFFFA), W16(0xFFDE), W16(0xFFFC), W16(0xFFEC), W16(0xFFE0), W16(0x000B), + W16(0x0026), W16(0x003C), W16(0x003F), W16(0x003E), W16(0x0049), W16(0x006F), W16(0x0080), W16(0x0080), + W16(0xFFB8), W16(0xFFC2), W16(0xFFBE), W16(0x0017), W16(0xFFF9), W16(0xFFF0), W16(0xFFE0), W16(0xFFE4), + W16(0x0027), W16(0x0000), W16(0xFFE9), W16(0x00A2), W16(0x002E), W16(0xFF66), W16(0xFF4F), W16(0x0042), + W16(0x007C), W16(0xFFE4), W16(0xFFF6), W16(0x000A), W16(0x0039), W16(0x0054), W16(0x0054), W16(0x0033), + W16(0xFFD9), W16(0x0003), W16(0x0012), W16(0x0010), W16(0x000B), W16(0x0000), W16(0xFF97), W16(0xFF97), + W16(0xFFC8), W16(0x00AF), W16(0x0215), W16(0xFF25), W16(0xFFD7), W16(0xFFF1), W16(0xFF98), W16(0xFFC3), + W16(0xFFF2), W16(0x0005), W16(0xFFDA), W16(0x0052), W16(0x0069), W16(0x0051), W16(0x008A), W16(0x00CA), + W16(0xFFAB), W16(0xFF9D), W16(0x00C3), W16(0x006D), W16(0x002D), W16(0x006D), W16(0x0064), W16(0x0037), + W16(0xFFBA), W16(0xFFA4), W16(0xFFB3), W16(0xFFF0), W16(0xFFFE), W16(0x0045), W16(0x0029), W16(0xFFD6), + W16(0xFF87), W16(0xFFCD), W16(0xFFFF), W16(0xFFCF), W16(0xFFFF), W16(0xFFE4), W16(0x0003), W16(0x0021), + W16(0x0066), W16(0xFF93), W16(0xFFAD), W16(0xFFFA), W16(0xFFC8), W16(0xFFA4), W16(0xFFD9), W16(0x0072), + W16(0x0007), W16(0x000D), W16(0x0011), W16(0x004A), W16(0x002A), W16(0x002B), W16(0x0002), W16(0xFFDF), + W16(0xFFA4), W16(0xFF6C), W16(0xFF66), W16(0xFF97), W16(0x0035), W16(0x0084), W16(0x00B6), W16(0x00EA), + W16(0x0017), W16(0xFFDC), W16(0x005C), W16(0x004A), W16(0xFFF1), W16(0x0038), W16(0xFFE1), W16(0xFF9F), + W16(0xFF3F), W16(0xFF63), W16(0xFFDE), W16(0x0092), W16(0x0082), W16(0x0053), W16(0x0033), W16(0x003F), + W16(0xFFFF), W16(0xFFEB), W16(0xFFD3), W16(0xFFC8), W16(0xFFC0), W16(0xFFD9), W16(0xFFBD), W16(0xFFA6), + W16(0xFFFE), W16(0x0006), W16(0x0045), W16(0xFF02), W16(0x0036), W16(0x008E), W16(0x000B), W16(0xFFE4), + W16(0x001C), W16(0xFFEF), W16(0xFFCF), W16(0xFFD5), W16(0xFFD3), W16(0xFFFA), W16(0xFFE6), W16(0xFFF1), + W16(0xFFFB), W16(0x001D), W16(0x0019), W16(0x001A), W16(0x002E), W16(0x0022), W16(0x0011), W16(0x0005), + W16(0x00D4), W16(0x0039), W16(0x0060), W16(0x0018), W16(0xFFC9), W16(0xFFB3), W16(0xFFDF), W16(0x0057), + W16(0x00B5), W16(0x007C), W16(0x001F), W16(0xFF64), W16(0xFF9B), W16(0xFFF1), W16(0x0011), W16(0xFFD2), + W16(0x002A), W16(0x0029), W16(0x001F), W16(0x0000), W16(0x002A), W16(0x0017), W16(0x0019), W16(0xFFEF), + W16(0x0082), W16(0x0064), W16(0x0002), W16(0x0057), W16(0x0006), W16(0x002D), W16(0x005F), W16(0x006D), + W16(0xFFF1), W16(0x0035), W16(0x0017), W16(0x001B), W16(0xFFB5), W16(0xFF99), W16(0xFFBE), W16(0xFFD3), + W16(0xFFCA), W16(0xFFD1), W16(0xFFDB), W16(0xFFE2), W16(0xFFF8), W16(0xFFF8), W16(0x000B), W16(0x0000), + W16(0x005A), W16(0x0064), W16(0x0024), W16(0x0001), W16(0xFFCF), W16(0xFFA4), W16(0xFF80), W16(0xFFA0), + W16(0xFFE3), W16(0xFFEF), W16(0xFFC4), W16(0x0006), W16(0x0022), W16(0x0093), W16(0x004D), W16(0x006A), + W16(0x0065), W16(0x0030), W16(0x001C), W16(0x001A), W16(0x0029), W16(0x004A), W16(0x0064), W16(0x0061), + W16(0xFFD8), W16(0xFF96), W16(0x000D), W16(0x008E), W16(0xFFDB), W16(0xFFB8), W16(0xFF8A), W16(0x0013), + W16(0x004D), W16(0x0032), W16(0x002E), W16(0xFFBB), W16(0xFFD1), W16(0xFFF1), W16(0x0062), W16(0x001F), + W16(0x0025), W16(0x003D), W16(0x0036), W16(0x0033), W16(0x0091), W16(0x008C), W16(0x0064), W16(0x0041), + W16(0x0053), W16(0x0030), W16(0xFF71), W16(0x005F), W16(0x0086), W16(0xFFCC), W16(0xFF97), W16(0xFFE9), + W16(0xFFF9), W16(0xFFAC), W16(0xFFD8), W16(0x0017), W16(0xFFF9), W16(0x001C), W16(0x000B), W16(0x001F), + W16(0x005A), W16(0x0052), W16(0x0036), W16(0xFFF3), W16(0xFFE2), W16(0xFFCE), W16(0xFFC4), W16(0xFFBA), + W16(0x0019), W16(0x0030), W16(0x0044), W16(0xFFD3), W16(0x000C), W16(0xFFF5), W16(0x0011), W16(0x0030), + W16(0x0029), W16(0xFF5C), W16(0x002B), W16(0x0012), W16(0x0008), W16(0x0004), W16(0x001F), W16(0xFFFA), + W16(0xFFD8), W16(0xFFE9), W16(0xFFE1), W16(0xFFE0), W16(0xFFF7), W16(0xFFF2), W16(0xFFF2), W16(0xFFDC), + W16(0xFFA8), W16(0x00AA), W16(0xFFE6), W16(0x0022), W16(0x000F), W16(0xFFE9), W16(0x0015), W16(0x0043), + W16(0x004C), W16(0xFFE2), W16(0xFFCE), W16(0xFFF5), W16(0xFFEB), W16(0xFFAC), W16(0xFFCE), W16(0x0016), + W16(0x0044), W16(0x005C), W16(0x003F), W16(0x0020), W16(0x0008), W16(0xFFF9), W16(0xFFF1), W16(0xFFE4), + W16(0x0033), W16(0x0005), W16(0x0088), W16(0x0023), W16(0x004C), W16(0xFFBB), W16(0x0015), W16(0x0011), + W16(0x0024), W16(0x002F), W16(0x0019), W16(0x0004), W16(0xFFC8), W16(0xFFB5), W16(0xFFDC), W16(0x0006), + W16(0x0004), W16(0x0011), W16(0x000E), W16(0x0003), W16(0xFFE2), W16(0xFFB2), W16(0xFF99), W16(0xFF7B), + W16(0xFFEE), W16(0xFFF8), W16(0x0017), W16(0x002B), W16(0xFF2C), W16(0xFFA2), W16(0x0086), W16(0x00F1), + W16(0xFFD0), W16(0xFFDD), W16(0xFFD5), W16(0x0032), W16(0x002C), W16(0xFFD5), W16(0xFFFD), W16(0x002B), + W16(0xFFDD), W16(0xFFE7), W16(0xFFF7), W16(0x003C), W16(0x0011), W16(0x002D), W16(0x004D), W16(0x001F), + W16(0xFFCE), W16(0x001A), W16(0x0052), W16(0xFF95), W16(0xFFFC), W16(0xFFEC), W16(0x0007), W16(0x0013), + W16(0x0013), W16(0x000F), W16(0xFFD7), W16(0x0057), W16(0x0028), W16(0x0019), W16(0xFFCD), W16(0xFFD3), + W16(0xFFCC), W16(0xFFF5), W16(0x006F), W16(0x011E), W16(0x00C4), W16(0x0064), W16(0xFFE2), W16(0xFFA3), + W16(0x0053), W16(0xFFE8), W16(0xFFC4), W16(0x0022), W16(0xFF9D), W16(0x0004), W16(0xFFD3), W16(0x001C), + W16(0x0017), W16(0xFFF0), W16(0xFFF1), W16(0x0012), W16(0x0007), W16(0x001D), W16(0x0010), W16(0x0015), + W16(0x001B), W16(0x000B), W16(0xFFE1), W16(0xFFDA), W16(0xFFA6), W16(0xFF79), W16(0x0002), W16(0x020E), + W16(0x003B), W16(0x0003), W16(0xFFFB), W16(0xFFEC), W16(0xFFCA), W16(0xFFD2), W16(0xFFC8), W16(0xFFAB), + W16(0xFFE1), W16(0x0013), W16(0x0005), W16(0x0020), W16(0x0048), W16(0x005D), W16(0x00E1), W16(0xFFA6), + W16(0xFFAC), W16(0x0073), W16(0x008A), W16(0x005B), W16(0xFFDC), W16(0xFFD2), W16(0xFFEF), W16(0x001A), + W16(0x0035), W16(0x0050), W16(0x000C), W16(0x0047), W16(0x0049), W16(0x0038), W16(0x002E), W16(0x0074), + W16(0xFFE5), W16(0xFF9E), W16(0xFF99), W16(0xFFB6), W16(0xFFF1), W16(0x0004), W16(0x0028), W16(0x0004), + W16(0xFFEA), W16(0x0000), W16(0x0000), W16(0x001A), W16(0x0061), W16(0x0079), W16(0x008A), W16(0x00A0), + W16(0x00D0), W16(0xFFF3), W16(0x0055), W16(0x004B), W16(0x005A), W16(0x0016), W16(0xFFE5), W16(0xFFCC), + W16(0xFFC2), W16(0x0004), W16(0x0017), W16(0x0014), W16(0x0007), W16(0x0000), W16(0xFFFB), W16(0xFFF3), + W16(0xFFF9), W16(0xFFFD), W16(0xFFFD), W16(0x0015), W16(0x003F), W16(0x0045), W16(0x0053), W16(0x004B), + W16(0xFFE7), W16(0x005D), W16(0x0018), W16(0xFFE0), W16(0xFFF7), W16(0x0059), W16(0x003D), W16(0xFFEA), + W16(0xFEFA), W16(0xFFDF), W16(0xFFDD), W16(0x0009), W16(0x001F), W16(0x0016), W16(0x0034), W16(0x002E), + W16(0x0033), W16(0x003F), W16(0x004D), W16(0x002D), W16(0x0016), W16(0x0020), W16(0x0023), W16(0x0014), + W16(0xFFC7), W16(0xFFDE), W16(0x0056), W16(0xFFE8), W16(0x003A), W16(0x008F), W16(0xFFEB), W16(0xFFB7), + W16(0x0011), W16(0x0001), W16(0xFFD2), W16(0xFF83), W16(0xFF90), W16(0xFFEE), W16(0x0037), W16(0x0020), + W16(0x0059), W16(0x00BE), W16(0x00A3), W16(0x000F), W16(0xFF91), W16(0xFFB4), W16(0xFF97), W16(0xFF67), + W16(0xFFDF), W16(0x0046), W16(0xFF9A), W16(0xFFB2), W16(0xFFF0), W16(0x000E), W16(0xFF8F), W16(0xFFC7), + W16(0x0017), W16(0x005B), W16(0x0054), W16(0xFFFB), W16(0xFFC4), W16(0xFFD7), W16(0xFFE8), W16(0x0022), + W16(0x0043), W16(0x004C), W16(0x0066), W16(0x0074), W16(0x0092), W16(0x00B9), W16(0x00D5), W16(0x00BB), + W16(0x0071), W16(0x0148), W16(0x00DB), W16(0x00D4), W16(0x005C), W16(0x0031), W16(0x0012), W16(0x0025), + W16(0xFFE7), W16(0xFFEB), W16(0xFFD8), W16(0xFFC1), W16(0xFFE8), W16(0xFFED), W16(0xFFFA), W16(0x0001), + W16(0xFFFF), W16(0xFFF0), W16(0xFFE3), W16(0xFFE7), W16(0x0004), W16(0xFFFF), W16(0xFFF0), W16(0xFFF3), + W16(0x0055), W16(0x0136), W16(0xFFF5), W16(0xFFA3), W16(0xFFE5), W16(0xFFDC), W16(0xFFC6), W16(0xFFDD), + W16(0xFFDF), W16(0x0000), W16(0x0023), W16(0x0040), W16(0x0045), W16(0x0003), W16(0x0007), W16(0x000B), + W16(0x0002), W16(0x0004), W16(0xFFE8), W16(0xFFDF), W16(0xFFAD), W16(0xFFAA), W16(0xFF6E), W16(0xFF35), + W16(0x0017), W16(0x000B), W16(0x002B), W16(0x00DC), W16(0x00B1), W16(0xFFE2), W16(0xFFC0), W16(0x0001), + W16(0x0024), W16(0x0023), W16(0x0029), W16(0x006A), W16(0xFFED), W16(0xFFDF), W16(0xFFCA), W16(0xFF98), + W16(0xFFA4), W16(0xFFEA), W16(0x001A), W16(0x002C), W16(0x0003), W16(0x002A), W16(0x005F), W16(0x0077) +}; + +const Word16 cdk_37bits_4_fx[1536] = +{ + W16(0xFFF5), W16(0xFFA9), W16(0x000E), W16(0xFFC8), W16(0xFFCB), W16(0xFFB9), W16(0xFFD4), W16(0xFFCC), + W16(0xFFCB), W16(0xFFC8), W16(0xFFD3), W16(0x001A), W16(0x0049), W16(0x003A), W16(0x001F), W16(0x0044), + W16(0x0077), W16(0x004D), W16(0xFFEC), W16(0xFF84), W16(0xFFBC), W16(0xFFED), W16(0xFFE0), W16(0xFFE5), + W16(0x0033), W16(0xFFF7), W16(0xFFF9), W16(0x005E), W16(0x00B6), W16(0x003A), W16(0xFFEA), W16(0xFFA0), + W16(0xFFAB), W16(0xFFB9), W16(0xFFD3), W16(0xFFFB), W16(0xFFF2), W16(0xFFFA), W16(0x0010), W16(0x0029), + W16(0x002E), W16(0xFFD6), W16(0xFFCA), W16(0xFFBE), W16(0xFFC9), W16(0xFFCA), W16(0xFFD8), W16(0xFFD2), + W16(0xFF2B), W16(0x0024), W16(0xFFAF), W16(0x0020), W16(0x0068), W16(0x0038), W16(0x0015), W16(0x001B), + W16(0x0006), W16(0x0005), W16(0xFFF4), W16(0xFFCC), W16(0xFFD1), W16(0xFFF3), W16(0xFFDF), W16(0xFFBF), + W16(0x0003), W16(0xFFE3), W16(0x0001), W16(0x0018), W16(0x0021), W16(0x0010), W16(0xFFF4), W16(0xFFD9), + W16(0xFF6C), W16(0xFFD8), W16(0x0011), W16(0xFFB4), W16(0xFFD1), W16(0xFFBD), W16(0x0002), W16(0xFFDA), + W16(0x003A), W16(0x0033), W16(0x0038), W16(0x001D), W16(0x0030), W16(0x002A), W16(0xFFD3), W16(0xFFC7), + W16(0xFFDF), W16(0xFFC0), W16(0xFFDE), W16(0xFFD8), W16(0xFFB9), W16(0xFFCC), W16(0xFFDE), W16(0xFFFF), + W16(0xFFFA), W16(0xFFCE), W16(0xFFB7), W16(0xFFD7), W16(0x0031), W16(0x0017), W16(0xFFB0), W16(0x0018), + W16(0x003E), W16(0x002E), W16(0xFFE7), W16(0x0096), W16(0xFFCB), W16(0xFFC8), W16(0xFFDB), W16(0xFFB8), + W16(0xFFE0), W16(0xFFF6), W16(0xFFE9), W16(0xFFA6), W16(0xFFBD), W16(0xFFC1), W16(0xFFCC), W16(0xFFE0), + W16(0xFFF0), W16(0xFFDA), W16(0xFFD5), W16(0x000E), W16(0xFF85), W16(0x0112), W16(0xFFBB), W16(0xFFDF), + W16(0xFFF1), W16(0xFFF0), W16(0xFFED), W16(0xFFFB), W16(0xFFF6), W16(0x0009), W16(0x0010), W16(0xFFF1), + W16(0x0005), W16(0xFFE2), W16(0xFFDF), W16(0x0003), W16(0xFFBA), W16(0x0003), W16(0xFFFC), W16(0xFFD8), + W16(0xFFBE), W16(0x0070), W16(0xFF97), W16(0xFFC2), W16(0xFFE8), W16(0xFFF4), W16(0x001A), W16(0xFFE6), + W16(0xFFCD), W16(0xFFDA), W16(0xFFB6), W16(0x0020), W16(0x0020), W16(0x0035), W16(0xFFEC), W16(0x0029), + W16(0x003B), W16(0x0012), W16(0x0026), W16(0x002E), W16(0xFFF9), W16(0xFFE0), W16(0xFFD2), W16(0xFFBC), + W16(0x0042), W16(0xFF99), W16(0xFF90), W16(0x0013), W16(0x0007), W16(0xFFBE), W16(0x0007), W16(0x0016), + W16(0x0019), W16(0xFFC5), W16(0xFFF7), W16(0x001A), W16(0xFFC3), W16(0x002E), W16(0x002C), W16(0x0037), + W16(0xFFDC), W16(0xFFE5), W16(0x0001), W16(0x002A), W16(0x0022), W16(0x0042), W16(0x0043), W16(0x003B), + W16(0x002A), W16(0xFF9D), W16(0xFFD0), W16(0xFFFA), W16(0xFFC4), W16(0x000A), W16(0x0005), W16(0xFFD4), + W16(0x0036), W16(0x0036), W16(0xFFFB), W16(0xFFFC), W16(0xFFEE), W16(0xFFC3), W16(0xFF9A), W16(0x004E), + W16(0x005D), W16(0xFFF4), W16(0xFFEB), W16(0x0015), W16(0xFFF1), W16(0xFFD1), W16(0xFF99), W16(0xFF78), + W16(0x004F), W16(0xFFBD), W16(0xFFA8), W16(0x0053), W16(0x0038), W16(0xFFE5), W16(0xFFD2), W16(0x0026), + W16(0xFFE1), W16(0x0003), W16(0xFFD5), W16(0xFFAB), W16(0x0039), W16(0x0045), W16(0x0028), W16(0xFFF6), + W16(0xFFEB), W16(0xFFD6), W16(0xFFD5), W16(0xFFB9), W16(0xFFDA), W16(0xFFEE), W16(0x0000), W16(0x000E), + W16(0xFF7C), W16(0xFF75), W16(0xFFFF), W16(0xFFED), W16(0xFFFF), W16(0x002D), W16(0x001E), W16(0xFFB1), + W16(0x000A), W16(0x0015), W16(0xFFF0), W16(0xFFF8), W16(0xFFE5), W16(0x0015), W16(0x000E), W16(0x0012), + W16(0xFFE4), W16(0x0003), W16(0x000B), W16(0x000D), W16(0x0024), W16(0x003A), W16(0x0039), W16(0x0033), + W16(0xFFBA), W16(0xFFFD), W16(0xFFD0), W16(0xFFC4), W16(0xFFAE), W16(0x0020), W16(0x0024), W16(0x0050), + W16(0xFFFE), W16(0xFFF7), W16(0xFFE7), W16(0x000C), W16(0x0040), W16(0x001F), W16(0x001E), W16(0xFFD4), + W16(0xFF86), W16(0xFF87), W16(0xFF8B), W16(0xFFD1), W16(0x0024), W16(0x0036), W16(0xFFF4), W16(0xFFD6), + W16(0xFFFE), W16(0x001D), W16(0x0010), W16(0xFFDC), W16(0xFFD0), W16(0xFFF2), W16(0xFFE6), W16(0x0003), + W16(0xFFD5), W16(0xFFED), W16(0x006C), W16(0xFF8D), W16(0x000A), W16(0x0022), W16(0x0023), W16(0x001A), + W16(0x0030), W16(0xFFCA), W16(0xFFD4), W16(0xFFF2), W16(0x0004), W16(0xFFE5), W16(0xFFAB), W16(0xFF9B), + W16(0x0058), W16(0xFFD4), W16(0xFFA9), W16(0xFFAF), W16(0xFFDB), W16(0xFFF2), W16(0x003C), W16(0x008E), + W16(0x0007), W16(0xFFEE), W16(0xFFCE), W16(0xFFE0), W16(0xFFF7), W16(0xFFC4), W16(0xFFF3), W16(0xFFF7), + W16(0x0021), W16(0x0016), W16(0x0017), W16(0x000E), W16(0xFFF1), W16(0xFFF4), W16(0x0004), W16(0x0009), + W16(0xFFDA), W16(0xFFC0), W16(0x0048), W16(0x008F), W16(0x0007), W16(0xFF9C), W16(0xFFE3), W16(0xFFEF), + W16(0x0036), W16(0x0023), W16(0xFFF7), W16(0x000E), W16(0xFFEF), W16(0xFFF5), W16(0x0022), W16(0x0004), + W16(0x0022), W16(0xFFE7), W16(0xFFC5), W16(0xFFDC), W16(0xFFCE), W16(0xFFD7), W16(0xFFAE), W16(0xFF8F), + W16(0xFF94), W16(0x0053), W16(0xFFE9), W16(0xFFFD), W16(0x0002), W16(0x000E), W16(0xFFCA), W16(0xFFB0), + W16(0xFF9E), W16(0x0024), W16(0x0040), W16(0x0048), W16(0x0032), W16(0xFFBC), W16(0xFFFE), W16(0x0025), + W16(0x001A), W16(0xFFC6), W16(0xFFD6), W16(0xFFE9), W16(0xFFFB), W16(0x0012), W16(0x000C), W16(0x0005), + W16(0xFFB4), W16(0xFF9D), W16(0x001F), W16(0xFF74), W16(0xFFE3), W16(0xFFF2), W16(0xFFD9), W16(0x005A), + W16(0x0009), W16(0xFFDD), W16(0xFFEB), W16(0x0033), W16(0x0013), W16(0x0003), W16(0xFFD9), W16(0x0000), + W16(0x0004), W16(0x0000), W16(0x0008), W16(0x0045), W16(0x0022), W16(0x0038), W16(0x004F), W16(0x0036), + W16(0xFFC8), W16(0xFFE4), W16(0xFFD6), W16(0x0076), W16(0x0020), W16(0xFFEE), W16(0x004C), W16(0xFFFA), + W16(0xFFB2), W16(0x0008), W16(0x002E), W16(0x001B), W16(0x0002), W16(0xFFEC), W16(0xFFDD), W16(0xFFEF), + W16(0xFFEE), W16(0xFFD1), W16(0xFFC8), W16(0xFFC8), W16(0xFFBB), W16(0xFFE7), W16(0x0008), W16(0x0018), + W16(0xFFF5), W16(0xFFBA), W16(0x000D), W16(0x001B), W16(0x0045), W16(0x0013), W16(0x0001), W16(0x0010), + W16(0x000D), W16(0xFFF9), W16(0x0043), W16(0x000D), W16(0xFFCD), W16(0xFFF2), W16(0x007E), W16(0xFFAA), + W16(0xFF59), W16(0x00A5), W16(0x0018), W16(0xFFEA), W16(0xFFAE), W16(0xFFCB), W16(0xFFD4), W16(0x0013), + W16(0xFFEA), W16(0xFFA6), W16(0xFFB1), W16(0xFFA5), W16(0x0036), W16(0xFFB5), W16(0xFFB5), W16(0xFFD0), + W16(0xFFD2), W16(0x002D), W16(0x002C), W16(0x0013), W16(0xFFF5), W16(0x0013), W16(0x001C), W16(0x001F), + W16(0x000F), W16(0x001F), W16(0x001A), W16(0x002E), W16(0x001C), W16(0xFFF4), W16(0xFFBE), W16(0xFF9E), + W16(0x000C), W16(0x0037), W16(0xFFDB), W16(0x001C), W16(0x003D), W16(0xFF98), W16(0xFF81), W16(0x0097), + W16(0x005A), W16(0x0001), W16(0xFFDE), W16(0xFFCB), W16(0x0024), W16(0xFFFD), W16(0xFFED), W16(0x0011), + W16(0xFFF0), W16(0xFFD4), W16(0xFFCA), W16(0xFFD8), W16(0xFFD8), W16(0xFFE1), W16(0xFFE2), W16(0xFFD1), + W16(0xFFF7), W16(0xFFD4), W16(0xFFF8), W16(0xFFAD), W16(0x002B), W16(0x002B), W16(0xFFC9), W16(0xFFED), + W16(0xFFED), W16(0x0006), W16(0xFFEE), W16(0xFFCF), W16(0xFF8C), W16(0x0007), W16(0x0022), W16(0x0011), + W16(0x007F), W16(0x005A), W16(0x001C), W16(0xFFBB), W16(0xFF8E), W16(0xFFF7), W16(0x00B9), W16(0x00C3), + W16(0xFFDB), W16(0xFFCB), W16(0x0004), W16(0x0024), W16(0x0025), W16(0x0016), W16(0x0019), W16(0xFFEF), + W16(0xFFD2), W16(0xFFCA), W16(0xFFAD), W16(0xFFE6), W16(0xFFCB), W16(0x0005), W16(0x0060), W16(0x0032), + W16(0x002D), W16(0xFFE8), W16(0xFFC9), W16(0xFFF6), W16(0x0177), W16(0xFF8E), W16(0xFF7B), W16(0xFFCF), + W16(0xFFC6), W16(0x000A), W16(0xFFD3), W16(0xFFDB), W16(0xFFF4), W16(0xFFF3), W16(0x0034), W16(0xFFE2), + W16(0x0035), W16(0xFF72), W16(0x0019), W16(0xFFDE), W16(0x0013), W16(0x000A), W16(0x0003), W16(0x0017), + W16(0x002F), W16(0x0006), W16(0x0012), W16(0xFFFB), W16(0xFFF5), W16(0x000D), W16(0x0004), W16(0xFFF9), + W16(0x0026), W16(0x0005), W16(0xFFF2), W16(0xFF8B), W16(0xFFEE), W16(0x0010), W16(0xFFEB), W16(0xFFBC), + W16(0x002C), W16(0x0043), W16(0xFFA2), W16(0x0014), W16(0x002C), W16(0xFFF6), W16(0x0007), W16(0x0000), + W16(0x000F), W16(0xFFF8), W16(0xFFE7), W16(0xFFDB), W16(0xFFC9), W16(0xFFE2), W16(0xFFFB), W16(0x000B), + W16(0x001F), W16(0xFFF4), W16(0xFFFD), W16(0xFFDB), W16(0x0008), W16(0x0052), W16(0xFFBB), W16(0xFFC6), + W16(0x004A), W16(0xFFFB), W16(0x0049), W16(0xFFE0), W16(0x0059), W16(0xFFEA), W16(0xFFD3), W16(0xFFD0), + W16(0xFFD0), W16(0xFFD9), W16(0xFFEB), W16(0xFFD8), W16(0xFFF0), W16(0x0026), W16(0x0084), W16(0x00A7), + W16(0xFFE8), W16(0xFFCB), W16(0x001B), W16(0x0039), W16(0x0009), W16(0x0000), W16(0x0030), W16(0x0048), + W16(0x0046), W16(0x0061), W16(0x000B), W16(0xFFE0), W16(0xFFEB), W16(0xFFC4), W16(0xFFB2), W16(0xFFB2), + W16(0xFFDC), W16(0xFFEC), W16(0x0009), W16(0x0006), W16(0xFFFC), W16(0x0001), W16(0xFFFB), W16(0xFFF4), + W16(0x004E), W16(0x004A), W16(0x003E), W16(0xFFE0), W16(0xFFCC), W16(0x0035), W16(0x0024), W16(0x0024), + W16(0x0017), W16(0xFFB7), W16(0xFFED), W16(0x0048), W16(0xFFF9), W16(0x000B), W16(0xFFCF), W16(0xFFF1), + W16(0xFFF1), W16(0xFFD0), W16(0xFFBC), W16(0xFFAA), W16(0xFF97), W16(0xFFA4), W16(0xFFA7), W16(0xFFAD), + W16(0x001D), W16(0xFFD1), W16(0x0036), W16(0xFFD3), W16(0x0015), W16(0x0016), W16(0x0065), W16(0x000F), + W16(0x0006), W16(0xFFED), W16(0xFFD0), W16(0xFFB1), W16(0xFFDE), W16(0x0022), W16(0x001A), W16(0x0012), + W16(0xFFC0), W16(0xFFBB), W16(0xFFBD), W16(0xFFBB), W16(0xFFD0), W16(0xFFE3), W16(0xFFE2), W16(0xFFE5), + W16(0x001C), W16(0x003A), W16(0x0004), W16(0xFFCD), W16(0x003C), W16(0x004D), W16(0xFFD8), W16(0x0004), + W16(0x0040), W16(0xFFDC), W16(0xFFA3), W16(0xFFB7), W16(0x002F), W16(0x0017), W16(0xFFDC), W16(0xFFFA), + W16(0x0009), W16(0x0033), W16(0x001C), W16(0x0008), W16(0x0004), W16(0xFFE6), W16(0xFFB8), W16(0xFFA5), + W16(0xFFF0), W16(0xFFD4), W16(0x0042), W16(0xFFD4), W16(0xFFE8), W16(0x003F), W16(0x0064), W16(0xFFEB), + W16(0xFFA8), W16(0xFFE1), W16(0x0017), W16(0x000C), W16(0x0020), W16(0xFFB8), W16(0xFFD5), W16(0x000C), + W16(0x0025), W16(0x0051), W16(0x0016), W16(0xFFF3), W16(0xFFCF), W16(0xFFB7), W16(0xFFA6), W16(0xFF84), + W16(0xFFE6), W16(0xFFC8), W16(0x0024), W16(0xFFE1), W16(0x0044), W16(0xFF29), W16(0x0015), W16(0x0029), + W16(0x0004), W16(0x0023), W16(0xFFD5), W16(0xFFEA), W16(0x001B), W16(0x002B), W16(0xFFFB), W16(0x0011), + W16(0x001C), W16(0x0015), W16(0x0017), W16(0x000B), W16(0xFFF6), W16(0x0009), W16(0x0005), W16(0x0007), + W16(0x0060), W16(0xFFE5), W16(0x005F), W16(0xFFCF), W16(0xFFAF), W16(0xFFB2), W16(0xFFD3), W16(0x0002), + W16(0xFFFA), W16(0xFFD1), W16(0x001D), W16(0x001D), W16(0x0019), W16(0x0037), W16(0x002A), W16(0x0025), + W16(0x0027), W16(0x0029), W16(0x003C), W16(0x0049), W16(0x0035), W16(0x0027), W16(0xFFF9), W16(0xFFD0), + W16(0x0067), W16(0xFFDD), W16(0x000F), W16(0x0043), W16(0x0027), W16(0x002A), W16(0x0051), W16(0xFF79), + W16(0xFFDC), W16(0x002B), W16(0x0012), W16(0x0010), W16(0x001B), W16(0xFFFE), W16(0x0000), W16(0xFFCE), + W16(0xFFD6), W16(0x0002), W16(0x0028), W16(0x0030), W16(0xFFE4), W16(0xFFD8), W16(0xFFCD), W16(0xFFC8), + W16(0x003F), W16(0x0064), W16(0x000C), W16(0x0049), W16(0x0034), W16(0x0062), W16(0x006F), W16(0x004F), + W16(0x0004), W16(0xFFB8), W16(0x0006), W16(0xFFDD), W16(0xFFB8), W16(0xFFD3), W16(0xFFE4), W16(0xFFB6), + W16(0xFFE8), W16(0xFFFE), W16(0x0018), W16(0x004A), W16(0x0022), W16(0xFFFA), W16(0xFFF9), W16(0xFFFC), + W16(0xFFD7), W16(0x0066), W16(0xFFFD), W16(0x0013), W16(0x0023), W16(0xFFE5), W16(0xFFB5), W16(0xFFE5), + W16(0xFFFA), W16(0x000D), W16(0x0043), W16(0x0011), W16(0x003E), W16(0x0083), W16(0xFFF8), W16(0xFFC5), + W16(0xFF84), W16(0x000E), W16(0x0013), W16(0xFFBB), W16(0xFFA7), W16(0xFFB8), W16(0xFFDB), W16(0xFFDA), + W16(0xFFFD), W16(0x001C), W16(0xFFE9), W16(0x0005), W16(0x006D), W16(0xFFD2), W16(0x000C), W16(0x0002), + W16(0x003A), W16(0x002A), W16(0x0012), W16(0x0000), W16(0xFF71), W16(0xFFCA), W16(0xFFE6), W16(0x0009), + W16(0x0012), W16(0xFFEF), W16(0xFFFB), W16(0xFFF5), W16(0x000E), W16(0x001C), W16(0x0029), W16(0x0028), + W16(0x0036), W16(0x002B), W16(0xFFE3), W16(0x004D), W16(0xFF48), W16(0x0019), W16(0x0032), W16(0x0003), + W16(0x0066), W16(0x0003), W16(0xFFE0), W16(0xFFFC), W16(0x0004), W16(0xFFFA), W16(0x001A), W16(0x000B), + W16(0x0001), W16(0xFFFE), W16(0xFFFC), W16(0xFFE3), W16(0xFFE8), W16(0x0004), W16(0x0024), W16(0x0032), + W16(0x0021), W16(0x002B), W16(0xFF99), W16(0x000C), W16(0x0008), W16(0x004D), W16(0xFFD5), W16(0xFFC1), + W16(0xFFDE), W16(0xFFD3), W16(0x0001), W16(0xFFE1), W16(0xFFD3), W16(0x0018), W16(0x0044), W16(0x0024), + W16(0x0030), W16(0x0004), W16(0x000F), W16(0x0017), W16(0x002D), W16(0x0042), W16(0x004A), W16(0x0048), + W16(0xFFDF), W16(0x000D), W16(0x000A), W16(0xFFF4), W16(0xFFF0), W16(0xFFCC), W16(0xFFE2), W16(0xFFF4), + W16(0xFFF3), W16(0x0009), W16(0x0024), W16(0x0054), W16(0x0004), W16(0xFFEB), W16(0x0019), W16(0x0092), + W16(0xFF5F), W16(0xFFFD), W16(0x0022), W16(0x001E), W16(0xFFD5), W16(0xFF9D), W16(0xFFB6), W16(0x002E), + W16(0xFFC7), W16(0xFFCB), W16(0xFF9E), W16(0x0036), W16(0xFF8C), W16(0xFFCD), W16(0xFFDC), W16(0xFFF8), + W16(0x0010), W16(0x001B), W16(0x0019), W16(0x0004), W16(0x0035), W16(0x0018), W16(0xFFFD), W16(0x0010), + W16(0x0032), W16(0x004E), W16(0x0035), W16(0x0037), W16(0x000A), W16(0xFFF5), W16(0xFFE6), W16(0xFFE5), + W16(0x002D), W16(0xFFFA), W16(0xFFF7), W16(0xFFF0), W16(0xFFC6), W16(0xFFCA), W16(0xFFEA), W16(0x001E), + W16(0x0041), W16(0x002C), W16(0xFFF9), W16(0xFFEF), W16(0xFFBD), W16(0x00C2), W16(0x0012), W16(0xFF8E), + W16(0xFFF4), W16(0xFFF1), W16(0x004F), W16(0x0026), W16(0xFFF2), W16(0xFFD6), W16(0xFFAE), W16(0xFFA5), + W16(0xFFBD), W16(0xFFEB), W16(0x0056), W16(0xFFA9), W16(0xFF78), W16(0x0020), W16(0x005D), W16(0xFFE9), + W16(0xFFFA), W16(0x0054), W16(0x0026), W16(0xFFFB), W16(0xFFAC), W16(0xFFE8), W16(0xFFF6), W16(0xFFEC), + W16(0x003E), W16(0x0025), W16(0x0045), W16(0x0027), W16(0x0046), W16(0x0031), W16(0x001D), W16(0xFFF3), + W16(0xFFDD), W16(0x0016), W16(0xFFE8), W16(0x003B), W16(0x0004), W16(0x0053), W16(0x0024), W16(0xFFFA), + W16(0xFFDA), W16(0x0014), W16(0xFF6A), W16(0x0062), W16(0x0006), W16(0xFFE2), W16(0x0003), W16(0xFFF4), + W16(0xFFF2), W16(0xFFF7), W16(0xFFFC), W16(0x0012), W16(0x0019), W16(0x0019), W16(0x000D), W16(0x000E), + W16(0x0049), W16(0xFFF4), W16(0x0028), W16(0x000C), W16(0xFFC1), W16(0xFFDF), W16(0x0025), W16(0x003D), + W16(0xFF8A), W16(0x0048), W16(0x001A), W16(0xFFD5), W16(0x003B), W16(0x0055), W16(0x000C), W16(0xFFB4), + W16(0xFFEF), W16(0xFFFF), W16(0x0007), W16(0x0026), W16(0x001D), W16(0x0025), W16(0x0029), W16(0x0030), + W16(0x0059), W16(0x0057), W16(0xFFF3), W16(0xFFE7), W16(0xFFE6), W16(0xFF6D), W16(0x0080), W16(0xFFD4), + W16(0x002A), W16(0x0027), W16(0xFFE6), W16(0xFF9C), W16(0xFFC5), W16(0x0009), W16(0x0023), W16(0x004C), + W16(0x0048), W16(0x004F), W16(0xFFFB), W16(0xFFF3), W16(0x0016), W16(0x0001), W16(0xFFED), W16(0xFFEC), + W16(0xFF76), W16(0x0021), W16(0x009C), W16(0x0018), W16(0xFFD7), W16(0x002C), W16(0xFFD7), W16(0xFFF4), + W16(0x0025), W16(0xFFD1), W16(0xFFC9), W16(0xFFFB), W16(0xFFF5), W16(0x0005), W16(0x001D), W16(0x0035), + W16(0x002A), W16(0xFFEB), W16(0xFFE6), W16(0xFFD3), W16(0xFFDF), W16(0xFFFB), W16(0xFFFB), W16(0xFFEE), + W16(0x000B), W16(0x0024), W16(0x000C), W16(0x0024), W16(0xFFDB), W16(0xFFEC), W16(0xFFF5), W16(0x0009), + W16(0xFFFE), W16(0x0015), W16(0x0034), W16(0x0058), W16(0xFFF7), W16(0xFF52), W16(0x0058), W16(0x0023), + W16(0xFFD8), W16(0xFFD4), W16(0xFFE6), W16(0xFFFB), W16(0x0000), W16(0x0029), W16(0x003E), W16(0x0041), + W16(0xFFF2), W16(0xFFBA), W16(0xFFF7), W16(0x000A), W16(0x002A), W16(0x004C), W16(0xFFC4), W16(0x0042), + W16(0xFFAC), W16(0xFF6C), W16(0x003B), W16(0x0025), W16(0x0005), W16(0xFFE3), W16(0x000B), W16(0x000F), + W16(0x000C), W16(0x0028), W16(0x0021), W16(0x0015), W16(0xFFFF), W16(0xFFFE), W16(0x0006), W16(0x000B), + W16(0x0005), W16(0x006C), W16(0x0018), W16(0x0068), W16(0x0027), W16(0xFFA0), W16(0x0025), W16(0x0003), + W16(0xFFE8), W16(0xFFD7), W16(0xFFE4), W16(0x0026), W16(0x000D), W16(0xFFFF), W16(0x001D), W16(0x001F), + W16(0x0000), W16(0xFFEC), W16(0xFFF5), W16(0x0017), W16(0x0023), W16(0x003C), W16(0x0041), W16(0x0032), + W16(0xFFB5), W16(0x0068), W16(0xFFE8), W16(0x0006), W16(0xFFB3), W16(0x0002), W16(0xFFF4), W16(0x005C), + W16(0xFFE6), W16(0x0011), W16(0xFFE6), W16(0xFFCA), W16(0xFFA2), W16(0x0023), W16(0x004C), W16(0x0038), + W16(0x000B), W16(0x0011), W16(0x0015), W16(0xFFEA), W16(0xFFEC), W16(0xFFFB), W16(0x000A), W16(0x0003), + W16(0xFFFF), W16(0x0040), W16(0xFF79), W16(0xFFC5), W16(0x002C), W16(0xFFCB), W16(0x0007), W16(0xFFF1), + W16(0x0030), W16(0x003E), W16(0x001F), W16(0xFFE1), W16(0x0020), W16(0x0013), W16(0xFFCE), W16(0xFFD6), + W16(0xFFCC), W16(0xFFFF), W16(0x0027), W16(0x004B), W16(0x004B), W16(0x0045), W16(0x0038), W16(0x0036), + W16(0x0008), W16(0xFFF8), W16(0x0026), W16(0xFFFE), W16(0x000F), W16(0xFFD1), W16(0xFFE3), W16(0x0039), + W16(0xFFF3), W16(0xFFCB), W16(0xFFDE), W16(0x000E), W16(0x0102), W16(0xFFC2), W16(0xFF93), W16(0xFFF9), + W16(0x000C), W16(0xFFD7), W16(0xFFF4), W16(0x000F), W16(0xFFFD), W16(0x0022), W16(0x0020), W16(0x0027), + W16(0x002B), W16(0x0034), W16(0x0006), W16(0x0022), W16(0x0018), W16(0x0022), W16(0xFFE0), W16(0xFFFC), + W16(0x0037), W16(0x001E), W16(0x003F), W16(0xFFCC), W16(0xFFE7), W16(0xFFC3), W16(0xFFA8), W16(0xFFE4), + W16(0x0054), W16(0x006D), W16(0x0025), W16(0xFF9E), W16(0xFFBD), W16(0xFFCB), W16(0xFFE6), W16(0x001A), + W16(0xFFD6), W16(0x0080), W16(0x0074), W16(0xFFA3), W16(0x0034), W16(0xFFFA), W16(0x0010), W16(0xFFBF), + W16(0xFFC1), W16(0x0009), W16(0x0006), W16(0xFFE6), W16(0x0000), W16(0x0035), W16(0x003F), W16(0xFFF7), + W16(0xFFE3), W16(0xFFCF), W16(0x0000), W16(0x0019), W16(0x003B), W16(0x0043), W16(0x003F), W16(0x0047), + W16(0x0028), W16(0xFFCD), W16(0x000C), W16(0x0026), W16(0x0052), W16(0xFFF9), W16(0x003A), W16(0xFF99), + W16(0x0071), W16(0xFFAD), W16(0xFFFB), W16(0x001F), W16(0x000C), W16(0xFFF0), W16(0xFFDB), W16(0xFFFF), + W16(0xFFD5), W16(0x0023), W16(0x0022), W16(0x0032), W16(0x0048), W16(0x0025), W16(0xFFFE), W16(0xFFDB), + W16(0x009C), W16(0x0007), W16(0x0022), W16(0x0002), W16(0xFFB7), W16(0xFFAE), W16(0x0011), W16(0xFFE0), + W16(0x0000), W16(0x003B), W16(0x0027), W16(0x004D), W16(0x003A), W16(0xFFE2), W16(0xFFF6), W16(0x0006), + W16(0xFFE3), W16(0xFFCE), W16(0xFFCD), W16(0xFFD5), W16(0xFFFC), W16(0x0000), W16(0xFFF5), W16(0xFFF5), + W16(0x0040), W16(0xFFDE), W16(0x0050), W16(0x0018), W16(0xFFFB), W16(0x0041), W16(0xFF88), W16(0x000F), + W16(0xFFD7), W16(0x006B), W16(0x0038), W16(0xFFFC), W16(0xFFD8), W16(0xFFE9), W16(0xFFEC), W16(0x0007), + W16(0x0002), W16(0x000E), W16(0x0007), W16(0x0035), W16(0x002B), W16(0x0028), W16(0x0018), W16(0xFFFF), + W16(0xFFD6), W16(0x00B3), W16(0x0087), W16(0x001B), W16(0xFFBD), W16(0x001E), W16(0x0073), W16(0x0071), + W16(0x004B), W16(0x0052), W16(0x004D), W16(0xFFCE), W16(0xFFC2), W16(0xFFC6), W16(0xFFCB), W16(0xFF92), + W16(0xFFA3), W16(0xFF9F), W16(0xFFBA), W16(0x0011), W16(0xFFCF), W16(0xFFD7), W16(0x0018), W16(0x0072), + W16(0x0075), W16(0x0016), W16(0xFFD3), W16(0xFFA9), W16(0x0048), W16(0x001E), W16(0x0019), W16(0x000F), + W16(0xFF97), W16(0xFFF0), W16(0x0025), W16(0x003D), W16(0x0003), W16(0xFFE5), W16(0xFFE9), W16(0xFFEB), + W16(0xFFCD), W16(0xFFEA), W16(0xFFF0), W16(0x000E), W16(0x0018), W16(0x002A), W16(0x0030), W16(0x003C), + W16(0x0041), W16(0xFF90), W16(0x0039), W16(0x0015), W16(0x0006), W16(0x0039), W16(0x004B), W16(0x001E), + W16(0xFFFA), W16(0xFFC3), W16(0x0001), W16(0xFFBD), W16(0xFFF5), W16(0xFFC3), W16(0x0001), W16(0xFFFD), + W16(0x0026), W16(0xFFF4), W16(0x0006), W16(0x0069), W16(0x0083), W16(0x0080), W16(0x0077), W16(0x006E), + W16(0x00B3), W16(0x003E), W16(0x0007), W16(0x0037), W16(0x0025), W16(0xFFFD), W16(0xFFA5), W16(0xFFF6), + W16(0x0000), W16(0xFFF8), W16(0xFFED), W16(0x0003), W16(0x001A), W16(0xFFF7), W16(0x001B), W16(0x0030), + W16(0x0001), W16(0x002D), W16(0x0032), W16(0x0016), W16(0x000B), W16(0x0020), W16(0x0017), W16(0x0004), + W16(0xFFED), W16(0x004D), W16(0x0067), W16(0x0053), W16(0xFFD0), W16(0x0003), W16(0xFFC8), W16(0xFFC3), + W16(0xFFF4), W16(0x0001), W16(0x0032), W16(0x005D), W16(0xFFDF), W16(0x0027), W16(0xFFF2), W16(0xFFFB), + W16(0x002B), W16(0x0048), W16(0x002F), W16(0x0019), W16(0x001B), W16(0x0027), W16(0x001B), W16(0xFFFF), + W16(0xFFB9), W16(0xFFFC), W16(0x0003), W16(0x0054), W16(0x006D), W16(0x0003), W16(0xFFCF), W16(0x000B), + W16(0xFFD1), W16(0x000B), W16(0xFFD6), W16(0xFFDC), W16(0x000B), W16(0x0013), W16(0xFFCB), W16(0x0015), + W16(0x0029), W16(0x0046), W16(0x0084), W16(0x0071), W16(0x004F), W16(0x0045), W16(0x0040), W16(0x0038) +}; + +const Word16 cdk_37bits_5_fx[1536] = +{ + W16(0xFFF5), W16(0x0024), W16(0xFFA1), W16(0xFFDD), W16(0x0022), W16(0x004B), W16(0x003F), W16(0x0001), + W16(0x0040), W16(0xFFF4), W16(0xFFEE), W16(0xFFE4), W16(0xFFA4), W16(0xFFD7), W16(0xFFEA), W16(0xFFFD), + W16(0xFFEB), W16(0xFFDF), W16(0xFFDA), W16(0xFFFA), W16(0xFFFC), W16(0xFFF7), W16(0xFFFA), W16(0x0003), + W16(0x0015), W16(0xFFF0), W16(0xFFF2), W16(0xFFC0), W16(0x002F), W16(0x0002), W16(0xFFCA), W16(0xFFCD), + W16(0xFFF3), W16(0xFFFE), W16(0xFFCF), W16(0xFFF4), W16(0x0017), W16(0x0047), W16(0xFFDD), W16(0xFFFD), + W16(0x004D), W16(0xFF98), W16(0xFFBF), W16(0x0005), W16(0x0041), W16(0x0029), W16(0xFFF9), W16(0x0001), + W16(0xFFA6), W16(0xFFB8), W16(0xFFE4), W16(0x0009), W16(0xFFE0), W16(0x0031), W16(0x0005), W16(0xFFFD), + W16(0xFFAC), W16(0xFFF1), W16(0x000B), W16(0xFFFB), W16(0xFFDB), W16(0x000F), W16(0x0062), W16(0x0000), + W16(0xFFFE), W16(0x0018), W16(0x0000), W16(0xFFDB), W16(0xFFE6), W16(0xFFD1), W16(0xFFCF), W16(0xFFE5), + W16(0xFFE6), W16(0x0002), W16(0xFFAF), W16(0x003F), W16(0xFFF2), W16(0xFFD9), W16(0x0036), W16(0xFFF1), + W16(0x0048), W16(0xFFE7), W16(0xFFD8), W16(0x0002), W16(0x003D), W16(0x0002), W16(0x0005), W16(0x0006), + W16(0xFFBD), W16(0xFFCF), W16(0xFFCB), W16(0x0003), W16(0xFFFB), W16(0xFFF2), W16(0xFFD9), W16(0xFFDF), + W16(0xFFF8), W16(0xFFBF), W16(0x0001), W16(0xFFBB), W16(0xFFEA), W16(0xFFE6), W16(0xFFC8), W16(0x0028), + W16(0x0014), W16(0x0041), W16(0x0014), W16(0x0018), W16(0x0006), W16(0x0007), W16(0x0003), W16(0xFFF2), + W16(0xFFBF), W16(0xFFB0), W16(0xFFDA), W16(0xFFCC), W16(0xFFD4), W16(0xFFE4), W16(0xFFCD), W16(0xFFBE), + W16(0xFFA2), W16(0xFFA8), W16(0xFFF8), W16(0x0055), W16(0x002D), W16(0xFFEA), W16(0xFFE6), W16(0x0000), + W16(0x0005), W16(0xFFEF), W16(0x002D), W16(0x002F), W16(0x003D), W16(0xFFE0), W16(0xFFCF), W16(0xFFE2), + W16(0xFFE5), W16(0xFFEB), W16(0xFFEE), W16(0x0018), W16(0x000B), W16(0x0001), W16(0xFFF6), W16(0x0015), + W16(0x001F), W16(0xFFBA), W16(0xFFEA), W16(0x0002), W16(0xFFDC), W16(0xFFFB), W16(0xFFF0), W16(0xFFE6), + W16(0x005A), W16(0x0013), W16(0xFFF6), W16(0xFFCA), W16(0xFFF9), W16(0xFFB6), W16(0x0060), W16(0x0006), + W16(0x0012), W16(0x0046), W16(0x001D), W16(0x000C), W16(0x0022), W16(0x0022), W16(0x001B), W16(0x0012), + W16(0xFFB2), W16(0x0021), W16(0x000B), W16(0xFFDB), W16(0xFFE3), W16(0x0023), W16(0xFFCE), W16(0xFF8C), + W16(0x0058), W16(0xFFF7), W16(0x0026), W16(0xFFFD), W16(0x0016), W16(0x000D), W16(0x0008), W16(0xFFF0), + W16(0x0015), W16(0x001E), W16(0xFFF6), W16(0xFFF0), W16(0xFFD7), W16(0xFFD2), W16(0xFFD7), W16(0xFFEA), + W16(0xFFD8), W16(0x0006), W16(0xFF77), W16(0x0047), W16(0x0021), W16(0xFFEA), W16(0xFFC7), W16(0x0036), + W16(0xFFE1), W16(0x0032), W16(0xFFDD), W16(0xFFF5), W16(0xFFEA), W16(0xFFAD), W16(0x0028), W16(0x0034), + W16(0x001F), W16(0xFFEB), W16(0x0002), W16(0xFFD9), W16(0xFFEC), W16(0xFFE9), W16(0xFFEA), W16(0xFFE7), + W16(0x0021), W16(0xFFFC), W16(0xFFCD), W16(0xFFD7), W16(0x000D), W16(0xFFE4), W16(0x0025), W16(0xFFEC), + W16(0xFFF0), W16(0xFFF2), W16(0x002B), W16(0xFFE5), W16(0x0040), W16(0xFFB0), W16(0x001C), W16(0xFFE5), + W16(0x001C), W16(0xFFF5), W16(0xFFBD), W16(0xFFD3), W16(0xFFB4), W16(0xFFC8), W16(0xFFDC), W16(0x0000), + W16(0x0029), W16(0xFFFC), W16(0xFFE5), W16(0xFFE3), W16(0xFFAB), W16(0xFFDA), W16(0x0017), W16(0xFFD4), + W16(0xFFE6), W16(0xFFFF), W16(0x0032), W16(0xFFF7), W16(0xFFE3), W16(0x002C), W16(0x0042), W16(0x004A), + W16(0xFFE6), W16(0xFFEE), W16(0xFFE5), W16(0x0008), W16(0xFFDC), W16(0xFFEC), W16(0xFFF6), W16(0x000B), + W16(0xFFB6), W16(0x002A), W16(0x0031), W16(0x0011), W16(0x004F), W16(0xFFCA), W16(0xFFEA), W16(0x002A), + W16(0xFFF7), W16(0xFFEF), W16(0x000D), W16(0xFFBB), W16(0x0023), W16(0xFFCC), W16(0x0048), W16(0xFFF2), + W16(0xFFFD), W16(0xFFFD), W16(0xFFFC), W16(0x0001), W16(0x002D), W16(0x0004), W16(0xFFD0), W16(0xFFA2), + W16(0xFFD7), W16(0xFFE2), W16(0x0041), W16(0x000A), W16(0xFFE5), W16(0xFFEB), W16(0x002B), W16(0x001F), + W16(0x0043), W16(0xFFBE), W16(0x0044), W16(0xFFCF), W16(0xFFD9), W16(0x001C), W16(0x001E), W16(0xFFDE), + W16(0xFFE0), W16(0xFFD3), W16(0xFFD0), W16(0xFFE6), W16(0xFFF0), W16(0xFFF7), W16(0xFFED), W16(0x0002), + W16(0xFFD7), W16(0xFFF8), W16(0xFFEB), W16(0x0002), W16(0x0046), W16(0xFFEE), W16(0xFFF7), W16(0xFFD8), + W16(0x001B), W16(0xFFB8), W16(0xFFBA), W16(0xFFCE), W16(0x000B), W16(0x0042), W16(0x000C), W16(0x003A), + W16(0x000F), W16(0xFFFB), W16(0xFFF2), W16(0xFFE0), W16(0xFFBC), W16(0xFFBE), W16(0xFFF1), W16(0x0023), + W16(0xFFE4), W16(0xFFE6), W16(0xFFEA), W16(0xFFA8), W16(0xFFC1), W16(0x0016), W16(0x0054), W16(0x0016), + W16(0x001B), W16(0xFFFD), W16(0xFFE2), W16(0xFFD0), W16(0x0008), W16(0x002A), W16(0xFFE8), W16(0xFFC0), + W16(0x0019), W16(0xFFFE), W16(0x0021), W16(0x0013), W16(0x000B), W16(0xFFF8), W16(0xFFFE), W16(0x000C), + W16(0xFFA9), W16(0x0036), W16(0x0016), W16(0xFFE9), W16(0xFFAB), W16(0x000E), W16(0x0042), W16(0x0006), + W16(0xFFD0), W16(0x0009), W16(0xFFE3), W16(0xFFE0), W16(0x0025), W16(0x0015), W16(0x0011), W16(0x0027), + W16(0xFFF2), W16(0xFFD4), W16(0xFFB1), W16(0xFFC6), W16(0x001F), W16(0x0038), W16(0x002B), W16(0x0029), + W16(0xFFF0), W16(0x0025), W16(0xFFED), W16(0xFF89), W16(0x0014), W16(0x0034), W16(0xFFE5), W16(0xFFF0), + W16(0xFFE6), W16(0x000B), W16(0x0066), W16(0x0016), W16(0xFFF3), W16(0xFFCC), W16(0xFFD6), W16(0xFFEA), + W16(0xFFF8), W16(0x0007), W16(0x0015), W16(0x0013), W16(0x000A), W16(0x0020), W16(0x001A), W16(0x000E), + W16(0xFFD8), W16(0x000C), W16(0xFFF2), W16(0x0001), W16(0xFFD0), W16(0x0006), W16(0x0018), W16(0x0010), + W16(0xFFED), W16(0x0000), W16(0x001A), W16(0xFFFE), W16(0xFFFD), W16(0x003E), W16(0xFF67), W16(0x004E), + W16(0x000B), W16(0x0015), W16(0xFFEC), W16(0xFFE8), W16(0xFFDE), W16(0xFFF3), W16(0xFFFB), W16(0x0033), + W16(0xFFC6), W16(0xFFF1), W16(0xFFDC), W16(0xFFCA), W16(0x0016), W16(0xFFE7), W16(0x0029), W16(0xFFF6), + W16(0xFFF9), W16(0xFFE2), W16(0xFFCD), W16(0x002A), W16(0xFFE5), W16(0xFFC4), W16(0x0006), W16(0x0027), + W16(0x003B), W16(0x0035), W16(0x001C), W16(0x001C), W16(0x0015), W16(0x0025), W16(0x001F), W16(0x0031), + W16(0x0020), W16(0xFFFB), W16(0x0023), W16(0x0015), W16(0xFFF8), W16(0xFFFD), W16(0xFFEE), W16(0x003F), + W16(0x0055), W16(0x0006), W16(0x001B), W16(0xFFF7), W16(0xFFFB), W16(0xFFED), W16(0xFFE4), W16(0xFFEB), + W16(0xFFBA), W16(0x0029), W16(0x005B), W16(0x0063), W16(0xFFA2), W16(0xFFA6), W16(0xFF9D), W16(0xFFBD), + W16(0xFFCC), W16(0xFFB9), W16(0x0034), W16(0x0011), W16(0x000E), W16(0xFFFD), W16(0x0048), W16(0xFFE9), + W16(0xFFD8), W16(0x0071), W16(0xFFAB), W16(0x0013), W16(0xFFEC), W16(0xFFD2), W16(0xFFD3), W16(0xFFF8), + W16(0x0034), W16(0xFFFE), W16(0xFFD9), W16(0xFFCC), W16(0xFFE6), W16(0xFFF1), W16(0xFFF1), W16(0x0004), + W16(0xFFFD), W16(0x0000), W16(0xFFCA), W16(0xFF9C), W16(0xFFE5), W16(0xFFFD), W16(0xFFF9), W16(0x0025), + W16(0x0023), W16(0xFFBA), W16(0xFFDC), W16(0x003F), W16(0x0039), W16(0xFFE2), W16(0x0027), W16(0xFFEA), + W16(0xFFDC), W16(0x0035), W16(0x0008), W16(0xFFF6), W16(0x0012), W16(0xFFE2), W16(0xFFAD), W16(0xFF94), + W16(0x002B), W16(0xFFE5), W16(0x0015), W16(0x001B), W16(0xFF94), W16(0xFFE8), W16(0xFFCE), W16(0x0023), + W16(0x002A), W16(0xFFF6), W16(0x0023), W16(0xFFD7), W16(0x0025), W16(0x0004), W16(0xFFE2), W16(0x0020), + W16(0x004F), W16(0x0026), W16(0xFFC5), W16(0xFFCE), W16(0xFFF7), W16(0x0012), W16(0x0018), W16(0x0019), + W16(0xFFFE), W16(0xFFCA), W16(0xFFFC), W16(0x0002), W16(0x0006), W16(0x002A), W16(0xFF55), W16(0x0006), + W16(0xFFEE), W16(0x0017), W16(0xFFE3), W16(0x0005), W16(0x0036), W16(0x003E), W16(0x000C), W16(0x000A), + W16(0xFFFD), W16(0x0017), W16(0x0022), W16(0x0013), W16(0xFFFF), W16(0xFFF6), W16(0xFFFE), W16(0x001A), + W16(0x0009), W16(0xFFEB), W16(0xFFE5), W16(0x0000), W16(0x0032), W16(0x0058), W16(0x0009), W16(0x0039), + W16(0xFFD0), W16(0xFFF7), W16(0xFFD8), W16(0xFFF0), W16(0x0014), W16(0xFFDC), W16(0xFFE1), W16(0x0009), + W16(0xFFCB), W16(0xFFD9), W16(0x0002), W16(0x000C), W16(0xFFF9), W16(0x000F), W16(0x003F), W16(0x0062), + W16(0x0013), W16(0x002F), W16(0x0028), W16(0xFFE9), W16(0x0030), W16(0x000D), W16(0xFFA7), W16(0x0000), + W16(0x000A), W16(0xFFED), W16(0xFFEB), W16(0x003F), W16(0xFFEE), W16(0xFFEB), W16(0x0014), W16(0x0029), + W16(0xFFE5), W16(0xFFF0), W16(0xFFB0), W16(0xFFCB), W16(0xFFD5), W16(0x0014), W16(0x0034), W16(0x003B), + W16(0xFFE9), W16(0x0059), W16(0xFFBC), W16(0xFFCD), W16(0x000C), W16(0xFFE6), W16(0x001F), W16(0x0013), + W16(0xFFE5), W16(0x0030), W16(0xFFFD), W16(0x0025), W16(0xFFD9), W16(0x0011), W16(0x002C), W16(0xFFAC), + W16(0xFFE2), W16(0x0014), W16(0xFFF0), W16(0xFFDA), W16(0xFFED), W16(0xFFFE), W16(0xFFFC), W16(0x0006), + W16(0xFFDE), W16(0xFFF0), W16(0xFFFB), W16(0x0001), W16(0x001D), W16(0xFFB6), W16(0xFFEF), W16(0x00CD), + W16(0xFF91), W16(0xFFD0), W16(0xFFCD), W16(0x0017), W16(0x0006), W16(0x0026), W16(0x0011), W16(0xFFF3), + W16(0xFFFD), W16(0x0005), W16(0xFFD7), W16(0xFFF7), W16(0xFFE7), W16(0xFFC3), W16(0xFFDB), W16(0xFFD3), + W16(0x0003), W16(0xFFE7), W16(0xFFD9), W16(0x0010), W16(0x0049), W16(0xFFF3), W16(0xFFFD), W16(0xFFB1), + W16(0x000B), W16(0x005E), W16(0x0030), W16(0xFF9D), W16(0xFFE3), W16(0x000F), W16(0xFFFB), W16(0xFFF3), + W16(0x0001), W16(0xFFFC), W16(0xFFF4), W16(0xFFEC), W16(0xFFEE), W16(0xFFF5), W16(0xFFEB), W16(0xFFFE), + W16(0x0049), W16(0x001E), W16(0x0011), W16(0xFFDF), W16(0xFFD5), W16(0x002C), W16(0xFFFD), W16(0xFFF8), + W16(0x0007), W16(0xFFBC), W16(0xFFD4), W16(0x0013), W16(0x0045), W16(0xFFDE), W16(0xFFFE), W16(0x0049), + W16(0xFFF6), W16(0xFFDC), W16(0xFFE6), W16(0x0000), W16(0xFFFA), W16(0xFFEF), W16(0xFFE3), W16(0xFFF1), + W16(0xFFE0), W16(0x000A), W16(0x0019), W16(0x0006), W16(0xFFF3), W16(0xFFFA), W16(0x000B), W16(0x002D), + W16(0x000E), W16(0x002A), W16(0x0015), W16(0xFFFC), W16(0xFFE9), W16(0xFFC0), W16(0x0034), W16(0xFFDF), + W16(0xFFD7), W16(0xFFF3), W16(0x0017), W16(0x000F), W16(0xFFAC), W16(0xFFEF), W16(0x0101), W16(0xFF60), + W16(0xFFE0), W16(0xFFBD), W16(0x0040), W16(0xFFEB), W16(0xFFFF), W16(0xFFE2), W16(0xFFD5), W16(0xFFE1), + W16(0xFFFA), W16(0xFFF7), W16(0xFFF4), W16(0x0003), W16(0xFFFE), W16(0xFFCA), W16(0x0004), W16(0x0097), + W16(0x001E), W16(0xFF9B), W16(0xFFE6), W16(0x0093), W16(0x0033), W16(0x006E), W16(0xFFFB), W16(0xFFBF), + W16(0x0036), W16(0xFFFE), W16(0x002B), W16(0x0004), W16(0x001A), W16(0x005D), W16(0x0027), W16(0xFFF2), + W16(0x0013), W16(0x0013), W16(0x000F), W16(0x0000), W16(0xFFD8), W16(0xFFB8), W16(0xFFD8), W16(0x0002), + W16(0xFFD2), W16(0x0004), W16(0xFFF1), W16(0xFFD9), W16(0x002C), W16(0x006B), W16(0x0016), W16(0xFF7E), + W16(0xFFFE), W16(0xFFFE), W16(0xFFEB), W16(0x000B), W16(0x000F), W16(0x006C), W16(0x000A), W16(0xFF8A), + W16(0xFFBB), W16(0xFFF3), W16(0xFFE8), W16(0xFFDF), W16(0x0055), W16(0x0037), W16(0xFFE0), W16(0xFFE8), + W16(0x0028), W16(0x000A), W16(0x0005), W16(0xFFDF), W16(0x001B), W16(0x0016), W16(0x0015), W16(0x001D), + W16(0xFFFC), W16(0xFFBA), W16(0x0016), W16(0xFFE0), W16(0x001E), W16(0xFFD4), W16(0xFFF6), W16(0xFFE0), + W16(0xFFA2), W16(0xFFF7), W16(0x0018), W16(0x0012), W16(0x0056), W16(0x0032), W16(0x001A), W16(0xFFEB), + W16(0xFFE7), W16(0x0021), W16(0xFFFE), W16(0x001F), W16(0x000E), W16(0x0016), W16(0x0007), W16(0x0011), + W16(0x0008), W16(0xFFF2), W16(0xFFC4), W16(0x0039), W16(0x0003), W16(0xFFFB), W16(0x0008), W16(0xFF8E), + W16(0x0027), W16(0xFFEA), W16(0x0021), W16(0x0041), W16(0xFFF2), W16(0xFFE4), W16(0x0018), W16(0x0005), + W16(0x0006), W16(0x000E), W16(0xFFEB), W16(0xFFDA), W16(0x0009), W16(0x0019), W16(0x002C), W16(0x004F), + W16(0x0077), W16(0xFFEC), W16(0xFFE6), W16(0xFFF4), W16(0xFFF6), W16(0x000D), W16(0x001C), W16(0xFFE2), + W16(0x0030), W16(0x0035), W16(0x0004), W16(0xFFF5), W16(0x001F), W16(0x003C), W16(0xFFD0), W16(0xFFC4), + W16(0xFFB1), W16(0x0000), W16(0xFFF9), W16(0xFFF5), W16(0xFFEB), W16(0xFFF8), W16(0xFFF8), W16(0xFFFB), + W16(0x0023), W16(0xFF64), W16(0x002A), W16(0x0001), W16(0x0004), W16(0x0030), W16(0x0004), W16(0xFFD9), + W16(0x001B), W16(0xFFDF), W16(0xFFF9), W16(0x0022), W16(0x0011), W16(0xFFE4), W16(0xFFE1), W16(0xFFE2), + W16(0x0023), W16(0x0014), W16(0x0025), W16(0xFFF3), W16(0xFFEA), W16(0xFFEB), W16(0xFFED), W16(0xFFF5), + W16(0x004C), W16(0xFFDE), W16(0xFFE9), W16(0x0024), W16(0x0073), W16(0xFFEB), W16(0xFFCA), W16(0x0018), + W16(0x0024), W16(0xFFE8), W16(0x0022), W16(0xFFD7), W16(0xFFD6), W16(0xFFFE), W16(0xFFE4), W16(0xFFFB), + W16(0x0009), W16(0xFFDF), W16(0x000D), W16(0x0008), W16(0x0012), W16(0x000C), W16(0x0012), W16(0x0019), + W16(0xFFC4), W16(0x005D), W16(0x001A), W16(0x004E), W16(0x0030), W16(0x0028), W16(0xFFFA), W16(0xFFE7), + W16(0xFFD3), W16(0xFFE7), W16(0x001A), W16(0x000C), W16(0xFFCB), W16(0xFFD8), W16(0x0013), W16(0x0011), + W16(0x001F), W16(0x003A), W16(0x0019), W16(0x0006), W16(0xFFF2), W16(0xFFFE), W16(0x000C), W16(0x0019), + W16(0xFFFF), W16(0x0027), W16(0xFF96), W16(0x0023), W16(0xFFFA), W16(0x002D), W16(0xFFC5), W16(0x0037), + W16(0x000B), W16(0xFFD5), W16(0x0027), W16(0xFFF7), W16(0x0007), W16(0x001C), W16(0xFFF4), W16(0xFFDB), + W16(0xFFEE), W16(0x0015), W16(0xFFF9), W16(0xFFF6), W16(0xFFE9), W16(0xFFE9), W16(0xFFFF), W16(0x0027), + W16(0x004C), W16(0x0038), W16(0xFFBB), W16(0xFFF4), W16(0x000E), W16(0xFFA5), W16(0xFFD7), W16(0xFFF3), + W16(0xFFE5), W16(0xFFFA), W16(0x0015), W16(0x0046), W16(0x0023), W16(0xFFFA), W16(0xFFED), W16(0x0010), + W16(0x0030), W16(0x0025), W16(0x003E), W16(0x0006), W16(0xFFD6), W16(0xFFDE), W16(0xFFEE), W16(0x0006), + W16(0x0002), W16(0x001D), W16(0xFFC3), W16(0x000D), W16(0xFFFD), W16(0x0008), W16(0x0053), W16(0xFFD9), + W16(0xFFA1), W16(0xFF9C), W16(0x004A), W16(0x0032), W16(0xFFB5), W16(0x0050), W16(0xFFF1), W16(0x000E), + W16(0x0013), W16(0xFFD6), W16(0xFFFA), W16(0xFFF4), W16(0xFFFE), W16(0xFFE9), W16(0xFFCD), W16(0xFFC4), + W16(0x002E), W16(0x001B), W16(0x0026), W16(0xFFC8), W16(0x001D), W16(0xFFA0), W16(0x0026), W16(0x0031), + W16(0x005B), W16(0x0017), W16(0xFFD8), W16(0x0004), W16(0x0003), W16(0xFFD6), W16(0xFFF9), W16(0xFFD2), + W16(0xFFFA), W16(0xFFEF), W16(0xFFF5), W16(0xFFF7), W16(0xFFEF), W16(0x000F), W16(0x0036), W16(0x004E), + W16(0xFFCD), W16(0x0006), W16(0x001E), W16(0x0007), W16(0x0024), W16(0x0000), W16(0x0012), W16(0x000B), + W16(0x0031), W16(0xFFFA), W16(0x0004), W16(0x004F), W16(0xFFB3), W16(0x0017), W16(0xFFCE), W16(0xFFDA), + W16(0xFFD0), W16(0xFFE6), W16(0xFFE6), W16(0x0039), W16(0x0044), W16(0x003F), W16(0x0024), W16(0x0014), + W16(0xFFF4), W16(0xFFE0), W16(0x0002), W16(0x0020), W16(0xFFD5), W16(0xFFE0), W16(0xFFF9), W16(0x0018), + W16(0x004A), W16(0x0032), W16(0xFF9D), W16(0x0010), W16(0xFFBA), W16(0x0019), W16(0x000B), W16(0x001F), + W16(0x0013), W16(0xFFFE), W16(0x0016), W16(0xFFFA), W16(0xFFF2), W16(0xFFED), W16(0xFFEA), W16(0xFFFD), + W16(0x0005), W16(0xFFE1), W16(0x0003), W16(0x0041), W16(0x000E), W16(0xFFF3), W16(0x0050), W16(0x002C), + W16(0xFFDC), W16(0xFFEE), W16(0x0002), W16(0xFF95), W16(0x001E), W16(0x0006), W16(0x0000), W16(0xFFFD), + W16(0x0002), W16(0x000F), W16(0x002E), W16(0x0041), W16(0x0008), W16(0xFFF4), W16(0xFFE4), W16(0xFFEF), + W16(0xFFC3), W16(0x001F), W16(0x0020), W16(0xFFFD), W16(0xFFEA), W16(0x0021), W16(0xFFEA), W16(0xFFEF), + W16(0xFFF4), W16(0x004B), W16(0x000F), W16(0xFFA9), W16(0x0058), W16(0xFFC5), W16(0xFFD5), W16(0x004C), + W16(0xFFE4), W16(0x003A), W16(0x0016), W16(0x000C), W16(0xFFED), W16(0x001D), W16(0x001E), W16(0x0017), + W16(0x0015), W16(0x007A), W16(0x001F), W16(0xFFDC), W16(0xFFEB), W16(0x0025), W16(0x0000), W16(0x000D), + W16(0x0031), W16(0x0001), W16(0xFFF5), W16(0xFFC2), W16(0xFFDF), W16(0xFFF7), W16(0xFFF7), W16(0x0004), + W16(0x002B), W16(0x0029), W16(0x0028), W16(0x0025), W16(0x001B), W16(0x0010), W16(0x000C), W16(0x0011), + W16(0xFFEE), W16(0x0062), W16(0x003D), W16(0x0058), W16(0x0031), W16(0xFFF5), W16(0x000E), W16(0x000D), + W16(0x000D), W16(0x0005), W16(0xFFEC), W16(0xFFF2), W16(0x0020), W16(0x001D), W16(0xFFB1), W16(0xFFEC), + W16(0xFFF4), W16(0xFFEB), W16(0xFFE7), W16(0xFFD8), W16(0xFFF3), W16(0xFFF0), W16(0xFFE2), W16(0xFFDC), + W16(0x0019), W16(0xFFBF), W16(0xFFF8), W16(0x0010), W16(0xFFF3), W16(0xFFE0), W16(0x0028), W16(0x0034), + W16(0xFFE6), W16(0x0016), W16(0x004D), W16(0x0000), W16(0xFFC6), W16(0xFFD8), W16(0xFFC6), W16(0x002E), + W16(0xFFF6), W16(0x0068), W16(0x002D), W16(0xFFE4), W16(0x0009), W16(0x002E), W16(0x0045), W16(0x0059), + W16(0x0013), W16(0x0009), W16(0x0031), W16(0x0012), W16(0x0041), W16(0x0003), W16(0x0009), W16(0xFFF9), + W16(0x0001), W16(0x0005), W16(0x0010), W16(0x0006), W16(0xFFFA), W16(0x0021), W16(0x001A), W16(0xFFE0), + W16(0xFF87), W16(0xFFC2), W16(0x00FF), W16(0xFFF1), W16(0x000C), W16(0x0020), W16(0xFFF1), W16(0x0033), + W16(0x002E), W16(0x0007), W16(0x0048), W16(0xFFA8), W16(0xFFFF), W16(0x003C), W16(0xFFE9), W16(0xFFCA), + W16(0xFFE5), W16(0x0023), W16(0xFFE6), W16(0x0048), W16(0xFFA2), W16(0x002F), W16(0x0011), W16(0xFFF0), + W16(0x0009), W16(0x0016), W16(0x002B), W16(0x002A), W16(0xFFCE), W16(0xFFDF), W16(0xFFC7), W16(0xFFC7), + W16(0xFFE0), W16(0x003A), W16(0x0040), W16(0x0013), W16(0xFF97), W16(0x000B), W16(0x0020), W16(0x001A), + W16(0xFFF6), W16(0xFFD8), W16(0x000C), W16(0x0064), W16(0x0024), W16(0xFFF9), W16(0xFFE1), W16(0xFFE1), + W16(0x0008), W16(0xFFFF), W16(0x0013), W16(0x001C), W16(0x0000), W16(0xFFEA), W16(0xFFEE), W16(0x0007), + W16(0x0042), W16(0xFFE7), W16(0xFFCB), W16(0x0004), W16(0xFFAD), W16(0x0010), W16(0x0001), W16(0x0019), + W16(0xFFD0), W16(0x0052), W16(0x000E), W16(0x000C), W16(0xFFF6), W16(0x0011), W16(0xFFE9), W16(0xFFE9), + W16(0x0013), W16(0xFFE4), W16(0x0014), W16(0x003B), W16(0x0033), W16(0x0034), W16(0x0030), W16(0x0030), + W16(0xFFD0), W16(0x002C), W16(0x0005), W16(0xFFF2), W16(0xFFF0), W16(0xFF90), W16(0xFFB8), W16(0xFFF6), + W16(0x0013), W16(0x001A), W16(0x0026), W16(0xFFFC), W16(0x000E), W16(0x0037), W16(0x0021), W16(0x000E), + W16(0x000E), W16(0x0010), W16(0x0029), W16(0x0020), W16(0x0025), W16(0x0026), W16(0x0033), W16(0x0038), + W16(0x0016), W16(0x000D), W16(0xFFD6), W16(0x002B), W16(0x000D), W16(0x0029), W16(0xFFF8), W16(0x000C), + W16(0x0027), W16(0x0008), W16(0xFFB4), W16(0x0012), W16(0x0016), W16(0xFFCF), W16(0xFFEF), W16(0xFFD4), + W16(0x0029), W16(0x0026), W16(0xFFF5), W16(0x00A4), W16(0x009C), W16(0xFE71), W16(0x003B), W16(0xFF88), + W16(0x0016), W16(0x000A), W16(0x0021), W16(0x0085), W16(0xFFE0), W16(0x0022), W16(0xFFB1), W16(0x000D), + W16(0xFFE9), W16(0x0000), W16(0x0017), W16(0x001A), W16(0x000A), W16(0x000F), W16(0x001A), W16(0xFFF8), + W16(0xFFFA), W16(0xFFCA), W16(0xFFCB), W16(0x0000), W16(0xFFE7), W16(0xFFDF), W16(0xFFD0), W16(0xFFE5), + W16(0x0052), W16(0x0028), W16(0xFFCD), W16(0xFFE0), W16(0x000D), W16(0xFFD1), W16(0x0016), W16(0x001F), + W16(0xFFE1), W16(0xFFDC), W16(0xFFF4), W16(0xFFD9), W16(0xFFE3), W16(0x0048), W16(0x001D), W16(0x0004), + W16(0x0017), W16(0x0009), W16(0xFFAA), W16(0xFFAD), W16(0x0093), W16(0x005D), W16(0x0023), W16(0x008B), + W16(0x0035), W16(0x001A), W16(0x008C), W16(0xFFD3), W16(0x001B), W16(0xFFF8), W16(0x000A), W16(0x001D), + W16(0xFFA4), W16(0xFFFC), W16(0x0037), W16(0xFFFA), W16(0xFFE3), W16(0xFFDA), W16(0x0008), W16(0x0011), + W16(0x0020), W16(0xFFEE), W16(0xFFF0), W16(0xFFD9), W16(0xFFEE), W16(0xFFF2), W16(0xFFE8), W16(0x0010), + W16(0x0043), W16(0x0017), W16(0x0077), W16(0x0038), W16(0xFFF2), W16(0xFFF0), W16(0xFFEC), W16(0xFFC5), + W16(0x0026), W16(0x0007), W16(0x0022), W16(0xFFEB), W16(0xFFFA), W16(0x0012), W16(0x000F), W16(0x0016), + W16(0x0002), W16(0xFFE9), W16(0xFFF4), W16(0x0015), W16(0x0008), W16(0x001D), W16(0x003B), W16(0x0044), + W16(0x0025), W16(0xFFEB), W16(0x0026), W16(0x002A), W16(0xFFDB), W16(0x0000), W16(0x0047), W16(0x0005), + W16(0x000E), W16(0xFFBA), W16(0xFF9B), W16(0x000E), W16(0x0007), W16(0x0052), W16(0x003F), W16(0x0004), + W16(0xFFCE), W16(0x0041), W16(0x002C), W16(0xFFF5), W16(0xFFDC), W16(0x000E), W16(0x0023), W16(0x002A), + W16(0xFFE0), W16(0xFFFA), W16(0x0013), W16(0x000F), W16(0x0001), W16(0xFFF3), W16(0x0019), W16(0x0003), + W16(0xFFDD), W16(0x0010), W16(0x0004), W16(0x0017), W16(0xFFBA), W16(0x002B), W16(0xFFF7), W16(0xFF9E), + W16(0x006E), W16(0xFFF2), W16(0x0013), W16(0xFFAC), W16(0x0037), W16(0x012C), W16(0xFFBB), W16(0xFFB8), + W16(0x002C), W16(0x001F), W16(0x0017), W16(0xFFFE), W16(0xFFCE), W16(0xFFF3), W16(0x001E), W16(0xFFC7), + W16(0xFFE3), W16(0x0038), W16(0xFFD2), W16(0x0010), W16(0x0025), W16(0xFFD2), W16(0x0035), W16(0x0012), + W16(0x001F), W16(0x0028), W16(0x0033), W16(0x003A), W16(0x0021), W16(0xFFE2), W16(0xFFB8), W16(0xFFAF) +}; + +const Word16 cdk_37bits_6_fx[1536] = +{ + W16(0x0003), W16(0xFFDA), W16(0x0007), W16(0x0012), W16(0x0022), W16(0xFFFC), W16(0x001A), W16(0x0047), + W16(0x001D), W16(0x0029), W16(0x0015), W16(0xFFF4), W16(0xFFE2), W16(0xFFC7), W16(0xFFD7), W16(0xFFDC), + W16(0xFFD6), W16(0xFFE8), W16(0xFFE9), W16(0xFFC5), W16(0xFFFA), W16(0x0002), W16(0x0019), W16(0x0032), + W16(0xFF9B), W16(0xFFEF), W16(0xFFDC), W16(0xFFDE), W16(0xFFF3), W16(0x0024), W16(0xFFE6), W16(0xFFCA), + W16(0xFFD9), W16(0x000B), W16(0x0009), W16(0x002B), W16(0xFFFB), W16(0x000A), W16(0xFFE1), W16(0xFFF7), + W16(0x0045), W16(0xFFE3), W16(0x0009), W16(0xFFF9), W16(0xFFD4), W16(0xFFDE), W16(0x001C), W16(0x0027), + W16(0xFFCC), W16(0xFFBD), W16(0xFFF8), W16(0xFFB6), W16(0x0017), W16(0x0015), W16(0x002B), W16(0xFFDC), + W16(0x0026), W16(0x001E), W16(0xFFCC), W16(0xFFF1), W16(0xFFD5), W16(0xFFF5), W16(0x0009), W16(0x000F), + W16(0xFFEA), W16(0xFFD5), W16(0xFFFD), W16(0x0018), W16(0xFFFF), W16(0xFFE9), W16(0xFFEA), W16(0x0000), + W16(0x000C), W16(0x002C), W16(0xFFCF), W16(0x0042), W16(0x001C), W16(0xFFF8), W16(0x0001), W16(0xFFDF), + W16(0xFFEE), W16(0x0014), W16(0x0030), W16(0xFFC4), W16(0x001C), W16(0x0013), W16(0xFFED), W16(0xFFF6), + W16(0x0003), W16(0xFFBD), W16(0xFFC7), W16(0xFFF4), W16(0x000A), W16(0xFFF4), W16(0xFFF5), W16(0xFFE4), + W16(0xFFF2), W16(0xFFD3), W16(0xFFE6), W16(0xFFEF), W16(0x0003), W16(0xFFE0), W16(0xFFCD), W16(0xFFF2), + W16(0x002D), W16(0xFFE1), W16(0x0061), W16(0xFFFF), W16(0xFFD0), W16(0xFFEB), W16(0xFFEA), W16(0x0024), + W16(0x0027), W16(0x000A), W16(0xFFE5), W16(0xFFCA), W16(0xFFE6), W16(0xFFEF), W16(0xFFF9), W16(0xFFE6), + W16(0xFFE1), W16(0x0000), W16(0xFFEB), W16(0x0011), W16(0xFFFA), W16(0xFFF0), W16(0x0024), W16(0x0018), + W16(0x0003), W16(0xFFE4), W16(0xFFF2), W16(0xFFF5), W16(0xFFEF), W16(0xFFE8), W16(0x000D), W16(0x0044), + W16(0xFFE4), W16(0xFFF9), W16(0xFFC7), W16(0xFFF8), W16(0xFF82), W16(0x00CE), W16(0xFFCF), W16(0x0030), + W16(0x0018), W16(0xFFAE), W16(0x0005), W16(0xFFC6), W16(0xFFBA), W16(0x0005), W16(0x0021), W16(0x000B), + W16(0xFFF5), W16(0xFFF4), W16(0x0005), W16(0x002F), W16(0xFFF4), W16(0xFFFB), W16(0xFFFE), W16(0x0004), + W16(0x0007), W16(0x0011), W16(0xFFF5), W16(0xFFE5), W16(0x0003), W16(0x001C), W16(0x003F), W16(0x0042), + W16(0xFFB1), W16(0xFFD1), W16(0x0012), W16(0xFFFB), W16(0x001F), W16(0xFFE4), W16(0x0016), W16(0xFFFF), + W16(0x0001), W16(0xFFFC), W16(0xFFF3), W16(0xFFB8), W16(0x001C), W16(0x0027), W16(0xFFFF), W16(0xFFEF), + W16(0x000F), W16(0x001C), W16(0x001B), W16(0xFFDA), W16(0x0008), W16(0x0003), W16(0x0018), W16(0x002B), + W16(0x0013), W16(0x0000), W16(0x0005), W16(0xFFF6), W16(0xFFF0), W16(0xFF94), W16(0x003D), W16(0x0003), + W16(0x0006), W16(0xFFFE), W16(0xFFFE), W16(0x0023), W16(0x0010), W16(0x000E), W16(0x0022), W16(0xFFDF), + W16(0xFFF7), W16(0xFFD6), W16(0xFFF5), W16(0xFFD2), W16(0xFFCA), W16(0xFFBC), W16(0xFFD7), W16(0xFFF2), + W16(0xFFD3), W16(0xFFF1), W16(0xFFB4), W16(0xFFEE), W16(0xFFCA), W16(0xFFCD), W16(0x000E), W16(0x0046), + W16(0x0001), W16(0xFFEB), W16(0x002D), W16(0x0005), W16(0x0001), W16(0x0011), W16(0xFFFC), W16(0x0007), + W16(0xFFE3), W16(0xFFDE), W16(0xFFF4), W16(0x0022), W16(0x0020), W16(0x000C), W16(0xFFF7), W16(0xFFE6), + W16(0xFFFA), W16(0xFFD0), W16(0x0004), W16(0x0004), W16(0xFFD6), W16(0x0004), W16(0xFFD3), W16(0x0012), + W16(0x001C), W16(0xFFA6), W16(0xFFCE), W16(0x0026), W16(0xFFF3), W16(0x004B), W16(0x002F), W16(0xFFFE), + W16(0x0021), W16(0xFFEE), W16(0xFFE8), W16(0x0008), W16(0x000E), W16(0x0002), W16(0x000C), W16(0xFFFC), + W16(0xFFDF), W16(0x003D), W16(0x0008), W16(0xFFB1), W16(0x0025), W16(0x0009), W16(0x001D), W16(0x0013), + W16(0xFFE9), W16(0xFFC5), W16(0xFFEF), W16(0x0006), W16(0x002C), W16(0x0018), W16(0x0014), W16(0xFFD7), + W16(0xFFD0), W16(0xFFDB), W16(0xFFEB), W16(0x0008), W16(0xFFE9), W16(0xFFF1), W16(0x0009), W16(0x0012), + W16(0x001A), W16(0xFFF4), W16(0xFFD3), W16(0xFFFB), W16(0xFFDF), W16(0x001B), W16(0x0004), W16(0xFFFD), + W16(0x0037), W16(0xFFE2), W16(0xFFF0), W16(0x0014), W16(0xFFF4), W16(0xFFF2), W16(0xFFF5), W16(0x000E), + W16(0xFFFF), W16(0xFFC4), W16(0x00C0), W16(0xFFAA), W16(0xFFBD), W16(0x0002), W16(0x001A), W16(0xFFCE), + W16(0x000E), W16(0xFFDE), W16(0xFF98), W16(0x0022), W16(0x0022), W16(0xFFFA), W16(0x0034), W16(0xFFF5), + W16(0x0013), W16(0xFFDB), W16(0xFFCF), W16(0x0003), W16(0xFFF3), W16(0xFFFB), W16(0x000C), W16(0xFFCE), + W16(0x0034), W16(0x0026), W16(0x0009), W16(0xFFF8), W16(0xFFE9), W16(0xFFE6), W16(0xFFF2), W16(0xFFFA), + W16(0xFFF6), W16(0x0002), W16(0xFFD7), W16(0x001A), W16(0x0007), W16(0x0004), W16(0xFFDC), W16(0xFFF3), + W16(0x0020), W16(0x0017), W16(0xFFD8), W16(0xFFF5), W16(0xFFC0), W16(0x006D), W16(0xFFDC), W16(0x0033), + W16(0xFFE6), W16(0xFFE3), W16(0xFFE1), W16(0xFFE2), W16(0x000C), W16(0x0019), W16(0x0026), W16(0x0023), + W16(0xFFDD), W16(0x0032), W16(0xFFFB), W16(0x0003), W16(0xFFD2), W16(0xFFDB), W16(0x001C), W16(0xFFF2), + W16(0xFFFD), W16(0x003B), W16(0xFFED), W16(0xFFF7), W16(0xFFD6), W16(0xFFB8), W16(0x0027), W16(0x003D), + W16(0x0037), W16(0x0003), W16(0xFFC9), W16(0xFFD7), W16(0x0021), W16(0x0011), W16(0x001E), W16(0xFFEA), + W16(0xFFEF), W16(0x001D), W16(0x0013), W16(0xFFEC), W16(0x0002), W16(0x0021), W16(0x0023), W16(0x003D), + W16(0xFFF4), W16(0xFFF0), W16(0xFFDD), W16(0x0008), W16(0x000F), W16(0xFFBF), W16(0xFFBA), W16(0xFFEF), + W16(0x003F), W16(0xFFE5), W16(0xFFF4), W16(0xFFFC), W16(0x000A), W16(0x000B), W16(0xFFFE), W16(0xFFD7), + W16(0xFFF7), W16(0x0013), W16(0xFFD5), W16(0xFFEA), W16(0xFFD1), W16(0x0025), W16(0xFFF1), W16(0xFFF8), + W16(0x000E), W16(0x004D), W16(0x0028), W16(0x0004), W16(0x001F), W16(0xFFEA), W16(0xFFD0), W16(0xFFCE), + W16(0xFFF1), W16(0xFFFF), W16(0xFFE6), W16(0xFFF1), W16(0xFFC9), W16(0xFFC2), W16(0xFFCC), W16(0xFFD9), + W16(0xFFFB), W16(0xFFC2), W16(0xFFFE), W16(0xFFE4), W16(0x0022), W16(0x0029), W16(0xFFF8), W16(0x0044), + W16(0xFFBD), W16(0xFFEE), W16(0xFFFF), W16(0xFFD1), W16(0xFFFF), W16(0x002C), W16(0xFFF2), W16(0xFFE4), + W16(0xFFFC), W16(0x000C), W16(0xFFE9), W16(0x001B), W16(0x0019), W16(0x0011), W16(0xFFF6), W16(0xFFC8), + W16(0xFFD8), W16(0x0018), W16(0xFFEE), W16(0xFFD1), W16(0x0042), W16(0xFFDE), W16(0x0031), W16(0xFFC4), + W16(0xFFFB), W16(0xFFEC), W16(0x002B), W16(0xFFF6), W16(0x000B), W16(0xFFEE), W16(0xFFCD), W16(0x003C), + W16(0xFFE2), W16(0xFFFE), W16(0x0006), W16(0xFFF5), W16(0xFFF9), W16(0xFFE4), W16(0xFFEA), W16(0xFFE3), + W16(0xFFD6), W16(0x0017), W16(0xFFFC), W16(0xFFEE), W16(0x0024), W16(0xFFF2), W16(0xFFEB), W16(0x0004), + W16(0x000E), W16(0xFFF3), W16(0x0021), W16(0xFFED), W16(0xFFD3), W16(0xFFFE), W16(0x003B), W16(0xFFDD), + W16(0x0006), W16(0x008A), W16(0xFF6E), W16(0x002F), W16(0x002E), W16(0x0020), W16(0x000F), W16(0xFFDB), + W16(0xFFFF), W16(0x0000), W16(0x0045), W16(0xFFF6), W16(0x0008), W16(0x003C), W16(0xFFE5), W16(0xFFF7), + W16(0xFFDD), W16(0xFFFD), W16(0xFFE8), W16(0xFFC4), W16(0xFFEE), W16(0x0000), W16(0x000D), W16(0x0028), + W16(0x0036), W16(0x0020), W16(0xFFDB), W16(0xFFB8), W16(0xFFDC), W16(0xFFEA), W16(0xFFF1), W16(0xFFE2), + W16(0xFFEE), W16(0x0014), W16(0x002C), W16(0xFFCD), W16(0xFFFB), W16(0x0018), W16(0xFFEE), W16(0x001D), + W16(0x0035), W16(0xFFDA), W16(0x0020), W16(0xFFEC), W16(0x0002), W16(0xFFFF), W16(0xFFB9), W16(0x002B), + W16(0xFFE1), W16(0xFFB9), W16(0xFFE5), W16(0x0007), W16(0x0001), W16(0x000A), W16(0x0025), W16(0x0027), + W16(0x0024), W16(0xFFA1), W16(0x0020), W16(0x001A), W16(0x0020), W16(0xFFFD), W16(0x0001), W16(0xFFDD), + W16(0xFFB9), W16(0x0008), W16(0xFFF3), W16(0x003F), W16(0x0004), W16(0x0012), W16(0xFFDE), W16(0x0026), + W16(0xFFF9), W16(0xFFEB), W16(0xFFFD), W16(0xFFFD), W16(0xFFF1), W16(0xFFF0), W16(0xFFEF), W16(0xFFCE), + W16(0x0002), W16(0xFFF6), W16(0xFFD5), W16(0x002D), W16(0x0014), W16(0x000B), W16(0x0050), W16(0xFFFB), + W16(0xFFC8), W16(0xFFF7), W16(0x0000), W16(0xFFF8), W16(0xFFD7), W16(0xFFE9), W16(0x0044), W16(0xFFFF), + W16(0xFFDC), W16(0xFFC0), W16(0x0010), W16(0x0016), W16(0xFFF1), W16(0x0003), W16(0x0011), W16(0x001F), + W16(0xFFD2), W16(0xFFE4), W16(0xFFDE), W16(0x0028), W16(0xFFE1), W16(0x0048), W16(0x001A), W16(0xFFED), + W16(0x0006), W16(0xFFE3), W16(0xFFD1), W16(0x0012), W16(0x002A), W16(0x0001), W16(0xFFF1), W16(0x001A), + W16(0xFFCE), W16(0x0007), W16(0xFFDA), W16(0xFFE4), W16(0x0034), W16(0xFFE1), W16(0xFFD0), W16(0xFFD2), + W16(0xFFD3), W16(0x0000), W16(0xFFF8), W16(0x0023), W16(0x001A), W16(0xFFD7), W16(0xFFC2), W16(0x0007), + W16(0x0027), W16(0x0035), W16(0xFFC3), W16(0x000D), W16(0x001A), W16(0xFFE5), W16(0x0033), W16(0xFFE6), + W16(0x0000), W16(0xFFCF), W16(0xFFFA), W16(0x0016), W16(0x000C), W16(0x0009), W16(0x001D), W16(0x0014), + W16(0x0014), W16(0x0015), W16(0x000F), W16(0xFFF3), W16(0xFFBB), W16(0x002B), W16(0x002F), W16(0xFFE4), + W16(0xFFF4), W16(0xFFEF), W16(0x004E), W16(0xFFCE), W16(0x0009), W16(0x0012), W16(0x0014), W16(0x0008), + W16(0xFFD1), W16(0x001C), W16(0x0010), W16(0xFFE0), W16(0xFFEE), W16(0xFFF1), W16(0x000C), W16(0x0004), + W16(0xFFA0), W16(0x0005), W16(0x0061), W16(0x000D), W16(0xFFE8), W16(0xFFFF), W16(0xFFF5), W16(0x0002), + W16(0xFFF2), W16(0x0003), W16(0x001F), W16(0x0020), W16(0x0006), W16(0x000D), W16(0xFFFF), W16(0xFFF3), + W16(0xFFE8), W16(0xFFFA), W16(0x0011), W16(0x000B), W16(0xFFE7), W16(0xFFDD), W16(0xFFDA), W16(0xFFC3), + W16(0x0013), W16(0x0022), W16(0xFFDA), W16(0x0002), W16(0xFFF1), W16(0x0049), W16(0xFFC8), W16(0x0025), + W16(0xFFBE), W16(0xFFF7), W16(0x001C), W16(0x002B), W16(0xFFC7), W16(0xFFEF), W16(0x0004), W16(0x002C), + W16(0xFFF7), W16(0xFFF3), W16(0xFFFB), W16(0x000B), W16(0x000A), W16(0xFFE8), W16(0xFFDF), W16(0xFFD2), + W16(0x002E), W16(0xFFEE), W16(0xFFFF), W16(0xFFEE), W16(0x003D), W16(0xFFE4), W16(0xFFE8), W16(0x002D), + W16(0x0000), W16(0x0015), W16(0x000C), W16(0xFFD1), W16(0xFFA8), W16(0xFFF7), W16(0x0011), W16(0x0015), + W16(0x0011), W16(0xFFF8), W16(0x0003), W16(0x0022), W16(0xFFD0), W16(0xFFC1), W16(0xFFC2), W16(0xFFD9), + W16(0x0006), W16(0x0016), W16(0xFFFB), W16(0xFF9E), W16(0xFFBD), W16(0xFFDF), W16(0xFFD1), W16(0x0019), + W16(0x000F), W16(0x0021), W16(0xFFE9), W16(0xFFF1), W16(0x0024), W16(0x0010), W16(0x0006), W16(0x0016), + W16(0x0021), W16(0x0014), W16(0x0017), W16(0x0016), W16(0x0002), W16(0xFFE5), W16(0xFFE0), W16(0xFFDD), + W16(0xFFE0), W16(0x0019), W16(0x0009), W16(0x0038), W16(0x0013), W16(0x0005), W16(0x0009), W16(0x0034), + W16(0x0024), W16(0xFFB7), W16(0xFFFD), W16(0x003C), W16(0xFFD1), W16(0xFFED), W16(0xFFFD), W16(0xFFEB), + W16(0xFFF1), W16(0x002C), W16(0x0031), W16(0xFFE2), W16(0xFFFD), W16(0xFFDA), W16(0xFFF5), W16(0x0001), + W16(0x0002), W16(0xFFE6), W16(0xFFDF), W16(0xFFDB), W16(0x0041), W16(0x000A), W16(0xFFD3), W16(0x0000), + W16(0x0021), W16(0x001C), W16(0xFFDC), W16(0x002A), W16(0x0012), W16(0xFFDF), W16(0xFFBD), W16(0x0001), + W16(0xFFF0), W16(0x003B), W16(0x0005), W16(0x0009), W16(0x0031), W16(0x0026), W16(0x001A), W16(0x0007), + W16(0x003C), W16(0xFFE4), W16(0x003E), W16(0xFFF5), W16(0x002C), W16(0xFFFB), W16(0x0024), W16(0xFFD0), + W16(0x001F), W16(0xFFD1), W16(0x0005), W16(0x0012), W16(0x0004), W16(0xFFCC), W16(0x001F), W16(0xFFF1), + W16(0xFFFE), W16(0xFFF4), W16(0xFFE6), W16(0x0020), W16(0xFFFD), W16(0xFFEA), W16(0xFFD6), W16(0xFFB7), + W16(0x0034), W16(0xFFDE), W16(0xFFC8), W16(0xFFBB), W16(0x0018), W16(0xFFFE), W16(0xFFC5), W16(0xFFDE), + W16(0x0010), W16(0xFFFB), W16(0x0013), W16(0xFFD3), W16(0x002C), W16(0x000E), W16(0x0032), W16(0x0002), + W16(0xFFEA), W16(0xFFDE), W16(0xFFD6), W16(0xFFEF), W16(0x0009), W16(0xFFFB), W16(0x0012), W16(0x001C), + W16(0x004A), W16(0xFFD8), W16(0x0012), W16(0x0013), W16(0xFFE1), W16(0xFFF3), W16(0xFFD0), W16(0xFFFB), + W16(0xFFEB), W16(0x001A), W16(0x004F), W16(0xFFF6), W16(0xFFE2), W16(0x001D), W16(0x003B), W16(0xFFBB), + W16(0x0022), W16(0x0016), W16(0x001D), W16(0xFFF7), W16(0xFFF3), W16(0x0000), W16(0x0007), W16(0x0003), + W16(0xFFE8), W16(0xFFFF), W16(0x000B), W16(0x0018), W16(0x0001), W16(0x002D), W16(0xFFE3), W16(0xFFEA), + W16(0xFFDD), W16(0x002D), W16(0x0008), W16(0xFFE3), W16(0x0031), W16(0x0029), W16(0x0000), W16(0xFFD6), + W16(0xFFDF), W16(0xFFE3), W16(0x0001), W16(0x0091), W16(0xFF6B), W16(0x0028), W16(0x0032), W16(0xFFF0), + W16(0x000B), W16(0xFFF6), W16(0x0011), W16(0x000E), W16(0xFFB0), W16(0x003F), W16(0x0007), W16(0x004A), + W16(0x0015), W16(0x0025), W16(0xFFCA), W16(0xFFD4), W16(0xFFE5), W16(0xFFF2), W16(0x0026), W16(0xFFFF), + W16(0xFFED), W16(0xFFFC), W16(0x0006), W16(0x0009), W16(0x000A), W16(0xFFF4), W16(0xFFFF), W16(0xFFFD), + W16(0x004B), W16(0x0013), W16(0xFFF7), W16(0x0009), W16(0x0021), W16(0x0000), W16(0x0015), W16(0x000D), + W16(0xFFD2), W16(0x002C), W16(0xFF9E), W16(0xFFED), W16(0x001E), W16(0x000D), W16(0x000D), W16(0xFFFE), + W16(0xFFFE), W16(0xFFF0), W16(0xFFF3), W16(0xFFF3), W16(0x0006), W16(0x000C), W16(0x0011), W16(0x0003), + W16(0x0026), W16(0x0047), W16(0xFFE0), W16(0xFFF6), W16(0xFFD5), W16(0xFFF6), W16(0xFFF4), W16(0xFFFC), + W16(0x0049), W16(0x001B), W16(0xFFDE), W16(0x0053), W16(0xFFE1), W16(0xFFF3), W16(0xFFF3), W16(0x0004), + W16(0xFFE5), W16(0xFFE4), W16(0xFFFD), W16(0x0013), W16(0xFFE9), W16(0x0005), W16(0xFFF0), W16(0xFFC2), + W16(0xFFFC), W16(0x000D), W16(0x0008), W16(0x0023), W16(0x002A), W16(0xFFCD), W16(0x0034), W16(0x0002), + W16(0xFFE5), W16(0x0032), W16(0x0036), W16(0x0011), W16(0x0006), W16(0xFFC8), W16(0xFFEE), W16(0xFFD7), + W16(0xFFE2), W16(0x0011), W16(0x001D), W16(0x0043), W16(0x002F), W16(0xFFF3), W16(0xFFE0), W16(0xFFD6), + W16(0xFFFC), W16(0x002B), W16(0x0000), W16(0x001E), W16(0x000D), W16(0x002E), W16(0xFFDF), W16(0x0006), + W16(0x000B), W16(0xFFE7), W16(0xFFEA), W16(0xFFF8), W16(0x000B), W16(0xFFDC), W16(0x004B), W16(0xFF7E), + W16(0x005D), W16(0xFFE1), W16(0xFFDF), W16(0xFFF9), W16(0x002E), W16(0xFFF6), W16(0xFFFE), W16(0x0027), + W16(0xFFEB), W16(0x0033), W16(0xFFC8), W16(0x0008), W16(0xFFE0), W16(0xFFEF), W16(0xFFF9), W16(0x0007), + W16(0xFFBB), W16(0x000D), W16(0xFFFF), W16(0x000D), W16(0x003E), W16(0x001F), W16(0x0014), W16(0xFFF6), + W16(0xFFF6), W16(0x003B), W16(0x001A), W16(0xFFD2), W16(0xFFE7), W16(0x0093), W16(0x0065), W16(0xFF85), + W16(0x0028), W16(0xFFCF), W16(0x0031), W16(0x0011), W16(0xFFF6), W16(0xFFE2), W16(0xFFFD), W16(0xFFFA), + W16(0x0003), W16(0x002F), W16(0xFFFB), W16(0xFFCB), W16(0x004A), W16(0x0012), W16(0xFFC6), W16(0xFFED), + W16(0x0029), W16(0xFFA8), W16(0x002F), W16(0x002C), W16(0x0013), W16(0xFFEF), W16(0xFFFD), W16(0x0004), + W16(0x0005), W16(0xFFD9), W16(0xFFD1), W16(0x000C), W16(0x0004), W16(0xFFF4), W16(0x0000), W16(0xFFF0), + W16(0x000F), W16(0xFFEB), W16(0x0029), W16(0x0019), W16(0x001D), W16(0x0022), W16(0xFFF5), W16(0xFFEF), + W16(0xFFBA), W16(0x0018), W16(0x0044), W16(0x002D), W16(0xFFD1), W16(0xFFA7), W16(0x0019), W16(0x0077), + W16(0xFFF4), W16(0x0056), W16(0x0010), W16(0x0017), W16(0x0014), W16(0x0019), W16(0x0015), W16(0xFFBF), + W16(0x001D), W16(0xFFFB), W16(0xFFD8), W16(0xFFEC), W16(0xFFEB), W16(0x000C), W16(0x002E), W16(0x0019), + W16(0xFFE5), W16(0xFFFB), W16(0x0021), W16(0x003B), W16(0x0022), W16(0xFFEE), W16(0xFFF2), W16(0xFFF2), + W16(0xFFFA), W16(0xFFF3), W16(0x000A), W16(0x0006), W16(0xFFF9), W16(0xFFEC), W16(0xFFF5), W16(0x0012), + W16(0xFFDD), W16(0xFFFD), W16(0x001F), W16(0x001A), W16(0x0037), W16(0xFF7C), W16(0x0024), W16(0x001C), + W16(0x000F), W16(0x0024), W16(0x0021), W16(0xFFD4), W16(0x0009), W16(0xFFF3), W16(0x0007), W16(0x0046), + W16(0xFFFF), W16(0x0015), W16(0x0002), W16(0x001C), W16(0xFFCE), W16(0xFFBC), W16(0x0023), W16(0xFFF2), + W16(0xFFF1), W16(0xFFD0), W16(0x001E), W16(0x001F), W16(0x0022), W16(0x0007), W16(0xFFDE), W16(0x001E), + W16(0x003F), W16(0x0009), W16(0x0020), W16(0x003E), W16(0x002F), W16(0x0028), W16(0x0035), W16(0x002D), + W16(0x000E), W16(0x0010), W16(0x002D), W16(0x0004), W16(0xFFDE), W16(0x0002), W16(0x0008), W16(0xFF95), + W16(0x000F), W16(0x002D), W16(0xFFF8), W16(0x003A), W16(0x002D), W16(0x0003), W16(0x0005), W16(0xFFEB), + W16(0xFFF5), W16(0xFFEF), W16(0xFFE0), W16(0x0003), W16(0x001F), W16(0x001B), W16(0x001C), W16(0x0017), + W16(0x0017), W16(0xFFFB), W16(0x0035), W16(0x001A), W16(0x003F), W16(0x0047), W16(0xFFD5), W16(0xFFEC), + W16(0x000E), W16(0x0005), W16(0xFFF6), W16(0x000A), W16(0xFFE4), W16(0x0020), W16(0x0004), W16(0xFFC5), + W16(0xFFD9), W16(0xFFDB), W16(0xFFFE), W16(0xFFE5), W16(0xFFF9), W16(0xFFF1), W16(0x000F), W16(0x001B), + W16(0x0006), W16(0x0052), W16(0x0025), W16(0xFFED), W16(0x001D), W16(0xFFEA), W16(0xFFE0), W16(0x0014), + W16(0xFFBF), W16(0x0042), W16(0x0025), W16(0x0004), W16(0xFFE4), W16(0x000B), W16(0xFFDE), W16(0x000B), + W16(0x0002), W16(0xFFF1), W16(0xFFEF), W16(0x0006), W16(0x0013), W16(0x0013), W16(0x0032), W16(0x0034), + W16(0x0028), W16(0x0016), W16(0x0017), W16(0xFFE7), W16(0x0025), W16(0xFFEF), W16(0x0009), W16(0xFFE8), + W16(0xFFEC), W16(0xFFC2), W16(0x002B), W16(0x0013), W16(0x0009), W16(0x004E), W16(0xFFC9), W16(0xFFC9), + W16(0x0027), W16(0x0040), W16(0xFFE6), W16(0xFFF6), W16(0x0000), W16(0x0007), W16(0xFFFE), W16(0xFFF3), + W16(0x0006), W16(0xFFEE), W16(0xFFF7), W16(0x0038), W16(0xFFFD), W16(0xFFF4), W16(0xFFE9), W16(0x000D), + W16(0xFFDE), W16(0xFFFD), W16(0xFFD1), W16(0x0010), W16(0xFFF1), W16(0x0006), W16(0xFFF2), W16(0x0033), + W16(0x0043), W16(0x000E), W16(0x0018), W16(0x0026), W16(0xFFF0), W16(0xFFA0), W16(0xFFB0), W16(0x00BF), + W16(0xFFF9), W16(0x0002), W16(0xFFFE), W16(0x0033), W16(0x0001), W16(0x0019), W16(0xFFD1), W16(0x000D), + W16(0x0016), W16(0xFFB4), W16(0xFFF4), W16(0xFFCA), W16(0x0046), W16(0x0002), W16(0x002A), W16(0x0010), + W16(0xFFFE), W16(0x0021), W16(0x0018), W16(0x0017), W16(0xFFF1), W16(0xFFE7), W16(0xFFF1), W16(0xFFF4), + W16(0x000D), W16(0xFFE0), W16(0x0019), W16(0x0015), W16(0x0006), W16(0xFFB4), W16(0xFFCB), W16(0x000E), + W16(0x0008), W16(0x0017), W16(0xFFF4), W16(0xFFF1), W16(0x0019), W16(0x000E), W16(0x0010), W16(0x0075), + W16(0xFFBD), W16(0x001F), W16(0x0012), W16(0xFFE7), W16(0x0025), W16(0x000A), W16(0xFFEC), W16(0xFFD9), + W16(0x0002), W16(0xFFF2), W16(0x0032), W16(0x0049), W16(0xFFDA), W16(0x000E), W16(0x0052), W16(0xFFD9), + W16(0x000D), W16(0x0006), W16(0x0006), W16(0xFFEF), W16(0xFFC3), W16(0x0020), W16(0xFFF4), W16(0xFFF0), + W16(0x001E), W16(0xFFFB), W16(0xFFF3), W16(0x000A), W16(0x000C), W16(0x000E), W16(0x0005), W16(0x000B), + W16(0xFFCF), W16(0xFFF1), W16(0xFFE8), W16(0x0019), W16(0xFFF4), W16(0x0043), W16(0xFFEF), W16(0xFFEF), + W16(0x003B), W16(0xFFF5), W16(0x0027), W16(0xFFDD), W16(0xFFE9), W16(0xFFD0), W16(0xFFEB), W16(0xFFF9), + W16(0x001B), W16(0x0003), W16(0x0033), W16(0x002A), W16(0x0049), W16(0x0024), W16(0x000F), W16(0xFFF8), + W16(0x0015), W16(0x0026), W16(0x0010), W16(0x000E), W16(0x0004), W16(0xFFDA), W16(0x0009), W16(0xFFF8), + W16(0x004F), W16(0x003C), W16(0xFFD9), W16(0xFFDE), W16(0xFFF3), W16(0x0012), W16(0xFFE9), W16(0xFFDE), + W16(0x0013), W16(0x0058), W16(0x0010), W16(0xFFF8), W16(0xFFEC), W16(0xFFEB), W16(0x0008), W16(0x001F), + W16(0x005B), W16(0x0043), W16(0xFFFA), W16(0x0028), W16(0xFFEC), W16(0xFFF8), W16(0xFFF9), W16(0x0044), + W16(0x0008), W16(0xFFE6), W16(0x000F), W16(0xFFF1), W16(0x0016), W16(0x0005), W16(0xFFF3), W16(0x0001), + W16(0xFFE4), W16(0xFFF3), W16(0xFFFC), W16(0xFFF7), W16(0x0015), W16(0xFFFC), W16(0xFFE2), W16(0xFFCD), + W16(0x0001), W16(0x0003), W16(0x006E), W16(0xFFEB), W16(0x0011), W16(0xFFC8), W16(0x0023), W16(0x0026), + W16(0xFFF9), W16(0x0000), W16(0xFFD4), W16(0x001A), W16(0x0010), W16(0xFFF0), W16(0xFFE0), W16(0x0029), + W16(0xFFEC), W16(0x0018), W16(0x0027), W16(0x0010), W16(0x0009), W16(0xFFFB), W16(0x0016), W16(0x0034), + W16(0x0041), W16(0x001F), W16(0xFFD6), W16(0xFFBD), W16(0x0011), W16(0x0026), W16(0x003B), W16(0xFFDE), + W16(0xFFD0), W16(0xFFEF), W16(0xFFE6), W16(0xFFF1), W16(0x000B), W16(0xFFF0), W16(0xFFE2), W16(0x001D), + W16(0x001F), W16(0x0038), W16(0x0028), W16(0x0005), W16(0xFFB6), W16(0xFFD4), W16(0x0013), W16(0x0007), + W16(0x0003), W16(0xFFF8), W16(0xFFFF), W16(0xFFDD), W16(0x0002), W16(0x0001), W16(0xFFFD), W16(0xFFD9), + W16(0xFFCE), W16(0x0003), W16(0xFFFE), W16(0x0007), W16(0xFFCF), W16(0x001B), W16(0x0049), W16(0x0026), + W16(0xFFF8), W16(0x0038), W16(0x0046), W16(0x0009), W16(0x006E), W16(0x0044), W16(0x0011), W16(0xFFFF), + W16(0x000F), W16(0x0003), W16(0x002A), W16(0x0001), W16(0xFFE9), W16(0xFFF7), W16(0xFFCF), W16(0x000F), + W16(0x0014), W16(0x0003), W16(0x0028), W16(0x0031), W16(0x0008), W16(0xFFF2), W16(0xFFF2), W16(0xFFE6), + W16(0x0001), W16(0x000E), W16(0xFFA6), W16(0xFFA6), W16(0x0081), W16(0x007A), W16(0xFFA0), W16(0x0023) +}; + +const Word16 * const cdk_37bits[] = { cdk_37bits_1_fx, cdk_37bits_2_fx, cdk_37bits_3_fx, cdk_37bits_4_fx, + cdk_37bits_5_fx, cdk_37bits_6_fx +}; /* Sine tables for FFT */ /* for (j=0; jfftlen/2+1; j++) hs->fftSineTab[j] = (float)sin(2.0*EVS_PI*j/hs->fftlen); */ @@ -11648,7 +16209,7 @@ const lsp_unw_triplet p16_gamma0_94to1[16] = /* Q14 */ { -5473, 10245, 0 } }; -const float dico_lsf_abs_8b[256*M] = +const float dico_lsf_abs_8b_flt[256*M] = { 377.3749f, 688.0079f, 1147.3799f, 1461.0438f, 1786.7794f, 2143.6711f, 2522.1946f, 2889.7402f, 3263.6023f, 3628.4624f, 4005.4351f, 4379.4170f, 4783.9556f, 5157.1753f, 5555.1797f, 5926.6816f, 601.5123f, 1066.8242f, 1384.3585f, 1652.9448f, 1978.3910f, 2311.2676f, 2674.0537f, 3010.3896f, 3360.0623f, 3725.9336f, 4093.3335f, 4470.6431f, 4859.1006f, 5210.4717f, 5598.3716f, 5954.4204f, @@ -11907,8 +16468,267 @@ const float dico_lsf_abs_8b[256*M] = 227.3320f, 323.2667f, 752.3189f, 1572.3750f, 1930.6083f, 2355.0117f, 2717.6223f, 2968.3215f, 3233.4026f, 3551.9622f, 3918.5608f, 4346.0190f, 4778.6880f, 5159.6172f, 5568.5566f, 5980.8086f, 307.9120f, 439.7297f, 660.0276f, 1243.3854f, 1532.3577f, 1796.3936f, 2437.3232f, 2691.4072f, 3030.3025f, 3524.1379f, 3771.7576f, 4083.2375f, 4601.1567f, 4963.4697f, 5434.8530f, 5942.8315f }; - -const float lsf_cdk_nb_gc_stg1[] = +const Word16 dico_lsf_abs_8b[256 * M] = /*14Q1*1.28*/ +{ + 966, 1761, 2937, 3740, 4574, 5488, 6457, 7398, 8355, 9289, 10254, 11211, 12247, 13202, 14221, 15172, + 1540, 2731, 3544, 4232, 5065, 5917, 6846, 7707, 8602, 9538, 10479, 11445, 12439, 13339, 14332, 15243, + 1414, 2201, 3469, 4160, 4832, 5563, 6504, 7493, 8507, 9423, 10261, 11087, 12014, 12887, 13935, 15041, + 1176, 2031, 3312, 4141, 4915, 5612, 6368, 7097, 7965, 8861, 9900, 10956, 12137, 13161, 14215, 15190, + 840, 1102, 1853, 3913, 4514, 5155, 5976, 6577, 7726, 8469, 9195, 9896, 12016, 13534, 14458, 15327, + 1165, 1552, 2467, 3520, 3933, 4902, 6085, 6607, 7652, 8343, 8922, 9577, 11002, 13331, 14521, 15310, + 1113, 1431, 2280, 3471, 3975, 4853, 5690, 6407, 7275, 8032, 8621, 9884, 12276, 13033, 13880, 15039, + 719, 1036, 1867, 2553, 4352, 5021, 5775, 6505, 7179, 7826, 9601, 11113, 12075, 12807, 14022, 15272, + 953, 1294, 1952, 2553, 3007, 5085, 6062, 6718, 8178, 8712, 9927, 11330, 12351, 13205, 14164, 15087, + 940, 1283, 2111, 2792, 3256, 3911, 6096, 6898, 7589, 9317, 10103, 10891, 11893, 12886, 13757, 15049, + 587, 903, 1795, 3140, 4297, 4853, 5479, 6468, 7886, 8442, 9844, 11336, 12043, 12793, 13911, 15151, + 861, 1323, 2258, 3258, 3853, 4815, 5824, 6684, 8004, 9358, 10709, 11951, 12810, 13582, 14465, 15216, + 758, 1202, 2449, 3134, 3694, 4423, 5673, 6885, 7835, 9014, 10027, 11120, 12196, 13199, 14218, 15199, + 1042, 1478, 2150, 3726, 4263, 4954, 6139, 6790, 7965, 8974, 9643, 10764, 12030, 12725, 13557, 14581, + 719, 926, 2434, 3748, 4185, 5032, 5661, 6815, 7286, 9180, 10365, 11159, 11991, 12918, 13824, 15248, + 715, 1008, 2245, 3846, 4283, 5859, 6516, 7754, 9005, 9791, 10611, 11473, 12342, 13216, 14190, 15177, + 972, 1282, 1856, 2557, 3020, 4536, 7105, 8030, 8649, 9405, 10103, 10712, 11575, 12633, 13608, 14745, + 813, 1132, 1994, 2990, 3472, 4041, 4711, 7349, 8285, 8967, 9924, 10497, 11905, 13402, 14503, 15358, + 897, 1260, 1953, 3238, 3878, 4495, 6373, 7420, 8046, 9326, 10330, 10893, 11883, 13155, 14226, 15156, + 772, 1190, 1952, 2591, 4617, 5613, 6788, 7715, 8323, 9061, 10103, 11442, 12520, 13313, 14105, 15130, + 648, 914, 1614, 2978, 3913, 5180, 6371, 7029, 7510, 8288, 10181, 11303, 12262, 13298, 14629, 15443, + 679, 934, 1510, 2061, 4006, 5506, 6056, 6653, 7326, 8996, 10254, 11800, 12686, 13410, 14130, 15080, + 536, 802, 1288, 2431, 4428, 4896, 5421, 6396, 8409, 9756, 10509, 11135, 12212, 13338, 14298, 15284, + 774, 1064, 1751, 2361, 3813, 5723, 6272, 7170, 7837, 9027, 9999, 10677, 11383, 12564, 14005, 15142, + 678, 938, 1492, 2025, 4146, 5207, 5984, 6738, 7509, 8781, 9766, 10948, 12156, 13220, 14217, 15296, + 639, 927, 1490, 2153, 4243, 5592, 6466, 7219, 7989, 9277, 10369, 11353, 12295, 13240, 14272, 15267, + 743, 1035, 1700, 2248, 3167, 5728, 6394, 7572, 8421, 9284, 10729, 11762, 12753, 13526, 14380, 15202, + 468, 692, 1255, 2740, 4287, 5357, 6462, 7499, 8537, 9503, 10499, 11458, 12457, 13393, 14352, 15260, + 734, 989, 1478, 1957, 2947, 5157, 6144, 7370, 8090, 8834, 9907, 11183, 12331, 13280, 14246, 15263, + 461, 681, 1659, 3534, 4547, 5654, 6632, 7664, 8623, 9608, 10561, 11542, 12490, 13438, 14368, 15271, + 792, 1113, 1855, 2398, 3238, 5817, 6524, 7434, 8483, 9164, 10021, 11002, 12178, 13218, 14316, 15216, + 658, 1008, 1970, 3074, 4543, 5908, 7154, 8105, 8980, 9832, 10606, 11401, 12264, 13165, 14158, 15163, + 1009, 1541, 2392, 3464, 4644, 5562, 6666, 7588, 8538, 9554, 10547, 11489, 12487, 13412, 14326, 15206, + 955, 1704, 3142, 3903, 4985, 6046, 7112, 8024, 8864, 9606, 10417, 11275, 12242, 13171, 14188, 15188, + 1152, 2084, 3441, 4308, 5341, 6367, 7465, 8361, 9258, 10034, 10799, 11569, 12435, 13295, 14269, 15192, + 1361, 2472, 3734, 4540, 5724, 6786, 7934, 8876, 9753, 10482, 11209, 11930, 12704, 13494, 14411, 15293, + 1448, 2793, 3997, 5078, 6382, 7418, 8278, 9062, 9827, 10479, 11193, 11976, 12798, 13632, 14523, 15357, + 1488, 2499, 3704, 4557, 5499, 6512, 7628, 8636, 9720, 10662, 11547, 12425, 13250, 13991, 14754, 15490, + 1099, 2055, 3146, 3872, 4700, 5675, 6721, 7670, 8652, 9638, 10640, 11603, 12561, 13473, 14404, 15285, + 575, 841, 1577, 3091, 3894, 4777, 5587, 6225, 8293, 8937, 9666, 10986, 12135, 13292, 14164, 15178, + 799, 1086, 1834, 2360, 3186, 5166, 5756, 7271, 8036, 8703, 9532, 10239, 11731, 13180, 14418, 15362, + 956, 1297, 2021, 2413, 4341, 5175, 5948, 6783, 7304, 8114, 9024, 9853, 10910, 12746, 14094, 15167, + 1288, 1856, 2407, 3125, 3686, 4421, 5672, 6339, 7288, 8274, 9315, 10205, 11191, 12856, 14483, 15463, + 1020, 1359, 2139, 2709, 3398, 4646, 5412, 6441, 7053, 7923, 9213, 10192, 11791, 13084, 14208, 15242, + 839, 1165, 2114, 2625, 3382, 3972, 5064, 7268, 7966, 8749, 9833, 12022, 13123, 13848, 14622, 15279, + 837, 1104, 1848, 2230, 3860, 4731, 5491, 6377, 6917, 8917, 10029, 10891, 12043, 12753, 13952, 15201, + 1136, 1564, 2097, 2558, 3026, 4824, 5743, 6459, 7664, 8183, 9819, 10837, 11538, 12762, 14193, 15309, + 1013, 1492, 2105, 2593, 3135, 5090, 6278, 6877, 7559, 8026, 9120, 10257, 11268, 12899, 14253, 15324, + 677, 952, 1578, 2156, 3456, 4665, 5545, 6815, 7822, 8967, 10044, 11143, 12218, 13205, 14269, 15290, + 560, 833, 1626, 2825, 4189, 5300, 5822, 6280, 7858, 9256, 10189, 11481, 12413, 13040, 14138, 15123, + 666, 1181, 2686, 3416, 4169, 5158, 6179, 7282, 8275, 9372, 10419, 11434, 12436, 13400, 14358, 15244, + 773, 1040, 1809, 3551, 4049, 5132, 5867, 6525, 7877, 8558, 9275, 10956, 12231, 13016, 14012, 15032, + 881, 1209, 1988, 3725, 4126, 5152, 6189, 6712, 8497, 9495, 10097, 11006, 12228, 13271, 14197, 15140, + 850, 1109, 2540, 3212, 3836, 4671, 5423, 6258, 6873, 7502, 9107, 10990, 12254, 13154, 14378, 15352, + 721, 954, 2751, 3694, 4320, 5071, 5825, 6738, 7291, 7984, 9289, 11579, 12483, 13254, 14338, 15260, + 1055, 1371, 1968, 3743, 4580, 4986, 5695, 6267, 7257, 8890, 9548, 10261, 11586, 12347, 13324, 15091, + 676, 972, 2112, 2850, 3753, 4728, 5494, 6367, 7285, 8675, 9943, 11368, 12460, 13350, 14172, 15122, + 1049, 1494, 2200, 3000, 3527, 5081, 6046, 6884, 8291, 9069, 10097, 11369, 12496, 13375, 14347, 15128, + 814, 1123, 2183, 2717, 3304, 3975, 5256, 6076, 7491, 8840, 10493, 11738, 12716, 13494, 14450, 15263, + 948, 1271, 2388, 3106, 3719, 4616, 5356, 6675, 7383, 7967, 9440, 11584, 12408, 13133, 13866, 14860, + 635, 881, 1924, 3907, 4384, 5217, 5950, 6984, 7695, 8650, 9877, 11108, 12074, 13120, 14245, 15282, + 762, 1028, 2283, 3533, 3943, 4563, 5144, 6692, 7423, 8653, 9739, 10969, 12023, 13103, 14147, 15192, + 579, 854, 1748, 3347, 3979, 4734, 5418, 7056, 8203, 9063, 10246, 11271, 12279, 13293, 14338, 15258, + 503, 768, 1465, 3077, 4620, 5151, 5798, 7143, 8378, 9391, 10401, 11373, 12315, 13200, 14113, 15106, + 717, 1002, 1807, 3675, 4066, 5418, 6034, 6837, 8445, 8980, 10353, 11755, 12753, 13520, 14476, 15232, + 672, 949, 1676, 3274, 4729, 5344, 6538, 7393, 8330, 9755, 10902, 11594, 12475, 13327, 14247, 15152, + 496, 912, 2757, 3804, 4833, 5819, 6853, 7814, 8753, 9709, 10654, 11604, 12540, 13471, 14395, 15300, + 775, 1049, 2302, 3012, 3920, 4950, 5709, 7219, 7761, 9746, 10544, 11297, 12044, 12831, 13700, 15084, + 1078, 1504, 2140, 3195, 3778, 4555, 5966, 6673, 7747, 8995, 9612, 10447, 11613, 12329, 13101, 14856, + 968, 1849, 3399, 4265, 5004, 5732, 6679, 7575, 8554, 9526, 10485, 11412, 12400, 13344, 14309, 15220, + 1199, 2464, 3945, 4913, 6009, 6786, 7495, 8106, 8835, 9620, 10520, 11438, 12438, 13342, 14319, 15235, + 1081, 2165, 3828, 4637, 5448, 6070, 6800, 7534, 8434, 9349, 10320, 11262, 12293, 13218, 14232, 15192, + 1083, 1694, 2537, 3083, 3771, 5128, 6256, 7141, 8587, 9530, 10324, 11062, 11832, 12707, 13900, 15104, + 925, 1244, 2121, 3433, 3834, 5306, 6241, 6848, 8344, 9060, 9700, 10464, 11277, 12214, 14081, 15400, + 773, 1006, 1754, 4566, 5209, 5778, 6451, 7124, 8069, 8706, 9253, 10001, 10837, 12064, 14326, 15356, + 620, 950, 1866, 3048, 4740, 5460, 5977, 6457, 7915, 9271, 9868, 10687, 11496, 12237, 13203, 15016, + 1104, 1439, 2275, 2648, 3695, 5401, 5983, 7243, 7860, 8327, 8987, 11178, 12399, 13141, 14208, 14977, + 1076, 1712, 2332, 3118, 4625, 5250, 6130, 7069, 7734, 8740, 10166, 11116, 12011, 12960, 13959, 14830, + 659, 949, 1548, 2807, 4382, 4952, 5938, 7089, 7729, 8587, 10547, 11148, 11668, 12528, 13953, 15131, + 618, 891, 1593, 3197, 3993, 4733, 5928, 6583, 7372, 9278, 10158, 10852, 12066, 13201, 14256, 15298, + 1226, 1611, 2351, 3438, 3930, 4616, 6358, 6975, 7675, 9306, 10025, 10545, 11077, 12750, 14164, 15269, + 680, 957, 1852, 3036, 3864, 5284, 5883, 6570, 7132, 8763, 9943, 10590, 11425, 12827, 14180, 15184, + 567, 890, 1811, 3039, 4034, 4670, 5067, 5886, 7597, 8889, 10127, 10989, 12275, 13126, 14471, 15240, + 1017, 1306, 1912, 4065, 5098, 5506, 6244, 6943, 7610, 8963, 10029, 10608, 11375, 12363, 14054, 15433, + 718, 949, 1640, 4407, 4989, 5504, 6145, 6846, 8055, 8755, 9764, 11309, 12335, 13157, 13991, 15052, + 833, 1104, 2582, 3256, 3910, 5291, 5740, 7382, 8142, 8582, 9618, 11230, 12436, 13284, 14118, 14993, + 1157, 1491, 2370, 3490, 3848, 5022, 5800, 6591, 7995, 8564, 9304, 10921, 12495, 13372, 14254, 15054, + 1052, 1417, 2072, 2620, 3044, 4572, 5432, 6284, 7546, 8244, 9800, 10798, 12368, 13625, 14662, 15445, + 795, 1132, 1902, 2810, 3433, 4747, 5790, 6745, 8443, 9315, 10050, 10836, 11673, 12528, 13832, 15149, + 967, 1250, 2420, 3159, 3625, 4266, 4948, 7030, 7674, 8235, 9112, 9840, 11161, 12837, 14235, 15341, + 730, 997, 2113, 3171, 3737, 4764, 5577, 6449, 7240, 8394, 9116, 10604, 12009, 13102, 14231, 15244, + 1192, 1617, 2341, 3430, 4000, 4721, 5596, 6358, 7429, 8167, 8895, 9916, 10855, 12188, 13896, 15254, + 872, 1150, 2032, 3553, 3983, 4963, 5636, 6604, 7462, 8064, 9470, 10203, 11089, 12799, 14118, 15282, + 1013, 1444, 1984, 3267, 4408, 4772, 5805, 7143, 7690, 8647, 10029, 10669, 11431, 12636, 13988, 15117, + 830, 1134, 1866, 3581, 4056, 4925, 6011, 6558, 8076, 8830, 9656, 10706, 12639, 13726, 14663, 15367, + 684, 957, 1801, 3005, 3559, 4879, 5574, 6920, 7739, 8471, 9724, 10719, 12040, 13148, 14262, 15275, + 699, 1022, 2042, 3021, 3652, 5369, 6030, 7152, 8031, 8854, 9968, 10869, 11910, 13073, 14255, 15228, + 831, 1105, 1945, 3827, 4272, 5403, 6214, 6843, 8117, 8827, 9516, 10328, 11201, 12905, 14507, 15398, + 785, 1036, 2037, 4291, 4698, 5531, 6223, 7000, 8372, 9181, 9784, 10501, 11195, 12592, 13855, 15023, + 1079, 1556, 2081, 3294, 4678, 5189, 5975, 6991, 7650, 8458, 9624, 10387, 11370, 12518, 13343, 14521, + 1085, 1535, 2122, 2772, 3190, 4157, 6280, 7310, 8119, 8898, 9511, 10169, 11313, 12529, 13732, 15153, + 1130, 1625, 2359, 3044, 3504, 5151, 6102, 6755, 7616, 8099, 8791, 9828, 10718, 12434, 14231, 15302, + 894, 1194, 1854, 2315, 3048, 5073, 5700, 6637, 7336, 8181, 9563, 10924, 12316, 13331, 14349, 15237, + 1274, 1843, 2368, 2935, 3396, 4031, 5905, 6950, 7597, 8704, 9554, 10193, 11657, 13031, 13891, 14934, + 1208, 1660, 2310, 3189, 3644, 4355, 5442, 6162, 7602, 8433, 9505, 10600, 12310, 13625, 14495, 15234, + 884, 1244, 2154, 2652, 3187, 3810, 5991, 6674, 7284, 8251, 9106, 10547, 11947, 13173, 14248, 15300, + 851, 1095, 2125, 2913, 3429, 4068, 4931, 6228, 6911, 8477, 9513, 10932, 12187, 13333, 14385, 15286, + 637, 976, 2370, 3892, 4718, 6063, 7126, 8378, 9405, 10359, 11188, 12001, 12807, 13610, 14465, 15303, + 674, 1156, 3206, 3848, 4574, 5332, 6275, 7180, 7979, 8944, 9945, 11135, 12211, 13166, 14189, 15185, + 648, 874, 1620, 4523, 5335, 5818, 6480, 7079, 8024, 8654, 9320, 10068, 11602, 13428, 14329, 15293, + 602, 831, 3174, 4258, 4758, 5558, 6154, 6862, 7261, 8173, 9894, 11228, 12406, 13185, 14416, 15390, + 728, 1050, 2523, 3324, 4581, 5112, 6274, 7249, 7665, 8228, 9024, 9779, 11962, 13886, 14569, 15310, + 625, 1064, 2658, 3373, 4317, 5328, 6341, 7576, 8230, 9137, 10072, 11030, 12105, 13071, 14050, 15127, + 860, 1199, 2569, 3264, 3928, 5082, 6012, 7023, 7568, 8726, 9899, 10975, 11665, 12602, 13465, 14849, + 994, 1326, 2131, 3392, 3914, 4629, 5507, 6365, 7208, 8086, 9307, 10139, 11960, 13752, 14791, 15505, + 1297, 1723, 2304, 2955, 3528, 4575, 5330, 6141, 7321, 7873, 9079, 11066, 12114, 12781, 13485, 14866, + 1247, 1673, 2480, 3557, 4100, 4892, 5843, 6678, 7764, 8607, 9292, 10007, 11055, 11895, 12912, 14829, + 1108, 1515, 2302, 3815, 4582, 5275, 6233, 7271, 7993, 8890, 9807, 10489, 11145, 11905, 12753, 14036, + 969, 1302, 2055, 2425, 3922, 5219, 6014, 6785, 7331, 9195, 10032, 10897, 11788, 12542, 13408, 14826, + 1042, 1398, 2217, 2813, 3449, 4242, 5032, 6957, 7766, 8985, 9916, 10576, 11237, 12222, 13952, 15302, + 1099, 1456, 2313, 2814, 3532, 5651, 6349, 7119, 8208, 8769, 9427, 10112, 11070, 12005, 12975, 14815, + 952, 1343, 2279, 4277, 5014, 5588, 6550, 7259, 8172, 9304, 10112, 10905, 11848, 12798, 13734, 14852, + 827, 1155, 2015, 2590, 3389, 5575, 6147, 7237, 8788, 9352, 9943, 10452, 11166, 11866, 13017, 14908, + 965, 1342, 1904, 3530, 4756, 5265, 6282, 7430, 8006, 8866, 10189, 10858, 11593, 12497, 13413, 14286, + 791, 1033, 1807, 4669, 5445, 6065, 6777, 7311, 8217, 8955, 9594, 10171, 10891, 11711, 13024, 15079, + 703, 982, 1468, 2926, 5508, 6551, 7045, 7648, 8280, 9027, 10043, 10724, 11477, 12486, 13816, 15160, + 636, 1084, 3228, 4342, 5051, 5884, 6638, 7545, 8362, 9253, 10190, 11160, 12212, 13207, 14220, 15198, + 821, 1100, 1682, 3559, 5618, 6419, 6944, 7630, 8233, 9075, 10130, 10822, 11427, 12149, 13027, 14146, + 629, 1332, 3013, 3722, 4532, 5532, 6531, 7553, 8517, 9499, 10507, 11474, 12457, 13390, 14358, 15272, + 1317, 2450, 3297, 3892, 4613, 5418, 6425, 7337, 8291, 9245, 10282, 11346, 12442, 13393, 14373, 15268, + 1375, 2387, 3533, 4376, 5325, 6263, 7320, 8268, 9276, 10272, 11197, 12094, 13000, 13818, 14648, 15432, + 1158, 2044, 2814, 3372, 4231, 5273, 6326, 7190, 8055, 8945, 9909, 11036, 12230, 13264, 14271, 15192, + 871, 1102, 2233, 4189, 4539, 5309, 5875, 6894, 8135, 8683, 9397, 10814, 12535, 13312, 14286, 15134, + 814, 1062, 2256, 4246, 4741, 5468, 6095, 6832, 7800, 8445, 9019, 9623, 10539, 12957, 14398, 15333, + 958, 1249, 1879, 3625, 4221, 4743, 5374, 6010, 7564, 8370, 9054, 10537, 11472, 12580, 13996, 15129, + 871, 1148, 2666, 3651, 4193, 5040, 5660, 6778, 7459, 8017, 8780, 9530, 10508, 12721, 14270, 15304, + 651, 1057, 2426, 3096, 4328, 5224, 6148, 6984, 7722, 9038, 10150, 11248, 12299, 13281, 14301, 15245, + 617, 889, 2138, 4101, 4573, 5464, 6134, 7293, 8294, 9277, 10316, 11265, 12281, 13301, 14327, 15273, + 792, 1161, 2081, 2883, 3644, 5502, 6438, 7760, 8867, 9704, 10404, 11003, 11913, 13286, 14647, 15445, + 1202, 1869, 2491, 2996, 4025, 5336, 6574, 7586, 8415, 9166, 9940, 11099, 12441, 13461, 14408, 15252, + 1164, 2036, 2762, 3315, 4510, 5722, 6901, 7925, 8892, 9813, 10715, 11594, 12526, 13416, 14359, 15235, + 1442, 2242, 2916, 3528, 4751, 5836, 6787, 7599, 8395, 9235, 10177, 11157, 12208, 13147, 14145, 15115, + 1182, 2189, 3501, 4359, 5481, 6402, 7306, 7997, 8719, 9457, 10314, 11195, 12207, 13152, 14186, 15159, + 1123, 1928, 3249, 4174, 5190, 6018, 6841, 7570, 8320, 9079, 9969, 10880, 11946, 12957, 14056, 15116, + 1391, 2121, 3172, 3766, 4449, 5215, 6232, 7171, 8096, 8981, 9854, 10664, 11746, 12851, 14017, 15116, + 1330, 2144, 2998, 3489, 4141, 5059, 6328, 7427, 8552, 9564, 10505, 11379, 12290, 13173, 14193, 15189, + 1109, 1492, 2303, 2946, 3382, 4987, 6548, 6997, 8296, 9305, 9871, 10389, 11172, 13047, 14487, 15395, + 1088, 1547, 2223, 3092, 3620, 4386, 6452, 7580, 8220, 9176, 10021, 10624, 11535, 12511, 13349, 14330, + 888, 1265, 1930, 3715, 4354, 4929, 6671, 7348, 8125, 9622, 10527, 11265, 12457, 13225, 13909, 14800, + 815, 1189, 2006, 3817, 4374, 5838, 6485, 7386, 8816, 9395, 10242, 10930, 11702, 12358, 13510, 14977, + 990, 1329, 1856, 2513, 2960, 3841, 6200, 7584, 8128, 9084, 9884, 10615, 11927, 13026, 14162, 15236, + 809, 1891, 3000, 3978, 4992, 5938, 6931, 7857, 8818, 9757, 10695, 11637, 12557, 13495, 14394, 15295, + 554, 1531, 2712, 3754, 4813, 5795, 6805, 7758, 8739, 9677, 10642, 11569, 12527, 13426, 14344, 15173, + 961, 1247, 2162, 4030, 4594, 5392, 6191, 6804, 7979, 8852, 9449, 10061, 10905, 11757, 12852, 14951, + 1214, 1854, 2494, 3286, 3894, 4471, 5973, 7358, 7967, 8807, 9608, 10178, 10994, 12344, 13316, 14487, + 1024, 1446, 2069, 2773, 3329, 5327, 6627, 7318, 8209, 8780, 9592, 11114, 12066, 12765, 13662, 14618, + 907, 1229, 2135, 2657, 3456, 4585, 5614, 6412, 7107, 8072, 10517, 11769, 12447, 13038, 14011, 15186, + 608, 888, 1729, 3791, 4395, 4825, 5374, 6977, 7738, 8387, 9316, 10715, 12651, 13548, 14546, 15311, + 941, 1202, 2101, 3123, 3503, 4159, 4619, 6676, 7402, 8223, 9627, 10280, 11822, 13131, 14470, 15468, + 800, 1065, 1726, 2186, 4630, 5715, 6394, 7256, 7782, 8452, 9368, 11407, 12394, 13086, 14086, 15167, + 875, 1208, 1941, 2508, 3296, 4447, 5532, 6821, 7582, 8862, 9556, 10519, 11696, 12896, 14109, 15273, + 900, 1183, 1959, 2423, 3386, 5868, 6409, 7218, 7883, 8442, 9143, 9913, 11104, 13003, 14241, 15213, + 1115, 1573, 2286, 3113, 3574, 4645, 5519, 6311, 8196, 8937, 9864, 11290, 12252, 13043, 13810, 14631, + 754, 1068, 2679, 3694, 4190, 5008, 5606, 7347, 8013, 8864, 9972, 10786, 11627, 12824, 14010, 15316, + 825, 1144, 1765, 3426, 4206, 4874, 6385, 7180, 7946, 9319, 10153, 10682, 11276, 11957, 13415, 15087, + 537, 862, 1866, 3116, 4349, 4842, 5496, 7245, 7958, 8822, 9611, 10099, 11455, 13291, 14370, 15284, + 887, 1205, 1698, 3243, 5173, 5813, 6470, 7237, 7881, 8707, 9739, 10497, 11284, 12115, 13185, 14869, + 726, 1002, 2984, 3728, 4334, 5142, 5946, 7127, 7676, 8367, 9085, 10668, 11889, 13054, 14011, 15180, + 771, 981, 1772, 4221, 4795, 5401, 6003, 6690, 7480, 8115, 8717, 9938, 12232, 13037, 13941, 15157, + 1303, 1922, 2468, 3316, 4185, 4656, 5507, 6631, 7341, 8291, 9593, 10378, 11412, 12616, 13556, 14820, + 1080, 1403, 2477, 2954, 3741, 4642, 5517, 6582, 7111, 7805, 8786, 9547, 11253, 12874, 14045, 15236, + 872, 1141, 2386, 3209, 3896, 5042, 5805, 7002, 7549, 8285, 9036, 9939, 12031, 13030, 13767, 15055, + 728, 1046, 2013, 4276, 5230, 5799, 6889, 7772, 8535, 9890, 10949, 11702, 12791, 13661, 14459, 15218, + 768, 1578, 3171, 4134, 5114, 6061, 7128, 8112, 9139, 10152, 11101, 12005, 12913, 13736, 14586, 15387, + 622, 1221, 3202, 4279, 5529, 6753, 7808, 8631, 9408, 10115, 10830, 11631, 12512, 13365, 14324, 15263, + 621, 848, 1626, 4612, 5335, 5797, 6416, 7167, 8286, 8933, 9880, 11327, 12709, 13565, 14439, 15329, + 650, 861, 3115, 4397, 4828, 5572, 6159, 7071, 7513, 8108, 8667, 9739, 12413, 13532, 14414, 15581, + 756, 1091, 1615, 2958, 4679, 5429, 6304, 7065, 7657, 8329, 10012, 10763, 11425, 12569, 14285, 15324, + 765, 1051, 2074, 3446, 3838, 5659, 6318, 7149, 8407, 8942, 9688, 11058, 12443, 13347, 14361, 15231, + 1121, 1473, 2217, 2827, 3347, 5017, 5872, 6668, 7595, 8264, 9085, 10487, 12210, 13022, 13866, 14985, + 1056, 1457, 2212, 2861, 3453, 5060, 5976, 6759, 7697, 8519, 9461, 10348, 11169, 12000, 13798, 15274, + 1042, 1388, 2220, 3677, 4297, 5120, 6037, 6788, 7788, 8549, 9262, 10069, 10878, 11755, 14085, 15413, + 961, 1331, 1957, 3111, 3796, 4344, 5010, 5553, 7612, 9441, 10155, 10903, 11982, 12664, 13391, 14959, + 1135, 1470, 2082, 3284, 3937, 4423, 5140, 5618, 7055, 8860, 9355, 10318, 11706, 12556, 13826, 15192, + 1084, 1383, 2209, 3550, 4038, 4636, 5240, 5911, 8011, 9044, 9570, 10294, 11155, 11865, 13587, 15219, + 737, 1028, 1858, 2434, 3038, 3815, 5414, 6560, 7753, 9010, 10088, 11109, 12200, 13241, 14292, 15286, + 979, 1377, 2142, 3511, 4042, 4787, 5869, 6505, 7764, 8710, 9567, 10378, 11383, 13445, 14620, 15417, + 802, 1063, 1768, 3997, 4648, 5273, 6005, 6694, 7698, 8427, 9191, 10230, 11176, 12425, 13991, 15244, + 926, 1148, 2359, 3438, 3811, 4446, 4994, 6492, 7088, 7840, 8921, 9955, 11823, 13037, 14140, 15275, + 639, 939, 1753, 3080, 4204, 5022, 5702, 6198, 6811, 8268, 9786, 10836, 12243, 13126, 14260, 15306, + 736, 1079, 1802, 3276, 4001, 5415, 6381, 7119, 8492, 9232, 10308, 11105, 12031, 12793, 13904, 15114, + 1249, 1897, 2616, 3398, 4149, 4840, 5809, 6616, 7453, 8768, 9869, 10767, 12051, 13177, 14339, 15241, + 1026, 1314, 2014, 3249, 3690, 4344, 4892, 5691, 7289, 7970, 9397, 10615, 11663, 13015, 14272, 15328, + 970, 1249, 2342, 2895, 3661, 4685, 5348, 6691, 7176, 8850, 10323, 11025, 11936, 12697, 13429, 14816, + 872, 1155, 1680, 2334, 2880, 4439, 6448, 7088, 8221, 9517, 10060, 10691, 11577, 12830, 14274, 15377, + 874, 1131, 2067, 2714, 3203, 3786, 4480, 6643, 7487, 8708, 9861, 10989, 12079, 13208, 14240, 15290, + 804, 1079, 1708, 2236, 2842, 5275, 6096, 7030, 7886, 8704, 9978, 11354, 12923, 13800, 14706, 15380, + 646, 907, 1724, 3428, 3981, 5158, 5889, 7244, 8226, 8728, 9227, 10055, 11833, 13065, 14232, 15287, + 986, 1315, 1948, 2518, 3010, 5465, 6638, 7224, 8275, 8820, 9602, 10482, 11268, 12169, 14206, 15449, + 565, 805, 1593, 3458, 4571, 5319, 6411, 7828, 8796, 9460, 10121, 10926, 11931, 12989, 14085, 15181, + 532, 795, 1654, 3253, 3949, 5323, 6246, 7279, 8378, 9364, 10397, 11379, 12395, 13375, 14390, 15290, + 835, 1169, 1895, 2461, 3233, 5608, 6358, 7353, 8521, 9756, 10632, 11371, 12291, 12967, 13777, 14575, + 528, 840, 1585, 2511, 4342, 5075, 5825, 7183, 8370, 8938, 9529, 10614, 12398, 13483, 14482, 15340, + 789, 1044, 2065, 2677, 3589, 5397, 5969, 7559, 8126, 8638, 9332, 10989, 12645, 13441, 14355, 15188, + 685, 970, 1644, 2232, 4331, 5344, 6203, 6877, 7736, 9534, 10331, 11186, 11981, 12778, 13629, 14878, + 800, 1120, 1829, 2303, 4180, 4963, 5877, 6722, 7425, 8436, 9106, 10138, 12113, 13163, 14087, 15242, + 851, 1150, 2243, 3088, 3642, 5370, 6027, 6953, 7919, 8562, 9276, 9957, 10896, 12786, 14320, 15324, + 735, 1113, 2000, 3196, 4699, 5471, 6589, 7347, 8003, 8855, 9650, 10594, 12001, 13017, 13918, 15089, + 837, 1098, 1699, 2175, 3008, 6101, 6902, 7529, 8229, 8790, 9674, 10585, 11532, 12971, 14334, 15323, + 626, 1278, 3315, 4325, 5436, 6586, 7790, 8824, 9821, 10690, 11482, 12268, 13043, 13789, 14591, 15381, + 1439, 2612, 3825, 4715, 5881, 7098, 8204, 9129, 10075, 10889, 11673, 12416, 13159, 13897, 14672, 15420, + 1489, 2697, 3785, 4568, 5440, 6284, 7191, 8043, 8936, 9852, 10756, 11696, 12662, 13539, 14458, 15314, + 663, 932, 1850, 4514, 5042, 5800, 6482, 7381, 8674, 9537, 10447, 11239, 12074, 12975, 13958, 14969, + 695, 1028, 1781, 2195, 4548, 5142, 6539, 7282, 7728, 8259, 8915, 9755, 11646, 13482, 14373, 15221, + 846, 1138, 1713, 2239, 2823, 5254, 6237, 6940, 7777, 8443, 9981, 10858, 11793, 13022, 14259, 15331, + 595, 882, 1481, 3108, 4815, 5391, 5979, 6529, 8058, 8939, 9706, 10649, 11884, 13065, 14350, 15334, + 887, 1139, 1829, 2276, 3102, 5552, 6221, 7067, 7712, 8368, 9127, 10682, 12241, 13127, 14112, 15133, + 1019, 1418, 2165, 2865, 3353, 4937, 6019, 6784, 7810, 8440, 9197, 10025, 12092, 13614, 14602, 15352, + 951, 1206, 2295, 3066, 3586, 4125, 4780, 7215, 7687, 8320, 9079, 10918, 12519, 13503, 14488, 15224, + 847, 1149, 2069, 2504, 4231, 5041, 6034, 6862, 7321, 7882, 8765, 10837, 12433, 13022, 13809, 15203, + 829, 1111, 2677, 3505, 3999, 5080, 5694, 7033, 7667, 8302, 8963, 10297, 12410, 13340, 14485, 15373, + 908, 1284, 2182, 2613, 3944, 5116, 5768, 7284, 7825, 8461, 10123, 11755, 12583, 13368, 14195, 15053, + 930, 1215, 2323, 2834, 3500, 4216, 5200, 5956, 6576, 7757, 9998, 10921, 12073, 12844, 14003, 15254, + 973, 1343, 2164, 3265, 3733, 4538, 5294, 6469, 7850, 8468, 9747, 10750, 11398, 12428, 13990, 15226, + 952, 1239, 1992, 3093, 3498, 4156, 4605, 5695, 7946, 8668, 9684, 11027, 12029, 13102, 14093, 15158, + 558, 828, 1638, 2628, 3361, 4827, 6046, 7182, 8226, 9297, 10326, 11331, 12343, 13333, 14312, 15248, + 543, 797, 1292, 2197, 4031, 4954, 6096, 7133, 8292, 9244, 10253, 11267, 12293, 13293, 14303, 15272, + 562, 818, 1546, 2854, 3792, 5212, 5897, 6697, 8329, 9105, 10103, 11572, 13033, 13866, 14716, 15223, + 897, 1320, 1937, 2717, 3205, 4412, 6880, 7773, 8381, 9585, 10492, 11242, 12589, 13425, 14212, 15053, + 798, 1174, 2038, 2482, 3869, 4999, 5820, 7157, 7807, 9160, 10013, 11078, 12122, 13113, 14028, 14997, + 686, 1000, 2269, 3020, 3755, 5347, 5960, 7664, 8406, 9199, 10485, 11521, 12512, 13361, 14217, 15144, + 715, 1058, 1660, 3282, 4591, 4997, 6361, 7315, 7878, 9084, 10356, 11033, 12186, 13333, 14390, 15279, + 784, 1087, 1584, 3299, 5404, 6007, 6611, 7254, 7870, 8870, 10201, 10911, 11780, 12799, 14077, 15156, + 664, 905, 1952, 4880, 5346, 5934, 6519, 7374, 8530, 9311, 10103, 10819, 11525, 12818, 14071, 15168, + 626, 914, 2854, 4227, 4737, 5634, 6361, 7354, 7918, 8636, 9491, 10701, 11785, 13139, 14220, 15292, + 1793, 3491, 4468, 5330, 6092, 6716, 7382, 8023, 8852, 9777, 10729, 11640, 12576, 13418, 14323, 15182, + 688, 949, 1560, 3990, 5022, 5519, 6194, 6798, 8071, 8773, 9515, 10514, 12712, 13784, 14609, 15400, + 783, 1014, 2824, 3542, 4129, 4903, 5606, 6542, 6965, 7778, 10053, 10913, 11995, 12759, 13498, 15320, + 753, 1093, 2085, 2706, 4391, 5134, 5930, 6777, 7408, 8184, 9523, 10719, 12392, 13543, 14552, 15277, + 920, 1325, 2067, 2928, 3400, 4646, 5913, 6704, 8091, 8819, 9941, 10843, 12080, 13740, 14761, 15449, + 618, 961, 2096, 3325, 4242, 5555, 6567, 7721, 8801, 9891, 10891, 11871, 12871, 13717, 14555, 15310, + 826, 1165, 2466, 3876, 4364, 5723, 6461, 7667, 8417, 9095, 9913, 10755, 11704, 12971, 14239, 15196, + 1056, 1577, 2885, 3726, 4232, 5031, 5736, 6842, 8006, 8903, 10198, 11414, 12536, 13409, 14359, 15205, + 876, 1205, 2453, 3059, 3652, 4312, 5617, 6518, 7542, 8743, 9363, 11286, 13049, 13835, 14643, 15303, + 763, 990, 2805, 3723, 4228, 4936, 5628, 6613, 7058, 7705, 8476, 10130, 11974, 13113, 14180, 15342, + 857, 1152, 1913, 3994, 4629, 5137, 6183, 6861, 7722, 9347, 10177, 10777, 11599, 13112, 14298, 15264, + 656, 1269, 3434, 4621, 5637, 6438, 7220, 7942, 8741, 9612, 10517, 11433, 12435, 13354, 14316, 15237, + 1359, 2605, 3748, 4758, 6042, 7092, 7952, 8651, 9338, 9974, 10723, 11579, 12528, 13418, 14397, 15297, + 1529, 3067, 4410, 5449, 6449, 7233, 7901, 8525, 9237, 10002, 10859, 11784, 12730, 13589, 14467, 15300, + 1790, 3311, 4192, 4897, 5538, 6210, 6922, 7697, 8597, 9590, 10560, 11494, 12426, 13283, 14229, 15138, + 1252, 2359, 3404, 4211, 5155, 6055, 7030, 7899, 8850, 9793, 10761, 11714, 12674, 13565, 14489, 15352, + 590, 998, 2402, 3314, 4528, 5604, 6649, 7644, 8508, 9487, 10408, 11383, 12335, 13276, 14293, 15243, + 727, 1025, 1614, 3818, 5876, 6391, 6980, 7606, 8211, 9304, 10696, 11324, 12381, 13241, 13988, 14791, + 621, 899, 2068, 4152, 5232, 6483, 7323, 8193, 8960, 9627, 10417, 11291, 12234, 13192, 14216, 15187, + 582, 828, 1926, 4025, 4942, 6029, 6957, 7599, 8278, 9093, 10032, 11126, 12233, 13209, 14256, 15311, + 788, 1126, 1690, 3183, 3923, 4599, 6240, 6890, 7758, 9022, 9656, 10453, 11779, 12706, 13913, 15214 +}; + +const float lsf_cdk_nb_gc_stg1_flt[] = { -50.2820f, -20.3699f, -85.9016f, -168.2552f, -219.7203f, -228.3721f, -209.7385f, -115.7139f, -70.1936f, 2.9143f, 53.7331f, 204.0881f, 324.2565f, 283.0311f, 194.2415f, 55.6127f, -7.7024f, 55.3216f, 40.0302f, -2.6173f, -31.0254f, -49.9638f, -89.5104f, -79.9710f, -100.2947f, -84.2426f, -89.8130f, -44.4505f, 8.1330f, 123.3018f, 115.2609f, 17.5947f, @@ -11944,7 +16764,7 @@ const float lsf_cdk_nb_gc_stg1[] = -2.1387f, 144.6784f, 257.4241f, 293.7984f, 302.9054f, 301.4404f, 234.6555f, 199.2878f, 117.8049f, 82.4572f, 28.1316f, 27.9394f, -20.8952f, -53.5108f, 47.9862f, -3.2292f }; -const float lsf_cdk_nb_gc_stg2[] = +const float lsf_cdk_nb_gc_stg2_flt[] = { -11.7897f, -34.0201f, -78.3915f, -67.4130f, 11.6646f, 27.0897f, -25.4365f, -16.9519f, 1.3623f, -14.4721f, -40.8934f, -28.8082f, @@ -11964,7 +16784,7 @@ const float lsf_cdk_nb_gc_stg2[] = 121.0591f, 124.7827f, 86.3632f, 52.5283f, 25.7588f, 2.2977f }; -const float lsf_cdk_nb_gc_stg3[] = +const float lsf_cdk_nb_gc_stg3_flt[] = { -20.1057f, -62.1359f, -90.9211f, -83.2088f, -41.8080f, 4.3801f, 64.9293f, 55.2259f, 18.8953f, 8.4560f, -12.4851f, -29.8479f, -46.3014f, -59.0597f, -57.9280f, -55.5646f, -16.2912f, 29.7501f, 6.4438f, 1.9289f, @@ -11984,7 +16804,7 @@ const float lsf_cdk_nb_gc_stg3[] = 62.0530f, 98.1263f, 103.5605f, 86.5243f, 56.8051f, 24.7345f, -16.4333f, -39.4116f, -16.3685f, -5.1868f }; -const float lsf_cdk_nb_vc_stg1[] = +const float lsf_cdk_nb_vc_stg1_flt[] = { -47.8739f, -33.3324f, -111.7403f, -187.1021f, -217.8067f, -211.2333f, -197.1951f, -112.5993f, -54.4085f, 25.6601f, 103.3922f, 273.8963f, 384.4787f, 321.9756f, 214.8825f, 64.7502f, 5.7213f, 62.0822f, 4.1813f, -75.3379f, -130.0791f, -169.8000f, -137.2333f, -8.1913f, 9.1551f, 12.5919f, -10.2666f, 24.1670f, 78.8903f, 170.0603f, 136.5900f, 28.5131f, @@ -12020,7 +16840,7 @@ const float lsf_cdk_nb_vc_stg1[] = 267.3715f, 336.4754f, 224.6896f, 104.9689f, 104.5109f, 94.7971f, -20.0482f, -88.9197f, -142.8754f, -60.7279f, 30.3207f, 189.5033f, 335.5709f, 295.5561f, 200.0838f, 57.2552f }; -const float lsf_cdk_nb_vc_stg2[] = +const float lsf_cdk_nb_vc_stg2_flt[] = { -9.6827f, -17.9738f, -44.2587f, -53.7409f, 10.1005f, 32.4057f, -29.5803f, -35.3673f, -50.3175f, -49.1053f, -47.5762f, -37.2894f, @@ -12040,7 +16860,7 @@ const float lsf_cdk_nb_vc_stg2[] = 91.6464f, 85.0063f, 63.6020f, 55.1679f, 36.0606f, 12.7997f }; -const float lsf_cdk_nb_vc_stg3[] = +const float lsf_cdk_nb_vc_stg3_flt[] = { -16.5483f, -67.8691f, -113.3476f, -92.9768f, -18.1549f, 21.7013f, 31.7869f, 25.1431f, 9.0112f, 3.4920f, -7.8375f, -22.7162f, -45.0895f, -61.3419f, -64.4643f, -67.3643f, -44.8953f, -6.2556f, -7.9342f, -3.9490f, @@ -12060,7 +16880,7 @@ const float lsf_cdk_nb_vc_stg3[] = 94.3797f, 104.2925f, 88.4585f, 69.5855f, 42.3052f, 34.1349f, 37.9570f, 35.2368f, 16.3058f, 7.4056f }; -const float lsf_cdk_wb_gc_stg1[] = +const float lsf_cdk_wb_gc_stg1_flt[] = { -21.1721f, -6.9787f, -78.7739f, -158.7331f, -205.5198f, -259.2706f, -287.6161f, -271.9965f, -264.8213f, -231.0206f, -194.9294f, -147.7609f, -117.1413f, -85.8077f, -63.7689f, -31.4680f, -66.9546f, -30.5144f, -36.8376f, -53.0491f, -36.1642f, -48.5647f, -62.2295f, -55.2760f, -57.6386f, -55.8977f, -55.9952f, -40.6957f, -43.2573f, -33.7185f, -37.3113f, -27.4703f, @@ -12096,7 +16916,7 @@ const float lsf_cdk_wb_gc_stg1[] = 59.8885f, 245.4498f, 371.2458f, 409.7723f, 455.9382f, 450.3678f, 424.1982f, 412.1477f, 364.9408f, 325.9947f, 285.4946f, 257.5709f, 202.0349f, 150.8332f, 79.0164f, 39.6259f }; -const float lsf_cdk_wb_gc_stg2[] = +const float lsf_cdk_wb_gc_stg2_flt[] = { -30.3104f, -56.7575f, -84.1487f, -72.1960f, -22.8352f, 3.3243f, -46.3791f, -58.1840f, -25.7428f, -7.3327f, -15.5902f, -11.0671f, @@ -12116,7 +16936,7 @@ const float lsf_cdk_wb_gc_stg2[] = 103.2615f, 89.8720f, 41.6101f, 14.5203f, 4.9658f, -6.6327f }; -const float lsf_cdk_wb_gc_stg3[] = +const float lsf_cdk_wb_gc_stg3_flt[] = { -41.3186f, -87.9369f, -117.0141f, -113.4593f, -76.4138f, -35.5126f, -13.8432f, -7.5581f, -3.0880f, 2.3802f, -19.0684f, -32.7726f, -38.9479f, -44.5597f, -48.0524f, -54.3931f, -59.1547f, -53.0509f, -42.1806f, -24.7633f, @@ -12136,7 +16956,7 @@ const float lsf_cdk_wb_gc_stg3[] = -40.9082f, -17.6764f, 44.9914f, 99.5556f, 123.8320f, 129.2527f, 119.7749f, 99.9787f, 72.9475f, 42.1147f }; -const float lsf_cdk_wb_vc_stg1[] = +const float lsf_cdk_wb_vc_stg1_flt[] = { -28.5460f, -28.7607f, -132.3446f, -253.0434f, -312.8796f, -342.8824f, -300.5386f, -244.2990f, -209.7251f, -159.5373f, -112.6287f, -67.3791f, -48.8219f, -29.0922f, -22.2704f, -4.3572f, -46.5981f, -22.9649f, -50.9384f, -55.9409f, -47.4823f, -67.2740f, -93.7612f, -98.1688f, -103.5437f, -102.1144f, -101.9471f, -86.9149f, -76.1870f, -53.2461f, -51.2004f, -39.3148f, @@ -12172,7 +16992,7 @@ const float lsf_cdk_wb_vc_stg1[] = 179.5714f, 241.9845f, 193.4582f, 112.7762f, 108.6980f, 80.4323f, 56.9618f, 58.6676f, 36.2938f, 12.8297f, 4.7285f, 10.9217f, 12.0551f, 12.0937f, 1.6504f, -14.7259f }; -const float lsf_cdk_wb_vc_stg2[] = +const float lsf_cdk_wb_vc_stg2_flt[] = { -4.8704f, -25.4945f, -63.8565f, -65.1017f, -4.5396f, 12.9750f, -51.6246f, -71.2351f, -70.8930f, -49.5365f, -41.5492f, -21.1764f, @@ -12192,7 +17012,7 @@ const float lsf_cdk_wb_vc_stg2[] = 63.2733f, 65.6975f, 59.3910f, 57.9345f, 46.9389f, 25.4049f }; -const float lsf_cdk_wb_vc_stg3[] = +const float lsf_cdk_wb_vc_stg3_flt[] = { -32.9020f, -78.5896f, -107.4534f, -95.7731f, -74.7222f, -53.0220f, -21.3706f, -6.3135f, 4.4667f, 8.3786f, -55.7273f, -51.1982f, -23.4921f, -31.8303f, -40.9730f, -44.0985f, -32.5056f, -19.4304f, -11.2363f, -6.8031f, @@ -12212,7 +17032,312 @@ const float lsf_cdk_wb_vc_stg3[] = 46.4076f, 80.4091f, 88.4039f, 96.0474f, 97.7032f, 96.0620f, 87.9680f, 71.7615f, 52.3257f, 28.0991f }; -const float * const lsf_codebook[2][2][TCXLPC_NUMSTAGES] = +const float * const lsf_codebook_flt[2][2][TCXLPC_NUMSTAGES] = +{ + { + { lsf_cdk_wb_gc_stg1_flt, lsf_cdk_wb_gc_stg2_flt, lsf_cdk_wb_gc_stg3_flt }, + { lsf_cdk_wb_vc_stg1_flt, lsf_cdk_wb_vc_stg2_flt, lsf_cdk_wb_vc_stg3_flt } + }, + { + { lsf_cdk_nb_gc_stg1_flt, lsf_cdk_nb_gc_stg2_flt, lsf_cdk_nb_gc_stg3_flt }, + { lsf_cdk_nb_vc_stg1_flt, lsf_cdk_nb_vc_stg2_flt, lsf_cdk_nb_vc_stg3_flt } + } +}; + +const Word16 lsf_cdk_nb_gc_stg1[] = /* 14Q1*1.28 */ +{ + -2046, -827, -3490, -8984, -9331, -8562, -2854, 112, 2194, 13294, 11592, 7952, + -294, 2271, 1647, -1260, -2029, -3649, -4081, -3432, -3649, 333, 5042, 4720, + -1209, 984, -241, -3413, -4476, -4817, -2910, -2016, -2016, 2900, 6868, 5408, + -1900, 896, 688, -197, -33, -993, -1470, -1283, -2145, -665, 2161, 4064, + -1998, -351, -1985, -4742, -4879, -5329, -3500, -2023, -1264, 8507, 9766, 6640, + 245, 3962, 3664, 1935, 1601, 144, -1054, -1236, -2225, -2647, -3746, 1695, + -3051, -1382, -1825, 828, 2537, 1872, 957, 689, -592, 1675, 5507, 5216, + -2178, -281, 2097, 5417, 4372, 1648, -802, -1304, -2817, -754, 3345, 4224, + -3400, -2402, -4098, -3148, -2066, -1985, -558, 466, 705, 11042, 11096, 7424, + 776, 4355, 3200, -1139, -2922, -3985, -2990, -2405, -2881, -661, 2897, 4176, + -1818, 394, -385, -1504, -1545, -2913, -3062, -2451, -2609, 2093, 6387, 5248, + -1081, 2069, 1952, 1345, 1649, 64, -1394, -1526, -2577, -2051, -1025, 2863, + 276, 2780, 1567, -3228, -4881, -5970, -4363, -3523, -3089, 3447, 7300, 5456, + 1917, 6445, 5552, 2069, 684, -1233, -2371, -2377, -3409, -1635, 1616, 3648, + -2734, -1049, -2001, -1927, -1908, -2273, -1294, -652, -944, 4451, 7893, 5888, + -1193, 2108, 5153, 7875, 8214, 6145, 2891, 2001, 208, -1312, -2273, 1599, + -3697, -3538, -6739, -7238, -4524, -2464, 2424, 4591, 6098, 15691, 13066, 8912, + -352, 2108, 847, -247, 1179, -769, -2757, -2873, -3713, 203, 4994, 4688, + -1185, 1565, 703, -1788, -2372, -2721, -1951, -1554, -2129, -374, 2529, 4192, + -2094, 401, 352, 1118, 2376, 1632, 582, 351, -1009, -1389, -784, 3056, + -367, 1637, -145, -5132, -6888, -8178, -5371, -3397, -1776, 9469, 9894, 6752, + 953, 5894, 6785, 5196, 4663, 2400, 31, -598, -2065, -2581, -2786, 1743, + -2637, -1222, -560, 5363, 6867, 5329, 2192, 1264, -544, -508, 1345, 3664, + -1112, 1918, 2976, 3989, 4508, 3104, 1245, 606, -897, -2381, -4258, 1119, + -1983, -328, -2930, -6112, -1802, 144, 486, 194, -960, 4066, 7797, 5872, + 648, 3526, 3104, 562, -200, -2177, -3380, -3162, -3857, -1516, 2433, 3920, + -2908, -722, -417, -181, 290, -352, -352, -175, -1088, 1689, 5603, 5184, + -536, 2771, 2064, 10, -643, -1793, -1733, -1523, -2193, -1813, -1585, 2831, + 2239, 5541, 4400, -637, -2370, -4802, -5148, -3901, -2912, 7328, 9222, 6320, + 8159, 12344, 9921, 5311, 4611, 2480, -1461, -1819, -2032, 5438, 7396, 5968, + -3908, -2998, -3105, 1031, 2171, 1952, 2012, 1982, 1280, 8825, 10343, 7056, + -80, 5935, 10546, 12414, 12351, 9601, 4823, 3380, 1152, -840, -2161, 1967 +}; +const Word16 lsf_cdk_nb_gc_stg2[] = /* 14Q1*1.28 */ +{ + -476, -1387, -3185, 464, 1104, 0, + -1029, -675, 63, -1664, -1168, 0, + -691, -1002, -1697, -1968, -704, 0, + -957, -724, -945, 816, 928, 0, + -1131, -2087, -1296, 2704, 1376, 0, + -1167, -1003, 512, 592, 192, 0, + 492, 517, -721, -3600, -1888, 0, + 489, -147, -1153, -688, -864, 0, + 865, 179, -608, 2000, 1008, 0, + -1286, -1953, -1633, -304, -368, 0, + 2033, 1593, -369, -576, 272, 0, + -718, 685, 751, -192, 192, 0, + 1394, 1172, 1520, -480, -576, 0, + -1455, -466, 2896, 2176, 896, 0, + -1171, 324, 2512, -272, -496, 0, + 4950, 5112, 3536, 1040, 80, 0 +}; +const Word16 lsf_cdk_nb_gc_stg3[] = /* 14Q1*1.28 */ +{ + 1, 6, -801, -3701, -3408, -1712, 2661, 2257, 768, + 4, 11, -481, -1886, -2409, -2353, -652, 1216, 256, + 14, 6, -1713, -1706, -1012, -817, -1158, -369, -97, + 8, 15, 127, -780, -1241, -1617, -2819, -1474, -577, + 13, 6, 2320, 103, -1175, -1681, 297, 1536, 384, + 4, 14, -529, -319, -161, -129, -2113, -4131, -1281, + 0, 5, -2001, -1650, -185, 1040, 2146, 1713, 736, + 12, 4, 320, 1615, 1634, 1376, -1700, -4675, -1697, + 15, 13, -401, -348, -511, -320, 2570, 2865, 944, + 7, 14, 335, -1107, -768, -112, -338, -65, 15, + 13, 15, -1025, 563, -38, -865, -1105, 383, 31, + 4, 6, 1056, 1034, 443, -289, -2357, -1986, -689, + 7, 6, 1008, 1608, 1329, 816, 730, 1312, 432, + 4, 12, -1281, 789, 1794, 1328, -517, -561, -113, + 12, 4, 704, 1656, 2289, 3153, 5215, 3682, 1680, + 11, 15, 2528, 4255, 3539, 2320, -669, -1585, -641 +}; +const Word16 lsf_cdk_nb_vc_stg1[] = /* 14Q1*1.28 */ +{ + -1950, -1358, -4562, -8912, -8626, -8050, -2211, 1051, 4226, 15749, 13194, 8800, + 224, 2532, 175, -5316, -6930, -5601, 381, 515, -416, 3224, 6964, 5584, + -2481, -1570, -3746, -3444, -3066, -3665, -2328, -929, -256, 10781, 10903, 7280, + -164, 2676, 1952, 1170, 1362, 32, -809, -978, -1793, -2288, -3137, 2287, + -1649, -589, -3746, -9056, -6586, -2160, 1693, 1869, 1072, 8982, 10375, 7056, + -1442, 731, -465, -352, 881, 0, -1397, -1476, -2273, -792, 2209, 4048, + -570, 1125, -577, -4067, -5011, -6130, -4457, -3228, -2464, 7796, 9414, 6432, + 314, 2780, 1599, -2442, -4050, -5762, -4680, -3747, -3169, 3706, 7556, 5568, + -3306, -3212, -6178, -5257, -2978, -2209, 33, 2038, 3490, 15396, 13130, 8704, + -303, 2334, 927, -1025, -1877, -2753, -1964, -1602, -2145, -943, 1457, 3872, + -1437, 228, -1633, -3020, -3188, -2833, -1579, -942, -1184, 2482, 6532, 5408, + 2622, 6487, 4448, 511, -1383, -2769, -2495, -2230, -2977, -107, 4082, 4480, + -1897, -706, -2994, -2432, 566, 704, 220, 99, -608, 3533, 7300, 5744, + -2605, -1419, -1376, 1700, 1217, 112, -957, -849, -1633, 1902, 6131, 5296, + 2177, 3621, 751, -6700, -10534, -11698, -2205, 713, 3954, 15329, 12986, 8656, + 7156, 9030, 4704, 653, -2345, -6178, -4996, -1616, 1762, 14213, 12329, 8272, + -997, 238, -2066, -5868, -6868, -7474, -4302, -2171, -623, 12371, 11336, 7600, + 2585, 4011, 959, -298, 477, -353, -2457, -2786, -3233, 5865, 8693, 6064, + -2145, -680, -1553, -1961, -2011, -3249, -3184, -2317, -1968, 5674, 8613, 6080, + 675, 4202, 4128, 2060, 1483, -865, -2647, -2552, -3377, -2094, 64, 3184, + -3084, -2915, -5698, -905, 1626, 2176, 1517, 1566, 1024, 9339, 10663, 7232, + -741, 1377, 1168, 206, 185, -1601, -3079, -2936, -3553, -265, 4402, 4528, + 872, 3048, 799, -4039, -5660, -7890, -7222, -4564, -1792, 10306, 10311, 6992, + 2766, 6132, 4848, -1357, -2881, -4914, -4864, -3528, -2608, 9503, 10134, 6832, + -1649, -1598, -6691, -10943, -5664, -3632, 2663, 6788, 11044, 19895, 15933, 10416, + 530, 3138, 2560, -401, -1453, -3425, -4047, -3463, -3713, 252, 4914, 4672, + -879, 1210, 47, -2253, -2732, -3777, -3689, -2947, -2833, 2110, 6499, 5232, + 5749, 8736, 6865, 3519, 2447, 383, -1446, -1459, -2385, 970, 4146, 4560, + -2556, -1914, -3969, 3390, 7938, 6305, 1777, 560, -928, 1091, 4563, 4928, + -1808, -411, 1313, 6469, 6395, 3680, 398, -149, -1713, -1588, 832, 3360, + 3630, 5517, 2479, -2938, -6552, -10675, -4951, -545, 1441, 13744, 12041, 8080, + 10956, 13776, 9201, 4285, 3873, -801, -5835, -2466, 1233, 13746, 12105, 8192 +}; +const Word16 lsf_cdk_nb_vc_stg2[] = /* 14Q1*1.28 */ +{ + -377, -729, -1793, 400, 1312, 0, + -1197, -1432, -2033, -1936, -1520, 0, + -403, -100, 127, -3232, -3456, 0, + 555, 364, -865, -592, -1264, 0, + -1136, -1968, -2640, 4448, 3824, 0, + -1539, 94, 591, 1600, 1376, 0, + -1564, -393, 2528, -304, -688, 0, + 1075, 823, 1648, -96, -704, 0, + -770, -404, 527, -1648, 64, 0, + -1320, -1678, -1072, 48, -688, 0, + 145, 83, -1089, -3632, -448, 0, + 1994, 1756, 159, 1120, 1504, 0, + 282, -236, -800, 2080, 624, 0, + -1357, -1537, 1008, 2624, 1360, 0, + 2002, 2046, 1215, -2336, -1808, 0, + 3757, 3480, 2592, 1472, 512, 0 +}; +const Word16 lsf_cdk_nb_vc_stg3[] = /* 14Q1*1.28 */ +{ + 3, 5, -657, -4633, -3805, -736, 1304, 1024, 368, + 6, 12, -305, -1836, -2507, -2625, -1818, -241, -305, + 6, 4, -2577, -1854, -1236, -1073, -594, 207, -1, + 2, 2, -80, 643, 38, -993, -3719, -1602, -769, + 13, 10, -625, -1825, -2422, -2449, 2887, 2625, 784, + 6, 0, -336, 315, 466, 560, -2183, -4867, -1345, + 10, 7, -2625, 1255, 2305, 1296, 181, 544, 208, + 0, 7, 912, 1998, 1662, 623, -416, 256, 32, + 10, 6, -1713, -1720, -311, 1408, 2066, 1585, 672, + 7, 11, 15, -1217, -99, -33, -851, -33, -81, + 12, 0, -1680, 556, -499, -897, 454, 896, 256, + 2, 8, 2608, 425, -938, -1937, -1205, 15, -177, + 6, 2, 1504, -796, -939, 80, 2179, 1777, 672, + 3, 13, 1984, 3517, 3171, 2320, -2605, -5651, -1857, + 14, 2, -160, 1660, 2380, 2832, 2924, 2097, 992, + 10, 0, 3857, 3623, 2853, 1728, 1554, 1441, 656 +}; +const Word16 lsf_cdk_wb_gc_stg1[] = /* 14Q1*1.28 */ +{ + -854, -266, -3202, -8408, -10604, -11763, -10826, -9448, -7970, -4784, -3493, -2593, + -2727, -1241, -1489, -1469, -1977, -2529, -2344, -2279, -2273, -1750, -1365, -1505, + -728, 1001, -113, -1594, -2256, -3553, -4619, -4591, -4497, -3300, -2327, -2129, + -590, 1699, 1264, 1187, 300, -865, -1554, -1669, -1649, -1202, -837, -1169, + -1612, -578, -2546, -5013, -6155, -6834, -6779, -6002, -5506, -3988, -2968, -2625, + -1725, 1072, 1280, 74, 277, 672, 1385, 2172, 2688, 2643, 2065, 848, + -86, 3639, 3824, 1931, 2115, 1120, 338, 500, 496, 751, 718, -65, + -1024, 1647, 5377, 9202, 8763, 7665, 5376, 4447, 3824, 2803, 2000, 608, + -2585, -2600, -6211, -11489, -11790, -10322, -5788, -3684, -2289, -465, -33, -289, + -3165, -2478, -3521, -1181, 298, 1632, 2160, 2107, 2272, 2075, 1407, 319, + 1275, 3587, 2848, 570, -26, -1489, -4034, -4818, -5202, -3732, -2550, -2049, + -2614, -1530, -848, 4992, 6996, 8002, 9185, 9172, 9106, 7739, 5862, 3408, + 440, 2263, 751, -3627, -4674, -4978, -4938, -5078, -5554, -5428, -4266, -3361, + -2308, -80, 176, 2603, 3871, 3792, 3219, 2667, 2480, 2189, 1405, 95, + 2569, 6546, 6257, 3885, 2438, 1504, 1431, 1319, 1392, 1337, 942, -65, + -712, 3328, 6290, 10673, 12635, 13827, 14544, 13939, 13619, 10691, 8026, 4768, + 842, 2338, 159, -5945, -8498, -9619, -8197, -7076, -6066, -4502, -3722, -3409, + -1628, 617, -129, -1907, -2194, -1505, -95, 486, 928, 1268, 1071, 175, + 538, 3277, 2111, -1606, -3194, -3553, -2105, -1604, -1393, -974, -740, -1009, + -1279, 456, 2593, 6823, 5435, 3536, 1502, 544, -96, -521, -548, -1105, + -983, 675, -865, -4388, -5936, -5697, -3245, -2211, -1633, -519, -276, -849, + -102, 3506, 2480, 332, -670, -448, 859, 1384, 1776, 1846, 1568, 448, + 270, 5022, 5136, 4435, 4546, 4305, 4185, 4385, 4337, 3659, 2785, 1152, + 216, 5449, 10098, 11459, 11060, 9922, 8139, 7175, 6289, 4794, 3394, 1600, + -3137, -3309, -5826, -6310, -5500, -4385, -2187, -1054, -288, 502, 527, -129, + -2997, -2031, -1344, 2452, 2535, 1856, 912, 451, 272, -124, -515, -993, + 3808, 7001, 5536, 908, -807, -1665, -2041, -2232, -2449, -2206, -1782, -1905, + -1117, 2493, 3616, 4843, 5755, 6273, 6815, 6906, 6769, 5801, 4580, 2528, + 2509, 4911, 3439, -2294, -4945, -7203, -9006, -7957, -6818, -4297, -3321, -3009, + -1110, 1877, 1776, 2112, 2398, 2704, 3465, 3938, 4257, 4039, 3202, 1568, + 7131, 11568, 10626, 7755, 6467, 5073, 4839, 4543, 4128, 3206, 2160, 912, + 2457, 10049, 15204, 18687, 18433, 17364, 14947, 13353, 11682, 8277, 6182, 3232 +}; +const Word16 lsf_cdk_wb_gc_stg2[] = /* 14Q1*1.28 */ +{ + -1224, -2316, -3425, -928, 128, 0, + -1874, -2354, -1025, -624, -448, 0, + -1026, -888, -481, -2352, -1024, 0, + 838, 174, -2306, -4048, -960, 0, + -1336, -2679, -1776, 2464, 1200, 0, + 497, 2649, 3536, 1344, 320, 0, + -1099, 4, 2448, -544, -752, 0, + 993, 486, 592, 64, -480, 0, + 288, -551, -2385, 1824, 2016, 0, + -1090, -815, 128, 1008, 704, 0, + 279, -579, -1729, -560, -832, 0, + 60, 1211, 543, -288, 272, 0, + 480, 1062, 560, 3152, 1680, 0, + -1276, -672, 2961, 2704, 1200, 0, + 1357, 1787, 767, -3424, -2768, 0, + 4229, 3682, 1696, 192, -256, 0 +}; +const Word16 lsf_cdk_wb_gc_stg3[] = /* 14Q1*1.28 */ +{ + 15, 1, -1665, -4778, -4630, -3105, -554, -304, -112, + 13, 10, -753, -1579, -1817, -1953, -2415, -2148, -1697, + 8, 15, 1135, -1716, -3415, -5154, -4958, -3443, -1905, + 4, 1, -32, 570, 443, -65, -2187, -2759, -2561, + 4, 14, 399, -979, -269, 816, 385, -194, -673, + 2, 5, -2161, -1600, -401, -97, -412, -433, -321, + 0, 15, 2128, 3449, 1993, 175, -2815, -2580, -1729, + 3, 2, 400, 714, 1209, 1904, 2711, 2436, 1840, + 9, 13, 143, -1925, -2694, -2545, 358, 930, 960, + 10, 0, -960, 868, 173, -513, -97, 577, 896, + 0, 5, 1824, 11, -1080, -1761, -1565, -1058, -705, + 7, 1, -880, 2304, 2790, 2384, 573, -18, -273, + 5, 8, 1840, 1467, 978, 768, 598, 351, -17, + 6, 7, -1473, -2052, -711, 992, 3166, 2788, 2080, + 7, 12, 1856, 3557, 3483, 3184, 2417, 1923, 1408, + 3, 13, -1649, 1850, 4068, 5073, 4907, 4086, 2976 +}; +const Word16 lsf_cdk_wb_vc_stg1[] = /* 14Q1*1.28 */ +{ + -1159, -1161, -5395, -12785, -14024, -12291, -8572, -6523, -4593, -1979, -1169, -897, + -1903, -921, -2065, -1931, -2752, -3825, -4238, -4174, -4145, -3108, -2167, -2081, + 522, 1696, -513, -6103, -8611, -9571, -9024, -8617, -7826, -5631, -4489, -3761, + -1839, -544, -1280, 1080, 564, 752, 844, 1110, 1344, 1185, 1039, 63, + -2685, -2538, -5074, -6161, -6745, -6738, -5709, -4457, -3377, -1830, -1188, -1185, + -3059, -3565, -6706, -3405, -1183, -272, -112, 33, 160, -5, 13, -721, + 4464, 5425, 1535, -8151, -13242, -15171, -5882, -2159, -288, 176, 739, 1440, + 1431, 2210, -769, -2539, -889, -721, -4378, -6019, -8099, -8147, -6215, -3873, + -1779, -2663, -8548, -12911, -8955, -5265, -1796, -700, 240, 746, 528, -160, + -847, 1228, 735, -1117, -1191, -1857, -2236, -2407, -2321, -1779, -1542, -1665, + -11, 1561, 591, -2764, -3940, -4994, -5679, -5652, -5586, -4852, -3930, -3297, + -783, 2500, 2912, 1480, 864, -64, -492, -833, -769, -353, -452, -1009, + -1207, 305, -1169, -3978, -4167, -3249, -1227, -606, -48, 233, -51, -545, + -2442, -2531, -3873, 5622, 7990, 7025, 4210, 3337, 2576, 1042, 237, -673, + 7644, 9215, 4703, -2206, -6625, -10676, -11281, -8039, -4321, -386, 15, -113, + 5397, 7494, 5296, -39, -1846, -2017, -1875, -1846, -1697, -2156, -2072, -1969, + -279, 230, -3010, -8280, -10317, -11859, -10729, -9576, -7922, -4867, -3862, -2865, + -899, -234, -2897, 3569, 4566, 799, -5740, -7153, -6546, -3276, -2048, -960, + 954, 3319, 1295, -3334, -5133, -5137, -2866, -2245, -1793, -1073, -934, -1281, + -1098, 1538, 1024, 1919, 2978, 3729, 4709, 5431, 5521, 4962, 3843, 1920, + -772, 429, -1810, -5319, -6411, -7074, -6828, -6001, -5266, -3901, -3160, -2833, + -140, 1442, -1153, -2496, -631, 1264, 2033, 3167, 3840, 3225, 2577, 1232, + 2263, 4102, 1167, -4671, -6812, -9651, -10507, -2400, 272, 1823, 1124, -2641, + 3904, 5709, 4800, 1435, -1797, -3682, -7176, -9009, -11812, -10666, -5157, -2353, + 122, 738, -2898, -9698, -11180, -8161, -1527, -926, -352, 476, -116, -705, + 1615, 3938, 3296, -117, -1405, -2593, -4075, -4383, -4273, -3528, -3017, -2881, + 3319, 4999, 2191, -4352, -6684, -7394, -7503, -7494, -6914, -5038, -4138, -3841, + 1933, 5658, 4544, 2619, 2149, 1456, 812, 401, 240, 207, 12, -673, + 1747, 3791, 1295, -236, -1712, -1232, 632, 903, 1488, 1527, 1184, 368, + -1030, 922, 4017, 7665, 6754, 5073, 3236, 1989, 1056, 426, 45, -609, + 12487, 14522, 8896, 2687, 1057, -3810, -10425, -9171, -6482, -2948, -2321, -1169, + 7344, 9906, 7921, 4454, 3289, 2320, 1483, 513, 192, 491, 493, 79 +}; +const Word16 lsf_cdk_wb_vc_stg2[] = /* 14Q1*1.28 */ +{ + -182, -1035, -2593, -176, 528, 0, + -2110, -2904, -2881, -1696, -864, 0, + -160, -876, -1777, -4160, -2112, 0, + 1601, 651, -1393, 208, -896, 0, + -1109, -1806, -2112, 2592, 1360, 0, + -1723, -1575, 1104, 912, 288, 0, + -700, 1343, 687, 1408, 144, 0, + 863, 454, 864, 464, -160, 0, + -1234, -1141, -289, -832, 832, 0, + -230, -608, -480, -1520, -2352, 0, + 1268, 2126, 1919, -3440, -3072, 0, + 1298, 1365, -65, -2832, 672, 0, + 1095, 493, -849, 3184, 3056, 0, + -469, -479, 1617, 3728, 2112, 0, + -675, 1400, 3984, 240, -592, 0, + 2580, 2697, 2432, 1920, 1040, 0 +}; +const Word16 lsf_cdk_wb_vc_stg3[] = /* 14Q1*1.28 */ +{ + 7, 3, -1329, -4391, -3913, -3041, -859, -255, 176, + 13, 7, -2257, -960, -1287, -1649, -1313, -770, -433, + 3, 13, -33, -1650, -2302, -2721, -4039, -3798, -2609, + 10, 4, 0, 1123, 279, -1057, -2271, -1039, 160, + 7, 12, 15, -748, 384, 848, -1029, -1992, -2385, + 4, 1, -2417, -2753, -316, 912, 1240, 993, 704, + 0, 0, 2497, 3043, 1347, -849, -5667, -5913, -4193, + 5, 2, 848, 519, 1737, 2560, 1763, 1506, 912, + 12, 12, 271, -2734, -3306, -736, 1294, 383, -209, + 10, 14, -577, -71, -129, -449, 1561, 2068, 1920, + 14, 1, 1408, -1285, -2943, -4177, -1355, 306, 752, + 15, 8, -2529, 2194, 2953, 2368, 1761, 1377, 816, + 14, 10, 3024, 1322, 224, -304, 514, 511, -81, + 1, 12, -849, -709, 112, 2417, 5221, 4664, 3648, + 1, 9, 160, 3607, 3314, 2016, -333, -884, -1233, + 13, 12, 1888, 3621, 3935, 4000, 3607, 2932, 2128 +}; + +const Word16 *const lsf_codebook[2][2][TCXLPC_NUMSTAGES] = { { { lsf_cdk_wb_gc_stg1, lsf_cdk_wb_gc_stg2, lsf_cdk_wb_gc_stg3 }, @@ -12226,10 +17351,12 @@ const float * const lsf_codebook[2][2][TCXLPC_NUMSTAGES] = const int16_t lsf_numbits[TCXLPC_NUMSTAGES] = { 5, 4, 4 }; -const int16_t lsf_dims[TCXLPC_NUMSTAGES] = { 16, 6, 10 }; -const int16_t lsf_offs[TCXLPC_NUMSTAGES] = { 0, 0, 6 }; +const int16_t lsf_dims_ivas[TCXLPC_NUMSTAGES] = { 16, 6, 10 }; +const int16_t lsf_offs_ivas[TCXLPC_NUMSTAGES] = { 0, 0, 6 }; +const Word16 lsf_dims[TCXLPC_NUMSTAGES] = { 16, 8, 12 }; +const Word16 lsf_offs[TCXLPC_NUMSTAGES] = { 0, 0, 4 }; -const float lsf_ind_cdk_nb_gc_stg4[] = +const float lsf_ind_cdk_nb_gc_stg4_flt[] = { -33.5099f, -17.2439f, 1.9585f, 6.4210f, @@ -12237,7 +17364,7 @@ const float lsf_ind_cdk_nb_gc_stg4[] = 23.6604f, 49.3421f }; -const float lsf_ind_cdk_nb_vc_stg4[] = +const float lsf_ind_cdk_nb_vc_stg4_flt[] = { -33.5292f, -23.3982f, 15.6149f, 34.3889f, @@ -12245,7 +17372,7 @@ const float lsf_ind_cdk_nb_vc_stg4[] = 60.7325f, 78.8354f }; -const float lsf_ind_cdk_wb_gc_stg4[] = +const float lsf_ind_cdk_wb_gc_stg4_flt[] = { -31.4516f, -19.9820f, 9.1071f, 6.9160f, @@ -12253,7 +17380,7 @@ const float lsf_ind_cdk_wb_gc_stg4[] = 31.7476f, 59.9379f }; -const float lsf_ind_cdk_wb_vc_stg4[] = +const float lsf_ind_cdk_wb_vc_stg4_flt[] = { -25.6665f, -20.7100f, 17.1565f, 9.9963f, @@ -12261,7 +17388,42 @@ const float lsf_ind_cdk_wb_vc_stg4[] = 55.4374f, 66.3001f }; -const float * const lsf_ind_codebook[2][2][TCXLPC_IND_NUMSTAGES] = +const float * const lsf_ind_codebook_flt[2][2][TCXLPC_IND_NUMSTAGES] = +{ + { { lsf_ind_cdk_wb_gc_stg4_flt }, { lsf_ind_cdk_wb_vc_stg4_flt } }, + { { lsf_ind_cdk_nb_gc_stg4_flt }, { lsf_ind_cdk_nb_vc_stg4_flt } } +}; + +const Word16 lsf_ind_cdk_nb_gc_stg4[] = /* 14Q1*1.28 */ +{ + -1360, -704, 0, + 80, 256, 0, + -896, 1008, 0, + 960, 2016, 0 +}; +const Word16 lsf_ind_cdk_nb_vc_stg4[] = /* 14Q1*1.28 */ +{ + -1360, -944, 0, + 624, 1408, 0, + -368, 240, 0, + 2480, 3216, 0 +}; +const Word16 lsf_ind_cdk_wb_gc_stg4[] = /* 14Q1*1.28 */ +{ + -1280, -816, 0, + 368, 272, 0, + -704, 1136, 0, + 1296, 2448, 0 +}; +const Word16 lsf_ind_cdk_wb_vc_stg4[] = /* 14Q1*1.28 */ +{ + -1040, -848, 0, + 688, 400, 0, + -560, 1520, 0, + 2256, 2704, 0 +}; + +const Word16 *const lsf_ind_codebook[2][2][TCXLPC_IND_NUMSTAGES] = { { { lsf_ind_cdk_wb_gc_stg4 }, { lsf_ind_cdk_wb_vc_stg4 } }, { { lsf_ind_cdk_nb_gc_stg4 }, { lsf_ind_cdk_nb_vc_stg4 } } @@ -12269,7 +17431,8 @@ const float * const lsf_ind_codebook[2][2][TCXLPC_IND_NUMSTAGES] = const int16_t lsf_ind_numbits[TCXLPC_IND_NUMSTAGES] = { 2 }; -const int16_t lsf_ind_dims[TCXLPC_IND_NUMSTAGES] = { 2 }; +const int16_t lsf_ind_dims_ivas[TCXLPC_IND_NUMSTAGES] = { 2 }; +const Word16 lsf_ind_dims[TCXLPC_IND_NUMSTAGES] = { 4 }; const int16_t lsf_ind_offs[TCXLPC_IND_NUMSTAGES] = { 0 }; const Word16 min_distance_thr[2][2] = /* 14Q1*1.28 */ @@ -12279,7 +17442,7 @@ const Word16 min_distance_thr[2][2] = /* 14Q1*1.28 */ /* NB */ {1000, 580 } }; -const float lsf_q_diff_cb_8b_rf[256*16] = +const float lsf_q_diff_cb_8b_rf_flt[256*16] = { -49.142456f, 13.490689f, -21.704788f, 63.851589f, 17.341200f, 49.889275f, 4.535705f, -49.377617f, 12.881550f, 3.317029f, -45.874687f, -91.048477f, -159.075317f, -244.532806f, -208.950378f, -60.136238f, -71.911499f, -50.432014f, -131.216339f, -25.763540f, -90.432335f, -140.176178f, -31.643175f, -46.414715f, -23.065298f, -42.936611f, -38.403904f, 15.094532f, -0.061476f, -28.153961f, -21.246065f, 10.218022f, @@ -12538,6 +17701,265 @@ const float lsf_q_diff_cb_8b_rf[256*16] = -19.139826f, 222.586807f, 160.578033f, 15.308187f, 37.928532f, 2.810670f, 89.260468f, 73.903893f, -14.074634f, 9.220748f, 52.358765f, 29.237804f, 68.572754f, 74.369972f, 135.163269f, 53.634529f, 27.498774f, 55.932766f, 90.594849f, 106.451241f, 66.339134f, 276.491119f, 112.921783f, 68.186401f, 34.717724f, 217.367447f, 183.300674f, 171.332642f, 233.111526f, 113.635857f, -94.105415f, 101.164040f }; +const Word16 lsf_q_diff_cb_8b_rf[256 * 16] = /* Q6 */ +{ + -3145, 863, -1389, 4087, 1110, 3193, 290, -3160, 824, 212, -2936, -5827, -10181, -15650, -13373, -3849, + -4602, -3228, -8398, -1649, -5788, -8971, -2025, -2971, -1476, -2748, -2458, 966, -4, -1802, -1360, 654, + -8629, -7702, 6280, 3296, -1205, 365, -5964, 3125, 2443, 1442, 1149, -3835, -9867, -4238, -1977, -1955, + -2629, -759, -2056, -2297, -1839, 1678, -2412, -7539, -13208, -9624, -1688, -2171, 943, -454, 536, 2644, + -2840, -1391, -10500, 2516, 907, 146, -2762, -6750, 2949, -2282, -4614, -5663, -7773, -5510, -5947, -3727, + -4006, -939, -2500, -771, -3414, -4521, -6417, -4064, 3698, 3969, 4300, 4177, -3195, -10419, -13072, -6695, + -4284, -1172, -4415, -1601, -6029, 66, -4338, -2300, -3402, -5614, -7181, -7288, 7154, 6538, 64, -3263, + -6470, -4503, -9698, -5885, 235, 5049, 2698, -3656, -3600, -6261, -4270, 766, 1037, -1511, -1274, 1800, + 669, 2937, -3464, -1034, -4098, -11296, -382, -4610, -9613, -2081, 3947, 2832, 2962, -332, -9039, -10702, + -11109, -5950, -7200, -6525, -4260, -5060, -8936, -91, -672, 4557, 3192, -147, -2247, 1566, -734, -3007, + -2411, 1587, -2575, 2172, -3270, 10648, 7093, 1517, 1512, -392, 49, -9117, -16895, -908, -8443, -9923, + -1934, -603, -6588, 5335, -1565, -11521, 5944, -5092, -615, -2221, -7703, -1903, -5195, 2323, 3958, 3050, + -7094, 5361, -7885, -3299, -3282, -3125, -1888, -406, 1522, -23, -1506, -6075, -8517, -7605, -3450, -3362, + -3573, -2421, 1385, -181, -11027, 4778, -4014, -4956, 7316, 3138, 2351, 3406, -1998, -968, -2375, -3262, + -141, 6652, 11944, -4131, -2073, -2592, -1562, 1521, -1804, -2585, -2685, -5798, -10850, -11629, -4300, -4287, + -1569, 2229, 2330, 3147, -1026, -7010, 265, -1320, -3648, 1942, -5375, 73, 10348, 3913, -5535, -5938, + -5642, -3433, -8423, 1178, -540, -4790, -1976, 4686, 1701, -1323, -2009, -5997, -5693, -3852, -7604, -5361, + -1784, -325, -8561, -17592, 1663, 1377, 2347, -245, -2426, 141, -137, 985, -4926, -7898, -3559, 895, + -2548, -1563, -5007, 7311, 4409, 3177, 3920, 1546, -725, -5252, -9754, -9267, -5701, -6900, -961, 1772, + -1676, 889, -4798, 8060, 3460, -1911, 415, -4044, -6146, -12074, -10588, 13056, 2765, 1396, -4737, -4905, + 943, 3342, -8515, 4676, -774, -3963, -5503, -1625, 3909, -3614, 12347, 2835, -9710, 5877, 297, -918, + -5317, -2799, -3708, -4084, -8175, -6155, 1752, 6801, 7493, 6271, 4083, 3132, -809, -4200, -5389, -5982, + -5060, -5285, -1533, -2751, 2259, -3893, -3473, -108, -4711, -2627, -2069, -2320, -172, 1547, 770, 309, + -4485, -2618, -7238, 1767, -2965, 6693, 5256, 18, -1789, -5076, 7167, 3204, -1242, 1628, 4519, 1796, + -114, 1225, -3083, 321, -4002, 4834, -3014, -741, -4189, -5946, 6871, -2068, -13016, -9772, -3235, 2044, + 559, 10477, -9704, -7733, -8989, -10787, -10342, -8585, -2844, 1474, 5638, 9798, 10986, 9105, 4619, 2186, + 1576, 9039, 4354, 2073, 1861, -1492, -715, 1840, -6736, -10798, 994, -2921, -6369, 779, 2668, -443, + -2067, -1020, 1, 14571, 2253, -2163, 5255, 973, -1722, 4173, 102, -3633, -1430, -1720, 1243, 1749, + -6589, -1601, -9469, -5581, 3018, 1186, -11, 1252, 5708, 3338, 187, -3950, -6035, -3294, -106, -1130, + -2490, 445, -2543, -3283, -3432, -6963, 9950, 4072, 2294, 4517, 2736, 8173, 4270, -8347, -9374, 4776, + -66, 3476, 537, 2659, -677, 1552, 1974, -1703, -2139, -634, -1988, 694, 1921, -12938, -16525, 5848, + -9849, 7389, 4653, -1158, 1340, -2250, -2460, -2201, -3122, -90, 3974, 5105, 9127, 8701, 6184, 3770, + -5086, -3159, -3197, -9944, -7474, 961, 1158, -3536, 1050, 5572, -1480, -11120, -9276, -1841, -2086, -24, + -1019, -346, -6765, -8343, -6302, -3019, -5606, 2728, -3994, -6909, 10146, 6321, -230, -393, -846, -1536, + -1598, 3610, 3330, -233, -1215, -1953, -1330, 19, -4839, -10681, -11699, -1104, 1146, -6143, -6849, 422, + 892, 7937, -5005, -5547, 1756, -4020, -3420, -6811, -6304, -7812, -6019, 5109, 5503, 5568, 4600, 6472, + -3296, -2230, -6010, 3497, 5502, -2291, -2342, -6544, -12576, 2192, -1004, -5205, -500, -6764, -6200, 1816, + 5114, 4922, 6498, 6613, 4909, 2318, -5626, -11915, 3072, 11570, 1766, 4361, 552, -8139, -14006, -17228, + -3321, -1514, -473, 3295, -1028, -4536, -12374, 12452, 7396, -2269, -5052, 554, 1053, -4370, -5859, 97, + -2532, 2546, -4920, -13800, 8116, 2425, 1695, -2088, -5105, -346, -2869, -2457, 9336, 13166, 6150, 5166, + -2329, 72, 11513, -3075, -7745, -5492, -8015, -5108, -16, 3261, 876, -357, -3241, -2956, -4265, -2320, + -7869, -6495, -16668, -1339, -3678, 975, -2740, -2776, 3755, 141, -190, 1026, 5972, 3232, -924, -3212, + -1077, 568, -5606, 1478, -243, 2479, 10198, 3667, 682, -2873, -9164, -9042, 2186, 4347, -750, 5303, + 556, 5098, -6825, -2564, -3946, -5752, 1977, -6171, -5627, 4580, -835, -6362, 10132, 9511, 6475, 2861, + 3320, 11074, -483, 2698, -20, -4084, -4213, -3931, -231, -17, -1826, -2737, -5920, -1539, -1897, -3347, + -1346, 2075, -1230, -5248, 10906, 9461, 5046, 3485, -267, -948, 4273, 1889, 81, -488, -4763, -5532, + -1237, 6446, 3974, 5166, -723, -10033, 8338, 4102, 683, 1474, 624, -5287, -8628, -7519, -6290, 1767, + 207, 2676, 870, 13754, 7087, 2357, -922, -1734, -4651, 352, 14028, 10050, 8916, 2725, -5722, -9415, + 364, 3660, -813, 4370, -2151, -2115, 5570, -2545, -8167, -1978, -8301, -10715, 959, -5127, -11250, -7721, + -1668, -1437, -5508, -11155, -15130, 6829, 6070, -1555, -3048, -314, -528, 1714, 1474, -42, -541, 3361, + -15356, -12047, -4659, -1598, 4105, 3069, 2375, 3647, 1217, 140, -2518, -4195, -3080, 2155, 66, -570, + 84, 1523, -742, 13326, 5544, -2653, -5484, -3816, -9239, -10794, 6967, 2095, -4231, -2102, 4368, 8737, + 2959, 3968, -2430, 4601, 317, 5804, -3547, -11099, 5849, 273, -5513, 767, -9421, -11095, 3029, 8472, + -518, 2355, 2733, 53, -1439, -2709, -394, 5355, -2408, -3122, 8729, 5660, 7771, 4999, -7588, -15134, + -2240, 2281, 6677, -5155, 5663, 266, -4355, -7052, -3825, -2235, -2745, -3212, -2018, 1828, 1971, 2086, + -1241, 699, -2126, 3835, 1147, 4456, -3810, -23, 1284, -4878, 3807, 14029, 2820, -6773, 9556, 6600, + -1716, 315, -3259, -3282, -2859, -2219, 3508, -3452, -7850, 623, -5558, -2168, 1842, -8228, -885, 15388, + -8177, -7705, -14377, -6808, -7099, -7676, -4141, -5548, 3677, 5846, 6160, 10031, 11318, 8141, 3326, 904, + -3072, 1139, 1875, 4811, 3767, 7294, 4507, 1476, -1622, -6385, 384, 3318, -3867, -10447, -6387, -4252, + -19, 1102, -6317, 3433, -1856, -5732, 7225, -2107, -6977, 9620, 7964, 3013, 7152, 4986, -2184, 2136, + -524, 1479, -923, 3729, -259, 227, 6477, 2660, 4208, 1017, -423, -6090, -13677, 5309, 702, 2721, + -822, 2175, 1717, 3580, 1133, 3835, 980, 13265, 6367, 2741, 7462, 6211, -2347, -7635, 4781, 4132, + -8168, 13481, 5777, -963, 643, -2853, -2086, -1593, -2092, 2348, 3867, 413, 461, 1644, -259, -1656, + -846, 1615, -2805, 935, 3206, 1907, 7862, 3901, -975, 4507, 3151, 1433, 15449, 4412, -1221, 1001, + -3952, 1411, -2148, -1025, -2553, -4164, -4725, -3465, -2654, -3828, -6151, -7679, -5881, -2007, -581, -2499, + -1744, 4546, -8725, -6274, -1364, -1087, -2198, -4504, -3542, -1966, -516, -802, 448, -162, -1277, -2081, + -12133, -10923, 10206, 4436, 611, -2300, -4926, -4708, -5138, -3373, 2358, 295, -370, 4406, 2947, 351, + 1477, 3584, 3776, 4714, -1508, 2029, 426, -5245, -2805, -5852, -8752, 199, -3945, 10358, 10127, 4852, + -1894, 528, -776, 2698, -1298, -7579, -12457, -12545, 2483, 2421, -140, 723, -395, -292, -4196, -1766, + -3071, 1449, -3716, 3712, -3017, 543, -391, -1984, 3301, 375, 1107, -2635, 4730, 870, -19666, -12653, + -2823, 3165, 5399, -10321, -6087, -2824, -329, -1699, -268, -1995, -2254, 2744, 319, 51, 2834, 452, + -2837, -240, -1298, 2244, 1977, 3061, 3676, -1207, -3774, -2607, -3405, 9701, 12102, -3052, -10263, 1164, + -1548, -515, -3862, 1117, 3329, 4105, -804, -4141, -9321, -3136, 1792, 3484, 2025, -6747, -11991, -10905, + -3361, -2922, -3472, 1165, -3055, -1620, -4751, -8940, -477, 1932, 1054, 4687, 5735, 5566, 2447, -778, + 1791, 3768, 602, -2421, -6876, 9505, 7350, 2428, -3175, -6252, -707, -3720, -7723, -42, 4292, -1141, + -2469, 269, -1028, 1057, -890, 383, -128, 821, -2854, -5548, -2437, -3349, 3935, 1474, 14267, 13393, + -3416, 14072, 1196, -3166, -4252, -711, 521, 2462, 5346, 1483, -4287, -7676, -5805, -321, 867, 475, + -1674, 1391, 539, -471, -5201, -25, 6911, -2142, 10454, 10963, 1353, -2831, -3219, -131, -3005, -4468, + 3476, 4986, 6318, -2959, -9204, -87, 3906, -833, -247, 5687, 451, 716, -2970, -5788, -6743, -9436, + 4831, 6767, 3852, 2164, -1362, -1404, -3260, -4807, 2809, -2699, -4693, 21984, 10803, 4063, 2353, 6177, + -2813, -890, -5363, -165, -5755, -20361, 3639, 4639, -2073, 1798, -1097, -6169, 30, -1827, -4590, -2586, + -5855, -6418, -10115, -6038, 2674, 3620, 1206, 1379, -520, 5333, 5334, 3618, 439, -1048, 439, 777, + -7871, 2657, -3649, 7671, 10875, 5285, 423, 1869, -2283, -6081, -2750, -3935, -1815, 2851, 754, -2545, + -2253, -245, 87, 3432, 4323, 803, -3981, -8416, -12174, 6263, 9281, 7472, 2558, 327, -3198, -1436, + -1398, -211, -6595, 4670, 63, 2041, -4372, 967, 2444, -9123, -11355, 1727, -4221, -3144, 6411, 4338, + -4409, -3256, -6504, 6064, 4055, -2268, 5638, 5466, 82, -516, 6974, 5206, 1235, -364, -4919, -6016, + 2, 7, -5, 5, 1, 2, -8, 4, 4, 2, 4, 5, 0, -1, -3, 1, + -1139, 1101, -1501, -3122, 2059, 9130, 5593, -2976, -5845, -8198, 10800, 771, -4815, 20594, 5385, 9434, + -497, 877, -5365, -1190, -2940, -6216, 4700, 872, -2276, 9901, 5530, 417, -4381, -9743, -1935, -1025, + -3555, -643, -5254, -6674, -6586, -4879, -3791, -2733, 1046, 2275, 3157, 3643, 8384, 10607, 11929, 9237, + 1573, 3323, 130, 12128, 9521, 6522, 4035, -1444, -7190, 565, 2160, -2808, -3716, -9398, -1115, 4631, + -1938, -2034, -5142, 6407, 5972, 302, -3078, -7362, -12229, 6591, 5640, 1240, 2727, 3243, 9738, 7334, + -8793, 935, -4176, 103, 2398, 1724, 1579, 7649, 5685, 2791, 1754, -453, -5030, -4870, -3871, -3139, + -243, 3111, -2068, 3022, -4587, -11340, 14571, 7771, 3558, 5750, 1203, 4665, -1981, -109, 4442, 1369, + -2041, 3713, 1013, 1345, 4716, 129, 3062, 1444, -3639, -6184, 7457, 7819, 958, -8391, -8799, 9312, + 235, 3895, 12172, 2716, -1347, -1094, -4869, -880, 7519, 9011, 9914, 5683, 5909, 7805, 4428, 2129, + -1538, -36, -678, 1486, -649, 1517, -5121, 8530, 5048, -1844, -4781, -9145, -11353, -8076, -4133, -307, + -2707, 80, -5905, -4315, -4389, -6758, -6105, -9003, -10744, -1701, 3765, 6091, 10523, 7504, 4350, 4312, + 786, 3663, 9280, 6578, 391, 1514, -7019, 5089, 3483, -6871, -8172, -180, -7469, 1419, -121, 838, + 2692, 6995, 1431, -1074, 1394, -268, -1170, -3367, -7586, -5698, 7587, 7378, 5733, 8353, 10152, 10834, + -8158, -6271, -9914, 9985, 5364, -2601, -1959, -6260, -4097, 3235, 2097, -196, 2968, 3371, 2095, -1207, + -2269, 648, -1910, 7766, 5356, 3667, 981, 2825, 4288, 6668, 696, -661, 4042, -5356, -12858, -3646, + -4703, -3239, 10100, -2312, -256, -2120, -2612, 4835, -1675, 1068, 5746, -140, -869, 3620, 3505, 1703, + -3250, -2423, -1423, -674, -4843, 10905, 4109, 635, -1606, -6241, -2449, 3295, 6275, 14389, 8002, 4352, + -842, 3170, 1430, 1513, -4583, -12820, 1470, -4220, -8952, 6987, 4718, 532, -2136, -3700, -1727, 4512, + -3663, -2257, -8998, 5471, 843, -2858, -4142, 5134, 7250, 525, 3002, 118, 423, 6929, 5389, -1003, + -3457, -2564, 4399, 5758, -1462, 9992, 2582, 885, 6350, -670, -4446, -5882, -1814, -1178, -3073, 1157, + 2529, 7505, 5440, 202, -5746, -976, 8235, 1049, -181, -142, -6919, -6675, 18283, 16554, 8385, 3001, + 2266, 12753, -3253, -3832, -7200, -5627, -4778, -925, 239, 539, 2225, 324, 3182, 1914, -309, -507, + 5074, 4381, 9167, 1915, -3908, 1754, -5997, 2537, 17796, 13293, 7314, 12286, 1815, -4329, -8064, -20774, + -2484, 4942, 14515, 5406, -2595, -1380, 8417, 5956, 1651, 1559, -1389, 24, -6421, -4047, 2557, -1331, + -3164, 848, 15096, 9663, 6043, 3180, 595, 2733, 830, 1861, 9051, 8435, 8904, 6571, 2208, -762, + -135, 870, -2484, -3227, -9497, -586, 14177, 5880, -3708, 505, -1483, -415, 2507, -1973, -13853, -8468, + -3854, -2420, -9258, -4766, -3435, -2360, 10467, 7572, 598, -4099, 3457, 402, -195, 4193, 2023, 1851, + -4359, -3760, -1315, -585, 11411, 2958, 5446, 1608, 228, 4691, 1446, -1971, -3898, -3822, -1651, -1697, + 5112, 1738, -12375, 11069, 8416, -139, -721, 740, -8678, -7527, 10378, 4791, 5388, 2724, 4652, 1931, + -1419, 520, -6325, 10393, 8379, 2544, -2104, -11110, 7461, 2884, -1766, 548, -217, -2709, -1287, -2598, + 1996, 4969, 3862, 5813, -629, -7138, 7107, 9009, 5157, 1564, 5244, 1326, 78, 263, -4389, -5858, + -5423, -34, 1648, 2316, -3981, -5525, -1762, -996, 2075, 878, 718, 1458, 613, 3914, 3912, 2074, + -1176, 643, -3222, -444, 779, 9634, 14238, 11755, 3727, 1970, -1421, 3653, 1795, -2315, 10947, 8623, + 19, 6095, 3277, 2648, 2148, 509, 3577, 978, 1862, 5842, 1302, -3853, -10993, -12406, 858, 7763, + -4944, -1993, -5563, 833, -1365, -2240, -25, 2546, 10150, 10369, 10670, 10551, 9322, 5582, 881, -1029, + -763, 4474, 9314, 8818, 2703, 4844, 7776, 1684, 1, -3980, -9739, 5565, 2667, 1185, 2203, 1611, + -635, 724, -4112, 8414, 3049, 1437, 2314, -2611, -5835, 5541, -3027, 1017, 14246, 10165, 9910, 14393, + 2201, 3204, -295, 2519, -855, 5303, -2184, -12725, 10839, 1337, 154, -5290, -7908, 9490, 4292, 5533, + 544, 3574, 602, -783, -3121, 21721, 8166, -1137, 4729, -2399, 2504, 3721, -2704, -10309, 4957, 8028, + 2782, 11109, 5440, 2691, -3942, 3286, 2848, -532, -186, -2661, 7318, 6015, -1200, 2174, 5498, -379, + 4440, 6050, 3576, -819, -3697, 13144, 9664, -2178, 2966, 3302, -623, 10572, 15713, 9000, 2137, -5160, + -1593, 613, 3985, -7128, -5989, 2429, 721, -5488, -11848, 981, -3054, -4499, -4102, -7743, -7416, -340, + -2759, -2449, -4426, -6796, -13804, -7472, -1409, -1103, 181, 3071, 434, -741, 1045, 1976, 1407, 1365, + -2578, -1275, 5323, 9313, 4798, -1130, -6220, -2101, -3402, -868, -1959, -4365, -4536, -1626, -3701, -5011, + -3479, -3407, -9706, 4812, -812, -4014, 2558, -5416, -10543, -5186, -3840, 1189, 3804, 5839, 4744, 1003, + -3585, -2339, -4745, 3869, -2763, 1306, -6059, -8604, -1377, -5116, -730, -1693, -3321, 888, -685, 876, + -3492, 910, -7012, -2555, -5147, -1372, -1910, -8518, 2661, 7652, 6967, 7296, 4514, -4741, -9827, 873, + -1258, 4649, 3654, 653, -5264, -5509, -4222, 1703, 3992, -5102, -4342, -6447, 6603, 2642, -923, 6242, + -992, 647, 1228, -3124, -3463, 15067, 838, -6186, -3433, 872, 97, 2876, 3686, -2643, -6780, 356, + -1727, 2555, 2552, -1938, -8798, -773, -757, -3588, -7005, -6121, 4601, 235, -4446, 2984, 1353, -776, + -15055, -12154, -6273, 84, 390, -3286, -4758, -3713, -2185, -1512, 1403, 3479, 7578, 6327, 5045, 3075, + 2469, 8960, 6679, 3813, 1059, 9183, 2971, 4300, -1040, -927, -2376, -6240, -5131, -6030, -7385, -7560, + 933, 4512, -899, -1226, -7230, -10649, 11249, 4655, -7924, -5423, -5107, 993, 588, 2896, 4305, 1369, + -1938, 11282, -2696, -7285, 1163, -6289, -344, -2329, 3632, 2191, -1017, -1404, -2305, -6223, -2822, -1369, + -3688, -918, -3118, 256, -5446, 8638, 6195, 2855, 7432, 6937, 8638, 4020, -3296, -4260, 21, -3914, + 3006, 5845, 16377, 17059, 3579, 103, 204, -563, 1735, 6204, -405, -2618, -7929, -14028, -9415, -5277, + 303, 934, -305, 3211, -2970, 2963, 10231, 2833, 1656, 1162, -4439, 6346, 9314, 7062, -5015, -15980, + -320, 499, -14803, 4610, 2112, -4049, 7242, -245, -3115, 1323, -1276, -4286, -1951, 100, -1389, -1612, + -4391, -2691, -5202, -11000, 373, -2423, 4221, 4146, 1045, 503, -4063, -2244, 2311, 1646, -1779, -3188, + -3374, 346, -3243, -3662, 5971, 5519, 3022, 516, -4538, -6550, -5227, -6165, -4919, -1105, 30, 721, + 2935, 3922, -1041, 4217, 2528, 1985, 661, -824, -10133, -13715, 8714, 2218, 3769, 3384, 1193, -6246, + -5357, -2959, -8106, 5394, 1542, -4964, -7749, -4183, 877, 1146, 8307, 2891, -4905, -5775, 1888, 1442, + -2472, -850, 1278, 1397, -4545, -3625, -11722, 9811, 7790, 7832, 12234, 6079, -2436, -890, -1820, -234, + -3905, -1081, -7818, 2577, -299, 5742, 4982, -1421, 3506, -604, -4944, 2130, 544, 1545, -2399, -3202, + -895, -203, 783, -203, -2734, 10200, 7718, 3943, -6098, 9859, 9374, 6777, 2263, -2089, 866, 3381, + -3828, 1991, -2866, -1612, 747, -3896, 6041, 2875, -5838, -6829, -2319, -1146, -8845, -10612, 3630, 2942, + -509, 5457, 1119, -3222, -3623, -6421, -9746, -8661, 5658, 8283, 8062, 6310, 1787, 454, 1766, 2750, + -1632, 7787, 5349, 243, -1526, 3143, 5218, 10290, 1446, -6324, -3035, -1055, 2974, -7871, 39, 3664, + -769, -9, -8896, 9699, 4546, -1295, 6107, -4534, 3367, 1450, -3607, 8816, 3219, -5601, 1298, 12366, + -7130, -4420, -6848, 3453, 3599, 4371, 609, -6059, 8057, 9067, 2408, -3523, -6908, -6822, -6636, -2017, + -477, 5145, -1462, -475, -2003, -3769, 7781, 4563, 4437, 2134, -2726, 15777, 2839, -1929, 2913, 2174, + 841, 2396, 754, 14163, 4130, -1807, -177, -3884, -6782, 9287, 1864, -599, 5913, -2587, -10749, 5856, + 1304, 7980, -2237, -2092, -4384, -828, 552, -6108, 2193, 10107, 6057, 9885, 13003, 8977, 4006, -926, + -1523, 1282, -1805, -2709, -6024, -7618, -10251, 832, -689, -1488, 1528, -1635, -4512, -3974, 3366, 5884, + -2891, -646, -4227, -16787, 4586, 2689, -48, 1956, -5398, -5693, 4030, 1138, 2292, 2634, 6453, 3271, + -3526, 9059, 2896, 8101, 3313, -270, -1336, -3002, 826, -1572, -3793, -2235, -1597, 272, 910, -778, + -1195, 3634, 1576, 2036, -3675, -10512, -6414, -3268, -9714, -6636, 3287, -947, 6643, 7755, 4317, 2928, + -592, -46, -6118, -3775, 11750, 5301, -2878, -7240, -4674, 1543, -626, -1300, -608, -1661, -4053, -3154, + -2514, -545, 771, 7292, 3641, 749, -1664, -1652, 2686, 8715, 10176, 4547, -6065, -7417, -6454, -4928, + -576, 940, 681, 2977, -2947, -1968, -6468, 10093, 7720, -2235, -3869, -8057, -4152, 7399, 8617, 5658, + -1043, 1637, -3699, -5968, 13092, 1526, 1185, -3128, -2234, 3343, 5773, 9935, 7870, 6240, 3284, 3932, + 377, 5872, 3528, 3824, -852, -1575, -3799, -8401, -5628, -3612, -2451, 1396, 1471, -1669, -579, -384, + -6978, -4522, -6731, -1881, 1485, -73, -38, -3990, 11379, 4104, 1154, 5492, 3709, -645, -641, -750, + -97, 2556, 1619, 3351, 1996, 10845, 8411, 2751, 3099, -165, -6582, -11822, 8128, 7722, 4495, 3322, + 950, 2744, -2039, -3959, -6098, -2113, 4512, -1699, -758, 3243, -4760, 7788, 11837, 5336, 7626, 5509, + -4876, 13906, -3059, 1351, 4037, 2283, 614, -5014, 2149, 613, 744, -4239, -5981, -4296, -1799, -3121, + -2111, 3530, -1221, 1654, 9442, 10361, 6422, 7826, 7510, 7790, 3836, -323, -761, 1652, 330, -386, + -3239, 3070, 7009, -1209, 6710, 213, 5225, 3105, 1173, 842, -1774, -5027, -3901, -1359, -2786, -3513, + 1481, 1904, 7402, 23443, 5946, -3615, -1528, -4317, -2629, 11277, 7171, 5620, 7938, 4715, 3575, -3794, + 2315, 5200, 63, 4010, -400, -2074, 6624, -516, -731, -2133, -10088, 6969, -3380, -7450, -7347, -6915, + -3407, -3447, -1422, -4020, -11809, 3562, 3865, 570, 7656, 6367, 5964, 802, -2306, 5862, 7700, 6476, + -17049, -2577, 3748, -1004, 990, 2569, 4487, 2137, -3540, -3508, 608, -2102, 90, 4634, 3115, 1273, + -1960, -1414, 1516, 9460, 6833, 2088, -3598, -3590, -2554, -1783, 2680, 2127, 939, 8562, 4170, 1914, + 3335, 6241, -2988, 1816, 3233, -951, 587, -5590, -3415, -926, -7987, 8897, 3700, -12712, 5722, 4683, + -756, 1823, 2804, 3392, -2019, 801, -2923, 43, 5720, 2302, 3604, 14791, 4960, -425, -7298, -6606, + 205, 5909, 8599, 4641, -4600, -1580, -4536, -5178, 2346, 6910, 3641, -2630, -6079, 351, 5478, 5524, + 151, 1252, -2569, 6834, 5377, 4284, 450, -1607, 7257, 4429, -2568, 9851, 9183, 2197, 20053, 9155, + -1462, 924, -3196, -3257, -8953, 6147, 6251, -3186, 3285, 3198, 2326, 1225, -8446, -11295, 5393, 10785, + -2381, -2014, -9329, 4719, -880, -2308, -4714, 4429, 3675, -1874, 3253, 9686, 12557, 9338, 4719, 3836, + -3103, 7031, 11258, 6883, 11690, 8131, 3644, -307, -2590, -274, 1004, -1314, -166, 3063, 695, -1815, + -2455, 811, -1161, 2731, 5931, 2352, 3361, -363, -7371, 2805, 4053, 3586, 7364, 242, -1692, 17531, + -4497, -535, 286, 214, 3804, 11412, 4562, -1157, 550, 4841, 1657, -4984, -6307, 1482, 5745, 3540, + -2763, -1313, -1385, 3735, -2423, 5601, 14635, 10815, 9726, 6141, 4010, 3556, -104, -3353, -7143, 7077, + -245, 8209, 15457, 5234, 1860, -2195, -4620, -4895, -4263, -759, 2016, 2664, 3153, 2966, 1601, 30, + -4764, -1351, 3227, 2660, 1556, 198, 5379, 11277, 8580, 6978, 2506, 3310, 13165, 9623, 7120, 1665, + -59, 558, 3194, 1299, -2918, -2455, 3754, -3394, -3634, -2782, -7987, -7903, -7058, -2214, -1060, 2183, + -1954, -186, -11418, -2859, -1110, -2027, -932, -2040, 1282, 174, -161, -2628, -3341, 2675, 4169, 2475, + -5934, -5196, 10580, 9382, 1417, -1362, -2572, -4391, 7418, 4314, 148, 31, -82, 461, -2595, -570, + -3639, -2081, -1014, 4355, 5943, 6217, 2491, -4106, -6520, -4050, -5030, -2053, 6821, 6135, 2456, 1015, + -3447, -1303, -5380, -6759, -3272, -129, -4989, -11231, 5106, 1264, -3433, -3327, -3139, -1282, 1031, 1558, + 4180, 1592, -3435, 2252, -4803, -6443, 8937, 1696, -5599, 9240, 5481, -328, 3197, -4392, -12452, -16482, + -4613, 5693, 11596, -9035, 1399, 1388, 5182, 4750, 958, 310, -866, 829, 5122, 1203, -115, -759, + -3551, -1843, -3272, -1753, -195, 17324, 8182, -502, -2987, -146, -2640, 6865, 6979, -3675, -6047, 12865, + 3739, 8307, 5634, -2783, 96, 1167, -274, -636, -5808, -8880, 835, 6363, 5092, -700, -8229, -7634, + -6799, -5871, 4391, 1265, -1493, 440, -7322, 2387, 1763, -1406, 4030, 8075, 8810, 5655, 1375, 2309, + 3191, 6527, 2671, -128, -5345, 14221, 13006, 1792, -548, -2974, -7549, -3471, 1835, -1490, -3556, -4240, + -3368, -1748, -3945, 8349, 2444, -5349, 5825, 4222, -1891, -3570, -10832, 8764, 2791, 5495, 9332, 5366, + 1020, 5766, -8313, 522, -568, -20, -2169, 3981, 6641, 4235, 1781, -4362, -7143, -3864, -2205, -3217, + -3300, -1346, -1200, 5950, -1315, -285, 2642, -180, 12986, 11560, 5996, 6755, -2578, -1417, 1848, 5560, + 10662, 13080, 11225, 419, -4335, -128, 6716, 1638, -4903, 154, -2404, -4228, 5262, -364, -5170, -12310, + 360, 1588, 2173, 8939, 4304, 7241, 367, -2361, 6569, 837, -4801, 8650, 7208, 5996, 3566, 1112, + -5017, 4300, 2649, 3064, -6110, -14292, 2204, 13008, 5245, 1594, -6536, -11045, 5146, -211, -4067, -11435, + -530, 1840, 187, -12175, 1984, -1576, 3659, 4293, -1971, 8025, 8287, 4420, 3935, 358, -1691, -2707, + -3429, 252, 1235, 3895, 13024, 5900, 317, 1720, 3724, 1510, -3576, -6091, -8218, -3620, -844, -406, + 2105, 7096, 3064, 3952, 2071, -2774, 8459, 1501, -10913, 1387, -405, 12863, 2328, 4475, 3498, -1584, + -3085, -920, -7032, 8494, 2146, 1346, 1867, -404, 1886, -1042, -378, -2121, -10433, -7336, 15525, 9808, + -15685, -7623, 1925, 2963, 4001, -105, 3843, 5498, 4039, 6151, 6044, 3867, 1730, 2971, 1484, -319, + 3080, 9412, -1223, -3973, 4734, 2248, 3127, 1119, -1738, -1669, -1477, -1472, 1412, 1213, 773, 1674, + -730, 2282, 495, 1849, 753, 4313, 2052, 11060, 2638, -4153, 12967, 4232, 1600, 8305, 6247, 4101, + 1078, -516, -6160, -2738, -3949, 549, 2665, 313, -11805, 5780, 13753, 4964, -3343, -3825, 7392, 657, + -3356, -672, 2091, 1930, -1942, -6931, -7983, -7306, 1452, 3417, 9758, 12537, 14305, 11570, 5653, 1593, + 2820, 8229, 5573, 6212, 5169, 4568, 4877, 1219, -5520, -3569, -4997, 3799, -1152, -6233, 13054, 8210, + -1905, -1112, -1728, 19102, 8663, -331, 3226, 1066, -1807, 8189, 5678, 1987, 4661, 3278, 7947, 11458, + -4574, -517, -5124, 4711, -740, 416, 4847, 4427, 11056, 3251, -1915, -3528, -2529, -2213, 1857, 1203, + 316, 3731, 4619, -1294, -3138, -336, 8691, 7311, 3124, 9892, 5880, 614, 1873, 1916, 3856, 3588, + 1323, 8284, 7332, 4197, 626, 4877, 9117, 4163, 1998, 4387, 5489, 4184, 2124, -5170, -10914, 3921, + -1504, 12727, 938, 3478, 1876, -1017, 389, 3233, 8278, 8027, 8392, 12663, 13264, 9858, 5767, 4287, + -4008, 49, -1854, -5454, -9369, 5309, -1597, 6002, 6031, -2543, -4793, -2340, -2559, 229, -983, -2068, + -3514, 815, -7510, -3824, -931, -1573, -1337, -1189, -2019, 245, 4084, 4416, 6165, 7239, 3899, 2461, + -4781, -2173, 17577, 2751, -894, 2264, 1789, -623, 992, -322, -3113, -1854, -1553, 2213, 731, 850, + 2054, 3456, 3747, 3842, 980, -940, -5065, -5905, 423, -2009, 74, 3933, 13511, 12742, 8908, 5783, + 894, 6872, -2742, 7127, 5497, -660, -2361, -3114, -5552, -884, -1825, -8536, 4278, 4047, 3263, 2117, + 46, 3829, 3392, 7000, 5004, 11640, 7090, 2661, 2072, 3834, 6408, 9453, 4328, -5807, -11811, -6081, + 1119, 3292, 8329, 5549, -1361, -4414, -15806, 7144, 6824, -4515, -1143, 4774, 1451, 5261, 4830, 5562, + -1393, 5662, 4446, 1807, 8826, 6248, 6415, 4547, -1665, 1181, 6405, 5864, 8293, 10387, 7545, 4688, + 1312, 7883, 6317, -3965, -8535, -2725, 1117, -5447, -7012, 3655, 3196, 4576, 6822, -341, -646, 6098, + -6332, -4527, -5839, 4942, 2805, 6652, 925, -1187, 3859, 4466, 5194, 4814, 7489, 8532, 2922, 2874, + -1137, 1068, 2253, 3741, -2505, 9887, 10247, 3472, 9158, 1176, -2976, 1937, -2064, 7351, 6057, 2696, + 532, 4702, 4601, 502, -1350, -5364, 9112, 2103, -4340, 18, -1329, -2532, 2939, 15707, 4071, -2154, + -628, 13794, -2239, -2982, -3391, -2332, -1483, 5699, 7418, 5487, 5469, 3426, 2471, 2248, -610, -2978, + 4520, 7035, 8360, 8190, 4367, 11231, 9045, 6518, 5468, 6414, -626, -2179, -2327, -6601, -11740, -18010, + 872, 6597, 9823, 6115, 5121, 3028, -3065, 9266, 9664, 2144, 2461, -758, -3373, -348, -421, -2786, + -2998, -2310, 5826, 14327, 10399, 10344, 5906, 4646, 4013, 7488, 6656, 3601, 212, 2499, 812, -4251, + -3455, -259, -2801, -3743, -3930, 4402, 11531, 8368, 3812, 2663, -1885, -3062, -3413, -12432, -6348, -1832, + -2574, 1227, -6578, -7396, -131, 1139, 3464, 2303, 6848, 4302, 422, 1994, 4840, 6023, 4369, 1222, + -5186, -3043, -5221, 9413, 9009, 6329, 6302, 7712, 4428, -1745, -1711, 1216, 1855, 1215, 1003, 58, + 3844, 4380, -2452, 17587, 5229, 106, 3809, 5238, 2909, -6280, 6367, 4649, 3777, 2815, 4377, 9833, + -3469, 6722, -2982, 1867, 2944, 3428, -115, -6063, 4740, 2369, 3681, 2580, 319, 76, 4169, 1079, + 5357, 7937, 8749, 6732, 3237, 475, 10599, 7708, 2300, 9384, 6872, 6516, 11437, 2109, -2788, -10922, + -2925, 1420, 3109, 500, 6953, 1289, -522, 1064, 2885, 6445, 3595, 2000, 2669, 2797, 2174, 873, + 1980, 6159, 1331, 1321, -1922, 6722, 11666, 3321, -1515, 1233, -1664, 9262, 9668, 2502, 13862, 9666, + 3582, 10575, 2715, -603, 596, -1567, 4182, 49, 2208, 1795, 10525, 9472, -2866, -8439, 7591, 11197, + -2356, 153, -10244, -4768, -2178, -2408, 1367, 708, 4615, 9681, 13007, 14875, 15382, 12708, 8355, 5074, + -358, 1803, 1987, 7888, 9168, 16089, 2288, -2716, -1669, 1078, 1165, 5324, 4412, -4354, 298, 6519, + 4826, 9355, 6507, 12087, 4177, -6, 2865, -2898, -5149, 6100, -1829, 80, 12459, 4967, 591, 7846, + -3452, 13887, -142, 4052, 5842, 3702, 4535, 2718, 4976, 3690, 1377, -72, -1938, -836, 961, -1944, + 4315, 5391, 6496, 1795, -2279, 20485, 16142, 9768, 8889, 6390, 1789, 3149, 4186, 487, -922, -2249, + -1225, 14246, 10277, 980, 2427, 180, 5713, 4730, -901, 590, 3351, 1871, 4389, 4760, 8650, 3433, + 1760, 3580, 5798, 6813, 4246, 17695, 7227, 4364, 2222, 13912, 11731, 10965, 14919, 7273, -6023, 6474, +}; /*----------------------------------------------------------------------------------* * LSF quantization - Scaling factors @@ -12561,24 +17983,35 @@ const float stable_LSP[M] = 0.9899f, 0.9667f, 0.8998f, 0.7837f, 0.6581f, 0.5009f, 0.3307f, 0.1643f, -0.0224f, -0.1955f, -0.3658f, -0.5200f, -0.6730f, -0.8040f, -0.9057f,-0.9700f }; -#ifdef IVAS_FLOAT_FIXED +/* Stable ISP vector in Q15 */ +const Word16 stable_ISP_fx[16] = { 32139, 30274, 27247, 23170, 18206, 12540, 6393, 0, -6390, -12537, -18203, -23170, -27243, -30271, -32139, 1475 }; +/* Stable LSP vector in Q15 */ /* This LSP corresponds to GEWB_Ave_fx */ -const Word16 stable_LSP_fx[M] = -{ - 32437, 31676, 29486, 25681, 21564, 16413, 10838, 5385, -735, -6405, -11986, -17040, -22052, -26346, -29678, -31784 -}; -#endif +const Word16 stable_LSP_fx[16] = { 32437, 31676, 29486, 25681, 21564, 16413, 10838, 5385, -735, -6405, -11986, -17040, -22052, -26346, -29678, -31784 }; + +/* stable ISF vector */ +const Word16 stable_ISF_fx[M] = +{ 1023, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13311, 14335, 15361, 3978 }; /*----------------------------------------------------------------------------------* * LSF quantization - Mean LSF vectors *----------------------------------------------------------------------------------*/ /* These are not used anywhere */ /* A 16-by-1 matrix */ -const float means_wb_cleanspeech_lsf16k0[16] = {355.08f, 696.48f, 1260.55f, 1735.55f, 2220.70f, 2676.17f, 3123.44f, 3560.94f, 3989.45f, 4399.61f, 4869.14f, 5372.66f, 5894.53f, 6364.45f, 6883.20f, 7302.73f}; +const float means_wb_cleanspeech_lsf16k0_flt[16] = {355.08f, 696.48f, 1260.55f, 1735.55f, 2220.70f, 2676.17f, 3123.44f, 3560.94f, 3989.45f, 4399.61f, 4869.14f, 5372.66f, 5894.53f, 6364.45f, 6883.20f, 7302.73f}; /* A 16-by-1 matrix */ -const float means_swb_cleanspeech_lsf25k6[16] = {614.44f, 1437.24f, 2259.37f, 2994.68f, 3732.57f, 4420.10f, 5187.93f, 5985.97f, 6790.66f, 7523.16f, 8283.87f, 9010.86f, 9757.03f, 10458.90f, 11209.84f, 11888.64f}; +const float means_swb_cleanspeech_lsf25k6_flt[16] = {614.44f, 1437.24f, 2259.37f, 2994.68f, 3732.57f, 4420.10f, 5187.93f, 5985.97f, 6790.66f, 7523.16f, 8283.87f, 9010.86f, 9757.03f, 10458.90f, 11209.84f, 11888.64f}; /* A 16-by-1 matrix */ -const float means_swb_cleanspeech_lsf32k0[16] = {739.65f, 1811.71f, 2794.79f, 3708.53f, 4594.87f, 5528.75f, 6583.99f, 7512.05f, 8455.51f, 9352.67f, 10266.73f, 11133.74f, 12067.91f, 12958.21f, 13940.67f, 14794.15f}; +const float means_swb_cleanspeech_lsf32k0_flt[16] = {739.65f, 1811.71f, 2794.79f, 3708.53f, 4594.87f, 5528.75f, 6583.99f, 7512.05f, 8455.51f, 9352.67f, 10266.73f, 11133.74f, 12067.91f, 12958.21f, 13940.67f, 14794.15f}; + +/* Length 16 vector in Scale = 2.56f */ +const Word16 means_wb_cleanspeech_lsf16k0[16] = { 727, 1426, 2582, 3554, 4548, 5481, 6397, 7293, 8170, 9010, 9972, 11003, 12072, 13034, 14097, 14956 }; +/* Length 16 vector in Scale = 2.56f */ +const Word16 means_swb_cleanspeech_lsf25k6[16] = { 786, 1840, 2892, 3833, 4778, 5658, 6641, 7662, 8692, 9630, 10603, 11534, 12489, 13387, 14349, 15217 }; +/* Length 16 vector in Scale = 2.56f */ +const Word16 means_swb_cleanspeech_lsf32k0[16] = { 757, 1855, 2862, 3798, 4705, 5661, 6742, 7692, 8658, 9577, 10513, 11401, 12358, 13269, 14275, 15149 }; + + /* An 16-by-1 matrix */ const float SVWB2_Ave[16] = @@ -12665,6 +18098,53 @@ const float AUWB2_Ave[16] = { 364.4531f, 681.6406f, 1187.5000f, 1623.8281f, 2101.1719f, 2535.1563f, 2986.7188f, 3408.2031f, 3848.4375f, 4269.5313f, 4771.0938f, 5330.8594f, 5883.5938f, 6366.0156f, 6889.0625f, 7331.2500f }; + +const Word16 SVWB2_Ave_fx[16] = { 998, 1488, 2682, 3823, 5084, 6305, 7485, 8686, 9861, 11004, 12339, 13664, 15088, 16330, 17663, 18754 }; +/* An 16-by-1 matrix */ +const Word16 IANB_Ave_fx[16] = +{ + 726, 1433, 2493, 3408, 4340, 5215, 6103, 6947, 7772, 8536, 9252, 10012, 10909, 12427, 13997, 15193 +}; +/* An 16-by-1 matrix */ +const Word16 IAWB_Ave_fx[16] = +{ + 577, 1350, 2526, 3535, 4539, 5504, 6497, 7460, 8445, 9396, 10371, 11319, 12307, 13268, 14249, 15207 +}; +/* An 16-by-1 matrix */ +const Word16 IAWB2_Ave_fx[16] = +{ + 731, 1777, 3194, 4386, 5629, 6806, 8012, 9164, 10329, 11469, 12731, 14037, 15326, 16538, 17801, 18927 +}; +/* Length 16 vector in Scale = 2.56f */ +const Word16 UVNB_Ave_fx[16] = { 1018, 1764, 2856, 3751, 4611, 5410, 6233, 6961, 7685, 8304, 8859, 9325, 9977, 11741, 13699, 15074 }; +/* Length 16 vector in Scale = 2.56f */ +const Word16 UVWB_Ave_fx[16] = { 898, 1900, 3172, 4190, 5181, 6161, 7134, 8066, 8995, 9888, 10784, 11636, 12527, 13396, 14301, 15183 }; +/* Length 16 vector in Scale = 2.56f */ +const Word16 SVNB_Ave_fx[16] = { 890, 1268, 1930, 2902, 3938, 4823, 5832, 6644, 7487, 8202, 8906, 9545, 10788, 12565, 13959, 15183 }; +/* Length 16 vector in Scale = 2.56f */ +const Word16 SVWB_Ave_fx[16] = { 832, 1248, 1949, 3083, 4131, 5117, 6179, 7067, 8008, 8922, 9875, 10741, 11785, 12860, 13968, 15048 }; +/* Length 16 vector in Scale = 2.56f */ +const Word16 GEWB_Ave_fx[16] = { 742, 1350, 2354, 3495, 4446, 5456, 6434, 7331, 8309, 9218, 10145, 11044, 12042, 13063, 14101, 15103 }; +/* Length 16 vector in Scale = 2.56f */ +const Word16 GEWB2_Ave_fx[16] = { 909, 1783, 3227, 4443, 5685, 6851, 7996, 9116, 10213, 11263, 12465, 13754, 15090, 16293, 17621, 18695 }; +/* Length 16 vector in Scale = 2.56f */ +const Word16 GENB_Ave_fx[16] = { 836, 1344, 2257, 3263, 4173, 5031, 5950, 6707, 7514, 8234, 8881, 9439, 10393, 12226, 13855, 15135 }; +/* Length 16 vector in Scale = 2.56f */ +const Word16 TRNB_Ave_fx[16] = { 919, 1335, 2106, 3142, 4092, 4938, 5905, 6670, 7490, 8199, 8868, 9444, 10544, 12383, 13900, 15156 }; +/* Length 16 vector in Scale = 2.56f */ +const Word16 TRWB_Ave_fx[16] = { 834, 1326, 2151, 3341, 4305, 5299, 6318, 7198, 8167, 9071, 10001, 10867, 11871, 12912, 13986, 15046 }; +/* Length 16 vector in Scale = 2.56f */ +const Word16 TRWB2_Ave_fx[16] = { 945, 1546, 2866, 4150, 5342, 6568, 7660, 8809, 9894, 10934, 12170, 13577, 14981, 16280, 17614, 18778 }; +/* Length 16 vector in Scale = 2.56f */ +const Word16 AUNB_Ave_fx[16] = { 887, 1443, 2356, 3194, 4105, 4949, 5841, 6635, 7437, 8181, 8867, 9478, 10385, 12182, 13858, 15131 }; +/* Length 16 vector in Scale = 2.56f */ +const Word16 AUWB_Ave_fx[16] = { 810, 1468, 2476, 3417, 4396, 5342, 6311, 7215, 8171, 9078, 10030, 10969, 12014, 13075, 14146, 15133 }; +/* Length 16 vector in Scale = 2.56f */ +const Word16 AUWB2_Ave_fx[16] = { 933, 1745, 3040, 4157, 5379, 6490, 7646, 8725, 9852, 10930, 12214, 13647, 15062, 16297, 17636, 18768 }; + + + + /* An 16-by-1 matrix */ const float Predictor0[16] = { @@ -12710,6 +18190,27 @@ const float Predictor8[16] = { 0.75500f, 0.75500f, 0.75500f, 0.75000f, 0.75000f, 0.75000f, 0.73499f, 0.72751f, 0.72000f, 0.71301f, 0.72751f, 0.72751f, 0.71301f, 0.70499f, 0.70499f, 0.67499f }; + +/* Length 16 vector in Q = 15 */ +const Word16 Predictor0_fx[16] = { 27361, 27361, 27361, 27197, 27197, 27197, 26378, 26460, 26214, 25985, 26460, 26460, 25985, 25723, 25723, 24740 }; +/* Length 16 vector in Q = 15 */ +const Word16 Predictor1_fx[16] = { 27034, 27034, 27034, 26640, 26313, 26640, 26640, 26132, 26214, 26214, 26460, 26870, 26870, 26706, 27034, 26640 }; +/* Length 16 vector in Q = 15 */ +const Word16 Predictor2_fx[16] = { 24248, 23593, 24510, 24248, 24510, 24019, 24019, 23757, 23757, 24019, 24248, 24248, 23593, 23101, 23593, 23101 }; +/* Length 16 vector in Q = 15 */ +const Word16 Predictor3_fx[16] = { 24248, 24248, 24740, 24248, 24510, 23757, 23429, 23101, 22610, 23101, 23593, 24740, 25002, 24740, 25002, 24838 }; +/* Length 16 vector in Q = 15 */ +const Word16 Predictor4_fx[16] = { 19005, 18350, 19268, 19005, 19268, 18776, 18776, 18514, 18514, 18776, 19005, 19005, 18350, 17859, 17695, 17203 }; +/* Length 16 vector in Q = 15 */ +const Word16 Predictor5_fx[16] = { 23839, 23593, 23593, 23839, 23839, 23593, 23593, 23593, 23839, 24084, 24347, 24576, 24576, 23364, 23364, 23364 }; +/* Length 16 vector in Q = 15 */ +const Word16 Predictor6_fx[16] = { 24084, 23839, 24084, 23593, 23593, 22938, 22381, 21791, 21135, 21955, 22381, 24347, 24576, 23593, 24576, 24347 }; +/* Length 16 vector in Q = 15 */ +const Word16 Predictor7_fx[16] = { 24347, 24084, 24347, 24347, 24347, 24084, 24347, 24576, 24576, 24740, 25068, 24347, 24084, 23839, 23364, 24740 }; +/* Length 16 vector in Q = 15 */ +const Word16 Predictor8_fx[16] = { 24740, 24740, 24740, 24576, 24576, 24576, 24084, 23839, 23593, 23364, 23839, 23839, 23364, 23101, 23101, 22118 }; + + /* An 16-by-16 matrix */ const float UVD_MA1[256] = { @@ -13154,6 +18655,28 @@ const float CNG_SN1[256] = 451.9531f, 710.9375f, 1072.2656f, 1369.1406f, 1700.7813f, 1991.0156f, 2317.1875f, 2596.8750f, 2893.7500f, 3138.2813f, 3373.0469f, 3548.0469f, 3897.2656f, 4776.5625f, 5398.0469f, 5901.5625f, 223.4375f, 547.2656f, 982.0313f, 1367.5781f, 1758.9844f, 2134.7656f, 2526.9531f, 2904.2969f, 3287.5000f, 3643.7500f, 4025.7813f, 4417.5781f, 4815.6250f, 5196.4844f, 5588.2813f, 5961.3281f }; +/* An 16-by-16 matrix */ +const short CNG_SN1_fx[256] = +{ + 600, 1640, 3039, 4257, 5512, 6740, 7989, 9169, 10393, 11612, 12880, 14100, 15378, 16554, 17816, 18918, + 1188, 2487, 3746, 4903, 6103, 7261, 8437, 9587, 10776, 11954, 13172, 14355, 15564, 16712, 17913, 19012, + 346, 799, 2259, 3555, 4876, 6175, 7516, 8803, 10073, 11323, 12631, 13938, 15282, 16553, 17817, 19039, + 439, 1616, 3446, 4743, 6073, 7288, 8553, 9726, 10947, 12106, 13312, 14474, 15650, 16773, 17894, 18977, + 921, 1800, 2976, 4007, 5105, 6137, 7178, 8150, 9057, 9914, 11009, 12545, 13671, 15502, 17428, 18927, + 896, 1899, 3035, 4128, 5301, 6429, 7604, 8719, 9886, 11059, 12417, 13621, 14962, 16135, 17475, 18460, + 722, 1507, 2537, 3437, 4328, 5190, 6018, 6841, 7587, 8343, 8925, 9511, 9919, 11075, 13613, 15021, + 315, 612, 1671, 2910, 3990, 5083, 6120, 7170, 8188, 9173, 10148, 11186, 12250, 13262, 14290, 15284, + 885, 1928, 3010, 3973, 4952, 5900, 6848, 7769, 8701, 9609, 10581, 11540, 12508, 13450, 14412, 15349, + 338, 1020, 2657, 3736, 4839, 5791, 6806, 7760, 8738, 9659, 10627, 11567, 12534, 13468, 14416, 15334, + 1126, 1964, 2999, 3855, 4764, 5608, 6482, 7286, 8109, 8827, 9570, 10649, 11999, 13125, 14223, 15252, + 385, 815, 2000, 2939, 3906, 4879, 5793, 6734, 7661, 8526, 9309, 10146, 11597, 12955, 14106, 15241, + 633, 1445, 2400, 3293, 4235, 5171, 6143, 7084, 8057, 8980, 9924, 10924, 11987, 12998, 14016, 15058, + 584, 1248, 2250, 3131, 4050, 4920, 5811, 6652, 7471, 8244, 8913, 9480, 10188, 12225, 13871, 15123, + 1157, 1820, 2745, 3505, 4354, 5097, 5932, 6648, 7408, 8034, 8635, 9083, 9977, 12228, 13819, 15108, + 572, 1401, 2514, 3501, 4503, 5465, 6469, 7435, 8416, 9328, 10306, 11309, 12328, 13303, 14306, 15261, +}; + + /* An 16-by-32 matrix */ const float IAA_MA1[512] = { @@ -13393,6 +18916,12 @@ const float * const ModeMeans[] = {IANB_Ave, UVNB_Ave, SVNB_Ave, GENB_Ave, TRNB_ const float * const Predictors[] = {Predictor6, NULL, Predictor1, Predictor3, NULL, Predictor6,Predictor5, NULL, Predictor0, Predictor2, NULL, Predictor5, Predictor7, NULL, Predictor8, Predictor4, NULL, Predictor7 }; +const Word16 *const ModeMeans_fx[] = { IANB_Ave_fx, UVNB_Ave_fx, SVNB_Ave_fx, GENB_Ave_fx, TRNB_Ave_fx, AUNB_Ave_fx, IAWB_Ave_fx, UVWB_Ave_fx, + SVWB_Ave_fx, GEWB_Ave_fx, TRWB_Ave_fx, AUWB_Ave_fx, IAWB2_Ave_fx, NULL, SVWB2_Ave_fx, GEWB2_Ave_fx, TRWB2_Ave_fx, AUWB2_Ave_fx +}; +const Word16 * const Predictors_fx[] = { Predictor6_fx, NULL, Predictor1_fx, Predictor3_fx, NULL, Predictor6_fx,Predictor5_fx, NULL, Predictor0_fx, + Predictor2_fx, NULL, Predictor5_fx, Predictor7_fx, NULL, Predictor8_fx, Predictor4_fx, NULL, Predictor7_fx +}; const float means_nb_31bits_ma_lsf_float[16] = {336.3281f , 531.2500f , 886.7188f , 1266.7969f , 1629.2969f , 1973.4375f , 2348.4375f , 2646.8750f , 2998.4375f , 3292.1875f , 3591.4062f , 3806.2500f , 4132.8125f , 4652.7344f , 5250.0000f , 5883.2031f}; const float means_wb_31bits_ma_lsf_float[16] = {319.5312f , 548.0469f , 934.3750f , 1353.5156f , 1730.0781f , 2120.3125f , 2505.4688f , 2860.5469f , 3243.7500f , 3601.9531f , 3969.5312f , 4332.4219f , 4736.3281f , 5137.8906f , 5562.8906f , 5963.2812f}; @@ -13813,33 +19342,12 @@ const Word16 AUWB2_SN1_fx[256] = -79, -389, -569, -699, -811, -940, -1058, -1299, -1534, -2077, -1953, -507, -216, 143, 191, 607, -106, -116, -210, -225, -323, -330, -494, -491, -700, -757, -1057, -1424, -2222, -1509, -259, 348, -366, -748, -1177, -1216, -1017, -698, -444, -154, 10, 285, 361, 284, 255, 359, 187, 365, - 77, 447, 418, 475, 453, 459, 475, 515, 562, 648, 658, 452, 367, 334, 244, 204, - 10, 197, 170, 166, 144, 60, 52, -2, -20, -40, 18, -238, -279, -434, -451, -807, - -460, -713, -547, -153, 64, 243, 386, 492, 620, 752, 759, 536, 445, 324, 151, -32, - -246, -396, -413, -371, -354, -317, -307, -228, -195, -101, -36, -174, -197, -162, -261, -349, - -329, -240, 326, 462, 428, 344, 405, 374, 439, 434, 467, 127, 85, -154, -248, -683, - -12, 15, -222, -227, -31, 124, 200, 294, 357, 541, 607, 459, 376, 352, 282, 283 -}; - -/* An 16-by-16 matrix */ -const short CNG_SN1_fx[256] = -{ - 600, 1640, 3039, 4257, 5512, 6740, 7989, 9169, 10393, 11612, 12880, 14100, 15378, 16554, 17816, 18918, - 1188, 2487, 3746, 4903, 6103, 7261, 8437, 9587, 10776, 11954, 13172, 14355, 15564, 16712, 17913, 19012, - 346, 799, 2259, 3555, 4876, 6175, 7516, 8803, 10073, 11323, 12631, 13938, 15282, 16553, 17817, 19039, - 439, 1616, 3446, 4743, 6073, 7288, 8553, 9726, 10947, 12106, 13312, 14474, 15650, 16773, 17894, 18977, - 921, 1800, 2976, 4007, 5105, 6137, 7178, 8150, 9057, 9914, 11009, 12545, 13671, 15502, 17428, 18927, - 896, 1899, 3035, 4128, 5301, 6429, 7604, 8719, 9886, 11059, 12417, 13621, 14962, 16135, 17475, 18460, - 722, 1507, 2537, 3437, 4328, 5190, 6018, 6841, 7587, 8343, 8925, 9511, 9919, 11075, 13613, 15021, - 315, 612, 1671, 2910, 3990, 5083, 6120, 7170, 8188, 9173, 10148, 11186, 12250, 13262, 14290, 15284, - 885, 1928, 3010, 3973, 4952, 5900, 6848, 7769, 8701, 9609, 10581, 11540, 12508, 13450, 14412, 15349, - 338, 1020, 2657, 3736, 4839, 5791, 6806, 7760, 8738, 9659, 10627, 11567, 12534, 13468, 14416, 15334, - 1126, 1964, 2999, 3855, 4764, 5608, 6482, 7286, 8109, 8827, 9570, 10649, 11999, 13125, 14223, 15252, - 385, 815, 2000, 2939, 3906, 4879, 5793, 6734, 7661, 8526, 9309, 10146, 11597, 12955, 14106, 15241, - 633, 1445, 2400, 3293, 4235, 5171, 6143, 7084, 8057, 8980, 9924, 10924, 11987, 12998, 14016, 15058, - 584, 1248, 2250, 3131, 4050, 4920, 5811, 6652, 7471, 8244, 8913, 9480, 10188, 12225, 13871, 15123, - 1157, 1820, 2745, 3505, 4354, 5097, 5932, 6648, 7408, 8034, 8635, 9083, 9977, 12228, 13819, 15108, - 572, 1401, 2514, 3501, 4503, 5465, 6469, 7435, 8416, 9328, 10306, 11309, 12328, 13303, 14306, 15261, + 77, 447, 418, 475, 453, 459, 475, 515, 562, 648, 658, 452, 367, 334, 244, 204, + 10, 197, 170, 166, 144, 60, 52, -2, -20, -40, 18, -238, -279, -434, -451, -807, + -460, -713, -547, -153, 64, 243, 386, 492, 620, 752, 759, 536, 445, 324, 151, -32, + -246, -396, -413, -371, -354, -317, -307, -228, -195, -101, -36, -174, -197, -162, -261, -349, + -329, -240, 326, 462, 428, 344, 405, 374, 439, 434, 467, 127, 85, -154, -248, -683, + -12, 15, -222, -227, -31, 124, 200, 294, 357, 541, 607, 459, 376, 352, 282, 283 }; /* An 16-by-32 matrix */ @@ -16721,10 +22229,19 @@ const float W_DTX_HO[HO_HIST_SIZE] = { 0.2f, 0.16f, 0.128f, 0.1024f, 0.08192f, 0.065536f, 0.0524288f, 0.01048576f }; + +const Word16 W_DTX_HO_FX[HO_HIST_SIZE] = /* Q15 */ +{ + 6554, 5243, 4194, 3355, 2684, 2147, 1718, 344 +}; const float ENR_ATT[5] = { 1.7938412f, 1.3952098f, 1.0962363f, 0.9965784f, 0.9965784f }; +const Word16 ENR_ATT_fx[5] = /*Q8*/ +{ + 459, 357, 281, 255, 255 +}; const float HO_ATT[5] = { 0.5370318f, 0.6165950f, 0.6839116f, 0.7079458f, 0.7079458f @@ -16744,7 +22261,13 @@ const float tbl_mid_gen_wb_2b[] = 0.4828f, 0.4701f, 0.1855f, 0.2034f, 0.1897f, 0.1691f, 0.1876f, 0.1558f, 0.1762f, 0.1863f, 0.1950f, 0.1997f, 0.2279f, 0.2492f, 0.3031f, 0.2513f, 0.8591f, 0.9902f, 0.8941f, 0.8507f, 0.8395f, 0.8579f, 0.8529f, 0.8665f, 0.8549f, 0.8490f, 0.8456f, 0.8310f, 0.8161f, 0.7884f, 0.7167f, 0.7381f }; - +const Word16 tbl_mid_gen_wb_2b_fx[] = +{ + 3814, 5145, 5856, 5290, 5277, 4880, 4877, 4273, 3868, 3776, 3392, 3163, 3120, 3019, 3395, 5814, + 1482, 861, 1968, 3198, 3105, 3737, 3749, 4525, 4982, 4828, 5023, 5335, 5327, 5296, 5092, 3444, + 3955, 3851, 1520, 1666, 1554, 1385, 1537, 1276, 1443, 1526, 1597, 1636, 1867, 2041, 2483, 2059, + 7038, 8112, 7324, 6969, 6877, 7028, 6987, 7098, 7003, 6955, 6927, 6808, 6685, 6459, 5871, 6047, +}; const float tbl_mid_gen_wb_4b[] = { 0.6754f, 0.6266f, 0.2594f, 0.4293f, 0.5988f, 0.6866f, 0.7737f, 0.8446f, 0.8367f, 0.7757f, 0.6525f, 0.4878f, 0.4399f, 0.6822f, 0.8499f, 0.9169f, @@ -16800,6 +22323,41 @@ const float tbl_mid_gen_wb_5b[] = 0.0608f, 0.0258f, 0.3738f, 0.8259f, 0.8728f, 0.9939f, 0.9193f, 0.9188f, 0.9589f, 0.8421f, 0.8073f, 0.7910f, 0.6457f, 0.5261f, 0.6520f, 0.5040f, 0.3360f, 0.8495f, 0.8652f, 0.5642f, 0.3230f, 0.2924f, 0.2144f, 0.0397f, 0.0596f, 0.0316f, -0.0152f, -0.0704f, -0.0675f, 0.0751f, 0.0680f, 0.5636f }; +const Word16 tbl_mid_gen_wb_5b_fx[] = +{ + 6510, 8058, 7103, 6095, 6483, 5866, 6026, 6443, 6882, 6907, 7015, 6581, 5649, 4044, 2816, 2519, + 3778, 2123, 3580, 4221, 2598, 4631, 2844, 4905, 5446, 4529, 5186, 6228, 6210, 5693, 6213, -4670, + 9050, 9934, 8441, 7921, 7546, 7840, 7977, 8335, 8679, 8706, 8703, 8607, 8560, 8375, 7759, 6405, + 4243, 5775, 2939, 5887, 4078, 3117, 5267, 5680, 4589, 2401, 731, 1011, 1657, 4733, 7051, 3992, + 2508, 3156, 3347, 1605, 4450, 4633, 3476, 6019, 4083, 3824, 5133, 6020, 3253, 1368, 1736, 13507, + 5934, 6372, 4494, 2957, 4424, 6667, 8167, 8413, 7957, 7139, 5518, 3059, 2829, 2821, 2773, 3274, + 4984, 5566, 5831, 4556, 5732, 6738, 6689, 4683, 2265, 4214, 7242, 9989, 9776, 9068, 4748, 2292, + 2601, 4933, 2764, 4923, 3763, 3678, 5596, 2079, 6108, 6824, 5507, 5612, 6793, 5553, 1140, 9993, + 7084, 6685, 5313, 5196, 3111, 5337, 3535, 2476, 2477, 1737, 2090, 4033, 5680, 6548, 7310, 11811, + 8140, 8602, 7166, 6738, 6018, 5299, 5686, 4722, 4108, 4456, 3713, 3131, 2658, 2336, 2250, 8051, + 727, 1865, 6073, 3932, 2258, 2413, 4823, 5733, 5101, 6126, 4690, 1130, 1172, 1479, 3956, 7204, + 6042, 1024, 5371, 5997, 4964, 5575, 5078, 5843, 6909, 8465, 8601, 6137, 5699, 8049, 9922, 8318, + 2728, 1625, 4750, 5004, 5799, 4938, 6353, 3274, 1781, 3095, 1479, 3136, 5470, 1391, -626, 2422, + 4407, 3228, 1266, 1488, 1222, 963, 1148, 1182, 1330, 1770, 860, 381, 813, 1268, 2352, 3956, + 1683, -120, 83, 1239, 946, 1609, 1982, 3215, 3950, 4200, 4497, 4898, 4551, 3595, 2345, 2444, + 1055, 3207, 7460, 6808, 7103, 6980, 7902, 8196, 6821, 6190, 6405, 7414, 7967, 7506, 6921, 9871, + 3164, 7995, 8446, 8770, 8443, 8302, 7372, 7049, 6090, 5698, 5090, 4792, 4996, 4874, 4285, 6685, + 3681, 319, 536, 3174, 4495, 5486, 5807, 5751, 5461, 4423, 3556, 3449, 5148, 7560, 6277, 3783, + 1987, 4209, 6954, 5880, 7459, 7762, 4326, 4958, 5154, 2150, 2988, 2469, 1175, 1099, 3999, 3950, + 1306, 2303, 7748, 8238, 6116, 2824, 1772, 1130, 2538, 3345, 5317, 4773, 3668, 5458, 5519, 5594, + 4140, 4329, 3339, 3001, 2669, -79, -582, -1729, -680, 1294, 2752, 3700, 3627, 4428, 4950, 2744, + 5309, 3611, 993, 3526, 2043, 3938, 2069, 1434, 4173, 2609, 2704, 3690, 3686, 1894, 1401, -1682, + 6091, 4810, 970, 1063, 1707, 3056, 4597, 6742, 7397, 6913, 7359, 7884, 7571, 6830, 6039, 3823, + 6599, 6006, 1248, 4330, 6935, 3784, 3535, 3902, 3221, 5384, 5691, 5997, 5975, 6731, 9125, 5385, + 204, 242, 2009, 3375, 3412, 3407, 2691, 2547, 598, -150, 67, 250, 618, 1185, 1987, 1157, + 4986, 7977, 6971, 1528, 86, 281, 1497, 3002, 4193, 4430, 4721, 5317, 6001, 6181, 6962, 5480, + 6914, 7963, 5254, 3050, 5365, 3224, 3781, 3044, 2571, 3155, 2243, 1612, 2157, 2526, 2784, -1629, + 7350, 6702, 2435, 1937, 2549, 1978, 2819, 2817, 2059, 2493, 3408, 2344, 1239, 1177, 914, 3763, + 4362, 3105, -1457, -1760, 314, 1452, 2603, 1642, 1670, 1652, 2258, 2492, 3844, 4399, 5213, 660, + 350, 357, 109, 83, -555, -886, -714, -587, -120, 25, 189, 531, 591, 146, 156, 1435, + 498, 211, 3062, 6766, 7150, 8142, 7531, 7527, 7855, 6898, 6613, 6480, 5290, 4310, 5341, 4129, + 2753, 6959, 7088, 4622, 2646, 2395, 1756, 325, 488, 259, -125, -577, -553, 615, 557, 4617, +}; @@ -16863,6 +22421,66 @@ const float tbl_mid_voi_wb_5b[] = 0.4576f, 0.3876f, 0.1800f, 0.0838f, 0.2449f, 0.2391f, 0.1902f, 0.3734f, 0.6560f, 0.6120f, 0.2977f, 0.2925f, 0.3012f, 0.2707f, 0.1258f, 0.9602f, 0.2486f, 0.0856f, 0.0151f, 0.0339f, 0.0400f, 0.0309f, 0.0806f, 0.0645f, 0.1008f, 0.0578f, 0.0978f, 0.0977f, 0.1286f, 0.1623f, 0.0981f, 0.1181f }; +const Word16 tbl_mid_voi_wb_1b_fx[] = /* Q13*/ +{ + 4551, 4599, 4754, 5035, 4982, 5228, 5318, 5603, 5699, 5652, 5642, 5766, 5825, 5874, 5819, 6056, + 3816, 3355, 2321, 2712, 2900, 2715, 2790, 2508, 2506, 2610, 2617, 2419, 2538, 2622, 3004, 2725, +}; +const Word16 tbl_mid_voi_wb_4b_fx[] = +{ + 4337, 4235, 3526, 4083, 3514, 5457, 3168, 2509, 4418, 5021, 1313, 2952, 5347, 3893, 8325, 11758, + 4180, 4037, 3965, 3481, 4028, 3284, 2644, 4585, 4749, 3076, 3211, 1101, 4175, 7440, 5745, -4105, + 4239, 3957, 4450, 4974, 5400, 5734, 6246, 6586, 7774, 2699, 2783, 3474, 1345, -316, 5069, 4904, + 3964, 3810, 2673, 3031, 2249, 3168, 3155, 4204, 7316, 7176, 8680, 7147, 4918, 4136, 3142, 3011, + 4071, 3853, 3898, 3973, 3464, 2878, 5783, 5341, 1725, 801, 1194, 4239, 6866, 4950, 794, 6270, + 3933, 3750, 4931, 3667, 3585, 2550, 4308, 5757, 4503, 7081, 4893, 1076, 109, 1650, 1887, 8861, + 4803, 4827, 4969, 5511, 5768, 4327, 5277, 4934, 6909, 7672, 5355, 3940, 9990, 9622, 7457, 4202, + 4515, 4259, 2444, 4847, 3728, 4599, 4975, 6144, 4087, 4367, 7025, 5028, 2405, 7014, 13366, 6264, + 4746, 4556, 5408, 5866, 4733, 4088, 3965, 3329, 4669, 3105, 5918, 7824, 6026, 9177, 1856, 13229, + 4130, 4214, 2516, 3542, 4847, 3751, 3704, 2380, 4190, 4787, 4651, 4981, 5702, -27, -2961, 129, + 4461, 4724, 5233, 4680, 6010, 7222, 6351, 3069, 605, 5934, 5627, 3836, 3490, 6060, 3556, 2585, + 4628, 4723, 5465, 4180, 4460, 6173, 5915, 7260, 4703, 4114, 3938, 9585, 8085, 3781, 7520, 625, + 5002, 5621, 6352, 6914, 7170, 7719, 7585, 8408, 8360, 7883, 7370, 7222, 6616, 6002, 5565, 9394, + 4059, 4121, 4178, 4417, 3437, 1460, 1031, 111, 585, 1708, 4219, 5419, 2585, 3195, 6149, 3221, + 3394, 2776, 1970, 2707, 2983, 3931, 3247, 1729, 449, -109, -46, -469, 397, 1980, 2305, 1573, + 3259, 1870, 242, 392, 748, 615, 1185, 1285, 2259, 2687, 2212, 1762, 2174, 1887, 1847, 2073, +}; +const Word16 tbl_mid_voi_wb_5b_fx[] = +{ + 4182, 3820, 4103, 5620, 4100, 4478, 3949, 5053, 2918, 3083, 4229, 3732, 1823, 6350, 17230, 4601, + 4361, 4077, 2236, 4128, 3216, 4673, 6022, 6522, 5746, 4282, 3121, 4448, 6457, 12573, 4401, 7796, + 4228, 4086, 4375, 4320, 4474, 4735, 4427, 5616, 5975, 138, 5887, 3722, 2304, -3430, 4995, 6246, + 4320, 4344, 4008, 4327, 3323, 6835, 3627, 3330, 3123, 3971, 2382, 1801, 6422, 3162, 9038, 14129, + 4193, 4202, 4413, 2703, 4175, 4330, 2615, 7600, 1717, 3506, 5671, 7170, 3545, 2350, -2738, 7287, + 4170, 3912, 4323, 3821, 4450, 6765, 7496, 8107, 7447, 5525, 3088, 1963, 2014, 3330, 976, 1002, + 4583, 4419, 3584, 4125, 4783, 5133, 3188, 5000, 4812, 4639, 10038, 7018, 5114, 5567, 3292, -6364, + 3926, 4092, 2710, 2721, 1799, 3509, 4542, 3351, 4583, 5877, 6539, 5135, 981, 4029, 7221, 592, + 4624, 4567, 4468, 4630, 5710, 5222, 5883, 2562, 8453, 2825, 109, 6491, 1210, 2921, 7292, 7118, + 4245, 4160, 5119, 4356, 5544, 3034, 1507, 4179, 5971, 1949, 3388, 613, 4995, 9019, 6755, -628, + 4905, 4962, 4529, 7025, 4905, 4470, 5063, 3440, 6348, 6102, 4319, 4395, 7515, 6549, -3697, 6513, + 4683, 4592, 5303, 4593, 4171, 5264, 6116, 7434, 4105, 5454, 2544, 8493, 6491, 894, 8983, -2406, + 3632, 3435, 3988, 4195, 3684, 2173, 6735, 4552, -339, 763, 308, 3463, 6123, 2895, 2831, 5715, + 4316, 4111, 2236, 2682, 1058, 544, 2541, 1677, 3549, 2767, 3376, 5901, 6689, 5811, 6617, 3311, + 4487, 4285, 4992, 3656, 5970, 4547, 3975, 5998, 4985, 6614, 4807, 1971, 14937, 4388, 6153, 3352, + 4601, 4710, 4957, 4454, 4873, 7207, 5881, 3461, 2282, 1829, 5617, 9926, 10043, 7722, 3232, 4629, + 3965, 3837, 2088, 4265, 5042, 3478, 4453, 2804, 4162, 4858, 4315, 4343, 5193, -1823, -5028, -1137, + 3439, 2837, 2549, 4062, 2857, 2657, 2662, 5088, 10548, 8913, 6631, 6395, 5568, 3210, 2431, 3400, + 4073, 3839, 5806, 5296, 3766, 2342, 2585, 891, 3144, 2988, 6807, 4626, 3700, 5854, 1543, 16158, + 4189, 4045, 4293, 4527, 4008, 1413, 4871, 6081, 3297, 6546, 5006, -365, -2369, 1375, 5522, 8787, + 4778, 4782, 4941, 4538, 4497, 3129, 4934, 4371, 7175, 6923, 8620, 10236, 8664, 10088, 10923, 7314, + 4945, 5016, 6439, 6353, 6624, 6463, 6938, 7547, 7004, 7283, 7655, 7149, 7650, 2747, 3416, 14892, + 4776, 5431, 5515, 6194, 5700, 5485, 2795, 5476, 4024, 8891, 2930, 7916, 3428, 8070, 5920, 13440, + 4718, 4986, 4800, 5286, 6567, 6554, 6601, 1235, -1216, 6556, 6098, 3962, 4361, 5536, 5517, 3935, + 4741, 4679, 5593, 4891, 3849, 5675, 6487, 6239, 7062, 12044, 10918, 2438, 3977, 7296, 8445, 6625, + 4859, 5781, 6592, 7399, 8027, 8858, 8139, 8951, 8760, 5506, 6294, 6540, 6516, 7527, 7688, 4084, + 4077, 3771, 3650, 3381, 3367, 4048, 3899, 4382, 3017, -2156, -1464, -2207, 828, 4838, 2071, 2363, + 3796, 3437, 3558, 3842, 2170, 4311, 2602, 696, 1939, 2576, 1239, 328, -129, -647, 1702, 2893, + 4015, 3506, 367, 1350, 3328, 3700, 3827, 2439, 1434, 3887, 2279, 1593, 3673, 5508, 3905, -2973, + 4088, 3990, 3732, 3256, 4718, 1375, 152, -99, -254, 1140, 3578, 3316, 2195, 2408, 5027, 999, + 3749, 3175, 1475, 686, 2006, 1959, 1558, 3059, 5374, 5014, 2439, 2396, 2467, 2218, 1031, 7866, + 2037, 701, 124, 278, 328, 253, 660, 528, 826, 473, 801, 800, 1053, 1330, 804, 967, +}; + const float tbl_mid_unv_wb_4b[] = { @@ -16919,7 +22537,60 @@ const float tbl_mid_unv_wb_5b[] = 0.5444f, 0.5385f, 0.4809f, 0.5395f, 1.1487f, -0.3404f, -0.3082f, -0.3512f, -0.2280f, 0.3479f, 0.5481f, 0.4996f, 0.3860f, 0.4747f, 0.4639f, 0.4263f, 0.7822f, 1.0122f, 1.0295f, 1.0430f, 1.0629f, 1.1165f, 1.1447f, 1.1354f, 1.1063f, 1.0919f, 1.0188f, 0.9977f, 0.8758f, 0.8855f, 0.7471f, 0.9058f }; - +const Word16 tbl_mid_unv_wb_4b_fx[] = +{ + 5190, 3143, 50, 2521, 5180, 6320, 3890, 3365, 3582, 3517, 3406, 3049, 2864, 1621, 1932, -950, + 6813, 6650, 2135, 972, 452, 1453, 3221, 1697, 3165, 4443, 5924, 6297, 3907, 2862, 3586, 4625, + 3204, 2673, 6499, 4319, 1054, 559, 4404, 5815, 5072, 6625, 4493, 2479, 1773, 1606, 2099, 8330, + 1924, 2666, 4171, 5517, 5898, 7238, 7318, 7696, 7250, 6269, 6164, 6038, 5249, 4284, 4147, 2828, + 2834, 788, 77, 2016, 1824, 3224, 3441, 4472, 6286, 6717, 6783, 6743, 6715, 7051, 6562, 2531, + 6386, 5634, 5761, 5184, 3523, 4284, 1867, 1045, 579, 1176, 1743, 2599, 5276, 5564, 5368, 7914, + 1795, 1380, 5184, 9326, 8023, 3138, 1258, 1729, 3328, 3934, 5169, 5645, 5271, 5894, 5591, 5145, + 5734, 5844, 8799, 8753, 5628, 5710, 5255, 4872, 5349, 3431, 3006, 2486, 1418, 974, 1115, 2035, + 4194, 8421, 1812, 6078, 3003, 3455, 6719, 7501, 2120, 1892, 2658, 2317, 2296, 5735, 6553, 4485, + 8072, 11456, 6455, 5069, 4918, 4936, 4819, 4932, 6029, 6246, 6289, 6704, 6749, 5337, 4526, 3974, + 3709, 5584, 4884, -1502, 4864, 2333, 606, 5976, 6438, 2413, 1937, 3663, 5593, 6989, 6450, 3555, + 3843, -6887, 3697, 3880, 4448, 4264, 5961, 4198, 3583, 3942, 3606, 3768, 4457, 4374, 4096, 4524, + 2551, 6781, 7017, 2902, 9227, 8728, 7130, 1873, 2308, 4393, 3981, 3976, 4002, 4080, 4820, 5611, + 220, -174, -43, -542, 449, 1470, 1759, 1893, 1294, 995, 723, 723, 769, 994, 1369, 4413, + 1651, 2259, 3079, 2913, 1176, -491, -1262, -827, -217, 908, 1126, 1751, 1901, 1765, 2656, 247, + 5380, 7307, 7727, 8135, 8270, 8471, 8792, 8573, 8335, 8420, 8057, 7562, 7119, 7458, 6806, 7385, +}; +const Word16 tbl_mid_unv_wb_5b_fx[] = +{ + 6237, 6323, 1151, 763, 4218, 6546, 8437, 8701, 7456, 6604, 4631, 2901, 3050, 1793, 1955, 2260, + 5542, 4318, 5343, 5521, 5999, 5477, 5265, 5234, 4616, 3329, 3444, 1816, -442, 45, -2, 8922, + 6370, 8208, 6583, 5630, 5401, 5458, 5188, 5595, 6637, 6891, 6962, 6967, 7014, 6330, 5445, 3101, + 2750, 2858, 5206, 4594, 3310, 3494, 2463, 3410, 3405, 6151, 7682, 8593, 4440, 3715, 2946, -4371, + 1157, 661, 3743, 6418, 7515, 8319, 7485, 7298, 7928, 7515, 6812, 5671, 5095, 5122, 4997, 3940, + 5133, 3446, 2693, 1620, 1860, 2663, 4603, 6289, 7451, 7255, 7511, 7486, 8869, 8704, 8431, 6632, + 2497, 6706, 7036, 3437, 10854, 8893, 6033, 3021, 2936, 4766, 4145, 4097, 5177, 4883, 5920, 7612, + -152, -54, 3955, 1170, 5562, 4695, 1370, 8293, 3106, 1942, 5508, 4878, 3495, 1094, 1079, 5401, + 482, 373, 220, -355, -236, -328, -426, -147, 244, 563, 567, 915, 1012, 676, 804, 2721, + 437, 816, 3208, 3395, 2501, 3795, 4380, 2553, 399, 31, -519, -475, -162, 1755, 2852, 1040, + 2067, 2125, 1247, 2393, 2872, 2218, 3502, 3977, 4712, 4275, 2600, 2380, 2314, 2893, 3555, 13929, + 3967, -635, -1752, 2490, 303, 969, 1045, 2839, 5670, 4651, 5202, 5248, 4182, 4381, 5492, 53, + 3041, 2494, 9264, 4970, 360, -3795, 6296, 6475, 4482, 6667, 5265, 2908, 2381, 2889, 3718, 5160, + 3364, 4119, 5929, 3164, -745, 9368, 1652, -719, 6323, 5113, 1919, 1260, 2630, 3585, 2224, 3178, + 1643, 837, 8074, 8337, 4237, 2332, 2190, -1176, 1968, 1238, 2354, 4756, 5269, 5759, 4962, 5411, + 7590, 6471, 2635, 1869, 1209, 1505, 2118, 892, 1652, 3717, 5010, 3969, 2265, 2428, 3278, 5027, + 7289, 8658, 11183, 8913, 6084, 6673, 5961, 4041, 3839, 2643, 2094, 3215, 2956, 2895, 3327, 5063, + 5814, -4982, 1120, 2112, 4384, 5288, 6052, 4305, 4724, 5062, 3380, 4200, 5838, 7181, 6383, 4771, + 3891, 7361, 4160, 1422, 4971, 939, 281, 3585, 4817, 1176, -306, 260, 3815, 8273, 7095, 1529, + 8179, 19416, 3518, 3547, 4619, 4231, 3359, 3606, 5131, 4469, 5204, 5115, 4941, 4772, 4175, 5160, + 4539, 5393, 2706, 5371, 1468, 8488, 10356, 2778, 1426, 371, 8093, 7808, 5208, 5996, 6081, 5057, + 3266, 3481, -4953, -5638, 4022, 5502, 3586, 3117, 2737, 3826, 3658, 3933, 3602, 4920, 4959, 3483, + 3846, 9592, 3360, 6480, 1215, 3170, 5218, 8641, 664, 2695, 3353, 1479, 1687, 6049, 7074, 4696, + 2231, 4497, 6761, 6799, 5941, 5445, 8083, 7944, 5879, 3744, 2518, 6482, 6581, 6096, 6379, -133, + 3360, 6078, 1064, 13807, 8185, 3605, 4327, 3777, 6211, 4977, 5015, 4871, 5825, 2506, 2130, 4946, + 5412, 4507, 952, 4098, 5027, 3949, 3501, 1778, 1955, 2126, 1626, 3669, 4446, -1101, 736, -2708, + 4824, 7481, 8884, -2619, -2754, 281, 4158, 3251, 4602, 2946, 3915, 6169, 6075, 3495, 3266, 4375, + 6135, 2668, 6784, 10326, 6892, 5479, 1511, 3070, 6410, 9193, 6954, 1084, 2873, 7030, 8139, 5670, + 7255, 5764, 5122, 5787, 3129, 5475, -2720, 3770, -827, 872, 1591, 4645, 7218, 5513, 5778, 6323, + 1185, -13100, 5560, 5867, 4153, 2591, 4923, 3450, 2062, 4251, 4289, 3397, 3835, 2082, 2343, 3172, + 4460, 4411, 3940, 4420, 9410, -2789, -2525, -2877, -1868, 2850, 4490, 4093, 3162, 3889, 3800, 3492, + 6408, 8292, 8434, 8544, 8707, 9146, 9377, 9301, 9063, 8945, 8346, 8173, 7175, 7254, 6120, 7420, +}; /*------------------------------------------------------------------------------* @@ -17031,8 +22702,12 @@ const int16_t Da_nq[NB_LEADER+2] = const int16_t skip_bands_SWB_TBE[NUM_SHB_SUBFR+1] = {0, 20, 40, 60, 80, 100, 120, 140, 160, 180, 200, 220, 240, 260, 280, 300, 320}; /* bands for SWB TBE quantisation */ const int16_t skip_bands_WB_TBE[NUM_SHB_SUBFR/2+1] = {0, 10, 20, 30, 40, 50, 60, 70, 80}; /* bands for WB TBE quantisation */ -const float interpol_frac_shb[NB_SUBFR*2] = { 0.7f, 0.3f, 0.4f, 0.6f, 0.1f, 0.9f, 0.0f, 1.0f }; - +const float interpol_frac_shb_flt[NB_SUBFR*2] = { 0.7f, 0.3f, 0.4f, 0.6f, 0.1f, 0.9f, 0.0f, 1.0f }; +const Word16 interpol_frac_shb[NB_SUBFR * 2] = +{ + 22938, 9830, 13107, 19660, 3277, 29490, 0, 32767 /* Q15*/ + /*0.7f, 0.3f, 0.4f, 0.6f, 0.1f, 0.9f, 0.0f, 1.0f */ +}; /* All pass filter coeffs for interpolation and decimation by a factor of 2 */ const float AP1_STEEP[ALLPASSSECTIONS_STEEP] = { 0.06056541924291f, 0.42943401549235f, 0.80873048306552f }; @@ -17101,6 +22776,13 @@ const float window_shb[L_SHB_LAHEAD]= /* sin, 1, sin */ 8.249975E-01f, 8.736224E-01f, 9.147939E-01f, 9.481606E-01f, 9.734381E-01f, 9.904104E-01f, 9.989330E-01f, 1.000000e+000f, 1.000000e+000f, 1.000000e+000f }; +const Word16 window_shb_fx[L_SHB_LAHEAD] = /*sin, 1, sin */ +{ + /*Q15(round) */ + 1513, 4527, 7502, 10413, 13236, 15945, 18518, 20934, 23170, 25210, + 27034, 28627, 29976, 31069, 31898, 32454, 32733, 32767, 32767, 32767, +}; + /* Upsampled overlap add window for SHB excitation used transition generation */ const float window_shb_32k[2*L_SHB_LAHEAD]= { @@ -17109,6 +22791,14 @@ const float window_shb_32k[2*L_SHB_LAHEAD]= 8.249975E-01f, 8.493099E-01f, 8.736224E-01f, 8.942082E-01f, 9.147939E-01f, 9.314773E-01f, 9.481606E-01f, 9.607993E-01f, 9.734381E-01f, 9.819242E-01f, 9.904104E-01f, 9.946717E-01f, 9.989330E-01f, 9.994665E-01f, 1.000000e+000f, 1.000000e+000f, 1.000000e+000f, 1.000000e+000f, 1.000000e+000f, 1.000000e+000f }; +const Word16 window_shb_32k_fx[2 * L_SHB_LAHEAD] = +{ + /*Q15(round) */ + 1513, 3020, 4527, 6015, 7502, 8958, 10413, 11825, 13236, 14590, + 15945, 17232, 18518, 19726, 20934, 22052, 23170, 24190, 25210, 26122, + 27034, 27830, 28627, 29301, 29976, 30523, 31069, 31483, 31898, 32176, + 32454, 32593, 32733, 32751, 32767, 32767, 32767, 32767, 32767, 32767, +}; /* Short overlap add window for SHB excitation used in anal and synth */ const float subwin_shb[SHB_OVERLAP_LEN+1]= @@ -17119,13 +22809,25 @@ const float subwin_shb[SHB_OVERLAP_LEN+1]= 0.853553391f, 0.904508497f, 0.945503262f, 0.975528258f, 0.993844170f, 1.000000000f }; - +const Word16 subwin_shb_fx[SHB_OVERLAP_LEN + 1] = +{ + /*Q15(round) */ + 0, 202, 802, 1786, 3129, + 4799, 6754, 8946, 11321, 13821, + 16384,18947, 21447, 23822, 26014, + 27969, 29639, 30982, 31966, 32566, + 32767 +}; const float window_wb[L_SHB_LAHEAD/4]=/* sin, 1 */ { 2.289505E-001f, 5.651364E-001f, 8.249975E-001f, 9.734381E-001f, 1.000000e+000f}; +const Word16 window_wb_fx[L_SHB_LAHEAD / 4] =/*sin, 1 */ +{ 7502, 18518, 27034, 31898, 32767 }; /*Q15*/ /* Short overlap add window for SHB excitation used in anal and synth */ const float subwin_wb[SHB_OVERLAP_LEN/2+1]= {0.00000000f, 0.15643448f, 0.30901700f, 0.45399052f, 0.58778524f, 0.70710677f, 0.80901700f, 0.89100653f, 0.95105654f, 0.98768836f, 1.0000000f}; +const Word16 subwin_wb_fx[SHB_OVERLAP_LEN / 2 + 1] = +{ 0, 5126, 10126, 14876, 19261, 23170, 26510, 29197, 31164, 32365, 32767 }; /* Window for calculating SHB LPC coeffs */ const float win_lpc_shb[(L_LOOK_12k8 + L_SUBFR + L_FRAME) * 5/8]= @@ -17503,8 +23205,268 @@ const float wb_bwe_lsfvq_cbook_8bit[256*6] = 0.136313630f, 0.18429069f, 0.26984493f, 0.34070980f, 0.40759216f, 0.45475266f, 0.240476170f, 0.27948010f, 0.32327234f, 0.37258368f, 0.41532038f, 0.45744253f }; - -const float swb_tbe_lsfvq_cbook_8b[256*LPC_SHB_ORDER] = +const Word16 wb_bwe_lsfvq_cbook_8bit_fx[256 * 6] = +{ + 2107, 3430, 5123, 6677, 9403, 13197, + 4031, 5069, 7343, 8910, 10647, 12245, + 2037, 3542, 6708, 8763, 10505, 12655, + 5732, 6373, 7912, 9546, 12584, 14230, + 2028, 3337, 5473, 7880, 10269, 12450, + 5809, 6497, 8317, 9624, 11497, 14007, + 2428, 3962, 5675, 7724, 11361, 13385, + 6348, 8307, 8898, 9948, 11058, 13350, + 3552, 4421, 5896, 7143, 9975, 13233, + 5719, 6344, 7482, 8403, 10765, 13455, + 3509, 4379, 5896, 7437, 11765, 14307, + 4521, 8122, 8791, 9856, 11232, 14020, + 2175, 3970, 7788, 9803, 11334, 12910, + 4511, 8156, 8886, 10450, 12686, 14959, + 4223, 5285, 7053, 8423, 11317, 14566, + 7159, 8379, 9040, 10122, 11799, 14270, + 1866, 3064, 4848, 7227, 11225, 13963, + 5915, 6631, 8740, 10002, 11385, 12726, + 3342, 4547, 6475, 9404, 11994, 13418, + 6156, 6880, 8932, 10353, 12380, 13746, + 2648, 4972, 7575, 9476, 12117, 13875, + 5822, 6526, 8747, 10941, 12671, 13971, + 4032, 5110, 7592, 9267, 11374, 14390, + 6864, 8384, 9086, 10649, 12944, 15026, + 3661, 4636, 6668, 8329, 10374, 12185, + 5802, 6444, 8344, 9811, 12234, 14843, + 3593, 4436, 6663, 8693, 11539, 14272, + 5110, 8270, 9006, 10703, 12269, 13901, + 1992, 3229, 5616, 9085, 11419, 13254, + 4319, 5859, 9602, 11396, 12836, 14199, + 3836, 4822, 8285, 10190, 11728, 13302, + 8016, 8698, 10179, 11434, 12944, 14783, + 1891, 3329, 6168, 8307, 10818, 14213, + 5803, 6442, 7973, 9131, 11090, 12657, + 2803, 5499, 8093, 9694, 11223, 12849, + 6222, 6981, 8615, 9848, 12016, 13380, + 2543, 4747, 7638, 9373, 11129, 13652, + 5912, 6615, 9006, 10553, 11959, 13312, + 3604, 4520, 7650, 9833, 12161, 14748, + 7970, 8729, 9780, 10789, 12483, 13985, + 3793, 4716, 7041, 8547, 10610, 13601, + 5640, 6235, 7313, 8370, 12057, 14300, + 3765, 4699, 6784, 9512, 12663, 14216, + 4634, 8363, 9195, 10385, 11477, 13310, + 2462, 4816, 8556, 10394, 11920, 13468, + 3698, 7974, 9207, 10962, 13507, 15208, + 3738, 4667, 7545, 10775, 13024, 14559, + 7267, 8610, 9509, 11264, 12821, 14495, + 2624, 4295, 6173, 8897, 12343, 14174, + 6324, 7135, 8742, 10013, 12598, 14108, + 4448, 5839, 8842, 10335, 11737, 13071, + 6147, 6988, 9510, 10893, 12240, 13535, + 3025, 5140, 7152, 9223, 11404, 13255, + 5985, 6782, 9611, 11341, 12723, 14007, + 4679, 5958, 8100, 9842, 11835, 13492, + 7740, 8565, 9432, 10478, 12611, 14609, + 3830, 4784, 7681, 9528, 11134, 12675, + 5742, 6527, 8359, 10728, 13195, 14626, + 4491, 5635, 7284, 8749, 11594, 13785, + 6772, 8490, 9253, 10943, 12476, 13973, + 2024, 3588, 7524, 10453, 12198, 13858, + 5783, 8882, 9978, 11763, 13237, 14829, + 3979, 5009, 8342, 10323, 12231, 14313, + 8148, 8903, 10193, 11350, 13246, 14490, + 2297, 3810, 5638, 7265, 9162, 11514, + 5809, 6518, 7832, 8766, 10327, 11957, + 2535, 4591, 7415, 9080, 10623, 12257, + 5948, 6598, 8515, 10082, 12721, 14188, + 2443, 4278, 6581, 8172, 9883, 11807, + 5913, 6535, 8878, 10296, 12141, 14245, + 2428, 3925, 6409, 9835, 11962, 13628, + 7430, 8531, 9302, 10259, 11444, 12933, + 3701, 4694, 6372, 7671, 9445, 11571, + 5822, 6470, 7807, 8885, 11506, 14529, + 3742, 4580, 6232, 7860, 11252, 13127, + 5710, 8330, 8943, 10243, 11696, 14511, + 2607, 4197, 6714, 10408, 12714, 14320, + 4116, 8438, 9717, 11018, 12156, 13663, + 4224, 5318, 7486, 10110, 12779, 14331, + 5565, 8413, 9115, 10930, 12588, 14759, + 1898, 3150, 5779, 9497, 12432, 14439, + 6274, 7186, 9258, 10404, 11733, 12952, + 3700, 4591, 7575, 9533, 11461, 13777, + 6234, 7104, 9032, 10986, 13088, 14417, + 2354, 4579, 7744, 9960, 12629, 14802, + 6050, 6729, 9345, 10745, 12436, 14253, + 4345, 5529, 8117, 9718, 12433, 14109, + 8009, 8701, 9863, 10954, 13046, 14474, + 4184, 5186, 6876, 8428, 11236, 12973, + 6113, 6842, 8386, 9659, 12892, 14707, + 3989, 4936, 7152, 8879, 11743, 13632, + 5169, 8411, 9209, 11361, 13452, 15076, + 2397, 4387, 7033, 9035, 11821, 13736, + 3607, 8128, 10170, 11565, 12819, 14147, + 4449, 5805, 8963, 10676, 12596, 14558, + 7911, 8741, 10040, 11622, 13579, 15092, + 2372, 4290, 6990, 8705, 10637, 13685, + 6137, 6917, 8382, 9380, 10859, 12348, + 3235, 5973, 8187, 10174, 12420, 14382, + 6077, 6764, 8551, 9803, 12150, 14079, + 2952, 5097, 6853, 8952, 12066, 14080, + 6606, 7683, 9508, 10695, 12182, 13601, + 3707, 4638, 7468, 10484, 12295, 13754, + 7960, 8715, 10051, 11348, 12757, 14072, + 4139, 5241, 7576, 9037, 10912, 13485, + 5838, 6444, 7768, 8965, 12867, 14998, + 4245, 5338, 7248, 9190, 12328, 14047, + 6159, 8874, 9899, 11134, 12150, 13512, + 2250, 4288, 8698, 10944, 12624, 14316, + 3146, 6848, 9904, 11775, 13534, 14953, + 4044, 5161, 8365, 10294, 12945, 14907, + 7398, 8724, 9813, 11821, 13246, 14552, + 2121, 3890, 6855, 9274, 12059, 14663, + 6329, 7182, 8789, 10081, 13001, 14917, + 4484, 5761, 8634, 10295, 12111, 14022, + 6326, 7208, 9672, 11078, 12830, 14529, + 3230, 5564, 7646, 9955, 12011, 13683, + 4683, 6896, 10002, 11805, 13329, 14747, + 4771, 6044, 8081, 10305, 12526, 14037, + 8231, 9203, 10351, 11427, 12926, 14635, + 4385, 5774, 7989, 9305, 10751, 12299, + 5810, 6658, 9062, 11629, 13359, 14655, + 4288, 5388, 7804, 9378, 11781, 13652, + 4398, 8560, 9646, 11161, 12701, 14872, + 1947, 3440, 7202, 10953, 13222, 14806, + 4686, 8972, 10615, 12054, 13260, 14615, + 3801, 4849, 8922, 11200, 12882, 14423, + 8061, 8813, 10453, 11912, 13335, 14710, + 2365, 3888, 5664, 7346, 10407, 14331, + 4563, 5839, 7472, 8684, 10572, 12800, + 2593, 4197, 6719, 9323, 11229, 12919, + 6081, 6774, 8132, 9244, 12202, 13918, + 2405, 3981, 6144, 8740, 11347, 13796, + 5793, 6444, 8286, 10049, 12152, 13520, + 2795, 4727, 6528, 8506, 11323, 13474, + 6181, 8598, 9346, 10614, 11725, 13545, + 4002, 5001, 6596, 7792, 9987, 13065, + 5748, 6365, 7759, 9028, 11818, 13487, + 3906, 4863, 6462, 7763, 10705, 14359, + 4315, 8428, 9322, 10582, 11942, 14500, + 2812, 4622, 7346, 10036, 11745, 13429, + 4221, 8338, 9277, 11280, 12869, 14317, + 4345, 5427, 7121, 8736, 12787, 14837, + 7678, 8614, 9456, 10461, 12024, 13852, + 2193, 3662, 5609, 7867, 12276, 14739, + 6083, 6864, 8879, 10080, 11623, 13720, + 4114, 5125, 7224, 9729, 11808, 13297, + 6383, 7232, 9252, 10720, 12622, 14030, + 2788, 5189, 8074, 9953, 11795, 14361, + 6079, 6987, 8662, 10589, 12444, 14390, + 4480, 5690, 7708, 9115, 11800, 14576, + 7848, 8763, 9802, 10924, 12515, 14832, + 3582, 4575, 6729, 9084, 11139, 12800, + 5885, 6534, 8853, 10432, 12664, 14960, + 3891, 4850, 7195, 8932, 12097, 14665, + 5797, 8545, 9385, 11556, 12997, 14392, + 1962, 3544, 7039, 9349, 11272, 13857, + 4106, 5493, 9652, 12038, 13603, 14932, + 4328, 5413, 7949, 10282, 12164, 13618, + 8135, 8918, 10057, 11085, 13190, 15015, + 2702, 4627, 6447, 8009, 10197, 13676, + 5998, 6656, 8315, 9496, 11597, 13122, + 3146, 6293, 8530, 10158, 11798, 13558, + 6374, 7289, 8698, 9776, 11885, 14236, + 3171, 5794, 7737, 9377, 11312, 13878, + 6279, 7150, 9192, 10414, 12052, 14174, + 4117, 5195, 7805, 9512, 12450, 14849, + 7963, 8955, 10071, 11129, 12324, 13605, + 4365, 5505, 7013, 8171, 10488, 13658, + 6124, 6894, 8286, 9349, 11859, 14737, + 3753, 4673, 6421, 8146, 12726, 14980, + 5457, 8706, 9598, 11035, 12294, 14268, + 2783, 4916, 7947, 10568, 12395, 14123, + 3909, 8145, 9524, 11951, 14052, 15282, + 3952, 5139, 8180, 11380, 13699, 15085, + 7200, 9031, 10025, 11484, 12924, 14848, + 2533, 4412, 6472, 8299, 11405, 14627, + 6563, 7530, 9064, 10267, 12560, 14422, + 4849, 6618, 8678, 10166, 11983, 13841, + 6393, 7569, 9960, 11300, 12644, 13906, + 3170, 5117, 7158, 9665, 11687, 14114, + 6122, 7071, 10013, 11733, 13170, 14466, + 4308, 5441, 7607, 9900, 11904, 14292, + 8129, 9024, 10087, 11081, 12670, 14356, + 4253, 5392, 8175, 9780, 11353, 12988, + 5453, 6638, 8596, 11453, 13885, 15263, + 4664, 5903, 7618, 9420, 12198, 13853, + 7149, 8859, 9746, 11029, 12219, 14188, + 2318, 4251, 7702, 9889, 11778, 14182, + 6679, 9280, 10573, 11950, 13100, 14491, + 4010, 5176, 8989, 10821, 12250, 13654, + 8076, 8886, 10411, 11722, 12992, 14267, + 2308, 4017, 6024, 7618, 9736, 13081, + 6001, 6751, 7987, 8966, 10964, 13589, + 2908, 5350, 7266, 8739, 10442, 12981, + 6143, 6839, 9027, 10366, 12881, 14416, + 2667, 4224, 6172, 8378, 10717, 12602, + 6275, 7120, 9249, 10613, 12580, 14823, + 2692, 4586, 6968, 9858, 12120, 14209, + 7771, 8769, 9743, 10745, 11943, 13225, + 4201, 5355, 7129, 8337, 9975, 11767, + 6216, 7100, 8444, 9442, 11298, 13690, + 4111, 5040, 6562, 8071, 12034, 13923, + 6657, 8599, 9337, 10665, 12040, 14704, + 3060, 5215, 7260, 10118, 12577, 14386, + 5103, 8913, 10157, 11519, 12669, 14220, + 4633, 5920, 7804, 9514, 12741, 14690, + 6720, 8585, 9448, 11556, 13510, 15095, + 2361, 3970, 6213, 9335, 13270, 15075, + 6506, 7440, 9041, 10179, 12024, 13587, + 4221, 5405, 8311, 9818, 11579, 14044, + 6216, 7224, 9515, 11389, 13545, 15068, + 2872, 5507, 8153, 10650, 13065, 14825, + 6002, 6676, 9393, 11023, 12965, 14755, + 4438, 5642, 8268, 10097, 12295, 14724, + 7797, 8622, 9642, 10932, 13287, 15118, + 4471, 5638, 7551, 9217, 11440, 12928, + 6051, 6890, 8906, 10655, 13437, 15116, + 3953, 4934, 7779, 9619, 12204, 14012, + 5439, 8649, 9791, 12232, 13899, 15193, + 2728, 4495, 6728, 9363, 11344, 14053, + 4069, 8460, 9835, 11742, 13366, 14825, + 4874, 6937, 9226, 10944, 12845, 14547, + 8195, 9093, 10392, 11594, 13355, 15010, + 2956, 5192, 7080, 8765, 11014, 14174, + 6384, 7287, 8812, 9816, 11336, 12808, + 2912, 6122, 9132, 10874, 12583, 14265, + 6148, 6925, 8821, 10030, 12212, 14758, + 2572, 4778, 7325, 9216, 11620, 14651, + 6654, 7718, 9546, 10806, 12633, 14354, + 4328, 5514, 8231, 10852, 12821, 14261, + 8051, 9205, 10385, 11490, 12674, 13988, + 4624, 6013, 7907, 9239, 11160, 13787, + 5786, 6531, 8210, 9968, 13410, 15249, + 3859, 4898, 7132, 9692, 13395, 15118, + 6712, 8944, 10028, 11521, 12690, 14118, + 2417, 4875, 9132, 11671, 13382, 14841, + 4113, 8355, 10734, 12517, 13905, 15115, + 4455, 5753, 7923, 10298, 13343, 15030, + 6998, 8878, 10113, 12233, 13768, 15107, + 2720, 4801, 6883, 9267, 12694, 14837, + 6507, 7496, 9312, 10696, 13185, 14850, + 4631, 6341, 9164, 10796, 12325, 13734, + 6602, 7817, 9932, 11349, 13132, 14672, + 3089, 5561, 7579, 9433, 12256, 14633, + 6246, 7715, 10371, 12065, 13563, 14878, + 4757, 6352, 8543, 10216, 12748, 14620, + 8183, 9366, 10628, 11857, 13185, 14599, + 4734, 6314, 8348, 9716, 11274, 12942, + 5824, 6871, 9829, 12268, 13874, 15138, + 4719, 6142, 8224, 9683, 11915, 14350, + 6288, 8774, 9655, 11204, 12696, 14867, + 2661, 4586, 7326, 10934, 13501, 15026, + 5932, 9323, 10877, 12454, 13715, 15004, + 4467, 6039, 8842, 11164, 13356, 14901, + 7880, 9158, 10593, 12209, 13609, 14989, +}; + + +const float swb_tbe_lsfvq_cbook_8b_flt[256*LPC_SHB_ORDER] = { 0.052035f, 0.098557f, 0.128235f, 0.155222f, 0.187634f, 0.220354f, 0.248003f, 0.327378f, 0.416763f, 0.468886f, 0.050902f, 0.090274f, 0.123988f, 0.172234f, 0.224479f, 0.288101f, 0.337089f, 0.374172f, 0.403673f, 0.442608f, @@ -17763,6 +23725,266 @@ const float swb_tbe_lsfvq_cbook_8b[256*LPC_SHB_ORDER] = 0.065840f, 0.126504f, 0.164612f, 0.196957f, 0.220935f, 0.267816f, 0.338526f, 0.391567f, 0.453372f, 0.479359f, 0.044781f, 0.115425f, 0.177337f, 0.247881f, 0.284229f, 0.319088f, 0.355269f, 0.403159f, 0.444401f, 0.467850f }; +const Word16 swb_tbe_lsfvq_cbook_8b[256 * LPC_SHB_ORDER] = /* Q15 */ +{ + 1705, 3230, 4202, 5086, 6148, 7221, 8127, 10728, 13656, 15364, + 1668, 2958, 4063, 5644, 7356, 9440, 11046, 12261, 13228, 14503, + 1546, 2917, 4226, 5477, 6976, 8349, 9709, 11882, 13218, 14715, + 1158, 2729, 5177, 6967, 8297, 9611, 10655, 11668, 12757, 14415, + 1616, 3005, 4368, 5810, 7107, 8129, 9376, 10457, 12738, 14835, + 1232, 2451, 4145, 6446, 7741, 8993, 10377, 11898, 14213, 15314, + 1638, 3089, 5134, 6351, 7360, 8304, 9787, 12377, 13755, 15209, + 1264, 2543, 5564, 6686, 7958, 9481, 11021, 12517, 13875, 15147, + 1304, 2537, 3713, 4863, 6564, 7910, 9400, 11794, 13268, 14834, + 1652, 3245, 4686, 6405, 7931, 9223, 10591, 12020, 13193, 14759, + 1302, 2619, 4287, 5884, 7166, 8556, 10512, 12471, 13767, 15075, + 2034, 3467, 5577, 6530, 7674, 8783, 10920, 12798, 13727, 15002, + 2621, 3956, 5275, 6542, 7509, 8517, 9456, 10781, 12456, 14099, + 1496, 2653, 4147, 5637, 7370, 9233, 11817, 12986, 13968, 15046, + 2224, 3324, 4700, 5868, 7211, 8638, 11369, 12695, 13600, 14559, + 1267, 3050, 4707, 6321, 8663, 10140, 11174, 12453, 13425, 14844, + 1662, 2980, 4155, 5414, 6639, 7797, 9253, 11360, 12838, 14440, + 1521, 2856, 4944, 6367, 7506, 8857, 10971, 12183, 13275, 15006, + 1454, 2859, 4563, 5971, 7186, 8569, 10151, 11770, 13396, 14984, + 1143, 2942, 5267, 6840, 8377, 9457, 10589, 11615, 13892, 15271, + 1674, 3053, 4605, 5768, 7104, 8452, 10094, 11782, 12793, 13758, + 1702, 3261, 4723, 6245, 7899, 9494, 11010, 12387, 13680, 15066, + 1365, 2796, 5406, 6505, 7488, 8679, 10447, 12000, 13637, 15046, + 2090, 3931, 5788, 7157, 8254, 9717, 11007, 12081, 13238, 14880, + 1952, 3157, 4132, 5164, 6334, 7389, 9004, 11798, 14096, 15505, + 1641, 3212, 4919, 6364, 7863, 9311, 10766, 12234, 13694, 15054, + 1653, 3008, 4213, 5354, 6980, 8821, 11185, 12685, 13903, 15251, + 1856, 3444, 5146, 6579, 7801, 9250, 11062, 12947, 14145, 15291, + 1365, 3567, 5552, 6474, 7332, 8254, 9952, 11364, 13505, 14951, + 1488, 2896, 4521, 6279, 7880, 9446, 11418, 12921, 14431, 15465, + 1516, 3174, 5364, 6410, 7295, 8285, 10799, 12594, 14172, 15424, + 1738, 3416, 5237, 6878, 8440, 10539, 12105, 13063, 13924, 15150, + 1431, 2659, 3909, 5328, 6641, 7950, 9347, 11037, 13510, 14992, + 1400, 2646, 4233, 6366, 7749, 9220, 10560, 11594, 13046, 14992, + 1115, 2198, 3607, 5279, 8055, 9774, 11024, 12426, 13972, 15232, + 1360, 3418, 5724, 6973, 7912, 9078, 10810, 12437, 13630, 14826, + 1422, 3051, 5132, 6141, 7206, 8275, 9355, 10859, 13814, 15202, + 1080, 2227, 4117, 6404, 8080, 9318, 10934, 12404, 13688, 14827, + 1611, 3423, 4928, 6214, 7426, 8723, 10502, 11915, 13438, 15105, + 1947, 3524, 5198, 7008, 8358, 10006, 11397, 12444, 13583, 15135, + 1394, 2672, 4004, 5681, 6953, 8301, 9815, 12000, 13709, 15079, + 1788, 3193, 4579, 6221, 7874, 9170, 11186, 12647, 13521, 14538, + 1548, 2811, 4058, 5331, 6528, 7769, 10982, 12743, 13822, 15131, + 1751, 4007, 5154, 6463, 7935, 9470, 11103, 12406, 13337, 14520, + 2004, 3172, 5079, 6116, 7109, 8155, 10351, 12192, 13413, 14773, + 1644, 3185, 4750, 6290, 7816, 9271, 11041, 12831, 14139, 15341, + 2311, 3779, 5116, 6100, 7321, 9139, 10353, 12134, 13834, 15172, + 1723, 3339, 5049, 6754, 8353, 10290, 12048, 13157, 14206, 15460, + 2218, 3501, 4639, 5764, 6789, 7834, 9804, 11907, 13182, 14689, + 1640, 3173, 4679, 6202, 7660, 9120, 10773, 12395, 13894, 15200, + 1591, 3070, 4537, 6005, 7341, 8802, 10480, 12240, 13768, 15130, + 1169, 3611, 5983, 7054, 8601, 10022, 10948, 11927, 12834, 14747, + 1708, 3191, 4642, 6156, 7396, 8805, 10028, 11733, 13206, 14857, + 1519, 3082, 4752, 6484, 7730, 9328, 10796, 12003, 14524, 15513, + 2153, 3558, 5162, 6714, 7762, 8857, 10008, 12012, 13725, 15209, + 2680, 4053, 5310, 6996, 8309, 9343, 10361, 12333, 14224, 15498, + 2356, 3805, 5032, 5970, 6915, 7880, 8924, 12060, 13838, 15185, + 1807, 3439, 4962, 6483, 8013, 9556, 10952, 12327, 13686, 15059, + 1571, 2900, 4208, 6449, 7675, 8592, 11138, 12775, 14181, 15422, + 2006, 4262, 5508, 6414, 7621, 8725, 10788, 12605, 13609, 14776, + 1785, 3741, 5267, 6702, 8097, 9460, 10487, 11481, 12889, 14885, + 1647, 3223, 4795, 6391, 8007, 9620, 11575, 12955, 14100, 15381, + 1518, 3214, 5233, 6509, 7687, 8803, 11778, 13932, 14760, 15491, + 2136, 3647, 5373, 7317, 8671, 10261, 11786, 12933, 13820, 15186, + 1633, 3265, 4672, 5640, 6776, 7783, 8907, 10184, 12066, 14492, + 1690, 3028, 4184, 6049, 7489, 8678, 11045, 12244, 13372, 15016, + 1649, 3080, 4358, 5795, 7364, 8601, 10257, 12126, 13328, 15113, + 1850, 3286, 5392, 6765, 7826, 9185, 10506, 11776, 13248, 15163, + 2111, 3522, 4870, 6087, 7162, 8385, 9645, 10861, 12341, 14302, + 1529, 2909, 4136, 6783, 8064, 9325, 10942, 12094, 13886, 15169, + 1847, 3281, 4752, 6098, 7310, 8744, 10129, 12278, 13554, 14930, + 1149, 2767, 5869, 7479, 8514, 9723, 11235, 12300, 13871, 15068, + 1689, 3066, 4325, 5613, 6772, 7936, 9051, 12135, 13730, 15025, + 2127, 3394, 5263, 6880, 7874, 9155, 10305, 12136, 13494, 14437, + 1682, 3054, 4412, 6053, 7380, 8465, 9817, 12460, 14155, 15285, + 1799, 3430, 5123, 6594, 7934, 9609, 11472, 12791, 13686, 14849, + 1899, 3656, 5369, 6355, 7516, 8800, 9888, 11646, 13024, 13965, + 1410, 3252, 5101, 6050, 7480, 9912, 11739, 12806, 14085, 15186, + 1487, 3934, 5351, 6390, 7519, 8890, 11488, 12818, 13787, 14941, + 1562, 3156, 5075, 7044, 8872, 10271, 11479, 12632, 13907, 14993, + 1548, 2926, 4338, 5796, 7011, 8143, 9336, 11323, 13461, 14904, + 1421, 2907, 4736, 6272, 7730, 8977, 10453, 12374, 13840, 15234, + 1495, 2996, 4496, 6036, 7545, 9034, 10534, 12014, 13486, 14958, + 1388, 3203, 5691, 7076, 8578, 9661, 10874, 12326, 14433, 15423, + 1248, 2983, 5304, 6423, 7544, 8611, 10290, 11682, 12904, 14549, + 1496, 2988, 4632, 6342, 7852, 9329, 11175, 12546, 13758, 15182, + 1373, 3379, 5067, 6179, 7379, 8775, 10005, 11464, 14147, 15386, + 2537, 3849, 5533, 7263, 8318, 9657, 11346, 12355, 13955, 15314, + 2113, 3405, 4419, 5268, 6436, 8005, 10292, 12442, 13655, 15176, + 1620, 3681, 5454, 6406, 7459, 9354, 10872, 12035, 14163, 15279, + 1903, 3232, 4517, 5758, 7156, 8851, 10670, 12413, 14518, 15565, + 1714, 3779, 5166, 6557, 8107, 9168, 10560, 12854, 14208, 15329, + 1926, 3645, 5521, 7072, 7999, 8974, 9806, 11088, 13527, 15298, + 1820, 2840, 4726, 7091, 8261, 9758, 11218, 12148, 14064, 15262, + 2072, 3303, 5391, 6710, 7504, 8497, 10457, 12394, 14480, 15541, + 1627, 3294, 5209, 7432, 8846, 10147, 11517, 12890, 14488, 15411, + 2172, 3405, 4580, 5623, 6732, 7648, 8485, 9913, 13396, 15213, + 1581, 3058, 4633, 6225, 7724, 9238, 10779, 12240, 13650, 15094, + 1675, 2927, 4090, 5753, 7461, 8922, 10277, 11670, 13987, 15336, + 1868, 3611, 5256, 6927, 8093, 9434, 10998, 12144, 13380, 15165, + 1498, 3635, 5273, 6823, 7825, 8916, 9811, 10903, 12514, 14884, + 1448, 2626, 3930, 6895, 8348, 9746, 11404, 12565, 14288, 15325, + 1945, 3408, 4987, 6340, 7627, 8954, 10251, 12381, 13481, 14983, + 1956, 3759, 5388, 6894, 8466, 9962, 11460, 12759, 14145, 15321, + 1670, 3271, 4588, 5970, 7185, 8366, 9640, 12011, 13488, 14833, + 1964, 3444, 4826, 6213, 7936, 9097, 10785, 12617, 13612, 15229, + 1646, 3390, 4669, 6049, 7001, 7940, 10461, 12478, 14675, 15704, + 2202, 3782, 5107, 6754, 8280, 9628, 11687, 13028, 13871, 15207, + 2354, 3830, 5174, 6360, 7555, 8997, 10681, 11977, 13066, 14781, + 2351, 3525, 4892, 6386, 7616, 9133, 11859, 13061, 13946, 15004, + 2252, 3772, 5155, 6485, 7799, 9145, 10769, 12561, 13763, 15241, + 1714, 3107, 4725, 6097, 9158, 10459, 11619, 12699, 14346, 15256, + 1830, 3506, 4969, 5973, 6900, 7836, 8994, 11088, 13366, 14860, + 1856, 3406, 4898, 6367, 7810, 9186, 10422, 12172, 13969, 15331, + 2006, 3382, 4743, 6100, 7430, 8753, 10805, 12234, 13673, 15195, + 1491, 3607, 5343, 7464, 9179, 10087, 11024, 12099, 13199, 14956, + 1749, 3371, 5121, 6500, 7646, 8770, 9968, 11673, 13339, 14931, + 1857, 3506, 5083, 6595, 8200, 9739, 11138, 12528, 13884, 15137, + 1780, 3860, 5581, 6692, 7837, 8989, 10304, 12318, 13611, 15109, + 2164, 4463, 5655, 7632, 9047, 9922, 10784, 12950, 14723, 15589, + 2305, 3300, 4366, 5608, 6857, 7795, 10006, 11950, 14376, 15700, + 1628, 3408, 5074, 6761, 8312, 9687, 11104, 12332, 13619, 15076, + 1842, 3314, 4771, 6460, 7463, 8661, 11191, 12739, 14592, 15633, + 1808, 4360, 5904, 6869, 8134, 9174, 10780, 12589, 13995, 15150, + 2966, 4354, 5686, 6983, 7938, 9092, 10062, 11747, 13307, 14611, + 1932, 3293, 4910, 6818, 7690, 9074, 11715, 13019, 14429, 15478, + 1978, 3772, 5429, 6580, 7448, 8496, 11755, 13132, 14549, 15560, + 1881, 3635, 5627, 7292, 8573, 10911, 12325, 13200, 14068, 15243, + 1436, 2716, 4002, 5347, 6553, 7646, 8955, 10690, 12967, 14784, + 1426, 2825, 4206, 5726, 8100, 9391, 10712, 12262, 13506, 14954, + 1448, 2767, 4089, 5265, 7185, 8684, 10378, 12257, 13431, 14803, + 1669, 3312, 4990, 6887, 8050, 9595, 10943, 12015, 13145, 14920, + 1534, 2814, 4191, 5933, 7393, 8687, 9865, 11185, 12958, 14743, + 1397, 2706, 4322, 6052, 7618, 9168, 10995, 12433, 13931, 15267, + 1717, 3164, 4630, 6329, 7519, 8846, 10088, 12116, 14012, 15197, + 1606, 3316, 5165, 6942, 8278, 9625, 11461, 12806, 14095, 15299, + 2014, 3357, 4281, 5076, 6191, 7372, 9501, 12414, 13419, 14901, + 1322, 3655, 5269, 6494, 7613, 9253, 10752, 11974, 13302, 14833, + 1687, 3291, 4718, 5817, 7001, 8136, 10741, 12692, 13884, 15224, + 2255, 3723, 5555, 7021, 8101, 9345, 10765, 12705, 13693, 15223, + 2376, 3715, 5249, 6505, 7410, 8345, 10176, 11618, 12708, 14488, + 1842, 3232, 4371, 5954, 7832, 9126, 11296, 12743, 13862, 15331, + 2046, 3597, 5325, 6453, 7353, 8588, 10588, 12082, 13664, 15152, + 1970, 3564, 4925, 6547, 8672, 9980, 11383, 12786, 13969, 15234, + 1497, 2938, 4909, 6099, 7102, 8072, 9514, 11294, 12761, 14578, + 1666, 3164, 5098, 6255, 7350, 8902, 10694, 12503, 13808, 14980, + 1467, 2774, 4556, 6308, 7435, 8644, 10040, 12356, 13597, 14776, + 1915, 3618, 5160, 6707, 8479, 9521, 10481, 11536, 14163, 15479, + 1857, 3466, 4760, 6205, 7312, 8801, 10376, 11978, 13161, 14235, + 1615, 3107, 4710, 6452, 8069, 9877, 11348, 12575, 13751, 15049, + 1563, 3092, 4977, 6851, 8056, 9025, 10327, 12181, 14039, 15192, + 2294, 3843, 5781, 7222, 8505, 9851, 11210, 12802, 13676, 15158, + 1931, 3436, 4681, 5837, 6908, 7825, 9440, 12600, 14162, 15305, + 1572, 3189, 4879, 6680, 7970, 9293, 10974, 12193, 13506, 15218, + 1759, 3172, 4687, 5950, 7484, 8874, 10563, 12821, 14112, 15299, + 1461, 4009, 5495, 6608, 7867, 9497, 11307, 12520, 14357, 15467, + 1922, 4314, 5736, 6599, 7481, 8598, 9852, 11345, 14012, 15280, + 1249, 2609, 4690, 7006, 8061, 9011, 11477, 13214, 14382, 15337, + 2251, 3776, 5514, 6458, 7300, 8078, 10961, 12696, 14279, 15567, + 1697, 3374, 5134, 6984, 8675, 10700, 12194, 13233, 14184, 15464, + 1985, 3326, 4440, 5685, 6870, 8207, 9545, 11223, 13672, 15143, + 1453, 2824, 4722, 6476, 7730, 8963, 10217, 11743, 13545, 15152, + 1217, 2442, 3821, 5409, 7315, 8949, 10797, 12564, 14281, 15410, + 1546, 3204, 5604, 6730, 8040, 9677, 11029, 12107, 13803, 15267, + 2042, 3424, 4830, 6328, 7473, 8525, 9386, 10755, 13398, 14998, + 1106, 2508, 4816, 7337, 8399, 9630, 11278, 12453, 14067, 15024, + 1764, 3305, 4955, 6537, 7767, 9117, 10404, 11961, 13576, 15021, + 1604, 3797, 5700, 7128, 8515, 9896, 11389, 12534, 13696, 15136, + 1623, 3004, 4355, 6217, 7351, 8437, 9819, 11537, 13974, 15340, + 2457, 3890, 4962, 5848, 7311, 9718, 11213, 12292, 13705, 15111, + 1601, 3330, 4648, 6043, 7138, 8179, 11247, 13078, 14768, 15641, + 2457, 3677, 5174, 6432, 7982, 10024, 11164, 12170, 13704, 15112, + 1552, 3777, 5267, 6325, 7532, 8642, 9894, 12404, 13569, 14620, + 1961, 3463, 4720, 6498, 8059, 9304, 11486, 12824, 14102, 15458, + 2443, 3699, 5252, 6348, 7638, 8733, 10224, 12666, 13768, 15009, + 2204, 3657, 5086, 6792, 8300, 10152, 12313, 13306, 14079, 15287, + 2360, 3731, 5002, 6094, 6952, 8009, 9152, 11586, 13038, 14158, + 1888, 3469, 4880, 6183, 7603, 9244, 10801, 12319, 13657, 15002, + 1670, 3283, 4591, 6080, 7801, 8951, 10534, 12572, 13620, 14969, + 1304, 4140, 5864, 7008, 8377, 9651, 10825, 11805, 13637, 15300, + 2077, 3547, 4890, 6216, 7303, 8608, 9810, 11796, 13525, 14984, + 1658, 3252, 4916, 6498, 8069, 9529, 11029, 12538, 13903, 15184, + 2206, 3648, 4949, 6636, 7875, 8833, 9853, 12624, 14448, 15475, + 3039, 4664, 5792, 7321, 8798, 9724, 10485, 12329, 14465, 15650, + 1885, 3201, 5227, 6590, 7343, 8049, 9372, 12313, 14594, 15645, + 1826, 3446, 5138, 6665, 8008, 9352, 10668, 12583, 13810, 15065, + 1455, 3065, 5233, 6306, 7404, 8776, 11422, 12775, 14032, 15239, + 2395, 4674, 5883, 6877, 7900, 9322, 10931, 12537, 13765, 14888, + 1840, 4359, 5629, 6875, 7968, 9185, 10266, 11861, 13202, 14464, + 1662, 3278, 4865, 6555, 8122, 10011, 11874, 13087, 14128, 15418, + 1643, 3366, 5837, 7033, 7854, 8928, 11487, 12972, 14409, 15467, + 1878, 3685, 5789, 7325, 8714, 10906, 12273, 13110, 13834, 14837, + 2259, 3652, 4995, 6055, 7005, 7900, 8843, 10024, 12609, 14736, + 1568, 2949, 4504, 6035, 7428, 9194, 10893, 12444, 13595, 14939, + 1678, 3143, 4416, 5872, 7501, 8768, 10418, 12127, 13144, 14622, + 1878, 3549, 5481, 7178, 8322, 9347, 10532, 12117, 13554, 15167, + 2055, 3346, 4814, 6193, 7418, 8757, 10144, 11365, 12698, 14779, + 1486, 2779, 3954, 6134, 8290, 9646, 10767, 12112, 14441, 15428, + 1787, 3511, 4962, 6055, 7295, 8858, 10179, 12437, 13813, 15217, + 1374, 3184, 5771, 7998, 9354, 10209, 11249, 12469, 14015, 15248, + 1627, 2947, 4046, 5182, 6798, 8225, 9770, 12661, 14250, 15408, + 2117, 3704, 5007, 6630, 8002, 9222, 10550, 12108, 13472, 15034, + 1365, 2885, 4896, 6144, 7426, 9137, 10283, 12727, 14709, 15505, + 2073, 3691, 5305, 6800, 8134, 9508, 11139, 12857, 13896, 15239, + 1564, 4084, 5497, 6495, 7391, 8539, 10468, 11705, 12804, 14704, + 1844, 3180, 4380, 5754, 8181, 9923, 11738, 12995, 14138, 15232, + 2157, 3736, 5059, 5932, 7192, 8916, 11216, 12783, 13945, 15189, + 1782, 2860, 4362, 7179, 9083, 10438, 11580, 12929, 14789, 15500, + 1651, 3273, 4587, 5886, 7069, 8346, 9787, 11277, 13152, 14811, + 1549, 3138, 5049, 6704, 7803, 9102, 10748, 12577, 13813, 15215, + 1674, 3187, 4709, 6204, 7622, 9024, 10541, 12135, 13576, 15063, + 1888, 3562, 5468, 7111, 8694, 9948, 11111, 12286, 14070, 15300, + 1905, 3158, 5368, 6372, 7554, 8719, 10568, 12430, 13449, 14427, + 1953, 3411, 4718, 6545, 8090, 9298, 11232, 12723, 13668, 15077, + 1459, 3444, 5688, 6814, 7843, 8977, 10119, 12107, 14316, 15368, + 2450, 4363, 5827, 7349, 8683, 10032, 11143, 12131, 13519, 15058, + 2482, 3664, 4763, 5944, 7191, 8390, 10105, 12234, 13702, 15188, + 1838, 3465, 5255, 6751, 8016, 9254, 10946, 12321, 13790, 15337, + 2497, 3548, 4702, 5987, 7645, 8883, 10740, 12247, 14393, 15540, + 1717, 3679, 5335, 6587, 8564, 9808, 10735, 12675, 14672, 15558, + 2454, 3997, 5364, 6810, 8026, 8913, 9715, 11315, 14258, 15605, + 1906, 3443, 4901, 6363, 8186, 9716, 11074, 13186, 14701, 15474, + 1992, 3246, 5488, 6514, 7455, 8324, 10807, 13238, 14763, 15579, + 1721, 3438, 5244, 7173, 9106, 10873, 12178, 13181, 14060, 15415, + 2191, 3555, 4802, 6108, 7015, 7850, 8947, 11115, 14483, 15593, + 1925, 3232, 4601, 6574, 7791, 8989, 11038, 12282, 13630, 15136, + 1816, 3167, 4292, 5730, 7588, 9096, 10743, 12341, 13760, 15252, + 2069, 3850, 5424, 6815, 8274, 9569, 10910, 12283, 13835, 15185, + 2419, 3773, 5288, 6591, 7672, 8909, 9832, 10975, 13163, 14998, + 1215, 2710, 4939, 6437, 8745, 9918, 11200, 12553, 14234, 15384, + 1867, 3527, 5134, 6496, 7656, 8923, 10602, 12568, 13896, 15276, + 2259, 4214, 5751, 7270, 8590, 10120, 11611, 12822, 14130, 15258, + 1911, 3261, 4446, 5685, 6897, 8494, 10128, 11970, 13707, 15106, + 1762, 3549, 4874, 6153, 8146, 9634, 10690, 11886, 13713, 15057, + 2371, 3716, 4778, 6111, 7097, 8063, 10544, 12615, 14716, 15724, + 2254, 3759, 5627, 6870, 7896, 9379, 11627, 12889, 13795, 15272, + 2516, 4000, 5378, 6444, 7496, 8634, 9767, 12110, 13503, 14640, + 2385, 3201, 4283, 6677, 8216, 9689, 11654, 12319, 14142, 15367, + 2775, 4055, 5455, 6553, 7821, 8901, 10890, 12775, 13696, 14884, + 1568, 3940, 5341, 6824, 9355, 10305, 11405, 12879, 14291, 15334, + 2436, 3807, 5183, 6189, 7099, 8116, 9655, 11275, 13641, 15137, + 1755, 3340, 4871, 6382, 7790, 9316, 10921, 12432, 13903, 15217, + 1932, 3246, 4603, 6454, 7590, 8678, 10609, 12641, 13938, 15245, + 1417, 4366, 6289, 7362, 8846, 10151, 11160, 12134, 13593, 15216, + 1820, 3378, 4782, 6421, 7788, 9056, 10070, 11271, 13614, 15297, + 1855, 3399, 4933, 6526, 8097, 9655, 11043, 12475, 14301, 15370, + 1901, 3653, 6053, 7290, 8154, 8986, 10262, 12993, 14405, 15387, + 1958, 4295, 5824, 8196, 9580, 10318, 11267, 12551, 13716, 15374, + 2082, 4060, 5500, 6423, 7298, 8128, 9713, 12497, 14442, 15562, + 1878, 3425, 4781, 7062, 8455, 9625, 10810, 12311, 13948, 15201, + 2035, 3727, 4804, 6256, 7248, 9235, 11563, 13120, 14882, 15662, + 2143, 3982, 6527, 7709, 8742, 9804, 11240, 12658, 14397, 15409, + 2593, 4431, 5861, 7222, 8381, 9351, 10400, 11837, 13286, 15326, + 1840, 3798, 5465, 6800, 7919, 9752, 12004, 13265, 14424, 15420, + 2157, 4145, 5394, 6454, 7240, 8776, 11093, 12831, 14856, 15708, + 1467, 3782, 5811, 8123, 9314, 10456, 11641, 13211, 14562, 15331, +}; + const float wac_swb[LPC_SHB_ORDER + 1] = { @@ -17777,6 +23999,15 @@ const float lbr_wb_bwe_lsfvq_cbook_2bit[4*4] = {0.11829331f, 0.18065347f, 0.2731 0.25797083f, 0.29579351f, 0.36694117f, 0.42482337f }; +const Word16 lbr_wb_bwe_lsfvq_cbook_2bit_fx[4 * 4] = +{ + /*Q15 */ + 3876, 5920, 8951, 11884, + 6556, 7979, 10835, 13133, + 4401, 6781, 10676, 13493, + 8453, 9693, 12024, 13921, +}; + const float wac[LPC_SHB_ORDER + 1] = { 1.000030000f, 0.999876638f, 0.999506642f, 0.998890286f, 0.998028026f, 0.996920500f, @@ -17821,6 +24052,43 @@ const float SHBCB_SubGain5bit[128] = -0.3547296f, -0.3050630f, -0.2355810f, -0.3526833f, -1.0319320f, -0.3646283f, -0.2706210f, -0.1999401f }; +const Word16 SHBCB_SubGain5bit_fx[128] = +{ + /*Q14 */ + -2388, -7806, -6576, -6024, + -7066, -5430, -4998, -3495, + -16722, -15343, -960, -7940, + -26291, -5921, -4917, -4378, + -1526, -6621, -8475, -9624, + -8047, -4086, -8940, -3043, + -3630, -5129, -4964, -7381, + -270, -18662, -24233, -25418, + -9246, -7551, -5584, -2053, + -2091, -4622, -9199, -14628, + -4645, -2197, -10255, -9697, + -2438, -9386, -11737, -4570, + -14366, -11436, -8252, -819, + -16192, -16332, -17043, -225, + -5407, -8588, -7577, -2296, + -26309, -21930, -7522, -2514, + -3260, -4246, -7947, -6614, + -1820, -5520, -15272, -19764, + -3706, -3737, -5850, -10520, + -10081, -4050, -4065, -5001, + -3908, -9909, -2881, -9604, + -520, -11156, -12620, -12768, + -4539, -5149, -6208, -4462, + -4866, -7672, -4235, -4407, + -9163, -13411, -2975, -3915, + -12267, -7568, -3842, -2827, + -7181, -4914, -2608, -9392, + -6275, -2868, -5962, -6511, + -12962, -1034, -8517, -10992, + -8247, -7608, -2502, -5026, + -5812, -4998, -3860, -5778, + -16907, -5974, -4434, -3276, +}; + /* 5-bit TD WB BWE temporal shaping codebook */ const float HBCB_SubGain5bit[128] = @@ -17858,6 +24126,26 @@ const float HBCB_SubGain5bit[128] = -6.772878f, -4.939885f, -7.817589f, -3.977276f, -2.728315f, -6.770474f, -8.485444f, -4.669493f }; +const Word16 HBCB_SubGain5bit_fx[128] = +{ + -15224, -17789, -9897, -5048, -456, -1232, -2238, -2782, + -3391, -3864, -4026, -4045, -2017, -1311, -878, -1973, + -12837, -15376, -8273, -4141, -2791, -3037, -2403, -342, + -3388, -3646, -3471, -2829, -157, -2025, -2318, -2243, + -14652, -16433, -7699, -1188, -2567, -1755, -346, -1682, + -2068, -2321, -2344, -2348, -1759, -1038, -1865, -2041, + -11396, -13719, -7749, -2734, -809, -1935, -1886, -781, + -2136, -1940, -942, -1571, -1926, -2378, -2572, -2145, + -17531, -19267, -7721, -2672, -714, -675, -1516, -2071, + -1925, -2325, -2523, -2657, -1644, -1674, -2036, -2017, + -12781, -14601, -6714, -1380, -2093, -1704, -1124, -756, + -2776, -2687, -2066, -1202, -1102, -680, -1956, -2376, + -14436, -15846, -4918, -2071, -1613, -744, -1807, -1381, + -620, -1294, -2026, -2162, -794, -1755, -1167, -1762, + -11627, -13377, -5876, -1959, -1009, -1879, -1027, -1915, + -1734, -1265, -2001, -1018, -698, -1733, -2172, -1195, + +}; /* 6 bit Quantizer table for SHB overall gain */ @@ -17872,6 +24160,18 @@ const float SHBCB_FrameGain64[64]= 14.56494800f, 16.38657700f, 18.56994600f, 21.17650800f, 24.29317200f, 27.95810000f, 32.33308400f, 37.72507700f, 44.44091200f, 52.62181300f, 62.89529200f, 76.21739000f, 94.34608600f, 119.5521800f, 160.0594500f, 245.1366400f }; +const Word32 SHBCB_FrameGain64_fx[64] = +{ + /* Q18 */ + 11553, 19429, 27466, 35948, 45184, 54817, 65050, 76114, + 88089, 100815, 114314, 128727, 144236, 160812, 178639, 197656, + 217917, 239688, 263098, 288617, 315962, 345380, 376751, 410569, + 446867, 485779, 527885, 574220, 624562, 679333, 738912, 803391, + 873329, 949299, 1032054, 1121728, 1219559, 1327347, 1446046, 1576547, + 1720983, 1881933, 2062979, 2266614, 2496129, 2759206, 3060575, 3409584, + 3818114, 4295643, 4868000, 5551295, 6368310, 7329048, 8475924, 9889403, + 11649918, 13794493, 16487623, 19979932, 24732260, 31339886, 41958624, 64261100, +}; /* 4 bit Quantizer table for SHB overall gain */ const float SHBCB_FrameGain16[16]= @@ -17894,6 +24194,13 @@ const float SHBCB_FrameGain16[16]= 735.8126500f }; +const Word32 SHBCB_FrameGain16_fx[16] = +{ + /*Q18*/ + 38968, 125277, 254474, 493383, 1043711, 2083177, 3792746, 6395076, + 10256080, 15738899, 23269902, 34118236, 48362464, 71128080, 107459896, 192888864 +}; + /* 18th order elliptic Bandpass filter at 14.15 to 20 kHz sampled at 48 kHz b0,b1,b2,a0,a1,a2 */ const float full_band_bpf_1[6][5] = { @@ -17972,12 +24279,30 @@ const float lsf_q_cb_3b[8] = 0.05307309f, 0.06137543f, 0.07216742f, 0.09013262f }; +const Word16 lsf_q_cb_4b_fx[16] = +{ + 589, 773, 914, 1043, + 1173, 1302, 1430, 1558, + 1698, 1843, 1973, 2103, + 2258, 2470, 2787, 3282 + +}; + +const Word16 lsf_q_cb_3b_fx[8] = +{ + 679, 976, 1245, 1491, + 1739, 2011, 2365, 2953 +}; + const float * const lsf_q_cb[NUM_Q_LSF] = { lsf_q_cb_4b, lsf_q_cb_4b, lsf_q_cb_3b, lsf_q_cb_3b, lsf_q_cb_3b }; +const Word16 * const lsf_q_cb_fx[NUM_Q_LSF] = { lsf_q_cb_4b_fx, lsf_q_cb_4b_fx, lsf_q_cb_3b_fx, lsf_q_cb_3b_fx, lsf_q_cb_3b_fx }; + const int16_t lsf_q_cb_size[NUM_Q_LSF] = {16, 16, 8, 8, 8}; const int16_t lsf_q_num_bits[NUM_Q_LSF] = { 4, 4, 3, 3, 3 }; /* Tables for approximation of upper half of SWB LSFs */ const float mirror_point_q_cb[MIRROR_POINT_Q_CB_SIZE] = { 0.01436178f, 0.02111641f, 0.02735687f, 0.03712105f }; +const Word16 mirror_point_q_cb_fx[MIRROR_POINT_Q_CB_SIZE] = { 471, 692, 896, 1216 }; const float lsf_grid[4][5] = { @@ -17986,9 +24311,17 @@ const float lsf_grid[4][5] = { 0.14185823f, 0.26648724f, 0.39740108f, 0.55685745f, 0.74688616f }, { 0.15416561f, 0.27238427f, 0.39376780f, 0.59287916f, 0.86613986f } }; - +const Word16 lsf_grid_fx[4][5] = +{ + { 5242, 10229, 15516, 21804, 27540, }, + { 5117, 10059, 14949, 20478, 25493, }, + { 4648, 8732, 13022, 18247, 24474, }, + { 5052, 8925, 12903, 19427, 28382, } +}; const float grid_smoothing[5] = { 0.2f, 0.35f, 0.5f, 0.75f, 0.8f }; +const Word16 grid_smoothing_fx[5] = { 6554, 11469, 16384, 24576, 26214 }; + const float allpass_poles_3_ov_2_flt[9] = { 0.072265625000000f, @@ -18068,7 +24401,17 @@ const float F_2_5[64] = 18.706564f, 18.308905f, 23.010420f, 22.915377f }; - +const Word16 F_2_5_fx[64] = /*Q10 */ +{ + 1189, 675, -5106, -5293, 10476, -12, 10860, 10026, + -382, -616, 6426, 339, 9681, 9068, 3002, 2216, + 3208, 3042, 8255, -604, 16133, 5171, 17641, 18769, + -2529, -3248, -1447, -1991, 15511, 14855, 11631, 11996, + 9654, -124, 7267, -1617, 12799, 3237, 10598, 1555, + 5510, -1775, 1149, -2292, 12659, 12425, 4382, -1814, + 6305, 5629, 3404, -2632, 19555, 9582, 7835, 7619, + -517, -3795, 19031, 11574, 19156, 18748, 23563, 23465, +}; /*------------------------------------------------------------------------------* * SWB BWE tables *------------------------------------------------------------------------------*/ @@ -18435,6 +24778,346 @@ const float EnvCdbk4th [N_CB4TH * DIM4TH] = -1.3301f, 3.6876f, 0.6120f, 0.3900f, }; +const Word16 EnvCdbk11_fx[N_CB11 * DIM11] = /*Q8 */ +{ + -2220, 29, 1168, 2124, 2180, 1208, 741, + 1521, -312, -843, -1523, -1970, -2205, -2541, + 746, 1835, 3461, 4398, 4292, 4184, 3462, + 1627, 2475, 2937, 2839, 2198, 1729, 1325, + -514, -731, -557, -200, 100, 475, 540, + 655, 956, 1272, 1083, 774, 687, 459, + 5987, 5460, 4689, 4192, 3845, 3615, 3393, + 3571, 4840, 5784, 6266, 5933, 5158, 4433, + 2959, 2087, 1180, 979, 1180, 1371, 1636, + 6029, 6157, 6431, 6762, 6998, 7153, 7050, + -822, 210, 450, 178, -639, -1346, -1577, + 4451, 4184, 4111, 4329, 4833, 5232, 5512, + 3420, 3994, 4321, 4205, 3684, 3154, 2651, + -3734, -2305, -1388, -324, 22, -847, -1141, + 850, 510, 896, 1780, 2130, 2688, 2826, + 3294, 2823, 2510, 2516, 3029, 3413, 3843, + -3563, -3409, -3199, -2917, -2584, -2282, -1981, + -2738, -3185, -3752, -4320, -4484, -4524, -4329, + -7534, -7481, -7283, -7175, -6757, -6281, -5865, + -4868, -4836, -4603, -4422, -4086, -3738, -3323, + -13896, -13775, -13484, -13339, -12926, -12399, -11970, + 8409, 8420, 8305, 8103, 7954, 7778, 7496, + 7180, 6845, 6369, 5971, 5557, 5309, 5027, + 4633, 4008, 3267, 2422, 2072, 1778, 1510, + 10128, 10432, 10540, 10473, 10176, 9837, 9586, + 2933, 2695, 2060, 1286, 424, -254, -825, + -10032, -9847, -9544, -9420, -9000, -8508, -8084, + 1830, 927, -158, -388, -360, -368, -287, + -21962, -21904, -21548, -21471, -21004, -20511, -20064, + -6090, -6142, -5937, -5852, -5493, -5104, -4671, + -1382, -1640, -2205, -2557, -2785, -3019, -2994, + -1300, -1567, -1744, -1642, -1409, -1080, -902, +}; + +const Word16 EnvCdbk1st_fx[N_CB1ST * DIM1ST] = /*Q8 */ +{ + -1819, -1138, 751, + -494, 162, -826, + -3199, -123, 2479, + -2071, 238, -429, + -1819, 1780, 1233, + 284, 1187, -1123, + -1689, -722, -484, + -1256, 52, -1336, + -604, 3738, -1297, + 555, 412, 743, + -626, -1685, 1527, + 145, 1557, -224, + -638, 1370, 1589, + -1188, 37, -410, + -428, -3320, 1860, + 2597, -95, -2876, + -742, -583, -684, + 1607, -1671, -1874, + -1111, -936, -1374, + 275, -2314, 518, + 2682, 2368, -302, + 1809, -555, -579, + 3193, -1270, -1208, + 750, 84, 154, + -1160, 429, 1098, + 816, -613, -2897, + 2159, -1885, 1245, + -671, 426, 3177, + 867, -144, -639, + 843, -1888, 2271, + 1542, 259, -148, + -1680, 1027, 285, + 162, -763, 1666, + -1916, 1175, -1227, + -345, -907, -151, + 1979, 1062, 402, + -1231, 2437, 3130, + -2422, 361, 1040, + -4314, -4106, -4221, + 146, -1200, -1828, + 485, 889, -3847, + 384, -2461, -2845, + 1526, -600, 1599, + -838, -571, 1097, + 1776, -3393, 4058, + -3330, 2429, 1732, + 468, -2140, -934, + 833, 2292, -1129, + -20, -1029, 652, + -346, 168, 1834, + -1730, 838, 2234, + 1622, -1695, -194, + -3198, -773, 228, + 1070, 1741, 285, + 1655, -212, -1628, + 2178, 604, 1784, + 1801, -3224, -848, + -819, 348, 187, + 16, 300, 244, + 769, 201, 1554, + 719, -394, 780, + 311, 2853, 185, + 1163, 489, -1022, + -330, 459, 877, + 109, -541, -691, + -509, -267, 478, + -340, -417, -1403, + -860, -675, -2703, + 1025, 826, 250, + -1043, 1008, -434, + -1042, -631, 60, + -173, 332, -2084, + 984, 919, -2042, + -1257, -2287, 339, + 366, -1309, -158, + 1041, 1039, 1083, + 3566, 918, 227, + 62, -139, 936, + 2424, 730, -1022, + -745, 1954, 427, + -1091, -1358, -478, + -173, 2121, -2367, + -2175, 2535, -1946, + -880, -1964, -1549, + -249, -1203, -927, + -2377, -443, -1775, + -1439, -582, 2037, + -529, -3679, -550, + 608, -284, -1566, + 201, 63, -344, + 1376, 218, 816, + 2471, -348, 479, + -1388, 988, -2674, + 1429, -3538, 1125, + 864, -1351, 845, + 301, 977, 408, + -1122, 3364, 1107, + -213, 730, -329, + 839, -683, -92, + 631, 1172, 2364, + 598, 685, -329, + -780, -1317, 448, + -424, -153, -199, + 768, -331, 2825, + 882, -1047, -975, + -375, -1835, -299, + 2861, -3375, -3158, + 2099, 2168, -2630, + 1602, 1930, 1451, + 1294, 1265, -586, + -2500, -2570, -2667, + -806, -1529, 3272, + -522, 1072, 478, + 4035, -2491, 480, + -1908, 2414, -178, + -1563, -143, 438, + 205, 861, 1287, + -691, 963, -1374, + -2359, -2032, -886, + 162, -442, 160, + 194, 2494, 1960, + -2533, -2578, 1924, + 267, 1701, 937, + 2919, 2950, 2382, + -670, 2102, -859, + -3147, 1385, -215, + 1482, -595, 415, + 228, 290, -1060, +}; + +const Word16 EnvCdbk2nd_fx[N_CB2ND * DIM2ND] = /*Q8 */ +{ + 1104, -1833, -1110, -954, + 757, 853, -176, 286, + -873, -587, -7, 1458, + -462, -553, -350, 104, + 1938, 1957, -1340, -703, + 1202, -779, 21, 1996, + -2851, -169, 1049, 940, + -1355, -726, -1788, 1076, + -767, -641, -646, -880, + 135, -832, -197, -889, + -826, 3, 279, -502, + -714, 544, -526, 375, + 291, -1076, -816, -3929, + -1175, -475, 2219, -642, + 197, -219, -1052, -1601, + 1175, -162, -695, -336, + 1124, 126, -2326, -1573, + 1164, -1323, -1958, 1074, + -2080, -2152, 113, 649, + -637, -860, 721, 267, + -609, 1658, -1006, -1352, + 1631, 2225, 2128, 1827, + -1112, -1351, 1856, 1656, + -2132, 1006, 770, -1294, + -472, 776, 1661, 2248, + -121, -574, -1481, -316, + 2565, -1081, 188, 293, + 398, 2598, 704, -1129, + 1023, 104, 550, 499, + -416, 127, 253, -1894, + 456, -2578, 190, 1018, + -1488, 286, -1202, -915, + -1164, 1874, 1651, 302, + -1312, -1547, -1625, -1516, + 170, -233, 817, 1209, + -1090, 341, 709, 725, + 854, 819, -278, -1083, + -15, 113, 286, 283, + 1166, -906, 1880, 301, + 342, -7, -587, 776, + -785, -1259, -1166, 3194, + -1630, -1071, 300, -1080, + -12, 190, -538, -493, + 351, 907, 1929, -1534, + 480, 36, 593, -526, + 813, 1216, 986, 89, + 98, 1010, -2272, 268, + 2766, -102, -1307, -873, + -1660, -467, -365, 47, + 1496, 1277, -228, -2791, + 1565, -669, 520, -1598, + -361, 1078, 457, -364, + 543, -950, 28, 248, + 1904, 815, -1034, 1125, + -13, -1951, 1085, -1005, + -2223, 1519, -624, 857, + 1121, 831, 872, 1295, + 193, 2284, -422, 609, + -156, 827, -733, 2065, + -3390, -3384, -3197, -3220, + 31, 896, 539, 978, + -21, 408, 1502, 405, + -583, -1662, -665, -164, + 2193, 976, 613, -436, +}; + +const Word16 EnvCdbk3rd_fx[N_CB3RD * DIM3RD] = /*Q8 */ +{ + 1031, -2454, 748, + 2770, 2442, 1761, + -2348, 4079, -959, + 1874, -735, -2242, + -59, 35, 201, + -1518, 162, 1809, + -1977, -1063, -103, + 2485, 1212, -863, + 882, 192, 39, + 1356, 851, 979, + -1377, -2961, -1477, + 497, -808, 593, + -394, -748, -1564, + -950, -198, -436, + -503, -1420, -234, + 318, 985, -1905, + -118, 1783, 1563, + 220, 929, 400, + 857, 37, -995, + -807, 1943, -409, + -743, -524, 552, + 940, 1643, -299, + 805, -1421, -768, + -2330, 705, 156, + 61, 203, 1213, + -138, 517, -642, + 64, -501, -435, + 2194, -625, 157, + -1600, 341, -1611, + 1137, -351, 2353, + -811, -1715, 1522, + -870, 613, 446, +}; + +const Word16 EnvCdbk4th_fx[N_CB4TH * DIM4TH] = /*Q8 */ +{ + 1024, -210, -207, 591, + -280, -2486, -951, 958, + 1539, 1136, 411, 1314, + 1761, -202, 1339, 203, + -2438, -2109, -2028, -2125, + 1849, -1408, -670, 144, + -469, 2674, -1589, -3604, + 1642, -702, 139, 2476, + -483, 372, -861, 540, + -119, 827, 863, 952, + 23, 99, -24, -303, + 488, -2233, -1432, -1399, + 54, -43, 96, -1527, + 1170, 133, -119, -717, + 258, -1215, -439, 160, + -1049, 793, 970, -770, + -1914, -1245, 1281, 422, + -1194, 1005, 176, -2368, + -1631, 1316, -1125, -361, + 1124, 1132, 61, -2186, + 790, -2055, 1174, 938, + 2974, 3874, 2315, 2040, + -300, 2484, 59, -860, + 543, 1307, -1868, -725, + 389, -115, -945, -146, + -1837, -578, -620, 975, + 389, 1779, 1732, 296, + 377, 897, 1555, 2269, + -854, 26, 590, 1413, + -780, -985, 1389, 2639, + 312, -277, -935, -3289, + 1740, 1852, 641, -519, + 738, 898, -466, 115, + 1187, -286, -1514, -1309, + 74, -801, -583, -987, + 510, -667, 430, -191, + 418, -303, 806, 1258, + -1083, -1065, 362, -2114, + -1075, 82, 260, 286, + -2579, 14, 75, -854, + -661, -634, 482, -581, + -338, -306, 3255, 388, + -230, -24, 1161, 205, + 256, 546, -141, 1379, + -63, -775, -484, 1478, + -517, -546, -451, 86, + 1473, -1201, 430, -1892, + 394, 831, 620, -664, + 334, 64, 1773, -1576, + -1783, 1270, 1020, 944, + 1023, 98, -1908, 1330, + -560, -1044, 380, 707, + -427, -708, -1815, -90, + -54, 2298, -537, 1151, + -499, 703, -1018, 3322, + 92, 717, -607, -1032, + -1313, -1393, -580, -485, + 34, -2192, 788, -860, + 2641, 628, -776, -259, + -702, -159, -1483, -1638, + -33, -63, 97, 553, + 692, 523, 548, 349, + -913, 54, -456, -702, + -341, 944, 157, 100, +}; + const float EnvCdbkFB [N_CB_FB * DIM_FB] = { -16.6120f, -9.7056f, -7.3815f, @@ -18470,12 +25153,52 @@ const float EnvCdbkFB [N_CB_FB * DIM_FB] = 32.8420f, 38.8016f, 38.3823f, 7.4425f, 11.3804f, 9.7292f }; +const Word16 EnvCdbkFB_fx[N_CB_FB * DIM_FB] = /*Q7 */ +{ + -2126, -1242, -945, + 1628, -686, -539, + 1230, 2245, 2532, + 2822, 3094, 2669, + -12376, -11507, -11342, + 2678, 3533, 3510, + 489, 903, 689, + 1930, 2929, 3025, + 3424, 4179, 4050, + -2500, -1707, -1415, + -3511, -2563, -2224, + -865, -987, -1212, + -424, 891, 1919, + 1976, 2520, 2277, + 673, 1667, 1945, + 5169, 6024, 5983, + -1367, -501, -236, + -254, 679, 989, + -18974, -18088, -17834, + -23007, -22053, -22109, + 2262, 2301, -625, + -124, 431, 372, + 1454, 1962, 1791, + 200, 1094, 1347, + -997, -110, 213, + -697, 267, 602, + -3066, -2172, -1876, + -4358, -3493, -3164, + -360, 59, -472, + -1813, -919, -601, + 4204, 4967, 4913, + 953, 1457, 1245 +}; const float Mean_env_fb[DIM_FB] = {13.75f, 6.29f, 3.70f}; +const Word16 Mean_env_fb_fx[DIM_FB] = { 1760, 805, 473 }; /*Q8 */ const float w_NOR[SWB_FENV] = {1.f,0.97826087f,0.957446809f,0.9375f,0.918367347f,0.9f,0.882352941f,0.865384615f,0.849056604f,0.833333333f,0.818181818f,0.803571429f,0.789473684f,0.775862069f}; const float Mean_env[SWB_FENV] = {28.62f, 28.96f, 28.05f, 27.97f, 26.91f, 26.82f, 26.35f, 25.98f, 24.94f, 24.03f, 22.94f, 22.14f, 21.23f, 20.40f}; - +const Word16 Mean_env_fx[SWB_FENV] = /*Q8 */ +{ + 7327, 7414, 7181, 7160, 6889, 6866, 6746, + 6651, 6385, 6152, 5873, 5668, 5435, 5222, +}; const float Env_TR_Cdbk1 [N_CB_TR1 * DIM_TR1] = { 0.8936f, -9.1696f, @@ -18676,7 +25399,209 @@ const float Env_TR_Cdbk2 [N_CB_TR2 * DIM_TR2] = -0.0134f, 0.0015f }; +const Word16 Env_TR_Cdbk1_fx[N_CB_TR1 * DIM_TR1] = /*Q8 */ +{ + 229, -2347, + 8199, 7726, + -312, 1700, + 9881, 5949, + 8942, 8358, + 3865, 3287, + 2405, 796, + 3664, 1433, + 3059, 2215, + 618, 874, + -5479, -4636, + 2237, 2512, + 4265, 2428, + 6583, 2065, + 4548, 6579, + 11325, 7340, + 10578, 9264, + 8491, 6457, + -1380, -2484, + 3377, 5069, + 7393, 5120, + 4798, 4440, + 5506, 7614, + -3371, -3982, + 2806, 2959, + 2242, 3550, + 1334, 3065, + 2055, -1350, + 815, 5507, + 4940, 1457, + -1950, -1046, + 653, -1133, + 872, -3622, + -1756, 245, + 5792, 5542, + 4084, 7696, + 4569, 5204, + -810, -1555, + 10127, 10384, + 11341, 11713, + 6365, 4996, + 8641, 10527, + 5914, 3366, + 4522, 3266, + 5217, 2830, + 8107, 8980, + 3952, 5858, + 5848, 8990, + 6424, 5931, + 5185, 3823, + 6367, 6917, + 3548, 2683, + 1634, 2098, + 2729, -89, + 6964, 7664, + 3179, 3561, + 6388, 4193, + 4024, 4828, + -378, 434, + 9338, 9507, + 7593, 3483, + -6835, -6317, + 5207, 5029, + 11326, 10488, + 7411, 6086, + 10072, 8255, + -6099, -5652, + 7074, 8702, + -12228, -11384, + -11471, -10567, + -13025, -12253, + -12879, -11289, + -13952, -13062, + -16214, -15389, + -11659, -10789, + -12351, -11477, + -12789, -11947, + -15139, -14249, + -11326, -11219, + -11950, -11093, + -11800, -10928, + -23738, -22881, + 12795, 11890, + -3793, -2879, + -27373, -26492, + -11928, -11531, + -12110, -11258, + -20492, -19634, + -14371, -13608, + -12591, -11728, + -14055, -11739, + 9471, 7272, + -11184, -10335, + -13313, -11673, + -12209, -10610, + -13465, -12761, + 7690, 7115, + 2564, 4496, + 5587, 4551, + -813, -562, + -4483, -5521, + 1556, 98, + 2, 3468, + 1410, 1339, + 4049, 161, + -4538, -4026, + -9866, -9115, + -1616, -4727, + 2457, 1653, + 631, 2155, + -17982, -17082, + 2628, 6088, + -10791, -9933, + -12426, -11566, + 4322, 4000, + -1574, 2162, + -7968, -7599, + 1523, 4192, + 5621, 6537, + -2511, -1987, + 12471, 9218, + 8746, 4971, + 3642, 4148, + 5089, 5948, + 350, -92, + 7028, 6683, + -2430, -3216, + -3974, -886, +}; + +const Word16 Env_TR_Cdbk2_fx[N_CB_TR2 * DIM_TR2] = /*Q8 */ +{ + 2639, 375, + -481, 1694, + -2400, -3306, + 86, -4018, + -1301, 47, + 734, 299, + 957, -1039, + 2204, 1486, + 361, -1136, + 2628, -838, + -2010, 1296, + 373, 127, + -573, 2604, + 689, -1554, + 1676, -371, + 1298, 279, + -901, 1086, + 1747, -2723, + 214, -657, + -731, -909, + 1545, -1658, + -369, -2208, + -1276, 1748, + 1141, -522, + 186, -1893, + -1260, -2016, + -478, -504, + 1287, 1882, + -97, -1400, + -1372, -1165, + 800, -152, + 413, -240, + -208, -858, + -90, -399, + 492, 2519, + 913, 1368, + -344, 282, + 305, 526, + -251, 860, + -1066, 567, + -2800, -687, + 1, 674, + 176, 878, + -716, -153, + 706, 831, + -1083, -424, + 419, 1192, + -132, 565, + 708, -2406, + 600, -661, + 1712, 2969, + -1974, 379, + -672, 208, + 26, 296, + -1821, -501, + -513, 635, + 266, 1737, + -221, 1232, + -3498, 1632, + -337, -66, + -552, -1427, + 1329, 850, + -718, -2948, + -3, 0, +}; + const float Mean_env_tr[5] = { 27.23f, 23.81f, 23.87f, 19.51f }; +const Word16 Mean_env_tr_fx[5] = { 6971, 6095, 6111, 4995 }; /*Q8 */ + /*------------------------------------------------------------------------------* * LR MDCT SWB BWE coding tables @@ -18842,6 +25767,71 @@ const float wscw16q15_8[40] = 0.137023925781250f, 0.098022460937500f, 0.058868408203125f, 0.019622802734375f, }; +const Word16 wscw16q15_fx[240] = +{ + -32768, -32766, -32764, -32759, -32754, -32747, -32738, -32729, -32717, -32705, -32691, + -32675, -32658, -32640, -32621, -32600, -32577, -32553, -32528, -32501, -32473, -32444, + -32413, -32381, -32348, -32313, -32276, -32239, -32200, -32159, -32117, -32074, -32029, + -31984, -31936, -31887, -31837, -31786, -31733, -31679, -31624, -31567, -31508, -31449, + -31388, -31326, -31262, -31197, -31131, -31063, -30994, -30924, -30853, -30780, -30705, + -30630, -30553, -30475, -30395, -30315, -30232, -30149, -30064, -29979, -29891, -29803, + -29713, -29622, -29530, -29436, -29341, -29245, -29148, -29049, -28949, -28848, -28746, + -28642, -28537, -28431, -28324, -28216, -28106, -27995, -27883, -27770, -27655, -27540, + -27423, -27305, -27186, -27066, -26944, -26821, -26698, -26573, -26447, -26320, -26191, + -26062, -25931, -25800, -25667, -25533, -25398, -25262, -25125, -24986, -24847, -24707, + -24565, -24423, -24279, -24135, -23989, -23843, -23695, -23546, -23397, -23246, 23095, + 22942, 22788, 22634, 22478, 22322, 22164, 22006, 21846, 21686, 21525, 21363, + 21199, 21035, 20871, 20705, 20538, 20371, 20202, 20033, 19863, 19692, 19520, + 19347, 19174, 18999, 18824, 18648, 18472, 18294, 18116, 17937, 17757, 17576, + 17395, 17213, 17030, 16846, 16662, 16477, 16291, 16105, 15917, 15730, 15541, + 15352, 15162, 14972, 14781, 14589, 14397, 14204, 14010, 13816, 13621, 13426, + 13230, 13033, 12836, 12639, 12441, 12242, 12043, 11843, 11643, 11442, 11241, + 11039, 10837, 10634, 10431, 10228, 10024, 9819, 9615, 9409, 9204, 8998, + 8791, 8585, 8377, 8170, 7962, 7754, 7545, 7336, 7127, 6918, 6708, + 6498, 6288, 6077, 5866, 5655, 5444, 5232, 5020, 4808, 4596, 4383, + 4171, 3958, 3745, 3532, 3319, 3105, 2892, 2678, 2464, 2250, 2036, + 1822, 1608, 1394, 1179, 965, 751, 536, 322, 107 +}; +const Word16 wscw16q15_8_fx[40] = +{ + -32762, -32711, -32610, -32459, -32258, -32007, -31706, -31357, + -30959, -30514, -30022, -29483, -28899, -28270, -27598, -26883, + -26127, -25330, -24494, -23621, 22711, 21766, 20788, 19777, + 18736, 17666, 16569, 15447, 14300, 13132, 11943, 10736, + 9512, 8274, 7022, 5760, 4490, 3212, 1929, 643 +}; +const Word16 wscw16q15_16_fx[80] = +{ + -32766, -32754, -32729, -32691, -32640, -32577, -32501, -32413, + -32313, -32200, -32074, -31936, -31786, -31624, -31449, -31262, + -31063, -30853, -30630, -30395, -30149, -29891, -29622, -29341, + -29049, -28746, -28431, -28106, -27770, -27423, -27066, -26698, + -26320, -25931, -25533, -25125, -24707, -24279, -23843, -23397, + 22942, 22478, 22006, 21525, 21035, 20538, 20033, 19520, + 18999, 18472, 17937, 17395, 16846, 16291, 15730, 15162, + 14589, 14010, 13426, 12836, 12242, 11643, 11039, 10431, + 9819, 9204, 8585, 7962, 7336, 6708, 6077, 5444, + 4808, 4171, 3532, 2892, 2250, 1608, 965, 322 +}; +const Word16 wscw16q15_32_fx[160] = +{ + -32768, -32764, -32758, -32749, -32736, -32720, -32701, -32679, -32654, -32626, -32594, + -32559, -32522, -32481, -32437, -32389, -32339, -32286, -32229, -32169, -32107, -32041, + -31972, -31900, -31825, -31747, -31665, -31581, -31494, -31403, -31310, -31214, -31114, + -31012, -30906, -30798, -30687, -30572, -30455, -30335, -30212, -30086, -29957, -29825, + -29690, -29553, -29412, -29269, -29123, -28974, -28823, -28668, -28511, -28351, -28188, + -28023, -27855, -27684, -27511, -27335, -27156, -26975, -26791, -26604, -26415, -26223, + -26029, -25833, -25633, -25432, -25228, -25021, -24812, -24601, -24387, -24171, -23953, + -23732, -23509, -23284, 23056, 22827, 22595, 22361, 22125, 21886, 21646, 21403, + 21159, 20912, 20663, 20413, 20160, 19905, 19649, 19390, 19130, 18868, 18604, + 18338, 18071, 17802, 17531, 17258, 16984, 16708, 16430, 16151, 15871, 15588, + 15305, 15019, 14733, 14445, 14155, 13865, 13572, 13279, 12984, 12688, 12391, + 12093, 11793, 11492, 11191, 10888, 10584, 10279, 9973, 9666, 9358, 9049, + 8740, 8429, 8118, 7806, 7493, 7180, 6865, 6550, 6235, 5919, 5602, + 5285, 4967, 4649, 4330, 4011, 3692, 3372, 3052, 2731, 2411, 2090, + 1768, 1447, 1126, 804, 483, 161 +}; + /* Codebook for quantization of norms */ const float dicn[40] = { @@ -18866,7 +25856,29 @@ const float dicn[40] = 0.5f, 0.353553f, 0.25f, 0.176777f }; - +const Word32 dicn_fx[40] = /* Q=14 */ +{ + 2147483647, 1518500224, + 1073741824, 759250112, + 536870912, 379625056, + 268435456, 189812528, + 134217728, 94906264, + 67108864, 47453132, + 33554432, 23726566, + 16777216, 11863283, + 8388608, 5931642, + 4194304, 2965821, + 2097152, 1482910, + 1048576, 741455, + 524288, 370728, + 262144, 185364, + 131072, 92682, + 65536, 46341, + 32768, 23170, + 16384, 11585, + 8192, 5793, + 4096, 2896 +}; const float dicn_inv[40]= /* Inversion of the codebook for quantization of norms */ { 0.00000762939453f, 0.00001078959322f, @@ -18918,7 +25930,18 @@ const float dicn_pg[45] = 0.3535530f, 0.2500000f, 0.176777f }; - +const Word32 dicn_pg_fx[45] = /* Q12 */ +{ + 536870912, 451452834, 379625056, 319225344, 268435456, + 225726416, 189812528, 159612672, 134217728, 112863208, + 94906264, 67108864, 47453132, 33554432, 23726566, + 16777216, 11863283, 8388608, 5931641, 4194304, + 2965821, 2097152, 1482910, 1048576, 741455, + 524288, 370728, 262144, 185364, 131072, + 92682, 65536, 46341, 32768, 23170, + 16384, 11585, 8192, 5793, 4096, + 2896, 2048, 1448, 1024, 724 +}; const int16_t expPkEnrg_tbl[45] = { 0, 0, 0, 0, 0, 2, 2, 2, 2, @@ -19668,6 +26691,64 @@ const float short_window_48kHz[480] = 0.0751953f, 0.0686646f, 0.0621338f, 0.055603f, 0.0490723f, 0.0425415f, 0.0359802f, 0.0294495f, 0.0229187f, 0.0163574f, 0.00982666f, 0.00326538f }; + +const Word16 short_window_48kHz_fx[L_FRAME48k / 2 / 2] = /* second half is symetric and omitted */ +{ + 107, 322, 536, 751, 965, 1179, 1394, 1608, 1822, 2036, 2250, 2464, 2678, 2892, 3105, 3319, + 3532, 3745, 3958, 4171, 4383, 4596, 4808, 5020, 5232, 5444, 5655, 5866, 6077, 6288, 6498, 6708, + 6918, 7127, 7336, 7545, 7754, 7962, 8170, 8377, 8585, 8791, 8998, 9204, 9409, 9615, 9819, 10024, + 10228, 10431, 10634, 10837, 11039, 11241, 11442, 11643, 11843, 12043, 12242, 12441, 12639, 12836, 13033, 13230, + 13426, 13621, 13816, 14010, 14204, 14397, 14589, 14781, 14972, 15162, 15352, 15541, 15730, 15917, 16105, 16291, + 16477, 16662, 16846, 17030, 17213, 17395, 17576, 17757, 17937, 18116, 18294, 18472, 18648, 18824, 18999, 19174, + 19347, 19520, 19692, 19863, 20033, 20202, 20371, 20538, 20705, 20871, 21035, 21199, 21363, 21525, 21686, 21846, + 22006, 22164, 22322, 22478, 22634, 22788, 22942, 23095, 23246, 23397, 23546, 23695, 23843, 23989, 24135, 24279, + 24423, 24565, 24707, 24847, 24986, 25125, 25262, 25398, 25533, 25667, 25800, 25931, 26062, 26191, 26320, 26447, + 26573, 26698, 26821, 26944, 27066, 27186, 27305, 27423, 27540, 27655, 27770, 27883, 27995, 28106, 28216, 28324, + 28431, 28537, 28642, 28746, 28848, 28949, 29049, 29148, 29245, 29341, 29436, 29530, 29622, 29713, 29803, 29891, + 29979, 30064, 30149, 30232, 30315, 30395, 30475, 30553, 30630, 30705, 30780, 30853, 30924, 30994, 31063, 31131, + 31197, 31262, 31326, 31388, 31449, 31508, 31567, 31624, 31679, 31733, 31786, 31837, 31887, 31936, 31984, 32029, + 32074, 32117, 32159, 32200, 32239, 32276, 32313, 32348, 32381, 32413, 32444, 32473, 32501, 32528, 32553, 32577, + 32600, 32621, 32640, 32658, 32675, 32691, 32705, 32717, 32729, 32738, 32747, 32754, 32759, 32764, 32766, 32767, +}; +const Word16 short_window_32kHz_fx[L_FRAME32k / 2 / 2] = /* second half is symetric and omitted */ +{ + 161, 483, 804, 1126, 1447, 1768, 2090, 2411, 2731, 3052, 3372, 3692, 4011, 4330, 4649, 4967, + 5285, 5602, 5919, 6235, 6550, 6865, 7180, 7493, 7806, 8118, 8429, 8740, 9049, 9358, 9666, 9973, + 10279, 10584, 10888, 11191, 11492, 11793, 12093, 12391, 12688, 12984, 13279, 13572, 13865, 14155, 14445, 14733, + 15019, 15305, 15588, 15871, 16151, 16430, 16708, 16984, 17258, 17531, 17802, 18071, 18338, 18604, 18868, 19130, + 19390, 19649, 19905, 20160, 20413, 20663, 20912, 21159, 21403, 21646, 21886, 22125, 22361, 22595, 22827, 23056, + 23284, 23509, 23732, 23953, 24171, 24387, 24601, 24812, 25021, 25228, 25432, 25633, 25833, 26029, 26223, 26415, + 26604, 26791, 26975, 27156, 27335, 27511, 27684, 27855, 28023, 28188, 28351, 28511, 28668, 28823, 28974, 29123, + 29269, 29412, 29553, 29690, 29825, 29957, 30086, 30212, 30335, 30455, 30572, 30687, 30798, 30906, 31012, 31114, + 31214, 31310, 31403, 31494, 31581, 31665, 31747, 31825, 31900, 31972, 32041, 32107, 32169, 32229, 32286, 32339, + 32389, 32437, 32481, 32522, 32559, 32594, 32626, 32654, 32679, 32701, 32720, 32736, 32749, 32758, 32764, 32767, +}; + +const Word16 short_window_16kHz_fx[L_FRAME16k / 2 / 2] = /* second half is symetric and omitted */ +{ + 322, 965, 1608, 2250, 2892, 3532, 4171, 4808, 5444, 6077, 6708, 7336, 7962, 8585, 9204, 9819, + 10431, 11039, 11643, 12242, 12836, 13426, 14010, 14589, 15162, 15730, 16291, 16846, 17395, 17937, 18472, 18999, + 19520, 20033, 20538, 21035, 21525, 22006, 22478, 22942, 23397, 23843, 24279, 24707, 25125, 25533, 25931, 26320, + 26698, 27066, 27423, 27770, 28106, 28431, 28746, 29049, 29341, 29622, 29891, 30149, 30395, 30630, 30853, 31063, + 31262, 31449, 31624, 31786, 31936, 32074, 32200, 32313, 32413, 32501, 32577, 32640, 32691, 32729, 32754, 32766, +}; + +const Word16 short_window_8kHz_fx[L_FRAME8k / 2 / 2] = /* second half is symetric and omitted */ +{ + 643, 1929, 3212, 4490, 5760, 7022, 8274, 9512, + 10736, 11943, 13132, 14300, 15447, 16569, 17666, 18736, + 19777, 20788, 21766, 22711, 23621, 24494, 25330, 26127, + 26883, 27598, 28270, 28899, 29483, 30022, 30514, 30959, + 31357, 31706, 32007, 32258, 32459, 32610, 32711, 32762, +}; + +const Word16 inv_jp2[64] = +{ + 16384, 10923, 8192, 6554, 5461, 4681, 4096, 3641, 3277, 2979, 2731, 2521, 2341, 2185, 2048, 1928, + 1820, 1725, 1638, 1560, 1489, 1425, 1365, 1311, 1260, 1214, 1170, 1130, 1092, 1057, 1024, 993, + 964, 936, 910, 886, 862, 840, 819, 799, 780, 762, 745, 728, 712, 697, 683, 669, + 655, 643, 630, 618, 607, 596, 585, 575, 565, 555, 546, 537, 529, 520, 512, 504 +}; const int16_t subf_norm_groups[4][11] = { {0,1,8,9,16,20,24,28,32,36,40}, @@ -20252,10 +27333,46 @@ const uint32_t exactdivodd[ODD_DIV_SIZE] = const int16_t gain_cb_size[MAX_GAIN_BITS] = {2, 4, 8, 16, 32}; const int16_t inner_frame_tbl[4] = {L_FRAME8k, L_FRAME16k, L_FRAME32k, L_FRAME48k}; /* corresponds to NB, WB, SWB, FB */ +const Word16 hq_nominal_scaling_inv[7] = { 0, 8192, 11585, 0, 16384, 0, 20066 }; /*Q13 */ +const Word16 hq_nominal_scaling[7] = { 0, 32767, 23170, 0, 16384, 0, 13377 }; /*Q15 */ const int16_t l_spec_tbl[4] = {L_SPEC8k, L_SPEC16k, L_SPEC32k, L_SPEC48k}; /* corresponds to NB, WB, SWB, FB */ const int16_t l_spec_ext_tbl[4] = {0, L_SPEC16k_EXT, L_SPEC32k_EXT, L_SPEC48k_EXT}; /* corresponds to NB, WB, SWB, FB */ - +const Word16 sinq_16k[3 * L_FRAME16k / 20] = +{ + 536, 1608, 2678, 3745, 4808, 5866, 6918, 7962, + 8998, 10024, 11039, 12043, 13033, 14010, 14972, 15917, + 16846, 17757, 18648, 19520, 20371, 21199, 22006, 22788, + 23546, 24279, 24986, 25667, 26319, 26944, 27540, 28106, + 28642, 29147, 29622, 30064, 30475, 30852, 31197, 31508, + 31786, 32029, 32238, 32413, 32553, 32658, 32728, 32763 +}; +const Word16 sinq_32k[3 * L_FRAME32k / 20] = +{ + 268, 804, 1340, 1876, 2411, 2945, 3479, 4011, 4543, 5073, 5602, 6130, + 6655, 7180, 7702, 8222, 8740, 9255, 9768, 10279, 10786, 11291, 11793, 12292, + 12787, 13279, 13767, 14252, 14733, 15210, 15683, 16151, 16616, 17075, 17531, 17981, + 18427, 18868, 19304, 19734, 20160, 20580, 20994, 21403, 21806, 22203, 22595, 22980, + 23359, 23732, 24098, 24459, 24812, 25159, 25499, 25832, 26159, 26478, 26790, 27095, + 27393, 27684, 27967, 28243, 28511, 28771, 29024, 29269, 29506, 29735, 29956, 30170, + 30375, 30572, 30761, 30941, 31114, 31278, 31433, 31580, 31719, 31849, 31971, 32084, + 32189, 32285, 32372, 32451, 32521, 32582, 32634, 32678, 32713, 32740, 32757, 32766 +}; +const Word16 sinq_48k[3 * L_FRAME48k / 20] = +{ + 179, 536, 893, 1251, 1608, 1965, 2321, 2678, 3034, 3390, 3745, 4100, + 4454, 4808, 5161, 5514, 5866, 6217, 6568, 6918, 7267, 7615, 7962, 8308, + 8654, 8998, 9341, 9683, 10024, 10364, 10702, 11039, 11375, 11710, 12043, 12375, + 12705, 13033, 13361, 13686, 14010, 14332, 14653, 14972, 15289, 15604, 15918, 16229, + 16539, 16846, 17152, 17455, 17757, 18056, 18353, 18648, 18941, 19232, 19520, 19806, + 20090, 20371, 20650, 20926, 21200, 21471, 21740, 22006, 22269, 22530, 22789, 23044, + 23297, 23547, 23794, 24038, 24280, 24519, 24754, 24987, 25217, 25444, 25667, 25888, + 26106, 26320, 26531, 26740, 26945, 27147, 27345, 27541, 27733, 27921, 28107, 28289, + 28468, 28643, 28815, 28984, 29149, 29310, 29468, 29623, 29774, 29922, 30066, 30206, + 30343, 30476, 30606, 30732, 30854, 30973, 31087, 31199, 31306, 31410, 31510, 31606, + 31699, 31788, 31873, 31954, 32031, 32105, 32175, 32241, 32303, 32361, 32415, 32466, + 32513, 32556, 32595, 32630, 32661, 32688, 32712, 32731, 32747, 32759, 32766, 32767 +}; /*------------------------------------------------------------------------------* * LR-MDCT tables *------------------------------------------------------------------------------*/ @@ -20350,6 +27467,17 @@ const float sm_table[] = 0.0276f, 0.0232f, 0.0192f, 0.0156f, 0.0123f, 0.0094f, 0.0069f, 0.0048f, 0.0031f, 0.0017f, 0.0008f, 0.0002f }; +const Word16 sm_table_fx[] = +{ + 32767, 32126, 31480, 30838, 30196, 29557, 28918, 28279, 27643, 27007, + 26375, 25746, 25120, 24494, 23875, 23255, 22643, 22033, 21427, 20824, + 20228, 19638, 19048, 18468, 17891, 17321, 16758, 16197, 15647, 15103, + 14562, 14031, 13507, 12989, 12481, 11980, 11488, 11000, 10525, 10056, + 9598, 9146, 8706, 8274, 7851, 7438, 7035, 6642, 6259, 5885, + 5521, 5171, 4830, 4499, 4178, 3870, 3572, 3287, 3011, 2746, + 2494, 2254, 2025, 1809, 1602, 1412, 1229, 1062, 904, 760, + 629, 511, 403, 308, 226, 157, 102, 56, 26, 7, +}; const int16_t GSC_freq_bits[] = { @@ -20367,7 +27495,33 @@ const int16_t GSC_freq_bits[] = 26, 96, 0, 28, 18, 13, 12,10,10, 5, 4, 4, 1, 0, 1, 3, 4, /* ACELP_22k60*/ 26, 96, 0, 28, 18, 13, 12,10,10, 5, 4, 4, 1, 0, 1, 3, 4 /* ACELP_24k40*/ }; - +#ifdef MOD_BIT_ALLOC_ROM_TABLE +const Word32 GSC_freq_bits_fx[] = +{ + 5505024, 17563648, -1572864, 6553600, 3932160, 2883584, 2621440, 1310720, 0, 0, 1310720, 1048576, 0, 0, 1048576, 0, 0, /* ACELP_5k00*/ + 5505024, 17563648, -1572864, 6553600, 3932160, 2883584, 2621440, 1310720, 0, 0, 1310720, 1048576, 0, 0, 1048576, 0, 0, /* ACELP_6k15*/ + 5505024, 17563648, -1572864, 6553600, 3932160, 2883584, 2621440, 1310720, 0, 0, 1310720, 1048576, 0, 0, 1048576, 0, 0, /* ACELP_7k20*/ + 5505024, 19660800, -1048576, 6815744, 4194304, 3145728, 2883584, 2359296, 0, 0, 1048576, 1048576, 262144, 262144, 786432, 0, 0, /* ACELP_8k00*/ + 6815744, 20971520, -786432, 7340032, 4718592, 3407872, 3145728, 2359296, 0, 0, 1048576, 1048576, 262144, 262144, 786432, 0, 0, /* ACELP_8k00*/ + 6815744, 25165824, -1048576, 7340032, 4718592, 3407872, 3145728, 2621440, 2621440, 1310720, 1048576, 1048576, 262144, 0, 262144, 786432, 1048576, /* ACELP_11k60*/ + 6815744, 25165824, -1048576, 7340032, 4718592, 3407872, 3145728, 2621440, 2621440, 1310720, 1048576, 1048576, 262144, 0, 262144, 786432, 1048576, /* ACELP_12k15*/ + 6815744, 25165824, -1048576, 7340032, 4718592, 3407872, 3145728, 2621440, 2621440, 1310720, 1048576, 1048576, 262144, 0, 262144, 786432, 1048576, /* ACELP_12k85*/ + 8126464, 25165824, -1048576, 7340032, 4718592, 3407872, 3145728, 2621440, 2621440, 1310720, 1048576, 1048576, 262144, 0, 262144, 786432, 1048576, /* ACELP_13k20*/ 26, 96, -1, 28, 18, 13, 12,10,10, 5, 4, 4, 1, 0, 1, 3, 4, /* ACELP_14k80*/ + 8126464, 25165824, -262144, 7340032, 4718592, 3407872, 3145728, 2621440, 2621440, 1310720, 1048576, 1048576, 262144, 0, 262144, 786432, 1048576, /* ACELP_13k20*/ 26, 96, -1, 28, 18, 13, 12,10,10, 5, 4, 4, 1, 0, 1, 3, 4, /* ACELP_16k40*/ + 8126464, 25165824, 0, 7340032, 4718592, 3407872, 3145728, 2621440, 2621440, 1310720, 1048576, 1048576, 262144, 0, 262144, 786432, 1048576, /* ACELP_22k60*/ 26, 96, -1, 28, 18, 13, 12,10,10, 5, 4, 4, 1, 0, 1, 3, 4, /* ACELP_16k40*/ + 8126464, 25165824, 0, 7340032, 4718592, 3407872, 3145728, 2621440, 2621440, 1310720, 1048576, 1048576, 262144, 0, 262144, 786432, 1048576, /* ACELP_22k60*/ 26, 96, -1, 28, 18, 13, 12,10,10, 5, 4, 4, 1, 0, 1, 3, 4, /* ACELP_16k40*/ +}; +#else +const Word32 GSC_freq_bits_fx[] = +{ + 5505024, 17563648, -1572864, 6553600, 3932160, 2883584, 2621440, 1310720, 0, 0, 1310720, 1048576, 0, 0, 1048576, 0, 0, /* ACELP_7k20*/ + 5505024, 19660800, -1048576, 6815744, 4194304, 3145728, 2883584, 2359296, 0, 0, 1048576, 1048576, 262144, 262144, 786432, 0, 0, /* ACELP_8k00*/ + 6815744, 25165824, -1048576, 7340032, 4718592, 3407872, 3145728, 2621440, 2621440, 1310720, 1048576, 1048576, 262144, 0, 262144, 786432, 1048576, /* ACELP_11k60*/ + 6815744, 25165824, -1048576, 7340032, 4718592, 3407872, 3145728, 2621440, 2621440, 1310720, 1048576, 1048576, 262144, 0, 262144, 786432, 1048576, /* ACELP_12k15*/ + 6815744, 25165824, -1048576, 7340032, 4718592, 3407872, 3145728, 2621440, 2621440, 1310720, 1048576, 1048576, 262144, 0, 262144, 786432, 1048576, /* ACELP_12k85*/ + 8126464, 25165824, -1048576, 7340032, 4718592, 3407872, 3145728, 2621440, 2621440, 1310720, 1048576, 1048576, 262144, 0, 262144, 786432, 1048576, /* ACELP_13k20*/ +}; +#endif const int16_t Compl_GSC_freq_bits[] = { 5, 10, 10, 10 /* bitrate > ACELP_16k40 && FS = 16kHz */ @@ -20394,7 +27548,13 @@ const float dic_gp[] = 0.0249f, 0.1013f, 0.1741f, 0.2485f, 0.361f, 0.4376f, 0.4776f, 0.5645f }; - +const Word16 dic_gp_fx[] = /*Q14*/ +{ + -9580, -7692, -6385, -4474, -3254, -2038, -806, -82, + 1034, 2259, 3457, 4684, 5290, 6544, 8548, 10052, + -8964, -8338, -7021, -5754, -5118, -3850, -2654, -1429, + 408, 1660, 2852, 4071, 5915, 7170, 7825, 9249 +}; const float Gain_meanNB[] = { 2.4052f }; const Word16 Gain_meanNB_fx[] = { @@ -22073,7 +29233,11 @@ const float w_fft32[16] = 1.0000000f,0.00000000f,0.70710677f,0.70710677f,0.92387950f,0.38268346f,0.38268346f,0.92387950f, 0.98078525f,0.19509032f,0.55557024f,0.83146960f,0.83146960f,0.55557024f,0.19509032f,0.98078525f }; - +const Word32 w_fft32_16fx[16] = +{ + 1073741824, 0, 759250113, 759250113, 992008059, 410903236, 410903236, 992008059, + 1053110143, 209476636, 596539003, 892783685, 892783685, 596539003, 209476636, 1053110143 +}; const int16_t Ip_fft32[6] = { 16,1,0,32,16,48 }; const int16_t Odx_fft32_5[32] = { 0,27,22,17,12,7,2,29,24,19,14,9,4,31,26,21,16,11,6,1,28,23,18,13,8,3,30,25,20,15,10,5 }; @@ -22167,6 +29331,17 @@ const float w_fft128[64] = 0.98917650f, 0.14673047f, 0.59569930f, 0.80320753f, 0.85772861f, 0.51410274f, 0.24298017f, 0.97003125f, 0.94154406f, 0.33688985f, 0.42755509f, 0.90398929f, 0.74095112f, 0.67155895f, 0.04906767f, 0.99879545f }; +const Word32 w_fft128_16fx[64] = +{ + 1073741824, 0, 759250112, 759250112, 992008064, 410903232, 410903232, 992008064, + 1053110144, 209476640, 596539008, 892783680, 892783680, 596539008, 209476640, 1053110144, + 1068571456, 105245104, 681174592, 830013632, 946955712, 506158400, 311690816, 1027506880, + 1027506880, 311690816, 506158400, 946955712, 830013632, 681174592, 105245104, 1068571456, + 1072448448, 52686008, 721080960, 795590208, 970651136, 459083776, 361732736, 1010975232, + 1041563136, 260897968, 552013632, 920979072, 862437504, 639627264, 157550640, 1062120192, + 1062120192, 157550640, 639627264, 862437504, 920979072, 552013632, 260897968, 1041563136, + 1010975232, 361732736, 459083776, 970651136, 795590208, 721080960, 52686008, 1072448448, +}; const int16_t Ip_fft256[10] = {128, 1, 0, 256, 128, 384, 64, 320,192, 448}; @@ -22227,7 +29402,41 @@ const float w_fft512[256] = 0.98310549f, 0.18303989f, 0.56573181f, 0.82458930f, 0.83822471f, 0.54532499f, 0.20711138f, 0.97831737f, 0.92850608f, 0.37131719f, 0.39399204f, 0.91911385f, 0.71573083f, 0.69837625f, 0.01227154f, 0.99992470f }; - +const Word16 w_fft512_fx_evs[256] = +{ + 16384, 0, 11585, 11585, 15137, 6270, 6270, 15137, + 16069, 3196, 9102, 13623, 13623, 9102, 3196, 16069, + 16305, 1606, 10394, 12665, 14449, 7723, 4756, 15679, + 15679, 4756, 7723, 14449, 12665, 10394, 1606, 16305, + 16364, 804, 11003, 12140, 14811, 7005, 5520, 15426, + 15893, 3981, 8423, 14053, 13160, 9760, 2404, 16207, + 16207, 2404, 9760, 13160, 14053, 8423, 3981, 15893, + 15426, 5520, 7005, 14811, 12140, 11003, 804, 16364, + 16379, 402, 11297, 11866, 14978, 6639, 5897, 15286, + 15986, 3590, 8765, 13842, 13395, 9434, 2801, 16143, + 16261, 2006, 10080, 12916, 14256, 8076, 4370, 15791, + 15557, 5139, 7366, 14635, 12406, 10702, 1205, 16340, + 16340, 1205, 10702, 12406, 14635, 7366, 5139, 15557, + 15791, 4370, 8076, 14256, 12916, 10080, 2006, 16261, + 16143, 2801, 9434, 13395, 13842, 8765, 3590, 15986, + 15286, 5897, 6639, 14978, 11866, 11297, 402, 16379, + 16383, 201, 11442, 11727, 15059, 6455, 6084, 15213, + 16029, 3393, 8935, 13733, 13510, 9269, 2999, 16107, + 16284, 1806, 10238, 12792, 14354, 7900, 4563, 15736, + 15619, 4948, 7545, 14543, 12537, 10549, 1406, 16324, + 16353, 1005, 10853, 12274, 14724, 7186, 5330, 15493, + 15843, 4176, 8250, 14155, 13039, 9921, 2205, 16235, + 16176, 2603, 9598, 13279, 13949, 8595, 3786, 15941, + 15357, 5708, 6823, 14896, 12004, 11151, 603, 16373, + 16373, 603, 11151, 12004, 14896, 6823, 5708, 15357, + 15941, 3786, 8595, 13949, 13279, 9598, 2603, 16176, + 16235, 2205, 9921, 13039, 14155, 8250, 4176, 15843, + 15493, 5330, 7186, 14724, 12274, 10853, 1005, 16353, + 16324, 1406, 10549, 12537, 14543, 7545, 4948, 15619, + 15736, 4563, 7900, 14354, 12792, 10238, 1806, 16284, + 16107, 2999, 9269, 13510, 13733, 8935, 3393, 16029, + 15213, 6084, 6455, 15059, 11727, 11442, 201, 16383 +}; const int16_t Idx_dortft40[40] = { 0, 25, 10, 35, 20, 5, 30, 15, 16, 1, 26, 11, 36, 21, 6, 31, 32, 17, 2, 27, @@ -22254,6 +29463,19 @@ const float w_edct2_64[80] = 0.19134171f, 0.17994751f, 0.16844492f, 0.15684087f, 0.14514233f, 0.13335637f, 0.12149008f, 0.10955062f, 0.09754516f, 0.08548094f, 0.07336523f, 0.06120533f, 0.04900857f, 0.03678228f, 0.02453383f, 0.01227061f }; +const Word16 w_edct2_64_fx[80] = /*Q14 */ +{ + 16384, 0, 11585, 11585, 15137, 6270, 6270, 15137, + 16069, 3196, 9102, 13623, 13623, 9102, 3196, 16069, + 11585, 8190, 8182, 8170, 8153, 8130, 8103, 8071, + 8035, 7993, 7946, 7895, 7839, 7779, 7713, 7643, + 7568, 7489, 7405, 7317, 7225, 7128, 7027, 6921, + 6811, 6698, 6580, 6458, 6333, 6203, 6070, 5933, + 5793, 5649, 5501, 5351, 5197, 5040, 4880, 4717, + 4551, 4383, 4212, 4038, 3862, 3683, 3503, 3320, + 3135, 2948, 2760, 2570, 2378, 2185, 1990, 1795, + 1598, 1401, 1202, 1003, 803, 603, 402, 201 +}; const float FFT_RotVector_32[40] = { 0.9807852507f, -0.1950903237f, 0.9238796234f, -0.3826834261f, 0.8314696550f, -0.5555702448f, 0.7071067691f, -0.7071067691f, @@ -23250,6 +30472,112 @@ const float hvq_peak_cb[1024] = 0.2074577f, 0.1714071f, 0.8760290f, -0.6561672f, 0.1851064f, 0.1440378f, 0.7655031f, -0.8835155f }; +const Word16 hvq_peak_cb_fx[1024] = /* Q15 */ +{ + -22652,-20549,-23019, 13968,-25496,-27493, -6957, 5753,-19678,-20274, + -6119, 18297, -5329,-22843,-21254, 13929,-27525,-29034, 563, 7265, + -26138,-13138, -9678, 7972, -517,-20830,-10703, 26832,-27818,-21449, + 208, 6297,-14803,-28396, -7655, 5118, 15134,-24005,-21776, 25330, + -11282,-23669,-20340, -2006,-16212,-24127, 9075, 22581,-20047,-25695, + -254, 6509,-17174,-29714, 1589, 7104,-17683, -4117, -4049, 22347, + -28338,-13898, 671, 6777,-18368,-17925, -7409, 5169,-22093,-19561, + 702, 5969, -6610,-27398, -4875, 8773,-29634, -5552, 272, 6992, + -9167,-19887, -9136, 6447,-23125,-25612, 9760, 5749,-10410,-29816, + 1606, 7019,-13758,-24849, 2084, 7129,-17795,-16160, 596, 7287, + -22276,-11145, 521, 6474,-13471,-20705, -74, 6740, 1891,-16245, + -12763, 13602, -1617,-27384, -9648, 2511,-21802,-11734, -4836, -1602, + -9670,-27913, 6456, 6338,-23227, -4603, 754, 5830, -7699,-24416, + 2204, 6518,-27591, 2763, 1885, 6839,-15248,-10500, 344, 6942, + -13247, -9761, -4486, 4294,-12097,-15164, 637, 6142,-25994,-16384, + 17277, 6511,-10346,-26179, 923, -2374,-13316,-18125, 6841, 7100, + -21083,-24251, 4207, -9464,-22914, -7057, 8647, 8026, 2488,-20731, + -799, 13754, -3451,-12872, 2545, 17315, 2576,-19594,-10340, 4361, + -7007,-19401, 1937, 6751, 17502,-24923,-16948, 8534, -3436,-29004, + 6315, 6467,-16936, -4957, 591, 6604, 1099,-26790, -708, 5543, + -5949,-14167, -4750, 4068,-10682,-14990, -7489, -5197, 169, -6472, + -5143, 16200,-20331, 1722, 395, 6233,-15661,-22913, 24689, 14221, + -3892,-22862, 5154, 6301, -8786,-10120, 216, 6831,-12390,-11062, + 4824, 6473, -7705, -4195, -5326, 6572, -560,-20773, -2777, 1822, + -6703,-14413, 2409, 6083,-10595,-25038, 14291, 4825, 2064,-25736, + 16863, 20463, -2752,-29103, 12609, 7539, -7638,-18024, 1948, 689, + -10961, -5839, 683, 6170,-26004, 12209, 10742, 15580, -2105, -8625, + -4932, 6977, -9940,-15129, 12160, 9806,-13921, -55, 440, 6315, + -305, -6080, 11303, 25730,-12423, -3161, 6875, 9836, -2780,-16434, + 4128, 5778, 17790,-10991, -6633, 21111, 12367,-26550,-10581, -2530, + -6713,-10210, 4804, 6280, -5932, 2832, 4978, 18330, 2696,-23822, + -11870,-13313, 5266,-10870, -7933, 4455, -3155,-10994, 2225, 5803, + 820,-11966, -1397, 5344, -5027, -7230, 1236, 5812, -1649,-21007, + 8948, 5539,-16246, -801, -533, -3132, -8272, -1302, 367, 5958, + -26574, -3470, 7126, -8876, -4819, -5380, -3923, 1466, 1929,-20655, + 4419, 3663, 2437,-26758, 10897, 5616, -6601,-10394, 2148, 137, + 15007,-22909, -3948, 6197, -9059,-27702, 23041, 4088, 8312, -267, + 2973, 25579, -3795, -3612, -489, 5401, 7711,-25887, 3443, 2623, + -24306, 3091, 13248, 3273, -3113, -1410, 3541, 12047, 306,-11933, + -4493, -1997,-18725, 8257, 7593, 7218,-13588, -8411, 8715, -1137, + -12028, 5907, 17904, 21327, -2223,-22989, 9863, -1633, -723, -5944, + 714, 5170, 2128,-15199, 2081, 1626, -482, -8521, 8131, 10765, + 53,-12020, 5152, 5033, 2361,-13747, 24714, 26357, 1074,-28538, + 18087, 4333, 1067,-22148, 14277, 5540, 729,-15049, 7936, 4648, + -16646, -6350, 23646, 9628, -91, -8477, 3298, 4297, 3499, -7417, + -2214, 2931, -4795, -4424, 6487, 4264, -9333, 3377, 6570, 5734, + 1733,-17598, 11163, 4167, -2713,-16183, 14693, 4188,-23780, 9825, + 25701, 15331, 586,-19288, 21576, 12040, 11328,-15656, 2944, 7335, + 9203,-16906, -5723, -5371, -7906, -4632, 12470, 5724, -123,-16520, + 976, -8288, 1262, -3966, -3014, -148, 230, -2169, 505, 3954, + -2256,-11474, 9990, 2644, 4841, -8017, -4617, -2959, 24226,-22733, + 7475, 17722, 6747, -5782, 4877, 8664, -6893,-24218, 12181,-14683, + 2839, -7574, 4815, 2376, 2680, -3986, 1749, 2061, -563, 3232, + 3039, 5761, 343, -4150, 6600, 3792, 6356, 7199, 10702, 24266, + -25636,-12157, 22874,-14633, 2438, -8680, 8312, 3091, 7135, -3110, + 268, 4547, 4272, 4886, 5861, 14177, 11382,-10386, -767, 1448, + 1770,-28758, 27658, 4643, -3008,-10314, 18024, 5252, 6999,-17854, + 9789, 909, 1556,-21532, 20929, 3182, 26836,-23774, -2868, 3509, + -9884,-14471, 24685, 193, -3300, -5891, 5237, -5722, -9043,-14338, + 17448, -7167, -683, 26, 4002, -235, 3072,-12689, 13537, 2670, + 3577,-10477, 10097, 1435, 17713,-24555, 7486, 1713, 6633, -6645, + 1863, -783, 3185, -8349, 3975, -3967, 8090,-23915, 7470, -8732, + 2793,-16733, 17412, 1948, -5975,-14195, 1741,-22095, 3376, -782, + 18258, 16642, 3845, -3536, 5136, 335, 3267, -719, 10538, 7756, + -10993, 5165, 17885, 4767, 4733, -7751, 15643, 8215, 3678, 1686, + 3571, 2189,-11186, 1470, 6152,-11489, 4353, -2197, 1357, -3164, + 4258, -6029, 8420, -230, 6220, -1478, 2105, -787, -4229, -4632, + 15095, -1672, 1986,-16134, 14035, -6088, 7849,-14512, 2875,-10127, + 4796,-14269, -8761,-25428, 1192,-24490, 22001, -6216, 258,-10418, + 27459, 10524, -754, 7182, 7574, 3444, 5995, 3253, 25190, 25483, + 6379, -6363, 409, -8435, -3319, 3253, 12035, 1358, 3184, -6482, + 12864, -216, 25363, -7652, -2971, 5718, 4969, -3415, 7040, -2605, + 2616,-21129, 28211, 1289, 2553,-15075, 23833, 1871, 14598, -6793, + 7189, 4535, 5581, -1997, 4257, -4337, 6027,-10630, 9913, -5633, + 3695,-11614, 19091, 585, 4415, -8798, 15569, -1099, -879, 752, + 19480, 5412, 5743, 448, 9863, 1342, 20634,-16941, -7404,-16938, + -11946, 17852, 19422, 5918, 12538,-20829, 22707, 1113, 4715, -4341, + 12573, -3709, 4015, -8219, 3349,-17549, 6395, -1551, 4414, -8302, + 24598,-24474, 21909, 9778, 5346, 1386, 6942, -4708, -1507, 2077, + 8224,-10420, 6088, -3411, 8824, -6355, 7219, 17353, 22325, 25889, + 6666, -1811, 1964,-13461, 8123, -4454, 26614, 11418, 4582, -7133, + 18420, -3918, -264, 10545, 24810, 12821, 6936,-22880, 10241,-24118, + 3108, -7220, 11991,-12963, 4237,-10392, 23417, -2591, 4624,-14780, + 29121, -1235, 7543, -1157, 17358, 1244, 20161, -6319, 2575, -5204, + 4384, 5974, 10993, -2909, 1619, -4017, 26017, 722, 4659, 11545, + 14463, 4774, -2892, 10593, 15058, -4543, 1972,-15782, 26652,-10199, + 6046, -562, 11992, -8022, 6197, -349, 7928,-12070, 21399,-13670, + 15116, 99, 5829, -4061, 16713, -7200, -8904, 4170, 24814, -7599, + 12177, 6080, 19388, 11094, 4262, 1544, 17090, -4775, -6957, -5908, + 19576,-23176, 7126,-23499, 24889,-17683, 5514, -5416, 23284, -5830, + 6388, -1788, 14378,-11597, 5099, -8771, 28791, -4573, 6029, -4164, + 3217,-26929, 6427, 145, 9306,-17874, 5544, 3835, 25432, -15, + 8297,-10673, 21003,-15084, 6019, -7628, 13891,-22535, 27144, 1685, + 10077, 4230, 5211, -1543, 22179,-10638, 6385, 5710, 13476,-12976, + 5272, 17571, 23747, 5084, -2100, 9127, 13746,-20852,-16310, 15716, + 21422,-23074, 6532, -31, 17127,-16620, 5397, -3362, 28477, -9453, + 6238, 1258, 13189,-22475, 12895, -4568, 8062,-26648, 2873, 5975, + 22151,-15208, 6319, -507, 23117,-17415, 24129,-14207, 12908,-21101, + 7262, 8470, 25405, -9450, 5424, -1162, 29494,-16114, 21373, 22875, + 24554, 16783, 6684, 2453, 15785,-28885, 6504, 1085, 21619,-24241, + 21468, 620, 23222, -7235, 10917, 8863, 18570,-21606, 6710, -2091, + 28961,-25837, 6884, 20869, 27603, -8999, 6798, 5617, 28706,-21501, + 6066, 4720, 25084,-28951 +}; const int16_t hvq_pg_huff_offset[NUM_PG_HUFFLEN] = {0,2,3,8,9,11,13,15,19}; const int16_t hvq_pg_huff_thres[NUM_PG_HUFFLEN] = {0,0x2,0x4,0x18,0x20,0x40,0x80,0x100,0x300}; @@ -23299,13 +30627,26 @@ const float SmoothingWin_NB875[70] = 0.81174493f,0.82896936f,0.84553134f,0.86139745f,0.87653571f,0.89091575f,0.90450847f,0.91728663f,0.92922437f,0.94029778f, 0.95048445f,0.95976388f,0.96811742f,0.97552824f,0.98198146f,0.98746395f,0.99196482f,0.99547487f,0.99798715f,0.99949653f }; +const Word16 SmoothingWin_NB875_fx[70] = /*Q15*/ +{ + 0, 16, 66, 148, 263, 411, 590, 802, 1045, 1318, + 1623, 1956, 2319, 2710, 3129, 3574, 4046, 4542, 5062, 5604, + 6169, 6754, 7358, 7981, 8620, 9275, 9945, 10627, 11321, 12025, + 12738, 13459, 14185, 14915, 15649, 16384, 17119, 17853, 18583, 19309, + 20030, 20743, 21447, 22141, 22823, 23493, 24148, 24787, 25410, 26014, + 26599, 27164, 27706, 28226, 28722, 29194, 29639, 30058, 30449, 30812, + 31145, 31450, 31723, 31966, 32178, 32357, 32505, 32620, 32702, 32752 +}; const float SmoothingWin_NB2[16] = { 0.00000000f,0.00960736f,0.03806023f,0.08426519f,0.14644661f,0.22221488f,0.30865828f,0.40245484f,0.50000000f,0.59754516f, 0.69134172f,0.77778512f,0.85355339f,0.91573481f,0.96193977f,0.99039264f }; - +const Word16 SmoothingWin_NB2_fx[16] = +{ + 0, 315, 1247, 2761, 4799, 7282, 10114, 13188, 16384, 19580, 22654, 25486, 27969, 30007, 31521, 32453 +}; /*----------------------------------------------------------------------------------* * SC-VBR *----------------------------------------------------------------------------------*/ @@ -24193,6 +31534,8 @@ const Word16 UVG2CB2_NB_FX[UVG2_CBSIZE][5] = /* Q12 */ const float frac_4sf[NB_SUBFR+2] = {0.25f,0.5f,0.75f,1.0f,1.0f,1.0f}; +const Word16 frac_4sf_fx[NB_SUBFR + 2] = { 4,8,12,16,16,16 }; /* Q4 */ + /* ERB table for PPP-ampl-quant */ const float erb_WB[NUM_ERB_WB+1] = {0.0f, 92.8061f, 185.6121f, 278.4182f, 371.2243f, 464.0304f, 556.8364f, 649.6425f, 746.4f, 853.6f, 972.5f, 1104.0f, 1251.8f, 1415.8f, 1599.2f, 1804.6f, 2035.2f, 2294.9f, 2588.4f, 2921.2f, 3300.1f, @@ -24831,7 +32174,6 @@ const float PowerCB_WB[64][2] = { 0.60449219f, 1.1943359f, }, }; - const float PowerCB_NB[64][2] = { { -1.6352539f, -1.359375f, }, @@ -24900,6 +32242,143 @@ const float PowerCB_NB[64][2] = { 0.95166016f, 1.0351563f, }, }; +const Word16 PowerCB_WB_fx[128] = +{ + -3371, -1712, + -170, 350, + -638, -939, + 56, 1074, + -1559, -626, + 200, 344, + -397, 238, + 284, 1415, + -1323, -1880, + -544, 1170, + -619, -255, + 587, 974, + -1262, -98, + 327, 151, + 41, -302, + 941, 1876, + -2257, -1233, + 28, 202, + -520, -561, + 338, 1048, + -1080, -495, + 190, 582, + -284, -24, + 578, 1585, + -1324, -1089, + -71, 568, + -471, -26, + 1140, 909, + -856, -128, + 425, 740, + 140, 12, + 1595, 1891, + -2176, -2310, + -308, 541, + -315, -859, + -80, 1314, + -1782, 510, + 403, 450, + -607, 582, + 145, 1837, + -920, -1386, + -225, 872, + -395, -258, + 829, 981, + -945, 345, + 643, 241, + -56, -23, + 1211, 1482, + -1793, -1459, + 40, 400, + -239, -471, + 532, 1238, + -774, -516, + 244, 831, + -157, 152, + 576, 2287, + -928, -844, + 41, 759, + -161, -198, + 873, 1353, + -640, 105, + 695, 623, + 364, -184, + 1238, 2446 +}; + +const Word16 PowerCB_NB_fx[128] = +{ + -3349, -2784, + -784, 385, + -891, -562, + 126, 915, + -1518, -1438, + 304, 53, + -314, -447, + 687, 1219, + -2585, -1807, + -65, 153, + -1219, -337, + 497, 700, + -894, -1051, + 161, 451, + -46, -516, + 987, 1519, + -2277, -2303, + -354, 445, + -532, -540, + 5, 1271, + -1047, -1433, + 672, -225, + -335, -75, + 1007, 1056, + -1362, -1879, + -93, 367, + -468, -259, + 1800, -290, + -1118, -793, + 412, 472, + -9, -197, + 1471, 1634, + -2627, -2847, + -269, 164, + -689, -373, + 432, 940, + -1601, -839, + 311, 271, + -212, -251, + 543, 1714, + -2014, -1336, + 109, 241, + -789, -110, + 729, 888, + -418, -1277, + 256, 674, + 218, -217, + 1027, 2065, + -1769, -2293, + -276, 853, + -360, -764, + 376, 1247, + -1274, -1122, + 602, 272, + -133, -32, + 1374, 1118, + -1860, -1795, + -23, 620, + -525, 60, + 1070, 548, + -691, -799, + 701, 572, + 81, 18, + 1949, 2120 +}; + + /* sinc for warp/extrapolate./16384., in Q14 */ const float sinc[8][12] = { @@ -24934,6 +32413,16 @@ const float overlap_coefs_48kHz[NSV_OVERLAP*WIDTH_BAND] = const float overlap_coefs[NSV_OVERLAP*WIDTH_BAND] = { 0.2700f, 0.3060f, 0.3240f, 0.3510f, 0.3780f, 0.3960f, 0.4140f, 0.4275f, 0.4410f, 0.4590f, 0.4860f, 0.5130f, 0.5580f, 0.6480f, 0.7470f, 0.855f }; +const Word16 overlap_coefs_48kHz_fx[NSV_OVERLAP*WIDTH_BAND] = /* in Q15 */ +{ + 9830, 11141, 11796, 12780, 13763, 14418, 15073, 15565, 16056, 16712, 17695, 18678, 20316, 23593, 27197, 31130 +}; + +const Word16 overlap_coefs_fx[NSV_OVERLAP*WIDTH_BAND] = /* in Q15 */ +{ + 8847, 10027, 10617, 11502, 12386, 12976, 13566, 14008, 14451, 15041, 15925, 16810, 18285, 21234, 24478, 28017 +}; + const float swb_hr_env_code1[NUM_ENVLOPE_CODE_HR1*2] = { 0.044983f, 0.041700f, @@ -25058,6 +32547,46 @@ const float swb_hr_env_code3[NUM_ENVLOPE_CODE_HR_TR*N_BANDS_TRANS_BWE_HR] = 11.724073f, 1.637023f }; +const Word16 swb_hr_env_code1_fx[NUM_ENVLOPE_CODE_HR1 * 2] = /* in Q9 */ +{ + 23, 21, 268, 240, 344, 310, 504, 438, + 629, 580, 856, 734, 1305, 1209, 1637, 1693, + 1321, 2671, 2154, 3709, 1801, 890, 2243, 1410, + 2436, 2404, 3496, 3127, 2279, 5187, 3715, 6394, + 3435, 1000, 3381, 1894, 5434, 1299, 4806, 2171, + 3645, 4240, 4640, 3628, 4567, 4999, 5785, 6023, + 6032, 3010, 7194, 4949, 5735, 4609, 7391, 6777, + 7341, 1999, 10276, 2220, 9270, 4210, 11444, 4917, + 3708, 8481, 6030, 9814, 5694, 7913, 7457, 8888, + 9124, 6090, 8943, 7832, 10925, 6889, 10519, 8768, + 4637, 11437, 5754, 14762, 6791, 12873, 8317, 14468, + 7818, 11028, 8696, 12646, 10031, 11617, 10315, 13255, + 9112, 9960, 10901, 10336, 12338, 9772, 12090, 11543, + 12125, 8360, 13766, 9934, 13317, 8004, 14817, 8315, + 12848, 6332, 14189, 6791, 14505, 5289, 15684, 6580, + 12940, 3143, 14948, 3698, 16472, 2570, 16373, 4851 +}; + +const Word16 swb_hr_env_code2_fx[NUM_ENVLOPE_CODE_HR2 * 2] = /* in Q9 */ +{ + 262, 242, 686, 568, 1303, 901, 1600, 1559, + 2505, 1905, 2053, 2944, 2617, 1108, 3414, 1993, + 4329, 1409, 5695, 1801, 3391, 3052, 4384, 2562, + 4567, 3985, 5509, 3051, 6374, 4280, 7003, 5750, + 7000, 2794, 8434, 2006, 10706, 3294, 13034, 4412, + 8402, 3878, 9510, 5269, 11309, 6406, 10839, 8811, + 2701, 4927, 4656, 5773, 6116, 7956, 8474, 7704, + 3255, 8984, 6818, 11144, 3915, 13367, 1255, 16350 +}; + +const Word16 swb_hr_env_code3_fx[NUM_ENVLOPE_CODE_HR_TR*N_BANDS_TRANS_BWE_HR] = /* in Q9 */ +{ + 409, 347, 898, 622, 1457, 1033, 2242, 1012, + 3039, 1508, 2017, 2161, 4137, 1348, 3881, 2553, + 2538, 5306, 3962, 4430, 4730, 3610, 5225, 2877, + 5450, 2240, 5970, 1779, 5553, 1364, 6003, 838 +}; + /* Searching thresholds for quantization of norms */ const float thren_HQ[39] = { @@ -25094,6 +32623,12 @@ const float hp12800_16000[21] = 0.13749378f, -0.18212549f, 0.19916883f, -0.18212549f, 0.13749378f, -0.08143591f, 0.03177450f, 0.00000000f, -0.01235466f, 0.01161181f, -0.00632535f, 0.00212227f, -0.00000000f }; +const Word16 hp12800_16000_fx[21] = +{ + -0, 70, -207, 380, -405, 0, 1041, -2668, 4505, + -5968, 6526, -5968, 4505, -2668, 1041, 0, -405, 380, + -207, 70, -0 +}; const float hp12800_32000[41] = { @@ -25104,6 +32639,15 @@ const float hp12800_32000[41] = -0.00620853f, 0.00477033f, 0.00583523f, 0.00000000f, -0.00317865f, -0.00143351f, 0.00106650f, 0.00136608f, -0.00000000f }; +const Word16 hp12800_32000_fx[41] = +{ + -0, 45, 35, -47, -104, 0, 191, 156, + -203, -422, -0, 675, 523, -656, -1341, 0, + 2264, 1943, -2999, -9872, 19678, -9872, -2999, 1943, + 2264, 0, -1341, -656, 523, 675, -0, -422, + -203, 156, 191, 0, -104, -47, 35, 45, -0 +}; + const float hp12800_48000[61] = { @@ -25116,7 +32660,15 @@ const float hp12800_48000[61] = -0.00413694f, 0.00122967f, 0.00427438f, 0.00388820f, 0.00136699f, -0.00111583f, -0.00211804f, -0.00156225f, -0.00030497f, 0.00071064f, 0.00101850f, 0.00067336f, -0.00000000f }; - +const Word16 hp12800_48000_fx[61] = +{ + -0, 22, 33, 23, -10, -51, -69, -37, 45, 127, + 140, 40, -136, -271, -238, 0, 326, 507, 349, -143, + -696, -894, -450, 535, 1509, 1696, 521, -1998, -5136, -7735, + 24039, -7735, -5136, -1998, 521, 1696, 1509, 535, -450, -894, + -696, -143, 349, 507, 326, 0, -238, -271, -136, 40, + 140, 127, 45, -37, -69, -51, -10, 23, 33, 22, -0, +}; const float hp16000_32000[33] = { @@ -25126,6 +32678,13 @@ const float hp16000_32000[33] = -0.00000000f, -0.01594711f, -0.00000000f, 0.00824247f, -0.00000000f, -0.00386248f, -0.00000000f, 0.00188788f, -0.00000000f }; +const Word16 hp16000_32000_fx[33] = +{ + -0, 62, -0, -127, -0, 270, -0, -523, -0, 940, + -0, -1662, -0, 3212, -0, -10353, 16407, -10353, -0, 3212, + -0, -1662, -0, 940, -0, -523, -0, 270, -0, -127, + -0, 62, -0 +}; const float hp16000_48000[49] = { @@ -25137,6 +32696,15 @@ const float hp16000_48000[49] = 0.00534416f, 0.00421805f, -0.00000000f, -0.00254135f, -0.00195325f, -0.00000000f, 0.00119953f, 0.00100660f, -0.00000000f }; +const Word16 hp16000_48000_fx[49] = +{ + -0, 33, 39, -0, -64, -83, -0, 138, 175, 0, + -272, -334, -0, 493, 596, 0, -870, -1059, -0, 1636, + 2120, 0, -4448, -9003, 21858, -9003, -4448, 0, 2120, 1636, + -0, -1059, -870, 0, 596, 493, -0, -334, -272, 0, + 175, 138, -0, -83, -64, -0, 39, 33, -0 +}; + const double cu15[28][3] = { @@ -25196,6 +32764,20 @@ const int16_t ct2[7][13] = /*32*/ { 4, 4, 4, 4, 4, 0, 0, 0, 2, 1, 1, 4, 4}, /*48*/ {18, 18, 18, 18, 18, 0, 0, 0, 5, 2, 1, 4, 15}, }; +const Word16 ct2_fx[7][14] = +{ + /* accepted configurations */ + /*input 12.8, output : fout/fin Q13*/ + /*8*/ {30, 22, 30, 16, 25, 30, 19, 30, 30, 0, 8, 4, 15, 5120}, + /*16*/ {25, 22, 19, 16, 16, 0, 0, 0, 12, 1, 4, 4, 15, 10240}, + /*32*/ {19, 16, 19, 16, 16, 0, 0, 0, 6, 2, 2, 4, 15, 20480}, + /*48*/ {17, 14, 15, 16, 16, 0, 0, 0, 4, 3, 4, 4, 15, 30720}, + + /*input 16, output :*/ + /*12*/ { 9, 3, 4, 5, 9, 0, 0, 0, 5, 0, 5, 5, 4, 6554}, + /*32*/ { 4, 4, 4, 4, 4, 0, 0, 0, 2, 1, 1, 4, 4, 16384}, + /*48*/ {18, 18, 18, 18, 18, 0, 0, 0, 5, 2, 1, 4, 15, 24576}, +}; const Word16 cu15_fx[28][3] = /*Q13*/ { @@ -25248,6 +32830,7 @@ const Word16 cu4_fx[6][3] = /*Q13*/ *----------------------------------------------------------------------------------*/ const float h_high[5] = { -0.0125f, -0.1090f, 0.7813f, -0.1090f, -0.0125f }; +const Word16 h_high_fx[5] = { -410, -3572, 25602, -3572, -410 }; const float sincos_t_rad3[T_SIN_PI_2+1] = { @@ -25358,10 +32941,12 @@ const Word16 sincos_t_rad3_fx[T_SIN_PI_2 + 1] = * TCX *----------------------------------------------------------------------------------*/ -const float gain_corr_fac[3] = {1.0208f,1.0103f,1.0052f}; /*pow(10,2^(-n-2)/28)*/ -const float gain_corr_inv_fac[3] = {0.9797f,0.9898f,0.9949f};/*pow(10,-2^(-n-2)/28)*/ +const float gain_corr_fac_flt[3] = {1.0208f,1.0103f,1.0052f}; /*pow(10,2^(-n-2)/28)*/ +const float gain_corr_inv_fac_flt[3] = {0.9797f,0.9898f,0.9949f};/*pow(10,-2^(-n-2)/28)*/ +const Word16 gain_corr_fac[3] = { 0x4155, 0x40A9, 0x4055 }; /* pow(10, 2^(-n-2)/28) (1Q14) */ +const Word16 gain_corr_inv_fac[3] = { 0x7D67, 0x7EB2, 0x7F59 }; /* pow(10,-2^(-n-2)/28) (0Q15) */ -const float inter4_2tcx2[4][4] = +const float inter4_2tcx2_flt[4][4] = { { 0.2325402f, 0.5349195f, 0.2325402f, 0.0000000f }, { 0.1353017f, 0.5094465f, 0.3400065f, 0.0152453f }, @@ -25369,7 +32954,7 @@ const float inter4_2tcx2[4][4] = { 0.0152453f, 0.3400065f, 0.5094465f, 0.1353017f } }; -const float inter6_2tcx2[6][4] = +const float inter6_2tcx2_flt[6][4] = { { 0.2241379f, 0.5517241f, 0.2241379f, 0.0000000f }, { 0.1562044f, 0.5388595f, 0.2990011f, 0.0059349f }, @@ -25378,20 +32963,37 @@ const float inter6_2tcx2[6][4] = { 0.0240275f, 0.3750000f, 0.5018346f, 0.0991379f }, { 0.0059349f, 0.2990011f, 0.5388595f, 0.1562044f } }; -const float inter_core_12_8kHz_output_8kHz[] = +const Word16 inter4_2tcx2[4][4] = +{ + { 7620/*0.2325402f Q15*/, 17528/*0.5349195f Q15*/, 7620/*0.2325402f Q15*/, 0/*0.0000000f Q15*/ }, + { 4434/*0.1353017f Q15*/, 16694/*0.5094465f Q15*/, 11141/*0.3400065f Q15*/, 500/*0.0152453f Q15*/ }, + { 1995/*0.0608774f Q15*/, 14389/*0.4391226f Q15*/, 14389/*0.4391226f Q15*/, 1995/*0.0608774f Q15*/ }, + { 500/*0.0152453f Q15*/, 11141/*0.3400065f Q15*/, 16694/*0.5094465f Q15*/, 4434/*0.1353017f Q15*/ } +}; +const Word16 inter6_2tcx2[6][4] = +{ + { 7345/*0.2241379f Q15*/, 18079/*0.5517241f Q15*/, 7345/*0.2241379f Q15*/, 0/*0.0000000f Q15*/ }, + { 5119/*0.1562044f Q15*/, 17657/*0.5388595f Q15*/, 9798/*0.2990011f Q15*/, 194/*0.0059349f Q15*/ }, + { 3249/*0.0991379f Q15*/, 16444/*0.5018346f Q15*/, 12288/*0.3750000f Q15*/, 787/*0.0240275f Q15*/ }, + { 1800/*0.0549361f Q15*/, 14584/*0.4450639f Q15*/, 14584/*0.4450639f Q15*/, 1800/*0.0549361f Q15*/ }, + { 787/*0.0240275f Q15*/, 12288/*0.3750000f Q15*/, 16444/*0.5018346f Q15*/, 3249/*0.0991379f Q15*/ }, + { 194/*0.0059349f Q15*/, 9798/*0.2990011f Q15*/, 17657/*0.5388595f Q15*/, 5119/*0.1562044f Q15*/ } +}; + +const float inter_core_12_8kHz_output_8kHz_flt[] = { 0.5349196f, 0.5094466f, 0.4391227f, 0.3400065f, 0.2325402f, 0.1353016f, 0.0608773f, 0.0152453f, 0.0000000f }; -const float inter_core_12_8kHz_output_16kHz[] = +const float inter_core_12_8kHz_output_16kHz_flt[] = { 0.4279357f, 0.4147958f, 0.3774199f, 0.3214508f, 0.2548195f, 0.1860321f, 0.1225801f, 0.0699165f, 0.0312127f, 0.0078047f, 0.0000000f, 0.0000000f, 0.0000000f }; -const float inter_core_12_8kHz_output_32kHz[] = +const float inter_core_12_8kHz_output_32kHz_flt[] = { 0.2139679f, 0.2123089f, 0.2073979f, 0.1994284f, 0.1887100f, 0.1756491f, 0.1607254f, 0.1444646f, @@ -25400,7 +33002,7 @@ const float inter_core_12_8kHz_output_32kHz[] = 0.0156063f, 0.0087817f, 0.0039024f, 0.0009753f, 0.0000000f }; -const float inter_core_12_8kHz_output_48kHz[] = +const float inter_core_12_8kHz_output_48kHz_flt[] = { 0.1426452f, 0.1421528f, 0.1406841f, 0.1382653f, 0.1349386f, 0.1307618f, 0.1258066f, 0.1201564f, @@ -25412,19 +33014,19 @@ const float inter_core_12_8kHz_output_48kHz[] = 0.0011560f, 0.0002890f, 0.0000000f, 0.0000000f, 0.0000000f }; -const float inter_core_16kHz_output_8kHz[] = +const float inter_core_16kHz_output_8kHz_flt[] = { 0.5517241f, 0.5388595f, 0.5018346f, 0.4450639f, 0.3750000f, 0.2990011f, 0.2241379f, 0.1562044f, 0.0991379f, 0.0549361f, 0.0240275f, 0.0059349f, 0.0000000f }; -const float inter_core_16kHz_output_16kHz[] = +const float inter_core_16kHz_output_16kHz_flt[] = { 0.5517241f, 0.5388595f, 0.5018346f, 0.4450639f, 0.3750000f, 0.2990011f, 0.2241379f, 0.1562044f, 0.0991379f, 0.0549361f, 0.0240275f, 0.0059349f, 0.0000000f }; -const float inter_core_16kHz_output_32kHz[] = +const float inter_core_16kHz_output_32kHz_flt[] = { 0.2758621f, 0.2742414f, 0.2694298f, 0.2615753f, 0.2509173f, 0.2377748f, 0.2225320f, 0.2056203f, 0.1875000f, 0.1686403f, 0.1495006f, 0.1305132f, @@ -25432,7 +33034,7 @@ const float inter_core_16kHz_output_32kHz[] = 0.0274680f, 0.0189188f, 0.0120137f, 0.0067120f, 0.0029675f, 0.0007394f, 0.0000000f }; -const float inter_core_16kHz_output_48kHz[] = +const float inter_core_16kHz_output_48kHz_flt[] = { 0.1839080f, 0.1834272f, 0.1819912f, 0.1796198f, 0.1763457f, 0.1722133f, 0.1672782f, 0.1616061f, 0.1552712f, 0.1483546f, 0.1409433f, 0.1331275f, @@ -25442,26 +33044,26 @@ const float inter_core_16kHz_output_48kHz[] = 0.0080092f, 0.0055360f, 0.0035286f, 0.0019783f, 0.0008771f, 0.0002189f, 0.0000000f }; -const float inter_core_25_6kHz_output_8kHz[] = +const float inter_core_25_6kHz_output_8kHz_flt[] = { 0.5349196f, 0.5094466f, 0.4391227f, 0.3400065f, 0.2325402f, 0.1353016f, 0.0608773f, 0.0152453f, 0.0000000f }; -const float inter_core_25_6kHz_output_16kHz[] = +const float inter_core_25_6kHz_output_16kHz_flt[] = { 0.5349196f, 0.5094466f, 0.4391227f, 0.3400065f, 0.2325402f, 0.1353016f, 0.0608773f, 0.0152453f, 0.0000000f }; -const float inter_core_25_6kHz_output_32kHz[] = +const float inter_core_25_6kHz_output_32kHz_flt[] = { 0.4279357f, 0.4147958f, 0.3774199f, 0.3214508f, 0.2548195f, 0.1860321f, 0.1225801f, 0.0699165f, 0.0312127f, 0.0078047f, 0.0000000f, 0.0000000f, 0.0000000f }; -const float inter_core_25_6kHz_output_48kHz[] = +const float inter_core_25_6kHz_output_48kHz_flt[] = { 0.2852965f, 0.2813740f, 0.2698819f, 0.2516166f, 0.2278099f, 0.2000000f, 0.1698781f, 0.1391327f, @@ -25470,6 +33072,114 @@ const float inter_core_25_6kHz_output_48kHz[] = 0.0000000f }; +const TCX_LTP_FILTER_FLT tcxLtpFilters_flt[12] = +{ + { inter_core_12_8kHz_output_8kHz_flt, 2 }, + { inter_core_12_8kHz_output_16kHz_flt, 3 }, + { inter_core_12_8kHz_output_32kHz_flt, 5 }, + { inter_core_12_8kHz_output_48kHz_flt, 8 }, + { inter_core_16kHz_output_8kHz_flt, 2 }, + { inter_core_16kHz_output_16kHz_flt, 2 }, + { inter_core_16kHz_output_32kHz_flt, 4 }, + { inter_core_16kHz_output_48kHz_flt, 6 }, + { inter_core_25_6kHz_output_8kHz_flt, 2 }, + { inter_core_25_6kHz_output_16kHz_flt, 2 }, + { inter_core_25_6kHz_output_32kHz_flt, 3 }, + { inter_core_25_6kHz_output_48kHz_flt, 4 }, +}; + +const Word16 inter_core_12_8kHz_output_8kHz[] = +{ + 17528/*0.5349196f Q15*/, 16694/*0.5094466f Q15*/, 14389/*0.4391227f Q15*/, 11141/*0.3400065f Q15*/, + 7620/*0.2325402f Q15*/, 4434/*0.1353016f Q15*/, 1995/*0.0608773f Q15*/, 500/*0.0152453f Q15*/, + 0/*0.0000000f Q15*/ +}; +const Word16 inter_core_12_8kHz_output_16kHz[] = +{ + 14023/*0.4279357f Q15*/, 13592/*0.4147958f Q15*/, 12367/*0.3774199f Q15*/, 10533/*0.3214508f Q15*/, + 8350/*0.2548195f Q15*/, 6096/*0.1860321f Q15*/, 4017/*0.1225801f Q15*/, 2291/*0.0699165f Q15*/, + 1023/*0.0312127f Q15*/, 256/*0.0078047f Q15*/, 0/*0.0000000f Q15*/, 0/*0.0000000f Q15*/, + 0/*0.0000000f Q15*/ +}; +const Word16 inter_core_12_8kHz_output_32kHz[] = +{ + 7011/*0.2139679f Q15*/, 6957/*0.2123089f Q15*/, 6796/*0.2073979f Q15*/, 6535/*0.1994284f Q15*/, + 6184/*0.1887100f Q15*/, 5756/*0.1756491f Q15*/, 5267/*0.1607254f Q15*/, 4734/*0.1444646f Q15*/, + 4175/*0.1274097f Q15*/, 3608/*0.1100939f Q15*/, 3048/*0.0930161f Q15*/, 2511/*0.0766219f Q15*/, + 2008/*0.0612900f Q15*/, 1551/*0.0473253f Q15*/, 1146/*0.0349583f Q15*/, 798/*0.0243509f Q15*/, + 511/*0.0156063f Q15*/, 288/*0.0087817f Q15*/, 128/*0.0039024f Q15*/, 32/*0.0009753f Q15*/, + 0/*0.0000000f Q15*/ +}; +const Word16 inter_core_12_8kHz_output_48kHz[] = +{ + 4674/*0.1426452f Q15*/, 4658/*0.1421528f Q15*/, 4610/*0.1406841f Q15*/, 4531/*0.1382653f Q15*/, + 4422/*0.1349386f Q15*/, 4285/*0.1307618f Q15*/, 4122/*0.1258066f Q15*/, 3937/*0.1201564f Q15*/, + 3732/*0.1139041f Q15*/, 3511/*0.1071503f Q15*/, 3277/*0.1000000f Q15*/, 3033/*0.0925607f Q15*/, + 2783/*0.0849398f Q15*/, 2531/*0.0772420f Q15*/, 2280/*0.0695677f Q15*/, 2032/*0.0620107f Q15*/, + 1791/*0.0546572f Q15*/, 1559/*0.0475844f Q15*/, 1339/*0.0408600f Q15*/, 1132/*0.0345417f Q15*/, + 940/*0.0286774f Q15*/, 764/*0.0233055f Q15*/, 605/*0.0184558f Q15*/, 464/*0.0141503f Q15*/, + 341/*0.0104042f Q15*/, 237/*0.0072274f Q15*/, 152/*0.0046257f Q15*/, 85/*0.0026016f Q15*/, + 38/*0.0011560f Q15*/, 9/*0.0002890f Q15*/, 0/*0.0000000f Q15*/, 0/*0.0000000f Q15*/, + 0/*0.0000000f Q15*/ +}; +const Word16 inter_core_16kHz_output_8kHz[] = +{ + 18079/*0.5517241f Q15*/, 17657/*0.5388595f Q15*/, 16444/*0.5018346f Q15*/, 14584/*0.4450639f Q15*/, 12288/*0.3750000f Q15*/, 9798/*0.2990011f Q15*/, + 7345/*0.2241379f Q15*/, 5119/*0.1562044f Q15*/, 3249/*0.0991379f Q15*/, 1800/*0.0549361f Q15*/, 787/*0.0240275f Q15*/, 194/*0.0059349f Q15*/, + 0/*0.0000000f Q15*/ +}; +const Word16 inter_core_16kHz_output_16kHz[] = +{ + 18079/*0.5517241f Q15*/, 17657/*0.5388595f Q15*/, 16444/*0.5018346f Q15*/, 14584/*0.4450639f Q15*/, 12288/*0.3750000f Q15*/, 9798/*0.2990011f Q15*/, + 7345/*0.2241379f Q15*/, 5119/*0.1562044f Q15*/, 3249/*0.0991379f Q15*/, 1800/*0.0549361f Q15*/, 787/*0.0240275f Q15*/, 194/*0.0059349f Q15*/, + 0/*0.0000000f Q15*/ +}; +const Word16 inter_core_16kHz_output_32kHz[] = +{ + 9039/*0.2758621f Q15*/, 8986/*0.2742414f Q15*/, 8829/*0.2694298f Q15*/, 8571/*0.2615753f Q15*/, 8222/*0.2509173f Q15*/, 7791/*0.2377748f Q15*/, + 7292/*0.2225320f Q15*/, 6738/*0.2056203f Q15*/, 6144/*0.1875000f Q15*/, 5526/*0.1686403f Q15*/, 4899/*0.1495006f Q15*/, 4277/*0.1305132f Q15*/, + 3672/*0.1120690f Q15*/, 3097/*0.0945060f Q15*/, 2559/*0.0781022f Q15*/, 2067/*0.0630725f Q15*/, 1624/*0.0495690f Q15*/, 1235/*0.0376861f Q15*/, + 900/*0.0274680f Q15*/, 620/*0.0189188f Q15*/, 394/*0.0120137f Q15*/, 220/*0.0067120f Q15*/, 97/*0.0029675f Q15*/, 24/*0.0007394f Q15*/, + 0/*0.0000000f Q15*/ +}; +const Word16 inter_core_16kHz_output_48kHz[] = +{ + 6026/*0.1839080f Q15*/, 6011/*0.1834272f Q15*/, 5963/*0.1819912f Q15*/, 5886/*0.1796198f Q15*/, 5778/*0.1763457f Q15*/, 5643/*0.1722133f Q15*/, + 5481/*0.1672782f Q15*/, 5296/*0.1616061f Q15*/, 5088/*0.1552712f Q15*/, 4861/*0.1483546f Q15*/, 4618/*0.1409433f Q15*/, 4362/*0.1331275f Q15*/, + 4096/*0.1250000f Q15*/, 3823/*0.1166535f Q15*/, 3545/*0.1081796f Q15*/, 3266/*0.0996670f Q15*/, 2988/*0.0912002f Q15*/, 2715/*0.0828579f Q15*/, + 2448/*0.0747126f Q15*/, 2190/*0.0668293f Q15*/, 1942/*0.0592649f Q15*/, 1706/*0.0520681f Q15*/, 1484/*0.0452794f Q15*/, 1276/*0.0389306f Q15*/, + 1083/*0.0330460f Q15*/, 906/*0.0276422f Q15*/, 745/*0.0227295f Q15*/, 600/*0.0183120f Q15*/, 472/*0.0143894f Q15*/, 359/*0.0109575f Q15*/, + 262/*0.0080092f Q15*/, 181/*0.0055360f Q15*/, 116/*0.0035286f Q15*/, 65/*0.0019783f Q15*/, 29/*0.0008771f Q15*/, 7/*0.0002189f Q15*/, + 0/*0.0000000f Q15*/ +}; +const Word16 inter_core_25_6kHz_output_8kHz[] = +{ + 17528/*0.5349196f Q15*/, 16694/*0.5094466f Q15*/, 14389/*0.4391227f Q15*/, 11141/*0.3400065f Q15*/, + 7620/*0.2325402f Q15*/, 4434/*0.1353016f Q15*/, 1995/*0.0608773f Q15*/, 500/*0.0152453f Q15*/, + 0/*0.0000000f Q15*/ +}; +const Word16 inter_core_25_6kHz_output_16kHz[] = +{ + 17528/*0.5349196f Q15*/, 16694/*0.5094466f Q15*/, 14389/*0.4391227f Q15*/, 11141/*0.3400065f Q15*/, + 7620/*0.2325402f Q15*/, 4434/*0.1353016f Q15*/, 1995/*0.0608773f Q15*/, 500/*0.0152453f Q15*/, + 0/*0.0000000f Q15*/ +}; +const Word16 inter_core_25_6kHz_output_32kHz[] = +{ + 14023/*0.4279357f Q15*/, 13592/*0.4147958f Q15*/, 12367/*0.3774199f Q15*/, 10533/*0.3214508f Q15*/, + 8350/*0.2548195f Q15*/, 6096/*0.1860321f Q15*/, 4017/*0.1225801f Q15*/, 2291/*0.0699165f Q15*/, + 1023/*0.0312127f Q15*/, 256/*0.0078047f Q15*/, 0/*0.0000000f Q15*/, 0/*0.0000000f Q15*/, + 0/*0.0000000f Q15*/ +}; +const Word16 inter_core_25_6kHz_output_48kHz[] = +{ + 9349/*0.2852965f Q15*/, 9220/*0.2813740f Q15*/, 8843/*0.2698819f Q15*/, 8245/*0.2516166f Q15*/, + 7465/*0.2278099f Q15*/, 6554/*0.2000000f Q15*/, 5567/*0.1698781f Q15*/, 4559/*0.1391327f Q15*/, + 3582/*0.1093111f Q15*/, 2678/*0.0817166f Q15*/, 1879/*0.0573517f Q15*/, 1209/*0.0369093f Q15*/, + 682/*0.0208069f Q15*/, 303/*0.0092505f Q15*/, 76/*0.0023118f Q15*/, 0/*0.0000000f Q15*/, + 0/*0.0000000f Q15*/ +}; + const TCX_LTP_FILTER tcxLtpFilters[12] = { { inter_core_12_8kHz_output_8kHz, 2 }, @@ -25487,6 +33197,7 @@ const TCX_LTP_FILTER tcxLtpFilters[12] = }; + const SCALE_TCX_SETUP scaleTcxTable[SIZE_SCALE_TABLE_TCX] = { { 0, 0, 8000, 0.67f , 21955/*0.67f Q15*/ }, @@ -27399,7 +35110,7 @@ const int16_t igf_tile_offset_table[IGF_BITRATE_UNKNOWN][2*IGF_MAX_TILES+1] = { { 1, 2, 416} /*128000 FB (stereo) */ }; -const float igf_whitening_TH[IGF_BITRATE_UNKNOWN][2][IGF_MAX_TILES] = +const float igf_whitening_TH_flt[IGF_BITRATE_UNKNOWN][2][IGF_MAX_TILES] = { /* 0: for 9600 kbs WB */ { @@ -27582,6 +35293,94 @@ const float igf_whitening_TH[IGF_BITRATE_UNKNOWN][2][IGF_MAX_TILES] = /* strong */ {2.82f, 0.f, 0.f, 0.f} } }; +const Word16 igf_whitening_TH[][2][IGF_MAX_TILES] = +{ + /* 0: for 9600 kbs WB */ + { + /* medium */ { 2949/*0.36f Q13*/, 2949/*0.36f Q13*/, 0/*0.f Q13*/, 0/*0.f Q13*/}, + /* strong */ { 11551/*1.41f Q13*/, 11551/*1.41f Q13*/, 0/*0.f Q13*/, 0/*0.f Q13*/} +}, +/* 1: for 13200 kbs WB RF */ +{ + /* medium */ { 2949/*0.36f Q13*/, 2949/*0.36f Q13*/, 0/*0.f Q13*/, 0/*0.f Q13*/}, + /* strong */ { 11551/*1.41f Q13*/, 11551/*1.41f Q13*/, 0/*0.f Q13*/, 0/*0.f Q13*/} +}, +/* 2: for 9600 kbs SWB */ +{ + /* medium */ { 6881/*0.84f Q13*/, 7291/*0.89f Q13*/, 0/*0.f Q13*/, 0/*0.f Q13*/}, + /* strong */ { 10650/*1.30f Q13*/, 10240/*1.25f Q13*/, 0/*0.f Q13*/, 0/*0.f Q13*/} +}, +/* 3: for 13200 kbs SWB */ +{ + /* medium */ { 6881/*0.84f Q13*/, 7291/*0.89f Q13*/, 0/*0.f Q13*/, 0/*0.f Q13*/}, + /* strong */ { 10650/*1.30f Q13*/, 10240/*1.25f Q13*/, 0/*0.f Q13*/, 0/*0.f Q13*/} +}, +/* 4: for 13200 kbs SWB RF */ +{ + /* medium */ { 6881/*0.84f Q13*/, 7291/*0.89f Q13*/, 0/*0.f Q13*/, 0/*0.f Q13*/}, + /* strong */ { 10650/*1.30f Q13*/, 10240/*1.25f Q13*/, 0/*0.f Q13*/, 0/*0.f Q13*/} +}, +/* 5: for 16400 kbs SWB */ +{ + /* medium */ { 6799/*0.83f Q13*/, 7291/*0.89f Q13*/, 7291/*0.89f Q13*/, 0/*0.f Q13*/}, + /* strong */ { 10732/*1.31f Q13*/, 9748/*1.19f Q13*/, 9748/*1.19f Q13*/, 0/*0.f Q13*/} +}, +/* 6: for 24400 kbs SWB*/ +{ + /* medium */ { 6636/*0.81f Q13*/, 6963/*0.85f Q13*/, 6963/*0.85f Q13*/, 0/*0.f Q13*/}, + /* strong */ { 11059/*1.35f Q13*/, 10076/*1.23f Q13*/, 10076/*1.23f Q13*/, 0/*0.f Q13*/} +}, +/* 7: for 32000 kbs SWB */ +{ + /* medium */ { 7455/*0.91f Q13*/, 6963/*0.85f Q13*/, 6963/*0.85f Q13*/, 0/*0.f Q13*/}, + /* strong */ { 10977/*1.34f Q13*/, 11059/*1.35f Q13*/, 11059/*1.35f Q13*/, 0/*0.f Q13*/} +}, +/* 8: for 48000 kbs SWB */ +{ + /* medium */ { 9421/*1.15f Q13*/, 0/*0.f Q13*/, 0/*0.f Q13*/, 0/*0.f Q13*/}, + /* strong */ { 9748/*1.19f Q13*/, 0/*0.f Q13*/, 0/*0.f Q13*/, 0/*0.f Q13*/} +}, +/* 9: for 64000 kbs SWB */ +{ + /* medium */ { 9421/*1.15f Q13*/, 0/*0.f Q13*/, 0/*0.f Q13*/, 0/*0.f Q13*/}, + /* strong */ { 9748/*1.19f Q13*/, 0/*0.f Q13*/, 0/*0.f Q13*/, 0/*0.f Q13*/} +}, +/* 10: for 16400 kbs FB */ +{ + /* medium */ { 5161/*0.63f Q13*/, 2212/*0.27f Q13*/, 2949/*0.36f Q13*/, 0/*0.f Q13*/}, + /* strong */ { 12534/*1.53f Q13*/, 10813/*1.32f Q13*/, 5489/*0.67f Q13*/, 0/*0.f Q13*/} +}, +/* 11: for 24400 kbs FB */ +{ + /* medium */ { 6390/*0.78f Q13*/, 2540/*0.31f Q13*/, 2785/*0.34f Q13*/, 2785/*0.34f Q13*/}, + /* strong */ { 12206/*1.49f Q13*/, 11305/*1.38f Q13*/, 5325/*0.65f Q13*/, 5325/*0.65f Q13*/} +}, +/* 12: for 32000 kbs FB */ +{ + /* medium */ { 6390/*0.78f Q13*/, 2540/*0.31f Q13*/, 2785/*0.34f Q13*/, 2785/*0.34f Q13*/}, + /* strong */ { 12206/*1.49f Q13*/, 11305/*1.38f Q13*/, 5325/*0.65f Q13*/, 5325/*0.65f Q13*/} +}, +/* 13: for 48000 kbs FB */ +{ + /* medium */ { 6554/*0.80f Q13*/, 0/*0.f Q13*/, 0/*0.f Q13*/, 0/*0.f Q13*/}, + /* strong */ { 8192/*1.00f Q13*/, 0/*0.f Q13*/, 0/*0.f Q13*/, 0/*0.f Q13*/} +}, +/* 14: for 64000 kbs FB */ +{ + /* medium */ { 6554/*0.80f Q13*/, 0/*0.f Q13*/, 0/*0.f Q13*/, 0/*0.f Q13*/}, + /* strong */ { 8192/*1.00f Q13*/, 0/*0.f Q13*/, 0/*0.f Q13*/, 0/*0.f Q13*/} +}, +/* 15: for 96000 kbs FB */ +{ + /* medium */ { 0/*0.f Q13*/, 0/*0.f Q13*/, 0/*0.f Q13*/, 0/*0.f Q13*/}, + /* strong */ { 23101/*2.82f Q13*/, 0/*0.f Q13*/, 0/*0.f Q13*/, 0/*0.f Q13*/} +}, +/* 16: for 128000 kbs FB */ +{ + /* medium */ { 0/*0.f Q13*/, 0/*0.f Q13*/, 0/*0.f Q13*/, 0/*0.f Q13*/}, + /* strong */ { 23101/*2.82f Q13*/, 0/*0.f Q13*/, 0/*0.f Q13*/, 0/*0.f Q13*/} +} +}; /* IGF SCF arithmetic coder cumulative frequency tables and offsets */ @@ -28084,6 +35883,49 @@ const float tcx_mdct_window_48[420] = 0.99936891f , 0.99949473f , 0.99960661f , 0.99970454f , 0.99978846f , 0.99985838f , 0.99991435f , 0.99995631f , 0.99998426f , 0.99999827f , }; +const Word16 tcx_mdct_window_48_fx[420] = +{ 61, 183, 306, 428, 551, 673, 796, 919, 1041, 1163, 1286, +1408, 1531, 1653, 1776, 1898, 2020, 2143, 2265, 2387, 2509, +2632, 2754, 2876, 2998, 3120, 3242, 3364, 3486, 3607, 3729, +3851, 3973, 4094, 4216, 4337, 4459, 4580, 4701, 4823, 4944, +5065, 5186, 5307, 5428, 5549, 5669, 5790, 5911, 6031, 6152, +6272, 6392, 6512, 6632, 6752, 6872, 6992, 7112, 7231, 7351, +7470, 7589, 7709, 7828, 7947, 8065, 8184, 8303, 8421, 8540, +8658, 8776, 8894, 9012, 9130, 9247, 9365, 9482, 9599, 9717, +9834, 9950, 10067, 10184, 10300, 10416, 10532, 10648, 10764, 10880, +10995, 11111, 11226, 11341, 11456, 11571, 11685, 11800, 11914, 12028, +12142, 12256, 12369, 12483, 12596, 12709, 12822, 12934, 13047, 13159, +13271, 13383, 13495, 13607, 13718, 13829, 13940, 14051, 14162, 14272, +14382, 14492, 14602, 14712, 14821, 14930, 15039, 15148, 15257, 15365, +15473, 15581, 15689, 15796, 15904, 16011, 16117, 16224, 16330, 16437, +16542, 16648, 16754, 16859, 16964, 17068, 17173, 17277, 17381, 17485, +17589, 17692, 17795, 17898, 18000, 18102, 18204, 18306, 18408, 18509, +18610, 18711, 18811, 18911, 19011, 19111, 19210, 19310, 19408, 19507, +19605, 19703, 19801, 19899, 19996, 20093, 20190, 20286, 20382, 20478, +20573, 20669, 20764, 20858, 20953, 21047, 21140, 21234, 21327, 21420, +21513, 21605, 21697, 21789, 21880, 21971, 22062, 22152, 22242, 22332, +22422, 22511, 22600, 22688, 22777, 22865, 22952, 23040, 23127, 23213, +23300, 23386, 23471, 23557, 23642, 23726, 23811, 23895, 23978, 24062, +24145, 24227, 24310, 24392, 24473, 24555, 24636, 24716, 24797, 24877, +24956, 25035, 25114, 25193, 25271, 25349, 25426, 25504, 25580, 25657, +25733, 25808, 25884, 25959, 26033, 26108, 26181, 26255, 26328, 26401, +26473, 26545, 26617, 26688, 26759, 26830, 26900, 26970, 27039, 27108, +27177, 27245, 27313, 27381, 27448, 27514, 27581, 27647, 27712, 27778, +27842, 27907, 27971, 28034, 28098, 28161, 28223, 28285, 28347, 28408, +28469, 28529, 28589, 28649, 28708, 28767, 28826, 28884, 28942, 28999, +29056, 29112, 29168, 29224, 29279, 29334, 29388, 29442, 29496, 29549, +29602, 29654, 29706, 29758, 29809, 29859, 29910, 29959, 30009, 30058, +30106, 30155, 30202, 30250, 30297, 30343, 30389, 30435, 30480, 30525, +30569, 30613, 30656, 30700, 30742, 30784, 30826, 30867, 30908, 30949, +30989, 31029, 31068, 31106, 31145, 31183, 31220, 31257, 31294, 31330, +31365, 31401, 31435, 31470, 31504, 31537, 31570, 31603, 31635, 31667, +31698, 31729, 31759, 31789, 31819, 31848, 31876, 31905, 31932, 31960, +31986, 32013, 32039, 32064, 32089, 32114, 32138, 32162, 32185, 32208, +32230, 32252, 32273, 32294, 32315, 32335, 32354, 32374, 32392, 32411, +32428, 32446, 32463, 32479, 32495, 32511, 32526, 32540, 32555, 32568, +32582, 32594, 32607, 32619, 32630, 32641, 32652, 32662, 32671, 32680, +32689, 32697, 32705, 32712, 32719, 32726, 32732, 32737, 32742, 32747, +32751, 32755, 32758, 32761, 32763, 32765, 32766, 32767, 32767 }; const float tcx_mdct_window_half_48[180] = { 0.00436331f , 0.01308960f , 0.02181488f , 0.03053851f , 0.03925982f , 0.04797813f , 0.05669279f , 0.06540313f , 0.07410849f , 0.08280820f , @@ -28106,6 +35948,26 @@ const float tcx_mdct_window_half_48[180] = 0.99656552f , 0.99725020f , 0.99785894f , 0.99839169f , 0.99884838f , 0.99922901f , 0.99953359f , 0.99976200f , 0.99991435f , 0.99999046f , }; +const Word16 tcx_mdct_window_half_48_fx[180] = +{ + 142, 428, 714, 1000, 1286, 1572, 1857, 2143, 2428, 2713, 2998, +3282, 3567, 3851, 4135, 4418, 4701, 4984, 5267, 5549, 5830, +6112, 6392, 6672, 6952, 7231, 7510, 7788, 8065, 8342, 8619, +8894, 9169, 9443, 9717, 9989, 10261, 10532, 10803, 11072, 11341, +11609, 11876, 12142, 12407, 12671, 12934, 13197, 13458, 13718, 13977, +14235, 14492, 14748, 15003, 15257, 15509, 15761, 16011, 16260, 16507, +16754, 16999, 17242, 17485, 17726, 17966, 18204, 18441, 18677, 18911, +19144, 19376, 19605, 19834, 20061, 20286, 20510, 20732, 20953, 21172, +21389, 21605, 21819, 22032, 22242, 22452, 22659, 22865, 23069, 23271, +23471, 23670, 23867, 24062, 24255, 24446, 24636, 24823, 25009, 25193, +25375, 25555, 25733, 25909, 26083, 26255, 26425, 26593, 26759, 26923, +27085, 27245, 27403, 27559, 27712, 27864, 28013, 28161, 28306, 28449, +28589, 28728, 28865, 28999, 29131, 29261, 29388, 29514, 29637, 29758, +29876, 29992, 30106, 30218, 30328, 30435, 30540, 30642, 30742, 30840, +30935, 31029, 31119, 31208, 31294, 31377, 31458, 31537, 31614, 31688, +31759, 31828, 31895, 31960, 32021, 32081, 32138, 32192, 32245, 32294, +32341, 32386, 32428, 32468, 32506, 32540, 32573, 32603, 32630, 32655, +32677, 32697, 32715, 32730, 32742, 32752, 32760, 32765, 32767 }; const float tcx_mdct_window_trans_48[60] = { 0.01308960f , 0.03925982f , 0.06540313f , 0.09150162f , 0.11753740f , 0.14349262f , 0.16934951f , 0.19509032f , 0.22069745f , 0.24615330f , @@ -28116,6 +35978,14 @@ const float tcx_mdct_window_trans_48[60] = 0.96923089f , 0.97534233f , 0.98078531f , 0.98555607f , 0.98965138f , 0.99306846f , 0.99580491f , 0.99785894f , 0.99922901f , 0.99991435f , }; +const Word16 tcx_mdct_window_trans_48_fx[60] = +{ 428, 1286, 2143, 2998, 3851, 4701, 5549, 6392, 7231, 8065, 8894, +9717, 10532, 11341, 12142, 12934, 13718, 14492, 15257, 16011, 16754, +17485, 18204, 18911, 19605, 20286, 20953, 21605, 22242, 22865, 23471, +24062, 24636, 25193, 25733, 26255, 26759, 27245, 27712, 28161, 28589, +28999, 29388, 29758, 30106, 30435, 30742, 31029, 31294, 31537, 31759, +31960, 32138, 32294, 32428, 32540, 32630, 32697, 32742, 32765 +}; /*----------------------------------------------------------------------------------* * SWB TBE LSF tables (1.75 kbps) @@ -29879,6 +37749,1360 @@ const Word16 cos_diff_table[512] = const Word32 bwMode2fs[4] = { 8000, 16000, 32000, 48000 }; +const Word16 swb_lsp_prev_interp_init[10] = { 32767, 31164, 26510, 19261, 10126, 0, -10126, -19261, -26510, -31164 }; +/* st->swb_lsp_prev_interp[i] = (float)cos( (float)i * PI / (float)10.0f )*/ + +const Word16 L_frame_inv[8] = { 0x4000, 0x369D, 0x3333, 0x2D83, 0x2AAB, 0x28F6, 0, 0x2222 }; +const Word16 InvIntTable[65] = +{ + 0x7FFF, + 0x7FFF, 0x4000, 0x2AAB, 0x2000, 0x199A, 0x1555, 0x1249, 0x1000, + 0x0E39, 0x0CCD, 0x0BA3, 0x0AAB, 0x09D9, 0x0925, 0x0889, 0x0800, + 0x0788, 0x071C, 0x06BD, 0x0666, 0x0618, 0x05D1, 0x0591, 0x0555, + 0x051F, 0x04EC, 0x04BE, 0x0492, 0x046A, 0x0444, 0x0421, 0x0400, + 0x03E1, 0x03C4, 0x03A8, 0x038E, 0x0376, 0x035E, 0x0348, 0x0333, + 0x031F, 0x030C, 0x02FA, 0x02E9, 0x02D8, 0x02C8, 0x02B9, 0x02AB, + 0x029D, 0x028F, 0x0283, 0x0276, 0x026A, 0x025F, 0x0254, 0x0249, + 0x023F, 0x0235, 0x022B, 0x0222, 0x0219, 0x0211, 0x0208, 0x0200 +}; + +const Word16 TecLowBandTable[] = { 0, 2, 4, 6 }; +const Word16 TecSC_Fx[] = +{ + 23999/*0.3662f*2.0f Q15*/, 7065/*0.1078f*2.0f Q15*/, 7825/*0.1194f*2.0f Q15*/, + 8448/*0.1289f*2.0f Q15*/, 8946/*0.1365f*2.0f Q15*/, 9254/*0.1412f*2.0f Q15*/ +}; +const float TecSC[] = { 0.3662f, 0.1078f, 0.1194f, 0.1289f, 0.1365f, 0.1412f }; /* clang-format on */ +const Word16 sqrt_table_pitch_search[256 + 1] = /* Q11 */ +{ + 0, 2048, 2896, 3547, 4096, 4579, 5017, 5418, + 5793, 6144, 6476, 6792, 7094, 7384, 7663, 7932, + 8192, 8444, 8689, 8927, 9159, 9385, 9606, 9822, + 10033, 10240, 10443, 10642, 10837, 11029, 11217, 11403, + 11585, 11765, 11942, 12116, 12288, 12457, 12625, 12790, + 12953, 13114, 13273, 13430, 13585, 13738, 13890, 14040, + 14189, 14336, 14482, 14626, 14768, 14910, 15050, 15188, + 15326, 15462, 15597, 15731, 15864, 15995, 16126, 16255, + 16384, 16512, 16638, 16764, 16888, 17012, 17135, 17257, + 17378, 17498, 17618, 17736, 17854, 17971, 18087, 18203, + 18318, 18432, 18545, 18658, 18770, 18882, 18992, 19102, + 19212, 19321, 19429, 19537, 19644, 19750, 19856, 19961, + 20066, 20170, 20274, 20377, 20480, 20582, 20684, 20785, + 20886, 20986, 21085, 21185, 21283, 21382, 21480, 21577, + 21674, 21771, 21867, 21962, 22058, 22153, 22247, 22341, + 22435, 22528, 22621, 22713, 22806, 22897, 22989, 23080, + 23170, 23261, 23351, 23440, 23530, 23619, 23707, 23796, + 23884, 23971, 24059, 24146, 24232, 24319, 24405, 24491, + 24576, 24661, 24746, 24831, 24915, 24999, 25083, 25166, + 25249, 25332, 25415, 25497, 25580, 25661, 25743, 25824, + 25905, 25986, 26067, 26147, 26227, 26307, 26387, 26466, + 26545, 26624, 26703, 26781, 26859, 26937, 27015, 27092, + 27170, 27247, 27324, 27400, 27477, 27553, 27629, 27705, + 27780, 27856, 27931, 28006, 28081, 28155, 28230, 28304, + 28378, 28452, 28525, 28599, 28672, 28745, 28818, 28891, + 28963, 29035, 29108, 29180, 29251, 29323, 29394, 29466, + 29537, 29608, 29678, 29749, 29819, 29890, 29960, 30030, + 30099, 30169, 30238, 30308, 30377, 30446, 30515, 30583, + 30652, 30720, 30788, 30856, 30924, 30992, 31059, 31127, + 31194, 31261, 31328, 31395, 31462, 31529, 31595, 31661, + 31727, 31794, 31859, 31925, 31991, 32056, 32122, 32187, + 32252, 32317, 32382, 32446, 32511, 32575, 32640, 32704, + 32766 +}; + +//fft_evs.c +const Word16 RotVector_32[2 * 20] = +{ + /** + * \brief Twiddle factors are unscaled + */ + SHC(0x7d8a), SHC(0xe707), SHC(0x7642), SHC(0xcf04), SHC(0x6a6e), SHC(0xb8e3), SHC(0x5a82), SHC(0xa57e), + SHC(0x471d), SHC(0x9592), SHC(0x30fc), SHC(0x89be), SHC(0x18f9), SHC(0x8276), SHC(0x7642), SHC(0xcf04), + SHC(0x5a82), SHC(0xa57e), SHC(0x30fc), SHC(0x89be), SHC(0xcf04), SHC(0x89be), SHC(0xa57e), SHC(0xa57e), + SHC(0x89be), SHC(0xcf04), SHC(0x6a6e), SHC(0xb8e3), SHC(0x30fc), SHC(0x89be), SHC(0xe707), SHC(0x8276), + SHC(0xa57e), SHC(0xa57e), SHC(0x8276), SHC(0xe707), SHC(0x89be), SHC(0x30fc), SHC(0xb8e3), SHC(0x6a6e) +}; + +/** + * \brief Twiddle factors are unscaled + */ +const Word16 RotVector_480[2 * (480 - 30)] = +{ + SHC(0x7fff), SHC(0x0000), SHC(0x7ff5), SHC(0xfca6), + SHC(0x7fd3), SHC(0xf94d), SHC(0x7f9b), SHC(0xf5f5), SHC(0x7f4c), SHC(0xf29f), SHC(0x7ee8), SHC(0xef4b), + SHC(0x7e6d), SHC(0xebfa), SHC(0x7ddb), SHC(0xe8ad), SHC(0x7d34), SHC(0xe563), SHC(0x7c77), SHC(0xe21e), + SHC(0x7ba3), SHC(0xdedf), SHC(0x7abb), SHC(0xdba5), SHC(0x79bc), SHC(0xd872), SHC(0x78a8), SHC(0xd546), + SHC(0x7780), SHC(0xd221), SHC(0x7642), SHC(0xcf04), SHC(0x74ef), SHC(0xcbf0), SHC(0x7388), SHC(0xc8e5), + SHC(0x720d), SHC(0xc5e4), SHC(0x707d), SHC(0xc2ec), SHC(0x6eda), SHC(0xc000), SHC(0x6d23), SHC(0xbd1f), + SHC(0x6b5a), SHC(0xba49), SHC(0x697d), SHC(0xb780), SHC(0x678e), SHC(0xb4c3), SHC(0x658d), SHC(0xb214), + SHC(0x637a), SHC(0xaf72), SHC(0x6155), SHC(0xacdf), SHC(0x5f1f), SHC(0xaa5a), SHC(0x5cd9), SHC(0xa7e4), + SHC(0x7fff), SHC(0x0000), SHC(0x7fd3), SHC(0xf94d), SHC(0x7f4c), SHC(0xf29f), SHC(0x7e6d), SHC(0xebfa), + SHC(0x7d34), SHC(0xe563), SHC(0x7ba3), SHC(0xdedf), SHC(0x79bc), SHC(0xd872), SHC(0x7780), SHC(0xd221), + SHC(0x74ef), SHC(0xcbf0), SHC(0x720d), SHC(0xc5e4), SHC(0x6eda), SHC(0xc000), SHC(0x6b5a), SHC(0xba49), + SHC(0x678e), SHC(0xb4c3), SHC(0x637a), SHC(0xaf72), SHC(0x5f1f), SHC(0xaa5a), SHC(0x5a82), SHC(0xa57e), + SHC(0x55a6), SHC(0xa0e1), SHC(0x508e), SHC(0x9c86), SHC(0x4b3d), SHC(0x9872), SHC(0x45b7), SHC(0x94a6), + SHC(0x4000), SHC(0x9126), SHC(0x3a1c), SHC(0x8df3), SHC(0x3410), SHC(0x8b11), SHC(0x2ddf), SHC(0x8880), + SHC(0x278e), SHC(0x8644), SHC(0x2121), SHC(0x845d), SHC(0x1a9d), SHC(0x82cc), SHC(0x1406), SHC(0x8193), + SHC(0x0d61), SHC(0x80b4), SHC(0x06b3), SHC(0x802d), SHC(0x7fff), SHC(0x0000), SHC(0x7f9b), SHC(0xf5f5), + SHC(0x7e6d), SHC(0xebfa), SHC(0x7c77), SHC(0xe21e), SHC(0x79bc), SHC(0xd872), SHC(0x7642), SHC(0xcf04), + SHC(0x720d), SHC(0xc5e4), SHC(0x6d23), SHC(0xbd1f), SHC(0x678e), SHC(0xb4c3), SHC(0x6155), SHC(0xacdf), + SHC(0x5a82), SHC(0xa57e), SHC(0x5321), SHC(0x9eab), SHC(0x4b3d), SHC(0x9872), SHC(0x42e1), SHC(0x92dd), + SHC(0x3a1c), SHC(0x8df3), SHC(0x30fc), SHC(0x89be), SHC(0x278e), SHC(0x8644), SHC(0x1de2), SHC(0x8389), + SHC(0x1406), SHC(0x8193), SHC(0x0a0b), SHC(0x8065), SHC(0x0000), SHC(0x8000), SHC(0xf5f5), SHC(0x8065), + SHC(0xebfa), SHC(0x8193), SHC(0xe21e), SHC(0x8389), SHC(0xd872), SHC(0x8644), SHC(0xcf04), SHC(0x89be), + SHC(0xc5e4), SHC(0x8df3), SHC(0xbd1f), SHC(0x92dd), SHC(0xb4c3), SHC(0x9872), SHC(0xacdf), SHC(0x9eab), + SHC(0x7fff), SHC(0x0000), SHC(0x7f4c), SHC(0xf29f), SHC(0x7d34), SHC(0xe563), SHC(0x79bc), SHC(0xd872), + SHC(0x74ef), SHC(0xcbf0), SHC(0x6eda), SHC(0xc000), SHC(0x678e), SHC(0xb4c3), SHC(0x5f1f), SHC(0xaa5a), + SHC(0x55a6), SHC(0xa0e1), SHC(0x4b3d), SHC(0x9872), SHC(0x4000), SHC(0x9126), SHC(0x3410), SHC(0x8b11), + SHC(0x278e), SHC(0x8644), SHC(0x1a9d), SHC(0x82cc), SHC(0x0d61), SHC(0x80b4), SHC(0x0000), SHC(0x8000), + SHC(0xf29f), SHC(0x80b4), SHC(0xe563), SHC(0x82cc), SHC(0xd872), SHC(0x8644), SHC(0xcbf0), SHC(0x8b11), + SHC(0xc000), SHC(0x9126), SHC(0xb4c3), SHC(0x9872), SHC(0xaa5a), SHC(0xa0e1), SHC(0xa0e1), SHC(0xaa5a), + SHC(0x9872), SHC(0xb4c3), SHC(0x9126), SHC(0xc000), SHC(0x8b11), SHC(0xcbf0), SHC(0x8644), SHC(0xd872), + SHC(0x82cc), SHC(0xe563), SHC(0x80b4), SHC(0xf29f), SHC(0x7fff), SHC(0x0000), SHC(0x7ee8), SHC(0xef4b), + SHC(0x7ba3), SHC(0xdedf), SHC(0x7642), SHC(0xcf04), SHC(0x6eda), SHC(0xc000), SHC(0x658d), SHC(0xb214), + SHC(0x5a82), SHC(0xa57e), SHC(0x4dec), SHC(0x9a73), SHC(0x4000), SHC(0x9126), SHC(0x30fc), SHC(0x89be), + SHC(0x2121), SHC(0x845d), SHC(0x10b5), SHC(0x8118), SHC(0x0000), SHC(0x8000), SHC(0xef4b), SHC(0x8118), + SHC(0xdedf), SHC(0x845d), SHC(0xcf04), SHC(0x89be), SHC(0xc000), SHC(0x9126), SHC(0xb214), SHC(0x9a73), + SHC(0xa57e), SHC(0xa57e), SHC(0x9a73), SHC(0xb214), SHC(0x9126), SHC(0xc000), SHC(0x89be), SHC(0xcf04), + SHC(0x845d), SHC(0xdedf), SHC(0x8118), SHC(0xef4b), SHC(0x8000), SHC(0x0000), SHC(0x8118), SHC(0x10b5), + SHC(0x845d), SHC(0x2121), SHC(0x89be), SHC(0x30fc), SHC(0x9126), SHC(0x4000), SHC(0x9a73), SHC(0x4dec), + SHC(0x7fff), SHC(0x0000), SHC(0x7e6d), SHC(0xebfa), SHC(0x79bc), SHC(0xd872), SHC(0x720d), SHC(0xc5e4), + SHC(0x678e), SHC(0xb4c3), SHC(0x5a82), SHC(0xa57e), SHC(0x4b3d), SHC(0x9872), SHC(0x3a1c), SHC(0x8df3), + SHC(0x278e), SHC(0x8644), SHC(0x1406), SHC(0x8193), SHC(0x0000), SHC(0x8000), SHC(0xebfa), SHC(0x8193), + SHC(0xd872), SHC(0x8644), SHC(0xc5e4), SHC(0x8df3), SHC(0xb4c3), SHC(0x9872), SHC(0xa57e), SHC(0xa57e), + SHC(0x9872), SHC(0xb4c3), SHC(0x8df3), SHC(0xc5e4), SHC(0x8644), SHC(0xd872), SHC(0x8193), SHC(0xebfa), + SHC(0x8000), SHC(0x0000), SHC(0x8193), SHC(0x1406), SHC(0x8644), SHC(0x278e), SHC(0x8df3), SHC(0x3a1c), + SHC(0x9872), SHC(0x4b3d), SHC(0xa57e), SHC(0x5a82), SHC(0xb4c3), SHC(0x678e), SHC(0xc5e4), SHC(0x720d), + SHC(0xd872), SHC(0x79bc), SHC(0xebfa), SHC(0x7e6d), SHC(0x7fff), SHC(0x0000), SHC(0x7ddb), SHC(0xe8ad), + SHC(0x7780), SHC(0xd221), SHC(0x6d23), SHC(0xbd1f), SHC(0x5f1f), SHC(0xaa5a), SHC(0x4dec), SHC(0x9a73), + SHC(0x3a1c), SHC(0x8df3), SHC(0x245b), SHC(0x8545), SHC(0x0d61), SHC(0x80b4), SHC(0xf5f5), SHC(0x8065), + SHC(0xdedf), SHC(0x845d), SHC(0xc8e5), SHC(0x8c78), SHC(0xb4c3), SHC(0x9872), SHC(0xa327), SHC(0xa7e4), + SHC(0x94a6), SHC(0xba49), SHC(0x89be), SHC(0xcf04), SHC(0x82cc), SHC(0xe563), SHC(0x800b), SHC(0xfca6), + SHC(0x8193), SHC(0x1406), SHC(0x8758), SHC(0x2aba), SHC(0x9126), SHC(0x4000), SHC(0x9eab), SHC(0x5321), + SHC(0xaf72), SHC(0x637a), SHC(0xc2ec), SHC(0x707d), SHC(0xd872), SHC(0x79bc), SHC(0xef4b), SHC(0x7ee8), + SHC(0x06b3), SHC(0x7fd3), SHC(0x1de2), SHC(0x7c77), SHC(0x3410), SHC(0x74ef), SHC(0x4880), SHC(0x697d), + SHC(0x7fff), SHC(0x0000), SHC(0x7ffd), SHC(0xfe53), SHC(0x7ff5), SHC(0xfca6), SHC(0x7fe7), SHC(0xfafa), + SHC(0x7fd3), SHC(0xf94d), SHC(0x7fba), SHC(0xf7a1), SHC(0x7f9b), SHC(0xf5f5), SHC(0x7f77), SHC(0xf44a), + SHC(0x7f4c), SHC(0xf29f), SHC(0x7f1d), SHC(0xf0f5), SHC(0x7ee8), SHC(0xef4b), SHC(0x7ead), SHC(0xeda2), + SHC(0x7e6d), SHC(0xebfa), SHC(0x7e27), SHC(0xea53), SHC(0x7ddb), SHC(0xe8ad), SHC(0x7d8a), SHC(0xe707), + SHC(0x7d34), SHC(0xe563), SHC(0x7cd8), SHC(0xe3c0), SHC(0x7c77), SHC(0xe21e), SHC(0x7c10), SHC(0xe07e), + SHC(0x7ba3), SHC(0xdedf), SHC(0x7b32), SHC(0xdd41), SHC(0x7abb), SHC(0xdba5), SHC(0x7a3e), SHC(0xda0b), + SHC(0x79bc), SHC(0xd872), SHC(0x7935), SHC(0xd6db), SHC(0x78a8), SHC(0xd546), SHC(0x7817), SHC(0xd3b2), + SHC(0x7780), SHC(0xd221), SHC(0x76e3), SHC(0xd092), SHC(0x7fff), SHC(0x0000), SHC(0x7fe7), SHC(0xfafa), + SHC(0x7f9b), SHC(0xf5f5), SHC(0x7f1d), SHC(0xf0f5), SHC(0x7e6d), SHC(0xebfa), SHC(0x7d8a), SHC(0xe707), + SHC(0x7c77), SHC(0xe21e), SHC(0x7b32), SHC(0xdd41), SHC(0x79bc), SHC(0xd872), SHC(0x7817), SHC(0xd3b2), + SHC(0x7642), SHC(0xcf04), SHC(0x743e), SHC(0xca69), SHC(0x720d), SHC(0xc5e4), SHC(0x6fae), SHC(0xc175), + SHC(0x6d23), SHC(0xbd1f), SHC(0x6a6e), SHC(0xb8e3), SHC(0x678e), SHC(0xb4c3), SHC(0x6485), SHC(0xb0c2), + SHC(0x6155), SHC(0xacdf), SHC(0x5dfe), SHC(0xa91d), SHC(0x5a82), SHC(0xa57e), SHC(0x56e3), SHC(0xa202), + SHC(0x5321), SHC(0x9eab), SHC(0x4f3e), SHC(0x9b7b), SHC(0x4b3d), SHC(0x9872), SHC(0x471d), SHC(0x9592), + SHC(0x42e1), SHC(0x92dd), SHC(0x3e8b), SHC(0x9052), SHC(0x3a1c), SHC(0x8df3), SHC(0x3597), SHC(0x8bc2), + SHC(0x7fff), SHC(0x0000), SHC(0x7fba), SHC(0xf7a1), SHC(0x7ee8), SHC(0xef4b), SHC(0x7d8a), SHC(0xe707), + SHC(0x7ba3), SHC(0xdedf), SHC(0x7935), SHC(0xd6db), SHC(0x7642), SHC(0xcf04), SHC(0x72cd), SHC(0xc763), + SHC(0x6eda), SHC(0xc000), SHC(0x6a6e), SHC(0xb8e3), SHC(0x658d), SHC(0xb214), SHC(0x603c), SHC(0xab9b), + SHC(0x5a82), SHC(0xa57e), SHC(0x5465), SHC(0x9fc4), SHC(0x4dec), SHC(0x9a73), SHC(0x471d), SHC(0x9592), + SHC(0x4000), SHC(0x9126), SHC(0x389d), SHC(0x8d33), SHC(0x30fc), SHC(0x89be), SHC(0x2925), SHC(0x86cb), + SHC(0x2121), SHC(0x845d), SHC(0x18f9), SHC(0x8276), SHC(0x10b5), SHC(0x8118), SHC(0x085f), SHC(0x8046), + SHC(0x0000), SHC(0x8000), SHC(0xf7a1), SHC(0x8046), SHC(0xef4b), SHC(0x8118), SHC(0xe707), SHC(0x8276), + SHC(0xdedf), SHC(0x845d), SHC(0xd6db), SHC(0x86cb), SHC(0x7fff), SHC(0x0000), SHC(0x7f77), SHC(0xf44a), + SHC(0x7ddb), SHC(0xe8ad), SHC(0x7b32), SHC(0xdd41), SHC(0x7780), SHC(0xd221), SHC(0x72cd), SHC(0xc763), + SHC(0x6d23), SHC(0xbd1f), SHC(0x668f), SHC(0xb36a), SHC(0x5f1f), SHC(0xaa5a), SHC(0x56e3), SHC(0xa202), + SHC(0x4dec), SHC(0x9a73), SHC(0x444d), SHC(0x93bf), SHC(0x3a1c), SHC(0x8df3), SHC(0x2f6e), SHC(0x891d), + SHC(0x245b), SHC(0x8545), SHC(0x18f9), SHC(0x8276), SHC(0x0d61), SHC(0x80b4), SHC(0x01ad), SHC(0x8003), + SHC(0xf5f5), SHC(0x8065), SHC(0xea53), SHC(0x81d9), SHC(0xdedf), SHC(0x845d), SHC(0xd3b2), SHC(0x87e9), + SHC(0xc8e5), SHC(0x8c78), SHC(0xbe8e), SHC(0x91ff), SHC(0xb4c3), SHC(0x9872), SHC(0xab9b), SHC(0x9fc4), + SHC(0xa327), SHC(0xa7e4), SHC(0x9b7b), SHC(0xb0c2), SHC(0x94a6), SHC(0xba49), SHC(0x8eb9), SHC(0xc467), + SHC(0x7fff), SHC(0x0000), SHC(0x7f1d), SHC(0xf0f5), SHC(0x7c77), SHC(0xe21e), SHC(0x7817), SHC(0xd3b2), + SHC(0x720d), SHC(0xc5e4), SHC(0x6a6e), SHC(0xb8e3), SHC(0x6155), SHC(0xacdf), SHC(0x56e3), SHC(0xa202), + SHC(0x4b3d), SHC(0x9872), SHC(0x3e8b), SHC(0x9052), SHC(0x30fc), SHC(0x89be), SHC(0x22bf), SHC(0x84ce), + SHC(0x1406), SHC(0x8193), SHC(0x0506), SHC(0x8019), SHC(0xf5f5), SHC(0x8065), SHC(0xe707), SHC(0x8276), + SHC(0xd872), SHC(0x8644), SHC(0xca69), SHC(0x8bc2), SHC(0xbd1f), SHC(0x92dd), SHC(0xb0c2), SHC(0x9b7b), + SHC(0xa57e), SHC(0xa57e), SHC(0x9b7b), SHC(0xb0c2), SHC(0x92dd), SHC(0xbd1f), SHC(0x8bc2), SHC(0xca69), + SHC(0x8644), SHC(0xd872), SHC(0x8276), SHC(0xe707), SHC(0x8065), SHC(0xf5f5), SHC(0x8019), SHC(0x0506), + SHC(0x8193), SHC(0x1406), SHC(0x84ce), SHC(0x22bf), SHC(0x7fff), SHC(0x0000), SHC(0x7ead), SHC(0xeda2), + SHC(0x7abb), SHC(0xdba5), SHC(0x743e), SHC(0xca69), SHC(0x6b5a), SHC(0xba49), SHC(0x603c), SHC(0xab9b), + SHC(0x5321), SHC(0x9eab), SHC(0x444d), SHC(0x93bf), SHC(0x3410), SHC(0x8b11), SHC(0x22bf), SHC(0x84ce), + SHC(0x10b5), SHC(0x8118), SHC(0xfe53), SHC(0x8003), SHC(0xebfa), SHC(0x8193), SHC(0xda0b), SHC(0x85c2), + SHC(0xc8e5), SHC(0x8c78), SHC(0xb8e3), SHC(0x9592), SHC(0xaa5a), SHC(0xa0e1), SHC(0x9d97), SHC(0xae27), + SHC(0x92dd), SHC(0xbd1f), SHC(0x8a65), SHC(0xcd79), SHC(0x845d), SHC(0xdedf), SHC(0x80e3), SHC(0xf0f5), + SHC(0x800b), SHC(0x035a), SHC(0x81d9), SHC(0x15ad), SHC(0x8644), SHC(0x278e), SHC(0x8d33), SHC(0x389d), + SHC(0x9683), SHC(0x4880), SHC(0xa202), SHC(0x56e3), SHC(0xaf72), SHC(0x637a), SHC(0xbe8e), SHC(0x6e01), + SHC(0x7fff), SHC(0x0000), SHC(0x7e27), SHC(0xea53), SHC(0x78a8), SHC(0xd546), SHC(0x6fae), SHC(0xc175), + SHC(0x637a), SHC(0xaf72), SHC(0x5465), SHC(0x9fc4), SHC(0x42e1), SHC(0x92dd), SHC(0x2f6e), SHC(0x891d), + SHC(0x1a9d), SHC(0x82cc), SHC(0x0506), SHC(0x8019), SHC(0xef4b), SHC(0x8118), SHC(0xda0b), SHC(0x85c2), + SHC(0xc5e4), SHC(0x8df3), SHC(0xb36a), SHC(0x9971), SHC(0xa327), SHC(0xa7e4), SHC(0x9592), SHC(0xb8e3), + SHC(0x8b11), SHC(0xcbf0), SHC(0x83f0), SHC(0xe07e), SHC(0x8065), SHC(0xf5f5), SHC(0x8089), SHC(0x0bb6), + SHC(0x845d), SHC(0x2121), SHC(0x8bc2), SHC(0x3597), SHC(0x9683), SHC(0x4880), SHC(0xa450), SHC(0x5951), + SHC(0xb4c3), SHC(0x678e), SHC(0xc763), SHC(0x72cd), SHC(0xdba5), SHC(0x7abb), SHC(0xf0f5), SHC(0x7f1d), + SHC(0x06b3), SHC(0x7fd3), SHC(0x1c40), SHC(0x7cd8), SHC(0x7fff), SHC(0x0000), SHC(0x7d8a), SHC(0xe707), + SHC(0x7642), SHC(0xcf04), SHC(0x6a6e), SHC(0xb8e3), SHC(0x5a82), SHC(0xa57e), SHC(0x471d), SHC(0x9592), + SHC(0x30fc), SHC(0x89be), SHC(0x18f9), SHC(0x8276), SHC(0x0000), SHC(0x8000), SHC(0xe707), SHC(0x8276), + SHC(0xcf04), SHC(0x89be), SHC(0xb8e3), SHC(0x9592), SHC(0xa57e), SHC(0xa57e), SHC(0x9592), SHC(0xb8e3), + SHC(0x89be), SHC(0xcf04), SHC(0x8276), SHC(0xe707), SHC(0x8000), SHC(0x0000), SHC(0x8276), SHC(0x18f9), + SHC(0x89be), SHC(0x30fc), SHC(0x9592), SHC(0x471d), SHC(0xa57e), SHC(0x5a82), SHC(0xb8e3), SHC(0x6a6e), + SHC(0xcf04), SHC(0x7642), SHC(0xe707), SHC(0x7d8a), SHC(0x0000), SHC(0x7fff), SHC(0x18f9), SHC(0x7d8a), + SHC(0x30fc), SHC(0x7642), SHC(0x471d), SHC(0x6a6e), SHC(0x5a82), SHC(0x5a82), SHC(0x6a6e), SHC(0x471d) +}; + +const Word16 RotVector_600[2 * (600 - 30)] = +{ + SHC(0x7fff), SHC(0x0000), SHC(0x7ff9), SHC(0xfd52), + SHC(0x7fe3), SHC(0xfaa4), SHC(0x7fbf), SHC(0xf7f6), SHC(0x7f8d), SHC(0xf54a), SHC(0x7f4c), SHC(0xf29f), + SHC(0x7efe), SHC(0xeff5), SHC(0x7ea0), SHC(0xed4d), SHC(0x7e35), SHC(0xeaa7), SHC(0x7dbc), SHC(0xe804), + SHC(0x7d34), SHC(0xe563), SHC(0x7c9e), SHC(0xe2c5), SHC(0x7bfb), SHC(0xe02b), SHC(0x7b49), SHC(0xdd94), + SHC(0x7a89), SHC(0xdb01), SHC(0x79bc), SHC(0xd872), SHC(0x78e1), SHC(0xd5e8), SHC(0x77f9), SHC(0xd362), + SHC(0x7703), SHC(0xd0e1), SHC(0x7600), SHC(0xce66), SHC(0x74ef), SHC(0xcbf0), SHC(0x73d1), SHC(0xc980), + SHC(0x72a7), SHC(0xc716), SHC(0x716f), SHC(0xc4b3), SHC(0x702b), SHC(0xc256), SHC(0x6eda), SHC(0xc000), + SHC(0x6d7d), SHC(0xbdb1), SHC(0x6c13), SHC(0xbb6a), SHC(0x6a9d), SHC(0xb92a), SHC(0x691b), SHC(0xb6f3), + SHC(0x7fff), SHC(0x0000), SHC(0x7fe3), SHC(0xfaa4), SHC(0x7f8d), SHC(0xf54a), SHC(0x7efe), SHC(0xeff5), + SHC(0x7e35), SHC(0xeaa7), SHC(0x7d34), SHC(0xe563), SHC(0x7bfb), SHC(0xe02b), SHC(0x7a89), SHC(0xdb01), + SHC(0x78e1), SHC(0xd5e8), SHC(0x7703), SHC(0xd0e1), SHC(0x74ef), SHC(0xcbf0), SHC(0x72a7), SHC(0xc716), + SHC(0x702b), SHC(0xc256), SHC(0x6d7d), SHC(0xbdb1), SHC(0x6a9d), SHC(0xb92a), SHC(0x678e), SHC(0xb4c3), + SHC(0x6450), SHC(0xb07e), SHC(0x60e5), SHC(0xac5d), SHC(0x5d4f), SHC(0xa861), SHC(0x598f), SHC(0xa48c), + SHC(0x55a6), SHC(0xa0e1), SHC(0x5197), SHC(0x9d60), SHC(0x4d64), SHC(0x9a0b), SHC(0x490d), SHC(0x96e5), + SHC(0x4496), SHC(0x93ed), SHC(0x4000), SHC(0x9126), SHC(0x3b4d), SHC(0x8e91), SHC(0x3680), SHC(0x8c2f), + SHC(0x319a), SHC(0x8a00), SHC(0x2c9e), SHC(0x8807), SHC(0x7fff), SHC(0x0000), SHC(0x7fbf), SHC(0xf7f6), + SHC(0x7efe), SHC(0xeff5), SHC(0x7dbc), SHC(0xe804), SHC(0x7bfb), SHC(0xe02b), SHC(0x79bc), SHC(0xd872), + SHC(0x7703), SHC(0xd0e1), SHC(0x73d1), SHC(0xc980), SHC(0x702b), SHC(0xc256), SHC(0x6c13), SHC(0xbb6a), + SHC(0x678e), SHC(0xb4c3), SHC(0x62a0), SHC(0xae69), SHC(0x5d4f), SHC(0xa861), SHC(0x579f), SHC(0xa2b1), + SHC(0x5197), SHC(0x9d60), SHC(0x4b3d), SHC(0x9872), SHC(0x4496), SHC(0x93ed), SHC(0x3daa), SHC(0x8fd5), + SHC(0x3680), SHC(0x8c2f), SHC(0x2f1f), SHC(0x88fd), SHC(0x278e), SHC(0x8644), SHC(0x1fd5), SHC(0x8405), + SHC(0x17fc), SHC(0x8244), SHC(0x100b), SHC(0x8102), SHC(0x080a), SHC(0x8041), SHC(0x0000), SHC(0x8000), + SHC(0xf7f6), SHC(0x8041), SHC(0xeff5), SHC(0x8102), SHC(0xe804), SHC(0x8244), SHC(0xe02b), SHC(0x8405), + SHC(0x7fff), SHC(0x0000), SHC(0x7f8d), SHC(0xf54a), SHC(0x7e35), SHC(0xeaa7), SHC(0x7bfb), SHC(0xe02b), + SHC(0x78e1), SHC(0xd5e8), SHC(0x74ef), SHC(0xcbf0), SHC(0x702b), SHC(0xc256), SHC(0x6a9d), SHC(0xb92a), + SHC(0x6450), SHC(0xb07e), SHC(0x5d4f), SHC(0xa861), SHC(0x55a6), SHC(0xa0e1), SHC(0x4d64), SHC(0x9a0b), + SHC(0x4496), SHC(0x93ed), SHC(0x3b4d), SHC(0x8e91), SHC(0x319a), SHC(0x8a00), SHC(0x278e), SHC(0x8644), + SHC(0x1d3b), SHC(0x8362), SHC(0x12b3), SHC(0x8160), SHC(0x080a), SHC(0x8041), SHC(0xfd52), SHC(0x8007), + SHC(0xf29f), SHC(0x80b4), SHC(0xe804), SHC(0x8244), SHC(0xdd94), SHC(0x84b7), SHC(0xd362), SHC(0x8807), + SHC(0xc980), SHC(0x8c2f), SHC(0xc000), SHC(0x9126), SHC(0xb6f3), SHC(0x96e5), SHC(0xae69), SHC(0x9d60), + SHC(0xa671), SHC(0xa48c), SHC(0x9f1b), SHC(0xac5d), SHC(0x7fff), SHC(0x0000), SHC(0x7f4c), SHC(0xf29f), + SHC(0x7d34), SHC(0xe563), SHC(0x79bc), SHC(0xd872), SHC(0x74ef), SHC(0xcbf0), SHC(0x6eda), SHC(0xc000), + SHC(0x678e), SHC(0xb4c3), SHC(0x5f1f), SHC(0xaa5a), SHC(0x55a6), SHC(0xa0e1), SHC(0x4b3d), SHC(0x9872), + SHC(0x4000), SHC(0x9126), SHC(0x3410), SHC(0x8b11), SHC(0x278e), SHC(0x8644), SHC(0x1a9d), SHC(0x82cc), + SHC(0x0d61), SHC(0x80b4), SHC(0x0000), SHC(0x8000), SHC(0xf29f), SHC(0x80b4), SHC(0xe563), SHC(0x82cc), + SHC(0xd872), SHC(0x8644), SHC(0xcbf0), SHC(0x8b11), SHC(0xc000), SHC(0x9126), SHC(0xb4c3), SHC(0x9872), + SHC(0xaa5a), SHC(0xa0e1), SHC(0xa0e1), SHC(0xaa5a), SHC(0x9872), SHC(0xb4c3), SHC(0x9126), SHC(0xc000), + SHC(0x8b11), SHC(0xcbf0), SHC(0x8644), SHC(0xd872), SHC(0x82cc), SHC(0xe563), SHC(0x80b4), SHC(0xf29f), + SHC(0x7fff), SHC(0x0000), SHC(0x7efe), SHC(0xeff5), SHC(0x7bfb), SHC(0xe02b), SHC(0x7703), SHC(0xd0e1), + SHC(0x702b), SHC(0xc256), SHC(0x678e), SHC(0xb4c3), SHC(0x5d4f), SHC(0xa861), SHC(0x5197), SHC(0x9d60), + SHC(0x4496), SHC(0x93ed), SHC(0x3680), SHC(0x8c2f), SHC(0x278e), SHC(0x8644), SHC(0x17fc), SHC(0x8244), + SHC(0x080a), SHC(0x8041), SHC(0xf7f6), SHC(0x8041), SHC(0xe804), SHC(0x8244), SHC(0xd872), SHC(0x8644), + SHC(0xc980), SHC(0x8c2f), SHC(0xbb6a), SHC(0x93ed), SHC(0xae69), SHC(0x9d60), SHC(0xa2b1), SHC(0xa861), + SHC(0x9872), SHC(0xb4c3), SHC(0x8fd5), SHC(0xc256), SHC(0x88fd), SHC(0xd0e1), SHC(0x8405), SHC(0xe02b), + SHC(0x8102), SHC(0xeff5), SHC(0x8000), SHC(0x0000), SHC(0x8102), SHC(0x100b), SHC(0x8405), SHC(0x1fd5), + SHC(0x88fd), SHC(0x2f1f), SHC(0x8fd5), SHC(0x3daa), SHC(0x7fff), SHC(0x0000), SHC(0x7ea0), SHC(0xed4d), + SHC(0x7a89), SHC(0xdb01), SHC(0x73d1), SHC(0xc980), SHC(0x6a9d), SHC(0xb92a), SHC(0x5f1f), SHC(0xaa5a), + SHC(0x5197), SHC(0x9d60), SHC(0x424f), SHC(0x9283), SHC(0x319a), SHC(0x8a00), SHC(0x1fd5), SHC(0x8405), + SHC(0x0d61), SHC(0x80b4), SHC(0xfaa4), SHC(0x801d), SHC(0xe804), SHC(0x8244), SHC(0xd5e8), SHC(0x871f), + SHC(0xc4b3), SHC(0x8e91), SHC(0xb4c3), SHC(0x9872), SHC(0xa671), SHC(0xa48c), SHC(0x9a0b), SHC(0xb29c), + SHC(0x8fd5), SHC(0xc256), SHC(0x8807), SHC(0xd362), SHC(0x82cc), SHC(0xe563), SHC(0x8041), SHC(0xf7f6), + SHC(0x8073), SHC(0x0ab6), SHC(0x8362), SHC(0x1d3b), SHC(0x88fd), SHC(0x2f1f), SHC(0x9126), SHC(0x4000), + SHC(0x9bb0), SHC(0x4f82), SHC(0xa861), SHC(0x5d4f), SHC(0xb6f3), SHC(0x691b), SHC(0xc716), SHC(0x72a7), + SHC(0x7fff), SHC(0x0000), SHC(0x7e35), SHC(0xeaa7), SHC(0x78e1), SHC(0xd5e8), SHC(0x702b), SHC(0xc256), + SHC(0x6450), SHC(0xb07e), SHC(0x55a6), SHC(0xa0e1), SHC(0x4496), SHC(0x93ed), SHC(0x319a), SHC(0x8a00), + SHC(0x1d3b), SHC(0x8362), SHC(0x080a), SHC(0x8041), SHC(0xf29f), SHC(0x80b4), SHC(0xdd94), SHC(0x84b7), + SHC(0xc980), SHC(0x8c2f), SHC(0xb6f3), SHC(0x96e5), SHC(0xa671), SHC(0xa48c), SHC(0x9872), SHC(0xb4c3), + SHC(0x8d59), SHC(0xc716), SHC(0x8577), SHC(0xdb01), SHC(0x8102), SHC(0xeff5), SHC(0x801d), SHC(0x055c), + SHC(0x82cc), SHC(0x1a9d), SHC(0x88fd), SHC(0x2f1f), SHC(0x9283), SHC(0x424f), SHC(0x9f1b), SHC(0x53a3), + SHC(0xae69), SHC(0x62a0), SHC(0xc000), SHC(0x6eda), SHC(0xd362), SHC(0x77f9), SHC(0xe804), SHC(0x7dbc), + SHC(0xfd52), SHC(0x7ff9), SHC(0x12b3), SHC(0x7ea0), SHC(0x7fff), SHC(0x0000), SHC(0x7dbc), SHC(0xe804), + SHC(0x7703), SHC(0xd0e1), SHC(0x6c13), SHC(0xbb6a), SHC(0x5d4f), SHC(0xa861), SHC(0x4b3d), SHC(0x9872), + SHC(0x3680), SHC(0x8c2f), SHC(0x1fd5), SHC(0x8405), SHC(0x080a), SHC(0x8041), SHC(0xeff5), SHC(0x8102), + SHC(0xd872), SHC(0x8644), SHC(0xc256), SHC(0x8fd5), SHC(0xae69), SHC(0x9d60), SHC(0x9d60), SHC(0xae69), + SHC(0x8fd5), SHC(0xc256), SHC(0x8644), SHC(0xd872), SHC(0x8102), SHC(0xeff5), SHC(0x8041), SHC(0x080a), + SHC(0x8405), SHC(0x1fd5), SHC(0x8c2f), SHC(0x3680), SHC(0x9872), SHC(0x4b3d), SHC(0xa861), SHC(0x5d4f), + SHC(0xbb6a), SHC(0x6c13), SHC(0xd0e1), SHC(0x7703), SHC(0xe804), SHC(0x7dbc), SHC(0x0000), SHC(0x7fff), + SHC(0x17fc), SHC(0x7dbc), SHC(0x2f1f), SHC(0x7703), SHC(0x4496), SHC(0x6c13), SHC(0x579f), SHC(0x5d4f), + SHC(0x7fff), SHC(0x0000), SHC(0x7ffe), SHC(0xfea9), SHC(0x7ff9), SHC(0xfd52), SHC(0x7ff0), SHC(0xfbfb), + SHC(0x7fe3), SHC(0xfaa4), SHC(0x7fd3), SHC(0xf94d), SHC(0x7fbf), SHC(0xf7f6), SHC(0x7fa8), SHC(0xf6a0), + SHC(0x7f8d), SHC(0xf54a), SHC(0x7f6f), SHC(0xf3f4), SHC(0x7f4c), SHC(0xf29f), SHC(0x7f27), SHC(0xf14a), + SHC(0x7efe), SHC(0xeff5), SHC(0x7ed1), SHC(0xeea1), SHC(0x7ea0), SHC(0xed4d), SHC(0x7e6d), SHC(0xebfa), + SHC(0x7e35), SHC(0xeaa7), SHC(0x7dfa), SHC(0xe955), SHC(0x7dbc), SHC(0xe804), SHC(0x7d7a), SHC(0xe6b3), + SHC(0x7d34), SHC(0xe563), SHC(0x7ceb), SHC(0xe414), SHC(0x7c9e), SHC(0xe2c5), SHC(0x7c4e), SHC(0xe178), + SHC(0x7bfb), SHC(0xe02b), SHC(0x7ba3), SHC(0xdedf), SHC(0x7b49), SHC(0xdd94), SHC(0x7aeb), SHC(0xdc4a), + SHC(0x7a89), SHC(0xdb01), SHC(0x7a25), SHC(0xd9b9), SHC(0x7fff), SHC(0x0000), SHC(0x7ff0), SHC(0xfbfb), + SHC(0x7fbf), SHC(0xf7f6), SHC(0x7f6f), SHC(0xf3f4), SHC(0x7efe), SHC(0xeff5), SHC(0x7e6d), SHC(0xebfa), + SHC(0x7dbc), SHC(0xe804), SHC(0x7ceb), SHC(0xe414), SHC(0x7bfb), SHC(0xe02b), SHC(0x7aeb), SHC(0xdc4a), + SHC(0x79bc), SHC(0xd872), SHC(0x786f), SHC(0xd4a4), SHC(0x7703), SHC(0xd0e1), SHC(0x7579), SHC(0xcd2a), + SHC(0x73d1), SHC(0xc980), SHC(0x720d), SHC(0xc5e4), SHC(0x702b), SHC(0xc256), SHC(0x6e2d), SHC(0xbed8), + SHC(0x6c13), SHC(0xbb6a), SHC(0x69de), SHC(0xb80e), SHC(0x678e), SHC(0xb4c3), SHC(0x6524), SHC(0xb18c), + SHC(0x62a0), SHC(0xae69), SHC(0x6004), SHC(0xab5a), SHC(0x5d4f), SHC(0xa861), SHC(0x5a82), SHC(0xa57e), + SHC(0x579f), SHC(0xa2b1), SHC(0x54a6), SHC(0x9ffc), SHC(0x5197), SHC(0x9d60), SHC(0x4e74), SHC(0x9adc), + SHC(0x7fff), SHC(0x0000), SHC(0x7fd3), SHC(0xf94d), SHC(0x7f4c), SHC(0xf29f), SHC(0x7e6d), SHC(0xebfa), + SHC(0x7d34), SHC(0xe563), SHC(0x7ba3), SHC(0xdedf), SHC(0x79bc), SHC(0xd872), SHC(0x7780), SHC(0xd221), + SHC(0x74ef), SHC(0xcbf0), SHC(0x720d), SHC(0xc5e4), SHC(0x6eda), SHC(0xc000), SHC(0x6b5a), SHC(0xba49), + SHC(0x678e), SHC(0xb4c3), SHC(0x637a), SHC(0xaf72), SHC(0x5f1f), SHC(0xaa5a), SHC(0x5a82), SHC(0xa57e), + SHC(0x55a6), SHC(0xa0e1), SHC(0x508e), SHC(0x9c86), SHC(0x4b3d), SHC(0x9872), SHC(0x45b7), SHC(0x94a6), + SHC(0x4000), SHC(0x9126), SHC(0x3a1c), SHC(0x8df3), SHC(0x3410), SHC(0x8b11), SHC(0x2ddf), SHC(0x8880), + SHC(0x278e), SHC(0x8644), SHC(0x2121), SHC(0x845d), SHC(0x1a9d), SHC(0x82cc), SHC(0x1406), SHC(0x8193), + SHC(0x0d61), SHC(0x80b4), SHC(0x06b3), SHC(0x802d), SHC(0x7fff), SHC(0x0000), SHC(0x7fa8), SHC(0xf6a0), + SHC(0x7ea0), SHC(0xed4d), SHC(0x7ceb), SHC(0xe414), SHC(0x7a89), SHC(0xdb01), SHC(0x7780), SHC(0xd221), + SHC(0x73d1), SHC(0xc980), SHC(0x6f84), SHC(0xc12a), SHC(0x6a9d), SHC(0xb92a), SHC(0x6524), SHC(0xb18c), + SHC(0x5f1f), SHC(0xaa5a), SHC(0x5898), SHC(0xa39d), SHC(0x5197), SHC(0x9d60), SHC(0x4a26), SHC(0x97aa), + SHC(0x424f), SHC(0x9283), SHC(0x3a1c), SHC(0x8df3), SHC(0x319a), SHC(0x8a00), SHC(0x28d4), SHC(0x86b0), + SHC(0x1fd5), SHC(0x8405), SHC(0x16ab), SHC(0x8206), SHC(0x0d61), SHC(0x80b4), SHC(0x0405), SHC(0x8010), + SHC(0xfaa4), SHC(0x801d), SHC(0xf14a), SHC(0x80d9), SHC(0xe804), SHC(0x8244), SHC(0xdedf), SHC(0x845d), + SHC(0xd5e8), SHC(0x871f), SHC(0xcd2a), SHC(0x8a87), SHC(0xc4b3), SHC(0x8e91), SHC(0xbc8d), SHC(0x9337), + SHC(0x7fff), SHC(0x0000), SHC(0x7f6f), SHC(0xf3f4), SHC(0x7dbc), SHC(0xe804), SHC(0x7aeb), SHC(0xdc4a), + SHC(0x7703), SHC(0xd0e1), SHC(0x720d), SHC(0xc5e4), SHC(0x6c13), SHC(0xbb6a), SHC(0x6524), SHC(0xb18c), + SHC(0x5d4f), SHC(0xa861), SHC(0x54a6), SHC(0x9ffc), SHC(0x4b3d), SHC(0x9872), SHC(0x4128), SHC(0x91d3), + SHC(0x3680), SHC(0x8c2f), SHC(0x2b5c), SHC(0x8791), SHC(0x1fd5), SHC(0x8405), SHC(0x1406), SHC(0x8193), + SHC(0x080a), SHC(0x8041), SHC(0xfbfb), SHC(0x8010), SHC(0xeff5), SHC(0x8102), SHC(0xe414), SHC(0x8315), + SHC(0xd872), SHC(0x8644), SHC(0xcd2a), SHC(0x8a87), SHC(0xc256), SHC(0x8fd5), SHC(0xb80e), SHC(0x9622), + SHC(0xae69), SHC(0x9d60), SHC(0xa57e), SHC(0xa57e), SHC(0x9d60), SHC(0xae69), SHC(0x9622), SHC(0xb80e), + SHC(0x8fd5), SHC(0xc256), SHC(0x8a87), SHC(0xcd2a), SHC(0x7fff), SHC(0x0000), SHC(0x7f27), SHC(0xf14a), + SHC(0x7c9e), SHC(0xe2c5), SHC(0x786f), SHC(0xd4a4), SHC(0x72a7), SHC(0xc716), SHC(0x6b5a), SHC(0xba49), + SHC(0x62a0), SHC(0xae69), SHC(0x5898), SHC(0xa39d), SHC(0x4d64), SHC(0x9a0b), SHC(0x4128), SHC(0x91d3), + SHC(0x3410), SHC(0x8b11), SHC(0x2647), SHC(0x85db), SHC(0x17fc), SHC(0x8244), SHC(0x0960), SHC(0x8058), + SHC(0xfaa4), SHC(0x801d), SHC(0xebfa), SHC(0x8193), SHC(0xdd94), SHC(0x84b7), SHC(0xcfa3), SHC(0x897d), + SHC(0xc256), SHC(0x8fd5), SHC(0xb5da), SHC(0x97aa), SHC(0xaa5a), SHC(0xa0e1), SHC(0x9ffc), SHC(0xab5a), + SHC(0x96e5), SHC(0xb6f3), SHC(0x8f31), SHC(0xc383), SHC(0x88fd), SHC(0xd0e1), SHC(0x845d), SHC(0xdedf), + SHC(0x8160), SHC(0xed4d), SHC(0x8010), SHC(0xfbfb), SHC(0x8073), SHC(0x0ab6), SHC(0x8286), SHC(0x194d), + SHC(0x7fff), SHC(0x0000), SHC(0x7ed1), SHC(0xeea1), SHC(0x7b49), SHC(0xdd94), SHC(0x7579), SHC(0xcd2a), + SHC(0x6d7d), SHC(0xbdb1), SHC(0x637a), SHC(0xaf72), SHC(0x579f), SHC(0xa2b1), SHC(0x4a26), SHC(0x97aa), + SHC(0x3b4d), SHC(0x8e91), SHC(0x2b5c), SHC(0x8791), SHC(0x1a9d), SHC(0x82cc), SHC(0x0960), SHC(0x8058), + SHC(0xf7f6), SHC(0x8041), SHC(0xe6b3), SHC(0x8286), SHC(0xd5e8), SHC(0x871f), SHC(0xc5e4), SHC(0x8df3), + SHC(0xb6f3), SHC(0x96e5), SHC(0xa95c), SHC(0xa1c8), SHC(0x9d60), SHC(0xae69), SHC(0x9337), SHC(0xbc8d), + SHC(0x8b11), SHC(0xcbf0), SHC(0x8515), SHC(0xdc4a), SHC(0x8160), SHC(0xed4d), SHC(0x8002), SHC(0xfea9), + SHC(0x8102), SHC(0x100b), SHC(0x845d), SHC(0x2121), SHC(0x8a00), SHC(0x319a), SHC(0x91d3), SHC(0x4128), + SHC(0x9bb0), SHC(0x4f82), SHC(0xa768), SHC(0x5c63), SHC(0x7fff), SHC(0x0000), SHC(0x7e6d), SHC(0xebfa), + SHC(0x79bc), SHC(0xd872), SHC(0x720d), SHC(0xc5e4), SHC(0x678e), SHC(0xb4c3), SHC(0x5a82), SHC(0xa57e), + SHC(0x4b3d), SHC(0x9872), SHC(0x3a1c), SHC(0x8df3), SHC(0x278e), SHC(0x8644), SHC(0x1406), SHC(0x8193), + SHC(0x0000), SHC(0x8000), SHC(0xebfa), SHC(0x8193), SHC(0xd872), SHC(0x8644), SHC(0xc5e4), SHC(0x8df3), + SHC(0xb4c3), SHC(0x9872), SHC(0xa57e), SHC(0xa57e), SHC(0x9872), SHC(0xb4c3), SHC(0x8df3), SHC(0xc5e4), + SHC(0x8644), SHC(0xd872), SHC(0x8193), SHC(0xebfa), SHC(0x8000), SHC(0x0000), SHC(0x8193), SHC(0x1406), + SHC(0x8644), SHC(0x278e), SHC(0x8df3), SHC(0x3a1c), SHC(0x9872), SHC(0x4b3d), SHC(0xa57e), SHC(0x5a82), + SHC(0xb4c3), SHC(0x678e), SHC(0xc5e4), SHC(0x720d), SHC(0xd872), SHC(0x79bc), SHC(0xebfa), SHC(0x7e6d), + SHC(0x7fff), SHC(0x0000), SHC(0x7dfa), SHC(0xe955), SHC(0x77f9), SHC(0xd362), SHC(0x6e2d), SHC(0xbed8), + SHC(0x60e5), SHC(0xac5d), SHC(0x508e), SHC(0x9c86), SHC(0x3daa), SHC(0x8fd5), SHC(0x28d4), SHC(0x86b0), + SHC(0x12b3), SHC(0x8160), SHC(0xfbfb), SHC(0x8010), SHC(0xe563), SHC(0x82cc), SHC(0xcfa3), SHC(0x897d), + SHC(0xbb6a), SHC(0x93ed), SHC(0xa95c), SHC(0xa1c8), SHC(0x9a0b), SHC(0xb29c), SHC(0x8df3), SHC(0xc5e4), + SHC(0x8577), SHC(0xdb01), SHC(0x80d9), SHC(0xf14a), SHC(0x8041), SHC(0x080a), SHC(0x83b2), SHC(0x1e88), + SHC(0x8b11), SHC(0x3410), SHC(0x9622), SHC(0x47f2), SHC(0xa48c), SHC(0x598f), SHC(0xb5da), SHC(0x6856), + SHC(0xc980), SHC(0x73d1), SHC(0xdedf), SHC(0x7ba3), SHC(0xf54a), SHC(0x7f8d), SHC(0x0c0c), SHC(0x7f6f), + SHC(0x226c), SHC(0x7b49), SHC(0x37b6), SHC(0x733e), SHC(0x7fff), SHC(0x0000), SHC(0x7d7a), SHC(0xe6b3), + SHC(0x7600), SHC(0xce66), SHC(0x69de), SHC(0xb80e), SHC(0x598f), SHC(0xa48c), SHC(0x45b7), SHC(0x94a6), + SHC(0x2f1f), SHC(0x88fd), SHC(0x16ab), SHC(0x8206), SHC(0xfd52), SHC(0x8007), SHC(0xe414), SHC(0x8315), + SHC(0xcbf0), SHC(0x8b11), SHC(0xb5da), SHC(0x97aa), SHC(0xa2b1), SHC(0xa861), SHC(0x9337), SHC(0xbc8d), + SHC(0x8807), SHC(0xd362), SHC(0x8193), SHC(0xebfa), SHC(0x801d), SHC(0x055c), SHC(0x83b2), SHC(0x1e88), + SHC(0x8c2f), SHC(0x3680), SHC(0x993d), SHC(0x4c51), SHC(0xaa5a), SHC(0x5f1f), SHC(0xbed8), SHC(0x6e2d), + SHC(0xd5e8), SHC(0x78e1), SHC(0xeea1), SHC(0x7ed1), SHC(0x080a), SHC(0x7fbf), SHC(0x2121), SHC(0x7ba3), + SHC(0x38ea), SHC(0x72a7), SHC(0x4e74), SHC(0x6524), SHC(0x60e5), SHC(0x53a3), SHC(0x6f84), SHC(0x3ed6) +}; + + + +/** + * \brief Twiddle factors are unscaled + */ +const Word16 RotVector_256[2 * (256 - 32)] = +{ + SHC(0x7fff), SHC(0x0000), SHC(0x7ff6), SHC(0xfcdc), SHC(0x7fd9), SHC(0xf9b8), SHC(0x7fa7), SHC(0xf695), + SHC(0x7f62), SHC(0xf374), SHC(0x7f0a), SHC(0xf055), SHC(0x7e9d), SHC(0xed38), SHC(0x7e1e), SHC(0xea1e), + SHC(0x7d8a), SHC(0xe707), SHC(0x7ce4), SHC(0xe3f4), SHC(0x7c2a), SHC(0xe0e6), SHC(0x7b5d), SHC(0xdddc), + SHC(0x7a7d), SHC(0xdad8), SHC(0x798a), SHC(0xd7d9), SHC(0x7885), SHC(0xd4e1), SHC(0x776c), SHC(0xd1ef), + SHC(0x7642), SHC(0xcf04), SHC(0x7505), SHC(0xcc21), SHC(0x73b6), SHC(0xc946), SHC(0x7255), SHC(0xc673), + SHC(0x70e3), SHC(0xc3a9), SHC(0x6f5f), SHC(0xc0e9), SHC(0x6dca), SHC(0xbe32), SHC(0x6c24), SHC(0xbb85), + SHC(0x6a6e), SHC(0xb8e3), SHC(0x68a7), SHC(0xb64c), SHC(0x66d0), SHC(0xb3c0), SHC(0x64e9), SHC(0xb140), + SHC(0x62f2), SHC(0xaecc), SHC(0x60ec), SHC(0xac65), SHC(0x5ed7), SHC(0xaa0a), SHC(0x5cb4), SHC(0xa7bd), + SHC(0x7fff), SHC(0x0000), SHC(0x7fd9), SHC(0xf9b8), SHC(0x7f62), SHC(0xf374), SHC(0x7e9d), SHC(0xed38), + SHC(0x7d8a), SHC(0xe707), SHC(0x7c2a), SHC(0xe0e6), SHC(0x7a7d), SHC(0xdad8), SHC(0x7885), SHC(0xd4e1), + SHC(0x7642), SHC(0xcf04), SHC(0x73b6), SHC(0xc946), SHC(0x70e3), SHC(0xc3a9), SHC(0x6dca), SHC(0xbe32), + SHC(0x6a6e), SHC(0xb8e3), SHC(0x66d0), SHC(0xb3c0), SHC(0x62f2), SHC(0xaecc), SHC(0x5ed7), SHC(0xaa0a), + SHC(0x5a82), SHC(0xa57e), SHC(0x55f6), SHC(0xa129), SHC(0x5134), SHC(0x9d0e), SHC(0x4c40), SHC(0x9930), + SHC(0x471d), SHC(0x9592), SHC(0x41ce), SHC(0x9236), SHC(0x3c57), SHC(0x8f1d), SHC(0x36ba), SHC(0x8c4a), + SHC(0x30fc), SHC(0x89be), SHC(0x2b1f), SHC(0x877b), SHC(0x2528), SHC(0x8583), SHC(0x1f1a), SHC(0x83d6), + SHC(0x18f9), SHC(0x8276), SHC(0x12c8), SHC(0x8163), SHC(0x0c8c), SHC(0x809e), SHC(0x0648), SHC(0x8027), + SHC(0x7fff), SHC(0x0000), SHC(0x7fa7), SHC(0xf695), SHC(0x7e9d), SHC(0xed38), SHC(0x7ce4), SHC(0xe3f4), + SHC(0x7a7d), SHC(0xdad8), SHC(0x776c), SHC(0xd1ef), SHC(0x73b6), SHC(0xc946), SHC(0x6f5f), SHC(0xc0e9), + SHC(0x6a6e), SHC(0xb8e3), SHC(0x64e9), SHC(0xb140), SHC(0x5ed7), SHC(0xaa0a), SHC(0x5843), SHC(0xa34c), + SHC(0x5134), SHC(0x9d0e), SHC(0x49b4), SHC(0x9759), SHC(0x41ce), SHC(0x9236), SHC(0x398d), SHC(0x8dab), + SHC(0x30fc), SHC(0x89be), SHC(0x2827), SHC(0x8676), SHC(0x1f1a), SHC(0x83d6), SHC(0x15e2), SHC(0x81e2), + SHC(0x0c8c), SHC(0x809e), SHC(0x0324), SHC(0x800a), SHC(0xf9b8), SHC(0x8027), SHC(0xf055), SHC(0x80f6), + SHC(0xe707), SHC(0x8276), SHC(0xdddc), SHC(0x84a3), SHC(0xd4e1), SHC(0x877b), SHC(0xcc21), SHC(0x8afb), + SHC(0xc3a9), SHC(0x8f1d), SHC(0xbb85), SHC(0x93dc), SHC(0xb3c0), SHC(0x9930), SHC(0xac65), SHC(0x9f14), + SHC(0x7fff), SHC(0x0000), SHC(0x7f62), SHC(0xf374), SHC(0x7d8a), SHC(0xe707), SHC(0x7a7d), SHC(0xdad8), + SHC(0x7642), SHC(0xcf04), SHC(0x70e3), SHC(0xc3a9), SHC(0x6a6e), SHC(0xb8e3), SHC(0x62f2), SHC(0xaecc), + SHC(0x5a82), SHC(0xa57e), SHC(0x5134), SHC(0x9d0e), SHC(0x471d), SHC(0x9592), SHC(0x3c57), SHC(0x8f1d), + SHC(0x30fc), SHC(0x89be), SHC(0x2528), SHC(0x8583), SHC(0x18f9), SHC(0x8276), SHC(0x0c8c), SHC(0x809e), + SHC(0x0000), SHC(0x8000), SHC(0xf374), SHC(0x809e), SHC(0xe707), SHC(0x8276), SHC(0xdad8), SHC(0x8583), + SHC(0xcf04), SHC(0x89be), SHC(0xc3a9), SHC(0x8f1d), SHC(0xb8e3), SHC(0x9592), SHC(0xaecc), SHC(0x9d0e), + SHC(0xa57e), SHC(0xa57e), SHC(0x9d0e), SHC(0xaecc), SHC(0x9592), SHC(0xb8e3), SHC(0x8f1d), SHC(0xc3a9), + SHC(0x89be), SHC(0xcf04), SHC(0x8583), SHC(0xdad8), SHC(0x8276), SHC(0xe707), SHC(0x809e), SHC(0xf374), + SHC(0x7fff), SHC(0x0000), SHC(0x7f0a), SHC(0xf055), SHC(0x7c2a), SHC(0xe0e6), SHC(0x776c), SHC(0xd1ef), + SHC(0x70e3), SHC(0xc3a9), SHC(0x68a7), SHC(0xb64c), SHC(0x5ed7), SHC(0xaa0a), SHC(0x539b), SHC(0x9f14), + SHC(0x471d), SHC(0x9592), SHC(0x398d), SHC(0x8dab), SHC(0x2b1f), SHC(0x877b), SHC(0x1c0c), SHC(0x831c), + SHC(0x0c8c), SHC(0x809e), SHC(0xfcdc), SHC(0x800a), SHC(0xed38), SHC(0x8163), SHC(0xdddc), SHC(0x84a3), + SHC(0xcf04), SHC(0x89be), SHC(0xc0e9), SHC(0x90a1), SHC(0xb3c0), SHC(0x9930), SHC(0xa7bd), SHC(0xa34c), + SHC(0x9d0e), SHC(0xaecc), SHC(0x93dc), SHC(0xbb85), SHC(0x8c4a), SHC(0xc946), SHC(0x8676), SHC(0xd7d9), + SHC(0x8276), SHC(0xe707), SHC(0x8059), SHC(0xf695), SHC(0x8027), SHC(0x0648), SHC(0x81e2), SHC(0x15e2), + SHC(0x8583), SHC(0x2528), SHC(0x8afb), SHC(0x33df), SHC(0x9236), SHC(0x41ce), SHC(0x9b17), SHC(0x4ec0), + SHC(0x7fff), SHC(0x0000), SHC(0x7e9d), SHC(0xed38), SHC(0x7a7d), SHC(0xdad8), SHC(0x73b6), SHC(0xc946), + SHC(0x6a6e), SHC(0xb8e3), SHC(0x5ed7), SHC(0xaa0a), SHC(0x5134), SHC(0x9d0e), SHC(0x41ce), SHC(0x9236), + SHC(0x30fc), SHC(0x89be), SHC(0x1f1a), SHC(0x83d6), SHC(0x0c8c), SHC(0x809e), SHC(0xf9b8), SHC(0x8027), + SHC(0xe707), SHC(0x8276), SHC(0xd4e1), SHC(0x877b), SHC(0xc3a9), SHC(0x8f1d), SHC(0xb3c0), SHC(0x9930), + SHC(0xa57e), SHC(0xa57e), SHC(0x9930), SHC(0xb3c0), SHC(0x8f1d), SHC(0xc3a9), SHC(0x877b), SHC(0xd4e1), + SHC(0x8276), SHC(0xe707), SHC(0x8027), SHC(0xf9b8), SHC(0x809e), SHC(0x0c8c), SHC(0x83d6), SHC(0x1f1a), + SHC(0x89be), SHC(0x30fc), SHC(0x9236), SHC(0x41ce), SHC(0x9d0e), SHC(0x5134), SHC(0xaa0a), SHC(0x5ed7), + SHC(0xb8e3), SHC(0x6a6e), SHC(0xc946), SHC(0x73b6), SHC(0xdad8), SHC(0x7a7d), SHC(0xed38), SHC(0x7e9d), + SHC(0x7fff), SHC(0x0000), SHC(0x7e1e), SHC(0xea1e), SHC(0x7885), SHC(0xd4e1), SHC(0x6f5f), SHC(0xc0e9), + SHC(0x62f2), SHC(0xaecc), SHC(0x539b), SHC(0x9f14), SHC(0x41ce), SHC(0x9236), SHC(0x2e11), SHC(0x8894), + SHC(0x18f9), SHC(0x8276), SHC(0x0324), SHC(0x800a), SHC(0xed38), SHC(0x8163), SHC(0xd7d9), SHC(0x8676), + SHC(0xc3a9), SHC(0x8f1d), SHC(0xb140), SHC(0x9b17), SHC(0xa129), SHC(0xaa0a), SHC(0x93dc), SHC(0xbb85), + SHC(0x89be), SHC(0xcf04), SHC(0x831c), SHC(0xe3f4), SHC(0x8027), SHC(0xf9b8), SHC(0x80f6), SHC(0x0fab), + SHC(0x8583), SHC(0x2528), SHC(0x8dab), SHC(0x398d), SHC(0x9930), SHC(0x4c40), SHC(0xa7bd), SHC(0x5cb4), + SHC(0xb8e3), SHC(0x6a6e), SHC(0xcc21), SHC(0x7505), SHC(0xe0e6), SHC(0x7c2a), SHC(0xf695), SHC(0x7fa7), + SHC(0x0c8c), SHC(0x7f62), SHC(0x2224), SHC(0x7b5d), SHC(0x36ba), SHC(0x73b6), SHC(0x49b4), SHC(0x68a7) +}; + +/** + * \brief Twiddle factors are unscaled + */ +const Word16 RotVector_320[2 * (320 - 20)] = +{ + SHC(0x7fff), SHC(0x0000), SHC(0x7fe7), SHC(0xfafa), SHC(0x7f9b), SHC(0xf5f5), SHC(0x7f1d), SHC(0xf0f5), + SHC(0x7e6d), SHC(0xebfa), SHC(0x7d8a), SHC(0xe707), SHC(0x7c77), SHC(0xe21e), SHC(0x7b32), SHC(0xdd41), + SHC(0x79bc), SHC(0xd872), SHC(0x7817), SHC(0xd3b2), SHC(0x7642), SHC(0xcf04), SHC(0x743e), SHC(0xca69), + SHC(0x720d), SHC(0xc5e4), SHC(0x6fae), SHC(0xc175), SHC(0x6d23), SHC(0xbd1f), SHC(0x6a6e), SHC(0xb8e3), + SHC(0x678e), SHC(0xb4c3), SHC(0x6485), SHC(0xb0c2), SHC(0x6155), SHC(0xacdf), SHC(0x5dfe), SHC(0xa91d), + SHC(0x7fff), SHC(0x0000), SHC(0x7f9b), SHC(0xf5f5), SHC(0x7e6d), SHC(0xebfa), SHC(0x7c77), SHC(0xe21e), + SHC(0x79bc), SHC(0xd872), SHC(0x7642), SHC(0xcf04), SHC(0x720d), SHC(0xc5e4), SHC(0x6d23), SHC(0xbd1f), + SHC(0x678e), SHC(0xb4c3), SHC(0x6155), SHC(0xacdf), SHC(0x5a82), SHC(0xa57e), SHC(0x5321), SHC(0x9eab), + SHC(0x4b3d), SHC(0x9872), SHC(0x42e1), SHC(0x92dd), SHC(0x3a1c), SHC(0x8df3), SHC(0x30fc), SHC(0x89be), + SHC(0x278e), SHC(0x8644), SHC(0x1de2), SHC(0x8389), SHC(0x1406), SHC(0x8193), SHC(0x0a0b), SHC(0x8065), + SHC(0x7fff), SHC(0x0000), SHC(0x7f1d), SHC(0xf0f5), SHC(0x7c77), SHC(0xe21e), SHC(0x7817), SHC(0xd3b2), + SHC(0x720d), SHC(0xc5e4), SHC(0x6a6e), SHC(0xb8e3), SHC(0x6155), SHC(0xacdf), SHC(0x56e3), SHC(0xa202), + SHC(0x4b3d), SHC(0x9872), SHC(0x3e8b), SHC(0x9052), SHC(0x30fc), SHC(0x89be), SHC(0x22bf), SHC(0x84ce), + SHC(0x1406), SHC(0x8193), SHC(0x0506), SHC(0x8019), SHC(0xf5f5), SHC(0x8065), SHC(0xe707), SHC(0x8276), + SHC(0xd872), SHC(0x8644), SHC(0xca69), SHC(0x8bc2), SHC(0xbd1f), SHC(0x92dd), SHC(0xb0c2), SHC(0x9b7b), + SHC(0x7fff), SHC(0x0000), SHC(0x7e6d), SHC(0xebfa), SHC(0x79bc), SHC(0xd872), SHC(0x720d), SHC(0xc5e4), + SHC(0x678e), SHC(0xb4c3), SHC(0x5a82), SHC(0xa57e), SHC(0x4b3d), SHC(0x9872), SHC(0x3a1c), SHC(0x8df3), + SHC(0x278e), SHC(0x8644), SHC(0x1406), SHC(0x8193), SHC(0x0000), SHC(0x8000), SHC(0xebfa), SHC(0x8193), + SHC(0xd872), SHC(0x8644), SHC(0xc5e4), SHC(0x8df3), SHC(0xb4c3), SHC(0x9872), SHC(0xa57e), SHC(0xa57e), + SHC(0x9872), SHC(0xb4c3), SHC(0x8df3), SHC(0xc5e4), SHC(0x8644), SHC(0xd872), SHC(0x8193), SHC(0xebfa), + SHC(0x7fff), SHC(0x0000), SHC(0x7d8a), SHC(0xe707), SHC(0x7642), SHC(0xcf04), SHC(0x6a6e), SHC(0xb8e3), + SHC(0x5a82), SHC(0xa57e), SHC(0x471d), SHC(0x9592), SHC(0x30fc), SHC(0x89be), SHC(0x18f9), SHC(0x8276), + SHC(0x0000), SHC(0x8000), SHC(0xe707), SHC(0x8276), SHC(0xcf04), SHC(0x89be), SHC(0xb8e3), SHC(0x9592), + SHC(0xa57e), SHC(0xa57e), SHC(0x9592), SHC(0xb8e3), SHC(0x89be), SHC(0xcf04), SHC(0x8276), SHC(0xe707), + SHC(0x8000), SHC(0x0000), SHC(0x8276), SHC(0x18f9), SHC(0x89be), SHC(0x30fc), SHC(0x9592), SHC(0x471d), + SHC(0x7fff), SHC(0x0000), SHC(0x7c77), SHC(0xe21e), SHC(0x720d), SHC(0xc5e4), SHC(0x6155), SHC(0xacdf), + SHC(0x4b3d), SHC(0x9872), SHC(0x30fc), SHC(0x89be), SHC(0x1406), SHC(0x8193), SHC(0xf5f5), SHC(0x8065), + SHC(0xd872), SHC(0x8644), SHC(0xbd1f), SHC(0x92dd), SHC(0xa57e), SHC(0xa57e), SHC(0x92dd), SHC(0xbd1f), + SHC(0x8644), SHC(0xd872), SHC(0x8065), SHC(0xf5f5), SHC(0x8193), SHC(0x1406), SHC(0x89be), SHC(0x30fc), + SHC(0x9872), SHC(0x4b3d), SHC(0xacdf), SHC(0x6155), SHC(0xc5e4), SHC(0x720d), SHC(0xe21e), SHC(0x7c77), + SHC(0x7fff), SHC(0x0000), SHC(0x7b32), SHC(0xdd41), SHC(0x6d23), SHC(0xbd1f), SHC(0x56e3), SHC(0xa202), + SHC(0x3a1c), SHC(0x8df3), SHC(0x18f9), SHC(0x8276), SHC(0xf5f5), SHC(0x8065), SHC(0xd3b2), SHC(0x87e9), + SHC(0xb4c3), SHC(0x9872), SHC(0x9b7b), SHC(0xb0c2), SHC(0x89be), SHC(0xcf04), SHC(0x80e3), SHC(0xf0f5), + SHC(0x8193), SHC(0x1406), SHC(0x8bc2), SHC(0x3597), SHC(0x9eab), SHC(0x5321), SHC(0xb8e3), SHC(0x6a6e), + SHC(0xd872), SHC(0x79bc), SHC(0xfafa), SHC(0x7fe7), SHC(0x1de2), SHC(0x7c77), SHC(0x3e8b), SHC(0x6fae), + SHC(0x7fff), SHC(0x0000), SHC(0x7ffa), SHC(0xfd7d), SHC(0x7fe7), SHC(0xfafa), SHC(0x7fc7), SHC(0xf877), + SHC(0x7f9b), SHC(0xf5f5), SHC(0x7f62), SHC(0xf374), SHC(0x7f1d), SHC(0xf0f5), SHC(0x7ecb), SHC(0xee76), + SHC(0x7e6d), SHC(0xebfa), SHC(0x7e02), SHC(0xe980), SHC(0x7d8a), SHC(0xe707), SHC(0x7d07), SHC(0xe492), + SHC(0x7c77), SHC(0xe21e), SHC(0x7bda), SHC(0xdfae), SHC(0x7b32), SHC(0xdd41), SHC(0x7a7d), SHC(0xdad8), + SHC(0x79bc), SHC(0xd872), SHC(0x78ef), SHC(0xd610), SHC(0x7817), SHC(0xd3b2), SHC(0x7732), SHC(0xd159), + SHC(0x7fff), SHC(0x0000), SHC(0x7fc7), SHC(0xf877), SHC(0x7f1d), SHC(0xf0f5), SHC(0x7e02), SHC(0xe980), + SHC(0x7c77), SHC(0xe21e), SHC(0x7a7d), SHC(0xdad8), SHC(0x7817), SHC(0xd3b2), SHC(0x7546), SHC(0xccb4), + SHC(0x720d), SHC(0xc5e4), SHC(0x6e6e), SHC(0xbf47), SHC(0x6a6e), SHC(0xb8e3), SHC(0x660f), SHC(0xb2bf), + SHC(0x6155), SHC(0xacdf), SHC(0x5c45), SHC(0xa749), SHC(0x56e3), SHC(0xa202), SHC(0x5134), SHC(0x9d0e), + SHC(0x4b3d), SHC(0x9872), SHC(0x4502), SHC(0x9432), SHC(0x3e8b), SHC(0x9052), SHC(0x37dc), SHC(0x8cd5), + SHC(0x7fff), SHC(0x0000), SHC(0x7f62), SHC(0xf374), SHC(0x7d8a), SHC(0xe707), SHC(0x7a7d), SHC(0xdad8), + SHC(0x7642), SHC(0xcf04), SHC(0x70e3), SHC(0xc3a9), SHC(0x6a6e), SHC(0xb8e3), SHC(0x62f2), SHC(0xaecc), + SHC(0x5a82), SHC(0xa57e), SHC(0x5134), SHC(0x9d0e), SHC(0x471d), SHC(0x9592), SHC(0x3c57), SHC(0x8f1d), + SHC(0x30fc), SHC(0x89be), SHC(0x2528), SHC(0x8583), SHC(0x18f9), SHC(0x8276), SHC(0x0c8c), SHC(0x809e), + SHC(0x0000), SHC(0x8000), SHC(0xf374), SHC(0x809e), SHC(0xe707), SHC(0x8276), SHC(0xdad8), SHC(0x8583), + SHC(0x7fff), SHC(0x0000), SHC(0x7ecb), SHC(0xee76), SHC(0x7b32), SHC(0xdd41), SHC(0x7546), SHC(0xccb4), + SHC(0x6d23), SHC(0xbd1f), SHC(0x62f2), SHC(0xaecc), SHC(0x56e3), SHC(0xa202), SHC(0x4930), SHC(0x96fd), + SHC(0x3a1c), SHC(0x8df3), SHC(0x29f0), SHC(0x8711), SHC(0x18f9), SHC(0x8276), SHC(0x0789), SHC(0x8039), + SHC(0xf5f5), SHC(0x8065), SHC(0xe492), SHC(0x82f9), SHC(0xd3b2), SHC(0x87e9), SHC(0xc3a9), SHC(0x8f1d), + SHC(0xb4c3), SHC(0x9872), SHC(0xa749), SHC(0xa3bb), SHC(0x9b7b), SHC(0xb0c2), SHC(0x9192), SHC(0xbf47), + SHC(0x7fff), SHC(0x0000), SHC(0x7e02), SHC(0xe980), SHC(0x7817), SHC(0xd3b2), SHC(0x6e6e), SHC(0xbf47), + SHC(0x6155), SHC(0xacdf), SHC(0x5134), SHC(0x9d0e), SHC(0x3e8b), SHC(0x9052), SHC(0x29f0), SHC(0x8711), + SHC(0x1406), SHC(0x8193), SHC(0xfd7d), SHC(0x8006), SHC(0xe707), SHC(0x8276), SHC(0xd159), SHC(0x88ce), + SHC(0xbd1f), SHC(0x92dd), SHC(0xaafa), SHC(0xa052), SHC(0x9b7b), SHC(0xb0c2), SHC(0x8f1d), SHC(0xc3a9), + SHC(0x8644), SHC(0xd872), SHC(0x8135), SHC(0xee76), SHC(0x8019), SHC(0x0506), SHC(0x82f9), SHC(0x1b6e), + SHC(0x7fff), SHC(0x0000), SHC(0x7d07), SHC(0xe492), SHC(0x743e), SHC(0xca69), SHC(0x660f), SHC(0xb2bf), + SHC(0x5321), SHC(0x9eab), SHC(0x3c57), SHC(0x8f1d), SHC(0x22bf), SHC(0x84ce), SHC(0x0789), SHC(0x8039), + SHC(0xebfa), SHC(0x8193), SHC(0xd159), SHC(0x88ce), SHC(0xb8e3), SHC(0x9592), SHC(0xa3bb), SHC(0xa749), + SHC(0x92dd), SHC(0xbd1f), SHC(0x8711), SHC(0xd610), SHC(0x80e3), SHC(0xf0f5), SHC(0x809e), SHC(0x0c8c), + SHC(0x8644), SHC(0x278e), SHC(0x9192), SHC(0x40b9), SHC(0xa202), SHC(0x56e3), SHC(0xb6d0), SHC(0x6903), + SHC(0x7fff), SHC(0x0000), SHC(0x7bda), SHC(0xdfae), SHC(0x6fae), SHC(0xc175), SHC(0x5c45), SHC(0xa749), + SHC(0x42e1), SHC(0x92dd), SHC(0x2528), SHC(0x8583), SHC(0x0506), SHC(0x8019), SHC(0xe492), SHC(0x82f9), + SHC(0xc5e4), SHC(0x8df3), SHC(0xaafa), SHC(0xa052), SHC(0x9592), SHC(0xb8e3), SHC(0x8711), SHC(0xd610), + SHC(0x8065), SHC(0xf5f5), SHC(0x81fe), SHC(0x1680), SHC(0x8bc2), SHC(0x3597), SHC(0x9d0e), SHC(0x5134), + SHC(0xb4c3), SHC(0x678e), SHC(0xd159), SHC(0x7732), SHC(0xf0f5), SHC(0x7f1d), SHC(0x118a), SHC(0x7ecb), + SHC(0x7fff), SHC(0x0000), SHC(0x7a7d), SHC(0xdad8), SHC(0x6a6e), SHC(0xb8e3), SHC(0x5134), SHC(0x9d0e), + SHC(0x30fc), SHC(0x89be), SHC(0x0c8c), SHC(0x809e), SHC(0xe707), SHC(0x8276), SHC(0xc3a9), SHC(0x8f1d), + SHC(0xa57e), SHC(0xa57e), SHC(0x8f1d), SHC(0xc3a9), SHC(0x8276), SHC(0xe707), SHC(0x809e), SHC(0x0c8c), + SHC(0x89be), SHC(0x30fc), SHC(0x9d0e), SHC(0x5134), SHC(0xb8e3), SHC(0x6a6e), SHC(0xdad8), SHC(0x7a7d), + SHC(0x0000), SHC(0x7fff), SHC(0x2528), SHC(0x7a7d), SHC(0x471d), SHC(0x6a6e), SHC(0x62f2), SHC(0x5134) +}; + + +/** + * \brief Twiddle factors are unscaled + * Rotation factor table, real and imaginary part interleaved, for dim1=20,dim2=20 + */ + +const Word16 RotVector_400[2 * (400 - 20)] = +{ + SHC(0x7fff), SHC(0x0000), SHC(0x7ff0), SHC(0xfbfb), SHC(0x7fbf), SHC(0xf7f6), SHC(0x7f6f), SHC(0xf3f4), + SHC(0x7efe), SHC(0xeff5), SHC(0x7e6d), SHC(0xebfa), SHC(0x7dbc), SHC(0xe804), SHC(0x7ceb), SHC(0xe414), + SHC(0x7bfb), SHC(0xe02b), SHC(0x7aeb), SHC(0xdc4a), SHC(0x79bc), SHC(0xd872), SHC(0x786f), SHC(0xd4a4), + SHC(0x7703), SHC(0xd0e1), SHC(0x7579), SHC(0xcd2a), SHC(0x73d1), SHC(0xc980), SHC(0x720d), SHC(0xc5e4), + SHC(0x702b), SHC(0xc256), SHC(0x6e2d), SHC(0xbed8), SHC(0x6c13), SHC(0xbb6a), SHC(0x69de), SHC(0xb80e), + SHC(0x7fff), SHC(0x0000), SHC(0x7fbf), SHC(0xf7f6), SHC(0x7efe), SHC(0xeff5), SHC(0x7dbc), SHC(0xe804), + SHC(0x7bfb), SHC(0xe02b), SHC(0x79bc), SHC(0xd872), SHC(0x7703), SHC(0xd0e1), SHC(0x73d1), SHC(0xc980), + SHC(0x702b), SHC(0xc256), SHC(0x6c13), SHC(0xbb6a), SHC(0x678e), SHC(0xb4c3), SHC(0x62a0), SHC(0xae69), + SHC(0x5d4f), SHC(0xa861), SHC(0x579f), SHC(0xa2b1), SHC(0x5197), SHC(0x9d60), SHC(0x4b3d), SHC(0x9872), + SHC(0x4496), SHC(0x93ed), SHC(0x3daa), SHC(0x8fd5), SHC(0x3680), SHC(0x8c2f), SHC(0x2f1f), SHC(0x88fd), + SHC(0x7fff), SHC(0x0000), SHC(0x7f6f), SHC(0xf3f4), SHC(0x7dbc), SHC(0xe804), SHC(0x7aeb), SHC(0xdc4a), + SHC(0x7703), SHC(0xd0e1), SHC(0x720d), SHC(0xc5e4), SHC(0x6c13), SHC(0xbb6a), SHC(0x6524), SHC(0xb18c), + SHC(0x5d4f), SHC(0xa861), SHC(0x54a6), SHC(0x9ffc), SHC(0x4b3d), SHC(0x9872), SHC(0x4128), SHC(0x91d3), + SHC(0x3680), SHC(0x8c2f), SHC(0x2b5c), SHC(0x8791), SHC(0x1fd5), SHC(0x8405), SHC(0x1406), SHC(0x8193), + SHC(0x080a), SHC(0x8041), SHC(0xfbfb), SHC(0x8010), SHC(0xeff5), SHC(0x8102), SHC(0xe414), SHC(0x8315), + SHC(0x7fff), SHC(0x0000), SHC(0x7efe), SHC(0xeff5), SHC(0x7bfb), SHC(0xe02b), SHC(0x7703), SHC(0xd0e1), + SHC(0x702b), SHC(0xc256), SHC(0x678e), SHC(0xb4c3), SHC(0x5d4f), SHC(0xa861), SHC(0x5197), SHC(0x9d60), + SHC(0x4496), SHC(0x93ed), SHC(0x3680), SHC(0x8c2f), SHC(0x278e), SHC(0x8644), SHC(0x17fc), SHC(0x8244), + SHC(0x080a), SHC(0x8041), SHC(0xf7f6), SHC(0x8041), SHC(0xe804), SHC(0x8244), SHC(0xd872), SHC(0x8644), + SHC(0xc980), SHC(0x8c2f), SHC(0xbb6a), SHC(0x93ed), SHC(0xae69), SHC(0x9d60), SHC(0xa2b1), SHC(0xa861), + SHC(0x7fff), SHC(0x0000), SHC(0x7e6d), SHC(0xebfa), SHC(0x79bc), SHC(0xd872), SHC(0x720d), SHC(0xc5e4), + SHC(0x678e), SHC(0xb4c3), SHC(0x5a82), SHC(0xa57e), SHC(0x4b3d), SHC(0x9872), SHC(0x3a1c), SHC(0x8df3), + SHC(0x278e), SHC(0x8644), SHC(0x1406), SHC(0x8193), SHC(0x0000), SHC(0x8000), SHC(0xebfa), SHC(0x8193), + SHC(0xd872), SHC(0x8644), SHC(0xc5e4), SHC(0x8df3), SHC(0xb4c3), SHC(0x9872), SHC(0xa57e), SHC(0xa57e), + SHC(0x9872), SHC(0xb4c3), SHC(0x8df3), SHC(0xc5e4), SHC(0x8644), SHC(0xd872), SHC(0x8193), SHC(0xebfa), + SHC(0x7fff), SHC(0x0000), SHC(0x7dbc), SHC(0xe804), SHC(0x7703), SHC(0xd0e1), SHC(0x6c13), SHC(0xbb6a), + SHC(0x5d4f), SHC(0xa861), SHC(0x4b3d), SHC(0x9872), SHC(0x3680), SHC(0x8c2f), SHC(0x1fd5), SHC(0x8405), + SHC(0x080a), SHC(0x8041), SHC(0xeff5), SHC(0x8102), SHC(0xd872), SHC(0x8644), SHC(0xc256), SHC(0x8fd5), + SHC(0xae69), SHC(0x9d60), SHC(0x9d60), SHC(0xae69), SHC(0x8fd5), SHC(0xc256), SHC(0x8644), SHC(0xd872), + SHC(0x8102), SHC(0xeff5), SHC(0x8041), SHC(0x080a), SHC(0x8405), SHC(0x1fd5), SHC(0x8c2f), SHC(0x3680), + SHC(0x7fff), SHC(0x0000), SHC(0x7ceb), SHC(0xe414), SHC(0x73d1), SHC(0xc980), SHC(0x6524), SHC(0xb18c), + SHC(0x5197), SHC(0x9d60), SHC(0x3a1c), SHC(0x8df3), SHC(0x1fd5), SHC(0x8405), SHC(0x0405), SHC(0x8010), + SHC(0xe804), SHC(0x8244), SHC(0xcd2a), SHC(0x8a87), SHC(0xb4c3), SHC(0x9872), SHC(0x9ffc), SHC(0xab5a), + SHC(0x8fd5), SHC(0xc256), SHC(0x8515), SHC(0xdc4a), SHC(0x8041), SHC(0xf7f6), SHC(0x8193), SHC(0x1406), + SHC(0x88fd), SHC(0x2f1f), SHC(0x9622), SHC(0x47f2), SHC(0xa861), SHC(0x5d4f), SHC(0xbed8), SHC(0x6e2d), + SHC(0x7fff), SHC(0x0000), SHC(0x7bfb), SHC(0xe02b), SHC(0x702b), SHC(0xc256), SHC(0x5d4f), SHC(0xa861), + SHC(0x4496), SHC(0x93ed), SHC(0x278e), SHC(0x8644), SHC(0x080a), SHC(0x8041), SHC(0xe804), SHC(0x8244), + SHC(0xc980), SHC(0x8c2f), SHC(0xae69), SHC(0x9d60), SHC(0x9872), SHC(0xb4c3), SHC(0x88fd), SHC(0xd0e1), + SHC(0x8102), SHC(0xeff5), SHC(0x8102), SHC(0x100b), SHC(0x88fd), SHC(0x2f1f), SHC(0x9872), SHC(0x4b3d), + SHC(0xae69), SHC(0x62a0), SHC(0xc980), SHC(0x73d1), SHC(0xe804), SHC(0x7dbc), SHC(0x080a), SHC(0x7fbf), + SHC(0x7fff), SHC(0x0000), SHC(0x7aeb), SHC(0xdc4a), SHC(0x6c13), SHC(0xbb6a), SHC(0x54a6), SHC(0x9ffc), + SHC(0x3680), SHC(0x8c2f), SHC(0x1406), SHC(0x8193), SHC(0xeff5), SHC(0x8102), SHC(0xcd2a), SHC(0x8a87), + SHC(0xae69), SHC(0x9d60), SHC(0x9622), SHC(0xb80e), SHC(0x8644), SHC(0xd872), SHC(0x8010), SHC(0xfbfb), + SHC(0x8405), SHC(0x1fd5), SHC(0x91d3), SHC(0x4128), SHC(0xa861), SHC(0x5d4f), SHC(0xc5e4), SHC(0x720d), + SHC(0xe804), SHC(0x7dbc), SHC(0x0c0c), SHC(0x7f6f), SHC(0x2f1f), SHC(0x7703), SHC(0x4e74), SHC(0x6524), + SHC(0x7fff), SHC(0x0000), SHC(0x7ffc), SHC(0xfdfd), SHC(0x7ff0), SHC(0xfbfb), SHC(0x7fdc), SHC(0xf9f8), + SHC(0x7fbf), SHC(0xf7f6), SHC(0x7f9b), SHC(0xf5f5), SHC(0x7f6f), SHC(0xf3f4), SHC(0x7f3a), SHC(0xf1f4), + SHC(0x7efe), SHC(0xeff5), SHC(0x7eb9), SHC(0xedf7), SHC(0x7e6d), SHC(0xebfa), SHC(0x7e18), SHC(0xe9fe), + SHC(0x7dbc), SHC(0xe804), SHC(0x7d57), SHC(0xe60b), SHC(0x7ceb), SHC(0xe414), SHC(0x7c77), SHC(0xe21e), + SHC(0x7bfb), SHC(0xe02b), SHC(0x7b77), SHC(0xde39), SHC(0x7aeb), SHC(0xdc4a), SHC(0x7a57), SHC(0xda5d), + SHC(0x7fff), SHC(0x0000), SHC(0x7fdc), SHC(0xf9f8), SHC(0x7f6f), SHC(0xf3f4), SHC(0x7eb9), SHC(0xedf7), + SHC(0x7dbc), SHC(0xe804), SHC(0x7c77), SHC(0xe21e), SHC(0x7aeb), SHC(0xdc4a), SHC(0x7919), SHC(0xd68a), + SHC(0x7703), SHC(0xd0e1), SHC(0x74a9), SHC(0xcb53), SHC(0x720d), SHC(0xc5e4), SHC(0x6f2f), SHC(0xc095), + SHC(0x6c13), SHC(0xbb6a), SHC(0x68b9), SHC(0xb666), SHC(0x6524), SHC(0xb18c), SHC(0x6155), SHC(0xacdf), + SHC(0x5d4f), SHC(0xa861), SHC(0x5914), SHC(0xa414), SHC(0x54a6), SHC(0x9ffc), SHC(0x5008), SHC(0x9c1b), + SHC(0x7fff), SHC(0x0000), SHC(0x7f9b), SHC(0xf5f5), SHC(0x7e6d), SHC(0xebfa), SHC(0x7c77), SHC(0xe21e), + SHC(0x79bc), SHC(0xd872), SHC(0x7642), SHC(0xcf04), SHC(0x720d), SHC(0xc5e4), SHC(0x6d23), SHC(0xbd1f), + SHC(0x678e), SHC(0xb4c3), SHC(0x6155), SHC(0xacdf), SHC(0x5a82), SHC(0xa57e), SHC(0x5321), SHC(0x9eab), + SHC(0x4b3d), SHC(0x9872), SHC(0x42e1), SHC(0x92dd), SHC(0x3a1c), SHC(0x8df3), SHC(0x30fc), SHC(0x89be), + SHC(0x278e), SHC(0x8644), SHC(0x1de2), SHC(0x8389), SHC(0x1406), SHC(0x8193), SHC(0x0a0b), SHC(0x8065), + SHC(0x7fff), SHC(0x0000), SHC(0x7f3a), SHC(0xf1f4), SHC(0x7ceb), SHC(0xe414), SHC(0x7919), SHC(0xd68a), + SHC(0x73d1), SHC(0xc980), SHC(0x6d23), SHC(0xbd1f), SHC(0x6524), SHC(0xb18c), SHC(0x5bec), SHC(0xa6ec), + SHC(0x5197), SHC(0x9d60), SHC(0x4646), SHC(0x9504), SHC(0x3a1c), SHC(0x8df3), SHC(0x2d3f), SHC(0x8843), + SHC(0x1fd5), SHC(0x8405), SHC(0x1209), SHC(0x8147), SHC(0x0405), SHC(0x8010), SHC(0xf5f5), SHC(0x8065), + SHC(0xe804), SHC(0x8244), SHC(0xda5d), SHC(0x85a9), SHC(0xcd2a), SHC(0x8a87), SHC(0xc095), SHC(0x90d1), + SHC(0x7fff), SHC(0x0000), SHC(0x7eb9), SHC(0xedf7), SHC(0x7aeb), SHC(0xdc4a), SHC(0x74a9), SHC(0xcb53), + SHC(0x6c13), SHC(0xbb6a), SHC(0x6155), SHC(0xacdf), SHC(0x54a6), SHC(0x9ffc), SHC(0x4646), SHC(0x9504), + SHC(0x3680), SHC(0x8c2f), SHC(0x25a3), SHC(0x85a9), SHC(0x1406), SHC(0x8193), SHC(0x0203), SHC(0x8004), + SHC(0xeff5), SHC(0x8102), SHC(0xde39), SHC(0x8489), SHC(0xcd2a), SHC(0x8a87), SHC(0xbd1f), SHC(0x92dd), + SHC(0xae69), SHC(0x9d60), SHC(0xa154), SHC(0xa9db), SHC(0x9622), SHC(0xb80e), SHC(0x8d0d), SHC(0xc7b0), + SHC(0x7fff), SHC(0x0000), SHC(0x7e18), SHC(0xe9fe), SHC(0x786f), SHC(0xd4a4), SHC(0x6f2f), SHC(0xc095), + SHC(0x62a0), SHC(0xae69), SHC(0x5321), SHC(0x9eab), SHC(0x4128), SHC(0x91d3), SHC(0x2d3f), SHC(0x8843), + SHC(0x17fc), SHC(0x8244), SHC(0x0203), SHC(0x8004), SHC(0xebfa), SHC(0x8193), SHC(0xd68a), SHC(0x86e7), + SHC(0xc256), SHC(0x8fd5), SHC(0xaff8), SHC(0x9c1b), SHC(0x9ffc), SHC(0xab5a), SHC(0x92dd), SHC(0xbd1f), + SHC(0x88fd), SHC(0xd0e1), SHC(0x82a9), SHC(0xe60b), SHC(0x8010), SHC(0xfbfb), SHC(0x8147), SHC(0x1209), + SHC(0x7fff), SHC(0x0000), SHC(0x7d57), SHC(0xe60b), SHC(0x7579), SHC(0xcd2a), SHC(0x68b9), SHC(0xb666), + SHC(0x579f), SHC(0xa2b1), SHC(0x42e1), SHC(0x92dd), SHC(0x2b5c), SHC(0x8791), SHC(0x1209), SHC(0x8147), + SHC(0xf7f6), SHC(0x8041), SHC(0xde39), SHC(0x8489), SHC(0xc5e4), SHC(0x8df3), SHC(0xaff8), SHC(0x9c1b), + SHC(0x9d60), SHC(0xae69), SHC(0x8ee1), SHC(0xc41b), SHC(0x8515), SHC(0xdc4a), SHC(0x8065), SHC(0xf5f5), + SHC(0x8102), SHC(0x100b), SHC(0x86e7), SHC(0x2976), SHC(0x91d3), SHC(0x4128), SHC(0xa154), SHC(0x5625), + SHC(0x7fff), SHC(0x0000), SHC(0x7c77), SHC(0xe21e), SHC(0x720d), SHC(0xc5e4), SHC(0x6155), SHC(0xacdf), + SHC(0x4b3d), SHC(0x9872), SHC(0x30fc), SHC(0x89be), SHC(0x1406), SHC(0x8193), SHC(0xf5f5), SHC(0x8065), + SHC(0xd872), SHC(0x8644), SHC(0xbd1f), SHC(0x92dd), SHC(0xa57e), SHC(0xa57e), SHC(0x92dd), SHC(0xbd1f), + SHC(0x8644), SHC(0xd872), SHC(0x8065), SHC(0xf5f5), SHC(0x8193), SHC(0x1406), SHC(0x89be), SHC(0x30fc), + SHC(0x9872), SHC(0x4b3d), SHC(0xacdf), SHC(0x6155), SHC(0xc5e4), SHC(0x720d), SHC(0xe21e), SHC(0x7c77), + SHC(0x7fff), SHC(0x0000), SHC(0x7b77), SHC(0xde39), SHC(0x6e2d), SHC(0xbed8), SHC(0x5914), SHC(0xa414), + SHC(0x3daa), SHC(0x8fd5), SHC(0x1de2), SHC(0x8389), SHC(0xfbfb), SHC(0x8010), SHC(0xda5d), SHC(0x85a9), + SHC(0xbb6a), SHC(0x93ed), SHC(0xa154), SHC(0xa9db), SHC(0x8df3), SHC(0xc5e4), SHC(0x82a9), SHC(0xe60b), + SHC(0x8041), SHC(0x080a), SHC(0x86e7), SHC(0x2976), SHC(0x9622), SHC(0x47f2), SHC(0xacdf), SHC(0x6155), + SHC(0xc980), SHC(0x73d1), SHC(0xe9fe), SHC(0x7e18), SHC(0x0c0c), SHC(0x7f6f), SHC(0x2d3f), SHC(0x77bd), + SHC(0x7fff), SHC(0x0000), SHC(0x7a57), SHC(0xda5d), SHC(0x69de), SHC(0xb80e), SHC(0x5008), SHC(0x9c1b), + SHC(0x2f1f), SHC(0x88fd), SHC(0x0a0b), SHC(0x8065), SHC(0xe414), SHC(0x8315), SHC(0xc095), SHC(0x90d1), + SHC(0xa2b1), SHC(0xa861), SHC(0x8d0d), SHC(0xc7b0), SHC(0x8193), SHC(0xebfa), SHC(0x8147), SHC(0x1209), + SHC(0x8c2f), SHC(0x3680), SHC(0xa154), SHC(0x5625), SHC(0xbed8), SHC(0x6e2d), SHC(0xe21e), SHC(0x7c77), + SHC(0x080a), SHC(0x7fbf), SHC(0x2d3f), SHC(0x77bd), SHC(0x4e74), SHC(0x6524), SHC(0x68b9), SHC(0x499a) +}; + +const Word16 FFT_W64[(64 * 2) * 2] = +{ + 16384, 0, 16364, -804, 16305, -1606, 16207, -2404, + 16069, -3196, 15893, -3981, 15679, -4756, 15426, -5520, + 15137, -6270, 14811, -7005, 14449, -7723, 14053, -8423, + 13623, -9102, 13160, -9760, 12665, -10394, 12140, -11003, + 11585, -11585, 11003, -12140, 10394, -12665, 9760, -13160, + 9102, -13623, 8423, -14053, 7723, -14449, 7005, -14811, + 6270, -15137, 5520, -15426, 4756, -15679, 3981, -15893, + 3196, -16069, 2404, -16207, 1606, -16305, 804, -16364, + 0, -16384, -804, -16364, -1606, -16305, -2404, -16207, + -3196, -16069, -3981, -15893, -4756, -15679, -5520, -15426, + -6270, -15137, -7005, -14811, -7723, -14449, -8423, -14053, + -9102, -13623, -9760, -13160, -10394, -12665, -11003, -12140, + -11585, -11585, -12140, -11003, -12665, -10394, -13160, -9760, + -13623, -9102, -14053, -8423, -14449, -7723, -14811, -7005, + -15137, -6270, -15426, -5520, -15679, -4756, -15893, -3981, + -16069, -3196, -16207, -2404, -16305, -1606, -16364, -804, + /* The following is a duplication of the above but scaled up by a factor of 2. + * This save one operation in inverse FFT inner loops */ + 32767, 0, 32729, -1608, 32610, -3212, 32413, -4808, + 32138, -6393, 31786, -7962, 31357, -9512, 30853, -11039, + 30274, -12540, 29622, -14010, 28899, -15447, 28106, -16846, + 27246, -18205, 26320, -19520, 25330, -20788, 24279, -22006, + 23170, -23170, 22006, -24279, 20788, -25330, 19520, -26320, + 18205, -27246, 16846, -28106, 15447, -28899, 14010, -29622, + 12540, -30274, 11039, -30853, 9512, -31357, 7962, -31786, + 6393, -32138, 4808, -32413, 3212, -32610, 1608, -32729, + 0, -32768, -1608, -32729, -3212, -32610, -4808, -32413, + -6393, -32138, -7962, -31786, -9512, -31357, -11039, -30853, + -12540, -30274, -14010, -29622, -15447, -28899, -16846, -28106, + -18205, -27246, -19520, -26320, -20788, -25330, -22006, -24279, + -23170, -23170, -24279, -22006, -25330, -20788, -26320, -19520, + -27246, -18205, -28106, -16846, -28899, -15447, -29622, -14010, + -30274, -12540, -30853, -11039, -31357, -9512, -31786, -7962, + -32138, -6393, -32413, -4808, -32610, -3212, -32729, -1608 +}; + +const Word16 FFT_W128[] = +{ + /* part of table that is not scaled by 2 */ + 16384, 0, 16379, -402, 16364, -804, 16339, -1205, + 16305, -1606, 16260, -2006, 16206, -2404, 16142, -2801, + 16069, -3196, 15985, -3590, 15893, -3981, 15790, -4370, + 15678, -4756, 15557, -5139, 15426, -5519, 15286, -5896, + 15136, -6270, 14978, -6639, 14811, -7005, 14634, -7366, + 14449, -7723, 14255, -8075, 14053, -8423, 13842, -8765, + 13622, -9102, 13395, -9434, 13159, -9760, 12916, -10080, + 12665, -10394, 12406, -10701, 12139, -11002, 11866, -11297, + 11585, -11585, 11297, -11866, 11002, -12139, 10701, -12406, + 10394, -12665, 10080, -12916, 9760, -13159, 9434, -13395, + 9102, -13622, 8765, -13842, 8423, -14053, 8075, -14255, + 7723, -14449, 7366, -14634, 7005, -14811, 6639, -14978, + 6270, -15136, 5896, -15286, 5519, -15426, 5139, -15557, + 4756, -15678, 4370, -15790, 3981, -15893, 3590, -15985, + 3196, -16069, 2801, -16142, 2404, -16206, 2006, -16260, + 1606, -16305, 1205, -16339, 804, -16364, 402, -16379, + 0, -16384, -402, -16379, -804, -16364, -1205, -16339, + -1606, -16305, -2006, -16260, -2404, -16206, -2801, -16142, + -3196, -16069, -3590, -15985, -3981, -15893, -4370, -15790, + -4756, -15678, -5139, -15557, -5519, -15426, -5896, -15286, + -6270, -15136, -6639, -14978, -7005, -14811, -7366, -14634, + -7723, -14449, -8075, -14255, -8423, -14053, -8765, -13842, + -9102, -13622, -9434, -13395, -9760, -13159, -10080, -12916, + -10394, -12665, -10701, -12406, -11002, -12139, -11297, -11866, + -11585, -11585, -11866, -11297, -12139, -11002, -12406, -10701, + -12665, -10394, -12916, -10080, -13159, -9760, -13395, -9434, + -13622, -9102, -13842, -8765, -14053, -8423, -14255, -8075, + -14449, -7723, -14634, -7366, -14811, -7005, -14978, -6639, + -15136, -6270, -15286, -5896, -15426, -5519, -15557, -5139, + -15678, -4756, -15790, -4370, -15893, -3981, -15985, -3590, + -16069, -3196, -16142, -2801, -16206, -2404, -16260, -2006, + -16305, -1606, -16339, -1205, -16364, -804, -16379, -402, + /* part of table that is scaled by 2 (this save one operation in FFT inner loops) */ + 32767, 0, 32758, -804, 32728, -1608, 32678, -2410, + 32610, -3212, 32520, -4012, 32412, -4808, 32284, -5602, + 32138, -6392, 31970, -7180, 31786, -7962, 31580, -8740, + 31356, -9512, 31114, -10278, 30852, -11038, 30572, -11792, + 30272, -12540, 29956, -13278, 29622, -14010, 29268, -14732, + 28898, -15446, 28510, -16150, 28106, -16846, 27684, -17530, + 27244, -18204, 26790, -18868, 26318, -19520, 25832, -20160, + 25330, -20788, 24812, -21402, 24278, -22004, 23732, -22594, + 23170, -23170, 22594, -23732, 22004, -24278, 21402, -24812, + 20788, -25330, 20160, -25832, 19520, -26318, 18868, -26790, + 18204, -27244, 17530, -27684, 16846, -28106, 16150, -28510, + 15446, -28898, 14732, -29268, 14010, -29622, 13278, -29956, + 12540, -30272, 11792, -30572, 11038, -30852, 10278, -31114, + 9512, -31356, 8740, -31580, 7962, -31786, 7180, -31970, + 6392, -32138, 5602, -32284, 4808, -32412, 4012, -32520, + 3212, -32610, 2410, -32678, 1608, -32728, 804, -32758, + 0, -32768, -804, -32758, -1608, -32728, -2410, -32678, + -3212, -32610, -4012, -32520, -4808, -32412, -5602, -32284, + -6392, -32138, -7180, -31970, -7962, -31786, -8740, -31580, + -9512, -31356, -10278, -31114, -11038, -30852, -11792, -30572, + -12540, -30272, -13278, -29956, -14010, -29622, -14732, -29268, + -15446, -28898, -16150, -28510, -16846, -28106, -17530, -27684, + -18204, -27244, -18868, -26790, -19520, -26318, -20160, -25832, + -20788, -25330, -21402, -24812, -22004, -24278, -22594, -23732, + -23170, -23170, -23732, -22594, -24278, -22004, -24812, -21402, + -25330, -20788, -25832, -20160, -26318, -19520, -26790, -18868, + -27244, -18204, -27684, -17530, -28106, -16846, -28510, -16150, + -28898, -15446, -29268, -14732, -29622, -14010, -29956, -13278, + -30272, -12540, -30572, -11792, -30852, -11038, -31114, -10278, + -31356, -9512, -31580, -8740, -31786, -7962, -31970, -7180, + -32138, -6392, -32284, -5602, -32412, -4808, -32520, -4012, + -32610, -3212, -32678, -2410, -32728, -1608, -32758, -804 +}; + +const Word16 FFT_W256[(256 * 2) * 2] = +{ + /* Each adjacent pair represents the real and imaginary part of a complex number: */ + /* W = exp{-j*(PI*n/256)} = cos(PI*n/256)*16384 -j*sin(PI*n/256)*16384 for n=0, 1, ..., 255. */ + 16384, 0, 16383, -201, 16379, -402, 16373, -603, + 16364, -804, 16353, -1005, 16340, -1205, 16324, -1406, + 16305, -1606, 16284, -1806, 16261, -2006, 16235, -2205, + 16207, -2404, 16176, -2603, 16143, -2801, 16107, -2999, + 16069, -3196, 16029, -3393, 15986, -3590, 15941, -3786, + 15893, -3981, 15843, -4176, 15791, -4370, 15736, -4563, + 15679, -4756, 15619, -4948, 15557, -5139, 15493, -5330, + 15426, -5520, 15357, -5708, 15286, -5897, 15213, -6084, + 15137, -6270, 15059, -6455, 14978, -6639, 14896, -6823, + 14811, -7005, 14724, -7186, 14635, -7366, 14543, -7545, + 14449, -7723, 14354, -7900, 14256, -8076, 14155, -8250, + 14053, -8423, 13949, -8595, 13842, -8765, 13733, -8935, + 13623, -9102, 13510, -9269, 13395, -9434, 13279, -9598, + 13160, -9760, 13039, -9921, 12916, -10080, 12792, -10238, + 12665, -10394, 12537, -10549, 12406, -10702, 12274, -10853, + 12140, -11003, 12004, -11151, 11866, -11297, 11727, -11442, + 11585, -11585, 11442, -11727, 11297, -11866, 11151, -12004, + 11003, -12140, 10853, -12274, 10702, -12406, 10549, -12537, + 10394, -12665, 10238, -12792, 10080, -12916, 9921, -13039, + 9760, -13160, 9598, -13279, 9434, -13395, 9269, -13510, + 9102, -13623, 8935, -13733, 8765, -13842, 8595, -13949, + 8423, -14053, 8250, -14155, 8076, -14256, 7900, -14354, + 7723, -14449, 7545, -14543, 7366, -14635, 7186, -14724, + 7005, -14811, 6823, -14896, 6639, -14978, 6455, -15059, + 6270, -15137, 6084, -15213, 5897, -15286, 5708, -15357, + 5520, -15426, 5330, -15493, 5139, -15557, 4948, -15619, + 4756, -15679, 4563, -15736, 4370, -15791, 4176, -15843, + 3981, -15893, 3786, -15941, 3590, -15986, 3393, -16029, + 3196, -16069, 2999, -16107, 2801, -16143, 2603, -16176, + 2404, -16207, 2205, -16235, 2006, -16261, 1806, -16284, + 1606, -16305, 1406, -16324, 1205, -16340, 1005, -16353, + 804, -16364, 603, -16373, 402, -16379, 201, -16383, + 0, -16384, -201, -16383, -402, -16379, -603, -16373, + -804, -16364, -1005, -16353, -1205, -16340, -1406, -16324, + -1606, -16305, -1806, -16284, -2006, -16261, -2205, -16235, + -2404, -16207, -2603, -16176, -2801, -16143, -2999, -16107, + -3196, -16069, -3393, -16029, -3590, -15986, -3786, -15941, + -3981, -15893, -4176, -15843, -4370, -15791, -4563, -15736, + -4756, -15679, -4948, -15619, -5139, -15557, -5330, -15493, + -5520, -15426, -5708, -15357, -5897, -15286, -6084, -15213, + -6270, -15137, -6455, -15059, -6639, -14978, -6823, -14896, + -7005, -14811, -7186, -14724, -7366, -14635, -7545, -14543, + -7723, -14449, -7900, -14354, -8076, -14256, -8250, -14155, + -8423, -14053, -8595, -13949, -8765, -13842, -8935, -13733, + -9102, -13623, -9269, -13510, -9434, -13395, -9598, -13279, + -9760, -13160, -9921, -13039, -10080, -12916, -10238, -12792, + -10394, -12665, -10549, -12537, -10702, -12406, -10853, -12274, + -11003, -12140, -11151, -12004, -11297, -11866, -11442, -11727, + -11585, -11585, -11727, -11442, -11866, -11297, -12004, -11151, + -12140, -11003, -12274, -10853, -12406, -10702, -12537, -10549, + -12665, -10394, -12792, -10238, -12916, -10080, -13039, -9921, + -13160, -9760, -13279, -9598, -13395, -9434, -13510, -9269, + -13623, -9102, -13733, -8935, -13842, -8765, -13949, -8595, + -14053, -8423, -14155, -8250, -14256, -8076, -14354, -7900, + -14449, -7723, -14543, -7545, -14635, -7366, -14724, -7186, + -14811, -7005, -14896, -6823, -14978, -6639, -15059, -6455, + -15137, -6270, -15213, -6084, -15286, -5897, -15357, -5708, + -15426, -5520, -15493, -5330, -15557, -5139, -15619, -4948, + -15679, -4756, -15736, -4563, -15791, -4370, -15843, -4176, + -15893, -3981, -15941, -3786, -15986, -3590, -16029, -3393, + -16069, -3196, -16107, -2999, -16143, -2801, -16176, -2603, + -16207, -2404, -16235, -2205, -16261, -2006, -16284, -1806, + -16305, -1606, -16324, -1406, -16340, -1205, -16353, -1005, + -16364, -804, -16373, -603, -16379, -402, -16383, -201, + + /* The following is a duplication of the above but scaled up by a factor of 2. + * This save one operation in inverse FFT inner loops */ + 32767, 0, 32766, -402, 32758, -804, 32746, -1206, + 32729, -1608, 32706, -2009, 32679, -2411, 32647, -2811, + 32610, -3212, 32568, -3612, 32522, -4011, 32470, -4410, + 32413, -4808, 32352, -5205, 32286, -5602, 32214, -5998, + 32138, -6393, 32058, -6787, 31972, -7180, 31881, -7571, + 31786, -7962, 31686, -8351, 31581, -8740, 31471, -9127, + 31357, -9512, 31238, -9896, 31114, -10279, 30986, -10660, + 30853, -11039, 30715, -11417, 30572, -11793, 30425, -12167, + 30274, -12540, 30118, -12910, 29957, -13279, 29792, -13646, + 29622, -14010, 29448, -14373, 29269, -14733, 29086, -15091, + 28899, -15447, 28707, -15800, 28511, -16151, 28311, -16500, + 28106, -16846, 27897, -17190, 27684, -17531, 27467, -17869, + 27246, -18205, 27020, -18538, 26791, -18868, 26557, -19195, + 26320, -19520, 26078, -19841, 25833, -20160, 25583, -20475, + 25330, -20788, 25073, -21097, 24812, -21403, 24548, -21706, + 24279, -22006, 24008, -22302, 23732, -22595, 23453, -22884, + 23170, -23170, 22884, -23453, 22595, -23732, 22302, -24008, + 22006, -24279, 21706, -24548, 21403, -24812, 21097, -25073, + 20788, -25330, 20475, -25583, 20160, -25833, 19841, -26078, + 19520, -26320, 19195, -26557, 18868, -26791, 18538, -27020, + 18205, -27246, 17869, -27467, 17531, -27684, 17190, -27897, + 16846, -28106, 16500, -28311, 16151, -28511, 15800, -28707, + 15447, -28899, 15091, -29086, 14733, -29269, 14373, -29448, + 14010, -29622, 13646, -29792, 13279, -29957, 12910, -30118, + 12540, -30274, 12167, -30425, 11793, -30572, 11417, -30715, + 11039, -30853, 10660, -30986, 10279, -31114, 9896, -31238, + 9512, -31357, 9127, -31471, 8740, -31581, 8351, -31686, + 7962, -31786, 7571, -31881, 7180, -31972, 6787, -32058, + 6393, -32138, 5998, -32214, 5602, -32286, 5205, -32352, + 4808, -32413, 4410, -32470, 4011, -32522, 3612, -32568, + 3212, -32610, 2811, -32647, 2411, -32679, 2009, -32706, + 1608, -32729, 1206, -32746, 804, -32758, 402, -32766, + 0, -32768, -402, -32766, -804, -32758, -1206, -32746, + -1608, -32729, -2009, -32706, -2411, -32679, -2811, -32647, + -3212, -32610, -3612, -32568, -4011, -32522, -4410, -32470, + -4808, -32413, -5205, -32352, -5602, -32286, -5998, -32214, + -6393, -32138, -6787, -32058, -7180, -31972, -7571, -31881, + -7962, -31786, -8351, -31686, -8740, -31581, -9127, -31471, + -9512, -31357, -9896, -31238, -10279, -31114, -10660, -30986, + -11039, -30853, -11417, -30715, -11793, -30572, -12167, -30425, + -12540, -30274, -12910, -30118, -13279, -29957, -13646, -29792, + -14010, -29622, -14373, -29448, -14733, -29269, -15091, -29086, + -15447, -28899, -15800, -28707, -16151, -28511, -16500, -28311, + -16846, -28106, -17190, -27897, -17531, -27684, -17869, -27467, + -18205, -27246, -18538, -27020, -18868, -26791, -19195, -26557, + -19520, -26320, -19841, -26078, -20160, -25833, -20475, -25583, + -20788, -25330, -21097, -25073, -21403, -24812, -21706, -24548, + -22006, -24279, -22302, -24008, -22595, -23732, -22884, -23453, + -23170, -23170, -23453, -22884, -23732, -22595, -24008, -22302, + -24279, -22006, -24548, -21706, -24812, -21403, -25073, -21097, + -25330, -20788, -25583, -20475, -25833, -20160, -26078, -19841, + -26320, -19520, -26557, -19195, -26791, -18868, -27020, -18538, + -27246, -18205, -27467, -17869, -27684, -17531, -27897, -17190, + -28106, -16846, -28311, -16500, -28511, -16151, -28707, -15800, + -28899, -15447, -29086, -15091, -29269, -14733, -29448, -14373, + -29622, -14010, -29792, -13646, -29957, -13279, -30118, -12910, + -30274, -12540, -30425, -12167, -30572, -11793, -30715, -11417, + -30853, -11039, -30986, -10660, -31114, -10279, -31238, -9896, + -31357, -9512, -31471, -9127, -31581, -8740, -31686, -8351, + -31786, -7962, -31881, -7571, -31972, -7180, -32058, -6787, + -32138, -6393, -32214, -5998, -32286, -5602, -32352, -5205, + -32413, -4808, -32470, -4410, -32522, -4011, -32568, -3612, + -32610, -3212, -32647, -2811, -32679, -2411, -32706, -2009, + -32729, -1608, -32746, -1206, -32758, -804, -32766, -402 +}; + +const Word16 FFT_W512[(512 * 2) * 2] = +{ + 16384, 0, 16384, -101, 16383, -201, 16381, -302, + 16379, -402, 16376, -503, 16373, -603, 16369, -704, + 16364, -804, 16359, -904, 16353, -1005, 16347, -1105, + 16340, -1205, 16332, -1306, 16324, -1406, 16315, -1506, + 16305, -1606, 16295, -1706, 16284, -1806, 16273, -1906, + 16261, -2006, 16248, -2105, 16235, -2205, 16221, -2305, + 16207, -2404, 16192, -2503, 16176, -2603, 16160, -2702, + 16143, -2801, 16125, -2900, 16107, -2999, 16088, -3098, + 16069, -3196, 16049, -3295, 16029, -3393, 16008, -3492, + 15986, -3590, 15964, -3688, 15941, -3786, 15917, -3883, + 15893, -3981, 15868, -4078, 15843, -4176, 15817, -4273, + 15791, -4370, 15763, -4467, 15736, -4563, 15707, -4660, + 15679, -4756, 15649, -4852, 15619, -4948, 15588, -5044, + 15557, -5139, 15525, -5235, 15493, -5330, 15460, -5425, + 15426, -5520, 15392, -5614, 15357, -5708, 15322, -5803, + 15286, -5897, 15250, -5990, 15213, -6084, 15175, -6177, + 15137, -6270, 15098, -6363, 15059, -6455, 15019, -6547, + 14978, -6639, 14937, -6731, 14896, -6823, 14854, -6914, + 14811, -7005, 14768, -7096, 14724, -7186, 14680, -7276, + 14635, -7366, 14589, -7456, 14543, -7545, 14497, -7635, + 14449, -7723, 14402, -7812, 14354, -7900, 14305, -7988, + 14256, -8076, 14206, -8163, 14155, -8250, 14104, -8337, + 14053, -8423, 14001, -8509, 13949, -8595, 13896, -8680, + 13842, -8765, 13788, -8850, 13733, -8935, 13678, -9019, + 13623, -9102, 13567, -9186, 13510, -9269, 13453, -9352, + 13395, -9434, 13337, -9516, 13279, -9598, 13219, -9679, + 13160, -9760, 13100, -9841, 13039, -9921, 12978, -10001, + 12916, -10080, 12854, -10159, 12792, -10238, 12729, -10316, + 12665, -10394, 12601, -10471, 12537, -10549, 12472, -10625, + 12406, -10702, 12340, -10778, 12274, -10853, 12207, -10928, + 12140, -11003, 12072, -11077, 12004, -11151, 11935, -11224, + 11866, -11297, 11797, -11370, 11727, -11442, 11656, -11514, + 11585, -11585, 11514, -11656, 11442, -11727, 11370, -11797, + 11297, -11866, 11224, -11935, 11151, -12004, 11077, -12072, + 11003, -12140, 10928, -12207, 10853, -12274, 10778, -12340, + 10702, -12406, 10625, -12472, 10549, -12537, 10471, -12601, + 10394, -12665, 10316, -12729, 10238, -12792, 10159, -12854, + 10080, -12916, 10001, -12978, 9921, -13039, 9841, -13100, + 9760, -13160, 9679, -13219, 9598, -13279, 9516, -13337, + 9434, -13395, 9352, -13453, 9269, -13510, 9186, -13567, + 9102, -13623, 9019, -13678, 8935, -13733, 8850, -13788, + 8765, -13842, 8680, -13896, 8595, -13949, 8509, -14001, + 8423, -14053, 8337, -14104, 8250, -14155, 8163, -14206, + 8076, -14256, 7988, -14305, 7900, -14354, 7812, -14402, + 7723, -14449, 7635, -14497, 7545, -14543, 7456, -14589, + 7366, -14635, 7276, -14680, 7186, -14724, 7096, -14768, + 7005, -14811, 6914, -14854, 6823, -14896, 6731, -14937, + 6639, -14978, 6547, -15019, 6455, -15059, 6363, -15098, + 6270, -15137, 6177, -15175, 6084, -15213, 5990, -15250, + 5897, -15286, 5803, -15322, 5708, -15357, 5614, -15392, + 5520, -15426, 5425, -15460, 5330, -15493, 5235, -15525, + 5139, -15557, 5044, -15588, 4948, -15619, 4852, -15649, + 4756, -15679, 4660, -15707, 4563, -15736, 4467, -15763, + 4370, -15791, 4273, -15817, 4176, -15843, 4078, -15868, + 3981, -15893, 3883, -15917, 3786, -15941, 3688, -15964, + 3590, -15986, 3492, -16008, 3393, -16029, 3295, -16049, + 3196, -16069, 3098, -16088, 2999, -16107, 2900, -16125, + 2801, -16143, 2702, -16160, 2603, -16176, 2503, -16192, + 2404, -16207, 2305, -16221, 2205, -16235, 2105, -16248, + 2006, -16261, 1906, -16273, 1806, -16284, 1706, -16295, + 1606, -16305, 1506, -16315, 1406, -16324, 1306, -16332, + 1205, -16340, 1105, -16347, 1005, -16353, 904, -16359, + 804, -16364, 703, -16369, 603, -16373, 503, -16376, + 402, -16379, 302, -16381, 201, -16383, 101, -16384, + 0, -16384, -101, -16384, -201, -16383, -302, -16381, + -402, -16379, -503, -16376, -603, -16373, -704, -16369, + -804, -16364, -904, -16359, -1005, -16353, -1105, -16347, + -1205, -16340, -1306, -16332, -1406, -16324, -1506, -16315, + -1606, -16305, -1706, -16295, -1806, -16284, -1906, -16273, + -2006, -16261, -2105, -16248, -2205, -16235, -2305, -16221, + -2404, -16207, -2503, -16192, -2603, -16176, -2702, -16160, + -2801, -16143, -2900, -16125, -2999, -16107, -3098, -16088, + -3196, -16069, -3295, -16049, -3393, -16029, -3492, -16008, + -3590, -15986, -3688, -15964, -3786, -15941, -3883, -15917, + -3981, -15893, -4078, -15868, -4176, -15843, -4273, -15817, + -4370, -15791, -4467, -15763, -4563, -15736, -4660, -15707, + -4756, -15679, -4852, -15649, -4948, -15619, -5044, -15588, + -5139, -15557, -5235, -15525, -5330, -15493, -5425, -15460, + -5520, -15426, -5614, -15392, -5708, -15357, -5803, -15322, + -5897, -15286, -5990, -15250, -6084, -15213, -6177, -15175, + -6270, -15137, -6363, -15098, -6455, -15059, -6547, -15019, + -6639, -14978, -6731, -14937, -6823, -14896, -6914, -14854, + -7005, -14811, -7096, -14768, -7186, -14724, -7276, -14680, + -7366, -14635, -7456, -14589, -7545, -14543, -7635, -14497, + -7723, -14449, -7812, -14402, -7900, -14354, -7988, -14305, + -8076, -14256, -8163, -14206, -8250, -14155, -8337, -14104, + -8423, -14053, -8509, -14001, -8595, -13949, -8680, -13896, + -8765, -13842, -8850, -13788, -8935, -13733, -9019, -13678, + -9102, -13623, -9186, -13567, -9269, -13510, -9352, -13453, + -9434, -13395, -9516, -13337, -9598, -13279, -9679, -13219, + -9760, -13160, -9841, -13100, -9921, -13039, -10001, -12978, + -10080, -12916, -10159, -12854, -10238, -12792, -10316, -12729, + -10394, -12665, -10471, -12601, -10549, -12537, -10625, -12472, + -10702, -12406, -10778, -12340, -10853, -12274, -10928, -12207, + -11003, -12140, -11077, -12072, -11151, -12004, -11224, -11935, + -11297, -11866, -11370, -11797, -11442, -11727, -11514, -11656, + -11585, -11585, -11656, -11514, -11727, -11442, -11797, -11370, + -11866, -11297, -11935, -11224, -12004, -11151, -12072, -11077, + -12140, -11003, -12207, -10928, -12274, -10853, -12340, -10778, + -12406, -10702, -12472, -10625, -12537, -10549, -12601, -10471, + -12665, -10394, -12729, -10316, -12792, -10238, -12854, -10159, + -12916, -10080, -12978, -10001, -13039, -9921, -13100, -9840, + -13160, -9760, -13219, -9679, -13279, -9598, -13337, -9516, + -13395, -9434, -13453, -9352, -13510, -9269, -13567, -9186, + -13623, -9102, -13678, -9019, -13733, -8935, -13788, -8850, + -13842, -8765, -13896, -8680, -13949, -8595, -14001, -8509, + -14053, -8423, -14104, -8337, -14155, -8250, -14206, -8163, + -14256, -8076, -14305, -7988, -14354, -7900, -14402, -7812, + -14449, -7723, -14497, -7635, -14543, -7545, -14589, -7456, + -14635, -7366, -14680, -7276, -14724, -7186, -14768, -7096, + -14811, -7005, -14854, -6914, -14896, -6823, -14937, -6731, + -14978, -6639, -15019, -6547, -15059, -6455, -15098, -6363, + -15137, -6270, -15175, -6177, -15213, -6084, -15250, -5990, + -15286, -5897, -15322, -5803, -15357, -5708, -15392, -5614, + -15426, -5520, -15460, -5425, -15493, -5330, -15525, -5235, + -15557, -5139, -15588, -5044, -15619, -4948, -15649, -4852, + -15679, -4756, -15707, -4660, -15736, -4563, -15763, -4467, + -15791, -4370, -15817, -4273, -15843, -4176, -15868, -4078, + -15893, -3981, -15917, -3883, -15941, -3786, -15964, -3688, + -15986, -3590, -16008, -3492, -16029, -3393, -16049, -3295, + -16069, -3196, -16088, -3098, -16107, -2999, -16125, -2900, + -16143, -2801, -16160, -2702, -16176, -2603, -16192, -2503, + -16207, -2404, -16221, -2305, -16235, -2205, -16248, -2105, + -16261, -2006, -16273, -1906, -16284, -1806, -16295, -1706, + -16305, -1606, -16315, -1506, -16324, -1406, -16332, -1306, + -16340, -1205, -16347, -1105, -16353, -1005, -16359, -904, + -16364, -804, -16369, -703, -16373, -603, -16376, -503, + -16379, -402, -16381, -302, -16383, -201, -16384, -101, + /* The following is a duplication of the above but scaled up by a factor of 2. + * This save one operation in inverse FFT inner loops */ + 32767, 0, 32767, -201, 32766, -402, 32762, -603, + 32758, -804, 32753, -1005, 32746, -1206, 32738, -1407, + 32729, -1608, 32718, -1809, 32706, -2009, 32693, -2210, + 32679, -2411, 32664, -2611, 32647, -2811, 32629, -3012, + 32610, -3212, 32590, -3412, 32568, -3612, 32546, -3812, + 32522, -4011, 32496, -4211, 32470, -4410, 32442, -4609, + 32413, -4808, 32383, -5007, 32352, -5205, 32319, -5404, + 32286, -5602, 32251, -5800, 32214, -5998, 32177, -6195, + 32138, -6393, 32099, -6590, 32058, -6787, 32015, -6983, + 31972, -7180, 31927, -7376, 31881, -7571, 31834, -7767, + 31786, -7962, 31737, -8157, 31686, -8351, 31634, -8546, + 31581, -8740, 31527, -8933, 31471, -9127, 31415, -9319, + 31357, -9512, 31298, -9704, 31238, -9896, 31177, -10088, + 31114, -10279, 31050, -10469, 30986, -10660, 30920, -10850, + 30853, -11039, 30784, -11228, 30715, -11417, 30644, -11605, + 30572, -11793, 30499, -11980, 30425, -12167, 30350, -12354, + 30274, -12540, 30196, -12725, 30118, -12910, 30038, -13095, + 29957, -13279, 29875, -13463, 29792, -13646, 29707, -13828, + 29622, -14010, 29535, -14192, 29448, -14373, 29359, -14553, + 29269, -14733, 29178, -14912, 29086, -15091, 28993, -15269, + 28899, -15447, 28803, -15624, 28707, -15800, 28610, -15976, + 28511, -16151, 28411, -16326, 28311, -16500, 28209, -16673, + 28106, -16846, 28002, -17018, 27897, -17190, 27791, -17361, + 27684, -17531, 27576, -17700, 27467, -17869, 27357, -18037, + 27246, -18205, 27133, -18372, 27020, -18538, 26906, -18703, + 26791, -18868, 26674, -19032, 26557, -19195, 26439, -19358, + 26320, -19520, 26199, -19681, 26078, -19841, 25956, -20001, + 25833, -20160, 25708, -20318, 25583, -20475, 25457, -20632, + 25330, -20788, 25202, -20943, 25073, -21097, 24943, -21251, + 24812, -21403, 24680, -21555, 24548, -21706, 24414, -21856, + 24279, -22006, 24144, -22154, 24008, -22302, 23870, -22449, + 23732, -22595, 23593, -22740, 23453, -22884, 23312, -23028, + 23170, -23170, 23028, -23312, 22884, -23453, 22740, -23593, + 22595, -23732, 22449, -23870, 22302, -24008, 22154, -24144, + 22006, -24279, 21856, -24414, 21706, -24548, 21555, -24680, + 21403, -24812, 21251, -24943, 21097, -25073, 20943, -25202, + 20788, -25330, 20632, -25457, 20475, -25583, 20318, -25708, + 20160, -25833, 20001, -25956, 19841, -26078, 19681, -26199, + 19520, -26320, 19358, -26439, 19195, -26557, 19032, -26674, + 18868, -26791, 18703, -26906, 18538, -27020, 18372, -27133, + 18205, -27246, 18037, -27357, 17869, -27467, 17700, -27576, + 17531, -27684, 17361, -27791, 17190, -27897, 17018, -28002, + 16846, -28106, 16673, -28209, 16500, -28311, 16326, -28411, + 16151, -28511, 15976, -28610, 15800, -28707, 15624, -28803, + 15447, -28899, 15269, -28993, 15091, -29086, 14912, -29178, + 14733, -29269, 14553, -29359, 14373, -29448, 14192, -29535, + 14010, -29622, 13828, -29707, 13646, -29792, 13463, -29875, + 13279, -29957, 13095, -30038, 12910, -30118, 12725, -30196, + 12540, -30274, 12354, -30350, 12167, -30425, 11980, -30499, + 11793, -30572, 11605, -30644, 11417, -30715, 11228, -30784, + 11039, -30853, 10850, -30920, 10660, -30986, 10469, -31050, + 10279, -31114, 10088, -31177, 9896, -31238, 9704, -31298, + 9512, -31357, 9319, -31415, 9127, -31471, 8933, -31527, + 8740, -31581, 8546, -31634, 8351, -31686, 8157, -31737, + 7962, -31786, 7767, -31834, 7571, -31881, 7376, -31927, + 7180, -31972, 6983, -32015, 6787, -32058, 6590, -32099, + 6393, -32138, 6195, -32177, 5998, -32214, 5800, -32251, + 5602, -32286, 5404, -32319, 5205, -32352, 5007, -32383, + 4808, -32413, 4609, -32442, 4410, -32470, 4211, -32496, + 4011, -32522, 3812, -32546, 3612, -32568, 3412, -32590, + 3212, -32610, 3012, -32629, 2811, -32647, 2611, -32664, + 2411, -32679, 2210, -32693, 2009, -32706, 1809, -32718, + 1608, -32729, 1407, -32738, 1206, -32746, 1005, -32753, + 804, -32758, 603, -32762, 402, -32766, 201, -32767, + 0, -32768, -201, -32767, -402, -32766, -603, -32762, + -804, -32758, -1005, -32753, -1206, -32746, -1407, -32738, + -1608, -32729, -1809, -32718, -2009, -32706, -2210, -32693, + -2411, -32679, -2611, -32664, -2811, -32647, -3012, -32629, + -3212, -32610, -3412, -32590, -3612, -32568, -3812, -32546, + -4011, -32522, -4211, -32496, -4410, -32470, -4609, -32442, + -4808, -32413, -5007, -32383, -5205, -32352, -5404, -32319, + -5602, -32286, -5800, -32251, -5998, -32214, -6195, -32177, + -6393, -32138, -6590, -32099, -6787, -32058, -6983, -32015, + -7180, -31972, -7376, -31927, -7571, -31881, -7767, -31834, + -7962, -31786, -8157, -31737, -8351, -31686, -8546, -31634, + -8740, -31581, -8933, -31527, -9127, -31471, -9319, -31415, + -9512, -31357, -9704, -31298, -9896, -31238, -10088, -31177, + -10279, -31114, -10469, -31050, -10660, -30986, -10850, -30920, + -11039, -30853, -11228, -30784, -11417, -30715, -11605, -30644, + -11793, -30572, -11980, -30499, -12167, -30425, -12354, -30350, + -12540, -30274, -12725, -30196, -12910, -30118, -13095, -30038, + -13279, -29957, -13463, -29875, -13646, -29792, -13828, -29707, + -14010, -29622, -14192, -29535, -14373, -29448, -14553, -29359, + -14733, -29269, -14912, -29178, -15091, -29086, -15269, -28993, + -15447, -28899, -15624, -28803, -15800, -28707, -15976, -28610, + -16151, -28511, -16326, -28411, -16500, -28311, -16673, -28209, + -16846, -28106, -17018, -28002, -17190, -27897, -17361, -27791, + -17531, -27684, -17700, -27576, -17869, -27467, -18037, -27357, + -18205, -27246, -18372, -27133, -18538, -27020, -18703, -26906, + -18868, -26791, -19032, -26674, -19195, -26557, -19358, -26439, + -19520, -26320, -19681, -26199, -19841, -26078, -20001, -25956, + -20160, -25833, -20318, -25708, -20475, -25583, -20632, -25457, + -20788, -25330, -20943, -25202, -21097, -25073, -21251, -24943, + -21403, -24812, -21555, -24680, -21706, -24548, -21856, -24414, + -22006, -24279, -22154, -24144, -22302, -24008, -22449, -23870, + -22595, -23732, -22740, -23593, -22884, -23453, -23028, -23312, + -23170, -23170, -23312, -23028, -23453, -22884, -23593, -22740, + -23732, -22595, -23870, -22449, -24008, -22302, -24144, -22154, + -24279, -22006, -24414, -21856, -24548, -21706, -24680, -21555, + -24812, -21403, -24943, -21251, -25073, -21097, -25202, -20943, + -25330, -20788, -25457, -20632, -25583, -20475, -25708, -20318, + -25833, -20160, -25956, -20001, -26078, -19841, -26199, -19681, + -26320, -19520, -26439, -19358, -26557, -19195, -26674, -19032, + -26791, -18868, -26906, -18703, -27020, -18538, -27133, -18372, + -27246, -18205, -27357, -18037, -27467, -17869, -27576, -17700, + -27684, -17531, -27791, -17361, -27897, -17190, -28002, -17018, + -28106, -16846, -28209, -16673, -28311, -16500, -28411, -16326, + -28511, -16151, -28610, -15976, -28707, -15800, -28803, -15624, + -28899, -15447, -28993, -15269, -29086, -15091, -29178, -14912, + -29269, -14733, -29359, -14553, -29448, -14373, -29535, -14192, + -29622, -14010, -29707, -13828, -29792, -13646, -29875, -13463, + -29957, -13279, -30038, -13095, -30118, -12910, -30196, -12725, + -30274, -12540, -30350, -12354, -30425, -12167, -30499, -11980, + -30572, -11793, -30644, -11605, -30715, -11417, -30784, -11228, + -30853, -11039, -30920, -10850, -30986, -10660, -31050, -10469, + -31114, -10279, -31177, -10088, -31238, -9896, -31298, -9704, + -31357, -9512, -31415, -9319, -31471, -9127, -31527, -8933, + -31581, -8740, -31634, -8546, -31686, -8351, -31737, -8157, + -31786, -7962, -31834, -7767, -31881, -7571, -31927, -7376, + -31972, -7180, -32015, -6983, -32058, -6787, -32099, -6590, + -32138, -6393, -32177, -6195, -32214, -5998, -32251, -5800, + -32286, -5602, -32319, -5404, -32352, -5205, -32383, -5007, + -32413, -4808, -32442, -4609, -32470, -4410, -32496, -4211, + -32522, -4011, -32546, -3812, -32568, -3612, -32590, -3412, + -32610, -3212, -32629, -3012, -32647, -2811, -32664, -2611, + -32679, -2411, -32693, -2210, -32706, -2009, -32718, -1809, + -32729, -1608, -32738, -1407, -32746, -1206, -32753, -1005, + -32758, -804, -32762, -603, -32766, -402, -32767, -201 +}; + +const Word16 FFT_REORDER_1024[512] = +{ + 0, 512, 256, 768, 128, 640, 384, 896, + 64, 576, 320, 832, 192, 704, 448, 960, + 32, 544, 288, 800, 160, 672, 416, 928, + 96, 608, 352, 864, 224, 736, 480, 992, + 16, 528, 272, 784, 144, 656, 400, 912, + 80, 592, 336, 848, 208, 720, 464, 976, + 48, 560, 304, 816, 176, 688, 432, 944, + 112, 624, 368, 880, 240, 752, 496, 1008, + 8, 520, 264, 776, 136, 648, 392, 904, + 72, 584, 328, 840, 200, 712, 456, 968, + 40, 552, 296, 808, 168, 680, 424, 936, + 104, 616, 360, 872, 232, 744, 488, 1000, + 24, 536, 280, 792, 152, 664, 408, 920, + 88, 600, 344, 856, 216, 728, 472, 984, + 56, 568, 312, 824, 184, 696, 440, 952, + 120, 632, 376, 888, 248, 760, 504, 1016, + 4, 516, 260, 772, 132, 644, 388, 900, + 68, 580, 324, 836, 196, 708, 452, 964, + 36, 548, 292, 804, 164, 676, 420, 932, + 100, 612, 356, 868, 228, 740, 484, 996, + 20, 532, 276, 788, 148, 660, 404, 916, + 84, 596, 340, 852, 212, 724, 468, 980, + 52, 564, 308, 820, 180, 692, 436, 948, + 116, 628, 372, 884, 244, 756, 500, 1012, + 12, 524, 268, 780, 140, 652, 396, 908, + 76, 588, 332, 844, 204, 716, 460, 972, + 44, 556, 300, 812, 172, 684, 428, 940, + 108, 620, 364, 876, 236, 748, 492, 1004, + 28, 540, 284, 796, 156, 668, 412, 924, + 92, 604, 348, 860, 220, 732, 476, 988, + 60, 572, 316, 828, 188, 700, 444, 956, + 124, 636, 380, 892, 252, 764, 508, 1020, + 2, 514, 258, 770, 130, 642, 386, 898, + 66, 578, 322, 834, 194, 706, 450, 962, + 34, 546, 290, 802, 162, 674, 418, 930, + 98, 610, 354, 866, 226, 738, 482, 994, + 18, 530, 274, 786, 146, 658, 402, 914, + 82, 594, 338, 850, 210, 722, 466, 978, + 50, 562, 306, 818, 178, 690, 434, 946, + 114, 626, 370, 882, 242, 754, 498, 1010, + 10, 522, 266, 778, 138, 650, 394, 906, + 74, 586, 330, 842, 202, 714, 458, 970, + 42, 554, 298, 810, 170, 682, 426, 938, + 106, 618, 362, 874, 234, 746, 490, 1002, + 26, 538, 282, 794, 154, 666, 410, 922, + 90, 602, 346, 858, 218, 730, 474, 986, + 58, 570, 314, 826, 186, 698, 442, 954, + 122, 634, 378, 890, 250, 762, 506, 1018, + 6, 518, 262, 774, 134, 646, 390, 902, + 70, 582, 326, 838, 198, 710, 454, 966, + 38, 550, 294, 806, 166, 678, 422, 934, + 102, 614, 358, 870, 230, 742, 486, 998, + 22, 534, 278, 790, 150, 662, 406, 918, + 86, 598, 342, 854, 214, 726, 470, 982, + 54, 566, 310, 822, 182, 694, 438, 950, + 118, 630, 374, 886, 246, 758, 502, 1014, + 14, 526, 270, 782, 142, 654, 398, 910, + 78, 590, 334, 846, 206, 718, 462, 974, + 46, 558, 302, 814, 174, 686, 430, 942, + 110, 622, 366, 878, 238, 750, 494, 1006, + 30, 542, 286, 798, 158, 670, 414, 926, + 94, 606, 350, 862, 222, 734, 478, 990, + 62, 574, 318, 830, 190, 702, 446, 958, + 126, 638, 382, 894, 254, 766, 510, 1022 +}; + +const Word16 Gamma_19661_Tbl_fx[] = +{ + 19661, 11797, 7078, 4247, 2548, 1529, 917, 550, 330, 198, 119, 71, 43, 26, 16, 10 +};/*Q15 */ + +const Word16 Gamma_29491_Tbl[] = +{ + 29491, 26542, 23888, 21499, 19349, 17414, 15672, 14105, + 12694, 11425, 10282, 9254, 8329, 7496, 6746, 6071 +}; + +/*---------------------------------------------------------------------* + * NB post-filter tables + *---------------------------------------------------------------------*/ + +const Word16 Tab_hup_s[SIZ_TAB_HUP_S] = +{ + -188, 2873, 31650, -1597, -484, 7041, 28469, -2147, -933, 12266, + 23705, -1992, -1492, 18050, 18050, -1492, -1992, 23705, 12266, -933, + -2147, 28469, 7041, -484, -1597, 31650, 2873, -188 +}; + +const Word16 Tab_hup_l[SIZ_TAB_HUP_L] = +{ + -40, 72, -156, 315, -579, 1023, -1874, 4439, + 31915, -3390, 1595, -887, 501, -266, 130, -59, + -77, 147, -317, 631, -1150, 2030, -3773, 9639, + 29436, -5579, 2727, -1527, 859, -453, 218, -101, + -106, 212, -455, 892, -1614, 2850, -5392, 15206, + 25569, -6549, 3303, -1860, 1041, -543, 258, -122, + -123, 253, -538, 1044, -1876, 3319, -6414, 20676, + 20676, -6414, 3319, -1876, 1044, -538, 253, -123, + -122, 258, -543, 1041, -1860, 3303, -6549, 25569, + 15206, -5392, 2850, -1614, 892, -455, 212, -106, + -101, 218, -453, 859, -1527, 2727, -5579, 29436, + 9639, -3773, 2030, -1150, 631, -317, 147, -77, + -59, 130, -266, 501, -887, 1595, -3390, 31915, + 4439, -1874, 1023, -579, 315, -156, 72, -40 +}; + +const Word16 mfreq_loc_Q2fx[] = { 700, 1500, 3100, 4700, 6300, 7900, 9500, 11100, 12700, 14300, 15900, 17500, 19100, 20700, 22300, 25500, 28700, 31900 }; +const Word16 mfreq_loc_div_25[] = { 7, 15, 31, 47, 63, 79, 95, 111, 127, 143, 159, 175, 191, 207, 223, 255, 287, 319 }; + +//low_rate_band_att_fx.c +/* %* lowered Table ROM, call with band_len_idx[sfm_size>>3] */ +/* % sfms =[ 8, 16, 24, 32, 48, 64, 80, 96 ], */ +/* sfm/8= [ 1 2 3 4 6 8 10 12]; */ +/* % idx= 0 1 2 3 4 5 6 7; */ +/* call with band_len_idx[sfm_size>>3] */ +const Word16 band_len_idx[1 + (MAX_SFM_LEN_FX / 8)] = +{ + /*sfm/8*/ /*1*/ /*2 */ /*3 */ /*4 */ /*6 */ /*8 */ /*10*/ /*12*/ + -1 , 0/*8*/, 1/*16*/,2/*24*/,3/*32*/,-1, 4/*48 */,-1, 5/*64 */,-1, 6/*80*/,-1, 7/*96*/ +}; +const Word16 band_len_ener_shift[8] = { 1, 2, 2, 2, 3, 3 , 4/*sfm==80*/, 4 /*sfm==96*/ }; /* 96 requires 1 bit more than 48 */ +/*% sfms=[8,16,24,32,48,64,80,96], round(sqrt(sfms)*2^11) */ +const Word16 fine_gain_pred_sqrt_bw[8] = { 5793, 8192, 10033, 11585, 14189, 16384, 18318 , 20066 }; /* (Q11) */ +/*----------------------------------------------------------------------------------* + * means of ISFs for WB active speech + *----------------------------------------------------------------------------------*/ +const Word16 Mean_isf_wb[M] = /* G722.2 active speech ISF's means */ +{ + 738, 1326, 2336, 3578, 4596, 5662, 6711, 7730, + 8750, 9753,10705, 11728, 12833, 13971,15043, 4037 +}; + +const Word16 lsp_shb_prev_tbl_fx[LPC_SHB_ORDER] = +{ + /*Q15 */ + 0, + 1638, + 3277, + 4915, + 6554, + 8192, + 9830, + 11469, + 13107, + 14746 +}; + +/* These words are subtracted from high/low/value with a shift left by 1. */ +/* The value 0x0CCC should never be referenced, low is less/equal high */ +/* The value 0x0BBB should never be referenced, loop must break instead. */ +/* Refer to this table with indices: tab_ari_qnew[msb_high][msb_low] */ +const +Word16 tab_ari_qnew[4][4] = { { 0x0000, 0x0CCC, 0x0CCC, 0x0CCC }, + { 0x0000, 0x0000, 0x0CCC, 0x0CCC }, + { 0x0BBB, 0x2000, 0x4000, 0x0CCC }, + { 0x0BBB, 0x0BBB, 0x4000, 0x4000 } +}; + +const Word16 phs_tbl_dec[64 * 2] = +{ + /* part of table that is not scaled by 2 */ + 16384, 0, 16305, -1606, 16069, -3196, 15678, -4756, 15136, -6270, + 14449, -7723, 13622, -9102, 12665, -10394, 11585, -11585, 10394, -12665, + 9102, -13622, 7723, -14449, 6270, -15136, 4756, -15678, 3196, -16069, + 1606, -16305, 0, -16384, -1606, -16305, -3196, -16069, -4756, -15678, + -6270, -15136, -7723, -14449, -9102, -13622, -10394, -12665, -11585, -11585, + -12665, -10394, -13622, -9102, -14449, -7723, -15136, -6270, -15678, -4756, + -16069, -3196, -16305, -1606, + /* part of table that is scaled by 2 (this save one operation in FFT inner loops) */ + 32767, 0, 32610, -3212, 32138, -6392, 31356, -9512, 30272, -12540, + 28898, -15446, 27244, -18204, 25330, -20788, 23170, -23170, 20788, -25330, + 18204, -27244, 15446, -28898, 12540, -30272, 9512, -31356, 6392, -32138, + 3212, -32610, 0, -32768, -3212, -32610, -6392, -32138, -9512, -31356, + -12540, -30272, -15446, -28898, -18204, -27244, -20788, -25330, -23170, -23170, + -25330, -20788, -27244, -18204, -28898, -15446, -30272, -12540, -31356, -9512, + -32138, -6392, -32610, -3212 +}; + +/* 2.0 - 6.4 kHz phase dispersion */ +const Word16 Low_H_phasedisp[L_SUBFR] = +{ + 16389, 16381, 16386, 16382, 16382, 16383, 16381, 16384, 16385, 10265, + 10154, 9894, 14052, 16343, -531, 13216, 16373, 15510, 9407, 15949, + 4726, 14593, 10404, 9796, -16336, -1815,-10623, 12647, 14556,-12683, + 11389, 8176, 16382,-14197, 11781, 10379, 7516, 10424,-12472, 16285, + -1200,-13137, 12659, -7446, 15684, -3763,-13418, -5280, 521, -9685, + -16375, -1219, 8436,-13059, -12861,-12775, 0, 3, 0, -2, + -1, -1, -1, 2 +}; + +/* 3.2 - 6.4 kHz phase dispersion */ +const Word16 Mid_H_phasedisp[L_SUBFR] = +{ + 16382, 16382, 16384, 16385, 16386, 16388, 16387, 16383, 16387, 16383, + 16386, 16386, 16386, 16384, 16382, 16388, 14847, 9629, 13249, 14487, + 10995, 643, 13818, 13779, 6468, 8665, 11634, 9781,-14636, -982, + 11746, -722, 16386,-16365, -11422, 16354, 7363, 13148,-11538,-13903, + -15051, -8862, 8812,-16371, -12146, 7661, -9637,-13253, -6922, 4, + -4, -1, -5, 1, 7, 6, -7, -1, 4, -4, + 0, -1, -3, 3 +}; + +//ACcontextMapping_dec_fx.c +const Word16 Tab_esc_nb[4] = { 0 << (NBITS_CONTEXT + NBITS_RATEQ), + 1 << (NBITS_CONTEXT + NBITS_RATEQ), + 2 << (NBITS_CONTEXT + NBITS_RATEQ), + 3 << (NBITS_CONTEXT + NBITS_RATEQ) +}; + +const Word16 pow2tab[15] = { 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000 }; + +//d_gain2p.c +const Word16 Es_pred_qua[8] = +{ + 1521/* 5.9422f Q8*/, + 3909/*15.2711f Q8*/, + 5987/*23.3857f Q8*/, + 7816/*30.5310f Q8*/, + 9477/*37.0190f Q8*/, + 11124/*43.4539f Q8*/, + 12863/*50.2442f Q8*/, + 15031/*58.7164f Q8*/ +}; + +const Word16 Es_pred_qua_2[16] = +{ + -1280/*-5.f Q8*/, + 0/* 0.f Q8*/, + 1280/* 5.f Q8*/, + 2560/*10.f Q8*/, + 3840/*15.f Q8*/, + 5120/*20.f Q8*/, + 6400/*25.f Q8*/, + 7680/*30.f Q8*/, + 8960/*35.f Q8*/, + 10240/*40.f Q8*/, + 11520/*45.f Q8*/, + 12800/*50.f Q8*/, + 14080/*55.f Q8*/, + 15360/*60.f Q8*/, + 16640/*65.f Q8*/, + 17920/*70.f Q8*/ +}; +const Word16 T_DIV_L_Frame[] = /*0Q15 * 2^-7 */ +{ + 26214 /*160*/ + ,16384 /*256*/ + ,13107 /*320*/ + ,8738 /*480*/ + ,8192 /*512*/ + ,6553 /*640*/ +}; \ No newline at end of file diff --git a/lib_com/rom_com.h b/lib_com/rom_com.h index 6f02594721c8d4258526fa073163ea2b3248849d..5cf66078c3ca683e9650c571d7bc60553085077c 100644 --- a/lib_com/rom_com.h +++ b/lib_com/rom_com.h @@ -46,6 +46,7 @@ #define MINSFTAB 7 #define MAXSFTAB 25 +#define INTERP_EXP 0 typedef struct { int32_t fin; /* input frequency */ @@ -157,7 +158,7 @@ extern const uint8_t ACELP_GAINS_BITS[10]; extern const uint8_t ACELP_BPF_MODE[RATE_MODE_MAX][BANDWIDTH_MODE_MAX][ACELP_MODE_MAX + RF_MODE_MAX]; extern const uint8_t ACELP_BPF_BITS[3]; - +extern const Word16 ACELP_CDK_BITS[]; /*----------------------------------------------------------------------------------* * Pre-processing @@ -165,7 +166,6 @@ extern const uint8_t ACELP_BPF_BITS[3]; extern const float inv_tbl[]; /* Table of 1/x values */ extern const Word16 inv_tbl_fx[]; -extern const Word32 dicn_fx[40]; extern const Word16 hvq_bwe_fac_fx[16]; extern const Word16 sqac_headroom_fx[146]; @@ -183,16 +183,23 @@ extern const Resampling_cfg resampling_cfg_tbl[]; /* table of resampling configu extern const FrameSizeParams FrameSizeConfig[FRAME_SIZE_NB]; extern const float h_high[]; /* HP filter for filtering random part of excitation in FEC */ +extern const Word16 h_high_fx[5]; extern const float crit_bands[]; /* Table of critical bands */ extern const float sincos_t[]; /* FFT - sinus and cosinus tables */ extern const Word16 sincos_t_fx[161]; extern const float sincos_t_ext[]; +extern const Word16 sincos_t_ext_fx[]; extern const float sincos_t_rad3[]; extern const Word16 sincos_t_rad3_fx[]; extern const int16_t fft256_read_indexes[]; /* FFT */ extern const float inter4_2[]; /* 1/4 resolution interpolation filter */ +extern const Word16 inter4_2_fx[]; +extern const Word16 pitch_inter4_1[UP_SAMP * L_INTERPOL1 + 1]; /*1Q14*/ +extern const Word16 pitch_inter4_2[PIT_FIR_SIZE2]; /*1Q14*/ extern const float LP_assym_window[]; /* Assymetric window for LP analysis @12.8kHz */ extern const float LP_assym_window_16k[]; /* Assymetric window for LP analysis @16kHz */ +extern const Word16 Assym_window_W16fx[]; +extern const Word16 assym_window_16k_fx[]; extern const float hamcos_window[]; /* Hamming-Cosinus window */ extern const float grid50[]; /* Table of grid points for evaluating Chebyshev polynomials */ extern const float grid40[]; /* Table of grid points for evaluating Chebyshev polynomials */ @@ -224,6 +231,7 @@ extern const Word16 lag_window_48k[2][16]; extern const float interpol_frac2[]; /* LPC interpolation coefficients for two-subframe mode */ extern const float interpol_frac2_mid[]; /* LPC interpolation coefficients with mid-ISFs for two-subframe mode */ extern const float interpol_frac_12k8[]; /* LPC interpolation coefficients */ +extern const Word16 interpol_frac_fx[NB_SUBFR]; extern const float interpol_isp_amr_wb[]; /* LPC interpolation coefficients for AMR-WB interoperable mode */ extern const Word16 interpol_isp_amr_wb_fx[]; @@ -248,12 +256,22 @@ extern const float interpol_frac_mid_relaxprev_pred_16k[]; extern const Word16 interpol_frac_mid_relaxprev_pred_16k_fx[NB_SUBFR16k * 3]; extern const float inter6_2[PIT_FIR_SIZE6_2]; -extern const float inter4_2tcx2[4][4]; -extern const float inter6_2tcx2[6][4]; -typedef struct TCX_LTP_FILTER +extern const Word16 pitch_inter6_2[PIT_FIR_SIZE6_2]; /*1Q14*/ + +extern const float inter4_2tcx2_flt[4][4]; +extern const float inter6_2tcx2_flt[6][4]; +extern const Word16 inter4_2tcx2[4][4]; +extern const Word16 inter6_2tcx2[6][4]; +typedef struct TCX_LTP_FILTER_FLT { const float *filt; int16_t length; +} TCX_LTP_FILTER_FLT; +extern const TCX_LTP_FILTER_FLT tcxLtpFilters_flt[12]; +typedef struct TCX_LTP_FILTER +{ + const Word16 *filt; + Word16 length; } TCX_LTP_FILTER; extern const TCX_LTP_FILTER tcxLtpFilters[12]; @@ -261,18 +279,35 @@ extern const float gain_qua_mless_7b[]; /* Gain quantization - gain quant extern const float gain_qua_mless_6b_stereo[]; /* Gain quantization - gain quantization table in IVAS */ extern const float gain_qua_mless_6b[]; /* Gain quantization - gain quantization table */ extern const float gain_qua_mless_5b[]; /* Gain quantization - gain quantization table */ +extern const Word16 gain_qua_mless_7b_fx[]; +extern const Word16 gain_qua_mless_6b_fx[]; +extern const Word16 gain_qua_mless_5b_fx[]; + extern const float pred_gain[]; /* Gain quantization - MA predicition coefficients for gain quantizer */ extern const float t_qua_gain6b[]; /* Gain quantization - gain quantization table for AMR-WB interoperable mode */ extern const float t_qua_gain7b[]; /* Gain quantization - gain quantization table for AMR-WB interoperable mode */ +extern const Word16 pred_gain_fx[GAIN_PRED_ORDER]; +extern const Word16 t_qua_gain6b_fx[64 * 2]; +extern const Word16 t_qua_gain7b_fx[128 * 2]; + extern const float Es_pred_qua_5b[]; /* Gain quantization - quantization table for scaled innovation energy prediciton */ extern const float Es_pred_qua_4b[]; /* Gain quantization - quantization table for scaled innovation energy prediciton */ extern const float Es_pred_qua_3b[]; /* Gain quantization - quantization table for scaled innovation energy prediciton */ extern const float Es_pred_qua_4b_no_ltp[]; /* Gain quantization - quantization table for scaled innovation energy prediciton */ +extern const Word16 Es_pred_qua_5b_fx[32]; +extern const Word16 Es_pred_qua_4b_fx[16]; +extern const Word16 Es_pred_qua_3b_fx[8]; +extern const Word16 Es_pred_qua_4b_no_ltp_fx[16]; extern const float b_1sfr[]; /* Gain quantization - gain estimation constants for gain quantizer at 7.2 and 8.0 kbps */ extern const float b_2sfr[]; /* Gain quantization - gain estimation constants for gain quantizer at 7.2 and 8.0 kbps */ extern const float b_3sfr[]; /* Gain quantization - gain estimation constants for gain quantizer at 7.2 and 8.0 kbps */ extern const float b_4sfr[]; /* Gain quantization - gain estimation constants for gain quantizer at 7.2 and 8.0 kbps */ +extern const Word16 b_1sfr_fx[]; +extern const Word16 b_2sfr_fx[]; +extern const Word16 b_3sfr_fx[]; +extern const Word16 b_4sfr_fx[]; + extern const float gp_gamma_1sfr_8b[]; /* Gain quantization - gain quantization table for gain quantizer at 7.2 and 8.0 kbps */ @@ -286,6 +321,15 @@ extern const float gp_gamma_2sfr_6b[]; /* Gain quantization - gain quantization extern const float gp_gamma_3sfr_6b[]; /* Gain quantization - gain quantization table for gain quantizer at 7.2 and 8.0 kbps */ extern const float gp_gamma_4sfr_6b[]; /* Gain quantization - gain quantization table for gain quantizer at 7.2 and 8.0 kbps */ +extern const Word16 gp_gamma_1sfr_8b_fx[]; +extern const Word16 gp_gamma_1sfr_7b_fx[]; +extern const Word16 gp_gamma_1sfr_6b_fx[]; +extern const Word16 gp_gamma_2sfr_7b_fx[]; +extern const Word16 gp_gamma_2sfr_6b_fx[]; +extern const Word16 gp_gamma_3sfr_6b_fx[]; +extern const Word16 gp_gamma_4sfr_6b_fx[]; + + extern const int16_t E_ROM_qua_gain5b_const[]; extern const int16_t E_ROM_qua_gain6b_const[]; extern const int16_t E_ROM_qua_gain7b_const[]; @@ -293,8 +337,12 @@ extern const int16_t E_ROM_qua_gain7b_const[]; extern const float gain_qua_mless[]; extern const float tbl_gain_code_tc[]; /* TC - code gain quantization table */ +extern const Word16 tbl_gain_code_tc_fx[N_GAIN_CODE_TC]; + extern const float tbl_gain_trans_tc[]; /* TC - gain quantization table for g_trans */ extern const float glottal_cdbk[]; /* TC - table of prototype glottal impulses */ +extern const Word16 tbl_gain_trans_tc_fx[]; +extern const Word16 Glottal_cdbk_fx[]; extern const int32_t PI_select_table[23][8]; /* selection table for Pulse indexing */ extern const int32_t PI_offset[8][8]; /* offset table for Pulse indexing */ @@ -309,21 +357,31 @@ extern const int16_t index_mask_ACELP[3]; extern const float deem_tab[]; /* HF BWE - de-emphasis coefficients */ +extern const Word16 deem_tab_fx[]; extern const float filt_hp[]; +extern const Word16 filt_hp_fx[]; extern const float exp_tab_p[]; /* HF BWE - Table of values exp(-j*w*i) */ +extern const Word16 exp_tab_p_fx[]; extern const float exp_tab_q[]; /* HF BWE - Table of values exp(-j*w*i) */ +extern const Word16 exp_tab_q_fx[]; extern const float HP_gain[]; /* HF BWE - quantization table for 23.85 */ +extern const Word16 HP_gain_fx[]; extern const float fir_6k_8k[]; /* HF BWE - band-pass filter coefficients */ extern const float b_hp400[]; /* HF (6-7kHz) BWE - 400Hz HP filter coefficients */ extern const float a_hp400[]; /* HF (6-7kHz) BWE - 400Hz HP filter coefficients */ extern const float fir_6k_7k[]; /* HF (6-7kHz) BWE - 6.0 - 7.0 kHz BP filter coefficients */ +extern const Word16 fir_6k_7k_fx[]; extern const Word16 no_lead_fx[][MAX_NO_SCALES * 2]; extern const Word16 no_lead_p_fx[][MAX_NO_SCALES * 2]; -extern const float low_H[]; /* Enhacer - 2.0 - 6.4 kHz impulse response with phase dispersion */ -extern const float mid_H[]; /* Enhancer - 3.2 - 6.4 kHz impulse response with phase dispersion */ +extern const float low_H_flt[]; /* Enhacer - 2.0 - 6.4 kHz impulse response with phase dispersion */ +extern const float mid_H_flt[]; /* Enhancer - 3.2 - 6.4 kHz impulse response with phase dispersion */ +extern const Word16 low_H[64]; +extern const Word16 low_H16k[80]; +extern const Word16 mid_H[64]; +extern const Word16 mid_H16k[80]; extern const float filt_lp[1 + L_FILT]; extern const float filt_lp_16kHz[1 + L_FILT16k]; @@ -346,19 +404,49 @@ extern const float edct_table_240[]; extern const float edct_table_256[]; extern const float edct_table_400[]; extern const float edct_table_600[]; /* EDCT */ +extern const Word16 edct_table_80_fx[]; /* EDCT */ +extern const Word16 edct_table_120_fx[]; /* EDCT */ +extern const Word16 edct_table_100_fx[]; /* EDCT */ +extern const Word16 edct_table_320_fx[]; /* EDCT */ +extern const Word16 edct_table_480_fx[]; /* EDCT */ +extern const Word16 edct_table_600_fx[]; /* EDCT */ +extern const Word16 edct_table_128_fx[]; /* EDCT */ +extern const Word16 edct_table_160_fx[]; /* EDCT */ +extern const Word16 edct_table_40_fx[]; /* EDCT */ +extern const Word16 edct_table_20_fx[]; /* EDCT */ +extern const Word16 edct_table_64_fx[]; +extern const Word16 edct_table_200_fx[]; +extern const Word16 edct_table_240_fx[]; +extern const Word16 edct_table_256_fx[]; +extern const Word16 edct_table_400_fx[]; +extern const Word16 edct_table_160_16fx[160]; +extern const Word16 edct_table_128_16fx[128]; +extern const Word16 edct_table_320_16fx[320]; + extern const int16_t crit_bins[]; /* (used only in AMR-WB IO mode) */ extern const float crit_bins_corr[CRIT_NOIS_BAND]; +extern const Word16 crit_bins_corr_fx[]; extern const float crit_bands_loc[]; /* (used only in AMR-WB IO mode) */ +extern const Word16 crit_bands_loc_fx[]; extern const float mfreq_loc_LD[]; /* LD music post-filter */ +extern const Word16 mfreq_loc_LD_fx[]; extern const int16_t mfreq_bindiv_LD[]; extern const float post_dct_wind[OFFSET2]; +extern const Word16 post_dct_wind_fx[]; extern const float MAX_SNR_SNR1_tab[]; extern const float INV_MAX_SNR_tab[]; +extern const Word16 MAX_SNR_SNR1_tab_FX[MBANDS_GN_LD]; +extern const Word16 INV_MAX_SNR_tab_FX[MBANDS_GN_LD]; extern const float sc_qnoise[]; - +extern const Word16 sc_qnoise_fx[]; +extern const Word16 inv_mfreq_bindiv_LD_fx[]; +extern const Word16 inv_mfreq_bindiv_LD_M1_fx[]; extern const float W_DTX_HO[HO_HIST_SIZE]; +extern const Word16 W_DTX_HO_FX[HO_HIST_SIZE]; extern const float ENR_ATT[5]; +extern const Word16 ENR_ATT_fx[5]; + extern const float HO_ATT[5]; extern const int16_t hq_swb_bwe_nb_bits[]; @@ -437,10 +525,10 @@ extern const float dico5_cng_ev[]; extern const float stable_ISP[]; extern const float stable_LSP[]; -#ifdef IVAS_FLOAT_FIXED -extern const Word16 stable_LSP_fx[]; -#endif extern const float stable_ISF[]; +extern const Word16 stable_ISP_fx[]; +extern const Word16 stable_ISF_fx[]; +extern const Word16 stable_LSP_fx[]; extern const float UVWB_Ave[]; extern const float UVNB_Ave[]; @@ -453,9 +541,25 @@ extern const float GEWB_Ave[]; extern const float GEWB2_Ave[]; extern const float TRWB_Ave[]; extern const float TRWB2_Ave[]; -extern const float means_wb_cleanspeech_lsf16k0[]; -extern const float means_swb_cleanspeech_lsf25k6[]; -extern const float means_swb_cleanspeech_lsf32k0[]; +extern const Word16 UVWB_Ave_fx[]; +extern const Word16 UVNB_Ave_fx[]; +extern const Word16 SVWB_Ave_fx[]; +extern const Word16 SVNB_Ave_fx[]; +extern const Word16 IANB_Ave_fx[]; +extern const Word16 IAWB_Ave_fx[]; +extern const Word16 IAWB2_Ave_fx[]; +extern const Word16 GENB_Ave_fx[]; +extern const Word16 GEWB_Ave_fx[]; +extern const Word16 GEWB2_Ave_fx[]; +extern const Word16 TRWB_Ave_fx[]; +extern const Word16 TRWB2_Ave_fx[]; + +extern const float means_wb_cleanspeech_lsf16k0_flt[]; +extern const float means_swb_cleanspeech_lsf25k6_flt[]; +extern const float means_swb_cleanspeech_lsf32k0_flt[]; +extern const Word16 means_wb_cleanspeech_lsf16k0[]; +extern const Word16 means_swb_cleanspeech_lsf25k6[]; +extern const Word16 means_swb_cleanspeech_lsf32k0[]; extern const float ModeMean12[]; extern const float Predictor0[]; @@ -467,12 +571,24 @@ extern const float Predictor5[]; extern const float Predictor6[]; extern const float Predictor7[]; extern const float Predictor8[]; -extern const float CNG_SN1[]; +extern const Word16 Predictor0_fx[]; +extern const Word16 Predictor1_fx[]; +extern const Word16 Predictor2_fx[]; +extern const Word16 Predictor3_fx[]; +extern const Word16 Predictor4_fx[]; +extern const Word16 Predictor5_fx[]; +extern const Word16 Predictor6_fx[]; +extern const Word16 Predictor7_fx[]; +extern const Word16 Predictor8_fx[]; +extern const float CNG_SN1[]; +extern const Word16 CNG_SN1_fx[]; extern const int16_t CB_lsf[]; extern const int16_t CB_p_lsf[]; extern const float *const ModeMeans[]; extern const float *const Predictors[]; +extern const Word16 * const ModeMeans_fx[]; +extern const Word16 * const Predictors_fx[]; extern const int16_t CBsizes[]; extern const int16_t CBbits[]; @@ -595,14 +711,20 @@ extern const int16_t uniform_model[]; extern const float tbl_mid_gen_wb_2b[]; extern const float tbl_mid_gen_wb_4b[]; extern const float tbl_mid_gen_wb_5b[]; +extern const Word16 tbl_mid_gen_wb_2b_fx[]; +extern const Word16 tbl_mid_gen_wb_5b_fx[]; extern const float tbl_mid_unv_wb_4b[]; extern const float tbl_mid_unv_wb_5b[]; +extern const Word16 tbl_mid_unv_wb_4b_fx[]; +extern const Word16 tbl_mid_unv_wb_5b_fx[]; extern const float tbl_mid_voi_wb_1b[]; extern const float tbl_mid_voi_wb_4b[]; extern const float tbl_mid_voi_wb_5b[]; - +extern const Word16 tbl_mid_voi_wb_1b_fx[]; +extern const Word16 tbl_mid_voi_wb_4b_fx[]; +extern const Word16 tbl_mid_voi_wb_5b_fx[]; /*-----------------------------------------------------------------* * LSF quantization - Mode 2 quantization tables *-----------------------------------------------------------------*/ @@ -615,34 +737,61 @@ extern const Word16 means_nb_31bits_ma_lsf[16]; extern const Word16 means_wb_31bits_ma_lsf[16]; extern const Word16 *lsf_means[2]; -extern const float *const lsf_codebook[2][2][TCXLPC_NUMSTAGES]; +extern const float *const lsf_codebook_flt[2][2][TCXLPC_NUMSTAGES]; +extern const Word16 *const lsf_codebook[2][2][TCXLPC_NUMSTAGES]; extern const int16_t lsf_numbits[TCXLPC_NUMSTAGES]; -extern const int16_t lsf_dims[TCXLPC_NUMSTAGES]; -extern const int16_t lsf_offs[TCXLPC_NUMSTAGES]; - -extern const float dico_lsf_abs_8b[]; - -extern const float lsf_q_diff_cb_8b_rf[]; -extern const float lsf_cdk_nb_gc_stg1[]; -extern const float lsf_cdk_nb_gc_stg2[]; -extern const float lsf_cdk_nb_gc_stg3[]; -extern const float lsf_ind_cdk_nb_gc_stg4[]; -extern const float lsf_cdk_nb_vc_stg1[]; -extern const float lsf_cdk_nb_vc_stg2[]; -extern const float lsf_cdk_nb_vc_stg3[]; -extern const float lsf_ind_cdk_nb_vc_stg4[]; -extern const float lsf_cdk_wb_gc_stg1[]; -extern const float lsf_cdk_wb_gc_stg2[]; -extern const float lsf_cdk_wb_gc_stg3[]; -extern const float lsf_ind_cdk_wb_gc_stg4[]; -extern const float lsf_cdk_wb_vc_stg1[]; -extern const float lsf_cdk_wb_vc_stg2[]; -extern const float lsf_cdk_wb_vc_stg3[]; -extern const float lsf_ind_cdk_wb_vc_stg4[]; - -extern const float *const lsf_ind_codebook[2][2][TCXLPC_IND_NUMSTAGES]; +extern const int16_t lsf_dims_ivas[TCXLPC_NUMSTAGES]; +extern const int16_t lsf_offs_ivas[TCXLPC_NUMSTAGES]; +extern const Word16 lsf_dims[TCXLPC_NUMSTAGES]; +extern const Word16 lsf_offs[TCXLPC_NUMSTAGES]; + +extern const float dico_lsf_abs_8b_flt[]; +extern const Word16 dico_lsf_abs_8b[]; + +extern const float lsf_q_diff_cb_8b_rf_flt[]; +extern const Word16 lsf_q_diff_cb_8b_rf[]; + +extern const float lsf_cdk_nb_gc_stg1_flt[]; +extern const float lsf_cdk_nb_gc_stg2_flt[]; +extern const float lsf_cdk_nb_gc_stg3_flt[]; +extern const float lsf_ind_cdk_nb_gc_stg4_flt[]; +extern const float lsf_cdk_nb_vc_stg1_flt[]; +extern const float lsf_cdk_nb_vc_stg2_flt[]; +extern const float lsf_cdk_nb_vc_stg3_flt[]; +extern const float lsf_ind_cdk_nb_vc_stg4_flt[]; +extern const float lsf_cdk_wb_gc_stg1_flt[]; +extern const float lsf_cdk_wb_gc_stg2_flt[]; +extern const float lsf_cdk_wb_gc_stg3_flt[]; +extern const float lsf_ind_cdk_wb_gc_stg4_flt[]; +extern const float lsf_cdk_wb_vc_stg1_flt[]; +extern const float lsf_cdk_wb_vc_stg2_flt[]; +extern const float lsf_cdk_wb_vc_stg3_flt[]; +extern const float lsf_ind_cdk_wb_vc_stg4_flt[]; + +extern const Word16 lsf_cdk_nb_gc_stg1[]; +extern const Word16 lsf_cdk_nb_gc_stg2[]; +extern const Word16 lsf_cdk_nb_gc_stg3[]; +extern const Word16 lsf_ind_cdk_nb_gc_stg4[]; +extern const Word16 lsf_cdk_nb_vc_stg1[]; +extern const Word16 lsf_cdk_nb_vc_stg2[]; +extern const Word16 lsf_cdk_nb_vc_stg3[]; +extern const Word16 lsf_ind_cdk_nb_vc_stg4[]; +extern const Word16 lsf_cdk_wb_gc_stg1[]; +extern const Word16 lsf_cdk_wb_gc_stg2[]; +extern const Word16 lsf_cdk_wb_gc_stg3[]; +extern const Word16 lsf_ind_cdk_wb_gc_stg4[]; +extern const Word16 lsf_cdk_wb_vc_stg1[]; +extern const Word16 lsf_cdk_wb_vc_stg2[]; +extern const Word16 lsf_cdk_wb_vc_stg3[]; +extern const Word16 lsf_ind_cdk_wb_vc_stg4[]; + + + +extern const float *const lsf_ind_codebook_flt[2][2][TCXLPC_IND_NUMSTAGES]; +extern const Word16 *const lsf_ind_codebook[2][2][TCXLPC_IND_NUMSTAGES]; extern const int16_t lsf_ind_numbits[TCXLPC_IND_NUMSTAGES]; -extern const int16_t lsf_ind_dims[TCXLPC_IND_NUMSTAGES]; +extern const int16_t lsf_ind_dims_ivas[TCXLPC_IND_NUMSTAGES]; +extern const Word16 lsf_ind_dims[TCXLPC_IND_NUMSTAGES]; extern const int16_t lsf_ind_offs[TCXLPC_IND_NUMSTAGES]; extern const Word16 min_distance_thr[2][2]; @@ -677,7 +826,8 @@ extern const int16_t Da_nq[]; /* Codebook number for each absolute leader */ extern const int16_t skip_bands_SWB_TBE[]; /* bands for SWB TBE quantisation */ extern const int16_t skip_bands_WB_TBE[]; /* bands for WB TBE quantisation */ -extern const float interpol_frac_shb[]; +extern const float interpol_frac_shb_flt[]; +extern const Word16 interpol_frac_shb[NB_SUBFR * 2]; extern const float AP1_STEEP[]; /* All pass filter coeffs for interpolation and decimation by a factor of 2 */ extern const float AP2_STEEP[]; /* All pass filter coeffs for interpolation and decimation by a factor of 2 */ @@ -698,11 +848,15 @@ extern const Word16 win_flatten_fx[]; extern const float win_flatten_4k[]; /* Window for calculating whitening filter for WB excitation */ extern const Word16 win_flatten_4k_fx[]; extern const float window_shb[]; /* Overlap add window for SHB excitation used in anal and synth */ +extern const Word16 window_shb_fx[]; extern const float window_shb_32k[]; /* Upsampled overlap add window for SHB excitation used transition generation */ +extern const Word16 window_shb_32k_fx[]; extern const float subwin_shb[]; /* Short overlap add window for SHB excitation used in anal and synth */ +extern const Word16 subwin_shb_fx[]; /* Short overlap add window for SHB excitation used in anal and synth */ extern const float window_wb[]; extern const float subwin_wb[]; /* Short overlap add window for SHB excitation used in anal and synth */ - +extern const Word16 window_wb_fx[]; +extern const Word16 subwin_wb_fx[]; extern const float Hilbert_coeffs[4 * NUM_HILBERTS][HILBERT_ORDER1 + 1]; extern const Word16 Hilbert_coeffs_fx[4 * NUM_HILBERTS][HILBERT_ORDER1 + 1]; @@ -711,13 +865,19 @@ extern const float wac[]; extern const float wac_swb[]; extern const float wb_bwe_lsfvq_cbook_8bit[]; +extern const Word16 wb_bwe_lsfvq_cbook_8bit_fx[]; extern const float lbr_wb_bwe_lsfvq_cbook_2bit[]; -extern const float swb_tbe_lsfvq_cbook_8b[]; +extern const Word16 lbr_wb_bwe_lsfvq_cbook_2bit_fx[]; +extern const float swb_tbe_lsfvq_cbook_8b_flt[]; +extern const Word16 swb_tbe_lsfvq_cbook_8b[]; extern const float SHBCB_SubGain5bit[]; /* 5 bit Quantizer table for SHB gain shapes */ +extern const Word16 SHBCB_SubGain5bit_fx[]; extern const float HBCB_SubGain5bit[]; /* 5-bit TD WB BWE temporal shaping codebook */ +extern const Word16 HBCB_SubGain5bit_fx[]; extern const float SHBCB_FrameGain64[]; /* 6 bit Quantizer table for SHB overall gain */ +extern const Word32 SHBCB_FrameGain64_fx[]; extern const float SHBCB_FrameGain16[]; - +extern const Word32 SHBCB_FrameGain16_fx[]; extern const float full_band_bpf_1[][5]; extern const float full_band_bpf_2[][5]; extern const float full_band_bpf_3[][5]; @@ -728,17 +888,27 @@ extern const Word16 full_band_bpf_3_fx[][5]; extern const float lsf_q_cb_4b[]; /* 4 bit differential scalar quantizer table for TD SWB BWE LSFs 1 and 2*/ extern const float lsf_q_cb_3b[]; /* 3 bit differential scalar quantizer table for TD SWB BWE LSFs 3, 4 and 5*/ extern const float *const lsf_q_cb[]; /* Codebook array for each LSF */ +extern const Word16 * const lsf_q_cb_fx[]; extern const int16_t lsf_q_cb_size[]; /* Size of each element of the above */ extern const int16_t lsf_q_num_bits[]; /* Size of each element of the above, in bits */ extern const float mirror_point_q_cb[]; /* LSF mirroring point codebook */ +extern const Word16 mirror_point_q_cb_fx[]; extern const float lsf_grid[4][5]; /* LSF mirroring adjustment grid */ +extern const Word16 lsf_grid_fx[4][5]; extern const float grid_smoothing[]; /* LSF mirroring smoothing table */ +extern const Word16 grid_smoothing_fx[]; /* LSF mirroring smoothing table */ extern const float overlap_coefs[]; /* HR SWB BWE - overlap coefficients */ extern const float overlap_coefs_48kHz[]; /* HR SWB BWE - overlap coefficients @48kHz */ +extern const Word16 overlap_coefs_fx[NSV_OVERLAP*WIDTH_BAND]; /* in Q15 */ +extern const Word16 overlap_coefs_48kHz_fx[NSV_OVERLAP*WIDTH_BAND]; /* in Q15 */ + extern const float swb_hr_env_code1[]; /* HR SWB BWE - envelope Q table - first two subabnds in non-transient frames */ extern const float swb_hr_env_code2[]; /* HR SWB BWE - envelope Q table - second two subabnds in non-transient frames*/ extern const float swb_hr_env_code3[]; /* HR SWB BWE - envelope Q table - two subabnds in transient frames */ +extern const Word16 swb_hr_env_code1_fx[]; /* HR SWB BWE - envelope Q table - first two subabnds in non-transient frames */ +extern const Word16 swb_hr_env_code2_fx[]; /* HR SWB BWE - envelope Q table - second two subabnds in non-transient frames*/ +extern const Word16 swb_hr_env_code3_fx[]; /* HR SWB BWE - envelope Q table - two subands in transient frames */ extern const float allpass_poles_3_ov_2_flt[]; extern const Word16 allpass_poles_3_ov_2[]; @@ -751,7 +921,7 @@ extern const float decimate_3_ov_2_lowpass_den[]; *------------------------------------------------------------------------------*/ extern const float F_2_5[64]; - +extern const Word16 F_2_5_fx[64]; /*------------------------------------------------------------------------------* * SWB BWE tables *------------------------------------------------------------------------------*/ @@ -780,14 +950,25 @@ extern const float EnvCdbk1st[]; extern const float EnvCdbk2nd[]; extern const float EnvCdbk3rd[]; extern const float EnvCdbk4th[]; +extern const Word16 EnvCdbk11_fx[]; +extern const Word16 EnvCdbk1st_fx[]; +extern const Word16 EnvCdbk2nd_fx[]; +extern const Word16 EnvCdbk3rd_fx[]; +extern const Word16 EnvCdbk4th_fx[]; + extern const float EnvCdbkFB[]; +extern const Word16 EnvCdbkFB_fx[]; extern const float Env_TR_Cdbk1[]; extern const float Env_TR_Cdbk2[]; +extern const Word16 Env_TR_Cdbk1_fx[]; +extern const Word16 Env_TR_Cdbk2_fx[]; extern const float w_NOR[]; extern const float Mean_env[]; +extern const Word16 Mean_env_fx[]; extern const float Mean_env_fb[]; +extern const Word16 Mean_env_fb_fx[]; extern const float Mean_env_tr[]; - +extern const Word16 Mean_env_tr_fx[]; /*------------------------------------------------------------------------------* * ACEPL/HQ core switching tables *------------------------------------------------------------------------------*/ @@ -797,14 +978,18 @@ extern const float hp16000_32000[]; extern const float hp12800_48000[]; extern const float hp16000_48000[]; extern const float hp12800_16000[]; - +extern const Word16 hp12800_32000_fx[]; +extern const Word16 hp16000_32000_fx[]; +extern const Word16 hp12800_48000_fx[]; +extern const Word16 hp16000_48000_fx[]; +extern const Word16 hp12800_16000_fx[]; extern const double cu15[28][3]; extern const double cu4[6][3]; extern const Word16 cu15_fx[28][3]; extern const Word16 cu4_fx[6][3]; extern const int16_t ct2[7][13]; - +extern const Word16 ct2_fx[7][14]; /*------------------------------------------------------------------------------* * HQ core tables *------------------------------------------------------------------------------*/ @@ -823,11 +1008,20 @@ extern const float short_window_48kHz[]; extern const float short_window_32kHz[]; extern const float short_window_16kHz[]; extern const float short_window_8kHz[]; +extern const Word16 short_window_48kHz_fx[L_FRAME48k / 2 / 2]; +extern const Word16 short_window_32kHz_fx[L_FRAME32k / 2 / 2]; +extern const Word16 short_window_16kHz_fx[L_FRAME16k / 2 / 2]; +extern const Word16 short_window_8kHz_fx[L_FRAME8k / 2 / 2]; +extern const Word16 inv_jp2[]; extern const float wscw16q15[]; extern const float wscw16q15_8[]; extern const float wscw16q15_16[]; extern const float wscw16q15_32[]; +extern const Word16 wscw16q15_fx[]; +extern const Word16 wscw16q15_8_fx[]; +extern const Word16 wscw16q15_16_fx[]; +extern const Word16 wscw16q15_32_fx[]; /* Band structure */ extern const int16_t band_len_HQ[]; @@ -852,6 +1046,7 @@ extern const int16_t norm_order_32[SFM_N_SWB]; extern const int16_t norm_order_16[SFM_N_WB]; extern const float dicn_pg[45]; +extern const Word32 dicn_pg_fx[]; extern const int16_t expPkEnrg_tbl[45]; extern const int32_t manPkEnrg_tbl[45]; extern const int32_t E_max5_tbl[40]; @@ -859,6 +1054,7 @@ extern const int32_t E_max5_tbl[40]; extern const float thren_pg[44]; extern const float dicn[40]; +extern const Word32 dicn_fx[40]; extern const float dicn_inv[40]; extern const float thren_HQ[39]; extern const int16_t dicnlg2_float[40]; @@ -882,11 +1078,14 @@ extern const Word32 SQRT_DIM_fx[]; /* HQ inner_frame signallisation table */ extern const int16_t inner_frame_tbl[]; - +extern const Word16 hq_nominal_scaling_inv[]; +extern const Word16 hq_nominal_scaling[]; /* HQ spectrum length lookup tables */ extern const int16_t l_spec_tbl[]; extern const int16_t l_spec_ext_tbl[]; - +extern const Word16 sinq_16k[]; +extern const Word16 sinq_32k[]; +extern const Word16 sinq_48k[]; /* NB short win: 7200/8000/9600, 13200/16400 */ extern const int16_t band_width_40_4_6_0_0_0[4]; extern const int16_t band_width_40_5_6_0_0_0[5]; @@ -1134,6 +1333,7 @@ extern const Word16 UVG2CB1_NB_FX[UVG2_CBSIZE][5]; extern const Word16 UVG2CB2_NB_FX[UVG2_CBSIZE][5]; extern const float frac_4sf[NB_SUBFR + 2]; +extern const Word16 frac_4sf_fx[NB_SUBFR + 2]; extern const float erb_WB[NUM_ERB_WB + 1]; extern const float erb_NB[NUM_ERB_NB + 1]; @@ -1154,11 +1354,14 @@ extern const Word16 AmpCB2_NB_fx[64 * (NUM_ERB_NB - 13)]; extern const float PowerCB_WB[64][2]; extern const float PowerCB_NB[64][2]; +extern const Word16 PowerCB_WB_fx[128]; +extern const Word16 PowerCB_NB_fx[128]; extern const float sinc[8][12]; extern const Word16 sinc_fx[8][12]; extern const float hvq_thr_adj[5]; extern const float hvq_peak_cb[1024]; +extern const Word16 hvq_peak_cb_fx[]; extern const float hvq_class_c[16]; extern const int16_t hvq_cb_search_overlap24k[17]; extern const int16_t hvq_cb_search_overlap32k[21]; @@ -1180,19 +1383,19 @@ extern const int16_t hvq_cp_huff_tab[52]; *------------------------------------------------------------------------------*/ extern const float sin_table256[]; - +extern const Word16 sin_table256_fx[]; extern const int16_t gsc_sfm_start[]; extern const int16_t gsc_sfm_end[]; extern const int16_t gsc_sfm_size[]; extern const float sm_table[]; - +extern const Word16 sm_table_fx[]; extern const float mfreq_loc[]; extern const int16_t mfreq_bindiv_loc[]; extern const float mean_gp[]; extern const float dic_gp[]; - +extern const Word16 dic_gp_fx[]; extern const float Gain_mean[]; extern const float Gain_meanHR[]; extern const float Gain_mean_dic[]; @@ -1235,6 +1438,7 @@ extern const float YG_dicHR_4_16kHz[]; extern const float YG_meanL2G_16kHz[]; extern const float YG_dicL2G_16kHz[]; extern const int16_t GSC_freq_bits[]; +extern const Word32 GSC_freq_bits_fx[]; extern const int16_t GSC_freq_DL0_bits[]; extern const int16_t Compl_GSC_freq_bits[]; extern const float Gain_meanNB[]; @@ -1259,6 +1463,7 @@ extern const float w_fft64[32]; extern const int16_t Ip_fft64[6]; extern const int16_t Odx_fft32_15[32]; extern const float w_fft32[16]; +extern const Word32 w_fft32_16fx[16]; extern const int16_t Ip_fft32[6]; extern const int16_t Odx_fft32_5[32]; extern const int16_t Odx_fft16[16]; @@ -1273,14 +1478,18 @@ extern const int16_t Idx_dortft320[320]; extern const int16_t Idx_dortft480[480]; extern const int16_t Ip_fft128[10]; extern const float w_fft128[64]; +extern const Word32 w_fft128_16fx[64]; extern const int16_t Ip_fft256[10]; extern const float w_fft256[128]; extern const int16_t Ip_fft512[18]; extern const float w_fft512[256]; +extern const Word16 w_fft512_fx_evs[256]; +//extern const Word16 w_fft512_fx[256]; extern const int16_t Idx_dortft40[40]; extern const int16_t Odx_fft8_5[8]; extern const int16_t ip_edct2_64[6]; extern const float w_edct2_64[80]; +extern const Word16 w_edct2_64_fx[80]; extern const int16_t Idx_dortft20[20]; extern const int16_t Odx_fft4_5[4]; extern const float w_fft4[2]; @@ -1301,10 +1510,15 @@ extern const float FFT_RotVector_960[1860]; extern const float Asr_LP32[41]; extern const float Asr_LP16[21]; extern const float Asr_LP48[61]; +extern const Word16 Asr_LP32_fx[41]; +extern const Word16 Asr_LP16_fx[21]; +extern const Word16 Asr_LP48_fx[61]; extern const int16_t Num_bands_NB[]; extern const float SmoothingWin_NB875[]; extern const float SmoothingWin_NB2[]; +extern const Word16 SmoothingWin_NB875_fx[]; +extern const Word16 SmoothingWin_NB2_fx[]; /*----------------------------------------------------------------------------------* * CLDFB @@ -1312,13 +1526,13 @@ extern const float SmoothingWin_NB2[]; extern const int16_t freqTable[2]; -extern const float CLDFB80_10[100]; -extern const float CLDFB80_16[160]; -extern const float CLDFB80_20[200]; -extern const float CLDFB80_30[300]; -extern const float CLDFB80_32[320]; -extern const float CLDFB80_40[400]; -extern const float CLDFB80_60[600]; +extern const float CLDFB80_10_flt[100]; +extern const float CLDFB80_16_flt[160]; +extern const float CLDFB80_20_flt[200]; +extern const float CLDFB80_30_flt[300]; +extern const float CLDFB80_32_flt[320]; +extern const float CLDFB80_40_flt[400]; +extern const float CLDFB80_60_flt[600]; /*5ms delay*/ extern const float LDQMF_10[100]; @@ -1346,6 +1560,35 @@ extern const float rot_vec_ana_im_L40[20]; extern const float rot_vec_ana_re_L60[30]; extern const float rot_vec_ana_im_L60[30]; +extern const Word16 CLDFB80_10[100]; +extern const Word16 CLDFB80_16[160]; +extern const Word16 CLDFB80_20[200]; +extern const Word16 CLDFB80_32[320]; +extern const Word16 CLDFB80_40[400]; +extern const Word16 CLDFB80_60[600]; + + +extern const Word16 rRotVectr_10[]; +extern const Word16 iRotVectr_10[]; +extern const Word16 rRotVectr_16[]; +extern const Word16 iRotVectr_16[]; +extern const Word16 rRotVectr_20[]; +extern const Word16 iRotVectr_20[]; +extern const Word16 rRotVectr_32[]; +extern const Word16 iRotVectr_32[]; +extern const Word16 rRotVectr_40[]; +extern const Word16 iRotVectr_40[]; +extern const Word16 rRotVectr_60[]; +extern const Word16 iRotVectr_60[]; + +extern const Word16 cldfb_anaScale[]; +extern const Word16 cldfb_synScale[]; +extern const Word16 cldfb_synGain[]; +extern const Word16 *cldfb_protoFilter_2_5ms[]; +extern const Word16 cldfb_scale_2_5ms[7]; + + + extern const float rot_vec_syn_re_L10[5]; extern const float rot_vec_syn_im_L10[5]; extern const float rot_vec_syn_re_L16[8]; @@ -1362,8 +1605,10 @@ extern const float rot_vec_syn_re_L60[30]; extern const float rot_vec_syn_im_L60[30]; extern const float bpf_weights_16[CLDFB_NO_COL_MAX]; +extern const Word16 bpf_weights_16_Fx[16]; extern const float CNG_details_codebook[64][NUM_ENV_CNG]; +extern const Word16 CNG_details_codebook_fx[64][NUM_ENV_CNG]; /*----------------------------------------------------------------------------------* @@ -1371,15 +1616,19 @@ extern const float CNG_details_codebook[64][NUM_ENV_CNG]; *----------------------------------------------------------------------------------*/ extern const int16_t d_array[SIZE_SCALE_TABLE_CN]; -extern const float m_array[SIZE_SCALE_TABLE_CN]; -extern const float msQeqInvAv_thresh[3]; -extern const float msNoiseSlopeMax[4]; +extern const float m_array_flt[SIZE_SCALE_TABLE_CN]; +extern const Word16 m_array[SIZE_SCALE_TABLE_CN]; +extern const float msQeqInvAv_thresh_flt[3]; +extern const Word16 msQeqInvAv_thresh[3]; +extern const float msNoiseSlopeMax_flt[4]; +extern const Word16 msNoiseSlopeMax[4]; extern const SCALE_SETUP scaleTableStereo[SIZE_SCALE_TABLE_STEREO]; extern const SCALE_SETUP scaleTableMono[SIZE_SCALE_TABLE_MONO]; extern const SCALE_SETUP scaleTable_cn_only[SIZE_SCALE_TABLE_CN]; extern const SCALE_SETUP scaleTable_cn_dirac[15]; -extern const float scaleTable_cn_only_amrwbio[SIZE_SCALE_TABLE_CN_AMRWB][2]; +extern const float scaleTable_cn_only_amrwbio_flt[SIZE_SCALE_TABLE_CN_AMRWB][2]; +extern const Word16 scaleTable_cn_only_amrwbio[SIZE_SCALE_TABLE_CN_AMRWB][2]; extern const int16_t sidparts_encoder_noise_est[SIZE_SIDPARTS_ENC_NOISE_EST]; @@ -1394,9 +1643,9 @@ extern const FD_CNG_SETUP FdCngSetup_swb2; extern const int16_t levels_37bits[FD_CNG_stages_37bits]; extern const int16_t bits_37bits[FD_CNG_stages_37bits]; -extern const float *const cdk_37bits[]; +extern const float *const cdk_37bits_flt[]; extern const float *const cdk_37bits_ivas[]; - +extern Word16 const * const cdk_37bits[]; extern const float fftSineTab640[321]; extern const float olapWinAna512[512]; @@ -1425,6 +1674,7 @@ extern const float cdk1r_tr_midQ_truncQ[]; extern const float fdcng_dct_invScaleF[]; extern const float fdcng_dct_scaleF[]; + extern const Word16 unique_idctT2_24coeffsQ16[]; extern const Word8 idctT2_24_compressed_idx[]; @@ -1454,8 +1704,10 @@ extern const float cdk_37bits_6[]; * TCX *----------------------------------------------------------------------------------*/ -extern const float gain_corr_fac[]; -extern const float gain_corr_inv_fac[]; +extern const float gain_corr_fac_flt[]; +extern const float gain_corr_inv_fac_flt[]; +extern const Word16 gain_corr_fac[]; /*pow(10,2^(-n-2)/28)*/ +extern const Word16 gain_corr_inv_fac[];/*pow(10,-2^(-n-2)/28)*/ extern const SCALE_TCX_SETUP scaleTcxTable[SIZE_SCALE_TABLE_TCX]; @@ -1623,7 +1875,8 @@ typedef struct igf_mode_type extern const IGF_MODE igfMode[IGF_BITRATE_UNKNOWN]; extern const int16_t swb_offset_LB_new[IGF_BITRATE_UNKNOWN][IGF_MAX_SFB]; extern const int16_t igf_tile_offset_table[IGF_BITRATE_UNKNOWN][2 * IGF_MAX_TILES + 1]; -extern const float igf_whitening_TH[IGF_BITRATE_UNKNOWN][2][IGF_MAX_TILES]; +extern const float igf_whitening_TH_flt[IGF_BITRATE_UNKNOWN][2][IGF_MAX_TILES]; +extern const Word16 igf_whitening_TH[][2][IGF_MAX_TILES]; extern const int16_t cf_off_se01_tab[10]; extern const int16_t cf_off_se10_tab; extern const int16_t cf_off_se02_tab[10][IGF_CTX_COUNT]; @@ -1647,8 +1900,11 @@ extern const Word16 sqrtTable[SQRT_TABLE_SIZE + 1]; extern const Word16 invSqrtTable[SQRT_TABLE_SIZE + 1]; extern const float tcx_mdct_window_48[420]; +extern const Word16 tcx_mdct_window_48_fx[420]; extern const float tcx_mdct_window_half_48[180]; +extern const Word16 tcx_mdct_window_half_48_fx[180]; extern const float tcx_mdct_window_trans_48[60]; +extern const Word16 tcx_mdct_window_trans_48_fx[60]; /*----------------------------------------------------------------------------------* @@ -1713,4 +1969,55 @@ extern const Word16 pwf_fx[17]; extern const Word32 inverse_table[]; extern const Word16 cos_diff_table[512]; extern const Word32 bwMode2fs[4]; +extern const Word16 swb_lsp_prev_interp_init[]; +extern const Word16 L_frame_inv[8]; +extern const Word16 InvIntTable[65]; +extern const Word16 TecLowBandTable[]; +extern const Word16 TecSC_Fx[]; +extern const float TecSC[]; +extern const Word16 sqrt_table_pitch_search[256 + 1]; +/* fft_evs.c */ +extern const Word16 RotVector_32[2 * 20]; +extern const Word16 RotVector_256[2 * (256 - 32)]; +extern const Word16 RotVector_320[2 * (320 - 20)]; +extern const Word16 RotVector_400[2 * (400 - 20)]; +extern const Word16 RotVector_480[2 * (480 - 30)]; +extern const Word16 RotVector_600[2 * (600 - 30)]; +extern const Word16 FFT_REORDER_1024[]; +extern const Word16 FFT_W64[]; +extern const Word16 FFT_W128[]; +extern const Word16 FFT_W256[]; +extern const Word16 FFT_W512[]; +extern const Word16 Gamma_19661_Tbl_fx[]; +extern const Word16 Gamma_29491_Tbl[]; +/*---------------------------------------------------------------------* + * NB post-filter tables + *---------------------------------------------------------------------*/ + +extern const Word16 Tab_hup_s[]; +extern const Word16 Tab_hup_l[]; + +extern const Word16 mfreq_loc_Q2fx[]; +extern const Word16 mfreq_loc_div_25[]; + +extern const Word16 band_len_idx[]; +extern const Word16 band_len_ener_shift[]; +extern const Word16 fine_gain_pred_sqrt_bw[]; +extern const Word16 Mean_isf_wb[]; +extern const Word16 lsp_shb_prev_tbl_fx[]; +extern const Word16 tab_ari_qnew[4][4]; + +//enhancer.c +extern const Word16 phs_tbl_dec[]; +extern const Word16 Low_H_phasedisp[L_SUBFR]; +extern const Word16 Mid_H_phasedisp[L_SUBFR]; + + +//ACcontextMapping_dec_fx.c +extern const Word16 Tab_esc_nb[4]; +extern const Word16 pow2tab[15]; +extern const Word16 Es_pred_qua[8]; +extern const Word16 Es_pred_qua_2[16]; +extern const Word16 T_DIV_L_Frame[];/*0Q15 * 2^-7 */ + #endif diff --git a/lib_com/stab_est_fx.c b/lib_com/stab_est_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..e6b55fe71cea7bbf2c2fbe1a727da3e3b00978cc --- /dev/null +++ b/lib_com/stab_est_fx.c @@ -0,0 +1,251 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ +#include +#include "options.h" /* Compilation switches */ +#include "cnst.h" /* Common constants */ +#include "prot_fx1.h" /* Function prototypes */ +#include "prot_fx2.h" /* Function prototypes */ + +/*-------------------------------------------------------------------* + * Local constants + *-------------------------------------------------------------------*/ + +#define BIN_4000 80 /* The frequency bin corresponding to 4kHz */ +#define MAX_BANDEXC 20 + +#define NB_TH3_MIN 30 +#define NB_TH1_MIN 30 + +#define TH_0_MAX_FX 9600 /* Q11 -> 1.5*3.125 */ +#define TH_1_MAX_FX 8640 /* Q11 -> 1.5*2.8125 */ +#define TH_2_MAX_FX 6720 /* Q11 -> 1.5*2.1875 */ +#define TH_3_MAX_FX 5760 /* Q11 -> 1.5*1.875 */ + +#define TH_UP_FX 320 /* Q11 -> 0.15625 */ +#define TH_DW_FX 320 /* Q11 -> 0.15625 */ + +/*------------------------------------------------------------------------* + * stab_est() + * + * Signal stability estimation based on energy variation + *------------------------------------------------------------------------*/ + +Word16 stab_est_fx( + Word16 etot, /* i : Total energy of the current frame */ + Word16 *lt_diff_etot, /* i/o : Long term total energy variation */ + Word16 *mem_etot, /* i/o : Total energy memory */ + Word16 *nb_thr_3, /* i/o : Number of consecutives frames of level 3 */ + Word16 *nb_thr_1, /* i/o : Number of consecutives frames of level 1 */ + Word16 *thresh, /* i/o : Detection thresold */ + Word16 *last_music_flag,/* i/o : Previous music detection ouptut */ + const Word16 vad_flag /* i : VAD flag */ +) +{ + Word16 i, music_flag2, tmp16, exp1, exp2; + Word16 mean_diff; + Word16 dev; + Word32 L_tmp; + + /*------------------------------------------------------------------------* + * Find mean of the past MAX_LT frames energy variation + *------------------------------------------------------------------------*/ + + L_tmp = L_deposit_l(0); + FOR (i = 1; i 1/25 (1/(MAX_LT-15))*/ + + exp1 = norm_l(L_tmp); + L_tmp = L_shl(L_tmp, exp1); +#ifdef BASOP_NOGLOB + tmp16 = round_fx_sat(L_tmp); +#else + tmp16 = round_fx(L_tmp); +#endif + exp2 = sub(31, exp1); + L_tmp = Isqrt_lc(L_tmp, &exp2); + L_tmp = Mpy_32_16_1(L_tmp, tmp16); /* we now have sqrt(L_corr) Q24 (8+16)*/ + exp2 = sub(31-15, sub(exp1, exp2)); /* for Q8 (because of -8^2 from Etot)*/ + + L_tmp = L_shl(L_tmp, exp2); /* Q8 + Q16*/ +#ifdef BASOP_NOGLOB + dev = extract_h(L_shl_sat(L_tmp, 3 )); /* Q(24+3-16) -> Q11 */ +#else /* BASOP_NOGLOB */ + dev = extract_h(L_shl(L_tmp, 3)); /* Q(24+3-16) -> Q11 */ +#endif + + /*------------------------------------------------------------------------* + * State machine to decide level of inter-harmonic noise reduction and + * (only if this frame is GOOD or if we are already far from NB_BFI_THR) + * (if music_flag2 is 0, the spectral modification is deactivated, otherwise, it is activated) + *------------------------------------------------------------------------*/ + + music_flag2 = 0; + move16();/* deactivate spectral modification (if music_flag2 != 0 is activated) */ + test(); + /*--------------------------------------------------------------------* + * statistical deviation < thresh3 and last signal category type >= 3 + * (last category was "tonal" and the new one is "very tonal") + *--------------------------------------------------------------------*/ + test(); + test(); + test(); + IF ((LT_16(dev, thresh[3]))&&(GE_16(*last_music_flag,3))) + { + music_flag2 = 4; + move16(); + *nb_thr_3 += 1; + move16(); + *nb_thr_1 = 0; + move16(); + } + + /*--------------------------------------------------------------------* + * statistical deviation < thresh2 and last signal category type >= 2 + * (last category was "moderatly tonal" and the new one is a "tonal" ) + *--------------------------------------------------------------------*/ + ELSE IF ((LT_16(dev, thresh[2]))&&(GE_16(*last_music_flag,2))) + { + music_flag2 = 3; + move16(); + *nb_thr_3 += 1; + move16(); + *nb_thr_1 = 0; + move16(); + } + + /*--------------------------------------------------------------------* + * statistical deviation < thresh1 and last signal category type >= 1 + * (last category was "slightly tonal" and the new one is a "moderatly tonal") + *--------------------------------------------------------------------*/ + ELSE IF ((LT_16(dev, thresh[1]))&&(GE_16(*last_music_flag,1))) + { + music_flag2 = 2; + move16(); + } + + /*--------------------------------------------------------------------* + * statistical deviation < thresh0 + * (last category was "not tonal" and the new one is "slightly tonal") + *--------------------------------------------------------------------*/ + ELSE IF ((LT_16(dev, thresh[0]))) + { + music_flag2 = 1; + move16();/* [2000, 4000] Hz */ + } + + /*--------------------------------------------------------------------* + * statistical deviation > thresh0 + * (Statistical deviation is high: the new tonal category is not tonal) + *--------------------------------------------------------------------*/ + ELSE + { + *nb_thr_1 = add(*nb_thr_1,1); + *nb_thr_3 = 0; + move16(); + + } + + /*------------------------------------------------------------------------* + * Update the thresholds + *------------------------------------------------------------------------*/ + IF (GT_16(*nb_thr_3,NB_TH3_MIN)) + { + + /* the number of consecutive categories type 3 or 4 (most tonal and tonal) */ + /* is greater than 30 frames ->increase the deviations thresholds to allow more variation */ + thresh[0] = add(thresh[0], TH_UP_FX); + move16(); /*Q11 */ + thresh[1] = add(thresh[1], TH_UP_FX); + move16(); + thresh[2] = add(thresh[2], TH_UP_FX); + move16(); + thresh[3] = add(thresh[3], TH_UP_FX); + move16(); + + } + ELSE IF (GT_16(*nb_thr_1,NB_TH1_MIN)) + { + /* the number of consecutive categories type 0 (non tonal frames) */ + /* is greater than 30 frames -> decrease the deviations thresholds to allow less variation */ + thresh[0] = sub(thresh[0], TH_DW_FX); + move16(); /*Q11 */ + thresh[1] = sub(thresh[1], TH_DW_FX); + move16(); + thresh[2] = sub(thresh[2], TH_DW_FX); + move16(); + thresh[3] = sub(thresh[3], TH_DW_FX); + move16(); + } + + /* limitation of the threshold (this local macro stores the highest of the two and it also + counts the # of operations) */ + + move16(); + move16(); + move16(); + thresh[0] = s_max(thresh[0], TH_0_MIN2_FX); + thresh[1] = s_max(thresh[1], TH_1_MIN2_FX); + thresh[2] = s_max(thresh[2], TH_2_MIN2_FX); + + move16(); + move16(); + move16(); + thresh[0] = s_min(thresh[0], TH_0_MAX_FX); + thresh[1] = s_min(thresh[1], TH_1_MAX_FX); + thresh[2] = s_min(thresh[2], TH_2_MAX_FX); + move16(); + move16(); + thresh[3] = s_max(thresh[3], TH_3_MIN2_FX); + thresh[3] = s_min(thresh[3], TH_3_MAX_FX); + /*------------------------------------------------------------------------* + * Final update + *------------------------------------------------------------------------*/ + + *last_music_flag = music_flag2; + move16(); + if (vad_flag == 0) + { + + music_flag2 = 0; + move16(); + } + + return music_flag2; +} diff --git a/lib_com/stat_com.h b/lib_com/stat_com.h index cd08c64baef3686f3b7cfb6a0902b70398b66a3e..0fdc29f90ce1c63609270ee9c001712f34fa69ff 100644 --- a/lib_com/stat_com.h +++ b/lib_com/stat_com.h @@ -84,25 +84,25 @@ typedef struct typedef struct { - uint8_t buf[MAX_SIZEBUF_PBITSTREAM]; - signed char curPos; - uint16_t numByte; - uint16_t numbits; - uint16_t maxBytes; + UWord8 buf[MAX_SIZEBUF_PBITSTREAM]; + Word16 curPos; + Word32 numByte; + Word32 numbits; + Word32 maxBytes; } TCQ_BITSTREAM, *TCQ_PBITSTREAM; typedef struct { TCQ_PBITSTREAM bsInst; - uint32_t low; - uint32_t high; + Word32 low; + Word32 high; - uint32_t value; - int16_t bits_to_follow; + Word32 value; + Word16 bits_to_follow; - int16_t num_bits; - int16_t max_bits; + Word32 num_bits; + Word32 max_bits; } ARCODEC, *PARCODEC; @@ -175,7 +175,11 @@ typedef struct /*---------------------------------------------------------------* * TCX Encoder/Decoder Static RAM * *---------------------------------------------------------------*/ - +typedef enum +{ + TNS_NO_ERROR = 0, + TNS_FATAL_ERROR +} TNS_ERROR; typedef struct { uint8_t maxOrder; @@ -233,6 +237,14 @@ typedef struct TCX_config_structure float tcx_aldo_window_1_flt[L_ALDO_WIN1_MAX_CORE_FS]; /* ALDO window long slope */ float tcx_aldo_window_2_flt[L_MDCT_OVLP_MAX_CORE_FS]; /* ALDO window short slope */ float *tcx_aldo_window_1_trunc_flt; /* ALDO window truncated long slope */ + PWord16 tcx_mdct_window[L_MDCT_OVLP_MAX_CORE_FS]; + PWord16 tcx_mdct_window_half[L_MDCT_HALF_OVLP_MAX_CORE_FS]; + PWord16 tcx_mdct_window_minimum[L_MDCT_MIN_OVLP_MAX_CORE_FS]; + PWord16 tcx_mdct_window_trans[L_MDCT_MIN_OVLP_MAX_CORE_FS]; + Word16 tcx_aldo_window_1[L_FRAME32k * 9 / 32]; + PWord16 tcx_aldo_window_1_trunc[L_FRAME32k * 7 / 32]; + PWord16 tcx_aldo_window_2[L_FRAME32k * 7 / 32]; + int16_t last_aldo; float tcx_mdct_window_half_flt[L_MDCT_HALF_OVLP_MAX_CORE_FS]; @@ -262,10 +274,10 @@ typedef struct TCX_config_structure float tcx_mdct_window_transFB_flt[L_MDCT_TRANS_OVLP_MAX]; /* transition window for ACELP->TCX */ /* TCX mdct window */ - const PWord16 *tcx_mdct_windowFB; - const PWord16 *tcx_mdct_window_halfFB; - const PWord16 *tcx_mdct_window_minimumFB; - const PWord16 *tcx_mdct_window_transFB; + PWord16 tcx_mdct_windowFB[L_MDCT_OVLP_MAX]; + PWord16 tcx_mdct_window_halfFB[L_MDCT_HALF_OVLP_MAX]; + PWord16 tcx_mdct_window_minimumFB[L_MDCT_MIN_OVLP_MAX]; + PWord16 tcx_mdct_window_transFB[L_MDCT_TRANS_OVLP_MAX]; Word16 tcx_aldo_window_1_FB[L_FRAME_MAX * 9 / 32]; PWord16 tcx_aldo_window_1_FB_trunc[L_FRAME_MAX * 7 / 32]; PWord16 tcx_aldo_window_2_FB[L_FRAME_MAX * 7 / 32]; @@ -371,35 +383,64 @@ typedef struct int16_t stopFFTbin; /* Total number of FFT subbands */ int16_t frameSize; /* Frame size in samples */ int16_t fftlen; /* FFT length used for the decomposition */ - - float timeDomainBuffer[L_FRAME16k]; - float fftBuffer[FFTLEN]; - float olapBufferAna[FFTLEN]; - float olapBufferSynth[FFTLEN]; - float olapBufferSynth2[FFTLEN]; - const float *olapWinAna; - const float *olapWinSyn; - const float *fftSineTab; - - float msM_win; - float msM_subwin; + Word16 fftlenShift; + Word16 fftlenFac; + + float timeDomainBuffer_flt[L_FRAME16k]; + Word16 timeDomainBuffer[L_FRAME16k]; + + float fftBuffer_flt[FFTLEN]; + float olapBufferAna_flt[FFTLEN]; + float olapBufferSynth_flt[FFTLEN]; + float olapBufferSynth2_flt[FFTLEN]; + const float *olapWinAna_flt; + const float *olapWinSyn_flt; + const float *fftSineTab_flt; + Word32 fftBuffer[FFTLEN]; + Word16 *olapBufferAna; /* points to FD_CNG_DEC->olapBufferAna[320] in case of decoder */ + Word16 olapBufferSynth[FFTLEN]; + Word16 *olapBufferSynth2; /* points to FD_CNG_DEC->olapBufferSynth2[FFTLEN] in case of decoder */ + const PWord16 * olapWinAna; + const PWord16 * olapWinSyn; + + + float msM_win_flt; + float msM_subwin_flt; + Word16 msM_win; + Word16 msM_subwin; int16_t msFrCnt_init_counter; /* Frame counter at initialization */ int16_t msFrCnt_init_thresh; - float init_old; + float init_old_flt; + Word16 init_old; + int16_t msFrCnt; /* Frame counter */ - float msAlphaCor[2]; /* Correction factor (smoothed) */ - float msSlope[2]; - float msQeqInvAv[2]; + float msAlphaCor_flt[2]; /* Correction factor (smoothed) */ + float msSlope_flt[2]; + float msQeqInvAv_flt[2]; + Word32 msAlphaCor[2]; /* Correction factor (smoothed) */ + Word16 msSlope[2]; + Word32 msQeqInvAv[2]; + Word16 msQeqInvAv_exp[2]; int16_t msMinBufferPtr; - float msPsdSum[2]; - float msPeriodogSum[2]; + float msPsdSum_flt[2]; + float msPeriodogSum_flt[2]; + Word32 msPsdSum[2]; + Word32 msPeriodogSum[2]; + Word16 msPeriodogSum_exp[2]; int16_t offsetflag; - float periodog[PERIODOGLEN]; /* Periodogram */ - float cngNoiseLevel[FFTCLDFBLEN]; /* Noise level applied for the CNG in each (sub)band */ + float periodog_flt[PERIODOGLEN]; /* Periodogram */ + float cngNoiseLevel_flt[FFTCLDFBLEN]; /* Noise level applied for the CNG in each (sub)band */ + Word32 periodog[PERIODOGLEN]; /* Periodogram */ + Word16 periodog_exp; + Word16 exp_cldfb_periodog; + + Word32 cngNoiseLevel[FFTCLDFBLEN]; /* Noise level applied for the CNG in each (sub)band */ + Word16 cngNoiseLevelExp; + int16_t seed; /* Seed memory (for random function) */ int16_t seed2; /* Seed for second noise source in MDCT-Stereo DTX */ int16_t seed3; /* Seed for third noise source in MDCT-Stereo DTX */ @@ -408,34 +449,47 @@ typedef struct int16_t midband[NPART]; /* Central band of each partition */ int16_t nFFTpart; /* Number of hybrid spectral partitions */ int16_t part[NPART]; /* Partition upper boundaries (band indices starting from 0) */ - float psize[NPART]; /* Partition sizes */ - float psize_inv[NPART]; /* Inverse of partition sizes */ - float FFTscalingFactor; /* Squared ratio between core signal analysis FFT and noise estimator FFT */ - float scalingFactor; + float psize_flt[NPART]; /* Partition sizes */ + float psize_inv_flt[NPART]; /* Inverse of partition sizes */ + float FFTscalingFactor_flt; /* Squared ratio between core signal analysis FFT and noise estimator FFT */ + float scalingFactor_flt; + Word16 psize[NPART]; /* Partition sizes */ + Word16 psize_norm[NPART]; /* Partition sizes, fractional variable */ + Word16 psize_norm_exp; /* Partition sizes exponent for fractional variable */ + Word16 psize_inv[NPART]; /* Inverse of partition sizes */ + Word16 FFTscalingFactor; /* Squared ratio between core signal analysis FFT and noise estimator FFT */ + Word16 scalingFactor; + Word16 invScalingFactor; int16_t nCLDFBpart; /* Number of CLDFB spectral partitions */ int16_t CLDFBpart[NPARTCLDFB]; /* CLDFB Partition upper boundaries (band indices starting from 0 above the core coder bands) */ - float CLDFBpsize_inv[NPARTCLDFB]; /* Inverse of CLDFB partition sizes */ + float CLDFBpsize_inv_flt[NPARTCLDFB]; /* Inverse of CLDFB partition sizes */ + Word16 CLDFBpsize_inv[NPARTCLDFB];/* Inverse of CLDFB partition sizes */ int16_t inactive_frame_counter; int16_t sid_frame_counter; int16_t active_frame_counter; /* Active frame counter limited to MSBUFLEN in stereo decoder */ - float sidNoiseEst[NPART]; /* Transmitted noise level */ + float sidNoiseEst_flt[NPART]; /* Transmitted noise level */ + Word32 sidNoiseEst[NPART]; /* Transmitted noise level */ + Word16 sidNoiseEstExp; - float sidNoiseEstLp[NPART]; + float sidNoiseEstLp_flt[NPART]; int16_t frame_type_previous; - float A_cng[M + 1]; - float exc_cng[L_FRAME16k]; + float A_cng_flt[M + 1]; + float exc_cng_flt[L_FRAME16k]; + Word16 A_cng[M + 1]; + Word16 exc_cng[L_FRAME16k]; int32_t CngBitrate; int16_t CngBandwidth; int16_t flag_noisy_speech; - float likelihood_noisy_speech; + float likelihood_noisy_speech_flt; + Word16 likelihood_noisy_speech; - float coherence; /* inter-channel coherence of noise */ + float coherence_flt; /* inter-channel coherence of noise */ int16_t no_side_flag; /* indicates whether the side noise shape should be zeroed-out or not */ } FD_CNG_COM, *HANDLE_FD_CNG_COM; @@ -721,17 +775,6 @@ typedef struct pfstat_structure } PFSTAT, *PFSTAT_HANDLE; -typedef struct -{ - Word16 pGainTemp_m[CLDFB_NO_COL_MAX]; - Word16 pGainTemp_e[CLDFB_NO_COL_MAX]; - Word16 loBuffer[CLDFB_NO_COL_MAX + MAX_TEC_SMOOTHING_DEG]; - - Word16 cldfbExp; - Word16 lastCldfbExp; -} TEMPORAL_ENVELOPE_CODING_DECODER_FX; -typedef TEMPORAL_ENVELOPE_CODING_DECODER_FX* HANDLE_TEC_DEC_FX; - typedef struct { @@ -761,7 +804,9 @@ typedef struct igf_grid_struct int16_t tile[IGF_MAX_TILES + 1]; int16_t infoIsRefined; int16_t infoGranuleLen; - float whiteningThreshold[2][IGF_MAX_TILES]; + Word16 infoTransFac; + float whiteningThreshold_flt[2][IGF_MAX_TILES]; + Word16 whiteningThreshold[2][IGF_MAX_TILES]; /* 2Q13 */ float gFactor_flt; float fFactor_flt; float lFactor_flt; diff --git a/lib_com/stat_noise_uv_mod_fx.c b/lib_com/stat_noise_uv_mod_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..f0ad7721fee0dac4fdc752b4a6ea6b873b91b318 --- /dev/null +++ b/lib_com/stat_noise_uv_mod_fx.c @@ -0,0 +1,440 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include +#include "options.h" /* Compilation switches */ +#include "prot_fx1.h" /* Function prototypes */ +#include "prot_fx2.h" /* Function prototypes */ +#include "cnst.h" /* Function prototypes */ + +/*---------------------------------------------------------------------* + * Local function prototypes + *---------------------------------------------------------------------*/ + +#define TILT_COMP_LIM_FX 24576 /* 0.75 in Q15 */ +#define GE_SHIFT 6 +#define P1 (32768-ISP_SMOOTHING_QUANT_A1_FX-1) +#define P9 (32767-P1) + +/*---------------------------------------------------------* + * Local functions + *---------------------------------------------------------*/ + +static Word16 calc_tilt_fx(const Word16 *x, const Word16 Q_shift, const Word16 len); +Word32 L_Sqrt_Q0(const Word32 x); +/*--------------------------------------------------------------------* + * stat_noise_uv_mod() + * + * Modifies excitation signal in stationary noise segments + *--------------------------------------------------------------------*/ + +void stat_noise_uv_mod_fx( + const Word16 coder_type, /* i : Coder type */ + Word16 noisiness, /* i : noisiness parameter */ + const Word16 *lsp_old, /* i : old LSP vector at 4th sfr */ + const Word16 *lsp_new, /* i : LSP vector at 4th sfr */ + const Word16 *lsp_mid, /* i : LSP vector at 2nd sfr */ + Word16 *Aq, /* o : A(z) quantized for the 4 subframes */ + Word16 *exc2, /* i/o: excitation buffer */ + Word16 Q_exc, /* i : Q of exc2 excitation buffer [11..-1] expected */ + const Word16 bfi , /* i : Bad frame indicator */ + Word32 *ge_sm, /* i/o: smoothed excitation gain */ + Word16 *uv_count, /* i/o: unvoiced counter */ + Word16 *act_count, /* i/o: activation counter */ + Word16 lspold_s[], /* i/o: old LSP */ + Word16 *noimix_seed, /* i/o: mixture seed */ + Word16 *st_min_alpha, /* i/o: minimum alpha */ + Word16 *exc_pe, /* i/o: scale Q_stat_noise */ + const Word32 bitrate, /* i : core bitrate */ + const Word16 bwidth_fx, /* i : input bandwidth */ + Word16 *Q_stat_noise, /* i/o: noise scaling */ + Word16 *Q_stat_noise_ge /* i/o: noise scaling */ +) +{ + Word16 exctilt; /* Q15 */ + Word32 vare; /* Q31 */ + Word16 randval; /* Q?? */ + Word16 alpha; /* Q15 */ + Word16 alpha_m1; /* (1-alpha) Q15 */ + Word16 min_alpha; /* Q15 */ + Word16 lspnew_s[M]; /* Same for all LSP (Q15) */ + Word16 oldlsp_mix[M]; + Word16 midlsp_mix[M]; + Word16 newlsp_mix[M]; + Word16 beta; /* Q15 */ + Word16 Noimix_fract; /* (noimix_fac - 1.0) in Q15 */ + /* noimix_fax * x <-> x + Noimix_fract * x */ + Word16 i_subfr; + Word16 i, k; + + /* Work variables for div and sqrt */ + Word16 tmp_nom,tmp_den,tmp_shift,tmp_res; + Word16 Qdiff,Q_local; /* new Q to be used for states Exc_pe and Ge_sm, and Exc2_local */ + Word32 L_tmp_res,L_tmp, L_tmp3,L_Ge; + + Word16 En_shift,Tmp; + Word16 Exc2_local[L_FRAME]; /* local_copy in scaled Q_local*/ +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + + /*---------------------------------------------------------* + * Init local variables + *---------------------------------------------------------*/ + alpha = 32767; + move16(); + min_alpha = 16384; + move16(); + + test(); + test(); + test(); + IF (EQ_16(coder_type,INACTIVE)&&(EQ_32(bitrate,ACELP_9k60)||(LT_32(bitrate,ACELP_9k60)&>_16(bwidth_fx,NB)))) + { + min_alpha = *st_min_alpha; + move16(); + /*---------------------------------------------------------* + * decode noisiness parameter + *---------------------------------------------------------*/ + IF (bfi == 0) + { + tmp_den = 31; + move16(); + tmp_shift = norm_s(tmp_den); + move16(); + L_tmp_res = L_deposit_h(noisiness); + L_tmp_res = L_shl(L_tmp_res,sub(tmp_shift,1)); + tmp_den = shl(tmp_den,tmp_shift); + move16(); + tmp_res = div_l(L_tmp_res,tmp_den); + move16(); +#ifdef BASOP_NOGLOB + min_alpha = add_o(tmp_res, 16384, &Overflow); +#else /* BASOP_NOGLOB */ + min_alpha = add(tmp_res, 16384); +#endif /* BASOP_NOGLOB */ + move16(); + + /**st_min_alpha = sub(*st_min_alpha, 1638); move16();*/ + min_alpha = s_max(min_alpha, sub(*st_min_alpha, 1638)); + + *st_min_alpha = min_alpha; + move16(); + } + } + + /*---------------------------------------------------------* + * Mix excitation signal with random noise + *---------------------------------------------------------*/ + test(); + test(); + test(); + IF ( EQ_16(coder_type,INACTIVE)&&(EQ_32(bitrate,ACELP_9k60)||(LT_32(bitrate,ACELP_9k60)&>_16(bwidth_fx,NB)))) + { + /* use a local working copy for scaling and filtering, not needed if input Q-range is fixed */ + Copy(exc2, Exc2_local, L_FRAME); + + /* bound Q for internal use, optimization possible */ + Q_local = s_min(11, s_max(-1, Q_exc)); + /* local excitation Q and incoming excitation Q*/ + Qdiff = sub(Q_local, Q_exc); + /* only shift if incoming Q is outside [11..-1] shift is done in energy calculations aswell */ + Scale_sig(Exc2_local, L_FRAME, Qdiff); + /* current excitation Q and previous stat_noise states Q */ + Qdiff = sub(Q_local, *Q_stat_noise); + + *Q_stat_noise_ge = GE_SHIFT; + move16(); /* assign the fixed Q for Ge_sm */ + + IF (Qdiff != 0) + { + Scale_sig(exc_pe, 1, Qdiff); + } + + En_shift = 0; + move16(); + if (GT_16(Q_local, 3)) + { + /* increase margin for energy accumulation in calc_tilt and vare accumulation */ + En_shift = sub(Q_local, 3); + } + + IF (LT_16(min_alpha, TILT_COMP_LIM_FX)) + { + FOR (i_subfr=0; i_subfrge_sm = ISP_SMOOTHING_QUANT_A1 * st->ge_sm + (1.0f-ISP_SMOOTHING_QUANT_A1) * ge */ + + IF ( EQ_16(*uv_count,1)) + { + *ge_sm = L_shr(L_Ge,Q_local); + } + ELSE + { + L_tmp = Mult_32_16(L_Ge,P1); /* 0.1*ge still in Q local */ + L_tmp3 = Mult_32_16(*ge_sm,P9); /* 0.9*ge_sm still in Q_ge */ + + *ge_sm = L_add(L_shr(L_tmp,Q_local),L_tmp3); + move32(); /* addition in Q_ge domain*/ + } + + /*--------------------------------------------------------------------* + * generate mixture of excitation and noise + * float: + * noimix_fac = 1.0f/(float)sqrt(alpha*alpha + (1-alpha)*(1-alpha)) + *--------------------------------------------------------------------*/ + + beta = shl(sub(alpha, 16384), 1); + alpha_m1 = sub(32767, alpha); + L_tmp_res = L_mac(0, alpha, alpha); + L_tmp_res = L_mac(L_tmp_res, alpha_m1, alpha_m1); + tmp_den = round_fx(L_Frac_sqrtQ31(L_tmp_res)); + + tmp_nom = sub(32767, tmp_den); + tmp_shift = norm_s(tmp_den); + tmp_den = shl(tmp_den, tmp_shift); + tmp_res = div_s(tmp_nom, tmp_den); + + Noimix_fract = shr(tmp_res, tmp_shift); /* float value is in range 0.0 to 0.42 */ + + /* L_Ge might be 0 in unvoiced WB */ + L_Ge = L_max(L_Ge, 1); + tmp_shift = norm_l(L_Ge); + tmp_den = extract_h(L_shl(L_Ge, tmp_shift)); /* Q_local+Q_ge+tmp_shift-16 */ + tmp_res = div_s(1<<14, tmp_den); /* 15+14-Q_local-tmp_shift-Q_ge+16 */ + L_tmp_res = Mult_32_16(*ge_sm, tmp_res); /* Q_stat_noise_ge+45-Q_local-Q_ge-tmp_shift-15 */ + L_tmp_res = Mult_32_16(L_tmp_res, sub(32767, beta)); /*30-Q_local-tmp_shift+15-15 */ + L_tmp_res = L_add(L_shl(L_tmp_res, sub(add(Q_local, tmp_shift), 15)), beta); /* Q15 */ +#ifdef BASOP_NOGLOB + tmp_res = extract_h(L_shl_o(L_tmp_res, 15, &Overflow)); /* 15+15-16=14 */ +#else + tmp_res = extract_h(L_shl(L_tmp_res, 15)); /* 15+15-16=14 */ +#endif + + Noimix_fract = extract_l(Mult_32_16(L_tmp_res, Noimix_fract)); /*15+15-15 */ + + FOR (i=0; ige_sm*Rnd*((1.0f)-alpha) + * flt: exc2[i] = (noimix_fract*exc2[i]+exc2 )* alpha + st->ge_sm*Rnd*((1.0f)-alpha) + * NB: currently uses 32bit accumulation for best low level performance, + * possibly overkill if input is always up-scaled + *--------------------------------------------------------------------*/ + + /* (1-alpha)*(float)sqrt(12.0f) * ((float)own_random(&(st->noimix_seed))/65536.0f) */ + randval = Random(noimix_seed); /* +/-32767 */ + randval = mult_r(28378, randval); /* Q downscaled by 2 bits ends up in Q14 */ /*sqrt(12.0f) in Q13*/ + randval = extract_l(L_shl(Mult_32_16(L_Ge, randval), 1-*Q_stat_noise_ge)); /*Q_local+Q_ge+14-15+1-Q_ge=Q_local */ + + L_tmp = L_mult(Exc2_local[i], alpha); /* Q_local + 16 */ + L_tmp = L_mac(L_tmp, randval, alpha_m1); /* Q_local + 16 */ + L_tmp3 = Mult_32_16(L_tmp, Noimix_fract); /* Q_local+16+15-15 */ + L_tmp = L_add(L_tmp3, L_shl(Mult_32_16(L_tmp, tmp_res), 1)); /* Q_local+16+14-15+1 */ + + Exc2_local[i] = extract_h(L_tmp); /*Q_local */ + } + *Q_stat_noise = Q_local; /* update for next call, routine can only be called once every frame */ + Qdiff = sub(Q_exc, Q_local); /* local excitation and incoming excitation */ + Scale_sig(Exc2_local, L_FRAME, Qdiff); + Copy(Exc2_local, exc2, L_FRAME); + + /*--------------------------------------------------------------------* + * Generate low-pass filtered version of ISP coefficients + *--------------------------------------------------------------------*/ + FOR (k=0; k correlation loop can be optimized */ + r0 = L_mac(r0,xi,xi); + + xi_p1 = shr(x[i+1], Q_shift); + r1 = L_mac(r1, xi, xi_p1); + + xi = xi_p1; + move16(); + } + + if (r0 == 0) + { + r0 = L_shl(327, 16); + } + + tmp_shift = norm_l(r0); + move16(); + r0 = L_shl(r0,tmp_shift); + tmp_sign = 1; + move16(); + if (r1 >= 0) + { + tmp_sign = 0; + move16(); + } + r1 = L_abs(r1); + + L_tmp_res = Div_32(r1,extract_h(r0), extract_l(r0)); + L_tmp_res = L_shl(L_tmp_res, tmp_shift); /*Q31 */ + + if (tmp_sign != 0) + { + L_tmp_res = L_negate(L_tmp_res); /*Q31 */ + } + + return extract_h(L_tmp_res); /*Q15 */ +} + +/*---------------------------------------------------------------------------* + * L_Sqrt_Q0 + * + * Calculate square root from fractional values (Q0 -> Q0) + * Uses 32 bit internal representation for precision + *---------------------------------------------------------------------------*/ +Word32 L_Sqrt_Q0( /* o : Square root of input */ + const Word32 x /* i : Input */ +) +{ + Word32 log2_work; + + Word16 log2_int; + Word16 log2_frac; + + IF (x > 0) + { + log2_int = norm_l(x); + log2_frac = Log2_norm_lc(L_shl(x, log2_int)); + + log2_work = L_mac0(30*32768L, log2_frac, 1); + log2_work = L_msu(log2_work, log2_int, 16384); + log2_frac = L_Extract_lc(log2_work, &log2_int); + + return Pow2(log2_int, log2_frac); + } + return 0; +} + diff --git a/lib_com/stl.h b/lib_com/stl.h index ec5643e39c1e3a2bb5497d6e5551cfd76c1ff574..a94ab6ec6f126cdf21677df60a9b9c3c5e62c0cf 100644 --- a/lib_com/stl.h +++ b/lib_com/stl.h @@ -57,7 +57,7 @@ #ifndef _STL_H #define _STL_H -//#define ENH_U_32_BIT_OPERATOR +#define ENH_U_32_BIT_OPERATOR #define COMPLEX_OPERATOR #define CONTROL_CODE_OPS #define ENH_32_BIT_OPERATOR @@ -66,6 +66,7 @@ #if defined BASOP_NOGLOB && !defined BASOP_NOGLOB_DEV_USE_GLOBALS #define BASOP_NOGLOB_DECLARE_LOCAL #endif +//#define EVS_FLOAT #include "options.h" /* note: needed until BASOP_NOGLOB is accepted */ #include "typedef.h" @@ -77,7 +78,10 @@ #include "enh1632.h" #include "enh40.h" #include "enh64.h" +#include "math_op.h" +#include "enhUL32.h" #include "enh32.h" +#include "complex_basop.h" #endif /* ifndef _STL_H */ diff --git a/lib_com/swb_bwe_com_hr_fx.c b/lib_com/swb_bwe_com_hr_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..c7714b09989e53642ffe4f1f63f7e811108d5360 --- /dev/null +++ b/lib_com/swb_bwe_com_hr_fx.c @@ -0,0 +1,263 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include +#include "options.h" +#include "prot_fx1.h" +#include "prot_fx2.h" + +/*-------------------------------------------------------------------* + * swb_hr_nonzero_subband_noise_fill() + * + * SWB BWE HR noise filling of zero subbands + *-------------------------------------------------------------------*/ +static void swb_hr_nonzero_subband_noise_fill_fx( + const Word16 tilt_wb_fx, /* i : tilt of wideband signal */ + Word16 *t_audio_fx, /* i/o: mdct spectrum */ + Word16 *bwe_highrate_seed, /* i/o: seed of random noise */ + const Word16 N, /* i : length of subband */ + const Word16 Nsv, /* i : number of subband */ + Word16 Q_audio +) +{ + Word16 i, j; + Word16 *ptr_fx; + Word16 min_bwe_fx, max_bwe_fx, tmpF_fx; + Word16 tmp; + + IF( GT_16(tilt_wb_fx, 10240)) + { + FOR( i=0; i 0 ) + { + min_bwe_fx = s_min(tmpF_fx, min_bwe_fx); + } + } + + test(); + if( EQ_16(max_bwe_fx, min_bwe_fx)&>_16(min_bwe_fx,shl(1,Q_audio))) + { + min_bwe_fx = mult_r(min_bwe_fx, 16384); + } + + ptr_fx = &t_audio_fx[tmp]; + FOR( j=0; jQ15 */ + } + } + + i = 0; + move16(); + IF( nq[i] == 0 ) + { + i = 1; + move16(); + test(); + WHILE( LT_16(i, Nsv)&&nq[i]==0) + { + i++; + move16(); + test(); + } + + pos_start = i; + move16(); + test(); + WHILE( LT_16(i, Nsv)&&nq[i]!=0) + { + i++; + move16(); + test(); + } + + pos_end = sub(i, 1); + move16(); + + IF( GT_16(pos_end, shl(pos_start, 1))) + { + pos_end = sub(shl(pos_start, 1), 1); + move16(); + } + + incr = pos_end; + move16(); + + FOR( j = sub(pos_start, 1); j >= 0; j-- ) + { + tmp = shl(j, 3); + tmp1 = shl(incr, 3); + FOR( k=0; k= pos_start; j-- ) + { + tmp = shl(j, 3); + tmp1 = shl(incr, 3); + FOR( k=0; k +#include "options.h" /* Compilation switches */ +#include "cnst.h" /* Common constants */ +#include "prot_fx1.h" /* Function prototypes */ +#include "prot_fx2.h" /* Function prototypes */ + + +/*===========================================================================*/ +/* FUNCTION : syn_12k8_fx() */ +/*---------------------------------------------------------------------------*/ +/* PURPOSE : perform the synthesis filtering 1/A(z). */ +/*---------------------------------------------------------------------------*/ +/* INPUT ARGUMENTS : */ +/* _ (Word16) st_fx->L_frame :length of the frame */ +/* _ (Word16[]) Aq : LP filter coefficients Q12 */ +/* _ (Word16) exc : input signal Q_exc */ +/* _ (Word16) update_m : update memory flag: 0-->no memory update */ +/* 1 --> update of memory */ +/* _ (Word16) Q_exc : Excitation scaling */ +/* _ (Word16) Q_syn : Synthesis scaling */ +/*---------------------------------------------------------------------------*/ +/* INPUT OUTPUT ARGUMENTS : */ +/*---------------------------------------------------------------------------*/ +/* OUTPUT ARGUMENTS : */ +/* _ (Word16[]) synth : initial filter states Q_syn */ +/*---------------------------------------------------------------------------*/ + +/* _ (Word16[]) st_fx->mem_syn2_fx: initial filter states Q_syn */ +/*---------------------------------------------------------------------------*/ +/* RETURN ARGUMENTS : */ +/* _ None */ +/*===========================================================================*/ +void syn_12k8_fx( + Word16 L_frame, + const Word16 *Aq, /* i : LP filter coefficients Q12 */ + const Word16 *exc, /* i : input signal Q_exc */ + Word16 *synth, /* o : output signal Q_syn */ + Word16 *mem, /* i/o: initial filter states Q_syn */ + const Word16 update_m, /* i : update memory flag: 0 --> no memory update Q0 */ + /* 1 --> update of memory */ + const Word16 Q_exc, /* i : Excitation scaling Q0 */ + const Word16 Q_syn /* i : Synthesis scaling Q0 */ +) +{ + const Word16 *p_Aq; + Word16 i_subfr; + Word16 shift; + + shift = sub(Q_exc, Q_syn); + p_Aq = Aq; + move16(); + FOR (i_subfr = 0; i_subfr < L_frame; i_subfr += L_SUBFR) + { + Syn_filt_s(shift, p_Aq, M, &exc[i_subfr], &synth[i_subfr], L_SUBFR, mem, update_m); + p_Aq += (M+1); + move16(); /* interpolated LPC parameters for next subframe */ + } + return; +} diff --git a/lib_com/tcq_position_arith.c b/lib_com/tcq_position_arith.c index 6e17301d95b4541162fa7a8f4216699be170fa9e..5c0d61e0b92e6bd255992a0383f177e5fb28134e 100644 --- a/lib_com/tcq_position_arith.c +++ b/lib_com/tcq_position_arith.c @@ -84,7 +84,7 @@ static void set32_fx( return; } -Word32 ar_div( +Word32 ar_div_ivas( Word32 num, Word32 denum ) { @@ -138,7 +138,7 @@ Word32 ar_div( return varout; } -void srt_vec_ind_fx( +void srt_vec_ind_fx_ivas( const Word32 *linear, /* linear input */ Word32 *srt, /* sorted output*/ Word16 *I, /* index for sorted output */ @@ -245,7 +245,7 @@ static Word32 GetBitsFromPulses_fx( temp_fx1 = extract_h( mantissa_fx ); temp32 = L_shl( L_sub( mantissa_fx, L_deposit_h( temp_fx1 ) ), 15 ); /*31 */ exp1 = sub( norm_l( temp32 ), 1 ); - temp32 = ar_div( L_shl( temp32, exp1 ), temp_fx1 ); /*31 + exp1 */ + temp32 = ar_div_ivas( L_shl( temp32, exp1 ), temp_fx1 ); /*31 + exp1 */ temp32 = L_shr( temp32, exp1 + 1 ); /*30 */ frac_fx32 = L_sub( 0x40000000, L_shr( temp32, 1 ) ); /*30 */ @@ -257,7 +257,7 @@ static Word32 GetBitsFromPulses_fx( return L_add( L_deposit_h( exp ), L_add( L_shl( temp_fx1, 1 ), frac_fx32 ) ); } -void decode_position_ari_fx( +void decode_position_ari_fx_ivas( PARCODEC pardec, Word16 size, Word16 npulses, @@ -411,7 +411,7 @@ void decode_position_ari_fx( } -void decode_magnitude_usq_fx( +void decode_magnitude_usq_fx_ivas( ARCODEC *pardec, Word16 size, Word16 npulses, @@ -561,7 +561,7 @@ void decode_magnitude_usq_fx( return; } -static Word16 quantize_fx( +static Word16 quantize_fx_ivas( Word16 val, Word16 D ) { @@ -582,7 +582,7 @@ static Word16 quantize_fx( return retval_fx; } -void decode_mangitude_tcq_fx( +void decode_mangitude_tcq_fx_ivas( ARCODEC *pardec, Word16 size, Word16 npulses, @@ -656,8 +656,8 @@ void decode_mangitude_tcq_fx( break; } - quantum1_fx = quantize_fx( shl( add( j, 1 ), 10 ), ddec[st][0] ); - quantum2_fx = quantize_fx( shl( add( j, 1 ), 10 ), ddec[st][1] ); + quantum1_fx = quantize_fx_ivas( shl( add( j, 1 ), 10 ), ddec[st][0] ); + quantum2_fx = quantize_fx_ivas( shl( add( j, 1 ), 10 ), ddec[st][1] ); if ( sub( quantum1_fx, add( j, 1 ) ) != 0 && sub( quantum2_fx, add( j, 1 ) ) != 0 ) { @@ -699,8 +699,8 @@ void decode_mangitude_tcq_fx( leftnz--; } - quantum1_fx = quantize_fx( (Word16) out[i], ddec[st][0] ); - quantum2_fx = quantize_fx( (Word16) out[i], ddec[st][1] ); + quantum1_fx = quantize_fx_ivas( (Word16) out[i], ddec[st][0] ); + quantum2_fx = quantize_fx_ivas( (Word16) out[i], ddec[st][1] ); /*generate the next state */ if ( sub( quantum1_fx, (Word16) out[i] ) == 0 ) @@ -732,7 +732,7 @@ void decode_mangitude_tcq_fx( return; } -Word16 GetScale_fx( +Word16 GetScale_fx_ivas( Word16 blen, Word32 bits_fx /*Q16*/, Word32 *surplus_fx /*Q16*/ @@ -777,7 +777,7 @@ Word16 GetScale_fx( } -void decode_signs_fx( +void decode_signs_fx_ivas( ARCODEC *pardec, Word16 size, Word32 *out ) @@ -795,7 +795,7 @@ void decode_signs_fx( return; } -Word32 encode_position_ari_fx( +Word32 encode_position_ari_fx_ivas( PARCODEC parenc, float *quants, Word16 size, @@ -933,7 +933,7 @@ Word32 encode_position_ari_fx( } -Word32 encode_magnitude_tcq_fx( +Word32 encode_magnitude_tcq_fx_ivas( ARCODEC *parenc, float *magn_fx, Word16 size, @@ -990,8 +990,8 @@ Word32 encode_magnitude_tcq_fx( prob0_fx = sub( MAX_16, prob1_fx ); } - quantum1_fx = quantize_fx( shl( add( j, 1 ), 10 ), ddec[st][0] ); - quantum2_fx = quantize_fx( shl( add( j, 1 ), 10 ), ddec[st][1] ); + quantum1_fx = quantize_fx_ivas( shl( add( j, 1 ), 10 ), ddec[st][0] ); + quantum2_fx = quantize_fx_ivas( shl( add( j, 1 ), 10 ), ddec[st][1] ); if ( sub( quantum1_fx, add( j, 1 ) ) != 0 && sub( quantum2_fx, add( j, 1 ) ) != 0 ) { @@ -1027,7 +1027,7 @@ Word32 encode_magnitude_tcq_fx( } -Word32 encode_signs_fx( +Word32 encode_signs_fx_ivas( ARCODEC *parenc, float *magn, Word16 size, @@ -1050,7 +1050,7 @@ Word32 encode_signs_fx( } -Word32 encode_magnitude_usq_fx( +Word32 encode_magnitude_usq_fx_ivas( ARCODEC *parenc, float *magn_fx, Word16 size, @@ -1425,7 +1425,7 @@ static uint32_t bitstream_load_bit( TCQ_PBITSTREAM pBS ) { uint32_t bit; - signed char *curPos; + Word16 *curPos; /* safety check in case of bit errors */ if ( pBS->numByte >= pBS->maxBytes ) @@ -1669,7 +1669,7 @@ float GetISCScale( } else { - pulsesnum = GetScale_fx( size, bits_fx, surplus_fx ); + pulsesnum = GetScale_fx_ivas( size, bits_fx, surplus_fx ); } *nzpout = 0; diff --git a/lib_com/tcq_position_arith_fx.c b/lib_com/tcq_position_arith_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..66730d918e1c98cda85f5af74b6c05370ad46cea --- /dev/null +++ b/lib_com/tcq_position_arith_fx.c @@ -0,0 +1,2719 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include +#include "options.h" /* Compilation switches */ +#include "stl.h" + +#include "rom_com.h" +#include "prot_fx1.h" +#include "prot_fx2.h" + +Word32 ar_div( + Word32 num, + Word32 denum +) +{ + Word16 exp1, exp2, exp, i; + Word32 varout; + Word32 sign; + + sign = L_and(L_xor(num, denum), 0x80000000); + + num = L_abs(num); + denum = L_abs(denum); + + test(); + IF (LT_32(num, denum)||denum==0) + { + return 0; + } + ELSE IF (EQ_32(num, denum)) + { + return 1; + } + ELSE + { + exp1 = norm_l(num); + exp2 = norm_l(denum); + exp = sub(exp2, exp1); + denum = L_shl(denum, exp); + exp = add(exp, 1); + varout = L_deposit_l(0); + FOR (i = 0; i < exp; i++) + { + num = L_sub(num, denum); + varout = L_shl(varout, 1); + IF (num >= 0) + { + num = L_shl(num, 1); + varout = L_add(varout, 1); + } + ELSE + { + num = L_add(num, denum); + num = L_shl(num, 1); + } + } + } + + if(sign != 0) + { + varout = L_negate(varout); + } + + return varout; +} + +static void bitstream_save_bit( + TCQ_PBITSTREAM pBS, + Word32 bit +) +{ + UWord8 cur; + + cur = pBS->buf[pBS->numByte]; + move16(); + + + cur = (UWord8)(cur | L_shl(bit,pBS->curPos)); + move16(); + pBS->curPos = sub(pBS->curPos,1); + pBS->buf[pBS->numByte] = cur; + move16(); + pBS->numbits = L_add(pBS->numbits, 1); + + IF (pBS->curPos < 0) + { + pBS->curPos = 7; + move16(); + pBS->numByte = L_add(pBS->numByte, 1); + } + + return; +} + +static UWord32 bitstream_load_bit( + TCQ_PBITSTREAM pBS +) +{ + UWord32 bit; + Word16 *curPos; + + /* safety check in case of bit errors */ + IF( GE_32(pBS->numByte, pBS->maxBytes)) + { + return 0; + } + + curPos = &pBS->curPos; + move16(); + bit = (( pBS->buf[pBS->numByte] >> (*curPos)--) & 0x00000001); + move16(); + move16(); + move16(); + + IF (*curPos < 0) + { + pBS->numByte = L_add(pBS->numByte, 1); + *curPos = 7; + move16(); + } + + return bit; +} + +static void bitstream_rollback( + TCQ_PBITSTREAM pBS, + Word32 numBits +) +{ + + FOR ( ; numBits > 0; numBits--) + { + pBS->curPos++; + move16(); + pBS->numbits = L_sub(pBS->numbits, 1); + IF (EQ_16(pBS->curPos, 8)) + { + pBS->curPos = 0; + move16(); + pBS->numByte = L_sub(pBS->numByte, 1); + } + } + + return; +} +static void transmission_bits( + PARCODEC arInst, + Word32 bit +) +{ + bitstream_save_bit( arInst->bsInst, bit ); + arInst->num_bits = L_add(arInst->num_bits, 1); + bit = !bit; + move32(); + + FOR ( ; arInst->bits_to_follow > 0 && arInst->num_bits < arInst->max_bits; arInst->bits_to_follow --) + { + bitstream_save_bit( arInst->bsInst, bit ); + arInst->num_bits = L_add(arInst->num_bits, 1); + } + + return; +} + +static Word32 ar_make_model_fx( + const Word16 *freq, + Word16 *model, + const Word16 len ) +{ + Word16 dist; + Word32 sum = 0; + Word32 cum = 0; + Word16 i, tmp; + + FOR ( i = 0 ; i < len ; i ++ ) + { + sum = L_add(sum, freq[i]); + } + + IF ( sum == 0 ) + { + return 0; + } + + FOR ( i = len ; i >= 0; i -- ) + { + /*model[i] = (short)( ( cum * MAX_AR_FREQ ) / sum ); */ + model[i] = extract_l(ar_div(cum * MAX_AR_FREQ, sum)); + + if (i) cum = L_add(cum, freq[i - 1]); + } + + tmp = sub(len, 1); + FOR ( i = 0 ; i < tmp ; i ++ ) + { + dist = sub(model[i], model[i + 1]); + + IF ( dist <= 0 ) + { + model[i + 1] = add(model[i + 1], sub(dist, 1)); + move16(); + } + } + + FOR ( i = len ; i > 0 ; i -- ) + { + dist = sub(model[i - 1], model[i]); + + IF ( dist <= 0 ) + { + model[i - 1] = sub(model[i - 1], sub(dist, 1)); + move16(); + } + } + + return (model[0] > model[1]); +} + +void ar_encoder_start_fx( + PARCODEC arInst, + TCQ_PBITSTREAM bsInst, + const Word32 max_bits +) +{ + arInst->bsInst = bsInst; + move32(); + + arInst->low = L_deposit_l(0); + arInst->high = AR_TOP; + move32(); + arInst->bits_to_follow = 0; + move16(); + + arInst->num_bits = L_deposit_l(0); + arInst->max_bits = max_bits; + move32(); +} + +static void ar_encode_fx( + PARCODEC arInst, + const Word16 *model, + Word32 symbol +) +{ + Word32 range, high, low; + + high = L_add(arInst->high, 0); + low = L_add(arInst->low, 0); + + symbol = L_add(symbol, 1); + range = L_add(L_sub(high, low), 1); + + high = L_sub(L_add(low, ar_div(range * model[symbol - 1], model[0])), 1); + low = L_add(low, ar_div(range * model[symbol], model[0])); + + FOR( ; ; ) + { + IF ( LT_32(high, AR_HALF)) + { + transmission_bits( arInst, 0 ); + } + ELSE + { + IF (GE_32(low, AR_HALF)) + { + transmission_bits( arInst, 1 ); + + low = L_sub(low, AR_HALF); + high = L_sub(high, AR_HALF); + } + ELSE + { + test(); + IF (GE_32(low, AR_FIRST)&<_32(high,AR_THIRD)) + { + arInst->bits_to_follow ++; + move16(); + + low = L_sub(low, AR_FIRST); + high = L_sub(high, AR_FIRST); + } + ELSE + { + BREAK; + } + } + } + + low = L_shl(low, 1); + high = L_add(L_shl(high, 1 ), 1); + } + + arInst->high = high; + move32(); + arInst->low = low; + move32(); + + return; +} + +static void ar_encode_uniform_fx( + PARCODEC arInst, + UWord32 data, + const Word32 bits +) +{ + Word32 i; + + FOR ( i = 0 ; i < bits ; i ++ ) + { + ar_encode_fx( arInst, uniform_model, data & 0x1 ); + data = L_lshr(data, 1); + } + + return; +} + +void ar_encoder_done_fx( + PARCODEC arInst +) +{ + arInst->bits_to_follow ++; + move16(); + transmission_bits( arInst, arInst->low >= AR_FIRST ); + + return; +} + +void ar_decoder_start_fx( + PARCODEC arInst, + TCQ_PBITSTREAM bsInst +) +{ + Word16 i; + + arInst->bsInst = bsInst; + move32(); + + arInst->low = L_deposit_l(0); + arInst->high = AR_TOP; + move32(); + arInst->value = L_deposit_l(0); + + FOR ( i = 0; i < AR_BITS ; i ++ ) + { + arInst->value = L_add(L_shl( arInst->value, 1), bitstream_load_bit( arInst->bsInst )); + } + + return; +} + +static Word16 ar_decode_fx( + PARCODEC arInst, + const Word16 *model +) +{ + Word32 range, high, low, value, i; + Word16 cum; + Word16 symbol; + + high = L_add(arInst->high, 0); + low = L_add(arInst->low, 0); + value = L_add(arInst->value, 0); + + range = L_add(L_sub( high, low ), 1); + /*cum = (short)( ( ( (unsigned int)( arInst->value - arInst->low ) + 1 ) * model[0] - 1 ) / range ); */ + cum = extract_l(ar_div(L_sub(L_add(L_sub( value, low ), 1 ) * model[0], 1), range)); + + symbol = 1; + move16(); + WHILE ( GT_16(model[symbol], cum)) + { + symbol = add(symbol, 1); + } + + high = L_sub(L_add(low, ar_div(range * model[symbol - 1], model[0])), 1); + low = L_add(low, ar_div(range * model[symbol], model[0])); + + FOR (i = 0; i < 0x7FFF; i++) + { + Word32 L_msb_diff, L_msb_low, L_msb_high; + + L_msb_high = L_shr(high,14); + L_msb_low = L_shr(low,14); + L_msb_diff = L_sub(L_msb_high, L_msb_low); + IF (GE_32(L_msb_diff,2)) + { + BREAK; + } + assert (tab_ari_qnew[L_msb_high][L_msb_low] != 0x0CCC); + assert (tab_ari_qnew[L_msb_high][L_msb_low] != 0x0BBB); + low = L_msu(low,1,tab_ari_qnew[L_msb_high][L_msb_low]); + low = L_shl(low,1); + high = L_msu(high,1,tab_ari_qnew[L_msb_high][L_msb_low]); + high = L_add(L_shl(high, 1), 1); + value = L_msu(value,1,tab_ari_qnew[L_msb_high][L_msb_low]); + value = L_add(L_shl(value, 1), bitstream_load_bit( arInst->bsInst )); + } + + arInst->low = low; + move32(); + arInst->high = high; + move32(); + arInst->value = value; + move32(); + + return (symbol - 1); +} + +void ar_decoder_done_fx( + PARCODEC arInst +) +{ + bitstream_rollback( arInst->bsInst, AR_BITS - 2 ); + + return; +} + +static Word16 quantize_fx( + Word16 val, + const Word16 D +) +{ + Word16 qval4_fx; + Word16 retval_fx; + + val = s_min(val, 32255); /* limit input by (2^15 - 1)-2^9 */ + qval4_fx = shr(abs_s(add(val, 512)), 12); + retval_fx = add(shl(qval4_fx, 2), DDP_fx[D]); + /* 2nd zero check */ + IF (D == 0) + { + if (GT_16(abs_s(sub(shl(abs_s(retval_fx), 10), abs_s(val))), abs_s(val))) + { + retval_fx = 0; + move16(); + } + } + /*return retval; */ + return retval_fx; +} + +static Word32 GetBitsFromPulses_fx( + Word16 m, + Word16 n +) +{ + Word16 i, tmp, integer_fx, temp_fx1, temp_fx2, exp1, exp2; + Word32 temp32; + Word32 frac_fx32; + Word32 logCoeff_fx; + Word16 exp = 0; + Word32 mantissa_fx = 0; + move16(); + move32(); + + IF (m == 0) + { + return 0; + } + + tmp = s_min(m, n); + FOR (i = 0; i < tmp; i++) + { + logCoeff_fx = L_add(L_shl(i + 1, 16), L_sub(table_logcum_fx[n+1], L_add(table_logcum_fx[i + 2], table_logcum_fx[n - i]))); + logCoeff_fx = L_add(logCoeff_fx, L_sub(table_logcum_fx[m], L_add(table_logcum_fx[i + 1], table_logcum_fx[m - i])));/*Q16 */ + integer_fx = extract_h(logCoeff_fx);/*Q0 */ + frac_fx32 = L_sub(logCoeff_fx, L_shl(integer_fx, 16));/*Q16 */ + + /*ln2, 0.987, ln2 * ln2, 0.977 */ + /*temp1 = (int) (frac / 0.0625); */ + /*temp2 = frac - (float)temp1 * 0.0625f; */ + + /* frac = pow(2.0, temp1 * 0.0625) * (1 + 0.693 * temp2 + 0.480 * temp2 * temp2 * 0.5);*/ + /*frac = pow_getbitsfrompulses[temp1] * (1 + 0.693f * temp2 + 0.480f * temp2 * temp2 * 0.5f); */ + + temp_fx1 = extract_h(L_shl(frac_fx32, 4)); + temp_fx2 = extract_l(L_and(frac_fx32, 0xfff));/*Q16 */ + + frac_fx32 =L_mac(Mult_32_16(L_mult0(temp_fx2, temp_fx2), 7864), temp_fx2, 22708);/*Q32 */ + frac_fx32 = L_add(0x40000000, L_shr(frac_fx32, 2));/*30 */ + + exp1 = norm_l(pow_getbitsfrompulses_fx[temp_fx1]); + exp2 = norm_l(frac_fx32); + frac_fx32 = Mult_32_32(L_shl(pow_getbitsfrompulses_fx[temp_fx1], exp1), L_shl(frac_fx32, exp2));/*21 + exp1 + 30 + exp2 - 31 */ + frac_fx32 = L_shr(frac_fx32, exp1 + exp2) + 1;/*20 */ + + IF (LT_16(exp, integer_fx)) + { + mantissa_fx = L_shr(mantissa_fx, sub(integer_fx, exp)); + mantissa_fx = L_add(mantissa_fx, frac_fx32); + + exp = integer_fx; + move16(); + } + ELSE + { + mantissa_fx = L_add(mantissa_fx, L_shr(frac_fx32, sub(exp, integer_fx))); + } + IF (GE_32(mantissa_fx, 0x200000)) + { + exp++; + move16(); + + mantissa_fx = L_shr(mantissa_fx, 1); + } + } + + mantissa_fx = L_shl(mantissa_fx, 2);/*22 */ + temp_fx1 = extract_h(mantissa_fx); + /*temp_fx2 = extract_h(L_shl(L_sub(mantissa_fx, L_deposit_h(temp_fx1)), 15)); // 15 */ + temp32 = L_shl(L_sub(mantissa_fx, L_deposit_h(temp_fx1)), 15);/*31 */ + exp1 = sub(norm_l(temp32), 1); + temp32 = ar_div(L_shl(temp32, exp1), temp_fx1); /*31 + exp1 */ + temp32 = L_shr(temp32, exp1 + 1);/*30 */ + + frac_fx32 = L_sub(0x40000000, L_shr(temp32, 1));/*30 */ + frac_fx32 = Mult_32_32(frac_fx32, temp32);/*29 */ + frac_fx32 = L_shr(frac_fx32, 13);/*16 */ + exp1 = norm_l(temp_fx1); + temp_fx1 = Log2_norm_lc(L_shl(temp_fx1, exp1));/*15 */ + frac_fx32 = frac_fx32 + Mult_32_32(frac_fx32, 950680361); /* frac_fx32 *= 1/ln(2) */ + return L_add(L_deposit_h(exp), L_add(L_shl(temp_fx1, 1), frac_fx32)); + /*return exp + (float)temp_fx1 / pow(2.0, 15) + (float)frac_fx32 / pow(2.0, 16); */ +} + +static +void TCQnew_fx( + Word32 *v_fx, + Word32 scale_fx, + Word16 Qscale, + Word16 length, + Word16 *vout_fx, + Word16 pulses, + Word16 *pulsesout, + Word16* nzposout, + Word32 *savedstates, + Word32 * lasttrellislevel, + Word32 terminate +) +{ + Word16 i, st, dminpos, position; + Word16 pulsesnum, nzpos = 0; + + Word32 metric_fx[STATES][TCQ_MAX_BAND_SIZE]; + Word16 path_fx[STATES][TCQ_MAX_BAND_SIZE]; + Word16 quant_fx[STATES][TCQ_MAX_BAND_SIZE]; + Word16 pused_fx[STATES][TCQ_MAX_BAND_SIZE]; + Word16 quantum1_fx, quantum2_fx, newdist1_fx, newdist2_fx/*, signq_fx*/; + Word32 /*scale_fx, */tmp32, dmin_fx, curdist1_fx, curdist2_fx; + Word16 value_fx, exp; + Word16 exp1, exp2; + + set32_fx(*metric_fx, 0, STATES * TCQ_MAX_BAND_SIZE); + set16_fx( *path_fx, 0, STATES*TCQ_MAX_BAND_SIZE ); + set16_fx( *quant_fx, 0, STATES*TCQ_MAX_BAND_SIZE ); + set16_fx( *pused_fx, 0, STATES*TCQ_MAX_BAND_SIZE ); + + /* Initialize metric */ + FOR ( st = 1; st < STATES; st++) + { + metric_fx[st][0] = MAX_32>>1; + move32(); + } + FOR ( st = 2; st < STATES; st++) + { + metric_fx[st][1] = MAX_32>>1; + move32(); + } + FOR ( st = 4; st < STATES; st++) + { + metric_fx[st][2] = MAX_32>>1; + move32(); + } + /* Viterbi for input sequence */ + FOR ( i = 0; i < length; i++) /* cycle over symbols */ + { + FOR ( st = 0; st < STATES; st++) /* cycle over conditions */ + { + curdist1_fx = L_add(metric_fx[ step_tcq[st][0]][i], 0); + curdist2_fx = L_add(metric_fx[ step_tcq[st][1]][i], 0); + + exp = norm_l(scale_fx); + tmp32 = L_shl(scale_fx, exp); + tmp32 = Mult_32_16(v_fx[i], extract_h(tmp32));/*12 + 20 + exp - 16 - 15 + Qscale */ + exp1 = 26-(exp-19+Qscale); + exp2 = norm_l(tmp32); + IF( GE_16(exp2, exp1)) + { + value_fx = extract_h(L_shl(tmp32, sub(26, add(sub(exp, 19), Qscale))));/*exp -19 + Qscale*/ /*10*/ + } + ELSE + { + value_fx = extract_h(L_shl(tmp32, exp2));/*exp -19 + Qscale*/ /*10*/ + } + /* step 1 */ + quantum1_fx = quantize_fx(value_fx, denc[st][0]); + newdist1_fx = sub(shl(quantum1_fx, 10), abs_s(value_fx));/*10*/ + newdist1_fx = mult(newdist1_fx, newdist1_fx); /* 5 */ + + test(); + if (GT_16(add(quantum1_fx , pused_fx[step_tcq[st][0]][i]), pulses)&&terminate) + { + newdist1_fx = MAX_16; + move16(); + } + /* step 2 */ + quantum2_fx = quantize_fx(value_fx, denc[st][1]); + newdist2_fx = sub(shl(quantum2_fx, 10), abs_s(value_fx));/*10*/ + newdist2_fx = mult(newdist2_fx, newdist2_fx);/*5*/ + + test(); + if (GT_16(add(quantum2_fx , pused_fx[step_tcq[st][1]][i]), pulses)&&terminate) + { + newdist2_fx = MAX_16; + move16(); + } + + /* decision */ + IF (LT_32(L_add(curdist1_fx, newdist1_fx), L_add(curdist2_fx, newdist2_fx))) + { + path_fx[st][i+1] = step_tcq[st][0]; + move16(); + metric_fx[st][i+1] = L_add(curdist1_fx, newdist1_fx); + move32(); + quant_fx[st][i+1] = quantize_fx(value_fx, denc[st][0]); + move16(); + pused_fx[st][i+1] = add(pused_fx[ step_tcq[st][0]][i], abs_s( quant_fx[st][i+1] )); + move16(); + } + ELSE + { + path_fx[st][i+1] = step_tcq[st][1]; + move16(); + metric_fx[st][i+1] = L_add(curdist2_fx, newdist2_fx); + move32(); + quant_fx[st][i+1] = quantize_fx(value_fx, denc[st][1]); + move16(); + pused_fx[st][i+1] = add(pused_fx[ step_tcq[st][1]][i], abs_s( quant_fx[st][i+1] )); + move16(); + } + } + } + + /* Find path with minimal metric */ + dminpos = 0; + move16(); + dmin_fx = L_add(metric_fx[dminpos][ length], 0); + FOR ( i = 1; i < STATES; i++) + { + test(); + test(); + test(); + IF ( (GT_32(dmin_fx, metric_fx[ i][ length])&&EQ_16(pused_fx[i][length],pulses))|| + (NE_16(pused_fx[dminpos][ length], pulses) && EQ_16(pused_fx[i][ length], pulses)) ) + { + dmin_fx = L_add(metric_fx[ i][ length], 0); + dminpos = i; + move16(); + } + } + /* Trace back to get output */ + nzpos = 0; + move16(); + pulsesnum = 0; + move16(); + position = dminpos; + move16(); + FOR ( i = length; i > 0; i--) + { + vout_fx[i-1] = quant_fx[position][i]; + move16(); + if (v_fx[i-1] <= 0) + { + vout_fx[i-1] = - quant_fx[position][i]; + move16(); + } + position = path_fx[position][i]; + move16(); + savedstates[i-1] = position; + move32(); + + /* calculate output pulses number & nz */ + pulsesnum = add(pulsesnum, abs_s(vout_fx[i-1]));/*quant[position][i]; */ + IF ( abs_s(vout_fx[i-1]) > 0 ) + { + if ( nzpos == 0 ) + { + *lasttrellislevel = i; + move32(); + } + + nzpos = add(nzpos, 1); + } + } + + if ( pulsesout != 0 ) + { + *pulsesout = pulsesnum; + move16(); + } + if ( nzposout != 0 ) + { + *nzposout = nzpos; + move16(); + } + + return; +} + +Word32 GetISCScale_fx( + Word32 *quants_fx, + Word16 size, + Word32 bits_fx, + Word16 *magn_fx, + Word32 *qscale_fx, + Word32 *surplus_fx, + Word16 *pulses, + Word32* savedstates, + Word32 noTCQ, + Word16 *nzpout, + Word16 *bcount, + Word32 *abuffer, + Word16 *mbuffer, + Word32 *sbuffer +) +{ + Word32 pos, terminate, trellislevel, st; + Word32 lasttrellislevel; + Word16 i, j, m_int, leftp, leftnz, nzpos, direction, pulsesnum, diff, pulsescurr, nzposcurr; + Word16 sign; + Word16 flag_g1; + Word32 t32; + Word16 SafeExp; + + Word32 magnbits_fx = 0, tcqmagnbits_fx/*, surplus_fx, bits_fx*/; + Word16 prob0_fx, prob1_fx, num, denum, quantum1_fx, quantum2_fx; + Word32 dmin_fx, scale_fx32; + Word32 actualt_fx; + Word32 pt_fx, sxy_fx = 0, sy2_fx = 0; + Word16 pn_fx, g_fx, scale_fx; + Word16 tmp16, exp, exp1, exp2, Q_temp, hi, lo; + Word32 m_fx, tmp32; + Word32 /*quants_fx[TCQ_MAX_BAND_SIZE], */aquants_fx[TCQ_MAX_BAND_SIZE], dist_fx[TCQ_MAX_BAND_SIZE]; + Word16 exp_dist[TCQ_MAX_BAND_SIZE]; + Word16 /*magn_fx[TCQ_MAX_BAND_SIZE], */t_fx; + Word16 Qscale; + Word16 Qsxy=4; + + exp = 0; /* to avoid compilation warnings */ + Qscale = 0; /* to avoid compilation warnings */ + + set32_fx( dist_fx, 0, size ); + set16_fx(exp_dist, 31, size ); + set32_fx( aquants_fx, 0, size ); + + IF( bits_fx < 0 ) + { + pulsesnum = 0; + move16(); + + IF( surplus_fx != NULL ) + { + /* *surplus_fx += bits_fx; */ + *surplus_fx = L_add(*surplus_fx, bits_fx); + move32(); + } + } + ELSE + { + pulsesnum = GetScale_fx(size, bits_fx, surplus_fx); + } + *nzpout = 0; + move16(); + + if ( pulses != NULL) + { + *pulses = pulsesnum; + move16(); + } + + IF ( pulsesnum > 0 ) + { + /* Initial quantization */ + m_fx = L_deposit_l(0); + FOR (i = 0; i < size; i++) + { + aquants_fx[i] = L_abs(quants_fx[i]);/*Q12 */ move32(); + m_fx = L_add(m_fx, L_shr( aquants_fx[i], 2) );/*Q12 - 2*/ + } + + IF (m_fx == 0) + { + scale_fx = 0; + move16(); + FOR (i = 0; i < size; i++) + { + magn_fx[i] = 0; + move16(); + } + t_fx = 0; + move16(); + } + ELSE + { + exp1 = sub(norm_s(pulsesnum), 1); + exp2 = norm_l(m_fx); + scale_fx = div_s(shl(pulsesnum, exp1), extract_h(L_shl(m_fx, exp2)));/*15 + exp1 - (exp2 + 12 - 16) */ + + exp = 15 + exp1 - (exp2 + 12 - 16) + 2; + move16(); + t_fx = 0; + move16(); + FOR (i = 0; i < size; i++) + { + tmp32 = Mult_32_16(aquants_fx[i], scale_fx);/*12 + exp - 15 */ + tmp32 = L_shl(tmp32, sub(16, 12 + exp - 15));/*16 */ + magn_fx[i] = extract_h(L_add(32768, tmp32)); + t_fx = add(t_fx, magn_fx[i]); + } + } + + /* Pulses redistribution */ + WHILE (NE_16(t_fx, pulsesnum)) + { + pn_fx = 0; + move16(); + pt_fx = L_deposit_l(0); + + nzpos = 0; + move16(); + FOR (i = 0; i < size; i++) + { + IF (magn_fx[i] > 0) + { + pn_fx = add(pn_fx, magn_fx[i]);/*0 */ + pt_fx = L_add(pt_fx, L_shr( aquants_fx[i], 2) );/*12 */ + } + } + + direction = -1; + move16(); + if ( GT_16(pulsesnum, t_fx)) + { + direction = 1; + move16(); + } + + /* new alg */ + { + FOR ( i = 0; i < size; i++) + { + sxy_fx = L_add(sxy_fx, L_shl(Mult_32_16(aquants_fx[i], magn_fx[i]), Qsxy+3)); /* 12+0-15 +9 -> 6 */ + sy2_fx = L_add(sy2_fx, L_mult0(magn_fx[i], magn_fx[i]));/*0 */ + } + Q_temp = 32; + move16(); + FOR ( i = 0; i < size; i++) + { + IF (magn_fx[i] > 0) + { + tmp16 = add(pn_fx, direction); + tmp32 = L_add(pt_fx, 0); + } + ELSE + { + tmp16 = add(pn_fx, direction); + tmp32 = L_add(pt_fx, L_shr( aquants_fx[i], 2) ); + } + + IF (tmp32 == 0) + { + g_fx = 0; + move16(); + } + ELSE + { + exp1 = sub(norm_l(tmp32), 1); + exp2 = norm_s(tmp16); + tmp32 = L_shl(tmp32, exp1); + IF (tmp16 == 0) + { + tmp16 = 1; + move16(); + exp2 = 16; + move16(); + } + ELSE + { + tmp16 = shl(tmp16, exp2); + } + g_fx = div_s(extract_h(tmp32), tmp16);/*15 + 12 + exp1 - 16 - exp2; */ + exp = 15 + 12 + exp1 - 16 - exp2 - 2; + move16(); + } + + IF (g_fx == 0) + { + dist_fx[i] = L_deposit_l(0); + } + ELSE + { + IF (direction > 0) + { + tmp32 = L_add(sxy_fx, L_shr(aquants_fx[i], 12-Qsxy));/*Qsxy */ + t32 = L_add( sy2_fx, L_add( 1, L_deposit_l( shl(magn_fx[i], 1) ) ) ); + + IF( LT_16(norm_l(t32), 15)) + { + SafeExp = sub(16, norm_l(t32)); + tmp16 = extract_l( L_shr( t32, SafeExp) ); + } + ELSE + { + SafeExp = 0; + move16(); + tmp16 = extract_l( t32 ); + } + } + ELSE + { + tmp32 = L_sub(sxy_fx, L_shr(aquants_fx[i], 12-Qsxy));/*Qsxy */ + t32 = L_add( sy2_fx, L_sub( 1, L_deposit_l( shl(magn_fx[i], 1) ) ) ); + SafeExp = norm_l(t32); + + IF( LE_16(norm_l(t32), 15)) + { + SafeExp = sub(16, norm_l(t32)); + tmp16 = extract_l( L_shr( t32, SafeExp) ); + } + ELSE + { + SafeExp = 0; + move16(); + tmp16 = extract_l( t32 ); + } + } + tmp32 = L_shl(tmp32, 1-SafeExp); /* *2 */ + tmp32 = L_sub(L_shl(L_mult0(g_fx, tmp16), sub(Qsxy, exp)), tmp32);/*Qsxy */ + dist_fx[i] = Mult_32_16(tmp32, g_fx);/*Qsxy + exp - 15 */ move32(); + exp_dist[i] = add(Qsxy-15, exp); + move16(); + if (LT_16(exp_dist[i], Q_temp)) + { + Q_temp = exp_dist[i]; + move16(); + } + } + + } + FOR (i = 0; i < size; i++) + { + dist_fx[i] = L_shr(dist_fx[i], s_min(sub(exp_dist[i], Q_temp), 31)); + move32(); + } + } + + { + /* find min */ + pos = L_deposit_l(0); + dmin_fx = L_add(dist_fx[0], 0); + FOR (i = 1; i < size; i++) + { + IF (GT_32(dmin_fx, dist_fx[i])) + { + pos = L_deposit_l(i); + dmin_fx = L_add(dist_fx[i], 0); + } + } + /*IF (magn_fx[i] == 0 && direction < 0) */ + test(); + IF (magn_fx[pos] == 0 && direction < 0) + { + pos = L_deposit_l(0); + FOR (i = 0; i < size; i++) + { + IF (magn_fx[i] != 0) + { + pos = L_deposit_l(i); + BREAK; + } + } + dmin_fx = L_add(dist_fx[i], 0); + FOR (; i < size; i++) + { + test(); + IF (magn_fx[i] != 0 && LT_32(dmin_fx, dist_fx[i])) + { + pos = L_deposit_l(i); + dmin_fx = L_add(dist_fx[i], 0); + } + } + } + + magn_fx[pos] = add(magn_fx[pos], direction); + move16(); + t_fx = add(t_fx, direction); + } + } + + /* calculate actual nz positions */ + actualt_fx = L_deposit_l(0); + nzpos = 0; + move16(); + FOR (i = 0; i < size; i++) + { + IF (magn_fx[i] > 0) + { + if (quants_fx[i] < 0) + { + magn_fx[i] = negate(magn_fx[i]); + move16(); + } + actualt_fx = L_add(actualt_fx, L_shr( aquants_fx[i], 2) );/*12 */ + nzpos++; + } + /*magn[i] = (float)magn_fx[i]; */ + } + + /* calculate scale */ + IF (actualt_fx == 0) + { + scale_fx32 = L_add(MAX_32, 0); + } + ELSE + { + exp1 = norm_l(actualt_fx); + exp2 = sub(norm_l(pulsesnum), 1); + lo = L_Extract_lc(L_shl(actualt_fx, exp1), &hi); + scale_fx32 = Div_32(L_shl(pulsesnum, exp2), hi, lo);/*31 + exp2 - exp1 - 12 */ + Qscale = 31 + exp2 - exp1 - 12 + 2; + move16(); + } + + *qscale_fx = scale_fx32; + move32(); + *nzpout = nzpos; + move16(); + + + test(); + test(); + IF ( (NE_16(nzpos, pulsesnum)&>_16(nzpos,1))&&noTCQ==0) + { + terminate = L_deposit_l(1); + /*TCQnew( quants, scale, size, magn, pulsesnum, &pulsescurr, &nzposcurr, savedstates, &lasttrellislevel, terminate); */ + TCQnew_fx(quants_fx, scale_fx32, Qscale, + size, magn_fx, pulsesnum, &pulsescurr, &nzposcurr, savedstates, &lasttrellislevel, terminate); + IF (GT_16(pulsesnum, pulsescurr)) + { + Word32 L_tmp; + IF( GT_32( 1952247030, scale_fx32)) + { + scale_fx32 = L_add(scale_fx32, Mult_32_16(scale_fx32, 3277)); + } + ELSE + { + L_tmp = L_shr(scale_fx32, 1); + scale_fx32 = L_add(L_tmp, Mult_32_16(L_tmp, 3277)); + Qscale = sub(Qscale, 1); + } + } + + if(LT_16(pulsesnum, pulsescurr)) + { + scale_fx32 = Mult_32_16(scale_fx32, 29491); + } + IF (GT_16(pulsesnum, pulsescurr)) + { + diff = sub(pulsesnum, pulsescurr); + + FOR ( i = size-1; i >=0; i--) + { + IF ( abs_s(magn_fx[i]) > 0 ) + { + sign = -1; + move16(); + if( magn_fx[i] > 0 ) + { + sign = 1; + move16(); + } + /*magn_fx[i] = sign * abs_s(add(magn_fx[i], diff)); move32(); */ + IF (sign > 0) + { + magn_fx[i] = abs_s(add(magn_fx[i], diff)); + move16(); + } + ELSE + { + magn_fx[i] = -abs_s(add(magn_fx[i], diff)); + move16(); + } + + BREAK; + } + } + } + ELSE IF(LT_16(pulsesnum, pulsescurr)) + { + diff = sub(pulsescurr, pulsesnum); + + FOR ( i = size-1; i >=0; i--) + { + IF (diff <= 0) + { + BREAK; + } + + IF ( abs_s(magn_fx[i]) > 0 ) + { + sign = -1; + move16(); + if( magn_fx[i] > 0 ) + { + sign = 1; + move16(); + } + m_int = abs_s(magn_fx[i]); + + IF (LT_16(diff, m_int)) + { + /*magn_fx[i] = sign * sub(abs_s(magn_fx[i]), diff); move16(); */ + IF (sign > 0) + { + magn_fx[i] = sub(abs_s(magn_fx[i]), diff); + move16(); + } + ELSE + { + magn_fx[i] = - sub(abs_s(magn_fx[i]), diff); + move16(); + } + BREAK; + } + ELSE + { + diff = sub(diff, m_int); + magn_fx[i] = 0; + move16(); + nzposcurr = sub(nzposcurr, 1); + } + } + } + } + + pulsescurr = pulsesnum; + move16(); + + /* Magnitudes coding */ + { + leftp = pulsescurr; + move16();/*pulsesnum; */ + leftnz = nzposcurr; + move16(); /*nzpos; */ + trellislevel = L_deposit_l(0); + + FOR ( i = 0; i < size; i++) + { + IF (LE_16(leftnz, 1)) + { + BREAK; + } + + IF ( magn_fx[i] != 0 ) + { + FOR ( j = 0; j < leftp; j++) + { + num = sub(leftnz, 1); + denum = sub(leftp, add(j, 1)); + IF (GE_16(num, denum)) + { + prob1_fx = MAX_16; + move16(); + prob0_fx = 0; + move16(); + } + ELSE + { + exp1 = sub(norm_s(num), 1); + exp2 = norm_s(denum); + prob1_fx = div_s(shl(num, exp1), shl(denum, exp2));/*15 + exp1 - exp2 */ + exp = 15 + exp1 - exp2; + move16(); + prob1_fx = shl(prob1_fx, sub(15, exp)); + prob0_fx = sub(MAX_16, prob1_fx); + } + + st = L_add(savedstates[ trellislevel ], 0); + quantum1_fx = quantize_fx(shl(add(j, 1), 10), ddec[st][0]); + quantum2_fx = quantize_fx(shl(add(j, 1), 10), ddec[st][1]); + + test(); + IF(NE_16(quantum1_fx, add(j, 1))&&NE_16(quantum2_fx,add(j,1))) + { + /* this magnitude is not possible so set probabilities */ + prob0_fx = MAX_16; + move16(); + prob1_fx = 0; + move16(); + } + + IF (LT_16(j, sub(abs_s(magn_fx[i]), 1))) + { + exp1 = norm_s(prob0_fx); + tmp32 = L_deposit_h(shl(prob0_fx, exp1));/*exp1 + 15 + 16 */ + tmp16 = Log2_norm_lc(tmp32);/*15 */ + magnbits_fx = L_sub(magnbits_fx, L_sub(tmp16, L_shl(add(exp1, 1), 15)));/*15 */ + } + ELSE + { + exp1 = norm_s(prob1_fx); + tmp32 = L_deposit_h(shl(prob1_fx, exp1));/*exp1 + 15 + 16 */ + tmp16 = Log2_norm_lc(tmp32);/*15 */ + magnbits_fx = L_sub(magnbits_fx, L_sub(tmp16, L_shl(add(exp1, 1), 15)));/*15 */ + BREAK; + } + } + + leftnz--; + move16(); + leftp = sub(leftp, abs_s(magn_fx[i])); + } + + trellislevel = L_add(trellislevel, 1); + } + + /* Update actual occurred surplus */ + tcqmagnbits_fx = L_sub(L_sub(table_logcum_fx[pulsescurr], table_logcum_fx[nzposcurr]), table_logcum_fx[pulsescurr - (nzposcurr - 1)]); + *surplus_fx = L_add(*surplus_fx, L_sub(tcqmagnbits_fx, L_shl(magnbits_fx, 1))); + + *nzpout = nzposcurr; + move16(); + }/*magnitude coding */ + }/*TCQ */ + + IF (actualt_fx == 0) + { + scale_fx32 = L_add(MAX_32, 0); + } + ELSE + { + exp1 = norm_l(actualt_fx); + exp2 = sub(norm_l(pulsesnum), 1); + lo = L_Extract_lc(L_shl(actualt_fx, exp1), &hi); + scale_fx32 = Div_32(L_shl(pulsesnum, exp2), hi, lo);/*31 + exp2 - exp1 - 12 */ + Qscale = 31 + exp2 - exp1 - 12; + move16(); + } + test(); + IF ( GT_16(*nzpout, 1) && bcount != NULL) + { + flag_g1 = 0; + move16(); + + FOR ( i = 0; i < size; i++) + { + if( abs_s(magn_fx[i]) > 1 ) + { + flag_g1 = 1; + move16(); + } + } + /* prepare vector for TCQ */ + FOR ( i = 0; i < size; i++) + { + test(); + IF (flag_g1 == 0 || GE_16(*bcount, 2*TCQ_AMP)) + { + BREAK; + } + + IF ( abs_s(magn_fx[i]) > 0 ) + { + abuffer[*bcount] = quants_fx[i]; + move32(); + mbuffer[*bcount] = magn_fx[i]; + move16(); + /*sbuffer[*bcount] = scale_fx32;*/ + exp = norm_s(pulsesnum); + tmp16 = div_l( actualt_fx, shl( pulsesnum, exp-1) ); + tmp32 = L_shl( L_deposit_l(tmp16), exp); + /*sbuffer[*bcount] = 1/((float)tmp32/pow(2.0, 12));*/ + sbuffer[*bcount] = tmp32;/*Q12*/ move32(); + /*sbuffer[*bcount] = (float)scale_fx32 / pow(2.0, Qscale);*/ + + (*bcount)++; + + } + } + } + *qscale_fx = scale_fx32; + move32(); + } + + return L_shl(magnbits_fx, 1); +} + +void TCQLSB_fx( + Word16 bcount, + Word32 *abuffer_fx, + Word16 *mbuffer_fx, + Word32 *sbuffer_fx, + Word16 *dpath +) +{ + Word16 i, st, dminpos, position; + Word16 q_fx = 6554;/*Q15*/ + Word32 dmin_fx, curdist1_fx, curdist2_fx, newdist1_fx, newdist2_fx; + Word16 path[STATES_LSB][TCQ_LSB_SIZE]; + Word16 quant[STATES_LSB][TCQ_LSB_SIZE]; + Word16 dquant[STATES_LSB][TCQ_LSB_SIZE]; + Word16 qout[TCQ_LSB_SIZE]; + Word32 s1_fx, s2_fx, a1_fx, a2_fx; + Word16 s1_fx16, s2_fx16; + Word16 q1_fx, q2_fx, sign1_fx, sign2_fx; + Word16 dbuffer_fx[MAX_PULSES]; + + Word32 tmp1, tmp2; + Word16 exp1, exp2; + Word32 metric_fx[STATES_LSB][TCQ_LSB_SIZE]; + Word32 MaxPath; + + set32_fx(*metric_fx, 0, STATES_LSB*TCQ_LSB_SIZE); + set16_fx( *path, 0, STATES_LSB*TCQ_LSB_SIZE ); + set16_fx( *quant, 0, STATES_LSB*TCQ_LSB_SIZE ); + set16_fx( *dquant, 0, STATES_LSB*TCQ_LSB_SIZE ); + set16_fx( qout, 0, TCQ_LSB_SIZE ); + + metric_fx[1][0] = MAX_32>>8; + move32(); + metric_fx[2][0] = MAX_32>>8; + move32(); + metric_fx[3][0] = MAX_32>>8; + move32(); + + FOR( i = 0; i < 2*TCQ_AMP; i+=2 ) + { + q1_fx = mbuffer_fx[i]; + move16(); + q2_fx = mbuffer_fx[i + 1]; + move16(); + + s1_fx= L_add(sbuffer_fx[i], 0); /*12*/ + s2_fx = L_add(sbuffer_fx[i + 1], 0); /*12*/ + exp1 = norm_l(s1_fx); + exp2 = norm_l(s2_fx); + s1_fx16 = extract_h(L_shl(s1_fx, exp1));/*12 + exp1 - 16*/ + s2_fx16 = extract_h(L_shl(s2_fx, exp2));/*12 + exp2 - 16*/ + exp1 = 12 + exp1 - 16; + move16(); + exp2 = 12 + exp2 - 16; + move16(); + + a1_fx = L_add(abuffer_fx[i], 0); + a2_fx = L_add(abuffer_fx[i + 1], 0); + + MaxPath = L_add(MAX_32, 0); + + /* cycle over conditions */ + FOR ( st = 0; st < 4; st++) + { + curdist1_fx = L_add(metric_fx[ step_LSB[st][0] ][i/2], 0); + curdist2_fx = L_add(metric_fx[ step_LSB[st][1] ][i/2], 0); + + /* step 1 */ + /*sign1_fx = (denc_LSB[st][0] & 0x1)?(q_fx):(-q_fx);*/ + IF (s_and(denc_LSB[st][0], 0x1)) + { + sign1_fx = q_fx; + move16(); + } + ELSE + { + sign1_fx = negate(q_fx); + } + /*sign2_fx = (denc_LSB[st][0] & 0x2)?(q_fx):(-q_fx);*/ + IF (s_and(denc_LSB[st][0], 0x2)) + { + sign2_fx = q_fx; + move16(); + } + ELSE + { + sign2_fx = negate(q_fx); + } + tmp1 = L_sub(a1_fx, L_shl(Mult_32_16(L_add(L_shl(q1_fx, 15), sign1_fx), s1_fx16), sub(12+2, exp1)));/*12*/ + tmp2 = L_sub(a2_fx, L_shl(Mult_32_16(L_add(L_shl(q2_fx, 15), sign2_fx), s2_fx16), sub(12+2, exp2)));/*12*/ + newdist1_fx = L_add(Mult_32_32(tmp1, tmp1), Mult_32_32(tmp2, tmp2)); /* -7 */ + + /* step 2 */ + /*sign1_fx = (denc_LSB[st][1] & 0x1)?(q_fx):(-q_fx);*/ + IF (s_and(denc_LSB[st][1], 0x1)) + { + sign1_fx = q_fx; + move16(); + } + ELSE + { + sign1_fx = negate(q_fx); + } + /*sign2_fx = (denc_LSB[st][1] & 0x2)?(q_fx):(-q_fx);*/ + IF (s_and(denc_LSB[st][1], 0x2)) + { + sign2_fx = q_fx; + move16(); + } + ELSE + { + sign2_fx = negate(q_fx); + } + tmp1 = L_sub(a1_fx, L_shl(Mult_32_16(L_add(L_shl(q1_fx, 15), sign1_fx), s1_fx16), sub(12+2, exp1)));/*12*/ + tmp2 = L_sub(a2_fx, L_shl(Mult_32_16(L_add(L_shl(q2_fx, 15), sign2_fx), s2_fx16), sub(12+2, exp2)));/*12*/ + newdist2_fx = L_add(Mult_32_32(tmp1, tmp1), Mult_32_32(tmp2, tmp2));/*-7*/ + + /* decision */ + IF ( LT_32(L_add(curdist1_fx, newdist1_fx), L_add(curdist2_fx, newdist2_fx))) + { + path[st][i/2+1] = step_LSB[st][0]; + move16(); + metric_fx[st][i/2+1] = L_add(curdist1_fx, newdist1_fx); + move32(); + quant[st][i/2+1] = 0; + move16(); + dquant[st][i/2+1] = dqnt_LSB[ step_LSB[st][0] ][st]; + move16(); + } + ELSE + { + path[st][i/2+1] = step_LSB[st][1]; + move16(); + metric_fx[st][i/2+1] = L_add(curdist2_fx, newdist2_fx); + move32(); + quant[st][i/2+1] = 1; + move16(); + dquant[st][i/2+1] = dqnt_LSB[ step_LSB[st][0] ][st]; + move16(); + } + + if( GT_32( MaxPath, metric_fx[st][i/2+1])) + { + MaxPath = L_add(metric_fx[st][i/2+1], 0); + } + } + /* Metric renormalization to prevent overflow */ + FOR ( st = 0; st < 4; st++) + { + metric_fx[st][i/2+1] = L_sub( metric_fx[st][i/2+1], MaxPath ); + move32(); + } + } + + /* Find path with minimal metric */ + dminpos = 0; + move16(); + dmin_fx = L_add(metric_fx[ dminpos][ i/2], 0); + FOR ( st = 1; st < 4; st++) + { + IF ( GT_32(dmin_fx, metric_fx[ st][ i/2])) + { + dmin_fx = L_add(metric_fx[ st][ i/2], 0); + dminpos = st; + move16(); + } + } + + /* Trace back to get output */ + position = dminpos; + move16(); + + FOR ( ; i >= 0; i-=2) + { + qout[i/2] = quant[position][ i/2+1 ]; + move16(); + dpath[i/2] = dquant[position][ i/2+1 ]; + move16(); + + IF (s_and(denc_LSB[position][qout[i/2]], 0x1)) + { + dbuffer_fx[i] = 1; + move16(); + } + ELSE + { + dbuffer_fx[i] = -1; + move16(); + } + IF (s_and(denc_LSB[position][qout[i/2]], 0x2)) + { + dbuffer_fx[i + 1] = 1; + move16(); + } + ELSE + { + dbuffer_fx[i + 1] = -1; + move16(); + } + + position = path[position][i/2+1]; + move16(); + } + + /* add decoded sequence to quanta */ + FOR ( i = 0; i < bcount; i++ ) + { + mbuffer_fx[i] = add(add(mbuffer_fx[i], shl(mbuffer_fx[i], 2)), dbuffer_fx[i]); + } + + return; +} +void TCQLSBdec_fx( + Word16 *dpath, + Word16 *mbuffer, + Word16 bcount +) +{ + /*float q = QTCQ;*/ + Word16 q = 1;/*x5*/ + Word16 i, tmp, state = 0; + + tmp = shr(bcount, 1); + FOR ( i = 0; i < tmp; i++) + { + IF (s_and(ddec_LSB[state][dpath[i]], 0x1)) + { + mbuffer[2*i] = q; + move16(); + } + ELSE + { + mbuffer[2*i] = negate(q); + } + + IF (s_and(ddec_LSB[state][dpath[i]], 0x2)) + { + mbuffer[2*i + 1] = q; + move16(); + } + ELSE + { + mbuffer[2*i + 1] = negate(q); + } + + state = dstep_LSB[state][dpath[i]]; + move16(); + } + + return; +} +void RestoreTCQ_fx( + Word16 * magn, + Word16 size, + Word16 *bcount, + Word16 *mbuffer +) +{ + Word16 i, nzpos = 0, flag_g1 = 0; + + /* calculate actual nz positions */ + nzpos = 0; + move16(); + FOR ( i = 0; i < size; i++) + { + IF ( magn[i] != 0 ) + { + nzpos = add(nzpos, 1); + if ( GT_16(abs_s(magn[i]), 5)) + { + flag_g1 = 1; + move16(); + } + } + } + + IF ( GT_16(nzpos, 1)) + { + FOR( i = 0; i < size; i++) + { + test(); + IF (flag_g1 == 0 || GE_16(*bcount, 2*TCQ_AMP)) + { + BREAK; + } + + IF( abs_s(magn[i]) > 0 ) + { + magn[i] = mbuffer[*bcount]; + move16(); + *bcount = add(*bcount, 1); + } + } + } + + return; +} +void RestoreTCQdec_fx( + Word16 * magn, + Word16 size, + Word16 *bcount, + Word16 *mbuffer +) +{ + Word16 i, nzpos = 0, flag_g1 = 0; + + /* calculate actual nz positions */ + nzpos = 0; + move16(); + FOR ( i = 0; i < size; i++) + { + IF( magn[i] != 0 ) + { + nzpos = add(nzpos, 1); + if ( GT_16(abs_s(magn[i]), 1)) + { + flag_g1 = 1; + move16(); + } + magn[i] = extract_l(L_mult0(magn[i], 5)); + } + } + + IF( GT_16(nzpos, 1)) + { + FOR ( i = 0; i < size; i++) + { + test(); + IF (!(flag_g1 && LT_16(*bcount, 2*TCQ_AMP))) + { + BREAK; + } + + IF ( magn[i] != 0 ) + { + mbuffer[*bcount] = add(magn[i], mbuffer[*bcount]); + move16(); + magn[i] = mbuffer[*bcount]; + move16(); + *bcount = add(*bcount, 1); + } + } + } + + return; +} + +void InitLSBTCQ_fx( + Word16 *bcount +) +{ + *bcount = 0; + move16(); + + return; +} +void SaveTCQdata_fx( + PARCODEC arInst, + Word16 *dpath, + Word16 bcount +) +{ + Word16 i; + FOR ( i = 0; i < bcount; i++) + { + ar_encode_uniform_fx( arInst, dpath[i], 1); + } + + return; +} +void LoadTCQdata_fx( + PARCODEC arInst, + Word16 *dpath, + Word16 bcount +) +{ + Word32 i; + FOR ( i = 0; i < bcount; i++) + { + dpath[i] = ar_decode_fx( arInst, uniform_model ); + } + + return; +} + + +Word32 encode_position_ari_fx( + PARCODEC parenc, + Word16* quants, + Word16 size, + Word32* est_bits_frame_fx +) +{ + Word16 i, tmp; + Word16 nz = 0, pulses = 0; + Word16 prob[TCQ_MAX_BAND_SIZE]; + Word16 model_num_nz[TCQ_MAX_BAND_SIZE]; + Word16 *cur_quants = quants; + Word16 integer, frac; + Word32 /*est_bits_frame_fx, */btcq_fx = 0, bits_fx = 0, pnzp_fx; + + Word32 cp, scp, fxone, fxp1; + Word16 pos; + + fxone = 32768; + move32(); + fxp1 = 512*32768; + move32(); + + + + set16_fx( prob, 0, TCQ_MAX_BAND_SIZE ); + set16_fx( model_num_nz, 0, TCQ_MAX_BAND_SIZE ); + + FOR (i = 0; i < size; i ++) + { + pulses = add(pulses, abs_s(cur_quants[i])); + if (cur_quants[i] != 0) + { + nz = add(nz, 1); + } + } + + btcq_fx = GetBitsFromPulses_fx(pulses, size); + /* Estimate TCQ bits */ + bits_fx = L_sub(table_logcum_fx[size + 1], L_add(table_logcum_fx[nz + 1], table_logcum_fx[size - nz + 1])); + bits_fx = L_add(bits_fx, L_sub(btcq_fx, L_sub(table_logcum_fx[size + 1], L_add(table_logcum_fx[nz + 1], table_logcum_fx[size - nz + 1])))); + bits_fx = L_sub(bits_fx, L_sub(table_logcum_fx[pulses], L_add(table_logcum_fx[nz], table_logcum_fx[pulses - (nz - 1)]))); + bits_fx = L_sub(bits_fx, nz); + *est_bits_frame_fx = L_add(*est_bits_frame_fx, bits_fx); + + /*caculate the #nz probability */ + tmp = s_min(pulses, size); + FOR (i = 0; i < tmp; i++) + { + pnzp_fx = L_sub(L_deposit_h(add(i, 1)), btcq_fx); + pnzp_fx = L_add(pnzp_fx, L_add(L_sub(table_logcum_fx[size + 1], L_add(table_logcum_fx[i + 2], table_logcum_fx[size - i])), + L_sub(table_logcum_fx[pulses], L_add(table_logcum_fx[i + 1], table_logcum_fx[pulses - i])))); + pnzp_fx = L_add(pnzp_fx, 917498);/*16 */ + IF( GT_32( pnzp_fx, 0)) + { + integer = extract_h(pnzp_fx); + frac = extract_l(L_shr(L_sub(pnzp_fx, L_deposit_h(integer)), 1));/*15 */ + prob[i] = extract_h(L_shl(Pow2(integer, frac), 16));/*0 */ + + /*zero probability will incur problems in ar_make_model() */ + if (prob[i] == 0) + { + prob[i] = 1; + move16(); + } + } + ELSE + { + prob[i] = 1; + move16(); + } + } + + ar_make_model_fx(prob, model_num_nz, s_min(pulses, size)); + + IF (GT_16(nz, 1)) + { + ar_encode_fx(parenc, model_num_nz, nz - 1);/*encode #nz */ + scp = L_add(fxp1, 0); + pos = 0; + move16(); + FOR( i = 0; i < size; i++) + { + IF (nz <= 0) + { + BREAK; + } + + IF( nz == (size - i) ) + { + cp = L_deposit_l(0); + } + ELSE + { + cp = L_sub( fxone, div_l( L_deposit_h(nz), (size - i)) ); + } + scp = Mult_32_16( scp, extract_l(cp) ); + model_num_nz[pos+1] = round_fx( L_shl( scp, 6) ); + + test(); + test(); + IF( (model_num_nz[pos+1] == 0 && scp > 0) || model_num_nz[pos] == model_num_nz[pos+1] ) + { + model_num_nz[pos+1] = 0; + move16(); + ar_encode_fx( parenc, model_num_nz, pos ); + i--; + move16(); + scp = L_add(fxp1, 0); + pos = 0; + move16(); + CONTINUE; + } + + IF( cur_quants[i] != 0 ) + { + ar_encode_fx( parenc, model_num_nz, pos ); + pos = 0; + move16(); + scp = L_add(fxp1, 0); + nz--; + move16(); + } + ELSE + { + pos++; + move16(); + } + } + } + ELSE IF (EQ_16(nz, 1)) + { + IF (GT_16(pulses, 1)) + { + /*temp -= log2_f((float)(model_num_nz[nz-1] - model_num_nz[nz]) / MAX_AR_FREQ); */ + ar_encode_fx(parenc, model_num_nz, 0);/*encode #nz */ + } + pos = 0; + move16(); + FOR( i = 0; i < size; i++) + { + model_num_nz[i+1] = round_fx( L_shr( L_deposit_h( div_l( L_deposit_h(size - i - 1), size)), 1) ); + + if( cur_quants[i] != 0 ) + { + pos = i; + move16(); + } + } + ar_encode_fx( parenc, model_num_nz, pos ); /* encode pos */ + } + return bits_fx; +} +Word32 encode_magnitude_usq_fx( + ARCODEC* parenc, + Word16* magn_fx, + Word16 size, + Word16 npulses, + Word16 nzpos, + Word32* est_frame_bits_fx +) +{ + Word16 i, j, k, tmp, magnp, magnzp; + Word16 magn_position[MAX_PULSES]; + Word32 /*est_frame_bits_fx, */bits_fx; + Word16 pos, model_m[MAX_PULSES + 2]; + Word32 fxone, fxp1, cp, scp; + + fxone = 32768; + move32(); + fxp1 = 512*32768; + move32(); + + + /*estimate fac bits */ + bits_fx = L_sub(table_logcum_fx[npulses], L_add(table_logcum_fx[nzpos], table_logcum_fx[npulses - nzpos + 1])); + *est_frame_bits_fx = L_add(*est_frame_bits_fx, bits_fx); + + test(); + IF (EQ_16(npulses, nzpos)||EQ_16(nzpos,1)) + { + return bits_fx; + } + magnp = sub(npulses, 1); + magnzp = sub(nzpos, 1); + + /*generate the binary sequences of magnitudes */ + k = 0; + move16(); + FOR (i = 0; i < size; i++) + { + IF (magn_fx[i] != 0) + { + tmp = sub(abs_s(magn_fx[i]), 1); + FOR (j = 0; j < tmp; j++) + { + magn_position[k++] = 0; + move16(); + } + magn_position[k++] = 1; + move16(); + } + } + + set16_fx( model_m, 0, MAX_PULSES + 2); + scp = L_add(fxp1, 0); + model_m[0] = MAX_AR_FREQ; + move16(); + pos = 0; + move16(); + tmp = sub(npulses, 1); + FOR( i = 0; i < tmp; i++ ) + { + IF (magnzp <= 0) + { + BREAK; + } + + IF( magnzp == magnp ) + { + cp = L_deposit_l(0); + } + ELSE + { + cp = L_sub( fxone, div_l( L_deposit_h(magnzp), magnp) ); + } + scp = Mult_32_16( scp, extract_l(cp) ); + model_m[pos+1] = round_fx( L_shl( scp, 6) ); + + test(); + test(); + IF( (model_m[pos+1] == 0 && scp > 0) || model_m[pos] == model_m[pos+1] ) + { + model_m[pos+1] = 0; + move16(); + + ar_encode_fx( parenc, model_m, pos ); + pos = 0; + move16(); + i--; + move16(); + scp = L_add(fxp1, 0); + CONTINUE; + } + + IF( magn_position[i] != 0 ) + { + ar_encode_fx( parenc, model_m, pos ); + pos = 0; + move16(); + magnzp--; + move16(); + scp = L_add(fxp1, 0); + } + ELSE + { + pos++; + move16(); + } + + magnp--; + move16(); + } + return bits_fx; +} +Word32 encode_magnitude_tcq_fx( + ARCODEC* parenc, + Word16* magn_fx, + Word16 size, + Word16 npulses, + Word16 nzpos, + Word32* savedstates, + Word32* est_frame_bits_fx +) +{ + Word32 tcq_bits_fx, bits_fx/*, est_frame_bits_fx*/; + Word16 prob0_fx, prob1_fx, num, denum, quantum1_fx, quantum2_fx; + Word16 exp, exp1, exp2; + + Word16 i, j; + Word32 st; + Word16 magn_mode[3] = {MAX_AR_FREQ, 0, 0}; + + Word16 leftp = npulses;/*pulsesnum; */ + Word16 leftnz = nzpos;/*nzpos; */ + move16(); + move16(); + + bits_fx = L_deposit_l(0); + tcq_bits_fx = L_sub(table_logcum_fx[npulses], L_add(table_logcum_fx[nzpos], table_logcum_fx[npulses - (nzpos - 1)])); + *est_frame_bits_fx = L_add(*est_frame_bits_fx, tcq_bits_fx); + + test(); + IF (EQ_16(nzpos, npulses)||EQ_16(nzpos,1)) + { + return bits_fx; + } + + st = L_deposit_l(0); + FOR ( i = 0; i < size; i++) + { + IF (LE_16(leftnz, 1)) + { + BREAK; + } + + st = L_add(savedstates[i], 0); + IF (magn_fx[i] != 0) + { + FOR ( j = 0; j < leftp; j++) + { + /*calculate the two path probs point to next two states */ + num = sub(leftnz, 1); + denum = sub(leftp, add(j, 0x1)); + IF (GE_16(num, denum)) + { + prob1_fx = MAX_16; + move16(); + prob0_fx = 0; + move16(); + } + ELSE + { + exp1 = sub(norm_s(num), 1); + exp2 = norm_s(denum); + prob1_fx = div_s(shl(num, exp1), shl(denum, exp2));/*15 + exp1 - exp2 */ + exp = 15 + exp1 - exp2; + move16(); + prob1_fx = shl(prob1_fx, sub(15, exp)); + prob0_fx = sub(MAX_16, prob1_fx); + } + + quantum1_fx = quantize_fx(shl(add(j, 1), 10), ddec[st][0]); + quantum2_fx = quantize_fx(shl(add(j, 1), 10), ddec[st][1]); + + test(); + IF (NE_16(quantum1_fx, add(j, 1))&&NE_16(quantum2_fx,add(j,1))) + { + prob0_fx = MAX_16; + move16(); + prob1_fx = 0; + move16(); + } + + test(); + IF (EQ_16(prob0_fx, MAX_16)||EQ_16(prob1_fx,MAX_16)) + { + CONTINUE; + } + + magn_mode[1] = mult(prob1_fx, MAX_AR_FREQ); + IF (LT_16(j, sub(abs_s(magn_fx[i]), 1))) + { + ar_encode_fx(parenc, magn_mode, 0); + } + ELSE + { + IF (sub(leftp, j) > leftnz) + { + ar_encode_fx(parenc, magn_mode, 1); + } + BREAK; + } + } + + leftnz--; + move16(); + leftp = sub(leftp, abs_s( magn_fx[i] )); + } + } + + return bits_fx; +} +Word32 encode_signs_fx( + ARCODEC* parenc, + Word16* magn, + Word16 size, + Word16 npos, + Word32* est_frame_bits_fx +) +{ + Word32 i, sign; + + *est_frame_bits_fx = L_add(*est_frame_bits_fx, L_deposit_h(npos)); + FOR (i = 0; i < size; i++) + { + IF (magn[i] != 0) + { + sign = L_deposit_l(0); + if (magn[i] > 0) + { + sign = L_deposit_l(1); + } + ar_encode_uniform_fx(parenc, sign, 1); + } + } + + return L_deposit_h(npos); +} +void decode_position_ari_fx( + PARCODEC pardec, + Word16 size, + Word16 npulses, + Word16* nz, + Word16* position +) +{ + Word16 i, tmp, nzp; + Word16 mode_num_nz[TCQ_MAX_BAND_SIZE]; + Word16 prob[TCQ_MAX_BAND_SIZE]; + + Word32 btcq_fx, pnzp_fx; + Word16 integer, frac; + Word32 cp, scp, fxone, fxp1; + Word16 stpos = 0, pos, ovrflag = 0, temppos, storepos; + + fxone = 32768; + move32(); + fxp1 = 512*32768; + move32(); + temppos = 0; + move16(); + storepos = 0; + move16(); + + set16_fx( mode_num_nz, 0, TCQ_MAX_BAND_SIZE ); + set16_fx( prob, 0, TCQ_MAX_BAND_SIZE ); + + FOR (i = 0; i < size; i++) + { + position[i] = 0; + move16(); + } + + IF (GT_32(npulses, 1)) + { + btcq_fx = GetBitsFromPulses_fx(npulses, size); + tmp = s_min(npulses, size); + FOR (i = 0; i < tmp; i++) + { + /*calculate the probability of #nz */ + + pnzp_fx = L_sub(L_deposit_h(add(i, 1)), btcq_fx); + pnzp_fx = L_add(pnzp_fx, L_add(L_sub(table_logcum_fx[size + 1], L_add(table_logcum_fx[i + 2], table_logcum_fx[size - i])), + L_sub(table_logcum_fx[npulses], L_add(table_logcum_fx[i + 1], table_logcum_fx[npulses - i])))); + pnzp_fx = L_add(pnzp_fx, 917498);/*16 */ + IF( GT_32( pnzp_fx, 0)) + { + integer = extract_h(pnzp_fx); + frac = extract_l(L_shr(L_sub(pnzp_fx, L_deposit_h(integer)), 1));/*15 */ + prob[i] = extract_h(L_shl(Pow2(integer, frac), 16));/*0 */ + if (prob[i] == 0) + { + prob[i] = 1; + move16(); + } + } + ELSE + { + prob[i] = 1; + move16(); + } + } + + ar_make_model_fx(prob, mode_num_nz, s_min(npulses, size)); + *nz = add(1, ar_decode_fx(pardec, mode_num_nz));/*get #nz */ + nzp = *nz; + move16(); + IF( nzp == 1 ) + { + mode_num_nz[0] = MAX_AR_FREQ; + move16(); + FOR (i = 0; i < size; i ++) + { + mode_num_nz[i+1] = round_fx( L_shr( L_deposit_h( div_l( L_deposit_h(size - i - 1), size)), 1) ); + } + + position[ ar_decode_fx(pardec, mode_num_nz) ] = 1; + move16(); + } + ELSE + { + mode_num_nz[0] = MAX_AR_FREQ; + move16(); + + FOR( ; nzp > 0; nzp-- ) + { + scp = L_add(fxp1, 0); + temppos = 0; + move16(); + storepos = 0; + move16(); + + FOR( i = stpos; i < size; i++) + { + ovrflag = 0; + move16(); + + IF( nzp == (size - i) ) + { + cp = L_deposit_l(0); + } + ELSE + { + cp = L_sub( fxone, div_l( L_deposit_h(nzp), (size - i)) ); + } + scp = Mult_32_16( scp, extract_l(cp) ); + mode_num_nz[i+1-storepos-stpos] = round_fx( L_shl( scp, 6) ); + + test(); + test(); + IF( (mode_num_nz[i+1-storepos-stpos] == 0 && scp > 0) || mode_num_nz[i-storepos-stpos] == mode_num_nz[i+1-storepos-stpos] ) + { + mode_num_nz[i+1-storepos-stpos] = 0; + move16(); + ovrflag = 1; + move16(); + temppos = ar_decode_fx(pardec, mode_num_nz); + move16(); + storepos += temppos; + move16(); + scp = L_add(fxp1, 0); + + IF( temppos == i-stpos) /* esc transmitted */ + { + i--; + move16(); + } + ELSE + { + BREAK; + } + } + } + IF( !ovrflag ) + { + pos = ar_decode_fx(pardec, mode_num_nz) + storepos; + move16(); + } + ELSE + { + pos = storepos; + move16(); + } + + position[ stpos + pos] = 1; + move16(); + stpos += pos + 1; + move16(); + } + } + } + ELSE IF (EQ_32(npulses, 1)) + { + *nz = npulses; + move16(); + nzp = *nz; + move16(); + mode_num_nz[0] = MAX_AR_FREQ; + move16(); + FOR (i = 0; i < size; i ++) + { + mode_num_nz[i+1] = round_fx( L_shr( L_deposit_h( div_l( L_deposit_h(size - i - 1), size)), 1) ); + } + + position[ ar_decode_fx(pardec, mode_num_nz) ] = 1; + move16(); + } + ELSE + { + *nz = 0; + move16(); + } + + return; +} +void decode_magnitude_usq_fx( + ARCODEC* pardec, + Word16 size, + Word16 npulses, + Word16 nzpos, + Word16* positions, + Word16* out +) +{ + Word16 i, magnp, magnzp; + Word16 magns[TCQ_MAX_BAND_SIZE], magncout = 0; + Word16 storemagn, ovrflag = 0, pos, tempmagn = 0, mmodel[MAX_PULSES+2]; + Word32 cp, scp, fxone, fxp1; + + fxone = 32768; + move32(); + fxp1 = 512*32768; + move32(); + + set16_fx( magns, 1, TCQ_MAX_BAND_SIZE ); + IF (EQ_16(nzpos, npulses)) + { + FOR (i = 0; i < size; i++) + { + out[i] = positions[i]; + move16(); + } + return; + } + ELSE IF (EQ_16(nzpos, 1)) + { + FOR (i = 0; i < size; i++) + { + IF ( positions[i] != 0 ) + { + out[i] = npulses; + move16(); + return; + } + } + } + + magnzp = sub(nzpos, 1); + magnp = sub(npulses, 1); + + magncout = 0; + move16(); + + set16_fx( out, 0, size ); + set16_fx( mmodel, 0, MAX_PULSES+2 ); + + mmodel[0] = MAX_AR_FREQ; + move16(); + magncout = 0; + move16(); + FOR( pos = 0; pos < size; pos++) + { + scp = L_add(fxp1, 0); + IF( positions[pos] != 0) + { + storemagn = 0; + move16(); + + FOR( i = 0; i < magnp; i++) + { + ovrflag = 0; + move16(); + + IF( magnzp == (magnp-i) ) + { + cp = L_deposit_l(0); + } + ELSE + { + cp = L_sub( fxone, div_l( L_deposit_h(magnzp), magnp-i) ); + } + + IF( cp == fxone ) + { + BREAK; + } + + scp = Mult_32_16( scp, extract_l(cp) ); + mmodel[i+1-storemagn] = round_fx( L_shl( scp, 6) ); + + test(); + test(); + IF( (mmodel[i+1- storemagn] == 0 && scp > 0) || mmodel[i- storemagn] == mmodel[i+1- storemagn] ) + { + mmodel[i+1-storemagn] = 0; + move16(); + /* read data */ + tempmagn = ar_decode_fx( pardec, mmodel ); + storemagn += tempmagn; + move16(); + + IF( tempmagn < i ) + { + /* just magnitude */ + ovrflag = 1; + move16(); + BREAK; + } + ELSE + { + /* esc code */ + scp = L_add(fxp1, 0); + i--; + move16(); + } + } + } + + IF( ovrflag ) + { + out[magncout] = storemagn + 1; + move16(); + } + ELSE + { + out[magncout] = ar_decode_fx( pardec, mmodel ) + storemagn + 1; + move16(); + } + magnp -= out[magncout]; + move16(); + magnzp--; + move16(); + magncout++; + move16(); + + IF (magnzp == 0) /* last magnitude generation */ + { + FOR( pos = add(pos,1); pos < size; pos++) + { + IF( positions[pos] != 0) + { + out[magncout] = magnp + 1; + move16(); + return; + } + ELSE + { + out[magncout] = 0; + move16(); + magncout++; + move16(); + } + } + } + ELSE IF(magnzp == magnp) /* rest magnitudes generation */ + { + FOR( pos = add(pos,1); pos < size; pos++) + { + out[magncout] = positions[pos]; + move16(); + magncout++; + move16(); + } + return; + } + } + ELSE + { + out[magncout] = 0; + move16(); + magncout++; + move16(); + } + } + + return; +} +void decode_mangitude_tcq_fx( + ARCODEC* pardec, + Word16 size, + Word16 npulses, + Word16 nzpos, + Word16* positions, + Word16* out, + Word32* surplus_fx +) +{ + Word32 tcq_bits_fx, bits_fx/*, surplus_fx*/; + Word16 prob0_fx, prob1_fx, num, denum, quantum1_fx, quantum2_fx; + Word16 exp, exp1, exp2, tmp16; + Word32 tmp32; + + Word16 i, j, symbol, st; + Word16 leftp = npulses;/*pulsesnum; */ + Word16 leftnz = nzpos; /*nzpos; */ + Word16 magn_mode[3] = {MAX_AR_FREQ, 0, 0}; + + bits_fx = L_deposit_l(0); + tcq_bits_fx = L_sub(table_logcum_fx[npulses], L_add(table_logcum_fx[nzpos], table_logcum_fx[npulses - (nzpos - 1)])); + + IF (EQ_16(nzpos, npulses)) + { + FOR (i = 0; i < size; i++) + { + out[i] = positions[i]; + move16(); + } + + return; + } + ELSE IF (EQ_16(nzpos, 1)) + { + FOR (i = 0; i < size; i++) + { + IF ( positions[i] != 0 ) + { + out[i] = npulses; + move16(); + return; + } + } + } + st = 0; + move16(); + FOR (i = 0; i < size; i++) + { + IF (LE_16(leftnz, 1)) + { + BREAK; + } + + out[i] = positions[i]; + IF (positions[i] != 0) + { + /*generate the trellis path */ + symbol = 0; + move16(); + FOR (j = 0; j < leftp; j++) + { + num = sub(leftnz, 1); + denum = sub(leftp, add(j, 1)); + IF (GE_16(num, denum)) + { + prob1_fx = MAX_16; + move16(); + prob0_fx = 0; + move16(); + } + ELSE + { + exp1 = sub(norm_s(num), 1); + exp2 = norm_s(denum); + prob1_fx = div_s(shl(num, exp1), shl(denum, exp2));/*15 + exp1 - exp2 */ + exp = 15 + exp1 - exp2; + prob1_fx = shl(prob1_fx, sub(15, exp)); + prob0_fx = sub(MAX_16, prob1_fx); + } + IF (EQ_32(sub(leftp, j), leftnz)) + { + symbol = add(j, 1); + BREAK; + } + + quantum1_fx = quantize_fx(shl(add(j, 1), 10), ddec[st][0]); + quantum2_fx = quantize_fx(shl(add(j, 1), 10), ddec[st][1]); + + test(); + IF (NE_16(quantum1_fx, add(j, 1))&&NE_16(quantum2_fx,add(j,1))) + { + prob0_fx = MAX_16; + move16(); + prob1_fx = 0; + move16(); + } + + test(); + IF (EQ_16(prob0_fx, MAX_16)||EQ_16(prob1_fx,MAX_16)) + { + symbol = add(j, 1); + CONTINUE; + } + + /*magn_mode[1] = (short)(prob1 * MAX_AR_FREQ); */ + magn_mode[1] = mult(prob1_fx, MAX_AR_FREQ); + + IF (ar_decode_fx(pardec, magn_mode)) + { + exp1 = norm_s(prob1_fx); + tmp32 = L_deposit_h(shl(prob1_fx, exp1));/*exp1 + 15 + 16 */ + tmp16 = Log2_norm_lc(tmp32);/*15 */ + bits_fx = L_sub(bits_fx, L_sub(tmp16, L_shl(add(exp1, 1), 15)));/*15 */ + + symbol = add(j, 1); + BREAK; + } + ELSE + { + exp1 = norm_s(prob0_fx); + tmp32 = L_deposit_h(shl(prob0_fx, exp1));/*exp1 + 15 + 16 */ + tmp16 = Log2_norm_lc(tmp32);/*15 */ + bits_fx = L_sub(bits_fx, L_sub(tmp16, L_shl(add(exp1, 1), 15)));/*15 */ + } + } + out[i] = symbol; + move16(); + /*leftp -= symbol; */ + leftp = sub(leftp, symbol); + leftnz = sub(leftnz, 1); + } + + quantum1_fx = quantize_fx(out[i], ddec[st][0]); + quantum2_fx = quantize_fx(out[i], ddec[st][1]); + + /*generate the next state */ + IF (EQ_16(quantum1_fx, out[i])) + { + st = nextstate[st][0]; + move16(); + } + ELSE + { + st = nextstate[st][1]; + move16(); + } + } + + /*generate the magnitudes */ + FOR (; i < size; i++) + { + out[i] = 0; + move16(); + IF (positions[i] != 0) + { + out[i] = add(sub(leftp, leftnz), 1); + } + + } + + test(); + IF (NE_16(nzpos, npulses)&>_16(nzpos,1)) + { + /*update the surplus */ + *surplus_fx = L_add(*surplus_fx, L_sub(tcq_bits_fx, L_shl(bits_fx, 1))); + } + + return; +} + +void decode_signs_fx( + ARCODEC* pardec, + Word16 size, + Word16* out +) +{ + Word16 i; + + FOR ( i = 0; i < size; i++) + { + IF ( out[i] != 0 ) + { + Word16 tmp; + tmp = ar_decode_fx( pardec, uniform_model ); + + if( tmp <= 0 ) + { + out[i] = negate(out[i]); + } + } + } + + return; +} + +Word16 GetScale_fx( + Word16 blen, + Word32 bits_fx/*Q16*/, + Word32 *surplus_fx/*Q16*/ +) +{ + Word16 pulses = MAX_PULSES, p_est, exp, exp1, exp2, magicnum; + Word32 t, a, b, ab, estbits_fx = 0; + + magicnum = 24773; + move16(); /*Q17: 0.188992013101951f; */ + + t = L_shr( L_mult( magicnum, blen), 2); + exp = norm_l(t); + a = L_shl( 14 - exp, 15) + Log2_norm_lc( L_shl( t, exp ) ); + + exp1 = sub( norm_l(bits_fx), 1); + exp2 = norm_s( blen - 1 ); + b = L_shr( L_deposit_l( div_l( L_shl( bits_fx, exp1), shl( blen - 1, exp2) ) ), exp1-exp2 ); + + ab = L_add( a, b); + + p_est = extract_h(L_shl(Pow2( extract_l( L_shr(ab,15) ), ab&0x7FFF ),16)); /* enable saturationof pow2 result */ + + pulses = s_min( p_est, MAX_PULSES ); + + FOR( ; pulses >= 0; pulses--) + { + estbits_fx = GetBitsFromPulses_fx( pulses, blen); + IF( GE_32( bits_fx, estbits_fx)) + { + BREAK; + } + } + + IF ( surplus_fx != 0 ) + { + *surplus_fx = L_add(*surplus_fx, L_sub(bits_fx, estbits_fx)); + } + + return pulses; +} + +void srt_vec_ind_fx ( + const Word32 *linear, /* linear input */ + Word32 *srt, /* sorted output*/ + Word16 *I, /* index for sorted output */ + Word16 length +) +{ + Word16 pos,npos,tmp; + Word16 idxMem; + Word32 valMem; + + /*initilize */ + FOR (pos = 0; pos < length; pos++) + { + I[pos] = pos; + move16(); + } + + Copy32(linear, srt, length); + + /* now iterate */ + tmp = sub(length, 1); + FOR (pos = 0; pos < tmp; pos++) + { + FOR (npos = add(pos, 1); npos < length; npos++) + { + IF (LT_32(srt[npos], srt[pos])) + { + idxMem = I[pos]; + move16(); + I[pos] = I[npos]; + move16(); + I[npos] = idxMem; + move16(); + + valMem = L_add(srt[pos], 0); + srt[pos] = srt[npos]; + move32(); + srt[npos] = valMem; + move32(); + } + } + } + + return; +} diff --git a/lib_com/tcx_ltp.c b/lib_com/tcx_ltp.c index d50aaf72bbbbdbb62de5a2e4d41416650ea2a307..084f570239337e15b133f6a5198605a98a53c989 100644 --- a/lib_com/tcx_ltp.c +++ b/lib_com/tcx_ltp.c @@ -48,12 +48,12 @@ #define ALPHA 0.85f /*------------------------------------------------------------------- - * tcx_ltp_get_lpc() + * tcx_ltp_get_lpc_flt() * * *-------------------------------------------------------------------*/ -static void tcx_ltp_get_lpc( +static void tcx_ltp_get_lpc_flt( float *input, const int16_t length, float *A, @@ -86,12 +86,12 @@ static void tcx_ltp_get_lpc( /*------------------------------------------------------------------- - * tcx_ltp_get_zir() + * tcx_ltp_get_zir_flt() * * *-------------------------------------------------------------------*/ -static void tcx_ltp_get_zir( +static void tcx_ltp_get_zir_flt( float *zir, const int16_t length, float *synth_ltp, @@ -117,11 +117,11 @@ static void tcx_ltp_get_zir( assert( filtIdx >= 0 ); - w0 = &tcxLtpFilters[filtIdx].filt[pitch_fr]; - w1 = &tcxLtpFilters[filtIdx].filt[pitres - pitch_fr]; - v0 = &tcxLtpFilters[filtIdx].filt[0]; - v1 = &tcxLtpFilters[filtIdx].filt[pitres]; - L = tcxLtpFilters[filtIdx].length; + w0 = &tcxLtpFilters_flt[filtIdx].filt[pitch_fr]; + w1 = &tcxLtpFilters_flt[filtIdx].filt[pitres - pitch_fr]; + v0 = &tcxLtpFilters_flt[filtIdx].filt[0]; + v1 = &tcxLtpFilters_flt[filtIdx].filt[pitres]; + L = tcxLtpFilters_flt[filtIdx].length; for ( j = 0; j < lpcorder; j++ ) { @@ -161,12 +161,12 @@ static void tcx_ltp_get_zir( /*------------------------------------------------------------------- - * predict_signal() + * predict_signal_flt() * * *-------------------------------------------------------------------*/ -void predict_signal( +void predict_signal_flt( const float excI[], /* i : input excitation buffer */ float excO[], /* o : output excitation buffer */ const int16_t T0, /* i : integer pitch lag */ @@ -190,11 +190,11 @@ void predict_signal( if ( frac_max == 6 ) { - win = &inter6_2tcx2[frac][0]; + win = &inter6_2tcx2_flt[frac][0]; } else { - win = &inter4_2tcx2[frac][0]; + win = &inter4_2tcx2_flt[frac][0]; } for ( j = 0; j < L_subfr; j++ ) @@ -209,12 +209,12 @@ void predict_signal( /*------------------------------------------------------------------- - * tcx_ltp_synth_filter() + * tcx_ltp_synth_filter_flt() * * *-------------------------------------------------------------------*/ -static void tcx_ltp_synth_filter( +static void tcx_ltp_synth_filter_flt( float *synth_ltp, float *synth, const int16_t length, @@ -239,12 +239,12 @@ static void tcx_ltp_synth_filter( assert( filtIdx >= 0 ); - w0 = &tcxLtpFilters[filtIdx].filt[pitch_fr]; - w1 = &tcxLtpFilters[filtIdx].filt[pitch_res - pitch_fr]; - v0 = &tcxLtpFilters[filtIdx].filt[0]; - v1 = &tcxLtpFilters[filtIdx].filt[pitch_res]; + w0 = &tcxLtpFilters_flt[filtIdx].filt[pitch_fr]; + w1 = &tcxLtpFilters_flt[filtIdx].filt[pitch_res - pitch_fr]; + v0 = &tcxLtpFilters_flt[filtIdx].filt[0]; + v1 = &tcxLtpFilters_flt[filtIdx].filt[pitch_res]; - L = tcxLtpFilters[filtIdx].length; + L = tcxLtpFilters_flt[filtIdx].length; for ( j = 0; j < length; j++ ) @@ -276,12 +276,12 @@ static void tcx_ltp_synth_filter( /*------------------------------------------------------------------- - * tcx_ltp_synth_filter_zir() + * tcx_ltp_synth_filter_zir_flt() * * *-------------------------------------------------------------------*/ -static void tcx_ltp_synth_filter_zir( +static void tcx_ltp_synth_filter_zir_flt( float *synth_ltp, float *synth, const int16_t length, @@ -305,11 +305,11 @@ static void tcx_ltp_synth_filter_zir( assert( filtIdx >= 0 ); - w0 = &tcxLtpFilters[filtIdx].filt[pitch_fr]; - w1 = &tcxLtpFilters[filtIdx].filt[pitch_res - pitch_fr]; - v0 = &tcxLtpFilters[filtIdx].filt[0]; - v1 = &tcxLtpFilters[filtIdx].filt[pitch_res]; - L = tcxLtpFilters[filtIdx].length; + w0 = &tcxLtpFilters_flt[filtIdx].filt[pitch_fr]; + w1 = &tcxLtpFilters_flt[filtIdx].filt[pitch_res - pitch_fr]; + v0 = &tcxLtpFilters_flt[filtIdx].filt[0]; + v1 = &tcxLtpFilters_flt[filtIdx].filt[pitch_res]; + L = tcxLtpFilters_flt[filtIdx].length; for ( j = 0; j < length; j++ ) { @@ -337,12 +337,12 @@ static void tcx_ltp_synth_filter_zir( /*------------------------------------------------------------------- - * tcx_ltp_synth_filter_fadein() + * tcx_ltp_synth_filter_fadein_flt() * * *-------------------------------------------------------------------*/ -static void tcx_ltp_synth_filter_fadein( +static void tcx_ltp_synth_filter_fadein_flt( float *synth_ltp, float *synth, const int16_t length, @@ -368,11 +368,11 @@ static void tcx_ltp_synth_filter_fadein( assert( filtIdx >= 0 ); - w0 = &tcxLtpFilters[filtIdx].filt[pitch_fr]; - w1 = &tcxLtpFilters[filtIdx].filt[pitch_res - pitch_fr]; - v0 = &tcxLtpFilters[filtIdx].filt[0]; - v1 = &tcxLtpFilters[filtIdx].filt[pitch_res]; - L = tcxLtpFilters[filtIdx].length; + w0 = &tcxLtpFilters_flt[filtIdx].filt[pitch_fr]; + w1 = &tcxLtpFilters_flt[filtIdx].filt[pitch_res - pitch_fr]; + v0 = &tcxLtpFilters_flt[filtIdx].filt[0]; + v1 = &tcxLtpFilters_flt[filtIdx].filt[pitch_res]; + L = tcxLtpFilters_flt[filtIdx].length; alpha = 0.f; step = 1.f / (float) ( length ); @@ -411,12 +411,12 @@ static void tcx_ltp_synth_filter_fadein( /*------------------------------------------------------------------- - * tcx_ltp_synth_filter_fadeout() + * tcx_ltp_synth_filter_fadeout_flt() * * *-------------------------------------------------------------------*/ -static void tcx_ltp_synth_filter_fadeout( +static void tcx_ltp_synth_filter_fadeout_flt( float *synth_ltp, float *synth, const int16_t length, @@ -442,11 +442,11 @@ static void tcx_ltp_synth_filter_fadeout( assert( filtIdx >= 0 ); - w0 = &tcxLtpFilters[filtIdx].filt[pitch_fr]; - w1 = &tcxLtpFilters[filtIdx].filt[pitch_res - pitch_fr]; - v0 = &tcxLtpFilters[filtIdx].filt[0]; - v1 = &tcxLtpFilters[filtIdx].filt[pitch_res]; - L = tcxLtpFilters[filtIdx].length; + w0 = &tcxLtpFilters_flt[filtIdx].filt[pitch_fr]; + w1 = &tcxLtpFilters_flt[filtIdx].filt[pitch_res - pitch_fr]; + v0 = &tcxLtpFilters_flt[filtIdx].filt[0]; + v1 = &tcxLtpFilters_flt[filtIdx].filt[pitch_res]; + L = tcxLtpFilters_flt[filtIdx].length; alpha = 1.f; step = 1.f / (float) ( length ); @@ -482,12 +482,12 @@ static void tcx_ltp_synth_filter_fadeout( /*------------------------------------------------------------------- - * tcx_ltp_decode_params() + * tcx_ltp_decode_params_flt() * * *-------------------------------------------------------------------*/ -int16_t tcx_ltp_decode_params( +int16_t tcx_ltp_decode_params_flt( int16_t *ltp_param, int16_t *pitch_int, int16_t *pitch_fr, @@ -544,11 +544,11 @@ int16_t tcx_ltp_decode_params( } /*------------------------------------------------------------------- - *tcx_ltp_synth_filter_10() + *tcx_ltp_synth_filter_10_flt() * * ---------------------------------------------------------------------*/ -static void tcx_ltp_synth_filter_10( +static void tcx_ltp_synth_filter_10_flt( float *out, float *in, const int16_t length, @@ -572,11 +572,11 @@ static void tcx_ltp_synth_filter_10( assert( filtIdx >= 0 ); - w0 = &tcxLtpFilters[filtIdx].filt[pitch_fr]; - w1 = &tcxLtpFilters[filtIdx].filt[pitch_res - pitch_fr]; - v0 = &tcxLtpFilters[filtIdx].filt[0]; - v1 = &tcxLtpFilters[filtIdx].filt[pitch_res]; - L = tcxLtpFilters[filtIdx].length; + w0 = &tcxLtpFilters_flt[filtIdx].filt[pitch_fr]; + w1 = &tcxLtpFilters_flt[filtIdx].filt[pitch_res - pitch_fr]; + v0 = &tcxLtpFilters_flt[filtIdx].filt[0]; + v1 = &tcxLtpFilters_flt[filtIdx].filt[pitch_res]; + L = tcxLtpFilters_flt[filtIdx].length; curr_gain = gain; gain_step = -gain / length; @@ -607,12 +607,12 @@ static void tcx_ltp_synth_filter_10( /*------------------------------------------------------------------- - *tcx_ltp_synth_filter_01() + *tcx_ltp_synth_filter_01_flt() * * ---------------------------------------------------------------------*/ -static void tcx_ltp_synth_filter_01( +static void tcx_ltp_synth_filter_01_flt( float *out, float *in, const int16_t length, @@ -636,11 +636,11 @@ static void tcx_ltp_synth_filter_01( assert( filtIdx >= 0 ); - w0 = &tcxLtpFilters[filtIdx].filt[pitch_fr]; - w1 = &tcxLtpFilters[filtIdx].filt[pitch_res - pitch_fr]; - v0 = &tcxLtpFilters[filtIdx].filt[0]; - v1 = &tcxLtpFilters[filtIdx].filt[pitch_res]; - L = tcxLtpFilters[filtIdx].length; + w0 = &tcxLtpFilters_flt[filtIdx].filt[pitch_fr]; + w1 = &tcxLtpFilters_flt[filtIdx].filt[pitch_res - pitch_fr]; + v0 = &tcxLtpFilters_flt[filtIdx].filt[0]; + v1 = &tcxLtpFilters_flt[filtIdx].filt[pitch_res]; + L = tcxLtpFilters_flt[filtIdx].length; curr_gain = 0.0f; gain_step = gain / length; @@ -673,7 +673,7 @@ static void tcx_ltp_synth_filter_01( #define MAX_TRANSITION_LEN 240 /* L_FRAME_48K / 4 */ /*------------------------------------------------------------------- - *tcx_ltp_synth_filter_11_unequal_pitch() + *tcx_ltp_synth_filter_11_unequal_pitch_flt() * * blend between two filters by means of OAO * filter the input signal at the initial subinterval with @@ -683,7 +683,7 @@ static void tcx_ltp_synth_filter_01( * the current update interval with scaling from 0 towards non-zero gain ---------------------------------------------------------------------*/ -static void tcx_ltp_synth_filter_11_unequal_pitch( +static void tcx_ltp_synth_filter_11_unequal_pitch_flt( float *out, float *in, const int16_t length, @@ -719,19 +719,19 @@ static void tcx_ltp_synth_filter_11_unequal_pitch( assert( filtIdx >= 0 && prev_filtIdx >= 0 ); - w0 = &tcxLtpFilters[prev_filtIdx].filt[prev_pitch_fr]; - w1 = &tcxLtpFilters[prev_filtIdx].filt[prev_pitch_res - prev_pitch_fr]; - v0 = &tcxLtpFilters[prev_filtIdx].filt[0]; - v1 = &tcxLtpFilters[prev_filtIdx].filt[prev_pitch_res]; + w0 = &tcxLtpFilters_flt[prev_filtIdx].filt[prev_pitch_fr]; + w1 = &tcxLtpFilters_flt[prev_filtIdx].filt[prev_pitch_res - prev_pitch_fr]; + v0 = &tcxLtpFilters_flt[prev_filtIdx].filt[0]; + v1 = &tcxLtpFilters_flt[prev_filtIdx].filt[prev_pitch_res]; - prev_L = tcxLtpFilters[prev_filtIdx].length; + prev_L = tcxLtpFilters_flt[prev_filtIdx].length; - p0 = &tcxLtpFilters[filtIdx].filt[cur_pitch_fr]; - p1 = &tcxLtpFilters[filtIdx].filt[pitch_res - cur_pitch_fr]; - q0 = &tcxLtpFilters[filtIdx].filt[0]; - q1 = &tcxLtpFilters[filtIdx].filt[pitch_res]; + p0 = &tcxLtpFilters_flt[filtIdx].filt[cur_pitch_fr]; + p1 = &tcxLtpFilters_flt[filtIdx].filt[pitch_res - cur_pitch_fr]; + q0 = &tcxLtpFilters_flt[filtIdx].filt[0]; + q1 = &tcxLtpFilters_flt[filtIdx].filt[pitch_res]; - L = tcxLtpFilters[filtIdx].length; + L = tcxLtpFilters_flt[filtIdx].length; /* 1. decreasing gain filter. The first filter unit with the parameters associated to the previous interval and scaling towards 0 */ gain = prev_gain; @@ -797,12 +797,12 @@ static void tcx_ltp_synth_filter_11_unequal_pitch( /*------------------------------------------------------------------- - * tcx_ltp_post() + * tcx_ltp_post_flt() * * *-------------------------------------------------------------------*/ -void tcx_ltp_post( +void tcx_ltp_post_flt( Decoder_State *st, TCX_LTP_DEC_HANDLE hTcxLtpDec, const int16_t core, @@ -1015,7 +1015,7 @@ void tcx_ltp_post( /******** Previous-frame part ********/ - tcx_ltp_synth_filter( sig_out, sig_in, delay, hTcxLtpDec->tcxltp_pitch_int_post_prev, hTcxLtpDec->tcxltp_pitch_fr_post_prev, hTcxLtpDec->tcxltp_gain_post_prev_float, st->pit_res_max_past, hTcxLtpDec->tcxltp_filt_idx_prev ); + tcx_ltp_synth_filter_flt( sig_out, sig_in, delay, hTcxLtpDec->tcxltp_pitch_int_post_prev, hTcxLtpDec->tcxltp_pitch_fr_post_prev, hTcxLtpDec->tcxltp_gain_post_prev_float, st->pit_res_max_past, hTcxLtpDec->tcxltp_filt_idx_prev ); /******** Transition part - initial subinterval ********/ @@ -1029,21 +1029,21 @@ void tcx_ltp_post( else if ( gain == 0.f && hTcxLtpDec->tcxltp_gain_post_prev_float != 0.f ) { /* Filtering with the first filter unit */ - tcx_ltp_synth_filter_10( sig_out + delay, sig_in + delay, L_transition, hTcxLtpDec->tcxltp_pitch_int_post_prev, hTcxLtpDec->tcxltp_pitch_fr_post_prev, hTcxLtpDec->tcxltp_gain_post_prev_float, st->pit_res_max_past, hTcxLtpDec->tcxltp_filt_idx_prev ); + tcx_ltp_synth_filter_10_flt( sig_out + delay, sig_in + delay, L_transition, hTcxLtpDec->tcxltp_pitch_int_post_prev, hTcxLtpDec->tcxltp_pitch_fr_post_prev, hTcxLtpDec->tcxltp_gain_post_prev_float, st->pit_res_max_past, hTcxLtpDec->tcxltp_filt_idx_prev ); } else if ( gain != 0.f && hTcxLtpDec->tcxltp_gain_post_prev_float == 0.f ) { /* Filtering with the second filter unit */ - tcx_ltp_synth_filter_01( sig_out + delay, sig_in + delay, L_transition, pitch_int, pitch_fr, gain, st->pit_res_max, filtIdx ); + tcx_ltp_synth_filter_01_flt( sig_out + delay, sig_in + delay, L_transition, pitch_int, pitch_fr, gain, st->pit_res_max, filtIdx ); } else if ( gain == hTcxLtpDec->tcxltp_gain_post_prev_float && pitch_int == hTcxLtpDec->tcxltp_pitch_int_post_prev && pitch_fr == hTcxLtpDec->tcxltp_pitch_fr_post_prev && st->pit_res_max == st->pit_res_max_past && filtIdx == hTcxLtpDec->tcxltp_filt_idx_prev ) { - tcx_ltp_synth_filter( sig_out + delay, sig_in + delay, L_transition, pitch_int, pitch_fr, gain, st->pit_res_max, filtIdx ); + tcx_ltp_synth_filter_flt( sig_out + delay, sig_in + delay, L_transition, pitch_int, pitch_fr, gain, st->pit_res_max, filtIdx ); } else { /* Filtering with the first filter unit, followed by the filtering with the second filter unit */ - tcx_ltp_synth_filter_11_unequal_pitch( sig_out + delay, sig_in + delay, L_transition, pitch_int, pitch_fr, gain, st->pit_res_max, filtIdx, + tcx_ltp_synth_filter_11_unequal_pitch_flt( sig_out + delay, sig_in + delay, L_transition, pitch_int, pitch_fr, gain, st->pit_res_max, filtIdx, hTcxLtpDec->tcxltp_pitch_int_post_prev, hTcxLtpDec->tcxltp_pitch_fr_post_prev, hTcxLtpDec->tcxltp_gain_post_prev_float, st->pit_res_max_past, hTcxLtpDec->tcxltp_filt_idx_prev ); } } @@ -1055,28 +1055,28 @@ void tcx_ltp_post( } else if ( hTcxLtpDec->tcxltp_gain_post_prev_float == 0.f ) { - tcx_ltp_synth_filter_fadein( sig_out + delay, sig_in + delay, L_transition, pitch_int, pitch_fr, gain, st->pit_res_max, filtIdx ); + tcx_ltp_synth_filter_fadein_flt( sig_out + delay, sig_in + delay, L_transition, pitch_int, pitch_fr, gain, st->pit_res_max, filtIdx ); } else if ( gain == 0.f ) { - tcx_ltp_synth_filter_fadeout( sig_out + delay, sig_in + delay, L_transition, hTcxLtpDec->tcxltp_pitch_int_post_prev, hTcxLtpDec->tcxltp_pitch_fr_post_prev, hTcxLtpDec->tcxltp_gain_post_prev_float, st->pit_res_max_past, hTcxLtpDec->tcxltp_filt_idx_prev ); + tcx_ltp_synth_filter_fadeout_flt( sig_out + delay, sig_in + delay, L_transition, hTcxLtpDec->tcxltp_pitch_int_post_prev, hTcxLtpDec->tcxltp_pitch_fr_post_prev, hTcxLtpDec->tcxltp_gain_post_prev_float, st->pit_res_max_past, hTcxLtpDec->tcxltp_filt_idx_prev ); } else if ( gain == hTcxLtpDec->tcxltp_gain_post_prev_float && pitch_int == hTcxLtpDec->tcxltp_pitch_int_post_prev && pitch_fr == hTcxLtpDec->tcxltp_pitch_fr_post_prev ) { - tcx_ltp_synth_filter( sig_out + delay, sig_in + delay, L_transition, pitch_int, pitch_fr, gain, st->pit_res_max, filtIdx ); + tcx_ltp_synth_filter_flt( sig_out + delay, sig_in + delay, L_transition, pitch_int, pitch_fr, gain, st->pit_res_max, filtIdx ); } else { { - tcx_ltp_get_lpc( sig_out + delay - output_frame, output_frame, A, lpcorder ); - tcx_ltp_get_zir( zir, L_transition, sig_out + delay - lpcorder, sig_in + delay - lpcorder, A, lpcorder, gain, pitch_int, pitch_fr, st->pit_res_max, filtIdx ); - tcx_ltp_synth_filter_zir( sig_out + delay, sig_in + delay, L_transition, pitch_int, pitch_fr, gain, st->pit_res_max, zir, filtIdx ); + tcx_ltp_get_lpc_flt( sig_out + delay - output_frame, output_frame, A, lpcorder ); + tcx_ltp_get_zir_flt( zir, L_transition, sig_out + delay - lpcorder, sig_in + delay - lpcorder, A, lpcorder, gain, pitch_int, pitch_fr, st->pit_res_max, filtIdx ); + tcx_ltp_synth_filter_zir_flt( sig_out + delay, sig_in + delay, L_transition, pitch_int, pitch_fr, gain, st->pit_res_max, zir, filtIdx ); } } } /******** Current-frame part - subsequent subinterval, filtered with the third filter unit ********/ - tcx_ltp_synth_filter( sig_out + ( delay + L_transition ), sig_in + ( delay + L_transition ), output_frame - ( delay + L_transition ), pitch_int, pitch_fr, gain, st->pit_res_max, filtIdx ); + tcx_ltp_synth_filter_flt( sig_out + ( delay + L_transition ), sig_in + ( delay + L_transition ), output_frame - ( delay + L_transition ), pitch_int, pitch_fr, gain, st->pit_res_max, filtIdx ); /******** Output ********/ diff --git a/lib_com/tcx_ltp_fx.c b/lib_com/tcx_ltp_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..2ffe0d99c07db518a1bcb359d20138840641005e --- /dev/null +++ b/lib_com/tcx_ltp_fx.c @@ -0,0 +1,810 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ +#include +#include "options.h" +#include "prot_fx1.h" +#include "prot_fx2.h" +#include "cnst.h" +#include "basop_util.h" +#include "rom_com.h" + +/*------------------------------------------------------------------- + * Local constants + *-------------------------------------------------------------------*/ + +#define ALPHA 27853/*0.85f Q15*/ + +void tcx_ltp_get_lpc( + Word16 *x, + const Word16 L, + Word16 *A, + const Word16 order +) +{ + Word16 i, j, s, s2, tmp; + Word32 r, L_tmp; + + Word16 tmpbuf[L_FRAME_MAX], *p = x; + Word16 r_l[TCXLTP_LTP_ORDER+1], r_h[TCXLTP_LTP_ORDER+1]; + + + assert(L <= L_FRAME_MAX); + + /* calc r[0], determine shift */ + s = 0; + move16(); + r = L_deposit_l(0); + FOR (j = 0; j < L; j++) + { + L_tmp = L_sub(r, 0x40000000); + if (L_tmp > 0) s = sub(s, 1); + if (L_tmp > 0) r = L_shr(r, 2); + + tmp = shl(x[j], s); + r = L_mac0(r, tmp, tmp); + } + r = L_max(r, L_shl(100, shl(s, 1))); + r = Mpy_32_16_1(r, 16386/*1.0001f Q14*/); + s2 = norm_l(r); + r = L_shl(r, s2); + s2 = sub(s2, 1); + r_l[0] = L_Extract_lc(r, &r_h[0]); + move16(); + move16(); + + IF (s < 0) + { + /* shift buffer by s, recompute r[0] to reduce risk of instable LPC */ + r = L_deposit_l(0); + tmp = lshl((Word16)0x8000, s); /* factor corresponding to right shift by -s */ + + { + Word64 r64 = 0; + move64(); + FOR (j = 0; j < L; j++) + { + tmpbuf[j] = mult_r(x[j], tmp); + move16(); + r64 = W_mac0_16_16(r64, tmpbuf[j], tmpbuf[j]); + } + r = W_sat_l(r64); + } + r = L_max(r, L_shl(100, shl(s, 1))); + r = Mpy_32_16_1(r, 16386/*1.0001f Q14*/); + s2 = norm_l(r); + r = L_shl(r, s2); + s2 = sub(s2, 1); + r_l[0] = L_Extract_lc(r, &r_h[0]); + move16(); + move16(); + + p = tmpbuf; + } + + /* calc r[1...] */ + FOR (i = 1; i <= order; i++) + { + r = L_deposit_l(0); + + tmp = sub(L, i); + { + Word64 r64 = 0; + move64(); + FOR (j = 0; j < tmp; j++) + { + r64 = W_mac0_16_16(r64, p[j], p[j+i]); + } + r = W_sat_l(r64); + } + r = L_shl(r, s2); + r_l[i] = L_Extract_lc(r, &r_h[i]); + move16(); + move16(); + } + + E_LPC_lev_dur(r_h, r_l, A, NULL, order, NULL); + +} + +static void tcx_ltp_get_zir( + Word16 *zir, + const Word16 length, + Word16 *synth_ltp, + Word16 *synth, + Word16 *A, + const Word16 lpcorder, + const Word16 gain, + const Word16 pitch_int, + const Word16 pitch_fr, + const Word16 pitres, + const Word16 filtIdx +) +{ + Word16 buf[TCXLTP_LTP_ORDER], alpha, step; + Word16 *x0, *x1; + Word16 *y0, *y1; + Word32 s, s2; + const Word16 *w0, *w1, *v0, *v1; + Word16 i, j, k, L; + + x0 = &synth_ltp[-pitch_int]; + x1 = x0 - 1; + y0 = synth; + y1 = y0 - 1; + + assert(filtIdx >= 0); + + w0 = &tcxLtpFilters[filtIdx].filt[pitch_fr]; + w1 = &tcxLtpFilters[filtIdx].filt[sub(pitres, pitch_fr)]; + v0 = &tcxLtpFilters[filtIdx].filt[0]; + v1 = &tcxLtpFilters[filtIdx].filt[pitres]; + L = tcxLtpFilters[filtIdx].length; + move16(); + + FOR (j = 0; j < lpcorder; j++) + { + s = L_deposit_l(0); + s2 = L_deposit_l(0); + k = 0; + move16(); + FOR (i = 0; i < L; i++) + { +#ifdef BASOP_NOGLOB + s = L_mac_sat(L_mac_sat(s, w0[k], x0[i]), w1[k], x1[-i]); + s2 = L_mac_sat(L_mac_sat(s2, v0[k], y0[i]), v1[k], y1[-i]); +#else + s = L_mac(L_mac(s, w0[k], x0[i]), w1[k], x1[-i]); + s2 = L_mac(L_mac(s2, v0[k], y0[i]), v1[k], y1[-i]); +#endif + k = add(k, pitres); + } + + /* s2 *= ALPHA; + buf[j] = ( synth[j] - gain * s2 ) - ( synth_ltp[j] - gain * s ); */ +#ifdef BASOP_NOGLOB + i = sub_sat(round_fx_sat(s), mult_r_sat(round_fx_sat(s2), ALPHA)); + buf[j] = add_sat(sub_sat(synth[j], synth_ltp[j]), mult_r_sat(gain, i)); +#else + i = sub(round_fx(s), mult_r(round_fx(s2), ALPHA)); + buf[j] = add(sub(synth[j], synth_ltp[j]), mult_r(gain, i)); +#endif + move16(); + + x0++; + x1++; + y0++; + y1++; + } + + set16_fx(zir, 0, length); + + E_UTIL_synthesis(0, A, zir, zir, length, buf, 0, lpcorder); + + alpha = 0x7FFF; + move16(); + /* step = 1.f/(float)(length/2); */ + step = shl(4, norm_s(length)); + if (s_and(length, sub(length, 1)) != 0) + { + step = mult_r(step, 26214/*64.f/80.f Q15*/); + } + if (EQ_16(length, 240)) + { + step = 273/*1.f/120.f Q15*/; + move16(); + } + + FOR (j = shr(length, 1); j < length; j++) + { + zir[j] = mult_r(zir[j], alpha); + move16(); + alpha = sub(alpha, step); + } +} + +void predict_signal( + const Word16 excI[], /* i : input excitation buffer */ + Word16 excO[], /* o : output excitation buffer */ + const Word16 T0, /* i : integer pitch lag */ + Word16 frac, /* i : fraction of lag */ + const Word16 frac_max, /* i : max fraction */ + const Word16 L_subfr /* i : subframe size */ +) +{ + Word16 j; + Word32 s; + const Word16 *x0, *win; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + x0 = &excI[-T0-1]; + frac = negate(frac); + + IF (frac < 0) + { + frac = add(frac, frac_max); + x0--; + } + + win = &inter4_2tcx2[frac][0]; + if (EQ_16(frac_max, 6))win=&inter6_2tcx2[frac][0]; + + FOR (j = 0; j < L_subfr; j++) + { +#ifdef BASOP_NOGLOB + s = L_mult_o(win[0], x0[0], &Overflow); + s = L_mac_o(s, win[1], x0[1], &Overflow); + s = L_mac_o(s, win[2], x0[2], &Overflow); + excO[j] = mac_ro(s, win[3], x0[3], &Overflow); +#else + s = L_mult(win[0], x0[0]); + s = L_mac(s, win[1], x0[1]); + s = L_mac(s, win[2], x0[2]); + excO[j] = mac_r(s, win[3], x0[3]); +#endif + move16(); + + x0++; + } + +} + +static void tcx_ltp_synth_filter( + Word16 *synth_ltp, + Word16 *synth, + Word16 length, + Word16 pitch_int, + Word16 pitch_fr, + Word16 gain, + Word16 pitch_res, + Word16 *zir, /* can be NULL */ + Word16 fade, /* 0=normal, +1=fade-in, -1=fade-out */ + Word16 filtIdx + ) +{ + Word16 *x0, *x1; + Word16 *y0, *y1; + Word32 s, s2; + const Word16 *v0, *v1; + const Word16 *w0, *w1; + Word16 alpha, step = 0; /* initialize just to avoid compiler warning */ + Word16 i, j, k, L; + + IF (gain > 0) + { + x0 = &synth_ltp[-pitch_int]; + x1 = x0 - 1; + y0 = synth; + y1 = y0 - 1; + + assert(filtIdx >= 0); + + w0 = &tcxLtpFilters[filtIdx].filt[pitch_fr]; + w1 = &tcxLtpFilters[filtIdx].filt[sub(pitch_res, pitch_fr)]; + v0 = &tcxLtpFilters[filtIdx].filt[0]; + v1 = &tcxLtpFilters[filtIdx].filt[pitch_res]; + + L = tcxLtpFilters[filtIdx].length; + move16(); + + alpha = 0; + move16(); + IF (fade != 0) + { + if (fade < 0) + { + alpha = 0x7FFF; + move16(); + } + + /* step = 1.f/(float)(length); */ + step = shl(2, norm_s(length)); + if (s_and(length, sub(length, 1)) != 0) + { + step = mult_r(step, 26214/*64.f/80.f Q15*/); + } + if (EQ_16(length, 240)) + { + step = 137/*1.f/240.f Q15*/; + move16(); + } + + if (fade < 0) step = negate(step); + } + + FOR(j = 0; j < length; j++) + { + s = L_deposit_l(0); + s2 = L_deposit_l(0); + k = 0; + move16(); + FOR(i = 0; i < L; i++) + { +#ifdef BASOP_NOGLOB + s = L_mac_sat(L_mac_sat(s, w0[k], x0[i]), w1[k], x1[-i]); + s2 = L_mac_sat(L_mac_sat(s2, v0[k], y0[i]), v1[k], y1[-i]); +#else + s = L_mac(L_mac(s, w0[k], x0[i]), w1[k], x1[-i]); + s2 = L_mac(L_mac(s2, v0[k], y0[i]), v1[k], y1[-i]); +#endif + k = add(k, pitch_res); + } + + /* s2 *= ALPHA; + normal: synth_ltp[j] = synth[j] - gain * s2 + gain * s; + zir: synth_ltp[j] = synth[j] - gain * s2 + gain * s - zir[j]; + fade-in/out: synth_ltp[j] = synth[j] - alpha * gain * s2 + alpha * gain * s; */ +#ifdef BASOP_NOGLOB + i = sub_sat(round_fx_sat(s), mult_r_sat(round_fx_sat(s2), ALPHA)); +#else + i = sub(round_fx(s), mult_r(round_fx(s2), ALPHA)); +#endif + k = mult_r(gain, i); + if (fade != 0) k = mult_r(k, alpha); +#ifdef BASOP_NOGLOB + k = add_sat(synth[j], k); + if (zir != NULL) + { + k = sub_sat(k, zir[j]); + } +#else + k = add(synth[j], k); + if (zir != NULL) k = sub(k, zir[j]); +#endif + + synth_ltp[j] = k; + move16(); + + BASOP_SATURATE_WARNING_OFF_EVS; +#ifdef BASOP_NOGLOB + if (fade != 0) + { + alpha = add_sat(alpha, step); + } +#else + if (fade != 0) alpha = add(alpha, step); +#endif + BASOP_SATURATE_WARNING_ON_EVS; + + x0++; + x1++; + y0++; + y1++; + } + } + ELSE + { + Copy( synth, synth_ltp, length ); + } +} + +Word16 tcx_ltp_decode_params( + Word16 *ltp_param, + Word16 *pitch_int, + Word16 *pitch_fr, + Word16 *gain, + Word16 pitmin, + Word16 pitfr1, + Word16 pitfr2, + Word16 pitmax, + Word16 pitres +) +{ + Word16 tmp, tmp2; + + + + /* Decode Pitch and Gain */ + test(); + IF (ltp_param != 0 && ltp_param[0] != 0) + { + tmp = imult1616(sub(pitfr2, pitmin), pitres); + + IF ( LT_16(ltp_param[1], tmp)) + { + tmp2 = idiv1616U(ltp_param[1], pitres); + + *pitch_int = add(pitmin, tmp2); + move16(); + *pitch_fr = sub(ltp_param[1], imult1616(tmp2, pitres)); + move16(); + } + ELSE + { + pitres = shr(pitres, 1); + tmp2 = imult1616(sub(pitfr1, pitfr2), pitres); + + IF ( LT_16(ltp_param[1], add(tmp, tmp2))) + { + tmp2 = idiv1616U(sub(ltp_param[1], tmp), pitres); + + *pitch_int = add(pitfr2, tmp2); + move16(); + *pitch_fr = shl( sub(sub(ltp_param[1], tmp), imult1616(tmp2, pitres)), 1 ); + move16(); + } + ELSE + { + *pitch_int = sub(add(ltp_param[1], pitfr1), add(tmp, tmp2)); + move16(); + *pitch_fr = 0; + move16(); + } + } + + *gain = imult1616(add(ltp_param[2], 1), 0x1400); + move16(); + + IF( LT_16(*pitch_int,PIT_MIN_SHORTER)) + { + /*pitch out of range due to bit error */ + *pitch_int = PIT_MIN_SHORTER; + move16(); + return 1; + } + + IF( GT_16(*pitch_int,PIT_MAX_MAX)) + { + /*pitch out of range due to bit error */ + *pitch_int = PIT_MAX_MAX; + move16(); + return 1; + } + } + ELSE + { + *pitch_int = pitmax; + move16(); + *pitch_fr = 0; + move16(); + *gain = 0; + move16(); + } + + return 0; +} + +void tcx_ltp_post( + Decoder_State* st, + TCX_LTP_DEC_HANDLE hTcxLtpDec, + Word16 core, + Word16 output_frame, + Word16 delay, + Word16 *sig, + Word16 *tcx_buf +) +{ + Word16 tmp, L_transition, lpcorder, filtIdx; + Word16 gain, gain2; + Word32 tmp32; + Word16 zir[L_FRAME_PLUS/4], A[TCXLTP_LTP_ORDER+1]; + Word16 buf_in[TCXLTP_MAX_DELAY+L_FRAME48k+TCXLTP_MAX_DELAY], buf_out[2*L_FRAME48k]; + Word16 *sig_in, *sig_out; + Word16 pitch_int, pitch_fr; + Word16 tcx_buf_len, bfi, L_frame_core, SideInfoOnly; + Word32 total_brate; + + total_brate = st->total_brate; + move32(); + IF (EQ_16(st->element_mode, IVAS_CPE_MDCT)) + { + total_brate = st->bits_frame_nominal* FRAMES_PER_SEC; + move32(); + } + + filtIdx = 0; /* just to avoid comilation warnings */ + tcx_buf_len = NS2SA(st->output_Fs, TCXLTP_DELAY_NS); + SideInfoOnly = 0; + + if (GE_32(total_brate, HQ_96k)) + { + SideInfoOnly = 1; + move16(); + } + + L_frame_core = st->L_frame; + move16(); + + if (EQ_16(st->element_mode, IVAS_CPE_MDCT)) + { + L_frame_core = L_FRAME; + move16(); + } + + IF (EQ_16(core, ACELP_CORE)) + { + bfi = 0; + pitch_int = 0; + pitch_fr = 0; + gain = 0; + L_frame_core = st->L_frame_past; + move16(); move16(); move16(); move16(); + } + ELSE + { + bfi = st->bfi; + pitch_int = hTcxLtpDec->tcxltp_pitch_int; + pitch_fr = hTcxLtpDec->tcxltp_pitch_fr; + gain = hTcxLtpDec->tcxltp_gain; + move16(); move16(); move16(); move16(); + } + /******** Init ********/ + + + /* Parameters */ + L_transition = shr(output_frame, 2); + lpcorder = TCXLTP_LTP_ORDER; + move16(); + + /* Input buffer */ + sig_in = buf_in + tcx_buf_len; + Copy(hTcxLtpDec->tcxltp_mem_in, buf_in, tcx_buf_len ); + Copy( sig, buf_in+tcx_buf_len, output_frame ); + IF ( core > ACELP_CORE ) + { + Copy( tcx_buf, sig_in+output_frame, tcx_buf_len ); + } + Copy( sig+output_frame-tcx_buf_len, hTcxLtpDec->tcxltp_mem_in, tcx_buf_len ); + + /* Output buffer */ + sig_out = buf_out + output_frame; + Copy(hTcxLtpDec->tcxltp_mem_out, buf_out, output_frame ); + + /* TCX-LTP parameters: integer pitch, fractional pitch, gain */ + test(); + test(); + IF ( !(SideInfoOnly != 0 || hTcxLtpDec->tcxltp != 0) || EQ_16(core, ACELP_CORE)) + { + /* No LTP */ + pitch_int = 0; + move16(); + pitch_fr = 0; + move16(); + gain = 0; + move16(); + } + ELSE IF (bfi == 0) + { + /* LTP and good frame */ + IF(EQ_16(st->element_mode, EVS_MONO)) /* hard tunings for EVS_MONO, HQ_48k is TCX only */ + { + IF(NE_16(output_frame, L_frame_core)) + { + tmp = div_s(output_frame, shl(L_frame_core, 2)); /* Q13 */ + tmp32 = L_mult0(add(imult1616(pitch_int, st->pit_res_max), pitch_fr), tmp); /* Q13 */ + tmp = round_fx(L_shl(tmp32, 3)); /* Q0 */ + pitch_int = idiv1616U(tmp, st->pit_res_max); + pitch_fr = sub(tmp, imult1616(pitch_int, st->pit_res_max)); + } + test(); + test(); + IF(EQ_32(total_brate, 48000) && EQ_16(L_frame_core, L_FRAME16k)) + { + gain = mult_r(gain, 10486/*0.32f Q15*/); + } + ELSE IF(EQ_32(total_brate, 48000) && EQ_16(L_frame_core, 512)) + { + gain = mult_r(gain, 13107/*0.40f Q15*/); + } + ELSE + { + gain = mult_r(gain, 20972/*0.64f Q15*/); + } + } + ELSE IF (GT_16(st->element_mode, IVAS_SCE) && GE_32(total_brate, IVAS_96k)) + { + gain = mult_r(gain, 13107/*0.40f Q15*/); + } + ELSE + { + gain = mult_r(gain, 20972/*0.64f Q15*/); + } + } + ELSE + { + /* PLC: [TCX: Fade-out] + * PLC: LTP and bad frame (concealment) */ + IF (st->pit_res_max == st->pit_res_max_past) /* ensure consistent core SR to previous frame; otherwise, set gain to 0 */ + { + pitch_int = hTcxLtpDec->tcxltp_pitch_int_post_prev; + move16(); + pitch_fr = hTcxLtpDec->tcxltp_pitch_fr_post_prev; + move16(); + gain = shl(mult_r(hTcxLtpDec->tcxltp_gain_post_prev, st->hTcxDec->damping), 1); + } + ELSE + { + gain = 0; + move16(); + } + } + + + IF ( SideInfoOnly != 0 ) + { + gain = 0; + move16(); + if ( bfi != 0 ) + { + hTcxLtpDec->tcxltp_gain_post_prev = 0; + move16(); + } + } + gain2 = gain; + move16(); + + IF (EQ_16(L_frame_core, L_FRAME)) + { + SWITCH ( output_frame ) + { + case L_FRAME8k: + filtIdx = 0; + move16(); + BREAK; + case L_FRAME16k: + filtIdx = 1; + move16(); + BREAK; + case L_FRAME32k: + filtIdx = 2; + move16(); + BREAK; + case L_FRAME48k: + filtIdx = 3; + move16(); + BREAK; + default: + assert(0); + } + } + ELSE IF (EQ_16(L_frame_core, L_FRAME16k)) + { + SWITCH ( output_frame ) + { + case L_FRAME8k: + filtIdx = 4; + move16(); + BREAK; + case L_FRAME16k: + filtIdx = 5; + move16(); + BREAK; + case L_FRAME32k: + filtIdx = 6; + move16(); + BREAK; + case L_FRAME48k: + filtIdx = 7; + move16(); + BREAK; + default: + assert(0); + } + } + ELSE IF (EQ_16(L_frame_core, 512)) + { + SWITCH ( output_frame ) + { + case L_FRAME8k: + filtIdx = 8; + move16(); + BREAK; + case L_FRAME16k: + filtIdx = 9; + move16(); + BREAK; + case L_FRAME32k: + filtIdx = 10; + move16(); + BREAK; + case L_FRAME48k: + filtIdx = 11; + move16(); + BREAK; + default: + assert(0); + } + } + ELSE + { + filtIdx = -1; + move16(); + } + + + /******** Previous-frame part ********/ + + tcx_ltp_synth_filter( sig_out, sig_in, delay, hTcxLtpDec->tcxltp_pitch_int_post_prev, hTcxLtpDec->tcxltp_pitch_fr_post_prev, hTcxLtpDec->tcxltp_gain_post_prev, + st->pit_res_max_past, NULL, 0, hTcxLtpDec->tcxltp_filt_idx_prev); + + /******** Transition part ********/ + + test(); + test(); + test(); +#ifdef IVAS_CODE_TCX_LTP + if (st->element_mode != EVS_MONO) + { + if (gain == 0.f && hTcxLtpDec->tcxltp_gain_post_prev == 0.f) + { + /* The filtering is deactivated, just copy input to the output */ + mvr2r(sig_in + delay, sig_out + delay, L_transition); + } + else if (gain == 0.f && hTcxLtpDec->tcxltp_gain_post_prev != 0.f) + { + /* Filtering with the first filter unit */ + tcx_ltp_synth_filter_10(sig_out + delay, sig_in + delay, L_transition, hTcxLtpDec->tcxltp_pitch_int_post_prev, hTcxLtpDec->tcxltp_pitch_fr_post_prev, hTcxLtpDec->tcxltp_gain_post_prev, st->pit_res_max_past, hTcxLtpDec->tcxltp_filt_idx_prev); + } + else if (gain != 0.f && hTcxLtpDec->tcxltp_gain_post_prev == 0.f) + { + /* Filtering with the second filter unit */ + tcx_ltp_synth_filter_01(sig_out + delay, sig_in + delay, L_transition, pitch_int, pitch_fr, gain, st->pit_res_max, filtIdx); + } + else if (gain == hTcxLtpDec->tcxltp_gain_post_prev && pitch_int == hTcxLtpDec->tcxltp_pitch_int_post_prev && pitch_fr == hTcxLtpDec->tcxltp_pitch_fr_post_prev && st->pit_res_max == st->pit_res_max_past && filtIdx == hTcxLtpDec->tcxltp_filt_idx_prev) + { + tcx_ltp_synth_filter(sig_out + delay, sig_in + delay, L_transition, pitch_int, pitch_fr, gain, st->pit_res_max, filtIdx); + } + else + { + /* Filtering with the first filter unit, followed by the filtering with the second filter unit */ + tcx_ltp_synth_filter_11_unequal_pitch(sig_out + delay, sig_in + delay, L_transition, pitch_int, pitch_fr, gain, st->pit_res_max, filtIdx, + hTcxLtpDec->tcxltp_pitch_int_post_prev, hTcxLtpDec->tcxltp_pitch_fr_post_prev, hTcxLtpDec->tcxltp_gain_post_prev, st->pit_res_max_past, hTcxLtpDec->tcxltp_filt_idx_prev); + } + } + ELSE +#endif + { + IF(gain == 0 && hTcxLtpDec->tcxltp_gain_post_prev == 0) + { + Copy(sig_in + delay, sig_out + delay, L_transition); + } + ELSE IF(hTcxLtpDec->tcxltp_gain_post_prev == 0) + { + tcx_ltp_synth_filter(sig_out + delay, sig_in + delay, L_transition, pitch_int, + pitch_fr, gain, st->pit_res_max, NULL, 1, filtIdx ); + } + ELSE IF(gain == 0) + { + tcx_ltp_synth_filter(sig_out + delay,sig_in + delay,L_transition, hTcxLtpDec->tcxltp_pitch_int_post_prev, hTcxLtpDec->tcxltp_pitch_fr_post_prev, + hTcxLtpDec->tcxltp_gain_post_prev, st->pit_res_max_past, NULL, -1, hTcxLtpDec->tcxltp_filt_idx_prev); + } + ELSE IF(EQ_16(gain, hTcxLtpDec->tcxltp_gain_post_prev) && EQ_16(pitch_int,hTcxLtpDec->tcxltp_pitch_int_post_prev) && EQ_16(pitch_fr,hTcxLtpDec->tcxltp_pitch_fr_post_prev)) + { + tcx_ltp_synth_filter(sig_out + delay, sig_in + delay, L_transition, pitch_int, pitch_fr, gain, st->pit_res_max, NULL, 0, filtIdx ); + } + ELSE + { + tcx_ltp_get_lpc(sig_out + delay - output_frame, output_frame, A, lpcorder); + + tcx_ltp_get_zir(zir, L_transition, sig_out + delay - lpcorder, sig_in + delay - lpcorder, A, lpcorder, gain, pitch_int, pitch_fr, st->pit_res_max, filtIdx); + + tcx_ltp_synth_filter(sig_out + delay, sig_in + delay, L_transition, pitch_int, pitch_fr, gain, st->pit_res_max, zir, 0, filtIdx); + } + } + + /******** Current-frame part - subsequent subinterval, filtered with the third filter unit ********/ + + tcx_ltp_synth_filter( sig_out+(delay+L_transition),sig_in+(delay+L_transition), output_frame-(delay+L_transition), pitch_int, pitch_fr, gain, st->pit_res_max, NULL, 0, filtIdx); + + + /******** Output ********/ + + + /* copy to output */ + + Copy( sig_out, sig, output_frame ); + + /* Update */ + hTcxLtpDec->tcxltp_pitch_int_post_prev = pitch_int; + move16(); + hTcxLtpDec->tcxltp_pitch_fr_post_prev = pitch_fr; + move16(); + hTcxLtpDec->tcxltp_gain_post_prev = gain2; + move16(); + hTcxLtpDec->tcxltp_filt_idx_prev = filtIdx; + move16(); + st->pit_res_max_past = st->pit_res_max; + Copy( sig_out, hTcxLtpDec->tcxltp_mem_out, output_frame ); + +} diff --git a/lib_com/tcx_mdct.c b/lib_com/tcx_mdct.c index e8ac35d07aa1c67f1cc385de95ad4330e8d38464..e3a0d02e18505b6aad3ffdc21b39e3be8de66d99 100644 --- a/lib_com/tcx_mdct.c +++ b/lib_com/tcx_mdct.c @@ -42,12 +42,12 @@ #include "wmc_auto.h" /*-------------------------------------------------------------------* - * TCX_MDCT() + * TCX_MDCT_flt() * * *-------------------------------------------------------------------*/ -void TCX_MDCT( +void TCX_MDCT_flt( const float *x, float *y, const int16_t l, @@ -88,12 +88,12 @@ void TCX_MDCT( /*-------------------------------------------------------------------* - * TCX_MDST() + * TCX_MDST_flt() * * *-------------------------------------------------------------------*/ -void TCX_MDST( +void TCX_MDST_flt( const float *x, float *y, const int16_t l, @@ -131,12 +131,12 @@ void TCX_MDST( /*-------------------------------------------------------------------* - * TCX_MDCT_Inverse() + * TCX_MDCT_Inverse_flt() * * *-------------------------------------------------------------------*/ -void TCX_MDCT_Inverse( +void TCX_MDCT_Inverse_flt( const float *x, float *y, const int16_t l, @@ -171,12 +171,12 @@ void TCX_MDCT_Inverse( /*-------------------------------------------------------------------* - * TCX_MDST_Inverse() + * TCX_MDST_Inverse_flt() * * *-------------------------------------------------------------------*/ -void TCX_MDST_Inverse( +void TCX_MDST_Inverse_flt( const float *x, float *y, const int16_t l, @@ -211,12 +211,12 @@ void TCX_MDST_Inverse( /*-------------------------------------------------------------------* - * TCX_MDXT_Inverse() + * TCX_MDXT_Inverse_flt() * * *-------------------------------------------------------------------*/ -void TCX_MDXT_Inverse( +void TCX_MDXT_Inverse_flt( const float *x, float *y, const int16_t l, diff --git a/lib_com/tcx_mdct_fx.c b/lib_com/tcx_mdct_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..9a04ae0633fdf8cd4a91224c4db2ef5215176de9 --- /dev/null +++ b/lib_com/tcx_mdct_fx.c @@ -0,0 +1,273 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include +#include "options.h" +#include "cnst.h" +#include "prot_fx1.h" +#include "prot_fx2.h" +#include "basop_util.h" + +static Word16 TCX_MDCT_GetScaleFactor( + const Word16 L, + Word16 *factor_e +) +{ + + Word16 factor; + + IF(EQ_16(L, NORM_MDCT_FACTOR)) + { + factor = 32767; + move16(); + *factor_e = 0; + move16(); + } + ELSE IF(EQ_16(L, 2*NORM_MDCT_FACTOR)) + { + factor = 23170; + move16(); + *factor_e = 0; + move16(); + } + ELSE IF(EQ_16(L, 4*NORM_MDCT_FACTOR)) + { + factor = 16384; + move16(); + *factor_e = 0; + move16(); + } + ELSE + { + + factor = mult_r(shl(L, 4), 26214 /*128.f / NORM_MDCT_FACTOR*/); /* 4Q11 */ + *factor_e = 4; + move16(); + + factor = ISqrt16(factor, factor_e); + } + + return factor; +} + +static Word16 TCX_MDCT_Inverse_GetScaleFactor( + const Word16 L, + Word16 *factor_e +) +{ + + Word16 factor; + + IF(EQ_16(L, NORM_MDCT_FACTOR)) + { + factor = 32767; + move16(); + *factor_e = 0; + move16(); + } + ELSE IF(EQ_16(L, 2*NORM_MDCT_FACTOR)) + { + factor = 23170; + move16(); + *factor_e = 1; + move16(); + } + ELSE IF(EQ_16(L, 4*NORM_MDCT_FACTOR)) + { + factor = 32767; + move16(); + *factor_e = 1; + move16(); + } + ELSE + { + factor = mult_r(shl(L, 4), 26214 /*128.f / NORM_MDCT_FACTOR*/); /* 4Q11 */ + *factor_e = 4; + move16(); + + factor = Sqrt16(factor, factor_e); + } + + return factor; +} + + +void TCX_MDCT( + const Word16 *x, + Word32 *y, + Word16* y_e, + const Word16 l, + const Word16 m, + const Word16 r, + const Word16 element_mode +) +{ + + Word16 i; + Word16 factor, neg_factor; + Word16 factor_e; +#ifdef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING + (void)element_mode; +#endif +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + factor = TCX_MDCT_GetScaleFactor(add(add(shr(l, 1), m), shr(r, 1)), &factor_e); + *y_e = add(*y_e, factor_e); + + neg_factor = negate(factor); + + + /* Init */ + FOR(i=0; i #include "cnst.h" #include "prot.h" +#include "prot_fx1.h" +#include "prot_fx2.h" #include "rom_com.h" #include "wmc_auto.h" + +const PWord16* getSineWindowTable(Word16 length); /*------------------------------------------------------------------- - * mdct_window_sine() + * mdct_window_sine_flt() * * *-------------------------------------------------------------------*/ -void mdct_window_sine( +void mdct_window_sine_flt( float *window, const int32_t Fs, const int16_t n, const int16_t window_type, const int16_t element_mode ) { - if ( element_mode == EVS_MONO ) + if ( element_mode == EVS_MONO) { int16_t i; float c; @@ -66,6 +70,7 @@ void mdct_window_sine( { window[i] = (float) sin( c * ( 0.5f + (float) i ) ); } + } else { @@ -101,18 +106,133 @@ void mdct_window_sine( lerp_flt( window_table, window, n, buf_in_size ); } } - return; } +void mdct_window_sine_IVAS_updated( + PWord16 *window, + const int32_t Fs, + const int16_t n, + const int16_t window_type, + const int16_t element_mode) +{ + if (element_mode == EVS_MONO) + { + const PWord16 *table; + table = getSineWindowTable(n); + for (int i = 0; i < n / 2; i++) + { + window[i].v.re = table[i].v.re; + window[i].v.im = table[i].v.im; + } + //PMT("getSineWindowTable needs to be updated for IVAS") + } + else + { + const Word16* window_table = 0; + int16_t buf_in_size = 0; + Word16 temp[420] = { 0 }; + switch (window_type) + { + case FULL_OVERLAP: + window_table = tcx_mdct_window_48_fx; + buf_in_size = 420; + break; + case HALF_OVERLAP: + window_table = tcx_mdct_window_half_48_fx; + buf_in_size = 180; + break; + case TRANSITION_OVERLAP: + case MIN_OVERLAP: + window_table = tcx_mdct_window_trans_48_fx; + buf_in_size = 60; + break; + + default: + assert(0 && "Unsupported window type"); + break; + } + + if (Fs == 48000) + { + Copy(window_table, temp, n); + } + else + { + lerp(window_table, temp, n, buf_in_size); + } + + for (int i = 0; i < n / 2; i++) + { + window[i].v.re = temp[n - 1 - i]; + window[i].v.im = temp[i]; + } + + } +} + +////Use mdct_window_sine_IVAS_updated for IVAS (EVS path covered as well) +void mdct_window_sine(PWord16 *window, Word16 n) +{ +#ifdef IVAS_CODE + if (element_mode == EVS_MONO) +#endif + { + const PWord16 *table; + table = getSineWindowTable(n); + for (int i = 0; i < n / 2; i++) + { + window[i].v.re = table[i].v.re; + window[i].v.im = table[i].v.im; + } + //PMT("getSineWindowTable needs to be updated for IVAS") + } +#ifdef IVAS_CODE + else + { + const float* window_table = 0; + int16_t buf_in_size = 0; + switch (window_type) + { + case FULL_OVERLAP: + window_table = tcx_mdct_window_48; + buf_in_size = 420; + break; + case HALF_OVERLAP: + window_table = tcx_mdct_window_half_48; + buf_in_size = 180; + break; + case TRANSITION_OVERLAP: + case MIN_OVERLAP: + window_table = tcx_mdct_window_trans_48; + buf_in_size = 60; + break; + + default: + assert(0 && "Unsupported window type"); + break; + } + + if (Fs == 48000) + { + mvr2r(window_table, window, n); + } + else + { + lerp(window_table, window, n, buf_in_size); + } + } +#endif +} + /*------------------------------------------------------------------- - * mdct_window_aldo() + * mdct_window_aldo_flt() * * *-------------------------------------------------------------------*/ -void mdct_window_aldo( +void mdct_window_aldo_flt( float *window1, float *window2, const int16_t n ) @@ -258,3 +378,189 @@ void mdct_window_aldo( return; } + + +void mdct_window_aldo( + Word16 *window1, + PWord16 *window1_trunc, + PWord16 *window2, + Word16 n +) +{ + Word16 i, n0, n1, n2, d, tmp; + const Word16 *p1, *p2; + + /* set table pointers and decimation factor */ + SWITCH(n) + { + case 320 / 2: + p1 = window_48kHz_fx + 2; + p2 = window_48kHz_fx + 1110 - 3; + d = 6; + BREAK; + case 512 / 2: + p1 = window_256kHz; + p2 = window_256kHz + 592 - 1; + d = 2; + BREAK; + case 640 / 2: + p1 = window_48kHz_fx + 1; + p2 = window_48kHz_fx + 1110 - 2; + d = 3; + BREAK; + case 1024 / 2: + p1 = window_256kHz; + p2 = window_256kHz + 592 - 1; + d = 1; + BREAK; + case 1280 / 2: + p1 = window_48kHz_fx + 1; + p2 = window_48kHz_fx + 1110 - 2; + d = 3; + BREAK; + case 1920 / 2: + p1 = window_48kHz_fx; + p2 = window_48kHz_fx + 1110 - 1; + d = 1; + BREAK; + default: + assert(0); + return; + } + + /* set lengths */ + n0 = shr(imult1616(n, 9), 5); + n1 = shr(imult1616(n, 23), 5); /* left slope length */ + n2 = shr(imult1616(n, 14), 5); /* right slope length */ + + /* first part (long slope) */ + IF(NE_16(n, 1280 / 2)) + { + FOR(i = 0; i < n0; i++) + { + *window1 = *p1; + move16(); + window1++; + p1 += d; + } + + tmp = shr(n, 1); + FOR(; i < tmp; i++) + { + window1_trunc->v.im = *p1; + move16(); + window1_trunc++; + p1 += d; + } + + test(); + if (EQ_16(n, 512 / 2) || EQ_16(n, 320 / 2))p1++; + + FOR(; i < n1; i++) + { + window1_trunc--; + window1_trunc->v.re = *p1; + move16(); + p1 += d; + } + } + ELSE + { + const Word16 *pi = window_8_16_32kHz_fx; + + FOR(i = 0; i < n0; i += 2) + { + *window1 = *p1; + move16(); + window1++; + p1 += d; + + *window1 = *pi; + move16(); + window1++; + pi++; + } + + tmp = shr(n, 1); + FOR(; i < tmp; i += 2) + { + window1_trunc->v.im = *p1; + move16(); + window1_trunc++; + p1 += d; + + window1_trunc->v.im = *pi; + move16(); + window1_trunc++; + pi++; + } + + FOR(; i < n1; i += 2) + { + window1_trunc--; + window1_trunc->v.re = *pi; + move16(); + pi++; + + window1_trunc--; + window1_trunc->v.re = *p1; + move16(); + p1 += d; + } + } + + /* second part (short slope) */ + IF(NE_16(n, 1280 / 2)) + { + tmp = shr(n2, 1); + FOR(i = 0; i < tmp; i++) + { + window2->v.im = *p2; + move16(); + window2++; + p2 -= d; + } + + test(); + if (EQ_16(n, 512 / 2) || EQ_16(n, 320 / 2))p2--; + + FOR(; i < n2; i++) + { + window2--; + window2->v.re = *p2; + move16(); + p2 -= d; + } + } + ELSE + { + const Word16 *pi = window_8_16_32kHz_fx + 370 - 1; + + tmp = shr(n2, 1); + FOR(i = 0; i < tmp; i += 2) + { + window2->v.im = *p2; + move16(); + window2++; + p2 -= d; + + window2->v.im = *pi; + move16(); + window2++; + pi--; + } + + FOR(; i < n2; i += 2) + { + window2--; + window2->v.re = *pi; + move16(); + pi--; + + window2--; + window2->v.re = *p2; + move16(); + p2 -= d; + } + } +} \ No newline at end of file diff --git a/lib_com/tcx_utils.c b/lib_com/tcx_utils.c index a72b23bd9dd8dbc8906e5c8b6de59a62d08ec803..f3a9644ac05ca54d3fa55495c0d1a7547b6810b4 100644 --- a/lib_com/tcx_utils.c +++ b/lib_com/tcx_utils.c @@ -44,11 +44,11 @@ #include "wmc_auto.h" /*-------------------------------------------------------------------* - * tcx_get_windows() + * tcx_get_windows_flt() * * *-------------------------------------------------------------------*/ -void tcx_get_windows( +void tcx_get_windows_flt( TCX_CONFIG_HANDLE hTcxCfg, /* i : TCX configuration */ const int16_t left_mode, /* i : overlap mode of left window half */ const int16_t right_mode, /* i : overlap mode of right window half */ @@ -178,12 +178,12 @@ void tcx_get_windows( } /*-------------------------------------------------------------------* - * tcx_windowing_analysis() + * tcx_windowing_analysis_flt() * * *-------------------------------------------------------------------*/ -void tcx_windowing_analysis( +void tcx_windowing_analysis_flt( const float *signal, /* i : signal vector */ const int16_t L_frame, /* i : frame length */ const int16_t left_overlap, /* i : left overlap length */ @@ -218,12 +218,12 @@ void tcx_windowing_analysis( /*-------------------------------------------------------------------* - * WindowSignal() + * WindowSignal_flt() * * *-------------------------------------------------------------------*/ -void WindowSignal( +void WindowSignal_flt( TCX_CONFIG_HANDLE hTcxCfg, /* i : configuration of TCX */ int16_t offset, /* i : left folding point offset relative to the input signal pointer */ const int16_t left_overlap_mode, /* i : overlap mode of left window half */ @@ -245,7 +245,7 @@ void WindowSignal( * Init * *-----------------------------------------------------------*/ - tcx_get_windows( hTcxCfg, left_overlap_mode, right_overlap_mode, &l, &left_win, &r, &right_win, fullband ); + tcx_get_windows_flt( hTcxCfg, left_overlap_mode, right_overlap_mode, &l, &left_win, &r, &right_win, fullband ); /* Init lengths */ @@ -269,7 +269,7 @@ void WindowSignal( * Windowing * *-----------------------------------------------------------*/ - tcx_windowing_analysis( in - l / 2 + offset, *L_frame, l, left_win, r, right_win, out ); + tcx_windowing_analysis_flt( in - l / 2 + offset, *L_frame, l, left_win, r, right_win, out ); if ( left_overlap_mode == FULL_OVERLAP && truncate_aldo ) { @@ -292,12 +292,12 @@ void WindowSignal( /*-------------------------------------------------------------------* - * tcx_windowing_synthesis_current_frame() + * tcx_windowing_synthesis_current_frame_flt() * * *-------------------------------------------------------------------*/ -void tcx_windowing_synthesis_current_frame( +void tcx_windowing_synthesis_current_frame_flt( float *signal, /* i/o: signal vector */ const float *window, /* i : TCX window vector */ const float *window_half, /* i : TCX window vector for half-overlap window */ @@ -471,12 +471,12 @@ void tcx_windowing_synthesis_current_frame( /*-------------------------------------------------------------------* - * tcx_windowing_synthesis_past_frame() + * tcx_windowing_synthesis_past_frame_flt() * * *-------------------------------------------------------------------*/ -void tcx_windowing_synthesis_past_frame( +void tcx_windowing_synthesis_past_frame_flt( float *signal, /* i/o: signal vector */ const float *window, /* i : TCX window vector */ const float *window_half, /* i : TCX window vector for half-overlap window */ @@ -527,12 +527,12 @@ void tcx_windowing_synthesis_past_frame( /*-------------------------------------------------------------------* - * lpc2mdct() + * lpc2mdct_flt() * * *-------------------------------------------------------------------*/ -void lpc2mdct( +void lpc2mdct_flt( float *lpcCoeffs, const int16_t lpcOrder, float mdct_gains[], @@ -584,12 +584,12 @@ void lpc2mdct( /*-------------------------------------------------------------------* - * mdct_noiseShaping() + * mdct_noiseShaping_flt() * * *-------------------------------------------------------------------*/ -void mdct_noiseShaping( +void mdct_noiseShaping_flt( float x[], const int16_t lg, const float gains[], @@ -658,12 +658,12 @@ void mdct_noiseShaping( /*-------------------------------------------------------------------* - * PsychAdaptLowFreqDeemph() + * PsychAdaptLowFreqDeemph_flt() * * *-------------------------------------------------------------------*/ -void PsychAdaptLowFreqDeemph( +void PsychAdaptLowFreqDeemph_flt( float x[], const float lpcGains[], float lf_deemph_factors[] ) @@ -718,12 +718,12 @@ void PsychAdaptLowFreqDeemph( /*-------------------------------------------------------------------* - * AdaptLowFreqDeemph() + * AdaptLowFreqDeemph_flt() * * *-------------------------------------------------------------------*/ -void AdaptLowFreqDeemph( +void AdaptLowFreqDeemph_flt( float x[], int16_t tcx_lpc_shaped_ari, const float lpcGains[], @@ -818,7 +818,7 @@ void AdaptLowFreqDeemph( } else { - PsychAdaptLowFreqDeemph( x, lpcGains, lf_deemph_factors ); + PsychAdaptLowFreqDeemph_flt( x, lpcGains, lf_deemph_factors ); } return; @@ -826,12 +826,12 @@ void AdaptLowFreqDeemph( /*-------------------------------------------------------------------* - * tcx_noise_filling() + * tcx_noise_filling_flt() * * *-------------------------------------------------------------------*/ -void tcx_noise_filling( +void tcx_noise_filling_flt( float *Q, const int16_t noiseFillSeed, const int16_t iFirstLine, @@ -940,12 +940,12 @@ void tcx_noise_filling( /*-------------------------------------------------------------------* - * InitTnsConfigs() + * InitTnsConfigs_flt() * * *-------------------------------------------------------------------*/ -void InitTnsConfigs( +void InitTnsConfigs_flt( const int16_t bwidth, const int16_t L_frame, STnsConfig tnsConfig[2][2], @@ -968,12 +968,12 @@ void InitTnsConfigs( /*-------------------------------------------------------------------* - * SetAllowTnsOnWhite + * SetAllowTnsOnWhite_flt * * set TNS config flag for possible application of TNS in the whitened domain *-------------------------------------------------------------------*/ -void SetAllowTnsOnWhite( +void SetAllowTnsOnWhite_flt( STnsConfig tnsConfig[2][2], /* o : updated TNS configurations */ const int8_t allowTnsOnWhite /* i : flag for TNS in whiteded domain mode */ ) @@ -988,12 +988,12 @@ void SetAllowTnsOnWhite( /*-------------------------------------------------------------------* - * SetTnsConfig() + * SetTnsConfig_flt() * * *-------------------------------------------------------------------*/ -void SetTnsConfig( +void SetTnsConfig_flt( TCX_CONFIG_HANDLE hTcxCfg, const int16_t isTCX20, const int16_t isAfterACELP ) diff --git a/lib_com/tcx_utils_fx.c b/lib_com/tcx_utils_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..84b00dd9d21344c0a1e551f10886a098577f28b1 --- /dev/null +++ b/lib_com/tcx_utils_fx.c @@ -0,0 +1,1789 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include +#include +#include "options.h" +#include "prot_fx1.h" +#include "prot_fx2.h" +#include "rom_com.h" +#include "rom_basop_util.h" +#include "basop_util.h" + +#define inv_int InvIntTable + + /*-------------------------------------------------------------------* + * getInvFrameLen() + * + * + *-------------------------------------------------------------------*/ +Word16 getInvFrameLen( /* returns 1/L_frame in Q21 format */ + const Word16 L_frame +) +{ + Word16 idx, s; + + s = norm_s(L_frame); + idx = shl(L_frame, s); + + assert((idx == 0x4000) || (idx == 0x4B00) || (idx == 0x5000) || (idx == 0x5A00) || (idx == 0x6000) || (idx == 0x6400) || (idx == 0x7800)); + + idx = mult_r(idx, 0x10); /* idx = shr(add(idx, 0x0400), 11); */ + idx = s_and(idx, 7); + + + return shl(L_frame_inv[idx], sub(s, 7)); +} +/*-------------------------------------------------------------------* + *tcx_get_windows() + * + * + * ------------------------------------------------------------------ - */ +static void tcx_get_windows( + TCX_CONFIG_HANDLE hTcxCfg, /* i : TCX configuration */ + const Word16 left_mode, /* i: overlap mode of left window half */ + const Word16 right_mode, /* i: overlap mode of right window half */ + Word16 *left_overlap, /* o: left overlap length */ + const PWord16 **left_win, /* o: left overlap window */ + Word16 *right_overlap, /* o: right overlap length */ + const PWord16 **right_win, /* o: right overlap window */ + const Word8 fullband /* i: fullband flag */ +) +{ /* LFE is only FULL_OVERLAP*/ + IF (fullband == 0) + { + /* Left part */ + SWITCH (left_mode) + { + case TRANSITION_OVERLAP: /* ACELP->TCX transition */ + *left_overlap = hTcxCfg->tcx_mdct_window_trans_length; + move16(); + *left_win = hTcxCfg->tcx_mdct_window_trans; + BREAK; + case MIN_OVERLAP: + *left_overlap = hTcxCfg->tcx_mdct_window_min_length; + move16(); + *left_win = hTcxCfg->tcx_mdct_window_minimum; + BREAK; + case HALF_OVERLAP: + *left_overlap = hTcxCfg->tcx_mdct_window_half_length; + move16(); + *left_win = hTcxCfg->tcx_mdct_window_half; + BREAK; + case FULL_OVERLAP: + *left_overlap = hTcxCfg->tcx_mdct_window_length; + move16(); + *left_win = hTcxCfg->tcx_aldo_window_1_trunc; + move16(); + BREAK; + default: + assert(!"Not supported overlap"); + } + + /* Right part */ + SWITCH(right_mode) + { + case MIN_OVERLAP: + *right_overlap = hTcxCfg->tcx_mdct_window_min_length; + move16(); + *right_win = hTcxCfg->tcx_mdct_window_minimum; + BREAK; + case HALF_OVERLAP: + *right_overlap = hTcxCfg->tcx_mdct_window_half_length; + move16(); + *right_win = hTcxCfg->tcx_mdct_window_half; + BREAK; + case FULL_OVERLAP: + *right_overlap = hTcxCfg->tcx_mdct_window_delay; + move16(); + *right_win = hTcxCfg->tcx_aldo_window_2; + move16(); + BREAK; + default: + assert(!"Not supported overlap"); + } + } + ELSE + { + /* Left part */ + SWITCH (left_mode) + { + case TRANSITION_OVERLAP: /* ACELP->TCX transition */ + *left_overlap = hTcxCfg->tcx_mdct_window_trans_lengthFB; + move16(); + *left_win = hTcxCfg->tcx_mdct_window_transFB; + BREAK; + case MIN_OVERLAP: + *left_overlap = hTcxCfg->tcx_mdct_window_min_lengthFB; + move16(); + *left_win = hTcxCfg->tcx_mdct_window_minimumFB; + BREAK; + case HALF_OVERLAP: + *left_overlap = hTcxCfg->tcx_mdct_window_half_lengthFB; + move16(); + *left_win = hTcxCfg->tcx_mdct_window_halfFB; + BREAK; + case RECTANGULAR_OVERLAP: + *left_overlap = 0; + move16(); + *left_win = NULL; + BREAK; + case FULL_OVERLAP: + *left_overlap = hTcxCfg->tcx_mdct_window_lengthFB; + *left_win = hTcxCfg->tcx_aldo_window_1_FB_trunc; + move16();move16(); + + BREAK; + default: + assert(!"Not supported overlap"); + } + + /* Right part */ + SWITCH (right_mode) + { + case MIN_OVERLAP: + *right_overlap = hTcxCfg->tcx_mdct_window_min_lengthFB; + move16(); + *right_win = hTcxCfg->tcx_mdct_window_minimumFB; + BREAK; + case HALF_OVERLAP: + *right_overlap = hTcxCfg->tcx_mdct_window_half_lengthFB; + move16(); + *right_win = hTcxCfg->tcx_mdct_window_halfFB; + BREAK; + case RECTANGULAR_OVERLAP: + *right_overlap = 0; + move16(); + *right_win = NULL; + BREAK; + case FULL_OVERLAP: + *right_overlap = hTcxCfg->tcx_mdct_window_delayFB; + move16();move16(); + *right_win = hTcxCfg->tcx_aldo_window_2_FB; + BREAK; + default: + assert(!"Not supported overlap"); + } + } +} + +static void tcx_windowing_analysis( + Word16 const *signal, /* i: signal vector */ + Word16 L_frame, /* i: frame length */ + Word16 left_overlap, /* i: left overlap length */ + PWord16 const *left_win, /* i: left overlap window */ + Word16 right_overlap, /* i: right overlap length */ + PWord16 const *right_win, /* i: right overlap window */ + Word16 *output /* o: windowed signal vector */ +) +{ + Word16 w, n; + + /* Left overlap */ + n = shr(left_overlap, 1); + FOR (w = 0; w < n; w++) + { + *output++ = mult_r(*signal++, left_win[w].v.im); + move16(); + } + FOR (w = 0; w < n; w++) + { + *output++ = mult_r(*signal++, left_win[n-1-w].v.re); + move16(); + } + + /* Non overlapping region */ + n = sub(L_frame, shr(add(left_overlap, right_overlap), 1)); + FOR (w = 0; w < n; w++) + { + *output++ = *signal++; + move16(); + } + + /* Right overlap */ + n = shr(right_overlap, 1); + FOR (w = 0; w < n; w++) + { + *output++ = mult_r(*signal++, right_win[w].v.re); + move16(); + } + FOR (w = 0; w < n; w++) + { + *output++ = mult_r(*signal++, right_win[n-1-w].v.im); + move16(); + } +} +/*-------------------------------------------------------------------* + * WindowSignal() + * + * + *-------------------------------------------------------------------*/ +void WindowSignal( + TCX_CONFIG_HANDLE hTcxCfg, /* i : configuration of TCX */ + Word16 offset, /* i : left folding point offset relative to the input signal pointer */ + const Word16 left_overlap_mode, /* i : overlap mode of left window half */ + Word16 right_overlap_mode, /* i : overlap mode of right window half */ + Word16 * left_overlap_length, /* o : TCX window left overlap length */ + Word16 * right_overlap_length, /* o : TCX window right overlap length */ + const Word16 in[], /* i : input signal */ + Word16 * L_frame, /* i/o: frame length */ + Word16 out[], /* o : output windowed signal */ + const Word16 truncate_aldo, /* i : nonzero to truncate long ALDO slope */ + const Word8 fullband /* i : fullband flag */ +) +{ + Word16 l, r; + PWord16 const * left_win; + PWord16 const * right_win; + + + /*-----------------------------------------------------------* + * Init * + *-----------------------------------------------------------*/ + + tcx_get_windows(hTcxCfg, left_overlap_mode, right_overlap_mode, &l, &left_win, &r, &right_win, fullband); + + /* Init lengths */ + + /* if past frame is ACELP */ + IF (EQ_16(left_overlap_mode, TRANSITION_OVERLAP)) + { + /* Increase frame size for 5ms */ + IF (fullband == 0) + { + *L_frame = add(*L_frame, hTcxCfg->tcx5Size); + move16(); + offset = negate(shr(hTcxCfg->tcx_mdct_window_trans_length, 1)); + } + ELSE + { + *L_frame = add(*L_frame, hTcxCfg->tcx5SizeFB); + move16(); + offset = negate(shr(hTcxCfg->tcx_mdct_window_trans_lengthFB, 1)); + } + } + + /*-----------------------------------------------------------* + * Windowing * + *-----------------------------------------------------------*/ + + tcx_windowing_analysis(in-shr(l,1)+offset, *L_frame, l, left_win, r, right_win, out); + test(); test(); + IF (EQ_16(left_overlap_mode, FULL_OVERLAP) && truncate_aldo ) + { + /* fade truncated ALDO window to avoid discontinuities */ + Word16 i, tmp; + const PWord16 *p; + + p = hTcxCfg->tcx_mdct_window_minimum; + tmp = shr(hTcxCfg->tcx_mdct_window_min_length, 1); + IF (fullband != 0) + { + p = hTcxCfg->tcx_mdct_window_minimumFB; + tmp = shr(hTcxCfg->tcx_mdct_window_min_lengthFB, 1); + } + + FOR (i = 0; i < tmp; i++) + { + out[i] = mult_r(out[i], p[i].v.im); + move16(); + } + FOR (i = 0; i < tmp; i++) + { + out[i+tmp] = mult_r(out[i+tmp], p[tmp-1-i].v.re); + move16(); + } + } + + *left_overlap_length = l; + move16(); + *right_overlap_length = r; + move16(); + +} +/*-------------------------------------------------------------------* + * tcx_windowing_synthesis_current_frame() + * + * + *-------------------------------------------------------------------*/ + +void tcx_windowing_synthesis_current_frame( + Word16 *signal, /* i/o: signal vector */ + const PWord16 *window, /* i: TCX window vector */ + const PWord16 *window_half, /* i: TCX window vector for half-overlap window */ + const PWord16 *window_min, /* i: TCX minimum overlap window */ + const Word16 window_length, /* i: TCX window length */ + const Word16 window_half_length, /* i: TCX half window length */ + const Word16 window_min_length, /* i: TCX minimum overlap length */ + const Word16 left_rect, /* i: left part is rectangular */ + const Word16 left_mode, /* i: overlap mode of left window half */ + Word16 *acelp_zir, /* i: acelp ZIR */ + const Word16* old_syn, + const Word16* syn_overl, + const Word16* A_zir, + const PWord16 *window_trans, + Word16 acelp_zir_len, + const Word16 acelp_mem_len, + const Word16 last_core_bfi, /* i : last core */ + const Word8 last_is_cng, + const Word16 fullbandScale +) +{ + + Word16 i, overlap, n, tmp, tmp2; + Word16 tmp_buf[L_FRAME_MAX/2]; + Word32 L_tmp; + + /* Init */ + + overlap = shr(window_length, 1); + + /* Past-frame is TCX concealed as CNG and current-frame is TCX */ + test(); + test(); + test(); + test(); + IF ( EQ_16(last_is_cng, 1)&&left_rect==0) + { + IF (!fullbandScale) + { + set16_fx(acelp_zir, 0, acelp_zir_len); + E_UTIL_synthesis(0, A_zir, acelp_zir, acelp_zir, acelp_zir_len, signal+overlap+acelp_mem_len-M, 0, M); + } + ELSE + { +#ifdef BASOP_NOGLOB + lerp(acelp_zir, tmp_buf, acelp_zir_len, idiv1616U(shl_sat(acelp_zir_len, LD_FSCALE_DENOM), fullbandScale)); +#else + lerp(acelp_zir, tmp_buf, acelp_zir_len, idiv1616U(shl(acelp_zir_len, LD_FSCALE_DENOM), fullbandScale)); +#endif + acelp_zir = tmp_buf; + } + + FOR (i = 0; i < acelp_zir_len; i++) + { + /*signal[i] *= (float)(i)/(float)(acelp_zir_len); + signal[i] += acelp_zir[i]*(float)(acelp_zir_len-i)/(float)(acelp_zir_len);*/ + move16(); + signal[i] = add(mult_r(signal[i], div_s(i, acelp_zir_len)), mult_r(acelp_zir[i], div_s(sub(acelp_zir_len, i), acelp_zir_len))); + } + } + /* Rectangular window (past-frame is ACELP) */ + ELSE IF ( EQ_16(left_rect, 1)&&last_core_bfi==ACELP_CORE) + { + tmp = sub(overlap,acelp_mem_len); + FOR (i=0; i< tmp ; i++) + { + move16(); + signal[i] = 0; + } + + IF (fullbandScale == 0) + { + + tmp = shl(acelp_mem_len, 1); + + /*OLA with ACELP*/ + FOR (i = 0; i < acelp_mem_len; i++) + { + + /*window decoded TCX with aliasing*/ + tmp2 = mult_r(signal[i+overlap-acelp_mem_len], window_trans[i].v.im); + + /*Time TDAC: 1)forward part of ACELP*/ + tmp2 = add(tmp2, mult_r(old_syn[acelp_zir_len-tmp+i], mult_r(window_trans[i].v.re, window_trans[i].v.re))); + + /*Time TDAC: 1)reward part of ACELP*/ + tmp2 = add(tmp2, mult_r(old_syn[acelp_zir_len-i-1], mult_r(window_trans[i].v.im, window_trans[i].v.re))); + + move16(); + signal[i+overlap-acelp_mem_len] = tmp2; + } + FOR ( ; i < tmp; i++) + { + + /*window decoded TCX with aliasing*/ + tmp2 = mult_r(signal[i+overlap-acelp_mem_len], window_trans[tmp-1-i].v.re); + + /*Time TDAC: 1)forward part of ACELP*/ + tmp2 = add(tmp2, mult_r(old_syn[acelp_zir_len-tmp+i], mult_r(window_trans[tmp-1-i].v.im, window_trans[tmp-1-i].v.im))); + + /*Time TDAC: 1)reward part of ACELP*/ + tmp2 = add(tmp2, mult_r(old_syn[acelp_zir_len-i-1], mult_r(window_trans[tmp-1-i].v.re, window_trans[tmp-1-i].v.im))); + + move16(); + signal[i+overlap-acelp_mem_len] = tmp2; + } + + FOR (i=0; i=0; i--) + { + L_tmp = L_mult(acelp_zir[i], 13107); + L_tmp = L_mac(L_tmp, acelp_zir[i+1], 11469); + acelp_zir[i] = mac_r(L_tmp, acelp_zir[i+2], 8192); + move16(); + } + } + } + + FOR (i = 0; i < acelp_zir_len; i++) + { + /*remove reconstructed ZIR and add ACELP ZIR*/ + move16(); + signal[i+overlap+acelp_mem_len] = sub(signal[i+overlap+acelp_mem_len], mult_r(acelp_zir[i], div_s(sub(acelp_zir_len, i), acelp_zir_len))); + } + } + /* Rectangular window (past-frame is TCX) */ + ELSE IF ( left_rect==1 && last_core_bfi!=ACELP_CORE ) + { + n = add(overlap, acelp_mem_len); + FOR (i=0; ican be skipped*/ + +} +/*-------------------------------------------------------------------* + * tcx_windowing_synthesis_past_frame() + * + * + *-------------------------------------------------------------------*/ +void tcx_windowing_synthesis_past_frame( + Word16 *signal, /* i/o: signal vector */ + const PWord16 *window, /* i: TCX window vector */ + const PWord16 *window_half, /* i: TCX window vector for half-overlap window */ + const PWord16 *window_min, /* i: TCX minimum overlap window */ + const Word16 window_length, /* i: TCX window length */ + const Word16 window_half_length, /* i: TCX half window length */ + const Word16 window_min_length, /* i: TCX minimum overlap length */ + const Word16 right_mode /* i: overlap mode (left_mode of current frame) */ +) +{ + + Word16 i, n; + + + IF ( EQ_16(right_mode, 2)) /* min. overlap */ + { + signal += shr(sub(window_length, window_min_length), 1); + + n = shr(window_min_length, 1); + FOR (i = 0; i < n; i++) + { + *signal = mult_r(*signal, window_min[i].v.re); + move16(); + signal++; + } + FOR (i = 0; i < n; i++) + { + *signal = mult_r(*signal, window_min[n-1-i].v.im); + move16(); + signal++; + } + + n = shr(sub(window_length, window_min_length), 1); + FOR (i = 0; i < n; i++) + { + *signal = 0; + move16(); + signal++; + } + } + ELSE IF ( EQ_16(right_mode,3)) /* half OL */ + { + Word16 w; + + i = shr(sub(window_length, window_half_length),1); + n = shr(window_half_length,1); + FOR (w=0 ; w < n; w++) + { + signal[i] = mult_r(signal[i], window_half[w].v.re); + move16(); + i = add(i,1); + } + FOR (w=0 ; w < n; w++) + { + signal[i] = mult_r(signal[i], window_half[window_half_length/2-1-w].v.im); + move16(); + i = add(i,1); + } + FOR (; i < window_length; i++) + { + move16(); + signal[i] = 0; + } + } + ELSE /* normal full/maximum overlap */ + { + + n = shr(window_length,1); + FOR (i = 0; i < n; i++) + { + move16(); + signal[i] = mult_r(signal[i], window[i].v.re); + move16(); + signal[window_length-1-i] = mult_r(signal[window_length-1-i], window[i].v.im); + } + } + +} +/*-------------------------------------------------------------------* + * lpc2mdct() + * + * + *-------------------------------------------------------------------*/ + +void lpc2mdct( + Word16 *lpcCoeffs, + const Word16 lpcOrder, + Word16 *mdct_gains, + Word16 *mdct_gains_exp, + Word16 *mdct_inv_gains, + Word16 *mdct_inv_gains_exp, + const int16_t length, + const int16_t noInverse +) +{ + Word32 ComplexData[2*FDNS_NPTS]; + Word16 i, j, k, sizeN, step, scale, s, tmp16; + Word16 g, g_e, ig, ig_e; + Word32 tmp32; + const PWord16 *ptwiddle; + Word32 workBuffer[2*BASOP_CFFT_MAX_LENGTH]; + +#ifndef IVAS_CODE_TCX_UTIL + (void) noInverse; +#endif + + assert(length <= FDNS_NPTS); + sizeN = shl(length, 1); + + BASOP_getTables(NULL, &ptwiddle, &step, sizeN); + /*ODFT*/ + assert(lpcOrder < FDNS_NPTS); + /* pre-twiddle */ + FOR (i=0; i<=lpcOrder; i++) + { + ComplexData[2*i] = L_mult(lpcCoeffs[i], ptwiddle->v.re); + move32(); + ComplexData[2*i+1] = L_negate(L_mult(lpcCoeffs[i], ptwiddle->v.im)); + move32(); + ptwiddle += step; + } + /* zero padding */ + FOR ( ; i In float the fft type changes as well + /*Get amplitude*/ + j = sub(length, 1); + k = 0; + for (i = 0; i < length; i++) + { + mdct_gains[i] = (float)(sqrt(RealData[i] * RealData[i] + ImagData[i] * ImagData[i])); + } + } + else +#endif + { + /* half length FFT */ + scale = add(norm_s(lpcCoeffs[0]), 1); + BASOP_cfft((cmplx*)ComplexData, FDNS_NPTS, &scale, workBuffer); + /*Get amplitude*/ + j = sub(length, 1); + k = 0; + FOR(i = 0; i < length / 2; i++) + { + s = sub(norm_l(L_max(L_abs(ComplexData[2 * i]), L_abs(ComplexData[2 * i + 1]))), 1); + tmp16 = extract_h(L_shl(ComplexData[2 * i], s)); + tmp32 = L_mult(tmp16, tmp16); + tmp16 = extract_h(L_shl(ComplexData[2 * i + 1], s)); + tmp16 = mac_r(tmp32, tmp16, tmp16); + s = shl(sub(scale, s), 1); + if (tmp16 == 0) + { + s = -16; + move16(); + } + if (tmp16 == 0) + { + tmp16 = 1; + move16(); + } + BASOP_Util_Sqrt_InvSqrt_MantExp(tmp16, s, &g, &g_e, &ig, &ig_e); + if (mdct_gains != 0) + { + mdct_gains[k] = g; + move16(); + } + if (mdct_gains_exp != 0) + { + mdct_gains_exp[k] = g_e; + move16(); + } + if (mdct_inv_gains != 0) + { + mdct_inv_gains[k] = ig; + move16(); + } + if (mdct_inv_gains_exp != 0) + { + mdct_inv_gains_exp[k] = ig_e; + move16(); + } + k = add(k, 1); + s = sub(norm_l(L_max(L_abs(ComplexData[2 * j]), L_abs(ComplexData[2 * j + 1]))), 1); + tmp16 = extract_h(L_shl(ComplexData[2 * j], s)); + tmp32 = L_mult(tmp16, tmp16); + tmp16 = extract_h(L_shl(ComplexData[2 * j + 1], s)); + tmp16 = mac_r(tmp32, tmp16, tmp16); + s = shl(sub(scale, s), 1); + if (tmp16 == 0) + { + s = -16; + move16(); + } + if (tmp16 == 0) + { + tmp16 = 1; + move16(); + } + BASOP_Util_Sqrt_InvSqrt_MantExp(tmp16, s, &g, &g_e, &ig, &ig_e); + if (mdct_gains != 0) + { + mdct_gains[k] = g; + move16(); + } + if (mdct_gains_exp != 0) + { + mdct_gains_exp[k] = g_e; + move16(); + } + if (mdct_inv_gains != 0) + { + mdct_inv_gains[k] = ig; + move16(); + } + if (mdct_inv_gains_exp != 0) + { + mdct_inv_gains_exp[k] = ig_e; + move16(); + } + j = sub(j, 1); + k = add(k, 1); + } + } +} +/** + * \brief Perform mdct shaping. In the floating point software there are two functions, + * mdct_noiseShaping and mdct_preShaping, which are combined here into a single function. + * \param x spectrum mantissas + * \param lg spectrum length + * \param gains shaping gains mantissas + * \param gains_exp shaping gains exponents + */ +void mdct_shaping( + Word32 x[], + const Word16 lg, + const Word16 gains[], + const Word16 gains_exp[] + /*const Word16 nBands*/ /*Parameter added in IVAS, but always equal to FDNS_NPTS */ +) +{ + + Word16 i, k, l; + Word16 m, n, k1, k2, j; + Word32 * px = x; + Word16 const * pgains = gains; + Word16 const * pgainsexp = gains_exp; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + + /* FDNS_NPTS = 64 */ + k = shr(lg, 6); + m = s_and(lg, 0x3F); + + IF (m != 0) + { + IF ( LE_16( m, FDNS_NPTS/2 )) + { + n = idiv1616U(FDNS_NPTS,m); + k1 = k; + move16(); + k2 = add(k,1); + } + ELSE + { + n = idiv1616U(FDNS_NPTS,sub(FDNS_NPTS,m)); + k1 = add(k,1); + k2 = k; + move16(); + } + + i = 0; + move16(); + j = 0; + move16(); + + WHILE (LT_16(i, lg)) + { + + k = k2; + move16(); + if (j != 0) + { + k = k1; + move16(); + } + + j = add(j, 1); + if ( EQ_16(j, n)) + { + j = 0; + move16(); + } + + /* Limit number of loops, if end is reached */ + k = s_min(k, sub(lg, i)); + + FOR (l=0; l < k; l++) + { + *x = L_shl(Mpy_32_16_r(*x, *gains), *gains_exp); + move32(); + x++; + } + i = add(i, k); + + gains++; + gains_exp++; + } + } + ELSE + { + FOR (l=0; l < k; l++) + { + x = &px[l]; + gains = pgains; + gains_exp = pgainsexp; + FOR (i=0; i 0) pg = shr(pg, tmp); + if (tmp < 0) g = shl(g, tmp); + e = s_max(gains_exp[j], gains_exp[jp]); + + tmp = mac_r(L_mult(pg, 12288/*0.375f Q15*/), g, 20480/*0.625f Q15*/); + x[i] = L_shl(Mpy_32_16_1(x[i], tmp), e); + move32(); + + tmp = mac_r(L_mult(pg, 4096/*0.125f Q15*/), g, 28672/*0.875f Q15*/); + x[i+1] = L_shl(Mpy_32_16_1(x[i+1], tmp), e); + move32(); + + /* common exponent for g and ng */ + g = gains[j]; + move16(); + tmp = sub(gains_exp[j], gains_exp[jn]); + if (tmp > 0) ng = shr(ng, tmp); + if (tmp < 0) g = shl(g, tmp); + e = s_max(gains_exp[j], gains_exp[jn]); + + tmp = mac_r(L_mult(g, 28672/*0.875f Q15*/), ng, 4096/*0.125f Q15*/); + x[i+2] = L_shl(Mpy_32_16_1(x[i+2], tmp), e); + move32(); + + tmp = mac_r(L_mult(g, 20480/*0.625f Q15*/), ng, 12288/*0.375f Q15*/); + x[i+3] = L_shl(Mpy_32_16_1(x[i+3], tmp), e); + move32(); + + jp = j; + move16(); + j = jn; + move16(); + jn = s_min(add(jn, 1), FDNS_NPTS-1); + } + } + ELSE IF (EQ_16(k, 5)) + { + jp = 0; + move16(); + j = 0; + move16(); + jn = 1; + move16(); + + FOR (i = 0; i < lg; i += 5) + { + pg = gains[jp]; + move16(); + g = gains[j]; + move16(); + ng = gains[jn]; + move16(); + + /* common exponent for pg and g */ + tmp = sub(gains_exp[j], gains_exp[jp]); + if (tmp > 0) pg = shr(pg, tmp); + if (tmp < 0) g = shl(g, tmp); + e = s_max(gains_exp[j], gains_exp[jp]); + + tmp = mac_r(L_mult(pg, 13107/*0.40f Q15*/), g, 19661/*0.60f Q15*/); + x[i] = L_shl(Mpy_32_16_1(x[i], tmp), e); + move32(); + + tmp = mac_r(L_mult(pg, 6554/*0.20f Q15*/), g, 26214/*0.80f Q15*/); + x[i+1] = L_shl(Mpy_32_16_1(x[i+1], tmp), e); + move32(); + + + x[i+2] = L_shl(Mpy_32_16_1(x[i+2], gains[j]), gains_exp[j]); + move32(); + + /* common exponent for g and ng */ + g = gains[j]; + move16(); + tmp = sub(gains_exp[j], gains_exp[jn]); + if (tmp > 0) ng = shr(ng, tmp); + if (tmp < 0) g = shl(g, tmp); + e = s_max(gains_exp[j], gains_exp[jn]); + + tmp = mac_r(L_mult(g, 26214/*0.80f Q15*/), ng, 6554/*0.20f Q15*/); + x[i+3] = L_shl(Mpy_32_16_1(x[i+3], tmp), e); + move32(); + + tmp = mac_r(L_mult(g, 19661/*0.60f Q15*/), ng, 13107/*0.40f Q15*/); + x[i+4] = L_shl(Mpy_32_16_1(x[i+4], tmp), e); + move32(); + + jp = j; + move16(); + j = jn; + move16(); + jn = s_min(add(jn, 1), FDNS_NPTS-1); + } + } + ELSE /* no interpolation */ + { + FOR (i = 0; i < FDNS_NPTS; i++) + { + FOR (l = 0; l < k; l++) + { + *x = L_shl(Mpy_32_16_1(*x, *gains), *gains_exp); + move32(); + x++; + } + + gains++; + gains_exp++; + } + } + } + +} + +void PsychAdaptLowFreqDeemph( + Word32 x[], + const Word16 lpcGains[], + const Word16 lpcGains_e[], + Word16 lf_deemph_factors[] +) +{ + Word16 i; + Word16 max_val, max_e, fac, min, min_e, tmp, tmp_e; + Word32 L_tmp; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + + + + assert(lpcGains[0] >= 0x4000); + + max_val = lpcGains[0]; + move16(); + max_e = lpcGains_e[0]; + move16(); + min = lpcGains[0]; + move16(); + min_e = lpcGains_e[0]; + move16(); + + /* find minimum (min) and maximum (max_val) of LPC gains in low frequencies */ + FOR (i = 1; i < 9; i++) + { + IF (compMantExp16Unorm(lpcGains[i], lpcGains_e[i], min, min_e) < 0) + { + min = lpcGains[i]; + move16(); + min_e = lpcGains_e[i]; + move16(); + } + + IF (compMantExp16Unorm(lpcGains[i], lpcGains_e[i], max_val, max_e) > 0) + { + max_val = lpcGains[i]; + move16(); + max_e = lpcGains_e[i]; + move16(); + } + } + + min_e = add(min_e, 5); /* min *= 32.0f; */ + + test(); + IF ((compMantExp16Unorm(max_val, max_e, min, min_e) < 0) && (min > 0)) + { + /* fac = tmp = (float)pow(max_val / min, 0.0078125f); */ + tmp_e = min_e; + move16(); + tmp = Inv16(min, &tmp_e); + L_tmp = L_shl(L_mult(tmp, max_val), add(tmp_e, max_e)); /* Q31 */ + L_tmp = BASOP_Util_Log2(L_tmp); /* Q25 */ + L_tmp = L_shr(L_tmp, 7); /* 0.0078125f = 1.f/(1<<7) */ + L_tmp = BASOP_Util_InvLog2(L_tmp); /* Q31 */ +#ifdef BASOP_NOGLOB + tmp = round_fx_o(L_tmp, &Overflow); /* Q15 */ +#else /* BASOP_NOGLOB */ + tmp = round_fx(L_tmp); /* Q15 */ +#endif + fac = tmp; /* Q15 */ move16(); + + /* gradual lowering of lowest 32 bins; DC is lowered by (max_val/tmp)^1/4 */ + FOR (i = 31; i >= 0; i--) + { + x[i] = Mpy_32_16_1(x[i], fac); + move32(); + if (lf_deemph_factors != NULL) + { + lf_deemph_factors[i] = mult_r(lf_deemph_factors[i], fac); + move16(); + } + fac = mult_r(fac, tmp); + } + } + +} + +void AdaptLowFreqDeemph( + Word32 x[], + Word16 x_e, + Word16 tcx_lpc_shaped_ari, + Word16 lpcGains[], + Word16 lpcGains_e[], + const Word16 lg, + Word16 lf_deemph_factors[] +) +{ + + Word16 i, i_max, i_max_old, lg_4; + Word32 v2, v4, tmp32; + + tmp32 = 0; /* to avoid compilation warnings */ + + + IF (tcx_lpc_shaped_ari == 0) + { + v2 = L_shl(2, sub(31, x_e)); /* 2.0 */ + v4 = L_shl(v2, 1); /* 4.0 */ + lg_4 = shr(lg, 2); /* lg/4 */ + + /* 1. find first magnitude maximum in lower quarter of spectrum */ + i_max = -1; + move16(); + + FOR (i = 0; i < lg_4; i++) + { + IF (GE_32(L_abs(x[i]), v4)) + { + + /* Debug initialization to catch illegal x[i] values. */ + tmp32 = 0; + + if (x[i] < 0) tmp32 = L_add(x[i], v2); + if (x[i] > 0) tmp32 = L_sub(x[i], v2); + + assert(tmp32 != 0); + + x[i] = tmp32; + move32(); + i_max = i; + move16(); + BREAK; + } + } + + /* 2. expand value range of all xi up to i_max: two extra steps */ + FOR (i = 0; i < i_max; i++) + { + x[i] = L_shr(x[i], 1); + move32(); + lf_deemph_factors[i] = shr(lf_deemph_factors[i], 1); + move16(); + } + + /* 3. find first magnitude maximum in lower quarter of spectrum */ + i_max_old = i_max; + move16(); + + IF (i_max_old >= 0) + { + i_max = -1; + move16(); + + FOR (i = 0; i < lg_4; i++) + { + IF (GE_32(L_abs(x[i]), v4)) + { + assert(x[i] != 0); + if (x[i] < 0) tmp32 = L_add(x[i], v2); + if (x[i] >= 0) tmp32 = L_sub(x[i], v2); + x[i] = tmp32; + move32(); + i_max = i; + move16(); + BREAK; + } + } + } + + /* 4. expand value range of all xi up to i_max: two extra steps */ + FOR (i = 0; i < i_max; i++) + { + x[i] = L_shr(x[i], 1); + move32(); + lf_deemph_factors[i] = shr(lf_deemph_factors[i], 1); + move16(); + } + + /* 5. always expand two lines; lines could be at index 0 and 1! */ + i_max = s_max(i_max, i_max_old); + i = add(i_max, 1); + + IF (x[i] < 0) + { + tmp32 = L_sub(x[i], L_negate(v4)); + + if (tmp32 > 0) + { + lf_deemph_factors[i] = shr(lf_deemph_factors[i], 1); + move16(); + } + if (tmp32 <= 0) + { + x[i] = L_add(x[i], v2); + move32(); + } + if (tmp32 > 0) + { + x[i] = L_shr(x[i], 1); + move32(); + } + } + ELSE + { + tmp32 = L_sub(x[i], v4); + + if (tmp32 < 0) + { + lf_deemph_factors[i] = shr(lf_deemph_factors[i], 1); + move16(); + } + if (tmp32 >= 0) + { + x[i] = L_sub(x[i], v2); + move32(); + } + if (tmp32 < 0) + { + x[i] = L_shr(x[i], 1); + move32(); + } + } + i = add(i, 1); + + IF (x[i] < 0) + { + tmp32 = L_sub(x[i], L_negate(v4)); + + if (tmp32 > 0) + { + lf_deemph_factors[i] = shr(lf_deemph_factors[i], 1); + move16(); + } + if (tmp32 <= 0) + { + x[i] = L_add(x[i], v2); + move32(); + } + if (tmp32 > 0) + { + x[i] = L_shr(x[i], 1); + move32(); + } + } + ELSE + { + tmp32 = L_sub(x[i], v4); + + if (tmp32 < 0) + { + lf_deemph_factors[i] = shr(lf_deemph_factors[i], 1); + move16(); + } + if (tmp32 >= 0) + { + x[i] = L_sub(x[i], v2); + move32(); + } + if (tmp32 < 0) + { + x[i] = L_shr(x[i], 1); + move32(); + } + } + } + ELSE /*if(!tcx_lpc_shaped_ari)*/ + { + PsychAdaptLowFreqDeemph(x, lpcGains, lpcGains_e, lf_deemph_factors); + }/*if(!tcx_lpc_shaped_ari)*/ + +} + +void tcx_noise_filling( + Word32* Q, + Word16 Q_e, + Word16 seed, + const Word16 iFirstLine, + const Word16 lowpassLine, + const Word16 nTransWidth, + const Word16 L_frame, + const Word16 tiltCompFactor, + Word16 fac_ns, + Word16* infoTCXNoise, + const Word16 element_mode /* i : IVAS element mode */ +) +{ + Word16 i, m, segmentOffset; + Word16 win; /* window coefficient */ + Word16 tilt_factor; + Word32 nrg; + Word16 tmp1, tmp2, s; + Word32 tmp32; + + + /* get inverse frame length */ + tmp1 = getInvFrameLen(L_frame); + + /* tilt_factor = (float)pow(max_val(0.375f, tiltCompFactor), 1.0f/(float)L_frame); */ + tmp32 = BASOP_Util_Log2(L_deposit_h(s_max(0x3000, tiltCompFactor))); /* 6Q25 */ + tmp32 = L_shr(Mpy_32_16_1(tmp32, tmp1), 6); + BASOP_SATURATE_WARNING_OFF_EVS; + tilt_factor = round_fx(BASOP_Util_InvLog2(tmp32)); + BASOP_SATURATE_WARNING_ON_EVS; + + /* find last nonzero line below iFirstLine, use it as start offset */ + i = iFirstLine; + move16(); + tmp1 = shr(iFirstLine, 1); + IF (EQ_16(element_mode, IVAS_CPE_MDCT)) /* ... but only in mono or parametric stereo since it may cause binaural unmasking in discrete stereo */ + { + segmentOffset = i; + move16(); + } + ELSE + { + FOR(; i > tmp1; i--) + { + IF(Q[i] != 0) + { + BREAK; + } + } + /* fac_ns *= (float)pow(tilt_factor, (float)i); */ + FOR(m = 0; m < i; m++) + { + fac_ns = mult_r(fac_ns, tilt_factor); + } + i = add(i, 1); + segmentOffset = i; + } + nrg = L_deposit_l(1); + win = 0; + move16(); + move16(); + + FOR (; i < lowpassLine; i++) + { + fac_ns = mult_r(fac_ns, tilt_factor); + + IF (Q[i] != 0) + { + IF (win > 0) + { + /* RMS-normalize current noise-filled segment */ + tmp1 = BASOP_Util_Divide3216_Scale(nrg, sub(i, segmentOffset), &s); /* mean */ + s = add(s, 9-15); /* scaling */ + tmp1 = ISqrt16(tmp1, &s); /* 1/RMS */ + tmp1 = mult_r(tmp1, inv_int[nTransWidth]); /* compensate win */ + s = add(s, sub(16, Q_e)); /* scaling */ + + tmp2 = sub(i, win); + IF (LT_16(segmentOffset, tmp2)) + { + FOR (m = segmentOffset; m < tmp2; m++) + { + Q[m] = L_shl(Mpy_32_16_1(Q[m], tmp1), s); + move32(); + } + } + + tmp2 = mult(tmp1, inv_int[nTransWidth]); + tmp1 = extract_l(L_mult0(tmp2, win)); + FOR (m = sub(i, win); m < i; m++) + { + Q[m] = L_shl(Mpy_32_16_1(Q[m], tmp1), s); + move32(); + win = sub(win, 1); + tmp1 = sub(tmp1, tmp2); + } + + nrg = L_deposit_l(1); /* start new segment: reset noise segment energy */ + } + segmentOffset = add(i, 1); + } + ELSE /* line is zero, so fill line and update window and energy */ + { + if (LT_16(win, nTransWidth)) + { + win = add(win, 1); + } + + seed = own_random2_fx(seed); + Q[i] = L_mult0(mult(seed, fac_ns), win); + move32(); + + tmp1 = shr(seed, 4); + nrg = L_mac0(nrg, tmp1, tmp1); /* sum up energy of current noise segment */ + + if(infoTCXNoise) /* set noiseflags for IGF */ + { + infoTCXNoise[i] = 1; + move16(); + } + } + } + + IF (win > 0) + { + /* RMS-normalize uppermost noise-filled segment */ + tmp1 = BASOP_Util_Divide3216_Scale(nrg, sub(lowpassLine, segmentOffset), &s); /* mean */ + s = add(s, 9-15); /* compensate energy scaling */ + tmp1 = ISqrt16(tmp1, &s); /* 1/RMS */ + tmp1 = mult_r(tmp1, inv_int[nTransWidth]); /* compensate win */ + s = add(s, sub(16, Q_e)); /* compensate noise scaling */ + + FOR (m = segmentOffset; m < lowpassLine; m++) + { + Q[m] = L_shl(Mpy_32_16_1(Q[m], tmp1), s); + move32(); + } + } + +} + + + +/*--------------------------------------------------------------- + * InitTnsConfigs() + *--------------------------------------------------------------*/ + + +void InitTnsConfigs( + const Word16 bwidth, + const Word16 L_frame, + STnsConfig tnsConfig[2][2], + const Word16 igfStopFreq, + const Word32 total_brate, + const int16_t element_mode, + const int16_t MCT_flag +) +{ + IF (GT_32(total_brate,ACELP_32k)) + { + InitTnsConfiguration(bwidth, shr(L_frame,1), &tnsConfig[0][0], igfStopFreq, total_brate, element_mode, MCT_flag); + } + InitTnsConfiguration(bwidth, L_frame, &tnsConfig[1][0], igfStopFreq, total_brate, element_mode, MCT_flag); + InitTnsConfiguration(bwidth, add(L_frame, shr(L_frame,2)), &tnsConfig[1][1], igfStopFreq, total_brate, element_mode, MCT_flag); +} + + +void SetTnsConfig( + TCX_CONFIG_HANDLE hTcxCfg, /* i : configuration of TCX */ + Word8 isTCX20, + Word8 isAfterACELP +) +{ + move16(); + hTcxCfg->pCurrentTnsConfig = &hTcxCfg->tnsConfig[isTCX20][isAfterACELP]; + assert(hTcxCfg->pCurrentTnsConfig != NULL); +} +#ifdef IVAS_CODE_TCX_UTIL +/*-------------------------------------------------------------------* + * SetAllowTnsOnWhite + * + * set TNS config flag for possible application of TNS in the whitened domain + *-------------------------------------------------------------------*/ + +void SetAllowTnsOnWhite( + STnsConfig tnsConfig[2][2], /* o : updated TNS configurations */ + const int8_t allowTnsOnWhite /* i : flag for TNS in whiteded domain mode */ +) +{ + tnsConfig[0][0].allowTnsOnWhite = allowTnsOnWhite; + tnsConfig[0][1].allowTnsOnWhite = allowTnsOnWhite; + tnsConfig[1][0].allowTnsOnWhite = allowTnsOnWhite; + tnsConfig[1][1].allowTnsOnWhite = allowTnsOnWhite; + + return; +} +#endif + +void tcx_get_gain( + Word32 *x, /* i: spectrum 1 */ + Word16 x_e, /* i: spectrum 1 exponent */ + Word32 *y, /* i: spectrum 2 */ + Word16 y_e, /* i: spectrum 2 exponent */ + Word16 n, /* i: length */ + Word16 *gain, /* o: gain */ + Word16 *gain_e, /* o: gain exponent */ + Word32 *en_y, /* o: energy of y (optional) */ + Word16 *en_y_e /* o: energy of y exponent (optional) */ +) +{ + Word32 maxX, minX, maxY, minY; + Word32 corr, ener; + Word16 sx, sy, corr_e, ener_e; + Word16 i, tmp; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + + maxX = L_deposit_l(1); + maxY = L_deposit_l(1); + minX = L_deposit_l(-1); + minY = L_deposit_l(-1); + FOR (i = 0; i < n; i++) + { + if (x[i] > 0) maxX = L_max(maxX, x[i]); + if (x[i] < 0) minX = L_min(minX, x[i]); + + if (y[i] > 0) maxY = L_max(maxY, y[i]); + if (y[i] < 0) minY = L_min(minY, y[i]); + } + sx = s_min(norm_l(maxX), norm_l(minX)); + sy = s_min(norm_l(maxY), norm_l(minY)); + sx = sub(sx, 4); + sy = sub(sy, 4); + + ener = L_deposit_l(0); + corr = L_deposit_l(0); + FOR (i = 0; i < n; i++) + { + tmp = round_fx(L_shl(y[i], sy)); + ener = L_mac0(ener, tmp, tmp); + corr = L_mac0(corr, tmp, round_fx(L_shl(x[i], sx))); + } + + if (ener == 0) ener = L_deposit_l(1); + + ener_e = add(shl(sub(y_e, sy), 1), 1); + corr_e = add(sub(add(x_e, y_e), add(sx, sy)), 1); + + tmp = sub(norm_l(corr), 1); + corr = L_shl(corr, tmp); + corr_e = sub(corr_e, tmp); + + tmp = norm_l(ener); + ener = L_shl(ener, tmp); + ener_e = sub(ener_e, tmp); + +#ifdef BASOP_NOGLOB + tmp = div_s(abs_s(round_fx_o(corr, &Overflow)), round_fx_o(ener, &Overflow)); +#else + tmp = div_s(abs_s(round_fx(corr)), round_fx(ener)); +#endif + if (corr < 0) tmp = negate(tmp); + + *gain = tmp; + move16(); + *gain_e = sub(corr_e, ener_e); + move16(); + + if (en_y != NULL) + { + *en_y = ener; + move32(); + } + if (en_y_e != NULL) + { + *en_y_e = ener_e; + move16(); + } + +} +#if 0 +void init_TCX_config_dec( /* TEMPORARY */ + TCX_CONFIG_HANDLE hTcxCfg, + Word16 L_frame, + Word16 fscale + , Word16 L_frameTCX + , Word16 fscaleFB +) +{ + /* Initialize the TCX MDCT windows */ + hTcxCfg->tcx_mdct_window_length = extract_l(L_shr(L_mult0(L_LOOK_12k8, fscale), LD_FSCALE_DENOM)); + hTcxCfg->tcx_mdct_window_delay = hTcxCfg->tcx_mdct_window_length; + move16(); + + hTcxCfg->tcx_mdct_window_half_length = extract_l(L_shr(L_mult0(L_LOOK_12k8 - NS2SA(12800, 5000000L), fscale), LD_FSCALE_DENOM)); + + hTcxCfg->tcx_mdct_window_min_length = shr(L_frame, 4); /* 1.25ms */ + hTcxCfg->tcx_mdct_window_trans_length = shr(L_frame, 4); /* 1.25ms */ + + hTcxCfg->tcx5Size = shr(L_frame, 2); /* 5ms */ + + hTcxCfg->tcx_mdct_window_lengthFB = extract_l(L_shr(L_mult0(L_LOOK_12k8, fscaleFB), LD_FSCALE_DENOM)); + hTcxCfg->tcx_mdct_window_delayFB = hTcxCfg->tcx_mdct_window_lengthFB; + move16(); + + hTcxCfg->tcx_mdct_window_half_lengthFB = extract_l(L_shr(L_mult0(L_LOOK_12k8 - NS2SA(12800, 5000000L), fscaleFB), LD_FSCALE_DENOM)); + + hTcxCfg->tcx_mdct_window_min_lengthFB = shr(L_frameTCX, 4); /* 1.25ms */ + hTcxCfg->tcx_mdct_window_trans_lengthFB = shr(L_frameTCX, 4); /* 1.25ms */ + + hTcxCfg->tcx5SizeFB = shr(L_frameTCX, 2); /* 5ms */ + + mdct_window_sine(hTcxCfg->tcx_mdct_window, hTcxCfg->tcx_mdct_window_length); + mdct_window_sine(hTcxCfg->tcx_mdct_window_half, hTcxCfg->tcx_mdct_window_half_length); + mdct_window_sine(hTcxCfg->tcx_mdct_window_minimum, hTcxCfg->tcx_mdct_window_min_length); + mdct_window_sine(hTcxCfg->tcx_mdct_window_trans, hTcxCfg->tcx_mdct_window_trans_length); + + mdct_window_sine(hTcxCfg->tcx_mdct_windowFB, hTcxCfg->tcx_mdct_window_lengthFB); + mdct_window_sine(hTcxCfg->tcx_mdct_window_halfFB, hTcxCfg->tcx_mdct_window_half_lengthFB); + mdct_window_sine(hTcxCfg->tcx_mdct_window_minimumFB, hTcxCfg->tcx_mdct_window_min_lengthFB); + mdct_window_sine(hTcxCfg->tcx_mdct_window_transFB, hTcxCfg->tcx_mdct_window_trans_lengthFB); + + /*ALDO windows for MODE2*/ + mdct_window_aldo(hTcxCfg->tcx_aldo_window_1, hTcxCfg->tcx_aldo_window_1_trunc, hTcxCfg->tcx_aldo_window_2, L_frame); + mdct_window_aldo(hTcxCfg->tcx_aldo_window_1_FB, hTcxCfg->tcx_aldo_window_1_FB_trunc, hTcxCfg->tcx_aldo_window_2_FB, L_frameTCX); +} +#endif +void init_TCX_config( + TCX_CONFIG_HANDLE hTcxCfg, + Word16 L_frame, + Word16 fscale + ,Word16 L_frameTCX + ,Word16 fscaleFB +) +{ + /* Initialize the TCX MDCT windows */ + hTcxCfg->tcx_mdct_window_length = extract_l(L_shr(L_mult0(L_LOOK_12k8, fscale), LD_FSCALE_DENOM)); + hTcxCfg->tcx_mdct_window_delay = hTcxCfg->tcx_mdct_window_length; + move16(); + + hTcxCfg->tcx_mdct_window_half_length = extract_l(L_shr(L_mult0(L_LOOK_12k8 - NS2SA(12800, 5000000L), fscale), LD_FSCALE_DENOM)); + + hTcxCfg->tcx_mdct_window_min_length = shr(L_frame, 4); /* 1.25ms */ + hTcxCfg->tcx_mdct_window_trans_length = shr(L_frame, 4); /* 1.25ms */ + + hTcxCfg->tcx5Size = shr(L_frame, 2); /* 5ms */ + + hTcxCfg->tcx_mdct_window_lengthFB = extract_l(L_shr(L_mult0(L_LOOK_12k8, fscaleFB), LD_FSCALE_DENOM)); + hTcxCfg->tcx_mdct_window_delayFB = hTcxCfg->tcx_mdct_window_lengthFB; + move16(); + + hTcxCfg->tcx_mdct_window_half_lengthFB = extract_l(L_shr(L_mult0(L_LOOK_12k8 - NS2SA(12800, 5000000L), fscaleFB), LD_FSCALE_DENOM)); + + hTcxCfg->tcx_mdct_window_min_lengthFB = shr(L_frameTCX, 4); /* 1.25ms */ + hTcxCfg->tcx_mdct_window_trans_lengthFB = shr(L_frameTCX, 4); /* 1.25ms */ + + hTcxCfg->tcx5SizeFB = shr(L_frameTCX, 2); /* 5ms */ + + mdct_window_sine( hTcxCfg->tcx_mdct_window, hTcxCfg->tcx_mdct_window_length ); + mdct_window_sine( hTcxCfg->tcx_mdct_window_half, hTcxCfg->tcx_mdct_window_half_length ); + mdct_window_sine( hTcxCfg->tcx_mdct_window_minimum, hTcxCfg->tcx_mdct_window_min_length ); + mdct_window_sine( hTcxCfg->tcx_mdct_window_trans, hTcxCfg->tcx_mdct_window_trans_length ); + + mdct_window_sine( hTcxCfg->tcx_mdct_windowFB, hTcxCfg->tcx_mdct_window_lengthFB ); + mdct_window_sine( hTcxCfg->tcx_mdct_window_halfFB, hTcxCfg->tcx_mdct_window_half_lengthFB ); + mdct_window_sine( hTcxCfg->tcx_mdct_window_minimumFB, hTcxCfg->tcx_mdct_window_min_lengthFB ); + mdct_window_sine( hTcxCfg->tcx_mdct_window_transFB, hTcxCfg->tcx_mdct_window_trans_lengthFB ); + + /*ALDO windows for MODE2*/ + mdct_window_aldo(hTcxCfg->tcx_aldo_window_1, hTcxCfg->tcx_aldo_window_1_trunc, hTcxCfg->tcx_aldo_window_2, L_frame); + mdct_window_aldo(hTcxCfg->tcx_aldo_window_1_FB, hTcxCfg->tcx_aldo_window_1_FB_trunc, hTcxCfg->tcx_aldo_window_2_FB, L_frameTCX); +} + diff --git a/lib_com/tec_com.c b/lib_com/tec_com.c index a22886b28c15a855c088e8770f9c3f950e7a0c60..da968995eaf9b95995b3926ec8c5b5e8864893bf 100644 --- a/lib_com/tec_com.c +++ b/lib_com/tec_com.c @@ -1,694 +1,1259 @@ -/****************************************************************************************************** - - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - /*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 ====================================================================================*/ -#include #include #include "options.h" -#include +#include "basop_util.h" +#include "prot_fx1.h" +#include "prot_fx2.h" +#include "cnst.h" #include "rom_com.h" -#include "prot.h" -#include "stat_dec.h" -#include "wmc_auto.h" /*------------------------------------------------------------------- * Local constants *-------------------------------------------------------------------*/ +/*#define EPS ( 1e-12f)*/ +#define ENV_SCALE_OFFSET_1_FX 1515133568l/*90.309f/128.0 Q31*/ /* 10*log10(2^30) */ /* scaled by 1/128.0 */ +#define MAX_TEC_BW_LO (12) +#define MAX_NB_TEC_LOW_BAND ( 3) +#define NBTECLOWBAND 3 +#define TECSMOOTHINGDEG 5 #define LOBUF_NO_SMOOTHING_MODE 1 -#define EPS ( 1e-12f ) -#define ENV_SCALE_OFFSET_1 90.309f /* 10*log10(2^30) */ -#define MAX_TEC_BW_LO ( 12 ) -#define MAX_NB_TEC_LOW_BAND ( 3 ) - -const float TecSC[] = { 0.3662f, 0.1078f, 0.1194f, 0.1289f, 0.1365f, 0.1412f }; -const int16_t TecLowBandTable[] = { 0, 2, 4, 6 }; - -#define TecSmoothingDeg 5 -#define NbTecLowBand 3 - -#define ratioHiLoFac 1.5894f -#define thRatio 0.3649f -#define thRatio2 2.0288f -#define thCorrCoef 0.8795f -#define ratioHiLoFacDec ( 1.5894f * 0.75f ) - /*------------------------------------------------------------------- - * calcLoBufferDec() + * resetTecDec_Fx() * * *-------------------------------------------------------------------*/ - -static void calcLoBufferDec( - float **pCldfbReal, - float **pCldfbImag, - float *loBuffer, - const int16_t startPos, - const int16_t stopPos, - const int16_t bandOffsetBottom, - const float scaleOffset ) +void resetTecDec_Fx( + TEC_DEC_HANDLE hTecDec +) { - int16_t slot, k, lb, li, ui; - float nrg, tmp; - /* calc loTempEnv */ - for ( slot = startPos; slot < stopPos; slot++ ) - { - tmp = 0; + set16_fx(hTecDec->pGainTemp_m, 0, CLDFB_NO_COL_MAX); + set16_fx(hTecDec->pGainTemp_e, 0, CLDFB_NO_COL_MAX); - for ( lb = 0; lb < NbTecLowBand; lb++ ) - { - li = TecLowBandTable[lb]; - ui = TecLowBandTable[lb + 1]; - - nrg = 0; - for ( k = li; k < ui; k++ ) - { - nrg += pCldfbReal[slot][k + bandOffsetBottom] * pCldfbReal[slot][k + bandOffsetBottom] + pCldfbImag[slot][k + bandOffsetBottom] * pCldfbImag[slot][k + bandOffsetBottom]; - } - tmp += (float) log10( nrg * normReciprocal[ui - li] + EPS ); - } - - loBuffer[slot] = 10.0f * tmp / NbTecLowBand + scaleOffset; - } + set16_fx(hTecDec->loBuffer, 0, CLDFB_NO_COL_MAX + MAX_TEC_SMOOTHING_DEG); return; } - /*------------------------------------------------------------------- - * calcLoBufferEnc() + * resetTecEnc_Fx() * * *-------------------------------------------------------------------*/ - -static void calcLoBufferEnc( - float **pCldfbPow, - const int16_t startPos, - const int16_t stopPos, - const int16_t bandOffsetBottom, - const float scaleOffset, - float *loBuffer ) +void resetTecEnc_Fx(TEC_ENC_HANDLE hTecEnc, Word16 flag) { - int16_t slot, k, lb, li, ui; - float nrg, tmp; - - /* calc loTempEnv */ - for ( slot = startPos; slot < stopPos; slot++ ) + IF (flag == 0) { - tmp = 0; - - for ( lb = 0; lb < NbTecLowBand; lb++ ) - { - li = TecLowBandTable[lb]; - ui = TecLowBandTable[lb + 1]; - - nrg = 0; - for ( k = li; k < ui; k++ ) - { - nrg += pCldfbPow[slot][k + bandOffsetBottom]; - } - tmp += (float) log10( nrg * normReciprocal[ui - li] + EPS ); - } - - loBuffer[slot] = 10.0f * tmp / NbTecLowBand + scaleOffset; + set16_fx(hTecEnc->loBuffer, 0, CLDFB_NO_COL_MAX + MAX_TEC_SMOOTHING_DEG + DELAY_TEMP_ENV_BUFF_TEC); + set16_fx(hTecEnc->loTempEnv, 0, CLDFB_NO_COL_MAX); + set16_fx(hTecEnc->loTempEnv_ns, 0, CLDFB_NO_COL_MAX); + set16_fx(hTecEnc->hiTempEnv, 0, CLDFB_NO_COL_MAX + DELAY_TEMP_ENV_BUFF_TEC + EXT_DELAY_HI_TEMP_ENV); + } + ELSE + { + set16_fx(hTecEnc->loBuffer, 0, MAX_TEC_SMOOTHING_DEG); } - return; } - /*------------------------------------------------------------------- - * calcLoTempEnv() + * calcVar() * * *-------------------------------------------------------------------*/ -static void calcLoTempEnv( - const float *loBuffer, - const int16_t noCols, - float *loTempEnv, - const float adjFac ) +static Word32 calcVar_Fix( + const Word32 in[], + const Word32 len, + Word32* x +) { - int16_t slot, i; + Word32 xx; + Word32 i; + Word16 exp1; + Word32 ans; + Word16 r_sft; + Word32 tmpX; + + xx = L_deposit_l(0); + *x = L_deposit_l(0); + FOR(i=0; ipGainTemp, 0, CLDFB_NO_COL_MAX ); + Word16 lb; + Word16 li; + Word16 ui; + Word16 slot; + Word32 nrg; + Word32 nrgLog; + Word32 tmp; + + FOR (slot=startPos; slot < stopPos; slot++) + { + tmp = L_deposit_l(0); - set_f( hTecDec->loBuffer, 0.f, CLDFB_NO_COL_MAX + MAX_TEC_SMOOTHING_DEG ); + /* scaling nrg : scale - 1 (sum up nrg) + 1 (inv_bw = 0.5) */ - return; -} + FOR (lb=0; lb < NBTECLOWBAND; lb++) + { + li = TecLowBandTable[lb]; + move16(); + ui = sub(TecLowBandTable[lb+1],1); + move16(); + + assert( (ui-li) == 1 ); + + /* sum up maximum of 2 nrg values, thus leave 1 bits headroom */ + nrg = L_add(L_shr(pCldfbPow_Fx[slot][li+bandOffsetBottom],1), + L_shr(pCldfbPow_Fx[slot][ui+bandOffsetBottom],1)); + + + /* assemble log2(EPS) */ + nrgLog = -668792462l/*-0.31143075889 Q31*/; + move32(); + IF ( nrg != 0 ) + { + /* assemble log2 value and shift factor */ + nrgLog = L_sub(L_shr(BASOP_Util_Log2(nrg),1), L_shl(scale,(WORD32_BITS-1)-(LD_DATA_SCALE+1))); + + /* /\* assemble log2 value and shift factor *\/ */ + /* nrgLog = L_shr(BASOP_Util_Log2(nrg),1); */ + } + tmp = L_add(tmp, nrgLog); + } + + /* 0.50171665944 = 10 * log10(2.0) / NbTecLowBand / 2.0 */ + loBuffer[slot] = extract_h(L_shl(Mpy_32_16_1(tmp,16440/*0.50171665944 Q15*/),1)); + + } +} /*------------------------------------------------------------------- - * calcLoTempEnv_TBE() + * calcHiTempEnv() * * *-------------------------------------------------------------------*/ -static void calcLoTempEnv_TBE( - const float *loBuffer, - const int16_t noCols, - float *loTempEnv, - const float adjFac ) +static void calcHiTempEnv_Fx( + Word32 **pCldfbPow, /* Q31 */ + Word16 scale, + const Word16 startPos, + const Word16 stopPos, + const Word16 lowSubband, + const Word16 highSubband, + Word16 *hiTempEnv /* Q7 = Q(15 - (LD_DATA_SCALE + 2)) */ +) { - int16_t slot, i; - int16_t delay = 1; + Word16 k; + Word16 s1; + Word16 s2; + Word16 bwHigh; + Word32 nrg; + Word32 nrgLog; + Word16 normFac; + Word16 timeIndex; + + s1 = 3; + move16(); + + bwHigh = sub(highSubband,lowSubband); + + normFac = getNormReciprocalWord16(bwHigh); + + scale = sub(scale, s1); + move16(); - for ( slot = 0; slot < noCols; slot++ ) + FOR (timeIndex=startPos; timeIndex < stopPos; timeIndex++) { - loTempEnv[slot] = TecSC[0] * loBuffer[slot - delay]; + nrg = L_deposit_l(0); - for ( i = 1; i < TecSmoothingDeg + 1; i++ ) + FOR (k=lowSubband; k < highSubband; k++) { - loTempEnv[slot] += TecSC[i] * loBuffer[slot - delay - i]; + nrg = L_add(nrg,L_shr(pCldfbPow[timeIndex][k], s1)); } - loTempEnv[slot] *= adjFac; - } - return; -} + s2 = norm_l(nrg); + nrg = L_shl(nrg,s2); + + /* assemble log2(EPS) */ + nrgLog = -668792462l/*-0.31143075889 Q31*/; + move32(); + + if ( nrg != 0 ) + { + /* assemble log2 value and shift factor */ + nrgLog = L_shr(BASOP_Util_Log2(Mpy_32_16_1(nrg, normFac)),1); + nrgLog = L_sub(nrgLog, L_shl(add(scale,s2),(WORD32_BITS-1)-(LD_DATA_SCALE+1))); + } + /* 0.75257498916 = 10 * log10(2.0) / 4.0 */ + hiTempEnv[timeIndex] = extract_h(L_shr(L_shl(Mpy_32_16_1(nrgLog,24660/*0.75257498916 Q15*/),2),1)); + } +} /*------------------------------------------------------------------- - * set_TEC_TFA_code() + * calcLoBufferDec() * * *-------------------------------------------------------------------*/ -void set_TEC_TFA_code( - const int16_t corrFlag, - int16_t *tec_flag, - int16_t *tfa_flag ) +static void calcLoBufferDec_Fx( + Word32 **pCldfbReal, + Word32 **pCldfbImag, + Word16 *loBuffer, + const Word16 startPos, + const Word16 stopPos, + const Word16 offset, + const Word16 scale +) { - *tec_flag = 0; - if ( *tfa_flag == 0 ) + Word16 k; + Word16 lb; + Word16 s1; + Word16 s2; + Word16 slot; + Word32 nrg32; + Word32 tmp; + Word32 maxVal; + + + FOR (slot=startPos; slot < stopPos; slot++) { - if ( corrFlag == 1 ) + tmp = L_deposit_l(0); + + FOR (lb=0; lb < NBTECLOWBAND; lb++) { - *tec_flag = 1; + Word16 li; + Word16 ui; + + li = TecLowBandTable[lb]; + move16(); + ui = TecLowBandTable[lb+1]; + move16(); + + assert( (ui-li) == 2 ); + + maxVal = L_deposit_l(0); + + /* determine maximum value */ + FOR (k=li; k < ui; k++) + { + maxVal = L_max(maxVal,L_abs(pCldfbReal[slot][k+offset])); + maxVal = L_max(maxVal,L_abs(pCldfbImag[slot][k+offset])); + } + + IF ( maxVal != 0 ) + { + /* sum up maximum of 4 squared values, thus leave 2 bits headroom */ + s1 = sub(norm_l(maxVal),2); + + nrg32 = L_deposit_l(0); + + FOR (k=li; k < ui; k++) + { + Word16 val; + + val = extract_h(L_shl(pCldfbReal[slot][k+offset], s1)); + nrg32 = L_mac(nrg32, val, val); + val = extract_h(L_shl(pCldfbImag[slot][k+offset], s1)); + nrg32 = L_mac(nrg32, val, val); + } + + /* square(scale) + square(s1) + 1(inv_bw = 0.5) */ + s2 = add(shl(add(scale,s1),1),1); + + /* assemble log value */ + tmp = L_add(tmp,L_shr(BASOP_Util_Log2(nrg32),1)); + + /* add shift factors */ + tmp = L_sub(tmp,L_shl(s2,(WORD32_BITS-1)-(LD_DATA_SCALE+1))); + + /* add scale of reference */ + tmp = L_add(tmp,L_shl(30,(WORD32_BITS-1)-(LD_DATA_SCALE+1))); + + /* 0.50171665944 = 10 * log10(2.0) / NbTecLowBand / 2.0 */ + loBuffer[slot] = extract_h(L_shl(Mpy_32_16_1(tmp,16440/*0.50171665944 Q15*/),1)); + } + ELSE + { + /* 10 * log10(EPS) / 64.0 / 2.0 */ + loBuffer[slot] = -30720/*-0.9375 Q15*/; + move16(); + } } - else if ( corrFlag == 2 ) + } +} +/*------------------------------------------------------------------- + * calcLoTempEnv_Fx() + * + * + *-------------------------------------------------------------------*/ +static void calcLoTempEnv_Fx( + Word16* loBuffer_Fx, /* Q8 = Q(15 - (LD_DATA_SCALE+1)) */ + const Word16 noCols, + Word16* loTempEnv_Fx, /* Q7 = Q(15 - (LD_DATA_SCALE+2)) */ + const Word16 adjFac_Fx +) +{ + Word16 i; + Word16 slot; + Word32 accu; + + /* TecSC_Fx values are scaled by factor 2.0 */ + FOR (slot = 0; slot < noCols; slot++) + { + accu = L_mult0(TecSC_Fx[0], loBuffer_Fx[slot]); + FOR (i=1; i < TECSMOOTHINGDEG + 1; i++) { - *tec_flag = 1; - *tfa_flag = 1; + accu = L_mac0(accu,TecSC_Fx[i], loBuffer_Fx[sub(slot, i)]); } + /* adjFac is scaled by factor 0.5 */ + loTempEnv_Fx[slot] = extract_h(Mpy_32_16_1(accu,adjFac_Fx)); } - - return; } + /*------------------------------------------------------------------- + * calcLoTempEnv_ns() + * + * + *-------------------------------------------------------------------*/ +static void calcLoTempEnv_ns_Fx( + Word16* loBuffer_Fx, /* Q8 = Q(15 - (LD_DATA_SCALE+1)) */ + const Word16 noCols, + Word16* loTempEnv_Fx /* Q7 = Q(15 - (LD_DATA_SCALE+2)) */ +) +{ + Word16 slot; + FOR (slot = 0; slot < noCols; slot++) + { + loTempEnv_Fx[slot] = shr(loBuffer_Fx[slot], 1); + move16(); + } + return; +} /*------------------------------------------------------------------- * calcLoTempEnv_ns_TBE() * * *-------------------------------------------------------------------*/ - -static void calcLoTempEnv_ns_TBE( - const float *loBuffer, - const int16_t noCols, - float *loTempEnv ) +static void calcLoTempEnv_TBE_Fx( + Word16* loBuffer_Fx, /* Q8 = Q(15 - (LD_DATA_SCALE+1)) */ + const Word16 noCols, + Word16* loTempEnv_Fx, /* Q7 = Q(15 - (LD_DATA_SCALE+2)) */ + const Word16 adjFac_Fx +) { - int16_t slot; - int16_t delay = 1; - float fac = 1.4f; + Word16 i; + Word16 slot; + Word32 accu; + Word16 delay = 1; - for ( slot = 0; slot < noCols; slot++ ) + /* TecSC_Fx values are scaled by factor 2.0 */ + FOR (slot = 0; slot < noCols; slot++) { - loTempEnv[slot] = fac * loBuffer[slot - delay]; + accu = L_mult0(TecSC_Fx[0], loBuffer_Fx[slot - delay]); + FOR (i=1; i < TECSMOOTHINGDEG + 1; i++) + { + accu = L_mac0(accu,TecSC_Fx[i], loBuffer_Fx[slot-i-delay]); + } + /* adjFac is scaled by factor 0.5 */ + loTempEnv_Fx[slot] = extract_h(Mpy_32_16_1(accu,adjFac_Fx)); } - - return; } - - /*------------------------------------------------------------------- - * calcLoTempEnv_ns() + * calcLoTempEnv_ns_TBE() * * *-------------------------------------------------------------------*/ -static void calcLoTempEnv_ns( - const float *loBuffer, - const int16_t noCols, - float *loTempEnv ) +static void calcLoTempEnv_ns_TBE_Fx( + Word16* loBuffer_Fx, /* Q8 = Q(15 - (LD_DATA_SCALE+1)) */ + const Word16 noCols, + Word16* loTempEnv_Fx /* Q7 = Q(15 - (LD_DATA_SCALE+2)) */ +) { - int16_t slot; + Word16 slot; + Word16 delay = 1; + Word16 fac = 22938/*1.4f * 0.5f Q15*/; - for ( slot = 0; slot < noCols; slot++ ) + FOR (slot = 0; slot < noCols; slot++) { - loTempEnv[slot] = loBuffer[slot]; + /* fac is scaled by factor 0.5 */ + loTempEnv_Fx[slot] = mult_r(fac, loBuffer_Fx[sub(slot, delay)]); + move16(); } return; } - /*------------------------------------------------------------------- * calcGainLinear_TBE() * * *-------------------------------------------------------------------*/ - -static void calcGainLinear_TBE( - const float *loTempEnv, - const int16_t startPos, - const int16_t stopPos, - float *pGainTemp ) +static void calcGainLinear_TBE_Fx( + const Word16* loTempEnv_m, /* Q7 = Q(15 - (LD_DATA_SCALE+2)) */ + const Word16 startPos, + const Word16 stopPos, + Word16* pGainTemp_m, /* Q0 */ + Word16* pGainTemp_e /* Q0 */ +) { - int16_t timeIndex; - float ftmp; - for ( timeIndex = startPos; timeIndex < stopPos; timeIndex++ ) + Word16 slot; + Word16 c; + Word32 logScaleFactor; + + + /* 0.1 * Log2(10.0) scaled by 2.0 */ + c = 21771/*2.0*0.33219280948 Q15*/; + move16(); + + FOR (slot=startPos; slot < stopPos; slot++) { - ftmp = loTempEnv[timeIndex]; - pGainTemp[timeIndex] = (float) pow( 10.0, 0.1 * ftmp ); - } + Word16 s; + Word16 s2; + Word32 tmp32; - return; -} + s = 0; + move16(); + /* adapt scale to LD_DATA_SCALE */ + tmp32 = L_shl(L_mult(c,loTempEnv_m[slot]),1); + + IF ( tmp32 > 0 ) + { + IF ( GE_32(tmp32,1006632960l/*0.46875 Q31*/)) + { + s = add(s,sub(WORD32_BITS,norm_l(BASOP_Util_InvLog2(L_sub(tmp32,1006632960l/*0.46875 Q31*/))))); + s = add(s,30); + } + ELSE + { + s = add(s,sub(WORD32_BITS,norm_l(BASOP_Util_InvLog2(tmp32)))); + } + /* scalefactor for logarithmic domain */ + logScaleFactor = L_shl(L_mult0(512/*1.0/(1<= BW_LO ); + Word16 noCols = stopPos - startPos; + Word16 bandOffset = lowSubband - BW_LO; - bandOffset = lowSubband - BW_LO; + assert(lowSubband >= BW_LO); - calcLoBufferDec( pCldfbRealSrc, pCldfbImagSrc, loBuffer + MAX_TEC_SMOOTHING_DEG, startPos, stopPos, bandOffset, scaleOffset ); + calcLoBufferDec_Fx( + pCldfbRealSrc_Fx, + pCldfbImagSrc_Fx, + loBuffer_Fx+MAX_TEC_SMOOTHING_DEG, + startPos, + stopPos, + bandOffset, + 15 - cldfb_exp + ); - if ( code > 0 ) + IF (code > 0) { - if ( code != 2 ) + IF (NE_16(code, 2)) { - calcLoTempEnv_TBE( loBuffer + MAX_TEC_SMOOTHING_DEG, noCols, loTempEnv, ratioHiLoFacDec ); + calcLoTempEnv_TBE_Fx(loBuffer_Fx + MAX_TEC_SMOOTHING_DEG, noCols, + loTempEnv_Fx, 19531/*0.5f * ratioHiLoFacDec Q15*/); } - else + ELSE { - calcLoTempEnv_ns_TBE( loBuffer + MAX_TEC_SMOOTHING_DEG, noCols, loTempEnv ); + calcLoTempEnv_ns_TBE_Fx(loBuffer_Fx + MAX_TEC_SMOOTHING_DEG, noCols, loTempEnv_Fx); } - calcGainLinear_TBE( loTempEnv, startPos, stopPos, pGainTemp ); + calcGainLinear_TBE_Fx(loTempEnv_Fx, startPos, stopPos, + pGainTemp_m, pGainTemp_e); } - - for ( slot = 0; slot < MAX_TEC_SMOOTHING_DEG; slot++ ) + FOR (slot = 0; slot < MAX_TEC_SMOOTHING_DEG; slot++) { - loBuffer[slot] = loBuffer[slot + stopPos]; + loBuffer_Fx[slot] = loBuffer_Fx[slot + stopPos]; + move16(); } - - return; } - - /*------------------------------------------------------------------- * setSubfrConfig() * * *-------------------------------------------------------------------*/ -static void setSubfrConfig( - const int16_t i_offset, - int16_t *k_offset, - int16_t *n_subfr, - const int16_t l_subfr ) +static void setSubfrConfig_Fix( + const Word16 i_offset, + Word16* k_offset, + Word16* n_subfr, + const Word16 l_subfr +) { - *n_subfr = N_TEC_TFA_SUBFR - i_offset; - *k_offset = i_offset * l_subfr; - - return; + *n_subfr = sub((Word16)N_TEC_TFA_SUBFR,i_offset); + *k_offset = i_mult(i_offset,l_subfr); } - - /*------------------------------------------------------------------- - * calcSubfrNrg() + * calcSum_Fx() * * *-------------------------------------------------------------------*/ -static float calcSubfrNrg( - const float *hb_synth, - const int16_t i_offset, - float *enr, - const int16_t k_offset, - const int16_t l_subfr ) +static Word16 calcSum_Fx( + Word16* vec_m, /*Q0*/ + Word16* vec_e, /*Q0*/ + const Word16 len, + Word16* sum16_m /*Q0*/ +) { - int16_t i, j, k; - float enr_all = 1e-12f; + Word16 slot; + Word16 sum16_e; /* Q0 */ - for ( i = i_offset, k = k_offset; i < N_TEC_TFA_SUBFR; i++ ) + *sum16_m = 0; + sum16_e = 0; + FOR (slot=0; slot 0) + { + Word16 tmp; + s = norm_l(nrg32); + tmp = extract_h(L_shl(nrg32, s)); + enr_m[i] = tmp; + move16(); + enr_e[i] = - s; + move16(); + } + ELSE + { + enr_m[i] = 0; + move16(); + enr_e[i] = - 15; + move16(); + } } - return; -} + sum16_e = enr_e[i_offset]; + *sum16_m = enr_m[i_offset]; + FOR (i=i_offset+1; i 0) + { + BASOP_Util_Divide_MantExp(enr_ave_m, enr_ave_e, + enr_m[i], enr_e[i], + &inv_curr_enr_m[i], &inv_curr_enr_e[i]); + } + ELSE + { + /* 1.0e+12 */ + inv_curr_enr_m[i] = 28282/*0.8631 Q15*/; + move16(); + inv_curr_enr_e[i] = 39; + move16(); + } - setSubfrConfig( i_offset, &k_offset, &n_subfr, l_subfr ); + s = norm_s(inv_curr_enr_m[i]); + inv_curr_enr_m[i] = shl(inv_curr_enr_m[i], s); + move16(); + inv_curr_enr_e[i] = sub(inv_curr_enr_e[i], s); + move16(); - enr_ave = calcSubfrNrg( hb_synth, i_offset, enr, k_offset, l_subfr ) / n_subfr; + IF (gain_m[i] > 0) + { + BASOP_Util_Divide_MantExp(gain_m[i], gain_e[i], + gain_ave_m, gain_ave_e, + &gain_m[i], &gain_e[i]); + } + ELSE + { + return exp_syn; + } + } - gain_ave = ( sum_f( &gain[i_offset], n_subfr ) + 1.0e-12f ) / n_subfr; + /* find the maximum of inv_curr_enr */ + max_inv_curr_enr_e = inv_curr_enr_e[i_offset]; + move16(); + max_inv_curr_enr_m = inv_curr_enr_m[i_offset]; + move16(); - max_inv_curr_enr = 10e-6f; - for ( i = i_offset, k = k_offset; i < N_TEC_TFA_SUBFR; i++ ) + FOR (i=i_offset+1; i ( tmp = 1.f / max_inv_curr_enr ) ) + /* evaluate lower limit of the gain's */ + BASOP_Util_Divide_MantExp(32767, 0, + max_inv_curr_enr_m, max_inv_curr_enr_e, + &min_curr_enr_m, &min_curr_enr_e); + + s = norm_s(min_curr_enr_m); + min_curr_enr_m = shl(min_curr_enr_m, s); + min_curr_enr_e = sub(min_curr_enr_e, s); + + lower_limit_gain_e = - 3; + move16(); + lower_limit_gain_m = 26214/*0.1 * 8 Q15*/; /* norm = 0 */move16(); + + test(); + test(); + IF ( (GT_16(lower_limit_gain_e, min_curr_enr_e))||(EQ_16(lower_limit_gain_e,min_curr_enr_e)&>_16(lower_limit_gain_m,min_curr_enr_m))) { - lower_limit_gain = tmp * 0.5f; + lower_limit_gain_m = min_curr_enr_m; + move16(); + lower_limit_gain_e = sub(min_curr_enr_e, 1); + move16(); } - upper_limit_gain = 1.2f; - if ( code == LOBUF_NO_SMOOTHING_MODE ) + /* upper_limit_gain */ + upper_limit_gain_m = 19661/*0.6f Q15*/; /* norm = 0 */ move16(); + upper_limit_gain_e = 1; + move16(); + IF (EQ_16(code, LOBUF_NO_SMOOTHING_MODE)) { - upper_limit_gain = 3.0; + upper_limit_gain_m = 24576/*0.75f Q15*/; /* norm = 0 */ move16(); + upper_limit_gain_e = 2; + move16(); } - for ( i = i_offset, k = k_offset; i < N_TEC_TFA_SUBFR; i++ ) + min_shift = 15; /* min_shift <= 15 */ move16(); + + k = k_offset; + move16(); + FOR (i=i_offset; i gain[i] ) + test(); + test(); + IF ( (GT_16(lower_limit_gain_e, gain_e[i]))||(EQ_16(lower_limit_gain_e,gain_e[i])&>_16(lower_limit_gain_m,gain_m[i]))) { - gain[i] = lower_limit_gain; + gain_m[i] = lower_limit_gain_m; + move16(); + gain_e[i] = lower_limit_gain_e; + move16(); } - gain[i] *= inv_curr_enr[i]; - if ( gain[i] > upper_limit_gain ) + gain_m[i] = mult_r(gain_m[i], inv_curr_enr_m[i]); + gain_e[i] = add(gain_e[i], inv_curr_enr_e[i]); + + s = norm_s(gain_m[i]); + gain_m[i] = shl(gain_m[i], s); + move16(); + gain_e[i] = sub(gain_e[i], s); + move16(); + + test(); + test(); + IF ( (LT_16(upper_limit_gain_e, gain_e[i]))||(EQ_16(upper_limit_gain_e,gain_e[i])&<_16(upper_limit_gain_m,gain_m[i]))) { - gain[i] = upper_limit_gain; + + gain_m[i] = upper_limit_gain_m; + move16(); + gain_e[i] = upper_limit_gain_e; + move16(); } - gain[i] = (float) sqrt( gain[i] ); - for ( j = 0; j < l_subfr; j++ ) + gain_m[i] = Sqrt16(gain_m[i], &gain_e[i]); + move16(); + s = norm_s(gain_m[i]); + gain_m[i] = shl(gain_m[i], s); + move16(); + gain_e[i] = sub(gain_e[i], s); + move16(); + + FOR(j=0; j 15) + { + exp_syn = 15; + move16(); + } + + if (exp_syn < 0) + { + exp_syn = 0; + move16(); + } + min_shift = sub(s, exp_syn); /* exp_syn(old) - exp_syn(new) */ + k = k_offset; + FOR (i=i_offset; i 0) + { + hb_synth_Fx[k] = shr(hb_synth_Fx[k], s); + move16(); + } + k = add(k, 1); + } + } + + return exp_syn; +} /*------------------------------------------------------------------- - * procTecTfa_TBE() + * procTfa_TBE() * * *-------------------------------------------------------------------*/ - -void procTecTfa_TBE( - float *hb_synth, - float *gain, - const int16_t flat_flag, - const int16_t last_core, - const int16_t l_subfr, - const int16_t code ) +static Word16 procTfa_Fx( + Word16* hb_synth_Fx, + Word16 exp_syn, + const Word16 i_offset, + const Word16 l_subfr +) { - int16_t i_offset = 0; + Word16 i,j,k; + Word16 k_offset, n_subfr; - if ( flat_flag ) - { - procTfa( hb_synth, i_offset, l_subfr ); - } - else + Word16 enr_m[N_TEC_TFA_SUBFR]; + Word16 enr_e[N_TEC_TFA_SUBFR]; + + Word16 enr_ave_m; + Word16 enr_ave_e; + + Word16 inv_n_subfr; + + Word16 s; + Word16 shift[L_FRAME_MAX]; + Word16 min_shift; + + Word16 gain_m[N_TEC_TFA_SUBFR]; + Word16 gain_e[N_TEC_TFA_SUBFR]; + + setSubfrConfig_Fix(i_offset, &k_offset, &n_subfr, l_subfr); + + assert(8 /* = 2^3 */ < n_subfr); + inv_n_subfr = getNormReciprocalWord16Scale(n_subfr, 3); + + enr_ave_e = calcSubfrNrg_Fx(hb_synth_Fx, + exp_syn, + i_offset, + enr_m, + enr_e, + k_offset, + &enr_ave_m + ,l_subfr + ); + + enr_ave_m = mult_r(enr_ave_m, inv_n_subfr); + enr_ave_e = sub(enr_ave_e, 3); + + min_shift = 15; /* min_shift <= 15 */ move16(); + + k = k_offset; + move16(); + FOR (i=i_offset; i 0) { - i_offset = 1; + BASOP_Util_Divide_MantExp(enr_ave_m, enr_ave_e, + enr_m[i], enr_e[i], + &gain_m[i], &gain_e[i]); + } + ELSE + { + /* gain = 1 */ + gain_m[i] = 32767; + move16(); + gain_e[i] = 0; + move16(); } - procTec( hb_synth, i_offset, l_subfr, gain, code ); + gain_m[i] = Sqrt16(gain_m[i], &gain_e[i]); + move16(); + + s = norm_s(gain_m[i]); + gain_m[i] = shl(gain_m[i], s); + move16(); + gain_e[i] = sub(gain_e[i], s); + move16(); + + FOR (j=0; j 15) + { + exp_syn = 15; + move16(); + } + + if (exp_syn < 0) + { + exp_syn = 0; + move16(); + } + + min_shift = sub(s, exp_syn); /* exp_syn(old) - exp_syn(new) */ + + k = k_offset; + move16(); + FOR (i=i_offset; i 0) + { + hb_synth_Fx[k] = shr(hb_synth_Fx[k], s); + move16(); + } + k = add(k, 1); + } + } + return exp_syn; +} /*------------------------------------------------------------------- - * resetTecEnc() + * procTecTfa_TBE() * * *-------------------------------------------------------------------*/ - -void resetTecEnc( - TEC_ENC_HANDLE hTecEnc, - const int16_t flag ) +Word16 procTecTfa_TBE_Fx( + Word16 *hb_synth_Fx, + Word16 hb_synth_fx_exp, + Word16 *gain_m, + Word16 *gain_e, + Word16 flat_flag, + Word16 last_core, + Word16 l_subfr, + Word16 code +) { - if ( flag == 0 ) + Word16 i_offset = 0; + Word16 exp_syn_frame = sub(15, hb_synth_fx_exp); + + + IF (flat_flag) { - set_f( hTecEnc->loBuffer_flt, 0.f, CLDFB_NO_COL_MAX + MAX_TEC_SMOOTHING_DEG + DELAY_TEMP_ENV_BUFF_TEC ); - set_f( hTecEnc->hiTempEnv_flt, 0.f, CLDFB_NO_COL_MAX + DELAY_TEMP_ENV_BUFF_TEC + EXT_DELAY_HI_TEMP_ENV ); - set_f( hTecEnc->loTempEnv_flt, 0.f, CLDFB_NO_COL_MAX ); - set_f( hTecEnc->loTempEnv_ns_flt, 0.f, CLDFB_NO_COL_MAX ); + exp_syn_frame = procTfa_Fx(hb_synth_Fx, + exp_syn_frame, + i_offset, + l_subfr + ); } - else + ELSE { - set_f( hTecEnc->loBuffer_flt, 0.f, MAX_TEC_SMOOTHING_DEG ); + if (NE_16(last_core, ACELP_CORE)) + { + i_offset = 1; + move16(); + } + + + exp_syn_frame = procTec_Fx(hb_synth_Fx, + exp_syn_frame, + gain_m, + gain_e, + i_offset, + l_subfr + , code + ); + } - return; + hb_synth_fx_exp = sub(15, exp_syn_frame); + + return hb_synth_fx_exp; } @@ -698,237 +1263,375 @@ void resetTecEnc( * *-------------------------------------------------------------------*/ -void calcHiEnvLoBuff( - const int16_t noCols, - const int16_t *pFreqBandTable, /*!< freqbandTable. */ - const int16_t nSfb, /*!< Number of scalefactors. */ - float **pCldfbPow, - float *loBuffer, - float *hiTempEnvOrig ) +void calcHiEnvLoBuff_Fix( + const Word16 noCols, + const Word16* pFreqBandTable, /*!< freqbandTable. */ + const Word16 nSfb, /*!< Number of scalefactors. */ + Word32** pCldfbPow_Fix /*float** pCldfbPow*/, + Word16* loBuffer_Fix /*float* loBuffer Q8*/, + Word16* hiTempEnvOrig_Fix /*float* hiTempEnvOrig*/, + Word16 pCldfbPow_FixScale +) { - const int16_t BW_LO = TecLowBandTable[NbTecLowBand]; - const int16_t lowSubband = pFreqBandTable[0]; - const int16_t highSubband = pFreqBandTable[nSfb]; + const Word16 BW_LO = TecLowBandTable[NBTECLOWBAND]; + const Word16 lowSubband = pFreqBandTable[0]; + const Word16 highSubband = pFreqBandTable[nSfb]; - int16_t bandOffsetBottom = lowSubband - BW_LO; + Word16 bandOffsetBottom; - float scaleOffset = 0; - float *hiTempEnv = hiTempEnvOrig + EXT_DELAY_HI_TEMP_ENV; + Word16* hiTempEnv = hiTempEnvOrig_Fix + EXT_DELAY_HI_TEMP_ENV; - assert( bandOffsetBottom > 0 ); + move16(); + move16(); + move16(); + bandOffsetBottom = sub(lowSubband, BW_LO); - /* calc hiTempEnv*/ - calcHiTempEnv( pCldfbPow, 0, noCols, lowSubband, highSubband, scaleOffset, hiTempEnv + DELAY_TEMP_ENV_BUFF_TEC ); + assert(bandOffsetBottom > 0); + assert(noCols <= CLDFB_NO_COL_MAX); - /* calc loBuffer */ - calcLoBufferEnc( pCldfbPow, 0, noCols, bandOffsetBottom, scaleOffset, loBuffer + MAX_TEC_SMOOTHING_DEG + DELAY_TEMP_ENV_BUFF_TEC ); + /* ============================================================ */ + /* = calc hiTempEnv = */ - return; -} + calcHiTempEnv_Fx(pCldfbPow_Fix,sub(pCldfbPow_FixScale,30),0,noCols,lowSubband,highSubband,hiTempEnv + DELAY_TEMP_ENV_BUFF_TEC); + + /* = = */ + /* ============================================================ */ + /* ============================================================ */ + /* = calc loBuffer = */ + + calcLoBufferEnc_Fx(pCldfbPow_Fix,sub(pCldfbPow_FixScale,30),0, noCols,bandOffsetBottom,loBuffer_Fix + MAX_TEC_SMOOTHING_DEG + DELAY_TEMP_ENV_BUFF_TEC); + + /* = = */ + /* ============================================================ */ +} /*------------------------------------------------------------------- * calcLoEnvCheckCorrHiLo() * * *-------------------------------------------------------------------*/ - -void calcLoEnvCheckCorrHiLo( - const int16_t noCols, - const int16_t *pFreqBandTable, /*!< freqbandTable. */ - float *loBuffer, - float *loTempEnv, - float *loTempEnv_ns, - float *hiTempEnvOrig, - int16_t *corrFlag ) +void calcLoEnvCheckCorrHiLo_Fix( + const Word16 noCols, + const Word16* pFreqBandTable, /*!< freqbandTable. */ + Word16* loBuffer_Fix /*float* loBuffer Q8*/, + Word16* loTempEnv_Fix /*float* loTempEnv Q7*/, + Word16* loTempEnv_ns_Fix /* float* loTempEnv_ns*/, + Word16* hiTempEnvOrig_Fix /*float* hiTempEnvOrig*/, + Word16* corrFlag /*int* corrFlag*/ +) { - const int16_t BW_LO = TecLowBandTable[NbTecLowBand]; - const int16_t lowSubband = pFreqBandTable[0]; - int16_t i; - float corrCoef; - int16_t bandOffsetBottom = lowSubband - BW_LO; - float ratio_float; - float hiVar, loVar; - float hiSum, loSum; - int16_t code = 0; /* SET TENTATIVELY */ - float loVar_ns; - float loSum_ns; - float diff_hi_lo_sum; + const Word16 BW_LO = TecLowBandTable[NBTECLOWBAND]; + const Word16 lowSubband = pFreqBandTable[0]; + Word16 i; + + Word16 bandOffsetBottom; + + Word32 hiVar_Fix, loVar_Fix; + Word32 hiSum_Fix, loSum_Fix; + Word32 hiTempEnv32_Fix[CLDFB_NO_COL_MAX + DELAY_TEMP_ENV_BUFF_TEC]; + Word32 loTempEnv32_Fix[CLDFB_NO_COL_MAX + DELAY_TEMP_ENV_BUFF_TEC]; + Word32 loTempEnv32_ns_Fix[CLDFB_NO_COL_MAX + DELAY_TEMP_ENV_BUFF_TEC]; - float *hiTempEnv = hiTempEnvOrig + EXT_DELAY_HI_TEMP_ENV; + Word32 corrCoef_Fix; - assert( bandOffsetBottom > 0 ); + Word32 EQ1, EQ2, EQ3; + Word32 EQ4,EQ5,EQ6; - hiVar = calcVar( hiTempEnv, noCols, &hiSum ); + Word16 code = 0; /* SET TENTATIVELY */ + Word32 loVar_ns_Fix; + Word32 diff_hi_lo_sum_Fix; + Word32 loSum_ns_Fix; + Word16* hiTempEnv = hiTempEnvOrig_Fix + EXT_DELAY_HI_TEMP_ENV; - /* calc loTempEnv */ - calcLoTempEnv( loBuffer + MAX_TEC_SMOOTHING_DEG, noCols, loTempEnv, ratioHiLoFac ); - calcLoTempEnv_ns( loBuffer + MAX_TEC_SMOOTHING_DEG, noCols, loTempEnv_ns ); + move16(); + move16(); + move16(); + bandOffsetBottom = sub(lowSubband, BW_LO); - loVar_ns = calcVar( loTempEnv_ns, noCols, &loSum_ns ); - diff_hi_lo_sum = loSum_ns - hiSum; + assert(bandOffsetBottom > 0); + assert(noCols <= CLDFB_NO_COL_MAX); - if ( hiVar > 800 && loVar_ns > 720 && diff_hi_lo_sum < 100 ) + + FOR( i = 0; i < noCols+ DELAY_TEMP_ENV_BUFF_TEC; i++) + { + hiTempEnv32_Fix[i] = L_deposit_l(hiTempEnv[i]); + } + hiVar_Fix = calcVar_Fix(hiTempEnv32_Fix, (Word32)noCols, &hiSum_Fix); + + + /* ============================================================ */ + /* = calc loTempEnv = */ + + + + calcLoTempEnv_Fx(loBuffer_Fix+MAX_TEC_SMOOTHING_DEG,noCols,loTempEnv_Fix,26041/*0.5 * ratioHiLoFac Q15*/); + + + calcLoTempEnv_ns_Fx(loBuffer_Fix+MAX_TEC_SMOOTHING_DEG,noCols,loTempEnv_ns_Fix); + + /* = = */ + /* ============================================================ */ + + + FOR( i = 0; i < noCols; i++) + { + loTempEnv32_ns_Fix[i] = L_deposit_l(loTempEnv_ns_Fix[i]); + } + loVar_ns_Fix = calcVar_Fix(loTempEnv32_ns_Fix, noCols, &loSum_ns_Fix); + + diff_hi_lo_sum_Fix = L_sub(loSum_ns_Fix,hiSum_Fix); + + EQ4 = L_sub(L_shr(hiVar_Fix,7),800); + EQ5 = L_sub(L_shr(loVar_ns_Fix,7),720);; + EQ6 = L_sub(L_shr(diff_hi_lo_sum_Fix,7),100); ; + test(); + test(); + if (EQ4 > 0 && EQ5 > 0 && EQ6 < 0) { code = 1; + move16(); } + + *corrFlag = 0; + move16(); - assert( code == 0 || code == 1 ); + assert(code == 0 || code == 1); - if ( code ) + IF (code) { /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ /* ++++ code == 1 +++++*/ /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ - int16_t maxPosHi, maxPosLo; - float maxHi, maxLo; + Word16 maxPosHi, maxPosLo; + Word16 maxHiFix, maxLoFix; - maxHi = hiTempEnv[0]; - maxLo = loTempEnv_ns[0]; + maxHiFix = hiTempEnv[0]; + move16(); + maxLoFix = loTempEnv_ns_Fix[0]; + move16(); maxPosHi = maxPosLo = 0; - - for ( i = 1; i < noCols; i++ ) + move16(); + FOR (i = 1; i < noCols; i++) { - if ( maxHi < hiTempEnv[i] ) + if ( LT_16(maxHiFix , hiTempEnv[i])) { - maxHi = hiTempEnv[i]; maxPosHi = i; + move16(); } + maxHiFix = s_max(maxHiFix, hiTempEnv[i]); - if ( maxLo < loTempEnv_ns[i] ) + if ( LT_16(maxLoFix , loTempEnv_ns_Fix[i])) { - maxLo = loTempEnv_ns[i]; maxPosLo = i; + move16(); } + maxLoFix = s_max(maxLoFix, loTempEnv_ns_Fix[i]); } - if ( abs( maxPosHi - maxPosLo ) < 2 ) + if (LT_16(abs_s( sub(maxPosHi , maxPosLo)), 2)) { *corrFlag = 2; + move16(); } { - float feature_max = 0; - int16_t pos_feature_max = 0; - float feature[16]; - float min_local, max_local; - int16_t j; - int16_t len_window = EXT_DELAY_HI_TEMP_ENV + 1; - float *curr_pos = hiTempEnv; + Word16 feature_max_Fix = 0; + Word16 pos_feature_max = 0; + Word16 feature_Fix[16]; + Word16 min_local_Fix, max_local_Fix; + Word16 j; + Word16 len_window = EXT_DELAY_HI_TEMP_ENV + 1; + + Word16* curr_pos_Fix = hiTempEnv; + + move16(); + move16(); + move16(); + move16(); - feature_max = 0; + feature_max_Fix = 0; + move16(); pos_feature_max = 0; + move16(); - for ( i = 0; i < 16; i++, curr_pos++ ) + FOR (i = 0; i < 16; i++) { - max_local = min_local = curr_pos[0]; + max_local_Fix = min_local_Fix = curr_pos_Fix[0]; + move16(); + move16(); - for ( j = 1; j < len_window; j++ ) + FOR (j = 1; j < len_window; j++) { - if ( max_local < curr_pos[-j] ) + if ( LT_16( max_local_Fix , curr_pos_Fix[-j])) { - max_local = curr_pos[-j]; + max_local_Fix = curr_pos_Fix[-j]; + move16(); } - if ( min_local > curr_pos[-j] ) + if ( GT_16(min_local_Fix, curr_pos_Fix[-j] )) { - min_local = curr_pos[-j]; + min_local_Fix = curr_pos_Fix[-j]; + move16(); } } + feature_Fix[i] = sub(max_local_Fix , min_local_Fix); - feature[i] = max_local - min_local; - - if ( feature_max < feature[i] ) + if ( LT_16(feature_max_Fix , feature_Fix[i])) { - feature_max = feature[i]; pos_feature_max = i; + move16(); } + feature_max_Fix = s_max(feature_max_Fix, feature_Fix[i]); + curr_pos_Fix += 1; } - if ( *corrFlag > 0 ) + IF (*corrFlag > 0) { - if ( !( feature_max > 20 && abs( pos_feature_max - maxPosHi ) < 3 ) ) + test(); + if ((LE_16(feature_max_Fix, shl(20, 7))||GE_16(abs_s(sub(pos_feature_max,maxPosHi)),3))) { *corrFlag = 0; + move16(); } } } + } - else + ELSE { /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ /* ++++ code == 0 ++++*/ /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ - /* calc the variance of loTempEnv */ - loVar = calcVar( loTempEnv, noCols, &loSum ); - /* calc correlation coefficient between loTempEnv and hiTempEnv */ - corrCoef = calcCorrelationCoefficient2( hiTempEnv, loTempEnv, noCols, hiVar, loVar, hiSum, loSum ); + /* ============================================================ */ + /* = calc the variance of loTempEnv = */ + + FOR( i = 0; i < noCols; i++) + { + loTempEnv32_Fix[i] = L_deposit_l(loTempEnv_Fix[i]); + } + loVar_Fix = calcVar_Fix(loTempEnv32_Fix, noCols, &loSum_Fix); + /* = = */ + /* ============================================================ */ + + /* ============================================================ */ + /* = calc correlation coefficient between = */ + /* = loTempEnv and hiTempEnv = */ + corrCoef_Fix = calcCorrelationCoefficient2_Fix( + hiTempEnv32_Fix, loTempEnv32_Fix, + noCols, hiVar_Fix, loVar_Fix, hiSum_Fix, loSum_Fix); + /* = = */ + /* ============================================================ */ - ratio_float = hiVar / ( loVar + EPS ); - if ( corrCoef >= thCorrCoef && ratio_float > thRatio && ratio_float < thRatio2 ) + + + EQ1 = L_sub(L_shl(corrCoef_Fix, 8),28819/*thCorrCoef Q15*/); + EQ2 = L_sub(L_shl(hiVar_Fix,0),Mpy_32_16_1(loVar_Fix,11957/*thRatio Q15*/)); + EQ3 = L_sub(L_shr(hiVar_Fix,2),Mpy_32_16_1(loVar_Fix,16620/*thRatio2 Q13*/)); + + test(); + test(); + if (EQ1 >= 0 && EQ2 > 0 /*ratio > thRatio*/ && EQ3 < 0) { *corrFlag = 1; + move16(); } + } - for ( i = 0; i < MAX_TEC_SMOOTHING_DEG + DELAY_TEMP_ENV_BUFF_TEC; i++ ) + FOR (i = 0; i < MAX_TEC_SMOOTHING_DEG + DELAY_TEMP_ENV_BUFF_TEC; i++) { - loBuffer[i] = loBuffer[noCols + i]; + loBuffer_Fix[i] = loBuffer_Fix[noCols + i]; + move16(); } - for ( i = 0; i < DELAY_TEMP_ENV_BUFF_TEC + EXT_DELAY_HI_TEMP_ENV; i++ ) + FOR (i = 0; i < DELAY_TEMP_ENV_BUFF_TEC + EXT_DELAY_HI_TEMP_ENV; i++) { - hiTempEnvOrig[i] = hiTempEnvOrig[noCols + i]; + hiTempEnvOrig_Fix[i] = hiTempEnvOrig_Fix[noCols + i]; + move16(); } - return; } - /*------------------------------------------------------------------- * tecEnc_TBE() * * *-------------------------------------------------------------------*/ -void tecEnc_TBE( - int16_t *corrFlag, - const float *voicing, - const int16_t coder_type ) +void tecEnc_TBE_fx( + Word16* corrFlag, + const Word16* voicing, + const Word16 coder_type +) { - float voice_sum; - float voice_diff; + Word16 voice_sum; + Word16 voice_diff; /*-----------------------------------------------------------------* * TEC updates *-----------------------------------------------------------------*/ - voice_sum = voicing[0] + voicing[1]; - voice_diff = voicing[0] - voicing[1]; + voice_sum = add(shr(voicing[0], 1), shr(voicing[1], 1)); /*voice_sum = voicing[0] + voicing[1];*/ + voice_diff = sub(voicing[0], voicing[1]); /*voice_diff = voicing[0] - voicing[1];*/ - if ( voice_diff < 0 ) + if( voice_diff < 0 ) { - voice_diff *= -1.0f; + voice_diff = negate(voice_diff);/*voice_diff *= -1.0f;*/ } - if ( *corrFlag == 1 ) + IF( EQ_16(*corrFlag, 1)) { - if ( coder_type == INACTIVE || ( ( voice_sum > 0.35 * 2 && voice_sum < 0.55 * 2 ) && ( voice_diff < 0.2 ) ) ) + test(); + test(); + test(); + /*if( ((voice_sum > 0.35 * 2 && voice_sum < 0.55 * 2) && (voice_diff < 0.2)) )*/ + if( EQ_16(coder_type,INACTIVE) || (GT_16(voice_sum,11469/*0.35 Q15*/) && LT_16(voice_sum,18022/*0.55 Q15*/) && (sub(voice_diff,6554/*0.2 Q15*/)<0))) { *corrFlag = 0; + move16(); } } - if ( voice_sum > 0.6 * 2 ) + if( GT_16(voice_sum, 19661/*0.6 Q15*/)) /*if( voice_sum > 0.6 * 2 )*/ { *corrFlag = 0; + move16(); } +} +/*------------------------------------------------------------------- + * set_TEC_TFA_code() + * + * + *-------------------------------------------------------------------*/ +void set_TEC_TFA_code_fx( + const Word16 corrFlag, + Word16* tec_flag, + Word16* tfa_flag +) +{ + *tec_flag = 0; + move16(); + IF (*tfa_flag == 0) + { + test(); + if (EQ_16(corrFlag, 1)||EQ_16(corrFlag,2)) + { + *tec_flag = 1; + move16(); + } - return; + if (EQ_16(corrFlag, 2)) + { + *tfa_flag = 1; + move16(); + } + } } + diff --git a/lib_com/tec_com_flt.c b/lib_com/tec_com_flt.c new file mode 100644 index 0000000000000000000000000000000000000000..fbe8ba4328138de5e7267263f573d1c3fd00b93e --- /dev/null +++ b/lib_com/tec_com_flt.c @@ -0,0 +1,932 @@ +/****************************************************************************************************** + + (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +/*==================================================================================== + EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 + ====================================================================================*/ + +#include +#include +#include "options.h" +#include +#include "rom_com.h" +#include "prot.h" +#include "stat_dec.h" +#include "wmc_auto.h" + +/*------------------------------------------------------------------- + * Local constants + *-------------------------------------------------------------------*/ + +#define LOBUF_NO_SMOOTHING_MODE 1 + +#define EPS ( 1e-12f ) +#define ENV_SCALE_OFFSET_1 90.309f /* 10*log10(2^30) */ +#define MAX_TEC_BW_LO ( 12 ) +#define MAX_NB_TEC_LOW_BAND ( 3 ) + + +#define TecSmoothingDeg 5 +#define NbTecLowBand 3 + +#define ratioHiLoFac 1.5894f +#define thRatio 0.3649f +#define thRatio2 2.0288f +#define thCorrCoef 0.8795f +#define ratioHiLoFacDec ( 1.5894f * 0.75f ) + +/*------------------------------------------------------------------- + * calcLoBufferDec() + * + * + *-------------------------------------------------------------------*/ + +static void calcLoBufferDec( + float **pCldfbReal, + float **pCldfbImag, + float *loBuffer, + const int16_t startPos, + const int16_t stopPos, + const int16_t bandOffsetBottom, + const float scaleOffset ) +{ + int16_t slot, k, lb, li, ui; + float nrg, tmp; + + /* calc loTempEnv */ + for ( slot = startPos; slot < stopPos; slot++ ) + { + tmp = 0; + + for ( lb = 0; lb < NbTecLowBand; lb++ ) + { + li = TecLowBandTable[lb]; + ui = TecLowBandTable[lb + 1]; + + nrg = 0; + for ( k = li; k < ui; k++ ) + { + nrg += pCldfbReal[slot][k + bandOffsetBottom] * pCldfbReal[slot][k + bandOffsetBottom] + pCldfbImag[slot][k + bandOffsetBottom] * pCldfbImag[slot][k + bandOffsetBottom]; + } + tmp += (float) log10( nrg * normReciprocal[ui - li] + EPS ); + } + + loBuffer[slot] = 10.0f * tmp / NbTecLowBand + scaleOffset; + } + + return; +} + + +/*------------------------------------------------------------------- + * calcLoBufferEnc() + * + * + *-------------------------------------------------------------------*/ + +static void calcLoBufferEnc( + float **pCldfbPow, + const int16_t startPos, + const int16_t stopPos, + const int16_t bandOffsetBottom, + const float scaleOffset, + float *loBuffer ) +{ + int16_t slot, k, lb, li, ui; + float nrg, tmp; + + /* calc loTempEnv */ + for ( slot = startPos; slot < stopPos; slot++ ) + { + tmp = 0; + + for ( lb = 0; lb < NbTecLowBand; lb++ ) + { + li = TecLowBandTable[lb]; + ui = TecLowBandTable[lb + 1]; + + nrg = 0; + for ( k = li; k < ui; k++ ) + { + nrg += pCldfbPow[slot][k + bandOffsetBottom]; + } + tmp += (float) log10( nrg * normReciprocal[ui - li] + EPS ); + } + + loBuffer[slot] = 10.0f * tmp / NbTecLowBand + scaleOffset; + } + + return; +} + + +/*------------------------------------------------------------------- + * calcLoTempEnv() + * + * + *-------------------------------------------------------------------*/ + +static void calcLoTempEnv( + const float *loBuffer, + const int16_t noCols, + float *loTempEnv, + const float adjFac ) +{ + int16_t slot, i; + + for ( slot = 0; slot < noCols; slot++ ) + { + loTempEnv[slot] = TecSC[0] * loBuffer[slot]; + for ( i = 1; i < TecSmoothingDeg + 1; i++ ) + { + loTempEnv[slot] += TecSC[i] * loBuffer[slot - i]; + } + + loTempEnv[slot] *= adjFac; + } + + return; +} + +/*------------------------------------------------------------------- + * calcHiTempEnv() + * + * + *-------------------------------------------------------------------*/ + +static void calcHiTempEnv( + float **pCldfbPow, + const int16_t startPos, + const int16_t stopPos, + const int16_t lowSubband, + const int16_t highSubband, + const float scaleOffset, + float *hiTempEnv ) +{ + int16_t timeIndex, k; + int16_t bwHigh = highSubband - lowSubband; + + /* set hiTempEnv */ + for ( timeIndex = startPos; timeIndex < stopPos; timeIndex++ ) + { + hiTempEnv[timeIndex] = 0; + for ( k = lowSubband; k < highSubband; k++ ) + { + hiTempEnv[timeIndex] += pCldfbPow[timeIndex][k]; + } + hiTempEnv[timeIndex] = (float) ( 10 * log10( hiTempEnv[timeIndex] / bwHigh + EPS ) + scaleOffset ); + } + + return; +} + + +/*------------------------------------------------------------------- + * calcVar() + * + * + *-------------------------------------------------------------------*/ + +static float calcVar( + const float in[], + const int16_t len, + float *x ) +{ + float xx; + int16_t i; + + xx = 0; + *x = 0; + + for ( i = 0; i < len; i++ ) + { + xx += in[i] * in[i]; + *x += in[i]; + } + + return ( xx - ( *x * *x ) / (float) len ); +} + + +/*------------------------------------------------------------------- + * calcCorrelationCoefficient2() + * + * + *-------------------------------------------------------------------*/ + +static float calcCorrelationCoefficient2( + const float in_vec1[], + const float in_vec2[], + const int16_t len, + float var_x, + float var_y, + float x, + float y ) +{ + int16_t i; + float xy; + float ans; + + xy = 0; + + for ( i = 0; i < len; i++ ) + { + xy += ( in_vec1[i] * in_vec2[i] ); + } + + ans = ( xy - x * y / (float) ( len ) ) / (float) sqrt( var_x * var_y + EPS ); + + return ans; +} + + +/*------------------------------------------------------------------- + * resetTecDec() + * + * + *-------------------------------------------------------------------*/ + +void resetTecDec( + TEC_DEC_HANDLE hTecDec ) +{ + set_f( hTecDec->pGainTemp, 0, CLDFB_NO_COL_MAX ); + + set_f( hTecDec->loBuffer_flt, 0.f, CLDFB_NO_COL_MAX + MAX_TEC_SMOOTHING_DEG ); + + return; +} + + +/*------------------------------------------------------------------- + * calcLoTempEnv_TBE() + * + * + *-------------------------------------------------------------------*/ + +static void calcLoTempEnv_TBE( + const float *loBuffer, + const int16_t noCols, + float *loTempEnv, + const float adjFac ) +{ + int16_t slot, i; + int16_t delay = 1; + + for ( slot = 0; slot < noCols; slot++ ) + { + loTempEnv[slot] = TecSC[0] * loBuffer[slot - delay]; + + for ( i = 1; i < TecSmoothingDeg + 1; i++ ) + { + loTempEnv[slot] += TecSC[i] * loBuffer[slot - delay - i]; + } + + loTempEnv[slot] *= adjFac; + } + + return; +} + + +/*------------------------------------------------------------------- + * set_TEC_TFA_code() + * + * + *-------------------------------------------------------------------*/ + +void set_TEC_TFA_code( + const int16_t corrFlag, + int16_t *tec_flag, + int16_t *tfa_flag ) +{ + *tec_flag = 0; + if ( *tfa_flag == 0 ) + { + if ( corrFlag == 1 ) + { + *tec_flag = 1; + } + else if ( corrFlag == 2 ) + { + *tec_flag = 1; + *tfa_flag = 1; + } + } + + return; +} + + +/*------------------------------------------------------------------- + * calcLoTempEnv_ns_TBE() + * + * + *-------------------------------------------------------------------*/ + +static void calcLoTempEnv_ns_TBE( + const float *loBuffer, + const int16_t noCols, + float *loTempEnv ) +{ + int16_t slot; + int16_t delay = 1; + float fac = 1.4f; + + for ( slot = 0; slot < noCols; slot++ ) + { + loTempEnv[slot] = fac * loBuffer[slot - delay]; + } + + return; +} + + +/*------------------------------------------------------------------- + * calcLoTempEnv_ns() + * + * + *-------------------------------------------------------------------*/ + +static void calcLoTempEnv_ns( + const float *loBuffer, + const int16_t noCols, + float *loTempEnv ) +{ + int16_t slot; + + for ( slot = 0; slot < noCols; slot++ ) + { + loTempEnv[slot] = loBuffer[slot]; + } + + return; +} + +/*------------------------------------------------------------------- + * calcGainLinear_TBE() + * + * + *-------------------------------------------------------------------*/ + +static void calcGainLinear_TBE( + const float *loTempEnv, + const int16_t startPos, + const int16_t stopPos, + float *pGainTemp ) +{ + int16_t timeIndex; + float ftmp; + + for ( timeIndex = startPos; timeIndex < stopPos; timeIndex++ ) + { + ftmp = loTempEnv[timeIndex]; + pGainTemp[timeIndex] = (float) pow( 10.0, 0.1 * ftmp ); + } + + return; +} + + +/*------------------------------------------------------------------- + * calcGainTemp_TBE() + * + * + *-------------------------------------------------------------------*/ + +void calcGainTemp_TBE( + float **pCldfbRealSrc, + float **pCldfbImagSrc, + float *loBuffer, + const int16_t startPos, /*!< Start position of the current envelope. */ + const int16_t stopPos, /*!< Stop position of the current envelope. */ + const int16_t lowSubband, /* lowSubband */ + float *pGainTemp, + const int16_t code ) +{ + float loTempEnv[16]; + const int16_t BW_LO = TecLowBandTable[NbTecLowBand]; + int16_t slot; + int16_t noCols = stopPos - startPos; + int16_t bandOffset = 0; + float scaleOffset = 0; + + assert( lowSubband >= BW_LO ); + + bandOffset = lowSubband - BW_LO; + + calcLoBufferDec( pCldfbRealSrc, pCldfbImagSrc, loBuffer + MAX_TEC_SMOOTHING_DEG, startPos, stopPos, bandOffset, scaleOffset ); + + if ( code > 0 ) + { + if ( code != 2 ) + { + calcLoTempEnv_TBE( loBuffer + MAX_TEC_SMOOTHING_DEG, noCols, loTempEnv, ratioHiLoFacDec ); + } + else + { + calcLoTempEnv_ns_TBE( loBuffer + MAX_TEC_SMOOTHING_DEG, noCols, loTempEnv ); + } + + calcGainLinear_TBE( loTempEnv, startPos, stopPos, pGainTemp ); + } + + + for ( slot = 0; slot < MAX_TEC_SMOOTHING_DEG; slot++ ) + { + loBuffer[slot] = loBuffer[slot + stopPos]; + } + + return; +} + + +/*------------------------------------------------------------------- + * setSubfrConfig() + * + * + *-------------------------------------------------------------------*/ + +static void setSubfrConfig( + const int16_t i_offset, + int16_t *k_offset, + int16_t *n_subfr, + const int16_t l_subfr ) +{ + *n_subfr = N_TEC_TFA_SUBFR - i_offset; + *k_offset = i_offset * l_subfr; + + return; +} + + +/*------------------------------------------------------------------- + * calcSubfrNrg() + * + * + *-------------------------------------------------------------------*/ + +static float calcSubfrNrg( + const float *hb_synth, + const int16_t i_offset, + float *enr, + const int16_t k_offset, + const int16_t l_subfr ) +{ + int16_t i, j, k; + float enr_all = 1e-12f; + + for ( i = i_offset, k = k_offset; i < N_TEC_TFA_SUBFR; i++ ) + { + enr[i] = 1e-12f; + for ( j = 0; j < l_subfr; j++ ) + { + enr[i] += hb_synth[k] * hb_synth[k]; + k++; + } + enr_all += enr[i]; + } + + return enr_all; +} + + +/*------------------------------------------------------------------- + * procTfa() + * + * + *-------------------------------------------------------------------*/ + +static void procTfa( + float *hb_synth, + const int16_t i_offset, + const int16_t l_subfr ) +{ + int16_t i, j, k; + int16_t k_offset, n_subfr; + float enr[N_TEC_TFA_SUBFR], enr_ave; + + setSubfrConfig( i_offset, &k_offset, &n_subfr, l_subfr ); + + enr_ave = calcSubfrNrg( hb_synth, i_offset, enr, k_offset, l_subfr ) / n_subfr; + + for ( i = i_offset, k = k_offset; i < N_TEC_TFA_SUBFR; i++ ) + { + float gain; + + gain = (float) sqrt( enr_ave / enr[i] ); + + for ( j = 0; j < l_subfr; j++ ) + { + hb_synth[k] *= gain; + k++; + } + } + + return; +} + + +/*------------------------------------------------------------------- + * procTec() + * + * + *-------------------------------------------------------------------*/ + +static void procTec( + float *hb_synth, + const int16_t i_offset, + const int16_t l_subfr, + float *gain, + const int16_t code ) +{ + int16_t i, j, k; + int16_t k_offset, n_subfr; + float enr[N_TEC_TFA_SUBFR], enr_ave, gain_ave; + float inv_curr_enr[N_TEC_TFA_SUBFR]; + float max_inv_curr_enr, lower_limit_gain; + float upper_limit_gain; + float tmp; + + setSubfrConfig( i_offset, &k_offset, &n_subfr, l_subfr ); + + enr_ave = calcSubfrNrg( hb_synth, i_offset, enr, k_offset, l_subfr ) / n_subfr; + + gain_ave = ( sum_f( &gain[i_offset], n_subfr ) + 1.0e-12f ) / n_subfr; + + max_inv_curr_enr = 10e-6f; + for ( i = i_offset, k = k_offset; i < N_TEC_TFA_SUBFR; i++ ) + { + inv_curr_enr[i] = enr_ave / enr[i]; + gain[i] /= gain_ave; + if ( max_inv_curr_enr < inv_curr_enr[i] ) + { + max_inv_curr_enr = inv_curr_enr[i]; + } + } + + lower_limit_gain = 0.1f; + if ( lower_limit_gain > ( tmp = 1.f / max_inv_curr_enr ) ) + { + lower_limit_gain = tmp * 0.5f; + } + + upper_limit_gain = 1.2f; + if ( code == LOBUF_NO_SMOOTHING_MODE ) + { + upper_limit_gain = 3.0; + } + + for ( i = i_offset, k = k_offset; i < N_TEC_TFA_SUBFR; i++ ) + { + if ( lower_limit_gain > gain[i] ) + { + gain[i] = lower_limit_gain; + } + gain[i] *= inv_curr_enr[i]; + + if ( gain[i] > upper_limit_gain ) + { + gain[i] = upper_limit_gain; + } + + gain[i] = (float) sqrt( gain[i] ); + for ( j = 0; j < l_subfr; j++ ) + { + hb_synth[k] *= gain[i]; + k++; + } + } + + return; +} + + +/*------------------------------------------------------------------- + * procTecTfa_TBE() + * + * + *-------------------------------------------------------------------*/ + +void procTecTfa_TBE( + float *hb_synth, + float *gain, + const int16_t flat_flag, + const int16_t last_core, + const int16_t l_subfr, + const int16_t code ) +{ + int16_t i_offset = 0; + + if ( flat_flag ) + { + procTfa( hb_synth, i_offset, l_subfr ); + } + else + { + if ( last_core != ACELP_CORE ) + { + i_offset = 1; + } + + procTec( hb_synth, i_offset, l_subfr, gain, code ); + } + + return; +} + + +/*------------------------------------------------------------------- + * resetTecEnc() + * + * + *-------------------------------------------------------------------*/ + +void resetTecEnc( + TEC_ENC_HANDLE hTecEnc, + const int16_t flag ) +{ + if ( flag == 0 ) + { + set_f( hTecEnc->loBuffer_flt, 0.f, CLDFB_NO_COL_MAX + MAX_TEC_SMOOTHING_DEG + DELAY_TEMP_ENV_BUFF_TEC ); + set_f( hTecEnc->hiTempEnv_flt, 0.f, CLDFB_NO_COL_MAX + DELAY_TEMP_ENV_BUFF_TEC + EXT_DELAY_HI_TEMP_ENV ); + set_f( hTecEnc->loTempEnv_flt, 0.f, CLDFB_NO_COL_MAX ); + set_f( hTecEnc->loTempEnv_ns_flt, 0.f, CLDFB_NO_COL_MAX ); + } + else + { + set_f( hTecEnc->loBuffer_flt, 0.f, MAX_TEC_SMOOTHING_DEG ); + } + + return; +} + + +/*------------------------------------------------------------------- + * calcHiEnvLoBuff() + * + * + *-------------------------------------------------------------------*/ + +void calcHiEnvLoBuff( + const int16_t noCols, + const int16_t *pFreqBandTable, /*!< freqbandTable. */ + const int16_t nSfb, /*!< Number of scalefactors. */ + float **pCldfbPow, + float *loBuffer, + float *hiTempEnvOrig ) +{ + const int16_t BW_LO = TecLowBandTable[NbTecLowBand]; + const int16_t lowSubband = pFreqBandTable[0]; + const int16_t highSubband = pFreqBandTable[nSfb]; + + int16_t bandOffsetBottom = lowSubband - BW_LO; + + float scaleOffset = 0; + float *hiTempEnv = hiTempEnvOrig + EXT_DELAY_HI_TEMP_ENV; + + assert( bandOffsetBottom > 0 ); + + /* calc hiTempEnv*/ + calcHiTempEnv( pCldfbPow, 0, noCols, lowSubband, highSubband, scaleOffset, hiTempEnv + DELAY_TEMP_ENV_BUFF_TEC ); + + /* calc loBuffer */ + calcLoBufferEnc( pCldfbPow, 0, noCols, bandOffsetBottom, scaleOffset, loBuffer + MAX_TEC_SMOOTHING_DEG + DELAY_TEMP_ENV_BUFF_TEC ); + + return; +} + + +/*------------------------------------------------------------------- + * calcLoEnvCheckCorrHiLo() + * + * + *-------------------------------------------------------------------*/ + +void calcLoEnvCheckCorrHiLo( + const int16_t noCols, + const int16_t *pFreqBandTable, /*!< freqbandTable. */ + float *loBuffer, + float *loTempEnv, + float *loTempEnv_ns, + float *hiTempEnvOrig, + int16_t *corrFlag ) +{ + const int16_t BW_LO = TecLowBandTable[NbTecLowBand]; + const int16_t lowSubband = pFreqBandTable[0]; + int16_t i; + float corrCoef; + int16_t bandOffsetBottom = lowSubband - BW_LO; + float ratio_float; + float hiVar, loVar; + float hiSum, loSum; + int16_t code = 0; /* SET TENTATIVELY */ + float loVar_ns; + float loSum_ns; + float diff_hi_lo_sum; + + float *hiTempEnv = hiTempEnvOrig + EXT_DELAY_HI_TEMP_ENV; + + assert( bandOffsetBottom > 0 ); + + hiVar = calcVar( hiTempEnv, noCols, &hiSum ); + + /* calc loTempEnv */ + calcLoTempEnv( loBuffer + MAX_TEC_SMOOTHING_DEG, noCols, loTempEnv, ratioHiLoFac ); + + calcLoTempEnv_ns( loBuffer + MAX_TEC_SMOOTHING_DEG, noCols, loTempEnv_ns ); + + loVar_ns = calcVar( loTempEnv_ns, noCols, &loSum_ns ); + diff_hi_lo_sum = loSum_ns - hiSum; + + if ( hiVar > 800 && loVar_ns > 720 && diff_hi_lo_sum < 100 ) + { + code = 1; + } + + *corrFlag = 0; + + assert( code == 0 || code == 1 ); + + if ( code ) + { + /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ + /* ++++ code == 1 +++++*/ + /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ + int16_t maxPosHi, maxPosLo; + float maxHi, maxLo; + + maxHi = hiTempEnv[0]; + maxLo = loTempEnv_ns[0]; + maxPosHi = maxPosLo = 0; + + for ( i = 1; i < noCols; i++ ) + { + if ( maxHi < hiTempEnv[i] ) + { + maxHi = hiTempEnv[i]; + maxPosHi = i; + } + + if ( maxLo < loTempEnv_ns[i] ) + { + maxLo = loTempEnv_ns[i]; + maxPosLo = i; + } + } + + if ( abs( maxPosHi - maxPosLo ) < 2 ) + { + *corrFlag = 2; + } + + { + float feature_max = 0; + int16_t pos_feature_max = 0; + float feature[16]; + + float min_local, max_local; + int16_t j; + int16_t len_window = EXT_DELAY_HI_TEMP_ENV + 1; + float *curr_pos = hiTempEnv; + + feature_max = 0; + pos_feature_max = 0; + + for ( i = 0; i < 16; i++, curr_pos++ ) + { + max_local = min_local = curr_pos[0]; + + for ( j = 1; j < len_window; j++ ) + { + if ( max_local < curr_pos[-j] ) + { + max_local = curr_pos[-j]; + } + + if ( min_local > curr_pos[-j] ) + { + min_local = curr_pos[-j]; + } + } + + feature[i] = max_local - min_local; + + if ( feature_max < feature[i] ) + { + feature_max = feature[i]; + pos_feature_max = i; + } + } + + if ( *corrFlag > 0 ) + { + if ( !( feature_max > 20 && abs( pos_feature_max - maxPosHi ) < 3 ) ) + { + *corrFlag = 0; + } + } + } + } + else + { + /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ + /* ++++ code == 0 ++++*/ + /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ + + /* calc the variance of loTempEnv */ + loVar = calcVar( loTempEnv, noCols, &loSum ); + + /* calc correlation coefficient between loTempEnv and hiTempEnv */ + corrCoef = calcCorrelationCoefficient2( hiTempEnv, loTempEnv, noCols, hiVar, loVar, hiSum, loSum ); + + ratio_float = hiVar / ( loVar + EPS ); + + if ( corrCoef >= thCorrCoef && ratio_float > thRatio && ratio_float < thRatio2 ) + { + *corrFlag = 1; + } + } + + for ( i = 0; i < MAX_TEC_SMOOTHING_DEG + DELAY_TEMP_ENV_BUFF_TEC; i++ ) + { + loBuffer[i] = loBuffer[noCols + i]; + } + + for ( i = 0; i < DELAY_TEMP_ENV_BUFF_TEC + EXT_DELAY_HI_TEMP_ENV; i++ ) + { + hiTempEnvOrig[i] = hiTempEnvOrig[noCols + i]; + } + + return; +} + + +/*------------------------------------------------------------------- + * tecEnc_TBE() + * + * + *-------------------------------------------------------------------*/ + +void tecEnc_TBE( + int16_t *corrFlag, + const float *voicing, + const int16_t coder_type ) +{ + float voice_sum; + float voice_diff; + + /*-----------------------------------------------------------------* + * TEC updates + *-----------------------------------------------------------------*/ + + voice_sum = voicing[0] + voicing[1]; + voice_diff = voicing[0] - voicing[1]; + + if ( voice_diff < 0 ) + { + voice_diff *= -1.0f; + } + + if ( *corrFlag == 1 ) + { + if ( coder_type == INACTIVE || ( ( voice_sum > 0.35 * 2 && voice_sum < 0.55 * 2 ) && ( voice_diff < 0.2 ) ) ) + { + *corrFlag = 0; + } + } + if ( voice_sum > 0.6 * 2 ) + { + *corrFlag = 0; + } + + return; +} diff --git a/lib_com/tns_base.c b/lib_com/tns_base.c index 13aea5208b2ba0177ed8c361234077b7fab378e9..e9acf6af42e6122b5a5fb63f60b842c8c1489c64 100644 --- a/lib_com/tns_base.c +++ b/lib_com/tns_base.c @@ -514,7 +514,7 @@ static Word16 DecodeUsingTable(Decoder_State *st, Word16 * pValue, const Coding WHILE (valueIndex == nSize) { - code = add(shl(code,1), get_next_indice_fx(st, 1)); + code = add(shl(code,1), get_next_indice(st, 1)); nBits = add(nBits,1); if (nBits > nSize || nBits > 16) { diff --git a/lib_com/tools_fx.c b/lib_com/tools_fx.c index c2355b1a3a9b28e77510d326396097727caf2ce6..3464943fa85b1298db1c2eff316a5dfa0748f1d8 100644 --- a/lib_com/tools_fx.c +++ b/lib_com/tools_fx.c @@ -609,7 +609,7 @@ Word16 mean_fx( /* o : mean of vector */ ) { Word16 tmp; - printf("TBV : this function could be written differently to minimize the risk of saturation"); + //PMT("TBV : this function could be written differently to minimize the risk of saturation"); tmp = sum16_fx(vec_fx,lvec_fx); tmp = mult_r(tmp,div_s(1,lvec_fx)); diff --git a/lib_com/trans_direct_fx.c b/lib_com/trans_direct_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..c4962a81332d56c3fe9b55808512b59a316b6a35 --- /dev/null +++ b/lib_com/trans_direct_fx.c @@ -0,0 +1,210 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ +#include +#include "options.h" /* Compilation switches */ +#include "cnst.h" /* Common FX constants */ +#include "prot_fx1.h" /* Function prototypes */ +#include "prot_fx2.h" /* Function prototypes */ +#include "rom_com.h" /* Function prototypes */ + +/*------------------------------------------------------------------- + * direct_transform() + * + * Transformation of the signal to DCT domain + *-------------------------------------------------------------------*/ + void direct_transform_fx( + const Word32 in32_fx[], /* i : input signal */ + Word32 out32_fx[], /* o : transformation */ + const Word16 is_transient, /* i : is transient */ + const Word16 L, /* i : length */ + Word16 *Q, + const Word16 element_mode /* i : IVAS element mode */ +) +{ + + Word16 i, k; + Word16 seg; + Word16 segment_length, segment_length2, segment_length4; + + const Word16 *wh_fx; + const Word16 *wl_fx; + const Word32 *sh_fx; + const Word32 *sl_fx2; + Word32 *sl_fx; + Word32 *iseg_fx; + Word32 *oseg_fx; + Word32 dctin32_fx[L_FRAME48k]; + Word32 in32_r16_fx[L_FRAME48k]; + + const Word16 *win_fx; + Word16 shift, Qmin = 31; + Word32 L_tmp; + Word16 Qs[NUM_TIME_SWITCHING_BLOCKS]; +#ifdef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING + (void)(element_mode); +#endif + + segment_length = shr(L, 1); + segment_length2 = shr(segment_length, 1); + segment_length4 = shr(segment_length2, 1); + + IF (is_transient) + { + IF (EQ_16(L, L_FRAME48k)) + { + win_fx = wscw16q15_fx; + } + ELSE IF (EQ_16(L, L_FRAME32k)) + { + win_fx = wscw16q15_32_fx; + } + ELSE IF (EQ_16(L, L_FRAME8k)) + { + win_fx = wscw16q15_8_fx; + } + ELSE + { + win_fx = wscw16q15_16_fx; + } + + sh_fx = &in32_fx[L-1]; + add(0,0); + sl_fx = &in32_r16_fx[L-1]; + add(0,0); + FOR (i = 0; i < segment_length; i++) + { + in32_r16_fx[i] = (*sh_fx--); + move32(); + (*sl_fx--) = in32_fx[i]; + move32(); + } + + iseg_fx = &in32_r16_fx[-segment_length4]; + add(0,0); + oseg_fx = out32_fx; + + wh_fx = &win_fx[segment_length4]; + add(0,0); + wl_fx = wh_fx - 1; + + shift = extract_l(L_mult0(3, segment_length4)); + sh_fx = &iseg_fx[shift]; + add(0,0); + sl_fx2 = sh_fx - 1; + + + FOR (i = 0; i < segment_length4; i++) + { + L_tmp = L_negate(Mult_32_16( (*sh_fx++), (*wh_fx++) )); /*Q+15-15=Q */ + dctin32_fx[i] = Madd_32_16(L_tmp, *sl_fx2--, *wl_fx-- ); + move32();/*Q */ + } + + sl_fx2 = &iseg_fx[segment_length2 - 1]; + add(0,0); + + FOR (i = segment_length4; i < segment_length2; i++) + { + dctin32_fx[i] = L_negate(*sl_fx2--); + move32(); + } + + Qs[0] = *Q; + move16(); + edct_fx(dctin32_fx, oseg_fx, segment_length2, &Qs[0]); + Qmin = s_min(Qs[0], Qmin); + + iseg_fx += segment_length2; + add(0,0); + oseg_fx += segment_length2; + add(0,0); + + FOR (seg = 1 ; seg < NUM_TIME_SWITCHING_BLOCKS-1; seg++) + { + wh_fx = &win_fx[segment_length4]; + add(0,0); + wl_fx = wh_fx - 1; + sh_fx = &iseg_fx[shift]; + add(0,0); + sl_fx2 = sh_fx - 1; + FOR (i = 0; i < segment_length4; i++) + { + L_tmp = L_negate(Mult_32_16( (*sh_fx++), (*wh_fx++) )); /*Q+15-15=Q */ + dctin32_fx[i] = Madd_32_16(L_tmp, *sl_fx2--, *wl_fx-- ); + move32(); /*Q */ + } + + sh_fx = iseg_fx; + sl_fx2 = &iseg_fx[segment_length2 - 1]; + add(0,0); + wh_fx = &win_fx[segment_length2 - 1]; + add(0,0); + wl_fx = win_fx ; + + FOR (i = segment_length4; i < segment_length2; i++) + { + L_tmp = Mult_32_16( (*sh_fx++), (*wh_fx--) ); /*Q+15-15=Q */ + dctin32_fx[i] = Madd_32_16(L_tmp, *sl_fx2--, *wl_fx++ ); + move32(); /*Q */ + } + + Qs[seg] = *Q; + move16(); + edct_fx(dctin32_fx, oseg_fx, segment_length2, &Qs[seg]); + Qmin = s_min(Qs[seg], Qmin); + + iseg_fx += segment_length2; + add(0,0); + oseg_fx += segment_length2; + add(0,0); + } + + sh_fx = &iseg_fx[shift - 1]; + add(0,0); + FOR (i = 0; i < segment_length4; i++) + { + dctin32_fx[i] = L_negate(*sh_fx--); + move32(); + } + + + sh_fx = iseg_fx; + sl_fx2 = &iseg_fx[segment_length2 - 1]; + add(0,0); + wh_fx = &win_fx[segment_length2 - 1]; + add(0,0); + wl_fx = win_fx; + + FOR (i = segment_length4; i < segment_length2; i++) + { + L_tmp = Mult_32_16( (*sl_fx2--), (*wl_fx++) ); /*Q+15-15=Q */ + dctin32_fx[i] = Madd_32_16(L_tmp, *sh_fx++, *wh_fx-- ); + move32(); /*Q */ + } + Qs[NUM_TIME_SWITCHING_BLOCKS-1] = *Q; + move16(); + edct_fx(dctin32_fx, oseg_fx, segment_length2, &Qs[NUM_TIME_SWITCHING_BLOCKS-1]); + Qmin = s_min(Qs[NUM_TIME_SWITCHING_BLOCKS-1], Qmin); + + *Q = Qmin; + move16(); + oseg_fx = out32_fx; + FOR ( k=0; k +#include "options.h" /* Compilation switches */ +#include "prot_fx1.h" /* Function prototypes */ +#include "prot_fx2.h" /* Function prototypes */ +#include "rom_com.h" /* Function prototypes */ +#include "rom_dec.h" + + + +/*--------------------------------------------------------------------------* + * Local constants + *--------------------------------------------------------------------------*/ + +#define NUMSF 8 +#define NUMSF_M1 (NUMSF-1) +#define NUMSF_M2 (NUMSF-2) +#define NUMSF_S2 (NUMSF/2) +#define LOG2_NUMSF 3 +#define INV_NUMSF (float)0.125 + +/*--------------------------------------------------------------------------* + * preecho_sb() + * + * Time-domain sub-band based pre-echo reduction + *--------------------------------------------------------------------------*/ + +void preecho_sb_fx( + const Word32 core_brate, /* i Q0 : core bit-rate */ + Word32 *wtda_audio_fx, /* i q_sig32 : imdct signal, used to compute imdct_mem_fx when not 24400 bps */ + Word16 q_sig32, /* i Q value for wtda_audio_fx */ + Word16 *rec_sig_fx, /* i q_sig16 : reconstructed signal, output of the imdct transform */ + Word16 q_sig16, /* i Q value for rec_sig_fx and imdct_mem_fx */ + const Word16 framelength, /* i Q0 : frame length */ + Word16 *memfilt_lb_fx, /* i/o Q0 : memory */ + Word32 *mean_prev_hb_fx, /* i/o Q0 : memory */ + Word16 *smoothmem_fx, /* i/o Q15 : memory */ + Word32 *mean_prev_fx, /* i/o Q0 : memory */ + Word32 *mean_prev_nc_fx, /* i/o Q0 : memory */ + Word16 *wmold_hb_fx, /* i/o Q15 : memory */ + Word16 *prevflag, /* i/o Q0 : flag */ + Word16 *pastpre, /* i/o Q0 : flag */ + const Word16 bwidth /* i Q0 : bandwidth */ +) +{ + Word16 i, j, len3xLp20; + Word16 zcr[9]; /* 0..3 (0..7): zero crossing of the 4 (8) subframes, 4..5: (8..10) zero crossing of the future subframes */ + Word16 maxnzcr[8], cntnzcr; /* max number of samples without zero crossing */ + + Word16 maxind, stind, stind_hb, cnt2, cnt5, adv, advmem; + Word16 ind2, ind3, ind4, ind5, ind6, pluslim, ind2_m1, ind2_sfl, numsf_ind2; + Word16 subframelength, subsubframelength; + Word16 *ptr_fx, *fxptr1, *fxptr2, *fxptr3, *fxptr4, *fxptr5, *fxptr6/*, *fxptr7, *fxptr8*/; + Word32 *fx32ptr1, *fx32ptr4, *fx32ptr5, *fx32ptr6; + Word16 *sptr1, *sptr2, sptr1_loc, sptr2_loc; + Word16 framelength_m1; + Word16 limzcr, limmaxnzcr; + Word16 num_subsubframes, log2_num_subsubframes; + Word16 nb_flag, smooth_len; + Word16 firstnzcr; + Word16 invsmoothlenp1_fx; + Word16 subframelength_s2, subframelength_s34; + Word16 tmp_fx1, tmp_fx2, tmp_fx3; + Word32 tmp_fxL1, tmp_fxL2, tmp_fxL3; + Word32 es_mdct_fx[9]; /* 0..3 (0..7): energy of the 4 (8) subframes, 4..5: (8..10) energy of the future subframes */ + Word32 es_mdct_hb_fx[9]; /* 0..3 (0..7): energy of the 4 (8) subframes, 4..5: (8..10) energy of the future subframes */ + Word32 es_mdct_half_fx[9]; + Word32 es_mdct_quart_fx[9]; + Word32 savehalfe_fx, last2_fx, maxcrit_fx, sum_plus_es_fx, mean_plus_es_fx[65]; + Word32 savehalfe_hb_fx, last2_hb_fx; + Word32 plus_es_mdct_fx[64], max_es_fx, max_es_hb_fx, max_plus_es_mdct_fx; + Word16 imdct_mem_fx[L_FRAME48k]; /* memory of the imdct transform, used in the next frame */ + Word16 rec_sig_lb_fx[L_FRAME48k], rec_sig_hb_fx[L_FRAME48k]; /* 960 max frame length at 48 kHz */ + + Word16 min_g_fx[13], g_fx, gt_fx[13]; + Word16 min_g_hb_fx[13], gt_hb_fx[13]; + Word16 preechogain_fx[L_FRAME48k +PREECHO_SMOOTH_LEN]; + Word16 preechogain_hb_fx[L_FRAME48k]; + Word16 pre_g_ch_tab[9]; + Word32 eshbmean2_fx, eshbmean3_fx, sxyhb2_fx, sxylb3_fx; + Word16 wmold_fx; + Word16 lim16_fx, lim32_fx; + Word16 fattnext_fx; + Word16 oldgain_fx, oldgain_hb_fx; + UWord16 tmp_u16; + Word32 mean_prev_hb_fx_loc, mean_prev_nc_fx_loc, mean_prev_fx_loc; /* */ + Word16 q16p1, qmemp1, qtmp; + + + q16p1 = add(q_sig16, 1); + qmemp1 = q16p1; + + IF(LE_32(core_brate, HQ_32k)) + { + + mean_prev_fx_loc = L_add(*mean_prev_fx, 0); +#ifdef BASOP_NOGLOB + mean_prev_hb_fx_loc = L_shl_sat(*mean_prev_hb_fx, shl(q_sig16, 1)); /*Q0 to q_sig16*/ +#else + mean_prev_hb_fx_loc = L_shl(*mean_prev_hb_fx, shl(q_sig16,1)); /*Q0 to q_sig16*/ +#endif + mean_prev_nc_fx_loc = L_add(*mean_prev_nc_fx, 0); + framelength_m1 = sub(framelength, 1); + nb_flag = 0; + move16(); + if( EQ_16(bwidth, NB)) + { + nb_flag = 1; + move16(); + } + limzcr = 16; + move16(); + smooth_len = 4; + move16(); + invsmoothlenp1_fx = 6554; + move16(); + IF( EQ_16(nb_flag, 1)) + { + limzcr = 10; + move16(); + smooth_len = PREECHO_SMOOTH_LEN; + move16(); + invsmoothlenp1_fx = INV_PREECHO_SMOOTH_LENP1_FX; + move16(); + } + + limmaxnzcr = mult(framelength, 1365); /*1/24*/ + num_subsubframes = 8; + move16(); + log2_num_subsubframes = 3; + move16(); + + IF( EQ_16(framelength, L_FRAME8k)) + { + num_subsubframes = 4; + move16(); + log2_num_subsubframes = 2; + move16(); + } + + len3xLp20 = mult_r(framelength, 7168); /*7*framelength/32;*/ + /* len3xLp20 = framelength/2-(short)((float)framelength*N_ZERO_MDCT/FRAME_SIZE_MS); in float*/ + + fxptr1 = imdct_mem_fx; + fx32ptr1 = wtda_audio_fx + len3xLp20 - 1; + FOR( i = 0; i < len3xLp20; i++ ) + { + *fxptr1++ = negate(extract_h(L_shl(*fx32ptr1--,15-q_sig32))); + move16(); /*convert to Word16 Q-1 with saturation (saturation not a problem here) */ + } + FOR( i = 0; i < L_shr(framelength, 1); i++ ) + { + *fxptr1++ = negate(extract_h(L_shl(wtda_audio_fx[i], 15-q_sig32))); + move16(); /*convert to Word16 Q-1 with saturation (saturation not a problem here) */ + } + qmemp1 = 0; /*already in q-1*/ + + subframelength = shr(framelength, LOG2_NUMSF); + subsubframelength = shr(subframelength, log2_num_subsubframes); + wmold_fx = *smoothmem_fx; + move16(); + subframelength_s2 = shr(subframelength, 1); + subframelength_s34 = mult(subframelength, 24576); + + cntnzcr = -1; + move16(); + + lim16_fx = 3277; + move16(); + lim32_fx = 328; + move16(); + savehalfe_fx = L_deposit_l(0); + savehalfe_hb_fx = L_deposit_l(0); + + IF( *pastpre == 0 ) + { + /* if past frame mean energies are not known (no preecho_sb in the past frame), limit max attenuation to 1*/ + lim16_fx = 32767; + move16(); + lim32_fx = 32767; + move16(); + } + + *pastpre = 2; + move16(); + fxptr1 = rec_sig_lb_fx; /*q_sig16*/ + fxptr2 = rec_sig_fx; + fxptr3 = rec_sig_fx + 1; + fxptr4 = rec_sig_fx + 2; + +#ifdef BASOP_NOGLOB + tmp_fxL1 = L_mult(shl_sat(*memfilt_lb_fx, q_sig16), 8192); /* *memfilt_lb_fx in q0 */ +#else + tmp_fxL1 = L_mult(shl(*memfilt_lb_fx, q_sig16), 8192); /* *memfilt_lb_fx in q0 */ +#endif + tmp_fxL1 = L_mac(tmp_fxL1, *fxptr3, 8192); + *fxptr1 = mac_r(tmp_fxL1, *fxptr2, 16384); + move16(); + fxptr1++; + + FOR(j = 2; j < framelength; j++) + { + tmp_fxL1 = L_mult(*fxptr2, 8192); + tmp_fxL1 = L_mac(tmp_fxL1, *fxptr4, 8192); + *fxptr1 = mac_r(tmp_fxL1, *fxptr3, 16384); + move16(); + fxptr1++; + fxptr2++; + fxptr3++; + fxptr4++; + } + + tmp_fxL1 = L_mult(*fxptr2, 8192); + *fxptr1 = mac_r(tmp_fxL1, *fxptr3, 16384); + move16(); + fxptr1 = rec_sig_lb_fx; /*q_sig16*/ + fxptr2 = rec_sig_fx; /*q_sig16*/ + fxptr3 = rec_sig_hb_fx; /*q_sig16*/ + + FOR(j = 0; j < framelength; j++) + { + *fxptr3 = sub(*fxptr2, *fxptr1); + move16(); + fxptr1++; + fxptr2++; + fxptr3++; + } + + fxptr2--; +#ifdef BASOP_NOGLOB + *memfilt_lb_fx = shr_sat(*fxptr2, q_sig16); +#else + *memfilt_lb_fx = shr(*fxptr2, q_sig16); +#endif + move16(); /* *memfilt_lb_fx in q0 */ + + /* energy of low bands 8 present and 1 future sub-frames */ + sptr1 = zcr; + sptr1_loc = 0; + move16(); + sptr2 = maxnzcr; + + fxptr2 = rec_sig_fx; + fxptr3 = rec_sig_hb_fx; + fx32ptr1 = es_mdct_fx; + fx32ptr5 = es_mdct_half_fx; + fx32ptr6 = es_mdct_quart_fx; + fx32ptr4 = es_mdct_hb_fx; + firstnzcr = 0; + move16(); + FOR (j = 0; j < NUMSF; j++) /* 8 present subframes */ + { + tmp_fx2 = sub(j, 1); + tmp_fx1 = shr(*fxptr2, q16p1); /*q-1 to avoisd saturation in energy*/ + tmp_fxL1 = L_mac0(25, tmp_fx1, tmp_fx1); + + tmp_fxL2 = L_mac0(100, *fxptr3, *fxptr3); + + sptr2_loc = 0; + move16(); + + fxptr2++; + fxptr3++; + + FOR (i = 1; i < subframelength; i++) + { + if( EQ_16(i, subframelength_s2)) + { + *fx32ptr5 = tmp_fxL1; + move32(); + } + + if( EQ_16(i, subframelength_s34)) + { + *fx32ptr6 = tmp_fxL1; + move32(); + } + tmp_fx1 = shr(*fxptr2, q16p1); /*q-1 to avoisd saturation in energy*/ +#ifdef BASOP_NOGLOB + tmp_fxL1 = L_mac0_sat(tmp_fxL1, tmp_fx1, tmp_fx1); + tmp_fxL2 = L_mac0_sat(tmp_fxL2, *fxptr3, *fxptr3); +#else + tmp_fxL1 = L_mac0(tmp_fxL1, tmp_fx1, tmp_fx1); + tmp_fxL2 = L_mac0(tmp_fxL2, *fxptr3, *fxptr3); +#endif + cntnzcr = add(cntnzcr, 1); + IF( L_mult0(*fxptr2, *(fxptr2-1)) <= 0 ) + { + sptr1_loc = add(sptr1_loc, 1); + sptr2_loc = s_max(sptr2_loc, cntnzcr); + + test(); + if( (firstnzcr > 0) && (GT_16(cntnzcr, maxnzcr[tmp_fx2]))) + { + maxnzcr[tmp_fx2] = cntnzcr; + move16(); + } + + firstnzcr = 0; + move16(); + cntnzcr = -1; + move16(); + } + fxptr2++; + fxptr3++; + } + if(LT_16(j, NUMSF_M1)) + { + cntnzcr = add(cntnzcr, 1); + } + sptr2_loc = s_max(sptr2_loc, cntnzcr); + *fx32ptr4 = tmp_fxL2; + move32(); + fx32ptr4++; + *sptr1 = sptr1_loc; + move16(); + *sptr2 = sptr2_loc; + move16(); + sptr1++; + sptr2++; + + test(); + if( (firstnzcr > 0) && (GT_16(cntnzcr, maxnzcr[tmp_fx2]))) + { + maxnzcr[tmp_fx2] = cntnzcr; + move16(); + } + + sptr1_loc = 0; + move16(); + test(); + firstnzcr = 1; + move16(); + IF((LT_16(j, NUMSF_M1))&&(L_mult0(*fxptr2,*(fxptr2-1))<=0)) /* zcr between 2 subframes */ + { + sptr1_loc = add(sptr1_loc, 1); /* counts for the nexte subframe */ + cntnzcr = -1; + move16(); + firstnzcr = 0; + move16(); + } + + *fx32ptr1 = tmp_fxL1; + move32(); + if( LT_32(*fx32ptr5, L_shr(*fx32ptr1, 1))) + { +#ifdef BASOP_NOGLOB + tmp_fxL1 = L_shl_sat(L_sub_sat(*fx32ptr1, *fx32ptr5),1); +#else + tmp_fxL1 = L_shl(L_sub(*fx32ptr1, *fx32ptr5),1); +#endif + } + *fx32ptr5 = tmp_fxL1; + move32(); + + fx32ptr1++; + fx32ptr5++; + fx32ptr6++; + } + + fxptr2 = imdct_mem_fx; /* q_sig16 or q-1*/ + j = NUMSF; + move16(); /* one future subframe but 96 samples (not 80) (enough with ALDO window) */ + tmp_fx1 = shr(*fxptr2, qmemp1); /* q-1 shr to avoid overflow in es_mdct_fx*/ + tmp_fxL1 = L_mac0(25, tmp_fx1, tmp_fx1); + + sptr1_loc = 0; + move16(); + fxptr2++; + tmp_fx3 = sub(len3xLp20,1); + FOR (i = 1; i < len3xLp20; i++) + { + tmp_fx1 = shr(*fxptr2, qmemp1); /*q-1 to avoisd saturation in energy*/ +#ifdef BASOP_NOGLOB + tmp_fxL1 = L_mac0_sat(tmp_fxL1, tmp_fx1, tmp_fx1); +#else + tmp_fxL1 = L_mac0(tmp_fxL1, tmp_fx1, tmp_fx1); +#endif + if(*fxptr2 **(fxptr2-1) <= 0) + { + sptr1_loc = add(sptr1_loc,1); + } + + fxptr2++; + } + *fx32ptr1 = tmp_fxL1; + move32(); + *sptr1 = sptr1_loc; + fxptr2 = imdct_mem_fx; + fxptr3 = imdct_mem_fx + 1; + fxptr4 = imdct_mem_fx + 2; + tmp_fxL1 = L_mult(rec_sig_fx[framelength_m1], -8192); + tmp_fxL1 = L_mac(tmp_fxL1, *fxptr3, -8192); + tmp_fx1 = mac_r(tmp_fxL1, *fxptr2, 16384); + + tmp_fxL2 = L_deposit_l(100); + tmp_fxL2 = L_mac0(tmp_fxL2, tmp_fx1, tmp_fx1); + + FOR(j = 1; j < tmp_fx3; j++) /* tmp_fx3 still contains subframelength*1.2-1 */ + { + tmp_fxL1 = L_mult(*fxptr2, -8192); +#ifdef BASOP_NOGLOB + tmp_fxL1 = L_mac_sat(tmp_fxL1, *fxptr4, -8192); + tmp_fx1 = mac_r_sat(tmp_fxL1, *fxptr3, 16384); + + tmp_fxL2 = L_mac0_sat(tmp_fxL2, tmp_fx1, tmp_fx1); +#else + tmp_fxL1 = L_mac(tmp_fxL1, *fxptr4, -8192); + tmp_fx1 = mac_r(tmp_fxL1, *fxptr3, 16384); + + tmp_fxL2 = L_mac0(tmp_fxL2, tmp_fx1, tmp_fx1); +#endif + fxptr2++; + fxptr3++; + fxptr4++; + } + + tmp_fxL1 = L_mult(*fxptr2, -8192); +#ifdef BASOP_NOGLOB + tmp_fx1 = mac_r_sat(tmp_fxL1, *fxptr3, 16384); + es_mdct_hb_fx[NUMSF] = L_mac0_sat(tmp_fxL2, tmp_fx1, tmp_fx1); +#else + tmp_fx1 = mac_r(tmp_fxL1, *fxptr3, 16384); + es_mdct_hb_fx[NUMSF] = L_mac0(tmp_fxL2, tmp_fx1, tmp_fx1); +#endif + move32(); + + max_es_hb_fx = L_add(es_mdct_hb_fx[0], 0); /* for memorising the max energy */ + max_es_fx = L_add(es_mdct_fx[0], 0); /* for memorising the max energy */ + maxind = 0; + move16(); + FOR (i = 1; i <= NUMSF; i++) + { + IF (GE_32(es_mdct_hb_fx[i], max_es_hb_fx)) /* '=' to handle the first window*/ + { + max_es_hb_fx = L_add(es_mdct_hb_fx[i], 0); /* max energy low band, 8 present and 1 future subframes */ + } + + IF (GE_32(es_mdct_fx[i], max_es_fx)) /* '=' to handle the first window*/ + { + max_es_fx = L_add(es_mdct_fx[i], 0); /* max energy low band, 8 present and 1 future subframes */ + maxind = i; + move16(); + } + } + + cnt2 = cnt5 = 0; + move16(); + move16(); + test(); + if( *prevflag != 0 || LT_32(max_es_fx, L_mult0(subframelength, 2500))) + { + maxind = 0; + move16(); + } + +#ifdef BASOP_NOGLOB + if( LT_32(max_es_fx, L_shl_sat(mean_prev_fx_loc, 2)))/*OK if saturated*/ +#else + if( LT_32(max_es_fx, L_shl(mean_prev_fx_loc, 2)))/*OK if saturated*/ +#endif + { + maxind = 0; + move16(); + } + *prevflag = 0; + move16(); + + FOR (i = 0; i < maxind; i++) /* only subbands before max energy subband are handled */ + { + g_fx = 32767; + move16(); /* default gain */ + min_g_fx[i] = 32767; + move16(); + min_g_hb_fx[i] = 32767; + move16(); + + Mpy_32_16_ss(es_mdct_half_fx[i], 328, &tmp_fxL1, &tmp_u16); /* 328 for 1/100*/ + Mpy_32_16_ss(es_mdct_half_fx[i], 3277, &tmp_fxL2, &tmp_u16); /* 3277 for 1/10*/ + Mpy_32_16_ss(es_mdct_fx[i], 5461, &tmp_fxL3, &tmp_u16); /* 5461 for 1/6*/ + test(); + test(); + test(); + IF( ( GT_32(tmp_fxL1, L_add(mean_prev_nc_fx_loc,125000)))||/* less then 20% energy in 3/4 of the subframe -> starting onset in the last quarter */ + (( GT_32(tmp_fxL2, L_add(mean_prev_nc_fx_loc,125000))) && + ((LT_16(zcr[i], limzcr))||(LT_32(es_mdct_quart_fx[i],tmp_fxL3))))) /* already an offset, plosif, do not touch */ + { + maxind = i; + move16(); /* no preecho reduction after the first subframe with gain 1 */ + *prevflag = 1; + move16(); + FOR(j = sub(i,1); j >= 0; j--) + { + if (GT_32(es_mdct_fx[j], L_shr(es_mdct_fx[i],1))) + { + maxind = j; + move16(); + } + } + } + ELSE + { + IF (LT_32(es_mdct_fx[i], L_shr(max_es_fx, 4))) + { + g_fx = lim16_fx; + move16(); + cnt5 = add(cnt5,1); + + IF (LT_32(es_mdct_fx[i], L_shr(max_es_fx, 5))) + { + g_fx = lim32_fx; + move16(); + cnt2 = add(cnt2, 1); + } + + IF(LT_32(mean_prev_fx_loc, es_mdct_fx[i])) + { + tmp_fx1 = norm_l(es_mdct_fx[i]); + tmp_fxL1 = L_shl(es_mdct_fx[i], tmp_fx1); + tmp_fxL2 = L_shl(mean_prev_fx_loc, tmp_fx1); + tmp_fx1 = round_fx(tmp_fxL1); + tmp_fx2 = round_fx(tmp_fxL2); + tmp_fx3 = div_s(tmp_fx2, tmp_fx1); + min_g_fx[i] = Frac_sqrt(tmp_fx3); + move16(); + } + + IF(LT_32(mean_prev_hb_fx_loc, es_mdct_hb_fx[i])) + { + tmp_fx1 = norm_l(es_mdct_hb_fx[i]); + tmp_fxL1 = L_shl(es_mdct_hb_fx[i], tmp_fx1); + tmp_fxL2 = L_shl(mean_prev_hb_fx_loc, tmp_fx1); + tmp_fx1 = round_fx(tmp_fxL1); + tmp_fx2 = round_fx(tmp_fxL2); + tmp_fx3 = div_s(tmp_fx2, tmp_fx1); + min_g_hb_fx[i] = Frac_sqrt(tmp_fx3); + move16(); + } + test(); + IF( (LT_16(zcr[i], limzcr/2))||(GT_16(maxnzcr[i],limmaxnzcr))) + { + if(LT_16(min_g_fx[i], 32767)) /* *mean_prev < es_mdct[i]) */ + { + mean_prev_fx_loc = L_add(es_mdct_fx[i], 0); + } + min_g_fx[i] = 32767; + move16(); /* not noise-like, do not touch the amplitude, but may do in HB*/ + } + } + ELSE + { + test(); + if( i > 0 && LT_16(maxind, NUMSF)) + { + *prevflag = 1; + move16(); + } + maxind = i; + move16(); /* no preecho reduction after the first subframe with gain 1*/ + } + } + gt_fx[i] = g_fx; + move16(); + gt_hb_fx[i] = g_fx; + move16(); + } + + FOR ( i = maxind; i <= NUMSF; i++ ) /* also for the first memory subframe */ + { + gt_fx[i] = 32767; + move16(); + min_g_fx[i] = 32767; + move16(); + gt_hb_fx[i] = 32767; + move16(); + min_g_hb_fx[i] = 32767; + move16(); + + } + + ind2 = 0; + move16(); + FOR( i = 0; i < NUMSF; i++ ) + { + if( LT_16(gt_fx[i], 32767)) /*gt not yet limited by min_g*/ + { + ind2 = add(i, 1); /* first subframe with gain = 1 after last gain < 1 --> frame with the attack*/ + } + } + + test(); + if( (GT_16(wmold_fx, 16384))&&(LT_16(add(cnt2,cnt5),2))) /* mini either 1 cnt2 (and so also cnt5) or 2 cnt5 */ + { + /* maxind = 0; false alarm, no echo reduction */ + ind2 = 0; + move16(); + } + ind2_m1 = sub(ind2, 1); + ind2_sfl = i_mult(subframelength,ind2); + numsf_ind2 = sub(NUMSF, ind2); + fxptr3 = gt_fx; + fxptr4 = gt_hb_fx; + fxptr5 = min_g_fx; + fxptr6 = min_g_hb_fx; + + fxptr1 = preechogain_fx + smooth_len; + pre_g_ch_tab[0] = smooth_len; + move16(); /*1st after smoothmem*/ + fxptr2 = preechogain_hb_fx; + FOR (i = 0; i < ind2; i++) /* only subbands before max energy subband are handled*/ + { + *fxptr3 = s_max(*fxptr3, *fxptr5); + move16(); + + *fxptr4 = s_max(*fxptr4, *fxptr6); + move16(); + + FOR(j = 0; j < subframelength; j++) + { + *fxptr1 = *fxptr3; + move16(); + *fxptr2 = *fxptr4; + move16(); + fxptr1++; + fxptr2++; + } + pre_g_ch_tab[add(i, 1)] = add(pre_g_ch_tab[i], subframelength); + fxptr3++; + fxptr4++; + fxptr5++; + fxptr6++; + } + + max_plus_es_mdct_fx = L_deposit_l(0); + adv = smooth_len; + move16(); /* samples needed to have near 1 gain after smoothing at the beggining of the attack subframe*/ + advmem = adv; + move16(); + + test(); + test(); + IF( ind2 > 0 || LT_16(wmold_fx, 32767)||LT_16(*wmold_hb_fx,32767)) + { + ptr_fx = imdct_mem_fx; + qtmp = qmemp1; + pluslim = num_subsubframes; + move16(); /* if ind2 == NUMSF */ + IF( numsf_ind2 > 0 ) + { + ptr_fx = rec_sig_fx + ind2_sfl; + qtmp = q16p1; + pluslim = i_mult(numsf_ind2, num_subsubframes); + } + + maxcrit_fx = L_add(mean_prev_nc_fx_loc, 0); + IF( ind2 == 0 ) + { + sum_plus_es_fx = L_add(mean_prev_nc_fx_loc, 0); /* 8 times mean sususb enenrgy (=maxcrit)*/ + pluslim = num_subsubframes; + move16(); + oldgain_fx = wmold_fx; + move16(); + oldgain_hb_fx = *wmold_hb_fx; + move16(); + } + ELSE /* ind2 > 0*/ + { + sum_plus_es_fx = es_mdct_fx[ind2_m1]; + move32(); /* 8 times mean sususb enenrgy (=maxcrit)*/ + oldgain_fx = gt_fx[ind2_m1]; + move16(); + oldgain_hb_fx = gt_hb_fx[ind2_m1]; + move16(); + + tmp_fx1 = mult_r(gt_fx[ind2_m1], gt_fx[ind2_m1]); + Mpy_32_16_ss(es_mdct_fx[ind2_m1], tmp_fx1, &maxcrit_fx, &tmp_u16); + Mpy_32_16_ss(max_es_fx, 410, &tmp_fxL1, &tmp_u16); /* 410 for 1/80*/ + + test(); + if( (GT_32(tmp_fxL1, maxcrit_fx))&&(GT_16(zcr[ind2],limzcr))) + { + maxcrit_fx = L_add(tmp_fxL1, 0); /* still 10 times smaller then mean max_es*/ + } + } + fx32ptr1 = plus_es_mdct_fx; + fx32ptr4 = mean_plus_es_fx + 1; + FOR (j = 0; j < pluslim; j++) /* 8 sub-subframes */ + { + tmp_fxL1 = 100; + move16(); + FOR (i = 0; i < subsubframelength; i++) + { + + tmp_fx1 = shr(*ptr_fx, qtmp); /* q-1, to have same shift as es_mdct_.. */ + tmp_fxL1 = L_mac0(tmp_fxL1, tmp_fx1, tmp_fx1); + ptr_fx++; + } + if( GT_32(tmp_fxL1, max_plus_es_mdct_fx)) + { + max_plus_es_mdct_fx = L_add(tmp_fxL1, 0); + } + +#ifdef BASOP_NOGLOB + sum_plus_es_fx = L_add_sat(sum_plus_es_fx, L_shl_sat(tmp_fxL1, 2)); +#else + sum_plus_es_fx = L_add(sum_plus_es_fx, L_shl(tmp_fxL1, 2)); +#endif + *fx32ptr1 = tmp_fxL1; + fx32ptr1++; + Mpy_32_16_ss(sum_plus_es_fx, inv_jp2[j], fx32ptr4, &tmp_u16); /* 410 for 1/80*/ + if( LT_32(*fx32ptr4, maxcrit_fx)) + { + *fx32ptr4 = maxcrit_fx; + move32(); + } + fx32ptr4++; + } + *fx32ptr4 = -1; + move32(); /*mean_plus_es_fx[pluslim] = -1; */ + *mean_plus_es_fx = *plus_es_mdct_fx; + move32(); /* index [0] */ + if( LT_32(*mean_plus_es_fx, maxcrit_fx)) + { + *mean_plus_es_fx = maxcrit_fx; + move32(); + } + + j = 0; + move16(); + WHILE((LT_32(plus_es_mdct_fx[j], mean_plus_es_fx[j]))&&(LT_32(plus_es_mdct_fx[j],max_plus_es_mdct_fx/8))) + { + test(); + j = add(j,1); + } + tmp_fx3 = i_mult(j,subsubframelength); + adv = sub(adv, tmp_fx3); + IF( numsf_ind2 > 0 ) /* onset not in future frame */ + { + fxptr1 = preechogain_fx + ind2_sfl+smooth_len; + fxptr2 = preechogain_hb_fx + ind2_sfl; + + FOR (i = 0; i < tmp_fx3; i++) + { + *fxptr1 = oldgain_fx; + move16(); /*keep the gain of the previous subframe*/ + *fxptr2 = oldgain_hb_fx; + move16(); /*keep the gain of the previous subframe*/ + fxptr1++; + fxptr2++; + } + } + } + + IF(ind2>0) + { + /* check increasing energy of preecho by regression last 3 subframes (if possible) */ + ind3 = add(ind2, shr(j, log2_num_subsubframes)); /* return (with rounding) to subframe basis */ + ind4 = sub(ind3, 1); + ind5 = sub(ind3, 2); + ind6 = sub(ind3, 3); + IF( ind4 > 0 ) + { + /* case of 3 points is simply */ + eshbmean2_fx = L_add(es_mdct_hb_fx[ind4], es_mdct_hb_fx[ind5]); + + sxyhb2_fx = L_sub(es_mdct_hb_fx[ind4], es_mdct_hb_fx[ind5]); /* / eshbmean2 * 2; 04042013: division not needed, only sign of sxyhb2 is used*/ + + IF( GT_16(ind3, 2)) + { + tmp_fxL1 = L_add(eshbmean2_fx, es_mdct_hb_fx[ind6]); + Mpy_32_16_ss(tmp_fxL1, 4369, &eshbmean3_fx, &tmp_u16); /*10922 : 1/3*/ + sxylb3_fx = L_sub(es_mdct_fx[ind4], es_mdct_fx[ind6]); /* /eslbmean3 / 2; /2 for 3 points regression calc; 04042013: division not needed, only sign of sxylb3 is used*/ + tmp_fxL1 = L_sub(es_mdct_hb_fx[ind4], es_mdct_hb_fx[ind6]); + test(); + IF ((LT_32(tmp_fxL1, eshbmean3_fx))||(sxylb3_fx<0)) + { + ind2 = 0; + move16(); + ind2_sfl = 0; + move16(); + adv = advmem; + move16(); + } + } + ELSE + { + IF (sxyhb2_fx < 0) + { + ind2 = 0; + move16(); + ind2_sfl = 0; + move16(); + adv = advmem; + move16();/* 04042013: small bug corection*/ + } + } + + tmp_fxL1 = L_add(eshbmean2_fx, es_mdct_hb_fx[ind3]); + Mpy_32_16_ss(tmp_fxL1, 4369, &eshbmean3_fx, &tmp_u16); /*10922 : 1/3*/ + + tmp_fxL1 = L_sub(es_mdct_hb_fx[ind3], es_mdct_hb_fx[ind5]); + IF (LT_32(tmp_fxL1, eshbmean3_fx)) + { + ind2 = 0; + move16(); + ind2_sfl = 0; + move16(); + adv = advmem; + move16(); + } + } + } + + ind2_m1 = sub(ind2, 1);/*ind2_m1 needs to be recomputed as ind2 could have changed since*/ + + stind = sub(ind2_sfl, adv); + stind_hb = add(stind, advmem); + if( stind < 0 ) + { + stind = 0; + move16(); + } + + if( stind_hb < 0 ) + { + stind_hb = 0; + move16(); + } + + tmp_fx1 = add(stind, smooth_len); + fxptr1 = preechogain_fx + tmp_fx1; + fxptr2 = preechogain_hb_fx + stind_hb; + + FOR (i = tmp_fx1; i < framelength; i++) /* rest of the gains, without 4 (PREECHO_SMOOTH_LEN) 1 for fadeout */ + { + *(fxptr1++) = 32767; + move16(); + } + pre_g_ch_tab[ind2] = s_min(tmp_fx1, framelength); + move16(); + + FOR (i = stind_hb; i < framelength; i++) /* rest of the gains*/ + { + *(fxptr2++) = 32767; + move16(); + } + + fxptr1 = preechogain_fx; + FOR (i = 0; i < smooth_len; i++) + { + *(fxptr1++) = *smoothmem_fx; + move16(); + } + + fattnext_fx = 32767; + move16(); + if( GT_16(stind, framelength)) + { + fattnext_fx = gt_fx[ind2_m1]; + move16(); + } + + fxptr1 = preechogain_fx + framelength; + FOR (i = 0; i < smooth_len; i++) + { + *(fxptr1++) = fattnext_fx; + move16(); + } + + FOR (i = 0; i <= ind2; i++) + { + tmp_fx1 = pre_g_ch_tab[i]; + move16(); + tmp_fx2 = sub(tmp_fx1, smooth_len); /* any index in the previous subframe*/ + tmp_fx3 = mult_r(sub(preechogain_fx[tmp_fx1], preechogain_fx[tmp_fx2]), invsmoothlenp1_fx);/*step*/ + tmp_fx1 = tmp_fx3; + move16(); /*cumulated step*/ + fxptr1 = preechogain_fx + tmp_fx2; + FOR(j = 0; j < smooth_len; j++) + { +#ifdef BASOP_NOGLOB + *fxptr1 = add_sat(*fxptr1, tmp_fx1); +#else + *fxptr1 = add(*fxptr1, tmp_fx1); +#endif + move16(); + tmp_fx1 = add(tmp_fx1, tmp_fx3); + fxptr1++; + } + } + + *smoothmem_fx = fattnext_fx; + move16(); + *wmold_hb_fx = preechogain_hb_fx[framelength_m1]; + move16(); + + /* apply gain */ + fxptr1 = preechogain_fx; + fxptr2 = preechogain_hb_fx; + fxptr3 = rec_sig_fx; + fxptr4 = rec_sig_lb_fx; + fxptr5 = rec_sig_hb_fx; + FOR (i = 0; i < framelength; i++) + { + tmp_fxL1 = L_mult(*fxptr4, *fxptr1); + *fxptr3 = mac_r(tmp_fxL1, *fxptr5, *fxptr2); + move16(); + fxptr1++; + fxptr2++; + fxptr3++; + fxptr4++; + fxptr5++; + } + + mean_prev_nc_fx_loc = L_add(es_mdct_fx[0], 0); /* compute mean not corrected by the actual gains*/ + + FOR (i = 1; i < NUMSF; i++) /* all present subbands */ + { + if( EQ_16(i, NUMSF_S2)) + { + savehalfe_fx = L_add(mean_prev_nc_fx_loc, 0); + } +#ifdef BASOP_NOGLOB + mean_prev_nc_fx_loc = L_add_sat(mean_prev_nc_fx_loc, es_mdct_fx[i]); +#else + mean_prev_nc_fx_loc = L_add(mean_prev_nc_fx_loc, es_mdct_fx[i]); +#endif + } + + if( LT_32(savehalfe_fx, L_shr(mean_prev_nc_fx_loc,1) )) + { +#ifdef BASOP_NOGLOB + mean_prev_nc_fx_loc = L_shl_sat(L_sub_sat(mean_prev_nc_fx_loc, savehalfe_fx), 1); +#else + mean_prev_nc_fx_loc = L_shl(L_sub(mean_prev_nc_fx_loc, savehalfe_fx), 1); +#endif + } + mean_prev_nc_fx_loc = L_shr(mean_prev_nc_fx_loc, 3); /* >> LOG2_NUMSF in fixpoint */ + + FOR( i = 0; i < ind2; i++ ) /* only subbands before max energy subband are handled*/ + { + tmp_fx1 = mult_r(gt_fx[i], gt_fx[i]); + Mpy_32_16_ss(es_mdct_fx[i], tmp_fx1, &es_mdct_fx[i], &tmp_u16); + + tmp_fx1 = mult_r(gt_hb_fx[i], gt_hb_fx[i]); + Mpy_32_16_ss(es_mdct_hb_fx[i], tmp_fx1, &es_mdct_hb_fx[i], &tmp_u16); + + } + + mean_prev_fx_loc = L_shr(es_mdct_fx[0],3); /* compute mean used in next frame to limit gain*/ + mean_prev_hb_fx_loc = L_shr(es_mdct_hb_fx[0],3); /* compute mean used in next frame to limit gain*/ + + FOR (i = 1; i < NUMSF; i++) /* all present subbands */ + { + IF(EQ_16(i, NUMSF_S2)) + { + savehalfe_fx = L_add(mean_prev_fx_loc, 0); + savehalfe_hb_fx = L_add(mean_prev_hb_fx_loc, 0); + } + + mean_prev_fx_loc = L_add(mean_prev_fx_loc, L_shr(es_mdct_fx[i], 3)); + mean_prev_hb_fx_loc = L_add(mean_prev_hb_fx_loc, L_shr(es_mdct_hb_fx[i], 3)); + } + + tmp_fxL1 = L_sub(mean_prev_fx_loc, savehalfe_fx); + if( LT_32(savehalfe_fx, L_shr(mean_prev_fx_loc, 1) )) + { + mean_prev_fx_loc = L_shl(tmp_fxL1, 1); + } + + tmp_fxL1 = L_sub(mean_prev_hb_fx_loc, savehalfe_hb_fx); + if( LT_32(savehalfe_hb_fx, L_shr(mean_prev_hb_fx_loc, 1) )) + { + mean_prev_hb_fx_loc = L_shl(tmp_fxL1, 1); + } + +#ifdef BASOP_NOGLOB + last2_fx = L_shr(L_add_sat(es_mdct_fx[NUMSF_M1], es_mdct_fx[NUMSF_M2]), 1); + last2_hb_fx = L_shr(L_add_sat(es_mdct_hb_fx[NUMSF_M1], es_mdct_hb_fx[NUMSF_M2]), 1); +#else + last2_fx = L_shr(L_add(es_mdct_fx[NUMSF_M1], es_mdct_fx[NUMSF_M2]), 1); + last2_hb_fx = L_shr(L_add(es_mdct_hb_fx[NUMSF_M1], es_mdct_hb_fx[NUMSF_M2]), 1); +#endif + if( GT_32(last2_fx, mean_prev_fx_loc)) + { + mean_prev_fx_loc = L_add(last2_fx, 0); + } + + if( GT_32(last2_hb_fx, mean_prev_hb_fx_loc)) + { + mean_prev_hb_fx_loc = L_add(last2_hb_fx, 0); + } + *mean_prev_fx = mean_prev_fx_loc; + move32(); +#ifdef BASOP_NOGLOB + *mean_prev_hb_fx = L_shr_sat(mean_prev_hb_fx_loc, shl_sat(q_sig16,1)); +#else + *mean_prev_hb_fx = L_shr(mean_prev_hb_fx_loc, shl(q_sig16,1)); +#endif + move32(); /*save in Q0*/ + *mean_prev_nc_fx = mean_prev_nc_fx_loc; + move32(); + } + + return; +} + +/*--------------------------------------------------------------------------* + * Inverse_Transform() + * + * Inverse transform from the DCT domain to time domain + *--------------------------------------------------------------------------*/ + +void Inverse_Transform( + const Word32 *in_mdct, /* i : input MDCT vector */ + Word16 *Q, /* i/o: Q value of input */ + Word32 *out, /* o : output vector */ + const Word16 is_transient, /* i : transient flag */ + const Word16 L, /* i : output frame length */ + const Word16 L_inner, /* i : length of the transform */ + const Word16 element_mode /* i : IVAS element mode */ +) +{ + Word16 ta, seg, tmp16; + Word16 segment_length; + const Word16 *win, *win2; + Word32 out_alias[L_FRAME48k]; + Word32 alias[MAX_SEGMENT_LENGTH]; + Word32 in_mdct_modif[L_FRAME48k]; + Word32 *in_segment_modif; + const Word32 *in_segment; + Word32 *out_segment; + Word16 segment_length_div2, segment_length_div4; + Word16 tmp, q_out; + Word32 L_temp; +#ifdef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING + (void)(element_mode); +#endif + /* This value is used to right shift all vectors returned by 'iedct_short_fx()' */ + /* to bring them to a scaling that is equal to the 1st 'Q' returned by the 1st */ + /* call to 'iedct_short_fx()' minus these guard bits. */ +#define N_GUARD_BITS (9+1) /* 9 is enough but we put one extra bit */ + + IF (is_transient) + { + segment_length = shr(L, 1); + segment_length_div2 = shr(L, 2); + segment_length_div4 = shr(L, 3); + + IF (EQ_16(L, L_FRAME48k)) + { + win = short_window_48kHz_fx; + } + ELSE IF (EQ_16(L, L_FRAME32k)) + { + win = short_window_32kHz_fx; + } + ELSE IF( EQ_16(L, L_FRAME16k)) + { + win = short_window_16kHz_fx; + } + ELSE /* L == L_FRAME8k */ + { + win = short_window_8kHz_fx; + } + + set32_fx(out_alias, 0, L); + + in_segment = in_mdct; + in_segment_modif = in_mdct_modif; + + tmp16 = sub(L, L_inner); + IF( tmp16 == 0 ) + { + Copy32(in_mdct, in_mdct_modif, L); + } + ELSE IF( tmp16 > 0 ) + { + FOR( seg = 0; seg < NUM_TIME_SWITCHING_BLOCKS; seg++ ) + { + FOR( ta = 0; ta < L_inner; ta += NUM_TIME_SWITCHING_BLOCKS ) + { + *in_segment_modif++ = *in_segment++; + move32(); + } + + FOR( ta = 0; ta < tmp16; ta += NUM_TIME_SWITCHING_BLOCKS ) + { + *in_segment_modif++ = 0L; + move32(); + } + } + } + ELSE /* L < L_inner */ + { + FOR( seg = 0; seg < NUM_TIME_SWITCHING_BLOCKS; seg++ ) + { + FOR( ta = 0; ta < segment_length_div2; ta++ ) + { + *in_segment_modif++ = *in_segment++; + move32(); + } + in_segment += shr(sub(L_inner, L), 2); + move32(); + } + } + + out_segment = out_alias - segment_length_div4; + in_segment = in_mdct_modif; + + tmp = *Q; + /* output of 'iedct_short_fx' has up to 'output frame length'/2 # of Elements */ + iedct_short_fx( in_segment, &tmp, alias, segment_length ); + IF (GT_16(tmp, N_GUARD_BITS)) + { + q_out = sub(tmp, N_GUARD_BITS); + tmp = sub(tmp, q_out); + } + ELSE + { + q_out = 0; + move16(); + } + + FOR( ta = segment_length_div4; ta < segment_length_div2; ta++ ) + { + out_segment[ta] = L_shr(alias[ta], tmp); + move32(); + } + /* This previous loop fills the output buffer from [0..seg_len_div4-1] */ + + win2 = &win[segment_length_div2]; + FOR( ta = segment_length_div2; ta < segment_length; ta++ ) + { + out_segment[ta] = L_shr(Mult_32_16(alias[ta], *--win2), tmp); + move32(); + } + /* This previous loop fills the output buffer from [seg_len_div4..seg_len-seg_len_div4-1] */ + + out_segment += segment_length_div2; + in_segment += segment_length_div2; + + FOR( seg = 1; seg < NUM_TIME_SWITCHING_BLOCKS-1; seg++ ) + { + tmp = *Q; + move16(); + /* output of 'iedct_short_fx' has up to 'output frame length'/2 # of Elements */ + iedct_short_fx( in_segment, &tmp, alias, segment_length ); + tmp = sub(tmp, q_out); + + FOR( ta = 0; ta < segment_length_div2; ta++ ) + { + out_segment[ta] = L_add(out_segment[ta], L_shr(Mult_32_16(alias[ta], *win2++), tmp)); + move32(); + } + FOR( ; ta < segment_length; ta++ ) + { + out_segment[ta] = L_add(out_segment[ta], L_shr(Mult_32_16(alias[ta], *--win2), tmp)); + move32(); + } + + in_segment += segment_length_div2; + out_segment += segment_length_div2; + } + + tmp = *Q; + move16(); + iedct_short_fx( in_segment, &tmp, alias, segment_length ); + tmp = sub(tmp, q_out); + + FOR (ta = 0; ta < segment_length_div2; ta++) + { + out_segment[ta] = L_add(out_segment[ta], L_shr(Mult_32_16(alias[ta], *win2++), tmp)); + move32(); + } + + seg = add(segment_length_div2, shr(segment_length_div2, 1)); /* seg = 3*segment_length/4 */ + FOR (ta = segment_length_div2; ta < seg; ta++) + { + out_segment[ta] = L_shr(alias[ta], tmp); + move32(); + } + + FOR (ta = 0; ta < segment_length; ta++) + { + L_temp = L_add(out_alias[ta], 0); + out[ta] = out_alias[L-1-ta]; + move32(); + out[L-1-ta] = L_temp; + move32(); + } + + *Q = q_out; + move16(); + } + ELSE + { + edct_fx(in_mdct, out, L, Q); + } +} diff --git a/lib_com/typedef.h b/lib_com/typedef.h index 02183e7c53e9099913b099dd65ed3bcce9f57f46..c27c80046f91ee1512d3a80834556f36f063d25d 100644 --- a/lib_com/typedef.h +++ b/lib_com/typedef.h @@ -68,6 +68,7 @@ #include #include +#include #if __STDC_VERSION__ >= 199901L typedef int8_t Word8; @@ -122,7 +123,10 @@ typedef int Flag; #ifdef ENH_64_BIT_OPERATOR #define Word64 long long int #endif /* #ifdef ENH_64_BIT_OPERATOR */ - +#define minWord32 INT_MIN +#define maxWord32 INT_MAX +#define minUWord32 0 +#define maxUWord32 UINT_MAX /* Definition of Word40 was missing 10/06/2013 */ #define Word40 long long diff --git a/lib_com/vlpc_2st_com.c b/lib_com/vlpc_2st_com.c index e180454c3e412fbba0de5970fdc6ae0173705531..4a61b21ba334275e06275a6277547206cf0fdc31 100644 --- a/lib_com/vlpc_2st_com.c +++ b/lib_com/vlpc_2st_com.c @@ -43,12 +43,12 @@ #include "wmc_auto.h" /*------------------------------------------------------------------* - * lsf_weight_2st() + * lsf_weight_2st_flt() * * *------------------------------------------------------------------*/ -void lsf_weight_2st( +void lsf_weight_2st_flt( const float *lsfq, float *w, const int16_t mode, diff --git a/lib_com/vlpc_2st_com_fx.c b/lib_com/vlpc_2st_com_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..81082087c0e87e836b18daaa16749a7d3b34b34a --- /dev/null +++ b/lib_com/vlpc_2st_com_fx.c @@ -0,0 +1,60 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include +#include "options.h" +#include "cnst.h" +#include "prot_fx1.h" +#include "prot_fx2.h" +#include "control.h" +#include "basop_util.h" + + +void lsf_weight_2st( + const Word16 *lsfq, /* input: quantized lsf coefficients (14Q1*1.28) */ + Word16 *w, /* output: weighting function (0Q15*1.28) */ + const Word16 mode /* input: operational mode */ +) +{ + Word16 i; + Word16 d[M+1], weight; + + /* compute lsf distance */ + d[0] = lsfq[0]; + move16(); /*14Q1*1.28*/ + FOR (i=1; i0); */ + + /*w[i] = (weight * sqrt(d[i]*d[i+1])));*/ + + w[i] = mult_r(weight,getSqrtWord32(L_shl(L_mult0(d[i],d[i+1]),6))); + move16(); + } + + + return; +} diff --git a/lib_com/weight_fx.c b/lib_com/weight_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..2bfd71e7de007e00a06ee3a31de0451904b74bea --- /dev/null +++ b/lib_com/weight_fx.c @@ -0,0 +1,363 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include +#include "options.h" /* Compilation switches */ +#include "cnst.h" /* Common constants */ +#include "rom_com.h" /* Static table prototypes */ +#include "prot_fx1.h" /* Function prototypes */ +#include "prot_fx2.h" /* Function prototypes */ + +/*--------------------------------------------------------------------------* + * sfm2mqb_fx() + * + * Map sub-vectors to pbands + *--------------------------------------------------------------------------*/ + +static void sfm2mqb_fx( + Word16 spe[], /* i : sub-vectors */ + Word16 spe2q[], /* o : pbands */ + const Word16 nb_sfm /* i : number of norms */ +) +{ + Word16 tmp, i; + + /* short groups */ + spe2q[0] = add(spe[0], 3); + move16(); + spe2q[1] = add(spe[1], 3); + move16(); + spe2q[2] = add(spe[2], 3); + move16(); + spe2q[3] = add(spe[3], 3); + move16(); + spe2q[4] = add(spe[4], 3); + move16(); + spe2q[5] = add(spe[5], 3); + move16(); + spe2q[6] = add(spe[6], 3); + move16(); + spe2q[7] = add(spe[7], 3); + move16(); + spe2q[8] = add(spe[8], 3); + move16(); + spe2q[9] = add(spe[9], 3); + move16(); + + spe2q[10] = add(shr(add(spe[10], spe[11]),1),4); + move16(); + spe2q[11] = add(shr(add(spe[12], spe[13]),1),4); + move16(); + spe2q[12] = add(shr(add(spe[14], spe[15]),1),4); + move16(); + + spe2q[13] = add(shr(add(spe[16], spe[17]),1),5); + move16(); + spe2q[14] = add(shr(add(spe[18], spe[19]),1),5); + move16(); + + tmp = 0; + move16(); + FOR (i=20; i < 24; i++) + { + tmp = add(tmp,spe[i]); + } + spe2q[15] = add(mult(tmp,8192),6); + move16(); + + tmp = 0; + move16(); + FOR (i=24; i < 27; i++) + { + tmp = add(tmp,spe[i]); + } + spe2q[16] = add(mult(tmp,10923),6); + move16(); + + IF (GT_16(nb_sfm, SFM_N_STA_8k)) + { + tmp = 0; + move16(); + FOR (i=27; i < 30; i++) + { + tmp = add(tmp,spe[i]); + } + spe2q[17] = add(mult(tmp,10923),6); + move16(); + + IF (GT_16(nb_sfm, SFM_N_STA_10k)) + { + tmp = 0; + move16(); + FOR (i=30; i < 35; i++) + { + tmp = add(tmp,spe[i]); + } + spe2q[18] = add(mult(tmp,6553),7); + move16(); + + tmp = 0; + move16(); + FOR (i=35; i < 44; i++) + { + tmp = add(tmp,spe[i]); + } + spe2q[19] = add(mult(tmp,3641),8); + move16(); + } + } + + return; +} + +/*--------------------------------------------------------------------------* + * mqb2sfm_fx() + * + * Map pbands to sub-vectors + *--------------------------------------------------------------------------*/ + +static void mqb2sfm_fx( + Word16 spe2q[], /* i : pbands */ + Word16 spe[], /* o : sub-vectors */ + const Word16 lnb_sfm /* i : number of norms */ +) +{ + Word16 i; + + spe[0] = spe2q[0]; + move16(); + spe[1] = spe2q[1]; + move16(); + spe[2] = spe2q[2]; + move16(); + spe[3] = spe2q[3]; + move16(); + spe[4] = spe2q[4]; + move16(); + spe[5] = spe2q[5]; + move16(); + spe[6] = spe2q[6]; + move16(); + spe[7] = spe2q[7]; + move16(); + spe[8] = spe2q[8]; + move16(); + spe[9] = spe2q[9]; + move16(); + + spe[10] = spe2q[10]; + move16(); + spe[11] = spe2q[10]; + move16(); + + spe[12] = spe2q[11]; + move16(); + spe[13] = spe2q[11]; + move16(); + + spe[14] = spe2q[12]; + move16(); + spe[15] = spe2q[12]; + move16(); + + spe[16] = spe2q[13]; + move16(); + spe[17] = spe2q[13]; + move16(); + + spe[18] = spe2q[14]; + move16(); + spe[19] = spe2q[14]; + move16(); + + FOR (i=20; i < 24; i++) + { + spe[i] = spe2q[15]; + move16(); + } + + FOR (i=24; i < 27; i++) + { + spe[i] = spe2q[16]; + move16(); + } + + IF (GT_16(lnb_sfm, SFM_N_STA_8k)) + { + FOR (i=27; i < 30; i++) + { + spe[i] = spe2q[17]; + move16(); + } + + IF (GT_16(lnb_sfm, SFM_N_STA_10k)) + { + FOR (i=30; i < 35; i++) + { + spe[i] = spe2q[18]; + move16(); + } + + FOR (i=35; i < 44; i++) + { + spe[i] = spe2q[19]; + move16(); + } + } + } + + return; +} + +/*--------------------------------------------------------------------------* + * map_quant_weight_fx() + * + * Calculate the quantization weights + *--------------------------------------------------------------------------*/ + +void map_quant_weight_fx( + const Word16 normqlg2[], /* i : quantized norms */ + Word16 wnorm[], /* o : weighted norm */ + const Word16 is_transient /* i : transient flag */ +) +{ + Word16 sfm; + Word16 tmp16; + Word16 spe2q[NUM_MAP_BANDS]; + Word16 spe[NB_SFM]; + + Word16 spe2q_max; + Word16 spe2q_min; + Word16 norm_max; + Word16 shift; + Word16 sum; + Word16 k; + Word16 lnb_sfm,num_map_bands; + + lnb_sfm = NB_SFM; + move16(); + num_map_bands = NUM_MAP_BANDS; + move16(); + + IF (is_transient != 0) + { + FOR (sfm = 0; sfm < lnb_sfm; sfm+=4) + { + sum = 0; + move16(); + FOR (k=0; k < 4; k++) + { + sum = add(sum,normqlg2[sfm+k]); + } + sum = shr(sum,2); + + FOR (k=0; k < 4; k++) + { + spe[sfm +k] = sum; + move16(); + } + } + } + ELSE + { + FOR (sfm = 0; sfm < lnb_sfm; sfm++) + { + spe[sfm] = normqlg2[sfm]; + move16(); + } + } + + sfm2mqb_fx(spe, spe2q, lnb_sfm); + + FOR (sfm = 0; sfm < num_map_bands; sfm++) + { + spe2q[sfm] = sub(spe2q[sfm],10); + move16(); + } + + /* spectral smoothing */ + FOR (sfm = 1; sfm < num_map_bands; sfm++) + { + tmp16 = sub(spe2q[sfm-1],4); + spe2q[sfm] = s_max(spe2q[sfm], tmp16); + move16(); + } + + FOR (sfm = num_map_bands-2 ; sfm >= 0 ; sfm--) + { + tmp16 = sub(spe2q[sfm+1],8); + spe2q[sfm] = s_max(spe2q[sfm], tmp16); + move16(); + } + + FOR (sfm = 0; sfm < num_map_bands ; sfm++) + { + spe2q[sfm] = s_max(spe2q[sfm], a_map[sfm]); + move16(); + } + + /* Saturate by the Absolute Threshold of Hearing */ + spe2q_max = -32768; + move16(); + spe2q_min = MAX_16; + move16(); + + FOR (sfm = 0; sfm < num_map_bands ; sfm++) + { + spe2q[sfm] = sub(sfm_width[sfm], spe2q[sfm]); + move16(); + spe2q_max = s_max(spe2q[sfm], spe2q_max); + spe2q_min = s_min(spe2q[sfm], spe2q_min); + } + + FOR (sfm = 0; sfm < num_map_bands ; sfm++) + { + spe2q[sfm] = sub(spe2q[sfm], spe2q_min); + move16(); + } + + spe2q_max = sub(spe2q_max, spe2q_min); + + norm_max = norm_s(spe2q_max); + + shift = sub(norm_max,13); + + FOR (sfm = 0; sfm < num_map_bands ; sfm++) + { + spe2q[sfm] = shl(spe2q[sfm],shift); + move16(); + } + + mqb2sfm_fx(spe2q,spe,lnb_sfm); + + IF (is_transient != 0) + { + FOR (sfm = 0; sfm < lnb_sfm; sfm+=4) + { + sum = 0; + move16(); + FOR (k=0; k < 4; k++) + { + sum = add(sum , spe[sfm+k]); + } + sum = shr(sum,2); + FOR (k=0; k < 4; k++) + { + spe[sfm +k] = sum; + move16(); + } + } + } + + /* modify the norms for bit-allocation */ + FOR (sfm = 0; sfm < lnb_sfm ; sfm++) + { + wnorm[sfm] = add(spe[sfm], normqlg2[sfm]); + move16(); + } + + return; +} + + diff --git a/lib_com/window.c b/lib_com/window.c index a54cb7c0771d149e6eb3392a5d4c143f2eaddd30..11337f82afadfb762893a01c02773b56c8b4e442 100644 --- a/lib_com/window.c +++ b/lib_com/window.c @@ -42,12 +42,12 @@ #define WMC_TOOL_SKIP /*------------------------------------------------------------------- - * ham_cos_window() + * ham_cos_window_flt() * * *-------------------------------------------------------------------*/ -void ham_cos_window( +void ham_cos_window_flt( float *fh, const int16_t n1, const int16_t n2 ) diff --git a/lib_com/window_fx.c b/lib_com/window_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..4df9da9cde383482d2f10a47207f5a94451d5b35 --- /dev/null +++ b/lib_com/window_fx.c @@ -0,0 +1,81 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + + +#include +#include "options.h" +#include +#include "basop_util.h" +#include "prot_fx1.h" + +#define PI_HALF_0Q15 51472 /* ~=round(pi/2*2^15) */ +#define PI2_15Q16 0x0006487F /* ~=round(2*PI*2^16) */ +#define PI2_10Q21 13176795 /* ~=round(2*PI*2^21) */ +#define PI2_11Q20 6588397 /* ~=round(2*PI*2^20) */ +#define P54_1Q14 8847 /* ~=round(0.54*2^14) */ +#define P54_0Q15 17695 /* ~=round(0.54*2^15) */ +#define P46_0Q15 15073 /* ~=round(0.46*2^15) */ +#define P92_0Q15 30147 /* ~=round(0.92*2^15) */ +#include "options.h" +#include "rom_basop_util.h" + + +void ham_cos_window( + Word16 *fh, /* o: 0Q15 */ + const Word16 n1, /* i: */ + const Word16 n2 /* i: */ +) +{ + Word16 i; + Word32 cte, cc; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + + + + assert( n1>=102 ); /* if n1 is too low -> overflow in div_l */ + /* cte = PI2/(Float32)(2*n1 - 1); */ + BASOP_SATURATE_WARNING_OFF_EVS + move16(); + cte = L_deposit_l(div_l(PI2_10Q21,sub(shl(n1,1),1))); /*0Q15*/ + BASOP_SATURATE_WARNING_ON_EVS + cc = 0; + FOR (i = 0; i < n1; i++) + { + /* fh_f[i] = 0.54f - 0.46f * (Float32)cos(cc); */ + BASOP_SATURATE_WARNING_OFF_EVS +#ifdef BASOP_NOGLOB + fh[i] = sub_o(P54_0Q15, mult_r(getCosWord16(round_fx_o(L_shl_o(cc,9, &Overflow), &Overflow)),P92_0Q15), &Overflow); /*0Q15*/ move16(); +#else + fh[i] = sub(P54_0Q15, mult_r(getCosWord16(round_fx(L_shl(cc,9))),P92_0Q15)); /*0Q15*/ move16(); +#endif + BASOP_SATURATE_WARNING_ON_EVS + cc = L_add(cc, cte); /*0Q15*/ + } + + assert( n2>=26 ); /* if n2 is too low -> overflow in div_l */ + /* cte = PI2/(Float32)(4*n2 - 1); */ + cte = L_deposit_l(div_l(PI2_11Q20,sub(shl(n2,2),1))); /*0Q15*/ + cc = 0; + move16(); + + add(n1,n2); + BASOP_SATURATE_WARNING_OFF_EVS + FOR (i = n1; i < n1+n2; i++) + { + /* fh_f[i] = (Float32)cos(cc); */ +#ifdef BASOP_NOGLOB + fh[i] = shl_o(getCosWord16(round_fx(L_shl(cc, 10))), 1, &Overflow); /*0Q15*/ move16(); +#else + fh[i] = shl(getCosWord16(round_fx(L_shl(cc,10))),1); /*0Q15*/ move16(); +#endif + cc = L_add(cc, cte); + } + BASOP_SATURATE_WARNING_ON_EVS + + + return; +} + diff --git a/lib_debug/sba_debug.c b/lib_debug/sba_debug.c index de4b549aacb5150c0010871700add2d0f9245043..df1b8119a836f110cd7cc7c412b0665b322b8b07 100644 --- a/lib_debug/sba_debug.c +++ b/lib_debug/sba_debug.c @@ -333,10 +333,10 @@ void ivas_open_sba_decoder_debug_files( cstrcat( (char *) fb_wav_dump_path[2], sizeof( fb_wav_dump_path[2] ), "pca_dec.wav" ); spar_foa_dec_wav[2] = CreateWav( (const char *) fb_wav_dump_path[2], fs, n_transport, 16 /* const uint32_t writeWaveExt */ ); - cstrcat( (char *) fb_wav_dump_path[3], sizeof( fb_wav_dump_path[3] ), "cldfbSynthesis.wav" ); + cstrcat( (char *) fb_wav_dump_path[3], sizeof( fb_wav_dump_path[3] ), "cldfbSynthesis_ivas.wav" ); spar_foa_dec_wav[3] = CreateWav( (const char *) fb_wav_dump_path[3], fs, n_transport, 16 /* const uint32_t writeWaveExt */ ); - cstrcat( (char *) fb_wav_dump_path[4], sizeof( fb_wav_dump_path[4] ), "cldfbAnalysis.wav" ); + cstrcat( (char *) fb_wav_dump_path[4], sizeof( fb_wav_dump_path[4] ), "cldfbAnalysis_ivas.wav" ); spar_foa_dec_wav[4] = CreateWav( (const char *) fb_wav_dump_path[4], fs, n_transport, 16 /* const uint32_t writeWaveExt */ ); return; diff --git a/lib_dec/ACcontextMapping_dec.c b/lib_dec/ACcontextMapping_dec.c index cabbef7c2609ad3d6e8bc4f9135b6c3b2a45a817..a50fac1eaf951f02e2b7fafdf2831029b85a9674 100644 --- a/lib_dec/ACcontextMapping_dec.c +++ b/lib_dec/ACcontextMapping_dec.c @@ -45,13 +45,13 @@ #include /*-------------------------------------------------------------------* - * ACcontextMapping_decode2_no_mem_s17_LC() + * ACcontextMapping_decode2_no_mem_s17_LC_ivas() * * Arithmetic decoder *-------------------------------------------------------------------*/ /*! r: resQBits */ -int16_t ACcontextMapping_decode2_no_mem_s17_LC( +int16_t ACcontextMapping_decode2_no_mem_s17_LC_ivas( Decoder_State *st, /* i/o: decoder state */ int16_t *x, /* o : decoded spectrum */ int16_t nt, /* i : size of spectrum */ @@ -145,7 +145,7 @@ int16_t ACcontextMapping_decode2_no_mem_s17_LC( /* Start Decoding */ - ari_start_decoding_14bits( st, &as ); + ari_start_decoding_14bits_ivas( st, &as ); overflow_bit_pos = st->next_bit_pos; nbbits_m2 = nbbits + cbitsnew - 2; @@ -156,13 +156,13 @@ int16_t ACcontextMapping_decode2_no_mem_s17_LC( { if ( hm_cfg ) { - a1_i = get_next_coeff_mapped( ii, &p1, &idx1, hm_cfg ); - b1_i = get_next_coeff_mapped( ii, &p2, &idx2, hm_cfg ); + a1_i = get_next_coeff_mapped_ivas( ii, &p1, &idx1, hm_cfg ); + b1_i = get_next_coeff_mapped_ivas( ii, &p2, &idx2, hm_cfg ); } else { - a1_i = get_next_coeff_unmapped( ii, &idx1 ); - b1_i = get_next_coeff_unmapped( ii, &idx2 ); + a1_i = get_next_coeff_unmapped_ivas( ii, &idx1 ); + b1_i = get_next_coeff_unmapped_ivas( ii, &idx2 ); } idx = min( idx1, idx2 ); @@ -188,7 +188,7 @@ int16_t ACcontextMapping_decode2_no_mem_s17_LC( { esc_nb = min( lev, 3 ); pki = ari_lookup_s17_LC[t + ( esc_nb << ( NBITS_CONTEXT + NBITS_RATEQ ) )]; - ari_decode_14bits_s17_ext( st, &r, &as, ari_pk_s17_LC_ext[pki] ); + ari_decode_14bits_s17_ext_ivas( st, &r, &as, ari_pk_s17_LC_ext[pki] ); if ( r < VAL_ESC ) { @@ -263,13 +263,13 @@ int16_t ACcontextMapping_decode2_no_mem_s17_LC( if ( idx1 & 1 ) { /* update first context */ - c[p1] = update_mixed_context( c[p1], a ); + c[p1] = update_mixed_context_ivas( c[p1], a ); } if ( idx2 & 1 ) { /* update second context */ - c[p2] = update_mixed_context( c[p2], b ); + c[p2] = update_mixed_context_ivas( c[p2], b ); } } } @@ -427,8 +427,8 @@ int16_t RCcontextMapping_decode2_no_mem_s17_LCS( /* Main Loop through the 2-tuples */ for ( k = 0; k < lastnz; k += 2 ) { - a1_i = get_next_coeff_mapped( ii, &p1, &idx1, hm_cfg ); - b1_i = get_next_coeff_mapped( ii, &p2, &idx2, hm_cfg ); + a1_i = get_next_coeff_mapped_ivas( ii, &p1, &idx1, hm_cfg ); + b1_i = get_next_coeff_mapped_ivas( ii, &p2, &idx2, hm_cfg ); idx = min( idx1, idx2 ); /* Get context */ @@ -520,13 +520,13 @@ int16_t RCcontextMapping_decode2_no_mem_s17_LCS( if ( idx1 & 1 ) { /* update first context */ - c[p1] = update_mixed_context( c[p1], a ); + c[p1] = update_mixed_context_ivas( c[p1], a ); } if ( idx2 & 1 ) { /* update second context */ - c[p2] = update_mixed_context( c[p2], b ); + c[p2] = update_mixed_context_ivas( c[p2], b ); } } } diff --git a/lib_dec/ACcontextMapping_dec_fx.c b/lib_dec/ACcontextMapping_dec_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..5fcc16b2e0d835f2deb2b8c5bdd6139fd700de04 --- /dev/null +++ b/lib_dec/ACcontextMapping_dec_fx.c @@ -0,0 +1,682 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include +#include +#include "options.h" +#include "rom_com.h" +#include "rom_dec.h" +#include "basop_util.h" +#include "cnst.h" +#include "prot_fx1.h" +#include "prot_fx2.h" + +/*-------------------------------------------------------------------* + * ACcontextMapping_decode2_no_mem_s17_LC() + * + * Arithmetic decoder + *-------------------------------------------------------------------*/ + +Word16 ACcontextMapping_decode2_no_mem_s17_LC( + Decoder_State *st,/* i/o: decoder state */ + Word16 *x, /* o: decoded spectrum */ + Word16 nt, /* i: size of spectrum */ + Word16 nbbits, /* i: bit budget */ + Word16 resQMaxBits, /* i: residual coding maximum bits*/ + CONTEXT_HM_CONFIG *hm_cfg /* i: context-based harmonic model configuration */ +) +{ + Tastat as; + Word16 start_bit_pos, lsbs_bit_pos, overflow_bit_pos; + Word16 a, b, t, a1, b1, a1_i, b1_i, k, L; + Word16 lev, pki, esc_nb; + Word16 rateFlag; + Word16 r, lastnz, n; + Word16 resQBits; + Word16 rest_bits, rest_bits_overflow; + Word16 tmp=0; /* initialize just to avoid compiler warning */ + Word16 nt_half; + Word16 c[2], *ctx; + Word16 p1, p2; + Word16 ii[2], idx1, idx2, idx; + Word16 numPeakIndicesOrig, numHoleIndices; + get_next_coeff_function get_next_coeff; + Word16 nbbits_m2; + Word32 La, Lb; + + r = 0; /* to avoid compilation warnings */ move16(); + esc_nb = 0; /* to avoid compilation warnings */ move16(); + + set16_fx(x, 0, nt); + + /* Rate flag */ + rateFlag = 0; + move16(); + if (GT_16(nbbits, 400)) + { + rateFlag = 2 << NBITS_CONTEXT; + move16(); + } + + /*Decode number of ntuples*/ + start_bit_pos = st->next_bit_pos; + move16(); + lsbs_bit_pos = add(start_bit_pos, sub(nbbits, 1)); + + n = 0; + move16(); + + L = sub(14, norm_s(negate(nt))); + n = add(get_next_indice(st, L), 1); + + /* Init */ + nt_half = shr(nt, 1); + c[0] = c[1] = 0; + move16(); + move16(); + + t = 0; + move16(); + + lastnz = shl(n, 1); + + IF (GT_16(lastnz, nt) || st->BER_detect) + { + st->BER_detect = 1; + move16(); + return 0; + } + + IF (hm_cfg) /* mapped domain */ + { + numPeakIndicesOrig = hm_cfg->numPeakIndices; + move16(); + hm_cfg->numPeakIndices = s_min(hm_cfg->numPeakIndices, lastnz); + move16(); + numHoleIndices = sub(lastnz, hm_cfg->numPeakIndices); + + /* Mark hole indices beyond lastnz as pruned */ + FOR (k=numHoleIndices; knumHoleIndices; ++k) + { + hm_cfg->holeIndices[k] = add(hm_cfg->holeIndices[k], nt); + move16(); + } + + ii[0] = numPeakIndicesOrig; + move16(); + ii[1] = 0; + move16(); + + get_next_coeff = get_next_coeff_mapped; + move16(); + } + ELSE /* unmapped domain */ + { + ii[0] = 0; + move16(); + + p1 = p2 = 0; + move16(); + move16(); + + get_next_coeff = get_next_coeff_unmapped; + move16(); + } + + /* Start Decoding */ + ari_start_decoding_14bits(st, &as); + + overflow_bit_pos = st->next_bit_pos; + move16(); + nbbits_m2 = add(nbbits, cbitsnew - 2); + rest_bits_overflow = rest_bits = negate(nbbits_m2); + move16(); + + /*Main Loop through the 2-tuples*/ + FOR (k = 0; k < lastnz; k += 2) + { + /* First coefficient */ + a1_i = get_next_coeff(ii, &p1, &idx1, hm_cfg); + + /* Second coefficient */ + b1_i = get_next_coeff(ii, &p2, &idx2, hm_cfg); + + idx = s_min(idx1, idx2); + + /* Get context */ + ctx = &c[s_or(p1, p2)]; + move16(); + + t = add(*ctx, rateFlag); + if (GT_16(idx, nt_half)) + { + t = add(t, 1 << NBITS_CONTEXT); + } + + test(); + IF (t < 0 || lsbs_bit_pos <= 0) + { + st->BER_detect = 1; + move16(); + return 0; + } + + La = L_deposit_l(0); + Lb = L_deposit_l(0); + /* MSBs decoding */ + test(); + FOR (lev = 0; lev < 15 && lsbs_bit_pos > 0; lev++) + { + test(); + esc_nb = s_min(lev, 3); + tmp = add(t, Tab_esc_nb[esc_nb]); + assert(tmp >= 0 && tmp < 4096); + pki = ari_lookup_s17_LC[tmp]; + move16(); + r = ari_decode_14bits_s17_ext(st, &as, ari_pk_s17_LC_ext[pki]); + + IF (LT_16(r, VAL_ESC)) + { + BREAK; + } + + /*LSBs decoding*/ + La = L_mac0(La, pow2tab[lev], get_indice_1_fx(st, lsbs_bit_pos--)); + Lb = L_mac0(Lb, pow2tab[lev], get_indice_1_fx(st, lsbs_bit_pos--)); + } + + test(); + test(); + IF ( ((LT_16(lsbs_bit_pos, -1)&&GE_16(r,VAL_ESC)))||(GT_16(lev,14))) + { + x[a1_i] = 0; + move16(); + x[b1_i] = 0; + move16(); + st->BER_detect = 1; + move16(); + return 0; + } + + /*MSBs contributions*/ + b1 = shr(r, 2); + a1 = s_and(r, 0x3); + a = extract_l(L_mac0(La, pow2tab[lev], a1)); + b = extract_l(L_mac0(Lb, pow2tab[lev], b1)); + + /*lsbs bits sign bits*/ + rest_bits = add(rest_bits, shl(lev, 1)); + + if (a > 0) + { + rest_bits = add(rest_bits, 1); + } + if (b > 0) + { + rest_bits = add(rest_bits, 1); + } + + /*Dectect overflow*/ + IF (add(sub(st->next_bit_pos, start_bit_pos), rest_bits) > 0) + { + /* Roll back bitstream position to overflow_bit_pos */ + get_next_indice_tmp_fx(st, sub(overflow_bit_pos, st->next_bit_pos)); + rest_bits = rest_bits_overflow; + move16(); + x[a1_i] = 0; + move16(); + x[b1_i] = 0; + move16(); + BREAK; + } + + overflow_bit_pos = st->next_bit_pos; + move16(); + rest_bits_overflow = rest_bits; + move16(); + + /* Store decoded data */ + x[a1_i] = a; + move16(); + x[b1_i] = b; + move16(); + + /* Update context for next 2-tuple */ + IF (EQ_16(p1, p2)) /* peak-peak or hole-hole context */ + { + lev = sub(esc_nb, 1); + if (lev > 0) t = add(12, lev); + if (lev <= 0) t = add(a1, b1); + if (lev == 0) t = add(t, t); + + *ctx = add(shl(s_and(*ctx, 0xf), 4), add(t, 1)); + move16(); + } + ELSE /* mixed context */ + { + IF (s_and(idx1, 1)) /* update first context */ + { + c[p1] = update_mixed_context(c[p1], a); + move16(); + } + + IF (s_and(idx2, 1)) /* update second context */ + { + c[p2] = update_mixed_context(c[p2], b); + move16(); + } + } + } + + /* Total number of decoded AC bits */ + get_next_indice_tmp_fx(st, -(cbitsnew - 2)); + + /*detect overflow*/ + IF (NE_16(k, lastnz)) + { + rest_bits = add(rest_bits, nbbits_m2); + /* Set bitstream position to (start_bit_pos+nbbits-rest_bits) */ + get_next_indice_tmp_fx(st, sub((sub(add(start_bit_pos, nbbits), rest_bits)), st->next_bit_pos)); + } + + /*Decode signs*/ + if (hm_cfg) + { + tmp = nt; + move16(); + } + if (!hm_cfg) + { + tmp = lastnz; + move16(); + } + FOR (k = 0; k < tmp; k++) + { + IF (x[k] > 0) + { + if (get_next_indice_1(st) != 0) + { + x[k] = negate(x[k]); + move16(); + } + } + } + + /*Decode Residual Q*/ + resQBits = s_min(resQMaxBits, sub(add(lsbs_bit_pos,1), st->next_bit_pos)); + FOR (k=0; knext_bit_pos)); + + + return resQBits; +} +#ifdef IVAS_CONTEXT_MAPPING + +/*-------------------------------------------------------------------* + * RCcontextMapping_decode2_no_mem_s17_LCS() + * + * Range decoder + *-------------------------------------------------------------------*/ + + /*! r: resQBits */ +int16_t RCcontextMapping_decode2_no_mem_s17_LCS( + Decoder_State* st, /* i/o: decoder state */ + int16_t* x, /* o : decoded spectrum */ + const int16_t nt, /* i : size of spectrum */ + const int16_t nbbits, /* i : bit budget */ + const int16_t resQMaxBits, /* i : residual coding maximum bits */ + CONTEXT_HM_CONFIG* hm_cfg /* i : context-based harmonic model configuration*/ +) +{ + RangeUniDecState rc_st_dec; /* State of the range decoder */ + int16_t start_bit_pos, lsbs_bit_pos; + int16_t a, b, a1, b1, k; + uint16_t t; + int16_t lev, pki, esc_nb; + int16_t rateFlag; + int16_t lastnz, n; + uint16_t r; + int16_t resQBits; + int16_t rest_bits; + int16_t nt_half; + int16_t nbbits_m2; + int16_t bits_tups; /* No. of bits for coding the no. of tuples */ + + set_s(x, 0, nt); + + /*Decode number of ntuples*/ + start_bit_pos = st->next_bit_pos; + lsbs_bit_pos = start_bit_pos + nbbits - 1; + n = 0; + k = 1; + nt_half = nt >> 1; + + while (k < nt_half) + { + ++n; + k = k << 1; + } + + bits_tups = n; + + n = get_next_indice(st, n) + 1; + + t = 0; + + lastnz = n << 1; + + if (lastnz > nt) + { + st->BER_detect = 1; + return 0; + } + + if (hm_cfg) + { + int16_t a1_i, b1_i; + int32_t c[2], * ctx; + int32_t p1, p2; + int16_t ii[2]; + int16_t idx1, idx2, idx; + int16_t numPeakIndicesOrig, numHoleIndices; + + /* Rate flag */ + if (nbbits > 400) + { + rateFlag = 2 << NBITS_CONTEXT; + } + else + { + rateFlag = 0; + } + + /* Init */ + c[0] = c[1] = 0; + + /* mapped domain */ + numPeakIndicesOrig = hm_cfg->numPeakIndices; + hm_cfg->numPeakIndices = min(hm_cfg->numPeakIndices, lastnz); + numHoleIndices = lastnz - hm_cfg->numPeakIndices; + + /* Mark hole indices beyond lastnz as pruned */ + for (k = numHoleIndices; k < hm_cfg->numHoleIndices; ++k) + { + hm_cfg->holeIndices[k] = hm_cfg->holeIndices[k] + nt; + } + + ii[0] = numPeakIndicesOrig; + ii[1] = 0; + + p1 = p2 = 0; /* to avoid compilation warnings */ + + /* Start Decoding */ + /* Initialize range decoder */ + rc_uni_dec_init(&rc_st_dec, &st->bit_stream[st->next_bit_pos], nbbits); /* (nbbits + 30) entries are read by the decoder */ + + nbbits_m2 = nbbits; + rest_bits = -nbbits_m2; + + /* Main Loop through the 2-tuples */ + for (k = 0; k < lastnz; k += 2) + { + a1_i = get_next_coeff_mapped(ii, &p1, &idx1, hm_cfg); + b1_i = get_next_coeff_mapped(ii, &p2, &idx2, hm_cfg); + idx = min(idx1, idx2); + + /* Get context */ + ctx = &c[p1 | p2]; + + t = (uint16_t)(*ctx + rateFlag); + t += (nt_half >= idx) ? 0 : (1 << NBITS_CONTEXT); + + esc_nb = 0; + r = 0; + + /* BER detection: Check max value of context t leading to out-of-bound access to ari_lookup_s17_LC[]*/ + if ((t >= (1 << (NBITS_CONTEXT + NBITS_RATEQ))) || lsbs_bit_pos <= 0) + { + st->BER_detect = 1; + return 0; + } + + a = b = 0; + + /* MSBs decoding */ + for (lev = 0; lev < 15 && lsbs_bit_pos > 0; ++lev) + { + esc_nb = min(lev, 3); + pki = ari_lookup_s17_LC[t + (esc_nb << (NBITS_CONTEXT + NBITS_RATEQ))]; + r = rc_uni_dec_read_symbol_fastS(&rc_st_dec, cum_freq_ari_pk_s17_LC_ext[pki], sym_freq_ari_pk_s17_LC_ext[pki], 17, 14); /*Alphabet size = 17 (2^4 = 16 MSB symbols + 1 ESC symbol) */ + /* r is the symbol read, the possible values are {0,1,....alphabet_size - 1} */ + + if (r < VAL_ESC) /* If symbol read corresponds to MSB */ + { + break; + } + + /* LSBs decoding */ + a += get_indice_1(st, lsbs_bit_pos--) << lev; + b += get_indice_1(st, lsbs_bit_pos--) << lev; + } + + if ((lsbs_bit_pos < -1 && r >= VAL_ESC) || (lev > 14)) + { + x[a1_i] = 0; + x[b1_i] = 0; + st->BER_detect = 1; + return 0; + } + + /* MSBs contributions */ + b1 = r >> 2; + a1 = r & 0x3; + a += a1 << lev; + b += b1 << lev; + + /* Add 2 LSB bits per bit-plane */ + rest_bits += 2 * lev; + /* Sign bits */ + rest_bits += min(a, 1); + rest_bits += min(b, 1); + + /* Update bitstream pointer */ + st->next_bit_pos = start_bit_pos + bits_tups + rc_uni_dec_virtual_finish(&rc_st_dec); + + /* Confirm that there is no overflow */ +#ifdef DEBUGGING + assert(st->next_bit_pos - start_bit_pos + rest_bits <= 0); +#endif + + /* Store decoded data */ + x[a1_i] = a; + x[b1_i] = b; + + /* Update context for next 2-tuple */ + if (p1 == p2) + { + /* peak-peak or hole-hole context */ + lev = esc_nb - 1; + + if (lev <= 0) + { + t = 1 + (a1 + b1) * (lev + 2); + } + else + { + t = 13 + lev; + } + + *ctx = (*ctx & 0xf) * 16 + t; + } + else + { + /* mixed context */ + + if (idx1 & 1) + { + /* update first context */ + c[p1] = update_mixed_context(c[p1], a); + } + + if (idx2 & 1) + { + /* update second context */ + c[p2] = update_mixed_context(c[p2], b); + } + } + } + + /* We don't need to finish because virtual_finish() already does the same */ + /*st->next_bit_pos = rc_uni_dec_finish(&rc_st_dec);*/ + + /* Check for bitstream errors */ + assert(rc_st_dec.bit_error_detected == 0); + + /* Cross-check: No overflow */ +#ifdef DEBUGGING + assert(k == lastnz); +#endif + + /* Decode signs */ + n = nt; + } + else /* if(!hm_cfg) */ + { + int16_t c, rateQ; + uint16_t s; + + /* Rate flag */ + if (nbbits > 400) + { + rateFlag = 2; + } + else + { + rateFlag = 0; + } + + /* Start Decoding */ + /* Initialize range decoder */ + rc_uni_dec_init(&rc_st_dec, &st->bit_stream[st->next_bit_pos], nbbits); /* (nbbits + 30) entries are read by the decoder */ + + nbbits_m2 = nbbits; + rest_bits = -nbbits_m2; + + t = 0; + s = 0; + + /* Main Loop through the 2-tuples */ + for (k = 0; k < lastnz; k += 2) + { + rateQ = rateFlag + (k > (nt_half)); + + /* BER detection: Check max value of context t leading to out-of-bound access to ari_lookup_s17_LC[]*/ + if ((t >= (1 << (NBITS_CONTEXT))) || lsbs_bit_pos <= 0) + { + st->BER_detect = 1; + return 0; + } + + a = b = 0; + esc_nb = 0; + r = 0; + + /* MSBs decoding */ + for (lev = 0; lev < 15 && lsbs_bit_pos > 0; ++lev) + { + esc_nb = min(lev, 3); + pki = ari_lookup_s17_LC[t + ((rateQ) << NBITS_CONTEXT) + (esc_nb << (NBITS_CONTEXT + NBITS_RATEQ))]; + r = rc_uni_dec_read_symbol_fastS(&rc_st_dec, cum_freq_ari_pk_s17_LC_ext[pki], sym_freq_ari_pk_s17_LC_ext[pki], 17, 14); /*Alphabet size = 17 (2^4 = 16 MSB symbols + 1 ESC symbol) */ + /* r is the symbol read, the possible values are {0,1,....alphabet_size - 1} */ + + if (r < VAL_ESC) /* If symbol read corresponds to MSB */ + { + break; + } + + /* LSBs decoding */ + a += get_indice_1(st, lsbs_bit_pos--) << lev; + b += get_indice_1(st, lsbs_bit_pos--) << lev; + } + + if ((lsbs_bit_pos < -1 && r >= VAL_ESC) || (lev > 14)) + { + x[k + 0] = 0; + x[k + 1] = 0; + st->BER_detect = 1; + return 0; + } + + /* MSBs contributions */ + b1 = r >> 2; + a1 = r & 0x3; + a += a1 << lev; + b += b1 << lev; + + /* Add 2 LSB bits per bit-plane */ + rest_bits += 2 * lev; + /* Sign bits */ + rest_bits += min(a, 1); + rest_bits += min(b, 1); + + /* Update bitstream pointer */ + st->next_bit_pos = start_bit_pos + bits_tups + rc_uni_dec_virtual_finish(&rc_st_dec); + + /* Confirm that there is no overflow */ +#ifdef DEBUGGING + assert(st->next_bit_pos - start_bit_pos + rest_bits <= 0); +#endif + + /* Store decoded data */ + x[k + 0] = a; + x[k + 1] = b; + + /* Update context for next 2-tuple */ + if (esc_nb < 2) + { + c = 1 + ((a1 + b1) * (esc_nb + 1)); + } + else + { + c = 12 + esc_nb; + } + + s = s << 4; /*Shift old 4 bits*/ + s = s + c; /*replace last 4 bits*/ + t = s & 0xFF; + } + + /* Decode signs */ + n = lastnz; + } /* end of if(hm_cfg) */ + + for (k = 0; k < n; k++) + { + if (x[k] > 0) + { + x[k] *= 1 - 2 * get_next_indice_1(st); + } + } + + /* Decode Residual Q */ + resQBits = min(resQMaxBits, lsbs_bit_pos + 1 - st->next_bit_pos); + + for (k = 0; k < resQBits; ++k) + { + x[nt + k] = get_indice_1(st, lsbs_bit_pos - k); + } + + /* Set bitstream pointer to end of buffer */ + get_next_indice_tmp(st, (start_bit_pos + nbbits) - st->next_bit_pos); + + return resQBits; +} + +#endif diff --git a/lib_dec/FEC.c b/lib_dec/FEC.c index 53770bc0b23fcdec98c826b625c078e02fd58a1c..ce581ec8dc6c2d4e6d04a96a6cd3d520ef0d188b 100644 --- a/lib_dec/FEC.c +++ b/lib_dec/FEC.c @@ -104,7 +104,7 @@ void FEC_exc_estim( *-----------------------------------------------------------------*/ /* pitch extrapolation */ - pitch_pred_linear_fit( st->nbLostCmpt, st->last_good, st->old_pitch_buf, L_frame == L_FRAME ? &st->old_pitch_buf[2 * NB_SUBFR - 1] : &st->old_pitch_buf[2 * NB_SUBFR16k - 1], &predPitchLag, L_frame == L_FRAME ? PIT_MIN_DOUBLEEXTEND : PIT16k_MIN_EXTEND, L_frame == L_FRAME ? PIT_MAX : PIT16k_MAX, st->mem_pitch_gain_float, 0, 0, &extrapolationFailed, L_frame / L_SUBFR ); + pitch_pred_linear_fit_flt( st->nbLostCmpt, st->last_good, st->old_pitch_buf, L_frame == L_FRAME ? &st->old_pitch_buf[2 * NB_SUBFR - 1] : &st->old_pitch_buf[2 * NB_SUBFR16k - 1], &predPitchLag, L_frame == L_FRAME ? PIT_MIN_DOUBLEEXTEND : PIT16k_MIN_EXTEND, L_frame == L_FRAME ? PIT_MAX : PIT16k_MAX, st->mem_pitch_gain_float, 0, 0, &extrapolationFailed, L_frame / L_SUBFR ); new_pit = (int16_t) ( predPitchLag + 0.5f ); @@ -268,7 +268,7 @@ void FEC_exc_estim( if ( ( cond1 < 0 ) && ( new_pit > 0 ) && ( cond2 != 0 ) && ( cond3 > 0 ) && extrapolationFailed == 0 ) { mvr2r( exc, exc - L_frame - L_SUBFR, L_frame + L_SUBFR ); - PulseResynchronization( exc - L_frame - L_SUBFR, exc, L_frame, L_frame / L_SUBFR, Tc, new_pit ); + PulseResynchronization_flt( exc - L_frame - L_SUBFR, exc, L_frame, L_frame / L_SUBFR, Tc, new_pit ); } } diff --git a/lib_dec/FEC_HQ_core_fx.c b/lib_dec/FEC_HQ_core_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..f1b24332856543cc44510c0f34bebbcccdc3bf81 --- /dev/null +++ b/lib_dec/FEC_HQ_core_fx.c @@ -0,0 +1,1739 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ +#include +#include "options.h" /* Compilation switches */ +#include "cnst.h" /* Common constants */ +#include "prot_fx1.h" /* Function prototypes */ +#include "prot_fx2.h" /* Function prototypes */ +#include "rom_com.h" + + +/*---------------------------------------------------------------------* + * Local function prototypes + *---------------------------------------------------------------------*/ + +static Word16 FEC_phase_matching_fx(HQ_NBFEC_HANDLE st_fx, Word32* ImdctOut_fx, Word16* auOut_fx, Word16* OldauOut_fx, Word16 OldauOut_pha_fx[2][N_LEAD_NB]); +static void FEC_phase_matching_nextgood_fx(const Word32* ImdctOut_fx, Word16* auOut_fx, Word16* OldauOut_fx, Word16 OldauOut_pha_fx[2][N_LEAD_NB],Word16 mean_en_high_fx); +static void FEC_phase_matching_burst_fx(const Word32* ImdctOut_fx, Word16* auOut_fx, Word16* OldauOut_fx, Word16 OldauOut_pha_fx[2][N_LEAD_NB], Word16* prev_oldauOut_fx ); +static void Repetition_smoothing_nextgood_fx(const Word32* ImdctOut_fx, Word16* auOut_fx, Word32* OldImdctOut_fx, Word16* OldauOut_fx, Word16 cur_data_use_flag, Word16 overlap_time); +static Word16 Repetition_smoothing_fx(const Word32* ImdctOut_fx, Word16* auOut_fx, Word32* OldImdctOut_fx, Word16* OldauOut_fx, const Word16 L, Word16* prev_oldauOut_fx, Word16 overlap_time ); +static void Smoothing_vector_scaledown_NB_fx(const Word16 OldauOutnoWin_fx[], const Word16 ImdctOutWin_fx[], const Word16 SmoothingWin_fx[], Word16 auOut_fx[], const Word16 ol_size); +static void Smoothing_vector_NB_fx(const Word16 OldauOutnoWin_fx[], const Word16 ImdctOutWin_fx[], const Word16 SmoothingWin_fx[], Word16 auOut_fx[], const Word16 ol_size); +static void Windowing_1st_NB_fx(Word16* ImdctOutWin_fx, const Word32* ImdctOut_fx, const Word16* win_fx, const Word16* smoothingWin_fx, Word16 smoothing_flag ); +static void Windowing_2nd_NB_fx(Word16* ImdctOutWin_fx, const Word32* ImdctOut_fx, const Word16* win_fx ); +static void Scaledown_fx(Word16 x[], Word16 y[], Word16 scale_v,const Word16 N ); +static void Next_good_after_burst_erasures_fx(const Word32* ImdctOut_fx, Word16* auOut_fx,Word16* OldauOut_fx, const Word16 ol_size); +static void common_overlapping_fx(Word16* auOut_fx, Word16* ImdctOutWin_fx, Word16* OldauOut_fx, Word16 end1, Word16 offset1, Word16 start2, Word16 end2, Word16 offset_i2, Word16 offset2); + + +/*--------------------------------------------------------------------------* + * Regression_Anal() + * + * + *--------------------------------------------------------------------------*/ +static void Regression_Anal_fx( + const Word32 *values_fx, /* i : Previous values */ + Word32 *r_p_fx, /* o : Output r[a b] array : y=ax+b */ + const Word16 num_pgf /* i : Number of previous good frame */ +) +{ + Word16 i; + Word16 tmp; + Word32 L_tmp1, L_tmp2; + Word16 aindex_fx[MAX_PGF+1]; + Word32 b_p_fx[MAX_PGF+1]; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + + /* Initialize */ + FOR (i=0; ihHQ_nbfec; + hHQ_core = st_fx->hHQ_core; + + + /* Decide the start frame number for adaptive muting */ + /* Normalized energy difference between the current frame and the moving average */ + tmp_fx = abs_s(sub(hHQ_nbfec->energy_MA_Curr_fx[1], hHQ_nbfec->energy_MA_Curr_fx[0])); + exp1 = sub(norm_s(tmp_fx), 1); + hHQ_nbfec->energy_MA_Curr_fx[0] = s_max(hHQ_nbfec->energy_MA_Curr_fx[0],1); + move16(); + exp2 = norm_s(hHQ_nbfec->energy_MA_Curr_fx[0]); + tmp_fx = div_s(shl(tmp_fx, exp1), shl(hHQ_nbfec->energy_MA_Curr_fx[0], exp2));/*15 + exp1 - exp2*/ + energy_diff_fx = shl(tmp_fx, sub(sub(exp2, exp1), 5));/*10*/ + test(); + IF ((LT_16(energy_diff_fx, 1024))&&(is_transient==0)) /* First erasure frame */ + { + mute_start = 5; + move16(); + } + ELSE + { + mute_start = 2; + move16(); + } + test(); + test(); + if( EQ_16(st_fx->prev_old_bfi_fx, 1)&&EQ_16(st_fx->nbLostCmpt,1)&&EQ_16(output_frame,L_FRAME8k)) + { + st_fx->nbLostCmpt = add(st_fx->nbLostCmpt, 1); + } + + /* Frequency-domain FEC */ + IF ( EQ_16(st_fx->nbLostCmpt, 1)) /* First erasure frame */ + { + IF ( is_transient == 0 ) + { + IF (LT_16(energy_diff_fx, 1024)) + { + FOR (i=0; i < output_frame; i++) + { + t_audio_q_fx[i] = hHQ_nbfec->old_coeffs_fx[i]; + move32(); + } + } + ELSE + { + FOR (i=0; i < output_frame; i++) + { + hHQ_nbfec->old_coeffs_fx[i] = Mult_32_16(hHQ_nbfec->old_coeffs_fx[i], 23170);/*23170, 3dB, Q15*/ + t_audio_q_fx[i] = hHQ_nbfec->old_coeffs_fx[i]; + move32(); + } + } + + /* Sign prediction in 4-dim bands up to 1.6 kHz*/ + IF (hHQ_core->old_is_transient_fx[1] == 0) + { + IF (hHQ_core->old_is_transient_fx[2] == 0) + { + FOR (sfm = 0; sfm < HQ_FEC_SIGN_SFM; sfm++) + { + IF (GE_16(hHQ_nbfec->prev_sign_switch_fx[sfm], HQ_FEC_SIGN_THRES)) + { + FOR (i = 0; i < HQ_FEC_BAND_SIZE; i++) + { + t_audio_q_fx[i+sfm*HQ_FEC_BAND_SIZE] = L_negate(t_audio_q_fx[i+sfm*HQ_FEC_BAND_SIZE]); + move32(); + } + } + } + } + ELSE + { + FOR (sfm = 0; sfm < HQ_FEC_SIGN_SFM; sfm++) + { + IF (GE_16(hHQ_nbfec->prev_sign_switch_fx[sfm], HQ_FEC_SIGN_THRES_TRANS)) + { + FOR (i = 0; i < HQ_FEC_BAND_SIZE; i++) + { + t_audio_q_fx[i+sfm*HQ_FEC_BAND_SIZE] = L_negate(t_audio_q_fx[i+sfm*HQ_FEC_BAND_SIZE]); + move32(); + } + } + } + } + } + ELSE + { + FOR (i = RANDOM_START*8; i < output_frame; i++) + { + IF(Random(&hHQ_nbfec->HQ_FEC_seed_fx) < 0) + { + t_audio_q_fx[i] = L_negate(t_audio_q_fx[i]); + move32(); + } + } + } + } + ELSE + { + IF(hHQ_core->old_is_transient_fx[1] ) /* hangover */ + { + FOR (i=0; i < output_frame; i++) + { + hHQ_nbfec->old_coeffs_fx[i] = Mult_32_16(hHQ_nbfec->old_coeffs_fx[i], 23170); + t_audio_q_fx[i] = hHQ_nbfec->old_coeffs_fx[i]; + move32(); + } + } + ELSE + { + FOR (i = 0; i < RANDOM_START*8; i++) + { + hHQ_nbfec->old_coeffs_fx[i] = Mult_32_16(hHQ_nbfec->old_coeffs_fx[i], 23170); + t_audio_q_fx[i] = hHQ_nbfec->old_coeffs_fx[i]; + move32(); + } + + FOR (i = RANDOM_START*8; i < output_frame; i++) + { + hHQ_nbfec->old_coeffs_fx[i] = Mult_32_16(hHQ_nbfec->old_coeffs_fx[i], 23170); + IF (Random(&hHQ_nbfec->HQ_FEC_seed_fx) < 0) + { + t_audio_q_fx[i] = L_negate(hHQ_nbfec->old_coeffs_fx[i]); + move32(); + } + ELSE + { + t_audio_q_fx[i] = hHQ_nbfec->old_coeffs_fx[i]; + move32(); + } + } + } + } + } + ELSE /* st_fx->nbLostCmpt > 1 */ + { + test(); + IF( LT_16(energy_diff_fx, 1024)&&is_transient==0) + { + num_pgf = 4; + move16(); + } + ELSE + { + num_pgf = 2; + move16(); + } + + Num_sb_bwe = num_Sb; + move16(); + IF ( EQ_16(st_fx->nbLostCmpt, 2)) + { + + FOR ( i=0; inbLostCmpt, mute_start)) + { + /* Scaling */ + FOR ( i=0; i < output_frame; i++ ) + { + hHQ_nbfec->old_coeffs_fx[i] = Mult_32_16(hHQ_nbfec->old_coeffs_fx[i], 23170); + move32(); + } + } + + k = 0; + move16(); + FOR ( i=0; i 0 ) + { + r_p_fx[1] = L_deposit_l(0); + norm_p_fx[i] = L_shr(norm_values_fx[0], 7);/*5*/ move32(); + } + ELSE + { + norm_p_fx[i] = L_add(r_p_fx[0], L_mult0(extract_l(r_p_fx[1]), sub(add(st_fx->nbLostCmpt, num_pgf), 1))); + } + + test(); + IF ( norm_values_fx[0] != 0 && norm_p_fx[i] > 0 ) /* Avoid negative value of the predicted energy */ + { + exp1 = sub(norm_l(norm_p_fx[i]), 1); + exp2 = norm_l(norm_values_fx[0]); + tmp_fx = div_s(extract_h(L_shl(norm_p_fx[i], exp1)), + extract_h(L_shl(norm_values_fx[0], exp2)));/*15 + (5 + exp1 - 16) - (12 + exp2 - 16)*/ + tmp_fx = shl(tmp_fx, add(6, sub(exp2, exp1)));/*14*/ + + if (GT_16(tmp_fx, 16384)) + { + tmp_fx = 16384; + move16(); + } + + FOR ( j=0; jNorm_gain_fx[k++] = shl_o(tmp_fx, 1, &Overflow); +#else + hHQ_nbfec->Norm_gain_fx[k++] = shl(tmp_fx, 1); +#endif + move16(); + } + } + ELSE + { + /* Scale down the last gain with the fixed gain(-3dB) */ + FOR (j=0; jNorm_gain_fx[k] = mult_r(hHQ_nbfec->Norm_gain_fx[k], 23170); + move16(); + k++; + } + } + } + + /* Scaling for core band */ + FEC_scaling_fx(hHQ_nbfec->old_coeffs_fx, t_audio_q_fx, hHQ_nbfec->Norm_gain_fx, &hHQ_nbfec->HQ_FEC_seed_fx, nb_sfm, sfm_start, sfm_end ); + + } + + + return; +} + +void HQ_FEC_Mem_update_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + Word32 *t_audio_q_fx, /*Q12*/ + Word32 *normq_fx, /*Q14*/ + Word16 *ynrm, + Word16 *Num_bands_p, + Word16 is_transient, + Word16 hqswb_clas, + Word16 c_switching_flag, + Word16 nb_sfm, + Word16 num_Sb, + Word16 *mean_en_high_fx, /*Q5*/ + Word16 hq_core_type, /* i : normal or low-rate MDCT(HQ) core */ + Word16 output_frame +) +{ + Word16 Min_ind; + Word32 Min_value; + Word16 Max_ind; + Word16 stat_mode_curr; + + Word16 i, j, k; + Word16 offset; + Word16 exp, exp1, exp2, tmp_fx; + Word32* norm_values_fx; + Word32 L_tmp, tmp_energy_fx = 0, Max_coeff_fx; + Word32 en_high_fx[MAX_SB_NB]; + HQ_NBFEC_HANDLE hHQ_nbfec; + HQ_DEC_HANDLE hHQ_core; + hHQ_nbfec = st_fx->hHQ_nbfec; + hHQ_core = st_fx->hHQ_core; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif +#ifdef ADD_IVAS_HQ_CODE_FEC + IF(EQ_16(output_frame, L_FRAME8k)) + { +#endif + + IF (is_transient) + { + set16_fx(hHQ_nbfec->prev_sign_switch_2_fx, 0, HQ_FEC_SIGN_SFM); + set16_fx(hHQ_nbfec->prev_sign_switch_fx, 0, HQ_FEC_SIGN_SFM); + } + ELSE + { + FOR (j = 0; j < HQ_FEC_SIGN_SFM; j++) + { + hHQ_nbfec->prev_sign_switch_fx[j] = hHQ_nbfec->prev_sign_switch_2_fx[j]; + move16(); + hHQ_nbfec->prev_sign_switch_2_fx[j] = 0; + move16(); + + FOR (i = 0; i < HQ_FEC_BAND_SIZE; i++) + { + test(); + test(); + test(); + IF ((hHQ_nbfec->old_coeffs_fx[i+j*HQ_FEC_BAND_SIZE]>0 && t_audio_q_fx[i+j*HQ_FEC_BAND_SIZE]<0) + || (hHQ_nbfec->old_coeffs_fx[i+j*HQ_FEC_BAND_SIZE]<0 && t_audio_q_fx[i+j*HQ_FEC_BAND_SIZE]>0)) + { + hHQ_nbfec->prev_sign_switch_fx[j] = add(hHQ_nbfec->prev_sign_switch_fx[j], 1); + move16(); + hHQ_nbfec->prev_sign_switch_2_fx[j] = add(hHQ_nbfec->prev_sign_switch_2_fx[j], 1); + move16(); + } + } + } + } +#ifndef ADD_IVAS_HQ_CODE_FEC + IF(EQ_16(output_frame, L_FRAME8k)) + { +#endif + /* if LR MDCT core is used, recalculate norms from decoded MDCT spectrum (using code from hq_hr_enc_fx()) */ + test(); + IF ( ( EQ_16(hqswb_clas, HQ_HVQ))||(EQ_16(hq_core_type,LOW_RATE_HQ_CORE))) + { + /* First group */ + logqnorm_fx(t_audio_q_fx, 12, ynrm, 32, WID_G1, (hqswb_clas == HQ_HVQ)); + j = ynrm[0]; + move16(); + offset = WID_G1; + move16(); + + FOR ( i=1; iynrm_values_fx[i][0]; + Copy32(norm_values_fx, &norm_values_fx[1], MAX_PGF-1); + + L_tmp = L_deposit_l(0); + FOR (j=0; jlast_core, ACELP_CORE))&&(EQ_16(st_fx->core,HQ_CORE)))) + { + FOR (i=0; iynrm_values_fx[i][j]= hHQ_nbfec->ynrm_values_fx[i][0]; + move32(); + } + } + } + set16_fx(hHQ_nbfec->Norm_gain_fx, 32767, SFM_N_NB);/*15*/ + /* st->energy_MA_Curr[1]=Energy of the current frame */ + tmp_fx = inv_tbl_fx[nb_sfm]; + move16();/*15*/ + L_tmp = Mult_32_16(tmp_energy_fx, tmp_fx);/*8 + 15 - 15*/ + + hHQ_nbfec->energy_MA_Curr_fx[1] = extract_h(L_shl(L_tmp, 16-8)); + /* Moving Average */ + hHQ_nbfec->energy_MA_Curr_fx[0] = s_max(1,add(mult_r(26214, hHQ_nbfec->energy_MA_Curr_fx[0]), mult_r(6554, hHQ_nbfec->energy_MA_Curr_fx[1]))); + + /*st->diff_energy = (float)fabs((st->energy_MA_Curr[1] - st->energy_MA_Curr[0])/st->energy_MA_Curr[0]); */ + hHQ_nbfec->diff_energy_fx = abs_s(sub(hHQ_nbfec->energy_MA_Curr_fx[1], hHQ_nbfec->energy_MA_Curr_fx[0])); + exp1 = sub(norm_l(hHQ_nbfec->diff_energy_fx), 1); + exp2 = norm_l(hHQ_nbfec->energy_MA_Curr_fx[0]); + hHQ_nbfec->diff_energy_fx = div_s(extract_h(L_shl(hHQ_nbfec->diff_energy_fx, exp1)), extract_h(L_shl(hHQ_nbfec->energy_MA_Curr_fx[0], exp2))); + exp = add(15, sub(exp1, exp2)); + hHQ_nbfec->diff_energy_fx = shl(hHQ_nbfec->diff_energy_fx, sub(11, exp));/*11*/ + + /* Classify the stationary mode : 12% */ + IF (LT_16(hHQ_nbfec->diff_energy_fx, ED_THRES_12P_fx)) + { + stat_mode_curr = 1; + move16(); + } + ELSE + { + stat_mode_curr = 0; + move16(); + } + + /* Apply Hysteresis to prevent frequent mode changing */ + IF(EQ_16(hHQ_nbfec->stat_mode_old_fx, stat_mode_curr)) + { + hHQ_nbfec->stat_mode_out_fx = stat_mode_curr; + move16(); + } + + hHQ_nbfec->stat_mode_old_fx = stat_mode_curr; + move16(); + + /* Find max. band index (Minimum value means maximum energy) */ + Min_ind=0; + move16(); + Min_value = L_deposit_l(100); + FOR (i=0; iynrm_values[i][j+1];*/ + en_high_fx[i] = L_add(en_high_fx[i], L_shr(hHQ_nbfec->ynrm_values_fx[i][j+1], 1));/*Q12*/ move32(); + } + } + + *mean_en_high_fx = 0; + move16(); + FOR (i=k; iynrm_values[i][0]);*/ + exp1 = sub(norm_l(en_high_fx[i]), 1); + exp2 = norm_l(hHQ_nbfec->ynrm_values_fx[i][0]); + tmp_fx = div_s(extract_h(L_shl(en_high_fx[i], exp1)), extract_h(L_shl(hHQ_nbfec->ynrm_values_fx[i][0], exp2))); + exp = add(15, sub(exp1, exp2)); +#ifdef BASOP_NOGLOB + *mean_en_high_fx = add_o(*mean_en_high_fx, shr_o(tmp_fx, sub(exp, 5), &Overflow), &Overflow); +#else + *mean_en_high_fx = add(*mean_en_high_fx, shr(tmp_fx, sub(exp, 5))); +#endif + } + *mean_en_high_fx = mult(*mean_en_high_fx, inv_tbl_fx[num_Sb-k]); + + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF ((LT_16(Min_ind, 5))&&(LT_16(abs_s(sub(Min_ind, hHQ_nbfec->old_Min_ind_fx)),2))&&(LT_16(hHQ_nbfec->diff_energy_fx,ED_THRES_90P_fx))&&(!st_fx->bfi)&&(!st_fx->prev_bfi)&&(!st_fx->prev_old_bfi_fx) + &&(!is_transient)&&(!hHQ_core->old_is_transient_fx[1]) && (hHQ_nbfec->prev_last_core_fx==HQ_CORE) && (st_fx->last_core==HQ_CORE)) + { + hHQ_nbfec->phase_mat_flag_fx = 1; + move16(); + test(); + if ((Min_ind == 0)&&(LT_16(Max_ind, 3))) + { + hHQ_nbfec->phase_mat_flag_fx = 0; + move16(); + } + } + ELSE + { + hHQ_nbfec->phase_mat_flag_fx = 0; + move16(); + } + + hHQ_nbfec->old_Min_ind_fx = Min_ind; + move16(); + } + + FOR (i=0; i < L_FRAME8k; i++) + { + hHQ_nbfec->old_coeffs_fx[i] = t_audio_q_fx[i]; + move32(); + } + + hHQ_core->old_is_transient_fx[2] = hHQ_core->old_is_transient_fx[1]; + move16(); + hHQ_core->old_is_transient_fx[1] = hHQ_core->old_is_transient_fx[0]; + move16(); + hHQ_core->old_is_transient_fx[0] = is_transient; + move16(); + + return; +} + + +static Word16 find_best_delay_fx( + Word16 *mu_o_fx, + Word16 *in_fx, + Word16 mind1, + Word16 maxd1, + Word16 lin, + Word16 delta, + Word16 *false_flag +) +{ + Word16 i, d1, k; + Word16 d1m = 0; + + Word16 tmp, exp1, exp2; + Word32 L_tmp1, L_tmp2; + + Word32 min_sq_cross_fx, min_corr_fx; + Word32 accA_fx, accB_fx; + Word32 Rxy_fx[MAXDELAY_FEC], Ryy_fx[MAXDELAY_FEC]; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + + + d1 = mind1; + move16(); + FOR ( k = 0; k < (maxd1-mind1)/delta; k++ ) + { + accA_fx = L_deposit_l(0); + accB_fx = L_deposit_l(0); + FOR ( i = 0; i < lin; i += delta ) + { + accA_fx = L_add(accA_fx, L_shr(L_mult(mu_o_fx[d1+i], mu_o_fx[d1+i]),2)); + accB_fx = L_add(accB_fx, L_shr(L_mult(mu_o_fx[d1+i], in_fx[i]),2)); + } + + Rxy_fx[k] = accB_fx; + move32(); + Ryy_fx[k] = accA_fx; + move32(); + + d1 = add(d1, delta); + } + + /* Obtain the best delay values */ + min_sq_cross_fx = 0x80000000; + move32(); + min_corr_fx = L_deposit_l(0); + exp2 = 0; + move16(); + FOR ( d1 = 0; d1 < (maxd1-mind1)/delta; d1++ ) + { + IF (L_abs(Rxy_fx[d1]) > L_abs(Ryy_fx[d1])) + exp1 = norm_l(Rxy_fx[d1]); + ELSE + exp1 = norm_l(Ryy_fx[d1]); + + L_tmp1 = Mult_32_32(L_shl(Rxy_fx[d1], exp1), L_shl(min_corr_fx, exp2)); + L_tmp2 = Mult_32_32(L_shl(Ryy_fx[d1], exp1), L_shl(min_sq_cross_fx, exp2)); + IF ( GE_32(L_tmp1, L_tmp2)) + { + d1m = d1; + move16(); + min_corr_fx = L_add(Ryy_fx[d1], 0); /*12 + 12 - 31 */ + min_sq_cross_fx = L_add(Rxy_fx[d1], 0); /*12 + 12 - 31 */ + exp2 = exp1; + move16(); + } + } + + test(); + IF((min_sq_cross_fx<=0) || (min_corr_fx<=0)) + { + tmp = 0; + move16(); /* If cross correlation is negative, the division per the energy will always be negative --> tmp will be < 8192, no need to do the division per say */ + } + ELSE + { + /*d1m *= delta; */ + d1m = extract_l(L_mult0(d1m, delta)); + + exp1 = sub(norm_l(min_sq_cross_fx), 1); + exp2 = norm_l(min_corr_fx); + L_tmp1 = L_shl(min_sq_cross_fx, exp1); + L_tmp2 = L_shl(min_corr_fx, exp2); + tmp = div_s(extract_h(L_tmp1), extract_h(L_tmp2));/*15 + exp1 - exp2 */ +#ifdef BASOP_NOGLOB + tmp = shl_o(tmp, sub(exp2, add(exp1, 1)), &Overflow);/*14 */ +#else + tmp = shl(tmp, sub(exp2, add(exp1, 1)));/*14 */ +#endif + } + + *false_flag = 0; + move16(); + test(); + if (LT_16(tmp, 8192)||GT_16(tmp,24576)) + { + *false_flag = 1; + move16(); + } + + return d1m; + +} + +static Word16 Search_Max_Corr_fx( + Word16 *mu_o_fx, /* i : *old_auOut_2fr, */ + Word16 old_Min_ind, /* i : *old_auOut_2fr, */ + const Word16 L /* i : L/2 */ +) +{ + Word16 pos; + Word16 pos2,delta2; + Word16 lin, delta; + Word16 mind1,maxd1; + Word16 false_flag; + Word16 min_d1, max_d1; + Word16 tmp1, tmp2; + Word16 *in_fx; + + IF (old_Min_ind == 0) + { + /*lin = 8*L/20; */ /* Basic size of the block for phase matching */ + lin = mult_r(L, 13107); /* Basic size of the block for phase matching */ + /*min_dist = -1e35f; */ + mind1 = 0; + move16(); /* min value of delay d1 to search for */ + /*maxd1 = 12*L/20; */ /* max value of delay d1 to search for */ + maxd1 = mult_r(L, 19661); /* max value of delay d1 to search for */ + + /*in = mu_o + 2*L -lin; */ + in_fx = mu_o_fx + 2*L - lin; + move16(); + + /* generate correlation */ + delta = 2; + move16(); + delta2 = 1; + move16(); + + pos = find_best_delay_fx(mu_o_fx, in_fx, mind1, maxd1, lin, delta, &false_flag); + + IF (false_flag) + { + return 0; + } + + tmp1 = add(mind1, sub(add(pos, 1), delta)); + tmp2 = add(mind1, add(pos, delta)); + min_d1 = s_max(mind1, tmp1); + max_d1 = s_min(maxd1, tmp2); + pos2 = find_best_delay_fx(mu_o_fx, in_fx, min_d1, max_d1, lin, delta2, &false_flag); + IF (GT_16(mind1, tmp1)) + { + pos = pos2; + move16(); + } + ELSE + { + pos = add(pos, add(sub(pos2, delta), 1)); + } + + pos = add(pos, add(lin, mind1)); + } + ELSE + { + lin = mult_r(L, 9830); + mind1 = mult_r(L, 14746); /* min value of delay d1 to search for */ + maxd1 = mult_r(L, 22938); /* max value of delay d1 to search for */ + in_fx = mu_o_fx + 2*L - lin; + move16(); + + /* generate correlation */ + delta = 2; + move16(); + delta2 = 1; + move16(); + + pos = find_best_delay_fx(mu_o_fx, in_fx, mind1, maxd1, lin, delta, &false_flag); + + IF (false_flag) + { + return 0; + } + + tmp1 = add(mind1, add(sub(pos, delta), 1)); + tmp2 = add(mind1, add(pos, delta)); + min_d1 = s_max(mind1, tmp1); + max_d1 = s_min(maxd1, tmp2); + pos2 = find_best_delay_fx(mu_o_fx, in_fx, min_d1, max_d1, lin, delta2, &false_flag); + + IF (GT_16(mind1, tmp1)) + { + pos = pos2; + move16(); + } + ELSE + { + pos = add(pos, add(sub(pos2, delta), 1)); + } + pos = add(pos, add(lin, mind1)); + } + + return pos; +} + +static Word16 FEC_phase_matching_fx( + HQ_NBFEC_HANDLE st_fx, /* i : Decoder State */ + Word32 *ImdctOut_fx, /* i : input */ + Word16 *auOut_fx, /* o : output audio */ + Word16 *OldauOut_fx, + Word16 OldauOut_pha_fx[2][N_LEAD_NB] +) +{ + Word16 i; + Word16 pos, remain; + Word16 ol_size; + Word16 L_overlap, L; + Word16 ImdctOutWin_fx[2*L_FRAME8k]; + Word16 OldauOutnoWin_fx[L_FRAME8k]; + Word16 OldauOut2_fx[L_FRAME8k]; + Word16 win_NB_fx[L_FRAME8k + 25]; + Word16 exp1, exp2, tmp; + Word32 pow1_fx, pow22_fx; + Word16 SmoothingWin_NB3_fx[24]; + + L = L_FRAME8k; + move16(); + ol_size = 2*L/20; + move16(); + L_overlap = 3*L/20; + move16(); + + FOR (i=0; iold_auOut_2fr_fx, st_fx->old_Min_ind_fx, L); + + IF (pos == 0) + { + return 1; + } + + /* Repetition */ + remain = L+N_Z_L_NB - ((2*L)-pos); + move16(); + Copy(&st_fx->old_auOut_2fr_fx[pos], &ImdctOutWin_fx[N_ZERO_NB], (2*L)-pos); + + /* OldauOut without windowing */ + FOR (i = N_ZERO_NB; i < L/2; i++) + { + OldauOutnoWin_fx[i-N_ZERO_NB] = extract_l( L_shr( L_negate(st_fx->oldIMDCTout_fx[L/2 - 1 - i]), 6 ) ); + } + FOR(i = 0; i < L/2; i++) + { + OldauOutnoWin_fx[i+N_ZERO_O_NB] = extract_l( L_shr( L_negate(st_fx->oldIMDCTout_fx[i]), 6 ) ); + } + + Copy(OldauOutnoWin_fx, &ImdctOutWin_fx[N_ZERO_NB+(2*L)-pos], remain); + + pow1_fx = L_deposit_l(0); + pow22_fx = L_deposit_l(0); + FOR (i = 0; i < L; i++) + { + pow1_fx = L_add(pow1_fx, shr(abs_s(st_fx->old_auOut_2fr_fx[L+i]), 1)); + pow22_fx = L_add(pow22_fx, shr(abs_s(ImdctOutWin_fx[N_ZERO_NB+i]), 1)); + } + IF(pow22_fx != 0) + { + exp1 = sub(norm_l(pow1_fx), 1); + exp2 = norm_l(pow22_fx); + tmp = div_s(extract_h(L_shl(pow1_fx, exp1)), extract_h(L_shl(pow22_fx, exp2)));/*15 + exp1 - exp2*/ + tmp = shl(tmp, sub(sub(exp2, exp1), 1));/*14*/ + FOR (i = N_ZERO_NB; i < 2*L; i++) + { + ImdctOutWin_fx[i] = shl(mult(ImdctOutWin_fx[i], tmp), 1); + } + } + Smoothing_vector_NB_fx(OldauOutnoWin_fx, &ImdctOutWin_fx[N_ZERO_NB], SmoothingWin_NB2_fx, auOut_fx, ol_size); + + FOR (i = 0; i < L/2; i++) + { + /*ImdctOutWin[3*L/2 + i] *= win_NB[L/2-i-1];*/ + ImdctOutWin_fx[3*L/2 + i] = mult(ImdctOutWin_fx[3*L/2 + i], win_NB_fx[L/2-i-1]); + move16(); + } + + FOR (i = N_ZERO_NB; i < L/2; i++) + { + /*ImdctOutWin_fx[L + i] *= win_NB_fx[(L-1-i)];*/ + ImdctOutWin_fx[L + i] = mult(ImdctOutWin_fx[L + i], win_NB_fx[(L-1-i)]); + move16(); + } + + Copy(&ImdctOutWin_fx[N_Z_L_O_NB], &OldauOut_pha_fx[0][0], N_LEAD_NB); + Copy(&ImdctOutWin_fx[ol_size+N_ZERO_NB], &auOut_fx[ol_size], N_Z_L_NB-ol_size); + Copy(&ImdctOutWin_fx[L], &auOut_fx[N_Z_L_NB], N_ZERO_NB); + Copy(&ImdctOutWin_fx[L], OldauOut_fx, L); + + FOR (i = 0; i < L/2; i++) + { + OldauOut2_fx[i] = extract_l( L_shr( L_negate(ImdctOut_fx[L/2 - 1 - i]), 6 ) ); + OldauOut2_fx[L/2+i] = extract_l( L_shr( L_negate(ImdctOut_fx[i]), 6 ) ); + } + + Smoothing_vector_NB_fx(&ImdctOutWin_fx[N_Z_L_O_NB], &OldauOut2_fx[N_ZERO_NB], SmoothingWin_NB3_fx, &OldauOut_pha_fx[1][0], L_overlap); + + FOR (i=L_overlap; i Q0 */ + } + FOR (i = 0; i < L/2; i++) + { + /*OldauOut[i+N_ZERO_O_NB] = -OldImdctOut[i];*/ + OldauOut_fx[i+N_ZERO_O_NB] = extract_l( L_shr( L_negate(OldImdctOut_fx[i]), 6 )); /* Q6 -> Q0 */ + } + + /* Overlapping with next good frame : Overlapping to remove the discontinuity */ + IF (cur_data_use_flag) + { + ol_size = N_LEAD_NB; + move16(); + + FOR (i = N_ZERO_NB; i < L/2; i++) + { + /* ImdctOutWin[i+L] = -ImdctOut[L/2 - 1 - i]; */ + ImdctOutWin_fx[i+L] = extract_l( L_shr( L_negate(ImdctOut_fx[L/2 - 1 - i]), 6 ) ); + } + FOR (i = 0; i < L/2; i++) + { + ImdctOutWin_fx[i+3*L/2] = extract_l( L_shr( L_negate(ImdctOut_fx[i]), 6 ) ); + } + + /*a = (float)(1./(float)(ol_size)); y = ax */ + Smoothing_vector_scaledown_NB_fx(OldauOut_fx, &ImdctOutWin_fx[N_Z_L_O_NB], SmoothingWin_NB875_fx, OldauOut_fx, ol_size); + + /* Scale down the overlapped signal */ + Scaledown_fx(&ImdctOutWin_fx[ol_size+N_Z_L_O_NB], &OldauOut_fx[ol_size], 23170, N_Z_L_NB-ol_size); + } + + L_overlap = overlap_time; + move16(); + FOR (i = 0; i < L_overlap; i++) + { + /*OldauOut[i] *= SmoothingWin_NB875[L_overlap-i-1];*/ + OldauOut_fx[i] = mult(OldauOut_fx[i], SmoothingWin_NB875_fx[L_overlap-i-1]); + move16(); + } + FOR (i=L_overlap; i < L; i++) + { + OldauOut_fx[i] = 0; + move16(); + } + + /* Windowing */ + /*Windowing_1st_NB(ImdctOutWin, ImdctOut, win_NB, SmoothingWin_NB875, 1);*/ + /*Windowing_2nd_NB(ImdctOutWin, ImdctOut, win_NB);*/ + Windowing_1st_NB_fx(ImdctOutWin_fx, ImdctOut_fx, win_NB_fx, SmoothingWin_NB875_fx, 1); + Windowing_2nd_NB_fx(ImdctOutWin_fx, ImdctOut_fx, win_NB_fx); + + /*v_add(&ImdctOutWin[N_ZERO_NB], OldauOut, auOut, L);*/ + /*mvr2r(&ImdctOutWin[L], OldauOut, L);*/ + FOR (i = 0; i < L; i++) + { + auOut_fx[i] = add(ImdctOutWin_fx[N_ZERO_NB + i], OldauOut_fx[i]); + move16(); + } + Copy(&ImdctOutWin_fx[L], OldauOut_fx, L); + + return; +} + +static Word16 Repetition_smoothing_fx( + const Word32 *ImdctOut_fx, /* i : input */ + Word16 *auOut_fx, /* o : output audio */ + Word32 *OldImdctOut_fx, /* i : input */ + Word16 *OldauOut_fx, /* i/o: audio from previous frame */ + const Word16 L, /* i : length */ + Word16 *prev_oldauOut_fx, /* i : OldauOut from previous frame */ + Word16 overlap_time /* i : overlap time */ +) +{ + Word16 i; + Word32 pow1_fx; + Word32 pow22_fx; + Word16 ImdctOutWin_fx[2*L_FRAME8k]; + Word16 OldauOutnoWin_fx[L_FRAME8k]; + Word16 win_NB_fx[L_FRAME8k + 25]; + + FOR (i=0; i L_add(pow1_fx, L_shl(pow1_fx, 1))) + { + return 1; + } + + /* Update the OldauOut array for next overlapping */ + Copy(&ImdctOutWin_fx[L], OldauOut_fx, L); + Scaledown_fx(prev_oldauOut_fx, prev_oldauOut_fx, 23170, L); + + return 0; +} + +static void common_overlapping_fx( + Word16 *auOut_fx, /* i : Input */ + Word16 *ImdctOutWin_fx, /* o : Output */ + Word16 *OldauOut_fx, /* i : Window */ + Word16 end1, /* i : Decay */ + Word16 offset1, + Word16 start2, + Word16 end2, + Word16 offset_i2, + Word16 offset2 +) +{ + Word16 i; + + /* Common Overlapping */ + FOR (i=0 ; i < end1; i++) + { + /*auOut_fx[i] = L_add(ImdctOutWin_fx[i+7*L/20], OldauOut_fx[i+offset1]);*/ + auOut_fx[i] = add(ImdctOutWin_fx[i+N_ZERO_NB], OldauOut_fx[i+offset1]); + move16(); + } + FOR (i=start2 ; i < end2; i++) + { + /*auOut_fx[i+offset2] = ImdctOutWin_fx[i+offset_i2]; move32();*/ + auOut_fx[i+offset2] = ImdctOutWin_fx[i+offset_i2]; + move16(); + } + + return; +} + + +static void Smoothing_vector_NB_fx( + const Word16 OldauOutnoWin_fx[], /* i : Input vector 1 */ + const Word16 ImdctOutWin_fx[], /* i : Input vector 2 */ + const Word16 SmoothingWin_fx[], /* i : Smoothing window */ + Word16 auOut_fx[], /* o : Output vector that contains vector 1 .* vector 2 */ + const Word16 ol_size /* i : Overlap size */ +) +{ + Word16 i; + Word16 weight_fx; + + FOR (i=0 ; i < ol_size; i++) + { + weight_fx = SmoothingWin_fx[i]; + move16(); + auOut_fx[i] = add(mult(OldauOutnoWin_fx[i], sub(32767, weight_fx)), mult(ImdctOutWin_fx[i], weight_fx)); + move16(); + } + + return; +} + + +static void Windowing_1st_NB_fx( + Word16 *ImdctOutWin_fx, /* o : Output */ + const Word32 *ImdctOut_fx, /* i : Input */ + const Word16 *win_fx, /* i : Window */ + const Word16 *smoothingWin_fx, /* i : Smoothing Window */ + Word16 smoothing_flag /* i : 1=Smoothing window, 0=Original window */ +) +{ + Word16 i; + Word16 L; + + L = L_FRAME8k; + move16(); + IF ( smoothing_flag == 0 ) + { + FOR (i = N_ZERO_NB; i < L/2; i++) + { + /*ImdctOutWin[i] = ImdctOut[L/2 + i] * win[(2*L-1-i)-N_LEAD_O_NB];*/ + ImdctOutWin_fx[i] = extract_l( L_shr( Mult_32_16(ImdctOut_fx[L/2 + i], win_fx[(2*L-1-i)-N_LEAD_O_NB]), 6 )); + } + + FOR (i = 0; i < N_ZERO_O_NB; i++) + { + /*ImdctOutWin[L/2 + i] = -ImdctOut[L - 1 - i] * win[(3*L/2-1-i)-N_LEAD_O_NB];*/ + /*ImdctOutWin[3*L/2 + i] = -ImdctOut[i] * win[(L/2-i-1)];*/ + ImdctOutWin_fx[L/2 + i] = extract_l( L_shr( Mult_32_16(L_negate(ImdctOut_fx[L - 1 - i]), win_fx[(3*L/2-1-i)-N_LEAD_O_NB]), 6 )); + ImdctOutWin_fx[3*L/2 + i] = extract_l( L_shr( Mult_32_16(L_negate(ImdctOut_fx[i]), win_fx[(L/2-i-1)]), 6 )); + } + } + ELSE + { + FOR (i = N_ZERO_NB; i < L/2; i++) + { + /*ImdctOutWin[i] = ImdctOut[L/2 + i] * smoothingWin[(i-N_ZERO_NB)];*/ /*win[(2*L-i)*decimate-1-decay-14*L_FRAME48k/20];*/ + ImdctOutWin_fx[i] = extract_l( L_shr( Mult_32_16(ImdctOut_fx[L/2 + i], smoothingWin_fx[(i-N_ZERO_NB)]), 6 )); /*win[(2*L-i)*decimate-1-decay-14*L_FRAME48k/20];*/ + } + + FOR (i = 0; i < N_ZERO_O_NB; i++) + { + /*ImdctOutWin[L/2 + i] = -ImdctOut[L - 1 - i] * smoothingWin[(i+N_ZERO_O_NB)];*/ /*win[(3*L/2-1-i)*decimate+decay-L_FRAME48k*14/20];*/ + /*ImdctOutWin[3*L/2 + i] = -ImdctOut[i] * win[(L/2-i-1)];*/ + ImdctOutWin_fx[L/2 + i] = extract_l( L_shr( Mult_32_16(L_negate(ImdctOut_fx[L - 1 - i]), smoothingWin_fx[(i+N_ZERO_O_NB)]), 6 )); /*win[(3*L/2-1-i)*decimate+decay-L_FRAME48k*14/20];*/ + ImdctOutWin_fx[3*L/2 + i] = extract_l( L_shr( Mult_32_16(L_negate(ImdctOut_fx[i]), win_fx[(L/2-i-1)]), 6 )); + } + } + + return; +} +static void Windowing_2nd_NB_fx( + Word16 *ImdctOutWin_fx, /* o : Output */ + const Word32 *ImdctOut_fx, /* i : Input */ + const Word16 *win_fx /* i : Window */ +) +{ + Word16 i; + Word16 L; + + L = L_FRAME8k; + move16(); + FOR (i = N_ZERO_O_NB; i < L/2; i++) + { + /*ImdctOutWin[L/2 + i] = -ImdctOut[L - 1 - i];*/ + /*ImdctOutWin[3*L/2 + i] = -ImdctOut[i] * win[L/2-i-1];*/ + ImdctOutWin_fx[L/2 + i] = extract_l( L_shr( L_negate(ImdctOut_fx[L - 1 - i]), 6 )); + ImdctOutWin_fx[3*L/2 + i] = extract_l( L_shr( Mult_32_16(L_negate(ImdctOut_fx[i]), win_fx[L/2-i-1]), 6 )); + } + + FOR (i = 0; i < N_ZERO_NB; i++) + { + /*ImdctOutWin[L + i] = -ImdctOut[L/2 - 1 - i];*/ + ImdctOutWin_fx[L + i] = extract_l( L_shr( L_negate(ImdctOut_fx[L/2 - 1 - i]), 6 )); + } + + FOR (i = N_ZERO_NB; i < L/2; i++) + { + /*ImdctOutWin[L + i] = -ImdctOut[L/2 - 1 - i] * win[L - 1 - i];*/ + ImdctOutWin_fx[L + i] = extract_l( L_shr( Mult_32_16(L_negate(ImdctOut_fx[L/2 - 1 - i]), win_fx[L - 1 - i]), 6 )); + } + + return; +} + +static void Smoothing_vector_scaledown_NB_fx( + const Word16 OldauOutnoWin_fx[], /* i : Input vector 1 */ + const Word16 ImdctOutWin_fx[], /* i : Input vector 2 */ + const Word16 SmoothingWin_fx[], /* i : Smoothing window */ + Word16 auOut_fx[], /* o : Output vector that contains vector 1 .* vector 2 */ + const Word16 ol_size /* i : Overlap size */ + +) +{ + Word16 i; + Word16 weight_fx; + + FOR (i=0 ; i < ol_size; i++) + { + weight_fx = SmoothingWin_fx[i]; + move16(); + auOut_fx[i] = add(mult(OldauOutnoWin_fx[i], sub(32767, weight_fx)), + mult(ImdctOutWin_fx[i], mult_r(23170, weight_fx))); + move16(); + } + + return; +} + + +static void Scaledown_fx( + Word16 x[], /* i : Input vector */ + Word16 y[], /* o : Output vector that contains vector 1 .* vector 2 */ + Word16 scale_v, /*Q15 */ + const Word16 N /* i : Overlap size */ +) +{ + Word16 i; + + FOR (i=0; ihHQ_nbfec; + hHQ_core = st_fx->hHQ_core; + + IF(hHQ_core->Q_old_wtda != 0) + { + Scale_sig(hHQ_core->old_out_fx, output_frame, negate(hHQ_core->Q_old_wtda)); + hHQ_core->Q_old_wtda = 0; + move16(); + } + + test(); + test(); + test(); + test(); + test(); + test(); + IF( (EQ_16(st_fx->nbLostCmpt, 1))&&(EQ_16(hHQ_nbfec->phase_mat_flag_fx,1))&&(EQ_16(hHQ_nbfec->phase_mat_next_fx,0))) + { + IF (FEC_phase_matching_fx(hHQ_nbfec, wtda_audio_fx, out_fx, hHQ_core->old_out_fx, hHQ_nbfec->old_out_pha_fx) ) + { + /* window_ola( wtda_audio, out, st->old_out, output_frame, 0, 0, 0 ); */ + window_ola_fx(wtda_audio_fx, out_fx, Q_synth, hHQ_core->old_out_fx, &hHQ_core->Q_old_wtda, output_frame, ALDO_WINDOW, ALDO_WINDOW, 0, 0, 0 ); + hHQ_nbfec->phase_mat_next_fx = 0; + move16(); + } + ELSE + { + hHQ_nbfec->phase_mat_next_fx = 1; + move16(); + *Q_synth = 0; + move16(); + } + } + ELSE IF((EQ_16(st_fx->prev_bfi, 1))&&(st_fx->bfi==0)&&(EQ_16(hHQ_nbfec->phase_mat_next_fx,1))) + { + FEC_phase_matching_nextgood_fx( wtda_audio_fx, out_fx, hHQ_core->old_out_fx, hHQ_nbfec->old_out_pha_fx, mean_en_high_fx); + + hHQ_nbfec->phase_mat_next_fx = 0; + move16(); + *Q_synth = 0; + move16(); + } + ELSE IF((EQ_16(st_fx->prev_bfi, 1))&&(EQ_16(st_fx->bfi,1))&&(EQ_16(hHQ_nbfec->phase_mat_next_fx,1))) + { + FEC_phase_matching_burst_fx( wtda_audio_fx, out_fx, hHQ_core->old_out_fx, hHQ_nbfec->old_out_pha_fx, hHQ_nbfec->prev_oldauOut_fx); + hHQ_nbfec->phase_mat_next_fx = 1; + move16(); + *Q_synth = 0; + move16(); + } + ELSE + { + /*n4 = (short)(N_LEAD_MDCT*(float)(output_frame/20));*/ + test(); + IF (st_fx->bfi == 0 && EQ_16(st_fx->prev_bfi, 1)) + { + test(); + IF((EQ_16(hHQ_nbfec->stat_mode_out_fx, 1))||(LT_16(hHQ_nbfec->diff_energy_fx,ED_THRES_50P_fx)))/* Q11 */ + { + Word16 tmp; + + tmp = 0; + if( GT_16(st_fx->old_bfi_cnt_fx,1)) + { + tmp = 1; + } + Repetition_smoothing_nextgood_fx( wtda_audio_fx, out_fx, hHQ_nbfec->oldIMDCTout_fx, hHQ_core->old_out_fx, tmp, N_LEAD_NB); + *Q_synth = 0; + move16(); + } + ELSE IF(GT_16(st_fx->old_bfi_cnt_fx, 1)) + { + Next_good_after_burst_erasures_fx( wtda_audio_fx, out_fx, hHQ_core->old_out_fx, N_LEAD_NB ); + *Q_synth = 0; + move16(); + } + ELSE + { + /*window_ola( wtda_audio, out, st->old_out, output_frame, 0, 0, 0); */ + window_ola_fx( wtda_audio_fx, out_fx, Q_synth, hHQ_core->old_out_fx, &hHQ_core->Q_old_wtda, output_frame, + st_fx->hTcxCfg->tcx_last_overlap_mode, st_fx->hTcxCfg->tcx_curr_overlap_mode, st_fx->prev_bfi, hHQ_core->oldHqVoicing_fx , hHQ_core->oldgapsynth_fx ); + } + } + ELSE /* if(st->bfi == 1) */ + { + test(); + IF( (EQ_16(hHQ_nbfec->stat_mode_out_fx, 1))||(LT_16(hHQ_nbfec->diff_energy_fx,ED_THRES_50P_fx))) + { + /* if( window_ola_bfi( wtda_audio, out, st->oldIMDCTout, st->old_out, output_frame, st->prev_oldauOut, N_LEAD_NB) ) */ + IF( Repetition_smoothing_fx( wtda_audio_fx, out_fx, hHQ_nbfec->oldIMDCTout_fx, hHQ_core->old_out_fx, output_frame, hHQ_nbfec->prev_oldauOut_fx, N_LEAD_NB) ) + { + /*window_ola( wtda_audio, out, st->old_out, output_frame, 0, 0, 0);*/ + window_ola_fx( wtda_audio_fx, out_fx, Q_synth, hHQ_core->old_out_fx, &hHQ_core->Q_old_wtda, output_frame, + st_fx->hTcxCfg->tcx_last_overlap_mode, st_fx->hTcxCfg->tcx_curr_overlap_mode, st_fx->prev_bfi, hHQ_core->oldHqVoicing_fx , hHQ_core->oldgapsynth_fx ); + } + ELSE + { + *Q_synth = 0; + move16(); + } + } + ELSE + { + /*window_ola( wtda_audio, out, st->old_out, output_frame, 0, 0, 0 );*/ + window_ola_fx( wtda_audio_fx, out_fx, Q_synth, hHQ_core->old_out_fx, &hHQ_core->Q_old_wtda, output_frame, + st_fx->hTcxCfg->tcx_last_overlap_mode, st_fx->hTcxCfg->tcx_curr_overlap_mode, st_fx->prev_bfi, hHQ_core->oldHqVoicing_fx , hHQ_core->oldgapsynth_fx ); + } + } + hHQ_nbfec->phase_mat_next_fx = 0; + move16(); + } + + return; +} + +static void Next_good_after_burst_erasures_fx( + const Word32 *ImdctOut_fx, + Word16 *auOut_fx, + Word16 *OldauOut_fx, + const Word16 ol_size +) +{ + Word16 i, L; + Word16 ImdctOutWin_fx[2*L_FRAME48k]; + Word16 win_NB_fx[L_FRAME8k + 25]; + + L = L_FRAME8k; + move16(); + FOR (i=0; ielement_mode) + { + case EVS_MONO: + post_hq_delay = NS2SA(st->output_Fs, POST_HQ_DELAY_NS); + break; + case IVAS_SCE: + post_hq_delay = NS2SA(st->output_Fs, DELAY_CLDFB_NS); + break; + case IVAS_CPE_DFT: + if (hCPE->nchan_out == 1 && hCPE->hStereoDft->hConfig->res_cod_mode == STEREO_DFT_RES_COD_OFF) + { + post_hq_delay = NS2SA(st->output_Fs, DELAY_CLDFB_NS); + } + else + { + post_hq_delay = 0; + } + break; + default: + post_hq_delay = 0; + break; + } + + + if ((st->codec_mode == MODE1 && st->hTcxDec != NULL) && ((st->core == ACELP_CORE && !(st->bfi == 1 && st->con_tcx == 1)) || st->core == HQ_CORE)) + { + mvr2r(st->hTcxDec->synth_history + output_frame, st->hTcxDec->synth_history, output_frame - post_hq_delay + NS2SA(st->output_Fs, PH_ECU_MEM_NS)); + mvr2r(output, st->hTcxDec->old_synthFB + output_frame - post_hq_delay, output_frame); + + if (st->element_mode == EVS_MONO) + { + /* reset the remaining buffer, which is read in TCX concealment the necessary samples to fill + this buffer are not available for all cases, the impact on the output is limited */ + set_f(st->hTcxDec->old_synthFB + 2 * output_frame - post_hq_delay, 0.f, post_hq_delay); + if (output_frame >= L_FRAME16k) + { + mvr2r(st->prev_synth_buffer, st->hTcxDec->old_synthFB + 2 * output_frame - NS2SA(st->output_Fs, DELAY_BWE_TOTAL_NS), NS2SA(st->output_Fs, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS)); + } + else + { + mvr2r(st->hHQ_core->old_out + NS2SA(st->output_Fs, N_ZERO_MDCT_NS), st->hTcxDec->old_synthFB + 2 * output_frame, NS2SA(st->output_Fs, PH_ECU_LOOKAHEAD_NS)); + } + + if (st->core != ACELP_CORE) + { + if (output_frame >= L_FRAME16k) + { + mvr2r(st->delay_buf_out, st->hTcxDec->old_synthFB + 2 * output_frame - NS2SA(st->output_Fs, DELAY_CLDFB_NS), NS2SA(st->output_Fs, DELAY_CLDFB_NS)); + mvr2r(st->hHQ_core->old_out + NS2SA(st->output_Fs, N_ZERO_MDCT_NS), st->hTcxDec->old_synthFB + 2 * output_frame, NS2SA(st->output_Fs, PH_ECU_LOOKAHEAD_NS)); + } + else + { + mvr2r(st->delay_buf_out, st->hTcxDec->old_synthFB + 2 * output_frame - NS2SA(st->output_Fs, DELAY_BWE_TOTAL_NS), NS2SA(st->output_Fs, DELAY_CLDFB_NS)); + mvr2r(st->hHQ_core->old_out + NS2SA(st->output_Fs, N_ZERO_MDCT_NS), st->hTcxDec->old_synthFB + 2 * output_frame - NS2SA(st->output_Fs, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS), NS2SA(st->output_Fs, PH_ECU_LOOKAHEAD_NS)); + } + } + } + else + { + if (st->core != ACELP_CORE) + { + mvr2r(st->delay_buf_out, st->hTcxDec->old_synthFB + 2 * output_frame - post_hq_delay, post_hq_delay); + mvr2r(st->hHQ_core->old_out + NS2SA(st->output_Fs, N_ZERO_MDCT_NS), st->hTcxDec->old_synthFB + 2 * output_frame, NS2SA(st->output_Fs, PH_ECU_LOOKAHEAD_NS)); + } + } + } + + return; +} +#endif \ No newline at end of file diff --git a/lib_dec/FEC_HQ_phase_ecu_fx.c b/lib_dec/FEC_HQ_phase_ecu_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..d6a65de422813c8ecfb1615104813898e9301596 --- /dev/null +++ b/lib_dec/FEC_HQ_phase_ecu_fx.c @@ -0,0 +1,3451 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include +#include "options.h" /* Compilation switches */ +#include "rom_dec.h" /* Static table prototypes */ +#include "rom_com.h" /* Static table prototypes */ +#include "prot_fx1.h" +#include "prot_fx2.h" +#include "basop_util.h" + +/*---------------------------------------------------------------------* + * Local constants + *---------------------------------------------------------------------*/ + +#define FEC_MAX 512 +#define FEC_NB_PULSE_MAX 20 +#define FEC_FFT_MAX_SIZE 512 +#define FEC_DCIM_FILT_SIZE_MAX 60 + +#define ENV_STAB_DEC_THR 16384 /* Q15 st->env_stab based threshold for hq-ecu technology decision */ + +#define PHASE_DITH_fx 25736 /* 2*pi in Q12 */ +#define DELTA_CORR 6 /* Tuning parameter - defining range for phase correction around peak */ +#define THRESH_TR_DB_FX 10 +#define THRESH_TR_LIN_BY2_FX (10/2) /* 10.0^(THRESH_TR_DB_FX/10.0)/2. Divided by 2 to facilitate fixed-point implementation. */ +#define MAX_INCREASE_GRPPOW_FX 0 /* max. amplification in case of transients (in dB scale) */ +#define MAX_INCREASE_GRPPOW_LIN_FX 32767 /* in Q15-- 10.0^(MAX_INCREASE_GRPPOW_FX/10.0) (in linear scale) */ + +#define PHASE_DITH_SCALE_SHIFT 16 /* The number of bit shift equivalent to multiply by PHASE_DITH_SCALE */ + +#define BURST_PHDITH_THRESH (4-1) /* speech start phase dither with losses in a row */ +#define BURST_PHDITH_RAMPUP_LEN 2 /* speech ramp up degree of phase dither over a length of frames */ +#define BURST_ATT_THRESH (3-1) /* speech start attenuate with losses in a row */ +#define ATT_PER_FRAME 4 /* speech attenuation in dB */ +#define BETA_MUTE_THR 10 /* time threshold to start beta-noise attenuation */ + +#define LGW32K 7 +#define LGW16K 6 +#define LGW48K LGW32K+1 /* Use the same frequency groups as for SWB + 1 */ + +#define LTRANALOG32K 8 +#define LTRANALOG16K 7 +#define PFIND_SENS_FX 31785 /* 0.97 in Q15 */ +#define CMPLMNT_PFIND_SENS_FX 983 /* (1.0 - pfind_sen) in Q15 */ + +#ifdef IVAS_FEC_ECU_TO_COMPLETE +#define DELTA_CORR_F0_INT 2 /* Constant controls the bin range where Jacobsen is used */ +#define ST_PFIND_SENS 0.93f /* peakfinder sensitivity */ +#define L_PROT_NS 32000000L /* Prototype frame length in nanoseconds (32 ms) */ +#define PH_ECU_CORR_LIMIT 0.85f /* Correlation limit for IVAS Phase ECU activation */ +#define PH_ECU_N_LIMIT 56 /* fec_alg analysis frame limit for IVAS Phase ECU activation */ +#endif + +#define FEC_HQ_ECU_POINT5 (0x4000) /* 0.5 in Q15. Prefix with FEC_HQ namespace to avoid naming conflict. */ +#define FEC_HQ_ECU_ROOT2 (0x5a83) /* sqrt(2) in Q14 */ +#define FEC_HQ_HAMM_A0 17695 /* 0.54 in Q15 */ +#define FEC_HQ_HAMM_A1 15073 /* 0.46 in Q15 */ +#define FEC_HQ_WIN_A0 FEC_HQ_HAMM_A0 +#define FEC_HQ_WIN_A1 FEC_HQ_HAMM_A1 + + +static Word16 sqrt2ndOrder(const Word16); + +static void windowing(const Word16*, Word16*, const Word16*, const Word16, const Word16); +static void windowing_ROM_optimized(const Word16*, Word16*, const Word16, const Word16, const Word16); +static void fft_spec2_fx(const Word16 [], Word32 [], const Word16); +static void trans_ana_fx(const Word16*, Word16*, Word16*, Word16*, const Word16, const Word16, const Word16,const Word16,Word16*, Word16*, Word16*, Word16*); +static void peakfinder_fx(const Word16*, const Word16, Word16*, Word16*, const Word16 +#ifdef IVAS_FEC_ECU_TO_COMPLETE + , const Word16 endpoints /* i : Flag to include endpoints in peak search */ +#endif + ); +static Word16 imax_fx( const Word16 *, const Word16); +static void spec_ana_fx(const Word16* prevsynth, Word16* plocs, Word32* plocsi, Word16* num_plocs, Word16* X_sav, const Word16 output_frame, const Word16 bwidth_fx, Word16* Q +#ifdef IVAS_FEC_ECU_TO_COMPLETE + , const Word16 element_mode, Word16* noise_fac, const Word16 pcorr +#endif + ); +static void subst_spec_fx(const Word16*, const Word32*, Word16*, const Word16, Word16*, const Word16*, const Word16, const Word16*, const Word16, Word16* + ,const Word16*, const Word16*, Word16, const Word16*); +static Word16 rand_phase_fx(const Word16 seed, Word16 *sin_F, Word16 *cos_F); +#ifdef IVAS_FEC_ECU_TO_COMPLETE +static float imax2_jacobsen_mag(const float* y_re, const float* y_im); +#endif + +/*------------------------------------------------------------------* + * rand_phase() + * + * randomized phase in form of sin and cos components + *------------------------------------------------------------------*/ +static Word16 rand_phase_fx(const Word16 seed, Word16 *sin_F, Word16 *cos_F) +{ + const Word16 *sincos = sincos_t_ext_fx + 128; + Word16 seed2 = own_random2_fx(seed); + Word16 seed2_shift = shr(seed2, 8); + + *sin_F = negate(*(sincos + seed2_shift)); + move16(); + if (s_and(seed2, 0x40) != 0) + { + *sin_F = *(sincos + seed2_shift); + move16(); + } + + *cos_F = negate(*(sincos - seed2_shift)); + move16(); + if (s_and(seed2, 0x80) != 0) + { + *cos_F = *(sincos - seed2_shift); + move16(); + } + + return seed2; +} +#ifdef IVAS_FEC_ECU_TO_COMPLETE +/*----------------------------------------------------------------------------- + * imax2_jacobsen_mag() + * + * refine peak interpolation using jacobsen and periodic speca ana windows + *----------------------------------------------------------------------------*/ + + /*! r: The location, relative to the middle of the 3 given data point, of the maximum. (Q15)*/ +static float imax2_jacobsen_mag( + const float* y_re, /* i : The 3 given data points. real part order -1 0 1 */ + const float* y_im /* i : The 3 given data points. imag part order 1 0 -1 (from FFT) */ +) +{ + float posi; + const float* pY; + float y_m1_re, y_0_re, y_p1_re; + float y_m1_im, y_0_im, y_p1_im; + float N_re, N_im; + float D_re, D_im; + float numer, denom; + + /* Jacobsen estimates peak offset relative y_0 using + * X_m1 - X_p1 + * d = REAL ( ------------------- ) * c_jacob + * 2*X_0 - X_m1 -Xp1 + * + * Where c_jacob is a window dependent constant + */ +#define C_JACOB 1.1453f /* % assume 0.1875 hammrect window 'symmetric' */ + + /* Get the bin parameters into variables */ + pY = y_re; + y_m1_re = *pY++; + y_0_re = *pY++; + y_p1_re = *pY++; + + /* Same for imaginary parts - note reverse order from FFT */ + pY = y_im; + y_p1_im = *pY++; + y_0_im = *pY++; + y_m1_im = *pY++; + + /* prepare numerator real and imaginary parts*/ + N_re = y_m1_re - y_p1_re; + N_im = y_m1_im - y_p1_im; + + /* prepare denominator real and imaginary parts */ + + D_re = 2 * y_0_re - y_m1_re - y_p1_re; + D_im = 2 * y_0_im - y_m1_im - y_p1_im; + + /* REAL part of complex division */ + numer = N_re * D_re + N_im * D_im; + denom = D_re * D_re + D_im * D_im; + + test(); + if (numer != 0 && denom != 0) + { + posi = numer / denom * C_JACOB; + } + else + { + posi = 0; /* flat top, division is not possible choose center freq */ + } + + return posi; +} +#endif + +/*----------------------------------------------------------------------------- + * fft_spec2_fx() + * + * Square magnitude of fft spectrum + *----------------------------------------------------------------------------*/ +static void fft_spec2_fx( + const Word16 x[], /* i : Input vector: complex spectrum */ + Word32 xMagSq[], /* o : Magnitude square spectrum */ + const Word16 N /* i : Input vector length */ +) +{ + Word16 i, l; + const Word16 *pRe, *pIm; + Word32 *pMagSq, acc; + + /* Magnitude at 0. */ + pMagSq = &xMagSq[0]; + pRe = &x[0]; + *pMagSq++ = L_mult0(*pRe, *pRe); + pRe++; /* Non-fractional multiply gives subsequent group power accumulation a bit headroom. */ + + /* From 1 to (N/2 - 1). */ + l = sub(shr(N, 1), 1); /* N/2 - 1. */ + pIm = &x[N]; + pIm--; + FOR (i = 0; i < l; i++) + { + acc = L_mult0(*pRe, *pRe); + pRe++; /* Non-fractional mode multiply. */ + *pMagSq++ = L_mac0(acc, *pIm, *pIm); + pIm--; + move32(); + } + + /* The magnitude square at N/2 */ + *pMagSq = L_mult0(*pRe, *pRe); + move32(); + return; +} + +/*----------------------------------------------------------------------------- + * trans_ana_fx() + * + * Transient analysis + *----------------------------------------------------------------------------*/ +static void trans_ana_fx( + const Word16 *xfp, /* i : Input signal Q0 */ + Word16 *mag_chg, /* o : Magnitude modification Q15 */ + Word16 *ph_dith, /* o : Phase dither, 2*PI is not included (Q15, i.e., between 0.0 and 1.0) */ + Word16 *mag_chg_1st, /* i/o: per band magnitude modifier for transients Q15 */ + const Word16 output_frame, /* i : Frame length */ + const Word16 time_offs, /* i : Time offset (integral multiple of output_frame) */ + const Word16 est_mus_content, /* i : 0.0=speech_like ... 1.0=Music (==st->env_stab ) */ + const Word16 last_fec, /* i : signal that previous frame was concealed with fec_alg */ + Word16 *alpha, /* o : Magnitude modification factors for fade to average */ + Word16 *beta, /* o : Magnitude modification factors for fade to average */ + Word16 *beta_mute, /* o : Factor for long-term mute */ + Word16 *Xavg /* o : Frequency group average gain to fade to */ +) +{ + const Word16 *w_hamm, *pFftTbl; + Word16 att_val, attDegreeFrames; + Word16 xfp_left[L_TRANA48k], xfp_right[L_TRANA48k]; + Word32 magSqLeft[L_TRANA48k/2+1], magSqRight[L_TRANA48k/2+1]; + Word32 *pLeft, *pRight, *pGrPowLeft, *pGrPowRight; + Word32 gr_pow_left[LGW_MAX], gr_pow_right[LGW_MAX]; + const Word16 *pXfp, *pGw; + Word16 Ltrana, Ltrana_2, Lprot, three4thLength, LtranaLogMinus1, Lgw, i, k, l, burst_len; + Word16 man, expo; + Word16 att_always = 0; /* fixed attenuation per frequency group if set to 1 */ + Word16 oneOverFrame, roundEstMusContent, tmp16, headroom, lowerEdge; + Word16 burst_phdith_thresh = BURST_PHDITH_THRESH; /*speech settings */ + Word16 burst_att_thresh = BURST_ATT_THRESH ; + Word16 att_per_frame = ATT_PER_FRAME; + Word16 burst_phdith_rampup_len = BURST_PHDITH_RAMPUP_LEN; + Word16 tr_dec[LGW_MAX]; + UWord16 lsb; + Word32 acc; + + Lgw = 0; + LtranaLogMinus1 = 0; + pFftTbl = NULL; + + /* Initialisation to prevent warnings */ + oneOverFrame = 102; /* 1/320 in Q15 */ move16(); + w_hamm = w_hamm16k_2_fx; + move16(); + Lprot = 512; + move16(); + + /* check burst error */ + IF (EQ_16(output_frame, L_FRAME48k)) /* output_frame = (sampling frequency)/50 */ + { + oneOverFrame = 34; /* 1/960 in Q15 */ move16(); + w_hamm = w_hamm48k_2_fx; + move16(); + Lgw = LGW48K; + move16(); + Lprot = 1536; /* (2*output_frame)*1024/1280; */ move16(); + } + ELSE IF (EQ_16(output_frame, L_FRAME32k)) + { + oneOverFrame = 51; /* 1/640 in Q15 */ move16(); + w_hamm = w_hamm32k_2_fx; + move16(); + Lgw = LGW32K; + move16(); + Lprot = 1024; + move16(); + pFftTbl = FFT_W128; /* Table for 256 real input radix-2 FFT */ move16(); + LtranaLogMinus1 = LTRANALOG32K - 1; + move16(); + } + ELSE + { + oneOverFrame = 102; /* 1/320 in Q15 */ move16(); + w_hamm = w_hamm16k_2_fx; + move16(); + Lgw = LGW16K; + move16(); + Lprot = 512; + move16(); + pFftTbl = FFT_W64; /* Table for 128 real input radix-2 FFT */ move16(); + LtranaLogMinus1 = LTRANALOG16K - 1; + move16(); + } + burst_len = add(mult_r(time_offs, oneOverFrame), 1); + + *ph_dith = 0; + move16(); /* typical pattern is 2*pi*[0 0 .25 .50 .75 1.0 1.0 1.0 ..] */ + + IF (GE_16(output_frame, L_FRAME32k)) /*currently est_mus_content only calculated for SWB and FB */ + { + roundEstMusContent = 0; + move16(); + if (GE_16(est_mus_content, FEC_HQ_ECU_POINT5)) /* est_mus_content is in [0.0, 1.0]. */ + { + roundEstMusContent = 1; + move16(); + } + + /* softly shift attenuation just a bit later for estimated "stable" music_content */ + burst_phdith_thresh = add(BURST_PHDITH_THRESH, roundEstMusContent); + burst_att_thresh = add(BURST_ATT_THRESH, roundEstMusContent); + att_per_frame = sub(ATT_PER_FRAME, roundEstMusContent); /* only slighty less att for music */ + } + ELSE + { + /* lock to music-like stable envelope setting for now */ + burst_phdith_thresh = add(BURST_PHDITH_THRESH, 1); /* in Q0 */ + burst_att_thresh = add(BURST_ATT_THRESH, 1); /* in Q0 */ + att_per_frame = sub(ATT_PER_FRAME, 1); /* in Q0 */ + } + + IF (GT_16(burst_len, burst_phdith_thresh)) + { + /* increase degree of dither */ +#if BURST_PHDITH_RAMPUP_LEN != 2 +#error The implementation of phase_dith=min(1.0, (burst_len - burst_phdith_thresh)/burst_phdith_rampup_len)) is incorrect +#endif + *ph_dith = 32767; /* 1.0 in Q15. N.B. 2*PI is not included. */ move16(); + tmp16 = sub(burst_len, burst_phdith_thresh); + if (LT_16(tmp16, burst_phdith_rampup_len)) + { + *ph_dith = 16384; /* 0.5 in Q15. N.B. 2*PI is not included. */ move16(); + } + } + + attDegreeFrames = 0; + move16(); + IF (GT_16(burst_len, burst_att_thresh)) + { + att_always = 1; + move16(); + /* increase degree of attenuation */ + + /* N.B. To facilitate the subsequent 10^(-att_degree/20) implementation + * so as to use direct table-lookup, + * (burstLen - burst_att_thresh) is NOT multiplied by "att_per_frame". */ + attDegreeFrames = sub(burst_len, burst_att_thresh); /* Not multiplied by att_per_frqme! */ + /* Furthermore, in order to minimize the size of the lookup-table required to + * implement 10^(-att_degree/10), hard limit attDegreeFrames to (30% of 50)=15. + * If attDegreeFrames is greater than 15, it means there are more than 15 successive + * bad frames. In this case, no matter what to do, the sound quality will be bad. + */ + if (GT_16(attDegreeFrames, OFF_FRAMES_LIMIT)) + { + attDegreeFrames = OFF_FRAMES_LIMIT; /* Hard limit the no. of frames */ move16(); + } + } + + Ltrana = shr(Lprot, 2); + Ltrana_2 = shr(Ltrana, 1); + + test(); + test(); + IF (LE_16(burst_len, 1)||(EQ_16(burst_len,2)&&last_fec!=0)) + { + + set16_fx(alpha, 32767, LGW_MAX); + set16_fx(beta, 0, LGW_MAX); + *beta_mute = BETA_MUTE_FAC_INI; + move16(); + + /* Apply Hamming window */ + windowing(xfp, xfp_left, w_hamm, 0, Ltrana_2); /* 1st quarter */ + three4thLength = sub(Lprot, Ltrana); + pXfp = xfp + three4thLength; + windowing(pXfp, xfp_right, w_hamm, 0, Ltrana_2); /* 4th quarter */ + + /* spectrum */ + IF (EQ_16(output_frame, L_FRAME48k)) + { + fft3_fx(xfp_left, xfp_left, Ltrana); + fft3_fx(xfp_right, xfp_right, Ltrana); + } + ELSE + { + r_fft_fx_lc(pFftTbl, Ltrana, Ltrana_2, LtranaLogMinus1, xfp_left, xfp_left, 1); + r_fft_fx_lc(pFftTbl, Ltrana, Ltrana_2, LtranaLogMinus1, xfp_right, xfp_right, 1); + } + + /* square representation */ + fft_spec2_fx(xfp_left, magSqLeft, Ltrana); + fft_spec2_fx(xfp_right, magSqRight, Ltrana); + + /* band powers in frequency groups + * exclude bin at PI from calculation */ + magSqLeft[Ltrana_2] = L_deposit_l(0); + magSqRight[Ltrana_2] = L_deposit_l(0); + } + + pGrPowLeft = &gr_pow_left[0]; + pGrPowRight = &gr_pow_right[0]; + pGw = gw; + FOR ( k = 0; k < Lgw; k++ ) + { + test(); + test(); + IF (LE_16(burst_len, 1)||(EQ_16(burst_len,2)&&last_fec!=0)) + { + lowerEdge = *pGw++; + move16(); + l = sub(*pGw, lowerEdge); + headroom = GR_POW_HEADROOM[k]; /* Number of bits to scale down preventing from saturation in accumulation.*/ move16(); + pLeft = magSqLeft + lowerEdge; + pRight = magSqRight + lowerEdge; + *pGrPowLeft = L_deposit_l(0); + *pGrPowRight = L_deposit_l(0); + FOR (i = 0; i < l; i++) + { + acc = L_shr(*pLeft++, headroom); /* Scale down to prevent from saturation. */ + *pGrPowLeft = L_add(*pGrPowLeft, acc); + move32(); + acc = L_shr(*pRight++, headroom); + *pGrPowRight = L_add(*pGrPowRight, acc); + move32(); + } + + /*Xavg[k] = sqrt(0.5f*(gr_pow_left[k]+gr_pow_right[k])/(float)(gw[k+1]-gw[k]));*/ + acc = L_shr(L_add(*pGrPowLeft, *pGrPowRight), 1); + acc = Mult_32_16(acc, gw_len_inv_fx[k]); /* -headroom */ + + acc = Sqrt_l(acc, &expo); /* -headroom+31+expo */ + + expo = sub(add(expo, 31), headroom); + if ( EQ_16(s_and(expo, 1), 1)) + { + acc = Mult_32_16(acc, 23170); /* 1/sqrt(2) in Q15 */ + } + expo = shr(expo, 1); + Xavg[k] = round_fx(L_shl(acc, sub(sub(16, expo), 2))); /* Q0, additional right shift by 2 to account for that Xavg is + calculated using lenght N/4 fft but is applied on a fft of length N */ + + /*dither phase in case of transient */ + /* separate transition detection and application of forced burst dithering */ + tr_dec[k] = 0; + move16(); + Mpy_32_16_ss(*pGrPowLeft, THRESH_TR_LIN_BY2_FX, &acc, &lsb); /* To facilitate fixed-point implementation, divide threshold by 2. */ + acc = L_or(L_shl(acc,16), L_and(0xffffL,lsb)); /* Equivalent to concatenate acc and lsb, and then down shift by 16 bits. */ + if (GT_32(*pGrPowRight, acc)) /* gr_pow_right > thres_tr_lin*gr_pow_left */ + { + tr_dec[k] = 1; + move16(); + } + Mpy_32_16_ss(*pGrPowRight, THRESH_TR_LIN_BY2_FX, &acc, &lsb); + acc = L_or(L_shl(acc,16), L_and(0xffffL,lsb)); /* Equivalent to concatenate acc and lsb, and then down shift by 16 bits. */ + if (GT_32(*pGrPowLeft, acc)) /* gr_pow_left > thres_tr_lin*gr_pow_right */ + { + tr_dec[k] = 1; + move16(); + } + + /* magnitude modification */ + IF ( add(tr_dec[k], att_always) != 0) + { + +#if MAX_INCREASE_GRPPOW_FX != 0 +#error trans_ana_fx-- The following implementation is incorrect +#endif + att_val = 32767; + move16(); + IF (GT_32(*pGrPowRight, 0)) + { + IF (LT_32(*pGrPowRight, *pGrPowLeft)) /* i.e., (gr_pow_right/gr_pow_left) < 1.0 */ + { + /* Compute sqrt(grp_pow_chg), where grp_pow_chg = gr_pow_right/gr_pow_left. */ + tmp16 = ratio(*pGrPowRight, *pGrPowLeft, &expo); /* tmp16 in Q14 */ + expo = sub(expo, (15-14)); /* Now, tmp16 is considered in Q15 */ + i = norm_s(tmp16); + man = shl(tmp16, i); /* Mandatory normalization before sqrtNthOrder(). */ + expo = add(expo, i); + man = sqrt2ndOrder(man); + if (s_and(expo,1) != 0) /* Check even or odd. */ + { + man = mult_r(man,FEC_HQ_ECU_ROOT2); + } + expo = shr(expo, 1); /* Divided by 2-- square root operation. */ + att_val = shr(man, expo); /* Denormalize the mantissa back to Q15. */ + } + /* ELSE do nothing because (gr_pow_right/gr_pow_left) >= 1.0 (i.e., + * max_increase_grppow_lin) */ + } + + mag_chg_1st[k] = att_val; + move16(); + mag_chg[k] = att_val; + move16(); + } + ELSE + { + mag_chg_1st[k] = 32767; + move16(); + mag_chg[k] = 32767; + move16(); /* Set to 1.0 in Q15 */ + } + } + ELSE + { + /* Since attDegreeFrames is discrete (integer) and hard limited to OFF_FRAMES_LIMIT, + * it is much easier to implement 10^(-att_degree/20.0) by a simply direct + * table-lookup. Also, att_per_frame is discrete as well and can be + * either ATT_PER_FRAME-1 or ATT_PER_FRAME and nothing else. This + * means only 2 tables of size=(OFF_FRAMES_LIMIT+1) each are required. + * To take square root into account, it is divided by 20 instead of 10. */ + IF (EQ_16(att_per_frame, ATT_PER_FRAME)) /* Select the corresponding lookup-table. */ + { + att_val = POW_ATT_TABLE0[attDegreeFrames]; /* 10^(-attDegreeFrames*(ATT_PER_FRAME)/20) */ move16(); + } + ELSE + { + att_val = POW_ATT_TABLE1[attDegreeFrames]; /* 10^(-attDegreeFrames*(ATT_PER_FRAME - 1)/20) */ move16(); + } + mag_chg[k] = mult_r(mag_chg_1st[k], att_val); /* Q15 */ + + if (GT_16(burst_len, BETA_MUTE_THR)) + { + *beta_mute = shr(*beta_mute, 1); + } + alpha[k] = mag_chg[k]; + move16(); + /*beta[k] = sqrt(1.0f - SQR(alpha[k])) * *beta_mute;*/ + acc = L_sub(1073741824, L_mult0(alpha[k], alpha[k])); + acc = Sqrt_l(acc, &expo); + expo = add(30, add(31, expo)); + if (EQ_16(s_and(expo, 1), 1)) + { + acc = Mult_32_16(acc, 23170); /* 1/sqrt(2) in Q15 */ + } + expo = shr(expo, 1); + beta[k] = mult_r(*beta_mute, round_fx(L_shl(acc, sub(31, expo)))); + move16(); + + IF (GE_16(k, LGW32K-1)) + { + beta[k] = mult_r(beta[k], 3277); /* 0.1 in Q15 */ + } + ELSE IF (GE_16(k, LGW16K-1)) + { + beta[k] = mult_r(beta[k], 16384); /* 0.5 in Q15 */ + } + } + pGrPowLeft++; + pGrPowRight++; + } + + return; +} + +/*----------------------------------------------------------------------------- + * peakfinder_fx() + * + * Peak-picking algorithm + *----------------------------------------------------------------------------*/ +static void peakfinder_fx( + const Word16 *x0, /* i : vector from which the maxima will be found */ + const Word16 len0, /* i : length of input vector */ + Word16 *plocs, /* o : the indices of the identified peaks in x0 Q0 */ + Word16 *cInd, /* o : number of identified peaks Q0 */ + const Word16 sel /* i : The amount above surrounding data for a peak to be identified */ +#ifdef IVAS_FEC_ECU_TO_COMPLETE + ,const Word16 endpoints /* i : Flag to include endpoints in peak search */ +#endif +) +{ + const Word16 *pX0; + Word16 minMag, tempMag, leftMin; + Word16 dx0[L_PROT48k_2], x[L_PROT48k_2+1], peakMag[MAX_PLOCS]; + Word16 *pDx0, *pDx01, *pX; + Word16 i, len, tempLoc, foundPeak, ii, xInd, tmp16, threshold, xAt0, xAt1, xAt2; + Word16 len0Minus1, len0Minus2, lenMinus1; + Word16 indarr[L_PROT48k_2+1], peakLoc[MAX_PLOCS]; + Word16 *pInd; + + tempLoc = 0; + + /* Find derivative */ + len0Minus1 = sub(len0, 1); + pX0 = x0 + 1; + Vr_subt(pX0, x0, dx0, len0Minus1); + + FOR (i=0; i 0))) +#else + IF (GT_16(len, 2)) +#endif + { + /* Set initial parameters for loop */ + tempMag = minMag; + move16(); + foundPeak = 0; + move16(); + leftMin = minMag; + move16(); + threshold = add(leftMin, sel); + +#ifdef IVAS_FEC_ECU_TO_COMPLETE + IF(len > 0) +#endif + { + /* Deal with first point a little differently since tacked it on + Calculate the sign of the derivative since we took the first point + on it does not necessarily alternate like the rest. */ + + /* The first point is larger or equal to the second */ + pX = x; + xAt0 = *pX++; + move16(); + xAt1 = *pX++; + move16(); + xAt2 = *pX--; /* After decrement, pX points to x[1]. */ move16(); + IF(GE_16(xAt0, xAt1)) + { + ii = -1; + move16(); + IF(GE_16(xAt1, xAt2)) /* x[1] is not extremum -> overwrite with x[0] */ + { + *pX = xAt0; /* x[1] = x[0] */ move16(); + tmp16 = *pInd++; + move16(); + *pInd++ = tmp16; /* ind[1] = ind[0] */ move16(); + len = sub(len, 1); + } + pX--; /* After decrement, pX points to x[0]. */ + } + ELSE /* First point is smaller than the second */ + { + ii = 0; + IF(LT_16(xAt1, xAt2)) /* x[1] is not extremum -> overwrite with x[0] */ + { + *pX = xAt0; /* x[1] = x[0] */ move16(); + tmp16 = *pInd++; + move16(); + *pInd++ = tmp16; /* ind[1] = ind[0] */ move16(); + len = sub(len, 1); + } + } + pX--; /* After decrement, pX points to either x[-1] or x[0]. */ + } +#ifdef IVAS_FEC_ECU_TO_COMPLETE + ELSE + { PMTE () + ii = -1; /* First point is a peak */ + if (len >= 2) + { + if (x[1] >= x[0]) + { + ii = 0; /* First point is a valley, skip it */ + } + } + } +#endif + *cInd = 0; + move16(); + /*Loop through extrema which should be peaks and then valleys*/ + lenMinus1 = sub(len, 1); + FOR (;;) + { + ii = add(ii, 1); /* This is a peak */ + + /* Make sure we don't iterate past the length of our vector */ + IF (GE_16(ii, lenMinus1)) + { + BREAK; + } + + /*Reset peak finding if we had a peak and the next peak is bigger + than the last or the left min was small enough to reset.*/ + IF (GT_16(foundPeak,0)) + { + tempMag = minMag; + move16(); + foundPeak = 0; + move16(); + } + + /* Found new peak that was larger than temp mag and selectivity larger + than the minimum to its left. */ + IF (GT_16(*(++pX), tempMag)) + { + IF ( GT_16(*pX, threshold)) /* threshold = leftMin + sel */ + { + tempLoc = ii; + move16(); + tempMag = *pX; + move16(); + } + } + + ii = add(ii, 1); /* Move onto the valley */ + pX++; + + /* Come down at least sel from peak */ + IF (foundPeak == 0) + { + IF (GT_16(tempMag, add(sel, *pX))) + { + foundPeak = 1; /* We have found a peak */ move16(); + leftMin = *pX; + move16(); + threshold = add(leftMin, sel); + peakLoc[*cInd] = tempLoc; /* Add peak to index */ move16(); + peakMag[*cInd] = tempMag; + move16(); + *cInd = add(*cInd, 1); + } + } + IF (foundPeak == 0) /* The above IF-block has not found the peak yet. */ + { + IF (LT_16(*pX, leftMin))/* New left minimum */ + { + leftMin = *pX; + move16(); + threshold = add(leftMin, sel); + } + } + } + + /* Check end point */ + IF (GT_16(x[lenMinus1], tempMag)) + { + IF (GT_16(x[lenMinus1], threshold)) /* threshold = leftMin + sel */ + { + peakLoc[*cInd] = lenMinus1; + move16(); + peakMag[*cInd] = x[lenMinus1]; + move16(); + *cInd = add(*cInd, 1); + foundPeak = 1; + move16(); + } + } + IF (foundPeak == 0) /* Check if we still need to add the last point */ + { + IF (GT_16(tempMag, minMag)) + { + peakLoc[*cInd] = tempLoc; + move16(); + peakMag[*cInd] = tempMag; + move16(); + *cInd = add(*cInd, 1); + } + } + + /* Create output */ + FOR (i = 0; i < *cInd; i++) + { + plocs[i] = *(indarr + peakLoc[i]); + move16(); + move16(); + } + } + ELSE /* This is a monotone function where an endpoint is the only peak */ + { +#ifdef IVAS_FEC_ECU_TO_COMPLETE + IF(endpoints) +#endif + { + xInd = 1; + move16(); + if (GT_16(x[0], x[1])) + { + xInd = 0; + move16(); + } + + peakMag[0] = x[xInd]; + move16(); + IF(GT_16(peakMag[0], add(minMag, sel))) + { + plocs[0] = *(indarr + xInd); + move16(); + *cInd = 1; + move16(); + } + ELSE + { + *cInd = 0; + move16(); + } + } +#ifdef IVAS_FEC_ECU_TO_COMPLETE + ELSE + {/* Input constant or all zeros -- no peaks found */ + *cInd = 0; + move16(); + } +#endif + } +} + +/*----------------------------------------------------------------------------- +* imax_fx() +* +* Get interpolated maximum position +*-----------------------------------------------------------------------------*/ +static Word16 imax_fx( /* o: The location, relative to the middle of the 3 given data point, of the maximum. (Q15) */ + const Word16 *y, /* i: The 3 given data points. */ + const Word16 special /* i: -1 = left edge special case, 0 = normal, +1 = right edge special case */ +) +{ + Word16 posi; + Word16 y1, y2, y3, man, expo, edge; + const Word16 *pY; + Word32 numer, denom, sign, acc, y3_y1; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + /* Seek the extremum of the parabola P(x) defined by 3 consecutive points + so that P([-1 0 1]) = [y1 y2 y3] */ + pY = y; + y1 = *pY++, y2 = *pY++, y3 = *pY; + move16(); + move16(); + move16(); + + /* The extremum value: + * y2i = -0.125f * SQR(y3_y1) / (y1+y3-2*y2)+y2 + * is not computed. Alternatively, the derivative of the parabola evaluated at y=0, + * dP/dy|y=0, is used to determine whether the extremum is maximum or not. + */ + + /* Compute the extremum location: posi = (y3 - y1)/(4*y2 - 2*y1 - 2*y3). */ + y3_y1 = L_sub(y3, y1); + acc = L_shl(y2,1); /* N.B. y2 is multiplied by 2 not 4. */ + acc = L_sub(acc, y1); /* N.B. Y1 is not multiplied by 2. */ + denom = L_sub(acc, y3); /* N.B. Y3 is not multiplied by 2. */ + sign = L_xor(y3_y1, denom); /* Preserve the sign since div_s() only takes positive arguments. */ + numer = L_abs(y3_y1); + denom = L_abs(denom); + IF (numer == 0) + { + return 0; + } + IF (denom == 0) + { + return 0; + } + /* Although the output of ratio() is in Q14, adding the missing factor of 2 (See above) + * in the denominator, the output is now considered to be in Q15. */ + man = ratio(numer, denom, &expo); /* The mantissa is considered in Q15 */ +#ifdef BASOP_NOGLOB + posi = shr_o(man, expo, &Overflow); /* in Q15 (Due to saturation, it is automatically bound inside [-1.0,1.0].) */ +#else + posi = shr(man, expo); /* in Q15 (Due to saturation, it is automatically bound inside [-1.0,1.0].) */ +#endif + if (sign < 0) /* Restore the sign. */ + { + posi = negate(posi); + } + + /* For both edges (left and right), the extremum found above may be minimum. + * It needs to reject the minimum. */ + IF (NE_16(special,0)) /* Either edge specical case. */ + { + edge = 0x7fff; /* 1 in Q15 for the right edge special case */ move16(); + if (LT_16(special,0)) + { + edge = 0; /* Left edge special case */ move16(); + } + + /* The derivative (slope) of the interpolating parabola = 2*A*y + B, + * where A = (y3 + y1)/2 - y2 + * and B = (y3 - y1)/2. + * Therefore, the slope at y=0 is simply B. Use this slope to determine + * if the parabola is concave upward or downward. + */ + IF (GT_16(posi,0)) /* The extremum is in between the middle and the right given data points. */ + { + IF (LE_16(y3, y1)) /* Check the slope at y=0, i.e., at the middle given data point. */ + { + posi = edge; /* minimum case */ move16(); + } + ELSE + { + posi = sub(0x7fff, posi); /* maximum case */ + } + } + ELSE /* The extremum is in between the left and the middle given data points. */ + { + IF (GE_16(y3, y1)) + { + posi = edge; /* minimum case */ move16(); + } + ELSE + { + posi = add(0x7fff, posi); /* maximum case */ + } + } + } + return posi; /* Q15. The position either left or right relative to the index of the middle of the 3 given data points. */ +} + +/*----------------------------------------------------------------------------- +* spec_ana_fx() +* +* Spectral analysis +*-----------------------------------------------------------------------------*/ +static void spec_ana_fx( + const Word16* prevsynth, /* i : Input signal */ + Word16* plocs, /* o : The indicies of the identified peaks Q0 */ + Word32* plocsi, /* o : Interpolated positions of the identified peaks Q16 */ + Word16* num_plocs, /* o : Number of identified peaks Q0 */ + Word16* X_sav, /* o : Stored fft spectrum */ + const Word16 output_frame, /* i : Frame length Q0 */ + const Word16 bwidth_fx, /* i : Encoded bandwidth index Q0 */ + Word16* Q /* o : Q value of the fft spectrum */ +#ifdef IVAS_FEC_ECU_TO_COMPLETE + , const Word16 element_mode, /* i : IVAS element mode */ + Word16* noise_fac, /* o : for few peaks zeroing valleys decision making */ + const Word16 pcorr +#endif +) +{ + Word16 Lprot, LprotLog2Minus1 = 0, hamm_len2 = 0, Lprot2, Lprot2_1, m, n; + const Word16* pFftTbl = NULL; + Word16 xfp[L_PROT48k]; + Word32 magSq[L_PROT48k / 2 + 1], * pMagSq; + Word16* pXfp, * pXfp1, * pXsav, * pPlocs; + Word16 Xmax, Xmin, sel, man, expo, expoBy2; + Word16 sinTblOffset, rectLength, fraction, special; + Word32* pPlocsi; + Word32 acc; + Word16 stop_band_start; + Word16 stop_band_length; + + Lprot = 512; /* 1536=(2*output_frame)*1024/1280; */ move16(); + + sinTblOffset = 0; + + IF(EQ_16(output_frame, L_FRAME48k)) + { + Lprot = L_PROT48k; /* 1536=(2*output_frame)*1024/1280; */ move16(); + hamm_len2 = L_PROT_HAMM_LEN2_48k; /* half Hamming window = 288 */ move16(); + } + ELSE IF(EQ_16(output_frame, L_FRAME32k)) + { + Lprot = L_PROT32k; /* 1024 */ move16(); + sinTblOffset = 4; + move16(); + hamm_len2 = L_PROT_HAMM_LEN2_32k; /* half Hamming window = 192 */ move16(); + pFftTbl = FFT_W512; /* Table for 1024-point real input FFT */ + LprotLog2Minus1 = 9; /* FFT stages for complex input FFT */ move16(); + } + ELSE + { + Lprot = 512; + move16(); + sinTblOffset = 8; + move16(); + hamm_len2 = L_PROT_HAMM_LEN2_16k; /* half Hamming window = 96 */ move16(); + pFftTbl = FFT_W256; /* Table for 512-point real input FFT */ + LprotLog2Minus1 = 8; /* FFT stages for complex input FFT */ move16(); + } + + Lprot2 = shr(Lprot, 1); + Lprot2_1 = add(Lprot2, 1); + rectLength = sub(Lprot, shl(hamm_len2, 1)); /* The length of the rectangular portion of the Hamming-Rectangular window. */ + + *Q = s_max(0, sub(Exp16Array(Lprot, prevsynth), 1)); + move16(); + Copy_Scale_sig(prevsynth, xfp, Lprot, *Q); + + IF(EQ_16(output_frame, L_FRAME48k)) + { + /* Apply hamming-rect window */ +#ifdef IVAS_FEC_ECU_TO_COMPLETE + IF(EQ_16(element_mode, EVS_MONO)) +#endif + { + windowing(xfp, xfp, w_hamm_sana48k_2_fx, rectLength, hamm_len2); + } +#ifdef IVAS_FEC_ECU_TO_COMPLETE + ELSE + { + PMTE() + //window_corr = w_hamm[0]; + //window_corr_step = w_hamm[0] / hamm_len2; + //for (i = 0; i < hamm_len2; i++) + //{ + // xfp[i] = prevsynth[i] * (w_hamm[i] - window_corr); + // xfp[Lprot - i - 1] = prevsynth[Lprot - i - 1] * (w_hamm[i] - window_corr); + // window_corr -= window_corr_step; + //} + } +#endif + /* Spectrum */ + fft3_fx(xfp, xfp, Lprot); + } + ELSE + { +#ifdef IVAS_FEC_ECU_TO_COMPLETE + IF(EQ_16(element_mode, EVS_MONO)) +#endif + { + /* Apply hamming-rect window */ + windowing_ROM_optimized(xfp, xfp, sinTblOffset, rectLength, hamm_len2); + } +#ifdef IVAS_FEC_ECU_TO_COMPLETE + ELSE + { + PMTE() + //window_corr = w_hamm[0]; + //window_corr_step = w_hamm[0] / hamm_len2; + //for (i = 0; i < hamm_len2; i++) + //{ + // xfp[i] = prevsynth[i] * (w_hamm[i] - window_corr); + // xfp[Lprot - i - 1] = prevsynth[Lprot - i - 1] * (w_hamm[i] - window_corr); + // window_corr -= window_corr_step; + //} + } +#endif + /* Spectrum */ + r_fft_fx_lc(pFftTbl, Lprot, Lprot2, LprotLog2Minus1, xfp, xfp, 1); + } + + /* Apply zeroing of non-coded FFT spectrum */ + IF(GT_16(output_frame, inner_frame_tbl[bwidth_fx])) + { + stop_band_start = shl(128, bwidth_fx); + stop_band_length = sub(Lprot, shl(stop_band_start, 1)); + stop_band_start = add(stop_band_start, 1); + set16_fx(xfp + stop_band_start, 0, stop_band_length); + } + + pXfp = xfp; + pXsav = X_sav; + FOR(m = 0; m < Lprot; m++) + { + *pXsav++ = *pXfp++; + move16(); + } + + /* Magnitude representation */ + fft_spec2_fx(xfp, magSq, Lprot); + + /* Compute xfp[m] = sqrt(magSq[m]) */ + pXfp = xfp; + pMagSq = magSq; + FOR(m = 0; m < Lprot2_1; m++) + { + IF(*pMagSq == 0) + { + *pXfp++ = extract_l(*pMagSq++); /* magSq[] is zero */ + } + ELSE + { + expo = norm_l(*pMagSq); /* exponent */ + man = extract_h(L_shl(*pMagSq++, expo)); /* mantissa */ + man = sqrt2ndOrder(man); + expoBy2 = shr(expo, 1); /* Divided by 2-- square root operation. */ + IF(s_and(expo,1) == 0) /* Check even or odd. */ + { + man = mult_r(man,FEC_HQ_ECU_ROOT2); /* FEC_HQ_ECU_ROOT2 is sqrt(2) in Q14 */ + expoBy2 = sub(expoBy2, 1); + } + *pXfp++ = shr(man, expoBy2); + move16();/* Denormalize the mantissa back to Q0. */ + } + } + + /* Find maximum and minimum. */ + maximum_fx(xfp, Lprot2_1, &Xmax); + minimum_fx(xfp, Lprot2_1, &Xmin); +#ifdef IVAS_FEC_ECU_TO_COMPLETE + IF(EQ_16(element_mode, EVS_MONO)) +#endif + { + sel = mult_r(sub(Xmax, Xmin), CMPLMNT_PFIND_SENS_FX); + } +#ifdef IVAS_FEC_ECU_TO_COMPLETE + ELSE + { + sel = (Xmax - Xmin) * (1.0f - ST_PFIND_SENS); + } +#endif + peakfinder_fx(xfp, Lprot2_1, plocs, num_plocs, sel +#ifdef IVAS_FEC_ECU_TO_COMPLETE + , endpoints +#endif + ); + + +#ifdef IVAS_FEC_ECU_TO_COMPLETE + /* Currently not the pitch correlation but some LF correlation */ + if (element_mode != EVS_MONO && *num_plocs > 50 && pcorr < 0.6f) + { + *num_plocs = 0; + } + + IF(EQ_16(element_mode, EVS_MONO)) +#endif + { + + /* Refine peaks */ + pPlocsi = plocsi; + pPlocs = plocs; + n = sub(*num_plocs, 1); /* -1 so as to exclude the very last peak. */ + /* Special case-- The very 1st peak if it is at 0 index position */ + IF(EQ_16(*pPlocs, 0)) /* Only the very 1st peak is possible the peak at 0 index position. */ + { + fraction = imax_fx(xfp, -1); /* -1 signifies special left edge case. */ + acc = L_deposit_h(*pPlocs++); /* N.B., (*pPlocs) must be zero here. */ + *pPlocsi++ = L_mac(acc, fraction, 1); + move32();/* in Q16 */ + n = sub(n, 1); /* This special case is taken care of-- one less to go */ + } + /* All peaks except the very last peak but including the very 1st one if it has not been taken care of. */ + pXfp1 = xfp - 1; + FOR(m = 0; m < n; m++) /* Loop through up to the last but one peak. (The last one is excluded.) */ + { + pXfp = pXfp1 + *pPlocs; + fraction = imax_fx(pXfp, 0); /* in Q15 */ + acc = L_deposit_h(*pPlocs++); + *pPlocsi++ = L_mac(acc, fraction, 1); + move32();/* in Q16. Append the fractional part to the integral part. */ + } + IF(n >= 0) + { + /* Special case-- The very last peak */ + pXfp = pXfp1 + *pPlocs; + IF(EQ_16(*pPlocs, Lprot2)) /* Only the very last peak is possible the peak at Lprot2 index position. */ + { + pXfp--; /* Special case needs extra decrement */ + special = 1; /* Signify special right edge case. */ move16(); + } + ELSE + { + special = 0; + move16(); + } + fraction = imax_fx(pXfp, special); /* in Q15 */ + acc = L_deposit_h(*pPlocs); + *pPlocsi = L_mac(acc, fraction, 1); + move32();/* in Q16. Append the fractional part to the integral part. */ + } + } +#ifdef IVAS_FEC_ECU_TO_COMPLETE + ELSE + { + Lprot2p1 = Lprot / 2 + 1; + + /* Refine peaks */ + pPlocsi = plocsi; + pPlocs = plocs; + n = *num_plocs; /* number of peaks to process */ + + /* Special case-- The very 1st peak if it is at 0 index position (DC) */ + /* With DELTA_CORR_F0_INT == 2 one needs to handle both *pPlocs==0 and *pPlocs==1 */ + if (n > 0 && *pPlocs == 0) /* Very 1st peak position possible to have a peak at 0/DC index position. */ + { + *pPlocsi++ = *pPlocs + imax_pos(&xfp[*pPlocs]); + pPlocs++; + n = n - 1; + } + + if (n > 0 && *pPlocs == 1) /* Also 2nd peak position uses DC which makes jacobsen unsuitable. */ + { + *pPlocsi++ = *pPlocs - 1 + imax_pos(&xfp[*pPlocs - 1]); + currPlocs = *pPlocs++; + n = n - 1; + } + + /* All remaining peaks except the very last two possible integer positions */ + currPlocs = *pPlocs++; + endPlocs = Lprot2p1 - DELTA_CORR_F0_INT; /* last *pPlocs position for Jacobsen */ + + /* precompute number of turns based on endpoint integer location and make into a proper for loop */ + if (n > 0) + { + nJacob = n; + if (sub(endPlocs, plocs[sub(*num_plocs, 1)]) <= 0) + { + nJacob = sub(nJacob, 1); + } + + for (k = 0; k < nJacob; k++) + { + *pPlocsi++ = currPlocs + imax2_jacobsen_mag(&(X_sav[currPlocs - 1]), &(X_sav[Lprot - 1 - currPlocs])); + currPlocs = *pPlocs++; + } + n = n - nJacob; + } + + /* At this point there should at most two plocs left to process */ + /* the position before fs/2 and fs/2 both use the same magnitude points */ + if (n > 0) + { + /* [ . . . . . . . ] Lprot/2+1 positions */ + /* | | | */ + /* 0 (Lprot/2-2) (Lprot/2) */ + + if (currPlocs == (Lprot2p1 - DELTA_CORR_F0_INT)) /* Also 2nd last peak position uses fs/2 which makes jacobsen less suitable. */ + { + *pPlocsi++ = currPlocs - 1 + imax_pos(&xfp[currPlocs - 1]); + currPlocs = *pPlocs++; + n = n - 1; + } + + /* Here the only remaining point would be a fs/2 plocs */ + /* pXfp = xfp + sub(Lprot2,1); already set just a reminder where it + * whould point */ + if (n > 0) /* fs/2 which makes special case . */ + { + *pPlocsi++ = currPlocs - 2 + imax_pos(&xfp[currPlocs - 2]); + currPlocs = *pPlocs++; + n = n - 1; + } + } + + /* For few peaks decide noise floor attenuation */ + if (*num_plocs < 3 && *num_plocs > 0) + { + sig = sum_f(xfp, Lprot2_1) + EPSILON; + + /*excluding peaks and neighboring bins*/ + for (i = 0; i < *num_plocs; i++) + { + st_point = max(0, plocs[i] - DELTA_CORR); + end_point = min(Lprot2_1 - 1, plocs[i] + DELTA_CORR); + set_f(&xfp[st_point], 0.0f, end_point - st_point + 1); + } + noise = sum_f(xfp, Lprot2_1) + EPSILON; + nsr = noise / sig; + + if (nsr < 0.03f) + { + *noise_fac = 0.5f; + } + else + { + *noise_fac = 1.0f; + } + } + } +#endif +} + +/*-------------------------------------------------------------------* +* subst_spec_fx() +* +* Substitution spectrum calculation +*-------------------------------------------------------------------*/ + +static void subst_spec_fx( + const Word16 *plocs, /* i : The indices of the identified peaks Q0 */ + const Word32 *plocsi, /* i : Interpolated positions of the identified peaks Q16 */ + Word16 *num_plocs, /* i/o : Number of identified peaks Q0 */ + const Word16 time_offs, /* i : Time offset Q0 */ + Word16 *X, /* i/o : FFT spectrum */ + const Word16 *mag_chg, /* i : Magnitude modification Q15 */ + const Word16 ph_dith, /* i : Phase dither, 2*PI is not included. (Q15, i.e., between 0.0 and 1.0) */ + const Word16 *is_trans, /* i : Transient flags (either 0 or 1) */ + const Word16 output_frame, /* i : Frame length Q0 */ + Word16 *seed, /* i/o : Random seed */ + const Word16 *alpha, /* i : Magnitude modification factors for fade to average Q15 */ + const Word16 *beta, /* i : Magnitude modification factors for fade to average Q15 */ + Word16 beta_mute, /* i : Factor for long-term mute Q15 */ + const Word16 *Xavg /* i : Frequency group averages to fade to Q0 */ +#ifdef IVAS_FEC_ECU_TO_COMPLETE + ,const Word16 element_mode, /* i : IVAS element mode */ + const Word16 ph_ecu_lookahead, /* i : Phase ECU lookahead */ + const Word16 noise_fac /* i : noise factor */ +#endif +) +{ + Word16 Xph_short; + Word32 corr_phase[MAX_PLOCS], Xph; + Word32 *pCorrPhase; + Word16 cos_F, sin_F, tmp; + Word16 Lprot, m, i, e, im_ind, delta_corr_up, delta_corr_dn, delta_tmp; + UWord16 lsb; + Word16 j, re, im, *pReX, *pImX, lastPeak, lprotBy2Minus1, segmentLen; + Word16 pkLocation_1, pkLocation, pkLocation1; + const Word16 *pPlocs; + const Word32 *pPlocsi; + Word32 acc; + Word16 Lecu; + Word16 Lprot_inv; + Word16 k; + Word16 tmp2; + Word16 alpha_local; + Word16 beta_local; + Word16 expo; +#ifdef IVAS_FEC_ECU_TO_COMPLETE + Word16 one_peak_flag_mask; + Word16 alpha_local; + Word16 beta_local; +#endif + Word16 mag_chg_local; /*for peak attenuation in burst */ + + Lprot = 512; + move16(); + Lprot_inv = 8192; + move16(); + Lecu = shl(output_frame, 1); + + IF (EQ_16(output_frame, L_FRAME48k)) + { + Lprot = L_PROT48k; /* 1536=(2*output_frame)*1024/1280; */ move16(); + Lprot_inv = 2731; /* Q22 */ move16(); + } + ELSE IF (EQ_16(output_frame, L_FRAME32k)) + { + Lprot = L_PROT32k; /* 1024 */ move16(); + Lprot_inv = 4096; /* Q22 */ move16(); + } + ELSE + { + Lprot = 512; + move16(); + Lprot_inv = 8192; /* Q22 */ move16(); + } + + /* Correction phase of the identified peaks */ + IF (s_or(is_trans[0], is_trans[1]) != 0) + { + *num_plocs = 0; + move16(); + } + ELSE + { + tmp = NS2SA(output_frame*50,PH_ECU_ALDO_OLP2_NS-PH_ECU_LOOKAHEAD_NS); + tmp = add(tmp, sub(Lecu, shr(sub(Lecu, Lprot), 1))); + tmp = sub(tmp, shr(output_frame, 1)); + tmp = add(tmp, time_offs); + tmp = round_fx(L_shl(L_mult0(tmp, Lprot_inv), 4)); /* 0+22+4-16=10 */ + + pPlocsi = plocsi; + pCorrPhase = corr_phase; + FOR (m = 0; m < *num_plocs; m++) + { + Mpy_32_16_ss(*pPlocsi++, tmp, &acc, &lsb); /* plocsi[] in Q16, tmp in Q10 and tmp does not include 2*PI. */ + acc = L_add(L_shl(acc, 5), lshr(lsb, 11)); + *pCorrPhase++ = acc; /* in Q16. 2*PI is not included. */ move32(); + } + } +#ifdef IVAS_FEC_ECU_TO_COMPLETE + one_peak_flag_mask = 1; /* all ones mask -> keep */ + IF(NE_16(element_mode, EVS_MONO)) + { + if ((*num_plocs > 0) && sub(*num_plocs, 3) < 0) + { + one_peak_flag_mask = noise_fac; /* all zeroes mask -> zero */ + } + if (*num_plocs == 0) + { + X[0] = 0; /* reset DC if there are no peaks */ + X[shr(Lprot, 1)] = 0; /* also reset fs/2 if there are no peaks */ + } + } +#endif + lprotBy2Minus1 = sub(shr(Lprot, 1), 1); + i = 1; + move16(); + k = 0; + move16(); + im_ind = sub(Lprot, 1); + move16(); + pReX = X + i; + pImX = X + im_ind; + pPlocs = plocs; + pCorrPhase = corr_phase; + pkLocation = *pPlocs; /* N.B. No post-increment */ move16(); + pkLocation1 = *pPlocs++; + move16(); + lastPeak = sub(*num_plocs, 1); + FOR (m = 0; m < *num_plocs; m++) + { + delta_corr_dn = DELTA_CORR; + move16(); + delta_corr_up = DELTA_CORR; + move16(); + + pkLocation_1 = pkLocation; /* plocs[m - 1] */ move16(); + pkLocation = pkLocation1; /* plocs[m] */ move16(); + pkLocation1 = *pPlocs++; /* plocs[m + 1] */ move16(); + IF (m > 0) + { + delta_tmp = shr(sub(sub(pkLocation, pkLocation_1), 1), 1); + if (LT_16(delta_tmp, DELTA_CORR)) + { + delta_corr_dn = delta_tmp; + move16(); + } + } + + IF (LT_16(m, lastPeak)) + { + delta_tmp = shr(sub(sub(pkLocation1, pkLocation), 1), 1); + if (LT_16(delta_tmp, DELTA_CORR )) + { + delta_corr_up = delta_tmp; + move16(); + } + } + + /* Input Xph */ + segmentLen = sub(sub(pkLocation, delta_corr_dn), i); + /* i = add(i, segmentLen); */ + FOR (j = 0; j < segmentLen; j++) + { + *seed = rand_phase_fx(*seed, &sin_F, &cos_F); + + re = *pReX; + move16(); + im = *pImX; + move16(); +#ifdef IVAS_FEC_ECU_TO_COMPLETE + IF(EQ_16(element_mode, EVS_MONO)) +#endif + { + tmp = sub(mult_r(re, cos_F), mult_r(im, sin_F)); + im = add(mult_r(re, sin_F), mult_r(im, cos_F)); + } +#ifdef IVAS_FEC_ECU_TO_COMPLETE + ELSE + { + PMTE() + //tmp = one_peak_flag_mask * (X[i] * cos_F - X[im_ind] * sin_F); + //X[im_ind] = one_peak_flag_mask * (X[i] * sin_F + X[im_ind] * cos_F); + } +#endif + IF (LT_16(alpha[k], 32766)) + { + *seed = rand_phase_fx(*seed, &sin_F, &cos_F); + tmp2 = mult_r(beta[k], Xavg[k]); + *pReX++ = add( mult_r(alpha[k], tmp), mult_r(tmp2, cos_F) ); + move16(); + *pImX-- = add( mult_r(alpha[k], im), mult_r(tmp2, sin_F) ); + move16(); + } + ELSE + { + *pReX++ = mult_r(mag_chg[k], tmp); + move16(); + *pImX-- = mult_r(mag_chg[k], im); + move16(); + } + i = add(i, 1); + if (GE_16(i, ivas_gwlpr[k+1])) + { + k = add(k, 1); + } + } + + e = add(pkLocation, delta_corr_up); + if (GT_16(e, lprotBy2Minus1)) + { + e = lprotBy2Minus1; + move16(); + } + + Xph = *pCorrPhase; + Xph_short = s_and(extract_l(L_shr(Xph, 16 - 10)), 0x3ff); /* 10 bits precision after radix point */ + IF (GE_16(Xph_short, 512)) + { + sin_F = negate(sincos_t_ext_fx[Xph_short - 512]); + IF (LT_16(Xph_short, 768)) + { + cos_F = negate(sincos_t_ext_fx[Xph_short - (512 - 256)]); + } + ELSE + { + cos_F = sincos_t_ext_fx[-Xph_short + (1024 + 256)]; + move16(); + } + } + ELSE + { + sin_F = sincos_t_ext_fx[Xph_short]; + move16(); + IF (LT_16(Xph_short, 256)) + { + cos_F = sincos_t_ext_fx[Xph_short + 256]; + move16(); + } + ELSE + { + cos_F = negate(sincos_t_ext_fx[-Xph_short + (256 + 512)]); + } + } + + segmentLen = add(sub(e, i), 1); + /* i = add(i, segmentLen); */ + FOR (j = 0; j < segmentLen; j++ ) + { + mag_chg_local = mag_chg[k]; + move16(); + IF (ph_dith != 0 ) + { + Xph = *pCorrPhase; /* in Q16. 2*PI is not included. */ + *seed = own_random2_fx(*seed); /* in Q0 */ + acc = L_mult(*seed, ph_dith); /* N.B. ph_dith[i] is in Q15, i.e., in between 0 and 1.0 (2*PI not included) */ + acc = L_shr(acc, PHASE_DITH_SCALE_SHIFT); + Xph = L_add(Xph, acc); /* in Q16. */ + + IF (ph_dith > 0 ) /* up to 6 dB additional att of peaks in non_transient longer bursts, (when peak phase is randomized ) */ + { + /* mag_chg_local *= 0.5 + (1.0 - ph_dith[i])/2 where 0.5~= sqrt((float)pow(10.0,-6/10.0)) and ph_dith=0..1.0--> scale=1.0 ...5 */ + mag_chg_local = mult_r(mag_chg_local, sub(32767, shr(ph_dith, 1))); + } + Xph_short = s_and(extract_l(L_shr(Xph, 16 - 10)), 0x3ff); + IF (GE_16(Xph_short, 512)) + { + sin_F = negate(sincos_t_ext_fx[Xph_short - 512]); + IF (LT_16(Xph_short, 768)) + { + cos_F = negate(sincos_t_ext_fx[Xph_short - (512 - 256)]); + } + ELSE + { + cos_F = sincos_t_ext_fx[-Xph_short + (1024 + 256)]; + move16(); + } + } + ELSE + { + sin_F = sincos_t_ext_fx[Xph_short]; + move16(); + IF (LT_16(Xph_short, 256)) + { + cos_F = sincos_t_ext_fx[Xph_short + 256]; + move16(); + } + ELSE + { + cos_F = negate(sincos_t_ext_fx[-Xph_short + (256 + 512)]); + } + } + } + + re = *pReX; + move16(); + im = *pImX; + move16(); +#ifdef IVAS_FEC_ECU_TO_COMPLETE + IF(EQ_16(element_mode, EVS_MONO)) +#endif + { + tmp = sub(mult_r(re, cos_F), mult_r(im, sin_F)); + im = add(mult_r(re, sin_F), mult_r(im, cos_F)); + } +#ifdef IVAS_FEC_ECU_TO_COMPLETE + ELSE + { + PMTE() + //tmp = one_peak_flag_mask * (X[i] * cos_F - X[im_ind] * sin_F); + //X[im_ind] = one_peak_flag_mask * (X[i] * sin_F + X[im_ind] * cos_F); + } +#endif + IF (LT_16(alpha[k], 32766)) + { + alpha_local = mag_chg_local; + move16(); + + acc = L_sub(1073741824L, L_mult0(alpha_local, alpha_local)); + acc = Sqrt_l(acc, &expo); + expo = add(30, add(31, expo)); + if (EQ_16(s_and(expo, 1), 1)) + { + acc = Mult_32_16(acc, 23170); /* 1/sqrt(2) in Q15 */ + } + expo = shr(expo, 1); + beta_local = mult_r(beta_mute, round_fx(L_shl(acc, sub(31, expo)))); + + IF (GE_16(k, LGW32K-1)) + { + beta_local = mult_r(beta_local, 3277); /* 0.1 in Q15 */ + } + ELSE if (GE_16(k, LGW16K-1)) + { + beta_local = mult_r(beta_local, 16384); /* 0.5 in Q15 */ + } + + *seed = rand_phase_fx(*seed, &sin_F, &cos_F); + tmp2 = mult_r(beta_local, Xavg[k]); + *pReX++ = add( mult_r(alpha_local, tmp), mult_r(tmp2, cos_F) ); + move16(); + *pImX-- = add( mult_r(alpha_local, im), mult_r(tmp2, sin_F) ); + move16(); + } + ELSE + { + *pReX++ = mult_r(mag_chg_local, tmp); + move16(); + *pImX-- = mult_r(mag_chg_local, im); + move16(); + } + + i = add(i, 1); + if (GE_16(i, ivas_gwlpr[k+1])) + { + k = add(k, 1); + } + } + pCorrPhase++; + } + + segmentLen = sub(shr(Lprot,1), i); + FOR (j = 0; j < segmentLen; j++) + { + *seed = rand_phase_fx(*seed, &sin_F, &cos_F); + + re = *pReX; + move16(); + im = *pImX; + move16(); + tmp = sub(mult_r(re, cos_F), mult_r(im, sin_F)); + im = add(mult_r(re, sin_F), mult_r(im, cos_F)); + IF (LT_16(alpha[k], 32766)) + { + *seed = rand_phase_fx(*seed, &sin_F, &cos_F); + tmp2 = mult_r(beta[k], Xavg[k]); + *pReX++ = add( mult_r(alpha[k], tmp), mult_r(tmp2, cos_F) ); + move16(); + *pImX-- = add( mult_r(alpha[k], im), mult_r(tmp2, sin_F) ); + move16(); + } + ELSE + { + *pReX++ = mult_r(mag_chg[k], tmp); + move16(); + *pImX-- = mult_r(mag_chg[k], im); + move16(); + } + + i = add(i, 1); + if (GE_16(i, ivas_gwlpr[k+1])) + { + k = add(k, 1); + } + } +} + +/*-------------------------------------------------------------------------- + * rec_wtda() + * + * Windowing and TDA of reconstructed frame + *--------------------------------------------------------------------------*/ + +static void rec_wtda_fx( + Word16 *X, /* i : FFT spectrum */ + Word32 *ecu_rec, /* o : Reconstructed frame in tda domain */ + const Word16 output_frame, /* i : Frame length */ + const Word16 Lprot, /* i : Prototype frame length */ + const Word32 fs +) +{ + Word16 l, Lprot2, timesh; + Word16 rec_buf[3*L_FRAME48k]; + Word16 *xsubst_,*out_ptr; + Word16 Qin; + Word16 xf_len; + Word16 i, idx; + Word16 *p_ecu; + Word16 g; + Word16 tbl_delta; +#ifdef IVAS_FEC_ECU_TO_COMPLETE + float xsubst_[2 * L_FRAME48k]; + const float* w_hamm; + float* pX_start, * pX_end; + float tmp; + int16_t hamm_len2; + float* pNew; + const float* pOldW, * pNewW; + float xfwin[NS2SA(L_FRAME48k * FRAMES_PER_SEC, N_ZERO_MDCT_NS - (2 * FRAME_SIZE_NS - L_PROT_NS) / 2)]; + const float* pOld; + int16_t copy_len; + int16_t ola_len; + + copy_len = NS2SA(output_frame * FRAMES_PER_SEC, (2 * FRAME_SIZE_NS - L_PROT_NS) / 2); /* prototype fill on each side of xsubst to fill MDCT Frame */ + ola_len = NS2SA(output_frame * FRAMES_PER_SEC, N_ZERO_MDCT_NS - (2 * FRAME_SIZE_NS - L_PROT_NS) / 2); /* remaining lengt of LA_ZEROS to overlap add decoded with xsubst */ + + if (output_frame == L_FRAME48k) + { + w_hamm = w_hamm_sana48k_2; + hamm_len2 = L_PROT_HAMM_LEN2_48k; + } + else if (output_frame == L_FRAME32k) + { + w_hamm = w_hamm_sana32k_2; + hamm_len2 = L_PROT_HAMM_LEN2_32k; + } + else + { + w_hamm = w_hamm_sana16k_2; + hamm_len2 = L_PROT_HAMM_LEN2_16k; + } + + if (element_mode != EVS_MONO && *num_p > 0 && plocs[0] > 3) + { + /* Perform inverse windowing of hammrect */ + pX_start = X; + pX_end = X + Lprot - 1; + for (i = 0; i < hamm_len2; i++) + { + tmp = 1.0f / *w_hamm; + *pX_start *= tmp; + *pX_end *= tmp; + pX_start++; + pX_end--; + w_hamm++; + } + } + + /* extract reconstructed frame with aldo window */ + timesh = NS2SA(output_frame * FRAMES_PER_SEC, N_ZERO_MDCT_NS) - (2 * output_frame - Lprot) / 2; + + set_f(xsubst_, 0.0f, 2 * output_frame - Lprot + timesh); + mvr2r(X, xsubst_ + 2 * output_frame - Lprot + timesh, Lprot - timesh); + + /* Copy and OLA look ahead zero part of MDCT window from decoded signal */ + if (element_mode != EVS_MONO) + { + mvr2r(old_dec, xsubst_ + NS2SA(output_frame * FRAMES_PER_SEC, N_ZERO_MDCT_NS), copy_len); /* also need to scale to Q0 ?? */ + pOld = old_dec + copy_len; + pNew = xsubst_ + copy_len + NS2SA(output_frame * FRAMES_PER_SEC, N_ZERO_MDCT_NS); + sinq(EVS_PI / (ola_len * 2), 0.0f, ola_len, xfwin); + v_mult(xfwin, xfwin, xfwin, ola_len); /* xfwin = sin^2 of 0..pi/4 */ + pOldW = xfwin + ola_len - 1; + pNewW = xfwin; + for (i = 0; i < ola_len; i++) + { + *pNew = *pOld * *pOldW + *pNew * *pNewW; + pOld += 1; + pNew += 1; + pOldW -= 1; + pNewW += 1; + } + } + else + { + /* Smoothen onset of ECU frame */ + xf_len = (int16_t)((float)output_frame * N_ZERO_MDCT_NS / FRAME_SIZE_NS) - (output_frame - Lprot / 2); + p_ecu = xsubst_ + 2 * output_frame - Lprot + timesh; + tbl_delta = 64.f / xf_len; /* 64 samples = 1/4 cycle in sincos_t */ + for (i = 0; i < xf_len; i++, p_ecu++) + { + g = sincos_t[((int16_t)(i * tbl_delta))]; + g *= g; + *p_ecu = g * (*p_ecu); + } + } + + /* Apply TDA and windowing to ECU frame */ + wtda(xsubst_ + output_frame, ecu_rec, NULL, ALDO_WINDOW, ALDO_WINDOW, output_frame); + +#else + //PMTE() + xsubst_ = rec_buf + output_frame; + Lprot2 = shr(Lprot, 1); + + /* Initialize to WB constants */ + xf_len = 26; + move16(); + tbl_delta = 10082; /* Q12 */ move16(); + IF (EQ_16(output_frame, L_FRAME48k)) + { + xf_len = 78; + move16(); + tbl_delta = 3361; /* Q12 */ move16(); + } + ELSE IF (EQ_16(output_frame, L_FRAME32k)) + { + xf_len = 52; + move16(); + tbl_delta = 5041; /* Q12 */ move16(); + } + + /* extract reconstructed frame with aldo window */ + l = sub(output_frame, Lprot2); + set16_fx(xsubst_,0 , l); + Copy(X, xsubst_ + l, Lprot); + set16_fx(xsubst_ + add(output_frame, Lprot2), 0, l); + + /* Smoothen onset of ECU frame */ + p_ecu = xsubst_ + (output_frame - Lprot2); + FOR ( i = 0; i < xf_len; i++) + { + idx = extract_l(L_shr(L_mult0(i, tbl_delta), 12)); + g = sincos_t_fx[idx]; + g = mult(g, g); + *p_ecu = mult(g, (*p_ecu)); + move16(); + p_ecu++; + } + + timesh = NS2SA_fx2(fs, 10000000L - PH_ECU_ALDO_OLP2_NS); + + set16_fx(rec_buf, 0, output_frame); + Qin = 0; + out_ptr = rec_buf + sub(shl(output_frame,1), timesh); + wtda_fx(out_ptr, &Qin, ecu_rec, NULL, 0, ALDO_WINDOW, ALDO_WINDOW, /* window overlap of current frame (0: full, 2: none, or 3: half) */ + output_frame); +#endif + return; +} + +/*-------------------------------------------------------------------------- + * rec_frame_fx() + * + * Frame reconstruction + *--------------------------------------------------------------------------*/ +static void rec_frame_fx( + Word16 *X, /* i : FFT spectrum */ + Word32 *ecu_rec, /* o : Reconstructed frame in tda domain */ + const Word16 output_frame, /* i : Frame length */ + const Word16 Q +#ifdef IVAS_FEC_ECU_TO_COMPLETE + ,const float* old_dec, /* i : end of last decoded for OLA before tda and itda */ + const int16_t element_mode, /* i : IVAS element mode */ + const int16_t* num_p, /* i : Number of peaks */ + const int16_t* plocs /* i : Peak locations */ +#endif +) +{ + const Word16 *pFftTbl; + Word16 Lprot, lprotLog2Minus1; + Word32 fs; + + fs = L_mult0(output_frame, 50); + + /* Initialize to WB constants */ + Lprot = 512; + move16(); + lprotLog2Minus1 = 9 - 1; + move16(); + pFftTbl = FFT_W256; /* Table for 512-point real input FFT */ + IF (EQ_16(output_frame, L_FRAME48k)) + { + Lprot = L_PROT48k; /* 1536 = (2*output_frame)*1024/1280 */ move16(); + } + ELSE IF (EQ_16(output_frame, L_FRAME32k)) + { + Lprot = L_PROT32k; /* 1024 */ move16(); + lprotLog2Minus1 = 10 - 1; + move16(); + pFftTbl = FFT_W512; /* Table for 1024-point real input FFT */ + } + + /* extend spectrum and IDFT */ + IF (EQ_16(output_frame, L_FRAME48k)) + { + ifft3_fx(X, X, Lprot); + } + ELSE + { + r_fft_fx_lc(pFftTbl, Lprot, shr(Lprot, 1), lprotLog2Minus1, X, X, 0); /* Inverse FFT */ + } + Scale_sig(X, Lprot, -Q); + + rec_wtda_fx(X, ecu_rec, output_frame, Lprot, fs); + + return; +} + +static +Word32 mult_32_32_q(const Word32 a, const Word32 b, const Word16 q) +{ + Word32 hi; + UWord32 lo; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + Mpy_32_32_ss(a, b, &hi, &lo); + +#ifdef BASOP_NOGLOB + return L_or(L_shl_o(hi, 32 - q - 1, &Overflow), L_lshr(lo, q + 1)); +#else + return L_or(L_shl(hi, 32 - q - 1), L_lshr(lo, q + 1)); +#endif +} + +static +void fir_dwn_fx( + const Word16 x[], /* i : input vector Q(x_Q) */ + const Word16 h[], /* i : impulse response of the FIR filter Q(h_Q) */ + const Word16 h_Q, /* H's Q */ + Word16 y[], /* o : output vector (result of filtering) Q~ */ + const Word16 L, /* i : input vector size */ + const Word16 K, /* i : order of the FIR filter (K+1 coefs.) */ + const Word16 decimation /* i : decimation */ +) +{ + Word32 s; + Word16 i, j; + const Word16 *ptr_h, *ptr_x; + Word16 *ptr_y; + Word16 Kdiv2; + Word16 centering; + Word16 tmp; + + centering = sub(16, h_Q); + Kdiv2 = shr(K,1); + + ptr_y = y; + /* do the filtering */ + FOR (i = Kdiv2; i < K; i+=decimation) + { + s = L_deposit_l(0); + ptr_h = h + 1; + ptr_x = x + i - 1; + move16(); + + FOR (j = 1; j <= i; j++) + { + s = L_mac0(s, *ptr_h++, *ptr_x--); + } + +#ifdef BASOP_NOGLOB + *ptr_y++ = extract_h(L_shl_sat(s, centering)); +#else + *ptr_y++ = extract_h(L_shl(s, centering)); +#endif + } + FOR (i = K; i < L; i+=decimation) + { + s = L_deposit_l(0); + ptr_h = h + 1; + ptr_x = x + i - 1; + move16(); + + FOR (j = 1; j <= K; j++) + { +#ifdef BASOP_NOGLOB + s = L_mac0_sat(s, *ptr_h++, *ptr_x--); +#else + s = L_mac0(s, *ptr_h++, *ptr_x--); +#endif + } + +#ifdef BASOP_NOGLOB + *ptr_y++ = extract_h(L_shl_sat(s, centering)); +#else + *ptr_y++ = extract_h(L_shl(s, centering)); +#endif + } + tmp = add(L,Kdiv2); + FOR (i = i; i < tmp; i+=decimation) + { + s = L_deposit_l(0); + ptr_h = h + i - L + 1; + move16(); + ptr_x = x + L - 1; + move16(); + + FOR (j = add(sub(i,L),1); j <= K; j++) + { +#ifdef BASOP_NOGLOB + s = L_mac0_sat(s, *ptr_h++, *ptr_x--); +#else + s = L_mac0(s, *ptr_h++, *ptr_x--); +#endif + } + +#ifdef BASOP_NOGLOB + *ptr_y++ = extract_h(L_shl_sat(s, centering)); +#else + *ptr_y++ = extract_h(L_shl(s, centering)); +#endif + } + + return; +} + +/*-------------------------------------------------------------------------- + * fec_ecu_pitch() + * + * Pitch/correlation analysis and adaptive analysis frame length calculation + *--------------------------------------------------------------------------*/ + +static +void fec_ecu_pitch_fx( + const Word16 *prevsynth_fx, /*Q15 16 */ + Word16 *prevsynth_LP_fx, /* Q15 16 */ + const Word16 L, + Word16 *N, + Word16 *min_corr_fx, /* Q15 16 */ + Word16 *decimatefator, + const Word16 HqVoicing +) +{ + + Word16 i,filt_size; + Word16 QAsr,Ryy,cb_start, tmpQLP; + Word32 Ryytmp; + Word32 accA,accB, accBisqrt,accC, accCisqrt; + Word16 delay_ind,k; + const Word16 *Asr_LP_fx; + Word16 *ptr_LP, *ptr_LP2, *ptr_LP3, *ptr_LP4; + Word16 cb_end; + Word16 Lmul2, Lon20mul6, Lon20mul28, Lon20mul33, Lon20mul34; + + + SWITCH(L) + { + case L_FRAME48k: + *decimatefator=6; + move16(); + filt_size=60; + move16(); + Asr_LP_fx = Asr_LP48_fx; + QAsr = 17; + move16(); + Lon20mul6 = 48; + move16(); + Lon20mul28 = 224; + move16(); + Lon20mul33 = 264; + move16(); + Lon20mul34 = 272; + move16(); + Lmul2 = 1920; + move16(); + BREAK; + + case L_FRAME32k: + *decimatefator=4; + move16(); + filt_size=40; + move16(); + Asr_LP_fx = Asr_LP32_fx; + QAsr = 15; + move16(); + Lon20mul6 = 48; + move16(); + Lon20mul28 = 224; + move16(); + Lon20mul33 = 264; + move16(); + Lon20mul34 = 272; + move16(); + Lmul2 = 1280; + move16(); + BREAK; + + case L_FRAME16k: + *decimatefator=2; + move16(); + filt_size=20; + move16(); + Asr_LP_fx = Asr_LP16_fx; + QAsr = 15; + move16(); + Lon20mul6 = 48; + move16(); + Lon20mul28 = 224; + move16(); + Lon20mul33 = 264; + move16(); + Lon20mul34 = 272; + move16(); + Lmul2 = 640; + move16(); + BREAK; + + default: + *decimatefator=2; + move16(); + filt_size=40; + move16(); + Asr_LP_fx = Asr_LP16_fx; + QAsr = 15; + move16(); + Lon20mul6 = 48; + move16(); + Lon20mul28 = 224; + move16(); + Lon20mul33 = 264; + move16(); + Lon20mul34 = 272; + move16(); + Lmul2 = 320; + move16(); + BREAK; + } + + + /* Resampling to work at 8Khz */ + fir_dwn_fx(prevsynth_fx, Asr_LP_fx, QAsr, prevsynth_LP_fx, Lmul2, filt_size, *decimatefator); /* resampling without delay */ + + + tmpQLP = Find_Max_Norm16(prevsynth_LP_fx,320); + Scale_sig(prevsynth_LP_fx,320,sub(tmpQLP,3)); /* to avoid over scaling */ + + + + /* Correlation analysis */ + *min_corr_fx = 0; + move16(); + accC = L_deposit_l(0); + + ptr_LP = prevsynth_LP_fx + Lon20mul34; + FOR (k = 0; k < Lon20mul6; k++) + { + accC = L_mac0 (accC, *ptr_LP, *ptr_LP); + ptr_LP++; + + } + + + + IF (HqVoicing==1) + { + cb_start=0; + cb_end=Lon20mul33; + } + ELSE + { + cb_start=0; + cb_end=Lon20mul28; + } + + accB=0; + delay_ind=cb_start; + + FOR (i=cb_start; i *min_corr_fx ) + { + *min_corr_fx = Ryy; + delay_ind = i; + } + + test(); + IF ( HqVoicing == 0 && *min_corr_fx > 31130) + { + BREAK; + } + } + + *N= sub(Lon20mul34, delay_ind); + + + Scale_sig(prevsynth_LP_fx,320,negate(sub(tmpQLP,3))); + return; +} + +static +void sin_cos_est_fx(Word32 phi, Word16 *cosfreq, Word16 *sinfreq) +{ + + + /* i phi : normalized frequency beteween 0 and Pi (nyquist) in Q30 */ + /* o cosfreq & sinfreq : cos(phi) and sin (phi) in Q15 */ + + Word16 i; + Word32 delta; + Word32 imin; + Word16 sinb, cosb; + Word32 sinv, cosv, tmp; + + i=0; + move16(); + FOR (imin=0; imin0 || HqVoicing */ + } + + + + + pt4 = pulses; + nb_pulses=0; + move16(); + PL=0; + move16(); + cpt=0; + move16(); + old=0; + move16(); + glued=1; + move16(); + new_s=Tf_abs[1]; + move16(); + if (flag ) + { + PL=1; + move16(); + } + tmp=sub(shr(N,1),3); + WHILE(LE_16(cpt,tmp)) + { + test(); + IF(GT_16(Tf_abs[cpt],old)&>_16(Tf_abs[cpt],new_s)) + { + Word16 tmp2; + + glued=cpt; + move16(); + + tmp2 = add(add(cpt,PL),1); + FOR (i=glued; i scaling of a_re is Qin+sN */ + *pt2++ = Tfi[indmax]; + move16(); /*L_shr(Tfi[indmax], sN); //instead shr -> scaling of a_im is Qin+sN */ + *pt3++ = indmax; + move16(); + Tf_abs[indmax] = -1; + move16(); + } + + } + ELSE + { + DO + { + mmax = 0; + move16(); + pt4 = pulses; + FOR ( k=0; k scaling of a_re is Qin+sN */ + *pt2++ = Tfi[indmax]; + move16(); /*L_shr(Tfi[indmax], sN); //instead shr -> scaling of a_im is Qin+sN */ + *pt3++ = indmax; + move16(); + Tf_abs[indmax] = -1; + move16(); + + maxi=sub(maxi,1); + } WHILE( maxi>0 && LT_32(cumsum, L_tmp)); + + nb_pulses_final = sub(nb_pulses_final,maxi); + move16(); + } + + + /* sinusoidal synthesis */ + + + set32_fx(synthesis_fx,0,Len); + + exp = add(exp,sN); + + + pt1 = a_re; + pt2 = a_im; + pt3 = freqi; + q = shr_r(N,2); + if (GT_16(N,shl(q,2))) + { + q = add(q,1); + } + + inv_den = i_mult2(N,decimate_factor); /*Q0 */ + + /*tmp = div_s(12868,inv_den);*/ /*Q15 */ + + + FOR ( i=0; i 0 ) + { + tmp_fx = Random(ni_seed_forfec); + + L_tmp = L_mac(1503264768, tmp_fx ,9830); + if ( kk == 0 ) + { + L_tmp = L_mac(1073741824, tmp_fx ,6554); + } + + kk = sub(1,kk) ; + tmp_fx = round_fx(L_tmp); + Rnd_N_noise = extract_h(L_mult(N_noise, tmp_fx)); /*Q0 */ + + + tmp_fx = div_s(1, Rnd_N_noise); /*Q15 */ + tmp_fx = round_fx(L_shl(L_mult(tmp_fx, 25736),2)); /*Q15 */ +#ifdef IVAS_FEC_ECU_TO_COMPLETE + if (element_mode == EVS_MONO) + { + kk = 7 * L / 20; + p_mdct_ola = prevsynth + 37 * L / 20; + } + else + { + kk = NS2SA(L * FRAMES_PER_SEC, N_ZERO_MDCT_NS); + p_mdct_ola = old_out + kk; + } +#endif + + sinq_fx( shr(tmp_fx,1), shr(tmp_fx,2), Rnd_N_noise, SS_fx); + + pt2 = &noisevect_fx[N_noise]; + pt1 = pt2 - Rnd_N_noise; + pt3 = SS_fx; + pt4 = pt3 + sub(Rnd_N_noise,1); + tmp_fx = s_min(Rnd_N_noise, flag); + FOR ( i=0 ; i 0) + { + seed = add(seed, plocs[*num_p-1]); + } + + subst_spec_fx(plocs, plocsi, num_p, *time_offs, X, mag_chg, ph_dith, old_is_transient, output_frame, &seed, + alpha, beta, *beta_mute, Xavg +#ifdef IVAS_FEC_ECU_TO_COMPLETE + , element_mode, ph_ecu_lookahead, noise_fac +#endif + ); + + /* reconstructed frame in tda domain */ +#ifdef IVAS_FEC_ECU_TO_COMPLETE + old_dec = prevsynth + 2 * output_frame - NS2SA(output_frame * FRAMES_PER_SEC, N_ZERO_MDCT_NS); +#endif + rec_frame_fx(X, ecu_rec, output_frame, *Q_spec +#ifdef IVAS_FEC_ECU_TO_COMPLETE + , old_dec, element_mode, num_p, plocs +#endif + ); + + *last_fec = 0; + *ph_ecu_active = 1; + move16(); +} + + +/*-------------------------------------------------------------------------- + * hq_ecu() + * + * Main routine for HQ ECU + *--------------------------------------------------------------------------*/ +void hq_ecu_fx( + const Word16 *prevsynth, /* i : buffer of previously synthesized signal */ + Word32 *ecu_rec, /* o : reconstructed frame in tda domain */ + Word16 *time_offs, /* i/o: Sample offset for consecutive frame losses */ + Word16 *X_sav, /* i/o: Stored spectrum of prototype frame */ + Word16 *Q_spec, /* i/o: Q value of stored spectrum */ + Word16 *num_p, /* i/o: Number of identified peaks */ + Word16 *plocs, /* i/o: Peak locations */ + Word32 *plocsi, /* i/o: Interpolated peak locations Q16 */ + const Word16 env_stab, /* i : Envelope stability parameter */ + Word16 *last_fec, /* i/o: Flag for usage of pitch dependent ECU */ + const Word16 ph_ecu_HqVoicing, /* i : HQ Voicing flag */ + Word16 *ph_ecu_active, /* i : Phase ECU active flag */ + Word16 *gapsynth, /* o : Gap synthesis */ + const Word16 prev_bfi, /* i : indicating burst frame error */ + const Word16 old_is_transient[2], /* i : flags indicating previous transient frames */ + Word16 *mag_chg_1st, /* i/o: per band magnitude modifier for transients */ + Word16 *Xavg, /* i/o: Frequency group average gain to fade to */ + Word16 *beta_mute, /* o : Factor for long-term mute */ + const Word16 output_frame, /* i : frame length */ + Decoder_State *st_fx /* i/o: decoder state structure */ +) +{ + Word16 N; + Word16 decimatefactor; + Word16 corr; /*Q15 */ + Word16 prevsynth_LP[2*L_FRAME8k]; +#ifdef IVAS_FEC_ECU_TO_COMPLETE + HQ_DEC_HANDLE hHQ_core; + const float* fec_alg_input; + int16_t evs_mode_selection; + int16_t ivas_mode_selection; + + hHQ_core = st->hHQ_core; + if (st->element_mode == EVS_MONO) + { + fec_alg_input = prevsynth + NS2SA(output_frame * FRAMES_PER_SEC, ACELP_LOOK_NS / 2 - PH_ECU_LOOKAHEAD_NS); + } + else + { + fec_alg_input = prevsynth - NS2SA(output_frame * FRAMES_PER_SEC, PH_ECU_LOOKAHEAD_NS); + } +#endif + /* init (values ar changed after) */ + decimatefactor=4; + N=shr(output_frame,2); + + + /* find pitch and R value */ + + IF (!(LT_16(output_frame,L_FRAME16k))) + { +#ifdef IVAS_FEC_ECU_TO_COMPLETE + fec_ecu_pitch_fx(fec_alg_input, prevsynth_LP, output_frame, &N, &corr, &decimatefactor, ph_ecu_HqVoicing); +#else + fec_ecu_pitch_fx( prevsynth+NS2SA(output_frame*50,ACELP_LOOK_NS/2-PH_ECU_LOOKAHEAD_NS), prevsynth_LP, output_frame, &N, &corr, &decimatefactor, ph_ecu_HqVoicing); +#endif + } + ELSE + { + corr = 0; + move16(); /* just to avoid using uninitialized value in if statement below */ + } + + test();test();test();test();test();test(); + test();test();test();test();test();test(); + test();test();test(); +#if defined IVAS_FEC_ECU_TO_COMPLETE + evs_mode_selection = (st->total_brate >= 48000 && (output_frame >= L_FRAME16k && !prev_bfi && (!old_is_transient[0] || old_is_transient[1]) && + (ph_ecu_HqVoicing || (((hHQ_core->env_stab_plc > 0.5) && (corr < 0.6)) || (hHQ_core->env_stab_plc < 0.5 && (corr > 0.85)))))) || + (st->total_brate < 48000 && ((ph_ecu_HqVoicing || corr > 0.85) && !prev_bfi && (!old_is_transient[0] || old_is_transient[1]))); + + ivas_mode_selection = (N < PH_ECU_N_LIMIT) || (corr < PH_ECU_CORR_LIMIT); + if (((st->element_mode == EVS_MONO) && evs_mode_selection) || + ((st->element_mode != EVS_MONO) && evs_mode_selection && ivas_mode_selection)) + + { + fec_alg_fx(fec_alg_input, prevsynth_LP, ecu_rec, output_frame, N, decimatefactor, ph_ecu_HqVoicing, gapsynth, &hHQ_core->ni_seed_forfec, st->element_mode, st->hHQ_core->old_out); + *last_fec = 1; + *ph_ecu_active = 0; + move16(); + *time_offs = output_frame; + move16();; + } + else + { + hq_phase_ecu(prevsynth - NS2SA(output_frame * FRAMES_PER_SEC, PH_ECU_LOOKAHEAD_NS), ecu_rec, time_offs, X_sav, num_p, plocs, plocsi, env_stab, last_fec, prev_bfi, old_is_transient, mag_chg_1st, Xavg, beta_mute, st->bwidth, output_frame, corr, st->element_mode); + + *last_fec = 0; + *ph_ecu_active = 1; + } +#else + IF ( (GE_32(st_fx->total_brate,48000)&& + ( GE_16(output_frame, L_FRAME16k) && !prev_bfi && (!old_is_transient[0] || old_is_transient[1] ) && (NE_16(ph_ecu_HqVoicing,0) || ( ((NE_16(st_fx->hHQ_core->env_stab_plc_fx ,0)) && (LT_16(corr,19661))) || (!(NE_16(st_fx->hHQ_core->env_stab_plc_fx ,0)) && (GT_16(corr, 27853)) ))))) || + (LT_32(st_fx->total_brate,48000) && ( ( ph_ecu_HqVoicing || GT_16(corr, 27853)) && !prev_bfi && (!old_is_transient[0] || old_is_transient[1]) )) ) + { + + fec_alg_fx( prevsynth+NS2SA(output_frame*50,ACELP_LOOK_NS/2-PH_ECU_LOOKAHEAD_NS), prevsynth_LP, &st_fx->hHQ_core->ni_seed_forfec, ecu_rec, output_frame, N, decimatefactor, ph_ecu_HqVoicing, gapsynth); + *last_fec = 1; + *ph_ecu_active = 0; + move16(); + *time_offs = output_frame; + move16(); + } + ELSE + { + hq_phase_ecu_fx( prevsynth, ecu_rec, time_offs, X_sav, Q_spec, num_p, plocs, plocsi, + env_stab, last_fec, ph_ecu_active, prev_bfi, old_is_transient, + mag_chg_1st, Xavg, beta_mute, st_fx->bwidth, output_frame ); + } +#endif + return; +} + +/******************************************************************************* + * The square root of x which MUST be 0.5 <= x < 1, i.e., x must be normalized. + * sqrt(x) is approximated by a polynomial of degree n. + * + * sqrt(x) = a0 x^n + a1 x^(n-1) + a2 x^(n-2) + ... + an + * = (...((a0 x + a1) x + a2) x + ...) x + an + * + * The coefficients can be readily obtained by the following open source Octave + * (or commercial Matlab) script: + * order = 2; + * N = 400; + * x = linspace(0.5, 1.0, N); + * y = sqrt(x); + * p = polyfit(x, y, order) + * z = polyval(p, x); + * err = y - z; + * plot(err); + ******************************************************************************/ + +static Word16 sqrt2ndOrder( /* o: in Q15 (2nd order least square approx.) */ + const Word16 x /* i: x must be in between 0.5 and 1.0 (Q15). */ +) +{ + Word32 acc; + Word16 z; + + acc = 1890205600L; /* 0.880195572812922 in Q31 */ move32(); + z = mac_r(acc, x, -6506); /* -0.198537395405340 in Q15 */ + acc = 682030261L; /* 0.317595089462249 in Q31 */ move32(); + z = mac_r(acc, z, x); /* in Q15 */ + return z; +} + +/*----------------------------------------------------------------------------- + * windowing() + * + * Apply a symmetric Hamming or Hamming-Rectangular window to the signal. + * If the "rectLength" parameter is zero, it is Hamming window; otherwise, the + * rectLength signifies the length of the rectangular part of the Hamming-Rectangular + * window. + *--------------------------------------------------------------------------- */ +static void windowing( + const Word16 *x, /* i: Input signal */ + Word16 *y, /* o: Windowed output */ + const Word16 *win, /* i: Window coefficients */ + const Word16 rectLength, /* i: Offset in between the 1st and 2nd symmetric halves of the Hamming window */ + const Word16 halfLength /* i: Half of the total length of a complete Hamming window. */ +) +{ + Word16 i; + Word16 *pY; + const Word16 *pX, *pW; + pX = x; + pW = win; + pY = y; + FOR (i = 0; i < halfLength; i++) /* 1st symmetric half of the Hamming window */ + { + *pY++ = mult_r(*pX++, *pW++); + move16(); + } + FOR (i = 0; i < rectLength; i++) /* If rectLength is zero, it's a pure Hamming window; otherwise Hamming-Rectangular. */ + { + *pY++ = *pX++; + move16(); + } + FOR (i = 0; i < halfLength; i++) /* 2nd symmetric half of the Hamming window. */ + { + *pY++ = mult_r(*pX++, *(--pW)); + move16(); + } +} + +/*----------------------------------------------------------------------------- + * windowing_ROM_optimized() + * + * The coefficients of the Hamming window are derived from the sine table + * shared with fft3_fx(). + * The entire Hamming-Rectangular window is decomposed into 5 segments: + * 1. 1st half of the left half of the Hamming window + * 2. 2nd half of the left half of the Hamming window + * 3. The flat part of the rectangular region + * 4. 1st half of the right half of the Hamming window + * 5. 2nd half of the right half of the Hamming window + *----------------------------------------------------------------------------*/ +static void windowing_ROM_optimized( + const Word16 *x, /* i: Input signal */ + Word16 *y, /* o: Windowed output */ + const Word16 downSamples,/* i: Offset in accessing the sine table. */ + const Word16 rectLength, /* i: Length of the rectangular portion (excluding the Hamming window part) */ + const Word16 halfLength /* i: Half of the total length of the Hamming (excluding rectangular part) window */ +) +{ + Word16 i, hamm, quarterLen, initOffset; + Word16 *pY; + const Word16 *pX, *pSine; + Word32 acc; + + quarterLen = shr(halfLength, 1); /* 1/4 length of the entire Hamming (excluding the rectangular part) window. */ + initOffset = add(T_SIN_PI_2, shr(downSamples,1)); + pSine = sincos_t_rad3_fx + initOffset; + pX = x; + pY = y; + + /* 1st half of the left half of the Hamming window. */ + FOR (i = 0; i < quarterLen; i++) + { + pSine -= downSamples; /* Decrement address counter */ + acc = L_deposit_h(FEC_HQ_WIN_A0); /* Derive the Hamming window coefficient from the sine table. */ + hamm = msu_r(acc, *pSine, FEC_HQ_WIN_A1); + *pY++ = mult_r(hamm, *pX++); + move16(); + } + + /* 2nd half of the left half of the Hamming window. */ + FOR (i = 0; i < quarterLen; i++) + { + acc = L_deposit_h(FEC_HQ_WIN_A0); +#ifdef BASOP_NOGLOB + hamm = mac_r_sat(acc, *pSine, FEC_HQ_WIN_A1); +#else + hamm = mac_r(acc, *pSine, FEC_HQ_WIN_A1); +#endif + *pY++ = mult_r(hamm, *pX++); + move16(); + pSine += downSamples; /* Increment address counter */ + } + + /* The rectangular flat region */ + FOR (i = 0; i < rectLength; i++) + { + *pY++ = *pX++; + move16(); + } + + /* 1st half of the right half of the Hamming window. */ + FOR (i = 0; i < quarterLen; i++) + { + pSine -= downSamples; /* Decrement address counter */ + acc = L_deposit_h(FEC_HQ_WIN_A0); +#ifdef BASOP_NOGLOB + hamm = mac_r_sat(acc, *pSine, FEC_HQ_WIN_A1); +#else + hamm = mac_r(acc, *pSine, FEC_HQ_WIN_A1); +#endif + *pY++ = mult_r(hamm, *pX++); + move16(); + } + + /* 2nd half of the right half of the Hamming window. */ + FOR (i = 0; i < quarterLen; i++) + { + acc = L_deposit_h(FEC_HQ_WIN_A0); + hamm = msu_r(acc, *pSine, FEC_HQ_WIN_A1); + *pY++ = mult_r(hamm, *pX++); + move16(); + pSine += downSamples; /* Increment address counter */ + } +} diff --git a/lib_dec/FEC_adapt_codebook_fx.c b/lib_dec/FEC_adapt_codebook_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..af58ed75728f9e45fd4aef9bec63fcdb8e6215cb --- /dev/null +++ b/lib_dec/FEC_adapt_codebook_fx.c @@ -0,0 +1,536 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ +#include +#include +#include "options.h" /* Compilation switches */ +#include "cnst.h" /* Common constants */ +#include "rom_dec.h" /* Decoder static table prototypes */ +#include "prot_fx1.h" /* Function prototypes */ +#include "prot_fx2.h" /* Function prototypes */ + + +/*---------------------------------------------------------------------* + * FEC_SinOnset() + * + * Create an artificial onset when it is lost + *---------------------------------------------------------------------*/ +Word16 FEC_SinOnset_fx ( + Word16 *exc, /* i/o : exc vector to modify */ + Word16 puls_pos, /* i : last pulse position desired */ + const Word16 T0, /* i : Pitch information of the 1 subfr */ + Word32 enr_q, /* i : energy provide by the encoder */ + Word16 *Aq, /* i : A(z) filter Q12 */ + const Word16 L_frame /* i : frame length */ + ,const Word16 Qold +) +{ + Word16 P0, onset_len, sign, i, len, L_subfr, L_subfr2; + Word16 h1[L_SUBFR16k], mem[M], exc_tmp[L_FRAME16k+ MODE1_L_FIR_FER]; + Word16 *pt_end, *pt_exc, enr_LP, gain, H_low_s[5], exp_gain, exp2, tmp; + Word32 L_tmp; + Word16 Q_exc; + + sign = 0; + move16(); + Q_exc = Qold; + move16(); + L_subfr = L_SUBFR; + move16(); + if( EQ_16(L_frame,L_FRAME16k)) + { + L_subfr = L_SUBFR16k; + move16(); + } + + L_subfr2 = shl(L_subfr,1); + onset_len = s_max(T0, L_subfr2); + + P0 = puls_pos; + move16(); + + IF (P0 < 0) + { + sign = 1; + move16(); + P0 = negate(P0); + } + + test(); + test(); + IF ( GT_16(P0,PIT_MAX)&&EQ_16(L_frame,L_FRAME)) + { + P0 = PIT_MAX; + move16();/* Should never be the case, however... */ + } + ELSE if ( GT_16(P0,PIT16k_MAX)&&EQ_16(L_frame,L_FRAME16k)) + { + P0 = PIT16k_MAX; + move16(); /* Should never be the case, however... */ + } + set16_fx( exc_tmp, 0, add(L_frame, MODE1_L_FIR_FER)); /* Reset excitation vector */ + + /*-------------------------------------------------------------------------------* + * Find LP filter impulse response energy and Generate the scaled pulse prototype + *-------------------------------------------------------------------------------*/ + + set16_fx(h1, 0, L_subfr); /* Find the impulse response */ + set16_fx(mem, 0, M); + h1[0] = 1024; + move16(); + Syn_filt_s(1, Aq, M, h1, h1, L_subfr, mem, 0); + + + enr_LP = extract_h(Dot_product12(h1, h1, L_subfr, &exp_gain)); + exp_gain = sub(exp_gain, 10 + 10); /* h1 in Q10 */ + + /* divide by LP filter E, scaled by transmitted E */ + /* gain = (float)sqrt( enr_q / enr_LP ); */ + + enr_q = L_max(enr_q,1); + + exp2 = norm_l(enr_q); + tmp = extract_h(L_shl(enr_q, exp2)); + tmp = mult(tmp, 24576); /* multpiply by 1.5 */ + + IF(LT_16(tmp, 16384)) + { + exp2 = add(exp2, 1); + tmp = shl(tmp, 1); + } + exp2 = sub(30, exp2); /* in Q15 */ + + + IF(GT_16(enr_LP, tmp)) + { + enr_LP = shr(enr_LP, 1); + exp_gain = add(exp_gain, 1); + } + + tmp = div_s(enr_LP, tmp); + exp2 = sub(exp_gain, exp2); + + L_tmp = L_deposit_h(tmp); + L_tmp = Isqrt_lc(L_tmp, &exp2); + gain = round_fx(L_tmp); + + gain = mult_r(gain, 31457); /* multiply by .96 like floating point */ + exp2 = add(sub(exp2, 15), Q_exc); /* from Q15 to Q_exc */ + + /* Find if rescaling needed */ + tmp = extract_h(L_mult(H_low[2], gain)); + exp_gain = norm_s(tmp); + tmp = sub(exp_gain, exp2); /* difference */ + + IF(tmp < 0)/* Need to correct scaling */ + { + Q_exc = add(Q_exc, tmp); + exp2 = add(exp2, tmp); + } + /* Scale pulse "prototype" energy */ + /* Generate the scaled pulse */ + FOR(i = 0; i < MODE1_L_FIR_FER; i++) + { + L_tmp = L_mult(gain, H_low[i]); /* Q_exc*Q15 -> Q_exc */ + H_low_s[i] = round_fx(L_shl(L_tmp, exp2)); + } + /*------------------------------------------------------------------------------------------* + * Construct the harmonic part as a train of low-pass filtered pulses + *------------------------------------------------------------------------------------------*/ + move16(); + move16(); + move16(); + pt_exc = exc_tmp + sub(L_frame, add(add(1, MODE1_L_FIR_FER/2), P0)); /* beginning of the 1st pulse */ + pt_end = exc_tmp + onset_len; + len = (Word16) (pt_exc - pt_end); + + len = s_min(len, MODE1_L_FIR_FER); + IF(!sign) + { + + FOR(i = 0; i < len; i++) + { + /* The filter response would have E=1 in full band. */ + pt_exc[i] = add(pt_exc[i], H_low_s[i]); + move16(); + } + } + ELSE + { + FOR(i = 0; i < len; i++) + { + /* The filter response would have E=1 in full band. */ + pt_exc[i] = sub(pt_exc[i], H_low_s[i]); + move16(); + } + } + Copy(&exc_tmp[L_frame - L_EXC_MEM], exc, L_EXC_MEM); + return Q_exc; +} + +Word16 FEC_enhACB_fx( + const Word16 L_frame, /* i : frame length */ + const Word16 last_L_frame, /* i : frame length of previous frame */ + Word16 *exc_io, /* i/o : adaptive codebook memory */ + const Word16 new_pit, /* i : decoded first frame pitch */ + const Word16 puls_pos, /* i : decoder position of the last glottal pulses decoded in the previous frame */ + const Word16 bfi_pitch /* i : Q6 pitch used for concealment */ +) +{ + Word16 Tc, P0, sign, pit_search; + Word16 Tlist[10], Terr, diff_pit, dist_Plast; + Word16 tmp2; + Word16 exc[L_FRAME16k + L_SUBFR]; + Word16 Do_WI = 1; + move16(); + + + set16_fx(exc, 0, L_FRAME16k - L_EXC_MEM); + set16_fx(exc+L_FRAME16k, 0, L_SUBFR); + Copy(exc_io, exc + L_FRAME16k - L_EXC_MEM, L_EXC_MEM); + + Tc = shr(bfi_pitch,6); + Copy(exc + L_FRAME16k - Tc, exc + L_FRAME16k, L_SUBFR); + + /*------------------------------------------------------------ + * Decode phase information transmitted in the bitstream + * (The position of the absolute maximum glottal pulse from + * the end of the frame and its sign) + *------------------------------------------------------------*/ + + P0 = puls_pos; + move16(); + sign = 0; + move16(); + IF (P0 < 0) + { + sign = 1; + move16(); + P0 = negate(P0); + } + + IF( EQ_16(L_frame,L_FRAME)) + { + P0 = s_min(PIT_MAX, P0); + } + ELSE /* L_frame == L_FRAME16k */ + { + P0 = s_min(PIT16k_MAX, P0); + } + + /*---------------------------------------------------------------------------------- + * Find the position of the first the maximum(minimum) lp_filtered pulse + * <----- Mem --->|<--------------------- L_frame ------------>|<----- L_SUBFR --->| + * |<-------pit_search----> | | + *----------------------------------------------------------------------------------*/ + + pit_search = Tc; + move16(); + + Tlist[0] = findpulse_fx( L_frame, exc+sub(L_frame,pit_search) , pit_search,DEC, &sign); + + /*Terr = (short) abs(pit_search-Tlist[0]-P0);*/ + Terr = abs_s(sub(pit_search,add(Tlist[0],P0))); + + dist_Plast = sub(Tc,Tlist[0]); + + Tlist[1] = findpulse_fx( L_frame, exc+sub(L_frame,pit_search) , add(pit_search,L_SUBFR),DEC, &sign); + + + /*if(Terr > abs(Tlist[1]-Tc + P0))*/ + IF(GT_16(Terr,abs_s(add(sub(Tlist[1],Tc), P0)))) + { + dist_Plast = sub(Tc,Tlist[1]); + Terr = abs_s(add(sub(Tlist[1],Tc), P0)); + } + + diff_pit = abs_s(sub(new_pit, Tc)); + /*ftmp = (float) (int)((float)L_frame/(float)Tc+0.5);*/ + tmp2 = mult_r(div_s(16, Tc), shr(L_frame,4)); + test(); + test(); + IF (LE_16(Terr, i_mult(tmp2, diff_pit))&& + Terr != 0 && /* If Terr = 0, no resynchronization required */ + sub(Terr, L_SUBFR) < 0 )/* prevent catastrophy search */ + { + /* performe excitation resynchronization here */ + Do_WI = FEC_synchro_exc_fx( L_frame, exc, P0, dist_Plast, Tc ); + move16(); + Copy(exc + L_FRAME16k - L_EXC_MEM, exc_io, L_EXC_MEM); + } + ELSE + { + Do_WI = 0; + move16(); + } + + if( NE_16(last_L_frame, L_FRAME16k)) + { + Do_WI = 0; + move16(); + } + + return Do_WI; +} + +Word16 FEC_synchro_exc_fx( /* o : do_WI flag */ + const Word16 L_frame, /* i : length of the frame */ + Word16 *exc, /* i/o: exc vector to modify */ + const Word16 desire_puls_pos, /* i : Pulse position send by the encoder */ + const Word16 true_puls_pos, /* i : Present pulse location */ + const Word16 Old_pitch /* i : Pitch use to create temporary adaptive codebook */ +) +{ + Word16 exc_tmp[L_FRAME16k+L_SUBFR]; + Word16 fact; + Word32 L_min_energy, L_tmp; + Word16 *pt_exc, *pt_exc1; + Word16 i, j, point_to_remove, point_to_add, nb_min; + Word16 min_pos[L_FRAME16k/PIT_MIN_DOUBLEEXTEND], points_by_pos[L_FRAME16k/PIT_MIN_DOUBLEEXTEND]; + Word16 total_point, tmp_len; + Word16 *pt_pos, pos, start_search, tmp16; + Word16 remaining_len; + + point_to_add = -1; + move16(); + + /* Init */ + FOR (i = 0; i < L_FRAME16k/PIT_MIN_DOUBLEEXTEND; i++) + { + min_pos[i] = 10000; + move16(); + points_by_pos[i] = 0; + move16(); + } + + /* Find number of point to remove and number of minimum */ + point_to_remove = sub(true_puls_pos, desire_puls_pos); /* if it is negative it means remove point else it means add point */ + + pos = sub(L_frame, true_puls_pos); + + /* Find number of minimum energy region */ + /* nb_min = (L_FRAME - true_puls_pos)/Old_pitch */ + tmp16 = shl(Old_pitch, 5); + tmp16 = div_s(pos, tmp16); + nb_min = shr(tmp16, 10); + /* if Old pitch < 128, must have at least 2 min */ + if (LE_16(Old_pitch, 128)) + { + nb_min = s_max(nb_min, 2); + } + /* Must have at least 1 min */ + nb_min = s_max(nb_min, 1); + + pt_exc = exc + pos; + move16(); + + /* Find starting point for minimum energy search */ + start_search = mult_r(Old_pitch, -24576); + if(EQ_16(s_and(Old_pitch,3),1)) + { + /* Only be align with integer operation -3*Old_pitch/4 */ + start_search = add(start_search,1); + } + IF (add(start_search, pos) < 0) + { + start_search = negate(pos); + IF (LT_16(abs_s(start_search), shr(Old_pitch, 3))) + { + /* it's not safe to remove/add point inside 1/8 of the pulse position */ + return 0; + } + } + + /* Find min energy in the first pitch section */ + /* -------------------------------------------------------------------- + * The minimum energy regions are determined by the computing the energy + * using a sliding 5-sample window. The minimum energy position is set + * at the middle of the window at which the energy is at minimum + * --------------------------------------------------------------------*/ + L_min_energy = L_add(MAX_32, 0); + L_tmp = L_mult(pt_exc[start_search], pt_exc[start_search]); + L_tmp = L_mac(L_tmp, pt_exc[start_search + 1], pt_exc[start_search + 1]); + L_tmp = L_mac(L_tmp, pt_exc[start_search + 2], pt_exc[start_search + 2]); + L_tmp = L_mac(L_tmp, pt_exc[start_search + 3], pt_exc[start_search + 3]); + L_tmp = L_mac(L_tmp, pt_exc[start_search + 4], pt_exc[start_search + 4]); + + IF (LT_32(L_tmp, L_min_energy)) + { + L_min_energy = L_add(L_tmp, 0); + min_pos[0] = add(add(pos, start_search), 2); + } + + FOR (i = start_search; i < -5; i++) + { + L_tmp = L_msu(L_tmp, pt_exc[i], pt_exc[i]); + L_tmp = L_mac(L_tmp, pt_exc[i + 5], pt_exc[i + 5]); + + IF (LT_32(L_tmp, L_min_energy)) + { + L_min_energy = L_tmp; /* sets to 'L_tmp' in 1 clock */ + move32(); + min_pos[0] = add(add(pos, i), 2); + } + } + + FOR (j = 1; j < nb_min; j++) + { + min_pos[j] = sub(min_pos[j-1], Old_pitch); + /* If the first minimum is in the past, forget this minimum */ + IF (min_pos[j] < 0) + { + min_pos[j] = -10000; + move16(); + nb_min = sub(nb_min, 1); + } + } + + /* safety-measure against not properly initialized min_pos[] */ + IF( GE_32(L_min_energy, MAX_32)) + { + return 0; + } + + IF(GT_16(nb_min,16)) /* inv_sqi & sqi are built for a maximum of nb_min-2 = 14 values*/ + { + return 0; + } + /*-------------------------------------------------------------------- + * Determine the number of samples to be added or removed at each pitch + * cycle whereby less samples are added/removed at the beginning and + * more towards the end of the frame + * --------------------------------------------------------------------*/ + test(); + IF (EQ_16(nb_min, 1)||EQ_16(abs_s(point_to_remove),1)) + { + nb_min = 1; + move16(); + points_by_pos[0] = abs_s(point_to_remove); + } + ELSE + { + /* First position */ + /* fact = (float)fabs(point_to_remove) / sqi[nb_min-2]; (nb_min*nb_min) */ + fact = mult_r(shl(abs_s(point_to_remove), 7), inv_sqi[nb_min - 2]); /*Q7 */ + points_by_pos[0] = mult_r(fact, 256); /*Q7 */ + total_point = points_by_pos[0]; + move16(); + + FOR (i = 2; i <= nb_min; i++) + { + /* points_by_pos[i-1] = (Word16)(fact*(sqi[i-2]) - total_point+0.5) */ + points_by_pos[i - 1] = sub(shr(extract_l(L_mac0(64L, fact, sqi[i - 2])), 7), total_point); + total_point = add(total_point, points_by_pos[i-1]); + + /* ensure a constant increase */ + IF (LT_16(points_by_pos[i-1], points_by_pos[i-2])) + { + tmp16 = points_by_pos[i-2]; + move16(); + points_by_pos[i-2] = points_by_pos[i-1]; + move16(); + points_by_pos[i-1] = tmp16; + move16(); + } + } + } + /* -------------------------------------------------------------------- + * Sample deletion or insertion is performed in minimum energy regions. + * At the end of this section the last maximum pulse in the concealed + * excitation is forced to align to the actual maximum pulse position + * at the end of the frame which is transmitted in the future frame. + * --------------------------------------------------------------------*/ + if (point_to_remove > 0) + { + point_to_add = point_to_remove; + move16(); + } + + pt_exc = exc_tmp; + move16(); + pt_exc1 = exc; + move16(); + + i = 0; + move16(); + pt_pos = min_pos + sub(nb_min, 1); + + IF (point_to_add > 0)/* Samples insertion */ + { + remaining_len = L_frame; + move16(); + FOR (i = 0; i < nb_min; i++) + { + /* Copy section */ + /* Compute len to copy */ + tmp_len = *pt_pos; + move16(); + IF (i != 0) + { + /* Compute len to copy */ + tmp_len = sub(sub(*pt_pos, *(pt_pos+1)), points_by_pos[i-1]); + } + /*Copy section */ + Copy(pt_exc1, pt_exc, tmp_len); + remaining_len = sub(remaining_len, tmp_len); + pt_exc1 += tmp_len; + move16(); + pt_exc += tmp_len; + move16(); + + /* Find point to add and Add points */ + tmp16 = mult_r(*pt_exc1, -1638); + FOR (j = 0; j < points_by_pos[i]; j++) + { + *pt_exc++ = tmp16; + move16();/* repeat last point */ + tmp16 = negate(tmp16); + } + + remaining_len = sub(remaining_len, points_by_pos[i]); + pt_pos--; + } + /* Copy remaining data */ + remaining_len = s_max(0, remaining_len); + Copy(pt_exc1, pt_exc, remaining_len); + /* Update true excitation vector */ + Copy(exc_tmp, exc, L_frame); + } + ELSE /* Samples deletion */ + { + remaining_len = L_frame; + move16(); + + FOR (i = 0; i < nb_min; i++) + { + /* Compute len to copy */ + tmp_len = *pt_pos; + move16(); + IF (i != 0) + { + /* Compute len to copy */ + tmp_len = sub(sub(*pt_pos, *(pt_pos+1)), points_by_pos[i-1]); + } + Copy(pt_exc1, pt_exc, tmp_len); + remaining_len = sub(remaining_len, tmp_len); + pt_exc1 += tmp_len; + move16(); + pt_exc += tmp_len; + move16(); + /* Remove points */ + FOR (j = 0; j < points_by_pos[i]; j++) + { + pt_exc1++; + } + pt_pos--; + } + /* Copy remaining data */ + remaining_len = s_max(0, remaining_len); + Copy(pt_exc1, pt_exc, remaining_len); + /* Update true excitation vector */ + Copy(exc_tmp, exc, L_frame); + } + + return 1; + +} \ No newline at end of file diff --git a/lib_dec/FEC_clas_estim.c b/lib_dec/FEC_clas_estim.c index 584a99ce15beb6f6d180e0103b173714f8311706..b74b44101832cf34e1b6d041e1c86610abeca37e 100644 --- a/lib_dec/FEC_clas_estim.c +++ b/lib_dec/FEC_clas_estim.c @@ -774,7 +774,7 @@ int16_t FEC_pos_dec( /* decode pitch period */ T0_min = PIT_MIN; T0_max = PIT_MAX; - pit16k_Q_dec( pitch_index, 10, 1, &T0, &T0_frac, &T0_min, &T0_max, &st->BER_detect ); + pit16k_Q_dec_flt( pitch_index, 10, 1, &T0, &T0_frac, &T0_min, &T0_max, &st->BER_detect ); /* decode last pulse position */ *last_pulse_pos = get_next_indice( st, FEC_BITS_POS ); diff --git a/lib_dec/FEC_clas_estim_fx.c b/lib_dec/FEC_clas_estim_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..786912b4cbcfb32a4fe4290dca71f979bc3a7606 --- /dev/null +++ b/lib_dec/FEC_clas_estim_fx.c @@ -0,0 +1,930 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include +#include "options.h" /* Compilation switches */ +#include "cnst.h" /* Common constants */ +#include "rom_com.h" /* Static table prototypes */ +#include "prot_fx1.h" /* Function prototypes */ +#include "prot_fx2.h" /* Function prototypes */ +#include "basop_util.h" + +/*-------------------------------------------------------------------* + * Local function prototypes + *-------------------------------------------------------------------*/ +static Word16 FEC_dec_class_fx( Decoder_State *st_fx, Word32 *enr_q); +static void Corre(const Word16 *x,const Word16 *y,const Word16 l,Word16 *gain); + +/*---------------------------------------------------------------------* + * Local Constants + *---------------------------------------------------------------------*/ +#define UNS6 10923/2 +#define UNS5 13107/2 + +#define K_COR_FX 14004 /* Q14 0.8547f <-0.29, 0.88> */ +#define C_COR_FX 266180599 /* Q14+16 0.2479f */ + +#define K_TILT_FX 13653 /*Q14 0.8333f <-0.35, 0.85> */ +#define C_TILT_FX 313210491 /*Q14+16 0.2917f */ + +#define K_ZC_FX -1310 /*Q15 -0.04f <63, 38> */ +#define C_ZC_FX 2642416 /*11Q20 2.52 */ + +#define K_ENR_FX 1311 /*Q15 0.04 <-14, 11> */ +#define C_ENR_FX 9395241 /*Q8+16 0.56f */ + +#define K_PC_FX -1169 /*Q15 -0.0357f <45, 17> */ +#define C_PC_FX 105323 /*Q0+16 1.6071f */ + + + +/*======================================================================*/ +/* FUNCTION : FEC_clas_estim() */ +/*----------------------------------------------------------------------*/ +/* PURPOSE : Estimation of classification */ +/* information, if not available in the bitsream */ +/* */ +/*======================================================================*/ + +void FEC_clas_estim_fx( + Decoder_State *st_fx , /* i/o: decoder state handle */ + const Word16 Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ /*A*/ + const Word16 L_frame, /* i : length of the frame */ + Word16 *clas, /* i/o: frame classification */ + const Word16 coder_type, /* i : coder type */ + const Word16 *pitch, /* i : pitch values for each subframe (Q6)*/ + Word16 *syn, /* i : synthesis buffer */ + Word16 *lp_speech, /* i/o: long term active speech energy average Q8 */ + Word16 *decision_hyst, /* i/o: hysteresis of the music/speech decision */ /*A*/ + Word16 *UV_cnt, /* i/o: number of consecutives frames classified as UV */ /*A*/ + Word16 *LT_UV_cnt, /* i/o: long term consecutives frames classified as UV */ /*A*/ + Word16 *Last_ener, /* i/o: last_energy frame */ /*A*/ + Word16 *locattack, /* i/o: detection of attack (mainly to localized speech burst) */ /*A*/ + Word16 *lt_diff_etot, /* i/o: long-term total energy variation */ /*A*/ + Word16 *amr_io_class, /* i/o: classification for AMR-WB IO mode */ /*A*/ + const Word32 bitrate, /* i : Decoded bitrate */ /*A*/ + Word16 Q_syn, /* i : Synthesis scaling */ + Word16 *class_para, /* o : classification para. fmerit1 */ /*A*/ + Word16 *mem_syn_clas_estim, /* i/o: memory of the synthesis signal for frame class estimation */ + Word16 *Q_mem_syn, /* i/o: exponent for memory of synthesis signal for frame class estimation */ /*B*/ + Word16 LTP_Gain, /* i : LTP gain is 0..0.6 or -1 Q15 *//*B*/ + Word16 mode, /* i : signal classifier mode *//*B*/ + Word16 bfi, /* i : bad frame indicator *//*B*/ + Word32 last_core_brate, /* i : bitrate of previous frame */ + const int16_t FEC_mode /* i : ACELP FEC mode */ +) +{ + Word16 i, j, pos; + Word16 *pt1, *pt2, zc_frame, frame_ener =1 ,tmp_scale=0, tmp_scale_syn, tmp_scale_mem; + Word16 tiltn, corn, zcn, pcn, fmerit1, enern, ener = 0/*not necessary, just to quiet a warning so not cmplxty counted*/, tilt, diff_ener; + Word16 voicing, cor_max[4], *synth, tmp16, exp1, exp2; + Word32 Ltmp, Ltmp1; + Word16 tmpS, T0, pc, /*max,*/ tmp_x, tmp_y; + Word16 old_synth[L_SYN_MEM_CLAS_ESTIM + L_FRAME16k]; + Word16 nb_subfr; + Word16 pos_limit; + Word16 codec_mode, narrowBand, tcxonly,preemph_fac; + Word16 memmax; + + nb_subfr = shr(L_frame,6); + memmax = 0; + move16(); + tmp_scale_syn = 0; + move16(); + + codec_mode = st_fx->codec_mode; + tcxonly = st_fx->tcxonly; /* i : tcxonly flag *//*B*/ + narrowBand = st_fx->narrowBand; /* i : narrowband flag *//*B*/ + preemph_fac = st_fx->preemph_fac; /* i : preemphasis factor *//*B*/ + /*------------------------------------------------------------------------* + * Copy synthesized into local buffer + *------------------------------------------------------------------------*/ + + /* After Rate Switching st->last_core is reset to 0. Check for last_core_brate is needed */ + test();test();test();test();test();test();test();test();test();test();test(); + IF((EQ_32(last_core_brate, SID_1k75)||EQ_32(last_core_brate,ACELP_6k60)||EQ_32(last_core_brate,ACELP_8k85) + || EQ_32(last_core_brate, ACELP_12k65) || EQ_32(last_core_brate, ACELP_14k25) || EQ_32(last_core_brate, ACELP_15k85) + || EQ_32(last_core_brate, ACELP_18k25) || EQ_32(last_core_brate, ACELP_19k85) || EQ_32(last_core_brate, ACELP_23k05) + || EQ_32(last_core_brate, ACELP_23k85)) && !Opt_AMR_WB && EQ_16(codec_mode, MODE2) + && GT_16(L_frame,L_FRAME) ) + { + Word16 oldLenClasBuff, newLenClasBuff; + oldLenClasBuff = extract_l(L_shr(Mpy_32_16_1(L_mult0(st_fx->last_L_frame,getInvFrameLen(st_fx->L_frame)/*Q21*/)/*Q21*/,L_SYN_MEM_CLAS_ESTIM/*Q0*/)/*Q6*/,6)/*Q0*/); + newLenClasBuff = L_SYN_MEM_CLAS_ESTIM; + move16(); + lerp( &mem_syn_clas_estim[L_SYN_MEM_CLAS_ESTIM-oldLenClasBuff], &mem_syn_clas_estim[L_SYN_MEM_CLAS_ESTIM-newLenClasBuff], newLenClasBuff, oldLenClasBuff ); + } + synth = old_synth + L_SYN_MEM_CLAS_ESTIM; + + /*Rescale synthesis mem buffer or synthesis buffer, if necessary - + allign them to the same scaling in case of switching MODE2->MODE1*/ + IF(EQ_16(codec_mode, MODE2)) + { + memmax=1; + move16(); + /*find maximum of mem syn*/ + FOR(i=0; i0) /*mem syn is bigger, scale it down*/ + { + tmp_scale_mem = negate(tmp_scale); + Scale_sig(mem_syn_clas_estim, L_SYN_MEM_CLAS_ESTIM, tmp_scale_mem); + } + ELSE /*synthesis is bigger, scale it down*/ + { + /*check for upscaling mem syn, first*/ + tmp_scale_mem = norm_s(sub(memmax,1)); + if (EQ_16(memmax,1)) + { + tmp_scale_mem = 14; + move16(); + } + tmp_scale_syn = sub(add(*Q_mem_syn, tmp_scale_mem), Q_syn); /*if this is negative, syn can be scaled down*/ + test(); + IF(tmp_scale_syn > 0 || EQ_16(mode , 1/*CLASSIFIER_TCX*/)) /*dont scale up syn, but scale mem_syn, adequately*/ + { + tmp_scale_mem = sub(tmp_scale_mem,tmp_scale_syn); + tmp_scale_syn = 0; + move16(); + } + + Scale_sig( mem_syn_clas_estim, L_SYN_MEM_CLAS_ESTIM, tmp_scale_mem ); + *Q_mem_syn = add(*Q_mem_syn, tmp_scale_mem); + } + + } + + tmp_scale = -1; + move16(); + + Copy_Scale_sig( mem_syn_clas_estim, old_synth, L_SYN_MEM_CLAS_ESTIM, tmp_scale ); + Copy_Scale_sig( syn, synth, L_frame, add(tmp_scale_syn, tmp_scale) ); + + /*Tell MODE2 decoder the scaling of the buffer*/ + *Q_mem_syn = add(add(Q_syn, tmp_scale_syn), tmp_scale); + + /**Q_mem_syn = *Q_syn; move16();*/ + + test(); + IF(EQ_16(codec_mode,MODE2)&&EQ_16(mode,1/*CLASSIFIER_TCX*/)) + { + /* TCX outputs non-pe-speech */ + move16(); + tmp16 = shl(syn[-1],tmp_scale); /*dont forget to scale the mem*/ + preemph_copy_fx(synth, synth, preemph_fac, L_frame, &tmp16); + } + + /*------------------------------------------------------------------------* + * GC, TC and AC frames + *------------------------------------------------------------------------*/ + /* Do the classification only + - MODE1: when the class is not transmitted in the bitstream + - MODE2: on good frames (classifier is also called for bfi=1) */ + test();test();test();test();test();test(); + IF (( EQ_16(codec_mode , MODE1) && (FEC_mode == 0 || LE_16(coder_type , UNVOICED) || Opt_AMR_WB)) || (EQ_16(codec_mode , MODE2) && NE_16(bfi,1) && !tcxonly )) + { + /*------------------------------------------------------------------------* + * Overwrite classification decision using coder_type information + *------------------------------------------------------------------------*/ + test(); + IF( EQ_16(coder_type,VOICED)) + { + *clas = VOICED_CLAS; + move16(); + } + ELSE IF( EQ_16(coder_type,UNVOICED)) + { + *clas = UNVOICED_CLAS; + move16(); + } + ELSE IF( EQ_16(coder_type,INACTIVE)&&!Opt_AMR_WB) + { + *clas = INACTIVE_CLAS; + move16(); + } + ELSE + { + /*------------------------------------------------------------------------* + * Compute the zero crossing rate for all subframes + *------------------------------------------------------------------------*/ + + pt1 = (Word16 *)synth - 1; + move16(); + tmpS = shr(*pt1, 15); /* sets 'tmpS to -1 if *pt1 < 0 */ + Ltmp = L_deposit_l(0); + FOR (j = 0; j < L_SUBFR*nb_subfr; j++) + { + tmp16 = add(1, tmpS); + pt1++; + if(*pt1 != 0) /* Do only count zero crossing, no zero touchings */ + { + tmpS = shr(*pt1, 15); /* 1Clk: >=0 ---> 0 OTHERWISE -1 */ + } + Ltmp = L_msu0(Ltmp, tmpS, tmp16); + } + + zc_frame = shl(extract_l(Ltmp),4); /* Q4 */ + + if( EQ_16(L_frame,L_FRAME16k)) + { + /*zc_frame *= 0.8f;*/ /* Renormalization for 12.8kHz core*/ + zc_frame = mult_r(zc_frame, 26214); + } + + + /*------------------------------------------------------------------------* + * Compute the normalized correlation pitch-synch. at the end of the frame + *------------------------------------------------------------------------*/ + T0 = shr(pitch[3], 6); + Ltmp1 = L_mult(pitch[3], 256); + + if (GT_16(T0, L_SUBFR*3/2)) + { + T0 = mac_r(Ltmp1, pitch[2], 256); + } + + + pt1 = synth; + move16(); + pos = sub(L_frame, T0); /* T0 [34 231] */ + + + Corre(&pt1[pos], &pt1[pos-T0], T0, &cor_max[0]); +#ifdef BASOP_NOGLOB + T0 = mult_r_sat(add_sat(pitch[2], pitch[3]), 256); +#else + T0 = mult_r(add(pitch[2], pitch[3]), 256); +#endif + pos_limit = sub(L_frame, L_SUBFR); + j = s_min(1, s_max(0, sub(pos, pos_limit))); + Ltmp = L_deposit_l(cor_max[0]); + IF (j > 0) + { + j = 16384; + move16(); + pos = sub(pos, T0); /* T0 [34 231] */ + Corre(&pt1[pos], &pt1[pos-T0], T0, &cor_max[1]); + Ltmp = L_add(Ltmp, cor_max[1]); + IF (GT_16(pos, pos_limit)) + { + j = 10923; + move16(); + pos = sub(pos, T0); /* T0 [34 231] */ + Corre(&pt1[pos], &pt1[pos-T0], T0, &cor_max[2]); + Ltmp = L_add(Ltmp, cor_max[2]); + } + IF (GT_16(pos, pos_limit)) + { + j = 8192; + move16(); + pos = sub(pos, T0); /* T0 [34 231] */ + Corre(&pt1[pos], &pt1[pos-T0], T0, &cor_max[3]); + Ltmp = L_add(Ltmp, cor_max[3]); + } + } + + voicing = cor_max[0]; + move16(); + IF(j > 0) + { + voicing = extract_l(Mult_32_16(Ltmp, j)); + } + /*------------------------------------------------------------------------* + * Compute pitch coherence + *------------------------------------------------------------------------*/ + + pc = 0; + move16(); + test(); + test(); + IF (EQ_16(codec_mode , MODE1)||!(NE_16(LTP_Gain,-32768/*-1.f Q15*/)&&EQ_16(mode,CLASSIFIER_TCX))) + { +#ifdef BASOP_NOGLOB + pc = shr(abs_s(sub(add_sat(pitch[3], sub(pitch[2], pitch[1])), pitch[0])), 6); +#else + pc = shr(abs_s(sub(add(pitch[3], sub(pitch[2], pitch[1])), pitch[0])), 6); +#endif + + if(EQ_16(L_frame,L_FRAME16k)) + { + pc = mult_r(pc, 26214); /* Renormalization for 12.8kHz core*/ + } + } + + /*------------------------------------------------------------------------* + * Compute spectral tilt + *------------------------------------------------------------------------*/ + pt1 = (Word16 *)synth + L_SUBFR; + move16(); + pt2 = (Word16 *)synth + L_SUBFR - 1; + move16(); + Ltmp = L_mult0(*pt1, *pt1); + Ltmp1 = L_mult0(*pt1, *pt2); + FOR(j = 1; j < L_SUBFR*(nb_subfr-1); j++) + { + pt1++; + pt2++; +#ifdef BASOP_NOGLOB + Ltmp = L_mac0_sat(Ltmp, *pt1, *pt1); + Ltmp1 = L_mac0_sat(Ltmp1, *pt1, *pt2); +#else + Ltmp = L_mac0(Ltmp, *pt1, *pt1); + Ltmp1 = L_mac0(Ltmp1, *pt1, *pt2); +#endif + } + tilt = 0; + move16(); + + IF (Ltmp != 0) + { + BASOP_SATURATE_WARNING_OFF_EVS + tmp16 = extract_l(L_or(L_shr(Ltmp1, 32), 1)); /* sets a flag -1 or 1 for sign of Ltmp1 */ + BASOP_SATURATE_WARNING_ON_EVS + Ltmp1 = L_abs(Ltmp1); + exp1 = norm_l(Ltmp1); + tmp_y = extract_h(L_shl(Ltmp1, exp1)); + exp1 = sub(31-1+3, exp1); + exp2 = norm_l(Ltmp); + tmp_x = extract_h(L_shl(Ltmp, exp2)); + exp2 = sub(31-1+3, exp2); + BASOP_SATURATE_WARNING_OFF_EVS + tmpS = shr(sub(tmp_x, tmp_y), 16); /* if tmp_x >= tmp_y tmpS = 0, -1 otherwise */ + BASOP_SATURATE_WARNING_ON_EVS + tmp_y = shl(tmp_y, tmpS); + exp1 = sub(exp1, tmpS); + + tilt = div_s(tmp_y, tmp_x); +#ifdef BASOP_NOGLOB + tilt = shl_sat(tilt, sub(exp1, exp2)); /* saturate to 1.0 */ +#else + tilt = shl(tilt, sub(exp1, exp2)); /* saturate to 1.0 */ +#endif + + tilt = i_mult2(tilt, tmp16); + } + + /*------------------------------------------------------------------------* + * Compute pitch-synchronous energy at the frame end + *------------------------------------------------------------------------*/ + ener = frame_energy_fx(L_frame, pitch, synth, *lp_speech, &frame_ener, *Q_mem_syn); + + /*------------------------------------------------------------------------* + * transform parameters between 0 & 1 + * find unique merit function + *------------------------------------------------------------------------*/ + enern = mac_r(C_ENR_FX, K_ENR_FX, ener); /*Q8*/ + + tiltn = extract_h(L_shr(L_mac(C_TILT_FX, K_TILT_FX, tilt), 6)); /*Q14 -> Q8*/ + + corn = extract_h(L_shr(L_mac(C_COR_FX, K_COR_FX, voicing), 6)); /*Q14 -> Q8*/ + + zcn = extract_h(L_shl(L_mac(C_ZC_FX, K_ZC_FX, zc_frame), 4)); /* Q4 -> Q8*/ + + BASOP_SATURATE_WARNING_OFF_EVS +#ifdef BASOP_NOGLOB + tmp16 = sub_sat(LTP_Gain, -32768/*-1.f Q15*/); +#else + tmp16 = sub(LTP_Gain , -32768/*-1.f Q15*/); +#endif + BASOP_SATURATE_WARNING_ON_EVS + test(); + test(); + IF ( EQ_16(codec_mode , MODE2)&&tmp16!=0&&EQ_16(mode,CLASSIFIER_TCX)) + { + pcn = round_fx(L_shl(Mpy_32_16_1(C_PC_FX/*Q16*/, LTP_Gain/*Q15*/),8)); /*Q16*/ + } + ELSE + { + pcn = extract_h(L_shl(L_mac(C_PC_FX, K_PC_FX, pc),8)); /* Q0 -> Q8*/ + } + + pcn = s_min(256, pcn); + pcn = s_max( 0, pcn); + /* fmerit1 = (1.0f/6.0f) * (tiltn + 2.0f*corn + zcn + pcn + enern) */ + Ltmp = L_mult(tiltn, UNS6); + Ltmp = L_mac(Ltmp, corn, 2*UNS6); + Ltmp = L_mac(Ltmp, zcn, UNS6); + Ltmp = L_mac(Ltmp, pcn, UNS6); + Ltmp = L_mac(Ltmp, enern, UNS6); + BASOP_SATURATE_WARNING_OFF_EVS +#ifdef BASOP_NOGLOB + fmerit1 = round_fx_sat(L_shl_sat(Ltmp, 15 - 8)); /*Q15 can saturate to 1.0 */ +#else + fmerit1 = round_fx(L_shl(Ltmp, 15-8)); /*Q15 can saturate to 1.0 */ +#endif + BASOP_SATURATE_WARNING_ON_EVS + test(); + if ( EQ_16(codec_mode,MODE2)&&narrowBand!=0) + { + fmerit1 = mult_r(fmerit1, 29491/*0.9f Q15*/); /* 0.90 */ + } + IF(EQ_16(codec_mode, MODE1)) + { + *class_para = round_fx(L_shl(Ltmp, 14-8)); /*Q14 - cannot be saturated, degrades HF synthesis */ + } + + /*------------------------------------------------------------------------* + * frame classification + *------------------------------------------------------------------------*/ + test(); + test(); + if ( (NE_16(coder_type,VOICED)&<_32(bitrate,ACELP_11k60))||Opt_AMR_WB) + { + Word16 result = UNVOICED_CLAS; + move16(); + SWITCH( *clas ) + { + case VOICED_CLAS: + case ONSET: + case SIN_ONSET: + case VOICED_TRANSITION: + IF(LT_16(fmerit1, 12780/*0.39f Q15*/)) + { + result = UNVOICED_CLAS; + move16(); + } + ELSE IF(LT_16(fmerit1, 20644/*0.63f Q15*/) + && (LT_16(ener,-3840) || EQ_16(codec_mode,MODE2))) + { + result = VOICED_TRANSITION; + move16(); + } + ELSE + { + result = VOICED_CLAS; + move16(); + } + + BREAK; + + case UNVOICED_CLAS: + case UNVOICED_TRANSITION: + case INACTIVE_CLAS: + IF( GT_16(fmerit1, 18350/*0.56f Q15*/)) + { + result = ONSET; + move16(); + } + ELSE IF( GT_16(fmerit1, 14746/*0.45f Q15*/)) + { + result = UNVOICED_TRANSITION; + move16(); + } + ELSE + { + result = UNVOICED_CLAS; + move16(); + } + BREAK; + + } + *clas = result; + move16(); + } + } + + + + IF(EQ_16(codec_mode,MODE1)) + { + /*------------------------------------------------------------------------* + * Overwrite classification decision in case of music + *------------------------------------------------------------------------*/ + IF( EQ_16(coder_type,AUDIO)) + { + (*decision_hyst) = add(*decision_hyst,4); + move16(); + } + ELSE + { + (*decision_hyst) = sub(*decision_hyst,1); + move16(); + } + + if( EQ_16(coder_type,INACTIVE)) + { + *decision_hyst = sub(*decision_hyst,10); + move16(); + } + IF( GT_16(*decision_hyst,200)) + { + *decision_hyst = 200; + move16(); + } + ELSE if( *decision_hyst < 0 ) + { + *decision_hyst = 0; + move16(); + } + + test(); + test(); + if( GT_16(*decision_hyst,16)&<_16(*clas,VOICED_CLAS)&&EQ_16(coder_type,AUDIO)) + { + *clas = VOICED_CLAS; + move16(); + } + } /*MODE1*/ + + /*---------------------------------------------------------------------------------* + * Measure energy on active voice frames (to improve FEC performance) + *---------------------------------------------------------------------------------*/ + IF( EQ_16(*clas,VOICED_CLAS)) + { + test(); + test(); + test(); + test(); + test(); + IF( (EQ_16(codec_mode,MODE2)&&EQ_16(coder_type,VOICED)) + || (EQ_16(codec_mode,MODE1) && (Opt_AMR_WB || (NE_16(coder_type,GENERIC) && NE_16(coder_type,TRANSITION) ) ) ) + ) + { + /* pitch-synchronous energy at the frame end */ + enern = frame_energy_fx(L_frame,pitch, synth, *lp_speech, &frame_ener, *Q_mem_syn); + } + /* update of long-term active speech energy */ + Ltmp = L_mult0(655, frame_ener); /* 0.01 */ + *lp_speech = mac_r(Ltmp, 32440, *lp_speech); + move16(); /* lp_speech update */ + } + + IF(EQ_16(codec_mode, MODE1)) + { + + /*---------------------------------------------------------------------------------* + * Overwrite classification decision to UNVOICED_CLAS in case of INACTIVE frame + *---------------------------------------------------------------------------------*/ + test(); + if( EQ_16(coder_type, INACTIVE)&&NE_16(*clas,INACTIVE_CLAS)) + { + *clas = UNVOICED_CLAS; + move16(); + } + + /*---------------------------------------------------------------------------------* + * Classification refinement to improve noise coding (only in AMR-WB IO mode) + *---------------------------------------------------------------------------------*/ + IF( Opt_AMR_WB ) + { + *locattack = 0; + move16(); + + /*-----------------------------------------------------------------------------* + * Unvoiced signal but not silence + *-----------------------------------------------------------------------------*/ + + test(); + IF( EQ_16(*clas, UNVOICED_CLAS)&&NE_16(coder_type,INACTIVE)) + { + IF ( LE_16(*lp_speech, 40*256/*Q8*/)) + { + *UV_cnt = 16; + move16(); + } + ELSE + { + move16(); + *UV_cnt = sub(*UV_cnt, 8); + } + } + + /*-----------------------------------------------------------------------------* + * Neither unvoiced nor clean silence + * Number of frames between UV is increased + *-----------------------------------------------------------------------------*/ + + ELSE IF ( NE_16(coder_type, INACTIVE)) + { + move16(); + *UV_cnt = add(*UV_cnt, 1); + } + + /*-----------------------------------------------------------------------------* + * Maximum/minimum number of frames between UV reached + *-----------------------------------------------------------------------------*/ + + /* Range 0..300 */ move16(); + *UV_cnt = s_max(s_min(300, *UV_cnt), 0); + + /*-----------------------------------------------------------------------------* + * IF VAD = 0 (no voice activity) + * long-term average updated towards to speech + * maximum number of frames between UV is limited to 125 + * Else + * update long-term average + *-----------------------------------------------------------------------------*/ + + IF ( EQ_16(coder_type, INACTIVE)) + { + move16(); + *LT_UV_cnt = mult_r(31130/*0.95f*/, *LT_UV_cnt); /* tend to speech if no activity */ + *UV_cnt = s_min(125, *UV_cnt); + move16(); + } + ELSE + { + /* *LT_UV_cnt = 0.9f * *LT_UV_cnt + 0.1f * *UV_cnt */ + + Ltmp = L_mult(3277/*0.1f*/, *UV_cnt); + /* Bring to Q22 */ + Ltmp = L_shl(Ltmp, 6); + /* Add to 0.9 x *LT_UV_cnt (Already in Q6) */ + Ltmp = L_mac(Ltmp, 29491/*0.9f*/, *LT_UV_cnt); /* Q22*/ + /* Store */ + *LT_UV_cnt = round_fx(Ltmp); + } + + /*-----------------------------------------------------------------------------* + * Compute frame energy difference + * IF long-term average is high and energy difference is relatively low + * classification is overwritten to AUDIO + * IF energy difference > 6.0dB + * consider an attack + *-----------------------------------------------------------------------------*/ + + diff_ener = sub(ener, *Last_ener); + *Last_ener = ener; + move16(); + *amr_io_class = *clas; + move16(); + test(); + if ( GT_16(*LT_UV_cnt, LT_UV_THR_FX)&<_16(diff_ener,12*256/*Q8*/)) + { + move16(); + *amr_io_class = AUDIO_CLAS; + } + test(); + test(); + if ( (GT_16(diff_ener, 6*256/*Q8*/)&&EQ_16(*clas,AUDIO_CLAS))||GT_16(diff_ener,9*256/*Q8*/)) + { + *locattack = 1; + move16(); + } + + /*------------------------------------------------------------------------* + * Find mean of the past 40 frames energy variation + *------------------------------------------------------------------------*/ + + IF( NE_16(coder_type, INACTIVE)) + { + Ltmp = L_deposit_l(0); + FOR (i = 1; icoder_type_fx,VOICED)) + { + /* decode the class */ + tmpS = (Word16)get_next_indice( st_fx, FEC_BITS_CLS ); + + IF( tmpS == 0 ) + { + clas = UNVOICED_CLAS; + move16(); + } + ELSE IF( EQ_16(tmpS,1)) + { + IF( GE_16(st_fx->last_good_fx,VOICED_TRANSITION)) + { + clas = VOICED_TRANSITION; + move16(); + } + ELSE + { + clas = UNVOICED_TRANSITION; + move16(); + } + } + ELSE IF( EQ_16(tmpS,2)) + { + clas = VOICED_CLAS; + move16(); + } + } + ELSE + { + clas = VOICED_CLAS; + move16(); + } + + /* decode the energy */ + test(); + test(); + IF(GT_16(st_fx->acelp_cfg.FEC_mode , 1) ) + { + tmpS = (Word16)get_next_indice( st_fx, FEC_BITS_ENR ); + /* convert from logarithmic to linear domain (the range is 0 : 3.0 : 96 dB) */ + tmpS = mult_r(shl(tmpS,10), 24576); /* Q10*Q13->Q8 */ + L_tmp = L_mult(tmpS, 10885); /* 0.332192 in Q15 */ + L_tmp = L_shr(L_tmp, 8); /* From Q24 to Q16 */ + sfrac = L_Extract_lc(L_tmp, &tmpS); + *enr_q = Pow2(tmpS, sfrac); + move32(); + } + + return clas; +} + +Word16 FEC_pos_dec_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + Word16 *last_pulse_pos, /* o : last glotal pulse position in the lost ACB */ + Word32 *enr_q, /* o : decoded energy in Q0 */ + const Word16 nBits_es_Pred /* i : number of bits for Es_pred Q */ +) +{ + Word16 pitch_index, T0, T0_frac, T0_min, T0_max; + Word16 bit_pos_pitch_index, nBits; + + T0 = 0; + move16(); + IF( GT_16(st_fx->coder_type_fx,UNVOICED)) + { + /* decode the clas and energy information */ + IF( LT_16(st_fx->coder_type_fx,AUDIO)) + { + st_fx->clas_dec = FEC_dec_class_fx( st_fx, enr_q); + move16(); + + test(); + test(); + test(); + IF( EQ_16(st_fx->coder_type_fx,GENERIC) && EQ_16(st_fx->clas_dec,VOICED_CLAS) && (LE_16(st_fx->last_good_fx,UNVOICED_CLAS) || EQ_16(st_fx->last_good_fx,INACTIVE_CLAS))) + { + st_fx->clas_dec = SIN_ONSET; + move16(); + } + } + + test(); + IF( EQ_16(st_fx->coder_type_fx,GENERIC) && GT_16(st_fx->acelp_cfg.FEC_mode,2) ) + { + nBits = st_fx->acelp_cfg.pitch_bits[0]; /* The first pitch index is located right after the actual position + the last pulse position index + predicted innovation energy index */ + bit_pos_pitch_index = st_fx->next_bit_pos + FEC_BITS_POS + nBits_es_Pred; + IF (GE_32(st_fx->core_brate, MIN_BRATE_AVQ_EXC) && LE_32(st_fx->core_brate, MAX_BRATE_AVQ_EXC_TD) && EQ_16(st_fx->coder_type_fx, GENERIC)) + { + /* Harmonic flag is present */ + bit_pos_pitch_index = add(bit_pos_pitch_index, 1); + } + /* retrieve the pitch index */ + pitch_index = (Word16)get_indice( st_fx, bit_pos_pitch_index, nBits ); + + /* decode pitch period */ + T0_min = PIT_MIN; + move16(); + T0_max = PIT_MAX; + move16(); + pit16k_Q_dec_fx( pitch_index, 10, 1, &T0, &T0_frac, &T0_min, &T0_max, &st_fx->BER_detect ); + + /* decode last pulse position */ + *last_pulse_pos = (Word16)get_next_indice( st_fx, FEC_BITS_POS ); + + /* respect the sign */ + IF (GE_16(*last_pulse_pos,128)) + { + *last_pulse_pos = negate(s_and(*last_pulse_pos , 0x7F)); + move16(); + } + if ( GE_16(T0,128)) + { + *last_pulse_pos = add(*last_pulse_pos,*last_pulse_pos); + move16(); + } + + if( st_fx->BER_detect ) + { + *last_pulse_pos = 0; + move16(); + } + } + } + + return T0; +} +/*----------------------------------------------------------------------* + * Corre: + * + * Correlation function. Signal x is compared to target signal y + * Information about the similarity between vectors is returned in *gain + *----------------------------------------------------------------------*/ +static void Corre( + const Word16 *x, /* i : vector 1 Q12 */ + const Word16 *y, /* i : vector 2 Q12 */ + const Word16 l, /* i : length of vectors */ + Word16 *gain /* o : normalized correlation gain Q15 */ +) +{ + Word16 cor, cor_exp; + Word16 den, den_exp; + Word16 den2, den2_exp; + Word32 tmp; + Word16 tmp_exp; + + /* keep Q15 normalized result */ + cor = extract_h(Dot_product12(x, y, l, &cor_exp)); +#ifdef BASOP_NOGLOB + den = add_sat(extract_h(Dot_product12(y, y, l, &den_exp)), 1); +#else + den = add(extract_h(Dot_product12(y, y, l, &den_exp)), 1); +#endif + den2 = extract_h(Dot_product12(x, x, l, &den2_exp)); + + /* keep Q31 normalized result */ + tmp = L_mult(den, den2); + tmp_exp = norm_l(tmp); + tmp = L_shl(tmp, tmp_exp); + tmp_exp = sub(add(den_exp, den2_exp), tmp_exp); + + tmp = Isqrt_lc(tmp, &tmp_exp); + /* keep Q15 result */ +#ifdef BASOP_NOGLOB + gain[0] = shl_sat(mult_r(cor, extract_h(tmp)), add(cor_exp, tmp_exp)); +#else + gain[0] = shl(mult_r(cor, extract_h(tmp)), add(cor_exp, tmp_exp)); +#endif + move16(); +} + diff --git a/lib_dec/FEC_fx.c b/lib_dec/FEC_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..49b41ab4182428f36f84132dcd0644872fddad89 --- /dev/null +++ b/lib_dec/FEC_fx.c @@ -0,0 +1,843 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include +#include "options.h" /* Compilation switches */ +#include "cnst.h" /* Common constants */ +#include "rom_com.h" /* Common static table prototypes */ +#include "rom_dec.h" /* Decoder static table prototypes */ +#include "prot_fx1.h" /* Function prototypes */ +#include "prot_fx2.h" /* Function prototypes */ +#include "basop_util.h" + +/*-------------------------------------------------------------------* + * Local function prototypes + *-------------------------------------------------------------------*/ +static void pulseRes_preCalc(Word16* cond1, Word16* cond2, Word32* cond3 ,Word16 new_pit, Word16 Tc, Word16 L_frame); +void gain_dec_bfi_fx(Word16 *past_qua_en); +/*======================================================================*/ +/* FUNCTION : FEC_exc_estim_fx() */ +/*----------------------------------------------------------------------*/ +/* PURPOSE : Calculation of excitation signal */ +/* */ +/*----------------------------------------------------------------------*/ +/* GLOBAL INPUT ARGUMENTS : */ +/* _ (Struct) st_fx : decoder static memory */ +/* _ (Word16) L_frame : length of the frame Q0 */ +/* _ (Word16) st_fx->lp_ener_fx : FEC - low-pass filtered energy Q6 */ +/* _ (Word16) st_fx->lp_gainc_fx : FEC - low-pass filtered code gain Q3 */ +/* _ (Word16) st_fx->old_pitch_buf : FEC buffer of old subframe pitch valuesQ6*/ +/* _ (Word16) st_fx->last_good : FEC - clas of last good received */ +/* _ (Word16) st_fx->bfi_pitch_fx : LP filter coefficient */ +/* _ (Word16) st_fx->upd_cnt : FEC counter of frames since last update*/ +/* _ (Word16) st_fx->last_coder_type_fx: previous coder type */ +/* _ (Word16) st_fx->Last_GSC_pit_band_idx_fx: AC mode (GSC)Last pitch band index*/ +/* _ (Word16) st_fx->stab_fac_fx : LSF stability factor Q15 */ +/* _ (Word16) st_fx->tilt_code : tilt of code Q15 */ +/* _ (Word16) st_fx->last_voice_factor : coding type Q12 */ +/* _ (Word16) st_fx->opt_AMR_WB_fx : coding type Q12 */ +/* _ (Word16) st_fx->lp_gainp_fx : FEC -low-pass filtered pitch gain Q14 */ +/* _ (Word16) st_fx->seed :FEC-seed for random generator for excitation*/ +/* _ (Word16) st_fx->opt_OMR_WB:flag indicating AMR-WB IO mode */ +/*-----------------------------------------------------------------------*/ +/* OUTPUT ARGUMENTS : */ +/* _ (Word16[]) exc_fx : adapt. excitation exc (Q_exc) */ +/* _ (Word16[]) exc2_fx : adapt. excitation/total exc (Q_exc) */ +/* _ (Word16[]) bwe_exc_fx : excitation for SWB TBE (Q_exc) */ +/* _ (Word16[]) pitch_buf_fx : floating pitch values for each subframe Q6*/ +/* _ (Word16[]) voice_factors_fx : frame error rate Q15 */ +/* _ (Word16[]) FEC_pitch_fx(tmp_tc): FEC pitch Q6 */ +/*-----------------------------------------------------------------------*/ + +/* _ (Word16) st_fx->lp_gainp_fx : FEC -low-pass filtered pitch gain Q14 */ +/* _ (Word16) st_fx->seed :FEC-seed for random generator for excitation*/ +/* _ (Word16) st_fx->bfi_pitch_fx : LP filter coefficient */ +/* _ (Word16) st_fx->lp_gainc_fx : FEC - low-pass filtered code gain Q3 */ +/*-----------------------------------------------------------------------*/ +/* RETURN ARGUMENTS : */ +/* _ None */ +/*=======================================================================*/ + + +void FEC_exc_estim_fx( + Decoder_State *st_fx, /* i/o: Decoder static memory */ + const Word16 L_frame, /* i : length of the frame */ + Word16 *exc, /* o : pointer to excitation buffer (with past) */ + Word16 *exc2, /* o : total excitation (for synthesis) */ + Word16 exc_dct_in[], /* o : GSC excitation in DCT domain */ + Word16 *pitch_buf, /* o : Floating pitch for each subframe */ + Word16 *voice_factors, /* o : voicing factors */ + Word16 *tmp_tc, /* o : FEC pitch Q6 */ + Word16 *bwe_exc, /* o : excitation for SWB TBE */ + Word16 *lsf_new, /* i : ISFs at the end of the frame */ + Word16 *Q_exc, + Word16 *tmp_noise /* o : long-term noise energy Q0 */ +) +{ + + Word16 exc2_buf[L_FRAME16k + MODE1_L_FIR_FER-1]; + Word16 gainCNG,new_pit /*Q0*/; /* Q3*/ + Word16 exp; + Word32 L_tmp,L_tmp2; + Word16 tmp,tmp1,tmp16; + Word16 delta; + Word16 i,j; + Word16 alpha; + Word16 gain,gain_inov; + Word16 Tc; + Word16 *pt_exc,*pt1_exc; + Word16 step; + Word32 L_step; + Word16 hp_filt[5]; + Word16 Diff_len,max_len,Len; + Word16 last_bin_fx, nb_subfr; + Word16 extrapolationFailed; + Word16 cond1, cond2; + Word32 cond3; + Word32 predPitchLag; + GSC_DEC_HANDLE hGSCDec; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + hGSCDec = st_fx->hGSCDec; + + AMRWB_IO_DEC_HANDLE hAmrwb_IO; + hAmrwb_IO = st_fx->hAmrwb_IO; + /* nb_subfr = L_frame/L_SUBFR */ + nb_subfr = shr(L_frame, 6); + Diff_len = 0; /* to avoid compilation flags */ + set16_fx( exc_dct_in, 0, L_FRAME16k ); + + extrapolationFailed = 1; + move16(); + + gainCNG = 0; + move16(); + IF(st_fx->lp_ener_fx != 0) + { + exp = norm_l(st_fx->lp_ener_fx); /*lp_ener in Q6*/ + tmp = extract_h(L_shl(st_fx->lp_ener_fx,exp)); + exp = sub(exp, 30-6); + + tmp = div_s(16384, tmp); + L_tmp = L_deposit_h(tmp); + L_tmp = Isqrt_lc(L_tmp, &exp); + + gainCNG = round_fx(L_shl(L_tmp, sub(exp, 12))); /* In Q3 */ + + } +#ifdef BASOP_NOGLOB + tmp1 = shl_o(st_fx->lp_gainc_fx, 1, &Overflow); +#else + tmp1 = shl(st_fx->lp_gainc_fx,1); +#endif + gainCNG = s_min(gainCNG , tmp1); + set16_fx( exc_dct_in, 0, L_FRAME16k ); + + /*-----------------------------------------------------------------* + * pitch extrapolation + *-----------------------------------------------------------------*/ + + { + Word32 *tmp_old_pitch /*15Q16*/; + Word16 tmp_pitmin, tmp_pitmax; + + /*tmp_old_pitch = L_frame == L_FRAME ? &st_fx->old_pitch_buf_fx[2*NB_SUBFR-1] : &st_fx->old_pitch_buf_fx[2*NB_SUBFR16k-1];*/ + /*tmp_pitmin = L_frame == L_FRAME?PIT_MIN_DOUBLEEXTEND:PIT16k_MIN_EXTEND;*/ + /*tmp_pitmax = L_frame == L_FRAME?PIT_MAX:PIT16k_MAX;*/ + + tmp_old_pitch = &st_fx->old_pitch_buf_fx[2*NB_SUBFR16k-1]; + tmp_pitmin = PIT16k_MIN_EXTEND; + tmp_pitmax = PIT16k_MAX; + IF(EQ_16(L_frame, L_FRAME)) + { + tmp_old_pitch = &st_fx->old_pitch_buf_fx[2*NB_SUBFR-1]; + tmp_pitmin = PIT_MIN_DOUBLEEXTEND; + move16(); + tmp_pitmax = PIT_MAX; + move16(); + } + + + pitch_pred_linear_fit( + st_fx->nbLostCmpt, + st_fx->last_good_fx, + st_fx->old_pitch_buf_fx, + tmp_old_pitch, + &predPitchLag, + tmp_pitmin, + tmp_pitmax, + st_fx->mem_pitch_gain, + 0, + 0, + &extrapolationFailed, + nb_subfr); + + new_pit/*Q0 int*/ = shl(round_fx(predPitchLag),0); + } + + + + /*-----------------------------------------------------------------* + * estimate subframe pitch values for the FEC frame + *-----------------------------------------------------------------*/ + + /* initialize pitch to the long-term pitch */ + + *tmp_tc = st_fx->bfi_pitch_fx; + move16(); /*Q6*/ + IF( EQ_16(L_frame,L_FRAME)) + { + test(); + test(); +#ifdef BASOP_NOGLOB + IF ( (LT_16(round_fx(L_shl(st_fx->old_pitch_buf_fx[2*NB_SUBFR-1], 6)), shl_o(mult(29491, st_fx->bfi_pitch_fx), 1, &Overflow))&& + GT_16(round_fx(L_shl(st_fx->old_pitch_buf_fx[2*NB_SUBFR-1], 6)), mult(19661, st_fx->bfi_pitch_fx)) ) || /* last pitch coherent with the past */ + GE_16(st_fx->upd_cnt, MAX_UPD_CNT) ) /* or last update too far in the past */ +#else + IF((LT_16(round_fx(L_shl(st_fx->old_pitch_buf_fx[2 * NB_SUBFR - 1], 6)), shl(mult(29491, st_fx->bfi_pitch_fx), 1)) && + GT_16(round_fx(L_shl(st_fx->old_pitch_buf_fx[2 * NB_SUBFR - 1], 6)), mult(19661, st_fx->bfi_pitch_fx)) ) || /* last pitch coherent with the past */ + GE_16(st_fx->upd_cnt, MAX_UPD_CNT) ) /* or last update too far in the past */ +#endif + { + /* take the pitch value of last subframe of the previous frame */ + *tmp_tc = round_fx(L_shl(st_fx->old_pitch_buf_fx[2*NB_SUBFR-1], 6)); + } + } + ELSE /* L_frame == L_FRAME16k */ + { + test(); + test(); +#ifdef BASOP_NOGLOB + IF ( (LT_16(round_fx(L_shl(st_fx->old_pitch_buf_fx[2*NB_SUBFR16k-1], 6)), shl_o(mult(29491, st_fx->bfi_pitch_fx), 1, &Overflow))&& + GT_16(round_fx(L_shl(st_fx->old_pitch_buf_fx[2*NB_SUBFR16k-1], 6)), mult(19661, st_fx->bfi_pitch_fx))) || /* last pitch coherent with the past */ + GE_16(st_fx->upd_cnt, MAX_UPD_CNT)) /* or last update too far in the past */ +#else + IF ( (LT_16(round_fx(L_shl(st_fx->old_pitch_buf_fx[2*NB_SUBFR16k-1], 6)), shl(mult(29491, st_fx->bfi_pitch_fx), 1))&& + GT_16(round_fx(L_shl(st_fx->old_pitch_buf_fx[2*NB_SUBFR16k-1], 6)), mult(19661, st_fx->bfi_pitch_fx))) || /* last pitch coherent with the past */ + GE_16(st_fx->upd_cnt, MAX_UPD_CNT)) /* or last update too far in the past */ +#endif + { + /* take the pitch value of last subframe of the previous frame */ + *tmp_tc = round_fx(L_shl(st_fx->old_pitch_buf_fx[2*NB_SUBFR16k-1], 6)); + } + } + + /* convert pitch period */ + /* Tc = (short)(tmp_tc + 0.5f) */ + Tc = shr_r(*tmp_tc,6); + + /* estimate pitch values for all subframes */ + /*calculate conditions for Pulse resynchronization to take place*/ + pulseRes_preCalc( &cond1, &cond2, &cond3 , new_pit, Tc, L_frame); + + test(); + test(); + test(); + test(); + IF ((cond1 < 0 ) + && (new_pit > 0) && (cond2 != 0) + && (cond3 > 0) + && extrapolationFailed == 0 + ) + { + tmp16 = *tmp_tc; /*Q6*/ move16(); + IF(EQ_16(nb_subfr,4)) + { + delta = shr(sub(shl(new_pit,6), *tmp_tc),2 ); /* 4 sub-frames */ + } + ELSE + { + delta = mult_r(sub(shl(new_pit,6), *tmp_tc),6554); /* 5 sub-frames */ + } + FOR (i = 0; i < nb_subfr; i++) /* subframe pitch values */ + { + /* fT0 += delta */ + tmp16 = add(tmp16, delta); + /* ptch_buf[i] = (short)(fT0 + 0.5) */ + pitch_buf[i] = shl(mult_r(tmp16, 512), 6); + move16(); + } + } + ELSE + { + FOR (i = 0; i < nb_subfr; i++) /* subframe pitch values for bass postfilter */ + { + pitch_buf[i] = *tmp_tc; + move16(); + } + } + + /*-----------------------------------------------------------------* + * estimate damping factor + *-----------------------------------------------------------------*/ + + /* rapid convergence to 0 */ + alpha = _ALPHA_VT_FX; + move16(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( st_fx->last_coder_type_fx == UNVOICED && LE_16(st_fx->nbLostCmpt, 3)) + { + /* last good frame was clearly unvoiced */ + alpha = _ALPHA_UU_FX; + move16(); + } + ELSE IF( EQ_16(st_fx->last_coder_type_fx,AUDIO)||EQ_16(st_fx->last_good_fx,INACTIVE_CLAS)) + { + test(); + IF( hGSCDec->Last_GSC_pit_band_idx_fx > 0 && GT_16(st_fx->nbLostCmpt,1)) + { + alpha = 26214; + move16(); + } + ELSE IF( LE_16(st_fx->nbLostCmpt,5)) + { + alpha = 32604; + move16(); + } + ELSE + { + alpha = 31130; + move16(); + } + } + ELSE IF( EQ_16(st_fx->last_good_fx,UNVOICED_CLAS)) + { + IF( LE_16(st_fx->nbLostCmpt,1)) + { + /* if stable, do not decrease the energy, pitch_gain = 0 */ +#ifdef BASOP_NOGLOB + alpha = mac_ro((1L << 16) * 2 * _ALPHA_U_FX, st_fx->stab_fac_fx, 32768 - 2 * _ALPHA_U_FX, &Overflow); /*st_fx->stab_fac_fx in Q15*/ +#else + alpha = mac_r((1L<<16)*2*_ALPHA_U_FX, st_fx->stab_fac_fx, 32768-2*_ALPHA_U_FX); /*st_fx->stab_fac_fx in Q15*/ +#endif + } + ELSE IF ( EQ_16(st_fx->nbLostCmpt,2)) + { + alpha =_ALPHA_S_FX; + move16(); /* ALPHA_U*1.5f = 0.6 */ + } + ELSE + { + alpha = _ALPHA_U_FX; + move16(); /* 0.4 go rapidly to CNG gain, pitch gain = 0 */ + } + } + ELSE IF( EQ_16(st_fx->last_good_fx,UNVOICED_TRANSITION)) + { + alpha = _ALPHA_UT_FX; + move16(); + } + ELSE IF( EQ_16(st_fx->last_good_fx,ONSET)&&LE_16(st_fx->nbLostCmpt,3)&&(EQ_16(st_fx->last_coder_type_fx,GENERIC)||EQ_16(st_fx->last_coder_type_fx,TRANSITION))) + { + alpha = 26214; + move16(); /* mild convergence to 0 for the first 3 erased frames 0.8 in Q15 */ + } + ELSE IF( ( EQ_16(st_fx->last_good_fx,VOICED_CLAS)||EQ_16(st_fx->last_good_fx,ONSET))&&LE_16(st_fx->nbLostCmpt,3)) + { + alpha = _ALPHA_V_FX; + move16(); /* constant for the first 3 erased frames */ + } + ELSE IF( EQ_16(st_fx->last_good_fx,SIN_ONSET)) + { + alpha = _ALPHA_S_FX; + move16(); + } + test(); + test(); + IF( GE_16(st_fx->last_good_fx,VOICED_CLAS)&<_16(st_fx->last_good_fx,INACTIVE_CLAS)&&NE_16(st_fx->last_coder_type_fx,AUDIO)) + { + IF( EQ_16(st_fx->nbLostCmpt,1)) /* if first erased frame in a block, reset harmonic gain */ + { + /* move pitch gain towards 1 for voiced to remove energy fluctuations */ + /*gain = (float)sqrt( st_fx->lp_gainp );*/ + st_fx->lp_gainp_fx = s_max(st_fx->lp_gainp_fx, 1); + exp = norm_s(st_fx->lp_gainp_fx); + tmp = shl(st_fx->lp_gainp_fx, exp); + tmp = div_s(16384, tmp); + L_tmp = L_deposit_h(tmp); + L_tmp = Isqrt_lc(L_tmp, &exp); + +#ifdef BASOP_NOGLOB + gain = extract_h(L_shl_o(L_tmp, exp, &Overflow)); +#else + gain = extract_h(L_shl(L_tmp, exp)); +#endif + + gain = s_min(gain, 32113); /*0.98 */ + gain = s_max(gain, 27853); /*0.85 */ + + alpha = mult_r(alpha, gain); + } + ELSE + { + /* st_fx->lp_gainp_fx is in Q14 when bfi_cnt > 1 to follow floating point because lp_gainp could be > than 1 */ + alpha = st_fx->lp_gainp_fx; + move16(); + } + } + + /*-----------------------------------------------------------------* + * construct the harmonic part of excitation + *-----------------------------------------------------------------*/ + test(); + test(); + test(); + test(); + IF( (GE_16(st_fx->last_good_fx,UNVOICED_TRANSITION)&<_16(st_fx->last_good_fx,INACTIVE_CLAS))|| + ( (EQ_16(st_fx->last_coder_type_fx,AUDIO) || EQ_16(st_fx->last_good_fx,INACTIVE_CLAS) ) && hGSCDec->Last_GSC_pit_band_idx_fx > 0) ) + { + + pt_exc = exc; + move16(); + pt1_exc = pt_exc - Tc; + move16(); + + IF (EQ_16(st_fx->nbLostCmpt,1)) + { + /* first pitch cycle is low-pass filtered */ + + FOR (i = 0; i < Tc; i++) /* pitch cycle is first low-pass filtered */ + { + /* *pt_exc++ = (0.18f * pt1_exc[-1] + 0.64f * pt1_exc[0] + 0.18f * pt1_exc[1]) */ + L_tmp = L_mult(5898, pt1_exc[-1]); + L_tmp = L_mac(L_tmp, 20972, pt1_exc[0]); + *pt_exc++ = mac_r(L_tmp, 5898, pt1_exc[1]); + move16(); + pt1_exc++; + } + } + + /* last pitch cycle of the previous frame is repeatedly copied up to an extra subframe */ + + tmp = (Word16)((exc + L_frame + L_SUBFR) - pt_exc); + FOR (i = 0; i < tmp; i++) + { + *pt_exc++ = *pt1_exc++; + move16(); + } + + IF (new_pit > 0 ) + { + /*calculate conditions for Pulse resynchronization to take place*/ + pulseRes_preCalc( &cond1, &cond2, &cond3 , new_pit, Tc, L_frame); + + test(); + test(); + test(); + test(); + IF ((cond1 < 0 ) + && (new_pit > 0) && (cond2 != 0) + && (cond3 > 0) + && extrapolationFailed == 0 + ) + { + Copy(exc,exc-L_frame-L_SUBFR,L_frame+L_SUBFR); + PulseResynchronization(exc-L_frame-L_SUBFR, exc, L_frame, nb_subfr, L_deposit_h(Tc/*Q0*/)/*15Q16*/, L_deposit_h(new_pit/*Q0*/)/*15Q16*/); + } + } + test(); + test(); + IF( EQ_16(st_fx->last_good_fx,UNVOICED_TRANSITION)&&(EQ_16(st_fx->last_coder_type_fx,GENERIC)||EQ_16(st_fx->last_coder_type_fx,TRANSITION))) + { + /* start of the frame gain */ + gain = 0; + move16(); + + /* end of the frame gain */ + st_fx->lp_gainp_fx = 0; + move16(); + step = 0; + move16(); + } + ELSE + { + + /* start of the frame gain */ + gain = 16384; + move16(); + + /* end of the frame gain */ + test(); + + IF(!(GE_16(st_fx->last_good_fx,VOICED_CLAS)&<_16(st_fx->last_good_fx,INACTIVE_CLAS)&&NE_16(st_fx->last_coder_type_fx,AUDIO)&>_16(st_fx->nbLostCmpt,1))) + { + st_fx->lp_gainp_fx = shr(alpha,1); /* alpha in Q15 */ + } + ELSE + { + st_fx->lp_gainp_fx = alpha; + move16(); /* alpha in Q14 */ + } + + IF(EQ_16(L_frame, L_FRAME)) + { + step = shr(sub(gain,st_fx->lp_gainp_fx),8); + } + ELSE /*L_frame == L_FRAME16k*/ + { + /*step = (1.0f/L_frame) * (gain - st_fx->lp_gainp);*/ + + step = shr(mult_r(26214,sub(gain,st_fx->lp_gainp_fx)),8); /*Q14*/ + } + } + + FOR( i=0 ; i< L_frame; i++ ) + { + /* exc[i] *= gain */ + exc[i] = round_fx(L_shl(L_mult(exc[i], gain), 1)); /* in Q_exc */ + /* gain -= step */ + gain = sub(gain, step); + } + test(); + test(); + IF( (EQ_16(st_fx->last_coder_type_fx,AUDIO)||EQ_16(st_fx->last_good_fx,INACTIVE_CLAS))&& hGSCDec->Last_GSC_pit_band_idx_fx>0) + { + Diff_len = mfreq_loc_div_25[hGSCDec->Last_GSC_pit_band_idx_fx]; + move16(); + + /* Transform to frequency domain */ + edct_16fx( exc, exc_dct_in, st_fx->L_frame, 5, st_fx->element_mode); + + /* Reset unvaluable part of the adaptive (pitch) excitation contribution */ + max_len = sub(st_fx->L_frame,Diff_len); + Len = s_min( max_len, 80 ); + + move16(); /*ptr init*/ + FOR( i=0; ilast_good >= VOICED_TRANSITION" */ + + /*-----------------------------------------------------------------* + * Replicate the last spectrum in case the last good frame was coded by GSC + *-----------------------------------------------------------------*/ + test(); + test(); + test(); + IF( EQ_16(st_fx->last_coder_type_fx,AUDIO)||(EQ_16(st_fx->last_good_fx,INACTIVE_CLAS)&&LE_32(st_fx->total_brate, MAX_GSC_INACTIVE_BRATE)&&!st_fx->Opt_AMR_WB)) + { + st_fx->GSC_noisy_speech_fx = st_fx->Last_GSC_noisy_speech_flag_fx; + move16(); + /* Replication of the last spectrum, with a slight downscaling of its dynamic */ + gsc_dec_fx( st_fx, exc_dct_in, hGSCDec->Last_GSC_pit_band_idx_fx, Diff_len, 0, st_fx->L_frame/L_SUBFR, st_fx->last_coder_type_fx, &last_bin_fx, lsf_new, NULL, st_fx->Q_exc ); + *tmp_noise = shr_r(st_fx->lp_gainc_fx,3); /*Q0*/ + /* Transform back to time domain */ + edct_16fx( exc_dct_in, exc, st_fx->L_frame, 5, st_fx->element_mode); + } + ELSE + { + /*-----------------------------------------------------------------* + * Construct the random part of excitation + *-----------------------------------------------------------------*/ + + /* generate the random part of the excitation */ + FOR (i=0; iseed ),3); + move16(); + } + + /* start of the frame gain */ + gain = st_fx->lp_gainc_fx; + move16(); + + test(); + test(); + test(); + IF(!(GE_16(st_fx->last_good_fx,VOICED_CLAS)&<_16(st_fx->last_good_fx,INACTIVE_CLAS)&&NE_16(st_fx->last_coder_type_fx,AUDIO)&>_16(st_fx->nbLostCmpt,1))) + { + /* Here alpha is in Q15 and lp_gainc_fx in Q3 */ + /* st_fx->lp_gainc = alpha * st_fx->lp_gainc + (1.0f - alpha) * gainCNG; */ + L_tmp = L_mult(alpha, st_fx->lp_gainc_fx); + + st_fx->lp_gainc_fx = msu_r(L_tmp, add(alpha, -32768), gainCNG); + } + ELSE + { /* Here alpha is in Q14, but lp_gainc still in Q3 */ + /* st_fx->lp_gainc = alpha * st_fx->lp_gainc + (1.0f - alpha) * gainCNG; */ + L_tmp = L_mult(alpha, st_fx->lp_gainc_fx); /* Q14*Q3->Q18 */ + + st_fx->lp_gainc_fx = round_fx(L_shl(L_msu(L_tmp, add(alpha, -16384), gainCNG),1));/* (Q14*Q3<<1)>>16 ->Q3 */ + } + + test(); + test(); + test(); + if( EQ_16(st_fx->last_good_fx,UNVOICED_TRANSITION)&&(EQ_16(st_fx->last_coder_type_fx,GENERIC)||EQ_16(st_fx->last_coder_type_fx,TRANSITION))&&gainCNG>0) + { + st_fx->lp_gainc_fx = gainCNG; + move16(); + } + + /* linearly attenuate the gain throughout the frame */ + /* step = (1.0f/L_FRAME) * (gain - *lp_gainc); */ + step = sub(gain,st_fx->lp_gainc_fx); /* divide by L_FRAME done later */ + test(); + if(EQ_16(L_frame,L_FRAME16k)) + { + step = mult_r(step,26214); /* L_frame16k-> L_frame and division by L_frame done later*/ + } + + /* calculate gain to normalize energy */ + pt_exc = exc2_buf + MODE1_L_FIR_FER/2; + move16(); + + /* To avoid saturation split the L_frame dot product into (L_frame/L_SUBFR) dot products + and scale down before adding */ + /* gain_inov = 1.0f / (float)sqrt( dotp( pt_exc, pt_exc, L_frame ) / L_frame + 0.01f ); */ + + L_tmp = L_deposit_l(0); + FOR (i = 0; i < 2; i++) + { + L_tmp2 = L_mult0(*pt_exc, *pt_exc); + pt_exc++; + FOR (j = 1; j < shr(L_frame,1); j++) + { + L_tmp2 = L_mac0(L_tmp2, *pt_exc, *pt_exc); /* Q-5 */ + pt_exc++; + } + L_tmp = L_add(L_tmp, L_shr(L_tmp2, 1)); /* Q-7 */ + } + test(); + if(EQ_16(L_frame,L_FRAME16k)) + { + L_tmp = Mult_32_16(L_tmp, 26214); /* x0.8 to normalize to 256 samples */ + } + exp = norm_l(L_tmp); + L_tmp = L_shl(L_tmp, exp); /* Normalize */ + exp = add(exp, 8-7); /* Q0, 8 ->divide by 256 */ + exp = sub(31, exp); /* For Denormalization in Q31 */ + L_tmp = Isqrt_lc(L_tmp, &exp);/* in Q(31-exp) */ + gain_inov = round_fx(L_tmp); + + /* attenuate somewhat on unstable unvoiced */ + test(); + test(); + if( (EQ_16(st_fx->last_good_fx,UNVOICED_CLAS)||EQ_16(st_fx->last_good_fx,INACTIVE_CLAS))&&NE_16(st_fx->last_coder_type_fx,UNVOICED)) + { + gain_inov = mult_r(gain_inov, 26214); + } + + /* scaling of the random part of excitation */ + pt_exc = exc2_buf; + move16(); + L_step = L_shr(L_mult(gain_inov, step), 8); /* here is the divide by L_FRAME */ + L_tmp2 = L_mult(gain_inov, gain); /* Q15 * Q3 -> Q3 */ + tmp = round_fx(L_tmp2); + exp = add(add(exp, *Q_exc), 15); /* 3+Q_exc+15 -> Q_exc+18 */ + + FOR( i=0; i< MODE1_L_FIR_FER/2; i++ ) + { + /* non-causal ringing of the FIR filter */ + /**pt_exc++ *= (gain_inov * gain);*/ + L_tmp = L_mult(tmp, *pt_exc); /* Q_exc+18 * Q-3 -> Q_exc+16 */ + *pt_exc++ = round_fx(L_shl(L_tmp, exp)); + } + + FOR( i=0; i< L_frame; i++ ) + { + /* the inner part of the FIR filter */ + /* *pt_exc++ *= (gain_inov * gain); */ + L_tmp = L_mult(tmp, *pt_exc); + *pt_exc++ = round_fx(L_shl(L_tmp, exp)); + /* gain -= step; */ + L_tmp2 = L_sub(L_tmp2, L_step); + tmp = round_fx(L_tmp2); + + } + + FOR (i = 0 ; i < MODE1_L_FIR_FER/2; i++) /* causal ringing of the FIR filter */ + { + /* *pt_exc++ *= (gain_inov * gain) */ + L_tmp = L_mult(tmp, *pt_exc); + *pt_exc++ = round_fx(L_shl(L_tmp, exp)); + } + } + + /*-----------------------------------------------------------------* + * Total excitation + *-----------------------------------------------------------------*/ + test(); + test(); + test(); + test(); + IF( (EQ_16(st_fx->last_coder_type_fx,AUDIO)||EQ_16(st_fx->last_good_fx,INACTIVE_CLAS))&&LE_32(st_fx->total_brate, MAX_GSC_INACTIVE_BRATE)&&!st_fx->Opt_AMR_WB) + { + /* For GSC - the excitation is already computed */ + Copy( exc, exc2, st_fx->L_frame ); + } + ELSE IF( GE_16(st_fx->last_good_fx,UNVOICED_TRANSITION)&<_16(st_fx->last_good_fx,INACTIVE_CLAS)) + { + /* For voiced and generic signals - prepare a HP filter for the random part of excitation */ + /* tmp = -(1-tilt_code) to correctly represent 1.0000 */ + tmp = add(st_fx->tilt_code_fx, -32768); + move16(); + FOR (i = 0; i < MODE1_L_FIR_FER; i++) + { + hp_filt[i] = msu_r(0, tmp, h_high_fx[i]); + move16(); + } + + /* HP filter the random part of the excitation and add the adaptive part */ + pt_exc = exc2_buf; + move16(); + FOR( i=0; i< L_frame; i++ ) + { + /* exc2[i] = exc[i] + dotp( &exc2_buf[i], hp_filt, MODE1_L_FIR_FER );*/ + L_tmp = L_mult(hp_filt[0], pt_exc[0]); + FOR (j = 1; j < MODE1_L_FIR_FER; j++) + { + L_tmp = L_mac(L_tmp, hp_filt[j], pt_exc[j]); + } + exc2[i] = msu_r(L_tmp, -32768, exc[i]); + move16(); + pt_exc++; + } + } + ELSE + { + /* For purely unvoiced signals - just copy the unfiltered random part of the excitation */ + Copy( exc2_buf + MODE1_L_FIR_FER/2, exc, L_frame ); + Copy( exc2_buf + MODE1_L_FIR_FER/2, exc2, L_frame ); + } + IF(st_fx->hBWE_TD != NULL) + { + IF(EQ_16(L_frame, L_FRAME)) + { + + interp_code_5over2_fx(exc, bwe_exc, L_frame); + } + ELSE + { + interp_code_4over2_fx(exc, bwe_exc, L_frame); + } + } + test(); + IF( EQ_16(st_fx->last_coder_type_fx,AUDIO)||EQ_16(st_fx->last_good_fx,INACTIVE_CLAS)) + { + IF( EQ_16(st_fx->L_frame,L_FRAME)) + { + set16_fx( voice_factors, 32767, NB_SUBFR ); + } + ELSE + { + set16_fx( voice_factors, 32767, NB_SUBFR16k ); + } + } + ELSE + { + IF( EQ_16(st_fx->L_frame,L_FRAME)) + { + set16_fx( voice_factors, st_fx->last_voice_factor_fx, NB_SUBFR); /* The factor of the last subframe is propagated forward */ + } + ELSE + { + set16_fx( voice_factors, st_fx->last_voice_factor_fx, NB_SUBFR16k ); /* The factor of the last subframe is propagated forward */ + } + } + IF( st_fx->Opt_AMR_WB ) + { + gain_dec_bfi_fx(hAmrwb_IO->past_qua_en_fx); + } + st_fx->bfi_pitch_fx = pitch_buf[(L_frame/L_SUBFR)-1]; + move16(); + st_fx->bfi_pitch_frame = st_fx->L_frame; + move16(); + return; +} + + +/*calculates some conditions for Pulse resynchronization to take place*/ +static void pulseRes_preCalc(Word16* cond1, Word16* cond2, Word32* cond3 ,Word16 new_pit, Word16 Tc, Word16 L_frame) +{ + Word16 tmp_pit, tmp_pit_e, tmp_frame, tmp_frame_e; + Word32 tmp_pit2; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + + tmp_pit = BASOP_Util_Divide1616_Scale(new_pit/*Q0*/,Tc/*Q0*/,&tmp_pit_e)/*Q15*/; + tmp_frame = add( extract_l(L_mult0(L_frame , 64/*1.f/L_SUBFR Q12*/)/*Q12*/) , 4096/*1.f Q12*/ );/*Q12*/ + tmp_frame = BASOP_Util_Divide1616_Scale(4096/*1.f Q12*/,tmp_frame, &tmp_frame_e);/*Q15*/ + tmp_frame = shl(tmp_frame,add(tmp_frame_e,1)); + tmp_frame = sub(32767/*1.f Q15*/, tmp_frame);/*Q15*/ + BASOP_SATURATE_WARNING_OFF_EVS + /*To calc Q15 threshold, overflow may happen - do negation and compare with negated value to check also highest possible value*/ +#ifdef BASOP_NOGLOB + tmp_pit = shl_o(negate(tmp_pit), tmp_pit_e, &Overflow); +#else + tmp_pit = shl(negate(tmp_pit),tmp_pit_e); +#endif + BASOP_SATURATE_WARNING_ON_EVS + *cond1 = sub(tmp_pit, negate(tmp_frame)); + + *cond2 = sub(Tc, new_pit); + + tmp_pit_e = BASOP_Util_Add_MantExp(new_pit,15-0,negate(Tc),15-0,&tmp_pit);/*Q15*/ + tmp_pit = abs_s(tmp_pit); + tmp_pit2 = L_mult(Tc,4915/*0.15f Q15*/);/*Q16*/ + BASOP_SATURATE_WARNING_OFF_EVS + /*To calc Q15 threshold, overflow may happen - do negation and compare with negated value to check also highest possible value*/ + tmp_pit2 = L_shl(L_negate(tmp_pit2),sub(15-16,tmp_pit_e)); + BASOP_SATURATE_WARNING_ON_EVS + *cond3 = L_sub(L_mult0(-1, tmp_pit),tmp_pit2); +} + +/*-------------------------------------------------------------------* + * gain_dec_bfi() + * + * Estimate past quantized gain prediction residual to be used in + * next frame + *-------------------------------------------------------------------*/ + +void gain_dec_bfi_fx( + Word16 *past_qua_en /* i/o: gain quantization memory (4 words) */ +) +{ + Word16 i; + Word16 av_pred_en; + Word32 Lav_pred_en; + + Lav_pred_en = L_mult(past_qua_en[0], 8192); + FOR (i = 1; i < GAIN_PRED_ORDER; i++) + { + Lav_pred_en = L_mac(Lav_pred_en, past_qua_en[i], 8192); + } + + /*av_pred_en = (float)(av_pred_en*(1.0f/(float)GAIN_PRED_ORDER)-3.0f);*/ + av_pred_en = sub(round_fx(Lav_pred_en),3<<10); + + /*if (av_pred_en < -14.0f)av_pred_en = -14.0f;*/ + av_pred_en = s_max(av_pred_en, -14 * (1 << 10)); + + + FOR (i=GAIN_PRED_ORDER-1; i>0; i--) + { + past_qua_en[i] = past_qua_en[i-1]; + move16(); + } + + past_qua_en[0] = av_pred_en; + move16(); + + return; +} diff --git a/lib_dec/FEC_lsf_estim.c b/lib_dec/FEC_lsf_estim.c index e8e16599149c57723c6432fa0149abad1639b566..e8b74f85baaa8a124008167227b554c4ddc240ea 100644 --- a/lib_dec/FEC_lsf_estim.c +++ b/lib_dec/FEC_lsf_estim.c @@ -42,13 +42,13 @@ #include "wmc_auto.h" /*-------------------------------------------------------------------* - * FEC_lsf_estim() + * FEC_lsf2lsp_interp_flt() * * - LSP calculation * - A(z) calculation *-------------------------------------------------------------------*/ -void FEC_lsf2lsp_interp( +void FEC_lsf2lsp_interp_flt( Decoder_State *st, /* i/o: Decoder static memory */ const int16_t L_frame, /* i : length of the frame */ float *Aq, /* o : calculated A(z) for 4 subframes */ diff --git a/lib_dec/FEC_lsf_estim_fx.c b/lib_dec/FEC_lsf_estim_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..bdfbb20233c6093afe4d8e152c2aaa03eccc58c1 --- /dev/null +++ b/lib_dec/FEC_lsf_estim_fx.c @@ -0,0 +1,60 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include +#include "options.h" /* Compilation switches */ +#include "cnst.h" /* Common constants */ +#include "rom_com.h" /* Static table prototypes */ +#include "prot_fx1.h" /* Function prototypes */ +#include "prot_fx2.h" /* Function prototypes */ + + +/*-------------------------------------------------------------------* + * FEC_lsf_estim() + * + * - LSP calculation + * - A(z) calculation + *-------------------------------------------------------------------*/ + +void FEC_lsf2lsp_interp( + Decoder_State *st, /* i/o: Decoder static memory */ + const Word16 L_frame, /* i : length of the frame */ + Word16 *Aq, /* o : calculated A(z) for 4 subframes */ + Word16 *lsf, /* o : estimated LSF vector */ + Word16 *lsp /* o : estimated LSP vector */ +) +{ + + /* convert LSFs to LSPs */ + IF ( st->Opt_AMR_WB ) + { + E_LPC_isf_isp_conversion( lsf, lsp, M); + } + ELSE + { + IF( EQ_16(L_frame,L_FRAME)) + { + lsf2lsp_fx( lsf, lsp, M, INT_FS_FX ); + } + ELSE /* L_frame == L_FRAME16k */ + { + lsf2lsp_fx( lsf, lsp, M, INT_FS_16k_FX); + } + } + + /*----------------------------------------------------------------------* + * Interpolate LSP vector and find A(z) + *----------------------------------------------------------------------*/ + + IF ( st->Opt_AMR_WB ) + { + int_lsp_fx( L_frame, st->lsp_old_fx, lsp, Aq, M, interpol_isp_amr_wb_fx, 1 ); + } + ELSE + { + int_lsp_fx( L_frame, st->lsp_old_fx, lsp, Aq, M, interpol_frac_fx, 0 ); + } + + return; +} diff --git a/lib_dec/FEC_pitch_estim_fx.c b/lib_dec/FEC_pitch_estim_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..85cf056ec80536d7e3dcc3c86cd54b3b33c27007 --- /dev/null +++ b/lib_dec/FEC_pitch_estim_fx.c @@ -0,0 +1,113 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ +#include +#include "options.h" /* Compilation switches */ +#include "cnst.h" /* Common constants */ +#include "prot_fx1.h" /* Function prototypes */ +#include "prot_fx2.h" /* Function prototypes */ +#include "stl.h" + + +/*========================================================================*/ +/* FUNCTION : FEC_pitch_estim_fx() */ +/*------------------------------------------------------------------------*/ +/* PURPOSE : Estimation of pitch for FEC */ +/* */ +/*------------------------------------------------------------------------*/ +/* INPUT ARGUMENTS : */ +/* _ (Word16) st_fx->Opt_AMR_WB: flag indicating AMR-WB IO mode */ +/* _ (Word16) st_fx->L_frame_fx: length of the frame */ +/* _ (Word16) st_fx->clas_dec: frame classification */ +/* _ (Word16) st_fx->last_good_fx: last good clas information */ +/* _ (Word16[]) pitch : pitch values for each subframe Q6 */ +/* _ (Word16[]) old_pitch_buf:pitch values for each subframe Q6 */ +/*------------------------------------------------------------------------*/ +/* INPUT/OUTPUT ARGUMENTS : */ +/*------------------------------------------------------------------------*/ +/* OUTPUT ARGUMENTS : */ +/*------------------------------------------------------------------------*/ + +/* _ (Word16[]) st_fx->bfi_pitch : initial synthesis filter states */ +/* _ (Word16) st_fx->bfi_pitch_frame: LP filter E of last */ +/* _ (Word16) st_fx->upd_cnt_fx: update counter */ +/*------------------------------------------------------------------------*/ +/* RETURN ARGUMENTS : */ +/* _ None */ +/*========================================================================*/ +void FEC_pitch_estim_fx( + const Word16 Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ + const Word16 last_core, /* i : last core */ + const Word16 L_frame, /* i : length of the frame */ + const Word16 clas, /* i : current frame classification */ + const Word16 last_good, /* i : last good clas information */ + const Word16 pitch_buf[], /* i : Floating pitch for each subframe */ + const Word32 old_pitch_buf[], /* i : buffer of old subframe pitch values 15Q16 */ + Word16 *bfi_pitch, /* i/o: update of the estimated pitch for FEC */ + Word16 *bfi_pitch_frame, /* o : frame length when pitch was updated */ + Word16 *upd_cnt /* i/o: update counter */ + ,const Word16 coder_type /* i : coder_type */ +) +{ + Word16 tmp,tmp1,tmp2,tmp3; + Word16 tmp16k1,tmp16k2; + + tmp = mult_r(pitch_buf[1],22938); /*Q6( 0.7f * pitch_buf[1] 0.7 in Q15)*/ + tmp1 = shl(tmp,1); /*Q6 (1.4f * pitch_buf[1])*/ + tmp2 = round_fx(L_shl(Mpy_32_16_1(old_pitch_buf[2*NB_SUBFR-1],22938), 6)); /*Q6 (0.7f * old_pitch_buf[2*NB_SUBFR-1])*/ + tmp3 = shl(tmp2,1); /*Q6 (1.4f * old_pitch_buf[2*NB_SUBFR-1])*/ + + tmp16k1 = round_fx(L_shl(Mpy_32_16_1(old_pitch_buf[2*NB_SUBFR16k-1],22938), 6)); /*Q6 0.7f * old_pitch_buf[2*NB_SUBFR16k-1]*/ +#ifdef BASOP_NOGLOB + tmp16k2 = shl_sat(tmp16k1,1); /*Q6 1.4f * old_pitch_buf[2*NB_SUBFR16k-1]*/ +#else + tmp16k2 = shl(tmp16k1,1); /*Q6 1.4f * old_pitch_buf[2*NB_SUBFR16k-1]*/ +#endif +#ifdef IVAS_CODE + test(); test(); + IF (EQ_16(last_core, HQ_CORE) || EQ_16(last_core, TCX_20_CORE) || EQ_16(last_core, TCX_10_CORE)) +#else + IF( EQ_16(last_core,HQ_CORE)) +#endif + { + *bfi_pitch = pitch_buf[shr(L_frame,6)-1]; + move16(); + *bfi_pitch_frame = L_frame; + move16(); + *upd_cnt = MAX_UPD_CNT; + move16(); + } + + test(); + test(); + test(); + IF( (EQ_16(clas,VOICED_CLAS)&&GE_16(last_good,VOICED_TRANSITION))||(Opt_AMR_WB&&EQ_16(clas,VOICED_CLAS))) + { + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( ( (LT_16(pitch_buf[3],tmp1))&&(GT_16(pitch_buf[3],tmp))&& + (LT_16(pitch_buf[1],tmp3) ) && (GT_16(pitch_buf[1],tmp2) ) && + (EQ_16(L_frame,L_FRAME) ) ) || + ( (LT_16(pitch_buf[3],tmp1) ) && (GT_16(pitch_buf[3],tmp) ) && + (LT_16(pitch_buf[1],tmp16k2) ) && (GT_16(pitch_buf[1],tmp16k1) ) && + (EQ_16(L_frame,L_FRAME16k) ) ) + || (EQ_16(coder_type, TRANSITION) ) ) + { + *bfi_pitch = pitch_buf[shr(L_frame,6)-1]; + move16(); + *bfi_pitch_frame = L_frame; + move16(); + *upd_cnt = 0; + move16(); + } + } +} + diff --git a/lib_dec/FEC_scale_syn_fx.c b/lib_dec/FEC_scale_syn_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..df9c7c5b28a6222a93681a5053cda40ae76aca1c --- /dev/null +++ b/lib_dec/FEC_scale_syn_fx.c @@ -0,0 +1,646 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ +#include +#include "options.h" /* Compilation switches */ +#include "cnst.h" /* Common constants */ +#include "prot_fx1.h" /* Function prototypes */ +#include "prot_fx2.h" /* Function prototypes */ + +/*-------------------------------------------------------------------* + * Local constants + *-------------------------------------------------------------------*/ +#define AGC_FX 32113 /* 0.98f */ +#define SCLSYN_LAMBDA (9830/*0.3f Q15*/) + +/*========================================================================*/ +/* FUNCTION : FEC_scale_syn_fx() */ +/*------------------------------------------------------------------------*/ +/* PURPOSE : Smooth the speech energy evolution when */ +/* recovering after a BAD frame */ +/*------------------------------------------------------------------------*/ +/* INPUT ARGUMENTS : */ +/* _ (Word16) L_frame : length of the frame */ +/* _ (Word16) *update_flg : indication about resynthesis */ +/* _ (Word16) st_fx->clas_dec: frame classification */ +/* _ (Word16) last_good : last good frame classification */ +/* _ (Word16[]) synth : synthesized speech at Fs = 12k8 Hz Q_syn */ +/* _ (Word16[]) pitch : pitch values for each subframe Q0 */ +/* _ (Word32) L_enr_old :energy at the end of previous frame Q0 */ +/* _ (Word16) L_enr_q : transmitted energy for current frame Q0 */ +/* _ (Word16) coder_type : coder type */ +/* _ (Word16) st_fx->prev_bfi_fx: previous frame BFI */ +/* _ (Word16) st_fx->last_core_brate_fx: previous frame core bitrate */ +/* _ (Word16[]) mem_tmp : temp. initial synthesis filter states Q_syn */ +/* _ (Word16) Q_exc : quantized LSPs from frame end */ +/* _ (Word16) Q_syn : quantized LSPs from frame end */ +/*------------------------------------------------------------------------*/ +/* INPUT/OUTPUT ARGUMENTS : */ +/* _ (Word16[]) exc : excitation signal without enhancement Q_exc */ +/* _ (Word16[]) exc2 : excitation signal with enhancement Q_exc */ +/* _ (Word16[]) Aq : LP filter coefs (can be modified if BR) Q12 */ +/*------------------------------------------------------------------------*/ +/* OUTPUT ARGUMENTS : */ +/*------------------------------------------------------------------------*/ + +/* _ (Word16[]) st_fx->mem_syn2 : initial synthesis filter states Q_syn */ +/* _ (Word16) st_fx->old_enr_LP : LP filter E of last Q5 */ +/* good voiced frame */ +/*------------------------------------------------------------------------*/ +/* RETURN ARGUMENTS : */ +/* _ None */ +/*========================================================================*/ + + +void FEC_scale_syn_fx( + const Word16 L_frame, /* i : length of the frame */ + Word16 *update_flg, /* o: flag indicating re-synthesis after scaling*/ + Word16 clas, /* i/o: frame classification */ + const Word16 last_good, /* i: last good frame classification */ + Word16 *synth, /* i/o: synthesized speech at Fs = 12k8 Hz */ + const Word16 *pitch, /* i: pitch values for each subframe */ + Word32 L_enr_old, /* i: energy at the end of previous frame */ + Word32 L_enr_q, /* i: transmitted energy for current frame */ + const Word16 coder_type, /* i: coder type */ + const Word16 LSF_Q_prediction, /* i : LSF prediction mode */ + Word16 *scaling_flag, /* i/o: flag to indicate energy control of syn */ + Word32 *lp_ener_FEC_av, /* i/o: averaged voiced signal energy */ + Word32 *lp_ener_FEC_max, /* i/o: averaged voiced signal energy */ + const Word16 bfi, /* i: current frame BFI */ + const Word32 total_brate, /* i: total bitrate */ + const Word16 prev_bfi, /* i: previous frame BFI */ + const Word32 last_core_brate, /* i: previous frame core bitrate */ + Word16 *exc, /* i/o: excitation signal without enhancement */ + Word16 *exc2, /* i/o: excitation signal with enhancement */ + Word16 Aq[], /* i/o: LP filter coefs (can be modified if BR) */ + Word16 *old_enr_LP, /* i/o: LP filter E of last good voiced frame */ + const Word16 *mem_tmp, /* i: temp. initial synthesis filter states */ + Word16 *mem_syn, /* o: initial synthesis filter states */ + Word16 Q_exc, + Word16 Q_syn, + const Word16 avoid_lpc_burst_on_recovery, /* i : if true the excitation energy is limited if LP has big gain */ + const Word16 force_scaling /* i: force scaling */ +) +{ + Word16 i; + Word32 L_enr1, L_enr2; + Word16 gain1, gain2, enr_LP; + Word16 tmp, tmp2, exp, exp2; + Word16 tmp3; + Word32 L_tmp; + Word16 scaling; + Word32 ener_max, L_enr2_av, L_ener2_max; + Word16 h1[L_FRAME/2], tilt, pitch_dist, mean_pitch; + Word16 k; + Word32 L_mean_pitch; + + enr_LP = 0; + move16(); + gain2 = 0; + move16(); + gain1 = 0; + move16(); + *update_flg = 0; + move16(); + L_enr_old = L_max(1, L_enr_old); /* to avoid division by zero (*L_enr_old is always >= 0) */ + scaling = 16384; + move16(); /* Q14*/ + + /*-----------------------------------------------------------------* + * Find the synthesis filter impulse response on voiced + *-----------------------------------------------------------------*/ + test(); + IF( GE_16(clas,VOICED_TRANSITION)&<_16(clas,INACTIVE_CLAS)) + { + IF( EQ_16(L_frame,L_FRAME)) + { + enr_LP = Enr_1_Az_fx(Aq+(NB_SUBFR-1)*(M+1), L_SUBFR ); + } + ELSE /* L_frame == L_FRAME16k */ + { + enr_LP = Enr_1_Az_fx( Aq+(NB_SUBFR16k-1)*(M+1), L_SUBFR ); /*Q3*/ + } + } + + /*-----------------------------------------------------------------* + * Define when to scale the synthesis + *-----------------------------------------------------------------*/ + + IF( bfi ) + { + *scaling_flag = 1; + move16(); /* Always check synthesis on bad frames */ + } + ELSE IF( prev_bfi ) + { + test(); + IF( ( EQ_16(LSF_Q_prediction,AUTO_REGRESSIVE))||(EQ_16(LSF_Q_prediction,MOVING_AVERAGE))) + { + *scaling_flag = 2; + move16(); /* Decoded LSFs affected */ + } + ELSE IF( NE_16(coder_type,TRANSITION)) + { + *scaling_flag = 1; + move16(); /* SN, but not TC mode - LSF still affected by the interpolation */ + } + ELSE + { + *scaling_flag = 0; + move16(); /* LSF still possibly affected due to interpolation */ + } + scaling = 24576; /*1.5 Q14*/ move16(); + } + ELSE + { + test(); + IF( (EQ_16(LSF_Q_prediction,AUTO_REGRESSIVE))&&(EQ_16(*scaling_flag,2))) + { + *scaling_flag = 2; + move16(); /* Continue with energy control till the end of AR prediction */ + } + ELSE IF( *scaling_flag > 0 ) + { + (*scaling_flag) = sub(*scaling_flag,1); /* If scaling flag was equal to 2, add one control frame to account for the LSF interpolation */ + } + scaling = 32767; /*2.0 Q14*/ move16(); + } + + /*-----------------------------------------------------------------* + * Find the energy/gain at the end of the frame + *-----------------------------------------------------------------*/ + + /*fer_energy( L_frame, clas, synth, pitch[(L_frame>>6)-1], &enr2, L_frame );*/ + frame_ener_fx(L_frame,clas, synth, pitch[sub(shr(L_frame,6),1)], &L_enr2/*Q0*/, 1, Q_syn, 3, 0); + + if( bfi || (EQ_32(total_brate,ACELP_7k20))||(EQ_32(total_brate,ACELP_8k00))) + { + /* previous frame erased and no TC frame */ + IF( *scaling_flag > 0 ) + { + /*enr2 += 0.01f;*/ + L_enr2 = L_max(L_enr2, 1); /* L_enr2 is in Q0 */ + + IF( bfi ) /* In all bad frames, limit the gain to 1 */ + { + /* gain2 = (float)sqrt( enr_old / enr2 );*/ + L_tmp = Sqrt_Ratio32(L_enr_old, 0, L_enr2, 0, &exp2); +#ifdef BASOP_NOGLOB + gain2 = round_fx_sat(L_shl_sat(L_tmp, sub(exp2, 1))); /* in Q14 */ +#else + gain2 = round_fx(L_shl(L_tmp, sub(exp2, 1))); /* in Q14 */ +#endif + + /*if( gain2 > 1.0f )gain2 = 1.0f;*/ + gain2 = s_min(gain2, 16384); + + /* find the energy/gain at the beginning of the frame */ + frame_ener_fx(L_frame,clas, synth, pitch[0], &L_enr1/*Q0*/, 1, Q_syn, 3, 0); + + /*enr1 += 0.1f;*/ + L_enr1 = L_max(L_enr1, 1); /* L_enr2 is in Q0 */ + + /*gain1 = (float)sqrt( enr_old / enr1 );*/ + L_tmp = Sqrt_Ratio32(L_enr_old, 0, L_enr1, 0, &exp2); +#ifdef BASOP_NOGLOB + gain1 = round_fx_sat(L_shl_sat(L_tmp, sub(exp2, 1))); /* in Q14 */ +#else + gain1 = round_fx(L_shl(L_tmp, sub(exp2, 1))); /* in Q14 */ +#endif + + /*if( gain1 > 1.0f )gain1 = 1.0f;*/ + gain1 = s_min(gain1, 16384); + } + ELSE /* good frame */ + { + IF( L_enr_q == 0 ) /* If E info (FEC protection bits) is not available in the bitstream */ + { + L_enr_q = L_enr2; + set16_fx( h1, 0, L_FRAME/2 ); + h1[0] = 1024; + move16(); + /*syn_filt( Aq+(3*(M+1)), M, h1, h1, L_FRAME/2, h1+(M+1), 0 );*/ + E_UTIL_synthesis(1, Aq+(3*(M+1)), h1, h1, L_FRAME/2, h1+(M+1), 0, M); + + /*Compute tilt */ + /*rr0 = dotp( h1, h1, L_FRAME/2-1 ) + 0.1f;*/ + /*rr1 = dotp( h1, h1+1, L_FRAME/2-1 );*/ + /*tilt = rr1 / rr0;*/ +#ifdef BASOP_NOGLOB + tilt = extract_h(L_shl_sat(get_gain(h1+1, h1, L_FRAME/2-1),15)); +#else + tilt = extract_h(L_shl(get_gain(h1+1, h1, L_FRAME/2-1),15)); +#endif + pitch_dist = 0; + move16(); + L_mean_pitch = L_mult(pitch[0], 8192); + move32(); + FOR( k=0; k<(NB_SUBFR - 1); k++ ) + { + pitch_dist = add(pitch_dist, abs_s(sub(pitch[k+1],pitch[k]))); + L_mean_pitch = L_mac(L_mean_pitch, pitch[k+1], 8192); + } + /*pitch_dist /= (float)(NB_SUBFR-1); */ + pitch_dist = mult_r(shl(pitch_dist,4),10923); + /*mean_pitch /= (float)(NB_SUBFR);*/ + mean_pitch = extract_h(L_shl(L_mean_pitch,4)); + + + test(); + test(); + test(); + test(); + test(); + test(); + IF( ( GT_16(tilt,22938))&& /* HF resonnant filter */ + ( (GT_16(pitch_dist, 8<<4) ) || (LT_16(mean_pitch,PIT_MIN<<4) ) ) && /* pitch unstable or very short */ + ( (prev_bfi) || ( (EQ_16(coder_type,GENERIC) ) && (EQ_16(LSF_Q_prediction,AUTO_REGRESSIVE) ) ) ) ) + { + /*if( enr_q > scaling * enr_old ){enr_q = scaling * enr_old;}*/ + L_enr_q = L_min(L_enr_q, L_shl(Mult_32_16(L_enr_old, scaling),1)); /* scaling in Q14*/ + } + ELSE + { + ener_max = *lp_ener_FEC_max; + move32(); + test(); + if( EQ_16(clas,VOICED_TRANSITION)||(GE_16(clas,INACTIVE_CLAS))) + { + ener_max = *lp_ener_FEC_av; + move32(); + } + /*if( enr_old > ener_max )ener_max = enr_old;*/ + ener_max = L_max(ener_max, L_enr_old); + + /*if( enr_q > scaling * ener_max ){enr_q = scaling * ener_max;}*/ +#ifdef BASOP_NOGLOB + L_enr_q = L_min(L_enr_q, L_shl_sat(Mult_32_16(ener_max, scaling),1)); /* scaling in Q14*/ +#else + L_enr_q = L_min(L_enr_q, L_shl(Mult_32_16(ener_max, scaling),1)); /* scaling in Q14*/ +#endif + } + } + /*gain2 = (float)sqrt( enr_q / enr2 );*/ + L_enr_q = L_max(L_enr_q, 1); /* L_enr2 is in Q0 */ + L_tmp = Sqrt_Ratio32(L_enr_q, 0, L_enr2, 0, &exp2); + gain2 = round_fx(L_shl(L_tmp, sub(exp2, 1))); /* in Q14 */ + + /*-----------------------------------------------------------------* + * Find the energy/gain at the beginning of the frame to ensure smooth transition after erasure(s) + *-----------------------------------------------------------------*/ + + test(); + test(); + test(); + test(); + test(); + test(); + IF( ( (GE_16(last_good,VOICED_TRANSITION)&<_16(last_good,INACTIVE_CLAS)&&(EQ_16(clas,UNVOICED_CLAS)||EQ_16(clas,INACTIVE_CLAS)))|| + EQ_32(last_core_brate,SID_1k75) || EQ_32(last_core_brate,SID_2k40) || EQ_32(last_core_brate,FRAME_NO_DATA) ) && prev_bfi ) + { + /* voiced -> unvoiced signal transition */ + /* CNG -> active signal transition */ + gain1 = gain2; + move16(); + } + ELSE + { + /* find the energy at the beginning of the frame */ + frame_ener_fx(L_frame,clas, synth, pitch[0], &L_enr1/*Q0*/, 1, Q_syn, 3, 0); + + /*enr1 += 0.1f;*/ + L_enr1 = L_max(L_enr1, 1); /* L_enr1 is in Q0 */ + + /*gain1 = (float)sqrt( enr_old / enr1 );*/ + L_tmp = Sqrt_Ratio32(L_enr_old, 0, L_enr1, 0, &exp2); +#ifdef BASOP_NOGLOB + gain1 = round_fx_sat(L_shl_sat(L_tmp, sub(exp2, 1))); /* in Q14 */ +#else + gain1 = round_fx(L_shl(L_tmp, sub(exp2, 1))); /* in Q14 */ +#endif + + /*if( gain1 > 1.2f )gain1 = 1.2f;*/ + /* prevent clipping */ + gain1 = s_min(gain1, 19661); + + /* prevent amplifying the unvoiced or inactive part of the frame in case an offset is followed by an onset */ + test(); + test(); + if( EQ_16(clas,ONSET)&>_16(gain1,gain2)&&prev_bfi) + { + gain1 = gain2; + move16(); + } + } + + L_enr2 = L_enr_q; + move32(); /* Set the end frame energy to the scaled energy, to be used in the lp_ener_FEC */ + } + + /*------------------------------------------------------------------------------* + * Smooth the energy evolution by exponentially evolving from gain1 to gain2 + *------------------------------------------------------------------------------*/ + + /*gain2 *= ( 1.0f - AGC );*/ + L_tmp = L_mult(gain2, (Word16)(32768 - AGC_FX)); + FOR( i=0; i scaling * enr_old )enr_q = scaling * enr_old;*/ + L_enr_q = L_min(L_enr_q, L_shl(Mult_32_16(L_enr_old, scaling),1)); /* scaling in Q14*/ + } + ELSE IF( GE_16(last_good,VOICED_TRANSITION)&<_16(last_good,INACTIVE_CLAS)&&GE_16(clas,VOICED_TRANSITION)&<_16(clas,INACTIVE_CLAS)) + { + /* Voiced-voiced recovery */ + test(); +#ifdef BASOP_NOGLOB + IF( *old_enr_LP != 0 && GT_16(enr_LP, shl_sat(*old_enr_LP, 1))) +#else + IF( *old_enr_LP != 0 && GT_16(enr_LP, shl(*old_enr_LP, 1))) +#endif + { + /* enr_q /= enr_LP */ + exp = norm_l(L_enr_q); + tmp = extract_h(L_shl(L_enr_q, exp)); + + exp2 = norm_s(enr_LP); + tmp2 = shl(enr_LP, exp2); + + exp = sub(exp2, exp); + + tmp3 = sub(tmp, tmp2); + IF (tmp3 > 0) + { + tmp = shr(tmp, 1); + exp = add(exp, 1); + } + tmp = div_s(tmp, tmp2); + + /* L_enr_q *= 2 * *old_enr_LP */ + L_enr_q = L_shl(L_mult(tmp, shl(*old_enr_LP, 1)), exp); + } + + ELSE + { + test(); + IF( avoid_lpc_burst_on_recovery && GT_16(enr_LP, 160)) + { + exp = norm_s(enr_LP); + tmp = shl(enr_LP, exp); + + exp2 = 7; + move16(); + tmp2 = 160 << 7; /* 160 = 20.0f in Q3 */ + exp = sub(exp2, exp); + + IF (GT_16(tmp, tmp2)) + { + tmp = shr(tmp, 1); + exp = add(exp, 1); + } + tmp = div_s(tmp, tmp2); /* tmp*2^exp = enr_LP/20.0 */ + L_tmp = Isqrt_lc(L_deposit_h(tmp), &exp); /* L_tmp*2^exp = sqrt(20.0/enr_LP) */ + L_enr_q = L_shl(Mpy_32_32(L_enr_q, L_tmp), exp); + } + } + + } + + test(); + test(); + test(); + IF( (GE_16(last_good,VOICED_TRANSITION)&<_16(last_good,INACTIVE_CLAS)&&GE_16(clas,VOICED_TRANSITION)&<_16(clas,INACTIVE_CLAS)) + || force_scaling ) + { + + IF( GT_32(L_enr_q, L_enr_old)) /* Prevent energy to increase on voiced */ + { + L_enr_q = L_add(Mpy_32_16_1(L_enr_old, 32767 - SCLSYN_LAMBDA), Mpy_32_16_1(L_enr_q, SCLSYN_LAMBDA)); + } + } + } + + L_enr_q = L_max(1, L_enr_q); + + /* gain2 = (float)sqrt( enr_q / enr2 );*/ + exp = norm_l(L_enr_q); + tmp = extract_h(L_shl(L_enr_q, exp)); + + exp2 = norm_l(L_enr2); + tmp2 = extract_h(L_shl(L_enr2, exp2)); + + exp2 = sub(exp, exp2); /* Denormalize and substract */ + + tmp3 = sub(tmp2, tmp); + IF (tmp3 > 0) + { + tmp2 = shr(tmp2, 1); + exp2 = add(exp2, 1); + } + + tmp = div_s(tmp2, tmp); + + L_tmp = L_deposit_h(tmp); + L_tmp = Isqrt_lc(L_tmp, &exp2); +#ifdef BASOP_NOGLOB + gain2 = round_fx_sat(L_shl_sat(L_tmp, sub(exp2, 1))); /* in Q14 */ +#else + gain2 = round_fx(L_shl(L_tmp, sub(exp2, 1))); /* in Q14 */ +#endif + /*-----------------------------------------------------------------* + * Clipping of the smoothing gain at the frame end + *-----------------------------------------------------------------*/ + + gain2 = s_min(gain2, 19661); /* Gain modification clipping */ + if (LT_32(L_enr_q, 2)) + { + gain2 = s_min(gain2, 16384); /* Gain modification clipping */ + } + + /*-----------------------------------------------------------------* + * Find the energy/gain at the beginning of the frame to ensure smooth transition after erasure(s) + *-----------------------------------------------------------------*/ + + test(); + test(); + test(); + test(); + test(); + test(); + IF( EQ_16(clas,SIN_ONSET)) /* slow increase */ + { + gain1 = shr(gain2, 1); + } + /*------------------------------------------------------------* + * voiced->unvoiced transition recovery + *------------------------------------------------------------*/ + ELSE IF( (GE_16(last_good,VOICED_TRANSITION)&<_16(last_good,INACTIVE_CLAS)&&(EQ_16(clas,UNVOICED_CLAS)||EQ_16(clas,INACTIVE_CLAS)))|| /* voiced->unvoiced transition recovery */ + EQ_32(last_core_brate,SID_1k75) || EQ_32(last_core_brate,SID_2k40) || EQ_32(last_core_brate,FRAME_NO_DATA)) /* CNG -> active signal transition */ + { + gain1 = gain2; + move16(); + } + ELSE + { + /*--------------------------------------------------------* + * Find the energy at the beginning of the frame + *--------------------------------------------------------*/ + tmp = frame_ener_fx(L_frame,clas, synth, pitch[0], &L_enr1, 0, Q_syn, 3, 0); + + /*gain1 = (float)sqrt( enr_old / enr1 );*/ + exp = norm_l(L_enr_old); + tmp = extract_h(L_shl(L_enr_old, exp)); + exp2 = norm_l(L_enr1); + tmp2 = extract_h(L_shl(L_enr1, exp2)); + + exp2 = sub(exp, exp2); /* Denormalize and substract */ + + tmp3 = sub(tmp2, tmp); + + IF (tmp3 > 0) + { + tmp2 = shr(tmp2, 1); + exp2 = add(exp2, 1); + } + + tmp = div_s(tmp2, tmp); + + L_tmp = L_deposit_h(tmp); + L_tmp = Isqrt_lc(L_tmp, &exp2); +#ifdef BASOP_NOGLOB + gain1 = round_fx_sat(L_shl_sat(L_tmp, sub(exp2, 1))); /* in Q14 */ +#else + gain1 = round_fx(L_shl(L_tmp, sub(exp2, 1))); /* in Q14 */ +#endif + /* exp2 is always <= 1 */ + + gain1 = s_min(gain1, 19661); + + test(); + test(); + if( avoid_lpc_burst_on_recovery && (GT_16(enr_LP, 160))&&(LE_16(enr_LP,shl(*old_enr_LP,1)))) + { + gain1 = s_min(gain1, 16384); + } + + /*--------------------------------------------------------* + * Prevent a catastrophy in case of offset followed by onset + *--------------------------------------------------------*/ + test(); + if( ( EQ_16(clas,ONSET))&&(GT_16(gain1,gain2))) + { + gain1 = gain2; + move16(); + } + } + /*-----------------------------------------------------------------* + * Smooth the energy evolution by exponentially evolving from + * gain1 to gain2 + *-----------------------------------------------------------------*/ + + L_tmp = L_mult(gain2, (Word16)(32768 - AGC_FX)); + + FOR( i=0; i +#include "options.h" /* Compilation switches */ +#include "cnst.h" /* Common constants */ +#include "rom_com.h" /* Static table prototypes */ +#include "prot_fx1.h" /* Function prototypes */ +#include "prot_fx2.h" /* Function prototypes */ + + +/*-------------------------------------------------------------------* + * Local constants + *-------------------------------------------------------------------*/ + +#define INV_MAX_SNR_FX 745 /* Q15 {1/(45-1)} Max. SNR considered for noise subtraction in voiced segments */ +#define MAX_SNR_SNR1_FX 16756 /* Q14 45* (1/(max_snr1-1)) */ + +#define BIN_1KHZ (Word16)(1000/BIN_16kdct_fx) +#define BIN_2KHZ (Word16)(2000/BIN_16kdct_fx) +#define BIN_4KHZ (Word16)(4000/BIN_16kdct_fx) + +#define MAX_GN_R_Q14_FX 3277 +#define ALPH_Q15_FX 32767 +#define BET_Q15_FX 30310 +#define MAXX_Q12_FX (20480) + +#define MAXX_FX 5 + +/*-------------------------------------------------------------------* + * Local function prototypes + *-------------------------------------------------------------------*/ +static void analy_sp_dct_fx(const Word16 *dct_buf, Word32 *fr_bands, Word32 *lf_E, Word16 *etot, const Word16 Qdct); +static void find_enr_dct_fx(const Word16 data[], Word32 band[], Word32 *ptE, Word32 *Etot, const Word16 min_band, + const Word16 max_band, const Word16 Q_dct, const Word16 bin_freq ); +static Word16 norm_lfe(const Word32 Lfe,const Word16 m_max,const Word16 e_max); +static void spectrum_mod_dct_fx(const Word16 Qdct,Word16 data[], const Word32 lf_E[], Word32 lf_EO[], + const Word32 noiseE[], const Word16 minGain, + Word16 lp_gbin[], const Word16 music_flag, Word16 min_band, const Word16 MAX_GN, const Word16 MAX_band ); + +/*------------------------------------------------------------------------* + * LD_music_post_filter() + * + * Music post-filter + *------------------------------------------------------------------------*/ +void LD_music_post_filter_fx +( + MUSIC_POSTFILT_HANDLE hMusicPF, /* i/o: LD music postfilter handle */ + const Word16 dtc_in[], /* i : input synthesis Qdct */ + Word16 dtc_out[], /* o : output synthesis Qdct */ + const Word32 core_brate, /* i : core bitrate Q0 */ + Word16 *Old_ener_Q, /* i/o : Old energy scaling factor */ + const Word16 coder_type, /* i : Coder type : -1 in case of IO Q0 */ + const Word16 Last_coder_type, /* i : input scaling Q0 */ + const Word16 Qdct /* i : input scaling Q0 */ +) +{ + Word32 fr_bands[MBANDS_GN_LD]; + Word32 lf_E[VOIC_BINS_HR]; + Word32 Ltmp, Ltmp_max; + Word16 LG_etot; /*Q8*/ + Word16 i, j, k; + Word16 min_band = 0; + Word16 local_min_gain; + Word16 music_flag2 = 0; + Word32 max_val; + Word16 max_ovf_2k, max_ovf_4k, max_ovf_6k; + Word16 min_g_2k, min_g_4k, min_g_6k; + Word32 m_ave; + Word16 tmp_lfE[DCT_L_POST]; /*Q12*/ + Word16 MAX_GN = MAX_GN_R_Q14_FX; + Word16 MAX_band = MBANDS_GN_LD; + Word16 mant, exp1, s_ave, tmp16, old_tmp16; + Word16 diff_sc; + Word16 old_tmp16_1; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + + + + local_min_gain = hMusicPF->LDm_enh_min_ns_gain_fx; + + /*------------------------------------------------------------------------* + * Frequency analysis + *------------------------------------------------------------------------*/ + + analy_sp_dct_fx( dtc_in, fr_bands, lf_E, &LG_etot, Qdct); + diff_sc = shl(sub(Qdct, *Old_ener_Q),1); + *Old_ener_Q = Qdct; + move16(); + + Scale_sig32(hMusicPF->LDm_enh_lf_EO_fx, VOIC_BINS_HR, diff_sc); + + /*------------------------------------------------------------------------* + * Find signal classification + *------------------------------------------------------------------------*/ + music_flag2 = stab_est_fx( LG_etot, hMusicPF->LDm_lt_diff_etot_fx, &hMusicPF->LDm_mem_etot_fx + , &hMusicPF->LDm_nb_thr_3_fx, &hMusicPF->LDm_nb_thr_1_fx, hMusicPF->LDm_thres_fx, &hMusicPF->LDm_last_music_flag_fx, 1 ); + + test(); + if ( LT_32(core_brate,ACELP_6k60)||NE_16(Last_coder_type,AUDIO)) + { + /* do not perform music improvement on SID frames */ + music_flag2 = 0; + move16(); + } + + hMusicPF->last_nonfull_music_fx = add(hMusicPF->last_nonfull_music_fx,1); + move16(); + if( LT_16(music_flag2,4)) + { + hMusicPF->last_nonfull_music_fx = 0; + move16(); + } + + + hMusicPF->last_nonfull_music_fx = s_min( 51, hMusicPF->last_nonfull_music_fx); + + /*------------------------------------------------------------------------* + * Remapping of bands + * Section to "remap" the minimal band and the minimum gain for our needs + *------------------------------------------------------------------------*/ + + IF( GT_16(music_flag2,3)) + { + min_band = 2; + move16(); + local_min_gain = 8231; /*Q15->0.25119f;*/ move16(); + } + ELSE IF( EQ_16(music_flag2,3)) + { + min_band = 3; + move16(); + local_min_gain = 8231; /*Q15->0.25119f; */ move16(); + } + ELSE IF( EQ_16(music_flag2,2)) + { + min_band = 4; + move16(); + local_min_gain = 11626; /*Q15->0.35481f; */ move16(); + } + ELSE IF( EQ_16(music_flag2,1)) + { + min_band = 4; + move16(); + local_min_gain = 16423; /*Q15->0.50119f;*/ move16(); + } + + min_band = add(min_band, 4); + + MAX_GN = 1638; /*Q14*/ move16(); + if( GT_32(core_brate,ACELP_9k60)) + { + /* overshoot not allowed, since GSC already matches the energy */ + MAX_GN = 0; + move16(); + } + + if( EQ_16(coder_type,AUDIO)) + { + /* with GSC we know for sure that we are in music */ + min_band = s_min( min_band, 3 ); + } + + /*------------------------------------------------------------------------* + * Approximation of the inter-harmonic noise level + * - sort the bin energy + * - compupte the average energy per band excluding the maximum energy bin + *------------------------------------------------------------------------*/ + + j = 0; + move16(); + Ltmp_max = L_deposit_l(0); + FOR (i = 0; i < MBANDS_GN_LD; i++) + { + Ltmp = L_deposit_l(0); + max_val = L_deposit_l(0); + + FOR( k=j; k < mfreq_bindiv_LD[i]+j; k++ ) + { + /*m_ave += lf_E[k];*/ +#ifdef BASOP_NOGLOB + Ltmp = L_add_o(lf_E[k], Ltmp, &Overflow); +#else + Ltmp = L_add(lf_E[k], Ltmp); +#endif + max_val = L_max(max_val, lf_E[k]); + } + Ltmp_max = L_max(Ltmp_max, max_val); + /*m_ave -= max_val;*/ + Ltmp = L_sub(Ltmp, max_val); + /*m_ave /=(mfreq_bindiv_LD[i]-1);*/ + m_ave = Mult_32_16(Ltmp,inv_mfreq_bindiv_LD_M1_fx[i]); + + /*bckr[i] = m_ave*sc_qnoise[i];*/ + hMusicPF->LDm_bckr_noise_fx[i] = Mult_32_16(m_ave,sc_qnoise_fx[i]); + move32(); + + j+=mfreq_bindiv_LD[i]; + } + + /* This is computed inside the loop i = maximum(lf_E, DCT_L_POST, &m_ave);*/ + /*------------------------------------------------------------------------* + * - Normalisation of the energy vector between [0.72, 5], with the form of pow(x,4) + * - Simple LP filtering along the frequency domain + * - LT averaging with the past and in function of the stability factor + *------------------------------------------------------------------------*/ + /*m_ave = ALPH/lf_E[i];*/ + exp1 = norm_l(Ltmp_max); + mant = extract_h(L_shl(Ltmp_max, exp1)); + /*exp1 = sub(16,exp1);*/ + + s_ave = div_s(16384, mant); + exp1 = sub(14/*+15*/+16, exp1); /*s_ave in Q15 + exp1*/ + old_tmp16 = norm_lfe(lf_E[0], s_ave, exp1); + old_tmp16 = s_min(old_tmp16, MAXX_Q12_FX); + tmp16 = norm_lfe(lf_E[1], s_ave, exp1); + tmp16 = s_min(tmp16, MAXX_Q12_FX); + old_tmp16_1 = tmp16; + move16(); + tmp_lfE[0] = round_fx(L_mac(L_mult(16384, old_tmp16), 16384, tmp16)); + + FOR(i = 1; i < DCT_L_POST-1; i++) + { + /*tmp_lfE[i] = 0.333f*old_ftmp + 0.333f*ftmp; */ + Ltmp = L_mac(L_mult(10813, old_tmp16), 10813, old_tmp16_1); + + old_tmp16 = old_tmp16_1; + move16(); + tmp16 = norm_lfe(lf_E[i+1], s_ave, exp1); + /*ftmp = min(ftmp, MAXX); + tmp_lfE[i] += 0.333f*ftmp; */ + old_tmp16_1 = s_min(tmp16, MAXX_Q12_FX); + Ltmp = L_mac(Ltmp, 10813, old_tmp16_1); + tmp_lfE[i] = round_fx(Ltmp); + } + + tmp16 = norm_lfe(lf_E[i], s_ave, exp1); + /*ftmp = min(ftmp, MAXX); + tmp_lfE[i] = 0.5f*old_ftmp + 0.5f*ftmp;*/ + tmp16 = s_min(tmp16, MAXX_Q12_FX); + tmp_lfE[i] = round_fx(L_mac(L_mult(16384, old_tmp16), 16384, tmp16)); + + FOR(i = 0; i < BIN_4KHZ; i++) + { + /*filt_lfE[i] = tmp_lfE[i]*.05f + .95f*filt_lfE[i] ;*/ + hMusicPF->filt_lfE_fx[i] = round_fx(L_mac(L_mult(tmp_lfE[i],1638), 31130, hMusicPF->filt_lfE_fx[i])) ; + } + + FOR(; i < DCT_L_POST; i++) + { + /*filt_lfE[i] = tmp_lfE[i]*(.15f) + .85f*filt_lfE[i] ;*/ + hMusicPF->filt_lfE_fx[i] = round_fx(L_mac(L_mult(tmp_lfE[i],4915), 27853, hMusicPF->filt_lfE_fx[i])) ; + } + /*------------------------------------------------------------------------* + * - Reduce inter-harmonic noise with SNR based method + * - Second stage of spectral shaping modification based + * on the pow(x,4) energy spectrum + *------------------------------------------------------------------------*/ + + if( EQ_16(coder_type,AUDIO)) + { + MAX_band = 16; + move16(); + } + + Copy(dtc_in, dtc_out, DCT_L_POST); + + spectrum_mod_dct_fx( Qdct, dtc_out, lf_E, hMusicPF->LDm_enh_lf_EO_fx, hMusicPF->LDm_bckr_noise_fx, local_min_gain, hMusicPF->LDm_enh_lp_gbin_fx, music_flag2, min_band, MAX_GN, MAX_band ); + + i = 0; + move16(); + IF( GE_16(music_flag2,1)) + { + FOR(i = 0; i < BIN_1KHZ; i++) + { + tmp16 = s_min(4096, hMusicPF->filt_lfE_fx[i]); + dtc_out[i] = round_fx(L_shl(L_mult(dtc_out[i], tmp16),3)); + } + } + { + IF( GT_16(hMusicPF->last_nonfull_music_fx,40)) + { + max_ovf_2k = 5120; /*1.25 Q12*/ move16(); + max_ovf_4k = 6144; /*1.5 Q12*/ move16(); + max_ovf_6k = 6144; /*1.5 Q12*/ move16(); + + min_g_2k = 0; + move16(); + min_g_4k = 0; + move16(); + min_g_6k = 0; + move16(); + + IF( EQ_16(coder_type,AUDIO )) + { + max_ovf_2k = 4096; /*1.0 Q12*/ move16(); + max_ovf_4k = 4506; /*1.1 Q12*/ move16(); + max_ovf_6k = 5120; /*1.25 Q12*/ move16(); + + min_g_2k = 3072; /*0.75 Q12*/ move16(); + min_g_4k = 2048; /*0.5 Q12*/ move16(); + min_g_6k = 2048; /*0.5 Q12*/ move16(); + + IF( GT_32(core_brate,ACELP_9k60)) + { + max_ovf_4k = 4096; /*1.0 Q12*/ move16(); + max_ovf_6k = 4710; /*1.15 Q12*/ move16(); + + min_g_2k = 3789; /*0.925 Q12*/ move16(); + min_g_4k = 3379; /*0.825 Q12*/ move16(); + min_g_6k = 3072; /*0.75 Q12*/ move16(); + } + } + ELSE IF( GE_32(core_brate,ACELP_12k65)) + { + max_ovf_2k = 4096; /*1.0 Q12*/ move16(); + max_ovf_4k = 5120; /*1.25 Q12*/ move16(); + + IF( GT_32(core_brate,ACELP_15k85)) + { + max_ovf_4k = 4096; /*1.0 Q12*/ move16(); + max_ovf_6k = 5120; /*1.25 Q12*/ move16(); + + min_g_2k = 3072; /*0.75 Q12*/ move16(); + min_g_4k = 2048; /*0.5 Q12*/ move16(); + min_g_6k = 2048; /*0.5 Q12*/ move16(); + } + } + + FOR(; i < BIN_2KHZ; i++) + { + tmp16 = s_min(max_ovf_2k, hMusicPF->filt_lfE_fx[i]); + tmp16 = s_max(min_g_2k, tmp16); + /*DCT_buf[i] *= ftmp;*/ + dtc_out[i] = round_fx(L_shl(L_mult(dtc_out[i], tmp16),3)); + + } + + FOR(; i < BIN_4KHZ; i++) + { + tmp16 = s_min(max_ovf_4k, hMusicPF->filt_lfE_fx[i]); + tmp16 = s_max(min_g_4k, tmp16); + /*DCT_buf[i] *= ftmp;*/ + dtc_out[i] = round_fx(L_shl(L_mult(dtc_out[i], tmp16),3)); + } + + test(); + IF( NE_16(coder_type,AUDIO)||GT_32(core_brate,ACELP_8k85)) + { + /* Do not modify HF when coded with GSC at LR, because the spectrum is just noise */ + FOR(; i < DCT_L_POST; i++) + { + tmp16 = s_min(max_ovf_6k, hMusicPF->filt_lfE_fx[i]); + tmp16 = s_max(min_g_6k, tmp16); + /*DCT_buf[i] *= ftmp;*/ + dtc_out[i] = round_fx(L_shl(L_mult(dtc_out[i], tmp16),3)); + } + } + } + ELSE IF( GT_16(hMusicPF->last_nonfull_music_fx,25)) + { + /* When unsure on content type only slight clean-up allowed, no overshoot allowed */ + FOR(; i < DCT_L_POST; i++) + { + tmp16 = s_min(4096, hMusicPF->filt_lfE_fx[i]); + /*DCT_buf[i] *= ftmp;*/ + dtc_out[i] = round_fx(L_shl(L_mult(dtc_out[i], tmp16),3)); + } + } + } +} + +/*---------------------------------------------------------------------------* + * spectrum_mod_dct() + * + * spectrum enhancement according to the output of signal_type_clas() + *---------------------------------------------------------------------------*/ + +static void spectrum_mod_dct_fx( + const Word16 Qdct, /* i : scaling factor Q0 */ + Word16 data[], /* i/o: dct spectrum */ + const Word32 lf_E[], /* i: per bin E for first 46 bins (without DC) 2*Qdct+10 */ + Word32 lf_EO[], /* i/o: old per bin E for previous half frame 2*Qdct+10 */ + const Word32 noiseE[], /* i: per band background noise energy estimate 2*Qdct+10 */ + const Word16 minGain, /* i: minimum suppression gain Q15 */ + Word16 lp_gbin[], /* i/o: Smoothed suppression gain, per FFT bin Q14*/ + const Word16 music_flag, /* i: music ? 1:0 */ + Word16 min_band, /* i : minimum band */ + const Word16 MAX_GN, /* i : Maximum gain overshoot */ + const Word16 MAX_band /* i : minimum band */ +) +{ + Word32 maxNoise; + Word32 binE[VOIC_BINS_HR], Lgain; + Word16 gain = 0, minE; + Word16 freq, slope, m_invno[MBANDS_GN_LD],e_invno[MBANDS_GN_LD]; + Word16 *pt_gbin, alpha, tmpN; + Word16 i; + Word32 Ltmp; + Word16 scaling; + Word16 tmp_snr; + Word16 *pt; + Word16 wtmp; + Word16 e_tmp; + Word16 m_binE, e_binE; + Word16 e_gain; + Word16 sqrt_gain; + Word32 Lshift; + Word32 dot5_scaled; + const Word32 *Lpt2; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + + + gain = 0; + move16(); + + /*-----------------------------------------------------------------* + * Compute the inverse of noise + *-----------------------------------------------------------------*/ + + scaling = add(shl(Qdct,1),10); + dot5_scaled = L_shl(1, sub(scaling,1)); + FOR ( i=0; i<=MBANDS_GN_LD-1; i++) + { + /*inv_noise[i] = 1.0f / noiseE[i];*/ + IF (noiseE[i] != 0) + { + e_invno[i] = norm_l(noiseE[i]); + move16(); + m_invno[i] = extract_h(L_shl(noiseE[i],e_invno[i])); + e_invno[i] = sub(14, e_invno[i]); + move16(); + m_invno[i] = div_s(16384, m_invno[i]); + move16(); + } + ELSE + { + /* noiseE[i] == 0 only if Q_new <0*/ + e_invno[i] = add(-16,Qdct); + move16(); + m_invno[i] = MAX_16; + move16(); + } + } + /*----------------------------------------------------------------------* + * Perform noise reduction for 1 frames + *----------------------------------------------------------------------*/ + FOR (i=0 ; i < VOIC_BINS_HR ; i++) + { + /*binE[i] = (float)(0.3 * lf_EO[i] + 0.7 * lf_E[i]);*/ + Ltmp = Mult_32_16(lf_EO[i], 9830); + binE[i] = Madd_32_16(Ltmp, lf_E[i], 22938); + move32(); + } + Copy32( lf_E, lf_EO, VOIC_BINS_HR ); /* update */ + /*----------------------------------------------------------------------* + * Find the maximum noise in a critical band + *----------------------------------------------------------------------*/ + + maxNoise = L_max(noiseE[0], noiseE[1]); + FOR (i=2; i<=MBANDS_GN_LD-1; i++) + { + maxNoise = L_max(maxNoise, noiseE[i]); + } + + /* pointer initialization */ + pt = &data[0]; + + /*-----------------------------------------------------------------* + * Initialization for active speech frames or VAD hangover frames, + * (exclude Clean speech) + *-----------------------------------------------------------------*/ + + IF ( music_flag != 0 ) /* prevent subtraction on clean speech */ + { +#ifdef BASOP_NOGLOB + IF(LE_32(maxNoise, L_shl_o(10, scaling, &Overflow))) +#else + IF( LE_32(maxNoise, L_shl(10, scaling))) +#endif + { + minE = 18432/2; /*Q14*/ move16(); + } + ELSE + { + minE = shr(mult_r(minGain, minGain),1); /*Q14*/ + } + + Lpt2 = binE; + freq = 0; + move16(); + + pt_gbin = lp_gbin; + FOR (i=0; i < min_band; i++) + { + + FOR (; freq <= mfreq_loc_LD_fx[i]; freq += BIN_16kdct_fx) + { + Lpt2++; + /* Lgain is already saturate if it's > 1*/ + pt++; + *pt_gbin = 16384; + move16(); + pt_gbin++; + } + } + /*-----------------------------------------------------------------* + * Per Frequency BIN processing + * For highly voiced and highly pitched speech, use per bin + * subtraction in low frequencies (maximum up to 3700 Hz, + * first 17 critical bands) + *-----------------------------------------------------------------*/ + + FOR (; i < MAX_band; i++) + { + + /*tmp = INV_MAX_SNR_tab[i]; + slope = tmp - tmp * minE; + shift = MAX_SNR_SNR1_tab[i] * minE - tmp;*/ + + /*tmp = 1.0f/ (MAX_SNR1 - 1.0f);*/ + tmp_snr = INV_MAX_SNR_tab_FX[i]; + move16(); + /*slope = -tmp * minE + tmp;*/ + Ltmp = L_mult(tmp_snr, 16384); + slope = msu_r(Ltmp,tmp_snr, minE); /*Q14*/ + + /*shift = MAX_SNR1 * tmp * minE - tmp;*/ + Ltmp = L_mult(MAX_SNR_SNR1_tab_FX[i], minE); /*Q14*Q14*/ + Lshift = L_msu(Ltmp, tmp_snr,8192); /*Q15*Q13+Q29*/ + Lshift = L_shl(Lshift,1); /*Q29 -> Q30*/ + + /*tmpN = slope * inv_noise[i];*/ + tmpN = mult(slope, m_invno[i]); + e_tmp = e_invno[i]; + move16(); + + /*while (freq <= mfreq_loc_LD[i])*/ + FOR (; freq <= mfreq_loc_LD_fx[i]; freq += BIN_16kdct_fx) + { + /*gain = 1.0f;*/ + Lgain = L_deposit_h(16384); + /*if (noiseE[i] >= 0.5f)*/ + IF (GT_32(noiseE[i], dot5_scaled))/* Do not alter if noise E very low */ + { + /*gain = tmpN * *pt2 + shift;*/ /* limits: [x,y] = {[1, minE], [MAX_SNR1, 1]}, */ + e_binE = norm_l(*Lpt2); + m_binE = extract_h(L_shl(*Lpt2, e_binE)); + + e_binE = sub(e_binE,0); /* lf_e divided by 4 in anal_sp*/ + + Ltmp = L_mult(tmpN, m_binE); + e_binE = sub(add(e_tmp, e_binE),15); +#ifdef BASOP_NOGLOB + Ltmp = L_shr_o(Ltmp, e_binE, &Overflow); + Lgain = L_add_o(Ltmp, Lshift, &Overflow); /*Saturation can occure here result in Q30*/ +#else + Ltmp = L_shr(Ltmp, e_binE); + Lgain = L_add(Ltmp, Lshift); /*Saturation can occure here result in Q30*/ +#endif + + } + + Lpt2++; +#ifdef BASOP_NOGLOB + gain = round_fx_o(Lgain, &Overflow); /*gain in Q30-16 = Q14*/ +#else + gain = round_fx(Lgain); /*gain in Q30-16 = Q14*/ +#endif + /*if (gain < minE)gain = minE;*/ + gain = s_max(gain,minE); + /*if (gain > 1.0f+MAX_GN)gain = 1.0f+MAX_GN;*/ + gain = s_min(gain,add(16384, MAX_GN)); + + /* prepare gain to find sqrt */ + e_gain = norm_s(gain); + Ltmp = L_shl(gain, add(16,e_gain)); + e_gain = negate(sub(e_gain,1)); + + Ltmp = Isqrt_lc(Ltmp, &e_gain); + wtmp = extract_h(Ltmp); + sqrt_gain = div_s(16384,wtmp); + + + /* the gain smoothing control: stronger lp filtering for lower gains */ + /*alpha = 1.0f - (float)sqrt(gain);*/ + /* keep gain in Q14*/ + sqrt_gain = shr(sqrt_gain, e_gain); + /*alpha = 1.0f - gain;*/ /* the gain smoothing control: stronger LP filtering for lower gains */ + alpha = shl(sub(16384, sqrt_gain),1); + + /**pt_gbin = gain + alpha * *pt_gbin;*/ + Ltmp = L_mult(gain, 32767); + *pt_gbin = round_fx(L_mac(Ltmp, alpha, *pt_gbin)); /*Q14*/ + /**pt++ *= *pt_gbin;*/ + *pt = round_fx(L_shl(L_mult(*pt, *pt_gbin),1)); + pt++; + pt_gbin++; + } + } + } + ELSE + { + freq = BIN_16kdct_fx; + move16(); + pt_gbin = lp_gbin; + move16(); + FOR (i=0; i < MBANDS_GN_LD; i++) + { + FOR (; freq <= mfreq_loc_LD[i]; freq += BIN_16kdct_fx) + { + /**pt_gbin = 0.9f* *pt_gbin + 0.1f;*/ + *pt_gbin = round_fx(L_mac(L_mult(29491, *pt_gbin), 32767, 1638)); + pt_gbin++; + } + } + } + + return; + +} + + +/*----------------------------------------------------------------------------------* + * analy_sp_dct() + * + * Spectral analysis of the current synthesized frame + *----------------------------------------------------------------------------------*/ + +static void analy_sp_dct_fx( + const Word16 *dct_buf, /* i input dct spectrum */ + Word32 *fr_bands, /* o: energy in critical frequency bands 2*Qdct+10 */ + Word32 *lf_E, /* o: per bin E for first... 2*Qdct+10 */ + Word16 *etot, /* o: total input energy Q8 */ + const Word16 Qdct /* i: Scaling of dct */ +) +{ + Word32 Letot = 0; + Word16 exp_etot, frac_etot; + + Letot = L_deposit_l(0); + /*-----------------------------------------------------------------* + * find energy per critical frequency band and total energy in dB + *-----------------------------------------------------------------*/ + find_enr_dct_fx(dct_buf, fr_bands, lf_E, &Letot, 0, MBANDS_GN_LD, Qdct, BIN_16kdct_fx ); + + /* find average log total energy over both half-frames */ + /**etot = 10.0f * (float)log10(*etot) - 3.0103f;*/ + exp_etot = norm_l(Letot); + frac_etot = Log2_norm_lc(L_shl(Letot, exp_etot)); + exp_etot = sub(30, exp_etot); + exp_etot = sub(exp_etot, add(shl(Qdct,1),10+1)); /* +(1) */ + Letot = Mpy_32_16(exp_etot, frac_etot, LG10); + /* Q8 Averaged the total energy over both half-frames in log10 */ + *etot = extract_l(L_shr(Letot, 14-8)); + + return; +} + +/*------------------------------------------------------------------------* + * find_enr_dct) + * + * find input signal energy for each critical band and first 74 LF bins + * The energy is normalized by the number of frequency bins in a channel + *------------------------------------------------------------------------*/ + +static void find_enr_dct_fx( + const Word16 data[], /* i : dct result, for the format Qdct*/ + Word32 band[], /* o : per band energy 2*Qdct+10*/ + Word32 *ptE, /* o : per bin energy for low frequencies 2*Qdct+10*/ + Word32 *Etot, /* o : total energy 2*Qdct+10*/ + const Word16 min_band, /* i : minimum critical band Q0 */ + const Word16 max_band, /* i : maximum critical band Q0 */ + const Word16 Q_dct, /* i : scaling factor Q0 */ + const Word16 bin_freq /* i : Number of frequency bins Q0 */ +) +{ + Word16 i; + Word16 freq; + const Word16 *ptR; + Word32 LE_min, Ltmp, Ltmp1; + + + LE_min = L_max(L_shl(E_MIN_Q15, sub(shl(Q_dct,1)+10,22)),1); + + ptR = &data[0]; /* pointer to first real coefficient */ + freq = 0; + move16(); + FOR( i=0; i < max_band; i++ ) + { + band[i] = 0; + move16(); + Ltmp1 = L_deposit_l(0); + FOR(; freq <= mfreq_loc_LD_fx[i]; freq += bin_freq) + { + /* energy */ + /**ptE = *ptR * *ptR; */ +#ifdef BASOP_NOGLOB + Ltmp = L_mult_sat(*ptR, *ptR); +#else + Ltmp = L_mult(*ptR, *ptR); +#endif + /* normalization */ + /**ptE *= 1.0f / (DCT_L_POST);*/ + Ltmp = Mult_32_16(Ltmp, 26214); /*26214 = 1.0/640 ->Q15+9 --> 2*Q_dct + 9*/ + Ltmp = L_max(Ltmp, LE_min); + *ptE = Ltmp; + move32(); + + /*band[i] += *ptE++;*/ +#ifdef BASOP_NOGLOB + Ltmp1 = L_add_sat(Ltmp, Ltmp1); +#else + Ltmp1 = L_add(Ltmp, Ltmp1); +#endif + + ptE++; + ptR++; + } + + /* normalization per frequency bin */ + /*band[i] /= cnt;*/ + band[i] = L_max(Mult_32_16(Ltmp1, inv_mfreq_bindiv_LD_fx[i]), LE_min); + move32(); /* 2*Q_dct + 9*/ + + } + + /*-----------------------------------------------------------------* + * Find the total energy over the input bandwidth + *-----------------------------------------------------------------*/ + + Ltmp = 0; + move16(); + FOR( i = min_band; i <= NB_LIMIT_BAND; i++ ) + { + /* total channel energy */ + Ltmp = L_add(band[i],Ltmp); + } + + *Etot = Ltmp; + move32(); + + return; +} + +/*------------------------------------------------------------------------* + * Prep_music_postP() + * + * Performs the steps needed to do the music post processing + *------------------------------------------------------------------------*/ + +void Prep_music_postP_fx( + Word16 exc_buffer_in[], /* i/o: excitation buffer Q_exc*/ + Word16 dct_buffer_out[], /* o : DCT output buffer (qdct)*/ + Word16 filt_lfE[], /* i/o: long term spectrum energy Q15?*/ + const Word16 last_core, /* i : last core */ + const Word16 *pitch_buf, /* i : current frame pitch information Q6*/ + Word16 *LDm_enh_lp_gbin, /* o : smoothed suppression gain, per dct bin Q14*/ + const Word16 Q_exc, /* i : excitation scaling */ + Word16 *qdct /* o : Scaling factor of dct coefficient */ +) +{ + Word16 i; + Word16 *pt1; + const Word16 *pt2; + Word16 s_pit, fr_pit; + + Word16 exc16[DCT_L_POST]; + Word16 *pt1_out; + + s_pit = shr(pitch_buf[3],6); + fr_pit = shr(sub(pitch_buf[3], shl(s_pit,6)),4); /* Find fractional part */ + + /*------------------------------------------------------------* + * Resetting some memories in case of switching + *------------------------------------------------------------*/ +#ifdef _DIFF_FLOAT_FIX_ + IF( EQ_16(last_core,HQ_CORE) || EQ_16(last_core, TCX_20_CORE) || EQ_16(last_core, TCX_10_CORE) ) +#else + IF(EQ_16(last_core, HQ_CORE)) +#endif + { + set16_fx( filt_lfE, 4096, DCT_L_POST ); + set16_fx( LDm_enh_lp_gbin, 16384, VOIC_BINS_HR ); + pt1 = exc_buffer_in + OFFSET2 - 1; + pt2 = pt1 + shr_r(pitch_buf[0],6); + FOR( i = 0; i < OFFSET2; i++ ) + { + *pt1 = *pt2; + move16(); + pt1--; + pt2--; + } + } + + /*------------------------------------------------------------* + * Extrapolation of the last future part and windowing + *------------------------------------------------------------*/ + pt1 = exc_buffer_in + DCT_L_POST - OFFSET2; + pred_lt4(pt1, pt1, s_pit, fr_pit, OFFSET2, pitch_inter4_2, L_INTERPOL2, PIT_UP_SAMP); + /*------------------------------------------------------------* + * windowing right side + *------------------------------------------------------------*/ + pt2 = post_dct_wind_fx; + pt1_out = exc16 + DCT_L_POST - OFFSET2; + FOR( i = 0; i < OFFSET2; i++ ) + { + *pt1_out = mult_r(*pt1,*pt2); + move16(); + pt1++; + pt2++; + pt1_out++; + } + /*------------------------------------------------------------* + * windowing left side + *------------------------------------------------------------*/ + pt1 = exc_buffer_in; + pt1_out = exc16; + pt2--; + FOR( i = 0; i < OFFSET2; i++ ) + { + *pt1_out = mult_r(*pt1,*pt2); + move16(); + pt1++; + pt1_out++; + pt2--; + } + /*------------------------------------------------------------* + * Copy remaining data (Flat part) + *------------------------------------------------------------*/ + + FOR(; i < L_FRAME+OFFSET2; i++ ) + { + *pt1_out = *pt1; + move16(); + pt1++; + pt1_out++; + } + /*------------------------------------------------------------* + * EDCT and back to 16 bits + *------------------------------------------------------------*/ + + edct_16fx(exc16, dct_buffer_out, DCT_L_POST, 6, EVS_MONO); + *qdct = Q_exc; + move16(); + + return; +} +/*------------------------------------------------------------------------* + * norm_lfe() + * + * Energy bins normalisation + *------------------------------------------------------------------------*/ +static Word16 norm_lfe( + const Word32 Lfe, /* i: energy bin to normalize 2*Qdct+10 */ + const Word16 m_norm, /* i: Normalisation factor Q e_norm */ + const Word16 e_norm /* i: Exponent of the normalisation factor */ +) +{ + Word32 Ltmp; + Word16 exp2, tmp16, exp3 ; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + + + Ltmp = Mult_32_16(Lfe, m_norm); + Ltmp = L_add(Ltmp, L_shl(BET_Q15_FX, sub(e_norm,15))); /* Ltmp -> e_norm*/ + exp2 = norm_l(Ltmp); + tmp16 = extract_h(L_shl(Ltmp,exp2)); /* exp2 -= 16 */ + exp2 = add(e_norm,exp2); + + tmp16 = mult_r(tmp16,tmp16); /* tmp16 in Q exp2 */ + tmp16 = mult_r(tmp16,tmp16); + tmp16 = mult_r(tmp16,tmp16); + + exp3 = sub(12+16, exp2); /* tmp16 in Q exp2 */ + if(NE_16(exp2,31)) + { + exp3 = sub(exp2, 12+16-3); /* if exp2 < 31, means that tmp >= 1.0 */ + /* Need to shl by 3 to take into account the 3 multiplications */ + } +#ifdef BASOP_NOGLOB + tmp16 = shl_o(tmp16, exp3, &Overflow); /* Result in Q12 */ +#else + tmp16 = shl(tmp16, exp3); /* Result in Q12 */ +#endif + + return tmp16; +} + +/*------------------------------------------------------------------------* + * Post_music_postP() + * + * Going back from frequency to time domain from the enhanced spectrum. + * Retreive the aligned excitation and redo the synthesis + *------------------------------------------------------------------------*/ + +void Post_music_postP_fx( + Word16 dct_buffer_in[], /* i/o: excitation buffer */ + Word16 *exc2, /* i/o: Current excitation to be overwriten */ + const Word16 *mem_tmp, /* i : previous frame synthesis memory */ + Word16 *st_mem_syn2, /* i/o: current frame synthesis memory */ + const Word16 *Aq, /* i : LPC filter coefficients */ + Word16 *syn, /* i/o: 12k8 synthesis */ + Word16 *Q_exc, /* i : excitation scaling */ + Word16 *prev_Q_syn, /* i : previsous frame synthesis scaling */ + Word16 *Q_syn, /* i : Current frame synthesis scaling */ + Word16 *mem_syn_clas_estim_fx, /* i : old 12k8 synthesis used for frame classification*/ + const Word16 IsIO, /* i: Flag to indicate IO mode */ + Word16 *mem_deemph, /* i/o: speech deemph filter memory */ + Word16 *st_pst_old_syn_fx, /* i/o: psfiler */ + Word16 *st_pst_mem_deemp_err_fx, /* i/o: psfiler */ + Word16 *mem_agc, + PFSTAT *pf_stat, /* i/o: All memories related to NB post filter */ + const Word16 *tmp_buffer /* tmp_buffer in Q-1 */ + ,Word16 *mem_tmp2 /* Temporary memory used with scale_syn */ +) +{ + Word16 exc16[DCT_L_POST]; + + /*------------------------------------------------------------------------* + * Go back to time domain + *------------------------------------------------------------------------*/ + + edct_16fx( dct_buffer_in, exc16, DCT_L_POST, 6, EVS_MONO); + + Copy( exc16 + OFFSET2, exc2, L_FRAME); + + Copy( mem_tmp, st_mem_syn2, M ); + + /*------------------------------------------------------------------------* + * Perform the synthesis filtering using the enhanced excitation + *------------------------------------------------------------------------*/ + IF(IsIO == 0) /* Rescaling already done in IO mode */ + { + Rescale_mem(*Q_exc, prev_Q_syn, Q_syn, st_mem_syn2,mem_syn_clas_estim_fx, 4, + mem_deemph, st_pst_old_syn_fx, st_pst_mem_deemp_err_fx, mem_agc, + pf_stat, 1, 0, tmp_buffer); + Copy( st_mem_syn2, mem_tmp2, M ); + } + + syn_12k8_fx( L_FRAME, Aq, exc2, syn, st_mem_syn2, 1 , *Q_exc, *Q_syn); + + return; +} + + +/*-------------------------------------------------------------------* + * music_postfilt_init() + * + * Initialize LD music postfilter state structure + *-------------------------------------------------------------------*/ +void music_postfilt_init( + MUSIC_POSTFILT_HANDLE hMusicPF /* i/o: LD music postfilter handle */ +) +{ + Word16 i, e_db, f_db; + Word32 L_tmp; + + set16_fx(hMusicPF->dct_post_old_exc_fx, 0, DCT_L_POST - OFFSET2); + /*st->LDm_enh_min_ns_gain = (float)pow(10.0f, -12/20.0f);*/ + L_tmp = L_mult(((-12 * 256)), 5443); /* *0.166096 in Q15 -> Q24 */ + L_tmp = L_shr(L_tmp, 8); /* From Q24 to Q16 */ + f_db = L_Extract_lc(L_tmp, &e_db); /* Extract exponent */ + f_db = extract_l(Pow2(14, f_db)); /* Put 14 as exponent so that */ + e_db = add(e_db, 15 - 14); + f_db = add(f_db, shr(1, add(e_db, 1))); + hMusicPF->LDm_enh_min_ns_gain_fx = shl(f_db, e_db); + + hMusicPF->LDm_last_music_flag_fx = 0; + move16(); + set16_fx(hMusicPF->LDm_lt_diff_etot_fx, 0, MAX_LT); + + hMusicPF->LDm_thres_fx[0] = TH_0_MIN_FX; + move16(); + hMusicPF->LDm_thres_fx[1] = TH_1_MIN_FX; + move16(); + hMusicPF->LDm_thres_fx[2] = TH_2_MIN_FX; + move16(); + hMusicPF->LDm_thres_fx[3] = TH_3_MIN_FX; + move16(); + + hMusicPF->LDm_nb_thr_1_fx = 0; + move16(); + hMusicPF->LDm_nb_thr_3_fx = 0; + move16(); + hMusicPF->LDm_mem_etot_fx = 0; + move16(); + + FOR(i = 0; i < VOIC_BINS_HR; i++) + { + hMusicPF->LDm_enh_lp_gbin_fx[i] = 16384; + move16(); + hMusicPF->LDm_enh_lf_EO_fx[i] = 328; + move16(); + } + + FOR(i = 0; i < MBANDS_GN_LD; i++) + { + hMusicPF->LDm_bckr_noise_fx[i] = E_MIN_Q15; + move16(); + } + set16_fx(hMusicPF->filt_lfE_fx, 4096, DCT_L_POST); + move16(); + hMusicPF->last_nonfull_music_fx = 0; + move16(); + hMusicPF->Old_ener_Q = 0; + move16(); + + return; +} diff --git a/lib_dec/TonalComponentDetection.c b/lib_dec/TonalComponentDetection.c index 8955abd7a284a509082263187666d869c8fd34d2..d86ff070c7e8e24f3e36c0ae2a14489247453afb 100644 --- a/lib_dec/TonalComponentDetection.c +++ b/lib_dec/TonalComponentDetection.c @@ -59,7 +59,7 @@ static void findTonalComponents( uint16_t *indexOfTonalPeak, uint16_t *lowerInde /*-------------------------------------------------------------------* - * DetectTonalComponents() + * DetectTonalComponents_flt() * * Detect tonal components in the lastMDCTSpectrum, use * secondLastPowerSpectrum for the precise location of the peaks and @@ -67,7 +67,7 @@ static void findTonalComponents( uint16_t *indexOfTonalPeak, uint16_t *lowerInde * pNumIndexes accordingly. *-------------------------------------------------------------------*/ -void DetectTonalComponents( +void DetectTonalComponents_flt( uint16_t indexOfTonalPeak[], uint16_t lowerIndex[], uint16_t upperIndex[], @@ -92,7 +92,7 @@ void DetectTonalComponents( if ( psychParamsCurrent == NULL ) { nBands = FDNS_NPTS; - mdct_noiseShaping( pScaledMdctSpectrum, nSamplesCore, scaleFactors, nBands ); + mdct_noiseShaping_flt( pScaledMdctSpectrum, nSamplesCore, scaleFactors, nBands ); } else { @@ -116,7 +116,7 @@ void DetectTonalComponents( /*-------------------------------------------------------------------* - * RefineTonalComponents() + * RefineTonalComponents_flt() * *-------------------------------------------------------------------*/ @@ -126,7 +126,7 @@ void DetectTonalComponents( * then keep in indexOfTonalPeak only the tonal components that are * again detected Updates indexOfTonalPeak, lowerIndex, upperIndex, * phaseDiff, phases, pNumIndexes accordingly. */ -void RefineTonalComponents( +void RefineTonalComponents_flt( uint16_t indexOfTonalPeak[], uint16_t lowerIndex[], uint16_t upperIndex[], @@ -150,7 +150,7 @@ void RefineTonalComponents( uint16_t iNew, iOld, j; float *pOldPhase, *pNewPhase; - DetectTonalComponents( newIndexOfTonalPeak, newLowerIndex, newUpperIndex, &newNumIndexes, lastPitchLag, currentPitchLag, lastMDCTSpectrum, scaleFactors, secondLastPowerSpectrum, + DetectTonalComponents_flt( newIndexOfTonalPeak, newLowerIndex, newUpperIndex, &newNumIndexes, lastPitchLag, currentPitchLag, lastMDCTSpectrum, scaleFactors, secondLastPowerSpectrum, nSamples, nSamplesCore, floorPowerSpectrum, psychParamsCurrent ); nPreservedPeaks = 0; diff --git a/lib_dec/TonalComponentDetection_fx.c b/lib_dec/TonalComponentDetection_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..ccc1421d6707f9bd56c2e2d8bbadde566d5cb41f --- /dev/null +++ b/lib_dec/TonalComponentDetection_fx.c @@ -0,0 +1,1045 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#define _USE_MATH_DEFINES + +#include +#include +#include "options.h" +#include "prot_fx1.h" +#include "prot_fx2.h" +#include "cnst.h" +#include "rom_basop_util.h" +#include "rom_com.h" +#include "basop_util.h" + +/*---------------------------------------------------------------------* + * Local function prototypes + *---------------------------------------------------------------------*/ +static void calcPseudoSpec(const Word32 * mdctSpec, const Word16 mdctSpec_exp, const Word16 nSamples, Word16 floorPowerSpectrum, Word32 * powerSpec, Word16 * powerSpec_exp); +static void getEnvelope(const Word16 nSamples, const Word32 * powerSpec, Word16 F0, Word32 * envelope, Word32 * smoothedSpectrum); +static void GetF0(Word16 const nSamples,Word16 const nSamplesCore,Word32 const * const powerSpectrum, Word32 const pitchLag, Word16 * const pOrigF0, Word16 * const pF0); +static void findStrongestHarmonics(const Word16 nSamples, const Word32 * powerSpectrum, const Word16 F0, const Word16 nTotalHarmonics, Word16 * pHarmonicIndexes, Word16 * pnHarmonics); +static void CorrectF0(const Word16 * pHarmonicIndexes, const Word16 nHarmonics, Word16 * pF0); +static void findCandidates(const Word16 nSamples, const Word32 * MDCTSpectrum, const Word16 MDCTSpectrum_exp, Word16 * thresholdModificationNew, Word16 floorPowerSpectrum ); +static void modifyThreshold(Word16 i, Word16 F0, Word16 threshold, Word16 * thresholdModification); +static void modifyThresholds(Word16 F0, Word16 origF0, Word16 * thresholdModification); +static void RefineThresholdsUsingPitch(const Word16 nSamples, const Word16 nSamplesCore, const Word32 powerSpectrum[], const Word32 lastPitchLag, const Word32 currentPitchLag, Word16 * pF0, Word16 * thresholdModification); +static void findTonalComponents(Word16 * indexOfTonalPeak, Word16 * lowerIndex, Word16 * upperIndex, Word16 *numIndexes, Word16 nSamples, const Word32 * powerSpectrum, Word16 F0, Word16 * thresholdModification); + +/*-------------------------------------------------------------------* + * DetectTonalComponents() + * + * Detect tonal components in the lastMDCTSpectrum, use + * secondLastPowerSpectrum for the precise location of the peaks and + * store them in indexOfTonalPeak. Updates lowerIndex, upperIndex, + * pNumIndexes accordingly. + *-------------------------------------------------------------------*/ +void DetectTonalComponents( + Word16 indexOfTonalPeak[], + Word16 lowerIndex[], + Word16 upperIndex[], + Word16* pNumIndexes, + const Word32 lastPitchLag, + const Word32 currentPitchLag, + const Word16 lastMDCTSpectrum[], + const Word16 lastMDCTSpectrum_exp, + const Word16 scaleFactors[], + const Word16 scaleFactors_exp[], + const Word16 scaleFactors_max_e, + const Word32 secondLastPowerSpectrum[], + const Word16 nSamples, + const Word16 nSamplesCore, + Word16 floorPowerSpectrum /* i: lower limit for power spectrum bins */ +#ifdef IVAS_CODE_MDCT_GSHAPE + , const PsychoacousticParameters* psychParamsCurrent +#endif +) +{ + Word16 F0; + Word16 thresholdModification[L_FRAME_MAX], lastMDCTSpect_exp; + Word32 pScaledMdctSpectrum[L_FRAME_MAX]; +#ifdef IVAS_CODE_MDCT_GSHAPE + Word16 nBands; + IF (psychParamsCurrent == NULL) + { + nBands = FDNS_NPTS; + PMT("add nBands argument to mdct_shaping_16") +#endif + + mdct_shaping_16(lastMDCTSpectrum, nSamplesCore, nSamples, scaleFactors, scaleFactors_exp, scaleFactors_max_e, pScaledMdctSpectrum); +#ifdef IVAS_CODE_MDCT_GSHAPE + } + ELSE + { + sns_shape_spectrum(pScaledMdctSpectrum, psychParamsCurrent, scaleFactors, nSamplesCore); + nBands = psychParamsCurrent->nBands; + } +#endif + + lastMDCTSpect_exp = add(lastMDCTSpectrum_exp, scaleFactors_max_e); + + /* Find peak candidates in the last frame. */ + findCandidates(nSamples, pScaledMdctSpectrum, lastMDCTSpect_exp, thresholdModification, floorPowerSpectrum); + + /* Refine peak candidates using the pitch information */ + RefineThresholdsUsingPitch(nSamples, nSamplesCore, secondLastPowerSpectrum, lastPitchLag, currentPitchLag, &F0, thresholdModification); + + /* Find peaks in the second last frame */ + findTonalComponents(indexOfTonalPeak, lowerIndex, upperIndex, pNumIndexes, nSamples, secondLastPowerSpectrum, F0, thresholdModification); +} + +/*-------------------------------------------------------------------* + * RefineTonalComponents() + * + *-------------------------------------------------------------------*/ +/* When called, the tonal components are already stored in + * indexOfTonalPeak. Detect tonal components in the lastMDCTSpectrum, + * use secondLastPowerSpectrum for the precise location of the peaks and + * then keep in indexOfTonalPeak only the tonal components that are + * again detected Updates indexOfTonalPeak, lowerIndex, upperIndex, + * phaseDiff, phases, pNumIndexes accordingly. */ +void RefineTonalComponents( + Word16 indexOfTonalPeak[], + Word16 lowerIndex[], + Word16 upperIndex[], + Word16 phaseDiff[], + Word16 phases[], + Word16 * pNumIndexes, + const Word32 lastPitchLag, + const Word32 currentPitchLag, + const Word16 lastMDCTSpectrum[], + const Word16 lastMDCTSpectrum_exp, + const Word16 scaleFactors[], + const Word16 scaleFactors_exp[], + const Word16 scaleFactors_max_e, + const Word32 secondLastPowerSpectrum[], + const Word16 nSamples, + const Word16 nSamplesCore, + const Word16 floorPowerSpectrum /* i: lower limit for power spectrum bins */ +#ifdef IVAS_CODE_MDCT_GSHAPE + ,const PsychoacousticParameters* psychParamsCurrent +#endif +) +{ + Word16 newIndexOfTonalPeak[MAX_NUMBER_OF_IDX]; + Word16 newLowerIndex[MAX_NUMBER_OF_IDX]; + Word16 newUpperIndex[MAX_NUMBER_OF_IDX]; + Word16 newNumIndexes, nPreservedPeaks; + Word16 iNew, iOld, j; + Word16 * pOldPhase, * pNewPhase; + + + DetectTonalComponents(newIndexOfTonalPeak, newLowerIndex, newUpperIndex, &newNumIndexes, lastPitchLag, currentPitchLag, lastMDCTSpectrum, + lastMDCTSpectrum_exp, scaleFactors, scaleFactors_exp, scaleFactors_max_e, secondLastPowerSpectrum, nSamples, nSamplesCore, floorPowerSpectrum +#ifdef IVAS_CODE_MDCT_GSHAPE + , psychParamsCurrent +#endif + ); + + nPreservedPeaks = 0; + move16(); + iNew = 0; + move16(); + pOldPhase = phases; + pNewPhase = phases; + + FOR (iOld = 0; iOld < *pNumIndexes; iOld++) + { + /* We don't want that the old peak index is at the border of the new peak region, that is why >= newUpperIndex and > newLowerIndex */ + test(); + WHILE (LT_16(iNew,newNumIndexes)&&GE_16(indexOfTonalPeak[iOld],newUpperIndex[iNew])) + { + iNew = add(iNew,1); + } + + test(); + IF (LT_16(iNew,newNumIndexes)&>_16(indexOfTonalPeak[iOld],newLowerIndex[iNew])) + { + newIndexOfTonalPeak[nPreservedPeaks] = indexOfTonalPeak[iOld]; + move16(); + newLowerIndex[nPreservedPeaks] = lowerIndex[iOld]; + move16(); + newUpperIndex[nPreservedPeaks] = upperIndex[iOld]; + move16(); + phaseDiff[nPreservedPeaks] = phaseDiff[iOld]; + move16(); + + FOR (j = lowerIndex[iOld]; j <= upperIndex[iOld]; j++) + { + *pNewPhase++ = *pOldPhase++; + move16(); + } + nPreservedPeaks = add(nPreservedPeaks,1); + } + ELSE + { + pOldPhase += sub(upperIndex[iOld],add(lowerIndex[iOld],1)); + } + } + + FOR (iNew = 0; iNew < nPreservedPeaks; iNew++) + { + indexOfTonalPeak[iNew] = newIndexOfTonalPeak[iNew]; + move16(); + lowerIndex[iNew] = newLowerIndex[iNew]; + move16(); + upperIndex[iNew] = newUpperIndex[iNew]; + move16(); + } + *pNumIndexes = nPreservedPeaks; + move16(); + return; +} + +/*-------------------------------------------------------------------* + * Local functions + *-------------------------------------------------------------------*/ +static void calcPseudoSpec( + const Word32 * mdctSpec, /* i: MDCT spectrum */ + const Word16 mdctSpec_exp, /* i: exponent of MDCT spectrum */ + const Word16 nSamples, /* i: frame size */ + Word16 floorPowerSpectrum, /* i: lower limit for power spectrum bins */ + Word32 * powerSpec, /* o: estimated power spectrum */ + Word16 * powerSpec_exp /* o: exponent of estimated power spectrum */ +) +{ + Word16 k; + Word32 x, L_tmp, L_tmp_floor; + Word16 tmp_loop; + + + + *powerSpec_exp = add(add(mdctSpec_exp, mdctSpec_exp), 5); + move16(); + + k = sub(31, *powerSpec_exp); + /* If the signal is bellow floor, special care is needed for *powerSpec_exp */ + IF (LT_16(add(16-3, norm_s(floorPowerSpectrum)), k)) /*extra 3 bits of headroom for MA filter in getEnvelope*/ + { + k = add(16-3, norm_s(floorPowerSpectrum)); /*extra 3 bits of headroom for MA filter in getEnvelope*/ + L_tmp_floor = L_shl(L_deposit_l(floorPowerSpectrum), k); + set32_fx(powerSpec, L_tmp_floor, nSamples); + *powerSpec_exp = sub(31, k); + } + ELSE + { + L_tmp_floor = L_shl(L_deposit_l(floorPowerSpectrum), k); + + tmp_loop = sub(nSamples, 2); + FOR (k = 1; k <= tmp_loop; k++) + { + x = L_sub(L_shr(mdctSpec[k+1], 1),L_shr(mdctSpec[k-1], 1)); /* An MDST estimate */ + + x = L_shr(Mpy_32_32(x, x), 3); + + L_tmp = Mpy_32_32(mdctSpec[k], mdctSpec[k]); + L_tmp = L_shr(L_tmp, 5); + + powerSpec[k] = L_max(L_tmp_floor, L_add(L_tmp, x)); + move32(); + } + } + + powerSpec[0] = L_shr(powerSpec[1], 1); + move32(); + powerSpec[nSamples-1] = L_shr(powerSpec[nSamples-2], 1); + move32(); + return; + +} + +#define LEVEL_EXP 3/*+4*/ +static void getEnvelope( + const Word16 nSamples, /*i: Q0 */ + const Word32* powerSpec, /*i: powerSpec_exp */ + Word16 F0, /*i: 5Q10*/ + Word32 * envelope, /*o: powerSpec_exp + LEVEL_EXP*/ + Word32 * smoothedSpectrum /*o: powerSpec_exp + LEVEL_EXP*/ +) +{ + Word16 nFilterLength, nHalfFilterLength, nSecondHalfFilterLength, n1, n2; + Word16 level, inv_len; + Word16 i; + Word32 sum, tmp; + + IF (F0 == 0) + { + nFilterLength = 15; + move16(); + } + ELSE IF (F0 <= 10240/*10.0f Q10*/) + { + nFilterLength = 11; + move16(); + } + ELSE IF (F0 >= 22528/*22.0f Q10*/) + { + /* For F0 >= 22 peak is isolated well enough with the filter length of 23. + This case is however not triggered due to the limit of pit_min, + but the line is left for security reasons. */ + nFilterLength = 23; + move16(); + } + ELSE + { + nFilterLength = s_or(1, shr(F0,10)); /*1+2*(int)(F0/2); F0->Q10*/ move16(); + } + + nHalfFilterLength = shr(nFilterLength,1); + + n1 = add(nHalfFilterLength,1); + + nSecondHalfFilterLength = sub(nFilterLength,nHalfFilterLength); + + n2 = sub(nSecondHalfFilterLength,1); + + assert((nFilterLength >= 7) && (nFilterLength <= 23) && (nFilterLength %2 == 1)); + + + sum = L_deposit_l(0); + level = 31089/*LEVEL_ABOVE_ENVELOPE Q12*/; /*Q12*/ + + FOR (i = 0; i < n2; i++) + { + sum = L_add(sum, powerSpec[i]); + } + /* No need for PTR_INIT for powerSpec[i+n2] as we continue from the previous loop */ + FOR (i = 0; i < n1; i++) + { +#ifdef BASOP_NOGLOB + sum = L_add_sat(sum, powerSpec[i+n2]); +#else + sum = L_add(sum, powerSpec[i+n2]); +#endif + tmp = Mpy_32_16_1(sum/*Q31,powerSpec_exp*/,level/*Q12*/); /*Q28,powerSpec_exp*/ + envelope[i]/*Q28,powerSpec_exp*/ = Mpy_32_16_1(tmp/*Q28,powerSpec_exp*/, InvIntTable[i+nSecondHalfFilterLength]/*Q15*/); + move32(); + } + + inv_len = mult_r(level, InvIntTable[nFilterLength]); + FOR (i = n1; i < nSamples-n2; i++) + { +#ifdef BASOP_NOGLOB + sum = L_add_sat(sum, L_sub(powerSpec[i+n2],powerSpec[i-n1])); +#else + sum = L_add(sum, L_sub(powerSpec[i+n2],powerSpec[i-n1])); +#endif + envelope[i] = Mpy_32_16_1(sum, inv_len); + move32(); + } + + FOR (i = nSamples-n2; i < nSamples; i++) + { + sum = L_sub(sum, powerSpec[i-n1]); + tmp = Mpy_32_16_1(sum,level); + envelope[i] = Mpy_32_16_1(tmp, InvIntTable[nSamples-(i-nHalfFilterLength)]); + move32(); + } + + FOR (i = 1; i < nSamples-1; i++) + { + smoothedSpectrum[i] = L_add(L_add(Mpy_32_16_1(powerSpec[i-1],3072/*0.75f Q12*/),L_shr(powerSpec[i],LEVEL_EXP)), Mpy_32_16_1(powerSpec[i+1],3072/*0.75f Q12*/)); + } + + move32(); + move32(); + smoothedSpectrum[0] = L_add(Mpy_32_16_1(powerSpec[1],3072/*0.75f Q12*/),L_shr(powerSpec[0],LEVEL_EXP)); + smoothedSpectrum[nSamples-1] = L_add(Mpy_32_16_1(powerSpec[nSamples-2],3072/*0.75f Q12*/),L_shr(powerSpec[nSamples-1],LEVEL_EXP)); + return; + +} + +static void GetF0( + Word16 /*int*/ const nSamples, /*i - Q0 */ + Word16 /*int*/ const nSamplesCore, /*i - Q0 */ + Word32 /*float*/ const * const powerSpectrum, /*i - Qx */ /*is justed handed over and given back*/ + Word32 /*float*/ const pitchLag, /*i - Q16*/ + Word16 /*float*/ * const pOrigF0, /*o - Q10*/ + Word16 /*float*/ * const pF0) /*o - Q10*/ +{ + Word16 /*float*/ tmpPitchLag; + Word16 /*int*/ rgiStrongHarmonics[MAX_PEAKS_FROM_PITCH]; + Word16 /*int*/ nTotalHarmonics, nStrongHarmonics; + Word16 tmp; + + + assert(LAST_HARMONIC_POS_TO_CHECK <= nSamplesCore); + + /* Use only F0 >= 100 Hz */ + test(); + IF ((pitchLag > 0) && (LE_16(round_fx(pitchLag) , shr(nSamplesCore,1)))) + { + + tmpPitchLag /*"halfPitchLag" in FLC - read as Q5 for comparison to halfpitchlag */ + = round_fx(L_shl(pitchLag,4)); /*no division by 2, will be done in following division - + furthermore, do a leftshift before rounding, to preserve more accuracy - + will be accommodated also in following division*/ + + /**pF0 = nSamplesCore/tmpPitchLag;*/ + BASOP_Util_Divide_MantExp(nSamplesCore,0,tmpPitchLag,-(1/*division by 2*/+4/*accommodate accuracy-prevention-leftshift*/),pF0,&tmp); /*pF0 is Q15*/ + move16(); + *pF0 = shr(*pF0,sub(5,tmp)); /*Q10 without scalingfactor*/ + move16(); + *pOrigF0 = *pF0; /*Q10*/ + move16(); + tmp = 2*LAST_HARMONIC_POS_TO_CHECK; + if (LT_16(nSamples , 2*LAST_HARMONIC_POS_TO_CHECK)) + { + move16(); + tmp = nSamples; + } + BASOP_Util_Divide_MantExp(tmp,15,*pF0,5,&nTotalHarmonics,&tmp); + nTotalHarmonics =shl(nTotalHarmonics,sub(tmp,15)); + + + /* Get in rgiStrongHarmonics all i for which i*F0 are the strongest harmonics */ + findStrongestHarmonics(nSamples, powerSpectrum, *pF0, nTotalHarmonics, rgiStrongHarmonics, &nStrongHarmonics); + + CorrectF0(rgiStrongHarmonics, nStrongHarmonics, pF0); + } + ELSE + { + move16(); + move16(); + *pF0 = 0; + *pOrigF0 = 0; + } + return; +} + + +static void findStrongestHarmonics( + const Word16 nSamples, + const Word32 * powerSpectrum, + const Word16 F0/*5Q10*/, + const Word16 nTotalHarmonics, + Word16 * pHarmonicIndexes, + Word16 * pnHarmonics +) +{ + Word32 peaks[MAX_PEAKS_FROM_PITCH], smallestPeak; + Word16 nPeaksToCheck, nPeaks, iSmallestPeak; + Word16 i, l, k; + (void)nSamples; + + + nPeaks = 0; + move16(); + + iSmallestPeak = 0; + move16(); + smallestPeak = 0x7fffffff; + move32(); + + nPeaksToCheck = s_min(nTotalHarmonics, MAX_PEAKS_FROM_PITCH+1); + + FOR (i = 1; i < nPeaksToCheck; i++) + { + Word32 newPeak; + + k = extract_h(L_shl(L_mult(i,F0),5)); /*k = (int)(i*F0);*/ + assert(k > 0 && k < 2*LAST_HARMONIC_POS_TO_CHECK && k < nSamples); + + newPeak = L_add(powerSpectrum[k], 0); + + peaks[nPeaks] = newPeak; + move32(); + pHarmonicIndexes[nPeaks] = i; + move16(); + + IF (LE_32(newPeak,smallestPeak)) + { + iSmallestPeak = nPeaks; + move16(); + smallestPeak = L_add(newPeak, 0); + } + + nPeaks = add(nPeaks,1); + } + + FOR (; i < nTotalHarmonics; i++) + { + Word32 newPeak; + + k = extract_h(L_shl(L_mult(i,F0),5)); + assert(k > 0 && k < 2*LAST_HARMONIC_POS_TO_CHECK && k < nSamples); + + newPeak = L_add(powerSpectrum[k], 0); + + IF (GT_32(newPeak,smallestPeak)) + { + peaks[iSmallestPeak] = newPeak; + move32(); + pHarmonicIndexes[iSmallestPeak] = i; + move16(); + smallestPeak = L_add(newPeak, 0); + + FOR (l = 0; l < MAX_PEAKS_FROM_PITCH; l++) + { + IF (peaks[l] <= smallestPeak) + { + iSmallestPeak = l; + move16(); + smallestPeak = L_add(peaks[l], 0); + } + } + } + } + + sort_fx(pHarmonicIndexes, 0, sub(nPeaks,1)); + + *pnHarmonics = nPeaks; + move16(); + return; +} + +/* Use new F0, for which harmonics are most common in pHarmonicIndexes */ +static void CorrectF0( + const Word16 /*int*/ * pHarmonicIndexes, /*I - Q0 */ + const Word16 /*int*/ nHarmonics, /*I - Q0 */ + Word16 /*float*/ * pF0) /*I/O - Q10 range: {0}, [4..18) */ +{ + Word16 /*int*/ i; + Word16 /*float*/ F0; + Word16 /*int*/ diff[MAX_PEAKS_FROM_PITCH-1], sortedDiff[MAX_PEAKS_FROM_PITCH-1]; + Word16 /*int*/ iMostCommonDiff, nMostCommonDiff, nSameDiff, iMult; + + Word16 tmp; + +#ifdef IVAS_CODE + FOR (i = 0; i < MAX_PEAKS_FROM_PITCH - 1; i++) + { + diff[i] = 0; + sortedDiff[i] = 0; + move16)); + move16)); + } +#endif + F0 = *pF0; + + test(); + IF (F0 > 0 && nHarmonics != 0) + { + tmp = sub(nHarmonics, 1); + FOR (i = 0; i < tmp; i++) + { + diff[i] = sub(pHarmonicIndexes[i+1], pHarmonicIndexes[i]); + move16(); + sortedDiff[i] = diff[i]; + move16(); + } + sort_fx(sortedDiff, 0,sub(nHarmonics, 1+1)); + iMostCommonDiff = sortedDiff[0]; + move16(); + nSameDiff = 1; + move16(); + i = 1; + move16(); + IF (EQ_16(imult1616(sortedDiff[0],pHarmonicIndexes[0]),1)) + { + /* Find how many distances between peaks have length 1 */ + FOR (; i < tmp; i++) + { + if (EQ_16(sortedDiff[i],1)) + { + nSameDiff=add(nSameDiff,1); + } + } + } + nMostCommonDiff = nSameDiff; + move16(); + + /* If there are at least 3 distances between peaks with length 1 and if the 1st harmonic is in pHarmonicIndexes then keep the original F0 */ + /* Otherwise find the most common distance between peaks */ + IF (LT_16(nSameDiff,3)) + { + /* Find the most common difference */ + FOR (i = nSameDiff; i < tmp; i++) + { + IF (EQ_16(sortedDiff[i], sortedDiff[i-1])) + { + nSameDiff=add(nSameDiff,1); + } + ELSE + { + IF (GT_16(nSameDiff, nMostCommonDiff)) + { + nMostCommonDiff = nSameDiff; + move16(); + iMostCommonDiff = sortedDiff[i-1]; + move16(); + } + ELSE { + test(); + IF (EQ_16(nSameDiff, nMostCommonDiff)&&(abs_s(sub(iMostCommonDiff,pHarmonicIndexes[0]))>abs_s(sub(sortedDiff[i-1],pHarmonicIndexes[0])))) + { + nMostCommonDiff = nSameDiff; + move16(); + iMostCommonDiff = sortedDiff[i-1]; + move16(); + } + } + nSameDiff = 1; + move16(); + } + } + IF (GT_16(nSameDiff,nMostCommonDiff)) + { + nMostCommonDiff = nSameDiff; + move16(); + iMostCommonDiff = sortedDiff[nHarmonics-2]; + move16(); + } + } + + /* If there are enough peaks at the same distance */ + IF (GE_16(nMostCommonDiff, MAX_PEAKS_FROM_PITCH/2)) + { + iMult = 1; + move16(); + FOR (i = 0; i < tmp; i++) + { + IF (EQ_16(diff[i], iMostCommonDiff)) + { + iMult = pHarmonicIndexes[i]; + move16(); + BREAK; + } + /* for rare cases of octave mismatch or missing harmonics */ + test(); + test(); + IF (GT_16(sub(nHarmonics,2),i)&&(EQ_16(diff[i],diff[i+1]))&&(EQ_16(add(diff[i],diff[i+1]),iMostCommonDiff))) + { + iMult = pHarmonicIndexes[i]; + move16(); + BREAK; + } + } + + /* If the real F0 is much higher than the original F0 from the pitch */ + + IF (LE_16(iMult, 3)) + { + /* Use iMostCommonDiff, because the lowest pHarmonicIndexes[i] (which is equal to iMult) may not correspond to the new F0, but to it's multiple */ + F0 = round_fx(L_shl(L_mult(iMostCommonDiff /*Q0*/,F0 /*Q10*/),15)); + } + ELSE + { + F0 = 0; + } + } + /* Otherwise if there are at least 3 distances between peaks with length 1 and if the 1st harmonic is in pHarmonicIndexes then keep the original F0 */ + /* Otherwise don't use F0 */ + ELSE + { + test(); + if ((GT_16(iMostCommonDiff,1))||(LT_16(nMostCommonDiff,3))) + { + /* Not enough peaks at the same distance => don't use the pitch. */ + F0 = 0; + move16(); + } + } + *pF0 = F0; + move16(); + } + return; +} + +static void modifyThreshold( + Word16 /*int*/ i, /*I - Q0 */ + Word16 /*float*/ F0, /*I - Q10*/ + Word16 /*float*/ threshold, /*I - Q10*/ + Word16* /*float*/ thresholdModification) /*I/O - Q10*/ +{ + Word32 harmonic; + Word16 fractional /*Q15*/; + Word16 k /*Q0*/; + Word16 twoTimesFract /*Q10*/; + + + + harmonic = L_mult(shl(i,5),F0); /*Q0 * Q10 = 15Q16*/ + k = extract_h(harmonic); /*Q0*/ + fractional = lshr(extract_l(harmonic),1); /* Fractional part of the i*F0 */ /*Q15*/ + twoTimesFract = mult(2048/*2 in Q10*/,fractional/*Q15*/); /*Q10*/ /* threshold if the center of the peek is between k-1 and k, threshold+2 if the center of the peek is between k and k+1 */ + + move16(); + thresholdModification[k] = threshold; + move16(); + thresholdModification[k-1] = add(threshold/*Q10*/, twoTimesFract/*Q10*/); /*Q10*/ + move16(); + thresholdModification[k+1] = add(threshold/*Q10*/, sub(2048/*2 in Q10*/, twoTimesFract/*Q10*/)/*Q10*/); /*Q10*/ + return; +} + +static void modifyThresholds( + Word16 /*float*/ F0, /*I - Q10*/ + Word16 /*float*/ origF0, /*I - Q10*/ + Word16* /*float*/ thresholdModification) /*I/O - Q10*/ +{ + Word16 /*int*/ i, /*int*/ nHarmonics; + Word16 tmp, tmpM, tmpE; + + + IF (origF0 > 0) + { + IF (F0 == 0) + { + nHarmonics /*Q0*/ = s_min(MAX_PEAKS_FROM_PITCH /*Q0*/, shl((div_s(LAST_HARMONIC_POS_TO_CHECK /*Q0*/, origF0/*Q10*/) /*Q15*2^10*/),-5 /*Q0*2^-5*/) /*Q0*/); + + FOR (i = 1; i <= nHarmonics; i++) + { + modifyThreshold(i, origF0, 717/*0.7f Q10*/ /*0.7f in Q10*/, thresholdModification); + } + } + IF (F0 > 0) + { + nHarmonics /*Q0*/ = s_min(MAX_PEAKS_FROM_PITCH /*Q0*/, shl((div_s(LAST_HARMONIC_POS_TO_CHECK /*Q0*/, F0/*Q10*/) /*Q15*2^10*/),-5 /*Q0*2^-5*/) /*Q0*/); + + /*(int)(F0/origF0+0.5f)*/ + BASOP_Util_Divide_MantExp(F0,0,origF0,0,&tmpM,&tmpE); + tmp=round_fx(L_shl(L_deposit_l(tmpM),add(tmpE,1))); + + FOR (i = tmp; i > 0; i--) + { + modifyThreshold(i, origF0, 358/*0.35f Q10*/, thresholdModification); + } + FOR (i = 1; i <= nHarmonics; i++) + { + modifyThreshold(i, F0, 358/*0.35f Q10*/, thresholdModification); + } + } + } + return; +} + +static void findCandidates( + const Word16 nSamples, /* i: frame size */ + const Word32 * MDCTSpectrum, /* i: MDCT spectrum */ + const Word16 MDCTSpectrum_exp, /* i: exponent of MDCT spectrum */ + Word16 * thresholdModificationNew, /* o: threshold modification Q10 */ + Word16 floorPowerSpectrum /* i: lower limit for power spectrum bins */ +) +{ + Word32 powerSpectrum[L_FRAME_MAX]; + Word16 powerSpectrum_exp; + Word32 envelope[L_FRAME_MAX]; + Word32 smoothedSpectrum[L_FRAME_MAX]; + Word16 upperIdx, lowerIdx; + Word16 k, j; + Word32 biggerNeighbor; + Word16 tmp_loop1, tmp_loop2, tmp_loop3; + + + + calcPseudoSpec(MDCTSpectrum, MDCTSpectrum_exp, nSamples, floorPowerSpectrum, powerSpectrum, &powerSpectrum_exp); + + getEnvelope(nSamples, powerSpectrum, 0, envelope, smoothedSpectrum); + + set16_fx(thresholdModificationNew, UNREACHABLE_THRESHOLD, nSamples); + + k = GROUP_LENGTH/2; + move16(); + tmp_loop1 = sub(nSamples, (GROUP_LENGTH-GROUP_LENGTH/2)); + tmp_loop2 = sub(nSamples,1); + WHILE ( LE_16(k, tmp_loop1)) + { + IF (GT_32(smoothedSpectrum[k],envelope[k])) + { + /* The check that bin at k is bigger than bins at k-1 and k+1 is needed to avoid deadlocks when the thresholds are low. */ + /* It removes some true peaks, especially if non weighted sum is used for the smoothed spectrum. */ + biggerNeighbor = L_max(powerSpectrum[k-1], powerSpectrum[k+1]); + + IF (GE_32(powerSpectrum[k], biggerNeighbor)) + { + /* Find the right foot */ + upperIdx = add(k, 1); + WHILE ( LT_16(upperIdx,tmp_loop2)) + { + + IF (LT_32(powerSpectrum[upperIdx],powerSpectrum[upperIdx+1])) + { + /* Side lobes may increase for certain amount */ + IF (LT_32( L_shl(Mpy_32_16_1(powerSpectrum[upperIdx], ALLOWED_SIDE_LOBE_FLUCTUATION), ALLOWED_SIDE_LOBE_FLUCTUATION_EXP), powerSpectrum[upperIdx+1] )) + { + BREAK; + } + /* Check for further decrease after a side lobe increase */ + FOR (j = add(upperIdx,1); j < tmp_loop2; j++) + { + IF (LT_32( powerSpectrum[j], L_shl(Mpy_32_16_1(powerSpectrum[j+1], ALLOWED_SIDE_LOBE_FLUCTUATION), ALLOWED_SIDE_LOBE_FLUCTUATION_EXP) )) + { + BREAK; + } + } + /* Side lobe increase must be 2 times smaller than the decrease to the foot */ + /* Eq. to 2.0f*powerSpectrum[lowerIdx-1]/powerSpectrum[lowerIdx] > powerSpectrum[lowerIdx]/powerSpectrum[j] */ + IF ( GT_32( Mpy_32_32(L_shl(powerSpectrum[upperIdx+1],1),powerSpectrum[j]), Mpy_32_32(powerSpectrum[upperIdx], powerSpectrum[upperIdx]) )) + { + BREAK; + } + upperIdx = sub(j,1); + } + upperIdx = add(upperIdx, 1); + } + /* left foot */ + lowerIdx = sub(k,1); + WHILE ( lowerIdx > 0 ) + { + + IF (LT_32(powerSpectrum[lowerIdx], powerSpectrum[lowerIdx-1])) + { + /* Side lobes may increase for certain amount */ + IF (LT_32( L_shl(Mpy_32_16_1(powerSpectrum[lowerIdx], ALLOWED_SIDE_LOBE_FLUCTUATION), ALLOWED_SIDE_LOBE_FLUCTUATION_EXP), powerSpectrum[lowerIdx-1])) + { + BREAK; + } + /* Check for further decrease after a side lobe increase */ + FOR (j = sub(lowerIdx,1); j > 0; j--) + { + IF (LT_32(powerSpectrum[j], L_shl(Mpy_32_16_1(powerSpectrum[j-1], ALLOWED_SIDE_LOBE_FLUCTUATION), ALLOWED_SIDE_LOBE_FLUCTUATION_EXP) ) ) + { + BREAK; + } + } + /* Side lobe increase must be 2 times smaller than the decrease to the foot */ + /* Eq. to 2.0f*powerSpectrum[lowerIdx-1]/powerSpectrum[lowerIdx] > powerSpectrum[lowerIdx]/powerSpectrum[j] */ + IF (GT_32 ( Mpy_32_32(L_shl(powerSpectrum[lowerIdx-1],1), powerSpectrum[j]), Mpy_32_32(powerSpectrum[lowerIdx], powerSpectrum[lowerIdx])) ) + { + BREAK; + } + lowerIdx = add(j,1); + } + lowerIdx = sub(lowerIdx, 1); + } + + /* Check if there is a bigger peak up to the next peak foot */ + tmp_loop3 = s_min(upperIdx, tmp_loop1); + FOR (j = s_max(GROUP_LENGTH/2, lowerIdx); j <= tmp_loop3; j++) + { + if (GT_32(powerSpectrum[j], powerSpectrum[k])) + { + k = j; + move16(); + } + } + + /* Modify thresholds for the following frame */ + tmp_loop3 = add(k,2); + FOR (j = sub(k,1); j < tmp_loop3; j++) + { + thresholdModificationNew[j] = BIG_THRESHOLD; + move16(); + + if (GT_32(smoothedSpectrum[j], envelope[j])) + { + thresholdModificationNew[j] = SMALL_THRESHOLD; + move16(); + } + + } + /* Jump to the next foot of the peak. */ + k = upperIdx; + move16(); + } + } + k = add(k, 1); + } + return; +} + +static void RefineThresholdsUsingPitch( + const Word16 nSamples, + const Word16 nSamplesCore, + const Word32 powerSpectrum[], + const Word32 lastPitchLag, + const Word32 currentPitchLag, + Word16 * pF0, + Word16 * thresholdModification) +{ + Word16 pitchIsStable; + Word16 origF0; + Word32 L_tmp; + + /*pitchIsStable = (fabs(lastPitchLag-currentPitchLag) < 0.25f);*/ + pitchIsStable = 0; + move16(); + L_tmp = L_abs(L_sub(lastPitchLag, currentPitchLag)); + if (LT_32(L_tmp, 16384l/*0.25f Q16*/)) + { + pitchIsStable = 1; + move16(); + } + + IF (pitchIsStable) + { + GetF0(nSamples, + nSamplesCore, + powerSpectrum, lastPitchLag, &origF0, pF0); + + modifyThresholds(*pF0, origF0, thresholdModification); + } + ELSE + { + *pF0 = 0; + move16(); + } + return; +} + +static void findTonalComponents( + Word16 * indexOfTonalPeak, /* OUT */ + Word16 * lowerIndex, /* OUT */ + Word16 * upperIndex, /* OUT */ + Word16 *numIndexes, /* OUT */ + Word16 nSamples, /* IN */ + const Word32 * powerSpectrum, /* IN */ + Word16 F0, /* IN */ + Word16 * thresholdModification) /* IN */ +{ + Word32 envelope[L_FRAME_MAX]; + Word32 smoothedSpectrum[L_FRAME_MAX]; + Word16 nrOfFIS; + Word16 upperIdx, lowerIdx, lowerBound; + Word16 k, j, m; + Word32 biggerNeighbor; + Word16 tmp_loop1, tmp_loop2, tmp_loop3; + + getEnvelope(nSamples, powerSpectrum, F0, envelope, smoothedSpectrum); + + + nrOfFIS = 0; + move16(); + lowerBound = 0; + move16(); + + k = GROUP_LENGTH/2; + move16(); + tmp_loop1 = sub(nSamples, (GROUP_LENGTH-GROUP_LENGTH/2)); + tmp_loop2 = sub(nSamples,1); + WHILE ( LE_16(k, tmp_loop1)) + { + /* There is 3 bits headroom in envelope and max of thresholdModification is 16384, so shifting left for 4 would produce overflow only when the result is anyhow close to 1 */ + IF (GT_32(L_shr(smoothedSpectrum[k], 1), L_shl(Mpy_32_16_1(envelope[k]/*Q28,powerSpec_exp*/, thresholdModification[k]/*Q10*/), 4))) + { + /* The check that bin at k is bigger than bins at k-1 and k+1 is needed to avoid deadlocks when the thresholds are low. */ + /* It removes some true peaks, especially if non weighted sum is used for the smoothed spectrum. */ + biggerNeighbor = L_max(powerSpectrum[k-1], powerSpectrum[k+1]); + + IF (GE_32(powerSpectrum[k], biggerNeighbor)) + { + /* Find the right foot */ + upperIdx = add(k, 1); + WHILE (LT_16(upperIdx, tmp_loop2)) + { + IF (LT_32(powerSpectrum[upperIdx], powerSpectrum[upperIdx+1])) + { + /* Side lobes may increase for certain amount */ + IF (LT_32( L_shl(Mpy_32_16_1(powerSpectrum[upperIdx], ALLOWED_SIDE_LOBE_FLUCTUATION), ALLOWED_SIDE_LOBE_FLUCTUATION_EXP), powerSpectrum[upperIdx+1])) + { + BREAK; + } + /* Check for further decrease after a side lobe increase */ + FOR (j = add(upperIdx, 1); j < tmp_loop2; j++) + { + IF (LT_32( powerSpectrum[j], L_shl(Mpy_32_16_1(powerSpectrum[j+1], ALLOWED_SIDE_LOBE_FLUCTUATION), ALLOWED_SIDE_LOBE_FLUCTUATION_EXP))) + { + BREAK; + } + } + /* Side lobe increase must be 2 times smaller than the decrease to the foot */ + /* Eq. to 2.0f*powerSpectrum[lowerIdx-1]/powerSpectrum[lowerIdx] > powerSpectrum[lowerIdx]/powerSpectrum[j] */ + IF (GT_32( Mpy_32_32(L_shl(powerSpectrum[upperIdx+1], 1), powerSpectrum[j]), Mpy_32_32(powerSpectrum[upperIdx], powerSpectrum[upperIdx]))) + { + BREAK; + } + upperIdx = sub(j, 1); + } + upperIdx = add(upperIdx, 1); + } + /* left foot */ + lowerIdx = sub(k, 1); + WHILE (GT_16(lowerIdx, lowerBound)) + { + IF (LT_32(powerSpectrum[lowerIdx], powerSpectrum[lowerIdx-1])) + { + /* Side lobes may increase for certain amount */ + IF ( LT_32(L_shl(Mpy_32_16_1(powerSpectrum[lowerIdx], ALLOWED_SIDE_LOBE_FLUCTUATION), ALLOWED_SIDE_LOBE_FLUCTUATION_EXP), powerSpectrum[lowerIdx-1])) + { + BREAK; + } + /* Check for further decrease after a side lobe increase */ + FOR (j = sub(lowerIdx, 1); j > 0; j--) + { + IF (LT_32(powerSpectrum[j], L_shl(Mpy_32_16_1(powerSpectrum[j-1], ALLOWED_SIDE_LOBE_FLUCTUATION), ALLOWED_SIDE_LOBE_FLUCTUATION_EXP))) + { + BREAK; + } + } + /* Side lobe increase must be 2 times smaller than the decrease to the foot */ + /* Eq. to 2.0f*powerSpectrum[lowerIdx-1]/powerSpectrum[lowerIdx] > powerSpectrum[lowerIdx]/powerSpectrum[j] */ + IF ( GT_32( Mpy_32_32(L_shl(powerSpectrum[lowerIdx-1], 1), powerSpectrum[j]), Mpy_32_32(powerSpectrum[lowerIdx], powerSpectrum[lowerIdx]))) + { + BREAK; + } + lowerIdx = add(j, 1); + } + lowerIdx = sub(lowerIdx, 1); + } + + lowerBound = upperIdx; + move16(); + + /* Check if there is a bigger peak up to the next peak foot */ + tmp_loop3 = s_min(upperIdx, tmp_loop1); + FOR (j = s_max(GROUP_LENGTH/2, lowerIdx); j <= tmp_loop3; j++) + { + if (GT_32(powerSpectrum[j],powerSpectrum[k])) + { + + k = j; + move16(); + } + } + + assert((nrOfFIS == 0) || (indexOfTonalPeak[nrOfFIS-1] < k)); + + lowerIndex[nrOfFIS] = sub(k, GROUP_LENGTH/2); + move16(); + + upperIndex[nrOfFIS] = add(k,(GROUP_LENGTH-GROUP_LENGTH/2-1)); + move16(); + + test(); + IF ((nrOfFIS > 0) && (LE_16(lowerIndex[nrOfFIS], upperIndex[nrOfFIS-1]))) + { + m = shr(add(k, indexOfTonalPeak[nrOfFIS-1]), 1); + upperIndex[nrOfFIS-1] = m; + move16(); + lowerIndex[nrOfFIS] = add(m, 1); + move16(); + } + + indexOfTonalPeak[nrOfFIS++] = k; + move16(); + + IF (EQ_16(nrOfFIS, MAX_NUMBER_OF_IDX)) + { + BREAK; + } + /* Jump to the next foot of the peak. */ + k = upperIdx; + move16(); + } + } + k = add(k, 1); + } + + *numIndexes = nrOfFIS; + move16(); + return; +} + diff --git a/lib_dec/acelp_core_dec.c b/lib_dec/acelp_core_dec.c index 13c2bddfadfebe664916868a4ceba79afece982e..fcc3fbb0f516e83659fd77102e12cea94f54d0c8 100644 --- a/lib_dec/acelp_core_dec.c +++ b/lib_dec/acelp_core_dec.c @@ -139,24 +139,24 @@ ivas_error acelp_core_dec( { if ( st->cng_type == FD_CNG ) { - configureFdCngDec( st->hFdCngDec, st->bwidth, ACELP_14k25, st->L_frame, st->last_L_frame, st->element_mode ); + configureFdCngDec_flt( st->hFdCngDec, st->bwidth, ACELP_14k25, st->L_frame, st->last_L_frame, st->element_mode ); /* Only run parameter decoding in SID frames */ if ( st->core_brate == SID_2k40 ) { - FdCng_decodeSID( st ); + FdCng_decodeSID_flt( st ); } for ( i = 0; i < NPART; i++ ) { - st->hFdCngDec->hFdCngCom->sidNoiseEstLp[i] = STEREO_DFT_FD_FILT * st->hFdCngDec->hFdCngCom->sidNoiseEstLp[i] + ( 1 - STEREO_DFT_FD_FILT ) * st->hFdCngDec->hFdCngCom->sidNoiseEst[i]; + st->hFdCngDec->hFdCngCom->sidNoiseEstLp_flt[i] = STEREO_DFT_FD_FILT * st->hFdCngDec->hFdCngCom->sidNoiseEstLp_flt[i] + ( 1 - STEREO_DFT_FD_FILT ) * st->hFdCngDec->hFdCngCom->sidNoiseEst_flt[i]; } - ApplyFdCng( NULL, NULL, NULL, NULL, st, 0, 0 ); + ApplyFdCng_flt( NULL, NULL, NULL, NULL, st, 0, 0 ); } else { - configureFdCngDec( st->hFdCngDec, st->bwidth, ACELP_14k25, st->L_frame, st->last_L_frame, st->element_mode ); + configureFdCngDec_flt( st->hFdCngDec, st->bwidth, ACELP_14k25, st->L_frame, st->last_L_frame, st->element_mode ); /* decode CNG parameters */ CNG_dec( st, last_element_mode, Aq, lsp_new, lsf_new, &allow_cn_step, sid_bw, q_env ); @@ -230,7 +230,7 @@ ivas_error acelp_core_dec( if ( ( st->element_mode == IVAS_CPE_DFT || st->element_mode == IVAS_CPE_TD ) && ( st->last_core_brate == SID_2k40 || st->last_core_brate == FRAME_NO_DATA ) ) { - set_zero( st->hFdCngDec->hFdCngCom->olapBufferSynth2, FFTLEN ); + set_zero( st->hFdCngDec->hFdCngCom->olapBufferSynth2_flt, FFTLEN ); set_zero( hStereoCng->olapBufferSynth22, FFTLEN ); } @@ -510,7 +510,7 @@ ivas_error acelp_core_dec( { if ( st->core_brate == SID_2k40 && st->element_mode != IVAS_CPE_MDCT ) { - FdCng_decodeSID( st ); + FdCng_decodeSID_flt( st ); *sid_bw = 0; } @@ -520,25 +520,25 @@ ivas_error acelp_core_dec( for ( i = 0; i < NPART; i++ ) { - st->hFdCngDec->hFdCngCom->sidNoiseEstLp[i] = STEREO_DFT_FD_FILT * st->hFdCngDec->hFdCngCom->sidNoiseEstLp[i] + ( 1 - STEREO_DFT_FD_FILT ) * st->hFdCngDec->hFdCngCom->sidNoiseEst[i]; + st->hFdCngDec->hFdCngCom->sidNoiseEstLp_flt[i] = STEREO_DFT_FD_FILT * st->hFdCngDec->hFdCngCom->sidNoiseEstLp_flt[i] + ( 1 - STEREO_DFT_FD_FILT ) * st->hFdCngDec->hFdCngCom->sidNoiseEst_flt[i]; } - ApplyFdCng( syn, NULL, realBuffer, imagBuffer, st, 0, ( st->coder_type == AUDIO && !st->GSC_noisy_speech ) ); + ApplyFdCng_flt( syn, NULL, realBuffer, imagBuffer, st, 0, ( st->coder_type == AUDIO && !st->GSC_noisy_speech ) ); } if ( !read_sid_info ) { float noise_lvl_highest; - noise_lvl_highest = st->hFdCngDec->hFdCngCom->cngNoiseLevel[st->hFdCngDec->hFdCngCom->stopFFTbin - st->hFdCngDec->hFdCngCom->startBand - 1]; + noise_lvl_highest = st->hFdCngDec->hFdCngCom->cngNoiseLevel_flt[st->hFdCngDec->hFdCngCom->stopFFTbin - st->hFdCngDec->hFdCngCom->startBand - 1]; for ( int16_t b = st->hFdCngDec->hFdCngCom->stopFFTbin - st->hFdCngDec->hFdCngCom->startBand; b < st->hFdCngDec->hFdCngCom->stopBand; b++ ) { - st->hFdCngDec->hFdCngCom->cngNoiseLevel[b] = noise_lvl_highest; + st->hFdCngDec->hFdCngCom->cngNoiseLevel_flt[b] = noise_lvl_highest; } } - generate_comfort_noise_dec( NULL, NULL, st, nchan_out ); + generate_comfort_noise_dec_flt( NULL, NULL, st, nchan_out ); - FdCng_exc( st->hFdCngDec->hFdCngCom, &st->CNG_mode, st->L_frame, st->lsp_old, st->first_CNG, st->lspCNG, Aq, lsp_new, lsf_new, exc, exc2, bwe_exc ); + FdCng_exc_flt( st->hFdCngDec->hFdCngCom, &st->CNG_mode, st->L_frame, st->lsp_old, st->first_CNG, st->lspCNG, Aq, lsp_new, lsf_new, exc, exc2, bwe_exc ); mvr2r( exc2, exc3, st->L_frame ); } @@ -607,11 +607,11 @@ ivas_error acelp_core_dec( nb_bits = -1; } - config_acelp1( DEC, st->total_brate, st->core_brate, st->core, st->extl_orig, st->extl_brate_orig, st->L_frame, st->GSC_noisy_speech, &( st->acelp_cfg ), st->next_bit_pos, st->coder_type, tc_subfr_tmp, 1, &nb_bits, unbits, st->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); + config_acelp1_IVAS( DEC, st->total_brate, st->core_brate, st->core, st->extl_orig, st->extl_brate_orig, st->L_frame, st->GSC_noisy_speech, &( st->acelp_cfg ), st->next_bit_pos, st->coder_type, tc_subfr_tmp, 1, &nb_bits, unbits, st->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); if ( st->coder_type == TRANSITION && tc_subfr < L_SUBFR && st->L_frame == L_FRAME ) { - config_acelp1( DEC, st->total_brate, st->core_brate, st->core, st->extl_orig, st->extl_brate_orig, st->L_frame, -1, &( st->acelp_cfg ), st->next_bit_pos, st->coder_type, tc_subfr, 2, &nb_bits, unbits, st->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); + config_acelp1_IVAS( DEC, st->total_brate, st->core_brate, st->core, st->extl_orig, st->extl_brate_orig, st->L_frame, -1, &( st->acelp_cfg ), st->next_bit_pos, st->coder_type, tc_subfr, 2, &nb_bits, unbits, st->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); } } @@ -935,9 +935,9 @@ ivas_error acelp_core_dec( } /* LSF estimation and A(z) calculation */ - lsf_dec_bfi( MODE1, lsf_new, st->lsf_old, st->lsf_adaptive_mean, NULL, st->mem_MA, st->mem_AR, st->stab_fac, st->last_coder_type, st->L_frame, st->last_good, st->nbLostCmpt, 0, NULL, NULL, NULL, st->hGSCDec->Last_GSC_pit_band_idx, st->Opt_AMR_WB, st->bwidth ); + lsf_dec_bfi_flt( MODE1, lsf_new, st->lsf_old, st->lsf_adaptive_mean, NULL, st->mem_MA, st->mem_AR, st->stab_fac, st->last_coder_type, st->L_frame, st->last_good, st->nbLostCmpt, 0, NULL, NULL, NULL, st->hGSCDec->Last_GSC_pit_band_idx, st->Opt_AMR_WB, st->bwidth ); - FEC_lsf2lsp_interp( st, st->L_frame, Aq, lsf_new, lsp_new ); + FEC_lsf2lsp_interp_flt( st, st->L_frame, Aq, lsf_new, lsp_new ); if ( st->nelp_mode_dec == 1 ) { @@ -1043,12 +1043,12 @@ ivas_error acelp_core_dec( if ( st->bwidth == NB ) { st->hPFstat->on = 1; - nb_post_filt( st->L_frame, L_SUBFR, st->hPFstat, &st->psf_lp_noise, tmp_noise, syn, Aq, pitch_buf, st->coder_type, st->BER_detect, 0 ); + nb_post_filt_ivas( st->L_frame, L_SUBFR, st->hPFstat, &st->psf_lp_noise, tmp_noise, syn, Aq, pitch_buf, st->coder_type, st->BER_detect, 0 ); } else { st->hPFstat->on = 0; - nb_post_filt( st->L_frame, L_SUBFR, st->hPFstat, &st->psf_lp_noise, tmp_noise, syn, Aq, pitch_buf, AUDIO, st->BER_detect, 0 ); + nb_post_filt_ivas( st->L_frame, L_SUBFR, st->hPFstat, &st->psf_lp_noise, tmp_noise, syn, Aq, pitch_buf, AUDIO, st->BER_detect, 0 ); } } else @@ -1081,7 +1081,7 @@ ivas_error acelp_core_dec( mvr2r( syn, temp_buf + L_SYN_MEM, L_FRAME16k ); st->hPFstat->on = 1; - formant_post_filt( st->hPFstat, temp_buf + L_SYN_MEM, Aq, syn, st->L_frame, L_SUBFR, st->lp_noise_float, st->total_brate, 0 ); + formant_post_filt_ivas( st->hPFstat, temp_buf + L_SYN_MEM, Aq, syn, st->L_frame, L_SUBFR, st->lp_noise_float, st->total_brate, 0 ); } else if ( st->hPFstat != NULL && st->last_bwidth >= WB ) { @@ -1091,9 +1091,9 @@ ivas_error acelp_core_dec( mvr2r( syn, temp_buf + M, L_SUBFR ); residu( Aq, M, temp_buf + M, temp_buf + M + L_SUBFR, L_SUBFR ); syn_filt( Aq, M, temp_buf + M + L_SUBFR, temp_buf, L_SUBFR, st->hPFstat->mem_stp_flt + L_SYN_MEM - M, 0 ); - scale_st( syn, temp_buf, &st->hPFstat->gain_prec_flt, L_SUBFR, -1 ); + scale_st_ivas( syn, temp_buf, &st->hPFstat->gain_prec_flt, L_SUBFR, -1 ); mvr2r( temp_buf, syn, L_SUBFR / 2 ); - blend_subfr2( temp_buf + L_SUBFR / 2, syn + L_SUBFR / 2, syn + L_SUBFR / 2 ); + blend_subfr2_flt( temp_buf + L_SUBFR / 2, syn + L_SUBFR / 2, syn + L_SUBFR / 2 ); } st->hPFstat->on = 0; } @@ -1112,9 +1112,9 @@ ivas_error acelp_core_dec( if ( st->idchan == 0 && ( st->flag_cna || ( st->cng_type == FD_CNG && st->total_brate <= ACELP_32k ) || ( st->cng_type == LP_CNG && st->core_brate <= SID_2k40 ) ) ) { /*Noisy speech detector*/ - noisy_speech_detection( st->hFdCngDec, st->VAD, syn ); + noisy_speech_detection_flt( st->hFdCngDec, st->VAD, syn ); - st->hFdCngDec->hFdCngCom->likelihood_noisy_speech = 0.99f * st->hFdCngDec->hFdCngCom->likelihood_noisy_speech + 0.01f * (float) st->hFdCngDec->hFdCngCom->flag_noisy_speech; + st->hFdCngDec->hFdCngCom->likelihood_noisy_speech_flt = 0.99f * st->hFdCngDec->hFdCngCom->likelihood_noisy_speech_flt + 0.01f * (float) st->hFdCngDec->hFdCngCom->flag_noisy_speech; } if ( st->idchan == 0 ) @@ -1125,7 +1125,7 @@ ivas_error acelp_core_dec( if ( st->element_mode != IVAS_CPE_TD && !st->cng_ism_flag ) { /*Noise estimate*/ - ApplyFdCng( syn, NULL, realBuffer, imagBuffer, st, 0, ( st->coder_type == AUDIO && !st->GSC_noisy_speech ) ); + ApplyFdCng_flt( syn, NULL, realBuffer, imagBuffer, st, 0, ( st->coder_type == AUDIO && !st->GSC_noisy_speech ) ); } if ( !st->cna_dirac_flag ) @@ -1157,9 +1157,9 @@ ivas_error acelp_core_dec( { if ( st->element_mode != last_element_mode ) { - set_f( st->hFdCngDec->hFdCngCom->olapBufferSynth2, 0.0f, st->hFdCngDec->hFdCngCom->fftlen ); + set_f( st->hFdCngDec->hFdCngCom->olapBufferSynth2_flt, 0.0f, st->hFdCngDec->hFdCngCom->fftlen ); } - generate_masking_noise( syn, st->hFdCngDec->hFdCngCom, st->hFdCngDec->hFdCngCom->frameSize, 0, 0, 0, st->element_mode, hStereoCng, nchan_out ); + generate_masking_noise_flt( syn, st->hFdCngDec->hFdCngCom, st->hFdCngDec->hFdCngCom->frameSize, 0, 0, 0, st->element_mode, hStereoCng, nchan_out ); } } } @@ -1172,7 +1172,7 @@ ivas_error acelp_core_dec( } else { - v_multc( st->hFdCngDec->hFdCngCom->olapBufferSynth2 + 5 * st->hFdCngDec->hFdCngCom->frameSize / 4, (float) ( st->hFdCngDec->hFdCngCom->fftlen / 2 ), temp_buf, st->hFdCngDec->hFdCngCom->frameSize / 2 ); + v_multc( st->hFdCngDec->hFdCngCom->olapBufferSynth2_flt + 5 * st->hFdCngDec->hFdCngCom->frameSize / 4, (float) ( st->hFdCngDec->hFdCngCom->fftlen / 2 ), temp_buf, st->hFdCngDec->hFdCngCom->frameSize / 2 ); v_add( temp_buf, syn, syn, st->hFdCngDec->hFdCngCom->frameSize / 2 ); } } @@ -1190,7 +1190,7 @@ ivas_error acelp_core_dec( /*Noise estimate*/ if ( st->idchan == 0 && ( nchan_out == 2 || ( st->core_brate != FRAME_NO_DATA && st->core_brate != SID_2k40 ) ) ) { - ApplyFdCng( syn, NULL, realBuffer, imagBuffer, st, 0, ( st->coder_type == AUDIO && !st->GSC_noisy_speech ) ); + ApplyFdCng_flt( syn, NULL, realBuffer, imagBuffer, st, 0, ( st->coder_type == AUDIO && !st->GSC_noisy_speech ) ); } } } @@ -1200,7 +1200,7 @@ ivas_error acelp_core_dec( { if ( st->flag_cna == 0 && st->L_frame == L_FRAME16k && st->last_flag_cna == 1 && ( ( st->last_core == ACELP_CORE && !( st->last_coder_type == AUDIO && !( st->element_mode > EVS_MONO && st->Last_GSC_noisy_speech_flag ) ) ) || st->last_core == AMR_WB_CORE ) ) { - v_multc( st->hFdCngDec->hFdCngCom->olapBufferSynth2 + 5 * st->L_frame / 4, 256.f, temp_buf, st->L_frame / 2 ); + v_multc( st->hFdCngDec->hFdCngCom->olapBufferSynth2_flt + 5 * st->L_frame / 4, 256.f, temp_buf, st->L_frame / 2 ); v_add( temp_buf, syn, syn, st->L_frame / 2 ); } @@ -1208,7 +1208,7 @@ ivas_error acelp_core_dec( { if ( st->idchan == 0 ) { - set_f( st->hFdCngDec->hFdCngCom->olapBufferSynth2, 0.f, st->hFdCngDec->hFdCngCom->fftlen ); + set_f( st->hFdCngDec->hFdCngCom->olapBufferSynth2_flt, 0.f, st->hFdCngDec->hFdCngCom->fftlen ); } if ( hStereoCng != NULL && st->idchan == 0 ) { @@ -1227,8 +1227,8 @@ ivas_error acelp_core_dec( /* check if the CLDFB works on the right sample rate */ if ( ( st->cldfbAna->no_channels * st->cldfbAna->no_col ) != st->L_frame ) { - resampleCldfb( st->cldfbAna, st->L_frame * FRAMES_PER_SEC ); - resampleCldfb( st->cldfbBPF, st->L_frame * FRAMES_PER_SEC ); + resampleCldfb_ivas( st->cldfbAna, st->L_frame * FRAMES_PER_SEC ); + resampleCldfb_ivas( st->cldfbBPF, st->L_frame * FRAMES_PER_SEC ); if ( st->ini_frame > 0 ) { @@ -1273,7 +1273,7 @@ ivas_error acelp_core_dec( } /* analysis of the synthesis at internal sampling rate */ - cldfbAnalysis( syn, realBuffer, imagBuffer, -1, st->cldfbAna ); + cldfbAnalysis_ivas( syn, realBuffer, imagBuffer, -1, st->cldfbAna ); /* analysis and add the BPF error signal */ addBassPostFilter( bpf_error_signal, st->bpf_off ? 0 : -1, realBuffer, imagBuffer, st->cldfbBPF ); @@ -1295,7 +1295,7 @@ ivas_error acelp_core_dec( /*WB/SWB-FD_CNG*/ if ( ( st->core_brate == FRAME_NO_DATA || st->core_brate == SID_2k40 ) && ( st->cng_type == FD_CNG ) && ( st->hFdCngDec->hFdCngCom->numCoreBands < st->cldfbSyn->no_channels ) ) { - generate_comfort_noise_dec_hf( realBuffer, imagBuffer, st->hFdCngDec->hFdCngCom, st->cng_ism_flag ); + generate_comfort_noise_dec_hf_flt( realBuffer, imagBuffer, st->hFdCngDec->hFdCngCom, st->cng_ism_flag ); if ( st->hFdCngDec->hFdCngCom->regularStopBand < st->cldfbSyn->no_channels ) { @@ -1325,7 +1325,7 @@ ivas_error acelp_core_dec( } } - cldfbSynthesis( realBuffer, imagBuffer, save_hb_synth, -1, st->cldfbSynHB ); + cldfbSynthesis_ivas( realBuffer, imagBuffer, save_hb_synth, -1, st->cldfbSynHB ); /* restore lowband */ for ( int16_t j = 0; j < CLDFB_NO_CHANNELS_MAX; j++ ) @@ -1337,12 +1337,12 @@ ivas_error acelp_core_dec( } } - cldfbSynthesis( pRealSave, pImagSave, synth, -1, st->cldfbSyn ); + cldfbSynthesis_ivas( pRealSave, pImagSave, synth, -1, st->cldfbSyn ); } else { /* synthesis of the combined signal */ - cldfbSynthesis( realBuffer, imagBuffer, synth, -1, st->cldfbSyn ); + cldfbSynthesis_ivas( realBuffer, imagBuffer, synth, -1, st->cldfbSyn ); } /* save synthesis - needed in case of core switching */ @@ -1354,13 +1354,13 @@ ivas_error acelp_core_dec( int16_t nSamples = NS2SA( st->L_frame * FRAMES_PER_SEC, FRAME_SIZE_NS /*DELAY_CLDFB_NS*/ ); /* IVAS-64: optimization is likely possible here (don't resample the whole frame) */ /* analysis of the synthesis at internal sampling rate - needed for DFT stereo -> TD stereo switching */ - cldfbAnalysis( syn + st->L_frame - nSamples, realBuffer, imagBuffer, nSamples, st->cldfbAna ); + cldfbAnalysis_ivas( syn + st->L_frame - nSamples, realBuffer, imagBuffer, nSamples, st->cldfbAna ); /* analysis and add the BPF error signal - needed for DFT stereo -> TD stereo switching */ addBassPostFilter( bpf_error_signal + st->L_frame - nSamples, st->bpf_off ? 0 : nSamples, realBuffer, imagBuffer, st->cldfbBPF ); /* synthesis of the combined signal - needed for DFT stereo -> TD stereo switching */ - cldfbSynthesis( realBuffer, imagBuffer, synth /*dummy*/, NS2SA( st->output_Fs, FRAME_SIZE_NS /*DELAY_CLDFB_NS*/ ), st->cldfbSyn ); + cldfbSynthesis_ivas( realBuffer, imagBuffer, synth /*dummy*/, NS2SA( st->output_Fs, FRAME_SIZE_NS /*DELAY_CLDFB_NS*/ ), st->cldfbSyn ); if ( st->p_bpf_noise_buf_float) { diff --git a/lib_dec/acelp_core_dec_fx.c b/lib_dec/acelp_core_dec_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..5fa9a1bafb9539d8b0f2189c6fe787e4b1e27197 --- /dev/null +++ b/lib_dec/acelp_core_dec_fx.c @@ -0,0 +1,1827 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include +#include +#include "options.h" /* Compilation switches */ +#include "rom_com.h" /* Static table prototypes */ +#include "prot_fx1.h" /* Function prototypes */ +#include "prot_fx2.h" /* Function prototypes */ +#include "ivas_prot_fx.h" +#include "ivas_cnst.h" /* Common constants */ +#include "cnst.h" /* Common constants */ + +/*==========================================================================*/ +/* FUNCTION : void acelp_core_dec_fx () */ +/*--------------------------------------------------------------------------*/ +/* PURPOSE : ACELP core decoder */ +/*--------------------------------------------------------------------------*/ +/* INPUT ARGUMENTS : */ +/* _ Word16 coder_type_fx i : coder type */ + +/*--------------------------------------------------------------------------*/ +/* OUTPUT ARGUMENTS : */ +/* _ Word16 *voice_factors o : voicing factors Q15 */ +/* _ Word16 old_syn_12k8_16k[] o : intermediate ACELP Q_syn2-1 */ +/* synthesis at 12.8kHz or 16kHz to be used by SWB BWE */ +/* _ Word16 synth_out[] o : synthesis Q_syn2-1 */ +/*--------------------------------------------------------------------------*/ +/* INPUT/OUTPUT ARGUMENTS : */ +/* _ Decoder_State_fx *st_fx: */ +/* _ Word16 bwe_exc_extended[] i/o: bandwidth extended excitation Q0*/ +/*--------------------------------------------------------------------------*/ +/* RETURN ARGUMENTS : */ +/* _ None */ +/*--------------------------------------------------------------------------*/ +/* CALLED FROM : RX */ +/*==========================================================================*/ + +ivas_error acelp_core_dec_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + Word16 output[], /* o : synthesis @internal Fs */ + Word16 synth_out[], /* o : synthesis */ + Word16 save_hb_synth[], /* o : HB synthesis */ + Word32 bwe_exc_extended[], /* i/o: bandwidth extended excitation */ + Word16 *voice_factors, /* o : voicing factors */ + Word16 old_syn_12k8_16k[], /* o : intermediate ACELP synthesis for SWB BWE */ + Word16 sharpFlag, + Word16 pitch_buf_fx[NB_SUBFR16k], /* o : floating pitch for each subframe */ + Word16 *unbits, /* o : number of unused bits */ + Word16 *sid_bw, /* o : 0-NB/WB, 1-SWB SID */ + STEREO_TD_DEC_DATA_HANDLE hStereoTD,/* i/o: TD stereo decoder handle */ + const Word16 tdm_lspQ_PCh[M], /* i : Q LSPs for primary channel */ + const Word16 tdm_lsfQ_PCh[M], /* i : Q LSFs for primary channel */ + const Word16 use_cldfb_for_dft, /* i : flag to use of CLDFB for DFT Stereo */ + const Word16 last_element_mode, /* i : last element mode */ + const Word32 last_element_brate, /* i : last element bitrate */ + const Word16 flag_sec_CNA, /* i : CNA flag for secondary channel */ + const Word16 nchan_out, /* i : number of output channels */ + STEREO_CNG_DEC_HANDLE hStereoCng, /* i : stereo CNG handle */ + const Word16 read_sid_info /* i : read SID info flag */ +) +{ + Word16 old_exc_fx[L_EXC_DEC] = {0}, *exc_fx; /* excitation signal buffer (Q0) */ + Word16 syn_fx_tmp[L_FRAME_16k+L_SUBFR], *syn_fx; /* synthesis signal buffer */ + Word16 temp_buf[L_FRAME16k + L_SYN_MEM]; + Word16 output_frame; /* frame length at output sampling freq. */ + Word16 mem_tmp_fx[M]; /* temporary synthesis filter memory */ + Word32 enr_q_fx; /* E information for FER protection */ + Word16 tmp_noise_fx; /* Long term temporary noise energy */ + Word16 i, int_fs; + Word16 tc_subfr_fx; + Word16 allow_cn_step_fx; + Word16 temp_buf_fx[L_FRAME16k + L_SYN_MEM]; + + Word16 Aq_fx[NB_SUBFR16k*(M+1)]= {0}; /*Q12*/ + Word16 Es_pred_fx; /*Q8*/ + Word16 old_bwe_exc_fx[((PIT16k_MAX + (L_FRAME16k+1) + L_SUBFR16k) * 2)] = {0}; /* excitation buffer */ + Word16 old_exc2_fx[L_FRAME16k + L_EXC_MEM], *exc2_fx; /* total excitation buffer */ + Word16 *bwe_exc_fx; + Word16 lsf_new_fx[M]; /* LSFs at the end of the frame */ + Word16 lsp_new_fx[M]; /* LSPs at the end of the frame */ + Word16 lsp_mid_fx[M]; /* LSPs in the middle of the frame */ + Word16 FEC_pitch_fx; /*Q6*/ + Word16 last_pulse_pos; + Word16 T0_tmp; + Word16 do_WI_fx; + Word16 dct_buffer_fx[DCT_L_POST]; + Word16 exc_buffer_fx[DCT_L_POST]; + Word16 dct_exc_tmp[L_FRAME16k]; + Word16 qdct; + Word16 delta_mem_scale; + Word16 bpf_error_signal[L_FRAME16k]; + CLDFB_SCALE_FACTOR scaleFactor; + Word32 workBuffer[128*3]; + Word32 q_env[20]; + Word16 exc3_fx[L_FRAME16k]; + Word16 syn1_fx_tmp[L_FRAME16k+2], *syn1_fx; + Word32 *realBuffer[CLDFB_NO_COL_MAX], *imagBuffer[CLDFB_NO_COL_MAX]; + Word16 gain_buf[NB_SUBFR16k]; /*Q14*/ + Word16 syn_fx_tmp2[L_FRAME_16k]; + Word16 pitch_buf_tmp[NB_SUBFR16k]; + Word16 k; + Word16 update_flg; + Word32 realBufferTmp[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + Word32 imagBufferTmp[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + Word16 LSF_Q_prediction; /* o : LSF prediction mode */ + Word16 avoid_lpc_burst_on_recovery; + Word16 uc_two_stage_flag, dec; + Word16 nb_bits, indice; + Word16 tdm_lp_reuse_flag, tdm_low_rate_mode, tdm_Pitch_reuse_flag; +#ifdef ADD_LRTD + Word16 * p_tdm_Pri_pitch_buf; +#endif + MUSIC_POSTFILT_HANDLE hMusicPF; + BPF_DEC_HANDLE hBPF; + TD_BWE_DEC_HANDLE hBWE_TD; + FD_BWE_DEC_HANDLE hBWE_FD; + TCX_DEC_HANDLE hTcxDec; + ivas_error error; +#ifdef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING + (void)(tdm_lspQ_PCh); + (void)(tdm_lsfQ_PCh); + (void)(use_cldfb_for_dft); + (void)(last_element_mode); + (void)(last_element_brate); + (void)(flag_sec_CNA); + (void)(nchan_out); + (void)(save_hb_synth); + (void)(output); + (void)(read_sid_info); + (void)hStereoCng; +#endif + hMusicPF = st_fx->hMusicPF; + hBPF = st_fx->hBPF; + hBWE_TD = st_fx->hBWE_TD; + hBWE_FD = st_fx->hBWE_FD; + hTcxDec = st_fx->hTcxDec; + error = IVAS_ERR_OK; + + //IF ( EQ_16(st_fx->element_mode, IVAS_CPE_MDCT) && EQ_16(nchan_out, 1) && EQ_16(st_fx->idchan, 1) && LE_32(last_element_brate, IVAS_SID_4k4) ) + IF ( EQ_16(st_fx->element_mode, IVAS_CPE_MDCT) && EQ_16(nchan_out, 1) && EQ_16(st_fx->idchan, 1) && LE_32(last_element_brate, IVAS_SID_5k2) ) + { + /* In MDCT-Stereo DTX with mono output, we can skip CNG for the second channel, except for the first inactive frame following an active period */ + return error; + } + + +#ifdef IVAS_CODE + output_frame = (int16_t)(st->output_Fs / FRAMES_PER_SEC); + + /*----------------------------------------------------------------* + * stereo SID and CNG frames processing + *----------------------------------------------------------------*/ + + if (st->core_brate <= SID_2k40 && st->element_mode == IVAS_CPE_DFT && nchan_out == 2) + { + if (st->cng_type == FD_CNG) + { + configureFdCngDec(st->hFdCngDec, st->bwidth, ACELP_14k25, st->L_frame, st->last_L_frame, st->element_mode); + + /* Only run parameter decoding in SID frames */ + if (st->core_brate == SID_2k40) + { + FdCng_decodeSID(st); + } + + for (i = 0; i < NPART; i++) + { + st->hFdCngDec->hFdCngCom->sidNoiseEstLp[i] = STEREO_DFT_FD_FILT * st->hFdCngDec->hFdCngCom->sidNoiseEstLp[i] + (1 - STEREO_DFT_FD_FILT) * st->hFdCngDec->hFdCngCom->sidNoiseEst[i]; + } + +#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT + ApplyFdCng(NULL, NULL, NULL, NULL, st, 0, 0); +#else + ApplyFdCng(NULL, NULL, NULL, NULL, st, 0, 0); +#endif + } + else + { + configureFdCngDec(st->hFdCngDec, st->bwidth, ACELP_14k25, st->L_frame, st->last_L_frame, st->element_mode); + + /* decode CNG parameters */ + CNG_dec(st, last_element_mode, Aq, lsp_new, lsf_new, &allow_cn_step, sid_bw, q_env); + + /* comfort noise generation */ + CNG_exc(st->core_brate, st->L_frame, &st->hTdCngDec->Enew, &st->hTdCngDec->cng_seed, NULL, NULL, &st->lp_ener, st->last_core_brate, &st->first_CNG, &(st->hTdCngDec->cng_ener_seed), NULL, allow_cn_step, &st->hTdCngDec->last_allow_cn_step, st->hTdCngDec->num_ho, q_env, st->hTdCngDec->lp_env, st->hTdCngDec->old_env, st->hTdCngDec->exc_mem, st->hTdCngDec->exc_mem1, sid_bw, &st->hTdCngDec->cng_ener_seed1, NULL, st->Opt_AMR_WB, st->element_mode); + + mvr2r(Aq, st->Aq_cng, M + 1); + + /* update old LSP and LSF vector */ + mvr2r(lsf_new, st->lsf_old, M); + mvr2r(lsp_new, st->lsp_old, M); + } + + set_f(output, 0, output_frame); /* output and synth are not used in DFT domain CNG generation and the decoder output is unaffected if they are left uninitalized */ + set_f(synth, 0, output_frame); /* They are however read in a few places which causes errors in the valgrind tests. Simplest solution from a code perspective was to set them to zero. */ + + /* CN generation done in DFT domain */ + wmops_sub_end(); + return error; + } + + /*----------------------------------------------------------------* + * Active frames processing + *----------------------------------------------------------------*/ +#endif + FOR( i=0; ioutput_Fs_fx / 50); move16();*/ + output_frame = st_fx->output_frame_fx; + move16(); + st_fx->bpf_off = 0; + move16(); + test(); test(); test(); test(); + IF ( EQ_16(st_fx->last_core, HQ_CORE) || EQ_16(st_fx->last_core, TCX_20_CORE) || EQ_16(st_fx->last_core, TCX_10_CORE) || (EQ_16(st_fx->element_mode, IVAS_CPE_DFT) && LE_32(st_fx->last_core_brate, SID_2k40)) || (EQ_16(st_fx->element_mode, IVAS_CPE_MDCT) && LE_32(st_fx->last_core_brate, SID_2k40) )) + { + /* in case of HQ->ACELP switching, do not apply BPF */ + st_fx->bpf_off = 1; + move16(); + /* in case of core switching, reset post-filter memories */ + IF (st_fx->hPFstat != NULL) + { + st_fx->hPFstat->on = 0; + } + move16(); + /* reset the GSC pre echo energy threshold in case of switching */ + IF (st_fx->hGSCDec != NULL) + { + st_fx->hGSCDec->Last_frame_ener_fx = MAX_32; + } + move32(); + } + if(st_fx->prev_bfi > 0) + { + /* reset the GSC pre echo energy threshold in case of FEC */ + IF(st_fx->hGSCDec != NULL) + { + st_fx->hGSCDec->Last_frame_ener_fx = MAX_32; + } + move32(); + } +#ifdef IVAS_CODE + if ((st->element_mode == IVAS_CPE_DFT || st->element_mode == IVAS_CPE_TD) && (st->last_core_brate == SID_2k40 || st->last_core_brate == FRAME_NO_DATA)) + { + set_zero(st->hFdCngDec->hFdCngCom->olapBufferSynth2, FFTLEN); + set_zero(hStereoCng->olapBufferSynth22, FFTLEN); + } +#endif + st_fx->clas_dec = st_fx->last_good_fx; + move16(); + enr_q_fx = 0; + move16(); + Es_pred_fx = 0; + move16(); + tmp_noise_fx = 0; + + Copy( st_fx->old_exc_fx, old_exc_fx, L_EXC_MEM_DEC ); + exc_fx = old_exc_fx + L_EXC_MEM_DEC; + move16(); + IF (st_fx->hWIDec != NULL) + { + Copy(st_fx->hWIDec->old_exc2_fx, old_exc2_fx, L_EXC_MEM); + } + ELSE + { + set16_fx(old_exc2_fx, 0, L_EXC_MEM); + } + exc2_fx = old_exc2_fx + L_EXC_MEM; + IF (st_fx->hBWE_TD != NULL) + { + Copy(hBWE_TD->old_bwe_exc_fx, old_bwe_exc_fx, PIT16k_MAX * 2); + bwe_exc_fx = old_bwe_exc_fx + PIT16k_MAX * 2; + } + ELSE + { + bwe_exc_fx = NULL; + } + + move16(); + last_pulse_pos = 0; + move16(); + do_WI_fx = 0; + move16(); + st_fx->GSC_noisy_speech_fx = 0; + move16(); + st_fx->relax_prev_lsf_interp_fx = 0; + move16(); + + set16_fx( gain_buf, 0, NB_SUBFR16k ); + IF( EQ_16(st_fx->L_frame,L_FRAME)) + { + st_fx->gamma = GAMMA1; + move16(); + st_fx->preemph_fac = PREEMPH_FAC; + move16(); + int_fs = INT_FS_FX; + move16(); + } + ELSE + { + st_fx->gamma = GAMMA16k; + move16(); + st_fx->preemph_fac = PREEMPH_FAC_16k; + move16(); + int_fs = INT_FS_16k; + move16(); + } + + /* reset post-filter in case post-filtering was off in previous frame */ + IF(st_fx->hPFstat != NULL) + { + if (st_fx->hPFstat->on == 0) + { + st_fx->hPFstat->reset = 1; + move16(); + } + } + avoid_lpc_burst_on_recovery = 0; + move16(); + test(); + test(); + if( st_fx->last_con_tcx && NE_16(st_fx->L_frameTCX_past, st_fx->L_frame)&&st_fx->last_core!=0) + { + avoid_lpc_burst_on_recovery = 1; + move16(); + } + /* TD stereo parameters */ + test(); + IF (EQ_16(st_fx->element_mode, IVAS_CPE_TD) && st_fx->idchan == 1) + { + tdm_lp_reuse_flag = hStereoTD->tdm_lp_reuse_flag; + tdm_low_rate_mode = hStereoTD->tdm_low_rate_mode; + tdm_Pitch_reuse_flag = hStereoTD->tdm_Pitch_reuse_flag; +#ifdef ADD_LRTD + p_tdm_Pri_pitch_buf = hStereoTD->tdm_Pri_pitch_buf; +#endif + move16(); move16(); move16(); move16(); + } + else + { + tdm_lp_reuse_flag = 0; + tdm_low_rate_mode = 0; + move16(); move16(); + test(); + IF (EQ_16(st_fx->element_mode, IVAS_SCE) && st_fx->low_rate_mode) + { + tdm_low_rate_mode = 1; + move16(); + } + tdm_Pitch_reuse_flag = 0; +#ifdef ADD_LRTD + p_tdm_Pri_pitch_buf = NULL; +#endif + move16(); move16(); + } + /*----------------------------------------------------------------* + * Updates in case of internal sampling rate switching + *----------------------------------------------------------------*/ + test(); + test(); + IF (NE_16(st_fx->last_L_frame, st_fx->L_frame) && (EQ_16(st_fx->last_core, ACELP_CORE) || EQ_16(st_fx->last_core, AMR_WB_CORE))) + { + if( st_fx->hPFstat->on != 0 ) + { + Word16 mem_syn_r_size_old, mem_syn_r_size_new; + + mem_syn_r_size_old = shr(st_fx->last_L_frame, 4); + mem_syn_r_size_new = shr(st_fx->L_frame, 4); + lerp( st_fx->hPFstat->mem_stp+L_SYN_MEM-mem_syn_r_size_old, st_fx->hPFstat->mem_stp+L_SYN_MEM-mem_syn_r_size_new, mem_syn_r_size_new, mem_syn_r_size_old ); + lerp( st_fx->hPFstat->mem_pf_in+L_SYN_MEM-mem_syn_r_size_old, st_fx->hPFstat->mem_pf_in+L_SYN_MEM-mem_syn_r_size_new, mem_syn_r_size_new, mem_syn_r_size_old ); + } + /* convert quantized LSP vector */ + st_fx->rate_switching_reset=lsp_convert_poly_fx( st_fx->lsp_old_fx, st_fx->L_frame, 0); + /* convert old quantized LSF vector */ + lsp2lsf_fx( st_fx->lsp_old_fx, st_fx->lsf_old_fx, M, int_fs ); + + /* FEC - update adaptive LSF mean vector */ + Copy( st_fx->lsf_old_fx, st_fx->lsfoldbfi1_fx, M ); + Copy( st_fx->lsf_old_fx, st_fx->lsfoldbfi0_fx, M ); + Copy( st_fx->lsf_old_fx, st_fx->lsf_adaptive_mean_fx, M ); + + /* Reset LPC mem */ + IF( EQ_32(st_fx->sr_core, INT_FS_16k)) + { + Copy( GEWB2_Ave_fx, st_fx->mem_AR_fx, M ); + } + ELSE + { + Copy( GEWB_Ave_fx, st_fx->mem_AR_fx, M ); + } + set16_fx( st_fx->mem_MA_fx,0, M ); +#if 1//def IVAS_CODE + dec = DEC; + move16(); + IF (NE_16(st_fx->element_mode, EVS_MONO)) + { + dec = DEC_IVAS; + move16(); + } + + /* update synthesis filter memories */ + synth_mem_updt2( st_fx->L_frame, st_fx->last_L_frame, st_fx->old_exc_fx, st_fx->mem_syn_r, st_fx->mem_syn2_fx, NULL, dec ); +#else + synth_mem_updt2( st_fx->L_frame, st_fx->last_L_frame, st_fx->old_exc_fx, st_fx->mem_syn_r, st_fx->mem_syn2_fx, NULL, DEC ); +#endif + Copy( st_fx->old_exc_fx, old_exc_fx, L_EXC_MEM_DEC ); + Copy_Scale_sig(st_fx->mem_syn2_fx, st_fx->mem_syn1_fx, M, sub(-1,st_fx->Q_syn)); /*Q-1*/ + + Copy( st_fx->mem_syn2_fx, st_fx->mem_syn3_fx, M ); + + } + + IF( NE_16(st_fx->last_L_frame,st_fx->L_frame)) + { + /* update buffer of old subframe pitch values */ + IF( EQ_16(st_fx->L_frame,L_FRAME)) + { + move16(); + IF( EQ_16(st_fx->last_L_frame,L_FRAME32k)) + { + /* (float)12800/(float)32000; */ + k = 13107; + } + ELSE IF( EQ_16(st_fx->last_L_frame,512)) + { + /* (float)12800/(float)25600; */ + k = 16384; + } + ELSE /* st->last_L_frame == L_FRAME16k */ + { + /* (float)12800/(float)16000; */ + k = 26214; + } + + FOR( i=NB_SUBFR16k-NB_SUBFR; iold_pitch_buf_fx[i-1] = Mpy_32_16_1(st_fx->old_pitch_buf_fx[i], k); + move32(); + } + + FOR( i=2*NB_SUBFR16k-NB_SUBFR; i<2*NB_SUBFR16k; i++ ) + { + st_fx->old_pitch_buf_fx[i-2] = Mpy_32_16_1(st_fx->old_pitch_buf_fx[i], k); + move32(); + } + } + ELSE + { + move16(); + IF( EQ_16(st_fx->last_L_frame,L_FRAME32k)) + { + /* (float)16000/(float)32000; */ + k = -16384; + } + ELSE IF( EQ_16(st_fx->last_L_frame,512)) + { + /* tmpF = (float)16000/(float)25600; */ + k = -12288; + } + ELSE /* st->last_L_frame == L_FRAME12k8 */ + { + /* tmpF = (float)16000/(float)12800; */ + k = 8192; + } + + FOR( i=2*NB_SUBFR-1; i>=NB_SUBFR; i-- ) + { + st_fx->old_pitch_buf_fx[i+2] = L_add(st_fx->old_pitch_buf_fx[i], Mpy_32_16_1(st_fx->old_pitch_buf_fx[i], k)); + move32(); + } + st_fx->old_pitch_buf_fx[NB_SUBFR+1] = st_fx->old_pitch_buf_fx[NB_SUBFR+2]; + move32(); + + FOR( i=NB_SUBFR-1; i>=0; i-- ) + { + st_fx->old_pitch_buf_fx[i+1] = L_add(st_fx->old_pitch_buf_fx[i], Mpy_32_16_1(st_fx->old_pitch_buf_fx[i], k)); + move32(); + } + st_fx->old_pitch_buf_fx[0] = st_fx->old_pitch_buf_fx[1]; + move32(); + } + } + + IF( NE_16(st_fx->bfi_pitch_frame, st_fx->L_frame)) + { + IF( EQ_16(st_fx->L_frame,L_FRAME)) + { + move16(); + IF( EQ_16(st_fx->bfi_pitch_frame,L_FRAME32k)) + { + /* (float)12800/(float)32000; */ + k = 13107; + } + ELSE IF( EQ_16(st_fx->bfi_pitch_frame,512)) + { + /* (float)12800/(float)25600; */ + k = 16384; + } + ELSE /* st->bfi_pitch_frame == L_FRAME16k */ + { + /* (float)12800/(float)16000; */ + k = 26214; + } + st_fx->bfi_pitch_fx = mult_r(k, st_fx->bfi_pitch_fx); + st_fx->bfi_pitch_frame = L_FRAME; + move16(); + } + ELSE + { + move16(); + IF( EQ_16(st_fx->bfi_pitch_frame,L_FRAME32k)) + { + /* (float)16000/(float)32000; */ + k = -16384; + } + ELSE IF( EQ_16(st_fx->bfi_pitch_frame,512)) + { + /* tmpF = (float)16000/(float)25600; */ + k = -12288; + } + ELSE /* st->bfi_pitch_frame == L_FRAME12k8 */ + { + /* tmpF = (float)16000/(float)12800; */ + k = 8192; + } + st_fx->bfi_pitch_fx = add(st_fx->bfi_pitch_fx, mult_r(st_fx->bfi_pitch_fx,k)); + st_fx->bfi_pitch_frame = L_FRAME16k; + move16(); + } + } + + test(); + test(); + if( EQ_16(st_fx->last_bwidth,NB)&&NE_16(st_fx->bwidth,NB)&&st_fx->ini_frame!=0) + { + st_fx->rate_switching_reset=1; + move16(); + } + + /*----------------------------------------------------------------------* + * GOOD frame + *----------------------------------------------------------------------*/ + + IF( !st_fx->bfi ) + { + + /*----------------------------------------------------------------* + * Decoding of TC subframe classification + *----------------------------------------------------------------*/ + + tc_subfr_fx = -1; + move16(); + if( EQ_16(st_fx->coder_type_fx,TRANSITION)) + { + tc_subfr_fx = tc_classif_fx( st_fx, st_fx->L_frame ); + move16(); + } +#if 1//def IVAS_CODE + /*----------------------------------------------------------------* + * Decoding of GSC IVAS mode + *----------------------------------------------------------------*/ + st_fx->GSC_IVAS_mode = 0; + IF (GT_16(st_fx->element_mode, EVS_MONO) && st_fx->idchan == 0 && !(EQ_32(st_fx->core_brate, FRAME_NO_DATA) || EQ_32(st_fx->core_brate, SID_2k40)) && !tdm_low_rate_mode) + { + IF (EQ_16(st_fx->coder_type_fx, AUDIO) || (EQ_16(st_fx->coder_type_fx, INACTIVE) && LE_32(st_fx->total_brate, MAX_GSC_INACTIVE_BRATE))) + { + st_fx->GSC_IVAS_mode = get_next_indice(st_fx, 2); + } + } +#endif + /*----------------------------------------------------------------* + * Decoding of inactive CNG frames + *----------------------------------------------------------------*/ + test(); + IF ( st_fx->core_brate == FRAME_NO_DATA || EQ_32(st_fx->core_brate,SID_2k40)) + { + /* decode CNG parameters */ + IF ( EQ_16(st_fx->cng_type,LP_CNG)) + { + + CNG_dec_fx( st_fx, st_fx->last_element_mode, Aq_fx, lsp_new_fx, lsf_new_fx, &allow_cn_step_fx, sid_bw, q_env ); +#ifdef IVAS_CODE + local_element_mode = st_fx->element_mode; + move16(); + IF ((EQ_16(nchan_out, 1) && EQ_16(st_fx->element_mode, IVAS_CPE_DFT)) || EQ_16(st_fx->masa_sid_format,1)) + { + local_element_mode = IVAS_SCE; /* For DFT Stereo mono decoding, run CNG_exc as in SCE */ + move16(); + } +#endif + /* comfort noise generation */ + CNG_exc_fx( st_fx->core_brate, st_fx->L_frame, &st_fx->hTdCngDec->Enew_fx, &st_fx->hTdCngDec->cng_seed_fx, exc_fx, exc2_fx, &st_fx->lp_ener_fx, st_fx->last_core_brate, + &st_fx->first_CNG, &(st_fx->hTdCngDec->cng_ener_seed_fx), bwe_exc_fx, allow_cn_step_fx, &st_fx->hTdCngDec->last_allow_cn_step_fx, st_fx->prev_Q_exc, st_fx->Q_exc, st_fx->hTdCngDec->num_ho_fx, + q_env, st_fx->hTdCngDec->lp_env_fx, st_fx->hTdCngDec->old_env_fx, st_fx->hTdCngDec->exc_mem_fx, st_fx->hTdCngDec->exc_mem1_fx, sid_bw, &st_fx->hTdCngDec->cng_ener_seed1_fx, exc3_fx ,st_fx->Opt_AMR_WB, st_fx->element_mode ); +#if 1//def IVAS_CODE + Copy(Aq_fx, st_fx->Aq_cng, M + 1); +#endif + + } + ELSE + { + IF( EQ_32(st_fx->core_brate,SID_2k40) && NE_16(st_fx->element_mode, IVAS_CPE_MDCT) ) + { + FdCng_decodeSID(st_fx->hFdCngDec_fx->hFdCngCom, st_fx); + *sid_bw=0; + move16(); + } +#ifdef IVAS_CODE + if (st->element_mode == IVAS_CPE_DFT) + { + assert(nchan_out == 1); + + for (i = 0; i < NPART; i++) + { + st->hFdCngDec->hFdCngCom->sidNoiseEstLp[i] = STEREO_DFT_FD_FILT * st->hFdCngDec->hFdCngCom->sidNoiseEstLp[i] + (1 - STEREO_DFT_FD_FILT) * st->hFdCngDec->hFdCngCom->sidNoiseEst[i]; + } +#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT + ApplyFdCng(syn, 0, NULL, realBuffer, imagBuffer, NULL, st, 0, (st->coder_type == AUDIO && !st->GSC_noisy_speech)); +#else + ApplyFdCng(syn, realBuffer, imagBuffer, st, 0, (st->coder_type == AUDIO && !st->GSC_noisy_speech)); +#endif + } + if (!read_sid_info) + { + float noise_lvl_highest; + + noise_lvl_highest = st->hFdCngDec->hFdCngCom->cngNoiseLevel[st->hFdCngDec->hFdCngCom->stopFFTbin - st->hFdCngDec->hFdCngCom->startBand - 1]; + for (int16_t b = st->hFdCngDec->hFdCngCom->stopFFTbin - st->hFdCngDec->hFdCngCom->startBand; b < st->hFdCngDec->hFdCngCom->stopBand; b++) + { + st->hFdCngDec->hFdCngCom->cngNoiseLevel[b] = noise_lvl_highest; + } + } +#endif + generate_comfort_noise_dec( NULL, NULL, NULL, st_fx, &(st_fx->Q_exc), 2, -1 ); + + FdCng_exc(st_fx->hFdCngDec_fx->hFdCngCom, &st_fx->CNG_mode, st_fx->L_frame, st_fx->lsp_old_fx, st_fx->first_CNG, st_fx->lspCNG_fx, Aq_fx, lsp_new_fx, lsf_new_fx, exc_fx, exc2_fx, bwe_exc_fx); + + Copy( exc2_fx, exc3_fx, st_fx->L_frame ); + } + + delta_mem_scale = 3; + move16(); + test(); + if( LT_32(st_fx->lp_ener_fx,40)&&EQ_16(st_fx->cng_type,LP_CNG)) /* very low energy frames, less than 0.3125 */ + { + delta_mem_scale = 0; + move16(); + } + i = st_fx->Q_exc; + Rescale_exc(hMusicPF->dct_post_old_exc_fx, exc_fx, bwe_exc_fx, st_fx->hGSCDec->last_exc_dct_in_fx, st_fx->L_frame, + st_fx->L_frame* HIBND_ACB_L_FAC, 0, &(st_fx->Q_exc), st_fx->Q_subfr, NULL, 0, INACTIVE); + Rescale_mem( st_fx->Q_exc, &st_fx->prev_Q_syn, &st_fx->Q_syn, st_fx->mem_syn2_fx, st_fx->mem_syn_clas_estim_fx, delta_mem_scale, + &st_fx->mem_deemph_fx, hBPF->pst_old_syn_fx,&hBPF->pst_mem_deemp_err_fx, &st_fx->agc_mem_fx[1], st_fx->hPFstat, 0, 0, NULL ); + Copy_Scale_sig(exc2_fx, exc2_fx, st_fx->L_frame, sub(st_fx->Q_exc, i)); + + /* update past excitation signals for LD music post-filter */ + IF(hMusicPF != NULL) + { + Copy(hMusicPF->dct_post_old_exc_fx + L_FRAME, hMusicPF->dct_post_old_exc_fx, DCT_L_POST - L_FRAME - OFFSET2); + Copy(exc2_fx, hMusicPF->dct_post_old_exc_fx + (DCT_L_POST - L_FRAME - OFFSET2), L_FRAME); + /* Update music post processing values */ + /* Filter energies update */ + FOR(i = 0; i < DCT_L_POST; i++) + { + /*st_fx->filt_lfE_fx[i] = 0.3f + 0.7f * st_fx->filt_lfE_fx[i];*/ + hMusicPF->filt_lfE_fx[i] = round_fx(L_mac((1228 << (16)), 22938, hMusicPF->filt_lfE_fx[i])); + } + } + /* synthesis at 12.8kHz sampling rate */ + syn_12k8_fx( st_fx->L_frame, Aq_fx, exc2_fx, syn_fx, st_fx->mem_syn2_fx, 1, st_fx->Q_exc, st_fx->Q_syn ); + syn_12k8_fx( st_fx->L_frame, Aq_fx, exc3_fx, syn1_fx, st_fx->mem_syn3_fx, 1, st_fx->Q_exc, st_fx->Q_syn ); + + /* reset the decoder */ + CNG_reset_dec_fx( st_fx, pitch_buf_fx, voice_factors ); + + /* update st_fx->mem_syn1 for ACELP core switching */ + Copy( st_fx->mem_syn3_fx, st_fx->mem_syn1_fx, M ); + + /* update old synthesis for classification */ + Copy( syn1_fx + st_fx->L_frame - L_SYN_MEM_CLAS_ESTIM, st_fx->mem_syn_clas_estim_fx, L_SYN_MEM_CLAS_ESTIM ); + + + /* save and delay synthesis to be used by SWB BWE */ + Copy_Scale_sig( syn1_fx, temp_buf_fx, st_fx->L_frame, sub(-1,st_fx->Q_syn)); + IF (hBWE_FD != NULL) + { + save_old_syn_fx(st_fx->L_frame, temp_buf_fx, old_syn_12k8_16k, hBWE_FD->old_syn_12k8_16k_fx, st_fx->preemph_fac, &hBWE_FD->mem_deemph_old_syn_fx); + } + } + + /*----------------------------------------------------------------* + * Decoding of all other frames + *----------------------------------------------------------------*/ + + ELSE + { + /*-----------------------------------------------------------------* + * Configure ACELP bit allocation + *-----------------------------------------------------------------*/ + nb_bits = 0; + st_fx->acelp_cfg.FEC_mode = 0; + uc_two_stage_flag = 0; + move16(); move16(); move16(); + test(); + IF (!st_fx->nelp_mode_dec_fx && !st_fx->ppp_mode_dec_fx) + { + Word16 tc_subfr_tmp; + + tc_subfr_tmp = tc_subfr_fx; + move16(); + IF (LT_16(tc_subfr_tmp, L_SUBFR)) + { + tc_subfr_tmp = 0; + move16(); + } + + IF (EQ_16(tc_subfr_fx, TC_0_192)) + { + nb_bits = -1; + move16(); + } + + config_acelp1(DEC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl_orig, st_fx->extl_brate_orig, st_fx->L_frame, st_fx->GSC_noisy_speech_fx, &(st_fx->acelp_cfg), st_fx->next_bit_pos, st_fx->coder_type_fx, tc_subfr_tmp, 1, &nb_bits, unbits, st_fx->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st_fx->idchan, st_fx->active_cnt, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode); + + test(); test(); test(); + IF (EQ_16(st_fx->coder_type_fx, TRANSITION) && LT_16(tc_subfr_fx, L_SUBFR) && EQ_16(st_fx->L_frame, L_FRAME)) + { + config_acelp1(DEC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl_orig, st_fx->extl_brate_orig, st_fx->L_frame, -1, &(st_fx->acelp_cfg), st_fx->next_bit_pos, st_fx->coder_type_fx, tc_subfr_fx, 2, &nb_bits, unbits, st_fx->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st_fx->idchan, st_fx->active_cnt, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode); + } + } + + /*-----------------------------------------------------------------* + * After CNG period, use the most up-to-date LSPs + *-----------------------------------------------------------------*/ + + test(); test(); + IF (st_fx->hTdCngDec != NULL && (st_fx->last_core_brate == FRAME_NO_DATA || EQ_32(st_fx->last_core_brate,SID_2k40))) + { + Copy( st_fx->lspCNG_fx, st_fx->lsp_old_fx, M ); + + lsp2lsf_fx( st_fx->lspCNG_fx, st_fx->lsf_old_fx, M, int_fs ); + } + + /*-----------------------------------------------------------------* + * Reset higher ACELP pre-quantizer in case of switching + *-----------------------------------------------------------------*/ + + IF( !st_fx->use_acelp_preq ) + { + st_fx->mem_preemp_preQ_fx = 0; + move16(); + st_fx->last_nq_preQ_fx = 0; + move16(); +#ifdef IVAS_CODE + st_fx->last_code_preq = 0; + move16(); +#endif + } + + st_fx->use_acelp_preq = 0; + move16(); + + /*-----------------------------------------------------------------* + * LSF de-quantization and interpolation + *-----------------------------------------------------------------*/ +#ifdef ADD_LRTD + if (!tdm_lp_reuse_flag) +#endif + { + lsf_dec_fx( st_fx, tc_subfr_fx, Aq_fx,&LSF_Q_prediction, lsf_new_fx, lsp_new_fx, lsp_mid_fx, tdm_low_rate_mode +#ifdef LSF_RE_USE_SECONDARY_CHANNEL + ,tdm_lsfQ_PCh +#endif + ); + } +#ifdef ADD_LRTD + else + { + const float* pt_interp_2; +#ifdef LSF_RE_USE_SECONDARY_CHANNEL + if (st->active_cnt != 1) + { + int16_t beta_index; + + beta_index = get_next_indice(st, TDM_IC_LSF_PRED_BITS); + tdm_SCh_lsf_reuse(DEC, st->element_brate, lsf_new, lsp_new, tdm_lsfQ_PCh, NULL, &beta_index); + } + else + { + mvr2r(tdm_lspQ_PCh, lsp_new, M); + mvr2r(tdm_lsfQ_PCh, lsf_new, M); + } +#else + mvr2r(tdm_lspQ_PCh, lsp_new, M); + mvr2r(tdm_lsfQ_PCh, lsf_new, M); +#endif + if (st->rate_switching_reset) + { + /* extrapolation in case of unstable LSF convert */ + mvr2r(lsp_new, st->lsp_old, M); + mvr2r(lsf_new, st->lsf_old, M); + } + + pt_interp_2 = interpol_frac_12k8; + if (tdm_low_rate_mode == 1 && st->coder_type > UNVOICED) + { + pt_interp_2 = interpol_frac2; + } + + if (st->active_cnt == 1) + { + mvr2r(lsp_new, st->lsp_old, M); + lsp2lsf(lsp_new, st->lsf_old, M, st->sr_core); + } + + /* LSP interpolation and conversion of LSPs to A(z) */ + int_lsp(st->L_frame, st->lsp_old, lsp_new, Aq, M, pt_interp_2, 0); + /* Check LSF stability (distance between old LSFs and current LSFs) */ + st->stab_fac = lsf_stab(lsf_new, st->lsf_old, 0, st->L_frame); + } + + if (st->last_core == HQ_CORE && st->element_mode > EVS_MONO) + { + /* Prepare ACB memory from last HQ frame */ + old_exc_s = st->old_exc + L_EXC_MEM_DEC - st->L_frame; + tmpF = *old_exc_s; + st->mem_deemph = old_exc_s[st->L_frame - 1]; + preemph(old_exc_s, st->preemph_fac, L_FRAME16k, &tmpF); + mvr2r(old_exc_s + st->L_frame - M, st->mem_syn2, M); + residu(Aq, M, old_exc_s, old_exc + L_EXC_MEM_DEC - st->L_frame, st->L_frame); + } + if (st->last_core != ACELP_CORE && st->element_mode > EVS_MONO) + { + /* Prepare ACB memory of old_bwe_exc */ +#ifdef CR_FIX_639_HQ_ACELP_TRANSITION + if (st->L_frame == L_FRAME) + { + lerp(old_exc, old_bwe_exc, L_EXC_MEM_DEC * HIBND_ACB_L_FAC, L_EXC_MEM_DEC); + } + else + { + lerp(old_exc, old_bwe_exc, L_EXC_MEM_DEC * 2, L_EXC_MEM_DEC); + } +#else + lerp(old_exc, old_bwe_exc, L_EXC_MEM_DEC * HIBND_ACB_L_FAC, L_EXC_MEM_DEC); +#endif + } +#endif + /*-----------------------------------------------------------------* + * FEC - first good frame after lost frame(s) (possibility to correct the ACB) + *-----------------------------------------------------------------*/ + + IF( st_fx->acelp_cfg.FEC_mode > 0) + { + last_pulse_pos = 0; + move16(); + + /* decode the last glottal pulse position */ + T0_tmp = FEC_pos_dec_fx( st_fx, &last_pulse_pos, &enr_q_fx, nb_bits); + move16(); + + test(); + test(); + IF( NE_16(st_fx->last_core,HQ_CORE)||(EQ_16(st_fx->last_core,HQ_CORE)&&st_fx->last_con_tcx)) + { + test(); + test(); + test(); + test(); + test(); + test(); + IF( EQ_16(st_fx->clas_dec,SIN_ONSET)&&last_pulse_pos!=0&&EQ_16(st_fx->prev_bfi,1)) + { + st_fx->Q_exc = + FEC_SinOnset_fx( old_exc_fx+L_EXC_MEM_DEC-L_EXC_MEM, last_pulse_pos, T0_tmp, enr_q_fx, Aq_fx, st_fx->L_frame, st_fx->Q_exc ); + } + ELSE IF( (EQ_16(st_fx->coder_type_fx,GENERIC) || EQ_16(st_fx->coder_type_fx,VOICED)) && last_pulse_pos!=0 && EQ_16(st_fx->old_bfi_cnt_fx,1) && EQ_16(output_frame,L_FRAME16k) && st_fx->hWIDec != NULL) + { + do_WI_fx = FEC_enhACB_fx( st_fx->L_frame, st_fx->last_L_frame, old_exc_fx+L_EXC_MEM_DEC-L_EXC_MEM , T0_tmp, last_pulse_pos, st_fx->bfi_pitch_fx ); + } + } + } + + /*------------------------------------------------------------* + * In case of first frame after an erasure and transition from voiced to unvoiced or inactive + * redo the LPC interpolation + *------------------------------------------------------------*/ + test(); + test(); + test(); + test(); + IF( st_fx->stab_fac_fx == 0 && st_fx->old_bfi_cnt_fx > 0 && NE_16(st_fx->clas_dec,VOICED_CLAS) && NE_16(st_fx->clas_dec,ONSET) && + st_fx->relax_prev_lsf_interp_fx==0 && !(EQ_16(st_fx->element_mode, IVAS_CPE_TD) && EQ_16(st_fx->idchan, 1))) + { + int_lsp4_fx(st_fx->L_frame, st_fx->lsp_old_fx, lsp_mid_fx, lsp_new_fx, Aq_fx, M, 2 ); + } + + /*---------------------------------------------------------------* + * Decoding of the scaled predicted innovation energy + *---------------------------------------------------------------*/ + + IF (nb_bits > 0) + { + indice = get_next_indice(st_fx, nb_bits); + Es_pred_dec_fx( &Es_pred_fx, indice, nb_bits, uc_two_stage_flag); + } + + /*------------------------------------------------------------* + * Decode excitation according to coding type + *------------------------------------------------------------*/ + test(); test(); test(); +#ifdef ADD_LRTD + IF (tdm_low_rate_mode) /* tdm stereo low rate mode */ + { + IF (LE_16(st_fx->coder_type_fx, UNVOICED)) + { + tdm_low_rate_dec(st_fx, dct_exc_tmp, &tmp_noise, pitch_buf, voice_factors, exc, exc2, bwe_exc, lsf_new); + } + ELSE /* GENERIC */ + { + decod_gen_2sbfr(st_fx, sharpFlag, Aq, pitch_buf, voice_factors, exc, exc2, bwe_exc, gain_buf, tdm_Pitch_reuse_flag, p_tdm_Pri_pitch_buf); + + IF (EQ_16(st_fx->element_mode, IVAS_CPE_TD)) + { + tmp_noise = st_fx->lp_gainc_fx; + move16(); + } + } + } + else +#endif + IF( EQ_16(st_fx->nelp_mode_dec_fx,1)) + { + /* SC-VBR - NELP frames */ + Scale_sig(exc_fx-L_EXC_MEM, L_EXC_MEM, -st_fx->Q_exc); + st_fx->Q_exc = 0; + move16(); + + decod_nelp_fx( st_fx, &tmp_noise_fx, pitch_buf_fx, exc_fx, exc2_fx,voice_factors, bwe_exc_fx, &st_fx->Q_exc, st_fx->bfi, gain_buf ); + Rescale_exc(hMusicPF->dct_post_old_exc_fx, exc_fx, NULL, st_fx->hGSCDec->last_exc_dct_in_fx, L_FRAME, 0, (Word32)0, &(st_fx->Q_exc), st_fx->Q_subfr, exc2_fx, L_FRAME, st_fx->coder_type_fx); + } + ELSE IF( EQ_16(st_fx->coder_type_fx,UNVOICED)) + { + /* UNVOICED frames */ + decod_unvoiced_fx( st_fx, Aq_fx, st_fx->coder_type_fx, &tmp_noise_fx, pitch_buf_fx, voice_factors, exc_fx, exc2_fx, bwe_exc_fx, gain_buf ); + } + ELSE IF ( EQ_16(st_fx->ppp_mode_dec_fx,1)) + { + Scale_sig(exc_fx-L_EXC_MEM, L_EXC_MEM, -st_fx->Q_exc); + st_fx->Q_exc = 0; + /* SC-VBR - PPP frames */ + IF ((error = decod_ppp_fx( st_fx, Aq_fx, pitch_buf_fx, exc_fx, exc2_fx, st_fx->bfi, gain_buf, voice_factors, bwe_exc_fx )) != IVAS_ERR_OK) + { + return error; + } + + Rescale_exc(hMusicPF->dct_post_old_exc_fx, exc_fx, NULL, st_fx->hGSCDec->last_exc_dct_in_fx, L_FRAME, 0, (Word32)0, &(st_fx->Q_exc), st_fx->Q_subfr, exc2_fx, L_FRAME, st_fx->coder_type_fx ); + } + ELSE IF( EQ_16(st_fx->coder_type_fx,TRANSITION )) + { + decod_tran_fx( st_fx, st_fx->L_frame, tc_subfr_fx, Aq_fx, Es_pred_fx, pitch_buf_fx, voice_factors, exc_fx, exc2_fx, bwe_exc_fx, unbits, sharpFlag, gain_buf ); + } + ELSE IF( EQ_16(st_fx->coder_type_fx,AUDIO) || (EQ_16(st_fx->coder_type_fx,INACTIVE) && LE_32(st_fx->core_brate, MAX_GSC_INACTIVE_BRATE))) + { + decod_audio_fx( st_fx, dct_exc_tmp, Aq_fx, pitch_buf_fx, voice_factors, exc_fx, exc2_fx, bwe_exc_fx, lsf_new_fx, gain_buf +#ifdef ADD_LRTD + , tdm_lp_reuse_flag, tdm_low_rate_mode, tdm_Pitch_reuse_flag, p_tdm_Pri_pitch_buf +#endif + ); + tmp_noise_fx = shr_r(st_fx->lp_gainc_fx,3); /*Q0*/ + } + ELSE + { + IF ((error = decod_gen_voic_fx(st_fx, st_fx->L_frame, sharpFlag, Aq_fx, Es_pred_fx, do_WI_fx, pitch_buf_fx, voice_factors, exc_fx, exc2_fx, bwe_exc_fx, unbits, gain_buf/*, tdm_Pitch_reuse_flag, p_tdm_Pri_pitch_buf*/)) != IVAS_ERR_OK) + { + return error; + } + + IF (EQ_16(st_fx->element_mode, IVAS_CPE_TD)) + { + tmp_noise_fx = shr_r(st_fx->lp_gainc_fx, 3); /*Q0*/ + } + } + + /* synthesis for ACELP core switching and SWB BWE */ + syn_12k8_fx( st_fx->L_frame, Aq_fx, exc_fx, temp_buf_fx, st_fx->mem_syn1_fx, 1, st_fx->Q_exc, -1 ); + /* save and delay synthesis to be used by SWB BWE */ + IF (hBWE_FD != NULL) + { + save_old_syn_fx(st_fx->L_frame, temp_buf_fx, old_syn_12k8_16k, hBWE_FD->old_syn_12k8_16k_fx, st_fx->preemph_fac, &hBWE_FD->mem_deemph_old_syn_fx); + } + + /*-----------------------------------------------------------------* + * Apply energy matching when switching to inactive frames + *-----------------------------------------------------------------*/ + + Inac_swtch_ematch_fx( exc2_fx, dct_exc_tmp, st_fx->hGSCDec->lt_ener_per_band_fx, st_fx->coder_type_fx, st_fx->L_frame, st_fx->core_brate, st_fx->Q_exc, st_fx->bfi, st_fx->last_core, st_fx->last_codec_mode ); + /*------------------------------------------------------------* + * Decode information and modify the excitation signal of stationary unvoiced frames + *------------------------------------------------------------*/ + test(); test(); test(); + IF (!(EQ_16(st_fx->idchan, 1) && EQ_16(st_fx->element_mode, IVAS_CPE_TD)) && NE_16(st_fx->nelp_mode_dec_fx, 1) && !(EQ_16(st_fx->element_mode, IVAS_SCE) && tdm_low_rate_mode)) + { + stat_noise_uv_dec_fx( st_fx, lsp_new_fx, lsp_mid_fx, Aq_fx, exc2_fx, uc_two_stage_flag); + } + + /*------------------------------------------------------------* + * Save filter memory in case the synthesis is redone after scaling + * Synthesis at 12k8 Hz sampling rate + *------------------------------------------------------------*/ + + /* update past excitation signals for LD music post-filter */ + IF(hMusicPF != NULL) + { + Copy(hMusicPF->dct_post_old_exc_fx + L_FRAME, hMusicPF->dct_post_old_exc_fx, DCT_L_POST - L_FRAME - OFFSET2); + Copy(exc2_fx, hMusicPF->dct_post_old_exc_fx + (DCT_L_POST - L_FRAME - OFFSET2), L_FRAME); + Copy(hMusicPF->dct_post_old_exc_fx, exc_buffer_fx, DCT_L_POST - OFFSET2); + } + test(); + IF(hMusicPF != NULL && ((EQ_16(st_fx->coder_type_fx, AUDIO) && EQ_16(st_fx->GSC_noisy_speech_fx, 0)) || (GE_16(st_fx->GSC_IVAS_mode, 1) && EQ_16(st_fx->L_frame, L_FRAME)))) + { + + Word16 last_coder_type = st_fx->last_coder_type_fx; + + if ( (EQ_16(st_fx->idchan, 1) && EQ_16(st_fx->element_mode, IVAS_CPE_TD)) || (GE_16(st_fx->GSC_IVAS_mode, 1) && st_fx->GSC_noisy_speech_fx == 0)) + { + last_coder_type = AUDIO; + } + /* Extrapolation of the last future part, windowing and high resolution DCT transform */ + qdct = 0; +#ifdef _DIFF_FLOAT_FIX_ /* FLoat point using last_core which fits with the inner part of the function */ + Prep_music_postP_fx(exc_buffer_fx, dct_buffer_fx, hMusicPF->filt_lfE_fx, st_fx->last_core, pitch_buf_fx, + hMusicPF->LDm_enh_lp_gbin_fx, st_fx->Q_exc, &qdct); +#else + Prep_music_postP_fx( exc_buffer_fx, dct_buffer_fx, hMusicPF->filt_lfE_fx, st_fx->last_coder_type_fx, pitch_buf_fx, + hMusicPF->LDm_enh_lp_gbin_fx, st_fx->Q_exc, &qdct ); +#endif + /* LD music post-filter */ + LD_music_post_filter_fx( hMusicPF, dct_buffer_fx, dct_buffer_fx, st_fx->core_brate, + &hMusicPF->Old_ener_Q, AUDIO, last_coder_type, qdct ); + + /* Inverse DCT transform, retrieval of the aligned excitation, re-synthesis */ + Post_music_postP_fx( dct_buffer_fx, exc2_fx, st_fx->mem_syn2_fx, st_fx->mem_syn2_fx, Aq_fx, syn_fx, &st_fx->Q_exc, &st_fx->prev_Q_syn, + &st_fx->Q_syn, st_fx->mem_syn_clas_estim_fx,0, &st_fx->mem_deemph_fx, hBPF->pst_old_syn_fx, + &hBPF->pst_mem_deemp_err_fx, &st_fx->agc_mem_fx[1], st_fx->hPFstat, temp_buf_fx, mem_tmp_fx ); + } + ELSE + { + /* Core synthesis at 12.8kHz or 16kHz */ + i = 1; + move16(); + if( EQ_16(st_fx->coder_type_fx,INACTIVE)) + { + i = 0; + move16(); + } + /* add extra headroom in case a CNA addition is likely (i.e. st_fx->psf_lp_noise_fx is close to the threshold) */ + k = 0; + move16(); + test(); + test(); + if( EQ_16(st_fx->coder_type_fx, INACTIVE)&&st_fx->flag_cna&&GE_16(round_fx(L_shl(st_fx->lp_noise,1)),15<<7)) + { + k = 1; + move16(); + } + + Rescale_mem( st_fx->Q_exc, &st_fx->prev_Q_syn, &st_fx->Q_syn, st_fx->mem_syn2_fx, st_fx->mem_syn_clas_estim_fx, 4, &st_fx->mem_deemph_fx, + hBPF->pst_old_syn_fx, &hBPF->pst_mem_deemp_err_fx, &st_fx->agc_mem_fx[1], st_fx->hPFstat, i, k, temp_buf_fx ); + Copy( st_fx->mem_syn2_fx, mem_tmp_fx, M ); + + syn_12k8_fx( st_fx->L_frame, Aq_fx, exc2_fx, syn_fx, st_fx->mem_syn2_fx, 1 , st_fx->Q_exc, st_fx->Q_syn); + IF(hMusicPF != NULL) + { + FOR(i = 0; i < DCT_L_POST; i++) + { + /*st_fx->filt_lfE_fx[i] = 0.3f + 0.7f * st_fx->filt_lfE_fx[i];*/ + hMusicPF->filt_lfE_fx[i] = round_fx(L_mac((1228 << (16)), 22938, hMusicPF->filt_lfE_fx[i])); + } + } + } + + /*------------------------------------------------------------* + * FEC - Estimate the classification information + *------------------------------------------------------------*/ + + FEC_clas_estim_fx( st_fx, st_fx->Opt_AMR_WB, st_fx->L_frame, &st_fx->clas_dec, st_fx->coder_type_fx, pitch_buf_fx, + syn_fx, &st_fx->lp_ener_FER_fx, &st_fx->decision_hyst, + NULL, NULL, NULL, NULL, 0, NULL, st_fx->core_brate, st_fx->Q_syn, temp_buf_fx, + st_fx->mem_syn_clas_estim_fx, &st_fx->classifier_Q_mem_syn, + 0, 0, 0, st_fx->last_core_brate, st_fx->acelp_cfg.FEC_mode); + + /*------------------------------------------------------------* + * FEC - Estimate pitch + *------------------------------------------------------------*/ + + FEC_pitch_estim_fx( st_fx->Opt_AMR_WB, st_fx->last_core, st_fx->L_frame, st_fx->clas_dec, st_fx->last_good_fx, pitch_buf_fx, st_fx->old_pitch_buf_fx, + &st_fx->bfi_pitch_fx, &st_fx->bfi_pitch_frame, &st_fx->upd_cnt, st_fx->coder_type_fx ); + + /*------------------------------------------------------------* + * FEC - Smooth the speech energy evolution when recovering after a BAD frame + * (smoothing is performed in the excitation domain and signal is resynthesized after) + *------------------------------------------------------------*/ + + k = 0; + move16(); + FOR (i = 0; i < st_fx->L_frame; i += L_SUBFR) + { + pitch_buf_tmp[k] = mult_r(pitch_buf_fx[k], 512); + move16(); + k++; + } + + FEC_scale_syn_fx( st_fx->L_frame, &update_flg, st_fx->clas_dec, st_fx->last_good_fx, syn_fx, pitch_buf_tmp, st_fx->enr_old_fx, enr_q_fx, st_fx->coder_type_fx, LSF_Q_prediction, + &st_fx->scaling_flag, &st_fx->lp_ener_FEC_av, &st_fx->lp_ener_FEC_max, st_fx->bfi, st_fx->total_brate, st_fx->prev_bfi, st_fx->last_core_brate, + exc_fx, exc2_fx, Aq_fx, &st_fx->old_enr_LP, mem_tmp_fx, st_fx->mem_syn2_fx, st_fx->Q_exc, st_fx->Q_syn , avoid_lpc_burst_on_recovery, 0 ); + + test(); + IF((EQ_16(st_fx->idchan, 1) && EQ_16(st_fx->element_mode, IVAS_CPE_TD) && LE_32(st_fx->total_brate, ACELP_7k20) ) || (EQ_32(st_fx->total_brate,ACELP_7k20))||(EQ_32(st_fx->total_brate,ACELP_8k00))) + { + frame_ener_fx( st_fx->L_frame, st_fx->clas_dec, syn_fx, pitch_buf_tmp[sub(shr(st_fx->L_frame,6),1)], &st_fx->enr_old_fx, st_fx->L_frame, st_fx->Q_syn, 3, 0 ); + } + } + + } /* End of GOOD FRAME */ + + /*----------------------------------------------------------------* + * BAD frame + *----------------------------------------------------------------*/ + ELSE + { + /* SC-VBR */ + if ( EQ_16(st_fx->last_nelp_mode_dec_fx,1)) + { + st_fx->nelp_mode_dec_fx = 1; + move16(); + } + + /* long burst frame erasures */ + test(); + test(); + if( GT_16(st_fx->nbLostCmpt,5)&&GE_16(st_fx->clas_dec,VOICED_CLAS)&<_16(st_fx->clas_dec,INACTIVE_CLAS)) + { + st_fx->last_good_fx = VOICED_TRANSITION; + move16(); + } + + /* LSF estimation and A(z) calculation */ + lsf_dec_bfi( MODE1, lsf_new_fx, st_fx->lsf_old_fx, st_fx->lsf_adaptive_mean_fx, NULL, st_fx->mem_MA_fx, st_fx->mem_AR_fx, + st_fx->stab_fac_fx, st_fx->last_coder_type_fx, st_fx->L_frame, st_fx->last_good_fx, + st_fx->nbLostCmpt, 0, NULL, NULL, NULL, st_fx->hGSCDec->Last_GSC_pit_band_idx_fx, st_fx->Opt_AMR_WB, 0, st_fx->bwidth); + + FEC_lsf2lsp_interp( st_fx, st_fx->L_frame, Aq_fx, lsf_new_fx, lsp_new_fx ); + + IF ( st_fx->nelp_mode_dec_fx == 1 ) + { + /* SC-VBR */ + Scale_sig(exc_fx-L_EXC_MEM, L_EXC_MEM, -st_fx->Q_exc); + st_fx->Q_exc = 0; + move16(); + + decod_nelp_fx( st_fx, &tmp_noise_fx, pitch_buf_fx, exc_fx, exc2_fx, voice_factors, bwe_exc_fx, &st_fx->Q_exc, st_fx->bfi, gain_buf ); + FEC_pitch_fx = pitch_buf_fx[3]; + move16(); + + Rescale_exc(hMusicPF->dct_post_old_exc_fx, exc_fx, NULL, st_fx->hGSCDec->last_exc_dct_in_fx, L_FRAME, 0, (Word32)0, &(st_fx->Q_exc), st_fx->Q_subfr, exc2_fx, L_FRAME, st_fx->coder_type_fx ); + } + ELSE + { + /* calculation of excitation signal */ + + FEC_exc_estim_fx( st_fx, st_fx->L_frame, exc_fx, exc2_fx, dct_exc_tmp, pitch_buf_fx, voice_factors, &FEC_pitch_fx, bwe_exc_fx, lsf_new_fx, &st_fx->Q_exc, &tmp_noise_fx ); + + Rescale_exc( NULL, exc_fx, bwe_exc_fx, st_fx->hGSCDec->last_exc_dct_in_fx, st_fx->L_frame, L_FRAME32k, (Word32)0, + &(st_fx->Q_exc), st_fx->Q_subfr, exc2_fx, st_fx->L_frame, st_fx->last_coder_type_fx ); + + tmp_noise_fx = shr_r(st_fx->lp_gainc_fx,3); /*Q0*/ + + /* SC-VBR */ + st_fx->prev_gain_pit_dec_fx = st_fx->lp_gainp_fx; + move16(); /*Q14*/ + } + + /* synthesis for ACELP core switching and SWB BWE */ + syn_12k8_fx( st_fx->L_frame, Aq_fx, exc_fx, temp_buf_fx, st_fx->mem_syn1_fx, 1, st_fx->Q_exc, -1 ); /*old_syn_12k8_16k directly in q-1*/ + + /* save and delay synthesis to be used by SWB BWE */ + IF (hBWE_FD != NULL) + { + save_old_syn_fx( st_fx->L_frame, temp_buf_fx, old_syn_12k8_16k, hBWE_FD->old_syn_12k8_16k_fx, st_fx->preemph_fac, &hBWE_FD->mem_deemph_old_syn_fx ); + } + /* Apply energy matching when switching to inactive frames */ + Inac_swtch_ematch_fx( exc2_fx, dct_exc_tmp, st_fx->hGSCDec->lt_ener_per_band_fx, st_fx->coder_type_fx, st_fx->L_frame, st_fx->core_brate, st_fx->Q_exc, st_fx->bfi, st_fx->last_core, st_fx->last_codec_mode ); + + /* udate past excitation signals for LD music post-filter */ + IF (hMusicPF != NULL) + { + Copy(hMusicPF->dct_post_old_exc_fx + L_FRAME, hMusicPF->dct_post_old_exc_fx, DCT_L_POST-L_FRAME-OFFSET2 ); + Copy( exc2_fx, hMusicPF->dct_post_old_exc_fx + (DCT_L_POST-L_FRAME-OFFSET2), L_FRAME ); + /* Update music post processing values */ + /* Filter energies update */ + FOR(i = 0; i < DCT_L_POST; i++) + { + /*st_fx->filt_lfE_fx[i] = 0.3f + 0.7f * st_fx->filt_lfE_fx[i];*/ + hMusicPF->filt_lfE_fx[i] = round_fx(L_mac((1228 << (16)), 22938, hMusicPF->filt_lfE_fx[i])); + } + /* Update circular buffer, keep last energy difference unchanged */ + FOR(i = 1; i < MAX_LT; i++) + { + hMusicPF->LDm_lt_diff_etot_fx[i - 1] = hMusicPF->LDm_lt_diff_etot_fx[i]; + move16(); + } + } + /* synthesis at 12k8 Hz sampling rate */ + /* add extra headroom in case a CNA addition is likely (i.e. st_fx->psf_lp_noise_fx is close to the threshold) */ + k = 0; + move16(); + test(); + test(); + if( EQ_16(st_fx->coder_type_fx, INACTIVE)&&st_fx->flag_cna&&GE_16(round_fx(L_shl(st_fx->lp_noise,1)),15<<7)) + { + k = 1; + move16(); + } + + Rescale_mem( st_fx->Q_exc, &st_fx->prev_Q_syn, &st_fx->Q_syn, st_fx->mem_syn2_fx, st_fx->mem_syn_clas_estim_fx, 4, &st_fx->mem_deemph_fx, + hBPF->pst_old_syn_fx, &hBPF->pst_mem_deemp_err_fx, &st_fx->agc_mem_fx[1], st_fx->hPFstat, 1, k, temp_buf_fx ); + + if( (EQ_32(st_fx->total_brate,ACELP_7k20))||(EQ_32(st_fx->total_brate,ACELP_8k00))) + { + Copy( st_fx->mem_syn2_fx, mem_tmp_fx, M ); + } + syn_12k8_fx( st_fx->L_frame, Aq_fx, exc2_fx, syn_fx, st_fx->mem_syn2_fx, 1, st_fx->Q_exc, st_fx->Q_syn); + + /* update buffer for classifier */ + IF (st_fx->hWIDec != NULL) + { + Copy(exc2_fx + st_fx->L_frame - L_EXC_MEM, st_fx->hWIDec->old_exc2_fx, L_EXC_MEM); + Copy(syn_fx + st_fx->L_frame - L_EXC_MEM, st_fx->hWIDec->old_syn2_fx, L_EXC_MEM); + } + st_fx->prev_Q_exc_fr = st_fx->Q_exc; + st_fx->prev_Q_syn_fr = st_fx->Q_syn; + + Copy( syn_fx + st_fx->L_frame - L_SYN_MEM_CLAS_ESTIM, st_fx->mem_syn_clas_estim_fx, L_SYN_MEM_CLAS_ESTIM ); + + + + if( (EQ_32(st_fx->total_brate,ACELP_7k20))||(EQ_32(st_fx->total_brate,ACELP_8k00))) + { + k = 0; + move16(); + FOR (i = 0; i < st_fx->L_frame; i += L_SUBFR) + { + pitch_buf_tmp[k] = mult_r(pitch_buf_fx[k], 512); + move16(); + k++; + } + + /*------------------------------------------------------------* + * FEC - Smooth the speech energy evolution when recovering after a BAD frame + * (smoothing is performed in the excitation domain and signal is resynthesized after) + *------------------------------------------------------------*/ + + FEC_scale_syn_fx( st_fx->L_frame, &update_flg, st_fx->clas_dec, st_fx->last_good_fx, syn_fx, pitch_buf_tmp, st_fx->enr_old_fx, enr_q_fx, st_fx->coder_type_fx, LSF_Q_prediction, + &st_fx->scaling_flag, &st_fx->lp_ener_FEC_av, &st_fx->lp_ener_FEC_max, st_fx->bfi, st_fx->total_brate, st_fx->prev_bfi, st_fx->last_core_brate, + exc_fx, exc2_fx, Aq_fx, &st_fx->old_enr_LP, mem_tmp_fx, st_fx->mem_syn2_fx, st_fx->Q_exc, st_fx->Q_syn, avoid_lpc_burst_on_recovery, 0 ); + } + + /* estimate the pitch-synchronous speech energy per sample to be used when normal operation recovers */ + /* fer_energy( st_fx->L_frame, st_fx->last_good_fx, syn_fx, FEC_pitch_fx, &st_fx->enr_old_fx, st_fx->L_frame ); */ + frame_ener_fx( st_fx->L_frame, st_fx->last_good_fx, syn_fx, shr(add(FEC_pitch_fx,32),6), &st_fx->enr_old_fx, st_fx->L_frame, st_fx->Q_syn, 3, 0 ); + + IF ( st_fx->nelp_mode_dec_fx !=1 ) + { + /* modify the excitation signal of stationary unvoiced frames */ + stat_noise_uv_mod_fx( st_fx->coder_type_fx, 0, st_fx->lsp_old_fx, lsp_new_fx, lsp_new_fx, Aq_fx, exc2_fx, st_fx->Q_exc, 1, &st_fx->ge_sm_fx, + &st_fx->uv_count_fx, &st_fx->act_count_fx, st_fx->lspold_s_fx, &st_fx->noimix_seed_fx, &st_fx->min_alpha_fx, + &st_fx->exc_pe_fx, st_fx->core_brate,st_fx->bwidth, &st_fx->Q_stat_noise, &st_fx->Q_stat_noise_ge ); + } + + /* SC-VBR */ + st_fx->hSC_VBR->FadeScale_fx = mult(st_fx->hSC_VBR->FadeScale_fx,24576); /*24576 in Q15*/ + } + IF(hBWE_TD != NULL) + { + IF (EQ_16(st_fx->L_frame,L_FRAME)) + { + Copy( Aq_fx+2*(M+1), hBWE_TD->cur_sub_Aq_fx, (M+1) ); + } + ELSE + { + Copy( Aq_fx+3*(M+1), hBWE_TD->cur_sub_Aq_fx, (M+1) ); + } + } + /*--------------------------------------------------------* + * Apply NB postfilter in case of 8kHz output + *--------------------------------------------------------*/ + test(); + IF( EQ_16(st_fx->last_bwidth,NB) && st_fx->hPFstat != NULL) + { + k = 0; + move16(); + FOR (i = 0; i < st_fx->L_frame; i += L_SUBFR) + { + pitch_buf_tmp[k] = mult_r(pitch_buf_fx[k], 512); + move16(); + k++; + } + + IF(EQ_16(st_fx->bwidth,NB)) + { + st_fx->hPFstat->on = 1; + move16(); + nb_post_filt( st_fx->L_frame, st_fx->hPFstat, &st_fx->psf_lp_noise_fx, tmp_noise_fx, syn_fx, Aq_fx, pitch_buf_tmp, st_fx->coder_type_fx, st_fx->BER_detect, 0 ); + } + ELSE + { + st_fx->hPFstat->on = 0; + move16(); + nb_post_filt( st_fx->L_frame, st_fx->hPFstat, &st_fx->psf_lp_noise_fx, tmp_noise_fx, syn_fx, Aq_fx, pitch_buf_tmp, AUDIO, st_fx->BER_detect, 0 ); + } + } + ELSE + { + st_fx->psf_lp_noise_fx = round_fx(L_shl(st_fx->lp_noise,1)); + } + + /*------------------------------------------------------------------* + * Perform fixed deemphasis through 1/(1 - g*z^-1) + *-----------------------------------------------------------------*/ + + /* Update old synthesis buffer - needed for ACELP internal sampling rate switching */ + Copy( syn_fx + st_fx->L_frame - L_SYN_MEM, st_fx->mem_syn_r, L_SYN_MEM ); + deemph_fx( syn_fx, st_fx->preemph_fac, st_fx->L_frame, &(st_fx->mem_deemph_fx) ); + unscale_AGC( syn_fx, st_fx->Q_syn, syn_fx_tmp2, st_fx->agc_mem_fx, st_fx->L_frame ); + Copy(syn_fx_tmp2, syn_fx, st_fx->L_frame); + + /* Update MODE2 memories*/ + IF(hTcxDec != NULL) + { + Copy_Scale_sig( syn_fx + st_fx->L_frame/2, hTcxDec->old_syn_Overl, st_fx->L_frame/2, sub(-1,st_fx->Q_syn)); /*Q-1*/ + } + Copy_Scale_sig( syn_fx + st_fx->L_frame-M-1, st_fx->syn, M+1, sub(0,st_fx->Q_syn)); /*Q0*/ + + /*------------------------------------------------------------------* + * Formant post-filter + *-----------------------------------------------------------------*/ + + IF(st_fx->hPFstat != NULL) + { + test(); test(); test(); + IF(GE_16(st_fx->last_bwidth, WB) && (GT_32(st_fx->core_brate, ACELP_24k40) || GT_16(st_fx->element_mode, EVS_MONO)) && LE_32(st_fx->core_brate, ACELP_32k)) + { + Copy( syn_fx, temp_buf + L_SYN_MEM, L_FRAME16k ); + st_fx->hPFstat->on = 1; + move16(); + formant_post_filt( st_fx->hPFstat, temp_buf + L_SYN_MEM, Aq_fx, syn_fx, L_FRAME16k, st_fx->lp_noise, st_fx->total_brate, 0); + } + ELSE IF( GE_16(st_fx->last_bwidth,WB)) + { + if( st_fx->hPFstat->on ) + { + Copy( st_fx->hPFstat->mem_pf_in+L_SYN_MEM-M, temp_buf, M ); + Copy( syn_fx, temp_buf + M, L_SUBFR ); + Residu3_fx ( Aq_fx, temp_buf + M, temp_buf+M+L_SUBFR, L_SUBFR, 1 ); + E_UTIL_synthesis ( 1, Aq_fx, temp_buf+M+L_SUBFR, temp_buf, L_SUBFR, st_fx->hPFstat->mem_stp+L_SYN_MEM-M, 0, M ); + scale_st ( syn_fx, temp_buf, &st_fx->hPFstat->gain_prec, L_SUBFR ); + Copy( temp_buf, syn_fx, L_SUBFR/2 ); + blend_subfr2( temp_buf + L_SUBFR/2, syn_fx + L_SUBFR/2, syn_fx + L_SUBFR/2 ); + } + st_fx->hPFstat->on = 0; + move16(); + } + } + /*----------------------------------------------------------------* + * Comfort noise addition + *----------------------------------------------------------------*/ + + test(); + test(); + test(); + test(); + IF((st_fx->hFdCngDec_fx != NULL || EQ_16(st_fx->idchan, 1)) && NE_16(st_fx->element_mode, IVAS_CPE_MDCT)) + { + IF(EQ_16(st_fx->element_mode, IVAS_CPE_TD) || st_fx->flag_cna || (EQ_16(st_fx->cng_type, FD_CNG) && LE_32(st_fx->total_brate, ACELP_32k)) || (EQ_16(st_fx->cng_type, LP_CNG) && LE_32(st_fx->total_brate, SID_2k40))) + { + /*VAD only for non inactive frame*/ + test(); + st_fx->VAD = st_fx->VAD && (st_fx->coder_type_fx != INACTIVE); + + IF(st_fx->idchan == 0 && (st_fx->flag_cna || (EQ_16(st_fx->cng_type, FD_CNG) && LE_32(st_fx->total_brate, ACELP_32k)) || + (EQ_16(st_fx->cng_type, LP_CNG) && LE_32(st_fx->total_brate, SID_2k40)))) + { + /*Noisy speech detector*/ + noisy_speech_detection(st_fx->hFdCngDec_fx, st_fx->VAD, syn_fx, st_fx->Q_syn); + + st_fx->hFdCngDec_fx->hFdCngCom->likelihood_noisy_speech = mult_r(st_fx->hFdCngDec_fx->hFdCngCom->likelihood_noisy_speech, 32440/*0.99 Q15*/); + IF(st_fx->hFdCngDec_fx->hFdCngCom->flag_noisy_speech != 0) + { + st_fx->hFdCngDec_fx->hFdCngCom->likelihood_noisy_speech = add(st_fx->hFdCngDec_fx->hFdCngCom->likelihood_noisy_speech, 328/*0.01 Q15*/); + move16(); + } + } + IF(st_fx->idchan == 0) + { + st_fx->lp_noise = st_fx->hFdCngDec_fx->lp_noise; + move32(); + } + /*Noise estimate*/ + test(); + test(); + IF(NE_16(st_fx->element_mode, IVAS_CPE_TD)/* && !st->cng_ism_flag IVAS_CODE */ ) + { +#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT + PMT("Code for IVAS_CODE_CNG_FIX185_PLC_FADEOUT not done") + ApplyFdCng(syn, st_fx->Q_syn, NULL, realBuffer, imagBuffer, st, 0, (st->coder_type == AUDIO && !st->GSC_noisy_speech)); +#else + ApplyFdCng(syn_fx, st_fx->Q_syn, realBuffer, imagBuffer, NULL, st_fx, 0, (EQ_16(st_fx->coder_type_fx, AUDIO) && st_fx->GSC_noisy_speech_fx == 0)); +#endif + } + /* CNA: Generate additional comfort noise to mask potential coding artefacts */ + test(); + test(); + test(); + test(); +#ifdef IVAS_CODE + if (!st->cna_dirac_flag) + { + /* CNA: Generate additional comfort noise to mask potential coding artefacts */ + if (st->flag_cna && !(st->coder_type == AUDIO && !(st->element_mode > EVS_MONO && st->GSC_noisy_speech))) + { + if (st->element_mode == IVAS_CPE_TD && nchan_out == 2) + { + if (hStereoCng->flag_cna_fade) + { + generate_stereo_masking_noise(syn, st, hStereoTD, flag_sec_CNA, 1, hStereoCng, nchan_out); + hStereoCng->flag_cna_fade = 0; + } + else + { + if (st->element_mode != last_element_mode && st->idchan == 0) + { + /* Clear memory for secondary channel CNA */ + set_f(hStereoCng->olapBufferSynth22, 0.0f, st->hFdCngDec->hFdCngCom->frameSize / 2); + } + + generate_stereo_masking_noise(syn, st, hStereoTD, flag_sec_CNA, 0, hStereoCng, nchan_out); + } + } + else if (st->element_mode != IVAS_CPE_DFT) + { + if (st->idchan == 0) + { + if (st->element_mode != last_element_mode) + { + set_f(st->hFdCngDec->hFdCngCom->olapBufferSynth2, 0.0f, st->hFdCngDec->hFdCngCom->fftlen); + } + generate_masking_noise(syn, st->hFdCngDec->hFdCngCom, st->hFdCngDec->hFdCngCom->frameSize, 0, 0, 0, st->element_mode, hStereoCng, nchan_out); + } + } + } + else if (st->flag_cna && st->coder_type == AUDIO && ((st->last_core == ACELP_CORE && !(st->last_coder_type == AUDIO && !(st->element_mode > EVS_MONO && st->Last_GSC_noisy_speech_flag))) || st->last_core == TCX_20_CORE)) + { + if (st->element_mode == IVAS_CPE_TD && nchan_out == 2) + { + generate_stereo_masking_noise(syn, st, hStereoTD, flag_sec_CNA, 1, hStereoCng, nchan_out); + hStereoCng->flag_cna_fade = 1; + } + else + { + v_multc(st->hFdCngDec->hFdCngCom->olapBufferSynth2 + 5 * st->hFdCngDec->hFdCngCom->frameSize / 4, (float)(st->hFdCngDec->hFdCngCom->fftlen / 2), temp_buf, st->hFdCngDec->hFdCngCom->frameSize / 2); + v_add(temp_buf, syn, syn, st->hFdCngDec->hFdCngCom->frameSize / 2); + } + } + else + { + if (hStereoCng != NULL) + { + hStereoCng->flag_cna_fade = 1; + hStereoCng->enableSecCNA = 0; + } + } + + if (st->element_mode == IVAS_CPE_TD) + { + /*Noise estimate*/ + if (st->idchan == 0 && (nchan_out == 2 || (st->core_brate != FRAME_NO_DATA && st->core_brate != SID_2k40))) + { +#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT + ApplyFdCng(syn, st_fx->Q_syn, realBuffer, imagBuffer, NULL, st, 0, (st->coder_type == AUDIO && !st->GSC_noisy_speech)); +#else + ApplyFdCng(syn, st_fx->Q_syn, realBuffer, imagBuffer, NULL, st, 0, (st->coder_type == AUDIO && !st->GSC_noisy_speech)); +#endif + } + } + } + } + + if (!st->cna_dirac_flag) + { + if (st->flag_cna == 0 && st->L_frame == L_FRAME16k && st->last_flag_cna == 1 && ((st->last_core == ACELP_CORE && !(st->last_coder_type == AUDIO && !(st->element_mode > EVS_MONO && st->Last_GSC_noisy_speech_flag))) || st->last_core == AMR_WB_CORE)) + { + v_multc(st->hFdCngDec->hFdCngCom->olapBufferSynth2 + 5 * st->L_frame / 4, 256.f, temp_buf, st->L_frame / 2); + v_add(temp_buf, syn, syn, st->L_frame / 2); + } + + if (st->flag_cna == 0 || (st->coder_type == AUDIO && !(st->element_mode > EVS_MONO && st->GSC_noisy_speech))) + { + if (st->idchan == 0) + { + set_f(st->hFdCngDec->hFdCngCom->olapBufferSynth2, 0.f, st->hFdCngDec->hFdCngCom->fftlen); + } + if (hStereoCng != NULL && st->idchan == 0) + { + set_f(hStereoCng->olapBufferSynth22, 0.f, st->hFdCngDec->hFdCngCom->fftlen); + } + } + } +#else + IF(st_fx->flag_cna && NE_16(st_fx->coder_type_fx, AUDIO)) + { + generate_masking_noise(syn_fx, st_fx->Q_syn, st_fx->hFdCngDec_fx->hFdCngCom, st_fx->hFdCngDec_fx->hFdCngCom->frameSize, 0); + } + ELSE IF(st_fx->flag_cna && st_fx->coder_type_fx == AUDIO && st_fx->last_core == ACELP_CORE && st_fx->last_coder_type_fx != AUDIO) + { + FOR(i = 0; i < st_fx->hFdCngDec_fx->hFdCngCom->frameSize / 2; i++) + { + syn_fx[i] = add(syn_fx[i], shr_r(mult_r(st_fx->hFdCngDec_fx->hFdCngCom->olapBufferSynth2[i + 5 * st_fx->hFdCngDec_fx->hFdCngCom->frameSize / 4], st_fx->hFdCngDec_fx->hFdCngCom->fftlenFac), -st_fx->Q_syn)); + move16(); + } + } + } + + IF(st_fx->flag_cna == 0 && EQ_16(st_fx->L_frame, L_FRAME16k) && st_fx->last_flag_cna == 1 && ((st_fx->last_core == ACELP_CORE && st_fx->last_coder_type_fx != AUDIO) || st_fx->last_core == AMR_WB_CORE)) + { + FOR(i = 0; i < st_fx->L_frame / 2; i++) + { + syn_fx[i] = add(syn_fx[i], shr_r(st_fx->hFdCngDec_fx->hFdCngCom->olapBufferSynth2[i + 5 * st_fx->L_frame / 4], -st_fx->Q_syn)); + move16(); + } + } + + test(); + IF(st_fx->flag_cna == 0 || EQ_16(st_fx->coder_type_fx, AUDIO)) + { + set16_fx(st_fx->hFdCngDec_fx->hFdCngCom->olapBufferSynth2, 0, st_fx->hFdCngDec_fx->hFdCngCom->fftlen); + } +#endif + } + /*----------------------------------------------------------------* + * Resample to the output sampling rate (8/16/32/48 kHz) + * Bass post-filter + *----------------------------------------------------------------*/ + + /* check if the CLDFB works on the right sample rate */ + IF( (st_fx->cldfbAna_fx->usb * st_fx->cldfbAna_fx->no_col) != st_fx->L_frame ) + { + /* resample to ACELP internal sampling rate */ + Word16 newCldfbBands = CLDFB_getNumChannels(L_mult0(st_fx->L_frame, FRAMES_PER_SEC)); + resampleCldfb( st_fx->cldfbAna_fx, newCldfbBands, st_fx->L_frame, 0 ); + resampleCldfb( st_fx->cldfbBPF_fx, newCldfbBands, st_fx->L_frame, 0 ); + + if( st_fx->ini_frame > 0 ) + { + st_fx->cldfbSyn_fx->bandsToZero = sub(st_fx->cldfbSyn_fx->no_channels,st_fx->cldfbAna_fx->no_channels); + } + } +#ifdef ADD_LRTD + /* analyze pitch coherence for bass post-filter */ + bpf_pitch_coherence(st, pitch_buf); +#endif + IF(!(EQ_16(st_fx->element_mode, IVAS_CPE_MDCT) && st_fx->bpf_off)) + { + test(); + IF( NE_16(st_fx->L_frame,st_fx->last_L_frame)&&NE_16(st_fx->last_codec_mode,MODE2)) + { + IF( EQ_16(st_fx->L_frame,L_FRAME)) + { + retro_interp5_4_fx(hBPF->pst_old_syn_fx ); + } + ELSE IF( EQ_16(st_fx->L_frame,L_FRAME16k)) + { + retro_interp4_5_fx( syn_fx, hBPF->pst_old_syn_fx ); + } + } + + bass_psfilter_fx(st_fx->hBPF, st_fx->Opt_AMR_WB, syn_fx, st_fx->L_frame, pitch_buf_fx, st_fx->bpf_off, + st_fx->stab_fac_fx, &st_fx->stab_fac_smooth_fx, st_fx->coder_type_fx, st_fx->Q_syn, bpf_error_signal ); + } + test(); + IF (NE_16(st_fx->element_mode, IVAS_CPE_DFT) || use_cldfb_for_dft) + { +#ifdef IVAS_CODE + float realBufferSave[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + float imagBufferSave[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + float* pRealSave[CLDFB_NO_COL_MAX], * pImagSave[CLDFB_NO_COL_MAX]; + for (i = 0; i < CLDFB_NO_COL_MAX; i++) + { + pRealSave[i] = realBufferSave[i]; + pImagSave[i] = imagBufferSave[i]; + } + if (st->p_bpf_noise_buf) + { + mvr2r(bpf_error_signal, st->p_bpf_noise_buf, st->L_frame); + } +#endif + /* analysis of the synthesis at internal sampling rate */ + cldfbAnalysisFiltering( st_fx->cldfbAna_fx, realBuffer, imagBuffer, &scaleFactor, syn_fx, negate(st_fx->Q_syn), CLDFB_NO_COL_MAX, workBuffer); + + scaleFactor.hb_scale = scaleFactor.lb_scale; + move16(); + + /* analysis and add the BPF error signal */ + i = 0; + move16(); + if( st_fx->bpf_off == 0 ) + { + i = CLDFB_NO_COL_MAX; + move16(); + } + addBassPostFilterFx( bpf_error_signal, realBuffer, imagBuffer, st_fx->cldfbBPF_fx, workBuffer, negate(st_fx->Q_syn), + i, st_fx->cldfbAna_fx->no_col, st_fx->cldfbAna_fx->no_channels, &scaleFactor ); + + /* set output mask for upsampling */ + IF( EQ_16(st_fx->bwidth,NB)) + { + /* set NB mask for upsampling */ + st_fx->cldfbSyn_fx->bandsToZero = sub(st_fx->cldfbSyn_fx->no_channels,10); + } + ELSE if( NE_16(st_fx->cldfbSyn_fx->bandsToZero,sub(st_fx->cldfbSyn_fx->no_channels,st_fx->cldfbAna_fx->no_channels))) + { + /* in case of BW switching, re-init to default */ + st_fx->cldfbSyn_fx->bandsToZero = sub(st_fx->cldfbSyn_fx->no_channels, st_fx->cldfbAna_fx->no_channels); + } + + /*WB/SWB-FD_CNG*/ + scaleFactor.hb_scale = scaleFactor.lb_scale; + move16(); + + test(); + test(); + test(); + IF(!st_fx->cng_sba_flag || EQ_16(st_fx->element_mode, IVAS_CPE_MDCT)) + { + IF((EQ_32(st_fx->core_brate, FRAME_NO_DATA) || EQ_32(st_fx->core_brate, SID_2k40)) && (EQ_16(st_fx->cng_type, FD_CNG)) && (LT_16(st_fx->hFdCngDec_fx->hFdCngCom->numCoreBands, st_fx->cldfbSyn_fx->no_channels))) + { + generate_comfort_noise_dec_hf(realBuffer, imagBuffer, &scaleFactor.hb_scale, st_fx); + + st_fx->cldfbSyn_fx->bandsToZero = 0; + move16(); + if (LT_16(st_fx->hFdCngDec_fx->hFdCngCom->regularStopBand, st_fx->cldfbSyn_fx->no_channels)) + { + st_fx->cldfbSyn_fx->bandsToZero = sub(st_fx->cldfbSyn_fx->no_channels, st_fx->hFdCngDec_fx->hFdCngCom->regularStopBand); + } + st_fx->cldfbSyn_fx->lsb = st_fx->cldfbAna_fx->no_channels; + move16(); + } + } + /* synthesis of the combined signal */ + st_fx->Q_syn2 = st_fx->Q_syn; + move16(); +#ifdef IVAS_CODE + if (save_hb_synth != NULL) + { + /* save and then zero-out lowband */ + for (int16_t j = 0; j < CLDFB_NO_CHANNELS_MAX; j++) + { + for (i = 0; i < CLDFB_NO_COL_MAX; i++) + { + realBufferSave[i][j] = realBuffer[i][j]; + imagBufferSave[i][j] = imagBuffer[i][j]; + if (j < st->hFdCngDec->hFdCngCom->numCoreBands && i < st->hFdCngDec->hFdCngCom->numSlots) + { + realBuffer[i][j] = 0.0f; + imagBuffer[i][j] = 0.0f; + } + } + } + + cldfbSynthesis(realBuffer, imagBuffer, save_hb_synth, -1, st->cldfbSynHB); + + /* restore lowband */ + for (int16_t j = 0; j < CLDFB_NO_CHANNELS_MAX; j++) + { + for (i = 0; i < CLDFB_NO_COL_MAX; i++) + { + realBuffer[i][j] = realBufferSave[i][j]; + imagBuffer[i][j] = imagBufferSave[i][j]; + } + } + + cldfbSynthesis(pRealSave, pImagSave, synth, -1, st->cldfbSyn); + } + else +#endif + { + cldfbSynthesisFiltering(st_fx->cldfbSyn_fx, realBuffer, imagBuffer, &scaleFactor, synth_out, negate(st_fx->Q_syn2), CLDFB_NO_COL_MAX, workBuffer); + } + /* Bring CLDFB output to Q0 */ + Scale_sig(synth_out, output_frame, negate(st_fx->Q_syn2)); + st_fx->Q_syn2 = 0; + move16(); + + /* save synthesis - needed in case of core switching */ + Copy( synth_out, st_fx->previoussynth_fx, output_frame ); + } +#ifdef IVAS_CODE + ELSE + { + int16_t nSamples = NS2SA(st->L_frame * FRAMES_PER_SEC, FRAME_SIZE_NS /*DELAY_CLDFB_NS*/); /* IVAS-64: optimization is likely possible here (don't resample the whole frame) */ + + /* analysis of the synthesis at internal sampling rate - needed for DFT stereo -> TD stereo switching */ + cldfbAnalysis(syn + st->L_frame - nSamples, realBuffer, imagBuffer, nSamples, st->cldfbAna); + + /* analysis and add the BPF error signal - needed for DFT stereo -> TD stereo switching */ + addBassPostFilter(bpf_error_signal + st->L_frame - nSamples, st->bpf_off ? 0 : nSamples, realBuffer, imagBuffer, st->cldfbBPF); + + /* synthesis of the combined signal - needed for DFT stereo -> TD stereo switching */ + cldfbSynthesis(realBuffer, imagBuffer, synth /*dummy*/, NS2SA(st->output_Fs, FRAME_SIZE_NS /*DELAY_CLDFB_NS*/), st->cldfbSyn); + + if (st->p_bpf_noise_buf) + { + mvr2r(bpf_error_signal, st->p_bpf_noise_buf, st->L_frame); + } + + set_f(synth, 0.0f, output_frame); + } + + /* Copy output signal */ + if (st->element_mode > EVS_MONO) + { + mvr2r(syn, output, st->L_frame); + } +#endif + /*-----------------------------------------------------------------* + * Bandwidth extension 6kHz-7kHz + *-----------------------------------------------------------------*/ + IF(st_fx->hBWE_zero != NULL) + { + test(); test(); test(); test(); test(); test(); test(); + IF( (EQ_16(st_fx->L_frame,L_FRAME)&&NE_16(st_fx->bwidth,NB)&&GE_16(output_frame,L_FRAME16k)&& + ( EQ_16(st_fx->extl,-1) || EQ_16(st_fx->extl,SWB_CNG) || (EQ_16(st_fx->extl,WB_BWE) && st_fx->extl_brate == 0 && NE_16(st_fx->coder_type_fx,AUDIO) )) ) ) + { + hf_synth_fx( st_fx->hBWE_zero, st_fx->core_brate, output_frame, Aq_fx, exc2_fx, syn_fx, synth_out, st_fx->Q_exc, + st_fx->Q_syn2, st_fx->hBWE_zero->delay_syn_hf_fx, &hBWE_FD->memExp1, st_fx->hBWE_zero->mem_hp_interp_fx, st_fx->extl, st_fx->CNG_mode ); + } + ELSE + { + hf_synth_reset_fx( st_fx->hBWE_zero ); + } + } + + /*-----------------------------------------------------------------* + * Populate parameters for SWB TBE + *-----------------------------------------------------------------*/ + + /* Apply a non linearity to the SHB excitation */ + IF(hBWE_TD != NULL) + { + test(); test(); test(); test(); test(); test(); test(); test(); test(); test(); + IF((!st_fx->bfi && (st_fx->prev_bfi)) || ((EQ_16(st_fx->last_vbr_hw_BWE_disable_dec_fx, 1)) && (st_fx->vbr_hw_BWE_disable_dec_fx == 0)) || ((EQ_16(st_fx->extl, SWB_TBE) || EQ_16(st_fx->extl, WB_TBE) || EQ_16(st_fx->extl, FB_TBE)) + && NE_16(st_fx->last_extl, SWB_TBE) && NE_16(st_fx->last_extl, WB_TBE) && NE_16(st_fx->last_extl, FB_TBE)) + || (EQ_16(st_fx->idchan, 1) && EQ_16(st_fx->element_mode, IVAS_CPE_TD) && !st_fx->tdm_LRTD_flag)) + { + hBWE_TD->bwe_non_lin_prev_scale_fx = L_deposit_l(0); + set16_fx(hBWE_TD->old_bwe_exc_extended_fx, 0, NL_BUFF_OFFSET ); + } + + + IF(!st_fx->ppp_mode_dec_fx && (st_fx->idchan == 0 || NE_16(st_fx->element_mode, IVAS_CPE_TD) || (EQ_16(st_fx->idchan, 1) && EQ_16(st_fx->element_mode, IVAS_CPE_TD) && st_fx->tdm_LRTD_flag))) + { + non_linearity_fx(bwe_exc_fx, bwe_exc_extended, L_FRAME32k, &hBWE_TD->bwe_non_lin_prev_scale_fx, st_fx->Q_exc, + st_fx->coder_type_fx, voice_factors, st_fx->L_frame); + } + + test(); + IF( EQ_32(st_fx->core_brate,FRAME_NO_DATA)||EQ_32(st_fx->core_brate,SID_2k40)) + { + hBWE_TD->bwe_non_lin_prev_scale_fx = L_deposit_l(0); + } + } + /*----------------------------------------------------------------------* + * Updates + *----------------------------------------------------------------------*/ + + updt_dec_fx( st_fx, old_exc_fx, pitch_buf_fx, Es_pred_fx, Aq_fx, lsf_new_fx, lsp_new_fx, voice_factors, old_bwe_exc_fx, gain_buf ); + + IF( GT_32(st_fx->core_brate,SID_2k40) && st_fx->hTdCngDec != NULL && st_fx->hFdCngDec_fx != NULL) + { + /* update CNG parameters in active frames */ + cng_params_upd_fx( lsp_new_fx, exc_fx, st_fx->L_frame, &st_fx->hTdCngDec->ho_circ_ptr_fx, st_fx->hTdCngDec->ho_ener_circ_fx, &st_fx->hTdCngDec->ho_circ_size_fx, st_fx->hTdCngDec->ho_lsp_circ_fx, + st_fx->Q_exc, DEC, st_fx->hTdCngDec->ho_env_circ_fx, NULL, NULL, NULL, NULL, st_fx->last_active_brate ); + /* Set 16k LSP flag for CNG buffer */ + st_fx->hTdCngDec->ho_16k_lsp_fx[st_fx->hTdCngDec->ho_circ_ptr_fx] = 0; + move16(); + if (NE_16(st_fx->L_frame, L_FRAME)) + { + st_fx->hTdCngDec->ho_16k_lsp_fx[st_fx->hTdCngDec->ho_circ_ptr_fx] = 1; + move16(); + } + } + + return IVAS_ERR_OK; + +} diff --git a/lib_dec/acelp_core_switch_dec.c b/lib_dec/acelp_core_switch_dec.c index 3269f3278b5545c976bfe9297fd31bc86054375b..e0830d608bc2bfc4f94a1ddf2a94773197321a88 100644 --- a/lib_dec/acelp_core_switch_dec.c +++ b/lib_dec/acelp_core_switch_dec.c @@ -155,7 +155,7 @@ ivas_error acelp_core_switch_dec( * Excitation decoding *----------------------------------------------------------------*/ - config_acelp1( DEC, st->total_brate, cbrate, st->core, -1, -1, st->last_L_frame, -1, &( st->acelp_cfg ), st->next_bit_pos, GENERIC, -1, -1, &decode_bwe /* dummy */, &i, st->element_mode, &i /*dummy*/, 0, 0, st->idchan, st->active_cnt, 0, 0, 0 /*st->GSC_IVAS_mode*/ ); + config_acelp1_IVAS( DEC, st->total_brate, cbrate, st->core, -1, -1, st->last_L_frame, -1, &( st->acelp_cfg ), st->next_bit_pos, GENERIC, -1, -1, &decode_bwe /* dummy */, &i, st->element_mode, &i /*dummy*/, 0, 0, st->idchan, st->active_cnt, 0, 0, 0 /*st->GSC_IVAS_mode*/ ); decod_gen_voic_core_switch( st, L_frame_for_cs, 0, Aq, exc, cbrate ); @@ -176,7 +176,7 @@ ivas_error acelp_core_switch_dec( pitch_buf_tmp[i] = L_SUBFR; } - nb_post_filt( 2 * L_SUBFR, L_SUBFR, st->hPFstat, &tmp_noise, 0, synth_intFreq, Aq, pitch_buf_tmp, AUDIO, st->BER_detect, 0 ); + nb_post_filt_ivas( 2 * L_SUBFR, L_SUBFR, st->hPFstat, &tmp_noise, 0, synth_intFreq, Aq, pitch_buf_tmp, AUDIO, st->BER_detect, 0 ); } if ( L_frame_for_cs == L_FRAME ) @@ -196,15 +196,15 @@ ivas_error acelp_core_switch_dec( mvr2r( synth_intFreq, bpf_error_signal + M, L_SUBFR ); residu( Aq, M, bpf_error_signal + M, old_exc, L_SUBFR ); syn_filt( Aq, M, old_exc, bpf_error_signal, L_SUBFR, st->hPFstat->mem_stp_flt + L_SYN_MEM - M, 0 ); - scale_st( synth_intFreq, bpf_error_signal, &st->hPFstat->gain_prec_flt, L_SUBFR, -1 ); + scale_st_ivas( synth_intFreq, bpf_error_signal, &st->hPFstat->gain_prec_flt, L_SUBFR, -1 ); mvr2r( bpf_error_signal, synth_intFreq, L_SUBFR / 2 ); - blend_subfr2( bpf_error_signal + L_SUBFR / 2, synth_intFreq + L_SUBFR / 2, synth_intFreq + L_SUBFR / 2 ); + blend_subfr2_flt( bpf_error_signal + L_SUBFR / 2, synth_intFreq + L_SUBFR / 2, synth_intFreq + L_SUBFR / 2 ); } st->hPFstat->on = 0; if ( st->flag_cna ) { - generate_masking_noise( synth_intFreq, st->hFdCngDec->hFdCngCom, 2 * L_SUBFR, 0, 0, 0, st->element_mode, NULL, nchan_out ); + generate_masking_noise_flt( synth_intFreq, st->hFdCngDec->hFdCngCom, 2 * L_SUBFR, 0, 0, 0, st->element_mode, NULL, nchan_out ); } /*----------------------------------------------------------------* @@ -216,31 +216,31 @@ ivas_error acelp_core_switch_dec( bass_psfilter( st->hBPF, st->Opt_AMR_WB, synth_intFreq, 2 * L_SUBFR, NULL, st->bpf_off, st->stab_fac, &st->stab_fac_smooth, GENERIC, bpf_error_signal ); /* CLDFB analysis of the synthesis at internal sampling rate */ - if ( ( error = cldfb_save_memory( st->cldfbAna ) ) != IVAS_ERR_OK ) + if ( ( error = cldfb_save_memory_ivas( st->cldfbAna ) ) != IVAS_ERR_OK ) { return error; } - cldfbAnalysis( synth_intFreq, realBuffer, imagBuffer, NS2SA( L_frame_for_cs * FRAMES_PER_SEC, SWITCH_GAP_LENGTH_NS + DELAY_CLDFB_NS ), st->cldfbAna ); - cldfb_restore_memory( st->cldfbAna ); + cldfbAnalysis_ivas( synth_intFreq, realBuffer, imagBuffer, NS2SA( L_frame_for_cs * FRAMES_PER_SEC, SWITCH_GAP_LENGTH_NS + DELAY_CLDFB_NS ), st->cldfbAna ); + cldfb_restore_memory_ivas( st->cldfbAna ); /* CLDFB analysis and add the BPF error signal */ - if ( ( error = cldfb_save_memory( st->cldfbBPF ) ) != IVAS_ERR_OK ) + if ( ( error = cldfb_save_memory_ivas( st->cldfbBPF ) ) != IVAS_ERR_OK ) { return error; } addBassPostFilter( bpf_error_signal, st->bpf_off ? 0 : NS2SA( L_frame_for_cs * FRAMES_PER_SEC, SWITCH_GAP_LENGTH_NS + DELAY_CLDFB_NS ), realBuffer, imagBuffer, st->cldfbBPF ); - cldfb_restore_memory( st->cldfbBPF ); + cldfb_restore_memory_ivas( st->cldfbBPF ); /* CLDFB synthesis of the combined signal */ - if ( ( error = cldfb_save_memory( st->cldfbSyn ) ) != IVAS_ERR_OK ) + if ( ( error = cldfb_save_memory_ivas( st->cldfbSyn ) ) != IVAS_ERR_OK ) { return error; } - cldfbSynthesis( realBuffer, imagBuffer, synth_subfr_out, NS2SA( st->output_Fs, SWITCH_GAP_LENGTH_NS + DELAY_CLDFB_NS ), st->cldfbSyn ); - cldfb_restore_memory( st->cldfbSyn ); + cldfbSynthesis_ivas( realBuffer, imagBuffer, synth_subfr_out, NS2SA( st->output_Fs, SWITCH_GAP_LENGTH_NS + DELAY_CLDFB_NS ), st->cldfbSyn ); + cldfb_restore_memory_ivas( st->cldfbSyn ); mvr2r( synth_intFreq + NS2SA( L_frame_for_cs * FRAMES_PER_SEC, SWITCH_GAP_LENGTH_NS - DELAY_CLDFB_NS ) - 2, mem_synth, NS2SA( L_frame_for_cs * FRAMES_PER_SEC, DELAY_CLDFB_NS ) + 2 ); /* need for switching (-2 is due to 0 delay filtering) */ @@ -419,9 +419,9 @@ ivas_error acelp_core_switch_dec_bfi( mvr2r( st->mem_MA, tmp_float2, M ); /* LSF estimation and A(z) calculation */ - lsf_dec_bfi( MODE1, lsf_new, st->lsf_old, st->lsf_adaptive_mean, NULL, st->mem_MA, st->mem_AR, st->stab_fac, st->last_coder_type, st->L_frame, st->last_good, st->nbLostCmpt, 0, NULL, NULL, NULL, st->hGSCDec->Last_GSC_pit_band_idx, st->Opt_AMR_WB, st->bwidth ); + lsf_dec_bfi_flt( MODE1, lsf_new, st->lsf_old, st->lsf_adaptive_mean, NULL, st->mem_MA, st->mem_AR, st->stab_fac, st->last_coder_type, st->L_frame, st->last_good, st->nbLostCmpt, 0, NULL, NULL, NULL, st->hGSCDec->Last_GSC_pit_band_idx, st->Opt_AMR_WB, st->bwidth ); - FEC_lsf2lsp_interp( st, st->L_frame, Aq, lsf_new, lsp_new ); + FEC_lsf2lsp_interp_flt( st, st->L_frame, Aq, lsf_new, lsp_new ); mvr2r( tmp_float, st->mem_AR, M ); mvr2r( tmp_float2, st->mem_MA, M ); @@ -506,22 +506,22 @@ ivas_error acelp_core_switch_dec_bfi( *----------------------------------------------------------------*/ /* CLDFB analysis of the synthesis at internal sampling rate */ - if ( ( error = cldfb_save_memory( st->cldfbAna ) ) != IVAS_ERR_OK ) + if ( ( error = cldfb_save_memory_ivas( st->cldfbAna ) ) != IVAS_ERR_OK ) { return error; } - cldfbAnalysis( syn, realBuffer, imagBuffer, st->L_frame / 2, st->cldfbAna ); - cldfb_restore_memory( st->cldfbAna ); + cldfbAnalysis_ivas( syn, realBuffer, imagBuffer, st->L_frame / 2, st->cldfbAna ); + cldfb_restore_memory_ivas( st->cldfbAna ); /* CLDFB synthesis of the combined signal */ - if ( ( error = cldfb_save_memory( st->cldfbSyn ) ) != IVAS_ERR_OK ) + if ( ( error = cldfb_save_memory_ivas( st->cldfbSyn ) ) != IVAS_ERR_OK ) { return error; } - cldfbSynthesis( realBuffer, imagBuffer, st->hHQ_core->fer_samples, (int16_t) ( st->output_Fs * 0.01f ), st->cldfbSyn ); - cldfb_restore_memory( st->cldfbSyn ); + cldfbSynthesis_ivas( realBuffer, imagBuffer, st->hHQ_core->fer_samples, (int16_t) ( st->output_Fs * 0.01f ), st->cldfbSyn ); + cldfb_restore_memory_ivas( st->cldfbSyn ); return error; } @@ -570,13 +570,13 @@ static void decod_gen_voic_core_switch( * Decode pitch lag *----------------------------------------------------------------------*/ - pitch = pit_decode( st, core_brate, 0, L_frame, 0, GENERIC, &pitch_limit_flag, &T0, &T0_frac, &T0_min, &T0_max, L_SUBFR, 0, NULL ); + pitch = pit_decode_flt( st, core_brate, 0, L_frame, 0, GENERIC, &pitch_limit_flag, &T0, &T0_frac, &T0_min, &T0_max, L_SUBFR, 0, NULL ); /*--------------------------------------------------------------* * Find the adaptive codebook vector. *--------------------------------------------------------------*/ - pred_lt4( &exc[0], &exc[0], T0, T0_frac, L_SUBFR + 1, inter4_2, L_INTERPOL2, PIT_UP_SAMP ); + pred_lt4_flt( &exc[0], &exc[0], T0, T0_frac, L_SUBFR + 1, inter4_2, L_INTERPOL2, PIT_UP_SAMP ); /*--------------------------------------------------------------* * LP filtering of the adaptive excitation @@ -625,7 +625,7 @@ static void decod_gen_voic_core_switch( * long term prediction on the 2nd sub frame *-----------------------------------------------------------------*/ - pred_lt4( &exc[L_SUBFR], &exc[L_SUBFR], T0, T0_frac, L_SUBFR + 1, inter4_2, L_INTERPOL2, PIT_UP_SAMP ); + pred_lt4_flt( &exc[L_SUBFR], &exc[L_SUBFR], T0, T0_frac, L_SUBFR + 1, inter4_2, L_INTERPOL2, PIT_UP_SAMP ); for ( i = 0; i < L_SUBFR; i++ ) { diff --git a/lib_dec/acelp_core_switch_dec_fx.c b/lib_dec/acelp_core_switch_dec_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..cda82ed5c548eb71b69c8edd0167471591a6dfc4 --- /dev/null +++ b/lib_dec/acelp_core_switch_dec_fx.c @@ -0,0 +1,734 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include +#include "options.h" /* Compilation switches */ +#include "cnst.h" /* Common constants */ +#include "rom_com.h" /* Static table prototypes */ +#include "prot_fx1.h" /* Function prototypes */ +#include "prot_fx2.h" /* Function prototypes */ + +/*---------------------------------------------------------------------* + * Local function prototypes + *---------------------------------------------------------------------*/ + +static void decod_gen_voic_core_switch_fx( Decoder_State *st_fx, const Word16 L_frame, const Word16 sharpFlag, const Word16 *Aq, + Word16 *exc, const Word32 core_brate, Word16 *Q_exc ); + +/*-------------------------------------------------------------------* +* acelp_core_switch_dec() +* +* ACELP core decoder in the first ACELP->HQ switching frame +*-------------------------------------------------------------------*/ + +ivas_error acelp_core_switch_dec_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + Word16 *synth_subfr_out, /* o : synthesized ACELP subframe Q_syn*/ + Word16 *tmp_synth_bwe, /* o : synthesized ACELP subframe BWE Q_syn*/ + const Word16 output_frame, /* i : input frame length */ + const Word16 core_switching_flag, /* i : core switching flag */ + Word16 *mem_synth, /* o : synthesis to overlap */ + Word16 *Q_syn +) +{ + Word16 i, delta, L_frame_for_cs, decode_bwe, tmp; + Word16 d1m, ind1, fdelay, gapsize; + Word32 cbrate; + Word16 synth_intFreq[2*L_SUBFR]; + CLDFB_SCALE_FACTOR scaleFactor; + Word32 workBuffer[128*3]; + Word16 old_exc[L_EXC_DEC], *exc; + Word16 tmp_mem2[2*L_FILT48k], gain; + Word16 hb_synth_tmp[NS2SA(48000,10000000)]; + const Word16 *hp_filter; + Word16 Aq[2*(M+1)]; + Word16 bpf_error_signal[2*L_SUBFR]; + Word16 *pt1, *pt2; + Word16 syn_fx_tmp[L_FRAME_16k]; + Word32 *realBuffer[CLDFB_NO_COL_MAX_SWITCH], *imagBuffer[CLDFB_NO_COL_MAX_SWITCH]; + Word32 realBufferTmp[CLDFB_NO_COL_MAX_SWITCH][CLDFB_NO_CHANNELS_MAX], imagBufferTmp[CLDFB_NO_COL_MAX_SWITCH][CLDFB_NO_CHANNELS_MAX]; + BPF_DEC_HANDLE hBPF; + hBPF = st_fx->hBPF; + + ivas_error error; + error = IVAS_ERR_OK; + + FOR( i=0; iold_Aq_12_8_fx, Aq, M+1 ); + Copy( st_fx->old_Aq_12_8_fx, Aq + (M+1), M+1 ); + + set16_fx( mem_synth, 0, NS2SA(16000, DELAY_CLDFB_NS)+2 ); + set16_fx( synth_subfr_out, 0, SWITCH_MAX_GAP ); /* avoid valgrind complaining about uninitialized memory in core_switching_OLA_fx() */ + + /* set multiplication factor according to the sampling rate */ + delta = 1; + if( GT_16(output_frame, L_FRAME16k)) + { + delta = shr(output_frame,8); + } + + /*----------------------------------------------------------------* + * set switching frame bitrate + *----------------------------------------------------------------*/ + + test(); + test(); + test(); + IF( core_switching_flag && EQ_16(st_fx->last_L_frame, st_fx->last_L_frame_ori)&&((EQ_16(st_fx->last_core,ACELP_CORE))||(EQ_16(st_fx->last_core,AMR_WB_CORE)))) + { + exc = old_exc + L_EXC_MEM_DEC; + Copy( st_fx->old_exc_fx, old_exc, L_EXC_MEM_DEC ); /*scaling of exc from previous frame*/ + + IF( EQ_16(st_fx->last_L_frame, L_FRAME)) + { + cbrate = L_add(st_fx->core_brate, 0); + if( GT_32(cbrate, ACELP_24k40)) + { + cbrate = L_add(ACELP_24k40, 0); + } + + L_frame_for_cs = L_FRAME; + move16(); + } + ELSE + { + IF( LE_32(st_fx->core_brate, ACELP_8k00)) + { + cbrate = L_add(ACELP_8k00, 0); + } + ELSE IF( LE_32(st_fx->core_brate, ACELP_14k80)) + { + cbrate = L_add(ACELP_14k80, 0); + } + ELSE + { + cbrate = L_min(st_fx->core_brate, ACELP_22k60 ); + } + + L_frame_for_cs = L_FRAME16k; + move16(); + } + + /*----------------------------------------------------------------* + * Excitation decoding + *----------------------------------------------------------------*/ + config_acelp1(DEC, st_fx->total_brate, cbrate, st_fx->core, -1, -1, st_fx->last_L_frame, -1, &(st_fx->acelp_cfg), st_fx->next_bit_pos, GENERIC, -1, -1, &decode_bwe /* dummy */, &i, st_fx->element_mode, &i /*dummy*/, 0, 0, st_fx->idchan, st_fx->active_cnt, 0, 0, 0 ); + decod_gen_voic_core_switch_fx( st_fx, L_frame_for_cs, 0, Aq, exc, cbrate, &st_fx->Q_exc ); + + /*----------------------------------------------------------------* + * synthesis, deemphasis, postprocessing and resampling + *----------------------------------------------------------------*/ + + /* Core synthesis at 12.8kHz or 16kHz */ + Rescale_mem( st_fx->Q_exc, &st_fx->prev_Q_syn, &st_fx->Q_syn, st_fx->mem_syn2_fx, st_fx->mem_syn_clas_estim_fx, + 4, &st_fx->mem_deemph_fx, hBPF->pst_old_syn_fx, &hBPF->pst_mem_deemp_err_fx,&st_fx->agc_mem_fx[1], st_fx->hPFstat , 1, 0, NULL ); + + syn_12k8_fx( 2*L_SUBFR, Aq, exc, synth_intFreq, st_fx->mem_syn2_fx, 1, st_fx->Q_exc, st_fx->Q_syn ); + + IF(st_fx->hPFstat->on && (EQ_16(st_fx->last_bwidth,NB))) + { + Word16 tmp_noise, pitch_buf_tmp[2]; + tmp_noise = 0; + FOR( i=0; i<2; i++ ) + { + pitch_buf_tmp[i] = L_SUBFR; + move16(); + } + nb_post_filt( 2*L_SUBFR, st_fx->hPFstat, &tmp_noise, 0, synth_intFreq, Aq, pitch_buf_tmp, AUDIO, st_fx->BER_detect, 0 ); + } + + IF( EQ_16(L_frame_for_cs,L_FRAME)) + { + deemph_fx( synth_intFreq, PREEMPH_FAC, 2*L_SUBFR, &(st_fx->mem_deemph_fx) ); + } + ELSE + { + deemph_fx( synth_intFreq, PREEMPH_FAC_16k, 2*L_SUBFR, &(st_fx->mem_deemph_fx) ); + } + + unscale_AGC( synth_intFreq, st_fx->Q_syn, syn_fx_tmp+M, st_fx->agc_mem_fx, 2*L_SUBFR ); + Copy( syn_fx_tmp+M, synth_intFreq, 2*L_SUBFR ); + + test(); + IF( st_fx->hPFstat->on && (NE_16(st_fx->last_bwidth,NB))) + { + Copy( st_fx->hPFstat->mem_pf_in+L_SYN_MEM-M, bpf_error_signal, M ); + Copy( synth_intFreq, bpf_error_signal + M, L_SUBFR ); + Residu3_fx ( Aq, bpf_error_signal + M, exc, L_SUBFR, 1 ); + E_UTIL_synthesis ( 1, Aq, exc, bpf_error_signal, L_SUBFR, st_fx->hPFstat->mem_stp+L_SYN_MEM-M, 0, M ); + scale_st ( synth_intFreq, bpf_error_signal, &st_fx->hPFstat->gain_prec, L_SUBFR ); + Copy( bpf_error_signal, synth_intFreq, L_SUBFR/2 ); + blend_subfr2( bpf_error_signal + L_SUBFR/2, synth_intFreq + L_SUBFR/2, synth_intFreq + L_SUBFR/2 ); + } + st_fx->hPFstat->on = 0; + + move16(); + + IF ( st_fx->flag_cna != 0 ) + { + generate_masking_noise( synth_intFreq, st_fx->Q_syn, st_fx->hFdCngDec_fx->hFdCngCom, 2*L_SUBFR, 0); + } + + /*----------------------------------------------------------------* + * Resample to the output sampling rate (8/16/32/48 kHz) + * Bass post-filter + *----------------------------------------------------------------*/ + + bass_psfilter_fx(st_fx->hBPF, st_fx->Opt_AMR_WB, synth_intFreq, 2*L_SUBFR, NULL, + st_fx->bpf_off, st_fx->stab_fac_fx, &st_fx->stab_fac_smooth_fx, + GENERIC, st_fx->Q_syn, bpf_error_signal ); + + if ((error = cldfb_save_memory( st_fx->cldfbAna_fx )) != IVAS_ERR_OK) + { + return error; + } + cldfbAnalysisFiltering( st_fx->cldfbAna_fx, realBuffer, imagBuffer, &scaleFactor, synth_intFreq, + negate(st_fx->Q_syn), CLDFB_NO_COL_MAX_SWITCH, workBuffer); + cldfb_restore_memory( st_fx->cldfbAna_fx ); + + /* CLDFB synthesis of the combined signal */ + scaleFactor.hb_scale = scaleFactor.lb_scale; + move16(); + + /* CLDFB analysis and add the BPF error signal */ + if ((error = cldfb_save_memory( st_fx->cldfbBPF_fx )) != IVAS_ERR_OK) + { + return error; + } + i = 0; + move16(); + if( st_fx->bpf_off == 0 ) + { + i = CLDFB_NO_COL_MAX_SWITCH; + move16(); + } + addBassPostFilterFx( bpf_error_signal, realBuffer, imagBuffer, st_fx->cldfbBPF_fx, workBuffer, negate(st_fx->Q_syn), + i, CLDFB_NO_COL_MAX_SWITCH, st_fx->cldfbAna_fx->no_channels, &scaleFactor ); + cldfb_restore_memory( st_fx->cldfbBPF_fx ); + + /* CLDFB synthesis of the combined signal */ + scaleFactor.hb_scale = scaleFactor.lb_scale; + + if ((error = cldfb_save_memory( st_fx->cldfbSyn_fx )) != IVAS_ERR_OK) + { + return error; + } + cldfbSynthesisFiltering(st_fx->cldfbSyn_fx, realBuffer, imagBuffer, &scaleFactor, synth_subfr_out, 0, CLDFB_NO_COL_MAX_SWITCH, workBuffer); + cldfb_restore_memory( st_fx->cldfbSyn_fx ); + *Q_syn = 0; + move16(); + + Copy_Scale_sig( synth_intFreq+ NS2SA(L_frame_for_cs * 50, SWITCH_GAP_LENGTH_NS-DELAY_CLDFB_NS)-2, mem_synth, NS2SA(L_frame_for_cs * 50, DELAY_CLDFB_NS)+2, negate(st_fx->Q_syn) ); /* Copy mem with Q0 */ + + /*----------------------------------------------------------------* + * BWE decoding + *----------------------------------------------------------------*/ + + decode_bwe = 0; + move16(); + test(); + test(); + IF( !(( EQ_16(inner_frame_tbl[st_fx->bwidth], L_FRAME16k)&&EQ_16(st_fx->last_L_frame,L_FRAME16k))||EQ_16(inner_frame_tbl[st_fx->bwidth],L_FRAME8k))) + { + /* Decoding of BWE */ + d1m = (Word16)get_next_indice(st_fx, AUDIODELAYBITS); + ind1 = (Word16)get_next_indice(st_fx, NOOFGAINBITS1); + gain = usdequant_fx( ind1, MINVALUEOFFIRSTGAIN_FX, shr(DELTAOFFIRSTGAIN_FX,3) ); /*Q13*/ + decode_bwe = 1; + move16(); + } + + test(); + test(); + test(); + IF( decode_bwe && !(( EQ_16(output_frame, L_FRAME16k)&&EQ_16(st_fx->last_L_frame,L_FRAME16k))||EQ_16(output_frame,L_FRAME8k))) + { + set16_fx( tmp_mem2, 0, 2*L_FILT48k ); + + hp_filter = hp16000_48000_fx; + fdelay = 48; + move16(); + IF ( EQ_32(st_fx->output_Fs, 16000)) + { + IF( EQ_16(st_fx->last_L_frame, L_FRAME)) + { + hp_filter = hp12800_16000_fx; + fdelay = 20; + move16(); + } + } + ELSE IF( EQ_32(st_fx->output_Fs, 32000)) + { + IF( EQ_16(st_fx->last_L_frame, L_FRAME)) + { + hp_filter = hp12800_32000_fx; + fdelay = 40; + move16(); + } + ELSE + { + hp_filter = hp16000_32000_fx; + fdelay = 32; + move16(); + } + } + ELSE IF( EQ_16(st_fx->last_L_frame, L_FRAME)) + { + hp_filter = hp12800_48000_fx; + fdelay = 60; + move16(); + } + + /* safety check in case of bit errors */ + i = MAX_D1M_16k; + move16(); + if( EQ_16(st_fx->last_L_frame,L_FRAME)) + { + i = MAX_D1M_12k8; + move16(); + } + + IF( GE_16(d1m,i)) + { + d1m = sub(i,1); + gain = 0; /* force muting */ move16(); + st_fx->BER_detect = 1; + move16(); + } + + i = NS2SA_fx2(st_fx->output_Fs, FRAME_SIZE_NS-ACELP_LOOK_NS-DELAY_BWE_TOTAL_NS); + move16(); + Copy( st_fx->old_synth_sw_fx, hb_synth_tmp, i ); + set16_fx( hb_synth_tmp + i, 0, NS2SA_fx2(st_fx->output_Fs, 10000000L) - i ); + fir_fx( hb_synth_tmp, hp_filter, hb_synth_tmp, tmp_mem2, shr(output_frame,1), fdelay, 1, 0 ); + + set16_fx( tmp_synth_bwe, 0, SWITCH_MAX_GAP ); + + gapsize = i_mult2(delta, (NS2SA(16000,SWITCH_GAP_LENGTH_NS))); + + pt1 = tmp_synth_bwe; + tmp = add(i_mult(d1m,delta),fdelay); + pt2 = &hb_synth_tmp[tmp]; + FOR( i=0; iHQ switching frame in case of BAD frame +*-------------------------------------------------------------------*/ + +ivas_error acelp_core_switch_dec_bfi_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + Word16 synth_out[], /* o : synthesis Q_syn */ + const Word16 coder_type /* i : coder type */ +) +{ + Word16 old_exc[L_EXC_DEC], *exc; /* excitation signal buffer */ + Word16 syn[L_FRAME16k]; /* synthesis signal buffer */ + Word16 lsf_new[M]; /* LSFs at the end of the frame */ + Word16 lsp_new[M]; /* LSPs at the end of the frame */ + Word16 Aq[NB_SUBFR16k*(M+1)]; /* A(q) quantized for the 4 subframes */ + Word16 old_exc2[L_FRAME16k + L_EXC_MEM], *exc2; /* total excitation buffer */ + Word16 tmp_noise; /* Long term temporary noise energy */ + Word16 FEC_pitch; /* FEC pitch */ + Word16 old_bwe_exc[((PIT16k_MAX + (L_FRAME16k+1) + L_SUBFR16k) * 2)]; /* excitation buffer */ + Word16 *bwe_exc; /* Excitation for SWB TBE */ + Word16 tmp_float[NBPSF_PIT_MAX]; + Word16 tmp_float2[M]; + Word16 tmp_float3; + Word16 tmp_float4[L_TRACK_HIST]; + Word16 tmp_float5[L_TRACK_HIST]; + Word16 tmp_float6[L_TRACK_HIST]; + Word16 tmp_float7; + Word32 tmp_float32; + Word16 voice_factors[NB_SUBFR16k]; + Word16 pitch_buf[NB_SUBFR16k]; + Word16 Q_exc; + Word32 *realBuffer[CLDFB_NO_COL_MAX_SWITCH_BFI], *imagBuffer[CLDFB_NO_COL_MAX_SWITCH_BFI]; + Word32 realBufferTmp[CLDFB_NO_COL_MAX_SWITCH_BFI][CLDFB_NO_CHANNELS_MAX], imagBufferTmp[CLDFB_NO_COL_MAX_SWITCH_BFI][CLDFB_NO_CHANNELS_MAX]; + Word16 i; + CLDFB_SCALE_FACTOR scaleFactor; + Word32 workBuffer[128*3]; + MUSIC_POSTFILT_HANDLE hMusicPF; + BPF_DEC_HANDLE hBPF; + ivas_error error; + + hMusicPF = st_fx->hMusicPF; + hBPF = st_fx->hBPF; + error = IVAS_ERR_OK; + + FOR( i=0; iQ_exc; + move16(); + st_fx->bpf_off = 1; + move16(); + st_fx->clas_dec = st_fx->last_good_fx; + move16(); + tmp_noise = 0; + move16(); + + Copy( st_fx->old_exc_fx, old_exc, L_EXC_MEM_DEC ); + exc = old_exc + L_EXC_MEM_DEC; + IF(st_fx->hWIDec != NULL) + { + Copy(st_fx->hWIDec->old_exc2_fx, old_exc2, L_EXC_MEM); + } + ELSE + { + set16_fx(old_exc2, 0, L_EXC_MEM); + } + exc2 = old_exc2 + L_EXC_MEM; + if (st_fx->hBWE_TD != NULL) + { + Copy(st_fx->hBWE_TD->old_bwe_exc_fx, old_bwe_exc, PIT16k_MAX * 2); + bwe_exc = old_bwe_exc + PIT16k_MAX * 2; + } + else + { + bwe_exc = NULL; + } + + st_fx->GSC_noisy_speech_fx = 0; + move16(); + st_fx->relax_prev_lsf_interp_fx = 0; + move16(); + + /* SC-VBR */ + if( EQ_16(st_fx->last_nelp_mode_dec_fx, 1)) + { + st_fx->nelp_mode_dec_fx = 1; + move16(); + } + + Copy(st_fx->mem_AR_fx,tmp_float,M); + Copy(st_fx->mem_MA_fx,tmp_float2,M); + + /* LSF estimation and A(z) calculation */ + lsf_dec_bfi(MODE1, lsf_new, st_fx->lsf_old_fx, st_fx->lsf_adaptive_mean_fx, NULL, st_fx->mem_MA_fx, st_fx->mem_AR_fx, + st_fx->stab_fac_fx, st_fx->last_coder_type_fx, st_fx->L_frame, st_fx->last_good_fx, + st_fx->nbLostCmpt, 0, NULL, NULL, NULL, st_fx->hGSCDec->Last_GSC_pit_band_idx_fx, st_fx->Opt_AMR_WB, 0, st_fx->bwidth); + + FEC_lsf2lsp_interp( st_fx, st_fx->L_frame, Aq, lsf_new, lsp_new); + + Copy( tmp_float, st_fx->mem_AR_fx, M ); + Copy( tmp_float2, st_fx->mem_MA_fx, M ); + + /*----------------------------------------------------------------* + * Excitation decoding + *----------------------------------------------------------------*/ + + IF( EQ_16(st_fx->nelp_mode_dec_fx, 1)) + { + Word16 gain_buf[NB_SUBFR16k]; + Scale_sig(exc-L_EXC_MEM, L_EXC_MEM, -st_fx->Q_exc); + st_fx->Q_exc = 0; + /* SC-VBR */ + decod_nelp_fx( st_fx, &tmp_noise, pitch_buf, exc, exc2, voice_factors, bwe_exc, &Q_exc, st_fx->bfi, gain_buf ); + FEC_pitch = pitch_buf[3]; + move16(); + Rescale_exc(hMusicPF->dct_post_old_exc_fx, exc, NULL, st_fx->hGSCDec->last_exc_dct_in_fx, L_FRAME, 0, (Word32)0, &Q_exc, st_fx->Q_subfr, exc2, L_FRAME, coder_type); + st_fx->Q_exc = Q_exc; + } + ELSE + { + tmp_float[0] = st_fx->bfi_pitch_fx; + move16(); + tmp_float[1] = st_fx->bfi_pitch_frame; + move16(); + tmp_float[2] = st_fx->lp_gainp_fx; + move16(); + tmp_float[3] = st_fx->lp_gainc_fx; + move16(); + tmp_float[4] = st_fx->upd_cnt; + move16(); + tmp_float[5] = st_fx->seed; + move16(); + + /* calculation of excitation signal */ + FEC_exc_estim_fx( st_fx, st_fx->L_frame, exc, exc2, syn /* dummy buffer */, pitch_buf, voice_factors, &FEC_pitch, bwe_exc, lsf_new, &Q_exc, &tmp_noise ); + Rescale_exc( NULL, exc, bwe_exc, st_fx->hGSCDec->last_exc_dct_in_fx, st_fx->L_frame, L_FRAME32k, (Word32)0, + &Q_exc, st_fx->Q_subfr, exc2, st_fx->L_frame, st_fx->last_coder_type_fx); + + st_fx->seed = tmp_float[5]; + move16(); + st_fx->bfi_pitch_fx = tmp_float[0]; + move16(); + st_fx->bfi_pitch_frame = tmp_float[1]; + move16(); + st_fx->lp_gainp_fx = tmp_float[2]; + move16(); + st_fx->lp_gainc_fx = tmp_float[3]; + move16(); + st_fx->upd_cnt = tmp_float[4]; + move16(); + } + + /*------------------------------------------------------------------* + * Synthesis + *-----------------------------------------------------------------*/ + + Rescale_mem( Q_exc, &st_fx->prev_Q_syn, &st_fx->Q_syn, st_fx->mem_syn2_fx, st_fx->mem_syn_clas_estim_fx, 4, &st_fx->mem_deemph_fx, + hBPF->pst_old_syn_fx, &hBPF->pst_mem_deemp_err_fx, &st_fx->agc_mem_fx[1], st_fx->hPFstat, 1, 0, NULL ); + Copy( st_fx->mem_syn2_fx,tmp_float,M); + syn_12k8_fx( st_fx->L_frame, Aq, exc2, syn, tmp_float, 1, Q_exc, st_fx->Q_syn ); + + tmp_float32 = st_fx->enr_old_fx; + frame_ener_fx( st_fx->L_frame, st_fx->last_good_fx, syn, shr(add(FEC_pitch,32),6), &tmp_float32, st_fx->L_frame, st_fx->Q_syn, 3, 0 ); + + /*------------------------------------------------------------------* + * Perform fixed deemphasis through 1/(1 - g*z^-1) + *-----------------------------------------------------------------*/ + tmp_float[0] = st_fx->mem_deemph_fx; + move16(); /*if in acelp_core_dec_fx deemph_fx is used*/ + /*tmp_float = shr(st_fx->mem_deemph_fx, sub(st_fx->Q_syn,1)); if in acelp_core_dec_fx Deemph2 is used*/ + + IF(EQ_16(st_fx->L_frame,L_FRAME )) + { + deemph_fx( syn, PREEMPH_FAC, L_FRAME, &tmp_float[0] ); /*Q0*/ + } + ELSE + { + deemph_fx( syn, PREEMPH_FAC_16k, L_FRAME16k, &tmp_float[0] ); /*Q0*/ + } + + /*----------------------------------------------------------------* + * Bass post-filter + *----------------------------------------------------------------*/ + + st_fx->bpf_off=1; + move16(); + Copy(hBPF->pst_old_syn_fx,tmp_float,NBPSF_PIT_MAX); + + tmp_float3 = st_fx->stab_fac_smooth_fx; + move16(); + Copy(hBPF->mem_mean_pit_fx,tmp_float4, L_TRACK_HIST); + Copy(hBPF->Track_on_hist_fx,tmp_float5, L_TRACK_HIST); + Copy(hBPF->vibrato_hist_fx,tmp_float6, L_TRACK_HIST); + tmp_float7 = hBPF->psf_att_fx; + move16(); + + bass_psfilter_fx(st_fx->hBPF, st_fx->Opt_AMR_WB, syn, st_fx->L_frame, pitch_buf, + st_fx->bpf_off, st_fx->stab_fac_fx, &tmp_float3, coder_type, st_fx->Q_syn, old_exc /* tmp buffer*/); + + Copy(tmp_float, hBPF->pst_old_syn_fx, NBPSF_PIT_MAX); + Copy(tmp_float4, hBPF->mem_mean_pit_fx, L_TRACK_HIST); + Copy(tmp_float5, hBPF->Track_on_hist_fx, L_TRACK_HIST); + Copy(tmp_float6, hBPF->vibrato_hist_fx, L_TRACK_HIST); + hBPF->psf_att_fx = tmp_float7 ; + /*----------------------------------------------------------------* + * Resamping to the output sampling frequency + *----------------------------------------------------------------*/ + /* CLDFB analysis of the synthesis at internal sampling rate */ + if ((error = cldfb_save_memory( st_fx->cldfbAna_fx )) != IVAS_ERR_OK) + { + return error; + } + cldfbAnalysisFiltering( st_fx->cldfbAna_fx, realBuffer, imagBuffer, &scaleFactor, syn, + negate(st_fx->Q_syn), CLDFB_NO_COL_MAX_SWITCH_BFI, workBuffer); + cldfb_restore_memory( st_fx->cldfbAna_fx ); + + scaleFactor.hb_scale = scaleFactor.lb_scale; + + /* CLDFB synthesis of the combined signal */ + if ((error = cldfb_save_memory( st_fx->cldfbSyn_fx )) != IVAS_ERR_OK) + { + return error; + } + cldfbSynthesisFiltering( st_fx->cldfbSyn_fx, realBuffer, imagBuffer, &scaleFactor, synth_out, + negate(st_fx->Q_syn), CLDFB_NO_COL_MAX_SWITCH_BFI, workBuffer ); + + /* output to Q0 */ + Scale_sig(synth_out,L_FRAME48k, negate(st_fx->Q_syn)); + + cldfb_restore_memory( st_fx->cldfbSyn_fx ); + + return error; +} + + +/*-------------------------------------------------------------------* +* decod_gen_voic_core_switch() +* +* Decode excitation signal in the first ACELP->HQ switching frame +*-------------------------------------------------------------------*/ + +static void decod_gen_voic_core_switch_fx( + Decoder_State *st_fx, /* i/o: decoder static memory */ + const Word16 L_frame, /* i : length of the frame */ + const Word16 sharpFlag, /* i : flag for formant sharpening */ + const Word16 *Aq, /* i : LP filter coefficient */ + Word16 *exc, /* i/o: adapt. excitation exc */ + const Word32 core_brate, /* i : switching frame bit-rate */ + Word16 *Q_exc +) +{ + Word16 T0, T0_frac, T0_min, T0_max;/* integer pitch variables */ + Word16 gain_pit,gain_code16; /* pitch gain */ + Word32 gain_code,L_tmp; /* gain/normalized gain of the algebraic excitation */ + Word32 norm_gain_code; /* normalized gain of the algebraic excitation */ + Word16 gain_inov; /* Innovation gain */ + Word16 voice_fac; /* voicing factor */ + Word16 code[L_SUBFR]; /* algebraic codevector */ + Word16 pitch; /* pointer to floating pitch */ + Word16 i; /* tmp variables */ + Word16 pitch_limit_flag; + Word16 *pt1; + GSC_DEC_HANDLE hGSCDec; + hGSCDec = st_fx->hGSCDec; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + + + + /*----------------------------------------------------------------------* + * initializations + *----------------------------------------------------------------------*/ + + IF( EQ_16(L_frame, L_FRAME)) + { + T0_max = PIT_MAX; + move16(); + T0_min = PIT_MIN; + move16(); + } + ELSE /* L_frame == L_FRAME16k */ + { + T0_max = PIT16k_MAX; + move16(); + T0_min = PIT16k_MIN; + move16(); + } + + /*----------------------------------------------------------------------* + * Decode pitch lag + *----------------------------------------------------------------------*/ + + pitch = pit_decode_fx( st_fx, core_brate, 0, L_frame, 0, GENERIC, &pitch_limit_flag, &T0, &T0_frac, &T0_min, &T0_max, L_SUBFR ); /*Q6*/ + + /*--------------------------------------------------------------* + * Find the adaptive codebook vector. + *--------------------------------------------------------------*/ + + pred_lt4( &exc[0], &exc[0], T0, T0_frac, L_SUBFR+1, pitch_inter4_2, L_INTERPOL2, PIT_UP_SAMP ); + + /*--------------------------------------------------------------* + * LP filtering of the adaptive excitation + *--------------------------------------------------------------*/ + + lp_filt_exc_dec_fx(st_fx, MODE1, 0, L_SUBFR, L_frame, st_fx->acelp_cfg.ltf_mode, exc); /*Scaling of exc doesn't change*/ + + /*--------------------------------------------------------------* + * Innovation decoding + *--------------------------------------------------------------*/ + + inov_decode_fx( st_fx, core_brate, 0, L_frame, sharpFlag, 0, Aq, st_fx->tilt_code_fx, pitch, code, L_SUBFR); /*code in Q9*/ + + /*--------------------------------------------------------------* + * Gain decoding + * Estimate spectrum tilt and voicing + *--------------------------------------------------------------*/ + + IF( EQ_16(L_frame, L_FRAME)) + { + gain_dec_mless_fx( st_fx, L_frame, TRANSITION, 0, -1, code, st_fx->old_Es_pred_fx, &gain_pit, &gain_code, &gain_inov, &norm_gain_code ); + } + ELSE + { + gain_dec_mless_fx( st_fx, L_frame, GENERIC, 0, -1, code, st_fx->old_Es_pred_fx, &gain_pit, &gain_code, &gain_inov, &norm_gain_code ); + } + + /* _ (Word16*) gain_pit : quantized pitch gain (Q14) */ + /* _ (Word32*) gain_code : quantized codebook gain (Q16) */ + /* _ (Word16*) gain_inov : gain of the innovation (used for normalization) (Q12) */ + /* _ (Word32*) norm_gain_code : norm. gain of the codebook excitation (Q16) */ + st_fx->tilt_code_fx = est_tilt_fx( exc, gain_pit, code, gain_code, &voice_fac, *Q_exc ); /*Q15*/ + + /*----------------------------------------------------------------------* + * Find the total excitation + *----------------------------------------------------------------------*/ + + /* Rescaling for 12.8k core */ + IF ( EQ_16(L_frame,L_FRAME)) + { + Rescale_exc( NULL, &exc[0], NULL, hGSCDec->last_exc_dct_in_fx, L_SUBFR, L_SUBFR * HIBND_ACB_L_FAC, gain_code, &(st_fx->Q_exc), st_fx->Q_subfr, NULL, 0, GENERIC ); + } + /* Rescaling for 16k core */ + ELSE + { + Rescale_exc(NULL, &exc[0], NULL, hGSCDec->last_exc_dct_in_fx, L_SUBFR, L_SUBFR * 2, gain_code, &(st_fx->Q_exc), st_fx->Q_subfr, NULL, 0, GENERIC); + } + + gain_code16 = round_fx(L_shl(gain_code,st_fx->Q_exc)); /*Q_exc*/ + IF( st_fx->prev_bfi ) + { + /*gain_code = min(gain_code, 0.5f*gain_code+0.5f*st->lp_gainc);*/ +#ifdef BASOP_NOGLOB + gain_code16 = s_min(gain_code16, mac_r(L_mult(16384, gain_code16), shl_o(16384 >> 3, st_fx->Q_exc, &Overflow), st_fx->lp_gainc_fx)); /* st_fx->lp_gainc_fx in Q3 >>3 to bring it to Q0 as gain_code16 */ +#else + gain_code16 = s_min(gain_code16, mac_r(L_mult(16384,gain_code16),shl(16384>>3, st_fx->Q_exc), st_fx->lp_gainc_fx)); /* st_fx->lp_gainc_fx in Q3 >>3 to bring it to Q0 as gain_code16 */ +#endif + } + + FOR (i = 0; i < L_SUBFR; i++) + { + L_tmp = L_shl(L_mult(gain_pit, exc[i]), 1); /*Q16+Q_exc*/ + /*exc2_fx[i+i_subfr] = round_fx(L_tmp);*/ /*Q_exc*/ + L_tmp = L_add(L_tmp, L_shl(L_mult(gain_code16, code[i]), 6)); /*Q16+Q_exc*/ + exc[i] = round_fx(L_tmp); /*Q_exc*/ + } + + /*-----------------------------------------------------------------* + * long term prediction on the 2nd sub frame + *-----------------------------------------------------------------*/ + + pred_lt4(&exc[L_SUBFR], &exc[L_SUBFR], T0, T0_frac, L_SUBFR+1, pitch_inter4_2, L_INTERPOL2, PIT_UP_SAMP); + pt1 = exc+L_SUBFR; + + FOR( i = 0; i < L_SUBFR; i++ ) + { + (*pt1) = round_fx(L_shl(L_mult(*pt1, gain_pit),1)); /*Q_exc + Q14 +1 +1 -16*/ + pt1++; + } + + return; +} diff --git a/lib_dec/amr_wb_dec.c b/lib_dec/amr_wb_dec.c index 33f980502362d23deeaf4c9e0c0347058ca786aa..41c265c849f1d368d81b92ed304defd781945000 100644 --- a/lib_dec/amr_wb_dec.c +++ b/lib_dec/amr_wb_dec.c @@ -43,12 +43,12 @@ #include "wmc_auto.h" /*------------------------------------------------------------------* - * amr_wb_dec() + * amr_wb_dec_flt() * * AMR-WB decoder *------------------------------------------------------------------*/ -ivas_error amr_wb_dec( +ivas_error amr_wb_dec_flt( Decoder_State *st, /* i/o: decoder state structure */ float mem_hp20_out[L_HP20_MEM], /* i/o: HP filter memory for synthesis */ float *output /* o : synthesis output */ @@ -518,9 +518,9 @@ ivas_error amr_wb_dec( class_para = 0.0f; /* LSF estimation and A(z) calculation */ - lsf_dec_bfi( MODE1, lsf_new, st->lsf_old, st->lsf_adaptive_mean, NULL, st->mem_MA, st->mem_AR, st->stab_fac, st->last_coder_type, L_FRAME, st->last_good, st->nbLostCmpt, 0, NULL, NULL, NULL, st->hGSCDec->Last_GSC_pit_band_idx, st->Opt_AMR_WB, st->bwidth ); + lsf_dec_bfi_flt( MODE1, lsf_new, st->lsf_old, st->lsf_adaptive_mean, NULL, st->mem_MA, st->mem_AR, st->stab_fac, st->last_coder_type, L_FRAME, st->last_good, st->nbLostCmpt, 0, NULL, NULL, NULL, st->hGSCDec->Last_GSC_pit_band_idx, st->Opt_AMR_WB, st->bwidth ); - FEC_lsf2lsp_interp( st, L_FRAME, Aq, lsf_new, lsp_new ); + FEC_lsf2lsp_interp_flt( st, L_FRAME, Aq, lsf_new, lsp_new ); /* calculation of excitation signal */ FEC_exc_estim( st, L_FRAME, exc, exc2, tmp_buffer, pitch_buf, voice_factors, &FEC_pitch, dummy_buf, lsf_new, &tmp_noise ); @@ -572,12 +572,12 @@ ivas_error amr_wb_dec( if ( output_frame == L_FRAME8k ) { st->hPFstat->on = 1; - nb_post_filt( L_FRAME, L_SUBFR, st->hPFstat, &st->psf_lp_noise, tmp_noise, syn, Aq, pitch_buf, st->coder_type, st->BER_detect, 0 ); + nb_post_filt_ivas( L_FRAME, L_SUBFR, st->hPFstat, &st->psf_lp_noise, tmp_noise, syn, Aq, pitch_buf, st->coder_type, st->BER_detect, 0 ); } else { st->hPFstat->on = 0; - nb_post_filt( L_FRAME, L_SUBFR, st->hPFstat, &st->psf_lp_noise, tmp_noise, syn, Aq, pitch_buf, AUDIO, st->BER_detect, 0 ); + nb_post_filt_ivas( L_FRAME, L_SUBFR, st->hPFstat, &st->psf_lp_noise, tmp_noise, syn, Aq, pitch_buf, AUDIO, st->BER_detect, 0 ); } } @@ -606,7 +606,7 @@ ivas_error amr_wb_dec( if ( output_frame != L_FRAME8k && st->last_bwidth != NB ) { st->hPFstat->on = 1; - formant_post_filt( st->hPFstat, tmp_buffer + L_SYN_MEM, Aq, syn, L_FRAME, L_SUBFR, st->psf_lp_noise, st->total_brate, amr_io_class == AUDIO_CLAS ); + formant_post_filt_ivas( st->hPFstat, tmp_buffer + L_SYN_MEM, Aq, syn, L_FRAME, L_SUBFR, st->psf_lp_noise, st->total_brate, amr_io_class == AUDIO_CLAS ); } /*----------------------------------------------------------------* @@ -619,39 +619,39 @@ ivas_error amr_wb_dec( /*VAD only for non inactive frame*/ st->VAD = ( st->VAD && ( st->coder_type != INACTIVE ) ); - ApplyFdCng( syn, NULL, NULL, NULL, st, 0, 0 ); + ApplyFdCng_flt( syn, NULL, NULL, NULL, st, 0, 0 ); st->hFdCngDec->hFdCngCom->frame_type_previous = st->m_frame_type; /*Noisy speech detector*/ - noisy_speech_detection( st->hFdCngDec, st->VAD, syn ); + noisy_speech_detection_flt( st->hFdCngDec, st->VAD, syn ); - st->hFdCngDec->hFdCngCom->likelihood_noisy_speech = 0.99f * st->hFdCngDec->hFdCngCom->likelihood_noisy_speech + 0.01f * (float) st->hFdCngDec->hFdCngCom->flag_noisy_speech; + st->hFdCngDec->hFdCngCom->likelihood_noisy_speech_flt = 0.99f * st->hFdCngDec->hFdCngCom->likelihood_noisy_speech_flt + 0.01f * (float) st->hFdCngDec->hFdCngCom->flag_noisy_speech; st->lp_noise_float = st->hFdCngDec->lp_noise_float; if ( st->flag_cna && ( st->psf_lp_noise >= 15.f ) ) { flag_cna = 1; - generate_masking_noise( syn, st->hFdCngDec->hFdCngCom, st->hFdCngDec->hFdCngCom->frameSize, AMR_WB_CORE, 0, 0, st->element_mode, NULL, -1 ); + generate_masking_noise_flt( syn, st->hFdCngDec->hFdCngCom, st->hFdCngDec->hFdCngCom->frameSize, AMR_WB_CORE, 0, 0, st->element_mode, NULL, -1 ); } else if ( st->flag_cna ) { - generate_masking_noise_update_seed( st->hFdCngDec->hFdCngCom ); + generate_masking_noise_update_seed_flt( st->hFdCngDec->hFdCngCom ); } } else if ( st->flag_cna ) { - generate_masking_noise_update_seed( st->hFdCngDec->hFdCngCom ); + generate_masking_noise_update_seed_flt( st->hFdCngDec->hFdCngCom ); } if ( flag_cna == 0 ) { if ( st->last_flag_cna == 1 && ( ( st->last_core == ACELP_CORE && st->last_coder_type != AUDIO ) || st->last_core == AMR_WB_CORE ) ) { - v_multc( st->hFdCngDec->hFdCngCom->olapBufferSynth2 + 5 * L_FRAME / 4, 256.f, tmp_buffer, L_FRAME / 2 ); + v_multc( st->hFdCngDec->hFdCngCom->olapBufferSynth2_flt + 5 * L_FRAME / 4, 256.f, tmp_buffer, L_FRAME / 2 ); v_add( tmp_buffer, syn, syn, L_FRAME / 2 ); } - set_f( st->hFdCngDec->hFdCngCom->olapBufferSynth2, 0.f, L_FRAME * 2 ); + set_f( st->hFdCngDec->hFdCngCom->olapBufferSynth2_flt, 0.f, L_FRAME * 2 ); } /*----------------------------------------------------------------* @@ -663,8 +663,8 @@ ivas_error amr_wb_dec( if ( ( st->cldfbAna->no_channels * st->cldfbAna->no_col ) != L_FRAME ) { /* resample to ACELP internal sampling rate */ - resampleCldfb( st->cldfbAna, INT_FS_12k8 ); - resampleCldfb( st->cldfbBPF, INT_FS_12k8 ); + resampleCldfb_ivas( st->cldfbAna, INT_FS_12k8 ); + resampleCldfb_ivas( st->cldfbBPF, INT_FS_12k8 ); if ( st->ini_frame > 0 ) { @@ -676,7 +676,7 @@ ivas_error amr_wb_dec( bass_psfilter( st->hBPF, st->Opt_AMR_WB, syn, L_FRAME, pitch_buf, st->bpf_off, st->stab_fac, &st->stab_fac_smooth, GENERIC, bpf_error_signal ); /* analysis of the synthesis at internal sampling rate */ - cldfbAnalysis( syn, realBuffer, imagBuffer, -1, st->cldfbAna ); + cldfbAnalysis_ivas( syn, realBuffer, imagBuffer, -1, st->cldfbAna ); /* analysis and add the BPF error signal */ addBassPostFilter( bpf_error_signal, st->bpf_off ? 0 : -1, realBuffer, imagBuffer, st->cldfbBPF ); @@ -687,10 +687,10 @@ ivas_error amr_wb_dec( st->cldfbSyn->bandsToZero = st->cldfbSyn->no_channels - st->cldfbAna->no_channels; } - cldfb_synth_set_bandsToZero( st, realBuffer, imagBuffer, CLDFB_NO_COL_MAX ); + cldfb_synth_set_bandsToZero_flt( st, realBuffer, imagBuffer, CLDFB_NO_COL_MAX ); /* synthesis of the combined signal */ - cldfbSynthesis( realBuffer, imagBuffer, synth_out, -1, st->cldfbSyn ); + cldfbSynthesis_ivas( realBuffer, imagBuffer, synth_out, -1, st->cldfbSyn ); /* save synthesis - needed in case of core switching */ mvr2r( synth_out, st->previoussynth, output_frame ); @@ -802,7 +802,7 @@ ivas_error amr_wb_dec( mvr2r( synth_out + NS2SA( st->output_Fs, ACELP_LOOK_NS + DELAY_BWE_TOTAL_NS ), st->old_synth_sw, NS2SA( st->output_Fs, FRAME_SIZE_NS - ACELP_LOOK_NS - DELAY_BWE_TOTAL_NS ) ); /* TCX-LTP Postfilter: used in AMR-WB IO to update memories and to avoid discontinuities when the past frame was TCX */ - tcx_ltp_post( st, hTcxLtpDec, ACELP_CORE, output_frame, 0, synth_out, NULL ); + tcx_ltp_post_flt( st, hTcxLtpDec, ACELP_CORE, output_frame, 0, synth_out, NULL ); /* final output of synthesis signal */ mvr2r( synth_out, output, output_frame ); @@ -813,12 +813,12 @@ ivas_error amr_wb_dec( /*------------------------------------------------------------------* - * amr_wb_dec_init() + * amr_wb_dec_init_flt() * * AMR-WB decoder initialization *------------------------------------------------------------------*/ -void amr_wb_dec_init( +void amr_wb_dec_init_flt( AMRWB_IO_DEC_HANDLE hAmrwb_IO /* i/o: AMR-WB IO data handle */ ) { diff --git a/lib_dec/amr_wb_dec_fx.c b/lib_dec/amr_wb_dec_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..82fbff42dd753ceb7513931db5a861b33be30451 --- /dev/null +++ b/lib_dec/amr_wb_dec_fx.c @@ -0,0 +1,1127 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include +#include "options.h" +#include "cnst.h" +#include "rom_com.h" +#include "prot_fx1.h" +#include "prot_fx2.h" +#include "basop_util.h" /* Function prototypes */ + +/*-------------------------------------------------------------------* + * amr_wb_dec_fx() + * + * AMR-WB decoder + *-------------------------------------------------------------------*/ + +ivas_error amr_wb_dec_fx( + Word16 output_sp[], /* o : synthesis output */ + Decoder_State *st_fx /* o : Decoder static variables structure */ +) +{ + Word16 i; + Word16 vad_flag; + Word16 output_frame; /* frame length at output sampling freq. */ + Word16 allow_cn_step; + Word16 locattack, amr_io_class; + Word16 tmps; + Word16 synth_out_fx[L_FRAME48k]; + + Word16 class_para_fx, hf_gain_fx[NB_SUBFR], voice_factors_fx[NB_SUBFR]; + Word16 delay_comp; + Word16 last_core_ori; + Word16 tmp_buffer_fx[L_FRAME48k]; + Word16 dct_buffer_fx[DCT_L_POST]; + Word16 frame_e_fx; + Word16 exc_buffer_fx[DCT_L_POST]; + Word16 lsp_new_fx[M]; /* LSPs at the end of the frame */ + Word16 lsf_new_fx[M]; /* LSFs at the end of the frame */ + Word16 xsp_tmp[M]; + Word16 Aq_fx[NB_SUBFR*(M+1)]; /* A(q) quantized for the 4 subframes */ + Word16 exc2_fx[L_FRAME]; /* total excitation buffer */ + Word16 mem_tmp_fx[M]; /* temporary synthesis filter memory */ + Word32 L_enr_q_fx; /* E information for FER protection */ + Word16 tmp_noise_fx; /* Long term temporary noise energy */ + Word16 FEC_pitch_fx; /* FEC pitch */ + Word16 dummy_buf_fx[L_FRAME32k]; /* dummy buffer - no usage */ + Word16 old_exc_fx[L_EXC_DEC], *exc_fx; /* excitation signal buffer */ + Word16 syn_tmp_fx[L_FRAME+2], *syn_fx; /* synthesis signal buffer */ + Word32 L_tmp, L_tmp1; + Word16 pitch_buf_fx[NB_SUBFR], Qdct, tmp_coder_type; /* floating pitch for each subframe (Q6) */ + Word16 tmp16; + Word16 sid_bw = 0; + Word32 L_Ng_ener; + Word16 exp2, ng_ener; + + Word16 bpf_error_signal[L_FRAME]; + CLDFB_SCALE_FACTOR scaleFactor; + Word32 workBuffer[128*3]; + Word32 q_env[20]; + Word16 exc3[L_FRAME]; + Word16 gain_buf[NB_SUBFR16k]; + + Word32 *realBuffer[CLDFB_NO_COL_MAX], *imagBuffer[CLDFB_NO_COL_MAX]; + Word32 realBufferTmp[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], imagBufferTmp[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + Word16 syn_fx_tmp2[L_FRAME]; + + Word16 pitch_buf_tmp[NB_SUBFR]; + Word16 update_flg; + Word8 flag_cna; + + Word8 waveadj_rec = 0; + + Word16 avoid_lpc_burst_on_recovery; + Word16 delta_mem_scale; + MUSIC_POSTFILT_HANDLE hMusicPF; + TCX_DEC_HANDLE hTcxDec; + HQ_DEC_HANDLE hHQ_core; + TCX_LTP_DEC_HANDLE hTcxLtpDec; + BPF_DEC_HANDLE hBPF; + ivas_error error; + + hMusicPF = st_fx->hMusicPF; + hBPF = st_fx->hBPF; + hHQ_core = st_fx->hHQ_core; + hTcxLtpDec = st_fx->hTcxLtpDec; + hTcxDec = st_fx->hTcxDec; + + error = IVAS_ERR_OK; + st_fx->idchan = 0; + move16(); + move16(); + /*------------------------------------------------------------------* + * Initialization + *------------------------------------------------------------------*/ + + syn_tmp_fx[0] = 0; + move16(); + syn_tmp_fx[1] = 0; + move16(); + syn_fx = syn_tmp_fx+2; + + FOR( i=0; iuse_partial_copy = 0; + move16(); + st_fx->rf_frame_type = RF_NO_DATA; + move16(); + st_fx->rf_flag = 0; + move16(); + st_fx->rf_flag_last = 0; + move16(); + + st_fx->L_frame = L_FRAME; + move16(); + st_fx->nb_subfr = NB_SUBFR; + move16(); + st_fx->core = AMR_WB_CORE; + move16(); + st_fx->core_brate = st_fx->total_brate; + move16(); + st_fx->extl = -1; + move16(); + st_fx->bwidth = WB; + move16(); + st_fx->coder_type_fx = GENERIC; + move16(); + output_frame = st_fx->output_frame_fx; + move16(); /* frame length of the input signal */ + + st_fx->bpf_off = 0; + move16(); + if( EQ_16(st_fx->last_core,HQ_CORE)) + { + st_fx->bpf_off = 1; + move16(); + st_fx->hPFstat->on = 0; + move16(); + } + st_fx->igf = 0; + move16(); + + st_fx->sr_core = i_mult(st_fx->L_frame,50); + st_fx->fscale_old = st_fx->fscale; + st_fx->fscale = sr2fscale(st_fx->sr_core); + + /* Initialization in case that the first frame is the good received AMR-WB (IO) frame */ + IF( st_fx->ini_frame == 0 ) + { + st_fx->last_core = AMR_WB_CORE; + move16(); + Copy( mean_isf_amr_wb_fx, st_fx->lsf_old_fx, M ); + E_LPC_isf_isp_conversion( st_fx->lsf_old_fx, st_fx->lsp_old_fx, M ); + } + + /* Updates in case of EVS primary mode -> AMR-WB IO mode switching */ + IF( NE_16(st_fx->last_core,AMR_WB_CORE)) + { + updt_IO_switch_dec_fx( output_frame, st_fx ); + } + + /* Updates in case of EVS -> AMR-WB IO switching */ + if ((error = core_switching_pre_dec_fx( st_fx, output_frame )) != IVAS_ERR_OK) + { + return error; + } + + last_core_ori = st_fx->last_core; + move16(); + set16_fx( hf_gain_fx, 0, NB_SUBFR); + + amr_io_class = UNVOICED_CLAS; + move16(); + L_enr_q_fx = L_deposit_l(0); + tmp_noise_fx = 0; + move16(); + + Copy( st_fx->old_exc_fx, old_exc_fx, L_EXC_MEM_DEC ); + exc_fx = old_exc_fx + L_EXC_MEM_DEC; + /* reset post-filter in case of switching */ + if( st_fx->hPFstat->on == 0 ) + { + st_fx->hPFstat->reset = 1; + move16(); + } + IF( st_fx->bfi > 0 ) + { + st_fx->nbLostCmpt = add(st_fx->nbLostCmpt,1); + } + ELSE + { + st_fx->nbLostCmpt = 0; + move16(); + } + + /* PLC: [TCX: Fade-out-recovery] + * PLC: overlapping part needs to be attenuated for first good frame */ test(); + test(); + test(); + test(); + IF (!st_fx->bfi && st_fx->prev_bfi && (EQ_16(st_fx->last_codec_mode, MODE2) ) + && (EQ_16(st_fx->last_core_bfi, TCX_20_CORE) || EQ_16(st_fx->last_core_bfi, TCX_10_CORE) )) + { + /* v_multc(st_fx->old_out_fx, st_fx->plcInfo.recovery_gain, */ + /* st_fx->old_out_fx, st_fx->L_frameTCX); */ + FOR( i = 0; i < hTcxDec->L_frameTCX; i++ ) + { + hHQ_core->old_out_fx[i] = shl(mult_r(hHQ_core->old_out_fx[i], st_fx->plcInfo.recovery_gain), 1); + } + } + + avoid_lpc_burst_on_recovery = 0; + move16(); + test(); + test(); + if (st_fx->last_con_tcx && (NE_16(st_fx->L_frameTCX_past, st_fx->L_frame))&&(st_fx->last_core!=0)) + { + avoid_lpc_burst_on_recovery = 1; + move16(); + } + + /*-----------------------------------------------------------------* + * switching from ACELP@16k core to AMR-WB IO mode + *-----------------------------------------------------------------*/ + st_fx->rate_switching_reset=0; + move16(); + test(); + test(); + IF( NE_16(st_fx->last_core,AMR_WB_CORE)&&EQ_16(st_fx->last_L_frame,L_FRAME16k)&&NE_16(st_fx->last_core,HQ_CORE)) + { + /* in case of switching, do not apply BPF */ + st_fx->bpf_off = 1; + move16(); + + if(st_fx->hPFstat->on!=0) + { + Word16 mem_syn_r_size_old, mem_syn_r_size_new; + + mem_syn_r_size_old = shr(st_fx->last_L_frame, 4); + mem_syn_r_size_new = shr(st_fx->L_frame, 4); + lerp( st_fx->hPFstat->mem_stp+L_SYN_MEM-mem_syn_r_size_old, st_fx->hPFstat->mem_stp+L_SYN_MEM-mem_syn_r_size_new, mem_syn_r_size_new, mem_syn_r_size_old ); + lerp( st_fx->hPFstat->mem_pf_in+L_SYN_MEM-mem_syn_r_size_old, st_fx->hPFstat->mem_pf_in+L_SYN_MEM-mem_syn_r_size_new, mem_syn_r_size_new, mem_syn_r_size_old ); + } + st_fx->rate_switching_reset=lsp_convert_poly_fx( st_fx->lsp_old_fx, L_FRAME, 1 ); + /* convert old quantized LSF vector */ + lsp2lsf_fx( st_fx->lsp_old_fx, st_fx->lsf_old_fx, M, INT_FS_FX ); + + /* FEC - update adaptive LSF mean vector */ + Copy( st_fx->lsf_old_fx, st_fx->lsfoldbfi1_fx, M ); + Copy( st_fx->lsf_old_fx, st_fx->lsfoldbfi0_fx, M ); + Copy( st_fx->lsf_old_fx, st_fx->lsf_adaptive_mean_fx, M ); + + /* Reset LPC mem */ + Copy( GEWB_Ave_fx, st_fx->mem_AR_fx, M ); + set16_fx( st_fx->mem_MA_fx,0, M ); + + /* update synthesis filter memories */ + synth_mem_updt2( L_FRAME, st_fx->last_L_frame, st_fx->old_exc_fx, st_fx->mem_syn_r, st_fx->mem_syn2_fx, NULL, DEC ); + Copy( st_fx->old_exc_fx, old_exc_fx, L_EXC_MEM_DEC ); + Copy_Scale_sig(st_fx->mem_syn2_fx, st_fx->mem_syn1_fx, M, sub(-1,st_fx->Q_syn)); /*Q-1*/ + Copy( st_fx->mem_syn2_fx, st_fx->mem_syn3_fx, M ); + + /* LSP -> ISP */ + Copy( stable_ISP_fx, xsp_tmp, M ); + lsp2isp_fx( st_fx->lsp_old_fx, st_fx->lsp_old_fx, xsp_tmp, M ); + + } + + /* update buffer of old subframe pitch values */ + IF( NE_16(st_fx->last_L_frame,L_FRAME)) + { + move16(); + IF( EQ_16(st_fx->last_L_frame,L_FRAME32k)) + { + /* (float)12800/(float)32000; */ + tmp16 = 13107; + } + ELSE IF( EQ_16(st_fx->last_L_frame,512)) + { + /* (float)12800/(float)25600; */ + tmp16 = 16384; + } + ELSE /* st->last_L_frame == L_FRAME16k */ + { + /* (float)12800/(float)16000; */ + tmp16 = 26214; + } + + FOR( i=NB_SUBFR16k-NB_SUBFR; iold_pitch_buf_fx[i-1] = Mpy_32_16_1(st_fx->old_pitch_buf_fx[i], tmp16); + move32(); + } + + FOR( i=2*NB_SUBFR16k-NB_SUBFR; i<2*NB_SUBFR16k; i++ ) + { + st_fx->old_pitch_buf_fx[i-2] = Mpy_32_16_1(st_fx->old_pitch_buf_fx[i], tmp16); + move32(); + } + } + + IF( NE_16(st_fx->bfi_pitch_frame, L_FRAME)) + { + move16(); + IF( EQ_16(st_fx->bfi_pitch_frame,L_FRAME32k)) + { + /* (float)12800/(float)32000; */ + tmp16 = 13107; + } + ELSE IF( EQ_16(st_fx->bfi_pitch_frame,512)) + { + /* (float)12800/(float)25600; */ + tmp16 = 16384; + } + ELSE /* st->bfi_pitch_frame == L_FRAME16k */ + { + /* (float)12800/(float)16000; */ + tmp16 = 26214; + } + st_fx->bfi_pitch_fx = mult_r(tmp16, st_fx->bfi_pitch_fx); + st_fx->bfi_pitch_frame = L_FRAME; + move16(); + } +#ifdef _DIFF_FLOAT_FIX_ + PMT("the code below has been removed in IVAS float (or moved somewhere else), is it ok?") +#endif + IF( NE_16(st_fx->last_core,AMR_WB_CORE)) + { + /* reset the unvoiced/audio signal improvement memories */ + E_LPC_f_isp_a_conversion( st_fx->lsp_old_fx, st_fx->hAmrwb_IO->old_Aq_fx, M ); + Copy( st_fx->hAmrwb_IO->old_Aq_fx, st_fx->hAmrwb_IO->old_Aq_fx + (M+1), M+1 ); + Copy( st_fx->hAmrwb_IO->old_Aq_fx, st_fx->hAmrwb_IO->old_Aq_fx + 2*(M+1), M+1 ); + Copy( st_fx->hAmrwb_IO->old_Aq_fx, st_fx->hAmrwb_IO->old_Aq_fx + 3*(M+1), M+1 ); + } + /*End of _DIFF_FLOAT_FIX_*/ + test(); + if( EQ_16(st_fx->last_bwidth,NB)&&st_fx->ini_frame!=0) + { + st_fx->rate_switching_reset=1; + move16(); + } + + /*----------------------------------------------------------------------* + * GOOD frame + *----------------------------------------------------------------------*/ + + IF( !st_fx->bfi ) + { + /*----------------------------------------------------------------* + * Processing of FRAME_NO_DATA frames + * Decoding of SID frames + *----------------------------------------------------------------*/ + + test(); + IF ( EQ_32(st_fx->core_brate,FRAME_NO_DATA)||EQ_32(st_fx->core_brate,SID_1k75)) + { + /* decode CNG parameters */ + CNG_dec_fx( st_fx, EVS_MONO, Aq_fx, lsp_new_fx, lsf_new_fx, &allow_cn_step, &sid_bw, q_env ); + + /* comfort noise generation */ + CNG_exc_fx( st_fx->core_brate, L_FRAME, &st_fx->hTdCngDec->Enew_fx, &st_fx->hTdCngDec->cng_seed_fx, exc_fx, exc2_fx, &st_fx->lp_ener_fx, st_fx->last_core_brate, + &st_fx->first_CNG, &st_fx->hTdCngDec->cng_ener_seed_fx, dummy_buf_fx, allow_cn_step, &st_fx->hTdCngDec->last_allow_cn_step_fx, st_fx->prev_Q_exc, st_fx->Q_exc , st_fx->hTdCngDec->num_ho_fx, + q_env, st_fx->hTdCngDec->lp_env_fx, st_fx->hTdCngDec->old_env_fx, st_fx->hTdCngDec->exc_mem_fx, st_fx->hTdCngDec->exc_mem1_fx, &sid_bw, &st_fx->hTdCngDec->cng_ener_seed1_fx, exc3, st_fx->Opt_AMR_WB, st_fx->element_mode); + + set16_fx( voice_factors_fx, 32767, NB_SUBFR ); + class_para_fx = 0; + move16(); + + // has been moved to updt_dec_common_fx() + //if( st_fx->first_CNG == 0 ) + //{ + // st_fx->first_CNG = 1; + // move16(); + //} + + delta_mem_scale = 3; + move16(); + test(); + if( LT_32(st_fx->lp_ener_fx,40)) /* very low energy frames, less than 0.3125 */ + { + delta_mem_scale = 0; + move16(); + } + + i = st_fx->Q_exc; + Rescale_exc(hMusicPF->dct_post_old_exc_fx, exc_fx, NULL, st_fx->hGSCDec->last_exc_dct_in_fx, st_fx->L_frame, + st_fx->L_frame* HIBND_ACB_L_FAC, 0, &(st_fx->Q_exc), st_fx->Q_subfr, NULL, 0, INACTIVE); + Rescale_mem( st_fx->Q_exc, &st_fx->prev_Q_syn, &st_fx->Q_syn, st_fx->mem_syn2_fx, st_fx->mem_syn_clas_estim_fx, delta_mem_scale, + &st_fx->mem_deemph_fx, hBPF->pst_old_syn_fx,&hBPF->pst_mem_deemp_err_fx, &st_fx->agc_mem_fx[1], st_fx->hPFstat, 0, 0, NULL ); + Copy_Scale_sig(exc2_fx, exc2_fx, st_fx->L_frame, sub(st_fx->Q_exc, i)); + + /* update past excitation signals for LD music post-filter */ + Copy(hMusicPF->dct_post_old_exc_fx + L_FRAME, hMusicPF->dct_post_old_exc_fx, DCT_L_POST-L_FRAME-OFFSET2 ); + Copy( exc2_fx, hMusicPF->dct_post_old_exc_fx + (DCT_L_POST-L_FRAME-OFFSET2), L_FRAME ); + + /* synthesis at 12k8 Hz sampling rate */ + syn_12k8_fx( L_FRAME, Aq_fx, exc2_fx, syn_fx, st_fx->mem_syn2_fx, 1, st_fx->Q_exc, st_fx->Q_syn ); + syn_12k8_fx( L_FRAME, Aq_fx, exc2_fx, dummy_buf_fx, st_fx->mem_syn3_fx, 1, st_fx->Q_exc, st_fx->Q_syn ); + + /* reset the decoder */ + CNG_reset_dec_fx( st_fx, pitch_buf_fx, dummy_buf_fx+L_FRAME ); + + /* update st_fx->mem_syn1 for ACELP core switching */ + Copy_Scale_sig( st_fx->mem_syn3_fx, st_fx->mem_syn1_fx, M, sub(-1,st_fx->Q_syn) ); /*Q-1*/ + IF( NE_16(output_frame,L_FRAME8k)) + { + Word16 pitch_temp[4]; + pitch_temp[2] = shl(L_FRAME, 6); + move16(); + pitch_temp[3] = shl(L_FRAME, 6); + move16(); + frame_energy_fx( L_FRAME, pitch_temp, syn_fx, 0, &frame_e_fx, st_fx->Q_syn ); + /*st->psf_lp_noise = 0.99f * st->psf_lp_noise + 0.01f * frame_e; */ + st_fx->psf_lp_noise_fx = round_fx(L_mac(L_mult(32440, st_fx->psf_lp_noise_fx), 328, frame_e_fx)); /*Q8*/ + } + /* update old synthesis for classification */ + Copy( syn_fx + L_FRAME - L_SYN_MEM_CLAS_ESTIM, st_fx->mem_syn_clas_estim_fx, L_SYN_MEM_CLAS_ESTIM ); + + /* Update music post processing values */ + /* Filter energies update */ + FOR( i = 0; i < DCT_L_POST; i++ ) + { + /*st->filt_lfE[i] = 0.3f + 0.7f * st->filt_lfE[i];*/ + hMusicPF->filt_lfE_fx[i] = round_fx(L_mac(L_deposit_h(1229), 22938, hMusicPF->filt_lfE_fx[i])); + } + + vad_flag = 0; + move16(); + } + + /*----------------------------------------------------------------* + * Decoding of all other frames + *----------------------------------------------------------------*/ + + ELSE + { + /*-----------------------------------------------------------------* + * After CNG period, use the most up-to-date ISPs + *-----------------------------------------------------------------*/ + + test(); + IF ( EQ_32(st_fx->last_core_brate,FRAME_NO_DATA)||EQ_32(st_fx->last_core_brate,SID_1k75)) + { + Copy( st_fx->lspCNG_fx, st_fx->lsp_old_fx, M ); + E_LPC_isp_isf_conversion( st_fx->lspCNG_fx, st_fx->lsf_old_fx, M ); + set16_fx( old_exc_fx, 0, L_EXC_MEM_DEC ); + } + + /*------------------------------------------------------------* + * Extracts VAD information from the bitstream in AMR-WB IO mode + *------------------------------------------------------------*/ + + vad_flag = (Word16)get_next_indice( st_fx, 1 ); + + st_fx->coder_type_fx = GENERIC; + move16(); + if ( vad_flag == 0 ) + { + st_fx->coder_type_fx = INACTIVE; + move16(); + } + + /*-----------------------------------------------------------------* + * ISF de-quantization and interpolation + *-----------------------------------------------------------------*/ + + isf_dec_amr_wb_fx( st_fx, Aq_fx, lsf_new_fx, lsp_new_fx ); + + /*------------------------------------------------------------* + * Decode excitation + *------------------------------------------------------------*/ + + decod_amr_wb_fx( st_fx, Aq_fx, pitch_buf_fx, exc_fx, exc2_fx, hf_gain_fx, voice_factors_fx, gain_buf ); + + /* synthesis for ACELP core switching and SWB BWE */ + syn_12k8_fx( L_FRAME, Aq_fx, exc_fx, tmp_buffer_fx, st_fx->mem_syn1_fx, 1, st_fx->Q_exc, -1 ); + + /*------------------------------------------------------------* + * Update long-term energies for FEC + * Update ISP vector for CNG + *------------------------------------------------------------*/ + + IF( EQ_16(st_fx->coder_type_fx,INACTIVE)) + { + IF( GT_16(st_fx->unv_cnt_fx,20)) + { + /*ftmp = st->lp_gainc * st->lp_gainc;*/ + L_tmp1 = L_mult0(st_fx->lp_gainc_fx, st_fx->lp_gainc_fx); /* Q3*Q3 -> Q6*/ + /*st->lp_ener = 0.7f * st->lp_ener + 0.3f * ftmp;*/ + L_tmp = Mult_32_16(st_fx->lp_ener_fx, 22938); + st_fx->lp_ener_fx = L_add(L_tmp, Mult_32_16(L_tmp1, 9830)); /*Q6 + Q6*/ + FOR( i=0; ilspCNG_fx[i] = round_fx(L_mac(L_tmp, 29491, st_fx->lspCNG_fx[i])); + } + } + ELSE + { + st_fx->unv_cnt_fx = add(st_fx->unv_cnt_fx,1); + } + } + ELSE + { + st_fx->unv_cnt_fx = 0; + move16(); + } + + /*------------------------------------------------------------* + * Save filter memory in case the synthesis is redone after scaling + * Core synthesis at 12k8 Hz + *------------------------------------------------------------*/ + + /* add extra headroom in case a CNA addition is likely (i.e. st_fx->psf_lp_noise_fx is close to the threshold) */ + tmp16 = 0; + move16(); + test(); + test(); + if(EQ_16(st_fx->coder_type_fx,INACTIVE)&&st_fx->flag_cna&&GE_16(st_fx->psf_lp_noise_fx,15<<7)) + { + tmp16 = 1; + move16(); + } + Rescale_mem( st_fx->Q_exc, &st_fx->prev_Q_syn, &st_fx->Q_syn, st_fx->mem_syn2_fx, st_fx->mem_syn_clas_estim_fx, 5, &st_fx->mem_deemph_fx, + hBPF->pst_old_syn_fx, &hBPF->pst_mem_deemp_err_fx, &st_fx->agc_mem_fx[1], st_fx->hPFstat, vad_flag, tmp16, tmp_buffer_fx ); + Copy( st_fx->mem_syn2_fx, mem_tmp_fx, M ); + syn_12k8_fx( L_FRAME, Aq_fx, exc2_fx, syn_fx, st_fx->mem_syn2_fx, 1, st_fx->Q_exc, st_fx->Q_syn ); + + /*------------------------------------------------------------* + * FEC - Estimate the classification information + *------------------------------------------------------------*/ + + FEC_clas_estim_fx( st_fx, 1, L_FRAME, &st_fx->clas_dec, st_fx->coder_type_fx, pitch_buf_fx, + syn_fx, &st_fx->lp_ener_FER_fx, + &st_fx->decision_hyst, &st_fx->hAmrwb_IO->UV_cnt_fx, &st_fx->hAmrwb_IO->LT_UV_cnt_fx, &st_fx->hAmrwb_IO->Last_ener_fx, &locattack, st_fx->hAmrwb_IO->lt_diff_etot_fx, + &amr_io_class, st_fx->core_brate, st_fx->Q_syn, &class_para_fx, st_fx->mem_syn_clas_estim_fx, &st_fx->classifier_Q_mem_syn, + 0, 0, 0, st_fx->last_core_brate, -1); + + /* update past excitation signals for LD music post-filter */ + Copy(hMusicPF->dct_post_old_exc_fx + L_FRAME, hMusicPF->dct_post_old_exc_fx, DCT_L_POST-L_FRAME-OFFSET2 ); + Copy( exc2_fx, hMusicPF->dct_post_old_exc_fx + (DCT_L_POST-L_FRAME-OFFSET2), L_FRAME ); + Copy(hMusicPF->dct_post_old_exc_fx, exc_buffer_fx, DCT_L_POST-OFFSET2 ); + + IF( NE_16(output_frame,L_FRAME8k)) + { + IF ( EQ_16(st_fx->coder_type_fx,INACTIVE)) + { + frame_energy_fx( L_FRAME, pitch_buf_fx, syn_fx, 0, &frame_e_fx, st_fx->Q_syn ); + /*st->psf_lp_noise = 0.99f * st->psf_lp_noise + 0.01f * frame_e; */ + st_fx->psf_lp_noise_fx = round_fx(L_mac(L_mult(32440, st_fx->psf_lp_noise_fx), 328, frame_e_fx)); /*Q8*/ + } + } + + test(); + test(); + IF( NE_16(amr_io_class,UNVOICED_CLAS)&&NE_16(st_fx->coder_type_fx,INACTIVE)&<_16(st_fx->psf_lp_noise_fx,15<<8)) + { + tmp_coder_type = AUDIO; + move16(); + test(); + if (EQ_16(st_fx->last_coder_type_fx,INACTIVE)||EQ_16(st_fx->last_coder_type_fx,UNVOICED)) + { + tmp_coder_type = INACTIVE; + move16(); + } + /* Extrapolation of the last future part, windowing and high resolution DCT transform */ + Prep_music_postP_fx( exc_buffer_fx, dct_buffer_fx, hMusicPF->filt_lfE_fx, st_fx->last_core, pitch_buf_fx, hMusicPF->LDm_enh_lp_gbin_fx, st_fx->Q_exc, &Qdct ); + + /* LD music post-filter */ + LD_music_post_filter_fx( hMusicPF, dct_buffer_fx, dct_buffer_fx, st_fx->core_brate,&hMusicPF->Old_ener_Q, -1, tmp_coder_type, Qdct ); + + /* Inverse DCT transform, retrieval of the aligned excitation, re-synthesis */ + Post_music_postP_fx( dct_buffer_fx, exc2_fx, mem_tmp_fx, st_fx->mem_syn2_fx, Aq_fx, syn_fx, &st_fx->Q_exc, &st_fx->prev_Q_syn, + &st_fx->Q_syn, st_fx->mem_syn_clas_estim_fx, 1, &st_fx->mem_deemph_fx, hBPF->pst_old_syn_fx, + &hBPF->pst_mem_deemp_err_fx, &st_fx->agc_mem_fx[1], st_fx->hPFstat, NULL, NULL ); + } + ELSE + { + /*------------------------------------------------------------* + * Improvement for unvoiced and audio signals + *------------------------------------------------------------*/ + + improv_amr_wb_gs_fx(amr_io_class, st_fx->coder_type_fx, st_fx->core_brate, &st_fx->hGSCDec->seed_tcx_fx, st_fx->hAmrwb_IO->old_Aq_fx, st_fx->mem_syn2_fx, st_fx->hAmrwb_IO->lt_voice_fac_fx, + locattack, Aq_fx, exc2_fx, st_fx->Q_exc, mem_tmp_fx, syn_fx, st_fx->Q_syn, pitch_buf_fx, st_fx->hAmrwb_IO->Last_ener_fx, st_fx->rate_switching_reset, st_fx->last_coder_type_fx); + + FOR( i = 0; i < DCT_L_POST; i++ ) + { + /*st->filt_lfE[i] = 0.3f + 0.7f * st->filt_lfE[i] ;*/ + hMusicPF->filt_lfE_fx[i] = round_fx(L_mac(L_deposit_h(1229), 22938, hMusicPF->filt_lfE_fx[i])); + } + } + + /*------------------------------------------------------------* + * FEC - Estimate pitch + *------------------------------------------------------------*/ + + FEC_pitch_estim_fx( 1, st_fx->last_core, L_FRAME, st_fx->clas_dec, st_fx->last_good_fx, pitch_buf_fx, st_fx->old_pitch_buf_fx, &st_fx->bfi_pitch_fx, + &st_fx->bfi_pitch_frame, &st_fx->upd_cnt, GENERIC ); + + /*------------------------------------------------------------* + * FEC - Smooth the speech energy evolution when recovering after a BAD frame + * (smoothing is performed in the excitation domain and signal is resynthesized after) + *------------------------------------------------------------*/ + + FOR( i=0; iclas_dec, st_fx->last_good_fx, syn_fx, pitch_buf_tmp, st_fx->enr_old_fx, L_enr_q_fx, -1, MOVING_AVERAGE, + &st_fx->scaling_flag, &st_fx->lp_ener_FEC_av, &st_fx->lp_ener_FEC_max, st_fx->bfi, st_fx->total_brate, st_fx->prev_bfi, st_fx->last_core_brate, + exc_fx, exc2_fx, Aq_fx, &st_fx->old_enr_LP, mem_tmp_fx, st_fx->mem_syn2_fx, st_fx->Q_exc, st_fx->Q_syn, avoid_lpc_burst_on_recovery, 0 ); + + frame_ener_fx( L_FRAME, st_fx->clas_dec, syn_fx, pitch_buf_tmp[3], &st_fx->enr_old_fx, L_FRAME, st_fx->Q_syn, 3, 0 ); + } + + } /* End of GOOD FRAME */ + + /*----------------------------------------------------------------* + * BAD frame + *----------------------------------------------------------------*/ + ELSE + { + /* long burst frame erasures */ + test(); + if( GT_16(st_fx->nbLostCmpt,5)&&GE_16(st_fx->clas_dec,VOICED_CLAS)) + { + st_fx->last_good_fx = VOICED_TRANSITION; + move16(); + } + vad_flag = st_fx->last_vad_fx; + move16(); + amr_io_class = st_fx->last_good_fx; + move16(); + class_para_fx = 0; + move16(); + + /* LSF estimation and A(z) calculation */ + lsf_dec_bfi( MODE1, lsf_new_fx, st_fx->lsf_old_fx, st_fx->lsf_adaptive_mean_fx, NULL, st_fx->mem_MA_fx, st_fx->mem_AR_fx, + st_fx->stab_fac_fx, st_fx->last_coder_type_fx, st_fx->L_frame, st_fx->last_good_fx, + st_fx->nbLostCmpt, 0, NULL, NULL, NULL, st_fx->hGSCDec->Last_GSC_pit_band_idx_fx, st_fx->Opt_AMR_WB, 0, st_fx->bwidth); + + FEC_lsf2lsp_interp( st_fx, st_fx->L_frame, Aq_fx, lsf_new_fx, lsp_new_fx ); + /* calculation of excitation signal */ + FEC_exc_estim_fx( st_fx, L_FRAME, exc_fx, exc2_fx, tmp_buffer_fx, pitch_buf_fx, voice_factors_fx, + &FEC_pitch_fx, dummy_buf_fx, lsf_new_fx, &st_fx->Q_exc, &tmp_noise_fx); + + /* synthesis for ACELP core switching and SWB BWE */ + syn_12k8_fx( L_FRAME, Aq_fx, exc_fx, tmp_buffer_fx, st_fx->mem_syn1_fx, 1, st_fx->Q_exc, -1 ); + + /* update past excitation signals */ + Copy(hMusicPF->dct_post_old_exc_fx + L_FRAME, hMusicPF->dct_post_old_exc_fx, DCT_L_POST-L_FRAME-OFFSET2 ); + Copy( exc2_fx, hMusicPF->dct_post_old_exc_fx + (DCT_L_POST-L_FRAME-OFFSET2), L_FRAME ); + + /* Update music post processing values */ + /* Update circular buffer, keep last energy difference unchanged */ + FOR( i = 1; iLDm_lt_diff_etot_fx[i-1] = hMusicPF->LDm_lt_diff_etot_fx[i]; + move16(); + } + /* Filter energies update */ + FOR( i = 0; i < DCT_L_POST; i++ ) + { + /*st->filt_lfE[i] = 0.3f + 0.7f * st->filt_lfE[i];*/ + hMusicPF->filt_lfE_fx[i] = round_fx(L_mac(L_deposit_h(1229), 22938, hMusicPF->filt_lfE_fx[i])); + } + + Rescale_mem( st_fx->Q_exc, &st_fx->prev_Q_syn, &st_fx->Q_syn, st_fx->mem_syn2_fx, st_fx->mem_syn_clas_estim_fx, 4, &st_fx->mem_deemph_fx, + hBPF->pst_old_syn_fx, &hBPF->pst_mem_deemp_err_fx, &st_fx->agc_mem_fx[1], st_fx->hPFstat, 1, 0, tmp_buffer_fx ); + Copy( st_fx->mem_syn2_fx, mem_tmp_fx, M ); + /* synthesis at 12k8 Hz sampling rate */ + syn_12k8_fx( L_FRAME, Aq_fx, exc2_fx, syn_fx, st_fx->mem_syn2_fx, 1 , st_fx->Q_exc, st_fx->Q_syn ); + + /* update old synthesis for classification */ + Copy( syn_fx + L_FRAME - L_SYN_MEM_CLAS_ESTIM, st_fx->mem_syn_clas_estim_fx, L_SYN_MEM_CLAS_ESTIM ); + + + FOR( i=0; iclas_dec, st_fx->last_good_fx, syn_fx, pitch_buf_tmp, st_fx->enr_old_fx, L_enr_q_fx, -1, + MOVING_AVERAGE, &st_fx->scaling_flag, &st_fx->lp_ener_FEC_av, &st_fx->lp_ener_FEC_max, st_fx->bfi, st_fx->total_brate, + st_fx->prev_bfi, st_fx->last_core_brate, exc_fx, exc2_fx, Aq_fx, &st_fx->old_enr_LP, mem_tmp_fx, st_fx->mem_syn2_fx, + st_fx->Q_exc, st_fx->Q_syn, 0, 0 ); + + /* estimate the pitch-synchronous speech energy per sample to be used when normal operation recovers */ + frame_ener_fx( L_FRAME, st_fx->last_good_fx, syn_fx, shr(FEC_pitch_fx, 6), &st_fx->enr_old_fx, L_FRAME, st_fx->Q_syn, 3, 0 ); + } + + /*--------------------------------------------------------* + * NB post-filter + *--------------------------------------------------------*/ + test(); + IF( EQ_16(output_frame,L_FRAME8k)||EQ_16(st_fx->last_bwidth,NB)) + { + FOR( i=0; ihPFstat->on = 1; + move16(); + nb_post_filt( L_FRAME, st_fx->hPFstat, &st_fx->psf_lp_noise_fx, tmp_noise_fx, syn_fx, Aq_fx, pitch_buf_tmp, st_fx->coder_type_fx, st_fx->BER_detect, 0 ); + } + ELSE + { + st_fx->hPFstat->on = 0; + move16(); + nb_post_filt( L_FRAME, st_fx->hPFstat, &st_fx->psf_lp_noise_fx, tmp_noise_fx, syn_fx, Aq_fx, pitch_buf_tmp, AUDIO, st_fx->BER_detect, 0 ); + } + } + + /*------------------------------------------------------------------* + * Perform fixed deemphasis through 1/(1 - g*z^-1) + *-----------------------------------------------------------------*/ + + /* update old synthesis buffer - needed for ACELP internal sampling rate switching */ + Copy( syn_fx + L_FRAME - L_SYN_MEM, st_fx->mem_syn_r, L_SYN_MEM ); + + deemph_fx( syn_fx, PREEMPH_FAC, L_FRAME, &(st_fx->mem_deemph_fx) ); + + unscale_AGC( syn_fx, st_fx->Q_syn, syn_fx_tmp2, st_fx->agc_mem_fx, L_FRAME ); + Copy( syn_fx_tmp2, syn_fx, L_FRAME ); + + /* TCX=Q-1, ACELP2 Q0 */ + Copy_Scale_sig( syn_fx + L_FRAME/2, hTcxDec->old_syn_Overl, L_FRAME/2, sub(-1,st_fx->Q_syn)); /*Q_syn*/ + Copy_Scale_sig( syn_fx + L_FRAME-M-1, st_fx->syn, M+1, sub(0,st_fx->Q_syn)); /*Q0*/ + + /*------------------------------------------------------------------* + * Formant post-filter + *-----------------------------------------------------------------*/ + + Copy( syn_fx, tmp_buffer_fx + L_SYN_MEM, L_FRAME ); + IF( NE_16(output_frame,L_FRAME8k)&&NE_16(st_fx->last_bwidth,NB)) + { + st_fx->hPFstat->on = 1; + move16(); + test(); + formant_post_filt( st_fx->hPFstat, tmp_buffer_fx + L_SYN_MEM, Aq_fx, syn_fx, L_FRAME, L_shl(st_fx->psf_lp_noise_fx,15), st_fx->total_brate, sub(amr_io_class,AUDIO_CLAS) == 0); + } + + /*----------------------------------------------------------------* + * Comfort Noise Addition + *----------------------------------------------------------------*/ + + flag_cna = 0; + move16(); + test(); + IF( (GE_16(st_fx->psf_lp_noise_fx,15<<8))||(st_fx->coder_type_fx==INACTIVE)) + { + /*VAD only for non inactive frame*/ + test(); + IF( EQ_16(st_fx->VAD, 1)&&NE_16(st_fx->coder_type_fx,INACTIVE)) + { + st_fx->VAD = 1; + move16(); + } + ELSE + { + st_fx->VAD = 0; + move16(); + } +#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT + PMT("Fixed point not done here ") + ApplyFdCng(syn, NULL, NULL, NULL, st, 0, 0); +#else + ApplyFdCng( syn_fx, st_fx->Q_syn, NULL, NULL, NULL, st_fx, 0, 0 ); +#endif + st_fx->hFdCngDec_fx->hFdCngCom->frame_type_previous = st_fx->m_frame_type; + + /*Noisy speech detector*/ + noisy_speech_detection(st_fx->hFdCngDec_fx, st_fx->VAD, syn_fx, st_fx->Q_syn); + + st_fx->hFdCngDec_fx->hFdCngCom->likelihood_noisy_speech = mult_r(st_fx->hFdCngDec_fx->hFdCngCom->likelihood_noisy_speech, 32440/*0.99 Q15*/); + IF ( st_fx->hFdCngDec_fx->hFdCngCom->flag_noisy_speech != 0 ) + { + st_fx->hFdCngDec_fx->hFdCngCom->likelihood_noisy_speech = add(st_fx->hFdCngDec_fx->hFdCngCom->likelihood_noisy_speech, 328/*0.01 Q15*/); + move16(); + } + st_fx->lp_noise = st_fx->hFdCngDec_fx->lp_noise; + move16(); + + test(); + IF( st_fx->flag_cna && GE_16(st_fx->psf_lp_noise_fx,15<<8)) + { + flag_cna = 1; + move16(); + generate_masking_noise( syn_fx, st_fx->Q_syn, st_fx->hFdCngDec_fx->hFdCngCom, st_fx->hFdCngDec_fx->hFdCngCom->frameSize, AMR_WB_CORE ); + } + ELSE IF ( st_fx->flag_cna ) + { + generate_masking_noise_update_seed( st_fx->hFdCngDec_fx->hFdCngCom ); + } + + /*Copy(syn+L_FRAME-M-1, st_fx->syn, M+1);*/ + } + ELSE IF ( st_fx->flag_cna ) + { + generate_masking_noise_update_seed( st_fx->hFdCngDec_fx->hFdCngCom ); + } + + + IF( flag_cna == 0 ) + { + test(); + test(); + test(); + IF( EQ_16(st_fx->last_flag_cna,1)&&((EQ_16(st_fx->last_core,ACELP_CORE)&&NE_16(st_fx->last_coder_type_fx,AUDIO))||EQ_16(st_fx->last_core,AMR_WB_CORE))) + { + FOR (i=0; i < L_FRAME/2; i++) + { + syn_fx[i] = add( syn_fx[i], shr_r( st_fx->hFdCngDec_fx->hFdCngCom->olapBufferSynth2[i+5*L_FRAME/4], -st_fx->Q_syn ) ); + move16(); + } + } + set16_fx( st_fx->hFdCngDec_fx->hFdCngCom->olapBufferSynth2, 0, shl(L_FRAME,1) ); + } + + /*----------------------------------------------------------------* + * Change the sampling frequency to 8/16/32 kHz + * Bass post-filter + *----------------------------------------------------------------*/ + + /* check if the CLDFB works on the right sample rate */ + IF( (st_fx->cldfbAna_fx->usb * st_fx->cldfbAna_fx->no_col) != L_FRAME ) + { + /* resample to ACELP internal sampling rate */ + Word16 newCldfbBands = CLDFB_getNumChannels(INT_FS_FX); + + resampleCldfb( st_fx->cldfbAna_fx, newCldfbBands, L_FRAME, 0 ); + resampleCldfb( st_fx->cldfbBPF_fx, newCldfbBands, L_FRAME, 0 ); + + if( st_fx->ini_frame > 0 ) + { + st_fx->cldfbSyn_fx->bandsToZero = sub(st_fx->cldfbSyn_fx->no_channels,st_fx->cldfbAna_fx->no_channels); + } + } + + bass_psfilter_fx(st_fx->hBPF, st_fx->Opt_AMR_WB, syn_fx, L_FRAME, pitch_buf_fx, st_fx->bpf_off, st_fx->stab_fac_fx, + &st_fx->stab_fac_smooth_fx, GENERIC, st_fx->Q_syn, bpf_error_signal); + + cldfbAnalysisFiltering( st_fx->cldfbAna_fx, realBuffer, imagBuffer, &scaleFactor, syn_fx, + negate(st_fx->Q_syn), CLDFB_NO_COL_MAX, workBuffer ); + + scaleFactor.hb_scale = scaleFactor.lb_scale; + move16(); + + /* CLDFB analysis and add the BPF error signal */ + i = 0; + move16(); + if( st_fx->bpf_off == 0 ) + { + i = CLDFB_NO_COL_MAX; + move16(); + } + addBassPostFilterFx( bpf_error_signal, realBuffer, imagBuffer, st_fx->cldfbBPF_fx, workBuffer, negate(st_fx->Q_syn), + i, st_fx->cldfbAna_fx->no_col, st_fx->cldfbAna_fx->no_channels, &scaleFactor ); + st_fx->Q_syn2 = st_fx->Q_syn; + move16(); + + if( NE_16(st_fx->cldfbSyn_fx->bandsToZero,sub(st_fx->cldfbSyn_fx->no_channels,st_fx->cldfbAna_fx->no_channels))) + { + /* in case of BW switching, re-init to default */ + st_fx->cldfbSyn_fx->bandsToZero = sub(st_fx->cldfbSyn_fx->no_channels, st_fx->cldfbAna_fx->no_channels); + } + cldfb_synth_set_bandsToZero( st_fx, realBuffer, imagBuffer, CLDFB_NO_COL_MAX, scaleFactor ); + /* CLDFB synthesis of the combined signal */ + cldfbSynthesisFiltering( st_fx->cldfbSyn_fx, realBuffer, imagBuffer, &scaleFactor, synth_out_fx, negate(st_fx->Q_syn2), CLDFB_NO_COL_MAX, workBuffer ); + + /* Bring CLDFB output to Q-1 */ + Scale_sig( synth_out_fx, output_frame, negate(st_fx->Q_syn2) ); + st_fx->Q_syn2 = 0; + move16(); + + /* save synthesis - needed in case of core switching */ + Copy( synth_out_fx, st_fx->previoussynth_fx, output_frame ); + st_fx->Q_syn2 = 0; + move16(); + + /*--------------------------------------------------------* + * calculate the average frame energy + *--------------------------------------------------------*/ + frame_ener_fx( L_FRAME, st_fx->clas_dec, syn_fx, mult_r(pitch_buf_fx[3],512), &L_Ng_ener, L_FRAME, st_fx->Q_syn, 3, 0 ); + /*--------------------------------------------------------* + * optimized for NO_S@-26dBov with street noise @ SNR=25dB + *--------------------------------------------------------*/ + + /* ng_ener = 10.0f * (float)log10(ng_ener + 0.01f) - 90.3087f + 15; */ + L_Ng_ener = L_max(1, L_Ng_ener); + tmp16 = norm_l(L_Ng_ener); + exp2 = Log2_norm_lc(L_shl(L_Ng_ener, tmp16)); + tmp16 = sub(30, tmp16); + ng_ener = mac_r(L_shl(L_mac(-1233858L, tmp16, 24660), 8+2), exp2, 771); + /* st_fx->ng_ener_ST = 0.7f * st_fx->ng_ener_ST + 0.3f * ng_ener; */ + st_fx->Ng_ener_ST_fx = mac_r(L_mult(st_fx->Ng_ener_ST_fx, 22938), ng_ener, 9830); + move16(); + + /*-----------------------------------------------------------------* + * Bandwidth extension 6kHz-8kHz + *-----------------------------------------------------------------*/ + + test(); + test(); + IF( GE_16(output_frame,L_FRAME16k)&&(NE_16(st_fx->cldfbSyn_fx->bandsToZero,sub(st_fx->cldfbSyn_fx->no_channels,10))||NE_16(st_fx->last_flag_filter_NB,1))) + { + hf_synth_amr_wb_fx( st_fx->hAmrwb_IO, st_fx->hBWE_zero, + st_fx->core_brate, output_frame, Aq_fx, exc2_fx, syn_fx, &amr_io_class, synth_out_fx, + class_para_fx, hf_gain_fx, voice_factors_fx, pitch_buf_fx, st_fx->Ng_ener_ST_fx, lsf_new_fx, + st_fx->Q_exc, st_fx->Q_syn2 ); + } + ELSE + { + hf_synth_amr_wb_reset_fx( st_fx->hBWE_zero, st_fx->hAmrwb_IO); + } + + /*----------------------------------------------------------------------* + * Updates + *----------------------------------------------------------------------*/ + + updt_dec_fx( st_fx, old_exc_fx, pitch_buf_fx, 0, Aq_fx , lsf_new_fx, lsp_new_fx, voice_factors_fx, dummy_buf_fx, gain_buf ); + /* update old_Aq[] - needed in improv_amr_wb_gs_fx() */ + Copy( Aq_fx, st_fx->hAmrwb_IO->old_Aq_fx, NB_SUBFR * (M+1) ); + + test();test();test();test();test();test();test();test(); + if (!st_fx->bfi + && st_fx->prev_bfi + && GE_32(st_fx->last_total_brate, HQ_48k) + && EQ_16(st_fx->last_codec_mode, MODE2) + && (EQ_16(st_fx->last_core_bfi, TCX_20_CORE) || EQ_16(st_fx->last_core_bfi, TCX_10_CORE) ) + && st_fx->plcInfo.concealment_method == TCX_NONTONAL + && LT_32(st_fx->plcInfo.nbLostCmpt, 4) ) + { + waveadj_rec = 1; + move16(); + } + + /* update main codec parameters */ + st_fx->last_core = st_fx->core; + move16(); + st_fx->last_extl = -1; + move16(); + st_fx->last_codec_mode = st_fx->codec_mode; + move16(); + st_fx->last_L_frame = L_FRAME; + move16(); + st_fx->last_core_brate = st_fx->core_brate; + move16(); + st_fx->last_codec_mode = st_fx->codec_mode; + move16(); + st_fx->last_bwidth = WB; + move16(); + st_fx->last_total_brate_ber = st_fx->total_brate; + move32(); + st_fx->prev_Q_exc = st_fx->Q_exc; + move16(); + if ( !st_fx->bfi ) + { + st_fx->last_total_brate = st_fx->total_brate; + move32(); + st_fx->last_good_fx = st_fx->clas_dec; + move16(); + } + st_fx->last_vad_fx = vad_flag; + move16(); + st_fx->last_flag_cna = flag_cna; + move16(); + + updt_dec_common_fx(st_fx, -1, -1, NULL, 0); + + /*----------------------------------------------------------------* + * Overlap of ACELP synthesis with old MDCT memory + *----------------------------------------------------------------*/ + + if( st_fx->bfi ) + { + /* calculate another loss frame to fill gap in case of switching frame loss */ + if ((error = acelp_core_switch_dec_bfi_fx( st_fx, hHQ_core->fer_samples_fx, st_fx->coder_type_fx )) != IVAS_ERR_OK) + { + return error; + } + } + + delay_comp = NS2SA_fx2(st_fx->output_Fs, DELAY_CLDFB_NS); + Scale_sig(st_fx->delay_buf_out_fx, delay_comp, sub(st_fx->Q_syn2, hHQ_core->Q_old_postdec)); + hHQ_core->Q_old_postdec=st_fx->Q_syn2; + move16(); + IF( EQ_16(last_core_ori,HQ_CORE)) + { + Word16 step, alpha,nz; + + Scale_sig(hHQ_core->old_out_fx, L_FRAME48k, sub(st_fx->Q_syn2, hHQ_core->Q_old_wtda)); + hHQ_core->Q_old_wtda=st_fx->Q_syn2; + move16(); + + Copy( st_fx->delay_buf_out_fx,synth_out_fx, delay_comp ); /* copy the HQ/ACELP delay synchroniation buffer at the beginning of ACELP frame */ + + i = 15; + move16(); + tmps = NS2SA_fx2(st_fx->output_Fs, 6000000L); + nz = NS2SA_fx2(st_fx->output_Fs, N_ZERO_MDCT_NS); + step = Inv16(tmps, &i); + step = shl(step, i); + alpha = 0; + move16(); + + test(); + IF( st_fx->prev_bfi && hHQ_core->HqVoicing_fx ) + { + Copy_Scale_sig(hHQ_core->fer_samples_fx, &hHQ_core->old_out_fx[nz], tmps,negate(st_fx->Q_syn2)); + } + + FOR (i = 0; i < tmps; i++) + { +#ifdef BASOP_NOGLOB + synth_out_fx[i+delay_comp] = msu_r_sat(L_mult(synth_out_fx[i+delay_comp], alpha), hHQ_core->old_out_fx[i+nz], add(alpha, -32768)); +#else + synth_out_fx[i+delay_comp] = msu_r(L_mult(synth_out_fx[i+delay_comp], alpha), hHQ_core->old_out_fx[i+nz], add(alpha, -32768)); +#endif + move16(); + alpha = add(alpha, step); + } + } + + /*----------------------------------------------------------------* + * HP filtering + * Final synthesis output + *----------------------------------------------------------------*/ + + /* Delay ACELP synthesis by DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS delay */ + IF ( GE_16(output_frame,L_FRAME16k)) + { + tmps = NS2SA_fx2(st_fx->output_Fs, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS); + Scale_sig( st_fx->prev_synth_buffer_fx, tmps, sub(st_fx->Q_syn2, st_fx->Qprev_synth_buffer_fx) ); + delay_signal(synth_out_fx, output_frame, st_fx->prev_synth_buffer_fx, tmps); + } + + if (waveadj_rec) + { + tmps = 0; + IF( GE_16(output_frame,L_FRAME16k)) + { + tmps = NS2SA_fx2(st_fx->output_Fs, DELAY_BWE_TOTAL_NS); + } + + waveform_adj2_fix(st_fx->tonalMDCTconceal.secondLastPcmOut, synth_out_fx+tmps, st_fx->plcInfo.data_noise, &st_fx->plcInfo.outx_new_n1_fx, + &st_fx->plcInfo.nsapp_gain_fx, &st_fx->plcInfo.nsapp_gain_n_fx, &st_fx->plcInfo.recovery_gain, st_fx->plcInfo.step_concealgain_fx, + st_fx->plcInfo.Pitch_fx, st_fx->plcInfo.FrameSize, tmps, add(extract_l(st_fx->plcInfo.nbLostCmpt), 1), st_fx->bfi); + } + + /* HP filter */ + Scale_sig32( st_fx->L_mem_hp_out_fx, 4, sub(st_fx->Q_syn2, st_fx->Qprev_synth_buffer_fx) ); + st_fx->Qprev_synth_buffer_fx = st_fx->Q_syn2; + hp20( synth_out_fx, 1/*stride*/, output_frame, st_fx->L_mem_hp_out_fx, L_mult0(output_frame, 50) ); + + /* save synthesis for core switching */ + Copy_Scale_sig( synth_out_fx+NS2SA_fx2( st_fx->output_Fs,ACELP_LOOK_NS+DELAY_BWE_TOTAL_NS), st_fx->old_synth_sw_fx, NS2SA_fx2(st_fx->output_Fs,FRAME_SIZE_NS-ACELP_LOOK_NS-DELAY_BWE_TOTAL_NS), sub(hHQ_core->Q_old_postdec, st_fx->Q_syn2) ); + + { + /* TCX-LTP Postfilter: used in AMR-WB IO to update memories and to avoid discontinuities when the past frame was TCX */ + Word16 delta = NS2SA_fx2( st_fx->output_Fs, TCXLTP_DELAY_NS ); + Scale_sig(hTcxLtpDec->tcxltp_mem_in, delta, sub(st_fx->Q_syn2, st_fx->Qprev_synth_buffer_fx)); + Scale_sig(hTcxLtpDec->tcxltp_mem_out, output_frame, sub(st_fx->Q_syn2, st_fx->Qprev_synth_buffer_fx)); + tcx_ltp_post(st_fx, hTcxLtpDec, ACELP_CORE, output_frame, 0, synth_out_fx, NULL); + } + + /* final output of synthesis signal */ + syn_output_fx( st_fx->codec_mode, synth_out_fx, output_frame, output_sp, st_fx->Q_syn2 ); + + + return error; +} +/*------------------------------------------------------------------* + * amr_wb_dec_init() + * + * AMR-WB decoder initialization + *------------------------------------------------------------------*/ + +void amr_wb_dec_init( + AMRWB_IO_DEC_HANDLE hAmrwb_IO /* i/o: AMR-WB IO data handle */ +) +{ + Word16 i; + /* gain quantization memory (used in AMR-WB IO mode) */ + FOR(i = 0; i < GAIN_PRED_ORDER; i++) + { + hAmrwb_IO->past_qua_en_fx[i] = -14336; + move16(); /* Q10; */ /* gain quantization memory (used also in AMR-WB IO mode) */ + } + /* Improvement of unvoiced and audio signals in AMR-WB IO mode */ + hAmrwb_IO->UV_cnt_fx = 30; + move16(); + hAmrwb_IO->LT_UV_cnt_fx = (60<<6); + move16(); + set16_fx(hAmrwb_IO->lt_diff_etot_fx, 0, MAX_LT); + hAmrwb_IO->Last_ener_fx = 0; + move16(); + + set16_fx(hAmrwb_IO->old_Aq_fx, 0, NB_SUBFR * (M + 1)); + hAmrwb_IO->old_Aq_fx[0] = 16384; + hAmrwb_IO->old_Aq_fx[M + 1] = 16384; + hAmrwb_IO->old_Aq_fx[2 * (M + 1)] = 16384; + hAmrwb_IO->old_Aq_fx[3 * (M + 1)] = 16384; + move16(); move16(); move16(); move16(); + hAmrwb_IO->lt_voice_fac_fx = 0; + move16(); + return; +} diff --git a/lib_dec/ari_dec.c b/lib_dec/ari_dec.c index fa8958660f6bcf518a686d3a6b94e7f0cd484271..dd238ef321483cd4cc2c2ab349df2132912d3f96 100644 --- a/lib_dec/ari_dec.c +++ b/lib_dec/ari_dec.c @@ -49,12 +49,12 @@ -------------------------------------------------------------*/ /*--------------------------------------------------------------- - * ari_start_decoding_14bits() + * ari_start_decoding_14bits_ivas() * * Start ArCo decoding *-------------------------------------------------------------*/ -void ari_start_decoding_14bits( +void ari_start_decoding_14bits_ivas( Decoder_State *st, Tastat *s ) { @@ -70,12 +70,12 @@ void ari_start_decoding_14bits( } /*--------------------------------------------------------------- - * ari_start_decoding_14bits_prm() + * ari_start_decoding_14bits_prm_ivas() * * Start ArCo decoding *-------------------------------------------------------------*/ -int16_t ari_start_decoding_14bits_prm( +int16_t ari_start_decoding_14bits_prm_ivas( const int16_t *ptr, int16_t bp, Tastat *s ) @@ -100,7 +100,7 @@ int16_t ari_start_decoding_14bits_prm( return bp; } -Word16 ari_start_decoding_14bits_prm_fx( +Word16 ari_start_decoding_14bits_prm_fx_ivas( const Word16 *ptr, Word16 bp, Tastat *s @@ -128,14 +128,14 @@ Word16 ari_start_decoding_14bits_prm_fx( } /*--------------------------------------------------------------- - * ari_decode_14bits_s17_ext() + * ari_decode_14bits_s17_ext_ivas() * * Only for 17 symbols with new extended Tables: * based on tri's optimization * based on extended Tables which need less branches for coding *-------------------------------------------------------------*/ -void ari_decode_14bits_s17_ext( +void ari_decode_14bits_s17_ext_ivas( Decoder_State *st, uint16_t *res, Tastat *s, @@ -186,8 +186,8 @@ void ari_decode_14bits_s17_ext( symbol = (uint16_t) ( p - cum_freq ); - high = low + mul_sbc_14bits( range, cum_freq[symbol] ) - 1; - low += mul_sbc_14bits( range, cum_freq[symbol + 1] ); + high = low + mul_sbc_14bits_ivas( range, cum_freq[symbol] ) - 1; + low += mul_sbc_14bits_ivas( range, cum_freq[symbol + 1] ); for ( ;; ) { @@ -230,15 +230,15 @@ void ari_decode_14bits_s17_ext( /*--------------------------------------------------------------- - * ari_decode_14bits_s27_ext() + * ari_decode_14bits_s27_ext_ivas() * * Only for 17 symbols with new extended Tables: * based on tri's optimization * based on extended Tables which need less branches for coding - * copied from ari_decode_14bits_s17_ext, with changes marked + * copied from ari_decode_14bits_s17_ext_ivas, with changes marked *-------------------------------------------------------------*/ -void ari_decode_14bits_s27_ext( +void ari_decode_14bits_s27_ext_ivas( Decoder_State *st, uint16_t *res, Tastat *s, @@ -262,7 +262,7 @@ void ari_decode_14bits_s27_ext( /* If the value multiplied by range is greater than cum, the pointer p is set to the tmp pointer */ /* tmp_p = p+8; if (tmp_p[0]*range>cum) p = tmp_p; */ - /* begin change when compared with ari_decode_14bits_s17_ext, + /* begin change when compared with ari_decode_14bits_s17_ext_ivas, starting with line: if (p[8] * range > cum) { */ il = 0; ih = 27; @@ -319,11 +319,11 @@ void ari_decode_14bits_s27_ext( } symbol = il; - /* end change when compared with ari_decode_14bits_s17_ext, + /* end change when compared with ari_decode_14bits_s17_ext_ivas, ending with line: symbol = p - cum_freq; */ - high = low + mul_sbc_14bits( range, cum_freq[symbol] ) - 1; - low += mul_sbc_14bits( range, cum_freq[symbol + 1] ); + high = low + mul_sbc_14bits_ivas( range, cum_freq[symbol] ) - 1; + low += mul_sbc_14bits_ivas( range, cum_freq[symbol + 1] ); for ( ;; ) { @@ -366,15 +366,15 @@ void ari_decode_14bits_s27_ext( /*--------------------------------------------------------------- - * ari_decode_14bits_bit_ext() + * ari_decode_14bits_bit_ext_ivas() * * Only for decoding one bit with uniform probability: * based on tri's optimization - * copied from ari_decode_14bits_s17_ext, with changes marked + * copied from ari_decode_14bits_s17_ext_ivas, with changes marked * the equivalent cum_freq table used is {16384, 8192, 0} *-------------------------------------------------------------*/ -void ari_decode_14bits_bit_ext( +void ari_decode_14bits_bit_ext_ivas( Decoder_State *st, uint16_t *res, Tastat *s ) @@ -396,7 +396,7 @@ void ari_decode_14bits_bit_ext( /* If the value multiplied by range is greater than cum, the pointer p is set to the tmp pointer */ /* tmp_p = p+8; if (tmp_p[0]*range>cum) p = tmp_p; */ - /* begin change when compared with ari_decode_14bits_s17_ext, + /* begin change when compared with ari_decode_14bits_s17_ext_ivas, starting with line: if (p[8] * range > cum) { */ symbol = 0; @@ -415,8 +415,8 @@ void ari_decode_14bits_bit_ext( high = low + ( range >> 1 ) - 1; /* low is unchanged */ } - /* end change when compared with ari_decode_14bits_s17_ext, - ending with line: low += mul_sbc_14bits(range, cum_freq[symbol + 1]); */ + /* end change when compared with ari_decode_14bits_s17_ext_ivas, + ending with line: low += mul_sbc_14bits_ivas(range, cum_freq[symbol + 1]); */ for ( ;; ) @@ -459,7 +459,7 @@ void ari_decode_14bits_bit_ext( } /*------------------------------------------------------------------------ - * Function: ari_decode_14bits_pow() + * Function: ari_decode_14bits_pow_ivas() * * Decode a symbol which follows the exponential distribution. That is, * symbols are in the following intervals @@ -469,7 +469,7 @@ void ari_decode_14bits_bit_ext( * *-------------------------------------------------------------------------*/ -int16_t ari_decode_14bits_pow( +int16_t ari_decode_14bits_pow_ivas( const int16_t *ptr, int16_t bp, int16_t bits, @@ -541,9 +541,9 @@ int16_t ari_decode_14bits_pow( } - high = low + mul_sbc_14bits( range, highlim ); + high = low + mul_sbc_14bits_ivas( range, highlim ); - low += mul_sbc_14bits( range, lowlim ); + low += mul_sbc_14bits_ivas( range, lowlim ); /*ptr init for ptr*/ for ( ; bp < bits; ) @@ -597,12 +597,12 @@ int16_t ari_decode_14bits_pow( /*------------------------------------------------------------------------ - * Function: ari_decode_14bits_sign() + * Function: ari_decode_14bits_sign_ivas() * * Decode a sign with equal probabilities. *-------------------------------------------------------------------------*/ -int16_t ari_decode_14bits_sign( +int16_t ari_decode_14bits_sign_ivas( const int16_t *ptr, int16_t bp, int16_t bits, diff --git a/lib_dec/ari_dec_fx.c b/lib_dec/ari_dec_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..c7b52aa7b25128a73d3b2dab882708e9baa95b73 --- /dev/null +++ b/lib_dec/ari_dec_fx.c @@ -0,0 +1,552 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include +#include "assert.h" +#include "options.h" +#include "cnst.h" +#include "rom_com.h" +#include "prot_fx1.h" +#include "prot_fx2.h" + +/*--------------------------------------------------------------- + * Ari decode 14 bits routines + -------------------------------------------------------------*/ + +Word16 ari_decode_overflow(Tastat *s) +{ + return L_sub(L_sub(s->high, 1), s->low) <= 0; +} + +/** + * \brief Start ArCo decoding + * + * \param[i/o] st + * \param[o] s + */ +void ari_start_decoding_14bits( + Decoder_State *st, + Tastat *s +) +{ + Word32 val; + + val = L_and(L_deposit_l(get_next_indice(st, cbitsnew)), 0xffffL); + + s->low = L_deposit_l(0); + s->high = ari_q4new+1; + move32(); + s->value = val; + move32(); +} + +Word16 ari_start_decoding_14bits_prm( + const Word16 *ptr, + Word16 bp, + Tastat *s +) +{ + Word32 val; + Word16 i; + const Word16 *p; + + val = L_deposit_l(0); + + p = ptr+bp; + + FOR (i=0; ilow = L_deposit_l(0); + s->high = ari_q4new+1; + move32(); + s->value = val; + move32(); + + return add(bp,i); +} + +static Word16 ari_lookup_s17( + Word32 cum, + Word32 range, + UWord16 const *cum_freq +) +{ + Word32 tmp; + const UWord16 *p; + Word16 range_l, range_h; + + p = cum_freq; + + /* Note: For each indirect addressing p[i], we assume a tmp pointer init followed by a costfree reading the value */ + /* If the value multiplied by range is greater than cum, the pointer p is set to the tmp pointer */ + /* tmp_p = p+8; if (tmp_p[0]*range>cum) p = tmp_p; */ + + /* max value in p[x] is 16384 => 14 bits */ + range_l = extract_l(L_and(range,0x7FFF)); + range_h = extract_l(L_shr(range,15)); + + tmp = L_multi31x16_X2(range_h, range_l,p[8]); + if (GT_32(tmp,cum)) + { + p = p + 8; + } + + tmp = L_multi31x16_X2(range_h, range_l,p[4]); + if (GT_32(tmp,cum)) + { + p = p + 4; + } + + + tmp = L_multi31x16_X2(range_h, range_l,p[2]); + if (GT_32(tmp,cum)) + { + p = p + 2; + } + + tmp = L_multi31x16_X2(range_h, range_l,p[1]); + IF (GT_32(tmp,cum)) + { + p = p + 1; + + tmp = L_multi31x16_X2(range_h, range_l,p[1]); + test(); + if ( ((Word32)(&cum_freq[15] - p) == 0) && (GT_32(tmp,cum))) + { + p = p + 1; + } + } + + /* return extract_l(L_shr(L_sub((Word32)p,(Word32)cum_freq),1)); */ + L_sub(0,0); + L_shr(0,0); /* pointer subtraction */ + return extract_l(p - cum_freq); +} + +static Word16 ari_lookup_s27( + Word32 cum, + Word32 range, + UWord16 const *cum_freq +) +{ + Word32 tmp; + Word16 range_l, range_h; + Word16 il, ih, im; + + /* Note: For each indirect addressing p[i], we assume a tmp pointer init followed by a costfree reading the value */ + /* If the value multiplied by range is greater than cum, the pointer p is set to the tmp pointer */ + /* tmp_p = p+8; if (tmp_p[0]*range>cum) p = tmp_p; */ + + /* max value in p[x] is 16384 => 14 bits */ + range_l = extract_l(L_and(range,0x7FFF)); + range_h = extract_l(L_shr(range,15)); + + /* begin change when compared with ari_decode_14bits_s17_ext, + starting with line: tmp = L_multi31x16_X2(range_h, range_l, p[8]); */ + il = 0; + move16(); + ih = 27; + move16(); + + /* do a five step binary search, using the interval [il, ih) */ + im = 13; + move16(); /* (il + ih) >> 1 */ + tmp = L_multi31x16_X2(range_h, range_l, cum_freq[im]); + tmp = L_sub(tmp, cum); + if (tmp > 0) + { + il = im; + move16(); + } + if (tmp <= 0) + { + ih = im; + move16(); + } + + im = shr(add(il, ih), 1); + tmp = L_multi31x16_X2(range_h, range_l, cum_freq[im]); + tmp = L_sub(tmp, cum); + if (tmp > 0) + { + il = im; + move16(); + } + if (tmp <= 0) + { + ih = im; + move16(); + } + + im = shr(add(il, ih), 1); + tmp = L_multi31x16_X2(range_h, range_l, cum_freq[im]); + tmp = L_sub(tmp, cum); + if (tmp > 0) + { + il = im; + move16(); + } + if (tmp <= 0) + { + ih = im; + move16(); + } + + im = shr(add(il, ih), 1); + tmp = L_multi31x16_X2(range_h, range_l, cum_freq[im]); + tmp = L_sub(tmp, cum); + if (tmp > 0) + { + il = im; + move16(); + } + if (tmp <= 0) + { + ih = im; + move16(); + } + + IF (GT_16(sub(ih, il), 1)) /* if the interval has more than one symbol */ + { + /* here, only ih == il + 2 is possible, which means two symbols in the interval */ + im = add(il, 1); /* (il + ih) >> 1 */ + tmp = L_multi31x16_X2(range_h, range_l, cum_freq[im]); + tmp = L_sub(tmp, cum); + if (tmp > 0) + { + il = im; + move16(); + } + } + + return il; +} + +static Word16 ari_lookup_bit( + Word32 cum, + Word32 range, + UWord16 const *cum_freq +) +{ + Word16 symbol = 0; /* initialize just to avoid compiler warning */ + + (void)cum_freq; + + range = L_shl(range, 13); /* L_multi31x16_X2(range_h, range_l, 8192) */ + cum = L_sub(range, cum); + + if (cum > 0) + { + symbol = 1; + move16(); + } + if (cum <= 0) + { + symbol = 0; + move16(); + } + + return symbol; +} + +static Word16 ari_decode_14bits_ext( + Decoder_State *st, + Tastat *s, + UWord16 const *cum_freq, + Word16 (*lookup_fn)(Word32 cum, Word32 range, UWord16 const *cum_freq) +) +{ + Word32 cum; + Word16 symbol; + Word32 low; + Word32 high; + Word32 range; + Word32 value; + Word16 i; + + low = s->low; + move32(); + high = s->high; + move32(); + value = s->value; + move32(); + + range = L_sub(high, low); + + cum = L_add(L_shl(L_sub(value, low), stat_bitsnew), sub(shl(1,stat_bitsnew),1)); + if (cum < 0) + { + cum = 0x7fffffff; + } + + symbol = lookup_fn(cum, range, cum_freq); + + high = L_add(low,mul_sbc_14bits(range,cum_freq[symbol])); + low = L_add(low,mul_sbc_14bits(range,cum_freq[symbol+1])); + + FOR (i = 0; i < 0x7FFF; i++) + { + Word32 L_msb_diff, L_msb_low, L_msb_high; + + L_msb_high = L_shr(L_sub(high,1),14); + L_msb_low = L_shr(low,14); + L_msb_diff = L_sub(L_msb_high, L_msb_low); + IF (GE_32(L_msb_diff,2)) + { + BREAK; + } + assert (tab_ari_qnew[L_msb_high][L_msb_low] != 0x0CCC); + assert (tab_ari_qnew[L_msb_high][L_msb_low] != 0x0BBB); + low = L_msu(low,1,tab_ari_qnew[L_msb_high][L_msb_low]); + low = L_shl(low,1); + high = L_msu(high,1,tab_ari_qnew[L_msb_high][L_msb_low]); + high = L_shl(high,1); + value = L_msu(value,1,tab_ari_qnew[L_msb_high][L_msb_low]); + value = L_mac0(L_shl(value,1),1,get_next_indice_1(st)); + } + + s->low = low; + move32(); + s->high = high; + move32(); + s->value = value; + move32(); + + return symbol; +} + + +/** + * \brief Only for 17 symbols with new extended Tables + */ +Word16 ari_decode_14bits_s17_ext(Decoder_State *st, Tastat *s, UWord16 const *cum_freq) +{ + return ari_decode_14bits_ext(st, s, cum_freq, ari_lookup_s17); +} + +/** + * \brief Only for 27 symbols with new extended Tables + */ +Word16 ari_decode_14bits_s27_ext(Decoder_State *st, Tastat *s, UWord16 const *cum_freq) +{ + return ari_decode_14bits_ext(st, s, cum_freq, ari_lookup_s27); +} + +/** + * \brief Only for decoding one bit with uniform probability: + * the equivalent cum_freq table used is {16384, 8192, 0} + */ +Word16 ari_decode_14bits_bit_ext(Decoder_State *st, Tastat *s) +{ + static const UWord16 cum_freq[3] = {16384, 8192, 0}; + return ari_decode_14bits_ext(st, s, cum_freq, ari_lookup_bit); +} + +static Word16 ari_lookup_pow(Tastat *s, Word16 base) +{ + Word32 cum, range; + Word16 symbol; + Word16 range_h, range_l; + Word16 pows[12]; /* "base" to the power of 2, 4, 8,... 2^12 */ + Word16 lowlim, highlim, testval; + Word16 k; + + range = L_sub(s->high, s->low); + cum = L_add(L_shl(L_sub(s->value, s->low), stat_bitsnew), sub(shl(1,stat_bitsnew),1)); + + range_h = extract_l(L_shr(range,15)); + range_l = extract_l(L_and(range,0x7FFF)); + + symbol = 0; + move16(); + lowlim = shr(base, 1); + highlim = 16384; + move16(); + + /* search for the interval where "cum" fits */ + IF (GT_32(L_multi31x16_X2(range_h, range_l, lowlim), cum)) /* below pow-1 */ + { + pows[0] = base; + move16(); + testval = base; + move16(); + /* increase exponent until it is smaller than "cum" */ + FOR (k = 1; k < 12; k++) + { + highlim = testval; + move16(); + pows[k] = mult_r(pows[k-1], pows[k-1]); + move16(); + testval = mult_r(pows[k], base); + + IF (LE_32(L_multi31x16_X2(range_h, range_l, shr(testval, 1)), cum)) /* found! big range is [lowlim,testval], (now narrow it down) */ + { + lowlim = testval; + move16(); + k = sub(k, 1); + symbol = shl(1, k); + BREAK; + } + } + assert(k < 12); /* maximum 2^10-1*/ + + /* narrow the range down */ + FOR (k = sub(k, 2); k >= 0; k--) + { + testval = mult_r(highlim, pows[k+1]); + + IF (LE_32(L_multi31x16_X2(range_h, range_l, shr(testval, 1)), cum)) + { + lowlim = testval; + move16(); + symbol = sub(symbol, shl(1, k)); + } + ELSE + { + highlim = testval; + move16(); + } + } + + highlim = shr(highlim, 1); + lowlim = shr(lowlim, 1); + } + + s->high = L_add(s->low, mul_sbc_14bits(range, highlim)); + move32(); + s->low = L_add(s->low, mul_sbc_14bits(range, lowlim)); + move32(); + + return symbol; +} + +static Word16 ari_lookup_sign(Tastat *s, Word16 base) +{ + Word32 cum, range; + Word16 symbol; + + (void)base; + + range = L_sub(s->high, s->low); + cum = L_sub(s->value, s->low); + range = L_shr(range, 1); + + IF (GT_32(range, cum)) + { + symbol = 1; + move16(); + s->high = L_add(s->low, range); + move32(); + } + ELSE + { + symbol = 0; + move16(); + s->low = L_add(s->low, range); + move32(); + } + + return symbol; +} + +static Word16 ari_decode_14bits_notbl( + Word16 *ptr, + Word16 bp, + Word16 bits, + Word16 *res, + Tastat *s, + Word16 base, + Word16 (*lookup_fn)(Tastat *s, Word16 base) +) +{ + Word16 symbol; + Word32 low, high, value; + + symbol = lookup_fn(s, base); + + low = L_add(s->low, 0); + high = L_add(s->high, 0); + value = L_add(s->value, 0); + + FOR (; bplow,low))&&(EQ_32(s->high,L_sub(high,1)))&&(EQ_32(s->value,value))))) + { + /* This should not happen except of bit errors. */ + s->high = 0; + move32(); + s->low = 0; + move32(); + *res = 0; + move16(); + return -1; + } + + s->low = low; + move32(); + s->high = high; + move32(); + s->value = value; + move32(); + + *res = symbol; + move16(); + + return bp; +} + +/*------------------------------------------------------------------------ + * Function: ari_decode_14bits_pow + * + * Decode a symbol which follows the exponential distribution. That is, + * symbols are in the following intervals + * + * p(x = 0) = 1 - exp(- 0.5 * base * 2) + * p(x = q>0) = exp(- (q-0.5)*base* 2) - exp(- (q+0.5)*base*2 ) + * + *-------------------------------------------------------------------------*/ +Word16 ari_decode_14bits_pow(Word16 *ptr, Word16 bp, Word16 bits, Word16 *res, Tastat *s, Word16 base) +{ + return ari_decode_14bits_notbl(ptr, bp, bits, res, s, base, ari_lookup_pow); +} + +/*------------------------------------------------------------------------ + * Function: ari_decode_14bits_sign + * + * Decode a sign with equal probabilities. + *-------------------------------------------------------------------------*/ +Word16 ari_decode_14bits_sign(Word16 *ptr, Word16 bp, Word16 bits, Word16 *res, Tastat *s) +{ + return ari_decode_14bits_notbl(ptr, bp, bits, res, s, 0, ari_lookup_sign); +} + diff --git a/lib_dec/ari_hm_dec.c b/lib_dec/ari_hm_dec.c index d2d7ffe55968d78ab79e6c71bfc0288b09ca0d36..1c6373e3fe545b55e8eeecde2fc371ab59a194f9 100644 --- a/lib_dec/ari_hm_dec.c +++ b/lib_dec/ari_hm_dec.c @@ -43,6 +43,7 @@ #include "prot.h" #include "rom_com.h" #include "wmc_auto.h" +#include "prot_fx2.h" /*-------------------------------------------------------------------* * DecodeIndex() @@ -76,6 +77,41 @@ int16_t DecodeIndex( } } +Word16 +DecodeIndex_fx( + Decoder_State *st, + Word16 Bandwidth, + Word16 *PeriodicityIndex) +{ + TCX_LTP_DEC_HANDLE hTcxLtpDec; + TCX_DEC_HANDLE hTcxDec; + + hTcxLtpDec = st->hTcxLtpDec; + hTcxDec = st->hTcxDec; + + test(); + IF((hTcxDec->tcx_hm_LtpPitchLag > 0) && GT_16(hTcxLtpDec->tcxltp_gain, kLtpHmGainThr)) + { + Word16 LtpPitchIndex = sub(mult_r(hTcxDec->tcx_hm_LtpPitchLag, 1 << (15 - kLtpHmFractionalResolution)), 2); + + *PeriodicityIndex = kLtpHmFlag; + move16(); + *PeriodicityIndex = s_or(*PeriodicityIndex, get_next_indice_fx(st, NumRatioBits[Bandwidth][LtpPitchIndex])); + *PeriodicityIndex = add(*PeriodicityIndex, 1); + move16(); + *PeriodicityIndex = s_or(*PeriodicityIndex, shl(LtpPitchIndex, 9)); + move16(); + + return NumRatioBits[Bandwidth][LtpPitchIndex]; + } + ELSE + { + *PeriodicityIndex = get_next_indice_fx(st, 8); + move16(); + return 8; + } +} + /*-------------------------------------------------------------------* * tcx_hm_dequantize_gain() @@ -129,12 +165,12 @@ static Word16 tcx_hm_dequantize_gain_fx( /*-------------------------------------------------------------------* - * tcx_hm_decode() + * tcx_hm_decode_ivas() * * *-------------------------------------------------------------------*/ -void tcx_hm_decode( +void tcx_hm_decode_ivas( const int16_t L_frame, /* i : number of spectral lines */ Word32 env[], /* i/o: envelope shape (Q16) */ const int16_t targetBits, /* i : target bit budget */ @@ -158,7 +194,7 @@ void tcx_hm_decode( return; } - NumTargetBits = CountIndexBits( L_frame >= 256, prm_hm[1] ) + targetBits; + NumTargetBits = CountIndexBits_ivas( L_frame >= 256, prm_hm[1] ) + targetBits; if ( coder_type == VOICED ) { @@ -167,11 +203,11 @@ void tcx_hm_decode( *hm_bits = NumTargetBits - targetBits + 1; /* Convert the index to lag */ - UnmapIndex( prm_hm[1], L_frame >= 256, LtpPitchLag, ( NumTargetBits <= kSmallerLagsTargetBitsThreshold ) || ( L_frame < 256 ), &fract_res, &tmpL ); + UnmapIndex_ivas( prm_hm[1], L_frame >= 256, LtpPitchLag, ( NumTargetBits <= kSmallerLagsTargetBitsThreshold ) || ( L_frame < 256 ), &fract_res, &tmpL ); lag = (int16_t) tmpL; /* Render the harmonic model */ - if ( tcx_hm_render( lag, fract_res, p ) ) + if ( tcx_hm_render_ivas( lag, fract_res, p ) ) { /* A bit error was encountered */ *hm_bits = -1; @@ -186,12 +222,12 @@ void tcx_hm_decode( *hm_bits = -1; return; } - tcx_hm_modify_envelope( gain, lag, fract_res, p, env, L_frame ); + tcx_hm_modify_envelope_ivas( gain, lag, fract_res, p, env, L_frame ); return; } -void tcx_hm_decode_fx( +void tcx_hm_decode( const Word16 L_frame, /* i : number of spectral lines */ Word32 env[], /* i/o: envelope shape (Q16) */ const Word16 targetBits, /* i : target bit budget */ diff --git a/lib_dec/arith_coder_dec.c b/lib_dec/arith_coder_dec.c index 12103c5113a48e4fd0f52e312ced4e8a273b26c5..8ebb7770eb6c841c638a593bfdfeb5315f5b70c3 100644 --- a/lib_dec/arith_coder_dec.c +++ b/lib_dec/arith_coder_dec.c @@ -46,13 +46,13 @@ #include "prot_fx1.h" /*-------------------------------------------------------* - * tcx_arith_decode() + * tcx_arith_decode_flt() * * *-------------------------------------------------------*/ /*! r: number of bits consumed */ -static int16_t tcx_arith_decode( +static int16_t tcx_arith_decode_flt( const int16_t L_frame, /* i : number of spectral lines */ const Word16 envelope[], /* i : scaled envelope (Q15-e) */ Word16 envelope_e, /* i : scaled envelope exponent (Q0) */ @@ -67,7 +67,7 @@ static int16_t tcx_arith_decode( uint16_t exp_k; Word16 tmp; - bp = ari_start_decoding_14bits_prm( prm, 0, &as ); + bp = ari_start_decoding_14bits_prm_ivas( prm, 0, &as ); tmp = sub( envelope_e, 1 ); for ( k = 0; k < L_frame; ++k ) @@ -80,16 +80,16 @@ static int16_t tcx_arith_decode( } else { - exp_k = expfp( negate( envelope[k] ), tmp ); + exp_k = expfp_evs( negate( envelope[k] ), tmp ); } /* decode line magnitude */ - bp = ari_decode_14bits_pow( prm, bp, target_bits, &q, &as, exp_k ); + bp = ari_decode_14bits_pow_ivas( prm, bp, target_bits, &q, &as, exp_k ); if ( q ) { /* line is non-zero, decode sign */ - bp = ari_decode_14bits_sign( prm, bp, target_bits, &s, &as ); + bp = ari_decode_14bits_sign_ivas( prm, bp, target_bits, &s, &as ); q_spectrum[k] = (float) q * ( 3 - 2 * s ); } else @@ -132,7 +132,7 @@ static Word16 tcx_arith_decode_fx( Word16 tmp; Word32 L_tmp; - bp = ari_start_decoding_14bits_prm_fx( prm, 0, &as ); + bp = ari_start_decoding_14bits_prm_fx_ivas( prm, 0, &as ); tmp = sub(envelope_e, 1); @@ -147,16 +147,16 @@ static Word16 tcx_arith_decode_fx( } ELSE { - exp_k = expfp( negate( envelope[k] ), tmp ); + exp_k = expfp_evs( negate( envelope[k] ), tmp ); } /* decode line magnitude */ - bp = ari_decode_14bits_pow( prm, bp, target_bits, &q, &as, exp_k ); + bp = ari_decode_14bits_pow_ivas( prm, bp, target_bits, &q, &as, exp_k ); IF ( q != 0 ) { /* line is non-zero, decode sign */ - bp = ari_decode_14bits_sign( prm, bp, target_bits, &s, &as ); + bp = ari_decode_14bits_sign_ivas( prm, bp, target_bits, &s, &as ); q_spectrum[k] = L_mult(q, sub(3, shl(s, 1))); q_spectrum[k] = L_shl(q_spectrum[k], 30 - SPEC_EXP_DEC); } @@ -186,12 +186,12 @@ static Word16 tcx_arith_decode_fx( /*-------------------------------------------------------* - * tcx_arith_decode_envelope() + * tcx_arith_decode_envelope_flt() * * *-------------------------------------------------------*/ -void tcx_arith_decode_envelope( +void tcx_arith_decode_envelope_flt( Decoder_State *st, /* i/o: coder state */ float q_spectrum[], /* o : quantised MDCT coefficients */ const int16_t L_frame, /* i : frame or MDCT length */ @@ -238,14 +238,14 @@ void tcx_arith_decode_envelope( gamma_uw = 1.0f / st->gamma_float; #define WMC_TOOL_SKIP - tcx_arith_render_envelope( A_ind, L_frame, L_spec, FL2WORD16( hTcxCfg->preemph_fac_flt), FL2WORD16( gamma_w ), FL2WORD16( 0.5f * gamma_uw ), env ); + tcx_arith_render_envelope_flt( A_ind, L_frame, L_spec, FL2WORD16( hTcxCfg->preemph_fac_flt), FL2WORD16( gamma_w ), FL2WORD16( 0.5f * gamma_uw ), env ); #undef WMC_TOOL_SKIP if ( use_hm ) { if ( prm_hm[0] ) { - tcx_hm_decode( L_spec, env, target_bits, st->coder_type, prm_hm, tcxltp_pitch, &hm_bits ); + tcx_hm_decode_ivas( L_spec, env, target_bits, st->coder_type, prm_hm, tcxltp_pitch, &hm_bits ); if ( hm_bits < 0 ) { @@ -271,9 +271,9 @@ void tcx_arith_decode_envelope( } envelope = (Word16 *) env; - tcx_arith_scale_envelope( L_spec, L_spec_core, env, target_bits, low_complexity, envelope, &envelope_e ); + tcx_arith_scale_envelope_flt( L_spec, L_spec_core, env, target_bits, low_complexity, envelope, &envelope_e ); - *arith_bits = tcx_arith_decode( L_spec, envelope, envelope_e, target_bits, prm, q_spectrum ); + *arith_bits = tcx_arith_decode_flt( L_spec, envelope, envelope_e, target_bits, prm, q_spectrum ); /* safety check in case of bit errors */ if ( *arith_bits < 0 ) @@ -346,14 +346,14 @@ void tcx_arith_decode_envelope_fx( move16(); #define WMC_TOOL_SKIP - tcx_arith_render_envelope( A_ind, L_frame, L_spec, hTcxCfg->preemph_fac, gamma_w, gamma_uw, env ); + tcx_arith_render_envelope_flt( A_ind, L_frame, L_spec, hTcxCfg->preemph_fac, gamma_w, gamma_uw, env ); #undef WMC_TOOL_SKIP IF (use_hm != 0) { IF (prm_hm[0] != 0) { - tcx_hm_decode_fx( L_spec, env, target_bits, st->coder_type, prm_hm, tcxltp_pitch, &hm_bits ); + tcx_hm_decode( L_spec, env, target_bits, st->coder_type, prm_hm, tcxltp_pitch, &hm_bits ); IF (hm_bits < 0) { @@ -385,7 +385,7 @@ void tcx_arith_decode_envelope_fx( } envelope = (Word16 *) env; - tcx_arith_scale_envelope( L_spec, L_spec_core, env, target_bits, low_complexity, envelope, &envelope_e ); + tcx_arith_scale_envelope_flt( L_spec, L_spec_core, env, target_bits, low_complexity, envelope, &envelope_e ); *arith_bits = tcx_arith_decode_fx( L_spec, envelope, envelope_e, target_bits, prm, q_spectrum, q_spectrum_e ); move16(); diff --git a/lib_dec/arith_coder_dec_fx.c b/lib_dec/arith_coder_dec_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..05696b29858eae7c5e6c836d3ca5fb46d68f1aba --- /dev/null +++ b/lib_dec/arith_coder_dec_fx.c @@ -0,0 +1,210 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include +#include +#include "options.h" +#include "cnst.h" +#include "rom_com.h" +#include "prot_fx1.h" +#include "prot_fx2.h" + +/* Returns: number of bits consumed */ +static Word16 tcx_arith_decode( + Word16 L_frame, /* i: number of spectral lines Q0 */ + const Word16 envelope[], /* i: scaled envelope Q15-e */ + Word16 envelope_e, /* i: scaled envelope exponent Q0 */ + Word16 target_bits, /* i: target bit budget Q0 */ + Word16 prm[], /* i: bit-stream Q0 */ + Word32 q_spectrum[], /* o: scalar quantized spectrum Q31-e */ + Word16 *q_spectrum_e, /* o: spectrum exponent Q0 */ + Word16 *nf_seed /* o: noise filling seed Q0 */ +) +{ + Word16 bp, k, q, s; + Tastat as; + Word16 exp_k; + Word16 tmp; + Word32 L_tmp, Q; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; + Flag Carry = 0; +#endif + + + bp = ari_start_decoding_14bits_prm(prm, 0, &as); + + tmp = sub(envelope_e, 1+15); + L_tmp = L_deposit_l(0); + FOR (k = 0; k < L_frame; k++) + { + IF( envelope[k] == 0 ) /* safety check in case of bit errors */ + { + set32_fx(q_spectrum, 0, L_frame); + return -1; + } + ELSE + { + exp_k = round_fx(expfp(envelope[k], tmp)); + } + /* decode line magnitude */ + bp = ari_decode_14bits_pow(prm, bp, target_bits, &q, &as, exp_k); + + if (q == 0) + { + q_spectrum[k] = L_deposit_l(0); + } + IF (q != 0) /* line is non-zero, decode sign */ + { + bp = ari_decode_14bits_sign(prm, bp, target_bits, &s, &as); + +#ifdef BASOP_NOGLOB + L_tmp = L_macNs_co(L_tmp, q, k, &Carry, &Overflow); +#else + L_tmp = L_macNs(L_tmp, q, k); +#endif + + Q = L_mult(q, -(1<<(30 - SPEC_EXP_DEC))); + if (s == 0) Q = L_mult(q, 1 << (30 - SPEC_EXP_DEC)); + q_spectrum[k] = Q; + move32(); + } + + IF (ari_decode_overflow(&as)) + { + if( LT_16(bp, target_bits)) /* safety check in case of bit errors */ + { + bp = -1; + move16(); + } + BREAK; /* no bits left, so exit loop */ + } + } + *q_spectrum_e = SPEC_EXP_DEC; + move16(); + + set32_fx(q_spectrum+k, 0, sub(L_frame, k)); + + /* noise filling seed */ + *nf_seed = extract_l(L_tmp); + + + return bp; +} + +void tcx_arith_decode_envelope( + Word32 q_spectrum[], /* o: quantised MDCT coefficients Q31-e */ + Word16 *q_spectrum_e, /* o: MDCT exponent Q0 */ + Word16 L_frame, /* i: frame or MDCT length Q0 */ + Word16 L_spec, /* i: length w/o BW limitation Q0 */ + Decoder_State *st, + const Word16 A_ind[], /* i: quantised LPC coefficients Q12 */ + Word16 target_bits, /* i: number of available bits Q0 */ + Word16 prm[], /* i: bitstream parameters Q0 */ + Word8 use_hm, /* i: use HM in current frame? */ + Word16 prm_hm[], /* i: HM parameter area Q0 */ + Word16 tcxltp_pitch, /* i: TCX LTP pitch in FD, -1 if n/a Q0*/ + Word16 *arith_bits, /* o: bits used for ari. coding Q0 */ + Word16 *signaling_bits, /* o: bits used for signaling Q0 */ + Word16 *nf_seed /* o: noise filling seed Q0 */ + ,Word16 low_complexity /* i: low-complexity flag Q0 */ +) +{ + Word32 env[N_MAX_ARI]; /* unscaled envelope */ + Word16 *envelope; /* scaled envelope */ + Word16 envelope_e; + Word16 L_spec_core; + TCX_CONFIG_HANDLE tcx_cfg; + Word16 gamma_w, gamma_uw; + Word16 hm_bits; + tcx_cfg = st->hTcxCfg; + + test(); + test(); + + IF( GT_16(L_spec,N_MAX_ARI)|| (EQ_16(st->element_mode, EVS_MONO) && GT_16(target_bits,(ACELP_13k20/ FRAMES_PER_SEC))) || + (EQ_16(st->element_mode, IVAS_SCE) && (GT_16(st->bits_frame_nominal, (LPC_SHAPED_ARI_MAX_RATE / FRAMES_PER_SEC)))) || + (GT_16(st->element_mode, IVAS_SCE) && (GT_16(st->bits_frame_nominal, (LPC_SHAPED_ARI_MAX_RATE_CPE / FRAMES_PER_SEC)))) || + (target_bits <= 0)) + { + /* this could happen in case of bit errors */ + st->BER_detect = 1; + move16(); + L_spec = N_MAX_ARI; + move16(); + *signaling_bits = 0; + move16(); + *arith_bits = 0; + move16(); + set32_fx( q_spectrum, 0, L_frame ); + + return; + } + + + *signaling_bits = 0; + move16(); + assert(st->hTcxDec->enableTcxLpc); + + gamma_w = 32767/*1.0f Q15*/; + move16(); + gamma_uw = st->inv_gamma; + move16(); + + tcx_arith_render_envelope(A_ind, L_frame, L_spec, tcx_cfg->preemph_fac, gamma_w, gamma_uw, env); + + IF (use_hm != 0) + { + IF (prm_hm[0] != 0) + { + tcx_hm_decode(L_spec, env, target_bits, tcx_cfg->coder_type, prm_hm, tcxltp_pitch, &hm_bits); + + IF (hm_bits < 0) + { + st->BER_detect = 1; + move16(); + *signaling_bits = 0; + move16(); + *arith_bits = 0; + move16(); + set32_fx( q_spectrum, 0, L_frame ); + return; + } + } + ELSE + { + hm_bits = 1; + move16(); + } + *signaling_bits = add(*signaling_bits, hm_bits); + move16(); + } + ELSE + { + prm_hm[0] = 0; /* just to be sure */ move16(); + } + + L_spec_core = L_spec; + move16(); + if (st->igf) + { + L_spec_core = s_min(L_spec_core, st->hIGFDec->infoIGFStartLine); + } + envelope = (Word16*)env; + + tcx_arith_scale_envelope(L_spec, L_spec_core, env, target_bits, low_complexity, envelope, &envelope_e); + + *arith_bits = tcx_arith_decode(L_spec, envelope, envelope_e, target_bits, prm, q_spectrum, q_spectrum_e, nf_seed); + move16(); + + /* safety check in case of bit errors */ + IF( *arith_bits < 0 ) + { + st->BER_detect = 1; + move16(); + set32_fx(q_spectrum, 0, L_frame); + } + + set32_fx(q_spectrum + L_spec, 0, sub(L_frame, L_spec)); +} diff --git a/lib_dec/avq_dec.c b/lib_dec/avq_dec.c index 6a7245d9d1e1e2eb2907a1fe18ae0b65393ae163..065dc76217faaa15c069c98113fc4db9863df0fd 100644 --- a/lib_dec/avq_dec.c +++ b/lib_dec/avq_dec.c @@ -286,13 +286,13 @@ void AVQ_demuxdec( /*-----------------------------------------------------------------* - * AVQ_dec_lpc() + * AVQ_dec_lpc_ivas() * * Demultiplex and decode subvectors for LPC dequantization * using split algebraic vector dequantizer *-----------------------------------------------------------------*/ -void AVQ_dec_lpc( +void AVQ_dec_lpc_ivas( const int16_t indx[], /* i : index[] (4 bits per words) */ int16_t nvecq[], /* o : vector quantized */ const int16_t Nsv /* i : number of subvectors (lg=Nsv*8) */ diff --git a/lib_dec/avq_dec_fx.c b/lib_dec/avq_dec_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..7ab3e51c83395c546f1e061f95a9cd4fe83ae72c --- /dev/null +++ b/lib_dec/avq_dec_fx.c @@ -0,0 +1,290 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + + +#include +#include "options.h" /* Compilation switches */ +#include "cnst.h" /* Common constants */ +#include "rom_com.h" /* Static table prototypes */ +#include "prot_fx1.h" /* Function prototypes */ +#include "prot_fx2.h" /* Function prototypes */ + +/*-----------------------------------------------------------------* + * Function AVQ_Demuxdec_Bstr * + * ~~~~~~~~~~~~~~~~~~ * + * Read indexes from one bitstream and decode subvectors. * + *-----------------------------------------------------------------*/ + +void AVQ_demuxdec_fx( + Decoder_State *st_fx,/* i/o: decoder state structure */ + Word16 xriq[], /* o: decoded subvectors [0..8*Nsv-1] */ + Word16 *nb_bits, /* i/o: number of allocated bits */ + const Word16 Nsv, /* i: number of subvectors */ + Word16 nq[] /* i/o: AVQ nq index */ +#ifdef IVAS_CODE_AVQ + ,Word16 avq_bit_sFlag, /* i : flag for AVQ bit saving solution */ + Word16 trgtSvPos /* i : target SV for AVQ bit savings */ +#endif +) +{ + Word16 i,j, bits, order_v; + UWord16 I[NSV_MAX]; + Word16 *kv, code[8]; + Word16 tmp16; +#ifdef IVAS_CODE_AVQ + Word16 nq_est, unused_bits_idx; + Word16 bitsMod; + Word16 underflow; + Word16 unusedbitsFlag; + Word16 svOrder[NSV_MAX], k, nullVec, dummy_bits; +#endif + + set16_fx( (Word16*)I, 0, NSV_MAX ); + set16_fx( code, 0, 8 ); + + kv = xriq; /* reuse vector to save memory */ + bits = *nb_bits; + move16(); +#ifdef IVAS_CODE_AVQ + bitsMod = 0; + move16(); + underflow = 0; + move16(); + unusedbitsFlag = 0; + move16(); + nullVec = 0; + move16(); + dummy_bits = 0; + move16(); + svOrder[Nsv - 1] = trgtSvPos; + move16(); + svOrder[0] = 0; + move16(); + svOrder[1] = 1; + move16(); + i = 2; + move16(); + j = i; + move16(); + if (EQ_16(avq_bit_sFlag, 2)) + { + j = add(i, 1); + } + + WHILE (LT_16(i, sub(Nsv, 1))) + { + move16(); + svOrder[i] = j; + i++; + j++; + } +#endif + FOR( i=0; iBER_detect = 1; + move16(); + set16_fx( xriq, 0, shl(Nsv,3) ); + set16_fx( nq, 0, Nsv ); + *nb_bits = 0; + move16(); + + return; + } + + bits = sub(bits,nq[i]); + bits = sub(bits,1); /* count the stop bit */ + + if( nq[i] > 0 ) + { + nq[i] = add(nq[i],1); + move16(); + } + + /* read codebook indices (rank I and event. Voronoi index kv) */ + IF( nq[i] != 0 ) /* for Q0 nothing to read */ + { + IF( LT_16(nq[i], 5)) /* Q2, Q3, Q4 */ + { + tmp16 = shl(nq[i], 2); + order_v = 0; + move16(); + } + ELSE /* for Q3/Q4 + Voronoi extensions r=1,2 */ + { + j = 1; + move16(); + if( s_and(nq[i], 1) == 0 ) + { + j = add(j,1); + } + order_v = sub(shr(nq[i], 1), j); /* Voronoi order determination */ + tmp16 = shl(add(j, 2), 2); + } + + I[i] = get_next_indice(st_fx, tmp16 ); + move16(); + bits = sub(bits, tmp16); + + IF( order_v > 0 ) + { + tmp16 = shl(i, 3); + FOR( j=0; j<8; j++ ) + { + kv[tmp16+j] = (Word16)get_next_indice(st_fx, order_v ); + move16(); + } + bits = sub(bits, shl(order_v, 3)); + } + } + } + } + + /* decode all subvectors */ + FOR( i=0; i=0; l--) + { + nq = indx[l]; /* quantizer number (0,2,3..n) */ move16(); + + nk = 0; + move16(); + n = nq; + move16(); + + IF (GT_16(nq, 4)) + { + nk = shr(sub(nq, 3), 1); + n = sub(nq, shl(nk, 1)); + } + + /* read n groups of 4-bit for Voronoi index (k[]) */ + + FOR (i=0; i<8; i++) + { + kv[i] = 0; + move16(); + } + + FOR ( ; nk > 0; nk--) + { + ival = s_and(indx[pos--], 0x0F); + ival = shl(ival, 4); + ival = add(ival, s_and(indx[pos--], 0x0F)); + + FOR (i=7; i>=0; i--) + { + kv[i] = shl(kv[i], 1); + kv[i] = add(kv[i], s_and(ival, 0x01)); + move16(); + ival = shr(ival, 1); + } + } + + /* read n groups of 4-bit for base codebook index (I) */ + I = L_deposit_l(0); + FOR (; n > 0; n--) + { + I = L_shl(I, 4); + I = L_add(I, (Word32) s_and(indx[pos--], 0x0F)); + } + + /* multi-rate RE8 decoder */ + I16 = (UWord16)extract_l(I); + cast16(); + re8_dec_fx(nq, I16, kv, c); + + /* write decoded RE8 vector */ + FOR (i=0; i<8; i++) + { + nvecq[(l*8)+i] = c[i]; + move16(); + } + } + + return; +} diff --git a/lib_dec/bass_psfilter.c b/lib_dec/bass_psfilter.c index 94538e1e7ce76c09fc79749449afd99cb8a7740c..0c5446c5b8a8383c3f40ac1dd74482e66cf3d5e9 100644 --- a/lib_dec/bass_psfilter.c +++ b/lib_dec/bass_psfilter.c @@ -492,7 +492,7 @@ void addBassPostFilter( } /* do the analysis of filtered signal */ - cldfbAnalysis( harm_timeIn, tmp_R, tmp_I, samplesToProcess, cldfb ); + cldfbAnalysis_ivas( harm_timeIn, tmp_R, tmp_I, samplesToProcess, cldfb ); /* now do the subtraction */ for ( i = 0; i < nColToProcess; i++ ) diff --git a/lib_dec/bass_psfilter_fx.c b/lib_dec/bass_psfilter_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..7a5d8476bdb34f004550f10c8e74eb86529c170f --- /dev/null +++ b/lib_dec/bass_psfilter_fx.c @@ -0,0 +1,1069 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include +#include +#include "options.h" /* Compilation switches */ +#include "prot_fx1.h" /* Function prototypes */ +#include "prot_fx2.h" /* Function prototypes */ +#include "cnst.h" /* Common constants */ +#include "rom_com.h" /* Static table prototypes */ +#include "rom_dec.h" /* Static table prototypes */ +#include "basop_util.h" + +/*---------------------------------------------------------------------* + * Local constants + *---------------------------------------------------------------------*/ + +#define NBPSF_L_EXTRA 120 +#define BPF_STOP_STOPBAND_16 16 + +/*---------------------------------------------------------------------* + * Local function prototypes + *---------------------------------------------------------------------*/ +static Word16 Pit_track_fx(Word16 syn[], Word16 T); + +/*---------------------------------------------------------------------* + * bass_psfilter_init() + * + * Initialisation of postfiltering variables + *---------------------------------------------------------------------*/ +void bass_psfilter_init_fx( + BPF_DEC_HANDLE hBPF /* o : BPF data handle */ +) +{ + /* post-filter memories */ + hBPF->pst_mem_deemp_err_fx = 0; + move16(); + hBPF->pst_lp_ener_fx = 0; + move16();/*0 in Q8 */ + set16_fx(hBPF->pst_old_syn_fx, 0, NBPSF_PIT_MAX); + set16_fx(hBPF->Track_on_hist_fx, 0, L_TRACK_HIST); + set16_fx(hBPF->vibrato_hist_fx, 0, L_TRACK_HIST); + set16_fx(hBPF->mem_mean_pit_fx, 80, L_TRACK_HIST); + hBPF->psf_att_fx = 32767; + + return; +} + +/*=========================================================================*/ +/* FUNCTION : void bass_psfilter_fx () */ +/*-------------------------------------------------------------------------*/ +/* PURPOSE : */ +/*-------------------------------------------------------------------------*/ +/* INPUT ARGUMENTS : */ +/* _ Word16 synth_in_fx[], Q_syn2-1 i :input synthesis (at 16kHz) */ +/* _ const Word16 L_frame, i : length of the last frame */ +/* _ Word16 pitch_buf_fx[],Q6 i : pitch for every subfr [0,1,2,3] */ +/* _ const Word16 bpf_off, i : do not use BPF when set to 1 */ +/* _ Word16 v_stab_fx, Q15 i : stability factor */ +/* _ Word16 Q_syn i : Q format of synth_in_fx */ +/*-------------------------------------------------------------------------*/ +/* OUTPUT ARGUMENTS : */ +/* _ Word16 *mem_deemph_err, Q_syn2-1 */ +/* o : Error deemphasis memory */ +/* _ Word16 *lp_ener, Q8 o : long_term error signal energy */ +/*-------------------------------------------------------------------------*/ +/* INPUT/OUTPUT ARGUMENTS : */ +/* _ Word16 old_syn_fx[], Q_syn2-1 i/o: NBPSF_PIT_MAX */ +/* _ Word16 *v_stab_smooth_fx,Q15 i/o: smoothed stability factor */ +/*-------------------------------------------------------------------------*/ +/* RETURN ARGUMENTS : */ +/* _ None */ +/*-------------------------------------------------------------------------*/ +/* CALLED FROM : TX/RX */ +/*=========================================================================*/ + +void bass_psfilter_fx( + BPF_DEC_HANDLE hBPF, /* i/o: BPF data handle */ + const Word16 Opt_AMR_WB, /* i : AMR-WB IO flag */ + Word16 synth_in_fx[], /* i : input synthesis (at 16kHz) */ + const Word16 L_frame, /* i : length of the last frame */ + Word16 pitch_buf_fx[], /* i : pitch for every subfr [0,1,2,3] */ + const Word16 bpf_off, /* i : do not use BPF when set to 1 */ + Word16 v_stab_fx, /* i : stability factor */ + Word16 *v_stab_smooth_fx, /* i/o: smoothed stability factor */ + const Word16 coder_type, /* i : coder_type */ + Word16 Q_syn, + Word16 bpf_noise_buf[] /* o : BPF error signal (at int_fs) */ +) +{ + Word16 i, j, i_subfr, T, exp, exp2; + Word16 tmp, gain, alpha, tmp2; + Word32 Lcorr, Lener; + Word32 Lcorr0,Lener0,Ltmp; + Word16 syn_buf_fx[NBPSF_PIT_MAX+L_FRAME16k+NBPSF_PIT_MAX], *syn_fx; + Word16 syn2_buf_fx[L_FRAME16k], *syn2_fx; + Word16 err[L_HALFR16k], *sigPtr, *sigPtr1; + Word16 T_sf[NB_SUBFR16k]; + Word16 subfr_pos; + Word16 nb_subfr; + Word16 delta_v_stab; + Word16 T_update = 0; + Word16 dist_pit_diff, idx_pit_min, idx_pit_max, vibrato, Track_on; + Word16 loc_pit_max, loc_pit_min, diff_pit; + Word16 TrackOnR, vibratR, alp_tmp; + Word16 Q_syn2x; + Word16 subfr_len; + Word16 nbpsf_pit_max; + + Track_on = 0; + move16(); + vibrato = 0; + move16(); + IF(EQ_16(L_frame, L_FRAME8k)) + { + subfr_len = STEREO_DFT_L_SUBFR_8k; + move16(); + nbpsf_pit_max = STEREO_DFT_NBPSF_PIT_MAX_8k; + move16(); + nb_subfr = shr(L_frame,5); + } + ELSE + { + subfr_len = L_SUBFR; + move16(); + nbpsf_pit_max = NBPSF_PIT_MAX; + move16(); + nb_subfr = shr(L_frame,6); + } + move16(); + + /*------------------------------------------------------- + * Initialize pointers to various synthesis buffers + * + * |--------------------syn_buf--------------------------------| + * |-----old_syn-----|-------synth_in--------|----extrapol---- | + * |--NBPSF_PIT_MAX--| sf1 | sf2 | sf3 | sf4 |--NBPSF_PIT_MAX--| + * |------syn2_buf---------| + * |------L_frame----------| + * |----bpf_noise_buf------| + * + *-------------------------------------------------------*/ + Q_syn2x = shl(Q_syn, 1); + move16(); + + Copy(hBPF->pst_old_syn_fx, syn_buf_fx, nbpsf_pit_max); + Copy(synth_in_fx, syn_buf_fx+nbpsf_pit_max, L_frame); + + test(); + IF( !(pitch_buf_fx == NULL || bpf_off) ) + { + FOR(i = L_TRACK_HIST-1; i > 0; i--) + { + hBPF->mem_mean_pit_fx[i] = hBPF->mem_mean_pit_fx[i-1]; + move16(); /*Q6 */ + } + Ltmp = L_deposit_l(0); + FOR(j=0; j Q4*/ + if(EQ_16(nb_subfr,5)) + { + tmp = mult_r(tmp, 26214); /* multiply by 0.8 for case where L_frame == L_FRAME16k*/ + } + hBPF->mem_mean_pit_fx[i] = tmp; /*Q4 */ move16(); + } + idx_pit_min = minimum_fx(hBPF->mem_mean_pit_fx, L_TRACK_HIST, &loc_pit_min); + idx_pit_max = maximum_fx(hBPF->mem_mean_pit_fx, L_TRACK_HIST, &loc_pit_max); + + dist_pit_diff = abs_s(sub(idx_pit_max,idx_pit_min)); + diff_pit = sub(loc_pit_max,loc_pit_min); /*Q4 */ + test(); + if( EQ_16(L_frame,L_FRAME16k) || EQ_16(L_frame, L_FRAME8k)) + { + diff_pit = mult_r(diff_pit,26214); /*Q4 */ + } + + test(); + test(); + test(); + if( coder_type != INACTIVE && GE_16(diff_pit,2<<4)&<_16(diff_pit,10<<4)&&GE_16(dist_pit_diff,3)) + { + vibrato = 1; + move16(); + } + + tmp = sum16_fx(hBPF->Track_on_hist_fx,L_TRACK_HIST); +#ifdef BASOP_NOGLOB + TrackOnR = round_fx_sat(L_shl_sat(L_mult0(tmp,3277),16)); /*Q15 */ +#else + TrackOnR = round_fx(L_shl(L_mult0(tmp,3277),16)); /*Q15 */ +#endif + vibratR = sum16_fx(hBPF->vibrato_hist_fx,L_TRACK_HIST); /*Q0 */ + + alp_tmp = sub(32767,TrackOnR); /*Q15 */ + + IF( vibrato ) + { + /* vibratR = vibratR * vibratR * -0.009f + 1.0f;move16(); */ + tmp = round_fx(L_shl(L_mult0(vibratR,vibratR),16)); /*Q0 */ + tmp = round_fx(L_shl(L_mult(tmp,18874),9)); /*Q15 */ + vibratR = sub(32767,tmp); /*Q15 */ + alp_tmp = mult_r(alp_tmp,vibratR); /*Q15 */ + } + + alp_tmp = s_max( 3277, alp_tmp ); + + IF( GT_16(alp_tmp, hBPF->psf_att_fx)) + { + /**psf_att = add(mult_r(1638,alp_tmp),mult_r(31130,*psf_att)); //Q15 */ + hBPF->psf_att_fx = round_fx(L_mac(L_mult(1638,alp_tmp),31130, hBPF->psf_att_fx)); /*Q15 */ + } + ELSE + { + /**psf_att = add(mult_r(13107,alp_tmp),mult_r(19661,*psf_att)); //Q15 */ + hBPF->psf_att_fx = round_fx(L_mac(L_mult(13107,alp_tmp),19661,hBPF->psf_att_fx)); /*Q15 */ + } + test(); + IF( pitch_buf_fx == NULL || bpf_off ) + { + /* do not use BPF for HQ core */ + T_update = 80; + if (EQ_16(L_frame, L_FRAME8k)) + { + T_update = 40; + } + move16(); + set16_fx( T_sf, 0, 5 ); + syn_fx = &syn_buf_fx[add(nbpsf_pit_max,L_frame)]; + sigPtr = syn_fx-T_update; + FOR (i=0; i< nbpsf_pit_max; i++) + { + syn_fx[i] = sigPtr[i]; + move16(); + } + } + ELSE + { + /* extrapolation of synth_in_fx */ + FOR ( i=0; ipst_lp_ener_fx), &tmp2); /* 2786635L is Q31 : 0.1xLog2(10) / 256 (/256 because lp_ener is Q8) */ + /* Note: 'Ltmp' is still the absolute value of 'Lcorr' + 'tmp' is still 'Ltmp' normalized and rounded to 16 bits + However, exp has to be recalculated because it is affected by exp = sub(exp, 1) before the div_s */ + exp = norm_l(Ltmp); + tmp2 = sub(tmp2, 1+4); /* substract 1 because 'Lener' is divided by two */ + tmp2 = add(tmp2, Q_syn2x); + tmp2 = s_max(0, s_min(30, tmp2)); +#ifdef BASOP_NOGLOB + Lener = L_add_sat(Lener, Pow2(tmp2, exp2)); +#else + Lener = L_add(Lener, Pow2(tmp2, exp2)); +#endif + exp2 = norm_l(Lener); +#ifdef BASOP_NOGLOB + tmp2 = round_fx_sat(L_shl(Lener, exp2)); +#else + tmp2 = round_fx(L_shl(Lener, exp2)); +#endif + if (GT_16(tmp, tmp2)) + { + exp = sub(exp, 1); + } + exp2 = sub(exp, exp2); /* exponent num - exponent denom */ + /* alpha = corr / ener */ +#ifdef BASOP_NOGLOB + alpha = shr_sat(div_s(round_fx(L_shl(Ltmp, exp)), tmp2), exp2); /*Q15 */ +#else + alpha = shr(div_s(round_fx(L_shl(Ltmp, exp)), tmp2), exp2); /*Q15 */ +#endif + if (Lcorr < 0) + { + alpha = sub(0, alpha); + } + + alpha = s_min(alpha, 16384);/*Q15 */ + + alpha = mult_r(alpha,hBPF->psf_att_fx); + test(); + test(); + IF (GT_16(alpha,9830)&&Track_on) + { + alpha = 9830; + move16(); + } + ELSE if (GT_16(alpha,13107)&&vibrato) + { + alpha = 13107; + move16(); + } + + alpha = s_max(alpha, 0); + + /**v_stab_smooth_fx = 0.8f * v_stab_fx + 0.2f * (*v_stab_smooth_fx); */ + tmp = mult(*v_stab_smooth_fx,6554); /*Q15 and 6554 is 0.2 in Q15 */ + tmp2= mult(v_stab_fx,26214);/*Q15 and 26214 is 0.8 in Q15 */ + *v_stab_smooth_fx = add(tmp2,tmp); + move16(); + + /*delta_v_stab = (float) fabs(*v_stab_smooth_fx - v_stab_fx); */ + tmp = sub(*v_stab_smooth_fx,v_stab_fx); /*Q15 */ + delta_v_stab = abs_s(tmp); + + /*v_stab_fx = (float) pow(v_stab_fx, 0.5f); */ + v_stab_fx = Frac_sqrt(v_stab_fx); + + /*alpha = (1.0f + 0.15f*v_stab_fx - 2.0f*delta_v_stab) * alpha; */ + tmp = mult(2458,v_stab_fx);/*Q14 */ + tmp = add(16384,tmp);/*Q14 */ + tmp = sub(tmp,delta_v_stab);/*Q14 */ + alpha = mult(tmp,alpha);/*Q14 */ + + FOR (i=0; i< subfr_len; i++) + { + /*syn2_fx[i] = alpha*(syn_fx[i]-syn2_fx[i]); */ + tmp = sub(syn_fx[i],syn2_fx[i]); +#ifdef BASOP_NOGLOB + syn2_fx[i] = mult_sat(alpha, shl_sat(tmp, 1)); +#else + syn2_fx[i] = mult(alpha,shl(tmp,1)); +#endif + move16();/*Q_syn2 */ + } + + /* low-frequency noise estimator (lp_ener is average in dB) */ + deemph_fx(err, 29491/*0.9*/, subfr_len, &(hBPF->pst_mem_deemp_err_fx)); /* +20dB at 50Hz */ + Lener = L_deposit_h(-32768); + /* by using the maximum negative value + it is possible to gain another bit + of range for the 'Lener' sum. + This sum is divided by 4 */ + FOR (i=0; i< subfr_len; i++) + { +#ifdef BASOP_NOGLOB + Lener = L_mac0_sat(Lener, err[i], err[i]); +#else + Lener = L_mac0(Lener, err[i], err[i]); +#endif + } + exp2 = -1-2; + move16(); + /* 'Lener' is divided by 2 */ + IF (EQ_32(Lener, 2147483647L)) + { + Lener = L_deposit_h(-32768); + sigPtr = err + subfr_len /2; + FOR (i=0; i< subfr_len /2; i++) + { + Lener0 = L_mult0(sigPtr[i], sigPtr[i]); +#ifdef BASOP_NOGLOB + Lener = L_add(Lener, L_shr(L_mac0_sat(Lener0, err[i], err[i]), 5)); +#else + Lener = L_add(Lener, L_shr(L_mac0(Lener0, err[i], err[i]), 5)); +#endif + } + exp2 = sub(exp2, 5); + } + Lener = L_shr(Lener, 1); + Lener = L_add(Lener, 0x40000001L); + /* ener = 10.0*log10(ener) */ + /* *lp_ener = 0.99f * *lp_ener + 0.01f * ener */ + tmp = norm_l(Lener); + exp = Log2_norm_lc(L_shl(Lener, tmp)); + tmp = sub(30, tmp); + tmp = sub(tmp, Q_syn2x); + tmp = sub(tmp, exp2); /* take care of exponent of 'Lener' */ + + Lener = L_Comp(tmp, exp); + Lener = Mpy_32_16_1(Lener, 31565); /* 31565 = Log10(2) x 0.1 x 2^15 x 32 (*32 to utilize all 15 bits) */ + Lener = L_shl(Lener, 3); + hBPF->pst_lp_ener_fx = mac_r(Lener, hBPF->pst_lp_ener_fx, 32440); + move16(); + + /* just write out the error signal */ + Copy( syn2_fx, bpf_noise_buf + i_subfr, subfr_len ); + } + ELSE + { + /* symetric pitch prediction : phase is opposite between harmonic */ + FOR (i=0; ipst_lp_ener_fx), &tmp2); /* 2786635L is Q31 : 0.1xLog2(10) / 256 (/256 because lp_ener is Q8) */ + /* Note: 'Ltmp' is still the absolute value of 'Lcorr' + 'tmp' is still 'Ltmp' normalized and rounded to 16 bits + However, exp has to be recalculated because it is affected by exp = sub(exp, 1) before the div_s */ + exp = norm_l(Ltmp); + tmp2 = sub(tmp2, 1+4); /* substract 1 because 'Lener' is divided by two */ + tmp2 = add(tmp2, Q_syn2x); + tmp2 = s_max(0, s_min(30, tmp2)); +#ifdef BASOP_NOGLOB + Lener = L_add_sat(Lener, Pow2(tmp2, exp2)); +#else + Lener = L_add(Lener, Pow2(tmp2, exp2)); +#endif + exp2 = norm_l(Lener); +#ifdef BASOP_NOGLOB + tmp2 = round_fx_sat(L_shl(Lener, exp2)); +#else + tmp2 = round_fx(L_shl(Lener, exp2)); +#endif + if (GT_16(tmp, tmp2)) + { + exp = sub(exp, 1); + } + exp2 = sub(exp, exp2); /* exponent num - exponent denom */ + alpha = 0; + move16(); + + /**v_stab_smooth_fx = 0.8f * v_stab_fx + 0.2f * (*v_stab_smooth_fx); */ + tmp = mult(*v_stab_smooth_fx,6554);/*Q15 and 6554 is 0.2 in Q15 */ + tmp2= mult(v_stab_fx,26214);/*Q15 and 26214 is 0.8 in Q15 */ + + *v_stab_smooth_fx = add(tmp2,tmp); + move16(); + + FOR (i=0; ipst_mem_deemp_err_fx)); /* +20dB at 50Hz */ + + Lener = L_deposit_h(-32768); + /* by using the maximum negative value + it is possible to gain another bit + of range for the 'Lener' sum. + This sum is divided by 4 */ + FOR (i=0; ipst_lp_ener_fx = mac_r(Lener, hBPF->pst_lp_ener_fx, 32440); + move16(); + + /* just write out the error signal */ + Copy( syn2_fx, bpf_noise_buf + i_subfr, subfr_len ); + } + + subfr_pos = add(subfr_pos, 1); + } + + /*-------------------------------------------------------* + * update memory for next frame + *-------------------------------------------------------*/ + + FOR( i = L_TRACK_HIST-1; i > 0; i-- ) + { + hBPF->Track_on_hist_fx[i] = hBPF->Track_on_hist_fx[i-1]; + move16(); + hBPF->vibrato_hist_fx[i] = hBPF->vibrato_hist_fx[i-1]; + move16(); + } + + hBPF->Track_on_hist_fx[i] = Track_on; + move16(); + hBPF->vibrato_hist_fx[i] = vibrato; + move16(); + + Copy( syn_buf_fx+L_frame, hBPF->pst_old_syn_fx, nbpsf_pit_max ); + + + return; +} + +/*==============================================================================*/ +/* FUNCTION : Word16 Pit_track_fx ( ) */ +/*------------------------------------------------------------------------------*/ +/* PURPOSE : */ +/*------------------------------------------------------------------------------*/ +/* INPUT ARGUMENTS : */ +/* Word16 syn[], st_fx->Q_syn2 i : synthesis [-PIT_MAX..L_SUBFR] */ +/* Word16 T Q0 i : pitch period (>= PIT_MIN) */ +/*------------------------------------------------------------------------------*/ +/* RETURN ARGUMENTS : */ +/* Word16 T Q0 */ +/*------------------------------------------------------------------------------*/ +/* CALLED FROM : TX/RX */ +/*==============================================================================*/ + +static Word16 Pit_track_fx( /* o : Pitch */ + Word16 syn[], /* i : synthesis [-PIT_MAX..L_SUBFR] */ + Word16 T /* i : pitch period (>= PIT_MIN) */ +) +{ + Word16 T2; + Word16 i, j; + Word32 Ltmp, Lcorr, Lener; + Word32 Ltmp0, Lcorr0, Lener0; + Word16 *v1, *v2; + Word16 exp1, exp2; + + /*----------------------------------------------------------------* + * Test pitch/2 to avoid continuous pitch doubling + * (short pitch is limited to PIT_MIN (34 = 376Hz) by the encoder + *----------------------------------------------------------------*/ + + T2 = shr(T, 1); + + v1 = &syn[-NBPSF_L_EXTRA]; + v2 = &syn[add(-T2, -NBPSF_L_EXTRA)]; + + Lener = L_deposit_h(-32768); + Ltmp = L_deposit_h(-32768); + Lcorr = L_deposit_l(2); + /* by using the maximum negative value + it is possible to gain another bit + of range for the 'Lener' sum. + It cannot be done for Lcorr + because it is a signed sum. */ + FOR (j = 0; j < 14; j++) + { + BASOP_SATURATE_WARNING_OFF_EVS + Lener0 = L_mult0(*v1, *v1); + Ltmp0 = L_mult0(*v2, *v2); + Lcorr0 = L_mult0(*v1++, *v2++); + FOR (i = 1; i < (L_HALFR16k+NBPSF_L_EXTRA)/14; i++) + { +#ifdef BASOP_NOGLOB + Lener0 = L_mac0_sat(Lener0, *v1, *v1); + Ltmp0 = L_mac0_sat(Ltmp0, *v2, *v2); + Lcorr0 = L_mac0_sat(Lcorr0, *v1++, *v2++); +#else + Lener0 = L_mac0(Lener0, *v1, *v1); + Ltmp0 = L_mac0(Ltmp0, *v2, *v2); + Lcorr0 = L_mac0(Lcorr0, *v1++, *v2++); +#endif + } + BASOP_SATURATE_WARNING_ON_EVS + test(); + test(); + test(); + IF (EQ_32(Lener0, 2147483647L)|| + EQ_32(Ltmp0, 2147483647L) || + EQ_32(Lcorr0, 2147483647L) || EQ_32(Lcorr0, -2147483647-1L)) + { + v1 -= i; + move16(); + v2 -= i; + move16(); + FOR (i = 0; i < (L_HALFR16k+NBPSF_L_EXTRA)/14; i++) + { + Lener = L_add(Lener, L_shr(L_mult0(*v1, *v1), 6)); + Ltmp = L_add(Ltmp, L_shr(L_mult0(*v2, *v2), 6)); + Lcorr = L_add(Lcorr, L_shr(L_mult0(*v1++, *v2++), 6)); + } + } + ELSE + { + Lener = L_add(Lener, L_shr(Lener0, 6)); + Ltmp = L_add(Ltmp, L_shr(Ltmp0, 6)); + Lcorr = L_add(Lcorr, L_shr(Lcorr0, 6)); + } + } + + Lener = L_shr(Lener, 1); + Lener = L_add(Lener, 0x40000001L); + Ltmp = L_shr(Ltmp, 1); + Ltmp = L_add(Ltmp, 0x40000001L); + Lcorr = L_shr(Lcorr, 1); + /* 'Lener', 'Ltmp' & 'Lcorr' are divided by 2 */ + + /* cn = corr / (float)sqrt(ener*tmp) */ + exp1 = norm_l(Lener); + exp2 = norm_l(Ltmp); + /* Multiply the Most Significant 16 bits */ +#ifdef BASOP_NOGLOB + Ltmp = L_mult0(round_fx_sat(L_shl_sat(Lener, exp1)), round_fx_sat(L_shl_sat(Ltmp, exp2))); +#else + Ltmp = L_mult0(round_fx(L_shl(Lener, exp1)), round_fx(L_shl(Ltmp, exp2))); +#endif + exp1 = add(exp1, exp2); + /* Correct if Odd # of Shifts */ + exp2 = s_and(exp1, 1); + exp1 = sub(exp1, exp2); + Ltmp = L_shr(Ltmp, exp2); + /* Call the Integer Square Root (it will normalize again if req.) */ + Ltmp = Isqrt(Ltmp); + /* We now do corr * 1 / sqrt(1/product) with high part of ratio only */ + exp1 = mac_r((16-1)*65536L-0x8000L, exp1, 16384); + exp2 = norm_l(Ltmp); + Ltmp = L_shl(Ltmp, exp2); + exp1 = sub(exp1, exp2); + exp2 = norm_l(Lcorr); + Lcorr= L_shl(Lcorr, exp2); + exp1 = sub(exp1, exp2); + Ltmp = Mpy_32_16_1(Lcorr, round_fx(Ltmp)); + /* Go to Q31 */ +#ifdef BASOP_NOGLOB + Ltmp = L_shl_sat(Ltmp, exp1); +#else + Ltmp = L_shl(Ltmp, exp1); +#endif + /* cn = normalized correlation of pitch/2 */ + if (GT_32(Ltmp, 2040109466L)) /* 0.95f in Q31 */ + { + T = T2; + move16(); + } + + return T; +} + +/*---------------------------------------------------------------------* + * addBassPostFilter() + * + * Add BPF component in cldfb domain + *---------------------------------------------------------------------*/ + +void addBassPostFilterFx ( + const Word16 *harm_timeIn_Fx, + Word32 **rAnalysis_Fx, + Word32 **iAnalysis_Fx, + HANDLE_CLDFB_FILTER_BANK cldfbBank_bpf_Fx, + Word32 *workBuffer, + const Word16 timeIn_e, + const Word16 nTimeSlots, + const Word16 nTimeSlotsTotal, + const Word16 nBandsTotal, + CLDFB_SCALE_FACTOR *cldfb_scale + ) +{ + Word16 i, scale1, scale2; + Word16 b; + Word16 maxBand; + Word16 nChan; + CLDFB_SCALE_FACTOR scale; + const Word16 *weights_Fx; + Word32 *tmp_R_Fx[CLDFB_NO_COL_MAX]; + Word32 *tmp_I_Fx[CLDFB_NO_COL_MAX]; + Word32 cldfbBufferReal[CLDFB_NO_COL_MAX][20]; + Word32 cldfbBufferImag[CLDFB_NO_COL_MAX][20]; + + nChan = cldfbBank_bpf_Fx->no_channels; + scale1 = scale2 = 0; + move16(); + move16(); + + weights_Fx = bpf_weights_16_Fx; + maxBand = s_min(nChan, BPF_STOP_STOPBAND_16); + + assert(nChan <= 20); + + FOR (i=0; i < nTimeSlots; i++) + { + tmp_R_Fx[i] = cldfbBufferReal[i]; + tmp_I_Fx[i] = cldfbBufferImag[i]; + } + + /* do the CLDFB anlysis of filtered signal */ + cldfbAnalysisFiltering( cldfbBank_bpf_Fx, + tmp_R_Fx, + tmp_I_Fx, + &scale, + harm_timeIn_Fx, + timeIn_e, + nTimeSlots, + workBuffer + ); + + /* now do the subtraction */ + + IF (nTimeSlots > 0) + { + /* Find common scale. */ + b = s_max(cldfb_scale->lb_scale, scale.lb_scale); + scale1 = limitScale32(sub(cldfb_scale->lb_scale, b)); + scale2 = limitScale32(sub(scale.lb_scale, b)); + cldfb_scale->lb_scale = b; + move16(); + /* Rescale time slots which do not have BPF contribution. */ + FOR (i=nTimeSlots; i < nTimeSlotsTotal; i++) + { + Scale_sig32(rAnalysis_Fx[i], nBandsTotal, scale1); + Scale_sig32(iAnalysis_Fx[i], nBandsTotal, scale1); + } + } + + FOR (i=0; i < nTimeSlots; i++) + { + /* Compensate first bpf_weights coefficient which is scaled by 0.5 */ + rAnalysis_Fx[i][0] = L_sub(L_shl(rAnalysis_Fx[i][0],scale1),L_shl(Mpy_32_16_1(tmp_R_Fx[i][0],weights_Fx[0]),add(1, scale2))); + move32(); + iAnalysis_Fx[i][0] = L_sub(L_shl(iAnalysis_Fx[i][0],scale1),L_shl(Mpy_32_16_1(tmp_I_Fx[i][0],weights_Fx[0]),add(1, scale2))); + move32(); + + /* loop over remaining low frequency bands */ + FOR (b=1; b < maxBand; b++) + { + rAnalysis_Fx[i][b] = L_sub(L_shl(rAnalysis_Fx[i][b],scale1),L_shr(Mpy_32_16_1(tmp_R_Fx[i][b],weights_Fx[b]), scale2)); + move32(); + iAnalysis_Fx[i][b] = L_sub(L_shl(iAnalysis_Fx[i][b],scale1),L_shr(Mpy_32_16_1(tmp_I_Fx[i][b],weights_Fx[b]), scale2)); + move32(); + } + + /* Rescale Bands with no BPF contribution. */ + Scale_sig32(rAnalysis_Fx[i]+maxBand, sub(nBandsTotal, maxBand), scale1); + Scale_sig32(iAnalysis_Fx[i]+maxBand, sub(nBandsTotal, maxBand), scale1); + } + + return; +} +#ifdef ADD_BPF_ADAPT +/*---------------------------------------------------------------------* + * res_bpf_adapt() + * + * Analyze BPF output and decide if it should be applied on DFT stereo + * residual signal + *---------------------------------------------------------------------*/ + + /*! r: Decision to enable or disable BPF on DFT stereo residual */ +int16_t res_bpf_adapt( + STEREO_DFT_DEC_DATA_HANDLE hStereoDft, /* i/o: DFT stereo decoder handle */ + const float* bpf_error_signal_8k, /* i : BPF modification signal */ + float res_buf[STEREO_DFT_BUF_MAX] /* i : residual buffer */ +) +{ + float error_nrg; + float tmp; + float res_hb_nrg; + float bpf_error_ratio; + int16_t res_bpf_flag; + int16_t i; + int16_t i_start; + int16_t i_end; + float bw_inv; + + if (hStereoDft->res_cod_band_max == 6) + { + i_start = 39; + i_end = 64; + bw_inv = 0.04f; /* 1/(64 - 39) */ + } + else + { + i_start = 28; + i_end = 40; + bw_inv = 0.083f; /* 1/(40 - 28) */ + } + + /* Measure energy of high frequency band in MDCT domain */ + res_hb_nrg = EPSILON; + for (i = i_start; i < i_end; i++) + { + res_hb_nrg += res_buf[i] * res_buf[i]; + } + res_hb_nrg *= bw_inv; + res_hb_nrg = STEREO_DFT_BPF_ADAPT_ALPHA * res_hb_nrg + (1 - STEREO_DFT_BPF_ADAPT_ALPHA) * hStereoDft->res_hb_nrg_mem; + hStereoDft->res_hb_nrg_mem = res_hb_nrg; + + /* Measure energy of discontinuities at subframe boundaries */ + error_nrg = 0; + for (i = 0; i < L_FRAME8k; i += STEREO_DFT_L_SUBFR_8k) + { + tmp = bpf_error_signal_8k[i] - hStereoDft->bpf_error_signal_last; + error_nrg += tmp * tmp; + hStereoDft->bpf_error_signal_last = bpf_error_signal_8k[i + STEREO_DFT_L_SUBFR_8k - 1]; + } + error_nrg *= 0.2f; /* Division by 5 for average value */ + bpf_error_ratio = min(2, error_nrg / res_hb_nrg); /* Form decision variable and apply limit */ + bpf_error_ratio = STEREO_DFT_BPF_ADAPT_BETA * bpf_error_ratio + (1 - STEREO_DFT_BPF_ADAPT_BETA) * hStereoDft->bpf_error_ratio_mem; + hStereoDft->bpf_error_ratio_mem = bpf_error_ratio; + + res_bpf_flag = bpf_error_ratio < 1; + + return res_bpf_flag; +} + +/*---------------------------------------------------------------------* + * bpf_pitch_coherence() + * + * Analyse pitch coherence + *---------------------------------------------------------------------*/ +void bpf_pitch_coherence( + Decoder_State* st, /* i/o: decoder state structure */ + const float pitch_buf[] /* i : pitch for every subfr [0,1,2,3] */ +) +{ + int16_t nb_subfr; + float pc, pcn1, pcn2, pcn3; + + nb_subfr = st->L_frame / L_SUBFR; + + if (st->clas_dec > UNVOICED_CLAS && st->element_mode != EVS_MONO) + { + pc = (float)fabs(st->old_pitch_buf[nb_subfr + 3] + st->old_pitch_buf[nb_subfr + 2] - st->old_pitch_buf[nb_subfr] - st->old_pitch_buf[nb_subfr + 1]) * 256.0f / (float)st->L_frame; + pcn1 = K_PC_DEC * pc + C_PC_DEC; + pcn1 = max(min(pcn1, 1.0f), 0.0f); + + pc = (float)fabs(pitch_buf[nb_subfr - 1] + pitch_buf[nb_subfr - 2] - pitch_buf[1] - pitch_buf[0]) * 256.0f / (float)st->L_frame; + pcn2 = K_PC_DEC * pc + C_PC_DEC; + pcn2 = max(min(pcn2, 1.0f), 0.0f); + + pc = (float)fabs(st->old_pitch_buf[nb_subfr + 3] + st->old_pitch_buf[nb_subfr + 2] - pitch_buf[1] - pitch_buf[0]) * 256.0f / (float)st->L_frame; + pcn3 = K_PC_DEC * pc + C_PC_DEC; + pcn3 = max(min(pcn3, 1.0f), 0.0f); + + if (pcn1 + pcn2 + pcn3 < 2.5f) + { + st->hBPF->psf_att = 0.4f; + set_s(&st->hBPF->Track_on_hist[L_TRACK_HIST - nb_subfr], 1, nb_subfr); + } + } + + return; +} +#endif \ No newline at end of file diff --git a/lib_dec/cng_dec.c b/lib_dec/cng_dec.c index 3362a88cc3baf54a9d42c316ed08fba4289156a3..60814c55de64c6dfe7a6e1637e37325dfc867425 100644 --- a/lib_dec/cng_dec.c +++ b/lib_dec/cng_dec.c @@ -247,7 +247,7 @@ void CNG_dec( } else { - st->CNG_mode = get_cng_mode( st->last_active_brate ); + st->CNG_mode = get_cng_mode_ivas( st->last_active_brate ); } } @@ -760,12 +760,12 @@ static void shb_CNG_decod( /*-------------------------------------------------------------------* - * td_cng_dec_init() + * td_cng_dec_init_flt() * * *-------------------------------------------------------------------*/ -void td_cng_dec_init( +void td_cng_dec_init_flt( DEC_CORE_HANDLE st /* i/o: decoder state structure */ ) { diff --git a/lib_dec/cng_dec_fx.c b/lib_dec/cng_dec_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..295a8a4ab3afb341fb5d24bdf99bb47c735d2ed9 --- /dev/null +++ b/lib_dec/cng_dec_fx.c @@ -0,0 +1,1075 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include +#include "options.h" /* Compilation switches */ +#include "cnst.h" +#include "rom_com.h" +#include "prot_fx1.h" +#include "prot_fx2.h" +#include "ivas_cnst.h" + +/*Temporary location to be move in prot* when merge is done*/ +void E_LPC_f_isp_a_conversion(const Word16 *isp, Word16 *a, const Word16 m); +void E_LPC_f_lsp_a_conversion(const Word16 *isp, Word16 *a, const Word16 m); + +/*-----------------------------------------------------------------* + * Local function prototypes + *-----------------------------------------------------------------*/ + +static void shb_CNG_decod_fx( Decoder_State *st_fx, const Word16 *synth_fx, Word16 *shb_synth_fx, const Word16 sid_bw,const Word16 Qsyn); + +/*-----------------------------------------------------------------* + * Decode residual signal energy + *-----------------------------------------------------------------*/ + +void CNG_dec_fx( + Decoder_State *st_fx, /* i/o: State structure */ + const Word16 last_element_mode, /* i : last element mode Q0 */ + Word16 Aq[], /* o : LP coefficients Q12 */ + Word16 *lsp_new, /* i/o: current frame LSPs Q15 */ + Word16 *lsf_new, /* i/o: current frame LSFs Qlog2(2.56) */ + Word16 *allow_cn_step, /* o : allow CN step Q0 */ + Word16 *sid_bw /* i : 0-NB/WB, 1-SWB SID */ + ,Word32 *q_env +) +{ + Word16 istep; + Word16 i, L_enr_index; + Word32 L_ener; + Word16 ener_fra,ener_int; + Word16 num_bits; + Word16 weights, ptr, j, k; + Word16 m1; + Word16 m = 0; + Word16 tmp[HO_HIST_SIZE*M]; + Word16 burst_ho_cnt = 0; + Word16 ll,s_ptr; + Word32 L_enr,L_tmp1; + Word16 tmp1,exp; + Word16 lsf_tmp[M]; + Word32 C[M]; + Word32 max_val[2]; + Word16 max_idx[2]; + Word16 ftmp_fx; + Word16 lsp_tmp[M]; + Word16 dev; + Word16 max_dev; + Word16 dist; + Word16 tmpv; + Word16 env_idx[2]; + Word32 enr1; + Word32 env[NUM_ENV_CNG]; + Word32 tmp_env[HO_HIST_SIZE*NUM_ENV_CNG]; + Word32 L_tmp; + Word16 fra; + Word16 temp_lo_fx, temp_hi_fx; + Word16 exp_pow; + Word16 tmp_loop; + Word16 enr_new, Aq_tmp[M + 1]; + + Word16 LSF_Q_prediction; /* o : LSF prediction mode - just temporary variable in CNG */ + TD_CNG_DEC_HANDLE hTdCngDec; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + hTdCngDec = st_fx->hTdCngDec; + + m = 0; + move16(); + /*-----------------------------------------------------------------* + * Decode CNG spectral envelope (only in SID frame) + *-----------------------------------------------------------------*/ + test(); + IF ( EQ_32(st_fx->core_brate,SID_1k75) || EQ_32(st_fx->core_brate,SID_2k40)) + { + /* de-quantize the LSF vector */ + IF ( st_fx->Opt_AMR_WB != 0 ) + { + /* Flt function */ + isf_dec_amr_wb_fx( st_fx, Aq, lsf_new, lsp_new); + /* check if ISPs may trigger too much synthesis energy */ + + E_LPC_f_isp_a_conversion(lsp_new, Aq_tmp, M); + enr_new = Enr_1_Az_fx(Aq_tmp, 2 * L_SUBFR); + + IF ((shr(enr_new, 14) > 0)) + { + /* Use old LSP vector */ + Copy(st_fx->lsp_old_fx, lsp_new, M); + Copy(st_fx->lsf_old_fx, lsf_new, M); + } + } + ELSE + { + lsf_dec_fx( st_fx, 0, Aq, &LSF_Q_prediction, lsf_new, lsp_new, 0, 0 +#ifdef LSF_RE_USE_SECONDARY_CHANNEL + ,NULL +#endif + ); + /* check if LSPs may trigger too much synthesis energy */ + + E_LPC_f_lsp_a_conversion(lsp_new, Aq_tmp, M); + enr_new = Enr_1_Az_fx(Aq_tmp, 2 * L_SUBFR); + + IF(shr(enr_new, 14) > 0) + { + /* Use old LSP vector */ + Copy(st_fx->lsp_old_fx, lsp_new, M); + Copy(st_fx->lsf_old_fx, lsf_new, M); + } + } + } + ELSE + { + /* Use old LSP vector */ + Copy( st_fx->lsp_old_fx, lsp_new, M ); + Copy( st_fx->lsf_old_fx, lsf_new, M ); + } + + /* Initialize the CNG spectral envelope in case of the very first CNG frame */ + IF( st_fx->first_CNG == 0 ) + { + Copy( st_fx->lsp_old_fx, st_fx->lspCNG_fx, M ); + } + + /*-----------------------------------------------------------------* + * Decode residual signal energy + *-----------------------------------------------------------------*/ + + *allow_cn_step = 0; + move16(); + test(); + IF( EQ_32(st_fx->core_brate,SID_1k75) || EQ_32(st_fx->core_brate,SID_2k40)) + { + istep = ISTEP_AMR_WB_SID_FX; + move16(); + if( EQ_32(st_fx->core_brate,SID_2k40)) + { + istep = ISTEP_SID_FX; + move16(); + } + + /* initialize the energy quantization parameters */ + num_bits = 6; + move16(); + if( st_fx->Opt_AMR_WB == 0 ) + { + num_bits = 7; + move16(); + } + + /* decode the energy index */ + L_enr_index = get_next_indice( st_fx, num_bits ); + + IF( LE_32(st_fx->last_core_brate, SID_2k40) || EQ_16(st_fx->prev_bfi, 1) ) + { + tmp1 = add(hTdCngDec->old_enr_index_fx, 20); + } + ELSE + { + tmp1 = add(hTdCngDec->old_enr_index_fx, 40); + } + IF( GT_16(L_enr_index, tmp1) && hTdCngDec->old_enr_index_fx >= 0 ) /* Likely bit error and not startup */ + { + L_enr_index = tmp1; move16(); + L_enr_index = s_min(L_enr_index, 127); + if (st_fx->Opt_AMR_WB != 0) + { + L_enr_index = s_min(L_enr_index, 63); + } + } + + test(); + test(); + test(); + IF (GT_32(st_fx->last_core_brate,SID_1k75)&& + st_fx->first_CNG != 0 && + hTdCngDec->old_enr_index_fx >= 0 && + GT_16(L_enr_index, add(hTdCngDec->old_enr_index_fx,1))) + { + *allow_cn_step = 1; + move16(); + } + + hTdCngDec->old_enr_index_fx = L_enr_index; + move16(); + if ( L_enr_index == 0 ) + { + L_enr_index = -5; + move16(); + } + /* st_fx->Enew = L_enr_index / step - 2.0f;*/ + L_ener = L_mult(L_enr_index, istep); /* Q16 (0+15) */ + /* subtract by 2 not done to leave Energy in Q2 */ + + /* extract integral and fractional parts */ + ener_fra = L_Extract_lc(L_ener, &ener_int); + ener_int = add(ener_int, 4); /* Q2 to Q6 */ + + /* find the new energy value */ + hTdCngDec->Enew_fx = Pow2(ener_int, ener_fra); + + IF( EQ_32(st_fx->core_brate,SID_2k40)) + { + burst_ho_cnt = get_next_indice( st_fx, 3 ); /* 3bit */ + + *sid_bw = get_next_indice( st_fx, 1 ); + IF ( *sid_bw == 0 ) + { + env_idx[0] = get_next_indice( st_fx, 6 ); + move16(); + + /* get quantized res_env_details */ + FOR ( i=0; ibwidth,WB) && st_fx->first_CNG!=0 && NE_16(st_fx->L_frame,st_fx->last_CNG_L_frame)) + { + hTdCngDec->ho_hist_size_fx = 0; + move16(); + } + } + + /*---------------------------------------------------------------------* + * CNG spectral envelope update + * Find A(z) coefficients + *---------------------------------------------------------------------*/ + test(); + test(); + test(); + IF( st_fx->last_core_brate <= SID_2k40 ) + { + /* Reset hangover counter if not first SID period */ + if( GT_32(st_fx->core_brate,FRAME_NO_DATA)) + { + hTdCngDec->num_ho_fx = 0; + move16(); + } + /* Update LSPs if last SID energy not outliers or insufficient number of hangover frames */ + test(); + IF( LT_16(hTdCngDec->num_ho_fx,3) || LT_32(Mult_32_16(hTdCngDec->Enew_fx,21845/*1/1.5f, Q15*/),st_fx->lp_ener_fx)) + { + FOR( i=0; ilspCNG_fx[i] = mac_r(L_mult(CNG_ISF_FACT_FX, st_fx->lspCNG_fx[i]), 32768-CNG_ISF_FACT_FX, lsp_new[i]); + move16(); /* Q15 (15+15+1-16) */ + } + } + } + ELSE + { + /* Update CNG_mode if allowed */ + test(); + test(); + test(); + IF( ( st_fx->Opt_AMR_WB || EQ_16(st_fx->bwidth,WB)) + && ( !st_fx->first_CNG || GE_16(hTdCngDec->act_cnt2_fx,MIN_ACT_CNG_UPD) ) ) + { + IF( GT_32(st_fx->last_active_brate,ACELP_16k40)) + { + st_fx->CNG_mode = -1; + move16(); + } + ELSE + { + st_fx->CNG_mode = get_cng_mode(st_fx->last_active_brate); + move16(); + } + } + + /* If first sid after active burst update LSF history from circ buffer */ + burst_ho_cnt = s_min(burst_ho_cnt, hTdCngDec->ho_circ_size_fx); /* MODE1_DTX_IN_CODEC_B_FIX */ + hTdCngDec->act_cnt_fx = 0; + move16(); + s_ptr = add(sub(hTdCngDec->ho_circ_ptr_fx, burst_ho_cnt),1); + move16(); + if( s_ptr < 0 ) + { + s_ptr = add(s_ptr, hTdCngDec->ho_circ_size_fx); + } + + FOR( ll = burst_ho_cnt; ll > 0; ll-- ) + { + hTdCngDec->ho_hist_ptr_fx = add(hTdCngDec->ho_hist_ptr_fx,1); + if( EQ_16(hTdCngDec->ho_hist_ptr_fx, HO_HIST_SIZE)) + { + hTdCngDec->ho_hist_ptr_fx = 0; + move16(); + } + + /* Conversion between 12.8k and 16k LSPs */ + test(); + test(); + test(); + IF( ( EQ_16(st_fx->L_frame,L_FRAME16k) && hTdCngDec->ho_16k_lsp_fx[s_ptr]==0) || (EQ_16(st_fx->L_frame,L_FRAME) && EQ_16(hTdCngDec->ho_16k_lsp_fx[s_ptr],1))) + { + /* Conversion from 16k LPSs to 12k8 */ + lsp_convert_poly_fx( &(hTdCngDec->ho_lsp_circ_fx[s_ptr*M]), st_fx->L_frame, 0 ); + } + /* update the circular buffers */ + Copy(&(hTdCngDec->ho_lsp_circ_fx[s_ptr*M]), &(hTdCngDec->ho_lsp_hist_fx[hTdCngDec->ho_hist_ptr_fx*M]), M ); + Copy32(&(hTdCngDec->ho_ener_circ_fx[s_ptr]), &(hTdCngDec->ho_ener_hist_fx[hTdCngDec->ho_hist_ptr_fx]), 1 ); + hTdCngDec->ho_sid_bw_fx = L_shl(L_and(hTdCngDec->ho_sid_bw_fx, (Word32) 0x3fffffffL ), 1); + Copy32(&(hTdCngDec->ho_env_circ_fx[s_ptr*NUM_ENV_CNG]), &(hTdCngDec->ho_env_hist_fx[hTdCngDec->ho_hist_ptr_fx*NUM_ENV_CNG]), NUM_ENV_CNG ); + + hTdCngDec->ho_hist_size_fx = add(hTdCngDec->ho_hist_size_fx,1); + + if (GT_16(hTdCngDec->ho_hist_size_fx, HO_HIST_SIZE)) + { + hTdCngDec->ho_hist_size_fx = HO_HIST_SIZE; + move16(); + } + + s_ptr = add(s_ptr,1); + if( EQ_16(s_ptr, hTdCngDec->ho_circ_size_fx)) + { + s_ptr = 0; + move16(); + } + } + + IF(hTdCngDec->ho_hist_size_fx > 0 ) /* can be -1 at init MODE1_DTX_IN_CODEC_B_FIX */ + { + /* *allow_cn_step |= ( st_fx->ho_ener_hist[st_fx->ho_hist_ptr] > 4.0f * st_fx->lp_ener );*/ + L_tmp1 = L_shr(hTdCngDec->ho_ener_hist_fx[hTdCngDec->ho_hist_ptr_fx], 2); + L_tmp1 = L_sub(L_tmp1, st_fx->lp_ener_fx); + + test(); test(); + if( ( L_tmp1 > 0 && (st_fx->first_CNG || EQ_16(st_fx->element_mode, EVS_MONO) ) ) ) + { + *allow_cn_step = s_or(*allow_cn_step,1); + } + } + IF ( EQ_16(last_element_mode, IVAS_CPE_TD) ) + { + *allow_cn_step = 1; + move16(); + } + test(); + IF ( *allow_cn_step == 0 && hTdCngDec->ho_hist_size_fx > 0 ) + { + /* Use average of energies below last energy */ + ptr = hTdCngDec->ho_hist_ptr_fx; + move16(); + Copy( &(hTdCngDec->ho_lsp_hist_fx[ptr*M]), tmp, M ); + m1 = 0; + move16(); + IF( L_and(hTdCngDec->ho_sid_bw_fx, (Word32) 0x1) == 0 ) + { + Copy32( &hTdCngDec->ho_env_hist_fx[ptr*NUM_ENV_CNG], tmp_env, NUM_ENV_CNG ); + m1 = 1; + move16(); + } + L_enr = Mult_32_16(hTdCngDec->ho_ener_hist_fx[ptr],W_DTX_HO_FX[0]) ;/* Q6+15-15->Q6 */ + + weights = W_DTX_HO_FX[0]; /* Q15 */ + + m = 1; + move16(); + FOR( k=1; k< hTdCngDec->ho_hist_size_fx; k++ ) + { + ptr = sub(ptr,1); + if( ptr < 0 ) + { + ptr = HO_HIST_SIZE - 1; + move16(); + } + + test(); + IF ( LT_32(Mult_32_16(hTdCngDec->ho_ener_hist_fx[ptr],ONE_OVER_BUF_H_NRG_FX), hTdCngDec->ho_ener_hist_fx[hTdCngDec->ho_hist_ptr_fx])&& + GT_32(hTdCngDec->ho_ener_hist_fx[ptr],Mult_32_16(hTdCngDec->ho_ener_hist_fx[hTdCngDec->ho_hist_ptr_fx], BUF_L_NRG_FX))) + { + /*enr += W_DTX_HO[k] * st_fx->ho_ener_hist[ptr];*/ + L_tmp1 = Mult_32_16(hTdCngDec->ho_ener_hist_fx[ptr],W_DTX_HO_FX[k]) ; /* Q6+15-15->Q6 */ + L_enr = L_add(L_enr,L_tmp1); /* Q6 */ + + /*weights += W_DTX_HO[k];*/ + weights = add( weights, W_DTX_HO_FX[k]); /* Q15 */ + + Copy( &hTdCngDec->ho_lsp_hist_fx[ptr*M], &tmp[m*M], M ); + IF( L_and(hTdCngDec->ho_sid_bw_fx, L_shl((Word32)0x1,k)) == 0 ) + { + Copy32( &hTdCngDec->ho_env_hist_fx[ptr*NUM_ENV_CNG], &tmp_env[m1*NUM_ENV_CNG], NUM_ENV_CNG ); + m1 = add(m1,1); + } + m = add(m,1); + } + } + + /*enr /= weights;*/ + exp = norm_s(weights); + tmp1 = div_s(shl(1,sub(14,exp)),weights); /* Q(15+14-exp-15) */ + L_tmp1 = Mult_32_16(L_enr,tmp1); /* Q(14-exp+6-15)->Q(5-exp) */ + L_enr = L_shl(L_tmp1,exp+1); /* Q6 */ + + st_fx->lp_ener_fx = L_enr; /* Q6 */ + + set32_fx( max_val, 0, 2 ); + set16_fx( max_idx, 0, 2 ); + + FOR( i=0; iL_frame,L_FRAME)) + { + lsp2lsf_fx( &tmp[i*M], lsf_tmp, M, INT_FS_FX ); + ftmp_fx = 964; + move16();/*X2.56 */ + tmpv = sub(16384,add(lsf_tmp[M-1],ftmp_fx)); /*QX2.56*/ + L_tmp = L_mult0(tmpv,tmpv); /*QX6.5536*/ + } + ELSE + { + lsp2lsf_fx( &tmp[i*M], lsf_tmp, M, INT_FS_16k_FX ); + ftmp_fx = 1205; + move16();/*QX2.56*/ + tmpv = sub(20480,add(lsf_tmp[M-1],ftmp_fx)); /*QX2.56*/ + L_tmp = L_mult0(tmpv,tmpv); /*QX6.5536*/ + } + + tmpv = sub(lsf_tmp[0],ftmp_fx); /*QX2.56*/ + L_tmp = L_mac0(L_tmp,tmpv,tmpv); /*QX6.5536*/ + FOR ( j=0; jlspCNG_fx[i] = lsp_tmp[i]; + move16(); /*Q15*/ + } + } + ELSE + { + FOR( i=0; ilspCNG_fx[i] = add(mult_r(26214,lsp_tmp[i]),mult_r(6554,lsp_new[i])); + } + } + IF( m1 > 0 ) + { + FOR ( i=0; ilp_ener_fx; */ + IF(EQ_16(m1,1)) + { + L_tmp = L_sub(L_tmp,L_add(st_fx->lp_ener_fx,st_fx->lp_ener_fx)); + } + ELSE + { + tmp1 = div_s(1,m1); + L_tmp = Mult_32_16(L_tmp,tmp1); + L_tmp = L_sub(L_tmp,L_add(st_fx->lp_ener_fx,st_fx->lp_ener_fx)); + } + env[i] = L_tmp; + move32(); + } + + Copy32(env, hTdCngDec->lp_env_fx, NUM_ENV_CNG); + } + } + ELSE + { + Copy( lsp_new, st_fx->lspCNG_fx, M ); /* use newly analyzed ISFs */ + } + } + + test(); + IF( EQ_32(st_fx->core_brate, SID_1k75) || EQ_32(st_fx->core_brate,SID_2k40)) + { + /* Update hangover memory during CNG */ + test(); + IF ( *allow_cn_step == 0 && LT_32(hTdCngDec->Enew_fx,L_add(st_fx->lp_ener_fx,L_shr(st_fx->lp_ener_fx,1)))) + { + /* update the pointer to circular buffer of old LSP vectors */ + hTdCngDec->ho_hist_ptr_fx = add(hTdCngDec->ho_hist_ptr_fx, 1); + if( EQ_16(hTdCngDec->ho_hist_ptr_fx,HO_HIST_SIZE)) + { + hTdCngDec->ho_hist_ptr_fx = 0; + move16(); + } + + /* update the circular buffer of old LSP vectors with the new LSP vector */ + Copy( lsp_new, &(hTdCngDec->ho_lsp_hist_fx[(hTdCngDec->ho_hist_ptr_fx)*M]), M ); + + /* update the hangover energy buffer */ + hTdCngDec->ho_ener_hist_fx[hTdCngDec->ho_hist_ptr_fx] = hTdCngDec->Enew_fx; + move32(); + test(); + IF ( EQ_32(st_fx->core_brate,SID_2k40)&&*sid_bw==0) + { + /* enr1 = (float)log10( st->Enew*L_frame + 0.1f ) / (float)log10( 2.0f );*/ + exp = norm_l(hTdCngDec->Enew_fx); + L_tmp = L_shl(hTdCngDec->Enew_fx,exp);/*Q(exp+6)*/ + L_tmp = Mult_32_16(L_tmp,shl(st_fx->L_frame,5));/*Q(exp+6+5-15=exp-4)*/ + L_tmp = L_shr(L_tmp,sub(exp,10));/*Q6*/ + + exp = norm_l(L_tmp); + fra = Log2_norm_lc(L_shl(L_tmp,exp)); + exp = sub(sub(30,exp),6); + L_tmp = L_Comp(exp,fra); + enr1 = L_shr(L_tmp,10);/* Q6 */ + + FOR ( i=0; iEnew;*/ + L_tmp = L_sub(enr1,q_env[i]);/* Q6 */ + L_tmp = L_shl(L_tmp, 10);/* 16 */ + temp_lo_fx = L_Extract_lc(L_tmp, &temp_hi_fx); + + exp_pow = sub(14, temp_hi_fx); + L_tmp = Pow2(14, temp_lo_fx); /* Qexp_pow */ + env[i] = L_shl(L_tmp, sub(6, exp_pow)); /* Q6 */ + L_tmp = L_add(hTdCngDec->Enew_fx, hTdCngDec->Enew_fx); + env[i] = L_add(env[i],L_tmp); /* Q6 */ move32(); + } + hTdCngDec->ho_sid_bw_fx = L_shl(L_and(hTdCngDec->ho_sid_bw_fx, (Word32) 0x3fffffffL ), 1); + Copy32( env, &(hTdCngDec->ho_env_hist_fx[(hTdCngDec->ho_hist_ptr_fx)*NUM_ENV_CNG]), NUM_ENV_CNG ); + } + ELSE IF( *sid_bw != 0 ) + { + hTdCngDec->ho_sid_bw_fx = L_shl(L_and(hTdCngDec->ho_sid_bw_fx, (Word32) 0x3fffffffL ), 1); + hTdCngDec->ho_sid_bw_fx = L_or(hTdCngDec->ho_sid_bw_fx, 0x1L); + } + + hTdCngDec->ho_hist_size_fx = add(hTdCngDec->ho_hist_size_fx,1); + if( GT_16(hTdCngDec->ho_hist_size_fx,HO_HIST_SIZE)) + { + hTdCngDec->ho_hist_size_fx = HO_HIST_SIZE; + move16(); + } + } + /* Update the frame length memory */ + st_fx->last_CNG_L_frame = st_fx->L_frame; + move16(); + + if( NE_32(st_fx->core_brate,SID_1k75)) + { + hTdCngDec->num_ho_fx = m; + move16(); + } + } + + /* Update the frame length memory */ + st_fx->last_CNG_L_frame = st_fx->L_frame; + + if( NE_32(st_fx->core_brate,SID_1k75)) + { + hTdCngDec->num_ho_fx = m; + move16(); + } + + IF ( st_fx->Opt_AMR_WB ) + { + E_LPC_f_isp_a_conversion( st_fx->lspCNG_fx, Aq, M ); + } + ELSE + { + E_LPC_f_lsp_a_conversion( st_fx->lspCNG_fx, Aq, M ); + } + + tmp_loop = shr(st_fx->L_frame,6); + FOR( i=1; icore_brate == FRAME_NO_DATA || EQ_32(st_fx->core_brate, SID_2k40)) + { + /* SHB SID decoding and CNG */ + test(); + IF (st_fx->cng_type == LP_CNG && EQ_16(st_fx->extl, SWB_CNG)) + { + shb_CNG_decod_fx( st_fx, synth_fx, shb_synth_fx, sid_bw, Qsyn ); + } + st_fx->last_vad_fx = 0; + move16(); + st_fx->hTdCngDec->burst_cnt_fx = 0; + move16(); + } + ELSE + { + st_fx->last_vad_fx = 1; + move16(); + st_fx->hTdCngDec->burst_cnt_fx = add(st_fx->hTdCngDec->burst_cnt_fx, 1); + if ( GT_16(st_fx->hTdCngDec->burst_cnt_fx, 10)) + { + st_fx->hTdCngDec->burst_cnt_fx = 0; + move16(); + } + } + + return; +} + +/*---------------------------------------------------------------------* + * shb_CNG_decod() + * + * Main routine of SHB SID decoding and CNG + *---------------------------------------------------------------------*/ +static void shb_CNG_decod_fx( + Decoder_State *st_fx, /* i/o: State structure */ + const Word16 *synth_fx, /* i : ACELP core synthesis at 32kHz */ + Word16 *shb_synth_fx, /* o : high-band CNG synthesis */ + const Word16 sid_bw /* i : 0-NB/WB, 1-SWB SID */ + ,const Word16 Qsyn /* i : Q value of ACELP core synthesis */ +) +{ + Word16 i; + Word16 idx_ener_fx; + Word16 shb_lpcCNG_fx[LPC_SHB_ORDER+1]; + Word16 shb_lspCNG_fx[LPC_SHB_ORDER]; + Word16 excTmp_fx[L_FRAME16k]; + Word16 excSHB_fx[L_FRAME16k]; + Word16 tmp_lsp[LPC_SHB_ORDER]; + Word16 ener_excSHB_fx; + Word32 wb_ener_fx; + Word16 wb_ener16_fx; + Word32 L_gain_fx; + Word16 gain_fx; + Word16 shb_syn16k_fx[L_FRAME16k]; + Word16 tmp; + Word16 step_fx; + Word16 interp_fx; + Word16 ener_fx; + Word16 exp,exp1; + Word16 fra; + Word32 L_tmp; + Word16 tmp2; + Word16 allow_cn_step_fx=0; + Word16 q; + TD_BWE_DEC_HANDLE hBWE_TD; + hBWE_TD = st_fx->hBWE_TD; + + IF ( st_fx->bfi == 0 ) + { + test(); + IF ( EQ_32(st_fx->core_brate, SID_2k40)&&EQ_16(sid_bw,1)) + { + idx_ener_fx = get_next_indice(st_fx, 4); + + if ( idx_ener_fx == 0 ) + { + idx_ener_fx = -15; + move16(); + } + IF (EQ_16(st_fx->element_mode, EVS_MONO)) + { + /* de-quantization of SHB CNG parameters */ + L_tmp = L_mult(idx_ener_fx, 27400); /*Q14 */ + st_fx->last_shb_cng_ener_fx = extract_l(L_shr(L_sub(L_tmp, 295924), 6)); /*Q8 */ + } + ELSE + { +#ifdef IVAS_CODE_CNG + /* de-quantization of SHB CNG parameters */ To be verified + L_tmp = L_mult(idx_ener_fx, 17615); /*Q13*/ + st_fx->last_shb_cng_ener_fx = extract_l(L_shr(L_sub(L_tmp, 147962), 5)); /*Q8 */ +#endif + } + } + } + + /* SHB spectrum estimation */ + + + interp_fx = s_min(st_fx->shb_dtx_count_fx,32); +#ifdef BASOP_NOGLOB + interp_fx = shl_sat(interp_fx, 10); /*Q15*/ +#else + interp_fx = shl(interp_fx, 10); /*Q15*/ +#endif + FOR ( i=0; ilsp_shb_prev_fx[i]); /*Q14*/ + tmp = mult(sub(32767, interp_fx), st_fx->lsp_shb_prev_prev_fx[i]); /*Q14*/ + shb_lspCNG_fx[i] = add(tmp2, tmp); + move16(); /*Q14*/ + } + + IF (NE_16(st_fx->element_mode, IVAS_CPE_DFT)) + { + if (LT_16(st_fx->shb_dtx_count_fx, 1000)) + { + st_fx->shb_dtx_count_fx = add(st_fx->shb_dtx_count_fx, 1); + } + } + E_LPC_lsf_lsp_conversion(shb_lspCNG_fx, tmp_lsp, LPC_SHB_ORDER); /*Q14*/ + E_LPC_f_lsp_a_conversion(tmp_lsp, shb_lpcCNG_fx, LPC_SHB_ORDER); + + Copy_Scale_sig( shb_lpcCNG_fx, shb_lpcCNG_fx, LPC_SHB_ORDER+1, sub(norm_s(shb_lpcCNG_fx[0]),2) ); /* Q12 */ + +#ifdef IVAS_CODE_CNG + //mvr2r(shb_lpcCNG, st->hTdCngDec->shb_lpcCNG, LPC_SHB_ORDER + 1); +#endif + /* SHB energy estimation */ + wb_ener_fx = L_deposit_l(1);/*Q1 */ + FOR ( i=0; ifirst_CNG == 0 ) + { + st_fx->wb_cng_ener_fx = wb_ener16_fx; + move16();/*Q8 */ + } + if ( GT_16(abs_s(sub(wb_ener16_fx,st_fx->wb_cng_ener_fx)),3072)) + { + allow_cn_step_fx = 1; + move16(); + } + + IF ( EQ_16(allow_cn_step_fx, 1)) + { + st_fx->wb_cng_ener_fx = wb_ener16_fx; + move16(); /*Q8 */ + } + ELSE + { + tmp = sub(wb_ener16_fx, st_fx->wb_cng_ener_fx); /*Q8 */ + tmp = mult_r(tmp, 29491); /*Q8 */ + st_fx->wb_cng_ener_fx = add(st_fx->wb_cng_ener_fx, tmp); /*Q8 */ + } + test(); + test(); + IF ( EQ_32(st_fx->core_brate, SID_2k40)&&EQ_16(sid_bw,1)&&st_fx->bfi==0) + { + st_fx->last_wb_cng_ener_fx = st_fx->wb_cng_ener_fx; + move16(); + + if ( st_fx->first_CNG == 0 ) + { + st_fx->shb_cng_ener_fx = st_fx->last_shb_cng_ener_fx; + move16(); + } + } + + gain_fx = sub(st_fx->wb_cng_ener_fx, st_fx->last_wb_cng_ener_fx); /*8 */ + if (GT_16(gain_fx, 15)) + { + gain_fx = 15; + move16(); + } + step_fx = sub(add(gain_fx, st_fx->last_shb_cng_ener_fx), st_fx->shb_cng_ener_fx); /*Q8 */ + test(); + IF ( EQ_16(allow_cn_step_fx,1)||GT_32(st_fx->last_core_brate,SID_2k40)) + { + st_fx->shb_cng_ener_fx = add(st_fx->shb_cng_ener_fx, step_fx); + } + ELSE + { + st_fx->shb_cng_ener_fx = add(st_fx->shb_cng_ener_fx, mult(8192, step_fx)); /*Q8 */ + } + /* generate white noise excitation */ + FOR ( i=0; iswb_cng_seed_fx), 8); + move16();/*Q-8*/ + } + + /* synthesis filtering */ + Syn_filt_s( 0, shb_lpcCNG_fx, LPC_SHB_ORDER, excTmp_fx, excSHB_fx, L_FRAME16k, hBWE_TD->state_lpc_syn_fx, 1 ); + + + /* synthesis signal gain shaping */ + L_tmp = 0; + FOR ( i=0; ilast_vad_fx, 1)) + { + st_fx->trans_cnt_fx = 0; + move16(); + test(); + if ( GT_16(st_fx->hTdCngDec->burst_cnt_fx, 3)&&NE_16(st_fx->last_core,HQ_CORE)) + { + st_fx->trans_cnt_fx = 5; + move16(); + } + } + + ener_fx = st_fx->shb_cng_ener_fx; + move16();/*Q8 */ + IF ( st_fx->trans_cnt_fx > 0 ) + { + i = extract_l(L_mult0(st_fx->trans_cnt_fx, 17)); /*Q0 */ + ener_fx = add(st_fx->shb_cng_ener_fx, mult(sin_table256_fx[i], sub(st_fx->last_shb_ener_fx, st_fx->shb_cng_ener_fx))); /*Q8 */ + st_fx->trans_cnt_fx = sub(st_fx->trans_cnt_fx, 1); + } + + tmp = mult(3277, ener_fx); /*Q8 */ + L_tmp = L_mult(27213, tmp); /*Q22, 27213=3.321928 in Q13 */ + L_tmp = L_shr(L_tmp, 6); /*Q16 */ + L_tmp = L_add(L_tmp, 10<<16); + if( L_tmp < 0 ) + { + L_tmp = 0; + move32(); + } + fra = L_Extract_lc(L_tmp, &exp); + L_tmp = L_shl(Pow2(exp, fra), 5); /*Q5 */ + L_tmp = L_shr(L_tmp, 10); + if( L_tmp == 0 ) + { + L_tmp = 1; /*Q5 */ + } + exp = norm_l(L_tmp); + L_tmp = L_shl(L_tmp, exp); /*Q31*/ + tmp = extract_h(L_tmp); /*Q15*/ + exp = sub(exp, 16); + exp1 = norm_s(ener_excSHB_fx); + fra = shl(ener_excSHB_fx, exp1); /*Q15*/ + + IF ( GT_16(fra,tmp)) + { + fra = shr(fra, 1); /*Q15*/ + exp1 = sub(exp1, 1); + } + tmp = div_s(fra, tmp); /*Q15*/ + + L_tmp = L_deposit_h(tmp); /*Q31 */ + tmp = -(q+exp1)+(5+exp); + L_gain_fx = Isqrt_lc(L_tmp, &tmp); /*Q31-Qtmp */ +#ifdef IVAS_CODE_CNG + st->hTdCngDec->shb_cng_gain = ener_fx; +#endif + FOR ( i=0; ilast_extl, SWB_TBE)||EQ_16(st_fx->last_extl,FB_TBE)) + { + /* rescale the Hilbert memories to Q0 */ + FOR(i = 0; i < HILBERT_MEM_SIZE ; i++) + { + hBWE_TD->genSHBsynth_Hilbert_Mem_fx[i] = L_shr(hBWE_TD->genSHBsynth_Hilbert_Mem_fx[i], st_fx->prev_Q_bwe_syn2); + move32(); + } + + FOR(i = 0; i < 2*ALLPASSSECTIONS_STEEP; i++ ) + { + hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx[i] = shr(hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx[i], st_fx->prev_Q_bwe_syn2); + } + + } + GenSHBSynth_fx( shb_syn16k_fx, shb_synth_fx, hBWE_TD->genSHBsynth_Hilbert_Mem_fx, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx, st_fx->L_frame, &(hBWE_TD->syn_dm_phase_fx) ); + + IF ( EQ_32(st_fx->output_Fs,48000)) + { + interpolate_3_over_2_allpass_fx( shb_synth_fx, L_FRAME32k, shb_synth_fx, st_fx->interpol_3_2_cng_dec_fx, allpass_poles_3_ov_2 ); + } +#ifdef IVAS_CODE_CNG + ResetSHBbuffer_Dec(st->hBWE_TD, st->extl); +#else + ResetSHBbuffer_Dec_fx( st_fx ); +#endif + + return; +} + +/*-------------------------------------------------------------------* + * td_cng_dec_init() + * + * + *-------------------------------------------------------------------*/ + +void td_cng_dec_init( + DEC_CORE_HANDLE st /* i/o: decoder state structure */ +) +{ + TD_CNG_DEC_HANDLE hTdCngDec; + + hTdCngDec = st->hTdCngDec; + + hTdCngDec->cng_seed_fx = RANDOM_INITSEED; move16(); + hTdCngDec->cng_ener_seed_fx = RANDOM_INITSEED; move16(); + hTdCngDec->cng_ener_seed1_fx = RANDOM_INITSEED; move16(); + hTdCngDec->old_enr_index_fx = -1; move16(); + hTdCngDec->Enew_fx = L_deposit_l(0); + hTdCngDec->last_allow_cn_step_fx = 0; move16(); +#ifdef IVAS_CODE_CNG + // mvr2r(st->lsp_old, st->lspCNG, M); +// hTdCngDec->shb_cng_ener = -6.02f; + IF (st->element_mode != EVS_MONO) + { + //set_f(hTdCngDec->shb_lpcCNG, 0.0f, LPC_SHB_ORDER + 1); + //hTdCngDec->shb_lpcCNG[0] = 1.0f; + //hTdCngDec->shb_cng_gain = -82.0; /* a dB value approximately corresponding to shb index 0(used as index -15) */ + } + //hTdCngDec->wb_cng_ener = -6.02f; + //hTdCngDec->last_wb_cng_ener = -6.02f; + //hTdCngDec->last_shb_cng_ener = -6.02f; + //hTdCngDec->swb_cng_seed = RANDOM_INITSEED; +#endif + hTdCngDec->ho_hist_ptr_fx = -1; move16(); + hTdCngDec->ho_sid_bw_fx = L_deposit_l(0); + set16_fx(hTdCngDec->ho_lsp_hist_fx, 0, HO_HIST_SIZE* M); + set32_fx(hTdCngDec->ho_ener_hist_fx, 0, HO_HIST_SIZE); + set32_fx(hTdCngDec->ho_env_hist_fx, 0, HO_HIST_SIZE* NUM_ENV_CNG); + hTdCngDec->ho_hist_size_fx = 0; move16(); + hTdCngDec->act_cnt_fx = 0; move16(); + hTdCngDec->ho_circ_ptr_fx = -1; move16(); + set16_fx(hTdCngDec->ho_lsp_circ_fx, 0, HO_HIST_SIZE* M); + set32_fx(hTdCngDec->ho_ener_circ_fx, 0, HO_HIST_SIZE); + set32_fx(hTdCngDec->ho_env_circ_fx, 0, HO_HIST_SIZE* NUM_ENV_CNG); + hTdCngDec->ho_circ_size_fx = 0; move16(); + + set16_fx(hTdCngDec->ho_16k_lsp_fx, 0, HO_HIST_SIZE); + hTdCngDec->act_cnt2_fx = 0; move16(); + hTdCngDec->num_ho_fx = 0; move16(); + hTdCngDec->last_cng_type_fx = -1; move16(); + set32_fx(hTdCngDec->lp_env_fx, 0, NUM_ENV_CNG); + set16_fx(hTdCngDec->exc_mem_fx, 0, 24); + set16_fx(hTdCngDec->exc_mem1_fx, 0, 30); + set32_fx(hTdCngDec->old_env_fx, 0, NUM_ENV_CNG); +#ifdef IVAS_CODE_CNG + //st->CNG_mode = -1; + //for (i = 0; i < LPC_SHB_ORDER; i++) + //{ + // if (st->element_mode != EVS_MONO) + // { + // hTdCngDec->lsp_shb_prev[i] = 0.5f * ((float)(i + 1)) / ((float)(LPC_SHB_ORDER + 1)); + // } + // else + // { + // hTdCngDec->lsp_shb_prev[i] = 0.5f * ((float)i) / ((float)LPC_SHB_ORDER); + // } + // hTdCngDec->lsp_shb_prev_prev[i] = hTdCngDec->lsp_shb_prev[i]; + //} + + //hTdCngDec->shb_dtx_count = 0; + //hTdCngDec->trans_cnt = 0; + //hTdCngDec->last_shb_ener = 0.001f; + //set_f(hTdCngDec->interpol_3_2_cng_dec, 0.0f, INTERP_3_2_MEM_LEN); +#endif + hTdCngDec->burst_cnt_fx = 0; move16(); + + return; +} + diff --git a/lib_dec/core_dec_init.c b/lib_dec/core_dec_init.c index 8f5f014f06de7f433ff74e9a2a31754ad7c0b43f..150048573e807291f153f9ade6b276cf07e60273 100644 --- a/lib_dec/core_dec_init.c +++ b/lib_dec/core_dec_init.c @@ -43,12 +43,12 @@ #include "wmc_auto.h" /*-----------------------------------------------------------------------* - * open_decoder_LPD() + * open_decoder_LPD_flt() * * Initialization of state variables *-----------------------------------------------------------------------*/ -void open_decoder_LPD( +void open_decoder_LPD_flt( Decoder_State *st, /* i/o: decoder state structure */ const int32_t total_brate, /* i : total bitrate */ const int32_t last_total_brate, /* i : last total bitrate */ @@ -71,7 +71,7 @@ void open_decoder_LPD( st->fscale_old = st->fscale; } - st->sr_core = getCoreSamplerateMode2( st->element_mode, total_brate, bwidth, st->flag_ACELP16k, st->rf_flag, st->is_ism_format ); + st->sr_core = getCoreSamplerateMode2_flt( st->element_mode, total_brate, bwidth, st->flag_ACELP16k, st->rf_flag, st->is_ism_format ); st->fscale = sr2fscale( st->sr_core ); fscaleFB = sr2fscale( st->output_Fs ); @@ -90,7 +90,7 @@ void open_decoder_LPD( } } - st->tcxonly = getTcxonly( st->element_mode, total_brate, MCT_flag, st->is_ism_format ); + st->tcxonly = getTcxonly_ivas( st->element_mode, total_brate, MCT_flag, st->is_ism_format ); /* the TD TCX PLC in MODE1 still runs with 80ms subframes */ if ( ( st->element_mode == EVS_MONO && st->L_frame == L_FRAME16k && total_brate <= ACELP_32k ) || ( st->element_mode > EVS_MONO && st->L_frame == L_FRAME16k && total_brate <= MAX_ACELP_BRATE ) || ( st->tcxonly && ( st->sr_core == 32000 || st->sr_core == 16000 ) ) ) @@ -102,7 +102,7 @@ void open_decoder_LPD( st->nb_subfr = NB_SUBFR; } st->bits_frame = (int16_t) ( ( (float) st->L_frame / (float) st->fscale ) * (float) FSCALE_DENOM / 128.0f * (float) total_brate / 100.0f + 0.49f ); - st->TcxBandwidth_float = getTcxBandwidth(bwidth); + st->TcxBandwidth_float = getTcxBandwidth_flt(bwidth); st->narrowBand = (bwidth == NB) ? 1 : 0; encoderLookahead = (L_LOOK_12k8 * st->fscale) / FSCALE_DENOM; encoderLookaheadFB = (L_LOOK_12k8 * fscaleFB) / FSCALE_DENOM; @@ -298,7 +298,7 @@ void open_decoder_LPD( /*Reset of ACELP memories*/ st->rate_switching_reset = 1; - st->tilt_code = TILT_CODE; + st->tilt_code = TILT_CODE_FLT; set_zero(st->old_exc, L_EXC_MEM_DEC); set_zero(st->syn_float, 1 + M); set_zero(st->mem_syn2, M); @@ -330,12 +330,12 @@ void open_decoder_LPD( } /* reset CLDFB memories */ - cldfb_reset_memory(st->cldfbAna); - cldfb_reset_memory(st->cldfbBPF); - cldfb_reset_memory(st->cldfbSyn); + cldfb_reset_memory_ivas(st->cldfbAna); + cldfb_reset_memory_ivas(st->cldfbBPF); + cldfb_reset_memory_ivas(st->cldfbSyn); if (st->cldfbSynHB != NULL) { - cldfb_reset_memory(st->cldfbSynHB); + cldfb_reset_memory_ivas(st->cldfbSynHB); } } else if ((st->L_frame != st->last_L_frame) && (st->L_frame <= L_FRAME16k) && (st->last_L_frame <= L_FRAME16k)) /* Rate switching between 12.8 and 16 kHz*/ @@ -363,7 +363,7 @@ void open_decoder_LPD( st->rate_switching_reset = 1; /*reset partly some memories*/ - st->tilt_code = TILT_CODE; + st->tilt_code = TILT_CODE_FLT; if (!st->last_con_tcx) { set_zero(st->old_exc, L_EXC_MEM_DEC); @@ -661,7 +661,7 @@ void open_decoder_LPD( st->hTonalMDCTConc->lastBlockData.tonalConcealmentActive = 0; st->hTonalMDCTConc->lastBlockData.nSamples = 0; - TonalMDCTConceal_Init(st->hTonalMDCTConc, st->hTcxDec->L_frameTCX, st->L_frame, FDNS_NPTS, st->hTcxCfg); + TonalMDCTConceal_Init_ivas(st->hTonalMDCTConc, st->hTcxDec->L_frameTCX, st->L_frame, FDNS_NPTS, st->hTcxCfg); } st->last_tns_active = 0; diff --git a/lib_dec/core_dec_init_fx.c b/lib_dec/core_dec_init_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..b1d4d830010d75dfa93304178a576c0adfb83159 --- /dev/null +++ b/lib_dec/core_dec_init_fx.c @@ -0,0 +1,1009 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include +#include +#include +#include +#include "options.h" +#include "prot_fx1.h" +#include "prot_fx2.h" +#include "basop_util.h" +#include "rom_com.h" +#include "cnst.h" /* for MIN_CNG_LEV */ + +/*-----------------------------------------------------------------------* + * open_decoder_LPD() + * + * Initialization of state variables + *-----------------------------------------------------------------------*/ + +void open_decoder_LPD( + Decoder_State *st, + const Word32 total_brate, +#ifdef NEW_IVAS_OPEN_DEC + const Word32 last_total_brate, +#endif + const Word16 bwidth +#ifdef NEW_IVAS_OPEN_DEC + ,const Word16 is_mct, /* i : MCT mode flag */ +#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT + const Word16 last_element_mode, +#endif + const Word16 is_init /* i : indicate call from init_decoder() to avoid double TC initialization */ +#endif +) +{ + Word16 i; + Word16 mem_syn_r_size_new; + Word16 mem_syn_r_size_old; + Word16 fscaleFB; + BPF_DEC_HANDLE hBPF; + TD_BWE_DEC_HANDLE hBWE_TD; + TCX_LTP_DEC_HANDLE hTcxLtpDec; + HQ_DEC_HANDLE hHQ_core; + TCX_DEC_HANDLE hTcxDec; + + hBPF = st->hBPF; + hBWE_TD = st->hBWE_TD; + hHQ_core = st->hHQ_core; + hTcxLtpDec = st->hTcxLtpDec; + hTcxDec = st->hTcxDec; + +#ifndef NEW_IVAS_OPEN_DEC + st->total_brate = total_brate; +#endif + + IF (NE_16(st->codec_mode, MODE1)) /*already updated in MODE1*/ + { + st->fscale_old = st->fscale; + } + st->sr_core = getCoreSamplerateMode2(st->element_mode, st->total_brate, bwidth, st->flag_ACELP16k, st->rf_flag , st->is_ism_format ); + + st->fscale = sr2fscale(st->sr_core); + fscaleFB = sr2fscale(st->output_Fs); + + /* initializing variables for frame lengths etc. right in the beginning */ + st->L_frame = extract_l(Mult_32_16(st->sr_core , 0x0290)); +#ifndef NEW_IVAS_OPEN_DEC + hTcxDec->L_frameTCX = extract_l(Mult_32_16(st->output_Fs , 0x0290)); +#endif + IF (st->ini_frame == 0) + { + st->last_L_frame = st->L_frame_past = st->L_frame; + move16(); + move16(); +#ifndef NEW_IVAS_OPEN_DEC + st->L_frameTCX_past = hTcxDec->L_frameTCX; +#endif + move16(); + } +#ifdef NEW_IVAS_OPEN_DEC + IF(st->hTcxDec != NULL) + { + hTcxDec->L_frameTCX = extract_l(Mult_32_16(st->output_Fs, 0x0290)); + IF(st->ini_frame == 0) + { + st->L_frameTCX_past = st->hTcxDec->L_frameTCX; + } + } +#endif + st->tcxonly = getTcxonly( +#ifdef IVAS_CODE_SWITCHING + st->element_mode, +#endif + st->total_brate +#ifdef IVAS_CODE_SWITCHING + ,is_mct +#endif + /*, st->is_ism_format Needed in the last version of float IVAS */ + ); + move16(); + + /* the TD TCX PLC in MODE1 still runs with 80ms subframes */ + st->nb_subfr = NB_SUBFR; + move16(); + test();test();test();test(); + + if ( (EQ_16(st->element_mode, EVS_MONO) && EQ_16(st->L_frame,L_FRAME16k) && LE_32(st->total_brate,32000)) || + (GT_16(st->element_mode, EVS_MONO) && EQ_16(st->L_frame, L_FRAME16k) && LE_32(total_brate, MAX_ACELP_BRATE)) || + (st->tcxonly != 0 && (EQ_32(st->sr_core,32000) || EQ_32(st->sr_core,16000)) ) + ) + { + st->nb_subfr = NB_SUBFR16k; + move16(); + } + + /* (float)st->L_frame/(float)st->fscale * (float)FSCALE_DENOM/128.0f * (float)st->total_brate */ + st->bits_frame = extract_l(L_shr(Mpy_32_16_1( L_shl(st->total_brate, 1) , 20972), 6)); /* 20972 = 0.01 * 64 * 32768 */ + + assert(FSCALE_DENOM == 512); + assert(st->fscale == 2 * st->L_frame); /* this assumption is true if operated in 20ms frames with FSCALE_DENOM == 512, which is the current default */ + assert(st->bits_frame == (int)( (float)st->L_frame/(float)st->fscale * (float)FSCALE_DENOM/128.0f * (float)st->total_brate/100.0f + 0.49f )); + + st->TcxBandwidth = getTcxBandwidth(bwidth); + st->narrowBand = 0; + move16(); + if (EQ_16(bwidth, NB)) + { + st->narrowBand = 1; + move16(); + } + + IF (EQ_16(st->element_mode, IVAS_CPE_MDCT)) + { + st->pit_res_max = initPitchLagParameters(INT_FS_12k8, &st->pit_min, &st->pit_fr1, &st->pit_fr1b, &st->pit_fr2, &st->pit_max); + IF(hTcxDec != NULL) + { + //st->pit_res_max = initPitchLagParameters(12800, &st->pit_min, &st->pit_fr1, &st->pit_fr1b, &st->pit_fr2, &st->pit_max); + //hTcxDec->pit_max_TCX = (int16_t)(st->pit_max * st->output_Fs / 12800); + //hTcxDec->pit_min_TCX = (int16_t)(st->pit_min * st->output_Fs / 12800); +#if 0 + PMT("Fixed point to be verified here") +#endif + i = mult_r(hTcxDec->L_frameTCX, getInvFrameLen(L_FRAME)); + hTcxDec->pit_max_TCX = extract_l(L_shr(L_mult(st->pit_max, i), 7)); + hTcxDec->pit_min_TCX = extract_l(L_shr(L_mult(st->pit_min, i), 7)); + + } + } + ELSE + { + st->pit_res_max = initPitchLagParameters(st->sr_core, &st->pit_min, &st->pit_fr1, &st->pit_fr1b, &st->pit_fr2, &st->pit_max); + IF (hTcxDec != NULL) + { + i = mult_r(hTcxDec->L_frameTCX, getInvFrameLen(st->L_frame)); + hTcxDec->pit_max_TCX = extract_l(L_shr(L_mult(st->pit_max, i), 7)); + hTcxDec->pit_min_TCX = extract_l(L_shr(L_mult(st->pit_min, i), 7)); + } + } + IF ( st->ini_frame == 0) + { + st->pit_res_max_past = st->pit_res_max; + } + + /*Preemphasis param*/ + st->preemph_fac = PREEMPH_FAC_SWB; /*SWB*/ move16(); + IF ( LT_16(st->fscale, (16000*FSCALE_DENOM)/ INT_FS_12k8)) + { + st->preemph_fac = PREEMPH_FAC; /*WB*/ move16(); + } + ELSE if ( LT_16(st->fscale, (24000*FSCALE_DENOM)/ INT_FS_12k8)) + { + st->preemph_fac = PREEMPH_FAC_16k; /*WB*/ move16(); + } + + st->gamma = GAMMA1; + move16(); + st->inv_gamma = GAMMA1_INV; + move16(); + IF ( EQ_32(st->sr_core, INT_FS_16k) || + (GT_32(st->sr_core, INT_FS_16k) && EQ_16(st->element_mode, IVAS_CPE_MDCT) ) + ) + { + st->gamma = GAMMA16k; + move16(); + st->inv_gamma = GAMMA16k_INV; + move16(); + } + + /* LPC quantization */ + st-> lpcQuantization = 0; + move16(); + test(); + if( st->tcxonly == 0 && LE_32(st->sr_core, INT_FS_16k)) + { + st->lpcQuantization = 1; + } + + st->numlpc = 2; + move16(); + if ( st->tcxonly==0 ) + { + st->numlpc = 1; + move16(); + } + + /* Initialize TBE */ + st->prev_coder_type_fx = GENERIC; + if (st->hBWE_TD != NULL) + { + set16_fx(hBWE_TD->prev_lsf_diff_fx, 16384, LPC_SHB_ORDER - 2); + hBWE_TD->prev_tilt_para_fx = 0; + set16_fx(hBWE_TD->cur_sub_Aq_fx, 0, M + 1); + } + + /*TCX config*/ +#ifndef NEW_IVAS_OPEN_DEC + st->hTcxCfg->preemph_fac = st->preemph_fac; + move16(); + st->hTcxCfg->tcx_mdct_window_length_old = st->hTcxCfg->tcx_mdct_window_length; + move16(); + init_TCX_config( st->hTcxCfg, st->L_frame, st->fscale, hTcxDec->L_frameTCX, fscaleFB ); // TEMPORARY should be rename to init_TCX_config + IF(st->ini_frame == 0) + { + st->hTcxCfg->tcx_last_overlap_mode = st->hTcxCfg->tcx_curr_overlap_mode = ALDO_WINDOW; + move16(); + move16(); + } + + /* TCX Offset */ + st->hTcxCfg->tcx_offset = shr(st->hTcxCfg->tcx_mdct_window_delay, 1); + st->hTcxCfg->tcx_offsetFB = shr(st->hTcxCfg->tcx_mdct_window_delayFB, 1); + + /* Initialize FAC */ + st->hTcxCfg->lfacNext = sub(st->hTcxCfg->tcx_offset, shr(st->L_frame, 2)); + st->hTcxCfg->lfacNextFB = sub(st->hTcxCfg->tcx_offsetFB, shr(hTcxDec->L_frameTCX, 2)); + + /* set number of coded lines */ + st->hTcxCfg->tcx_coded_lines = getNumTcxCodedLines(st->bwidth); + + /* TNS in TCX */ + st->hTcxCfg->pCurrentTnsConfig = NULL; + st->hTcxCfg->fIsTNSAllowed = getTnsAllowed(st->total_brate, st->igf, st->element_mode); + + IF(st->hTcxCfg->fIsTNSAllowed != 0) + { + InitTnsConfigs(st->bwidth, st->hTcxCfg->tcx_coded_lines, st->hTcxCfg->tnsConfig, st->hIGFDec->infoIGFStopFreq, st->total_brate, st->element_mode, 0/*is_mct*/); + + } + /*Constraint for adaptive BPF, otherwise parameter estimation and post-processing not time aligned*/ + if (st->tcxonly == 0) + { + assert(0 == (st->hTcxCfg->lfacNext > 0 ? st->hTcxCfg->lfacNext : 0)); + } + + if (st->element_mode == EVS_MONO) + { + if ((st->hTECDec = (TEC_DEC_HANDLE)malloc(sizeof(TEC_DEC_DATA))) == NULL) + { + return (IVAS_ERROR(IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TEC\n")); + } + } + else + { + st->hTECDec = NULL; + } + resetTecDec_Fx(st->hTECDec); + + +#else + if (st->hIGFDec != NULL) + { + PMT("To be done") + //if (!is_init || st->element_mode != IVAS_CPE_MDCT) + //{ + // init_tcx_cfg(st->hTcxCfg, total_brate, st->sr_core, st->output_Fs, st->L_frame, st->bwidth, st->hTcxDec->L_frameTCX, st->fscale, encoderLookahead, encoderLookaheadFB, st->preemph_fac, st->tcxonly, st->rf_flag, st->igf, st->hIGFDec->infoIGFStopFreq, st->element_mode, st->ini_frame, MCT_flag); + //} + //else + //{ + // st->hTcxCfg->tcx_curr_overlap_mode = st->hTcxCfg->tcx_last_overlap_mode = ALDO_WINDOW; + // st->hTcxCfg->last_aldo = 1; + //} + } + /*Constraint for adaptive BPF, otherwise parameter estimation and post-processing not time aligned*/ + if (st->tcxonly == 0) + { + assert(0 == (st->hTcxCfg->lfacNext > 0 ? st->hTcxCfg->lfacNext : 0)); + } + //if (st->tecDec_fx != NULL) + { + resetTecDec_Fx(&(st->tecDec_fx)); + } + +#endif + + + + /* Initialize decoder delay */ + + + IF (NE_16(st->element_mode, IVAS_SCE)) + { + st->flag_cna = 0; + move16(); + } + IF( st->ini_frame == 0 ) + { + st->flag_cna = 0; + st->last_flag_cna = 0; + move16(); + } + + /* Static vectors to zero */ + IF (st->ini_frame == 0) + { + + st->last_is_cng = 0; + move16(); + + st->rate_switching_reset = 0; + move16(); + IF(hTcxDec != NULL) + { + set16_fx(hTcxDec->old_syn_Overl, 0, L_FRAME32k / 2); + + set16_fx(hTcxDec->syn_Overl_TDAC, 0, L_FRAME32k / 2); + set16_fx(hTcxDec->syn_OverlFB, 0, L_FRAME_MAX / 2); + set16_fx(hTcxDec->syn_Overl_TDACFB, 0, L_FRAME_MAX / 2); + + set16_fx(hTcxDec->syn_Overl, 0, L_FRAME32k / 2); + + set16_fx(hTcxDec->old_synth, 0, OLD_SYNTH_INTERNAL_DEC); + set16_fx(hTcxDec->synth_history_fx, 0, L_PROT48k + L_FRAME_MAX); + } + set16_fx(st->syn, 0, M+1); + + set16_fx(st->mem_syn_r, 0, L_SYN_MEM); + + mem_syn_r_size_old = 0; /* just to avoid MSVC warnings */ + mem_syn_r_size_new = 0; /* just to avoid MSVC warnings */ + + st->con_tcx = 0; + } + ELSE + { + /* Reset old_synth in case of core sampling rate switching and codec switching*/ + test(); + IF(st->hTcxDec != NULL && ((NE_16(st->L_frame, st->last_L_frame))||(EQ_16(st->last_codec_mode,MODE1)))) + { + set16_fx(hTcxDec->old_synth, 0, OLD_SYNTH_INTERNAL_DEC); + } + + /*Size of LPC syn memory*/ + /* 1.25/20.0 = 1.0/16.0 -> shift 4 to the right. */ + mem_syn_r_size_old = shr(st->last_L_frame, 4); + mem_syn_r_size_new = shr(st->L_frame, 4); + + /*Reset LPC mem*/ + test(); + test(); + IF( (NE_16(st->L_frame,st->last_L_frame))||(EQ_16(st->last_core,AMR_WB_CORE)) + || EQ_16(st->last_core,HQ_CORE) ) + { + /*LPC quant. mem*/ + set16_fx(st->mem_MA_fx, 0, M); + IF( EQ_32(st->sr_core, INT_FS_16k)) + { + Copy( GEWB2_Ave_fx, st->mem_AR_fx, M ); + } + ELSE + { + Copy( GEWB_Ave_fx, st->mem_AR_fx, M ); + } + } + + /*Codec switching*/ + IF( EQ_16(st->last_codec_mode,MODE1) && EQ_16(st->element_mode, EVS_MONO)) + { + Copy( st->lsp_old_fx, st->lspold_uw, M ); + Copy( st->lsf_old_fx, st->lsfold_uw, M ); + set16_fx( st->syn, 0, M ); + } + IF( EQ_16(st->last_core,AMR_WB_CORE)) + { + st->last_core = ACELP_CORE; + move16(); + st->last_core_bfi = ACELP_CORE; + move16(); + } + + /*Codec switching from ACELP-A */ + test(); test(); test(); test(); + IF( (NE_16(st->element_mode, IVAS_CPE_DFT) || (EQ_16(st->element_mode, IVAS_CPE_DFT) && st->prev_bfi ) ) && EQ_16(st->last_codec_mode, MODE1) && EQ_16(st->last_core,ACELP_CORE) ) + { + st->last_core_bfi = ACELP_CORE; + move16(); + + /*PLC*/ +#ifndef NEW_IVAS_OPEN_DEC + IF(st->prev_bfi!=0) + { + PWord16 const *w; + Word16 W1,W2,nz,delay_comp; + + W1 = st->hTcxCfg->tcx_mdct_window_lengthFB; + move16(); + W2 = shr(st->hTcxCfg->tcx_mdct_window_lengthFB, 1); + w = st->hTcxCfg->tcx_mdct_windowFB; /*pointer - no need to instrument*/ + + nz = NS2SA_fx2(st->output_Fs, N_ZERO_MDCT_NS); + delay_comp = NS2SA_fx2(st->output_Fs, DELAY_CLDFB_NS); /*CLDFB delay*/ + + Copy(hHQ_core->fer_samples_fx+delay_comp, hTcxDec->syn_OverlFB, shr(hTcxDec->L_frameTCX,1)); + + lerp(hHQ_core->fer_samples_fx+delay_comp, hTcxDec->syn_Overl , shr(st->L_frame,1), shr(hTcxDec->L_frameTCX,1)); /*Q0: ACELP(bfi)->TCX(rect)*/ + + /*old_out needed for MODE1 routine and syn_Overl_TDAC for MODE2 routine*/ + hHQ_core->Q_old_wtda=-1; + set16_fx(hHQ_core->old_out_fx, 0, nz); + Copy_Scale_sig(hHQ_core->fer_samples_fx+delay_comp, hHQ_core->old_out_fx+nz,W1, hHQ_core->Q_old_wtda); /*Q-1*/ + + FOR (i=0; i < W2; i++) + { + hHQ_core->old_out_fx[i+nz] = round_fx(Mpy_32_16_1(L_mult(w[i].v.re,w[i].v.re), hHQ_core->old_out_fx[i+nz])); + } + FOR ( ; i < W1; i++) + { + hHQ_core->old_out_fx[i+nz] = round_fx(Mpy_32_16_1(L_mult(w[W2-1-(i-W2)].v.im,w[W2-1-(i-W2)].v.im), hHQ_core->old_out_fx[i+nz])); + } + set16_fx(&hHQ_core->old_out_fx[W1+nz], 0, nz); + + lerp(hHQ_core->old_out_fx, hHQ_core->old_out_LB_fx,st->L_frame , hTcxDec->L_frameTCX); + + Copy(hHQ_core->old_out_fx +nz, hTcxDec->syn_Overl_TDACFB, shr(hTcxDec->L_frameTCX,1)); + nz = NS2SA_fx2(st->sr_core, N_ZERO_MDCT_NS); + Copy(hHQ_core->old_out_LB_fx+nz, hTcxDec->syn_Overl_TDAC , shr(st->L_frame,1)); + hHQ_core->Q_old_wtda_LB = hHQ_core->Q_old_wtda; + } +#else + PMT("acelp_plc_mdct_transition is missing") + //acelp_plc_mdct_transition(st); +#endif + } + + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( EQ_16(st->last_codec_mode,MODE2)&& + NE_16(st->L_frame, st->last_L_frame) && + ( ( EQ_16(st->m_frame_type, SID_FRAME) && GT_16(st->last_core, ACELP_CORE) ) || + ( GT_16(st->last_core, ACELP_CORE) && GT_16(st->core, ACELP_CORE) ) || + st->prev_bfi ) ) + { + lerp(hHQ_core->old_out_LB_fx, hHQ_core->old_out_LB_fx, st->L_frame, st->last_L_frame); + } + + /* Rate switching */ + test(); + test(); + test(); + IF( EQ_16(st->last_codec_mode,MODE1)&&EQ_16(st->last_core,HQ_CORE)) + { + /*Codec switching from MDCT */ + + /*Reset of ACELP memories*/ + move16(); + move16(); + st->rate_switching_reset=1; + st->tilt_code_fx = TILT_CODE; + set16_fx(st->old_exc_fx, 0, L_EXC_MEM_DEC); + set16_fx(st->syn, 0, 1+M); + set16_fx(st->mem_syn2_fx, 0, M); + + /*OLA -> zero */ + if (st->hTcxDec != NULL) + { + set16_fx(hTcxDec->old_syn_Overl, 0, L_FRAME32k / 2); /*HQ-CORE(bfi)->TCX don't need it*/ + set16_fx(hTcxDec->syn_Overl_TDAC, 0, L_FRAME32k / 2); /*HQ-CORE(bfi)->TCX don't need it*/ + set16_fx(hTcxDec->syn_Overl_TDACFB, 0, L_FRAME_MAX / 2); /*HQ-CORE(bfi)->TCX don't need it*/ + set16_fx(hTcxDec->syn_Overl, 0, L_FRAME32k / 2); /*HQ-CORE(bfi)->TCX don't need it*/ +#if 0 + PMT("to be moved to reset_tcx_overl_buf") +#endif + } + if (st->hTcxCfg != NULL) + { + Copy_Scale_sig(hHQ_core->old_out_fx + NS2SA(st->output_Fs, N_ZERO_MDCT_NS), hTcxDec->syn_OverlFB, st->hTcxCfg->tcx_mdct_window_lengthFB, negate(add(hHQ_core->Q_old_wtda, TCX_IMDCT_HEADROOM))); + + move16(); + move16(); + st->hTcxCfg->last_aldo = 1; /*It was previously ALDO*/ + st->hTcxCfg->tcx_curr_overlap_mode = ALDO_WINDOW; + } + /*OLA for MDCT-LB always reset in codec switching cases*/ + if (st->hHQ_core != NULL) + { + set16_fx(hHQ_core->old_out_LB_fx, 0, st->L_frame); + } + move16(); + st->last_core_bfi = TCX_20_CORE; + + if (st->hPFstat != NULL) + { + st->hPFstat->on = 0; + } + move16(); + /* reset CLDFB memories */ + cldfb_reset_memory( st->cldfbAna_fx ); + cldfb_reset_memory( st->cldfbBPF_fx ); + cldfb_reset_memory( st->cldfbSyn_fx ); +#ifndef NEW_IVAS_OPEN_DEC +#if 0 + PMT("cldfbSynHB is missing ") +#endif + //if (st->cldfbSynHB != NULL) + //{ + // cldfb_reset_memory(st->cldfbSynHB); + //} +#endif + } + ELSE IF( (NE_16(st->L_frame,st->last_L_frame))&&(LE_16(st->L_frame,L_FRAME16k))&&(LE_16(st->last_L_frame,L_FRAME16k))) /* Rate switching between 12.8 and 16 kHz*/ + { + /*Interpolation of ACELP memories*/ + + /* convert quantized LSP vector */ + st->rate_switching_reset=lsp_convert_poly_fx( st->lsp_old_fx, st->L_frame, 0 ); + IF( st->tcxonly == 0 ) + { + lsp2lsf_fx( st->lsp_old_fx, st->lsf_old_fx, M, st->sr_core ); + } + ELSE + { + E_LPC_lsp_lsf_conversion( st->lsp_old_fx, st->lsf_old_fx, M ); + } + E_LPC_f_lsp_a_conversion(st->lsp_old_fx, st->old_Aq_12_8_fx, M); + + + Copy( st->lsp_old_fx, st->lspold_uw, M ); + Copy( st->lsf_old_fx, st->lsfold_uw, M ); + + IF( !st->last_con_tcx ) + { + synth_mem_updt2( st->L_frame, st->last_L_frame, st->old_exc_fx, st->mem_syn_r, st->mem_syn2_fx, NULL, DEC ); + } + + /*mem of deemphasis stayed unchanged.*/ + } + ELSE IF( NE_16(st->L_frame,st->last_L_frame)) /* Rate switching involving TCX only modes */ + { + /*Partial reset of ACELP memories*/ + st->rate_switching_reset = 1; + + /*reset partly some memories*/ + st->tilt_code_fx = TILT_CODE; + IF( !st->last_con_tcx ) + { + set16_fx( st->old_exc_fx, 0, L_EXC_MEM_DEC ); + } + set16_fx( st->old_Aq_12_8_fx, 0, M+1 ); + + /*Resamp others memories*/ + /*Size of LPC syn memory*/ + lerp( st->mem_syn_r+L_SYN_MEM-mem_syn_r_size_old, st->mem_syn_r+L_SYN_MEM-mem_syn_r_size_new, mem_syn_r_size_new, mem_syn_r_size_old ); + Copy( st->mem_syn_r+L_SYN_MEM-M, st->mem_syn2_fx, M ); + + /*Untouched memories : st->syn */ + } + ELSE IF( !st->tcxonly && EQ_16(st->L_frame,L_FRAME16k)&>_32(st->last_total_brate,ACELP_32k)) + { + lsp2lsf_fx( st->lsp_old_fx, st->lsf_old_fx, M, st->sr_core ); + } + } + + test(); + test(); + if(EQ_16(st->last_bwidth,NB)&&NE_16(st->bwidth,NB)&&st->ini_frame!=0) + { + st->rate_switching_reset=1; + move16(); + } + IF (st->hTcxDec != NULL) + { + hTcxDec->old_synth_len = shl(st->L_frame, 1); + hTcxDec->old_synth_lenFB = shl(hTcxDec->L_frameTCX, 1); + } + /* bass pf reset */ + st->bpf_gain_param = 0; + move16(); + if (st->hBPF != NULL) + { + set16_fx(hBPF->pst_old_syn_fx, 0, NBPSF_PIT_MAX); + } + /* Formant postfilter */ + IF ( st->ini_frame==0 ) + { + /*do nothing*/ + } + ELSE IF( EQ_16(st->last_codec_mode,MODE2)) + { + IF (st->tcxonly==0) + { + IF ( st->hPFstat->on!=0 ) + { + lerp( st->hPFstat->mem_stp+L_SYN_MEM-mem_syn_r_size_old, st->hPFstat->mem_stp+L_SYN_MEM-mem_syn_r_size_new, mem_syn_r_size_new, mem_syn_r_size_old ); + lerp( st->hPFstat->mem_pf_in+L_SYN_MEM-mem_syn_r_size_old, st->hPFstat->mem_pf_in+L_SYN_MEM-mem_syn_r_size_new, mem_syn_r_size_new, mem_syn_r_size_old ); + } + ELSE + { + set16_fx( st->hPFstat->mem_stp, 0,L_SYN_MEM ); + set16_fx( st->hPFstat->mem_pf_in, 0,L_SYN_MEM ); + st->hPFstat->reset = 1; + st->hPFstat->gain_prec = 16384; + move16(); + } + } + ELSE IF ( st->hPFstat->on!=0 ) + { + lerp( st->hPFstat->mem_stp+L_SYN_MEM-mem_syn_r_size_old, st->hPFstat->mem_stp+L_SYN_MEM-mem_syn_r_size_new, mem_syn_r_size_new, mem_syn_r_size_old ); + lerp( st->hPFstat->mem_pf_in+L_SYN_MEM-mem_syn_r_size_old, st->hPFstat->mem_pf_in+L_SYN_MEM-mem_syn_r_size_new, mem_syn_r_size_new, mem_syn_r_size_old ); + } + } + ELSE + { + /*codec switching*/ + /*reset post-filter except for Narrowband*/ + IF ( NE_32(st->output_Fs,8000)) + { + if (st->hPFstat != NULL) + { + st->hPFstat->reset = 1; + if (st->hPFstat->on != 0) + { + st->hPFstat->reset = 0; + Scale_sig(st->hPFstat->mem_pf_in, L_SUBFR, negate(st->Q_syn)); /* WB post_filter mem */ + Scale_sig(st->hPFstat->mem_stp, L_SUBFR, negate(st->Q_syn)); /* WB post_filter mem */ + lerp(st->hPFstat->mem_stp + L_SYN_MEM - mem_syn_r_size_old, st->hPFstat->mem_stp + L_SYN_MEM - mem_syn_r_size_new, mem_syn_r_size_new, mem_syn_r_size_old); + lerp(st->hPFstat->mem_pf_in + L_SYN_MEM - mem_syn_r_size_old, st->hPFstat->mem_pf_in + L_SYN_MEM - mem_syn_r_size_new, mem_syn_r_size_new, mem_syn_r_size_old); + } + } + } + ELSE + { + if (st->hPFstat != NULL) + { + Scale_sig(st->hPFstat->mem_pf_in, L_SUBFR, negate(st->Q_syn)); /* NB post_filter mem */ + Scale_sig(st->hPFstat->mem_res2, DECMEM_RES2, negate(st->Q_syn)); /* NB post_filter mem */ + Scale_sig(st->hPFstat->mem_stp, L_SUBFR, negate(st->Q_syn)); /* NB post_filter mem */ + } + /*feed last value old_synth as it is used for pre-emphasis mem*/ + if (st->hTcxDec != NULL) + { + hTcxDec->old_synth[hTcxDec->old_synth_len - 1] = st->syn[M]; + } + move16(); + if (st->hBPF != NULL) + { + hBPF->pst_old_syn_fx[NBPSF_PIT_MAX - 1] = st->syn[M]; + } + move16(); + } + } + + /* lsf and lsp initialization */ + IF ( st->ini_frame == 0 ) + { + Copy(st->lsp_old_fx, st->lspold_uw, M); + Copy(st->lsf_old_fx, st->lsfold_uw, M); + + set16_fx(st->lsf_cng, 0, M); + } + + st->seed_tcx_plc = RANDOM_INITSEED; + move16(); + st->past_gpit = 0; + move16(); + st->past_gcode = L_deposit_l(0); + st->gc_threshold_fx = L_deposit_l(0); + + E_LPC_lsf_lsp_conversion(st->lsf_cng, st->lspold_cng, M); + E_LPC_f_lsp_a_conversion(st->lspold_cng, st->Aq_cng, M); + st->plcBackgroundNoiseUpdated = 0; + move16(); + Copy(st->lsf_old_fx, st->lsf_q_cng, M); + Copy(st->lsf_old_fx, st->old_lsf_q_cng, M); + Copy(st->lsp_old_fx, st->lsp_q_cng, M); + Copy(st->lsp_old_fx, st->old_lsp_q_cng, M); + set16_fx(st->mem_syn_unv_back, 0, M); + + st->last_gain_syn_deemph = 32768/2; + move16(); + st->last_gain_syn_deemph_e = 1; + move16(); + test(); + IF( EQ_16(st->last_codec_mode,MODE1)||st->ini_frame==0) + { + /* this assumes that MODE1 fades out in the frequency domain - + otherwise some data from MODE1 would be needed here */ + st->last_concealed_gain_syn_deemph = 32768/2; + move16(); + st->last_concealed_gain_syn_deemph_e = 1; + move16(); + if (hTcxDec != NULL) + { + hTcxDec->conceal_eof_gain = 32768 / 2;/*Q14*/ move16(); + } + } + + /* Post processing */ + set16_fx(st->mem_Aq,0,NB_SUBFR16k*(M+1)); + st->lp_ener_FER_fx = 15360; + move16(); /*60 in Q8*/ + IF (st->ini_frame == 0) + { + st->prev_bfi = 0; + move16(); + st->last_core_bfi = -1; + move16(); + } + st->prev_old_bfi_fx = 0; + move16(); + + /*st->noise_filling_index = 0;*/ /* not in BASOP */ + + Copy(st->lsf_old_fx, st->lsf_adaptive_mean_fx, M); + Copy(st->lsf_old_fx, st->lsfoldbfi0_fx, M); + Copy(st->lsf_old_fx, st->lsfoldbfi1_fx, M); + + st->clas_dec = UNVOICED_CLAS; + move16(); + move16(); + IF (!st->last_con_tcx) + { + move16(); + st->old_enr_LP = 0; /* LP filter E of last good voiced frame or local LP filter E in TD TCX PLC */ + } + + IF (st->prev_bfi) + { + /* calculate energy at the end of the previous frame */ + test(); + IF( EQ_16(st->core,ACELP_CORE)&&EQ_16(st->last_core,HQ_CORE)) + { + /*_DIFF_FLOAT_FIX_*/ +#if 0 + PMT("floating point is using L_frameTCX instead of output_frame, is it ok?") +#endif + frame_ener_fx( st->output_frame_fx, UNVOICED_CLAS, st->previoussynth_fx, -1, &st->enr_old_fx, 1, 0, 0, 0 ); + } + } + ELSE + { + st->last_good_fx = UNVOICED_CLAS; /* last good received frame for concealment */ move16(); + st->enr_old_fx = L_deposit_l(0); /* energy at the end of the previous frame */ + } + st->Mode2_lp_gainc = L_deposit_l(0); + st->Mode2_lp_gainp = L_deposit_l(0); + + st->prev_widow_left_rect = 0; + move16(); + if (st->hTcxDec != NULL) + { +#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT + /* Todo: should be considered for other stereo modes as well */ + if (is_init || MCT_flag || !(st->element_mode == IVAS_CPE_MDCT && st->element_mode == last_element_mode)) + { PMT("Fixed point to be done") + st->hTcxDec->CngLevelBackgroundTrace_bfi = PLC_MIN_CNG_LEV; + st->hTcxDec->NoiseLevelIndex_bfi = PLC_MIN_STAT_BUFF_SIZE - 1; + st->hTcxDec->CurrLevelIndex_bfi = 0; + st->hTcxDec->LastFrameLevel_bfi = PLC_MIN_CNG_LEV; + set_f(st->hTcxDec->NoiseLevelMemory_bfi, PLC_MIN_CNG_LEV, PLC_MIN_STAT_BUFF_SIZE); + + st->hTcxDec->cummulative_damping_tcx = 1.0f; + } +#else + hTcxDec->conCngLevelBackgroundTrace = PLC_MIN_CNG_LEV; /*Q15*/ move16(); + hTcxDec->conNoiseLevelIndex = PLC_MIN_STAT_BUFF_SIZE - 1; + move16(); + hTcxDec->conCurrLevelIndex = 0; + move16(); + hTcxDec->conLastFrameLevel = PLC_MIN_CNG_LEV; /*Q15*/ move16(); + set16_fx(hTcxDec->conNoiseLevelMemory, PLC_MIN_CNG_LEV, PLC_MIN_STAT_BUFF_SIZE); /*Q15*/ + set16_fx(hTcxDec->conNoiseLevelMemory_e, 0, PLC_MIN_STAT_BUFF_SIZE); + hTcxDec->conLastFrameLevel_e = 0; + hTcxDec->conCngLevelBackgroundTrace_e = 0; + + hTcxDec->cummulative_damping_tcx = 32767/*1.0f Q15*/; +#endif + } + move16(); + st->cummulative_damping = 32767/*1.0f Q15*/; + move16(); + + FOR ( i=0; i<2*NB_SUBFR16k+2; i++ ) + { + st->old_pitch_buf_fx[i] = L_deposit_h(st->pit_min); + } + + FOR ( i=0; i<2*NB_SUBFR16k+2; i++ ) + { + st->mem_pitch_gain[i] = 16384/*1.f Q14*/;/*Q14*/ + } + + + st->old_fpitch = L_deposit_h(st->pit_min); +#ifndef NEW_IVAS_OPEN_DEC + st->old_fpitchFB = L_deposit_h(hTcxDec->pit_min_TCX); +#endif + st->rate_switching_init = 1; + move16(); + + st->reset_mem_AR = 0; + move16(); + + /* For phase dispersion */ + st->dm_fx.prev_gain_code = L_deposit_l(0); + set16_fx(st->dm_fx.prev_gain_pit, 0, 6); + st->dm_fx.prev_state = 0; + move16(); + + st->voice_fac = -1; /* purely unvoiced */ move16(); + + /* TCX-LTP */ + if (hTcxLtpDec != NULL) + { + hTcxLtpDec->tcxltp = getTcxLtp(st->sr_core); + } + move16(); + + test(); + IF (hTcxLtpDec != NULL && (st->ini_frame == 0 || (EQ_16(st->last_codec_mode,MODE1) && EQ_16(st->element_mode, EVS_MONO)))) + { +#if 0 + PMT("TO be verify, update seems to differ from float") +#endif + hTcxLtpDec->tcxltp_pitch_int = st->pit_max; + move16(); + hTcxLtpDec->tcxltp_pitch_fr = 0; + move16(); + if (hTcxDec != NULL) + { + hTcxDec->tcxltp_last_gain_unmodified = 0; + } + move16(); + IF ( st->ini_frame == 0) + { + set16_fx(hTcxLtpDec->tcxltp_mem_in, 0, TCXLTP_MAX_DELAY ); + set16_fx(hTcxLtpDec->tcxltp_mem_out, 0, L_FRAME48k ); + hTcxLtpDec->tcxltp_pitch_int_post_prev = 0; + move16(); + hTcxLtpDec->tcxltp_pitch_fr_post_prev = 0; + move16(); + hTcxLtpDec->tcxltp_gain_post_prev = 0; + move16(); + hTcxLtpDec->tcxltp_filt_idx_prev = -1; + move16(); + } + } + + /* in floating point implementation, different buffers are used: lp_error_ener <-> pst_lp_ener, mem_error <-> pst_mem_deemp_err */ + if (st->hBPF != NULL) + { + + st->lp_error_ener = Mpy_32_16_1(L_shl(hBPF->pst_lp_ener_fx, 8), 0x2a86); /* convert from 7Q8 10*log10 -> 15Q16, log2 */ + } + else + { + st->lp_error_ener = 0; + } + st->mem_error = L_deposit_l(0); + st->hTcxCfg->ctx_hm = getCtxHm (st->element_mode, total_brate, st->rf_flag); + st->last_ctx_hm_enabled = 0; + move16(); + + st->hTcxCfg->resq = getResq(total_brate); + move16(); + + st->hTcxCfg->sq_rounding = 12288/*0.375f Q15*/; /*deadzone of 1.25->rounding=1-1.25/2 (No deadzone=0.5)*/ move16(); + if (hTcxDec != NULL) + { + hTcxDec->tcx_lpc_shaped_ari = getTcxLpcShapedAri(total_brate, st->rf_flag, st->element_mode); + + hTcxDec->envWeighted = 0; + } + move16(); + + st->p_bpf_noise_buf = NULL; + if (st->tcxonly == 0) + { + st->p_bpf_noise_buf = st->bpf_noise_buf; + } + + st->tec_tfa = 0; + move16(); + test(); + test(); + if ( EQ_16(bwidth, SWB)&& + (EQ_32(st->total_brate, ACELP_16k40) || EQ_32(st->total_brate, ACELP_24k40)) && EQ_16(st->element_mode, EVS_MONO)) + { + st->tec_tfa = 1; + move16(); + } + + st->tec_flag = 0; + move16(); + st->tfa_flag = 0; + move16(); + + st->enableGplc = 0; + move16(); + + st->flagGuidedAcelp = 0; + move16(); + st->T0_4th = L_SUBFR; + move16(); + st->guidedT0 = st->T0_4th; + move16(); + test(); + test(); + test(); + + st->enablePlcWaveadjust = 0; + move16(); + IF(st->hTcxDec != NULL && GE_32(st->total_brate, 48000) && EQ_16(st->element_mode, EVS_MONO)) + { + st->enablePlcWaveadjust = 1; + move16(); + test(); + test(); + test(); + IF (st->ini_frame == 0 || LT_32(st->last_total_brate, HQ_48k)||EQ_16(st->last_codec_mode,MODE1)||st->force_lpd_reset) + { + concealment_init_x(hTcxDec->L_frameTCX, &st->plcInfo ); + } + } + + /* PLC: [TCX: Tonal Concealment] */ +#if 0 + PMT("handle to tonalMDCTconceal is missing") +#endif +//#ifdef ADD_IVAS_HTONALMDCTCONC + if (/*st->ADD_IVAS_HTONALMDCTCONC != NULL &&*/ !(GT_16(st->element_mode, EVS_MONO) && NE_16(st->ini_frame,0) && EQ_16(st->tonalMDCTconceal.nSamples, st->hTcxDec->L_frameTCX))) + { + st->tonalMDCTconceal.nScaleFactors = 0; + move16(); + st->tonalMDCTconceal.nSamples = 0; + move16(); + st->tonalMDCTconceal.lastPcmOut = 0x0; + move16(); + st->tonalMDCTconceal.lastBlockData.tonalConcealmentActive = 0; + move16(); + st->tonalMDCTconceal.lastBlockData.nSamples = 0; + move16(); + + TonalMDCTConceal_Init(&st->tonalMDCTconceal, hTcxDec->L_frameTCX, st->L_frame, FDNS_NPTS, st->hTcxCfg); + } + st->last_tns_active = 0; + st->second_last_tns_active = 0; + st->second_last_core = -1; +#ifdef NEW_IVAS_OPEN_DEC + if (st->hTcxCfg != NULL && NE_16(st->element_mode, EVS_MONO ) ) + { + st->hTcxCfg->fIsTNSAllowed = getTnsAllowed(is_init ? total_brate : st->bits_frame_nominal * FRAMES_PER_SEC, st->igf); + } +#endif + if (hTcxDec != NULL) + { + hTcxDec->tcxltp_second_last_pitch = st->old_fpitch; + move16(); + hTcxDec->tcxltp_third_last_pitch = st->old_fpitch; + move16(); + } + move16(); + st->dec_glr = 0; + test(); + test(); + test(); + if ((total_brate == ACELP_9k60 || total_brate == ACELP_16k40 || total_brate == ACELP_24k40) && st->element_mode == EVS_MONO) + + if( ((EQ_32(st->total_brate, 9600))||(EQ_32(st->total_brate,16400))|| + (EQ_32(st->total_brate, 24400))) && st->element_mode == EVS_MONO) + { + move16(); + st->dec_glr = 1; + } + move16(); + st->dec_glr_idx = 0; + if (hTcxDec != NULL) + { + hTcxDec->enableTcxLpc = 1; + st->VAD = 0; + hTcxDec->old_gaintcx_bfi = 0; + hTcxDec->old_gaintcx_bfi_e = 0; + hTcxDec->tcx_hm_LtpPitchLag = -1; + } +#ifndef NEW_IVAS_OPEN_DEC + st->hTcxCfg->na_scale = 32767/*1.0f Q15*/; +#endif + if (hTcxLtpDec != NULL) + { + hTcxLtpDec->tcxltp_gain = 0; + } + return; +} + diff --git a/lib_dec/core_dec_reconf.c b/lib_dec/core_dec_reconf.c index f0519b6292da891572a0cf8e97644d6be841ed23..9c7bfcd8c4d3260b042eb9ad2c66d09fc859bd16 100644 --- a/lib_dec/core_dec_reconf.c +++ b/lib_dec/core_dec_reconf.c @@ -40,14 +40,15 @@ #include "rom_com.h" #include "rom_dec.h" #include "wmc_auto.h" +#include "prot_fx2.h" /*---------------------------------------------------------------------* - * reconfig_decoder_LPD() + * reconfig_decoder_LPD_ivas() * * *---------------------------------------------------------------------*/ -void reconfig_decoder_LPD( +void reconfig_decoder_LPD_ivas( Decoder_State *st, /* i/o: decoder state structure */ const int16_t bits_frame, /* i : bit budget */ const int16_t bwidth, /* i : audio bandwidth */ @@ -125,7 +126,7 @@ void reconfig_decoder_LPD( if ( st->hTcxCfg != NULL && st->fscale != st->fscale_old && !( st->element_mode == EVS_MONO && st->last_codec_mode == MODE1 && st->last_core == ACELP_CORE && st->prev_bfi != 0 ) ) /* no resempling is needed here when recovering from mode 1 ACELP PLC, since the buffers are already sampled with the - correct sampling rate in open_decoder_LPD() */ + correct sampling rate in open_decoder_LPD_flt() */ { newLen = st->hTcxCfg->tcx_mdct_window_length; oldLen = st->hTcxCfg->tcx_mdct_window_length_old; diff --git a/lib_dec/core_dec_reconf_fx.c b/lib_dec/core_dec_reconf_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..d2abbbdb333e92b2891e3efd832c9d57dfb1b0f3 --- /dev/null +++ b/lib_dec/core_dec_reconf_fx.c @@ -0,0 +1,192 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include +#include +#include "options.h" +#include "basop_util.h" +#include "prot_fx1.h" +#include "prot_fx2.h" +#include "rom_com.h" + + +void reconfig_decoder_LPD( + Decoder_State *st, /* i/o: decoder state structure */ + Word16 bits_frame, /* i : bit budget */ + Word16 bwidth, /* i : audio bandwidth */ + Word32 total_brate, /* i : total bitrate */ + Word16 L_frame_old /* i : frame length */ +) +{ + Word16 newLen; + Word16 oldLen; + Word32 lowrate_tcxlpc_max_br; + + TCX_LTP_DEC_HANDLE hTcxLtpDec; + TCX_DEC_HANDLE hTcxDec; + + hTcxLtpDec = st->hTcxLtpDec; + hTcxDec = st->hTcxDec; + + move16(); + st->bits_frame=bits_frame; + + IF (EQ_16(bwidth, NB)) + { + move16(); + st->narrowBand = 1; + } + ELSE if (GT_16(bwidth,NB)) + { + move16(); + st->narrowBand = 0; + } + + BITS_ALLOC_init_config_acelp(st->total_brate, st->narrowBand, st->nb_subfr, &(st->acelp_cfg)); + + /*Configuration of partial copy*/ + st->acelp_cfg_rf.mode_index = 1; + st->acelp_cfg_rf.midLpc = 0; + st->acelp_cfg_rf.midLpc_enable = 0; + st->acelp_cfg_rf.pre_emphasis = 0; + st->acelp_cfg_rf.formant_enh = 1; + st->acelp_cfg_rf.formant_tilt = 1; + st->acelp_cfg_rf.voice_tilt = 1; + st->acelp_cfg_rf.formant_enh_num = FORMANT_SHARPENING_G1; + st->acelp_cfg_rf.formant_enh_den = FORMANT_SHARPENING_G2; + + + IF (NE_16(st->element_mode, IVAS_SCE)) + { + st->flag_cna = (Word8)getCnaPresent(st->element_mode, st->element_brate, total_brate, bwidth); + } + move16(); + + /* TCX-LTP */ + IF (hTcxLtpDec != NULL) + { + hTcxLtpDec->tcxltp = getTcxLtp(st->sr_core); + } + move16(); + + if (st->hTcxCfg != NULL) + { + Word16 i; + + /*Scale TCX for non-active frames to adjust loudness with ACELP*/ + st->hTcxCfg->na_scale=32767/*1.0f Q15*/; + test(); + IF ((LT_16(bwidth,SWB))&&!(st->tcxonly)) + { + Word16 scaleTableSize = sizeof (scaleTcxTable) / sizeof (scaleTcxTable[0]); /* is a constant */ + + FOR (i = 0 ; i < scaleTableSize ; i++) + { + test(); + test(); + IF ( (EQ_16(bwidth,scaleTcxTable[i].bwmode)) && + (GE_32 (total_brate,scaleTcxTable[i].bitrateFrom) ) && + (LT_32 (total_brate,scaleTcxTable[i].bitrateTo) ) + ) + { + if( st->rf_flag ) + { + i--; + } + st->hTcxCfg->na_scale=scaleTcxTable[i].scale; + move16(); + BREAK; + } + } + } + } + + /*if its not the first frame resample overlap buffer to new sampling rate */ + IF ( st->ini_frame != 0 ) + { + test(); + test(); + test(); + IF(st->hTcxCfg != NULL && + (NE_16 (st->fscale,st->fscale_old) && + !(EQ_16(st->element_mode, EVS_MONO) && EQ_16(st->last_codec_mode, MODE1) && + EQ_16(st->last_core, ACELP_CORE) && st->prev_bfi != 0))) + /* no resempling is needed here when recovering from mode 1 + acelp plc, since the buffers are already sampled with the + correct sampling rate in open_decoder_LPD() */ + { + + newLen = st->hTcxCfg->tcx_mdct_window_length; + oldLen = st->hTcxCfg->tcx_mdct_window_length_old; + move16(); + move16(); + test(); + test(); + IF( (st->prev_bfi && EQ_16(st->last_core_bfi,ACELP_CORE))||EQ_16(st->last_core,ACELP_CORE)) + { + newLen = shr(st->L_frame,1); + oldLen = shr(L_frame_old,1); + } + IF (st->hTcxDec != NULL) + { + lerp(hTcxDec->old_syn_Overl, hTcxDec->old_syn_Overl, newLen, oldLen); + lerp(hTcxDec->syn_Overl, hTcxDec->syn_Overl, newLen, oldLen); + + test(); + IF(st->prev_bfi && EQ_16(st->last_core_bfi, ACELP_CORE)) + { + lerp(hTcxDec->syn_Overl_TDAC, hTcxDec->syn_Overl_TDAC, newLen, oldLen); + } + } + } + + + IF (LE_16(st->L_frame,L_FRAME16k)) + { + IF (LE_16(st->last_L_frame,L_FRAME16k)) + { + IF (NE_16(st->L_frame,st->last_L_frame)) + { + IF (GT_16(st->L_frame,st->last_L_frame)) + { + oldLen = extract_l(L_shr(Mpy_32_16_1(L_mult0(st->last_L_frame,getInvFrameLen(st->L_frame)/*Q21*/)/*Q21*/,L_SYN_MEM_CLAS_ESTIM/*Q0*/)/*Q6*/,6)/*Q0*/); + newLen = L_SYN_MEM_CLAS_ESTIM; + move16(); + + } + ELSE + { + oldLen = L_SYN_MEM_CLAS_ESTIM; + newLen = extract_l(L_shr(Mpy_32_16_1(L_mult0(st->L_frame,getInvFrameLen(st->last_L_frame)/*Q21*/)/*Q21*/,L_SYN_MEM_CLAS_ESTIM/*Q0*/)/*Q6*/,6)/*Q0*/); + } + lerp( &st->mem_syn_clas_estim_fx[sub(L_SYN_MEM_CLAS_ESTIM, oldLen)], &st->mem_syn_clas_estim_fx[sub(L_SYN_MEM_CLAS_ESTIM, newLen)], newLen, oldLen); + } + } + ELSE + { + set16_fx(st->mem_syn_clas_estim_fx, 0, L_SYN_MEM_CLAS_ESTIM); + st->classifier_Q_mem_syn = 0; + move16(); + } + } + } + test(); + test(); + + lowrate_tcxlpc_max_br = LOWRATE_TCXLPC_MAX_BR; + move16(); + IF (GT_16(st->element_mode, IVAS_SCE)) + { + lowrate_tcxlpc_max_br = LOWRATE_TCXLPC_MAX_BR_CPE; + } + hTcxDec->enableTcxLpc = EQ_16(st->numlpc, 1) && EQ_16(st->lpcQuantization, 1) && (LE_32(total_brate, lowrate_tcxlpc_max_br)/*LOWRATE_TCXLPC_MAX_BR*/ || st->rf_flag); + if (st->ini_frame == 0) + { + hTcxDec->envWeighted = 0; + move16(); + } + + + return; +} diff --git a/lib_dec/core_dec_switch.c b/lib_dec/core_dec_switch.c index a0d36c9ae06f6985f773f9f22c4dffd433e997d8..834465bf1204b61b09c78e464fe3c987b992153f 100644 --- a/lib_dec/core_dec_switch.c +++ b/lib_dec/core_dec_switch.c @@ -42,12 +42,12 @@ #include "wmc_auto.h" /*-------------------------------------------------------------* - * mode_switch_decoder_LPD() + * mode_switch_decoder_LPD_flt() * * *-------------------------------------------------------------*/ -void mode_switch_decoder_LPD( +void mode_switch_decoder_LPD_flt( Decoder_State *st, /* i/o: decoder state structure */ const int16_t bwidth, /* i : audio bandwidth */ const int32_t total_brate, /* i : total bitrate */ @@ -69,7 +69,7 @@ void mode_switch_decoder_LPD( { bSwitchFromAmrwbIO = 1; } - sr_core = getCoreSamplerateMode2( st->element_mode, total_brate, bwidth, st->flag_ACELP16k, st->rf_flag, st->is_ism_format ); + sr_core = getCoreSamplerateMode2_flt( st->element_mode, total_brate, bwidth, st->flag_ACELP16k, st->rf_flag, st->is_ism_format ); fscale = sr2fscale( sr_core ); /* set number of coded lines */ @@ -98,12 +98,12 @@ void mode_switch_decoder_LPD( if ( st->igf && ( st->idchan == 0 || st->element_mode == IVAS_CPE_MDCT ) ) { /* switch IGF configuration */ - IGFDecSetMode( st->hIGFDec, total_brate, bwidth, st->element_mode, -1, -1, st->rf_flag ); + IGFDecSetMode_flt( st->hIGFDec, total_brate, bwidth, st->element_mode, -1, -1, st->rf_flag ); } if ( fscale != st->fscale || switchWB || bSwitchFromAmrwbIO || st->last_codec_mode == MODE1 || st->force_lpd_reset ) { - open_decoder_LPD( st, total_brate, last_total_brate, bwidth, MCT_flag, last_element_mode, 0 ); + open_decoder_LPD_flt( st, total_brate, last_total_brate, bwidth, MCT_flag, last_element_mode, 0 ); } else { @@ -132,7 +132,7 @@ void mode_switch_decoder_LPD( { st->narrowBand = 0; } - st->TcxBandwidth_float = getTcxBandwidth( bwidth ); + st->TcxBandwidth_float = getTcxBandwidth_flt( bwidth ); if ( st->hTcxCfg != NULL ) { @@ -142,14 +142,14 @@ void mode_switch_decoder_LPD( if ( st->hTcxCfg->fIsTNSAllowed && st->hIGFDec != NULL && st->hTcxCfg != NULL ) { - InitTnsConfigs( bwidth, st->hTcxCfg->tcx_coded_lines, st->hTcxCfg->tnsConfig, st->hIGFDec->infoIGFStopFreq, total_brate, st->element_mode, MCT_flag ); + InitTnsConfigs_flt( bwidth, st->hTcxCfg->tcx_coded_lines, st->hTcxCfg->tnsConfig, st->hIGFDec->infoIGFStopFreq, total_brate, st->element_mode, MCT_flag ); - SetAllowTnsOnWhite( st->hTcxCfg->tnsConfig, st->element_mode == IVAS_CPE_MDCT ); + SetAllowTnsOnWhite_flt( st->hTcxCfg->tnsConfig, st->element_mode == IVAS_CPE_MDCT ); } } frame_size = FrameSizeConfig[frame_size_index].frame_net_bits; - reconfig_decoder_LPD( st, frame_size, bwidth, total_brate, st->last_L_frame ); + reconfig_decoder_LPD_ivas( st, frame_size, bwidth, total_brate, st->last_L_frame ); if ( hTcxDec->envWeighted && !hTcxDec->enableTcxLpc ) { @@ -186,7 +186,7 @@ void mode_switch_decoder_LPD( { if ( st->tec_tfa == 0 && st->hTECDec != NULL ) { - set_zero( st->hTECDec->loBuffer, MAX_TEC_SMOOTHING_DEG ); + set_zero( st->hTECDec->loBuffer_flt, MAX_TEC_SMOOTHING_DEG ); } st->tec_tfa = 1; } diff --git a/lib_dec/core_dec_switch_fx.c b/lib_dec/core_dec_switch_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..eae80e023ce7fd55cc61e6a188246ef9af570e57 --- /dev/null +++ b/lib_dec/core_dec_switch_fx.c @@ -0,0 +1,253 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include +#include +#include "options.h" +#include "basop_util.h" +#include "prot_fx1.h" +#include "prot_fx2.h" +#include "rom_com.h" + + +void mode_switch_decoder_LPD( + Decoder_State *st, /* i/o: decoder state structure */ + Word16 bwidth, /* i : audio bandwidth */ + Word32 total_brate, /* i : total bitrate */ +#ifdef IVAS_CODE_SWITCHING + const int32_t last_total_brate, /* i : last frame total bitrate */ +#endif + Word16 frame_size_index /* i : index determining the frame size*/ +#ifdef IVAS_CODE_SWITCHING + ,const int16_t MCT_flag /* i : hMCT handle allocated (1) or not (0)*/ +#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT + ,const int16_t last_element_mode +#endif +#endif +) +{ + Word16 fscale, switchWB; + Word32 sr_core; + Word8 bSwitchFromAmrwbIO; + Word16 frame_size; + TD_BWE_DEC_HANDLE hBWE_TD; + TCX_DEC_HANDLE hTcxDec; + + hBWE_TD = st->hBWE_TD; + hTcxDec = st->hTcxDec; + + switchWB = 0; + move16(); + bSwitchFromAmrwbIO = 0; + move16(); + + if (EQ_16(st->last_core,AMR_WB_CORE)) + { + bSwitchFromAmrwbIO = 1; + move16(); + } + + sr_core = getCoreSamplerateMode2(st->element_mode, total_brate, bwidth, st->flag_ACELP16k, st->rf_flag, st->is_ism_format ); + + fscale = sr2fscale(sr_core); + move16(); + + /* set number of coded lines */ + st->hTcxCfg->tcx_coded_lines = getNumTcxCodedLines(bwidth); + test(); + test(); + IF (( (GE_16(bwidth, WB)) && (EQ_16(fscale,(FSCALE_DENOM*16000)/12800)) && (EQ_16(fscale,st->fscale)))) + { + test(); + test(); + test(); + if ( ((GT_32(total_brate, 32000)) && (st->tcxonly==0)) || ((LE_32(total_brate,32000)) && (st->tcxonly!=0))) + { + switchWB = 1; + move16(); + } + } + + test(); + if( GT_16(st->last_L_frame,L_FRAME16k) && LE_32(total_brate ,ACELP_32k)) + { + switchWB = 1; + move16(); + } + + st->igf = getIgfPresent(st->element_mode, total_brate, bwidth, st->rf_flag); + + IF(st->hIGFDec != NULL) + { + st->hIGFDec->infoIGFStopFreq = -1; + } + move16(); + test(); test(); + IF( st->igf && (st->idchan == 0 || EQ_16(st->element_mode, IVAS_CPE_MDCT) ) ) + { + /* switch IGF configuration */ + IGFDecSetMode( st->hIGFDec, total_brate, bwidth, st->element_mode, -1, -1, st->rf_flag); + } + + test(); + test(); + test(); + test(); + IF ( NE_16(fscale, st->fscale)||switchWB!=0||bSwitchFromAmrwbIO!=0||EQ_16(st->last_codec_mode,MODE1)||st->force_lpd_reset) + { +#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT + open_decoder_LPD(st, total_brate, last_total_brate, bwidth, MCT_flag, last_element_mode, 0); +#else +#ifdef IVAS_CODE + open_decoder_LPD(st, total_brate, last_total_brate, bwidth, is_mct, 0); +#else + open_decoder_LPD(st, total_brate, bwidth); +#endif +#endif + + } + ELSE + { + assert(fscale > (FSCALE_DENOM/2)); + + st->fscale_old = st->fscale; + move16(); + st->fscale = fscale; + move16(); + st->L_frame = extract_l(Mult_32_16(st->sr_core , 0x0290)); + IF(hTcxDec != NULL) + { + hTcxDec->L_frameTCX = extract_l(Mult_32_16(st->output_Fs, 0x0290)); + } + IF (st->hTcxCfg != NULL) + { + st->hTcxCfg->ctx_hm = getCtxHm(st->element_mode, total_brate, st->rf_flag); + st->hTcxCfg->resq = getResq(total_brate); + } + move16(); + + hTcxDec->tcx_lpc_shaped_ari = getTcxLpcShapedAri(total_brate, st->rf_flag, st->element_mode ); + + st->narrowBand = 0; + move16(); + if ( EQ_16(bwidth, NB)) + { + st->narrowBand = 1; + move16(); + } + st->TcxBandwidth = getTcxBandwidth(bwidth); + + IF (st->hTcxCfg != NULL) + { + st->hTcxCfg->pCurrentTnsConfig = NULL; + st->hTcxCfg->fIsTNSAllowed = getTnsAllowed(total_brate, st->igf, st->element_mode); + move16(); + + IF(st->hTcxCfg->fIsTNSAllowed != 0 && st->hIGFDec != NULL) + { + InitTnsConfigs(bwidth, st->hTcxCfg->tcx_coded_lines, st->hTcxCfg->tnsConfig, st->hIGFDec->infoIGFStopFreq, total_brate, st->element_mode, 0/* 0 should be replaced with MCT_flag*/); +#ifdef IVAS_CODE + SetAllowTnsOnWhite(st->hTcxCfg->tnsConfig, st->element_mode == IVAS_CPE_MDCT); +#endif + } + } + } + + frame_size = FrameSizeConfig[frame_size_index].frame_net_bits; + move16(); + + reconfig_decoder_LPD( st, frame_size, bwidth, total_brate, st->last_L_frame ); + + test(); + IF (hTcxDec->envWeighted != 0 && hTcxDec->enableTcxLpc == 0) + { + Copy(st->lspold_uw, st->lsp_old_fx, M); + Copy(st->lsfold_uw, st->lsf_old_fx, M); + hTcxDec->envWeighted = 0; + move16(); + } + + /* update PLC LSF memories */ + IF( st->tcxonly == 0 ) + { + lsp2lsf_fx( st->lsp_old_fx, st->lsfoldbfi1_fx, M, extract_l(st->sr_core) ); + } + ELSE + { + E_LPC_lsp_lsf_conversion( st->lsp_old_fx, st->lsfoldbfi1_fx, M ); + } + Copy(st->lsfoldbfi1_fx, st->lsfoldbfi0_fx,M); + Copy(st->lsfoldbfi1_fx, st->lsf_adaptive_mean_fx,M); + + IF( st->igf != 0 && hBWE_TD != NULL) + { + test();test();test();test();test(); + IF( (EQ_16(st->bwidth, WB)&&NE_16(st->last_extl,WB_TBE))|| + (EQ_16(st->bwidth, SWB) && NE_16(st->last_extl, SWB_TBE)) || + (EQ_16(st->bwidth, FB) && NE_16(st->last_extl,FB_TBE)) ) + { +#ifdef IVAS_CODE + TBEreset_dec_fx(st); +#else + TBEreset_dec_fx(st, st->bwidth); +#endif + } + ELSE + { + set16_fx(hBWE_TD->state_lpc_syn_fx, 0, LPC_SHB_ORDER ); + set16_fx(hBWE_TD->state_syn_shbexc_fx, 0, L_SHB_LAHEAD ); + set16_fx(hBWE_TD->mem_stp_swb_fx, 0, LPC_SHB_ORDER ); + set16_fx(hBWE_TD->mem_zero_swb_fx, 0, LPC_SHB_ORDER ); + hBWE_TD->gain_prec_swb_fx = 16384; + move16(); /*Q14 = 1 */ + } + } + + test(); + test(); + IF( (EQ_16(bwidth, SWB))&& (EQ_32(total_brate, ACELP_16k40) || EQ_32(total_brate, ACELP_24k40)) && EQ_16(st->element_mode, EVS_MONO) ) + { + IF (st->tec_tfa == 0) + { + set16_fx(st->hTECDec->loBuffer , 0, MAX_TEC_SMOOTHING_DEG); + } + st->tec_tfa = 1; + move16(); + } + ELSE + { + st->tec_tfa = 0; + move16(); + } + + st->tec_flag = 0; + move16(); + st->tfa_flag = 0; + move16(); + + /* needed in decoder to read the bitstream */ + st->enableGplc = 0; + move16(); + test(); + test(); + IF ( GE_16(bwidth, WB) && EQ_32(total_brate, 24400) && EQ_16(st->element_mode, EVS_MONO) ) + { + st->enableGplc = 1; + move16(); + } + move16(); + st->dec_glr = 0; + test(); + test(); + test(); + IF (( EQ_32(total_brate, 9600) || EQ_32(total_brate,16400) || EQ_32(total_brate, 24400)) && EQ_16(st->element_mode, EVS_MONO) ) + { + st->dec_glr = 1; + move16(); + } + move16(); + st->dec_glr_idx = 0; + +} + diff --git a/lib_dec/core_switching_dec.c b/lib_dec/core_switching_dec.c index 965c7519902d70dad7499127a9e0805e816af7a9..ac571678bd1a93d47f321336870ababb8bd59911 100644 --- a/lib_dec/core_switching_dec.c +++ b/lib_dec/core_switching_dec.c @@ -189,22 +189,22 @@ ivas_error core_switching_pre_dec( } /* CLDFB analysis of the synthesis at internal sampling rate */ - if ( ( error = cldfb_save_memory( st->cldfbAna ) ) != IVAS_ERR_OK ) + if ( ( error = cldfb_save_memory_ivas( st->cldfbAna ) ) != IVAS_ERR_OK ) { return error; } - cldfbAnalysis( st->hTcxDec->syn_Overl_float, realBuffer, imagBuffer, delay_comp, st->cldfbAna ); - cldfb_restore_memory( st->cldfbAna ); + cldfbAnalysis_ivas( st->hTcxDec->syn_Overl_float, realBuffer, imagBuffer, delay_comp, st->cldfbAna ); + cldfb_restore_memory_ivas( st->cldfbAna ); /* CLDFB synthesis of the combined signal */ - if ( ( error = cldfb_save_memory( st->cldfbSyn ) ) != IVAS_ERR_OK ) + if ( ( error = cldfb_save_memory_ivas( st->cldfbSyn ) ) != IVAS_ERR_OK ) { return error; } - cldfbSynthesis( realBuffer, imagBuffer, st->hHQ_core->fer_samples, delay_comp, st->cldfbSyn ); - cldfb_restore_memory( st->cldfbSyn ); + cldfbSynthesis_ivas( realBuffer, imagBuffer, st->hHQ_core->fer_samples, delay_comp, st->cldfbSyn ); + cldfb_restore_memory_ivas( st->cldfbSyn ); } if ( !st->last_con_tcx && st->last_core_bfi == ACELP_CORE && st->core == HQ_CORE ) @@ -289,7 +289,7 @@ ivas_error core_switching_pre_dec( { /* Last frame was Stereo CNG and the synthesis memory is outdated -- reset */ set_f( st->hTcxDec->old_syn_Overl_float, 0.0f, L_FRAME32k / 2 ); - set_f( st->hFdCngDec->hFdCngCom->olapBufferAna, 0.0f, FFTLEN ); + set_f( st->hFdCngDec->hFdCngCom->olapBufferAna_flt, 0.0f, FFTLEN ); } set_f( st->agc_mem2, 0, 2 ); @@ -328,9 +328,9 @@ ivas_error core_switching_pre_dec( st->Last_GSC_noisy_speech_flag = 0; /* reset CLDFB memories */ - cldfb_reset_memory( st->cldfbAna ); - cldfb_reset_memory( st->cldfbBPF ); - cldfb_reset_memory( st->cldfbSyn ); + cldfb_reset_memory_ivas( st->cldfbAna ); + cldfb_reset_memory_ivas( st->cldfbBPF ); + cldfb_reset_memory_ivas( st->cldfbSyn ); /* reset TBE memories */ if ( !st->last_con_tcx && !( ( st->last_core == HQ_CORE ) && st->element_mode > EVS_MONO ) ) @@ -496,11 +496,11 @@ ivas_error core_switching_pre_dec( /* || st->last_core == AMR_WB_CORE || st->last_codec_mode == MODE2)){*/ if ( st->core != AMR_WB_CORE ) { - configureFdCngDec( st->hFdCngDec, st->bwidth, st->rf_flag == 1 && st->total_brate == ACELP_13k20 ? ACELP_9k60 : st->total_brate, st->L_frame, st->last_L_frame, st->element_mode ); + configureFdCngDec_flt( st->hFdCngDec, st->bwidth, st->rf_flag == 1 && st->total_brate == ACELP_13k20 ? ACELP_9k60 : st->total_brate, st->L_frame, st->last_L_frame, st->element_mode ); } else { - configureFdCngDec( st->hFdCngDec, WB, ACELP_8k00, st->L_frame, st->last_L_frame, st->element_mode ); + configureFdCngDec_flt( st->hFdCngDec, WB, ACELP_8k00, st->L_frame, st->last_L_frame, st->element_mode ); if ( st->VAD ) { @@ -511,27 +511,27 @@ ivas_error core_switching_pre_dec( { if ( st->element_mode == IVAS_CPE_DFT || st->element_mode == IVAS_CPE_TD ) { - lerp_flt( st->hFdCngDec->hFdCngCom->olapBufferAna + st->last_L_frame, st->hFdCngDec->hFdCngCom->olapBufferAna + st->L_frame, st->L_frame, st->last_L_frame ); + lerp_flt( st->hFdCngDec->hFdCngCom->olapBufferAna_flt + st->last_L_frame, st->hFdCngDec->hFdCngCom->olapBufferAna_flt + st->L_frame, st->L_frame, st->last_L_frame ); } - lerp_flt( st->hFdCngDec->hFdCngCom->olapBufferSynth2, st->hFdCngDec->hFdCngCom->olapBufferSynth2, st->L_frame * 2, st->last_L_frame * 2 ); + lerp_flt( st->hFdCngDec->hFdCngCom->olapBufferSynth2_flt, st->hFdCngDec->hFdCngCom->olapBufferSynth2_flt, st->L_frame * 2, st->last_L_frame * 2 ); if ( st->total_brate <= SID_2k40 && st->last_total_brate <= SID_2k40 ) { - lerp_flt( st->hFdCngDec->hFdCngCom->olapBufferSynth, st->hFdCngDec->hFdCngCom->olapBufferSynth, st->L_frame * 2, st->last_L_frame * 2 ); + lerp_flt( st->hFdCngDec->hFdCngCom->olapBufferSynth_flt, st->hFdCngDec->hFdCngCom->olapBufferSynth_flt, st->L_frame * 2, st->last_L_frame * 2 ); if ( st->L_frame == L_FRAME ) { for ( i = 0; i < st->L_frame * 2; i++ ) { - st->hFdCngDec->hFdCngCom->olapBufferSynth[i] = st->hFdCngDec->hFdCngCom->olapBufferSynth[i] * 0.6250f; + st->hFdCngDec->hFdCngCom->olapBufferSynth_flt[i] = st->hFdCngDec->hFdCngCom->olapBufferSynth_flt[i] * 0.6250f; } } else { for ( i = 0; i < st->L_frame * 2; i++ ) { - st->hFdCngDec->hFdCngCom->olapBufferSynth[i] = st->hFdCngDec->hFdCngCom->olapBufferSynth[i] * 1.6f; + st->hFdCngDec->hFdCngCom->olapBufferSynth_flt[i] = st->hFdCngDec->hFdCngCom->olapBufferSynth_flt[i] * 1.6f; } } } @@ -686,14 +686,14 @@ ivas_error core_switching_post_dec( { if ( st->cldfbAna->no_channels * st->cldfbAna->no_col != st->L_frame ) { - configureCldfb( st->cldfbAna, st->L_frame * FRAMES_PER_SEC ); - configureCldfb( st->cldfbBPF, min( 16000, st->L_frame * FRAMES_PER_SEC ) ); + configureCldfb_ivas( st->cldfbAna, st->L_frame * FRAMES_PER_SEC ); + configureCldfb_ivas( st->cldfbBPF, min( 16000, st->L_frame * FRAMES_PER_SEC ) ); } - cldfb_reset_memory( st->cldfbAna ); - cldfb_reset_memory( st->cldfbBPF ); + cldfb_reset_memory_ivas( st->cldfbAna ); + cldfb_reset_memory_ivas( st->cldfbBPF ); } - cldfb_reset_memory( st->cldfbSyn ); + cldfb_reset_memory_ivas( st->cldfbSyn ); /* Update memories for CLDFB ana for eventual next ACELP frame */ if ( st->cldfbAna != NULL ) @@ -714,17 +714,17 @@ ivas_error core_switching_post_dec( { if ( st->cldfbAna->no_channels * st->cldfbAna->no_col != st->L_frame ) { - configureCldfb( st->cldfbAna, st->L_frame * FRAMES_PER_SEC ); - configureCldfb( st->cldfbBPF, min( 16000, st->L_frame * FRAMES_PER_SEC ) ); + configureCldfb_ivas( st->cldfbAna, st->L_frame * FRAMES_PER_SEC ); + configureCldfb_ivas( st->cldfbBPF, min( 16000, st->L_frame * FRAMES_PER_SEC ) ); } - cldfb_reset_memory( st->cldfbAna ); - cldfb_reset_memory( st->cldfbBPF ); + cldfb_reset_memory_ivas( st->cldfbAna ); + cldfb_reset_memory_ivas( st->cldfbBPF ); } if ( st->cldfbSyn != NULL ) { - cldfb_reset_memory( st->cldfbSyn ); + cldfb_reset_memory_ivas( st->cldfbSyn ); } /* Update memories for CLDFB ana for eventual next ACELP frame */ @@ -1196,11 +1196,11 @@ static void core_switch_lb_upsamp( /* check if the CLDFB works on the right sample rate */ if ( ( st->cldfbAna->no_channels * st->cldfbAna->no_col ) != st->L_frame ) { - resampleCldfb( st->cldfbAna, st->L_frame * FRAMES_PER_SEC ); + resampleCldfb_ivas( st->cldfbAna, st->L_frame * FRAMES_PER_SEC ); if ( st->cldfbBPF != NULL && st->L_frame <= L_FRAME16k ) { - resampleCldfb( st->cldfbBPF, st->L_frame * FRAMES_PER_SEC ); + resampleCldfb_ivas( st->cldfbBPF, st->L_frame * FRAMES_PER_SEC ); } if ( st->ini_frame > 0 ) @@ -1210,7 +1210,7 @@ static void core_switch_lb_upsamp( } /* analysis of the synthesis at internal sampling rate */ - cldfbAnalysis( output, realBuffer, imagBuffer, CLDFB_OVRLP_MIN_SLOTS * st->cldfbAna->no_channels, st->cldfbAna ); + cldfbAnalysis_ivas( output, realBuffer, imagBuffer, CLDFB_OVRLP_MIN_SLOTS * st->cldfbAna->no_channels, st->cldfbAna ); /* analysis and add the BPF error signal */ if ( st->p_bpf_noise_buf_float) @@ -1231,7 +1231,7 @@ static void core_switch_lb_upsamp( } /* synthesis of the combined signal */ - cldfbSynthesis( realBuffer, imagBuffer, output, CLDFB_OVRLP_MIN_SLOTS * st->cldfbSyn->no_channels, st->cldfbSyn ); + cldfbSynthesis_ivas( realBuffer, imagBuffer, output, CLDFB_OVRLP_MIN_SLOTS * st->cldfbSyn->no_channels, st->cldfbSyn ); /* save synthesis - needed in case of core switching */ if ( st->hTcxDec != NULL ) diff --git a/lib_dec/core_switching_dec_fx.c b/lib_dec/core_switching_dec_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..6a22da6634d2f0915136c134f8583b2075b146eb --- /dev/null +++ b/lib_dec/core_switching_dec_fx.c @@ -0,0 +1,1568 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include +#include "options.h" /* Compilation switches */ +#include "cnst.h" /* Common constants */ +#include "rom_com.h" /* Static table prototypes */ +#include "prot_fx1.h" /* Function prototypes */ +#include "prot_fx2.h" /* Function prototypes */ +#include "basop_util.h" /* Function prototypes */ + + +/*---------------------------------------------------------------------* + * bandwidth_switching_detect_fx() + * + * + *---------------------------------------------------------------------*/ +#ifdef IVAS_CODE_SWITCHING +static void core_switch_lb_upsamp(Decoder_State* st, float* output); +static void smoothTransitionDtxToTcx(float synth[], const int16_t output_frame, const int16_t delay_comp); +#endif +void bandwidth_switching_detect_fx( + Decoder_State *st_fx /* i/o: encoder state structure */ +) +{ + IF ((EQ_16(st_fx->element_mode, IVAS_CPE_TD) && EQ_16(st_fx->idchan, 1) ) || EQ_16(st_fx->element_mode, IVAS_CPE_MDCT)) + { + /* there is no BWE in TD stereo secondary channel and in MDCT stereo, IGF is part of the core decoding -> no BW switching -> reset BWS counters */ + st_fx->prev_bws_cnt_fx = 0; + st_fx->bws_cnt_fx = 0; + st_fx->bws_cnt1_fx = 0; + move16(); move16(); move16(); + + return; + } + /* update band-width switching counter */ + test(); + test(); + test(); + IF( GE_16(st_fx->bws_cnt1_fx, N_NS2W_FRAMES)) + { + st_fx->bws_cnt1_fx = 0; + move16(); + } + ELSE IF( GT_32(st_fx->total_brate, ACELP_9k60)&<_32(st_fx->last_core_brate,ACELP_9k60) + && EQ_16(st_fx->bwidth, SWB) && EQ_16(st_fx->last_bwidth, WB) ) + { + st_fx->bws_cnt1_fx = add(st_fx->bws_cnt1_fx,1); + move16(); + } + ELSE IF( st_fx->bws_cnt1_fx > 0 ) + { + IF( LT_16(st_fx->bwidth, st_fx->last_bwidth)) + { + st_fx->bws_cnt_fx = sub( shl(sub(N_NS2W_FRAMES, st_fx->bws_cnt1_fx), 1), 1 ); + move16(); + } + ELSE + { + st_fx->bws_cnt_fx = 0; + move16(); + } + + IF( LT_16(st_fx->bwidth, st_fx->last_bwidth)) + { + st_fx->bws_cnt1_fx = 0; + move16(); + } + ELSE + { + IF(EQ_16(st_fx->bwidth, SWB)) + { + st_fx->bws_cnt1_fx = add(st_fx->bws_cnt1_fx,1); + move16(); + } + ELSE + { + st_fx->bws_cnt1_fx = 0; + move16(); + } + } + } + + /* update band-width switching counter */ + test(); + test(); + test(); + IF( GE_16(st_fx->bws_cnt_fx, N_WS2N_FRAMES)) + { + st_fx->bws_cnt_fx = 0; + move16(); + } + ELSE IF( LT_32(st_fx->total_brate, ACELP_9k60)&>_32(st_fx->last_core_brate,ACELP_9k60) + && LT_16(st_fx->bwidth, st_fx->last_bwidth) && EQ_16(st_fx->bwidth, WB) ) + { + st_fx->bws_cnt_fx = add(st_fx->bws_cnt_fx,1); + move16(); + } + ELSE IF( st_fx->bws_cnt_fx > 0 ) + { + IF( GT_16(st_fx->bwidth, st_fx->last_bwidth)) + { + st_fx->bws_cnt1_fx = shr(sub(N_WS2N_FRAMES, st_fx->bws_cnt_fx), 1); + move16(); + } + ELSE + { + st_fx->bws_cnt1_fx = 0; + move16(); + } + + IF( GT_16(st_fx->bwidth, st_fx->last_bwidth)) + { + st_fx->bws_cnt_fx = 0; + move16(); + } + ELSE + { + IF( EQ_16(st_fx->bwidth, WB)) + { + st_fx->bws_cnt_fx = add(st_fx->bws_cnt_fx,1); + move16(); + } + ELSE + { + st_fx->bws_cnt_fx = 0; + move16(); + } + } + } + + return; +} + +/*---------------------------------------------------------------------* + * Calc_freq_ener() + * + * + *---------------------------------------------------------------------*/ + +static Word32 Calc_freq_ener(Word32 L_tmp, const Word16 Q_syn2) +{ + Word32 enerLL_fx; + Word16 exp, tmp; + IF(L_tmp == 0) + { + enerLL_fx = L_deposit_l(0); + } + ELSE + { + exp = norm_l(L_tmp); + tmp = extract_h(L_shl(L_tmp, exp)); + exp = sub(exp, sub(30,shl(Q_syn2,1))); + + tmp = div_s(16384, tmp); + L_tmp = L_deposit_h(tmp); + L_tmp = Isqrt_lc(L_tmp, &exp); /*31-exp*/ + + enerLL_fx = L_shr(L_tmp, sub(sub(31, exp), Q_syn2)); /*st_fx->Q_syn2-1*/ + } + return enerLL_fx; +} + +/*---------------------------------------------------------------------* + * bw_switching_pre_proc_fx() + * + * + *---------------------------------------------------------------------*/ + +void bw_switching_pre_proc_fx( + const Word16 *old_syn_12k8_16k_fx, /* i : ACELP core synthesis at 12.8kHz or 16kHz */ + Decoder_State *st_fx /* i/o: decoder state structure */ +) +{ + Word16 i; + Word16 syn_dct_fx[L_FRAME]; + Word32 L_tmp; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif +#ifdef IVAS_CODE_SWITCHING + IF (GT_16(st_fx->element_mode, EVS_MONO)) + { + test(); test(); test(); test(); test(); test(); test(); test(); test(); test(); + IF (EQ_16(st_fx->core, ACELP_CORE) && !(EQ_16(st_fx->bfi, 1) && EQ_16(st_fx->con_tcx, 1)) && + st_fx->hBWE_FD != NULL && !(LE_16(st_fx->core_brate, SID_2k40) && EQ_16(st_fx->element_mode, IVAS_CPE_DFT) && EQ_16(nchan_out, 2)) && + !(EQ_16(st_fx->element_mode, IVAS_CPE_MDCT) && EQ_16(nchan_out, 1) && EQ_16(st_fx->idchan, 1) && LE_16(last_element_brate, IVAS_SID_4k4))) + { + /* Calculate tilt of the ACELP core synthesis - needed in SWB BWE decoding */ + calc_tilt_bwe(old_syn_12k8_16k, &st->tilt_wb, st->L_frame); + } + + return; + } +#endif + test(); test(); + IF( EQ_16(st_fx->core, ACELP_CORE) && !(EQ_16(st_fx->bfi, 1) && EQ_16(st_fx->con_tcx, 1))) + { + /*----------------------------------------------------------------------* + * Calculate tilt of the ACELP core synthesis + *----------------------------------------------------------------------*/ + +#ifdef BASOP_NOGLOB + st_fx->tilt_wb_fx = round_fx_o(L_shl_o(calc_tilt_bwe_fx(old_syn_12k8_16k_fx, -1, st_fx->L_frame), 3, &Overflow), &Overflow); +#else + st_fx->tilt_wb_fx = round_fx(L_shl(calc_tilt_bwe_fx(old_syn_12k8_16k_fx, -1, st_fx->L_frame), 3)); +#endif + /*-------------------------------------------------------------------------------* + * Calculate frequency energy of 0~3.2kHz and 3.2~6.4kHz the ACELP core synthesis + *-------------------------------------------------------------------------------*/ + + edct_16fx(old_syn_12k8_16k_fx, syn_dct_fx, L_FRAME, 6, st_fx->element_mode); + + L_tmp = L_deposit_l(0); + FOR ( i=0; i < L_FRAME/2; i++ ) + { +#ifdef BASOP_NOGLOB + L_tmp = L_mac0_o(L_tmp, syn_dct_fx[i], syn_dct_fx[i], &Overflow); +#else + L_tmp = L_mac0(L_tmp, syn_dct_fx[i], syn_dct_fx[i]); +#endif + } + L_tmp = L_shr(L_tmp, 7); /*2*(st_fx->Q_syn2-1)*/ + st_fx->enerLL_fx = Calc_freq_ener(L_tmp, shl(st_fx->Q_syn2,1)); + L_tmp = L_deposit_l(0); + FOR (; iQ_syn2-1)*/ + st_fx->enerLH_fx = Calc_freq_ener(L_tmp, shl(st_fx->Q_syn2,1)); + } + ELSE + { + IF( st_fx->hHQ_core->old_is_transient_fx[0] ) + { + L_tmp = L_deposit_l(0); + FOR ( i=0; i<32; i++ ) + { +#ifdef BASOP_NOGLOB + L_tmp = L_mac0_o(L_tmp, st_fx->t_audio_q_fx[i], st_fx->t_audio_q_fx[i], &Overflow); +#else + L_tmp = L_mac0(L_tmp, st_fx->t_audio_q_fx[i], st_fx->t_audio_q_fx[i]); +#endif + } + L_tmp = L_shr(L_tmp, 5); /*st_fx->Q_syn2-1*/ + st_fx->enerLL_fx = Calc_freq_ener(L_tmp, shl(st_fx->Q_syn2,1)); + L_tmp = L_deposit_l(0); + FOR (; i<64; i++ ) + { +#ifdef BASOP_NOGLOB + L_tmp = L_mac0_o(L_tmp, st_fx->t_audio_q_fx[i], st_fx->t_audio_q_fx[i], &Overflow); +#else + L_tmp = L_mac0(L_tmp, st_fx->t_audio_q_fx[i], st_fx->t_audio_q_fx[i]); +#endif + } + L_tmp = L_shr(L_tmp, 5); /*st_fx->Q_syn2-1*/ + st_fx->enerLH_fx = Calc_freq_ener(L_tmp, shl(st_fx->Q_syn2,1)); + } + ELSE + { + L_tmp = L_deposit_l(0); + FOR ( i=0; i < L_FRAME/2; i++ ) + { +#ifdef BASOP_NOGLOB + L_tmp = L_mac0_o(L_tmp, st_fx->t_audio_q_fx[i], st_fx->t_audio_q_fx[i], &Overflow); +#else + L_tmp = L_mac0(L_tmp, st_fx->t_audio_q_fx[i], st_fx->t_audio_q_fx[i]); +#endif + } + L_tmp = L_shr(L_tmp, 7); /*st_fx->Q_syn2-1*/ + st_fx->enerLL_fx = Calc_freq_ener(L_tmp, shl(st_fx->Q_syn2,1)); + L_tmp = L_deposit_l(0); + FOR (; it_audio_q_fx[i], st_fx->t_audio_q_fx[i], &Overflow); +#else + L_tmp = L_mac0(L_tmp, st_fx->t_audio_q_fx[i], st_fx->t_audio_q_fx[i]); +#endif + } + L_tmp = L_shr(L_tmp, 7); /*st_fx->Q_syn2-1*/ + st_fx->enerLH_fx = Calc_freq_ener(L_tmp, shl(st_fx->Q_syn2,1)); + + } + } + + + test(); + test(); + test(); + test(); + test(); + IF( st_fx->last_bwidth == 0 && LE_16(st_fx->extl, SWB_CNG)) + { + st_fx->prev_ener_shb_fx = 0; + move16(); + set16_fx(st_fx->prev_SWB_fenv_fx, 0, SWB_FENV); + } + ELSE if(((EQ_16(st_fx->core, ACELP_CORE) && ( EQ_16(st_fx->last_core,HQ_CORE) || EQ_16(st_fx->last_core, TCX_10_CORE) || EQ_16(st_fx->last_core, TCX_20_CORE)))||(EQ_16(st_fx->core,st_fx->last_core)&&NE_16(st_fx->extl,st_fx->last_extl)))&&GE_16(st_fx->last_bwidth,SWB)) + { + st_fx->attenu_fx = 3277; + move16(); + } + + test(); + test(); + test(); + test(); + IF(EQ_16(st_fx->last_core, HQ_CORE) + || ( EQ_16(st_fx->last_core, ACELP_CORE) + && !(EQ_16(st_fx->last_extl, WB_TBE) || EQ_16(st_fx->last_extl, SWB_TBE) || EQ_16(st_fx->last_extl, FB_TBE) ) && GT_32(st_fx->core_brate, ACELP_8k00) )) + { + st_fx->prev_fractive_fx = 0; + move16(); + } + return; +} + +#ifdef IVAS_CODE_SWITCHING + + +/*---------------------------------------------------------------------* + * core_switch_lb_upsamp() + * + * Resample HQ/TCX-LB to the output sampling rate (8/16/32/48 kHz) + *---------------------------------------------------------------------*/ + +static void core_switch_lb_upsamp( + Decoder_State* st, /* i/o: Decoder state */ + float* output /* i/o: LB synth/upsampled LB synth */ +) +{ + int16_t i; + float* realBuffer[CLDFB_OVRLP_MIN_SLOTS], * imagBuffer[CLDFB_OVRLP_MIN_SLOTS]; + float realBufferTmp[CLDFB_OVRLP_MIN_SLOTS][CLDFB_NO_CHANNELS_MAX]; + float imagBufferTmp[CLDFB_OVRLP_MIN_SLOTS][CLDFB_NO_CHANNELS_MAX]; + + /* open CLDFB buffer up to CLDFB_NO_CHANNELS_MAX bands for 48kHz */ + for (i = 0; i < CLDFB_OVRLP_MIN_SLOTS; i++) + { + set_f(realBufferTmp[i], 0, CLDFB_NO_CHANNELS_MAX); + set_f(imagBufferTmp[i], 0, CLDFB_NO_CHANNELS_MAX); + realBuffer[i] = realBufferTmp[i]; + imagBuffer[i] = imagBufferTmp[i]; + } + + /* check if the CLDFB works on the right sample rate */ + if ((st->cldfbAna->no_channels * st->cldfbAna->no_col) != st->L_frame) + { + resampleCldfb(st->cldfbAna, st->L_frame * FRAMES_PER_SEC); + + if (st->cldfbBPF != NULL && st->L_frame <= L_FRAME16k) + { + resampleCldfb(st->cldfbBPF, st->L_frame * FRAMES_PER_SEC); + } + + if (st->ini_frame > 0) + { + st->cldfbSyn->bandsToZero = st->cldfbSyn->no_channels - st->cldfbAna->no_channels; + } + } + + /* analysis of the synthesis at internal sampling rate */ + cldfbAnalysis(output, realBuffer, imagBuffer, CLDFB_OVRLP_MIN_SLOTS * st->cldfbAna->no_channels, st->cldfbAna); + + /* analysis and add the BPF error signal */ + if (st->p_bpf_noise_buf) + { + addBassPostFilter(st->p_bpf_noise_buf, st->bpf_off ? 0 : CLDFB_OVRLP_MIN_SLOTS * st->cldfbBPF->no_channels, realBuffer, imagBuffer, st->cldfbBPF); + } + + /* set output mask for upsampling */ + if (st->bwidth == NB) + { + /* set NB mask for upsampling */ + st->cldfbSyn->bandsToZero = st->cldfbSyn->no_channels - 10; + } + else if (st->cldfbSyn->bandsToZero != st->cldfbSyn->no_channels - st->cldfbAna->no_channels) + { + /* in case of BW switching, re-init to default */ + st->cldfbSyn->bandsToZero = st->cldfbSyn->no_channels - st->cldfbAna->no_channels; + } + + /* synthesis of the combined signal */ + cldfbSynthesis(realBuffer, imagBuffer, output, CLDFB_OVRLP_MIN_SLOTS * st->cldfbSyn->no_channels, st->cldfbSyn); + + /* save synthesis - needed in case of core switching */ + if (st->hTcxDec != NULL) + { + mvr2r(output, st->previoussynth, st->hTcxDec->L_frameTCX); + } + + return; +} + +/*---------------------------------------------------------------------* + * smoothTransitionMdctStereoDtx() + * + * apply smoothing to the transition part for MDCT-Stereo DTX + *---------------------------------------------------------------------*/ + +#define TRANSITION_SMOOTHING_LEN_16k 15 +#define TRANSITION_SMOOTHING_LEN_32k 31 +#define TRANSITION_SMOOTHING_LEN_48k 47 + +static void smoothTransitionMdctStereoDtx( + float synth[], /* i/o: synthesis */ + const int16_t output_frame, /* i : output frame length */ + const int16_t delay_comp /* i : delay compensation in samples */ +) +{ + int16_t i, filter_len; + float w, mem, step, fade_in; + float smoothing_input_buffer[2 * NS2SA(48000, DELAY_CLDFB_NS) + TRANSITION_SMOOTHING_LEN_48k]; + float smoothing_out_buffer[2 * NS2SA(48000, DELAY_CLDFB_NS) + TRANSITION_SMOOTHING_LEN_48k]; + + filter_len = TRANSITION_SMOOTHING_LEN_16k; + if (output_frame == L_FRAME32k) + { + filter_len = TRANSITION_SMOOTHING_LEN_32k; + } + else if (output_frame == L_FRAME48k) + { + filter_len = TRANSITION_SMOOTHING_LEN_48k; + } + + /* prepare buffer */ + for (i = 0; i < filter_len / 2; i++) + { + smoothing_input_buffer[i] = synth[0]; + } + mvr2r(synth, smoothing_input_buffer + filter_len / 2, 2 * delay_comp + filter_len / 2); + + /* apply Mean filter */ + w = 1.f / filter_len; + mem = sum_f(smoothing_input_buffer, filter_len); + for (i = 0; i < 2 * delay_comp; i++) + { + smoothing_out_buffer[i] = w * mem; + mem = mem - smoothing_input_buffer[i] + smoothing_input_buffer[i + filter_len]; + } + + /* apply fades around transition */ + step = 1.f / delay_comp; + fade_in = 0.f; + for (i = 0; i < delay_comp; i++) + { + synth[i] = smoothing_out_buffer[i] * fade_in + synth[i] * (1 - fade_in); + fade_in += step; + } + + fade_in = 0.f; + for (; i < 2 * delay_comp; i++) + { + synth[i] = synth[i] * fade_in + smoothing_out_buffer[i] * (1 - fade_in); + fade_in += step; + } + + return; +} +#endif +/*---------------------------------------------------------------------* +* core_switching_pre_dec_fx() +* +* Preprocessing/preparation for ACELP/HQ core switching +*---------------------------------------------------------------------*/ +ivas_error core_switching_pre_dec_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + const Word16 output_frame /* i : frame length */ +) +{ + Word16 oldLenClasBuff, newLenClasBuff, i; + BPF_DEC_HANDLE hBPF; + TD_BWE_DEC_HANDLE hBWE_TD; + FD_BWE_DEC_HANDLE hBWE_FD; + HQ_DEC_HANDLE hHQ_core; + TCX_DEC_HANDLE hTcxDec; + ivas_error error; + + hBWE_TD = st_fx->hBWE_TD; + hBWE_FD = st_fx->hBWE_FD; + hHQ_core = st_fx->hHQ_core; + hBPF = st_fx->hBPF; + hTcxDec = st_fx->hTcxDec; + + error = IVAS_ERR_OK; + /* Codec switching */ + IF( EQ_16(st_fx->last_codec_mode,MODE2) || ((EQ_16(st_fx->last_core, TCX_20_CORE) || EQ_16(st_fx->last_core, TCX_10_CORE)) && GT_16(st_fx->element_mode, EVS_MONO))) + { + st_fx->mem_deemph_fx = st_fx->syn[M]; + move16(); + set16_fx( st_fx->agc_mem_fx, 0, 2 ); + Scale_sig(&(st_fx->mem_deemph_fx), 1, st_fx->Q_syn); /* Brings mem_deemph to Qsyn */ + + Copy_Scale_sig(st_fx->mem_syn2_fx, st_fx->mem_syn1_fx, M, sub(-1,st_fx->Q_syn)); /*Q-1*/ + + st_fx->bpf_off = 1; + move16(); + Scale_sig(st_fx->hPFstat->mem_pf_in, L_SUBFR, st_fx->Q_syn); /* Post_filter mem */ + Scale_sig(st_fx->hPFstat->mem_res2, DECMEM_RES2, st_fx->Q_syn); /* NB post_filter mem */ + Scale_sig(st_fx->hPFstat->mem_stp, L_SUBFR, st_fx->Q_syn); /* Post_filter mem */ + IF (hBPF != NULL) + { + set16_fx(hBPF->pst_old_syn_fx, 0, NBPSF_PIT_MAX); /* BPF mem*/ + hBPF->pst_lp_ener_fx = round_fx(L_shl(Mpy_32_16_1(st_fx->lp_error_ener, 0x6054), 2 + 8)); /* convert from 15Q16, log2 -> 7Q8 10*log10 */ + hBPF->pst_mem_deemp_err_fx = 0; + } + move16(); + st_fx->psf_lp_noise_fx = round_fx(L_shl(st_fx->lp_noise,1)); + + /* reset old HB synthesis buffer */ + IF( EQ_16(st_fx->last_L_frame,L_FRAME)) + { + st_fx->old_bwe_delay_fx = NS2SA_fx2( st_fx->output_Fs, MAX_DELAY_TBE_NS - DELAY_SWB_TBE_12k8_NS ); + } + ELSE + { + st_fx->old_bwe_delay_fx = NS2SA_fx2( st_fx->output_Fs, MAX_DELAY_TBE_NS - DELAY_SWB_TBE_16k_NS ); + } + set16_fx( st_fx->hb_prev_synth_buffer_fx, 0, NS2SA(48000, DELAY_BWE_TOTAL_NS) ); + + /* reset upd_cnt */ + st_fx->upd_cnt = MAX_UPD_CNT; + move16(); + st_fx->igf = 0; + move16(); + + + IF(hBWE_TD != NULL && NE_16(st_fx->last_core,ACELP_CORE)) + { + hBWE_TD->prev_hb_synth_fx_exp = 31; + move16(); + /* reset BWE memories */ + set16_fx(hBWE_TD->old_bwe_exc_fx, 0, PIT16k_MAX*2 ); + hBWE_TD->bwe_non_lin_prev_scale_fx = L_deposit_l(0); + } + + IF( GE_32(st_fx->output_Fs,16000) && st_fx->hBWE_zero != NULL) + { + hf_synth_reset_fx(st_fx->hBWE_zero); + } + IF (st_fx->hBWE_FD != NULL) + { + set16_fx(hBWE_FD->old_syn_12k8_16k_fx, 0, NS2SA(16000, DELAY_FD_BWE_ENC_NS)); + } + IF(st_fx->hHQ_core != NULL) + { + set32_fx(hHQ_core->prev_env_fx, 0, SFM_N_WB); + set32_fx(hHQ_core->prev_normq_fx, 0, SFM_N_WB); + + set32_fx(hHQ_core->last_ni_gain_fx, 0, BANDS_MAX); + set16_fx(hHQ_core->last_env_fx, 0, BANDS_MAX); + hHQ_core->last_max_pos_pulse_fx = 0; + move16(); + + IF(GT_32(st_fx->output_Fs, 16000)) + { + set32_fx(hHQ_core->prev_coeff_out_fx, 0, L_HQ_WB_BWE); + } + + /* pre-echo */ + hHQ_core->pastpre_fx = 0; + move16(); + } + /* reset the GSC pre echo energy threshold in case of switching */ + IF (st_fx->hGSCDec != NULL) + { + st_fx->hGSCDec->Last_frame_ener_fx = MAX_32; + } + move32(); + + test(); + IF( EQ_16(st_fx->last_core,TCX_20_CORE)||EQ_16(st_fx->last_core,TCX_10_CORE)) + { + IF (EQ_16(st_fx->element_mode, EVS_MONO)) + { + st_fx->last_core = HQ_CORE; + move16(); + Copy(hTcxDec->FBTCXdelayBuf, st_fx->prev_synth_buffer_fx, NS2SA(st_fx->output_Fs, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS)); + } + IF (hHQ_core != NULL) + { + set32_fx(hHQ_core->last_ni_gain_fx, 0, BANDS_MAX); + set16_fx(hHQ_core->last_env_fx, 0, BANDS_MAX); + hHQ_core->last_max_pos_pulse_fx = 0; + move16(); + + set16_fx(hHQ_core->prev_SWB_peak_pos_fx, 0, SPT_SHORTEN_SBNUM); + hHQ_core->prev_frm_hfe2_fx = 0; + move16(); + hHQ_core->prev_stab_hfe2_fx = 0; + move16(); + } + } + + IF(st_fx->prev_bfi!=0) + { + Word16 delay_comp; + + /*switch off Hq Voicing as it was not uodated in MODE2*/ + IF(hHQ_core != NULL) + { + hHQ_core->oldHqVoicing_fx = 0; + hHQ_core->HqVoicing_fx = 0; + move16();move16(); + } + + delay_comp = NS2SA_fx2(st_fx->output_Fs, DELAY_CLDFB_NS); + + IF( !st_fx->last_con_tcx && st_fx->last_core_bfi == ACELP_CORE && EQ_16(st_fx->core,HQ_CORE)) + { + + Word16 no_col; + Word32 *realBuffer[CLDFB_NO_COL_MAX_SWITCH], *imagBuffer[CLDFB_NO_COL_MAX_SWITCH]; + Word32 realBufferTmp[CLDFB_NO_COL_MAX_SWITCH][CLDFB_NO_CHANNELS_MAX], imagBufferTmp[CLDFB_NO_COL_MAX_SWITCH][CLDFB_NO_CHANNELS_MAX]; + CLDFB_SCALE_FACTOR scaleFactor; + Word32 workBuffer[128*3]; + + FOR( i=0; i< CLDFB_NO_COL_MAX_SWITCH; i++ ) + { + set32_fx(realBufferTmp[i], 0, CLDFB_NO_CHANNELS_MAX); + set32_fx(imagBufferTmp[i], 0, CLDFB_NO_CHANNELS_MAX); + realBuffer[i] = realBufferTmp[i]; + move32(); + imagBuffer[i] = imagBufferTmp[i]; + move32(); + } + + no_col = s_min(st_fx->cldfbAna_fx->no_col, idiv1616(sub(add(delay_comp, st_fx->cldfbAna_fx->no_channels),1) , st_fx->cldfbAna_fx->no_channels)); + + /* CLDFB analysis of the synthesis at internal sampling rate */ + IF ((error = cldfb_save_memory( st_fx->cldfbAna_fx )) != IVAS_ERR_OK) + { + return error; + } + cldfbAnalysisFiltering( st_fx->cldfbAna_fx, realBuffer, imagBuffer, &scaleFactor, hTcxDec->syn_Overl, 0, no_col, workBuffer); + cldfb_restore_memory( st_fx->cldfbAna_fx ); + + scaleFactor.hb_scale = scaleFactor.lb_scale; + move16(); + + /* CLDFB synthesis of the combined signal */ + IF ((error = cldfb_save_memory( st_fx->cldfbSyn_fx )) != IVAS_ERR_OK) + { + return error; + } + cldfbSynthesisFiltering(st_fx->cldfbSyn_fx, realBuffer, imagBuffer, &scaleFactor, hHQ_core->fer_samples_fx, 0, no_col, workBuffer); + cldfb_restore_memory( st_fx->cldfbSyn_fx ); + } + + IF( !st_fx->last_con_tcx && st_fx->last_core_bfi == ACELP_CORE && EQ_16(st_fx->core,HQ_CORE)) + { + lerp(hTcxDec->syn_Overl, hHQ_core->fer_samples_fx+delay_comp,shr(st_fx->output_frame_fx,1), shr(st_fx->last_L_frame,1)); + /*Set to zero the remaining part*/ + set16_fx(hHQ_core->fer_samples_fx+delay_comp+shr(st_fx->output_frame_fx,1), 0, shr(st_fx->output_frame_fx,1)-delay_comp); + } + } + + st_fx->use_acelp_preq = 0; + move16(); + st_fx->reset_mem_AR=0; + move16(); + + } + + /*FEC*/ + IF( LE_16(st_fx->L_frame,L_FRAME16k)) + { + test(); + IF( LE_16(st_fx->last_L_frame,L_FRAME16k)&&NE_16(st_fx->core,HQ_CORE)) + { + IF( NE_16(st_fx->L_frame,st_fx->last_L_frame)) + { + IF (GT_16(st_fx->L_frame,st_fx->last_L_frame)) + { + oldLenClasBuff = extract_l(L_shr(Mpy_32_16_1(L_mult0(st_fx->last_L_frame,getInvFrameLen(st_fx->L_frame)/*Q21*/)/*Q21*/,L_SYN_MEM_CLAS_ESTIM/*Q0*/)/*Q6*/,6)/*Q0*/); + newLenClasBuff = L_SYN_MEM_CLAS_ESTIM; + move16(); + } + ELSE + { + oldLenClasBuff = L_SYN_MEM_CLAS_ESTIM; + move16(); + newLenClasBuff = extract_l(L_shr(Mpy_32_16_1(L_mult0(st_fx->L_frame,getInvFrameLen(st_fx->last_L_frame)/*Q21*/)/*Q21*/,L_SYN_MEM_CLAS_ESTIM/*Q0*/)/*Q6*/,6)/*Q0*/); + } + lerp( &st_fx->mem_syn_clas_estim_fx[L_SYN_MEM_CLAS_ESTIM-oldLenClasBuff], &st_fx->mem_syn_clas_estim_fx[L_SYN_MEM_CLAS_ESTIM-newLenClasBuff], newLenClasBuff, oldLenClasBuff ); + } + } + ELSE + { + set16_fx( st_fx->mem_syn_clas_estim_fx, 0,L_SYN_MEM_CLAS_ESTIM ); + st_fx->classifier_Q_mem_syn = 0; + move16(); + } + } + + /* Here we only handle cases where last_ppp and last_nelp not updated when coming from CodecB or other cores + within ACELP_CORE if switching from another bitarate to vbr, last_ppp and last_nelp is always updated in the previous frame */ + test(); + test(); + IF( EQ_16(st_fx->core, ACELP_CORE)&&(NE_16(st_fx->last_core,ACELP_CORE)||EQ_16(st_fx->last_codec_mode,MODE2))) + { + st_fx->last_ppp_mode_dec_fx = 0; + move16(); + st_fx->last_nelp_mode_dec_fx =0; + move16(); + } + + test(); + test(); + test(); + IF( EQ_16(st_fx->core, ACELP_CORE)&&(NE_16(st_fx->last_core,ACELP_CORE)||EQ_16(st_fx->last_codec_mode,MODE2)||LE_32(st_fx->last_total_brate,PPP_NELP_2k80))) + { + st_fx->act_count_fx = 3; + move16(); + st_fx->uv_count_fx = 0; + move16(); + } + + test(); + test(); + IF( ((EQ_16(st_fx->core,ACELP_CORE)||EQ_16(st_fx->core,AMR_WB_CORE))&&EQ_16(st_fx->last_core,HQ_CORE) ) +//#ifdef IVAS_CODE_SWITCHING +// || ((EQ_16(st_fx->element_mode, IVAS_CPE_DFT) || EQ_16(st_fx->element_mode, IVAS_CPE_TD) || +// (EQ_16(st_fx->element_mode, IVAS_CPE_MDCT) && last_element_mode == IVAS_CPE_DFT)) && EQ_16(nchan_out,2) && +// NE_16(st_fx->core_brate, SID_2k40) && NE_16(st_fx->core_brate, FRAME_NO_DATA) && (EQ_16(last_core_brate_st0, FRAME_NO_DATA) || EQ_16(last_core_brate_st0, SID_2k40))) +//#endif + ) + { + test(); + IF (EQ_16(st_fx->element_mode, IVAS_CPE_DFT) || EQ_16(st_fx->element_mode, IVAS_CPE_TD)) + { + st_fx->hPFstat->reset = 1; + move16(); + } + + IF(EQ_16(st_fx->L_frame, L_FRAME16k)) + { + Copy( TRWB2_Ave_fx, st_fx->lsf_old_fx, M ); + Copy( TRWB2_Ave_fx, st_fx->lsfoldbfi1_fx, M ); + Copy( TRWB2_Ave_fx, st_fx->lsfoldbfi0_fx, M ); + Copy( TRWB2_Ave_fx, st_fx->lsf_adaptive_mean_fx, M ); + lsf2lsp_fx( st_fx->lsf_old_fx, st_fx->lsp_old_fx, M, INT_FS_16k ); + } + ELSE + { + Copy( TRWB_Ave_fx, st_fx->lsf_old_fx, M ); /* init of LSP */ + Copy( TRWB_Ave_fx, st_fx->lsfoldbfi1_fx, M ); + Copy( TRWB_Ave_fx, st_fx->lsfoldbfi0_fx, M ); + Copy( TRWB_Ave_fx, st_fx->lsf_adaptive_mean_fx, M ); + lsf2lsp_fx( st_fx->lsf_old_fx, st_fx->lsp_old_fx, M, INT_FS_FX ); + } + +#ifdef IVAS_CODE_SWITCHING + if ((st->element_mode == IVAS_CPE_DFT || st->element_mode == IVAS_CPE_TD) && nchan_out == 2 && st->core_brate > SID_2k40 && (last_core_brate_st0 == FRAME_NO_DATA || last_core_brate_st0 == SID_2k40) && st->hTcxDec != NULL) + { + /* Last frame was Stereo CNG and the synthesis memory is outdated -- reset */ + set_f(st->hTcxDec->old_syn_Overl, 0.0f, L_FRAME32k / 2); + set_f(st->hFdCngDec->hFdCngCom->olapBufferAna, 0.0f, FFTLEN); + } +#endif + set16_fx( st_fx->agc_mem_fx, 0, 2 ); + st_fx->mem_deemph_fx = 0; + move16(); + IF( !st_fx->last_con_tcx ) + { + set16_fx( st_fx->mem_syn2_fx, 0, M ); + } + set16_fx( st_fx->mem_syn1_fx, 0, M ); + IF(hBWE_TD != NULL) + { + hBWE_TD->bwe_non_lin_prev_scale_fx = 0; + move16(); + } + /* Reset ACELP parameters */ + set16_fx( st_fx->mem_MA_fx,0, M ); + IF( EQ_32(st_fx->sr_core, INT_FS_16k)) + { + Copy( GEWB2_Ave_fx, st_fx->mem_AR_fx, M ); + } + ELSE + { + Copy( GEWB_Ave_fx, st_fx->mem_AR_fx, M ); + } + st_fx->tilt_code_fx = 0; + move16(); + st_fx->gc_threshold_fx = 0; + move16(); + st_fx->dm_fx.prev_gain_code = L_deposit_l(0); + set16_fx(st_fx->dm_fx.prev_gain_pit, 0, 6); + st_fx->dm_fx.prev_state = 0; + move16(); + + st_fx->last_coder_type_fx = GENERIC; + move16(); + + frame_ener_fx( output_frame, UNVOICED_CLAS, st_fx->previoussynth_fx, -1, &st_fx->enr_old_fx, 1, 0, 0, 0 ); + st_fx->lp_gainp_fx = 0; + move16(); + + /* the sqrt below needs to be changed to use basop Sqrt16 */ + /*st_fx->lp_gainc_fx = (float)sqrt( st_fx->lp_ener_fx ); */ + IF( st_fx->lp_ener_fx != 0 ) + { + Word32 L_tmp; + Word16 tmp, exp; + exp = norm_l(st_fx->lp_ener_fx); /* In Q6 */ + tmp = extract_h(L_shl(st_fx->lp_ener_fx, exp)); + exp = sub(exp, 30-6); + + tmp = div_s(16384, tmp); + L_tmp = L_deposit_h(tmp); + L_tmp = Isqrt_lc(L_tmp, &exp); + + st_fx->lp_gainc_fx = round_fx(L_shl(L_tmp, sub(exp, 12))); /* In Q3 */ + } + + + st_fx->last_voice_factor_fx = 0; + move16(); + st_fx->Last_GSC_noisy_speech_flag_fx = 0; + move16(); + + /* reset CLDFB memories */ + cldfb_reset_memory( st_fx->cldfbAna_fx ); + cldfb_reset_memory( st_fx->cldfbBPF_fx ); + cldfb_reset_memory( st_fx->cldfbSyn_fx ); + + /* reset TBE memories */ + test(); + + IF (!st_fx->last_con_tcx && !((EQ_16(st_fx->last_core, HQ_CORE)) && GT_16(st_fx->element_mode, EVS_MONO))) + { + set16_fx(st_fx->old_exc_fx,0, L_EXC_MEM_DEC ); + } + ELSE IF (LT_16(st_fx->L_frame,L_FRAME16k)) + { + /* resample from 16kHz to 12.8kHZ */ + synth_mem_updt2( st_fx->L_frame, L_FRAME16k, st_fx->old_exc_fx, st_fx->mem_syn_r, st_fx->mem_syn2_fx, NULL, DEC ); + } + + IF (hBWE_TD != NULL) + { + set16_fx(hBWE_TD->old_bwe_exc_fx, 0, PIT16k_MAX * 2); + } + + IF( GE_32(st_fx->output_Fs, 16000L) && st_fx->hBWE_zero != NULL) + { + hf_synth_reset_fx(st_fx->hBWE_zero); + } + IF(hBWE_FD != NULL) + { + set16_fx(hBWE_FD->old_syn_12k8_16k_fx, 0, NS2SA(16000, DELAY_FD_BWE_ENC_NS)); + } + } +#ifdef IVAS_CODE_SWITCHING + if ((st->core == ACELP_CORE || st->core == AMR_WB_CORE) && (st->last_core == TCX_20_CORE || st->last_core == TCX_10_CORE)) + { + if (st->hBWE_TD != NULL) + { + st->hBWE_TD->bwe_non_lin_prev_scale = 0.0f; + set_f(st->hBWE_TD->old_bwe_exc, 0, PIT16k_MAX * 2); + } + + st->tilt_code = 0.0f; + st->gc_threshold = 0.0f; + set_f(st->dispMem, 0, 8); + + st->last_coder_type = GENERIC; + + fer_energy(output_frame, UNVOICED_CLAS, st->previoussynth, -1, &st->enr_old, 1); + st->lp_gainp = 0.0f; + st->lp_gainc = (float)sqrt(st->lp_ener); + + st->last_voice_factor = 0; + st->Last_GSC_noisy_speech_flag = 0; + + if (st->output_Fs >= 16000 && st->hBWE_zero != NULL) + { + hf_synth_reset(st->hBWE_zero); + } + + if (st->hBWE_FD != NULL) + { + set_f(st->hBWE_FD->old_syn_12k8_16k, 0, NS2SA(16000, DELAY_FD_BWE_ENC_NS)); + } + + if (nchan_out == 1 && st->element_mode == IVAS_CPE_DFT && st->element_brate <= IVAS_24k4 && last_element_brate > IVAS_24k4) + { + /* update cldbf state with previous frame TCX synthesis when going from a bitrate with residual coding to a bitrate without it */ + int16_t offset; + offset = st->cldfbAna->p_filter_length - st->cldfbAna->no_channels; + mvr2r(st->hTcxDec->old_synthFB + st->hTcxDec->old_synth_lenFB - offset, st->cldfbAna->cldfb_state, offset); + } + } +#endif + test(); test(); test(); test(); test(); + IF(hHQ_core!= NULL && EQ_16(st_fx->core,HQ_CORE) && (EQ_16(st_fx->last_core,ACELP_CORE) || EQ_16(st_fx->last_core,AMR_WB_CORE) || (NE_16(st_fx->element_mode, EVS_MONO) && NE_16(st_fx->last_core, HQ_CORE ) ) ) ) + { + set32_fx(hHQ_core->prev_env_fx, 0, SFM_N_WB ); + set32_fx(hHQ_core->prev_normq_fx, 0, SFM_N_WB ); + + set32_fx(hHQ_core->last_ni_gain_fx, 0, BANDS_MAX ); + set16_fx(hHQ_core->last_env_fx, 0, BANDS_MAX ); + hHQ_core->last_max_pos_pulse_fx = 0; + + set16_fx(hHQ_core->prev_SWB_peak_pos_fx, 0, SPT_SHORTEN_SBNUM ); + hHQ_core->prev_frm_hfe2_fx = 0; + hHQ_core->prev_stab_hfe2_fx = 0; + + IF( GT_32(st_fx->output_Fs,16000)) + { + set32_fx(hHQ_core->prev_coeff_out_fx, 0, L_HQ_WB_BWE ); + } +#ifdef IVAS_CODE_SWITCHING + if (st->element_mode != EVS_MONO) + { + /* Estimate mem_env_delta to reinit env_stab */ + tmp = max(0, ENV_STAB_EST1 + (ENV_STAB_EST2 * st->stab_fac_smooth_lt) + (ENV_STAB_EST3 * st->log_energy_diff_lt)); + st->hHQ_core->mem_env_delta = (int16_t)min(MAX16B, (int32_t)(tmp * (1 << 12))); /* Convert to Q12 and handle saturation */ + + if (st->last_core != TCX_20_CORE && st->last_core != TCX_10_CORE) + { + set_f(st->hHQ_core->old_out, 0, output_frame); + set_f(st->hHQ_core->old_outLB, 0, L_FRAME16k); + } + + st->hHQ_core->no_att_hangover = 0; + st->hHQ_core->energy_lt = 300.0f; + + set_s(st->hHQ_core->old_is_transient, 0, 3); + set_f(st->hHQ_core->prev_noise_level, 0.0f, 2); + st->hHQ_core->prev_R = 0; + set_s(st->hHQ_core->mem_norm + 1, 39, SFM_N_ENV_STAB - 1); + st->hHQ_core->prev_hqswb_clas = HQ_NORMAL; + st->hHQ_core->prev_ni_ratio = 0.5f; + set_f(st->hHQ_core->prev_En_sb, 0.0f, NB_SWB_SUBBANDS); + } + else +#endif + { + set16_fx(hHQ_core->old_out_fx, 0, output_frame); + hHQ_core->Q_old_wtda_LB = 15; + hHQ_core->Q_old_wtda = 15; +#ifdef IVAS_CODE_SWITCHING + set_f(st->hHQ_core->old_outLB, 0, L_FRAME16k); +#endif + } + } + + /* handle switching cases where preecho_sb was not called in the last frame (memory not up to date) */ + IF (hHQ_core != NULL) + { + hHQ_core->pastpre_fx--; + IF(hHQ_core->pastpre_fx <= 0) + { + reset_preecho_dec_fx(hHQ_core); + } + } + IF( EQ_32(st_fx->core_brate,FRAME_NO_DATA)) + { + st_fx->VAD = 0; + move16(); + st_fx->m_frame_type = ZERO_FRAME; + move16(); + } + ELSE IF( EQ_32(st_fx->core_brate,SID_2k40) || EQ_32(st_fx->core_brate, SID_1k75) ) + { + st_fx->VAD = 0; + move16(); + st_fx->m_frame_type = SID_FRAME; + move16(); + } + ELSE + { + st_fx->VAD = 1; + move16(); + st_fx->m_frame_type = ACTIVE_FRAME; + move16(); + } + + /*switch on CNA on active frames*/ + test(); + test(); + test(); + test(); + IF(EQ_16(st_fx->element_mode, EVS_MONO)) /* for IVAS modes, st->flag_cna is set earlier */ + { + IF(NE_16(st_fx->core, AMR_WB_CORE) && st_fx->VAD && LE_32(st_fx->total_brate, CNA_MAX_BRATE)) + { + st_fx->flag_cna = 1; + move16(); + } + ELSE IF(EQ_16(st_fx->core, AMR_WB_CORE) && st_fx->VAD && LE_32(st_fx->total_brate, ACELP_8k85)) + { + st_fx->flag_cna = 1; + move16(); + } + ELSE IF(st_fx->VAD || (EQ_16(st_fx->cng_type, FD_CNG) && EQ_16(st_fx->L_frame, L_FRAME16k))) + { + st_fx->flag_cna = 0; + move16(); + } + } + if( EQ_16(st_fx->core,AMR_WB_CORE)) + { + st_fx->cng_type = LP_CNG; + move16(); + } + + test(); + test(); + test(); + test(); + IF( st_fx->hFdCngDec_fx && ((NE_16(st_fx->last_L_frame,st_fx->L_frame))|| + (NE_16(st_fx->hFdCngDec_fx->hFdCngCom->frameSize,st_fx->L_frame)) || + st_fx->ini_frame == 0 || NE_16(st_fx->bwidth, st_fx->last_bwidth) )) + { + + IF( NE_16(st_fx->core,AMR_WB_CORE)) + { + Word32 tmp; + + tmp = st_fx->total_brate; + move32(); + test(); + if( EQ_16(st_fx->rf_flag,1)&&EQ_32(st_fx->total_brate,ACELP_13k20)) + { + tmp = ACELP_9k60; + move32(); + } + configureFdCngDec(st_fx->hFdCngDec_fx, st_fx->bwidth, tmp, st_fx->L_frame, st_fx->last_L_frame, st_fx->element_mode ); + } + ELSE + { + configureFdCngDec(st_fx->hFdCngDec_fx, 1, ACELP_8k00, st_fx->L_frame, st_fx->last_L_frame, st_fx->element_mode); + + if( st_fx->VAD ) + { + st_fx->hFdCngDec_fx->hFdCngCom->CngBitrate = st_fx->total_brate; + move32(); + } + } + + test(); + test(); + IF ( NE_16(st_fx->last_L_frame,st_fx->L_frame)&&LE_16(st_fx->L_frame,L_FRAME16k)&&LE_16(st_fx->last_L_frame,L_FRAME16k)) + { + test(); +#ifdef IVAS_CODE_SWITCHING + IF (EQ_16(st_fx->element_mode, IVAS_CPE_DFT) || EQ_16(st_fx->element_mode, IVAS_CPE_TD)) + { + lerp(st_fx->hFdCngDec_fx->hFdCngCom->olapBufferAna + st_fx->last_L_frame, st_fx->hFdCngDec_fx->hFdCngCom->olapBufferAna + st_fx->L_frame, st_fx->L_frame, st_fx->last_L_frame); + } +#endif + lerp(st_fx->hFdCngDec_fx->hFdCngCom->olapBufferSynth2, st_fx->hFdCngDec_fx->hFdCngCom->olapBufferSynth2, st_fx->L_frame * 2, st_fx->last_L_frame * 2); + test(); + IF( LE_32(st_fx->total_brate,SID_2k40)&&LE_32(st_fx->last_total_brate,SID_2k40)) + { + lerp( st_fx->hFdCngDec_fx->hFdCngCom->olapBufferSynth, st_fx->hFdCngDec_fx->hFdCngCom->olapBufferSynth, st_fx->L_frame*2, st_fx->last_L_frame*2 ); + IF( EQ_16(st_fx->L_frame, L_FRAME)) + { + FOR( i=0; i < st_fx->L_frame*2; i++ ) + { + st_fx->hFdCngDec_fx->hFdCngCom->olapBufferSynth[i] = mult_r( st_fx->hFdCngDec_fx->hFdCngCom->olapBufferSynth[i], 20480 ); + } + } + ELSE + { + FOR( i=0; i < st_fx->L_frame*2; i++ ) + { + st_fx->hFdCngDec_fx->hFdCngCom->olapBufferSynth[i] = mult_r( shl(st_fx->hFdCngDec_fx->hFdCngCom->olapBufferSynth[i],1), 26214 ); + } + } + } + } + } + + return error; +} + +/*---------------------------------------------------------------------* + * core_switching_post_dec() + * + * Postprocessing for ACELP/HQ core switching + *---------------------------------------------------------------------*/ + +ivas_error core_switching_post_dec_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + Word16 *synth, /* i/o: output synthesis Qsynth */ +#ifdef IVAS_CODE_SWITCHING + float* output, /* i/o: LB synth/upsampled LB synth */ + float output_mem[], /* i : OLA memory from last TCX/HQ frame */ + const IVAS_FORMAT ivas_format, /* i : IVAS format */ + const Word16 use_cldfb_for_dft, /* i : flag to use of CLDFB for DFT Stereo */ +#endif + const Word16 output_frame, /* i : frame length */ + const Word16 core_switching_flag, /* i : ACELP->HQ switching flag */ +#ifdef IVAS_CODE_SWITCHING + const Word16 sba_dirac_stereo_flag, /* i : signal stereo output for SBA DirAC */ + const Word16 nchan_out, /* i : number of output channels */ +#endif + const Word16 last_element_mode, /* i : element mode of previous frame */ + Word16 *Qsynth /* i/o: Scaling of ACELP exit (Q_syn2-1) or HQ exit (Qsynth); changes after this function */ +) +{ + Word16 i, delay_comp, delta; + Word16 tmpF, tmp, Fs_kHz, shift, *ptmp1, *ptmp2; + Word32 L_tmp; + Word16 synth_subfr_out[SWITCH_MAX_GAP], synth_subfr_bwe[SWITCH_MAX_GAP]; + Word16 mem_synth[NS2SA(16000, DELAY_CLDFB_NS)+2]; + Word16 Qtmp; + Word16 Qsubfr; + TD_BWE_DEC_HANDLE hBWE_TD; + FD_BWE_DEC_HANDLE hBWE_FD; + HQ_DEC_HANDLE hHQ_core; + ivas_error error; + +#ifdef IVAS_CODE_SWITCHING + int16_t offset; +#endif +#ifdef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING + (void)(last_element_mode); +#endif + hBWE_TD = st_fx->hBWE_TD; + hBWE_FD = st_fx->hBWE_FD; + hHQ_core = st_fx->hHQ_core; + error = IVAS_ERR_OK; + + //PMT("core_switching_post_dec_fx : Only handles has been converted, code needs to be entirely reviewed ") + + /* Rescale synthesis in Q0 to avoid multiple rescaling after */ + tmp = Find_Max_Norm16(synth,output_frame); + Scale_sig(synth,output_frame,tmp); + *Qsynth=add(*Qsynth,tmp); + + test(); test(); test(); + IF( EQ_16(st_fx->core, ACELP_CORE)&&st_fx->bfi && hHQ_core != NULL && !st_fx->con_tcx) + { + if ((error = acelp_core_switch_dec_bfi_fx( st_fx, hHQ_core->fer_samples_fx, st_fx->coder_type_fx )) != IVAS_ERR_OK) + { + return error; + } /*the output at Q0*/ + } + + /* set multiplication factor according to the sampling rate */ + tmp = extract_l(L_shr(st_fx->output_Fs,13)); + Fs_kHz = shl(add(tmp,1),3); + + delta = 1; + move16(); + if ( GE_16(output_frame, L_FRAME16k)) + { + delta = shr(Fs_kHz, 3); + } + + /* set delay compensation between HQ synthesis and ACELP synthesis */ + delay_comp = i_mult2(delta, HQ_DELAY_COMP); + + IF( EQ_16(st_fx->core, HQ_CORE)) + { + st_fx->use_acelp_preq = 0; + move16(); + /* rescaling to the min exp of the 2 */ + /* Qtmp=s_min(*Qsynth,st_fx->Q_old_postdec); + Scale_sig(synth, output_frame, sub(Qtmp,*Qsynth)); + Scale_sig(st_fx->delay_buf_out_fx, delay_comp, sub(Qtmp,st_fx->Q_old_postdec));*/ + + hBWE_FD->mem_deemph_old_syn_fx = 0; + move16(); + + test(); + test(); + test(); + IF ( core_switching_flag && EQ_16(st_fx->last_L_frame, st_fx->last_L_frame_ori)&&(EQ_16(st_fx->last_core,ACELP_CORE)||EQ_16(st_fx->last_core,AMR_WB_CORE))) + { + if ((error = acelp_core_switch_dec_fx( st_fx, synth_subfr_out, synth_subfr_bwe, output_frame, core_switching_flag, mem_synth, &Qsubfr )) != IVAS_ERR_OK) + { + return error; + } + } + test(); + test(); + IF( core_switching_flag && EQ_16(st_fx->last_core, HQ_CORE)&&st_fx->prev_bfi) + { + Copy( st_fx->delay_buf_out_fx, synth_subfr_out, delay_comp ); + Qsubfr= hHQ_core->Q_old_postdec; + } + + /* delay HQ synthesis to synchronize with ACELP synthesis */ + /* rescaling to the min exp of the 2 */ + Qtmp=s_min(*Qsynth, hHQ_core->Q_old_postdec); + Scale_sig(synth, output_frame, sub(Qtmp,*Qsynth)); + *Qsynth=Qtmp; + move16(); + Scale_sig(st_fx->delay_buf_out_fx, delay_comp, sub(Qtmp, hHQ_core->Q_old_postdec)); + hHQ_core->Q_old_postdec=Qtmp; + move16(); + + Copy( synth, &synth[delay_comp], output_frame); + Copy( st_fx->delay_buf_out_fx, synth, delay_comp ); + Copy( &synth[output_frame], st_fx->delay_buf_out_fx, delay_comp ); + + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF ( core_switching_flag && EQ_16(st_fx->last_L_frame, st_fx->last_L_frame_ori)&&(EQ_16(st_fx->last_core,ACELP_CORE)||EQ_16(st_fx->last_core,AMR_WB_CORE))) + { + /* mem_over_hp_fx : Qsubfr */ + core_switching_OLA_fx( mem_synth, st_fx->last_L_frame, st_fx->output_Fs, synth, synth_subfr_out, synth_subfr_bwe, output_frame, st_fx->bwidth, Qsynth, &Qsubfr ); + } + ELSE IF ( core_switching_flag && EQ_16(st_fx->last_core, HQ_CORE)&&st_fx->prev_bfi) /* HQ | ACELP | TRANSITION with ACELP frame lost */ + { + /* Overlapp between old->out (stocked in st_fx->fer_samples)and good HQ frame on L/2 */ + ptmp1 = &synth[delay_comp]; + shift = i_mult2(Fs_kHz, 10); + tmp = i_mult2(delta,shr(N16_CORE_SW,1)); + + Scale_sig(hHQ_core->fer_samples_fx, output_frame, *Qsynth); + ptmp2 = &hHQ_core->fer_samples_fx[tmp]; + tmp = div_s(1, shift); /*Q15*/ + tmpF = 0; + move16(); + + FOR( i=0; icore, HQ_CORE)&&(EQ_16(st_fx->last_core,ACELP_CORE)||EQ_16(st_fx->last_core,AMR_WB_CORE))) /* ACELP | TRANSITION | HQ with TRANSITION lost */ + || (core_switching_flag && st_fx->prev_bfi && NE_16(st_fx->last_L_frame, st_fx->last_L_frame_ori) ) ) + { + /* Overlapp between CELP estimation (BFI) and good HQ frame on L/2 */ + shift = i_mult2(Fs_kHz, 10); + tmp = div_s(1, shift); /*Q15*/ + tmpF = 0; + move16(); + ptmp1 = synth; + Scale_sig(hHQ_core->fer_samples_fx, output_frame, *Qsynth); + ptmp2 = hHQ_core->fer_samples_fx; + FOR( i=0; ibwe_non_lin_prev_scale_fx = L_deposit_l(0); + IF ( !(EQ_16(inner_frame_tbl[st_fx->bwidth], L_FRAME16k)&&EQ_32(st_fx->core_brate,HQ_32k))) + { + set32_fx(hHQ_core->prev_env_fx, 0, SFM_N_WB ); + set32_fx(hHQ_core->prev_normq_fx, 0, SFM_N_WB ); + } + Copy_Scale_sig( synth, st_fx->previoussynth_fx, output_frame, negate(*Qsynth) ); /*scaling of st_fx->previoussynth_fx set at Q0*/ + + /*Set post-filtering flag to zero*/ + st_fx->hPFstat->on = 0; + move16(); + } + ELSE + { + IF ( EQ_16(st_fx->last_core, HQ_CORE)) /* MDCT to ACELP transition */ + { + Qtmp = s_min(s_min(*Qsynth, hHQ_core->Q_old_postdec), hHQ_core->Q_old_wtda); + + Scale_sig(synth, output_frame, sub(Qtmp,*Qsynth)); + Scale_sig(st_fx->delay_buf_out_fx, delay_comp, sub(Qtmp, hHQ_core->Q_old_postdec)); + Scale_sig(hHQ_core->old_out_fx, L_FRAME48k, sub(Qtmp, hHQ_core->Q_old_wtda)); + *Qsynth = Qtmp; + move16(); + hHQ_core->Q_old_postdec=Qtmp; + move16(); + hHQ_core->Q_old_wtda=Qtmp; + move16(); + + Copy( st_fx->delay_buf_out_fx, synth, delay_comp ); /* copy the HQ/ACELP delay synchroniation buffer at the beginning of ACELP frame */ + + tmp = i_mult2(delta, N_ZERO_8); + shift = i_mult2(Fs_kHz, 3); + test(); + IF( st_fx->prev_bfi && hHQ_core->HqVoicing_fx ) + { + Copy_Scale_sig(hHQ_core->fer_samples_fx, &hHQ_core->old_out_fx[tmp], shift, *Qsynth ); + } + + ptmp2 = &hHQ_core->old_out_fx[tmp]; + tmp = div_s(1, shift); + ptmp1 = &synth[delay_comp]; + tmpF = 0; + move16(); + FOR( i=0; idelay_buf_out_fx, 0, HQ_DELTA_MAX*HQ_DELAY_COMP ); + hHQ_core->oldHqVoicing_fx = 0; + move16(); + + set16_fx(hHQ_core->prev_SWB_peak_pos_fx, 0, SPT_SHORTEN_SBNUM); + hHQ_core->prev_frm_hfe2_fx = 0; + move16(); + hHQ_core->prev_stab_hfe2_fx = 0; + move16(); + } + + /* reset SWB BWE buffers */ + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF(st_fx->bws_cnt_fx == 0 || (st_fx->bws_cnt_fx > 0 && NE_16(st_fx->coder_type_fx, INACTIVE)&&NE_16(st_fx->coder_type_fx,AUDIO))) + { + st_fx->attenu_fx = 3277; + move16(); + } + + IF( ( NE_16(st_fx->last_extl, SWB_BWE)&&EQ_16(st_fx->extl,SWB_BWE))||(NE_16(st_fx->last_extl,FB_BWE)&&EQ_16(st_fx->extl,FB_BWE))|| + ((EQ_16(st_fx->last_core, HQ_CORE) || EQ_16(st_fx->last_extl, SWB_TBE) ) && st_fx->extl < 0 && NE_16(st_fx->core, HQ_CORE) ) + || (EQ_16(st_fx->last_core,ACELP_CORE) && EQ_16(st_fx->core,ACELP_CORE) + && ((NE_16(st_fx->prev_coder_type_fx,INACTIVE) && EQ_16(st_fx->coder_type_fx,INACTIVE) ) || (NE_16(st_fx->prev_coder_type_fx,AUDIO) && EQ_16(st_fx->coder_type_fx,AUDIO) )) + && st_fx->bws_cnt_fx > 0) + ) + { + set16_fx(hBWE_FD->L_old_wtda_swb_fx, 0, output_frame ); + hBWE_FD->old_wtda_swb_fx_exp = 0; + move16(); + if( NE_16(st_fx->last_extl, WB_BWE)) + { + hBWE_FD->prev_mode_fx = NORMAL; + move16(); + } + + hBWE_FD->prev_Energy_fx = 0; + move16(); + hBWE_FD->prev_L_swb_norm_fx = 8; + move16(); + hBWE_FD->prev_frica_flag_fx = 0; + move16(); + set16_fx(hBWE_FD->mem_imdct_fx, 0, L_FRAME48k ); + hBWE_FD->prev_td_energy_fx = 0; + move16(); + hBWE_FD->prev_weight_fx = 6554; + move16(); /*0.2 in Q15*/ + st_fx->prev_fb_ener_adjust_fx = 0; + move16(); + } + + /* reset WB BWE buffers */ + test(); + IF( NE_16(st_fx->last_extl, WB_BWE)&&EQ_16(st_fx->extl,WB_BWE)) + { + set16_fx(hBWE_FD->L_old_wtda_swb_fx, 0, output_frame); + + test(); + if ( NE_16(st_fx->last_extl, SWB_BWE)&&NE_16(st_fx->last_extl,FB_BWE)) + { + hBWE_FD->prev_mode_fx = NORMAL; + move16(); + } + hBWE_FD->prev_Energy_wb_fx = 0; + move16(); + hBWE_FD->prev_L_swb_norm_fx = 8; + move16(); + set16_fx(hBWE_FD->mem_imdct_fx, 0, L_FRAME48k ); + hBWE_FD->prev_flag_fx = 0; + move16(); + } + + /* reset SWB TBE buffers */ + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( (( EQ_16(st_fx->extl, SWB_TBE)||EQ_16(st_fx->extl,FB_TBE)||EQ_16(st_fx->extl,SWB_CNG))&& + ( NE_16(st_fx->L_frame, st_fx->last_L_frame) || ( NE_16(st_fx->last_extl, SWB_TBE) && NE_16(st_fx->last_extl, FB_TBE) ) || EQ_16(st_fx->last_core, HQ_CORE) )) || + ( LT_16(st_fx->bwidth, st_fx->last_bwidth) && NE_16(st_fx->last_extl, SWB_TBE) ) || st_fx->old_ppp_mode_fx + || ((EQ_16(st_fx->prev_coder_type_fx, AUDIO) || EQ_16(st_fx->prev_coder_type_fx, INACTIVE) ) && st_fx->bws_cnt_fx > 0) + || (st_fx->bws_cnt_fx == 0 && EQ_16(st_fx->prev_bws_cnt_fx, N_WS2N_FRAMES)) ) + { + swb_tbe_reset_fx(hBWE_TD->mem_csfilt_fx, hBWE_TD->mem_genSHBexc_filt_down_shb_fx, hBWE_TD->state_lpc_syn_fx, + hBWE_TD->syn_overlap_fx, hBWE_TD->state_syn_shbexc_fx, &(hBWE_TD->tbe_demph_fx), &(hBWE_TD->tbe_premph_fx) + , hBWE_TD->mem_stp_swb_fx, &(hBWE_TD->gain_prec_swb_fx) ); + + set16_fx( st_fx->GainShape_Delay, 0, NUM_SHB_SUBFR/2 ); + swb_tbe_reset_synth_fx(hBWE_TD->genSHBsynth_Hilbert_Mem_fx, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx ); + + IF( EQ_16(output_frame, L_FRAME16k)) + { + /* reset in case that SWB TBE layer is transmitted, but the output is 16kHz sampled */ + set16_fx(hBWE_TD->mem_resamp_HB_32k_fx, 0, 2*ALLPASSSECTIONS_STEEP+1 ); + } + set16_fx(hBWE_TD->int_3_over_2_tbemem_dec_fx, 0, INTERP_3_2_MEM_LEN); + } + ELSE IF( ( EQ_16(st_fx->extl, SWB_TBE)||EQ_16(st_fx->extl,FB_TBE))&& + ( NE_32(st_fx->last_total_brate, st_fx->total_brate) || NE_16(st_fx->last_bwidth, st_fx->bwidth) || + NE_16(st_fx->last_codec_mode, MODE1) || NE_16(st_fx->rf_flag, st_fx->rf_flag_last) ) ) + { + set16_fx(hBWE_TD->state_lpc_syn_fx, 0, LPC_SHB_ORDER ); + set16_fx(hBWE_TD->state_syn_shbexc_fx, 0, L_SHB_LAHEAD ); + set16_fx(hBWE_TD->mem_stp_swb_fx, 0, LPC_SHB_ORDER ); + set16_fx(hBWE_TD->mem_zero_swb_fx, 0, LPC_SHB_ORDER ); + hBWE_TD->gain_prec_swb_fx = 16384; + move16(); /*Q14 = 1 */ + } + + /* Interp_3_2 CNG buffers reset */ + test(); + test(); + test(); + IF(EQ_32(st_fx->output_Fs,48000)&&((GT_32(st_fx->last_core_brate,SID_2k40))&&(EQ_32(st_fx->core_brate,FRAME_NO_DATA)||EQ_32(st_fx->core_brate,SID_2k40)))) + { + set16_fx(st_fx->interpol_3_2_cng_dec_fx, 0, INTERP_3_2_MEM_LEN ); + } + + /* reset FB TBE buffers */ + test(); + test(); + IF( EQ_16(st_fx->extl, FB_TBE)&&(NE_16(st_fx->last_extl,FB_TBE)||NE_16(st_fx->L_frame,st_fx->last_L_frame))) + { + set16_fx(hBWE_TD->fb_state_lpc_syn_fx, 0, LPC_SHB_ORDER ); + hBWE_TD->fb_tbe_demph_fx = 0; + fb_tbe_reset_synth_fx(hBWE_TD->fbbwe_hpf_mem_fx, hBWE_TD->fbbwe_hpf_mem_fx_Q,&hBWE_TD->prev_fbbwe_ratio_fx ); + } + + /* reset WB TBE buffers */ + test(); + IF( NE_16(st_fx->last_extl, WB_TBE)&&EQ_16(st_fx->extl,WB_TBE)) + { + wb_tbe_extras_reset_fx(hBWE_TD->mem_genSHBexc_filt_down_wb2_fx, hBWE_TD->mem_genSHBexc_filt_down_wb3_fx ); + wb_tbe_extras_reset_synth_fx(hBWE_TD->state_lsyn_filt_shb_fx, hBWE_TD->state_lsyn_filt_dwn_shb_fx, hBWE_TD->state_32and48k_WB_upsample_fx, hBWE_TD->mem_resamp_HB_fx ); + + set16_fx(hBWE_TD->state_syn_shbexc_fx, 0, L_SHB_LAHEAD / 4 ); + set16_fx(hBWE_TD->syn_overlap_fx, 0, L_SHB_LAHEAD ); + set32_fx(hBWE_TD->mem_csfilt_fx, 0, 2 ); + } + + return error; +} + +/*---------------------------------------------------------------------* +* core_switching_hq_prepare_dec() +* +* Preprocessing in the first HQ frame after ACELP frame +* - modify bit allocation for HQ core by removing CELP subframe budget +*---------------------------------------------------------------------*/ + +void core_switching_hq_prepare_dec_fx( + Decoder_State *st_fx, /* i/o: encoder state structure */ + Word16 *num_bits, /* i/o: bit budget update */ + const Word16 output_frame /* i : output frame length */ +) +{ + Word32 cbrate; + + test(); + IF( EQ_16(st_fx->last_core, HQ_CORE)&&st_fx->prev_bfi) + { + Copy_Scale_sig( st_fx->hHQ_core->old_out_fx, st_fx->hHQ_core->fer_samples_fx, output_frame, negate(st_fx->hHQ_core->Q_old_wtda) ); /*Q0*/ + } + + /* set switching frame bitrate */ + IF( EQ_16(st_fx->last_L_frame, L_FRAME)) + { + cbrate = L_add(st_fx->core_brate, 0); + if( GT_32(st_fx->core_brate, ACELP_24k40)) + { + cbrate = L_add(ACELP_24k40, 0); + } + + /* subtract ACELP switching frame bits */ + if( GE_32(st_fx->core_brate, ACELP_11k60)) + { + (*num_bits) = sub((*num_bits), 1); /* LP_FLAG bit */ + } + *num_bits = sub( (*num_bits), ACB_bits_tbl[BIT_ALLOC_IDX_fx(cbrate, GENERIC, 0, 0)] ); /* pitch bits*/ + *num_bits = sub( (*num_bits), gain_bits_tbl[BIT_ALLOC_IDX_fx(cbrate, TRANSITION, 0, 0)] ); /* gain bits */ + *num_bits = sub( (*num_bits), FCB_bits_tbl[BIT_ALLOC_IDX_fx(cbrate, GENERIC, 0, 0)] ); /* FCB bits */ + } + ELSE /* L_frame == L_FRAME16k */ + { + IF( LE_32(st_fx->core_brate, ACELP_8k00)) + { + cbrate = L_add(ACELP_8k00, 0); + } + ELSE IF( LE_32(st_fx->core_brate, ACELP_14k80)) + { + cbrate = L_add(ACELP_14k80, 0); + } + ELSE + { + cbrate = L_min(st_fx->core_brate, ACELP_22k60); + } + + /* subtract ACELP switching frame bits */ + if( GE_32(st_fx->core_brate, ACELP_11k60)) + { + (*num_bits) = sub((*num_bits), 1); /* LP_FLAG bit */ + } + *num_bits = sub((*num_bits), ACB_bits_16kHz_tbl[BIT_ALLOC_IDX_16KHZ_fx(cbrate, GENERIC, 0, 0)]); /* pitch bits*/ + *num_bits = sub((*num_bits), gain_bits_16kHz_tbl[BIT_ALLOC_IDX_16KHZ_fx(cbrate, GENERIC, 0, 0)]); /* gain bits */ + *num_bits = sub((*num_bits), FCB_bits_16kHz_tbl[BIT_ALLOC_IDX_16KHZ_fx(cbrate, GENERIC, 0, 0)]); /* FCB bits */ + } + + /* subtract BWE bits */ + test(); + test(); + IF( !( ( EQ_16(inner_frame_tbl[st_fx->bwidth], L_FRAME16k)&&EQ_16(st_fx->last_L_frame,L_FRAME16k))||EQ_16(inner_frame_tbl[st_fx->bwidth],L_FRAME8k))) + { + *num_bits = sub((*num_bits), (NOOFGAINBITS1 + AUDIODELAYBITS)); + } + + /* reset state of old_out if switching */ + set16_fx( st_fx->hHQ_core->old_out_fx, 0, output_frame ); + return; + +} diff --git a/lib_dec/d_gain2p.c b/lib_dec/d_gain2p.c index 826208b9a2a87df187743f99870ef51f625fee23..db8c755f7d50b7cf43935de69abade1da6dcb351 100644 --- a/lib_dec/d_gain2p.c +++ b/lib_dec/d_gain2p.c @@ -43,12 +43,12 @@ #include "wmc_auto.h" /*--------------------------------------------------------------------------* - * Mode2_gain_dec_mless + * Mode2_gain_dec_mless_flt * * Decoding of pitch and codebook gains without updating long term energies *-------------------------------------------------------------------------*/ -static void Mode2_gain_dec_mless( +static void Mode2_gain_dec_mless_flt( const int16_t index, /* i : index of quantizer */ const float code[], /* i : Innovative code vector */ const int16_t lcode, /* i : Subframe size */ @@ -135,12 +135,12 @@ static void Mode2_gain_dec_mless( /*---------------------------------------------------------------------* - * gain_dec_uv + * gain_dec_uv_flt * * Decoding of pitch and codebook gains for Unvoiced mode *---------------------------------------------------------------------*/ -static void gain_dec_uv( +static void gain_dec_uv_flt( const int16_t index, /* i/o: Quantization index vector */ const float *code, /* i : algebraic code excitation */ const int16_t lcode, /* i : Subframe size */ @@ -181,12 +181,12 @@ static void gain_dec_uv( /*---------------------------------------------------------------------* - * gain_dec_gacelp_uv + * gain_dec_gacelp_uv_flt * * Decoding of pitch and codebook gains for Unvoiced mode *---------------------------------------------------------------------*/ -void gain_dec_gacelp_uv( +void gain_dec_gacelp_uv_flt( int16_t index, /* i/o: Quantization index vector */ const float *code, /* i : algebraic code excitation */ const float *code2, /* i : algebraic code excitation */ @@ -240,12 +240,12 @@ void gain_dec_gacelp_uv( /*---------------------------------------------------------------------* - * decode_acelp_gains + * decode_acelp_gains_flt * * *---------------------------------------------------------------------*/ -void decode_acelp_gains( +void decode_acelp_gains_flt( const float *code, const int16_t gains_mode, const float mean_ener_code, @@ -267,17 +267,17 @@ void decode_acelp_gains( if ( ( ( gains_mode > 0 ) && ( gains_mode < 4 ) ) ) { /* EVS gains quantizer (5bits/subfr) */ - Mode2_gain_dec_mless( index, code, L_subfr, gain_pit, gain_code, mean_ener_code, past_gpit, past_gcode, gain_inov, gains_mode - 1 ); + Mode2_gain_dec_mless_flt( index, code, L_subfr, gain_pit, gain_code, mean_ener_code, past_gpit, past_gcode, gain_inov, gains_mode - 1 ); } else if ( gains_mode == 6 ) { /* UV gains quantizer (6bits/subfr) */ - gain_dec_uv( index, code, L_subfr, gain_pit, gain_code, past_gpit, past_gcode, gain_inov ); + gain_dec_uv_flt( index, code, L_subfr, gain_pit, gain_code, past_gpit, past_gcode, gain_inov ); } else if ( gains_mode == 7 ) { /* GACELP_UV gains quantizer (7=5-2bits/subfr) */ - gain_dec_gacelp_uv( index, code, code2, mean_ener_code, L_subfr, gain_pit, gain_code, gain_code2, past_gpit, past_gcode, gain_inov ); + gain_dec_gacelp_uv_flt( index, code, code2, mean_ener_code, L_subfr, gain_pit, gain_code, gain_code2, past_gpit, past_gcode, gain_inov ); } else { diff --git a/lib_dec/d_gain2p_fx.c b/lib_dec/d_gain2p_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..4bf6c098e1e110a2c2dd038c560143d1b0783415 --- /dev/null +++ b/lib_dec/d_gain2p_fx.c @@ -0,0 +1,412 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include +#include +#include "prot_fx1.h" +#include "prot_fx2.h" +#include "basop_util.h" +#include "stl.h" +#include "rom_com.h" + + /*-------------------------------------------------------------------* + * Decoding of pitch and codebook gains (see q_gain2_plus.c) * + *-------------------------------------------------------------------*/ + +/********************* + * private functions * + *********************/ +static Word32 calc_gcode0( + Word16 *gcode0, + Word16 *exp_gcode0 +) +{ + Word32 L_tmp; + + /*gcode0 = (float)pow(10.0,(gcode0)*0.05);*/ /* predicted gain */ + + L_tmp = L_mult(*gcode0, 5443/*0.166096f Q15*/); + *exp_gcode0 = add(1,extract_l(L_shr(L_tmp, 24))); + L_tmp = L_lshl(L_tmp, 7); + L_tmp = L_and(0x7FFFFFFF, L_tmp); + + L_tmp = Pow2(30,round_fx(L_tmp)); + *gcode0 = round_fx(L_tmp); + + return L_tmp; +} + +static Word32 calc_gain_code(Word16 g_code, Word16 gcode0, Word16 exp_gcode0) +{ + Word32 L_tmp; + + L_tmp = L_mult(g_code, gcode0); /* Q11*Q15 -> Q27 */ + exp_gcode0 = add(exp_gcode0,-11); +#ifdef BASOP_NOGLOB + L_tmp = L_shl_sat(L_tmp, exp_gcode0); /* Q27 -> Q16 */ +#else + L_tmp = L_shl(L_tmp, exp_gcode0); /* Q27 -> Q16 */ +#endif + + return L_tmp; +} + +/*--------------------------------------------------------------------------* +* Mode2_gain_dec_mless +* +* Decoding of pitch and codebook gains without updating long term energies +*-------------------------------------------------------------------------*/ + +static void Mode2_gain_dec_mless( + Word16 index, /* i : Quantization index vector Q0 */ + Word16 *code, /* i : algebraic code excitation Q9 */ + Word16 lcode, /* i : Subframe size Q0 */ + Word16 *gain_pit, /* o : Quantized pitch gain 1Q14 */ + Word32 *gain_code, /* o : Quantized codebook gain Q16 */ + Word16 mean_ener, /* i : mean_ener defined in open-loop Q8 */ + Word16 *past_gpit, /* i/o: past gain of pitch 1Q14 */ + Word32 *past_gcode, /* i/o: past energy of code Q16 */ + Word16 *gain_inov, /* o : unscaled innovation gain 3Q12 */ + Word16 coder_type /* i : coder type for number of bits */ +) +{ + + Word16 ener_code; + const Word16 *t_qua_gain; + Word16 exp_L_tmp1; + Word16 gcode0, exp_gcode0; + Word32 L_tmp, L_tmp1; + + + + /**gain_inov = 1.0f / (float)sqrt( ( dot_product( code, code, lcode ) + 0.01f ) / lcode);*/ + L_tmp = calc_gain_inov(code, lcode, &L_tmp1, &exp_L_tmp1); + move16(); +#ifdef BASOP_NOGLOB + *gain_inov = round_fx_sat(L_shl_sat(L_tmp, 15-3)); /* gain_inov in Q12 */ +#else + *gain_inov = round_fx(L_shl(L_tmp, 15-3)); /* gain_inov in Q12 */ +#endif + /*-----------------------------------------------------------------* + * Select the gains quantization table + *-----------------------------------------------------------------*/ + t_qua_gain = E_ROM_qua_gain7b_const; + + if( coder_type == 0 ) + { + t_qua_gain = E_ROM_qua_gain5b_const; + } + + if(EQ_16(coder_type,1)) + { + t_qua_gain = E_ROM_qua_gain6b_const; + } + + /*-----------------------------------------------------------------* + * decode pitch gain + *-----------------------------------------------------------------*/ + *gain_pit = t_qua_gain[index*2]; + + /*-----------------------------------------------------------------* + * calculate the predicted gain code + *-----------------------------------------------------------------*/ + /*ener_code = 10 * log10((dot_product(code, code, lcode) + 0.01) / lcode) */ + L_tmp = BASOP_Util_Log2(L_tmp1); + L_tmp = L_add(L_tmp,L_shl(L_deposit_l(exp_L_tmp1),31-LD_DATA_SCALE)); + + L_tmp = Mpy_32_16_1(L_tmp, 24660/*(10.0f/3.3219280948873623478703194294894f)/4.0f Q15*/); + /* exponent of L_tmp = 6+2 */ + ener_code = round_fx(L_shl(L_tmp, 6+2-7)); /* Q8 */ + + /* predicted codebook gain */ + gcode0 = sub(mean_ener, ener_code); /* Q8 */ + + /*gcode0 = (float)pow(10.0,(gcode0)*0.05);*/ /* predicted gain */ + + calc_gcode0(&gcode0, &exp_gcode0); + + /*-----------------------------------------------------------------* + * decode normalized codebook gain + *-----------------------------------------------------------------*/ + /* *gain_code = t_qua_gain[index*2+1] * gcode0;*/ + + L_tmp = calc_gain_code(t_qua_gain[index*2+1], gcode0, exp_gcode0); + + *gain_code = L_tmp; + *past_gpit = *gain_pit; + /**past_gcode = *gain_code / *gain_inov; */ + /* Q16/Q12 => Q5 */ + L_tmp1 = L_deposit_h(BASOP_Util_Divide3216_Scale(L_tmp,*gain_inov,&exp_L_tmp1)); + *past_gcode = L_shl(L_tmp1,sub(exp_L_tmp1,15-12)); + + + + return; +} + +/*---------------------------------------------------------------------* + * gain_dec_uv + * + * Decoding of pitch and codebook gains for Unvoiced mode + *---------------------------------------------------------------------*/ + +static void gain_dec_uv( + Word16 index, /* i : Quantization index vector Q0 */ + Word16 *code, /* i : algebraic code excitation Q9 */ + Word16 lcode, /* i : Subframe size Q0 */ + Word16 *gain_pit, /* o : Quantized pitch gain 1Q14 */ + Word32 *gain_code, /* o : Quantized codebook gain Q16 */ + Word16 *past_gpit, /* i/o: past gain of pitch 1Q14 */ + Word32 *past_gcode, /* i/o: past energy of code Q16 */ + Word16 *gain_inov /* o : unscaled innovation gain 3Q12 */ +) +{ + Word16 i, exp_L_tmp1; + Word32 L_tmp, L_tmp1; + + + /*-----------------------------------------------------------------* + * Innovation energy (without gain) + *-----------------------------------------------------------------*/ + /* *gain_inov = 1.0f / (float)sqrt( ( dot_product( code, code, lcode ) + 0.01f ) / lcode );*/ + L_tmp = calc_gain_inov(code, lcode, &L_tmp1, &exp_L_tmp1); + move16(); + *gain_inov = round_fx(L_shl(L_tmp, 15-3)); /* gain_inov in Q12 */ + + /*-----------------------------------------------------------------* + * Decode pitch gain + *-----------------------------------------------------------------*/ + *gain_pit = 0; + move16(); + + /*-----------------------------------------------------------------* + * Decode codebook gain + *-----------------------------------------------------------------*/ + /* *gain_code= (float)pow(10.f,(((index*1.9f)-30.f)/20.f));*/ + L_tmp = L_mac(-167197708l/*-0.166096*30.0f Q25*/,shl(index, 16-7), 10341/*0.166096f*1.9f Q15*/); + i = add(1,extract_l(L_shr(L_tmp, 25))); + L_tmp = L_lshl(L_tmp, 6); + L_tmp = L_and(0x7FFFFFFF, L_tmp); + + L_tmp = Pow2(30,round_fx(L_tmp)); + L_tmp = L_shl(L_tmp, i-(31-16)); /* Q16 */ + + + /*-----------------------------------------------------------------* + * past gains for error concealment + *-----------------------------------------------------------------*/ + *past_gpit = *gain_pit; + *past_gcode = L_tmp; + L_tmp = L_shl(Mpy_32_16_1(L_tmp, *gain_inov), 3); /* Q16*Q12 -> Q13 -> Q16 */ + *gain_code = L_tmp; + move32(); + + + return; +} + +/*---------------------------------------------------------------------* + * gain_dec_gacelp_uv + * + * Decoding of pitch and codebook gains for Unvoiced mode + *---------------------------------------------------------------------*/ + +static void gain_dec_gacelp_uv( + Word16 index, /* i : Quantization index vector Q0 */ + Word16 *code, /* i : algebraic code excitation Q9 */ + Word16 *code2, /* i : algebraic code excitation Q9 */ + Word16 mean_ener, /* i : Q8 */ + Word16 lcode, /* i : Subframe size Q0 */ + Word16 *gain_pit, /* o : Quantized pitch gain 1Q14 */ + Word32 *gain_code, /* o : Quantized codebook gain Q16 */ + Word32 *gain_code2, /* o : Quantized codebook gain Q16 */ + Word16 *past_gpit, /* i/o: past gain of pitch 1Q14 */ + Word32 *past_gcode, /* i/o: past energy of code Q16 */ + Word16 *gain_inov /* o : unscaled innovation gain 3Q12 */ +) +{ + Word16 i, exp_L_tmp1; + Word16 exp_gcode; + Word16 g_code; + Word32 L_tmp, L_tmp1; + Word32 pred_nrg_frame; + Word16 exp_gcode2, g_code2, norm_code2; + Word16 index2, s; + + + + + /* pred_nrg_frame = (float)pow(10.0,mean_ener/20.0); */ + L_tmp = L_mult(mean_ener, 10885/*0.166096f * 2 Q15*/); /* 6Q25 */ + pred_nrg_frame = BASOP_Util_InvLog2(L_sub(L_tmp, 503316480l/*15.f Q25*/)); /* 15Q16 */ + + /*-----------------------------------------------------------------* + * Prediction gains + *-----------------------------------------------------------------*/ + /* gain_inov = 1.0f / sqrt((dot_product(code, code, L_SUBFR) + 0.01) / L_SUBFR) */ + L_tmp = calc_gain_inov(code, lcode, NULL, NULL); + *gain_inov = round_fx(L_shl(L_tmp, 15-3)); /* gain_inov in Q12 */ + + /* gcode = pred_nrg_frame * (*gain_inov); */ + L_tmp = Mpy_32_16_1(pred_nrg_frame, *gain_inov); /* 18Q13 */ + i = norm_l(L_tmp); + g_code = round_fx(L_shl(L_tmp, i)); + exp_gcode = sub(18, i); + + /* norm_code2 = 1.0f / sqrt((dot_product(code2, code2, lcode) + 0.01f) / lcode); */ + L_tmp = calc_gain_inov(code2, lcode, NULL, NULL); + norm_code2 = round_fx(L_shl(L_tmp, 15-3)); /* Q12 */ + + /* g_code2 = pred_nrg_frame * norm_code2; */ + L_tmp = Mpy_32_16_1(pred_nrg_frame, norm_code2); /* 18Q13 */ + i = norm_l(L_tmp); + g_code2 = round_fx(L_shl(L_tmp, i)); + exp_gcode2 = sub(18, i); + + /*-----------------------------------------------------------------* + * Decode pitch gain + *-----------------------------------------------------------------*/ + *gain_pit = 0; + move16(); + *past_gpit = *gain_pit; + move16(); + + /*-----------------------------------------------------------------* + * past gains for error concealment + *-----------------------------------------------------------------*/ + index2=shr(index,5); + index=s_and(index,0x1F); + + /**gain_code= (float)pow(10.f,(((index*1.25f)-20.f)/20.f))*gcode;*/ + + L_tmp = L_mac(-111465139l/*-0.166096*20.0f Q25*/,shl(index, 16-7), 6803/*0.166096f*1.25f Q15*/); + + i = add(1,extract_l(L_shr(L_tmp, 25))); + L_tmp = L_lshl(L_tmp, 6); + L_tmp = L_and(0x7FFFFFFF, L_tmp); + + L_tmp = Pow2(30,round_fx(L_tmp)); + L_tmp = L_shl(L_tmp, i-(31-16)); /* Q16 */ + + /* *past_gcode = L_tmp * pred_nrg_frame; */ + i = norm_l(L_tmp); + L_tmp1 = L_shl(L_tmp, i); + exp_L_tmp1 = sub(15, i); + + i = norm_l(pred_nrg_frame); + L_tmp1 = Mpy_32_32(L_tmp1, L_shl(pred_nrg_frame, i)); + exp_L_tmp1 = add(exp_L_tmp1, sub(15, i)); + + *past_gcode = L_shl(L_tmp1, sub(exp_L_tmp1, 15)); /* Q16 */ move32(); + + *gain_code = L_shl(Mpy_32_16_1(*past_gcode, *gain_inov), 3); + move32(); + + + L_tmp = Mpy_32_16_1(*gain_code, BASOP_Util_Divide1616_Scale(g_code2, g_code, &s)); + L_tmp = L_shl(L_tmp, sub(sub(add(s, exp_gcode2), exp_gcode), 2)); /* Q16 */ + L_tmp1 = L_add(L_tmp, 0); + FOR (i = 0; i < index2; i++) + { + L_tmp1 = L_add(L_tmp1, L_tmp); + } + *gain_code2 = L_tmp1; + + + return; +} + +/********************* + * public functions * + *********************/ + +void decode_acelp_gains( + Word16 *code, /* i : algebraic code excitation Q9 */ + Word16 gains_mode, + Word16 mean_ener_code, /* i : mean_ener defined in open-loop Q8 */ + Word16 *gain_pit, /* o : Quantized pitch gain 1Q14 */ + Word32 *gain_code, /* o : Quantized codebook gain Q16 */ + Word16 **pt_indice, + Word16 *past_gpit, /* i/o: past gain of pitch 1Q14 */ + Word32 *past_gcode, /* i/o: past energy of code Q16 */ + Word16 *gain_inov, /* o : unscaled innovation gain 3Q12 */ + Word16 L_subfr, /* i : Subframe size Q0 */ + Word16 *code2, /* i : algebraic code excitation Q9 */ + Word32 *gain_code2 /* o : Quantized codebook gain Q16 */ +) +{ + Word16 index = 0; + + + index = **pt_indice; + (*pt_indice)++; + + IF ( s_and(gains_mode > 0,(Word16) LT_16(gains_mode, 4))) + { + /* ACELP gains quantizer (5bits/subfr) */ + Mode2_gain_dec_mless(index, code, L_subfr, gain_pit, gain_code, mean_ener_code, past_gpit, past_gcode, gain_inov, gains_mode-1 ); + } + ELSE IF (s_or((Word16)EQ_16(gains_mode,4),(Word16)EQ_16(gains_mode,5))) + { + /* AMR-WB gains quantizer (6bits/subfr (mode 2) or 7bits/subfr (mode 3)) */ + assert(0); + } + ELSE IF ( EQ_16(gains_mode,6)) + { + /* UV gains quantizer (6bits/subfr) */ + gain_dec_uv( index, code, L_subfr, gain_pit, gain_code, past_gpit, past_gcode, gain_inov ); + } + ELSE IF (EQ_16(gains_mode,7)) + { + /* GACELP_UV gains quantizer (7=5-2bits/subfr) */ + gain_dec_gacelp_uv( index, code, code2, mean_ener_code, L_subfr, gain_pit, gain_code, gain_code2, past_gpit, past_gcode, gain_inov ); + } + ELSE + { + IVAS_ERROR(IVAS_ERR_INTERNAL, "invalid gains coding for acelp!"); + } + +} + + +/*---------------------------------------------------------------------* + * d_gain_pred : + * + * decode the predicted value for the scaled + * innovation energy in all subframes + *---------------------------------------------------------------------*/ +void d_gain_pred( + Word16 nrg_mode, /* i : NRG moe */ + Word16 *Es_pred, /* o : predicted scaled innovation energy Q8 */ + Word16 **pt_indice /* i/o: pointer to the buffer of indices */ +) +{ + Word16 indice; + + indice = (Word16)**pt_indice; + (*pt_indice)++; + + *Es_pred = 0; + move16(); + + if( EQ_16(nrg_mode,1)) + { + *Es_pred = Es_pred_qua[indice]; + move16(); + } + + if( EQ_16(nrg_mode,2)) + { + *Es_pred = Es_pred_qua_2[indice]; + move16(); + } + + IF( GT_16(nrg_mode,2)) + { + move16(); + *Es_pred= extract_l(L_mac(-335544320l/* -20.f Q24*/, indice, 224/* 1.75f Q7*/)); /*(Q8 - ((Q0*Q7)=Q8))*/ + } + + return; +} diff --git a/lib_dec/dec2t32_fx.c b/lib_dec/dec2t32_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..b1cd2af3a63cde8ae7b0d68c9c4b35715158e8f6 --- /dev/null +++ b/lib_dec/dec2t32_fx.c @@ -0,0 +1,135 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ +#include +#include "options.h" /* Compilation switches */ +#include "cnst.h" /* Common constants */ +#include "prot_fx1.h" /* Function prototypes */ +#include "prot_fx2.h" /* Function prototypes */ + + +/*==========================================================================*/ +/* FUNCTION : void dec_acelp_2t32_fx () */ +/*--------------------------------------------------------------------------*/ +/* PURPOSE : */ +/* * 12 bits algebraic codebook decoder. */ +/* * 2 track x 32 positions per track = 64 samples. */ +/* * 12 bits --> 2 pulses in a frame of 64 samples. */ +/* * All pulses can have two (2) possible amplitudes: +1 or -1. */ +/* * Each pulse can have 32 possible positions. */ +/* * See cod2t32.c for more details of the algebraic code. */ +/*--------------------------------------------------------------------------*/ +/* INPUT ARGUMENTS : */ +/* _Word16 i_subfr, i : subframe index */ +/*--------------------------------------------------------------------------*/ +/* OUTPUT ARGUMENTS : */ +/* _Word16 code[] o : algebraic (fixed) codebook excitation Q12 */ +/*--------------------------------------------------------------------------*/ +/* INPUT/OUTPUT ARGUMENTS : */ +/*--------------------------------------------------------------------------*/ +/* RETURN ARGUMENTS : */ +/* _ None */ +/*--------------------------------------------------------------------------*/ +/* CALLED FROM : */ +/*==========================================================================*/ + + +void dec_acelp_2t32_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + Word16 code[] /* o: algebraic (fixed) codebook excitation */ +) +{ + + Word16 index, i0, i1; + + index = (Word16) get_next_indice( st_fx, 12 ); + move16(); + + set16_fx( code, 0, L_SUBFR ); + + /*------------------------------------------------------------------------------------------* + * decode the positions and signs of pulses and build the codeword + *------------------------------------------------------------------------------------------*/ + + i0 = shl(s_and(shr(index, 6), NB_POS_FCB_2T-1), 1); + + i1 = add(shl(s_and(index, NB_POS_FCB_2T-1), 1), 1); + + + code[i0] = -512; + move16(); + if (s_and(index, 0x800) == 0) + { + code[i0] = 512; + move16(); + } + + code[i1] = -512; + move16(); + if (s_and(index, 0x20) == 0) + { + code[i1] = 512; + move16(); + } + +} + + +/*==========================================================================*/ +/* FUNCTION : void dec_acelp_1t64_fx () */ +/*--------------------------------------------------------------------------*/ +/* PURPOSE : * 7 bits algebraic codebook. */ +/* * 1 track x 64 positions per track = 64 samples. */ +/* * The pulse can have 64 possible positions and two (2) possible amplitudes: +1 or -1.*/ +/*--------------------------------------------------------------------------*/ +/* INPUT ARGUMENTS : */ +/* _Word16 i_subfr, i : subframe index */ +/*--------------------------------------------------------------------------*/ +/* OUTPUT ARGUMENTS : */ +/* _Word16 code[] o : algebraic (fixed) codebook excitation Q12 */ +/*--------------------------------------------------------------------------*/ +/* INPUT/OUTPUT ARGUMENTS : */ +/*--------------------------------------------------------------------------*/ +/* RETURN ARGUMENTS : */ +/* _ None */ +/*--------------------------------------------------------------------------*/ +/* CALLED FROM : */ +/*==========================================================================*/ +void dec_acelp_1t64_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + Word16 code[], /* o: algebraic (fixed) codebook excitation Q12*/ + const Word16 L_subfr /* i : sub frame lenght*/ + +) +{ + Word16 pos,sgn; + + /*-----------------------------------------------------------------* + * decode the positions and signs of pulses and build the codeword + *-----------------------------------------------------------------*/ + IF ( EQ_16(L_subfr, L_SUBFR) ) + { + pos = (Word16)get_next_indice(st_fx, 7); + move16(); + } + ELSE /* L_subfr == 2*L_SUBFR */ + { + pos = (Word16)get_next_indice(st_fx, 8); + move16(); + } + + sgn = -512; + move16(); + IF( GE_16(pos, L_subfr)) + { + pos = sub(pos, L_subfr); + move16(); + sgn = 512; + move16(); + } + set16_fx(code, 0, L_subfr); + code[pos] = sgn; + move16(); + return; + +} diff --git a/lib_dec/dec4t64.c b/lib_dec/dec4t64.c index a0e969b1b097d7fc8ead8e7e66535ff51898d84c..59b1c9cb3c4ee72668dc3af72c95c135dd59d671 100644 --- a/lib_dec/dec4t64.c +++ b/lib_dec/dec4t64.c @@ -132,7 +132,7 @@ void dec_acelp_4t64( { indexing_indices[i] = get_next_indice( st, bitcnt ); } - D_ACELP_indexing( code, config, NB_TRACK_FCB_4T, indexing_indices, &st->BER_detect ); + D_ACELP_indexing_ivas( code, config, NB_TRACK_FCB_4T, indexing_indices, &st->BER_detect ); } else { @@ -740,7 +740,7 @@ static void fcb_decode_PI( * Read FCB index * *---------------------------------------------------------------------*/ -void D_ACELP_decode_43bit( +void D_ACELP_decode_43bit_flt( uint16_t idxs[], float code[], int16_t *pulsestrack ) diff --git a/lib_dec/dec4t64_fx.c b/lib_dec/dec4t64_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..9b25d08ffebd2d21958b031ca2c53f026f907698 --- /dev/null +++ b/lib_dec/dec4t64_fx.c @@ -0,0 +1,1035 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ +#include +#include "options.h" /* Compilation switches */ +#include "cnst.h" /* Common constants */ +#include "prot_fx1.h" /* Function prototypes */ +#include "prot_fx2.h" /* Function prototypes */ +#include "rom_com.h" /* Static table prototypes */ +#include "assert.h" /* Static table prototypes */ + +/*-------------------------------------------------------------------* + * Local functions + *-------------------------------------------------------------------*/ +static void add_pulses_fx(const Word16 pos[],const Word16 nb_pulse, const Word16 track,Word16 code[]); +static void dec_1p_N1_fx(const Word32 index, const Word16 N, const Word16 offset, Word16 pos[] ); +static void dec_2p_2N1_fx(const Word32 index, const Word16 N, const Word16 offset, Word16 pos[] ); +static void dec_3p_3N1_fx(const Word32 index, const Word16 N, const Word16 offset, Word16 pos[] ); +static void dec_4p_4N1_fx(const Word32 index, const Word16 N, const Word16 offset, Word16 pos[] ); +static void dec_4p_4N_fx(const Word32 index, const Word16 N, const Word16 offset, Word16 pos[]); +static void dec_5p_5N_fx(const Word32 index,const Word16 N,const Word16 offset,Word16 pos[]); +static void dec_6p_6N2_fx(const Word32 index,const Word16 N,const Word16 offset,Word16 pos[]); +static void fcb_decode_PI_fx(Word32 code_index,Word16 sector_6p[],Word16 pulse_num); + + +/*==========================================================================*/ +/* FUNCTION : void dec_acelp_4t64_fx () */ +/*--------------------------------------------------------------------------*/ +/* PURPOSE : */ +/* * 20, 36 bits algebraic codebook decoder. */ +/* * 4 tracks x 16 positions per track = 64 samples. */ +/* * 20 bits --> 4 pulses in a frame of 64 samples. */ +/* * 36 bits --> 8 pulses in a frame of 64 samples. */ +/* * All pulses can have two (2) possible amplitudes: +1 or -1. */ +/* * Each pulse can have sixteen (16) possible positions. */ +/* * See cod4t64.c for more details of the algebraic code. */ +/*--------------------------------------------------------------------------*/ +/* INPUT ARGUMENTS : */ +/* _Word16 i_subfr i : subframe index */ +/* _Word16 nbbits i : number of bits per codebook */ +/* _Word16 FCB_5Sx4T_fla i : 5Sx4Track flag for PI */ +/*--------------------------------------------------------------------------*/ +/* OUTPUT ARGUMENTS : */ +/* _Word16 code[] o : algebraic (fixed) codebook excitation Q12 */ +/* _Word16 index_buf_4T[] o : 5Sx4Track buffer for PI */ +/*--------------------------------------------------------------------------*/ +/* INPUT/OUTPUT ARGUMENTS : */ +/*--------------------------------------------------------------------------*/ +/* RETURN ARGUMENTS : */ +/* _ None */ +/*--------------------------------------------------------------------------*/ +/* CALLED FROM : */ +/*==========================================================================*/ +void dec_acelp_4t64_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + Word16 nbbits, /* i : number of bits per codebook */ + Word16 code[], /* o : algebraic (fixed) codebook excitation Q9*/ + const Word16 Opt_AMR_WB +) +{ + Word16 i, k, pos[7]; + Word32 L_index; + Word32 ind1[NB_TRACK_FCB_4T]; + PulseConfig config; + Word16 indexing_indices[6], wordcnt, bitcnt, index2; + + IF ( !Opt_AMR_WB ) + { + SWITCH (nbbits) + { + case 20: + config.nb_pulse = 4; + move16(); + BREAK; + + case 28: + config.nb_pulse = 6; + move16(); + BREAK; + + case 36: + config.nb_pulse = 8; + move16(); + BREAK; + + case 43: + config.nb_pulse = 10; + move16(); + BREAK; + + case 50: + config.nb_pulse = 12; + move16(); + BREAK; + + case 62: + config.nb_pulse = 16; + move16(); + BREAK; + + case 87: + config.nb_pulse = 26; + move16(); + BREAK; + } + + config.bits = nbbits; + move16(); + config.codetrackpos = TRACKPOS_FIXED_FIRST; + move16(); + + + wordcnt = shr(nbbits, 4); + bitcnt = s_and(nbbits, 15); + FOR ( i = 0; i < wordcnt; i++ ) + { + indexing_indices[i] = get_next_indice( st_fx, 16 ); + move16(); + } + IF ( bitcnt ) + { + indexing_indices[i] = get_next_indice( st_fx, bitcnt ); + move16(); + } + + D_ACELP_indexing( code, config, NB_TRACK_FCB_4T, indexing_indices, &st_fx->BER_detect ); + } + ELSE + { + FOR (i=0; i> N) & 1); */ + i = L_shr(index, N) & 1L; + + if (i != 0) + { + pos1 = add(pos1, NB_POS_FCB_4T); + } + pos[0] = pos1; + move16(); +} +/*-------------------------------------------------------* + * dec_2p_2N1() + * + * Decode 2 pulses with 2*N+1 bits: + *-------------------------------------------------------*/ + +void dec_2p_2N1_fx( + const Word32 index, /* i: quantization index */ + const Word16 N, /* i: nb. of bits */ + const Word16 offset, /* i: pulse position offset */ + Word16 pos[] /* o: pulse position */ +) +{ + + Word16 pos1, pos2, tmp; + Word32 mask, i; + + mask = L_deposit_l(sub(shl(1, N), 1)); /* mask = ((1<> N) & mask) + offset); */ + logic16(); + pos1 = extract_l(L_add((L_shr(index, N) & mask), L_deposit_l(offset))); + + /* i = (index >> (2*N)) & 1; */ + tmp = shl(N, 1); + i = L_and(L_shr(index, tmp), 1L); + + /* pos2 = ((index & mask) + offset); */ + pos2 = add(extract_l(index & mask), offset); + logic16(); + + + IF (LT_16(pos2, pos1)) + { + IF (i != 0) + { + pos1 = add(pos1, NB_POS_FCB_4T); + } + ELSE + { + pos2 = add(pos2, NB_POS_FCB_4T); + } + } + ELSE + { + IF (i != 0) + { + pos1 = add(pos1, NB_POS_FCB_4T); + pos2 = add(pos2, NB_POS_FCB_4T); + } + } + + pos[0] = pos1; + move16(); + pos[1] = pos2; + move16(); + + return; + +} +/*-------------------------------------------------------* +* Dec_3p_3N1 +* +* Decode 3 pulses with 3*N+1 bits: +*-------------------------------------------------------*/ +static void dec_3p_3N1_fx( + const Word32 index, /* i : quantization index */ + const Word16 N, /* i : nb. of bits */ + const Word16 offset, /* i : pulse position offset */ + Word16 pos[] /* o : pulse position */ +) +{ + Word16 j, tmp; + Word32 mask, idx; + + tmp = sub(shl(N, 1), 1); /* mask = ((1<<((2*N)-1))-1); */ + mask = L_sub(L_shl(1L, tmp), 1L); + + idx = L_and(index, mask); + j = offset; + move16(); + tmp = sub(shl(N, 1), 1); + + logic16(); + IF ((L_shr(index, tmp) & 1L) != 0) + { + /* IF (((index >> ((2*N)-1)) & 1) == 1){ */ + j = add(j, shl(1, sub(N, 1))); /* j += (1<<(N-1)); */ + } + dec_2p_2N1_fx(idx, sub(N, 1), j, pos); + + mask = sub(shl(1, add(N, 1)), 1); /* mask = ((1<<(N+1))-1); */ + tmp = shl(N, 1); /* idx = (index >> (2*N)) & mask; */ + idx = L_shr(index, tmp) & mask; + logic16(); + + dec_1p_N1_fx(idx, N, offset, pos + 2); +} + +/*-------------------------------------------------------* + * Dec_4p_4N1 + * + * Decode 4 pulses with 4*N+1 bits: + *-------------------------------------------------------*/ +static void dec_4p_4N1_fx( + const Word32 index, /* i : quantization index */ + const Word16 N, /* i : nb. of bits */ + const Word16 offset, /* i : pulse position offset */ + Word16 pos[] /* o : pulse position */ +) +{ + Word16 j, tmp; + Word32 mask, idx; + + tmp = sub(shl(N, 1), 1); /* mask = ((1<<((2*N)-1))-1); */ + mask = L_sub(L_shl(1L, tmp), 1L); + idx = L_and(index, mask); + j = offset; + move16(); + tmp = sub(shl(N, 1), 1); + + logic16(); + IF((L_shr(index, tmp) & 1L) != 0L) + { + /* (((index >> ((2*N)-1)) & 1) == 1) */ + j = add(j, shl(1, sub(N, 1))); /* j += (1<<(N-1)); */ + } + dec_2p_2N1_fx(idx, sub(N, 1), j, pos); + + + tmp = add(shl(N, 1), 1); /* mask = ((1<<((2*N)+1))-1); */ + mask = L_sub(L_shl(1L, tmp), 1L); + idx = L_shr(index, shl(N, 1)) & mask; + logic16();/* idx = (index >> (2*N)) & mask; */ + dec_2p_2N1_fx(idx, N, offset, pos + 2); /* Dec_2p_2N1(idx, N, offset, pos+2); */ +} + + +/*-------------------------------------------------------* +* Dec_4p_4N +* +* Decode 4 pulses with 4*N bits: +*-------------------------------------------------------*/ +static void dec_4p_4N_fx( + const Word32 index, /* i : quantization index */ + const Word16 N, /* i : nb. of bits */ + const Word16 offset, /* i : pulse position offset */ + Word16 pos[] /* o : pulse position */ +) +{ + Word16 j, n_1, tmp; + + n_1 = sub(N, 1); + j = add(offset, shl(1, n_1)); /* j = offset + (1 << n_1) */ + + tmp = sub(shl(N, 2), 2); + logic16(); + SWITCH (L_shr(index, tmp) & 3) + { + /* ((index >> ((4*N)-2)) & 3) */ + case 0: + tmp = add(shl(n_1, 2), 1); + + logic16(); + IF((L_shr(index, tmp) & 1) == 0) + { + /* (((index >> ((4*n_1)+1)) & 1) == 0) */ + dec_4p_4N1_fx(index, n_1, offset, pos); + } + ELSE + { + dec_4p_4N1_fx(index, n_1, j, pos); + } + BREAK; + case 1: + tmp = add(extract_l(L_shr(L_mult(3, n_1), 1)), 1); /* Dec_1p_N1((index>>((3*n_1)+1)), n_1, offset, pos) */ + dec_1p_N1_fx(L_shr(index, tmp), n_1, offset, pos); + dec_3p_3N1_fx(index, n_1, j, pos + 1); + move16(); + BREAK; + case 2: + tmp = add(shl(n_1, 1), 1); /* Dec_2p_2N1((index>>((2*n_1)+1)), n_1, offset, pos) */ + dec_2p_2N1_fx(L_shr(index, tmp), n_1, offset, pos); + dec_2p_2N1_fx(index, n_1, j, pos + 2); + move16(); + BREAK; + case 3: + tmp = add(n_1, 1); /* Dec_3p_3N1((index>>(n_1+1)), n_1, offset, pos) */ + dec_3p_3N1_fx(L_shr(index, tmp), n_1, offset, pos); + dec_1p_N1_fx(index, n_1, j, pos + 3); + move16(); + BREAK; + } +} + + +/*-------------------------------------------------------* + * Dec_5p_5N + * + * Decode 5 pulses with 5*N bits: + *-------------------------------------------------------*/ +static void dec_5p_5N_fx( + const Word32 index, /* i : quantization index */ + const Word16 N, /* i : nb. of bits */ + const Word16 offset, /* i : pulse position offset */ + Word16 pos[] /* o : pulse position */ +) +{ + Word16 j, n_1, tmp; + Word32 idx; + + n_1 = sub(N, 1); + j = add(offset, shl(1, n_1)); /* j = offset + (1 << n_1); */ + tmp = add(shl(N, 1), 1); /* idx = (index >> ((2*N)+1)); */ + idx = L_shr(index, tmp); + tmp = sub(extract_l(L_shr(L_mult(5, N), 1)), 1); /* ((5*N)-1)) */ + + logic16(); + IF ((L_shr(index, tmp) & 1) == 0) /* ((index >> ((5*N)-1)) & 1) */ + { + dec_3p_3N1_fx(idx, n_1, offset, pos); + dec_2p_2N1_fx(index, N, offset, pos + 3); + move16(); + } + ELSE + { + dec_3p_3N1_fx(idx, n_1, j, pos); + dec_2p_2N1_fx(index, N, offset, pos + 3); + move16(); + } +} + +/*-------------------------------------------------------* + * Dec_6p_6N_2 + * + * Decode 6 pulses with 6*N+2 bits: + *-------------------------------------------------------*/ +static void dec_6p_6N2_fx( + const Word32 index, /* i : quantization index */ + const Word16 N, /* i : nb. of bits */ + const Word16 offset, /* i : pulse position offset */ + Word16 pos[] /* o : pulse position */ +) +{ + Word16 j, n_1, offsetA, offsetB, n_6; + + n_1 = sub(N, 1); + j = add(offset, shl(1, n_1)); /* j = offset + (1 << n_1); */ + n_6 = extract_l(L_mult0(N, 6)); + + /* !! N and n_1 are constants -> it doesn't need to be operated by Basic Operators */ + + offsetA = offsetB = j; + move16(); + logic16(); + IF ((L_shr(index, sub(n_6, 5)) & 1L) == 0) + { + /* IF (((index >> ((6*N)-5)) & 1) == 0) */ + offsetA = offset; + move16(); + } + ELSE + { + offsetB = offset; + move16(); + } + + + logic16(); + SWITCH (L_shr(index, sub(n_6, 4)) & 3) + { + /* (index >> ((6*N)-4)) & 3 */ + case 0: + dec_5p_5N_fx(L_shr(index, N), n_1, offsetA, pos); /* Dec_5p_5N(index>>N, n_1, offsetA, pos); */ + dec_1p_N1_fx(index, n_1, offsetA, pos + 5); + move16(); + BREAK; + case 1: + dec_5p_5N_fx(L_shr(index, N), n_1, offsetA, pos); /* Dec_5p_5N(index>>N, n_1, offsetA, pos); */ + dec_1p_N1_fx(index, n_1, offsetB, pos + 5); + move16(); + BREAK; + case 2: + dec_4p_4N_fx(L_shr(index, add(shl(n_1,1),1)), n_1, offsetA, pos); /* Dec_4p_4N(index>>((2*n_1)+1 ), n_1, offsetA, pos); */ + dec_2p_2N1_fx(index, n_1, offsetB, pos + 4); + move16(); + BREAK; + case 3: + dec_3p_3N1_fx(L_shr(index, add(add(shl(n_1, 1),n_1), 1)), n_1, offset, pos); /* Dec_3p_3N1(index>>((3*n_1)+ 1), n_1, offset, pos); */ + dec_3p_3N1_fx(index, n_1, j, pos + 3); + move16(); + BREAK; + } +} + +static Word32 fcb_decode_class_all_p_fx( /* o: The index of pulse positions */ + Word32 *code_index, /* i: fcb index information */ + Word16 sector_6p_num[], /* o: Number of pulses for each position */ + Word16 pulse_num, /* i: Number of pulses on a track. */ + Word16 *pos_num /* o: Number of positions which have pulses on the track.*/ +) +{ + Word16 i; + Word32 mn9,j,k; + Word16 pulse_pos_num; + Word32 L_tmp, L_tmp1; + FOR (i=1; i<=pulse_num; i++) + { + IF (LT_32((*code_index),PI_offset[pulse_num][i])) + { + BREAK; + } + } + + /* (*code_index) -= PI_offset[pulse_num][i-1];*/ + (*code_index) = L_sub((*code_index),PI_offset[pulse_num][i-1]); + + /*pulse_pos_num = pulse_num - i + 2;*/ + pulse_pos_num = add(sub(pulse_num , i) , 2); + + /* j = (*code_index)>>pulse_pos_num;*/ + j = L_shr((*code_index) , pulse_pos_num); + IF(LT_32(j,PI_select_table[16][pulse_pos_num])) + { + k = L_deposit_l(0); + mn9 = L_add(j, 0); + } + ELSE + { + L_tmp = L_deposit_l(0); + L_tmp1 = L_add(j, 0); + WHILE(GE_32(L_tmp1,PI_select_table[16][pulse_pos_num])) + { + L_tmp = L_add(L_tmp,1); + L_tmp1 = L_sub(L_tmp1,PI_select_table[16][pulse_pos_num]); + } + k = L_add(L_tmp, 0); + mn9 = L_add(L_tmp1, 0); + } + /* mn9 = Mult_32_32(sub(j , k) , PI_select_table[16][pulse_pos_num]);*/ + + test(); + IF ( (LT_16( pulse_pos_num,pulse_num))&&(GT_16(pulse_pos_num,1))) + { + FOR (i=0; i= k; l+=2); + + if (GT_32(k,PI_select_table[L_sub(17,l)][temp])) + { + l = L_sub(l,1); + } + + /* k = PI_select_table[17-l][temp--] - k ;*/ + k = L_sub(PI_select_table[L_sub(17,l)][temp--] , k); + pos_vector[i] = extract_l(L_sub(l,1)); + } + pos_vector[i] = extract_l(L_add(l,k)); + + return; +} + +static void fcb_decode_PI_fx( /* o: return pulse position number */ + Word32 code_index, /* i: fcb index information */ + Word16 sector_6p[], /* o: decoded pulse position */ + Word16 pulse_num /* i: pulse number for the track */ +) +{ + Word16 i,l, j; + Word32 mn9; + Word16 pulse_pos_num; + Word16 sector_6p_temp[7], sector_6p_num_temp[7]; + Word16 *sector_6p_ptr0; + Word16 *sector_6p_ptr1; + + /*get the position number and the pulse number on every position */ + mn9 = fcb_decode_class_all_p_fx(&code_index, sector_6p_num_temp, pulse_num, &pulse_pos_num); + + /* rebuild the vector*/ + /* decode the pulse position not same to the others*/ + fcb_decode_position_fx(mn9, sector_6p_temp, pulse_pos_num); + FOR (i=pulse_pos_num-1; i>=0; i--) + { + /*sector_6p_temp[i] += ((code_index&0x1)<<4) ;*/ + sector_6p_temp[i] = add(sector_6p_temp[i],extract_l(L_shl((code_index&0x1),4))) ; + move16(); + /*code_index = code_index>>1;*/ + code_index = L_shr(code_index , 1); + + } + + /* decode the pulse position maybe some pulse position same to other pulse */ + sector_6p_ptr0 = §or_6p[pulse_num]; + sector_6p_ptr1 = §or_6p_temp[pulse_pos_num]; + FOR (i=0; i> N) & 1; + + if (i == 1) + { + pos1 += nb_pos; + } + + pos[0] = pos1; + + return; +} + +/*-------------------------------------------------------* + * add_pulses() + * + * Add decoded pulses to the codeword + *-------------------------------------------------------*/ + +static void add_pulses_L_subfr( + const int16_t nb_pos, /* i : number of positions */ + const int16_t pos[], /* i : pulse position */ + const int16_t nb_pulse, /* i : nb. of pulses */ + const int16_t track, /* i : no. of the tracks */ + float code[] /* i/o: decoded codevector */ +) +{ + int16_t i, k; + + for (k = 0; k < nb_pulse; k++) + { + i = ((pos[k] & (nb_pos - 1)) * NB_TRACK_FCB_4T) + track; + if ((pos[k] & nb_pos) == 0) + { + code[i] += 1.0f; + } + else + { + code[i] -= 1.0f; + } + } + + return; +} + +/*----------------------------------------------------------------------------------* + * dec_acelp_fast() + * + * fast algebraic codebook decoder + *----------------------------------------------------------------------------------*/ + +void dec_acelp_fast( + Decoder_State* st, /* i/o: decoder state structure */ + const int16_t cdk_index, /* i : codebook index */ + float code[], /* o : algebraic (fixed) codebook excitation */ + const int16_t L_subfr /* i : subframe length */ +) +{ + int16_t k, pos[7], skip_track; + int32_t L_index; + PulseConfig config; + + skip_track = -1; + set_f(code, 0.0f, L_subfr); + + if (L_subfr == L_SUBFR) + { + config = PulseConfTable[cdk_index]; + + if (cdk_index == 2) + { + dec_acelp_2t32(st, code); + } + else if (config.nb_pulse == 2) + { + /* 10 bits, 2 pulses, 4 tracks 1010 (used only even tracks) */ + for (k = 0; k < NB_TRACK_FCB_4T - 1; k += 2) + { + L_index = get_next_indice(st, 5); + dec_1p_N1(L_index, 4, 0, pos); + add_pulses(pos, 1, k, code); + } + } + else if (config.nb_pulse == 3) + { + if (config.codetrackpos == TRACKPOS_FIXED_FIRST) + { + /* 15 bits, 3 pulses, 4 tracks 1110 fixed track to first ? */ + for (k = 0; k < NB_TRACK_FCB_4T - 1; k++) + { + L_index = get_next_indice(st, 5); + dec_1p_N1(L_index, 4, 0, pos); + add_pulses(pos, 1, k, code); + } + } + else if (config.codetrackpos == TRACKPOS_FREE_THREE) + { + /* 17 bits, 3 pulses, 4 tracks (used all tracks) - 1110, 1101, 1011, 0111 */ + skip_track = get_next_indice(st, 2); + for (k = 0; k < NB_TRACK_FCB_4T; k++) + { + if (k != skip_track) + { + L_index = get_next_indice(st, 5); + dec_1p_N1(L_index, 4, 0, pos); + add_pulses(pos, 1, k, code); + } + } + } + } + else + { + if (config.bits == 20) + { + skip_track = -1; + } + else if (config.codetrackpos == TRACKPOS_FIXED_FIRST) + { + skip_track = 0; + } + else if (config.codetrackpos == TRACKPOS_FREE_ONE) + { + skip_track = get_next_indice(st, 2); + } + + for (k = 0; k < NB_TRACK_FCB_4T; k++) + { + if (k == skip_track) + { + L_index = get_next_indice(st, 9); + dec_2p_2N1(L_index, 4, 0, pos); + add_pulses(pos, 2, k, code); + } + else + { + L_index = get_next_indice(st, 5); + dec_1p_N1(L_index, 4, 0, pos); + add_pulses(pos, 1, k, code); + } + } + } + } + else /* L_subfr == 2*L_SUBFR */ + { + config.bits = cdk_index; + + if (cdk_index == 14) + { + /* 14 bits, 2 pulses, 2 tracks: 11 (used all tracks) */ + int16_t index, i0, i1; + + index = get_next_indice(st, 14); + + i0 = ((index >> 7) & (NB_POS_FCB_2T_128 - 1)) * NB_TRACK_FCB_2T; + i1 = ((index & (NB_POS_FCB_2T_128 - 1)) * NB_TRACK_FCB_2T) + 1; + + code[i0] = -1.0f; + if ((index & 0x2000) == 0) + { + code[i0] = 1.0f; + } + + code[i1] = -1.0f; + if ((index & 0x40) == 0) + { + code[i1] = 1.0f; + } + } + else if (cdk_index == 12) + { + /* 12 bits, 2 pulses, 4 tracks: 1010 (used only even tracks) */ + for (k = 0; k < NB_TRACK_FCB_4T - 1; k += 2) + { + L_index = get_next_indice(st, 6); + dec_1p_N1_L_subfr(L_index, NB_POS_FCB_4T_128, 5, pos); + add_pulses_L_subfr(NB_POS_FCB_4T_128, pos, 1, k, code); + } + } + else if (cdk_index == 18) + { + /* 18 bits, 3 pulses, 4 tracks: 1110 (used first three tracks) */ + for (k = 0; k < NB_TRACK_FCB_4T - 1; k++) + { + L_index = get_next_indice(st, 6); + dec_1p_N1_L_subfr(L_index, NB_POS_FCB_4T_128, 5, pos); + add_pulses_L_subfr(NB_POS_FCB_4T_128, pos, 1, k, code); + } + } + else if (cdk_index == 20) + { + /* 20 bits, 3 pulses, 4 tracks (used all tracks): 1110, 1101, 1011, 0111 */ + skip_track = get_next_indice(st, 2); + for (k = 0; k < NB_TRACK_FCB_4T; k++) + { + if (k != skip_track) + { + L_index = get_next_indice(st, 6); + dec_1p_N1_L_subfr(L_index, NB_POS_FCB_4T_128, 5, pos); + add_pulses_L_subfr(NB_POS_FCB_4T_128, pos, 1, k, code); + } + } + } + else if (cdk_index == 24) + { + /* 24 bits, 4 pulses, 4 tracks: 1111 */ + for (k = 0; k < NB_TRACK_FCB_4T; k++) + { + L_index = get_next_indice(st, 6); + dec_1p_N1_L_subfr(L_index, NB_POS_FCB_4T_128, 5, pos); + add_pulses_L_subfr(NB_POS_FCB_4T_128, pos, 1, k, code); + } + } + } + + return; +} +#endif \ No newline at end of file diff --git a/lib_dec/dec_LPD.c b/lib_dec/dec_LPD.c index 8c984392606e05e88fcbd27c389640d540fedd0e..a6a5ee626b7c438c878157cd1d66b7609801787f 100644 --- a/lib_dec/dec_LPD.c +++ b/lib_dec/dec_LPD.c @@ -47,12 +47,12 @@ /*-------------------------------------------------------------------* - * decoder_LPD() + * decoder_LPD_flt() * * Core decoder MODE2 *--------------------------------------------------------------------*/ -void decoder_LPD( +void decoder_LPD_flt( Decoder_State *st, /* i/o: decoder memory state pointer */ float signal_out[], /* o : signal with LPD delay (7 subfrs) */ float signal_outFB[], /* o : synthesis @output_FS */ @@ -150,7 +150,7 @@ void decoder_LPD( tcx_last_overlap_mode = st->hTcxCfg->tcx_last_overlap_mode; tcx_current_overlap_mode = st->hTcxCfg->tcx_curr_overlap_mode; - dec_prm( st, param, param_lpc, total_nbbits, bitsRead ); + dec_prm_ivas( st, param, param_lpc, total_nbbits, bitsRead ); if ( !st->rate_switching_init && ( st->last_codec_mode ) == MODE2 && st->BER_detect ) { @@ -163,14 +163,14 @@ void decoder_LPD( st->flagGuidedAcelp = 0; st->nbLostCmpt++; st->core_brate = st->last_core_brate; - st->core = GetPLCModeDecision( st ); + st->core = GetPLCModeDecision_flt( st ); } } else { if ( st->use_partial_copy && st->rf_frame_type >= RF_TCXFD && st->rf_frame_type <= RF_TCXTD2 ) { - dec_prm( st, param, param_lpc, total_nbbits, bitsRead ); + dec_prm_ivas( st, param, param_lpc, total_nbbits, bitsRead ); } if ( st->nbLostCmpt > 1 ) @@ -179,7 +179,7 @@ void decoder_LPD( } /* PLC: [Common: mode decision] * PLC: Decide which Concealment to use. Update pitch lags if needed */ - st->core = GetPLCModeDecision( st ); + st->core = GetPLCModeDecision_flt( st ); } /* PLC: [Common: Memory update] @@ -215,11 +215,11 @@ void decoder_LPD( /* first stage VQ, 8 bits; reuse TCX high rate codebook */ set_f( lsf_q_1st_rf, 0.0f, M ); - vlpc_1st_dec( param_lpc[0], lsf_q_1st_rf, st->sr_core ); + vlpc_1st_dec_flt( param_lpc[0], lsf_q_1st_rf, st->sr_core ); /* second stage vq */ /* quantized lsf from two stages */ - v_add( lsf_q_1st_rf, lsf_q_diff_cb_8b_rf + M * param_lpc[1], lsf_q_rf, M ); + v_add( lsf_q_1st_rf, lsf_q_diff_cb_8b_rf_flt + M * param_lpc[1], lsf_q_rf, M ); v_sort_float( lsf_q_rf, 0, M - 1 ); reorder_lsf( lsf_q_rf, LSF_GAP, M, st->sr_core ); @@ -270,7 +270,7 @@ void decoder_LPD( mvr2r( st->lsf_old, &lsf[0], M ); mvr2r( st->lsp_old, &lsp[0], M ); - D_lsf_tcxlpc( param_lpc, &lsf[M], lspind, st->narrowBand, tcx_lpc_cdk, st->mem_MA ); + D_lsf_tcxlpc_ivas( param_lpc, &lsf[M], lspind, st->narrowBand, tcx_lpc_cdk, st->mem_MA ); lsf2lsp( &lsf[M], &lsp[M], M, st->sr_core ); @@ -292,11 +292,11 @@ void decoder_LPD( /* Unquantize LPC */ if ( st->core == TCX_20_CORE ) { - lpc_unquantize( st, lsf, lsp, param_lpc, lspmid, lsfmid, AUDIO, &LSF_Q_prediction ); + lpc_unquantize_flt( st, lsf, lsp, param_lpc, lspmid, lsfmid, AUDIO, &LSF_Q_prediction ); } else { - lpc_unquantize( st, lsf, lsp, param_lpc, lspmid, lsfmid, st->coder_type, &LSF_Q_prediction ); + lpc_unquantize_flt( st, lsf, lsp, param_lpc, lspmid, lsfmid, st->coder_type, &LSF_Q_prediction ); if ( st->prev_use_partial_copy && st->last_core == ACELP_CORE && st->core == ACELP_CORE && st->prev_rf_frame_type >= RF_GENPRED && st->coder_type == UNVOICED ) { @@ -347,9 +347,9 @@ void decoder_LPD( } - lsfBase = PlcGetlsfBase( st->lpcQuantization, st->narrowBand, st->sr_core ); + lsfBase = PlcGetlsfBase_flt( st->lpcQuantization, st->narrowBand, st->sr_core ); - dlpc_bfi( st->L_frame, lsfnew_uw, st->lsfold_uw_float, st->last_good, st->nbLostCmpt, st->mem_MA, st->mem_AR, &( st->stab_fac ), st->lsf_adaptive_mean, st->numlpc, st->lsf_cng_float, st->plcBackgroundNoiseUpdated, st->lsf_q_cng_float, st->old_lsf_q_cng_float, lsfBase ); + dlpc_bfi_flt( st->L_frame, lsfnew_uw, st->lsfold_uw_float, st->last_good, st->nbLostCmpt, st->mem_MA, st->mem_AR, &( st->stab_fac ), st->lsf_adaptive_mean, st->numlpc, st->lsf_cng_float, st->plcBackgroundNoiseUpdated, st->lsf_q_cng_float, st->old_lsf_q_cng_float, lsfBase ); hTcxDec->envWeighted = 0; @@ -430,7 +430,7 @@ void decoder_LPD( if ( !bfi && ( st->dec_glr_idx == 1 || ( !( st->safety_net ) && enr_new >= 256.f && enr_new > 2 * enr_old ) ) && st->prev_bfi ) { - RecLpcSpecPowDiffuseLc( &lsp[M], &lsp[0], &lsf[M], st, st->dec_glr_idx == 1 ? 1 : 0 ); + RecLpcSpecPowDiffuseLc_flt( &lsp[M], &lsp[0], &lsf[M], st, st->dec_glr_idx == 1 ? 1 : 0 ); int_lsp( L_frame, &lsp[0], &lsp[M], Aq, M, interpol_frac_12k8, 0 ); mvr2r( &lsf[M], lsfnew_uw, M ); } @@ -475,7 +475,7 @@ void decoder_LPD( if ( bfi && st->last_core != ACELP_CORE ) { /* PLC: [TCX: TD PLC] */ - con_tcx( st, &synthFB[0], -1.f, NULL, 0, NULL ); + con_tcx_flt( st, &synthFB[0], -1.f, NULL, 0, NULL ); lerp_flt( synthFB, synth, st->L_frame, st->hTcxDec->L_frameTCX ); st->con_tcx = 1; set_f( &st->mem_pitch_gain_float[2], st->lp_gainp, st->nb_subfr ); @@ -499,13 +499,13 @@ void decoder_LPD( { /* PLC: [ACELP: general] * PLC: Use the ACELP like concealment */ - con_acelp( Aq, st->core_ext_mode, &synth[0], pitch, pit_gain, st->stab_fac, st, pitch_buf, voice_factors, ptr_bwe_exc ); + con_acelp_flt( Aq, st->core_ext_mode, &synth[0], pitch, pit_gain, st->stab_fac, st, pitch_buf, voice_factors, ptr_bwe_exc ); mvr2r( &st->mem_pitch_gain_float[2], &st->mem_pitch_gain_float[st->nb_subfr + 2], st->nb_subfr ); set_zero( &st->mem_pitch_gain_float[2], st->nb_subfr ); } else { - decoder_acelp( st, prm, Aq, st->acelp_cfg, &synth[0], pitch, pit_gain, st->stab_fac, pitch_buf, voice_factors, LSF_Q_prediction, ptr_bwe_exc ); + decoder_acelp_flt( st, prm, Aq, st->acelp_cfg, &synth[0], pitch, pit_gain, st->stab_fac, pitch_buf, voice_factors, LSF_Q_prediction, ptr_bwe_exc ); if ( st->flagGuidedAcelp > 0 ) { @@ -528,7 +528,7 @@ void decoder_LPD( /* PLC: [TCX: Tonal Concealment] */ /* Signal that this frame is not TCX */ - TonalMDCTConceal_UpdateState( st->hTonalMDCTConc, 0, 0, 0, 0 ); + TonalMDCTConceal_UpdateState_ivas( st->hTonalMDCTConc, 0, 0, 0, 0 ); if ( !bfi ) { @@ -566,7 +566,7 @@ void decoder_LPD( if ( !bfi && st->prev_bfi && !( st->safety_net ) && st->rate_switching_reset ) { /* diffuse LPC power on rate switching*/ - RecLpcSpecPowDiffuseLc( &lsp[M], &lsp[0], &lsf[M], st, 0 ); + RecLpcSpecPowDiffuseLc_flt( &lsp[M], &lsp[0], &lsf[M], st, 0 ); int_lsp( L_frame, &lsp[0], &lsp[M], Aq, M, interpol_frac_12k8, 0 ); mvr2r( &lsf[M], lsfnew_uw, M ); } @@ -588,7 +588,7 @@ void decoder_LPD( } /* TCX decoder */ - decoder_tcx( st, prm, Aq, Aind, &synth[0], &synthFB[0], bfi, 0, 0 ); + decoder_tcx_flt( st, prm, Aq, Aind, &synth[0], &synthFB[0], bfi, 0, 0 ); } /*--------------------------------------------------------------------------------* @@ -611,10 +611,10 @@ void decoder_LPD( } lsp2a_stab( &lsp[( k + 1 ) * M], Aq, M ); - IGFDecRestoreTCX10SubFrameData( st->hIGFDec, k ); + IGFDecRestoreTCX10SubFrameData_flt( st->hIGFDec, k ); /* TCX decoder */ - decoder_tcx( st, prm, Aq, Aind, &synth[k * L_frame / 2], &synthFB[k * L_frameTCX / 2], bfi, k, 0 ); + decoder_tcx_flt( st, prm, Aq, Aind, &synth[k * L_frame / 2], &synthFB[k * L_frameTCX / 2], bfi, k, 0 ); } } @@ -640,10 +640,10 @@ void decoder_LPD( if ( !bfi ) { - TonalMDCTConceal_SaveTimeSignal( st->hTonalMDCTConc, synthFB, L_frameTCX ); + TonalMDCTConceal_SaveTimeSignal_ivas( st->hTonalMDCTConc, synthFB, L_frameTCX ); } - decoder_tcx_post( st, synth, synthFB, Aq, bfi, 0 ); + decoder_tcx_post_flt( st, synth, synthFB, Aq, bfi, 0 ); if ( st->core == TCX_20_CORE ) { @@ -763,7 +763,7 @@ void decoder_LPD( st->last_is_cng = 0; /* Postfiltering */ - post_decoder( st, synth_buf, pit_gain, pitch, signal_out, bpf_noise_buf ); + post_decoder_flt( st, synth_buf, pit_gain, pitch, signal_out, bpf_noise_buf ); if ( signal_outFB ) { @@ -779,7 +779,7 @@ void decoder_LPD( if ( st->core == ACELP_CORE ) /* may happen only if bfi==1 */ { - set_state( st->hPlcInfo->Transient, st->core, MAX_POST_LEN ); + set_state_ivas( st->hPlcInfo->Transient, st->core, MAX_POST_LEN ); } } diff --git a/lib_dec/dec_LPD_fx.c b/lib_dec/dec_LPD_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..afa4a82a0a573e0d6f02c3f69624d92fdacffec4 --- /dev/null +++ b/lib_dec/dec_LPD_fx.c @@ -0,0 +1,970 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + + +#include +#include +#include "options.h" +#include "prot_fx1.h" +#include "prot_fx2.h" +#include "basop_util.h" +#include "rom_com.h" + +/* #if defined(_WIN32) && (_MSC_VER <= 1200) /\* disable global optimizations to overcome an internal compiler error *\/ */ +#if defined(_MSC_VER) && (_MSC_VER <= 1200) /* disable global optimizations to overcome an internal compiler error */ +#pragma optimize("g", off) +#endif + +/*-------------------------------------------------------------------* +* decoder_LPD() +* +* Core decoder MODE2 +*--------------------------------------------------------------------*/ + +void decoder_LPD( + Word16 signal_out[], /* output: signal with LPD delay (7 subfrs) */ + Word16 signal_outFB[], /* o : synthesis @output_FS */ + Word16 *total_nbbits, /* i/o: number of bits / decoded bits */ + Decoder_State *st, /* i/o: decoder memory state pointer */ + Word16 * bpf_noise_buf, /* i/o: BPF noise buffer */ + Word16 bfi, /* i : BFI flag */ + Word16 *bitsRead, /* o : number of read bits */ + Word16 param[], /* o : buffer of parameters */ + Word16 *pitch_buf, /* i/o: floating pitch values for each subfr*/ + Word16 *voice_factors, /* o : voicing factors */ + Word16 *ptr_bwe_exc /* o : excitation for SWB TBE */ +) +{ + Word16 *param_lpc; + Word16 synth_buf[OLD_SYNTH_SIZE_DEC+L_FRAME_PLUS+M]; + Word16 *synth; + Word16 synth_bufFB[OLD_SYNTH_SIZE_DEC+L_FRAME_PLUS+M]; + Word16 *synthFB; + Word16 lsf[(NB_DIV+1)*M],lsp[(NB_DIV+1)*M],lspmid[M],lsfmid[M]; + Word16 Aq[(NB_SUBFR16k+1)*(M+1)]; /* Dyn RAM: it can be reduced by M+1 if insert branch for nb_subfr==5*/ + Word16 pitch[NB_SUBFR16k]; + Word16 pit_gain[NB_SUBFR16k]; + Word16 i, k, *prm; + Word16 L_frame,nb_subfr; + Word16 L_frameTCX; + Word16 Aind[M+1], lspind[M]; + Word16 tmp_old[M+1], tmp_new[M+1], enr_old, enr_new; + Word16 xspnew_uw[NB_DIV*M], xsfnew_uw[NB_DIV*M]; + Word16 const* xsfBase; /* base for differential XSF coding */ + Word16 past_core_mode; + + Word16 lsf_q_1st_rf[M], lsf_q_rf[M], lsp_q_rf[M]; + Word32 lsp_diff; + Word16 LSF_Q_prediction; + Word16 tcx_last_overlap_mode, tcx_current_overlap_mode; + TD_BWE_DEC_HANDLE hBWE_TD; + TCX_DEC_HANDLE hTcxDec; + TCX_LTP_DEC_HANDLE hTcxLtpDec; + + hBWE_TD = st->hBWE_TD; + hTcxLtpDec = st->hTcxLtpDec; + hTcxDec = st->hTcxDec; + + st->core = 0; /* to avoid compilation warnings */ + prm = NULL; /* to avoid compilation warnings */ + + /*--------------------------------------------------------------------------------* + * INIT + *--------------------------------------------------------------------------------*/ + + enr_old = 0; + move16(); + enr_new = 0; + move16(); + + LSF_Q_prediction= -1; + move16(); + + param_lpc = param+DEC_NPRM_DIV*NB_DIV; + + past_core_mode = st->last_core_bfi; + move16(); + + test(); + test(); + if(st->use_partial_copy && GE_16(st->rf_frame_type, RF_TCXFD)&&LE_16(st->rf_frame_type,RF_TCXTD2)) + { + bfi = st->bfi; + move16(); + } + + /*Adjust bit per frame*/ + if (bfi == 0) + { + st->bits_frame_core = sub(st->bits_frame, bitsRead[0]); + } + + /* Framing parameters */ + L_frame = st->L_frame; + move16(); + L_frameTCX = hTcxDec->L_frameTCX; + move16(); + nb_subfr = st->nb_subfr; + move16(); + + + /* Initialize pointers */ + synth = synth_buf + hTcxDec->old_synth_len; + /*st->old_synth: Q_0*/ + Copy(hTcxDec->old_synth, synth_buf, hTcxDec->old_synth_len); + set16_fx(synth, 0, L_FRAME_PLUS + M); + + synthFB = synth_bufFB + hTcxDec->old_synth_lenFB; + Copy(hTcxDec->old_synthFB_fx, synth_bufFB, hTcxDec->old_synth_lenFB); + set16_fx(synthFB, 0, L_FRAME_PLUS + M); + + /*For post-processing (post-filtering+blind BWE)*/ + IF (st->tcxonly==0) + { + /* for bass postfilter */ + set16_fx(pitch, L_SUBFR, nb_subfr); + + set16_fx(pit_gain, 0, nb_subfr); + } + + /* PLC: [Common: Memory update] + * PLC: Update the number of lost frames */ + IF ( bfi != 0) + { + move16(); + st->nbLostCmpt = add(st->nbLostCmpt, 1); + } + + + /*--------------------------------------------------------------------------------* + * BITSTREAM DECODING + *--------------------------------------------------------------------------------*/ + + IF (bfi == 0) + { + /* PLC: [TCX: Tonal Concealment] */ + st->second_last_core = st->last_core; + move16(); + tcx_last_overlap_mode = st->hTcxCfg->tcx_last_overlap_mode; + move16(); + tcx_current_overlap_mode = st->hTcxCfg->tcx_curr_overlap_mode; + move16(); + dec_prm(&st->coder_type_fx, param, param_lpc, total_nbbits, st, L_frame, bitsRead); + IF(!st->rate_switching_init && EQ_16((st->last_codec_mode), MODE2)&&st->BER_detect) + { + st->coder_type_fx = st->last_coder_type_fx; + move16(); + st->last_core = st->second_last_core; + move16(); + st->hTcxCfg->tcx_last_overlap_mode = tcx_last_overlap_mode; + move16(); + st->hTcxCfg->tcx_curr_overlap_mode = tcx_current_overlap_mode; + move16(); + st->bfi = 1; + move16(); + bfi = 1; + move16(); + st->flagGuidedAcelp = 0; + move16(); + st->nbLostCmpt++; + move16(); + st->core_brate = st->last_core_brate; + move16(); + st->core = GetPLCModeDecision( st ); + } + + } + ELSE + { + + test(); + test(); + IF( st->use_partial_copy && GE_16(st->rf_frame_type, RF_TCXFD)&&LE_16(st->rf_frame_type,RF_TCXTD2)) + { + dec_prm( &st->coder_type_fx, param, param_lpc, total_nbbits, st, L_frame, bitsRead ); + } + + if (GT_16(st->nbLostCmpt, 1)) + { + st->flagGuidedAcelp = 0; + move16(); + } + } + + /* PLC: [Common: mode decision] + * PLC: Decide which Concealment to use. Update pitch lags if needed */ + IF ( bfi!=0 ) + { + st->core = GetPLCModeDecision(st); + } + + IF ( bfi == 0 ) + { + IF( EQ_16(st->prev_bfi, 1)) + { + st->prev_nbLostCmpt = st->nbLostCmpt; + move16(); + } + ELSE + { + st->prev_nbLostCmpt = 0; + move16(); + } + move16(); + st->nbLostCmpt = 0; + } + + /*--------------------------------------------------------------------------------* + * LPC PARAMETERS + *--------------------------------------------------------------------------------*/ + + test(); + test(); + test(); + test(); + IF( (bfi == 0 ) || ( bfi != 0 && st->use_partial_copy != 0 && EQ_16(st->rf_frame_type,RF_TCXFD))) + { + test(); + test(); + test(); + test(); + test(); + IF(EQ_16(st->use_partial_copy,1)&&(LT_16(st->rf_frame_type,RF_TCXFD)||GT_16(st->rf_frame_type,RF_TCXTD2))) + { + IF( EQ_16((Word16)hTcxDec->envWeighted,1)) + { + Copy( st->lspold_uw, st->lsp_old_fx, M ); + Copy( st->lsfold_uw, st->lsf_old_fx, M ); + hTcxDec->envWeighted = 0; + move16(); + } + + /* first stage VQ, 8 bits; reuse TCX high rate codebook */ + set16_fx(lsf_q_1st_rf, 0, M); + vlpc_1st_dec(param_lpc[0], lsf_q_1st_rf ); + + /* second stage vq */ + /* quantized lsf from two stages */ + /*v_add(lsf_q_1st_rf, lsf_q_diff_cb_8b_rf + M * param_lpc[1], lsf_q_rf, M);*/ + FOR (i=0; isr_core ); + + /* current n-th ACELP frame and its corresponding partial copy */ + /*lsf2lsp( lsf_q_rf, lsp_q_rf, M, st->sr_core );*/ + E_LPC_lsf_lsp_conversion( lsf_q_rf, lsp_q_rf, M ); + + /* copy the old and current lsfs and lsps into the lsf[] and lsp[] buffer for interpolation */ + Copy(st->lsf_old_fx, &lsf[0], M); + Copy(st->lsp_old_fx, &lsp[0], M); + Copy(lsf_q_rf, &lsf[M], M); + Copy(lsp_q_rf, &lsp[M], M); + lsp_diff = 0; + FOR( i=0; i < M; i++ ) + { + lsp_diff = L_add(lsp_diff,(Word32)abs_s(sub(lsp[i+M],lsp[i]))); + } + + IF( EQ_16(st->core,ACELP_CORE)&&EQ_16(st->last_core,ACELP_CORE) + && LT_32(lsp_diff, 52428 )&>_32(lsp_diff,3932)&&EQ_16(st->next_coder_type,GENERIC) + && !st->prev_use_partial_copy && EQ_16(st->last_coder_type_fx,UNVOICED) && GE_16(st->rf_frame_type,RF_GENPRED) ) + { + Copy( &lsp[0], &lsp[M], M ); + } + + /* update mem_MA and mem_AR memories */ + lsf_update_memory( (Word16)st->narrowBand, &lsf[M], st->mem_MA_fx, st->mem_MA_fx, M ); + Copy(&lsf[M], st->mem_AR_fx, M); + + FOR( k=0; knumlpc; ++k ) + { + Copy( &lsp[(k+1)*M], &xspnew_uw[k*M], M ); + Copy( &lsf[(k+1)*M], &xsfnew_uw[k*M], M ); + } + } + ELSE IF ((hTcxDec->enableTcxLpc !=0 && NE_16(st->core , ACELP_CORE))||(bfi&&st->use_partial_copy&&st->rf_frame_type==RF_TCXFD)) + { + Word16 tcx_lpc_cdk; + IF(bfi && st->use_partial_copy && EQ_16(st->rf_frame_type, RF_TCXFD)) + { + tcx_lpc_cdk = tcxlpc_get_cdk(GENERIC); + } + ELSE + { + tcx_lpc_cdk = tcxlpc_get_cdk(st->coder_type_fx); /* inlined */ + } + + Copy(st->lsf_old_fx, &lsf[0], M); + Copy(st->lsp_old_fx, &lsp[0], M); + + D_lsf_tcxlpc( param_lpc, &lsf[M], lspind, st->narrowBand, tcx_lpc_cdk, st->mem_MA_fx ); + + E_LPC_lsf_lsp_conversion( &lsf[M], &lsp[M], M ); + + lsf_update_memory( (Word16)st->narrowBand, &lsf[M], st->mem_MA_fx, st->mem_MA_fx, M ); + Copy(&lsf[M], st->mem_AR_fx, M); + + hTcxDec->envWeighted = 1; + move16(); + + E_LPC_lsp_unweight( &lsp[M], xspnew_uw, xsfnew_uw, st->inv_gamma, M ); + } + ELSE + { + + IF (hTcxDec->envWeighted) + { + Copy(st->lspold_uw, st->lsp_old_fx, M); + Copy(st->lsfold_uw, st->lsf_old_fx, M); + hTcxDec->envWeighted = 0; + move16(); + } + IF (EQ_16(st->core, TCX_20_CORE)) + { + lpc_unquantize( st, lsf, lsp, M, param_lpc, lspmid, lsfmid, AUDIO, &LSF_Q_prediction); + } + ELSE + { + lpc_unquantize( st, lsf, lsp, M, param_lpc, lspmid, lsfmid, st->coder_type_fx, &LSF_Q_prediction); + + IF(EQ_16(st->prev_use_partial_copy,1)&&EQ_16(st->last_core,ACELP_CORE)&&EQ_16(st->core,ACELP_CORE) + && GE_16(st->prev_rf_frame_type, RF_GENPRED) && EQ_16(st->coder_type_fx, UNVOICED)) + { + IF ( st->lpcQuantization && st->acelp_cfg.midLpc ) + { + Copy(lspmid, &lsp[0], M ); + Copy(&lsp[M], lspmid, M ); + } + } + } + + FOR(k=0; knumlpc; ++k) + { + Copy(&lsp[(k+1)*M], &xspnew_uw[k*M], M); + Copy(&lsf[(k+1)*M], &xsfnew_uw[k*M], M); + } + } + + /* PLC: [LPD: LPC concealment] + * built the moving average for the LPC concealment */ + + FOR (k=0; knumlpc; k++) + { + FOR (i=0; ilsf_adaptive_mean_fx[i] = add(add(mult_r(st->lsfoldbfi1_fx[i], 10923/*1.0f/3.0f Q15*/), mult_r(st->lsfoldbfi0_fx[i], 10923/*1.0f/3.0f Q15*/)), mult_r(xsfnew_uw[k*M+i], 10923/*1.0f/3.0f Q15*/)); + move16(); + st->lsfoldbfi1_fx[i] = st->lsfoldbfi0_fx[i]; + move16(); + st->lsfoldbfi0_fx[i] = xsfnew_uw[k*M+i]; + } + } + } + ELSE + { + /* PLC: [LPD: LPC concealment] + * Conceal the LPC from the lost frame */ + st->numlpc = 2; + move16(); + test(); + if ( st->tcxonly == 0 || LT_16(st->core, TCX_10_CORE)) + { + move16(); + st->numlpc = 1; + } + IF(EQ_16(st->nbLostCmpt,1)) + { + Copy(st->lsf_old_fx, st->old_lsf_q_cng, M); + Copy(st->lsp_old_fx, st->old_lsp_q_cng, M); + } + move16(); + xsfBase = PlcGetLsfBase (st->lpcQuantization, (Word16)st->narrowBand, st->sr_core); + + dlpc_bfi( st->L_frame,xsfnew_uw,st->lsfold_uw,st->last_good_fx,st->nbLostCmpt,st->mem_MA_fx,st->mem_AR_fx, + &(st->stab_fac_fx), st->lsf_adaptive_mean_fx, st->numlpc, st->lsf_cng, st->plcBackgroundNoiseUpdated, st->lsf_q_cng, st->old_lsf_q_cng, xsfBase, (Word8)st->tcxonly); + + hTcxDec->envWeighted = 0; + move16(); + + Copy( st->lspold_uw, lsp, M ); + Copy( st->lsfold_uw, lsf, M ); + + FOR ( k = 0; k < st->numlpc; k++ ) + { + Copy( &xsfnew_uw[k*M], &lsf[(k+1)*M], M ); + + IF ( st->tcxonly ) + { + E_LPC_lsf_lsp_conversion(&lsf[(k+1)*M], &lsp[(k+1)*M], M); + E_LPC_lsf_lsp_conversion(st->lsf_q_cng, st->lsp_q_cng, M); + } + ELSE + { + lsf2lsp_fx( &lsf[(k+1)*M], &lsp[(k+1)*M], M, st->sr_core ); + lsf2lsp_fx( st->lsf_q_cng, st->lsp_q_cng, M, st->sr_core ); + } + + Copy( &lsp[(k+1)*M], &xspnew_uw[k*M], M ); + } + } + + /*--------------------------------------------------------------* + * Rate switching + *---------------------------------------------------------------*/ + IF( st->rate_switching_reset!=0 ) + { + Copy( &(lsf[M]),&(lsf[0]), M ); + Copy( &(lsp[M]),&(lsp[0]), M ); + Copy( &(lsf[M]),st->lsf_old_fx, M ); + Copy( &(lsp[M]),st->lsp_old_fx, M ); + Copy( &(lsf[M]),lsfmid, M ); + Copy( &(lsp[M]),lspmid, M ); + E_LPC_f_lsp_a_conversion(st->lsp_old_fx, st->old_Aq_12_8_fx, M); + } + + + IF(st->enablePlcWaveadjust) + { + if(EQ_16(st->core, ACELP_CORE)) + { + st->tonality_flag = 0; + move16(); + } + if(bfi) + { + st->plcInfo.nbLostCmpt++; + move16(); + } + } + + /*--------------------------------------------------------------------------------* + * ACELP + *--------------------------------------------------------------------------------*/ + test(); + test(); + test(); + IF( (st->prev_bfi!=0) && (bfi==0) && (EQ_16(st->coder_type_fx,VOICED))&>_16(st->prev_nbLostCmpt,4)) + { + st->dec_glr_idx = 1; + move16(); + st->reset_mem_AR = 1; + move16(); + } + + IF ( st->core == ACELP_CORE ) + { + IF (st->tcxonly==0) + { + /* Set pointer to parameters */ + prm = param; + + /* Stability Factor */ + IF ( bfi == 0 ) + { + st->stab_fac_fx = lsf_stab_fx(&lsf[M], &lsf[0], 0, st->L_frame); + } + + test(); + IF( bfi==0 && st->prev_bfi != 0 ) + { + /* check if LSP interpolation can be relaxed or if LPC power can be diffused*/ + E_LPC_f_lsp_a_conversion(&lsp[0], tmp_old, M); + enr_old = Enr_1_Az_fx(tmp_old, 2*L_SUBFR); + + E_LPC_f_lsp_a_conversion(&lsp[M], tmp_new, M); + enr_new = Enr_1_Az_fx(tmp_new, 2*L_SUBFR); + } + + test(); + test(); + test(); + test(); + IF( (bfi == 0) && ((EQ_16(st->dec_glr_idx, 1))||((st->safety_net_fx==0)&&(shr(enr_new,11)>0)&&(GT_16(shr(enr_new,1),enr_old))))&&(st->prev_bfi!=0)) + { + Word16 reset_q = 0; + if( EQ_16(st->dec_glr_idx, 1)) + { + reset_q = 1; + move16(); + } + RecLpcSpecPowDiffuseLc( &lsp[M], &lsp[0], &lsf[M], st, reset_q); + + int_lsp_fx( L_frame, &lsp[0], &lsp[M], Aq, M, interpol_frac_fx, 0 ); + + Copy(&lsf[M], xsfnew_uw, M); + } + ELSE + { + /* LPC Interpolation for ACELP */ + test(); + IF ( bfi==0 && st->acelp_cfg.midLpc ) + { + st->relax_prev_lsf_interp_fx = 0; + move16(); + IF (st->prev_bfi) + { + /* check if LSP interpolation can be relaxed */ + IF ( LT_16(enr_new, shr(enr_old, 2))) + { + st->relax_prev_lsf_interp_fx = -1; + move16(); + test(); + test(); + test(); + test(); + IF ( EQ_16(st->clas_dec, UNVOICED_CLAS)||EQ_16(st->clas_dec,SIN_ONSET)||EQ_16(st->clas_dec,INACTIVE_CLAS)||EQ_16(st->coder_type_fx,GENERIC)||EQ_16(st->coder_type_fx,TRANSITION)) + { + st->relax_prev_lsf_interp_fx = 1; + move16(); + } + } + } + + test(); + test(); + test(); + test(); + IF (st->stab_fac_fx == 0 && st->old_bfi_cnt_fx > 0 && NE_16(st->clas_dec, VOICED_CLAS)&&NE_16(st->clas_dec,ONSET)&&st->relax_prev_lsf_interp_fx==0) + { + st->relax_prev_lsf_interp_fx = 2; + move16(); + } + int_lsp4_fx( L_frame, &lsp[0], lspmid, &lsp[M], Aq, M, st->relax_prev_lsf_interp_fx ); + } + ELSE + { + int_lsp_fx( L_frame, &lsp[0], &lsp[M], Aq, M, interpol_frac_fx, 0 ); + int_lsp_fx( L_frame, st->old_lsp_q_cng, st->lsp_q_cng, st->Aq_cng, M, interpol_frac_fx, 0 ); + } + } + } + + test(); + IF (bfi!=0 && st->last_core != ACELP_CORE) + { + /* PLC: [TCX: TD PLC] */ +#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT + con_tcx(st, &synthFB[0], -1.f, NULL, 0, NULL); +#else + con_tcx( st, &synthFB[0] ); +#endif + lerp( synthFB, synth, st->L_frame, hTcxDec->L_frameTCX ); + st->con_tcx = 1; + move16(); + set16_fx (st->mem_pitch_gain+2,round_fx(L_shl(st->Mode2_lp_gainp , 1)), st->nb_subfr); + } + ELSE + { + /* ACELP decoder */ + IF(hBWE_TD != NULL) + { + IF(EQ_16(st->L_frame,L_FRAME)) + { + Copy(Aq + 2 * (M + 1), hBWE_TD->cur_sub_Aq_fx, (M + 1)); + } + ELSE + { + Copy(Aq + 3 * (M + 1), hBWE_TD->cur_sub_Aq_fx, (M + 1)); + } + } + IF ( bfi != 0 ) + { + /* PLC: [ACELP: general] + * PLC: Use the ACELP like concealment */ + con_acelp(Aq,st->core_ext_mode,&synth[0],pitch,pit_gain,st->stab_fac_fx,st, + &st->Q_exc, &st->Q_syn, /*Q format of st->mem_syn*/ pitch_buf, voice_factors, ptr_bwe_exc); + + Copy(&st->mem_pitch_gain[2], &st->mem_pitch_gain[st->nb_subfr+2], st->nb_subfr); + set16_fx(&st->mem_pitch_gain[2],0,st->nb_subfr); + } + ELSE + { + decoder_acelp(st, prm, Aq, st->acelp_cfg, &synth[0], pitch, pit_gain, st->stab_fac_fx, pitch_buf, voice_factors, LSF_Q_prediction, ptr_bwe_exc); + + IF(st->flagGuidedAcelp > 0) + { + st->guidedT0 = s_max(s_min(add(st->T0_4th, st->guidedT0), NBPSF_PIT_MAX), PIT_MIN_16k); + } + + FOR (i=0; inb_subfr; i++) + { + move16(); + move16(); + st->mem_pitch_gain[2+(2*st->nb_subfr-1)-i] = st->mem_pitch_gain[2+ (st->nb_subfr-1) -i]; + st->mem_pitch_gain[2+(st->nb_subfr-1)-i] = pit_gain[i]; + } + } + } + + + /* LPC for ACELP/BBWE */ + test(); + test(); + IF( st->narrowBand || (EQ_32(st->sr_core, INT_FS_12k8))||(EQ_32(st->sr_core, INT_FS_16k))) + { + Copy(Aq, st->mem_Aq, nb_subfr*(M+1)); + } + + /* PLC: [TCX: Tonal Concealment] */ + /* Signal that this frame is not TCX */ + TonalMDCTConceal_UpdateState(&st->tonalMDCTconceal, 0, 0, 0, 0); + + IF (bfi==0) + { + st->second_last_tns_active = st->last_tns_active; + st->last_tns_active = 0; + hTcxDec->tcxltp_last_gain_unmodified = 0; + move16(); + } + + } + + + + /*--------------------------------------------------------------------------------* + * TCX20 + *--------------------------------------------------------------------------------*/ + + IF ( EQ_16(st->core, TCX_20_CORE)) + { + /* Set pointer to parameters */ + prm = param; + + /* Stability Factor */ + IF ( bfi == 0 ) + { + IF ( st->tcxonly != 0 ) + { + st->stab_fac_fx = lsf_stab_fx(&lsf[M], &lsf[0],0, L_FRAME); + } + ELSE + { + st->stab_fac_fx = lsf_stab_fx(&lsf[M], &lsf[0],0, st->L_frame); + } + } + + IF (hTcxDec->enableTcxLpc) + { + /* Convert quantized xSP to A */ + E_LPC_f_lsp_a_conversion(&lsp[M], Aq, M); + } + ELSE + { + IF (st->tcxonly == 0) + { + test(); + test(); + test(); + IF( (bfi == 0) && (st->prev_bfi != 0 ) && (st->safety_net_fx==0) && (st->rate_switching_reset != 0) ) + { + /* diffuse LPC power on rate switching*/ + RecLpcSpecPowDiffuseLc( &lsp[M], &lsp[0], &lsf[M], st, 0 ); + int_lsp_fx( L_frame, &lsp[0], &lsp[M], Aq, M, interpol_frac_fx, 0 ); + Copy(&lsf[M], xsfnew_uw, M); + } + ELSE + { + /* LPC Interpolation for TCX */ + E_LPC_int_lpc_tcx(&lsp[0], &lsp[M], Aq); + } + } + ELSE + { + E_LPC_f_lsp_a_conversion(&lsp[M], Aq, M); + } + } + + test(); + IF ( bfi == 0 && hTcxDec->tcx_lpc_shaped_ari != 0 ) + { + E_LPC_f_lsp_a_conversion(lspind, Aind, M); + } + /* TCX decoder */ + decoder_tcx(st->hTcxCfg,prm,Aq,Aind,L_frame,L_frameTCX,st->hTcxCfg->tcx_coded_lines,&synth[0],&synthFB[0],st, st->coder_type_fx, bfi,0,st->stab_fac_fx); + + } + + /*--------------------------------------------------------------------------------* + * TCX10 + *--------------------------------------------------------------------------------*/ + + IF ( EQ_16(st->core, TCX_10_CORE)) + { + FOR (k=0; k<2; k++) + { + + /* Set pointer to parameters */ + prm = param + (k*DEC_NPRM_DIV); + + /* Stability Factor */ + IF ( bfi==0 ) + { + st->stab_fac_fx = lsf_stab_fx(&lsf[(k+1)*M], &lsf[k*M],0, L_FRAME); + } + + E_LPC_f_lsp_a_conversion(&lsp[(k+1)*M], Aq, M); + + /* TCX decoder */ + + IGFDecRestoreTCX10SubFrameData( st->hIGFDec, k ); + decoder_tcx(st->hTcxCfg,prm,Aq,Aind,shr(L_frame, 1),shr(L_frameTCX, 1), + shr(st->hTcxCfg->tcx_coded_lines, 1),&synth[k*L_frame/2],&synthFB[k*L_frameTCX/2],st, st->coder_type_fx, bfi, k, st->stab_fac_fx ); + } + + } + + + test(); + IF (EQ_16(st->core, TCX_10_CORE)||EQ_16(st->core,TCX_20_CORE)) + { + test(); + test(); + IF(st->enablePlcWaveadjust || /* bfi */ + (GE_32(st->last_total_brate, HQ_48k) && /* recovery */ + EQ_16(st->last_codec_mode, MODE2) ) ) + { + /* waveform adjustment */ + + concealment_signal_tuning_fx( bfi, st->core, + synthFB, &st->plcInfo, st->nbLostCmpt, st->prev_bfi, + st->tonalMDCTconceal.secondLastPcmOut, + past_core_mode,st->tonalMDCTconceal.lastPcmOut, st ); + test(); + test(); + test(); + IF ((bfi || st->prev_bfi) && st->plcInfo.Pitch_fx && (EQ_16(st->plcInfo.concealment_method, TCX_NONTONAL))) + { + lerp( synthFB, synth, L_frame, L_frameTCX ); + test(); + if( !bfi && st->prev_bfi ) + { + st->plcInfo.Pitch_fx = 0; + move16(); + } + } + } + + IF (!bfi) + { + TonalMDCTConceal_SaveTimeSignal( &st->tonalMDCTconceal, synthFB, L_frameTCX ); + } +#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT + decoder_tcx_post(st, synth, synthFB, Aq, bfi, 0); +#else + decoder_tcx_post( st, synth, synthFB, Aq, bfi ); +#endif + IF (EQ_16(st->core, TCX_20_CORE)) + { + /* LPC Interpolation for BWE/post-processing */ + test(); + test(); + IF( st->narrowBand || (EQ_32(st->sr_core, INT_FS_12k8))||(EQ_32(st->sr_core, INT_FS_16k))) + { + int_lsp_fx( L_frame, st->lspold_uw, xspnew_uw, Aq, M, interpol_frac_fx, 0 ); + Copy(Aq, st->mem_Aq, nb_subfr*(M+1)); + } + } + } + + /* PLC: [Common: Classification] */ + + IF( LE_32( st->sr_core, INT_FS_16k)) + { + test(); + test(); + test(); + IF ( EQ_16(st->core, TCX_20_CORE)||EQ_16(st->core,TCX_10_CORE)||(st->tcxonly&&st->bfi)) + { + Word16 pitch_C[NB_SUBFR16k]; + Word16 core_ext_mode, LTP_Gain; + + set16_fx(pitch_C, shl(round_fx(st->old_fpitch), 6), NB_SUBFR16k); + + core_ext_mode = GENERIC; + move16(); + if(st->tcxonly == 0) + { + core_ext_mode = st->core_ext_mode; + move16(); + } + + LTP_Gain = -32768/*-1.0f Q15*/; + if(hTcxLtpDec->tcxltp) + { + LTP_Gain = hTcxDec->tcxltp_last_gain_unmodified; + move16(); + } + + + FEC_clas_estim_fx( + st, + /*Opt_AMR_WB*/0, /*A*/ + st->L_frame, + &(st->clas_dec), + core_ext_mode, + pitch_C, + synth, + &st->lp_ener_FER_fx, + /**decision_hyst*/NULL, /* i/o: hysteresis of the music/speech decision */ + /**UV_cnt*/ NULL, /* i/o: number of consecutive frames classified as */ + /**LT_UV_cnt*/ NULL, /* i/o: long term consecutive frames classified as UV */ + /**Last_ener*/ NULL, /* i/o: last_energy frame */ + /**locattack*/ NULL, /* i/o: detection of attack (mainly to localized speech burst) */ + /**lt_diff_etot*/NULL, /* i/o: long-term total energy variation */ + /**amr_io_class*/ NULL, /* i/o: classification for AMR-WB IO mode */ + /*bitrate*/ 0 , /* i : Decoded bitrate */ + 0, /* i : Synthesis scaling */ + /**class_para*/ NULL, /* o : classification para. fmerit1 */ + st->mem_syn_clas_estim_fx, /* i/o: memory of the synthesis signal for frame class estimation */ + &st->classifier_Q_mem_syn, /* i/o: exponent for memory of synthesis signal for frame class estimation */ + LTP_Gain, /* i : means LTP Gain */ + 1 /*CLASSIFIER_TCX*/, /* i : signal classifier mode */ + bfi, /* i : bad frame indicator */ + st->last_core_brate, /* i : bitrate of previous frame */ + -1 + ); + + } + } + + /*--------------------------------------------------------------------------------* + * Updates + *--------------------------------------------------------------------------------*/ + + test(); + IF( bfi && NE_16(st->last_core_bfi , ACELP_CORE)) + { + /* Update FEC_scale_syn parameters */ + IF(hTcxLtpDec->tcxltp_gain == 0) + { + frame_ener_fx( L_frame, UNVOICED_CLAS, synth, shr(L_frame,1), &st->enr_old_fx, L_frame, 0, 0, 0 ); + } + ELSE + { + Word16 pitch_Q0; + pitch_Q0 = round_fx(st->old_fpitch); + frame_ener_fx( L_frame, st->clas_dec, synth, pitch_Q0, &st->enr_old_fx, L_frame, 0, 0, 0 ); + } + } + + + test(); + test(); + IF(!bfi && GE_16(st->clas_dec, VOICED_TRANSITION)&<_16(st->clas_dec,INACTIVE_CLAS)) + { + Word16 offset; + + IF(EQ_16(st->core, ACELP_CORE)) + { + offset = sub(st->nb_subfr,1); + offset = imult1616(offset,add(M,1)); + } + ELSE + { + offset = 0; + move16(); + } + /* use latest LPC set */ + st->old_enr_LP = Enr_1_Az_fx(Aq+offset, L_SUBFR); /*Q3*/ + } + + + /* Update */ + Copy(synth_buf+L_frame, hTcxDec->old_synth, hTcxDec->old_synth_len); + + Copy(hTcxDec->old_synthFB_fx + L_frameTCX - NS2SA_fx2(st->output_Fs, PH_ECU_MEM_NS), hTcxDec->synth_history_fx, NS2SA_fx2(st->output_Fs, PH_ECU_MEM_NS) ); + Copy(synth_bufFB+L_frameTCX, hTcxDec->old_synthFB_fx, hTcxDec->old_synth_lenFB); + Copy_Scale_sig( st->hHQ_core->old_out_fx+NS2SA_fx2(st->output_Fs, N_ZERO_MDCT_NS), hTcxDec->old_synthFB_fx+ hTcxDec->old_synth_lenFB, NS2SA_fx2(st->output_Fs, PH_ECU_LOOKAHEAD_NS), negate(st->hHQ_core->Q_old_wtda)); + + Copy(&xspnew_uw[(st->numlpc-1)*M], st->lspold_uw, M); + Copy(&xsfnew_uw[(st->numlpc-1)*M], st->lsfold_uw, M); + + IF (bfi) + { + Copy(st->lspold_uw, st->lsp_old_fx, M); /* for recovery */ + Copy(st->lsfold_uw, st->lsf_old_fx, M); /* for recovery */ + } + ELSE + { + Copy(&lsp[st->numlpc*M], st->lsp_old_fx, M); + Copy(&lsf[st->numlpc*M], st->lsf_old_fx, M); + } + Copy(st->lsp_q_cng, st->old_lsp_q_cng, M); + Copy(st->lsf_q_cng, st->old_lsf_q_cng, M); + + /* Update LP_CNG parameters */ + IF( st->tcxonly == 0 && st->hTdCngDec != NULL ) + { + /* update CNG parameters in active frames */ + IF (EQ_16(st->bwidth,NB)&& hTcxDec->enableTcxLpc!=0&&NE_16(st->core,ACELP_CORE)) + { + Word16 buf[L_LP], res[L_FRAME], A[M+1], Qexc, r_l[M+1], r_h[M+1], lsptmp[M], Q_r, tmp; + + assert(st->L_frame==L_FRAME); + Copy(synth+L_FRAME-L_LP, buf, L_LP); + tmp = synth[L_FRAME-L_LP-1]; + Qexc = E_UTIL_f_preemph3(buf, st->preemph_fac, L_LP, &tmp, 1); + autocorr_fx( buf, M, r_h, r_l, &Q_r, L_LP, Assym_window_W16fx, 0, 0 ); + lag_wind(r_h, r_l, M, INT_FS_FX, LAGW_WEAK); + E_LPC_lev_dur(r_h, r_l, A, NULL, M, NULL); + E_LPC_a_lsp_conversion(A, lsptmp, &xspnew_uw[0], M); + Residu3_fx(A, buf+L_LP-L_FRAME, res, L_FRAME, 1); + cng_params_upd_fx( lsptmp, res, st->L_frame, &st->hTdCngDec->ho_circ_ptr_fx, + st->hTdCngDec->ho_ener_circ_fx, &st->hTdCngDec->ho_circ_size_fx, st->hTdCngDec->ho_lsp_circ_fx, + Qexc, DEC, st->hTdCngDec->ho_env_circ_fx, NULL, NULL, NULL, NULL, st->last_active_brate ); + } + ELSE + { + cng_params_upd_fx( &lsp[M], st->old_exc_fx+L_EXC_MEM_DEC-st->L_frame, + st->L_frame, &st->hTdCngDec->ho_circ_ptr_fx, st->hTdCngDec->ho_ener_circ_fx, + &st->hTdCngDec->ho_circ_size_fx, st->hTdCngDec->ho_lsp_circ_fx, st->Q_exc, DEC, + st->hTdCngDec->ho_env_circ_fx, NULL, NULL, NULL, NULL, st->last_active_brate ); + } + + /* Set 16k LSP flag for CNG buffer */ + st->hTdCngDec->ho_16k_lsp_fx[st->hTdCngDec->ho_circ_ptr_fx] = 1; + move16(); + if ( EQ_16(st->L_frame,L_FRAME)) + { + st->hTdCngDec->ho_16k_lsp_fx[st->hTdCngDec->ho_circ_ptr_fx] = 0; + move16(); + } + } + + move16(); + st->last_is_cng = 0; + + /* Postfiltering */ + post_decoder( st, synth_buf, pit_gain, pitch, signal_out, bpf_noise_buf); + + IF( signal_outFB ) + { + Copy( synthFB, signal_outFB, L_frameTCX ); + } + + IF( st->enablePlcWaveadjust) + { + if(!bfi) + { + st->plcInfo.nbLostCmpt = L_deposit_l(0); + } + + IF (st->core == 0) + { + set_state(st->plcInfo.Transient, st->core, MAX_POST_LEN); + } + } + + + return; +} + + diff --git a/lib_dec/dec_ace.c b/lib_dec/dec_ace.c index 2ff764e1117b815f01e19ccf65c67eb1bde4ccf0..d359d527b3b133cbd5706b4657c5878fb8df3477 100644 --- a/lib_dec/dec_ace.c +++ b/lib_dec/dec_ace.c @@ -42,12 +42,12 @@ #include "wmc_auto.h" /*-------------------------------------------------------------------* - * decoder_acelp() + * decoder_acelp_flt() * * Decode ACELP frame MODE2 *-------------------------------------------------------------------*/ -void decoder_acelp( +void decoder_acelp_flt( Decoder_State *st, /* i/o: coder memory state */ int16_t prm[], /* i : parameters */ const float A[], /* i : coefficients NxAz[M+1] */ @@ -254,29 +254,29 @@ void decoder_acelp( if ( acelp_cfg.ltp_bits != 0 ) { /* pitch lag decoding */ - *pt_pitch = Mode2_pit_decode( acelp_cfg.ltp_mode, i_subfr, L_SUBFR, &prm, &T0, &T0_frac, &T0_res, &T0_min, &T0_min_frac, &T0_max, &T0_max_frac, st->pit_min, st->pit_fr1, st->pit_fr1b, st->pit_fr2, st->pit_max, st->pit_res_max ); + *pt_pitch = Mode2_pit_decode_flt( acelp_cfg.ltp_mode, i_subfr, L_SUBFR, &prm, &T0, &T0_frac, &T0_res, &T0_min, &T0_min_frac, &T0_max, &T0_max_frac, st->pit_min, st->pit_fr1, st->pit_fr1b, st->pit_fr2, st->pit_max, st->pit_res_max ); /* find pitch excitation */ if ( st->pit_res_max == 6 && !( st->use_partial_copy ) ) { if ( T0_res == ( st->pit_res_max >> 1 ) ) { - pred_lt4( &exc[i_subfr], &exc[i_subfr], T0, T0_frac << 1, L_SUBFR + 1, inter6_2, PIT_L_INTERPOL6_2, PIT_UP_SAMP6 ); + pred_lt4_flt( &exc[i_subfr], &exc[i_subfr], T0, T0_frac << 1, L_SUBFR + 1, inter6_2, PIT_L_INTERPOL6_2, PIT_UP_SAMP6 ); } else { - pred_lt4( &exc[i_subfr], &exc[i_subfr], T0, T0_frac, L_SUBFR + 1, inter6_2, PIT_L_INTERPOL6_2, PIT_UP_SAMP6 ); + pred_lt4_flt( &exc[i_subfr], &exc[i_subfr], T0, T0_frac, L_SUBFR + 1, inter6_2, PIT_L_INTERPOL6_2, PIT_UP_SAMP6 ); } } else { if ( T0_res == ( st->pit_res_max >> 1 ) ) { - pred_lt4( &exc[i_subfr], &exc[i_subfr], T0, T0_frac << 1, L_SUBFR + 1, inter4_2, L_INTERPOL2, PIT_UP_SAMP ); + pred_lt4_flt( &exc[i_subfr], &exc[i_subfr], T0, T0_frac << 1, L_SUBFR + 1, inter4_2, L_INTERPOL2, PIT_UP_SAMP ); } else { - pred_lt4( &exc[i_subfr], &exc[i_subfr], T0, T0_frac, L_SUBFR + 1, inter4_2, L_INTERPOL2, PIT_UP_SAMP ); + pred_lt4_flt( &exc[i_subfr], &exc[i_subfr], T0, T0_frac, L_SUBFR + 1, inter4_2, L_INTERPOL2, PIT_UP_SAMP ); } } @@ -320,7 +320,7 @@ void decoder_acelp( else { config = PulseConfTable[acelp_cfg.fixed_cdk_index[i_subfr / L_SUBFR]]; - D_ACELP_indexing( code, config, NB_TRACK_FCB_4T, prm, &st->BER_detect ); + D_ACELP_indexing_ivas( code, config, NB_TRACK_FCB_4T, prm, &st->BER_detect ); ( prm ) += 8; /*-------------------------------------------------------* @@ -336,7 +336,7 @@ void decoder_acelp( if ( acelp_cfg.gains_mode[i_subfr / L_SUBFR] == 7 && !st->use_partial_copy ) { - gaus_L2_dec( code2, st->tilt_code, p_A, acelp_cfg.formant_enh_num_flt, &( st->seed_acelp ) ); + gaus_L2_dec_flt( code2, st->tilt_code, p_A, acelp_cfg.formant_enh_num_flt, &( st->seed_acelp ) ); } else { @@ -350,7 +350,7 @@ void decoder_acelp( if ( st->acelp_cfg.gains_mode[i_subfr / L_SUBFR] != 0 ) { - decode_acelp_gains( code, acelp_cfg.gains_mode[i_subfr / L_SUBFR], Es_pred, &gain_pit, &gain_code, &prm, &( st->past_gpit_float), &( st->past_gcode_float), &gain_inov, L_SUBFR, code2, &gain_code2 ); + decode_acelp_gains_flt( code, acelp_cfg.gains_mode[i_subfr / L_SUBFR], Es_pred, &gain_pit, &gain_code, &prm, &( st->past_gpit_float), &( st->past_gcode_float), &gain_inov, L_SUBFR, code2, &gain_code2 ); } if ( st->use_partial_copy && st->rf_frame_type == RF_ALLPRED ) diff --git a/lib_dec/dec_ace_fx.c b/lib_dec/dec_ace_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..d659e3277e505c2d12511b7df7386150ad28dbce --- /dev/null +++ b/lib_dec/dec_ace_fx.c @@ -0,0 +1,675 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +/*BASOp version info: This file is up to date with trunk rev. 39929 */ + +#include +#include +#include +#include "options.h" +#include "prot_fx1.h" +#include "prot_fx2.h" +#include "basop_util.h" +#include "stl.h" +#include "rom_com.h" +/*-------------------------------------------------------------------* + * decoder_acelp() + * + * Decode ACELP frame MODE2 + *-------------------------------------------------------------------*/ + +void decoder_acelp( + Decoder_State *st, + Word16 prm[], /* i : parameters */ + Word16 A[], /* i : coefficients NxAz[M+1] */ + ACELP_config acelp_cfg, /* i : ACELP config */ + Word16 synth[], /* i/o: synth[-2*LFAC..L_DIV] Q0 */ + Word16 *pT, /* o : pitch for all subframe Q0 */ + Word16 *pgainT, /* o : pitch gain for all subfr 1Q14 */ + Word16 stab_fac, /* i : stability of isf */ + Word16 *pitch_buffer, /* o : pitch values for each subfr. */ + Word16 *voice_factors, /* o : voicing factors */ + const Word16 LSF_Q_prediction, /* i : LSF prediction mode */ + Word16 *bwe_exc /* o : excitation for SWB TBE */ +) +{ + Word16 i, j, i_subfr; + Word16 T0, T0_frac, T0_min, T0_min_frac, T0_max, T0_max_frac, T0_res; + Word16 tmp, tmp2, gain_pit/*Q14*/, Es_pred, tmp_deemph; + Word32 Ltmp, Ltmp2, gain_code; + Word16 code[L_SUBFR]; + Word16 mem_syn[M]; + Word16 *syn, syn_buf[M+L_FRAME16k+L_FRAME16k/2]; + Word16 *exc, exc_buf[L_EXC_MEM_DEC+L_FRAME16k+1]; + Word16 exc2[L_FRAME_16k]; + Word16 *p_A; + Word32 pitch_buf[NB_SUBFR16k]; + Word16 dummy_pitch_buf[NB_SUBFR16k]; + Word16 gain_inov; + Word16 mem_back[M]; + Word16 update_flg; + Word16 Q_mem_back; /*Q format of mem_back*/ + Word16 h1[L_FRAME_16k/4+1]; + Word16 mem[M]; + Word16 *pA; + PulseConfig config; + Word16 weights[5]; /* Q15 */ + + Word16 reScaleLen_fx; /* rescaling length for the BWE buffers */ + Word16 reSampLen; + + /*Q formats of buffers */ + Word16 prev_Q_syn; + Word32 gain_code2=0; + Word16 code2[L_SUBFR]; + Word16 error = 0; + Word16 gain_preQ = 0; /* Gain of prequantizer excitation */ + Word16 code_preQ[L_SUBFR]; /* Prequantizer excitation */ + Word16 lp_flag; + + + Word16 prev_gain_pit; + Word16 tmp_noise; /* Long term temporary noise energy */ + Word32 gain_code_tmp; + Word16 gain_pit_tmp; + Word32 gain_code_pre; + Word16 avoid_lpc_burst_on_recovery; + Word16 force_scale_syn; + TD_BWE_DEC_HANDLE hBWE_TD; + TCX_DEC_HANDLE hTcxDec; + + hBWE_TD = st->hBWE_TD; + hTcxDec = st->hTcxDec; + + gain_code_pre = 0; + move16(); + + + set16_fx(code_preQ, 0, L_SUBFR); + + gain_inov = 0; /* to avoid compilation warnings */ + T0 = 0; /* to avoid compilation warnings */ + T0_frac = 0; /* to avoid compilation warnings */ + T0_res = 0; /* to avoid compilation warnings */ + prev_Q_syn = st->prev_Q_syn = st->Q_syn; + move16(); + move16(); + move16(); + move16(); + gain_pit = 0; + gain_code = 0; + move16(); + move16(); + move16(); + update_flg = 0; + move16(); + gain_code2=0; + + prev_gain_pit = 0; + tmp_noise = 0; + + IF(EQ_16(st->nb_subfr,4)) + { + move16(); + move16(); + move16(); + move16(); + weights[0] = 3277/*0.1f Q15*/; + weights[1] = 6554/*0.2f Q15*/; + weights[2] = 9830/*0.3f Q15*/; + weights[3] = 13107/*0.4f Q15*/; + } + ELSE /*nb_subfr == 5*/ + { + move16(); + move16(); + move16(); + move16(); + move16(); + weights[0] = 2185/*(float)1/15 Q15*/; + weights[1] = 4369/*(float)2/15 Q15*/; + weights[2] = 6554/*(float)3/15 Q15*/; + weights[3] = 8738/*(float)4/15 Q15*/; + weights[4] = 10923/*(float)5/15 Q15*/; + } + st->Mode2_lp_gainp = L_deposit_l(0); + st->Mode2_lp_gainc = L_deposit_l(0); + + avoid_lpc_burst_on_recovery = 0; + move16(); + test(); + test(); + if (st->last_con_tcx && (NE_16(st->L_frameTCX_past, st->L_frame))&&(st->last_core!=0)) + { + avoid_lpc_burst_on_recovery = 1; + move16(); + } + + + /*------------------------------------------------------------------------* + * Previous frame is TCX * + *------------------------------------------------------------------------*/ + + + /* Reset phase dispersion */ + IF ( st->last_core_bfi > ACELP_CORE ) + { + st->dm_fx.prev_gain_code = L_deposit_l(0); + set16_fx(st->dm_fx.prev_gain_pit, 0, 6); + st->dm_fx.prev_state = 0; + move16(); + } + + /* Update of synthesis filter memories in case of 12k8 core */ + test(); + test(); + IF ( st->prev_bfi && st->last_con_tcx && LT_16(st->L_frame, L_FRAME16k)) + { + synth_mem_updt2( st->L_frame, L_FRAME16k, st->old_exc_fx, st->mem_syn_r, st->mem_syn2_fx, NULL, DEC ); + } + + IF( st->last_con_tcx && st->old_enr_LP ) + { + Word16 enr_LP, ratio; + + /* rescale excitation buffer if LPC energies differs too much */ + enr_LP = Enr_1_Az_fx( A, L_SUBFR ); + + IF(LT_16(st->old_enr_LP, enr_LP)) + { + ratio = div_s(st->old_enr_LP,enr_LP); /* Q15 */ + IF (LT_16(ratio, 26215)) + { + FOR (i = 0; i < L_EXC_MEM_DEC; i++) + { + st->old_exc_fx[i] = mult_r(st->old_exc_fx[i], ratio); + } + } + } + } + + /*------------------------------------------------------------------------* + * Initialize buffers * + *------------------------------------------------------------------------*/ + Copy( st->mem_syn2_fx, mem_back, M); + move16(); + Q_mem_back = st->Q_syn; + /* set ACELP synthesis memory */ + Copy( st->mem_syn2_fx, mem_syn, M ); + + /* set excitation memory*/ + exc=exc_buf+L_EXC_MEM_DEC; + Copy( st->old_exc_fx, exc_buf, L_EXC_MEM_DEC); + *(exc+st->L_frame) = 0; + + /* Init syn buffer */ + syn = syn_buf + M; + Copy( st->mem_syn2_fx, syn_buf, M ); + + /*------------------------------------------------------------------------* + * Fast recovery flag + *------------------------------------------------------------------------*/ + test(); + if(st->prev_bfi && EQ_16(st->coder_type_fx,VOICED)) + { + /*Force BPF to be applied fully*/ + st->bpf_gain_param=3; + move16(); + } + + /*------------------------------------------------------------------------* + * - decode mean_ener_code for gain decoder (d_gain2.c) * + *------------------------------------------------------------------------*/ + Es_pred = 0; + move16(); + IF ( acelp_cfg.nrg_mode>0 ) + { + d_gain_pred(acelp_cfg.nrg_mode, &Es_pred, &prm ); + } + + /*------------------------------------------------------------------------* + * Loop for every subframe in the analysis frame * + *------------------------------------------------------------------------* + * To find the pitch and innovation parameters. The subframe size is * + * L_subfr and the loop is repeated L_ACELP/L_subfr times. * + * - compute impulse response of weighted synthesis filter (h1[]) * + * - compute the target signal for pitch search * + * - find the closed-loop pitch parameters * + * - encode the pitch delay * + * - update the impulse response h1[] by including fixed-gain pitch * + * - find target vector for codebook search * + * - correlation between target vector and impulse response * + * - codebook search * + * - encode codebook address * + * - VQ of pitch and codebook gains * + * - find synthesis speech * + * - update states of weighting filter * + *------------------------------------------------------------------------*/ + + p_A = A; + + FOR (i_subfr = 0; i_subfr < st->L_frame; i_subfr += L_SUBFR) + { + + test(); + IF( EQ_16(st->use_partial_copy,1)&&EQ_16(st->rf_frame_type,RF_NELP)) + { + IF( i_subfr == 0 ) + { + decod_nelp_fx( st, &tmp_noise, dummy_pitch_buf, exc, exc2, voice_factors, bwe_exc, &st->Q_exc, st->bfi, pgainT ); + set32_fx(pitch_buf, L_SUBFR_Q16, NB_SUBFR); + set16_fx(pitch_buffer, 4096, NB_SUBFR); /* L_SUBFR_Q16 in Q6 */ + } + } + ELSE + { + + /*-------------------------------------------------------* + * - Decode adaptive codebook. * + *-------------------------------------------------------*/ + + test(); + IF( EQ_16(st->use_partial_copy,1)&&st->acelp_cfg.gains_mode[i_subfr/L_SUBFR]==0) + { + gain_pit = prev_gain_pit; + } + + IF ( acelp_cfg.ltp_bits != 0 ) + { + /* pitch lag decoding */ + pitch_buf[i_subfr/L_SUBFR] = Mode2_pit_decode( acelp_cfg.ltp_mode, i_subfr, L_SUBFR, &prm, &T0, &T0_frac, &T0_res, + &T0_min, &T0_min_frac, &T0_max, &T0_max_frac, st->pit_min, st->pit_fr1, st->pit_fr1b, st->pit_fr2, st->pit_max, st->pit_res_max); + /* find pitch excitation */ + test(); + IF( EQ_16(st->pit_res_max,6)&&!(st->use_partial_copy)) + { + IF ( EQ_16(T0_res, shr(st->pit_res_max, 1))) + { + pred_lt4( &exc[i_subfr], &exc[i_subfr], T0, shl(T0_frac,1), L_SUBFR+1, pitch_inter6_2, PIT_L_INTERPOL6_2, PIT_UP_SAMP6 ); + } + ELSE + { + pred_lt4( &exc[i_subfr],&exc[i_subfr], T0, T0_frac, L_SUBFR+1, pitch_inter6_2, PIT_L_INTERPOL6_2, PIT_UP_SAMP6 ); + } + } + ELSE + { + IF ( EQ_16(T0_res, shr(st->pit_res_max, 1))) + { + pred_lt4( &exc[i_subfr], &exc[i_subfr], T0, shl(T0_frac,1), L_SUBFR+1, pitch_inter4_2, L_INTERPOL2, PIT_UP_SAMP ); + } + ELSE + { + pred_lt4( &exc[i_subfr], &exc[i_subfr], T0, T0_frac, L_SUBFR+1, pitch_inter4_2, L_INTERPOL2, PIT_UP_SAMP ); + } + } + + /* LP filtering of the adaptive excitation*/ + lp_flag = acelp_cfg.ltf_mode; + move16(); + + IF( EQ_16(acelp_cfg.ltf_mode, NORMAL_OPERATION)) + { + lp_flag = *prm; + move16(); + prm++; + } + + lp_filt_exc_dec_fx(st, MODE2, i_subfr, L_SUBFR, st->L_frame, lp_flag, exc); + + } + ELSE + { + /* No adaptive codebook (UC) */ + set16_fx(&exc[i_subfr], 0, L_SUBFR); + + T0 = L_SUBFR; + T0_frac = 0; + T0_res = 1; + pitch_buf[i_subfr/L_SUBFR] = L_deposit_h(L_SUBFR); + } + + IF( st->igf != 0 ) + { + tbe_celp_exc(st->L_frame, i_subfr, T0, T0_frac, &error, bwe_exc); + } + + pitch_buffer[i_subfr/L_SUBFR] = shl(add(shl(T0,2),T0_frac), 4); + + /*-------------------------------------------------------* + * - Decode innovative codebook. * + *-------------------------------------------------------*/ + test(); + test(); + test(); + test(); + IF( EQ_16(st->use_partial_copy,1)&& + ( EQ_16(st->rf_frame_type,RF_ALLPRED) || + ( EQ_16(st->rf_frame_type,RF_GENPRED) && + ( EQ_16(i_subfr,L_SUBFR) || EQ_16(i_subfr,3*L_SUBFR) )) ) ) + { + set16_fx(code, 0, L_SUBFR); + } + ELSE + { + config = PulseConfTable[acelp_cfg.fixed_cdk_index[i_subfr/L_SUBFR]]; + D_ACELP_indexing( code, config, NB_TRACK_FCB_4T, prm, &st->BER_detect ); + (prm) += 8; + /*-------------------------------------------------------* + * - Add the fixed-gain pitch contribution to code[]. * + *-------------------------------------------------------*/ + + cb_shape_fx( acelp_cfg.pre_emphasis, acelp_cfg.pitch_sharpening, acelp_cfg.phase_scrambling, acelp_cfg.formant_enh, acelp_cfg.formant_tilt, + acelp_cfg.formant_enh_num, acelp_cfg.formant_enh_den, p_A, code, st->tilt_code_fx, extract_h(L_add(pitch_buf[i_subfr/L_SUBFR],26216)), 1, L_SUBFR); + } + /*-------------------------------------------------------* + * - Generate Gaussian excitation * + *-------------------------------------------------------*/ + test(); + IF( EQ_16(acelp_cfg.gains_mode[i_subfr/L_SUBFR],7)&&!st->use_partial_copy) + { + gaus_L2_dec( code2, st->tilt_code_fx, p_A, acelp_cfg.formant_enh_num, &(st->seed_acelp) ); + } + ELSE + { + gain_code2 = L_deposit_l(0); + set16_fx(code2,0,L_SUBFR); + } + + /*-------------------------------------------------* + * - Decode codebooks gains. * + *-------------------------------------------------*/ + IF( st->acelp_cfg.gains_mode[i_subfr/L_SUBFR] != 0 ) + { + decode_acelp_gains( code, acelp_cfg.gains_mode[i_subfr/L_SUBFR], Es_pred, &gain_pit, &gain_code, &prm, &(st->past_gpit), + &(st->past_gcode), &gain_inov, L_SUBFR, code2, &gain_code2 ); + } + IF(st->use_partial_copy&& st->rf_frame_type == RF_ALLPRED) + { + st->past_gcode = 0; + } + IF(st->use_partial_copy&& st->rf_frame_type == RF_NOPRED) + { + st->past_gpit = 67; + } + IF( st->igf != 0 ) + { + /* Rescaling for 12.8k and 16k cores related to BWE */ + IF ( EQ_16(st->L_frame, L_FRAME)) + { + /* 5/2 times resampled past memories*/ + reScaleLen_fx = add(shl(i_subfr, 1), shr(i_subfr, 1)); + reSampLen = (L_SUBFR * HIBND_ACB_L_FAC); + } + ELSE + { + /* 2 times resampled past memories*/ + reScaleLen_fx = shl(i_subfr, 1); + reSampLen = (L_SUBFR * 2); + } + + Rescale_exc(NULL, &exc[i_subfr], &bwe_exc[reScaleLen_fx], + NULL, L_SUBFR, reSampLen, gain_code, &(st->Q_exc), st->Q_subfr, + exc2, i_subfr, GENERIC); + } + ELSE + { + Rescale_exc(NULL, &exc[i_subfr], NULL, NULL, L_SUBFR, 0, + gain_code, &(st->Q_exc), st->Q_subfr, exc2, i_subfr, GENERIC); + } + + /*----------------------------------------------------------* + * Update parameters for the next subframe. * + * - tilt of code: 0.0 (unvoiced) to 0.5 (voiced) * + *----------------------------------------------------------*/ + E_UTIL_voice_factor( exc, i_subfr, code, gain_pit, gain_code, &(st->voice_fac), &(st->tilt_code_fx), L_SUBFR, acelp_cfg.voice_tilt, st->Q_exc, 0); + + pgainT[i_subfr/L_SUBFR] = gain_pit; + move16(); + + /*-------------------------------------------------------* + * - Find the total excitation. * + *-------------------------------------------------------*/ + gain_code_tmp = gain_code; + gain_pit_tmp = gain_pit; + IF( i_subfr == 0 ) + { + gain_code_pre = 0; + } + IF ( EQ_16(st->core,ACELP_CORE)&&EQ_16(st->last_core,ACELP_CORE)&&(EQ_16(st->use_partial_copy,1)||EQ_16(st->prev_use_partial_copy,1))) + { + IF( i_subfr > 0 && GT_16(gain_pit,20152)&>_16(st->prev_tilt_code_dec_fx,6553)&&EQ_16(st->next_coder_type,VOICED) + &&( EQ_16(st->use_partial_copy,1) || EQ_16(st->prev_use_partial_copy, 1) ) ) + { + gain_pit = mult(gain_pit,sub(26214, mult(i_subfr,51))); + } + ELSE IF( !st->prev_use_partial_copy && EQ_16(st->last_coder_type_fx,UNVOICED)&&NE_16(st->next_coder_type,UNVOICED)&<_32(gain_code,gain_code_pre)) + + { + gain_code = 0; + } + } + gain_code_pre = gain_code; + st->tilt_code_dec_fx[i_subfr/L_SUBFR] = st->tilt_code_fx; + + + tmp2 = shr(L_SUBFR, 1); + FOR (j = 0; j < 2; j++) + { + FOR (i = sub(tmp2, shr(L_SUBFR, 1)); i < tmp2; i++) + { + /* code in Q9, gain_pit in Q14, gain_code in Q16; exc Q_new */ + Ltmp = Mpy_32_16_1(gain_code2, code2[i]); + Ltmp = L_shl(Ltmp, add(5,st->Q_exc)); + Ltmp = L_mac(Ltmp, gain_pit, exc[i+i_subfr]); + exc2[i + i_subfr] = round_fx(L_shl(Ltmp, 1)); + + Ltmp2 = Mpy_32_16_1(gain_code, code[i]); + Ltmp2 = L_shl(Ltmp2, add(5,st->Q_exc)); + Ltmp = L_add(Ltmp, Ltmp2); + BASOP_SATURATE_WARNING_OFF_EVS + Ltmp = L_shl(Ltmp, 1); /* saturation can occur here */ + BASOP_SATURATE_WARNING_ON_EVS + exc[i + i_subfr] = round_fx(Ltmp); + } + tmp2 = L_SUBFR; + move16(); + } + + /*-----------------------------------------------------------------* + * Prepare TBE excitation + *-----------------------------------------------------------------*/ + gain_code = gain_code_tmp; + gain_pit = gain_pit_tmp; + IF( st->igf != 0 ) + { + prep_tbe_exc_fx( st->L_frame, +#ifdef ADD_IVAS_TBE_CODE + L_SUBFR, +#endif + i_subfr, gain_pit, gain_code, code, st->voice_fac, &voice_factors[i_subfr/L_SUBFR], bwe_exc, + gain_preQ, code_preQ, st->Q_exc, T0, T0_frac, st->coder_type_fx, st->core_brate +#ifdef ADD_IVAS_TBE_CODE + , st->element_mode, st->idchan, st->hBWE_TD != NULL, 0 +#endif + ); + } + + /*---------------------------------------------------------* + * Enhance the excitation * + *---------------------------------------------------------*/ + E_UTIL_enhancer( st->voice_fac, stab_fac, st->past_gcode, gain_inov, &(st->gc_threshold_fx), code, &exc2[i_subfr], + gain_pit, & st->dm_fx.prev_gain_code, st->dm_fx.prev_gain_pit, & st->dm_fx.prev_state, st->coder_type_fx, + acelp_cfg.fixed_cdk_index[i_subfr/L_SUBFR], L_SUBFR, st->L_frame, st->Q_exc ); + + } /* !RF_NELP frame partial copy */ + /*----------------------------------------------------------* + * - compute the synthesis speech * + *----------------------------------------------------------*/ + rescale_mem(&st->Q_exc, &prev_Q_syn, &st->Q_syn, mem_syn, syn, M, i_subfr); + + E_UTIL_synthesis(sub(st->Q_exc,st->Q_syn), p_A, &exc2[i_subfr], &syn[i_subfr], L_SUBFR, mem_syn, 1, M); + + /*-----------------------------------------------------------------* + * update lp_filtered gains for the case of frame erasure + *-----------------------------------------------------------------*/ + + st->Mode2_lp_gainp = L_add(st->Mode2_lp_gainp, L_mult0(st->past_gpit, weights[i_subfr/L_SUBFR])); /* 2Q29=1Q14*Q15 */ move32(); + st->Mode2_lp_gainc = L_add(st->Mode2_lp_gainc, Mpy_32_16_1(st->past_gcode, weights[i_subfr/L_SUBFR])); /* 15Q16=15Q16*Q15 */ move32(); + + /*----------------------------------------------------------* + * - update pitch lag for guided ACELP * + *----------------------------------------------------------*/ + test(); + if( st->enableGplc && EQ_16( shr(i_subfr,6), sub(st->nb_subfr,1) )) + { + st->T0_4th = T0; + move16(); + } + + /*----------------------------------------------------------* + * - Update LPC coeffs * + *----------------------------------------------------------*/ + p_A += (M+1); + + /* copy current gain for next subframe use, in case there is no explicit encoding */ + prev_gain_pit = gain_pit; + } /* end of subframe loop */ + + IF(st->BER_detect) + { + FOR (i=0; iL_frame; i++) + { + exc[i] = 0; + move16(); + } + + int_lsp_fx( st->L_frame, st->old_lsp_q_cng, st->lsp_q_cng, st->Aq_cng, M, interpol_frac_fx, 0 ); + + p_A = st->Aq_cng; + IF(st->last_good_fx < UNVOICED_TRANSITION ) + { + Copy(st->mem_syn2_fx, mem_syn, M ); + } + ELSE + { + set16_fx( mem_syn, 0, M ); + } + + FOR (i_subfr = 0; i_subfr < st->L_frame; i_subfr += L_SUBFR) + { + E_UTIL_synthesis(sub(st->Q_exc,st->Q_syn), p_A, &exc[i_subfr], &syn[i_subfr], L_SUBFR, mem_syn, 1, M); + p_A += (M+1); + } + } + + tmp = 0; + move16(); + pA = A+(st->nb_subfr-1)*(M+1); + set16_fx(h1, 0, add(L_SUBFR,1)); + set16_fx(mem, 0, M); + h1[0] = 32768/32; + move16(); + E_UTIL_synthesis(0, pA, h1, h1, L_SUBFR, mem, 0, M); /* impulse response of LPC */ + deemph_fx(h1, st->preemph_fac, L_SUBFR, &tmp); /* impulse response of deemph */ + /* impulse response level = gain introduced by synthesis+deemphasis */ + Ltmp = Dot_productSq16HQ( 0, h1, L_SUBFR, &st->last_gain_syn_deemph_e); + st->last_gain_syn_deemph_e= add(st->last_gain_syn_deemph_e,10/*scaling of h1[0] and E_UTIL_synthesis * 2*/); +#ifdef BASOP_NOGLOB + st->last_gain_syn_deemph = round_fx_sat(Sqrt32(Ltmp,&st->last_gain_syn_deemph_e)); +#else + st->last_gain_syn_deemph = round_fx(Sqrt32(Ltmp,&st->last_gain_syn_deemph_e)); +#endif + + /* Do the classification */ + { + Word16 pit16[NB_SUBFR16k]; + Word16 k; + FOR(k = 0 ; k < st->nb_subfr ; k++) + { + pit16[k] = shl(extract_h(pitch_buf[k]),6);/*Q6*/ + } + + FEC_clas_estim_fx(st, /*Opt_AMR_WB*/0, st->L_frame, &(st->clas_dec), st->core_ext_mode, pit16, syn, + &st->lp_ener_FER_fx, /**decision_hyst*/NULL, /**UV_cnt*/ NULL, /**LT_UV_cnt*/ NULL, /**Last_ener*/ NULL, /**locattack*/ NULL, + /**lt_diff_etot*/NULL, /**amr_io_class*/ NULL, /*bitrate*/ 0 , st->Q_syn, /**class_para*/ NULL, st->mem_syn_clas_estim_fx, + &st->classifier_Q_mem_syn, -32768/*-1.f Q15*/, 0/*CLASSIFIER_ACELP*/, 0/*bfi*/, st->last_core_brate, -1); + } + + /* Update Pitch Lag memory */ + + Copy32(&st->old_pitch_buf_fx[st->nb_subfr], st->old_pitch_buf_fx, st->nb_subfr); + Copy32(pitch_buf, &st->old_pitch_buf_fx[st->nb_subfr], st->nb_subfr); + + + { + Word16 pBuf_scaleSyn[NB_SUBFR16k]; + + FOR(i=0; i<(st->L_frame/L_SUBFR); i++) + { + pBuf_scaleSyn[i] = round_fx(pitch_buf[i]); + } + + Scale_sig(mem_back, M, sub(st->Q_syn,Q_mem_back)); + + force_scale_syn = 0; + move16(); + test(); + test(); + test(); + IF ( (EQ_16(st->clas_dec,ONSET))||((GE_16(st->last_good_fx,VOICED_TRANSITION))&&(LT_16(st->last_good_fx,INACTIVE_CLAS)))) + { + force_scale_syn = 1; + move16(); + } + + FEC_scale_syn_fx( st->L_frame, &update_flg,st->clas_dec, st->last_good_fx, syn, pBuf_scaleSyn, st->enr_old_fx, 0, + st->coder_type_fx, LSF_Q_prediction, &st->scaling_flag, &st->lp_ener_FEC_av, &st->lp_ener_FEC_max, st->bfi, st->total_brate, st->prev_bfi, st->last_core_brate, + exc, exc2, A, &(st->old_enr_LP), mem_back, mem_syn, st->Q_exc, st->Q_syn , avoid_lpc_burst_on_recovery , force_scale_syn); + } + /* update ACELP synthesis memory */ + Copy( mem_syn, st->mem_syn2_fx, M ); + Copy( syn+st->L_frame-L_SYN_MEM, st->mem_syn_r, L_SYN_MEM ); + + /* Deemphasis and output synth and ZIR */ + tmp_deemph = st->syn[M]; + move16(); + E_UTIL_deemph2(st->Q_syn, syn, st->preemph_fac, st->L_frame, &tmp_deemph); /* tmp_deemph and syn in Q0 starting from here*/ + + bufferCopyFx(syn+st->L_frame- st->L_frame/2, hTcxDec->old_syn_Overl, shr(st->L_frame, 1),0 /*Qf_syn*/, -1 /*Qf_old_xnq*/, 0 , 0 /*Q_old_xnq*/); + + Copy(syn+st->L_frame-M-1, st->syn, 1+M); /*Q0*/ + + Copy(syn, synth, st->L_frame); + IF (st->hBWE_TD != NULL) + { + Copy(syn, hBWE_TD->old_core_synth_fx, st->L_frame); + } + + + /* update old_Aq */ + Copy(exc_buf+st->L_frame, st->old_exc_fx, L_EXC_MEM_DEC); + + /* Output pitch parameters for bass post-filter */ + FOR (i_subfr = 0; i_subfr < st->L_frame; i_subfr += L_SUBFR) + { + *pT++ = round_fx(pitch_buf[i_subfr/L_SUBFR]); + } + + + hTcxDec->tcxltp_last_gain_unmodified = 0; + + /*Update MODE1*/ + Copy( p_A-(M+1), st->old_Aq_12_8_fx, M+1 ); + st->old_Es_pred_fx = Es_pred; + + hTcxDec->tcxltp_third_last_pitch = hTcxDec->tcxltp_second_last_pitch; + hTcxDec->tcxltp_second_last_pitch = st->old_fpitch; + st->old_fpitch = pitch_buf[shr(st->L_frame, 6) - 1]; + move32(); + + + return; +} + diff --git a/lib_dec/dec_acelp.c b/lib_dec/dec_acelp.c index 615fa8eae1a0e14a0e2788a2cc61e897b3ca9178..c6572792e7193432cc2c947aac32c10967c1e086 100644 --- a/lib_dec/dec_acelp.c +++ b/lib_dec/dec_acelp.c @@ -45,14 +45,14 @@ * Local function prototypes *---------------------------------------------------------------------*/ -static void D_ACELP_decode_arithtrack( float v[], uint32_t s, int16_t p, const int16_t trackstep, const int16_t tracklen ); +static void D_ACELP_decode_arithtrack_ivas( float v[], uint32_t s, int16_t p, const int16_t trackstep, const int16_t tracklen ); /*---------------------------------------------------------------------* - * Function D_ACELP_indexing() + * Function D_ACELP_indexing_ivas() * *---------------------------------------------------------------------*/ -void D_ACELP_indexing( +void D_ACELP_indexing_ivas( float code[], PulseConfig config, const int16_t num_tracks, @@ -142,11 +142,11 @@ void D_ACELP_indexing( if ( config.bits == 43 ) { - D_ACELP_decode_43bit( idxs, code, pulsestrack ); + D_ACELP_decode_43bit_flt( idxs, code, pulsestrack ); } else { - fcb_pulse_track_joint_decode( idxs, wordcnt, index_n, pulsestrack, num_tracks ); + fcb_pulse_track_joint_decode_ivas( idxs, wordcnt, index_n, pulsestrack, num_tracks ); for ( track = num_tracks - 1; track >= 1; track-- ) { @@ -158,7 +158,7 @@ void D_ACELP_indexing( /* decode state to actual pulse positions on track */ /*D_ACELP_decode_arithtrack_old(code+track, s, pulses, 4); */ - D_ACELP_decode_arithtrack( code + track, s, pulses, num_tracks, 16 ); + D_ACELP_decode_arithtrack_ivas( code + track, s, pulses, num_tracks, 16 ); } else { @@ -180,7 +180,7 @@ void D_ACELP_indexing( } if ( pulses ) { - D_ACELP_decode_arithtrack( code, s, pulses, num_tracks, 16 ); + D_ACELP_decode_arithtrack_ivas( code, s, pulses, num_tracks, 16 ); } else { @@ -196,7 +196,7 @@ void D_ACELP_indexing( } -static void D_ACELP_decode_arithtrack( +static void D_ACELP_decode_arithtrack_ivas( float v[], uint32_t s, int16_t p, @@ -244,7 +244,7 @@ static void D_ACELP_decode_arithtrack( } -void fcb_pulse_track_joint_decode( +void fcb_pulse_track_joint_decode_ivas( uint16_t *idxs, const int16_t wordcnt, uint32_t *index_n, diff --git a/lib_dec/dec_acelp_fx.c b/lib_dec/dec_acelp_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..392adb1dffae439cf6890ef1b38f8516c1b1c51b --- /dev/null +++ b/lib_dec/dec_acelp_fx.c @@ -0,0 +1,376 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include +#include +#include +#include "options.h" +#include "basop_util.h" +#include "prot_fx1.h" +#include "prot_fx2.h" +#include "rom_com.h" +#include "rom_basop_util.h" + +#define _1_CODE 0x200 /*codebook excitation Q9 */ + +/*---------------------------------------------------------------------* + * Local function prototypes + *---------------------------------------------------------------------*/ +static void D_ACELP_decode_arithtrack(Word16 v[], Word32 s, Word16 p, Word16 trackstep, Word16 tracklen); + +/*---------------------------------------------------------------------* +* Function D_ACELP_indexing() +* +*---------------------------------------------------------------------*/ + +void D_ACELP_indexing( + Word16 code[], + PulseConfig config, + Word16 num_tracks, + Word16 index[] + ,Word16 *BER_detect +) +{ + Word16 track, pulses, k, pulsestrack[NB_TRACK_FCB_4T]; + Word32 s; + Word16 trackpos; + UWord16 *idxs; + UWord32 idxs32[4], index_n[NB_TRACK_FCB_4T]; + Word16 restpulses, wordcnt, wordcnt32; + + assert(num_tracks == NB_TRACK_FCB_4T); + + wordcnt = shr(add(config.bits,15),4); /* ceil(bits/16) */ + + /* check if some tracks have more pulses */ + restpulses = s_and((Word16)config.nb_pulse, sub(num_tracks, 1)); + + /* cast to short */ + idxs= (UWord16 *)idxs32; + FOR (k=0; k=1; track--) + { + pulses = pulsestrack[track]; + move16(); + + IF (pulses) + { + /* divide by number of possible states: rest is actual state and + * the integer part goes to next track */ + s = index_n[track]; + /* decode state to actual pulse positions on track */ + D_ACELP_decode_arithtrack(code+track, s, pulses, num_tracks, 16); + } + ELSE /* track is empty */ + { + FOR (k=track; k < 16*num_tracks; k+=num_tracks) + { + code[k] = 0; + move16(); + } + } + } + + s = L_add(index_n[0], 0); + pulses = pulsestrack[0]; + move16(); + + /* safety check in case of bit errors */ + IF( GE_32(s,pulsestostates[16][pulses-1])) + { + set16_fx( code, 0, L_SUBFR ); + *BER_detect = 1; + move16(); + return; + } + + IF (pulses) + { + D_ACELP_decode_arithtrack(code, s, pulses, num_tracks, 16); + } + ELSE {/* track is empty */ + FOR (k=0; k < 16*num_tracks; k+=num_tracks) + { + code[k] = 0; + move16(); + } + } + } +} + +static void D_ACELP_decode_arithtrack(Word16 v[], Word32 s, Word16 p, Word16 trackstep, Word16 tracklen) +{ + Word16 k, idx; + + /*initialy s was UWords32 but it seems that s is never greater then 0x80000000*/ + /*this assumption reduces complexity but if it is not true than exit*/ + assert(s >= 0); + + FOR (k=(tracklen)-1; k>= 0; k--) + { + idx = imult1616(k,trackstep); + v[idx] = 0; /* default: there is no pulse here */ move16(); + + FOR(; p; p--) /* one pulse placed, so one less left */ + { + IF (LT_32(s, pulsestostates[k][p-1])) + { + BREAK; + } + + s = L_sub(s, pulsestostates[k][p-1]); + + IF (v[idx] != 0) /* there is a pulse here already = sign is known */ + { + if (v[idx] > 0) + { + v[idx] = add(v[idx],_1_CODE); /* place one more pulse here */ move16(); + } + if (v[idx] <= 0) + { + v[idx] = sub(v[idx],_1_CODE); /* place one more pulse here */ move16(); + } + } + ELSE /* this is the first pulse here -> determine sign */ + { + v[idx] = +_1_CODE; /* place a negative pulse here */ move16(); + if (L_and(s, 0x1) != 0) + { + v[idx] = -_1_CODE; /* place a negative pulse here */ move16(); + } + s = L_lshr(s,1); + } + } + } +} + +void fcb_pulse_track_joint_decode(UWord16 *idxs, Word16 wordcnt, UWord32 *index_n, Word16 *pulse_num, Word16 track_num) +{ + Word16 hi_to_low[10] = { 0, 0, 0, 3, 9, 5, 3, 1, 8, 8}; + + UWord32 index; + Word32 indx_tmp; + Word16 indx_flag, indx_flag_1; + Word16 track, track_num1, pulse_num0, pulse_num1; + Word32 div_tmp; + Word16 indx_flag_2; + + indx_flag = 0; + move16(); + indx_flag_1 = 0; + move16(); + indx_flag_2 = 0; + move16(); + + FOR (track = 0; track < track_num; track++) + { + indx_flag = add(indx_flag, shr(pulse_num[track], 2)); + indx_flag_1 = add(indx_flag_1, shr(pulse_num[track], 1)); + indx_flag_2 = add(indx_flag_2, shr(pulse_num[track], 3)); + } + + hi_to_low[4] = 1; + move16(); + if (GE_16(indx_flag, track_num)) + { + hi_to_low[4] = 9; + move16(); + } + + hi_to_low[7] = 1; + move16(); + if (GE_16(indx_flag_2, 1)) + { + hi_to_low[7] = 9; + move16(); + } + + IF (GE_16(indx_flag_1, track_num)) + { + IF (GE_16(indx_flag, track_num)) + { + index = L_deposit_l(0); + IF (GE_16(indx_flag_2, 1)) + { + FOR (track = sub(wordcnt, 1); track >= 6; track--) + { + index = L_add(L_lshl(index, 16), (UWord32) idxs[track]); + } + index_n[3] = L_add(L_lshl(idxs[5], 8), L_and(L_lshr(idxs[4], 8), 0xFF)); + move32(); + index_n[2] = L_and(L_add(L_lshl(idxs[4], 16), idxs[3]), 0xFFFFFF); + move32(); + index_n[1] = L_add(L_lshl(idxs[2], 8), L_and(L_lshr(idxs[1], 8), 0xFF)); + move32(); + index_n[0] = L_and(L_add(L_lshl(idxs[1], 16), idxs[0]), 0xFFFFFF); + move32(); + } + ELSE + { + FOR (track = (wordcnt-1); track >= track_num; track--) + { + index = L_add(L_lshl(index, 16), (UWord32) idxs[track]); + } + FOR (track = 0; track < track_num; track++) + { + index_n[track] = (UWord32) idxs[track]; + move32(); + } + } + } + ELSE + { + index = L_deposit_l(0); + FOR (track = (wordcnt-1); track >= 2; track--) + { + index = L_add(L_lshl(index, 16), (UWord32) idxs[track]); + } + + index_n[3] = L_and((Word32) idxs[1], 0xFF); + move32(); + index_n[2] = L_lshr((Word32) idxs[1], 8); + move32(); + index_n[1] = L_and((Word32) idxs[0], 0xFF); + move32(); + index_n[0] = L_lshr((Word32) idxs[0], 8); + move32(); + } + + track_num1 = sub(track_num, 1); + pulse_num1 = pulse_num[track_num1]; + move16(); + index = L_add(L_lshl(index, hi_to_low[pulse_num1]), L_lshr(index_n[track_num1], low_len[pulse_num1])); + FOR (track = (track_num-1); track > 0; track--) + { + track_num1 = sub(track, 1); + pulse_num0 = pulse_num[track_num1]; + move16(); + pulse_num1 = pulse_num[track]; + move16(); + index = L_add(L_lshl(index, hi_to_low[pulse_num0]), L_lshr(index_n[track_num1], low_len[pulse_num0])); + + iDiv_and_mod_32(index, indx_fact[pulse_num1], &div_tmp, &indx_tmp, 0); + index_n[track] = L_add(L_and(index_n[track], low_mask[pulse_num1]), L_lshl(indx_tmp, low_len[pulse_num1])); + index = L_add(div_tmp, 0); + } + pulse_num1 = pulse_num[0]; + move16(); + index_n[0] = L_add(L_and(index_n[0], low_mask[pulse_num1]), L_lshl(index, low_len[pulse_num1])); + move32(); + } + ELSE + { + index = L_deposit_l(0); + FOR (track = (wordcnt-1); track >= 0; track--) + { + index = L_add(L_lshl(index, 16), (UWord32) idxs[track]); + } + FOR (track = 3; track > 0; track--) + { + pulse_num1 = pulse_num[track]; + move16(); + index_n[track] = L_and(index, index_mask_ACELP[pulse_num1]); + move32(); + index = L_lshr(index, index_len[pulse_num1]); + } + index_n[0] = index; + move32(); + } + + return; +} + diff --git a/lib_dec/dec_acelp_tcx_main.c b/lib_dec/dec_acelp_tcx_main.c index 94febad5e786f360bec721cbc8136bf7719dbc65..809c64aed0c5c154279154d3141d39329667c72e 100644 --- a/lib_dec/dec_acelp_tcx_main.c +++ b/lib_dec/dec_acelp_tcx_main.c @@ -43,12 +43,12 @@ #include "wmc_auto.h" /*-------------------------------------------------------------------* - * decode_frame_type() + * decode_frame_type_flt() * * *--------------------------------------------------------------------*/ -static void decode_frame_type( +static void decode_frame_type_flt( Decoder_State *st, /* i/o: decoder state structure */ STEREO_CNG_DEC_HANDLE hStereoCng /* i/o: Stereo CNG data structure */ ) @@ -195,15 +195,15 @@ static void decode_frame_type( st->rate_switching_init = 1; /* Reconf Core */ - mode_switch_decoder_LPD( st, st->bwidth, st->total_brate, st->last_total_brate, frame_size_index, 0, st->element_mode ); + mode_switch_decoder_LPD_flt( st, st->bwidth, st->total_brate, st->last_total_brate, frame_size_index, 0, st->element_mode ); /* Reconf. CLDFB: check if the CLDFB works on the right sample rate */ if ( ( st->cldfbAna->no_channels * st->cldfbAna->no_col ) != st->L_frame ) { - resampleCldfb( st->cldfbAna, ( st->L_frame * FRAMES_PER_SEC ) ); + resampleCldfb_ivas( st->cldfbAna, ( st->L_frame * FRAMES_PER_SEC ) ); if ( st->L_frame <= L_FRAME16k ) { - resampleCldfb( st->cldfbBPF, ( st->L_frame * FRAMES_PER_SEC ) ); + resampleCldfb_ivas( st->cldfbBPF, ( st->L_frame * FRAMES_PER_SEC ) ); } } if ( st->bwidth == NB ) @@ -217,27 +217,27 @@ static void decode_frame_type( } /*Reconf Frequency-domain based CNG*/ - configureFdCngDec( st->hFdCngDec, st->bwidth, st->rf_flag == 1 && st->total_brate == ACELP_13k20 ? ACELP_9k60 : st->total_brate, st->L_frame, st->last_L_frame, st->element_mode ); + configureFdCngDec_flt( st->hFdCngDec, st->bwidth, st->rf_flag == 1 && st->total_brate == ACELP_13k20 ? ACELP_9k60 : st->total_brate, st->L_frame, st->last_L_frame, st->element_mode ); if ( st->last_L_frame != st->L_frame && st->L_frame <= L_FRAME16k && st->last_L_frame <= L_FRAME16k ) { - lerp_flt( st->hFdCngDec->hFdCngCom->olapBufferSynth2, st->hFdCngDec->hFdCngCom->olapBufferSynth2, st->L_frame * 2, st->last_L_frame * 2 ); + lerp_flt( st->hFdCngDec->hFdCngCom->olapBufferSynth2_flt, st->hFdCngDec->hFdCngCom->olapBufferSynth2_flt, st->L_frame * 2, st->last_L_frame * 2 ); if ( st->m_frame_type == SID_FRAME && st->hFdCngDec->hFdCngCom->frame_type_previous != ACTIVE_FRAME ) { - lerp_flt( st->hFdCngDec->hFdCngCom->olapBufferSynth, st->hFdCngDec->hFdCngCom->olapBufferSynth, st->L_frame * 2, st->last_L_frame * 2 ); + lerp_flt( st->hFdCngDec->hFdCngCom->olapBufferSynth_flt, st->hFdCngDec->hFdCngCom->olapBufferSynth_flt, st->L_frame * 2, st->last_L_frame * 2 ); lerp_flt( hStereoCng->olapBufferSynth22, hStereoCng->olapBufferSynth22, st->L_frame * 2, st->last_L_frame * 2 ); if ( st->L_frame == L_FRAME ) { for ( n = 0; n < st->L_frame * 2; n++ ) { - st->hFdCngDec->hFdCngCom->olapBufferSynth[n] = st->hFdCngDec->hFdCngCom->olapBufferSynth[n] * 1.25f; + st->hFdCngDec->hFdCngCom->olapBufferSynth_flt[n] = st->hFdCngDec->hFdCngCom->olapBufferSynth_flt[n] * 1.25f; } } else { for ( n = 0; n < st->L_frame * 2; n++ ) { - st->hFdCngDec->hFdCngCom->olapBufferSynth[n] = st->hFdCngDec->hFdCngCom->olapBufferSynth[n] / 1.25f; + st->hFdCngDec->hFdCngCom->olapBufferSynth_flt[n] = st->hFdCngDec->hFdCngCom->olapBufferSynth_flt[n] / 1.25f; } } } @@ -246,7 +246,7 @@ static void decode_frame_type( if ( st->bwidth != st->last_bwidth ) { st->hFdCngDec->hFdCngCom->msFrCnt_init_counter = 0; - st->hFdCngDec->hFdCngCom->init_old = FLT_MAX; + st->hFdCngDec->hFdCngCom->init_old_flt = FLT_MAX; } if ( st->tcxonly ) @@ -267,12 +267,12 @@ static void decode_frame_type( /*-------------------------------------------------------------------* - * dec_acelp_tcx_frame() + * dec_acelp_tcx_frame_flt() * * Main decoding function *--------------------------------------------------------------------*/ -void dec_acelp_tcx_frame( +void dec_acelp_tcx_frame_flt( Decoder_State *st, /* i/o: decoder state structure */ int16_t *concealWholeFrame, /* i/o: concealment flag */ float *output, /* o : synthesis */ @@ -292,7 +292,7 @@ void dec_acelp_tcx_frame( float old_bwe_exc[( PIT16k_MAX + ( L_FRAME16k + 1 ) + L_SUBFR16k ) * 2]; /* excitation buffer */ float *ptr_bwe_exc; /* pointer to BWE excitation signal in the current frame */ - push_wmops( "dec_acelp_tcx_frame" ); + push_wmops( "dec_acelp_tcx_frame_flt" ); start_bit_pos = st->next_bit_pos; if ( st->rf_flag == 1 ) @@ -314,7 +314,7 @@ void dec_acelp_tcx_frame( int16_t L_frame = st->L_frame; int32_t total_brate = st->last_total_brate; - decode_frame_type( st, hStereoCng ); + decode_frame_type_flt( st, hStereoCng ); st->force_lpd_reset = 0; @@ -397,7 +397,7 @@ void dec_acelp_tcx_frame( /* Decode the LPD data */ if ( st->m_decodeMode == DEC_NO_FRAM_LOSS ) { - decoder_LPD( st, output, pcmbufFB, &tmp, bpf_noise_buf, 0, &bitsRead, param, pitch_buf, voice_factors, ptr_bwe_exc ); + decoder_LPD_flt( st, output, pcmbufFB, &tmp, bpf_noise_buf, 0, &bitsRead, param, pitch_buf, voice_factors, ptr_bwe_exc ); if ( !st->rate_switching_init && ( st->last_codec_mode ) == MODE2 && !( st->use_partial_copy && st->rf_frame_type >= RF_TCXFD && st->rf_frame_type <= RF_TCXTD2 ) && st->bfi ) { @@ -408,7 +408,7 @@ void dec_acelp_tcx_frame( } else if ( st->m_decodeMode == DEC_CONCEALMENT_EXT ) { - decoder_LPD( st, output, pcmbufFB, NULL, bpf_noise_buf, 1, /* bfi - st->bfi can be 0 here - MODE2 stays in PLC when DTX appears after a loss */ + decoder_LPD_flt( st, output, pcmbufFB, NULL, bpf_noise_buf, 1, /* bfi - st->bfi can be 0 here - MODE2 stays in PLC when DTX appears after a loss */ &bitsRead, NULL, pitch_buf, voice_factors, ptr_bwe_exc ); } @@ -468,7 +468,7 @@ void dec_acelp_tcx_frame( if ( st->m_frame_type == SID_FRAME ) { /* Decode the FD-CNG bitstream */ - FdCng_decodeSID( st ); + FdCng_decodeSID_flt( st ); } /* updates */ diff --git a/lib_dec/dec_acelp_tcx_main_fx.c b/lib_dec/dec_acelp_tcx_main_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..5ba4c53d3b4f3ee10c0a4c7fa911e871bb0114d4 --- /dev/null +++ b/lib_dec/dec_acelp_tcx_main_fx.c @@ -0,0 +1,530 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + + +#include +#include +#include "options.h" +#include "rom_com.h" +#include "stat_com.h" +#include "prot_fx1.h" +#include "prot_fx2.h" +#include "basop_util.h" + +static +void decode_frame_type(Decoder_State *st +#ifdef IVAS_CODE_CNG + , STEREO_CNG_DEC_HANDLE hStereoCng +#endif +) +{ + Word32 L_tmp; + Word16 num_bits; + UWord16 lsb; + Word16 frame_size_index; + Word16 n; + Word32 total_brate; + Word16 frame_len_indicator; + + frame_size_index = 0; + move16(); + total_brate = st->total_brate; + move16(); + + Mpy_32_16_ss(st->total_brate, 5243, &L_tmp, &lsb); /* 5243 is 1/50 in Q18. (0+18-15=3) */ + num_bits = extract_l(L_shr(L_tmp, 3)); /* Q0 */ + + + /* Get Frame Type (NULL,SID,ACTIVE) and Frame Mode (2kbps, 4kbps,...) */ + + IF (EQ_16(st->mdct_sw, MODE1)) + { + st->m_frame_type = ACTIVE_FRAME; + move16(); + + FOR (n=0; ntotal_brate, FRAME_NO_DATA)) + { + st->bwidth = st->last_bwidth; + move16(); + st->m_frame_type = ZERO_FRAME; + move16(); + } + + /* SID frame */ + ELSE IF ( EQ_32(st->total_brate, SID_2k40)) + { + st->cng_type = get_next_indice(st, 1); + if( NE_16(st->cng_type, FD_CNG)) + { + st->BER_detect = 1; + } + st->m_frame_type = SID_FRAME; + move16(); + frame_size_index = 1; + move16(); + st->bwidth = get_next_indice(st, 2); + move16(); + + frame_len_indicator = get_next_indice(st, 1); + IF ( EQ_16(st->bwidth, NB)) + { + if( frame_len_indicator ) + { + st->BER_detect = 1; + move16(); + } + frame_len_indicator = 0; + move16(); + } + IF ( frame_len_indicator == 0 ) + { + st->L_frame = L_FRAME; + st->total_brate = ACELP_9k60; + } + ELSE + { + st->L_frame = L_FRAME16k; + IF ( st->last_total_brate== ACELP_16k40 || st->last_total_brate== ACELP_24k40) + { + st->total_brate = st->last_total_brate; + } + ELSE + { + st->total_brate = ACELP_16k40; + } + } + + Mpy_32_16_ss(st->total_brate, 5243, &L_tmp, &lsb); /* 5243 is 1/50 in Q18. (0+18-15=3) */ + num_bits = extract_l(L_shr(L_tmp, 3)); /* Q0 */ + FOR (n=0; nm_frame_type = ACTIVE_FRAME; + move16(); + + FOR (n=0; nrf_flag == 0) + { + + /* Get bandwidth mode */ + st->bwidth = get_next_indice(st, FrameSizeConfig[frame_size_index].bandwidth_bits); + + st->bwidth = add(st->bwidth, FrameSizeConfig[frame_size_index].bandwidth_min); + + } + ELSE + { + st->bwidth += FrameSizeConfig[frame_size_index].bandwidth_min; + } + + IF (GT_16(st->bwidth, FB)) + { + st->bwidth = FB; + move16(); + st->BER_detect = 1; + move16(); + } + + test(); + IF ( GT_16(st->bwidth, SWB)&<_32(st->total_brate,ACELP_16k40)) + { + st->bwidth = SWB; + move16(); + st->BER_detect = 1; + move16(); + } + + /* Get reserved bits */ + IF (FrameSizeConfig[frame_size_index].reserved_bits && st->rf_flag == 0) + { + Word16 dummyBit; + dummyBit = (Word8)get_next_indice(st, 1); + move16(); + if (dummyBit != 0) + { + st->BER_detect = 1; + move16(); + } + assert( FrameSizeConfig[frame_size_index].reserved_bits == 1); + } + } + } + + st->rate_switching_init = 0; + move16(); + + if( st->last_codec_mode != MODE2 || !st->BER_detect ) + { + /* Mode or Rate Change */ + test(); + test(); + test(); + IF ( (EQ_16(st->m_frame_type, ACTIVE_FRAME)||EQ_16(st->m_frame_type,SID_FRAME))&&(s_or(s_or(s_or(s_or((Word16)NE_32(st->total_brate,st->last_total_brate),(Word16)NE_16(st->bwidth,st->last_bwidth)),(Word16)EQ_16(st->last_codec_mode,MODE1)),(Word16)NE_16(st->rf_flag,st->rf_flag_last)),st->force_lpd_reset))) + { + st->rate_switching_init = 1; + move16(); + + /* Reconf Core */ +#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT + mode_switch_decoder_LPD(st, st->bwidth, st->total_brate, st->last_total_brate, frame_size_index, 0, st->element_mode); +#else + mode_switch_decoder_LPD( st, st->bwidth, st->total_brate, frame_size_index ); +#endif + /* Reconf CLDFB */ + IF( NE_16 (i_mult(st->cldfbAna_fx->no_channels,st->cldfbAna_fx->no_col), st->L_frame) ) + { + Word16 newCldfbBands = CLDFB_getNumChannels(L_mult0(st->L_frame,50)); + + resampleCldfb( st->cldfbAna_fx, newCldfbBands, st->L_frame, 0 ); + IF ( LE_16(st->L_frame,L_FRAME16k) ) + { + resampleCldfb( st->cldfbBPF_fx, newCldfbBands, st->L_frame, 0 ); + } + } + IF ( EQ_16(st->bwidth,NB)) + { + st->cldfbSyn_fx->bandsToZero = sub (st->cldfbSyn_fx->no_channels,10); + } + ELSE + { + st->cldfbSyn_fx->bandsToZero = 0; + } + + /* Reconf FD-CNG */ + L_tmp = st->total_brate; + move32(); + test(); + if( EQ_16(st->rf_flag,1)&&EQ_32(st->total_brate,ACELP_13k20)) + { + L_tmp = ACELP_9k60; + move32(); + } + configureFdCngDec( st->hFdCngDec_fx, st->bwidth, L_tmp, st->L_frame, st->last_L_frame, st->element_mode); + test(); + test(); + IF ( (NE_16(st->last_L_frame,st->L_frame))&&(LE_16(st->L_frame, L_FRAME16k))&&(LE_16(st->last_L_frame, L_FRAME16k))) + { + lerp( st->hFdCngDec_fx->hFdCngCom->olapBufferSynth2, st->hFdCngDec_fx->hFdCngCom->olapBufferSynth2, st->L_frame*2, st->last_L_frame*2 ); + test(); + IF ( EQ_16(st->m_frame_type, SID_FRAME)&&NE_16(st->hFdCngDec_fx->hFdCngCom->frame_type_previous,ACTIVE_FRAME)) + { + lerp( st->hFdCngDec_fx->hFdCngCom->olapBufferSynth, st->hFdCngDec_fx->hFdCngCom->olapBufferSynth, st->L_frame*2, st->last_L_frame*2 ); +#ifdef IVAS_CODE_CNG + lerp(hStereoCng->olapBufferSynth22, hStereoCng->olapBufferSynth22, st->L_frame * 2, st->last_L_frame * 2); +#endif + IF( EQ_16(st->L_frame, L_FRAME)) + { + FOR( n=0; n < st->L_frame*2; n++ ) + { + st->hFdCngDec_fx->hFdCngCom->olapBufferSynth[n] = mult_r( st->hFdCngDec_fx->hFdCngCom->olapBufferSynth[n], 20480 ); + } + } + ELSE + { + FOR( n=0; n < st->L_frame*2; n++ ) + { + st->hFdCngDec_fx->hFdCngCom->olapBufferSynth[n] = mult_r( shl(st->hFdCngDec_fx->hFdCngCom->olapBufferSynth[n],1), 26214 ); + } + } + } + } + IF ( NE_16(st->bwidth,st->last_bwidth)) + { + st->hFdCngDec_fx->hFdCngCom->msFrCnt_init_counter = 0; + st->hFdCngDec_fx->hFdCngCom->init_old = 32767; + } + + /* Reconf BPF */ + st->p_bpf_noise_buf=NULL; + IF (st->tcxonly == 0) + { + st->p_bpf_noise_buf = st->bpf_noise_buf; + } + } + } + + st->total_brate = total_brate; + +} + + +Word16 dec_acelp_tcx_frame( + Decoder_State *st, /* i/o: decoder state structure */ + Word16* concealWholeFrame, /* i/o: concealment flag */ + Word16* pcmBuf, /* o : synthesis */ + Word16* bpf_noise_buf, /* i/o: BPF noise buffer */ + Word16* pcmbufFB, /* o : synthesis @output_FS */ + Word32 bwe_exc_extended[], /* i/o: bandwidth extended excitation */ + Word16* voice_factors, /* o : voicing factors */ + Word16 pitch_buf[] /* o : floating pitch for each subframe */ +#ifdef IVAS_CODE_CNG + , STEREO_CNG_DEC_HANDLE hStereoCng /* i : stereo CNG handle */ +#endif + ) +{ + Word16 num_bits; + Word32 L_tmp; + UWord16 lsb; + Word16 bitsRead; + Word16 tmp; + Word16 i; + Word16 start_bit_pos; + Word16 param[DEC_NPRM_DIV*NB_DIV+NPRM_LPC_NEW]; + Word16 old_bwe_exc[(PIT16k_MAX + (L_FRAME16k + 1) + L_SUBFR16k) * 2]; /* excitation buffer */ + Word16 *ptr_bwe_exc; /* pointer to BWE excitation signal in the current frame */ + TD_BWE_DEC_HANDLE hBWE_TD; + hBWE_TD = st->hBWE_TD; + + Mpy_32_16_ss(st->total_brate, 5243, &L_tmp, &lsb); /* 5243 is 1/50 in Q18. (0+18-15=3) */ + num_bits = extract_l(L_shr(L_tmp, 3)); /* Q0 */ + + /* -------------------------------------------------------------- */ + /* Set the bit-stream */ + /* -------------------------------------------------------------- */ + + + start_bit_pos = st->next_bit_pos; + move16(); + + if( EQ_16(st->rf_flag,1)) + { + start_bit_pos = sub(start_bit_pos,2); + } + /* -------------------------------------------------------------- */ + /* IDENTIFY FRAME TYPE */ + /* -------------------------------------------------------------- */ + + st->m_old_frame_type = st->m_frame_type; + move16(); + + IF ( *concealWholeFrame == 0) + { + + Word16 m_frame_type = st->m_frame_type; + Word16 bwidth = st->bwidth; + Word16 cng_type = st->cng_type; + Word16 L_frame = st->L_frame; + Word32 total_brate = st->last_total_brate; + + decode_frame_type( st +#ifdef IVAS_CODE_CNG + , hStereoCng +#endif + ); + + st->force_lpd_reset = 0; + + test(); + test(); + test(); + test(); + IF( (EQ_16(st->last_codec_mode, MODE2))&&(st->BER_detect||(st->prev_bfi&&(EQ_16(st->m_frame_type,ZERO_FRAME))&&(EQ_16(st->m_old_frame_type,ACTIVE_FRAME))))) + { + /* Copy back parameters from previous frame, because there is a high risk they are corrupt + * DO concealment with configuration used in previous frame */ + st->m_frame_type = m_frame_type; + move16(); + st->bwidth = bwidth; + move16(); + st->cng_type = cng_type; + move16(); + st->L_frame = L_frame; + move16(); + if( st->ini_frame != 0 ) + { + st->total_brate = total_brate; + move32(); + } + + *concealWholeFrame = 1; + move16(); + st->m_decodeMode = DEC_CONCEALMENT_EXT; + move16(); + st->BER_detect = 0; + move16(); + + test(); + test(); + IF( (NE_16(st->bwidth, st->last_bwidth))||(NE_16(st->rf_flag,st->rf_flag_last))||(NE_32(st->total_brate,st->last_total_brate))) + { + st->force_lpd_reset = 1; + move16(); + } + + st->core_brate = st->last_core_brate; + move32(); + st->bfi = 1; + move16(); + IF(st->ini_frame == 0 && st->hTcxCfg != NULL ) + { + st->hTcxCfg->tcx_coded_lines = getNumTcxCodedLines(SWB); + } + } + ELSE + { + st->core_brate = st->total_brate; + move32(); + bpf_noise_buf = st->p_bpf_noise_buf; + move16(); + } + } + + IF( *concealWholeFrame != 0 ) + { + /* add two zero bytes for arithmetic coder flush */ + FOR( i=0; i<8*2; i++ ) + { + st->bit_stream[i] = 0; + } + } + + + IF ( s_and((Word16)NE_16(st->m_frame_type,SID_FRAME),(Word16)NE_16(st->m_frame_type,ZERO_FRAME))) /* test */ + { + + /* -------------------------------------------------------------- */ + /* DECODE CORE */ + /* -------------------------------------------------------------- */ + + tmp = sub(num_bits, sub(st->next_bit_pos, start_bit_pos)); + bitsRead = 0; + move16(); + + set16_fx( old_bwe_exc + PIT16k_MAX * 2, 0, ((L_FRAME16k + 1) + L_SUBFR16k) * 2 ); + ptr_bwe_exc = old_bwe_exc + PIT16k_MAX * 2; + Copy(hBWE_TD->old_bwe_exc_fx, old_bwe_exc, PIT16k_MAX * 2 ); + + IF ( EQ_16(st->m_decodeMode, DEC_NO_FRAM_LOSS)) + { + decoder_LPD(pcmBuf, pcmbufFB, &tmp, st, bpf_noise_buf, 0, &bitsRead, param, pitch_buf, voice_factors, ptr_bwe_exc ); + + test(); + test(); + test(); + test(); + test(); + IF( st->rate_switching_init == 0 && EQ_16((st->last_codec_mode), MODE2)&&!(st->use_partial_copy&&GE_16(st->rf_frame_type,RF_TCXFD)&&LE_16(st->rf_frame_type,RF_TCXTD2))&&EQ_16(st->bfi,1)) + { + *concealWholeFrame = 1; + move16(); + st->m_decodeMode = DEC_CONCEALMENT_EXT; + move16(); + st->BER_detect = 0; + move16(); + } + + } + ELSE IF (EQ_16(st->m_decodeMode, DEC_CONCEALMENT_EXT)) + { + /* Decode the LPD data */ + decoder_LPD( pcmBuf, pcmbufFB, NULL, st, bpf_noise_buf, 1, &bitsRead, NULL, pitch_buf, voice_factors, ptr_bwe_exc ); + } + + test(); + test(); + test(); + test(); + if (st->hBWE_TD != NULL) + { + IF((st->bfi == 0 && (EQ_16(st->prev_bfi, 1) || EQ_16(st->prev_use_partial_copy, 1))) || ((EQ_16(st->last_vbr_hw_BWE_disable_dec_fx, 1)) && (st->vbr_hw_BWE_disable_dec_fx == 0))) + { + hBWE_TD->bwe_non_lin_prev_scale_fx = 0; + set16_fx(hBWE_TD->old_bwe_exc_extended_fx, 0, NL_BUFF_OFFSET); + } + + test(); + test(); + IF(st->core == ACELP_CORE && st->igf != 0 && st->con_tcx == 0) + { + non_linearity_fx(ptr_bwe_exc, bwe_exc_extended, L_FRAME32k, &hBWE_TD->bwe_non_lin_prev_scale_fx, st->Q_exc, st->coder_type_fx, voice_factors, st->L_frame); + /* update the old BWE exe memory */ + Copy(&old_bwe_exc[L_FRAME32k], hBWE_TD->old_bwe_exc_fx, PIT16k_MAX * 2); + } + ELSE + { + set16_fx(hBWE_TD->old_bwe_exc_extended_fx, 0, NL_BUFF_OFFSET); + set16_fx(hBWE_TD->old_bwe_exc_fx, 0, PIT16k_MAX * 2); + hBWE_TD->bwe_non_lin_prev_scale_fx = 0; + move32(); + } + } + + /* for ACELP mode, skip core data to read TD-BWE side info */ + test(); + test(); + IF( (!st->bfi) && EQ_16(st->core,ACELP_CORE)&&st->total_brate>0) + { + /* target bs-position "-3": -2 as earlier "start_bit_pos -= 2;" are included in st->rf_target_bits + -1 as flag-bit not considered in rf_target_bits */ + IF (EQ_16(st->rf_flag, 1)) + { + get_next_indice_tmp_fx(st, start_bit_pos + num_bits - st->rf_target_bits - 3 - get_tbe_bits_fx(st->total_brate, st->bwidth, st->rf_flag) - st->next_bit_pos); + } + ELSE + { + get_next_indice_tmp_fx(st, start_bit_pos + num_bits - st->rf_target_bits - get_tbe_bits_fx(st->total_brate, st->bwidth, st->rf_flag) - st->next_bit_pos); + } + tbe_read_bitstream_fx(st); + } + + /* updates */ + st->last_voice_factor_fx = voice_factors[st->nb_subfr-1];; + move16(); + st->last_coder_type_fx = st->coder_type_fx; + } + ELSE + { + + IF ( EQ_16(st->m_frame_type,SID_FRAME)) + { + FdCng_decodeSID(st->hFdCngDec_fx->hFdCngCom, st); + } + + /* updates */ + st->last_voice_factor_fx = 0; + move16(); + st->last_coder_type_fx = INACTIVE; + move16(); + } + + return 0; +} diff --git a/lib_dec/dec_amr_wb.c b/lib_dec/dec_amr_wb.c index 88605c5ba9d274eab54217eb2faedb3ac28554f9..4195214720e86c737f0a5c88ee164e67b715036c 100644 --- a/lib_dec/dec_amr_wb.c +++ b/lib_dec/dec_amr_wb.c @@ -99,13 +99,13 @@ void decod_amr_wb( * Decode pitch lag *----------------------------------------------------------------------*/ - *pt_pitch = pit_decode( st, st->core_brate, 1, L_FRAME, i_subfr, -1, &pitch_limit_flag, &T0, &T0_frac, &T0_min, &T0_max, L_SUBFR, 0, NULL ); + *pt_pitch = pit_decode_flt( st, st->core_brate, 1, L_FRAME, i_subfr, -1, &pitch_limit_flag, &T0, &T0_frac, &T0_min, &T0_max, L_SUBFR, 0, NULL ); /*--------------------------------------------------------------* * Find the adaptive codebook vector *--------------------------------------------------------------*/ - pred_lt4( &exc[i_subfr], &exc[i_subfr], T0, T0_frac, L_SUBFR + 1, inter4_2, L_INTERPOL2, PIT_UP_SAMP ); + pred_lt4_flt( &exc[i_subfr], &exc[i_subfr], T0, T0_frac, L_SUBFR + 1, inter4_2, L_INTERPOL2, PIT_UP_SAMP ); /*--------------------------------------------------------------* * LP filtering of the adaptive excitation diff --git a/lib_dec/dec_amr_wb_fx.c b/lib_dec/dec_amr_wb_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..1d609cd6ad3f0d505376adc780713465a367b56d --- /dev/null +++ b/lib_dec/dec_amr_wb_fx.c @@ -0,0 +1,155 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include +#include "options.h" /* Compilation switches */ +#include "cnst.h" /* Common constants */ +#include "rom_com.h" /* Static table prototypes */ +#include "prot_fx1.h" /* Function prototypes */ +#include "prot_fx2.h" /* Function prototypes */ + + +/*---------------------------------------------------------------------* + * decod_amr_wb() + * + * Decode excitation signal in AMR-WB IO mode + *---------------------------------------------------------------------*/ + +void decod_amr_wb_fx( + Decoder_State *st_fx, /* i/o: decoder static memory */ + const Word16 *Aq_fx, /* i : LP filter coefficients */ + Word16 *pitch_buf_fx, /* o : floating pitch values for each subframe */ + Word16 *exc_fx, /* i/o: adapt. excitation exc */ + Word16 *exc2_fx, /* i/o: adapt. excitation/total exc */ + Word16 hf_gain_fx[NB_SUBFR], /* o : decoded HF gain */ + Word16 *voice_factors_fx, /* o : voicing factors */ + Word16 *gain_buf /* o : floating pitch gain for each subframe Q14 */ +) +{ + Word16 T0, T0_frac, T0_min, T0_max; /* integer pitch variables */ + Word16 gain_pit_fx, gain_code16; /* pitch gain */ + Word32 L_gain_code_fx; /* gain/normalized gain of the algebraic excitation */ + Word32 L_norm_gain_code_fx; /* normalized gain of the algebraic excitation */ + Word16 gain_inov_fx; /* Innovation gain */ + Word16 voice_fac_fx; /* voicing factor */ + Word16 code_fx[L_SUBFR]; /* algebraic codevector */ + const Word16 *p_Aq_fx; /* Pointer to frame LP coefficient */ + Word16 *pt_pitch_fx; /* pointer to floating pitch */ + Word16 i_subfr; /* tmp variables */ + Word16 pitch_limit_flag; + Word32 L_Voice_fac_ave, L_tmp; + Word16 lp_flag; + AMRWB_IO_DEC_HANDLE hAmrwb_IO; + hAmrwb_IO = st_fx->hAmrwb_IO; + MUSIC_POSTFILT_HANDLE hMusicPF; + hMusicPF = st_fx->hMusicPF; + + /*------------------------------------------------------------------* + * Initializations + *------------------------------------------------------------------*/ + + p_Aq_fx = Aq_fx; /* pointer to interpolated LPC parameters */ + pt_pitch_fx = pitch_buf_fx; /* pointer to the pitch buffer */ + L_Voice_fac_ave = L_deposit_l(0); + pitch_limit_flag = 0; + move16(); /* always restrained pitch Q range in IO mode */ + + lp_flag = NORMAL_OPERATION; + move16(); /* always restrained pitch Q range in IO mode */ + IF (LT_32(st_fx->core_brate, ACELP_11k60) ) + { + lp_flag = LOW_PASS; + move16(); /* always restrained pitch Q range in IO mode */ + } + /*------------------------------------------------------------------* + * ACELP subframe loop + *------------------------------------------------------------------*/ + + FOR( i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR ) + { + /*----------------------------------------------------------------------* + * Decode pitch lag + *----------------------------------------------------------------------*/ + + *pt_pitch_fx = pit_decode_fx( st_fx, st_fx->core_brate, 1, L_FRAME, i_subfr, -1, &pitch_limit_flag, &T0, &T0_frac, &T0_min, &T0_max, L_SUBFR +#ifdef ADD_LRTD + , 0 , NULL +#endif + ); + + /*--------------------------------------------------------------* + * Find the adaptive codebook vector + *--------------------------------------------------------------*/ + + pred_lt4(&exc_fx[i_subfr],&exc_fx[i_subfr], T0, T0_frac, L_SUBFR+1, pitch_inter4_2, L_INTERPOL2, PIT_UP_SAMP); + + /*--------------------------------------------------------------* + * LP filtering of the adaptive excitation + *--------------------------------------------------------------*/ + + lp_filt_exc_dec_fx(st_fx, MODE1, i_subfr, L_SUBFR, L_FRAME, lp_flag, exc_fx); + /*--------------------------------------------------------------* + * Innovation decoding + *--------------------------------------------------------------*/ + + inov_decode_fx( st_fx, st_fx->core_brate, 1, L_FRAME, 0, i_subfr, p_Aq_fx, st_fx->tilt_code_fx, *pt_pitch_fx, code_fx, L_SUBFR); + + /*--------------------------------------------------------------* + * Gain decoding + * Estimate spectrum tilt and voicing + *--------------------------------------------------------------*/ + + gain_dec_amr_wb_fx( st_fx, st_fx->core_brate, &gain_pit_fx, &L_gain_code_fx, hAmrwb_IO->past_qua_en_fx, &gain_inov_fx, code_fx, &L_norm_gain_code_fx ); + + /* update LP filtered gains for the case of frame erasures */ + lp_gain_updt_fx( i_subfr, gain_pit_fx, L_norm_gain_code_fx, &st_fx->lp_gainp_fx, &st_fx->lp_gainc_fx, L_FRAME ); + + st_fx->tilt_code_fx = est_tilt_fx( exc_fx+i_subfr, gain_pit_fx, code_fx, L_gain_code_fx, &voice_fac_fx, st_fx->Q_exc ); + + Rescale_exc(hMusicPF->dct_post_old_exc_fx, &exc_fx[i_subfr], NULL, st_fx->hGSCDec->last_exc_dct_in_fx, L_SUBFR, 0, + L_gain_code_fx, &(st_fx->Q_exc), st_fx->Q_subfr, exc2_fx, i_subfr, -1 ); + + gain_code16 = round_fx(L_shl(L_gain_code_fx,st_fx->Q_exc)); /*Q_exc*/ + + /*----------------------------------------------------------------------* + * Find the total excitation + *----------------------------------------------------------------------*/ + + Acelp_dec_total_exc( exc_fx, exc2_fx, gain_code16, gain_pit_fx, i_subfr, code_fx, L_SUBFR); + + /*----------------------------------------------------------------* + * Excitation enhancements + *----------------------------------------------------------------*/ + + enhancer_fx( st_fx->core_brate, 1, -1, i_subfr, L_FRAME, voice_fac_fx, st_fx->stab_fac_fx, + L_norm_gain_code_fx, gain_inov_fx, &st_fx->gc_threshold_fx, code_fx, exc2_fx, gain_pit_fx, &(st_fx->dm_fx),st_fx->Q_exc ); + + /*-----------------------------------------------------------------* + * HF gain modification factors at 23.85 kbps + *-----------------------------------------------------------------*/ + + IF ( EQ_32(st_fx->core_brate,ACELP_23k85)) + { + hf_gain_fx[shr(i_subfr,6)] = (Word16)get_next_indice(st_fx, 4); + } + + /*voice_fac = VF_0th_PARAM + VF_1st_PARAM * voice_fac + VF_2nd_PARAM * voice_fac * voice_fac;*/ + L_tmp = L_mult(VF_2nd_PARAM_FX, mult_r(voice_fac_fx, voice_fac_fx)); + L_tmp = L_mac(L_tmp, VF_1st_PARAM_FX, voice_fac_fx); + voice_fac_fx = mac_r(L_tmp, VF_0th_PARAM_FX, 32767); + + /*voice_factors[i_subfr/L_SUBFR] = min( max(0.0f, voice_fac), 1.0f);*/ + voice_factors_fx[i_subfr/L_SUBFR] = s_min(s_max(0, voice_fac_fx),32767); + move16(); + p_Aq_fx += (M+1); + pt_pitch_fx++; + + L_Voice_fac_ave = L_mac(L_Voice_fac_ave, 8192, voice_fac_fx); + gain_buf[i_subfr/L_SUBFR] = gain_pit_fx; + } + + hAmrwb_IO->lt_voice_fac_fx = round_fx(L_Voice_fac_ave); + + return; +} diff --git a/lib_dec/dec_gen_voic.c b/lib_dec/dec_gen_voic.c index 0e8285c82e4b95f2901186b211d2e5df799223ef..2317a8f8a81c821ce80ec75c8349b6e75491349f 100644 --- a/lib_dec/dec_gen_voic.c +++ b/lib_dec/dec_gen_voic.c @@ -115,13 +115,13 @@ ivas_error decod_gen_voic( * Decode pitch lag *----------------------------------------------------------------------*/ - *pt_pitch = pit_decode( st, st->core_brate, 0, L_frame, i_subfr, st->coder_type, &pitch_limit_flag, &T0, &T0_frac, &T0_min, &T0_max, L_SUBFR, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf ); + *pt_pitch = pit_decode_flt( st, st->core_brate, 0, L_frame, i_subfr, st->coder_type, &pitch_limit_flag, &T0, &T0_frac, &T0_min, &T0_max, L_SUBFR, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf ); /*--------------------------------------------------------------* * Find the adaptive codebook vector *--------------------------------------------------------------*/ - pred_lt4( &exc[i_subfr], &exc[i_subfr], T0, T0_frac, L_SUBFR + 1, inter4_2, L_INTERPOL2, PIT_UP_SAMP ); + pred_lt4_flt( &exc[i_subfr], &exc[i_subfr], T0, T0_frac, L_SUBFR + 1, inter4_2, L_INTERPOL2, PIT_UP_SAMP ); tbe_celp_exc_flt( st->element_mode, st->idchan, bwe_exc, L_frame, L_SUBFR, i_subfr, T0, T0_frac, &error_flag, st->tdm_LRTD_flag ); diff --git a/lib_dec/dec_gen_voic_fx.c b/lib_dec/dec_gen_voic_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..a8689594156b8c37457bc40bd2e18e23c4b31c25 --- /dev/null +++ b/lib_dec/dec_gen_voic_fx.c @@ -0,0 +1,465 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include +#include "options.h" /* Compilation switches */ +#include "cnst.h" /* Common constants */ +#include "rom_com.h" /* Static table prototypes */ +#include "prot_fx1.h" /* Function prototypes */ +#include "prot_fx2.h" /* Function prototypes */ +#include "stl.h" +#include "basop_util.h" + + +/*======================================================================*/ +/* FUNCTION : decod_gen_voic_fx() */ +/*----------------------------------------------------------------------*/ +/* PURPOSE : Decode generic (GC), voiced (VC) and AMR-WB IO frames */ +/* */ +/*----------------------------------------------------------------------*/ +/* GLOBAL INPUT ARGUMENTS : */ +/* _ (Struct) st_fx : decoder static memory */ +/* _ (Word16) L_frame : length of the frame */ + +/* _ (Word16[]) Aq_fx : LP filter coefficient Q12 */ +/* _ (Word16) Es_pred_fx : predicted scaled innov. energy Q8 */ +/* _ (Word16[]) pitch_buf_fx : floating pitch values for each subframe Q6*/ +/* _ (Word16[]) voice_factors_fx: frame error rate Q15 */ +/*----------------------------------------------------------------------*/ +/* OUTPUT ARGUMENTS : */ +/* _ (Word16[]) exc_fx : adapt. excitation exc (Q_exc) */ +/* _ (Word16[]) exc2_fx : adapt. excitation/total exc (Q_exc) */ +/*----------------------------------------------------------------------*/ + + +/*----------------------------------------------------------------------*/ +/* RETURN ARGUMENTS : */ +/* _ None */ +/*======================================================================*/ + +ivas_error decod_gen_voic_fx( + Decoder_State *st_fx, /* i/o: decoder static memory */ + const Word16 L_frame, /* i : length of the frame */ + const Word16 sharpFlag_fx, /* i : formant sharpening flag */ + const Word16 *Aq_fx, /* i : LP filter coefficient */ + const Word16 Es_pred_fx, /* i : predicted scaled innov. energy */ + const Word16 do_WI_fx, /* i : do interpolation after a FER */ + Word16 *pitch_buf_fx, /* o : floating pitch values for each subframe */ + Word16 *voice_factors_fx, /* o : voicing factors */ + Word16 *exc_fx, /* i/o: adapt. excitation exc */ + Word16 *exc2_fx, /* i/o: adapt. excitation/total exc */ + Word16 *bwe_exc_fx, /* o : excitation for SWB TBE */ + Word16 *unbits, /* number of unused bits */ + Word16 *gain_buf +) +{ + + + Word16 T0_fx, T0_frac_fx, T0_min_fx, T0_max_fx;/* integer pitch variables */ + Word16 gain_pit_fx = 0; /* pitch gain Q14 */ + Word32 gain_code_fx=0; /* gain/normalized gain of the algebraic excitation Q16 */ + Word32 norm_gain_code_fx=0; /* normalized gain of the algebraic excitation Q16 */ + Word16 gain_inov_fx=0; /* Innovation gain Q12 */ + Word32 gc_mem[NB_SUBFR-1]; /* gain_code from previous subframes */ + Word16 gp_mem[NB_SUBFR-1]; /* gain_pitch from previous subframes */ + Word16 voice_fac_fx; /* voicing factor Q15 */ + Word16 code_fx[L_SUBFR]; /* algebraic codevector Q12 */ + + const Word16 *p_Aq_fx; /* Pointer to frame LP coefficient Q12 */ + Word16 *pt_pitch_fx; /* pointer to floating pitch Q6 */ + Word16 i_subfr_fx, i; /* tmp variables */ + Word16 error_fx = 0; + Word16 gain_preQ_fx = 0; /* Gain of prequantizer excitation */ + Word16 code_preQ_fx[L_SUBFR]; /* Prequantizer excitation */ + Word32 norm_gain_preQ_fx; + Word16 pitch_limit_flag_fx; + + Word16 tmp1_fx,gain_code16; + Word32 L_tmp_GC; + Word32 L_tmp; + + Word16 harm_flag_acelp; + + Word16 shft_prev, ph_offset_fx; + Word32 prev_res_nrg; + Word32 prev_spch_nrg; + Word32 curr_res_nrg; + Word32 curr_spch_nrg; + Word16 rint_bfi_pitch, rint_pitch; + Word16 fraca, fracb, expa, expb, scale, exp1; + Word16 *p_exc; + Word16 mem_tmp_fx[M]; + Word16 syn_tmp_fx[L_FRAME16k]; + Word16 shft_curr; + Word16 *p_syn; + Word16 sp_enratio, Qsp_enratio; + Word16 enratio, Qenratio; + DTFS_STRUCTURE *PREVP, *CURRP; + Word16 S_fx[PIT_MAX*4+1], C_fx[PIT_MAX*4+1]; + Word16 dummy2[2]; + Word16 out_fx[L_FRAME16k]; + + Word16 pf_temp1[MAXLAG_WI]; /*may not need more than MAXLAG_WI/2+1 */ + Word16 pf_temp2[MAXLAG_WI]; + Word16 pf_temp[MAXLAG_WI]; + Word16 pf_n2[MAXLAG_WI]; + MUSIC_POSTFILT_HANDLE hMusicPF; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + hMusicPF = st_fx->hMusicPF; + + GSC_DEC_HANDLE hGSCDec; + hGSCDec = st_fx->hGSCDec; + ivas_error error; + + error = IVAS_ERR_OK; + + T0_fx = PIT_MIN; + move16(); + T0_frac_fx = 0; + move16(); + + /* read harmonicity flag */ + harm_flag_acelp = 0; + move16(); + test(); + test(); + IF( (GE_32(st_fx->core_brate, MIN_BRATE_AVQ_EXC)&&LE_32(st_fx->core_brate, MAX_BRATE_AVQ_EXC_TD))&&EQ_16(st_fx->coder_type_fx,GENERIC)) + { + harm_flag_acelp = (Word16)get_next_indice( st_fx, 1 ); + } + + /*------------------------------------------------------------------* + * ACELP subframe loop + *------------------------------------------------------------------*/ + + p_Aq_fx = Aq_fx; + move16(); /* pointer to interpolated LPC parameters */ + pt_pitch_fx = pitch_buf_fx; + move16(); /* pointer to the pitch buffer */ + norm_gain_preQ_fx = 0; + move16(); + gain_preQ_fx = 0; + move16(); + set16_fx( code_preQ_fx, 0, L_SUBFR ); + + FOR( i_subfr_fx = 0; i_subfr_fx < L_frame; i_subfr_fx += L_SUBFR ) + { + /*----------------------------------------------------------------------* + * Decode pitch lag + *----------------------------------------------------------------------*/ + + *pt_pitch_fx = pit_decode_fx( st_fx, st_fx->core_brate, 0, L_frame, i_subfr_fx, st_fx->coder_type_fx, &pitch_limit_flag_fx, + &T0_fx, &T0_frac_fx, &T0_min_fx, &T0_max_fx, L_SUBFR ); + move16(); /*Q6*/ + + /*--------------------------------------------------------------* + * Find the adaptive codebook vector + *--------------------------------------------------------------*/ + + pred_lt4( &exc_fx[i_subfr_fx], &exc_fx[i_subfr_fx], T0_fx, T0_frac_fx, L_SUBFR+1, pitch_inter4_2, L_INTERPOL2, PIT_UP_SAMP ); + + tbe_celp_exc( L_frame,i_subfr_fx,T0_fx, T0_frac_fx, &error_fx, bwe_exc_fx ); + + /*--------------------------------------------------------------* + * LP filtering of the adaptive excitation + *--------------------------------------------------------------*/ + lp_filt_exc_dec_fx(st_fx, MODE1, i_subfr_fx, L_SUBFR, L_frame, st_fx->acelp_cfg.ltf_mode, exc_fx); + /*-----------------------------------------------------------------* + * Transform-domain contribution decoding (active frames) + *-----------------------------------------------------------------*/ + + test(); + IF( GE_32(st_fx->core_brate, MIN_BRATE_AVQ_EXC)&&NE_16(st_fx->coder_type_fx,INACTIVE)) + { + gain_code_fx = 0; + move16(); + transf_cdbk_dec_fx( st_fx, harm_flag_acelp, i_subfr_fx, Es_pred_fx, gain_code_fx, &gain_preQ_fx, &norm_gain_preQ_fx, code_preQ_fx, unbits ); + } + + /*--------------------------------------------------------------* + * Innovation decoding + *--------------------------------------------------------------*/ + + inov_decode_fx( st_fx, st_fx->core_brate, 0, L_frame, sharpFlag_fx, i_subfr_fx, p_Aq_fx, st_fx->tilt_code_fx, *pt_pitch_fx, code_fx, L_SUBFR); + + /*--------------------------------------------------------------* + * Gain decoding + * Estimate spectrum tilt and voicing + *--------------------------------------------------------------*/ + + IF( LE_32(st_fx->core_brate,ACELP_8k00)) + { + gain_dec_lbr_fx( st_fx, st_fx->coder_type_fx, i_subfr_fx, code_fx, &gain_pit_fx, &gain_code_fx, &gain_inov_fx, &norm_gain_code_fx, gc_mem, gp_mem, L_SUBFR); + } + ELSE IF( GT_32(st_fx->core_brate,ACELP_32k)) + { + gain_dec_SQ_fx( st_fx, i_subfr_fx, code_fx, Es_pred_fx, &gain_pit_fx, &gain_code_fx, &gain_inov_fx, &norm_gain_code_fx ); + } + ELSE + { + gain_dec_mless_fx( st_fx, L_frame, st_fx->coder_type_fx, i_subfr_fx, -1, code_fx, Es_pred_fx, &gain_pit_fx, &gain_code_fx, &gain_inov_fx, &norm_gain_code_fx ); + } + st_fx->tilt_code_fx = est_tilt_fx( exc_fx+i_subfr_fx, gain_pit_fx, code_fx, gain_code_fx, &voice_fac_fx, st_fx->Q_exc ); + + /*-----------------------------------------------------------------* + * Transform domain contribution decoding + *-----------------------------------------------------------------*/ + test(); + IF( GE_32( st_fx->core_brate, MAX_GSC_INACTIVE_BRATE) && EQ_16(st_fx->coder_type_fx,INACTIVE)) + { + transf_cdbk_dec_fx( st_fx, harm_flag_acelp, i_subfr_fx, Es_pred_fx, gain_code_fx, &gain_preQ_fx, &norm_gain_preQ_fx, code_preQ_fx, unbits ); + } + + /* update LP filtered gains for the case of frame erasures */ + lp_gain_updt_fx( i_subfr_fx, gain_pit_fx, L_add(norm_gain_code_fx,norm_gain_preQ_fx), &st_fx->lp_gainp_fx, &st_fx->lp_gainc_fx, L_frame ); + + /*----------------------------------------------------------------------* + * Find the total excitation + *----------------------------------------------------------------------*/ + + IF ( EQ_16(L_frame,L_FRAME)) /* Rescaling for 12.8k core */ + { + Rescale_exc(hMusicPF->dct_post_old_exc_fx, &exc_fx[i_subfr_fx], &bwe_exc_fx[i_subfr_fx * HIBND_ACB_L_FAC], hGSCDec->last_exc_dct_in_fx, + L_SUBFR, L_SUBFR * HIBND_ACB_L_FAC, gain_code_fx, &(st_fx->Q_exc), st_fx->Q_subfr, exc2_fx, i_subfr_fx, st_fx->coder_type_fx ); + + } + ELSE /* Rescaling for 16k core */ + { + + L_tmp_GC = L_max(gain_code_fx, L_shl(gain_preQ_fx,16)); /* Chose the maximum of gain_code or the prequantizer excitation x4 to keep some room*/ + Rescale_exc(hMusicPF->dct_post_old_exc_fx, &exc_fx[i_subfr_fx], &bwe_exc_fx[i_subfr_fx * 2], hGSCDec->last_exc_dct_in_fx, + L_SUBFR, L_SUBFR * 2, L_tmp_GC, &(st_fx->Q_exc), st_fx->Q_subfr, exc2_fx, i_subfr_fx, st_fx->coder_type_fx ); + } + + gain_code16 = round_fx(L_shl(gain_code_fx,st_fx->Q_exc)); /*Q_exc*/ + + /*-----------------------------------------------------------------* + * Add the ACELP pre-quantizer contribution + *-----------------------------------------------------------------*/ + + IF (gain_preQ_fx != 0) + { + tmp1_fx = add(15-Q_AVQ_OUT_DEC-2,st_fx->Q_exc); + FOR( i = 0; i < L_SUBFR; i++ ) + { + Word32 Ltmp1; + /* Contribution from AVQ layer */ + Ltmp1 = L_mult(gain_preQ_fx, code_preQ_fx[i]); /* Q2 + Q6 -> Q9*/ + Ltmp1 = L_shl(Ltmp1,tmp1_fx); /* Q16 + Q_exc */ + + /* Compute exc2 */ + L_tmp = L_shl(L_mult(gain_pit_fx,exc_fx[i+i_subfr_fx]),1); + exc2_fx[i+i_subfr_fx] = round_fx(L_add(L_tmp, Ltmp1)); + + /* code in Q9, gain_pit in Q14 */ + L_tmp = L_mult(gain_code16, code_fx[i]); + L_tmp = L_shl(L_tmp, 5); + L_tmp = L_mac(L_tmp, exc_fx[i + i_subfr_fx], gain_pit_fx); + L_tmp = L_shl(L_tmp, 1); /* saturation can occur here */ + + exc_fx[i+i_subfr_fx] = round_fx(L_add(L_tmp, Ltmp1)); + } + } + ELSE + { + Acelp_dec_total_exc( exc_fx, exc2_fx, gain_code16, gain_pit_fx, i_subfr_fx, code_fx, L_SUBFR); + } + + /*-----------------------------------------------------------------* + * Prepare TBE excitation + *-----------------------------------------------------------------*/ + + prep_tbe_exc_fx( L_frame, i_subfr_fx, gain_pit_fx, gain_code_fx, code_fx, voice_fac_fx, + &voice_factors_fx[i_subfr_fx/L_SUBFR], bwe_exc_fx, gain_preQ_fx, code_preQ_fx, + st_fx->Q_exc, T0_fx, T0_frac_fx, st_fx->coder_type_fx, st_fx->core_brate ); + + + /*----------------------------------------------------------------* + * Excitation enhancements (update of total excitation signal) + *----------------------------------------------------------------*/ + + test(); + IF( GT_32(st_fx->core_brate,ACELP_32k)||EQ_16(st_fx->coder_type_fx,INACTIVE)) + { + Copy( exc_fx+i_subfr_fx, exc2_fx+i_subfr_fx, L_SUBFR ); + } + ELSE + { + enhancer_fx( st_fx->core_brate, 0, st_fx->coder_type_fx, i_subfr_fx, L_frame, voice_fac_fx, st_fx->stab_fac_fx, + norm_gain_code_fx, gain_inov_fx, &st_fx->gc_threshold_fx, code_fx, exc2_fx, gain_pit_fx, &(st_fx->dm_fx), st_fx->Q_exc ); + } + + p_Aq_fx += (M+1); + move16(); + pt_pitch_fx++; + gain_buf[i_subfr_fx/L_SUBFR] = gain_pit_fx; + move16(); + } + + /* FEC fast recovery */ + + IF( do_WI_fx ) + { + /* shft_prev = L_EXC_MEM - rint_new_fx(st_fx->bfi_pitch_fx);*/ + L_tmp = L_shl(L_deposit_l(st_fx->bfi_pitch_fx),10); /*Q16*/ + rint_bfi_pitch = rint_new_fx(L_tmp); /*Q0*/ + shft_prev = sub( L_EXC_MEM, rint_bfi_pitch ); /*Q0*/ + + p_exc = st_fx->hWIDec->old_exc2_fx + shft_prev; + p_syn = st_fx->hWIDec->old_syn2_fx + shft_prev; + move16(); + move16(); + + prev_res_nrg = L_deposit_l(1); + prev_spch_nrg = L_deposit_l(1); + FOR( i=0; iprev_Q_exc_fr */ + prev_spch_nrg = L_mac0(prev_spch_nrg, *p_syn, *p_syn); /* 2*st_fx->prev_Q_syn_fr */ + p_exc++; + p_syn++; + } + + Copy( st_fx->mem_syn2_fx, mem_tmp_fx, M ); + + syn_12k8_fx( st_fx->L_frame, Aq_fx, exc2_fx, syn_tmp_fx, mem_tmp_fx, 1, st_fx->Q_exc, st_fx->Q_syn ); + + L_tmp = L_shl(L_deposit_l(pitch_buf_fx[NB_SUBFR16k-1]),10); /*Q16*/ + rint_pitch = rint_new_fx(L_tmp); /*Q0*/ + shft_curr = sub( st_fx->L_frame, rint_pitch ); /*Q0*/ + + p_exc = exc2_fx + shft_curr; + move16(); + p_syn = syn_tmp_fx + shft_curr; + move16(); + + curr_res_nrg = L_deposit_l(1); + curr_spch_nrg = L_deposit_l(1); + FOR( i=0; iQ_exc */ + curr_spch_nrg = L_mac0(curr_spch_nrg, *p_syn, *p_syn); /* 2*st_fx->Q_syn */ + p_exc++; + p_syn++; + } + + /* enratio = (curr_res_nrg / prev_res_nrg); */ + IF(prev_res_nrg>0) + { + expa = norm_l(prev_res_nrg); + fraca = extract_h(L_shl(prev_res_nrg,expa)); + expa = sub(30,expa+(2*st_fx->prev_Q_exc_fr)); + + expb = norm_l(curr_res_nrg); + fracb = round_fx(L_shl(curr_res_nrg,expb)); + expb = sub(30,expb+(2*st_fx->Q_exc)); + + scale = shr(sub(fraca,fracb),15); + fracb = shl(fracb,scale); + expb = sub(expb,scale); + + enratio = div_s(fracb,fraca); + exp1 = sub(expb,expa); + Qenratio = 15-exp1; + } + ELSE + { + enratio = 0; + Qenratio = 0; + } + + /* sp_enratio = curr_spch_nrg/prev_spch_nrg */ + IF(prev_spch_nrg>0) + { + expa = norm_l(prev_spch_nrg); + fraca = extract_h(L_shl(prev_spch_nrg,expa)); + expa = sub(30,expa+(2*st_fx->prev_Q_syn_fr)); + + expb = norm_l(curr_spch_nrg); + fracb = round_fx(L_shl(curr_spch_nrg,expb)); + expb = sub(30,expb+(2*st_fx->Q_syn)); + + scale = shr(sub(fraca,fracb),15); + fracb = shl(fracb,scale); + expb = sub(expb,scale); + + sp_enratio = div_s(fracb,fraca); + exp1 = sub(expb,expa); + Qsp_enratio = 15-exp1; + } + ELSE + { + sp_enratio = 0; + Qsp_enratio = 0; + } + + test(); + test(); + test(); + test(); +#ifdef BASOP_NOGLOB + IF ( GT_16(shl_ro(enratio,15-Qenratio, &Overflow), 8192)&& /*compare with 0.25 in Q15*/ + LT_16(shl_ro(enratio,10-Qenratio, &Overflow), 15360) && /*compare with 15.0 in Q10*/ + GT_16(shl_ro(sp_enratio,15-Qsp_enratio, &Overflow), 4915) &&/*compare with 0.15 in Q15*/ + st_fx->bfi_pitch_fx < 9600 && /*Q6*/ + pitch_buf_fx[ sub( NB_SUBFR16k, 1 ) ] < 9600 ) /*Q6*/ +#else + IF ( GT_16(shl_r(enratio,15-Qenratio), 8192)&& /*compare with 0.25 in Q15*/ + LT_16(shl_r(enratio,10-Qenratio), 15360) && /*compare with 15.0 in Q10*/ + GT_16(shl_r(sp_enratio,15-Qsp_enratio), 4915) &&/*compare with 0.15 in Q15*/ + st_fx->bfi_pitch_fx < 9600 && /*Q6*/ + pitch_buf_fx[ sub( NB_SUBFR16k, 1 ) ] < 9600 ) /*Q6*/ +#endif + { + IF ((error = DTFS_new_fx(&PREVP)) != IVAS_ERR_OK) + { + return error; + } + + IF ((error = DTFS_new_fx(&CURRP)) != IVAS_ERR_OK) + { + return error; + } + + GetSinCosTab_fx(rint_bfi_pitch,S_fx,C_fx); + DTFS_to_fs_fx( st_fx->hWIDec->old_exc2_fx + shft_prev, rint_bfi_pitch, PREVP, (Word16)st_fx->output_Fs, do_WI_fx, S_fx, C_fx); + PREVP->Q = add(PREVP->Q, st_fx->prev_Q_exc_fr); + + GetSinCosTab_fx(rint_pitch,S_fx,C_fx); + DTFS_to_fs_fx( exc2_fx + shft_curr, rint_pitch, CURRP, (Word16)st_fx->output_Fs, do_WI_fx, S_fx, C_fx); + CURRP->Q = add(CURRP->Q, st_fx->Q_exc); + + ph_offset_fx = 0; + move16(); + if ((error = WIsyn_fx(*PREVP, CURRP, dummy2, &(ph_offset_fx), out_fx, (Word16)st_fx->L_frame, 1, S_fx, C_fx, pf_temp1, pf_temp2, pf_temp, pf_n2)) != IVAS_ERR_OK) + { + return error; + } + + + Copy_Scale_sig( out_fx, exc2_fx, st_fx->L_frame, st_fx->Q_exc ); + Copy_Scale_sig( out_fx, exc_fx, st_fx->L_frame, st_fx->Q_exc ); + + /* update bwe_exc for SWB-TBE */ + FOR (i_subfr_fx = 0; i_subfr_fx < L_frame; i_subfr_fx += L_SUBFR) + { + interp_code_4over2_fx( exc_fx + i_subfr_fx, bwe_exc_fx + (i_subfr_fx*2), L_SUBFR ); + } + + count_free(PREVP); + count_free(CURRP); + } + + } + + /* SC-VBR */ + st_fx->prev_gain_pit_dec_fx = gain_pit_fx; + move16(); /*Q14*/ + st_fx->prev_tilt_code_dec_fx = st_fx->tilt_code_fx; + move16(); /*Q15*/ + + return error; +} diff --git a/lib_dec/dec_higher_acelp_fx.c b/lib_dec/dec_higher_acelp_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..00e9fffbbc6bc7e8d4a4d2150a237d530af4526f --- /dev/null +++ b/lib_dec/dec_higher_acelp_fx.c @@ -0,0 +1,308 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ +#include +#include "options.h" /* Compilation switches */ +#include "cnst.h" /* Common constants */ +#include "prot_fx1.h" /* Function prototypes */ +#include "prot_fx2.h" /* Function prototypes */ +#include "rom_com.h" /* Static table prototypes */ + +/*-----------------------------------------------------------------* + * transf_cdbk_dec() + * Transform domain contribution decoding + *-----------------------------------------------------------------*/ +void transf_cdbk_dec_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + const Word16 harm_flag_acelp,/* i : harmonic flag for higher rates ACELP */ + const Word16 i_subfr, /* i : subframe index */ + const Word16 Es_pred, /* i : predicited scaled innovation energy (Q8) */ + const Word32 gain_code, /* i : innovative excitation gain (Q16) */ + Word16 *gain_preQ, /* o : prequantizer excitation gain (Q2) */ + Word32 *norm_gain_preQ, /* o : normalized prequantizer excitation gain (Q16) */ + Word16 code_preQ[], /* o : prequantizer excitation (Q8) */ + Word16 *unbits /* o : number of AVQ unused bits */ +) +{ + Word16 i, index, nBits; + Word16 nq[L_SUBFR/WIDTH_BAND]; + Word16 gain16, exp16, tmp16; + Word32 L_tmp; + Word32 dct_code32[L_SUBFR]; + Word16 qdct; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif +#ifdef IVAS_CODE + Word16 avq_bit_sFlag; + Word16 trgtSvPos; + + avq_bit_sFlag = 0; + move16(); + IF (GT_16(st_fx->element_mode, EVS_MONO)) + { + move16(); + avq_bit_sFlag = 1; + } +#endif + /*--------------------------------------------------------------* + * Set bit-allocation + *--------------------------------------------------------------*/ + + nBits = st_fx->acelp_cfg.AVQ_cdk_bits[shr(i_subfr, 6)]; + move16(); + + /* increase # of AVQ allocated bits by unused bits from the previous subframe */ + nBits = add(nBits,*unbits); + + /*--------------------------------------------------------------* + * Dequantize prequantizer excitation gain + *--------------------------------------------------------------*/ + + index = (Word16)get_next_indice(st_fx, G_AVQ_BITS ); + + IF(EQ_16(st_fx->coder_type_fx, INACTIVE)) + { + IF(GT_32(st_fx->core_brate, 56000)) + { + gain16 = usdequant_fx( index, G_AVQ_MIN_INACT_64k_Q12, G_AVQ_DELTA_INACT_64k_Q12>>1 ); + } + ELSE IF( GT_32(st_fx->core_brate,42000)) + { + gain16 = usdequant_fx( index, G_AVQ_MIN_INACT_48k_Q12, G_AVQ_DELTA_INACT_48k_Q12>>1 ); + } + ELSE + { + gain16 = usdequant_fx( index, G_AVQ_MIN_INACT_Q12, G_AVQ_DELTA_INACT_Q12>>1 ); + } + + L_tmp = Mult_32_16(gain_code,gain16); /* Q16 * Q12 - 15 -> Q13*/ + L_tmp = L_shl(L_tmp,5); /* Q13 -> Q18*/ + *gain_preQ = round_fx(L_tmp); /* Q2*/ + } + ELSE + { + IF( GT_32(st_fx->core_brate,ACELP_24k40) && LE_32(st_fx->core_brate,42000)) + { + gain16 = gain_dequant_fx( index, G_AVQ_MIN_32kbps_Q15, G_AVQ_MAX_Q0, G_AVQ_BITS, &exp16 ); + } + ELSE + { + gain16 = gain_dequant_fx( index, G_AVQ_MIN_Q15, G_AVQ_MAX_Q0, G_AVQ_BITS, &exp16 ); + } + + IF( Es_pred < 0 ) + { + tmp16 = shr(negate(Es_pred),2); + L_tmp = L_mult(gain16,tmp16); /* Q0*Q8 -> Q9*/ + } + ELSE + { + L_tmp = L_mult(gain16,Es_pred); /* Q0*Q8 -> Q9*/ + } + L_tmp = L_shl(L_tmp,add(exp16,9)); /* Q18*/ + *gain_preQ = round_fx(L_tmp); /* Q2*/ + } +#ifdef IVAS_CODE + trgtSvPos =sub(Nsv, 1); + test(); test(); test(); test(); test(); + IF (avq_bit_sFlag && GT_16(nBits, 85) && !harm_flag_acelp && (EQ_16(st_fx->coder_type_fx, GENERIC) || EQ_16(st_fx->coder_type_fx, TRANSITION) || EQ_16(st_fx->coder_type_fx, INACTIVE) )) + { + trgtSvPos = 2; + avq_bit_sFlag = 2; + move16(); move16(); + } +#endif + /*--------------------------------------------------------------* + * Demultiplex and decode subvectors from bit-stream + *--------------------------------------------------------------*/ + +#ifdef IVAS_CODE_AVQ + AVQ_demuxdec_fx(st_fx, code_preQ, &nBits, 8, nq, avq_bit_sFlag, trgtSvPos); +#else + AVQ_demuxdec_fx(st_fx, code_preQ, &nBits, 8, nq ); +#endif + FOR( i=0; icoder_type_fx,INACTIVE) || GT_32(st_fx->core_brate, MAX_BRATE_AVQ_EXC_TD)||harm_flag_acelp) + { + qdct = 0; + move16(); + edct2_fx( L_SUBFR, 1, code_preQ, dct_code32, &qdct, ip_edct2_64, w_edct2_64_fx ); + /*qdct = sub(Q_AVQ_OUT_DEC,qdct+Q_AVQ_OUT_DEC);*/ + qdct = negate(qdct); + Copy_Scale_sig_32_16(dct_code32, code_preQ, L_SUBFR, qdct); /* Output in Q_AVQ_OUT_DEC */ + /*qdct = Q_AVQ_OUT_DEC;*/ + } +#ifdef IVAS_CODE_AVQ + /* TD pre-quantizer: in extreme cases at subframe boundaries, lower the preemphasis memory to avoid a saturation */ + IF (GT_16(st_fx->element_mode, EVS_MONO) && NE_16(st_fx->coder_type_fx, INACTIVE) && GE_32(st_fx->core_brate, MIN_BRATE_AVQ_EXC) && LE_32(st_fx->core_brate, MAX_BRATE_AVQ_EXC_TD) && !harm_flag_acelp && code_preQ[0] != 0) + { + PMT("Fixed point taking accound of the scaling needs to be done here ") + IF (fabs((float)(st->last_code_preq)) > 16.0f * (float)fabs(code_preQ[0])) + { + st->mem_preemp_preQ /= 16; + } + ELSE IF (fabs((float)(st->last_code_preq)) > 8.0f * (float)fabs(code_preQ[0])) + { + st->mem_preemp_preQ /= 8; + } + } + + st->last_code_preq = (int16_t)code_preQ[L_SUBFR - 1]; +#endif + /*--------------------------------------------------------------* + * Preemphasise + *--------------------------------------------------------------*/ + /* in extreme cases at subframe boundaries, lower the preemphasis memory to avoid a saturation */ + test(); + if( (nq[7] != 0) && (GT_16( sub(st_fx->last_nq_preQ_fx, nq[0]), 7))) + { + /* *mem_preemp /= 16; */ + st_fx->mem_preemp_preQ_fx= shr(st_fx->mem_preemp_preQ_fx,4); + move16(); + } + st_fx->last_nq_preQ_fx = nq[7]; + move16(); + + preemph_fx( code_preQ, FAC_PRE_AVQ_FX, L_SUBFR, &st_fx->mem_preemp_preQ_fx); + /*--------------------------------------------------------------* + * Compute normalized prequantizer excitation gain for FEC + * + * somewhat attenuate pre-quantizer normalized gain for FEC + *--------------------------------------------------------------*/ + + /*Ecode = (sum2_f( code_preQ, L_SUBFR ) + 0.01f) / L_SUBFR;*/ + /*norm_gain_preQ = 0.8f * (*gain_preQ) * (float)sqrt( Ecode );*/ + + L_tmp = Dot_product12(code_preQ, code_preQ, L_SUBFR, &exp16); + + IF( EQ_32(L_tmp,L_shl(1,sub(30,exp16)))) + { + /* pre-quantizer contribution is zero */ + *norm_gain_preQ = 1; + move16(); + } + ELSE + { + exp16 = sub(exp16, Q_AVQ_OUT_DEC*2 + 6); /* exp: (code_preQ in Q_AVQ_OUT_DEC), -6 (/L_SUBFR) */ + L_tmp = Isqrt_lc(L_tmp, &exp16); + tmp16 = extract_h(L_tmp); + exp16 = 15 - 10 - exp16; /* tmp16 in Q10+exp16*/ + tmp16 = div_s(16384,tmp16); /* Q15+Q14-(Q10+Qexp16) = Q19-exp16*/ + + L_tmp = L_mult(*gain_preQ,tmp16); /* Q2+Q19-exp16+1 -> Q22-exp16 */ + L_tmp = Mult_32_16(L_tmp, 26214 ); /* Q22-Qexp16+Q15+1-16 -> Q22-exp16*/ + *norm_gain_preQ = L_shr(L_tmp,6-exp16); + move32(); /* Q22-exp16 -> Q16*/ + } + + + st_fx->use_acelp_preq = 1; + move16(); + + return; + +} + +/*==========================================================================*/ +/* FUNCTION : Word16 gain_dequant_fx () */ +/*--------------------------------------------------------------------------*/ +/* PURPOSE : */ +/* * Returns decoded gain quantized between the specified */ +/* * range using the specified number of levels. */ +/*--------------------------------------------------------------------------*/ +/* INPUT ARGUMENTS : */ +/* Word16 index i: quantization index */ +/* Word16 min_val i : value of lower limit */ +/* Word16 max_val i : value of upper limit */ +/* Word16 bits i : number of bits to dequantize */ +/*--------------------------------------------------------------------------*/ +/* OUTPUT ARGUMENTS : */ +/* _Word16 *expg o : */ +/*--------------------------------------------------------------------------*/ +/* INPUT/OUTPUT ARGUMENTS : */ +/*--------------------------------------------------------------------------*/ +/* RETURN ARGUMENTS : */ +/* Word16 gain Q0 */ +/*--------------------------------------------------------------------------*/ +/* CALLED FROM : */ +/*==========================================================================*/ +Word16 gain_dequant_fx( /* o: decoded gain */ + Word16 index, /* i: quantization index */ + const Word16 min_val, /* i: value of lower limit */ + const Word16 max_val, /* i: value of upper limit */ + const Word16 bits, /* i: number of bits to dequantize */ + Word16 *expg +) +{ + Word16 gain, c_min, c_max; + Word16 levels; + Word16 e_tmp, f_tmp; + Word16 tmp, frac; + Word32 L_tmp; + levels = 1<Q16*/ + + frac = L_Extract_lc(L_tmp, expg); /* Extract exponent of gcode0 */ + + gain = extract_l(Pow2(14, frac));/* Put 14 as exponent so that */ + /* output of Pow2() will be: */ + /* 16384 < Pow2() <= 32767 */ + *expg = sub(*expg, 14); + + return( gain ); +} diff --git a/lib_dec/dec_nelp_fx.c b/lib_dec/dec_nelp_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..7ac5ac5bbba08a60ea88ad8cdce7bb5fc10c02a2 --- /dev/null +++ b/lib_dec/dec_nelp_fx.c @@ -0,0 +1,103 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ +#include +#include "options.h" /* Compilation switches */ +#include "cnst.h" /* Common constants */ +#include "prot_fx1.h" /* Function prototypes */ +#include "prot_fx2.h" /* Function prototypes */ + +/*======================================================================*/ +/* FUNCTION : decod_nelp_fx() */ +/*-----------------------------------------------------------------------*/ +/* PURPOSE : Decode unvoiced NELP */ +/* */ +/*-----------------------------------------------------------------------*/ +/* GLOBAL INPUT ARGUMENTS : */ +/* _ (Struct) st_fx : decoder static memory */ +/* _ (Word16) coder_type : coding type */ +/* _ (Word16[]) tmp_noise_fx : long term temporary noise energy */ +/* _ (Word16[]) pitch_buf_fx : floating pitch values for each + subframe(Q6) */ +/* _ (Word16[]) exc_fx : adapt. excitation exc (Q_exc) */ +/* _ (Word16[]) exc2_fx : adapt. excitation/total exc (Q_exc) */ +/* _ (Word16) bfi : frame error rate */ +/*-----------------------------------------------------------------------*/ +/* OUTPUT ARGUMENTS : */ +/* _ (Word16[]) exc_fx : adapt. excitation exc (Q_exc) */ +/* _ (Word16[]) exc2_fx : adapt. excitation/total exc (Q_exc) */ +/*-----------------------------------------------------------------------*/ + +/* _ (Word16[]) tmp_noise_fx : long term temporary noise energy + (Q0) */ +/* _ (Word16[]) pitch_buf_fx : floating pitch values for each + subframe (Q6) */ +/* _ (Word16[]) st_fx->dispMem : Noise enhancer - phase dispersion + algorithm memory (Q14) */ +/* _ (Word16) st_fx->tilt_code : tilt of code (Q15) */ +/* _ (Word16) st_fx->prev_gain_pit_dec */ +/*-----------------------------------------------------------------------*/ +/* RETURN ARGUMENTS : */ +/* _ None */ +/*=======================================================================*/ + +void decod_nelp_fx( + Decoder_State *st_fx, + Word16 *tmp_noise_fx, + Word16 *pitch_buf_fx, + Word16 *exc_fx, + Word16 *exc2_fx, + Word16 *voice_factors, + Word16 *bwe_exc_fx, + Word16 *Q_exc, Word16 bfi + , Word16 *gain_buf +) +{ + Word16 i; + Word16 exc_nelp_fx[L_FRAME]; + Word16 coder_type; + test(); + IF (st_fx->use_partial_copy && EQ_16(st_fx->rf_frame_type, RF_NELP)) + { + coder_type = UNVOICED; + move16(); + } + ELSE + { + coder_type = st_fx->coder_type_fx; + move16(); + } + + *tmp_noise_fx = 0; + move16(); + + nelp_decoder_fx(st_fx, exc_nelp_fx, exc_fx, Q_exc, bfi, coder_type, gain_buf); + + Copy(exc_nelp_fx, exc_fx, L_FRAME); + Copy(exc_nelp_fx, exc2_fx, L_FRAME); + + st_fx->tilt_code_fx = 0; + move16();/* purely unvoiced */ /* Q15 */ + set16_fx(st_fx->tilt_code_dec_fx, 0, NB_SUBFR16k); + + st_fx->dm_fx.prev_state = 0; + move16();/* Q0 */ + st_fx->prev_gain_pit_dec_fx = 0; + move16(); /* Q14 */ + st_fx->dm_fx.prev_gain_pit[0]= st_fx->prev_gain_pit_dec_fx; + move16(); /* Q16 */ + + FOR(i=1; i<5; i++) + { + st_fx->dm_fx.prev_gain_pit[i] = st_fx->dm_fx.prev_gain_pit[i-1]; + move16(); /* Q14 */ + } + + set16_fx(pitch_buf_fx, L_SUBFR_Q6, NB_SUBFR); /* L_SUBFR = 64, Q6 */ + set16_fx(voice_factors, 0, NB_SUBFR16k); + IF (st_fx->hBWE_TD != NULL) + { + interp_code_5over2_fx(exc2_fx, bwe_exc_fx, L_FRAME); + } + return; +} diff --git a/lib_dec/dec_pit_exc.c b/lib_dec/dec_pit_exc.c index 27e49a6ef9f180a962f05d74e4a39ef6d3acf5d4..43cf8c3ff1c38eeeae54f0fc9f84fac511282402 100644 --- a/lib_dec/dec_pit_exc.c +++ b/lib_dec/dec_pit_exc.c @@ -152,13 +152,13 @@ void dec_pit_exc( * Decode pitch lag *----------------------------------------------------------------------*/ - *pt_pitch = pit_decode( st, Pitch_BR, 0, L_frame, i_subfr, Pitch_CT, &pitch_limit_flag, &T0, &T0_frac, &T0_min, &T0_max, L_subfr, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf ); + *pt_pitch = pit_decode_flt( st, Pitch_BR, 0, L_frame, i_subfr, Pitch_CT, &pitch_limit_flag, &T0, &T0_frac, &T0_min, &T0_max, L_subfr, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf ); /*--------------------------------------------------------------* * Find the adaptive codebook vector. *--------------------------------------------------------------*/ - pred_lt4( &exc[i_subfr], &exc[i_subfr], T0, T0_frac, L_subfr + 1, inter4_2, L_INTERPOL2, PIT_UP_SAMP ); + pred_lt4_flt( &exc[i_subfr], &exc[i_subfr], T0, T0_frac, L_subfr + 1, inter4_2, L_INTERPOL2, PIT_UP_SAMP ); /*--------------------------------------------------------------* * Innovation decoding diff --git a/lib_dec/dec_pit_exc_fx.c b/lib_dec/dec_pit_exc_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..7976bf6492d8a482643b0c82abec6663756167c3 --- /dev/null +++ b/lib_dec/dec_pit_exc_fx.c @@ -0,0 +1,405 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ +#include +#include "options.h" /* Compilation switches */ +#include "cnst.h" /* Common constants */ +#include "rom_com.h" /* Static table prototypes */ +#include "prot_fx1.h" /* Function prototypes */ +#include "prot_fx2.h" /* Function prototypes */ + + +/*==========================================================================*/ +/* FUNCTION : void dec_pit_exc_fx() */ +/*--------------------------------------------------------------------------*/ +/* PURPOSE : Decode pitch only contribution */ +/*--------------------------------------------------------------------------*/ +/* INPUT ARGUMENTS : */ +/* _ (Word16*) Aq_fx : LP filter coefficient Q12 */ +/* _ (Word16) coder_type_fx : coding type Q0 */ +/* _ (Word16) nb_subfr_fx :Number of subframe considered */ +/* _ (Word16) Es_pred_fx :predicted scaled innov. energy */ +/*--------------------------------------------------------------------------*/ +/* OUTPUT ARGUMENTS : */ +/* _ (Word16*) pitch_buf_fx : floating pitch values for each subframe Q6 */ +/* _ (Word16*) code_fx : innovation */ +/*--------------------------------------------------------------------------*/ +/* INPUT/OUTPUT ARGUMENTS : */ +/* Decoder_State_fx *st_fx : decoder state structure */ +/* _ (Word16*) exc_fx : adapt. excitation exc */ +/*--------------------------------------------------------------------------*/ +/* RETURN ARGUMENTS : */ +/* _ None */ +/*==========================================================================*/ +void dec_pit_exc_fx( + Decoder_State *st_fx, /* i/o: decoder static memory */ + const Word16 *Aq_fx, /* i : LP filter coefficient */ + const Word16 coder_type_fx, /* i : coding type */ + const Word16 Es_pred_fx, /* i : predicted scaled innov. energy */ + Word16 *pitch_buf_fx, /* o : floating pitch values for each subframe */ + Word16 *code_fx, /* o : innovation */ + Word16 *exc_fx, /* i/o: adapt. excitation exc */ + Word16 *bwe_exc_fx, /* o : excitation for SWB TBE */ + const Word16 nb_subfr_fx /* i : Number of subframe considered */ + , Word16 *gain_buf /*Q14*/ +#ifdef ADD_LRTD + , const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ + const Word16 tdm_Pri_pitch_buf[] /* i : primary channel pitch buffer */ +#endif +) +{ + Word16 T0_fx, T0_frac_fx, T0_min_fx, T0_max_fx;/* integer pitch variables */ + Word16 gain_pit_fx = 0; /* pitch gain Q14 */ + Word32 gain_code_fx; /* gain/normalized gain of the algebraic excitation Q16 */ + Word32 norm_gain_code_fx; /* normalized gain of the algebraic excitation Q16 */ + Word16 gain_inov_fx; /* Innovation gain Q12 */ + Word16 voice_fac_fx; /* voicing factor Q15 */ + Word16 L_subfr_fx,pit_idx_fx; + const Word16 *p_Aq_fx; /* Pointer to frame LP coefficient Q12 */ + Word16 *pt_pitch_fx; /* pointer to floating pitch Q6 */ + Word16 i_subfr_fx, i; /* tmp variables */ + Word32 Local_BR_fx, Pitch_BR_fx; + Word16 pitch_limit_flag, Pitch_CT_fx; + Word16 exc2_bidon[L_SUBFR]; + Word16 *pt_gain; /* Pointer to floating gain values for each subframe */ + + Word16 gain_code16,gain_pitx2; + Word32 L_tmp; + Word16 nbits; + GSC_DEC_HANDLE hGSCDec; + hGSCDec = st_fx->hGSCDec; + + MUSIC_POSTFILT_HANDLE hMusicPF; + hMusicPF = st_fx->hMusicPF; + + Word16 use_fcb; + Word32 gc_mem[NB_SUBFR - 1]; /* gain_code from previous subframes */ + Word16 gp_mem[NB_SUBFR - 1]; /* gain_pitch from previous subframes */ +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + + use_fcb = 0; + move16(); + test(); test(); test(); + IF (GT_16(st_fx->GSC_IVAS_mode, 0) && (EQ_16(st_fx->GSC_noisy_speech_fx, 1) || GT_32(st_fx->core_brate, GSC_H_RATE_STG) ) ) + { + Local_BR_fx = ACELP_8k00; + Pitch_CT_fx = GENERIC; + Pitch_BR_fx = ACELP_8k00; + move32(); move32(); move16(); + IF (EQ_16(st_fx->L_frame, L_FRAME16k)) + { + Local_BR_fx = ACELP_14k80; + IF (GT_16(st_fx->GSC_IVAS_mode, 0 ) ) + { + Local_BR_fx = ACELP_9k60; + move32(); + } + Pitch_BR_fx = st_fx->core_brate; + move32(); + } + } + ELSE IF( EQ_16(st_fx->GSC_noisy_speech_fx,1)) + { + Local_BR_fx = ACELP_7k20; + move32(); + Pitch_CT_fx = GENERIC; + move16(); + Pitch_BR_fx = ACELP_7k20; + move32(); + IF(EQ_16(st_fx->L_frame, L_FRAME16k)) + { + Pitch_BR_fx = st_fx->core_brate; + move32(); + } + } + ELSE + { + Local_BR_fx = ACELP_7k20; + move32(); + Pitch_CT_fx = AUDIO; + move16(); + Pitch_BR_fx = st_fx->core_brate; + move32(); + IF(EQ_16(st_fx->L_frame, L_FRAME16k)) + { + Pitch_BR_fx = ACELP_13k20; + move32(); + Pitch_CT_fx = GENERIC; + move16(); + } + } + L_subfr_fx = mult_r(st_fx->L_frame, div_s(1, nb_subfr_fx)); /* TV2Opt : this could be less complex with 2 ifs*/ + + + gain_code_fx = 0; + move16(); + pitch_limit_flag = 1; + move16();/* always extended pitch Q range */ + test(); test(); test(); test(); test(); test(); + IF (((GE_32(st_fx->core_brate, MIN_RATE_FCB) || (EQ_16(st_fx->GSC_noisy_speech_fx, 1) && ((EQ_16(st_fx->L_frame, L_FRAME) && GE_32(st_fx->core_brate, ACELP_13k20)) || (EQ_16(st_fx->L_frame, L_FRAME16k) && GE_32(st_fx->core_brate, GSC_H_RATE_STG)) || st_fx->GSC_IVAS_mode == 0))) && EQ_16(L_subfr_fx, L_SUBFR))) + { + use_fcb = 1; move16(); + } + ELSE IF (GT_16(st_fx->GSC_IVAS_mode, 0) && EQ_16(L_subfr_fx, 2 * L_SUBFR) && LT_16(st_fx->GSC_IVAS_mode, 3) ) + { + use_fcb = 2; + st_fx->acelp_cfg.fcb_mode = 1; + move16(); move16(); + set16_fx(st_fx->acelp_cfg.gains_mode, 6, 4); + set16_fx(st_fx->acelp_cfg.pitch_bits, 9, 4); + set16_fx(st_fx->acelp_cfg.fixed_cdk_index, 14, 5); + } + /*------------------------------------------------------------------* + * ACELP subframe loop + *------------------------------------------------------------------*/ + p_Aq_fx = Aq_fx; /* pointer to interpolated LPC parameters */ + pt_pitch_fx = pitch_buf_fx; /* pointer to the pitch buffer */ + pt_gain = gain_buf; /* pointer to the gain buffer */ + FOR ( i_subfr_fx = 0; i_subfr_fx < st_fx->L_frame; i_subfr_fx += L_subfr_fx ) + { + /*----------------------------------------------------------------------* + * Decode pitch lag + *----------------------------------------------------------------------*/ + *pt_pitch_fx = pit_decode_fx(st_fx, Pitch_BR_fx, 0, st_fx->L_frame, i_subfr_fx, Pitch_CT_fx, &pitch_limit_flag, &T0_fx, &T0_frac_fx, &T0_min_fx, &T0_max_fx, L_subfr_fx +#ifdef ADD_LRTD + , tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf +#endif + ); + move16(); + + /*--------------------------------------------------------------* + * Find the adaptive codebook vector. + *--------------------------------------------------------------*/ + + pred_lt4( &exc_fx[i_subfr_fx], &exc_fx[i_subfr_fx], T0_fx, T0_frac_fx, L_subfr_fx+1, pitch_inter4_2, L_INTERPOL2, PIT_UP_SAMP ); + + /*--------------------------------------------------------------* + * Innovation decoding + *--------------------------------------------------------------*/ + + IF( EQ_16(use_fcb,1)) + { + inov_decode_fx( st_fx, Local_BR_fx, 0, st_fx->L_frame, 1, i_subfr_fx, p_Aq_fx, st_fx->tilt_code_fx, *pt_pitch_fx, code_fx, L_subfr_fx); + /*--------------------------------------------------------------* + * Gain decoding + * Estimate spectrum tilt and voicing + *--------------------------------------------------------------*/ + + gain_dec_mless_fx( st_fx, st_fx->L_frame, LOCAL_CT, i_subfr_fx, -1, code_fx, Es_pred_fx, &gain_pit_fx, &gain_code_fx, &gain_inov_fx, &norm_gain_code_fx ); + + st_fx->tilt_code_fx = est_tilt_fx( exc_fx+i_subfr_fx, gain_pit_fx, code_fx, gain_code_fx, &voice_fac_fx,0 +#ifdef ADD_LRTD + , L_subfr_fx +#endif + ); + } + ELSE IF(EQ_16(use_fcb, 2)) /* IVAS only */ + { + inov_decode_fx(st_fx, Local_BR_fx, 0, st_fx->L_frame, 1, i_subfr_fx, p_Aq_fx, st_fx->tilt_code_fx, *pt_pitch_fx, code_fx, L_subfr_fx); + /*--------------------------------------------------------------* + * Gain decoding + * Estimate spectrum tilt and voicing + *--------------------------------------------------------------*/ + + gain_dec_lbr_fx(st_fx, GENERIC, i_subfr_fx, code_fx, &gain_pit_fx, &gain_code_fx, &gain_inov_fx, &norm_gain_code_fx, gc_mem, gp_mem, L_subfr_fx); + + st_fx->tilt_code_fx = est_tilt_fx(exc_fx + i_subfr_fx, gain_pit_fx, code_fx, gain_code_fx, &voice_fac_fx, 0 +#ifdef ADD_LRTD + , L_subfr_fx +#endif + ); + + } + ELSE + { + nbits = 5; + IF ( LT_32(st_fx->core_brate, MIN_RATE_FCB) ) + { + nbits = 4; + } + move16(); + + set16_fx(code_fx, 0, L_SUBFR); + gain_code_fx = L_deposit_l(0); + st_fx->tilt_code_fx = 0; + move16(); + pit_idx_fx = (Word16)get_next_indice( st_fx, nbits ); + move16(); + + gain_pit_fx = add(9590,dic_gp_fx[pit_idx_fx]); + move16(); /*Q14 0.5853 in Q14 9590*/ + + if( st_fx->BER_detect ) /* Bitstream is corrupted, use the past pitch gain */ + { + gain_pit_fx = st_fx->lp_gainp_fx; + move16(); + } +#ifdef BASOP_NOGLOB + gain_code_fx = L_mult0(s_max(sub(32767, shl_o(gain_pit_fx, 1, &Overflow)), 16384), st_fx->lp_gainc_fx); /* Use gain pitch and past gain code as an indicator to help finding the best scaling value. gain_code_fx used a temp var*/ +#else + gain_code_fx = L_mult0(s_max(sub(32767, shl(gain_pit_fx,1)), 16384), st_fx->lp_gainc_fx); /* Use gain pitch and past gain code as an indicator to help finding the best scaling value. gain_code_fx used a temp var*/ +#endif + } + + /*----------------------------------------------------------------------* + * Find the total excitation + *----------------------------------------------------------------------*/ + + Rescale_exc(hMusicPF->dct_post_old_exc_fx, &exc_fx[i_subfr_fx], &bwe_exc_fx[i_subfr_fx * HIBND_ACB_L_FAC], hGSCDec->last_exc_dct_in_fx, + L_subfr_fx, L_subfr_fx * HIBND_ACB_L_FAC, gain_code_fx, &(st_fx->Q_exc), st_fx->Q_subfr, NULL, i_subfr_fx, coder_type_fx); + + gain_code16 = round_fx(L_shl(gain_code_fx,st_fx->Q_exc)); /*Q_exc*/ + + IF( NE_16(use_fcb,0)) + { + Acelp_dec_total_exc( exc_fx, exc2_bidon-i_subfr_fx, gain_code16, gain_pit_fx, i_subfr_fx, code_fx, L_subfr_fx); + } + ELSE + { + IF (norm_s(s_or(gain_pit_fx, 1)) == 0) + { + FOR (i = 0; i < L_subfr_fx; i++) + { + L_tmp = L_shl(L_mult(gain_pit_fx, exc_fx[i+i_subfr_fx]), 1); /*Q16+Q_exc*/ + exc_fx[i+i_subfr_fx] = round_fx(L_tmp); /*Q_exc*/ + } + } + ELSE + { + gain_pitx2 = shl(gain_pit_fx, 1); /*Q15*/ + + FOR (i = 0; i < L_subfr_fx; i++) + { + L_tmp = L_mult(gain_pitx2, exc_fx[i+i_subfr_fx]); /*Q16+Q_exc*/ + exc_fx[i+i_subfr_fx] = round_fx(L_tmp); /*Q_exc*/ + } + } + } + + IF (EQ_16(L_subfr_fx, L_FRAME16k)) + { + /* update gains for FEC - equivalent to lp_gain_updt() */ + st_fx->lp_gainp_fx = gain_pit_fx; move16(); + st_fx->lp_gainc_fx = 0; move32(); + + pt_pitch_fx++; + *pt_pitch_fx = *(pt_pitch_fx - 1); + pt_pitch_fx++; + *pt_pitch_fx = *(pt_pitch_fx - 1); + pt_pitch_fx++; + *pt_pitch_fx = *(pt_pitch_fx - 1); + pt_pitch_fx++; + *pt_pitch_fx = *(pt_pitch_fx - 1); + pt_pitch_fx++; + move16(); move16(); move16(); move16(); move16(); + p_Aq_fx += 5 * (M + 1); + } + ELSE IF (EQ_16(L_subfr_fx, L_FRAME16k/2)) + { + IF (i_subfr_fx == 0) + { + pt_pitch_fx++; + *pt_pitch_fx = *(pt_pitch_fx - 1); + pt_pitch_fx++; + p_Aq_fx += 2 * (M + 1); + move16(); move16(); move16(); move16(); + + /* update gains for FEC - equivalent to lp_gain_updt() */ + st_fx->lp_gainp_fx = extract_h(L_mult(6554, gain_pit_fx)); /*Q14 (3/15 in Q15 9830)*/ + st_fx->lp_gainc_fx = 0; move32(); + } + ELSE + { + pt_pitch_fx++; + *pt_pitch_fx = *(pt_pitch_fx - 1); + pt_pitch_fx++; + *pt_pitch_fx = *(pt_pitch_fx - 1); + pt_pitch_fx++; + p_Aq_fx += 3 * (M + 1); + move16(); move16(); move16(); move16(); + + /* update gains for FEC - equivalent to lp_gain_updt() */ + st_fx->lp_gainp_fx = extract_h(L_mult(26214, gain_pit_fx)); /*Q14 (12/15 in Q15 9830)*/ + st_fx->lp_gainc_fx = 0; move32(); + } + } + ELSE IF( EQ_16(L_subfr_fx,128)) /*2*L_SUBFR*/ + { + p_Aq_fx += 2*(M+1); + move16(); + pt_pitch_fx++; + *pt_pitch_fx = *(pt_pitch_fx-1); + move16(); + pt_pitch_fx++; + *pt_gain = gain_pit_fx; + move16(); + pt_gain++; + *pt_gain = *(pt_gain-1); + move16(); + pt_gain++; + IF( i_subfr_fx == 0 ) + { + /* update gains for FEC - equivalent to lp_gain_updt() */ + st_fx->lp_gainp_fx = extract_h(L_mult(9830,gain_pit_fx)); /*Q14 (3/10 in Q15 9830)*/ + st_fx->lp_gainc_fx = 0; + move16(); + } + ELSE + { + /* update gains for FEC - equivalent to lp_gain_updt() */ + st_fx->lp_gainp_fx = extract_h(L_mult(22938,gain_pit_fx)); /*Q14 (7/10 in Q15 22938)*/ + st_fx->lp_gainc_fx = 0; + move16(); + } + } + ELSE IF( EQ_16(L_subfr_fx,256)) /*4*L_SUBFR*/ + { + pt_pitch_fx++; + *pt_pitch_fx = *(pt_pitch_fx-1); + move16(); + pt_pitch_fx++; + *pt_pitch_fx = *(pt_pitch_fx-1); + move16(); + pt_pitch_fx++; + *pt_pitch_fx = *(pt_pitch_fx-1); + move16(); + pt_pitch_fx++; + *pt_gain = gain_pit_fx; + move16(); + pt_gain++; + *pt_gain = *(pt_gain-1); + move16(); + pt_gain++; + *pt_gain = *(pt_gain-1); + move16(); + pt_gain++; + *pt_gain = *(pt_gain-1); + move16(); + pt_gain++; + p_Aq_fx += 4*(M+1); + move16(); + + /* update gains for FEC - equivalent to lp_gain_updt() */ + st_fx->lp_gainp_fx = gain_pit_fx; + move16(); + st_fx->lp_gainc_fx = 0; + move16(); + } + ELSE + { + p_Aq_fx += (M+1); + move16(); + pt_pitch_fx++; + move16(); + *pt_gain = gain_pit_fx; + move16(); + pt_gain++; + + lp_gain_updt_fx( i_subfr_fx, gain_pit_fx, 0, &st_fx->lp_gainp_fx, &st_fx->lp_gainc_fx, st_fx->L_frame); + } + } + + return; +} diff --git a/lib_dec/dec_post.c b/lib_dec/dec_post.c index 99c3b4041439583e3308771b9f2858a98bbabf5d..9aa654ca423c5db60de3e1dc8dd7888ecad22203 100644 --- a/lib_dec/dec_post.c +++ b/lib_dec/dec_post.c @@ -71,12 +71,12 @@ static void Dec_formant_postfilt( PFSTAT *pfstat, const float *signal_ptr, const /*--------------------------------------------------------------------------* - * Function Init_post_filter() + * Function Init_post_filter_ivas() * * Post-filter initialization *--------------------------------------------------------------------------*/ -void Init_post_filter( +void Init_post_filter_ivas( PFSTAT_HANDLE hPFstat /* i/o: post-filter state memories handle */ ) { @@ -106,12 +106,12 @@ void Init_post_filter( /*-------------------------------------------------------------------------- - * nb_post_filt() + * nb_post_filt_ivas() * * Main routine to perform post filtering of NB signals *--------------------------------------------------------------------------*/ -void nb_post_filt( +void nb_post_filt_ivas( const int16_t L_frame, /* i : frame length */ const int16_t L_subfr, /* i : sub-frame length */ PFSTAT_HANDLE hPFstat, /* i/o: Post filter related memories */ @@ -186,7 +186,7 @@ void nb_post_filt( * WB and SWB formant post-filtering *--------------------------------------------------------------------------*/ -void formant_post_filt( +void formant_post_filt_ivas( PFSTAT_HANDLE hPFstat, /* i/o: Post filter related memories */ float *synth_in, /* i : 12k8 synthesis */ const float *Aq, /* i : LP filter coefficient */ @@ -378,7 +378,7 @@ static void Dec_postfilt( filt_mu( sig_ltp, sig_out, parcor0, L_subfr, -1 ); /* Gain control */ - scale_st( signal_ptr, sig_out, &( pfstat->gain_prec_flt), L_subfr, -1 ); + scale_st_ivas( signal_ptr, sig_out, &( pfstat->gain_prec_flt), L_subfr, -1 ); /* Update for next subframe */ mvr2r( &res2[L_subfr], pfstat->mem_res2_flt, DECMEM_RES2 ); @@ -443,7 +443,7 @@ static void Dec_formant_postfilt( filt_mu( resynth, sig_out, parcor0, l_subfr, -1 ); /* Gain control */ - scale_st( signal_ptr, sig_out, &hPFstat->gain_prec_flt, l_subfr, -1 ); + scale_st_ivas( signal_ptr, sig_out, &hPFstat->gain_prec_flt, l_subfr, -1 ); return; } diff --git a/lib_dec/dec_post_fx.c b/lib_dec/dec_post_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..aaf334c68da6fac290b4d2f469e5ad3b00c9366a --- /dev/null +++ b/lib_dec/dec_post_fx.c @@ -0,0 +1,1613 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ +#include +#include "options.h" +#include "prot_fx1.h" +#include "prot_fx2.h" +#include "basop_util.h" +#include "rom_dec.h" +#include "rom_com.h" +#include "cnst.h" + +#define FORMAT_POST_FILT_G1 24576/*0.75f Q15*/ /*0.75f*/ /*denominator 0.9,0.75,0.15,0.9*/ +#define FORMAT_POST_FILT_G2 22938/*0.7f Q15*/ /*0.7f*/ /*numerator 0.75,0.7,0.1,0.7*/ +#define FORMAT_POST_FILT_G1_MAX 26214/*0.8f Q15*/ /*for low bit-rates on clean speech*/ +#define FORMAT_POST_FILT_G1_MIN 24576/*0.75f Q15*/ /*for high bit-rates on clean speech and noisy speech*/ + +/*-------------------------------------------------------------------------- + * Local function prototypes + *--------------------------------------------------------------------------*/ + +static void Dec_postfilt( PFSTAT_HANDLE hPFstat, const Word16 t0, const Word16 *signal_ptr, const Word16 *coeff, + Word16 *sig_out, const Word16 gamma1, const Word16 gamma2, const Word16 Gain_factor, const Word16 disable_hpf ); + +static void pst_ltp( Word16 t0, Word16 * ptr_sig_in, Word16 * ptr_sig_pst0, Word16 gain_factor ); + +static void search_del( Word16 t0, Word16 * ptr_sig_in, Word16 * ltpdel, Word16 * phase, Word16 * num_gltp, Word16 * den_gltp, + Word16 * sh_num_gltp, Word16 * sh_den_gltp, Word16 * y_up, Word16 * off_yup ); + +static void filt_plt( Word16 * s_in, Word16 * s_ltp, Word16 * s_out, Word16 gain_plt ); + +static void compute_ltp_l( Word16 * s_in, Word16 ltpdel, Word16 phase, Word16 * y_up, Word16 * num, Word16 * den, Word16 * sh_num, Word16 * sh_den ); + +static Word16 select_ltp( Word16 num1, Word16 den1, Word16 sh_num1, Word16 sh_den1, Word16 num2, Word16 den2, Word16 sh_num2, Word16 sh_den2 ); + +static void calc_st_filt( Word16 * apond2, Word16 * apond1, Word16 * parcor0, Word16 * sig_ltp_ptr, Word16 * mem_zero ); + +static void modify_pst_param( const Word16 lp_noise, Word16 *g1, Word16 *g2, const Word16 coder_type, Word16 *gain_factor ); + +static void Dec_formant_postfilt( PFSTAT_HANDLE hPFstat, Word16 *signal_ptr, Word16 *coeff, Word16 *sig_out, Word16 gamma1, Word16 gamma2 ); + + +/*-------------------------------------------------------------------------- + * Init_post_filter + * + * post filter initialization + *--------------------------------------------------------------------------*/ +void Init_post_filter( + PFSTAT_HANDLE hPFstat /* i : core decoder parameters */ +) +{ + /* It is off by default */ + hPFstat->on = 0; + + /* Reset */ + hPFstat->reset = 0; + + /* Initialize arrays and pointers */ + set16_fx(hPFstat->mem_pf_in, 0, L_SUBFR); + + /* res2 = A(gamma2) residual */ + set16_fx(hPFstat->mem_res2, 0, DECMEM_RES2); + + /* 1/A(gamma1) memory */ + set16_fx(hPFstat->mem_stp, 0, L_SUBFR); + + /* null memory to compute i.r. of A(gamma2)/A(gamma1) */ + set16_fx(hPFstat->mem_zero, 0, M); + + /* for gain adjustment */ + hPFstat->gain_prec = 16384; /*Q14*/ move16(); + + return; +} + +/*-------------------------------------------------------------------------- + * NB_post_filt: + * + * Main routine to perform post filtering on NB synthesis + *--------------------------------------------------------------------------*/ +void nb_post_filt( + const Word16 L_frame, /* i : frame length */ + PFSTAT_HANDLE hPFstat, /* i : core decoder parameters */ + Word16 *psf_lp_noise, /* i : Long term noise Q8 */ + const Word16 tmp_noise, /* i : noise energy Q0 */ + Word16 *Synth, /* i : 12k8 synthesis Qsyn */ + const Word16 *Aq, /* i : LP filter coefficient Q12 */ + const Word16 *Pitch_buf, /* i : Fractionnal subframe pitch buffer Q6 */ + const Word16 coder_type, /* i : coder_type */ + const Word16 BER_detect, /* i : BER detect flag */ + const Word16 disable_hpf /* i : flag to diabled HPF */ +) +{ + Word16 i, j, Post_G1, Post_G2, Gain_factor; + Word16 T0_first, *Pf_in; + const Word16 *p_Aq; + Word16 pf_in_buffer[M+L_FRAME16k]; + + IF( BER_detect == 0 ) + { + /* update long-term background noise energy during inactive frames */ + IF( EQ_16(coder_type,INACTIVE)) + { + *psf_lp_noise = round_fx(L_mac(L_mult(31130, *psf_lp_noise), 26214 /*0.05 Q19*/, shl(tmp_noise,4))); /*Q8*Q15 + Q19*Q4 -> Q8 */ + } + } + + modify_pst_param( *psf_lp_noise, &Post_G1, &Post_G2, coder_type, &Gain_factor ); + + if(hPFstat->reset) + { + set16_fx(hPFstat->mem_res2, 0, DECMEM_RES2); + Copy( &Synth[L_frame-L_SYN_MEM], hPFstat->mem_pf_in, L_SYN_MEM); + Copy( &Synth[L_frame-L_SYN_MEM], hPFstat->mem_stp, L_SYN_MEM ); + hPFstat->gain_prec = 16384; + move16(); + hPFstat->reset = 0; + move16(); + return; + } + Pf_in = &pf_in_buffer[M]; + Copy( hPFstat->mem_pf_in+L_SYN_MEM-M, &Pf_in[-M], M ); + Copy( Synth, Pf_in, L_frame ); + Copy( &Synth[L_frame - L_SYN_MEM], hPFstat->mem_pf_in, L_SYN_MEM ); + /* deactivation of the post filter in case of AUDIO because it causes problems to singing sequences */ + if( EQ_16(coder_type,AUDIO)) + { + Post_G1 = 32767; + move16(); + Post_G2 = 32767; + move16(); + Gain_factor = 32767; + move16(); + } + + + /* run the post filter */ + p_Aq = Aq; + move16(); + j = 0; + move16(); + FOR (i = 0; i < L_frame; i += L_SUBFR) + { + T0_first = Pitch_buf[j]; + + Dec_postfilt( hPFstat, T0_first, &Pf_in[i], p_Aq, &Synth[i], Post_G1, Post_G2, Gain_factor, disable_hpf ); + + p_Aq += (M+1); + j = add(j,1); + } + + + return; +} + +/*---------------------------------------------------------------------------- + * Dec_postfilt() + * + * Post - adaptive postfilter main function + * Short term postfilter : + * Hst(z) = Hst0(z) Hst1(z) + * Hst0(z) = 1/g0 A(gamma2)(z) / A(gamma1)(z) + * if {hi} = i.r. filter A(gamma2)/A(gamma1) (truncated) + * g0 = SUM(|hi|) if > 1 + * g0 = 1. else + * Hst1(z) = 1/(1 - |mu|) (1 + mu z-1) + * with mu = k1 * gamma3 + * k1 = 1st parcor calculated on {hi} + * gamma3 = gamma3_minus if k1<0, gamma3_plus if k1>0 + * Long term postfilter : + * harmonic postfilter : H0(z) = gl * (1 + b * z-p) + * b = gamma_g * gain_ltp + * gl = 1 / 1 + b + * computation of delay p on A(gamma2)(z) s(z) + * sub optimal search + * 1. search around 1st subframe delay (3 integer values) + * 2. search around best integer with fract. delays (1/8) + *----------------------------------------------------------------------------*/ +static void Dec_postfilt( + PFSTAT_HANDLE hPFstat, /* i : core decoder parameters */ + const Word16 t0, /* i : pitch delay given by coder */ + const Word16 * signal_ptr, /* i : input signal (pointer to current subframe */ + const Word16 * coeff, /* i : LPC coefficients for current subframe */ + Word16 * sig_out, /* o : postfiltered output */ + const Word16 gamma1, /* i : short term postfilt. den. weighting factor */ + const Word16 gamma2, /* i : short term postfilt. num. weighting factor */ + const Word16 Gain_factor, /* i : Gain Factor (Q15) */ + const Word16 disable_hpf +) +{ + /* Local variables and arrays */ + Word16 apond1[M+1]; /* s.t. denominator coeff. */ + Word16 apond2[LONG_H_ST]; + Word16 sig_ltp[L_SUBFR+1]; /* H0 output signal */ + Word16 res2[SIZ_RES2]; + + Word16 *sig_ltp_ptr; + Word16 *res2_ptr; + Word16 *ptr_mem_stp; + + Word16 parcor0; + + + /* Init pointers and restore memories */ + res2_ptr = res2 + DECMEM_RES2; + ptr_mem_stp = hPFstat->mem_stp + L_SYN_MEM - 1; + Copy(hPFstat->mem_res2, res2, DECMEM_RES2); + + /* Compute weighted LPC coefficients */ + weight_a_fx(coeff, apond1, gamma1, M); + weight_a_fx(coeff, apond2, gamma2, M); + set16_fx(&apond2[M+1], 0, LONG_H_ST-(M+1)); + + /* Compute A(gamma2) residual */ + Residu3_fx(apond2, signal_ptr, res2_ptr, L_SUBFR, 1); + + /* Harmonic filtering */ + sig_ltp_ptr = sig_ltp + 1; + + IF (disable_hpf == 0) + { + pst_ltp( t0, res2_ptr, sig_ltp_ptr, Gain_factor ); + } + ELSE + { + Copy(res2_ptr, sig_ltp_ptr, L_SUBFR); + } + + /* Save last output of 1/A(gamma1) */ + /* (from preceding subframe) */ + sig_ltp[0] = *ptr_mem_stp; + move16(); + + /* Controls short term pst filter gain and compute parcor0 */ + calc_st_filt(apond2, apond1, &parcor0, sig_ltp_ptr, hPFstat->mem_zero ); + + E_UTIL_synthesis(1, apond1, sig_ltp_ptr, sig_ltp_ptr, L_SUBFR, hPFstat->mem_stp+L_SYN_MEM-M, 0, M); + Copy( sig_ltp_ptr+L_SUBFR-L_SYN_MEM, hPFstat->mem_stp, L_SYN_MEM ); + + /* Tilt filtering */ + Filt_mu(sig_ltp, sig_out, parcor0, L_SUBFR); + + /* Gain control */ + scale_st(signal_ptr, sig_out, &hPFstat->gain_prec, L_SUBFR); + + /* Update for next subframe */ + Copy(&res2[L_SUBFR], hPFstat->mem_res2, DECMEM_RES2); + + + return; +} + +/*-------------------------------------------------------------------------- + * formant_post_filt: + * + * Main routine to perform formant post filtering + *--------------------------------------------------------------------------*/ +void formant_post_filt( + PFSTAT_HANDLE hPFstat, /* i : core decoder parameters */ + Word16 *synth_in, /* i : 12k8 synthesis */ + Word16 *Aq, /* i : LP filter coefficient */ + Word16 *synth_out, /* i/o: input signal */ + Word16 L_frame, + Word32 lp_noise, /* (i) : background noise energy (15Q16) */ + Word32 brate, /* (i) : bit-rate */ + const Word16 off_flag /* i : off flag */ +) +{ + Word16 i_subfr; + Word16 *p_Aq; + Word16 post_G1, post_G2; + + + /*default parameter for noisy speech and high bit-rates*/ + IF (EQ_16(L_frame, L_FRAME)) + { + post_G2 = 22938/*0.7f Q15*/; + move16(); + IF (LT_32(lp_noise, LP_NOISE_THRESH)) + { + /*Clean speech*/ + IF (LT_32(brate, ACELP_13k20)) + { + /*Low rates*/ + + post_G1 = 26214/*0.8f Q15*/; + move16(); + } + ELSE IF (LT_32(brate, ACELP_24k40)) + { + /*Low rates*/ + + post_G1 = 24576/*0.75f Q15*/; + move16(); + } + ELSE + { + post_G1 = 23593/*0.72f Q15*/; + move16(); + } + } + ELSE /*Noisy speech*/ + { + post_G1 = 22938/*0.7f Q15*/; + move16(); + if (LT_32(brate, ACELP_15k85)) + { + /*Low rates*/ + post_G1 = 24576/*0.75f Q15*/; + move16(); + } + } + } + ELSE + { + post_G2 = 24904/*0.76f Q15*/; + move16(); + test(); + IF (GE_32(lp_noise, LP_NOISE_THRESH)) + { + post_G1 = 24904/*0.76f Q15*/; + } + ELSE IF (EQ_32(brate, ACELP_13k20)) + { + post_G1 = 26870/*0.82f Q15*/; + move16(); + } + ELSE IF (EQ_32(brate, ACELP_16k40)) + { + post_G1 = 26214/*0.80f Q15*/; + move16(); + } + ELSE IF (EQ_32(brate, ACELP_24k40)||EQ_32(brate,ACELP_32k)) + { + post_G1 = 25559/*0.78f Q15*/; + move16(); + } + ELSE + { + post_G1 = 24904/*0.76f Q15*/; + move16(); + } + } + + /* Switch off post-filter */ + if( off_flag != 0 ) + { + post_G1 = post_G2; + move16(); + } + + /* Reset post filter */ + if( hPFstat->reset != 0 ) + { + post_G1 = MAX16B; + move16(); + post_G2 = MAX16B; + move16(); + hPFstat->reset = 0; + move16(); + Copy( &synth_in[L_frame-L_SYN_MEM], hPFstat->mem_pf_in, L_SYN_MEM); + Copy( &synth_in[L_frame-L_SYN_MEM], hPFstat->mem_stp, L_SYN_MEM ); + hPFstat->gain_prec = 16384; + move16(); + Copy( synth_in,synth_out, L_frame ); + + return; + } + + /* input memory*/ + Copy( hPFstat->mem_pf_in, synth_in-L_SYN_MEM, L_SYN_MEM); + Copy( &synth_in[L_frame-L_SYN_MEM], hPFstat->mem_pf_in, L_SYN_MEM); + + move16(); + p_Aq = Aq; + FOR (i_subfr = 0; i_subfr < L_frame; i_subfr += L_SUBFR ) + { + Dec_formant_postfilt(hPFstat, &synth_in[i_subfr], p_Aq, &synth_out[i_subfr], post_G1, post_G2 ); + p_Aq += (M+1); + } + +} + +/*---------------------------------------------------------------------------- + * Dec_postfilt + * + * Post - adaptive postfilter main function + * Short term postfilter : + * Hst(z) = Hst0(z) Hst1(z) + * Hst0(z) = 1/g0 A(gamma2)(z) / A(gamma1)(z) + * if {hi} = i.r. filter A(gamma2)/A(gamma1) (truncated) + * g0 = SUM(|hi|) if > 1 + * g0 = 1. else + * Hst1(z) = 1/(1 - |mu|) (1 + mu z-1) + * with mu = k1 * gamma3 + * k1 = 1st parcor calculated on {hi} + * gamma3 = gamma3_minus if k1<0, gamma3_plus if k1>0 + *----------------------------------------------------------------------------*/ +static void Dec_formant_postfilt( + PFSTAT_HANDLE hPFstat, /* i : core decoder parameters */ + Word16 *signal_ptr, /* i : input signal (pointer to current subframe */ + Word16 *coeff, /* i : LPC coefficients for current subframe */ + Word16 *sig_out, /* o : postfiltered output */ + Word16 gamma1, /* i : short term postfilt. den. weighting factor*/ + Word16 gamma2 /* i : short term postfilt. num. weighting factor*/ +) +{ + /* Local variables and arrays */ + Word16 apond1[M+1]; /* s.t. denominator coeff. */ + Word16 apond2[LONG_H_ST]; + Word16 res2[L_SUBFR]; + Word16 resynth[L_SUBFR+1]; + Word16 parcor0; + Word16 i, max; + Word16 scale_down; + + /* Compute weighted LPC coefficients */ + weight_a_fx(coeff, apond1, gamma1, M); + weight_a_fx(coeff, apond2, gamma2, M); + set16_fx(&apond2[M+1], 0, LONG_H_ST-(M+1)); + + max = abs_s(signal_ptr[0]); + FOR (i = 1; i < L_SUBFR; i++) + { + max = s_max(max, abs_s(signal_ptr[i])); + } + scale_down = 0; + move16(); + if (GT_16(max, 16384)) + { + scale_down = 1; + move16(); + } + + /* Compute A(gamma2) residual */ + IF (!scale_down) + { + Residu3_fx(apond2, signal_ptr, res2, L_SUBFR, 1); + } + ELSE + { + Residu3_fx(apond2, signal_ptr, res2, L_SUBFR, 0); + Scale_sig(hPFstat->mem_stp, L_SYN_MEM, -1); + } + + /* Controls short term pst filter gain and compute parcor0 */ + calc_st_filt(apond2, apond1, &parcor0, res2, hPFstat->mem_zero ); + + /* 1/A(gamma1) filtering, mem_stp is updated */ + resynth[0] = *(hPFstat->mem_stp + sub(L_SYN_MEM, 1)); + move16(); + + E_UTIL_synthesis(1, apond1, res2, &(resynth[1]), L_SUBFR, hPFstat->mem_stp+L_SYN_MEM-M, 0, M); + + IF (!scale_down) + { + Copy( &(resynth[1])+L_SUBFR-L_SYN_MEM, hPFstat->mem_stp, L_SYN_MEM ); + } + ELSE + { + Copy_Scale_sig( &(resynth[1])+L_SUBFR-L_SYN_MEM, hPFstat->mem_stp, L_SYN_MEM, 1 ); + } + + /* Tilt filtering */ + Filt_mu(resynth, sig_out, parcor0, L_SUBFR); + IF (scale_down) + { + Scale_sig(sig_out, L_SUBFR, 1); + } + + /* Gain control */ + scale_st(signal_ptr, sig_out, &hPFstat->gain_prec, L_SUBFR); + + + return; +} + + +/*------------------------------------------------------------------------------------ + * modify_pst_param() + * + * Modify gamma1 and gamma2 values in function of the long term noise level + *-----------------------------------------------------------------------------------*/ + +static void modify_pst_param( + const Word16 lp_noise, /* i : Long term noise energy Q8 */ + Word16 *g1, /* o : Gamma1 used in post filter Q15 */ + Word16 *g2, /* o : Gamma1 used in post filter Q15 */ + const Word16 coder_type, /* i : Vad information decoded in UV frame */ + Word16 *gain_factor /* o : Gain factor applied in post filtering */ +) +{ + Word16 tmp; + Word16 lp_noiseQ12; + Word32 L_tmp; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + + + test(); + IF( NE_16(coder_type,INACTIVE)&<_16(lp_noise,LP_NOISE_THR_FX)) + { +#ifdef BASOP_NOGLOB + lp_noiseQ12 = shl_o(lp_noise, 4, &Overflow); /* to go from Q8 to Q12 */ +#else + lp_noiseQ12 = shl(lp_noise, 4); /* to go from Q8 to Q12 */ +#endif + + /* ftmp = lp_noise*BG1_FX + CG1_FX */ + tmp = mac_r(CG1_FX*65536L, lp_noiseQ12, BG1_FX*8); /* x8 to go from Q12 to Q15 */ + tmp = s_min(tmp, POST_G1_FX ); + tmp = s_max(tmp, GAMMA1_PST12K_MIN_FX ); + + *g1 = tmp; + move16(); + + /* ftmp = lp_noise*BG2_FX + CG2_FX */ + L_tmp = L_mac0(CG2_FX/2*65536L, lp_noiseQ12, BG2_FX*8);/* L_mac0 and /2 to go from Q12 to Q14 */ + /* we go to Q30 to avoid overflow CG2_FX*/ + + L_tmp = L_min(L_tmp, POST_G2_FX*65536L/2); /* /2 because L_tmp is Q30 */ + L_tmp = L_max(L_tmp, GAMMA2_PST12K_MIN_FX*65536L/2); + + *g2 = extract_h(L_shl(L_tmp, 1)); /* Q30=>Q31=>Q15 */ + } + ELSE + { + *g1 = GAMMA1_PST12K_NOIS_FX; + move16(); + *g2 = GAMMA2_PST12K_NOIS_FX; + move16(); + } + + /* Set gain_factor of the harmonic filtering*/ + /* ftmp = (lp_noise - K_LP_NOISE)*C_LP_NOISE_FX */ + L_tmp = L_mac(-CK_LP_NOISE_FX, lp_noise, C_LP_NOISE_FX); /* tmp is in Q24 (from Q8) */ + + L_tmp = L_min(L_tmp, 64*65536L); /* 0.25 in Q24 */ + L_tmp = L_max(L_tmp, 0); + + *gain_factor = extract_h(L_shl(L_tmp, 7)); /* Q24=>Q31=>Q15 */ + + + return; +} + +/*---------------------------------------------------------------------------- + * pst_ltp + * + * Perform harmonic postfilter + *----------------------------------------------------------------------------*/ +static void pst_ltp( + Word16 t0, /* i : pitch delay given by coder */ + Word16 * ptr_sig_in, /* i : postfilter i filter (residu2) */ + Word16 * ptr_sig_pst0, /* o : harmonic postfilter o */ + Word16 gain_factor /* i : Gain Factor (Q15) */ +) +{ + Word32 L_temp; + + Word16 y_up[SIZ_Y_UP]; + Word16 sig_cadr[SIZ_RES2]; + + Word16 *ptr_y_up; + Word16 *ptr_sig; + Word16 *ptr_sig_cadr; + + Word16 i; + Word16 temp; + Word16 ltpdel, phase; + Word16 num_gltp, den_gltp; + Word16 num2_gltp, den2_gltp; + Word16 sh_num, sh_den; + Word16 sh_num2, sh_den2; + Word16 gain_plt; + Word16 off_yup; + Word16 nb_sh_sig; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + + + + /* i signal justified on 13 bits */ + ptr_sig = ptr_sig_in - DECMEM_RES2; + nb_sh_sig = getScaleFactor16(ptr_sig, add(DECMEM_RES2, L_SUBFR)); + nb_sh_sig = sub(3, nb_sh_sig); + + FOR (i = 0; i < DECMEM_RES2+L_SUBFR; i++) + { + /* nb_sh_sig may be >0, <0 or =0 */ + sig_cadr[i] = shr(ptr_sig[i], nb_sh_sig); + move16(); + } + ptr_sig_cadr = sig_cadr + DECMEM_RES2; + + /* Sub optimal delay search */ + search_del(t0, ptr_sig_cadr, <pdel, &phase, &num_gltp, &den_gltp, &sh_num, &sh_den, y_up, &off_yup); + + + IF (num_gltp == 0) + { + Copy(ptr_sig_in, ptr_sig_pst0, L_SUBFR); + } + ELSE + { + IF (phase == 0) + { + ptr_y_up = ptr_sig_in - ltpdel; + } + ELSE + { + /* Filtering with long filter */ + compute_ltp_l(ptr_sig_cadr, ltpdel, phase, ptr_sig_pst0, &num2_gltp, &den2_gltp, &sh_num2, &sh_den2); + + + IF (EQ_16(select_ltp(num_gltp, den_gltp, sh_num, sh_den, num2_gltp, den2_gltp, sh_num2, sh_den2), 1)) + { + /* select short filter */ + temp = sub(phase, 1); + L_temp = L_mult0(temp, L_SUBFR + 1); + temp = extract_l(L_temp); + temp = add(temp, off_yup); + + /* ptr_y_up = y_up + (phase-1) * (L_SUBFR+1) + off_yup */ + ptr_y_up = y_up + temp; + } + ELSE + { + /* select long filter */ + num_gltp = num2_gltp; + move16(); + den_gltp = den2_gltp; + move16(); + sh_num = sh_num2; + move16(); + sh_den = sh_den2; + move16(); + ptr_y_up = ptr_sig_pst0; + } + + /* rescale y_up */ + FOR (i = 0; i < L_SUBFR; i++) + { + /* nb_sh_sig may be >0, <0 or =0 */ + ptr_y_up[i] = shl(ptr_y_up[i], nb_sh_sig); + move16(); + } + } + + temp = sub(sh_num, sh_den); + IF (temp >= 0) + { + den_gltp = shr(den_gltp, temp); + } + ELSE + { + num_gltp = shl(num_gltp, temp); /* >> (-temp) */ + } + IF (GE_16(num_gltp, den_gltp)) + { + /* beta bounded to 1 */ + gain_plt = MIN_GPLT_FX; + move16(); + } + ELSE + { + /* GAMMA_G = 0.5 */ + /* gain_plt = den_gltp x 2**15 / (den_gltp + 0.5 num_gltp) */ + /* shift 1 bit to avoid overflows in add */ + num_gltp = shr(num_gltp, 2); + den_gltp = shr(den_gltp, 1); + temp = add(den_gltp, num_gltp); + gain_plt = div_s(den_gltp, temp); /* Q15 */ + } + + /* decrease gain in noisy condition */ + /* gain_plt += (1.0f-gain_plt) * gain_factor */ + /* gain_plt = gain_plt + gain_factor - gain_plt*gain_factor */ +#ifdef BASOP_NOGLOB + gain_plt = msu_ro(L_msu(L_deposit_h(gain_plt), gain_plt, gain_factor), -32768, gain_factor, &Overflow); +#else + gain_plt = msu_r(L_msu(L_deposit_h(gain_plt), gain_plt, gain_factor), -32768, gain_factor); +#endif + + /** filtering by H0(z) = harmonic filter **/ + filt_plt(ptr_sig_in, ptr_y_up, ptr_sig_pst0, gain_plt); + } + +} + +/*---------------------------------------------------------------------------- + * search_del: + * + * Computes best (shortest) integer LTP delay + fine search + *---------------------------------------------------------------------------*/ +static void search_del( + Word16 t0, /* i : pitch delay given by coder */ + Word16 * ptr_sig_in, /* i : i signal (with delay line) */ + Word16 * ltpdel, /* o : delay = *ltpdel - *phase / f_up */ + Word16 * phase, /* o : phase */ + Word16 * num_gltp, /* o : 16 bits numerator of LTP gain */ + Word16 * den_gltp, /* o : 16 bits denominator of LTP gain */ + Word16 * sh_num_gltp, /* o : justification for num_gltp */ + Word16 * sh_den_gltp, /* o : justification for den_gltp */ + Word16 * y_up, /* o : LT delayed signal if fract. delay */ + Word16 * off_yup /* o : offset in y_up */ +) +{ + Word32 L_den0[F_UP_PST - 1]; + Word32 L_den1[F_UP_PST - 1]; + + Word32 *ptr_L_den0, *ptr_L_den1; + + Word32 L_num_int, L_den_int, L_den_max; + Word32 L_temp0, L_temp1; + Word32 L_acc; + Word32 L_temp; + + const Word16 *ptr_h; + Word16 *ptr_sig_past, *ptr_sig_past0; + Word16 *ptr1, *ptr_y_up; + + Word16 i, n; + Word16 num, den0, den1; + Word16 den_max, num_max; + Word32 L_numsq_max; + Word16 ener; + Word16 sh_num, sh_den, sh_ener; + Word16 i_max, lambda, phi, phi_max, ioff; + Word16 temp; + + + /*------------------------------------- + * Computes energy of current signal + *-------------------------------------*/ + + L_acc = L_mult(ptr_sig_in[0], ptr_sig_in[0]); + FOR(i = 1; i < L_SUBFR; i++) + { +#ifdef BASOP_NOGLOB + L_acc = L_mac_sat(L_acc, ptr_sig_in[i], ptr_sig_in[i]); +#else + L_acc = L_mac(L_acc, ptr_sig_in[i], ptr_sig_in[i]); +#endif + } + IF (L_acc == 0) + { + *num_gltp = 0; + move16(); + *den_gltp = 1; + move16(); + *ltpdel = 0; + move16(); + *phase = 0; + move16(); + + return; + } + sh_ener = sub(16, norm_l(L_acc)); + /* save energy for final decision */ + sh_ener = s_max(0, sh_ener); + ener = extract_l(L_shr(L_acc, sh_ener)); + + /*------------------------------------- + * Selects best of 3 integer delays + * Maximum of 3 numerators around t0 + *-------------------------------------*/ + lambda = sub(t0, 1); + ptr_sig_past = ptr_sig_in - lambda; + L_num_int = L_deposit_l(-1); + + /* initialization used only to suppress Microsoft Visual C++ warnings */ + i_max = (Word16) 0; + move16(); + + FOR (i = 0; i < 3; i++) + { + L_acc = L_mult(ptr_sig_in[0], ptr_sig_past[0]); + FOR (n = 1; n < L_SUBFR; n++) + { +#ifdef BASOP_NOGLOB + L_acc = L_mac_sat(L_acc, ptr_sig_in[n], ptr_sig_past[n]); +#else + L_acc = L_mac(L_acc, ptr_sig_in[n], ptr_sig_past[n]); +#endif + } + + + L_acc = L_max(L_acc, 0); +#ifdef BASOP_NOGLOB + L_temp = L_sub_sat(L_acc, L_num_int); +#else + L_temp = L_sub(L_acc, L_num_int); +#endif + if (L_temp > 0L) + { + i_max = (Word16) i; + move16(); + } + L_num_int = L_max(L_num_int, L_acc); + ptr_sig_past--; + } + + IF (L_num_int == 0) + { + *num_gltp = 0; + move16(); + *den_gltp = 1; + move16(); + *ltpdel = 0; + move16(); + *phase = 0; + move16(); + + return; + } + + /* Compute den for i_max */ + lambda = add(lambda, (Word16) i_max); + ptr_sig_past = ptr_sig_in - lambda; + temp = *ptr_sig_past++; + move16(); + L_acc = L_mult(temp, temp); + FOR (i = 1; i < L_SUBFR; i++) + { + temp = *ptr_sig_past++; + move16(); +#ifdef BASOP_NOGLOB + L_acc = L_mac_sat(L_acc, temp, temp); +#else + L_acc = L_mac(L_acc, temp, temp); +#endif + } + IF (L_acc == 0L) + { + *num_gltp = 0; + move16(); + *den_gltp = 1; + move16(); + *ltpdel = 0; + move16(); + *phase = 0; + move16(); + + return; + } + L_den_int = L_acc; /* sets to 'L_acc' in 1 clock */ + move32(); + + /*---------------------------------- + * Select best phase around lambda + *---------------------------------- + * Compute y_up & denominators + *----------------------------------*/ + + ptr_y_up = y_up; + L_den_max = L_den_int; /* sets to 'L_acc' in 1 clock */ + move32(); + ptr_L_den0 = L_den0; + ptr_L_den1 = L_den1; + ptr_h = Tab_hup_s; + temp = sub(lambda, LH_UP_S - 1); + ptr_sig_past0 = ptr_sig_in - temp; + + /* Loop on phase */ + FOR (phi = 1; phi < F_UP_PST; phi++) + { + /* Compute y_up for lambda+1 - phi/F_UP_PST */ + /* and lambda - phi/F_UP_PST */ + + ptr_sig_past = ptr_sig_past0; + FOR (n = 0; n <= L_SUBFR; n++) + { + ptr1 = ptr_sig_past++; + + L_acc = L_mult(ptr_h[0], ptr1[0]); + FOR (i = 1; i < LH2_S; i++) + { + L_acc = L_mac(L_acc, ptr_h[i], ptr1[-i]); + } + ptr_y_up[n] = round_fx(L_acc); + } + + /* compute den0 (lambda+1) and den1 (lambda) */ + + /* part common to den0 and den1 */ + L_acc = L_mult(ptr_y_up[1], ptr_y_up[1]); + FOR (n = 2; n < L_SUBFR; n++) + { +#ifdef BASOP_NOGLOB + L_acc = L_mac_sat(L_acc, ptr_y_up[n], ptr_y_up[n]); +#else + L_acc = L_mac(L_acc, ptr_y_up[n], ptr_y_up[n]); +#endif + } + L_temp0 = L_acc; /* sets to 'L_acc' in 1 clock (saved for den1) */ + move32(); + + /* den0 */ +#ifdef BASOP_NOGLOB + L_acc = L_mac_sat(L_acc, ptr_y_up[0], ptr_y_up[0]); +#else + L_acc = L_mac(L_acc, ptr_y_up[0], ptr_y_up[0]); +#endif + *ptr_L_den0 = L_acc; + move32(); + + /* den1 */ +#ifdef BASOP_NOGLOB + L_acc = L_mac_sat(L_temp0, ptr_y_up[L_SUBFR], ptr_y_up[L_SUBFR]); +#else + L_acc = L_mac(L_temp0, ptr_y_up[L_SUBFR], ptr_y_up[L_SUBFR]); +#endif + *ptr_L_den1 = L_acc; + move32(); + + IF (GT_16(abs_s(ptr_y_up[0]), abs_s(ptr_y_up[L_SUBFR]))) + { + L_den_max = L_max(*ptr_L_den0, L_den_max); + } + ELSE + { + L_den_max = L_max(*ptr_L_den1, L_den_max); + } + ptr_L_den0++; + ptr_L_den1++; + ptr_y_up += (L_SUBFR+1); + ptr_h += LH2_S; + } + + IF (L_den_max == 0) + { + *num_gltp = 0; + move16(); + *den_gltp = 1; + move16(); + *ltpdel = 0; + move16(); + *phase = 0; + move16(); + + return; + } + + sh_den = sub(16, norm_l(L_den_max)); + /* if sh_den <= 0 : dynamic between current frame */ + /* and delay line too high */ + IF (sh_den <= 0) + { + *num_gltp = 0; + move16(); + *den_gltp = 1; + move16(); + *ltpdel = 0; + move16(); + *phase = 0; + move16(); + + return; + } + + /* search sh_num to justify correlations */ + /* sh_num = Max(sh_den, sh_ener) */ + sh_num = sh_ener; + move16(); + if (GE_16(sh_den, sh_ener)) + { + sh_num = sh_den; + move16(); + } + + /* Computation of the numerators */ + /* and selection of best num*num/den */ + /* for non null phases */ + + /* Initialize with null phase */ + L_acc = L_shr(L_den_int, sh_den); /* sh_den > 0 */ + den_max = extract_l(L_acc); + L_acc = L_shr(L_num_int, sh_num); /* sh_num > 0 */ + num_max = extract_l(L_acc); + L_numsq_max = L_mult(num_max, num_max); + + phi_max = 0; + move16(); + ioff = 1; + move16(); + + ptr_L_den0 = L_den0; + ptr_L_den1 = L_den1; + ptr_y_up = y_up; + + + /* if den_max = 0 : will be selected and declared unvoiced */ + /* if num!=0 & den=0 : will be selected and declared unvoiced */ + /* degenerated seldom cases, switch off LT is OK */ + + /* Loop on phase */ + FOR (phi = 1; phi < F_UP_PST; phi++) + { + /* compute num for lambda+1 - phi/F_UP_PST */ + L_acc = L_mult(ptr_sig_in[0], ptr_y_up[0]); + FOR (n = 1; n < L_SUBFR; n++) + { +#ifdef BASOP_NOGLOB + L_acc = L_mac_sat(L_acc, ptr_sig_in[n], ptr_y_up[n]); +#else + L_acc = L_mac(L_acc, ptr_sig_in[n], ptr_y_up[n]); +#endif + } + L_acc = L_shr(L_acc, sh_num); /* sh_num > 0 */ + L_acc = L_max(0, L_acc); + num = extract_l(L_acc); + + /* selection if num**2/den0 max */ + L_temp1 = L_mult(num, num); + L_temp0 = Mpy_32_16_1(L_temp1, den_max); + L_acc = L_add(*ptr_L_den0++, 0); + L_acc = L_shr(L_acc, sh_den); /* sh_den > 0 */ + den0 = extract_l(L_acc); + L_temp = Msub_32_16(L_temp0, L_numsq_max, den0); + IF (L_temp > 0L) + { + num_max = num; + move16(); + L_numsq_max = L_temp1; /* sets to 'L_temp1' in 1 clock */ + move32(); + den_max = den0; + move16(); + ioff = 0; + move16(); + phi_max = phi; + move16(); + } + + /* compute num for lambda - phi/F_UP_PST */ + ptr_y_up++; + + L_acc = L_mult(ptr_sig_in[0], ptr_y_up[0]); + FOR (n = 1; n < L_SUBFR; n++) + { +#ifdef BASOP_NOGLOB + L_acc = L_mac_sat(L_acc, ptr_sig_in[n], ptr_y_up[n]); +#else + L_acc = L_mac(L_acc, ptr_sig_in[n], ptr_y_up[n]); +#endif + } + L_acc = L_shr(L_acc, sh_num); /* sh_num > 0 */ + L_acc = L_max(0, L_acc); + num = extract_l(L_acc); + + /* selection if num**2/den1 max */ + L_temp1 = L_mult(num, num); + L_temp0 = Mpy_32_16_1(L_temp1, den_max); + L_acc = L_add(*ptr_L_den1++, 0); + L_acc = L_shr(L_acc, sh_den); /* sh_den > 0 */ + den1 = extract_l(L_acc); + L_temp = Msub_32_16(L_temp0, L_numsq_max, den1); + IF (L_temp > 0L) + { + num_max = num; + move16(); + L_numsq_max = L_temp1; /* sets to 'L_temp1' in 1 clock */ + move32(); + den_max = den1; + move16(); + ioff = 1; + move16(); + phi_max = phi; + move16(); + } + + ptr_y_up += L_SUBFR; + } + + /*--------------------------------------------------- + * test if normalized crit0[iopt] > THRESHCRIT + *--------------------------------------------------*/ + test(); + IF (num_max == 0 || LE_16(den_max, 1)) + { + *num_gltp = 0; + move16(); + *den_gltp = 1; + move16(); + *ltpdel = 0; + move16(); + *phase = 0; + move16(); + + return; + } + + /* compare num**2 */ + /* to ener * den * 0.5 */ + /* (THRESHCRIT = 0.5) */ + L_temp1 = L_mult(den_max, ener); + + /* temp = 2 * sh_num - sh_den - sh_ener + 1 */ + /* 16 bits with no overflows */ + temp = shl(sh_num, 1); + temp = sub(temp, sh_den); + temp = sub(temp, sh_ener); + temp = add(temp, 1); + IF (temp < 0) + { + temp = negate(temp); /* no overflow */ + L_numsq_max = L_shr(L_numsq_max, temp); + } + ELSE + { + if (temp > 0) + { + L_temp1 = L_shr(L_temp1, temp); + } + } + L_temp = L_sub(L_numsq_max, L_temp1); + IF (L_temp >= 0L) + { + temp = add(lambda, 1); + *ltpdel = sub(temp, ioff); + *off_yup = ioff; + move16(); + *phase = phi_max; + move16(); + *num_gltp = num_max; + move16(); + *den_gltp = den_max; + move16(); + *sh_den_gltp = sh_den; + move16(); + *sh_num_gltp = sh_num; + move16(); + } + ELSE + { + *num_gltp = 0; + move16(); + *den_gltp = 1; + move16(); + *ltpdel = 0; + move16(); + *phase = 0; + move16(); + } + + + return; +} + +/*---------------------------------------------------------------------------- + * filt_plt: + * + * Perform long term postfilter + *----------------------------------------------------------------------------*/ +static void filt_plt( + Word16 * s_in, /* i : i signal with past */ + Word16 * s_ltp, /* i : filtered signal with gain 1 */ + Word16 * s_out, /* o : signal */ + Word16 gain_plt /* i : filter gain */ +) +{ + + /* Local variables */ + Word32 L_acc; + + Word16 n; + Word16 gain_plt_1; + + + gain_plt_1 = sub(32767, gain_plt); + gain_plt_1 = add(gain_plt_1, 1); /* 2**15 (1 - g) */ + + FOR (n = 0; n < L_SUBFR; n++) + { + /* s_out(n) = gain_plt x s_in(n) + gain_plt_1 x s_ltp(n) */ + L_acc = L_mult(gain_plt, s_in[n]); + s_out[n] = mac_r(L_acc, gain_plt_1, s_ltp[n]); + move16(); /* no overflow */ + } + + + return; +} + + +/*---------------------------------------------------------------------------- + * compute_ltp_l : + * + * compute delayed signal, num & den of gain for fractional delay + * with long interpolation filter + *----------------------------------------------------------------------------*/ +static void compute_ltp_l( + Word16 * s_in, /* i/o: signal with past */ + Word16 ltpdel, /* i : delay factor */ + Word16 phase, /* i : phase factor */ + Word16 * y_up, /* i : delayed signal */ + Word16 * num, /* i : numerator of LTP gain */ + Word16 * den, /* i : denominator of LTP gain */ + Word16 * sh_num, /* i : justification factor of num */ + Word16 * sh_den /* i : justification factor of den */ +) +{ + Word32 L_acc; + Word16 *ptr2; + const Word16 *ptr_h; + Word16 n, i; + Word16 temp; + + temp = sub(phase, 1); + temp = shl(temp, L2_LH2_L); + ptr_h = Tab_hup_l + temp; /* Tab_hup_l + LH2_L * (phase-1) */ + + temp = sub(LH_UP_L, ltpdel); + ptr2 = s_in + temp; + + /* Compute y_up */ + FOR (n = 0; n < L_SUBFR; n++) + { + L_acc = L_mult(ptr_h[0], *ptr2--); + + FOR (i = 1; i < LH2_L; i++) + { + L_acc = L_mac(L_acc, ptr_h[i], *ptr2--); + } + y_up[n] = round_fx(L_acc); + ptr2 += LH2_L_P1; + } + + /* Compute num */ + L_acc = L_mult(y_up[0], s_in[0]); + FOR (n = 1; n < L_SUBFR; n++) + { + L_acc = L_mac(L_acc, y_up[n], s_in[n]); + } + IF (L_acc < 0L) + { + *num = 0; + move16(); + *sh_num = 0; + move16(); + } + ELSE + { + temp = sub(16, norm_l(L_acc)); + temp = s_max(temp, 0); + L_acc = L_shr(L_acc, temp); /* with temp >= 0 */ + *num = extract_l(L_acc); + *sh_num = temp; + move16(); + } + + /* Compute den */ + L_acc = L_mult(y_up[0], y_up[0]); + FOR (n = 1; n < L_SUBFR; n++) + { + L_acc = L_mac(L_acc, y_up[n], y_up[n]); + } + temp = sub(16, norm_l(L_acc)); + temp = s_max(temp, 0); + L_acc = L_shr(L_acc, temp); /* with temp >= 0 */ + *den = extract_l(L_acc); + *sh_den = temp; + move16(); + + + return; +} + +/*---------------------------------------------------------------------------- + * select_ltp: + * + * selects best of (gain1, gain2) + * with gain1 = num1 * 2** sh_num1 / den1 * 2** sh_den1 + * and gain2 = num2 * 2** sh_num2 / den2 * 2** sh_den2 + *----------------------------------------------------------------------------*/ +static Word16 select_ltp( /* o : 1 = 1st gain, 2 = 2nd gain */ + Word16 num1, /* i : numerator of gain1 */ + Word16 den1, /* i : denominator of gain1 */ + Word16 sh_num1, /* i : just. factor for num1 */ + Word16 sh_den1, /* i : just. factor for den1 */ + Word16 num2, /* i : numerator of gain2 */ + Word16 den2, /* i : denominator of gain2 */ + Word16 sh_num2, /* i : just. factor for num2 */ + Word16 sh_den2 /* i : just. factor for den2 */ +) +{ + Word32 L_temp1, L_temp2; + Word32 L_temp; + + Word16 temp1, temp2; + + + IF (den2 == 0) + { + return 1; + } + + /* compares criteria = num**2/den */ + L_temp1 = L_mult(num1, num1); + L_temp1 = Mpy_32_16_1(L_temp1, den2); + + L_temp2 = L_mult(num2, num2); + L_temp2 = Mpy_32_16_1(L_temp2, den1); + + /* temp1 = sh_den2 + 2 * sh_num1 */ + temp1 = shl(sh_num1, 1); + temp1 = add(temp1, sh_den2); + /* temp2 = sh_den1 + 2 * sh_num2; */ + temp2 = shl(sh_num2, 1); + temp2 = add(temp2, sh_den1); + + temp2 = sub(temp2, temp1); + if (temp2 > 0) + { + L_temp1 = L_shr(L_temp1, temp2); /* temp2 > 0 */ + } + if (temp2 < 0) + { + L_temp2 = L_shl(L_temp2, temp2); /* temp2 < 0 */ + } + + L_temp = L_sub(L_temp2, L_temp1); + temp1 = 1; + move16(); + if (L_temp > 0L) + { + temp1 = 2; + move16(); + } + + return temp1; +} + +/*---------------------------------------------------------------------------- + * calc_st_filt + * + * computes impulse response of A(gamma2) / A(gamma1) + * controls gain : computation of energy impulse response as + * SUMn (abs (h[n])) and computes parcor0 + *---------------------------------------------------------------------------- */ +static void calc_st_filt( + Word16 * apond2, /* i : coefficients of numerator */ + Word16 * apond1, /* i : coefficients of denominator */ + Word16 * parcor0, /* o : 1st parcor calcul. on composed filter */ + Word16 * sig_ltp_ptr, /* i/o: i of 1/A(gamma1) : scaled by 1/g0 */ + Word16 * mem_zero /* i : All zero memory */ +) +{ + Word32 L_g0; + + Word16 h[LONG_H_ST]; + + Word16 g0, temp; + Word16 i; + + + temp = sub( 2, norm_s( apond2[0] ) ); + + /* compute i.r. of composed filter apond2 / apond1 */ + E_UTIL_synthesis(temp, apond1, apond2, h, LONG_H_ST, mem_zero, 0, M); + + /* compute 1st parcor */ + Calc_rc0_h(h, parcor0); + + /* compute g0 */ + L_g0 = L_mult0(1, abs_s(h[0])); + FOR (i = 1; i < LONG_H_ST; i++) + { + L_g0 = L_mac0(L_g0, 1, abs_s(h[i])); + } + g0 = extract_h(L_shl(L_g0, 14)); + + /* Scale signal i of 1/A(gamma1) */ + IF (GT_16(g0, 1024)) + { + temp = div_s(1024, g0); /* temp = 2**15 / gain0 */ + FOR (i = 0; i < L_SUBFR; i++) + { + sig_ltp_ptr[i] = mult_r(sig_ltp_ptr[i], temp); + move16(); + } + } + + + return; +} + +/*---------------------------------------------------------------------------- + * filt_mu + * + * tilt filtering with : (1 + mu z-1) * (1/1-|mu|) + * computes y[n] = (1/1-|mu|) (x[n]+mu*x[n-1]) + *---------------------------------------------------------------------------*/ +void Filt_mu( + Word16 * sig_in, /* i : signal (beginning at sample -1) */ + Word16 * sig_out, /* o : signal with tilt */ + Word16 parcor0, /* i : parcor0 (mu = parcor0 * gamma3) */ + Word16 L_subfr /* i : the length of subframe */ +) +{ + Word32 L_acc, L_temp, L_fact; + + Word16 *ptrs; + + Word16 n; + Word16 mu, mu2, ga, temp; + Word16 fact, sh_fact; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + + + IF (parcor0 > 0) + { + mu = mult_r(parcor0, GAMMA3_PLUS_FX); + /* GAMMA3_PLUS_FX < 0.5 */ + sh_fact = 14; + move16(); /* sh_fact */ + fact = (Word16) 0x4000; + move16(); /* 2**sh_fact */ + L_fact = (Word32) L_deposit_l(0x2000); /* fact >> 1 */ + } + ELSE + { + mu = mult_r(parcor0, GAMMA3_MINUS_FX); + /* GAMMA3_MINUS_FX < 0.9375 */ + sh_fact = 11; + move16(); /* sh_fact */ + fact = (Word16) 0x0800; + move16(); /* 2**sh_fact */ + L_fact = (Word32) L_deposit_l(0x0400); /* fact >> 1 */ + } + + temp = sub(1, abs_s(mu)); + BASOP_SATURATE_WARNING_OFF_EVS; +#ifdef BASOP_NOGLOB + mu2 = add_o(32767, temp, &Overflow); /* 2**15 (1 - |mu|) */ +#else + mu2 = add(32767, temp); /* 2**15 (1 - |mu|) */ +#endif + BASOP_SATURATE_WARNING_ON_EVS; + ga = div_s(fact, mu2); /* 2**sh_fact / (1 - |mu|) */ + + ptrs = sig_in; /* points on sig_in(-1) */ + + sh_fact = sub(sh_fact,16); /* to remove the saturate(), should shl by 16 before rounding */ + + FOR (n = 0; n < L_subfr; n++) + { + L_acc = L_mult0(mu, *ptrs++); + L_temp = L_mac(L_acc, 16384, *ptrs); /* sig_in(n) * 2**15 */ + + L_temp = Madd_32_16(L_fact, L_temp, ga); + L_temp = L_shr(L_temp, sh_fact); /* mult. temp x ga */ + + BASOP_SATURATE_WARNING_OFF_EVS; + /*sig_out[n] = saturate(L_temp); move16();*/ + sig_out[n] = round_fx(L_temp); + BASOP_SATURATE_WARNING_ON_EVS; + } + + + return; +} + + +/*---------------------------------------------------------------------------- + * scale_st() + * + * control of the subframe gain + * gain[n] = AGC_FAC_FX * gain[n-1] + (1 - AGC_FAC_FX) g_in/g_out + *---------------------------------------------------------------------------*/ +void scale_st( + const Word16 * sig_in, /* i : postfilter i signal */ + Word16 * sig_out, /* i/o: postfilter o signal */ + Word16 * gain_prec, /* i/o: last value of gain for subframe */ + Word16 L_subfr +) +{ + Word32 L_acc, L_temp; + + Word16 i; + Word16 scal_in, scal_out; + Word16 s_g_in, s_g_out, temp, sh_g0, g0; + Word16 gain = 0; + + + /* compute i gain */ + L_acc = L_deposit_l(0); + FOR (i = 0; i < L_subfr; i++) + { + if(sig_in[i] > 0) + { + L_acc = L_mac0(L_acc, 1, sig_in[i]); + } + if(sig_in[i] < 0) + { + L_acc = L_msu0(L_acc, 1, sig_in[i]); + } + } + + g0 = 0; + move16(); + IF (L_acc != 0L) + { + scal_in = norm_l(L_acc); + L_acc = L_shl(L_acc, scal_in); + s_g_in = extract_h(L_acc); /* normalized */ + + /* Compute o gain */ + { + Word64 acc64 = 0; + FOR (i = 0; i < L_subfr; i++) + { + acc64 = W_mac0_16_16(acc64, 1, abs_s(sig_out[i])); + } + L_acc = W_sat_l(acc64); + } + IF (L_acc == 0L) + { + *gain_prec = 0; + move16(); + + return; + } + scal_out = norm_l(L_acc); + L_acc = L_shl(L_acc, scal_out); + s_g_out = extract_h(L_acc); /* normalized */ + + sh_g0 = add(scal_in, 1); + sh_g0 = sub(sh_g0, scal_out); /* scal_in - scal_out + 1 */ + IF (LT_16(s_g_in, s_g_out)) + { + g0 = div_s(s_g_in, s_g_out); /* s_g_in/s_g_out in Q15 */ + } + ELSE + { + temp = sub(s_g_in, s_g_out); /* sufficient since normalized */ + g0 = shr(div_s(temp, s_g_out), 1); + g0 = add(g0, (Word16) 0x4000); /* s_g_in/s_g_out in Q14 */ + sh_g0 = sub(sh_g0, 1); + } + /* L_gain_in/L_gain_out in Q14 */ + /* overflows if L_gain_in > 2 * L_gain_out */ +#ifdef BASOP_NOGLOB + g0 = shr_sat(g0, sh_g0); /* sh_g0 may be >0, <0, or =0 */ +#else + g0 = shr(g0, sh_g0); /* sh_g0 may be >0, <0, or =0 */ +#endif + g0 = mult_r(g0, AGC_FAC1_FX); /* L_gain_in/L_gain_out * AGC_FAC1_FX */ + } + + /* gain(n) = AGC_FAC gain(n-1) + AGC_FAC1 gain_in/gain_out */ + /* sig_out(n) = gain(n) sig_out(n) */ + gain = *gain_prec; + move16(); + FOR (i = 0; i < L_subfr; i++) + { + temp = mult_r(AGC_FAC_FX, gain); + gain = add(temp, g0); /* in Q14 */ + L_temp = L_mult(gain, sig_out[i]); +#ifdef BASOP_NOGLOB + L_temp = L_shl_sat(L_temp, 1); + sig_out[i] = round_fx_sat(L_temp); +#else + L_temp = L_shl(L_temp, 1); + sig_out[i] = round_fx(L_temp); +#endif + } + *gain_prec = gain; + move16(); + + + return; +} + +/*---------------------------------------------------------------------------- + * blend_subfr2() + * + * + *---------------------------------------------------------------------------*/ + +void blend_subfr2( + Word16 *sigIn1, + Word16 *sigIn2, + Word16 *sigOut +) +{ + Word16 fac1 = 32768 - 512; + Word16 fac2 = 0 + 512; + Word16 step = 1024; + Word16 i; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + FOR( i=0; i +#include +#include "options.h" /* Compilation switches */ +#include "prot_fx1.h" /* Function prototypes */ +#include "prot_fx2.h" /* Function prototypes */ + +/*===================================================================*/ +/* FUNCTION : void decod_ppp_fx () */ +/*-------------------------------------------------------------------*/ +/* PURPOSE : decode highly voiced frames using PPP */ +/*-------------------------------------------------------------------*/ +/* INPUT ARGUMENTS : */ +/* _ const Word16 Aq_fx[] - Q12 12k8 Lp coefficient */ +/* _ Word16 bfi_fx - Q0 bad frame indicator */ +/*-------------------------------------------------------------------*/ +/* OUTPUT ARGUMENTS : */ +/* _ Decoder_State_fx *st_fx: */ +/* _ lastLgainD_fx - Q11 */ +/* _ lastHgainD_fx - Q11 */ +/* _ lasterbD_fx - Q13 */ +/*-------------------------------------------------------------------*/ +/* INPUT/OUTPUT ARGUMENTS : */ +/* _ Decoder_State_fx *st_fx: */ +/* _ lsp_old_fx - Q15 */ +/* _ st_fx->dtfs_dec_xxxx */ +/* _ a nd b in st_fx->dtfs_dec_Q */ +/* rest all in Q0 */ +/* _ gainp_ppp Q14 */ +/* _ FadeScale_fx - Q15 */ +/* _ tilt_code_fx - Q15 */ +/* _ prev_tilt_code_dec_fx - Q15 */ +/* _ prev_gain_pit_dec_fx - Q14 */ +/* _ dm_fx.prev_state - Q0 */ +/* _ dm_fx.prev_gain_code - Q16 */ +/* _ .dm_fx.prev_gain_pit - Q14 */ +/* _ prev_gain_pit_dec - Q14 */ +/* _ Word16 *pitch_buf_fx - Q6 fixed pitch values for each subframe */ +/* _ Word16 *exc_fx - Q_exc current non-enhanced excitation */ +/* _ Word16 *exc2_fx - Q_exc current enhanced excitation */ +/*-------------------------------------------------------------------*/ +/* RETURN ARGUMENTS : */ +/* _ None */ +/*-------------------------------------------------------------------*/ +/* CALLED FROM : RX */ +/*===================================================================*/ +ivas_error decod_ppp_fx( + Decoder_State *st_fx, /* i/o: state structure */ + const Word16 Aq_fx[], /* i : 12k8 Lp coefficient */ + Word16 *pitch_buf_fx, /* i/o: fixed pitch values for each subframe */ + Word16 *exc_fx, /* i/o: current non-enhanced excitation */ + Word16 *exc2_fx, /* i/o: current enhanced excitation */ + Word16 bfi, /* i : bad frame indicator */ + Word16 *gain_buf, + Word16 *voice_factors, /* o : voicing factors */ + Word16 *bwe_exc_fx /* o : excitation for SWB TBE */ +) +{ + Word16 k; + + Word16 LPC_de_curr_fx[M+1], p_Aq_curr_fx[M], p_Aq_old_fx[M+1]; + Word16 excQ_ppp_fx[L_FRAME], pitch_fx[NB_SUBFR], LPC_de_old_fx[M+1]; + ivas_error error; + + error = IVAS_ERR_OK; + + /* call voiced decoder at this point */ + FOR( k=0; ktilt_code_fx = st_fx->tilt_code_dec_fx[3]; + move16(); + + Copy(excQ_ppp_fx, exc_fx, L_FRAME); + Copy(exc_fx, exc2_fx, L_FRAME); + + st_fx->dm_fx.prev_state = 2; + move16(); + + st_fx->dm_fx.prev_gain_pit[0] = st_fx->prev_gain_pit_dec_fx; + move16();/*Q14 */ + + FOR(k=3; k<7; k++) + { + st_fx->dm_fx.prev_gain_pit[k-2] = st_fx->dm_fx.prev_gain_pit[k-3]; + move16();/*Q14 */ + } + + Copy(pitch_fx, pitch_buf_fx, NB_SUBFR);/*Q6 */ + + IF(st_fx->hBWE_TD != NULL) + { + interp_code_5over2_fx(exc2_fx, bwe_exc_fx, L_FRAME); + } + set16_fx( voice_factors, 0, NB_SUBFR16k ); + + + + set16_fx(gain_buf,0,NB_SUBFR16k); + return error; +} diff --git a/lib_dec/dec_prm.c b/lib_dec/dec_prm.c index 508db037581f346c72eb970d52639616b6f8114f..83f180d2d54bfc78098f629c07d2927d7aa9a282 100644 --- a/lib_dec/dec_prm.c +++ b/lib_dec/dec_prm.c @@ -44,12 +44,12 @@ /*-------------------------------------------------------------------* - * getTCXMode() + * getTCXMode_ivas() * * get TCX mode *--------------------------------------------------------------------*/ -void getTCXMode( +void getTCXMode_ivas( Decoder_State *st, /* i/o: decoder memory state */ Decoder_State *st0, /* i : bitstream */ const int16_t MCT_flag /* i : hMCT handle allocated (1) or not (0) */ @@ -113,7 +113,7 @@ void getTCXMode( if ( get_next_indice_1( st0 ) ) /* TCX */ { ind = get_next_indice( st0, 3 ); - assert( !( ind & 4 ) || !"HQ_CORE encountered in dec_prm" ); + assert( !( ind & 4 ) || !"HQ_CORE encountered in dec_prm_ivas" ); st->core = TCX_20_CORE; st->hTcxCfg->coder_type = ind; st->coder_type = st->hTcxCfg->coder_type; @@ -196,12 +196,12 @@ void getTCXMode( /*-------------------------------------------------------------------* - * getTCXWindowing() + * getTCXWindowing_ivas() * * get TCX transform type for each subframe *--------------------------------------------------------------------*/ -void getTCXWindowing( +void getTCXWindowing_ivas( const int16_t core, /* i : current core */ const int16_t last_core, /* i : last frame core */ const int16_t element_mode, /* i : element mode */ @@ -268,12 +268,12 @@ void getTCXWindowing( /*-------------------------------------------------------------------* - * getLPCparam() + * getLPCparam_ivas() * * get LPC parameters *--------------------------------------------------------------------*/ -void getLPCparam( +void getLPCparam_ivas( Decoder_State *st, /* i/o: decoder memory state */ int16_t param_lpc[], /* o : LTP parameters */ Decoder_State *st0, /* i : bitstream */ @@ -298,13 +298,13 @@ void getLPCparam( { int16_t tcx_lpc_cdk; tcx_lpc_cdk = tcxlpc_get_cdk_float( st->coder_type ); - dec_lsf_tcxlpc( st0, ¶m_lpc, st->narrowBand, tcx_lpc_cdk ); + dec_lsf_tcxlpc_ivas( st0, ¶m_lpc, st->narrowBand, tcx_lpc_cdk ); } else { if ( st->lpcQuantization == 0 ) { - decode_lpc_avq( st0, st->numlpc, param_lpc, ch, st->element_mode, sns_low_br_mode ); + decode_lpc_avq_flt( st0, st->numlpc, param_lpc, ch, st->element_mode, sns_low_br_mode ); } else if ( st->lpcQuantization == 1 ) { @@ -312,11 +312,11 @@ void getLPCparam( { assert( st->element_mode == EVS_MONO ); - lsf_bctcvq_decprm( st0, param_lpc ); + lsf_bctcvq_decprm_ivas( st0, param_lpc ); } else { - lsf_msvq_ma_decprm( st0, param_lpc ); + lsf_msvq_ma_decprm_ivas( st0, param_lpc ); } } else @@ -348,12 +348,12 @@ void getLPCparam( } /*-------------------------------------------------------------------* - * getTCXparam() + * getTCXparam_ivas() * * get TCX core parameters *-------------------------------------------------------------------*/ -void getTCXparam( +void getTCXparam_ivas( Decoder_State *st, /* i/o: Decoder State handle */ Decoder_State *st0, /* i : bitstream */ CONTEXT_HM_CONFIG hm_cfg, /* i/o: HM config */ @@ -417,11 +417,11 @@ void getTCXparam( { ix = st->next_bit_pos; - IGFDecReadLevel( st->hIGFDec, st0, IGF_GRID_LB_SHORT, 1 - k ); + IGFDecReadLevel_flt( st->hIGFDec, st0, IGF_GRID_LB_SHORT, 1 - k ); - IGFDecReadData( st->hIGFDec, st0, IGF_GRID_LB_SHORT, 1 - k ); + IGFDecReadData_flt( st->hIGFDec, st0, IGF_GRID_LB_SHORT, 1 - k ); - IGFDecStoreTCX10SubFrameData( st->hIGFDec, k ); + IGFDecStoreTCX10SubFrameData_flt( st->hIGFDec, k ); nbits_igf += st0->next_bit_pos - ix; } @@ -471,7 +471,7 @@ void getTCXparam( tcxltp_prm_1 = prm[j + 1]; tcxltp_prm_2 = prm[j + 2]; } - st->BER_detect = st->BER_detect | tcx_ltp_decode_params( &prm[j], &( hTcxLtpDec->tcxltp_pitch_int ), &( hTcxLtpDec->tcxltp_pitch_fr ), &( hTcxLtpDec->tcxltp_gain_float ), st->pit_min, st->pit_fr1, st->pit_fr2, st->pit_max, st->pit_res_max ); + st->BER_detect = st->BER_detect | tcx_ltp_decode_params_flt( &prm[j], &( hTcxLtpDec->tcxltp_pitch_int ), &( hTcxLtpDec->tcxltp_pitch_fr ), &( hTcxLtpDec->tcxltp_gain_float ), st->pit_min, st->pit_fr1, st->pit_fr2, st->pit_max, st->pit_res_max ); hTcxDec->tcxltp_last_gain_unmodified_float = hTcxLtpDec->tcxltp_gain_float; @@ -523,7 +523,7 @@ void getTCXparam( last_core = TCX_20_CORE; } - SetTnsConfig( st->hTcxCfg, core == TCX_20_CORE, ( st->last_core_from_bs == ACELP_CORE ) && ( k == 0 ) ); + SetTnsConfig_flt( st->hTcxCfg, core == TCX_20_CORE, ( st->last_core_from_bs == ACELP_CORE ) && ( k == 0 ) ); ix = 0; if ( no_param_tns ) { @@ -536,7 +536,7 @@ void getTCXparam( } else { - ReadTnsData( st->hTcxCfg->pCurrentTnsConfig, st0, &nTnsBits, prm + j, &nTnsParams ); + ReadTnsData_ivas( st->hTcxCfg->pCurrentTnsConfig, st0, &nTnsBits, prm + j, &nTnsParams ); } hTcxDec->tnsActive[k] = ( prm[j] != 0 ? 1 : 0 ) * nTnsParams; if ( nTnsBitsTCX10 != NULL ) @@ -555,7 +555,7 @@ void getTCXparam( if ( hTcxDec->tcx_lpc_shaped_ari && st->last_core_from_bs != ACELP_CORE ) { - dec_prm_hm( st0, &prm[j], hm_size ); + dec_prm_hm_ivas( st0, &prm[j], hm_size ); } nbits_tcx = st->bits_frame_core - ( st0->next_bit_pos - start_bit_pos ); @@ -582,7 +582,7 @@ void getTCXparam( PeriodicityIndex = *( prm + j + 1 ); if ( st->element_mode == EVS_MONO ) { - ConfigureContextHm( lgFB, nbits_tcx, PeriodicityIndex, hTcxDec->tcx_hm_LtpPitchLag, &hm_cfg ); + ConfigureContextHm_ivas( lgFB, nbits_tcx, PeriodicityIndex, hTcxDec->tcx_hm_LtpPitchLag, &hm_cfg ); } nbits_tcx -= ix; } @@ -596,9 +596,9 @@ void getTCXparam( if ( st->igf ) { ix = st->next_bit_pos; - IGFDecReadLevel( st->hIGFDec, st0, ( st->last_core_from_bs == ACELP_CORE ) ? IGF_GRID_LB_TRAN : IGF_GRID_LB_NORM, 1 ); + IGFDecReadLevel_flt( st->hIGFDec, st0, ( st->last_core_from_bs == ACELP_CORE ) ? IGF_GRID_LB_TRAN : IGF_GRID_LB_NORM, 1 ); - IGFDecReadData( st->hIGFDec, st0, ( st->last_core_from_bs == ACELP_CORE ) ? IGF_GRID_LB_TRAN : IGF_GRID_LB_NORM, 1 ); + IGFDecReadData_flt( st->hIGFDec, st0, ( st->last_core_from_bs == ACELP_CORE ) ? IGF_GRID_LB_TRAN : IGF_GRID_LB_NORM, 1 ); nbits_tcx -= ( st0->next_bit_pos - ix ); } @@ -642,13 +642,13 @@ void getTCXparam( { if ( useHarmonicModel ) { - ConfigureContextHm( lgFB, nbits_tcx, PeriodicityIndex, hTcxDec->tcx_hm_LtpPitchLag, &hm_cfg ); + ConfigureContextHm_ivas( lgFB, nbits_tcx, PeriodicityIndex, hTcxDec->tcx_hm_LtpPitchLag, &hm_cfg ); } hTcxDec->resQBits[k] = RCcontextMapping_decode2_no_mem_s17_LCS( st0, prm + j, lgFB, nbits_tcx, NPRM_RESQ * st->hTcxCfg->resq, flag_ctx_hm ? &hm_cfg : NULL ); } else { - hTcxDec->resQBits[k] = ACcontextMapping_decode2_no_mem_s17_LC( st0, prm + j, lgFB, nbits_tcx, NPRM_RESQ * st->hTcxCfg->resq, flag_ctx_hm ? &hm_cfg : NULL ); + hTcxDec->resQBits[k] = ACcontextMapping_decode2_no_mem_s17_LC_ivas( st0, prm + j, lgFB, nbits_tcx, NPRM_RESQ * st->hTcxCfg->resq, flag_ctx_hm ? &hm_cfg : NULL ); } } } @@ -659,12 +659,12 @@ void getTCXparam( /*-----------------------------------------------------------------* - * dec_prm_hm() + * dec_prm_hm_ivas() * * *-----------------------------------------------------------------*/ -void dec_prm_hm( +void dec_prm_hm_ivas( Decoder_State *st, int16_t *prm_hm, const int16_t hm_size ) @@ -700,7 +700,7 @@ void dec_prm_hm( /*-----------------------------------------------------------------* - * Function dec_prm() * + * Function dec_prm_ivas() * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * * SQ is used for TCX modes @@ -708,7 +708,7 @@ void dec_prm_hm( * decode parameters according to selected mode * *-----------------------------------------------------------------*/ -void dec_prm( +void dec_prm_ivas( Decoder_State *st, /* i/o: decoder memory state */ int16_t param[], /* o : decoded parameters */ int16_t param_lpc[], /* o : LPC parameters */ @@ -783,7 +783,7 @@ void dec_prm( *--------------------------------------------------------------------------------*/ /* Modes (ACE_GC, ACE_UC, TCX20, TCX10...) */ - getTCXMode( st, st, 0 /* <- MCT_flag */ ); + getTCXMode_ivas( st, st, 0 /* <- MCT_flag */ ); core = st->core; /* Decode last_core for error concealment */ @@ -822,7 +822,7 @@ void dec_prm( if ( !st->use_partial_copy ) { - getTCXWindowing( st->core, st->last_core, st->element_mode, st->hTcxCfg, st ); + getTCXWindowing_ivas( st->core, st->last_core, st->element_mode, st->hTcxCfg, st ); if ( st->enableGplc ) /* SIDE INFO. DECODING */ { @@ -875,7 +875,7 @@ void dec_prm( ( &( st->acelp_cfg ) )->midLpc = st->acelp_cfg.midLpc_enable; } - getLPCparam( st, param_lpc, st, -1, 0 ); + getLPCparam_ivas( st, param_lpc, st, -1, 0 ); bits_common = st->next_bit_pos - start_bit_pos; @@ -893,7 +893,7 @@ void dec_prm( acelp_target_bits = st->bits_frame_core - bits_common; /* Configure ACELP */ - tmp = BITS_ALLOC_config_acelp( acelp_target_bits, st->coder_type, &( st->acelp_cfg ), st->narrowBand, st->nb_subfr ); + tmp = BITS_ALLOC_config_acelp_IVAS( acelp_target_bits, st->coder_type, &( st->acelp_cfg ), st->narrowBand, st->nb_subfr ); if ( tmp < 0 ) { /* erroneous configuration, resulting from a corrupt bitstream */ @@ -972,7 +972,7 @@ void dec_prm( } else if ( st->rf_frame_type >= RF_ALLPRED && st->use_partial_copy ) { - int16_t tmp = BITS_ALLOC_config_acelp( st->rf_target_bits, /* target bits ranges from 56 to 72 depending on rf_type */ + int16_t tmp = BITS_ALLOC_config_acelp_IVAS( st->rf_target_bits, /* target bits ranges from 56 to 72 depending on rf_type */ st->rf_frame_type, /* already offset by 4 to parse the config elements for partial copy */ &( st->acelp_cfg ), /* acelp_cfg_rf*/ 0, /* is narrowBand */ @@ -1043,7 +1043,7 @@ void dec_prm( if ( ( core == TCX_20_CORE || core == TCX_10_CORE ) && st->use_partial_copy == 0 ) { - getTCXparam( st, st, hm_cfg, param, bits_common, start_bit_pos, NULL, NULL, NULL, -1 ); + getTCXparam_ivas( st, st, hm_cfg, param, bits_common, start_bit_pos, NULL, NULL, NULL, -1 ); } if ( st->rf_frame_type >= RF_TCXFD && st->rf_frame_type <= RF_TCXTD2 && st->use_partial_copy == 1 ) @@ -1090,7 +1090,7 @@ void dec_prm( if ( !st->prev_bfi ) { st->BER_detect = st->BER_detect | - tcx_ltp_decode_params( &prm_ltp[0], &( hTcxLtpDec->tcxltp_pitch_int ), &( hTcxLtpDec->tcxltp_pitch_fr ), &( hTcxLtpDec->tcxltp_gain_float ), st->pit_min, st->pit_fr1, st->pit_fr2, st->pit_max, st->pit_res_max ); + tcx_ltp_decode_params_flt( &prm_ltp[0], &( hTcxLtpDec->tcxltp_pitch_int ), &( hTcxLtpDec->tcxltp_pitch_fr ), &( hTcxLtpDec->tcxltp_gain_float ), st->pit_min, st->pit_fr1, st->pit_fr2, st->pit_max, st->pit_res_max ); hTcxDec->tcxltp_last_gain_unmodified_float = hTcxLtpDec->tcxltp_gain_float; } diff --git a/lib_dec/dec_prm_fx.c b/lib_dec/dec_prm_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..a8c37abf165380da112eab917cb549c11eb94feb --- /dev/null +++ b/lib_dec/dec_prm_fx.c @@ -0,0 +1,1189 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + + + +#include +#include +#include +#include +#include "rom_com.h" +#include "stl.h" +#include "prot_fx1.h" +#include "prot_fx2.h" +#include "basop_util.h" + +static void dec_prm_hm( + Decoder_State *st, + Word16 *prm_hm, + Word16 L_frame +) +{ + Word16 tmp; + + /* Disable HM for non-GC,VC modes */ + test(); + IF (NE_16(st->hTcxCfg->coder_type, VOICED)&&NE_16(st->hTcxCfg->coder_type,GENERIC)) + { + prm_hm[0] = 0; + move16(); + + return; + } + + prm_hm[1] = -1; + move16(); + prm_hm[2] = 0; + move16(); + + /* Flag */ + prm_hm[0] = get_next_indice(st, 1); + move16(); + + IF (prm_hm[0] != 0) + { + tmp = 0; + move16(); + if (GE_16(L_frame, 256)) + { + tmp = 1; + move16(); + } + /* Periodicity index */ + DecodeIndex_fx(st, tmp, &prm_hm[1]); + + /* Gain index */ + IF (EQ_16(st->hTcxCfg->coder_type, VOICED)) + { + prm_hm[2] = get_next_indice(st, kTcxHmNumGainBits); + move16(); + } + } +} + +/*-----------------------------------------------------------------* + * Funtion dec_prm() * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * + * + * SQ is used for TCX modes + * + * decode parameters according to selected mode * + *-----------------------------------------------------------------*/ +void dec_prm( + Word16 *coder_type, + Word16 param[], /* (o) : decoded parameters */ + Word16 param_lpc[], /* (o) : LPC parameters */ + Word16 *total_nbbits, /* i/o : number of bits / decoded bits */ + Decoder_State *st, + Word16 L_frame, + Word16 *bitsRead +) +{ + Word16 j, k, n, sfr, *prm; + Word16 lg; + Word16 lgFB; + Word16 start_bit_pos; + Word16 acelp_target_bits=-1; + Word16 tmp; + Word16 nTnsParams; + Word16 nTnsBits; + Word16 nb_subfr; + Word16 nbits_tcx; + Word16 ix, j_old, wordcnt, bitcnt; + Word16 hm_size; + Word16 *prms; + CONTEXT_HM_CONFIG hm_cfg; + CONTEXT_HM_CONFIG * phm_cfg; + Word16 indexBuffer[N_MAX+1]; + Word8 flag_ctx_hm; + Word32 L_tmp; + Word16 num_bits; + UWord16 lsb; + Word16 ltp_mode, gains_mode; + Word16 ind; + Word16 prm_ltp[LTPSIZE]; + TCX_LTP_DEC_HANDLE hTcxLtpDec; + TCX_DEC_HANDLE hTcxDec; + + hTcxLtpDec = st->hTcxLtpDec; + hTcxDec = st->hTcxDec; + + /*--------------------------------------------------------------------------------* + * INIT + *--------------------------------------------------------------------------------*/ + + hm_cfg.indexBuffer = indexBuffer; + move16(); + + IF (EQ_16(st->mdct_sw, MODE1)) + { + start_bit_pos = 0; /* count from frame start */ move16(); + + /* Adjust st->bits_frame_core not to subtract MODE2 bandwidth signaling */ + FOR (n=0; ntotal_brate, 5243, &L_tmp, &lsb); /* 5243 is 1/50 in Q18. (0+18-15=3) */ + num_bits = extract_l(L_shr(L_tmp, 3)); /* Q0 */ + assert(num_bits == st->total_brate/50); + IF (EQ_16(FrameSizeConfig[n].frame_bits, num_bits)) + { + st->bits_frame_core = add(st->bits_frame_core, FrameSizeConfig[n].bandwidth_bits); + BREAK; + } + } + } + ELSE + { + IF( EQ_16(st->rf_flag,1)) + { + /*Inherent adjustment to accommodate the compact packing used in the RF mode*/ + start_bit_pos = sub(st->next_bit_pos,2); + } + ELSE + { + start_bit_pos = st->next_bit_pos; + } + } + + /* Framing parameters */ + nb_subfr = st->nb_subfr; + move16(); + + /* Initialize pointers */ + prm = param; + + /* Init counters */ + j = 0; + move16(); + + /* Init LTP data */ + hTcxDec->tcx_hm_LtpPitchLag = -1; + move16(); + hTcxLtpDec->tcxltp_gain = 0; + move16(); + + /*--------------------------------------------------------------------------------* + * HEADER + *--------------------------------------------------------------------------------*/ + + /* Modes (ACE_GC, ACE_UC, TCX20, TCX10...) */ + IF ( st->tcxonly ) + { + st->core = add(get_next_indice(st, 1), 1); + move16(); + ind = get_next_indice(st, 2); + st->clas_dec = ONSET; + move16(); + IF( ind == 0 ) + { + st->clas_dec = UNVOICED_CLAS; + move16(); + } + ELSE IF( EQ_16(ind, 1)) + { + st->clas_dec = UNVOICED_TRANSITION; + move16(); + if( GE_16(st->last_good_fx, VOICED_TRANSITION)) + { + st->clas_dec = VOICED_TRANSITION; + move16(); + } + } + ELSE if( EQ_16(ind, 2)) + { + st->clas_dec = VOICED_CLAS; + move16(); + } + *coder_type = INACTIVE; + st->VAD = 0; + move16(); + } + ELSE + { + IF (EQ_16(st->mdct_sw, MODE1)) + { + /* 2 bits instead of 3 as TCX is already signaled */ + st->core = TCX_20_CORE; + move16(); + st->hTcxCfg->coder_type = get_next_indice(st, 2); + move16(); + *coder_type = st->hTcxCfg->coder_type; + move16(); + } + ELSE + { + IF (EQ_16(st->mdct_sw_enable, MODE2)) + { + IF (get_next_indice_1(st) != 0) /* TCX */ + { + tmp = get_next_indice(st, 3); + assert(!(tmp & 4) || !"HQ_CORE encountered in dec_prm"); + st->core = TCX_20_CORE; + move16(); + st->hTcxCfg->coder_type = tmp; + move16(); + *coder_type = st->hTcxCfg->coder_type; + move16(); + } + ELSE /* ACELP */ + { + st->core = ACELP_CORE; + move16(); + *coder_type = get_next_indice(st, 2); + move16(); + } + } + ELSE + { + IF(EQ_16(st->rf_flag,1)) + { + IF( !( st->use_partial_copy ) ) + { + tmp = get_next_indice(st, 1); + IF(tmp == 0) + { + st->core = ACELP_CORE; + move16(); + } + ELSE + { + st->core = TCX_20_CORE; + move16(); + st->hTcxCfg->coder_type = *coder_type; + move16(); + } + } + } + ELSE + { + st->core = ACELP_CORE; + move16(); + *coder_type = get_next_indice(st, 3); + move16(); + IF ( GE_16(*coder_type, ACELP_MODE_MAX)) + { + st->core = TCX_20_CORE; + move16(); + *coder_type=sub(*coder_type,ACELP_MODE_MAX); + st->hTcxCfg->coder_type = *coder_type; + move16(); + } + } + } + } + + test(); + IF ( st->igf != 0 && EQ_16(st->core, ACELP_CORE) ) + { + st->bits_frame_core = sub( st->bits_frame_core, get_tbe_bits_fx(st->total_brate, st->bwidth, st->rf_flag) ); + } + + IF( EQ_16(st->rf_flag,1)) + { + st->bits_frame_core = sub(st->bits_frame_core, add(st->rf_target_bits, 1)); /* +1 as flag-bit not considered in rf_target_bits */ + } + + /* Inactive frame detection on non-DTX mode */ + st->VAD = 1; + move16(); + if( EQ_16(*coder_type, INACTIVE)) + { + st->VAD = 0; + move16(); + } + } + + /*Core extended mode mapping for correct PLC classification*/ + st->core_ext_mode = *coder_type; + move16(); + + if( EQ_16(*coder_type, INACTIVE)) + { + st->core_ext_mode = UNVOICED; + move16(); + } + + /* Decode previous mode for error concealment */ + tmp = 0; + move16(); + test(); + test(); + IF( ( NE_16(st->core, ACELP_CORE) || st->hTcxCfg->lfacNext > 0 ) && st->use_partial_copy == 0 ) + { + st->last_core_bs_fx = get_next_indice(st, 1); + move16(); + + /* + need to introduce special error handling for lost transition frames from CNG: + in such cases, the bitstream reader continues with CNG, setting bfi = 0, total_brate = 0 + this might result in a not matching last_core transmitted in the BS - we should use this + only for interpreting the bitstream and re-use the internal state for the proper + transition handling; still, for voiced onsets rather stick to wrong windowing... + */ + if( (!((st->last_total_brate == 0) && (sub(st->clas_dec, VOICED_CLAS) != 0))) && (sub(st->last_core_bs_fx, st->last_core) != 0) ) + { + st->last_core = st->last_core_bs_fx; + } + /*for TCX 10 force last_core to be TCX since ACELP as previous core is forbidden*/ + IF( EQ_16(st->core, TCX_10_CORE)) + { + st->last_core = TCX_20_CORE; + st->last_core_bs_fx = TCX_20_CORE; + move16(); + move16(); + } + } + + test(); + test(); + IF(EQ_16(st->rf_flag,1)&&EQ_16(st->use_partial_copy,1)&&!st->tcxonly) + { + st->bits_frame_core = st->rf_target_bits; + + /* offset the indices to read the acelp partial copy */ + Mpy_32_16_ss(st->total_brate, 5243, &L_tmp, &lsb); /* 5243 is 1/50 in Q18. (0+18-15=3) */ + num_bits = extract_l(L_shr(L_tmp, 3)); /* Q0 */ + + get_next_indice_tmp_fx(st, start_bit_pos + num_bits - st->rf_target_bits - 3 - st->next_bit_pos); + } + + IF( st->use_partial_copy == 0 ) + { + /* Set the last overlap mode based on the previous and current frame type and coded overlap mode */ + test(); + IF ((EQ_16(st->last_core, ACELP_CORE))||(EQ_16(st->last_core,AMR_WB_CORE))) + { + st->hTcxCfg->tcx_last_overlap_mode = TRANSITION_OVERLAP; + move16(); + } + ELSE + { + test(); + IF ((EQ_16(st->core, TCX_10_CORE))&&(EQ_16(st->hTcxCfg->tcx_curr_overlap_mode,ALDO_WINDOW))) + { + st->hTcxCfg->tcx_last_overlap_mode = FULL_OVERLAP; + move16(); + } + ELSE + { + st->hTcxCfg->tcx_last_overlap_mode = st->hTcxCfg->tcx_curr_overlap_mode; + move16(); + test(); + if ((NE_16(st->core, TCX_10_CORE))&&(EQ_16(st->hTcxCfg->tcx_curr_overlap_mode,FULL_OVERLAP))) + { + st->hTcxCfg->tcx_last_overlap_mode = ALDO_WINDOW; + move16(); + } + } + } + /* Set the current overlap mode based on the current frame type and coded overlap mode */ + st->hTcxCfg->tcx_curr_overlap_mode = ALDO_WINDOW; + move16(); + + IF (NE_16(st->core, ACELP_CORE)) + { + tmp = 0; + move16(); + /* if current TCX mode is not 0 (full overlap), read another bit */ + IF (get_next_indice(st, 1)) + { + tmp = add(2, get_next_indice(st, 1)); + } + st->hTcxCfg->tcx_curr_overlap_mode = tmp; + move16(); + + /* TCX10 : always symmetric windows */ + test(); + test(); + test(); + if ((EQ_16(st->core, TCX_20_CORE))&&(tmp==0)&&(NE_16(st->last_core,ACELP_CORE))&&(NE_16(st->last_core,AMR_WB_CORE))) + { + st->hTcxCfg->tcx_curr_overlap_mode = ALDO_WINDOW; + move16(); + } + } + + /* SIDE INFO. DECODING */ + IF(st->enableGplc) + { + Word16 pitchDiff; + Word16 bits_per_subfr, search_range; + bits_per_subfr = 4; + move16(); + search_range = 8; + move16(); + + st->flagGuidedAcelp = get_next_indice(st, 1); + move16(); + + pitchDiff = 0; + move16(); + IF(st->flagGuidedAcelp) + { + pitchDiff = get_next_indice(st, bits_per_subfr); + move16(); + st->guidedT0 = sub(pitchDiff, search_range); + move16(); + } + test(); + if( (pitchDiff == 0) && st->flagGuidedAcelp) + { + st->flagGuidedAcelp = 0; + move16(); + } + } + ELSE + { + st->flagGuidedAcelp = 0; + move16(); + } + + IF( st->dec_glr ) + { + move16(); + st->dec_glr_idx = -1; + IF( EQ_16(st->core, ACELP_CORE) ) + { + st->dec_glr_idx = get_next_indice(st, G_LPC_RECOVERY_BITS); + } + } + } + /*--------------------------------------------------------------------------------* + * LPC PARAMETERS + *--------------------------------------------------------------------------------*/ + + /*Initialization of LPC Mid flag*/ + st->acelp_cfg.midLpc = st->acelp_cfg.midLpc_enable; + move16(); + test(); + test(); + IF( (EQ_16(st->lpcQuantization, 1)&&(EQ_16(*coder_type,VOICED)))||(st->use_partial_copy)) + { + st->acelp_cfg.midLpc = 0; + move16(); + } + + IF( st->use_partial_copy == 0 ) + { + /* Number of sets of LPC parameters (does not include mid-lpc) */ + st->numlpc = 2; + move16(); + test(); + if ( st->tcxonly==0 || LT_16(st->core, TCX_10_CORE)) + { + st->numlpc = 1; + move16(); + } + + /* Decode LPC parameters */ + test(); + IF (hTcxDec->enableTcxLpc && NE_16(st->core, ACELP_CORE)) + { + Word16 tcx_lpc_cdk; + tcx_lpc_cdk = tcxlpc_get_cdk(*coder_type); + dec_lsf_tcxlpc(st, ¶m_lpc, st->narrowBand, tcx_lpc_cdk); + } + ELSE + { + IF (st->lpcQuantization==0) + { + decode_lpc_avq( st, st->numlpc, param_lpc +#ifdef IVAS_CODE_AVQ_LPC + , , , +#endif + ); + move16(); + } + ELSE IF (EQ_16(st->lpcQuantization, 1)) + { + test(); + test(); + IF(EQ_32(st->sr_core, 16000)&&EQ_16(*coder_type,VOICED)&&EQ_16(st->core,ACELP_CORE)) + { + lsf_bctcvq_decprm(st, param_lpc); + } + ELSE + { + lsf_msvq_ma_decprm( st, param_lpc); + } + + } + ELSE + { + assert(0 && "LPC quant not supported!"); + } + } + } + ELSE + { + st->numlpc = 1; + move16(); + + test(); + IF( EQ_16(st->rf_frame_type, RF_TCXFD)) + { + param_lpc[0] = 0; + move16(); + param_lpc[1] = get_next_indice(st, lsf_numbits[0]); /* VQ 1 */ + param_lpc[2] = get_next_indice(st, lsf_numbits[1]); /* VQ 2 */ + param_lpc[3] = get_next_indice(st, lsf_numbits[2]); /* VQ 3 */ + } + ELSE IF( GE_16(st->rf_frame_type, RF_ALLPRED)&&LE_16(st->rf_frame_type,RF_NELP)) + { + /* LSF indices */ + param_lpc[0] = get_next_indice(st, 8); /* VQ 1 */ + param_lpc[1] = get_next_indice(st, 8); /* VQ 2 */ + } + } + + st->bits_common = sub(st->next_bit_pos, start_bit_pos); + move16(); + + + /*--------------------------------------------------------------------------------* + * ACELP + *--------------------------------------------------------------------------------*/ + test(); + test(); + IF( EQ_16(st->core,ACELP_CORE)&&st->use_partial_copy==0) + { + /* Target Bits */ + acelp_target_bits = sub(st->bits_frame_core, st->bits_common); + + { + Word16 acelp_bits; + move16(); + acelp_bits = BITS_ALLOC_config_acelp( acelp_target_bits, *coder_type, &(st->acelp_cfg), st->narrowBand, st->nb_subfr ); + + if ( acelp_bits < 0 ) + { + st->BER_detect = 1; + move16(); + } + } + + /* Adaptive BPF (2 bits)*/ + n=ACELP_BPF_BITS[st->acelp_cfg.bpf_mode]; + move16(); + + st->bpf_gain_param = shl(st->acelp_cfg.bpf_mode, 1); + IF( n != 0) + { + st->bpf_gain_param = get_next_indice(st, n); + move16(); + } + + /* Mean energy (2 or 3 bits) */ + n = ACELP_NRG_BITS[st->acelp_cfg.nrg_mode]; + move16(); + IF( n != 0 ) + { + prm[j++] = get_next_indice(st, n); + move16(); + } + + /* Subframe parameters */ + FOR (sfr=0; sfracelp_cfg.ltp_mode][sfr]; + move16(); + + IF(n!=0) + { + prm[j++] = get_next_indice(st, n); + move16(); + } + + /* Adaptive codebook filtering (1 bit) */ + IF ( EQ_16(st->acelp_cfg.ltf_mode, 2)) + { + prm[j++] = get_next_indice(st, 1); + move16(); + } + + /* Innovative codebook */ + { + /* Decode pulse positions. */ + j_old = j; + move16(); + wordcnt = shr(ACELP_FIXED_CDK_BITS(st->acelp_cfg.fixed_cdk_index[sfr]), 4); + bitcnt = s_and(ACELP_FIXED_CDK_BITS(st->acelp_cfg.fixed_cdk_index[sfr]), 0xF); + + /* sanity check for testing - not instrumented */ + test(); + if ( GE_16(st->acelp_cfg.fixed_cdk_index[sfr], ACELP_FIXED_CDK_NB)||(st->acelp_cfg.fixed_cdk_index[sfr]<0)) + { + st->acelp_cfg.fixed_cdk_index[sfr] = 0; + move16(); + st->BER_detect = 1; + move16(); + } + + FOR (ix = 0; ix < wordcnt; ix++) + { + prm[j++] = get_next_indice(st, 16); + move16(); + } + IF (bitcnt) + { + prm[j] = get_next_indice(st, bitcnt); + move16(); + } + + j = add(j_old, 8); + + } + + /* Gains (5b, 6b or 7b / subfr) */ + n = ACELP_GAINS_BITS[st->acelp_cfg.gains_mode[sfr]]; + move16(); + + prm[j++] = get_next_indice(st, n); + move16(); + }/*end of subfr loop*/ + } + + ELSE IF( GE_16(st->rf_frame_type,RF_ALLPRED)&&st->use_partial_copy) + { + Word16 acelp_bits = + BITS_ALLOC_config_acelp( st->rf_target_bits, /* target bits ranges from 56 to 72 depending on rf_type */ + st->rf_frame_type, /* already offset by 4 to parse the config elements for partial copy */ + &(st->acelp_cfg), /* acelp_cfg_rf*/ + 0, /* is narrowBand */ + st->nb_subfr ); + + if ( acelp_bits < 0 ) + { + st->BER_detect = 1; + move16(); + } + + /* rf_frame_type NELP: 7 */ + IF(EQ_16(st->rf_frame_type,RF_NELP)) + { + /* NELP gain indices */ + st->rf_indx_nelp_iG1 = get_next_indice( st, 5 ); + st->rf_indx_nelp_iG2[0] = get_next_indice( st, 6 ); + st->rf_indx_nelp_iG2[1] = get_next_indice( st, 6 ); + + /* NELP filter selection index */ + st->rf_indx_nelp_fid = get_next_indice( st, 2 ); + + /* tbe gainFr */ + st->rf_indx_tbeGainFr = get_next_indice( st, 5 ); + } + ELSE + { + /* rf_frame_type ALL_PRED: 4, NO_PRED: 5, GEN_PRED: 6*/ + /* ES pred */ + prm[j++] = get_next_indice(st, 3); + + ltp_mode = ACELP_LTP_MODE[1][1][st->rf_frame_type]; + gains_mode = ACELP_GAINS_MODE[1][1][st->rf_frame_type]; + + /* Subframe parameters */ + FOR( sfr = 0; sfr < nb_subfr; sfr++ ) + { + /* Pitch lag (5, or 8 bits) */ + n = ACELP_LTP_BITS_SFR[ltp_mode][sfr]; + IF (n != 0) + { + prm[j++] = get_next_indice(st, n); + } + + /*Innovative codebook*/ + test(); + test(); + test(); + IF( EQ_16(st->rf_frame_type,RF_NOPRED) + || ( EQ_16(st->rf_frame_type,RF_GENPRED) && (sfr == 0 || EQ_16(sfr,2) )) ) + { + /* NOTE: FCB actual bits need to be backed up as well */ + /*n = ACELP_FIXED_CDK_BITS(st->rf_indx_fcb[fec_offset][sfr]) & 15;*/ + prm[j] = get_next_indice(st, 7); + j = add(j,8); + } + + /* Gains (5b, 6b or 7b / subfr) */ + test(); + IF( sfr == 0 || EQ_16(sfr,2)) + { + n = ACELP_GAINS_BITS[gains_mode]; + prm[j++] = get_next_indice(st, n); + } + } + + st->rf_indx_tbeGainFr = get_next_indice( st, 2 ); + } + } + + /*--------------------------------------------------------------------------------* + * TCX20 + *--------------------------------------------------------------------------------*/ + test(); + IF( EQ_16(st->core, TCX_20_CORE)&&st->use_partial_copy==0) + { + flag_ctx_hm = 0; + move16(); + + IF (st->enablePlcWaveadjust) + { + st->tonality_flag = get_next_indice(st, 1); + move16(); + } + + /* TCX Gain = 7 bits */ + prm[j++] = get_next_indice(st, 7); + move16(); + + /* TCX Noise Filling = NBITS_NOISE_FILL_LEVEL bits */ + prm[j++] = get_next_indice(st, NBITS_NOISE_FILL_LEVEL); + move16(); + + /* LTP data */ + /* PLC pitch info for HB */ + test(); + IF (hTcxLtpDec->tcxltp != 0 || GT_32(st->sr_core, 25600)) + { + + prm[j] = get_next_indice(st, 1); + move16(); + + IF ( prm[j] ) + { + prm[j+1] = get_next_indice(st, 9); + move16(); + prm[j+2] = get_next_indice(st, 2); + move16(); + } + + st->BER_detect = st->BER_detect | + tcx_ltp_decode_params(&prm[j], + &(hTcxLtpDec->tcxltp_pitch_int), + &(hTcxLtpDec->tcxltp_pitch_fr), + &(hTcxLtpDec->tcxltp_gain), + st->pit_min, + st->pit_fr1, + st->pit_fr2, + st->pit_max, + st->pit_res_max); + + hTcxDec->tcx_hm_LtpPitchLag = -1; + move16(); + hTcxDec->tcxltp_last_gain_unmodified = hTcxLtpDec->tcxltp_gain; + move16(); + + test(); + IF ((st->tcxonly == 0) && (LT_16(hTcxLtpDec->tcxltp_pitch_int, L_frame))) + { + Word32 tmp32 = L_shl(L_mult0(st->L_frame, st->pit_res_max), 1+kLtpHmFractionalResolution+1); + Word16 tmp1 = add(imult1616(hTcxLtpDec->tcxltp_pitch_int, st->pit_res_max), hTcxLtpDec->tcxltp_pitch_fr); + hTcxDec->tcx_hm_LtpPitchLag = div_l(tmp32, tmp1); + } + } + + j = add(j, 3); + + /* TCX spectral data */ + lg = L_frame; + move16(); + lgFB = st->hTcxCfg->tcx_coded_lines; + move16(); + + IF (st->last_core_bs_fx == ACELP_CORE ) + { + /* ACE->TCX transition */ + lg = add(lg, st->hTcxCfg->tcx_offset); + if (st->hTcxCfg->lfacNext < 0) + { + lg = sub(lg, st->hTcxCfg->lfacNext); + } + + lgFB = add(lgFB, shr(lgFB, 2)); + } + + /* TNS data */ + nTnsParams = 0; + move16(); + nTnsBits = 0; + move16(); + + IF (st->hTcxCfg->fIsTNSAllowed) + { + SetTnsConfig(st->hTcxCfg, 1, st->last_core_bs_fx == ACELP_CORE); + ReadTnsData(st->hTcxCfg->pCurrentTnsConfig, st, &nTnsBits, prm+j, &nTnsParams); + + j = add(j, nTnsParams); + } + hm_size = shl(mult(st->TcxBandwidth, lg), 1); + + test(); + IF (hTcxDec->tcx_lpc_shaped_ari != 0 && NE_16(st->last_core_bs_fx, ACELP_CORE)) + { + dec_prm_hm(st, &prm[j], hm_size); + } + + nbits_tcx = sub(st->bits_frame_core, sub(st->next_bit_pos, start_bit_pos)); + if (st->enableGplc != 0) + { + nbits_tcx = sub(nbits_tcx, 7); + } + + /*Context HM flag*/ + test(); + IF ( st->hTcxCfg->ctx_hm && NE_16(st->last_core_bs_fx, ACELP_CORE)) + { + prm[j] = get_next_indice(st, 1); + move16(); + nbits_tcx = sub(nbits_tcx, 1); + + IF (prm[j]) + { + Word16 NumIndexBits; + + tmp = 0; + move16(); + if(GE_16(hm_size, 256)) + { + tmp = 1; + move16(); + } + NumIndexBits = DecodeIndex_fx(st, + tmp, + prm + j + 1); + + flag_ctx_hm = 1; + move16(); + + ConfigureContextHm( + lgFB, + nbits_tcx, + *(prm+j+1), + hTcxDec->tcx_hm_LtpPitchLag, + &hm_cfg); + + nbits_tcx = sub(nbits_tcx, NumIndexBits); + } + } + j = add(j, NPRM_CTX_HM); + + /* read IGF payload */ + IF (st->igf) + { + + n = st->next_bit_pos; + move16(); + IF (EQ_16(st->last_core_bs_fx, ACELP_CORE)) + { + IGFDecReadLevel( st->hIGFDec, st, IGF_GRID_LB_TRAN, 1 ); + IGFDecReadData( st->hIGFDec, st, IGF_GRID_LB_TRAN, 1 ); + } + ELSE + { + IGFDecReadLevel( st->hIGFDec, st, IGF_GRID_LB_NORM, 1 ); + IGFDecReadData( st->hIGFDec, st, IGF_GRID_LB_NORM, 1 ); + } + + nbits_tcx = sub(nbits_tcx, sub(st->next_bit_pos, n)); + + } + nbits_tcx = sub(st->bits_frame_core, sub(st->next_bit_pos, start_bit_pos)); + IF (hTcxDec->tcx_lpc_shaped_ari != 0) + { + prm[j++] = nbits_tcx; /* store length of buffer */ move16(); + prms = &prm[j]; + FOR (ix = 0; ix < nbits_tcx; ix++) + { + prms[ix] = get_next_indice_1(st); + move16(); + } + set16_fx(prms+nbits_tcx, 1, 32); + j = add(j, nbits_tcx); + } + ELSE + { + phm_cfg = NULL; + move16(); + if (flag_ctx_hm) + { + phm_cfg = &hm_cfg; + move16(); + } + hTcxDec->resQBits[0] = ACcontextMapping_decode2_no_mem_s17_LC(st, prm+j, lgFB, nbits_tcx,NPRM_RESQ*st->hTcxCfg->resq,phm_cfg); + move16(); + j = add(j, lg); + } + } + + test(); + test(); + IF( GE_16(st->rf_frame_type,RF_TCXFD)&&LE_16(st->rf_frame_type,RF_TCXTD2)&&EQ_16(st->use_partial_copy,1)) + { + /* classification */ + ind = get_next_indice(st, 2); + st->clas_dec = ONSET; + move16(); + + IF( ind == 0 ) + { + st->clas_dec = UNVOICED_CLAS; + move16(); + } + ELSE IF( EQ_16(ind, 1)) + { + IF( GE_16(st->last_good_fx, VOICED_TRANSITION)) + { + st->clas_dec = VOICED_TRANSITION; + move16(); + } + ELSE + { + st->clas_dec = UNVOICED_TRANSITION; + move16(); + } + } + ELSE IF( EQ_16(ind, 2)) + { + st->clas_dec = VOICED_CLAS; + move16(); + } + + IF( EQ_16(st->rf_frame_type, RF_TCXFD)) + { + /* TCX Gain = 7 bits */ + hTcxDec->old_gaintcx_bfi = get_next_indice(st, 7); + } + ELSE + { + /* LTP data */ + IF(hTcxLtpDec->tcxltp != 0 ) + { + IF( EQ_16(st->rf_frame_type, RF_TCXTD2)||EQ_16(st->rf_frame_type,RF_TCXTD1)) + { + prm_ltp[0] = 1; + move16(); /* LTP active*/ + prm_ltp[1] = get_next_indice(st, 9); + prm_ltp[2] = 3; + move16(); /* max ampl. quantizer output (2bits), anyway not used later*/ + + IF( st->prev_bfi == 0 ) + { + st->BER_detect = st->BER_detect | + tcx_ltp_decode_params(&prm_ltp[0], &(hTcxLtpDec->tcxltp_pitch_int), &(hTcxLtpDec->tcxltp_pitch_fr), &(hTcxLtpDec->tcxltp_gain), + st->pit_min, st->pit_fr1, st->pit_fr2, st->pit_max, st->pit_res_max ); + + hTcxDec->tcxltp_last_gain_unmodified = hTcxLtpDec->tcxltp_gain; + move16(); + } + } + } + } + } + + + /*--------------------------------------------------------------------------------* + * TCX10 + *--------------------------------------------------------------------------------*/ + IF ( EQ_16(st->core, TCX_10_CORE)) + { + Word16 tcxltp_prm_0 = 0; + Word16 tcxltp_prm_1 = 0; + Word16 tcxltp_prm_2 = 0; + Word16 nbits_igf = 0; + move16(); + move16(); + move16(); + move16(); + move16(); + /* read IGF payload */ + IF (st->igf) + { + + n = st->next_bit_pos; + move16(); + + IGFDecReadLevel( st->hIGFDec, st, IGF_GRID_LB_SHORT, 1); + IGFDecReadData( st->hIGFDec, st, IGF_GRID_LB_SHORT, 1); + IGFDecStoreTCX10SubFrameData( st->hIGFDec, 0 ); + + IGFDecReadLevel( st->hIGFDec, st, IGF_GRID_LB_SHORT, 0); + IGFDecReadData( st->hIGFDec, st, IGF_GRID_LB_SHORT, 0); + IGFDecStoreTCX10SubFrameData( st->hIGFDec, 1 ); + nbits_igf = sub(st->next_bit_pos, n); + + } + FOR (k = 0; k < 2; k++) + { + flag_ctx_hm = 0; + move16(); + + prm = param + (k*DEC_NPRM_DIV); + j = 0; + move16(); + + nbits_tcx = sub(st->next_bit_pos, start_bit_pos); + + test(); + IF (st->enablePlcWaveadjust && k) + { + st->tonality_flag = get_next_indice(st, 1); + move16(); + } + /* TCX Gain = 7 bits */ + prm[j++] = get_next_indice(st, 7); + move16(); + + /* TCX Noise Filling = NBITS_NOISE_FILL_LEVEL bits */ + prm[j++] = get_next_indice(st, NBITS_NOISE_FILL_LEVEL); + move16(); + + /* LTP data */ + test(); + test(); + IF ( (k == 0) && ((hTcxLtpDec->tcxltp != 0) || (GT_32(st->sr_core, 25600)))) + { + prm[j] = get_next_indice(st, 1); + move16(); + + IF ( prm[j] ) + { + + prm[j+1] = get_next_indice(st, 9); + move16(); + prm[j+2] = get_next_indice(st, 2); + move16(); + + tcxltp_prm_0 = prm[j]; + move16(); + tcxltp_prm_1 = prm[j+1]; + move16(); + tcxltp_prm_2 = prm[j+2]; + move16(); + } + + st->BER_detect = st->BER_detect | + tcx_ltp_decode_params(&prm[j], + &(hTcxLtpDec->tcxltp_pitch_int), + &(hTcxLtpDec->tcxltp_pitch_fr), + &(hTcxLtpDec->tcxltp_gain), + st->pit_min, + st->pit_fr1, + st->pit_fr2, + st->pit_max, + st->pit_res_max); + + hTcxDec->tcxltp_last_gain_unmodified = hTcxLtpDec->tcxltp_gain; + move16(); + hTcxDec->tcx_hm_LtpPitchLag = -1; + move16(); + + j = add(j, 3); + } + ELSE + { + prm[j++] = tcxltp_prm_0; + move16(); + prm[j++] = tcxltp_prm_1; + move16(); + prm[j++] = tcxltp_prm_2; + move16(); + } + + /* TCX spectral data */ + lg = shr(L_frame, 1); + lgFB = shr(st->hTcxCfg->tcx_coded_lines, 1); + + test(); + IF ( k == 0 && st->last_core_bs_fx == ACELP_CORE ) + { + /* ACE->TCX transition */ + lg = add(lg, st->hTcxCfg->tcx_offset); + if(st->hTcxCfg->lfacNext<0) + { + lg = sub(lg,st->hTcxCfg->lfacNext); + } + + lgFB = add(lgFB, shr(lgFB, 1)); + } + + /* TNS data */ + nTnsParams = 0; + move16(); + nTnsBits = 0; + move16(); + + IF (st->hTcxCfg->fIsTNSAllowed) + { + IF( EQ_16(st->last_core_bs_fx, ACELP_CORE)&&(k==0)) + { + st->BER_detect = 1; + st->last_core = TCX_20_CORE; move16(); + st->last_core_bs_fx = TCX_20_CORE; move16(); + } + test(); + test(); + SetTnsConfig(st->hTcxCfg, 0, (st->last_core_bs_fx == ACELP_CORE) && (k == 0)); + + ReadTnsData(st->hTcxCfg->pCurrentTnsConfig, st, &nTnsBits, prm+j, &nTnsParams); + j = add(j, nTnsParams); + } + + hm_size = shl(mult(st->TcxBandwidth, lgFB), 1); + + /*compute target bits*/ + nbits_tcx = sub(shr(sub(add(sub(sub(st->bits_frame_core, st->bits_common), nbits_igf), 1), k), 1), sub(sub(st->next_bit_pos, start_bit_pos), nbits_tcx)); + + /*Context HM flag*/ + test(); + test(); + IF ( st->hTcxCfg->ctx_hm && !(st->last_core_bs_fx == ACELP_CORE && k == 0) ) + { + prm[j] = get_next_indice(st, 1); + move16(); + nbits_tcx = sub(nbits_tcx, 1); + move16(); + + IF (prm[j]) /* Read PeriodicityIndex */ + { + Word16 NumIndexBits = DecodeIndex_fx(st,hm_size >= 256,prm+j+1); + + flag_ctx_hm = 1; + move16(); + + ConfigureContextHm(lgFB,nbits_tcx,*(prm+j+1),-1,&hm_cfg); + + nbits_tcx = sub(nbits_tcx, NumIndexBits); + } + } + j = add(j, NPRM_CTX_HM); + phm_cfg = NULL; + move16(); + if (flag_ctx_hm) + { + phm_cfg = &hm_cfg; + move16(); + } + hTcxDec->resQBits[k] = ACcontextMapping_decode2_no_mem_s17_LC(st, prm+j,lgFB,nbits_tcx,NPRM_RESQ*st->hTcxCfg->resq,phm_cfg); + move16(); + j = add(j, lgFB); + + } /* k, window index */ + } + + IF(!st->use_partial_copy) + { + IF (LT_16(sub(*total_nbbits, bitsRead[0]), sub(st->next_bit_pos, start_bit_pos))) + { + st->BER_detect = 1; + move16(); + st->next_bit_pos = add(start_bit_pos, sub(*total_nbbits, bitsRead[0])); + } + bitsRead[0] = sub(st->next_bit_pos, start_bit_pos); + move16(); + } + + return; +} + diff --git a/lib_dec/dec_tcx.c b/lib_dec/dec_tcx.c index f82956be9776f61d57647c971d51eb88a674304b..72c70909995609e12bbe554aab07c27eac853a6e 100644 --- a/lib_dec/dec_tcx.c +++ b/lib_dec/dec_tcx.c @@ -50,12 +50,12 @@ /*-----------------------------------------------------------------* - * decoder_tcx() + * decoder_tcx_flt() * * *-----------------------------------------------------------------*/ -void decoder_tcx( +void decoder_tcx_flt( Decoder_State *st, /* i/o: coder memory state */ int16_t prm[], /* i : parameters */ float A[], /* i : coefficients NxAz[M+1] */ @@ -111,12 +111,12 @@ void decoder_tcx( /*-------------------------------------------------------------------* - * decoder_tcx_post() + * decoder_tcx_post_flt() * * *-------------------------------------------------------------------*/ -void decoder_tcx_post( +void decoder_tcx_post_flt( Decoder_State *st, /* i/o: decoder memory state */ float *synth, /* i/o: synthesis */ float *synthFB, /* i/o: FB synthesis */ @@ -176,7 +176,7 @@ void decoder_tcx_post( * PLC: update or retrieve the background level */ if ( bfi == 0 && st->tcxonly && ( st->element_mode != IVAS_CPE_MDCT || MCT_flag ) && st->clas_dec == UNVOICED_CLAS ) { - minimumStatistics( hTcxDec->NoiseLevelMemory_bfi, &hTcxDec->NoiseLevelIndex_bfi, &hTcxDec->CurrLevelIndex_bfi, &hTcxDec->CngLevelBackgroundTrace_bfi, &hTcxDec->LastFrameLevel_bfi, level_syn, PLC_MIN_CNG_LEV_FLT, PLC_MIN_STAT_BUFF_SIZE ); + minimumStatistics_flt( hTcxDec->NoiseLevelMemory_bfi, &hTcxDec->NoiseLevelIndex_bfi, &hTcxDec->CurrLevelIndex_bfi, &hTcxDec->CngLevelBackgroundTrace_bfi, &hTcxDec->LastFrameLevel_bfi, level_syn, PLC_MIN_CNG_LEV_FLT, PLC_MIN_STAT_BUFF_SIZE ); } /* PLC: [TCX: Fade-out] @@ -249,7 +249,7 @@ void decoder_tcx_post( *-----------------------------------------------------------*/ /* Update synth, exc and old_Aq */ - tcx_decoder_memory_update( st, xn_buf, synth, A ); + tcx_decoder_memory_update_flt( st, xn_buf, synth, A ); /* PLC: [TCX: Memory update] */ @@ -274,12 +274,12 @@ void decoder_tcx_post( /*-------------------------------------------------------------------* - * IMDCT() + * IMDCT_flt() * * *-------------------------------------------------------------------*/ -void IMDCT( +void IMDCT_flt( float *x, float *old_syn_overl, float *syn_Overl_TDAC, @@ -353,22 +353,22 @@ void IMDCT( { if ( kernel_type == MDST_IV || ( kernel_type & w ) ) { - TCX_MDST_Inverse( x + w * L_spec_TCX5, win, L_ola, L_win - L_ola, L_ola, st->element_mode ); + TCX_MDST_Inverse_flt( x + w * L_spec_TCX5, win, L_ola, L_win - L_ola, L_ola, st->element_mode ); } else if ( kernel_type != 0 && w == 0 ) /* type 1 or 2 */ { - TCX_MDXT_Inverse( x + w * L_spec_TCX5, win, L_ola, L_win - L_ola, L_ola, kernel_type ); + TCX_MDXT_Inverse_flt( x + w * L_spec_TCX5, win, L_ola, L_win - L_ola, L_ola, kernel_type ); } else { - TCX_MDCT_Inverse( x + w * L_spec_TCX5, win, L_ola, L_win - L_ola, L_ola, st->element_mode ); + TCX_MDCT_Inverse_flt( x + w * L_spec_TCX5, win, L_ola, L_win - L_ola, L_ola, st->element_mode ); } - tcx_windowing_synthesis_current_frame( win, tcx_aldo_window_2, tcx_mdct_window_half, tcx_mdct_window_minimum, L_ola, tcx_mdct_window_half_length, tcx_mdct_window_min_length, ( w > 0 ) ? 0 : left_rect, ( w > 0 ) || ( w == 0 && index == 2 ) ? MIN_OVERLAP : hTcxCfg->tcx_last_overlap_mode, acelp_zir, hTcxDec->old_syn_Overl_float, syn_Overl_TDAC, st->old_Aq_12_8, tcx_mdct_window_trans, L_win, tcx_offset < 0 ? -tcx_offset : 0, ( w > 0 ) || ( frame_cnt > 0 ) ? 1 : st->last_core, ( w > 0 ) || ( frame_cnt > 0 ) ? 0 : st->last_is_cng, fullbandScale ); + tcx_windowing_synthesis_current_frame_flt( win, tcx_aldo_window_2, tcx_mdct_window_half, tcx_mdct_window_minimum, L_ola, tcx_mdct_window_half_length, tcx_mdct_window_min_length, ( w > 0 ) ? 0 : left_rect, ( w > 0 ) || ( w == 0 && index == 2 ) ? MIN_OVERLAP : hTcxCfg->tcx_last_overlap_mode, acelp_zir, hTcxDec->old_syn_Overl_float, syn_Overl_TDAC, st->old_Aq_12_8, tcx_mdct_window_trans, L_win, tcx_offset < 0 ? -tcx_offset : 0, ( w > 0 ) || ( frame_cnt > 0 ) ? 1 : st->last_core, ( w > 0 ) || ( frame_cnt > 0 ) ? 0 : st->last_is_cng, fullbandScale ); if ( w > 0 ) { - tcx_windowing_synthesis_past_frame( xn_buf + tcx_offset - ( L_ola >> 1 ) + w * L_win, tcx_aldo_window_1_trunc, tcx_mdct_window_half, tcx_mdct_window_minimum, L_ola, tcx_mdct_window_half_length, tcx_mdct_window_min_length, MIN_OVERLAP ); + tcx_windowing_synthesis_past_frame_flt( xn_buf + tcx_offset - ( L_ola >> 1 ) + w * L_win, tcx_aldo_window_1_trunc, tcx_mdct_window_half, tcx_mdct_window_minimum, L_ola, tcx_mdct_window_half_length, tcx_mdct_window_min_length, MIN_OVERLAP ); } /* add part of current sub-window overlapping with previous window */ @@ -383,7 +383,7 @@ void IMDCT( if ( st->prev_bfi && frame_cnt == 0 && st->last_core != st->last_core_bfi && st->last_core_bfi == ACELP_CORE ) { - tcx_windowing_synthesis_past_frame( old_syn_overl, tcx_aldo_window_1_trunc, tcx_mdct_window_half, tcx_mdct_window_minimum, overlap, tcx_mdct_window_half_length, tcx_mdct_window_min_length, hTcxCfg->tcx_last_overlap_mode ); + tcx_windowing_synthesis_past_frame_flt( old_syn_overl, tcx_aldo_window_1_trunc, tcx_mdct_window_half, tcx_mdct_window_minimum, overlap, tcx_mdct_window_half_length, tcx_mdct_window_min_length, hTcxCfg->tcx_last_overlap_mode ); v_add( xn_buf, old_syn_overl, xn_buf, overlap ); } } @@ -399,15 +399,15 @@ void IMDCT( /* 1st TCX-5 window, special MDCT with minimum overlap on right side */ if ( kernel_type == MDST_IV ) { - TCX_MDST_Inverse( x, win + L_win, 0, L_win - ( L_ola >> 1 ), L_ola, st->element_mode ); + TCX_MDST_Inverse_flt( x, win + L_win, 0, L_win - ( L_ola >> 1 ), L_ola, st->element_mode ); } else if ( kernel_type != MDCT_IV ) /* type 1 or 2 */ { - TCX_MDXT_Inverse( x, win + L_win, 0, L_win - ( L_ola >> 1 ), L_ola, kernel_type ); + TCX_MDXT_Inverse_flt( x, win + L_win, 0, L_win - ( L_ola >> 1 ), L_ola, kernel_type ); } else { - TCX_MDCT_Inverse( x, win + L_win, 0, L_win - ( L_ola >> 1 ), L_ola, st->element_mode ); + TCX_MDCT_Inverse_flt( x, win + L_win, 0, L_win - ( L_ola >> 1 ), L_ola, st->element_mode ); } set_zero( xn_buf, ( overlap >> 1 ) ); @@ -418,17 +418,17 @@ void IMDCT( /* 2nd TCX-5 window, regular MDCT with minimum overlap on both sides */ if ( kernel_type & 1 ) { - TCX_MDST_Inverse( x + L_spec_TCX5, win, L_ola, L_win - L_ola, L_ola, st->element_mode ); + TCX_MDST_Inverse_flt( x + L_spec_TCX5, win, L_ola, L_win - L_ola, L_ola, st->element_mode ); } else { - TCX_MDCT_Inverse( x + L_spec_TCX5, win, L_ola, L_win - L_ola, L_ola, st->element_mode ); + TCX_MDCT_Inverse_flt( x + L_spec_TCX5, win, L_ola, L_win - L_ola, L_ola, st->element_mode ); } - tcx_windowing_synthesis_current_frame( win, tcx_aldo_window_2, tcx_mdct_window_half, tcx_mdct_window_minimum, L_ola, tcx_mdct_window_half_length, tcx_mdct_window_min_length, 0, + tcx_windowing_synthesis_current_frame_flt( win, tcx_aldo_window_2, tcx_mdct_window_half, tcx_mdct_window_minimum, L_ola, tcx_mdct_window_half_length, tcx_mdct_window_min_length, 0, /* left_rect */ MIN_OVERLAP, /* left_mode */ acelp_zir, hTcxDec->old_syn_Overl_float, syn_Overl_TDAC, st->old_Aq_12_8, tcx_mdct_window_trans, L_win, tcx_offset < 0 ? -tcx_offset : 0, 1, /* st->last_mode_bfi */ 0, /* st->last_is_cng */ fullbandScale ); - tcx_windowing_synthesis_past_frame( xn_buf + ( overlap >> 1 ) + L_win - ( L_ola >> 1 ), tcx_aldo_window_1_trunc, tcx_mdct_window_half, tcx_mdct_window_minimum, L_ola, tcx_mdct_window_half_length, tcx_mdct_window_min_length, 2 ); + tcx_windowing_synthesis_past_frame_flt( xn_buf + ( overlap >> 1 ) + L_win - ( L_ola >> 1 ), tcx_aldo_window_1_trunc, tcx_mdct_window_half, tcx_mdct_window_minimum, L_ola, tcx_mdct_window_half_length, tcx_mdct_window_min_length, 2 ); /* add part of current sub-window overlapping with previous window */ v_add( win, xn_buf + ( overlap >> 1 ) + L_win - ( L_ola >> 1 ), xn_buf + ( overlap >> 1 ) + L_win - ( L_ola >> 1 ), L_ola ); @@ -451,25 +451,25 @@ void IMDCT( xn_buf[overlap - 1 - w] = -1.0f * xn_buf[w]; } } - tcx_windowing_synthesis_current_frame( xn_buf, tcx_aldo_window_2, tcx_mdct_window_half, tcx_mdct_window_minimum, overlap, tcx_mdct_window_half_length, tcx_mdct_window_min_length, left_rect, 0, /* left_mode */ acelp_zir, hTcxDec->old_syn_Overl_float, syn_Overl_TDAC, st->old_Aq_12_8, tcx_mdct_window_trans, 2 * L_win, tcx_offset < 0 ? -tcx_offset : 0, st->last_core_bfi, st->last_is_cng, fullbandScale ); + tcx_windowing_synthesis_current_frame_flt( xn_buf, tcx_aldo_window_2, tcx_mdct_window_half, tcx_mdct_window_minimum, overlap, tcx_mdct_window_half_length, tcx_mdct_window_min_length, left_rect, 0, /* left_mode */ acelp_zir, hTcxDec->old_syn_Overl_float, syn_Overl_TDAC, st->old_Aq_12_8, tcx_mdct_window_trans, 2 * L_win, tcx_offset < 0 ? -tcx_offset : 0, st->last_core_bfi, st->last_is_cng, fullbandScale ); } else { /* default, i.e. maximum overlap, single transform, no grouping */ if ( kernel_type == MDST_IV ) { - TCX_MDST_Inverse( x, xn_buf, overlap, L_frame - overlap, overlap, st->element_mode ); + TCX_MDST_Inverse_flt( x, xn_buf, overlap, L_frame - overlap, overlap, st->element_mode ); } else if ( kernel_type != MDCT_IV ) /* type 1 or 2 */ { - TCX_MDXT_Inverse( x, xn_buf, overlap, L_frame - overlap, overlap, kernel_type ); + TCX_MDXT_Inverse_flt( x, xn_buf, overlap, L_frame - overlap, overlap, kernel_type ); } else { - TCX_MDCT_Inverse( x, xn_buf, overlap, L_frame - overlap, overlap, st->element_mode ); + TCX_MDCT_Inverse_flt( x, xn_buf, overlap, L_frame - overlap, overlap, st->element_mode ); } - tcx_windowing_synthesis_current_frame( xn_buf, tcx_aldo_window_2, tcx_mdct_window_half, tcx_mdct_window_minimum, overlap, tcx_mdct_window_half_length, tcx_mdct_window_min_length, left_rect, !bfi && ( frame_cnt > 0 ) && ( index == 0 ) && ( st->last_core != ACELP_CORE ) ? MIN_OVERLAP : index, acelp_zir, hTcxDec->old_syn_Overl_float, syn_Overl_TDAC, st->old_Aq_12_8, tcx_mdct_window_trans, L_frame_glob >> 1, tcx_offset < 0 ? -tcx_offset : 0, ( frame_cnt > 0 /*|| (st->last_con_tcx )*/ ) ? 1 : st->last_core_bfi, ( frame_cnt > 0 ) ? 0 : st->last_is_cng, fullbandScale ); + tcx_windowing_synthesis_current_frame_flt( xn_buf, tcx_aldo_window_2, tcx_mdct_window_half, tcx_mdct_window_minimum, overlap, tcx_mdct_window_half_length, tcx_mdct_window_min_length, left_rect, !bfi && ( frame_cnt > 0 ) && ( index == 0 ) && ( st->last_core != ACELP_CORE ) ? MIN_OVERLAP : index, acelp_zir, hTcxDec->old_syn_Overl_float, syn_Overl_TDAC, st->old_Aq_12_8, tcx_mdct_window_trans, L_frame_glob >> 1, tcx_offset < 0 ? -tcx_offset : 0, ( frame_cnt > 0 /*|| (st->last_con_tcx )*/ ) ? 1 : st->last_core_bfi, ( frame_cnt > 0 ) ? 0 : st->last_is_cng, fullbandScale ); } /* tcx_last_overlap_mode != FULL_OVERLAP */ } @@ -533,15 +533,15 @@ void IMDCT( if ( kernel_type == MDST_IV ) { - TCX_MDST_Inverse( x, xn_buf, overlap, L_frame - overlap, overlap, st->element_mode ); + TCX_MDST_Inverse_flt( x, xn_buf, overlap, L_frame - overlap, overlap, st->element_mode ); } else if ( kernel_type != MDCT_IV ) /* type 1 or 2 */ { - TCX_MDXT_Inverse( x, xn_buf, overlap, L_frame - overlap, overlap, kernel_type ); + TCX_MDXT_Inverse_flt( x, xn_buf, overlap, L_frame - overlap, overlap, kernel_type ); } else { - TCX_MDCT_Inverse( x, xn_buf, overlap, L_frame - overlap, overlap, st->element_mode ); + TCX_MDCT_Inverse_flt( x, xn_buf, overlap, L_frame - overlap, overlap, st->element_mode ); } /*-----------------------------------------------------------* @@ -559,14 +559,14 @@ void IMDCT( mvr2r( xn_buf + overlap / 2 + 2 * acelp_mem_len, &buf[0], analysis_len ); /* get LPC from that signal part to use for acelp zir smoothing */ - ham_cos_window( &window_buf[0], analysis_len / 2, analysis_len / 2 ); + ham_cos_window_flt( &window_buf[0], analysis_len / 2, analysis_len / 2 ); autocorr( &buf[0], &r[0], M, analysis_len, &window_buf[0], 0, 0, 0 ); lag_wind_flt( r, M, L_frame_glob * FRAMES_PER_SEC, LAGW_STRONG ); lev_dur( &st->old_Aq_12_8[0], &r[0], M, NULL ); } /* Window current frame */ - tcx_windowing_synthesis_current_frame( xn_buf, tcx_aldo_window_2, tcx_mdct_window_half, tcx_mdct_window_minimum, overlap, tcx_mdct_window_half_length, tcx_mdct_window_min_length, left_rect, hTcxCfg->tcx_last_overlap_mode, acelp_zir, hTcxDec->old_syn_Overl_float, syn_Overl_TDAC, st->old_Aq_12_8, tcx_mdct_window_trans, L_frame_glob >> 1, acelp_mem_len, st->last_core_bfi, st->last_is_cng, fullbandScale ); + tcx_windowing_synthesis_current_frame_flt( xn_buf, tcx_aldo_window_2, tcx_mdct_window_half, tcx_mdct_window_minimum, overlap, tcx_mdct_window_half_length, tcx_mdct_window_min_length, left_rect, hTcxCfg->tcx_last_overlap_mode, acelp_zir, hTcxDec->old_syn_Overl_float, syn_Overl_TDAC, st->old_Aq_12_8, tcx_mdct_window_trans, L_frame_glob >> 1, acelp_mem_len, st->last_core_bfi, st->last_is_cng, fullbandScale ); } } /* TCX-20 and TCX-only */ @@ -610,7 +610,7 @@ void IMDCT( } else { - tcx_windowing_synthesis_past_frame( old_syn_overl, tcx_aldo_window_1_trunc, tcx_mdct_window_half, tcx_mdct_window_minimum, overlap, tcx_mdct_window_half_length, tcx_mdct_window_min_length, ( index == 0 || hTcxCfg->tcx_last_overlap_mode == MIN_OVERLAP ) ? hTcxCfg->tcx_last_overlap_mode : index ); + tcx_windowing_synthesis_past_frame_flt( old_syn_overl, tcx_aldo_window_1_trunc, tcx_mdct_window_half, tcx_mdct_window_minimum, overlap, tcx_mdct_window_half_length, tcx_mdct_window_min_length, ( index == 0 || hTcxCfg->tcx_last_overlap_mode == MIN_OVERLAP ) ? hTcxCfg->tcx_last_overlap_mode : index ); if ( bfi ) { @@ -643,7 +643,7 @@ void IMDCT( mvr2r( xn_buf + L_frame - nz, old_out, nz + overlap ); set_zero( old_out + nz + overlap, nz ); - tcx_windowing_synthesis_past_frame( old_out + nz, tcx_aldo_window_1_trunc, tcx_mdct_window_half, tcx_mdct_window_minimum, overlap, tcx_mdct_window_half_length, tcx_mdct_window_min_length, hTcxCfg->tcx_curr_overlap_mode ); + tcx_windowing_synthesis_past_frame_flt( old_out + nz, tcx_aldo_window_1_trunc, tcx_mdct_window_half, tcx_mdct_window_minimum, overlap, tcx_mdct_window_half_length, tcx_mdct_window_min_length, hTcxCfg->tcx_curr_overlap_mode ); /* If current overlap mode = FULL_OVERLAP -> ALDO_WINDOW */ if ( hTcxCfg->tcx_curr_overlap_mode == FULL_OVERLAP ) @@ -782,7 +782,7 @@ void decoder_tcx_invQ( /* read TNS data */ if ( !bfi && hTcxCfg->fIsTNSAllowed ) { - *fUseTns = DecodeTnsData( hTcxCfg->pCurrentTnsConfig, prm_tns, &tnsSize, tnsData ); + *fUseTns = DecodeTnsData_ivas( hTcxCfg->pCurrentTnsConfig, prm_tns, &tnsSize, tnsData ); } else { @@ -831,7 +831,7 @@ void decoder_tcx_invQ( x[k] = ((float)x_fx[k] / ((unsigned)1 << (31 - x_e))); } #else - tcx_arith_decode_envelope( st, x, L_frame, L_spec, Aind, *prm_target, prm_sqQ, st->last_core_from_bs != ACELP_CORE, prm_hm, /* HM parameter area */ hTcxDec->tcx_hm_LtpPitchLag, &arith_bits, &signaling_bits, ( st->bwidth > WB ) ? 1 : 0 ); + tcx_arith_decode_envelope_flt( st, x, L_frame, L_spec, Aind, *prm_target, prm_sqQ, st->last_core_from_bs != ACELP_CORE, prm_hm, /* HM parameter area */ hTcxDec->tcx_hm_LtpPitchLag, &arith_bits, &signaling_bits, ( st->bwidth > WB ) ? 1 : 0 ); #endif hTcxDec->resQBits[frame_cnt] = *prm_target - arith_bits; @@ -883,7 +883,7 @@ void decoder_tcx_invQ( if ( st->element_mode != IVAS_CPE_MDCT ) { weight_a( A, Ap, gamma1, M ); - lpc2mdct( Ap, M, gainlpc2, FDNS_NPTS, 0 ); + lpc2mdct_flt( Ap, M, gainlpc2, FDNS_NPTS, 0 ); } /* initialize LF deemphasis factors in xn_buf */ @@ -897,7 +897,7 @@ void decoder_tcx_invQ( if ( !st->tcxonly ) { - AdaptLowFreqDeemph( x, hTcxDec->tcx_lpc_shaped_ari, gainlpc2, L_frame, xn_buf /* LF deemphasis factors */ ); + AdaptLowFreqDeemph_flt( x, hTcxDec->tcx_lpc_shaped_ari, gainlpc2, L_frame, xn_buf /* LF deemphasis factors */ ); } } @@ -947,7 +947,7 @@ void decoder_tcx_invQ( else { *gain_tcx = hTcxDec->old_gaintcx_bfi_float; - hTcxDec->damping_float = Damping_fact( st->coder_type, st->nbLostCmpt, st->last_good, st->stab_fac, &( st->lp_gainp ), st->last_core ); + hTcxDec->damping_float = Damping_fact_flt( st->coder_type, st->nbLostCmpt, st->last_good, st->stab_fac, &( st->lp_gainp ), st->last_core ); } hTcxDec->cummulative_damping_tcx_float *= hTcxDec->damping_float; @@ -979,7 +979,7 @@ void decoder_tcx_invQ( if ( st->element_mode != IVAS_CPE_MDCT ) { weight_a( A, Ap, gamma, M ); - lpc2mdct( Ap, M, gainlpc2, FDNS_NPTS, 0 ); + lpc2mdct_flt( Ap, M, gainlpc2, FDNS_NPTS, 0 ); } } @@ -1044,13 +1044,13 @@ void decoder_tcx_invQ( /* envelope based arithmetic coder */ const int16_t *prm_resq; prm_resq = prm_sqQ + *prm_target /* = targetBits */ - hTcxDec->resQBits[frame_cnt]; - i = tcx_ari_res_invQ_spec( x, L_spec, prm_resq, hTcxDec->resQBits[frame_cnt], 0, hTcxCfg->sq_rounding_flt, xn_buf /* LF deemphasis factors */ ); + i = tcx_ari_res_invQ_spec_flt( x, L_spec, prm_resq, hTcxDec->resQBits[frame_cnt], 0, hTcxCfg->sq_rounding_flt, xn_buf /* LF deemphasis factors */ ); } else { /* context based arithmetic coder */ - i = tcx_res_invQ_gain( gain_tcx, &prm_sqQ[L_spec], hTcxDec->resQBits[frame_cnt] ); - tcx_res_invQ_spec( x, L_spec, &prm_sqQ[L_spec], hTcxDec->resQBits[frame_cnt], i, hTcxCfg->sq_rounding_flt, st->tcxonly ? NULL : xn_buf /* LF deemphasis factors */ ); + i = tcx_res_invQ_gain_flt( gain_tcx, &prm_sqQ[L_spec], hTcxDec->resQBits[frame_cnt] ); + tcx_res_invQ_spec_flt( x, L_spec, &prm_sqQ[L_spec], hTcxDec->resQBits[frame_cnt], i, hTcxCfg->sq_rounding_flt, st->tcxonly ? NULL : xn_buf /* LF deemphasis factors */ ); } } @@ -1058,7 +1058,7 @@ void decoder_tcx_invQ( { if ( hTcxLtpDec->tcxltp && ( hTcxLtpDec->tcxltp_gain_float > 0.0f ) && !( *fUseTns ) ) { - PsychAdaptLowFreqDeemph( x, gainlpc2, NULL ); + PsychAdaptLowFreqDeemph_flt( x, gainlpc2, NULL ); } } @@ -1138,7 +1138,7 @@ void decoder_tcx_noisefilling( *-----------------------------------------------------------------*/ /* Init lengths */ - infoIGFStartLine = get_igf_startline( st, L_frame, L_frameTCX ); + infoIGFStartLine = get_igf_startline_flt( st, L_frame, L_frameTCX ); noiseFillingSize = L_spec; if ( st->igf ) @@ -1187,7 +1187,7 @@ void decoder_tcx_noisefilling( nf_seed += (int16_t) ( abs( prm_sqQ[i] ) * i * 2 ); } } - tcx_noise_filling( x, nf_seed, firstLine, noiseFillingSize, noiseTransWidth, L_frame, noiseTiltFactor, fac_ns, st->igf ? st->hIGFDec->infoTCXNoise : NULL, st->element_mode ); + tcx_noise_filling_flt( x, nf_seed, firstLine, noiseFillingSize, noiseTransWidth, L_frame, noiseTiltFactor, fac_ns, st->igf ? st->hIGFDec->infoTCXNoise : NULL, st->element_mode ); st->seed_tcx_plc = nf_seed; } @@ -1249,7 +1249,7 @@ void decoder_tcx_noisefilling( { if ( !bfi && st->element_mode != IVAS_CPE_MDCT ) { - TonalMDCTConceal_SaveFreqSignal( st->hTonalMDCTConc, x, L_frameTCX, L_frame, gainlpc2, infoIGFStartLine ); + TonalMDCTConceal_SaveFreqSignal_ivas( st->hTonalMDCTConc, x, L_frameTCX, L_frame, gainlpc2, infoIGFStartLine ); } else if ( bfi ) { @@ -1330,11 +1330,11 @@ void decoder_tcx_noisefilling( if ( st->element_mode == IVAS_CPE_MDCT && !MCT_flag ) { - TonalMDCTConceal_InsertNoise( st->hTonalMDCTConc, x, st->tonal_mdct_plc_active, &st->seed_tcx_plc, noiseTiltFactor, f, concealment_noise, hTcxDec->CngLevelBackgroundTrace_bfi, infoIGFStartLine ); + TonalMDCTConceal_InsertNoise_ivas( st->hTonalMDCTConc, x, st->tonal_mdct_plc_active, &st->seed_tcx_plc, noiseTiltFactor, f, concealment_noise, hTcxDec->CngLevelBackgroundTrace_bfi, infoIGFStartLine ); } else { - TonalMDCTConceal_InsertNoise( st->hTonalMDCTConc, x, st->tonal_mdct_plc_active, &st->seed_tcx_plc, noiseTiltFactor, f, NULL, hTcxDec->CngLevelBackgroundTrace_bfi, infoIGFStartLine ); + TonalMDCTConceal_InsertNoise_ivas( st->hTonalMDCTConc, x, st->tonal_mdct_plc_active, &st->seed_tcx_plc, noiseTiltFactor, f, NULL, hTcxDec->CngLevelBackgroundTrace_bfi, infoIGFStartLine ); } } } @@ -1360,17 +1360,17 @@ void decoder_tcx_noisefilling( if ( bfi && ( !st->enablePlcWaveadjust || ( *temp_concealment_method == TCX_TONAL ) ) && st->igf && ( frame_cnt == 0 ) && ( L_frameTCX == hTcxDec->L_frameTCX >> 1 ) && ( st->tcxonly ) && ( !st->tonal_mdct_plc_active ) && ( st->nbLostCmpt == 1 ) && ( hTcxCfg->tcx_last_overlap_mode != FULL_OVERLAP ) && ( hTcxCfg->tcx_curr_overlap_mode != FULL_OVERLAP ) ) { - IGFDecCopyLPCFlatSpectrum( st->hIGFDec, x, IGF_GRID_LB_SHORT ); + IGFDecCopyLPCFlatSpectrum_flt( st->hIGFDec, x, IGF_GRID_LB_SHORT ); /* also replace flat spectrum for the second TCX10 sub frame */ - IGFDecUpdateInfo( st->hIGFDec, 1, IGF_GRID_LB_SHORT ); - IGFDecCopyLPCFlatSpectrum( st->hIGFDec, x, IGF_GRID_LB_SHORT ); - IGFDecUpdateInfo( st->hIGFDec, 0, IGF_GRID_LB_SHORT ); + IGFDecUpdateInfo_flt( st->hIGFDec, 1, IGF_GRID_LB_SHORT ); + IGFDecCopyLPCFlatSpectrum_flt( st->hIGFDec, x, IGF_GRID_LB_SHORT ); + IGFDecUpdateInfo_flt( st->hIGFDec, 0, IGF_GRID_LB_SHORT ); mvs2s( st->hIGFDec->igfData.igf_curr_subframe[0][0], st->hIGFDec->igfData.igf_curr_subframe[1][0], IGF_MAX_SFB ); } else if ( bfi && st->igf && ( frame_cnt == 0 ) && ( L_frameTCX == hTcxDec->L_frameTCX >> 1 ) ) { /* copy second to first subframe */ - IGFDecReplicateTCX10State( st->hIGFDec ); + IGFDecReplicateTCX10State_flt( st->hIGFDec ); } if ( st->element_mode != EVS_MONO ) @@ -1422,18 +1422,18 @@ void decoder_tcx_noiseshaping_igf( { if ( ( L_frame == st->L_frame >> 1 ) && ( st->tcxonly ) ) { - IGFDecCopyLPCFlatSpectrum( st->hIGFDec, x, IGF_GRID_LB_SHORT ); + IGFDecCopyLPCFlatSpectrum_flt( st->hIGFDec, x, IGF_GRID_LB_SHORT ); } else { - IGFDecCopyLPCFlatSpectrum( st->hIGFDec, x, ( st->last_core == ACELP_CORE ) ? IGF_GRID_LB_TRAN : IGF_GRID_LB_NORM ); + IGFDecCopyLPCFlatSpectrum_flt( st->hIGFDec, x, ( st->last_core == ACELP_CORE ) ? IGF_GRID_LB_TRAN : IGF_GRID_LB_NORM ); } } /* LPC gains already available */ if ( st->element_mode != IVAS_CPE_MDCT && ( !st->enablePlcWaveadjust || !bfi || ( *temp_concealment_method == TCX_TONAL ) ) ) { - mdct_noiseShaping( x, L_frame, gainlpc2, FDNS_NPTS ); + mdct_noiseShaping_flt( x, L_frame, gainlpc2, FDNS_NPTS ); if ( !bfi ) { @@ -1446,12 +1446,12 @@ void decoder_tcx_noiseshaping_igf( /* PLC: [TCX: Tonal Concealment] */ if ( bfi && st->tonal_mdct_plc_active && st->element_mode != IVAS_CPE_MDCT ) { - TonalMDCTConceal_Apply( st->hTonalMDCTConc, x, st->hTcxCfg->psychParamsCurrent ); + TonalMDCTConceal_Apply_ivas( st->hTonalMDCTConc, x, st->hTcxCfg->psychParamsCurrent ); } if ( st->hTonalMDCTConc != NULL && st->element_mode != IVAS_CPE_MDCT ) { - TonalMDCTConceal_UpdateState( st->hTonalMDCTConc, L_frameTCX, ( hTcxDec->tcxltp_last_gain_unmodified_float > 0 ) ? st->old_fpitch_float : 0, bfi, bfi && st->tonal_mdct_plc_active ); + TonalMDCTConceal_UpdateState_ivas( st->hTonalMDCTConc, L_frameTCX, ( hTcxDec->tcxltp_last_gain_unmodified_float > 0 ) ? st->old_fpitch_float : 0, bfi, bfi && st->tonal_mdct_plc_active ); } if ( st->enablePlcWaveadjust ) @@ -1474,7 +1474,7 @@ void decoder_tcx_noiseshaping_igf( { if ( st->element_mode != IVAS_CPE_MDCT ) { - IGFDecApplyMono( st->hIGFDec, x, ( st->last_core == ACELP_CORE || ( left_rect && bfi ) ) ? IGF_GRID_LB_TRAN : IGF_GRID_LB_NORM, bfi, st->element_mode ); + IGFDecApplyMono_flt( st->hIGFDec, x, ( st->last_core == ACELP_CORE || ( left_rect && bfi ) ) ? IGF_GRID_LB_TRAN : IGF_GRID_LB_NORM, bfi, st->element_mode ); } } @@ -1482,7 +1482,7 @@ void decoder_tcx_noiseshaping_igf( { if ( st->element_mode != IVAS_CPE_MDCT ) { - IGFDecApplyMono( st->hIGFDec, x, IGF_GRID_LB_SHORT, bfi, st->element_mode ); + IGFDecApplyMono_flt( st->hIGFDec, x, IGF_GRID_LB_SHORT, bfi, st->element_mode ); } } @@ -1549,7 +1549,7 @@ void decoder_tcx_tns( if ( hTcxCfg->fIsTNSAllowed && fUseTns != 0 && bfi != 1 && tnsData->tnsOnWhitenedSpectra == whitenedDomain ) { /* Apply TNS to get the reconstructed signal */ - SetTnsConfig( hTcxCfg, L_frame_glob == st->L_frame, ( st->last_core == ACELP_CORE ) && ( frame_cnt == 0 ) ); + SetTnsConfig_flt( hTcxCfg, L_frame_glob == st->L_frame, ( st->last_core == ACELP_CORE ) && ( frame_cnt == 0 ) ); if ( ( L_frame == st->L_frame >> 1 ) && st->tcxonly && isTCX5 ) { @@ -1738,7 +1738,7 @@ void decoder_tcx_imdct( if ( st->element_mode != IVAS_CPE_DFT && !sba_dirac_stereo_flag ) { - IMDCT( xn_bufFB, hTcxDec->syn_Overl_float, hTcxDec->syn_Overl_TDAC_float, xn_buf, hTcxCfg->tcx_aldo_window_1_trunc_flt, hTcxCfg->tcx_aldo_window_2_flt, + IMDCT_flt( xn_bufFB, hTcxDec->syn_Overl_float, hTcxDec->syn_Overl_TDAC_float, xn_buf, hTcxCfg->tcx_aldo_window_1_trunc_flt, hTcxCfg->tcx_aldo_window_2_flt, hTcxCfg->tcx_mdct_window_half_flt, hTcxCfg->tcx_mdct_window_minimum_flt, hTcxCfg->tcx_mdct_window_trans_flt, hTcxCfg->tcx_mdct_window_half_length, hTcxCfg->tcx_mdct_window_min_length, index, kernelType, left_rect, tcx_offset, overlap, L_frame, L_frameTCX, max( L_frameTCX, L_spec ) >> 1, L_frame_glob, frame_cnt, bfi, st->hHQ_core->old_outLB, 0, st, 0, acelp_zir ); } @@ -1746,7 +1746,7 @@ void decoder_tcx_imdct( /* Generate additional comfort noise to mask potential coding artefacts */ if ( st->flag_cna && st->element_mode != IVAS_CPE_TD && st->element_mode != IVAS_CPE_DFT && !st->cna_dirac_flag ) { - generate_masking_noise_mdct( x, st->hFdCngDec->hFdCngCom ); + generate_masking_noise_mdct_flt( x, st->hFdCngDec->hFdCngCom ); } if ( st->element_mode == IVAS_CPE_DFT || sba_dirac_stereo_flag ) @@ -1754,21 +1754,21 @@ void decoder_tcx_imdct( mvr2r( x, xn_bufFB, max( L_spec, max( L_frame, L_frameTCX ) ) ); - IMDCT( xn_bufFB, hTcxDec->syn_Overl_float, hTcxDec->syn_Overl_TDAC_float, xn_buf, hTcxCfg->tcx_aldo_window_1_trunc_flt, hTcxCfg->tcx_aldo_window_2_flt, hTcxCfg->tcx_mdct_window_half_flt, hTcxCfg->tcx_mdct_window_minimum_flt, hTcxCfg->tcx_mdct_window_trans_flt, hTcxCfg->tcx_mdct_window_half_length, hTcxCfg->tcx_mdct_window_min_length, index, + IMDCT_flt( xn_bufFB, hTcxDec->syn_Overl_float, hTcxDec->syn_Overl_TDAC_float, xn_buf, hTcxCfg->tcx_aldo_window_1_trunc_flt, hTcxCfg->tcx_aldo_window_2_flt, hTcxCfg->tcx_mdct_window_half_flt, hTcxCfg->tcx_mdct_window_minimum_flt, hTcxCfg->tcx_mdct_window_trans_flt, hTcxCfg->tcx_mdct_window_half_length, hTcxCfg->tcx_mdct_window_min_length, index, kernelType, left_rect, tcx_offset, overlap, L_frame, L_frameTCX, max( L_frameTCX, L_spec ) >> 1, L_frame_glob, frame_cnt, bfi, st->hHQ_core->old_outLB, 0, st, 0, acelp_zir ); } if ( st->element_mode != EVS_MONO ) { - IMDCT( x_tmp, hTcxDec->syn_OverlFB_float, hTcxDec->syn_Overl_TDACFB_float, xn_bufFB, hTcxCfg->tcx_aldo_window_1_FB_trunc_flt, hTcxCfg->tcx_aldo_window_2_FB_flt, + IMDCT_flt( x_tmp, hTcxDec->syn_OverlFB_float, hTcxDec->syn_Overl_TDACFB_float, xn_bufFB, hTcxCfg->tcx_aldo_window_1_FB_trunc_flt, hTcxCfg->tcx_aldo_window_2_FB_flt, hTcxCfg->tcx_mdct_window_halfFB_flt, hTcxCfg->tcx_mdct_window_minimumFB_flt, hTcxCfg->tcx_mdct_window_transFB_flt, hTcxCfg->tcx_mdct_window_half_lengthFB, hTcxCfg->tcx_mdct_window_min_lengthFB, index, kernelType, left_rect, tcx_offsetFB, overlapFB, L_frameTCX, L_frameTCX, max( L_frameTCX, L_spec ) >> 1, L_frameTCX_glob, frame_cnt, bfi, st->hHQ_core->old_out, 1, st, FSCALE_DENOM * L_frameTCX_glob / L_frame_glob, acelp_zir ); } else { - IMDCT( x, hTcxDec->syn_OverlFB_float, hTcxDec->syn_Overl_TDACFB_float, xn_bufFB, hTcxCfg->tcx_aldo_window_1_FB_trunc_flt, hTcxCfg->tcx_aldo_window_2_FB_flt, hTcxCfg->tcx_mdct_window_halfFB_flt, hTcxCfg->tcx_mdct_window_minimumFB_flt, hTcxCfg->tcx_mdct_window_transFB_flt, hTcxCfg->tcx_mdct_window_half_lengthFB, hTcxCfg->tcx_mdct_window_min_lengthFB, index, + IMDCT_flt( x, hTcxDec->syn_OverlFB_float, hTcxDec->syn_Overl_TDACFB_float, xn_bufFB, hTcxCfg->tcx_aldo_window_1_FB_trunc_flt, hTcxCfg->tcx_aldo_window_2_FB_flt, hTcxCfg->tcx_mdct_window_halfFB_flt, hTcxCfg->tcx_mdct_window_minimumFB_flt, hTcxCfg->tcx_mdct_window_transFB_flt, hTcxCfg->tcx_mdct_window_half_lengthFB, hTcxCfg->tcx_mdct_window_min_lengthFB, index, kernelType, left_rect, tcx_offsetFB, overlapFB, L_frameTCX, L_frameTCX, max( L_frameTCX, L_spec ) >> 1, L_frameTCX_glob, frame_cnt, bfi, st->hHQ_core->old_out, 1, st, FSCALE_DENOM * L_frameTCX_glob / L_frame_glob, acelp_zir ); } @@ -1900,11 +1900,11 @@ void init_tcx_info( { if ( ( *L_frame == st->L_frame >> 1 ) && ( st->tcxonly ) ) { - IGFDecUpdateInfo( st->hIGFDec, frame_cnt, IGF_GRID_LB_SHORT ); + IGFDecUpdateInfo_flt( st->hIGFDec, frame_cnt, IGF_GRID_LB_SHORT ); } else { - IGFDecUpdateInfo( st->hIGFDec, frame_cnt, ( st->last_core == ACELP_CORE || ( *left_rect && st->bfi ) ) ? IGF_GRID_LB_TRAN : IGF_GRID_LB_NORM ); + IGFDecUpdateInfo_flt( st->hIGFDec, frame_cnt, ( st->last_core == ACELP_CORE || ( *left_rect && st->bfi ) ) ? IGF_GRID_LB_TRAN : IGF_GRID_LB_NORM ); } } @@ -1929,7 +1929,7 @@ void decoder_tcx_IGF_mono( { int16_t igfGridIdx; - IGFDecUpdateInfo( st->hIGFDec, frame_cnt, ( L_frame == st->L_frame >> 1 ) && ( st->tcxonly ) ? IGF_GRID_LB_SHORT : ( st->last_core == ACELP_CORE || left_rect ) ? IGF_GRID_LB_TRAN + IGFDecUpdateInfo_flt( st->hIGFDec, frame_cnt, ( L_frame == st->L_frame >> 1 ) && ( st->tcxonly ) ? IGF_GRID_LB_SHORT : ( st->last_core == ACELP_CORE || left_rect ) ? IGF_GRID_LB_TRAN : IGF_GRID_LB_NORM ); if ( st->igf ) @@ -1941,7 +1941,7 @@ void decoder_tcx_IGF_mono( igfGridIdx = ( st->last_core == ACELP_CORE || ( left_rect && bfi ) ) ? IGF_GRID_LB_TRAN : IGF_GRID_LB_NORM; } - IGFDecApplyMono( st->hIGFDec, x, igfGridIdx, bfi, st->element_mode ); + IGFDecApplyMono_flt( st->hIGFDec, x, igfGridIdx, bfi, st->element_mode ); } return; @@ -1995,10 +1995,10 @@ void decoder_tcx_IGF_stereo( set_s( &coreMsMask[sfbConf->sfbOffset[sfb]], ms_mask[k][sfb], sfbConf->sfbOffset[sfb + 1] - sfbConf->sfbOffset[sfb] ); } - IGFDecUpdateInfo( sts[0]->hIGFDec, k, ( L_frame == sts[0]->L_frame >> 1 ) && ( sts[0]->tcxonly ) ? IGF_GRID_LB_SHORT : ( sts[0]->last_core == ACELP_CORE || left_rect ) ? IGF_GRID_LB_TRAN + IGFDecUpdateInfo_flt( sts[0]->hIGFDec, k, ( L_frame == sts[0]->L_frame >> 1 ) && ( sts[0]->tcxonly ) ? IGF_GRID_LB_SHORT : ( sts[0]->last_core == ACELP_CORE || left_rect ) ? IGF_GRID_LB_TRAN : IGF_GRID_LB_NORM ); - IGFDecUpdateInfo( sts[1]->hIGFDec, k, ( L_frame == sts[1]->L_frame >> 1 ) && ( sts[1]->tcxonly ) ? IGF_GRID_LB_SHORT : ( sts[1]->last_core == ACELP_CORE || left_rect ) ? IGF_GRID_LB_TRAN + IGFDecUpdateInfo_flt( sts[1]->hIGFDec, k, ( L_frame == sts[1]->L_frame >> 1 ) && ( sts[1]->tcxonly ) ? IGF_GRID_LB_SHORT : ( sts[1]->last_core == ACELP_CORE || left_rect ) ? IGF_GRID_LB_TRAN : IGF_GRID_LB_NORM ); if ( sts[0]->igf ) @@ -2009,7 +2009,7 @@ void decoder_tcx_IGF_stereo( igfGridIdx = ( sts[0]->last_core == ACELP_CORE || ( left_rect && bfi ) ) ? IGF_GRID_LB_TRAN : IGF_GRID_LB_NORM; } - IGFDecApplyStereo( sts[0]->hIGFDec, sts[1]->hIGFDec, x[0][k], x[1][k], igfGridIdx, coreMsMask, hStereoMdct->IGFStereoMode[k] == SMDCT_BW_MS, bfi, MCT_flag ); + IGFDecApplyStereo_flt( sts[0]->hIGFDec, sts[1]->hIGFDec, x[0][k], x[1][k], igfGridIdx, coreMsMask, hStereoMdct->IGFStereoMode[k] == SMDCT_BW_MS, bfi, MCT_flag ); } return; diff --git a/lib_dec/dec_tcx_fx.c b/lib_dec/dec_tcx_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..076abe402f40b0137521b35c0bc918c22c3982b3 --- /dev/null +++ b/lib_dec/dec_tcx_fx.c @@ -0,0 +1,2385 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include +#include +#include +#include "prot_fx1.h" +#include "prot_fx2.h" +#include "basop_util.h" +#include "stl.h" +#include "options.h" + +extern const Word16 T_DIV_L_Frame[];/*0Q15 * 2^-7 */ + +static Word32 CalculateAbsEnergy( /* o : normalized result Q31 */ + const Word32 L_off, /* i : initial sum value Qn */ + const Word16 x[], /* i : x vector Qn */ + const Word16 lg, /* i : vector length, range [0..7FFF] Q0 */ + Word16 * exp /* o : exponent of result in [-32,31] Q0 */ +); + +static void IMDCT(Word32 *x, Word16 x_e, + Word16 *old_syn_overl, + Word16 *syn_Overl_TDAC, + Word16 *xn_buf, + const Word16 *tcx_aldo_window_1, + const PWord16 *tcx_aldo_window_1_trunc, + const PWord16 *tcx_aldo_window_2, + const PWord16 *tcx_mdct_window_half, + const PWord16 *tcx_mdct_window_minimum, + const PWord16 *tcx_mdct_window_trans, + Word16 tcx_mdct_window_half_length, + Word16 tcx_mdct_window_min_length, + Word16 index, + Word16 left_rect, + Word16 tcx_offset, + Word16 overlap, + Word16 L_frame, + Word16 L_frameTCX, + Word16 L_spec_TCX5, + Word16 L_frame_glob, + Word16 frame_cnt, + Word16 bfi, + Word16 *old_out, + Word16 *Q_old_wtda, + Decoder_State *st + ,Word16 fullbandScale + ,Word16 *acelp_zir + ); + + +void decoder_tcx( + TCX_CONFIG_HANDLE hTcxCfg, + Word16 prm[], /* input: parameters */ + Word16 A[], /* input: coefficients NxAz[M+1] */ + Word16 Aind[], /* input: frame-independent coefficients Az[M+1] */ + Word16 L_frame_glob, /* input: frame length */ + Word16 L_frameTCX_glob, + Word16 L_spec, + Word16 synth[], /* in/out: synth[-M-LFAC..L_frame] */ + Word16 synthFB[], + Decoder_State *st, + Word16 coder_type, /* input : coder type */ + Word16 bfi, /* input: Bad frame indicator */ + Word16 frame_cnt, /* input: frame counter in the super frame */ + Word16 stab_fac /* input: stability of isf (1Q14) */ +) +{ + Word16 i, index, L_frame, tcx_offset; + Word16 L_frameTCX, tcx_offsetFB; + Word16 firstLine; + Word16 gain_tcx, gain_tcx_e, fac_ns; + Word16 Ap[M+2]; + Word32 x[N_MAX]; + Word16 x_e; + Word16 *xn_buf; + Word16 xn_bufFB[L_MDCT_OVLP_MAX+L_FRAME_PLUS+L_MDCT_OVLP_MAX]; + Word32 xn_buf32[N_MAX]; + Word16 overlap; + Word16 overlapFB; + Word16 noiseFillingSize; + Word16 noiseTransWidth; + Word16 tnsSize; /* number of tns parameters put into prm */ + Word8 fUseTns; /* flag that is set if TNS data is present */ + STnsData tnsData; + Word16 left_rect; + Word16 gainlpc2[FDNS_NPTS]; + Word16 gainlpc2_e[FDNS_NPTS]; + Word16 noiseTiltFactor; + Word16 nf_seed; + Word16 tmp1, tmp2, s, *tmpP16; + Word8 tmp8; + Word32 tmp32; + Word16 gamma1; + Word16 gamma; + Word16 gainCompensate, gainCompensate_e; + Word16 h1[L_FRAME_MAX/4+1]; + Word16 mem[M]; + Word16 temp_concealment_method = 0; + Word16 arith_bits, signaling_bits; + Word16 *prm_ltp, *prm_tns, *prm_hm, *prm_sqQ, *prm_target; + Word16*pInfoTCXNoise; + Word16 acelp_zir[L_FRAME_MAX/2]; + Word16 noise_filling_index; + Word16 infoIGFStartLine; + Word16 L_spec_con; + TCX_LTP_DEC_HANDLE hTcxLtpDec; + TCX_DEC_HANDLE hTcxDec; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; + Flag Carry = 0; +#endif + + hTcxLtpDec = st->hTcxLtpDec; + hTcxDec = st->hTcxDec; + + prm_target = NULL; /* just to suppress MSVC warnigs */ + + + x_e = 0; /* to avoid compilation warnings */ + nf_seed = 0; /* to avoid compilation warnings */ + + + + /* Overlay xn_buf32 with xn_buf */ + xn_buf = (Word16 *) xn_buf32; + + noiseTransWidth = MIN_NOISE_FILLING_HOLE; + move16(); + tnsSize = 0; + move16(); + fUseTns = 0; + move16(); + gainCompensate = 32768/2; + move16(); + gainCompensate_e = 1; + move16(); + FOR (i=0 ; i < (L_MDCT_OVLP_MAX+L_FRAME_PLUS+L_MDCT_OVLP_MAX)/2; i++) + { + xn_buf32[i] = L_deposit_l(0); + } + + + /* Init lengths */ + + overlap = hTcxCfg->tcx_mdct_window_length; + move16(); + overlapFB = hTcxCfg->tcx_mdct_window_lengthFB; + move16(); + /* Modified the overlap to the delay in case of short blocks*/ + tcx_offset = hTcxCfg->tcx_offset; + move16(); + tcx_offsetFB = hTcxCfg->tcx_offsetFB; + move16(); + L_spec_con = L_spec; + move16(); + gamma1 = st->gamma; + move16(); + + if (hTcxDec->enableTcxLpc != 0) + { + gamma1 = 0x7FFF; + move16(); + } + + IF (bfi != 0) + { + /* PLC: [TCX: Memory update] + * PLC: Init buffers */ + + assert(st->L_frame_past > 0); + L_frame = st->L_frame_past; + move16(); + L_frameTCX = st->L_frameTCX_past; + move16(); + + left_rect = st->prev_widow_left_rect; + move16(); + + IF (left_rect != 0) + { + tcx_offset = hTcxCfg->lfacNext; + move16(); + tcx_offsetFB = hTcxCfg->lfacNextFB; + move16(); + L_spec = add(L_spec, shr(st->hTcxCfg->tcx_coded_lines, 2)); + L_spec_con = add(L_spec_con, shr(st->hTcxCfg->tcx_coded_lines, 2)); + } + } + ELSE + { + test(); + IF ( frame_cnt == 0 && st->last_core == ACELP_CORE ) + { + if (st->prev_bfi == 0) + { + hTcxCfg->last_aldo = 0; + move16(); + } + + /* if past frame is ACELP */ + L_frame = add(L_frame_glob, tcx_offset); + L_frameTCX = add(L_frameTCX_glob, tcx_offsetFB); + L_spec_con = add(L_spec_con, shr(st->hTcxCfg->tcx_coded_lines, 2)); + assert(hTcxCfg->lfacNext<=0); + L_frame = sub(L_frame , hTcxCfg->lfacNext); + L_frameTCX = sub(L_frameTCX, hTcxCfg->lfacNextFB); + tcx_offset = hTcxCfg->lfacNext; + move16(); + tcx_offsetFB = hTcxCfg->lfacNextFB; + move16(); + left_rect = 1; + move16(); + st->prev_widow_left_rect = 1; + move16(); + } + ELSE + { + + L_frame = L_frame_glob; + move16(); + L_frameTCX = L_frameTCX_glob; + move16(); + left_rect = 0; + move16(); + st->prev_widow_left_rect = 0; + move16(); + } + + IF ( frame_cnt == 0 && EQ_16(st->last_core_bs_fx, ACELP_CORE) ) + { + L_spec += st->hTcxCfg->tcx_coded_lines >> 2; + } + + st->L_frame_past = L_frame; + move16(); + st->L_frameTCX_past = L_frameTCX; + move16(); + } + + test(); + IF ( (EQ_16(L_frame, shr(st->L_frame, 1)))&&(st->tcxonly)) + { + IGFDecUpdateInfo( st->hIGFDec,IGF_GRID_LB_SHORT); + } + ELSE + { + test(); + test(); + IF ((EQ_16(st->last_core, ACELP_CORE))||(left_rect&&st->bfi)) + { + IGFDecUpdateInfo(st->hIGFDec,IGF_GRID_LB_TRAN); + } + ELSE + { + IGFDecUpdateInfo(st->hIGFDec,IGF_GRID_LB_NORM); + } + } + + IF (0 == st->igf) + { + IF (st->narrowBand == 0) + { + /* minimum needed for output with sampling rates lower then the + nominal sampling rate */ + infoIGFStartLine = s_min(L_frameTCX, L_frame); + move16(); + } + ELSE + { + infoIGFStartLine = L_frameTCX; + move16(); + } + } + ELSE + { + infoIGFStartLine = s_min(st->hIGFDec->infoIGFStartLine,L_frameTCX); + move16(); + } + + noiseFillingSize = L_spec; + move16(); + if (st->igf != 0) + { + noiseFillingSize = st->hIGFDec->infoIGFStartLine; + move16(); + } + + + prm_ltp = &prm[1+NOISE_FILL_RANGES]; + move16(); + prm_tns = prm_ltp + LTPSIZE; + move16(); + + /*-----------------------------------------------------------* + * Read TCX parameters * + *-----------------------------------------------------------*/ + + index = 0; + move16(); + + IF (bfi == 0) + { + + index = prm[0]; + move16(); + + /* read noise level (fac_ns) */ + + noise_filling_index = prm[1]; + move16(); + + fac_ns = extract_l(L_shr(L_mult0(noise_filling_index, 0x6000), NBITS_NOISE_FILL_LEVEL)); + } + ELSE + { + fac_ns = 0; + move16(); + } + + /* read TNS data */ + test(); + IF ((bfi == 0) && (hTcxCfg->fIsTNSAllowed != 0)) + { + cast16(); + + fUseTns = (Word8)DecodeTnsData(hTcxCfg->pCurrentTnsConfig, + prm_tns, + &tnsSize, + &tnsData); + } + ELSE + { + fUseTns = 0; + move16(); + } + + prm_hm = prm_tns + tnsSize; + move16(); + prm_sqQ = prm_hm + NPRM_CTX_HM; + move16(); + + /*-----------------------------------------------------------* + * Spectrum data * + *-----------------------------------------------------------*/ + + IF (bfi == 0) + { + + /*-----------------------------------------------------------* + * Context HM * + *-----------------------------------------------------------*/ + test(); + test(); + IF(hTcxCfg->ctx_hm != 0 && ( (st->last_core_bs_fx != ACELP_CORE) || (frame_cnt > 0) ) ) + { + st->last_ctx_hm_enabled = prm_hm[0]; + move16(); + { + FOR (i = 0; i < L_spec; i++) /* no context harmonic model, copy MDCT coefficients to x */ + { + + x[i] = L_mult(prm_sqQ[i], + 1 << (30 - SPEC_EXP_DEC)); + move32(); + } + } + x_e = SPEC_EXP_DEC; + move16(); + } + ELSE /* hTcxCfg->ctx_hm == 0 */ + { + + IF (hTcxDec->tcx_lpc_shaped_ari != 0) /* low rates: new arithmetic coder */ + { + prm_target = prm_sqQ; + move16(); + prm_sqQ = prm_target + 1; + move16(); + + tmp8 = 1; + move16(); + if (EQ_16(st->last_core_bs_fx, ACELP_CORE)) + { + tmp8 = 0; + move16(); + } + + tcx_arith_decode_envelope( + x, &x_e, + L_frame, + L_spec, + st, + Aind, + *prm_target, + prm_sqQ, + tmp8, + prm_hm, /* HM parameter area */ + hTcxDec->tcx_hm_LtpPitchLag, + &arith_bits, + &signaling_bits, + &nf_seed, + shr(st->bwidth, 1) /* equivalent to: (st->bwidth > WB)?1:0 */ + ); + + hTcxDec->resQBits[frame_cnt] = sub(*prm_target, arith_bits); + move16(); + } + ELSE /* TCX-only: old arithmetic coder */ + { + FOR (i = 0; i < L_spec; i++) + { + + x[i] = L_mult(prm_sqQ[i], + 1 << (30 - SPEC_EXP_DEC)); + move32(); + } + + set32_fx(x+L_spec, 0, sub(L_frameTCX, L_spec)); + + x_e = SPEC_EXP_DEC; + move16(); + } + + } /* else of if hTcxCfg->ctx_hm */ + tmp1 = s_max(L_frame, L_frameTCX); + tmp1 = s_max(tmp1, L_spec_con); + set32_fx(x+L_spec, 0, sub(tmp1, L_spec)); + + + /*-----------------------------------------------------------* + * adaptive low frequency deemphasis. * + *-----------------------------------------------------------*/ + + weight_a_fx(A, Ap, gamma1, M); + + lpc2mdct(Ap, M, NULL, NULL, gainlpc2, gainlpc2_e, FDNS_NPTS, 0); + + + /* initialize LF deemphasis factors in xn_buf */ + tmp1 = s_max(L_spec, L_frameTCX); + set16_fx(xn_buf, 0x4000, tmp1); + + IF (st->tcxonly == 0) + { + AdaptLowFreqDeemph( x, x_e, hTcxDec->tcx_lpc_shaped_ari, gainlpc2, gainlpc2_e, + L_frame, xn_buf /* LF deemphasis factors */ ); + } + } + + /* Global Gain */ + hTcxDec->damping = 0; + + IF(bfi==0) + { + /*-----------------------------------------------------------* + * Compute global gain * + *-----------------------------------------------------------*/ + + tmp32 = L_shl(L_mult0(index, 0x797D), 7); /* 6Q25; 0x797D -> log2(10)/28 (Q18) */ + gain_tcx_e = add(extract_l(L_shr(tmp32, 25)), 1); /* get exponent */ + gain_tcx = round_fx(BASOP_Util_InvLog2(L_or(tmp32, 0xFE000000))); + +#ifdef BASOP_NOGLOB + tmp1 = mult_r(shl_sat(L_spec, 5), 26214/*128.f/NORM_MDCT_FACTOR Q15*/); +#else + tmp1 = mult_r(shl(L_spec, 5), 26214/*128.f/NORM_MDCT_FACTOR Q15*/); +#endif + s = 15-5-7; + if(L_spec>=1024) /*reduce precision for avoiding overflow*/ + { + tmp1 = mult_r(shl(L_spec, 4), 26214/*128.f/NORM_MDCT_FACTOR Q15*/); + s = 15-4-7; + } + tmp1 = ISqrt16(tmp1, &s); + + gain_tcx = mult(gain_tcx, tmp1); + gain_tcx_e = add(gain_tcx_e, s); + + hTcxDec->old_gaintcx_bfi = gain_tcx; + move16(); + hTcxDec->old_gaintcx_bfi_e = gain_tcx_e; + move16(); + + hTcxDec->cummulative_damping_tcx = 32767/*1.0f Q15*/; + move16(); + } + ELSE /* bfi = 1 */ + { + /* PLC: [TCX: Fade-out] + * derivation of damping factor */ + + + IF( st->use_partial_copy != 0 ) + { + IF( EQ_16(st->rf_frame_type, RF_TCXFD)) + { + tmp32 = L_shl(L_mult0(hTcxDec->old_gaintcx_bfi, 0x797D), 7); /* 6Q25; 0x797D -> log2(10)/28 (Q18) */ + gain_tcx_e = add(extract_l(L_shr(tmp32, 25)), 1); /* get exponent */ + gain_tcx = round_fx(BASOP_Util_InvLog2(L_or(tmp32, 0xFE000000))); + + tmp1 = mult_r(shl(L_spec, 5), 26214/*128.f/NORM_MDCT_FACTOR Q15*/); + s = 15-5-7; + tmp1 = ISqrt16(tmp1, &s); + + gain_tcx = mult(gain_tcx, tmp1); + gain_tcx_e = add(gain_tcx_e, s); + + hTcxDec->old_gaintcx_bfi = gain_tcx; + move16(); + hTcxDec->old_gaintcx_bfi_e = gain_tcx_e; + move16(); + } + ELSE + { + gain_tcx = hTcxDec->old_gaintcx_bfi; + move16(); + gain_tcx_e = hTcxDec->old_gaintcx_bfi_e; + move16(); + } + + hTcxDec->damping = 16384/*1.f Q14*/; /*Q14*/ move16(); + } + ELSE + { + hTcxDec->damping = Damping_fact(coder_type, st->nbLostCmpt, st->last_good_fx, stab_fac, &(st->Mode2_lp_gainp), st->last_core); + gain_tcx = hTcxDec->old_gaintcx_bfi; + move16(); + gain_tcx_e = hTcxDec->old_gaintcx_bfi_e; + move16(); + } + + hTcxDec->cummulative_damping_tcx = shl(mult(hTcxDec->cummulative_damping_tcx,hTcxDec->damping),1);/*shl(Q15*Q14,1)=shl(Q14,1) = Q15*/ + + } + { + IF(bfi) + { + gamma = gamma1; + move16(); + if (hTcxDec->envWeighted) + { + gamma = st->gamma; + move16(); + } + + /* PLC: [TCX: Fade-out] + * PLC: invert LPC weighting in case of PLC */ + IF (hTcxDec->enableTcxLpc != 0) + { + gamma = add(mult_r(hTcxDec->cummulative_damping_tcx,sub(st->gamma, 32767/*1.0f Q15*/)), 32767/*1.0f Q15*/); + } + ELSE + { + gamma = add(mult_r(hTcxDec->cummulative_damping_tcx,sub(gamma1, 32767/*1.0f Q15*/)), 32767/*1.0f Q15*/); + } + weight_a_fx(A, Ap, gamma, M); + + lpc2mdct(Ap, M, NULL, NULL, gainlpc2, gainlpc2_e, FDNS_NPTS, 0); + + } + tmp2 = 0; + move16(); + + set16_fx(h1, 0, add(L_SUBFR,1)); + set16_fx(mem, 0, M); + h1[0] = 32768/32; + move16(); + E_UTIL_synthesis(0,Ap, h1, h1, L_SUBFR, mem, 0, M ); + deemph_fx(h1, st->preemph_fac, L_SUBFR, &tmp2); + /* impulse response level = gain introduced by synthesis+deemphasis */ + test(); + IF (bfi==0) + { + /* st->last_gain_syn_deemph = (float)sqrt(dot_product( h1, h1, L_SUBFR)); */ + tmp32 = Dot_productSq16HQ( 0, h1, L_SUBFR, &st->last_gain_syn_deemph_e)/*Q15, st->last_gain_syn_deemph_e*/; + st->last_gain_syn_deemph_e = add(st->last_gain_syn_deemph_e,10/*scaling of h1[0] and E_UTIL_synthesis * 2*/); + tmp32 = Sqrt32(tmp32,&st->last_gain_syn_deemph_e); +#ifdef BASOP_NOGLOB + st->last_gain_syn_deemph = round_fx_o(tmp32, &Overflow); +#else + st->last_gain_syn_deemph = round_fx(tmp32); +#endif + /*for avoiding compiler warnings*/ + hTcxDec->gainHelper = 32768/2; + move16(); + hTcxDec->gainHelper_e = 1; + move16(); + hTcxDec->stepCompensate = 0; + move16(); + hTcxDec->stepCompensate_e = 0; + move16(); + } + /* not instrumenting the additional test() here seems to be common practice */ + ELSE IF (EQ_16(TCX_20_CORE, st->core)||EQ_16(frame_cnt,1)) + { + /* gainCompensate = st->last_gain_syn_deemph/(float)sqrt(dot_product( h1, h1, L_SUBFR)); */ + tmp32 = Dot_productSq16HQ( 0, h1, L_SUBFR, &gainCompensate_e)/*Q15, gainCompensate_e*/; + gainCompensate_e = add(gainCompensate_e,10/*scaling of h1[0] and E_UTIL:synthesis*/); + gainCompensate = round_fx(Sqrt32(tmp32,&gainCompensate_e))/*Q15, gainCompensate_e*/; + BASOP_Util_Divide_MantExp ( st->last_gain_syn_deemph, + st->last_gain_syn_deemph_e, + gainCompensate, + gainCompensate_e, + &gainCompensate, + &gainCompensate_e); + + tmp1 = T_DIV_L_Frame[L_shl(L_mac(-28000,st->L_frame,95),1-15)]; + + IF (EQ_16(st->nbLostCmpt,1)) + { + /* stepCompensate = (1.f - gainCompensate)/st->L_frame; */ + hTcxDec->stepCompensate_e = BASOP_Util_Add_MantExp( + tmp1, + -7, + negate(mult(gainCompensate,tmp1)), + add(-7,gainCompensate_e), + &hTcxDec->stepCompensate); + + hTcxDec->gainHelper = 32768/2; + move16(); + hTcxDec->gainHelper_e = 1; + move16(); + } + ELSE + { + /* stepCompensate = (st->last_concealed_gain_syn_deemph - gainCompensate)/st->L_frame; */ + hTcxDec->stepCompensate_e = BASOP_Util_Add_MantExp( + mult(tmp1,st->last_concealed_gain_syn_deemph), + add(-7, st->last_concealed_gain_syn_deemph_e), + negate(mult(tmp1,gainCompensate)), + add(-7, gainCompensate_e), + &hTcxDec->stepCompensate); + move16(); + move16(); + hTcxDec->gainHelper = st->last_concealed_gain_syn_deemph; + hTcxDec->gainHelper_e = st->last_concealed_gain_syn_deemph_e; + } + move16(); + move16(); + st->last_concealed_gain_syn_deemph = gainCompensate; + st->last_concealed_gain_syn_deemph_e = gainCompensate_e; + } + + } + + + /*-----------------------------------------------------------* + * Residual inv. Q. * + *-----------------------------------------------------------*/ + test(); + IF ((bfi == 0) && (hTcxCfg->resq != 0)) + { + + IF (hTcxDec->tcx_lpc_shaped_ari != 0) /* new arithmetic coder */ + { + + Word16 *prm_resq; + + prm_resq = prm_sqQ + + *prm_target /* = targetBits */ + - hTcxDec->resQBits[frame_cnt]; + + i = tcx_ari_res_invQ_spec(x, x_e, L_spec, + prm_resq, + hTcxDec->resQBits[frame_cnt], + 0, + hTcxCfg->sq_rounding, + xn_buf /* LF deemphasis factors */ ); + } + ELSE /* old arithmetic coder */ + { + i = tcx_res_invQ_gain(&gain_tcx, &gain_tcx_e, &prm_sqQ[L_spec], hTcxDec->resQBits[frame_cnt]); + + tmpP16 = xn_buf; + if (st->tcxonly != 0) tmpP16 = NULL; + + tcx_res_invQ_spec(x, x_e, L_spec, &prm_sqQ[L_spec],hTcxDec->resQBits[frame_cnt],i,hTcxCfg->sq_rounding,tmpP16 /* LF deemphasis factors */ ); + } + } + test(); + IF (bfi == 0 && st->tcxonly != 0) + { + test(); + test(); + IF (hTcxLtpDec->tcxltp && (hTcxLtpDec->tcxltp_gain > 0) && !fUseTns) + { + + PsychAdaptLowFreqDeemph(x, gainlpc2, gainlpc2_e, NULL); + } + } + + /* for FAC */ + + test(); + IF (bfi == 0 && st->tcxonly == 0) + { + + + /* Replication of ACELP formant enhancement for low rates */ + IF (LT_32(st->total_brate, ACELP_13k20)||st->rf_flag!=0) + { + tcxFormantEnhancement(xn_buf, gainlpc2, gainlpc2_e, x, &x_e, L_frame, L_frameTCX); + } + } + + /*-----------------------------------------------------------* + * Add gain to the lpc gains * + *-----------------------------------------------------------*/ + + if(st->VAD==0 ) + { + gain_tcx = mult_r(gain_tcx, hTcxCfg->na_scale); + } + + i = norm_s(gain_tcx); + gain_tcx = shl(gain_tcx, i); + gain_tcx_e = sub(gain_tcx_e, i); + FOR (i = 0; i < FDNS_NPTS; i++) + { + gainlpc2[i] = mult_r(gainlpc2[i], gain_tcx); + move16(); + } + + + /*-----------------------------------------------------------* + * Noise filling. * + *-----------------------------------------------------------*/ + + test(); + IF (bfi==0 && (fac_ns > 0)) + { + + tmp1 = 0; + move16(); + test(); + if ( GE_16(st->bits_frame, 256)&&st->rf_flag==0) + { + tmp1 = 1; + move16(); + } + + firstLine = tcxGetNoiseFillingTilt( A, M, L_frame, tmp1, &noiseTiltFactor ); + + IF (st->tcxonly != 0) + { + tmp1 = 0; + move16(); + test(); + test(); + if ((hTcxCfg->ctx_hm != 0) && (st->last_core != ACELP_CORE) && (st->last_ctx_hm_enabled != 0)) + { + tmp1 = 10240/*0.3125f Q15*/; + move16(); + } + noiseTransWidth = HOLE_SIZE_FROM_LTP(s_max(hTcxLtpDec->tcxltp_gain, tmp1)); + + if (EQ_16(L_frame, shr(st->L_frame, 1))) + { + noiseTransWidth = 3; /* minimum transition fading for noise filling in TCX-10 */ move16(); + } + } + + + IF (hTcxDec->tcx_lpc_shaped_ari == 0) /* old arithmetic coder */ + { + /* noise filling seed */ + tmp32 = L_deposit_l(0); + FOR (i = 0; i < L_spec; i++) + { +#ifdef BASOP_NOGLOB + tmp32 = L_macNs_co(tmp32, abs_s(prm_sqQ[i]), i, &Carry, &Overflow); +#else + tmp32 = L_macNs(tmp32, abs_s(prm_sqQ[i]), i); +#endif + } + nf_seed = extract_l(tmp32); + } + + tmp1 = nf_seed; + move16(); + + pInfoTCXNoise = NULL; + if (st->igf) + { +#if 0 + //pointer changed from 8bit to 16bit +#endif + + pInfoTCXNoise = st->hIGFDec->infoTCXNoise_evs; + move16(); + } + tcx_noise_filling(x, x_e,tmp1 /* seed */, firstLine, noiseFillingSize, noiseTransWidth, L_frame, noiseTiltFactor, + fac_ns, pInfoTCXNoise, st->element_mode); + st->seed_tcx_plc = tmp1; + move16(); + } + + IF (st->enablePlcWaveadjust) + { + IF (bfi) + { + IF (EQ_16(st->nbLostCmpt, 1)) + { + st->plcInfo.concealment_method = TCX_NONTONAL; + move16(); + /* tonal/non-tonal decision */ + test(); + test(); + IF (EQ_16(st->plcInfo.Transient[0],1) + && EQ_16(st->plcInfo.Transient[1], 1) + && EQ_16(st->plcInfo.Transient[2], 1)) + { + Word16 sum_word16 = 0; + move16(); + + FOR (i = 9; i >= 0; i--) + { + sum_word16 = add(sum_word16, st->plcInfo.TCX_Tonality[i]); + } + + if(GE_16(sum_word16, 6)) + { + st->plcInfo.concealment_method = TCX_TONAL; + move16(); + } + } + + if(st->tonal_mdct_plc_active) + { + st->plcInfo.concealment_method = TCX_TONAL; + move16(); + } + } + + if (GT_16(L_frameTCX, hTcxDec->L_frameTCX)) + { + st->plcInfo.concealment_method = TCX_TONAL; + move16(); + } + + temp_concealment_method = st->plcInfo.concealment_method; + move16(); + + if (EQ_16(st->core, TCX_10_CORE)) + { + temp_concealment_method = TCX_TONAL; + move16(); + } + } + /* get the starting location of the subframe in the frame */ + IF (EQ_16(st->core, TCX_10_CORE)) + { + st->plcInfo.subframe_fx =extract_l( L_mult0(frame_cnt,L_frameTCX_glob)); + } + } + + /* PLC: [TCX: Tonal Concealment] */ + /* PLC: [TCX: Fade-out] + * PLC: Fade out to white noise */ + + IF (bfi == 0) + { + TonalMDCTConceal_SaveFreqSignal(&st->tonalMDCTconceal,x, x_e, L_frameTCX, + L_frame, gainlpc2, gainlpc2_e, gain_tcx_e); + } + ELSE + { + test(); + IF( !st->enablePlcWaveadjust || EQ_16(temp_concealment_method, TCX_TONAL)) + { + Word16 f, tmp; + + /* set f to 1 to not fade out */ + /* set f to 0 to immediately switch to white noise */ + f = hTcxDec->cummulative_damping_tcx; + move16(); + if (0 != st->tcxonly) + { + f = 32767/*1.0f Q15*/; + move16(); + } + + test(); + test(); + IF ( (frame_cnt == 0) && (EQ_16(L_frameTCX, shr(hTcxDec->L_frameTCX, 1))) + && (st->tcxonly) && (!st->tonal_mdct_plc_active) && (EQ_16(st->nbLostCmpt, 1)) + && (hTcxCfg->tcx_last_overlap_mode != FULL_OVERLAP) + && (hTcxCfg->tcx_curr_overlap_mode != FULL_OVERLAP) ) + { + Word16 exp1, exp2; + Word32 E_2ndlast, E_last; + + E_2ndlast = CalculateAbsEnergy(1, &(st->tonalMDCTconceal.lastBlockData.spectralData[0]), infoIGFStartLine, &exp2); + E_last = CalculateAbsEnergy(1, &(st->tonalMDCTconceal.lastBlockData.spectralData[1]), infoIGFStartLine, &exp1); + + BASOP_Util_Divide_MantExp(extract_h(E_2ndlast), exp2, extract_h(E_last), exp1, &tmp1, &tmp2); + + tmp1 = shr(tmp1,2); /*Q13*/ +#ifdef BASOP_NOGLOB + tmp1 = shl_sat(tmp1,tmp2); +#else + tmp1 = shl(tmp1,tmp2); +#endif + test(); + test(); + /* replace higher energy TCX5 frame by lower one to avoid energy fluctuation */ + IF(GT_16(tmp1,16384 /*2 in Q13*/)) + { + FOR(i=0; itonalMDCTconceal.lastBlockData.spectralData[i] = st->tonalMDCTconceal.lastBlockData.spectralData[i+1]; + } + } + ELSE IF(LT_16(tmp1,4096/*0.5 in Q13*/)) + { + FOR(i=0; itonalMDCTconceal.lastBlockData.spectralData[i+1] = st->tonalMDCTconceal.lastBlockData.spectralData[i]; + } + } + } + + noiseTiltFactor = 32767/*1.0f Q15*/; + move16(); + + tmp = 0; + move16(); + test(); + IF( GE_16(st->bits_frame, 256)&&st->rf_flag==0) + { + tmp = 1; + move16(); + } + + tcxGetNoiseFillingTilt( A, M, L_frame, tmp, &noiseTiltFactor ); + + TonalMDCTConceal_InsertNoise(&st->tonalMDCTconceal, x, &x_e, st->tonal_mdct_plc_active, &st->seed_tcx_plc, + noiseTiltFactor, f, +#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT + concealment_noise, +#endif + infoIGFStartLine ); + + } + } + + + IF (LT_16(L_spec, L_frame)) + { + set32_fx(x+L_spec, 0, sub(L_frame,L_spec)); + } + ELSE IF (GT_16(L_spec, L_frameTCX)) + { + set32_fx(x+L_frameTCX, 0, sub(L_spec,L_frameTCX)); + } + + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF ( bfi && (!st->enablePlcWaveadjust || EQ_16(temp_concealment_method, TCX_TONAL)) + && st->igf && (frame_cnt == 0) && (EQ_16(L_frameTCX, shr(hTcxDec->L_frameTCX, 1))) + && (st->tcxonly) && (!st->tonal_mdct_plc_active) && (EQ_16(st->nbLostCmpt, 1)) + && (hTcxCfg->tcx_last_overlap_mode != FULL_OVERLAP) + && (hTcxCfg->tcx_curr_overlap_mode != FULL_OVERLAP) ) + { + IGFDecCopyLPCFlatSpectrum( st->hIGFDec, x, x_e, IGF_GRID_LB_SHORT ); + Copy(st->hIGFDec->igfData.igf_curr_subframe[0][0], st->hIGFDec->igfData.igf_curr_subframe[1][0], IGF_MAX_SFB); + } + + /*-----------------------------------------------------------* + * Noise shaping in frequency domain (1/Wz) * + *-----------------------------------------------------------*/ + test(); + IF(st->igf && ! bfi) + { + test(); + IF ( (EQ_16(L_frame, shr(st->L_frame, 1)))&&(st->tcxonly)) + { + IGFDecCopyLPCFlatSpectrum( st->hIGFDec, x, x_e, IGF_GRID_LB_SHORT); + } + ELSE + { + IF (EQ_16(st->last_core, ACELP_CORE)) + { + IGFDecCopyLPCFlatSpectrum(st->hIGFDec, x, x_e, IGF_GRID_LB_TRAN ); + } + ELSE + { + IGFDecCopyLPCFlatSpectrum(st->hIGFDec, x, x_e, IGF_GRID_LB_NORM ); + } + } + } + + /* LPC gains already available */ + test(); + test(); + IF(!st->enablePlcWaveadjust || !bfi || (EQ_16(temp_concealment_method, TCX_TONAL))) + { + x_e = add(x_e, gain_tcx_e); + mdct_shaping(x, L_frame, gainlpc2, gainlpc2_e); + IF ( bfi == 0 ) + { + FOR (i = L_frame; i < L_spec; i++) + { + x[i] = L_shl(Mpy_32_16_1(x[i], gainlpc2[FDNS_NPTS-1]), gainlpc2_e[FDNS_NPTS-1]); + move32(); + } + } + + set32_fx(x+L_spec, 0, sub(L_frameTCX, L_spec)); + test(); + test(); + IF (( bfi != 0) && ( !st->enablePlcWaveadjust || EQ_16(temp_concealment_method, TCX_TONAL))) + { + scale_sig32(x+infoIGFStartLine, sub(L_spec, infoIGFStartLine), negate(gain_tcx_e)); + } + } + + /* PLC: [TCX: Tonal Concealment] */ + IF( bfi && st->tonal_mdct_plc_active ) + { + TonalMDCTConceal_Apply(&st->tonalMDCTconceal, x, &x_e); + } + + tmp32 = L_deposit_h(0); + if(hTcxDec->tcxltp_last_gain_unmodified > 0) + { + tmp32 = L_add(st->old_fpitch, 0); + } + tmp8 = 0; + move16(); + test(); + if(bfi && st->tonal_mdct_plc_active) + { + tmp8 = 1; + move16(); + } + TonalMDCTConceal_UpdateState(&st->tonalMDCTconceal, + L_frameTCX, + tmp32, + bfi, + tmp8); + + IF (st->enablePlcWaveadjust) + { + Word16 core; + core = st->core; + move16(); + /* spectrum concealment */ + IF (bfi && (EQ_16(temp_concealment_method, TCX_NONTONAL))) + { + /* x_e =31-x_scale; */ + concealment_decode_fix(core, x, &x_e, &st->plcInfo); + } + /* update spectrum buffer, tonality flag, etc. */ + concealment_update_x(bfi, core, st->tonality_flag, x, &x_e, &st->plcInfo); + } + + /*-----------------------------------------------------------* + * IGF * + *-----------------------------------------------------------*/ + test(); + test(); + IF (st->igf && !((EQ_16(L_frame, shr(st->L_frame, 1)))&&(st->tcxonly))) + { + Word16 igfGridIdx; + + test(); + test(); + IF ((EQ_16(st->last_core, ACELP_CORE))||(left_rect&&bfi)) + { + /* packet loss after first TCX must be handled like transition frame */ + igfGridIdx = IGF_GRID_LB_TRAN; + } + ELSE + { + igfGridIdx = IGF_GRID_LB_NORM; + } + + *st->hIGFDec->igfData.igfInfo.nfSeed = extract_l(L_mac0(13849L, nf_seed, 31821)); + IGFDecApplyMono(st->hIGFDec, x, &x_e, igfGridIdx, bfi); + } + test(); + test(); + IF (st->igf && ((EQ_16(L_frame, shr(st->L_frame, 1)))&&(st->tcxonly))) + { + *st->hIGFDec->igfData.igfInfo.nfSeed = extract_l(L_mac0(13849L, nf_seed, 31821)); + IGFDecApplyMono(st->hIGFDec,x,&x_e,IGF_GRID_LB_SHORT,bfi); + } + + index = hTcxCfg->tcx_last_overlap_mode; /* backup last TCX overlap mode */ move16(); + + /* normalize spectrum to minimize IMDCT noise */ + tmp1 = s_max(s_max(L_frame,L_frameTCX), L_spec); + s = s_max(0, sub(getScaleFactor32(x, tmp1), 4)); /* Keep 4 bits headroom for TNS */ + Scale_sig32(x, tmp1, s); + x_e = sub(x_e, s); + + IF(st->igf) + { + test(); + IF(st->hIGFDec->flatteningTrigger != 0 && fUseTns == 0) + { + Word16 startLine = st->hIGFDec->infoIGFStartLine; + Word16 endLine = st->hIGFDec->infoIGFStopLine; + Word32 x_itf[N_MAX_TCX-IGF_START_MN]; + Word16 j; + + const Word16* chk_sparse = st->hIGFDec->flag_sparseBuf; + const Word32* virtualSpec = st->hIGFDec->virtualSpec; + + const Word16 maxOrder = 8; + Word16 curr_order = 0; /* not counted */ + Word16 A_itf[ITF_MAX_FILTER_ORDER+1]; + Word16 Q_A_itf; + Word16 predictionGain = 0; /* not counted */ + + move16(); + move16(); + + move16(); + + FOR (j = startLine; j < endLine; j++) + { + IF (EQ_16(chk_sparse[j-IGF_START_MN], 2)) + { + x_itf[j-IGF_START_MN] = x[j]; + move32(); + x[j] = virtualSpec[j-IGF_START_MN]; + move32(); + } + } + ITF_Detect_fx(x+IGF_START_MN, startLine, endLine, maxOrder, A_itf, &Q_A_itf, &predictionGain, &curr_order, shl(x_e, 1)); + s = getScaleFactor32(&x[startLine], sub(endLine, startLine)); + s = sub(s, 2); + FOR(j = startLine; j < endLine; j++) + { + x[j] = L_shl(x[j], s); + move32(); + } + + ITF_Apply_fx(x, startLine, endLine, A_itf, Q_A_itf, curr_order); + + FOR(j = startLine; j < endLine; j++) + { + x[j] = L_shr(x[j], s); + move32(); + } + + FOR (j = startLine; j < endLine; j++) + { + if (EQ_16(chk_sparse[j-IGF_START_MN],2)) + { + x[j] = x_itf[j-IGF_START_MN]; + move32(); + } + } + } + } + + test(); + IF ((EQ_16(L_frame, shr(st->L_frame, 1)))&&(st->tcxonly!=0)) + { + Word16 L = L_frameTCX; + move16(); + + test(); + test(); + test(); + if ((hTcxCfg->fIsTNSAllowed != 0 && fUseTns != 0 && bfi == 0) || (GT_16(L_spec, L_frameTCX))) + { + L = L_spec; + move16(); + } + + tcxInvertWindowGrouping(hTcxCfg, + xn_buf32, + x, + L, + fUseTns, + st->last_core, + index, + frame_cnt, + bfi + ); + } + + + /*-----------------------------------------------------------* + * Temporal Noise Shaping Synthesis * + *-----------------------------------------------------------*/ + + test(); + test(); + IF ((hTcxCfg->fIsTNSAllowed != 0) && (fUseTns != 0) && bfi == 0 ) + { + /* Apply TNS to get the reconstructed signal */ + test(); + test(); + SetTnsConfig(hTcxCfg, L_frame_glob == st->L_frame, (st->last_core == ACELP_CORE) && (frame_cnt == 0)); + ApplyTnsFilter(hTcxCfg->pCurrentTnsConfig, &tnsData, x, 0); + + test(); + IF ((EQ_16(L_frame, shr(st->L_frame, 1)))&&(st->tcxonly!=0)) + { + + test(); + test(); + test(); + IF ((hTcxCfg->tcx_last_overlap_mode != FULL_OVERLAP) || + ((hTcxCfg->tcx_curr_overlap_mode == FULL_OVERLAP) && (frame_cnt == 0) && (index == 0)) + ) + { + tmp1 = shr(hTcxCfg->tnsConfig[0][0].iFilterBorders[0], 1); + /* undo rearrangement of LF sub-window lines for TNS synthesis filtering */ + IF (s_max(L_frameTCX, L_spec) > hTcxCfg->tnsConfig[0][0].iFilterBorders[0]) + { + tmp2 = shr(s_max(L_frameTCX, L_spec), 1); + Copy32(x+tmp1+8, x+tmp2+8, sub(tmp1, 8)); + Copy32(x+8, x+tmp2, 8); + Copy32(x+16, x+8, sub(tmp1, 8)); + set32_fx(x+tmp1, 0, sub(tmp2, tmp1)); + set32_fx(x+tmp2+tmp1, 0, sub(tmp2, tmp1)); + } + ELSE + { + Copy32(x+8, xn_buf32, 8); + Copy32(x+16, x+8, sub(tmp1,8)); + Copy32(xn_buf32, x+tmp1, 8); + } + + } + } + } + + + /*-----------------------------------------------------------* + * Compute inverse MDCT of x[]. * + *-----------------------------------------------------------*/ + + + Copy32(x, xn_buf32, s_max(s_max(L_frame,L_frameTCX), L_spec)); + + IF(st->igf != 0) + { + set32_fx( xn_buf32+st->hIGFDec->infoIGFStartLine, 0, sub(L_frameTCX, st->hIGFDec->infoIGFStartLine) ); + } + IMDCT(xn_buf32, x_e, hTcxDec->syn_Overl, hTcxDec->syn_Overl_TDAC, xn_buf, hTcxCfg->tcx_aldo_window_1, hTcxCfg->tcx_aldo_window_1_trunc, hTcxCfg->tcx_aldo_window_2, + st->hTcxCfg->tcx_mdct_window_half, hTcxCfg->tcx_mdct_window_minimum, st->hTcxCfg->tcx_mdct_window_trans, st->hTcxCfg->tcx_mdct_window_half_length, hTcxCfg->tcx_mdct_window_min_length, + index, left_rect, tcx_offset, overlap, L_frame, L_frameTCX, shr(s_max(L_frameTCX, L_spec), 1), L_frame_glob, frame_cnt, bfi, st->hHQ_core->old_out_LB_fx, + &st->hHQ_core->Q_old_wtda_LB,st, 0, acelp_zir); + /* Generate additional comfort noise to mask potential coding artefacts */ + IF ( st->flag_cna != 0 ) + { + generate_masking_noise_mdct (x, &x_e, st->hFdCngDec_fx->hFdCngCom, s_max(s_max(L_frame,L_frameTCX), L_spec) ); + } + + IMDCT(x, x_e, hTcxDec->syn_OverlFB, hTcxDec->syn_Overl_TDACFB, xn_bufFB, hTcxCfg->tcx_aldo_window_1_FB, hTcxCfg->tcx_aldo_window_1_FB_trunc, hTcxCfg->tcx_aldo_window_2_FB, + hTcxCfg->tcx_mdct_window_halfFB, hTcxCfg->tcx_mdct_window_minimumFB, hTcxCfg->tcx_mdct_window_transFB, hTcxCfg->tcx_mdct_window_half_lengthFB, hTcxCfg->tcx_mdct_window_min_lengthFB, + index, left_rect, tcx_offsetFB, overlapFB, L_frameTCX, L_frameTCX, shr(s_max(L_frameTCX, L_spec), 1), L_frameTCX_glob, + frame_cnt, bfi, st->hHQ_core->old_out_fx, &st->hHQ_core->Q_old_wtda, st, div_l(L_mult(FSCALE_DENOM, L_frameTCX_glob), L_frame_glob), acelp_zir); + + /* PLC: [TCX: Tonal Concealment] */ + + IF (!bfi) + { + st->second_last_tns_active = st->last_tns_active; + st->last_tns_active = 0; + move16(); + test(); + if ( hTcxCfg->fIsTNSAllowed && fUseTns) + { + st->last_tns_active = 1; + move16(); + } + + hTcxDec->tcxltp_third_last_pitch = hTcxDec->tcxltp_second_last_pitch; + move32(); + hTcxDec->tcxltp_second_last_pitch = st->old_fpitch; + move32(); + st->old_fpitch = L_add(L_deposit_h(hTcxLtpDec->tcxltp_pitch_int), L_mult(hTcxLtpDec->tcxltp_pitch_fr, div_s(1,st->pit_res_max) /*Q16*/)); + st->old_fpitchFB = Mpy_32_16_1(st->old_fpitch/*Q16*/, mult_r(L_frameTCX/*Q0*/,getInvFrameLen(L_frame)/*Q21*/)/*Q6*/)/*Q7*/; + st->old_fpitchFB = L_shr(st->old_fpitchFB,7-16);/*->Q16*/ + } + + + /* Update old_syn_overl */ + IF (st->hTcxCfg->last_aldo == 0) + { + Copy(xn_buf+L_frame, hTcxDec->syn_Overl, overlap); + Copy(xn_bufFB+L_frameTCX, hTcxDec->syn_OverlFB, overlapFB); + } + + /* Output */ + Copy(xn_buf+shr(overlap,1)-tcx_offset, synth, L_frame_glob); + Copy(xn_bufFB+shr(overlapFB,1)-tcx_offsetFB, synthFB, L_frameTCX_glob); + +} + + + +void decoder_tcx_post(Decoder_State *st_fx, + Word16 *synth, + Word16 *synthFB, + Word16 *A, + Word16 bfi + ) +{ + Word16 i; + Word16 level_syn; + Word16 level_syn_e; + Word32 step; + Word16 gainCNG,gainCNG_e; + Word16 xn_buf[L_FRAME_MAX]; + Word16 tmp1, tmp2, s; + Word32 tmp32; + Word32 tmp32_1, tmp32_2; + TCX_DEC_HANDLE hTcxDec; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + + hTcxDec = st_fx->hTcxDec; + + /* TCX output */ + Copy( synth, xn_buf, st_fx->L_frame ); + + /* first TCX frame after ACELP; overwrite ltp initialization done during acelp PLC */ + test(); + test(); + if (!st_fx->bfi && st_fx->prev_bfi && EQ_16(st_fx->last_core,ACELP_CORE)) + { + hTcxDec->tcxltp_last_gain_unmodified = 0; + move16(); + } + IF (bfi != 0 && st_fx->use_partial_copy == 0) + { + test(); + /* run lpc gain compensation not for waveform adjustment */ + IF ( 0 == st_fx->enablePlcWaveadjust || EQ_16(st_fx->plcInfo.concealment_method,TCX_TONAL)) + { + UWord32 dmy; + tmp32_1 /*gainHelperFB*/ = L_shl_r(L_deposit_h(hTcxDec->gainHelper) ,sub(hTcxDec->gainHelper_e, 31-28));/*Q28*/ + tmp32_2 /*stepCompensateFB*/= L_shl_r(L_deposit_h(hTcxDec->stepCompensate),sub(hTcxDec->stepCompensate_e,31-28));/*Q28*/ + + Mpy_32_32_ss(tmp32_2/*Q28*/, + L_shl(L_mult0(st_fx->L_frame, + getInvFrameLen(hTcxDec->L_frameTCX)/*Q21*/)/*Q21*/, + 8)/*Q29*/, + &tmp32_2, + &dmy ); /*Q26*/ + + tmp32_2 = L_shl(tmp32_2,3-1); /*Q28*/ + + FOR( i=0; i < hTcxDec->L_frameTCX; i++ ) + { + tmp32 = L_shl(tmp32_1/*Q28*/,-(28-15)); /*16Q15*/ +#ifdef BASOP_NOGLOB + synthFB[i] = round_fx_sat(L_shl_sat(Mpy_32_16_1(tmp32,synthFB[i]), 16)); +#else + synthFB[i] = round_fx(L_shl(Mpy_32_16_1(tmp32,synthFB[i]), 16)); +#endif + move16(); + tmp32_1 = L_sub(tmp32_1 , tmp32_2); + } + } + tmp32_1 /*gainHelper*/ = L_shl_r(L_deposit_h(hTcxDec->gainHelper) ,sub(hTcxDec->gainHelper_e, 31-28));/*Q28*/ + tmp32_2 /*stepCompensate*/= L_shl_r(L_deposit_h(hTcxDec->stepCompensate),sub(hTcxDec->stepCompensate_e,31-28));/*Q28*/ + FOR( i=0; i < st_fx->L_frame; i++ ) + { + tmp32 = L_shl(tmp32_1/*Q28*/,-(28-15)); /*16Q15*/ + xn_buf[i] = extract_l(Mpy_32_16_1(tmp32,xn_buf[i])); + move16(); + tmp32_1 = L_sub(tmp32_1 , tmp32_2); + } + } + + /* PLC: [TCX: Fade-out] + * PLC: estimate and update CNG energy */ + + /* level_syn = (float)sqrt(( dot_product(synthFB, synthFB, L_frame)) / L_frame ); */ + s = sub(getScaleFactor16(synthFB, hTcxDec->L_frameTCX), 4); + { + Word64 tmp64 = 0; + move64(); + FOR (i = 0; i < hTcxDec->L_frameTCX; i++) + { + tmp1 = shl(synthFB[i], s); + tmp64 = W_mac0_16_16(tmp64, tmp1, tmp1); + } + tmp32 = W_sat_l(tmp64); + } + tmp32 = Mpy_32_16_1(tmp32, getInvFrameLen(hTcxDec->L_frameTCX)); + tmp2 = norm_l(tmp32); +#ifdef BASOP_NOGLOB + tmp1 = round_fx_o(L_shl(tmp32, tmp2), &Overflow); +#else + tmp1 = round_fx(L_shl(tmp32, tmp2)); +#endif + s = sub(sub(sub(1, shl(s, 1)), 6/*table lookup for inverse framelength*/), tmp2); + tmp1 = Sqrt16(tmp1, &s); + move16(); + level_syn = tmp1; /*Q0*/ + + /* PLC: [TCX: Fade-out] + * PLC: estimate and update CNG energy */ + + level_syn_e = add(s,15); + test(); + test(); + IF (bfi == 0 && st_fx->tcxonly != 0 && EQ_16(st_fx->clas_dec , UNVOICED_CLAS)) + { + + Word16 Qnew_levelBackgroundTrace; + Qnew_levelBackgroundTrace = 0; + move16(); + minimumStatistics(hTcxDec->conNoiseLevelMemory, /*Q15*/ + &hTcxDec->conNoiseLevelIndex, /*Q0 */ + &hTcxDec->conCurrLevelIndex, /*Q0 */ + &hTcxDec->conCngLevelBackgroundTrace, /*Q15*/ + &hTcxDec->conLastFrameLevel, /*Q15*/ + level_syn, /*Q15*/ + hTcxDec->conNoiseLevelMemory_e, + hTcxDec->conCngLevelBackgroundTrace_e, + &Qnew_levelBackgroundTrace, + &hTcxDec->conLastFrameLevel_e, + level_syn_e /*scaling of level_syn*/ + ); + + /*note: All parameters being different from Q0 have to have the same Q-format*/ + + hTcxDec->conCngLevelBackgroundTrace_e = Qnew_levelBackgroundTrace; + move16(); + } + + /* PLC: [TCX: Fade-out] + * PLC: fade-out in time domain */ + IF (bfi != 0) + { + Word32 conceal_eof_gain32; + Word32 conceal_eof_gainFB; + move16(); + move16(); + gainCNG = 1; + gainCNG_e = 14+15+6; /*gainCNG is 2`097`152 - should be enough in case tracinglevel =~0 */ + IF (st_fx->tcxonly != 0) + { + /*gainCNG = st_fx->conCngLevelBackgroundTrace/(tracingLevel+0.01f);*/ + + IF(level_syn != 0) + { + BASOP_Util_Divide_MantExp ( + hTcxDec->conCngLevelBackgroundTrace, + hTcxDec->conCngLevelBackgroundTrace_e, + level_syn, + level_syn_e, + &gainCNG, + &gainCNG_e); + } + } + ELSE + { + /*gainCNG = st_fx->cngTDLevel/(tracingLevel+0.01f);*/ + IF(level_syn != 0) + { + BASOP_Util_Divide_MantExp ( + st_fx->cngTDLevel, + st_fx->cngTDLevel_e, + level_syn, + level_syn_e, + &gainCNG, + &gainCNG_e); + } + } + + if ((EQ_16(st_fx->nbLostCmpt, 1))) + { + hTcxDec->conceal_eof_gain = 16384/*1.0f Q14*/; /*Q14*/ move16(); + } + + /* step = (st_fx->conceal_eof_gain - ( st_fx->conceal_eof_gain * st_fx->damping + gainCNG * (1 - st_fx->damping) )) / st_fx->L_frame; */ + tmp2 = BASOP_Util_Add_MantExp( + mult_r(hTcxDec->conceal_eof_gain /*Q14*/, + hTcxDec->damping /*Q14*/), + 15-13/*->Q15*/, + mult_r(gainCNG/*Q15*/,sub(0x4000, hTcxDec->damping/*Q14*/)) /*Q14*/, + add(gainCNG_e,15-14)/*->Q15*/, + &tmp1); + tmp2 = BASOP_Util_Add_MantExp(hTcxDec->conceal_eof_gain, 15-14, negate(tmp1), tmp2, &tmp1); + +#ifdef BASOP_NOGLOB + step = L_shl_o(L_mult(tmp1, getInvFrameLen(st_fx->L_frame)), sub(tmp2, 6/*scaling from table lookup*/ + 1/*go to Q30*/), &Overflow); /*Q30*/ +#else + step = L_shl(L_mult(tmp1, getInvFrameLen(st_fx->L_frame)), sub(tmp2,6/*scaling from table lookup*/ +1/*go to Q30*/)); /*Q30*/ +#endif + { + Word32 stepFB; + UWord32 dmy; + conceal_eof_gainFB = L_deposit_h(hTcxDec->conceal_eof_gain); /*Q30*/ + Mpy_32_32_ss(step,L_shl(L_mult0(st_fx->L_frame, getInvFrameLen(hTcxDec->L_frameTCX)),8),&stepFB ,&dmy ); +#ifdef BASOP_NOGLOB + stepFB = L_shl_o(stepFB, 3 - 1, &Overflow); /*Q30*/ +#else + stepFB = L_shl(stepFB,3-1); /*Q30*/ +#endif + FOR( i=0; i < hTcxDec->L_frameTCX; i++ ) + { + synthFB[i] = round_fx(L_shl(Mpy_32_16_1(conceal_eof_gainFB, synthFB[i]),1)); + move16(); +#ifdef BASOP_NOGLOB + conceal_eof_gainFB = L_sub_o(conceal_eof_gainFB, stepFB, &Overflow); +#else + conceal_eof_gainFB = L_sub(conceal_eof_gainFB, stepFB); +#endif + } + } + conceal_eof_gain32 = L_deposit_h(hTcxDec->conceal_eof_gain); /*Q30*/ + FOR( i=0; i < st_fx->L_frame; i++ ) + { + xn_buf[i] = round_fx(L_shl(Mpy_32_16_1(conceal_eof_gain32 /*Q30*/, xn_buf[i]),1)); + move16(); +#ifdef BASOP_NOGLOB + conceal_eof_gain32 = L_sub_o(conceal_eof_gain32, step, &Overflow); +#else + conceal_eof_gain32 = L_sub(conceal_eof_gain32,step); +#endif + } +#ifdef BASOP_NOGLOB + hTcxDec->conceal_eof_gain = round_fx_o(conceal_eof_gain32, &Overflow); /*Q14*/ move16(); +#else + hTcxDec->conceal_eof_gain = round_fx(conceal_eof_gain32); /*Q14*/ move16(); +#endif + /* run lpc gain compensation not for waveform adjustment */ test(); + IF ( 0 == st_fx->enablePlcWaveadjust || EQ_16(st_fx->plcInfo.concealment_method,TCX_TONAL)) + { +#ifdef BASOP_NOGLOB + st_fx->plcInfo.recovery_gain = extract_h(L_shl_o(Mpy_32_16_1(conceal_eof_gainFB, + st_fx->last_concealed_gain_syn_deemph), + st_fx->last_concealed_gain_syn_deemph_e, &Overflow + ));/*Q30->Q14*/ +#else + st_fx->plcInfo.recovery_gain = extract_h(L_shl(Mpy_32_16_1(conceal_eof_gainFB, + st_fx->last_concealed_gain_syn_deemph), + st_fx->last_concealed_gain_syn_deemph_e + ));/*Q30->Q14*/ +#endif + } + ELSE + { + st_fx->plcInfo.recovery_gain = extract_h(conceal_eof_gainFB); /*Q14*/ + } + st_fx->plcInfo.step_concealgain_fx = +#ifdef BASOP_NOGLOB + round_fx_sat(L_shl_sat(L_mult0( round_fx_sat(step), round_fx_sat(L_shl_sat(L_mult0(st_fx->L_frame, getInvFrameLen(hTcxDec->L_frameTCX)), 8))), 3)); /*Q15*/ +#else + round_fx(L_shl(L_mult0( + round_fx(step), + round_fx(L_shl(L_mult0(st_fx->L_frame, getInvFrameLen(hTcxDec->L_frameTCX)),8))),3)); /*Q15*/ +#endif + } + + /*-----------------------------------------------------------* + * Memory update * + *-----------------------------------------------------------*/ + + /* Update synth, exc and old_Aq */ + tcx_decoder_memory_update(xn_buf, /*Q0*/ + synth, /*Q0*/ + A, + st_fx, + 0 + ); + + + /* PLC: [TCX: Memory update] */ + + st_fx->old_pitch_buf_fx[0] = st_fx->old_pitch_buf_fx[st_fx->nb_subfr]; + move32(); + st_fx->old_pitch_buf_fx[1] = st_fx->old_pitch_buf_fx[st_fx->nb_subfr+1]; + move32(); + Copy32(&st_fx->old_pitch_buf_fx[st_fx->nb_subfr+2], &st_fx->old_pitch_buf_fx[2], st_fx->nb_subfr); + set32_fx(&st_fx->old_pitch_buf_fx[st_fx->nb_subfr+2], st_fx->old_fpitch, st_fx->nb_subfr); +#ifdef BASOP_NOGLOB /*TBV st_fx->old_fpitch seems to have an odd value for this bitstream stv48n1_dtx_sw_164_1280_48kHz.f06.COD at frame 10 */ + st_fx->bfi_pitch_fx = shl_sat(round_fx(st_fx->old_fpitch),6); +#else + st_fx->bfi_pitch_fx = shl(round_fx(st_fx->old_fpitch),6); +#endif + st_fx->bfi_pitch_frame = st_fx->L_frame; + move16(); + + st_fx->mem_pitch_gain[2*st_fx->nb_subfr+1] = st_fx->mem_pitch_gain[st_fx->nb_subfr+1]; + move16(); + st_fx->mem_pitch_gain[2*st_fx->nb_subfr] = st_fx->mem_pitch_gain[st_fx->nb_subfr]; + move16(); + + FOR (i = 0; i < st_fx->nb_subfr; i++) + { + st_fx->mem_pitch_gain[2*st_fx->nb_subfr-1 - i] = st_fx->mem_pitch_gain[st_fx->nb_subfr-1 - i]; + move16(); + st_fx->mem_pitch_gain[st_fx->nb_subfr-1 - i] = hTcxDec->tcxltp_last_gain_unmodified; + move16(); + } +} + + +static Word32 CalculateAbsEnergy( /* o : normalized result Q31 */ + const Word32 L_off, /* i : initial sum value Qn */ + const Word16 x[], /* i : x vector Qn */ + const Word16 lg, /* i : vector length, range [0..7FFF] Q0 */ + Word16 * exp /* o : exponent of result in [-32,31] Q0 */ +) +{ + Word16 i; + Word32 L_sum, L_c; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; + Flag Carry = 0; +#endif + /* Clear carry flag and init sum */ + Carry = 0; + L_c = 0; + move32(); +#ifdef BASOP_NOGLOB /* Critical Overflow/Carry */ + L_sum = L_macNs_co(L_off,0,0, &Carry, &Overflow); + if (L_sum > 0) + { + L_c = L_macNs_co(L_c, 0, 0, &Carry, &Overflow); + } + if (L_sum < 0) + { + L_c = L_msuNs_co(L_c, 0, 0, &Carry, &Overflow); + } +#else + L_sum = L_macNs(L_off,0,0); + if (L_sum > 0) + L_c = L_macNs(L_c,0,0); + if (L_sum < 0) + L_c = L_msuNs(L_c,0,0); +#endif + FOR (i=0; i < lg; i+=2) + { + Carry = 0; + BASOP_SATURATE_WARNING_OFF_EVS /*multiplication of -32768 * -32768 throws an overflow, but is not critical*/ +#ifdef BASOP_NOGLOB /* Critical Overflow/Carry */ + L_sum = L_macNs_co(L_sum, x[i], x[i], &Carry, &Overflow); +#else + L_sum = L_macNs(L_sum, x[i], x[i]); +#endif + BASOP_SATURATE_WARNING_ON_EVS + Overflow = 0; /* to avoid useless warning in L_macNs calling L_mult */ +#ifdef BASOP_NOGLOB /* Critical Overflow/Carry */ + L_c = L_macNs_co(L_c,0,0, &Carry, &Overflow); +#else + L_c = L_macNs(L_c,0,0); +#endif + } + L_sum = norm_llQ31(L_c,L_sum,exp); + return L_sum; +} + + +static void IMDCT(Word32 *x, Word16 x_e, + Word16 *old_syn_overl, + Word16 *syn_Overl_TDAC, + Word16 *xn_buf, + const Word16 *tcx_aldo_window_1, + const PWord16 *tcx_aldo_window_1_trunc, + const PWord16 *tcx_aldo_window_2, + const PWord16 *tcx_mdct_window_half, + const PWord16 *tcx_mdct_window_minimum, + const PWord16 *tcx_mdct_window_trans, + Word16 tcx_mdct_window_half_length, + Word16 tcx_mdct_window_min_length, + Word16 index, + Word16 left_rect, + Word16 tcx_offset, + Word16 overlap, + Word16 L_frame, + Word16 L_frameTCX, + Word16 L_spec_TCX5, + Word16 L_frame_glob, + Word16 frame_cnt, + Word16 bfi, + Word16 *old_out, + Word16 *Q_old_wtda, + Decoder_State *st, + Word16 fullbandScale, + Word16 *acelp_zir) +{ + const TCX_CONFIG_HANDLE tcx_cfg = st->hTcxCfg; + Word16 tmp_offset; + Word16 tmp1, tmp2, tmp3, *tmpP16; + Word32 tmp32; + Word8 tmp8; + Word16 i; + Word16 nz; + Word16 aldo=0; + TCX_DEC_HANDLE hTcxDec; + + hTcxDec = st->hTcxDec; + + /* number of zero for ALDO windows*/ + tmp32 = L_add(st->sr_core, 0); + if (fullbandScale != 0) + { + tmp32 = L_add(st->output_Fs, 0); + } + nz = NS2SA_fx2(tmp32, N_ZERO_MDCT_NS); + + tmp_offset = 0; + move16(); + if (tcx_offset < 0) + { + tmp_offset = negate(tcx_offset); + } + test(); + IF ((EQ_16(L_frameTCX, shr(hTcxDec->L_frameTCX, 1)))&&(st->tcxonly!=0)) + { + /* Mode decision in PLC + + last OL curr OL left TCX-10 right TCX-10 + ------------------------------------------------------------- + 0 0 2x TCX-5* 1x TCX-10 + 0 2 1x TCX-10 1x TCX-10 + 0 3 1x TCX-10 1x TCX-10 + 2 0 2x TCX-5 1x TCX-10 + 2 2 2x TCX-5 2x TCX-5 + 2 3 2x TCX-5 2x TCX-5 + 3 0 2x TCX-5 1x TCX-10 + 3 2 2x TCX-5 2x TCX-5 + 3 3 2x TCX-5 2x TCX-5 + */ + test(); + test(); + test(); + test(); + test(); + test(); + IF ((bfi == 0 && tcx_cfg->tcx_last_overlap_mode != FULL_OVERLAP) || (bfi!=0 && (tcx_cfg->tcx_last_overlap_mode != FULL_OVERLAP) && (tcx_cfg->tcx_curr_overlap_mode != FULL_OVERLAP))) + { + /* minimum or half overlap, two transforms, grouping into one window */ + Word16 win[(L_FRAME_PLUS+L_MDCT_OVLP_MAX)/2]; + Word16 w; + Word16 L_win, L_ola; + + L_win = shr(L_frame, 1); + L_ola = tcx_mdct_window_half_length; + move16(); + if (EQ_16(tcx_cfg->tcx_last_overlap_mode, MIN_OVERLAP)) + { + L_ola = tcx_mdct_window_min_length; + move16(); + } + + set16_fx(xn_buf, 0, add(tcx_offset,shr(L_ola,1))); /* zero left end of buffer */ + set16_fx(win, 0, (L_FRAME_PLUS+L_MDCT_OVLP_MAX)/2); + + FOR (w = 0; w < 2 ; w++) + { + + TCX_MDCT_Inverse(x+L_mult0(w,L_spec_TCX5), sub(x_e,TCX_IMDCT_SCALE+TCX_IMDCT_HEADROOM),win, L_ola, sub(L_win,L_ola), L_ola, st->element_mode); + + tmp1 = left_rect; + move16(); + tmp2 = tcx_cfg->tcx_last_overlap_mode; + move16(); + tmp3 = st->last_core_bfi; + move16(); + tmp8 = st->last_is_cng; + move16(); + IF (w > 0) + { + tmp1 = 0; + move16(); + tmp2 = MIN_OVERLAP; + move16(); + tmp3 = 1; + move16(); + tmp8 = (Word8)0; + move16(); + } + test(); + if(w == 0 && EQ_16(index,2)) + { + tmp2 = MIN_OVERLAP; + move16(); + } + IF (frame_cnt>0) + { + tmp3 = 1; + move16(); + tmp8 = (Word8)0; + move16(); + } + + tcx_windowing_synthesis_current_frame(win, + tcx_aldo_window_2, + tcx_mdct_window_half, + tcx_mdct_window_minimum, + L_ola, + tcx_mdct_window_half_length, + tcx_mdct_window_min_length, + tmp1, + tmp2, + acelp_zir, + hTcxDec->old_syn_Overl, + syn_Overl_TDAC, + st->old_Aq_12_8_fx, + tcx_mdct_window_trans, + L_win, + tmp_offset, + tmp3, + tmp8, + fullbandScale + ); + + IF (w > 0) + { + tcx_windowing_synthesis_past_frame(xn_buf+tcx_offset-shr(L_ola , 1)+ imult1616(w,L_win), + tcx_aldo_window_1_trunc, + tcx_mdct_window_half, + tcx_mdct_window_minimum, + L_ola, + tcx_mdct_window_half_length, + tcx_mdct_window_min_length, + MIN_OVERLAP + ); + } + /* add part of current sub-window overlapping with previous window */ + Vr_add(win, + xn_buf+tcx_offset-shr(L_ola,1)+w*L_win, /*instrumented only shr because in fact, its only L_win+L_win+L_win...*/ + xn_buf+tcx_offset-shr(L_ola,1)+w*L_win, + L_ola); + /* copy new sub-window region not overlapping with previous window */ + Copy( + win+L_ola, + xn_buf+tcx_offset+shr(L_ola,1)+w*L_win, + L_win); + } + + /* To assure that no garbage values are passed to overlap */ + set16_fx(xn_buf+L_frame+tcx_offset+shr(L_ola,1), 0, overlap-tcx_offset-shr(L_ola,1)); + } + ELSE IF ( bfi == 0 && (frame_cnt == 0) && (tcx_cfg->tcx_curr_overlap_mode == FULL_OVERLAP)) + { + Word16 win[(L_FRAME_PLUS+L_MDCT_OVLP_MAX)/2]; + Word16 L_win, L_ola, w; + + /* special overlap attempt, two transforms, grouping into one window */ + L_win = shr(L_frame, 1); + L_ola = tcx_mdct_window_min_length; + move16(); + + set16_fx(win, 0, (L_FRAME_PLUS+L_MDCT_OVLP_MAX)/2); + + /* 1st TCX-5 window, special MDCT with minimum overlap on right side */ + + TCX_MDCT_Inverse(x, sub(x_e, TCX_IMDCT_SCALE+TCX_IMDCT_HEADROOM), + win + L_win, + 0, sub(L_win, shr(L_ola, 1)), L_ola, st->element_mode); + + set16_fx(xn_buf, 0, shr(overlap,1)); + /* copy new sub-window region not overlapping with previous window */ + Copy(win+L_win, xn_buf+shr(overlap,1), add(L_win,shr(L_ola,1)) ); + + /* 2nd TCX-5 window, regular MDCT with minimum overlap on both sides */ + TCX_MDCT_Inverse(x + L_spec_TCX5, sub(x_e, TCX_IMDCT_SCALE+TCX_IMDCT_HEADROOM), + win, + L_ola, sub(L_win, L_ola), L_ola, st->element_mode); + + tcx_windowing_synthesis_current_frame(win, + tcx_aldo_window_2, + tcx_mdct_window_half, + tcx_mdct_window_minimum, + L_ola, + tcx_mdct_window_half_length, + tcx_mdct_window_min_length, + 0, /* left_rect */ + MIN_OVERLAP, /* left_mode */ + acelp_zir, + hTcxDec->old_syn_Overl, + syn_Overl_TDAC, + st->old_Aq_12_8_fx, + tcx_mdct_window_trans, + L_win, + tmp_offset, + 1, /* st->last_core_bfi */ + 0, /* st->last_is_cng */ + fullbandScale + ); + + tmpP16 = xn_buf + add(sub(L_win, shr(L_ola, 1)), shr(overlap,1)); + + tcx_windowing_synthesis_past_frame(tmpP16, + tcx_aldo_window_1_trunc, + tcx_mdct_window_half, + tcx_mdct_window_minimum, + L_ola, + tcx_mdct_window_half_length, + tcx_mdct_window_min_length, + MIN_OVERLAP + ); + + /* add part of current sub-window overlapping with previous window */ + FOR (i = 0; i < L_ola; i++) + { + tmpP16[i] = add(tmpP16[i], win[i]); + move16(); + } + + /* copy new sub-window region not overlapping with previous window */ + Copy(win + L_ola, + xn_buf + add(add(shr(overlap,1), shr(L_ola, 1)), L_win), + L_win); + + /* extra folding-out on left side of win, for perfect reconstruction */ + FOR (w = shr(overlap,1); w < overlap; w++) + { + xn_buf[overlap-1-w] = negate(xn_buf[w]); + move16(); + } + + tcx_windowing_synthesis_current_frame(xn_buf, + tcx_aldo_window_2, + tcx_mdct_window_half, + tcx_mdct_window_minimum, + overlap, + tcx_mdct_window_half_length, + tcx_mdct_window_min_length, + left_rect, + 0, /* left_mode */ + acelp_zir, + hTcxDec->old_syn_Overl, + syn_Overl_TDAC, + st->old_Aq_12_8_fx, + tcx_mdct_window_trans, + shl(L_win,1), + tmp_offset, + st->last_core_bfi, + st->last_is_cng, + fullbandScale + ); + + } + ELSE /* default i.e. maximum overlap, single transform, no grouping */ + { + + TCX_MDCT_Inverse(x, sub(x_e, TCX_IMDCT_SCALE+TCX_IMDCT_HEADROOM),xn_buf, overlap, sub(L_frame, overlap), overlap, st->element_mode); + + tmp1 = index; + move16(); + test(); + test(); + test(); + if ( bfi==0 && (frame_cnt > 0) && (index == 0) && (st->last_core != ACELP_CORE)) + { + tmp1 = MIN_OVERLAP; + move16(); + } + + tmp3 = st->last_core_bfi; + move16(); + if (frame_cnt > 0) + { + tmp3 = 1; + move16(); + } + + tmp8 = st->last_is_cng; + move16(); + if (frame_cnt > 0) + { + tmp8 = 0; + move16(); + } + + tcx_windowing_synthesis_current_frame(xn_buf, + tcx_aldo_window_2, + tcx_mdct_window_half, + tcx_mdct_window_minimum, + overlap, + tcx_mdct_window_half_length, + tcx_mdct_window_min_length, + left_rect, + tmp1, + acelp_zir, + hTcxDec->old_syn_Overl, + syn_Overl_TDAC, + st->old_Aq_12_8_fx, + tcx_mdct_window_trans, + shr(L_frame_glob, 1), + tmp_offset, + tmp3, + tmp8, + fullbandScale + ); + } + } + ELSE /* frame is TCX-20 or not TCX-only */ + { + assert(frame_cnt == 0); + + IF (NE_16(st->hTcxCfg->tcx_last_overlap_mode, TRANSITION_OVERLAP)) + { + Word32 tmp_buf[L_FRAME_PLUS]; + Word16 Q; + + /* DCT */ + Q = sub(31, x_e); + edct_fx(x, tmp_buf, L_frame, &Q); + + /* scale by sqrt(L / NORM_MDCT_FACTOR) */ + tmp1 = mult_r(shl(L_frame, 4), 26214/*128.f / NORM_MDCT_FACTOR Q15*/); /* 4Q11 */ + tmp2 = 4; + move16(); + tmp1 = Sqrt16(tmp1, &tmp2); + + FOR (i = 0; i < L_frame; i++) + { + tmp_buf[i] = Mpy_32_16_1(tmp_buf[i], tmp1); + move32(); + } + Q = sub(Q, tmp2); + + + window_ola_fx(tmp_buf, + xn_buf, + &Q, + old_out, + Q_old_wtda, + L_frame, + tcx_cfg->tcx_last_overlap_mode, + tcx_cfg->tcx_curr_overlap_mode, + 0, + 0, + NULL); + + /* scale output */ + IF (Q <= 0) + { + FOR (i = 0; i < L_frame; i++) + { +#ifdef BASOP_NOGLOB + xn_buf[i] = shr_sat(xn_buf[i], Q); +#else + xn_buf[i] = shr(xn_buf[i], Q); +#endif + move16(); + } + } + ELSE + { + tmp1 = shr(0x4000, sub(Q,1)); + + FOR (i = 0; i < L_frame; i++) + { + xn_buf[i] = mult_r(xn_buf[i], tmp1); + move16(); + } + } + + aldo = 1; + move16(); + } + ELSE + { + + TCX_MDCT_Inverse(x, sub(x_e, TCX_IMDCT_SCALE+TCX_IMDCT_HEADROOM), xn_buf, overlap, sub(L_frame, overlap), overlap, st->element_mode); + + + /*-----------------------------------------------------------* + * Windowing, overlap and add * + *-----------------------------------------------------------*/ + + + /* Window current frame */ + tmp3 = st->last_core_bfi; + move16(); + + tmp8 = st->last_is_cng; + move16(); + tcx_windowing_synthesis_current_frame( xn_buf, + tcx_aldo_window_2, + tcx_mdct_window_half, + tcx_mdct_window_minimum, + overlap, + tcx_mdct_window_half_length, + tcx_mdct_window_min_length, + left_rect, + tcx_cfg->tcx_last_overlap_mode, + acelp_zir, + hTcxDec->old_syn_Overl, + syn_Overl_TDAC, + st->old_Aq_12_8_fx, + tcx_mdct_window_trans, + shr(L_frame_glob, 1), + tmp_offset, + tmp3, + tmp8, + fullbandScale + ); + } /* TRANSITION_OVERLAP */ + } /* TCX-20 and TCX-only */ + + /* Window and overlap-add past frame if past frame is TCX */ + test(); + IF ((frame_cnt != 0) || (st->last_core_bfi > ACELP_CORE)) + { + test(); + test(); + IF (((EQ_16(L_frameTCX, shr(hTcxDec->L_frameTCX, 1)))&&(st->tcxonly!=0))||(EQ_16(st->hTcxCfg->tcx_last_overlap_mode,TRANSITION_OVERLAP))) + { + test(); + test(); + test(); + test(); + if ((bfi == 0) && (frame_cnt > 0) && (index == 0) && + (tcx_cfg->tcx_curr_overlap_mode == FULL_OVERLAP) && (st->last_core != ACELP_CORE)) + { + index = MIN_OVERLAP; /* use minimum overlap between the two TCX-10 windows */ move16(); + } + + IF (tcx_cfg->last_aldo != 0) + { + Word16 tmp4; + + tmp2 = add(*Q_old_wtda, TCX_IMDCT_HEADROOM); + tmp4 = sub(shr(overlap, 1), tcx_offset); + + FOR (i = 0; i < tmp4; i++) + { + xn_buf[i] = shl(xn_buf[i], TCX_IMDCT_HEADROOM); + move16(); + } + + tmp1 = sub(overlap, tcx_mdct_window_min_length); + FOR (i=0; i < tmp1; i++) + { + xn_buf[i+tmp4] = shl(add(xn_buf[i+tmp4], shr(old_out[i+nz], tmp2)), TCX_IMDCT_HEADROOM); + move16(); + } + + /* fade truncated ALDO window */ + tmp1 = sub(overlap, shr(tcx_mdct_window_min_length, 1)); + FOR ( ; i < tmp1; i++) + { + tmp3 = mult_r(shr(old_out[i+nz], tmp2), tcx_mdct_window_minimum[i-overlap+tcx_mdct_window_min_length].v.re); + xn_buf[i+tmp4] = shl(add(xn_buf[i+tmp4], tmp3), TCX_IMDCT_HEADROOM); + move16(); + } + FOR ( ; i < overlap; i++) + { + tmp3 = mult_r(shr(old_out[i+nz], tmp2), tcx_mdct_window_minimum[overlap-1-i].v.im); + xn_buf[i+tmp4] = shl(add(xn_buf[i+tmp4], tmp3), TCX_IMDCT_HEADROOM); + move16(); + } + + FOR (i = add(i, tmp4) ; i < L_frame; i++) + { + xn_buf[i] = shl(xn_buf[i], TCX_IMDCT_HEADROOM); + move16(); + } + } + ELSE + { + tmp1 = index; + move16(); + test(); + if ((index == 0) || (EQ_16(tcx_cfg->tcx_last_overlap_mode, MIN_OVERLAP))) + { + tmp1 = tcx_cfg->tcx_last_overlap_mode; + move16(); + } + + tcx_windowing_synthesis_past_frame( old_syn_overl + , + tcx_aldo_window_1_trunc, + tcx_mdct_window_half, + tcx_mdct_window_minimum, + overlap, + tcx_mdct_window_half_length, + tcx_mdct_window_min_length, + tmp1 + ); + + BASOP_SATURATE_WARNING_OFF_EVS; + IF ( bfi ) + { + tmp1 = sub(shr(overlap, 1), tcx_offset); + tmp3 = shr(tcx_mdct_window_half_length, 1); + FOR (i=0; i < tmp1; i++) + { + xn_buf[i] = shl(xn_buf[i], TCX_IMDCT_HEADROOM); + move16(); + } + FOR (i = 0; i < tmp3; i++) + { + tmp2 = add(xn_buf[i+tmp1], mult_r(old_syn_overl[i], tcx_mdct_window_half[i].v.re)); + xn_buf[i+tmp1] = shl(tmp2, TCX_IMDCT_HEADROOM); + move16(); + } + FOR ( ; i < tcx_mdct_window_half_length; i++) + { + tmp2 = add(xn_buf[i+tmp1], mult_r(old_syn_overl[i], tcx_mdct_window_half[tcx_mdct_window_half_length-1-i].v.im)); + xn_buf[i+tmp1] = shl(tmp2, TCX_IMDCT_HEADROOM); + move16(); + } + IF (LT_16(add(i, tmp1), L_frame)) + { + FOR (i = add(i, tmp1); i < L_frame; i++) + { + xn_buf[i] = shl(xn_buf[i], TCX_IMDCT_HEADROOM); + move16(); + } + } + } + ELSE IF (left_rect == 0) + { + FOR (i=0; iL_frameTCX >> 1 && st->tcxonly) || st->hTcxCfg->tcx_last_overlap_mode == TRANSITION_OVERLAP); + } + ELSE + { + IF (aldo == 0) + { + BASOP_SATURATE_WARNING_OFF_EVS; + FOR (i = 0; i < L_frame; i++) + { +#ifdef BASOP_NOGLOB + xn_buf[i] = shl_sat(xn_buf[i], TCX_IMDCT_HEADROOM); +#else + xn_buf[i] = shl(xn_buf[i], TCX_IMDCT_HEADROOM); +#endif + move16(); + } + BASOP_SATURATE_WARNING_ON_EVS; + } + } + + test(); + test(); + test(); + IF ( (aldo == 0) && + ((EQ_16(L_frameTCX, shr(hTcxDec->L_frameTCX, 1)) && frame_cnt > 0) || + NE_16(L_frameTCX, shr(hTcxDec->L_frameTCX, 1)) ) ) + { + /*Compute windowed synthesis in case of switching to ALDO windows in next frame*/ + FOR (i = 0; i < nz; i++) + { + old_out[i] = shr(xn_buf[L_frame-nz+i], TCX_IMDCT_HEADROOM); + move16(); + } + Copy(xn_buf+L_frame, old_out+nz, overlap); + set16_fx(old_out+nz+overlap, 0, nz); + + tcx_windowing_synthesis_past_frame( old_out+nz, + tcx_aldo_window_1_trunc, + tcx_mdct_window_half, + tcx_mdct_window_minimum, + overlap, + tcx_mdct_window_half_length, + tcx_mdct_window_min_length, + tcx_cfg->tcx_curr_overlap_mode + ); + + /* If current overlap mode = FULL_OVERLAP -> ALDO_WINDOW */ + IF (EQ_16(tcx_cfg->tcx_curr_overlap_mode, FULL_OVERLAP)) + { + FOR (i=0; ihTcxCfg->last_aldo = aldo; + move16(); + } + + /* Smoothing between the ACELP PLC and TCX Transition frame. Using the shape of the half overlap window for the crossfading. */ + test(); + test(); + test(); + IF (left_rect && (frame_cnt == 0) && (st->last_core_bfi == ACELP_CORE) + && st->prev_bfi) + { + + IF (fullbandScale) + { + tmp1 = sub(shr(overlap, 1), tcx_offset); + tmp3 = shr(tcx_mdct_window_half_length, 1); + FOR (i = 0; i < tmp3; i++) + { + xn_buf[i+tmp1] = mult_r( xn_buf[i+tmp1], tcx_mdct_window_half[i].v.im ); + xn_buf[i+tmp1] = add( xn_buf[i+tmp1], mult_r(hTcxDec->syn_OverlFB[i], mult_r( tcx_mdct_window_half[i].v.re, tcx_mdct_window_half[i].v.re ) ) ); + move16(); + } + FOR ( ; i < tcx_mdct_window_half_length; i++) + { + xn_buf[i+tmp1] = mult_r( xn_buf[i+tmp1], tcx_mdct_window_half[tcx_mdct_window_half_length-1-i].v.re ); + xn_buf[i+tmp1] = add( xn_buf[i+tmp1], mult_r(hTcxDec->syn_OverlFB[i], mult_r( tcx_mdct_window_half[tcx_mdct_window_half_length-1-i].v.im, tcx_mdct_window_half[tcx_mdct_window_half_length-1-i].v.im ) ) ); + move16(); + } + } + ELSE + { + tmp1 = sub(shr(overlap, 1), tcx_offset); + tmp3 = shr(tcx_mdct_window_half_length, 1); + FOR (i = 0; i < tmp3; i++) + { + xn_buf[i+tmp1] = mult_r( xn_buf[i+tmp1], tcx_mdct_window_half[i].v.im ); + xn_buf[i+tmp1] = add( xn_buf[i+tmp1], mult_r(hTcxDec->syn_Overl[i], mult_r( tcx_mdct_window_half[i].v.re, tcx_mdct_window_half[i].v.re ) ) ); + move16(); + } + FOR ( ; i < tcx_mdct_window_half_length; i++) + { + xn_buf[i+tmp1] = mult_r( xn_buf[i+tmp1], tcx_mdct_window_half[tcx_mdct_window_half_length-1-i].v.re ); + xn_buf[i+tmp1] = add( xn_buf[i+tmp1], mult_r(hTcxDec->syn_Overl[i], mult_r( tcx_mdct_window_half[tcx_mdct_window_half_length-1-i].v.im, tcx_mdct_window_half[tcx_mdct_window_half_length-1-i].v.im ) ) ); + move16(); + } + } + } +} + diff --git a/lib_dec/dec_tran_fx.c b/lib_dec/dec_tran_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..3192c9cd2b428399982ef908bdfcdef914f0ea5a --- /dev/null +++ b/lib_dec/dec_tran_fx.c @@ -0,0 +1,228 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ +#include +#include "options.h" /* Compilation switches */ +#include "cnst.h" /* Common constants */ +#include "prot_fx1.h" /* Function prototypes */ +#include "prot_fx2.h" /* Function prototypes */ + +/*======================================================================*/ +/* FUNCTION : decod_tran_fx() */ +/*----------------------------------------------------------------------*/ +/* PURPOSE : Decode transition (TC) frames */ +/* */ +/*----------------------------------------------------------------------*/ +/* GLOBAL INPUT ARGUMENTS : */ +/* _ (Struct) st_fx : decoder static memory */ +/* _ (Word16) L_frame_fx : length of the frame Q0 */ +/* _ (Word16[]) Aq_fx : LP filter coefficient Q12 */ +/* _ (Word16) coder_type_fx : coding type Q12 */ +/* _ (Word16) Es_pred_fx : predicted scaled innov. energy Q8 */ +/* _ (Word16[]) pitch_buf_fx : floating pitch values for each subframe Q6*/ +/* _ (Word16[]) voice_factors_fx: frame error rate Q15 */ +/*-----------------------------------------------------------------------*/ +/* OUTPUT ARGUMENTS : */ +/* _ (Word16[]) exc_fx : adapt. excitation exc (Q_exc) */ +/* _ (Word16[]) exc2_fx : adapt. excitation/total exc (Q_exc) */ +/*-----------------------------------------------------------------------*/ + + +/*-----------------------------------------------------------------------*/ +/* RETURN ARGUMENTS : */ +/* _ None */ +/*=======================================================================*/ + +void decod_tran_fx( + Decoder_State *st_fx, /* i/o: decoder static memory */ + const Word16 L_frame_fx, /* i : length of the frame */ + const Word16 tc_subfr_fx, /* i : TC subframe index */ + const Word16 *Aq_fx, /* i : LP filter coefficient */ + const Word16 Es_pred_fx, /* i : predicted scaled innov. energy */ + Word16 *pitch_buf_fx, /* o : floating pitch values for each subframe*/ + Word16 *voice_factors_fx, /* o : voicing factors */ + Word16 *exc_fx, /* i/o: adapt. excitation exc */ + Word16 *exc2_fx, /* i/o: adapt. excitation/total exc */ + Word16 *bwe_exc_fx, /* i/o: excitation for SWB TBE */ + Word16 *unbits, /* i/o: number of unused bits */ + const Word16 sharpFlag, /* i : formant sharpening flag */ + Word16 *gain_buf /* o : floating pitch gain for each subframe */ +) +{ + Word16 T0, T0_frac, T0_min, T0_max; /* integer pitch variables */ + Word32 gain_code_fx=0; /* Quantized algebraic codeebook gain */ + Word32 norm_gain_code_fx=0; /* normalized algebraic codeebook gain */ + Word16 gain_pit_fx = 0; /* Quantized pitch gain */ + Word16 voice_fac_fx; /* Voicing factor */ + Word16 gain_inov_fx=0; /* inovation gain */ + Word16 code_fx[L_SUBFR]; /* algebraic codevector */ + const Word16 *p_Aq_fx; /* pointer to lp filter coefficient */ + Word16 *pt_pitch_fx; /* pointer to floating pitch */ + Word16 i_subfr, i; /* tmp variables */ + Word16 position; /* TC related flag */ + Word16 gain_preQ_fx = 0; /* Gain of prequantizer excitation */ + Word16 code_preQ_fx[L_SUBFR]; /* Prequantizer excitation */ + Word16 Jopt_flag; /* flag indicating zero adaptive contribtuion */ + Word32 norm_gain_preQ_fx; + Word16 gain_code16; + Word32 L_tmp; + Word16 tmp16, tmp1_fx, tmp_fx; + GSC_DEC_HANDLE hGSCDec; + hGSCDec = st_fx->hGSCDec; + MUSIC_POSTFILT_HANDLE hMusicPF; + hMusicPF = st_fx->hMusicPF; + + gain_preQ_fx = 0; + move16(); + set16_fx( code_preQ_fx, 0, L_SUBFR ); + /*----------------------------------------------------------------* + * ACELP subframe loop + *----------------------------------------------------------------*/ + + p_Aq_fx = Aq_fx; + move16(); + pt_pitch_fx = pitch_buf_fx; + move16(); + Jopt_flag = 0; + move16(); + norm_gain_preQ_fx = 0; + move16(); + + FOR( i_subfr = 0; i_subfr < L_frame_fx; i_subfr += L_SUBFR ) + { + /*------------------------------------------------------------* + * TC : subframe determination & + * adaptive/glottal part of excitation construction + *------------------------------------------------------------*/ + + test(); + IF( i_subfr == 0 && GT_16(st_fx->Q_exc,2)) + { + tmp16 = sub(2, st_fx->Q_exc); + Scale_sig(exc_fx-L_EXC_MEM, L_EXC_MEM, tmp16); + Scale_sig(bwe_exc_fx-PIT16k_MAX*2, PIT16k_MAX*2, tmp16); + Scale_sig(hGSCDec->last_exc_dct_in_fx, L_FRAME, tmp16); + st_fx->Q_exc = add(st_fx->Q_exc,tmp16); + } + + transition_dec_fx( st_fx, 0, L_frame_fx, i_subfr, tc_subfr_fx, &Jopt_flag, exc_fx, + &T0, &T0_frac, &T0_min, &T0_max, &pt_pitch_fx, &position, bwe_exc_fx, &st_fx->Q_exc ); + /*-----------------------------------------------------------------* + * Transform domain contribution decoding - active frames + *-----------------------------------------------------------------*/ + IF( GE_32(st_fx->core_brate, MIN_BRATE_AVQ_EXC)) + { + gain_code_fx = 0; + move16(); + transf_cdbk_dec_fx( st_fx, 0, i_subfr, Es_pred_fx, gain_code_fx, &gain_preQ_fx, &norm_gain_preQ_fx, code_preQ_fx, unbits); + } + + /*-----------------------------------------------------------------* + * ACELP codebook search + pitch sharpening + *-----------------------------------------------------------------*/ + + inov_decode_fx( st_fx, st_fx->core_brate, 0, L_frame_fx, sharpFlag, i_subfr, p_Aq_fx, st_fx->tilt_code_fx, *pt_pitch_fx, code_fx, L_SUBFR); + + /*-----------------------------------------------------------------* + * De-quantize the gains + * Update tilt of code: 0.0 (unvoiced) to 0.5 (voiced) + *-----------------------------------------------------------------*/ + + IF( Jopt_flag == 0 ) + { + /* 2/3-bit decoding */ + gain_dec_tc_fx( st_fx, code_fx, i_subfr,Es_pred_fx, &gain_pit_fx, &gain_code_fx, &gain_inov_fx, &norm_gain_code_fx); + } + ELSE + { + /* 5-bit decoding */ + IF( GT_32(st_fx->core_brate,ACELP_32k)) + { + gain_dec_SQ_fx( st_fx, i_subfr, code_fx, Es_pred_fx, &gain_pit_fx, &gain_code_fx, &gain_inov_fx, &norm_gain_code_fx ); + } + ELSE + { + gain_dec_mless_fx( st_fx, L_frame_fx, st_fx->coder_type_fx, i_subfr, tc_subfr_fx , code_fx, Es_pred_fx, &gain_pit_fx, &gain_code_fx, &gain_inov_fx, &norm_gain_code_fx ); + + } + } + + /* update LP filtered gains for the case of frame erasures */ + lp_gain_updt_fx( i_subfr, gain_pit_fx, L_add(norm_gain_code_fx,norm_gain_preQ_fx), &st_fx->lp_gainp_fx, &st_fx->lp_gainc_fx, L_frame_fx ); + + st_fx->tilt_code_fx = est_tilt_fx( exc_fx+i_subfr, gain_pit_fx, code_fx, gain_code_fx,&voice_fac_fx,st_fx->Q_exc); + + /*----------------------------------------------------------------------* + * Find the total excitation + *----------------------------------------------------------------------*/ + + IF ( EQ_16(L_frame_fx,L_FRAME)) /* Rescaling for 12.8k core */ + { + Rescale_exc(hMusicPF->dct_post_old_exc_fx, &exc_fx[i_subfr], &bwe_exc_fx[i_subfr * HIBND_ACB_L_FAC], hGSCDec->last_exc_dct_in_fx, + L_SUBFR, L_SUBFR * HIBND_ACB_L_FAC, gain_code_fx, &(st_fx->Q_exc), st_fx->Q_subfr, exc2_fx, i_subfr, st_fx->coder_type_fx ); + } + ELSE /* Rescaling for 16k core */ + { + Rescale_exc(hMusicPF->dct_post_old_exc_fx, &exc_fx[i_subfr], &bwe_exc_fx[i_subfr * 2], hGSCDec->last_exc_dct_in_fx, + L_SUBFR, L_SUBFR * 2, gain_code_fx, &(st_fx->Q_exc), st_fx->Q_subfr, exc2_fx, i_subfr,st_fx->coder_type_fx ); + } + + gain_code16 = round_fx(L_shl(gain_code_fx,st_fx->Q_exc)); /*Q_exc*/ + Acelp_dec_total_exc( exc_fx, exc2_fx, gain_code16, gain_pit_fx, i_subfr, code_fx, L_SUBFR); + + /*-----------------------------------------------------------------* + * Add the ACELP pre-quantizer contribution + *-----------------------------------------------------------------*/ + IF(GE_32(st_fx->core_brate, MIN_BRATE_AVQ_EXC)) + { + tmp1_fx = add(15-Q_AVQ_OUT_DEC-2,st_fx->Q_exc); + FOR( i = 0; i < L_SUBFR; i++ ) + { + L_tmp = L_mult(gain_preQ_fx, code_preQ_fx[i]); /* Q2 + Q10 -> Q13*/ + L_tmp = L_shl(L_tmp,tmp1_fx); /* Q16 + Q_exc */ + tmp_fx = round_fx(L_tmp); + + exc2_fx[i+i_subfr] = add(exc2_fx[i+i_subfr],tmp_fx); + move16(); + exc_fx[i+i_subfr] = add(exc_fx[i+i_subfr],tmp_fx); + move16(); + } + } + + /*-----------------------------------------------------------------* + * Prepare TBE excitation + *-----------------------------------------------------------------*/ + + prep_tbe_exc_fx( L_frame_fx, i_subfr, gain_pit_fx, gain_code_fx, code_fx, voice_fac_fx, + &voice_factors_fx[i_subfr/L_SUBFR], bwe_exc_fx, gain_preQ_fx, code_preQ_fx, + st_fx->Q_exc, T0, T0_frac, st_fx->coder_type_fx, st_fx->core_brate ); + + /*----------------------------------------------------------------* + * Excitation enhancements (update of total excitation signal) + *----------------------------------------------------------------*/ + + IF( GT_32(st_fx->core_brate,ACELP_32k)) + { + Copy( exc_fx+i_subfr, exc2_fx+i_subfr, L_SUBFR ); + } + ELSE + { + enhancer_fx( st_fx->core_brate, 0, st_fx->coder_type_fx, i_subfr, L_frame_fx, voice_fac_fx, st_fx->stab_fac_fx, + norm_gain_code_fx, gain_inov_fx, &st_fx->gc_threshold_fx, code_fx, exc2_fx, gain_pit_fx, &(st_fx->dm_fx), st_fx->Q_exc ); + } + + p_Aq_fx += (M+1); + move16(); + pt_pitch_fx++; + st_fx->tilt_code_dec_fx[i_subfr/L_SUBFR] = st_fx->tilt_code_fx; + move16(); + gain_buf[i_subfr/L_SUBFR] = gain_pit_fx; + move16(); + } + + /* SC-VBR */ + st_fx->prev_gain_pit_dec_fx = gain_pit_fx; + move16(); /*Q14*/ + + return; +} diff --git a/lib_dec/dec_uv.c b/lib_dec/dec_uv.c index f6c9b913b119f28647d7c9a609a1b531649b2d5a..2b513dcff95e31e7a045aa07ce7aa508933a61a1 100644 --- a/lib_dec/dec_uv.c +++ b/lib_dec/dec_uv.c @@ -113,14 +113,14 @@ void decod_unvoiced( * Generate Gaussian excitation * *-------------------------------------------------------*/ - gaus_L2_dec( code2, st->tilt_code, p_Aq, FORMANT_SHARPENING_G1_FLT, &( st->seed_acelp ) ); + gaus_L2_dec_flt( code2, st->tilt_code, p_Aq, FORMANT_SHARPENING_G1_FLT, &( st->seed_acelp ) ); /*-----------------------------------------------------------------* * Gain encoding *-----------------------------------------------------------------*/ index = get_next_indice( st, st->acelp_cfg.gains_mode[i_subfr / L_SUBFR] ); - gain_dec_gacelp_uv( index, code, code2, Es_pred, L_SUBFR, &gain_pit, &gain_code, &gain_code2, &( st->past_gpit_float), &norm_gain_code, &gain_inov ); + gain_dec_gacelp_uv_flt( index, code, code2, Es_pred, L_SUBFR, &gain_pit, &gain_code, &gain_code2, &( st->past_gpit_float), &norm_gain_code, &gain_inov ); st->tilt_code = est_tilt( exc + i_subfr, gain_pit, code, gain_code, &voice_fac, L_SUBFR, 0 ); diff --git a/lib_dec/dec_uv_fx.c b/lib_dec/dec_uv_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..f37cee3d477a8e934d4c8a2d97bf4d011d6b54c5 --- /dev/null +++ b/lib_dec/dec_uv_fx.c @@ -0,0 +1,88 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ +#include +#include "options.h" /* Compilation switches */ +#include "cnst.h" /* Common constants */ +#include "prot_fx1.h" /* Function prototypes */ +#include "prot_fx2.h" /* Function prototypes */ + +/*-------------------------------------------------------------------* + * decod_unvoiced() + * + * Decode unvoiced (UC) frames + *-------------------------------------------------------------------*/ + +void decod_unvoiced_fx( + Decoder_State *st_fx, /* i/o: decoder static memory */ + const Word16 *Aq_fx, /* Q12 i : LP filter coefficient */ + const Word16 coder_type_fx, /* Q0 i : coding type */ + Word16 *tmp_noise_fx, /* Q0 o : long term temporary noise energy */ + Word16 *pitch_buf_fx, /* Q6 o : floating pitch values for each subframe*/ + Word16 *voice_factors_fx, /* Q15 o : voicing factors */ + Word16 *exc_fx, /* Q_X o : adapt. excitation exc */ + Word16 *exc2_fx, /* Q_X o : adapt. excitation/total exc */ + Word16 *bwe_exc_fx, /* Q_X i/o: excitation for SWB TBE */ + Word16 *gain_buf +) +{ + Word16 gain_pit_fx = 0; /* Quantized pitch gain */ + Word32 gain_code_fx; /* Quantized algebraic codeebook gain */ + Word16 gain_inov_fx; /* inovation gain */ + Word32 norm_gain_code_fx; /* normalized algebraic codeebook gain */ + Word16 voice_fac_fx; /* Voicing factor */ + Word16 code_fx[L_SUBFR]; /* algebraic codevector */ + Word16 i_subfr_fx; + const Word16 *p_Aq_fx; + Word16 *pt_pitch_fx; + + test(); + IF ( EQ_16(st_fx->last_ppp_mode_dec_fx,1)||EQ_16(st_fx->last_nelp_mode_dec_fx,1)) + { + /* SC_VBR - reset the decoder, to avoid memory not updated issue for this unrealistic case */ + CNG_reset_dec_fx( st_fx, pitch_buf_fx, voice_factors_fx ); + } + + p_Aq_fx = Aq_fx; + move16(); /*Q12*/ /* pointer to interpolated LPC parameters */ + pt_pitch_fx = pitch_buf_fx; + move16(); /* pointer to the pitch buffer */ + + FOR( i_subfr_fx=0; i_subfr_fxlp_gainp_fx, &st_fx->lp_gainc_fx, &gain_inov_fx, &st_fx->tilt_code_fx, + &voice_fac_fx, &gain_pit_fx, pt_pitch_fx, exc_fx, &gain_code_fx, exc2_fx, bwe_exc_fx,&(st_fx->Q_exc),st_fx->Q_subfr ); + + *tmp_noise_fx = extract_h(norm_gain_code_fx); /*Q16*/ + + /*----------------------------------------------------------------* + * Excitation enhancements (update of total excitation signal) + *----------------------------------------------------------------*/ + + enhancer_fx( st_fx->core_brate, 0, coder_type_fx, i_subfr_fx, L_FRAME, voice_fac_fx, st_fx->stab_fac_fx, + norm_gain_code_fx, gain_inov_fx, &st_fx->gc_threshold_fx, code_fx, exc2_fx, gain_pit_fx, &(st_fx->dm_fx), st_fx->Q_exc ); + + voice_factors_fx[i_subfr_fx/L_SUBFR] = 0; + move16(); + + interp_code_5over2_fx( &exc_fx[i_subfr_fx], &bwe_exc_fx[i_subfr_fx * HIBND_ACB_L_FAC], L_SUBFR ); + + p_Aq_fx += (M+1); + move16(); + pt_pitch_fx++; + st_fx->tilt_code_dec_fx[i_subfr_fx/L_SUBFR] = st_fx->tilt_code_fx; + move16(); + } + + /* SC-VBR */ + st_fx->prev_gain_pit_dec_fx = gain_pit_fx; + move16(); + + set16_fx( gain_buf, 0, NB_SUBFR ); + + return; +} diff --git a/lib_dec/decision_matrix_dec_fx.c b/lib_dec/decision_matrix_dec_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..766cad69fe9d3cf9a1830911489f736dae8067a5 --- /dev/null +++ b/lib_dec/decision_matrix_dec_fx.c @@ -0,0 +1,711 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include +#include "options.h" +#include "prot_fx1.h" +#include "prot_fx2.h" +#include "stat_dec.h" +#include "rom_com.h" +#include "stl.h" + + +/*-----------------------------------------------------------------* + * decision_matrix_dec() + * + * ACELP/HQ core selection + * Read ACELP signaling bits from the bitstream + * Set extension layers + *-----------------------------------------------------------------*/ + +void decision_matrix_dec_fx( + Decoder_State *st, /* i/o: decoder state structure */ + Word16 *sharpFlag, /* o : formant sharpening flag */ + Word16 *hq_core_type, /* o : HQ core type */ + Word16 *core_switching_flag/* o : ACELP->HQ switching frame flag */ +) +{ + Word16 start_idx; + Word16 ppp_nelp_mode; + Word32 ind; + Word16 nBits; + Word16 tmp16, temp_core; + + /* init */ + st->core = -1; + move16(); + st->core_brate = L_deposit_l(0); + st->extl = -1; + move16(); + st->extl_brate = 0; + move16(); + st->ppp_mode_dec_fx = 0; + move16(); + st->nelp_mode_dec_fx = 0; + move16(); + st->igf = 0; + move16(); + + if( GT_32(st->total_brate,ACELP_8k00)) + { + st->vbr_hw_BWE_disable_dec_fx = 0; + move16(); + } + + IF (EQ_16(st->mdct_sw, MODE2)) + { + st->core = HQ_CORE; + move16(); + } + ELSE + { + test(); + IF( EQ_32(st->total_brate,FRAME_NO_DATA)||EQ_32(st->total_brate,SID_2k40)) + { + st->core = ACELP_CORE; + move16(); + st->core_brate = st->total_brate; + move32(); + + IF( NE_32(st->total_brate,FRAME_NO_DATA)) + { + st->cng_type = get_next_indice( st, 1 ); + + IF( EQ_16(st->cng_type,LP_CNG)) + { + st->L_frame = L_FRAME; + move16(); + + tmp16 = get_next_indice( st, 1 ); + if( EQ_16(tmp16,1)) + { + st->L_frame = L_FRAME16k; + move16(); + } + } + ELSE + { + st->bwidth = get_next_indice(st, 2); + + tmp16 = get_next_indice(st, 1); + move16(); + + st->L_frame = L_FRAME16k; + move16(); + if( tmp16 == 0 ) + { + st->L_frame = L_FRAME; + move16(); + } + } + } + + test(); + if( GE_32(st->output_Fs,32000)&&GE_16(st->bwidth,SWB)) + { + st->extl = SWB_CNG; + move16(); + } + + test(); + test(); + test(); + if( EQ_32(st->total_brate,FRAME_NO_DATA)&&st->prev_bfi&&!st->bfi&>_16(st->L_frame,L_FRAME16k)) + { + st->L_frame = st->last_CNG_L_frame; + move16(); + } + + return; + } + + /* SC-VBR */ + ELSE IF( EQ_32(st->total_brate,PPP_NELP_2k80)) + { + st->core = ACELP_CORE; + move16(); + st->core_brate = PPP_NELP_2k80; + move32(); + st->L_frame = L_FRAME; + move16(); + st->fscale = sr2fscale(INT_FS_FX); + move16(); + + IF ( st->ini_frame == 0 ) + { + /* avoid switching of internal ACELP Fs in the very first frame */ + st->last_L_frame = st->L_frame; + st->last_core = st->core; + st->last_core_brate = st->core_brate; + st->last_extl = st->extl; + } + + st->vbr_hw_BWE_disable_dec_fx = 1; + move16(); + get_next_indice( st, 1 ); + + ppp_nelp_mode = get_next_indice( st, 2 ); + + /* 0 - PPP_NB, 1 - PPP_WB, 2 - NELP_NB, 3 - NELP_WB */ + IF( ppp_nelp_mode == 0 ) + { + st->ppp_mode_dec_fx = 1; + move16(); + st->coder_type_fx = VOICED; + move16(); + st->bwidth = NB; + move16(); + } + ELSE IF( EQ_16(ppp_nelp_mode,1)) + { + st->ppp_mode_dec_fx = 1; + move16(); + st->coder_type_fx = VOICED; + move16(); + st->bwidth = WB; + move16(); + } + ELSE IF( EQ_16(ppp_nelp_mode,2)) + { + st->nelp_mode_dec_fx = 1; + move16(); + st->coder_type_fx = UNVOICED; + move16(); + st->bwidth = NB; + move16(); + } + ELSE IF( EQ_16(ppp_nelp_mode,3)) + { + st->nelp_mode_dec_fx = 1; + move16(); + st->coder_type_fx = UNVOICED; + move16(); + st->bwidth = WB; + move16(); + } + + + return; + } + + /*---------------------------------------------------------------------* + * ACELP/HQ core selection + *---------------------------------------------------------------------*/ + + test(); + IF( LT_32(st->total_brate,ACELP_24k40)) + { + st->core = ACELP_CORE; + move16(); + } + ELSE IF( GE_32(st->total_brate,ACELP_24k40)&&LE_32(st->total_brate,ACELP_64k)) + { + /* read the ACELP/HQ core selection bit */ + temp_core = get_next_indice( st, 1 ); + + st->core = HQ_CORE; + move16(); + if( temp_core == 0 ) + { + st->core = ACELP_CORE; + move16(); + } + } + } + + /*-----------------------------------------------------------------* + * Read ACELP signaling bits from the bitstream + *-----------------------------------------------------------------*/ + + IF( EQ_16(st->core,ACELP_CORE)) + { + /* find the section in the ACELP signaling table corresponding to bitrate */ + start_idx = 0; + move16(); + WHILE( NE_32(acelp_sig_tbl[start_idx],st->total_brate)) + { + start_idx = add(start_idx,1); + IF( GE_16(start_idx,MAX_ACELP_SIG)) + { + st->BER_detect = 1; + move16(); + start_idx = 0; + move16(); + break; + } + } + + /* skip the bitrate */ + start_idx = add(start_idx,1); + + /* retrieve the number of bits */ + nBits = extract_l(acelp_sig_tbl[start_idx]); + start_idx = add(start_idx,1); + + start_idx = add(start_idx,get_next_indice( st, nBits )); + IF( start_idx >= MAX_ACELP_SIG ) + { + ind = 0; + move16(); + st->BER_detect = 1; + move16(); + } + ELSE + { + /* retrieve the signaling indice */ + ind = acelp_sig_tbl[start_idx]; + + /* convert signaling indice into signaling information */ + st->coder_type_fx = extract_l(L_and(ind,0x7L)); + IF(EQ_16(st->coder_type_fx, LR_MDCT)) + { + st->core = HQ_CORE; + move16(); + st->bwidth = extract_l(L_shr(ind,3) & 0x7L); + } + ELSE + { + st->bwidth = extract_l(L_and(L_shr(ind,3),0x7L)); + *sharpFlag = extract_l(L_and(L_shr(ind,6),0x1L)); + + } + } + + /* detect corrupted signaling (due to bit errors) */ + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( ( st->BER_detect ) || + ( GE_32(ind,1<<7) ) || + ( LE_32(st->total_brate,ACELP_13k20) && EQ_16(st->bwidth,FB) ) || + ( GE_32(st->total_brate,ACELP_32k) && EQ_16(st->bwidth,NB) ) || + ( GE_32(st->total_brate,ACELP_32k) && !(EQ_16(st->coder_type_fx,GENERIC) || EQ_16(st->coder_type_fx,TRANSITION) || EQ_16(st->coder_type_fx,INACTIVE) ) ) || + ( LT_32(st->total_brate,ACELP_13k20) && NE_16(st->bwidth,NB) && EQ_16(st->coder_type_fx,LR_MDCT) ) || + ( GE_32(st->total_brate,ACELP_13k20) && EQ_16(st->coder_type_fx,UNVOICED) ) || + ( GE_32(st->total_brate,ACELP_13k20) && EQ_16(st->coder_type_fx,AUDIO) && EQ_16(st->bwidth,NB) ) + ) + { + st->BER_detect = 0; + move16(); + st->bfi = 1; + move16(); + + IF( st->ini_frame == 0 ) + { + st->core = ACELP_CORE; + move16(); + st->L_frame = L_FRAME; + move16(); + st->last_core = st->core; + move16(); + st->last_core_brate = st->core_brate; + move32(); + } + ELSE IF( EQ_32(st->last_total_brate, -1)) /* can happen in case of BER when no good frame was received before */ + { + st->coder_type_fx = st->last_coder_type_fx; + move16(); + st->bwidth = st->last_bwidth; + move16(); + st->total_brate = st->last_total_brate_ber; + move32(); + test(); + IF( EQ_16(st->last_core, AMR_WB_CORE)) + { + st->core = ACELP_CORE; + move16(); + st->codec_mode = MODE1; + move16(); + } + ELSE IF( EQ_16(st->last_core_bfi, TCX_20_CORE)||EQ_16(st->last_core_bfi,TCX_10_CORE)) + { + st->core = st->last_core_bfi; + move16(); + st->codec_mode = MODE2; + move16(); + } + ELSE + { + st->core = st->last_core; + move16(); + st->codec_mode = MODE1; + move16(); + } + st->core_brate = st->last_core_brate; + move32(); + st->extl = st->last_extl; + move16(); + st->extl_brate = L_sub(st->total_brate, st->core_brate); + move32(); + } + ELSE + { + st->coder_type_fx = st->last_coder_type_fx; + move16(); + st->bwidth = st->last_bwidth; + move16(); + st->total_brate = st->last_total_brate; + move16(); + + test(); + IF( EQ_16(st->last_core,AMR_WB_CORE)) + { + st->core = ACELP_CORE; + move16(); + st->codec_mode = MODE1; + move16(); + } + ELSE IF( EQ_16(st->last_core,TCX_20_CORE)||EQ_16(st->last_core,TCX_10_CORE)) + { + st->core = st->last_core; + move16(); + st->codec_mode = MODE2; + move16(); + } + ELSE + { + st->core = st->last_core; + move16(); + st->codec_mode = MODE1; + move16(); + } + st->core_brate = st->last_core_brate; + move32(); + st->extl = st->last_extl; + move16(); + st->extl_brate = L_sub(st->total_brate,st->core_brate); + } + + return; + } + } + + /*-----------------------------------------------------------------* + * Set extension layers + *-----------------------------------------------------------------*/ + + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( EQ_16(st->core,ACELP_CORE)&&EQ_16(st->bwidth,WB)&<_32(st->total_brate,ACELP_9k60)) + { + if( st->vbr_hw_BWE_disable_dec_fx == 0 ) + { + st->extl = WB_BWE; + move16(); + } + } + ELSE IF( EQ_16(st->core,ACELP_CORE)&&EQ_16(st->bwidth,WB)&&GE_32(st->total_brate,ACELP_9k60)&&LE_32(st->total_brate,ACELP_16k40)) + { + /* read the WB TBE/BWE selection bit */ + tmp16 = get_next_indice( st, 1 ); + IF( EQ_16(tmp16,1)) + { + st->extl = WB_BWE; + move16(); + st->extl_brate = WB_BWE_0k35; + move32(); + } + ELSE + { + st->extl = WB_TBE; + move16(); + st->extl_brate = WB_TBE_1k05; + move32(); + } + } + ELSE IF( EQ_16(st->core,ACELP_CORE)&&(EQ_16(st->bwidth,SWB)||EQ_16(st->bwidth,FB))&&GE_32(st->total_brate,ACELP_13k20)) + { + IF( GE_32(st->total_brate,ACELP_48k)) + { + st->extl = SWB_BWE_HIGHRATE; + move16(); + if( EQ_16(st->bwidth,FB)) + { + st->extl = FB_BWE_HIGHRATE; + move16(); + } + + st->extl_brate = SWB_BWE_16k; + move32(); + } + + /* read the SWB TBE/BWE selection bit */ + ELSE + { + tmp16 = get_next_indice( st, 1 ); + IF( tmp16 ) + { + st->extl = SWB_BWE; + move16(); + st->extl_brate = SWB_BWE_1k6; + move32(); + } + ELSE + { + st->extl = SWB_TBE; + move16(); + st->extl_brate = SWB_TBE_1k6; + move32(); + if( GE_32(st->total_brate,ACELP_24k40)) + { + st->extl_brate = SWB_TBE_2k8; + move32(); + } + } + } + + /* set FB TBE and FB BWE extension layers */ + test(); + IF( EQ_16(st->bwidth,FB)&&GE_32(st->total_brate,ACELP_24k40)) + { + IF( EQ_16(st->extl,SWB_BWE)) + { + st->extl = FB_BWE; + move16(); + st->extl_brate = FB_BWE_1k8; + move32(); + } + ELSE IF( EQ_16(st->extl,SWB_TBE)) + { + st->extl = FB_TBE; + move16(); + { + st->extl_brate = FB_TBE_3k0; + move32(); + } + } + } + } + + /* set core bitrate */ + st->core_brate = L_sub(st->total_brate,st->extl_brate); + + /*-----------------------------------------------------------------* + * Read HQ signaling bits from the bitstream + * Set HQ core type + *-----------------------------------------------------------------*/ + + + IF( EQ_16(st->core,HQ_CORE)) + { + IF( NE_16(st->mdct_sw, MODE2)) + { + /* skip the HQ/TCX core switching flag */ + get_next_indice_tmp_fx( st, 1 ); + } + + /* read ACELP->HQ core switching flag */ + *core_switching_flag = get_next_indice( st, 1 ); + + IF( EQ_16(*core_switching_flag,1)) + { + st->last_L_frame_ori = st->last_L_frame; + move16(); + + /* read ACELP L_frame info */ + st->last_L_frame = L_FRAME16k; + move16(); + tmp16 = get_next_indice( st, 1 ); + if( tmp16 == 0 ) + { + st->last_L_frame = L_FRAME; + move16(); + } + } + + IF( NE_16(st->mdct_sw, MODE2)) + { + + /* read/set band-width (needed for different I/O sampling rate support) */ + IF( GT_32(st->total_brate,ACELP_16k40)) + { + tmp16 = get_next_indice( st, 2 ); + + IF( tmp16 == 0 ) + { + st->bwidth = NB; + move16(); + } + ELSE IF( EQ_16(tmp16,1)) + { + st->bwidth = WB; + move16(); + } + ELSE IF( EQ_16(tmp16,2)) + { + st->bwidth = SWB; + move16(); + } + ELSE + { + st->bwidth = FB; + move16(); + } + } + } + + /* detect bit errors in signaling */ + test(); + test(); + test(); + test(); + IF( ( GE_32(st->total_brate,ACELP_24k40)&&EQ_16(st->bwidth,NB))|| + ( EQ_16(st->core,HQ_CORE) && LE_32(st->total_brate,LRMDCT_CROSSOVER_POINT) && EQ_16(st->bwidth,FB) ) + ) + { + st->bfi = 1; + move16(); + + st->core_brate = st->total_brate; + move32(); + st->extl = -1; + move16(); + st->extl_brate = 0; + move32(); + IF( EQ_16(st->last_core,AMR_WB_CORE)) + { + st->core = ACELP_CORE; + move16(); + st->L_frame = L_FRAME; + move16(); + st->codec_mode = MODE1; + move16(); + st->last_L_frame = L_FRAME; + move16(); + + IF( GE_32(st->total_brate,ACELP_16k40)) + { + st->total_brate = ACELP_13k20; + move32(); + st->core_brate = st->total_brate; + move32(); + } + } + ELSE + { + /* make sure, we are in a valid configuration wrt to bandwidth */ + st->bwidth = WB; + move16(); + } + } + + /* set HQ core type */ + *hq_core_type = NORMAL_HQ_CORE; + move16(); + + test(); + test(); + IF( (EQ_16(st->bwidth,SWB)||EQ_16(st->bwidth,WB))&&LE_32(st->total_brate,LRMDCT_CROSSOVER_POINT)) + { + *hq_core_type = LOW_RATE_HQ_CORE; + move16(); + } + ELSE IF( EQ_16(st->bwidth,NB)) + { + *hq_core_type = LOW_RATE_HQ_CORE; + move16(); + } + } + + /*-----------------------------------------------------------------* + * Set ACELP frame lnegth + *-----------------------------------------------------------------*/ + + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( EQ_32(st->core_brate,FRAME_NO_DATA)) + { + /* prevent "L_frame" changes in CNG segments */ + st->L_frame = st->last_L_frame; + move16(); + } + ELSE IF( EQ_32(st->core_brate,SID_2k40)&&EQ_16(st->bwidth,WB)&&st->first_CNG&<_16(st->hTdCngDec->act_cnt2_fx,MIN_ACT_CNG_UPD)) + { + /* prevent "L_frame" changes in SID frame after short segment of active frames */ + st->L_frame = st->last_CNG_L_frame; + move16(); + } + ELSE IF( ( EQ_32(st->core_brate,SID_2k40)&&GE_32(st->total_brate,ACELP_9k60)&&EQ_16(st->bwidth,WB))|| + ( GE_32(st->total_brate, ACELP_32k) && LT_32(st->total_brate,HQ_96k) ) || ( EQ_32(st->total_brate,ACELP_24k40) && GE_16(st->bwidth,WB) ) ) + { + st->L_frame = L_FRAME16k; + move16(); + } + ELSE + { + st->L_frame = L_FRAME; + move16(); + } + + st->nb_subfr = NB_SUBFR; + move16(); + if ( EQ_16(st->L_frame,L_FRAME16k)) + { + st->nb_subfr = NB_SUBFR16k; + move16(); + } +#if 1//def ADD_IVAS_BWE 0> NEEDED for IO with conf_acelp1 + st->extl_orig = st->extl; + st->extl_brate_orig = st->extl_brate; +#endif + test(); + IF( EQ_32(st->output_Fs,8000)) + { + st->extl = -1; + move16(); + } + ELSE IF( EQ_32(st->output_Fs,16000)&&EQ_16(st->L_frame,L_FRAME16k)) + { + st->extl = -1; + move16(); + st->extl_brate = L_deposit_l(0); + } + + IF( st->ini_frame == 0 ) + { + /* avoid switching of internal ACELP Fs in the very first frame */ + st->last_L_frame = st->L_frame; + move16(); + st->last_core = st->core; + move16(); + st->last_core_brate = st->core_brate; + move32(); + st->last_extl = st->extl; + move16(); + } + + return; +} diff --git a/lib_dec/dlpc_avq.c b/lib_dec/dlpc_avq.c index b4a95fd74d5369d449c1386a2fa889a9cf95d3a9..77ec2c2ec44b64589d287f7b00172c457b24084e 100644 --- a/lib_dec/dlpc_avq.c +++ b/lib_dec/dlpc_avq.c @@ -41,12 +41,12 @@ #include "wmc_auto.h" /*------------------------------------------------------------------* - * dlpc_avq() + * dlpc_avq_flt() * * Variable bitrate multiple LPC un-quantizer *------------------------------------------------------------------*/ -int16_t dlpc_avq( +int16_t dlpc_avq_flt( int16_t *index, /* i : Quantization indices */ float *LSF_Q, /* o : Quantized LSF vectors */ const int16_t numlpc, /* i : Number of sets of lpc */ @@ -74,9 +74,9 @@ int16_t dlpc_avq( LSF_Q[last + i] = 0.0f; } - vlpc_1st_dec( p_index[0], &LSF_Q[last], sr_core ); + vlpc_1st_dec_flt( p_index[0], &LSF_Q[last], sr_core ); p_index++; - vlpc_2st_dec( &LSF_Q[last], &p_index[0], 0, sr_core ); + vlpc_2st_dec_flt( &LSF_Q[last], &p_index[0], 0, sr_core ); nbi = 2 + p_index[0] + p_index[1]; p_index += nbi; @@ -94,9 +94,9 @@ int16_t dlpc_avq( { LSF_Q[i] = 0.0f; } - vlpc_1st_dec( p_index[0], &LSF_Q[0], sr_core ); + vlpc_1st_dec_flt( p_index[0], &LSF_Q[0], sr_core ); p_index++; - vlpc_2st_dec( &LSF_Q[0], &p_index[0], 0, sr_core ); + vlpc_2st_dec_flt( &LSF_Q[0], &p_index[0], 0, sr_core ); } else if ( q_type == 1 ) { @@ -105,7 +105,7 @@ int16_t dlpc_avq( LSF_Q[i] = LSF_Q[M + i]; } - vlpc_2st_dec( &LSF_Q[0], &p_index[0], 3, sr_core ); + vlpc_2st_dec_flt( &LSF_Q[0], &p_index[0], 3, sr_core ); } nbi = 2 + p_index[0] + p_index[1]; @@ -175,12 +175,12 @@ static int16_t pack4bits( /*------------------------------------------------------------------* - * decode_lpc_avq() + * decode_lpc_avq_flt() * * *------------------------------------------------------------------*/ -int16_t decode_lpc_avq( +int16_t decode_lpc_avq_flt( Decoder_State *st, /* i/o: decoder state structure */ const int16_t numlpc, /* i : Number of sets of lpc */ int16_t *param_lpc, /* o : lpc parameters */ diff --git a/lib_dec/dlpc_avq_fx.c b/lib_dec/dlpc_avq_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..b0a485de1b318ada51ce8aab2c9baa8d5f950126 --- /dev/null +++ b/lib_dec/dlpc_avq_fx.c @@ -0,0 +1,343 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + + +#include +#include "options.h" +#include +#include "prot_fx1.h" +#include "prot_fx2.h" + + /* Constants */ + +#define M 16 /* length of LPC */ +#define BFI_FAC 29491/*0.9f Q15*/ + +/***********************************************/ +/* Variable bit-rate multiple LPC un-quantizer */ +/***********************************************/ + +Word16 dlpc_avq( + Word16 *index, /* i : Quantization indices */ + Word16 *LSF_Q, /* o : Quantized LSF vectors */ + Word16 numlpc, /* i : Number of sets of lpc */ + Word32 sr_core /* i : Core sampling rate */ +) +{ + Word16 i, nbi, last; + Word16 *p_index, q_type; + + + /* Last LPC index */ + + move16(); + last = 0; + if ( NE_16(numlpc,1)) + { + move16(); + last = M; + } + + move16(); + p_index = index; + + /* Decode last LPC */ + + FOR (i=0; inext_bit_pos; + + /* Index bits */ + + move16(); + *ind = 0; + WHILE ((get_next_indice_1(st) != 0) && !st->BER_detect) + { + move16(); + *ind = add(*ind,1); + } + + if (*ind != 0) + { + move16(); + *ind = add(*ind, 1); + } + + return sub(st->next_bit_pos, start_bit_pos); + +} + +static Word16 pack4bits( + Word16 nbits, + Decoder_State *st, + Word16 *prm +) +{ + Word16 i; + + + move16(); + i=0; + + FOR ( ; nbits > 4; nbits -= 4 ) + { + move16(); + prm[i] = get_next_indice(st, 4); + i = add(i,1); + + + } + prm[i] = get_next_indice(st, nbits); + move16(); + i = add(i,1); + + return(i); +} + +Word16 decode_lpc_avq( + Decoder_State *st, /* i/o: decoder state structure */ + const Word16 numlpc, /* i : Number of sets of lpc */ + Word16* param_lpc /* o : lpc parameters */ +#ifdef IVAS_CODE_AVQ_LPC + ,const int16_t ch, /* i : channel */ + const int16_t element_mode, /* i : element mode */ + const int16_t sns_low_br_mode /* i : SNS low-bitrate mode */ +#endif +) +{ + Word16 k,j; + Word16 nb, qn1, qn2, avqBits, q_type; + Word16 start_bit_pos; +#ifdef IVAS_CODE_AVQ_LPC + Word16 stereo_mode = 0; +#endif + move16(); + move16(); + move16(); + j = 0; + start_bit_pos = st->next_bit_pos; + + FOR (k=0; kBER_detect = 1; + move16(); + } + + move16(); + param_lpc[j] = qn1; + j = add(j, 1); + move16(); + param_lpc[j] = qn2; + j = add(j, 1); + + /* Decode Split-by-2 algebraic VQ */ + avqBits = shl(qn1, 2); + + pack4bits(avqBits, st, ¶m_lpc[j]); + j = add(j, qn1); + + avqBits = shl(qn2, 2); + pack4bits(avqBits, st, ¶m_lpc[j]); + j = add(j, qn2); + } +#ifdef IVAS_CODE_AVQ_LPC + ELSE + { + param_lpc[j] = 0; + j = add(j, 1); + param_lpc[j] = 0; + j = add(j, 1); + move16(); + move16(); + } +#endif + } + + return sub(st->next_bit_pos, start_bit_pos); +} diff --git a/lib_dec/dlpc_stoch.c b/lib_dec/dlpc_stoch.c index c033c5bb054afe1eff12fcf28234d826a20c8f72..054c844b840ed74fbee8f21f35958ea62e884bc6 100644 --- a/lib_dec/dlpc_stoch.c +++ b/lib_dec/dlpc_stoch.c @@ -43,12 +43,12 @@ #include "wmc_auto.h" /*------------------------------------------------------------------* - * lpc_unquantize() + * lpc_unquantize_flt() * * *------------------------------------------------------------------*/ -void lpc_unquantize( +void lpc_unquantize_flt( Decoder_State *st, float *lsf, float *lsp, @@ -67,7 +67,7 @@ void lpc_unquantize( nb_indices = 0; if ( st->lpcQuantization == 0 ) { - nb_indices = dlpc_avq( param_lpc, &lsf[M], st->numlpc, st->sr_core ); + nb_indices = dlpc_avq_flt( param_lpc, &lsf[M], st->numlpc, st->sr_core ); for ( k = 0; k < st->numlpc; k++ ) { @@ -109,7 +109,7 @@ void lpc_unquantize( /* Decoded mid-frame lsf */ if ( st->lpcQuantization && st->acelp_cfg.midLpc && st->core == ACELP_CORE && st->rate_switching_reset == 0 ) { - midlsf_dec( &lsf[0], &lsf[M], param_lpc[nb_indices], lsfmid, M, coder_type, &( st->mid_lsf_int ), st->prev_bfi, st->safety_net ); + midlsf_dec_flt( &lsf[0], &lsf[M], param_lpc[nb_indices], lsfmid, M, coder_type, &( st->mid_lsf_int ), st->prev_bfi, st->safety_net ); reorder_lsf( lsfmid, LSF_GAP_MID, M, st->sr_core ); lsf2lsp( lsfmid, lspmid, M, st->sr_core ); diff --git a/lib_dec/dlpc_stoch_fx.c b/lib_dec/dlpc_stoch_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..be07d2a5a98ca0752a00d970635f4de320ad64ae --- /dev/null +++ b/lib_dec/dlpc_stoch_fx.c @@ -0,0 +1,110 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + + +/* Header files */ +#include +#include +#include "options.h" +#include "basop_util.h" +#include "prot_fx1.h" +#include "prot_fx2.h" + +/* Constants */ +#define M 16 +#define BFI_FAC 0.9f + + +void lpc_unquantize( + Decoder_State * st, + Word16 *lsf, + Word16 *lsp, + const Word16 m, + Word16* param_lpc, + Word16 *lspmid, + Word16 *lsfmid, + Word16 coder_type, + Word16 *LSF_Q_prediction /* o : LSF prediction mode */ +) +{ + Word16 nb_indices, k; + Word16 i; + + nb_indices = 0; /* to avoid compilation warnings */ + + + Copy(st->lsf_old_fx, &lsf[0], m); + Copy(st->lsp_old_fx, &lsp[0], m); + + IF(st->lpcQuantization == 0 ) + { + nb_indices = dlpc_avq(param_lpc, &lsf[m], st->numlpc, st->sr_core); + FOR ( k=0; k< st->numlpc; k++ ) + { + E_LPC_lsf_lsp_conversion(&lsf[(k+1)*m], &lsp[(k+1)*m], m); + } + } + ELSE IF ( EQ_16(st->lpcQuantization, 1)) + { + test(); + IF ((EQ_32(st->sr_core, INT_FS_16k))&&(EQ_16(coder_type,UNVOICED))) + { + lsf_end_dec_fx( st, 1, GENERIC, sub(1, st->narrowBand) /* st->bwidth */ , ENDLSF_NBITS, &lsf[m], param_lpc, LSF_Q_prediction, &nb_indices +#ifdef LSF_RE_USE_SECONDARY_CHANNEL + ,NULL +#endif + ); + } + ELSE + { + IF (EQ_16(st->core, TCX_20_CORE)) + { + lsf_end_dec_fx( st, 1, AUDIO, sub(1, st->narrowBand) /* st->bwidth */ , ENDLSF_NBITS, &lsf[m], param_lpc, LSF_Q_prediction, &nb_indices +#ifdef LSF_RE_USE_SECONDARY_CHANNEL + ,NULL +#endif + ); + + } + ELSE + { + lsf_end_dec_fx( st, 1, coder_type, sub(1, st->narrowBand) /* st->bwidth */ , ENDLSF_NBITS, &lsf[m], param_lpc, LSF_Q_prediction, &nb_indices +#ifdef LSF_RE_USE_SECONDARY_CHANNEL + ,NULL +#endif + ); + + } + } + + lsf2lsp_fx(&lsf[m], &lsp[m], M, st->sr_core); + } + ELSE + { + assert(0); + } + + st->seed_acelp=0; + move16(); + FOR(i=nb_indices-1; i>=0; i--) + { + st->seed_acelp = extract_l(L_mac0(L_mac0(13849, shr(st->seed_acelp, 1), 31821), param_lpc[i], 31821)); + } + + /* Decoded mid-frame isf */ + test(); + test(); + test(); + IF (st->lpcQuantization && st->acelp_cfg.midLpc&& st->core==ACELP_CORE && st->rate_switching_reset==0) + { + midlsf_dec ( &lsf[0], &lsf[m], param_lpc[nb_indices], lsfmid + ,coder_type ,&(st->mid_lsf_int_fx), st->prev_bfi, st->safety_net_fx); + reorder_lsf_fx( lsfmid, LSF_GAP_MID_FX, M, st->sr_core ); + lsf2lsp_fx(lsfmid, lspmid, M, st->sr_core); + } + + + return; +} + diff --git a/lib_dec/er_dec_acelp.c b/lib_dec/er_dec_acelp.c index 829ed27f3059a8072e2afc2a29a2e7ea4a42d697..05e84d769c6040172551f031e82354ddc3e9af60 100644 --- a/lib_dec/er_dec_acelp.c +++ b/lib_dec/er_dec_acelp.c @@ -42,12 +42,12 @@ #include "wmc_auto.h" /*-------------------------------------------------------------------* - * con_acelp() + * con_acelp_flt() * * Concealment function for ACELP and TD-TCX *--------------------------------------------------------------------*/ -void con_acelp( +void con_acelp_flt( float A[], /* i : coefficients NxAz[M+1] */ const int16_t coder_type, /* i : ACELP coder type */ float synth[], /* i/o: synthesis */ @@ -116,7 +116,7 @@ void con_acelp( T0 = st->guidedT0; } - pitch_pred_linear_fit( st->nbLostCmpt, st->last_good, st->old_pitch_buf, &st->old_fpitch_float, &predPitchLag, st->pit_min, st->pit_max, st->mem_pitch_gain_float, 0, st->plc_use_future_lag, &extrapolationFailed, st->nb_subfr ); + pitch_pred_linear_fit_flt( st->nbLostCmpt, st->last_good, st->old_pitch_buf, &st->old_fpitch_float, &predPitchLag, st->pit_min, st->pit_max, st->mem_pitch_gain_float, 0, st->plc_use_future_lag, &extrapolationFailed, st->nb_subfr ); T0 = (int16_t) ( predPitchLag + 0.5f ); if ( extrapolationFailed ) @@ -156,7 +156,7 @@ void con_acelp( /* PLC: [ACELP: Fade-out] * PLC: calculate damping factor */ - alpha = Damping_fact( coder_type, st->nbLostCmpt, st->last_good, stab_fac, &( st->lp_gainp ), 0 ); + alpha = Damping_fact_flt( coder_type, st->nbLostCmpt, st->last_good, stab_fac, &( st->lp_gainp ), 0 ); if ( st->nbLostCmpt == 1 ) { @@ -208,7 +208,7 @@ void con_acelp( { /* pitch cycle is first low-pass filtered */ /*get filter coefficients*/ - genPlcFiltBWAdap( st->sr_core, &lpFiltAdapt[0], 0, st->cummulative_damping_float); + genPlcFiltBWAdap_flt( st->sr_core, &lpFiltAdapt[0], 0, st->cummulative_damping_float); for ( i = 0; i < Tc; i++ ) { *pt_exc++ = ( lpFiltAdapt[0] * pt1_exc[-1] + lpFiltAdapt[1] * pt1_exc[0] + lpFiltAdapt[2] * pt1_exc[1] ); @@ -258,9 +258,9 @@ void con_acelp( { if ( fUseExtrapolatedPitch != 0 ) { - get_subframe_pitch( st->nb_subfr, st->old_fpitch_float, predPitchLag, pitch_buf ); + get_subframe_pitch_flt( st->nb_subfr, st->old_fpitch_float, predPitchLag, pitch_buf ); - PulseResynchronization( harmonic_exc_buf, exc, L_frame, st->nb_subfr, st->old_fpitch_float, predPitchLag ); + PulseResynchronization_flt( harmonic_exc_buf, exc, L_frame, st->nb_subfr, st->old_fpitch_float, predPitchLag ); } else { @@ -391,12 +391,12 @@ void con_acelp( } /*get filter coefficients*/ - genPlcFiltBWAdap( st->sr_core, &hp_filt[0], 1, st->cummulative_damping_float); + genPlcFiltBWAdap_flt( st->sr_core, &hp_filt[0], 1, st->cummulative_damping_float); /* PLC: [ACELP: Fade-out] * PLC: retrieve background level */ tmp = 1.0f; - gainSynthDeemph = getLevelSynDeemph( &( tmp ), A, L_SUBFR, st->preemph_fac_float, L_frame / L_SUBFR ); + gainSynthDeemph = getLevelSynDeemph_flt( &( tmp ), A, L_SUBFR, st->preemph_fac_float, L_frame / L_SUBFR ); gainCNG = st->cngTDLevel_float / gainSynthDeemph; gain = st->lp_gainc; /* start-of-the-frame gain */ @@ -415,7 +415,7 @@ void con_acelp( st->lp_gainc = gainCNG; } - highPassFiltering( st->last_good, L_frame + l_fir_fer / 2, noise_buf, hp_filt, l_fir_fer ); + highPassFiltering_flt( st->last_good, L_frame + l_fir_fer / 2, noise_buf, hp_filt, l_fir_fer ); /* Find energy normalization factor */ pt_exc = noise_buf + l_fir_fer / 2; diff --git a/lib_dec/er_dec_acelp_fx.c b/lib_dec/er_dec_acelp_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..bc7c27a2fa4d5e11eba34adf3ed5ec7e295e4c69 --- /dev/null +++ b/lib_dec/er_dec_acelp_fx.c @@ -0,0 +1,1164 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +/*VERSIONINFO: File up to date with trunk rev. 39929*/ + + +#include +#include "options.h" +#include +#include "prot_fx1.h" +#include "prot_fx2.h" +#include "basop_util.h" +#include "rom_dec.h" + +extern const Word16 T_DIV_L_Frame[];/*0Q15 * 2^-7 */ + +/*Table 2^7 * 1/L_frame */ + +#define L_SYN_BUF M+L_DIV_MAX+L_DIV_MAX +#define L_EXC_BUF OLD_EXC_SIZE_DEC_16k+L_DIV_MAX+L_SUBFR+1+L_DIV_MAX/2 + +/*LOCAL FUNCTIONS*/ +static void memsynPrecission(Word16 nbLostCmpt,Word16* mem_syn, Word16* exc, Word16 len, Word16*s_16); + + + +/*************************************************************** + * \brief Main concealment function for ACELP + * + * +****************************************************************/ + +void con_acelp( + const Word16 A[], /*mem_syn >rescaling done */ + Word16 *pitch_buffer, + Word16 *voice_factors, + Word16 *bwe_exc +) +{ + + Word16 i_subfr, i, T0; /*Q0*/ + Word16 tmp, tmp2, tmp_deemph; + Word16 mem_syn[M], mem_syn2[M], *syn; + Word16 *noise_buf; + Word16 *exc, *harmonic_exc_buf, buf[L_EXC_MEM_DEC+M+L_FRAME_16k+L_FRAME_16k/2]; /*Qf_exc*/ + const Word16 *p_A; + Word32 pitch_buf[NB_SUBFR16k] /*15Q16*/; + Word16 alpha; /*Q14*/ + Word16 step, gain, gainCNG,ftmp; + Word16 *pt_exc; + Word16 gain_inov; + Word16 gainCNG_e ; /*scaling Factor (exponent) of gainCNG*/ + Word16 Qf_syn; /*Q format and exponent of new synthesis*/ + Word16 *pt1_exc; + Word32 tmp_tc; /*15Q16*/ + Word16 extrapolationFailed; + Word32 predPitchLag; /*15Q16*/ + Word32 pc; /*float 15Q16*/ + Word16 fUseExtrapolatedPitch;/*int*/ + Word16 tmpSeed, Tc; /*Q0*/ + Word16 s_32; + Word16 synthScaling; + PWord16 const *w = st->hTcxCfg->tcx_mdct_window; + Word16 W1, W2; + Word16 nSubframes; + Word16 s_16, s_gain_inov, s2; + Word16 tmp_16, gain_16; + Word32 tmp_32, gain_32, step_32; + Word16 l_fir_fer; + Word16 lpFiltAdapt[3]; + Word16 hp_filt[3]; + Word16 Qf_syn_new; + Word16 exc_unv[L_FRAME_16k+L_FRAME_16k/2]; + Word16 syn_unv[L_FRAME_16k+L_FRAME_16k/2]; + Word16 mem_syn_unv[M]; + Word16 gain_lpc[NB_SUBFR16k]; + Word16 gain_lpc_e[NB_SUBFR16k]; + Word16 mem[M]; + Word16 h1[L_FRAME_16k/4+1]; + Word16 gainSynthDeemph; + Word16 gainSynthDeemph_e; + Word16 l; + Word16 g, g_e; + Word16 n; + const Word16 scale_h1 = 5; + HQ_DEC_HANDLE hHQ_core; + TCX_DEC_HANDLE hTcxDec; + + hHQ_core = st->hHQ_core; + hTcxDec = st->hTcxDec; + + /*Inits*/ + move16(); + l_fir_fer = L_FIR_FER; + + fUseExtrapolatedPitch = 0; + move16(); + extrapolationFailed = 1; + move16(); + + move16(); + move16(); + move16(); + alpha = 0; + /*st->Mode2_lp_gainc = L_shl(st->Mode2_lp_gainc,7);*/ /*rudiment, could be changed in the whole file but should work also*/ + pc=L_deposit_l(0); + + /*------------------------------------------------------------------------* + * Initialize buffers * + *------------------------------------------------------------------------*/ + + /* set ACELP synthesis memory */ + Copy( st->mem_syn2_fx, mem_syn, M); + + /* set excitation memory*/ + harmonic_exc_buf = buf+M; + exc = harmonic_exc_buf+L_EXC_MEM_DEC; + Copy( st->old_exc_fx, harmonic_exc_buf, L_EXC_MEM_DEC); + exc[st->L_frame] = 0; + move16(); + + /*------------------------------------------------------------------------* + * PLC: [ACELP:Extrapolate Pitch Lag] + *------------------------------------------------------------------------*/ + + if (EQ_16(st->flagGuidedAcelp, 1)) + { + T0 = st->guidedT0; + move16(); + } + + pitch_pred_linear_fit(st->nbLostCmpt, st->last_good_fx, + st->old_pitch_buf_fx, + &st->old_fpitch, + &predPitchLag, st->pit_min, st->pit_max, st->mem_pitch_gain, 0, + st->plc_use_future_lag, &extrapolationFailed, st->nb_subfr); + T0 = round_fx(predPitchLag); + + IF (extrapolationFailed != 0) + { + /*------------------------------------------------------------------------* + * - Construct adaptive codebook from side information * + *------------------------------------------------------------------------*/ + + IF (st->flagGuidedAcelp == 0) + { + nSubframes = 0; + move16(); + } + ELSE + { + nSubframes = 2; + move16(); + /* Construct adaptive codebook with T0, T0_frac, T0_res, gain_pit for 2 sub-frames */ + l = shl(L_SUBFR,1); + FOR (i = 0; i < l; i++) + { + exc[i] = exc[sub(i,st->guidedT0)]; + move16(); + } + } + } + ELSE + { + nSubframes = 0; + move16(); + } + + tmp_tc = st->old_fpitch; + move16(); /* take the previous frame last pitch*/ + if( nSubframes > 0 ) + { + tmp_tc = L_deposit_h(st->guidedT0); /* take the transmit pitch*/ + } + + /* PLC: [ACELP: Fade-out] + * PLC: calculate damping factor */ + alpha = Damping_fact(coder_type, st->nbLostCmpt, st->last_good_fx, stab_fac, &(st->Mode2_lp_gainp), 0); /*Q14*/ + st->cummulative_damping = shl(mult(st->cummulative_damping,alpha),1);/*shl(Q15*Q14,1)=shl(Q14,1) = Q15*/ + if (EQ_16(st->nbLostCmpt,1)) + { + st->cummulative_damping = 32767/*1.f Q15*/; /*Q15*/ + } + + /*-----------------------------------------------------------------* + * PLC: [ACELP: adaptive codebook] + * PLC: Construct the harmonic part of excitation + *-----------------------------------------------------------------*/ + + IF( GE_16(st->last_good_fx , UNVOICED_TRANSITION )) + { + + /*---------------------------------------------------------------* + * Last pitch cycle of the previous frame is repeatedly copied. * + *---------------------------------------------------------------*/ + + Tc = round_fx(tmp_tc); + BASOP_SATURATE_WARNING_OFF_EVS /*if this ever saturates, it doesn't matter*/ + tmp = sub(shl(abs_s(sub(T0,Tc)),6) , mult(19661/*0.15f Q17*/,shl(Tc,4)) /*Q6*/); + BASOP_SATURATE_WARNING_ON_EVS + test(); + test(); + test(); + if ((T0 > 0) && (NE_16(T0 , Tc)) + && ( tmp < 0 ) + && extrapolationFailed == 0 ) + { + fUseExtrapolatedPitch = 1; + move16(); + } + + pt_exc = exc; + if (st->enableGplc != 0) + { + pt_exc = &exc[nSubframes*L_SUBFR]; + } + pt1_exc = pt_exc - Tc; + + IF (fUseExtrapolatedPitch != 0) + { + /* Required because later pt1_exc[1] used in filtering points to exc[0]. To make it safe also for GPL pt_exc is used instead of exc */ + pt_exc[0] = 0; + move16(); + pt_exc = harmonic_exc_buf; + assert(pt_exc < pt1_exc-1); + } + + IF (EQ_16(st->nbLostCmpt, 1)) + { + /* pitch cycle is first low-pass filtered */ + + /*get filter coefficients*/ + genPlcFiltBWAdap( + st->sr_core, /*W32 Q0*/ + &lpFiltAdapt[0] /*Q15*/, + 0, + st->cummulative_damping /*Q15*/ + ); + FOR( i=0 ; i< Tc; i++ ) + { + + /* *pt_exc++ = ( lpFiltAdapt[0] * pt1_exc[-1] + lpFiltAdapt[1] * pt1_exc[0] + lpFiltAdapt[2] * pt1_exc[1]);*/ + tmp_32 = L_mult( lpFiltAdapt[0] , pt1_exc[-1]) ; + tmp_32 = L_mac(tmp_32, lpFiltAdapt[1] , pt1_exc[0]) ; + tmp_16 = mac_r(tmp_32, lpFiltAdapt[2] , pt1_exc[1]); + move16(); + *pt_exc = tmp_16; + pt_exc++; + pt1_exc++; + } + } + ELSE + { + /* copy the first pitch cycle without low-pass filtering */ + FOR( i=0 ; i< Tc; i++ ) + { + move16(); + *pt_exc++ = *pt1_exc++; + } + } + + if (fUseExtrapolatedPitch != 0) + { + pt1_exc = harmonic_exc_buf; + } + + l = add(st->L_frame,sub(imult1616(L_SUBFR,sub(1,nSubframes)),Tc)); + FOR( i= 0; i < l; i++ ) + { + move16(); + *pt_exc++ = *pt1_exc++; + } + + /*-------------------------------------------------------* + * PLC: [ACELP: adaptive codebook] + * PLC: Resync pulse positions. + *-------------------------------------------------------*/ + + IF( nSubframes > 0 ) + { + move16(); + move16(); + pitch_buf[0] = L_deposit_h(st->guidedT0); + pitch_buf[1] = L_deposit_h(st->guidedT0); + } + + IF (nSubframes>0) + { + move16(); + move16(); + pitch_buf[3] = pitch_buf[2] = pitch_buf[1]; /* do not resync on second half of frame */ + if (EQ_16(st->nb_subfr, 5)) + { + /* for guided acelp cases and nSubframes=2, set pitch_buf[4] to avoid memory_access issues in post_decoder() */ + pitch_buf[4] = pitch_buf[3]; + move16(); + } + } + ELSE + { + IF (fUseExtrapolatedPitch != 0) + { + + get_subframe_pitch(st->nb_subfr, st->old_fpitch, predPitchLag, pitch_buf); + PulseResynchronization(harmonic_exc_buf, exc, st->L_frame, st->nb_subfr, st->old_fpitch, predPitchLag); + } + ELSE { + set32_fx(pitch_buf, st->old_fpitch, st->nb_subfr); + } + } + + /*------------------------------------------------------------* + * PLC: [ACELP: adaptive codebook] + * PLC: Create the harmonic part needed for the overlap-add. + *------------------------------------------------------------*/ + pt_exc = exc+st->L_frame; + pt1_exc = pt_exc - T0; + if (T0 == 0) + { + pt1_exc = pt_exc - Tc; + } + l = shr(st->L_frame, 1); + FOR (i = 0; i < l; i++) + { + *pt_exc++ = *pt1_exc++; + move16(); + } + + /*-------------------------------------------------------* + * PLC: [ACELP: adaptive codebook] + * PLC: update the floating point pitch for consecutive loss + *-------------------------------------------------------*/ + + IF (fUseExtrapolatedPitch != 0) + { + move32(); + st->old_fpitch = predPitchLag; + if (EQ_16(st->flagGuidedAcelp ,1)) + { + st->old_fpitch = L_deposit_h(T0); + } + } + + /*-------------------------------------------------------* + * PLC: [ACELP: adaptive BPF] + * PLC: Accommodate the BPF + *-------------------------------------------------------*/ + + st->bpf_gain_param = 3 ; /*full BPF*/ move16(); + + /*-------------------------------------------------------* + * PLC: [ACELP: adaptive codebook] + * PLC: Calculate the initial gain and fade out step. + *-------------------------------------------------------*/ + + /* Compute pitch coherence (copied from decoder classifier)*/ + + pc = L_abs(L_sub(L_add(pitch_buf[3], L_sub(pitch_buf[2], pitch_buf[1])), pitch_buf[0])); /*9Q6*/ /*> 15Q16*/ + + /* mapping: floor(( 0.824[15Q15]-x[15Q0]*0.0733[0Q15] )*4) */ + + pc = Mpy_32_16_1( L_shl(pc,1)/*precompensate Q14 from table*/, /*15Q16*/ + T_256DIV_L_Frame[L_shr(L_msu0(54000,shr(st->L_frame,5),2402),15-2)]); + + test(); + test();/*test();*/ + IF (LE_16(st->last_good_fx , UNVOICED_TRANSITION) + && (EQ_16(coder_type , GENERIC ) ) + && GT_32(pc , 6*2*32768/*6(15Q16)*/ ) /*&& (stab_fac <= 0.5f)*/ + ) + { + gain = 0; + move16(); + st->Mode2_lp_gainp = L_deposit_l(0); + } + ELSE + { + gain = 0x4000 /*1 (1Q14)*/; /* start-of-the-frame gain */ + st->Mode2_lp_gainp = L_shl(L_deposit_l(alpha),15); /*1Q14->2Q29*/ + } + + tmp_16 = extract_l(L_shl(L_mac(-28000,st->L_frame,95),1-15)); + tmp_16 = T_DIV_L_Frame[tmp_16]; + tmp_32 = L_mult0(tmp_16 , sub(gain , alpha));/* 0Q15 * 2^-7 * 1Q14 -> 2Q29 * 2^-7*/ + tmp_32 = L_shr(tmp_32,6); /*-> 1Q30*/ + step = round_fx(tmp_32); /*->1Q14*/ + + /*FLC: step: 6.25e-5 .. 0.0045*/ /*-> s_step = -7*/ + /*lp_gainp : 0..0.2856..0.98*/ + + /*-------------------------------------------------------* + * PLC: [ACELP: Fade-out] + * Apply fade out + *-------------------------------------------------------*/ + + tmp_16 = 0; + move16(); + l = 0; + move16(); + FOR (i_subfr = 0; i_subfr < st->nb_subfr; i_subfr++) + { + pgainT[i_subfr] = gain; /*Q14*/ move16(); + i = l; + move16(); + l = add(l, L_SUBFR); + FOR (; i < l; i++) + { + move16(); + BASOP_SATURATE_WARNING_OFF_EVS +#ifdef BASOP_NOGLOB + exc[i] = mult_r(exc[i], shl_sat(gain, 1)); /*overflow is first iteration because gain may be 1 after shift*/ +#else + exc[i] = mult_r(exc[i] , shl(gain,1)); /*overflow is first iteration because gain may be 1 after shift*/ +#endif + BASOP_SATURATE_WARNING_ON_EVS + gain = sub(gain , step); + } + } + + l = add(st->L_frame,shr(st->L_frame,1)); + FOR (; i < l; i++ ) + { + move16(); + BASOP_SATURATE_WARNING_OFF_EVS +#ifdef BASOP_NOGLOB + exc[i] = mult_r(exc[i] , shl_sat(gain,1)); /*overflow is first iteration because gain may become 1 due to shift*/ +#else + exc[i] = mult_r(exc[i] , shl(gain,1)); /*overflow is first iteration because gain may become 1 due to shift*/ +#endif + BASOP_SATURATE_WARNING_ON_EVS + gain = sub(gain , step); + } + + FOR (i = 0; i < st->nb_subfr; i ++) + { + pT[i] = round_fx(pitch_buf[i]); /*Q0*/ + pitch_buffer[i] = round_fx(pitch_buf[i]); + } + + /* update old exc without random part*/ + Copy(harmonic_exc_buf+st->L_frame, st->old_exc_fx, L_EXC_MEM_DEC); + } + ELSE + { + /* No harmonic part */ + assert( (int)(sizeof(buf)/sizeof(buf[0])) - M - L_EXC_MEM_DEC >= st->L_frame + st->L_frame/2); + set16_fx(&exc[0], 0, add(st->L_frame, shr(st->L_frame,1))); + + FOR (i = 0; i < st->nb_subfr; i ++) + { + pitch_buf[i] = L_deposit_h(st->pit_max); /*15Q16*/ + pgainT[i] = 0; + move16(); + pT[i] = L_SUBFR; + move16(); + pitch_buffer[i] = L_SUBFR; + move16(); + } + + st->bpf_gain_param = 0; /*no BPF*/ move16(); + } + + /*-----------------------------------------------------------------* + * Construct the random part of excitation (5/2 st->L_frame + 2L_FIR_FER - 2) + * + * This is done in Q0 and will be corrected to current Q format of excitation + * when doing "non-causal ringing of the FIR filter" + * + * search for "Scale from randomized buffer to excitation buffer" + *-----------------------------------------------------------------*/ + noise_buf = buf; + move16(); + tmpSeed = st->seed_acelp; + move16(); + l = add(st->L_frame,sub(l_fir_fer,1)); + FOR (i = 0; i < l; i++) + { + tmpSeed = own_random2_fx(tmpSeed); + noise_buf[i] = tmpSeed; /*Q0*/ move16(); + } + + st->seed_acelp = tmpSeed; + move16(); + l = add(add(st->L_frame,shr(st->L_frame,1)),sub(l_fir_fer,1)); + FOR ( ; i < l; i++) + { + tmpSeed = own_random2_fx(tmpSeed); + noise_buf[i] = tmpSeed; /*Q0*/ move16(); + } + + /*get filter coefficients*/ + genPlcFiltBWAdap(st->sr_core, /*W32 Q0*/ + &hp_filt[0], /*Q15*/ + 1, + st->cummulative_damping); /*Q15*/ + + /* PLC: [ACELP: Fade-out] + * PLC: retrieve background level */ + + tmp2 = shl(div_s(st->L_frame,shl(L_SUBFR,3)),3-15); + + + tmp = 32767/*1.0f Q15*/; + gainSynthDeemph=getLevelSynDeemph(&(tmp), + A, + M, + L_SUBFR, + st->preemph_fac, + tmp2, + &gainSynthDeemph_e); + + + + /*gainCNG=st->cngTDLevel/gainSynthDeemph;*/ + BASOP_Util_Divide_MantExp(st->cngTDLevel, st->cngTDLevel_e, gainSynthDeemph, gainSynthDeemph_e,&gainCNG, &gainCNG_e); + gainCNG_e=sub(gainCNG_e,15-5);/*Q15->Q5*/ + if(gainCNG==0) + { + gainCNG_e = 0; + move16(); + } + + gain_32 = st->Mode2_lp_gainc; /*15Q16 *//* start-of-the-frame gain */ move16(); + + ftmp = round_fx(L_shl(gain_32,1));/*Q0*/ + + BASOP_SATURATE_WARNING_OFF_EVS +#ifdef BASOP_NOGLOB + tmp_16 = sub(shl_sat(gainCNG,sub(gainCNG_e,5/*Q5*/)),ftmp); +#else + tmp_16 = sub(shl(gainCNG,sub(gainCNG_e,5/*Q5*/)),ftmp); +#endif + /*in case of overflow:*/ + test(); +#ifdef BASOP_NOGLOB + if ((EQ_16(shl_sat(ftmp,sub(gainCNG_e,1)),MAXVAL_WORD16))&&(gainCNG==MAXVAL_WORD16)) +#else + if ((EQ_16(shl(ftmp,sub(gainCNG_e,1)),MAXVAL_WORD16))&&(gainCNG==MAXVAL_WORD16)) +#endif + { + move16(); + tmp_16 = 1; + } + BASOP_SATURATE_WARNING_ON_EVS + + IF (tmp_16 > 0 ) + { + gainCNG = ftmp/*Q0*/; + gainCNG_e = 5; /*-> Q5*/ + s_16 = norm_s(gainCNG); + gainCNG = shl(gainCNG,s_16); + gainCNG_e = sub(gainCNG_e,s_16); + } + + /* end-of-the-frame gain */ + /* st->Mode2_lp_gainc = alpha * st->Mode2_lp_gainc + (1.0f - alpha) * gainCNG;*/ + tmp_32 = Mpy_32_16_1(st->Mode2_lp_gainc /*Q16*/,alpha/*Q14*/);/*Q31-16 = Q15*/ + s_32 = norm_l(tmp_32); + tmp_32 = L_shl(tmp_32,s_32); + tmp_16 = round_fx(tmp_32); + s_16 = negate(s_32); + s_16 = sub(s_16,-1-15); /*->Q15*/ + + tmp2 = sub(16384/*1 in Q14*/,alpha); /*Q14*/ + tmp2 = mult(tmp2,gainCNG); /*Q14+Q5 +1 -16 = Q4*/ + s2 = norm_s(tmp2); + tmp2 = shl(tmp2,s2); + s2 = add(negate(s2),gainCNG_e); + s2 = sub(s2,4-15);/*->Q15*/ + + s_16 = BASOP_Util_Add_MantExp(tmp_16,s_16,tmp2,s2,&tmp_16); + st->Mode2_lp_gainc = L_shl(L_deposit_l(tmp_16),add(s_16,1)); + test(); + IF( (EQ_16(st->last_good_fx, UNVOICED_TRANSITION))&&(EQ_16(coder_type,GENERIC))) + { + st->Mode2_lp_gainc = L_deposit_h(gainCNG);/*Q21*/ + st->Mode2_lp_gainc = L_shr(st->Mode2_lp_gainc,sub(5,gainCNG_e)); /*15Q16, no scaling*/ + } + + highPassFiltering(st->last_good_fx, add(st->L_frame,shr(l_fir_fer,1)), noise_buf, hp_filt, l_fir_fer); + + pt_exc = noise_buf + l_fir_fer/2; + + /*** Find energy normalization factor ***/ + /*gain_inov = 1.0f / (float)sqrt( dot_product( pt_exc, pt_exc, st->L_frame ) / st->L_frame );*//* normalize energy */ /*<--- FLC*/ + + BASOP_SATURATE_WARNING_OFF_EVS /*norm_llQ31 at the end of Dot_productSq16HQ may throw an overflow, but result is okay*/ + tmp_32 = Dot_productSq16HQ(0,pt_exc,st->L_frame,&s_32); + BASOP_SATURATE_WARNING_ON_EVS + s_32 = add(s_32, 31-1); + /*scalingfactor is twice the headroom (at noise insertion onto the buffer), -1 (because of mult) +31 (Result is Q31) +s_32 (output scalingfactor of dot_product)*/ + + tmp_16 = T_DIV_L_Frame[L_shl(L_mac(-28000,st->L_frame,95),1-15)]; + tmp_32 = Mpy_32_16_1(tmp_32,tmp_16 ); /* Q31 * 2^s_32 * 0Q15 * 2^-7 */ + + s_32 = sub(s_32,7); /*tmp_32 is Q31 * 2^s_32 */ + + /*assure doing Isqrt not for 0*/ + IF (tmp_32 != 0) + { + s_gain_inov = s_32; + tmp_32 = ISqrt32(tmp_32, &s_gain_inov); + } + ELSE + { + s_gain_inov = 0; + tmp_32 = 0; + } + + + gain_inov = round_fx(tmp_32);/*Inverse sqrt*/ /* Q15 * 2^s_gain_inov */ + + /* PLC: [ACELP: Fade-out] + * PLC: Linearly attenuate the gain through the frame */ + + step_32 = L_sub(gain_32, st->Mode2_lp_gainc); /* 15Q16 */ + tmp_16 = extract_l(L_shl(L_mac(-28000,st->L_frame,95),1-15)); + step_32 = Mpy_32_16_1(step_32, T_DIV_L_Frame[tmp_16]); /* 15Q16 * 2^-7 = 15Q16 * Q15 * 2^-7 */ + step_32 = L_shr(step_32, 7); /* 15Q16 */ + + test(); + if ((EQ_16(st->last_good_fx ,UNVOICED_CLAS))&&(NE_16(coder_type,UNVOICED))) /* Attenuate somewhat on unstable unvoiced */ + { + gain_inov = mult_r(gain_inov, 26214/*0.8f Q15*/); /*Q15 * 2^s_gain_inov*/ + } + + IF ( GE_16(st->last_good_fx , UNVOICED_TRANSITION)) + { + Word16 tilt_code; + + /*tilt_code = (float)(0.10f*(1.0f + st->voice_fac));*/ + tilt_code = mac_r(214748368l/*0.1f Q31*/, 3277/*0.1f Q15*/ , st->voice_fac); + + gain_inov = mult_r(gain_inov, sub(32767/*1.0f Q15*/, tilt_code)); /* Q15 * 2^s_gain_inov */ + } + + pt_exc = noise_buf; + + /* non-causal ringing of the FIR filter */ + + /* gain_16 = gain_32 = gain_inov * gain */ + gain_32 = Mpy_32_16_1(gain_32, gain_inov); /* 15Q16 * Q15 * 2^s_gain_inov */ + gain_32 = L_shl(gain_32, add(15, s_gain_inov)); /* Q31 */ + gain_16 = round_fx(gain_32); /* Q15 */ + + /* step_32 = gain_inov * step */ + step_32 = Mpy_32_16_1(step_32, gain_inov); /* 15Q16 * Q15 * 2^s_gain_inov */ + step_32 = L_shl(step_32, add(15, s_gain_inov)); /* Q31 */ + + g_e = norm_s(round_fx(L_shl(Mpy_32_16_1(st->Mode2_lp_gainc, gain_inov), add(15, s_gain_inov)))); /* norm_s for gain*gain_inov at the end of the following loops */ + g_e = s_min(norm_s(gain_16), g_e); + gain_16 = shl(gain_16, g_e); + gain_32 = L_shl(gain_32, g_e); + step_32 = L_shl(step_32, g_e); + l = shr(l_fir_fer,1); + FOR( i=0 ; i < l; i++ ) + { + /* *pt_exc++ *= (gain_inov * gain); <=> *pt_exc++ *= gain_16; */ /*<-- FLC*/ + *pt_exc = mult_r(*pt_exc , gain_16); /* Q0 = Q0 * Q15 */ move16(); + pt_exc++; + } + + /* gain -= step; gain is updated after the loop and inside the loop gain_16 = gain_inov * gain is modified using gain_inov * (gain-step) = gain_inov * gain - gain_inov * step */ /*<-- FLC*/ + FOR( i=0 ; i < st->L_frame; i++ ) + { + /* *pt_exc++ *= (gain_inov * gain); <=> *pt_exc++ *= gain_16; */ /*<-- FLC*/ + *pt_exc = mult_r(*pt_exc , gain_16); /* Q0 = Q0 * Q15 */ move16(); + pt_exc++; + + gain_32 = L_sub(gain_32, step_32); + gain_16 = round_fx(gain_32); + } + + l = add(shr(st->L_frame,1),l_fir_fer/2); + FOR( i=0 ; i < l; i++ ) + { + /* *pt_exc++ *= (gain_inov * gain); <=> *pt_exc++ *= gain_16; */ /*<-- FLC*/ + *pt_exc = mult_r(*pt_exc , gain_16); /* Q0 = Q0 * Q15 */ move16(); + pt_exc++; + } + + /*store st->past_gcode*/ + /* at this point gain is equal to st->Mode2_lp_gainc, so we don't need to calculate gain at all */ + st->past_gcode = st->Mode2_lp_gainc; /*15Q16 */ move16(); + + /*-----------------------------------------------------------------* + * PLC: [ACELP: general] + * PLC: Construct the total excitation + *-----------------------------------------------------------------*/ + + IF( st->last_good_fx < UNVOICED_TRANSITION ) + { + bufferCopyFx(noise_buf+l_fir_fer/2, exc, add(st->L_frame,shr(st->L_frame,1)), 0, *Qf_exc, negate(g_e), 0); /*copy between different formats*/ + Copy(harmonic_exc_buf+st->L_frame, st->old_exc_fx, L_EXC_MEM_DEC); + Copy(exc, exc_unv, add(st->L_frame, shr(st->L_frame,1))); /* Update exc_unv */ + } + ELSE + { + /* Update exc_unv */ + bufferCopyFx(noise_buf+l_fir_fer/2, exc_unv, add(st->L_frame,shr(st->L_frame,1)), 0, *Qf_exc, negate(g_e), 0); /*copy between different formats*/ + } + + /* Compute total excitation in noisebuffer to save memories */ + IF( GE_16( st->last_good_fx, UNVOICED_TRANSITION )) + { + Vr_add(exc, exc_unv, noise_buf, add(st->L_frame, 1)); + } + ELSE + { + noise_buf = exc_unv; + } + IF(st->hBWE_TD != NULL) + { + IF(EQ_16(st->L_frame, L_FRAME)) + { + interp_code_5over2_fx(noise_buf, bwe_exc, st->L_frame); + set16_fx(voice_factors, st->last_voice_factor_fx, NB_SUBFR); + } + ELSE + { + interp_code_4over2_fx(noise_buf, bwe_exc, st->L_frame); + set16_fx(voice_factors, st->last_voice_factor_fx, NB_SUBFR16k); + } + } + /*----------------------------------------------------------* + * - compute the synthesis speech * + *----------------------------------------------------------*/ + + /* Init syn buffer */ + syn = buf + M; + Copy(st->mem_syn2_fx, buf, M ); + + IF (EQ_16(st->nbLostCmpt,1)) + { + IF( st->last_good_fx < UNVOICED_TRANSITION ) + { + Copy(st->mem_syn2_fx, mem_syn_unv, M ); + } + ELSE + { + set16_fx( mem_syn_unv, 0, M ); + } + } + ELSE + { + Copy( st->mem_syn_unv_back, mem_syn_unv, M ); + } + + /* voiced synth */ + IF(st->last_good_fx >= UNVOICED_TRANSITION) + { + p_A = A; + FOR (i_subfr = 0; i_subfr < st->L_frame; i_subfr += L_SUBFR) + { + tmp = 0; + move16(); + set16_fx(h1, 0, L_SUBFR+1); + set16_fx(mem, 0, M); + h1[0] = 1024/*1.0f/((float)(1 << scale_h1)) Q15*/; + move16(); + E_UTIL_synthesis(0, p_A, h1, h1, L_SUBFR, mem, 0, M); /* impulse response of LPC */ + deemph_fx(h1, st->preemph_fac, L_SUBFR, &tmp); /* impulse response of deemph */ + + /* impulse response level = gain introduced by synthesis+deemphasis */ + /* gain_lpc[i_subfr/L_SUBFR] = 1.f/(float)sqrt(dotp( h1, h1, L_SUBFR)); */ + tmp_32 = Dot_productSq16HQ(0, h1, L_SUBFR, &gain_lpc_e[i_subfr/L_SUBFR]); + tmp_32 = L_max(tmp_32, 1); + gain_lpc_e[i_subfr/L_SUBFR] = add(gain_lpc_e[i_subfr/L_SUBFR], 2*scale_h1); + move16(); + gain_lpc[i_subfr/L_SUBFR] = round_fx(ISqrt32(tmp_32, &gain_lpc_e[i_subfr/L_SUBFR])); + + p_A += (M+1); /* Pointer move */ + } + + g = 0; + move16(); + FOR (i_subfr = 0; i_subfr < st->L_frame; i_subfr += L_SUBFR) + { + + g = mult_r(st->last_gain_syn_deemph, gain_lpc[i_subfr/L_SUBFR]); +#ifdef BASOP_NOGLOB + g_e = add_sat(st->last_gain_syn_deemph_e, gain_lpc_e[i_subfr / L_SUBFR]); + g = shl_sat(g, g_e); +#else + g_e = add(st->last_gain_syn_deemph_e, gain_lpc_e[i_subfr/L_SUBFR]); + g = shl(g, g_e); +#endif + + FOR (i=0; i < L_SUBFR; i++) + { + /* exc[i_subfr + i] *= st->last_gain_syn_deemph*gain_lpc[j]; */ + exc[i_subfr + i] = mult_r(exc[i_subfr + i], g); + move16(); + } + } + l = add(st->L_frame, shr(st->L_frame, 1)); + FOR (i = st->L_frame; i < l; i++) + { + exc[i] = mult_r(exc[i], g); + move16(); + } + + /*Rescale the synthesis memory*/ + Qf_syn_new = *Qf_mem_syn; + move16(); + Qf_syn = *Qf_mem_syn; + move16(); + rescale_mem(Qf_exc, &Qf_syn_new, &Qf_syn, mem_syn, NULL, M, st->L_frame); + synthScaling = sub(*Qf_exc,Qf_syn); + + p_A = A; + + /*in case of more than 5 consecutive concealed frames, improve precision of synthesis*/ + memsynPrecission(st->nbLostCmpt,mem_syn, exc, st->L_frame, &s_16); + FOR (i_subfr = 0; i_subfr < st->L_frame; i_subfr += L_SUBFR) + { + + + E_UTIL_synthesis(synthScaling, p_A, &exc[i_subfr], &syn[i_subfr], L_SUBFR, mem_syn, 1, M); + p_A += (M+1); + } + Copy( mem_syn, mem_syn2, M ); + /* synthesize ola*/ + E_UTIL_synthesis(synthScaling, p_A-(M+1), &exc[i_subfr], &syn[i_subfr], (st->L_frame/2), mem_syn2, 0, M); + } + + test(); + IF(GT_16(st->nbLostCmpt,5)&&(s_16>0)) + { + /*scale back mem_syn, exc and synthesis*/ + Scale_sig(mem_syn,M,negate(s_16)); + Scale_sig(syn, add(shr(st->L_frame,1),st->L_frame) ,negate(s_16)); + /*Scale_sig(exc, add(shr(st->L_frame,1),st->L_frame) ,negate(s_16));*/ + } + + + /* unvoiced synth */ + + tmp = 0; + move16(); + p_A = st->Aq_cng; + + FOR (i_subfr = 0; i_subfr < st->L_frame; i_subfr += L_SUBFR) + { + set16_fx(h1, 0, L_SUBFR+1); + set16_fx(mem, 0, M); + h1[0] = 1024/*1.0f/((float)(1 << scale_h1)) Q15*/; + move16(); + E_UTIL_synthesis(0, p_A, h1, h1, L_SUBFR, mem, 0, M); /* impulse response of LPC */ + deemph_fx(h1, st->preemph_fac, L_SUBFR, &tmp); /* impulse response of deemph */ + + /* impulse response level = gain introduced by synthesis+deemphasis */ + /* gain_lpc[i_subfr/L_SUBFR] = 1.f/(float)sqrt(dotp( h1, h1, L_SUBFR)); */ + tmp_32 = Dot_productSq16HQ(0, h1, L_SUBFR, &gain_lpc_e[i_subfr/L_SUBFR]); + tmp_32 = L_max(tmp_32, 1); + gain_lpc_e[i_subfr/L_SUBFR] = add(gain_lpc_e[i_subfr/L_SUBFR], 2*scale_h1); + move16(); + gain_lpc[i_subfr/L_SUBFR] = round_fx(ISqrt32(tmp_32, &gain_lpc_e[i_subfr/L_SUBFR])); + + p_A += (M+1); /* Pointer move */ + } + + g = 0; + move16(); + FOR (i_subfr = 0; i_subfr < st->L_frame; i_subfr += L_SUBFR) + { + g = mult_r(st->last_gain_syn_deemph, gain_lpc[i_subfr/L_SUBFR]); + g_e = add(st->last_gain_syn_deemph_e, gain_lpc_e[i_subfr/L_SUBFR]); +#ifdef BASOP_NOGLOB + g = shl_sat(g, g_e); +#else + g = shl(g, g_e); +#endif + FOR (i=0; i < L_SUBFR; i++) + { + /* exc[i_subfr + i] *= st->last_gain_syn_deemph*gain_lpc[j]; */ + exc_unv[i_subfr + i] = mult_r(exc_unv[i_subfr + i], g); + move16(); + } + } + l = add(st->L_frame, shr(st->L_frame, 1)); + FOR (i = st->L_frame; i < l; i++) + { + exc_unv[i] = mult_r(exc_unv[i], g); + move16(); + } + + /* Update Qf_syn */ + Qf_syn_new = *Qf_mem_syn; + move16(); + Qf_syn = *Qf_mem_syn; + move16(); + rescale_mem(Qf_exc, &Qf_syn_new, &Qf_syn, mem_syn_unv, NULL, M, st->L_frame); + synthScaling = sub(*Qf_exc,Qf_syn); + *Qf_mem_syn = Qf_syn; + + p_A = st->Aq_cng; + + /*in case of more than 5 consecutive concealed frames, improve precision of synthesis*/ + memsynPrecission(st->nbLostCmpt,mem_syn_unv, exc_unv, st->L_frame, &s_16); + + FOR (i_subfr = 0; i_subfr < st->L_frame; i_subfr += L_SUBFR) + { + E_UTIL_synthesis(synthScaling, p_A, &exc_unv[i_subfr], &syn_unv[i_subfr], L_SUBFR, mem_syn_unv, 1, M); + p_A += (M+1); + } + Copy(mem_syn_unv,st->mem_syn_unv_back,M); + + IF(LT_16(st->last_good_fx,UNVOICED_TRANSITION)) + { + Copy(mem_syn_unv,mem_syn,M); + /* unvoiced for ola */ + E_UTIL_synthesis(synthScaling, p_A-(M+1), &exc_unv[i_subfr], &syn_unv[i_subfr], shr(st->L_frame,1), mem_syn_unv, 0, M); + } + + test(); + IF(GT_16(st->nbLostCmpt,5)&&(s_16>0)) + { + /*scale back mem_syn_unv, exc_unv and synthesis*/ + Scale_sig(mem_syn_unv,M,negate(s_16)); + IF(LT_16(st->last_good_fx,UNVOICED_TRANSITION)) + { + Scale_sig(mem_syn,M,negate(s_16)); + Scale_sig(syn_unv, add(shr(st->L_frame,1),st->L_frame) ,negate(s_16)); + } + ELSE + { + Scale_sig(syn_unv, st->L_frame ,negate(s_16)); + } + + Scale_sig(st->mem_syn_unv_back,M,negate(s_16)); + + /*Scale_sig(exc_unv, add(shr(st->L_frame,1),st->L_frame) ,negate(s_16));*/ + } + + /* add separate synthesis buffers */ + IF (GE_16(st->last_good_fx,UNVOICED_TRANSITION)) + { + FOR( i=0 ; i < st->L_frame; i++ ) + { + syn[i] = add(syn[i], syn_unv[i]); + move16(); + } + } + ELSE + { + Copy(syn_unv,syn,add(st->L_frame, shr(st->L_frame,1))); + } + + + /* update buffer for the classification */ + { + Word16 pit16[NB_SUBFR16k]; + Word16 k; + FOR(k = 0 ; k < st->nb_subfr; k++) + { + pit16[k] = shl(extract_h(pitch_buf[k]),6);/*Q6*/ + } + + FEC_clas_estim_fx( + st, + /*Opt_AMR_WB*/0, /*A*/ + st->L_frame, + &(st->clas_dec), + coder_type, + pit16, + syn, + &st->lp_ener_FER_fx, + /**decision_hyst*/NULL, /* i/o: hysteresis of the music/speech decision */ + /**UV_cnt*/ NULL, /* i/o: number of consecutives frames classified as UV */ + /**LT_UV_cnt*/ NULL, /* i/o: long term consecutives frames classified as UV */ + /**Last_ener*/ NULL, /* i/o: last_energy frame */ + /**locattack*/ NULL, /* i/o: detection of attack (mainly to localized speech burst) */ + /**lt_diff_etot*/NULL, /* i/o: long-term total energy variation */ + /**amr_io_class*/ NULL, /* i/o: classification for AMR-WB IO mode */ + /*bitrate*/ 0 , /* i : Decoded bitrate */ + Qf_syn, /* i : Synthesis scaling */ + /**class_para*/ NULL, /* o : classification para. fmerit1 */ + st->mem_syn_clas_estim_fx, /* i/o: memory of the synthesis signal for frame class estimation */ + &st->classifier_Q_mem_syn, /*i/o : exponent for memory of synthesis signal for frame class estimation */ + -32768/*-1.f Q15*/, /* i : LTP Gain */ + 0/*CLASSIFIER_ACELP*/, /* i : signal classifier mode */ + 1/*bfi*/, /* i : bad frame indicator */ + st->last_core_brate, /* i : bitrate of previous frame */ + -1 + ); + } + + /* Update Pitch Lag memory */ + Copy32(&st->old_pitch_buf_fx[st->nb_subfr], st->old_pitch_buf_fx, st->nb_subfr); + Copy32(pitch_buf, &st->old_pitch_buf_fx[st->nb_subfr], st->nb_subfr); + + /*updating enr_old parameters*/ + frame_ener_fx( st->L_frame, st->last_good_fx, syn, round_fx(tmp_tc), &(st->enr_old_fx), 1, 0, 0, 0 ); + + st->enr_old_fx = L_shl(st->enr_old_fx,shl(negate(Qf_syn),1)); + + /* update ACELP synthesis memory */ + Copy(mem_syn, st->mem_syn2_fx , M); + Copy(syn+st->L_frame-L_SYN_MEM, st->mem_syn_r , L_SYN_MEM); + + /*Q_mem_syn_new = Q_mem_syn;*//*NOT "+synthScaling", cause mem_syn format is not changed*/ + /* Deemphasis and output synth */ + tmp_deemph = st->syn[M]; + + E_UTIL_deemph2(*Qf_mem_syn, syn, st->preemph_fac, add(st->L_frame,shr(st->L_frame,1)), &tmp_deemph); + + Copy(syn, synth, st->L_frame); + + bufferCopyFx(syn+st->L_frame-st->L_frame/2, hTcxDec->old_syn_Overl, shr(st->L_frame,1),0 /*Qf_syn*/, -1 /*Qf_old_xnq*/, 0 , 0 /*Q_old_xnq*/); + + /* save last half frame if next frame is TCX */ + bufferCopyFx(syn+st->L_frame, hTcxDec->syn_Overl_TDAC, shr(st->L_frame,1),0 /*Qf_syn*/, -1 /*Qf_old_xnq*/, 0 , 0 /*Q_old_xnq*/ ); + Copy(syn+st->L_frame-M-1, st->syn, add(1,M)); + + /* update old_Aq */ + Copy(p_A-(M+1), st->old_Aq_12_8_fx, add(M,1)); + + + Copy(syn+st->L_frame, hTcxDec->syn_Overl, shr(st->L_frame,1)); + + /* create aliasing and windowing */ + + W1 = st->hTcxCfg->tcx_mdct_window_length; + move16(); + W2 = shr(W1,1); + st->hTcxCfg->tcx_curr_overlap_mode = FULL_OVERLAP; + move16(); + + n = extract_h(L_mult(st->L_frame,9216/*(float)N_ZERO_MDCT_NS/(float)FRAME_SIZE_NS Q15*/)); + + hHQ_core->Q_old_wtda_LB = getScaleFactor16(syn+st->L_frame-n, + sub(st->L_frame,n)); + move16(); + + bufferCopyFx(syn+st->L_frame-n, hHQ_core->old_out_LB_fx, sub(st->L_frame, n), 0, 0, hHQ_core->Q_old_wtda_LB, 0); + FOR (i=0; i < W2; i++) + { + hHQ_core->old_out_LB_fx[i+n] = round_fx(Mpy_32_16_1(L_mult(w[i].v.re,w[i].v.re), hHQ_core->old_out_LB_fx[i+n])); + } + FOR ( ; i < W1; i++) + { + hHQ_core->old_out_LB_fx[i+n] = round_fx(Mpy_32_16_1(L_mult(w[W2-1-(i-W2)].v.im,w[W2-1-(i-W2)].v.im), hHQ_core->old_out_LB_fx[i+n])); + } + set16_fx(&hHQ_core->old_out_LB_fx[W1+n], 0, n); + + hHQ_core->Q_old_wtda = hHQ_core->Q_old_wtda_LB; + + + + FOR (i=0; isyn_Overl_TDAC[i],w[i].v.re); + + } + FOR(; isyn_Overl_TDAC[i],w[W1-1-i].v.im); + } + + + FOR (i=0; isyn_Overl_TDAC[i] = add(buf[i],buf[W1-1-i]); /* A-D */ + } + /*-2*/ + FOR (i=0; isyn_Overl_TDAC[W2+i] = add(buf[W2+i],buf[W1-1-W2-i]);/* B-C */ + } + + + FOR (i=0; isyn_Overl_TDAC[i] = mult_r(hTcxDec->syn_Overl_TDAC[i],w[i].v.re); + } + + FOR(; isyn_Overl_TDAC[i] = mult_r(hTcxDec->syn_Overl_TDAC[i],w[W1-1-i].v.im); + } + + /* update memory for full band */ + lerp(hTcxDec->syn_Overl_TDAC, hTcxDec->syn_Overl_TDACFB, shr(hTcxDec->L_frameTCX, 1), shr(st->L_frame, 1)); + lerp(hTcxDec->syn_Overl, hTcxDec->syn_OverlFB, shr(hTcxDec->L_frameTCX, 1), shr(st->L_frame, 1)); + lerp(hHQ_core->old_out_LB_fx, hHQ_core->old_out_fx, hTcxDec->L_frameTCX, st->L_frame); + + /* copy total excitation exc2 as 16kHz for acelp mode1 decoding */ + IF(st->hWIDec != NULL) + { + lerp(exc, st->hWIDec->old_exc2_fx, L_EXC_MEM, st->L_frame); + lerp(syn, st->hWIDec->old_syn2_fx, L_EXC_MEM, st->L_frame); + } + st->bfi_pitch_fx = shl(round_fx(pitch_buf[st->nb_subfr-1]),6); + move16(); + st->bfi_pitch_frame = st->L_frame; + move16(); + + return; +} + +static void memsynPrecission(Word16 nbLostCmpt,Word16* mem_syn, Word16* exc, Word16 len, Word16*s_16) +{ + IF(GT_16(nbLostCmpt,5)) + { + Word16 sf_mem_syn, sf_exc,k, tmp_loop, max, tmp, i; + tmp = 0; + move16(); + *s_16 = 0; + move16(); + max = 0; + move16(); + + /*check energy of mem_syn*/ + FOR(i=0; i 0 ) + { + sf_mem_syn = getScaleFactor16(mem_syn,M); + /*sf_exc = getScaleFactor16(exc, add(shr(len,1),len));*/ /*this returns 0 if signal is 0*/ + tmp_loop = add(shr(len,1),len); + FOR(k=0; klp_gainp = 1.0f; } ana_window = buf; - ham_cos_window( ana_window, 3 * L_frame / 4, L_frame / 4 ); + ham_cos_window_flt( ana_window, 3 * L_frame / 4, L_frame / 4 ); /* Autocorrelation */ autocorr( &( synth[-L_frame - 1] ), r, M, L_frame, ana_window, 0, 0, 0 ); @@ -189,7 +189,7 @@ void con_tcx( } else { - pitch_pred_linear_fit( st->nbLostCmpt, st->last_good, old_pitch_buf, &( st->old_fpitchFB_float ), &predPitchLag, hTcxDec->pit_min_TCX, hTcxDec->pit_max_TCX, st->mem_pitch_gain_float, st->output_Fs > 25600, st->plc_use_future_lag, &extrapolationFailed, st->nb_subfr ); + pitch_pred_linear_fit_flt( st->nbLostCmpt, st->last_good, old_pitch_buf, &( st->old_fpitchFB_float ), &predPitchLag, hTcxDec->pit_min_TCX, hTcxDec->pit_max_TCX, st->mem_pitch_gain_float, st->output_Fs > 25600, st->plc_use_future_lag, &extrapolationFailed, st->nb_subfr ); T0 = (int16_t) ( predPitchLag + 0.5f ); @@ -248,9 +248,9 @@ void con_tcx( if ( fUseExtrapolatedPitch != 0 ) { - get_subframe_pitch( st->nb_subfr, st->old_fpitch_float, predPitchLag * st->L_frame / L_frame, pitch_buf ); + get_subframe_pitch_flt( st->nb_subfr, st->old_fpitch_float, predPitchLag * st->L_frame / L_frame, pitch_buf ); - PulseResynchronization( buf, exc, L_frame, st->nb_subfr, st->old_fpitchFB_float, predPitchLag ); + PulseResynchronization_flt( buf, exc, L_frame, st->nb_subfr, st->old_fpitchFB_float, predPitchLag ); } else { @@ -275,7 +275,7 @@ void con_tcx( st->bpf_gain_param = 0; /* PLC: calculate damping factor */ - alpha = Damping_fact( st->core_ext_mode, st->nbLostCmpt, st->last_good, st->stab_fac, &( st->lp_gainp ), ACELP_CORE ); + alpha = Damping_fact_flt( st->core_ext_mode, st->nbLostCmpt, st->last_good, st->stab_fac, &( st->lp_gainp ), ACELP_CORE ); if ( st->nbLostCmpt == 1 ) { @@ -334,7 +334,7 @@ void con_tcx( set_f( pitch_buf, (float) L_SUBFR, st->nb_subfr ); /* PLC: calculate damping factor */ - alpha = Damping_fact( st->core_ext_mode, st->nbLostCmpt, st->last_good, st->stab_fac, &( st->lp_gainp ), ACELP_CORE ); + alpha = Damping_fact_flt( st->core_ext_mode, st->nbLostCmpt, st->last_good, st->stab_fac, &( st->lp_gainp ), ACELP_CORE ); } /*-----------------------------------------------------------------* @@ -403,20 +403,20 @@ void con_tcx( { for ( i = 0; i < L_FIR_FER2; i++ ) { - hp_filt[i] = h_high3_16[i]; + hp_filt[i] = h_high3_16_flt[i]; } } else /*(st->output_Fs==32000)*/ { for ( i = 0; i < L_FIR_FER2; i++ ) { - hp_filt[i] = h_high3_32[i]; + hp_filt[i] = h_high3_32_flt[i]; } } if ( st->nbLostCmpt == 1 ) { - highPassFiltering( st->last_good, L_frame + L_frame / 2 + L_FIR_FER2, noise, hp_filt, L_FIR_FER2 ); + highPassFiltering_flt( st->last_good, L_frame + L_frame / 2 + L_FIR_FER2, noise, hp_filt, L_FIR_FER2 ); } else { @@ -433,11 +433,11 @@ void con_tcx( tmp = 1.0f; if ( A_cng != NULL ) { - gainSynthDeemph = getLevelSynDeemph( &( tmp ), A_cng, L_frame / 4, st->preemph_fac_float, 1 ) / 4.f; + gainSynthDeemph = getLevelSynDeemph_flt( &( tmp ), A_cng, L_frame / 4, st->preemph_fac_float, 1 ) / 4.f; } else { - gainSynthDeemph = getLevelSynDeemph( &( tmp ), A_local, L_frame / 4, st->preemph_fac_float, 1 ); + gainSynthDeemph = getLevelSynDeemph_flt( &( tmp ), A_local, L_frame / 4, st->preemph_fac_float, 1 ); } if ( st->tcxonly ) { @@ -555,7 +555,7 @@ void con_tcx( alpha_delayed = 1.0f; if ( st->nbLostCmpt > MDCT_ST_PLC_FADEOUT_DELAY_4_LSP_FADE ) { - alpha_delayed = Damping_fact( st->core_ext_mode, st->nbLostCmpt - MDCT_ST_PLC_FADEOUT_DELAY_4_LSP_FADE, st->last_good, st->stab_fac, &( st->lp_gainp ), ACELP_CORE ); + alpha_delayed = Damping_fact_flt( st->core_ext_mode, st->nbLostCmpt - MDCT_ST_PLC_FADEOUT_DELAY_4_LSP_FADE, st->last_good, st->stab_fac, &( st->lp_gainp ), ACELP_CORE ); } if ( st->plcBackgroundNoiseUpdated && alpha_delayed != 1.0f ) diff --git a/lib_dec/er_dec_tcx_fx.c b/lib_dec/er_dec_tcx_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..9ea6d2082cddd7500d2bc7aa52e56cd5fb753ffd --- /dev/null +++ b/lib_dec/er_dec_tcx_fx.c @@ -0,0 +1,1082 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + + +#include +#include +#include "options.h" +#include "prot_fx1.h" +#include "prot_fx2.h" +#include "basop_util.h" +#include "rom_dec.h" + + +/***************************************************** + calcGainc calculates st->lp_gainc +******************************************************/ +static void calcGainc(Word16* exc, Word16 Q_exc, Word32 old_fpitch, Word16 L_subfr, Word32 lp_gainp, Word32* lp_gainc) +{ + Word32 L_c ; + Word16 tmp16, tmp16_2, tmp16_3, tmp_e, tmp2_e, tmp_loop, i; + Word32 L_acc, L_tmp; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; + Flag Carry = 0; +#endif + + + L_acc = L_deposit_l(0); + L_c = L_deposit_l(0); + Overflow = 0; + Carry = 0; + + tmp16 = round_fx(old_fpitch);/*Q0*/ + tmp_loop = shl(L_subfr,1); + BASOP_SATURATE_WARNING_OFF_EVS +#ifdef BASOP_NOGLOB + tmp16_2 = round_fx_o(L_shl_o(lp_gainp,2, &Overflow), &Overflow); /*Q31->Q15, no severe saturation, because st->lp_gainp here is [0,1]*/ +#else + tmp16_2 = round_fx(L_shl(lp_gainp,2)); /*Q31->Q15, no severe saturation, because st->lp_gainp here is [0,1]*/ +#endif + BASOP_SATURATE_WARNING_ON_EVS + + FOR ( i=0; i< tmp_loop; i++ ) + { + /*st->lp_gainc += ( exc[i-2*L_subfr] - st->Mode2_lp_gainp * exc[i-2*L_subfr-(int)(st->old_fpitch+0.5f)] ) * + ( exc[i-2*L_subfr] - st->Mode2_lp_gainp * exc[i-2*L_subfr-(int)(st->old_fpitch+0.5f)] );*/ +#ifdef BASOP_NOGLOB + tmp16_3 = sub_o(exc[i-2*L_subfr] /*Q1*/,mult_r(tmp16_2 /*Q15*/, exc[i-2*L_subfr-tmp16]/*Q1*/)/*Q1*/, &Overflow); +#else + tmp16_3 = sub(exc[i-2*L_subfr] /*Q1*/,mult_r(tmp16_2 /*Q15*/, exc[i-2*L_subfr-tmp16]/*Q1*/)/*Q1*/); +#endif +#ifdef BASOP_NOGLOB + L_acc = L_macNs_co(L_acc, tmp16_3, tmp16_3, &Carry, &Overflow); /*Q3*/ +#else + L_acc = L_macNs(L_acc,tmp16_3,tmp16_3); /*Q3*/ +#endif + Overflow = 0; +#ifdef BASOP_NOGLOB + L_c = L_macNs_co(L_c, 0, 0, &Carry, &Overflow); /*Accumulate Carrys*/ +#else + L_c = L_macNs(L_c,0,0); /*Accumulate Carrys*/ +#endif + Carry = 0; + } + L_tmp = norm_llQ31(L_c,L_acc,&tmp_e);/*Q3,norm,tmp_e*/ + tmp_e = add(tmp_e,31-(add(shl(Q_exc,1),1))); /*L_tmp is Q31, now*/ + tmp16 = BASOP_Util_Divide3216_Scale(L_tmp/*Q31,norm,tmp_e*/,shl(L_subfr,1)/*Q15,15*/,&tmp2_e)/*Q15,tmp2_e+tmp_e-15*/; + tmp_e = sub(add(tmp2_e,tmp_e), 15); + + IF (tmp16 != 0) + { + tmp16 = Sqrt16(tmp16,&tmp_e); /*Q15,norm,tmp_e*/ + } + *lp_gainc = L_shl(L_deposit_l(tmp16),add(tmp_e,1)); /*15Q16*/ + +} + +static void calcGainc2(Word16 *exc, Word16 Q_exc, Word16 L_subfr, Word32* lp_gainc) +{ + Word16 i, cnt, tmp16 , tmp_e, tmp2_e; + Word32 L_c, L_acc, L_tmp; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; + Flag Carry = 0; +#endif + + + Carry = 0; + Overflow = 0; + + L_c = L_deposit_l(0); + L_acc = L_deposit_l(0); + + cnt = shl(L_subfr,1); + + FOR (i=0; i < cnt; i++) + { + /* *gainc += ( exc[i-2*L_subfr] ) * ( exc[i-2*L_subfr]); */ +#ifdef BASOP_NOGLOB /* Critical Carry/Overflow */ + L_acc = L_macNs_co(L_acc, exc[i-2*L_subfr] /*Q1*/, exc[i-2*L_subfr] /*Q1*/, &Carry, &Overflow); /*Q3*/ +#else + L_acc = L_macNs(L_acc, exc[i-2*L_subfr] /*Q1*/, exc[i-2*L_subfr] /*Q1*/); /*Q3*/ +#endif + Overflow = 0; +#ifdef BASOP_NOGLOB /* Critical Carry/Overflow */ + L_c = L_macNs_co(L_c,0,0, &Carry, &Overflow); /* Accumulate Carrys */ +#else + L_c = L_macNs(L_c,0,0); /* Accumulate Carrys */ +#endif + Carry = 0; + } + + L_tmp = norm_llQ31(L_c,L_acc,&tmp_e); /*Q3,norm,tmp_e*/ + tmp_e = add(tmp_e,31-(add(shl(Q_exc,1),1))); /*L_tmp is Q31, now*/ + tmp16 = BASOP_Util_Divide3216_Scale(L_tmp/*Q31,norm,tmp_e*/,shl(L_subfr,1)/*Q15,15*/,&tmp2_e)/*Q15,tmp2_e+tmp_e-15*/; + tmp_e = sub(add(tmp2_e,tmp_e), 15); + + IF ( tmp16 != 0 ) + { + tmp16 = Sqrt16(tmp16,&tmp_e); /*Q15,norm,tmp_e*/ + } + *lp_gainc = L_shl(L_deposit_l(tmp16),add(tmp_e,1)); /*15Q16*/ move32(); + +} + +/****************************************************** + +con_tcx + +\brief main function in time domain TCX concealment + +*******************************************************/ + +void con_tcx( + Decoder_State *st, /* i/o: coder memory state */ + Word16 synth[] /* i/o: synth[] *//*Q0 */ +#ifdef IVAS_CODE_CON_TCX + ,const Word16 coh, /* i : coherence of stereo signal */ + Word16 * noise_seed, /* i/o: noise seed for stereo */ + const Word16 only_left /* i : TD-PLC only in left channel */ +#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT + ,const float* A_cng /* i : CNG LP filter coefficients */ +#endif +#endif + +) +{ + Word16 i, s, c, L_frame, L_subfr, fLowPassFilter, T0; + Word16 n, mem_syn_r_size_old, mem_syn_r_size_new; + Word16 *noise; + Word16 mem_syn[M], *syn; + Word16 *exc, buf[OLD_EXC_SIZE_DEC+L_FRAME_MAX+L_FRAME_MAX/NB_SUBFR+1+L_FRAME_MAX/2]; + Word16 pre_emph_buf; + Word16 hp_filt[L_FIR_FER2]; + Word16 alpha; + Word16 tmp_deemph, gain, gainCNG, gain_inov; + Word16 *pt_exc, *pt1_exc; + Word16 Tc, tmpSeed; + Word16 fUseExtrapolatedPitch; + Word16 *ana_window; + Word16 r_h[M+1], A_local[M+1], mem, r_l[M+1]; + PWord16 const *w; + Word16 W1, W2, W12; + Word16 Q_r; + Word16 tmp16, tmp16_2, tmp_loop, tmp_e, gain_tmp; + Word16 gainCNG_e, noise_e, gain_inov_e ;/*Exponents for gainCNG, noise, gain_inov*/ + Word16 Q_syn; /*Q format of temporary synthesis buffer syn*/ + Word32 L_tmp, L_tmp2, step32_tmp; + Word32 predPitchLag, pitch_buf[NB_SUBFR16k], step32, gain32; + Word16 extrapolationFailed; + Word16 gainSynthDeemph; + Word16 gainSynthDeemph_e; + Word32 old_pitch_buf[2*NB_SUBFR16k+2]; + Word16 Q_exc, new_Q, exp_scale; + Word16 offset; + HQ_DEC_HANDLE hHQ_core; + TCX_LTP_DEC_HANDLE hTcxLtpDec; + TCX_DEC_HANDLE hTcxDec; + + hTcxLtpDec = st->hTcxLtpDec; + hHQ_core = st->hHQ_core; + hTcxDec = st->hTcxDec; + + /* inits */ + alpha = 0; + move16(); + fUseExtrapolatedPitch = 0; + move16(); + extrapolationFailed = 1; + move16(); + + noise_e = 0; + move16(); + Q_syn = -1; /*Q format of temporary synthesis buffer syn*/ move16(); + offset = 0; + move16(); + + /* Framing parameters */ + L_frame = hTcxDec->L_frameTCX; + move16(); + /* L_subfr = st->L_frameTCX/st->nb_subfr */ + L_subfr = mult_r(hTcxDec->L_frameTCX,div_s(1,st->nb_subfr)); + assert( L_subfr == hTcxDec->L_frameTCX/st->nb_subfr ); + move32(); + w = st->hTcxCfg->tcx_mdct_windowFB; /*pointer - no need to instrument*/ + W1 = st->hTcxCfg->tcx_mdct_window_lengthFB; + move16(); + W2 = shr(st->hTcxCfg->tcx_mdct_window_lengthFB, 1); + W12 = shr(W1,1); + + /* take the previous frame last pitch */ + Tc = round_fx(st->old_fpitchFB); + + + set16_fx(buf,0, OLD_EXC_SIZE_DEC + L_FRAME_MAX + L_FRAME_MAX / NB_SUBFR + 1 + L_FRAME_MAX / 2); /* initialize buf with 0 */ + //set16_fx(buf,0,shr(sizeof(buf),1)); /* initialize buf with 0 */ + + c = BASOP_Util_Divide1616_Scale( + L_frame, + st->L_frame, + &s + ); + + FOR (i=0; i < (2*NB_SUBFR16k+2); i++) + { + old_pitch_buf[i] = L_shl(Mpy_32_16_1(st->old_pitch_buf_fx[i],c),s); + move32(); + } + + /* set excitation memory*/ + exc = buf+OLD_EXC_SIZE_DEC; + tmp_deemph = synth[-1]; + move16(); + pre_emph_buf = synth[-1]; + move16(); + + test(); + IF ( (EQ_16( st->nbLostCmpt, 1 ))|| hTcxDec->tcxConceal_recalc_exc) + { + /* apply pre-emphasis to the signal */ + mem = synth[-((shr(L_frame,1))+ hTcxDec->pit_max_TCX+M+M)-1]; + Q_exc = E_UTIL_f_preemph3(&(synth[-((shr(L_frame,1))+ hTcxDec->pit_max_TCX+2*M)]), st->preemph_fac, add(add(shr(L_frame,1), hTcxDec->pit_max_TCX),shl(M,1)), &mem,1); + st->Mode2_lp_gainc = L_deposit_l(0); + + st->Mode2_lp_gainp = get_gain2( synth-2*L_subfr, synth-2*L_subfr-Tc, shl(L_subfr,1) ); + move32(); + + st->Mode2_lp_gainp = L_max(st->Mode2_lp_gainp,0); + st->Mode2_lp_gainp = L_min(st->Mode2_lp_gainp,65536l/*1.0f Q16*/); + st->Mode2_lp_gainp = L_shl(st->Mode2_lp_gainp, 13); + + ana_window = buf; + ham_cos_window(ana_window, mult(L_frame,24576/*0.75f Q15*/), shr(L_frame,2)); + + /* Autocorrelation */ + autocorr_fx(&(synth[-L_frame-1]), M, r_h ,r_l , &Q_r , L_frame, ana_window, 0, 0); + + /* Lag windowing */ + lag_wind( r_h,r_l, M, st->output_Fs, LAGW_STRONG ); + + /* Levinson Durbin */ + E_LPC_lev_dur(r_h, r_l, A_local, NULL, M, NULL); + + /* copy for multiple frame loss */ + Copy(A_local, st->old_Aq_12_8_fx, M+1); + + /* Residu */ + assert((2*L_subfr+Tc+1+M) <= hTcxDec->old_synth_lenFB); + + BASOP_SATURATE_WARNING_OFF_EVS /*saturation possible in case of spiky synthesis*/ + Residu3_fx( + A_local, + &(synth[-(2*L_subfr+Tc+1+M)]), /*Qx = Q0*/ + &(exc[-(2*L_subfr+Tc+1+M)]), /*Qx+1 = Q1*/ + add(add(add(shl(L_subfr,1),Tc),1),M), + 1); + BASOP_SATURATE_WARNING_ON_EVS + } + ELSE + { + /* apply pre-emphasis to the signal */ + mem = synth[-L_frame-1]; + Q_exc = E_UTIL_f_preemph3(&(synth[-L_frame]), st->preemph_fac, L_frame, &mem, 1); + Copy(st->old_Aq_12_8_fx, A_local, M+1); + + offset = shr(L_frame,1); + IF(GE_16(st->last_good_fx, UNVOICED_TRANSITION)) + { + tmp16 = s_max(Tc - shr(L_frame,1), 0); + Copy_Scale_sig(hTcxDec->old_excFB_fx, &(exc[-tmp16]), offset+tmp16, Q_exc-st->Q_exc); + } + ELSE { + Copy_Scale_sig(hTcxDec->old_excFB_fx, &(exc[-2*L_subfr]), 2*L_subfr+offset, Q_exc-st->Q_exc); + } + } + + /*-----------------------------------------------------------------* + * PLC: Construct the harmonic part of excitation + *-----------------------------------------------------------------*/ + + test(); + test(); + IF( GT_16(st->last_good_fx, UNVOICED_CLAS)&&!(EQ_16(st->last_good_fx,UNVOICED_TRANSITION)&&EQ_16(st->core_ext_mode,GENERIC))) + { + + IF ( EQ_16(st->nbLostCmpt,1)|| hTcxDec->tcxConceal_recalc_exc) + { + calcGainc( exc, Q_exc, st->old_fpitchFB, L_subfr, st->Mode2_lp_gainp, &(st->Mode2_lp_gainc)); + } + + tmp16 = 0; + move16(); + if (GT_32(st->output_Fs , 25600)) + { + tmp16 = 1; + move16(); + } + + test(); + test(); + test(); + test(); + IF( ((EQ_16(st->nbLostCmpt,1))|| hTcxDec->tcxConceal_recalc_exc)&&GE_16(st->rf_frame_type,RF_TCXFD)&&LE_16(st->rf_frame_type,RF_TCXTD2)&&st->use_partial_copy) + { + Word32 tcxltp_pitch_tmp = L_add(L_deposit_h(hTcxLtpDec->tcxltp_pitch_int), L_shl(L_deposit_l(div_s(hTcxLtpDec->tcxltp_pitch_fr,st->pit_res_max)),1)); /*15Q16*/ + Word16 scale_tmp = mult_r(hTcxDec->L_frameTCX, getInvFrameLen(st->L_frame)); /*getInvFrameLen()->9Q6*/ + Word16 tmp_shift = norm_s(scale_tmp); + predPitchLag = L_shl(Mpy_32_16_1(tcxltp_pitch_tmp, shl(scale_tmp, tmp_shift)), sub(9, tmp_shift)); + + T0 = round_fx(predPitchLag); + + test(); + test(); + test(); + if ( (T0 > 0) + && (NE_16(T0,Tc) ) + && (LT_32(L_deposit_h(abs_s(sub(T0,Tc)))/*Q16*/ , L_mult(4915/*.15f Q15*//*Q15*/,Tc/*Q0*/) /*Q16*/ ) ) + ) + { + fUseExtrapolatedPitch = 1; + move16(); + } + } + ELSE + { + + pitch_pred_linear_fit( + st->nbLostCmpt, + st->last_good_fx, + old_pitch_buf, + &(st->old_fpitchFB), + &predPitchLag, + hTcxDec->pit_min_TCX, + hTcxDec->pit_max_TCX, + st->mem_pitch_gain, + tmp16, + st->plc_use_future_lag, + &extrapolationFailed, + st->nb_subfr + ); + + T0 = round_fx(predPitchLag); + test(); + test(); + test(); + if ( (T0 > 0) + && (NE_16(T0,Tc) ) + && (LT_32(L_deposit_h(abs_s(sub(T0,Tc)))/*Q16*/ , L_mult(4915/*.15f Q15*//*Q15*/,Tc/*Q0*/) /*Q16*/ ) ) + && (extrapolationFailed == 0) + ) + { + fUseExtrapolatedPitch = 1; + move16(); + } + } + + + fLowPassFilter = 0; + move16(); + pt_exc = exc + offset; + pt1_exc = pt_exc - Tc; + + if (fUseExtrapolatedPitch != 0) + { + pt_exc = buf; + } + test(); + IF( LT_16(st->stab_fac_fx ,32767/*1.f Q15*/)&&EQ_16(st->nbLostCmpt,1)) + { + /* pitch cycle is first low-pass filtered */ + + IF (LE_32(st->output_Fs , 16000)) + { + FOR( i=0 ; i< Tc; i++ ) + { + move16(); + *pt_exc++ = mac_r(L_mac(L_mac(L_mac(L_mac(L_mac(L_mac(L_mac(L_mac(L_mac( + L_mult(174/* 0.0053f Q15*/, pt1_exc[-5]), + 0/* 0.0000f Q15*/, pt1_exc[-4]), + -1442/*-0.0440f Q15*/, pt1_exc[-3]), + 0/* 0.0000f Q15*/, pt1_exc[-2]), + 8641/* 0.2637f Q15*/, pt1_exc[-1]), + 18022/* 0.5500f Q15*/, pt1_exc[0] ), + 8641/* 0.2637f Q15*/, pt1_exc[1] ), + 0/* 0.0000f Q15*/, pt1_exc[2] ), + -1442/*-0.0440f Q15*/, pt1_exc[3] ), + 0/* 0.0000f Q15*/, pt1_exc[4] ), + 174/* 0.0053f Q15*/, pt1_exc[5] ); + pt1_exc++; + } + } + ELSE /*(st->output_Fs >= 32000)*/ + { + FOR( i=0 ; i< Tc; i++ ) + { + move16(); + *pt_exc++ = mac_r(L_mac(L_mac(L_mac(L_mac(L_mac(L_mac(L_mac(L_mac(L_mac( + L_mult(-174/*-0.0053f Q15*/, pt1_exc[-5]), + -121/*-0.0037f Q15*/, pt1_exc[-4]), + -459/*-0.0140f Q15*/, pt1_exc[-3]), + 590/* 0.0180f Q15*/, pt1_exc[-2]), + 8743/* 0.2668f Q15*/, pt1_exc[-1]), + 16355/* 0.4991f Q15*/, pt1_exc[0] ), + 8743/* 0.2668f Q15*/, pt1_exc[1] ), + 590/* 0.0180f Q15*/, pt1_exc[2] ), + -459/*-0.0140f Q15*/, pt1_exc[3] ), + -121/*-0.0037f Q15*/, pt1_exc[4] ), + -174/*-0.0053f Q15*/, pt1_exc[5] ); + pt1_exc++; + } + } + + fLowPassFilter = 1; + move16(); + } + ELSE + { + /* copy the first pitch cycle without low-pass filtering */ + FOR( i=0 ; i < Tc; i++ ) + { + *pt_exc++ = *pt1_exc++; + move16(); + } + fLowPassFilter = 1; + move16(); + } + + if (fUseExtrapolatedPitch != 0) + { + pt1_exc = buf; + } + tmp16 = add(sub(L_frame,imult1616(fLowPassFilter,Tc)),L_subfr); + FOR (i = 0; i < tmp16; i++) + { + *pt_exc++ = *pt1_exc++; + move16(); + } + + IF (fUseExtrapolatedPitch != 0) + { + get_subframe_pitch(st->nb_subfr, + st->old_fpitch, + /* predPitchLag * L_frame/st->L_frame, */ + L_shr(Mpy_32_16_1(predPitchLag/*Q16*/, + mult_r(st->L_frame/*Q0*/, + getInvFrameLen(L_frame)/*Q21*/ + )/*Q6*/ + )/*Q7*/, + 7-16)/*Q16*/, + pitch_buf); + + PulseResynchronization(buf, exc, L_frame, st->nb_subfr, st->old_fpitchFB, predPitchLag); + } + ELSE + { + set32_fx( pitch_buf, st->old_fpitch, st->nb_subfr); + } + + IF ( EQ_16(st->nbLostCmpt , 1)) + { + pt_exc = exc+L_frame; + IF (T0 == 0) + { + pt1_exc = pt_exc - Tc; + } + ELSE + { + pt1_exc = pt_exc - T0; + } + + tmp_loop = shr(L_frame,1); + FOR (i = 0; i < tmp_loop; i++) + { + *pt_exc++ = *pt1_exc++; + move16(); + } + } + + if (fUseExtrapolatedPitch != 0) + { + st->old_fpitchFB = predPitchLag; + move16(); + } + st->bpf_gain_param = 0; + move16(); + + /* PLC: calculate damping factor */ +#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT + alpha = 1.0f; + if (st->element_mode == IVAS_CPE_MDCT && st->nbLostCmpt >= MDCT_ST_PLC_FADEOUT_START_FRAME) + { + alpha = Damping_fact(st->core_ext_mode, st->nbLostCmpt - MDCT_ST_PLC_FADEOUT_START_FRAME, st->last_good, st->stab_fac, &(st->lp_gainp), 0); + } + else if (st->element_mode != IVAS_CPE_MDCT) + { + alpha = Damping_fact(st->core_ext_mode, st->nbLostCmpt, st->last_good, st->stab_fac, &(st->lp_gainp), 0); + } +#else + alpha = Damping_fact(st->core_ext_mode, st->nbLostCmpt, st->last_good_fx, st->stab_fac_fx, &(st->Mode2_lp_gainp), 0);/*Q14*/ +#endif + IF ( EQ_16(st->nbLostCmpt , 1)) + { + st->cummulative_damping = 32767/*1.f Q15*/; + move16(); + } + ELSE + { +#ifdef BASOP_NOGLOB + st->cummulative_damping = shl_sat(mult_r_sat(st->cummulative_damping/*Q15*/,alpha/*Q14*/),1)/*Q15*/; +#else + st->cummulative_damping = shl(mult_r(st->cummulative_damping/*Q15*/,alpha/*Q14*/),1)/*Q15*/; +#endif + } + + gain32 = L_add(2147483647l/*1.f Q31*/, 0); /*Q31*/ + gain = 32767/*1.f Q15*/; /*Q15*/ move16(); + if( EQ_16(st->rf_frame_type, RF_TCXTD1)&&EQ_16(st->use_partial_copy,1)) + { + gain32 = 1073741824l/*0.5f Q31*/; + gain = 16384/*0.5f Q15*/; + } + + /*step = (1.0f/(L_frame+(L_frame/2))) * (gain - alpha);*/ + tmp16 = shr(imult1616(3,L_frame),1); + tmp_e = norm_s(tmp16); + tmp16 = shl(tmp16,tmp_e); + tmp16 = div_s(16384/*1.f Q14*/,tmp16);/*Q15,1+tmp_e-15*/ + tmp16_2 = sub(shr(gain,1),alpha)/*Q14*/; + step32 = L_shl(L_mult(tmp16,tmp16_2)/*Q30, 1+tmp_e-15*/,add(1-14,tmp_e))/*Q31*/; + + /* PLC: Apply fade out */ + tmp_loop = shr(imult1616(L_frame,3),1); + FOR ( i=offset; i < tmp_loop; i++ ) + { +#ifdef BASOP_NOGLOB + exc[i] = mult_r(exc[i], round_fx_sat(gain32))/*Q1*/; + move16(); + gain32 = L_sub_sat(gain32, step32); +#else + exc[i] = mult_r(exc[i],round_fx(gain32))/*Q1*/; + move16(); + gain32 = L_sub(gain32, step32); +#endif + + } + + /* update old exc without random part */ + offset = s_max(round_fx(st->old_fpitchFB) - shr(L_frame,1), 0); + Copy(exc+L_frame-offset, hTcxDec->old_excFB_fx, shr(L_frame,1)+offset); + /* copy old_exc as 16kHz for acelp decoding */ + IF ( EQ_16(st->nbLostCmpt, 1)) + { + lerp(exc - shr(L_frame,1), st->old_exc_fx, L_EXC_MEM_DEC, add(L_frame, shr(L_frame,1))); + } + ELSE + { + Copy(st->old_exc_fx+L_FRAME16k, st->old_exc_fx, L_FRAME16k/2); + lerp(exc, st->old_exc_fx+L_FRAME16k/2, L_FRAME16k, L_frame); + } + st->Q_exc = Q_exc; + } + ELSE + { + /* No harmonic part */ + set16_fx(&exc[0], 0, add(L_frame,shr(L_frame,1))); + IF ( EQ_16(st->nbLostCmpt , 1)) + { + calcGainc2(&exc[0], Q_exc, L_subfr, &(st->Mode2_lp_gainc)); + } + set32_fx( pitch_buf, L_deposit_h(L_SUBFR), st->nb_subfr); + /* PLC: calculate damping factor */ +#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT + alpha = 1.0f; + if (st->element_mode == IVAS_CPE_MDCT && st->nbLostCmpt >= MDCT_ST_PLC_FADEOUT_START_FRAME) + { + alpha = Damping_fact(st->core_ext_mode, st->nbLostCmpt - MDCT_ST_PLC_FADEOUT_START_FRAME, st->last_good, st->stab_fac, &(st->lp_gainp), 0); + } + else if (st->element_mode != IVAS_CPE_MDCT) + { + alpha = Damping_fact(st->core_ext_mode, st->nbLostCmpt, st->last_good, st->stab_fac, &(st->lp_gainp), 0); + } +#else + alpha = Damping_fact(st->core_ext_mode, st->nbLostCmpt, st->last_good_fx, st->stab_fac_fx, &(st->Mode2_lp_gainp), 0);/*Q14*/ +#endif + } + + /*-----------------------------------------------------------------* + * Construct the random part of excitation + *-----------------------------------------------------------------*/ +#ifdef IVAS_CODE_CON_TCX + if (coh != -1.f) + { + int16_t tmpSeed1; + float alpha_coh; + float random1, random2; + + tmpSeed1 = *noise_seed; + noise = buf; + + alpha_coh = sqrtf((1 - coh) / (1 + coh)); + if (st->idchan == 1) + { + alpha_coh = -alpha_coh; + } + + for (i = 0; i < L_frame + L_FIR_FER2 - 1; i++) + { + random1 = (float)own_random(&tmpSeed1); + random2 = (float)own_random(&tmpSeed1); + noise[i] = random1 + alpha_coh * random2; + } + + if (st->idchan == 1 || only_left) + { + *noise_seed = tmpSeed1; + } + + for (; i < L_frame + (L_frame / 2) + 2 * L_FIR_FER2; i++) + { + random1 = (float)own_random(&tmpSeed1); + random2 = (float)own_random(&tmpSeed1); + noise[i] = random1 + alpha_coh * random2; + } + } + else +#endif /*IVAS_CODE_CON_TCX*/ + { + tmpSeed = st->seed_acelp; + move16(); + noise = buf; + noise_e = 1;/*set exponent of noise to 1*/ move16(); + + tmp_loop = add(L_frame, L_FIR_FER2 - 1); + FOR(i = 0; i < tmp_loop; i++) + { + tmpSeed = own_random2_fx(tmpSeed); + noise[i] = shr(tmpSeed, noise_e); + move16(); + } + st->seed_acelp = tmpSeed; + move16(); + + tmp_loop = add(add(L_frame, shr(L_frame, 1)), shl(L_FIR_FER2, 1)); + FOR(; i < tmp_loop; i++) + { + tmpSeed = own_random2_fx(tmpSeed); + noise[i] = shr(tmpSeed, noise_e); + move16(); + } + } + test(); + IF (EQ_16(st->last_good_fx , VOICED_CLAS)||EQ_16(st->last_good_fx,ONSET)) + { + tmp16 = 19661/*0.6f Q15*/; + move16(); + if ( LE_32(st->output_Fs,16000)) + { + tmp16 = 6554/*0.2f Q15*/; + move16(); + } + + mem = noise[0]; + move16(); + preemph_copy_fx(&noise[1], &noise[1], tmp16, L_frame+(L_frame/2)+L_FIR_FER2, &mem); + } + /* high rate filter tuning */ + IF ( LE_32(st->output_Fs,16000)) + { + FOR( i=0; i< L_FIR_FER2; i++ ) + { + hp_filt[i] = h_high3_16[i]; + move16(); + } + } + ELSE /*(st->output_Fs==32000)*/ + { + FOR( i=0; i< L_FIR_FER2; i++ ) + { + hp_filt[i] = h_high3_32[i]; + move16(); + } + } + IF ( EQ_16(st->nbLostCmpt,1)) + { + highPassFiltering(st->last_good_fx, add(add(L_frame, shr(L_frame,1)),L_FIR_FER2), noise, hp_filt, L_FIR_FER2); + } + ELSE + { + IF(GT_16( st->last_good_fx , UNVOICED_TRANSITION)) + { + tmp_loop = add(add(L_frame,shr(L_frame,1)),L_FIR_FER2); + gain_tmp = negate(add(-32768,st->cummulative_damping));/*Q15*/ + FOR( i=0 ; i < tmp_loop; i++ ) + { + Word16 j; + L_tmp2 = 0; move32(); + for (j=11; j>0; j--) + { + L_tmp2 = L_mac(L_tmp2, noise[i+L_FIR_FER2-j], hp_filt[L_FIR_FER2-j]); + } + L_tmp2 = Mpy_32_16_1(L_tmp2, st->cummulative_damping/*Q15*/);/*Q0, noise_e*/ + noise[i] = mac_r(L_tmp2, gain_tmp,noise[i]);/*Q15, noise_e*/ + } + } + } + + /* PLC: [TCX: Fade-out] retrieve background level */ +#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT + if (A_cng != NULL) + { + gainSynthDeemph = getLevelSynDeemph(&(tmp), A_cng, L_frame / 4, st->preemph_fac, 1) / 4.f; + } + else + { + gainSynthDeemph = getLevelSynDeemph(&(tmp), A_local, L_frame / 4, st->preemph_fac, 1); + } +#else + tmp16 = 32767; + move16(); + gainSynthDeemph = getLevelSynDeemph(&(tmp16), A_local, M, shr(L_frame,2), st->preemph_fac, 1, &gainSynthDeemph_e); +#endif + IF (0 != st->tcxonly) + { + /* gainCNG = st->conCngLevelBackgroundTrace/gainSynthDeemph; */ + BASOP_Util_Divide_MantExp(hTcxDec->conCngLevelBackgroundTrace, + hTcxDec->conCngLevelBackgroundTrace_e, + gainSynthDeemph, gainSynthDeemph_e, + &gainCNG, &gainCNG_e); +#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT + if (st->element_mode == IVAS_CPE_MDCT && A_cng != NULL) + { + if (st->nbLostCmpt > MDCT_ST_PLC_FADEOUT_MAX_CONC_FRAME + MDCT_ST_PLC_FADEOUT_TO_ZERO_LEN) + { + gainCNG = 0.f; + } + else if (st->nbLostCmpt > MDCT_ST_PLC_FADEOUT_MAX_CONC_FRAME) + { + gainCNG *= 1.f - (float)(st->nbLostCmpt - MDCT_ST_PLC_FADEOUT_MAX_CONC_FRAME) / MDCT_ST_PLC_FADEOUT_TO_ZERO_LEN; + } + } +#endif + } + ELSE + { + /* gainCNG = st->cngTDLevel/gainSynthDeemph; */ + BASOP_Util_Divide_MantExp(st->cngTDLevel, + st->cngTDLevel_e, + gainSynthDeemph, gainSynthDeemph_e, + &gainCNG, &gainCNG_e); + } + + gain32 = L_add(st->Mode2_lp_gainc, 0); /* start-of-the-frame gain - Q16*/ + if( EQ_16(st->rf_frame_type, RF_TCXTD1)&&EQ_16(st->use_partial_copy,1)) + { + gain32 = Mpy_32_16_1(gain32, 22938/*0.7f Q15*/); + } + L_tmp = L_shl(gain32,1); + + IF (GT_32(L_shl(L_deposit_h(gainCNG),sub(gainCNG_e,31-16)/*Q16*/) , L_tmp)) + { + gainCNG_e = sub(15+1,norm_l(L_tmp)); + gainCNG = extract_l(L_shr(L_tmp,gainCNG_e));/*Q15,gainCNG_e*/ + gainCNG_e = sub(gainCNG_e,1); + } + + /* st->Mode2_lp_gainc = alpha * (st->Mode2_lp_gainc) + (1.0f - alpha) * gainCNG;*/ /* end-of-the-frame gain */ + + L_tmp = Mpy_32_16_1(st->Mode2_lp_gainc,alpha)/*Q15*/; + L_tmp2 = L_mult(sub(16384/*1.f Q14*/,alpha)/*Q14*/,gainCNG/*Q15,gainCNG_e*/);/*Q30,gainCNG_e*/ + st->Mode2_lp_gainc = BASOP_Util_Add_Mant32Exp(L_tmp,31-15,L_tmp2,add(gainCNG_e,31-30),&tmp_e);/*Q31*/ move32(); + st->Mode2_lp_gainc = L_shl(st->Mode2_lp_gainc,sub(tmp_e,31-16)); + move32(); + + /* PLC: [TCX: Fade-out] Linearly attenuate the gain through the frame */ + /*step = (1.0f/L_frame) * (gain - (st->Mode2_lp_gainc));*/ + L_tmp = L_sub(gain32,st->Mode2_lp_gainc);/*Q16*/ + tmp_e = norm_l(L_tmp); + L_tmp = L_shl(L_tmp,tmp_e);/*Q16,-tmp_e*/ + step32 = Mpy_32_16_1(L_tmp/*Q16,-tmp_e*/,getInvFrameLen(L_frame)/*W16Q21*/);/*Q22,-tmp_e*/ + step32 = L_shl(step32,sub((25-22),tmp_e));/*Q25*/ + + pt_exc = noise + L_FIR_FER2/2; + + /*gain_inov = 1.0f / (float)sqrt( dot_product( pt_exc, pt_exc, L_frame ) / L_frame + 0.01f );*//* normalize energy */ + L_tmp = Dot_productSq16HQ(0,pt_exc/*Q0,15+1*/,L_frame,&tmp_e)/*Q31,tmp_e+16+16*/; + L_tmp = Mpy_32_16_1(L_tmp,getInvFrameLen(L_frame)/*W16Q21*/)/*W32Q37,tmp_e+16+16*//*Q5,tmp_e*/; + tmp_e = add(tmp_e,31-5);/*-->Q31*/ + gain_inov = round_fx(ISqrt32(L_tmp,&tmp_e));/*Q15,tmp_e*/ + gain_inov_e = tmp_e; + move16(); + test(); + test(); + IF (EQ_16(st->last_good_fx , UNVOICED_CLAS)&&NE_16(st->core_ext_mode,UNVOICED)) + { + gain_inov = mult_r(gain_inov,26214/*0.8f Q15*/); + } + ELSE IF (!( EQ_16(st->last_good_fx , UNVOICED_CLAS)||EQ_16(st->last_good_fx,UNVOICED_TRANSITION))) + { + /*gain_inov *= (1.1f- 0.75*st->lp_gainp);*/ + L_tmp = Mpy_32_16_1(L_sub(590558016l/*1.1f Q29*/, Mpy_32_16_1(st->Mode2_lp_gainp,24576))/*Q29*/,gain_inov/*Q15,gain_inov_e*/);/*Q29,gain_inov_e*/ + tmp_e = norm_l(L_tmp); + L_tmp = L_shl(L_tmp,tmp_e); + gain_inov_e = add(sub(gain_inov_e,tmp_e),31-29);/*->Q31*/ + gain_inov = round_fx(L_tmp);/*Q15,gain_inov_e*/ + } + + st->Mode2_lp_gainp = L_shr(L_deposit_h(alpha/*Q14*/)/*Q14+16*/,1);/*Q29*/ + pt_exc = noise; /* non-causal ringing of the FIR filter */ + + tmp_e = norm_l(gain32); + tmp_e = sub(tmp_e,5); /*5 Bit additional Headroom for the gain - should be enough*/ + gain32 = L_shl(gain32,tmp_e);/*Q16,-tmp_e*/ + L_tmp = Mpy_32_16_1(gain32/*Q16,-tmp_e*/, gain_inov/*Q15,gain_inov_e*/)/*Q16,gain_inov_e-tmp_e*/; + + gain_tmp = round_fx(L_tmp);/*Q0, gain_inov_e-tmp_e*/ + + FOR( i=0 ; i< L_FIR_FER2/2; i++ ) + { + *pt_exc = mult_r(*pt_exc,gain_tmp);/*Q-15,noise_e+gain_inov_e-tmp_e*/ move16(); + pt_exc++; + } + tmp16 = add(L_frame,L_FIR_FER2/2); + step32_tmp = L_shl(step32/*Q25*/,sub(tmp_e,(25-16)));/*Q16,-tmp_e*/ + FOR( i=0 ; i< tmp16; i++ ) /* Actual filtered random part of excitation */ + { + *pt_exc = mult_r(*pt_exc, gain_tmp); + move16(); + pt_exc++; + gain32 = L_sub(gain32/*Q16,-tmp_e*/,step32_tmp);/*Q16,-tmp_e*/ + gain_tmp = mult_r(round_fx(gain32/*Q16,-tmp_e*/)/*Q0*/, gain_inov/*Q15,gain_inov_e*/)/*Q0,gain_inov_e-tmp_e*/; + } + tmp16 = shr(L_frame,1); + FOR( i=0 ; i< tmp16; i++ ) /* causal ringing of the FIR filter */ + { + *pt_exc = mult_r(*pt_exc , gain_tmp); + move16(); + pt_exc++; + } + noise_e = add(sub(add(noise_e,gain_inov_e),tmp_e),15);/*--> noise is Q0, noise_e*/ + /*buf[0;L_FIR_FER2 + L_Frame + L_Frame/2] Q0, noise_e*/ + + /*-----------------------------------------------------------------* + * Construct the total excitation + *-----------------------------------------------------------------*/ + + IF( GE_16(st->last_good_fx , UNVOICED_TRANSITION)) + { + tmp16 = add(L_frame,shr(L_frame,1)); + FOR( i=0 ; i< tmp16; i++ ) + { +#ifdef BASOP_NOGLOB + exc[i] = add_sat(exc[i], shl(noise[i + (L_FIR_FER2 / 2)], Q_exc + noise_e));/*Q1*/ move16(); +#else + exc[i] = add(exc[i] , shl(noise[i+(L_FIR_FER2/2)],Q_exc+noise_e));/*Q1*/ move16(); +#endif + } + } + ELSE + { + bufferCopyFx(noise+L_FIR_FER2/2, exc, add(L_frame , shr(L_frame,1)),0/*Q_noise*/, noise_e, Q_exc, 0/*exc_e*/); + Copy(exc+L_frame-2*L_subfr, hTcxDec->old_excFB_fx, 2*L_subfr+shr(L_frame,1)); + /* copy old_exc as 16kHz for acelp decoding */ + IF ( EQ_16(st->nbLostCmpt, 1)) + { + lerp(exc, st->old_exc_fx, L_EXC_MEM_DEC, add(L_frame, shr(L_frame,1))); + } + ELSE { + Copy(st->old_exc_fx+L_FRAME16k, st->old_exc_fx, L_FRAME16k/2); + lerp(exc, st->old_exc_fx+L_FRAME16k/2, L_FRAME16k, L_frame); + } + st->Q_exc = Q_exc; + } + /*buf[0;L_FIR_FER2 + L_Frame + L_Frame/2] Q0, noise_e*/ + /*buf[OLD_EXC_SIZE_DEC;3/2 L_frame] Q1*/ + + /* Update Pitch Lag memory */ + Copy32( &st->old_pitch_buf_fx[st->nb_subfr], st->old_pitch_buf_fx, st->nb_subfr ); + Copy32( pitch_buf, &st->old_pitch_buf_fx[st->nb_subfr], st->nb_subfr ); + + /*----------------------------------------------------------* + * - compute the synthesis speech * + *----------------------------------------------------------*/ + + syn = buf + M; + Copy(synth-M, buf, M); + + new_Q = sub(Q_exc, 3); + new_Q = s_max(new_Q, -1); + + tmp16 = s_min(new_Q, st->prev_Q_syn); + st->prev_Q_syn = new_Q; + move16(); + + exp_scale = sub(tmp16, Q_exc-1); + Q_syn = tmp16; + move16(); + + Copy_Scale_sig(buf, mem_syn, M, exp_scale); + +#ifdef BASOP_NOGLOB + tmp_deemph = shl_sat(tmp_deemph,Q_syn); +#else + tmp_deemph = shl(tmp_deemph,Q_syn); +#endif + st->Q_syn = Q_syn; + + /*buf[OLD_EXC_SIZE_DEC;3/2 L_frame] Q1: exc*/ + /*buf[0;M] Q0: mem_syn*/ +#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT + if (A_cng != NULL) + { + float alpha_delayed; + + alpha_delayed = 1.0f; + if (st->nbLostCmpt > MDCT_ST_PLC_FADEOUT_DELAY_4_LSP_FADE) + { + alpha_delayed = Damping_fact(st->core_ext_mode, st->nbLostCmpt - MDCT_ST_PLC_FADEOUT_DELAY_4_LSP_FADE, st->last_good, st->stab_fac, &(st->lp_gainp), ACELP_CORE); + } + + if (st->plcBackgroundNoiseUpdated && alpha_delayed != 1.0f) + { + float lsp_local[M], lsp_fade[M], alpha_inv; + + alpha_inv = 1.0f - alpha_delayed; + + a2lsp_stab(A_local, lsp_local, lsp_local); + + for (i = 0; i < M; i++) + { + lsp_fade[i] = alpha_delayed * lsp_local[i] + alpha_inv * st->lspold_cng[i]; + } + + lsp2a_stab(lsp_fade, A_local, M); + } + } +#endif + E_UTIL_synthesis( + sub(Q_exc, Q_syn), + A_local, + &exc[0], + &syn[0], + add(L_frame, shr(L_frame,1)), + mem_syn, + 1, + M); + + /*buf[OLD_EXC_SIZE_DEC;3/2 L_frame-1] Q1: exc*/ + /*buf[0;M-1] Q0: mem_syn*/ + /*buf[M;3/2 L_frame-1] Q-1: syn*/ + + n = extract_h(L_mult(L_frame,9216/*(float)N_ZERO_MDCT_NS/(float)FRAME_SIZE_NS Q15*/)); + + /* update ACELP synthesis memory */ + mem_syn_r_size_old = shr(L_frame,4); /* replace 1.25/20.0 by shr(4) */ + /* copy mem_syn as 16kHz */ + mem_syn_r_size_new = shr(L_FRAME16k,4); /* replace 1.25/20.0 by shr(4) */ + + Copy(syn+L_frame-L_SYN_MEM, st->mem_syn_r, L_SYN_MEM); + lerp(st->mem_syn_r+L_SYN_MEM-mem_syn_r_size_old, st->mem_syn_r+L_SYN_MEM-mem_syn_r_size_new, mem_syn_r_size_new, mem_syn_r_size_old); + Copy(st->mem_syn_r+L_SYN_MEM-M, st->mem_syn2_fx, M); + + /* Deemphasis and output synth and ZIR */ + deemph_fx(syn, st->preemph_fac, add(L_frame,shr(L_frame,1)), &tmp_deemph); + bufferCopyFx(syn+L_frame-M-1, st->syn, 1+M, Q_syn, 0, 0, 0); + + + lerp( syn+L_frame-shr(L_frame, 1), hTcxDec->old_syn_Overl, shr(st->L_frame, 1), shr(L_frame, 1) ); + Copy(syn+L_frame-n, hHQ_core->old_out_fx, sub(L_frame,n)); + + FOR (i=0; i < W12; i++) + { + hHQ_core->old_out_fx[i+n] = round_fx(Mpy_32_16_1(L_mult(w[i].v.re,w[i].v.re), hHQ_core->old_out_fx[i+n])); + } + FOR ( ; i < W1; i++) + { + hHQ_core->old_out_fx[i+n] = round_fx(Mpy_32_16_1(L_mult(w[W12-1-(i-W12)].v.im,w[W12-1-(i-W12)].v.im), hHQ_core->old_out_fx[i+n])); + } + + set16_fx(&hHQ_core->old_out_fx[W1+n], 0, n); + + hHQ_core->Q_old_wtda = Q_syn; + move16(); + + /* As long as there is no synth scaling factor introduced, which + is given to the outside, there might occur overflows here */ + BASOP_SATURATE_WARNING_OFF_EVS + bufferCopyFx(syn, synth, L_frame, Q_syn, 0, 0, 0); + BASOP_SATURATE_WARNING_ON_EVS + + Copy_Scale_sig(syn+L_frame, hTcxDec->syn_OverlFB, shr(L_frame,1), negate(Q_syn)); + + /* copy total excitation exc2 as 16kHz for acelp mode1 decoding */ + IF(st->hWIDec != NULL) + { + lerp(exc, st->hWIDec->old_exc2_fx, L_EXC_MEM, L_frame); + lerp(syn, st->hWIDec->old_syn2_fx, L_EXC_MEM, L_frame); + } + +#ifdef BASOP_NOGLOB + st->bfi_pitch_fx/*Q6*/ = round_fx_sat(L_shl_sat(pitch_buf[st->nb_subfr-1]/*15Q16*/,6/*Q6*/)); +#else + st->bfi_pitch_fx/*Q6*/ = round_fx(L_shl(pitch_buf[st->nb_subfr-1]/*15Q16*/,6/*Q6*/)); +#endif + move16(); + st->bfi_pitch_frame = st->L_frame; + move16(); + + /* create aliasing and windowing need for transition to TCX10/5 */ + bufferCopyFx(syn+L_frame, hTcxDec->syn_Overl_TDACFB, shr(L_frame,1),Q_syn,0,-1,0); + + FOR (i=0 ; i < W12 ; i++) + { + buf[i] = mult_r(hTcxDec->syn_Overl_TDACFB[i] , w[i].v.re); + move16(); + } + FOR ( ; i syn_Overl_TDACFB[i],w[W12-1-(i-W12)].v.im); + move16(); + } + + + FOR (i=0; isyn_Overl_TDACFB[i] = add(buf[i] , buf[W1-1-i]); + move16(); + } + + FOR (i=0; isyn_Overl_TDACFB[W2+i] = add(buf[W2+i] , buf[W1-1-W2-i]); + move16(); + } + + FOR (i=0 ; i < W12 ; i++) + { + hTcxDec->syn_Overl_TDACFB[i] = mult_r(hTcxDec->syn_Overl_TDACFB[i],w[i].v.re); + move16(); + } + FOR ( ; i syn_Overl_TDACFB[i] = mult_r(hTcxDec->syn_Overl_TDACFB[i],w[W12-1-(i-W12)].v.im); + move16(); + } + + st->hTcxCfg->tcx_curr_overlap_mode = FULL_OVERLAP; + + synth[-1] = pre_emph_buf; + move16(); + + /* update memory for low band */ + 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) ); + lerp( st->hHQ_core->old_out_fx, st->hHQ_core->old_out_LB_fx, st->L_frame, L_frame ); + + st->old_enr_LP = Enr_1_Az_fx(A_local, L_SUBFR); /*Q3*/ + + return; +} + diff --git a/lib_dec/er_scale_syn.c b/lib_dec/er_scale_syn.c index d6d048b234a115a4ddf10b64725d5e6bd44ce045..fdd0c60bf349721bb49aa1fcb8567acdff40ecb9 100644 --- a/lib_dec/er_scale_syn.c +++ b/lib_dec/er_scale_syn.c @@ -43,12 +43,12 @@ /*----------------------------------------------------------------------------------* - * Damping_fact() + * Damping_fact_flt() * * Estimate damping factor *----------------------------------------------------------------------------------*/ -float Damping_fact( +float Damping_fact_flt( const int16_t coder_type, const int16_t nbLostCmpt, int16_t last_good, diff --git a/lib_dec/er_scale_syn_fx.c b/lib_dec/er_scale_syn_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..8ee2514d6439913d33a08f87a45edde365622514 --- /dev/null +++ b/lib_dec/er_scale_syn_fx.c @@ -0,0 +1,137 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +/*This file is up to date with trunk rev 36531*/ + +#include +#include "options.h" +#include "prot_fx1.h" +#include "prot_fx2.h" +#include "basop_util.h" +#include "cnst.h" + + +/*----------------------------------------------------------------------------------* +* Damping_fact() +* +* Estimate damping factor +*----------------------------------------------------------------------------------*/ + +/*This BASOP version was ported based on trunk rev. 27621 and updated based on trunk rev. 29287, re-updated based on trunk rev. 32244 */ +Word16 Damping_fact( /* o : damping factor *//*Q14*/ + const Word16 coder_type, /* i : coding type in last good received frame */ + const Word16 nbLostCmpt, /* i : counter of consecutive bfi frames */ + const Word16 last_good, /* i : last good frame class */ + const Word16 stab_fac, /* i : ISF stability factor *//*Q15*/ + Word32 *lp_gainp, /*i/o: damped pitch gain *//*2Q29 Word32!*/ + const Word16 core /* i : current coding mode */ +) +{ + Word16 alpha; /*Q14*/ + Word16 gain; /*Q14*/ + Word32 lp_tmp; + Word16 s_gainp; + Word32 gain32; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + + + IF (core == ACELP_CORE) + { + alpha = mult_r(_ALPHA_VT_FX,16384); /* rapid convergence to 0 *//*Q14*/ + test(); + test(); + test();/*ELSEIF*/ + test(); + test();/*ELSEIF*/ + IF( ( EQ_16(coder_type, UNVOICED))&&(LE_16(nbLostCmpt,3))) /* Clear unvoiced last good frame */ + { + alpha = mult_r(_ALPHA_UU_FX,16384); /*Q14*/ + } + ELSE IF( EQ_16(last_good, UNVOICED_CLAS)) + { + IF( EQ_16(nbLostCmpt,1)) + { + /* If stable, do not decrease the energy, pitch gain = 0 */ + /* * (1.0f - 2.0f*_ALPHA_U_FX) + 2.0f*MODE2_ALPHA_U; */ /* [0.8, 1.0] */ + alpha = add(mult_r(stab_fac,sub(16384,_ALPHA_U_FX)),_ALPHA_U_FX); + } + ELSE IF (EQ_16(nbLostCmpt, 2)) + { + /*alpha = _ALPHA_U_FX * 1.5f;*/ /* 0.6 */ + alpha = mult_r(_ALPHA_U_FX, 24576/*1.5f Q14*/); /*Q14*/ + } + ELSE + { + alpha = mult_r(_ALPHA_U_FX,16384); /*Q14*/ /* 0.4 go rapidly to CNG gain, pitch gain = 0 */ + } + } + ELSE IF( EQ_16(last_good, UNVOICED_TRANSITION)) + { + alpha = mult_r(_ALPHA_UT_FX,16384); /*Q14*/ + } + ELSE IF( (EQ_16(last_good, ONSET))&&(LE_16(nbLostCmpt,3))&&(EQ_16(coder_type,GENERIC))) + { + alpha = 13107/*0.8f Q14*/; /*Q14*/ + } + ELSE if( ( (EQ_16(last_good, VOICED_CLAS))||(EQ_16(last_good,ONSET)))&&(LE_16(nbLostCmpt,3))) + { + alpha = mult_r(_ALPHA_V_FX,16384); /* constant for the first 3 erased frames */ + } + + IF (GE_16(last_good, VOICED_CLAS)) + { + move16(); + lp_tmp = *lp_gainp; + + IF( EQ_16(nbLostCmpt, 1)) /* if first erased frame in a block, reset harmonic gain */ + { + /*lp_gainp_E = 1;*/ /*For sqrt, because *lp_gain is Q14 */ + + /*gain = (float)sqrt( *lp_gainp );*/ /* move pitch gain towards 1 for voiced to remove energy fluctuations */ + /*BASOP_Util_Sqrt_MantExp(lp_gainp,&lp_gainp_E);*/ + s_gainp = 31-29; + move16(); + gain32 = Sqrt32(lp_tmp, &s_gainp); + +#ifdef BASOP_NOGLOB + gain = round_fx_o(L_shl_o(gain32, s_gainp, &Overflow), &Overflow); /* Q15*/ +#else + gain = round_fx(L_shl(gain32,s_gainp)); /* Q15*/ +#endif + gain = s_min(gain, 32113/*0.98f Q15*/); /*Q15*/ + gain = s_max(gain, 27853/*0.85f Q15*/); /*Q15*/ + alpha = mult_r(alpha , gain); /*Q14*/ + } + ELSE IF ( EQ_16(nbLostCmpt, 2)) + { + /*0.6 + 0.35*stab_fac*/ + alpha = mult_r(mac_r(1288490240l/*0.6f Q31*/, 11469/*0.35f Q15*/, stab_fac), round_fx(L_shl(lp_tmp,1))); + } + ELSE + { + /*0.7 + 0.2*stab_fac*/ move16(); + lp_tmp = Mpy_32_16_1(lp_tmp, mac_r(1503238528l/*0.7f Q31*/, 6554/*0.2f Q15*/, stab_fac)); /*2Q29*/ + alpha = round_fx(L_shl(lp_tmp,1)); /*1Q14*/ + } + move16(); + *lp_gainp = lp_tmp; /*store*/ + } + } + ELSE + { + alpha = mac_r(375809632l/*0.35f Q30*/,6554/*0.4f Q14*/,stab_fac); /*Q14*/ + if (LT_16(nbLostCmpt,2)) + { + alpha = mac_r(751619264l/*0.70f Q30*/,4915/*0.3f Q14*/,stab_fac); /*Q14*/ + } + if (EQ_16(nbLostCmpt, 2)) + { + alpha = mac_r(483183808l/*0.45f Q30*/,6554/*0.4f Q14*/,stab_fac); /*Q14*/ + } + + } + return alpha; +} diff --git a/lib_dec/er_sync_exc.c b/lib_dec/er_sync_exc.c index b28a172715875c93696b27547bbf4e2efd86bd6a..36e20ce8aefcf8834577e552aea4aa04ba768e62 100644 --- a/lib_dec/er_sync_exc.c +++ b/lib_dec/er_sync_exc.c @@ -177,12 +177,12 @@ static void RemoveSamples( /*-------------------------------------------------------------------* - * PulseResynchronization() + * PulseResynchronization_flt() * * Resynchronize glottal pulse positions of the signal in src_exc and store it in dst_exc *--------------------------------------------------------------------*/ -void PulseResynchronization( +void PulseResynchronization_flt( const float *src_exc, /* i : Input excitation buffer */ float *dst_exc, /* o : output excitation buffer */ const int16_t nFrameLength, /* i : frame length */ diff --git a/lib_dec/er_sync_exc_fx.c b/lib_dec/er_sync_exc_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..23145a7d06c89312928c5e8802f301dfb47b7f42 --- /dev/null +++ b/lib_dec/er_sync_exc_fx.c @@ -0,0 +1,554 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +/*This BASOP port is up to date with trunk rev. 36554*/ + +#include +#include +#include "options.h" +#include "cnst.h" +#include "prot_fx1.h" +#include "prot_fx2.h" +#include "basop32.h" +#include "basop_util.h" + +/*------------------------------------------------------------------------- +* +* Perform resynchronisation of the last glottal pulse in voiced lost frame +* +*------------------------------------------------------------------------*/ + + +/** Get the location of the minimum energy in the given signal. + * @returns Index of the position of the minimum energy, that is the position i where filter(x[i-filterLength/2],...,x[i+(filterLength-filterLength/2)-1]) is at maximum. + */ +static Word16 GetMinimumPosition( + Word16 const * x, /* Input signal. Qx*/ + Word16 length, /* The length of the input signal. Q0*/ + Word16 filterLength /* the length of the filter length used for the energy calculation. Q0*/ +) +{ + Word16 iMinEnergyPos, center, i; + Word16 cnt, tmp_e, tmp16; + Word32 energy, energy_old, tmptest; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + + filterLength = s_min(filterLength, length); + center = shr(filterLength,1); + iMinEnergyPos = center; + move16(); + + IF (filterLength > 0) + { + center = add(center,1); + energy = L_deposit_l(0); + energy_old = L_deposit_l(0); + + cnt = sub(length,filterLength); + + tmp_e = 0; + move16(); + FOR (i = 0; i < cnt; i++) + { + tmp16 = shr(x[i],tmp_e); + energy = L_msu(energy_old,tmp16,tmp16); + tmp16 = shr(x[i+filterLength],tmp_e); + BASOP_SATURATE_WARNING_OFF_EVS /*Saturation will be handled*/ + energy = L_mac(energy,tmp16,tmp16); + BASOP_SATURATE_WARNING_ON_EVS + + /*if (energy == MAXVAL_WORD32)*/ + BASOP_SATURATE_WARNING_OFF_EVS /*saturates if energy < 0*/ +#ifdef BASOP_NOGLOB + tmptest = L_sub_o(energy,MAXVAL_WORD32, &Overflow); +#else + tmptest = L_sub(energy,MAXVAL_WORD32); +#endif + BASOP_SATURATE_WARNING_ON_EVS + IF (tmptest == 0) + { + tmp_e = add(tmp_e,1); + energy = L_shr(energy_old,2); + tmp16 = shr(x[i],tmp_e); + energy = L_msu(energy,tmp16,tmp16); + tmp16 = shr(x[i+filterLength],tmp_e); + energy = L_mac(energy,tmp16,tmp16); + } + + IF (energy < 0) + { + iMinEnergyPos = add(i,center); + tmp_e = 0; + move16(); + energy = 0; + move16(); + } + energy_old = L_add(energy, 0); + } + + } + + return iMinEnergyPos; +} + +/*! + * \brief FindMaxPeak - Get the location of the maximum peak in the given signal. + * + * \returns Index of the position of the maximum peak, that is the position i where abs(x[i]) has it's maximum. + */ + +static Word16 FindMaxPeak +( + Word16 /*float*/ const * x, /* 0; j--) + { + *pt_dest++ = *pt_src++; + move16(); + } + /* Add some samples */ + ftmp = negate(mult(*pt_src,1638/*.05f Q15*/)); + + FOR (j = 0; j < points_by_pos[i]; j++) + { + *pt_dest++ = ftmp; + move16(); + ftmp = negate(ftmp); + } + /* Prepare for the next loop iteration */ + last_min_pos = min_pos[i]; + move16(); + } + /* Copy remaining length */ + FOR (j = sub(L_frame , add(n_samples_to_add , last_min_pos)); j > 0; j--) + { + *pt_dest++ = *pt_src++; + move16(); + } + +} + +static void RemoveSamples( + Word16 /*float*/const * const old_exc, /*i : Qx */ + Word16 /*float*/ * const new_exc, /*o : Qx */ + Word16 /*int*/ const L_frame, /*i : Q0 */ + Word16 /*int*/ const n_samples_to_add, /*i : Q0 */ + Word16 /*int*/ const min_pos[], /*i : Q0 */ + Word16 /*int*/ const points_by_pos[], /*i : Q0 */ + Word16 /*int*/ const nb_min /*i : Q0*/ +) +{ + Word16 /*float*/ * pt_dest; + Word16 /*float*/ const * pt_src; + Word16 /*int*/ last_min_pos, i, j; + + + + pt_dest = new_exc+L_frame; + last_min_pos = sub(L_frame,n_samples_to_add); + + FOR(i = sub(nb_min,1); i >= 0; i--) + { + /* Compute len to copy */ + /* Copy section, removing some samples */ + pt_src = old_exc+last_min_pos; + + FOR (j = sub(last_min_pos , add(min_pos[i],points_by_pos[i])); j > 0; j--) + { + *--pt_dest = *--pt_src; + move16(); + } + /* Prepare for the next loop iteration */ + last_min_pos = min_pos[i]; + move16(); + } + /* Copy remaining length */ + pt_src = old_exc+last_min_pos; + + FOR (j = last_min_pos; j > 0; j--) + { + *--pt_dest = *--pt_src; + move16(); + } + +} + +/** Resynchronize glotal pulse positions of the signal in src_exc and store it in dst_exc. + * src_exc holds on call the harmonic part of the signal with the constant pitch, constructed by repeating the last pitch cycle of length pitchStart. + * dst_exc holds on return the harmonic part of the signal with the pitch changing from pitchStart to pitchEnd. + * src_exc and dst_exc can overlap, but src_exc < dst_exc must be fullfiled. + */ +/*This BASOP port is up to date with trunk rev 8779(svnext2)*/ +void PulseResynchronization( + Word16 /*float*/ const * const src_exc, /*= 0)) + { + /* This is error handling and recovery that should never occur. */ + test(); + IF (src_exc != dst_exc && LE_16(nFrameLength, 1200)) + { + Copy(src_exc, dst_exc, nFrameLength); + } + return; + } + + roundedPitchStart = round_fx(pitchStart); /*Q0*/ + + /* freqStart = 1.0f/roundedPitchStart; */ + freqStart_e = 15; + move16(); + freqStart = Inv16(roundedPitchStart, &freqStart_e); /*Q15,freqStart_e*/ + + /* Calculate number of samples to be removed (if negative) or added (if positive) */ + /*samplesDelta = 0.5f*pitchDelta*nFrameLength*(nSubframes+1)*freqStart;*/ + /* pitchDelta*freqStart = ((pitchEnd - pitchStart)/roundedPitchStart)/nSubframes */ + tmp16 = shl(roundedPitchStart, 2); /*Q0*/ + if (EQ_16(nSubframes, 5)) + { + tmp16 = add(tmp16, roundedPitchStart);/*Q0*/ /*tmp16=roundedPitchStart*nSubframes*/ + } + tmp_e = norm_s(tmp16); + tmp16 = shl(tmp16, tmp_e);/*Q0,-tmp_e*/ /*tmp16=roundedPitchStart*nSubframes*/ + tmp_e = sub(15, tmp_e); + tmp16 = Inv16(tmp16, &tmp_e); /*Q15,tmp_e*/ /*tmp16=1.0/(roundedPitchStart*nSubframes)*/ + tmp32 = L_sub(pitchEnd,pitchStart); + tmp2_e = norm_l(tmp32); + tmp32 = L_shl(tmp32, tmp2_e);/*Q16,-tmp2_e*/ + tmp32 = Mpy_32_16_1(tmp32, tmp16);/*Q16,tmp_e-tmp2_e*/ /*tmp32=pitchDelta*freqStart*/ + tmp_e = sub(tmp_e, tmp2_e); /* sum up all the scalings for tmp32 */ + + tmp16 = imult1616(nFrameLength,add(nSubframes,1));/*Q0*//*tmp16=nFrameLength*(nSubframes+1)*/ + tmp2_e = norm_s(tmp16); + tmp16 = shl(tmp16,tmp2_e); + + tmp32 = Mpy_32_16_1(tmp32,tmp16);/*Q1 scaling (tmp_e-tmp2_e-1), -1 because of 0.5f*/ /*tmp32=0.5f*pitchDelta*nFrameLength*(nSubframes+1)*freqStart*/ + tmp_e = sub(sub(tmp_e,tmp2_e),1); /* sum up all the scalings for tmp32 */ + tmp_e = add(tmp_e,31-1); /* tmp32 is now regarded as Q31 with scaling tmp_e */ + + /*samplesDelta -= nFrameLength*(1.0f-pitchStart*freqStart);*/ + tmp2_e = norm_l(pitchStart); + tmp32_a = L_shl(pitchStart,tmp2_e); + tmp32_a = Mpy_32_16_1(tmp32_a/*Q16,-tmp2_e*/,freqStart/*Q15,freqStart_e*/);/*Q16, scaling (freqStart_e-tmp2_e)*/ /*tmp32_a=pitchStart*freqStart*/ + tmp16 = norm_l(tmp32_a); + tmp32_a = L_shl(tmp32_a,tmp16); + tmp2_e = sub(sub(freqStart_e,tmp16),tmp2_e); /* sum up all scalings for tmp32_a */ + tmp2_e = add(tmp2_e,31-16); /* tmp32_a is now regarded as Q31 with scaling tmp2_e */ + + tmp3_e = tmp2_e; + tmp32_a = L_negate(tmp32_a); +#ifdef BASOP_NOGLOB + tmp32_a = L_add(L_shl_o(1, sub(31, tmp3_e), &Overflow), tmp32_a); /*Q31,tmp3_e*//*tmp32_a= 1.0f-pitchStart*freqStart*/ +#else + tmp32_a = L_add(L_shl(1, sub(31, tmp3_e)), tmp32_a); /*Q31,tmp3_e*//*tmp32_a= 1.0f-pitchStart*freqStart*/ +#endif + tmp2_e = norm_s(nFrameLength); + tmp16_a = shl(nFrameLength,tmp2_e); + tmp32_a = Mpy_32_16_1(tmp32_a/*Q31,tmp3_e*/,tmp16_a/*Q0,-tmp2_e*/);/*Q16,tmp3_e-tmp2_e*/ /*tmp32_a= nFrameLength*(1.0f-pitchStart*freqStart)*/ + tmp2_e = add(sub(tmp3_e, tmp2_e), 15); + samplesDelta = BASOP_Util_Add_Mant32Exp(tmp32, tmp_e, L_negate(tmp32_a), tmp2_e, &samplesDelta_e); /*Q31,samplesDelta_e*/ + + /* To have enough samples in the buffer of length nFrameLength*(nSubframes+1)/nSubframes, pitchEnd/pitchEnd must be bigger than (nSubframes-1)/(nSubframes+1)=1-2/(nSubframes+1) */ + /* Thus nSubframes must be bigger than 1 */ + nSamplesDelta = round_fx(L_shl(samplesDelta,sub(samplesDelta_e,31-16))); /*Q0*/ + nSamplesDeltaRemain = abs_s(nSamplesDelta); + /* Find the location of the glottal pulse */ + T0 = FindMaxPeak(src_exc, roundedPitchStart); /*Q0*/ + /* Get the index of the last pulse in the resynchronized frame */ + /*k = (int)ceil((nFrameLength-nSamplesDelta-T0)*freqStart - 1);*/ + tmp32 = BASOP_Util_Add_Mant32Exp(L_mult(sub(nFrameLength,add(nSamplesDelta,T0)),freqStart)/*Q16*/,add(freqStart_e,31-16),0x80000000/*-1.f Q31*/,0,&tmp_e); + tmp32 = L_shl(tmp32,sub(tmp_e,31-16))/*Q16*/; + tmp32 = L_add(tmp32,65536l/*1.f Q16*/); + k=extract_h(tmp32); + test(); + IF ((k >= 0) && LE_16(add(k,1) , NB_PULSES_MAX)) + { + absPitchDiff = L_abs(L_sub(L_deposit_h(roundedPitchStart),pitchEnd));/*Q16*/ + + /* Calculate the delta of the samples to be added/removed between consecutive cycles */ + /*perCycleDeltaDelta = (absPitchDiff*(nFrameLength-samplesDelta) - (float)fabs(samplesDelta)*roundedPitchStart) + / ((k+1)*(T0+0.5f*k*roundedPitchStart));*/ + tmp32 = L_sub(L_deposit_h(nFrameLength),L_shl(samplesDelta,sub(samplesDelta_e,31-16)));/*Q16*/ + tmp_e = 15; /*tmp32 = Q31,tmp_e*/ move16(); + tmp2_e = norm_l(tmp32); + tmp32 = L_shl(tmp32,tmp2_e); + tmp_e = sub(tmp_e,tmp2_e); /*tmp32 = Q31,tmp_e*/ + tmp2_e = norm_l(absPitchDiff); + tmp32_b = L_shl(absPitchDiff,tmp2_e); + tmp_e = sub(tmp_e,tmp2_e); + tmp32 = Mpy_32_16_1(tmp32_b,round_fx(tmp32));/*Q16,tmp_e*/ /*tmp32 = absPitchDiff*(nFrameLength-samplesDelta)*/ + tmp32_a = Mpy_32_16_1(L_abs(samplesDelta)/*Q31,samplesDelta_e*/,roundedPitchStart/*Q0*/);/*Q16,samplesDelta_e*/ /*tmp32_a=fabs(samplesDelta)*roundedPitchStart*/ + tmp32 = BASOP_Util_Add_Mant32Exp(tmp32, add(tmp_e,31-16), L_negate(tmp32_a), add(samplesDelta_e,31-16),&tmp_e);/*Q31,tmp_e*/ /*tmp32=absPitchDiff*(nFrameLength-samplesDelta)-fabs(samplesDelta)*roundedPitchStart*/ + tmp16 = imult1616(add(k,1),add(shl(T0,1),imult1616(k,roundedPitchStart)));/*Q0,-1*/ /*tmp16=(k+1)*(T0+0.5f*k*roundedPitchStart)*/ + perCycleDeltaDelta = BASOP_Util_Divide3216_Scale(tmp32/*Q31,tmp_e*/,tmp16/*Q0,-1*/,&perCycleDeltaDelta_e); /*Q15,perCycleDeltaDelta_e*/ + perCycleDeltaDelta_e = add(perCycleDeltaDelta_e,sub(tmp_e,-1+15)); + tmp_e = norm_s(perCycleDeltaDelta); + perCycleDeltaDelta_e = sub(perCycleDeltaDelta_e,tmp_e); + perCycleDeltaDelta = shl(perCycleDeltaDelta,tmp_e);/*Q15,perCycleDeltaDelta_e*/ + + + /* Calculate the integer number of samples to be added/removed in each pitch cycle */ + /*cycleDelta = max(0, (absPitchDiff-(k+1)*perCycleDeltaDelta)*T0*freqStart); */ + tmp_e = norm_s(k+1); + tmp32 = L_mult(perCycleDeltaDelta/*Q15,perCycleDeltaDelta_e*/,shl(add(k,1),tmp_e)/*Q0, tmp_e*/)/*Q0+16, perCycleDeltaDelta_e-tmp_e*/; + tmp32 = BASOP_Util_Add_Mant32Exp(absPitchDiff/*Q16*/,31-16,L_negate(tmp32),add(sub(perCycleDeltaDelta_e,tmp_e),31-16),&tmp_e);/*Q31,tmp_e*/ + tmp32 = Mpy_32_16_1(tmp32,T0/*Q0*/);/*Q16,tmp_e*/ + tmp32 = Mpy_32_16_1(tmp32/*Q16,tmp_e*/,freqStart/*Q15,freqStart_e*/)/*Q16, tmp_e+(freqStart_e)*/; + tmp32 = L_max(0,tmp32); + cycleDelta_e = add(tmp_e,freqStart_e); + tmp32_a = L_shl(tmp32,cycleDelta_e); + roundedCycleDelta = extract_h(L_abs(tmp32_a)); + if (tmp32<0) + { + roundedCycleDelta = negate(roundedCycleDelta); + } + fractionalLeft = lshr(extract_l(tmp32_a),1);/*Q15*/ + tmp_e = sub(15,norm_l(tmp32)); + cycleDelta_e = add(cycleDelta_e,tmp_e); + tmp32 = L_shr(tmp32,sub(tmp_e,15));/*Q31 frac, cycleDelta_e*/ +#ifdef BASOP_NOGLOB + cycleDelta = round_fx_o(tmp32, &Overflow);/*Q15, cycleDelta_e*/ +#else + cycleDelta = round_fx(tmp32);/*Q15, cycleDelta_e*/ +#endif + if (cycleDelta == 0) + { + move16(); + cycleDelta_e = 0; + } + + /*roundedCycleDelta = (int)(cycleDelta); */ /*done above*/ + move16(); + iDeltaSamples[0] = roundedCycleDelta;/*Q0*/ + /*fractionalLeft = cycleDelta-roundedCycleDelta;*/ /*done above*/ + nSamplesDeltaRemain = sub(nSamplesDeltaRemain,roundedCycleDelta);/*Q0*/ + + tmp_e = (s_max(2,k)); + tmp_e = norm_s(tmp_e);/*maximum norming factor for following loop*/ + + + FOR (i = 1; i <= k; i++) + { + /*cycleDelta = (absPitchDiff-(k+1-i)*perCycleDeltaDelta) + fractionalLeft; */ + tmp32 = L_mult(perCycleDeltaDelta/*Q15,perCycleDeltaDelta_e*/,shl(sub(add(k,1),i),tmp_e)/*Q0, tmp_e*/)/*Q0+16, perCycleDeltaDelta_e-tmp_e*/; /*calcultion of base for first iteration*/ + tmp32 = L_shl(tmp32,sub(perCycleDeltaDelta_e,tmp_e));/*Q16*/ + tmp32_a = L_sub(absPitchDiff,tmp32); + tmp32_b = L_lshl(L_deposit_l(fractionalLeft/*Q15*/),1)/*Q16*/; + cycleDelta32 = L_add(tmp32_a,tmp32_b);/*Q16*/ + cycleDelta32 = L_max(0, cycleDelta32); + + /* Make sure that the number of samples increases */ + IF (GT_32(L_deposit_h(roundedCycleDelta), cycleDelta32)) + { + iDeltaSamples[i] = roundedCycleDelta; + move16(); + roundedCycleDelta = extract_h(cycleDelta32); /* cycleDelta32 should never be < 0 here */ + iDeltaSamples[i-1] = roundedCycleDelta; + move16(); + + } + ELSE + { + roundedCycleDelta = extract_h(cycleDelta32); /* cycleDelta32 should never be < 0 here */ + iDeltaSamples[i] = roundedCycleDelta; + move16(); + } + /*fractionalLeft = cycleDelta-roundedCycleDelta = cycleDelta-(int)cycleDelta;*/ + fractionalLeft = lshr(extract_l(cycleDelta32),1); /*Q15*/ /* cycleDelta32 should never be < 0 here */ + nSamplesDeltaRemain = sub(nSamplesDeltaRemain,roundedCycleDelta); + } + iDeltaSamples[k+1] = s_max(0, nSamplesDeltaRemain); + move16(); + maxDeltaSamples = s_max(iDeltaSamples[k], iDeltaSamples[k+1]);/*Q0*/ + + /* Find the location of the minimum energy between the first two pulses */ + + /*iMinPos1 = T0+GetMinimumPosition(src_exc+T0, min(roundedPitchStart, (nSubframes+1)*nFrameLength/nSubframes-T0), maxDeltaSamples);*/ + BASOP_Util_Divide_MantExp(add(nSubframes,1),15,nSubframes,15,&tmp16,&tmp_e); + tmp32 = L_mult(nFrameLength/*Q0*/,tmp16/*Q15,tmp_e*/);/*Q16,tmp_e*/ + tmp16 = round_fx(L_shl(tmp32,tmp_e)); + tmp16 = sub(tmp16,T0); + tmp16 = s_min(roundedPitchStart,tmp16); + + iMinPos1 = GetMinimumPosition( + src_exc+T0, /*Qx*/ + tmp16, /*Q0*/ + maxDeltaSamples /*Q0*/ + ); + iMinPos1 = add(iMinPos1,T0); + + + IF (nSamplesDelta < 0) + { + /* Find the location of the minimum energy before the first pulse */ + + IF (GT_16(iMinPos1 , add(roundedPitchStart , shr(iDeltaSamples[0],1)))) + { + iMinPos[0] = sub(iMinPos1 , sub(roundedPitchStart , shr(iDeltaSamples[0],1))); + move16(); + } + ELSE + { + move16(); + iMinPos[0] = sub(GetMinimumPosition(src_exc, T0, iDeltaSamples[0]) , shr(iDeltaSamples[0],1)); + } + + /* Find the location of the minimum energy between the pulses */ + FOR (i = 1; i <= k; i++) + { + move16(); + iMinPos[i] = add(iMinPos1 , sub(imult1616(sub(i,1),roundedPitchStart) , shr(iDeltaSamples[i],1))); + } + /* Find the location of the minimum energy after the last pulse */ + + IF (LT_16(add(iMinPos1 , add(imult1616(k,roundedPitchStart) , sub(iDeltaSamples[k+1] , shr(iDeltaSamples[k+1],1)))) , sub(nFrameLength,nSamplesDelta) )) + { + move16(); + iMinPos[k+1] = add(iMinPos1 , sub(imult1616(k,roundedPitchStart) , shr(iDeltaSamples[k+1],1))); + } + ELSE + { + /*iMinPos[k+1] = T0+k*roundedPitchStart + + GetMinimumPosition(src_exc+T0+k*roundedPitchStart, nFrameLength-nSamplesDelta-(T0+k*roundedPitchStart), iDeltaSamples[k+1]) + - iDeltaSamples[k+1]/2; */ + tmp16 = GetMinimumPosition(src_exc+T0+k*roundedPitchStart, sub(nFrameLength,add(nSamplesDelta,add(T0,imult1616(k,roundedPitchStart)))), iDeltaSamples[k+1]); + tmp16 = add(add(T0,imult1616(k,roundedPitchStart)),tmp16); + tmp16 = sub(tmp16,shr(iDeltaSamples[k+1],1)); + iMinPos[k+1] = tmp16; + move16(); + } + + IF (GT_16(add(iMinPos[k+1],iDeltaSamples[k+1]) , sub(nFrameLength,nSamplesDelta))) + { + iDeltaSamples[k] += add(iMinPos[k+1] , sub(iDeltaSamples[k+1] , sub(nFrameLength,nSamplesDelta))); + iDeltaSamples[k+1] = sub(nFrameLength , add(nSamplesDelta , iMinPos[k+1])); + } + + /* Remove samples at the given positions */ + RemoveSamples(src_exc, dst_exc, nFrameLength, nSamplesDelta, iMinPos, iDeltaSamples, k+2); + } + ELSE + { + /* Find the location of the minimum energy before the first pulse */ + IF (GT_16(iMinPos1 , roundedPitchStart)) + { + iMinPos[0] = sub(iMinPos1 , roundedPitchStart); + move16(); + } + ELSE + { + iMinPos[0] = GetMinimumPosition(src_exc, T0, iDeltaSamples[0]); + move16(); + } + /* Find the location of the minimum energy between the pulses */ + + FOR (i = 1; i <= k; i++) + { + iMinPos[i] = iMinPos1; + move16(); + iMinPos1 = add(iMinPos1,roundedPitchStart); + } + + /* Find the location of the minimum energy after the last pulse */ + IF (LT_16(iMinPos1 , sub(nFrameLength,nSamplesDelta))) + { + iMinPos[k+1] = iMinPos1; + move16(); + } + ELSE + { + + tmp16 = GetMinimumPosition(src_exc+T0+k*roundedPitchStart, sub(nFrameLength,add(nSamplesDelta,add(T0,imult1616(k,roundedPitchStart)))), iDeltaSamples[k+1]); + tmp16 = add(add(tmp16,T0),imult1616(k,roundedPitchStart)); + iMinPos[k+1] = tmp16; + move16(); + } + + IF (GT_16(add(iMinPos[k+1],iDeltaSamples[k+1]) , sub(nFrameLength,nSamplesDelta))) + { + move16(); + move16(); + iDeltaSamples[k] = add(iDeltaSamples[k] , add(iMinPos[k+1] , sub(iDeltaSamples[k+1] , sub(nFrameLength,nSamplesDelta)))); + iDeltaSamples[k+1] = sub(sub(nFrameLength, nSamplesDelta),iMinPos[k+1]); + } + /* Add samples at the given positions */ + AddSamples(src_exc, dst_exc, nFrameLength, nSamplesDelta, iMinPos, iDeltaSamples, k+2); + } + } + +} + diff --git a/lib_dec/er_util.c b/lib_dec/er_util.c index 2800621a84dd7756e16057928b43931dac769762..ffc863fcc88f5618111ac49d1ef1520020c68bd3 100644 --- a/lib_dec/er_util.c +++ b/lib_dec/er_util.c @@ -44,12 +44,12 @@ /*---------------------------------------------------------------------* - * minimumStatistics() + * minimumStatistics_flt() * * *---------------------------------------------------------------------*/ -void minimumStatistics( +void minimumStatistics_flt( float *noiseLevelMemory, int16_t *noiseLevelIndex, int16_t *currLevelIndex, @@ -127,14 +127,14 @@ void minimumStatistics( } /*---------------------------------------------------------------------* - * getLevelSynDeemph() + * getLevelSynDeemph_flt() * * PLC: [ACELP: Fade-out] - * PLC: getLevelSynDeemph: derives on frame or subframe basis the level + * PLC: getLevelSynDeemph_flt: derives on frame or subframe basis the level * of LPC synthesis and deeemphasis based on the given input *----------------------------------------------------------------------*/ -float getLevelSynDeemph( +float getLevelSynDeemph_flt( const float h1Init[], /* i : input value or vector to be processed */ const float A[], /* i : LPC coefficients */ const int16_t lenLpcExc, /* i : length of the LPC excitation buffer */ @@ -172,12 +172,12 @@ float getLevelSynDeemph( /*--------------------------------------------------------------------- - * genPlcFiltBWAdap() + * genPlcFiltBWAdap_flt() * * *---------------------------------------------------------------------*/ -void genPlcFiltBWAdap( +void genPlcFiltBWAdap_flt( const int32_t sr_core, /* i : core sampling rate */ float *lpFiltAdapt, /* o : filter coefficients for filtering codebooks in case of flc */ const int16_t type, /* i : type of filter, either 0 : lowpass or 1 : highpass */ @@ -218,13 +218,13 @@ void genPlcFiltBWAdap( } /*------------------------------------------------------------------ - * highPassFiltering() + * highPassFiltering_flt() * * PLC: [ACELP: general] * PLC: high pass filtering *-----------------------------------------------------------------*/ -void highPassFiltering( +void highPassFiltering_flt( const int16_t last_good, /* i : last classification type */ const int16_t L_buffer, /* i : buffer length */ float exc2[], /* i/o: unvoiced excitation before the high pass filtering */ @@ -246,13 +246,13 @@ void highPassFiltering( } /*--------------------------------------------------------------------- - * GetPLCModeDecision() + * GetPLCModeDecision_flt() * * PLC: [Common: mode decision] * PLC: Decide which Concealment to use. Update pitch lags if needed *--------------------------------------------------------------------*/ -int16_t GetPLCModeDecision( +int16_t GetPLCModeDecision_flt( Decoder_State *st /* i/o: decoder memory state pointer */ ) { @@ -310,7 +310,7 @@ int16_t GetPLCModeDecision( && ( st->old_fpitch_float == hTcxDec->tcxltp_second_last_pitch_float ) && !st->last_tns_active && !st->second_last_tns_active ) { - TonalMDCTConceal_Detect( st->hTonalMDCTConc, ( hTcxDec->tcxltp_last_gain_unmodified_float > 0 ) ? st->old_fpitch_float : 0, &numIndices, + TonalMDCTConceal_Detect_ivas( st->hTonalMDCTConc, ( hTcxDec->tcxltp_last_gain_unmodified_float > 0 ) ? st->old_fpitch_float : 0, &numIndices, ( st->element_mode == IVAS_CPE_MDCT ? &( st->hTcxCfg->psychParamsTCX20 ) : st->hTcxCfg->psychParamsCurrent ) ); if ( ( numIndices > 10 ) || ( ( numIndices > 5 ) && ( fabs( hTcxDec->tcxltp_third_last_pitch_float - hTcxDec->tcxltp_second_last_pitch_float ) < 0.5f ) ) || ( ( numIndices > 0 ) && ( ( st->last_good <= UNVOICED_TRANSITION ) || ( hTcxDec->tcxltp_last_gain_unmodified_float <= 0.4f ) ) && ( fabs( hTcxDec->tcxltp_third_last_pitch_float - hTcxDec->tcxltp_second_last_pitch_float ) < 0.5f ) ) ) diff --git a/lib_dec/er_util_fx.c b/lib_dec/er_util_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..bb4bed2998c6c597d7419bbd2cfe9462fc86f159 --- /dev/null +++ b/lib_dec/er_util_fx.c @@ -0,0 +1,496 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + + +#include +#include "options.h" +#include "prot_fx1.h" +#include "prot_fx2.h" +#include "basop_util.h" +#include + + + +/* static void setnoiseLevelMemory() + * + * Helper function - updates buffer for minimumStatistics function + */ +static void setnoiseLevelMemory(Word16 f, Word16* new_noiseEstimate_e, Word16* noiseLevelMemory_e, Word16* noiseLevelMemory, Word16* currLevelIndex) +{ + noiseLevelMemory[*currLevelIndex] = f; + move16(); + noiseLevelMemory_e[*currLevelIndex] = *new_noiseEstimate_e; + move16(); +} + + +/* PLC: [Common: Fade-out] + * PLC: and for PLC fade out */ + +void minimumStatistics( + Word16* noiseLevelMemory, /* Qx, internal state */ + Word16* noiseLevelIndex, /* Q0, internal state */ + Word16* currLevelIndex, /* Q0, internal state (circular buffer) */ + Word16* noiseEstimate, /* Qx, previous estimate of background noise */ + Word16* lastFrameLevel, /* Qx, level of the last frame */ + Word16 currentFrameLevel, /* Qx, level of the current frame */ + Word16* noiseLevelMemory_e, /* scaling factor for noiseLevelMemory */ + Word16 const noiseEstimate_e, /* exponent of noiseEstimate */ + Word16* new_noiseEstimate_e, /* new exponent of noise Estimate*/ + Word16* const lastFrameLevel_e, /* exponent of lastFrameLevel */ + Word16 currentFrameLevel_e) /* exponent of currentFrameLevel */ +{ + Word16 aOpt, aOpt_e; + Word16 f, p, i; + Word16 tmp,tmp2, tmp_e; + Word32 tmp32; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + move16(); + aOpt_e = 0; + + + BASOP_SATURATE_WARNING_OFF_EVS +#ifdef BASOP_NOGLOB + IF (LT_16(shl_o(currentFrameLevel, currentFrameLevel_e, &Overflow),PLC_MIN_CNG_LEV)) +#else + IF (LT_16(shl(currentFrameLevel, currentFrameLevel_e),PLC_MIN_CNG_LEV)) +#endif + { + BASOP_SATURATE_WARNING_ON_EVS + currentFrameLevel = PLC_MIN_CNG_LEV; + move16(); + move16(); + currentFrameLevel_e = 0; + } + BASOP_SATURATE_WARNING_ON_EVS + + /* compute optimal factor aOpt for recursive smoothing of frame minima */ + tmp2 = BASOP_Util_Add_MantExp(*lastFrameLevel,*lastFrameLevel_e,negate(*noiseEstimate),noiseEstimate_e,&tmp); + IF (tmp >= 0) + { + /* aOpt = *noiseEstimate / *lastFrameLevel; */ + aOpt = BASOP_Util_Divide1616_Scale(*noiseEstimate, *lastFrameLevel, &aOpt_e); + aOpt_e = add(aOpt_e, sub(noiseEstimate_e, *lastFrameLevel_e)); + } + ELSE + { + /* aOpt = *lastFrameLevel / *noiseEstimate; */ + aOpt = BASOP_Util_Divide1616_Scale(*lastFrameLevel, *noiseEstimate, &aOpt_e); + aOpt_e = add(aOpt_e, sub(*lastFrameLevel_e, noiseEstimate_e)); + } + aOpt = mult_r(aOpt, aOpt); /* Q15 */ + aOpt_e = shl(aOpt_e,1); + if (aOpt == 0) + { + move16(); + aOpt_e = 0; + } + + *lastFrameLevel = currentFrameLevel; + move16(); + move16(); + *lastFrameLevel_e = currentFrameLevel_e; + + /* recursively compute smoothed frame minima using optimal factor aOpt */ + tmp = *currLevelIndex; + move16(); + move16(); + if (tmp == 0) + { + tmp = PLC_MIN_STAT_BUFF_SIZE; + move16(); + + } + /*f = msu_r(L_mult(aOpt, noiseLevelMemory[sub(tmp, 1)]), add(aOpt, 0x8000), currentFrameLevel);*/ + /*f = (aOpt * noiseLevelMemory[tmp-1]) - (currentFrameLevel * (aOpt-1))*/ + /*tmp32*/ /*tmp*/ + + tmp32 = L_mult(aOpt,noiseLevelMemory[tmp-1]); /*Q_tmp32 = aOpt_e + noiseLevelMemory_e[tmp - 1]*/ + move16(); + tmp_e = tmp; + + + tmp2 = BASOP_Util_Add_MantExp(aOpt,aOpt_e,negate(32768/2),1,&tmp); + tmp = mult_r(tmp,currentFrameLevel); /*Q_tmp = tmp2 + currentFrameLevel_e*/ + tmp2 = add(tmp2,currentFrameLevel_e); + + *new_noiseEstimate_e = BASOP_Util_Add_MantExp(round_fx(tmp32),add(aOpt_e,noiseLevelMemory_e[tmp_e - 1]),negate(s_max(tmp,-32767)/*to avoid negate(-32768)*/),tmp2,&f); + + assert(f >= 0); + + /* if current frame min is a new local min, set index to current index */ + p = *noiseLevelIndex; + move16(); + tmp2 = BASOP_Util_Add_MantExp(noiseLevelMemory[p],noiseLevelMemory_e[p],negate(f),*new_noiseEstimate_e,&tmp); + IF (tmp >= 0) + { + + /*rescale noiseLevelMemory*/ + + setnoiseLevelMemory(f,new_noiseEstimate_e,noiseLevelMemory_e, noiseLevelMemory, currLevelIndex); + p = *currLevelIndex; + move16(); + } + ELSE + { + move16(); + + setnoiseLevelMemory(f,new_noiseEstimate_e, noiseLevelMemory_e, noiseLevelMemory, currLevelIndex); + + /* current min is not a new min, so check if min must be re-searched */ + IF (NE_16(p, *currLevelIndex)) + { + f = noiseLevelMemory[p]; /* min is still in memory, so return it */ + move16(); + *new_noiseEstimate_e = noiseLevelMemory_e[p]; + } + ELSE { + /* p == currLevelIndex; min was removed from memory, re-search min */ + FOR (i = 0; i < PLC_MIN_STAT_BUFF_SIZE; i++) + { + tmp2 = BASOP_Util_Add_MantExp(noiseLevelMemory[p],noiseLevelMemory_e[p],negate(noiseLevelMemory[i]),noiseLevelMemory_e[i],&tmp); + if ( tmp > 0) + { + p = i; + move16(); + } + } + f = noiseLevelMemory[p]; + move16(); + *new_noiseEstimate_e = noiseLevelMemory_e[p]; + } + } + + /* update local-minimum-value index and current circular-buffer index */ + *noiseLevelIndex = p; + move16(); + p = add(*currLevelIndex,1); + *currLevelIndex = add(*currLevelIndex, 1); + move16(); + if (EQ_16(*currLevelIndex, PLC_MIN_STAT_BUFF_SIZE)) + { + *currLevelIndex = 0; + move16(); + } + + *noiseEstimate = f; + move16(); +} + +/*----------------------------------------------------------------------* + * PLC: [ACELP: Fade-out] + * PLC: getLevelSynDeemph: derives on frame or subframe basis the level + * of LPC synthesis and deeemphasis based on the given input + *----------------------------------------------------------------------*/ +Word16 getLevelSynDeemph( /*10Q5*/ + Word16 h1Init[], /* i: input value or vector to be processed */ /* Q15 */ + Word16 const A[], /* i: LPC coefficients */ /* Qx */ + Word16 const lpcorder, /* i: LPC order */ /* Q0 */ + Word16 const lenLpcExc, /* i: length of the LPC excitation buffer */ /* Q0 */ + Word16 const preemph_fac, /* i: preemphasis factor */ /* Q15 */ + Word16 const numLoops, /* i: number of loops */ /* Q0 */ + Word16 *Exp /* o: exponent of return value Q15 */ +) +{ + Word32 levelSynDeemphSub; + Word32 levelSynDeemph ; + Word16 h1[L_FRAME_PLUS/4]; /*Q15*/ + Word16 mem[M]; + Word16 tmp; + Word16 loop; + Word16 s16, tmp16, Hr16; + Word16 Q_h1; + + + levelSynDeemphSub = L_deposit_l(0); + levelSynDeemph = L_deposit_l(0); + tmp = 0; + Q_h1 = 9; /*synthesis scaling for */ move16(); + + /*calculate headroom for dotproduct*/ + Hr16 = sub(15,norm_s(lenLpcExc)); + + Q_h1 = s_max(sub(Q_h1,Hr16),0); /*compensate synthesis scaling with Headroom as much as possible to retain as much precision as possible*/ + + /*Factor to be multiplied in order to calculate dotproduct with headroom*/ + tmp16 = shr(32768/2,sub(Hr16,1)); + + /*moved from inside loop, before synthesis*/ + h1Init[0] = mult_r(h1Init[0],tmp16); + move16(); + + FOR (loop = 0; loop < numLoops; loop++) + { + set16_fx(h1, 0, lenLpcExc); + set16_fx(mem, 0, lpcorder); + + Copy(h1Init, h1, 1); + /*h1 will be scaled down, Q_h1 */ + E_UTIL_synthesis(Q_h1, A, h1, h1, lenLpcExc, mem, 0, lpcorder); + deemph_fx(h1, preemph_fac, lenLpcExc, &tmp); + A += (M+1); + + /* gain introduced by synthesis+deemphasis */ + /*levelSynDeemphSub = (float)sqrt(dot_product( h1, h1, lenLpcExc));*/ + levelSynDeemphSub = Dot_product12_offs(h1, h1, lenLpcExc, &s16, 0); + s16 = sub(shl(add(Q_h1,Hr16),1), sub(30, s16)); + + levelSynDeemphSub = Sqrt32(levelSynDeemphSub,&s16); /*Q31*/ + + /* mean of the above across all subframes -- moved outta loop*/ + /*levelSynDeemph += (1.0/(float)numLoops) * levelSynDeemphSub;*/ + tmp16 = 32767/*1.0f Q15*/; + move16(); + + if (GT_16(numLoops , 1)) + { + tmp16 = div_s(1,numLoops); + } + + levelSynDeemph = L_add(levelSynDeemph , L_shl(Mpy_32_16_1(levelSynDeemphSub,tmp16),sub(s16,10))); /*10Q21*/ + + } + s16 = norm_l(levelSynDeemph); + levelSynDeemph = L_shl(levelSynDeemph, s16); + move16(); + *Exp = sub(10,s16); /*Set exponent in order to transform returnvalue to Q15*/ + +#ifdef BASOP_NOGLOB + return round_fx_sat(levelSynDeemph); /*Q15*/ +#else + return round_fx(levelSynDeemph); /*Q15*/ +#endif +} + +/* BASOP version: up to date with rev 7422 */ +void genPlcFiltBWAdap( + const Word32 sr_core, /* i : core sampling rate */ + Word16* lpFiltAdapt, /* o : filter coefficients for filtering codebooks in case of flc */ + const Word16 type, /* i : type of filter, either 0 : lowpass or 1 : highpass */ + const Word16 alpha /* i : fade out factor [0 1) used decrease filter tilt */ +) +{ + Word16 a, b, exp; + + + assert(type == 0 || type == 1); + + IF ( EQ_32(sr_core, INT_FS_16k)) + { + IF (type == 0) + { + move16(); + move16(); + move16(); + *lpFiltAdapt++ = 7282/* 0.4000f/(2.f*0.4000f+1.f) Q15*/; + *lpFiltAdapt++ = 18204/* 1.f/(2.f*0.4000f+1.f) Q15*/; + *lpFiltAdapt = 7282/* 0.4000f/(2.f*0.4000f+1.f) Q15*/; + } + ELSE + { + a = mult_r(13107/*0.4000f Q15*/, alpha); + exp = 0; + move16(); + b = Inv16(add(a, 16384/*0.5f Q15*/), &exp); + b = shr(b, sub(1, exp)); + a = negate(mult_r(a, b)); + move16(); + move16(); + move16(); + *lpFiltAdapt++ = a; + *lpFiltAdapt++ = b; + *lpFiltAdapt = a; + } + } + ELSE /*sr_core = INT_FS_12k8 */ + { + IF (type == 0) + { + move16(); + move16(); + move16(); + *lpFiltAdapt++ = 5899/* 0.2813f/(2.f*0.2813f+1.f) Q15*/; + *lpFiltAdapt++ = 20970/* 1.f/(2.f*0.2813f+1.f) Q15*/; + *lpFiltAdapt = 5899/* 0.2813f/(2.f*0.2813f+1.f) Q15*/; + } + ELSE { + a = mult_r(9218/*0.2813f Q15*/, alpha); + exp = 0; + move16(); + b = Inv16(add(a, 16384/*0.5f Q15*/), &exp); + b = shr(b, sub(1, exp)); + a = negate(mult_r(a, b)); + move16(); + move16(); + move16(); + *lpFiltAdapt++ = a; + *lpFiltAdapt++ = b; + *lpFiltAdapt = a; + } + } + +} + + +/*-----------------------------------------------------------------* + * PLC: [ACELP: general] + * PLC: high pass filtering + *-----------------------------------------------------------------*/ +/*VERSIONINFO: This port is up to date with trunk rev. 32434*/ +void highPassFiltering( + const Word16 last_good, /* i: short last classification type */ + const Word16 L_buffer, /* i: int buffer length */ + Word16 exc2[], /* i/o: Qx unvoiced excitation before the high pass filtering */ + const Word16 hp_filt[], /* i: Q15 high pass filter coefficients */ + const Word16 l_fir_fer) /* i: high pass filter length */ + +{ + Word16 i; /*int*/ + + IF( GT_16(last_good , UNVOICED_TRANSITION)) + { + + FOR( i=0 ; i< L_buffer; i++ ) + { + exc2[i] = round_fx(L_sub(Dot_product(&exc2[i], hp_filt, l_fir_fer), 1)); + } + } +} + +/*----------------------------------------------------------------------------------* + * PLC: [Common: mode decision] + * PLC: Decide which Concealment to use. Update pitch lags if needed + *----------------------------------------------------------------------------------*/ +Word16 GetPLCModeDecision( + Decoder_State *st /* i/o: decoder memory state pointer */ +) +{ + Word16 /*int*/ core; + Word16 numIndices = 0; + TCX_DEC_HANDLE hTcxDec; + + hTcxDec = st->hTcxDec; + + + IF( EQ_16(st->flagGuidedAcelp,1)) + { + st->old_pitch_buf_fx[2*st->nb_subfr] = L_deposit_h(st->guidedT0); + st->old_pitch_buf_fx[2*st->nb_subfr+1] = L_deposit_h(st->guidedT0); + st->mem_pitch_gain[0] = st->mem_pitch_gain[1] = 16384/*1.f Q14*/;/*Q14*/ + } + st->plc_use_future_lag = 0; + move16(); + test(); + test(); + if(( st->last_core > ACELP_CORE && hTcxDec->tcxltp_last_gain_unmodified!=0 ) + || ( EQ_16(st->flagGuidedAcelp,1) ) + ) + { + /* no updates needed here, because already updated in last good frame */ + st->plc_use_future_lag = 1; + move16(); + } + + IF (EQ_16(st->last_core,-1)) + { + core = TCX_20_CORE; + move16(); + st->last_core = ACELP_CORE; + move16(); + if(st->Opt_AMR_WB) + { + core = ACELP_CORE; + move16(); + } + st->tonal_mdct_plc_active = 0; + move16(); + } + ELSE + { + core = ACELP_CORE; + move16(); + if (GT_16(st->nbLostCmpt,1)) + { + core = st->last_core_bfi; + move16(); + } + IF (EQ_16(st->nbLostCmpt,1)) + { + st->tonal_mdct_plc_active = 0; + move16(); + test(); + test(); + test(); + IF ( !(st->rf_flag && st->use_partial_copy && (EQ_16(st->rf_frame_type, RF_TCXTD1)||EQ_16(st->rf_frame_type,RF_TCXTD2)))) + { + test(); + test(); + test(); + test(); + test(); + test(); +//PMT("handle to tonalMDCTconceal is missing") +//#ifdef ADD_IVAS_HTONALMDCTCONC + IF ((/*st->ADD_IVAS_HTONALMDCTCONC != NULL &&*/ EQ_16(st->last_core,TCX_20_CORE))&&(EQ_16(st->second_last_core,TCX_20_CORE)) + && ((LE_32(st->old_fpitch,L_deposit_h(shr(st->L_frame,1)))) + || (LE_16(hTcxDec->tcxltp_last_gain_unmodified,13107/*0.4f Q15*/))) + /* it is fine to call the detection even if no ltp information + is available, meaning that st->old_fpitch == + st->tcxltp_second_last_pitch == st->L_frame */ + && (EQ_32(st->old_fpitch, hTcxDec->tcxltp_second_last_pitch)) + && !st->last_tns_active && !st->second_last_tns_active) + { + Word32 pitch; + + + pitch = L_deposit_h(0); + if(hTcxDec->tcxltp_last_gain_unmodified > 0) + { + pitch = L_add(st->old_fpitch, 0); + } + TonalMDCTConceal_Detect(&st->tonalMDCTconceal, pitch, &numIndices +#ifdef ADD_IVAS_HTONALMDCTCONC + , (st->element_mode == IVAS_CPE_MDCT ? &(st->hTcxCfg->psychParamsTCX20) : st->hTcxCfg->psychParamsCurrent) +#endif + ); + + test(); + test(); + test(); + test(); + test(); + test(); + IF ((GT_16(numIndices,10)) + || ((GT_16(numIndices,5) ) + && (LT_32(L_abs(L_sub(hTcxDec->tcxltp_third_last_pitch, hTcxDec->tcxltp_second_last_pitch)),32768l/*0.5f Q16*/) )) + || ((numIndices > 0) && ((LE_16(st->last_good_fx,UNVOICED_TRANSITION))||(LE_16(hTcxDec->tcxltp_last_gain_unmodified,13107/*0.4f Q15*/))) + && (LT_32(L_abs(L_sub(hTcxDec->tcxltp_third_last_pitch, hTcxDec->tcxltp_second_last_pitch)),32768l/*0.5f Q16*/) ))) + { + core = TCX_20_CORE; + move16(); + st->tonal_mdct_plc_active = 1; + move16(); + } + ELSE IF (LE_16(st->last_good_fx,UNVOICED_TRANSITION)||LE_16(hTcxDec->tcxltp_last_gain_unmodified,13107/*0.4f Q15*/)) + { + core = TCX_20_CORE; + move16(); + } + } + ELSE IF (st->last_core != ACELP_CORE) + { + test(); + if (LE_16(st->last_good_fx,UNVOICED_TRANSITION)||LE_16(hTcxDec->tcxltp_last_gain_unmodified,13107/*0.4f Q15*/)) + { + core = st->last_core; + move16(); + } + } + } + } + } + return core; +} diff --git a/lib_dec/evs_dec.c b/lib_dec/evs_dec.c index 7bd86c44dfb84b08d606216c467149a86b4a0c07..b882f89288626d3eddc4de073be01d60d2c59760 100644 --- a/lib_dec/evs_dec.c +++ b/lib_dec/evs_dec.c @@ -43,12 +43,12 @@ #include "wmc_auto.h" /*--------------------------------------------------------------------------* - * evs_dec() + * evs_dec_flt() * * Principal decoder routine *--------------------------------------------------------------------------*/ -ivas_error evs_dec( +ivas_error evs_dec_flt( Decoder_State *st, /* i/o: Decoder state structure */ float mem_hp20_out[L_HP20_MEM], /* i/o: HP filter memory for synthesis */ float *output, /* o : output synthesis signal */ @@ -80,13 +80,13 @@ ivas_error evs_dec( error = IVAS_ERR_OK; - push_wmops( "evs_dec" ); + push_wmops( "evs_dec_flt" ); /*------------------------------------------------------------------* * Initialization *-----------------------------------------------------------------*/ st->idchan = 0; - st->flag_ACELP16k = set_ACELP_flag( EVS_MONO, -1, st->total_brate, 0, 0, -1, -1 ); + st->flag_ACELP16k = set_ACELP_flag_IVAS( EVS_MONO, -1, st->total_brate, 0, 0, -1, -1 ); tmps = 0; delay_tdbwe = 0; @@ -177,7 +177,7 @@ ivas_error evs_dec( } /* if previous frame was HQ Core/TCX10/TCX20 (high bitrate), drop partial copy info and continue HQ Core/TCX10/TCX20 concealment */ - if ( st->use_partial_copy && ( st->last_core == HQ_CORE || st->last_core == TCX_10_CORE || ( st->last_core == TCX_20_CORE && getTcxonly( EVS_MONO, st->last_total_brate, 0, 0 ) ) ) ) + if ( st->use_partial_copy && ( st->last_core == HQ_CORE || st->last_core == TCX_10_CORE || ( st->last_core == TCX_20_CORE && getTcxonly_ivas( EVS_MONO, st->last_total_brate, 0, 0 ) ) ) ) { st->bfi = 1; st->codec_mode = st->last_codec_mode; @@ -295,7 +295,7 @@ ivas_error evs_dec( if ( st->extl == WB_BWE && st->bws_cnt == 0 ) { /* WB BWE decoder */ - wb_bwe_dec( st, NULL, synth, hb_synth, 0, output_frame, voice_factors, pitch_buf ); + wb_bwe_dec_flt( st, NULL, synth, hb_synth, 0, output_frame, voice_factors, pitch_buf ); } /*---------------------------------------------------------------------* @@ -317,7 +317,7 @@ ivas_error evs_dec( else if ( st->extl == SWB_BWE || st->extl == FB_BWE || ( st->output_Fs >= 32000 && st->core == ACELP_CORE && st->bwidth > NB && st->bws_cnt > 0 && !st->ppp_mode_dec && !( st->nelp_mode_dec == 1 && st->bfi == 1 ) ) ) { /* SWB BWE decoder */ - swb_bwe_dec( st, NULL, synth, hb_synth, 0, output_frame ); + swb_bwe_dec_flt( st, NULL, synth, hb_synth, 0, output_frame ); } else if ( st->extl == SWB_BWE_HIGHRATE || st->extl == FB_BWE_HIGHRATE ) { @@ -474,7 +474,7 @@ ivas_error evs_dec( } /* TCX-LTP Postfilter: used in Mode 1 to update memories and to avoid discontinuities when the past frame was TCX */ - tcx_ltp_post( st, hTcxLtpDec, ACELP_CORE, output_frame, 0, synth, NULL ); + tcx_ltp_post_flt( st, hTcxLtpDec, ACELP_CORE, output_frame, 0, synth, NULL ); /* final output of synthesis signal */ mvr2r( synth, output, output_frame ); @@ -514,7 +514,7 @@ ivas_error evs_dec( * Decode core * -------------------------------------------------------------- */ - dec_acelp_tcx_frame( st, &concealWholeFrame, output, st->p_bpf_noise_buf_float, pcmbufFB, bwe_exc_extended, voice_factors, pitch_buf, NULL ); + dec_acelp_tcx_frame_flt( st, &concealWholeFrame, output, st->p_bpf_noise_buf_float, pcmbufFB, bwe_exc_extended, voice_factors, pitch_buf, NULL ); concealWholeFrameTmp = concealWholeFrame; if ( st->bfi ) @@ -662,57 +662,57 @@ ivas_error evs_dec( * - do CNG during inactive frames * -------------------------------------------------------------- */ - noisy_speech_detection( st->hFdCngDec, st->VAD && st->m_frame_type == ACTIVE_FRAME, output ); + noisy_speech_detection_flt( st->hFdCngDec, st->VAD && st->m_frame_type == ACTIVE_FRAME, output ); - st->hFdCngDec->hFdCngCom->likelihood_noisy_speech = 0.99f * st->hFdCngDec->hFdCngCom->likelihood_noisy_speech + 0.01f * (float) st->hFdCngDec->hFdCngCom->flag_noisy_speech; + st->hFdCngDec->hFdCngCom->likelihood_noisy_speech_flt = 0.99f * st->hFdCngDec->hFdCngCom->likelihood_noisy_speech_flt + 0.01f * (float) st->hFdCngDec->hFdCngCom->flag_noisy_speech; st->lp_noise_float = st->hFdCngDec->lp_noise_float; - ApplyFdCng( output, NULL, realBuffer, imagBuffer, st, concealWholeFrame, 0 ); + ApplyFdCng_flt( output, NULL, realBuffer, imagBuffer, st, concealWholeFrame, 0 ); /* Generate additional comfort noise to mask potential coding artefacts */ if ( st->m_frame_type == ACTIVE_FRAME && st->flag_cna ) { - generate_masking_noise( output, st->hFdCngDec->hFdCngCom, st->hFdCngDec->hFdCngCom->frameSize, 0, 0, 0, st->element_mode, NULL, -1 ); + generate_masking_noise_flt( output, st->hFdCngDec->hFdCngCom, st->hFdCngDec->hFdCngCom->frameSize, 0, 0, 0, st->element_mode, NULL, -1 ); } } if ( st->flag_cna == 0 && st->L_frame == L_FRAME16k && st->last_flag_cna == 1 && ( ( st->last_core == ACELP_CORE && st->last_coder_type != AUDIO ) || st->last_core == TCX_20_CORE || st->last_core == AMR_WB_CORE ) ) { - v_multc( st->hFdCngDec->hFdCngCom->olapBufferSynth2 + 5 * st->L_frame / 4, 256.f, tmp_buffer, st->L_frame / 2 ); + v_multc( st->hFdCngDec->hFdCngCom->olapBufferSynth2_flt + 5 * st->L_frame / 4, 256.f, tmp_buffer, st->L_frame / 2 ); v_add( tmp_buffer, output, output, st->L_frame / 2 ); } if ( st->m_frame_type == ACTIVE_FRAME ) { - cldfbAnalysis( output, realBuffer, imagBuffer, -1, st->cldfbAna ); + cldfbAnalysis_ivas( output, realBuffer, imagBuffer, -1, st->cldfbAna ); } else { float timeDomainBuffer[L_FRAME16k]; float A[M + 1]; - mvr2r( st->hFdCngDec->hFdCngCom->timeDomainBuffer, timeDomainBuffer, st->L_frame ); - mvr2r( st->hFdCngDec->hFdCngCom->A_cng, A, M + 1 ); + mvr2r( st->hFdCngDec->hFdCngCom->timeDomainBuffer_flt, timeDomainBuffer, st->L_frame ); + mvr2r( st->hFdCngDec->hFdCngCom->A_cng_flt, A, M + 1 ); - update_decoder_LPD_cng( st, timeDomainBuffer, A, st->p_bpf_noise_buf_float); + update_decoder_LPD_cng_flt( st, timeDomainBuffer, A, st->p_bpf_noise_buf_float); /* Generate additional comfort noise to mask potential coding artefacts */ if ( st->flag_cna ) { - generate_masking_noise( timeDomainBuffer, st->hFdCngDec->hFdCngCom, st->hFdCngDec->hFdCngCom->frameSize, 0, 0, 0, st->element_mode, NULL, -1 ); + generate_masking_noise_flt( timeDomainBuffer, st->hFdCngDec->hFdCngCom, st->hFdCngDec->hFdCngCom->frameSize, 0, 0, 0, st->element_mode, NULL, -1 ); } else if ( st->L_frame == L_FRAME16k && st->last_flag_cna == 1 && ( ( st->last_core == ACELP_CORE && st->last_coder_type != AUDIO ) || st->last_core == TCX_20_CORE || st->last_core == AMR_WB_CORE ) ) { - v_multc( st->hFdCngDec->hFdCngCom->olapBufferSynth2 + 5 * st->L_frame / 4, 256.f, tmp_buffer, st->L_frame / 2 ); + v_multc( st->hFdCngDec->hFdCngCom->olapBufferSynth2_flt + 5 * st->L_frame / 4, 256.f, tmp_buffer, st->L_frame / 2 ); v_add( tmp_buffer, timeDomainBuffer, timeDomainBuffer, st->L_frame / 2 ); } /* check if the CLDFB works on the right sample rate */ if ( ( st->cldfbAna->no_channels * st->cldfbAna->no_col ) != st->L_frame ) { - resampleCldfb( st->cldfbAna, ( st->L_frame * FRAMES_PER_SEC ) ); - resampleCldfb( st->cldfbBPF, ( st->L_frame * FRAMES_PER_SEC ) ); + resampleCldfb_ivas( st->cldfbAna, ( st->L_frame * FRAMES_PER_SEC ) ); + resampleCldfb_ivas( st->cldfbBPF, ( st->L_frame * FRAMES_PER_SEC ) ); } st->cldfbSyn->bandsToZero = 0; @@ -724,12 +724,12 @@ ivas_error evs_dec( { st->cldfbSyn->bandsToZero = st->cldfbSyn->no_channels - st->hFdCngDec->hFdCngCom->regularStopBand; } - cldfbAnalysis( timeDomainBuffer, realBuffer, imagBuffer, -1, st->cldfbAna ); + cldfbAnalysis_ivas( timeDomainBuffer, realBuffer, imagBuffer, -1, st->cldfbAna ); } if ( st->flag_cna == 0 ) { - set_f( st->hFdCngDec->hFdCngCom->olapBufferSynth2, 0.f, st->hFdCngDec->hFdCngCom->fftlen ); + set_f( st->hFdCngDec->hFdCngCom->olapBufferSynth2_flt, 0.f, st->hFdCngDec->hFdCngCom->fftlen ); } if ( st->p_bpf_noise_buf_float) @@ -739,7 +739,7 @@ ivas_error evs_dec( if ( st->output_Fs > 8000 && st->hTECDec != NULL ) { - calcGainTemp_TBE( realBuffer, imagBuffer, st->hTECDec->loBuffer, 0, st->cldfbAna->no_col, st->cldfbAna->no_channels, st->hTECDec->pGainTemp, st->tec_flag ); + calcGainTemp_TBE( realBuffer, imagBuffer, st->hTECDec->loBuffer_flt, 0, st->cldfbAna->no_col, st->cldfbAna->no_channels, st->hTECDec->pGainTemp, st->tec_flag ); } /* set high band buffers to zero. Covering the current frame and the overlap area. */ @@ -752,7 +752,7 @@ ivas_error evs_dec( } } - cldfbSynthesis( realBuffer, imagBuffer, output, -1, st->cldfbSyn ); + cldfbSynthesis_ivas( realBuffer, imagBuffer, output, -1, st->cldfbSyn ); /* set multiplication factor according to the sampling rate */ delay_comp = NS2SA( st->output_Fs, DELAY_CLDFB_NS ); @@ -890,7 +890,7 @@ ivas_error evs_dec( } } - tcx_ltp_post( st, hTcxLtpDec, st->core, output_frame, NS2SA( st->output_Fs, ACELP_LOOK_NS ) + tmps, output, st->hTcxDec->FBTCXdelayBuf_float ); + tcx_ltp_post_flt( st, hTcxLtpDec, st->core, output_frame, NS2SA( st->output_Fs, ACELP_LOOK_NS ) + tmps, output, st->hTcxDec->FBTCXdelayBuf_float ); } /* end of Mode 2 */ diff --git a/lib_dec/evs_dec_fx.c b/lib_dec/evs_dec_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..bb4637d1f85d3c1f9ed4b4e9f46f58eebd577ee0 --- /dev/null +++ b/lib_dec/evs_dec_fx.c @@ -0,0 +1,1464 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ +#include +#include /* Debug prototypes */ +#include "options.h" /* Compilation switches */ +#include "cnst.h" /* Common constants */ +#include "rom_com.h" /* Static table prototypes */ +#include "prot_fx1.h" /* Function prototypes */ +#include "prot_fx2.h" /* Function prototypes */ +#include "basop_util.h" /* Function prototypes */ + + +/*--------------------------------------------------------------------------* + * evs_dec_fx() + * + * Principal decoder routine + *--------------------------------------------------------------------------*/ + +ivas_error evs_dec_fx( + Decoder_State *st_fx, /* i/o : Decoder state structure */ + Word16 output_sp[], /* o : output synthesis signal */ + frameMode_fx frameMode /* i : Decoder frame mode */ +) +{ + Word16 i, j, output_frame; + Word16 sharpFlag; + Word16 tmps, incr; + Word16 core_switching_flag; + Word16 unbits; + Word16 hq_core_type; + Word16 post_hq_delay; + Word32 bwe_exc_extended_fx[L_FRAME32k+NL_BUFF_OFFSET]; + Word16 voice_factors_fx[NB_SUBFR16k]; + Word16 hb_synth_fx[L_FRAME48k]; + Word16 hb_synth_fx_exp; + Word32 L_tmp; + Word16 exp,fra; + Word16 tmp_buffer_fx[L_FRAME48k]; + Word16 tmp16,tmp16_2; +#ifdef IVAS_CODE + Word16 synth_fx[L_FRAME48k]; +#else + Word16 synth_fx[L_FRAME48k + HQ_DELTA_MAX*HQ_DELAY_COMP]; +#endif + Word16 fb_exc_fx[L_FRAME16k]; + Word16 pitch_buf_fx[NB_SUBFR16k] = { 0 }; + Word16 Q_fb_exc; + Word16 old_syn_12k8_16k_fx[L_FRAME16k]; + Word16 sid_bw=-1; + Word16 pcmbufFB[L_FRAME_MAX]; + Word32 workBuffer[128*3]; + Word16 delta; + Word16 nab; + Word16 concealWholeFrame; + Word16 concealWholeFrameTmp = -1; + Word16 delay_comp, delay_tdbwe; + + Word16 Qpostd; + Word16 Q_synth; + Word16 Qpostd_prev; + + Word32 *realBuffer[CLDFB_NO_COL_MAX], *imagBuffer[CLDFB_NO_COL_MAX]; + Word32 realBufferTmp[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], imagBufferTmp[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + Word16 timeIn_e; + TD_BWE_DEC_HANDLE hBWE_TD; + HQ_DEC_HANDLE hHQ_core; + TCX_LTP_DEC_HANDLE hTcxLtpDec; + TCX_DEC_HANDLE hTcxDec; + ivas_error error; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + hBWE_TD = st_fx->hBWE_TD; + hHQ_core = st_fx->hHQ_core; + hTcxLtpDec = st_fx->hTcxLtpDec; + hTcxDec = st_fx->hTcxDec; + error = IVAS_ERR_OK; + + timeIn_e = 0; + move16(); + + delay_tdbwe = 0; /* for compiler warning*/ + Qpostd = 0; + move16(); /* default and used for MODE2 */ + concealWholeFrame = -1; + move16(); + + /*------------------------------------------------------------------* + * Initialization + *-----------------------------------------------------------------*/ + + st_fx->idchan = 0; + st_fx->element_brate = st_fx->total_brate; + st_fx->flag_ACELP16k = set_ACELP_flag(EVS_MONO, -1, st_fx->total_brate, 0, 0, -1, -1); + + FOR( i=0; ibfi == 0 ) + { + st_fx->extl = -1; + move16(); + } + + output_frame = st_fx->output_frame_fx; + move16(); + + core_switching_flag = 0; + move16(); + sharpFlag = 0; + move16(); + unbits = 0; + move16(); + + st_fx->use_partial_copy = 0; + move16(); + st_fx->rf_flag = 0; + move16(); + + Qpostd_prev = st_fx->Qprev_synth_buffer_fx; + move16(); + + IF( EQ_16(st_fx->bfi,1)) + { + hq_core_type = hHQ_core->last_hq_core_type_fx; + move16(); + st_fx->coder_type_fx = st_fx->last_coder_type_fx; + move16(); + } + ELSE + { + hq_core_type = -1; + move16(); + st_fx->coder_type_fx = INACTIVE; + move16(); + } + + + /* PLC: [TCX: Fade-out-recovery] + * PLC: overlapping part needs to be attenuated for first good frame */ test(); + test(); + test(); + test(); + IF (!st_fx->bfi + && st_fx->prev_bfi + && (EQ_16(st_fx->last_codec_mode, MODE2) ) + && (EQ_16(st_fx->last_core_bfi, TCX_20_CORE) + || EQ_16(st_fx->last_core_bfi, TCX_10_CORE) )) + { + /* v_multc(st_fx->old_out_fx, st_fx->plcInfo.recovery_gain, */ + /* st_fx->old_out_fx, st_fx->L_frameTCX); */ + FOR( i = 0; i < hTcxDec->L_frameTCX; i++ ) + { + hHQ_core->old_out_fx[i] = shl(mult_r(hHQ_core->old_out_fx[i] , st_fx->plcInfo.recovery_gain), 1); + } + FOR( i = 0; i < st_fx->L_frame; i++ ) + { + hHQ_core->old_out_LB_fx[i] = shl(mult_r(hHQ_core->old_out_LB_fx[i], st_fx->plcInfo.recovery_gain), 1); + } + /* attenuate PLC buffers, if no aldo window + is used and if no sid or zero frame is received */ + IF ( 0 == st_fx->hTcxCfg->last_aldo ) + { + Word32 f; + Word16 s; + Word16 tmp1; + f = L_deposit_l(hTcxDec->conceal_eof_gain); /*Q14*/ + s = norm_l(f); + s = sub(16,s); + tmp1 = extract_l(L_shr_r(f,s)); + FOR( i=0; i < st_fx->hTcxCfg->tcx_mdct_window_lengthFB; i++ ) + { + + hTcxDec->syn_OverlFB[i] = shl(mult(tmp1, hTcxDec->syn_OverlFB[i]), add(s,1)); + move16(); + + } + s = norm_l(f); + s = sub(16,s); + tmp1 = extract_l(L_shr_r(f,s)); + FOR( i=0; i < st_fx->hTcxCfg->tcx_mdct_window_length; i++ ) + { + hTcxDec->syn_Overl[i] = shl(mult(tmp1, hTcxDec->syn_Overl[i]),s); + move16(); + } + } + } + + set16_fx( voice_factors_fx, 0, NB_SUBFR16k ); + set16_fx( hb_synth_fx, 0, L_FRAME48k ); + hb_synth_fx_exp = 0; + move16(); + + st_fx->rate_switching_reset = 0; + move16(); + + if(!st_fx->bfi) + { + st_fx->flagGuidedAcelp = 0; + } + + /*----------------------------------------------------------------* + * Updates in case of AMR-WB IO mode -> EVS primary switching + *----------------------------------------------------------------*/ + + IF( EQ_16(st_fx->last_core,AMR_WB_CORE)) + { + updt_IO_switch_dec_fx( output_frame, st_fx ); + } + + IF( NE_16(frameMode,FRAMEMODE_MISSING)) /* frame mode normal or future frame */ + { + getPartialCopyInfo(st_fx, &st_fx->coder_type_fx, &sharpFlag); + frameMode = st_fx->bfi; + } + + test(); + IF( EQ_16(st_fx->rf_frame_type,RF_NO_DATA)&&EQ_16(st_fx->use_partial_copy,1)) + { + /* the partial copy is a RF FRAME_NO_DATA frame and should follow the concealment path*/ + st_fx->bfi = 1; + move16(); + st_fx->codec_mode = st_fx->last_codec_mode; + move16(); + frameMode = FRAMEMODE_MISSING; + move16(); + st_fx->use_partial_copy = 0; + move16(); + } + + /* if previous frame was concealed via ACELP, drop TCX partial copy info and continue ACELP concealment */ + test(); + test(); + test(); + IF( EQ_16(st_fx->use_partial_copy,1)&&EQ_16(st_fx->core,TCX_20_CORE)&& + EQ_16(st_fx->prev_bfi,1) && EQ_16(st_fx->last_core,ACELP_CORE) ) + { + st_fx->bfi = 1; + move16(); + st_fx->codec_mode = st_fx->last_codec_mode; + move16(); + frameMode = FRAMEMODE_MISSING; + move16(); + st_fx->use_partial_copy = 0; + move16(); + st_fx->core = ACELP_CORE; + move16(); + } + + /* if previous frame was HQ Core or TCX10, drop partial copy info and continue HQ Core/TCX10 concealment */ + IF( st_fx->use_partial_copy && ((sub(st_fx->last_core, HQ_CORE) == 0) || (sub(st_fx->last_core, TCX_10_CORE) == 0) || ((sub(st_fx->last_core, TCX_20_CORE) == 0) && getTcxonly(/*EVS_MONO, */st_fx->last_total_brate/*, 0, 0*/))) ) + { + st_fx->bfi = 1; + move16(); + st_fx->codec_mode = st_fx->last_codec_mode; + move16(); + frameMode = FRAMEMODE_MISSING; + move16(); + st_fx->use_partial_copy = 0; + move16(); + st_fx->core = st_fx->last_core; + move16(); + } + + /*------------------------------------------------------------------* + * Decoding + *-----------------------------------------------------------------*/ + IF( EQ_16(st_fx->codec_mode,MODE1)) + { + /*------------------------------------------------------------------* + * Decision matrix (selection of technologies) + *-----------------------------------------------------------------*/ + + IF ( NE_16(st_fx->bfi,1)) + { + decision_matrix_dec_fx( st_fx, &sharpFlag, &hq_core_type, &core_switching_flag ); + IF( NE_16(st_fx->bfi,1)) + { + st_fx->sr_core = i_mult(st_fx->L_frame, FRAMES_PER_SEC); + st_fx->fscale_old = st_fx->fscale; + st_fx->fscale = sr2fscale(st_fx->sr_core); + } + ELSE + { + frameMode = FRAMEMODE_MISSING; + move16(); + } + } + } + IF( EQ_16(st_fx->codec_mode,MODE1)) + { + /*------------------------------------------------------------------* + * Initialization + *-----------------------------------------------------------------*/ + + IF( EQ_16(st_fx->bfi,1)) + { + st_fx->nbLostCmpt = add(st_fx->nbLostCmpt,1); + } + ELSE + { + st_fx->nbLostCmpt = 0; + move16(); + } + st_fx->enablePlcWaveadjust = 0; + move16(); + + /*---------------------------------------------------------------------* + * Detect bandwidth switching + *---------------------------------------------------------------------*/ + + bandwidth_switching_detect_fx(st_fx); + + /*---------------------------------------------------------------------* + * Preprocessing (preparing) for ACELP/HQ core switching + *---------------------------------------------------------------------*/ + //PMT("core_switching_pre_dec_fx missign args") + if ((error = core_switching_pre_dec_fx( st_fx, output_frame )) != IVAS_ERR_OK) + { + return error; + } + + /*---------------------------------------------------------------------* + * ACELP core decoding + * HQ core decoding + *---------------------------------------------------------------------*/ + IF ( EQ_16(st_fx->core,ACELP_CORE)) + { + /* ACELP core decoder */ + + if ((error = acelp_core_dec_fx(st_fx, NULL, synth_fx, NULL, bwe_exc_extended_fx, voice_factors_fx, old_syn_12k8_16k_fx, sharpFlag, pitch_buf_fx, &unbits, &sid_bw, NULL, NULL, NULL, 0, EVS_MONO, 0, 0, 1, NULL, 1)) != IVAS_ERR_OK) + { + return error; + } + Qpostd = st_fx->Q_syn2; + move16(); + } + ELSE + { + //PMT("HQ core missing args") + + hq_core_dec_fx( st_fx, synth_fx, &Q_synth, output_frame, hq_core_type, core_switching_flag ); + Qpostd = Q_synth; + move16(); + } + /*---------------------------------------------------------------------* + * Postprocessing for ACELP/HQ core switching + *---------------------------------------------------------------------*/ + + if ((error = core_switching_post_dec_fx( st_fx, synth_fx, +#ifdef IVAS_CODE_SWITCHING + output, output_mem[], IVAS_FORMAT ivas_format, use_cldfb_for_dft, +#endif + output_frame, core_switching_flag, +#ifdef IVAS_CODE_SWITCHING + sba_dirac_stereo_flag, nchan_out, +#endif + st_fx->last_element_mode, &Qpostd )) != IVAS_ERR_OK) + { + return error; + } + /*---------------------------------------------------------------------* + * Pre-processing for bandwidth switching + *---------------------------------------------------------------------*/ + + ///PMT("bw_switching_pre_proc_fx missing args") + bw_switching_pre_proc_fx( old_syn_12k8_16k_fx, st_fx ); + + /*---------------------------------------------------------------------* + * WB TBE decoding + * WB BWE decoding + *---------------------------------------------------------------------*/ + + IF ( EQ_16(st_fx->extl,WB_TBE)) + { + /* WB TBE decoder */ + wb_tbe_dec_fx( st_fx, st_fx->coder_type_fx, bwe_exc_extended_fx, st_fx->Q_exc, voice_factors_fx, hb_synth_fx, &hb_synth_fx_exp ); + } + ELSE IF ( EQ_16(st_fx->extl,WB_BWE)&&st_fx->bws_cnt_fx==0) + { + /* WB BWE decoder */ + hb_synth_fx_exp = wb_bwe_dec_fx( +#ifdef ADD_IVAS_BWE + NULL, +#endif + synth_fx, hb_synth_fx, +#ifdef ADD_IVAS_BWE + 0, +#endif + output_frame, voice_factors_fx, pitch_buf_fx, st_fx, &Qpostd ); + } + + /*---------------------------------------------------------------------* + * SWB TBE decoding + * SWB BWE decoding + * FB TBE decoding + *---------------------------------------------------------------------*/ + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF ( EQ_16(st_fx->extl,SWB_TBE)||EQ_16(st_fx->extl,FB_TBE) + || (NE_16(st_fx->coder_type_fx,AUDIO) && NE_16(st_fx->coder_type_fx,INACTIVE) && GT_32(st_fx->core_brate,SID_2k40) && EQ_16(st_fx->core,ACELP_CORE) + && GE_32(st_fx->output_Fs,32000) && GT_16(st_fx->bwidth,NB) && st_fx->bws_cnt_fx > 0 && !st_fx->ppp_mode_dec_fx + && !( EQ_16( st_fx->nelp_mode_dec_fx, 1) && EQ_16( st_fx->bfi, 1) ) ) ) + { + swb_tbe_dec_fx( st_fx, st_fx->coder_type_fx, bwe_exc_extended_fx, st_fx->Q_exc, voice_factors_fx, + old_syn_12k8_16k_fx, fb_exc_fx, &Q_fb_exc, hb_synth_fx, &hb_synth_fx_exp, pitch_buf_fx ); + /* FB TBE decoder/synthesis */ + test(); + IF ( EQ_16(output_frame,L_FRAME48k)&&EQ_16(st_fx->extl,FB_TBE)) + { + fb_tbe_dec_fx( st_fx, fb_exc_fx, Q_fb_exc, hb_synth_fx, hb_synth_fx_exp); + } + } + ELSE IF( EQ_16(st_fx->extl,SWB_BWE)||EQ_16(st_fx->extl,FB_BWE)|| + (GE_32(st_fx->output_Fs,32000) && EQ_16(st_fx->core,ACELP_CORE) && GT_16(st_fx->bwidth,NB) && st_fx->bws_cnt_fx > 0 && !st_fx->ppp_mode_dec_fx + && !( EQ_16( st_fx->nelp_mode_dec_fx, 1) && EQ_16( st_fx->bfi, 1) ) ) ) + { + /* SWB BWE decoder */ + hb_synth_fx_exp = swb_bwe_dec_fx( +#ifdef ADD_IVAS_BWE + NULL, +#endif + st_fx, synth_fx, hb_synth_fx, +#ifdef ADD_IVAS_BWE + 0, +#endif + output_frame, &Qpostd); + } + ELSE IF( EQ_16(st_fx->extl,SWB_BWE_HIGHRATE)||EQ_16(st_fx->extl,FB_BWE_HIGHRATE)) + { + hb_synth_fx_exp = swb_bwe_dec_hr_fx( st_fx, old_syn_12k8_16k_fx, Qpostd, hb_synth_fx, output_frame, unbits, pitch_buf_fx ); + } + + /*---------------------------------------------------------------------* + * FEC - recovery after lost HQ core (smoothing of the BWE component) + *---------------------------------------------------------------------*/ + + test(); + test(); + IF ( st_fx->prev_bfi && EQ_16(st_fx->last_core,HQ_CORE)&&NE_16(st_fx->extl,-1)) + { + /*tmp = FRAC_BWE_SMOOTH/output_frame;*/ + tmp16 = shr(410,shr(output_frame,8)); + if(EQ_16(output_frame, L_FRAME48k)) + { + tmp16 = 68; + move16(); + } + /*output_frame/FRAC_BWE_SMOOTH*/ + j = shr(output_frame,1); + tmp16_2 = 0; + move16(); + FOR (i = 0; i < j; i++) + { + /*hb_synth[i] *= (i*tmp);*/ + hb_synth_fx[i] = mult_r(hb_synth_fx[i], tmp16_2); + move16(); +#ifdef BASOP_NOGLOB + tmp16_2 = add_o(tmp16_2, tmp16, &Overflow); +#else + tmp16_2 = add(tmp16_2, tmp16); +#endif + } + } + + /*---------------------------------------------------------------------* + * SWB CNG + *---------------------------------------------------------------------*/ + IF( GE_16(output_frame,L_FRAME32k)) + { + /* SHB CNG decoder */ + swb_CNG_dec_fx( st_fx, synth_fx, hb_synth_fx, sid_bw, Qpostd ); + + test(); + if( LE_32(st_fx->core_brate, SID_2k40)&&st_fx->bws_cnt_fx==0) + { + hb_synth_fx_exp = 3; + move16(); + } + } + + /*----------------------------------------------------------------* + * Delay ACELP core synthesis to be synchronized with the components of bandwidth extension layers + *----------------------------------------------------------------*/ + + IF ( GE_16(output_frame,L_FRAME16k)) + { + tmps = NS2SA_fx2(st_fx->output_Fs, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS); + + exp=s_min(Qpostd, st_fx->Qprev_synth_buffer_fx); + Scale_sig(synth_fx, output_frame, sub(exp,Qpostd)); + Qpostd=exp; + move16(); + Scale_sig(st_fx->prev_synth_buffer_fx, tmps, sub(exp, st_fx->Qprev_synth_buffer_fx)); + st_fx->Qprev_synth_buffer_fx=exp; + move16(); + Copy(synth_fx, tmp_buffer_fx, output_frame); + Copy(st_fx->prev_synth_buffer_fx, synth_fx, tmps); + Copy(tmp_buffer_fx, synth_fx + tmps, output_frame - tmps); + Copy(tmp_buffer_fx + output_frame - tmps, st_fx->prev_synth_buffer_fx, tmps); + } + ELSE + { + exp=s_min(Qpostd, st_fx->Qprev_synth_buffer_fx); + Scale_sig(synth_fx, output_frame, sub(exp,Qpostd)); + Qpostd=exp; + move16(); + st_fx->Qprev_synth_buffer_fx=exp; + move16(); + } + + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF (EQ_16(st_fx->core,ACELP_CORE) + && !st_fx->bfi + && st_fx->prev_bfi + && GE_32(st_fx->last_total_brate, HQ_48k) + && EQ_16(st_fx->last_codec_mode, MODE2) + && (EQ_16(st_fx->last_core_bfi, TCX_20_CORE) || EQ_16(st_fx->last_core_bfi, TCX_10_CORE) ) + && st_fx->plcInfo.concealment_method == TCX_NONTONAL + && LT_32(st_fx->plcInfo.nbLostCmpt, 4) ) + { + tmps = 0; + IF( GE_16(output_frame,L_FRAME16k)) + { + tmps = NS2SA_fx2(st_fx->output_Fs, DELAY_BWE_TOTAL_NS); + } + + waveform_adj2_fix(st_fx->tonalMDCTconceal.secondLastPcmOut, + synth_fx+tmps, + st_fx->plcInfo.data_noise, + &st_fx->plcInfo.outx_new_n1_fx, + &st_fx->plcInfo.nsapp_gain_fx, + &st_fx->plcInfo.nsapp_gain_n_fx, + &st_fx->plcInfo.recovery_gain, + st_fx->plcInfo.step_concealgain_fx, + st_fx->plcInfo.Pitch_fx, + st_fx->plcInfo.FrameSize, + tmps, + add(extract_l(st_fx->plcInfo.nbLostCmpt), 1), + st_fx->bfi); + st_fx->plcInfo.Pitch_fx = 0; + } + + /*----------------------------------------------------------------* + * Addition of BWE components to the ACELP core synthesis + *----------------------------------------------------------------*/ + + test(); + test(); + IF ( NE_16(st_fx->extl,-1)||(st_fx->bws_cnt_fx>0&&EQ_16(st_fx->core,ACELP_CORE))) + { + /* Calculate an additional delay of extension layer components to be synchronized with ACELP synthesis */ + IF ( EQ_16(st_fx->L_frame,L_FRAME)) + { + /* TBE on top of ACELP@12.8kHz */ + tmps = NS2SA_fx2( st_fx->output_Fs, MAX_DELAY_TBE_NS - DELAY_SWB_TBE_12k8_NS ); + } + ELSE + { + test(); + IF( EQ_16(st_fx->extl,SWB_BWE_HIGHRATE)||EQ_16(st_fx->extl,FB_BWE_HIGHRATE)) + { + /* HR SWB BWE on top of ACELP@16kHz */ + tmps = NS2SA_fx2( st_fx->output_Fs, DELAY_BWE_TOTAL_NS ); + } + ELSE + { + /* TBE on top of ACELP@16kHz */ + tmps = NS2SA_fx2( st_fx->output_Fs, MAX_DELAY_TBE_NS - DELAY_SWB_TBE_16k_NS ); + } + } + + /* Smooth transitions when switching between different technologies */ + test(); + test(); + test(); + test(); + IF ( (NE_16(st_fx->extl,st_fx->last_extl)||(EQ_16(st_fx->extl,st_fx->last_extl)&&EQ_16((st_fx->core^st_fx->last_core),HQ_CORE))) + && !(EQ_16(st_fx->extl,SWB_CNG) && EQ_16(st_fx->last_extl,SWB_TBE)) ) + { + /*incr = (short) ( L_FRAME / (tmps + 0.5f) );*/ + incr = idiv1616(L_FRAME*2, add(shl(tmps,1),1)); + tmp16 = 0; + move16(); + FOR (i=0; ihb_prev_synth_buffer_fx, 0, tmps ); + } + ELSE IF ( LT_16(tmps,st_fx->old_bwe_delay_fx)) + { + /* the previous frame was TBE on top of ACELP@16kHz and the current frame is TBE on top of ACELP@12.8kHz */ + /*incr = (short) ( L_FRAME / (tmps + 0.5f) );*/ + incr = idiv1616(L_FRAME*2, add(shl(tmps,1),1)); + tmp16 = 0; + move16(); + FOR (i=0; ihb_prev_synth_buffer_fx[i], sin_table256_fx[255 - tmp16]), + st_fx->hb_prev_synth_buffer_fx[st_fx->old_bwe_delay_fx - 1 - i], sin_table256_fx[tmp16])); + tmp16 = add(tmp16, incr); + } + Copy(tmp_buffer_fx, st_fx->hb_prev_synth_buffer_fx, tmps); + } + ELSE IF (GT_16(tmps,st_fx->old_bwe_delay_fx)) + { + /* the previous frame was TBE on top of ACELP@12.8kHz and the current frame is TBE on top of ACELP@16kHz */ + /*incr = (short)( L_FRAME / (st->old_bwe_delay + 0.5f) );*/ + incr = idiv1616(L_FRAME*2, add(shl(st_fx->old_bwe_delay_fx,1),1)); + tmp16 = 0; + move16(); + FOR (i=0; iold_bwe_delay_fx; i++) + { + tmp_buffer_fx[i] = mult_r(st_fx->hb_prev_synth_buffer_fx[i], sin_table256_fx[255 - tmp16]); + move16(); + tmp16 = add(tmp16, incr); + + } + FOR (; iold_bwe_delay_fx; i++) + { + /*tmp_buffer[tmps - 1 - i] += st->hb_prev_synth_buffer[st->old_bwe_delay - 1 - i] * sin_table256[i * incr];*/ + tmp_buffer_fx[tmps - 1 - i] = round_fx(L_mac(L_mult(tmp_buffer_fx[tmps - 1 - i], 32767), st_fx->hb_prev_synth_buffer_fx[st_fx->old_bwe_delay_fx - 1 - i], sin_table256_fx[tmp16/*i * incr*/])); + tmp16 = add(tmp16, incr); + } + + Copy( tmp_buffer_fx, st_fx->hb_prev_synth_buffer_fx, tmps ); + } + /* Delay hb_synth */ + tmp16 = sub(hb_synth_fx_exp, hBWE_TD->prev_hb_synth_fx_exp); + IF ( tmp16 != 0 ) + { + Scale_sig(st_fx->hb_prev_synth_buffer_fx, tmps, tmp16 ); + } + Copy( hb_synth_fx, tmp_buffer_fx, output_frame ); + Copy( st_fx->hb_prev_synth_buffer_fx, hb_synth_fx, tmps ); + Copy( tmp_buffer_fx, hb_synth_fx + tmps, output_frame - tmps ); + Copy( tmp_buffer_fx + output_frame - tmps, st_fx->hb_prev_synth_buffer_fx, tmps ); + + st_fx->old_bwe_delay_fx = tmps; + move16(); + + test(); + test(); + test(); + test(); + test(); + test(); + IF( ( st_fx->ppp_mode_dec_fx || (EQ_16(st_fx->nelp_mode_dec_fx,1)&&EQ_16(st_fx->bfi,1)))&&EQ_16(st_fx->L_frame,st_fx->last_L_frame)&&(st_fx->bws_cnt_fx>1||st_fx->last_extl!=-1)) + + { + Copy(hBWE_TD->old_hb_synth_fx, hb_synth_fx, output_frame ); + IF(LT_16(hBWE_TD->prev_hb_synth_fx_exp, 14)) + { + hb_synth_fx_exp = add(hBWE_TD->prev_hb_synth_fx_exp, 1); + } + ELSE + { + hb_synth_fx_exp = 14; + } + } + ELSE + { + Copy( hb_synth_fx, hBWE_TD->old_hb_synth_fx, output_frame ); + } + + add_vec_fx( synth_fx, Qpostd, hb_synth_fx, hb_synth_fx_exp, synth_fx, Qpostd, output_frame ); + + /* SWB CNG/DTX - calculate SHB energy */ + test(); + IF ( GE_16(output_frame, L_FRAME32k)&>_16(st_fx->extl,SWB_CNG)) + { + SWITCH (output_frame) + { + case L_FRAME8k: + tmp16 = 205; + BREAK; /*Q15*/ + case L_FRAME16k: + tmp16 = 102; + BREAK; /*Q15*/ + case L_FRAME32k: + tmp16 = 51; + BREAK; /*Q15*/ + case L_FRAME48k: + tmp16 = 34; + BREAK; /*Q15*/ + } + + L_tmp = L_deposit_l(1); /*Q2*hb_synth_fx_exp*/ + FOR ( i=0; ilast_shb_ener_fx = round_fx_sat(L_shl_sat(L_tmp, 10)); /*Q8*/ +#else + st_fx->last_shb_ener_fx = round_fx(L_shl(L_tmp, 10)); /*Q8*/ +#endif + } + } + hBWE_TD->prev_hb_synth_fx_exp = hb_synth_fx_exp; + move16(); + + /* TCX-LTP Postfilter: used in MODE1 to update memories and to avoid discontinuities when the past frame was TCX */ + delta = NS2SA_fx2( st_fx->output_Fs, TCXLTP_DELAY_NS ); + Scale_sig(hTcxLtpDec->tcxltp_mem_in, delta, sub(Qpostd, Qpostd_prev)); + Scale_sig(hTcxLtpDec->tcxltp_mem_out, output_frame, sub(Qpostd, Qpostd_prev)); + tcx_ltp_post(st_fx, hTcxLtpDec, ACELP_CORE, output_frame, 0, synth_fx, NULL); + + + /* final output of synthesis signal */ + Copy( synth_fx, output_sp, output_frame ); + + + } + ELSE /* MODE2 PART */ + { + + /* -------------------------------------------------------------- */ + /* CONCEALMENT */ + /* -------------------------------------------------------------- */ + + concealWholeFrame = 0; + move16(); + + if( EQ_16(frameMode, FRAMEMODE_NORMAL)) + { + st_fx->m_decodeMode = DEC_NO_FRAM_LOSS; + move16(); + } + + IF( EQ_16(frameMode, FRAMEMODE_MISSING)) + { + test(); + test(); + IF( st_fx->use_partial_copy && GE_16(st_fx->rf_frame_type, RF_TCXFD)&&LE_16(st_fx->rf_frame_type,RF_TCXTD2)) + { + st_fx->m_decodeMode = DEC_NO_FRAM_LOSS; + move16(); + } + ELSE + { + st_fx->m_decodeMode = DEC_CONCEALMENT_EXT; + move16(); + } + } + + SWITCH( st_fx->m_decodeMode ) + { + case DEC_NO_FRAM_LOSS: + BREAK; + case DEC_CONCEALMENT_EXT: + concealWholeFrame = 1; + move16(); + BREAK; + } + + + /* -------------------------------------------------------------- */ + /* DECODE CORE */ + /* -------------------------------------------------------------- */ + + dec_acelp_tcx_frame(st_fx, &concealWholeFrame, output_sp, + st_fx->p_bpf_noise_buf, pcmbufFB, bwe_exc_extended_fx, voice_factors_fx, pitch_buf_fx); + + concealWholeFrameTmp = concealWholeFrame; + move16(); + if(st_fx->bfi) + { + frameMode = FRAMEMODE_MISSING; + move16(); + } + IF( st_fx->igf ) + { + + /* TBE interface */ + test(); + test(); + IF( (st_fx->bfi == 0 || st_fx->last_core == ACELP_CORE) && st_fx->core == ACELP_CORE ) + { + test(); + test(), test(); + SWITCH (st_fx->bwidth) + { + case WB: + st_fx->extl = WB_TBE; + move16(); + st_fx->extl_brate = WB_TBE_0k35; + move32(); + BREAK; + + case SWB: + st_fx->extl = SWB_TBE; + move16(); + st_fx->extl_brate = SWB_TBE_1k6; + move32(); + + IF ( LT_32(st_fx->total_brate, ACELP_13k20)) + { + st_fx->extl_brate = SWB_TBE_0k95; + move32(); + } + ELSE IF (GE_32(st_fx->total_brate, ACELP_24k40)) + { + st_fx->extl_brate = SWB_TBE_2k8; + move32(); + } + BREAK; + + case FB: + st_fx->extl = FB_TBE; + move16(); + st_fx->extl_brate = FB_TBE_1k8; + move32(); + IF(GE_32(st_fx->total_brate, ACELP_24k40)) + { + st_fx->extl_brate = FB_TBE_3k0; + move32(); + } + BREAK; + } + } + ELSE + { + st_fx->extl = IGF_BWE; + move16(); + st_fx->extl_brate = L_deposit_l(0); + } + + test(); + test(); + if( EQ_32(st_fx->output_Fs,8000)||(EQ_32(st_fx->output_Fs, INT_FS_16k)&&EQ_16(st_fx->L_frame,L_FRAME16k))) + { + st_fx->extl = -1; + move16(); + } + + st_fx->core_brate = L_sub(st_fx->total_brate, st_fx->extl_brate); + + st_fx->bws_cnt_fx = 0; + move16(); + st_fx->bws_cnt1_fx = 0; + move16(); + st_fx->tilt_wb_fx = 0; + move16(); + + IF( EQ_16(st_fx->m_frame_type, ACTIVE_FRAME)) + { + test(); + test(); + IF( ( st_fx->bfi == 0 || st_fx->last_core == ACELP_CORE ) && st_fx->core == ACELP_CORE ) + { + test(); + IF( EQ_16(st_fx->extl, WB_TBE)) + { + wb_tbe_dec_fx( st_fx, st_fx->coder_type_fx, bwe_exc_extended_fx, st_fx->Q_exc, voice_factors_fx, hb_synth_fx, &hb_synth_fx_exp ); + } + ELSE IF( EQ_16(st_fx->extl, SWB_TBE)||EQ_16(st_fx->extl,FB_TBE)) + { + /* SWB TBE decoder */ + swb_tbe_dec_fx( st_fx, st_fx->coder_type_fx, bwe_exc_extended_fx, st_fx->Q_exc, voice_factors_fx, hBWE_TD->old_core_synth_fx, + fb_exc_fx, &Q_fb_exc, hb_synth_fx, &hb_synth_fx_exp, pitch_buf_fx ); + test(); + IF( EQ_16(st_fx->extl, FB_TBE)&&EQ_16(output_frame,L_FRAME48k)) + { + fb_tbe_dec_fx( st_fx, fb_exc_fx, Q_fb_exc, hb_synth_fx, hb_synth_fx_exp ); + } + } + Copy( hb_synth_fx, hBWE_TD->old_hb_synth_fx, output_frame ); + } + ELSE + { + IF( EQ_16(st_fx->last_core,ACELP_CORE)) + { + test(); + test(); + test(); + test(); + IF( ( EQ_16(st_fx->bwidth, SWB)||EQ_16(st_fx->bwidth,FB))&& + (( EQ_16(st_fx->last_extl, SWB_TBE) || EQ_16(st_fx->last_extl, FB_TBE) ) && EQ_16(st_fx->last_codec_mode, MODE2) ) ) + { + GenTransition_fx(hBWE_TD->syn_overlap_fx, hBWE_TD->old_tbe_synth_fx, 2*NS2SA(st_fx->output_Fs, DELAY_BWE_TOTAL_NS), hb_synth_fx, + hBWE_TD->genSHBsynth_Hilbert_Mem_fx, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx, + hBWE_TD->mem_resamp_HB_32k_fx, + &(hBWE_TD->syn_dm_phase_fx), st_fx->output_Fs, hBWE_TD->int_3_over_2_tbemem_dec_fx, st_fx->rf_flag, st_fx->total_brate ); + + hb_synth_fx_exp = st_fx->prev_Q_bwe_syn2; + move16(); + } + ELSE IF ( st_fx->bwidth == WB && st_fx->last_extl == WB_TBE ) + { + GenTransition_WB_fx(hBWE_TD->syn_overlap_fx, hBWE_TD->old_tbe_synth_fx, st_fx->prev_Qx, 2*NS2SA(st_fx->output_Fs, DELAY_BWE_TOTAL_NS), hb_synth_fx, + hBWE_TD->state_lsyn_filt_shb_fx, hBWE_TD->state_lsyn_filt_dwn_shb_fx, st_fx->output_Fs, hBWE_TD->mem_resamp_HB_fx ); + + hb_synth_fx_exp = st_fx->prev_Qx; + move16(); + } + + TBEreset_dec_fx( st_fx, st_fx->bwidth ); + } + ELSE IF ( EQ_16(st_fx->last_codec_mode,MODE1)) + { + swb_tbe_reset_fx(hBWE_TD->mem_csfilt_fx, hBWE_TD->mem_genSHBexc_filt_down_shb_fx, hBWE_TD->state_lpc_syn_fx, + hBWE_TD->syn_overlap_fx, hBWE_TD->state_syn_shbexc_fx, &(hBWE_TD->tbe_demph_fx), &(hBWE_TD->tbe_premph_fx), hBWE_TD->mem_stp_swb_fx, &(hBWE_TD->gain_prec_swb_fx) ); + IF( EQ_16(st_fx->extl, FB_TBE)) + { + set16_fx(hBWE_TD->fb_state_lpc_syn_fx, 0, LPC_SHB_ORDER ); + hBWE_TD->fb_tbe_demph_fx = 0; + fb_tbe_reset_synth_fx(hBWE_TD->fbbwe_hpf_mem_fx, hBWE_TD->fbbwe_hpf_mem_fx_Q,&hBWE_TD->prev_fbbwe_ratio_fx ); + } + swb_tbe_reset_synth_fx(hBWE_TD->genSHBsynth_Hilbert_Mem_fx, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx ); + } + } + } + } + + IF( NE_16(st_fx->m_frame_type,ACTIVE_FRAME)) + { + st_fx->extl = -1; + move16(); + st_fx->extl_brate = L_deposit_l(0); + } + + /* -------------------------------------------------------------- */ + /* APPLY POSTPROC */ + /* -------------------------------------------------------------- */ + + { + nab = s_min( st_fx->cldfbAna_fx->no_channels, st_fx->cldfbSyn_fx->no_channels ); + st_fx->cldfbSyn_fx->lsb = s_min(st_fx->cldfbAna_fx->no_channels, st_fx->cldfbSyn_fx->no_channels); + move16(); + st_fx->cldfbSyn_fx->usb = st_fx->cldfbSyn_fx->no_channels; + move16(); + st_fx->cldfbAna_fx->lsb = st_fx->cldfbAna_fx->no_channels; + move16(); + st_fx->cldfbAna_fx->usb = st_fx->cldfbAna_fx->no_channels; + move16(); + + test(); + test(); + test(); + test(); + IF ( st_fx->hFdCngDec_fx != NULL && (EQ_32(st_fx->sr_core,8000)||EQ_32(st_fx->sr_core, INT_FS_12k8)||EQ_32(st_fx->sr_core, INT_FS_16k))&&LE_32(st_fx->total_brate,ACELP_32k)) + { + /*************************************** + In CLDFB domain: + - perform noise estimation during active frames + - do CNG during inactive frames + ****************************************/ + HANDLE_FD_CNG_DEC hFdCngDec = st_fx->hFdCngDec_fx; + move16(); + noisy_speech_detection(st_fx->hFdCngDec_fx, st_fx->VAD && st_fx->m_frame_type == ACTIVE_FRAME, output_sp, 0); + + hFdCngDec->hFdCngCom->likelihood_noisy_speech = mult_r(hFdCngDec->hFdCngCom->likelihood_noisy_speech, 32440/*0.99 Q15*/); + IF ( hFdCngDec->hFdCngCom->flag_noisy_speech != 0 ) + { + hFdCngDec->hFdCngCom->likelihood_noisy_speech = add(hFdCngDec->hFdCngCom->likelihood_noisy_speech, 328/*0.01 Q15*/); + move16(); + } + st_fx->lp_noise = hFdCngDec->lp_noise; + move32(); +#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT + ApplyFdCng(output, NULL, realBuffer, imagBuffer, st, concealWholeFrame, 0); +#else + ApplyFdCng( output_sp, 0, realBuffer, imagBuffer, &st_fx->scaleFactor.hb_scale, st_fx, concealWholeFrame, 0); +#endif + /* Generate additional comfort noise to mask potential coding artefacts */ + test(); + IF( EQ_16(st_fx->m_frame_type,ACTIVE_FRAME)&&st_fx->flag_cna) + { + generate_masking_noise( output_sp, 0, hFdCngDec->hFdCngCom, hFdCngDec->hFdCngCom->frameSize, 0 ); + } + + } + + test(); + test(); + test(); + test(); + test(); + test(); + IF( st_fx->flag_cna == 0 && EQ_16(st_fx->L_frame,L_FRAME16k)&&EQ_16(st_fx->last_flag_cna,1) + && ( (st_fx->last_core == ACELP_CORE && NE_16(st_fx->last_coder_type_fx,AUDIO) ) || EQ_16(st_fx->last_core,TCX_20_CORE) || EQ_16(st_fx->last_core,AMR_WB_CORE) ) ) + { + FOR (i=0; i < st_fx->L_frame/2; i++) + { + output_sp[i] = add( output_sp[i], st_fx->hFdCngDec_fx->hFdCngCom->olapBufferSynth2[i+5*st_fx->L_frame/4] ); + move16(); + } + } + + IF( EQ_16(st_fx->m_frame_type,ACTIVE_FRAME)) + { + timeIn_e = s_max(0, sub(getScaleFactor16( output_sp, st_fx->L_frame ), 3)); + IF( NE_16(st_fx->core,ACELP_CORE)) + { + timeIn_e = s_max(0, s_min(sub(getScaleFactor16( pcmbufFB, hTcxDec->L_frameTCX ), 3),timeIn_e)); + } + Scale_sig( output_sp, st_fx->L_frame, timeIn_e ); + timeIn_e = negate( timeIn_e ); + cldfbAnalysisFiltering( st_fx->cldfbAna_fx, realBuffer, imagBuffer, &st_fx->scaleFactor, output_sp, timeIn_e, CLDFB_NO_COL_MAX, workBuffer ); + st_fx->scaleFactor.hb_scale = st_fx->scaleFactor.lb_scale; + move16(); + } + ELSE + { + Word16 timeDomainBuffer[L_FRAME16k]; + Word16 A[M+1]; + + Copy( st_fx->hFdCngDec_fx->hFdCngCom->timeDomainBuffer, timeDomainBuffer, st_fx->L_frame ); + Copy( st_fx->hFdCngDec_fx->hFdCngCom->A_cng, A, M+1 ); + + update_decoder_LPD_cng( st_fx, st_fx->coder_type_fx, timeDomainBuffer, A, st_fx->p_bpf_noise_buf ); + /* Generate additional comfort noise to mask potential coding artefacts */ + IF( st_fx->flag_cna ) + { + generate_masking_noise( timeDomainBuffer, 0, st_fx->hFdCngDec_fx->hFdCngCom, st_fx->hFdCngDec_fx->hFdCngCom->frameSize, 0 ); + } + ELSE IF( EQ_16(st_fx->L_frame,L_FRAME16k)&&EQ_16(st_fx->last_flag_cna,1)&&((EQ_16(st_fx->last_core,ACELP_CORE)&&NE_16(st_fx->last_coder_type_fx,AUDIO))||EQ_16(st_fx->last_core,TCX_20_CORE)||EQ_16(st_fx->last_core,AMR_WB_CORE))) + { + FOR( i=0; i < st_fx->L_frame/2; i++ ) + { + timeDomainBuffer[i] = add( timeDomainBuffer[i], st_fx->hFdCngDec_fx->hFdCngCom->olapBufferSynth2[i+5*st_fx->L_frame/4] ); + move16(); + } + } + /* check if the CLDFB works on the right sample rate */ + IF( NE_16((st_fx->cldfbAna_fx->no_channels * st_fx->cldfbAna_fx->no_col),st_fx->L_frame)) + { + Word16 newCldfbBands = CLDFB_getNumChannels(L_mult0(st_fx->L_frame, 50)); + + resampleCldfb( st_fx->cldfbAna_fx, newCldfbBands, st_fx->L_frame, 0 ); + resampleCldfb( st_fx->cldfbBPF_fx, newCldfbBands, st_fx->L_frame, 0 ); + } + + st_fx->cldfbSyn_fx->bandsToZero = 0; + move16(); + test(); + IF ( EQ_16( st_fx->bwidth, NB )&>_16(st_fx->cldfbSyn_fx->no_channels,10)) + { + st_fx->cldfbSyn_fx->bandsToZero = sub( st_fx->cldfbSyn_fx->no_channels, 10 ); + } + ELSE IF ( st_fx->hFdCngDec_fx->hFdCngCom->regularStopBand < st_fx->cldfbSyn_fx->no_channels ) + { + st_fx->cldfbSyn_fx->bandsToZero = st_fx->cldfbSyn_fx->no_channels - st_fx->hFdCngDec_fx->hFdCngCom->regularStopBand; + } + + timeIn_e = 2; + move16(); + Scale_sig(timeDomainBuffer, st_fx->L_frame, timeIn_e); + IF ( st_fx->p_bpf_noise_buf ) + { + Scale_sig(st_fx->p_bpf_noise_buf, st_fx->L_frame, timeIn_e); + } + + timeIn_e = negate(timeIn_e); + cldfbAnalysisFiltering( st_fx->cldfbAna_fx, realBuffer, imagBuffer, &st_fx->scaleFactor, timeDomainBuffer, timeIn_e, CLDFB_NO_COL_MAX, workBuffer) ; + } + + if( st_fx->flag_cna == 0 ) + { + set16_fx( st_fx->hFdCngDec_fx->hFdCngCom->olapBufferSynth2, 0, st_fx->hFdCngDec_fx->hFdCngCom->fftlen ); + } + + IF( st_fx->p_bpf_noise_buf ) + { + Word16 timeInBpf_e = timeIn_e; + move16(); + if( EQ_16(st_fx->m_frame_type,ACTIVE_FRAME)) + { + timeInBpf_e = 0; + move16(); + } + + addBassPostFilterFx( st_fx->p_bpf_noise_buf, realBuffer, imagBuffer, st_fx->cldfbBPF_fx, workBuffer, + timeInBpf_e, CLDFB_NO_COL_MAX, st_fx->cldfbAna_fx->no_col, st_fx->cldfbAna_fx->no_channels, &st_fx->scaleFactor ); + + IF( NE_16(st_fx->m_frame_type,ACTIVE_FRAME)) + { + Scale_sig(st_fx->p_bpf_noise_buf, st_fx->L_frame, timeIn_e); + } + + } + + IF (GT_32(st_fx->output_Fs, 8000)) + { + st_fx->hTECDec->cldfbExp = add(15, st_fx->scaleFactor.lb_scale); + + calcGainTemp_TBE_Fx( realBuffer, imagBuffer, st_fx->hTECDec->cldfbExp, st_fx->hTECDec->loBuffer, + 0, /*startPos,*//*!< Start position of the current envelope. */ + st_fx->cldfbAna_fx->no_col, /*stopPos,*/ /*!< Stop position of the current envelope. */ + st_fx->cldfbAna_fx->no_channels, /*lowSubband*/ + st_fx->hTECDec->pGainTemp_m, st_fx->hTECDec->pGainTemp_e, st_fx->tec_flag + ); + } + + /* set high band buffers to zero. Covering the current frame and the overlap area. */ + IF( EQ_16(st_fx->m_frame_type,ACTIVE_FRAME)) + { + FOR( i = 0; i < 16; i++ ) + { + set32_fx( &realBuffer[i][nab], 0, sub(st_fx->cldfbSyn_fx->no_channels,nab) ); + set32_fx( &imagBuffer[i][nab], 0, sub(st_fx->cldfbSyn_fx->no_channels,nab) ); + } + } + + timeIn_e = s_min(0, add(timeIn_e, 2)); + cldfbSynthesisFiltering(st_fx->cldfbSyn_fx, realBuffer, imagBuffer, &st_fx->scaleFactor, output_sp, timeIn_e, CLDFB_NO_COL_MAX, workBuffer ); + /*CLDFB output always in timeIn_e*/ + + /* MODE1 MDCT to ACELP 2 transition */ + delay_comp = NS2SA_fx2(st_fx->output_Fs, DELAY_CLDFB_NS); + Scale_sig(st_fx->delay_buf_out_fx, delay_comp, negate(hHQ_core->Q_old_postdec)); + hHQ_core->Q_old_postdec = 0; + move16(); + delay_tdbwe= NS2SA_fx2(st_fx->output_Fs, DELAY_BWE_TOTAL_NS- DELAY_CLDFB_NS); + IF( GE_16(output_frame,L_FRAME16k)) + { + Scale_sig(st_fx->prev_synth_buffer_fx, delay_tdbwe, sub(Qpostd, st_fx->Qprev_synth_buffer_fx)); + } + + test(); + IF( EQ_16(st_fx->last_codec_mode,MODE1)&>_16(st_fx->last_core_bfi,ACELP_CORE)) + { + Copy_Scale_sig( st_fx->delay_buf_out_fx, output_sp, delay_comp, negate(timeIn_e) ); /* copy the HQ/ACELP delay synchronization buffer at the beginning of ACELP frame */ + IF( EQ_16(st_fx->core,ACELP_CORE)) + { + Word16 step, alpha, nz; + + i = 15; + move16(); + tmps = NS2SA_fx2(st_fx->output_Fs, 3000000L); + nz = NS2SA_fx2(st_fx->output_Fs, N_ZERO_MDCT_NS); + step = Inv16(tmps, &i); + step = shl(step, i); + alpha = 0; + move16(); + + test(); + IF( st_fx->prev_bfi && hHQ_core->HqVoicing_fx ) + { + Copy(hHQ_core->fer_samples_fx, &hHQ_core->old_out_fx[nz], tmps); + } + ELSE + { + Scale_sig(hHQ_core->old_out_fx, nz+tmps, negate(hHQ_core->Q_old_wtda)); + } + hHQ_core->Q_old_wtda = 0; + move16(); + + FOR (i = 0; i < tmps; i++) + { + output_sp[i+delay_comp] = msu_r(L_mult(output_sp[i+delay_comp], alpha), shr(hHQ_core->old_out_fx[i+nz], timeIn_e), add(alpha, -32768)); + move16(); + alpha = add(alpha, step); + } + } + ELSE + { + IF( EQ_32(st_fx->output_Fs,8000)) + { + Copy(st_fx->delay_buf_out_fx, hTcxDec->FBTCXdelayBuf, delay_comp); + } + ELSE + { + Copy( st_fx->prev_synth_buffer_fx, hTcxDec->FBTCXdelayBuf, delay_tdbwe ); + Copy( st_fx->delay_buf_out_fx, hTcxDec->FBTCXdelayBuf + delay_tdbwe, delay_comp ); + } + } + } + + /* set delay compensation between HQ synthesis and ACELP synthesis */ + test(); + IF( EQ_16(st_fx->core,ACELP_CORE)&&!(st_fx->con_tcx)) + { + set16_fx( st_fx->delay_buf_out_fx, 0, delay_comp ); + Copy_Scale_sig( output_sp, st_fx->previoussynth_fx, output_frame, timeIn_e ); + } + ELSE + { + Copy(hTcxDec->old_synthFB_fx+ hTcxDec->old_synth_lenFB-delay_comp, st_fx->delay_buf_out_fx, delay_comp ); + IF( EQ_32(st_fx->output_Fs, 8000)) + { + Copy(hTcxDec->FBTCXdelayBuf, st_fx->previoussynth_fx, delay_comp); + } + ELSE + { + Copy(hTcxDec->FBTCXdelayBuf + delay_tdbwe, st_fx->previoussynth_fx, delay_comp ); + } + Copy(pcmbufFB, st_fx->previoussynth_fx + delay_comp, sub(output_frame, delay_comp)); + } + } + + /* Delay compensation for TD-BWE*/ + IF( GE_16(output_frame,L_FRAME16k)) + { + Copy( output_sp, tmp_buffer_fx, output_frame ); + Copy_Scale_sig( st_fx->prev_synth_buffer_fx, output_sp, delay_tdbwe, negate(timeIn_e) ); + Copy( tmp_buffer_fx, output_sp + delay_tdbwe, output_frame - delay_tdbwe ); + Copy_Scale_sig( tmp_buffer_fx + output_frame - delay_tdbwe, st_fx->prev_synth_buffer_fx, delay_tdbwe, timeIn_e); + } + + test(); + IF( st_fx->igf != 0 && EQ_16( st_fx->m_frame_type, ACTIVE_FRAME )) + { + test(); + test(); + test(); + test(); + IF( st_fx->bfi == 0 && EQ_16(st_fx->core, ACELP_CORE)&&(st_fx->tec_flag!=0||st_fx->tfa_flag!=0)&>_32(st_fx->output_Fs,8000) /*&& st_fx->hTECDec_fx != NULL*/) + { + tmp16 = 0; + move16(); + if (EQ_16(st_fx->tec_flag, 2)) + { + tmp16 = 1; + move16(); + } + + hb_synth_fx_exp = procTecTfa_TBE_Fx( hb_synth_fx, hb_synth_fx_exp, st_fx->hTECDec->pGainTemp_m, st_fx->hTECDec->pGainTemp_e, + st_fx->tfa_flag, st_fx->last_core, shr(output_frame, 4 ), tmp16 ); + } + + test(); + test(); + test(); + test(); + test(); + test(); + IF( (( ( st_fx->bfi == 0 || st_fx->last_core == ACELP_CORE ) && st_fx->core == ACELP_CORE ) || + ( ( EQ_16(st_fx->last_core, ACELP_CORE) ) && (NE_16(st_fx->bwidth, NB) && EQ_16(st_fx->last_codec_mode, MODE2) ) )) + && (GT_32( st_fx->output_Fs, 8000 ) ) ) + { + add_vec_fx( output_sp, negate(timeIn_e), hb_synth_fx, hb_synth_fx_exp, output_sp, negate(timeIn_e), output_frame ); + } + } + + + IF( EQ_32( st_fx->output_Fs, 8000 )) + { + tmps = NS2SA_fx2(st_fx->output_Fs, DELAY_CLDFB_NS ); + } + ELSE + { + tmps = NS2SA_fx2(st_fx->output_Fs, DELAY_BWE_TOTAL_NS ); + } + delta = NS2SA_fx2( st_fx->output_Fs, TCXLTP_DELAY_NS ); + + test(); + test(); + test(); + IF ( (st_fx->bfi && GT_16(st_fx->last_core, ACELP_CORE))||GT_16(st_fx->core,ACELP_CORE)) + { + test(); + test(); + test(); + test(); + IF ( GT_16(st_fx->last_core_bfi, ACELP_CORE)||(st_fx->bfi&&st_fx->last_core>ACELP_CORE)||(st_fx->prev_bfi&&st_fx->last_con_tcx)) + { + Copy_Scale_sig(hTcxDec->FBTCXdelayBuf, output_sp, tmps, negate(timeIn_e)); + Copy_Scale_sig(pcmbufFB, output_sp + tmps, sub(hTcxDec->L_frameTCX, tmps), negate(timeIn_e)); + } + ELSE + { + Word16 step, alpha; + + i = 15; + move16(); + step = Inv16(tmps, &i); + step = shl(step, i); + alpha = 0; + move16(); + + FOR (i = 0; i < tmps; i++) + { + output_sp[i+tmps] = msu_r(L_mult(shr(pcmbufFB[i], timeIn_e), alpha), output_sp[i+tmps], add(alpha, -32768)); + move16(); + alpha = add(alpha, step); + } + Copy_Scale_sig( pcmbufFB + tmps, output_sp + shl(tmps,1), sub(hTcxDec->L_frameTCX, shl(tmps,1)), negate(timeIn_e) ); + } + + Copy( pcmbufFB + hTcxDec->L_frameTCX - tmps, hTcxDec->FBTCXdelayBuf, tmps ); + + test(); + IF( st_fx->bfi && GT_16(st_fx->last_core, ACELP_CORE)) + { + IF( EQ_32(st_fx->output_Fs, 8000)) + { + Copy(hTcxDec->FBTCXdelayBuf, st_fx->delay_buf_out_fx, NS2SA(st_fx->output_Fs, DELAY_CLDFB_NS)); + } + ELSE + { + Copy(hTcxDec->FBTCXdelayBuf, st_fx->prev_synth_buffer_fx, NS2SA(st_fx->output_Fs, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS) ); + Copy(hTcxDec->FBTCXdelayBuf + NS2SA(st_fx->output_Fs, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS), st_fx->delay_buf_out_fx, NS2SA(st_fx->output_Fs, DELAY_CLDFB_NS) ); + } + } + } + ELSE IF( (EQ_16(st_fx->last_codec_mode,MODE2))&&(GT_16(st_fx->last_core,ACELP_CORE))) + { + Word16 step, alpha; + + Copy_Scale_sig(hTcxDec->FBTCXdelayBuf, output_sp, delta, negate(timeIn_e)); + + i = 15; + move16(); + step = Inv16(sub(tmps,delta), &i); + step = shl(step, i); + alpha = 0; + move16(); + + FOR (i = delta; i < tmps; i++) + { + output_sp[i] = msu_r(L_mult(output_sp[i], alpha), shr(hTcxDec->FBTCXdelayBuf[i], timeIn_e), add(alpha, -32768)); + move16(); +#ifdef BASOP_NOGLOB + alpha = add_sat(alpha, step); +#else + alpha = add(alpha, step); +#endif + } + } + + Scale_sig(hTcxLtpDec->tcxltp_mem_in, delta, sub(Qpostd, Qpostd_prev)); + Scale_sig(hTcxLtpDec->tcxltp_mem_out, output_frame, sub(Qpostd, Qpostd_prev)); + test(); + + Scale_sig( output_sp, output_frame, timeIn_e ); + + tcx_ltp_post(st_fx, hTcxLtpDec, st_fx->core, output_frame/*hTcxDec->L_frameTCX*/, NS2SA_fx2( st_fx->output_Fs, ACELP_LOOK_NS ) + tmps, + output_sp, hTcxDec->FBTCXdelayBuf); + Copy( output_sp, synth_fx, output_frame ); + + } /* end of MODE2 */ + + + /*----------------------------------------------------------------* + * Save synthesis for HQ FEC + *----------------------------------------------------------------*/ + //PMT("The code below could be move to save_synthesis_hq_fec") + post_hq_delay = NS2SA_fx2( st_fx->output_Fs, POST_HQ_DELAY_NS ); + IF (EQ_16(st_fx->codec_mode, MODE1)) + { + + Copy(hTcxDec->synth_history_fx+output_frame, hTcxDec->synth_history_fx, output_frame-post_hq_delay+NS2SA_fx2( st_fx->output_Fs, PH_ECU_MEM_NS )); + Copy_Scale_sig( synth_fx, hTcxDec->old_synthFB_fx+output_frame-post_hq_delay, output_frame,negate(Qpostd)); /* output_sp not initialized yet */ + /* reset the remaining buffer, which is read in TCX concealment the necessary samples to fill + this buffer are not available for all cases, the impact on the output is limited */ + set16_fx(hTcxDec->old_synthFB_fx+2*output_frame-post_hq_delay, 0, post_hq_delay ); + + IF( GE_16(output_frame, L_FRAME16k)) + { + + Copy_Scale_sig( st_fx->prev_synth_buffer_fx, hTcxDec->old_synthFB_fx+2*output_frame-NS2SA_fx2(st_fx->output_Fs, DELAY_BWE_TOTAL_NS), NS2SA_fx2(st_fx->output_Fs, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS),negate(st_fx->Qprev_synth_buffer_fx)); + } + IF( NE_16(st_fx->core,ACELP_CORE)) + { + IF( GE_16(output_frame, L_FRAME16k)) + { + + Copy_Scale_sig( synth_fx+output_frame, hTcxDec->old_synthFB_fx+2*output_frame-NS2SA_fx2(st_fx->output_Fs, DELAY_CLDFB_NS), NS2SA_fx2(st_fx->output_Fs, DELAY_CLDFB_NS),negate(Qpostd)); + Copy_Scale_sig(hHQ_core->old_out_fx+NS2SA_fx2(st_fx->output_Fs, N_ZERO_MDCT_NS), hTcxDec->old_synthFB_fx+2*output_frame, NS2SA_fx2(st_fx->output_Fs, PH_ECU_LOOKAHEAD_NS), negate(hHQ_core->Q_old_wtda)); + } + ELSE + { + + Copy_Scale_sig( synth_fx+output_frame, hTcxDec->old_synthFB_fx+2*output_frame-NS2SA_fx2(st_fx->output_Fs, DELAY_BWE_TOTAL_NS), NS2SA_fx2(st_fx->output_Fs, DELAY_CLDFB_NS),negate(Qpostd)); + Copy_Scale_sig(hHQ_core->old_out_fx+NS2SA_fx2(st_fx->output_Fs, N_ZERO_MDCT_NS), hTcxDec->old_synthFB_fx+2*output_frame-NS2SA_fx2(st_fx->output_Fs, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS), NS2SA_fx2(st_fx->output_Fs, PH_ECU_LOOKAHEAD_NS), negate(hHQ_core->Q_old_wtda)); + } + } + } + /*----------------------------------------------------------------* + * HP filtering + *----------------------------------------------------------------*/ + + st_fx->Qprev_synth_buffer_fx=Qpostd; + move16(); + Scale_sig32(st_fx->L_mem_hp_out_fx, 4, sub(Qpostd, Qpostd_prev)); + hp20(synth_fx, 1/*stride*/, output_frame, st_fx->L_mem_hp_out_fx, L_mult0(output_frame, 50)); + + /*----------------------------------------------------------------* + * Synthesis output + *----------------------------------------------------------------*/ + + IF( EQ_16(st_fx->codec_mode,MODE1)) + { + /* final output of synthesis signal */ + syn_output_fx( st_fx->codec_mode, synth_fx, output_frame, output_sp, Qpostd ); + } + ELSE + { + Copy( synth_fx, output_sp, output_frame ); + } + + /*--------------------------------------------------------* + * Updates + *--------------------------------------------------------*/ + + test(); + IF( st_fx->last_is_cng == 0 && EQ_16(st_fx->codec_mode,MODE2)) + { + st_fx->bfi = 0; + move16(); + IF( st_fx->use_partial_copy && GE_16(st_fx->rf_frame_type, RF_TCXFD)&&LE_16(st_fx->rf_frame_type,RF_TCXTD2)) + { + if( EQ_16(frameMode, FRAMEMODE_MISSING)) + { + st_fx->bfi = 1; + move16(); + } + } + ELSE IF( EQ_16(st_fx->m_decodeMode, DEC_CONCEALMENT_EXT)) + { + st_fx->bfi = 1; + move16(); + } + updt_dec_common_fx( st_fx, -1, concealWholeFrameTmp, output_sp, Qpostd); + } + ELSE + { + if( EQ_16(st_fx->codec_mode,MODE2)) + { + st_fx->bfi = 0; + move16(); + } + updt_dec_common_fx( st_fx, hq_core_type, concealWholeFrameTmp, output_sp, Qpostd); + } + return IVAS_ERR_OK; + +} diff --git a/lib_dec/fd_cng_dec.c b/lib_dec/fd_cng_dec.c index 69cd79471821728e7dc4f17662f4927c3a60be2f..5bb24d72736b3f61659942cf9e4b159677828722 100644 --- a/lib_dec/fd_cng_dec.c +++ b/lib_dec/fd_cng_dec.c @@ -60,16 +60,16 @@ * Local fucntions declarations *-------------------------------------------------------------------*/ -static void perform_noise_estimation_dec( const float *timeDomainInput, float *power_spectrum, HANDLE_FD_CNG_DEC hFdCngDec, const int16_t element_mode, const int16_t bwidth, const int16_t L_frame, const int16_t last_L_frame, const int32_t last_core_brate, const int16_t VAD ); +static void perform_noise_estimation_dec_flt( const float *timeDomainInput, float *power_spectrum, HANDLE_FD_CNG_DEC hFdCngDec, const int16_t element_mode, const int16_t bwidth, const int16_t L_frame, const int16_t last_L_frame, const int32_t last_core_brate, const int16_t VAD ); /*------------------------------------------------------------------- - * createFdCngDec() + * createFdCngDec_flt() * * Create an instance of type FD_CNG *-------------------------------------------------------------------*/ -ivas_error createFdCngDec( +ivas_error createFdCngDec_flt( HANDLE_FD_CNG_DEC *hFdCngDec ) { HANDLE_FD_CNG_DEC hs; @@ -85,7 +85,7 @@ ivas_error createFdCngDec( return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for FD CNG DEC structure" ); } - if ( ( error = createFdCngCom( &( hs->hFdCngCom ) ) ) != IVAS_ERR_OK ) + if ( ( error = createFdCngCom_flt( &( hs->hFdCngCom ) ) ) != IVAS_ERR_OK ) { return error; } @@ -97,12 +97,12 @@ ivas_error createFdCngDec( /*------------------------------------------------------------------- - * initFdCngDec() + * initFdCngDec_flt() * * Initialize an instance of type FD_CNG *-------------------------------------------------------------------*/ -void initFdCngDec( +void initFdCngDec_flt( DEC_CORE_HANDLE st /* i/o: decoder state structure */ ) { @@ -111,7 +111,7 @@ void initFdCngDec( hFdCngDec = st->hFdCngDec; /* Initialize common */ - initFdCngCom( hFdCngDec->hFdCngCom, st->cldfbSyn->scale_flt ); + initFdCngCom_flt( hFdCngDec->hFdCngCom, st->cldfbSyn->scale_flt ); /* Set some counters and flags */ hFdCngDec->flag_dtx_mode = 0; @@ -143,7 +143,7 @@ void initFdCngDec( set_f( hFdCngDec->psize_shaping_float, 0.0f, NPART_SHAPING ); hFdCngDec->nFFTpart_shaping = 0; - set_f( hFdCngDec->hFdCngCom->sidNoiseEstLp, 0.0f, NPART ); + set_f( hFdCngDec->hFdCngCom->sidNoiseEstLp_flt, 0.0f, NPART ); set_f( hFdCngDec->smoothed_psd, 0.0f, L_FRAME16k ); set_f( hFdCngDec->msPeriodog_ST, 0.0f, NPART_SHAPING ); @@ -171,12 +171,12 @@ void initFdCngDec( /*------------------------------------------------------------------- - * configureFdCngDec() + * configureFdCngDec_flt() * * Configure an instance of type FD_CNG *-------------------------------------------------------------------*/ -void configureFdCngDec( +void configureFdCngDec_flt( HANDLE_FD_CNG_DEC hFdCngDec, /* i/o: Contains the variables related to the FD-based CNG process */ const int16_t bwidth, const int32_t total_brate, @@ -290,7 +290,7 @@ void configureFdCngDec( hsCom->startBand = 2; hsCom->stopBand = hsCom->FdCngSetup.sidPartitions[hsCom->FdCngSetup.numPartitions - 1] + 1; - initPartitions( hsCom->FdCngSetup.sidPartitions, hsCom->FdCngSetup.numPartitions, hsCom->startBand, hsCom->stopBand, hsCom->part, &hsCom->npart, hsCom->midband, hsCom->psize, hsCom->psize_inv, 0 ); + initPartitions_flt( hsCom->FdCngSetup.sidPartitions, hsCom->FdCngSetup.numPartitions, hsCom->startBand, hsCom->stopBand, hsCom->part, &hsCom->npart, hsCom->midband, hsCom->psize_flt, hsCom->psize_inv_flt, 0 ); if ( hsCom->stopFFTbin == 160 ) { hsCom->nFFTpart = 17; @@ -307,7 +307,7 @@ void configureFdCngDec( for ( j = 0; j < hsCom->nCLDFBpart; j++ ) { hsCom->CLDFBpart[j] = hsCom->part[j + hsCom->nFFTpart] - ( hsCom->stopFFTbin - hsCom->startBand ); - hsCom->CLDFBpsize_inv[j] = hsCom->psize_inv[j + hsCom->nFFTpart]; + hsCom->CLDFBpsize_inv_flt[j] = hsCom->psize_inv_flt[j + hsCom->nFFTpart]; } stopBandFR = (int16_t) floor( 1000.f /*Hz*/ / 25.f /*Hz/Bin*/ ); @@ -315,21 +315,21 @@ void configureFdCngDec( { stopBandFR = hsCom->stopFFTbin; } - initPartitions( hsCom->FdCngSetup.shapingPartitions, hsCom->FdCngSetup.numShapingPartitions, hsCom->startBand, hsCom->stopFFTbin, hFdCngDec->part_shaping, &hFdCngDec->npart_shaping, hFdCngDec->midband_shaping, hFdCngDec->psize_shaping_float, hFdCngDec->psize_inv_shaping_float, stopBandFR ); + initPartitions_flt( hsCom->FdCngSetup.shapingPartitions, hsCom->FdCngSetup.numShapingPartitions, hsCom->startBand, hsCom->stopFFTbin, hFdCngDec->part_shaping, &hFdCngDec->npart_shaping, hFdCngDec->midband_shaping, hFdCngDec->psize_shaping_float, hFdCngDec->psize_inv_shaping_float, stopBandFR ); hFdCngDec->nFFTpart_shaping = hFdCngDec->npart_shaping; switch ( hsCom->fftlen ) { case 512: - hsCom->fftSineTab = NULL; - hsCom->olapWinAna = olapWinAna512; - hsCom->olapWinSyn = olapWinSyn256; + hsCom->fftSineTab_flt = NULL; + hsCom->olapWinAna_flt = olapWinAna512; + hsCom->olapWinSyn_flt = olapWinSyn256; break; case 640: - hsCom->fftSineTab = fftSineTab640; - hsCom->olapWinAna = olapWinAna640; - hsCom->olapWinSyn = olapWinSyn320; + hsCom->fftSineTab_flt = fftSineTab640; + hsCom->olapWinAna_flt = olapWinAna640; + hsCom->olapWinSyn_flt = olapWinSyn320; break; default: assert( !"Unsupported FFT length for FD-based CNG" ); @@ -342,19 +342,19 @@ void configureFdCngDec( /*------------------------------------------------------------------- - * deleteFdCngDec() + * deleteFdCngDec_flt() * * Delete the instance of type FD_CNG *-------------------------------------------------------------------*/ -void deleteFdCngDec( +void deleteFdCngDec_flt( HANDLE_FD_CNG_DEC *hFdCngDec ) { HANDLE_FD_CNG_DEC hsDec = *hFdCngDec; if ( hsDec != NULL ) { - deleteFdCngCom( &( hsDec->hFdCngCom ) ); + deleteFdCngCom_flt( &( hsDec->hFdCngCom ) ); free( hsDec ); *hFdCngDec = NULL; } @@ -364,12 +364,12 @@ void deleteFdCngDec( /*------------------------------------------------------------------- - * ApplyFdCng() + * ApplyFdCng_flt() * * Apply the CLDFB-based CNG at the decoder *-------------------------------------------------------------------*/ -void ApplyFdCng( +void ApplyFdCng_flt( float *timeDomainInput, float *powerSpectrum, float **realBuffer, /* i/o: Real part of the buffer */ @@ -380,15 +380,15 @@ void ApplyFdCng( { HANDLE_FD_CNG_DEC hFdCngDec = st->hFdCngDec; HANDLE_FD_CNG_COM hFdCngCom = hFdCngDec->hFdCngCom; - float *cngNoiseLevel = hFdCngCom->cngNoiseLevel; - float *sidNoiseEst = hFdCngCom->sidNoiseEst; + float *cngNoiseLevel_flt = hFdCngCom->cngNoiseLevel_flt; + float *sidNoiseEst_flt = hFdCngCom->sidNoiseEst_flt; int16_t j, k; float factor; float lsp_cng[M]; int16_t L_frame, last_L_frame; int32_t sr_core; - push_wmops( "ApplyFdCng" ); + push_wmops( "ApplyFdCng_flt" ); /* limit L_frame and core Fs values for MDCT-Stereo modes which can have higher core sampling than 16kHz, but use a downsampled buffer */ L_frame = min( st->L_frame, L_FRAME16k ); @@ -428,26 +428,26 @@ void ApplyFdCng( ( !st->BER_detect ) ) { /* Perform noise estimation at the decoder */ - perform_noise_estimation_dec( timeDomainInput, powerSpectrum, hFdCngDec, st->element_mode, st->bwidth, L_frame, last_L_frame, st->last_core_brate, st->VAD ); + perform_noise_estimation_dec_flt( timeDomainInput, powerSpectrum, hFdCngDec, st->element_mode, st->bwidth, L_frame, last_L_frame, st->last_core_brate, st->VAD ); if ( st->element_mode != IVAS_CPE_TD && st->element_mode != IVAS_CPE_DFT ) { /* Update the shaping parameters */ - scalebands( hFdCngDec->msNoiseEst_float, hFdCngDec->part_shaping, hFdCngDec->nFFTpart_shaping, hFdCngDec->midband_shaping, hFdCngDec->nFFTpart_shaping, hFdCngCom->stopFFTbin - hFdCngCom->startBand, hFdCngDec->bandNoiseShape_float, 1 ); + scalebands_flt( hFdCngDec->msNoiseEst_float, hFdCngDec->part_shaping, hFdCngDec->nFFTpart_shaping, hFdCngDec->midband_shaping, hFdCngDec->nFFTpart_shaping, hFdCngCom->stopFFTbin - hFdCngCom->startBand, hFdCngDec->bandNoiseShape_float, 1 ); } /* Update CNG levels */ if ( hFdCngDec->flag_dtx_mode && st->cng_type == FD_CNG ) { - bandcombinepow( hFdCngDec->bandNoiseShape_float, hFdCngCom->stopFFTbin - hFdCngCom->startBand, hFdCngCom->part, hFdCngCom->nFFTpart, hFdCngCom->psize_inv, hFdCngDec->partNoiseShape_float); /* This needs to be done only once per inactive phase */ + bandcombinepow_flt( hFdCngDec->bandNoiseShape_float, hFdCngCom->stopFFTbin - hFdCngCom->startBand, hFdCngCom->part, hFdCngCom->nFFTpart, hFdCngCom->psize_inv_flt, hFdCngDec->partNoiseShape_float); /* This needs to be done only once per inactive phase */ j = 0; for ( k = 0; k < hFdCngCom->nFFTpart; k++ ) { - factor = ( hFdCngCom->sidNoiseEst[k] + DELTA ) / ( hFdCngDec->partNoiseShape_float[k] + DELTA ); + factor = ( hFdCngCom->sidNoiseEst_flt[k] + DELTA ) / ( hFdCngDec->partNoiseShape_float[k] + DELTA ); for ( ; j <= hFdCngCom->part[k]; j++ ) { - cngNoiseLevel[j] = hFdCngDec->bandNoiseShape_float[j] * factor; + cngNoiseLevel_flt[j] = hFdCngDec->bandNoiseShape_float[j] * factor; } } } @@ -456,26 +456,26 @@ void ApplyFdCng( /* This sets the new CNG levels until a SID update overwrites it */ if ( !( st->element_mode == IVAS_CPE_TD ) || ( st->element_mode == IVAS_CPE_TD && !hFdCngDec->flag_dtx_mode && !st->VAD ) ) { - mvr2r( hFdCngDec->bandNoiseShape_float, cngNoiseLevel, hFdCngCom->stopFFTbin - hFdCngCom->startBand ); /* This sets the new CNG levels until a SID update overwrites it */ + mvr2r( hFdCngDec->bandNoiseShape_float, cngNoiseLevel_flt, hFdCngCom->stopFFTbin - hFdCngCom->startBand ); /* This sets the new CNG levels until a SID update overwrites it */ } } if ( st->element_mode == IVAS_CPE_MDCT && timeDomainInput == NULL ) { - st->hTcxDec->CngLevelBackgroundTrace_bfi = sqrtf( sum_f( cngNoiseLevel, hFdCngCom->stopFFTbin - hFdCngCom->startBand ) / NORM_MDCT_FACTOR ); + st->hTcxDec->CngLevelBackgroundTrace_bfi = sqrtf( sum_f( cngNoiseLevel_flt, hFdCngCom->stopFFTbin - hFdCngCom->startBand ) / NORM_MDCT_FACTOR ); } else { - st->hTcxDec->CngLevelBackgroundTrace_bfi = (float) sqrt( ( sum_f( cngNoiseLevel, hFdCngCom->stopFFTbin - hFdCngCom->startBand ) / 2 * hFdCngCom->fftlen ) / L_frame ); + st->hTcxDec->CngLevelBackgroundTrace_bfi = (float) sqrt( ( sum_f( cngNoiseLevel_flt, hFdCngCom->stopFFTbin - hFdCngCom->startBand ) / 2 * hFdCngCom->fftlen ) / L_frame ); } - st->cngTDLevel_float = (float) sqrt( ( sum_f( cngNoiseLevel, hFdCngCom->stopFFTbin - hFdCngCom->startBand ) / 2 * hFdCngCom->fftlen ) / st->L_frame ); + st->cngTDLevel_float = (float) sqrt( ( sum_f( cngNoiseLevel_flt, hFdCngCom->stopFFTbin - hFdCngCom->startBand ) / 2 * hFdCngCom->fftlen ) / st->L_frame ); } else if ( st->element_mode == IVAS_CPE_TD || st->element_mode == IVAS_CPE_DFT ) { if ( hFdCngCom->active_frame_counter > 0 ) { /* Perform noise estimation in active frames in the decoder for downward updates */ - perform_noise_estimation_dec( timeDomainInput, powerSpectrum, hFdCngDec, st->element_mode, st->bwidth, L_frame, last_L_frame, st->last_core_brate, st->VAD ); + perform_noise_estimation_dec_flt( timeDomainInput, powerSpectrum, hFdCngDec, st->element_mode, st->bwidth, L_frame, last_L_frame, st->last_core_brate, st->VAD ); } } @@ -490,16 +490,16 @@ void ApplyFdCng( } /* ... but do actual computations only if sufficient energy in noise shape */ - if ( sum_f( cngNoiseLevel + hFdCngCom->startBand, hFdCngCom->stopFFTbin - hFdCngCom->startBand ) > 0.01f ) + if ( sum_f( cngNoiseLevel_flt + hFdCngCom->startBand, hFdCngCom->stopFFTbin - hFdCngCom->startBand ) > 0.01f ) { if ( st->element_mode == IVAS_CPE_MDCT && st->core != ACELP_CORE ) { - TonalMdctConceal_whiten_noise_shape( st, L_frame, ON_FIRST_LOST_FRAME ); + TonalMdctConceal_whiten_noise_shape_ivas( st, L_frame, ON_FIRST_LOST_FRAME ); } else if ( st->element_mode != IVAS_CPE_MDCT || st->core == ACELP_CORE ) { - lpc_from_spectrum( hFdCngCom, hFdCngCom->startBand, hFdCngCom->stopFFTbin, 0.f ); - a2lsp_stab( hFdCngCom->A_cng, lsp_cng, st->lspold_cng_float); + lpc_from_spectrum_flt( hFdCngCom, hFdCngCom->startBand, hFdCngCom->stopFFTbin, 0.f ); + a2lsp_stab( hFdCngCom->A_cng_flt, lsp_cng, st->lspold_cng_float); mvr2r( lsp_cng, st->lspold_cng_float, M ); lsp2lsf( lsp_cng, st->lsf_cng_float, M, sr_core ); } @@ -517,18 +517,18 @@ void ApplyFdCng( if ( st != NULL && st->cng_type == LP_CNG ) { /* Perform noise estimation on inactive phase at the decoder */ - perform_noise_estimation_dec( timeDomainInput, powerSpectrum, hFdCngDec, st->element_mode, st->bwidth, L_frame, last_L_frame, st->last_core_brate, st->VAD ); + perform_noise_estimation_dec_flt( timeDomainInput, powerSpectrum, hFdCngDec, st->element_mode, st->bwidth, L_frame, last_L_frame, st->last_core_brate, st->VAD ); if ( st->element_mode != IVAS_CPE_TD && st->element_mode != IVAS_CPE_DFT ) { /* Update the shaping parameters */ - scalebands( hFdCngDec->msNoiseEst_float, hFdCngDec->part_shaping, hFdCngDec->nFFTpart_shaping, hFdCngDec->midband_shaping, hFdCngDec->nFFTpart_shaping, hFdCngCom->stopFFTbin - hFdCngCom->startBand, hFdCngDec->bandNoiseShape_float, 1 ); + scalebands_flt( hFdCngDec->msNoiseEst_float, hFdCngDec->part_shaping, hFdCngDec->nFFTpart_shaping, hFdCngDec->midband_shaping, hFdCngDec->nFFTpart_shaping, hFdCngCom->stopFFTbin - hFdCngCom->startBand, hFdCngDec->bandNoiseShape_float, 1 ); } /* This sets the new CNG levels until a SID update overwrites it */ - mvr2r( hFdCngDec->bandNoiseShape_float, cngNoiseLevel, hFdCngCom->stopFFTbin - hFdCngCom->startBand ); /* This sets the new CNG levels until a SID update overwrites it */ + mvr2r( hFdCngDec->bandNoiseShape_float, cngNoiseLevel_flt, hFdCngCom->stopFFTbin - hFdCngCom->startBand ); /* This sets the new CNG levels until a SID update overwrites it */ - st->cngTDLevel_float = (float) sqrt( ( sum_f( cngNoiseLevel, hFdCngCom->stopFFTbin - hFdCngCom->startBand ) / 2 * hFdCngCom->fftlen ) / L_frame ); + st->cngTDLevel_float = (float) sqrt( ( sum_f( cngNoiseLevel_flt, hFdCngCom->stopFFTbin - hFdCngCom->startBand ) / 2 * hFdCngCom->fftlen ) / L_frame ); break; } @@ -542,11 +542,11 @@ void ApplyFdCng( if ( hFdCngCom->inactive_frame_counter == 1 ) { /* Compute the fine spectral structure of the comfort noise shape using the decoder-side noise estimates */ - bandcombinepow( hFdCngDec->bandNoiseShape_float, hFdCngCom->stopFFTbin - hFdCngCom->startBand, hFdCngCom->part, hFdCngCom->nFFTpart, hFdCngCom->psize_inv, hFdCngDec->partNoiseShape_float); + bandcombinepow_flt( hFdCngDec->bandNoiseShape_float, hFdCngCom->stopFFTbin - hFdCngCom->startBand, hFdCngCom->part, hFdCngCom->nFFTpart, hFdCngCom->psize_inv_flt, hFdCngDec->partNoiseShape_float); if ( st->element_mode == IVAS_CPE_DFT ) { - mvr2r( st->hFdCngDec->hFdCngCom->sidNoiseEst, st->hFdCngDec->hFdCngCom->sidNoiseEstLp, NPART ); + mvr2r( st->hFdCngDec->hFdCngCom->sidNoiseEst_flt, st->hFdCngDec->hFdCngCom->sidNoiseEstLp_flt, NPART ); } } @@ -555,19 +555,19 @@ void ApplyFdCng( if ( hFdCngCom->msFrCnt_init_counter < hFdCngCom->msFrCnt_init_thresh ) { /* At initialization, interpolate the bin/band-wise levels from the partition levels */ - scalebands( sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, hFdCngCom->stopBand - hFdCngCom->startBand, cngNoiseLevel, 1 ); + scalebands_flt( sidNoiseEst_flt, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, hFdCngCom->stopBand - hFdCngCom->startBand, cngNoiseLevel_flt, 1 ); } else { if ( st->element_mode == IVAS_CPE_DFT ) { - sidNoiseEst = hFdCngCom->sidNoiseEstLp; + sidNoiseEst_flt = hFdCngCom->sidNoiseEstLp_flt; } /* Interpolate the CLDFB band levels from the SID (partition) levels */ if ( hFdCngCom->regularStopBand > hFdCngCom->numCoreBands ) { - scalebands( sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, hFdCngCom->stopBand - hFdCngCom->startBand, cngNoiseLevel, 0 ); + scalebands_flt( sidNoiseEst_flt, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, hFdCngCom->stopBand - hFdCngCom->startBand, cngNoiseLevel_flt, 0 ); } @@ -575,10 +575,10 @@ void ApplyFdCng( j = 0; for ( k = 0; k < hFdCngCom->nFFTpart; k++ ) { - factor = ( sidNoiseEst[k] + DELTA ) / ( hFdCngDec->partNoiseShape_float[k] + DELTA ); + factor = ( sidNoiseEst_flt[k] + DELTA ) / ( hFdCngDec->partNoiseShape_float[k] + DELTA ); for ( ; j <= hFdCngCom->part[k]; j++ ) { - cngNoiseLevel[j] = hFdCngDec->bandNoiseShape_float[j] * factor; + cngNoiseLevel_flt[j] = hFdCngDec->bandNoiseShape_float[j] * factor; } } } @@ -587,14 +587,14 @@ void ApplyFdCng( { if ( !( hFdCngCom->msFrCnt_init_counter < hFdCngCom->msFrCnt_init_thresh ) ) { - sidNoiseEst = hFdCngCom->sidNoiseEstLp; + sidNoiseEst_flt = hFdCngCom->sidNoiseEstLp_flt; j = 0; for ( k = 0; k < hFdCngCom->nFFTpart; k++ ) { - factor = ( sidNoiseEst[k] + DELTA ) / ( hFdCngDec->partNoiseShape_float[k] + DELTA ); + factor = ( sidNoiseEst_flt[k] + DELTA ) / ( hFdCngDec->partNoiseShape_float[k] + DELTA ); for ( ; j <= hFdCngCom->part[k]; j++ ) { - cngNoiseLevel[j] = hFdCngDec->bandNoiseShape_float[j] * factor; + cngNoiseLevel_flt[j] = hFdCngDec->bandNoiseShape_float[j] * factor; } } } @@ -602,7 +602,7 @@ void ApplyFdCng( if ( st->codec_mode == MODE2 ) { /* Generate comfort noise during SID or zero frames */ - generate_comfort_noise_dec( realBuffer, imagBuffer, st, -1 ); + generate_comfort_noise_dec_flt( realBuffer, imagBuffer, st, -1 ); } break; @@ -618,12 +618,12 @@ void ApplyFdCng( /*------------------------------------------------------------------- - * perform_noise_estimation_dec() + * perform_noise_estimation_dec_flt() * * Perform noise estimation at the decoder *-------------------------------------------------------------------*/ -static void perform_noise_estimation_dec( +static void perform_noise_estimation_dec_flt( const float *timeDomainInput, float *power_spectrum, HANDLE_FD_CNG_DEC hFdCngDec, /* i/o: FD_CNG structure containing all buffers and variables */ @@ -639,17 +639,17 @@ static void perform_noise_estimation_dec( float *ptr_i; int16_t startBand = hFdCngDec->hFdCngCom->startBand; int16_t stopFFTbin = hFdCngDec->hFdCngCom->stopFFTbin; - float *fftBuffer = hFdCngDec->hFdCngCom->fftBuffer; - float *periodog = hFdCngDec->hFdCngCom->periodog; - float *ptr_per = periodog; + float *fftBuffer = hFdCngDec->hFdCngCom->fftBuffer_flt; + float *periodog_flt = hFdCngDec->hFdCngCom->periodog_flt; + float *ptr_per = periodog_flt; float *msPeriodog = hFdCngDec->msPeriodog_float; float *msNoiseEst = hFdCngDec->msNoiseEst_float; int16_t *part = hFdCngDec->part_shaping; int16_t npart = hFdCngDec->npart_shaping; int16_t nFFTpart = hFdCngDec->nFFTpart_shaping; - float *psize_inv = hFdCngDec->psize_inv_shaping_float; - float *psize = hFdCngDec->psize_shaping_float; + float *psize_inv_flt = hFdCngDec->psize_inv_shaping_float; + float *psize_flt = hFdCngDec->psize_shaping_float; float *msLogPeriodog = hFdCngDec->msLogPeriodog_float; float *msLogNoiseEst = hFdCngDec->msLogNoiseEst_float; int16_t i; @@ -661,7 +661,7 @@ static void perform_noise_estimation_dec( if ( !( element_mode == IVAS_CPE_MDCT && power_spectrum != NULL ) ) { /* Perform STFT analysis */ - AnalysisSTFT( timeDomainInput, fftBuffer, hFdCngDec->hFdCngCom ); + AnalysisSTFT_flt( timeDomainInput, fftBuffer, hFdCngDec->hFdCngCom ); } if ( element_mode == IVAS_CPE_TD || element_mode == IVAS_CPE_DFT ) @@ -680,7 +680,7 @@ static void perform_noise_estimation_dec( ptr_i = ptr_r + 1; - for ( ; ptr_per < periodog + stopFFTbin - startBand; ptr_per++ ) + for ( ; ptr_per < periodog_flt + stopFFTbin - startBand; ptr_per++ ) { ( *ptr_per ) = ( *ptr_r ) * ( *ptr_r ) + ( *ptr_i ) * ( *ptr_i ); ptr_r += 2; @@ -688,7 +688,7 @@ static void perform_noise_estimation_dec( } /* Rescale to get energy/sample: it should be 2*(1/N)*(2/N), parseval relation with 1/N,*2 for nrg computed till Nyquist only, 2/N as windowed samples correspond to half a frame*/ - v_multc( periodog, 4.f / (float) ( hFdCngDec->hFdCngCom->fftlen * hFdCngDec->hFdCngCom->fftlen ), periodog, stopFFTbin - startBand ); + v_multc( periodog_flt, 4.f / (float) ( hFdCngDec->hFdCngCom->fftlen * hFdCngDec->hFdCngCom->fftlen ), periodog_flt, stopFFTbin - startBand ); /* Combine bins of power spectrum into partitions */ i = 0; @@ -699,9 +699,9 @@ static void perform_noise_estimation_dec( temp = 0; for ( ; i <= part[p]; i++ ) { - temp += periodog[i]; + temp += periodog_flt[i]; } - msPeriodog[p] = temp * psize_inv[p]; + msPeriodog[p] = temp * psize_inv_flt[p]; } /* compensate for the loss of variance - don't do when first noise update is not completed yet due to risk of msPeriodog[p] < 0 */ @@ -714,13 +714,13 @@ static void perform_noise_estimation_dec( temp = 0; for ( ; i <= part[p]; i++ ) { - delta = periodog[i] - msPeriodog[p]; + delta = periodog_flt[i] - msPeriodog[p]; temp += delta * delta; } - temp *= psize_inv[p]; + temp *= psize_inv_flt[p]; /* compensate for the loss of variance */ - msPeriodog[p] = (float) ( msPeriodog[p] + sqrt( temp ) * rand_gauss( &ftemp, &hFdCngDec->cna_seed ) ); + msPeriodog[p] = (float) ( msPeriodog[p] + sqrt( temp ) * rand_gauss_flt( &ftemp, &hFdCngDec->cna_seed ) ); if ( msPeriodog[p] < 1e-5f ) { @@ -888,7 +888,7 @@ static void perform_noise_estimation_dec( mvr2r( msNoiseEst, hFdCngDec->msPsd_float, npart ); /* Expand partitions into bins of power spectrum */ - scalebands( msNoiseEst, part, nFFTpart, hFdCngDec->midband_shaping, nFFTpart, stopFFTbin - startBand, hFdCngDec->bandNoiseShape_float, 1 ); + scalebands_flt( msNoiseEst, part, nFFTpart, hFdCngDec->midband_shaping, nFFTpart, stopFFTbin - startBand, hFdCngDec->bandNoiseShape_float, 1 ); mvr2r( hFdCngDec->bandNoiseShape_float, &hFdCngDec->smoothed_psd[startBand], stopFFTbin - startBand ); set_zero( &hFdCngDec->smoothed_psd[stopFFTbin], L_FRAME16k - stopFFTbin ); @@ -898,7 +898,7 @@ static void perform_noise_estimation_dec( if ( element_mode == IVAS_CPE_MDCT && power_spectrum != NULL ) { /* use power spectrum calculated in the MDCT-domain instead of calculating new power spectrum */ - periodog = power_spectrum; + periodog_flt = power_spectrum; } else { @@ -916,7 +916,7 @@ static void perform_noise_estimation_dec( ptr_i = ptr_r + 1; - for ( ; ptr_per < periodog + stopFFTbin - startBand; ptr_per++ ) + for ( ; ptr_per < periodog_flt + stopFFTbin - startBand; ptr_per++ ) { ( *ptr_per ) = ( *ptr_r ) * ( *ptr_r ) + ( *ptr_i ) * ( *ptr_i ); ptr_r += 2; @@ -925,21 +925,21 @@ static void perform_noise_estimation_dec( /* Nyquist frequency is discarded */ /* Rescale to get energy/sample: it should be 2*(1/N)*(2/N), parseval relation with 1/N,*2 for nrg computed till Nyquist only, 2/N as windowed samples correspond to half a frame*/ - v_multc( periodog, 4.f / (float) ( hFdCngDec->hFdCngCom->fftlen * hFdCngDec->hFdCngCom->fftlen ), periodog, stopFFTbin - startBand ); + v_multc( periodog_flt, 4.f / (float) ( hFdCngDec->hFdCngCom->fftlen * hFdCngDec->hFdCngCom->fftlen ), periodog_flt, stopFFTbin - startBand ); } /* Adjust to the desired frequency resolution by averaging over spectral partitions for SID transmission */ - bandcombinepow( periodog, stopFFTbin - startBand, part, npart, psize_inv, msPeriodog ); + bandcombinepow_flt( periodog_flt, stopFFTbin - startBand, part, npart, psize_inv_flt, msPeriodog ); /* Compress MS inputs */ - compress_range( msPeriodog, msLogPeriodog, npart ); + compress_range_flt( msPeriodog, msLogPeriodog, npart ); /* Call the minimum statistics routine for noise estimation */ - minimum_statistics( npart, nFFTpart, psize, msLogPeriodog, hFdCngDec->msNoiseFloor_float, msLogNoiseEst, hFdCngDec->msAlpha_float, hFdCngDec->msPsd_float, hFdCngDec->msPsdFirstMoment_float, hFdCngDec->msPsdSecondMoment_float, hFdCngDec->msMinBuf_float, hFdCngDec->msBminWin_float, hFdCngDec->msBminSubWin_float, hFdCngDec->msCurrentMin_float, hFdCngDec->msCurrentMinOut_float, hFdCngDec->msCurrentMinSubWindow_float, hFdCngDec->msLocalMinFlag, hFdCngDec->msNewMinFlag, hFdCngDec->msPeriodogBuf_float, &( hFdCngDec->msPeriodogBufPtr ), hFdCngDec->hFdCngCom, + minimum_statistics_flt( npart, nFFTpart, psize_flt, msLogPeriodog, hFdCngDec->msNoiseFloor_float, msLogNoiseEst, hFdCngDec->msAlpha_float, hFdCngDec->msPsd_float, hFdCngDec->msPsdFirstMoment_float, hFdCngDec->msPsdSecondMoment_float, hFdCngDec->msMinBuf_float, hFdCngDec->msBminWin_float, hFdCngDec->msBminSubWin_float, hFdCngDec->msCurrentMin_float, hFdCngDec->msCurrentMinOut_float, hFdCngDec->msCurrentMinSubWindow_float, hFdCngDec->msLocalMinFlag, hFdCngDec->msNewMinFlag, hFdCngDec->msPeriodogBuf_float, &( hFdCngDec->msPeriodogBufPtr ), hFdCngDec->hFdCngCom, DEC, element_mode ); /* Expand MS outputs */ - expand_range( msLogNoiseEst, msNoiseEst, npart ); + expand_range_flt( msLogNoiseEst, msNoiseEst, npart ); } return; @@ -947,17 +947,17 @@ static void perform_noise_estimation_dec( /*------------------------------------------------------------------- - * FdCng_decodeSID() + * FdCng_decodeSID_flt() * * Decode the FD-CNG bitstream *-------------------------------------------------------------------*/ -void FdCng_decodeSID( +void FdCng_decodeSID_flt( Decoder_State *st /* i/o: decoder state structure */ ) { int16_t N; - float *sidNoiseEst; + float *sidNoiseEst_flt; float gain; int16_t i, index; float v[32]; @@ -972,7 +972,7 @@ void FdCng_decodeSID( hFdCngCom = ( st->hFdCngDec )->hFdCngCom; - sidNoiseEst = hFdCngCom->sidNoiseEst; + sidNoiseEst_flt = hFdCngCom->sidNoiseEst_flt; N = hFdCngCom->npart; gain = 0.0f; @@ -995,7 +995,7 @@ void FdCng_decodeSID( } else { /* Legacy EVS_MONO MSVQ tables */ - msvq_dec_float( cdk_37bits, NULL, NULL, FD_CNG_stages_37bits, N, FD_CNG_maxN_37bits, indices, 0, NULL, v, NULL ); + msvq_dec_float(cdk_37bits_flt, NULL, NULL, FD_CNG_stages_37bits, N, FD_CNG_maxN_37bits, indices, 0, NULL, v, NULL ); } @@ -1005,36 +1005,36 @@ void FdCng_decodeSID( /* Apply gain and undo log */ for ( i = 0; i < N; i++ ) { - sidNoiseEst[i] = (float) pow( 10.f, ( v[i] + gain ) / 10.f ); + sidNoiseEst_flt[i] = (float) pow( 10.f, ( v[i] + gain ) / 10.f ); } /* NB last band energy compensation */ if ( hFdCngCom->CngBandwidth == NB ) { - sidNoiseEst[N - 1] *= NB_LAST_BAND_SCALE_FLT; + sidNoiseEst_flt[N - 1] *= NB_LAST_BAND_SCALE_FLT; } if ( hFdCngCom->CngBandwidth == SWB && hFdCngCom->CngBitrate <= ACELP_13k20 ) { - sidNoiseEst[N - 1] *= SWB_13k2_LAST_BAND_SCALE_FLT; + sidNoiseEst_flt[N - 1] *= SWB_13k2_LAST_BAND_SCALE_FLT; } - scalebands( sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, hFdCngCom->stopBand - hFdCngCom->startBand, hFdCngCom->cngNoiseLevel, 1 ); + scalebands_flt( sidNoiseEst_flt, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, hFdCngCom->stopBand - hFdCngCom->startBand, hFdCngCom->cngNoiseLevel_flt, 1 ); - lpc_from_spectrum( hFdCngCom, hFdCngCom->startBand, hFdCngCom->stopFFTbin, st->preemph_fac_float); + lpc_from_spectrum_flt( hFdCngCom, hFdCngCom->startBand, hFdCngCom->stopFFTbin, st->preemph_fac_float); return; } /*------------------------------------------------------------------- - * noisy_speech_detection() + * noisy_speech_detection_flt() * * *-------------------------------------------------------------------*/ -void noisy_speech_detection( +void noisy_speech_detection_flt( HANDLE_FD_CNG_DEC hFdCngDec, /* i/o: FD_CNG structure */ const int16_t vad, /* i : VAD flag */ const float syn[] /* i : input time-domain frame */ @@ -1066,12 +1066,12 @@ void noisy_speech_detection( /*------------------------------------------------------------------- - * generate_comfort_noise_dec() + * generate_comfort_noise_dec_flt() * * Generate the comfort noise based on the target noise level *-------------------------------------------------------------------*/ -void generate_comfort_noise_dec( +void generate_comfort_noise_dec_flt( float **bufferReal, /* o : Real part of input bands */ float **bufferImag, /* o : Imaginary part of input bands */ Decoder_State *st, /* i/o: decoder state structure */ @@ -1082,23 +1082,23 @@ void generate_comfort_noise_dec( float *ptr_r, *ptr_i; HANDLE_FD_CNG_DEC hFdCngDec = st->hFdCngDec; HANDLE_FD_CNG_COM hFdCngCom = hFdCngDec->hFdCngCom; - float *cngNoiseLevel = hFdCngCom->cngNoiseLevel; - float *ptr_level = cngNoiseLevel; + float *cngNoiseLevel_flt = hFdCngCom->cngNoiseLevel_flt; + float *ptr_level = cngNoiseLevel_flt; int16_t *seed = &( hFdCngCom->seed ); int16_t *seed2; float c1, c2; float tmp1, tmp2; float scale, scaleCldfb; - float *fftBuffer = hFdCngCom->fftBuffer; - float *timeDomainOutput = hFdCngCom->timeDomainBuffer; + float *fftBuffer = hFdCngCom->fftBuffer_flt; + float *timeDomainOutput = hFdCngCom->timeDomainBuffer_flt; int16_t tcx_transition; float enr, att; scale = 1.f; - scaleCldfb = CLDFB_SCALING / hFdCngCom->scalingFactor; + scaleCldfb = CLDFB_SCALING_FLT / hFdCngCom->scalingFactor_flt; - c1 = (float) sqrt( hFdCngCom->coherence ); - c2 = (float) sqrt( 1 - hFdCngCom->coherence ); + c1 = (float) sqrt( hFdCngCom->coherence_flt); + c2 = (float) sqrt( 1 - hFdCngCom->coherence_flt); seed2 = &( hFdCngCom->seed2 ); if ( st->element_mode == IVAS_CPE_MDCT && st->idchan == 1 ) @@ -1107,19 +1107,19 @@ void generate_comfort_noise_dec( } /* Generate Gaussian random noise in real and imaginary parts of the FFT bins - Amplitudes are adjusted to the estimated noise level cngNoiseLevel in each bin */ + Amplitudes are adjusted to the estimated noise level cngNoiseLevel_flt in each bin */ if ( hFdCngCom->startBand == 0 ) { if ( st->element_mode == IVAS_CPE_MDCT || ( st->element_mode == IVAS_SCE && st->cng_ism_flag ) ) { - rand_gauss( &tmp1, seed ); - rand_gauss( &tmp2, seed2 ); + rand_gauss_flt( &tmp1, seed ); + rand_gauss_flt( &tmp2, seed2 ); fftBuffer[0] = tmp1 * c1 + tmp2 * c2; } else { - rand_gauss( &fftBuffer[0], seed ); + rand_gauss_flt( &fftBuffer[0], seed ); } fftBuffer[0] *= (float) sqrt( scale * *ptr_level ); /* DC component in FFT */ ptr_level++; @@ -1133,18 +1133,18 @@ void generate_comfort_noise_dec( } ptr_i = ptr_r + 1; - for ( ; ptr_level < cngNoiseLevel + hFdCngCom->stopFFTbin - hFdCngCom->startBand; ptr_level++ ) + for ( ; ptr_level < cngNoiseLevel_flt + hFdCngCom->stopFFTbin - hFdCngCom->startBand; ptr_level++ ) { /* Real part in FFT bins */ if ( st->element_mode == IVAS_CPE_MDCT || ( st->element_mode == IVAS_SCE && st->cng_ism_flag ) ) { - rand_gauss( &tmp1, seed ); - rand_gauss( &tmp2, seed2 ); + rand_gauss_flt( &tmp1, seed ); + rand_gauss_flt( &tmp2, seed2 ); *ptr_r = tmp1 * c1 + tmp2 * c2; } else { - rand_gauss( ptr_r, seed ); + rand_gauss_flt( ptr_r, seed ); } ( *ptr_r ) *= (float) sqrt( ( scale * *ptr_level ) * 0.5f ); ptr_r += 2; @@ -1152,13 +1152,13 @@ void generate_comfort_noise_dec( /* Imaginary part in FFT bins */ if ( st->element_mode == IVAS_CPE_MDCT || ( st->element_mode == IVAS_SCE && st->cng_ism_flag ) ) { - rand_gauss( &tmp1, seed ); - rand_gauss( &tmp2, seed2 ); + rand_gauss_flt( &tmp1, seed ); + rand_gauss_flt( &tmp2, seed2 ); *ptr_i = tmp1 * c1 + tmp2 * c2; } else { - rand_gauss( ptr_i, seed ); + rand_gauss_flt( ptr_i, seed ); } ( *ptr_i ) *= (float) sqrt( ( scale * *ptr_level ) * 0.5f ); ptr_i += 2; @@ -1174,7 +1174,7 @@ void generate_comfort_noise_dec( tcx_transition = 0; if ( hFdCngCom->frame_type_previous == ACTIVE_FRAME ) { - set_f( hFdCngCom->olapBufferSynth, 0.0f, hFdCngCom->fftlen ); + set_f( hFdCngCom->olapBufferSynth_flt, 0.0f, hFdCngCom->fftlen ); if ( ( st->core > ACELP_CORE && st->codec_mode == MODE2 ) || st->codec_mode == MODE1 ) { tcx_transition = 1; @@ -1182,12 +1182,12 @@ void generate_comfort_noise_dec( } /* Perform STFT synthesis */ - SynthesisSTFT( fftBuffer, timeDomainOutput, hFdCngCom->olapBufferSynth, hFdCngCom->olapWinSyn, tcx_transition, hFdCngCom, st->element_mode, nchan_out ); + SynthesisSTFT_flt( fftBuffer, timeDomainOutput, hFdCngCom->olapBufferSynth_flt, hFdCngCom->olapWinSyn_flt, tcx_transition, hFdCngCom, st->element_mode, nchan_out ); /* update CNG excitation energy for LP_CNG */ /* calculate the residual signal energy */ - enr = dotp( hFdCngCom->exc_cng, hFdCngCom->exc_cng, hFdCngCom->frameSize ) / hFdCngCom->frameSize; + enr = dotp( hFdCngCom->exc_cng_flt, hFdCngCom->exc_cng_flt, hFdCngCom->frameSize ) / hFdCngCom->frameSize; /* convert log2 of residual signal energy */ enr = (float) log10( enr + 0.1f ) / (float) log10( 2.0f ); @@ -1219,7 +1219,7 @@ void generate_comfort_noise_dec( st->lp_ener = (float) ( 0.8f * st->lp_ener + 0.2f * pow( 2.0f, enr ) ); /* Generate Gaussian random noise in real and imaginary parts of the CLDFB bands - Amplitudes are adjusted to the estimated noise level cngNoiseLevel in each band */ + Amplitudes are adjusted to the estimated noise level cngNoiseLevel_flt in each band */ if ( bufferReal != NULL && hFdCngCom->numCoreBands < hFdCngCom->regularStopBand ) { @@ -1230,26 +1230,26 @@ void generate_comfort_noise_dec( /* Real part in CLDFB band */ if ( st->element_mode == IVAS_CPE_MDCT || ( st->element_mode == IVAS_SCE && st->cng_ism_flag ) ) { - rand_gauss( &tmp1, seed ); - rand_gauss( &tmp2, seed2 ); + rand_gauss_flt( &tmp1, seed ); + rand_gauss_flt( &tmp2, seed2 ); bufferReal[i][j] = tmp1 * c1 + tmp2 * c2; } else { - rand_gauss( &bufferReal[i][j], seed ); + rand_gauss_flt( &bufferReal[i][j], seed ); } bufferReal[i][j] *= (float) sqrt( ( scaleCldfb * *ptr_level ) * 0.5f ); /* Imaginary part in CLDFB band */ if ( st->element_mode == IVAS_CPE_MDCT || ( st->element_mode == IVAS_SCE && st->cng_ism_flag ) ) { - rand_gauss( &tmp1, seed ); - rand_gauss( &tmp2, seed2 ); + rand_gauss_flt( &tmp1, seed ); + rand_gauss_flt( &tmp2, seed2 ); bufferImag[i][j] = tmp1 * c1 + tmp2 * c2; } else { - rand_gauss( &bufferImag[i][j], seed ); + rand_gauss_flt( &bufferImag[i][j], seed ); } bufferImag[i][j] *= (float) sqrt( ( scaleCldfb * *ptr_level ) * 0.5f ); } @@ -1267,7 +1267,7 @@ void generate_comfort_noise_dec( if ( st->core > ACELP_CORE ) { - tcx_windowing_synthesis_current_frame( timeDomainOutput, st->hTcxCfg->tcx_mdct_window_flt, /*Keep sine windows for limiting Time modulation*/ + tcx_windowing_synthesis_current_frame_flt( timeDomainOutput, st->hTcxCfg->tcx_mdct_window_flt, /*Keep sine windows for limiting Time modulation*/ st->hTcxCfg->tcx_mdct_window_half_flt, st->hTcxCfg->tcx_mdct_window_minimum_flt, st->hTcxCfg->tcx_mdct_window_length, st->hTcxCfg->tcx_mdct_window_half_length, st->hTcxCfg->tcx_mdct_window_min_length, 0, st->hTcxCfg->tcx_last_overlap_mode == ALDO_WINDOW ? FULL_OVERLAP : st->hTcxCfg->tcx_last_overlap_mode, NULL, NULL, NULL, NULL, NULL, N / 2, st->hTcxCfg->tcx_offset < 0 ? -st->hTcxCfg->tcx_offset : 0, 1, 0, 0 ); if ( st->hTcxCfg->last_aldo ) @@ -1280,7 +1280,7 @@ void generate_comfort_noise_dec( else { - tcx_windowing_synthesis_past_frame( st->hTcxDec->syn_Overl_float, st->hTcxCfg->tcx_mdct_window_flt, st->hTcxCfg->tcx_mdct_window_half_flt, st->hTcxCfg->tcx_mdct_window_minimum_flt, st->hTcxCfg->tcx_mdct_window_length, st->hTcxCfg->tcx_mdct_window_half_length, st->hTcxCfg->tcx_mdct_window_min_length, st->hTcxCfg->tcx_last_overlap_mode ); + tcx_windowing_synthesis_past_frame_flt( st->hTcxDec->syn_Overl_float, st->hTcxCfg->tcx_mdct_window_flt, st->hTcxCfg->tcx_mdct_window_half_flt, st->hTcxCfg->tcx_mdct_window_minimum_flt, st->hTcxCfg->tcx_mdct_window_length, st->hTcxCfg->tcx_mdct_window_half_length, st->hTcxCfg->tcx_mdct_window_min_length, st->hTcxCfg->tcx_last_overlap_mode ); for ( i = 0; i < st->hTcxCfg->tcx_mdct_window_length; i++ ) @@ -1305,7 +1305,7 @@ void generate_comfort_noise_dec( for ( i = 0; i < N; i++ ) { - rand_gauss( &( noise[i] ), &( seed_loc ) ); + rand_gauss_flt( &( noise[i] ), &( seed_loc ) ); gain += noise[i] * noise[i]; } @@ -1324,7 +1324,7 @@ void generate_comfort_noise_dec( for ( i = 0; i < N / 2; i++ ) { - timeDomainOutput[i] += noise[i] * hFdCngCom->olapWinSyn[N / 2 + i]; + timeDomainOutput[i] += noise[i] * hFdCngCom->olapWinSyn_flt[N / 2 + i]; } } } @@ -1334,12 +1334,12 @@ void generate_comfort_noise_dec( /*------------------------------------------------------------------- - * generate_comfort_noise_dec_hf() + * generate_comfort_noise_dec_hf_flt() * * Generate the comfort noise based on the target noise level for the CLDFB part *-------------------------------------------------------------------*/ -void generate_comfort_noise_dec_hf( +void generate_comfort_noise_dec_hf_flt( float **bufferReal, /* o : Real part of input bands */ float **bufferImag, /* o : Imaginary part of input bands */ HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables */ @@ -1350,7 +1350,7 @@ void generate_comfort_noise_dec_hf( float *ptr_level; int16_t *seed = &( hFdCngCom->seed ); - float scale = CLDFB_SCALING / hFdCngCom->scalingFactor; + float scale = CLDFB_SCALING_FLT / hFdCngCom->scalingFactor_flt; int16_t *seed2 = &( hFdCngCom->seed ); @@ -1360,14 +1360,14 @@ void generate_comfort_noise_dec_hf( { seed2 = &( hFdCngCom->seed2 ); - c1 = (float) sqrt( hFdCngCom->coherence ); - c2 = (float) sqrt( 1 - hFdCngCom->coherence ); + c1 = (float) sqrt( hFdCngCom->coherence_flt); + c2 = (float) sqrt( 1 - hFdCngCom->coherence_flt); } - ptr_level = hFdCngCom->cngNoiseLevel + hFdCngCom->stopFFTbin - hFdCngCom->startBand; + ptr_level = hFdCngCom->cngNoiseLevel_flt + hFdCngCom->stopFFTbin - hFdCngCom->startBand; /* Generate Gaussian random noise in real and imaginary parts of the CLDFB bands - Amplitudes are adjusted to the estimated noise level cngNoiseLevel in each band + Amplitudes are adjusted to the estimated noise level cngNoiseLevel_flt in each band */ if ( hFdCngCom->numCoreBands < hFdCngCom->regularStopBand ) { @@ -1378,24 +1378,24 @@ void generate_comfort_noise_dec_hf( if ( cng_coh_flag ) { /* Real part in CLDFB band */ - rand_gauss( &tmp1, seed ); - rand_gauss( &tmp2, seed2 ); + rand_gauss_flt( &tmp1, seed ); + rand_gauss_flt( &tmp2, seed2 ); bufferReal[i][j] = tmp1 * c1 + tmp2 * c2; bufferReal[i][j] *= (float) sqrt( ( scale * *ptr_level ) * 0.5f ); /* Imaginary part in CLDFB band */ - rand_gauss( &tmp1, seed ); - rand_gauss( &tmp2, seed2 ); + rand_gauss_flt( &tmp1, seed ); + rand_gauss_flt( &tmp2, seed2 ); bufferImag[i][j] = tmp1 * c1 + tmp2 * c2; bufferImag[i][j] *= (float) sqrt( ( scale * *ptr_level ) * 0.5f ); } else { /* Real part in CLDFB band */ - rand_gauss( &bufferReal[i][j], seed ); + rand_gauss_flt( &bufferReal[i][j], seed ); bufferReal[i][j] *= (float) sqrt( ( scale * *ptr_level ) * 0.5f ); /* Imaginary part in CLDFB band */ - rand_gauss( &bufferImag[i][j], seed ); + rand_gauss_flt( &bufferImag[i][j], seed ); bufferImag[i][j] *= (float) sqrt( ( scale * *ptr_level ) * 0.5f ); } } @@ -1408,12 +1408,12 @@ void generate_comfort_noise_dec_hf( /*------------------------------------------------------------------- - * generate_masking_noise() + * generate_masking_noise_flt() * * Generate additional comfort noise (kind of noise filling) *-------------------------------------------------------------------*/ -void generate_masking_noise( +void generate_masking_noise_flt( float *timeDomainBuffer, /* i/o: time-domain signal */ HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables */ const int16_t length, /* i : frame size */ @@ -1425,9 +1425,9 @@ void generate_masking_noise( const int16_t nchan_out /* i : number of output channels */ ) { - float *cngNoiseLevel = hFdCngCom->cngNoiseLevel; - float *ptr_level = cngNoiseLevel; - float *fftBuffer = hFdCngCom->fftBuffer; + float *cngNoiseLevel_flt = hFdCngCom->cngNoiseLevel_flt; + float *ptr_level = cngNoiseLevel_flt; + float *fftBuffer = hFdCngCom->fftBuffer_flt; int16_t i; float maskingNoise[L_FRAME16k]; float *ptr_r; @@ -1437,7 +1437,7 @@ void generate_masking_noise( float scale = 1.f; /* skip noise generating if level is very low, to avoid problems with possibly running into denormals */ - if ( hFdCngCom->likelihood_noisy_speech > DELTA_MASKING_NOISE ) + if ( hFdCngCom->likelihood_noisy_speech_flt > DELTA_MASKING_NOISE ) { if ( core != AMR_WB_CORE ) { @@ -1459,7 +1459,7 @@ void generate_masking_noise( /* Compute additional CN level */ for ( i = 0; i < SIZE_SCALE_TABLE_CN_AMRWB; i++ ) { - if ( hFdCngCom->CngBitrate >= scaleTable_cn_only_amrwbio[i][0] ) + if ( hFdCngCom->CngBitrate >= scaleTable_cn_only_amrwbio_flt[i][0] ) { break; } @@ -1467,7 +1467,7 @@ void generate_masking_noise( if ( i < SIZE_SCALE_TABLE_CN_AMRWB ) { - scale *= (float) pow( 10.f, -scaleTable_cn_only_amrwbio[i][1] / 10.f ) - 1.f; + scale *= (float) pow( 10.f, -scaleTable_cn_only_amrwbio_flt[i][1] / 10.f ) - 1.f; } else { @@ -1476,13 +1476,13 @@ void generate_masking_noise( } /* Exclude clean speech */ - scale *= hFdCngCom->likelihood_noisy_speech; + scale *= hFdCngCom->likelihood_noisy_speech_flt; /* Generate Gaussian random noise in real and imaginary parts of the FFT bins - Amplitudes are adjusted to the estimated noise level cngNoiseLevel in each bin */ + Amplitudes are adjusted to the estimated noise level cngNoiseLevel_flt in each bin */ if ( startBand == 0 ) { - rand_gauss( &fftBuffer[0], seed ); + rand_gauss_flt( &fftBuffer[0], seed ); ptr_r = fftBuffer + 2; fftBuffer[0] *= (float) sqrt( scale * *ptr_level ); /* DC component in FFT */ ptr_level++; @@ -1494,14 +1494,14 @@ void generate_masking_noise( ptr_r = fftBuffer + 2 * startBand; } ptr_i = ptr_r + 1; - for ( ; ptr_level < cngNoiseLevel + hFdCngCom->stopFFTbin - startBand; ptr_level++ ) + for ( ; ptr_level < cngNoiseLevel_flt + hFdCngCom->stopFFTbin - startBand; ptr_level++ ) { /* Real part in FFT bins */ - rand_gauss( ptr_r, seed ); + rand_gauss_flt( ptr_r, seed ); ( *ptr_r ) *= (float) sqrt( ( scale * *ptr_level ) * 0.5f ); ptr_r += 2; /* Imaginary part in FFT bins */ - rand_gauss( ptr_i, seed ); + rand_gauss_flt( ptr_i, seed ); ( *ptr_i ) *= (float) sqrt( ( scale * *ptr_level ) * 0.5f ); ptr_i += 2; } @@ -1513,8 +1513,8 @@ void generate_masking_noise( } else { - /* very low level case - update random seeds and reset FFT buffer; don't fully skip SynthesisSTFT(), because of the buffer updates done there... */ - generate_masking_noise_update_seed( hFdCngCom ); + /* very low level case - update random seeds and reset FFT buffer; don't fully skip SynthesisSTFT_flt(), because of the buffer updates done there... */ + generate_masking_noise_update_seed_flt( hFdCngCom ); set_f( fftBuffer, 0.f, hFdCngCom->fftlen ); } @@ -1522,11 +1522,11 @@ void generate_masking_noise( /* Perform STFT synthesis */ if ( secondary ) { - SynthesisSTFT( fftBuffer, maskingNoise, hStereoCng->olapBufferSynth22, hFdCngCom->olapWinSyn, 0, hFdCngCom, element_mode, nchan_out ); + SynthesisSTFT_flt( fftBuffer, maskingNoise, hStereoCng->olapBufferSynth22, hFdCngCom->olapWinSyn_flt, 0, hFdCngCom, element_mode, nchan_out ); } else { - SynthesisSTFT( fftBuffer, maskingNoise, hFdCngCom->olapBufferSynth2, hFdCngCom->olapWinSyn, 0, hFdCngCom, element_mode, nchan_out ); + SynthesisSTFT_flt( fftBuffer, maskingNoise, hFdCngCom->olapBufferSynth2_flt, hFdCngCom->olapWinSyn_flt, 0, hFdCngCom, element_mode, nchan_out ); } /* Add some comfort noise on top of decoded signal */ @@ -1544,37 +1544,37 @@ void generate_masking_noise( /*------------------------------------------------------------------- - * generate_masking_noise_update_seed() + * generate_masking_noise_update_seed_flt() * - * Update seed for scenarios where generate_masking_noise() is + * Update seed for scenarios where generate_masking_noise_flt() is * not called based on signal statistics *-------------------------------------------------------------------*/ -void generate_masking_noise_update_seed( +void generate_masking_noise_update_seed_flt( HANDLE_FD_CNG_COM hFdCngCom /* i/o: FD_CNG structure containing all buffers and variables */ ) { - float *cngNoiseLevel = hFdCngCom->cngNoiseLevel; - float *ptr_level = cngNoiseLevel; + float *cngNoiseLevel_flt = hFdCngCom->cngNoiseLevel_flt; + float *ptr_level = cngNoiseLevel_flt; int16_t startBand = hFdCngCom->startBand; int16_t *seed = &( hFdCngCom->seed ); float tmp = 0; /* Generate Gaussian random noise in real and imaginary parts of the FFT bins - Amplitudes are adjusted to the estimated noise level cngNoiseLevel in each bin + Amplitudes are adjusted to the estimated noise level cngNoiseLevel_flt in each bin */ if ( startBand == 0 ) { - rand_gauss( &tmp, seed ); + rand_gauss_flt( &tmp, seed ); ptr_level++; } - for ( ; ptr_level < cngNoiseLevel + hFdCngCom->stopFFTbin - startBand; ptr_level++ ) + for ( ; ptr_level < cngNoiseLevel_flt + hFdCngCom->stopFFTbin - startBand; ptr_level++ ) { /* Real part in FFT bins */ - rand_gauss( &tmp, seed ); - rand_gauss( &tmp, seed ); + rand_gauss_flt( &tmp, seed ); + rand_gauss_flt( &tmp, seed ); } return; @@ -1582,27 +1582,27 @@ void generate_masking_noise_update_seed( /*------------------------------------------------------------------- - * generate_masking_noise_mdct() + * generate_masking_noise_mdct_flt() * * Generate additional comfort noise (kind of noise filling) *-------------------------------------------------------------------*/ -void generate_masking_noise_mdct( +void generate_masking_noise_mdct_flt( float *mdctBuffer, /* i/o: time-domain signal */ HANDLE_FD_CNG_COM hFdCngCom /* i/o: FD_CNG structure containing all buffers and variables */ ) { - float *cngNoiseLevel = hFdCngCom->cngNoiseLevel; + float *cngNoiseLevel_flt = hFdCngCom->cngNoiseLevel_flt; int16_t i; float maskingNoise[2 * L_FRAME16k]; float *ptr_r; - float *ptr_level = cngNoiseLevel; + float *ptr_level = cngNoiseLevel_flt; int16_t startBand = hFdCngCom->startBand; int16_t *seed = &( hFdCngCom->seed ); float scale = 1.f; /* skip noise generating if level is very low, to avoid problems with possibly running into denormals */ - if ( hFdCngCom->likelihood_noisy_speech > DELTA_MASKING_NOISE ) + if ( hFdCngCom->likelihood_noisy_speech_flt > DELTA_MASKING_NOISE ) { for ( i = 0; i < SIZE_SCALE_TABLE_CN; i++ ) { @@ -1617,15 +1617,15 @@ void generate_masking_noise_mdct( scale *= (float) pow( 10.f, -scaleTable_cn_only[i].scale_flt / 10.f ) - 1.f; /* Exclude clean speech */ - scale *= hFdCngCom->likelihood_noisy_speech; + scale *= hFdCngCom->likelihood_noisy_speech_flt; /* Generate Gaussian random noise in real and imaginary parts of the FFT bins - Amplitudes are adjusted to the estimated noise level cngNoiseLevel in each bin + Amplitudes are adjusted to the estimated noise level cngNoiseLevel_flt in each bin */ if ( startBand == 0 ) { - rand_gauss( &maskingNoise[0], seed ); + rand_gauss_flt( &maskingNoise[0], seed ); maskingNoise[0] *= (float) sqrt( scale * *ptr_level * 0.5f ); /* DC component in FFT */ ptr_level++; ptr_r = maskingNoise + 1; @@ -1637,10 +1637,10 @@ void generate_masking_noise_mdct( ptr_r = maskingNoise + startBand; } - for ( ; ptr_level < cngNoiseLevel + hFdCngCom->stopFFTbin - startBand; ptr_level++ ) + for ( ; ptr_level < cngNoiseLevel_flt + hFdCngCom->stopFFTbin - startBand; ptr_level++ ) { /* MDCT bins */ - rand_gauss( ptr_r, seed ); + rand_gauss_flt( ptr_r, seed ); ( *ptr_r ) *= (float) sqrt( scale * *ptr_level * 0.5f ); ptr_r += 1; } @@ -1656,13 +1656,13 @@ void generate_masking_noise_mdct( /* very low level case - just update random seeds */ if ( startBand == 0 ) { - rand_gauss( &maskingNoise[0], seed ); + rand_gauss_flt( &maskingNoise[0], seed ); ptr_level++; } - for ( ; ptr_level < cngNoiseLevel + hFdCngCom->stopFFTbin - startBand; ptr_level++ ) + for ( ; ptr_level < cngNoiseLevel_flt + hFdCngCom->stopFFTbin - startBand; ptr_level++ ) { - rand_gauss( &maskingNoise[0], seed ); + rand_gauss_flt( &maskingNoise[0], seed ); } } @@ -1696,18 +1696,18 @@ void generate_stereo_masking_noise( if ( st->idchan == 0 ) { hFdCngCom = st->hFdCngDec->hFdCngCom; - mvr2r( hFdCngCom->olapBufferSynth2, Np, hFdCngCom->frameSize / 2 ); + mvr2r( hFdCngCom->olapBufferSynth2_flt, Np, hFdCngCom->frameSize / 2 ); mvr2r( hStereoCng->olapBufferSynth22, Ns, hFdCngCom->frameSize / 2 ); set_f( &Np[hFdCngCom->frameSize / 2], 0.0f, hFdCngCom->frameSize / 2 ); set_f( &Ns[hFdCngCom->frameSize / 2], 0.0f, hFdCngCom->frameSize / 2 ); if ( !fadeOut ) { - generate_masking_noise( N1, hFdCngCom, hFdCngCom->frameSize, 0, 1, 0, st->element_mode, hStereoCng, nchan_out ); + generate_masking_noise_flt( N1, hFdCngCom, hFdCngCom->frameSize, 0, 1, 0, st->element_mode, hStereoCng, nchan_out ); /* Generate masking noise for secondary channel */ if ( flag_sec_CNA ) { - generate_masking_noise( N2, hFdCngCom, hFdCngCom->frameSize, 0, 1, 1, st->element_mode, hStereoCng, nchan_out ); + generate_masking_noise_flt( N2, hFdCngCom, hFdCngCom->frameSize, 0, 1, 1, st->element_mode, hStereoCng, nchan_out ); gamma = hStereoCng->c_PS_LT * hStereoCng->c_PS_LT; scale = 1.0f; if ( gamma < 0.9f ) @@ -1734,8 +1734,8 @@ void generate_stereo_masking_noise( scale *= (float) ( hFdCngCom->fftlen / 2 ); for ( i = 0; i < hFdCngCom->frameSize / 2; i++ ) { - hFdCngCom->olapBufferSynth2[i] = scale * ( hFdCngCom->olapBufferSynth2[i + 5 * hFdCngCom->frameSize / 4] + gamma * hStereoCng->olapBufferSynth22[i + 5 * hFdCngCom->frameSize / 4] ); - hStereoCng->olapBufferSynth22[i] = sign( hStereoCng->c_PS_LT ) * scale * ( hFdCngCom->olapBufferSynth2[i + 5 * hFdCngCom->frameSize / 4] - gamma * hStereoCng->olapBufferSynth22[i + 5 * hFdCngCom->frameSize / 4] ); + hFdCngCom->olapBufferSynth2_flt[i] = scale * ( hFdCngCom->olapBufferSynth2_flt[i + 5 * hFdCngCom->frameSize / 4] + gamma * hStereoCng->olapBufferSynth22[i + 5 * hFdCngCom->frameSize / 4] ); + hStereoCng->olapBufferSynth22[i] = sign( hStereoCng->c_PS_LT ) * scale * ( hFdCngCom->olapBufferSynth2_flt[i + 5 * hFdCngCom->frameSize / 4] - gamma * hStereoCng->olapBufferSynth22[i + 5 * hFdCngCom->frameSize / 4] ); } } else @@ -1748,13 +1748,13 @@ void generate_stereo_masking_noise( scale = (float) ( hFdCngCom->fftlen / 2 ); for ( i = 0; i < hFdCngCom->frameSize; i++ ) { - hFdCngCom->olapBufferSynth2[i] = scale * hFdCngCom->olapBufferSynth2[i + 5 * hFdCngCom->frameSize / 4]; + hFdCngCom->olapBufferSynth2_flt[i] = scale * hFdCngCom->olapBufferSynth2_flt[i + 5 * hFdCngCom->frameSize / 4]; } } } else { - set_f( hFdCngCom->olapBufferSynth2, 0.0f, hFdCngCom->frameSize / 2 ); + set_f( hFdCngCom->olapBufferSynth2_flt, 0.0f, hFdCngCom->frameSize / 2 ); set_f( hStereoCng->olapBufferSynth22, 0.0f, hFdCngCom->frameSize / 2 ); } if ( flag_sec_CNA ) @@ -1808,8 +1808,8 @@ void generate_masking_noise_lb_dirac( ) { int16_t i; - float *cngNoiseLevel = hFdCngCom->cngNoiseLevel; - float *fftBuffer = hFdCngCom->fftBuffer; + float *cngNoiseLevel_flt = hFdCngCom->cngNoiseLevel_flt; + float *fftBuffer = hFdCngCom->fftBuffer_flt; float *ptr_r; float *ptr_i; float *ptr_level; @@ -1828,7 +1828,7 @@ void generate_masking_noise_lb_dirac( if ( cna_flag ) { /* skip noise generating if level is very low, to avoid problems with possibly running into denormals */ - if ( hFdCngCom->likelihood_noisy_speech > DELTA_MASKING_NOISE ) + if ( hFdCngCom->likelihood_noisy_speech_flt > DELTA_MASKING_NOISE ) { /* Compute additional CN level */ for ( i = 0; i < 15; i++ ) @@ -1842,7 +1842,7 @@ void generate_masking_noise_lb_dirac( } scale = (float) pow( 10.f, -scaleTable_cn_dirac[i].scale_flt / 10.f ) - 1.f; - scale *= hFdCngCom->likelihood_noisy_speech; + scale *= hFdCngCom->likelihood_noisy_speech_flt; } } @@ -1855,13 +1855,13 @@ void generate_masking_noise_lb_dirac( if ( scale != 0 ) { /*Generate LF comfort noise only at first slot, for the whole frame*/ - ptr_level = cngNoiseLevel; + ptr_level = cngNoiseLevel_flt; /* Generate Gaussian random noise in real and imaginary parts of the FFT bins - Amplitudes are adjusted to the estimated noise level cngNoiseLevel in each bin */ + Amplitudes are adjusted to the estimated noise level cngNoiseLevel_flt in each bin */ if ( hFdCngCom->startBand == 0 ) { - rand_gauss( &fftBuffer[0], seed ); + rand_gauss_flt( &fftBuffer[0], seed ); ptr_r = fftBuffer + 2; fftBuffer[0] *= (float) sqrt( scale * *ptr_level ); /* DC component in FFT */ ptr_level++; @@ -1874,14 +1874,14 @@ void generate_masking_noise_lb_dirac( } ptr_i = ptr_r + 1; - for ( ; ptr_level < cngNoiseLevel + hFdCngCom->stopFFTbin - hFdCngCom->startBand; ptr_level++ ) + for ( ; ptr_level < cngNoiseLevel_flt + hFdCngCom->stopFFTbin - hFdCngCom->startBand; ptr_level++ ) { /* Real part in FFT bins */ - rand_gauss( ptr_r, seed ); + rand_gauss_flt( ptr_r, seed ); ( *ptr_r ) *= (float) sqrt( ( scale * *ptr_level ) * 0.5f ); ptr_r += 2; /* Imaginary part in FFT bins */ - rand_gauss( ptr_i, seed ); + rand_gauss_flt( ptr_i, seed ); ( *ptr_i ) *= (float) sqrt( ( scale * *ptr_level ) * 0.5f ); ptr_i += 2; } @@ -1892,19 +1892,19 @@ void generate_masking_noise_lb_dirac( fftBuffer[1] = 0.f; /* Perform STFT synthesis */ - SynthesisSTFT_dirac( fftBuffer, tdBuffer + n_samples_start, hFdCngCom->olapBufferSynth2, hFdCngCom->olapWinSyn, n_samples_out_loop, hFdCngCom ); + SynthesisSTFT_dirac_flt( fftBuffer, tdBuffer + n_samples_start, hFdCngCom->olapBufferSynth2_flt, hFdCngCom->olapWinSyn_flt, n_samples_out_loop, hFdCngCom ); } else { /* very low level case - update random seeds */ - generate_masking_noise_update_seed( hFdCngCom ); + generate_masking_noise_update_seed_flt( hFdCngCom ); set_f( fftBuffer, 0.f, hFdCngCom->fftlen ); /* Perform STFT synthesis */ - SynthesisSTFT_dirac( fftBuffer, tdBuffer + n_samples_start, hFdCngCom->olapBufferSynth2, hFdCngCom->olapWinSyn, n_samples_out_loop, hFdCngCom ); + SynthesisSTFT_dirac_flt( fftBuffer, tdBuffer + n_samples_start, hFdCngCom->olapBufferSynth2_flt, hFdCngCom->olapWinSyn_flt, n_samples_out_loop, hFdCngCom ); } n_samples_out -= hFdCngCom->frameSize; @@ -1948,7 +1948,7 @@ void generate_masking_noise_dirac( /* Resample CLDFB memories if necessary*/ if ( ( h_cldfb->no_channels * h_cldfb->no_col ) != hFdCngCom->frameSize ) { - resampleCldfb( h_cldfb, hFdCngCom->frameSize * FRAMES_PER_SEC ); + resampleCldfb_ivas( h_cldfb, hFdCngCom->frameSize * FRAMES_PER_SEC ); } set_zero( Cldfb_RealBuffer, CLDFB_NO_CHANNELS_MAX ); @@ -1958,7 +1958,7 @@ void generate_masking_noise_dirac( if ( cna_flag ) { /* skip noise generating if level is very low, to avoid problems with possibly running into denormals */ - if ( hFdCngCom->likelihood_noisy_speech > DELTA_MASKING_NOISE ) + if ( hFdCngCom->likelihood_noisy_speech_flt > DELTA_MASKING_NOISE ) { /* Compute additional CN level */ for ( i = 0; i < 15; i++ ) @@ -1972,7 +1972,7 @@ void generate_masking_noise_dirac( } scale = (float) pow( 10.f, -scaleTable_cn_dirac[i].scale_flt / 10.f ) - 1.f; - scale *= hFdCngCom->likelihood_noisy_speech; + scale *= hFdCngCom->likelihood_noisy_speech_flt; } } /* LB CLDFB - CNA from STFT: CNA applied only in channel 0*/ @@ -1981,12 +1981,12 @@ void generate_masking_noise_dirac( if ( scale != 0 ) { /* LF CLDFB*/ - cldfbAnalysis_ts( &( tdBuffer[hFdCngCom->numCoreBands * slot_index] ), Cldfb_RealBuffer, Cldfb_ImagBuffer, hFdCngCom->numCoreBands, h_cldfb ); + cldfbAnalysis_ts_ivas( &( tdBuffer[hFdCngCom->numCoreBands * slot_index] ), Cldfb_RealBuffer, Cldfb_ImagBuffer, hFdCngCom->numCoreBands, h_cldfb ); } else { /* LB ana CLDFB*/ - cldfbAnalysis_ts( &( tdBuffer[hFdCngCom->numCoreBands * slot_index] ), Cldfb_RealBuffer, Cldfb_ImagBuffer, hFdCngCom->numCoreBands, h_cldfb ); + cldfbAnalysis_ts_ivas( &( tdBuffer[hFdCngCom->numCoreBands * slot_index] ), Cldfb_RealBuffer, Cldfb_ImagBuffer, hFdCngCom->numCoreBands, h_cldfb ); } } @@ -1997,16 +1997,16 @@ void generate_masking_noise_dirac( } if ( scale != 0 ) { - scale *= CLDFB_SCALING * ( h_cldfb->scale_flt * h_cldfb->scale_flt * 8.f ); - ptr_level = hFdCngCom->cngNoiseLevel + hFdCngCom->stopFFTbin - hFdCngCom->startBand; + scale *= CLDFB_SCALING_FLT * ( h_cldfb->scale_flt * h_cldfb->scale_flt * 8.f ); + ptr_level = hFdCngCom->cngNoiseLevel_flt + hFdCngCom->stopFFTbin - hFdCngCom->startBand; for ( i = hFdCngCom->numCoreBands; i < hFdCngCom->regularStopBand; i++ ) { /* Real part in CLDFB band */ - rand_gauss( &Cldfb_RealBuffer[i], seed ); + rand_gauss_flt( &Cldfb_RealBuffer[i], seed ); Cldfb_RealBuffer[i] *= (float) sqrt( ( scale * *ptr_level ) * 0.5f ); /* Imaginary part in CLDFB band */ - rand_gauss( &Cldfb_ImagBuffer[i], seed ); + rand_gauss_flt( &Cldfb_ImagBuffer[i], seed ); Cldfb_ImagBuffer[i] *= (float) sqrt( ( scale * *ptr_level ) * 0.5f ); ptr_level++; @@ -2058,7 +2058,7 @@ void FdCngDecodeMDCTStereoSID( { sts[ch] = hCPE->hCoreCoder[ch]; ms_ptr[ch] = &logNoiseEst[ch][0]; - lr_ptr[ch] = &sts[ch]->hFdCngDec->hFdCngCom->sidNoiseEst[0]; + lr_ptr[ch] = &sts[ch]->hFdCngDec->hFdCngCom->sidNoiseEst_flt[0]; } /* decode noise shapes and gains */ @@ -2111,9 +2111,9 @@ void FdCngDecodeMDCTStereoSID( lr_ptr[ch][p] = powf( 10.f, ( ms_ptr[ch][p] + gain[ch] ) / 10.f ); } - scalebands( hFdCngCom->sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, hFdCngCom->stopBand - hFdCngCom->startBand, hFdCngCom->cngNoiseLevel, 1 ); + scalebands_flt( hFdCngCom->sidNoiseEst_flt, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, hFdCngCom->stopBand - hFdCngCom->startBand, hFdCngCom->cngNoiseLevel_flt, 1 ); - lpc_from_spectrum( hFdCngCom, hFdCngCom->startBand, hFdCngCom->stopFFTbin, sts[ch]->preemph_fac_float); + lpc_from_spectrum_flt( hFdCngCom, hFdCngCom->startBand, hFdCngCom->stopFFTbin, sts[ch]->preemph_fac_float); } if ( hCPE->nchan_out == 1 && hCPE->last_element_brate <= IVAS_SID_5k2 ) @@ -2121,7 +2121,7 @@ void FdCngDecodeMDCTStereoSID( /* create proper M noise shape in channel zero after gains have been applied */ for ( p = 0; p < N; p++ ) { - sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p] = 0.5f * ( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p] + sts[1]->hFdCngDec->hFdCngCom->sidNoiseEst[p] ); + sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst_flt[p] = 0.5f * ( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst_flt[p] + sts[1]->hFdCngDec->hFdCngCom->sidNoiseEst_flt[p] ); } } @@ -2158,7 +2158,7 @@ void FdCngDecodeDiracMDCTStereoSID( { sts[ch] = hCPE->hCoreCoder[ch]; ms_ptr[ch] = &logNoiseEst[ch][0]; - lr_ptr[ch] = &sts[ch]->hFdCngDec->hFdCngCom->sidNoiseEst[0]; + lr_ptr[ch] = &sts[ch]->hFdCngDec->hFdCngCom->sidNoiseEst_flt[0]; ( sts[ch]->hFdCngDec )->hFdCngCom->sid_frame_counter++; } @@ -2198,19 +2198,19 @@ void FdCngDecodeDiracMDCTStereoSID( lr_ptr[ch][N - 1] *= SWB_13k2_LAST_BAND_SCALE_FLT; } - scalebands( hFdCngCom->sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, hFdCngCom->stopBand - hFdCngCom->startBand, hFdCngCom->cngNoiseLevel, 1 ); + scalebands_flt( hFdCngCom->sidNoiseEst_flt, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, hFdCngCom->stopBand - hFdCngCom->startBand, hFdCngCom->cngNoiseLevel_flt, 1 ); - lpc_from_spectrum( hFdCngCom, hFdCngCom->startBand, hFdCngCom->stopFFTbin, sts[ch]->preemph_fac_float); + lpc_from_spectrum_flt( hFdCngCom, hFdCngCom->startBand, hFdCngCom->stopFFTbin, sts[ch]->preemph_fac_float); } - sts[0]->hFdCngDec->hFdCngCom->coherence = 0.0f; - sts[1]->hFdCngDec->hFdCngCom->coherence = 0.0f; + sts[0]->hFdCngDec->hFdCngCom->coherence_flt = 0.0f; + sts[1]->hFdCngDec->hFdCngCom->coherence_flt = 0.0f; if ( hCPE->nchan_out == 1 ) { /* create proper M noise shape in channel zero after gains have been applied */ for ( p = 0; p < N; p++ ) { - sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p] = 0.5f * ( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p] + sts[1]->hFdCngDec->hFdCngCom->sidNoiseEst[p] ); + sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst_flt[p] = 0.5f * ( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst_flt[p] + sts[1]->hFdCngDec->hFdCngCom->sidNoiseEst_flt[p] ); } } diff --git a/lib_dec/fd_cng_dec_fx.c b/lib_dec/fd_cng_dec_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..68c602e88ed69ab76c22df38713c9ed16ca13b5e --- /dev/null +++ b/lib_dec/fd_cng_dec_fx.c @@ -0,0 +1,3154 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + + +#include +#include "typedef.h" +#include +#include "options.h" +#include "rom_com.h" +#include "stat_dec.h" +#include "prot_fx1.h" +#include "prot_fx2.h" +#include "basop_util.h" +#include "rom_basop_util.h" + + +/******************************** +* External tables * +********************************/ + +extern const Word16 T_DIV_L_Frame[]; /* format: 0Q15 * 2^-7 */ + +const Word16 maxN_37bits = FD_CNG_maxN_37bits; +const Word16 maxC_37bits = FD_CNG_maxC_37bits; +const Word16 stages_37bits = FD_CNG_stages_37bits; +/* + createFdCngDec + + Parameters: + + hFdCngDec i/0 : pointer to cng decoder structure + + Function: + create an instance of type FD_CNG +*/ +ivas_error createFdCngDec (HANDLE_FD_CNG_DEC *hFdCngDec) +{ + HANDLE_FD_CNG_DEC hs; + ivas_error error; + error = IVAS_ERR_OK; + + /* Allocate memory */ + hs = (HANDLE_FD_CNG_DEC)count_malloc(sizeof (FD_CNG_DEC)); + + if (hs == NULL) + { + return IVAS_ERROR(IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for FD CNG DEC structure"); + } + if ((error = createFdCngCom(&(hs->hFdCngCom))) != IVAS_ERR_OK) + { + return error; + } + + *hFdCngDec = hs; + return error; +} + +void initFdCngDec( + DEC_CORE_HANDLE st, /* i/o: decoder state structure */ + Word16 scale +) +{ + /* Initialize common */ + HANDLE_FD_CNG_DEC hFdCngDec; + + hFdCngDec = st->hFdCngDec_fx; + + initFdCngCom( hFdCngDec->hFdCngCom, scale ); + set16_fx( hFdCngDec->olapBufferAna, 0, 320 ); + hFdCngDec->hFdCngCom->olapBufferAna = hFdCngDec->olapBufferAna; + move16(); + set16_fx( hFdCngDec->olapBufferSynth2, 0, FFTLEN ); + hFdCngDec->hFdCngCom->olapBufferSynth2 = hFdCngDec->olapBufferSynth2; + move16(); + + /* Set some counters and flags */ + + hFdCngDec->flag_dtx_mode = 0; + move16(); + hFdCngDec->lp_noise = -167772160l/*-20.f Q23*/; /* format: Q8.24 */ + hFdCngDec->lp_speech = 209715200l/* 25.f Q23*/; /* format: Q8.24 */ + + /* Initialization of the noise estimation algorithm */ + + set32_fx( hFdCngDec->bandNoiseShape, 0, FFTLEN2 ); + set16_fx( &hFdCngDec->bandNoiseShape_exp, 0, 1); + + set32_fx (hFdCngDec->partNoiseShape, 0, NPART ); + set16_fx( &hFdCngDec->partNoiseShape_exp, 0, 1); + + set32_fx( hFdCngDec->msPeriodog, 0, NPART_SHAPING ); + set16_fx( &hFdCngDec->msPeriodog_exp, 0, 1); + + set32_fx( hFdCngDec->msAlpha, 0, NPART_SHAPING ); + + set32_fx( hFdCngDec->msBminWin, 0, NPART_SHAPING ); + + set32_fx( hFdCngDec->msBminSubWin, 0, NPART_SHAPING ); + + set16_fx( hFdCngDec->msPsd, 0, NPART_SHAPING ); + set16_fx( hFdCngDec->msNoiseFloor, 0, NPART_SHAPING ); + + set32_fx( hFdCngDec->msNoiseEst, 0, NPART_SHAPING ); + set16_fx( &hFdCngDec->msNoiseEst_exp, 0, 1); + + set32_fx( hFdCngDec->msMinBuf, 2147483647l/*1.0 Q31*/, MSNUMSUBFR*NPART_SHAPING ); + + set32_fx( hFdCngDec->msCurrentMin, 2147483647l/*1.0 Q31*/, NPART_SHAPING ); + + set32_fx( hFdCngDec->msCurrentMinOut, 2147483647l/*1.0 Q31*/, NPART_SHAPING ); + + set32_fx( hFdCngDec->msCurrentMinSubWindow, 2147483647l/*1.0 Q31*/, NPART_SHAPING ); + + set16_fx( hFdCngDec->msLocalMinFlag, 0, NPART_SHAPING ); + set16_fx( hFdCngDec->msNewMinFlag, 0, NPART_SHAPING ); + + set16_fx( hFdCngDec->msPsdFirstMoment, 0, NPART_SHAPING ); + + set32_fx( hFdCngDec->msPsdSecondMoment, 0, NPART_SHAPING ); + set16_fx( hFdCngDec->msPeriodogBuf, 0, MSBUFLEN*NPART_SHAPING ); + + hFdCngDec->msPeriodogBufPtr = 0; + move16(); + + set16_fx( hFdCngDec->msLogPeriodog, 0, NPART_SHAPING ); + set16_fx( hFdCngDec->msLogNoiseEst, 0, NPART_SHAPING ); + + set16_fx( hFdCngDec->psize_shaping, 0, NPART_SHAPING ); + move16(); + hFdCngDec->nFFTpart_shaping = 0; +#ifdef IVAS_CODE_CNG + set_f(hFdCngDec->hFdCngCom->sidNoiseEstLp, 0.0f, NPART); + + set_f(hFdCngDec->smoothed_psd, 0.0f, L_FRAME16k); + set_f(hFdCngDec->msPeriodog_ST, 0.0f, NPART_SHAPING); + + hFdCngDec->ms_last_inactive_bwidth = NB; + hFdCngDec->ms_cnt_bw_up = 0; + + hFdCngDec->cna_LR_LT = 0.5f; + hFdCngDec->cna_ILD_LT = 0.0f; + hFdCngDec->first_cna_noise_updated = 0; + hFdCngDec->first_cna_noise_update_cnt = 0; + hFdCngDec->cna_nbands = 6; + mvs2s(cna_init_bands, hFdCngDec->cna_band_limits, MAX_CNA_NBANDS + 1); + hFdCngDec->cna_act_fact = 1.0f; + hFdCngDec->cna_rescale_fact = 0.0f; + hFdCngDec->cna_seed = 5687; + set_zero(hFdCngDec->cna_cm, STEREO_DFT_BAND_MAX); + set_zero(hFdCngDec->cna_g_state, STEREO_DFT_BAND_MAX); + + st->CNG_mode = -1; + mvr2r(st->lsp_old, st->lspCNG, M); +#endif + return; + +} + +/* + configureFdCngDec + + Parameters: + + hs i/o: Contains the variables related to the FD-based CNG process + numSlots i : Number of time slots in CLDFB matrix + numCoreBands i : Number of core bands + regularStopBand i : Number of CLDFB bands to be considered + CLDFBscale i : cldfb scale factor + + Function: + configure FD_CNG + + Returns: + void +*/ +void configureFdCngDec ( + HANDLE_FD_CNG_DEC hFdCngDec, /* i/o: Contains the variables related to the CLDFB-based CNG process */ + Word16 bwidth, + Word32 total_brate, + Word16 L_frame, + const Word16 Last_L_frame, + const Word16 element_mode + ) +{ + Word16 j, stopBandFR; + HANDLE_FD_CNG_COM hsCom = hFdCngDec->hFdCngCom; + + + hsCom->CngBandwidth = bwidth; + IF ( EQ_16( hsCom->CngBandwidth, FB )) + { + hsCom->CngBandwidth = SWB; + } + test(); + if ( total_brate != FRAME_NO_DATA && NE_32(total_brate, SID_2k40)) + { + hsCom->CngBitrate = total_brate; + move32(); + } + ELSE IF (EQ_32(hsCom->CngBitrate, -1 )) + { + /* set minimum active CBR bitrate if CngBitrate is uninitialized */ + hsCom->CngBitrate = ACELP_7k20; + IF (GT_16(element_mode, EVS_MONO)) + { + hsCom->CngBitrate = IVAS_13k2; + move32(); + } + move32(); + } + + /* FD-CNG config for MDCT-Stereo is always the same (since for > 48 kbps only) */ + /* This may need adjustment in the future if 2TC DTX for some mode uses MDCT-Stereo DTX for lower bitrates too */ + IF (EQ_16(element_mode, IVAS_CPE_MDCT)) + { + hsCom->CngBitrate = IVAS_48k; + move32(); + } + + hsCom->numSlots = 16; + move16(); + + /* NB configuration */ + IF ( bwidth == NB ) + { + hsCom->FdCngSetup = FdCngSetup_nb; + hsCom->numCoreBands = 16; + move16(); + hsCom->regularStopBand = 16; + move16(); + } + + /* WB configuration */ + ELSE IF ( EQ_16(bwidth, WB)) + { + /* FFT 6.4kHz, no CLDFB */ + test(); + test(); + IF ( LE_32(hsCom->CngBitrate, ACELP_8k00) + && EQ_16(L_frame,L_FRAME) + ) + { + hsCom->FdCngSetup = FdCngSetup_wb1; + hsCom->numCoreBands = 16; + move16(); + hsCom->regularStopBand = 16; + move16(); + } + /* FFT 6.4kHz, CLDFB 8.0kHz */ + ELSE IF ( LE_32(hsCom->CngBitrate, ACELP_13k20) + || EQ_16(L_frame,L_FRAME) + ) + { + hsCom->FdCngSetup = FdCngSetup_wb2; + hsCom->numCoreBands = 16; + move16(); + hsCom->regularStopBand = 20; + move16(); + IF ( + EQ_16(L_frame,L_FRAME16k) + ) + { + hsCom->FdCngSetup = FdCngSetup_wb2; + hsCom->numCoreBands = 20; + move16(); + hsCom->regularStopBand = 20; + move16(); + hsCom->FdCngSetup.fftlen = 640; + move16(); + hsCom->FdCngSetup.stopFFTbin = 256; + move16(); + } + } + /* FFT 8.0kHz, no CLDFB */ + ELSE + { + hsCom->FdCngSetup = FdCngSetup_wb3; + hsCom->numCoreBands = 20; + move16(); + hsCom->regularStopBand = 20; + move16(); + + } + + } + + /* SWB/FB configuration */ + ELSE + { + /* FFT 6.4kHz, CLDFB 14kHz */ + IF ( + EQ_16(L_frame,L_FRAME) + ) + { + hsCom->FdCngSetup = FdCngSetup_swb1; + hsCom->numCoreBands = 16; + move16(); + hsCom->regularStopBand = 35; + move16(); + } + /* FFT 8.0kHz, CLDFB 16kHz */ + ELSE + { + hsCom->FdCngSetup = FdCngSetup_swb2; + hsCom->numCoreBands = 20; + move16(); + hsCom->regularStopBand = 40; + move16(); + test(); + IF(EQ_16(Last_L_frame, L_FRAME) && EQ_16(element_mode, IVAS_CPE_DFT)) + { + hsCom->regularStopBand = 35; + move16(); + } + } + } + hsCom->fftlen = hsCom->FdCngSetup.fftlen; + move16(); + hsCom->stopFFTbin = hsCom->FdCngSetup.stopFFTbin; + move16(); + + /* Configure the SID quantizer and the Confort Noise Generator */ + + hsCom->startBand = 2; + move16(); + hsCom->stopBand = add( hsCom->FdCngSetup.sidPartitions[hsCom->FdCngSetup.numPartitions-1], 1 ); + initPartitions(hsCom->FdCngSetup.sidPartitions, hsCom->FdCngSetup.numPartitions, hsCom->startBand, hsCom->stopBand, hsCom->part, + &hsCom->npart, hsCom->midband, hsCom->psize, hsCom->psize_norm, &hsCom->psize_norm_exp, hsCom->psize_inv, 0); + + hsCom->nFFTpart = 21; + move16(); + if ( EQ_16(hsCom->stopFFTbin, 256)) + { + hsCom->nFFTpart = 20; + move16(); + } + if ( EQ_16(hsCom->stopFFTbin, 160)) + { + hsCom->nFFTpart = 17; + move16(); + } + + hsCom->nCLDFBpart = sub( hsCom->npart, hsCom->nFFTpart ); + FOR(j=0; jnCLDFBpart; j++) + { + hsCom->CLDFBpart[j] = sub( hsCom->part[j+hsCom->nFFTpart], (hsCom->stopFFTbin-hsCom->startBand) ); + move16(); + hsCom->CLDFBpsize_inv[j] = hsCom->psize_inv[j+hsCom->nFFTpart]; + move16(); + } + + stopBandFR = 1000/25; + if ( GT_16(stopBandFR, hsCom->stopFFTbin)) + { + stopBandFR = hsCom->stopFFTbin; + move16(); + } + initPartitions(hsCom->FdCngSetup.shapingPartitions, hsCom->FdCngSetup.numShapingPartitions, + hsCom->startBand, hsCom->stopFFTbin, hFdCngDec->part_shaping, &hFdCngDec->npart_shaping, hFdCngDec->midband_shaping, + hFdCngDec->psize_shaping, hFdCngDec->psize_shaping_norm, &hFdCngDec->psize_shaping_norm_exp, hFdCngDec->psize_inv_shaping, + stopBandFR ); + hFdCngDec->nFFTpart_shaping = hFdCngDec->npart_shaping; + move16(); + + SWITCH (hsCom->fftlen) + { + case 512: + hsCom->fftlenShift = 8; + move16(); + hsCom->fftlenFac = 32767/*1.0 Q15*/; + move16(); + BREAK; + case 640: + hsCom->fftlenShift = 9; + move16(); + hsCom->fftlenFac = 20480/*0.625 Q15*/; + move16(); + BREAK; + default: + assert(!"Unsupported FFT length for FD-based CNG"); + BREAK; + } + BASOP_getTables( &hsCom->olapWinAna, NULL, NULL, shr(hsCom->fftlen, 1)); + BASOP_getTables( &hsCom->olapWinSyn, NULL, NULL, shr(hsCom->fftlen, 2)); + hsCom->frameSize = shr(hsCom->fftlen,1); + +} + + +/* + deleteFdCngDec + + Parameters: + + hFdCngDec i/0 : pointer to cng decoder structure + + Function: + delete the instance of type FD_CNG + + Returns: + void +*/ +void deleteFdCngDec (HANDLE_FD_CNG_DEC *hFdCngDec) +{ + HANDLE_FD_CNG_DEC hsDec = *hFdCngDec; + + IF ( hsDec != NULL ) + { + deleteFdCngCom (&(hsDec->hFdCngCom)); + count_free(hsDec); + *hFdCngDec = NULL; + } +} + + +/* + ApplyFdCng + + Parameters: + + timeDomainInput, i : pointer to time domain input + cldfbBufferReal i/o: real part of the CLDFB buffer + cldfbBufferImag i/o: imaginary part of the CLDFB buffer + cldfbBufferScale o : pointer to the scalefactor for real and imaginary part of the CLDFB buffer + st i/o: pointer to FD_CNG structure containing all buffers and variables + m_frame_type i : type of frame at the decoder side + stcod i : pointer to Coder_State structure + st i : pointer to Decoder_State structure + bitrate i : bitrate + concealWholeFrame i : binary flag indicating frame loss + + Function: + apply the CLDFB-based CNG at the decoder + + Returns: + error +*/ +Word16 ApplyFdCng ( + Word16 *timeDomainInput, /* i : pointer to time domain input */ + Word16 Q, +#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT + Word16* powerSpectrum, +#endif + Word32 **cldfbBufferReal, /* i/o: real part of the CLDFB buffer */ + Word32 **cldfbBufferImag, /* i/o: imaginary part of the CLDFB buffer */ + Word16 *cldfbBufferScale, /* o : pointer to the scalefactor for real and imaginary part of the CLDFB buffer */ + Decoder_State *st, + const Word16 concealWholeFrame, /* i : binary flag indicating frame loss */ + Word16 is_music + ) +{ + Word16 j, k, nBins; + Word16 s, s1, s2, num, denom; + Word32 *cngNoiseLevel; + Word16 *cngNoiseLevel_exp; + Word32 L_tmp; + Word16 L_tmp_exp; + Word16 facTab[NPART]; + Word16 facTabExp[NPART]; + Word16 tmp_loop; + Word32 L_c; + Word16 lsp_cng[M]; + HANDLE_FD_CNG_DEC hFdCngDec; + HANDLE_FD_CNG_COM hFdCngCom; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; + Flag Carry = 0; +#endif +#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT + int16_t L_frame, last_L_frame; + int32_t sr_core; + + PMT("Fix point code missing for IVAS_CODE_CNG_FIX185_PLC_FADEOUT") + /* limit L_frame and core fs values for MDCT-Stereo modes which can have higher core sampling than 16kHz, but use a downsampled buffer */ + L_frame = min(st->L_frame, L_FRAME16k); + last_L_frame = min(st->last_L_frame, L_FRAME16k); + sr_core = min(st->sr_core, INT_FS_16k); +#endif + + hFdCngDec = st->hFdCngDec_fx; + hFdCngCom = hFdCngDec->hFdCngCom; + + + if(EQ_16(hFdCngCom->frame_type_previous,ACTIVE_FRAME)) + { + hFdCngCom->inactive_frame_counter = 0; + move16(); + } + IF (EQ_16(st->element_mode, IVAS_CPE_TD)) + { + hFdCngDec->flag_dtx_mode = hFdCngDec->flag_dtx_mode || st->first_CNG; + test(); move16(); + } + cngNoiseLevel = hFdCngCom->cngNoiseLevel; + cngNoiseLevel_exp = &hFdCngCom->cngNoiseLevelExp; + move16(); move16(); + nBins = sub(hFdCngCom->stopFFTbin,hFdCngCom->startBand); + + SWITCH ( st->m_frame_type ) + { + case ACTIVE_FRAME: + + /************************** + * ACTIVE_FRAME at DECODER * + **************************/ + + hFdCngCom->inactive_frame_counter = 0; + move16(); + hFdCngCom->sid_frame_counter = 0; + move16(); + + /* set noise estimation inactive during concealment, as no update with noise generated by concealment should be performed. */ + /* set noise estimation inactive during concealment, no update with noise generated by concealment should be performed. */ + + test();test();test();test();test();test(); + test();test();test();test(); +#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT + if (concealWholeFrame == 0 && + (timeDomainInput == NULL || + (*timeDomainInput(-FLT_MAX) && + *(timeDomainInput + hFdCngCom->frameSize - 1) < FLT_MAX && + *(timeDomainInput + hFdCngCom->frameSize - 1) > (-FLT_MAX))) && + ((((st->element_mode != IVAS_CPE_TD && st->element_mode != IVAS_CPE_DFT && hFdCngDec->flag_dtx_mode) || !st->VAD) && + !(st->cng_type == LP_CNG && hFdCngDec->flag_dtx_mode) && (is_music == 0)) || + (st->element_mode == IVAS_CPE_TD)) && + (!st->BER_detect)) +#else + IF( + (concealWholeFrame == 0) && + (*timeDomainInput < MAXVAL_WORD16) && (*timeDomainInput > MINVAL_WORD16) && (*(timeDomainInput+hFdCngCom->frameSize-1) < MAXVAL_WORD16) && (*(timeDomainInput+hFdCngCom->frameSize-1) > MINVAL_WORD16) + && ( ((hFdCngDec->flag_dtx_mode == 0) && (st->VAD != 0)) == 0 ) + && ( ((st->cng_type == LP_CNG) && (hFdCngDec->flag_dtx_mode != 0)) == 0) + && ( is_music == 0 ) + && (st->BER_detect == 0) + ) +#endif + { + /* Perform noise estimation at the decoder */ +#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT + perform_noise_estimation_dec(timeDomainInput, powerSpectrum, hFdCngDec, st->element_mode, st->bwidth, L_frame, last_L_frame, st->last_core_brate, st->VAD); +#else + perform_noise_estimation_dec (timeDomainInput, Q, hFdCngDec); +#endif + + /* Update the shaping parameters */ + test(); + IF (NE_16(st->element_mode, IVAS_CPE_TD) && NE_16(st->element_mode, IVAS_CPE_DFT)) + { + scalebands(hFdCngDec->msNoiseEst, hFdCngDec->part_shaping, hFdCngDec->nFFTpart_shaping, hFdCngDec->midband_shaping, hFdCngDec->nFFTpart_shaping, nBins, hFdCngDec->bandNoiseShape,1 ); + } + hFdCngDec->bandNoiseShape_exp = hFdCngDec->msNoiseEst_exp; + move16(); + + + /* Update CNG levels */ + test(); + IF ( hFdCngDec->flag_dtx_mode != 0 && st->cng_type == FD_CNG ) + { + /* This needs to be done only once per inactive phase */ + bandcombinepow ( + hFdCngDec->bandNoiseShape, + hFdCngDec->bandNoiseShape_exp, + nBins, + hFdCngCom->part, + hFdCngCom->nFFTpart, + hFdCngCom->psize_inv, + hFdCngDec->partNoiseShape, + &hFdCngDec->partNoiseShape_exp + ); + + + j = 0; + move16(); + s2 = -(WORD32_BITS-1); + move16(); + FOR (k=0; k < hFdCngCom->nFFTpart; k++) + { + assert(hFdCngDec->partNoiseShape[k]>=0); + assert(hFdCngCom->sidNoiseEst[k]>=0); + + /* add DELTA as it is done in FLC version, in order to avoid num > denom */ + facTab[k] = 0; + move16(); + IF ( hFdCngDec->partNoiseShape[k] != 0) + { + s1 = norm_l(hFdCngCom->sidNoiseEst[k]); + L_tmp = L_shl(hFdCngCom->sidNoiseEst[k], s1); + L_tmp_exp = sub(hFdCngCom->sidNoiseEstExp, s1); + L_tmp = BASOP_Util_Add_Mant32Exp(L_tmp, L_tmp_exp, DELTA_MANTISSA_W32, DELTA_EXPONENT, &L_tmp_exp); + L_tmp = L_shr(L_tmp, 1); + s = add(L_tmp_exp, 1); + num = extract_h(L_tmp); + + s1 = norm_l(hFdCngDec->partNoiseShape[k]); + L_tmp = L_shl(hFdCngDec->partNoiseShape[k], s1); + L_tmp_exp = sub(hFdCngDec->partNoiseShape_exp, s1); + L_tmp = BASOP_Util_Add_Mant32Exp(L_tmp, L_tmp_exp, DELTA_MANTISSA_W32, DELTA_EXPONENT, &L_tmp_exp); + s = sub(s, L_tmp_exp); + denom = extract_h(L_tmp); + + facTab[k] = div_s(num,denom); + move16(); + facTabExp[k] = s; + move16(); + } + /* Set unique exponent, if mantissa is equal to zero */ + if (facTab[k] == 0) + { + facTabExp[k] = -(WORD32_BITS-1); + move16(); + } + s2 = s_max(s2,facTabExp[k]); + } + + FOR (k=0; k < hFdCngCom->nFFTpart; k++) + { + s = sub(facTabExp[k],s2); + s = s_max(s_min(s,WORD32_BITS-1),-(WORD32_BITS-1)); + FOR ( ; j <= hFdCngCom->part[k]; j++) + { + cngNoiseLevel[j] = L_shl(Mpy_32_16_1(hFdCngDec->bandNoiseShape[j],facTab[k]),s); + move32(); + } + } + + /* adapt scaling for rest of the buffer */ + IF (NE_16(s2,-(WORD32_BITS-1))) + { + s = sub(*cngNoiseLevel_exp,add(hFdCngDec->bandNoiseShape_exp,s2)); + FOR ( ; k < hFdCngCom->npart; k++) + { + FOR( ; j <= hFdCngCom->part[k]; j++) + { + cngNoiseLevel[j] = L_shl(cngNoiseLevel[j],s); + move32(); + } + } + + *cngNoiseLevel_exp = add(hFdCngDec->bandNoiseShape_exp,s2); + move16(); + } + } + ELSE + { + /* This sets the new CNG levels until a SID update overwrites it */ + test(); test(); test(); + IF(!(EQ_16(st->element_mode, IVAS_CPE_TD)) || (EQ_16(st->element_mode, IVAS_CPE_TD) && !hFdCngDec->flag_dtx_mode && !st->VAD)) + { + Copy32(hFdCngDec->bandNoiseShape,cngNoiseLevel,nBins); + *cngNoiseLevel_exp = hFdCngDec->bandNoiseShape_exp; + move16(); + } + } +#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT + if (st->element_mode == IVAS_CPE_MDCT && timeDomainInput == NULL) + { + st->hTcxDec->CngLevelBackgroundTrace_bfi = sqrtf(sum_f(cngNoiseLevel, hFdCngCom->stopFFTbin - hFdCngCom->startBand) / NORM_MDCT_FACTOR); + } + else + { + st->hTcxDec->CngLevelBackgroundTrace_bfi = (float)sqrt((sum_f(cngNoiseLevel, hFdCngCom->stopFFTbin - hFdCngCom->startBand) / 2 * hFdCngCom->fftlen) / L_frame); + } +#endif + /*st->cngTDLevel = (float)sqrt( (sumFLOAT(cngNoiseLevel, hFdCngCom->stopFFTbin - hFdCngCom->startBand) / 2 * hFdCngCom->fftlen) / st->Mode2_L_frame);*/ + tmp_loop = sub(hFdCngCom->stopFFTbin , hFdCngCom->startBand); + L_tmp = L_deposit_h(0); + L_c = L_deposit_h(0); + FOR(j = 0 ; j < tmp_loop; j++) + { + + Carry = 0; +#ifdef BASOP_NOGLOB + L_tmp = L_add_co(L_tmp, *(cngNoiseLevel + j), &Carry, &Overflow); +#else + L_tmp = L_add_c(L_tmp,*(cngNoiseLevel+j)); +#endif + Overflow = 0; + + if(*(cngNoiseLevel+j) < 0) + { + L_c = L_msuNs(L_c,0,0); + } + if(*(cngNoiseLevel+j) >= 0) + { +#ifdef BASOP_NOGLOB + L_c = L_macNs_co(L_c, 0, 0, &Carry, &Overflow); +#else + L_c = L_macNs(L_c,0,0); +#endif + } + } + L_tmp = norm_llQ31(L_c,L_tmp,&L_tmp_exp); + L_tmp_exp = sub(add(L_tmp_exp,*cngNoiseLevel_exp),1); + + L_tmp = Mpy_32_16_1(L_tmp,hFdCngCom->fftlen); /*Q16*/ + + L_tmp = Mpy_32_16_1(L_tmp,T_DIV_L_Frame[L_shl(L_mac(-28000,st->L_frame,95),1-15)]);/*Q16,exp -7*/ + L_tmp_exp = add(L_tmp_exp,-7); /*->Q16, L_tmp_exp */ + L_tmp_exp = add(L_tmp_exp,31-16); /*->Q31, L_tmp_exp*/ + +#ifdef BASOP_NOGLOB + st->cngTDLevel = round_fx_sat(Sqrt32(L_tmp, &L_tmp_exp)); +#else + st->cngTDLevel = round_fx(Sqrt32(L_tmp, &L_tmp_exp)); +#endif + st->cngTDLevel_e = L_tmp_exp; + move16(); + + + } + ELSE IF (EQ_16(st->element_mode, IVAS_CPE_TD) || EQ_16(st->element_mode, IVAS_CPE_DFT)) + { + IF (hFdCngCom->active_frame_counter > 0) + { + /* Perform noise estimation in active frames in the decoder for downward updates */ +#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT + perform_noise_estimation_dec(timeDomainInput, powerSpectrum, hFdCngDec, st->element_mode, st->bwidth, L_frame, last_L_frame, st->last_core_brate, st->VAD); +#else + perform_noise_estimation_dec(timeDomainInput, Q, hFdCngDec); +#endif + } + } + test(); + test(); + L_tmp = 0; + FOR( j=hFdCngCom->startBand; jstopFFTbin; j++ ) + { + L_tmp = L_add(L_tmp,L_shr(cngNoiseLevel[j],16)); + } + L_tmp_exp = add(*cngNoiseLevel_exp,16); +#ifdef BASOP_NOGLOB + IF(EQ_16(concealWholeFrame, 1) && EQ_16(st->nbLostCmpt, 1) && (L_shl_o(L_tmp, L_tmp_exp, &Overflow) > 21474836 /*0.01f Q31*/)) +#else + IF (EQ_16(concealWholeFrame,1)&&EQ_16(st->nbLostCmpt,1)&&(L_shl(L_tmp,L_tmp_exp)>21474836 /*0.01f Q31*/)) +#endif + { + /* update isf cng estimate for concealment. Do that during concealment, in order to avoid addition clean channel complexity*/ +#ifndef IVAS_CODE_CNG_FIX185_PLC_FADEOUT + lpc_from_spectrum(hFdCngCom, hFdCngCom->startBand, hFdCngCom->stopFFTbin, 0); + E_LPC_a_lsp_conversion( hFdCngCom->A_cng, lsp_cng, st->lspold_cng, M ); + Copy( lsp_cng, st->lspold_cng, M); + + lsp2lsf_fx( lsp_cng, st->lsf_cng, M, st->sr_core ); +#else + if (st->element_mode == IVAS_CPE_MDCT && st->core != ACELP_CORE) + { + float scf[SNS_NPTS]; + float scf_int[FDNS_NPTS]; + float whitenend_noise_shape[L_FRAME16k]; + int16_t inc, start_idx, stop_idx; + float* noiseLevelPtr; + + + inc = (st->core > TCX_20) ? 2 : 1; + start_idx = hFdCngCom->startBand / inc; + stop_idx = L_frame / inc; + noiseLevelPtr = cngNoiseLevel; + + set_zero(whitenend_noise_shape, start_idx); + for (j = start_idx; j < stop_idx; j++, noiseLevelPtr += inc) + { + whitenend_noise_shape[j] = *noiseLevelPtr; + } + if (st->core == TCX_20_CORE) + { + st->hTonalMDCTConc->psychParams = &st->hTonalMDCTConc->psychParamsTCX20; + } + else + { + st->hTonalMDCTConc->psychParams = &st->hTonalMDCTConc->psychParamsTCX10; + } + + sns_compute_scf(whitenend_noise_shape, st->hTonalMDCTConc->psychParams, L_frame, scf); + sns_interpolate_scalefactors(scf_int, scf, ENC); + sns_interpolate_scalefactors(st->hTonalMDCTConc->scaleFactorsBackground, scf, DEC); + sns_shape_spectrum(whitenend_noise_shape, st->hTonalMDCTConc->psychParams, scf_int, L_frame); + + mvr2r(whitenend_noise_shape + start_idx, cngNoiseLevel, stop_idx - start_idx); + wmops_sub_end(); + } + else if (st->element_mode != IVAS_CPE_MDCT) + { + lpc_from_spectrum(hFdCngCom, hFdCngCom->startBand, hFdCngCom->stopFFTbin, 0.f); + a2lsp_stab(hFdCngCom->A_cng, lsp_cng, st->lspold_cng); + mvr2r(lsp_cng, st->lspold_cng, M); + lsp2lsf(lsp_cng, st->lsf_cng, M, sr_core); + } + +#endif + st->plcBackgroundNoiseUpdated = 1; + move16(); + } + BREAK; + + case SID_FRAME: + + hFdCngDec->flag_dtx_mode = 1; + move16(); + /* no break */ + + case ZERO_FRAME: + + test(); + IF(st!=NULL && st->cng_type==LP_CNG) + { + /* Perform noise estimation on inactive phase at the decoder */ +#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT + perform_noise_estimation_dec(timeDomainInput, powerSpectrum, hFdCngDec, st->element_mode, st->bwidth, L_frame, last_L_frame, st->last_core_brate, st->VAD); +#else + perform_noise_estimation_dec(timeDomainInput, Q, hFdCngDec); +#endif + /* Update the shaping parameters */ + + IF (NE_16(st->element_mode, IVAS_CPE_TD) && NE_16(st->element_mode, IVAS_CPE_DFT)) + { + scalebands(hFdCngDec->msNoiseEst, hFdCngDec->part_shaping, hFdCngDec->nFFTpart_shaping, hFdCngDec->midband_shaping, hFdCngDec->nFFTpart_shaping, hFdCngCom->stopFFTbin - hFdCngCom->startBand, hFdCngDec->bandNoiseShape, 1); + } + hFdCngDec->bandNoiseShape_exp = hFdCngDec->msNoiseEst_exp; + move16(); + /* This sets the new CNG levels until a SID update overwrites it */ + Copy32(hFdCngDec->bandNoiseShape, cngNoiseLevel, hFdCngCom->stopFFTbin-hFdCngCom->startBand); /* This sets the new CNG levels until a SID update overwrites it */ + *cngNoiseLevel_exp = hFdCngDec->bandNoiseShape_exp; + move16(); +#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT + st->cngTDLevel = (float)sqrt((sum_f(cngNoiseLevel, hFdCngCom->stopFFTbin - hFdCngCom->startBand) / 2 * hFdCngCom->fftlen) / L_frame); +#else + /*st->cngTDLevel = (float)sqrt( (sumFLOAT(cngNoiseLevel, hFdCngCom->stopFFTbin - hFdCngCom->startBand) / 2 * hFdCngCom->fftlen) / st->Mode2_L_frame);*/ + tmp_loop = sub(hFdCngCom->stopFFTbin , hFdCngCom->startBand); + L_tmp = L_deposit_h(0); + L_c = L_deposit_h(0); + FOR(j = 0 ; j < tmp_loop; j++) + { + + Carry = 0; +#ifdef BASOP_NOGLOB /* Critical Carry/Overflow */ + L_tmp = L_add_co(L_tmp,*(cngNoiseLevel+j), &Carry, &Overflow); + Overflow = 0; + + if(*(cngNoiseLevel+j) < 0) + { + L_c = L_msuNs_co(L_c,0,0, &Carry, &Overflow); + } + if(*(cngNoiseLevel+j) >= 0) + { + L_c = L_macNs_co(L_c,0,0, &Carry, &Overflow); + } +#else + L_tmp = L_add_c(L_tmp,*(cngNoiseLevel+j)); + Overflow = 0; + + if(*(cngNoiseLevel+j) < 0) + { + L_c = L_msuNs(L_c,0,0); + } + if(*(cngNoiseLevel+j) >= 0) + { + L_c = L_macNs(L_c,0,0); + } +#endif + } + L_tmp = norm_llQ31(L_c,L_tmp,&L_tmp_exp); + L_tmp_exp = sub(add(L_tmp_exp,*cngNoiseLevel_exp),1); + + L_tmp = Mpy_32_16_1(L_tmp,hFdCngCom->fftlen); /*Q16*/ + + L_tmp = Mpy_32_16_1(L_tmp,T_DIV_L_Frame[L_shl(L_mac(-28000,st->L_frame,95),1-15)]);/*Q16,exp -7*/ + L_tmp_exp = add(L_tmp_exp,-7); /*->Q16, L_tmp_exp */ + L_tmp_exp = add(L_tmp_exp,31-16); /*->Q31, L_tmp_exp*/ + +#ifdef BASOP_NOGLOB /* Critical Carry/Overflow */ + st->cngTDLevel = round_fx_o(Sqrt32(L_tmp, &L_tmp_exp), &Overflow); +#else + st->cngTDLevel = round_fx(Sqrt32(L_tmp, &L_tmp_exp)); +#endif + st->cngTDLevel_e = L_tmp_exp; + move16(); +#endif + BREAK; + } + hFdCngCom->inactive_frame_counter = add(hFdCngCom->inactive_frame_counter,1); + move16(); + + /************************************* + * SID_FRAME or ZERO_FRAME at DECODER * + *************************************/ + + /* Detect first non-active frame */ + IF ( EQ_16(hFdCngCom->inactive_frame_counter,1)) + { + /* Compute the fine spectral structure of the comfort noise shape using the decoder-side noise estimates */ + bandcombinepow ( + hFdCngDec->bandNoiseShape, + hFdCngDec->bandNoiseShape_exp, + nBins, + hFdCngCom->part, + hFdCngCom->nFFTpart, + hFdCngCom->psize_inv, + hFdCngDec->partNoiseShape, + &hFdCngDec->partNoiseShape_exp + ); + IF (EQ_16(st->element_mode, IVAS_CPE_DFT)) + { +#ifdef IVAS_CODE_CNG + Copy(hFdCngDec->hFdCngCom->sidNoiseEst, hFdCngDec->hFdCngCom->sidNoiseEstLp, NPART); +#endif + } + } + + IF ( EQ_16(st->m_frame_type,SID_FRAME)) + { + IF ( LT_32(hFdCngCom->msFrCnt_init_counter,L_deposit_l(hFdCngCom->msFrCnt_init_thresh))) + { + /* At initialization, interpolate the bin/band-wise levels from the partition levels */ + scalebands (hFdCngCom->sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, + hFdCngCom->nFFTpart, sub(hFdCngCom->stopBand,hFdCngCom->startBand), cngNoiseLevel,1 ); + *cngNoiseLevel_exp = hFdCngCom->sidNoiseEstExp; + move16(); + } + ELSE + { + if (EQ_16(st->element_mode, IVAS_CPE_DFT)) + { +#ifdef IVAS_CODE_CNG + sidNoiseEst = hFdCngCom->sidNoiseEstLp; +#endif + move16(); + } + /* Interpolate the CLDFB band levels from the SID (partition) levels */ + IF ( GT_16( hFdCngCom->regularStopBand, hFdCngCom->numCoreBands )) + { + scalebands ( hFdCngCom->sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, + hFdCngCom->nFFTpart, sub(hFdCngCom->stopBand,hFdCngCom->startBand), cngNoiseLevel, 0); + + *cngNoiseLevel_exp = hFdCngCom->sidNoiseEstExp; + move16(); + } + + s2 = -(WORD32_BITS-1); + move16(); + /* Shape the SID noise levels in each FFT bin */ + j = 0; + move16(); + FOR (k=0; k < hFdCngCom->nFFTpart ; k++) + { + assert(hFdCngDec->partNoiseShape[k]>=0); + + /* add DELTA as it is done in FLC version, in order to avoid num > denom */ + facTab[k] = 0; + move16(); + IF ( hFdCngDec->partNoiseShape[k] != 0) + { + s1 = norm_l(hFdCngCom->sidNoiseEst[k]); + L_tmp = L_shl(hFdCngCom->sidNoiseEst[k], s1); + L_tmp_exp = sub(hFdCngCom->sidNoiseEstExp, s1); + L_tmp = BASOP_Util_Add_Mant32Exp(hFdCngCom->sidNoiseEst[k], hFdCngCom->sidNoiseEstExp, DELTA_MANTISSA_W32, DELTA_EXPONENT, &L_tmp_exp); + L_tmp = L_shr(L_tmp, 1); + s = add(L_tmp_exp, 1); + num = extract_h(L_tmp); + + s1 = norm_l(hFdCngDec->partNoiseShape[k]); + L_tmp = L_shl(hFdCngDec->partNoiseShape[k], s1); + L_tmp_exp = sub(hFdCngDec->partNoiseShape_exp, s1); + L_tmp = BASOP_Util_Add_Mant32Exp(L_tmp, L_tmp_exp, DELTA_MANTISSA_W32, DELTA_EXPONENT, &L_tmp_exp); + s = sub(s, L_tmp_exp); + denom = extract_h(L_tmp); + + facTab[k] = div_s(num,denom); + move16(); + facTabExp[k] = s; + move16(); + } + /* Set unique exponent, if mantissa is equal to zero */ + if (facTab[k] == 0) + { + facTabExp[k] = -(WORD32_BITS-1); + move16(); + } + s2 = s_max(s2,facTabExp[k]); + } + + FOR (k=0; k < hFdCngCom->nFFTpart; k++) + { + s = sub(facTabExp[k],s2); + s = s_max(s_min(s,WORD32_BITS-1),-(WORD32_BITS-1)); + FOR( ; j <= hFdCngCom->part[k]; j++) + { + cngNoiseLevel[j] = L_shl(Mpy_32_16_1(hFdCngDec->bandNoiseShape[j],facTab[k]),s); + move32(); + } + } + /* adapt scaling for rest of the buffer */ + s = sub(*cngNoiseLevel_exp,add(hFdCngDec->bandNoiseShape_exp,s2)); + FOR ( ; k < hFdCngCom->npart; k++) + { + FOR( ; j <= hFdCngCom->part[k]; j++) + { + cngNoiseLevel[j] = L_shl(cngNoiseLevel[j],s); + move32(); + } + } + *cngNoiseLevel_exp = add(hFdCngDec->bandNoiseShape_exp,s2); + move16(); + } + } +#ifdef IVAS_CODE_CNG + else if (st->element_mode == IVAS_CPE_DFT) + { + if (!(hFdCngCom->msFrCnt_init_counter < hFdCngCom->msFrCnt_init_thresh)) + { + sidNoiseEst = hFdCngCom->sidNoiseEstLp; + j = 0; + for (k = 0; k < hFdCngCom->nFFTpart; k++) + { + factor = (sidNoiseEst[k] + DELTA) / (hFdCngDec->partNoiseShape[k] + DELTA); + for (; j <= hFdCngCom->part[k]; j++) + { + cngNoiseLevel[j] = hFdCngDec->bandNoiseShape[j] * factor; + } + } + } + } +#endif + IF ( EQ_16(st->codec_mode, MODE2)) + { + /* Generate comfort noise during SID or zero frames */ + generate_comfort_noise_dec (cldfbBufferReal, cldfbBufferImag, cldfbBufferScale, st, &(st->Q_exc), 2, -1); + } + + BREAK; + + default: + return -1; + } + + + return 0; +} + + +/* + perform_noise_estimation_dec + + Parameters: + + timeDomainInput, i: pointer to time domain input + bitrate, i: bitrate + st i/o: FD_CNG structure containing all buffers and variables + + Function: + perform noise estimation + + Returns: + void +*/ +void perform_noise_estimation_dec ( + const Word16 *timeDomainInput, /* i: pointer to time domain input */ + const Word16 Q, +#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT + float* power_spectrum, +#endif + HANDLE_FD_CNG_DEC hFdCngDec /* i/o: FD_CNG structure containing all buffers and variables */ +#ifdef IVAS_CODE_CNG + ,const int16_t element_mode, /* i : element mode */ + const int16_t bwidth, /* i : audio bandwidth */ + const int16_t L_frame, /* i : frame length at internal Fs */ + const int16_t last_L_frame, /* i : frame length of the last frame at internal Fs */ + const int32_t last_core_brate, /* i : previous frame core bitrate */ + const int16_t VAD /* i : VAD flag in the decoder */ +#endif + ) +{ + Word16 i, tmp_r, tmp_i, fac, fftBuffer_exp; + Word16 s, len, npart, nFFTpart; + Word16 startBand, stopFFTbin; + + Word16 *part, *psize_inv, *psize_norm; + Word32 tmp, *fftBuffer, *periodog, *ptr_per, *ptr_r, *ptr_i; +#ifdef IVAS_CODE_CNG + PMT("lots of code related to IVAS needs to be done ") +#endif + + + /* pointer initialization */ + periodog = hFdCngDec->hFdCngCom->periodog; + fftBuffer = hFdCngDec->hFdCngCom->fftBuffer; + + part = hFdCngDec->part_shaping; + psize_inv = hFdCngDec->psize_inv_shaping; + psize_norm = hFdCngDec->psize_shaping_norm; + + /* variable initialization */ + startBand = hFdCngDec->hFdCngCom->startBand; + move16(); + stopFFTbin = hFdCngDec->hFdCngCom->stopFFTbin; + move16(); + + npart = hFdCngDec->npart_shaping; + move16(); + nFFTpart = hFdCngDec->nFFTpart_shaping; + move16(); + + /* Perform STFT analysis */ +#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT + IF (!(EQ_16(element_mode, IVAS_CPE_MDCT) && power_spectrum != NULL)) + { + /* Perform STFT analysis */ + AnalysisSTFT(timeDomainInput, Q, fftBuffer, &fftBuffer_exp, hFdCngDec->hFdCngCom); + } +#else + /* Perform STFT analysis */ + AnalysisSTFT (timeDomainInput, Q, fftBuffer, &fftBuffer_exp, hFdCngDec->hFdCngCom); +#endif + fftBuffer_exp = add(fftBuffer_exp,WORD16_BITS-1); +#ifdef IVAS_CODE_CNG + if (element_mode == IVAS_CPE_TD || element_mode == IVAS_CPE_DFT) + { + /* Calculate periodogram (squared magnitude in each FFT bin) */ + if (startBand == 0) + { + (*ptr_per) = fftBuffer[0] * fftBuffer[0]; + ptr_per++; + ptr_r = fftBuffer + 2; + } + else + { + ptr_r = fftBuffer + 2 * startBand; + } + + ptr_i = ptr_r + 1; + + for (; ptr_per < periodog + stopFFTbin - startBand; ptr_per++) + { + (*ptr_per) = (*ptr_r) * (*ptr_r) + (*ptr_i) * (*ptr_i); + ptr_r += 2; + ptr_i += 2; + } + + /* Rescale to get energy/sample: it should be 2*(1/N)*(2/N), parseval relation with 1/N,*2 for nrg computed till Nyquist only, 2/N as windowed samples correspond to half a frame*/ + v_multc(periodog, 4.f / (float)(hFdCngDec->hFdCngCom->fftlen * hFdCngDec->hFdCngCom->fftlen), periodog, stopFFTbin - startBand); + + /* Combine bins of power spectrum into partitions */ + i = 0; + for (p = 0; p < npart; p++) + { + + /* calculate mean over all bins in power partition */ + temp = 0; + for (; i <= part[p]; i++) + { + temp += periodog[i]; + } + msPeriodog[p] = temp * psize_inv[p]; + } + + /* compensate for the loss of variance - don't do when first noise update is not completed yet due to risk of msPeriodog[p] < 0 */ + if (hFdCngDec->first_cna_noise_updated) + { + i = 0; + for (p = 0; p < npart; p++) + { + /* calculate variance over all bins in power partition */ + temp = 0; + for (; i <= part[p]; i++) + { + delta = periodog[i] - msPeriodog[p]; + temp += delta * delta; + } + temp *= psize_inv[p]; + + /* compensate for the loss of variance */ + msPeriodog[p] = (float)(msPeriodog[p] + sqrt(temp) * rand_gauss(&ftemp, &hFdCngDec->cna_seed)); + + if (msPeriodog[p] < 1e-5f) + { + msPeriodog[p] = 1e-5f; + } + } + } + + /* calculate total energy (short-term and long-term) */ + enr_tot = sum_f(msPeriodog, npart) + EPSILON; + enr_tot0 = sum_f(msNoiseEst, npart) + EPSILON; + + /* update short-term periodogram on larger partitions */ + for (p = CNA_ACT_DN_LARGE_PARTITION; p < npart; p++) + { + if (L_frame != last_L_frame || last_core_brate <= SID_2k40) + { + /* core Fs has changed or last frame was SID/NO_DATA -> re-initialize short-term periodogram */ + hFdCngDec->msPeriodog_ST[p] = msPeriodog[p]; + } + else + { + hFdCngDec->msPeriodog_ST[p] = (float)(ST_PERIODOG_FACT * hFdCngDec->msPeriodog_ST[p] + (1 - ST_PERIODOG_FACT) * msPeriodog[p]); + } + } + + /* core Fs has changed -> partitions have changed -> re-calculate long-term periodogram */ + /* part L_FRAME16k L_FRAME */ + /* ... */ + /* [55] 146 146 */ + /* [56] 174 160 */ + /* [57] 210 174 */ + /* [58] 254 190 */ + /* [59] 306 210 */ + /* [60] 317 230 */ + /* [61] 253 */ + + if (last_L_frame == L_FRAME16k && L_frame == L_FRAME) + { + msNoiseEst[61] = msNoiseEst[58]; + msNoiseEst[60] = min(msNoiseEst[58], msNoiseEst[57]); + msNoiseEst[59] = msNoiseEst[57]; + msNoiseEst[58] = msNoiseEst[56]; + msNoiseEst[57] = msNoiseEst[56]; + msNoiseEst[56] = min(msNoiseEst[56], msNoiseEst[55]); + } + else if (last_L_frame == L_FRAME && L_frame == L_FRAME16k) + { + msNoiseEst[56] = min(msNoiseEst[56], msNoiseEst[57]); + msNoiseEst[57] = min(msNoiseEst[58], msNoiseEst[59]); + msNoiseEst[58] = min(msNoiseEst[60], msNoiseEst[61]); + msNoiseEst[59] = 0.0f; + msNoiseEst[60] = 0.0f; + msNoiseEst[61] = 0.0f; + + hFdCngDec->ms_cnt_bw_up = FIRST_CNA_NOISE_UPD_FRAMES; + } + + /* Smooth with IIR filter */ + if (!hFdCngDec->first_cna_noise_updated) + { + if (!VAD) + { + /* background noise update with moving average */ + alpha = 1.0f / (hFdCngDec->first_cna_noise_update_cnt + 1); + for (p = 0; p < npart; p++) + { + msNoiseEst[p] = (1 - alpha) * msNoiseEst[p] + alpha * msPeriodog[p]; + } + + /* check, if we reached the required number of first CNA noise update frames */ + if (hFdCngDec->first_cna_noise_update_cnt < FIRST_CNA_NOISE_UPD_FRAMES - 1) + { + hFdCngDec->first_cna_noise_update_cnt++; + } + else + { + hFdCngDec->first_cna_noise_updated = 1; + if (hFdCngDec->hFdCngCom->msFrCnt_init_counter == 0) + { + hFdCngDec->hFdCngCom->msFrCnt_init_counter = 1; + } + } + } + else + { + hFdCngDec->first_cna_noise_update_cnt = 0; + } + } + else + { + hFdCngDec->hFdCngCom->msFrCnt_init_counter = 1; + if (VAD) + { + /* no updates during active frames except for significant energy drops */ + enr_ratio = enr_tot / enr_tot0; + if (enr_ratio < 0.5f) + { + /* total energy significantly decreases during active frames -> downward update */ + wght = lin_interp(enr_ratio, 0.0f, 0.8f, 0.5f, 0.95f, 1); + for (p = 0; p < npart; p++) + { + if (msPeriodog[p] < msNoiseEst[p]) + { + msNoiseEst[p] = wght * msNoiseEst[p] + (1 - wght) * msPeriodog[p]; + } + } + } + else + { + /* energy significantly decreases in one of the larger partitions during active frames -> downward update */ + for (p = CNA_ACT_DN_LARGE_PARTITION; p < npart; p++) + { + if (hFdCngDec->msPeriodog_ST[p] < msNoiseEst[p]) + { + msNoiseEst[p] = (float)(CNA_ACT_DN_FACT * msNoiseEst[p] + (1 - CNA_ACT_DN_FACT) * hFdCngDec->msPeriodog_ST[p]); + } + } + } + } + else + { + + if (bwidth >= WB && hFdCngDec->ms_last_inactive_bwidth == NB) + { + /* bandwidth increased -> set counter for fast initilization */ + hFdCngDec->ms_cnt_bw_up = FIRST_CNA_NOISE_UPD_FRAMES; + } + hFdCngDec->ms_last_inactive_bwidth = bwidth; + /* update background noise during inactive frames */ + ptr_per = msNoiseEst; + for (p = 0; p < npart; p++) + { + enr = msPeriodog[p]; + alpha = 0.95f; + /* bandwidth increased -> do fast re-initilization */ + if (hFdCngDec->ms_cnt_bw_up > 0 && p > 55) + { + alpha = 1.0f / (hFdCngDec->ms_cnt_bw_up + 1); + } + else if (enr < *ptr_per && part[p] == 1) + { + /* faster downward update for single-bin partitions */ + alpha = 0.8f; + } + else if (enr > 2.0f * (*ptr_per)) + { + /* prevent abrupt upward updates */ + enr = 2.0f * (*ptr_per); + } + + /* IIR smoothing */ + *ptr_per *= alpha; + *ptr_per += (1 - alpha) * enr; + ptr_per++; + } + + if (hFdCngDec->ms_cnt_bw_up > 0) + { + hFdCngDec->ms_cnt_bw_up--; + } + } + } + + mvr2r(msNoiseEst, hFdCngDec->msPsd, npart); + + /* Expand partitions into bins of power spectrum */ + scalebands(msNoiseEst, part, nFFTpart, hFdCngDec->midband_shaping, nFFTpart, stopFFTbin - startBand, hFdCngDec->bandNoiseShape, 1); + + mvr2r(hFdCngDec->bandNoiseShape, &hFdCngDec->smoothed_psd[startBand], stopFFTbin - startBand); + set_zero(&hFdCngDec->smoothed_psd[stopFFTbin], L_FRAME16k - stopFFTbin); + } + else +#endif + { +#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT + if (element_mode == IVAS_CPE_MDCT && power_spectrum != NULL) + { + /* use power spectrum calculated in the MDCT-domain instead of calculating new power spectrum */ + periodog = power_spectrum; + } + else + { + /* Compute the squared magnitude in each FFT bin */ + if (startBand == 0) + { + (*ptr_per) = fftBuffer[0] * fftBuffer[0]; /* DC component */ + ptr_per++; + ptr_r = fftBuffer + 2; + } + else + { + ptr_r = fftBuffer + 2 * startBand; + } + + ptr_i = ptr_r + 1; + + for (; ptr_per < periodog + stopFFTbin - startBand; ptr_per++) + { + (*ptr_per) = (*ptr_r) * (*ptr_r) + (*ptr_i) * (*ptr_i); + ptr_r += 2; + ptr_i += 2; + } + /* Nyquist frequency is discarded */ + + /* Rescale to get energy/sample: it should be 2*(1/N)*(2/N), parseval relation with 1/N,*2 for nrg computed till Nyquist only, 2/N as windowed samples correspond to half a frame*/ + v_multc(periodog, 4.f / (float)(hFdCngDec->hFdCngCom->fftlen * hFdCngDec->hFdCngCom->fftlen), periodog, stopFFTbin - startBand); + } +#else + assert(startBand != 0); + + len = sub(stopFFTbin, startBand); + + s = getScaleFactor32 (&fftBuffer[2*startBand], 2*len); + s = sub(s,1); + + ptr_per = periodog; + IF ( startBand == 0 ) + { + /* DC component */ + tmp_r = extract_h(L_shl(fftBuffer[0],s)); + + tmp = L_mult(tmp_r, tmp_r); + *ptr_per = tmp; + + ptr_per++; + ptr_r = fftBuffer + 2; + len = sub(len, 1); + } + ELSE + { + ptr_r = fftBuffer + shl(startBand, 1); + } + + ptr_i = ptr_r+1; + FOR (i=0; i < len; i++) + { + tmp_r = extract_h(L_shl(*ptr_r,s)); + tmp_i = extract_h(L_shl(*ptr_i,s)); + + tmp = L_mac(L_mult(tmp_r, tmp_r),tmp_i, tmp_i); + *ptr_per = tmp; + + ptr_r += 2; + ptr_i += 2; + ptr_per++; + } + + hFdCngDec->hFdCngCom->periodog_exp = shl(sub(fftBuffer_exp, s), 1); + + /* Rescale */ + assert((hFdCngDec->hFdCngCom->fftlen == 640) || (hFdCngDec->hFdCngCom->fftlen == 512) || (hFdCngDec->hFdCngCom->fftlen == 320)); + + fac = 20972/*0.64 Q15*/; + move16(); + if (EQ_16(hFdCngDec->hFdCngCom->fftlen, 512)) + { + fac = 16384/*0.5 Q15*/; + move16(); + } + + if (EQ_16(hFdCngDec->hFdCngCom->fftlen, 640)) + { + s = 18; + move16(); + } + if (EQ_16(hFdCngDec->hFdCngCom->fftlen, 512)) + { + s = 17; + move16(); + } + if (EQ_16(hFdCngDec->hFdCngCom->fftlen, 320)) + { + s = 16; + move16(); + } + + len = sub(stopFFTbin, startBand); + FOR (i=0; i < len; i++) + { + hFdCngDec->hFdCngCom->periodog[i] = Mpy_32_16_1(hFdCngDec->hFdCngCom->periodog[i], fac); + } + hFdCngDec->hFdCngCom->periodog_exp = add(hFdCngDec->hFdCngCom->periodog_exp, sub(2, s)); +#endif + + /* Adjust to the desired frequency resolution by averaging over spectral partitions for SID transmission */ + bandcombinepow(periodog, hFdCngDec->hFdCngCom->periodog_exp, sub(stopFFTbin, startBand), part, npart, psize_inv, hFdCngDec->msPeriodog, &hFdCngDec->msPeriodog_exp); + + + hFdCngDec->msPeriodog_exp_fft = hFdCngDec->msPeriodog_exp; + move16(); + hFdCngDec->msPeriodog_exp_cldfb = hFdCngDec->msPeriodog_exp; + move16(); + + + /* Compress MS inputs */ + compress_range(hFdCngDec->msPeriodog, hFdCngDec->msPeriodog_exp, hFdCngDec->msLogPeriodog, npart); + + /* Call the minimum statistics routine for noise estimation */ + minimum_statistics ( + npart, + nFFTpart, + psize_norm, + hFdCngDec->msLogPeriodog, + hFdCngDec->msNoiseFloor, + hFdCngDec->msLogNoiseEst, + hFdCngDec->msAlpha, + hFdCngDec->msPsd, + hFdCngDec->msPsdFirstMoment, + hFdCngDec->msPsdSecondMoment, + hFdCngDec->msMinBuf, + hFdCngDec->msBminWin, + hFdCngDec->msBminSubWin, + hFdCngDec->msCurrentMin, + hFdCngDec->msCurrentMinOut, + hFdCngDec->msCurrentMinSubWindow, + hFdCngDec->msLocalMinFlag, + hFdCngDec->msNewMinFlag, + hFdCngDec->msPeriodogBuf, + &(hFdCngDec->msPeriodogBufPtr), + hFdCngDec->hFdCngCom +#ifdef IVAS_CODE_CNG + , DEC, element_mode +#endif + ); + + /* Expand MS outputs */ + expand_range(hFdCngDec->msLogNoiseEst, hFdCngDec->msNoiseEst, &hFdCngDec->msNoiseEst_exp, npart); +} +} + + + +/* + FdCng_decodeSID + + Parameters: + + st i/o: FD_CNG structure containing all buffers and variables + bs_word16 i : Bitstream + amrwb_io i : amr wideband mode + preemph_fac i : preemphase factor + + Function: + decode the FD-CNG bitstream + + Returns: + void +*/ +void FdCng_decodeSID (HANDLE_FD_CNG_COM st, Decoder_State *corest) +{ + Word16 i, N, index; + Word32 *sidNoiseEst; + + Word16 indices[32], v16[32]; + Word32 v[32], gain; + + Word32 tmp, maxVal, E_ExpLd64; + Word16 sidNoiseEst_Exp; + + Word16 preemph_fac; + + + sidNoiseEst = st->sidNoiseEst; + move16(); + preemph_fac = corest->preemph_fac; + move16(); + + N = st->npart; + move16(); + + st->sid_frame_counter = add(st->sid_frame_counter,1); + move16(); + + /* Read bitstream */ + FOR (i=0; i= 0; maxVal -= 33554432l/*0.015625 Q31*/) + { + sidNoiseEst_Exp = add(sidNoiseEst_Exp,1); + } + st->sidNoiseEstExp = sidNoiseEst_Exp; + move16(); + E_ExpLd64 = L_shl(sidNoiseEst_Exp, WORD32_BITS-1-LD_DATA_SCALE); + + /* format v: Q9.23, format sidNoiseEst: Q6.26, 0.66438561897 = log10(10)/log10(2.0) / 10.0 * 2.0 */ + FOR (i=0; isidNoiseEst[i] = BASOP_Util_InvLog2(tmp); + move32(); + } + + /* NB last band energy compensation */ + IF ( st->CngBandwidth == NB ) + { + st->sidNoiseEst[N-1] = Mpy_32_16_1(st->sidNoiseEst[N-1], NB_LAST_BAND_SCALE); + move32(); + } + + test(); + if ( st->CngBandwidth == SWB && st->CngBitrate <= ACELP_13k20 ) + { + st->sidNoiseEst[N-1] = Mpy_32_16_1(st->sidNoiseEst[N-1], SWB_13k2_LAST_BAND_SCALE); + } + + + scalebands (sidNoiseEst, st->part, st->npart, st->midband, st->nFFTpart, st->stopBand-st->startBand, st->cngNoiseLevel, 1); + st->cngNoiseLevelExp = st->sidNoiseEstExp; + move16(); + + + lpc_from_spectrum (st, st->startBand, st->stopFFTbin, preemph_fac); + + +} + + +/* + noisy_speech_detection + + Parameters: + + vad i : VAD decision + Etot i : total channel E + Etot_exp i : exponent for total channel E + totalNoise i : noise estimate over all critical bands + totalNoise_exp i : exponent for noise estimate over all critical bands + lp_noise i/o: pointer to long term total Noise energy average + lp_speech i/o: pointer to long term active speech energy average + + Function: + detector for noisy speech, lp_noise and lp_speech are scaled by LD_DATA_SCALE+2 bits + + Returns: flag, that indicates whether noisy speech has been detected + + void +*/ +void noisy_speech_detection ( + HANDLE_FD_CNG_DEC hFdCngDec,/* i/o: FD_CNG structure */ + const Word16 vad, + const Word16 * syn, /* i : input time-domain frame */ + const Word16 Q +) +{ + Word16 i; + Word32 tmp; + Word32 Etot; + Word16 Etot_exp; + Word32 logEtot; + Word32 logEtotExp; + Word32 totalNoise; + Word16 totalNoise_exp; + Word32 logTotalNoise; + Word32 logTotalNoiseExp; + + + IF ( vad == 0 ) + { + totalNoise = dotWord32_16_Mant32Exp(hFdCngDec->msNoiseEst, hFdCngDec->msNoiseEst_exp, hFdCngDec->psize_shaping_norm, hFdCngDec->psize_shaping_norm_exp, hFdCngDec->nFFTpart_shaping, &totalNoise_exp); + + /* + - logTotalNoise is scaled by LD_DATA_SCALE+2 + - logTotalNoise = 10.0 * log10(totalNoise + DELTA); + - constant: -0.78125 = 10.0*log10(DELTA)/(1<<(LD_DATA_SCALE+2)) + - constant: 0.75257498916 = 10.0 * log10(2.0)/log10(10.0)/(1<<2) + */ + IF ( totalNoise == 0 ) + { + logTotalNoise = L_add(-1677721600l/*-0.78125 Q31*/, 0); + } + ELSE + { + logTotalNoise = BASOP_Util_Log2(totalNoise); + logTotalNoiseExp = L_shl(L_deposit_l(totalNoise_exp),WORD32_BITS-1-LD_DATA_SCALE); + logTotalNoise = Mpy_32_16_1(L_add(logTotalNoise,logTotalNoiseExp),24660/*0.75257498916 Q15*/); + } + + hFdCngDec->lp_noise = L_add(Mpy_32_16_1(hFdCngDec->lp_noise,32604/*0.995 Q15*/),L_shr(Mpy_32_16_1(logTotalNoise,20972/*0.64 Q15*/),7)); + move32(); + } + ELSE + { + Etot = 0; + Etot_exp = 31; + FOR( i = 0; i < hFdCngDec->hFdCngCom->frameSize; i++ ) + { + tmp = L_shr_r( L_mult0(syn[i], syn[i] ), sub( Etot_exp, 31 ) ); + IF( L_sub( maxWord32, tmp ) < Etot ) + { + Etot_exp = add( Etot_exp, 1 ); + Etot = L_shr_r( Etot, 1 ); + tmp = L_shr_r( tmp, 1 ); + } + Etot = L_add( Etot, tmp ); + } + Etot_exp = sub( Etot_exp, shl( Q, 1 ) ); + + /* + - logEtot is scaled by LD_DATA_SCALE+2 + - logEtot = 10.0 * log10(totalNoise + DELTA); + - constant: -0.78125 = 10.0*log10(DELTA)/(1<<(LD_DATA_SCALE+2)) + - constant: 0.75257498916 = 10.0 * log10(2.0)/log10(10.0)/(1<<2) + */ + IF ( Etot == 0 ) + { + logEtot = L_add(-1677721600l/*-0.78125 Q31*/, 0); + } + ELSE + { + logEtot = BASOP_Util_Log2(Etot); + logEtotExp = L_shl(L_deposit_l(Etot_exp),WORD32_BITS-1-LD_DATA_SCALE); + logEtot = Mpy_32_16_1(L_add(logEtot,logEtotExp),24660/*0.75257498916 Q15*/); + IF ( EQ_16( hFdCngDec->hFdCngCom->frameSize, L_FRAME16k )) + { + logEtot = L_add( logEtot, -184894985l/*-0.086098436822497 Q31*/ ); + } + ELSE + { + logEtot = L_add( logEtot, -176765584l/*-0.082312889439370 Q31*/ ); + } + } + + hFdCngDec->lp_speech = L_add(Mpy_32_16_1(hFdCngDec->lp_speech,32604/*0.995 Q15*/),L_shr(Mpy_32_16_1(logEtot,20972/*0.64 Q15*/),7)); + move32(); + } + + tmp = L_sub(hFdCngDec->lp_speech,377487360l/*45.0 Q23*/); + + if ( LT_32(hFdCngDec->lp_noise,tmp)) + { + hFdCngDec->lp_noise = tmp; + move32(); + } + + hFdCngDec->hFdCngCom->flag_noisy_speech = 0; + move16(); + if ( LT_32(L_sub(hFdCngDec->lp_speech, hFdCngDec->lp_noise),234881024l/*28.0 Q23*/)) + { + hFdCngDec->hFdCngCom->flag_noisy_speech = 1; + move16(); + } + + + return; +} + + +void +generate_comfort_noise_dec ( + Word32 **bufferReal, /* o : matrix to real part of input bands */ + Word32 **bufferImag, /* o : matrix to imaginary part of input bands */ + Word16 *bufferScale, /* o : pointer to scalefactor for real and imaginary part of input bands */ + Decoder_State *st, + Word16 *Q_new, + Word16 gen_exc, + const Word16 nchan_out /* i : number of output channels */ +) +{ + Word16 i, j, s, sc, sn, cnt; + Word16 startBand2; + Word16 stopFFTbin2; + Word16 scaleCLDFB; + Word16 preemph_fac; + Word32 sqrtNoiseLevel; + Word16 randGaussExp; + Word16 fftBufferExp; + Word16 cngNoiseLevelExp; + Word16 *seed; + Word16 *timeDomainOutput; + Word32 *ptr_r, *ptr_i; + Word32 *cngNoiseLevel; + Word32 *ptr_level; + Word32 *fftBuffer; + Word16 old_syn_pe_tmp[16]; + Word16 tcx_transition = 0; + HANDLE_FD_CNG_DEC hFdCngDec = st->hFdCngDec_fx; + HANDLE_FD_CNG_COM hFdCngCom = hFdCngDec->hFdCngCom; + TCX_DEC_HANDLE hTcxDec; + + hTcxDec = st->hTcxDec; + + /* Warning fix */ + s = 0; +//PMTE(); /*IVAS CODE need to be added */ + + /* pointer initialization */ + + cngNoiseLevel = hFdCngCom->cngNoiseLevel; + cngNoiseLevelExp = hFdCngCom->cngNoiseLevelExp; + ptr_level = cngNoiseLevel; + seed = &(hFdCngCom->seed); + fftBuffer = hFdCngCom->fftBuffer; + timeDomainOutput = hFdCngCom->timeDomainBuffer; + + /* scaleCLDFB: CLDFBinvScalingFactor_EXP + 1 */ + scaleCLDFB = mult(hFdCngCom->invScalingFactor,CLDFB_SCALING); + + /* + Generate Gaussian random noise in real and imaginary parts of the FFT bins + Amplitudes are adjusted to the estimated noise level cngNoiseLevel in each bin + scaling Gaussian random noise: format Q3.29 + */ + sn = 0; + move16(); + IF ( s_and(cngNoiseLevelExp,1) != 0 ) + { + sn = add(sn,1); + cngNoiseLevelExp = add(cngNoiseLevelExp,sn); + move16(); + } + + randGaussExp = CNG_RAND_GAUSS_SHIFT; + move16(); + cnt = sub(hFdCngCom->stopFFTbin, hFdCngCom->startBand); + IF ( hFdCngCom->startBand == 0 ) + { + /* DC component in FFT */ + s = 0; + move16(); + sqrtNoiseLevel = Sqrt32(L_shr(*ptr_level,sn), &s); + + fftBuffer[0] = L_shl(Mpy_32_32(rand_gauss(seed),sqrtNoiseLevel),s); + move32(); + + /* Nyquist frequency is discarded */ + fftBuffer[1] = L_deposit_l(0); + + ptr_level = ptr_level + 1; + ptr_r = fftBuffer + 2; + cnt = sub(cnt, 1); + } + ELSE + { + startBand2 = shl(hFdCngCom->startBand,1); + set32_fx(fftBuffer, 0, startBand2); + ptr_r = fftBuffer + startBand2; + } + + sn = add(sn,1); + ptr_i = ptr_r + 1; + FOR (i=0; i < cnt; i++) + { + s = 0; + move16(); + sqrtNoiseLevel = Sqrt32(L_shr(*ptr_level,sn), &s); + + /* Real part in FFT bins */ + *ptr_r = L_shl(Mpy_32_32(rand_gauss(seed),sqrtNoiseLevel),s); + move32(); + + /* Imaginary part in FFT bins */ + *ptr_i = L_shl(Mpy_32_32(rand_gauss(seed),sqrtNoiseLevel),s); + move32(); + + ptr_r = ptr_r + 2; + ptr_i = ptr_i + 2; + ptr_level = ptr_level + 1; + } + + /* Remaining FFT bins are set to zero */ + stopFFTbin2 = shl(hFdCngCom->stopFFTbin,1); + set32_fx(fftBuffer+stopFFTbin2, 0, sub(hFdCngCom->fftlen,stopFFTbin2)); + + fftBufferExp = add(shr(cngNoiseLevelExp,1),randGaussExp); + + /* If previous frame is active, reset the overlap-add buffer */ + IF ( hFdCngCom->frame_type_previous == ACTIVE_FRAME ) + { + set16_fx(hFdCngCom->olapBufferSynth, 0, hFdCngCom->fftlen); + test(); + test(); + if ( ( st->last_core_bfi > ACELP_CORE && st->codec_mode == MODE2 ) || st->codec_mode == MODE1 ) + { + tcx_transition = 1; + move16(); + } + } + + /* Perform STFT synthesis */ + SynthesisSTFT (fftBuffer, fftBufferExp, timeDomainOutput, hFdCngCom->olapBufferSynth, hFdCngCom->olapWinSyn, + tcx_transition, hFdCngCom, gen_exc, Q_new, st->element_mode, nchan_out); + + { + Word32 Lener, att; + Word16 exp; + /* update CNG excitation energy for LP_CNG */ + + /* calculate the residual signal energy */ + /*enr = dotp( hFdCngCom->exc_cng, hFdCngCom->exc_cng, hFdCngCom->frameSize ) / hFdCngCom->frameSize;*/ + Lener = Dot_productSq16HQ(1,hFdCngCom->exc_cng,st->L_frame,&exp); + exp = add(sub(shl(sub(15,*Q_new),1),8),exp); /*8 = log2(256)*/ + + /* convert log2 of residual signal energy */ + /*(float)log10( enr + 0.1f ) / (float)log10( 2.0f );*/ + Lener = BASOP_Util_Log2(Lener); + Lener = L_add(Lener,L_shl(L_deposit_l(exp),WORD32_BITS-1-LD_DATA_SCALE)); /*Q25*/ + if(st->L_frame == L_FRAME16k) + { + Lener = L_sub(Lener, 10802114l/*0.3219280949f Q25*/); /*log2(320) = 8.3219280949f*/ + } + /* decrease the energy in case of WB input */ + IF( NE_16(st->bwidth, NB)) + { + IF( EQ_16(st->bwidth,WB)) + { + IF( st->CNG_mode >= 0 ) + { + /* Bitrate adapted attenuation */ + att = L_shl(L_deposit_l(ENR_ATT_fx[st->CNG_mode]),17); + } + ELSE + { + /* Use least attenuation for higher bitrates */ + att = L_shl(L_deposit_l(ENR_ATT_fx[4]),17); + } + } + ELSE + { + att = 384<<17; + move16();/*1.5 Q8<<17=Q25*/ + } + Lener = L_sub(Lener, att ); + } + /*st->lp_ener = 0.8f * stcod->lp_ener + 0.2f * pow( 2.0f, enr );*/ + Lener = BASOP_util_Pow2(Lener, 6, &exp); + Lener = Mult_32_16(Lener, 6554/*0.2f Q15*/); + exp = sub(25,exp); + Lener = L_shr(Lener, exp); /*Q6*/ + st->lp_ener_fx = L_add(Mult_32_16(st->lp_ener_fx, 26214/*0.8f Q15*/), Lener); /*Q6*/ + } + + /* + Generate Gaussian random noise in real and imaginary parts of the CLDFB bands + Amplitudes are adjusted to the estimated noise level cngNoiseLevel in each band + */ + test(); + IF ( bufferReal!=NULL && (LT_16(hFdCngCom->numCoreBands,hFdCngCom->regularStopBand))) + { + + sn = sub(sn,1); + sc = add(shr(add(cngNoiseLevelExp,CLDFBinvScalingFactor_EXP+1-1),1),randGaussExp); + move16(); + assert( ((cngNoiseLevelExp+CLDFBinvScalingFactor_EXP+1-1)&1) == 0); + + FOR (j=hFdCngCom->numCoreBands; jregularStopBand; j++) + { + /* scaleCLDFB: CLDFBinvScalingFactor_EXP + 1 */ + s = 0; + move16(); + sqrtNoiseLevel = Sqrt32(L_shr(Mpy_32_16_1(*ptr_level,scaleCLDFB),sn), &s); + + FOR (i=0; inumSlots; i++) + { + /* Real part in CLDFB band */ + bufferReal[i][j] = L_shl(Mpy_32_32(rand_gauss(seed),sqrtNoiseLevel),s); + move32(); + /*fprintf(pFile,"%13.10f\n",WORD322FL_SCALE(bufferReal[i][j],sc));*/ + + /* Imaginary part in CLDFB band */ + bufferImag[i][j] = L_shl(Mpy_32_32(rand_gauss(seed),sqrtNoiseLevel),s); + move32(); + /*fprintf(pFile,"%13.10f\n",WORD322FL_SCALE(bufferImag[i][j],sc));*/ + } + ptr_level = ptr_level + 1; + } + *bufferScale = sub(sc,15); + move16(); + } + + /* Overlap-add when previous frame is active */ + test(); + IF ( hFdCngCom->frame_type_previous == ACTIVE_FRAME && st->codec_mode == MODE2 ) + { + Word32 old_exc_ener, gain, noise32; + Word16 seed_loc, lpcorder, old_syn, tmp, gain16, N, N2, N4, N8; + Word16 old_exc_ener_exp, gain_exp; + Word16 normFacE, normShiftE, normShiftEM1; + Word16 normFacG, normShiftG, normShiftGM1; + Word16 noiseExp, *old_exc, *old_Aq, *old_syn_pe; + Word16 noise[640], normShiftP2; + Word16 Q_exc, Q_syn; + + + assert(hFdCngCom->frameSize <= 640); + + seed_loc = hFdCngCom->seed; + move16(); + N = hFdCngCom->frameSize; + move16(); + N2 = shr(hFdCngCom->frameSize,1); + + IF ( st->last_core_bfi > ACELP_CORE ) + { + Word16 left_overlap_mode; + left_overlap_mode = st->hTcxCfg->tcx_last_overlap_mode; + move16(); + if (EQ_16(left_overlap_mode, ALDO_WINDOW)) + { + left_overlap_mode = FULL_OVERLAP; + move16(); + } + tcx_windowing_synthesis_current_frame( timeDomainOutput,st->hTcxCfg->tcx_mdct_window, st->hTcxCfg->tcx_mdct_window_half,st->hTcxCfg->tcx_mdct_window_minimum,st->hTcxCfg->tcx_mdct_window_length,st->hTcxCfg->tcx_mdct_window_half_length, + st->hTcxCfg->tcx_mdct_window_min_length,0,left_overlap_mode,NULL,NULL,NULL,NULL,NULL,N/2,shr(sub(abs_s(st->hTcxCfg->tcx_offset), st->hTcxCfg->tcx_offset), 1), 1,0,0); + + IF (st->hTcxCfg->last_aldo != 0) + { + FOR (i=0; iframeSize,NS2SA(st->sr_core, N_ZERO_MDCT_NS)); i++) + { + timeDomainOutput[i] = add(timeDomainOutput[i], shr_r(st->hHQ_core->old_out_LB_fx[i+NS2SA(st->sr_core, N_ZERO_MDCT_NS)],st->hHQ_core->Q_old_wtda_LB)); + } + } + ELSE + { + tcx_windowing_synthesis_past_frame(hTcxDec->syn_Overl,st->hTcxCfg->tcx_mdct_window, st->hTcxCfg->tcx_mdct_window_half, st->hTcxCfg->tcx_mdct_window_minimum, + st->hTcxCfg->tcx_mdct_window_length, st->hTcxCfg->tcx_mdct_window_half_length, st->hTcxCfg->tcx_mdct_window_min_length, st->hTcxCfg->tcx_last_overlap_mode); + + FOR (i=0; ihTcxCfg->tcx_mdct_window_length; i++) + { + timeDomainOutput[i] += shl(hTcxDec->syn_Overl[i],TCX_IMDCT_HEADROOM); + } + } + } + ELSE + { + + /* + - the scaling of the LPCs (e.g. old_Aq) is always Q12 (encoder or decoder) + + - the scaling of the deemphasized signals (e.g. old_syn) is always Q0 (encoder or decoder) + + - the scaling of the excitation signals in the encoder (e.g. old_exc) is Q_new + - the scaling of the preemphasized signals in the encoder (e.g. old_syn_pe) is Q_new-1 + + - the scaling of the excitation signals in the decoder (e.g. old_exc) is Q_exc (or stdec->Q_exc) + - the scaling of the preemphasized signals in the decoder (e.g. old_syn_pe) is Q_syn (or stdec->Q_syn) + */ + + lpcorder = M; + move16(); + old_Aq = st->old_Aq_12_8_fx; + old_exc = st->old_exc_fx+sub(L_EXC_MEM_DEC,N2); + old_syn_pe = st->mem_syn2_fx; + old_syn = st->syn[lpcorder]; + move16(); + preemph_fac = st->preemph_fac; + move16(); + Q_exc = st->Q_exc; + move16(); + Q_syn = st->Q_syn; + move16(); + + /* shift to be in the range of values supported by getNormReciprocalWord16() */ + N8 = shr(N2, CNG_NORM_RECIPROCAL_RANGE_SHIFT); + + assert( N2 == (N8<olapWinSyn[i].v.re); + timeDomainOutput[i] = add(timeDomainOutput[i],tmp); + move16(); + tmp = mult(noise[i+N4],hFdCngCom->olapWinSyn[N4-1-i].v.im); + timeDomainOutput[i+N4] = add(timeDomainOutput[i+N4],tmp); + move16(); + } + } + } + +} + + +void +generate_comfort_noise_dec_hf ( + Word32 **bufferReal, /* o : matrix to real part of input bands */ + Word32 **bufferImag, /* o : matrix to imaginary part of input bands */ + Word16 *bufferScale, /* o : pointer to scalefactor for real and imaginary part of input bands */ + Decoder_State *st + ) +{ + Word16 i, j, s, sc, sn; + Word16 scaleCLDFB; + Word32 sqrtNoiseLevel; + Word16 randGaussExp; + Word16 cngNoiseLevelExp; + Word16 *seed; + Word32 *cngNoiseLevel; + Word32 *ptr_level; + HANDLE_FD_CNG_COM hFdCngCom = st->hFdCngDec_fx->hFdCngCom; + + cngNoiseLevel = hFdCngCom->cngNoiseLevel+hFdCngCom->stopFFTbin-hFdCngCom->startBand; + cngNoiseLevelExp = hFdCngCom->cngNoiseLevelExp; + ptr_level = cngNoiseLevel; + seed = &(hFdCngCom->seed); + + /* scaleCLDFB: CLDFBinvScalingFactor_EXP + 1 */ + scaleCLDFB = mult(hFdCngCom->invScalingFactor,CLDFB_SCALING); + + sn = 0; + move16(); + IF ( s_and(cngNoiseLevelExp,1) != 0 ) + { + sn = add(sn,1); + cngNoiseLevelExp = add(cngNoiseLevelExp,sn); + move16(); + } + + randGaussExp = CNG_RAND_GAUSS_SHIFT; + move16(); + + IF ( LT_16(hFdCngCom->numCoreBands,hFdCngCom->regularStopBand)) + { + + sc = add(shr(add(cngNoiseLevelExp,CLDFBinvScalingFactor_EXP+1-1),1),randGaussExp); + move16(); + assert( ((cngNoiseLevelExp+CLDFBinvScalingFactor_EXP+1-1)&1) == 0); + + FOR (j=hFdCngCom->numCoreBands; jregularStopBand; j++) + { + /* scaleCLDFB: CLDFBinvScalingFactor_EXP + 1 */ + s = 0; + move16(); + sqrtNoiseLevel = Sqrt32(L_shr(Mpy_32_16_1(*ptr_level,scaleCLDFB),sn), &s); + + FOR (i=0; inumSlots; i++) + { + /* Real part in CLDFB band */ + bufferReal[i][j] = L_shl(Mpy_32_32(rand_gauss(seed),sqrtNoiseLevel),s); + move32(); + /*fprintf(pFile,"%13.10f\n",WORD322FL_SCALE(bufferReal[i][j],sc));*/ + + /* Imaginary part in CLDFB band */ + bufferImag[i][j] = L_shl(Mpy_32_32(rand_gauss(seed),sqrtNoiseLevel),s); + move32(); + /*fprintf(pFile,"%13.10f\n",WORD322FL_SCALE(bufferImag[i][j],sc));*/ + } + ptr_level = ptr_level + 1; + } + *bufferScale = sub(sc,15); + move16(); + } +} + + +/* + generate_masking_noise + + Parameters: + + timeDomainBuffer i/o : pointer to time domain output buffer 15Q0 + st i/o : pointer to FD_CNG_COM structure + bitrate i : bitrate + + Function: + Generate additional comfort noise (kind of noise filling) + + Returns: none + + void +*/ +void generate_masking_noise ( + Word16 *timeDomainBuffer, /* i/o : pointer to time domain output buffer 15Q0 */ + Word16 Q, + HANDLE_FD_CNG_COM hFdCngCom /* i/o : pointer to FD_CNG_COM structure */ + ,Word16 length + ,Word16 core + ) +{ + Word16 i, s, s1, s2, sq, cnt, startBand2, stopFFTbin2; + Word16 scaleExp,fftBufferExp,cngNoiseLevelExp; + Word16 scale, scaleTableSize; + Word16 maskingNoise[L_FRAME16k]; + Word32 sqrtNoiseLevel; + Word32 *cngNoiseLevel; + Word32 *fftBuffer; + Word16 *seed; + + // PMTE(); /*IVAS CODE need to be added */ + + /* pointer initializations */ + cngNoiseLevel = hFdCngCom->cngNoiseLevel; + fftBuffer = hFdCngCom->fftBuffer; + seed = &(hFdCngCom->seed); + + /* Compute additional CN level */ + cngNoiseLevelExp = hFdCngCom->cngNoiseLevelExp; + move16(); + + IF(core!=AMR_WB_CORE) + { + scaleTableSize = 18; + move16(); + assert( scaleTableSize == (sizeof (scaleTable_cn_only) / sizeof (scaleTable_cn_only[0])) ); + + scale = -1; + move16(); + FOR (i=0; i < scaleTableSize; i++) + { + test(); + test(); + IF ( ( EQ_16(hFdCngCom->CngBandwidth,scaleTable_cn_only[i].bwmode)) + && (GE_32(hFdCngCom->CngBitrate,scaleTable_cn_only[i].bitrateFrom) ) + && ( LT_32(hFdCngCom->CngBitrate,scaleTable_cn_only[i].bitrateTo) )) + + { + scale = scaleTable_cn_only[i].scale; + move16(); + BREAK; + } + } + assert(scale >= 0); + } + ELSE + { + scaleTableSize = 3; + move16(); + assert( scaleTableSize == (sizeof (scaleTable_cn_only_amrwbio) / sizeof (scaleTable_cn_only_amrwbio[0])) ); + + scale = 0; + move16(); + FOR (i=0; i < scaleTableSize; i++) + { + IF ( GE_32(hFdCngCom->CngBitrate,scaleTable_cn_only_amrwbio[i][0])) + { + scale = scaleTable_cn_only_amrwbio[i][1]; + move16(); + BREAK; + } + } + } + + /* Exclude clean speech */ + + s1 = norm_s(scale); + s2 = norm_s(hFdCngCom->likelihood_noisy_speech); + + /* scaleTable_cn_only[i].scale is scaled by 1 bit */ + scaleExp = sub(1,add(s1,s2)); + scale = mult_r(shl(scale,s1),shl(hFdCngCom->likelihood_noisy_speech,s2)); + + { + /* add exponent of scale and cngNoiseLevel */ + fftBufferExp = add(scaleExp,cngNoiseLevelExp); + + /* even scalefactor needed for sqrt calculation */ + s = s_and(fftBufferExp,1); + fftBufferExp = add(fftBufferExp,s); + + /* sqrt calculation => shift exponent */ + fftBufferExp = shr(fftBufferExp,1); + + /* consider scaling of random noise */ + fftBufferExp = add(fftBufferExp,CNG_RAND_GAUSS_SHIFT); + + cnt = sub(hFdCngCom->stopFFTbin,hFdCngCom->startBand); + /* + Generate Gaussian random noise in real and imaginary parts of the FFT bins + Amplitudes are adjusted to the estimated noise level cngNoiseLevel in each bin + */ + IF ( hFdCngCom->startBand == 0 ) + { + /* random noise is scaled by CNG_RAND_GAUSS_SHIFT bits */ + + /* DC component in FFT */ + + /* -s => consider scalefactor adaptation for sqrt calculation */ + sq = sub(0,s); + sqrtNoiseLevel = Sqrt32(Mpy_32_16_1(*cngNoiseLevel,scale),&sq); + hFdCngCom->fftBuffer[0] = L_shl(Mpy_32_32(rand_gauss(seed),sqrtNoiseLevel),sq); + move32(); + hFdCngCom->fftBuffer[1] = 0; + move32(); + + fftBuffer = hFdCngCom->fftBuffer + 2; + cngNoiseLevel++; + + cnt = sub(cnt,1); + } + ELSE + { + startBand2 = shl(hFdCngCom->startBand,1); + set32_fx(hFdCngCom->fftBuffer,0,startBand2); + fftBuffer = hFdCngCom->fftBuffer + startBand2; + } + + FOR (i=0; i weighting with 0.5, -s => consider scalefactor adaptation for sqrt calculation */ + sq = sub(-1,s); + sqrtNoiseLevel = Sqrt32(Mpy_32_16_1(*cngNoiseLevel,scale),&sq); + + /* real part in FFT bins */ + + /* random noise is scaled by CNG_RAND_GAUSS_SHIFT bits */ + *fftBuffer = L_shl(Mpy_32_32(rand_gauss(seed),sqrtNoiseLevel),sq); + move32(); + fftBuffer++; + + /* imaginary part in FFT bins */ + + /* random noise is scaled by CNG_RAND_GAUSS_SHIFT bits */ + *fftBuffer = L_shl(Mpy_32_32(rand_gauss(seed),sqrtNoiseLevel),sq); + move32(); + fftBuffer++; + + cngNoiseLevel++; + } + + /* remaining FFT bins are set to zero */ + stopFFTbin2 = shl(hFdCngCom->stopFFTbin,1); + set32_fx(hFdCngCom->fftBuffer+stopFFTbin2, 0, sub(hFdCngCom->fftlen,stopFFTbin2)); + + + /* perform STFT synthesis */ + assert(hFdCngCom->olapBufferSynth2 != NULL); + SynthesisSTFT(hFdCngCom->fftBuffer, fftBufferExp, maskingNoise, hFdCngCom->olapBufferSynth2, hFdCngCom->olapWinSyn, + 0, hFdCngCom, 0, NULL, -1/*st->element_mode*/, -1/*nchan_out*/); + //PMT("parameters need update") + + + /* add some comfort noise on top of decoded signal */ + IF ( hFdCngCom->frameSize > length ) + { + FOR (i=0; iframeSize; i++) + { +#ifdef BASOP_NOGLOB + timeDomainBuffer[i] = add_sat(timeDomainBuffer[i],shr_r_sat (maskingNoise[i],-Q)); +#else + timeDomainBuffer[i] = add(timeDomainBuffer[i],shr_r(maskingNoise[i],-Q)); +#endif + move16(); + } + } + } + +} + +/*------------------------------------------------------------------- + * generate_masking_noise_update_seed() + * + * Update seed for scenarios where generate_masking_noise() is + * not called based on signal statistics + *-------------------------------------------------------------------*/ + +void generate_masking_noise_update_seed ( + HANDLE_FD_CNG_COM hFdCngCom /* i/o : pointer to FD_CNG_COM structure */ +) +{ + Word16 *seed; + Word16 cnt, i; + + /* pointer initializations */ + seed = &(hFdCngCom->seed); + + cnt = sub(hFdCngCom->stopFFTbin, hFdCngCom->startBand); + + IF ( hFdCngCom->startBand == 0 ) + { + rand_gauss(seed); + cnt = sub(cnt,1); + } + + FOR (i=0; icngNoiseLevel; + seed = &(hFdCngCom->seed); + + /* Compute additional CN level */ + cngNoiseLevelExp = hFdCngCom->cngNoiseLevelExp; + move16(); + + /* Compute additional CN level */ + scaleTableSize = 18; + move16(); + assert( scaleTableSize == (sizeof (scaleTable_cn_only) / sizeof (scaleTable_cn_only[0])) ); + + scale = -1; + move16(); + FOR (i=0; i < scaleTableSize; i++) + { + test(); + test(); + IF ( ( EQ_16(hFdCngCom->CngBandwidth,scaleTable_cn_only[i].bwmode)) + && ( GE_32(hFdCngCom->CngBitrate,scaleTable_cn_only[i].bitrateFrom) ) + && ( LT_32(hFdCngCom->CngBitrate,scaleTable_cn_only[i].bitrateTo) ) + ) + { + scale = scaleTable_cn_only[i].scale; + move16(); + BREAK; + } + } + assert(scale >= 0); + + /* Exclude clean speech */ + s1 = norm_s(scale); + s2 = norm_s(hFdCngCom->likelihood_noisy_speech); + + /* scaleTable_cn_only[i].scale is scaled by 1 bit */ + scaleExp = sub(1,add(s1,s2)); + scale = mult_r(shl(scale,s1),shl(hFdCngCom->likelihood_noisy_speech,s2)); + + /* add exponent of scale and cngNoiseLevel */ + maskingNoiseExp = add(scaleExp,cngNoiseLevelExp); + + /* even scalefactor needed for sqrt calculation */ + s = s_and(maskingNoiseExp,1); + maskingNoiseExp = add(maskingNoiseExp,s); + + /* sqrt calculation => shift exponent */ + maskingNoiseExp = shr(maskingNoiseExp,1); + + /* consider scaling of random noise */ + maskingNoiseExp = add(maskingNoiseExp,CNG_RAND_GAUSS_SHIFT); + + cnt = sub(hFdCngCom->stopFFTbin,hFdCngCom->startBand); + + /* + Generate Gaussian random noise in real and imaginary parts of the FFT bins + Amplitudes are adjusted to the estimated noise level cngNoiseLevel in each bin + */ + IF ( hFdCngCom->startBand == 0 ) + { + /* random noise is scaled by CNG_RAND_GAUSS_SHIFT bits */ + + /* DC component in FFT */ + + /* -1 => weighting with 0.5, -s => consider scalefactor adaptation for sqrt calculation */ + sq = sub(-1,s); + sqrtNoiseLevel = Sqrt32(Mpy_32_16_1(*cngNoiseLevel,scale),&sq); + maskingNoise[0] = L_shl(Mpy_32_32(rand_gauss(seed),sqrtNoiseLevel),sq); + move32(); + + pMaskingNoise = &maskingNoise[1]; + cngNoiseLevel++; + + cnt = sub(cnt,1); + } + ELSE + { + set32_fx(maskingNoise,0,hFdCngCom->startBand); + pMaskingNoise = maskingNoise + hFdCngCom->startBand; + } + + FOR (i=0; i weighting with 0.5, -s => consider scalefactor adaptation for sqrt calculation */ + sq = sub(-1,s); + sqrtNoiseLevel = Sqrt32(Mpy_32_16_1(*cngNoiseLevel,scale),&sq); + + /* real part in FFT bins */ + + /* random noise is scaled by CNG_RAND_GAUSS_SHIFT bits */ + *pMaskingNoise = L_shl(Mpy_32_32(rand_gauss(seed),sqrtNoiseLevel),sq); + move32(); + pMaskingNoise++; + + cngNoiseLevel++; + } + + /* re-normalization of energy level + 16 * 0.79056941504 = sqrt(NORM_MDCT_FACTOR) + */ + assert( NORM_MDCT_FACTOR == 160 ); + + /* do weighting with factor 0.79056941504 later */ + maskingNoiseExp = add(maskingNoiseExp,4); + + s = s_max(*mdctBuffer_e,maskingNoiseExp); + s1 = sub(s,*mdctBuffer_e); + s2 = sub(s,maskingNoiseExp); + + /* avoid rescaling of mdct samples if no comfort noise is added */ + IF ( scale != 0 ) + { + /* Add some comfort noise on top of decoded signal */ + IF ( s1 == 0 ) + { + FOR (i=0; i < hFdCngCom->stopFFTbin; i++) + { + /* If shifting negative noise values the lowest result is -1 but never 0. + Shift positive noise values to avoid unwanted amplification of these small values later */ + noise = L_shr(Mpy_32_16_1(L_abs(maskingNoise[i]),25905/*0.79056941504 Q15*/),s2); + + if ( maskingNoise[i] < 0 ) + { + noise = L_negate(noise); + } + + mdctBuffer[i] = L_add(mdctBuffer[i], noise); + move32(); + } + } + ELSE + { + FOR (i=0; i < hFdCngCom->stopFFTbin; i++) + { + mdctBuffer[i] = L_add(L_shr(mdctBuffer[i],s1), + Mpy_32_16_1(maskingNoise[i],25905/*0.79056941504 Q15*/)); + move32(); + } + FOR (i=hFdCngCom->stopFFTbin; i < L_frame; i++) + { + mdctBuffer[i] = L_shr(mdctBuffer[i],s1); + move32(); + } + *mdctBuffer_e = s; + move16(); + } + } + +} + +#ifdef IVAS_CODE_CNG + +/*------------------------------------------------------------------- + * generate_stereo_masking_noise() + * + * Generate additional comfort noise (kind of noise filling) + *-------------------------------------------------------------------*/ + +void generate_stereo_masking_noise( + float* syn, /* i/o: time-domain signal */ + Decoder_State* st, /* i/o: decoder state structure */ + STEREO_TD_DEC_DATA_HANDLE hStereoTD, /* i : TD stereo structure */ + const int16_t flag_sec_CNA, /* i : CNA flag for secondary channel */ + const int16_t fadeOut, /* i : only fade out of previous state */ + STEREO_CNG_DEC_HANDLE hStereoCng, /* i : Stereo CNG handle */ + const int16_t nchan_out /* i : number of output channels */ +) +{ + HANDLE_FD_CNG_COM hFdCngCom; + float gamma, scale, SP_ratio; + float Np[L_FRAME16k]; + float Ns[L_FRAME16k]; + float N1[L_FRAME16k]; + float N2[L_FRAME16k]; + int16_t i; + + if (st->idchan == 0) + { + hFdCngCom = st->hFdCngDec->hFdCngCom; + mvr2r(hFdCngCom->olapBufferSynth2, Np, hFdCngCom->frameSize / 2); + mvr2r(hStereoCng->olapBufferSynth22, Ns, hFdCngCom->frameSize / 2); + set_f(&Np[hFdCngCom->frameSize / 2], 0.0f, hFdCngCom->frameSize / 2); + set_f(&Ns[hFdCngCom->frameSize / 2], 0.0f, hFdCngCom->frameSize / 2); + + if (!fadeOut) + { + generate_masking_noise(N1, hFdCngCom, hFdCngCom->frameSize, 0, 1, 0, st->element_mode, hStereoCng, nchan_out); + /* Generate masking noise for secondary channel */ + if (flag_sec_CNA) + { + generate_masking_noise(N2, hFdCngCom, hFdCngCom->frameSize, 0, 1, 1, st->element_mode, hStereoCng, nchan_out); + gamma = hStereoCng->c_PS_LT * hStereoCng->c_PS_LT; + scale = 1.0f; + if (gamma < 0.9f) + { + gamma = gamma / (1 - gamma); + gamma = (float)sqrt(gamma + 1) - (float)sqrt(gamma); + scale = 1.0f / (float)sqrt(1 + gamma * gamma); + } + else + { + gamma = 0.0f; + } + + for (i = 0; i < 2 * hFdCngCom->frameSize / 4; i++) + { + Np[i] += scale * (N1[i] + gamma * N2[i]); + Ns[i] += scale * sign(hStereoCng->c_PS_LT) * (N1[i] - gamma * N2[i]); + } + for (; i < hFdCngCom->frameSize; i++) + { + Np[i] = scale * (N1[i] + gamma * N2[i]); + Ns[i] = scale * sign(hStereoCng->c_PS_LT) * (N1[i] - gamma * N2[i]); + } + scale *= (float)(hFdCngCom->fftlen / 2); + for (i = 0; i < hFdCngCom->frameSize / 2; i++) + { + hFdCngCom->olapBufferSynth2[i] = scale * (hFdCngCom->olapBufferSynth2[i + 5 * hFdCngCom->frameSize / 4] + gamma * hStereoCng->olapBufferSynth22[i + 5 * hFdCngCom->frameSize / 4]); + hStereoCng->olapBufferSynth22[i] = sign(hStereoCng->c_PS_LT) * scale * (hFdCngCom->olapBufferSynth2[i + 5 * hFdCngCom->frameSize / 4] - gamma * hStereoCng->olapBufferSynth22[i + 5 * hFdCngCom->frameSize / 4]); + } + } + else + { + for (i = 0; i < hFdCngCom->frameSize / 2; i++) + { + Np[i] += N1[i]; + } + mvr2r(&N1[hFdCngCom->frameSize / 2], &Np[hFdCngCom->frameSize / 2], hFdCngCom->frameSize / 2); + scale = (float)(hFdCngCom->fftlen / 2); + for (i = 0; i < hFdCngCom->frameSize; i++) + { + hFdCngCom->olapBufferSynth2[i] = scale * hFdCngCom->olapBufferSynth2[i + 5 * hFdCngCom->frameSize / 4]; + } + } + } + else + { + set_f(hFdCngCom->olapBufferSynth2, 0.0f, hFdCngCom->frameSize / 2); + set_f(hStereoCng->olapBufferSynth22, 0.0f, hFdCngCom->frameSize / 2); + } + if (flag_sec_CNA) + { + mvr2r(Ns, hStereoCng->maskingNoiseS, hFdCngCom->frameSize); + hStereoCng->enableSecCNA = 1; + } + else + { + set_f(hStereoCng->olapBufferSynth22, 0.0f, hFdCngCom->frameSize); + } + + /* add masking noise */ + v_add(Np, syn, syn, hFdCngCom->frameSize); + } + else if (hStereoCng->enableSecCNA) + { + SP_ratio = hStereoTD->SP_ratio_LT; /* Use long-term SP ratio based on L/R synthesis */ + /* scale and add masking noise */ + for (i = 0; i < *hStereoCng->frameSize / 4; i++) + { + scale = ((hStereoTD->prevSP_ratio * (*hStereoCng->frameSize / 4 - (float)i) + SP_ratio * (float)i) / (*hStereoCng->frameSize / 4)); + syn[i] += scale * hStereoCng->maskingNoiseS[i]; + } + for (; i < *hStereoCng->frameSize / 2; i++) + { + syn[i] += SP_ratio * hStereoCng->maskingNoiseS[i]; + } + for (; i < *hStereoCng->frameSize; i++) + { + syn[i] += SP_ratio * hStereoCng->maskingNoiseS[i]; + } + hStereoTD->prevSP_ratio = SP_ratio; + } + + return; +} + +/*------------------------------------------------------------------- + * generate_masking_noise_hf_cldfb() + * + * Generate additional comfort noise (kind of noise filling) + *-------------------------------------------------------------------*/ + +void generate_masking_noise_dirac( + HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables */ + HANDLE_CLDFB_FILTER_BANK h_cldfb, /* i : filterbank state */ + float* tdBuffer, /* i/o: time-domain signal, if NULL no LB-CNA */ + float* Cldfb_RealBuffer, /* o : CLDFD real buffer */ + float* Cldfb_ImagBuffer, /* o : CLDFD imaginary buffer */ + const int16_t slot_index, /* i : CLDFB slot index */ + const int16_t cna_flag, /* i : CNA flag for LB and HB */ + const int16_t fd_cng_flag /* i : FD-CNG flag for HB */ +) +{ + int16_t i; + float* cngNoiseLevel = hFdCngCom->cngNoiseLevel; + float* fftBuffer = hFdCngCom->fftBuffer; + float* ptr_r; + float* ptr_i; + float* ptr_level; + int16_t* seed = &(hFdCngCom->seed); + float scale; + + wmops_sub_start("fd_cng_dirac"); + + /* Init */ + scale = 0.f; + + /* Resample CLDFB memories if necessary*/ + if ((h_cldfb->no_channels * h_cldfb->no_col) != hFdCngCom->frameSize) + { + resampleCldfb(h_cldfb, hFdCngCom->frameSize * FRAMES_PER_SEC); + } + + set_zero(Cldfb_RealBuffer, CLDFB_NO_CHANNELS_MAX); + set_zero(Cldfb_ImagBuffer, CLDFB_NO_CHANNELS_MAX); + + /*LB CLDFB - CNA from STFT*/ +#ifdef DEBUG_MODE_DIRAC + { + int16_t tmp_s; + tmp_s = (int16_t)(32768.f * 0.5f * hFdCngCom->likelihood_noisy_speech * cna_flag + 0.5f); + dbgwrite(&tmp_s, sizeof(int16_t), 1, hFdCngCom->frameSize / 16, "./res/ivas_dirac_likelihood_noisy.pcm"); + } +#endif + if (cna_flag) + { + /* skip noise generating if level is very low, to avoid problems with possibly running into denormals */ + if (hFdCngCom->likelihood_noisy_speech > DELTA_MASKING_NOISE) + { + /* Compute additional CN level */ + for (i = 0; i < 15; i++) + { + if ((hFdCngCom->CngBandwidth == scaleTable_cn_dirac[i].bwmode) && + (hFdCngCom->CngBitrate >= scaleTable_cn_dirac[i].bitrateFrom) && + (hFdCngCom->CngBitrate < scaleTable_cn_dirac[i].bitrateTo)) + { + break; + } + } + + scale = (float)pow(10.f, -scaleTable_cn_dirac[i].scale / 10.f) - 1.f; + scale *= hFdCngCom->likelihood_noisy_speech; + } + } + + /* LB CLDFB - CNA from STFT: CNA applied only in channel 0*/ + if (cna_flag && tdBuffer != NULL) + { + if (scale != 0) + { + /*Generate LF comfort noise only at first slot, for the whole frame*/ + if (slot_index == 0) + { + ptr_level = cngNoiseLevel; + + /* Generate Gaussian random noise in real and imaginary parts of the FFT bins + Amplitudes are adjusted to the estimated noise level cngNoiseLevel in each bin */ + if (hFdCngCom->startBand == 0) + { + rand_gauss(&fftBuffer[0], seed); + ptr_r = fftBuffer + 2; + fftBuffer[0] *= (float)sqrt(scale * *ptr_level); /* DC component in FFT */ + ptr_level++; + } + else + { + fftBuffer[0] = 0.f; + set_f(fftBuffer + 2, 0.0f, 2 * (hFdCngCom->startBand - 1)); + ptr_r = fftBuffer + 2 * hFdCngCom->startBand; + } + ptr_i = ptr_r + 1; + + for (; ptr_level < cngNoiseLevel + hFdCngCom->stopFFTbin - hFdCngCom->startBand; ptr_level++) + { + /* Real part in FFT bins */ + rand_gauss(ptr_r, seed); + (*ptr_r) *= (float)sqrt((scale * *ptr_level) * 0.5f); + ptr_r += 2; + /* Imaginary part in FFT bins */ + rand_gauss(ptr_i, seed); + (*ptr_i) *= (float)sqrt((scale * *ptr_level) * 0.5f); + ptr_i += 2; + } + + /* Remaining FFT bins are set to zero */ + set_f(fftBuffer + 2 * hFdCngCom->stopFFTbin, 0.0f, hFdCngCom->fftlen - 2 * hFdCngCom->stopFFTbin); + /* Nyquist frequency is discarded */ + fftBuffer[1] = 0.f; + + /* Perform STFT synthesis */ + SynthesisSTFT(fftBuffer, tdBuffer, hFdCngCom->olapBufferSynth2, hFdCngCom->olapWinSyn, 0, hFdCngCom, X, Y, -1, -1); + +#ifdef DEBUG_MODE_DIRAC + { + int16_t tmp[1000]; + + for (i = 0; i < hFdCngCom->frameSize; i++) + { + tmp[i] = (int16_t)(tdBuffer[i] + 0.5f); + } + dbgwrite(tmp, sizeof(int16_t), hFdCngCom->frameSize, 1, "./res/ivas_dirac_cna_fft.pcm"); + } +#endif + } + + /* LF CLDFB*/ + cldfbAnalysis_ts(&(tdBuffer[hFdCngCom->numCoreBands * slot_index]), Cldfb_RealBuffer, Cldfb_ImagBuffer, hFdCngCom->numCoreBands, h_cldfb); + } + else + { + if (slot_index == 0) + { + /* very low level case - update random seeds */ + generate_masking_noise_update_seed(hFdCngCom); + + set_f(fftBuffer, 0.f, hFdCngCom->fftlen); + + /* Perform STFT synthesis */ + SynthesisSTFT(fftBuffer, tdBuffer, hFdCngCom->olapBufferSynth2, hFdCngCom->olapWinSyn, 0, hFdCngCom,X, Y , -1, -1); + +#ifdef DEBUG_MODE_DIRAC + { + int16_t tmp[1000]; + + for (i = 0; i < hFdCngCom->frameSize; i++) + { + tmp[i] = (int16_t)(tdBuffer[i] + 0.5f); + } + dbgwrite(tmp, sizeof(int16_t), hFdCngCom->frameSize, 1, "./res/ivas_dirac_cna_fft.pcm"); + } +#endif + } + + /* LB ana CLDFB*/ + cldfbAnalysis_ts(&(tdBuffer[hFdCngCom->numCoreBands * slot_index]), Cldfb_RealBuffer, Cldfb_ImagBuffer, hFdCngCom->numCoreBands, h_cldfb); + } + } + + /*HF CLDFB - CNA and/or FD-CNG*/ + if (fd_cng_flag) + { + scale += 1.f; + } + if (scale != 0) + { + scale *= CLDFB_SCALING_FLT * (h_cldfb->scale * h_cldfb->scale * 8.f); + ptr_level = hFdCngCom->cngNoiseLevel + hFdCngCom->stopFFTbin - hFdCngCom->startBand; + + for (i = hFdCngCom->numCoreBands; i < hFdCngCom->regularStopBand; i++) + { + /* Real part in CLDFB band */ + rand_gauss(&Cldfb_RealBuffer[i], seed); + Cldfb_RealBuffer[i] *= (float)sqrt((scale * *ptr_level) * 0.5f); + /* Imaginary part in CLDFB band */ + rand_gauss(&Cldfb_ImagBuffer[i], seed); + Cldfb_ImagBuffer[i] *= (float)sqrt((scale * *ptr_level) * 0.5f); + + ptr_level++; + } + } + + wmops_sub_end(); + + return; +} + + +/*------------------------------------------------------------------- + * FdCngDecodeMDCTStereoSID() + * + * Decode FD-Cng parameters for CNG in MDCT-Stereo mode from the bitstream + * + *-------------------------------------------------------------------*/ + +void FdCngDecodeMDCTStereoSID( + CPE_DEC_HANDLE hCPE /* i/o: CPE decoder state structure */ +) +{ + DEC_CORE_HANDLE sts[CPE_CHANNELS]; + HANDLE_FD_CNG_COM hFdCngCom; + float* ms_ptr[CPE_CHANNELS]; + float* lr_ptr[CPE_CHANNELS]; + float logNoiseEst[CPE_CHANNELS][NPART]; + float gain[CPE_CHANNELS]; + int16_t indices[FD_CNG_stages_37bits]; + int16_t N, i, ch, p, stages; + int16_t is_out_ms; + + is_out_ms = 0; + if (hCPE->hCoreCoder[0]->cng_sba_flag) + { + is_out_ms = 1; + } + + N = 0; /* to avoid compilation warning */ + + for (ch = 0; ch < CPE_CHANNELS; ch++) + { + sts[ch] = hCPE->hCoreCoder[ch]; + ms_ptr[ch] = &logNoiseEst[ch][0]; + lr_ptr[ch] = &sts[ch]->hFdCngDec->hFdCngCom->sidNoiseEst[0]; + } + + /* decode noise shapes and gains */ + for (ch = 0; ch < CPE_CHANNELS; ch++) + { + sts[ch] = hCPE->hCoreCoder[ch]; + hFdCngCom = (sts[ch]->hFdCngDec)->hFdCngCom; + N = hFdCngCom->npart; + hFdCngCom->sid_frame_counter++; + + if (ch) + { + stages = FD_CNG_JOINT_stages_25bits; + } + else + { + stages = FD_CNG_stages_37bits; + } + + /* read bitstream */ + for (i = 0; i < stages; i++) + { + indices[i] = get_next_indice(sts[ch], bits_37bits[i]); + } + { + gain[ch] = ((float)get_next_indice(sts[ch], 7) - GAIN_Q_OFFSET_IVAS) / 1.5f; + } + + /* MSVQ decoder */ + msvq_dec(cdk_37bits_ivas, NULL, NULL, stages, N, FD_CNG_maxN_37bits, indices, ms_ptr[ch], NULL); + } + + if (sts[0]->hFdCngDec->hFdCngCom->no_side_flag) + { + set_zero(ms_ptr[1], NPART); + } + + if (is_out_ms == 0) + { + inverseMS(N, ms_ptr[0], ms_ptr[1], 1.f); + } + + for (ch = 0; ch < CPE_CHANNELS; ch++) + { + hFdCngCom = sts[ch]->hFdCngDec->hFdCngCom; + for (p = 0; p < N; p++) + { + lr_ptr[ch][p] = powf(10.f, (ms_ptr[ch][p] + gain[ch]) / 10.f); + } + + scalebands(hFdCngCom->sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, hFdCngCom->stopBand - hFdCngCom->startBand, hFdCngCom->cngNoiseLevel, 1); + + lpc_from_spectrum(hFdCngCom, hFdCngCom->startBand, hFdCngCom->stopFFTbin, sts[ch]->preemph_fac); + } + + if (hCPE->nchan_out == 1 && hCPE->last_element_brate <= IVAS_SID_4k4) + { + /* create proper M noise shape in channel zero after gains have been applied */ + for (p = 0; p < N; p++) + { + sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p] = 0.5f * (sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p] + sts[1]->hFdCngDec->hFdCngCom->sidNoiseEst[p]); + } + } + + return; +} + + +/*------------------------------------------------------------------- + * FdCngDecodeDiracMDCTStereoSID() + * + * Decode FD-Cng parameters for CNG in 2TC DirAC mode from the bitstream + *-------------------------------------------------------------------*/ + +void FdCngDecodeDiracMDCTStereoSID( + CPE_DEC_HANDLE hCPE /* i/o: CPE decoder state structure */ +) +{ + DEC_CORE_HANDLE sts[CPE_CHANNELS]; + HANDLE_FD_CNG_COM hFdCngCom; + float* ms_ptr[CPE_CHANNELS]; + float* lr_ptr[CPE_CHANNELS]; + float logNoiseEst[CPE_CHANNELS][NPART]; + float gain[CPE_CHANNELS]; + int16_t indices[FD_CNG_stages_37bits]; + int16_t N, i, ch, p; + + for (ch = 0; ch < CPE_CHANNELS; ch++) + { + sts[ch] = hCPE->hCoreCoder[ch]; + ms_ptr[ch] = &logNoiseEst[ch][0]; + lr_ptr[ch] = &sts[ch]->hFdCngDec->hFdCngCom->sidNoiseEst[0]; + (sts[ch]->hFdCngDec)->hFdCngCom->sid_frame_counter++; + } + + /* decode noise shapes and gains */ + hFdCngCom = (sts[0]->hFdCngDec)->hFdCngCom; + N = hFdCngCom->npart; + + /* read bitstream */ + for (i = 0; i < FD_CNG_stages_37bits; i++) + { + indices[i] = get_next_indice(sts[0], bits_37bits[i]); + } + gain[0] = ((float)get_next_indice(sts[0], 7) - GAIN_Q_OFFSET_IVAS) / 1.5f; + gain[1] = gain[0]; + + /* MSVQ decoder */ + msvq_dec(cdk_37bits_ivas, NULL, NULL, FD_CNG_stages_37bits, N, FD_CNG_maxN_37bits, indices, ms_ptr[0], NULL); + mvr2r(ms_ptr[0], ms_ptr[1], N); + + /*inverseMS( N, ms_ptr[0], ms_ptr[1], 1.f );*/ + + for (ch = 0; ch < CPE_CHANNELS; ch++) + { + hFdCngCom = sts[ch]->hFdCngDec->hFdCngCom; + for (p = 0; p < N; p++) + { + lr_ptr[ch][p] = powf(10.f, (ms_ptr[ch][p] + gain[ch]) / 10.f); + } + + /* NB last band energy compensation */ + if (hFdCngCom->CngBandwidth == NB) + { + lr_ptr[ch][N - 1] *= NB_LAST_BAND_SCALE; + } + else if (hFdCngCom->CngBandwidth == SWB && hFdCngCom->CngBitrate <= ACELP_13k20) + { + lr_ptr[ch][N - 1] *= SWB_13k2_LAST_BAND_SCALE; + } + + scalebands(hFdCngCom->sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, hFdCngCom->stopBand - hFdCngCom->startBand, hFdCngCom->cngNoiseLevel, 1); + + lpc_from_spectrum(hFdCngCom, hFdCngCom->startBand, hFdCngCom->stopFFTbin, sts[ch]->preemph_fac); + } + sts[0]->hFdCngDec->hFdCngCom->coherence = 0.0f; + sts[1]->hFdCngDec->hFdCngCom->coherence = 0.0f; + + if (hCPE->nchan_out == 1) + { + /* create proper M noise shape in channel zero after gains have been applied */ + for (p = 0; p < N; p++) + { + sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p] = 0.5f * (sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p] + sts[1]->hFdCngDec->hFdCngCom->sidNoiseEst[p]); + } + sts[0]->hFdCngDec->hFdCngCom->coherence = 0.0f; + sts[1]->hFdCngDec->hFdCngCom->coherence = 0.0f; + } + + return; +} +#endif \ No newline at end of file diff --git a/lib_dec/gain_dec_fx.c b/lib_dec/gain_dec_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..7ce5209c9db90a731228655d4e4c56d8a5def87a --- /dev/null +++ b/lib_dec/gain_dec_fx.c @@ -0,0 +1,1279 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ +#include +#include "options.h" /* Compilation switches */ +#include "cnst.h" /* Common constants */ +#include "rom_com.h" /* Static table prototypes */ +#include "prot_fx1.h" /* Function prototypes */ +#include "prot_fx2.h" /* Function prototypes */ + + +/*===========================================================================*/ +/* FUNCTION : Es_pred_dec_fx() */ +/*---------------------------------------------------------------------------*/ +/* PURPOSE : Decoding of scaled predicted innovation energy to be */ +/* used in all subframes */ +/*---------------------------------------------------------------------------*/ +/* INPUT ARGUMENTS : */ +/* _ (Word16) coder_type : coder type */ +/* _ (Word32) core_brate : core bitrate */ +/* _ (Word16*) Es_pred_qua_nb_fx : Gain quantization - quantization table */ +/* for scaled innovation energy prediciton Q8*/ +/*---------------------------------------------------------------------------*/ +/* OUTPUT ARGUMENTS : */ +/* _ (Word16*) Es_pred : predicited scaled innovation energy Q8 */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* RETURN ARGUMENTS : */ +/* _ None */ +/*===========================================================================*/ +void Es_pred_dec_fx( + Word16 *Es_pred, /* o : predicited scaled innovation energy Q8*/ + const Word16 enr_idx, /* i : indice */ + const Word16 nb_bits, /* i : number of bits */ + const Word16 no_ltp /* i : no LTP flag */ +) +{ +#ifdef IVAS_GAIN_MOD + PMT("Verify if Es_pred_dec_fx should use noltp parameters") +#endif +#if 1//def IVAS_GAIN_MOD + IF(no_ltp == 0) +#endif + { + SWITCH(nb_bits) + { + case 5: + *Es_pred = Es_pred_qua_5b_fx[enr_idx]; + move16(); + BREAK; + case 4: + *Es_pred = Es_pred_qua_4b_fx[enr_idx]; + move16(); + BREAK; +#ifdef IVAS_GAIN_MOD + case 3: + *Es_pred = Es_pred_qua_3b_fx[enr_idx]; + break; +#endif + default: + *Es_pred = Es_pred_qua_5b_fx[enr_idx]; + move16(); + BREAK; + } + } +#ifdef IVAS_GAIN_MOD + ELSE + { + *Es_pred = Es_pred_qua_4b_no_ltp_fx[enr_idx]; + } +#endif +} +/*======================================================================================*/ +/* FUNCTION : void gain_dec_tc_fx () */ +/*--------------------------------------------------------------------------------------*/ +/* PURPOSE : Decoding of pitch and codebook gains and updating long term energies */ +/*--------------------------------------------------------------------------------------*/ +/* INPUT ARGUMENTS : */ +/* Word32 core_brate_fx i : core bitrate */ +/* Word16 *code_fx i : algebraic code excitation */ +/* Word16 L_frame_fx i : length of the frame */ +/* Word16 i_subfr_fx i : subframe number */ +/* Word16 tc_subfr_fx i : TC subframe index */ +/* Word16 Es_pred_fx i : predicted scaled innov. energy Q8 */ +/*--------------------------------------------------------------------------------------*/ +/* OUTPUT ARGUMENTS : */ +/* Word16 *gain_pit_fx o : pitch gain Q14 */ +/* Word32 *gain_code_fx o : Quantized codeebook gain Q16 */ +/* Word16 *gain_inov_fx o : unscaled innovation gain Q12 */ +/* Word32 *norm_gain_code_fx o : norm. gain of the codebook excit. Q16 */ +/*--------------------------------------------------------------------------------------*/ +/* INPUT/OUTPUT ARGUMENTS : */ +/*--------------------------------------------------------------------------------------*/ +/* RETURN ARGUMENTS : */ +/* _ None */ +/*--------------------------------------------------------------------------------------*/ +/* CALLED FROM : */ +/*======================================================================================*/ + +void gain_dec_tc_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + const Word16 *code_fx, /* i : algebraic code excitation */ + const Word16 i_subfr_fx, /* i : subframe number */ + const Word16 Es_pred_fx, /* i : predicted scaled innov. energy */ + Word16 *gain_pit_fx, /* o : pitch gain */ + Word32 *gain_code_fx, /* o : Quantized codeebook gain */ + Word16 *gain_inov_fx, /* o : unscaled innovation gain */ + Word32 *norm_gain_code_fx /* o : norm. gain of the codebook excit. */ +) +{ + Word16 index, nBits; + Word16 gcode0_fx; + Word16 Ei_fx; + Word16 expg, expg2, e_tmp, f_tmp, exp_gcode0, tmp_fx, frac; + Word32 L_tmp, L_tmp1; + Word16 wgain_code=0; + move16(); + *gain_pit_fx = 0; + move16(); + + /*----------------------------------------------------------------* + * find number of bits for gain dequantization + *----------------------------------------------------------------*/ + nBits = st_fx->acelp_cfg.gains_mode[shr(i_subfr_fx, 6)]; + /*-----------------------------------------------------------------* + * calculate the predicted gain code + *-----------------------------------------------------------------*/ + + /*Ecode = (dotp( code, code, L_SUBFR) + 0.01f) / L_SUBFR; + *gain_inov = 1.0f / (float)sqrt( Ecode );*/ + L_tmp = Dot_product12(code_fx, code_fx, L_SUBFR, &expg); + expg = sub(expg, 18 + 6); /* exp: -18 (code in Q9), -6 (/L_SUBFR) */ + expg2 = expg; + move16(); + L_tmp1 = L_tmp; /* sets to 'L_tmp' in 1 clock */ + move32(); + L_tmp = Isqrt_lc(L_tmp, &expg); + + *gain_inov_fx = extract_h(L_shl(L_tmp, sub(expg, 3))); + move16(); /* gain_inov in Q12 */ + + + /* Ei = 10 * (float)log10( Ecode );*/ + e_tmp = norm_l(L_tmp1); + f_tmp = Log2_norm_lc(L_shl(L_tmp1, e_tmp)); + e_tmp = sub(expg2,add(1,e_tmp)); + L_tmp1 = Mpy_32_16(e_tmp, f_tmp, 12330); /* Q13 */ /* 10*log10(2) in Q12*/ + Ei_fx = round_fx(L_shl(L_tmp1, 11)); /* Q8 */ + /* gcode0 = (float) pow(10, 0.05 * (Es_pred - Ei));*/ + gcode0_fx = sub(Es_pred_fx, Ei_fx); /* Q8 */ + + /*-----------------------------------------------------------------* + * gcode0 = pow(10.0, gcode0/20) + * = pow(2, 3.321928*gcode0/20) + * = pow(2, 0.166096*gcode0) + *-----------------------------------------------------------------*/ + L_tmp = L_mult(gcode0_fx, 21771); /* *0.166096 in Q17 -> Q26 */ + L_tmp = L_shr(L_tmp, 10); /* From Q26 to Q16 */ + frac = L_Extract_lc(L_tmp, &exp_gcode0); /* Extract exponent of gcode0 */ + gcode0_fx = extract_l(Pow2(14, frac));/* Put 14 as exponent so that */ + /* output of Pow2() will be: */ + /* 16384 < Pow2() <= 32767 */ + exp_gcode0 = sub(exp_gcode0, 14); + /*------------------------------------------------------------------------------------------* + * Select the gain quantization table and dequantize the gain + *------------------------------------------------------------------------------------------*/ + + /* index = (Word16)get_indice( st_fx,"gain_code", i_subfr_fx, ACELP_CORE);move16();*/ + index = (Word16)get_next_indice( st_fx, nBits ); + move16(); + + + IF( GT_16(nBits,3)) + { + wgain_code = gain_dequant_fx( index, G_CODE_MIN_TC_Q15, G_CODE_MAX_TC_Q0, nBits, &expg ); + wgain_code = shl(wgain_code,add(expg,13)); /* wgain_code in Q13*/ + } + ELSE /* nBits == 3 */ + { + wgain_code = tbl_gain_code_tc_fx[index]; + move16(); + } + + /*-----------------------------------------------------------------* + * decode normalized codebook gain + *-----------------------------------------------------------------*/ + + /* *gain_code *= gcode0;*/ + L_tmp = L_mult(wgain_code, gcode0_fx); /* Q13*Q0 -> Q14 */ + *gain_code_fx= L_shl(L_tmp, add(exp_gcode0, 2)); + move32(); /* Q14 -> Q16 */ + + /**norm_gain_code = *gain_code / *gain_inov;*/ + expg = sub(norm_s(*gain_inov_fx),1); + expg = s_max(expg, 0); + + tmp_fx = div_s(shr(8192,expg),*gain_inov_fx); + *norm_gain_code_fx = L_shr(Mult_32_16(*gain_code_fx, tmp_fx),sub(1,expg)); + move32(); + + return; +} +/*======================================================================================*/ +/* FUNCTION : gain_dec_mless_fx() */ +/*--------------------------------------------------------------------------------------*/ +/* PURPOSE : Decoding of pitch and codebook gains without updating long term energies */ +/*--------------------------------------------------------------------------------------*/ +/* INPUT ARGUMENTS : */ +/* _ (Word32) core_brate_fx : core bitrate */ +/* _ (Word16) L_frame_fx : length of the frame */ +/* _ (Word16) coder_type_fx : coding type */ +/* _ (Word16) i_subfr_fx : subframe index */ +/* _ (Word16) tc_subfr_fx : TC subframe index */ +/* _ (Word16*[]) code_fx : algebraic code excitation (Q12) */ +/* _ (Word16) Es_pred_fx : predicted scaled innov. energy (Q8) */ +/*--------------------------------------------------------------------------------------*/ +/* OUTPUT ARGUMENTS : */ +/* _ (Word16*) gain_pit_fx : quantized pitch gain (Q14) */ +/* _ (Word32*) gain_code_fx : quantized codebook gain (Q16) */ +/* _ (Word16*) gain_inov_fx : gain of the innovation (used for normalization) (Q12) */ +/* _ (Word32*) norm_gain_code_fx : norm. gain of the codebook excitation (Q16) */ +/*--------------------------------------------------------------------------------------*/ +/* INPUT/OUTPUT ARGUMENTS : */ +/* _ None */ +/*--------------------------------------------------------------------------------------*/ + +/* _ None */ +/*--------------------------------------------------------------------------------------*/ +/* RETURN ARGUMENTS : */ +/* _ None */ +/*======================================================================================*/ +void gain_dec_mless_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + const Word16 L_frame_fx, /* i : length of the frame */ + const Word16 coder_type_fx, /* i : coding type */ + const Word16 i_subfr_fx, /* i : subframe number */ + const Word16 tc_subfr_fx, /* i : TC subframe index */ + const Word16 *code_fx, /* i : algebraic code excitation */ + const Word16 Es_pred_fx, /* i : predicted scaled innov. energy */ + Word16 *gain_pit_fx, /* o : Quantized pitch gain Q14*/ + Word32 *gain_code_fx, /* o : Quantized codeebook gain Q16*/ + Word16 *gain_inov_fx, /* o : unscaled innovation gain Q12*/ + Word32 *norm_gain_code_fx /* o : norm. gain of the codebook excitation Q16*/ +) +{ + Word16 index, nBits; + Word16 gcode0_fx, Ei_fx, gain_code16; + const Word16 *qua_table_fx; + Word16 expg, expg2, e_tmp, f_tmp, exp_gcode0, tmp_fx, frac; + Word32 L_tmp, L_tmp1; + + /*-----------------------------------------------------------------* + * decode pitch gain + *-----------------------------------------------------------------*/ + nBits = st_fx->acelp_cfg.gains_mode[shr(i_subfr_fx, 6) ]; + test(); + test(); + test(); + test(); + test(); + IF( (EQ_16(tc_subfr_fx,3*L_SUBFR )&&EQ_16(i_subfr_fx,3*L_SUBFR)&&EQ_16(L_frame_fx,L_FRAME))|| + (EQ_16(tc_subfr_fx,4*L_SUBFR ) && EQ_16(i_subfr_fx,4*L_SUBFR) && EQ_16(L_frame_fx,L_FRAME16k)) ) + { + /* decode pitch gain */ + index = (Word16)get_next_indice( st_fx, shr(nBits,1) ); + move16(); + + /*Ei = (G_PITCH_MAX_TC192 - G_PITCH_MIN_TC192) / ((1 << (nBits>>1)) - 1);*/ /* set quantization step */ + tmp_fx = div_s(1,sub(shl(1,shr(nBits,1)),1)); /*Q15*/ + Ei_fx = mult_r(G_PITCH_MAX_MINUS_MIN_TC192_Q13,tmp_fx); /*Q13*/ + + /**gain_pit = usdequant( index, G_PITCH_MIN_TC192, Ei );*/ + *gain_pit_fx = usdequant_fx( index, G_PITCH_MIN_TC192_Q14, Ei_fx ); + move16(); /*Q14*/ + + /* calculate the predicted gain code */ + /*Ecode = (dotp( code, code, L_SUBFR) + 0.01f) / L_SUBFR; + *gain_inov = 1.0f / (float)sqrt( Ecode );*/ + L_tmp = Dot_product12(code_fx, code_fx, L_SUBFR, &expg); + expg = sub(expg, 18 + 6); /* exp: -18 (code in Q12), -6 (/L_SUBFR) */ + expg2 = expg; + move16(); + L_tmp1 = L_tmp; /* sets to 'L_tmp' in 1 clock */ + move32(); + L_tmp = Isqrt_lc(L_tmp, &expg); + + *gain_inov_fx = extract_h(L_shl(L_tmp, sub(expg, 3))); /* gain_inov in Q12 */ + + /*Ei = 10 * (float)log10( Ecode );*/ + e_tmp = norm_l(L_tmp1); + f_tmp = Log2_norm_lc(L_shl(L_tmp1, e_tmp)); + e_tmp = sub(expg2,add(1,e_tmp)); + L_tmp1 = Mpy_32_16(e_tmp, f_tmp, 12330); /* Q13 */ /* 10*log10(2) in Q12*/ + Ei_fx = round_fx(L_shl(L_tmp1, 11)); /* Q8 */ + + /*-----------------------------------------------------------------* + * calculate the predicted gain code + *-----------------------------------------------------------------*/ + + /*gcode0 = (float) pow(10, 0.05 * (Es_pred - Ei));*/ + gcode0_fx = sub(Es_pred_fx, Ei_fx); /* Q8 */ + + /*-----------------------------------------------------------------* + * gcode0 = pow(10.0, gcode0/20) + * = pow(2, 3.321928*gcode0/20) + * = pow(2, 0.166096*gcode0) + *-----------------------------------------------------------------*/ + L_tmp = L_mult(gcode0_fx, 21771); /* *0.166096 in Q17 -> Q26 */ + L_tmp = L_shr(L_tmp, 10); /* From Q26 to Q16 */ + frac = L_Extract_lc(L_tmp, &exp_gcode0); /* Extract exponent of gcode0 */ + + gcode0_fx = extract_l(Pow2(14, frac));/* Put 14 as exponent so that */ + /* output of Pow2() will be: */ + /* 16384 < Pow2() <= 32767 */ + exp_gcode0 = sub(exp_gcode0, 14); + + /* decode normalized codebook gain */ + /*index = (short)get_indice( st_fx, "gain_code", i_subfr_fx, ACELP_CORE );move16();*/ + index = (Word16)get_next_indice( st_fx, shr(add(nBits,1),1) ); + move16(); + + /**gain_code = gain_dequant( index, G_CODE_MIN_TC192, G_CODE_MAX_TC192, (nBits+1)>>1 );*/ + gain_code16 = gain_dequant_fx( index, G_CODE_MIN_TC192_Q15, G_CODE_MAX_TC192_Q0, shr(add(nBits,1),1), &expg ); + move16(); + + /**gain_code *= gcode0;*/ + L_tmp = L_mult(gain_code16,gcode0_fx); /*Q0*Q0 -> Q1*/ + *gain_code_fx = L_shl(L_tmp,add(add(expg,exp_gcode0),15)); + move32(); /*Q16*/ + } + ELSE + { + SWITCH ( nBits ) + { + case 7: + { + qua_table_fx = gain_qua_mless_7b_fx; + move16(); + BREAK; + } + case 6: + { + qua_table_fx = gain_qua_mless_6b_fx; + move16(); + IF (GT_16(st_fx->element_mode, EVS_MONO) ) + { + //PMT("gain_qua_mless_6b_stereo to fixed point") + //qua_table_fx = gain_qua_mless_6b_stereo; + } + BREAK; + } + case 5: + { + qua_table_fx = gain_qua_mless_5b_fx; + move16(); + BREAK; + } + default: + { + qua_table_fx = gain_qua_mless_6b_fx; + move16(); + BREAK; + } + } + + test(); + if( EQ_16(coder_type_fx,INACTIVE)&&EQ_16(nBits,6)) + { + nBits = sub(nBits, 1); + } + + index = (Word16)get_next_indice( st_fx, nBits ); + move16(); + + *gain_pit_fx = qua_table_fx[index * 2]; + move16(); + + /*Ecode = (dotp( code, code, L_SUBFR) + 0.01f) / L_SUBFR; + *gain_inov = 1.0f / (float)sqrt( Ecode );*/ + + L_tmp = Dot_product12(code_fx, code_fx, L_SUBFR, &expg); + expg = sub(expg, 18 + 6); /* exp: -18 (code in Q9), -6 (/L_SUBFR) */ + expg2 = expg; + move16(); + L_tmp1 = L_tmp; /* sets to 'L_tmp' in 1 clock */ + move32(); + L_tmp = Isqrt_lc(L_tmp, &expg); + + *gain_inov_fx = extract_h(L_shl(L_tmp, sub(expg, 3))); /* gain_inov in Q12 */ + + /*Ei = 10 * (float)log10( Ecode );*/ + e_tmp = norm_l(L_tmp1); + f_tmp = Log2_norm_lc(L_shl(L_tmp1, e_tmp)); + e_tmp = sub(expg2,add(1,e_tmp)); + L_tmp1 = Mpy_32_16(e_tmp, f_tmp, 12330); /* Q13 */ /* 10*log10(2) in Q12*/ + Ei_fx = round_fx(L_shl(L_tmp1, 11)); /* Q8 */ + + /*-----------------------------------------------------------------* + * calculate the predicted gain code + *-----------------------------------------------------------------*/ + + /*gcode0 = (float) pow(10, 0.05 * (Es_pred - Ei));*/ + gcode0_fx = sub(Es_pred_fx, Ei_fx); /* Q8 */ + + /*-----------------------------------------------------------------* + * gcode0 = pow(10.0, gcode0/20) + * = pow(2, 3.321928*gcode0/20) + * = pow(2, 0.166096*gcode0) + *-----------------------------------------------------------------*/ + L_tmp = L_mult(gcode0_fx, 21771); /* *0.166096 in Q17 -> Q26 */ + L_tmp = L_shr(L_tmp, 10); /* From Q26 to Q16 */ + frac = L_Extract_lc(L_tmp, &exp_gcode0); /* Extract exponent of gcode0 */ + + gcode0_fx = extract_l(Pow2(14, frac));/* Put 14 as exponent so that */ + /* output of Pow2() will be: */ + /* 16384 < Pow2() <= 32767 */ + exp_gcode0 = sub(exp_gcode0, 14); + + /*-----------------------------------------------------------------* + * decode normalized codebook gain + *-----------------------------------------------------------------*/ + + /**gain_code = qua_table[index * 2 + 1] * gcode0;*/ + L_tmp = L_mult(qua_table_fx[add(shl(index,1),1)] , gcode0_fx); /* Q9*Q0 -> Q10 */ + *gain_code_fx = L_shl(L_tmp, add(exp_gcode0, 6)); + move32(); /* Q10 -> Q16*/ + } + + /**norm_gain_code = *gain_code / *gain_inov;*/ + expg = sub(norm_s(*gain_inov_fx),1); + expg = s_max(expg, 0); + + tmp_fx = div_s(shr(8192,expg),*gain_inov_fx); + *norm_gain_code_fx = L_shr(Mult_32_16(*gain_code_fx, tmp_fx),sub(1,expg)); + move32(); + + return; +} + +/*==================================================================================*/ +/* FUNCTION : gain_dec_lbr_fx() */ +/*----------------------------------------------------------------------------------*/ +/* PURPOSE : Decoding of pitch and codebook gains in ACELP at 6.6 and 7.5 kbps */ +/*----------------------------------------------------------------------------------*/ +/* INPUT ARGUMENTS : */ +/* _ (Word32) core_brate : core bitrate */ +/* _ (Word16) coder_type : coding type */ +/* _ (Word16) i_subfr : subframe index */ +/* _ (Word16*[]) code_fx : algebraic excitation (Q12) */ +/*----------------------------------------------------------------------------------*/ +/* OUTPUT ARGUMENTS : */ +/* _ (Word16*) gain_pit_fx : quantized pitch gain (Q14) */ +/* _ (Word32*) gain_code_fx : quantized codebook gain (Q16) */ +/* _ (Word16*) gain_inov_fx : gain of the innovation (used for normalization) (Q12) */ +/* _ (Word32*) norm_gain_code_fx : norm. gain of the codebook excitation (Q12) */ +/*----------------------------------------------------------------------------------*/ +/* INPUT/OUTPUT ARGUMENTS : */ +/* _ None */ +/*----------------------------------------------------------------------------------*/ + +/* _ None */ +/*----------------------------------------------------------------------------------*/ +/* RETURN ARGUMENTS : */ +/* _ None */ +/*==================================================================================*/ +void gain_dec_lbr_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + const Word16 coder_type, /* i : coding type */ + const Word16 i_subfr, /* i : subframe index */ + const Word16 *code_fx, /* i : algebraic excitation Q9 */ + Word16 *gain_pit_fx, /* o : quantized pitch gain Q14*/ + Word32 *gain_code_fx, /* o : quantized codebook gain Q16*/ + Word16 *gain_inov_fx, /* o : gain of the innovation (used for normalization) Q12*/ + Word32 *norm_gain_code_fx, /* o : norm. gain of the codebook excitation Q16*/ + Word32 gc_mem[], /* i/o: gain_code from previous subframes */ + Word16 gp_mem[], /* i/o: gain_pitch from previous subframes */ + const Word16 L_subfr /* i : subfr lenght */ +) +{ + Word16 index, nBits, n_pred, ctype; + Word16 gcode0_fx, aux_fx[10]; + Word32 L_tmp, L_tmp1, L_tmp2; + Word16 expg, expg2, e_tmp, exp_gcode0, f_tmp, frac, tmp_fx; + const Word16 *b_fx ,*cdbk_fx = 0; + /* Ecode = ( dotp( code, code, L_SUBFR ) + 0.01f ) / L_SUBFR; + *gain_inov = 1.0f / (float)sqrt(Ecode); */ + Word16 shift_L_subfr; + shift_L_subfr = 6; + move16(); + IF(GT_16(L_subfr, L_SUBFR)) + { + shift_L_subfr = add(shift_L_subfr, 1); + } + L_tmp = Dot_product12(code_fx, code_fx, L_subfr, &expg); + expg = sub(expg, add(18, shift_L_subfr)); /* exp: -18 (code in Q9), -6 (/L_SUBFR) */ + + expg2 = expg; + move16(); + L_tmp2 = L_tmp; /* sets to 'L_tmp' in 1 clock */ + move32(); + L_tmp = Isqrt_lc(L_tmp, &expg); + + *gain_inov_fx = extract_h(L_shl(L_tmp, sub(expg, 3))); /* gain_inov in Q12 */ + + + /*-----------------------------------------------------------------* + * select the codebook, size and number of bits + * set the gains searching range + *-----------------------------------------------------------------*/ + nBits = st_fx->acelp_cfg.gains_mode[shr(i_subfr, shift_L_subfr)]; + move16(); + + ctype = shl(sub(coder_type, 1),1); + + /*-----------------------------------------------------------------* + * calculate prediction of gcode + * search for the best codeword + *-----------------------------------------------------------------*/ + IF (i_subfr == 0) + { + b_fx = b_1sfr_fx; + move16(); + n_pred = 2; + move16(); + cdbk_fx = gp_gamma_1sfr_6b_fx; + SWITCH ( nBits ) + { + case 8: + { + cdbk_fx = gp_gamma_1sfr_8b_fx; /* Q14/Q9*/ + move16(); + BREAK; + } + case 7: + { + cdbk_fx = gp_gamma_1sfr_7b_fx; /* Q14/Q9*/ + move16(); + BREAK; + } + case 6: + { + cdbk_fx = gp_gamma_1sfr_6b_fx; /* Q14/Q9*/ + move16(); + BREAK; + } + } + + /* calculate predicted gain */ + aux_fx[0] = 4096; + move16(); + aux_fx[1] = shl(ctype,12); + + /* gcode0 = (float)pow(10, dotp(b, aux, n_pred) - 0.5f * (float)log10(Ecode)); + gcode0 = (float)pow(10, dotp(b, aux, n_pred) - 0.05f * 10 * (float)log10(Ecode)); + gcode0 = (float)pow(10, 0.05(20 * dotp(b, aux, n_pred) - 10 * (float)log10(Ecode))); */ + + e_tmp = norm_l(L_tmp2); + f_tmp = Log2_norm_lc(L_shl(L_tmp2, e_tmp)); + e_tmp = sub(expg2,add(1,e_tmp)); + L_tmp1 = Mpy_32_16(e_tmp, f_tmp, 12330); /* Q13 */ /* 10*log10(2) in Q12*/ + + L_tmp = Dot_product(b_fx, aux_fx, n_pred); /*Q25*/ + L_tmp = Mult_32_16(L_tmp,160);/*Q13, 20 in Q3*/ + L_tmp = L_sub(L_tmp,L_tmp1);/*Q13*/ + + gcode0_fx = round_fx(L_shl(L_tmp, 11)); /* Q8 */ + + + /*-----------------------------------------------------------------* + * gcode0 = pow(10.0, gcode0/20) + * = pow(2, 3.321928*gcode0/20) + * = pow(2, 0.166096*gcode0) + *-----------------------------------------------------------------*/ + + L_tmp = L_mult(gcode0_fx, 21771); /* *0.166096 in Q17 -> Q26 */ + L_tmp = L_shr(L_tmp, 10); /* From Q26 to Q16 */ + frac = L_Extract_lc(L_tmp, &exp_gcode0); /* Extract exponent of gcode0 */ + + gcode0_fx = extract_l(Pow2(14, frac));/* Put 14 as exponent so that */ + /* output of Pow2() will be: */ + /* 16384 < Pow2() <= 32767 */ + exp_gcode0 = sub(exp_gcode0, 14); + + /* retrieve the codebook index and calculate both gains */ + /*index = (Word16)get_indice( st_fx,"gain", i_subfr, ACELP_CORE);move16();*/ + index = (Word16)get_next_indice( st_fx, nBits ); + move16(); + + *gain_pit_fx = cdbk_fx[index * 2]; + move16(); + + L_tmp = L_mult(cdbk_fx[add(shl(index,1),1)] , gcode0_fx); /* Q9*Q0 -> Q10 */ + *gain_code_fx = L_shl(L_tmp, add(exp_gcode0, 6)); + move16(); /* Q10 -> Q16*/ + + gc_mem[0] = *gain_code_fx; + move32(); /*Q16*/ + gp_mem[0] = *gain_pit_fx; + move16(); /*Q14*/ + } + ELSE IF (EQ_16(i_subfr,L_SUBFR) || EQ_16(L_subfr, 2*L_SUBFR)) + { + b_fx = b_2sfr_fx; + move16(); + n_pred = 4; + move16(); + + cdbk_fx = gp_gamma_1sfr_6b_fx; + SWITCH ( nBits ) + { + case 7: + { + cdbk_fx = gp_gamma_2sfr_7b_fx; /* Q14/Q9*/ + move16(); + BREAK; + } + case 6: + { + cdbk_fx = gp_gamma_2sfr_6b_fx; /* Q14/Q9*/ + move16(); + BREAK; + } + } + + /* calculate predicted gain */ + aux_fx[0] = 4096; + move16(); + aux_fx[1] = shl(ctype,12); + + /*aux_fx[2] = (float)log10(gc_mem[0]); + = log2(gc_mem[0])*log10(2);*/ + e_tmp = norm_l(gc_mem[0]); + f_tmp = Log2_norm_lc(L_shl(gc_mem[0], e_tmp)); + e_tmp = sub(sub(30,e_tmp),16); /*Q_format(gc_mem[0])=16*/ + L_tmp1 = Mpy_32_16(e_tmp, f_tmp, 9864); /* Q16 */ + aux_fx[2] = round_fx(L_shl(L_tmp1, 12)); /* Q12 */ + + aux_fx[3] = shr(gp_mem[0],2); /*Q12*/ + + /*-----------------------------------------------------------------* + * gcode0 = pow(10.0, dotp(b, aux, n_pred) + * = pow(2, 3.321928*dotp(b, aux, n_pred) + *-----------------------------------------------------------------*/ + L_tmp = Dot_product(b_fx, aux_fx, n_pred); /*Q25*/ + L_tmp = Mult_32_16(L_tmp, 27213); /* *3.321928 in Q13 -> Q23 */ + L_tmp = L_shr(L_tmp, 7); /* From Q23 to Q16 */ + frac = L_Extract_lc(L_tmp, &exp_gcode0); /* Extract exponent of gcode0 */ + + gcode0_fx = extract_l(Pow2(14, frac));/* Put 14 as exponent so that */ + /* output of Pow2() will be: */ + /* 16384 < Pow2() <= 32767 */ + exp_gcode0 = sub(exp_gcode0, 14); + + /* retrieve the codebook index and calculate both gains */ + index = (Word16)get_next_indice( st_fx, nBits ); + move16(); + + *gain_pit_fx = cdbk_fx[index * 2]; + move16(); + + L_tmp = L_mult(cdbk_fx[add(shl(index,1),1)] , gcode0_fx); /* Q9*Q0 -> Q10 */ + *gain_code_fx = L_shl(L_tmp, add(exp_gcode0, 6)); + move16(); /* Q10 -> Q16*/ + + gc_mem[1] = *gain_code_fx; + move32(); + gp_mem[1] = *gain_pit_fx; + move16(); + } + ELSE IF (EQ_16(i_subfr,2*L_SUBFR)) + { + b_fx = b_3sfr_fx; + move16(); + n_pred = 6; + move16(); + + cdbk_fx = gp_gamma_3sfr_6b_fx; +#ifdef IVAS_GAIN_MOD + IF(EQ_16(nBits, 7)) + { + cdbk_fx = gp_gamma_3sfr_7b_fx; + PMT("verify if gp_gamma_3sfr_7b_fx is correct") + } +#endif + move16(); /* Q14/Q9*/ + + /* calculate predicted gain */ + aux_fx[0] = 4096; + move16(); + aux_fx[1] = shl(ctype,12); + move16(); + + /*aux_fx[2] = (float)log10(gc_mem[0]); + = log2(gc_mem[0])*log10(2);*/ + e_tmp = norm_l(gc_mem[0]); + f_tmp = Log2_norm_lc(L_shl(gc_mem[0], e_tmp)); + e_tmp = sub(sub(30,e_tmp),16); /*Q_format(gc_mem[0])=16*/ + L_tmp1 = Mpy_32_16(e_tmp, f_tmp, 9864); /* Q16 */ + aux_fx[2] = round_fx(L_shl(L_tmp1, 12)); /* Q12 */ + + /*aux[3] = (float)log10(gc_mem[1]); + = log2(gc_mem[1])*log10(2);*/ + e_tmp = norm_l(gc_mem[1]); + f_tmp = Log2_norm_lc(L_shl(gc_mem[1], e_tmp)); + e_tmp = sub(sub(30,e_tmp),16); /*Q_format(gc_mem[1])=16*/ + L_tmp1 = Mpy_32_16(e_tmp, f_tmp, 9864); /* Q16 */ + aux_fx[3] = round_fx(L_shl(L_tmp1, 12)); /* Q12 */ + + aux_fx[4] = shr(gp_mem[0],2); + move16(); + aux_fx[5] = shr(gp_mem[1],2); + move16(); + + /*-----------------------------------------------------------------* + * gcode0 = pow(10.0, dotp(b, aux, n_pred) + * = pow(2, 3.321928*dotp(b, aux, n_pred) + *-----------------------------------------------------------------*/ + L_tmp = Dot_product(b_fx, aux_fx, n_pred); /*Q25*/ + L_tmp = Mult_32_16(L_tmp, 27213); /* *3.321928 in Q13 -> Q23 */ + L_tmp = L_shr(L_tmp, 7); /* From Q23 to Q16 */ + frac = L_Extract_lc(L_tmp, &exp_gcode0); /* Extract exponent of gcode0 */ + + gcode0_fx = extract_l(Pow2(14, frac));/* Put 14 as exponent so that */ + /* output of Pow2() will be: */ + /* 16384 < Pow2() <= 32767 */ + exp_gcode0 = sub(exp_gcode0, 14); + + /* retrieve the codebook index and calculate both gains */ + index = (Word16)get_next_indice( st_fx, nBits ); + move16(); + + *gain_pit_fx = cdbk_fx[index * 2]; + move16(); + + L_tmp = L_mult(cdbk_fx[add(shl(index,1),1)] , gcode0_fx); /* Q9*Q0 -> Q10 */ + *gain_code_fx = L_shl(L_tmp, add(exp_gcode0, 6)); /* Q10 -> Q16*/ + + gc_mem[2] = *gain_code_fx; + move32(); + gp_mem[2] = *gain_pit_fx; + move16(); + } + ELSE IF (EQ_16(i_subfr,3*L_SUBFR)) + { + b_fx = b_4sfr_fx; + move16(); + n_pred = 8; + move16(); + + + cdbk_fx = gp_gamma_4sfr_6b_fx; +#ifdef IVAS_GAIN_MOD + IF(EQ_16(nBits, 7)) + { + cdbk_fx = gp_gamma_4sfr_7b_fx; + PMT("verify if gp_gamma_4sfr_7b_fx is correct") + } +#endif + move16(); /* Q14/Q9*/ + + /* calculate predicted gain */ + aux_fx[0] = 4096; + move16(); + aux_fx[1] = shl(ctype,12); + move16(); + + /*aux[2] = (float)log10(gc_mem[0]); + = log2(gc_mem[0])*log10(2);*/ + e_tmp = norm_l(gc_mem[0]); + f_tmp = Log2_norm_lc(L_shl(gc_mem[0], e_tmp)); + e_tmp = sub(sub(30,e_tmp),16); /*Q_format(gc_mem[0])=16*/ + L_tmp1 = Mpy_32_16(e_tmp, f_tmp, 9864); /* Q16 */ + aux_fx[2] = round_fx(L_shl(L_tmp1, 12)); /* Q12 */ + + /*aux[3] = (float)log10(gc_mem[1]); + = log2(gc_mem[1])*log10(2);*/ + e_tmp = norm_l(gc_mem[1]); + f_tmp = Log2_norm_lc(L_shl(gc_mem[1], e_tmp)); + e_tmp = sub(sub(30,e_tmp),16); /*Q_format(gc_mem[1])=16*/ + L_tmp1 = Mpy_32_16(e_tmp, f_tmp, 9864); /* Q16 */ + aux_fx[3] = round_fx(L_shl(L_tmp1, 12)); /* Q12 */ + + /*aux[4] = (float)log10(gc_mem[2]); + = log2(gc_mem[2])*log10(2);*/ + e_tmp = norm_l(gc_mem[2]); + f_tmp = Log2_norm_lc(L_shl(gc_mem[2], e_tmp)); + e_tmp = sub(sub(30,e_tmp),16); /*Q_format(gc_mem[2])=16*/ + L_tmp1 = Mpy_32_16(e_tmp, f_tmp, 9864); /* Q16 */ + aux_fx[4] = round_fx(L_shl(L_tmp1, 12)); /* Q12 */ + + aux_fx[5] = shr(gp_mem[0],2);/*Q12*/ move16(); + aux_fx[6] = shr(gp_mem[1],2);/*Q12*/ move16(); + aux_fx[7] = shr(gp_mem[2],2);/*Q12*/ move16(); + + /*-----------------------------------------------------------------* + * gcode0 = pow(10.0, dotp(b, aux, n_pred) + * = pow(2, 3.321928*dotp(b, aux, n_pred) + *-----------------------------------------------------------------*/ + L_tmp = Dot_product(b_fx, aux_fx, n_pred); /*Q25*/ + L_tmp = Mult_32_16(L_tmp, 27213); /* *3.321928 in Q13 -> Q23 */ + L_tmp = L_shr(L_tmp, 7); /* From Q23 to Q16 */ + frac = L_Extract_lc(L_tmp, &exp_gcode0); /* Extract exponent of gcode0 */ + + gcode0_fx = extract_l(Pow2(14, frac));/* Put 14 as exponent so that */ + /* output of Pow2() will be: */ + /* 16384 < Pow2() <= 32767 */ + exp_gcode0 = sub(exp_gcode0, 14); + + /* retrieve the codebook index and calculate both gains */ + index = (Word16)get_next_indice( st_fx, nBits ); + move16(); + *gain_pit_fx = cdbk_fx[index * 2]; + move16(); + + L_tmp = L_mult(cdbk_fx[add(shl(index,1),1)] , gcode0_fx); /* Q9*Q0 -> Q10 */ + *gain_code_fx = L_shl(L_tmp, add(exp_gcode0, 6)); + move32(); /* Q10 -> Q16*/ + } + + /* *norm_gain_code = *gain_code / *gain_inov; */ + expg = sub(norm_s(*gain_inov_fx),1); + expg = s_max(expg, 0); + + tmp_fx = div_s(shr(8192,expg),*gain_inov_fx); + *norm_gain_code_fx = L_shr(Mult_32_16(*gain_code_fx, tmp_fx),sub(1,expg)); + move32(); + + return; +} + +/*====================================================================== */ +/* FUNCTION : lp_gain_updt_fx() */ +/*-----------------------------------------------------------------------*/ +/* PURPOSE : Update of LP pitch and code gains (FEC) */ +/* */ +/*-----------------------------------------------------------------------*/ +/* INPUT ARGUMENTS : */ +/* _ (Word16) i_subfr : subframe number Q0 */ +/* _ (Word16) gain_pit : Decoded gain pitch Q14 */ +/* _ (Word32) norm_gain_code : Normalised gain code Q16 */ +/* _ (Word16) L_frame : length of the frame Q0 */ +/*-----------------------------------------------------------------------*/ +/* OUTPUT ARGUMENTS : */ +/* _ (Word16 *) T0 : close loop integer pitch */ +/* _ (Word16 *) T0_frac : close loop fractional part of the pitch */ +/* _ (Word16 ) pitch : pitch value Q6 */ +/*-----------------------------------------------------------------------*/ +/* INPUT OUTPUT ARGUMENTS */ +/* _ (Word16 *) lp_gainp : LP-filtered pitch gain(FEC) Q14 */ +/* _ (Word16 *) lp_gainc : LP-filtered code gain (FEC) Q3 */ +/*-----------------------------------------------------------------------*/ + +/*-----------------------------------------------------------------------*/ +/* RETURN ARGUMENTS : */ +/* _ None */ +/*=======================================================================*/ + + +void lp_gain_updt_fx( + const Word16 i_subfr, /* i : subframe number Q0 */ + const Word16 gain_pit, /* i : Decoded gain pitch Q14 */ + const Word32 norm_gain_code, /* i : Normalised gain code Q16 */ + Word16 *lp_gainp, /* i/o: LP-filtered pitch gain(FEC) Q14 */ + Word16 *lp_gainc, /* i/o: LP-filtered code gain (FEC) Q3 */ + const Word16 L_frame /* i : length of the frame */ +) +{ + Word16 tmp; + +#ifdef BASOP_NOGLOB + tmp = extract_h(L_shl_sat(norm_gain_code, 3)); /*(16+3)-16 -> Q3*/ +#else + tmp = extract_h(L_shl(norm_gain_code,3)); /*(16+3)-16 -> Q3*/ +#endif + IF( EQ_16(L_frame,L_FRAME)) + { + IF(i_subfr == 0) + { + *lp_gainp = mult(3277,gain_pit); + move16(); /*0.1 in Q15 = 3277 , (15+14)-15 -> Q14*/ + *lp_gainc = mult_r(3277,tmp); + move16(); /* (15+3)-15 -> Q3*/ + } + ELSE IF( EQ_16(i_subfr,L_SUBFR)) + { + *lp_gainp = add(*lp_gainp, mult(6554, gain_pit)); + move16(); /*Q14 (0.2 in Q15 = 6554)*/ + *lp_gainc = mac_r(L_deposit_h(*lp_gainc), 6554, tmp); + move16(); /*Q3*/ + } + ELSE IF( EQ_16(i_subfr,2*L_SUBFR)) + { + *lp_gainp = add( *lp_gainp, mult(9830, gain_pit)); + move16(); /*Q14 (0.3 in Q15 = 9830)*/ + *lp_gainc = mac_r(L_deposit_h(*lp_gainc), 9830, tmp); + move16(); /*Q3*/ + } + ELSE /* i_subfr == 3*L_SUBFR */ + { + *lp_gainp = add( *lp_gainp, mult(13107, gain_pit)); + move16(); /*Q14 (0.4 in Q15 = 13107)*/ +#ifdef BASOP_NOGLOB + *lp_gainc = mac_r_sat(L_deposit_h(*lp_gainc), 13107, tmp); +#else + *lp_gainc = mac_r(L_deposit_h(*lp_gainc), 13107, tmp); +#endif + move16(); /*Q3*/ + } + } + ELSE + { + IF( i_subfr == 0 ) + { + *lp_gainp = mult(2185,gain_pit); + move16(); /*(1.0/15.0) in Q15 = 2185 , (15+14)-15 -> Q14*/ + *lp_gainc = mult_r(2185,tmp); + move16(); /* (15+3)-15 -> Q3*/ + } + ELSE IF( EQ_16(i_subfr,L_SUBFR )) + { + *lp_gainp = add(*lp_gainp, mult(4369, gain_pit)); + move16(); /*Q14 (2.0/15.0 in Q15 = 4369)*/ + *lp_gainc = mac_r(L_deposit_h(*lp_gainc), 4369, tmp); + move16(); /*Q3*/ + } + ELSE IF( EQ_16(i_subfr,2*L_SUBFR)) + { + *lp_gainp = add(*lp_gainp, mult(6554, gain_pit)); + move16(); /*Q14 (3.0/15.0 in Q15 = 6554)*/ + *lp_gainc = mac_r(L_deposit_h(*lp_gainc), 6554, tmp); + move16(); /*Q3*/ + } + ELSE IF( EQ_16(i_subfr,3*L_SUBFR)) + { + *lp_gainp = add(*lp_gainp, mult(8738, gain_pit)); + move16(); /*Q14 (4.0/15.0 in Q15 = 8738)*/ + *lp_gainc = mac_r(L_deposit_h(*lp_gainc), 8738, tmp); + move16(); /*Q3*/ + } + ELSE /* i_subfr == 4*L_SUBFR */ + { + *lp_gainp = add(*lp_gainp, mult(10923, gain_pit)); + move16(); /*Q14 (5.0/15.0 in Q15 = 10923)*/ +#ifdef BASOP_NOGLOB + *lp_gainc = mac_r_sat(L_deposit_h(*lp_gainc), 10923, tmp); +#else + *lp_gainc = mac_r(L_deposit_h(*lp_gainc), 10923, tmp); +#endif + move16(); /*Q3*/ + } + } + return; + +} + +/*-------------------------------------------------* + * Gain_dec_gaus_vbr + * + * Decode gains of purely unvoiced sounds + *-------------------------------------------------*/ +Word32 gain_dec_gaus_fx( /* o : quantized codebook gain Q16 */ + Word16 index, /* i : quantization index */ + const Word16 bits, /* i : number of bits to quantize */ + const Word16 lowBound, /* i : lower bound of quantizer (dB) */ + const Word16 topBound, /* i : upper bound of quantizer (dB) */ + const Word16 inv_gain_inov, /* o : unscaled innovation gain Q12 */ + Word32 *L_norm_gain_code /* o : gain of normalized gaussian excitation Q16 */ +) +{ + Word16 stepSize, gain, expg, frac, expi, tmp_igi; + Word32 L_tmp, L_enr_q, L_gain; + + /*------------------------------------------------------------------------------------------* + * Quantize linearly the log E + *------------------------------------------------------------------------------------------*/ + + stepSize = shl(sub(topBound,lowBound),sub(14, bits)); /* Q14 */ + + /*------------------------------------------------------------------------------------------* + * Gaussian codebook gain + *------------------------------------------------------------------------------------------*/ + + /* enr_q = (float)index*stepSize ,lowBound); */ + L_enr_q = L_mult(index, stepSize); /* Q0 * Q14 -> Q15 */ + L_enr_q = L_shl(L_enr_q, 9); /* Q15 -> Q24 */ + L_enr_q = L_add(L_enr_q, L_shl(L_deposit_h(lowBound),8)); /* Q24 */ + + /*------------------------------------------------------------* + * gain = pow(10.0, enr/20) + * = pow(2, 3.321928*enr/20) + * = pow(2, 0.166096*enr) + *------------------------------------------------------------*/ + + /* gain = (float)pow( 10.0f, enr/20.0f ); quantized codebook gain */ + L_tmp = Mult_32_16(L_enr_q, 21771); /* *0.166096 in Q17 -> Q26 */ + L_tmp = L_shr(L_tmp, 10); /* From Q26 to Q16 */ + frac = L_Extract_lc(L_tmp, &expg); /* Extract exponent of enr */ + L_gain = Pow2(30, frac); /* Put 30 as exponent so that the */ + expg = add(expg, 16-30); /* output of Pow2() will be */ + /* Normalized, set result in Q16 */ + gain = round_fx(L_gain); +#ifdef BASOP_NOGLOB + L_gain = L_shl_sat(L_gain, expg); /* In Q16*/ +#else + L_gain = L_shl(L_gain, expg); /* In Q16*/ +#endif + /* *norm_gain_code = gain / *inv_gain_inov;*/ + expi = norm_s(inv_gain_inov); + tmp_igi = shl(inv_gain_inov, expi); + L_tmp = div_s(shr(gain,1), tmp_igi); +#ifdef BASOP_NOGLOB + L_tmp = L_shl_sat(L_tmp, add(1,expi)); + *L_norm_gain_code = L_shl_sat(L_tmp, add(expg,13)); /* Q16 */ move32(); +#else + L_tmp = L_shl(L_tmp, add(1,expi)); + *L_norm_gain_code = L_shl(L_tmp, add(expg,13)); /* Q16 */ move32(); +#endif + + return L_gain; +} + +/*--------------------------------------------------------------------------* +* gain_dec_SQ() +* +* Decoding of pitch and codebook gains using scalar quantizers +*-------------------------------------------------------------------------*/ + +void gain_dec_SQ_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + const Word16 i_subfr, /* i : subframe number */ + const Word16 *code, /* i : algebraic code excitation Q9*/ + const Word16 Es_pred, /* i : predicted scaled innov. energy Q8 */ + Word16 *gain_pit, /* o : Quantized pitch gain Q14*/ + Word32 *gain_code, /* o : Quantized codeebook gain Q16*/ + Word16 *gain_inov, /* o : unscaled innovation gain Q12*/ + Word32 *norm_gain_code /* o : norm. gain of the codebook excitation Q16*/ +) +{ + Word16 index, nBits; + Word16 gcode0, Ei; + Word16 tmp16, expg, expg2, e_tmp, f_tmp, exp_gcode0, frac; + Word32 L_tmp, L_tmp1; + + /*-----------------------------------------------------------------* + * get number of bits + *-----------------------------------------------------------------*/ + + nBits = st_fx->acelp_cfg.gains_mode[shr(i_subfr, 6)]; + move16(); + + /*-----------------------------------------------------------------* + * decode pitch gain + *-----------------------------------------------------------------*/ + + index = (Word16)get_next_indice(st_fx, shr(nBits,1) ); + + /*Ei = (G_PITCH_MAX - G_PITCH_MIN) / ((1 << (nBits>>1)) - 1); set quantization step */ + tmp16 = div_s(1,sub(shl(1,shr(nBits,1)),1)); /* Q15*/ + Ei = mult_r(G_PITCH_MAX_MINUS_MIN_Q13,tmp16); /* Q13*/ + + /**gain_pit = usdequant( index, G_PITCH_MIN, Ei );*/ + *gain_pit = usdequant_fx( index, G_PITCH_MIN_Q14, Ei ); + move16(); /*Q14 */ + + /*-----------------------------------------------------------------* + * calculate the predicted gain code + *-----------------------------------------------------------------*/ + + /*Ecode = (dotp( code, code, L_SUBFR) + 0.01f) / L_SUBFR;*/ + /**gain_inov = 1.0f / (float)sqrt( Ecode );*/ + + L_tmp = Dot_product12(code, code, L_SUBFR, &expg); + expg = sub(expg, 18 + 6); /* exp: -18 (code in Q9), -6 (/L_SUBFR) */ + expg2 = expg; + move16(); + L_tmp1 = L_tmp; /* sets to 'L_tmp' in 1 clock */ + move32(); + L_tmp = Isqrt_lc(L_tmp, &expg); + + *gain_inov = extract_h(L_shl(L_tmp, sub(expg, 3))); /* gain_inov in Q12 */ + + /*Ei = 10 * (float)log10( Ecode );*/ + e_tmp = norm_l(L_tmp1); + f_tmp = Log2_norm_lc(L_shl(L_tmp1, e_tmp)); + e_tmp = sub(expg2,add(1,e_tmp)); + L_tmp1 = Mpy_32_16(e_tmp, f_tmp, 12330); /* Q13 */ /* 10*log10(2) in Q12*/ + Ei = round_fx(L_shl(L_tmp1, 11)); /* Q8 */ + + /*gcode0 = (float) pow(10, 0.05 * (Es_pred - Ei));*/ + gcode0 = sub(Es_pred, Ei); /* Q8 */ + + /* gcode0 = pow(10.0, gcode0/20) = pow(2, 3.321928*gcode0/20) = pow(2, 0.166096*gcode0) */ + L_tmp = L_mult(gcode0, 21771); /* *0.166096 in Q17 -> Q26 */ + L_tmp = L_shr(L_tmp, 10); /* From Q26 to Q16 */ + frac = L_Extract_lc(L_tmp, &exp_gcode0); /* Extract exponent of gcode0 */ + + gcode0 = extract_l(Pow2(14, frac));/* Put 14 as exponent so that output of Pow2() will be: 16384 < Pow2() <= 32767 */ + exp_gcode0 = sub(exp_gcode0, 14); + + /*-----------------------------------------------------------------* + * decode normalized codebook gain + *-----------------------------------------------------------------*/ + + index = (Word16)get_next_indice(st_fx, shr(add(nBits,1),1) ); + + tmp16 = gain_dequant_fx( index, G_CODE_MIN_TC_Q15, G_CODE_MAX_TC_Q0, shr(add(nBits,1),1), &expg ); + + /**gain_code *= gcode0;*/ + L_tmp = L_mult(tmp16,gcode0); /* Q0*Q0 -> Q1*/ + /**gain_code = L_shl(L_tmp,add(expg,15)); Q16*/ + *gain_code = L_shl(L_tmp,add(add(expg,exp_gcode0),15)); + move32(); /*Q16*/ + + /**norm_gain_code = *gain_code / *gain_inov;*/ + expg = sub(norm_s(*gain_inov),1); + expg = s_max(expg, 0); + + tmp16 = div_s(shr(8192,expg),*gain_inov); + *norm_gain_code = L_shr(Mult_32_16(*gain_code,tmp16),sub(1,expg)); + move32(); + + return; +} + +/*---------------------------------------------------------------------* + * gain_dec_amr_wb() + * + * Decoding of pitch and fixed codebook gains (used also in AMR-WB IO mode) + *---------------------------------------------------------------------*/ + +void gain_dec_amr_wb_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + const Word32 core_brate, /* i : core bitrate */ + Word16 *gain_pit, /* o : Quantized pitch gain */ + Word32 *gain_code, /* o : Quantized codeebook gain */ + Word16 *past_qua_en, /* i/o: gain quantization memory (4 words) */ + Word16 *gain_inov, /* o : unscaled innovation gain */ + const Word16 *code, /* i : algebraic code excitation */ + Word32 *norm_gain_code /* o : norm. gain of the codebook excitation */ +) +{ + Word16 i, index, index2; + Word16 nbits; + Word16 gcode0, qua_en; + const Word16 *t_qua_gain; + Word16 tmp; + Word32 L_tmp; + Word16 expg, exp_gcode0, fracg; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + + + /**gain_inov = 1.0f/ (float)sqrt( ( dotp( code, code, L_SUBFR ) + 0.01f ) / L_SUBFR );*/ + + L_tmp = Dot_product12(code, code, L_SUBFR, &expg); + expg = sub(expg, 18 + 6); /* exp: -18 (code in Q9), -6 (/L_SUBFR) */ + L_tmp = Isqrt_lc(L_tmp, &expg); + + *gain_inov = extract_h(L_shl(L_tmp, sub(expg, 3))); /* gain_inov in Q12 */ + + /*-----------------------------------------------------------------* + * Select the gain quantization table + *-----------------------------------------------------------------*/ + nbits = 7; + move16(); + t_qua_gain = t_qua_gain7b_fx; + + IF( LT_32(core_brate,ACELP_12k65)) + { + nbits = 6; + move16(); + t_qua_gain = t_qua_gain6b_fx; + } + + /*-----------------------------------------------------------------* + * predicted code gain + *-----------------------------------------------------------------*/ + + /* start with predicting code energy in dB */ + /**for (i=0; i Q25 */ + } + + /* predicted codebook gain */ + gcode0 = extract_h(L_tmp); /* From Q25 to Q9 */ + + /*-----------------------------------------------------------------* + * gcode0 = pow(10.0, gcode0/20) + * = pow(2, 3.321928*gcode0/20) + * = pow(2, 0.166096*gcode0) + *-----------------------------------------------------------------*/ + L_tmp = L_mult(gcode0, 21771); /* *0.166096 in Q17 -> Q27 */ + L_tmp = L_shr(L_tmp, 9+2); /* From Q27 to Q16 */ + L_Extract(L_tmp, &exp_gcode0, &fracg); /* Extract exponent of gcode0 */ + + gcode0 = extract_l(Pow2(14, fracg));/* Put 14 as exponent so that */ + /* output of Pow2() will be: */ + /* 16384 < Pow2() <= 32767 */ + exp_gcode0 = sub(exp_gcode0, 14); + + /*-----------------------------------------------------------------* + * Decode pitch gain + *-----------------------------------------------------------------*/ + + index = (Word16)get_next_indice( st_fx, nbits ); + index2 = shl(index,1); + *gain_pit = t_qua_gain[index2]; + move16(); + + /*-----------------------------------------------------------------* + * Decode code gain + *-----------------------------------------------------------------*/ + qua_en = t_qua_gain[add(index2,1)]; + move16(); + + /* *gain_code = t_qua_gain[indice*2+1] * gcode0; */ + L_tmp = L_mult(qua_en, gcode0); /* Q11*Q0 -> Q12 */ + tmp = round_fx(L_tmp); + move16(); /* Q-4 */ + *gain_code = L_shl(L_tmp, add(exp_gcode0, 4)); + move32(); /* Q12 -> Q16 */ + + /* adjust gain according to energy of code */ + L_tmp = Mult_32_16(*gain_code, *gain_inov); +#ifdef BASOP_NOGLOB + *gain_code = L_shl_o(L_tmp, 3, &Overflow); +#else + *gain_code = L_shl(L_tmp, 3); +#endif + move32(); /* gcode_inov in Q12*/ + + /*-----------------------------------------------------------------* + * update table of past quantized energies + *-----------------------------------------------------------------*/ + + FOR (i=GAIN_PRED_ORDER-1; i>0; i--) + { + past_qua_en[i] = past_qua_en[i-1]; + move16(); + } + /*past_qua_en[0] = (float)(20.0*log10(qua_en));*/ + /*----------------------------------------------------------* + * past_qua_en[0] = 20*log10(t_qua_gain[indice*2+1]) + * = 6.0206*log2(t_qua_gain[indice*2+1]) + * = 6.0206*(log2(t_qua_gain[indice*2+1]Q11 -11) + *----------------------------------------------------------*/ + tmp = norm_l(qua_en); + fracg = Log2_norm_lc(L_shl(qua_en, tmp)); + expg = sub(30,tmp); + expg = sub(expg, 11); + L_tmp = Mpy_32_16(expg, fracg, 24660); /* x 6.0206 in Q12 */ + qua_en = extract_h(L_shl(L_tmp, 13)); /* result in Q10 */ + + past_qua_en[0] = qua_en; + move16(); /* in Q10 */ + + /*-----------------------------------------------------------------* + * Normalized code gain + *-----------------------------------------------------------------*/ + /**norm_gain_code = *gain_code / *gain_inov;*/ + expg = sub(norm_s(*gain_inov),1); + expg = s_max(expg, 0); + + tmp = div_s(shr(8192,expg),*gain_inov); + *norm_gain_code = L_shr(Mult_32_16(*gain_code,tmp),sub(1,expg)); + move32(); + + return; +} diff --git a/lib_dec/gaus_dec.c b/lib_dec/gaus_dec.c index daa6148afaafbca53b0022066b1bc005ef699957..77d40a14fd7e563825cda2be76d8df0d6e9b43c8 100644 --- a/lib_dec/gaus_dec.c +++ b/lib_dec/gaus_dec.c @@ -233,14 +233,14 @@ static void dec_2pos( /*-----------------------------------------------------* - * gaus_L2_dec : + * gaus_L2_dec_flt : * * decoder of Gaussian Codebook for unvoiced as Layer 2 * * One Gaussian vector *-----------------------------------------------------*/ -void gaus_L2_dec( +void gaus_L2_dec_flt( float *code, /* o : decoded gaussian codevector */ float tilt_code, const float *Aq, diff --git a/lib_dec/gaus_dec_fx.c b/lib_dec/gaus_dec_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..0f304704207300ee1e620c146ce17e0ccc5eebc2 --- /dev/null +++ b/lib_dec/gaus_dec_fx.c @@ -0,0 +1,287 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include +#include "options.h" /* Compilation switches */ +#include "cnst.h" /* Common constants */ +#include "rom_com.h" /* Static table prototypes */ +#include "prot_fx1.h" /* Function prototypes */ +#include "prot_fx2.h" /* Function prototypes */ + +/*---------------------------------------------------------------------* + * Local function prototypes + *---------------------------------------------------------------------*/ + +void gaus_dec2v_fx( Decoder_State *st_fx, Word16 *code, const Word16 lg, const Word16 nb_bits); +static void dec_2pos_fx(Word16 index, Word16 *ind1, Word16 *ind2, Word16 *sign1, Word16 *sign2, Word16 log2_n); + +/*---------------------------------------------------------------------* + * gaus_dec() + * + * no adaptive excitation constructed + * - decode the codebook indices, + * - find the excitation + *---------------------------------------------------------------------*/ +void gaus_dec_fx( + Decoder_State *st_fx, /* i/o: decoder static memory */ + const Word16 i_subfr, /* i : subframe index */ + Word16 *code, /* o : unvoiced excitation Q12 */ + Word32 *L_norm_gain_code, /* o : gain of normalized gaussian excitation Q16 */ + Word16 *lp_gainp, /* i/o : lp filtered pitch gain(FER) Q14 */ + Word16 *lp_gainc, /* i/o : lp filtered code gain (FER) Q3 */ + Word16 *inv_gain_inov, /* o : unscaled innovation gain Q12 */ + Word16 *tilt_code, /* o : synthesis excitation spectrum tilt Q15 */ + Word16 *voice_fac, /* o : estimated voicing factor Q15 */ + Word16 *gain_pit, /* o : pitch gain Q14 */ + Word16 *pt_pitch_1, /* o : floating pitch buffer Q6 */ + Word16 *exc, /* o : excitation signal frame */ + Word32 *L_gain_code, /* o : gain of the gaussian excitation Q16 */ + Word16 *exc2, /* o : Scaled excitation signal frame */ + Word16 *bwe_exc_fx, + Word16 *sQ_exc, /* i/o : Excitation scaling factor (Decoder state) */ + Word16 *sQsubfr /* i/o : Past excitation scaling factors (Decoder State) */ +) +{ + Word16 i, exp, gain_code; + Word16 idx, nb_bits; + Word32 L_tmp; + GSC_DEC_HANDLE hGSCDec; + hGSCDec = st_fx->hGSCDec; + MUSIC_POSTFILT_HANDLE hMusicPF; + hMusicPF = st_fx->hMusicPF; + + /*------------------------------------------------------------------------------------------* + * Unvoiced : Gaussian codebook + *------------------------------------------------------------------------------------------*/ + nb_bits = st_fx->acelp_cfg.fixed_cdk_index[shr(i_subfr,6)]; + move16(); + + gaus_dec2v_fx( st_fx, code, L_SUBFR, shr(nb_bits,1)); + + /*------------------------------------------------------------------------------------------* + * - Gain of Gaussian excitation and normalized Gaussian excitation + *------------------------------------------------------------------------------------------*/ + /* gain_inov = 1.0f / (float)sqrt((dot_product(code, code, L_SUBFR) + 0.01f) / L_SUBFR) */ + L_tmp = Dot_product12(code, code, L_SUBFR, &exp); + exp = sub(exp, 18/*24*/ + 6); /* exp: -18 (code in Q9), -6 (/L_SUBFR) */ + L_tmp = Isqrt_lc(L_tmp, &exp); + *inv_gain_inov = extract_h(L_shl(L_tmp, sub(exp, 3))); /* inv_gain_inov in Q12 */ + + nb_bits = st_fx->acelp_cfg.gains_mode[shr(i_subfr, 6)]; + move16(); + idx = (Word16)get_next_indice( st_fx, nb_bits ); + move16(); + + /* safety check in case of bit errors */ + IF( GT_16(idx,78) && EQ_16(st_fx->element_mode, EVS_MONO)) + { + idx = 78; + move16(); + st_fx->BER_detect = 1; + move16(); + } + + *L_gain_code = gain_dec_gaus_fx( idx, nb_bits,-30,190, *inv_gain_inov, L_norm_gain_code ); + + /* update LP filtered gains for the case of frame erasures */ + lp_gain_updt_fx( i_subfr, 0, *L_norm_gain_code, lp_gainp, lp_gainc, L_FRAME ); /* supposes that gain_dec_gaus() is used for ACELP@12k8 only */ + + /*------------------------------------------------------------------------------------------* + * Updates + *------------------------------------------------------------------------------------------*/ + + *tilt_code = 0; + move16(); + *voice_fac = -32768; /* only unvoiced */ move16(); + *gain_pit = 0; /* needed for BASS postfitler */ move16(); + *pt_pitch_1 = 4096; /* floating pitch buffer Q6 */ move16(); + + /*------------------------------------------------------------------------------------------* + * Construct scaled excitation + *------------------------------------------------------------------------------------------*/ + + set16_fx(&exc[i_subfr],0, L_SUBFR); + set16_fx(&exc2[i_subfr],0, L_SUBFR); + + IF( EQ_16(st_fx->L_frame,L_FRAME)) + { + Rescale_exc(hMusicPF->dct_post_old_exc_fx, &exc[i_subfr], &bwe_exc_fx[i_subfr * HIBND_ACB_L_FAC], hGSCDec->last_exc_dct_in_fx, + L_SUBFR, L_SUBFR* HIBND_ACB_L_FAC, *L_gain_code, sQ_exc, sQsubfr, exc2, i_subfr, UNVOICED ); + } + ELSE + { + Rescale_exc(hMusicPF->dct_post_old_exc_fx, &exc[i_subfr], &bwe_exc_fx[i_subfr * 2], hGSCDec->last_exc_dct_in_fx, + L_SUBFR, L_SUBFR* 2, *L_gain_code, sQ_exc, sQsubfr, exc2, i_subfr, UNVOICED ); + } + + gain_code = round_fx(L_shl(*L_gain_code, *sQ_exc)); + FOR (i = 0; i < L_SUBFR; i++) + { + L_tmp = L_shl(L_mult(gain_code, code[i]), 6/*3*/); + exc[i+i_subfr] = round_fx(L_tmp); + } + + return; +} + + + +/*-----------------------------------------------------* + * gaus_dec2v() + * + * decoder of Gaussian Codebook for unvoiced + * consisting of addition of 2 Gaussian vectors + * + * One Gaussian vector of 190 values + *-----------------------------------------------------*/ + +void gaus_dec2v_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + Word16 *code, /* o : decoded gaussian vector Q12-exp */ + const Word16 lg, /* i : codevector length Q0 */ + const Word16 nb_bits /* i : nb ob bits per track (max 6) */ +) +{ + Word16 i, ind1, ind2,idx; + Word16 step; + Word16 sign1, sign2; + Word16 delta, delta2, inv_delta; + Word16 gaus_dico2_fx[190]; + Word16 tmp16; + const Word16 *pt1, *pt2; + Word16 index_delta; + + step = shr(0x80, nb_bits); + + idx = (Word16)get_next_indice( st_fx, add(shl(nb_bits,1),1) ); + index_delta = (Word16)get_next_indice( st_fx, 3 ); + + dec_2pos_fx( idx, &ind1, &ind2, &sign1, &sign2, nb_bits ); + + delta = shl(index_delta, STEP_DELTA_FX); + delta2 = mac_r(16384*65536, shr(delta,1), delta); + inv_delta = div_s(16384, delta2); + + IF (delta > 0) + { + gaus_dico2_fx[0] = gaus_dico_fx[0]; + move16(); /*Q12 */ + FOR (i=1; i<190; i++) + { + /* gaus_dico2[i] = (gaus_dico_fx[i] - delta*gaus_dico_fx[i-1])/(1+delta*delta) */ + tmp16 = msu_r(L_deposit_h(gaus_dico_fx[i]), delta, gaus_dico_fx[i-1]); + gaus_dico2_fx[i] = mult_r(tmp16, inv_delta); + } + } + ELSE + { + FOR (i=0; i<190; i++) + { + gaus_dico2_fx[i] = gaus_dico_fx[i]; + move16(); /*Q12 */ + } + } + + pt1 = &gaus_dico2_fx[i_mult2(ind1, step)]; + move16(); + pt2 = &gaus_dico2_fx[i_mult2(ind2, step)]; + move16(); + + FOR (i = 0; i < lg; i++) + { + /* code is Q9, Gaussian codebook is Q12 */ + /* code[i] = pt1[i] * sign1 + pt2[i] * sign2 */ + code[i] = add(mult(pt1[i], sign1), mult(pt2[i], sign2)); + } + + return; +} + + +/*-----------------------------------------------------* + * dec_2pos() + * + * Decode the codevectors positions and signs + *-----------------------------------------------------*/ +static void dec_2pos_fx( + Word16 index, /* i : quantization index Q0 */ + Word16 *ind1, /* o : 1st vector index Q0 */ + Word16 *ind2, /* o : 2nd vector index Q0 */ + Word16 *sign1, /* o : 1st vector sign Q0 */ + Word16 *sign2, /* o : 2nd vector sign Q0 */ + Word16 log2_n /* i : Log2(number of vector) Q0 */ +) +{ + Word16 i; + + i = s_and(index, 1); + *sign1 = (-32768); /* -1 (Q15) */ move16(); + if (i == 0) + { + *sign1 = MAX_16; /* 1 (Q15) */ move16(); + } + *sign1 = shr(*sign1,3); + move16(); /* To have code dec in Q9 instead of Q12 */ + + index = shr(index, 1); + + *ind1 = shr(index, log2_n); + move16(); + *ind2 = sub(index, shl(*ind1, log2_n)); + move16(); + *sign2 = *sign1; + move16(); + if (GT_16(*ind1, *ind2)) + { + *sign2 = negate(*sign1); + move16(); + } + return; +} + + + +/*-----------------------------------------------------* + * gaus_L2_dec : + * + * decoder of Gaussian Codebook for unvoiced as Layer 2 + * + * One Gaussian vector + *-----------------------------------------------------*/ +void gaus_L2_dec( + Word16 *code, /* o : decoded gaussian codevector Q9 */ + Word16 tilt_code, /* i : tilt of code Q15 */ + const Word16 *A, /* i : quantized LPCs Q12 */ + Word16 formant_enh, /* i : formant enhancement factor Q15 */ + Word16 *seed_acelp /*i/o : random seed Q0 */ +) +{ + Word16 i, seed; + Word32 tmp32; + + /*Generate white gaussian noise using central limit theorem method (N only 4 as E_util_random is not purely uniform)*/ + seed = *seed_acelp; + move16(); + FOR (i = 0; i < L_SUBFR; i++) + { + seed = own_random2_fx(seed); + tmp32 = L_mac(0, seed, 1<<9); + + seed = own_random2_fx(seed); + tmp32 = L_mac(tmp32, seed, 1<<9); + + seed = own_random2_fx(seed); + code[i] = mac_r(tmp32, seed, 1<<9); + move16(); + } + *seed_acelp = seed; + move16(); + + /*Shape the gaussian excitation*/ + cb_shape_fx( 1, 0, 0, 1, 0, formant_enh, FORMANT_SHARPENING_G2, A, code, tilt_code, 0, 1 , L_SUBFR); + + + return; +} + diff --git a/lib_dec/gs_dec.c b/lib_dec/gs_dec.c index ba9c574afdb3e1601033678cb6165a2226a4cc0f..7fda687a347a55e4c3bb20a63e6c786ccd3d82ef 100644 --- a/lib_dec/gs_dec.c +++ b/lib_dec/gs_dec.c @@ -108,7 +108,7 @@ void decod_audio( } /* set bit-allocation */ - config_acelp1( DEC, st->total_brate, st->core_brate, st->core, st->extl_orig, st->extl_brate_orig, st->L_frame, st->GSC_noisy_speech, &( st->acelp_cfg ), st->next_bit_pos, st->coder_type, -1, 1, &nb_bits, NULL, st->element_mode, &nbits /*dummy*/, tdm_lp_reuse_flag, tdm_low_rate_mode, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); + config_acelp1_IVAS( DEC, st->total_brate, st->core_brate, st->core, st->extl_orig, st->extl_brate_orig, st->L_frame, st->GSC_noisy_speech, &( st->acelp_cfg ), st->next_bit_pos, st->coder_type, -1, 1, &nb_bits, NULL, st->element_mode, &nbits /*dummy*/, tdm_lp_reuse_flag, tdm_low_rate_mode, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); /*---------------------------------------------------------------* * Decode energy dynamics @@ -700,12 +700,12 @@ void gsc_dec( } /*-------------------------------------------------------------------* - * GSC_dec_init() + * GSC_dec_init_ivas() * * Initialize GSC decoder state structure *-------------------------------------------------------------------*/ -void GSC_dec_init( +void GSC_dec_init_ivas( GSC_DEC_HANDLE hGSCDec /* i/o: GSC data handle */ ) { diff --git a/lib_dec/gs_dec_amr_wb_fx.c b/lib_dec/gs_dec_amr_wb_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..69f37c2d3c132d721c168199c44739d8794b8f87 --- /dev/null +++ b/lib_dec/gs_dec_amr_wb_fx.c @@ -0,0 +1,522 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include +#include "options.h" /* Compilation switches */ +#include "cnst.h" /* Common constants */ +#include "rom_com.h" /* Static table prototypes */ +#include "prot_fx1.h" /* Function prototypes */ +#include "prot_fx2.h" /* Function prototypes */ + + +/*-------------------------------------------------------------------* + * Local constants + *-------------------------------------------------------------------*/ + +#define ALP_FX 22938 /* 0.70f */ +#define MALP_FX (Word16)(32768L-ALP_FX) +#define ALPMY_FX 28180 /* 0.86f */ + +#define BAND3k 15 +#define BIN_1k2 48 +#define BAND_2k 12 +#define BAND_0k4 4 + +#define NORMALIZE_SPECS_Q_OUT 6 +#define ENER_FX_Q_GUARD 1 + +#ifdef ADD_IVAS_GS_DEC_IMPR +#define CONTR_LIMIT 3012 to be verified for fixed point /* Threshold to allow an increase in the contribution length */ +#endif + /*-------------------------------------------------------------------* + * Local functions + *-------------------------------------------------------------------*/ +static void NoiseFill_fx(Word16* exc_diffQ_fx, Word16* seed_tcx, const Word16 Mbands_gn, const Word16 Q_out); +static void Ener_per_band_fx(const Word16 exc_diff_fx[], const Word16 exc_diff_exp, Word32 y_gain4_fx[]); +static void Apply_gain_fx(Word16 exc_diffQ_fx[], Word32 L_Ener_per_bd_iQ[], Word32 L_Ener_per_bd_yQ[], const Word16 Q_out); +static void normalize_spec_fx(Word16 fac_up_fx, Word16 fy_norm_fx[], const Word16 L_frame, const Word16 Q_out); +static void gs_dec_amr_wb_fx(const long core_brate, Word16* seed_tcx, const Word16 dct_in_fx[], const Word16 Q_dct_in, + Word16 dct_out_fx[], Word16 Q_dct_out, const Word16 pitch_fx[], const Word16 voice_fac, const Word16 clas, const Word16 coder_type +#ifdef ADD_IVAS_GS_DEC_IMPR + , const Word16 VeryLowRateSTflag +#endif + ); + +/*-------------------------------------------------------------------* + * NoiseFill_fx() + * + * noise fill function for unvoiced/inactive frames (used only in AMR-WB IO mode) + *-------------------------------------------------------------------*/ + +static void NoiseFill_fx( + Word16 *exc_diffQ_fx, /* i/o: Noise per band */ + Word16 *seed_tcx, /* i : Seed for noise */ + const Word16 Mbands_gn, /* i : number of bands */ + const Word16 Q_out /* i : Q of exc_diffQ_fx[] */ +) +{ + Word16 i_band, CurBin, EndBin; + Word32 L_temp; + Word16 fact; + CurBin = 0; + move16(); + fact = shr(24576/*0.75f*/, sub(15, Q_out)); + + FOR( i_band = 0; i_band < Mbands_gn; i_band++ ) + { + EndBin = add(CurBin, crit_bins[i_band]); + FOR( ; CurBin Q9 */ + L_temp = L_mult(exc_diffQ_fx[i],s_max(temp2,512)); /*Q(Qexc_diffQ+10) */ + exc_diffQ_fx[i] = round_fx(L_shl(L_temp,16-10));/*Qexc_diffQ */ + } + + /*--------------------------------------------------------------------------------------* + * Match the energy of the modified excitation vector to the decoded excitation + *--------------------------------------------------------------------------------------*/ + Apply_gain_fx( exc_diffQ_fx, Ener_per_bd_iQ_fx, Ener_per_bd_yQ_fx,sub(NORMALIZE_SPECS_Q_OUT, Q_dct_out) ); + /*--------------------------------------------------------------------------------------* + * Copy to the output vector + *--------------------------------------------------------------------------------------*/ + + Copy(exc_diffQ_fx, dct_out_fx, L_FRAME); + + return; +} + +/*-------------------------------------------------------------------* + * improv_amr_wb_gs_fx() + * + * Modify the decoded excitation to increase quality of + * unvoiced and audio signals (used only in AMR-WB IO mode) + *-------------------------------------------------------------------*/ +void improv_amr_wb_gs_fx( + const Word16 clas, /* i : signal frame class */ + const Word16 coder_type, /* i : coder type */ + const Word32 core_brate, /* i : bitrate allocated to the core */ + Word16 *seed_tcx, /* i/o: Seed used for noise generation */ + Word16 *old_Aq_fx, /* i/o: old LPC filter coefficient */ + Word16 *mem_syn2_fx, /* i/o: synthesis memory */ + const Word16 lt_voice_fac_fx, /* i/o: long term voice factor Q14 */ + const Word16 locattack, /* i : Flag for a detected attack */ + Word16 *Aq_fx, /* i/o: Decoded LP filter coefficient */ + Word16 *exc2_fx, /* i/o: Decoded complete excitation */ + const Word16 Q_exc2, /* i : Exponent of Exc2 */ + Word16 *mem_tmp_fx, /* i/o: synthesis temporary memory */ + Word16 *syn_fx, /* o: Decoded synthesis to be updated */ + const Word16 Q_syn, /* i : Synthesis scaling Q0 */ + const Word16 *pitch_buf_fx, /* i : Decoded pitch buffer Q6 */ + const Word16 Last_ener_fx, /* i : Last energy (Q8) */ + const Word16 rate_switching_reset, /* i : rate switching reset flag */ + const Word16 last_coder_type_fx /* i : Last coder_type */ +#ifdef ADD_IVAS_GS_DEC_IMPR + ,const Word16 VeryLowRateSTflag /* i : Enable the noise enhancement for very low rate stereo generic mode */ +#endif +) +{ + Word16 i, exp_a, exp_b, exp_diff, j; + Word16 dct_exc_in_fx[L_FRAME], dct_exc_out_fx[L_FRAME]; + Word16 Aq_orig[NB_SUBFR*(M+1)], enr_LP_old, enr_LP_new; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + + /*------------------------------------------------------------* + * Condition to enter the section on excitation modification + *------------------------------------------------------------*/ + + /* Enter the modification for all inactive frames and also for unvoiced frames if bit rate is below 8k85 */ + + test(); + test(); + test(); + test(); + test(); + test(); +#ifdef ADD_IVAS_GS_DEC_IMPR + IF(VeryLowRateSTflag || + ((locattack == 0 && LE_32(core_brate, ACELP_12k65)) && + ((LT_32(core_brate, ACELP_8k85) && NE_16(clas, AUDIO_CLAS) && + (EQ_16(clas, UNVOICED_CLAS) || EQ_16(clas, VOICED_TRANSITION))) || EQ_16(coder_type, INACTIVE)))) +#else + IF( ( locattack == 0 && LE_32(core_brate, ACELP_12k65))&& + ( (LT_32(core_brate, ACELP_8k85) && NE_16(clas, AUDIO_CLAS) && + (EQ_16(clas, UNVOICED_CLAS) || EQ_16(clas, VOICED_TRANSITION) )) || EQ_16(coder_type, INACTIVE) ) ) +#endif + { + /*------------------------------------------------------------* + * two differents paths: + * unvoiced or inactive + * generic audio sound + * LP filter smoothing for inactive parts + *------------------------------------------------------------*/ + *seed_tcx = extract_l(L_mult0(pitch_buf_fx[0],pitch_buf_fx[3])); + /* last_coder_type_fx == UNVOICED should be understand as INACTIVE, but it is forced to UNVOICED in update_dec */ + test(); + test(); + test(); + IF( EQ_16(coder_type, INACTIVE)&>_16(Last_ener_fx,-3*256)&&EQ_16(last_coder_type_fx,UNVOICED)&&rate_switching_reset==0) /* 3.0 x 256 to Go to Q8 */ + { + + FOR(i =0; i < NB_SUBFR; i++) + { + Copy( Aq_fx, Aq_orig, NB_SUBFR*(M+1) ); + + exp_a = norm_s(Aq_fx[i*(M+1)]); + exp_b = norm_s(old_Aq_fx[i*(M+1)]); + exp_diff = sub(exp_a, exp_b); + IF(exp_diff>0) + { + Scale_sig(&old_Aq_fx[i*(M+1)], (M+1), negate(exp_diff)); + } + ELSE + { + Scale_sig(&Aq_fx[i*(M+1)], (M+1), exp_diff); + + } + FOR(j = i*(M+1); j < (i+1)*(M+1); j++) + { + + Aq_fx[j] = round_fx(L_mac(L_mult(ALP_FX, old_Aq_fx[j]), MALP_FX, Aq_fx[j])); + } + } + + /* check the smoothed LP filter stability */ + enr_LP_old = Enr_1_Az_fx( old_Aq_fx, L_SUBFR ); + Overflow = 0; + move16(); + + FOR( i=0; i < NB_SUBFR; i++ ) + { +#ifdef BASOP_NOGLOB + enr_LP_new = Enr_1_Az_fx_o( Aq_fx+i*(M+1), L_SUBFR, &Overflow ); +#else + enr_LP_new = Enr_1_Az_fx( Aq_fx+i*(M+1), L_SUBFR ); +#endif + IF( (shr(enr_LP_new,7) > enr_LP_old) || Overflow ) + { + /* filter is unstable, do not modify the excitation */ + Copy( Aq_orig, Aq_fx, NB_SUBFR*(M+1) ); + Overflow = 0; + move16(); + + return; + } + + enr_LP_old = enr_LP_new; + move16(); + } + } + + /*------------------------------------------------------------* + * Find frequency representation of the excitation + * Do the excitation modification according to the content + * Go back to time domain -> Overwrite exctiation + *------------------------------------------------------------*/ + edct_16fx(exc2_fx, dct_exc_in_fx, L_FRAME, 6, EVS_MONO); + gs_dec_amr_wb_fx( core_brate, seed_tcx, dct_exc_in_fx, Q_exc2, dct_exc_out_fx, Q_exc2, pitch_buf_fx, lt_voice_fac_fx, clas, coder_type +#ifdef ADD_IVAS_GS_DEC_IMPR + , VeryLowRateSTflag +#endif + ); + + edct_16fx(dct_exc_out_fx, exc2_fx, L_FRAME, 6, EVS_MONO); + /*------------------------------------------------------------* + * Redo core synthesis at 12k8 Hz with the modified excitation + *------------------------------------------------------------*/ + + Copy( mem_tmp_fx, mem_syn2_fx, M ); + syn_12k8_fx(L_FRAME, Aq_fx, exc2_fx, syn_fx, mem_syn2_fx, 1, Q_exc2, Q_syn ); + } + + return; +} diff --git a/lib_dec/gs_dec_fx.c b/lib_dec/gs_dec_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..d1413f69f1dc4575c7bec0b053fc58ab1182da3f --- /dev/null +++ b/lib_dec/gs_dec_fx.c @@ -0,0 +1,855 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include +#include "options.h" +#include "cnst.h" +#include "rom_com.h" +#include "prot_fx1.h" +#include "prot_fx2.h" +#include "ivas_cnst.h" + +/*=========================================================================*/ +/* FUNCTION : void decod_audio_fx(); */ +/*-------------------------------------------------------------------------*/ +/* PURPOSE : Decode audio (AC) frames */ +/*-------------------------------------------------------------------------*/ +/* INPUT ARGUMENTS : */ +/* _ (Word16[]) Aq : LP filter coefficient Q12 */ +/* _ (Word16) coder_type : coding type Q0 */ +/* _(Word16) Q_exc :Q format of excitation */ +/*-------------------------------------------------------------------------*/ +/* OUTPUT ARGUMENTS : */ +/* _ (Word16[]) pitch_buf_fx : floating pitch values for each subframe Q6*/ +/* _ (Word16[]) voice_factors_fx: frame error rate Q15 */ +/*--------------------------------------------------------------------------*/ +/* INPUT/OUTPUT ARGUMENTS : */ +/* Decoder_State *st_fx : decoder memory structure */ +/* _ (Word16[]) exc_fx : adapt. excitation exc (Q_exc) */ +/* _ (Word16[]) exc2_fx : adapt. excitation/total exc (Q_exc) */ +/*--------------------------------------------------------------------------*/ +/* RETURN ARGUMENTS : */ +/* _ None */ +/*==========================================================================*/ +void decod_audio_fx( + Decoder_State *st_fx, /* i/o: decoder static memory */ + Word16 dct_epit[], /* o : GSC excitation in DCT domain */ + const Word16 *Aq, /* i : LP filter coefficient */ + Word16 *pitch_buf, /* o : floating pitch values for each subframe */ + Word16 *voice_factors, /* o : voicing factors */ + Word16 *exc, /* i/o: adapt. excitation exc */ + Word16 *exc2, /* i/o: adapt. excitation/total exc */ + Word16 *bwe_exc, /* o : excitation for SWB TBE */ + Word16 *lsf_new /* i : ISFs at the end of the frame */ + , Word16 *gain_buf /*Q14*/ +) +{ + Word16 tmp_nb_bits_tot, pit_band_idx; + Word16 code[4*L_SUBFR]; + Word16 Diff_len, nb_subfr, i; + Word16 nb_frame_flg; + Word16 Es_pred = 0; + Word16 Len, max_len; + Word16 gsc_attack_flag; + + Word16 low_pit; + Word16 last_bin; + Word16 nbits; + + Word16 exc_wo_nf[L_FRAME16k]; + GSC_DEC_HANDLE hGSCDec; + hGSCDec = st_fx->hGSCDec; + + + /*---------------------------------------------------------------* + * Initialization + *---------------------------------------------------------------*/ + Diff_len = 0; + move16(); + + /* decode GSC attack flag (used to reduce possible pre-echo) */ + gsc_attack_flag = (Word16) get_next_indice( st_fx, 1 ); + + /* decode GSC SWB speech flag */ + test(); +#if !defined ADD_LRTD + IF( NE_16(st_fx->coder_type_fx,INACTIVE)&&GE_32(st_fx->total_brate,ACELP_13k20)) +#else + if (st_fx->GSC_IVAS_mode >= 1 || (st_fx->coder_type != INACTIVE && ((st_fx->element_mode == EVS_MONO && st_fx->total_brate >= ACELP_13k20) || + (st_fx->element_mode > EVS_MONO && st_fx->total_brate > MIN_BRATE_GSC_NOISY_FLAG && st_fx->bwidth >= SWB && !st_fx->flag_ACELP16k)))) +#endif + { + st_fx->GSC_noisy_speech_fx = (Word16) get_next_indice( st_fx, 1 ); + } + + /* safety check in case of bit errors */ + test(); + IF(st_fx->GSC_noisy_speech_fx && LT_16(st_fx->bwidth, SWB) && st_fx->GSC_IVAS_mode == 0) + { + st_fx->BER_detect = 1; + move16(); + st_fx->GSC_noisy_speech_fx = 0; + move16(); + } + /* set bit-allocation */ +#ifdef ADD_LRTD + config_acelp1(DEC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl_orig, st_fx->extl_brate_orig, st_fx->L_frame, st_fx->GSC_noisy_speech_fx, &(st_fx->acelp_cfg), st_fx->next_bit_pos, st_fx->coder_type_fx, -1, 1, &nbits, NULL, st_fx->element_mode, &nbits /*dummy*/, tdm_lp_reuse_flag, tdm_low_rate_mode, st_fx->idchan, st_fx->active_cnt, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode); +#else + config_acelp1(DEC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl_orig, st_fx->extl_brate_orig, st_fx->L_frame, st_fx->GSC_noisy_speech_fx, &(st_fx->acelp_cfg), st_fx->next_bit_pos, st_fx->coder_type_fx, -1, 1, &nbits, NULL, st_fx->element_mode, &nbits /*dummy*/, 0, 0, st_fx->idchan, st_fx->active_cnt, 0, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode); +#endif + /*---------------------------------------------------------------* + * Decode energy dynamics + *---------------------------------------------------------------*/ +#if defined ADD_LRTD + test(); test(); + IF (st_fx->GSC_IVAS_mode >= 1 || (EQ_16(st_fx->GSC_noisy_speech_fx, 1) && st_fx->GSC_IVAS_mode == 0)) +#else + IF( EQ_16(st_fx->GSC_noisy_speech_fx,1)) +#endif + { + nb_subfr = NB_SUBFR; + move16(); + hGSCDec->cor_strong_limit_fx = 0; + move16(); + hGSCDec->noise_lev_fx = NOISE_LEVEL_SP3; + move16(); +#ifdef ADD_LRTD + if (st_fx->GSC_IVAS_mode >= 1) + { + if (st_fx->core_brate < GSC_L_RATE_STG && st_fx->GSC_IVAS_mode < 3) + { + nb_subfr = 2; + } + hGSCDec->noise_lev = NOISE_LEVEL_SP2; + + if (st_fx->GSC_IVAS_mode == 3) /* Music like */ + { + hGSCDec->noise_lev = NOISE_LEVEL_SP0; + } + else if (st_fx->GSC_noisy_speech == 0) /* speech like but not noisy */ + { + hGSCDec->noise_lev = NOISE_LEVEL_SP3; + } + } +#endif + } + ELSE + { + IF( LE_32(st_fx->core_brate,ACELP_8k00)) + { + hGSCDec->noise_lev_fx = add((Word16)get_next_indice( st_fx, 2 ), NOISE_LEVEL_SP2); + } + ELSE + { + hGSCDec->noise_lev_fx = add((Word16)get_next_indice( st_fx, 3 ), NOISE_LEVEL_SP0); + } + + /*---------------------------------------------------------------* + * Decode number of subframes + *---------------------------------------------------------------*/ +#ifdef ADD_LRTD + if (st_fx->L_frame == L_FRAME16k && (st_fx->core_brate <= ACELP_13k20 || st_fx->coder_type == INACTIVE)) + { + hGSCDec->cor_strong_limit = 0; + nb_subfr = 1; + } + else +#endif + { + hGSCDec->cor_strong_limit_fx = 1; + move16(); + nb_subfr = SWNB_SUBFR; + move16(); + + IF(GE_32(st_fx->core_brate,ACELP_9k60)) + { + nbits = 1; + move16(); +#ifdef ADD_LRTD + if (st_fx->L_frame == L_FRAME16k && st_fx->core_brate >= MIN_RATE_4SBFR) + { + nbits = 2; + } +#endif + nb_frame_flg = (Word16)get_next_indice(st_fx, nbits); + + IF(s_and(nb_frame_flg,0x1) == 0) + { + nb_subfr = 2 * SWNB_SUBFR; + move16(); + hGSCDec->cor_strong_limit_fx = 0; + move16(); + } +#ifdef ADD_LRTD + else if (st_fx->L_frame == L_FRAME16k && st_fx->core_brate >= MIN_RATE_4SBFR) + { + nb_subfr = 2 * SWNB_SUBFR; /* cor_strong already set to 1 */ + } + + if ((nb_frame_flg >> 1) == 1) + { + nb_subfr *= 2; + } +#endif + } + } + } +#if 0 + if (st_fx->L_frame == L_FRAME16k && nb_subfr == NB_SUBFR) + { + nb_subfr = NB_SUBFR16k; + } +#endif + /*---------------------------------------------------------------* + * Decode the last band where the adaptive (pitch) contribution is significant + *---------------------------------------------------------------*/ + + IF( LT_32(st_fx->core_brate,CFREQ_BITRATE)) + { + nbits = 3; + move16(); + test(); + if( LT_32(st_fx->core_brate,ACELP_9k60)&&(EQ_16(st_fx->coder_type_fx,INACTIVE))) + { + nbits = 1; + move16(); + } + } + ELSE + { + nbits = 4; + move16(); + } + test(); + IF( LT_32(st_fx->core_brate,ACELP_9k60)&&NE_16(st_fx->coder_type_fx,INACTIVE)) + { + pit_band_idx = 1; + move16(); + } + ELSE + { + pit_band_idx = (Word16)get_next_indice( st_fx, nbits ); + } + + IF( pit_band_idx != 0 ) + { + IF( LT_32(st_fx->core_brate,ACELP_9k60)) + { + pit_band_idx = 7+BAND1k2; + move16(); /* At low rate, if pitch model is chosen, then for to be use on extented and constant frequency range */ + } + ELSE + { + pit_band_idx = add(pit_band_idx, BAND1k2); + } + + /* detect bit errors in the bitstream */ + IF( GT_16(pit_band_idx,13)) /* The maximum decodable index is 10 + BAND1k2 (3) = 13 */ + { + pit_band_idx = 13; + move16(); + st_fx->BER_detect = 1; + move16(); + } + Diff_len = mfreq_loc_div_25[pit_band_idx]; + move16(); + } + hGSCDec->Last_GSC_pit_band_idx_fx = pit_band_idx; + move16(); + + + /*--------------------------------------------------------------------------------------* + * Decode adaptive (pitch) excitation contribution + * Reset unvaluable part of the adaptive (pitch) excitation contribution + *--------------------------------------------------------------------------------------*/ + IF( GT_16(pit_band_idx,BAND1k2)) + { + /*---------------------------------------------------------------* + * Decode adaptive (pitch) excitation contribution + *---------------------------------------------------------------*/ + test(); +#ifdef ADD_LRTD + if (!(st_fx->GSC_IVAS_mode > 0 && st_fx->L_frame / nb_subfr == 2 * L_SUBFR && st_fx->GSC_IVAS_mode < 3) && + ((st_fx->core_brate >= MIN_RATE_FCB || st_fx->GSC_noisy_speech) && + ((nb_subfr == NB_SUBFR && st_fx->L_frame == L_FRAME) || (nb_subfr == NB_SUBFR16k && st_fx->L_frame == L_FRAME16k)))) +#else + IF( EQ_16(st_fx->GSC_noisy_speech_fx,1)&&EQ_16(nb_subfr,NB_SUBFR)) +#endif + { + Word16 indice; + nbits = Es_pred_bits_tbl[BIT_ALLOC_IDX_fx(st_fx->core_brate, GENERIC, -1, -1)]; + move16(); + IF (GT_16(st_fx->element_mode, EVS_MONO)) + { + nbits = 5; + move16(); + } + + indice = get_next_indice(st_fx, nbits); + + Es_pred_dec_fx( &Es_pred, indice, nbits, 0); + } +#ifdef ADD_LRTD + dec_pit_exc_fx(st_fx, Aq, coder_type, Es_pred, pitch_buf, code, exc, bwe_exc, nb_subfr, gain_buf, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf); +#else + dec_pit_exc_fx(st_fx, Aq, st_fx->coder_type_fx, Es_pred, pitch_buf, code, exc, bwe_exc, nb_subfr, gain_buf); +#endif + IF( LT_32(st_fx->core_brate,ACELP_9k60)) + { + minimum_fx(pitch_buf, shr(st_fx->L_frame, 6), &low_pit); + low_pit = shr(low_pit, 6); /*Q6 -> Q0 */ + + IF( LT_16(low_pit,64)) + { + pit_band_idx = 9+BAND1k2; + move16(); + if(EQ_16(st_fx->bwidth,NB)) + { + pit_band_idx = 7+BAND1k2; + move16(); + } + } + ELSE IF ( LT_16(low_pit,128)) + { + pit_band_idx = 5+BAND1k2; + move16(); + } + ELSE + { + pit_band_idx = 3+BAND1k2; + move16(); + } + + Diff_len = mfreq_loc_div_25[pit_band_idx]; + move16(); + hGSCDec->Last_GSC_pit_band_idx_fx = pit_band_idx; + move16(); + } + + /*---------------------------------------------------------------* + * DCT transform + *---------------------------------------------------------------*/ + edct_16fx( exc, dct_epit, st_fx->L_frame, 7 , st_fx->element_mode); + + /*---------------------------------------------------------------* + * Reset unvaluable part of the adaptive (pitch) excitation contribution + *---------------------------------------------------------------*/ + + max_len = sub(st_fx->L_frame, Diff_len ); + + if(EQ_16(st_fx->bwidth,NB)) + { + max_len = sub(160,Diff_len); + } + + Len = 80; + move16(); + if( max_len < 80 ) + { + Len = max_len; + move16(); + } + + test(); + IF(EQ_32(st_fx->core_brate,ACELP_8k00)&&NE_16(st_fx->bwidth,NB)) + { + FOR (i=0; i < max_len; i++) + { + dct_epit[i+Diff_len] = 0; + move16(); + } + } + ELSE + { + FOR (i = 0; i < Len; i++) + { + dct_epit[i + Diff_len] = mult_r(dct_epit[i + Diff_len],sm_table_fx[i]); + move16(); + } + + FOR (; i < max_len; i++) + { + dct_epit[i + Diff_len] = 0; + move16(); + } + } + //PMT("in the rare case of 4 subfr, bfi_pitch_fx might be wrong") + st_fx->bfi_pitch_fx = mean_fx(pitch_buf, nb_subfr); + move16(); + st_fx->bfi_pitch_frame = st_fx->L_frame; + move16(); + + Diff_len = add(Diff_len,1); + st_fx->bpf_off = 0; + move16(); + } + ELSE + { + /* No adaptive (pitch) excitation contribution */ + st_fx->bpf_off = 1; + move16(); + set16_fx(dct_epit, 0, st_fx->L_frame); + + IF (EQ_16(st_fx->L_frame, L_FRAME16k)) + { + set16_fx(pitch_buf, shl(L_SUBFR16k, 6), NB_SUBFR16k); + } + ELSE + { + set16_fx(pitch_buf, shl(L_SUBFR, 6), NB_SUBFR); + } + + set16_fx( gain_buf, 0, NB_SUBFR16k); + + st_fx->bfi_pitch_fx = shl(L_SUBFR,6); + st_fx->bfi_pitch_frame = st_fx->L_frame; + move16(); + st_fx->lp_gainp_fx = 0; + move16(); + st_fx->lp_gainc_fx = 0; + move16(); + st_fx->tilt_code_fx = 0; + move16(); + pit_band_idx = 0; + move16(); + Diff_len = 0; + move16(); + } + + /*--------------------------------------------------------------------------------------* + * GSC decoder + *--------------------------------------------------------------------------------------*/ + + /* find the current total number of bits used */ + + tmp_nb_bits_tot = st_fx->next_bit_pos; + move16(); +#ifdef IVAS_CODE + if( st_fx->extl_brate_fx_orig > 0 ) +#else + if( st_fx->extl_brate > 0 ) +#endif + { + /* subtract 1 bit for TBE/BWE BWE flag (bit counted in extl_brate) */ + tmp_nb_bits_tot = sub(tmp_nb_bits_tot, 1); + } + + + test(); +#if defined ADD_LRTD + test(); + if( EQ_16(st_fx->coder_type_fx,INACTIVE) && LE_32(st_fx->core_brate,ACELP_9k60) && st_fx->idchan == 0) +#else + if (EQ_16(st_fx->coder_type_fx, INACTIVE) && LE_32(st_fx->core_brate, ACELP_9k60)) +#endif + { + tmp_nb_bits_tot = add(tmp_nb_bits_tot,5); + } + +#ifdef ADD_LRTD + IF (EQ_16(st_fx->idchan, 1) ) + { + tmp_nb_bits_tot = add(tmp_nb_bits_tot, TDM_SIGNAL_BITS_READ_FROM_THE_END_OF_BS); + IF (EQ_16(st_fx->tdm_LRTD_flag, 1)) + { + tmp_nb_bits_tot = sub(tmp_nb_bits_tot, STEREO_BITS_TCA); + } + } +#endif + gsc_dec_fx(st_fx, dct_epit, pit_band_idx, Diff_len, tmp_nb_bits_tot, nb_subfr, st_fx->coder_type_fx, &last_bin, lsf_new, exc_wo_nf, st_fx->Q_exc ); + /*--------------------------------------------------------------------------------------* + * iDCT transform + *--------------------------------------------------------------------------------------*/ + + edct_16fx( dct_epit, exc, st_fx->L_frame, 7, st_fx->element_mode); + edct_16fx( exc_wo_nf, exc_wo_nf, st_fx->L_frame, 7, st_fx->element_mode); + /*----------------------------------------------------------------------* + * Remove potential pre-echo in case an onset has been detected + *----------------------------------------------------------------------*/ + + pre_echo_att_fx( &hGSCDec->Last_frame_ener_fx, exc, gsc_attack_flag + ,st_fx->Q_exc ,st_fx->last_coder_type_fx, st_fx->L_frame); + + /*--------------------------------------------------------------------------------------* + * Update BWE excitation + *--------------------------------------------------------------------------------------*/ + + if (st_fx->hBWE_TD != NULL) + { + set16_fx(voice_factors, 0, NB_SUBFR16k); + IF (EQ_16(st_fx->L_frame, L_FRAME16k)) + { + interp_code_4over2_fx(exc, bwe_exc, st_fx->L_frame); + } + ELSE + { + interp_code_5over2_fx(exc, bwe_exc, L_FRAME); + } + } + /*--------------------------------------------------------------------------------------* + * Updates + *--------------------------------------------------------------------------------------*/ + + Copy( exc, exc2, st_fx->L_frame); + Copy( exc_wo_nf, exc, st_fx->L_frame); + + /*--------------------------------------------------------------------------------------* + * Channel aware mode parameters + *--------------------------------------------------------------------------------------*/ + + set16_fx( st_fx->tilt_code_dec_fx, 0, NB_SUBFR16k ); + + return; +} + +/*==========================================================================*/ +/* FUNCTION : void gsc_dec_fx () */ +/*--------------------------------------------------------------------------*/ +/* PURPOSE : Generic audio signal decoder */ +/*--------------------------------------------------------------------------*/ +/* INPUT ARGUMENTS : */ +/* _ (Word16) pit_band_idx : bin position of the cut-off frequency Q0 */ +/* _ (Word16) Diff_len : Lenght of the difference signal Q0 */ +/* _ (Word16) coder_type : coding type Q0 */ +/* _ (Word16) bits_used : Number of bit used before frequency Q Q0 */ +/* _ (Word16) nb_subfr : Number of subframe considered Q0 */ +/* _ (Word16) Qexc : Q format of exc_dct_in */ +/*--------------------------------------------------------------------------*/ +/* OUTPUT ARGUMENTS : */ +/* _ None */ +/*--------------------------------------------------------------------------*/ +/* INPUT/OUTPUT ARGUMENTS : */ +/* Decoder_State *st_fx:Decoder State Structure */ +/* _ (Word16[]) exc_dct_in : dctof pitch-only excitation / total excitation Qexc*/ +/*--------------------------------------------------------------------------*/ +/* RETURN ARGUMENTS : */ +/* _None */ +/*==========================================================================*/ +void gsc_dec_fx( + Decoder_State *st_fx, /* i/o: State structure */ + Word16 exc_dct_in[], /* i/o: dct of pitch-only excitation / total excitation */ + const Word16 pit_band_idx, /* i : bin position of the cut-off frequency */ + const Word16 Diff_len, /* i : Lenght of the difference signal (before pure spectral)*/ + const Word16 bits_used, /* i : Number of bit used before frequency Q */ + const Word16 nb_subfr, /* i : Number of subframe considered */ + const Word16 coder_type, /* i : coding type */ + Word16 *last_bin, /* i : last bin of bit allocation */ + const Word16 *lsf_new, /* i : ISFs at the end of the frame */ + Word16 *exc_wo_nf, /* o : excitation (in f domain) without noisefill */ + Word16 Q_exc +) +{ + Word16 i, j, bit, nb_subbands, pvq_len; +#if 1//def ADD_LRTD + Word16 bitallocation_band[MBANDS_GN_BITALLOC16k]; + Word16 bitallocation_exc[2]; + Word16 Ener_per_bd_iQ[MBANDS_GN_BITALLOC16k]; + Word16 max_ener_band[MBANDS_GN_BITALLOC16k]; + Word16 exc_diffQ[L_FRAME16k]; + Word16 bits_per_bands[MBANDS_GN_BITALLOC16k]; + Word16 concat_out[L_FRAME16k]; +#else + Word16 bitallocation_band[MBANDS_GN]; + Word16 bitallocation_exc[2]; + Word16 Ener_per_bd_iQ[MBANDS_GN]; + Word16 max_ener_band[MBANDS_GN]; + Word16 exc_diffQ[L_FRAME]; + Word16 bits_per_bands[MBANDS_GN]; + Word16 concat_out[L_FRAME]; +#endif + Word16 inpulses_fx[NB_SFM]; + Word16 imaxpulse_fx[NB_SFM]; + Word16 mean_gain; + Word16 Mbands_gn = 16; + Word16 Qexc_diffQ = Q_PVQ_OUT; + Word32 L_tmp; + Word16 Q_tmp; + Word16 seed_init; + GSC_DEC_HANDLE hGSCDec; + hGSCDec = st_fx->hGSCDec; + + set16_fx(inpulses_fx, 0,NB_SFM); + set16_fx(imaxpulse_fx, 0,NB_SFM); + + /*--------------------------------------------------------------------------------------* + * Initialization + *--------------------------------------------------------------------------------------*/ + bit = bits_used; + move16(); +#ifdef ADD_LRTD + test(); test(); test(); test(); + IF (EQ_16(coder_type, INACTIVE) && (EQ_16(st_fx->tdm_LRTD_flag, 1) || EQ_16(st_fx->element_mode, IVAS_SCE) ) && LE_32(st_fx->core_brate, GSC_LRES_GAINQ_LIMIT) ) + { + bit = add( bit, GSC_LRES_NB_NITS); + } + + IF (EQ_16(st_fx->L_frame, L_FRAME16k) ) + { + Mbands_gn = MBANDS_GN16k; + move16(); + } +#endif + set16_fx( exc_diffQ, 0, st_fx->L_frame ); + + /*--------------------------------------------------------------------------------------* + * Gain decoding + *--------------------------------------------------------------------------------------*/ + + test(); + IF( st_fx->bfi || st_fx->BER_detect ) + { + /* copy old gain */ + Copy(hGSCDec->old_y_gain_fx, Ener_per_bd_iQ, Mbands_gn ); + mean_gain = mult_r(st_fx->lp_gainc_fx,3277); /*Q3*/ + FOR( i=0; ilp_gainc_fx = mult_r(st_fx->lp_gainc_fx,32112); /*Q3*/ + } + ELSE + { + +#ifdef ADD_LRTD + i = 0; + move16(); + While (LT_16(i, SIZE_BRATE_INTERMED_TBL)) + { + IF (LQ_32(st_fx->core_brate, brate_intermed_tbl[i])) + { + break; + } + i = add(i,1); + } + + test(); test(); test(); test(); + IF (GT_16(st_fx->element_mode, EVS_MONO) > && EQ_16(coder_type, AUDIO) && + LE_32(st_fx->core_brate, STEREO_GSC_BIT_RATE_ALLOC) && EQ_32(brate_intermed_tbl[i],ACELP_9k60) ) /* Bit allocation is mapped to 8 kb/s instead of 9.6 kb/s in this case */ + { + i--; + } + mean_gain = gsc_gaindec_fx(st_fx, Ener_per_bd_iQ, brate_intermed_tbl[i], hGSCDec->old_y_gain_fx, coder_type, st_fx->bwidth); + +#else + mean_gain = gsc_gaindec_fx( st_fx, Ener_per_bd_iQ, st_fx->core_brate, hGSCDec->old_y_gain_fx, coder_type, st_fx->bwidth ); +#endif + st_fx->lp_gainc_fx = mult_r(640,mean_gain); /*10 in Q6 x Q12 -> lp_gainc in Q3 */ + } + + *last_bin = 0; + move16(); + test(); + IF( EQ_32(st_fx->core_brate,ACELP_8k00)&&NE_16(st_fx->bwidth,NB)) + { + bitallocation_exc[0] = 0; + move16(); + bitallocation_exc[1] = 0; + move16(); + } + + set16_fx( bitallocation_band, 0, MBANDS_GN ); + + test(); + IF( (EQ_16(st_fx->bfi,1))||st_fx->BER_detect) + { + /*--------------------------------------------------------------------------------------* + * Copy old spectrum + * reduce spectral dynamic + * save spectrum + *--------------------------------------------------------------------------------------*/ +#ifdef ADD_LRTD + max_eq = 32767; + move16(); +#endif + test(); + IF( EQ_16(st_fx->last_good_fx,INACTIVE_CLAS)||EQ_16(st_fx->Last_GSC_noisy_speech_flag_fx,1)) + { + FOR( i=0; iL_frame; i++ ) + { + L_tmp = L_shr(L_mult(Random(&hGSCDec->seed_tcx_fx),26214),5); /*Q10*/ + L_tmp = L_mac(L_tmp, hGSCDec->Last_GSC_spectrum_fx[i],6554); + hGSCDec->Last_GSC_spectrum_fx[i] = round_fx(L_tmp); /*Q10*/ + } + } + + Copy(hGSCDec->Last_GSC_spectrum_fx, exc_diffQ, st_fx->L_frame); + + FOR( i=0; i< st_fx->L_frame; i++ ) + { + hGSCDec->Last_GSC_spectrum_fx[i] = mult_r(hGSCDec->Last_GSC_spectrum_fx[i],24576); /*Q10*/ move16(); + } + + } + ELSE + { + /*--------------------------------------------------------------------------------------* + * PVQ decoder + *--------------------------------------------------------------------------------------*/ + + bands_and_bit_alloc_fx(hGSCDec->cor_strong_limit_fx, hGSCDec->noise_lev_fx, st_fx->core_brate, Diff_len, bit, &bit, Ener_per_bd_iQ, + max_ener_band, bits_per_bands, &nb_subbands, NULL, NULL, &pvq_len, coder_type, st_fx->bwidth, st_fx->GSC_noisy_speech_fx, + st_fx->L_frame, st_fx->element_mode, st_fx->GSC_IVAS_mode ); + +#ifdef ADD_LRTD + if (bit == 0) + { + set16_fx(concact_out, 0, L_FRAME16k); + } +#endif + { + pvq_core_dec_fx(st_fx, gsc_sfm_start, gsc_sfm_end, gsc_sfm_size, concat_out, &Q_tmp, bit, nb_subbands, bits_per_bands, NULL, inpulses_fx, imaxpulse_fx, ACELP_CORE); + Scale_sig(concat_out, gsc_sfm_end[nb_subbands - 1], sub(Q_PVQ_OUT, Q_tmp)); + } + seed_init = 0; + move16(); + +#ifdef ADD_LRTD + max_eq = 0.0f; + max_eq_val = 1.0f; + + if (((st_fx->core_brate < ACELP_7k20 && st_fx->GSC_noisy_speech == 1) || st_fx->core_brate < 6000) && coder_type <= UNVOICED) + { + j = emaximum(concat_out, nb_subbands * 16, &max_eq); + max_eq = (float)(max_eq_val / (fabs(concat_out[j]) + 0.01f)); + max_eq = min(max_eq_val, max_eq); + } +#endif + /* Reorder Q bands */ + FOR(j = 0; j < nb_subbands; j++) + { + Copy( concat_out+j*16, exc_diffQ + max_ener_band[j]*16, 16); + + *last_bin = s_max(*last_bin,max_ener_band[j]); + move16(); + + bitallocation_band[max_ener_band[j]] = 1; + move16(); + + seed_init =add(seed_init,inpulses_fx[j]); + } + test(); + IF( NE_16(st_fx->last_coder_type_fx, AUDIO) /* First audio frame */ + && NE_16(st_fx->last_coder_type_fx, UNVOICED) )/* last_coder_type == INACTIVE is overwritten in update_dec to UNVOICED */ + { + FOR( j = 0; j < shl(nb_subbands,4); j++ ) + { + IF( concat_out[j] > 0 ) + { + seed_init = extract_l(L_shl(seed_init,3)); + } + IF( concat_out[j] < 0 ) + { + seed_init = add(seed_init,3); + move16(); + } + } + + hGSCDec->seed_tcx_fx = seed_init; + move16(); + } + test(); + IF( EQ_32(st_fx->core_brate,ACELP_8k00)&&NE_16(st_fx->bwidth,NB)) + { + if( exc_diffQ[L_FRAME8k - 2] != 0 ) + { + bitallocation_exc[0] = 1; + move16(); + } + + if( exc_diffQ[L_FRAME8k - 1] != 0 ) + { + bitallocation_exc[1] = 1; + move16(); + } + } + + Copy( exc_diffQ, hGSCDec->Last_GSC_spectrum_fx, st_fx->L_frame ); + + /*--------------------------------------------------------------------------------------* + * Skip adaptive (pitch) contribution frequency band (no noise added over the time contribution) + * Find x pulses between 1.6-3.2kHz to code in the spectrum of the residual signal + * Gain is based on the inter-correlation gain between the pulses found and residual signal + *--------------------------------------------------------------------------------------*/ +#ifdef ADD_LRTD + test(); test(); test(); test(); test(); test(); + IF (GE_16(st_fx->GSC_IVAS_mode, 1) && EQ_16(st_fx->GSC_noisy_speech, 1)) + { + FOR (i = 64; i < st_fx->L_frame; i++) + { + PMT("GSC FIX point to be done here") + exc_diffQ[i] *= max_eq; + } + } + ELSE IF (((LT_32(st_fx->core_brate, ACELP_7k20) && EQ_16(st_fx->GSC_noisy_speech, 1) ) || LT_32(st_fx->core_brate, 6000) ) && LE_16(st_fx->coder_type, UNVOICED)) + { + FOR (i = 0; i < L_FRAME; i++) + { + PMT("GSC FIX point to be done here") + exc_diffQ[i] *= max_eq; + } + } + else +#endif + { + freq_dnw_scaling_fx(hGSCDec->cor_strong_limit_fx, st_fx->coder_type_fx, hGSCDec->noise_lev_fx, st_fx->core_brate, exc_diffQ, Qexc_diffQ, st_fx->L_frame); + } + } + + /*--------------------------------------------------------------------------------------* + * Estimate noise level + *--------------------------------------------------------------------------------------*/ + + highband_exc_dct_in_fx( st_fx->core_brate, mfreq_bindiv_loc, *last_bin, Diff_len, hGSCDec->noise_lev_fx, pit_band_idx, exc_diffQ, + &hGSCDec->seed_tcx_fx, Ener_per_bd_iQ, nb_subfr, exc_dct_in, st_fx->last_coder_type_fx, bitallocation_band, lsf_new, + hGSCDec->last_exc_dct_in_fx, &hGSCDec->last_ener_fx, hGSCDec->last_bitallocation_band_fx, bitallocation_exc, st_fx->bfi, coder_type, + st_fx->bwidth, exc_wo_nf, Qexc_diffQ, Q_exc, st_fx->GSC_noisy_speech_fx, hGSCDec->lt_ener_per_band_fx + , st_fx->L_frame, st_fx->element_mode, st_fx->GSC_IVAS_mode + ); + + exc_dct_in[0] = 0; + move16(); + + return; + +} +/*-------------------------------------------------------------------* +* GSC_dec_init() +* +* Initialize GSC decoder state structure +*-------------------------------------------------------------------*/ + +void GSC_dec_init( + GSC_DEC_HANDLE hGSCDec /* i/o: GSC data handle */ +) +{ + hGSCDec->seed_tcx_fx = 15687; + hGSCDec->cor_strong_limit_fx = 1; + move16(); + move16(); + + hGSCDec->noise_lev_fx = NOISE_LEVEL_SP0; + hGSCDec->Last_GSC_pit_band_idx_fx = 0; + move16(); + move16(); + +#ifdef ADD_LRTD + set16_fx(hGSCDec->Last_GSC_spectrum_fx, 0, L_FRAME16k); + set16_fx(hGSCDec->last_exc_dct_in_fx, 0, L_FRAME16k); + set16_fx(hGSCDec->lt_ener_per_band_fx, 4096, MBANDS_GN_BITALLOC16k); + set16_fx(hGSCDec->old_y_gain_fx, 0, MBANDS_GN_BITALLOC16k); +#else + set16_fx(hGSCDec->Last_GSC_spectrum_fx, 0, L_FRAME); + set16_fx(hGSCDec->last_exc_dct_in_fx, 0, L_FRAME); + set16_fx(hGSCDec->old_y_gain_fx, 0, MBANDS_GN); + set16_fx(hGSCDec->lt_ener_per_band_fx, 4096, MBANDS_GN);/*Q12*/ +#endif + hGSCDec->last_ener_fx = 0; + move16(); + set16_fx(hGSCDec->last_bitallocation_band_fx, 0, 6); + + hGSCDec->Last_frame_ener_fx = MAX_32; + move32(); + return; +} diff --git a/lib_dec/hdecnrm_fx.c b/lib_dec/hdecnrm_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..e815efcc27d370d223e4cbc91784733508575091 --- /dev/null +++ b/lib_dec/hdecnrm_fx.c @@ -0,0 +1,405 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ +#include +#include "options.h" /* Compilation switches */ +#include "prot_fx1.h" +#include "prot_fx2.h" +#include "rom_dec.h" + +/*--------------------------------------------------------------------------*/ +/* Function hdecnrm_fx */ +/* ~~~~~~~~~~~~~~~~~~~~ */ +/* */ +/* Huffman decoding for indices of quantized norms */ +/*--------------------------------------------------------------------------*/ +void hdecnrm_fx( + Decoder_State *st_fx,/* i/o: decoder state structure */ + const Word16 numNorms, /* i : number of norms */ + Word16 *index) /* o : indices of quantized norms */ +{ + Word16 i, j, k, n, m; + Word16 temp; + Word16 *pidx; + + + pidx = index; + + m = sub(numNorms, 1); + FOR (i=0; i 0) + { + tmp_h = shr(hufftab[hufftab_idx],4); + tmp_l = sub(hufftab[hufftab_idx],shl(tmp_h,4)); + *rbits = add(*rbits,tmp_l); + hufftab_idx = L_add(hufftab_idx, L_add(L_deposit_l(tmp_h), get_next_indice( st_fx, tmp_l ) )); + } + return negate(hufftab[hufftab_idx]); +} + + +/*--------------------------------------------------------------------------*/ +/* hdecnrm_context_fx() */ +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +/* */ +/* Huffman decoding for indices of quantized norms */ +/*--------------------------------------------------------------------------*/ +/* Word16 N (i) number of norms */ +/* Word16 *index (o) indices of quantized norms */ +/* Word16 *n_length (o) decoded stream length */ +/*--------------------------------------------------------------------------*/ + +void hdecnrm_context_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + const Word16 N, + Word16 *index, + Word16 *n_length +) +{ + Word16 i, prevj, tmp; + + prevj = add(index[0], OFFSET_NORM); + FOR( i=1; i < N; i++) + { + IF( GT_16(prevj, HTH_NORM)) + { + /* above */ + tmp = decode_huff_context_fx( st_fx, hntable, n_length); + index[i] = sub(31 , tmp); + move16(); + } + ELSE + { + IF( LT_16(prevj, LTH_NORM)) + { + /* less */ + index[i] = decode_huff_context_fx(st_fx, hntable, n_length); + move16(); + } + ELSE + { + /* equal */ + index[i] = decode_huff_context_fx(st_fx, hetable, n_length); + move16(); + } + } + prevj = index[i]; + move16(); + } + return; +} + +void hdecnrm_resize_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + const Word16 N, /* (i) number of SFMs */ + Word16 *index /* (o) norm quantization index vector */ +) +{ + Word16 i, j, k, m; + Word16 temp; + Word16 *pidx; + + pidx = index; + + m = sub(N, 1); + move16(); + FOR (i=0; inext_bit_pos = sub(st_fx->next_bit_pos, j); + + return; +} + +/*-------------------------------------------------------------------------- + * hdecnrm_trans() + * + * Huffman decoding for indices of quantized norms + *--------------------------------------------------------------------------*/ + +void hdecnrm_tran_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + const Word16 N, /* i : number of norms */ + Word16 *index /* o : indices of quantized norms */ +) +{ + Word16 i, j, k, n, m; + Word16 temp; + Word16 *pidx; + Word16 l; + + pidx = index; + move16(); + + m = sub(N, 1); + FOR (i=0; i +#include "options.h" /* Compilation switches */ +#include "cnst.h" /* Common constants */ +#include "prot_fx1.h" /* Function prototypes */ +#include "prot_fx2.h" /* Function prototypes */ +#include "rom_com.h" /* Static table prototypes */ +#include "basop32.h" + +/*---------------------------------------------------------------------* + * Local constants + *---------------------------------------------------------------------*/ + +#define L_SUBFR48k 240 +#define L_SUBFR32k 160 + +/*---------------------------------------------------------------------* + * Local function prototypes + *---------------------------------------------------------------------*/ + +static void filt_6k_7k_scale_fx(Word16 signal[], Word16 lg, Word16 mem[], Word16 fact, Word16 exp); + +static void hf_synthesis_fx(ZERO_BWE_DEC_HANDLE hBWE_zero, const Word32 core_brate, const Word16 output_subfr,const Word16 Aq[], + const Word16 exc[], const Word16 Q_exc,Word16 synth[],Word16 synth16k[] + , const Word16 Q_syn, Word16* delay_syn_hf, Word16 *memExp1, Word16* mem_hp_interp, const Word16 extl, const Word16 CNG_mode ); + +static void hf_synthesis_amr_wb_fx( const Word32 core_brate, const Word16 output_subfr, const Word16 Ap[], Word16 exc16k[], + Word16 synth_out[], Word16 *mem_syn_hf, Word16 *delay_syn_hf, Word16 *mem_hp_interp, Word16 p_r, + Word16 HF_corr_gain, Word16 til, Word16 voice_factors, const Word16 exc[], const Word16 Q_exc, const Word16 Q_out, Word16 qhf ); +static void envelope_fx(AMRWB_IO_DEC_HANDLE hAmrwb_IO, const Word32 core_brate, const Word16 Aq[], Word16 Ap[], Word16 *r, Word16 tilt0, Word16 tilt, Word16 voice_factor); +static void AdaptiveStartBand_fx( Word16 *start_band, const Word32 rate, const Word16 *lsf, const Word16 voicing_fac, const Word16 clas, Word16 *voicing_flag, + Word16 *start_band_old, Word32 *OptCrit_old ); + + + +/*-------------------------------------------------------------------* + * hf_synth_init() + * + * hf synthesis filters initialization + * - initialization of 400 Hz high pass filter + * - initialization of band pass 6kHz to 7kHz FIR filter + *-------------------------------------------------------------------*/ +void hf_synth_init_fx( + ZERO_BWE_DEC_HANDLE hBWE_zero /* o : zero BWE decoder handle */ +) +{ + + hBWE_zero->seed2_fx = RANDOM_INITSEED; + set16_fx(hBWE_zero->mem_hf_fx, 0, 2 * L_FILT16k); + set16_fx(hBWE_zero->mem_syn_hf_fx, 0, M); + set16_fx(hBWE_zero->mem_hp400_fx, 0, 4); + set16_fx(hBWE_zero->delay_syn_hf_fx, 0, NS2SA(16000, DELAY_CLDFB_NS)); + set16_fx(hBWE_zero->mem_hp_interp_fx, 0, INTERP_3_1_MEM_LEN); + + return; +} +void hf_synth_reset_fx( + ZERO_BWE_DEC_HANDLE hBWE_zero /* o : zero BWE decoder handle */ +) +{ + Word16 i; + + FOR(i = 0; i < L_FRAME16k; i++) + { + Random(&hBWE_zero->seed2_fx); + } + + set16_fx(hBWE_zero->mem_hf_fx, 0, 2 * L_FILT16k); + set16_fx(hBWE_zero->mem_syn_hf_fx, 0, M); + set16_fx(hBWE_zero->mem_hp400_fx, 0, 4); /* TBV -> mem_hp400_fx has a length of 6, but only 4 values initialized in EVS ??? */ + + set16_fx(hBWE_zero->delay_syn_hf_fx, 0, NS2SA(16000, DELAY_CLDFB_NS)); + set16_fx(hBWE_zero->mem_hp_interp_fx, 0, INTERP_3_1_MEM_LEN); + + return; +} + +/*---------------------------------------------------------------------* + * hf_synth() + * + * High frequency regeneration + *---------------------------------------------------------------------*/ + +void hf_synth_fx( + ZERO_BWE_DEC_HANDLE hBWE_zero, /* i/o: handle to 0 bit BWE parameters */ + const Word32 core_brate, /* i : core bitrate */ + const Word16 output_frame, /* i : output frame length */ + const Word16 *Aq, /* i : quantized Az */ + const Word16 *exc, /* i : excitation at 12.8 kHz */ + Word16 *synth, /* i : 12.8kHz synthesis signal */ + Word16 *synth16k, /* o : 16kHz synthesis signal */ + const Word16 Q_exc, /* i : excitation scaling */ + const Word16 Q_syn2, /* i : synthesis scaling */ + Word16 *delay_syn_hf, /*i/o: HF synthesis memory */ + Word16 *memExp1, /* o : HF excitation exponent */ + Word16 *mem_hp_interp, /* i/o: interpol. memory */ + const Word16 extl, /* i : flag indicating BWE */ + const Word16 CNG_mode /* i : CNG_mode */ +) +{ + const Word16 *p_Aq; + Word16 i_subfr, output_subfr; + + output_subfr = output_frame/NB_SUBFR; + move16(); + + p_Aq = Aq; + move16(); + FOR( i_subfr=0; i_subfr 0.8 ==> - 14 dB (voiced) + * tilt 0.5 ==> - 6 dB (voiced or noise) + * tilt < 0.0 ==> 0 dB (noise) + *-----------------------------------------------------------------------------------*/ + +static void hf_synthesis_fx( + ZERO_BWE_DEC_HANDLE hBWE_zero, + const Word32 core_brate, /* i : core bitrate */ + const Word16 output_subfr, /* i : output sub-frame length */ + const Word16 Aq[], /* i : quantized Az Q12 */ + const Word16 exc[], /* i : excitation at 12.8 kHz Q_exc */ + const Word16 Q_exc, /* i : excitation scaling */ + Word16 synth[], /* i : 12.8kHz synthesis signal Q_syn */ + Word16 synth16k[], /* i/o: 16kHz synthesis signal Q_syn */ + const Word16 Q_syn, /* i : synthesis scaling */ + Word16 *delay_syn_hf, /* i/o: HF synthesis memory Q_syn */ + Word16 *memExp1, /* o : HF excitation scaling exponent */ + Word16 *mem_hp_interp, /* i/o: interpol. memory */ + const Word16 extl, /* i : flag indicating BWE */ + const Word16 CNG_mode /* i : CNG_mode */ +) +{ + Word16 i; + Word16 HF_syn[L_SUBFR16k], upsampled_HF_syn[L_FRAME48k/NB_SUBFR]; + Word16 HF_exc[L_SUBFR16k]; + Word16 temp_buffer[NS2SA(16000,DELAY_CLDFB_NS) - L_FILT16k]; + Word16 tmp, ener, exp1, exp2, scale, delay; + Word32 L_tmp; + Word16 Ap[M16k+1]; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + (void)extl; + (void)CNG_mode; + + /*-----------------------------------------------------------------* + * generate white noise vector + *-----------------------------------------------------------------*/ + + Random_Fill(&hBWE_zero->seed2_fx, L_SUBFR16k, HF_exc, 3); /* 3 = Shift Right by 3 */ + + /* o: HF_exc in Q-3 */ + + /*-----------------------------------------------------------------* + * calculate energy scaling factor so that white noise would have the + * same energy as exc12k8 + *-----------------------------------------------------------------*/ + + /*ener = sum2_f( exc, L_SUBFR ) + 0.01f*/ + ener = extract_h(Dot_product12(exc, exc, L_SUBFR, &exp2)); + exp2 = sub(exp2, add(Q_exc, Q_exc)); + + /*tmp = round_fx(Dot_product12(HF_exc, HF_exc, output_subfr, &exp1)); */ + L_tmp = Dot_product12(HF_exc, HF_exc, L_SUBFR16k, &exp1); + tmp = round_fx(L_tmp); + /* tmp = (float)(sqrt(ener/tmp)) */ + /* scale is -1 if tmp > ener */ + scale = shr(sub(ener, tmp), 15); + tmp = shl(tmp, scale); + exp1 = sub(exp1, scale); + + tmp = div_s(tmp, ener); + exp1 = sub(exp1, exp2); + + L_tmp = L_deposit_h(tmp); + + L_tmp = Isqrt_lc(L_tmp, &exp1); + scale = round_fx(L_tmp);/* Q18 when Q_exc=-1, HF_exc in Q-3 */ + + exp2 = sub(*memExp1, exp1); + move16(); + *memExp1 = exp1; + move16(); + + /*-----------------------------------------------------------------* + * calculate energy scaling factor to respect tilt of synth12k8 + * (tilt: 1=voiced, -1=unvoiced) + *-----------------------------------------------------------------*/ + + hp400_12k8_fx( synth, L_SUBFR, hBWE_zero->mem_hp400_fx ); + /* i: mem_hp400 in Q_syn */ + /* i: synth in Q_syn */ + /* o: synth in Q_syn-3 */ + + L_tmp = L_mac(1L, synth[0], synth[0]); + FOR (i = 1; i < L_SUBFR; i++) + { +#ifdef BASOP_NOGLOB + L_tmp = L_mac_sat(L_tmp, synth[i], synth[i]); +#else + L_tmp = L_mac(L_tmp, synth[i], synth[i]); +#endif + } + tmp = norm_l(L_tmp); + ener = extract_h(L_shl(L_tmp, tmp)); /* ener = r[0] */ + /*ener in Q = 2*(Q_syn-3)+1 = Q-5 when Q_syn=0*/ + + L_tmp = L_mac(1L, synth[1], synth[0]); + FOR (i = 2; i < L_SUBFR; i++) + { +#ifdef BASOP_NOGLOB + L_tmp = L_mac_sat(L_tmp, synth[i], synth[i - 1]); +#else + L_tmp = L_mac(L_tmp, synth[i], synth[i - 1]); +#endif + } + tmp = extract_h(L_shl(L_tmp, tmp)); /* tmp = r[1] */ + /*tmp in Q = 2*(Q_syn-3)+1 = Q-5 when Q_syn=0 */ + /*we use the same normalization factor for both ener and tmp, */ + /*if the headroom in "tmp" is less than "ener", tmp can saturate */ + /*but this is ok since below we apply some thresholds to tmp */ + + tmp = s_max(0, tmp); + if (tmp > 0) + { + tmp = div_s(tmp, ener); + } + + /*-----------------------------------------------------------------* + * modify energy of white noise according to synthesis tilt + *-----------------------------------------------------------------*/ + + /* tmp = 1.0 - fac */ +#ifdef BASOP_NOGLOB + tmp = add_o(1, sub(32767, tmp), &Overflow); +#else + tmp = add(1, sub(32767, tmp)); +#endif + test(); + if( EQ_32(core_brate,FRAME_NO_DATA)||EQ_32(core_brate,SID_2k40)) + { + /* emphasize HF noise in CNG */ + /*fac *= 2.0f;*/ +#ifdef BASOP_NOGLOB + tmp = add_o(tmp, tmp, &Overflow); +#else + tmp = add(tmp, tmp); +#endif + } + tmp = s_max(tmp, 3277); /* 0.1 in Q15 */ + + /*scale *= fac;*/ + tmp = mult_r(scale, tmp); + /*-----------------------------------------------------------------* + * modify HF excitation according to both calculated scaling factors + * high pass filtering (0.94ms of delay) + *-----------------------------------------------------------------*/ + + filt_6k_7k_scale_fx( HF_exc, L_SUBFR16k, hBWE_zero->mem_hf_fx,tmp,exp2 ); + /* i: input HF_exc is scaled in float, here scaling is done inside this filter */ + /* i: mem_hf in Q-2 */ + /* o: HF_exc in Q0 */ + + /*-----------------------------------------------------------------* + * synthesis of noise: 4.8kHz..5.6kHz --> 6kHz..7kHz + *-----------------------------------------------------------------*/ + + /*weight_a( Aq, Ap, 0.6f, M );*/ + weight_a_lc_fx(Aq, Ap, Gamma_19661_Tbl_fx, M); + /* o: Ap in Q14 */ + + Syn_filt_s( 0, Ap, M, HF_exc, HF_syn, L_SUBFR16k, hBWE_zero->mem_syn_hf_fx, 1 ); + /* i: Ap in Q14 */ + /* i: HF_exc in Q0 */ + /* o: HF_syn in Q0 */ + /* i/o: mem_syn_hf in Q0 */ + + Scale_sig(HF_syn, L_SUBFR16k, (add(Q_syn, exp1))); /* bring HF_syn to (Q_syn+exp1) */ + + /*-----------------------------------------------------------------* + * add filtered HF noise to speech synthesis + *-----------------------------------------------------------------*/ + + /* delay by 5 samples @16kHz to compensate CLDFB resampling delay (20samples) and HP filtering delay (roughly 15 samples) */ + delay = NS2SA(16000,DELAY_CLDFB_NS) - 15; + Copy( HF_syn+L_SUBFR16k-delay, temp_buffer, delay ); + Copy( HF_syn, HF_syn+delay, L_SUBFR16k-delay ); + Copy( delay_syn_hf, HF_syn, delay ); + Copy( temp_buffer, delay_syn_hf, delay ); + + /* interpolate the HF synthesis */ + IF( EQ_16(output_subfr,L_SUBFR48k)) /* 48kHz sampled output */ + { + { + Word16 s; + s = s_max(s_min(sub(s_min(Find_Max_Norm16(HF_syn, L_SUBFR16k), Find_Max_Norm16(mem_hp_interp, INTERP_3_1_MEM_LEN - 3)), 3), + sub(Find_Max_Norm16(mem_hp_interp + INTERP_3_1_MEM_LEN - 3, 3), 1)), 0 ); + Scale_sig(HF_syn, L_SUBFR16k, s); + Scale_sig(mem_hp_interp, INTERP_3_1_MEM_LEN, s); + interpolate_3_over_1_allpass_fx( HF_syn, L_SUBFR16k, upsampled_HF_syn, mem_hp_interp); + Scale_sig(upsampled_HF_syn, 3*L_SUBFR16k, -s); + Scale_sig(mem_hp_interp, INTERP_3_1_MEM_LEN, -s); + Scale_sig(HF_syn, L_SUBFR16k, -s); + } + Scale_sig( upsampled_HF_syn, L_SUBFR48k, -1 ); + } + ELSE IF( EQ_16(output_subfr,L_SUBFR32k)) /* 32kHz sampled output */ + { + { + Word16 s; + s = s_max(sub(s_min(Find_Max_Norm16(HF_syn, L_SUBFR16k), Find_Max_Norm16(mem_hp_interp, 2*ALLPASSSECTIONS_STEEP)),2), 0); + Scale_sig(HF_syn, L_SUBFR16k, s); + Scale_sig(mem_hp_interp, 2*ALLPASSSECTIONS_STEEP, s); + Interpolate_allpass_steep_fx( HF_syn, mem_hp_interp, L_SUBFR16k, upsampled_HF_syn ); + Scale_sig(upsampled_HF_syn, 2*L_SUBFR16k, -s); + Scale_sig(mem_hp_interp, 2*ALLPASSSECTIONS_STEEP, -s); + Scale_sig(HF_syn, L_SUBFR16k, -s); + } + } + ELSE /* 16kHz sampled output */ + { + Copy( HF_syn, upsampled_HF_syn, L_SUBFR16k ); + } + + Vr_add( synth16k, upsampled_HF_syn, synth16k, output_subfr ); + + return; +} + + +/*-------------------------------------------------------------------* + * filt_6k_7k: + * + * 15th order band pass 6kHz to 7kHz FIR filter. + * + * frequency: 4kHz 5kHz 5.5kHz 6kHz 6.5kHz 7kHz 7.5kHz 8kHz + * dB loss: -60dB -45dB -13dB -3dB 0dB -3dB -13dB -45dB + * (gain=4.0) + *-------------------------------------------------------------------*/ +static void filt_6k_7k_scale_fx( + Word16 signal[], /* i/o: signal */ + Word16 lg, /* i : length of input */ + Word16 mem[], /* i/o: memory (size=30) */ + Word16 fact, /* i : multiply factor */ + Word16 exp /* i : Mem Exponent */ +) +{ + Word16 i, x[L_FRAME48k/NB_SUBFR+(L_FIR-1)]; + Word32 L_tmp; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + Copy_Scale_sig(mem, x, L_FIR - 1, exp); + + FOR (i = 0; i < lg; i++) + { + x[i + L_FIR - 1] = shr(mult(signal[i], fact), 2); + move16(); /* gain of filter = 4 */ + } + FOR (i = 0; i < lg; i++) + { + + Word16 j; + L_tmp = 0; move32(); + for (j = 0; j<31; j++) + { +#ifdef BASOP_NOGLOB + L_tmp = L_mac_o(L_tmp, x[i+j], fir_6k_7k_fx[j], &Overflow); +#else + L_tmp = L_mac(L_tmp, x[i+j], fir_6k_7k_fx[j]); +#endif + } + +#ifdef BASOP_NOGLOB + signal[i] = round_fx_o(L_tmp, &Overflow); +#else + signal[i] = round_fx(L_tmp); +#endif + } + Copy(x + lg, mem, L_FIR - 1); +} + +/*-------------------------------------------------------------------* + * hf_synth_amr_wb_init() + * + * hf synthesis filters initialization + * - initialization of 1600 Hz low pass filter + * - initialization of band pass 6kHz to 8kHz FIR filter for noise and line resampled signals + *-------------------------------------------------------------------*/ + +void hf_synth_amr_wb_init_fx( + AMRWB_IO_DEC_HANDLE hAmrwb_IO /* i/o: AMR-WB IO data handle */ +) +{ + hAmrwb_IO->prev_r_fx = 0; + move16(); + hAmrwb_IO->fmerit_w_sm_fx = 0; + move16(); + hAmrwb_IO->frame_count_fx = 0; + move16(); + hAmrwb_IO->ne_min_fx = -7680; + move16(); /*Q8*/ + hAmrwb_IO->fmerit_m_sm_fx = 0; + move16(); + hAmrwb_IO->voice_fac_amr_wb_hf = 0; + move16(); + hAmrwb_IO->unvoicing_fx = 0; + move16(); + hAmrwb_IO->unvoicing_sm_fx = 32767; + move16(); /*Q15*/ + hAmrwb_IO->unvoicing_flag_fx = 0; + move16(); + hAmrwb_IO->voicing_flag_fx = 0; + move16(); + hAmrwb_IO->start_band_old_fx = 160; + move16(); + hAmrwb_IO->OptCrit_old_fx = 32768; + move32(); /*Q15*/; + return; +} + + +/*-------------------------------------------------------------------* + * hf_synth_amr_wb_reset() + * + * reset of HF synthesis filters + * - needed in switching scenarios + *-------------------------------------------------------------------*/ +void hf_synth_amr_wb_reset_fx( + ZERO_BWE_DEC_HANDLE hBWE_zero, /* o : zero BWE decoder handle */ + AMRWB_IO_DEC_HANDLE hAmrwb_IO /* i/o: AMR-WB IO data handle */ +) +{ + Word16 i; + + + FOR(i = 0; i < L_FRAME16k; i++) + { + Random(&hBWE_zero->seed2_fx); + } + + set16_fx(hBWE_zero->mem_syn_hf_fx, 0, M); + set16_fx(hBWE_zero->delay_syn_hf_fx, 0, NS2SA(16000, DELAY_CLDFB_NS)); + set16_fx(hBWE_zero->mem_hp_interp_fx, 0, INTERP_3_1_MEM_LEN); + + hAmrwb_IO->prev_r_fx = 0; + move16(); + hAmrwb_IO->fmerit_w_sm_fx = 0; + move16(); + hAmrwb_IO->frame_count_fx = 0; + move16(); + hAmrwb_IO->ne_min_fx = -7680; + move16(); /*Q8*/ + hAmrwb_IO->fmerit_m_sm_fx = 0; + move16(); + hAmrwb_IO->voice_fac_amr_wb_hf = 0; + move16(); + hAmrwb_IO->unvoicing_fx = 0; + move16(); + hAmrwb_IO->unvoicing_sm_fx = 32767; + move16(); /*Q15*/ + hAmrwb_IO->unvoicing_flag_fx = 0; + move16(); + hAmrwb_IO->voicing_flag_fx = 0; + move16(); + hAmrwb_IO->start_band_old_fx = 160; + move16(); + hAmrwb_IO->OptCrit_old_fx = 32768; + move32(); /*Q15*/ + + return; +} + +/*-------------------------------------------------------------------* + * hf_synth_amr_wb() + * + * HF synthesis in AMR-WB IO + *-------------------------------------------------------------------*/ + +void hf_synth_amr_wb_fx( + AMRWB_IO_DEC_HANDLE hAmrwb_IO, /* i/o: AMR-WB IO data handle */ + ZERO_BWE_DEC_HANDLE hBWE_zero, /* o : zero BWE decoder handle */ + const Word32 core_brate, /* i : core bitrate */ + const Word16 output_frame, /* i : output frame length */ + const Word16 *Aq, /* i : quantized Az : Q12 */ + const Word16 *exc, /* i : excitation at 12.8 kHz : Q_exc */ + Word16 *synth, /* i/o: synthesis signal at 12.8k : Q_syn */ + Word16 *amr_io_class, /* i : signal class (determined by FEC algorithm) */ + Word16 *synth_out, /* i/o: output signal at output Fs : Q_out */ + Word16 fmerit, /* i : classify parameter from FEC : Q14 */ + const Word16 *hf_gain, /* i : decoded HF gain */ + const Word16 *voice_factors, /* i : voicing factors : Q15 */ + const Word16 pitch_buf[], /* i : pitch buffer : Q5 */ + const Word16 ng_ener_ST, /* i : Noise gate - short-term energy : Q8 */ + const Word16 *lsf_new, /* i : ISF vector : Q2 */ + const Word16 Q_exc, /* i : exc scaling */ + const Word16 Q_out /* i : Q_syn2-1 */ +) +{ + Word16 core_type = 1; + Word16 start_band; + Word16 HF_corr_gain[NB_SUBFR]; + Word16 filt_weight_coeff; + Word16 i, j, output_subfr; + Word16 *pt3, *pt4, *pt5; + const Word16 *pt6, *pt7; + Word16 *pt1, *pt2; + Word32 enr1, enr2; + Word16 til[NB_SUBFR], til0[NB_SUBFR]; + Word16 tmp1, tmp2; + Word32 L_tmp; + Word16 exp; + Word16 pitch_var_cur; + Word16 voice_fac; + Word16 fmerit_w; + Word16 fmerit_m; + Word16 *p_Ap; + const Word16 *p_Aq; + Word16 Ap[(M16k+1)*NB_SUBFR]; + Word16 sub_gain[NB_SUBFR]; + Word16 exc16k[L_FRAME16k] ; + Word16 qhf; + Word16 dct_exc[L_FRAME], dct_hb[L_FRAME16k], filt_weight[L_SUBFR16k]; + Word16 hb_ener, g, hb_tonal[L_SUBFR16k], tonal_ener, hb_amb[L_SUBFR16k], inv_g; + Word16 fb, fn, signum[L_SUBFR16k]; + Word16 alpha, beta, ener, tmp, scale, rev_filt_weight_coeff, qdct, q1, q2, q3, q4, shift; + Word16 e_subfr1, e_subfr2; + Word32 exc32[L_FRAME], dct_exc32[L_FRAME], dct_hb32[L_FRAME16k], exc16k32[L_FRAME16k]; + Word16 q_tmp; + Word16 gamma; + + Scale_sig(synth, L_FRAME, -3); + + pt1 = synth+1; + pt2 = synth; + pt3 = til; + pt4 = til0; + FOR( i=0; i30-exp */ + *pt3 = round_fx(L_shl(L_tmp, sub(exp,1))); /*13 */ + *pt4++ = *pt3++; + move16(); + + pt1 += L_SUBFR; + pt2 += L_SUBFR; + } + + output_subfr = shr(output_frame , 2); + + if( NE_16(*amr_io_class, 7)) + { + core_type = 0; + move16(); + } + + /* modify LF parameters for excitation weighting or sub-frame gains calculating */ + pitch_var_cur = 0; + move16(); + pt6 = pitch_buf; + pt7 = pitch_buf+1; + FOR( i = 0; i < 3; i++ ) + { + tmp1 = abs_s(sub(*pt6++, *pt7++)); /*Q5 */ + pitch_var_cur = add(pitch_var_cur, shr(tmp1,1)); /*Q6 -> Q5 */ + } + test(); + IF( GT_16(hAmrwb_IO->frame_count_fx, FRAME_COUNT_HF_SYNTH) && *amr_io_class == UNVOICED_CLAS) + { + hAmrwb_IO->frame_count_fx = 0; + hAmrwb_IO->ne_min_fx = -7680; + move16(); + move16();/*Q8; */ + } + ELSE + { + move16(); + hAmrwb_IO->frame_count_fx = s_min(hAmrwb_IO->frame_count_fx, 2 * FRAME_COUNT_HF_SYNTH-1); + hAmrwb_IO->frame_count_fx = add(hAmrwb_IO->frame_count_fx, 1); + hAmrwb_IO->ne_min_fx = s_min(hAmrwb_IO->ne_min_fx, ng_ener_ST); + } + + pt6 = voice_factors; + L_tmp = L_mult(*pt6++,4096); + FOR(i = 1; i < 4; i++) + { + L_tmp = L_mac(L_tmp, *pt6++,4096); + } + + voice_fac = round_fx(L_tmp); + + /*fmerit_w = fmerit > 5734 ? 5734 : (fmerit < 2458 ? 2458 : fmerit); //Q14 */ + + fmerit_w = s_min(fmerit,5734); + fmerit_w = s_max(fmerit_w,2458); + + if ( EQ_16(core_type, 1)) + { + fmerit_w = shr(fmerit_w, 1); /*Q14; */ + } + +#ifdef BASOP_NOGLOB + L_tmp = L_mult(fmerit_w, add_sat(16384, voice_fac)); +#else + L_tmp = L_mult(fmerit_w, add(16384, voice_fac)); +#endif + fmerit_w = extract_l(L_shr(L_tmp, 15)); /*Q14 */ + /**fmerit_w_sm = add(mult_r(*fmerit_w_sm, 29491), mult_r(fmerit_w, 3277)); //Q14 */ + hAmrwb_IO->fmerit_w_sm_fx = round_fx(L_mac(L_mult(hAmrwb_IO->fmerit_w_sm_fx, 29491), fmerit_w, 3277)); /*Q14 */ + fmerit_w = hAmrwb_IO->fmerit_w_sm_fx; + + move16(); + + tmp1 = fmerit; + move16(); + if(LT_16(fmerit, 8192)) + { + tmp1 = 16384; + move16(); + } + fmerit_m = negate(add(-32768, tmp1)); + hAmrwb_IO->fmerit_m_sm_fx = add(shr(hAmrwb_IO->fmerit_m_sm_fx, 1), shr(fmerit_m, 1)); /*Q14 */ + fmerit_m = hAmrwb_IO->fmerit_m_sm_fx; + move16(); + + pt1 = til; + FOR( i = 0; i < NB_SUBFR; i++ ) + { + tmp = sub(pitch_var_cur, 320); + tmp = s_and(tmp, *pt1); + if (tmp < 0 ) + { + *pt1 = 1638; + move16(); + } + + tmp1 = sub(8192, *pt1); + *pt1 = s_max(6554, tmp1); + move16(); + tmp1 = add(hAmrwb_IO->ne_min_fx, 7680); /*Q8 */ + tmp1 = mult_r(tmp1, 7340); /*Q20 - > 0.007 //Q13 */ + *pt1 = add(*pt1, tmp1); + move16();/*Q13 */ + + L_tmp = L_mult0(*pt1, fmerit_m); /*Q13+14 */ + *pt1++ = extract_l(L_shr(L_tmp, 14)); /*Q13 */ + } + /* predict LPC coefficents and calculate sub-frame gains */ + p_Aq = Aq; + p_Ap = Ap; + pt1 = sub_gain; + pt2 = til0; + pt3 = til; + pt6 = voice_factors; + FOR( i = 0; i < NB_SUBFR; i++ ) + { + envelope_fx(hAmrwb_IO, core_brate, p_Aq, p_Ap, pt1, *pt2, *pt3, *pt6); + pt1++; + pt2++; + pt3++; + pt6++; + + p_Aq += (M+1); + p_Ap += (M+1); + } + + AdaptiveStartBand_fx( &start_band, core_brate, lsf_new, voice_fac, *amr_io_class, &hAmrwb_IO->voicing_flag_fx, &hAmrwb_IO->start_band_old_fx, &hAmrwb_IO->OptCrit_old_fx ); + + q_tmp = Exp16Array(L_FRAME, exc); + qdct = sub(q_tmp, 1); + Copy_Scale_sig_16_32(exc, exc32, L_FRAME, qdct); + + qdct = add(qdct, Q_exc); + edct_fx(exc32, dct_exc32, L_FRAME, &qdct); + q_tmp = Exp32Array(L_FRAME, dct_exc32); + + q_tmp = sub(q_tmp,16); + Copy_Scale_sig_32_16(dct_exc32, dct_exc, L_FRAME, q_tmp); + qdct = add(qdct, q_tmp); + + set16_fx( dct_hb, 0, L_FRAME16k); + pt1 = &dct_hb[200]; + pt2 = &dct_exc[200]; + FOR ( i = 200; i < 240; i++) + { + *pt1++ = *pt2++; + move16();/*qdct */ + } + set16_fx(signum, 1, L_SUBFR16k); + pt1 = dct_hb+240; + pt2 = dct_exc+start_band; + pt3 = signum; + FOR ( i = 240; i < L_FRAME16k; i++ ) + { + if (*pt2<0) + { + *pt3 = -1; + move16(); + } + *pt1++ = abs_s(*pt2++); + move16(); /*qdct */ + pt3++; + } + hb_ener = dot_prod_satcontr(&dct_hb[240], &dct_hb[240], qdct, qdct, &q1, L_SUBFR16k); + + L_tmp = L_shl(L_mult(start_band, 205), 14); /*Q30 */ + tmp = round_fx(L_tmp); /*Q14 */ + tmp = sub(18022, tmp); /*Q14 */ + fmerit_w = round_fx(L_shl(L_mult(fmerit_w, tmp), 1)); /*Q: 14+14+1+1-16 = 14 */ + + + L_tmp = L_deposit_l(fmerit_w); /*Q14 */ + L_tmp = Isqrt(L_tmp); /*Q(31-7) */ + tmp = round_fx(L_tmp); /*Q8 */ + q2 = norm_s(tmp); + alpha = div_s(shl(1, sub(14, q2)), tmp); /*Q(29-q2-8); */ + alpha = shl(alpha, sub(q2, 7));/*Q14 */ + + beta = sub(16384, fmerit_w); /*Q14 */ + + L_tmp = L_mult(alpha, 31130); /*Q30 */ + gamma = round_fx(L_tmp); /*Q14 */ + gamma = sub(17203, gamma); /*Q14 */ + gamma = s_min(16384, gamma); + gamma = s_max(4915, gamma); + + IF ( LT_16(beta, 16384)) + { + L_tmp = 1; /*variable for tonal energy*/ + + pt1 = hb_amb; + pt2 = hb_tonal; + pt3 = &dct_hb[240]; + FOR (i=0; i<8; i++) + { + fn = add(i,8); + tmp1 = div_s(1, fn); /*Q15 */ + tmp = 0; + move16(); + pt4 = &dct_hb[240]; + FOR (j=0; j 0 ) + { + L_tmp = L_mac0(L_tmp, shr(*pt2,1), shr(*pt2,1)); + } + pt1++; + pt2++; + pt3++; + } + FOR (; i < L_SUBFR16k-8; i++) + { + fb = sub(i,7); + fn = add(fb,15); + tmp = 0; + pt4 = &dct_hb[fb+240]; + FOR (j=fb; j 0 ) + { +#ifdef BASOP_NOGLOB + L_tmp = L_mac0_sat(L_tmp, shr(*pt2,1), shr(*pt2,1)); +#else + L_tmp = L_mac0(L_tmp, shr(*pt2,1), shr(*pt2,1)); +#endif + } + pt1++; + pt2++; + pt3++; + } + FOR (; i 0 ) + { +#ifdef BASOP_NOGLOB + L_tmp = L_mac0_sat(L_tmp, shr(*pt2,1), shr(*pt2,1)); /*2*qdct-2 */ +#else + L_tmp = L_mac0(L_tmp, shr(*pt2,1), shr(*pt2,1)); /*2*qdct-2 */ +#endif + } + pt1++; + pt2++; + pt3++; + } + + /*scaling of hb_ener is q1; tonal_ener0) + { + *pt1 = mult_r(*pt1,g); /*qdct */ move16(); + } +#ifdef BASOP_NOGLOB + * pt2 = round_fx_sat(L_shl_sat(L_mult(*pt2, inv_g), 3)); /*qdct */ + *pt3 = add_sat(*pt1, *pt2); +#else + * pt2 = round_fx(L_shl(L_mult(*pt2, inv_g), 3)); /*qdct */ + *pt3 = add(*pt1, *pt2); +#endif + move16(); + *pt3 = extract_l(L_mult0(*pt3, *pt4)); /*qdct */ + pt1++; + pt2++; + pt3++; + pt4++; + } + + ener = dot_prod_satcontr(&dct_hb[240], &dct_hb[240], qdct, qdct, &q2, L_SUBFR16k); + scale = div_s(shl(1, 14), hb_ener); /*Q(29-q1) */ + L_tmp = L_mult(ener, scale); /*30-q1+q2 */ + q2 = sub(q1, q2); /*30-q2 */ + scale = round_fx(Isqrt(L_shl(L_tmp, sub(q2, 24)))); /*Q12 */ +#ifdef BASOP_NOGLOB + scale = round_fx_sat(L_shl_sat(L_mult(scale, gamma),4)); /*Q15 */ +#else + scale = round_fx(L_shl(L_mult(scale, gamma),4)); /*Q15 */ +#endif + } + ELSE + { + scale = 32767; /*~1 in Q15 */ move16(); + } + + IF ( EQ_32(core_brate, ACELP_6k60)) + { + filt_weight_coeff = 60; + move16(); + rev_filt_weight_coeff = 555; + move16(); /* 1/(filt_weight_coeff-1) Q15 */ + } + ELSE IF ( EQ_32(core_brate, ACELP_8k85)) + { + filt_weight_coeff = 40; + move16(); + rev_filt_weight_coeff = 840; + move16(); + } + ELSE + { + filt_weight_coeff = 20; + move16(); + rev_filt_weight_coeff = 1725; + move16(); + } + + pt1 = filt_weight; + FOR ( i = 0; i < filt_weight_coeff; i++) + { + L_tmp = L_mult(-32735, rev_filt_weight_coeff); /*Q31 */ + L_tmp = L_shl(Mult_32_16(L_tmp, i), 14); /*Q16+14 */ + *pt1++ = add(round_fx(L_tmp), 16384); + move16();/*Q14 */ + } + + IF ( EQ_32(core_brate, ACELP_23k85)) + { + pt1 = dct_hb+240; + tmp = sub(filt_weight_coeff, 80); + pt3 = filt_weight+tmp; + FOR( i = 240; i < L_FRAME16k; i++ ) + { + *pt1 = mult_r(*pt1, scale); /*qdct */ move16(); + + IF ( GE_16(i, sub(L_FRAME16k, filt_weight_coeff))) + { + *pt1 = round_fx(L_shl(L_mult(*pt3, *pt1), 1)); /*qdct */ + } + pt1++; + pt3++; + } + pt1 = dct_hb+200; + pt6 = filt_hp_fx; + FOR( i = 200; i < 256; i++ ) + { + *pt1 = mult_r(*pt6++, *pt1); + move16(); /*qdct */ + pt1++; + } + pt1 = HF_corr_gain; + pt6 = hf_gain; + FOR ( i = 0; i < NB_SUBFR; i++) + { + tmp = *pt6++; + move16(); + *pt1++ = HP_gain_fx[tmp]; + move16(); + } + } + ELSE + { + pt1 = dct_hb+240; + tmp = sub(filt_weight_coeff, 80); + pt3 = filt_weight+tmp; + FOR( i = 240; i < L_FRAME16k; i++ ) + { + *pt1 = mult_r(*pt1, scale); /*qdct */ + IF ( GT_16(i, 255)) + { + *pt1 = mult_r(19505, *pt1); + move16(); + } + + IF ( GE_16(i, sub(L_FRAME16k, filt_weight_coeff))) + { + *pt1 = round_fx(L_shl(L_mult(*pt3, *pt1), 1)); /*qdct */ + } + pt1++; + pt3++; + } + + pt1 = dct_hb+200; + pt6 = filt_hp_fx; + pt7 = deem_tab_fx; + FOR( i = 200; i < 256; i++ ) + { + *pt1 = mult_r(*pt6++, *pt1); + move16();/*qdct */ + *pt1 = mult_r(*pt7++, *pt1); + move16(); + pt1++; + } + } + + q_tmp = Exp16Array(L_FRAME16k, dct_hb); + qhf = sub(q_tmp, 1); + Copy_Scale_sig_16_32(dct_hb, dct_hb32, L_FRAME16k, qhf); + qhf = add(qhf, qdct); + edct_fx(dct_hb32, exc16k32, L_FRAME16k, &qhf); + q_tmp = Exp32Array(L_FRAME16k, exc16k32); + q_tmp = sub(q_tmp,16); + Copy_Scale_sig_32_16(exc16k32, exc16k, L_FRAME16k, q_tmp); + qhf = add(qhf, q_tmp); + + ener = dot_prod_satcontr(exc, exc, Q_exc, Q_exc, &q1, L_FRAME); + tmp = dot_prod_satcontr(exc16k, exc16k, qhf, qhf, &q2, L_FRAME16k); + + pt6 = exc; + pt2 = exc16k; + + FOR ( i = 0; i < NB_SUBFR; i++ ) + { + e_subfr1 = dot_prod_satcontr(pt6, pt6, Q_exc, Q_exc, &q3, L_SUBFR); + e_subfr2 = dot_prod_satcontr(pt2, pt2, qhf, qhf, &q4, L_SUBFR16k); + + L_tmp = L_mult(e_subfr1, tmp); /*Q(q2+q3+1) */ + q3 = add(add(q2, q3), 1); + shift = norm_l(L_tmp); + L_tmp = L_shl(L_tmp, shift); /*Q(q3+shift); */ + q3 = add(q3, shift); +#ifdef BASOP_NOGLOB + scale = round_fx_sat(L_tmp); /*Q(q3-16); */ +#else + scale = round_fx(L_tmp); /*Q(q3-16); */ +#endif + q3 = sub(q3, 16); + scale = div_s(shl(1, 14), scale); /*Q(29-q3) */ + L_tmp = L_mult(scale, ener); /*Q(29-q3+q1+1) */ + shift = norm_l(L_tmp); + L_tmp = L_shl(L_tmp, shift); /*Q(29-q3+q1+1+shift) */ +#ifdef BASOP_NOGLOB + scale = round_fx_sat(L_tmp); /*Q(29-q3+q1+1+shift-16) */ +#else + scale = round_fx(L_tmp); /*Q(29-q3+q1+1+shift-16) */ +#endif + L_tmp = L_mult(scale, e_subfr2); /*Q(29-q3+q1+1+shift-16+q4+1)=Q(15+q1-q3+q4+shift) */ + q3 = sub(15, q3); + q3 = add(q3, q1); + q3 = add(q3, shift); + q3 = add(q3, q4); +#ifdef BASOP_NOGLOB + scale = round_fx_sat(Isqrt(L_shl_sat(L_tmp, sub(6, q3)))); /*Q12 */ +#else + scale = round_fx(Isqrt(L_shl(L_tmp, sub(6, q3)))); /*Q12 */ +#endif + pt6 += L_SUBFR; + FOR ( j = 0; j < L_SUBFR16k; j++ ) + { +#ifdef BASOP_NOGLOB + *pt2 = round_fx_sat(L_shl_sat(L_mult(*pt2, scale), 2)); /*qhf-1 */ +#else + *pt2 = round_fx(L_shl(L_mult(*pt2, scale), 2)); /*qhf-1 */ +#endif + pt2++; + } + } + qhf = sub(qhf, 1); + + p_Ap = Ap; + pt1 = exc16k; + pt2 = synth_out; + pt3 = sub_gain; + pt4 = HF_corr_gain; + pt5 = til0; + pt6 = voice_factors; + pt7 = exc; + + FOR( i = 0; i < NB_SUBFR; i++ ) + { + hf_synthesis_amr_wb_fx( core_brate, output_subfr, p_Ap, pt1, pt2, hBWE_zero->mem_syn_hf_fx, hBWE_zero->delay_syn_hf_fx, + hBWE_zero->mem_hp_interp_fx, *pt3, *pt4, *pt5, *pt6, pt7, Q_exc, Q_out, qhf); + p_Ap += (M+1); + pt1 += L_SUBFR16k; + pt2 += output_subfr; + pt3++; + pt4++; + pt5++; + pt6++; + pt7 += L_SUBFR; + } + + return; +} +static void hf_synthesis_amr_wb_fx( + const Word32 core_brate, /* i : core bitrate : Q0 */ + const Word16 output_subfr, /* i : output sub-frame length : Q0 */ + const Word16 Ap[], /* i : quantized Aq : Q12 */ + Word16 exc16k[], /* i : excitation at 16 kHz : Qhf */ + Word16 synth_out[], /* i/o: synthesis signal at output Fs : Qo */ + Word16 *mem_syn_hf, /* i/o: HF synthesis memory : Qo */ + Word16 *delay_syn_hf, /* i/o: HF synthesis memory : Qo */ + Word16 *mem_hp_interp, /* i/o: interpol. memory : Qo */ + Word16 p_r, /* i : sub-frame gain : Q12 */ + Word16 HF_corr_gain, /* i : HF gain index : Q14 */ + Word16 til, /*Q14*/ + Word16 voice_factors, /*Q14*/ + const Word16 exc[], /* i : excitation at 12.8 kHz : Qi */ + const Word16 Q_exc, /*exc scaling*/ + const Word16 Q_out, /*synth_out scaling*/ + Word16 qhf /*exc16k scaling*/ +) +{ + Word16 i; + Word16 HF_syn[L_SUBFR16k], upsampled_HF_syn[L_SUBFR48k]; + Word16 ener, tmp, scale, exc2385[L_SUBFR16k]; + Word32 L_tmp; + Word16 q1, q2,q3, shift; + Word16 *pt1, *pt2, flag; + IF ( EQ_32(core_brate, ACELP_23k85)) + { + ener = dot_prod_satcontr(exc, exc, Q_exc, Q_exc, &q1, L_SUBFR); + tmp = dot_prod_satcontr(exc16k, exc16k, qhf, qhf, &q2, L_SUBFR16k); + + L_tmp = L_mult(ener, 6554); /*Q(q1+16) */ + q3 = norm_l(L_tmp); + L_tmp = L_shl(L_tmp, q3); /*Q(q1+q3+16) */ + ener = extract_h(L_tmp); /*Q(q1+q3); */ + q1 = add(q1, q3); + + scale = div_s(shl(1, 14), ener); /*Q(29-q1) */ + L_tmp = L_mult(tmp, scale); /*30-q1+q2 */ + q2 = sub(q1, q2); /*30-q2 */ +#ifdef BASOP_NOGLOB + scale = round_fx_sat(Isqrt(L_shl_sat(L_tmp, sub(q2, 24)))); /*Q12 */ +#else + scale = round_fx(Isqrt(L_shl(L_tmp, sub(q2, 24)))); /*Q12 */ +#endif + pt1 = exc16k; + pt2 = exc2385; + FOR ( i = 0; i < L_SUBFR16k; i++ ) + { + L_tmp = L_mult(*pt1++, HF_corr_gain); /*qhf+15*/ + L_tmp = Mult_32_16(L_tmp, scale); /*qhf-1+12+1*/ + *pt2++ = round_fx(L_shl(L_tmp, 1)); /*qhf-3*/ + } + + pt1 = exc16k; + FOR ( i = 0; i < L_SUBFR16k; i++ ) + { + *pt1 = mult_r(*pt1, p_r); /*qhf-3*/ move16(); + pt1++; + } + + qhf = sub(qhf, 3); + + ener = dot_prod_satcontr(exc16k, exc16k, qhf, qhf, &q1, L_SUBFR16k); + tmp = dot_prod_satcontr(exc2385, exc2385, qhf, qhf, &q2, L_SUBFR16k); + L_tmp = L_mult(ener, 9830); /*Q(q1+16) */ + q3 = norm_l(L_tmp); + L_tmp = L_shl(L_tmp, q3); /*Q(q1+q3+16) */ + ener = extract_h(L_tmp); /*Q(q1+q3); */ + q1 = add(q1, q3); + + scale = div_s(shl(1, 14), ener); /*Q(29-q1) */ + L_tmp = L_mult(tmp, scale); /*30-q1+q2 */ + q2 = sub(q1, q2); /*30-q2 */ +#ifdef BASOP_NOGLOB + scale = round_fx_sat(Isqrt(L_shl_sat(L_tmp, sub(q2, 24)))); /*Q12 */ +#else + scale = round_fx(Isqrt(L_shl(L_tmp, sub(q2, 24)))); /*Q12 */ +#endif + flag = negate(s_and(til,-0x8000)); + if (GT_16(scale, 4096)) + { + flag = 1; + move16(); + } + IF ( flag ) + { + Copy( exc2385, exc16k, L_SUBFR16k ); + } + ELSE + { + pt1 = exc16k; + pt2 = exc2385; + FOR ( i = 0; i < L_SUBFR16k; i++ ) + { + tmp = sub(16348, shl(til, 1));/*Q14 */ + L_tmp = L_mult(tmp, sub(26214, shr(voice_factors, 1))); /*Q29*/ + tmp = round_fx(L_shr(L_tmp, 1)); /*Q12*/ + tmp = s_min(tmp, 4096); + tmp = s_max(tmp, scale); + *pt1++ = round_fx(L_shl(L_mult(*pt2++, tmp), 3))/*qhf*/; + } + } + + } + ELSE + { + pt1 = exc16k; + FOR ( i = 0; i < L_SUBFR16k; i++ ) + { + *pt1 = mult_r(*pt1, p_r); /*qhf-3*/ move16(); + pt1++; + } + + qhf = sub(qhf, 3); + } + + shift = sub(qhf, Q_out); + Syn_filt_s( shift, Ap, M, exc16k, HF_syn, L_SUBFR16k, mem_syn_hf, 1 ); /*Q_out=qhf-shift */ + + /*-----------------------------------------------------------------* + * Resample to output sampling rate + * Synchronize LB and HB components (delay componsation) + * Add synthesised high band to speech synthesis + *-----------------------------------------------------------------*/ + delay_signal(HF_syn, L_SUBFR16k, delay_syn_hf, NS2SA(16000, DELAY_CLDFB_NS)); + + IF( EQ_16(output_subfr, L_SUBFR48k)) /* 48kHz sampled output */ + { + Word16 s; + s = s_max(s_min(sub(s_min(Find_Max_Norm16(HF_syn, L_SUBFR16k), Find_Max_Norm16(mem_hp_interp, INTERP_3_1_MEM_LEN - 3)), 3), + sub(Find_Max_Norm16(mem_hp_interp + INTERP_3_1_MEM_LEN - 3, 3), 1)), 0 ); + Scale_sig( HF_syn, L_SUBFR16k, s ); + Scale_sig( mem_hp_interp, INTERP_3_1_MEM_LEN, s ); + + interpolate_3_over_1_allpass_fx( HF_syn, L_SUBFR16k, upsampled_HF_syn, mem_hp_interp); + + Scale_sig( upsampled_HF_syn, L_SUBFR48k, add(-s,-1) ); + Scale_sig( mem_hp_interp, INTERP_3_1_MEM_LEN, -s ); + Scale_sig( HF_syn, L_SUBFR16k, -s ); + } + ELSE IF( EQ_16(output_subfr, L_SUBFR32k)) /* 32kHz sampled output */ + { + Word16 s; + s = s_max( sub(s_min(Find_Max_Norm16(HF_syn, L_SUBFR16k), Find_Max_Norm16(mem_hp_interp, 2*ALLPASSSECTIONS_STEEP)),2), 0 ); + Scale_sig( HF_syn, L_SUBFR16k, s ); + Scale_sig( mem_hp_interp, 2*ALLPASSSECTIONS_STEEP, s ); + + Interpolate_allpass_steep_fx( HF_syn, mem_hp_interp, L_SUBFR16k, upsampled_HF_syn ); + + Scale_sig( upsampled_HF_syn, 2*L_SUBFR16k, -s ); + Scale_sig( mem_hp_interp, 2*ALLPASSSECTIONS_STEEP, -s ); + Scale_sig( HF_syn, L_SUBFR16k, -s ); + } + ELSE /* 16kHz sampled output */ + { + Copy( HF_syn, upsampled_HF_syn, L_SUBFR16k ); + } + + Vr_add( synth_out, upsampled_HF_syn, synth_out, output_subfr); + + return; +} + +static Word16 EnhanceClass_fx( + const Word16 qq_fx, + const Word16 pp_fx, + const Word16 tilt0_fx, /* i : spectrum tilt */ + const Word16 tilt_fx, /* i : spectrum tilt */ + const Word16 voice_factor_fx, /* i : voice factor */ + Word16 *voice_fac_fx, /* i/o: smoothed voiced parameter */ + Word16 *unvoicing_fx, /* i/o: unvoiced parameter */ + Word16 *unvoicing_sm_fx, /* i/o: smoothed unvoiced parameter */ + Word16 *unvoicing_flag /* i/o: unvoiced flag */ +) +{ + Word16 unvoicing_tmp_fx; + Word16 tmp, tmp1; + Word32 L_tmp; +#ifdef BASOP_NOGLOB + Flag Overflow; +#endif + + + /* Decide (*unvoicing_flag) to allow BWE enhancement when qq>pp */ + /**voice_fac_fx = add(mult_r(*voice_fac_fx, 24576), mult_r(voice_factor_fx, 8192)); //Q15 */ + *voice_fac_fx = round_fx(L_mac(L_mult(*voice_fac_fx, 24576), voice_factor_fx, 8192)); /*Q15 */ + + tmp = mult_r(sub(8192, tilt0_fx), 16384); /*Q13 */ + + L_tmp = L_sub(32768, *voice_fac_fx); /*Q15 */ + + L_tmp = Mult_32_16(L_tmp, tmp); /*Q13 */ + tmp = extract_l(L_tmp); /*Q13 */ + + tmp1 = mult_r(tilt_fx, 21845); /*Q15->1/1.5 ->Q13+15-15->Q13 */ + tmp1 = s_min(tmp1, 8192); + + L_tmp = L_mult(tmp, tmp1); /*Q13+Q13+1 */ + unvoicing_tmp_fx = extract_l(L_shr(L_tmp, 12)); /*Q15 */ + + /**unvoicing_fx = add(mult_r(16384, *unvoicing_fx), mult_r(16384, unvoicing_tmp_fx)); //Q15 */ + *unvoicing_fx = round_fx(L_mac(L_mult(16384, *unvoicing_fx), 16384, unvoicing_tmp_fx)); /*Q15 */ + + IF( GT_16(*unvoicing_sm_fx, *unvoicing_fx)) + { + /**unvoicing_sm_fx = add(mult_r(29491, *unvoicing_sm_fx), mult_r(3277, *unvoicing_fx)); //Q15 */ + *unvoicing_sm_fx = round_fx(L_mac(L_mult(29491, *unvoicing_sm_fx), 3277, *unvoicing_fx)); /*Q15 */ + } + ELSE + { + /**unvoicing_sm_fx = add(mult_r(32440, *unvoicing_sm_fx), mult_r(328, *unvoicing_fx)); //Q15 */ + *unvoicing_sm_fx = round_fx(L_mac(L_mult(32440, *unvoicing_sm_fx), 328, *unvoicing_fx)); /*Q15 */ + } + +#ifdef BASOP_NOGLOB + if (GT_16(sub_o(*unvoicing_fx, *unvoicing_sm_fx, &Overflow), 3277)) +#else + if ( GT_16(sub(*unvoicing_fx, *unvoicing_sm_fx),3277)) +#endif + { + *unvoicing_flag = 1; + } + +#ifdef BASOP_NOGLOB + if (LT_16(sub_o(*unvoicing_fx, *unvoicing_sm_fx, &Overflow), 1638)) +#else + if ( LT_16(sub(*unvoicing_fx, *unvoicing_sm_fx),1638)) +#endif + { + *unvoicing_flag = 0; + } + test(); + return ( *unvoicing_flag && GT_16(qq_fx, pp_fx) ); +} + +static void envelope_fx( + AMRWB_IO_DEC_HANDLE hAmrwb_IO, + const Word32 core_brate, /* i : core bitrate */ + const Word16 Aq_dyn_scal[], /* i : de-quant. LPC coefficents, dynamic scaling */ + Word16 Ap[], /* o : extended LPC coefficents, Q12 */ + Word16 *sub_gain, /* o : sub-frame gain, Q12 */ + Word16 tilt0, /* i : spectrum tilt, Q14 */ + Word16 tilt, /* i : spectrum tilt, Q13 */ + Word16 voice_factor /* i : voice factor, Q15 */ +) +{ + + Word16 px, py, rx, ry, pp, rr, qx, qy, qq; /*Q10*/ + Word16 i, Unvoicing_flag; + Word16 alpha; /*Q14*/ + Word16 est_level1, est_level2; /*Q10*/ + Word32 L_tmp; + Word16 tmp, q1, q2, q3, shift; + Word16 As[3], k1, k2; + Word16 *pt1; + const Word16 *pt2, *pt3; + Word16 Aq[M+1]; + + + /* Aq has dynamic scaling + go back to Q12 to make sure there's no overflow while calculating qx,qy*/ + shift = sub(norm_s(Aq_dyn_scal[0]),2); + Copy_Scale_sig(Aq_dyn_scal, Aq, M+1, shift); + + /* LPC envelope weighting */ + IF( EQ_32(core_brate,ACELP_6k60)) + { + weight_a_lc_fx( Aq, Ap, Gamma_29491_Tbl, M ); + } + ELSE + { + weight_a_lc_fx( Aq, Ap, Gamma_19661_Tbl_fx, M ); + } + /* Ap has dynamic scaling + go back to Q12 to make sure there's no overflow while calculating px,py*/ + shift = sub(norm_s(Ap[0]),2); + IF(shift != 0) + { + Scale_sig(Ap, M+1, shift); + } + + /* LPC envelope level estimate */ + L_tmp = L_deposit_l(0); + pt1 = Ap; + pt2 = exp_tab_p_fx; + FOR ( i = 0; i <= M; i++ ) + { + L_tmp = L_mac(L_tmp, *pt1++, *pt2++); + } + q1 = norm_l(L_tmp); + L_tmp = L_shl(L_tmp, q1);/*Q(27+q1)*/ + px = round_fx(L_shr(L_tmp, 1)); /*Q(10+q1)*/ + + L_tmp = L_deposit_l(0); + + pt1 = Ap; + pt2 = exp_tab_p_fx+33; + FOR ( i = 0; i <= M; i++ ) + { + L_tmp = L_mac(L_tmp, *pt1++, *pt2--); + } + q2 = norm_l(L_tmp); + shift = sub(q1, q2); + IF ( shift >= 0 ) + { + px = shr(px, shift); + L_tmp = L_shl(L_tmp, q2);/*Q(27+q2)*/ + q1 = q2; + move16(); + } + ELSE + { + L_tmp = L_shl(L_tmp, q1);/*Q(27+q1)*/ + } + py = round_fx(L_shr(L_tmp, 1)); /*Q(10+q1)*/ + + L_tmp = L_deposit_l(0); + pt2 = Aq; + pt3 = exp_tab_q_fx; + FOR ( i = 0; i <= M; i++ ) + { +#ifdef BASOP_NOGLOB + L_tmp = L_mac_sat(L_tmp, *pt2++, *pt3++); +#else + L_tmp = L_mac(L_tmp, *pt2++, *pt3++); +#endif + } + q2 = norm_l(L_tmp); + L_tmp = L_shl(L_tmp, q2);/*Q(27+q2)*/ + rx = round_fx(L_shr(L_tmp, 1)); /*Q(10+q2)*/ + + L_tmp = L_deposit_l(0); + pt2 = Aq; + pt3 = exp_tab_q_fx+33; + FOR ( i = 0; i <= M; i++ ) + { +#ifdef BASOP_NOGLOB + L_tmp = L_mac_sat(L_tmp, *pt2++, *pt3--); +#else + L_tmp = L_mac(L_tmp, *pt2++, *pt3--); +#endif + } + q3 = norm_l(L_tmp); + shift = sub(q2, q3); + IF ( shift >= 0 ) + { + rx = shr(rx, shift); + L_tmp = L_shl(L_tmp, q3);/*Q(27+q3)*/ + q2 = q3; + move16(); + } + ELSE + { + L_tmp = L_shl(L_tmp, q2);/*Q(27+q2)*/ + } + ry = round_fx(L_shr(L_tmp, 1)); /*Q(10+q2)*/ + + L_tmp = L_mult(px, px); + L_tmp = L_mac(L_tmp, py, py); /*Q(21+2*q1)*/ +#ifdef BASOP_NOGLOB + pp = round_fx_sat(Isqrt(L_shr(L_tmp, add(11, shl(q1, 1))))); /*Q10*/ +#else + pp = round_fx(Isqrt(L_shr(L_tmp, add(11, shl(q1, 1))))); /*Q10*/ +#endif + L_tmp = L_mult(rx, rx); + L_tmp = L_mac(L_tmp, ry, ry); /*Q(21+2*q1)*/ +#ifdef BASOP_NOGLOB + rr = round_fx_sat(Isqrt(L_shr(L_tmp, add(11, shl(q2, 1))))); /*Q10*/ +#else + rr = round_fx(Isqrt(L_shr(L_tmp, add(11, shl(q2, 1))))); /*Q10*/ +#endif + Copy(Aq, As, 3); + IF ( EQ_16(shr(As[2],1),-2048) ) + { + k2 = -2458; + move16(); + k1 = 4055; + move16(); + if (As[1]<0) + { + k1 = -k1; + move16(); + } + } + ELSE + { + k1 = add(2048, shr(As[2],1)); /*Q11 */ + q1 = 11; + move16(); + q2 = norm_s(k1); + k1 = (shl(k1, q2)); /*q1+q2 */ + tmp = abs_s(k1); + q1 = add(q1, q2); + tmp = div_s(shl(1, 14), tmp); /*Q(29-q1) */ + if ( k1 < 0 ) + { + tmp = negate(tmp); + move16(); + } + + L_tmp = L_mult(As[1], tmp); /*Q(42-q1) */ + q1 = sub(q1, 14); +#ifdef BASOP_NOGLOB + k1 = round_fx_sat(L_shl_sat(L_tmp, q1)); /*Q12 */ +#else + k1 = round_fx(L_shl(L_tmp, q1)); /*Q12 */ +#endif + k2 = As[2]; + move16(); /*Q12 */ + if ( GT_16(k2, 2458)) + { + k2 = 2458; + move16(); + } + if ( LT_16(k2, -2458) ) + { + k2 = -2458; + move16(); + } + if ( GT_16(k1, 4055)) + { + k1 = 4055; + move16(); + } + if ( LT_16(k1, -4055) ) + { + k1 = -4055; + move16(); + } + } + As[1] = add(4096, k2); + move16(); + L_tmp = L_mult(As[1], k1); /*Q25 */ + As[1] = round_fx(L_shl(L_tmp, 3)); /*Q12 */ + As[2] = k2; + move16(); /*Q12 */ + + L_tmp = L_deposit_l(0); + pt1 = As; + pt2 = exp_tab_q_fx; + FOR ( i = 0; i < 3; i++ ) + { + L_tmp = L_mac(L_tmp, *pt1++, *pt2++); + } + q1 = norm_l(L_tmp); + L_tmp = L_shl(L_tmp, q1);/*Q(27+q1)*/ + qx = round_fx(L_shr(L_tmp, 1)); /*Q(10+q1)*/ + + + L_tmp = L_deposit_l(0); + pt1 = As; + pt2 = exp_tab_q_fx+33; + FOR ( i = 0; i < 3; i++ ) + { + L_tmp = L_mac(L_tmp, *pt1++, *pt2--); + } + q2 = norm_l(L_tmp); + shift = sub(q1, q2); + IF ( shift >= 0 ) + { + qx = shr(qx, shift); + L_tmp = L_shl(L_tmp, q2);/*Q(27+q2)*/ + q1 = q2; + move16(); + } + ELSE + { + L_tmp = L_shl(L_tmp, q1);/*Q(27+q1)*/ + } + qy = round_fx(L_shr(L_tmp, 1)); /*Q(10+q1)*/ + + + L_tmp = L_mult(qx, qx); + L_tmp = L_mac(L_tmp, qy, qy); + qq = round_fx(Isqrt(L_shr(L_tmp, add(11, shl(q1, 1))))); /*Q10*/ + + Unvoicing_flag = EnhanceClass_fx( rr, pp, tilt0, tilt, voice_factor, &hAmrwb_IO->voice_fac_amr_wb_hf, &hAmrwb_IO->unvoicing_fx, &hAmrwb_IO->unvoicing_sm_fx, &hAmrwb_IO->unvoicing_flag_fx ); + alpha = 0; + move16(); + IF ( Unvoicing_flag ) + { + IF ( GT_16(rr, (hAmrwb_IO->prev_r_fx))) + { +#ifdef BASOP_NOGLOB + rr = shr(add_sat(rr, (hAmrwb_IO->prev_r_fx)), 1); +#else + rr = shr(add(rr, (hAmrwb_IO->prev_r_fx)), 1); +#endif + } + + hAmrwb_IO->prev_r_fx = rr; + move16(); + + L_tmp = L_mult(tilt, sub(26214, shr(voice_factor, 1))); /*Q28*/ + + L_tmp = L_min(L_tmp, 268435456); + + L_tmp = Mult_32_16(L_tmp, rr); /*Q23*/ + rr = round_fx(L_shl(L_tmp, 3)); /*Q10*/ + L_tmp = L_mult(tilt, sub(26214, shr(voice_factor, 1))); /*Q28*/ + L_tmp = L_max(L_tmp, 268435456); + L_tmp = Mult_32_16(L_tmp, qq); /*Q23*/ +#ifdef BASOP_NOGLOB + qq = round_fx_sat(L_shl_sat(L_tmp, 3)); /*Q10*/ +#else + qq = round_fx(L_shl(L_tmp, 3)); /*Q10*/ +#endif + rr = s_min(rr, qq); + rr= s_max(rr, pp); + } + ELSE + { + test(); + IF ( LT_16(rr, 1024)&<_16((hAmrwb_IO->prev_r_fx),1024)) + { + L_tmp = L_mult(rr, rr); /*Q21*/ + tmp = round_fx(L_shl(L_tmp, 9)); /*Q14*/ + L_tmp = L_sub(2097152, L_tmp); /*Q21*/ + alpha = round_fx(L_shl(L_tmp, 9)); /*Q14*/ + L_tmp = L_mult(alpha, (hAmrwb_IO->prev_r_fx)); /*Q25*/ + L_tmp = L_mac(L_tmp, tmp, rr); /*Q25*/ +#ifdef BASOP_NOGLOB + rr = round_fx_sat(L_shl_sat(L_tmp, 1)); /*Q10*/ +#else + rr = round_fx(L_shl(L_tmp, 1)); /*Q10*/ +#endif + } + + hAmrwb_IO->prev_r_fx = rr; + move16(); + + L_tmp = L_mult(tilt, sub(26214, shr(voice_factor, 1))); /*Q28*/ + + L_tmp = L_min(L_tmp, 268435456); + L_tmp = Mult_32_16(L_tmp, qq); /*Q23*/ + est_level1 = round_fx(L_shl(L_tmp, 3)); /*Q10*/ + + tmp = pp; + move16(); + tmp = s_min(tmp, qq); + rr = s_min(tmp, rr); + + L_tmp = L_mult(abs_s(sub(tilt, 8192)), sub(26214, shr(voice_factor, 1))); /*Q28*/ + L_tmp = L_add(L_tmp, 268435456); + L_tmp = Mult_32_16(L_tmp, rr); /*Q23*/ + est_level2 = round_fx(L_shl(L_tmp, 3)); /*Q10*/ + + rr = s_min(est_level1, est_level2); + } + + + q1 = norm_s(pp); + tmp = div_s(shl(1, sub(14, q1)), pp); /*Q(29-q1-10) */ + L_tmp = L_mult(rr, tmp);/*Q(30-q1-10+10) */ + +#ifdef BASOP_NOGLOB + *sub_gain = s_min(20480,round_fx_sat(L_shl_sat(L_tmp, sub(q1, 2)))); /*Q12 */ +#else + *sub_gain = s_min(20480,round_fx(L_shl(L_tmp, sub(q1, 2)))); /*Q12 */ +#endif + return; + +} + +/*---------------------------------------------------------------------* + * AdaptiveStartBand_fx() + * + * adaptively select the start band of bandwidth extension + *---------------------------------------------------------------------*/ + +void AdaptiveStartBand_fx( + Word16 *start_band, /* o : start point of copied band */ + const Word32 core_rate, /* i : core bitrate */ + const Word16 *lsf_fx, /* i : Q2 lsf frequency */ + const Word16 voicing_fac_fx, /* i : Q14 voicing factors */ + const Word16 clas, /* i : signal class (determined by FEC algorithm)*/ + Word16 *voicing_flag, + Word16 *start_band_old, + Word32 *OptCrit_old_fx /*i/o : Q15 */ +) +{ + Word16 i, pos, M2, voicing_flag_old; + Word16 lsf_diff_fx[M]; + Word16 W_fx; + Word16 tmp1, tmp2; + Word32 L_tmp; + Word32 OptCrit_fx = 32768, Crit_fx; + Word16 *pt1, flag; + const Word16 *pt2, *pt3; + + /*voicing switching flag : to avoid switching start band frequently in VOICED or AUDIO area*/ + voicing_flag_old = *voicing_flag; + test(); + test(); + test(); + if( GT_16(voicing_fac_fx, 6554)||(GT_16(voicing_fac_fx,4915)&&GE_16(clas,VOICED_CLAS))||EQ_16(clas,AUDIO_CLAS)) + { + *voicing_flag = 1; + move16(); + } + + test(); + if( LT_16(voicing_fac_fx, 3277)&<_16(clas,VOICED_CLAS)) + { + *voicing_flag = 0; + move16(); + } + + /* core_rate adaptive start band */ + *start_band = 160; + move16(); + IF( LT_32(core_rate, ACELP_23k05)) + { + pt1 = lsf_diff_fx+1; + pt2 = lsf_fx+1; + pt3 = lsf_fx; + FOR(i=1; i<(M-1); i++) + { + *pt1++ = sub(*pt2++, *pt3++); + move16();/*Q2 */ + } + tmp1 = extract_l(Mult_32_16(core_rate, 27046)); /*Q14 */ + L_tmp = L_shr(L_mult0(tmp1, 22370), 15); /*Q27->1/6000 ->Q26 */ + tmp2 = extract_l(L_tmp); /*Q26 */ + W_fx = mult_r(tmp1, tmp2); /*Q25 */ + + if (EQ_16(clas,AUDIO_CLAS)) + { + W_fx = mult_r(W_fx, 24576); /*Q25 */ + } + + pos = 2; + move16(); + M2 = sub(M, 2); + IF( EQ_16(*voicing_flag,1)) + { + IF( LE_32(core_rate, ACELP_8k85)) + { + M2 = sub(M, 8); + } + ELSE IF( LE_32(core_rate, ACELP_12k65)) + { + M2 = sub(M, 6); + } + ELSE IF( LE_32(core_rate, ACELP_15k85)) + { + M2 = sub(M, 4); + } + } + + /*do the procedure for i==2*/ + L_tmp = L_max(L_msu(171798692, lsf_fx[2], W_fx), 171799); /* Q2.56+25+1 */ + Crit_fx = Mult_32_16(L_tmp, lsf_diff_fx[2]); /* Q2.56+25+1+2.56-15 = Q11+2.56+2.56 */ + + OptCrit_fx = L_add(Crit_fx, 0); + pos = 2; + move16(); + /*----------------------------------------------------------------*/ + + pt2 = &lsf_fx[3]; + pt1 = &lsf_diff_fx[3]; + FOR(i=3; i 0 ) ) + { + *OptCrit_old_fx = OptCrit_fx; + move16(); + test(); + test(); + if ( LT_16(abs_s(sub((*start_band),(*start_band_old))), 20)&&EQ_16(*voicing_flag,1)&&EQ_16(voicing_flag_old,1)) + { + *start_band = *start_band_old; + move16(); + } + } + ELSE + { + test(); + if (LT_32(OptCrit_fx, (*OptCrit_old_fx))&&EQ_16((*voicing_flag),1)) + { + *OptCrit_old_fx = OptCrit_fx; + move16(); + } + + *start_band = *start_band_old; + move16(); + } + + if (EQ_16(clas,AUDIO_CLAS)) + { + *start_band = s_min(*start_band, 120); + move16(); + } + + flag = sub(s_and(*start_band, 0x0001),1); + if (flag == 0) + { + *start_band = sub(*start_band, 1); + move16(); + } + } + + *start_band_old = *start_band; + move16(); + + return; +} + diff --git a/lib_dec/hq_classifier_dec_fx.c b/lib_dec/hq_classifier_dec_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..893e613d0daa3b468d84fe85434430822643be0e --- /dev/null +++ b/lib_dec/hq_classifier_dec_fx.c @@ -0,0 +1,88 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ +#include +#include "options.h" /* Compilation switches */ +#include "prot_fx1.h" /* Function prototypes */ +#include "prot_fx2.h" /* Function prototypes */ + +/*--------------------------------------------------------------------------* + * hq_classifier_dec() + * + * HQ mode selector (decision_matrix) + *--------------------------------------------------------------------------*/ + +Word16 hq_classifier_dec_fx( /* o : Consumed bits Q0 */ + Decoder_State *st_fx, /* i/o: decoder state structure */ + const Word32 core_brate, /* i : Core bit rate Q0 */ + const Word16 length, /* i : Frame length Q0 */ + Word16 *is_transient, /* o : Transient flag Q0 */ + Word16 *hqswb_clas /* o : HQ class Q0 */ +) +{ + Word16 bits; + Word32 max_brate; + + max_brate = HQ_32k; + move32(); + if (GT_16(st_fx->element_mode, EVS_MONO)) + { + max_brate = HQ_48k; + move32(); + } +#ifndef SOLVED_COMP_ENC_DEC + IF((EQ_16(length, L_SPEC32k) || EQ_16(length, L_FRAME48k)) && LE_32(core_brate, max_brate)) +#else + /*_DIFF_FLOAT_FIX_ -> could this modification break the interoperability with EVS ?? */ + test(); + IF ((EQ_16(length, L_SPEC32k) || EQ_16(length, L_SPEC48k)) && LE_32(core_brate, max_brate)) +#endif + { + *hqswb_clas = get_next_indice( st_fx, 2 ); + bits = 2; + move16(); + } + ELSE IF( EQ_16(length, L_SPEC16k_EXT) || EQ_16(length, L_SPEC48k_EXT) ) + { + *hqswb_clas = HQ_NORMAL; + bits = 0; + move16(); move16(); + } + ELSE + { + *hqswb_clas = get_next_indice( st_fx, 1 ); + bits = 1; + move16(); + } + + *is_transient = 0; + move16(); + if ( EQ_16(*hqswb_clas, HQ_TRANSIENT)) + { + *is_transient = 1; + move16(); + } + + test(); + IF (LE_32(st_fx->core_brate, HQ_32k) && EQ_16(*hqswb_clas, HQ_NORMAL)) + { + move16(); + IF (EQ_16(length, L_SPEC32k) ) + { + *hqswb_clas = HQ_GEN_SWB; + move16(); + } +#ifndef SOLVED_COMP_ENC_DEC + ELSE IF (EQ_16(length, L_FRAME48k)) +#else + ELSE IF (EQ_16(length, L_SPEC48k)) +#endif + { + *hqswb_clas = HQ_GEN_FB; + move16(); + } + } + + return bits; +} + diff --git a/lib_dec/hq_conf_fec_fx.c b/lib_dec/hq_conf_fec_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..31c13c2549426d82474a0a79c0eb3e57446a97f4 --- /dev/null +++ b/lib_dec/hq_conf_fec_fx.c @@ -0,0 +1,39 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include +#include "options.h" +#include "rom_com.h" /* Static table prototypes */ +#include "prot_fx1.h" +#include "prot_fx2.h" +#include "cnst.h" + + +/*--------------------------------------------------------------------------* + * hq_configure_bfi_fx() + * + * Initialization of HQ bands and subframes + *--------------------------------------------------------------------------*/ +void hq_configure_bfi_fx( + Word16 *nb_sfm, /* o : Number of sub bands Q0 */ + Word16 *num_Sb, /* o : Number of FEC sub bands ? Q0 */ + Word16 *num_bands_p, /* o : FEC sub bands Q0 */ + const Word16 **sfmsize, /* o : Subband bandwidths */ + const Word16 **sfm_start, /* o : Subband start coefficients */ + const Word16 **sfm_end /* o : Subband end coefficients */ +) +{ + *num_Sb = MAX_SB_NB; + move16(); + *nb_sfm = SFM_N_NB; + move16(); + Copy( Num_bands_NB, num_bands_p, *num_Sb ); + *sfmsize = band_len_wb; + *sfm_start = band_start_wb; + *sfm_end = band_end_wb; + move16(); + move16(); + move16(); + return; +} diff --git a/lib_dec/hq_core_dec.c b/lib_dec/hq_core_dec.c index 749e7f23fa673511375bef4ac003b04c869de3d8..95375b02160a7db33565f482229fe780ffdab019 100644 --- a/lib_dec/hq_core_dec.c +++ b/lib_dec/hq_core_dec.c @@ -345,14 +345,14 @@ void hq_core_dec( /* LB synthesis */ - IMDCT( t_audio_q, hTcxDec->syn_Overl_float, hTcxDec->syn_Overl_TDAC_float, wtda_audio, tcx_cfg->tcx_aldo_window_1_trunc_flt, tcx_cfg->tcx_aldo_window_2_flt, tcx_cfg->tcx_mdct_window_half_flt, tcx_cfg->tcx_mdct_window_minimum_flt, tcx_cfg->tcx_mdct_window_trans_flt, tcx_cfg->tcx_mdct_window_half_length, tcx_cfg->tcx_mdct_window_min_length, index, + IMDCT_flt( t_audio_q, hTcxDec->syn_Overl_float, hTcxDec->syn_Overl_TDAC_float, wtda_audio, tcx_cfg->tcx_aldo_window_1_trunc_flt, tcx_cfg->tcx_aldo_window_2_flt, tcx_cfg->tcx_mdct_window_half_flt, tcx_cfg->tcx_mdct_window_minimum_flt, tcx_cfg->tcx_mdct_window_trans_flt, tcx_cfg->tcx_mdct_window_half_length, tcx_cfg->tcx_mdct_window_min_length, index, MDCT_IV, left_rect, tcx_offset, overlap, L_frame, L_frameTCX, max( L_frameTCX, L_spec ) >> 1, L_frame_glob, 0, st->bfi, hHQ_core->old_outLB, 0, st, 0, acelp_zir ); mvr2r( wtda_audio + ( overlap >> 1 ) - tcx_offset, output, L_frame_glob ); /* FB synthesis */ - IMDCT( t_audio_q, hTcxDec->syn_OverlFB_float, hTcxDec->syn_Overl_TDACFB_float, wtda_audio, tcx_cfg->tcx_aldo_window_1_FB_trunc_flt, tcx_cfg->tcx_aldo_window_2_FB_flt, tcx_cfg->tcx_mdct_window_halfFB_flt, tcx_cfg->tcx_mdct_window_minimumFB_flt, tcx_cfg->tcx_mdct_window_transFB_flt, tcx_cfg->tcx_mdct_window_half_lengthFB, tcx_cfg->tcx_mdct_window_min_lengthFB, index, + IMDCT_flt( t_audio_q, hTcxDec->syn_OverlFB_float, hTcxDec->syn_Overl_TDACFB_float, wtda_audio, tcx_cfg->tcx_aldo_window_1_FB_trunc_flt, tcx_cfg->tcx_aldo_window_2_FB_flt, tcx_cfg->tcx_mdct_window_halfFB_flt, tcx_cfg->tcx_mdct_window_minimumFB_flt, tcx_cfg->tcx_mdct_window_transFB_flt, tcx_cfg->tcx_mdct_window_half_lengthFB, tcx_cfg->tcx_mdct_window_min_lengthFB, index, MDCT_IV, left_rect, tcx_offsetFB, overlapFB, L_frameTCX, L_frameTCX, max( L_frameTCX, L_spec ) >> 1, L_frameTCX_glob, 0, st->bfi, hHQ_core->old_out, 1, st, FSCALE_DENOM * L_frameTCX_glob / L_frame_glob, acelp_zir ); mvr2r( wtda_audio + ( overlapFB >> 1 ) - tcx_offsetFB, synth, L_frameTCX_glob ); @@ -505,7 +505,7 @@ void hq_core_dec( * Initialize HQ core state structure *-------------------------------------------------------------------*/ -void HQ_core_dec_init( +void HQ_core_dec_init_flt( HQ_DEC_HANDLE hHQ_core /* i/o: HQ core data handle */ ) { @@ -579,12 +579,12 @@ void HQ_core_dec_init( } /*-------------------------------------------------------------------* - * HQ_nbfec_init() + * HQ_nbfec_init_flt() * * Initialize HQ NB FEC state structure *-------------------------------------------------------------------*/ -void HQ_nbfec_init( +void HQ_nbfec_init_flt( HQ_NBFEC_HANDLE hHQ_nbfec /* i/o: HQ NB FEC data handle */ ) { diff --git a/lib_dec/hq_core_dec_fx.c b/lib_dec/hq_core_dec_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..f8eb4a25df5185d7591af5e64b740358f8020f32 --- /dev/null +++ b/lib_dec/hq_core_dec_fx.c @@ -0,0 +1,723 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ +#include +#include "options.h" /* Compilation switches */ +#include "cnst.h" /* Common constants */ +#include "prot_fx1.h" /* Function prototypes */ +#include "prot_fx2.h" /* Function prototypes */ +#include "rom_com.h" /* Static table prototypes */ +/*-------------------------------------------------------------------------- + * hq_core_dec() + * + * HQ core decoder + *--------------------------------------------------------------------------*/ + +void hq_core_dec_fx( + Decoder_State *st_fx, /* i/o: decoder state structure fx */ + Word16 synth[], /* o : output synthesis */ + Word16 *Q_synth, /* o : Q value of synth */ + const Word16 output_frame, /* i : output frame length */ + const Word16 hq_core_type, /* i : HQ core type */ + const Word16 core_switching_flag /* i : ACELP->HQ switching frame flag */ +) +{ + Word16 num_bits, is_transient, hqswb_clas, inner_frame; + Word16 i, j, flag_uv, num_Sb, nb_sfm; + Word16 ynrm[NB_SFM], num_bands_p[MAX_SB_NB]; + Word16 ener_match; /* Q13 */ + Word32 t_audio_q[L_FRAME48k_EXT]; /* Q12 */ + Word16 Q_audio; + Word32 wtda_audio[2*L_FRAME48k]; + Word16 delay_comp; + Word32 normq_fx[NB_SFM]; + Word16 mean_en_high_fx; + Word16 SWB_fenv_fx[SWB_FENV+DIM_FB]; + const Word16 *sfmsize, *sfm_start, *sfm_end; + Word16 gapsynth_fx[L_FRAME48k]; + Word16 tmp, tmp_loop; + Word32 L_tmp; + UWord16 lsb; + Word16 L_spec; + HQ_NBFEC_HANDLE hHQ_nbfec; + HQ_DEC_HANDLE hHQ_core; + hHQ_nbfec = st_fx->hHQ_nbfec; + hHQ_core = st_fx->hHQ_core; + + /*-------------------------------------------------------------------------- + * Initializations + *--------------------------------------------------------------------------*/ + + set32_fx( t_audio_q, 0, L_FRAME48k_EXT); + set16_fx( gapsynth_fx, 0, L_FRAME48k ); + set16_fx( num_bands_p, 0, MAX_SB_NB ); + set16_fx( ynrm, 39, NB_SFM ); /* Initialize to the smallest value */ + mean_en_high_fx = 0; + move16(); + Q_audio = 12; + move16(); + sfm_start = sfm_end = NULL; + num_Sb = nb_sfm = 0; + + st_fx->hTcxCfg->tcx_last_overlap_mode = st_fx->hTcxCfg->tcx_curr_overlap_mode; + move16(); + if (EQ_16(st_fx->hTcxCfg->tcx_curr_overlap_mode, FULL_OVERLAP)) + { + st_fx->hTcxCfg->tcx_last_overlap_mode = ALDO_WINDOW; + move16(); + } + st_fx->hTcxCfg->tcx_curr_overlap_mode = ALDO_WINDOW; + move16(); + /*-------------------------------------------------------------------------- + * Find the number of bits for transform-domain coding + *--------------------------------------------------------------------------*/ + + /* set the total bit-budget */ + /*num_bits = (short)(st->total_brate / 50); */ + Mpy_32_16_ss(st_fx->total_brate, 5243, &L_tmp, &lsb); /* 5243 is 1/50 in Q18. (0+18-15=3) */ + num_bits = extract_l(L_shr(L_tmp, 3)); /*Q0 */ + +#ifdef ADD_IVAS_HQ_CODE_L_SPEC + /* Set default spectrum length */ + L_spec = l_spec_tbl[st_fx->bwidth]; +#endif + IF( !st_fx->bfi ) + { + IF ( EQ_16(core_switching_flag, 1)) + { +#ifdef ADD_IVAS_HQ_CODE_L_SPEC + IF (NE_16(st_fx->element_mode, EVS_MONO)) + { + L_spec = l_spec_ext_tbl[st_fx->bwidth]; + } + ELSE +#endif + { + core_switching_hq_prepare_dec_fx(st_fx, &num_bits, output_frame); + + /* During ACELP->HQ core switching, limit the HQ core bitrate to 48kbps */ + if (GT_16(num_bits, HQ_48k / 50)) + { + num_bits = (Word16)(HQ_48k / 50); + move16(); + } + } + } +#ifdef ADD_IVAS_HQ_CODE + IF (hq_recovery_flag) + { + acelp_plc_mdct_transition(st); + } +#endif + /* subtract signalling bits */ + num_bits = sub(num_bits, st_fx->next_bit_pos); + + /* set FEC parameters */ + flag_uv = sub(1, hHQ_core->HqVoicing_fx); + + /* subtract the number of bits for pitch & gain at higher bitrates */ + test(); + IF ( !(core_switching_flag) && GT_32(st_fx->core_brate, MINIMUM_RATE_TO_ENCODE_VOICING_FLAG)) + { + hHQ_core->HqVoicing_fx = get_next_indice( st_fx, 1 ); + num_bits = sub(num_bits, 1); + } + ELSE + { + hHQ_core->HqVoicing_fx = 0; + move16(); + if ( GT_32(st_fx->core_brate, MINIMUM_RATE_TO_ENCODE_VOICING_FLAG)) + { + hHQ_core->HqVoicing_fx = 1; + move16(); + } + } + } + ELSE + { + flag_uv = 0; + move16(); + } + + /* set inner frame (== coded bandwidth) length */ + inner_frame = inner_frame_tbl[st_fx->bwidth]; +#ifndef ADD_IVAS_HQ_CODE_L_SPEC + L_spec = inner_frame; +#endif + move16(); + + IF ( st_fx->bfi == 0) + { + hHQ_core->ph_ecu_HqVoicing_fx = 0; + move16(); + if ( GE_16(output_frame, L_FRAME16k)) + { + hHQ_core->ph_ecu_HqVoicing_fx = hHQ_core->HqVoicing_fx; + move16(); + } + } + + IF ( EQ_16(output_frame, L_FRAME8k)) + { + hq_configure_bfi_fx( &nb_sfm, &num_Sb, num_bands_p, &sfmsize, &sfm_start, &sfm_end ); + } + + /*-------------------------------------------------------------------------- + * transform-domain decoding + *--------------------------------------------------------------------------*/ + + IF( EQ_16(st_fx->bfi, 1)) + { + is_transient = hHQ_core->old_is_transient_fx[0]; + move16(); + IF ( GE_16(output_frame, L_FRAME16k)) /* Apply phase ecu for WB, SWB and FB */ + { + /* ecu_rec sent to OLA, env_stab passed in ph_ecu_st */ + hq_ecu_fx( st_fx->hTcxDec->prev_good_synth_fx, t_audio_q, &hHQ_core->time_offs_fx, hHQ_core->X_sav_fx, &hHQ_core->Q_X_sav, &hHQ_core->num_p_fx, hHQ_core->plocs_fx, hHQ_core->plocsi_fx, hHQ_core->env_stab_fx, + &hHQ_core->last_fec_fx, hHQ_core->ph_ecu_HqVoicing_fx, &hHQ_core->ph_ecu_active_fx, gapsynth_fx, st_fx->prev_bfi, hHQ_core->old_is_transient_fx, hHQ_core->mag_chg_1st_fx, + hHQ_core->Xavg_fx, &hHQ_core->beta_mute_fx, output_frame, st_fx ); + } + ELSE + { + HQ_FEC_processing_fx( st_fx, t_audio_q, is_transient, hHQ_nbfec->ynrm_values_fx, hHQ_nbfec->r_p_values_fx, num_Sb, nb_sfm, num_bands_p, + output_frame, sfm_start, sfm_end ); + } + + hHQ_core->old_is_transient_fx[2] = hHQ_core->old_is_transient_fx[1]; + move16(); + hHQ_core->old_is_transient_fx[1] = hHQ_core->old_is_transient_fx[0]; + move16(); + + IF ( GE_16(output_frame, L_FRAME16k)) + { + /* keep st->previoussynth updated as in FEC_HQ_pitch_analysis but no LP analysis */ + delay_comp = NS2SA_fx2(st_fx->output_Fs, DELAY_CLDFB_NS); + + Copy( st_fx->previoussynth_fx + delay_comp, st_fx->previoussynth_fx, sub(output_frame, delay_comp) ); + Copy( st_fx->delay_buf_out_fx, st_fx->previoussynth_fx + output_frame - delay_comp, delay_comp ); + + flag_uv = 1; + move16(); /* disable costly pitch out synthesis in bfi frame */ + hHQ_core->HqVoicing_fx = sub(1, flag_uv); /* safety setting for HQ->ACELP switch logic */ + set16_fx(hHQ_core->fer_samples_fx, 0, L_FRAME48k ); /* safety, create a known signal state for HQ->ACELP switch logic */ + } + } + ELSE + { + IF( EQ_16(hq_core_type, LOW_RATE_HQ_CORE)) + { + IF( EQ_16(st_fx->prev_bfi, 1)) + { + set32_fx(hHQ_core->last_ni_gain_fx, 0, BANDS_MAX ); + set16_fx(hHQ_core->last_env_fx, 0, BANDS_MAX ); + hHQ_core->last_max_pos_pulse_fx = 0; + move16(); + } + + /* HQ low rate decoder */ + hq_lr_dec_fx(st_fx, t_audio_q, inner_frame, num_bits, &is_transient); + hqswb_clas = is_transient; + move16(); + Q_audio = 12; + move16(); + } + ELSE + { + /* HQ high rate decoder */ + hq_hr_dec_fx(st_fx, t_audio_q, L_spec, num_bits, ynrm, &is_transient, &hqswb_clas, SWB_fenv_fx, core_switching_flag); + Q_audio = 12; + move16(); + } + +#ifdef ADD_IVAS_HQ_CODE + test(); test(); test(); + IF (EQ_16(st_fx->element_mode, EVS_MONO) || (!core_switching_flag && !hq_recovery_flag)) +#endif + { + /* scaling (coefficients are in nominal level) */ + IF(NE_16(output_frame, NORM_MDCT_FACTOR)) + { + IF(EQ_16(output_frame, L_FRAME32k)) + { + Q_audio = sub(Q_audio, 1); /* Multiply by 2 */ + } + ELSE + { + tmp = mult_r(output_frame, 410 / 2); /* 1/8000 in Q15 */ + ener_match = hq_nominal_scaling_inv[tmp]; + FOR(i = 0; i < inner_frame; i++) + { + /*t_audio_q[i] *= ener_match;*/ + Mpy_32_16_ss(t_audio_q[i], ener_match, &L_tmp, &lsb); /*12+13-15=10 */ +#ifdef BASOP_NOGLOB + t_audio_q[i] = L_add_sat(L_shl_sat(L_tmp, 2), lshr(lsb, 14)); +#else + t_audio_q[i] = L_add(L_shl(L_tmp, 2), lshr(lsb, 14)); +#endif + move16(); /* Q12 */ + } + } + } + } + HQ_FEC_Mem_update_fx( st_fx, t_audio_q, normq_fx, ynrm, num_bands_p, is_transient, hqswb_clas, + core_switching_flag, nb_sfm, num_Sb, &mean_en_high_fx, hq_core_type, output_frame ); + } + /*-------------------------------------------------------------------------- + * Attenuate HFs in case of band-width switching (from higher BW to lower BW) + *--------------------------------------------------------------------------*/ + /* attenuate HFs in case of band-width switching */ + IF( st_fx->bws_cnt1_fx > 0 ) + { + IF( EQ_16(st_fx->bws_cnt1_fx,N_NS2W_FRAMES)) + { + ener_match = 32767; + move16(); /*Q15*/ + } + ELSE + { + ener_match = div_s(st_fx->bws_cnt1_fx,N_NS2W_FRAMES); /*Q15*/ + } + + IF( is_transient ) + { + FOR( i = 0; i < NUM_TIME_SWITCHING_BLOCKS; i++ ) + { + tmp_loop = mult(inner_frame,8192); + FOR( j=mult(inner_frame_tbl[sub(st_fx->bwidth,1)],8192); jbwidth,1)]; it_audio_q_fx, 80, -13); + } + ELSE + { + Copy_Scale_sig_32_16(t_audio_q, st_fx->t_audio_q_fx, L_FRAME, -13); + } + + + /*-------------------------------------------------------------------------- + * Inverse transform + * Overlap-add + * Pre-echo reduction + *--------------------------------------------------------------------------*/ +#ifdef ADD_IVAS_HQ_CODE + if (st->element_mode > EVS_MONO && (core_switching_flag || hq_recovery_flag)) + { + /* Initializations for TCX MDCT framework, to be used for switching frame */ + tcx_cfg = st->hTcxCfg; + L_frameTCX_glob = hTcxDec->L_frameTCX; + L_frame_glob = st->L_frame; + L_spec = hTcxDec->L_frameTCX; + st->fscale = sr2fscale(st->sr_core); + fscaleFB = sr2fscale(st->output_Fs); + encoderLookahead = (L_LOOK_12k8 * st->fscale) / FSCALE_DENOM; + encoderLookaheadFB = (L_LOOK_12k8 * fscaleFB) / FSCALE_DENOM; + mdctWindowLength = getMdctWindowLength(st->fscale); + mdctWindowLengthFB = (int16_t)(mdctWindowLength * st->output_Fs / st->sr_core); + if (core_switching_flag) + { + tcx_cfg->tcx_last_overlap_mode = TRANSITION_OVERLAP; + tcx_cfg->tcx_curr_overlap_mode = FULL_OVERLAP; + } + else + { + tcx_cfg->tcx_last_overlap_mode = ALDO_WINDOW; + tcx_cfg->tcx_curr_overlap_mode = ALDO_WINDOW; + st->last_core = HQ_CORE; /* Needed to decode non-transition frame */ + } + + init_tcx_window_cfg(tcx_cfg, st->sr_core, st->output_Fs, st->L_frame, hTcxDec->L_frameTCX, encoderLookahead, encoderLookaheadFB, mdctWindowLength, mdctWindowLengthFB, st->element_mode); + + init_tcx_info(st, L_frame_glob, L_frameTCX_glob, 0, st->bfi, &tcx_offset, &tcx_offsetFB, &L_frame, &L_frameTCX, &left_rect, &L_spec); + + overlap = tcx_cfg->tcx_mdct_window_length; + overlapFB = tcx_cfg->tcx_mdct_window_lengthFB; + index = tcx_cfg->tcx_last_overlap_mode; + + /* LB synthesis */ + IMDCT(t_audio_q, hTcxDec->syn_Overl, hTcxDec->syn_Overl_TDAC, wtda_audio, tcx_cfg->tcx_aldo_window_1_trunc, tcx_cfg->tcx_aldo_window_2, tcx_cfg->tcx_mdct_window_half, tcx_cfg->tcx_mdct_window_minimum, tcx_cfg->tcx_mdct_window_trans, tcx_cfg->tcx_mdct_window_half_length, tcx_cfg->tcx_mdct_window_min_length, index, + MDCT_IV, left_rect, tcx_offset, overlap, L_frame, L_frameTCX, max(L_frameTCX, L_spec) >> 1, L_frame_glob, 0, st->bfi, hHQ_core->old_outLB, 0, st, 0, acelp_zir); + + mvr2r(wtda_audio + (overlap >> 1) - tcx_offset, output, L_frame_glob); + + /* FB synthesis */ + IMDCT(t_audio_q, hTcxDec->syn_OverlFB, hTcxDec->syn_Overl_TDACFB, wtda_audio, tcx_cfg->tcx_aldo_window_1_FB_trunc, tcx_cfg->tcx_aldo_window_2_FB, tcx_cfg->tcx_mdct_window_halfFB, tcx_cfg->tcx_mdct_window_minimumFB, tcx_cfg->tcx_mdct_window_transFB, tcx_cfg->tcx_mdct_window_half_lengthFB, tcx_cfg->tcx_mdct_window_min_lengthFB, index, + MDCT_IV, left_rect, tcx_offsetFB, overlapFB, L_frameTCX, L_frameTCX, max(L_frameTCX, L_spec) >> 1, L_frameTCX_glob, 0, st->bfi, hHQ_core->old_out, 1, st, FSCALE_DENOM * L_frameTCX_glob / L_frame_glob, acelp_zir); + + mvr2r(wtda_audio + (overlapFB >> 1) - tcx_offsetFB, synth, L_frameTCX_glob); + + if (!core_switching_flag) + { + st->last_core = ACELP_CORE; /* Restore last core */ + } + } + else +#endif + { + test(); + IF(EQ_16(output_frame, L_FRAME8k) || st_fx->bfi == 0) + { + test(); + IF(NE_16(inner_frame, output_frame) && EQ_16(st_fx->bfi, 1)) + { + Inverse_Transform(t_audio_q, &Q_audio, wtda_audio, is_transient, output_frame, output_frame, st_fx->element_mode); + } + ELSE + { + Inverse_Transform(t_audio_q, &Q_audio, wtda_audio, is_transient, output_frame, inner_frame, st_fx->element_mode); + } + *Q_synth = Q_audio; + move16(); + } + } +#ifdef ADD_IVAS_HQ_CODE + if (st->element_mode > EVS_MONO) + { + if (st->bfi) + { + /* Rough resampling, but reduces energy loss in case of switch to ACELP in first good frame */ + lerp(t_audio_q, wtda_audio_LB, st->L_frame, inner_frame); + v_multc(t_audio_q, 0.5f, wtda_audio_LB, st->L_frame); + } + else + { + /* LB synthesis for potential switch to ACELP */ + ener_match = (float)sqrt((float)st->L_frame / (float)output_frame); + v_multc(t_audio_q, ener_match, t_audio_q, inner_frame); + inverse_transform(t_audio_q, wtda_audio_LB, is_transient, st->L_frame, inner_frame, st->element_mode); + } + } +#endif + IF ( EQ_16(output_frame, L_FRAME8k)) + { + test(); + IF( st_fx->bfi == 0 && st_fx->prev_bfi == 0) + { + Copy_Scale_sig(hHQ_core->old_out_fx+N_ZERO_NB, hHQ_nbfec->prev_oldauOut_fx, output_frame-N_ZERO_NB, negate(hHQ_core->Q_old_wtda) ); + } + ELSE IF( EQ_16(st_fx->prev_bfi, 1)) + { + set16_fx(hHQ_nbfec->prev_oldauOut_fx, 0, output_frame ); + } + + test(); + test(); + test(); + test(); + IF( (EQ_16(st_fx->prev_bfi, 1)||EQ_16(st_fx->bfi,1))&& hHQ_core->old_is_transient_fx[2]==0&&EQ_16(st_fx->last_core,HQ_CORE)&&EQ_16(st_fx->last_codec_mode,MODE1)) + { + time_domain_FEC_HQ_fx( st_fx, wtda_audio, synth, mean_en_high_fx, output_frame, Q_synth ); + } + ELSE + { + window_ola_fx( wtda_audio, synth, Q_synth, hHQ_core->old_out_fx, &hHQ_core->Q_old_wtda, output_frame, + st_fx->hTcxCfg->tcx_last_overlap_mode, st_fx->hTcxCfg->tcx_curr_overlap_mode, st_fx->prev_bfi, hHQ_core->oldHqVoicing_fx , hHQ_core->oldgapsynth_fx ); + hHQ_nbfec->phase_mat_next_fx = 0; + move16(); + } + + test(); + test(); + IF ( (st_fx->bfi == 0 && st_fx->prev_bfi == 0) || !(GE_16(output_frame, L_FRAME16k))) + { + preecho_sb_fx( st_fx->core_brate, wtda_audio, Q_audio, synth, *Q_synth, output_frame, &hHQ_core->memfilt_lb_fx, + &hHQ_core->mean_prev_hb_fx, &hHQ_core->smoothmem_fx, &hHQ_core->mean_prev_fx, &hHQ_core->mean_prev_nc_fx, &hHQ_core->wmold_hb_fx, &hHQ_core->prevflag_fx, &hHQ_core->pastpre_fx, st_fx->bwidth ); + } + } + ELSE + { + test(); + IF (EQ_16(st_fx->bfi, 1)&&GE_16(output_frame,L_FRAME16k)) + { + /* PHASE_ECU active */ + Q_audio = 15; + move16(); + window_ola_fx( t_audio_q, synth, &Q_audio, hHQ_core->old_out_fx, &hHQ_core->Q_old_wtda, output_frame, + ALDO_WINDOW, ALDO_WINDOW, st_fx->prev_bfi && !hHQ_core->ph_ecu_active_fx, hHQ_core->oldHqVoicing_fx, hHQ_core->oldgapsynth_fx ); + *Q_synth = Q_audio; + move16(); + } + ELSE + { + /* no BFI or baseline PLC active */ + window_ola_fx( wtda_audio, synth, Q_synth, hHQ_core->old_out_fx, &hHQ_core->Q_old_wtda, output_frame, + st_fx->hTcxCfg->tcx_last_overlap_mode, st_fx->hTcxCfg->tcx_curr_overlap_mode, st_fx->prev_bfi && !hHQ_core->ph_ecu_active_fx, hHQ_core->oldHqVoicing_fx, hHQ_core->oldgapsynth_fx); + } +#ifdef ADD_IVAS_HQ_CODE + if (st->element_mode > EVS_MONO) + { + /* LB synthesis for potential switch to ACELP */ + window_ola(wtda_audio_LB, output, hHQ_core->old_outLB, L_FRAME16k, st->hTcxCfg->tcx_last_overlap_mode, st->hTcxCfg->tcx_curr_overlap_mode, st->prev_bfi && !hHQ_core->ph_ecu_active, hHQ_core->oldHqVoicing, hHQ_core->oldgapsynth); + } +#endif + test(); + test(); + IF ( (st_fx->bfi == 0 && st_fx->prev_bfi == 0) || !(GE_16(output_frame, L_FRAME16k))) + { + preecho_sb_fx( st_fx->core_brate, wtda_audio, Q_audio, synth,*Q_synth, output_frame, &hHQ_core->memfilt_lb_fx, + &hHQ_core->mean_prev_hb_fx, &hHQ_core->smoothmem_fx, &hHQ_core->mean_prev_fx, &hHQ_core->mean_prev_nc_fx, + &hHQ_core->wmold_hb_fx, &hHQ_core->prevflag_fx, &hHQ_core->pastpre_fx, st_fx->bwidth ); + } + } + + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF (!st_fx->bfi + && st_fx->prev_bfi + && GE_32(st_fx->last_total_brate, HQ_48k) + && EQ_16(st_fx->last_codec_mode, MODE2) + && (EQ_16(st_fx->last_core_bfi, TCX_20_CORE) || EQ_16(st_fx->last_core_bfi, TCX_10_CORE) ) + && st_fx->plcInfo.concealment_method == TCX_NONTONAL + && LT_32(st_fx->plcInfo.nbLostCmpt, 4) ) + { +#ifdef BASOP_NOGLOB + st_fx->plcInfo.recovery_gain = shl_sat(st_fx->plcInfo.recovery_gain, *Q_synth); +#else + st_fx->plcInfo.recovery_gain = shl(st_fx->plcInfo.recovery_gain, *Q_synth); +#endif + waveform_adj2_fix(st_fx->tonalMDCTconceal.secondLastPcmOut, + synth, + st_fx->plcInfo.data_noise, + &st_fx->plcInfo.outx_new_n1_fx, + &st_fx->plcInfo.nsapp_gain_fx, + &st_fx->plcInfo.nsapp_gain_n_fx, + &st_fx->plcInfo.recovery_gain, + st_fx->plcInfo.step_concealgain_fx, + st_fx->plcInfo.Pitch_fx, + st_fx->plcInfo.FrameSize, + 0, + add(extract_l(st_fx->plcInfo.nbLostCmpt), 1), + st_fx->bfi); + } + + IF (GE_16(output_frame, L_FRAME16k)) + { + IF (EQ_16(hHQ_core->ph_ecu_HqVoicing_fx, 1)) + { + hHQ_core->oldHqVoicing_fx = 1; + move16(); + Copy( gapsynth_fx, hHQ_core->oldgapsynth_fx, L_FRAME48k ); + } + ELSE + { + hHQ_core->oldHqVoicing_fx = 0; + move16(); + } + } + ELSE + { + hHQ_core->oldHqVoicing_fx = 0; + move16(); + } + + if( EQ_16(st_fx->nbLostCmpt, FRAMECTTOSTART_MDCT)) + { + hHQ_core->HqVoicing_fx = 0; + move16(); + } + + IF( EQ_16(output_frame, L_FRAME8k)) + { + Copy32( wtda_audio, hHQ_nbfec->oldIMDCTout_fx, L_FRAME8k/2 ); + Copy(&hHQ_nbfec->old_auOut_2fr_fx[output_frame], hHQ_nbfec->old_auOut_2fr_fx, output_frame); + Copy_Scale_sig(synth, &hHQ_nbfec->old_auOut_2fr_fx[output_frame], output_frame, negate(*Q_synth)); + } + + /* prepare synthesis output buffer (as recent as possible) for HQ FEC */ + + { + Word16 nbsubfr; + /*nbsubfr = extract_l(L_mult0(st_fx->L_frame,FL2WORD16(1/L_SUBFR)));*/ + nbsubfr = 4; + if(EQ_16(st_fx->L_frame,320)) + { + nbsubfr = 5; + move16(); + } + + /* update buffer of old subframe pitch values */ + test(); + IF( EQ_16(st_fx->last_core,HQ_CORE)&&NE_16(st_fx->L_frame,st_fx->last_L_frame)) + { + set32_fx( &st_fx->old_pitch_buf_fx[nbsubfr], (L_SUBFR<<16), nbsubfr ); + } + Copy32( &st_fx->old_pitch_buf_fx[nbsubfr], &st_fx->old_pitch_buf_fx[0], nbsubfr ); + set32_fx( &st_fx->old_pitch_buf_fx[nbsubfr], (L_SUBFR<<16), nbsubfr ); + Copy( &st_fx->mem_pitch_gain[2], &st_fx->mem_pitch_gain[nbsubfr+2], nbsubfr ); + set16_fx( &st_fx->mem_pitch_gain[2], 0, nbsubfr ); + } +#ifdef ADD_IVAS_HQ_CODE + /* Move LB excitation to old_exc memory in case of switch HQ->ACELP */ + if (st->element_mode > EVS_MONO) + { + mvr2r(output, st->old_exc + L_EXC_MEM_DEC - st->L_frame, st->L_frame); + } +#endif + return; +} +/*-------------------------------------------------------------------* + * hq_core_dec_init() + * + * Initialize HQ core state structure + *-------------------------------------------------------------------*/ + +void HQ_core_dec_init( + HQ_DEC_HANDLE hHQ_core /* i/o: HQ core data handle */ +) +{ + + set16_fx(hHQ_core->old_out_fx, 0, L_FRAME48k); + set16_fx(hHQ_core->old_out_LB_fx, 0, L_FRAME32k); + hHQ_core->Q_old_wtda = 15; + hHQ_core->Q_old_postdec = 0; + hHQ_core->Q_old_wtda_LB = 0; + + hHQ_core->last_hq_core_type_fx = -1; + set16_fx(hHQ_core->old_is_transient_fx, 0, 3); + + hHQ_core->mem_norm_fx[0] = 31; + set16_fx(hHQ_core->mem_norm_fx + 1, 39, SFM_N_ENV_STAB - 1); + hHQ_core->mem_env_delta_fx = 0; + hHQ_core->no_att_hangover_fx = 0; + move16(); move16(); move16(); move16(); + hHQ_core->energy_lt_fx = 2457600; /*Q13*/ + hHQ_core->hq_generic_seed_fx = RANDOM_INITSEED; + set16_fx(hHQ_core->prev_noise_level_fx, 0, 2); + hHQ_core->prev_hqswb_clas_fx = HQ_NORMAL; + hHQ_core->prev_R_fx = 0; + move16(); + set32_fx(hHQ_core->prev_coeff_out_fx, 0, L_HQ_WB_BWE); + set16_fx(hHQ_core->prev_SWB_peak_pos_fx, 0, SPT_SHORTEN_SBNUM); + + hHQ_core->HqVoicing_fx = 0; + set16_fx(hHQ_core->fer_samples_fx, 0, L_FRAME48k); + set32_fx(hHQ_core->prev_env_fx, 0, SFM_N_WB); + set32_fx(hHQ_core->prev_normq_fx, 0, SFM_N_WB); + set16_fx(hHQ_core->prev_env_Q, 0, SFM_N_WB); + + set32_fx(hHQ_core->last_ni_gain_fx, 0, BANDS_MAX); + set16_fx(hHQ_core->last_env_fx, 0, BANDS_MAX); + hHQ_core->last_max_pos_pulse_fx = 0; + move16(); + + reset_preecho_dec_fx(hHQ_core); + + hHQ_core->prev_frm_hfe2_fx = 0; + move16(); + hHQ_core->prev_stab_hfe2_fx = 0; + move16(); + hHQ_core->prev_ni_ratio_fx = 16384; /*Q15*/ + move16(); + set16_fx(hHQ_core->prev_En_sb_fx, 0, NB_SWB_SUBBANDS); + + + /*----------------------------------------------------------------------------------* + * HQ FEC + *----------------------------------------------------------------------------------*/ + hHQ_core->time_offs_fx = 0; + set16_fx(hHQ_core->X_sav_fx, 0, PH_ECU_SPEC_SIZE); + hHQ_core->Q_X_sav = 0; + hHQ_core->num_p_fx = 0; + + //set16_fx(hHQ_core->plocs_fx, 0, MAX_PLOCS); + //set32_fx(hHQ_core->plocsi_fx, 0, MAX_PLOCS); + hHQ_core->env_stab_fx = 0x6000; /*0.75 Q15*/ + hHQ_core->mem_norm_hqfec_fx[0] = 31; + move16(); + set16_fx(hHQ_core->mem_norm_hqfec_fx + 1, 39, SFM_N_ENV_STAB - 1); + hHQ_core->mem_env_delta_hqfec_fx = 0; + hHQ_core->env_stab_plc_fx = 0; + set16_fx(hHQ_core->env_stab_state_p_fx, INV_NUM_ENV_STAB_PLC_STATES, NUM_ENV_STAB_PLC_STATES); + hHQ_core->envstabplc_hocnt_fx = 0; + set16_fx(hHQ_core->mag_chg_1st_fx, 32767, LGW_MAX); + set16_fx(hHQ_core->Xavg_fx, 0, LGW_MAX); + hHQ_core->beta_mute_fx = BETA_MUTE_FAC_INI; + hHQ_core->last_fec_fx = 0; + hHQ_core->ph_ecu_HqVoicing_fx = 0; + hHQ_core->oldHqVoicing_fx = 0; + set16_fx(hHQ_core->oldgapsynth_fx, 0, L_FRAME48k); + hHQ_core->ph_ecu_active_fx = 0; + hHQ_core->ni_seed_forfec = 0; + hHQ_core->ber_occured_in_pvq = 0; + move16(); move16(); move16(); move16(); move16(); + + + return; +} + +/*-------------------------------------------------------------------* + * HQ_nbfec_init() + * + * Initialize HQ NB FEC state structure + *-------------------------------------------------------------------*/ + +void HQ_nbfec_init( + HQ_NBFEC_HANDLE hHQ_nbfec /* i/o: HQ NB FEC data handle */ +) +{ + int16_t i, j; + + hHQ_nbfec->prev_last_core_fx = -1; + hHQ_nbfec->diff_energy_fx = 0; + hHQ_nbfec->stat_mode_out_fx = 0; + hHQ_nbfec->stat_mode_old_fx = 0; + move16(); move16(); + hHQ_nbfec->phase_mat_flag_fx = 0; + hHQ_nbfec->phase_mat_next_fx = 0; + hHQ_nbfec->old_Min_ind_fx = 0; + move16(); move16(); move16(); move16(); + set16_fx(hHQ_nbfec->old_auOut_2fr_fx, 0, L_FRAME8k * 2); + set16_fx(hHQ_nbfec->old_out_pha_fx[0], 0, N_LEAD_NB); + set16_fx(hHQ_nbfec->old_out_pha_fx[1], 0, N_LEAD_NB); + + FOR(i = 0; i < MAX_SB_NB; i++) + { + FOR(j = 0; j < MAX_PGF; j++) + { + hHQ_nbfec->ynrm_values_fx[i][j] = 0; + move16(); + } + FOR(j = 0; j < MAX_ROW; j++) + { + hHQ_nbfec->r_p_values_fx[i][j] = 0; + move16(); + } + } + + set16_fx(hHQ_nbfec->Norm_gain_fx, 1, SFM_N_NB); + hHQ_nbfec->HQ_FEC_seed_fx = RANDOM_INITSEED; + set16_fx(hHQ_nbfec->energy_MA_Curr_fx, 100, 2); + + set16_fx(hHQ_nbfec->prev_sign_switch_fx, 0, HQ_FEC_SIGN_SFM); + set16_fx(hHQ_nbfec->prev_sign_switch_2_fx, 0, HQ_FEC_SIGN_SFM); + + set32_fx(hHQ_nbfec->old_coeffs_fx, 0, L_FRAME8k); + set32_fx(hHQ_nbfec->oldIMDCTout_fx, 0, L_FRAME8k / 2); + set16_fx(hHQ_nbfec->prev_oldauOut_fx, 0, L_FRAME8k); + + return; +} diff --git a/lib_dec/hq_env_dec_fx.c b/lib_dec/hq_env_dec_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..6362cc79838da5047322fbb521e60eb579b06d22 --- /dev/null +++ b/lib_dec/hq_env_dec_fx.c @@ -0,0 +1,216 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include +#include "options.h" /* Compilation switches */ +#include "prot_fx1.h" /* Function prototypes */ +#include "prot_fx2.h" /* Function prototypes */ +#include "rom_com.h" /* Static table prototypes */ + +/*------------------------------------------------------------------------* + * decode_envelope_indices_fx() + * + * Decode envelope indices + *------------------------------------------------------------------------*/ + +Word16 decode_envelope_indices_fx( /* o : Number of bits */ + Decoder_State *st_fx, /* i/o: decoder state structure */ + const Word16 start_norm, /* i : starting band index */ + const Word16 num_sfm, /* i : Number of subbands */ + const Word16 numnrmibits, /* i : Bitrate of fall-back coding mode */ + Word16 *difidx, /* o : Diff indices/encoded diff indices */ + const Word16 flag_HQ2 /* i : indicator of HQ2 core */ + ,const Word16 is_transient /* i : indicator of HQ_TRANSIENT */ +) +{ + Word16 hcode_l; + Word16 i,j; + Word16 LCmode; + Word16 startNormPlus1,numSfmMinus1,numSfmMinus2,offset; + Word16 *pDifidx,*pDifidx1; + + test(); + IF( EQ_16(flag_HQ2, LOW_RATE_HQ_CORE)||EQ_16(flag_HQ2,LOW_RATE_HQ_CORE_TRAN)) + { + LCmode = (Word16)get_next_indice ( st_fx, BITS_DE_HMODE); + difidx[start_norm] = (Word16)get_next_indice ( st_fx, BITS_DE_FCOMP); + } + ELSE + { + LCmode = (Word16)get_next_indice( st_fx, 2 ); + difidx[start_norm] = (Word16)get_next_indice( st_fx, NORM0_BITS ); + } + + test(); + IF( is_transient && EQ_16(flag_HQ2, LOW_RATE_HQ_CORE_TRAN)) + { + hcode_l = 0; + move16(); + IF( EQ_16(LCmode, 1)) + { + hdecnrm_tran_fx(st_fx, num_sfm, &difidx[start_norm + 1] ); + j = add(start_norm, num_sfm); + FOR( i = start_norm + 1; i < j; i++ ) + { + hcode_l = add(hcode_l, huffsizn_tran[difidx[i]]); + } + } + ELSE + { + hdecnrm_context_fx(st_fx, num_sfm, &difidx[start_norm], &hcode_l); + } + } + ELSE + { + hcode_l = 0; + IF( LCmode == 0 ) + { + hdecnrm_context_fx( st_fx, num_sfm, &difidx[start_norm], &hcode_l); + } + ELSE IF( LCmode == 1 ) + { + startNormPlus1 = add(start_norm, 1); + hdecnrm_resize_fx( st_fx, num_sfm, &difidx[startNormPlus1] ); + + pDifidx = &difidx[startNormPlus1]; + move16(); + numSfmMinus1 = sub(num_sfm, 1); + FOR( i = 0; i < numSfmMinus1; i++ ) + { + j = *pDifidx++; + move16(); + hcode_l = add(hcode_l, resize_huffsizn[j]); + } + + pDifidx1 = &difidx[startNormPlus1]; + move16(); + numSfmMinus2 = sub(num_sfm, 2); + FOR( i = 0; i < numSfmMinus2; i++ ) + { + pDifidx = pDifidx1++; + move16(); + IF( *pDifidx > 17 ) + { + offset = sub(*pDifidx, 17); + offset = s_min(offset, 3); + *pDifidx1 = sub(*pDifidx1, offset); + } + ELSE IF( *pDifidx < 13 ) + { + offset = sub(*pDifidx, 13); + offset = s_max(offset, -3); + *pDifidx1 = sub(*pDifidx1, offset); + } + } + } + ELSE IF( LCmode == 2 ) + { + startNormPlus1 = add(start_norm, 1); + hdecnrm_fx( st_fx, num_sfm, &difidx[start_norm + 1] ); + + pDifidx = &difidx[startNormPlus1]; + move16(); + numSfmMinus1 = sub(num_sfm, 1); + FOR( i = 0; i < numSfmMinus1; i++ ) + { + j = *pDifidx++; + move16(); + hcode_l = add(hcode_l, huffsizn[j]); + } + } + ELSE + { + startNormPlus1 = add(start_norm, 1); + numSfmMinus1 = sub(num_sfm, 1); + pDifidx = &difidx[startNormPlus1]; + FOR( i = 0; i < numSfmMinus1; i++ ) + { + *pDifidx++ = (Word16)get_next_indice( st_fx, NORMI_BITS ); + move16(); + } + hcode_l = numnrmibits; + move16(); + } + } + + return hcode_l; +} + +/*------------------------------------------------------------------------* + * dequantize_norms_fx() + * + * De-quantization of norms + *------------------------------------------------------------------------*/ + +void dequantize_norms_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + const Word16 start_norm, /* i : First SDE encoded norm */ + const Word16 num_sfm, /* i : Number of norms */ + const Word16 is_transient, /* i : Transient flag */ + Word16 *ynrm, /* o : Decoded norm indices */ + Word16 *normqlg2 /* o : Log2 of decoded norms */ +) +{ + Word16 i,j; + Word16 idxbuf[NB_SFM]; + Word16 *pYnrm, *pNormqlg2; + + /* First sub-frame */ + i = ynrm[start_norm]; + move16(); + normqlg2[start_norm] = dicnlg2[i]; + move16(); + + /* Other sub-frames */ + IF ( is_transient ) + { + /* Recover quantization indices and quantized norms */ + idxbuf[0] = ynrm[0]; + move16(); + FOR ( i = 1; i < num_sfm; i++ ) + { + idxbuf[i] = sub( add(ynrm[i],idxbuf[i-1]), 15 ); + move16(); + /* safety check in case of bit errors */ + test(); + IF ( idxbuf[i] < 0 || GT_16( idxbuf[i], 39 )) + { + idxbuf[i] = 39; + move16(); + st_fx->BER_detect = 1; + move16(); + } + } + + recovernorm_fx( idxbuf, ynrm, normqlg2, num_sfm ); + } + ELSE + { + pYnrm = &ynrm[start_norm]; + move16(); + pNormqlg2 = &normqlg2[start_norm+1]; + move16(); + FOR ( i = 1; i < num_sfm; i++ ) + { + j = sub(*pYnrm++,15); + move16(); + *pYnrm = add(*pYnrm,j); + move16(); + /* safety check in case of bit errors */ + test(); + IF ( *pYnrm < 0 || GT_16( *pYnrm, 39 )) + { + *pYnrm = 39; + move16(); + st_fx->BER_detect = 1; + move16(); + } + *pNormqlg2++ = dicnlg2[*pYnrm]; + move16(); + } + } + + return; +} + diff --git a/lib_dec/hq_hr_dec.c b/lib_dec/hq_hr_dec.c index 923d3b05ef917c14ffdf92d1b72d510c6189493c..b959d953f14268e0629dbcebfb488d8f5ba1d9d8 100644 --- a/lib_dec/hq_hr_dec.c +++ b/lib_dec/hq_hr_dec.c @@ -178,7 +178,7 @@ void hq_hr_dec( if ( *hqswb_clas == HQ_GEN_SWB || *hqswb_clas == HQ_GEN_FB ) { - hq_generic_exc_clas = swb_bwe_gain_deq( st, HQ_CORE, NULL, SWB_fenv, st->core_brate >= HQ_32k, *hqswb_clas ); /* Use (st->core_brate >= HQ_32k) to be consistent with hq_configure */ + hq_generic_exc_clas = swb_bwe_gain_deq_flt( st, HQ_CORE, NULL, SWB_fenv, st->core_brate >= HQ_32k, *hqswb_clas ); /* Use (st->core_brate >= HQ_32k) to be consistent with hq_configure */ if ( hq_generic_exc_clas == HQ_GENERIC_SP_EXC ) { bits_left++; /* conditional 1 bit saving for representing FD3 BWE excitation class */ diff --git a/lib_dec/hq_hr_dec_fx.c b/lib_dec/hq_hr_dec_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..768572fa52c0fb6ae93bce0f4ca4fa61bc558b41 --- /dev/null +++ b/lib_dec/hq_hr_dec_fx.c @@ -0,0 +1,331 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ +#include +#include "options.h" /* Compilation switches */ +#include "prot_fx1.h" /* Function prototypes */ +#include "prot_fx2.h" /* Function prototypes */ +#include "rom_com.h" /* Static table prototypes */ + +/*--------------------------------------------------------------------------* + * hq_pred_hb_bws() + * + * HQ core HB band-width switching handling + *--------------------------------------------------------------------------*/ + +void hq_pred_hb_bws_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + const Word16 *ynrm, /* i : norm quantization index vector */ + const Word16 length, /* i : frame length */ + const Word16 hqswb_clas, /* i : HQ SWB class */ + const Word16 *SWB_fenv /* i : SWB frequency envelopes Q1 */ +) +{ + Word16 i; + Word32 L_tmp; + + IF( GE_16(length,L_FRAME32k)) + { + /* calculate the switching parameters */ + test(); + test(); + IF( ( NE_16(hqswb_clas,HQ_GEN_SWB)&&LE_32(st_fx->core_brate,HQ_32k))||GT_32(st_fx->core_brate,HQ_32k)) + { + st_fx->prev_ener_shb_fx = 0; + move16(); + L_tmp = L_deposit_l(0); + FOR(i=25; iprev_ener_shb_fx = extract_l(L_tmp);/*Q1*/ + st_fx->prev_ener_shb_fx = mult(st_fx->prev_ener_shb_fx,5461); /*Q1*/ + } + ELSE + { + st_fx->prev_ener_shb_fx = 0; + move16(); + FOR(i=0; iprev_ener_shb_fx = add(st_fx->prev_ener_shb_fx,SWB_fenv[i]);/*Q1*/ + } + st_fx->prev_ener_shb_fx = mult(st_fx->prev_ener_shb_fx, 2979); /*Q1*/ + } + } + + IF( GE_16(st_fx->last_inner_frame,L_FRAME32k)) + { + set16_fx(st_fx->prev_SWB_fenv_fx, st_fx->prev_ener_shb_fx, SWB_FENV); + } + + return; + +} +/*--------------------------------------------------------------------------* + * hq_hr_dec_fx() + * + * HQ High rate decoding routine + *--------------------------------------------------------------------------*/ +void hq_hr_dec_fx( + Decoder_State *st_fx, /* i/o: decoder state structure fx */ + Word32 *t_audio_q, /* o : transform-domain coefficients Q12 */ + const Word16 length, /* i : frame length Q0 */ + Word16 num_bits, /* i : number of available bits Q0 */ + Word16 *ynrm, /* o : norm quantization index vector Q0 */ + Word16 *is_transient, /* o : transient flag Q0 */ + Word16 *hqswb_clas, /* o : HQ SWB class Q0 */ + Word16 *SWB_fenv, /* o : SWB frequency envelopes Q1 */ + const Word16 core_switching_flag /* i : Core switching flag */ +) +{ + Word16 nb_sfm; + Word16 sum, hcode_l; + Word16 sfmsize[NB_SFM], sfm_start[NB_SFM], sfm_end[NB_SFM]; + Word16 num_sfm, numnrmibits; + Word16 nf_idx; + Word16 normqlg2[NB_SFM], R[NB_SFM]; + Word16 pulses[NB_SFM], maxpulse[NB_SFM]; + Word16 env_stab; /*Q15*/ + Word16 Rsubband[NB_SFM]; /*Q3*/ + Word16 start_norm, Npeaks = 0; + Word16 noise_level[HVQ_BWE_NOISE_BANDS]; /*Q15*/ + Word16 peak_idx[HVQ_MAX_PEAKS]; + Word16 hq_generic_offset; + Word16 num_env_bands; + Word16 hq_generic_exc_clas = 0; + Word16 core_sfm; + Word16 har_freq_est1, har_freq_est2; + Word16 flag_dis; + const Word16 *subband_search_offset; + Word16 wBands[2]; + Word16 bits, i; + Word16 t_audio_q_norm[L_FRAME48k]; + Word16 Q_audio; + Word16 b_delta_env; + Word16 tmp,n_band; + Word16 Q_shift; + Word16 bits_left; + Word16 csw_flag1, csw_flag2; + + HQ_DEC_HANDLE hHQ_core = st_fx->hHQ_core; + + move16(); + + Q_audio = 0; /* to avoid compilation warnings */ + + /*------------------------------------------------------------------* + * Initializations + *------------------------------------------------------------------*/ + + set16_fx( pulses, 0, NB_SFM ); + set16_fx( maxpulse, 0, NB_SFM ); + flag_dis = 1; + move16(); + har_freq_est1 = 0; + move16(); + har_freq_est2 = 0; + move16(); + set16_fx( peak_idx, 0, HVQ_MAX_PEAKS); + + /*------------------------------------------------------------------* + * Decode classification + *------------------------------------------------------------------*/ + + bits = hq_classifier_dec_fx( st_fx, st_fx->core_brate, length, is_transient, hqswb_clas); + bits_left = sub(num_bits, bits); + + /*------------------------------------------------------------------* + * set quantization parameters + *------------------------------------------------------------------*/ + hq_configure_evs_fx( length, *hqswb_clas, st_fx->core_brate, &num_sfm, &nb_sfm, &start_norm, + &num_env_bands, &numnrmibits, &hq_generic_offset, sfmsize, sfm_start, sfm_end ); + + /*------------------------------------------------------------------* + * Unpacking bitstream + *------------------------------------------------------------------*/ + + nf_idx = 0; + move16(); + test(); + test(); + test(); + IF( !*is_transient && NE_16(*hqswb_clas, HQ_HVQ) && !(EQ_16(length,L_FRAME16k) && LE_32(st_fx->core_brate,HQ_32k))) + { + nf_idx = get_next_indice( st_fx, 2 ); + } + + /*------------------------------------------------------------------* + * Decode envelope + *------------------------------------------------------------------*/ + + hcode_l = decode_envelope_indices_fx( st_fx, start_norm, num_env_bands, numnrmibits, ynrm, NORMAL_HQ_CORE, *is_transient ); + bits_left = sub(bits_left, add(hcode_l, NORM0_BITS + FLAGS_BITS)); + + dequantize_norms_fx( st_fx, start_norm, num_env_bands, *is_transient, ynrm, normqlg2 ); + + test(); + IF ( EQ_16(*hqswb_clas, HQ_GEN_SWB)||EQ_16(*hqswb_clas,HQ_GEN_FB)) + { + hq_generic_exc_clas = swb_bwe_gain_deq_fx( st_fx, HQ_CORE, NULL, SWB_fenv, st_fx->core_brate >= HQ_32k, *hqswb_clas ); /* Use (st->core_brate >= HQ_32k) to be consistent with hq_configure */ + if ( EQ_16(hq_generic_exc_clas , HQ_GENERIC_SP_EXC)) + { + bits_left = add(bits_left,1); /* conditional 1 bit saving for representing HQ GENERIC excitation class */ + } + map_hq_generic_fenv_norm_fx( *hqswb_clas, SWB_fenv, ynrm, normqlg2, num_env_bands, nb_sfm, hq_generic_offset ); + } + + env_stab = 0; + move16(); + + csw_flag1 = s_and(core_switching_flag, (Word16)NE_16(st_fx->element_mode, EVS_MONO) ); + csw_flag2 = s_and(csw_flag1, (Word16)EQ_16(length, L_SPEC32k_EXT)); + test(); + IF( EQ_16(*hqswb_clas, HQ_HVQ)) + { + hHQ_core->mem_env_delta_fx = 0; + move16(); + } + ELSE IF (EQ_16(length, L_FRAME32k) || csw_flag2 ) + { + env_stab = env_stability_fx( ynrm, SFM_N_ENV_STAB, hHQ_core->mem_norm_fx, &hHQ_core->mem_env_delta_fx, csw_flag1); + } + ELSE + { + hHQ_core->mem_norm_fx[0] = 31; + move16(); + hHQ_core->mem_env_delta_fx = 0; + move16(); + } + + IF ( EQ_16(*hqswb_clas, HQ_HVQ)) + { + hHQ_core->env_stab_fx = 32767; + move16(); /* 1 in Q15, stable by definition */ + } + ELSE + { + IF ( EQ_16(length, L_FRAME32k) || csw_flag2) + { + move16(); /* calculated stability */ + hHQ_core->env_stab_fx = env_stab; + } + ELSE + { + hHQ_core->env_stab_fx = env_stability_fx( ynrm, SFM_N_ENV_STAB_WB, hHQ_core->mem_norm_hqfec_fx, &hHQ_core->mem_env_delta_hqfec_fx, csw_flag1); + } + } + hHQ_core->env_stab_plc_fx = env_stab_smo_fx(s_min(hHQ_core->env_stab_fx, sub(32767, stab_trans_fx[L_STAB_TBL-1])), hHQ_core->env_stab_state_p_fx, &hHQ_core->envstabplc_hocnt_fx); + + /*------------------------------------------------------------------* + * Bit allocation + *------------------------------------------------------------------*/ + + hq_bit_allocation_fx( st_fx->core_brate, length, *hqswb_clas, &bits_left, normqlg2, nb_sfm, sfmsize, noise_level, + R, Rsubband, &sum, &core_sfm, num_env_bands ); + + test(); + test(); + IF( EQ_16(*hqswb_clas, HQ_GEN_SWB) && st_fx->bws_cnt1_fx>0 && LT_32(st_fx->core_brate,HQ_32k)) + { + tmp = i_mult(st_fx->bws_cnt1_fx, 1638); + move16(); + IF( EQ_16(st_fx->L_frame, L_FRAME16k)) + { + FOR (n_band = 0; n_band < 4; n_band++) + { + SWB_fenv[n_band] = mult_r(SWB_fenv[n_band], tmp); + move16(); + } + } + + FOR (n_band = 4; n_band < SWB_FENV; n_band++) + { + SWB_fenv[n_band] = mult_r(SWB_fenv[n_band], tmp); + move16(); + } + } + + test(); + IF ( EQ_16(*hqswb_clas , HQ_GEN_SWB)||EQ_16(*hqswb_clas,HQ_GEN_FB)) + { + b_delta_env = get_nor_delta_hf_fx(st_fx, ynrm, Rsubband, num_env_bands, nb_sfm, core_sfm ); + sum = sub(sum,b_delta_env); + } + + /*------------------------------------------------------------------* + * Decode spectral fine structure using HVQ/PVQ + *------------------------------------------------------------------*/ + + IF( EQ_16(*hqswb_clas, HQ_HVQ)) + { + hvq_dec_fx( st_fx, bits_left, st_fx->core_brate, ynrm, R, noise_level, peak_idx, &Npeaks, t_audio_q, st_fx->core ); + } + ELSE + { + pvq_core_dec_fx(st_fx, sfm_start, sfm_end, sfmsize, t_audio_q_norm, &Q_audio, sum, nb_sfm, Rsubband, R, pulses, maxpulse, HQ_CORE ); + } + + test(); + IF ( EQ_16(*hqswb_clas, HQ_HVQ)||EQ_16(*hqswb_clas,HQ_HARMONIC)) + { + subband_search_offset = subband_search_offsets_13p2kbps_Har; + wBands[0] = SWB_SB_BW_LEN0_16KBPS_HAR; + move16(); + wBands[1] = SWB_SB_BW_LEN1_16KBPS_HAR; + move16(); + + IF (EQ_16(*hqswb_clas, HQ_HARMONIC)) + { + Q_shift = sub(SWB_BWE_LR_Qs, Q_audio); + FOR (i = 0; i < 300; i++) + { + t_audio_q[i] = L_shl(L_deposit_l(t_audio_q_norm[i]), Q_shift); /* Q12 */ + } + } + + har_est_fx( t_audio_q, 300 ,&har_freq_est1, &har_freq_est2, &flag_dis, &hHQ_core->prev_frm_hfe2_fx, subband_search_offset, wBands, &hHQ_core->prev_stab_hfe2_fx ); + + hHQ_core->prev_frm_hfe2_fx = har_freq_est2; + move16(); + } + + test(); + test(); +#if 0 + IF ( NE_16(*hqswb_clas, HQ_HARMONIC)||NE_16(*hqswb_clas,HQ_HVQ)||flag_dis==0) // TV2VE -> always reset in floating point code, is it OK +#endif + { + hHQ_core->prev_frm_hfe2_fx = 0; /*reset*/ move16(); + hHQ_core->prev_stab_hfe2_fx = 0; /*reset*/ move16(); + } + + /*------------------------------------------------------------------* + * Spectral filling + *------------------------------------------------------------------*/ + fill_spectrum_fx( t_audio_q_norm, t_audio_q, R, *is_transient, ynrm, SWB_fenv, hq_generic_offset, nf_idx, length, env_stab, + &hHQ_core->no_att_hangover_fx, &hHQ_core->energy_lt_fx, &hHQ_core->hq_generic_seed_fx, hq_generic_exc_clas, + core_sfm, *hqswb_clas, noise_level, st_fx->core_brate, hHQ_core->prev_noise_level_fx, &hHQ_core->prev_R_fx, hHQ_core->prev_coeff_out_fx, peak_idx, Npeaks, pulses, hHQ_core->old_is_transient_fx[0], + hHQ_core->prev_normq_fx, hHQ_core->prev_env_fx, st_fx->prev_bfi, sfmsize, sfm_start, sfm_end, + &st_fx->hBWE_FD->prev_L_swb_norm_fx, hHQ_core->prev_hqswb_clas_fx, num_sfm, hHQ_core->prev_env_Q, num_env_bands + ,st_fx->element_mode); + + enforce_zero_for_min_envelope_fx( *hqswb_clas, ynrm, t_audio_q, nb_sfm, sfm_start, sfm_end ); + + + IF( EQ_16(*is_transient, 1)) + { + de_interleave_spectrum_fx( t_audio_q, length ); + } + + /*------------------------------------------------------------------* + * WB/SWB bandwidth switching + *------------------------------------------------------------------*/ + hq_pred_hb_bws_fx(st_fx, ynrm, length, *hqswb_clas, SWB_fenv ); + + /* update */ + hHQ_core->prev_hqswb_clas_fx = *hqswb_clas; + move16(); + + return; +} diff --git a/lib_dec/hq_lr_dec_fx.c b/lib_dec/hq_lr_dec_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..7acc5e8b1289448a287ffcd1ea09f4bb576ee1b7 --- /dev/null +++ b/lib_dec/hq_lr_dec_fx.c @@ -0,0 +1,1356 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include +#include +#include "options.h" +#include "cnst.h" +#include "rom_dec.h" +#include "prot_fx1.h" +#include "prot_fx2.h" +#include "rom_com.h" + +/*--------------------------------------------------------------------------* + * Local function prototypes + *--------------------------------------------------------------------------*/ + +static Word16 p2a_threshold_dequant_fx( Decoder_State *st_fx, Word16 *p2a_flags, const Word16 bands, const Word16 p2a_bands ); + +static void mdct_spectrum_fine_gain_dec_fx( Decoder_State *st_fx, Word32 L_y2[], const Word16 band_start[], const Word16 band_end[], + const Word16 k_sort[], const Word16 bands, + const Word32 L_qint,const Word16 Ngq, const Word16 gqlevs, const Word16 gqbits ); + +static Word16 band_energy_dequant_fx( Decoder_State *st_fx, Word32 L_band_energy[], const Word16 bands, + const Word32 L_qint,const Word16 eref_fx, const Word16 is_transient_fx ); + +static Word16 Calc_inv(Word32 L_tmp, Word16 *exp) +{ + Word16 exp2, tmp; + + tmp = extract_h(L_tmp); + + IF(tmp != 0) + { + exp2 = norm_s(tmp); + tmp = shl(tmp,exp2);/*Q(exp) */ + tmp = div_s(16384,tmp);/*Q(15+14-exp=29-exp) */ + *exp = sub(29,exp2); + move16(); + } + ELSE + { + tmp = 0x7fff; + move16(); + *exp = 0; + move16(); + } + return tmp; +} + +/*--------------------------------------------------------------------------* + * spt_shorten_domain_set_dec() + * + * update the shorten band information based on p2a analysis + *--------------------------------------------------------------------------*/ + +static void spt_shorten_domain_set_dec_fx( + Decoder_State *st_fx, /* i: encoder state structure */ + const Word16 p2a_flags[], /* i: p2a anlysis information */ + const Word16 new_band_start[], /* i: new band start position */ + const Word16 new_band_end[], /* i: new band end position */ + const Word16 new_band_width[], /* i: new subband band width */ + const Word16 bands, /* i: total number of subbands */ + Word16 band_start[], /* o: band start position */ + Word16 band_end[], /* o: band end position */ + Word16 band_width[], /* o: sub band band width */ + Word16 *bit_budget /* i/o: bit budget */ +) +{ + Word16 j,k; + Word16 spt_shorten_flag[SPT_SHORTEN_SBNUM]; + + j = 0; + move16(); + FOR( k = sub(bands,SPT_SHORTEN_SBNUM); k < bands; k++ ) + { + spt_shorten_flag[j] = 0; + move16(); + IF( EQ_16(p2a_flags[k], 1)) + { + spt_shorten_flag[j] = get_next_indice (st_fx, 1 ); + *bit_budget = sub(*bit_budget, 1); + IF( EQ_16(spt_shorten_flag[j], 1)) + { + band_start[k] = new_band_start[j]; + move16(); + band_end[k] = new_band_end[j]; + move16(); + band_width[k] = new_band_width[j]; + move16(); + } + } + + j = add(j, 1); + } + + return; +} + +/*-------------------------------------------------------------------* + * hq_lr_dec_fx() + * + * HQ low rate decoding routine + *-------------------------------------------------------------------*/ + +void hq_lr_dec_fx( + Decoder_State *st_fx, /* i/o: : decoder state structure */ + Word32 L_yout[], /* o : Q12 : transform-domain output coefs. */ + const Word16 inner_frame, /* i : Q0 : inner frame length */ + Word16 num_bits, /* i : Q0 : number of available bits */ + Word16 *is_transient_fx /* o : Q0 : transient flag */ +) +{ + Word16 i, j, k; + + Word32 L_y2[L_FRAME48k]; + Word32 L_y2_ni[L_FRAME48k]; + Word32 L_y2_org[L_FRAME48k]; + Word16 inp_vector_fx[L_FRAME48k]; + Word16 flag_spt_fx; + Word32 L_m[L_FRAME48k]; + Word32 L_band_energy[BANDS_MAX]; + Word32 L_band_energy_tmp[BANDS_MAX]; + + Word16 npulses_fx[BANDS_MAX]; + Word16 lowlength_fx, highlength_fx, hqswb_clas_fx, har_bands_fx, bands_fx; + Word16 p2a_flags_fx[BANDS_MAX]; + Word32 L_bwe_br; + Word16 prev_SWB_peak_pos_tmp_fx[SPT_SHORTEN_SBNUM]; + + Word16 band_start[BANDS_MAX], band_end[BANDS_MAX], band_width[BANDS_MAX],trans_bit_fx; + + /* hq2_core_configure */ + Word32 L_qint; + /*Word16 Qqint=29;*/ + + Word16 eref_fx/*, Qeref=10*/; + Word16 bit_alloc_weight_fx/*, Qbaw=13*/; + Word16 ld_slope_fx/*, Qldslope=15*/; + Word16 p2a_th_fx/*, Qp2ath=11*/; + Word16 pd_thresh_fx/*, Qpdth=15*/; + Word16 ni_coef_fx/*, Qnicoef=14*/; + + Word32 L_Rk[BANDS_MAX]; + Word16 bit_budget_fx; + + Word16 ni_seed_fx; + Word16 length_fx; + Word16 pbits_fx; + + Word16 k1_fx; + Word16 gqlevs_fx, gqbits_fx, Ngq_fx, p2a_bands_fx; + Word16 ebits_fx; + Word16 exp_norm; + Word16 org_band_start[SPT_SHORTEN_SBNUM]; + Word16 org_band_end[SPT_SHORTEN_SBNUM]; + Word16 org_band_width[SPT_SHORTEN_SBNUM]; + + Word16 new_band_start[SPT_SHORTEN_SBNUM]; + Word16 new_band_end[SPT_SHORTEN_SBNUM]; + Word16 new_band_width[SPT_SHORTEN_SBNUM]; + + Word16 k_sort_fx[BANDS_MAX]; + Word16 last_bitalloc_max_band[2]; + Word32 L_tmp; + Word16 lowband,highband,p2a_flags_tmp[BANDS_MAX]; + Word32 L_tmp2,L_tmp3; + Word16 exp,exp2,tmp,tmp1,tmp2,tmp3,frac1,alpha_fx,Q_band_energy; + Word32 enerH_fx; + Word32 enerL_fx; + Word32 Ep_fx[BANDS_MAX]; + Word32 Ep_avrg_fx, Ep_vari_fx; + Word32 Ep_avrgL_fx; + Word32 Ep_peak_fx; + Word32 Ep_tmp_fx[BANDS_MAX]; + Word16 gama_fx;/*Q15 0.85f;// */ + Word16 beta_fx;/*Q14 1.05f; */ + Word16 adjustFlag; + Word16 bw_low, bw_high; + + + HQ_DEC_HANDLE hHQ_core = st_fx->hHQ_core; + + tmp2 = 0; /* to avoid compilation flags */ + + set16_fx(last_bitalloc_max_band, 0, 2); + set32_fx( L_y2, 0x0L, L_FRAME48k ); + set16_fx( inp_vector_fx, 0, inner_frame ); + flag_spt_fx = 0; + move16(); + set16_fx(prev_SWB_peak_pos_tmp_fx, 0, SPT_SHORTEN_SBNUM); + adjustFlag = 0; + move16(); + bw_low = 0; + move16(); + bw_high = 20; + move16(); + enerL_fx = L_deposit_l(0); + enerH_fx = L_deposit_l(0); + + L_bwe_br = L_add(st_fx->core_brate, 0); + hqswb_clas_fx = 0; + move16(); + test(); + test(); + IF( EQ_16(st_fx->bwidth, SWB)&&(EQ_32(L_bwe_br,HQ_16k40)||EQ_32(L_bwe_br,HQ_13k20))) + { + hqswb_clas_fx = get_next_indice(st_fx, 2); + num_bits = sub(num_bits, 2); + + *is_transient_fx = 0; + move16(); + if ( EQ_16(hqswb_clas_fx, HQ_TRANSIENT)) + { + *is_transient_fx = 1; + move16(); + } + } + ELSE + { + /* decode transient flag */ + *is_transient_fx = get_next_indice(st_fx, 1); + num_bits = sub(num_bits, 1); + } + + /* Configure decoder for different bandwidths, bit rates, etc. */ + hq2_core_configure_fx( inner_frame, num_bits, *is_transient_fx, &bands_fx, &length_fx, band_width, band_start, band_end, + &L_qint, &eref_fx, &bit_alloc_weight_fx, &gqlevs_fx, &Ngq_fx, &p2a_bands_fx, &p2a_th_fx, &pd_thresh_fx, &ld_slope_fx, &ni_coef_fx + ,L_bwe_br); + + highlength_fx = band_end[bands_fx-1]; + move16(); + har_bands_fx = bands_fx; + move16(); + + test(); + test(); + test(); + IF( EQ_16(st_fx->bwidth, SWB)&&*is_transient_fx==0&&(EQ_32(L_bwe_br,HQ_16k40)||EQ_32(L_bwe_br,HQ_13k20))) + { + /* reserve bits for HQ_NORMAL2 and HQ_HARMONIC modes */ + test(); + IF( EQ_16(hqswb_clas_fx, HQ_NORMAL)||EQ_16(hqswb_clas_fx,HQ_HARMONIC)) + { + num_bits = sub(num_bits, get_usebit_npswb_fx(hqswb_clas_fx)); + } + if( EQ_16(hqswb_clas_fx, HQ_NORMAL)) + { + flag_spt_fx = 1; + move16(); + } + } + + test(); + test(); + IF(( EQ_32(L_bwe_br, HQ_16k40)||EQ_32(L_bwe_br,HQ_13k20))&&EQ_16(st_fx->bwidth,SWB)) + { + IF( NE_16(hHQ_core->prev_hqswb_clas_fx, HQ_NORMAL)) + { + j = 0; + move16(); + FOR(k=sub(bands_fx,SPT_SHORTEN_SBNUM); kprev_SWB_peak_pos_fx[j] = 0; + move16(); + j = add(j, 1); + } + } + } + + /* Spectral energy calculation/quantization */ + ebits_fx = band_energy_dequant_fx( st_fx, L_band_energy, bands_fx, L_qint, eref_fx, *is_transient_fx ); + + /* simple check: band_energy is too large, Abnormal Situation of bit errors */ + FOR( k=0; kBER_detect = 1; + move16(); + set32_fx( L_yout, 0x0L, inner_frame ); + return; + } + } + + /* First pass bit budget for TCQ of spectral band information */ + exp_norm = norm_s(gqlevs_fx); + gqbits_fx = sub(14, exp_norm); + + bit_budget_fx = sub(sub(num_bits, ebits_fx), round_fx(L_shl(L_mult(Ngq_fx, gqbits_fx), 15))); /* (*num_bits) - (short) ceil (ebits) - Ngq * gqbits; */ + + + pbits_fx = 0; + move16(); + test(); + test(); + IF( EQ_16(st_fx->bwidth, SWB)&&(EQ_32(L_bwe_br,HQ_16k40)||EQ_32(L_bwe_br,HQ_13k20))) + { + IF ( EQ_16(hqswb_clas_fx, HQ_HARMONIC)) + { + set16_fx( p2a_flags_fx, 1, har_bands_fx ); + } + ELSE + { + pbits_fx = p2a_threshold_dequant_fx( st_fx, p2a_flags_fx, bands_fx, p2a_bands_fx ); + bit_budget_fx = sub(bit_budget_fx, pbits_fx); + + IF( EQ_16(hqswb_clas_fx, HQ_NORMAL)) + { + return_bits_normal2_fx( &bit_budget_fx, p2a_flags_fx, bands_fx, bits_lagIndices_modeNormal ); + } + } + } + ELSE + { + pbits_fx = p2a_threshold_dequant_fx( st_fx, p2a_flags_fx, bands_fx, p2a_bands_fx ); + bit_budget_fx = sub(bit_budget_fx, pbits_fx); + } + + IF( EQ_16(flag_spt_fx, 1)) + { + /* initialize the desired parameters for SPT */ + spt_shorten_domain_band_save_fx(bands_fx, band_start, band_end, band_width, org_band_start, org_band_end, org_band_width); + spt_shorten_domain_pre_fx(band_start, band_end, hHQ_core->prev_SWB_peak_pos_fx, bands_fx, L_bwe_br, new_band_start, new_band_end, new_band_width); + spt_shorten_domain_set_dec_fx(st_fx, p2a_flags_fx, new_band_start, new_band_end, new_band_width, bands_fx, band_start, band_end, band_width, &bit_budget_fx); + } + + /* safety check in case of bit errors */ + IF( LT_16(bit_budget_fx, 2)) + { + st_fx->BER_detect = 1; + move16(); + set32_fx( L_yout, 0x0, inner_frame ); + return; + } + + Q_band_energy = SWB_BWE_LR_Qbe; + FOR(i = 0; i < bands_fx; i++) + { + L_tmp = L_shl(L_band_energy[i],sub(16,Q_band_energy));/*Q16 */ + + frac1 = L_Extract_lc(L_tmp, &exp); /* Extract exponent of L_tmp */ + L_tmp = Pow2(30, frac1); + exp = sub(exp, 30); + Ep_fx[i] = L_shl(L_tmp , s_max(sub(exp,6), -31)); /* Q -6 */ + } + + FOR( i = 0; i < bands_fx; i++ ) + { + L_tmp2 = Ep_fx[i]; + L_tmp = L_max(1, L_tmp2); + exp = norm_l(L_tmp); + tmp = extract_h(L_shl(L_tmp, exp)); + + L_tmp3 = (Word32)band_width[i]; + exp2 = norm_l(L_tmp3); + tmp2 = extract_h(L_shl(L_tmp3, exp2)); + + exp2 = sub(exp, exp2); /* Denormalize and substract */ + + tmp3 = sub(tmp2, tmp); + if (tmp3 > 0) + { + tmp2 = shr(tmp2, 1); + } + if (tmp3 > 0) + { + exp2 = add(exp2, 1); + } + tmp = div_s(tmp2, tmp); + L_tmp = L_deposit_h(tmp); + L_tmp = Isqrt_lc(L_tmp, &exp2);/*Q(31-exp2) */ + Ep_tmp_fx[i] = L_shr(L_tmp,sub(15,exp2));/*Q13 */ move32(); + } + + test(); + test(); + test(); + test(); + test(); + test(); + IF ( *is_transient_fx == 0 && EQ_16(inner_frame, L_FRAME8k)&&LE_32(st_fx->core_brate,ACELP_13k20)) + { + /* decode the last p2a_bands-1 subbands bit-allocation index of the previous frame */ + j = 0; + FOR(i = 0; i < 2; i++) + { + last_bitalloc_max_band[i] = get_next_indice( st_fx, 1 ); + } + lowband = 6; + move16(); + trans_bit_fx = 2; + move16(); + bit_budget_fx = sub(bit_budget_fx,trans_bit_fx); + gama_fx = 27852; + move16(); /*Q15 0.85f; */ + beta_fx = 17203; + move16(); /*Q14 1.05f; */ + + set16_fx(&p2a_flags_tmp[sub(bands_fx,trans_bit_fx)], 0, 2); + + IF( EQ_32(st_fx->core_brate, ACELP_13k20)) + { + beta_fx = 13107; + move16();/*14 1.25f; */ + gama_fx = 31130; + move16();/*0.95f; */ + Copy(&p2a_flags_fx[sub(bands_fx,trans_bit_fx)], &p2a_flags_tmp[sub(bands_fx,trans_bit_fx)], trans_bit_fx); + } + + /* calculate the the low band/high band energy and the variance/avrage of the envelopes */ + Ep_vari_fx = L_deposit_l(0); + Ep_avrg_fx = L_deposit_l(0); + Ep_avrgL_fx = L_deposit_l(0); + Ep_peak_fx = L_deposit_l(0); + FOR( i = 0; i < bands_fx; i++ ) + { + IF( GE_16(i,lowband)) + { + Ep_vari_fx = L_add(Ep_vari_fx,L_abs(L_sub(Ep_tmp_fx[i],Ep_tmp_fx[sub(i,1)])));/*Q15 */ + Ep_avrg_fx = L_add(Ep_avrg_fx,Ep_tmp_fx[i]);/*Q15 */ + + } + ELSE + { + Ep_avrgL_fx = L_add(Ep_avrgL_fx,Ep_tmp_fx[i]);/*Q15 */ + if(GT_32(Ep_tmp_fx[i],Ep_peak_fx)) + { + Ep_peak_fx = L_add(Ep_tmp_fx[i], 0); /*Q15 */ + } + } + + } + /* modify the last p2a_bands subbands band_energies */ + Copy32( L_band_energy,L_band_energy_tmp,bands_fx ); /*Q_band_energy */ + L_tmp = Mult_32_16(Ep_peak_fx,24576);/*Q(13+14-15 = 12) 1.5 lowband = 6; */ + L_tmp2 =Mult_32_16(Ep_peak_fx,shl(sub(bands_fx,lowband),9));/*Q(13+9-15 = 7) */ + L_tmp3 =Mult_32_16(Ep_avrg_fx,1126);/*Q(13+9-15 = 7) */ + + test(); + test(); + test(); + test(); + IF(( (LT_32(L_tmp, L_shr(Ep_avrgL_fx,1))&&EQ_32(st_fx->core_brate,ACELP_13k20))||LT_32(st_fx->core_brate,ACELP_13k20))&& + LT_32(L_tmp2, L_tmp3) && GT_32(L_tmp2, L_shr(Ep_avrg_fx,7)) ) + { + FOR(i = lowband; i < bands_fx; i++) + { + L_tmp = Mult_32_16(Ep_avrg_fx,24576);/*Q(13+14-15 = 12) 1.5 */ + IF(LT_32(L_shr(Ep_tmp_fx[i],1), L_tmp)) + { + L_tmp = Mult_32_16(Ep_peak_fx,sub(bands_fx,lowband));/*Q(13+0-15 = -2) */ + tmp = Calc_inv(L_shl(L_tmp,14), &exp); + L_tmp = L_shl(Mult_32_16(Ep_avrg_fx,tmp),sub(13,exp));/*Q(13+exp-15 +13-exp +4 = 15) */ + L_tmp2 = L_add(L_tmp,13107); /*15 */ + tmp2 = extract_l(L_min(L_max(L_tmp2,16384),gama_fx)); /*15 = 15 */ + L_band_energy_tmp[i] = Mult_32_16(L_band_energy_tmp[i],tmp2);/*Q(Q_band_energy+15-15 = Q_band_energy) */ move32(); + } + } + } + ELSE + { + FOR(i = sub(bands_fx,trans_bit_fx); i < bands_fx; i++) + { + alpha_fx = 16384; + move16();/*Q14 */ + IF( EQ_16(p2a_flags_tmp[i],1)) + { + L_tmp = Mult_32_16(Ep_tmp_fx[i],sub(bands_fx,lowband));/*Q(13+0-15 = -2) */ + tmp = Calc_inv(L_shl(L_tmp,14), &exp); + L_tmp =Mult_32_16(Ep_vari_fx,3277);/*13+15-15=13 */ + L_tmp = L_shl(Mult_32_16(L_tmp,tmp),sub(12,exp));/*Q(13+exp-15 +12-exp +4 = 14) */ + + tmp2 = extract_h(Ep_avrg_fx);/*Q13-16=-3 */ + IF(tmp2 != 0) + { + exp = norm_s(tmp2); + tmp2 = shl(tmp2,exp);/*Q(exp) */ + tmp2 = div_s(16384,tmp2);/*Q(15+14-exp=29-exp) */ + exp = sub(29,exp); + } + ELSE + { + /*when the divisor is zero, happens rarely*/ + tmp2 = 0x7fff; + move16(); + exp = 0; + move16(); + } + L_tmp2 =Mult_32_16(Ep_vari_fx,6554);/*13+15-15=13 */ + L_tmp2 = L_shl(Mult_32_16(L_tmp2,tmp2),sub(13,exp));/*Q(13+exp-15 +13-exp +3 = 14) */ + L_tmp=L_min(L_tmp,L_tmp2);/*14 */ + tmp=extract_l(L_min(L_tmp,13107));/*14 */ + alpha_fx =add(16384,tmp); + + } + IF(EQ_16(last_bitalloc_max_band[j++], 1)) + { + L_tmp = Mult_32_16(Ep_tmp_fx[i],sub(bands_fx,lowband));/*Q(13+0-15 = -2) */ + tmp = Calc_inv(L_shl(L_tmp,14), &exp); +#ifdef BASOP_NOGLOB + L_tmp = L_shl_sat(Mult_32_16(Ep_avrg_fx, tmp), sub(14, exp));/*Q(13+exp-15 +14-exp+2 = 14) */ +#else + L_tmp = L_shl(Mult_32_16(Ep_avrg_fx,tmp),sub(14,exp));/*Q(13+exp-15 +14-exp+2 = 14) */ +#endif + L_tmp =L_max(L_tmp,16384); /*14 */ + tmp=extract_l(L_min(L_tmp,beta_fx)); /*14 */ + alpha_fx=shl(mult(alpha_fx,tmp),1);/*14+14-15 +1=14 */ + } + ELSE + { + tmp2 = extract_h(Ep_avrg_fx);/*13 -16 =-3 */ + IF(tmp2 != 0) + { + exp = norm_s(tmp2); + tmp2 = shl(tmp2,exp);/*Q(exp) */ + tmp2 = div_s(16384,tmp2);/*Q(15+14-exp=29-exp) */ + exp = sub(29,exp); + } + ELSE + { + /*when the divisor is zero, happens rarely*/ + tmp2 = 0x7fff; + move16(); + exp = 0; + move16(); + } + L_tmp = L_shl(Mult_32_16(Ep_tmp_fx[i],tmp2),sub(19,exp));/*Q(13+exp-15 +19-exp +3 = 20) */ + L_tmp = Mult_32_16(L_tmp,shl(sub(bands_fx,lowband),9));/*20 +9 -15 =14 */ + L_tmp =L_max(L_tmp,13926); /*14 */ + tmp2 =extract_l(L_min(L_tmp,16384)); /*14 */ + alpha_fx=shl(mult(alpha_fx,tmp2),1);/*14+14-15+1 =14 */ + } + L_band_energy_tmp[i] = L_shl(Mult_32_16(L_band_energy_tmp[i],alpha_fx),1);/*Q(Q_band_energy+14-15 +1= Q_band_energy) */ move32(); + } + } + lowband = 3; + move16(); + Ep_avrg_fx = L_deposit_l(0); + Ep_avrgL_fx = L_deposit_l(0); + Ep_peak_fx = L_deposit_l(0); + FOR(i = 0; i < bands_fx; i++) + { + IF(GE_16(i,lowband)) + { + Ep_avrg_fx = L_add(Ep_avrg_fx,Ep_tmp_fx[i]);/*Q15 */ + } + ELSE + { + Ep_avrgL_fx = L_add(Ep_avrgL_fx,L_shr(Ep_tmp_fx[i],1));/*Q12 */ + if(GT_32(Ep_tmp_fx[i],Ep_peak_fx)) + { + Ep_peak_fx = L_add(Ep_tmp_fx[i], 0); /*Q13 */ + } + } + } + L_tmp = Mult_32_16(Ep_peak_fx,28262);/*Q(13+14-15 = 12) 1.725 lowband = 3; */ + L_tmp2 =Mult_32_16(Ep_avrgL_fx,24576);/*Q(12+14-15 = 11) */ + test(); + test(); + IF( GT_32(L_shr(Ep_avrg_fx,2), L_tmp2)&<_32(L_shr(Ep_avrg_fx,4),L_tmp2)&>_32(L_tmp,Ep_avrgL_fx)) + { + adjustFlag = 1; + move16(); + FOR (i = 0; i < lowband; i++) + { + tmp = Calc_inv(Ep_avrgL_fx, &exp); + L_tmp = Mult_32_16(Ep_peak_fx,tmp);/*Q(13+exp-15+4 = exp+2) */ + L_tmp = Mult_32_16(L_tmp,lowband);/*Q(exp+2+0-15 = exp-13) */ + L_tmp = Mult_32_16(L_tmp,18842);/*Q(exp-13+16-16 = exp-13) */ + L_tmp = L_shl(L_tmp,sub(27,exp));/*Q14 0.5 */ + tmp2=extract_l(L_min(L_tmp,19661));/*14 */ + L_tmp = Mult_32_16(L_band_energy_tmp[i],tmp2);/*Q(Q_band_energy+14-15 = Q_band_energy-1) */ + L_band_energy_tmp[i] = L_shl(L_tmp,1); /*Q_band_energy */ move32(); + } + } + hq2_bit_alloc_fx( + L_band_energy_tmp, bands_fx, L_Rk, &bit_budget_fx, p2a_flags_fx, bit_alloc_weight_fx, band_width, + num_bits, hqswb_clas_fx, st_fx->bwidth, *is_transient_fx ); + } + ELSE IF( *is_transient_fx == 0 && EQ_16(inner_frame, L_FRAME16k)) + { + bit_budget_fx = sub(bit_budget_fx,2);/* bits in high bands to indicate the last 2 subbands is allocated bits or not */ + + FOR(i = 0; i < 2; i++) + { + last_bitalloc_max_band[i] = get_next_indice( st_fx, 1 ); + move16(); + } + FOR( i = 0; i < bands_fx; i++ ) + { +#ifdef BASOP_NOGLOB + Ep_tmp_fx[i] = L_shl_sat(Ep_tmp_fx[i],2); +#else + Ep_tmp_fx[i] = L_shl(Ep_tmp_fx[i],2); +#endif + move32(); + } + IF( EQ_32( st_fx->core_brate, ACELP_13k20 )) + { + lowband = 8; + move16(); + highband = 15; + move16(); + bw_low = sub(band_start[highband],band_start[lowband]); + bw_high = sub(add(band_end[sub(bands_fx,1)],1),band_start[highband]); + } + ELSE + { + lowband = 8; + move16(); + highband = 16; + move16(); + bw_low = sub(band_start[highband],band_start[lowband]); + bw_high = sub(add(band_end[sub(bands_fx,1)],1),band_start[highband]); + } + /* calculate the the low band/high band energy and the variance/avrage of the envelopes */ + enerL_fx = L_deposit_l(0); + enerH_fx = L_deposit_l(0); + Ep_vari_fx = L_deposit_l(0); + Ep_avrg_fx = L_deposit_l(0); + FOR( i = 0; i < bands_fx; i++ ) + { + test(); + IF( GE_16(i,lowband)&&add(sub(i,bands_fx),p2a_bands_fx)<0) + { +#ifdef BASOP_NOGLOB + Ep_vari_fx = L_add_sat(Ep_vari_fx, L_abs(L_sub(Ep_tmp_fx[i], Ep_tmp_fx[sub(i, 1)])));/*Q15 */ + Ep_avrg_fx = L_add_sat(Ep_avrg_fx,Ep_tmp_fx[i]);/*Q15 */ +#else + Ep_vari_fx = L_add(Ep_vari_fx, L_abs(L_sub(Ep_tmp_fx[i], Ep_tmp_fx[sub(i, 1)])));/*Q15 */ + Ep_avrg_fx = L_add(Ep_avrg_fx,Ep_tmp_fx[i]);/*Q15 */ +#endif + } + + IF(GE_16(i,highband)) + { +#ifdef BASOP_NOGLOB + enerH_fx = L_add_sat(enerH_fx,L_shl_sat(Ep_fx[i],2));/*Q0 */ +#else + enerH_fx = L_add(enerH_fx,L_shl(Ep_fx[i],2));/*Q0 */ +#endif + } + ELSE IF(GE_16(i,lowband)) + { +#ifdef BASOP_NOGLOB + enerL_fx = L_add_sat(enerL_fx,L_shl_sat(Ep_fx[i],2));/*Q0 */ +#else + enerL_fx = L_add(enerL_fx,L_shl(Ep_fx[i],2));/*Q0 */ +#endif + } + } + + /* modify the last p2a_bands subbands band_energies */ + Copy32( L_band_energy,L_band_energy_tmp,bands_fx ); /*Q_band_energy */ + L_tmp = L_max(enerH_fx,enerL_fx); + tmp = s_max(bw_low,bw_high); + i = norm_l(L_tmp); + j = norm_s(tmp); + L_tmp = Mult_32_16(L_shl(enerH_fx,i), shl(bw_low,j)); /* i + j -15 */ + L_tmp2 = Mult_32_16(L_shl(enerL_fx,i), shl(bw_high,j)); /*i + j -15 */ + L_tmp2 = L_sub(L_tmp,L_tmp2); + FOR( i = sub(bands_fx,p2a_bands_fx); i < bands_fx; i++ ) + { + test(); + IF( EQ_16(p2a_flags_fx[i],1)||L_tmp2>0) + { + tmp = sub(bands_fx,p2a_bands_fx); + tmp = sub(tmp,lowband);/*Q0 */ + + tmp1 = extract_h(L_shl(Ep_avrg_fx,1));/*Q0 */ + IF(tmp1 != 0) + { + exp = norm_s(tmp1); + tmp1 = shl(tmp1,exp);/*Q(exp) */ + tmp1 = div_s(16384,tmp1);/*Q(15+14-exp = 29-exp) */ + exp = sub(29,exp); + } + ELSE + { + /*when the divisor is zero, happens rarely*/ + tmp1 = 0x7fff; + move16(); + exp = 0; + move16(); + } + L_tmp = Mult_32_16(Ep_tmp_fx[i],tmp1);/*Q(15+exp-15 = exp) */ + L_tmp = Mult_32_16(L_tmp,tmp);/*Q(exp+0-15 = exp-15) */ + L_tmp = Mult_32_16(L_tmp,16384);/*Q(exp-15+13-15 = exp-17) */ + L_tmp = L_shl(L_tmp,sub(32,exp));/*Q15 */ + tmp = extract_l(L_min(L_tmp,6554));/*Q15 */ + L_tmp = Mult_32_16(Ep_vari_fx,tmp1);/*Q(15+exp-15 = exp) */ + L_tmp = Mult_32_16(L_tmp,tmp);/*Q(exp+15-15 = exp) */ + L_tmp = L_shl(L_tmp,sub(15,exp));/*Q15 */ + tmp = extract_l(L_shr(L_min(L_tmp,13107),1));/*Q14 */ + + alpha_fx = add(tmp,16384);/*Q14 */ + } + ELSE + { + alpha_fx = 16384; + move16();/*Q14 */ + } + + IF(add(sub(i,bands_fx),p2a_bands_fx) > 0) + { + tmp = sub(bands_fx, p2a_bands_fx); + IF(EQ_16(last_bitalloc_max_band[sub(i, add(tmp, 1))], 1)) + { + tmp = sub(tmp,lowband); + L_tmp = Mult_32_16(Ep_tmp_fx[i],tmp);/*Q(15+0-15 = 0) */ +#ifdef BASOP_NOGLOB + tmp = Calc_inv(L_shl_sat(L_tmp,16), &exp); +#else + tmp = Calc_inv(L_shl(L_tmp,16), &exp); +#endif + L_tmp = Mult_32_16(Ep_avrg_fx,tmp);/*Q(15+exp-15 = exp) */ + L_tmp = L_shl(L_tmp,sub(14,exp));/*Q14 */ + tmp = extract_l(L_min(L_max(L_tmp,16384),20480));/*Q14 */ + L_tmp = L_mult(alpha_fx,tmp);/*Q(14+14+1=29) */ + alpha_fx = extract_l(L_shr(L_tmp,15)); /*Q14 */ + } + ELSE + { + tmp = sub(tmp,lowband); + + tmp1 = extract_h(L_shl(Ep_avrg_fx,1));/*Q0 */ + IF(tmp1 != 0) + { + exp = norm_s(tmp1); + tmp1 = shl(tmp1,exp);/*Q(exp) */ + tmp1 = div_s(16384,tmp1);/*Q(15+14-exp=29-exp) */ + exp = sub(29,exp); + } + ELSE + { + /*when the divisor is zero, happens rarely*/ + tmp1 = 0x7fff; + move16(); + exp = 0; + move16(); + } + L_tmp = Mult_32_16(Ep_tmp_fx[i],tmp1);/*Q(15+exp-15 = exp) */ + L_tmp = Mult_32_16(L_tmp,tmp);/*Q(exp+0-15 = exp-15) */ + L_tmp = L_shl(L_tmp,sub(29,exp));/*Q14 */ + tmp = extract_l(L_min(L_max(L_tmp,13926),16384));/*Q14 */ + L_tmp = L_mult(alpha_fx,tmp);/*Q(14+14+1=29) */ + alpha_fx = extract_l(L_shr(L_tmp,15)); /*Q14 */ + } + } + L_tmp = Mult_32_16(L_band_energy_tmp[i],alpha_fx);/*Q(Q_band_energy+14-15=Q_band_energy-1) */ + L_band_energy_tmp[i] = L_shl(L_tmp,1);/*Q Q_band_energy */ + } + lowband = 6; + move16(); + Ep_avrg_fx = L_deposit_l(0); + Ep_avrgL_fx = L_deposit_l(0); + Ep_peak_fx = L_deposit_l(0); + FOR(i = 0; i < bands_fx; i++) + { + IF(GE_16(i,lowband)) + { +#ifdef BASOP_NOGLOB + Ep_avrg_fx = L_add_sat(Ep_avrg_fx,Ep_tmp_fx[i]);/*Q15 */ +#else + Ep_avrg_fx = L_add(Ep_avrg_fx,Ep_tmp_fx[i]);/*Q15 */ +#endif + } + ELSE + { +#ifdef BASOP_NOGLOB + Ep_avrgL_fx = L_add_sat(Ep_avrgL_fx,Ep_tmp_fx[i]);/*Q15 */ +#else + Ep_avrgL_fx = L_add(Ep_avrgL_fx,Ep_tmp_fx[i]);/*Q15 */ +#endif + if(GT_32(Ep_tmp_fx[i],Ep_peak_fx)) + { + Ep_peak_fx = L_add(Ep_tmp_fx[i], 0); /*Q15 */ + } + } + } + + + L_tmp = Mult_32_16(Ep_peak_fx,24576);/*Q(15+13-15 = 13) lowband = 6; */ + L_tmp2 =Mult_32_16(Ep_peak_fx,19661);/*Q(15+14-15 = 14) */ + L_tmp3 =Mult_32_16(Ep_avrgL_fx,24576);/*Q(15+12-15 = 12) */ + + test(); + test(); + test(); + test(); + test(); + IF( (GT_32(L_shr(Ep_avrgL_fx,1), Ep_avrg_fx)&>_32(L_tmp,L_shr(Ep_avrgL_fx,2))&<_32(L_shr(Ep_avrgL_fx,1),L_tmp2))|| + (GT_32(L_shr(Ep_avrg_fx,1), Ep_avrgL_fx) && LT_32(L_shr(Ep_avrg_fx,3),L_tmp3) && GT_32(L_tmp,L_shr(Ep_avrgL_fx,2)) ) ) + { + adjustFlag = 1; + move16(); + FOR (i = 0; i < lowband; i++) + { + tmp = Calc_inv(L_shl(Ep_avrgL_fx,1), &exp); + L_tmp = Mult_32_16(Ep_peak_fx,tmp);/*Q(15+exp-15 = exp) */ + L_tmp = Mult_32_16(L_tmp,lowband);/*Q(exp+0-15 = exp-15) */ + L_tmp = L_shl(L_tmp,sub(28,exp));/*Q14 0.5 */ + tmp = extract_l(L_min(L_tmp,19661));/*//Q14 */ + L_tmp = Mult_32_16(L_band_energy_tmp[i],tmp);/*Q(Q_band_energy+14-15 = Q_band_energy-1) */ + L_band_energy_tmp[i] = L_shl(L_tmp,1); /*Q_band_energy */ move32(); + } + } + + hq2_bit_alloc_fx( + L_band_energy_tmp, bands_fx, L_Rk, &bit_budget_fx, p2a_flags_fx, bit_alloc_weight_fx, band_width, + num_bits, hqswb_clas_fx, st_fx->bwidth, *is_transient_fx ); + } + ELSE IF( EQ_16(st_fx->bwidth, SWB)&&EQ_16(hqswb_clas_fx,HQ_HARMONIC)&&(EQ_32(L_bwe_br,HQ_16k40)||EQ_32(L_bwe_br,HQ_13k20))) + { + hq2_bit_alloc_har_fx( L_band_energy, bit_budget_fx, bands_fx, L_Rk, p2a_bands_fx, L_bwe_br, p2a_flags_fx, band_width ); + } + ELSE + { + hq2_bit_alloc_fx( + L_band_energy, bands_fx, L_Rk, &bit_budget_fx, p2a_flags_fx, bit_alloc_weight_fx, band_width, + num_bits, hqswb_clas_fx, st_fx->bwidth, *is_transient_fx ); + } + + IF( bit_budget_fx < 0 ) + { + st_fx->BER_detect = 1; + move16(); + bit_budget_fx = 0; + move16(); + } + tcq_core_LR_dec_fx( st_fx, /*inp_vector*/inp_vector_fx, bit_budget_fx, bands_fx, band_start, band_width, /*Rk, */L_Rk, npulses_fx, k_sort_fx, + p2a_flags_fx, p2a_bands_fx, last_bitalloc_max_band, inner_frame, adjustFlag, is_transient_fx ); + + /* Denormalize the coded MDCT spectrum */ + mdct_spectrum_denorm_fx( inp_vector_fx, L_y2, band_start, band_end, band_width, L_band_energy, npulses_fx, bands_fx, ld_slope_fx, pd_thresh_fx ); + + /* Apply fine gain to denormalized coded spectrum */ + mdct_spectrum_fine_gain_dec_fx( st_fx, L_y2, band_start, band_end, k_sort_fx, bands_fx, + L_qint, Ngq_fx, gqlevs_fx, gqbits_fx ); + + test(); + test(); + test(); + /* Restore the band information */ + IF( EQ_16(flag_spt_fx, 1)) + { + spt_shorten_domain_band_restore_fx(bands_fx, band_start, band_end, band_width, org_band_start, org_band_end, org_band_width); + } + + Copy32( L_y2, L_y2_org, L_FRAME32k ); + + /* Inject noise into components having relatively low pulse energy per band */ + ni_seed_fx = add(add(add(npulses_fx[0], npulses_fx[1]), npulses_fx[2]), npulses_fx[3]); + Copy32( L_y2, L_y2_ni, band_end[bands_fx-1]+1 ); + + hq2_noise_inject_fx( L_y2_ni, band_start, band_end, band_width, Ep_fx, L_Rk, npulses_fx, ni_seed_fx, bands_fx, 0, bw_low, bw_high, enerL_fx, enerH_fx, + hHQ_core->last_ni_gain_fx, hHQ_core->last_env_fx, &hHQ_core->last_max_pos_pulse_fx, p2a_flags_fx, p2a_bands_fx, + hqswb_clas_fx, st_fx->bwidth, L_bwe_br ); + + test(); + test(); + IF( EQ_16(st_fx->bwidth, SWB)&&(EQ_32(L_bwe_br,HQ_16k40)||EQ_32(L_bwe_br,HQ_13k20))) + { + test(); + IF( EQ_16(hqswb_clas_fx, HQ_NORMAL)||EQ_16(hqswb_clas_fx,HQ_HARMONIC)) + { + preset_hq2_swb_fx( hqswb_clas_fx, band_end, &har_bands_fx, p2a_bands_fx,length_fx, bands_fx, &lowlength_fx, &highlength_fx, L_m ); + + swb_bwe_dec_lr_fx(st_fx, L_y2, SWB_BWE_LR_Qs, L_m, L_bwe_br, bands_fx, band_start, band_end, L_band_energy, SWB_BWE_LR_Qbe, + p2a_flags_fx, hqswb_clas_fx, lowlength_fx, highlength_fx, har_bands_fx, &hHQ_core->prev_frm_hfe2_fx, &hHQ_core->prev_stab_hfe2_fx + , band_width, L_y2_ni, &ni_seed_fx); + + post_hq2_swb_fx( L_m, lowlength_fx, highlength_fx, hqswb_clas_fx, har_bands_fx, bands_fx, p2a_flags_fx, band_start, band_end, L_y2, npulses_fx ); + + IF( EQ_16(hqswb_clas_fx, HQ_NORMAL)) + { + spt_swb_peakpos_tmp_save_fx(L_y2, bands_fx, band_start, band_end, prev_SWB_peak_pos_tmp_fx); + FOR( k=0; klast_inner_frame, L_FRAME16k)&&st_fx->bws_cnt_fx>0)) + { + k1_fx = sub(bands_fx,2); + if(NE_16(*is_transient_fx,1)) + { + k1_fx = sub(bands_fx,6); + } + L_tmp = L_deposit_l(0); + FOR(i = k1_fx; i < bands_fx; i++) + { + tmp = div_s(1,sub(bands_fx,k1_fx));/*Q15 */ + L_tmp = L_add(L_tmp,Mult_32_16(Ep_tmp_fx[i],tmp));/*Q15 */ + } + st_fx->prev_ener_shb_fx = extract_l(L_shr(L_tmp, 14)); + } + test(); + IF(GE_16(st_fx->last_inner_frame, L_FRAME32k) && st_fx->hBWE_FD != NULL) + { + set16_fx(st_fx->prev_SWB_fenv_fx, st_fx->prev_ener_shb_fx, SWB_FENV); + } + + updat_prev_frm_fx( L_y2, L_yout, L_bwe_br, length_fx, inner_frame, bands_fx, st_fx->bwidth, *is_transient_fx, hqswb_clas_fx, &hHQ_core->prev_hqswb_clas_fx, + hHQ_core->prev_SWB_peak_pos_fx, prev_SWB_peak_pos_tmp_fx, &hHQ_core->prev_frm_hfe2_fx, &hHQ_core->prev_stab_hfe2_fx, st_fx->bws_cnt_fx ); + + return; +} + +/*------------------------------------------------------------------------------------ + * small_symbol_dec_tran_fx() + * + * Huffman decoding of differential energies + *--------------------------------------------------------------------------------------*/ + +static Word16 small_symbol_dec_tran_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + Word16 *qbidx, /* o : output of dequantized differential energy */ + const Word16 bands, /* i : number of bands */ + const Word16 is_transient /* i : transient flag */ +) +{ + Word16 i, bits; + Word16 difidx[BANDS_MAX]; + + /* Decoding differential energies*/ + bits = decode_envelope_indices_fx(st_fx, 0, bands, 0, difidx, LOW_RATE_HQ_CORE_TRAN ,is_transient); + bits = add(bits, BITS_DE_FCOMP); + + /* counting 1 bit for band_energy_huff_coding_mode */ + bits = add(bits, BITS_DE_HMODE); + + /* converting to original values */ + FOR( i=0; i 0 ) + { + *rbits = add(*rbits, s_and(*hufftab, 0xf)); + bit = get_next_indice( st_fx, s_and(*hufftab, 0xf) ); + hufftab += add(shr(*hufftab, 4), bit); + } + + return negate(*hufftab); +} + +static Word16 large_symbol_dec_fx( /* o : bits */ + Decoder_State *st_fx, /* i/o: decoder state structure */ + Word16 *qbidx, /* o : output of dequantized differential energy */ + const Word16 bands /* i : number of bands */ +) +{ + Word16 i, bits; + Word16 LSB[BANDS_MAX]; + Word16 basic_shift,cntbits,ns2mode; + Word16 pos_outlyer; + Word16 ns2mode0,ns2mode1; + + cntbits = BITS_DE_8SMODE; + move16(); + ns2mode = get_next_indice (st_fx, BITS_DE_8SMODE); + + IF ( ns2mode == 0 ) + { + ns2mode0 = get_next_indice (st_fx, BITS_DE_8SMODE_N0); + ns2mode1 = get_next_indice (st_fx, BITS_DE_8SMODE_N1); + cntbits = add(cntbits, BITS_DE_8SMODE_N0+BITS_DE_8SMODE_N1); + + IF ( ns2mode0 == 0 ) + { + IF ( EQ_16(ns2mode1, 1)) + { + pos_outlyer = get_next_indice (st_fx, BITS_DE_8SPOS); + cntbits = add(cntbits, BITS_DE_8SPOS); + qbidx[pos_outlyer] = sub(get_next_indice (st_fx, BITS_ABS_ENG), ABS_ENG_OFFSET); + move16(); + cntbits = add(cntbits, BITS_ABS_ENG); + } + ELSE + { + pos_outlyer = -1; + move16(); + } + + FOR( i=0; i Qbe(Q14) */ + } + + IF (is_transient_fx) + { + reverse_transient_frame_energies_fx( L_band_energy, bands_fx ); + } + + return( deng_bits ); +} + + +/*--------------------------------------------------------------------------* + * p2a_threshold_dequant() + * + * + *--------------------------------------------------------------------------*/ + +static Word16 p2a_threshold_dequant_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + Word16 *p2a_flags, /* o : tonaly indicator */ + const Word16 bands, /* i : number of subbands */ + const Word16 p2a_bands /* i : number of subbnads for computing tonality */ +) +{ + Word16 j, k; + + j = sub(bands, p2a_bands); + FOR( k = 0; k < j; k++ ) + { + p2a_flags[k] = 1; + move16(); + } + + j = 0; + move16(); + FOR( k = sub(bands, p2a_bands); k < bands; k++ ) + { + p2a_flags[k] = get_next_indice( st_fx, 1 ); + move16(); + j = add(j, 1); + } + + return( j ); +} + + +/*--------------------------------------------------------------------------* + * mdct_spectrum_fine_gain_dec() + * + * + *--------------------------------------------------------------------------*/ + +static void mdct_spectrum_fine_gain_dec_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + Word32 L_y2[], /* i/o: Q12 : decoded spectrum */ + const Word16 band_start[], /* i : Q0 : table of start freq for every subband */ + const Word16 band_end[], /* i : Q0 : table of end freq for every subband */ + const Word16 k_sort[], /* i : Q0 : sort table by band_energy */ + const Word16 bands, /* i : Q0 : nubmber of subbands */ + const Word32 L_qint, /* i : Q0 : */ + const Word16 Ngq, /* i : Q0 : */ + const Word16 gqlevs, /* i : Q0 : quantized level */ + const Word16 gqbits /* i : Q0 : quantized bits */ +) +{ + Word16 i, k, imin_fx; + + Word16 delta_fx, Qdelta; + Word32 L_delta; + Word32 L_q; + + Word16 gain_table_fx[MAX_GQLEVS]; + Word16 Qgt; + Word16 gamma_fx; /* Q14 */ + + Word16 exp_normn, exp_normd; + + Word32 L_temp; + Word16 temp_lo_fx, temp_hi_fx; + + /* Fine gain quantization on only the most significant energy bands */ + + exp_normn = norm_l(L_qint); + exp_normn = sub(exp_normn, 1); + exp_normd = norm_s(gqlevs); + delta_fx = div_l(L_shl(L_qint, exp_normn), shl(gqlevs, exp_normd)); + Qdelta = add(sub(exp_normn, exp_normd), 28); /* 29+exp_normn-(exp_normd)-1; */ + L_delta = L_shl(L_deposit_h(delta_fx), sub(13, Qdelta)); + + L_q = L_shr(L_sub(L_delta, L_qint), 1); + + FOR ( i=0; i Q14 */ move16(); + } + + FOR( k = sub(bands, Ngq); k < bands; k++ ) + { + imin_fx = get_next_indice( st_fx, gqbits ); + + /*gamma = gain_table[imin]; */ + gamma_fx = gain_table_fx[imin_fx]; + move16(); + + FOR (i = band_start[k_sort[k]]; i <= band_end[k_sort[k]]; i++) + { + /* This IF statement for keeping same mantissa evenif y2 is plus or minus */ + IF ( L_y2[i] >= 0x0 ) + { + L_y2[i] = L_shl(Mpy_32_16_1(L_y2[i], gamma_fx), 1); + } + ELSE + { + L_y2[i] = L_negate(L_shl(Mpy_32_16_1(L_abs(L_y2[i]), gamma_fx), 1)); + } + } + } + + return; +} diff --git a/lib_dec/igf_dec.c b/lib_dec/igf_dec.c index 49067b9870f0c84e937a80880fe8880cac8e0201..ddc6f3e3d5ea8020fa01a2d7eae84edbd7206445 100644 --- a/lib_dec/igf_dec.c +++ b/lib_dec/igf_dec.c @@ -46,13 +46,13 @@ /*-------------------------------------------------------------------* - * IGF_replaceTCXNoise_1() + * IGF_replaceTCXNoise_1_flr() * * measures TCX noise *-------------------------------------------------------------------*/ /*! r: number of noise bands */ -static int16_t IGF_replaceTCXNoise_1( +static int16_t IGF_replaceTCXNoise_1_flr( const float *in, /* i : MDCT spectrum */ const uint8_t *TCXNoise, /* i : tcx noise indicator vector */ const int16_t start, /* i : start MDCT subband index */ @@ -82,12 +82,12 @@ static int16_t IGF_replaceTCXNoise_1( /*-------------------------------------------------------------------* - * IGF_replaceTCXNoise_2() + * IGF_replaceTCXNoise_2_flt() * * replaces TCX noise *-------------------------------------------------------------------*/ -static void IGF_replaceTCXNoise_2( +static void IGF_replaceTCXNoise_2_flt( float *in, /* i/o: MDCT spectrum */ const uint8_t *TCXNoise, /* i : tcx noise indicator vector */ const int16_t start, /* i : start MDCT subband index */ @@ -127,12 +127,12 @@ static void IGF_replaceTCXNoise_2( /*-------------------------------------------------------------------* - * IGF_replaceTCXNoise_2_new() + * IGF_replaceTCXNoise_2_new_flt() * * *-------------------------------------------------------------------*/ -static void IGF_replaceTCXNoise_2_new( +static void IGF_replaceTCXNoise_2_new_flt( float *in, /* i/o: MDCT spectrum */ const uint8_t *TCXNoise, /* i : tcx noise indicator vector */ const int16_t start, /* i : start MDCT subband index */ @@ -183,12 +183,12 @@ static void IGF_replaceTCXNoise_2_new( /*-------------------------------------------------------------------* - * IGF_decode_whitening_level() + * IGF_decode_whitening_level_flt() * * reads whitening levels *-------------------------------------------------------------------*/ -static void IGF_decode_whitening_level( +static void IGF_decode_whitening_level_flt( Decoder_State *st, /* i : decoder state */ IGF_DEC_PRIVATE_DATA_HANDLE hPrivateData, /* i/o: instance handle of IGF Deccoder */ const int16_t p /* i : tile index, p = [0, 3] */ @@ -220,12 +220,12 @@ static void IGF_decode_whitening_level( /*-------------------------------------------------------------------* - * IGF_getMDCTSquare() + * IGF_getMDCTSquare_flt() * * square the MDCT spectrum *-------------------------------------------------------------------*/ -static void IGF_getMDCTSquare( +static void IGF_getMDCTSquare_flt( const int16_t startLine, /* i : start MDCT subband index */ const int16_t stopLine, /* i : stop MDCT subband index */ const float *pSpectralData, /* i : MDCT spectrum */ @@ -244,12 +244,12 @@ static void IGF_getMDCTSquare( /*-------------------------------------------------------------------* - * IGF_calcSfbEnergy() + * IGF_calcSfbEnergy_flt() * * calculate energy per SFB *-------------------------------------------------------------------*/ -static void IGF_calcSfbEnergy( +static void IGF_calcSfbEnergy_flt( const int16_t startSfb, /* i : start sfb index */ const int16_t stopSfb, /* i : stop sfb index */ const int16_t *swb_offset, /* i : IGF swb offset table */ @@ -275,12 +275,12 @@ static void IGF_calcSfbEnergy( /*-------------------------------------------------------------------* - * IGF_setLinesToZero() + * IGF_setLinesToZero_flt() * * set power spectrum values to zero, needed for energy calculation *-------------------------------------------------------------------*/ -static void IGF_setLinesToZero( +static void IGF_setLinesToZero_flt( const int16_t startLine, /* i : start MDCT subband index */ const int16_t stopLine, /* i : stop MDCT subband index */ const float *pSpectralData, /* i : original MDCT spectrum */ @@ -302,12 +302,12 @@ static void IGF_setLinesToZero( /*-------------------------------------------------------------------* - * IGF_prep() + * IGF_prep_flt() * * prepare IGF spectrum *-------------------------------------------------------------------*/ -static void IGF_prep( +static void IGF_prep_flt( IGF_DEC_PRIVATE_DATA_HANDLE hPrivateData, /* i : IGF private data handle */ const int16_t igfGridIdx, /* i : in case of CELP->TCX switching, use 1.25 framelength */ const uint8_t *TCXNoise, /* i : TCX noise vector */ @@ -377,14 +377,14 @@ static void IGF_prep( { if ( hPrivateData->n_noise_bands ) { - IGF_replaceTCXNoise_2_new( igf_spec, TCXNoise, strt_cpy, stop, hPrivateData->totalNoiseNrg_float, hPrivateData->n_noise_bands, hInfo->nfSeed ); + IGF_replaceTCXNoise_2_new_flt( igf_spec, TCXNoise, strt_cpy, stop, hPrivateData->totalNoiseNrg_float, hPrivateData->n_noise_bands, hInfo->nfSeed ); } } else { if ( hPrivateData->n_noise_bands ) { - IGF_replaceTCXNoise_2( igf_spec, TCXNoise, hGrid->minSrcSubband, hGrid->startLine, hPrivateData->totalNoiseNrg_float, hInfo->nfSeed ); + IGF_replaceTCXNoise_2_flt( igf_spec, TCXNoise, hGrid->minSrcSubband, hGrid->startLine, hPrivateData->totalNoiseNrg_float, hInfo->nfSeed ); } } @@ -396,14 +396,14 @@ static void IGF_prep( { if ( hPrivateData->n_noise_bands_off ) { - IGF_replaceTCXNoise_2_new( src_spec, TCXNoise, strt_cpy, stop, hPrivateData->totalNoiseNrg_off_float, hPrivateData->n_noise_bands_off, hInfo->nfSeed ); + IGF_replaceTCXNoise_2_new_flt( src_spec, TCXNoise, strt_cpy, stop, hPrivateData->totalNoiseNrg_off_float, hPrivateData->n_noise_bands_off, hInfo->nfSeed ); } } else { if ( hPrivateData->n_noise_bands_off ) { - IGF_replaceTCXNoise_2( src_spec, TCXNoise, hGrid->minSrcSubband, hGrid->startLine, hPrivateData->totalNoiseNrg_off_float, hInfo->nfSeed ); + IGF_replaceTCXNoise_2_flt( src_spec, TCXNoise, hGrid->minSrcSubband, hGrid->startLine, hPrivateData->totalNoiseNrg_off_float, hInfo->nfSeed ); } } @@ -425,12 +425,12 @@ static void IGF_prep( /*-------------------------------------------------------------------* - * IGF_prepStereo() + * IGF_prepStereo_flt() * * *-------------------------------------------------------------------*/ -static void IGF_prepStereo( +static void IGF_prepStereo_flt( IGF_DEC_PRIVATE_DATA_HANDLE hPrivateDataL, /* i : IGF private data handle */ IGF_DEC_PRIVATE_DATA_HANDLE hPrivateDataR, /* i : IGF private data handle */ const int16_t igfGridIdx, /* i : in case of CELP->TCX switching, use 1.25 framelength */ @@ -479,7 +479,7 @@ static void IGF_prepStereo( { if ( hPrivateDataL->n_noise_bands ) { - IGF_replaceTCXNoise_2_new( igf_specL, TCXNoiseL, strt_cpy, stop, hPrivateDataL->totalNoiseNrg_float, hPrivateDataL->n_noise_bands, hInfoL->nfSeed ); + IGF_replaceTCXNoise_2_new_flt( igf_specL, TCXNoiseL, strt_cpy, stop, hPrivateDataL->totalNoiseNrg_float, hPrivateDataL->n_noise_bands, hInfoL->nfSeed ); } sel_specL = igf_specL; } @@ -487,7 +487,7 @@ static void IGF_prepStereo( { if ( hPrivateDataL->n_noise_bands_off ) { - IGF_replaceTCXNoise_2_new( igf_specL, TCXNoiseL, strt_cpy, stop, hPrivateDataL->totalNoiseNrg_off_float, hPrivateDataL->n_noise_bands_off, hInfoL->nfSeed ); + IGF_replaceTCXNoise_2_new_flt( igf_specL, TCXNoiseL, strt_cpy, stop, hPrivateDataL->totalNoiseNrg_off_float, hPrivateDataL->n_noise_bands_off, hInfoL->nfSeed ); } sel_specL = src_specL; } @@ -496,7 +496,7 @@ static void IGF_prepStereo( { if ( hPrivateDataR->n_noise_bands ) { - IGF_replaceTCXNoise_2_new( igf_specR, TCXNoiseR, strt_cpy, stop, hPrivateDataR->totalNoiseNrg_float, hPrivateDataR->n_noise_bands, hInfoR->nfSeed ); + IGF_replaceTCXNoise_2_new_flt( igf_specR, TCXNoiseR, strt_cpy, stop, hPrivateDataR->totalNoiseNrg_float, hPrivateDataR->n_noise_bands, hInfoR->nfSeed ); } sel_specR = igf_specR; } @@ -504,7 +504,7 @@ static void IGF_prepStereo( { if ( hPrivateDataR->n_noise_bands_off ) { - IGF_replaceTCXNoise_2_new( igf_specR, TCXNoiseR, strt_cpy, stop, hPrivateDataR->totalNoiseNrg_off_float, hPrivateDataR->n_noise_bands_off, hInfoR->nfSeed ); + IGF_replaceTCXNoise_2_new_flt( igf_specR, TCXNoiseR, strt_cpy, stop, hPrivateDataR->totalNoiseNrg_off_float, hPrivateDataR->n_noise_bands_off, hInfoR->nfSeed ); } sel_specR = src_specR; } @@ -560,7 +560,7 @@ static void IGF_prepStereo( { if ( hPrivateDataL->n_noise_bands ) { - IGF_replaceTCXNoise_2_new( igf_specL, TCXNoiseL, strt_cpy, stop, hPrivateDataL->totalNoiseNrg_float, hPrivateDataL->n_noise_bands, hInfoL->nfSeed ); + IGF_replaceTCXNoise_2_new_flt( igf_specL, TCXNoiseL, strt_cpy, stop, hPrivateDataL->totalNoiseNrg_float, hPrivateDataL->n_noise_bands, hInfoL->nfSeed ); } sel_specL = igf_specL; } @@ -568,7 +568,7 @@ static void IGF_prepStereo( { if ( hPrivateDataL->n_noise_bands_off ) { - IGF_replaceTCXNoise_2_new( igf_specL, TCXNoiseL, strt_cpy, stop, hPrivateDataL->totalNoiseNrg_off_float, hPrivateDataL->n_noise_bands_off, hInfoL->nfSeed ); + IGF_replaceTCXNoise_2_new_flt( igf_specL, TCXNoiseL, strt_cpy, stop, hPrivateDataL->totalNoiseNrg_off_float, hPrivateDataL->n_noise_bands_off, hInfoL->nfSeed ); } sel_specL = src_specL; } @@ -577,7 +577,7 @@ static void IGF_prepStereo( { if ( hPrivateDataR->n_noise_bands ) { - IGF_replaceTCXNoise_2_new( igf_specR, TCXNoiseR, strt_cpy, stop, hPrivateDataR->totalNoiseNrg_float, hPrivateDataR->n_noise_bands, hInfoR->nfSeed ); + IGF_replaceTCXNoise_2_new_flt( igf_specR, TCXNoiseR, strt_cpy, stop, hPrivateDataR->totalNoiseNrg_float, hPrivateDataR->n_noise_bands, hInfoR->nfSeed ); } sel_specR = igf_specR; } @@ -585,7 +585,7 @@ static void IGF_prepStereo( { if ( hPrivateDataR->n_noise_bands_off ) { - IGF_replaceTCXNoise_2_new( igf_specR, TCXNoiseR, strt_cpy, stop, hPrivateDataR->totalNoiseNrg_off_float, hPrivateDataR->n_noise_bands_off, hInfoR->nfSeed ); + IGF_replaceTCXNoise_2_new_flt( igf_specR, TCXNoiseR, strt_cpy, stop, hPrivateDataR->totalNoiseNrg_off_float, hPrivateDataR->n_noise_bands_off, hInfoR->nfSeed ); } sel_specR = src_specR; } @@ -629,12 +629,12 @@ static void IGF_prepStereo( /*-------------------------------------------------------------------* - * IGF_calc() + * IGF_calc_flt() * * calculates IGF energies *-------------------------------------------------------------------*/ -static void IGF_calc( +static void IGF_calc_flt( const IGF_DEC_PRIVATE_DATA_HANDLE hPrivateData, /* i/o: IGF private data handle */ const int16_t igfGridIdx, /* i : in case of CELP->TCX switching, use 1.25 framelength */ const float *spectrum, /* i : MDCT spectrum */ @@ -652,23 +652,23 @@ static void IGF_calc( igf_pN = hPrivateData->igf_pN_float; igf_sN = hPrivateData->igf_sN_float; - IGF_getMDCTSquare( hGrid->startLine, hGrid->stopLine, spectrum, tmp ); - IGF_calcSfbEnergy( hGrid->startSfb, hGrid->stopSfb, hGrid->swb_offset, tmp, igf_sN ); - IGF_getMDCTSquare( hGrid->startLine, hGrid->stopLine, igf_spec, tmp ); - IGF_setLinesToZero( hGrid->startLine, hGrid->stopLine, spectrum, tmp ); - IGF_calcSfbEnergy( hGrid->startSfb, hGrid->stopSfb, hGrid->swb_offset, tmp, igf_pN ); + IGF_getMDCTSquare_flt( hGrid->startLine, hGrid->stopLine, spectrum, tmp ); + IGF_calcSfbEnergy_flt( hGrid->startSfb, hGrid->stopSfb, hGrid->swb_offset, tmp, igf_sN ); + IGF_getMDCTSquare_flt( hGrid->startLine, hGrid->stopLine, igf_spec, tmp ); + IGF_setLinesToZero_flt( hGrid->startLine, hGrid->stopLine, spectrum, tmp ); + IGF_calcSfbEnergy_flt( hGrid->startSfb, hGrid->stopSfb, hGrid->swb_offset, tmp, igf_pN ); return; } /*-------------------------------------------------------------------* - * IGF_appl() + * IGF_appl_flt() * * apply IGF *-------------------------------------------------------------------*/ -static void IGF_appl( +static void IGF_appl_flt( IGF_DEC_PRIVATE_DATA_HANDLE hPrivateData, /* i : IGF private data handle */ const int16_t igfGridIdx, /* i : in case of ACELP->TCX switching, use 1.25 framelength*/ float *pSpectralData, /* i/o: Q31 | MDCT spectrum */ @@ -881,12 +881,12 @@ static void IGF_appl( /*-------------------------------------------------------------------* - * IGF_getWhiteSpectralData() + * IGF_getWhiteSpectralData_flt() * * spectral whitening *-------------------------------------------------------------------*/ -static void IGF_getWhiteSpectralData( +static void IGF_getWhiteSpectralData_flt( const float *in, /* i : MDCT spectrum */ float *out, /* o : whitened spectrum */ const int16_t start, /* i : start MDCT subband index */ @@ -945,12 +945,12 @@ static void IGF_getWhiteSpectralData( /*-------------------------------------------------------------------* - * IGF_RefineGrid() + * IGF_RefineGrid_flt() * * refines the IGF grid *-------------------------------------------------------------------*/ -static void IGF_RefineGrid( +static void IGF_RefineGrid_flt( H_IGF_GRID hGrid /* i/o: IGF grid handle */ ) { @@ -986,12 +986,12 @@ static void IGF_RefineGrid( /*-------------------------------------------------------------------* - * IGFDecReadData() + * IGFDecReadData_flt() * * reads whitening information from the bitstream *-------------------------------------------------------------------*/ -void IGFDecReadData( +void IGFDecReadData_flt( const IGF_DEC_INSTANCE_HANDLE hIGFDec, /* i/o: instance handle of IGF Deccoder */ Decoder_State *st, /* i : decoder state */ const int16_t igfGridIdx, /* i : in case of CELP->TCX switching, use 1.25 framelength */ @@ -1033,7 +1033,7 @@ void IGFDecReadData( } else { - IGF_decode_whitening_level( st, hPrivateData, 0 ); + IGF_decode_whitening_level_flt( st, hPrivateData, 0 ); if ( hPrivateData->igfInfo.bitRateIndex == IGF_BITRATE_SWB_48000_CPE || hPrivateData->igfInfo.bitRateIndex == IGF_BITRATE_FB_48000_CPE ) { tmp = 0; @@ -1047,7 +1047,7 @@ void IGFDecReadData( { for ( p = 1; p < nT; p++ ) { - IGF_decode_whitening_level( st, hPrivateData, p ); + IGF_decode_whitening_level_flt( st, hPrivateData, p ); } } else @@ -1072,13 +1072,13 @@ void IGFDecReadData( /*-------------------------------------------------------------------* - * IGFDecReadLevel() + * IGFDecReadLevel_flt() * * read the IGF level information from the bitstream *-------------------------------------------------------------------*/ /*! r: return igfAllZero flag indicating if no envelope is transmitted */ -int16_t IGFDecReadLevel( +int16_t IGFDecReadLevel_flt( const IGF_DEC_INSTANCE_HANDLE hIGFDec, /* i/o: instance handle of IGF Deccoder */ Decoder_State *st, /* i : decoder state */ const int16_t igfGridIdx, /* i : in case of CELP->TCX switching, use 1.25 framelength */ @@ -1103,11 +1103,11 @@ int16_t IGFDecReadLevel( { mvs2s( hPrivateData->igf_curr, hPrivateData->igf_prev, hGrid->stopSfb ); - IGFSCFDecoderDecode( &hPrivateData->hArithSCFdec, st, &hPrivateData->igf_curr[m_igfSfbStart], igfGridIdx, isIndepFrame ); + IGFSCFDecoderDecode_ivas( &hPrivateData->hArithSCFdec, st, &hPrivateData->igf_curr[m_igfSfbStart], igfGridIdx, isIndepFrame ); } else { - IGFSCFDecoderReset( &hPrivateData->hArithSCFdec ); + IGFSCFDecoderReset_ivas( &hPrivateData->hArithSCFdec ); set_s( &hPrivateData->igf_curr[m_igfSfbStart], 0, hGrid->stopSfb - m_igfSfbStart ); } @@ -1120,12 +1120,12 @@ int16_t IGFDecReadLevel( /*-------------------------------------------------------------------* - * IGFDecApplyMono() + * IGFDecApplyMono_flt() * * apply the IGF decoder in mono *-------------------------------------------------------------------*/ -void IGFDecApplyMono( +void IGFDecApplyMono_flt( const IGF_DEC_INSTANCE_HANDLE hIGFDec, /* i/o: instance handle of IGF Decoder */ float *spectrum, /* i/o: MDCT spectrum */ const int16_t igfGridIdx, /* i : in case of CELP->TCX switching, use 1.25 framelength */ @@ -1182,14 +1182,14 @@ void IGFDecApplyMono( { if ( element_mode == EVS_MONO || !bfi ) { - IGF_getWhiteSpectralData( hPrivateData->pSpecFlat_float, igf_spec, hGrid->minSrcSubband, hGrid->startLine, whiteningLevel ); + IGF_getWhiteSpectralData_flt( hPrivateData->pSpecFlat_float, igf_spec, hGrid->minSrcSubband, hGrid->startLine, whiteningLevel ); } else { mvr2r( hPrivateData->pSpecFlat_float, igf_spec, hGrid->startLine ); } - hPrivateData->n_noise_bands = IGF_replaceTCXNoise_1( igf_spec, hIGFDec->infoTCXNoise, hGrid->minSrcSubband, hGrid->startLine, &hPrivateData->totalNoiseNrg_float ); + hPrivateData->n_noise_bands = IGF_replaceTCXNoise_1_flr( igf_spec, hIGFDec->infoTCXNoise, hGrid->minSrcSubband, hGrid->startLine, &hPrivateData->totalNoiseNrg_float ); break; } } @@ -1198,15 +1198,15 @@ void IGFDecApplyMono( { if ( hPrivateData->currWhiteningLevel[i] == IGF_WHITENING_OFF ) { - hPrivateData->n_noise_bands_off = IGF_replaceTCXNoise_1( hPrivateData->pSpecFlat_float, hIGFDec->infoTCXNoise, hGrid->minSrcSubband, hGrid->startLine, &hPrivateData->totalNoiseNrg_off_float ); + hPrivateData->n_noise_bands_off = IGF_replaceTCXNoise_1_flr( hPrivateData->pSpecFlat_float, hIGFDec->infoTCXNoise, hGrid->minSrcSubband, hGrid->startLine, &hPrivateData->totalNoiseNrg_off_float ); break; } } /* apply IGF in three steps: */ - IGF_prep( hPrivateData, igfGridIdx, hIGFDec->infoTCXNoise, igf_spec, hPrivateData->pSpecFlat_float, element_mode ); - IGF_calc( hPrivateData, igfGridIdx, spectrum, igf_spec ); - IGF_appl( hPrivateData, igfGridIdx, spectrum, igf_spec, hIGFDec->virtualSpec_float, hIGFDec->flag_sparse, 1 ); + IGF_prep_flt( hPrivateData, igfGridIdx, hIGFDec->infoTCXNoise, igf_spec, hPrivateData->pSpecFlat_float, element_mode ); + IGF_calc_flt( hPrivateData, igfGridIdx, spectrum, igf_spec ); + IGF_appl_flt( hPrivateData, igfGridIdx, spectrum, igf_spec, hIGFDec->virtualSpec_float, hIGFDec->flag_sparse, 1 ); } /* reset TCX noise indicator vector */ @@ -1219,12 +1219,12 @@ void IGFDecApplyMono( /*-------------------------------------------------------------------* - * IGFDecApplyStereo() + * IGFDecApplyStereo_flt() * * apply the IGF decoder in stereo *-------------------------------------------------------------------*/ -void IGFDecApplyStereo( +void IGFDecApplyStereo_flt( const IGF_DEC_INSTANCE_HANDLE hIGFDecL, /* i : instance handle of IGF Decoder */ const IGF_DEC_INSTANCE_HANDLE hIGFDecR, /* i : instance handle of IGF Decoder */ float *spectrumL, /* i/o: L MDCT spectrum */ @@ -1289,25 +1289,25 @@ void IGFDecApplyStereo( { if ( !bfi ) { - IGF_getWhiteSpectralData( hPrivateDataL->pSpecFlat_float, igf_specL, hGrid->minSrcSubband, hGrid->startLine, whiteningLevel ); + IGF_getWhiteSpectralData_flt( hPrivateDataL->pSpecFlat_float, igf_specL, hGrid->minSrcSubband, hGrid->startLine, whiteningLevel ); } else { mvr2r( hPrivateDataL->pSpecFlat_float, igf_specL, hGrid->startLine ); } - hPrivateDataL->n_noise_bands = IGF_replaceTCXNoise_1( igf_specL, hIGFDecL->infoTCXNoise, hGrid->minSrcSubband, hGrid->startLine, &hPrivateDataL->totalNoiseNrg_float ); + hPrivateDataL->n_noise_bands = IGF_replaceTCXNoise_1_flr( igf_specL, hIGFDecL->infoTCXNoise, hGrid->minSrcSubband, hGrid->startLine, &hPrivateDataL->totalNoiseNrg_float ); if ( !bfi ) { - IGF_getWhiteSpectralData( hPrivateDataR->pSpecFlat_float, igf_specR, hGrid->minSrcSubband, hGrid->startLine, whiteningLevel ); + IGF_getWhiteSpectralData_flt( hPrivateDataR->pSpecFlat_float, igf_specR, hGrid->minSrcSubband, hGrid->startLine, whiteningLevel ); } else { mvr2r( hPrivateDataR->pSpecFlat_float, igf_specR, hGrid->startLine ); } - hPrivateDataR->n_noise_bands = IGF_replaceTCXNoise_1( igf_specR, hIGFDecR->infoTCXNoise, hGrid->minSrcSubband, hGrid->startLine, &hPrivateDataR->totalNoiseNrg_float ); + hPrivateDataR->n_noise_bands = IGF_replaceTCXNoise_1_flr( igf_specR, hIGFDecR->infoTCXNoise, hGrid->minSrcSubband, hGrid->startLine, &hPrivateDataR->totalNoiseNrg_float ); break; } @@ -1317,20 +1317,20 @@ void IGFDecApplyStereo( { if ( hPrivateDataL->currWhiteningLevel[i] == IGF_WHITENING_OFF || hPrivateDataR->currWhiteningLevel[i] == IGF_WHITENING_OFF ) { - hPrivateDataL->n_noise_bands_off = IGF_replaceTCXNoise_1( hPrivateDataL->pSpecFlat_float, hIGFDecL->infoTCXNoise, hGrid->minSrcSubband, hGrid->startLine, &hPrivateDataL->totalNoiseNrg_off_float ); + hPrivateDataL->n_noise_bands_off = IGF_replaceTCXNoise_1_flr( hPrivateDataL->pSpecFlat_float, hIGFDecL->infoTCXNoise, hGrid->minSrcSubband, hGrid->startLine, &hPrivateDataL->totalNoiseNrg_off_float ); - hPrivateDataR->n_noise_bands_off = IGF_replaceTCXNoise_1( hPrivateDataR->pSpecFlat_float, hIGFDecR->infoTCXNoise, hGrid->minSrcSubband, hGrid->startLine, &hPrivateDataR->totalNoiseNrg_off_float ); + hPrivateDataR->n_noise_bands_off = IGF_replaceTCXNoise_1_flr( hPrivateDataR->pSpecFlat_float, hIGFDecR->infoTCXNoise, hGrid->minSrcSubband, hGrid->startLine, &hPrivateDataR->totalNoiseNrg_off_float ); break; } } /* apply IGF in three steps: */ - IGF_prepStereo( hPrivateDataL, hPrivateDataR, igfGridIdx, hIGFDecL->infoTCXNoise, hIGFDecR->infoTCXNoise, igf_specL, igf_specR, hPrivateDataL->pSpecFlat_float, hPrivateDataR->pSpecFlat_float, coreMsMask ); + IGF_prepStereo_flt( hPrivateDataL, hPrivateDataR, igfGridIdx, hIGFDecL->infoTCXNoise, hIGFDecR->infoTCXNoise, igf_specL, igf_specR, hPrivateDataL->pSpecFlat_float, hPrivateDataR->pSpecFlat_float, coreMsMask ); - IGF_calc( hPrivateDataL, igfGridIdx, spectrumL, igf_specL ); - IGF_calc( hPrivateDataR, igfGridIdx, spectrumR, igf_specR ); - IGF_appl( hPrivateDataL, igfGridIdx, spectrumL, igf_specL, hIGFDecL->virtualSpec_float, hIGFDecL->flag_sparse, bfi_apply_damping ); - IGF_appl( hPrivateDataR, igfGridIdx, spectrumR, igf_specR, hIGFDecR->virtualSpec_float, hIGFDecR->flag_sparse, bfi_apply_damping ); + IGF_calc_flt( hPrivateDataL, igfGridIdx, spectrumL, igf_specL ); + IGF_calc_flt( hPrivateDataR, igfGridIdx, spectrumR, igf_specR ); + IGF_appl_flt( hPrivateDataL, igfGridIdx, spectrumL, igf_specL, hIGFDecL->virtualSpec_float, hIGFDecL->flag_sparse, bfi_apply_damping ); + IGF_appl_flt( hPrivateDataR, igfGridIdx, spectrumR, igf_specR, hIGFDecR->virtualSpec_float, hIGFDecR->flag_sparse, bfi_apply_damping ); } /* reset TCX noise indicator vector */ @@ -1344,12 +1344,12 @@ void IGFDecApplyStereo( /*-------------------------------------------------------------------* - * IGFDecSetMode() + * IGFDecSetMode_flt() * * set mode is used to init the IGF dec with a new bitrate *-------------------------------------------------------------------*/ -void IGFDecSetMode( +void IGFDecSetMode_flt( const IGF_DEC_INSTANCE_HANDLE hIGFDec, /* i : instance handle of IGF Decoder */ const int32_t total_brate, /* i : bitrate */ const int16_t bwidth, /* i : audio bandwidth */ @@ -1364,9 +1364,9 @@ void IGFDecSetMode( hPrivateData = &hIGFDec->igfData; hIGFDec->isIGFActive = 0; - if ( IGFCommonFuncsIGFConfiguration( total_brate, bwidth, element_mode, &hPrivateData->igfInfo, rf_mode ) ) + if (IGFCommonFuncsIGFConfiguration_flt( total_brate, bwidth, element_mode, &hPrivateData->igfInfo, rf_mode ) ) { - IGFSCFDecoderOpen( &hPrivateData->hArithSCFdec, &hPrivateData->igfInfo, total_brate, bwidth, element_mode, rf_mode ); + IGFSCFDecoderOpen_ivas( &hPrivateData->hArithSCFdec, &hPrivateData->igfInfo, total_brate, bwidth, element_mode, rf_mode ); hIGFDec->infoIGFAllZero = 0; hIGFDec->isIGFActive = 1; @@ -1379,9 +1379,9 @@ void IGFDecSetMode( if ( hPrivateData->igfInfo.bitRateIndex != IGF_BITRATE_FB_96000 && hPrivateData->igfInfo.bitRateIndex != IGF_BITRATE_FB_96000_CPE && hPrivateData->igfInfo.bitRateIndex != IGF_BITRATE_FB_128000 && hPrivateData->igfInfo.bitRateIndex != IGF_BITRATE_FB_128000_CPE ) { - IGF_RefineGrid( &hPrivateData->igfInfo.grid[IGF_GRID_LB_NORM] ); - IGF_RefineGrid( &hPrivateData->igfInfo.grid[IGF_GRID_LB_TRAN] ); - IGF_RefineGrid( &hPrivateData->igfInfo.grid[IGF_GRID_LB_SHORT] ); + IGF_RefineGrid_flt( &hPrivateData->igfInfo.grid[IGF_GRID_LB_NORM] ); + IGF_RefineGrid_flt( &hPrivateData->igfInfo.grid[IGF_GRID_LB_TRAN] ); + IGF_RefineGrid_flt( &hPrivateData->igfInfo.grid[IGF_GRID_LB_SHORT] ); } /* IGFDecOutInformation(hIGFDec); */ } @@ -1391,7 +1391,7 @@ void IGFDecSetMode( hIGFDec->infoIGFStartLine = defaultStartLine; hIGFDec->infoIGFStopFreq = -1; hIGFDec->infoIGFStartFreq = -1; - IVAS_ERROR( IVAS_ERR_INTERNAL, "IGFDecSetMode: initialization error!" ); + IVAS_ERROR( IVAS_ERR_INTERNAL, "IGFDecSetMode_flt: initialization error!" ); } hIGFDec->flag_sparse = &hIGFDec->flag_sparseBuf[0]; @@ -1405,12 +1405,12 @@ void IGFDecSetMode( /*-------------------------------------------------------------------* - * IGFDecUpdateInfo() + * IGFDecUpdateInfo_flt() * * updates the start/stop frequency of IGF according to igfGridIdx *-------------------------------------------------------------------*/ -void IGFDecUpdateInfo( +void IGFDecUpdateInfo_flt( const IGF_DEC_INSTANCE_HANDLE hIGFDec, /* i/o: instance handle of IGF Decoder */ const int16_t subFrameIdx, /* i : index of subframe */ const int16_t igfGridIdx /* i : IGF grid index */ @@ -1427,7 +1427,7 @@ void IGFDecUpdateInfo( if ( igfGridIdx == IGF_GRID_LB_SHORT ) { - IGFDecRestoreTCX10SubFrameData( hIGFDec, subFrameIdx ); + IGFDecRestoreTCX10SubFrameData_flt( hIGFDec, subFrameIdx ); } hPrivateData = &hIGFDec->igfData; @@ -1445,12 +1445,12 @@ void IGFDecUpdateInfo( /*-------------------------------------------------------------------* - * IGFDecReplicateTCX10State() + * IGFDecReplicateTCX10State_flt() * * *-------------------------------------------------------------------*/ -void IGFDecReplicateTCX10State( +void IGFDecReplicateTCX10State_flt( IGF_DEC_INSTANCE_HANDLE hIGFDec /* i/o: instance handle of IGF Decoder */ ) { @@ -1466,12 +1466,12 @@ void IGFDecReplicateTCX10State( /*-------------------------------------------------------------------* - * IGFDecCopyLPCFlatSpectrum() + * IGFDecCopyLPCFlatSpectrum_flt() * * copy the LPC flat spectrum to IGF buffer *-------------------------------------------------------------------*/ -void IGFDecCopyLPCFlatSpectrum( +void IGFDecCopyLPCFlatSpectrum_flt( const IGF_DEC_INSTANCE_HANDLE hIGFDec, /* i/o: instance handle of IGF Decoder */ const float *pSpectrumFlat, /* i : LPC flattend spectrum from TCX dec */ const int16_t igfGridIdx /* i : IGF grid index */ @@ -1497,12 +1497,12 @@ void IGFDecCopyLPCFlatSpectrum( /*-------------------------------------------------------------------* - * IGFDecStoreTCX10SubFrameData() + * IGFDecStoreTCX10SubFrameData_flt() * * store the IGF bitstream information for TCX10 subframes *-------------------------------------------------------------------*/ -void IGFDecStoreTCX10SubFrameData( +void IGFDecStoreTCX10SubFrameData_flt( const IGF_DEC_INSTANCE_HANDLE hIGFDec, /* i/o: instance handle of IGF Decoder */ const int16_t subFrameIdx /* i : index of subframe */ ) @@ -1527,12 +1527,12 @@ void IGFDecStoreTCX10SubFrameData( /*-------------------------------------------------------------------* - * IGFDecRestoreTCX10SubFrameData() + * IGFDecRestoreTCX10SubFrameData_flt() * * restore the IGF bitstream information for TCX10 subframes *-------------------------------------------------------------------*/ -void IGFDecRestoreTCX10SubFrameData( +void IGFDecRestoreTCX10SubFrameData_flt( const IGF_DEC_INSTANCE_HANDLE hIGFDec, /* i/o: instance handle of IGF Decoder */ const int16_t subFrameIdx /* i : index of subframe */ ) @@ -1561,12 +1561,12 @@ void IGFDecRestoreTCX10SubFrameData( } /*-----------------------------------------------------------------------* - * init_igf_dec() + * init_igf_dec_flt() * * Initialize IGF decoder parameters *-----------------------------------------------------------------------*/ -void init_igf_dec( +void init_igf_dec_flt( IGF_DEC_INSTANCE_HANDLE hIGFDec /* i/o: IGF decoder handle */ ) { @@ -1585,13 +1585,13 @@ void init_igf_dec( /*-----------------------------------------------------------------------* - * get_igf_startline() + * get_igf_startline_flt() * * *-----------------------------------------------------------------------*/ /*! r: IGF start line */ -int16_t get_igf_startline( +int16_t get_igf_startline_flt( Decoder_State *st, /* i : decoder state */ const int16_t L_frame, /* i : length of the frame */ const int16_t L_frameTCX /* i : full band frame length */ diff --git a/lib_dec/igf_dec_fx.c b/lib_dec/igf_dec_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..24502b0839ec9e52525519f1920be03d527e6351 --- /dev/null +++ b/lib_dec/igf_dec_fx.c @@ -0,0 +1,1786 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include +#include +#include +#include +#include "options.h" +#include "stl.h" +#include "prot_fx1.h" +#include "prot_fx2.h" +#include "cnst.h" +#include "stat_dec.h" +#include "basop_util.h" + +/**********************************************************************/ /* +get scalefactor of an Word32 array with condition +**************************************************************************/ +static Word16 IGF_getScaleFactor32Cond( /**< out: Q0 | measured headroom in range [0..31], 0 if all x[i] == 0 */ + const Word16 *cond, /**< in: Q0 | array conating the condition */ + const Word32 *x, /**< in: Q31 | array containing 32-bit data */ + const Word16 len_x /**< in: Q0 | length of the array to scan */ +) +{ + Word16 i; + Word16 i_min; + Word16 i_max; + Word32 x_min; + Word32 x_max; + Word32 tmp32; + + + x_max = 0; + move32(); + x_min = 0; + move32(); + FOR (i = 0; i < len_x; i++) + { + tmp32 = L_add(x[i], 0); /*L_and(x[i], cond[i]);*/ + + if (cond[i] == 0) + { + tmp32 = L_deposit_h(0); + } + + + if (tmp32>= 0) + { + x_max = L_max(x_max, tmp32); + } + if (tmp32< 0) + { + x_min = L_min(x_min, tmp32); + } + } + + i_max = 0x20; + move16(); + i_min = 0x20; + move16(); + + if (x_max != 0) + { + i_max = norm_l(x_max); + } + if (x_min != 0) + { + i_min = norm_l(x_min); + } + + i = s_and(s_min(i_max, i_min), 0x1F); + + return i; +} + +/**********************************************************************/ /* +measures TCX noise +**************************************************************************/ +static Word16 IGF_replaceTCXNoise_1( /**< out: Q0 | number of noise bands */ + const Word32 *in, /**< in: Q31 | MDCT spectrum */ + Word16 s_l, /**< in: Q0 | noise headroom */ + const Word16 *TCXNoise, /**< in: | tcx noise indicator vector */ + const Word16 start, /**< in: Q0 | start MDCT subband index */ + const Word16 stop, /**< in: Q0 | stop MDCT subband index */ + Word32 *totalNoiseNrg /**< out: | measured noise energy */ +) +{ + Word16 sb; + Word16 tmp16; + Word16 noise; + Word32 nE; + + + tmp16 = 0; + move16(); + noise = 0; + move16(); + s_l = sub(s_l, 5); + nE = 0; + move32(); + + FOR (sb = start; sb < stop; sb++) + { + if (TCXNoise[sb]) + { + tmp16 = extract_h(L_shl(in[sb], s_l)); + } + if (TCXNoise[sb]) + { + nE = L_mac(nE, tmp16, tmp16); + } + if (TCXNoise[sb]) + { + noise = add(noise, 1); + } + } + + *totalNoiseNrg = nE; + move32(); + + return noise; +} + +/**********************************************************************/ /* +replaces TCX noise +**************************************************************************/ +static void IGF_replaceTCXNoise_2(Word32 *in, /**< in/out: | MDCT spectrum */ + const Word16 *TCXNoise, /**< in: Q0 | tcx noise indicator vector */ + const Word16 start, /**< in: Q0 | start MDCT subband index */ + const Word16 stop, /**< in: Q0 | stop MDCT subband index */ + Word32 totalNoiseNrg, /**< in: | measured noise energy */ + const Word16 s_l, /**< in: Q0 | noise headroom */ + Word16 *nfSeed /**< in: | random generator noise seed */ + ) +{ + Word16 sb; + Word16 g; + Word16 val; + Word32 rE; + Word32 L_tmp; + + + val = 0; + move16(); + rE = 0; + move32(); + + FOR (sb = start; sb < stop; sb++) + { + if (TCXNoise[sb]) + { + val = Random(nfSeed); + } + if (TCXNoise[sb]) + { + in[sb] = L_deposit_l(val); + } + if (TCXNoise[sb]) + { + val = shr(val, 5); + } + if (TCXNoise[sb]) + { + rE = L_mac(rE, val, val); + } + } + + totalNoiseNrg = L_shr(totalNoiseNrg, 1); + + + /* make sure that rE is never 0 */ + if (rE == 0) + { + rE = L_add(totalNoiseNrg, 0); /* save move32() -> use L_add(x, 0) = x; */ + } + + /* if totalNoiseNrg == 0, then rE must be at least 0x00010000, otherwise division by 0 will occur */ + if (totalNoiseNrg == 0) + { + rE = L_max(rE, 0x00010000); + } + + /* make sure that rE is never smaller than totalNoiseNrg */ + L_tmp = L_sub(rE, totalNoiseNrg); + if (L_tmp < 0) + { + rE = totalNoiseNrg; /* save move32() -> use L_add(x, 0) = x; */ + move32(); + } + + + g = getSqrtWord32(L_mult(divide3232(totalNoiseNrg, rE), 8192/*1.0f / 4.0f Q15*/)); + g = shl(g, 1); + + FOR (sb = start; sb < stop; sb++) + { + if (TCXNoise[sb]) + { + in[sb] = L_shr(L_mult(extract_l(in[sb]), g), s_l); + move32(); + } + } + +} + +/**********************************************************************/ /* +reads whitening levels +**************************************************************************/ +static void IGF_decode_whitening_level(Decoder_State *st, /**< in: | decoder state */ + IGF_DEC_PRIVATE_DATA_HANDLE hPrivateData, /**< in: | instance handle of IGF Deccoder */ + const Word16 p /**< in: Q0 | tile index, p = [0, 3] */ + ) +{ + Word16 tmp; + + + tmp = get_next_indice(st, 1); + + IF (tmp == 0) + { + hPrivateData->currWhiteningLevel[p] = IGF_WHITENING_MID; + move16(); + + return; + } + + tmp = get_next_indice(st, 1); + hPrivateData->currWhiteningLevel[p] = IGF_WHITENING_STRONG; + move16(); + + if (tmp == 0) + { + hPrivateData->currWhiteningLevel[p] = IGF_WHITENING_OFF; + move16(); + } + +} + +/**********************************************************************/ /* +reads flattening trigger +**************************************************************************/ +static void IGF_decode_temp_flattening_trigger(Decoder_State *st, /**< in: | decoder state */ + IGF_DEC_INSTANCE_HANDLE hInstance /**< in: | instance handle of IGF Deccoder */ + ) +{ + hInstance->flatteningTrigger = get_next_indice(st, 1); +} + +/**********************************************************************/ /* +set power spectrum values to zero, needed for energy calculation +**************************************************************************/ +static void IGF_setLinesToZero(const Word16 startLine, /**< in: Q0 | start MDCT subband index */ + const Word16 stopLine, /**< in: Q0 | stop MDCT subband index */ + const Word32 *pSpectralData, /**< in: | original MDCT spectrum */ + Word32 *pPowerSpecIGF /**< in/out: | prepared IGF energy spectrum */ + ) +{ + Word16 i; + + + /* set energy values in the IGF "power spectrum" to 0, + if there is content in the original MDCT spectrum */ + FOR (i = startLine; i < stopLine; i++) + { + if (pSpectralData[i] != 0) + { + pPowerSpecIGF[i] = L_deposit_l(0); + } + } + +} + +/**********************************************************************/ /* +prepare IGF spectrum +**************************************************************************/ +static void IGF_prep(IGF_DEC_PRIVATE_DATA_HANDLE hPrivateData, /**< in: | IGF private data handle */ + const Word16 igfGridIdx, /**< in: Q0 | in case of CELP->TCX switching, use 1.25 framelength */ + const Word16 *TCXNoise, /**< in: Q0 | TCX noise vector */ + Word32 *igf_spec, /**< in: Q31 | prepared IGF spectrum */ + Word16 *igf_spec_e, /**< in: | array exponents of igf_spec, one exponent per tile */ + const Word32 *src_spec, /**< in: | source spectrum */ + const Word16 src_spec_e, /**< in: | exponent of src_spec, whitening off */ + const Word16 specMed_e /**< in: | exponent of medium flattening level */ + ) +{ + H_IGF_GRID hGrid; + H_IGF_INFO hInfo; + Word16 i; + Word16 tb; + Word16 sfb; + Word16 nTiles; + Word16 n_noise_bands; + Word16 n_noise_bands_off; + Word16 strt_cpy; + Word16 startLine; + Word16 minSrcSubband; + Word16 tile_idx; + Word32 totalNoiseNrg; + Word32 totalNoiseNrg_off; + const Word32 *sel_spec; + + + /* initialize variables */ + hInfo = &hPrivateData->igfInfo; + hGrid = &hPrivateData->igfInfo.grid[igfGridIdx]; + n_noise_bands = hPrivateData->n_noise_bands; + move16(); + n_noise_bands_off = hPrivateData->n_noise_bands_off; + move16(); + totalNoiseNrg = hPrivateData->totalNoiseNrg; + move32(); + totalNoiseNrg_off = hPrivateData->totalNoiseNrg_off; + move32(); + nTiles = hGrid->nTiles; + move16(); + startLine = hGrid->startLine; + move16(); + minSrcSubband = hGrid->minSrcSubband; + move16(); + tile_idx = 0; + move16(); + + FOR (tile_idx = 0; tile_idx < nTiles; tile_idx++) + { + strt_cpy = hGrid->sbWrap[tile_idx]; + move16(); + + /* strong whitening detected */ + IF (EQ_16(IGF_WHITENING_STRONG, hPrivateData->currWhiteningLevel[tile_idx])) + { + Word32 abs_sum; + abs_sum = 0; + move32(); + + FOR(i = strt_cpy; i < hGrid->startLine; i++) + { + abs_sum = L_add(abs_sum, L_abs(src_spec[i])); + } + + /* fill igf_spec with random noise */ + tb = hGrid->swb_offset[hGrid->sfbWrap[tile_idx]]; + move16(); + + IF (abs_sum != 0) + { + FOR (i = strt_cpy; i < startLine; i++) + { + igf_spec[tb++] = L_deposit_l(Random(hInfo->nfSeed)); /* 31Q0, fill LSBs */ + } + } + ELSE + { + FOR (i = strt_cpy; i < startLine; i++) + { + igf_spec[tb++] = 0; + move32(); + } + } + + /* set exponent of the current tile, random noise is 31Q0 */ + igf_spec_e[tile_idx] = 31; + move16(); + } + ELSE + { + /* medium whitening detected */ + IF (EQ_16(IGF_WHITENING_MID, hPrivateData->currWhiteningLevel[tile_idx])) + { + IF (n_noise_bands != 0) + { + IGF_replaceTCXNoise_2(igf_spec, + TCXNoise, + + minSrcSubband, + startLine, + totalNoiseNrg, + hPrivateData->headroom_TCX_noise_white, + hInfo->nfSeed); + } + + /* selected source spectrum is igf_spec, igf_spec contains the whitened signal in the core region */ + sel_spec = igf_spec; + move16(); + + /* set exponent of the current tile */ + igf_spec_e[tile_idx] = specMed_e; + move16(); + } + /* off whitening detectded */ + ELSE + { + IF (n_noise_bands_off != 0) + { + IGF_replaceTCXNoise_2(hPrivateData->pSpecFlat, + TCXNoise, + minSrcSubband, + startLine, + totalNoiseNrg_off, + hPrivateData->headroom_TCX_noise, + hInfo->nfSeed); + + } + /* selected source spectrum is pSpecFlat, pSpecFlat contains the signal before the LPC reshaping */ + sel_spec = src_spec; + move16(); + + /* set exponent of the current tile */ + igf_spec_e[tile_idx] = src_spec_e; + move16(); + } + /* generate the raw IGF spectrum out if the selected spectrum */ + FOR (sfb = hGrid->sfbWrap[tile_idx]; sfb < hGrid->sfbWrap[tile_idx + 1]; sfb++) + { + FOR (tb = hGrid->swb_offset[sfb]; tb < hGrid->swb_offset[sfb + 1]; tb++) + { + igf_spec[tb] = sel_spec[strt_cpy]; + move32(); + strt_cpy = add(strt_cpy, 1); + } + } + } + } + +} + +/**********************************************************************/ /* +calculates IGF energies +**************************************************************************/ +static void IGF_calc(IGF_DEC_PRIVATE_DATA_HANDLE hPrivateData, /**< in: | IGF private data handle */ + const Word16 igfGridIdx, /**< in: Q0 | in case of CELP->TCX switching, use 1.25 framelength */ + const Word32 *spectrum, /**< in: Q31 | MDCT spectrum */ + const Word16 spectrum_e, /**< in: | exponent of pSpectralData */ + Word32 *igf_spec, /**< in: Q31 | prepared IGF spectrum */ + Word16 *igf_spec_e /**< in: | array exponents of igf_spec, one exponent per tile */ + ) +{ + H_IGF_GRID hGrid; + Word16 i; + Word32 *igf_pN; /* Q31 | processed energy */ + Word16 *igf_pN_e; /* | exponents of igf_pN, one for each entry of igf_pN */ + Word32 *igf_sN; /* Q31 | survived energy */ + Word16 *igf_sN_e; /* | exponents of igf_sN, one for each entry of igf_sN */ + Word32 squaredSpectra[IGF_MAX_GRANULE_LEN]; /* Q31 | MDCT^2 spectra */ + Word16 squaredSpectra_e[IGF_MAX_TILES]; /* | exponents of squaredSpectra, one exponent per tile! */ + + + /* initialize variables */ + hGrid = &hPrivateData->igfInfo.grid[igfGridIdx]; + igf_pN = hPrivateData->igf_pN; + igf_pN_e = hPrivateData->igf_pN_e; + igf_sN = hPrivateData->igf_sN; + igf_sN_e = hPrivateData->igf_sN_e; + + set32_fx(squaredSpectra, 0, IGF_MAX_GRANULE_LEN); + set16_fx(squaredSpectra_e, 0, IGF_MAX_TILES); + + /* square the original spectrum */ + IGFCommonFuncsMDCTSquareSpec(hGrid->startLine, + hGrid->stopLine, + spectrum, + spectrum_e, + squaredSpectra, + squaredSpectra_e, + 0); + + /* calculate the energy per SFB of the survied subbands */ + IGFCommonFuncsCalcSfbEnergyPowerSpec(hGrid->startSfb, + hGrid->stopSfb, + hGrid->swb_offset, + squaredSpectra, + squaredSpectra_e, + igf_sN, + igf_sN_e); + + /* loop over tiles, every tile has his own exponent! */ + FOR (i = 0; i < hGrid->nTiles; i++) + { + /* square the prepared IGF spectrum */ + IGFCommonFuncsMDCTSquareSpec(hGrid->tile[i], + hGrid->tile[i + 1], + igf_spec, + igf_spec_e[i], + squaredSpectra, + &squaredSpectra_e[i], + 0); + + /* set all squared values to 0, if the core contains survied lines */ + IGF_setLinesToZero(hGrid->tile[i], + hGrid->tile[i + 1], + spectrum, + squaredSpectra); + + /* calculate the energy per SFB of the processed subbands */ + IGFCommonFuncsCalcSfbEnergyPowerSpec(hGrid->sfbWrap[i], + hGrid->sfbWrap[i + 1], + hGrid->swb_offset, + squaredSpectra, + &squaredSpectra_e[i], + igf_pN, + igf_pN_e); + } + +} + +/**********************************************************************/ /* +apply IGF +**************************************************************************/ +static void IGF_appl(IGF_DEC_PRIVATE_DATA_HANDLE hPrivateData, /**< in: | IGF private data handle */ + const Word16 igfGridIdx, /**< in: Q0 | in case of CELP->TCX switching, use 1.25 framelength */ + Word32 *spectrum, /**< in: Q31 | MDCT spectrum */ + Word16 *spectrum_e, /**< in: | exponent of pSpectralData */ + const Word32 *igf_spec, /**< in: Q31 | prepared IGF spectrum */ + const Word16 *igf_spec_e, /**< in: | array exponents of igf_spec, one exponent per tile */ + Word32 *virtualSpec, /**< out:Q31 | virtual IGF spectrum, used for temp flattening */ + Word16 *virtualSpec_e, /**< out: | exponent of virtualSpec */ + Word16 *flag_sparse /**< out: Q0 | temp flattening indicator */ + ) +{ + H_IGF_GRID hGrid; + Word16 i; + Word16 tb; + Word16 sfb; + Word16 shift; + Word16 s; + Word16 s_sfb; + Word16 start_sfb; + Word16 stop_sfb; + Word16 sfb_p1; + Word16 sfb_m1; + Word16 hopsize; + Word16 sum; + Word16 tileIdx; + Word16 width; /* Q0 | width of the current sfb */ + Word16 width_e; /* | exponent of widthent sfb, initialized as 15! */ + Word16 gFactor; /* 1Q14 | general SCF adaption */ + Word16 fFactor; /* 1Q14 | first SCF adaption */ + Word16 lFactor; /* 1Q14 | last SCF adaption */ + Word16 w0; /* Q15 | float value: 0.201f */ + Word16 w1; /* Q15 | float value: 0.389f */ + Word16 w2; /* Q15 | float value: 0.410f */ + Word16 dE; /* Q31 | energy below igfBgn */ + Word16 dE_e ; /* | exponent of dE */ + Word16 gn; /* Q0 | gain read from bitstream + processing */ + Word16 gn_e; /* | exponent of gn */ + Word16 maxGain_e; /* | maximal gain exponent over sfbs */ + Word16 tmp; + Word16 tmp_e; + Word16 tmp_loop; + Word32 L_tmp; + Word16 L_tmp_e; + Word32 L_tmp2; + Word32 sNlocal; + Word16 sNlocal_e; + Word32 dNlocal; + Word16 dNlocal_e; + Word32 E; + Word16 E_e; + Word32 *sN; + Word16 *sN_e; + Word32 *pN; + Word16 *pN_e; + Word16 gain[IGF_MAX_SFB]; + Word16 gain_e[IGF_MAX_SFB]; + Word16 dN[IGF_MAX_SFB + 1]; + Word16 dN_e[IGF_MAX_SFB + 1]; + Word16 dS[IGF_MAX_SFB]; + Word16 dS_e[IGF_MAX_SFB]; + Word32 energyTmp[24]; + Word32 L_c; + Word16 Hr; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; + Flag Carry = 0; +#endif + + + /* initialize variables */ + w0 = 6586; + move16(); + w1 = 12747; + move16(); + w2 = 13435; + move16(); + dE = 0; + move16(); + dE_e = 0; + move16(); + tmp = 0; + move16(); + s = 0; + move16(); + tmp_e = 0; + move16(); + gn = 0; + move16(); + gn_e = 0; + move16(); + maxGain_e = 0; + move16(); + L_tmp_e = 0; + move16(); + dNlocal_e = 0; + move16(); + L_tmp = 0; + move32(); + dNlocal = 0; + move32(); + + set16_fx(gain, 0, IGF_MAX_SFB); + set16_fx(gain_e, 0, IGF_MAX_SFB); + set16_fx(dN, 0, add(IGF_MAX_SFB,1)); + set16_fx(dN_e, 0, add(IGF_MAX_SFB,1)); + set16_fx(dS, 0, IGF_MAX_SFB); + set16_fx(dS_e, 0, IGF_MAX_SFB); + set32_fx(energyTmp, 0, 24); + + /* more inits */ + hGrid = &hPrivateData->igfInfo.grid[igfGridIdx]; + sN = hPrivateData->igf_sN; + sN_e = hPrivateData->igf_sN_e; + pN = hPrivateData->igf_pN; + pN_e = hPrivateData->igf_pN_e; + start_sfb = hGrid->startSfb; + move16(); + stop_sfb = hGrid->stopSfb; + move16(); + gFactor = hGrid->gFactor; + move16(); + fFactor = hGrid->fFactor; + move16(); + lFactor = hGrid->lFactor; + move16(); + + /* reset virtual spec */ + set16_fx(flag_sparse, 0, N_MAX_TCX-IGF_START_MN); + set32_fx(virtualSpec, 0, N_MAX_TCX-IGF_START_MN); + *virtualSpec_e = *spectrum_e; + move16(); + + /* collect energy below hGrid->startLine: */ + tmp = sub(hGrid->startLine, 24); + IGFCommonFuncsMDCTSquareSpec(tmp, + hGrid->startLine, + spectrum, + *spectrum_e, + energyTmp, + &dE_e, + negate(tmp)); + + L_c = 0; + move32(); + FOR (tb = 0; tb < 24; tb++) + { + Carry = 0; +#ifdef BASOP_NOGLOB /* Critical Carry/Overflow*/ + L_tmp = L_add_co(L_tmp, energyTmp[tb], &Carry, &Overflow); + Overflow = 0; + L_c = L_macNs_co(L_c, 0, 0, &Carry, &Overflow); +#else + L_tmp = L_add_c(L_tmp, energyTmp[tb]); + Overflow = 0; + L_c = L_macNs(L_c, 0, 0); +#endif + } + L_tmp = norm_llQ31(L_c, L_tmp, &shift); + /* float: dE = (float)sqrt(dE / 24.f); basop: */ + shift = add(sub(shift, 4), dE_e); /* x/24 = (x >> 4) * 1/1.5 */ + dE = Sqrt16norm(extract_h(L_tmp), &shift); + dE = mult_r(dE, 26755/*0.81649658092772603273242802490196f Q15*/); /* 0.81649658092772603273242802490196f = sqrt(1/1.5)) */ + dE_e = shift; + move16(); + + /* select correct hopsize for envelope refinement */ + hopsize = 2; + move16(); + if (EQ_16(hPrivateData->currWhiteningLevel[0], IGF_WHITENING_OFF)) + { + hopsize = 4; + move16(); + } + if (EQ_16(hPrivateData->currWhiteningLevel[0], IGF_WHITENING_STRONG)) + { + hopsize = 1; + move16(); + } + hopsize = s_min(hopsize, hPrivateData->igfInfo.maxHopsize); + + IF (hopsize > 1) + { + FOR (sfb = start_sfb; sfb < stop_sfb; sfb += hopsize) + { + tmp_loop = s_min(add(sfb, hopsize), stop_sfb); + FOR (tb = add(sfb, 1); tb < tmp_loop; tb++) + { + sN[sfb] = BASOP_Util_Add_Mant32Exp(sN[sfb], + sN_e[sfb], + sN[tb], + sN_e[tb], + &sN_e[sfb]); + move32(); + pN[sfb] = BASOP_Util_Add_Mant32Exp(pN[sfb], + pN_e[sfb], + pN[tb], + pN_e[tb], + &pN_e[sfb]); + move32(); + sN[tb] = L_deposit_l(0); + pN[tb] = L_deposit_l(0); + } + } + } + + /* IGF_rescale_SCF */ + IF (hGrid->infoIsRefined != 0) + { + FOR (sfb = start_sfb; sfb < stop_sfb; sfb += 2) + { + /* calculate and normalize the width of the current sfb */ + width = sub(hGrid->swb_offset[sfb + 2], hGrid->swb_offset[sfb]); + shift = norm_s(width); + width = shl(width, shift); + width_e = sub(15, shift); /* initial value of width_e is 15, -> width = 15Q0 */ + + /* float: gn = 0.25f * igf_curr - 4.f; basop: */ + gn = hPrivateData->igf_curr[shr(sfb,1)]; + move16(); + move16(); + gn_e = 13; /* set exponent of igf_curr to 13 = 15 - 2; -> igf_curr = igf_curr * 0.25, virtual division by 4 */ + gn = sub(gn, 16); /* 13Q2 | 4 = 16 * 2^(-15 + 13); ("4" has same exponent as igf_curr now) */ + + /* float: tmp = pow(2.f, gn); basop: */ + L_tmp = BASOP_util_Pow2(L_deposit_h(gn), gn_e, &L_tmp_e); + + /* float: tmp = tmp * tmp; basop: */ + tmp = round_fx(L_tmp); + L_tmp = L_mult(tmp, tmp); + L_tmp_e = add(L_tmp_e, L_tmp_e); + + /* get sNlocal | float: sNlocal = sN[ sfb ] + sN[ sfb+ 1 ]; basop: */ + sNlocal = BASOP_Util_Add_Mant32Exp(sN[sfb], + sN_e[sfb], + sN[sfb + 1], + sN_e[sfb + 1], + &sNlocal_e); + + /* float: sNlocal /= width; basop: */ + shift = sub(norm_l(sNlocal), 1); /* leave MSB empty, so in the division sNlocal is always smaller than width */ + sNlocal = L_deposit_h(div_s(extract_h(L_shl(sNlocal, shift)), width)); + sNlocal_e = sub(sub(sNlocal_e, shift), width_e); + + /* float: tmp = max(0.001 * sNlocal, tmp - sNlocal); basop: */ + L_tmp = BASOP_Util_Add_Mant32Exp(L_tmp, + L_tmp_e, + L_negate(sNlocal), + sNlocal_e, + &L_tmp_e); /* float: tmp = tmp - sNlocal */ + + /* max(0.001 * sNlocal, L_tmp) */ + /* Build a threshold and compare with L_tmp. + Build negated threshold and compare with negated L_tmp to cover also fullscale L_tmp case */ + BASOP_SATURATE_WARNING_OFF_EVS +#ifdef BASOP_NOGLOB + L_tmp2 = L_shl_sat(L_negate(Mpy_32_16_1(sNlocal, 33/*0.001f Q15*/)), sub(sNlocal_e, L_tmp_e)); + L_tmp2 = L_sub_sat(L_tmp2, L_negate(L_tmp)); +#else + L_tmp2 = L_shl(L_negate(Mpy_32_16_1(sNlocal, 33/*0.001f Q15*/)), sub(sNlocal_e, L_tmp_e)); + L_tmp2 = L_sub(L_tmp2, L_negate(L_tmp)); +#endif + BASOP_SATURATE_WARNING_ON_EVS + + IF (L_tmp2 < 0) + { + L_tmp = Mpy_32_16_1( sNlocal,33/*0.001f Q15*/); + L_tmp_e = sNlocal_e; + move16(); + } + + /* calc square root of L_tmp and store result in dN */ + L_tmp = Sqrt32(L_tmp, &L_tmp_e); + dN[sfb] = round_fx(L_tmp); + dN_e[sfb] = L_tmp_e; + move16(); + dN[sfb+1] = dN[sfb]; + move16(); + dN_e[sfb+1] = dN_e[sfb]; + move16(); + } + } + ELSE + { + FOR (sfb = start_sfb; sfb < stop_sfb; sfb++) + { + /* calculate and normalize the width of the current sfb */ + width = sub(hGrid->swb_offset[sfb + 1], hGrid->swb_offset[sfb]); + shift = norm_s(width); + width = shl(width, shift); + width_e = sub(15, shift); /* initial value of width_e is 15, -> width = 15Q0 */ + + /* float: gn = 0.25f * igf_curr - 4.f; basop: */ + gn = hPrivateData->igf_curr[sfb]; + move16(); + move16(); + gn_e = 13; /* set exponent of igf_curr to 13 = 15 - 2; -> igf_curr = igf_curr * 0.25, virtual division by 4 */ + gn = sub(gn, 16); /* 13Q2 | 4 = 16 * 2^(-15 + 13); ("4" has same exponent as igf_curr now) */ + + /* float: tmp = pow(2.f, gn); basop: */ + L_tmp = BASOP_util_Pow2(L_deposit_h(gn), gn_e, &L_tmp_e); + + /* float: tmp = tmp * tmp; basop: */ + tmp = round_fx(L_tmp); + L_tmp = L_mult(tmp, tmp); + L_tmp_e = add(L_tmp_e, L_tmp_e); + + /* get sNlocal */ + sNlocal = sN[sfb]; + move32(); + sNlocal_e = sN_e[sfb]; + move16(); + + /* float: sNlocal /= width; basop: */ + shift = sub(norm_l(sNlocal), 1); /* leave MSB empty, so in the division sNlocal is always smaller than width */ + sNlocal = L_deposit_h(div_s(extract_h(L_shl(sNlocal, shift)), width)); + sNlocal_e = sub(sub(sNlocal_e, shift), width_e); + + /* float: tmp = max(0.001 * sNlocal, tmp - sNlocal); basop: */ + L_tmp = BASOP_Util_Add_Mant32Exp(L_tmp, + L_tmp_e, + L_negate(sNlocal), + sNlocal_e, + &L_tmp_e); /* float: tmp = tmp - sNlocal */ + + /* max(0.001 * sNlocal, L_tmp) */ + /* Build a threshold and compare with L_tmp. + Build negated threshold and compare with negated L_tmp to cover also fullscale L_tmp case */ + BASOP_SATURATE_WARNING_OFF_EVS + L_tmp2 = L_shl(L_negate(Mpy_32_16_1(sNlocal, 33/*0.001f Q15*/)), sub(sNlocal_e,L_tmp_e)); + L_tmp2 = L_sub(L_tmp2, L_negate(L_tmp)); + BASOP_SATURATE_WARNING_ON_EVS + + IF (L_tmp2 < 0 ) + { + L_tmp = Mpy_32_16_1(sNlocal,33/*0.001f Q15*/); + L_tmp_e = sNlocal_e; + } + + /* calc square root of L_tmp and store result in dN */ + L_tmp = Sqrt32(L_tmp, &L_tmp_e); + dN[sfb] = round_fx(L_tmp); + dN_e[sfb] = L_tmp_e; + move16(); + } + } + + dS[start_sfb] = dN[start_sfb]; + move16(); + dS_e[start_sfb] = dN_e[start_sfb]; + move16(); + + /* first value with adaption to core energy: */ + tmp_e = BASOP_Util_Add_MantExp(dE, + dE_e, + negate(dN[start_sfb]), + dN_e[start_sfb], + &tmp); /* float: tmp = dE - dN[start_sfb] */ + IF (tmp < 0) + { + /* float: dS[start_sfb] = dN[start_sfb] + fFactor * (dE-dN[start_sfb]); basop: */ + L_tmp = L_mult(fFactor, tmp); + L_tmp_e = add(tmp_e, 1); /* 1Q14 | fFactor is 1Q14 */ + dS_e[start_sfb] = BASOP_Util_Add_MantExp(dN[start_sfb], + dN_e[start_sfb], + round_fx(L_tmp), + L_tmp_e, + &dS[start_sfb]); + move16(); + } + /* last value with less energy: */ + dS[stop_sfb - 1] = mult_r(lFactor, dN[stop_sfb - 1]); + move16(); + move16(); + dS_e[stop_sfb - 1] = add(dN_e[stop_sfb - 1], 1); /* 1Q14 | lFactor is 1Q14 */ + + sfb_p1 = add(start_sfb, 1); + sfb_m1 = sub(stop_sfb, 1); + test(); + IF (hGrid->infoIsRefined != 0 && EQ_16(hopsize, 1)) + { + /* apply filter to absolute energy values: */ + FOR (sfb = sfb_p1; sfb < sfb_m1; sfb++) + { + /* float: dS[sfb] = w0 * dN[sfb-1] + w1 * dN[sfb+0] + w2 * dN[sfb+1]; basop: */ + L_tmp = L_mult(w0, dN[sfb - 1]); + dS[sfb] = round_fx(L_tmp); + move16(); + dS_e[sfb] = dN_e[sfb-1]; /* w0 is Q15, so no need to add an exponent */ + L_tmp = L_mult(w1, dN[sfb]); + dS_e[sfb] = BASOP_Util_Add_MantExp(dS[sfb], + dS_e[sfb], + round_fx(L_tmp), + dN_e[sfb], /* w1 is Q15, so no need to add an exponent */ + &tmp); + move16(); + dS[sfb] = tmp; + move16(); + L_tmp = L_mult(w2, dN[sfb + 1]); + dS_e[sfb] = BASOP_Util_Add_MantExp(dS[sfb], + dS_e[sfb], + round_fx(L_tmp), + dN_e[sfb + 1], /* w2 is Q15, so no need to add an exponent */ + &tmp); + move16(); + dS[sfb] = tmp; + move16(); + } + } + ELSE + { + FOR (sfb = sfb_p1; sfb < sfb_m1; sfb++) + { + dS[sfb] = dN[sfb]; + move16(); + dS_e[sfb] = dN_e[sfb]; + move16(); + } + } + + Hr = 0; + move16(); + tileIdx = -1; + move16(); + FOR (sfb = start_sfb; sfb < stop_sfb; sfb += hopsize) + { + E = 0; + move32(); + E_e = 0; + move16(); + sum = 0; + move16(); + + FOR (tb = 0; tb < hopsize; tb++) + { + /* calculate of the current sfb width */ + width = sub(hGrid->swb_offset[s_min(add(add(sfb, tb), 1), stop_sfb)], /* 15Q0 | width is Q0 */ + hGrid->swb_offset[s_min(add(sfb, tb), stop_sfb)]); + + tmp = dS[s_min(add(sfb, tb), sub(stop_sfb, 1))]; + tmp_e = dS_e[s_min(add(sfb, tb), sub(stop_sfb, 1))]; + + /* square tmp */ + L_tmp = L_mult(tmp, tmp); + L_tmp_e = add(tmp_e, tmp_e); + + /* mult L_tmp times width */ + L_tmp = L_mult(round_fx(L_tmp), width); + L_tmp_e = add(L_tmp_e, 15); /* 15Q0 | width is Q0 */ + + /* calculate resulting energy */ + E = BASOP_Util_Add_Mant32Exp(E, + E_e, + L_tmp, + L_tmp_e, + &E_e); + sum = add(sum, width); /* 15Q0 | sum shares its exponent with width */ + } + + /* normalize sum for the following division */ + shift = norm_s(sum); + sum = shl(sum, shift); /* exponent of sum: sub(15, shift) */ + + /* divide E by sum */ +#ifdef BASOP_NOGLOB /* Critical Carry/Overflow*/ + tmp = div_s(shr(round_fx_o(E, &Overflow), 1), sum); /* shift E 1 bit to the right in order to make it smaller than sum */ +#else + tmp = div_s(shr(round_fx(E), 1), sum); /* shift E 1 bit to the right in order to make it smaller than sum */ +#endif + tmp_e = sub(add(E_e, 1), sub(15, shift)); /* 15Q0 | sum is 15Q0 */ + + /* multiply the result by the hopsize */ + L_tmp = L_mult(tmp, hopsize); + L_tmp_e = add(tmp_e, 15); /* 15Q0 | hopsize is 15Q0 */ + + /* take the square root and store the result in dS */ + L_tmp = Sqrt32(L_tmp, &L_tmp_e); + dS[sfb] = round_fx(L_tmp); + dS_e[sfb] = L_tmp_e; + move16(); + + /* calculate the new dN */ + dN[sfb] = mult_r(gFactor, dS[sfb]); + move16(); + move16(); + dN_e[sfb] = add(dS_e[sfb], 1); /* 1Q14 | gFactor is 1Q14 */ + + /* calculate of the current sfb width */ + width = sub(hGrid->swb_offset[sfb + 1], /* 15Q0 | width is Q0 */ + hGrid->swb_offset[sfb]); + + /* square dN */ + L_tmp = L_mult(dN[sfb], dN[sfb]); + L_tmp_e = add(dN_e[sfb], dN_e[sfb]); + + /* mult L_tmp times width */ + shift = norm_l(L_tmp); + L_tmp = L_shl(L_tmp, shift); + L_tmp = L_mult(round_fx(L_tmp), width); + L_tmp_e = sub(add(L_tmp_e, 15), shift); /* 15Q0 | width is Q0 */ + shift = norm_l(L_tmp); + + /* store normalized result */ + dNlocal = L_shl(L_tmp, shift); + dNlocal_e = sub(L_tmp_e, shift); + + /* gain calculation */ + gain[sfb] = 0; + move16(); + IF (pN[sfb] != 0) + { + tmp = BASOP_Util_Divide3232_Scale(dNlocal, pN[sfb],&s); + s = sub(add(s, dNlocal_e), pN_e[sfb]); + gain[sfb] = Sqrt16(tmp, &s); + move16(); + gain_e[sfb] = s; + move16(); + + + /* get the maximal exponent of the gain array, needed for exponent adjustment of the spectrum */ + maxGain_e = s_max(maxGain_e, gain_e[sfb]); + } + sfb_p1 = add(sfb, 1); + sfb_m1 = s_min(add(sfb, hopsize), stop_sfb); + FOR (s_sfb = sfb_p1; s_sfb < sfb_m1; s_sfb++) + { + gain[s_sfb] = gain[sfb]; + move16(); + gain_e[s_sfb] = gain_e[sfb]; + move16(); + } + + /*--- check gains /spectrum exponents for possible overflows --- */ + /* get tile index */ + if (LE_16(hGrid->sfbWrap[tileIdx + 1], sfb)) + { + tileIdx = add(tileIdx, 1); + } + /*do a test multiplication with the highest possible value*/ + L_tmp = Mpy_32_16_1(0xFFFF8000/*igf_spec occupies only the 16LSBs */, gain[sfb]); + L_tmp_e = add(igf_spec_e[tileIdx], gain_e[sfb]); + /*check whether overflow would occur and calculate Headroom, needed*/ + shift = sub(L_tmp_e, *spectrum_e); + tmp = sub(shift , sub(norm_l(L_tmp), TCX_IMDCT_HEADROOM)); + if (tmp > 0) + { + Hr = s_max(Hr, tmp); + } + + /* disable rescaling if gain is smaler than 1 */ + /* gain < 1, if norm_s(gain[sfb]) >= gain_e[sfb] */ + tmp = sub(norm_s(gain[sfb]), gain_e[sfb]); + if (tmp >= 0) + { + Hr = 0; + move16(); + } + } + + /* Rescale spectrum if overflow may occur */ + tileIdx = -1; + move16(); + IF (Hr > 0) + { + /* rescale virtual Spec, cheap and easy: reset scalingfactor */ + *virtualSpec_e = add(*virtualSpec_e, Hr); + move16(); + + /* rescale spectrum */ + FOR (i = 0; i < hGrid->stopLine; i++) + { + spectrum[i] = L_shr(spectrum[i], Hr); + move16(); + } + *spectrum_e = add(*spectrum_e, Hr); + move16(); + } + + /* tiling */ + tileIdx = -1; + move16(); + FOR (sfb = start_sfb; sfb < stop_sfb; sfb++) + { + /* get tile index */ + if (EQ_16(hGrid->sfbWrap[tileIdx + 1], sfb)) + { + tileIdx = add(tileIdx, 1); + } + + IF (hPrivateData->frameLossCounter > 0) + { + /* normalize gain */ + tmp = norm_s(gain[sfb]); + gain[sfb] = shl(gain[sfb], tmp); + gain_e[sfb] = sub(gain_e[sfb], tmp); + + /* gain[sfb] = min(gain[sfb], 12.f); */ + BASOP_SATURATE_WARNING_OFF_EVS /* threshold, may overflow */ + tmp = shl(gain[sfb], sub(gain_e[sfb], 15 - 5)); /* 10Q5 | tmp is in 10Q5 */ + BASOP_SATURATE_WARNING_ON_EVS + + IF (tmp > 384) /* 10Q5 | 384 = 12 in 10Q5 */ + { + gain[sfb] = 384; + move16(); + gain_e[sfb] = 10; + move16(); + } + + IF (LT_16(hPrivateData->frameLossCounter, 5)) + { + /* gain[sfb] -= gain[sfb] / 8 * hPrivateData->frameLossCounter; -> multiply with 0Q15 -> adaption of the exponent not needed */ + IF (EQ_16(hPrivateData->frameLossCounter, 1)) + { + /* 0Q15 | >> 3 ^= * 0.125 = 1 / 8 */ + gain[sfb] = sub(gain[sfb], shr_r(gain[sfb], 3)); + move16(); + } + ELSE IF (EQ_16(hPrivateData->frameLossCounter, 2)) + { + /* 0Q15 | >> 2 ^= * 0.25 = 2 / 8 */ + gain[sfb] = sub(gain[sfb], shr_r(gain[sfb], 2)); + move16(); + } + ELSE IF (EQ_16(hPrivateData->frameLossCounter, 3)) + { + /* 0Q15 | * 12288 ^= * 0.3750 = 3 / 8 */ + gain[sfb] = sub(gain[sfb], mult_r(gain[sfb], 12288)); + move16(); + } + ELSE + { + /* 0Q15 | >> 1 ^= * 0.5 = 4 / 8 */ + gain[sfb] = sub(gain[sfb], shr_r(gain[sfb], 1)); + move16(); + } + } + ELSE + { + /* gain[sfb] /= 2; -> reduce exponent by 1 */ + gain_e[sfb] = sub(gain_e[sfb], 1); + move16(); + } + } + + FOR (tb = hGrid->swb_offset[sfb]; tb < hGrid->swb_offset[sfb + 1]; tb++) + { + /* multiply the prepared IGF spectrum with the gain */ + L_tmp2 = 0; /* set L_tmp2 to default value */ + move32(); + L_tmp = Mpy_32_16_1(igf_spec[tb], gain[sfb]); + L_tmp_e = add(igf_spec_e[tileIdx], gain_e[sfb]); + + /* store the finalized IGF spectrum */ + IF (spectrum[tb] == 0) + { + shift = sub(L_tmp_e, *spectrum_e); + tmp = norm_l(L_tmp) - shift - 32; + if (tmp < 0) + { + L_tmp2 = L_shl(L_tmp, shift); + } + spectrum[tb] = L_tmp2; + move32(); + flag_sparse[tb-IGF_START_MN] = 1; + move16(); + } + ELSE + { + shift = sub(L_tmp_e, *virtualSpec_e); + tmp = norm_l(L_tmp) - shift - 32; + if (tmp < 0) + { + L_tmp2 = L_shl(L_tmp, shift); + } + virtualSpec[tb-IGF_START_MN] = L_tmp2; + move32(); + flag_sparse[tb-IGF_START_MN] = 2; + move16(); + } + } + } + +} + +/**********************************************************************/ /* +spectral whitening +**************************************************************************/ +static void IGF_getWhiteSpectralData(const Word32 *in, /**< in: Q31 | MDCT spectrum */ + Word16 s_l, /**< in: Q0 | getScaleFactor32() of in */ + Word32 *out, /**< out: Q31| whitened spectrum */ + const Word16 start, /**< in: Q0 | start MDCT subband index */ + const Word16 stop, /**< in: Q0 | stop MDCT subband index */ + const Word16 level /**< in: Q0 | whitening strength */ + ) +{ + Word16 j; + Word32 ak; /* moving average */ + Word32 ak_norm; + Word16 tmp_16; + Word16 div; + Word16 nrm_i; + Word16 nrm_tab[] = {2341 /* 1/14 */, 2521 /* 1/13 */, 2731 /* 1/12 */, 2979 /* 1/11 */, 3277 /* 1/10 */, 3641 /* 1/9 */, 4096 /* 1/8 */, 4681 /* 1/7 */}; + + + /* inits */ + div = 0; + move16(); + s_l = sub(s_l, 2); + ak = 0; + move32(); + + + FOR (j = start - level; j < start + level; j++) + { + tmp_16 = extract_h(L_shl(in[j], s_l)); + ak = L_mac(ak, tmp_16, tmp_16); + } + FOR (j = start; j < stop - level; j++) + { + tmp_16 = extract_h(L_shl(in[j + level], s_l)); + ak = L_mac(ak, tmp_16, tmp_16); + ak_norm = Mpy_32_16_r(ak, 2185); + tmp_16 = sub(31, norm_l(ak_norm)); + + if (ak == 0) + { + tmp_16 = 0; + move16(); + } + + tmp_16 = s_min(14, sub(15, shr(tmp_16, 1))); + div = shl(1, tmp_16); + out[j] = Mpy_32_16_1(L_shl(in[j], s_l), div); + move32(); + + tmp_16 = extract_h(L_shl(in[j - level], s_l)); + ak = L_msu(ak, tmp_16, tmp_16); + } + + nrm_i = 0; + move16(); + + FOR (; j < stop; j++) + { + ak_norm = Mpy_32_16_r(ak, nrm_tab[nrm_i++]); + tmp_16 = sub(31, norm_l(ak_norm)); + + if (ak == 0) + { + tmp_16 = 0; + move16(); + } + + tmp_16 = s_min(14, sub(15, shr(tmp_16, 1))); + div = shl(1, tmp_16); + + if (LT_32(ak, 16)) + { + div = 1; + move16(); + } + + out[j] = Mpy_32_16_1(L_shl(in[j], s_l), div); + move32(); + tmp_16 = extract_h(L_shl(in[j - level], s_l)); + ak = L_msu(ak, tmp_16, tmp_16); + } + +} + +/**********************************************************************/ /* +refines the IGF grid +**************************************************************************/ +static void IGF_RefineGrid(H_IGF_GRID hGrid /**< in/out: | IGF grid handle */ + ) +{ + Word16 a[IGF_MAX_SFB+1]; + Word16 sfb; + Word16 tmp; + Word16 delta; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + + set16_fx(a, 0, IGF_MAX_SFB+1); + + + hGrid->infoIsRefined = 1; + move16(); + FOR (sfb = 0; sfb < hGrid->swb_offset_len; sfb++) + { + tmp = shl(sfb, 1); + a[tmp] = hGrid->swb_offset[sfb]; + move16(); + tmp = add(tmp, 1); + delta = sub(hGrid->swb_offset[sfb+1], hGrid->swb_offset[sfb]); +#ifdef BASOP_NOGLOB /* TBV for 16 kHz, 9.6kbps dtx condition, hGrid->swb_offset[sfb+1] points to an uninit value */ + delta = mac_r(0x00195000, 29491/*0.45f Q16*/, shl_o(delta, 5, &Overflow)); +#else + delta = mac_r(0x00195000, 29491/*0.45f Q16*/, shl(delta, 5)); +#endif + a[tmp] = add(hGrid->swb_offset[sfb], shr(delta, 6)); + move16(); + if (s_and(a[tmp], 1) != 0) + { + a[tmp] = sub(a[tmp], 1); + move16(); + } + } + hGrid->stopSfb = shl(hGrid->stopSfb, 1); + FOR (sfb = 0; sfb <= hGrid->stopSfb; sfb++) + { + hGrid->swb_offset[sfb] = a[sfb]; + move16(); + } + + FOR (sfb = 0; sfb <= hGrid->nTiles; sfb++) + { + hGrid->sfbWrap[sfb] = shl(hGrid->sfbWrap[sfb], 1); + move16(); + } + +} + +/**********************************************************************/ /* +reads whitening information from the bitstream +**************************************************************************/ +void IGFDecReadData(const IGF_DEC_INSTANCE_HANDLE hInstance, /**< in: | instance handle of IGF Deccoder */ + Decoder_State *st, /**< in: | decoder state */ + const Word16 igfGridIdx, /**< in: Q0 | in case of CELP->TCX switching, use 1.25 framelength */ + const Word16 isIndepFrame /**< in: Q0 | if 1: arith dec force reset, if 0: no reset */ + ) +{ + IGF_DEC_PRIVATE_DATA_HANDLE hPrivateData; + H_IGF_GRID hGrid; + Word16 p; + Word16 nT; + Word16 tmp; + + + IF (hInstance != NULL) + { + hPrivateData = &hInstance->igfData; + hGrid = &hPrivateData->igfInfo.grid[igfGridIdx]; + nT = hGrid->nTiles; + move16(); + tmp = 0; + move16(); + + /* set/reset all values to default = IGF_WHITENING_OFF */ + FOR (p = 0; p < IGF_MAX_TILES; p++) + { + hPrivateData->currWhiteningLevel[p] = IGF_WHITENING_OFF; + move16(); + } + + IF (isIndepFrame == 0) + { + tmp = get_next_indice(st, 1); + } + + IF (tmp == 1) + { + FOR (p = 0; p < nT; p++) + { + hPrivateData->currWhiteningLevel[p] = hPrivateData->prevWhiteningLevel[p]; + move16(); + } + } + ELSE + { + IGF_decode_whitening_level(st, hPrivateData, 0); + tmp = get_next_indice(st, 1); + IF (tmp == 1) + { + FOR (p = 1; p < nT; p++) + { + IGF_decode_whitening_level(st, hPrivateData, p); + } + } + ELSE + { + FOR (p = 1; p < nT; p++) + { + hPrivateData->currWhiteningLevel[p] = hPrivateData->currWhiteningLevel[0]; + move16(); + } + } + } + + /* save current level for concealment */ + FOR (p = 0; p < IGF_MAX_TILES; p++) + { + hPrivateData->prevWhiteningLevel[p] = hPrivateData->currWhiteningLevel[p]; + move16(); + } + + /* read flattening trigger from bitstream */ + IGF_decode_temp_flattening_trigger(st, hInstance); + } + +} + +/**********************************************************************/ /* +read the IGF level information from the bitsream +**************************************************************************/ +void IGFDecReadLevel( /**< out: Q0 | return igfAllZero flag indicating if no envelope is transmitted */ + const IGF_DEC_INSTANCE_HANDLE hInstance, /**< in: | instance handle of IGF Decoder */ + Decoder_State *st, /**< in: | decoder state */ + const Word16 igfGridIdx, /**< in: Q0 | in case of CELP->TCX switching, use 1.25 framelength */ + const Word16 isIndepFrame /**< in: Q0 | if 1: arith dec force reset, if 0: no reset */ +) +{ + IGF_DEC_PRIVATE_DATA_HANDLE hPrivateData; + H_IGF_GRID hGrid; + Word16 m_igfSfbStart; + Word16 IGFAllZero; + + IGFAllZero = 1; + move16(); + + IF (hInstance != NULL) + { + hPrivateData = &hInstance->igfData; + hGrid = &hPrivateData->igfInfo.grid[igfGridIdx]; + m_igfSfbStart = hGrid->startSfb; + move16(); + IGFAllZero = get_next_indice(st, 1); + + IF (IGFAllZero == 0) + { + Copy(hPrivateData->igf_curr, hPrivateData->igf_prev, hGrid->stopSfb); + IGFSCFDecoderDecode(&hPrivateData->hArithSCFdec, st, &hPrivateData->igf_curr[m_igfSfbStart],/* 0Q15, hPrivateData->igf_curr = [0, 91] */igfGridIdx, isIndepFrame ); + } + ELSE + { + IGFSCFDecoderReset(&hPrivateData->hArithSCFdec); + set16_fx(&hPrivateData->igf_curr[m_igfSfbStart], 0, sub(hGrid->stopSfb, m_igfSfbStart)); + } + } + + hInstance->infoIGFAllZero = IGFAllZero; + move16(); +} + +/**********************************************************************/ /* +apply the IGF decoder +**************************************************************************/ +void IGFDecApplyMono(const IGF_DEC_INSTANCE_HANDLE hInstance, /**< in: | instance handle of IGF Decoder */ + Word32 *spectrum, /**< in/out: | MDCT spectrum */ + Word16 *spectrum_e, /**< in/out: | exponent of spectrum */ + const Word16 igfGridIdx, /**< in: | in case of CELP->TCX switching, use 1.25 framelength */ + Word16 bfi /**< in: | frame loss == 1, frame good == 0 */ + ) +{ + IGF_DEC_PRIVATE_DATA_HANDLE hPrivateData; + H_IGF_GRID hGrid; + Word16 i; + Word16 whiteningLevel; + Word16 s_l; /* | headroom of pSpecFlat */ + Word16 specMed_e; /* | exponent of the medium whitened spectrum */ + Word32 igf_spec[IGF_MAX_GRANULE_LEN]; /* Q31 | prepared IGF spectrum */ + Word16 igf_spec_e[IGF_MAX_TILES]; /* | exponents of igf_spec, one exponent per tile */ + + + hPrivateData = &hInstance->igfData; + hGrid = &hPrivateData->igfInfo.grid[igfGridIdx]; + + /* initialize variables */ + whiteningLevel = 7; + move16(); + specMed_e = 0; + move16(); + hPrivateData->n_noise_bands = 0; + move16(); + hPrivateData->n_noise_bands_off = 0; + move16(); + hPrivateData->headroom_TCX_noise_white = 0; + move16(); + hPrivateData->headroom_TCX_noise = 0; + move16(); + hPrivateData->totalNoiseNrg = 0; move32(); + hPrivateData->totalNoiseNrg_off = 0; move32(); + + set32_fx(igf_spec, 0, IGF_MAX_GRANULE_LEN); + set16_fx(igf_spec_e, 0, IGF_MAX_TILES); + + /* concealment counter */ + IF (bfi != 0) + { + hPrivateData->frameLossCounter = add(hPrivateData->frameLossCounter, 1); + } + ELSE + { + hPrivateData->frameLossCounter = 0; + } + + /* skip IGF processing if all IGF levels are zero */ + IF (hInstance->infoIGFAllZero == 0) + { + + + FOR (i = 0; i < hGrid->nTiles; i++) + { + IF (EQ_16(hPrivateData->currWhiteningLevel[i], IGF_WHITENING_MID)) + { + s_l = getScaleFactor32(hPrivateData->pSpecFlat + hGrid->minSrcSubband - whiteningLevel, + add(sub(hGrid->startLine, hGrid->minSrcSubband), whiteningLevel)); + + specMed_e = hPrivateData->pSpecFlat_exp; + move16(); + IGF_getWhiteSpectralData(hPrivateData->pSpecFlat, + s_l, + igf_spec, + hGrid->minSrcSubband, + hGrid->startLine, + whiteningLevel); + + /*14 seems to be precise enough*/ + hPrivateData->headroom_TCX_noise_white = IGF_getScaleFactor32Cond(hInstance->infoTCXNoise_evs + hGrid->minSrcSubband, + igf_spec + hGrid->minSrcSubband, + sub(hGrid->startLine, hGrid->minSrcSubband)); + hPrivateData->n_noise_bands = IGF_replaceTCXNoise_1(igf_spec, + hPrivateData->headroom_TCX_noise_white, + hInstance->infoTCXNoise_evs, + hGrid->minSrcSubband, + hGrid->startLine, + &hPrivateData->totalNoiseNrg); + + BREAK; + } + } + + FOR (i = 0; i < hGrid->nTiles; i++) + { + IF (hPrivateData->currWhiteningLevel[ i ] == IGF_WHITENING_OFF) + { + hPrivateData->headroom_TCX_noise = IGF_getScaleFactor32Cond(hInstance->infoTCXNoise_evs + hGrid->minSrcSubband, + hPrivateData->pSpecFlat + hGrid->minSrcSubband, + sub(hGrid->startLine, hGrid->minSrcSubband)); + + hPrivateData->n_noise_bands_off = IGF_replaceTCXNoise_1(hPrivateData->pSpecFlat, + hPrivateData->headroom_TCX_noise, + hInstance->infoTCXNoise_evs, + hGrid->minSrcSubband, + hGrid->startLine, + &hPrivateData->totalNoiseNrg_off); + BREAK; + } + } + + /* apply IGF in three steps: */ + IGF_prep(hPrivateData, + igfGridIdx, + hInstance->infoTCXNoise_evs, + igf_spec, + igf_spec_e, + hPrivateData->pSpecFlat, + hPrivateData->pSpecFlat_exp, + specMed_e); + IGF_calc(hPrivateData, + igfGridIdx, + spectrum, + *spectrum_e, + igf_spec, + igf_spec_e); + IGF_appl(hPrivateData, + igfGridIdx, + spectrum, + spectrum_e, + igf_spec, + igf_spec_e, + hInstance->virtualSpec, + &hInstance->virtualSpec_e, + hInstance->flag_sparseBuf); + + } + + /* reset TCX noise indicator vector */ + set16_fx(hInstance->infoTCXNoise_evs, 0, IGF_START_MX); + +} + +/**********************************************************************/ /* +set mode is used to init the IGF dec with a new bitrate +**************************************************************************/ +void IGFDecSetMode( + const IGF_DEC_INSTANCE_HANDLE hIGFDec, /* o : instance handle of IGF Decoder */ + const Word32 total_brate, /* i : bitrate */ + const Word16 bwidth, /* i : audio bandwidth */ + const Word16 element_mode, /* i : IVAS element mode */ + const Word16 defaultStartLine, /* i : default start subband index */ + const Word16 defaultStopLine, /* i : default stop subband index */ + const Word16 rf_mode /* i : flag to signal the RF mode */ +) +{ + IGF_DEC_PRIVATE_DATA_HANDLE hPrivateData; + + + hPrivateData = &hIGFDec->igfData; + hIGFDec->isIGFActive = 0; + move16(); + + IF (IGFCommonFuncsIGFConfiguration(total_brate, bwidth, element_mode, &hPrivateData->igfInfo, rf_mode) != 0) + { + IGFSCFDecoderOpen(&hPrivateData->hArithSCFdec, &hPrivateData->igfInfo, total_brate, bwidth, element_mode, rf_mode); + + hIGFDec->infoIGFStopLine = hPrivateData->igfInfo.grid[0].stopLine; + move16(); + hIGFDec->infoIGFStartLine = hPrivateData->igfInfo.grid[0].startLine; + move16(); + hIGFDec->infoIGFStopFreq = hPrivateData->igfInfo.grid[0].stopFrequency; + move16(); + hIGFDec->infoIGFStartFreq = hPrivateData->igfInfo.grid[0].startFrequency; + move16(); + hIGFDec->infoIGFAllZero = 0; + move16(); + hIGFDec->isIGFActive = 1; + move16(); + + test(); + IF ((LE_16(hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_SWB_48000))||(LE_16(hPrivateData->igfInfo.bitRateIndex,IGF_BITRATE_FB_48000))) + { + IGF_RefineGrid(&hPrivateData->igfInfo.grid[IGF_GRID_LB_NORM]); + IGF_RefineGrid(&hPrivateData->igfInfo.grid[IGF_GRID_LB_TRAN]); + IGF_RefineGrid(&hPrivateData->igfInfo.grid[IGF_GRID_LB_SHORT]); + } + } + ELSE + { + hIGFDec->infoIGFStopLine = defaultStopLine; + move16(); + hIGFDec->infoIGFStartLine = defaultStartLine; + move16(); + hIGFDec->infoIGFStopFreq = -1; + move16(); + hIGFDec->infoIGFStartFreq = -1; + move16(); + fprintf(stderr,"IGFDecSetMode: initialization error!\n"); + } + +} + +/**********************************************************************/ /* +updates the start/stop frequency of IGF according to igfGridIdx +**************************************************************************/ +void IGFDecUpdateInfo(const IGF_DEC_INSTANCE_HANDLE hInstance, /**< in: | instance handle of IGF Decoder */ + const Word16 igfGridIdx /**< in: | IGF grid index */ + ) +{ + IGF_DEC_PRIVATE_DATA_HANDLE hPrivateData; + H_IGF_GRID hGrid; + + + hPrivateData = &hInstance->igfData; + IF (hInstance->isIGFActive != 0) + { + hGrid = &hPrivateData->igfInfo.grid[igfGridIdx]; + hInstance->infoIGFStartFreq = hGrid->startFrequency; + move16(); + hInstance->infoIGFStopFreq = hGrid->stopFrequency; + move16(); + hInstance->infoIGFStartLine = hGrid->startLine; + move16(); + hInstance->infoIGFStopLine = hGrid->stopLine; + move16(); + } +} + +/**********************************************************************/ /* +copy the LPC flat spectrum to IGF buffer +**************************************************************************/ +void IGFDecCopyLPCFlatSpectrum(const IGF_DEC_INSTANCE_HANDLE hInstance, /**< in: | instance handle of IGF Decoder */ + const Word32 *pSpectrumFlat, /**< in: Q31 | LPC flattend spectrum from TCX dec */ + const Word16 pSpectrumFlat_exp, /**< in: | exponent of pSpectrumFlat */ + const Word16 igfGridIdx /**< in: Q0 | IGF grid index */ + ) +{ + IGF_DEC_PRIVATE_DATA_HANDLE hPrivateData; + H_IGF_GRID hGrid; + + + IF (hInstance) + { + hPrivateData = &hInstance->igfData; + hGrid = &hPrivateData->igfInfo.grid[igfGridIdx]; + + + /* pSpectrumFlat_exp has to be multiplied with 1024 = 2^10 go achive proper gain values */ + hPrivateData->pSpecFlat_exp = add(pSpectrumFlat_exp, 10); + move16(); + + Copy32(pSpectrumFlat, hPrivateData->pSpecFlat, hGrid->startLine); + } + +} + +/**********************************************************************/ /* +store the IGF bitstream information for TCX10 subframes +**************************************************************************/ +void IGFDecStoreTCX10SubFrameData(const IGF_DEC_INSTANCE_HANDLE hInstance, /**< in: | instance handle of IGF Decoder */ + const Word16 subFrameIdx /**< in: Q0 | index of subframe */ + ) +{ + IGF_DEC_PRIVATE_DATA_HANDLE hPrivateData; + + + hPrivateData = &hInstance->igfData; + + /* store igf energies for subframe*/ + Copy(hPrivateData->igf_curr, hPrivateData->igf_curr_subframe[subFrameIdx][0], IGF_MAX_SFB); + Copy(hPrivateData->igf_prev, hPrivateData->igf_prev_subframe[subFrameIdx], IGF_MAX_SFB); + + /* store spectral whitening information for current subframe */ + Copy(hPrivateData->currWhiteningLevel, hPrivateData->currWhiteningLevel_subframe[subFrameIdx], IGF_MAX_TILES); + Copy(hPrivateData->prevWhiteningLevel, hPrivateData->prevWhiteningLevel_subframe[subFrameIdx], IGF_MAX_TILES); + /* store flattening trigger for current subframe */ + hPrivateData->igf_flatteningTrigger_subframe[subFrameIdx] = hInstance->flatteningTrigger; + move16(); + +} + +/**********************************************************************/ /* +restore the IGF bitstream information for TCX10 subframes +**************************************************************************/ +void IGFDecRestoreTCX10SubFrameData(const IGF_DEC_INSTANCE_HANDLE hInstance, /**< in: | instance handle of IGF Decoder */ + const Word16 subFrameIdx /**< in: Q0 | index of subframe */ + ) +{ + IGF_DEC_PRIVATE_DATA_HANDLE hPrivateData; + + + hPrivateData = &hInstance->igfData; + + /* store igf energies for subframe*/ + Copy(hPrivateData->igf_curr_subframe[subFrameIdx][0], hPrivateData->igf_curr, IGF_MAX_SFB); + Copy(hPrivateData->igf_prev_subframe[subFrameIdx], hPrivateData->igf_prev, IGF_MAX_SFB); + + /* store spectral whitening information for current subframe */ + Copy(hPrivateData->currWhiteningLevel_subframe[subFrameIdx], hPrivateData->currWhiteningLevel, IGF_MAX_TILES); + Copy(hPrivateData->prevWhiteningLevel_subframe[subFrameIdx], hPrivateData->prevWhiteningLevel, IGF_MAX_TILES); + /* restore flattening trigger for current subframe */ + hInstance->flatteningTrigger = hPrivateData->igf_flatteningTrigger_subframe[subFrameIdx]; + move16(); + +} +/*-----------------------------------------------------------------------* + * init_igf_dec() + * + * Initialize IGF decoder parameters + *-----------------------------------------------------------------------*/ +void init_igf_dec( + IGF_DEC_INSTANCE_HANDLE hIGFDec /* i/o: IGF decoder handle */ +) +{ + set16_fx(hIGFDec->infoTCXNoise_evs, 0, IGF_START_MX); + set16_fx(hIGFDec->flag_sparseBuf, 0, N_MAX_TCX - IGF_START_MN); + set32_fx(hIGFDec->virtualSpec, 0, N_MAX_TCX - IGF_START_MN); + hIGFDec->virtualSpec_e = 0; + hIGFDec->infoIGFStopFreq = -1; + move16(); + hIGFDec->infoIGFStartFreq = -1; + move16(); + hIGFDec->flatteningTrigger = -1; + move16(); + hIGFDec->infoIGFStartLine = -1; + move16(); + hIGFDec->isIGFActive = -1; + move16(); + hIGFDec->infoIGFAllZero = 0; + move16(); + hIGFDec->infoIGFStopLine = -1; + move16(); + hIGFDec->infoIGFStartLine = -1; + move16(); + + return; +} diff --git a/lib_dec/igf_scf_dec.c b/lib_dec/igf_scf_dec.c index 11c6f0845bc76b0e0b164226d4825eee34e50167..a5b1760dcaf510b41b5a3e58005f0bec9555fbc8 100644 --- a/lib_dec/igf_scf_dec.c +++ b/lib_dec/igf_scf_dec.c @@ -42,12 +42,12 @@ /*---------------------------------------------------------------------* - * IGFSCFDecoderOpen() + * IGFSCFDecoderOpen_ivas() * * initialization of an instance of this module, pass a ptr to a hPublicData *---------------------------------------------------------------------*/ -void IGFSCFDecoderOpen( +void IGFSCFDecoderOpen_ivas( IGFSCFDEC_INSTANCE_HANDLE hPublicData, /* i/o: handle to public data */ H_IGF_INFO hIgfInfo, /* i : IGF info handle */ const int32_t total_brate, @@ -62,7 +62,7 @@ void IGFSCFDecoderOpen( hPublicData->scfCountLongBlock[2] = hIgfInfo->grid[2].swb_offset_len - 1; hPublicData->t = 0; /* protect against the invalid request of starting decoding with a dependent block */ - IGFCommonFuncsIGFGetCFTables( total_brate, bwidth, element_mode, rf_mode, &hPublicData->cf_se00, &hPublicData->cf_se01, &hPublicData->cf_off_se01, &hPublicData->cf_se02, &hPublicData->cf_off_se02, &hPublicData->cf_se10, &hPublicData->cf_off_se10, &hPublicData->cf_se11, &hPublicData->cf_off_se11 ); + IGFCommonFuncsIGFGetCFTables_flt( total_brate, bwidth, element_mode, rf_mode, &hPublicData->cf_se00, &hPublicData->cf_se01, &hPublicData->cf_off_se01, &hPublicData->cf_se02, &hPublicData->cf_off_se02, &hPublicData->cf_se10, &hPublicData->cf_off_se10, &hPublicData->cf_se11, &hPublicData->cf_off_se11 ); return; } @@ -114,7 +114,7 @@ static int16_t arith_decode_bits( for ( i = 0; i < nBits; ++i ) { /* decode one bit using the new raw AC function */ - ari_decode_14bits_bit_ext( st, &bit, ac_state ); + ari_decode_14bits_bit_ext_ivas( st, &bit, ac_state ); x = ( x << 1 ) | bit; } @@ -139,7 +139,7 @@ static int16_t arith_decode_residual( int16_t x, extra, extra_tmp; /* decode one of the IGF_SYMBOLS_IN_TABLE == 27 alphabet symbols using the new raw AC function */ - ari_decode_14bits_s27_ext( st, &val, ac_state, cumulativeFrequencyTable ); + ari_decode_14bits_s27_ext_ivas( st, &val, ac_state, cumulativeFrequencyTable ); /* meaning of the values of val: */ /* esc_{0} IGF_MIN_ENC_SEPARATE ... IGF_MAX_ENC_SEPARATE esc_{IGF_SYMBOLS_IN_TABLE - 1} */ @@ -218,7 +218,7 @@ static void decode_sfe_vector( if ( f == 0 ) { /* decode one of the IGF_SYMBOLS_IN_TABLE == 27 alphabet symbols using the new raw AC function */ - ari_decode_14bits_s27_ext( st, &pred, &hPrivateData->acState, hPrivateData->cf_se00 ); + ari_decode_14bits_s27_ext_ivas( st, &pred, &hPrivateData->acState, hPrivateData->cf_se00 ); x[f] = pred << 2; x[f] += arith_decode_bits( &hPrivateData->acState, st, 2 ); /* LSBs as 2 bit raw */ } @@ -269,12 +269,12 @@ static void decode_sfe_vector( /*---------------------------------------------------------------------* - * IGFSCFDecoderReset() + * IGFSCFDecoderReset_ivas() * * resets the internal decoder memory (context memory) *---------------------------------------------------------------------*/ -void IGFSCFDecoderReset( +void IGFSCFDecoderReset_ivas( IGFSCFDEC_INSTANCE_HANDLE hPublicData /* i/o: handle to public data or NULL in case there was no instance created */ ) { @@ -288,12 +288,12 @@ void IGFSCFDecoderReset( /*---------------------------------------------------------------------* - * IGFSCFDecoderDecode() + * IGFSCFDecoderDecode_ivas() * * main IGF decoder function *---------------------------------------------------------------------*/ -void IGFSCFDecoderDecode( +void IGFSCFDecoderDecode_ivas( IGFSCFDEC_INSTANCE_HANDLE hPublicData, /* i/o: handle to public data or NULL in case there was no instance created */ Decoder_State *st, /* i/o: pointer to decoder state */ int16_t *sfe, /* o : ptr to an array which will contain the decoded quantized coefficients */ @@ -304,13 +304,13 @@ void IGFSCFDecoderDecode( { /* insert data */ hPublicData->bitsRead = st->next_bit_pos; - ari_start_decoding_14bits( st, &hPublicData->acState ); /* start AC decoding */ + ari_start_decoding_14bits_ivas( st, &hPublicData->acState ); /* start AC decoding */ /* check if coder needs a reset and do it if neccessary */ if ( indepFlag ) { /* reset of coder */ - IGFSCFDecoderReset( hPublicData ); + IGFSCFDecoderReset_ivas( hPublicData ); } decode_sfe_vector( hPublicData, st, hPublicData->t, hPublicData->prev, sfe, hPublicData->scfCountLongBlock[igfGridIdx] ); diff --git a/lib_dec/igf_scf_dec_fx.c b/lib_dec/igf_scf_dec_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..fc732cc89aaa671c5e4b0da76bdf999e52afb0d9 --- /dev/null +++ b/lib_dec/igf_scf_dec_fx.c @@ -0,0 +1,337 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include +#include +#include +#include +#include "options.h" +#include "stl.h" +#include "prot_fx1.h" +#include "prot_fx2.h" +#include "stat_dec.h" +#include "basop_util.h" + + +/**********************************************************************/ /** +initialization of an instance of this module +**************************************************************************/ +void IGFSCFDecoderOpen( + IGFSCFDEC_INSTANCE_HANDLE hPublicData, /* i : handle to public data */ + H_IGF_INFO hIgfInfo, /* i : IGF info handle */ + const Word32 total_brate, + const Word16 bwidth, + const Word16 element_mode, + const Word16 rf_mode +) +{ + + + hPublicData->scfCountLongBlock[0] = hIgfInfo->grid[0].swb_offset_len - 1; + hPublicData->scfCountLongBlock[1] = hIgfInfo->grid[1].swb_offset_len - 1; + hPublicData->scfCountLongBlock[2] = hIgfInfo->grid[2].swb_offset_len - 1; + move16();move16();move16();move16(); + + hPublicData->t = 0; + move16(); /* protect against the invalid request of starting decoding with a dependent block */ + + IGFCommonFuncsIGFGetCFTables(total_brate, bwidth, element_mode, rf_mode, &hPublicData->cf_se00, &hPublicData->cf_se01, &hPublicData->cf_off_se01, &hPublicData->cf_se02, &hPublicData->cf_off_se02, &hPublicData->cf_se10, &hPublicData->cf_off_se10, &hPublicData->cf_se11, &hPublicData->cf_off_se11); + +} + + +static Word16 quant_ctx_fx( + Word16 ctx /* i: the context value to be quantized */ +) +{ + /* + ctx ... -5 -4 -3 -2 -1 0 1 2 3 4 5 ... + Q(ctx)... -3 -3 -3 -2 -1 0 1 2 3 3 3 ... + */ + Word16 result; + + + result = s_min(abs_s(ctx), IGF_CTX_OFFSET); /* limit the absolute value to IGF_CTX_OFFSET */ + if (ctx < 0) /* add the sign back, if needed */ + { + result = negate(result); + } + + return result; +} + +static Word16 arith_decode_bits_fx( + IGFSCFDEC_INSTANCE_HANDLE hPrivateData, /* i/o: instance handle */ + Decoder_State *st, /* i/o: pointer to bitstream decoder state */ + Word16 nBits /* i: number of bits to decode */ +) +{ + Word16 i; + Word16 x; + Word16 bit; + + + x = 0; + move16(); + FOR (i = 0; i < nBits; ++i) /* nBits > 0 */ + { + x = lshl(x, 1); + /* decode one bit using the new raw AC function */ + bit = ari_decode_14bits_bit_ext(st, &hPrivateData->acState); + if (bit != 0) + { + x = s_or(x, 1); + } + } + + return x; +} + +static Word16 arith_decode_residual_fx( + IGFSCFDEC_INSTANCE_HANDLE hPrivateData, /* i/o: instance handle */ + Decoder_State *st, /* i/o: pointer to decoder state */ + const Word16 *cumulativeFrequencyTable, /* i: cumulative frequency table to be used */ + Word16 tableOffset /* i: offset used to align the table */ +) +{ + Word16 val; + Word16 x = 0; /* to avoid a compiler warning (potentially uninitialized local variable used) */ + Word16 extra; + + + /* decode one of the IGF_SYMBOLS_IN_TABLE == 27 alphabet symbols using the new raw AC function */ + val = ari_decode_14bits_s27_ext(st, &hPrivateData->acState, (const UWord16*) cumulativeFrequencyTable); + + /* meaning of the values of val: */ + /* esc_{0} IGF_MIN_ENC_SEPARATE ... IGF_MAX_ENC_SEPARATE esc_{IGF_SYMBOLS_IN_TABLE - 1} */ + test(); + IF ((val != 0) && (NE_16(val, IGF_SYMBOLS_IN_TABLE - 1))) + { + x = add(val, - 1 + IGF_MIN_ENC_SEPARATE); /* (val - 1) + IGF_MIN_ENC_SEPARATE */ + + + x = sub(x, tableOffset); + + return x; + } + + /* decode one of the tails of the distribution */ + /* decode extra with 4 bits */ + extra = arith_decode_bits_fx(hPrivateData, st, 4); + IF (EQ_16(extra, 15)) /* escape code 15 to indicate extra >= 15 */ + { + /* decode addtional extra with 6 bits */ + extra = arith_decode_bits_fx(hPrivateData, st, 6); + IF (EQ_16(extra, 63)) /* escape code 63 to indicate extra >= 63 */ + { + /* decode safety extra with 7 bits */ + extra = arith_decode_bits_fx(hPrivateData, st, 7); + extra = add(63, extra); + } + extra = add(15, extra); + } + + if (val == 0) + { + /* escape code 0 to indicate x <= IGF_MIN_ENC_SEPARATE - 1 */ + x = sub(IGF_MIN_ENC_SEPARATE - 1, extra); + } + if (EQ_16(val, IGF_SYMBOLS_IN_TABLE - 1)) + { + /* escape code (IGF_SYMBOLS_IN_TABLE - 1) to indicate x >= IGF_MAX_ENC_SEPARATE + 1 */ + x = add(IGF_MAX_ENC_SEPARATE + 1, extra); + } + + x = sub(x, tableOffset); + + return x; +} + +static void arith_decode_flush_fx( + Decoder_State *st /* i/o: pointer to decoder state */ +) +{ + + get_next_indice_tmp_fx(st, -14); /* return back the least significant 14 bits to the bitstream */ + +} + +static void decode_sfe_vector_fx( + IGFSCFDEC_INSTANCE_HANDLE hPrivateData, /* i/o: instance handle */ + Decoder_State *st, /* i/o: pointer to decoder state */ + Word16 t, /* i: counter reset to 0 at each independent block */ + Word16 *prev_x, /* i: previous vector */ + Word16 *x, /* o: current vector to decode */ + Word16 length /* i: number of elements to decode */ +) +{ + /* + f + ^ + | d a x + | c b + | e --> t + */ + Word16 f; + Word16 pred; + Word16 res; + Word16 ctx; + Word16 ctx_f; + Word16 ctx_t; + Word16 prev_offset; + Word32 index1; + Word32 index2; + + + + FOR (f = 0; f < length; ++f) + { + IF (t == 0) + { + IF (f == 0) + { + /* (t == 0) && (f == 0) */ + /* decode one of the IGF_SYMBOLS_IN_TABLE == 27 alphabet symbols using the new raw AC function */ + res = ari_decode_14bits_s27_ext(st, &hPrivateData->acState, (const UWord16*) hPrivateData->cf_se00); + + pred = arith_decode_bits_fx(hPrivateData, st, 2); /* LSBs as 2 bit raw */ + x[f] = add(shl(res, 2), pred); + move16(); + } + ELSE IF (EQ_16(f, 1)) + { + /* (t == 0) && (f == 1) */ + res = arith_decode_residual_fx(hPrivateData, + st, + hPrivateData->cf_se01, + hPrivateData->cf_off_se01); + x[f] = add(x[0], res); + move16(); /* f - increment is 0, pred = b */ + } + ELSE + { + /* (t == 0) && (f >= 2) */ + prev_offset = sub(f, 1); + ctx = quant_ctx_fx(sub(x[prev_offset], x[sub(prev_offset, 1)])); /* Q(b - e) */ + /* index1 is (IGF_SYMBOLS_IN_TABLE + 1) * (CTX_OFFSET + ctx) */ + index1 = L_mac0((IGF_SYMBOLS_IN_TABLE + 1) * IGF_CTX_OFFSET, (IGF_SYMBOLS_IN_TABLE + 1), ctx); + /* index2 is IGF_CTX_OFFSET + ctx */ + index2 = L_mac0(IGF_CTX_OFFSET, 1, ctx); + res = arith_decode_residual_fx(hPrivateData, + st, + hPrivateData->cf_se02 + index1, + hPrivateData->cf_off_se02[index2]); + x[f] = add(x[prev_offset], res); + move16(); /* pred = b */ + } + } + ELSE + { + /* t == 1 */ + IF (f == 0) + { + /* (t == 1) && (f == 0) */ + res = arith_decode_residual_fx(hPrivateData, + st, + hPrivateData->cf_se10, + hPrivateData->cf_off_se10); + x[f] = add(prev_x[f], res); + move16(); /* pred = a */ + } + ELSE + { + /* (t == 1) && (f >= 1) */ + prev_offset = sub(f, 1); + pred = add(prev_x[f], x[prev_offset]); + pred = sub(pred, prev_x[prev_offset]); /* pred = a + b - c */ + ctx_f = quant_ctx_fx(sub(prev_x[f], prev_x[prev_offset])); /* Q(a - c) */ + ctx_t = quant_ctx_fx(sub(x[prev_offset], prev_x[prev_offset])); /* Q(b - c) */ + /* index1 is (IGF_SYMBOLS_IN_TABLE + 1) * IGF_CTX_COUNT * (IGF_CTX_OFFSET + ctx_t) + + (IGF_SYMBOLS_IN_TABLE + 1) * (IGF_CTX_OFFSET + ctx_f) */ + index1 = L_mac0( + ((IGF_SYMBOLS_IN_TABLE + 1) * IGF_CTX_COUNT + (IGF_SYMBOLS_IN_TABLE + 1)) * IGF_CTX_OFFSET, + (IGF_SYMBOLS_IN_TABLE + 1) * IGF_CTX_COUNT, ctx_t); + index1 = L_mac0(index1, (IGF_SYMBOLS_IN_TABLE + 1), ctx_f); + /* index2 is IGF_CTX_COUNT * (IGF_CTX_OFFSET + ctx_t) + (IGF_CTX_OFFSET + ctx_f) */ + index2 = L_mac0((IGF_CTX_COUNT + 1) * IGF_CTX_OFFSET, IGF_CTX_COUNT, ctx_t); + index2 = L_mac0(index2, 1, ctx_f); + res = arith_decode_residual_fx(hPrivateData, + st, + hPrivateData->cf_se11 + index1, + hPrivateData->cf_off_se11[index2]); + x[f] = add(pred, res); + move16(); + } + } + + IF( x[f] < 0 ) + { + x[f] = 0; + move16(); + st->BER_detect = 1; + move16(); + } + + IF (GT_16(x[f],91)) + { + x[f] = 91; + move16(); + st->BER_detect = 1; + move16(); + } + } + +} + +/**********************************************************************/ /** +resets the internal decoder memory (context memory) +**************************************************************************/ +void IGFSCFDecoderReset( + IGFSCFDEC_INSTANCE_HANDLE hPublicData /* i/o: handle to public data */ +) +{ + + + /* reset of coder */ + hPublicData->t = 0; /* indicate that an independent block follows */ + /* we do not need to fill hPublicData->prev with zeros, because when t = 0 no previous information is used */ + +} + +/**********************************************************************/ /** +main decoder function +**************************************************************************/ +void IGFSCFDecoderDecode( + IGFSCFDEC_INSTANCE_HANDLE hPublicData, /* i/o: handle to public data or NULL in case there was no instance created */ + Decoder_State* st, /* i/o: pointer to decoder state */ + int16_t* sfe, /* o : ptr to an array which will contain the decoded quantized coefficients */ + const Word16 igfGridIdx, /* i : igf grid index see declaration of IGF_GRID_IDX for details */ + const Word16 indepFlag /* i : if 1 on input the decoder will be forced to reset, + if 0 on input the decoder will be forced to encode without a reset */ +) +{ + /* insert data */ + hPublicData->bitsRead = st->next_bit_pos; + move16(); + ari_start_decoding_14bits(st, &hPublicData->acState); /* start AC decoding */ + + /* check if coder needs a reset and do it if necessary */ + IF (indepFlag != 0) + { + /* reset of coder */ + IGFSCFDecoderReset(hPublicData); + } + + decode_sfe_vector_fx(hPublicData, st, hPublicData->t, hPublicData->prev, sfe, hPublicData->scfCountLongBlock[igfGridIdx] ); + + arith_decode_flush_fx(st); /* finish AC decoding */ + + + /* advance history */ + Copy(sfe, hPublicData->prev, hPublicData->scfCountLongBlock[igfGridIdx]); + hPublicData->t = add(hPublicData->t, 1); + + hPublicData->bitsRead = sub(st->next_bit_pos, hPublicData->bitsRead); + +} diff --git a/lib_dec/init_dec.c b/lib_dec/init_dec.c index 2a493472baec31a9ab26f3f3f9132af1635cfaf2..51098eb58c88ce25b94d40cf9fb6ba1b30a9ee61 100644 --- a/lib_dec/init_dec.c +++ b/lib_dec/init_dec.c @@ -88,7 +88,7 @@ ivas_error init_decoder( st->last_core = -1; st->last_extl = st->extl; - st->flag_ACELP16k = set_ACELP_flag( st->element_mode, st->total_brate, st->total_brate, idchan, 0, -1, -1 ); + st->flag_ACELP16k = set_ACELP_flag_IVAS( st->element_mode, st->total_brate, st->total_brate, idchan, 0, -1, -1 ); /*-----------------------------------------------------------------* * ACELP core parameters @@ -199,7 +199,7 @@ ivas_error init_decoder( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for GSC\n" ) ); } - GSC_dec_init( st->hGSCDec ); + GSC_dec_init_ivas( st->hGSCDec ); } else { @@ -236,7 +236,7 @@ ivas_error init_decoder( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for NB/formant postflter\n" ) ); } - Init_post_filter( st->hPFstat ); + Init_post_filter_ivas( st->hPFstat ); st->psf_lp_noise = 0.0f; } else @@ -274,7 +274,7 @@ ivas_error init_decoder( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LD music postflter\n" ) ); } - music_postfilt_init( st->hMusicPF ); + music_postfilt_init_flt( st->hMusicPF ); } else { @@ -300,7 +300,7 @@ ivas_error init_decoder( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DTX/TD CNG\n" ) ); } - td_cng_dec_init( st ); + td_cng_dec_init_flt( st ); } else { @@ -330,7 +330,7 @@ ivas_error init_decoder( } /* HQ core initialization */ - HQ_core_dec_init( st->hHQ_core ); + HQ_core_dec_init_flt( st->hHQ_core ); if ( st->element_mode == EVS_MONO ) { @@ -339,7 +339,7 @@ ivas_error init_decoder( { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HQ NB FEC\n" ) ); } - HQ_nbfec_init( st->hHQ_nbfec ); + HQ_nbfec_init_flt( st->hHQ_nbfec ); } else { @@ -384,7 +384,7 @@ ivas_error init_decoder( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for FD BWE\n" ) ); } - fd_bwe_dec_init( st->hBWE_FD ); + fd_bwe_dec_init_flt( st->hBWE_FD ); } else { @@ -419,7 +419,7 @@ ivas_error init_decoder( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HR BWE\n" ) ); } - hr_bwe_dec_init( st->hBWE_FD_HR ); + hr_bwe_dec_init_flt( st->hBWE_FD_HR ); } else { @@ -438,7 +438,7 @@ ivas_error init_decoder( } /* AMR-WB IO init */ - amr_wb_dec_init( st->hAmrwb_IO ); + amr_wb_dec_init_flt( st->hAmrwb_IO ); /* AMR-WB IO HF synth init */ hf_synth_amr_wb_init( st->hAmrwb_IO ); @@ -496,13 +496,13 @@ ivas_error init_decoder( if ( ( idchan == 0 && st->element_mode != IVAS_CPE_MDCT ) || st->element_mode == IVAS_CPE_TD ) { /* open analysis for max. sampling rate 48kHz */ - if ( ( error = openCldfb( &st->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS ) ) != IVAS_ERR_OK ) + if ( ( error = openCldfb_ivas( &st->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS ) ) != IVAS_ERR_OK ) { return error; } /* open analysis BPF for max. internal sampling rate 16kHz */ - if ( ( error = openCldfb( &st->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS ) ) != IVAS_ERR_OK ) + if ( ( error = openCldfb_ivas( &st->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS ) ) != IVAS_ERR_OK ) { return error; } @@ -514,7 +514,7 @@ ivas_error init_decoder( } /* open synthesis for output sampling rate */ - if ( ( error = openCldfb( &st->cldfbSyn, CLDFB_SYNTHESIS, st->output_Fs, CLDFB_PROTOTYPE_1_25MS ) ) != IVAS_ERR_OK ) + if ( ( error = openCldfb_ivas( &st->cldfbSyn, CLDFB_SYNTHESIS, st->output_Fs, CLDFB_PROTOTYPE_1_25MS ) ) != IVAS_ERR_OK ) { return error; } @@ -550,7 +550,7 @@ ivas_error init_decoder( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SC-VBR\n" ) ); } - sc_vbr_dec_init( st->hSC_VBR ); + sc_vbr_dec_init_flt( st->hSC_VBR ); } else { @@ -642,7 +642,7 @@ ivas_error init_decoder( } st->igf = 0; - init_igf_dec( st->hIGFDec ); + init_igf_dec_flt( st->hIGFDec ); } else { @@ -678,7 +678,7 @@ ivas_error init_decoder( } /* Init Core Decoder */ - open_decoder_LPD( st, st->total_brate, st->last_total_brate, st->bwidth, 0, st->element_mode, 1 ); + open_decoder_LPD_flt( st, st->total_brate, st->last_total_brate, st->bwidth, 0, st->element_mode, 1 ); /* PLC mode initialization */ st->m_decodeMode = DEC_NO_FRAM_LOSS; @@ -689,8 +689,8 @@ ivas_error init_decoder( if ( ( idchan == 0 && st->element_mode != IVAS_CPE_MDCT ) ) { - resampleCldfb( st->cldfbAna, st->L_frame * FRAMES_PER_SEC ); - resampleCldfb( st->cldfbBPF, st->L_frame * FRAMES_PER_SEC ); + resampleCldfb_ivas( st->cldfbAna, st->L_frame * FRAMES_PER_SEC ); + resampleCldfb_ivas( st->cldfbBPF, st->L_frame * FRAMES_PER_SEC ); } /*-----------------------------------------------------------------* @@ -700,13 +700,13 @@ ivas_error init_decoder( if ( ( st->element_mode == IVAS_CPE_MDCT || idchan == 0 ) && mc_mode != MC_MODE_MCT && mc_mode != MC_MODE_PARAMUPMIX ) { /* Create FD_CNG instance */ - if ( ( error = createFdCngDec( &st->hFdCngDec ) ) != IVAS_ERR_OK ) + if ( ( error = createFdCngDec_flt( &st->hFdCngDec ) ) != IVAS_ERR_OK ) { return error; } /* Init FD-CNG */ - initFdCngDec( st ); + initFdCngDec_flt( st ); } else { @@ -754,22 +754,22 @@ void reset_preecho_dec( /*----------------------------------------------------------------------* - * destroy_cldfb_decoder() + * destroy_cldfb_decoder_flt() * * Free memory which was allocated in init_decoder() *----------------------------------------------------------------------*/ -void destroy_cldfb_decoder( +void destroy_cldfb_decoder_flt( Decoder_State *st /* o : Decoder static variables structure */ ) { /* CLDFB BPF & resampling tools */ - deleteCldfb( &st->cldfbAna ); /* delete analysis at max. sampling rate 48kHz */ - deleteCldfb( &st->cldfbBPF ); /* delete analysis BPF at max. internal sampling rate 16kHz */ - deleteCldfb( &st->cldfbSyn ); /* delete synthesis at output sampling rate */ - deleteCldfb( &st->cldfbSynHB ); + deleteCldfb_ivas( &st->cldfbAna ); /* delete analysis at max. sampling rate 48kHz */ + deleteCldfb_ivas( &st->cldfbBPF ); /* delete analysis BPF at max. internal sampling rate 16kHz */ + deleteCldfb_ivas( &st->cldfbSyn ); /* delete synthesis at output sampling rate */ + deleteCldfb_ivas( &st->cldfbSynHB ); - deleteFdCngDec( &st->hFdCngDec ); + deleteFdCngDec_flt( &st->hFdCngDec ); return; } diff --git a/lib_dec/init_dec_fx.c b/lib_dec/init_dec_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..5cc8c315d702e6decc1693679ee91d7e9a9fe64e --- /dev/null +++ b/lib_dec/init_dec_fx.c @@ -0,0 +1,882 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include "options.h" /* Compilation switches */ +#include "prot_fx1.h" +#include "prot_fx2.h" +#include "cnst.h" /* Common constants */ +#include "rom_com.h" /* Static table prototypes */ +#include "stl.h" /* required for wmc_tool */ +#include "basop_util.h" + +/*----------------------------------------------------------------------* + * init_decoder() + * + * Initialization of static variables for the decoder + *----------------------------------------------------------------------*/ + +ivas_error init_decoder_fx( + Decoder_State *st_fx, /* o: Decoder static variables structure */ + const Word16 idchan /* i : channel ID */ +#ifdef IVAS_CODE + ,const MC_MODE mc_mode /* i : MC mode */ +#endif +) +{ + Word16 i; + ivas_error error; + + error = IVAS_ERR_OK; + + Word16 newCldfbBands; + + + st_fx->total_num_bits = -1; + move16(); + + /*-----------------------------------------------------------------* + * ACELP core parameters + *-----------------------------------------------------------------*/ + + st_fx->codec_mode = MODE1; + move16(); + st_fx->last_codec_mode = MODE1; + move16(); + st_fx->core = ACELP_CORE; + move16(); + st_fx->L_frame = L_FRAME; + move16(); + st_fx->extl = -1; + move16(); + st_fx->total_brate = 8000; + move16(); + st_fx->last_total_brate = -1; + move16(); + st_fx->last_total_brate_ber = -1; + move32(); + st_fx->core_brate = 8000; + move16(); + st_fx->ini_frame = 0; + move16(); + st_fx->bwidth = NB; + move16(); + st_fx->extl_brate = 0; + move16(); + + + st_fx->last_coder_type_fx = GENERIC; + move16(); + st_fx->last_L_frame = st_fx->L_frame; + move16(); + st_fx->last_core_brate = st_fx->core_brate ; + move16(); + + st_fx->last_core = -1; + move16(); + st_fx->last_extl = st_fx->extl; + move16(); + + + /* LSF initilaizations */ + Copy( GEWB_Ave_fx, st_fx->mem_AR_fx, M ); + + init_lvq_fx( st_fx->offset_scale1_fx, st_fx->offset_scale2_fx, st_fx->offset_scale1_p_fx, st_fx->offset_scale2_p_fx, st_fx->no_scales_fx, st_fx->no_scales_p_fx ); + + set16_fx( st_fx->mem_MA_fx, 0, M ); + + st_fx->dm_fx.prev_state = 0; + move16(); /* This corresponds to st_fx->dispMem in FLP */ + st_fx->dm_fx.prev_gain_code = L_deposit_l(0); + FOR(i=2; i<8; i++) + { + st_fx->dm_fx.prev_gain_pit[i-2] = 0; + move16(); + } + + st_fx->tilt_code_fx = 0; + move16(); + st_fx->gc_threshold_fx = L_deposit_l(0); + st_fx->last_good_fx = UNVOICED_CLAS; + move16(); + st_fx->clas_dec = UNVOICED_CLAS; + move16(); + + st_fx->lp_gainp_fx = 0; + move16(); + st_fx->lp_gainc_fx = 0; + move16(); + + set16_fx( st_fx->old_exc_fx, 0, L_EXC_MEM_DEC ); + + /* AVQ pre-quantizer memory */ + st_fx->mem_preemp_preQ_fx = 0; + move16(); + st_fx->last_nq_preQ_fx = 0; + move16(); + st_fx->use_acelp_preq = 0; + move16(); + + st_fx->mem_deemph_fx = 0; + move16(); + /*-----------------------------------------------------------------* + * SWB BWE parameters + *-----------------------------------------------------------------*/ + + IF (idchan == 0 && NE_16(st_fx->element_mode, IVAS_CPE_MDCT)) + { + IF ((st_fx->hBWE_FD = (FD_BWE_DEC_HANDLE)count_malloc(sizeof(FD_BWE_DEC_DATA))) == NULL) + { + return (IVAS_ERROR(IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for FD BWE\n")); + } + + fd_bwe_dec_init(st_fx, st_fx->hBWE_FD); + } + ELSE + { + st_fx->hBWE_FD = NULL; + } + + /*-----------------------------------------------------------------* + * IGF + *-----------------------------------------------------------------*/ + + IF ((idchan == 0 || EQ_16(st_fx->element_mode, IVAS_CPE_MDCT)) ) + { + IF ((st_fx->hIGFDec = (IGF_DEC_INSTANCE_HANDLE)count_malloc(sizeof(IGFDEC_INSTANCE))) == NULL) + { + return (IVAS_ERROR(IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for IGF\n")); + } + + st_fx->igf = 0; + //init_igf_dec(st_fx->hIGFDec); + set16_fx((Word16*)st_fx->hIGFDec, 0, (sizeof(IGFDEC_INSTANCE) ) / sizeof(Word16)); + st_fx->hIGFDec->igfData.igfInfo.nfSeedBuf[0] = 9733; + st_fx->hIGFDec->igfData.igfInfo.nfSeedBuf[1] = 9733; + st_fx->hIGFDec->igfData.igfInfo.nfSeed = &st_fx->hIGFDec->igfData.igfInfo.nfSeedBuf[0]; + } + else + { + st_fx->hIGFDec = NULL; + } + + /*-----------------------------------------------------------------* + * HR SWB BWE parameters + *-----------------------------------------------------------------*/ + + IF (EQ_16(st_fx->element_mode, EVS_MONO)) + { + IF ((st_fx->hBWE_FD_HR = (HR_BWE_DEC_HANDLE)count_malloc(sizeof(HR_BWE_DEC_DATA))) == NULL) + { + return (IVAS_ERROR(IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HR BWE\n")); + } + + hr_bwe_dec_init(st_fx->hBWE_FD_HR); + } + ELSE + { + st_fx->hBWE_FD_HR = NULL; + } + set16_fx( st_fx->mem_syn1_fx, 0, M ); + move16(); + set16_fx( st_fx->mem_syn2_fx, 0, M ); + st_fx->stab_fac_fx = 0; + move16(); + st_fx->stab_fac_smooth_fx = 0; + move16(); + set16_fx( st_fx->agc_mem_fx, 0, 2 ); + set32_fx( st_fx->L_mem_hp_out_fx, 0, 5 ); + set16_fx( st_fx->mem_syn3_fx, 0, M ); + + + Copy( GEWB_Ave_fx, st_fx->lsf_old_fx, M ); + lsf2lsp_fx( st_fx->lsf_old_fx, st_fx->lsp_old_fx, M, INT_FS_FX ); + st_fx->mid_lsf_int_fx = 0; + move16(); + st_fx->safety_net_fx = 0; + move16(); + st_fx->GSC_noisy_speech_fx = 0; + move16(); + st_fx->last_voice_factor_fx = 0; + move16(); + + set16_fx(st_fx->prev_lpc_wb_fx, 0, LPC_SHB_ORDER_WB); + + IF ((idchan == 0 && NE_16(st_fx->element_mode, IVAS_CPE_MDCT)) || EQ_16(st_fx->element_mode, IVAS_CPE_TD)) + { + IF ((st_fx->hGSCDec = (GSC_DEC_HANDLE)count_malloc(sizeof(GSC_DEC_DATA))) == NULL) + { + return (IVAS_ERROR(IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for GSC\n")); + } + + GSC_dec_init(st_fx->hGSCDec); + } + ELSE + { + st_fx->hGSCDec = NULL; + } + + /*-----------------------------------------------------------------* + * parameters for fast recovery (WI) + *-----------------------------------------------------------------*/ + test(); test(); + IF (EQ_32(st_fx->output_Fs, 16000) && EQ_16(st_fx->element_mode, EVS_MONO ) ) + { + IF ((st_fx->hWIDec = (WI_DEC_HANDLE)count_malloc(sizeof(WI_DEC_DATA))) == NULL) + { + return (IVAS_ERROR(IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for FEC WI\n")); + } + + set16_fx(st_fx->hWIDec->old_exc2_fx, 0, L_EXC_MEM); + set16_fx(st_fx->hWIDec->old_syn2_fx, 0, L_EXC_MEM); + } + else + { + st_fx->hWIDec = NULL; + } + + /* NB post-filter */ + /*-----------------------------------------------------------------* + * NB/formant post-filter + *-----------------------------------------------------------------*/ + IF ((idchan == 0 && NE_16(st_fx->element_mode,IVAS_CPE_MDCT)) || EQ_16(st_fx->element_mode, IVAS_CPE_TD)) + { + IF ((st_fx->hPFstat = (PFSTAT_HANDLE)count_malloc(sizeof(PFSTAT))) == NULL) + { + return (IVAS_ERROR(IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for NB/formant postflter\n")); + } + + Init_post_filter(st_fx->hPFstat); + st_fx->psf_lp_noise_fx = 0; + } + ELSE + { + st_fx->hPFstat = NULL; + } + st_fx->psf_lp_noise_fx = 0; + move16(); + + /* FEC */ + st_fx->scaling_flag = 0; + move16(); + st_fx->lp_ener_FEC_av = 500000; + move32(); + st_fx->lp_ener_FEC_max = 500000; + move32(); + st_fx->prev_bfi = 0; + move16(); + st_fx->lp_ener_FER_fx = 15360; + move16(); /*60 in Q8*/ + st_fx->old_enr_LP = 0; + move16(); + st_fx->lp_ener_fx = L_deposit_l(0); + st_fx->enr_old_fx = L_deposit_l(0); + st_fx->bfi_pitch_fx = L_SUBFR_Q6; + move16(); + st_fx->bfi_pitch_frame = L_SUBFR; + move16(); + set16_fx( st_fx->mem_syn_clas_estim_fx, 0, L_SYN_MEM_CLAS_ESTIM ); + st_fx->classifier_Q_mem_syn = 0; + move16(); + st_fx->last_con_tcx = 0; + move16(); + + FOR (i=0; i<2*NB_SUBFR16k; i++) + { + st_fx->old_pitch_buf_fx[i] = L_SUBFR<<16; + move32(); /*15Q16*/ + } + + st_fx->upd_cnt = MAX_UPD_CNT; + move16(); + Copy( GEWB_Ave_fx, st_fx->lsfoldbfi0_fx, M ); + Copy( GEWB_Ave_fx, st_fx->lsfoldbfi1_fx, M ); + Copy( GEWB_Ave_fx, st_fx->lsf_adaptive_mean_fx, M ); + + st_fx->seed_acelp = RANDOM_INITSEED; + move16(); + st_fx->seed = RANDOM_INITSEED; + move16(); + st_fx->nbLostCmpt = 0; + move16(); + st_fx->decision_hyst = 0; + move16(); + + + /* Stationary noise UV modification */ + st_fx->unv_cnt_fx = 0; + move16(); + st_fx->ge_sm_fx = L_deposit_l(640); /*Q(GE_SHIFT)*/ + st_fx->uv_count_fx = 0; + move16(); + st_fx->act_count_fx = 3; + move16(); + Copy( st_fx->lsp_old_fx, st_fx->lspold_s_fx, M ); + st_fx->noimix_seed_fx = RANDOM_INITSEED; + move16(); + st_fx->min_alpha_fx = 32767; + move16(); /*1; Q15*/ + st_fx->exc_pe_fx = 0; + move16(); + /*-----------------------------------------------------------------* + * LD music post-filter + *-----------------------------------------------------------------*/ + IF ((idchan == 0 && NE_16(st_fx->element_mode, IVAS_CPE_MDCT)) || EQ_16(st_fx->element_mode, IVAS_CPE_TD)) + { + IF ((st_fx->hMusicPF = (MUSIC_POSTFILT_HANDLE)count_malloc(sizeof(MUSIC_POSTFILT_DATA))) == NULL) + { + return (IVAS_ERROR(IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LD music postflter\n")); + } + + music_postfilt_init(st_fx->hMusicPF); + } + ELSE + { + st_fx->hMusicPF = NULL; + } + + /* CNG and DTX */ + test(); test(); test(); + IF (idchan == 0 && (EQ_16(st_fx->element_mode, EVS_MONO) || EQ_16(st_fx->element_mode, IVAS_CPE_DFT) || EQ_16(st_fx->element_mode, IVAS_CPE_TD) )) + { + if ((st_fx->hTdCngDec = (TD_CNG_DEC_HANDLE)count_malloc(sizeof(TD_CNG_DEC_DATA))) == NULL) + { + return (IVAS_ERROR(IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DTX/TD CNG\n")); + } + + td_cng_dec_init(st_fx); + } + ELSE + { + st_fx->hTdCngDec = NULL; + } + st_fx->cng_type = -1; + st_fx->CNG_fx = 0; + move16(); /* RTXDTX handler CNG=1 nonCNG= 0,*/ + st_fx->prev_ft_speech_fx = 1; + move16(); /* RXDTX handeler previous frametype flag for G.192 format AMRWB SID_FIRST detection */ + st_fx->first_CNG = 0; + move16(); + Copy( st_fx->lsp_old_fx, st_fx->lspCNG_fx, M ); + st_fx->shb_cng_ener_fx = -1541; + move16(); + st_fx->wb_cng_ener_fx = -1541; + move16(); + st_fx->last_wb_cng_ener_fx = -1541; + move16(); + st_fx->last_shb_cng_ener_fx = -1541; + move16(); + st_fx->swb_cng_seed_fx = RANDOM_INITSEED; + move16(); + + st_fx->CNG_mode = -1; + move16(); + st_fx->last_active_brate = ACELP_7k20; + move32(); + st_fx->last_CNG_L_frame = L_FRAME; + move16(); + move16(); + + FOR ( i=0; ilsp_shb_prev_fx[i] = lsp_shb_prev_tbl_fx[i]; + st_fx->lsp_shb_prev_prev_fx[i] = st_fx->lsp_shb_prev_fx[i]; + } + + st_fx->shb_dtx_count_fx = 0; + move16(); + st_fx->last_vad_fx = 0; + move16(); + st_fx->trans_cnt_fx = 0; + move16(); + st_fx->last_shb_ener_fx = 0; + move16(); + + /* HF (6-7kHz) BWE */ + move16(); + st_fx->Q_stat_noise_ge = GE_SHIFT; + move16(); + st_fx->cngTDLevel = 0; + move16(); + st_fx->cngTDLevel_e = 0; + move16(); + + + + /*-----------------------------------------------------------------* + * HQ core parameters + *-----------------------------------------------------------------*/ + test(); test(); test(); test(); test(); test(); + IF ((idchan == 0 || EQ_16(st_fx->element_mode, IVAS_CPE_MDCT) || EQ_16(st_fx->element_mode, IVAS_SCE) || EQ_16(st_fx->element_mode, EVS_MONO)) ) + { + IF ((st_fx->hHQ_core = (HQ_DEC_HANDLE)count_malloc(sizeof(HQ_DEC_DATA))) == NULL) + { + return (IVAS_ERROR(IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HQ core\n")); + } + + /* HQ core initialization */ + HQ_core_dec_init(st_fx->hHQ_core); + + IF (EQ_16(st_fx->element_mode, EVS_MONO)) + { + /* HQ NB FEC initialization */ + IF ((st_fx->hHQ_nbfec = (HQ_NBFEC_HANDLE)count_malloc(sizeof(HQ_NBFEC_DATA))) == NULL) + { + return (IVAS_ERROR(IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HQ NB FEC\n")); + } + HQ_nbfec_init(st_fx->hHQ_nbfec); + } + ELSE + { + st_fx->hHQ_nbfec = NULL; + move16(); + } + } + ELSE + { + st_fx->hHQ_core = NULL; + st_fx->hHQ_nbfec = NULL; + move16(); move16(); + } + st_fx->Qprev_synth_buffer_fx = 15; + st_fx->old_bfi_cnt_fx = 0; + st_fx->prev_old_bfi_fx = 0; + set16_fx(st_fx->delay_buf_out_fx, 0, HQ_DELTA_MAX* HQ_DELAY_COMP); + set16_fx(st_fx->previoussynth_fx, 0, L_FRAME48k); + IF (EQ_16(st_fx->element_mode, EVS_MONO ) ) + { + set16_fx(st_fx->old_synth_sw_fx, 0, NS2SA(48000, FRAME_SIZE_NS - ACELP_LOOK_NS - DELAY_BWE_TOTAL_NS)); + } + /*-----------------------------------------------------------------* + * TCX core + *-----------------------------------------------------------------*/ + + /* TCX-LTP */ + IF ((idchan == 0 || EQ_16(st_fx->element_mode, IVAS_CPE_MDCT)) ) + { + IF ((st_fx->hTcxLtpDec = (TCX_LTP_DEC_HANDLE)count_malloc(sizeof(TCX_LTP_DEC_DATA))) == NULL) + { + return (IVAS_ERROR(IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TCX-LTP handle\n")); + } + } + ELSE + { + st_fx->hTcxLtpDec = NULL; + } + + /* TCX core */ + // VE: reduction possible for MCT_CHAN_MODE_LFE channel - see I1-172 + IF (idchan == 0 || EQ_16(st_fx->element_mode, IVAS_CPE_MDCT)) + { + IF ((st_fx->hTcxDec = (TCX_DEC_HANDLE)count_malloc(sizeof(TCX_DEC_DATA))) == NULL) + { + return (IVAS_ERROR(IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for hTcxDec\n")); + } + + set16_fx(st_fx->hTcxDec->FBTCXdelayBuf, 0, 111); + + st_fx->hTcxDec->old_synthFB_fx = st_fx->hTcxDec->synth_history_fx + NS2SA(st_fx->output_Fs, PH_ECU_MEM_NS); + st_fx->hTcxDec->prev_good_synth_fx = st_fx->hTcxDec->old_synthFB_fx + NS2SA(st_fx->output_Fs, PH_ECU_LOOKAHEAD_NS); + } + ELSE + { + st_fx->hTcxDec = NULL; + } + /* TCX config. data structure */ + IF ((idchan == 0 || EQ_16(st_fx->element_mode, IVAS_CPE_MDCT))) + { + IF ((st_fx->hTcxCfg = (TCX_CONFIG_HANDLE)count_malloc(sizeof(TCX_config))) == NULL) + { + return (IVAS_ERROR(IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for hTcxCfg\n")); + } + } + ELSE + { + st_fx->hTcxCfg = NULL; + } + st_fx->prev_coder_type_fx = GENERIC; + move16(); + + move16(); + st_fx->tilt_wb_fx = 0; + move16(); + + set16_fx(st_fx->prev_synth_buffer_fx, 0, NS2SA_fx2(48000, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS)); + set16_fx(st_fx->hb_prev_synth_buffer_fx, 0, NS2SA_fx2(48000, DELAY_BWE_TOTAL_NS)); + st_fx->old_bwe_delay_fx = -1; /*Q0*/ move16(); + + /*-----------------------------------------------------------------* + * TBE parameters + *-----------------------------------------------------------------*/ + + + IF (idchan == 0 && NE_16(st_fx->element_mode, IVAS_CPE_MDCT)) + { + if ((st_fx->hBWE_TD = (TD_BWE_DEC_HANDLE)count_malloc(sizeof(TD_BWE_DEC_DATA))) == NULL) + { + return (IVAS_ERROR(IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD BWE\n")); + } + + td_bwe_dec_init_fx(st_fx, st_fx->hBWE_TD, +#ifdef ADD_IVAS_BWE + st_fx->extl, +#endif + st_fx->output_Fs); + + } + ELSE + { + st_fx->hBWE_TD = NULL; + } + + st_fx->tilt_swb_fx = 0; + st_fx->tilt_wb_fx = 0; + + st_fx->prev_ener_shb_fx = 0; + move16(); + st_fx->prev_enerLH_fx = 0; + move16(); + st_fx->enerLH_fx = L_deposit_l(0); + st_fx->enerLL_fx = L_deposit_l(0); + st_fx->prev_enerLL_fx = 0; + move16(); + st_fx->prev_fractive_fx = 0; + move16(); + st_fx->prev_bws_cnt_fx = 0; + move16(); + st_fx->bws_cnt_fx = N_WS2N_FRAMES; + move16(); + st_fx->bws_cnt1_fx = N_NS2W_FRAMES; + move16(); + st_fx->attenu_fx = 3277; + move16(); + st_fx->last_inner_frame = L_FRAME8k; + move16(); + st_fx->last_bwidth = 0; + move16(); + + /*-----------------------------------------------------------------* + * channel-aware mode parameters + *-----------------------------------------------------------------*/ + + set16_fx( st_fx->tilt_code_dec_fx, 0, NB_SUBFR16k ); + + st_fx->use_partial_copy = 0; + move16(); + st_fx->prev_use_partial_copy = 0; + move16(); + st_fx->rf_flag = 0; + move16(); + st_fx->rf_flag_last = 0; + st_fx->prev_rf_frame_type = 0; + move16(); + st_fx->next_coder_type = 0; + move16(); + + st_fx->rf_target_bits = 0; + move16(); + + st_fx->rf_indx_nelp_fid = 0; + move16(); + st_fx->rf_indx_nelp_iG1 = 0; + move16(); + st_fx->rf_indx_nelp_iG2[0] = 0; + move16(); + st_fx->rf_indx_nelp_iG2[1] = 0; + move16(); + st_fx->rf_indx_tbeGainFr = 0; + move16(); + + /*----------------------------------------------------------------------------------* + * AMR-WB IO mode parameters + *----------------------------------------------------------------------------------*/ + IF (st_fx->Opt_AMR_WB || EQ_16(st_fx->element_mode, EVS_MONO) ) + { + IF ((st_fx->hAmrwb_IO = (AMRWB_IO_DEC_HANDLE)count_malloc(sizeof(AMRWB_IO_DEC_DATA))) == NULL) + { + return (IVAS_ERROR(IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for AMR-WB IO\n")); + } + + /* AMR-WB IO init */ + amr_wb_dec_init(st_fx->hAmrwb_IO); + + /* AMR-WB IO HF synth init */ + hf_synth_amr_wb_init_fx(st_fx->hAmrwb_IO); + } + ELSE + { + st_fx->hAmrwb_IO = NULL; + } + /*-----------------------------------------------------------------* + * HF (6-7kHz) (zero) BWE parameters + *-----------------------------------------------------------------*/ + + IF ((idchan == 0 && NE_16(st_fx->element_mode, IVAS_CPE_MDCT)) || EQ_16(st_fx->element_mode, IVAS_CPE_TD)) + { + IF ((st_fx->hBWE_zero = (ZERO_BWE_DEC_HANDLE)count_malloc(sizeof(ZERO_BWE_DEC_DATA))) == NULL) + { + return (IVAS_ERROR(IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for zero BWE\n")); + } + + hf_synth_init_fx(st_fx->hBWE_zero); + /* TBV Hack for bit exactness with 26.452, Issue should be corrected there as the the reset is not perform on all values of mem_hp400_fx*/ + set16_fx(st_fx->hBWE_zero->mem_hp400_fx, 0, 6); + + } + ELSE + { + st_fx->hBWE_zero = NULL; + } + + /* HF synth init */ + hf_synth_amr_wb_init_fx(st_fx->hAmrwb_IO); + + + + st_fx->bpf_off = 0; + /*-----------------------------------------------------------------* + * Bass post-filter parameters + *-----------------------------------------------------------------*/ + test(); test(); test(); + IF ((idchan == 0 && NE_16(st_fx->element_mode, IVAS_CPE_MDCT)) || EQ_16(st_fx->element_mode, IVAS_CPE_TD)) + { + IF ((st_fx->hBPF = (BPF_DEC_HANDLE)count_malloc(sizeof(BPF_DEC_DATA))) == NULL) + { + return (IVAS_ERROR(IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for BPF\n")); + } + + bass_psfilter_init_fx(st_fx->hBPF); + } + ELSE + { + st_fx->hBPF = NULL; + } + /*-----------------------------------------------------------------* + * FD BPF & resampling tools parameters + *-----------------------------------------------------------------*/ + /* open analysis for max. SR 48kHz */ + if ((error = openCldfb(&st_fx->cldfbAna_fx, CLDFB_ANALYSIS, CLDFB_getNumChannels(48000), 320)) != IVAS_ERR_OK) + { + return error; + } + + /* open analysis BPF for max. SR 16kHz */ + if ((error = openCldfb(&st_fx->cldfbBPF_fx, CLDFB_ANALYSIS, CLDFB_getNumChannels(16000), 320)) != IVAS_ERR_OK) + { + return error; + } + /* open synthesis for output SR */ + if ((error = openCldfb(&st_fx->cldfbSyn_fx, CLDFB_SYNTHESIS, CLDFB_getNumChannels(st_fx->output_Fs), st_fx->output_frame_fx)) != IVAS_ERR_OK) + { + return error; + } + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move32(); + st_fx->last_active_bandsToZero_bwdec = 0; + st_fx->perc_bwddec = 0; + st_fx->last_flag_filter_NB = 0; + st_fx->active_frame_cnt_bwddec = 0; + st_fx->total_frame_cnt_bwddec = 0; + set16_fx(st_fx->flag_buffer, 0, 20); + st_fx->avg_nrg_LT = 0; + + st_fx->Ng_ener_ST_fx = -13056; + move16(); /*-51 IN Q8*/ + st_fx->old_Es_pred_fx = 0; + move16(); + set16_fx(st_fx->old_Aq_12_8_fx + 1, 0, M ); + st_fx->old_Aq_12_8_fx[0] = 4096; + move16(); /*1 in Q12*/ + + /*-----------------------------------------------------------------* + * SC-VBR parameters + *-----------------------------------------------------------------*/ + + IF (EQ_16(st_fx->element_mode, EVS_MONO)) + { + IF ((st_fx->hSC_VBR = (SC_VBR_DEC_HANDLE)count_malloc(sizeof(SC_VBR_DEC_DATA))) == NULL) + { + return (IVAS_ERROR(IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SC-VBR\n")); + } + + sc_vbr_dec_init(st_fx->hSC_VBR); + } + ELSE + { + st_fx->hSC_VBR = NULL; + } + + st_fx->last_ppp_mode_dec_fx = 0; + move16(); + st_fx->old_ppp_mode_fx = 0; + move16(); + st_fx->ppp_mode_dec_fx = 0; + move16(); + st_fx->last_nelp_mode_dec_fx = 0; + move16(); + st_fx->nelp_mode_dec_fx = 0; + move16(); + st_fx->prev_gain_pit_dec_fx = 0; + move16(); + st_fx->prev_tilt_code_dec_fx = 0; + move16(); + st_fx->vbr_hw_BWE_disable_dec_fx = 0; + move16(); + st_fx->last_vbr_hw_BWE_disable_dec_fx = 0; + move16(); + + + + + st_fx->enablePlcWaveadjust = 0; + move16(); + + /* Init Decoder */ + open_decoder_LPD( st_fx, st_fx->total_brate, st_fx->bwidth); + + st_fx->m_decodeMode = DEC_NO_FRAM_LOSS; + move16(); + st_fx->m_frame_type = ACTIVE_FRAME; + move16(); + st_fx->m_old_frame_type = ACTIVE_FRAME; + move16(); + + + newCldfbBands = CLDFB_getNumChannels(L_mult0(st_fx->L_frame, 50)); + + resampleCldfb( st_fx->cldfbAna_fx, newCldfbBands, st_fx->L_frame, 1 ); + resampleCldfb( st_fx->cldfbBPF_fx, newCldfbBands, st_fx->L_frame, 1 ); +#ifdef IVAS_CODE + IF((EQ_16(st_fx->element_mode, IVAS_CPE_MDCT) || idchan == 0 ) && NE_16(mc_mode, MC_MODE_MCT) && NE_16(mc_mode, MC_MODE_PARAMUPMIX) ) // TBV Fixed point missing +#else + IF ( ( EQ_16(st_fx->element_mode, IVAS_CPE_MDCT) || idchan == 0) /*&& mc_mode != MC_MODE_MCT && mc_mode != MC_MODE_PARAMUPMIX*/) +#endif + { + /* Create FD_CNG instance */ + + if ((error = createFdCngDec(&st_fx->hFdCngDec_fx)) != IVAS_ERR_OK ) + { + return error; + } + + /* Init FD-CNG */ + initFdCngDec( st_fx, st_fx->cldfbSyn_fx->scale ); + } + ELSE + { + st_fx->hFdCngDec_fx = NULL; + } + + st_fx->lp_noise = -167772160l/*-20.f Q23*/; + st_fx->force_lpd_reset = 0; + move16(); + + /*-----------------------------------------------------------------* + * initialzie Q values + *-----------------------------------------------------------------*/ + + st_fx->Q_syn2 = 0; + move16(); + st_fx->Q_exc = 8; + st_fx->prev_Q_exc = 0; + move16(); + st_fx->Q_syn = 0; + move16(); + st_fx->prev_Q_syn = 0; + move16(); + + FOR(i=0; iQ_subfr[i] = 8; + move16(); + } + + st_fx->prev_Q_exc_fr = 0; + move16(); + st_fx->prev_Q_syn_fr = 0; + move16(); + + /*----------------------------------------------------------------------------------* + * Stereo/IVAS parameters + *----------------------------------------------------------------------------------*/ +#if 1 // IVAS_CODE -> To be verified + st_fx->tdm_LRTD_flag = 0; /* LRTD stereo mode flag */ + st_fx->cna_dirac_flag = 0; /* CNA in DirAC flag */ + st_fx->cng_sba_flag = 0; /* CNG in SBA flag */ + st_fx->element_mode = EVS_MONO; /* element mode */ + st_fx->last_element_mode = st_fx->element_mode; /* element mode */ + st_fx->element_brate = -1; /* element bitrate */ + st_fx->low_rate_mode = 0; /* low-rate mode flag */ + st_fx->last_low_rate_mode = 0; /* low-rate mode flag */ + //st_fx->cng_ism_flag = 0; + //st_fx->coder_type_fx = GENERIC; /* low-rate mode flag */ + +#endif +#ifdef DEBUGGING + st_fx->id_element = -1; /* element ID */ +#endif + st_fx->extl_orig = -1; /* extension layer */ + st_fx->extl_brate_orig = 0; /* extension layer bitrate */ + + return error; + +} + + +/*----------------------------------------------------------------------* + * reset_preecho_dec() + * + * Initialization of static variables for pre-echo + *----------------------------------------------------------------------*/ +void reset_preecho_dec_fx( + HQ_DEC_HANDLE hHQ_core /* i/o: HQ core data handle */ +) +{ + hHQ_core->memfilt_lb_fx = 0; + move16(); + hHQ_core->mean_prev_hb_fx = L_deposit_l(0); + hHQ_core->smoothmem_fx = 32767; + move16(); + hHQ_core->mean_prev_fx = L_deposit_l(0); + hHQ_core->mean_prev_nc_fx = L_deposit_l(0); + hHQ_core->wmold_hb_fx = 32767; + move16(); + hHQ_core->prevflag_fx = 0; + move16(); + hHQ_core->pastpre_fx = 0; + move16(); + + return; +} + +/*----------------------------------------------------------------------* + * destroy_cldfb_decoder() + * + * Free memory which was allocated in init_decoder() + *----------------------------------------------------------------------*/ + +void destroy_cldfb_decoder( + Decoder_State *st_fx /* o: Decoder static variables structure */ +) +{ + + /* CLDFB BPF & resampling tools */ + + /* delete analysis for max. SR 16kHz */ + deleteCldfb(&st_fx->cldfbAna_fx); + + /* delete analysis BPF for max. SR 16kHz */ + deleteCldfb(&st_fx->cldfbBPF_fx); + + /* delete synthesis for output SR */ + deleteCldfb(&st_fx->cldfbSyn_fx); + + deleteFdCngDec( &st_fx->hFdCngDec_fx ); + + return; +} diff --git a/lib_dec/inov_dec.c b/lib_dec/inov_dec.c index e8eaa38e87b07634625685d493b2b562819b4576..f281b6f4008b9af76bf524abba883ab3fbbca65d 100644 --- a/lib_dec/inov_dec.c +++ b/lib_dec/inov_dec.c @@ -124,7 +124,7 @@ void inov_decode( indexing_indices[i] = get_next_indice( st, bitcnt ); } config = PulseConfTable[st->acelp_cfg.fixed_cdk_index[i_subfr / L_SUBFR]]; - D_ACELP_indexing( code, config, NB_TRACK_FCB_4T, indexing_indices, &st->BER_detect ); + D_ACELP_indexing_ivas( code, config, NB_TRACK_FCB_4T, indexing_indices, &st->BER_detect ); } } else diff --git a/lib_dec/inov_dec_fx.c b/lib_dec/inov_dec_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..370635f5b7478c69c5e2d6b6ee3755688402927a --- /dev/null +++ b/lib_dec/inov_dec_fx.c @@ -0,0 +1,185 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include +#include "options.h" /* Compilation switches */ +#include "cnst.h" /* Common constants */ +#include "prot_fx1.h" /* Function prototypes */ +#include "prot_fx2.h" /* Function prototypes */ +#include "rom_com.h" /* Static table prototypes */ + +/*======================================================================*/ +/* FUNCTION : inov_decode_fx() */ +/*-----------------------------------------------------------------------*/ +/* PURPOSE : Decode the algebraic innovation and do pitch sharpening */ +/* */ +/*-----------------------------------------------------------------------*/ +/* INPUT ARGUMENTS : */ +/* _ (Word32) core_brate : Core bitrate Q0 */ +/* _ (Word16) Opt_AMR_WB : flag indicating AMR-WB IO mode Q0 */ +/* _ (Word16) L_frame : length of the frame Q0 */ +/* _ (Word16) i_subfr : length of the frame Q0 */ +/* _ (Word16) coder_type : coding type */ +/* _ (Word16) L_subfr : subframe length */ +/* _ (Word16) sharpFlag : formant sharpening flag */ +/* _ (Word16) tc_subfr : TC subframe index */ +/* _ (Word16 *) p_Aq : LP filter coefficients Q12 */ +/* _ (Word16) tilt_code : tilt of the excitation of previous subframe Q15*/ +/* _ (Word16) pt_pitch : current subframe fractional pitch Q6 */ +/*-----------------------------------------------------------------------*/ +/* OUTPUT ARGUMENTS : */ +/* _ (Word16 *[]) code : subframe length Q12 */ +/* _ (Word16 []) index_buf_4T : subframe length */ +/*-----------------------------------------------------------------------*/ +/* INPUT OUTPUT ARGUMENTS */ +/*-----------------------------------------------------------------------*/ + +/*-----------------------------------------------------------------------*/ +/* RETURN ARGUMENTS : */ +/* _ None */ +/*=======================================================================*/ + +void inov_decode_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + const Word32 core_brate, /* i : core bitrate */ + const Word16 Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ + const Word16 L_frame, /* i : length of the frame */ + const Word16 sharpFlag, /* i : formant sharpening flag */ + const Word16 i_subfr, /* i : subframe index */ + const Word16 *p_Aq, /* i : LP filter coefficients Q12 */ + const Word16 tilt_code, /* i : tilt of the excitation of previous subframe Q15 */ + const Word16 pt_pitch, /* i : pointer to current subframe fractional pitch Q6*/ + Word16 *code, /* o : algebraic excitation */ + const Word16 L_subfr /* i : subframe length */ +) +{ + Word16 nBits; + Word16 g1, g2; + + IF( EQ_16(L_frame,L_FRAME)) + { + g1 = FORMANT_SHARPENING_G1; + g2 = FORMANT_SHARPENING_G2; + } + ELSE + { + g1 = FORMANT_SHARPENING_G1_16k; + g2 = FORMANT_SHARPENING_G2_16k; + } + + IF ( !Opt_AMR_WB ) + { +#ifdef IVAS_CODE + if (st_fx->acelp_cfg.fcb_mode) + { + int16_t i; + int16_t indexing_indices[8], wordcnt, bitcnt; + PulseConfig config; + if (st_fx->acelp_cfg.fixed_cdk_index[i_subfr / L_subfr] >= 0) + { + if (L_subfr == 2 * L_SUBFR) + { + nBits = st_fx->acelp_cfg.fixed_cdk_index[i_subfr / L_subfr]; + + if (nBits == 8) + { + //dec_acelp_1t64(st_fx, code, L_subfr); + } + else + { + //dec_acelp_fast(st_fx, nBits, code, L_subfr); + } + } + //else if ((st_fx->idchan == 1 && st_fx->acelp_cfg.fixed_cdk_index[i_subfr / L_SUBFR] <= 7) || (st_fx->idchan == 0 && st_fx->acelp_cfg.fixed_cdk_index[i_subfr / L_SUBFR] <= 3)) + //{ + // if (st_fx->acelp_cfg.fixed_cdk_index[i_subfr / L_SUBFR] == 0) + // { + // dec_acelp_1t64(st_fx, code, L_SUBFR); + // } + // else + // { + // dec_acelp_fast(st_fx, st_fx->acelp_cfg.fixed_cdk_index[i_subfr / L_SUBFR], code, L_SUBFR); + // } + //} + else + { + wordcnt = ACELP_FIXED_CDK_BITS(st_fx->acelp_cfg.fixed_cdk_index[i_subfr / L_SUBFR]) >> 4; + bitcnt = ACELP_FIXED_CDK_BITS(st_fx->acelp_cfg.fixed_cdk_index[i_subfr / L_SUBFR]) & 15; +PMT("CONDITION above is missing -> idchan") + for (i = 0; i < wordcnt; i++) + { + indexing_indices[i] = get_next_indice(st_fx, 16); + } + if (bitcnt) + { + indexing_indices[i] = get_next_indice(st_fx, bitcnt); + } + config = PulseConfTable[st_fx->acelp_cfg.fixed_cdk_index[i_subfr / L_SUBFR]]; + D_ACELP_indexing(code, config, NB_TRACK_FCB_4T, indexing_indices, &st_fx->BER_detect); + } + } + else + { + set16_fx(code, 0.0f, L_SUBFR); + } + } + else +#endif + { + nBits = st_fx->acelp_cfg.fixed_cdk_index[i_subfr / L_SUBFR]; + + IF(EQ_16(nBits,7)) + { + dec_acelp_1t64_fx(st_fx, code, L_SUBFR); + } + ELSE IF( EQ_16(nBits,12)) + { + dec_acelp_2t32_fx( st_fx, code ); + } + ELSE + { + dec_acelp_4t64_fx( st_fx, nBits, code, Opt_AMR_WB ); + } + } + } + ELSE + { + IF ( EQ_32(core_brate,ACELP_6k60)) + { + dec_acelp_2t32_fx( st_fx, code ); + } + ELSE IF ( EQ_32(core_brate,ACELP_8k85)) + { + dec_acelp_4t64_fx( st_fx, 20, code, Opt_AMR_WB ); + } + ELSE IF ( EQ_32(core_brate,ACELP_12k65)) + { + dec_acelp_4t64_fx( st_fx, 36, code, Opt_AMR_WB ); + } + ELSE IF ( EQ_32(core_brate,ACELP_14k25)) + { + dec_acelp_4t64_fx( st_fx, 44, code, Opt_AMR_WB ); + } + ELSE IF ( EQ_32(core_brate,ACELP_15k85)) + { + dec_acelp_4t64_fx( st_fx, 52, code, Opt_AMR_WB ); + } + ELSE IF ( EQ_32(core_brate,ACELP_18k25)) + { + dec_acelp_4t64_fx( st_fx, 64, code, Opt_AMR_WB ); + } + ELSE IF ( EQ_32(core_brate,ACELP_19k85)) + { + dec_acelp_4t64_fx( st_fx, 72, code, Opt_AMR_WB ); + } + ELSE + { + dec_acelp_4t64_fx( st_fx, 88, code, Opt_AMR_WB ); + } + } + + cb_shape_fx( 1, 1, 0, sharpFlag, 0, g1, g2, p_Aq, code, tilt_code, shr(add(pt_pitch,26),6), 0, L_subfr); + return; + +} diff --git a/lib_dec/ivas_core_dec.c b/lib_dec/ivas_core_dec.c index 03bc07792657c09c1a7d5afbba445af7435183f2..e1a5b2a335e34fb89b2e5b487fd41f69820bd1eb 100644 --- a/lib_dec/ivas_core_dec.c +++ b/lib_dec/ivas_core_dec.c @@ -404,7 +404,7 @@ ivas_error ivas_core_dec( { if ( sts[n]->last_core_bfi != ACELP_CORE ) { - TonalMdctConceal_whiten_noise_shape( sts[n], L_FRAME16k, ON_FIRST_GOOD_FRAME ); + TonalMdctConceal_whiten_noise_shape_ivas( sts[n], L_FRAME16k, ON_FIRST_GOOD_FRAME ); } } } @@ -493,7 +493,7 @@ ivas_error ivas_core_dec( else if ( st->extl == WB_BWE && st->bws_cnt == 0 ) { /* WB BWE decoder */ - wb_bwe_dec( st, output[n], synth[n], hb_synth[n], use_cldfb_for_dft, output_frame, voice_factors[n], pitch_buf[n] ); + wb_bwe_dec_flt( st, output[n], synth[n], hb_synth[n], use_cldfb_for_dft, output_frame, voice_factors[n], pitch_buf[n] ); } /*---------------------------------------------------------------------* @@ -515,7 +515,7 @@ ivas_error ivas_core_dec( else if ( st->extl == SWB_BWE || st->extl == FB_BWE || ( output_Fs >= 32000 && st->core == ACELP_CORE && st->bwidth > NB && st->bws_cnt > 0 && !st->ppp_mode_dec && !( st->nelp_mode_dec == 1 && st->bfi == 1 ) ) ) { /* SWB BWE decoder */ - swb_bwe_dec( st, output[n], synth[n], hb_synth[n], use_cldfb_for_dft, output_frame ); + swb_bwe_dec_flt( st, output[n], synth[n], hb_synth[n], use_cldfb_for_dft, output_frame ); } /*---------------------------------------------------------------------* diff --git a/lib_dec/ivas_corecoder_dec_reconfig.c b/lib_dec/ivas_corecoder_dec_reconfig.c index e8d73d28c56ea26d62114dc61f6eb3d450fb900c..422bb5ef577a9d028d9a2262565cb3299d8b1206 100644 --- a/lib_dec/ivas_corecoder_dec_reconfig.c +++ b/lib_dec/ivas_corecoder_dec_reconfig.c @@ -475,7 +475,7 @@ ivas_error ivas_cldfb_dec_reconfig( remove the second CLDFB here, it was for CNA/CNG */ if ( st_ivas->ivas_format == SBA_FORMAT && nchan_transport_old == 1 && numCldfbAnalyses_old == 2 && st_ivas->nchan_transport > 1 ) { - deleteCldfb( &( st_ivas->cldfbAnaDec[1] ) ); + deleteCldfb_ivas( &( st_ivas->cldfbAnaDec[1] ) ); numCldfbAnalyses_old--; } @@ -484,7 +484,7 @@ ivas_error ivas_cldfb_dec_reconfig( { if ( ( st_ivas->cldfbAnaDec[i]->no_channels * st_ivas->cldfbAnaDec[i]->no_col ) != ( hDecoderConfig->output_Fs / FRAMES_PER_SEC ) ) { - resampleCldfb( st_ivas->cldfbAnaDec[i], hDecoderConfig->output_Fs ); + resampleCldfb_ivas( st_ivas->cldfbAnaDec[i], hDecoderConfig->output_Fs ); } } @@ -494,7 +494,7 @@ ivas_error ivas_cldfb_dec_reconfig( /* delete superfluous CLDFB synthesis instances */ for ( i = numCldfbAnalyses; i < numCldfbAnalyses_old; i++ ) { - deleteCldfb( &( st_ivas->cldfbAnaDec[i] ) ); + deleteCldfb_ivas( &( st_ivas->cldfbAnaDec[i] ) ); } } else if ( numCldfbAnalyses_old < numCldfbAnalyses ) @@ -502,7 +502,7 @@ ivas_error ivas_cldfb_dec_reconfig( /* create additional CLDFB synthesis instances */ for ( i = numCldfbAnalyses_old; i < numCldfbAnalyses; i++ ) { - if ( ( error = openCldfb( &( st_ivas->cldfbAnaDec[i] ), CLDFB_ANALYSIS, hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) + if ( ( error = openCldfb_ivas( &( st_ivas->cldfbAnaDec[i] ), CLDFB_ANALYSIS, hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) { return error; } @@ -515,7 +515,7 @@ ivas_error ivas_cldfb_dec_reconfig( /* delete superfluous CLDFB synthesis instances */ for ( i = numCldfbSyntheses; i < numCldfbSyntheses_old; i++ ) { - deleteCldfb( &( st_ivas->cldfbSynDec[i] ) ); + deleteCldfb_ivas( &( st_ivas->cldfbSynDec[i] ) ); } } else if ( numCldfbSyntheses_old < numCldfbSyntheses ) @@ -523,7 +523,7 @@ ivas_error ivas_cldfb_dec_reconfig( /* create additional CLDFB synthesis instances */ for ( i = numCldfbSyntheses_old; i < numCldfbSyntheses; i++ ) { - if ( ( error = openCldfb( &( st_ivas->cldfbSynDec[i] ), CLDFB_SYNTHESIS, hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) + if ( ( error = openCldfb_ivas( &( st_ivas->cldfbSynDec[i] ), CLDFB_SYNTHESIS, hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) { return error; } diff --git a/lib_dec/ivas_cpe_dec.c b/lib_dec/ivas_cpe_dec.c index 85c7b7a11dae4503febf6d0df03e8462bfe50536..eb6df1bf7f1db5f13a11007ddef6b1a4ee2636c3 100644 --- a/lib_dec/ivas_cpe_dec.c +++ b/lib_dec/ivas_cpe_dec.c @@ -356,7 +356,7 @@ ivas_error ivas_cpe_dec( for ( n = 0; n < n_channels; n++ ) { /* set ACELP12k8 / ACELP16k flag for flexible ACELP core */ - sts[n]->flag_ACELP16k = set_ACELP_flag( hCPE->element_mode, hCPE->element_brate, sts[n]->total_brate, n, ( hCPE->hStereoTD != NULL ? hCPE->hStereoTD->tdm_LRTD_flag : 0 ), sts[n]->bwidth, sts[n]->cng_type ); + sts[n]->flag_ACELP16k = set_ACELP_flag_IVAS( hCPE->element_mode, hCPE->element_brate, sts[n]->total_brate, n, ( hCPE->hStereoTD != NULL ? hCPE->hStereoTD->tdm_LRTD_flag : 0 ), sts[n]->bwidth, sts[n]->cng_type ); } for ( n = 0; n < n_channels; n++ ) diff --git a/lib_dec/ivas_decision_matrix_dec.c b/lib_dec/ivas_decision_matrix_dec.c index 0134e2ef666de734768456f18007c8ba3659d314..11786e016ff7ea369d528a8513c8566cb8084706 100644 --- a/lib_dec/ivas_decision_matrix_dec.c +++ b/lib_dec/ivas_decision_matrix_dec.c @@ -101,7 +101,7 @@ void ivas_decision_matrix_dec( else if ( st->total_brate == SID_2k40 && st->idchan == 1 && st->element_mode == IVAS_CPE_MDCT && st->cng_sba_flag == 0 ) { /* read channel coherence */ - st->hFdCngDec->hFdCngCom->coherence = (float) get_next_indice( st, 4 ) / 15.f; + st->hFdCngDec->hFdCngCom->coherence_flt = (float) get_next_indice( st, 4 ) / 15.f; /* read flag for no side noise shape */ st->hFdCngDec->hFdCngCom->no_side_flag = get_next_indice( st, 1 ); diff --git a/lib_dec/ivas_dirac_dec.c b/lib_dec/ivas_dirac_dec.c index 348a5ed5f4831e0e9704845a4d56d60105e9f8a7..e864a7a57f7e544f0554964ec60db8137511087d 100644 --- a/lib_dec/ivas_dirac_dec.c +++ b/lib_dec/ivas_dirac_dec.c @@ -1794,7 +1794,7 @@ void ivas_dirac_dec_render_sf( /* CLDFB Analysis*/ for ( ch = 0; ch < nchan_transport; ch++ ) { - cldfbAnalysis_ts( &( st_ivas->hTcBuffer->tc[hDirACRend->sba_map_tc[ch]][hSpatParamRendCom->num_freq_bands * index_slot] ), + cldfbAnalysis_ts_ivas( &( st_ivas->hTcBuffer->tc[hDirACRend->sba_map_tc[ch]][hSpatParamRendCom->num_freq_bands * index_slot] ), Cldfb_RealBuffer_Temp[ch][slot_idx], Cldfb_ImagBuffer_Temp[ch][slot_idx], hSpatParamRendCom->num_freq_bands, @@ -1840,7 +1840,7 @@ void ivas_dirac_dec_render_sf( /* CLDFB Analysis*/ for ( ch = 0; ch < nchan_transport; ch++ ) { - cldfbAnalysis_ts( &( st_ivas->hTcBuffer->tc[hDirACRend->sba_map_tc[ch]][hSpatParamRendCom->num_freq_bands * index_slot] ), + cldfbAnalysis_ts_ivas( &( st_ivas->hTcBuffer->tc[hDirACRend->sba_map_tc[ch]][hSpatParamRendCom->num_freq_bands * index_slot] ), Cldfb_RealBuffer[ch][0], Cldfb_ImagBuffer[ch][0], hSpatParamRendCom->num_freq_bands, @@ -2264,7 +2264,7 @@ void ivas_dirac_dec_render_sf( ImagBuffer[i] = Cldfb_ImagBuffer_Binaural[ch][i]; } - cldfbSynthesis( RealBuffer, ImagBuffer, &( output_f[ch][index_slot * hSpatParamRendCom->num_freq_bands] ), hSpatParamRendCom->num_freq_bands * hSpatParamRendCom->subframe_nbslots[subframe_idx], st_ivas->cldfbSynDec[ch] ); + cldfbSynthesis_ivas( RealBuffer, ImagBuffer, &( output_f[ch][index_slot * hSpatParamRendCom->num_freq_bands] ), hSpatParamRendCom->num_freq_bands * hSpatParamRendCom->subframe_nbslots[subframe_idx], st_ivas->cldfbSynDec[ch] ); } } else if ( st_ivas->ivas_format == SBA_FORMAT || st_ivas->ivas_format == SBA_ISM_FORMAT ) @@ -2335,7 +2335,7 @@ void ivas_dirac_dec_render_sf( RealBuffer[i] = Cldfb_RealBuffer[idx_in][i]; ImagBuffer[i] = Cldfb_ImagBuffer[idx_in][i]; } - cldfbSynthesis( RealBuffer, ImagBuffer, &( output_f[ch][subframe_start_sample] ), num_samples_subframe, st_ivas->cldfbSynDec[idx_in] ); + cldfbSynthesis_ivas( RealBuffer, ImagBuffer, &( output_f[ch][subframe_start_sample] ), num_samples_subframe, st_ivas->cldfbSynDec[idx_in] ); if ( !st_ivas->hLsSetupCustom->separate_ch_found ) { @@ -2361,7 +2361,7 @@ void ivas_dirac_dec_render_sf( RealBuffer[i] = Cldfb_RealBuffer[MAX_OUTPUT_CHANNELS - 1][i]; ImagBuffer[i] = Cldfb_ImagBuffer[MAX_OUTPUT_CHANNELS - 1][i]; } - cldfbSynthesis( RealBuffer, ImagBuffer, &( output_f[ch][index_slot * hSpatParamRendCom->num_freq_bands] ), hSpatParamRendCom->num_freq_bands * hSpatParamRendCom->subframe_nbslots[subframe_idx], st_ivas->cldfbSynDec[hDirACRend->hOutSetup.nchan_out_woLFE + idx_lfe] ); + cldfbSynthesis_ivas( RealBuffer, ImagBuffer, &( output_f[ch][index_slot * hSpatParamRendCom->num_freq_bands] ), hSpatParamRendCom->num_freq_bands * hSpatParamRendCom->subframe_nbslots[subframe_idx], st_ivas->cldfbSynDec[hDirACRend->hOutSetup.nchan_out_woLFE + idx_lfe] ); } else if ( st_ivas->mc_mode == MC_MODE_MCMASA && hDirACRend->hOutSetup.separateChannelEnabled ) { @@ -2390,7 +2390,7 @@ void ivas_dirac_dec_render_sf( RealBuffer[i] = Cldfb_RealBuffer[idx_in][i]; ImagBuffer[i] = Cldfb_ImagBuffer[idx_in][i]; } - cldfbSynthesis( RealBuffer, ImagBuffer, &( output_f[ch][index_slot * hSpatParamRendCom->num_freq_bands] ), hSpatParamRendCom->num_freq_bands * hSpatParamRendCom->subframe_nbslots[subframe_idx], st_ivas->cldfbSynDec[idx_in] ); + cldfbSynthesis_ivas( RealBuffer, ImagBuffer, &( output_f[ch][index_slot * hSpatParamRendCom->num_freq_bands] ), hSpatParamRendCom->num_freq_bands * hSpatParamRendCom->subframe_nbslots[subframe_idx], st_ivas->cldfbSynDec[idx_in] ); idx_in++; } } diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index 4951f9e198ad897d4b42f601748ae3291e7fc76d..d88605eed9717f4472d5cce00600f50369a4ccf4 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -1834,7 +1834,7 @@ ivas_error ivas_init_decoder( FOR ( i = 0; i < numCldfbAnalyses; i++ ) { - IF ( ( error = openCldfb( &( st_ivas->cldfbAnaDec[i] ), CLDFB_ANALYSIS, output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) + IF ( ( error = openCldfb_ivas( &( st_ivas->cldfbAnaDec[i] ), CLDFB_ANALYSIS, output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) { return error; } @@ -1846,7 +1846,7 @@ ivas_error ivas_init_decoder( FOR ( i = 0; i < numCldfbSyntheses; i++ ) { - IF ( ( error = openCldfb( &( st_ivas->cldfbSynDec[i] ), CLDFB_SYNTHESIS, output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) + IF ( ( error = openCldfb_ivas( &( st_ivas->cldfbSynDec[i] ), CLDFB_SYNTHESIS, output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) { return error; } @@ -1940,7 +1940,7 @@ void destroy_core_dec( DEC_CORE_HANDLE hCoreCoder /* i/o: core decoder structure */ ) { - destroy_cldfb_decoder( hCoreCoder ); + destroy_cldfb_decoder_flt( hCoreCoder ); IF ( hCoreCoder->hGSCDec != NULL ) { @@ -2186,7 +2186,7 @@ void ivas_destroy_dec( { IF ( st_ivas->cldfbAnaDec[i] != NULL ) { - deleteCldfb( &( st_ivas->cldfbAnaDec[i] ) ); + deleteCldfb_ivas( &( st_ivas->cldfbAnaDec[i] ) ); } } @@ -2194,7 +2194,7 @@ void ivas_destroy_dec( { IF ( st_ivas->cldfbSynDec[i] != NULL ) { - deleteCldfb( &( st_ivas->cldfbSynDec[i] ) ); + deleteCldfb_ivas( &( st_ivas->cldfbSynDec[i] ) ); } } diff --git a/lib_dec/ivas_ism_dtx_dec.c b/lib_dec/ivas_ism_dtx_dec.c index 998dc97ee9e7ea49ea9746fc58c00245cdac65eb..c06c9bfe087334529e25cdc80d3c26febf257b5c 100644 --- a/lib_dec/ivas_ism_dtx_dec.c +++ b/lib_dec/ivas_ism_dtx_dec.c @@ -153,7 +153,7 @@ void ivas_ism_dtx_limit_noise_energy_for_near_silence( hFdCngCom = hSCE[sce_id_dtx]->hCoreCoder[0]->hFdCngDec->hFdCngCom; cng_noise_level_len = hFdCngCom->stopFFTbin - hFdCngCom->startBand; - cng_noise_nrg_dominant = dotp( hFdCngCom->cngNoiseLevel, hFdCngCom->cngNoiseLevel, cng_noise_level_len ); + cng_noise_nrg_dominant = dotp( hFdCngCom->cngNoiseLevel_flt, hFdCngCom->cngNoiseLevel_flt, cng_noise_level_len ); if ( cng_noise_nrg_dominant < 1.f ) { @@ -166,12 +166,12 @@ void ivas_ism_dtx_limit_noise_energy_for_near_silence( hFdCngCom = hSCE[ch]->hCoreCoder[0]->hFdCngDec->hFdCngCom; cng_noise_level_len = hFdCngCom->stopFFTbin - hFdCngCom->startBand; - cng_noise_nrg_obj = dotp( hFdCngCom->cngNoiseLevel, hFdCngCom->cngNoiseLevel, cng_noise_level_len ); + cng_noise_nrg_obj = dotp( hFdCngCom->cngNoiseLevel_flt, hFdCngCom->cngNoiseLevel_flt, cng_noise_level_len ); if ( cng_noise_nrg_obj > cng_noise_nrg_dominant ) { fac = sqrtf( cng_noise_nrg_dominant / cng_noise_nrg_obj ); - v_multc( hFdCngCom->cngNoiseLevel, fac, hFdCngCom->cngNoiseLevel, cng_noise_level_len ); + v_multc( hFdCngCom->cngNoiseLevel_flt, fac, hFdCngCom->cngNoiseLevel_flt, cng_noise_level_len ); } } } diff --git a/lib_dec/ivas_ism_metadata_dec.c b/lib_dec/ivas_ism_metadata_dec.c index c4b07078dc0d303b6f16665629b5455bb9b9e948..4647b901fb8c63a0762427289bdabc4c30f1ad83 100644 --- a/lib_dec/ivas_ism_metadata_dec.c +++ b/lib_dec/ivas_ism_metadata_dec.c @@ -1025,18 +1025,18 @@ void ivas_ism_metadata_sid_dec( { if ( ch == *sce_id_dtx ) { - hSCE[ch]->hCoreCoder[0]->hFdCngDec->hFdCngCom->coherence = 1.0f; + hSCE[ch]->hCoreCoder[0]->hFdCngDec->hFdCngCom->coherence_flt = 1.0f; continue; } idx = get_next_indice( st0, nBits_coh ); - hSCE[ch]->hCoreCoder[0]->hFdCngDec->hFdCngCom->coherence = (float) ( idx ) / (float) ( ( 1 << nBits_coh ) - 1 ); + hSCE[ch]->hCoreCoder[0]->hFdCngDec->hFdCngCom->coherence_flt = (float) ( idx ) / (float) ( ( 1 << nBits_coh ) - 1 ); } } if ( ism_mode == ISM_MODE_PARAM ) { - hSCE[*sce_id_dtx]->hCoreCoder[0]->hFdCngDec->hFdCngCom->coherence = hSCE[!*sce_id_dtx]->hCoreCoder[0]->hFdCngDec->hFdCngCom->coherence; + hSCE[*sce_id_dtx]->hCoreCoder[0]->hFdCngDec->hFdCngCom->coherence_flt = hSCE[!*sce_id_dtx]->hCoreCoder[0]->hFdCngDec->hFdCngCom->coherence_flt; } /*----------------------------------------------------------------* diff --git a/lib_dec/ivas_ism_param_dec.c b/lib_dec/ivas_ism_param_dec.c index 9f48c82e171e112a35e052382d7c521d8b06cb1c..05aca6651625ded47986685b3c5555e7f4c14e69 100644 --- a/lib_dec/ivas_ism_param_dec.c +++ b/lib_dec/ivas_ism_param_dec.c @@ -858,7 +858,7 @@ void ivas_param_ism_dec( /* CLDFB Analysis */ for ( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX; slot_idx++ ) { - cldfbAnalysis_ts( &( output_f[ch][hSpatParamRendCom->num_freq_bands * slot_idx] ), Cldfb_RealBuffer_in[ch][slot_idx], Cldfb_ImagBuffer_in[ch][slot_idx], hSpatParamRendCom->num_freq_bands, st_ivas->cldfbAnaDec[ch] ); + cldfbAnalysis_ts_ivas( &( output_f[ch][hSpatParamRendCom->num_freq_bands * slot_idx] ), Cldfb_RealBuffer_in[ch][slot_idx], Cldfb_ImagBuffer_in[ch][slot_idx], hSpatParamRendCom->num_freq_bands, st_ivas->cldfbAnaDec[ch] ); ivas_param_ism_collect_slot( hParamIsmDec, Cldfb_RealBuffer_in[ch][slot_idx], Cldfb_ImagBuffer_in[ch][slot_idx], ch, ref_power, cx_diag ); } @@ -926,7 +926,7 @@ void ivas_param_ism_dec( ImagBuffer[i] = Cldfb_ImagBuffer[idx_in][i]; } - cldfbSynthesis( RealBuffer, ImagBuffer, &( output_f[ch][slot_idx_start * hSpatParamRendCom->num_freq_bands] ), + cldfbSynthesis_ivas( RealBuffer, ImagBuffer, &( output_f[ch][slot_idx_start * hSpatParamRendCom->num_freq_bands] ), hSpatParamRendCom->num_freq_bands * hSpatParamRendCom->subframe_nbslots[subframe_idx], st_ivas->cldfbSynDec[ch] ); idx_in++; @@ -1200,7 +1200,7 @@ void ivas_param_ism_dec_digest_tc( float RealBuffer[CLDFB_NO_CHANNELS_MAX]; float ImagBuffer[CLDFB_NO_CHANNELS_MAX]; - cldfbAnalysis_ts( &( transport_channels_f[ch][hSpatParamRendCom->num_freq_bands * slot_idx] ), RealBuffer, ImagBuffer, hSpatParamRendCom->num_freq_bands, st_ivas->cldfbAnaDec[ch] ); + cldfbAnalysis_ts_ivas( &( transport_channels_f[ch][hSpatParamRendCom->num_freq_bands * slot_idx] ), RealBuffer, ImagBuffer, hSpatParamRendCom->num_freq_bands, st_ivas->cldfbAnaDec[ch] ); mvr2r( RealBuffer, &hParamIsmDec->hParamIsmRendering->Cldfb_RealBuffer_tc[slot_idx * hSpatParamRendCom->num_freq_bands * nchan_transport + ch * hSpatParamRendCom->num_freq_bands], hSpatParamRendCom->num_freq_bands ); mvr2r( ImagBuffer, &hParamIsmDec->hParamIsmRendering->Cldfb_ImagBuffer_tc[slot_idx * hSpatParamRendCom->num_freq_bands * nchan_transport + ch * hSpatParamRendCom->num_freq_bands], hSpatParamRendCom->num_freq_bands ); } @@ -1368,7 +1368,7 @@ static void ivas_ism_param_dec_render_sf( ImagBuffer[i] = Cldfb_ImagBuffer[idx_in][i]; } - cldfbSynthesis( RealBuffer, ImagBuffer, output_f[ch], hSpatParamRendCom->num_freq_bands * hSpatParamRendCom->subframe_nbslots[subframe_idx], st_ivas->cldfbSynDec[ch] ); + cldfbSynthesis_ivas( RealBuffer, ImagBuffer, output_f[ch], hSpatParamRendCom->num_freq_bands * hSpatParamRendCom->subframe_nbslots[subframe_idx], st_ivas->cldfbSynDec[ch] ); idx_in++; } } @@ -1516,7 +1516,7 @@ void ivas_param_ism_params_to_masa_param_mapping( if ( st_ivas->hISMDTX.dtx_flag ) { float energy_ratio; - energy_ratio = powf( st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->coherence, 2.0f ); + energy_ratio = powf( st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->coherence_flt, 2.0f ); hSpatParamRendCom->numSimultaneousDirections = 1; azimuth[0] = (int16_t) roundf( hParamIsmDec->azimuth_values[0] ); diff --git a/lib_dec/ivas_jbm_dec.c b/lib_dec/ivas_jbm_dec.c index a2f6bf5c19211fda01ef9e5dafd3a36dede6649a..e7d3709463dfc2236a5fcc43312ee1745c538933 100644 --- a/lib_dec/ivas_jbm_dec.c +++ b/lib_dec/ivas_jbm_dec.c @@ -2565,7 +2565,7 @@ void ivas_jbm_dec_copy_tc_no_tsm( { for ( slot_idx = 0; slot_idx < DEFAULT_JBM_CLDFB_TIMESLOTS; slot_idx++ ) { - cldfbAnalysis_ts( &( tc[ch_idx][num_freq_bands * slot_idx] ), + cldfbAnalysis_ts_ivas( &( tc[ch_idx][num_freq_bands * slot_idx] ), &cldfb_real_buffer[slot_idx * num_freq_bands * n_ch_cldfb + cldfb_ch * num_freq_bands], &cldfb_imag_buffer[slot_idx * num_freq_bands * n_ch_cldfb + cldfb_ch * num_freq_bands], num_freq_bands, st_ivas->cldfbAnaDec[cldfb_ch] ); diff --git a/lib_dec/ivas_mc_param_dec.c b/lib_dec/ivas_mc_param_dec.c index 5536baa149d9fcb52ee70ddb1374580048b1137c..4ea487a5f46b00881479853219bae967621f87ec 100644 --- a/lib_dec/ivas_mc_param_dec.c +++ b/lib_dec/ivas_mc_param_dec.c @@ -1468,7 +1468,7 @@ void ivas_param_mc_dec_digest_tc( /* CLDFB Analysis*/ for ( ch = 0; ch < nchan_transport; ch++ ) { - cldfbAnalysis_ts( &( transport_channels_f[ch][hParamMC->num_freq_bands * slot_idx] ), RealBuffer, ImagBuffer, hParamMC->num_freq_bands, st_ivas->cldfbAnaDec[ch] ); + cldfbAnalysis_ts_ivas( &( transport_channels_f[ch][hParamMC->num_freq_bands * slot_idx] ), RealBuffer, ImagBuffer, hParamMC->num_freq_bands, st_ivas->cldfbAnaDec[ch] ); mvr2r( RealBuffer, &hParamMC->Cldfb_RealBuffer_tc[slot_idx * hParamMC->num_freq_bands * nchan_transport + ch * hParamMC->num_freq_bands], hParamMC->num_freq_bands ); mvr2r( ImagBuffer, &hParamMC->Cldfb_ImagBuffer_tc[slot_idx * hParamMC->num_freq_bands * nchan_transport + ch * hParamMC->num_freq_bands], hParamMC->num_freq_bands ); @@ -1784,7 +1784,7 @@ void ivas_param_mc_dec_render( } } - cldfbSynthesis( RealBuffer, ImagBuffer, &( output_f[ch][slot_idx_start_cldfb_synth * hParamMC->num_freq_bands] ), + cldfbSynthesis_ivas( RealBuffer, ImagBuffer, &( output_f[ch][slot_idx_start_cldfb_synth * hParamMC->num_freq_bands] ), hParamMC->num_freq_bands * hParamMC->subframe_nbslots[subframe_idx], st_ivas->cldfbSynDec[ch] ); } else diff --git a/lib_dec/ivas_mc_paramupmix_dec.c b/lib_dec/ivas_mc_paramupmix_dec.c index 50c286d90cf6a28e72804796fc6561a4b7b2b6c7..efc15aa597cb1cbe6e99f26f7098ffd7958ab4b4 100644 --- a/lib_dec/ivas_mc_paramupmix_dec.c +++ b/lib_dec/ivas_mc_paramupmix_dec.c @@ -650,7 +650,7 @@ static void ivas_mc_paramupmix_dec_sf( /* slot loop for gathering the input data */ for ( slot_idx = 0; slot_idx < st_ivas->hTcBuffer->subframe_nbslots[st_ivas->hTcBuffer->subframes_rendered]; slot_idx++ ) { - cldfbAnalysis_ts( &( pPcm_temp[ch][hMCParamUpmix->num_freq_bands * slot_idx] ), Cldfb_RealBuffer[ch][slot_idx], Cldfb_ImagBuffer[ch][slot_idx], hMCParamUpmix->num_freq_bands, st_ivas->cldfbAnaDec[ch] ); + cldfbAnalysis_ts_ivas( &( pPcm_temp[ch][hMCParamUpmix->num_freq_bands * slot_idx] ), Cldfb_RealBuffer[ch][slot_idx], Cldfb_ImagBuffer[ch][slot_idx], hMCParamUpmix->num_freq_bands, st_ivas->cldfbAnaDec[ch] ); } } for ( ch = 0; ch < MC_PARAMUPMIX_COMBINATIONS; ch++ ) @@ -698,7 +698,7 @@ static void ivas_mc_paramupmix_dec_sf( /* slot loop for gathering the input data */ for ( slot_idx = 0; slot_idx < st_ivas->hTcBuffer->subframe_nbslots[st_ivas->hTcBuffer->subframes_rendered]; slot_idx++ ) { - cldfbAnalysis_ts( &( pPcm_temp[ch][hMCParamUpmix->num_freq_bands * slot_idx] ), + cldfbAnalysis_ts_ivas( &( pPcm_temp[ch][hMCParamUpmix->num_freq_bands * slot_idx] ), Cldfb_RealBuffer_subfr[idx_in][slot_idx], Cldfb_ImagBuffer_subfr[idx_in][slot_idx], maxBand, st_ivas->cldfbAnaDec[2 * MC_PARAMUPMIX_COMBINATIONS + idx_in] ); @@ -750,7 +750,7 @@ static void ivas_mc_paramupmix_dec_sf( ImagBuffer[slot_idx] = Cldfb_ImagBuffer_Binaural[ch][slot_idx]; } - cldfbSynthesis( RealBuffer, ImagBuffer, &( output_f[ch][0] ), maxBand * st_ivas->hTcBuffer->subframe_nbslots[subframeIdx], st_ivas->cldfbSynDec[ch] ); + cldfbSynthesis_ivas( RealBuffer, ImagBuffer, &( output_f[ch][0] ), maxBand * st_ivas->hTcBuffer->subframe_nbslots[subframeIdx], st_ivas->cldfbSynDec[ch] ); } } else @@ -774,7 +774,7 @@ static void ivas_mc_paramupmix_dec_sf( ptr_re[0] = Cldfb_RealBuffer[ch][slot_idx]; ptr_im[0] = Cldfb_ImagBuffer[ch][slot_idx]; - cldfbSynthesis( ptr_re, ptr_im, &( pPcm_temp[ch][hMCParamUpmix->num_freq_bands * slot_idx] ), + cldfbSynthesis_ivas( ptr_re, ptr_im, &( pPcm_temp[ch][hMCParamUpmix->num_freq_bands * slot_idx] ), hMCParamUpmix->num_freq_bands, st_ivas->cldfbSynDec[ch] ); } } diff --git a/lib_dec/ivas_mct_dec.c b/lib_dec/ivas_mct_dec.c index 0212b00b528b5383efaf7a74826a638e1d9955b2..80d0d882926e3cd42fd76f9f2ac8ddfc223f556a 100644 --- a/lib_dec/ivas_mct_dec.c +++ b/lib_dec/ivas_mct_dec.c @@ -492,7 +492,7 @@ ivas_error mct_dec_reconfigure( st->igf = getIgfPresent( st->element_mode, st->bits_frame_nominal * FRAMES_PER_SEC, st->bwidth, st->rf_flag ); if ( st->igf ) { - IGFDecSetMode( st->hIGFDec, st_ivas->hCPE[cpe_id]->element_brate, st->bwidth, st->element_mode, -1, -1, st->rf_flag ); + IGFDecSetMode_flt( st->hIGFDec, st_ivas->hCPE[cpe_id]->element_brate, st->bwidth, st->element_mode, -1, -1, st->rf_flag ); } } } @@ -975,7 +975,7 @@ static ivas_error ivas_mc_dec_reconfig( } st->igf = 0; - init_igf_dec( st->hIGFDec ); + init_igf_dec_flt( st->hIGFDec ); } if ( st->hHQ_core == NULL ) @@ -986,7 +986,7 @@ static ivas_error ivas_mc_dec_reconfig( } /* HQ core initialization */ - HQ_core_dec_init( st->hHQ_core ); + HQ_core_dec_init_flt( st->hHQ_core ); } /* check if we have a doubly used hTxcCfg, if so, allocate a distint one for the old MCT LFE channel */ diff --git a/lib_dec/ivas_mdct_core_dec.c b/lib_dec/ivas_mdct_core_dec.c index bdf7bf0e534c52f764b22b9d236461c10b3ab0c3..00dff066cc22bdf7c26a3011cecf2f41c6014087 100644 --- a/lib_dec/ivas_mdct_core_dec.c +++ b/lib_dec/ivas_mdct_core_dec.c @@ -64,20 +64,20 @@ void mdct_read_IGF_bits( if ( st->core == TCX_20_CORE ) { /* read IGF payload */ - IGFDecReadLevel( st->hIGFDec, st0, ( st->last_core == ACELP_CORE ) ? IGF_GRID_LB_TRAN : IGF_GRID_LB_NORM, 1 ); + IGFDecReadLevel_flt( st->hIGFDec, st0, ( st->last_core == ACELP_CORE ) ? IGF_GRID_LB_TRAN : IGF_GRID_LB_NORM, 1 ); - IGFDecReadData( st->hIGFDec, st0, ( st->last_core == ACELP_CORE ) ? IGF_GRID_LB_TRAN : IGF_GRID_LB_NORM, 1 ); + IGFDecReadData_flt( st->hIGFDec, st0, ( st->last_core == ACELP_CORE ) ? IGF_GRID_LB_TRAN : IGF_GRID_LB_NORM, 1 ); } if ( st->core == TCX_10_CORE ) { for ( k = 0; k < 2; k++ ) { - IGFDecReadLevel( st->hIGFDec, st0, IGF_GRID_LB_SHORT, k == 0 ? 1 : 0 ); + IGFDecReadLevel_flt( st->hIGFDec, st0, IGF_GRID_LB_SHORT, k == 0 ? 1 : 0 ); - IGFDecReadData( st->hIGFDec, st0, IGF_GRID_LB_SHORT, k == 0 ? 1 : 0 ); + IGFDecReadData_flt( st->hIGFDec, st0, IGF_GRID_LB_SHORT, k == 0 ? 1 : 0 ); - IGFDecStoreTCX10SubFrameData( st->hIGFDec, k ); + IGFDecStoreTCX10SubFrameData_flt( st->hIGFDec, k ); } } @@ -124,7 +124,7 @@ static void dec_prm_tcx_sidebits( *--------------------------------------------------------------------------------*/ /* Modes (ACE_GC, ACE_UC, TCX20, TCX10...) */ - getTCXMode( st, st0, MCT_flag ); + getTCXMode_ivas( st, st0, MCT_flag ); st->flagGuidedAcelp = 0; @@ -151,7 +151,7 @@ static void dec_prm_tcx_sidebits( st->last_core_from_bs = st->last_core; } - getTCXWindowing( st->core, st->last_core, st->element_mode, st->hTcxCfg, st0 ); + getTCXWindowing_ivas( st->core, st->last_core, st->element_mode, st->hTcxCfg, st0 ); st->hTcxDec->kernel_type[0] = st->hTcxDec->kernel_type[1] = MDCT_IV; st->hTcxDec->kernel_type[0] = get_next_indice( st0, st->last_core_from_bs != ACELP_CORE ? 2 : 1 ); @@ -185,7 +185,7 @@ static void dec_prm_tcx_sidebits( * TCX20/TCX10 parameters *--------------------------------------------------------------------------------*/ - getTCXparam( st, st0, hm_cfg, param, 0, 0, ( ( ch > 0 ) && ( tnsSize ) && ( tnsSize[0] + tnsSize[1] > 0 ) ? tnsSize : NULL ), p_param, nTnsBitsTCX10, 0 ); + getTCXparam_ivas( st, st0, hm_cfg, param, 0, 0, ( ( ch > 0 ) && ( tnsSize ) && ( tnsSize[0] + tnsSize[1] > 0 ) ? tnsSize : NULL ), p_param, nTnsBitsTCX10, 0 ); st->side_bits_frame_channel = st0->next_bit_pos - start_bit_pos; @@ -244,7 +244,7 @@ static void dec_prm_tcx_spec( * TCX20/TCX10 parameters *--------------------------------------------------------------------------------*/ - getTCXparam( st, st, hm_cfg, param, 0, 0, NULL, p_param, target_bitsTCX10, 1 ); + getTCXparam_ivas( st, st, hm_cfg, param, 0, 0, NULL, p_param, target_bitsTCX10, 1 ); nf_bits = nSubframes * ( NBITS_TCX_GAIN + NOISE_FILL_RANGES * NBITS_NOISE_FILL_LEVEL ); @@ -447,7 +447,7 @@ void ivas_mdct_dec_side_bits_frame_channel( tmp = 3; } - getLPCparam( st, ¶m_lpc[ch][0], st0, tmp, sns_low_br_mode && !( sts[0]->core == TCX_20 && sts[1]->core == TCX_20 ) ); + getLPCparam_ivas( st, ¶m_lpc[ch][0], st0, tmp, sns_low_br_mode && !( sts[0]->core == TCX_20 && sts[1]->core == TCX_20 ) ); st->side_bits_frame_channel += st0->next_bit_pos - start_bit_pos_sns; } @@ -604,7 +604,7 @@ void ivas_mdct_core_invQ( /* PLC: [Common: mode decision] * PLC: Decide which Concealment to use. Update pitch lags if needed */ - st->core = GetPLCModeDecision( st ); + st->core = GetPLCModeDecision_flt( st ); } if ( ( !st->bfi || st->hTcxCfg->psychParamsCurrent == NULL ) && st->core > ACELP_CORE ) @@ -751,7 +751,7 @@ void ivas_mdct_core_invQ( if ( bfi && !MCT_flag ) { - TonalMdctConceal_create_concealment_noise( concealment_noise[ch], hCPE, L_frameTCX[ch], L_frame[ch], ch, k, st->core, st->hTcxDec->cummulative_damping_tcx_float, noise_gen_mode_bfi ); + TonalMdctConceal_create_concealment_noise_ivas( concealment_noise[ch], hCPE, L_frameTCX[ch], L_frame[ch], ch, k, st->core, st->hTcxDec->cummulative_damping_tcx_float, noise_gen_mode_bfi ); } decoder_tcx_noisefilling( st, concealment_noise[ch], Aq[ch], L_frameTCX_global[ch], L_spec[ch], L_frame[ch], L_frameTCX[ch], x[ch][k], NULL, &tmp_concealment_method, gain_tcx, prm_sqQ, nf_seed, bfi, MCT_flag, k ); @@ -852,10 +852,10 @@ void ivas_mdct_core_reconstruct( if ( !bfi && st->hTonalMDCTConc != NULL ) { - TonalMDCTConceal_SaveTimeSignal( st->hTonalMDCTConc, synthFB, L_frameTCX[ch] ); + TonalMDCTConceal_SaveTimeSignal_ivas( st->hTonalMDCTConc, synthFB, L_frameTCX[ch] ); } - decoder_tcx_post( st, synth, synthFB, NULL, bfi, MCT_flag ); + decoder_tcx_post_flt( st, synth, synthFB, NULL, bfi, MCT_flag ); } else /*ACELP core for ACELP-PLC */ { @@ -863,11 +863,11 @@ void ivas_mdct_core_reconstruct( /* PLC: [TCX: TD PLC] */ if ( MCT_flag ) { - con_tcx( st, &synthFB[0], -1.f, NULL, 0, NULL ); + con_tcx_flt( st, &synthFB[0], -1.f, NULL, 0, NULL ); } else { - con_tcx( st, &synthFB[0], hCPE->hStereoMdct->lastCoh, &sts[0]->seed_acelp, ( sts[1]->core != ACELP_CORE ) ? 1 : 0, &st->hFdCngDec->hFdCngCom->A_cng[0] ); + con_tcx_flt( st, &synthFB[0], hCPE->hStereoMdct->lastCoh, &sts[0]->seed_acelp, ( sts[1]->core != ACELP_CORE ) ? 1 : 0, &st->hFdCngDec->hFdCngCom->A_cng_flt[0] ); } lerp_flt( synthFB, synth, st->L_frame, st->hTcxDec->L_frameTCX ); @@ -878,7 +878,7 @@ void ivas_mdct_core_reconstruct( /* Signal that this frame is not TCX */ if ( st->hTonalMDCTConc != NULL ) { - TonalMDCTConceal_UpdateState( st->hTonalMDCTConc, 0, 0, 0, 0 ); + TonalMDCTConceal_UpdateState_ivas( st->hTonalMDCTConc, 0, 0, 0, 0 ); } } @@ -916,7 +916,7 @@ void ivas_mdct_core_reconstruct( st->last_is_cng = 0; /* Postfiltering */ - post_decoder( st, synth_buf, pit_gain[ch], pitch[ch], x[ch][0], st->p_bpf_noise_buf_float); + post_decoder_flt( st, synth_buf, pit_gain[ch], pitch[ch], x[ch][0], st->p_bpf_noise_buf_float); if ( signal_outFB[ch] ) { @@ -1001,7 +1001,7 @@ void ivas_mdct_core_tns_ns( { if ( st->hTonalMDCTConc != NULL ) { - TonalMDCTConceal_UpdateState( st->hTonalMDCTConc, st->hTcxDec->L_frameTCX, 0, bfi, 0 ); + TonalMDCTConceal_UpdateState_ivas( st->hTonalMDCTConc, st->hTcxDec->L_frameTCX, 0, bfi, 0 ); } /* nothing to do for missing LFE */ @@ -1019,7 +1019,7 @@ void ivas_mdct_core_tns_ns( if ( MCT_flag && st->hTonalMDCTConc != NULL && ( ( k + 1 ) == nSubframes[ch] ) ) { - TonalMDCTConceal_SaveFreqSignal( st->hTonalMDCTConc, x[ch][k], L_frameTCX[ch], L_frame[ch], &sns_int_scf[0], get_igf_startline( st, L_frame[ch], L_frameTCX[ch] ) ); + TonalMDCTConceal_SaveFreqSignal_ivas( st->hTonalMDCTConc, x[ch][k], L_frameTCX[ch], L_frame[ch], &sns_int_scf[0], get_igf_startline_flt( st, L_frame[ch], L_frameTCX[ch] ) ); } } else @@ -1062,12 +1062,12 @@ void ivas_mdct_core_tns_ns( if ( bfi && st->tonal_mdct_plc_active ) { - TonalMDCTConceal_Apply( st->hTonalMDCTConc, x[ch][0], st->hTcxCfg->psychParamsCurrent ); + TonalMDCTConceal_Apply_ivas( st->hTonalMDCTConc, x[ch][0], st->hTcxCfg->psychParamsCurrent ); } if ( ( bfi || MCT_flag ) && st->hTonalMDCTConc != NULL ) { - TonalMDCTConceal_UpdateState( st->hTonalMDCTConc, L_frameTCX[ch], ( st->hTcxDec->tcxltp_last_gain_unmodified_float > 0 ) ? st->old_fpitch_float : 0, bfi, bfi && st->tonal_mdct_plc_active ); + TonalMDCTConceal_UpdateState_ivas( st->hTonalMDCTConc, L_frameTCX[ch], ( st->hTcxDec->tcxltp_last_gain_unmodified_float > 0 ) ? st->old_fpitch_float : 0, bfi, bfi && st->tonal_mdct_plc_active ); } } diff --git a/lib_dec/ivas_post_proc.c b/lib_dec/ivas_post_proc.c index e29366eb68b74dde43cbb3dd7fc4151153c5f13d..5ff377606458b36f87f3fcf377d11a210a9600a2 100644 --- a/lib_dec/ivas_post_proc.c +++ b/lib_dec/ivas_post_proc.c @@ -85,7 +85,7 @@ void ivas_post_proc( if ( sts[n]->core != TCX_20_CORE && sts[n]->core != TCX_10_CORE ) { /* TCX-LTP Postfilter: used in Mode 1 to update memories and to avoid discontinuities when the past frame was TCX */ - tcx_ltp_post( sts[n], hTcxLtpDec, ACELP_CORE, output_frame, 0, synth, NULL ); + tcx_ltp_post_flt( sts[n], hTcxLtpDec, ACELP_CORE, output_frame, 0, synth, NULL ); } else { @@ -103,7 +103,7 @@ void ivas_post_proc( mvr2r( sts[n]->hHQ_core->old_out + numZeros, sts[n]->hTcxDec->FBTCXdelayBuf_float, delay_comp ); } - tcx_ltp_post( sts[n], hTcxLtpDec, sts[n]->core, output_frame, NS2SA( output_Fs, ACELP_LOOK_NS ) + delay_comp, synth, sts[n]->hTcxDec->FBTCXdelayBuf_float ); + tcx_ltp_post_flt( sts[n], hTcxLtpDec, sts[n]->core, output_frame, NS2SA( output_Fs, ACELP_LOOK_NS ) + delay_comp, synth, sts[n]->hTcxDec->FBTCXdelayBuf_float ); } } } @@ -134,12 +134,12 @@ void ivas_post_proc( if ( sts[0]->core != TCX_20_CORE && sts[0]->core != TCX_10_CORE ) { /* update memories and to avoid discontinuities when the past frame was TCX */ - tcx_ltp_post( sts[0], hTcxLtpDec, ACELP_CORE, output_frame, 0, output[k], NULL ); + tcx_ltp_post_flt( sts[0], hTcxLtpDec, ACELP_CORE, output_frame, 0, output[k], NULL ); } else { /*Use channel 0 side info.*/ - tcx_ltp_post( sts[0], hTcxLtpDec, TCX_20_CORE, output_frame, NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ), output[k], hCPE->output_mem[k] ); + tcx_ltp_post_flt( sts[0], hTcxLtpDec, TCX_20_CORE, output_frame, NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ), output[k], hCPE->output_mem[k] ); } } } diff --git a/lib_dec/ivas_sce_dec.c b/lib_dec/ivas_sce_dec.c index 39a622fb77a541e0f54d49d920e42e8634f6edc6..fc27af7f6ff47fa2b06d982f5d519eab5611d344 100644 --- a/lib_dec/ivas_sce_dec.c +++ b/lib_dec/ivas_sce_dec.c @@ -37,6 +37,8 @@ #include "ivas_cnst.h" #include "rom_com.h" #include "prot.h" +#include "prot_fx1.h" +#include "prot_fx2.h" #include "ivas_prot.h" #include "ivas_rom_com.h" #include "wmc_auto.h" @@ -205,7 +207,7 @@ ivas_error ivas_sce_dec( } else { - st->flag_ACELP16k = set_ACELP_flag( IVAS_SCE, hSCE->element_brate, st->total_brate, 0, 0, -1, -1 ); + st->flag_ACELP16k = set_ACELP_flag_IVAS( IVAS_SCE, hSCE->element_brate, st->total_brate, 0, 0, -1, -1 ); } if ( is_DTXrate( ivas_total_brate ) ) @@ -325,8 +327,9 @@ ivas_error create_sce_dec( /*-----------------------------------------------------------------* * Core Coder, 1 instance: allocate and initialize *-----------------------------------------------------------------*/ - - if ( ( st = (DEC_CORE_HANDLE) malloc( sizeof( Decoder_State ) ) ) == NULL ) + + //if ( ( st = (DEC_CORE_HANDLE) calloc( sizeof( Decoder_State ) ) ) == NULL ) + if ( ( st = (Decoder_State *)calloc(1, sizeof(Decoder_State))) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for CoreCoder structure\n" ) ); } @@ -340,15 +343,18 @@ ivas_error create_sce_dec( { st->is_ism_format = 1; } - +#ifdef EVS_FLOAT if ( ( error = init_decoder( st, 0, st_ivas->mc_mode ) ) != IVAS_ERR_OK ) +#else + if ( ( error = init_decoder_fx(st, EVS_MONO) ) != IVAS_ERR_OK ) +#endif { return error; } if ( st_ivas->ivas_format == SBA_FORMAT && ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_STEREO || ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_MONO && st_ivas->nchan_transport == 1 ) ) ) { - if ( ( error = openCldfb( &st->cldfbSynHB, CLDFB_SYNTHESIS, st->output_Fs, CLDFB_PROTOTYPE_1_25MS ) ) != IVAS_ERR_OK ) + if ( ( error = openCldfb_ivas( &st->cldfbSynHB, CLDFB_SYNTHESIS, st->output_Fs, CLDFB_PROTOTYPE_1_25MS ) ) != IVAS_ERR_OK ) { return error; } @@ -366,7 +372,7 @@ ivas_error create_sce_dec( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DTX/TD CNG\n" ) ); } - td_cng_dec_init( st ); + td_cng_dec_init_flt( st ); } /*-----------------------------------------------------------------* diff --git a/lib_dec/ivas_sns_dec.c b/lib_dec/ivas_sns_dec.c index 775494013ffa64fd0e4a1b782e971f12624827a1..6837f2ae8fdacc637c07f080b01848aeb08b27ac 100644 --- a/lib_dec/ivas_sns_dec.c +++ b/lib_dec/ivas_sns_dec.c @@ -109,7 +109,7 @@ static void sns_2st_dec( float scale = 1.0f / 2.5f; /* quantize */ - AVQ_dec_lpc( indx, xq, 2 ); + AVQ_dec_lpc_ivas( indx, xq, 2 ); for ( i = 0; i < M; i++ ) { diff --git a/lib_dec/ivas_spar_decoder.c b/lib_dec/ivas_spar_decoder.c index ab913d08b565e1c614dd2ff92a44cfa185572984..b093b3301f78c2dd3984dc6ab913171a6169a129 100644 --- a/lib_dec/ivas_spar_decoder.c +++ b/lib_dec/ivas_spar_decoder.c @@ -641,9 +641,9 @@ void ivas_spar_get_cldfb_gains( ts_inout[sample] = x; } - cldfbAnalysis_ts( ts_inout, ts_re, ts_im, num_cldfb_bands, cldfbAnaDec0 ); - cldfb_reset_memory( cldfbSynDec0 ); - cldfbSynthesis( pp_ts_re, pp_ts_im, ts_inout, num_cldfb_bands, cldfbSynDec0 ); + cldfbAnalysis_ts_ivas( ts_inout, ts_re, ts_im, num_cldfb_bands, cldfbAnaDec0 ); + cldfb_reset_memory_ivas( cldfbSynDec0 ); + cldfbSynthesis_ivas( pp_ts_re, pp_ts_im, ts_inout, num_cldfb_bands, cldfbSynDec0 ); for ( sample = 0; sample < stride; sample++ ) { @@ -702,8 +702,8 @@ void ivas_spar_get_cldfb_gains( weights[cf_cldfb_start + slot_row] = max( min( tmp, 1.0f ), 0.0f ); } - cldfb_reset_memory( cldfbSynDec0 ); - cldfb_reset_memory( cldfbAnaDec0 ); + cldfb_reset_memory_ivas( cldfbSynDec0 ); + cldfb_reset_memory_ivas( cldfbAnaDec0 ); return; } @@ -1609,7 +1609,7 @@ void ivas_spar_dec_upmixer_sf( { for ( ts = 0; ts < hSpar->subframe_nbslots[hSpar->subframes_rendered]; ts++ ) { - cldfbAnalysis_ts( &p_tc[in_ch][ts * num_cldfb_bands], cldfb_in_ts_re[in_ch][ts], cldfb_in_ts_im[in_ch][ts], num_cldfb_bands, st_ivas->cldfbAnaDec[in_ch] ); + cldfbAnalysis_ts_ivas( &p_tc[in_ch][ts * num_cldfb_bands], cldfb_in_ts_re[in_ch][ts], cldfb_in_ts_im[in_ch][ts], num_cldfb_bands, st_ivas->cldfbAnaDec[in_ch] ); } } @@ -1619,7 +1619,7 @@ void ivas_spar_dec_upmixer_sf( { for ( ts = 0; ts < hSpar->subframe_nbslots[hSpar->subframes_rendered]; ts++ ) { - cldfbAnalysis_ts( &p_tc[in_ch][ts * num_cldfb_bands], cldfb_in_ts_re[in_ch][ts], cldfb_in_ts_im[in_ch][ts], num_cldfb_bands, st_ivas->cldfbAnaDec[in_ch] ); + cldfbAnalysis_ts_ivas( &p_tc[in_ch][ts * num_cldfb_bands], cldfb_in_ts_re[in_ch][ts], cldfb_in_ts_im[in_ch][ts], num_cldfb_bands, st_ivas->cldfbAnaDec[in_ch] ); } } } @@ -1753,7 +1753,7 @@ void ivas_spar_dec_upmixer_sf( { for ( ts = 0; ts < hSpar->subframe_nbslots[hSpar->subframes_rendered]; ts++ ) { - cldfbSynthesis( &cldfb_in_ts_re[idx_in][ts], &cldfb_in_ts_im[idx_in][ts], &output[ch][ts * num_cldfb_bands], num_cldfb_bands, st_ivas->cldfbSynDec[idx_in] ); + cldfbSynthesis_ivas( &cldfb_in_ts_re[idx_in][ts], &cldfb_in_ts_im[idx_in][ts], &output[ch][ts * num_cldfb_bands], num_cldfb_bands, st_ivas->cldfbSynDec[idx_in] ); } } idx_in++; @@ -1767,7 +1767,7 @@ void ivas_spar_dec_upmixer_sf( { for ( ts = 0; ts < hSpar->subframe_nbslots[hSpar->subframes_rendered]; ts++ ) { - cldfbSynthesis( &cldfb_in_ts_re[out_ch][ts], &cldfb_in_ts_im[out_ch][ts], &output[out_ch][ts * num_cldfb_bands], num_cldfb_bands, st_ivas->cldfbSynDec[out_ch] ); + cldfbSynthesis_ivas( &cldfb_in_ts_re[out_ch][ts], &cldfb_in_ts_im[out_ch][ts], &output[out_ch][ts * num_cldfb_bands], num_cldfb_bands, st_ivas->cldfbSynDec[out_ch] ); } } } diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index 3b04a0afcfc5d3e11b5922ac9bce0a4c03eaee7a..8d3a5cb9f959f6b7fdff6d0c9fe6d820e83448db 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -1008,6 +1008,7 @@ typedef struct Decoder_Struct int16_t bfi; /* FEC - bad frame indicator */ int16_t BER_detect; /* BER detect flag */ + int16_t num_bits; /* BER detect flag */ uint16_t *bit_stream; /* Pointer to bitstream buffer */ int16_t writeFECoffset; /* parameter for debugging JBM stuff */ diff --git a/lib_dec/ivas_stereo_cng_dec.c b/lib_dec/ivas_stereo_cng_dec.c index 00545ed10af33e4bd5144de344fd52f5ed5011f7..1d6177b946f39781c4a1220550a7bb918549b4d4 100644 --- a/lib_dec/ivas_stereo_cng_dec.c +++ b/lib_dec/ivas_stereo_cng_dec.c @@ -448,12 +448,12 @@ static void stereo_dft_generate_comfort_noise( for ( i = 0; i < ( hFdCngCom->stopFFTbin - hFdCngCom->startBand ) / 2; i++ ) { /* Real part in FFT bins */ - rand_gauss( ptr_r, &st->hTdCngDec->cng_seed ); + rand_gauss_flt( ptr_r, &st->hTdCngDec->cng_seed ); tmp = scale * *ptr_level; ( *ptr_r ) *= tmp; ptr_r += 2; /* Imaginary part in FFT bins */ - rand_gauss( ptr_i, &st->hTdCngDec->cng_seed ); + rand_gauss_flt( ptr_i, &st->hTdCngDec->cng_seed ); ( *ptr_i ) *= tmp; ptr_i += 2; ptr_level++; @@ -475,11 +475,11 @@ static void stereo_dft_generate_comfort_noise( for ( i = 0; i < ( min( output_frame, hFdCngCom->regularStopBand * 16 ) - hFdCngCom->stopFFTbin ) / 2; i++ ) { /* Real part in FFT bins */ - rand_gauss( ptr_r, &st->hTdCngDec->cng_seed ); + rand_gauss_flt( ptr_r, &st->hTdCngDec->cng_seed ); ( *ptr_r ) *= *ptr_shb; ptr_r += 2; /* Imaginary part in FFT bins */ - rand_gauss( ptr_i, &st->hTdCngDec->cng_seed ); + rand_gauss_flt( ptr_i, &st->hTdCngDec->cng_seed ); ( *ptr_i ) *= *ptr_shb; ptr_i += 2; ptr_shb--; @@ -499,9 +499,9 @@ static void stereo_dft_generate_comfort_noise( } } - /* Expand cngNoiseLevel from 0-159 to 0-318, compute noise level */ + /* Expand cngNoiseLevel_flt from 0-159 to 0-318, compute noise level */ lp_noise = 0.0f; - ptr_level = hFdCngCom->cngNoiseLevel + hFdCngCom->stopFFTbin - hFdCngCom->startBand - 1; + ptr_level = hFdCngCom->cngNoiseLevel_flt + hFdCngCom->stopFFTbin - hFdCngCom->startBand - 1; ptr_tmp = cngNoiseLevel_upd + ( hFdCngCom->stopFFTbin - hFdCngCom->startBand ) / 2 - 1; for ( i = 0; i < ( hFdCngCom->stopFFTbin - hFdCngCom->startBand ) / 2; i++ ) { @@ -522,11 +522,11 @@ static void stereo_dft_generate_comfort_noise( j = 0; for ( k = 0; k < ( hFdCngCom->nFFTpart - 2 ); k++ ) { - factor = ( hFdCngCom->sidNoiseEstLp[k] + DELTA ) / ( st->hFdCngDec->partNoiseShape_float[k] + DELTA ); + factor = ( hFdCngCom->sidNoiseEstLp_flt[k] + DELTA ) / ( st->hFdCngDec->partNoiseShape_float[k] + DELTA ); factor = min( hStereoDft->scale + ( 1 / MAX_K ) * ( factor - hStereoDft->scale ) * hStereoCng->xfade_frame_counter, factor ); for ( ; j <= hFdCngCom->part[k]; j++ ) { - hFdCngCom->cngNoiseLevel[j] = st->hFdCngDec->bandNoiseShape_float[j] * factor; + hFdCngCom->cngNoiseLevel_flt[j] = st->hFdCngDec->bandNoiseShape_float[j] * factor; } } } @@ -535,7 +535,7 @@ static void stereo_dft_generate_comfort_noise( numSlots = hFdCngCom->numSlots / 2; for ( k = 0; k < STEREO_DFT_NBDIV; k++ ) { - ptr_level = hFdCngCom->cngNoiseLevel; + ptr_level = hFdCngCom->cngNoiseLevel_flt; ptr_r = DFT[chan] + hFdCngCom->startBand + k * STEREO_DFT32MS_N_MAX; ptr_i = ptr_r + 1; for ( i = 0; i < ( hFdCngCom->stopFFTbin - hFdCngCom->startBand ) / 2; i++ ) @@ -544,16 +544,16 @@ static void stereo_dft_generate_comfort_noise( tmp = *ptr_level++; tmp += *ptr_level++; tmp = tmp * 0.5f; - rand_gauss( ptr_r, &st->hTdCngDec->cng_seed ); + rand_gauss_flt( ptr_r, &st->hTdCngDec->cng_seed ); tmp = sqrtf( tmp ) * scale; ( *ptr_r ) *= tmp; ptr_r += 2; /* Imaginary part in FFT bins */ - rand_gauss( ptr_i, &st->hTdCngDec->cng_seed ); + rand_gauss_flt( ptr_i, &st->hTdCngDec->cng_seed ); ( *ptr_i ) *= tmp; ptr_i += 2; } - ptr_level = hFdCngCom->cngNoiseLevel + hFdCngCom->stopFFTbin - hFdCngCom->startBand; + ptr_level = hFdCngCom->cngNoiseLevel_flt + hFdCngCom->stopFFTbin - hFdCngCom->startBand; ptr_r = DFT[chan] + hFdCngCom->stopFFTbin + k * STEREO_DFT32MS_N_MAX; ptr_i = ptr_r + 1; for ( j = hFdCngCom->numCoreBands; j < hFdCngCom->regularStopBand; j++ ) @@ -561,12 +561,12 @@ static void stereo_dft_generate_comfort_noise( for ( i = 0; i < numSlots; i++ ) { /* Real part in FFT bins */ - rand_gauss( ptr_r, &st->hTdCngDec->cng_seed ); + rand_gauss_flt( ptr_r, &st->hTdCngDec->cng_seed ); tmp = sqrtf( *ptr_level ) * scale; ( *ptr_r ) *= tmp; ptr_r += 2; /* Imaginary part in FFT bins */ - rand_gauss( ptr_i, &st->hTdCngDec->cng_seed ); + rand_gauss_flt( ptr_i, &st->hTdCngDec->cng_seed ); ( *ptr_i ) *= tmp; ptr_i += 2; } @@ -576,7 +576,7 @@ static void stereo_dft_generate_comfort_noise( /* Compute noise level */ lp_noise = 0.0f; - ptr_level = hFdCngCom->cngNoiseLevel; + ptr_level = hFdCngCom->cngNoiseLevel_flt; for ( i = 0; i < hFdCngCom->stopFFTbin - hFdCngCom->startBand; i++ ) { lp_noise += *ptr_level++; @@ -592,15 +592,15 @@ static void stereo_dft_generate_comfort_noise( st->hFdCngDec->lp_noise_float = 0.9f * st->hFdCngDec->lp_noise_float + 0.1f * 10.f * log10f( lp_noise + DELTA ); st->lp_noise_float = st->hFdCngDec->lp_noise_float; st->hFdCngDec->hFdCngCom->flag_noisy_speech = ( st->hFdCngDec->lp_speech_float - st->hFdCngDec->lp_noise_float ) < 28.f; - st->hFdCngDec->hFdCngCom->likelihood_noisy_speech = 0.99f * st->hFdCngDec->hFdCngCom->likelihood_noisy_speech + 0.01f * st->hFdCngDec->hFdCngCom->flag_noisy_speech; + st->hFdCngDec->hFdCngCom->likelihood_noisy_speech_flt = 0.99f * st->hFdCngDec->hFdCngCom->likelihood_noisy_speech_flt + 0.01f * st->hFdCngDec->hFdCngCom->flag_noisy_speech; } if ( chan == 0 && st->core_brate <= SID_2k40 ) { - /* update smoothed periodogram used by stereo CNA in SID and NO_DATA frames from cngNoiseLevel */ + /* update smoothed periodogram used by stereo CNA in SID and NO_DATA frames from cngNoiseLevel_flt */ for ( i = hFdCngCom->startBand; i < hFdCngCom->stopFFTbin; i++ ) { - ftmp = hFdCngCom->cngNoiseLevel[i - hFdCngCom->startBand]; + ftmp = hFdCngCom->cngNoiseLevel_flt[i - hFdCngCom->startBand]; if ( !st->hFdCngDec->first_cna_noise_updated ) { @@ -627,7 +627,7 @@ static void stereo_dft_generate_comfort_noise( } /* update msNoiseEst in SID and NO_DATA frames */ - bandcombinepow( &st->hFdCngDec->smoothed_psd[hFdCngCom->startBand], hFdCngCom->stopFFTbin - hFdCngCom->startBand, st->hFdCngDec->part_shaping, st->hFdCngDec->nFFTpart_shaping, st->hFdCngDec->psize_inv_shaping_float, st->hFdCngDec->msNoiseEst_float); + bandcombinepow_flt( &st->hFdCngDec->smoothed_psd[hFdCngCom->startBand], hFdCngCom->stopFFTbin - hFdCngCom->startBand, st->hFdCngDec->part_shaping, st->hFdCngDec->nFFTpart_shaping, st->hFdCngDec->psize_inv_shaping_float, st->hFdCngDec->msNoiseEst_float); st->hFdCngDec->first_cna_noise_updated = 1; mvr2r( st->hFdCngDec->msNoiseEst_float, st->hFdCngDec->msPeriodog_ST, st->hFdCngDec->nFFTpart_shaping ); diff --git a/lib_dec/ivas_stereo_dft_dec.c b/lib_dec/ivas_stereo_dft_dec.c index 03c0fe15a41576a9b691aebeee1f57ac45f64b79..7e64c459384a8773e3ea49f86502ea68af6042d6 100644 --- a/lib_dec/ivas_stereo_dft_dec.c +++ b/lib_dec/ivas_stereo_dft_dec.c @@ -1575,13 +1575,13 @@ void stereo_dft_dec( scale_fact = scale_fact0 * sqrtf( cna_level ); /* generate comfort noise from gaussian noise and add to the decoded DFT spectrum */ - N1 = scale_fact * rand_gauss( &ftmp, cna_seed ); - N2 = scale_fact * rand_gauss( &ftmp, cna_seed ); + N1 = scale_fact * rand_gauss_flt( &ftmp, cna_seed ); + N2 = scale_fact * rand_gauss_flt( &ftmp, cna_seed ); DFT_L[2 * i] += ( 1 + g ) * N1 + gamma * N2; DFT_R[2 * i] += ( 1 - g ) * N1 - gamma * N2; - N1 = scale_fact * rand_gauss( &ftmp, cna_seed ); - N2 = scale_fact * rand_gauss( &ftmp, cna_seed ); + N1 = scale_fact * rand_gauss_flt( &ftmp, cna_seed ); + N2 = scale_fact * rand_gauss_flt( &ftmp, cna_seed ); DFT_L[2 * i + 1] += ( 1 + g ) * N1 + gamma * N2; DFT_R[2 * i + 1] += ( 1 - g ) * N1 - gamma * N2; } @@ -1653,7 +1653,7 @@ void stereo_dft_dec_res( } /*Inverse MDCT*/ - TCX_MDCT_Inverse( res_buf, win, STEREO_DFT_OVL_8k, L_FRAME8k - STEREO_DFT_OVL_8k, STEREO_DFT_OVL_8k, IVAS_CPE_DFT ); + TCX_MDCT_Inverse_flt( res_buf, win, STEREO_DFT_OVL_8k, L_FRAME8k - STEREO_DFT_OVL_8k, STEREO_DFT_OVL_8k, IVAS_CPE_DFT ); if ( !prev_bfi ) { diff --git a/lib_dec/ivas_stereo_icbwe_dec.c b/lib_dec/ivas_stereo_icbwe_dec.c index 334fb5bd71b00e4d402371cb04eb9a28b32ad8e8..37f4afa15f74216ce5f0044e4429872a5cfcaa3d 100644 --- a/lib_dec/ivas_stereo_icbwe_dec.c +++ b/lib_dec/ivas_stereo_icbwe_dec.c @@ -736,7 +736,7 @@ void stereo_icBWE_decproc( } /* reset BWE structs as they are only needed in the transition frame in MDCT Stereo */ td_bwe_dec_init( hCPE->hCoreCoder[0]->hBWE_TD, -1, output_Fs ); - fd_bwe_dec_init( hCPE->hCoreCoder[0]->hBWE_FD ); + fd_bwe_dec_init_flt( hCPE->hCoreCoder[0]->hBWE_FD ); } if ( hCPE->element_mode == IVAS_CPE_DFT && ( max( hCPE->hStereoDft->td_gain[0], hCPE->hStereoDft->td_gain[1] ) > 0 ) ) diff --git a/lib_dec/ivas_stereo_mdct_core_dec.c b/lib_dec/ivas_stereo_mdct_core_dec.c index f2e527b3e458a96ac90c53034c0a00ffd21b7aa8..fa392bc494c58ee475850dc1bd2bbe1ce8e52ef8 100644 --- a/lib_dec/ivas_stereo_mdct_core_dec.c +++ b/lib_dec/ivas_stereo_mdct_core_dec.c @@ -319,11 +319,11 @@ void stereo_mdct_core_dec( if ( st->hTonalMDCTConc != NULL && ( ( k + 1 ) == nSubframes[ch] ) ) { - TonalMDCTConceal_SaveFreqSignal( st->hTonalMDCTConc, x[ch][k], L_frameTCX[ch], L_frame[ch], &sns_int_scf[0], get_igf_startline( st, L_frame[ch], L_frameTCX[ch] ) ); + TonalMDCTConceal_SaveFreqSignal_ivas( st->hTonalMDCTConc, x[ch][k], L_frameTCX[ch], L_frame[ch], &sns_int_scf[0], get_igf_startline_flt( st, L_frame[ch], L_frameTCX[ch] ) ); } } - TonalMDCTConceal_UpdateState( st->hTonalMDCTConc, L_frameTCX[ch], ( st->hTcxDec->tcxltp_last_gain_unmodified_float > 0 ) ? st->old_fpitch_float : 0, bfi, bfi && st->tonal_mdct_plc_active ); + TonalMDCTConceal_UpdateState_ivas( st->hTonalMDCTConc, L_frameTCX[ch], ( st->hTcxDec->tcxltp_last_gain_unmodified_float > 0 ) ? st->old_fpitch_float : 0, bfi, bfi && st->tonal_mdct_plc_active ); } mvs2s( ms_mask[0], hCPE->hStereoMdct->prev_ms_mask[0], MAX_SFB ); @@ -625,16 +625,16 @@ static void run_min_stats( } } - noisy_speech_detection( st->hFdCngDec, st->VAD && st->m_frame_type == ACTIVE_FRAME, power_spec ); + noisy_speech_detection_flt( st->hFdCngDec, st->VAD && st->m_frame_type == ACTIVE_FRAME, power_spec ); - st->hFdCngDec->hFdCngCom->likelihood_noisy_speech = 0.99f * st->hFdCngDec->hFdCngCom->likelihood_noisy_speech + 0.01f * (float) st->hFdCngDec->hFdCngCom->flag_noisy_speech; + st->hFdCngDec->hFdCngCom->likelihood_noisy_speech_flt = 0.99f * st->hFdCngDec->hFdCngCom->likelihood_noisy_speech_flt + 0.01f * (float) st->hFdCngDec->hFdCngCom->flag_noisy_speech; st->lp_noise_float = st->hFdCngDec->lp_noise_float; } if ( will_estimate_noise_on_channel[0] || will_estimate_noise_on_channel[1] || st->bfi ) { - ApplyFdCng( NULL, st->bfi ? NULL : power_spec, NULL, NULL, st, st->bfi, 0 ); + ApplyFdCng_flt( NULL, st->bfi ? NULL : power_spec, NULL, NULL, st, st->bfi, 0 ); } /* restore VAD (see above) */ diff --git a/lib_dec/ivas_stereo_mdct_stereo_dec.c b/lib_dec/ivas_stereo_mdct_stereo_dec.c index 7efe849d28353123cc511faaa99d64548681697e..c8dfd6a6b2d6eec06e0c35f7af47280795735d0f 100644 --- a/lib_dec/ivas_stereo_mdct_stereo_dec.c +++ b/lib_dec/ivas_stereo_mdct_stereo_dec.c @@ -439,13 +439,13 @@ ivas_error initMdctStereoDtxData( if ( st->hFdCngDec == NULL ) { /* Create FD_CNG instance */ - if ( ( error = createFdCngDec( &st->hFdCngDec ) ) != IVAS_ERR_OK ) + if ( ( error = createFdCngDec_flt( &st->hFdCngDec ) ) != IVAS_ERR_OK ) { return error; } /* Init FD-CNG */ - initFdCngDec( st ); + initFdCngDec_flt( st ); } if ( st->first_CNG == 0 ) @@ -459,7 +459,7 @@ ivas_error initMdctStereoDtxData( if ( st->cldfbAna == NULL ) { /* open analysis for max. sampling rate 48kHz */ - if ( ( error = openCldfb( &st->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS ) ) != IVAS_ERR_OK ) + if ( ( error = openCldfb_ivas( &st->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS ) ) != IVAS_ERR_OK ) { return error; } @@ -468,7 +468,7 @@ ivas_error initMdctStereoDtxData( if ( st->cldfbBPF == NULL ) { /* open analysis BPF for max. internal sampling rate 16kHz */ - if ( ( error = openCldfb( &st->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS ) ) != IVAS_ERR_OK ) + if ( ( error = openCldfb_ivas( &st->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS ) ) != IVAS_ERR_OK ) { return error; } @@ -501,20 +501,20 @@ void synchonize_channels_mdct_sid( sts[1]->L_frame = sts[0]->L_frame; sts[1]->cng_type = sts[0]->cng_type; sts[1]->bwidth = sts[0]->bwidth; - sts[0]->hFdCngDec->hFdCngCom->coherence = sts[1]->hFdCngDec->hFdCngCom->coherence; /* coherence is stored in sts[1] - see ivas_decision_matrix_dec() */ + sts[0]->hFdCngDec->hFdCngCom->coherence_flt = sts[1]->hFdCngDec->hFdCngCom->coherence_flt; /* coherence is stored in sts[1] - see ivas_decision_matrix_dec() */ sts[0]->hFdCngDec->hFdCngCom->no_side_flag = sts[1]->hFdCngDec->hFdCngCom->no_side_flag; /* configure when there is a switching from DFT CNG to MDCT CNG */ if ( sts[0]->first_CNG == 1 && sts[1]->first_CNG == 0 ) { - configureFdCngDec( st->hFdCngDec, st->bwidth, st->element_brate, st->L_frame, st->last_L_frame, st->element_mode ); + configureFdCngDec_flt( st->hFdCngDec, st->bwidth, st->element_brate, st->L_frame, st->last_L_frame, st->element_mode ); } } if ( sts[0]->first_CNG == 0 ) { /* configure CNG after reading first side info from SID to get correct values for L_frame and bwidth if first SID is also first valid frame */ - configureFdCngDec( st->hFdCngDec, st->bwidth, st->element_brate, st->L_frame, st->last_L_frame, st->element_mode ); + configureFdCngDec_flt( st->hFdCngDec, st->bwidth, st->element_brate, st->L_frame, st->last_L_frame, st->element_mode ); } } @@ -555,7 +555,7 @@ void updateBuffersForDmxMdctStereo( /* in the first SID frame after an active frame, create mid noise shape here, in SID frames that follow inactive frames, it is done directly in the SID decoding since the mid shape is being used in CNG then */ for ( int16_t p = 0; p < sts[0]->hFdCngDec->hFdCngCom->npart; p++ ) { - sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p] = 0.5f * ( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p] + sts[1]->hFdCngDec->hFdCngCom->sidNoiseEst[p] ); + sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst_flt[p] = 0.5f * ( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst_flt[p] + sts[1]->hFdCngDec->hFdCngCom->sidNoiseEst_flt[p] ); } } diff --git a/lib_dec/ivas_stereo_switching_dec.c b/lib_dec/ivas_stereo_switching_dec.c index 7716b670a08719d734cf47e80c31ca0c831f2851..036e8d300c0c8289e34d508bcff45ac785340a66 100644 --- a/lib_dec/ivas_stereo_switching_dec.c +++ b/lib_dec/ivas_stereo_switching_dec.c @@ -99,7 +99,7 @@ static ivas_error allocate_CoreCoder_TCX( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for HQ core\n" ) ); } - HQ_core_dec_init( st->hHQ_core ); + HQ_core_dec_init_flt( st->hHQ_core ); } if ( st->hIGFDec == NULL ) @@ -110,7 +110,7 @@ static ivas_error allocate_CoreCoder_TCX( } st->igf = 0; - init_igf_dec( st->hIGFDec ); + init_igf_dec_flt( st->hIGFDec ); } if ( st->hTonalMDCTConc == NULL ) @@ -149,7 +149,7 @@ static ivas_error allocate_CoreCoder( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for GSC\n" ) ); } - GSC_dec_init( st->hGSCDec ); + GSC_dec_init_ivas( st->hGSCDec ); } if ( st->hPFstat == NULL ) @@ -159,7 +159,7 @@ static ivas_error allocate_CoreCoder( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for NB/formant postflter\n" ) ); } - Init_post_filter( st->hPFstat ); + Init_post_filter_ivas( st->hPFstat ); st->psf_lp_noise = 0.0f; } @@ -170,7 +170,7 @@ static ivas_error allocate_CoreCoder( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LD music postflter\n" ) ); } - music_postfilt_init( st->hMusicPF ); + music_postfilt_init_flt( st->hMusicPF ); } if ( st->hBPF == NULL ) @@ -196,7 +196,7 @@ static ivas_error allocate_CoreCoder( if ( st->cldfbAna == NULL ) { /* open analysis for max. sampling rate 48kHz */ - if ( ( error = openCldfb( &st->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS ) ) != IVAS_ERR_OK ) + if ( ( error = openCldfb_ivas( &st->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS ) ) != IVAS_ERR_OK ) { return error; } @@ -205,7 +205,7 @@ static ivas_error allocate_CoreCoder( if ( st->cldfbBPF == NULL ) { /* open analysis BPF for max. internal sampling rate 16kHz */ - if ( ( error = openCldfb( &st->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS ) ) != IVAS_ERR_OK ) + if ( ( error = openCldfb_ivas( &st->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS ) ) != IVAS_ERR_OK ) { return error; } @@ -296,8 +296,8 @@ static void deallocate_CoreCoder( /* CLDFB BPF & resampling tools */ if ( st->element_mode != IVAS_CPE_MDCT ) { - deleteCldfb( &st->cldfbAna ); /* delete analysis at max. sampling rate 48kHz */ - deleteCldfb( &st->cldfbBPF ); /* delete analysis BPF at max. internal sampling rate 16kHz */ + deleteCldfb_ivas( &st->cldfbAna ); /* delete analysis at max. sampling rate 48kHz */ + deleteCldfb_ivas( &st->cldfbBPF ); /* delete analysis BPF at max. internal sampling rate 16kHz */ } if ( st->element_mode != IVAS_CPE_MDCT ) @@ -432,7 +432,7 @@ ivas_error stereo_memory_dec( if ( hCPE->last_element_mode == IVAS_CPE_MDCT ) { cpy_tcx_ltp_data( hCPE->hCoreCoder[1]->hTcxLtpDec, hCPE->hStereoDft->hTcxLtpDec, output_Fs ); - deleteFdCngDec( &hCPE->hCoreCoder[1]->hFdCngDec ); + deleteFdCngDec_flt( &hCPE->hCoreCoder[1]->hFdCngDec ); } /* memory update - needed in TD stereo, TCX/HQ frame -> DFT stereo, ACELP frame switching */ @@ -458,7 +458,7 @@ ivas_error stereo_memory_dec( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HQ core\n" ) ); } - HQ_core_dec_init( st->hHQ_core ); + HQ_core_dec_init_flt( st->hHQ_core ); } /* allocate TD CNG handle */ @@ -469,7 +469,7 @@ ivas_error stereo_memory_dec( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DTX/TD CNG\n" ) ); } - td_cng_dec_init( st ); + td_cng_dec_init_flt( st ); } } @@ -497,7 +497,7 @@ ivas_error stereo_memory_dec( if ( hCPE->last_element_mode == IVAS_CPE_MDCT ) { - deleteFdCngDec( &hCPE->hCoreCoder[1]->hFdCngDec ); + deleteFdCngDec_flt( &hCPE->hCoreCoder[1]->hFdCngDec ); } /* allocate TD stereo data structure */ @@ -594,19 +594,19 @@ ivas_error stereo_memory_dec( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for FD BWE\n" ) ); } - fd_bwe_dec_init( st->hBWE_FD ); + fd_bwe_dec_init_flt( st->hBWE_FD ); } /* Allocated FD_CNG instance for primary channel*/ if ( st->hFdCngDec == NULL ) { /* Create FD_CNG instance */ - if ( ( error = createFdCngDec( &st->hFdCngDec ) ) != IVAS_ERR_OK ) + if ( ( error = createFdCngDec_flt( &st->hFdCngDec ) ) != IVAS_ERR_OK ) { return error; } - initFdCngDec( st ); - configureFdCngDec( st->hFdCngDec, st->bwidth, st->total_brate, st->L_frame, st->last_L_frame, st->element_mode ); + initFdCngDec_flt( st ); + configureFdCngDec_flt( st->hFdCngDec, st->bwidth, st->total_brate, st->L_frame, st->last_L_frame, st->element_mode ); } /* allocate stereo CNG structure */ @@ -687,7 +687,7 @@ ivas_error stereo_memory_dec( if ( st->cldfbAna == NULL ) { - if ( ( error = openCldfb( &st->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS ) ) != IVAS_ERR_OK ) + if ( ( error = openCldfb_ivas( &st->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS ) ) != IVAS_ERR_OK ) { return error; } @@ -696,20 +696,20 @@ ivas_error stereo_memory_dec( if ( st->cldfbBPF == NULL ) { /* open analysis BPF for max. internal sampling rate 16kHz */ - if ( ( error = openCldfb( &st->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS ) ) != IVAS_ERR_OK ) + if ( ( error = openCldfb_ivas( &st->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS ) ) != IVAS_ERR_OK ) { return error; } } /* allocate Fd-Cng structure for second channel */ - if ( ( error = createFdCngDec( &st->hFdCngDec ) ) != IVAS_ERR_OK ) + if ( ( error = createFdCngDec_flt( &st->hFdCngDec ) ) != IVAS_ERR_OK ) { return error; } /* Init FD-CNG */ - initFdCngDec( st ); + initFdCngDec_flt( st ); if ( hCPE->last_element_mode == IVAS_CPE_DFT ) { @@ -796,7 +796,7 @@ ivas_error stereo_memory_dec( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for FD BWE\n" ) ); } - fd_bwe_dec_init( st->hBWE_FD ); + fd_bwe_dec_init_flt( st->hBWE_FD ); } } else /* tdm_LRTD_flag == 0 */ @@ -970,7 +970,7 @@ ivas_error stereo_memory_dec( /* deallocate the FdCNG handle */ for ( i = 0; i < CPE_CHANNELS; ++i ) { - deleteFdCngDec( &hCPE->hCoreCoder[i]->hFdCngDec ); + deleteFdCngDec_flt( &hCPE->hCoreCoder[i]->hFdCngDec ); } } else @@ -980,7 +980,7 @@ ivas_error stereo_memory_dec( { if ( hCPE->hCoreCoder[i]->cldfbSyn == NULL ) /* could be NULL when we had the MCT LFE channel */ { - if ( ( error = openCldfb( &hCPE->hCoreCoder[i]->cldfbSyn, CLDFB_SYNTHESIS, hCPE->hCoreCoder[i]->output_Fs, CLDFB_PROTOTYPE_1_25MS ) ) != IVAS_ERR_OK ) + if ( ( error = openCldfb_ivas( &hCPE->hCoreCoder[i]->cldfbSyn, CLDFB_SYNTHESIS, hCPE->hCoreCoder[i]->output_Fs, CLDFB_PROTOTYPE_1_25MS ) ) != IVAS_ERR_OK ) { return error; } @@ -988,11 +988,11 @@ ivas_error stereo_memory_dec( if ( hCPE->hCoreCoder[i]->hFdCngDec == NULL ) { - if ( ( error = createFdCngDec( &hCPE->hCoreCoder[i]->hFdCngDec ) ) != IVAS_ERR_OK ) + if ( ( error = createFdCngDec_flt( &hCPE->hCoreCoder[i]->hFdCngDec ) ) != IVAS_ERR_OK ) { return error; } - initFdCngDec( hCPE->hCoreCoder[i] ); + initFdCngDec_flt( hCPE->hCoreCoder[i] ); } } } @@ -1499,9 +1499,9 @@ void stereo_switching_dec( if ( hCPE->last_element_brate <= IVAS_SID_5k2 && hCPE->nchan_out == 2 ) { /* reset CLDFB memories */ - cldfb_reset_memory( sts[0]->cldfbAna ); - cldfb_reset_memory( sts[0]->cldfbBPF ); - cldfb_reset_memory( sts[0]->cldfbSyn ); + cldfb_reset_memory_ivas( sts[0]->cldfbAna ); + cldfb_reset_memory_ivas( sts[0]->cldfbBPF ); + cldfb_reset_memory_ivas( sts[0]->cldfbSyn ); sts[0]->mem_deemph = 0; @@ -1528,9 +1528,9 @@ void stereo_switching_dec( sts[1]->old_fpitchFB_float = 2 * (float) L_SUBFR; /* reset CLDFB memories */ - cldfb_reset_memory( sts[1]->cldfbAna ); - cldfb_reset_memory( sts[1]->cldfbBPF ); - cldfb_reset_memory( sts[1]->cldfbSyn ); + cldfb_reset_memory_ivas( sts[1]->cldfbAna ); + cldfb_reset_memory_ivas( sts[1]->cldfbBPF ); + cldfb_reset_memory_ivas( sts[1]->cldfbSyn ); sts[1]->mem_deemph = 0; diff --git a/lib_dec/ivas_tcx_core_dec.c b/lib_dec/ivas_tcx_core_dec.c index ad11712213ae3e2463b56090b71594a21543b059..c4205c353bdacd8007da9aedbffc90bad977cfc7 100644 --- a/lib_dec/ivas_tcx_core_dec.c +++ b/lib_dec/ivas_tcx_core_dec.c @@ -70,7 +70,7 @@ void stereo_tcx_init_dec( st->core_brate = st->total_brate; /*sampling rate*/ - st->sr_core = getCoreSamplerateMode2( st->element_mode, st->bits_frame_nominal * FRAMES_PER_SEC, st->bwidth, st->flag_ACELP16k, st->rf_flag, st->is_ism_format ); + st->sr_core = getCoreSamplerateMode2_flt( st->element_mode, st->bits_frame_nominal * FRAMES_PER_SEC, st->bwidth, st->flag_ACELP16k, st->rf_flag, st->is_ism_format ); st->fscale = sr2fscale( st->sr_core ); /*frame size*/ @@ -103,7 +103,7 @@ void stereo_tcx_init_dec( if ( st->element_mode == IVAS_SCE ) { - st->tcxonly = getTcxonly( st->element_mode, st->bits_frame_nominal * FRAMES_PER_SEC, MCT_flag, st->is_ism_format ); + st->tcxonly = getTcxonly_ivas( st->element_mode, st->bits_frame_nominal * FRAMES_PER_SEC, MCT_flag, st->is_ism_format ); /* LPC quantization */ if ( st->sr_core <= INT_FS_16k && st->tcxonly == 0 ) @@ -266,7 +266,7 @@ void stereo_tcx_core_dec( /* PLC: [Common: mode decision] * PLC: Decide which Concealment to use. Update pitch lags if needed */ - st->core = GetPLCModeDecision( st ); + st->core = GetPLCModeDecision_flt( st ); } /*--------------------------------------------------------------------------------* @@ -293,7 +293,7 @@ void stereo_tcx_core_dec( mvr2r( st->lsf_old, &lsf[0], M ); mvr2r( st->lsp_old, &lsp[0], M ); - D_lsf_tcxlpc( param_lpc, &lsf[M], lspind, st->narrowBand, tcx_lpc_cdk, st->mem_MA ); + D_lsf_tcxlpc_ivas( param_lpc, &lsf[M], lspind, st->narrowBand, tcx_lpc_cdk, st->mem_MA ); lsf2lsp( &lsf[M], &lsp[M], M, st->sr_core ); @@ -312,7 +312,7 @@ void stereo_tcx_core_dec( hTcxDec->envWeighted = 0; } - lpc_unquantize( st, lsf, lsp, param_lpc, lspmid, lsfmid, AUDIO, &LSF_Q_prediction ); + lpc_unquantize_flt( st, lsf, lsp, param_lpc, lspmid, lsfmid, AUDIO, &LSF_Q_prediction ); for ( k = 0; k < st->numlpc; ++k ) { @@ -352,9 +352,9 @@ void stereo_tcx_core_dec( mvr2r( st->lsp_old, st->old_lsp_q_cng_float, M ); } - lsfBase = PlcGetlsfBase( st->lpcQuantization, st->narrowBand, st->sr_core ); + lsfBase = PlcGetlsfBase_flt( st->lpcQuantization, st->narrowBand, st->sr_core ); - dlpc_bfi( st->L_frame, lsfnew_uw, st->lsfold_uw_float, st->last_good, st->nbLostCmpt, st->mem_MA, st->mem_AR, &( st->stab_fac ), st->lsf_adaptive_mean, st->numlpc, st->lsf_cng_float, st->plcBackgroundNoiseUpdated, st->lsf_q_cng_float, st->old_lsf_q_cng_float, lsfBase ); + dlpc_bfi_flt( st->L_frame, lsfnew_uw, st->lsfold_uw_float, st->last_good, st->nbLostCmpt, st->mem_MA, st->mem_AR, &( st->stab_fac ), st->lsf_adaptive_mean, st->numlpc, st->lsf_cng_float, st->plcBackgroundNoiseUpdated, st->lsf_q_cng_float, st->old_lsf_q_cng_float, lsfBase ); hTcxDec->envWeighted = 0; @@ -408,7 +408,7 @@ void stereo_tcx_core_dec( } /* PLC: [TCX: TD PLC] */ - con_tcx( st, &synthFB[0], -1.f, NULL, 0, NULL ); + con_tcx_flt( st, &synthFB[0], -1.f, NULL, 0, NULL ); lerp_flt( synthFB, synth, st->L_frame, hTcxDec->L_frameTCX ); st->con_tcx = 1; set_f( &st->mem_pitch_gain_float[2], st->lp_gainp, st->nb_subfr ); @@ -423,7 +423,7 @@ void stereo_tcx_core_dec( /* Signal that this frame is not TCX */ if ( st->hTonalMDCTConc != NULL ) { - TonalMDCTConceal_UpdateState( st->hTonalMDCTConc, 0, 0, 0, 0 ); + TonalMDCTConceal_UpdateState_ivas( st->hTonalMDCTConc, 0, 0, 0, 0 ); } } @@ -453,7 +453,7 @@ void stereo_tcx_core_dec( if ( !bfi && st->prev_bfi && !( st->safety_net ) && st->rate_switching_reset ) { /* diffuse LPC power on rate switching*/ - RecLpcSpecPowDiffuseLc( &lsp[M], &lsp[0], &lsf[M], st, 0 ); + RecLpcSpecPowDiffuseLc_flt( &lsp[M], &lsp[0], &lsf[M], st, 0 ); int_lsp( st->L_frame, &lsp[0], &lsp[M], Aq, M, interpol_frac_12k8, 0 ); mvr2r( &lsf[M], lsfnew_uw, M ); } @@ -475,7 +475,7 @@ void stereo_tcx_core_dec( } /* TCX decoder */ - decoder_tcx( st, prm, Aq, Aind, &synth[0], &synthFB[0], bfi, 0, sba_dirac_stereo_flag ); + decoder_tcx_flt( st, prm, Aq, Aind, &synth[0], &synthFB[0], bfi, 0, sba_dirac_stereo_flag ); } /*--------------------------------------------------------------------------------* @@ -499,11 +499,11 @@ void stereo_tcx_core_dec( lsp2a_stab( &lsp[( k + 1 ) * M], Aq, M ); { - IGFDecRestoreTCX10SubFrameData( st->hIGFDec, k ); + IGFDecRestoreTCX10SubFrameData_flt( st->hIGFDec, k ); } /* TCX decoder */ - decoder_tcx( st, prm, Aq, Aind, &synth[k * st->L_frame / 2], &synthFB[k * hTcxDec->L_frameTCX / 2], bfi, k, sba_dirac_stereo_flag ); + decoder_tcx_flt( st, prm, Aq, Aind, &synth[k * st->L_frame / 2], &synthFB[k * hTcxDec->L_frameTCX / 2], bfi, k, sba_dirac_stereo_flag ); } } @@ -533,10 +533,10 @@ void stereo_tcx_core_dec( if ( !bfi && st->hTonalMDCTConc != NULL ) { - TonalMDCTConceal_SaveTimeSignal( st->hTonalMDCTConc, synthFB, hTcxDec->L_frameTCX ); + TonalMDCTConceal_SaveTimeSignal_ivas( st->hTonalMDCTConc, synthFB, hTcxDec->L_frameTCX ); } - decoder_tcx_post( st, synth, synthFB, Aq, bfi, 0 ); + decoder_tcx_post_flt( st, synth, synthFB, Aq, bfi, 0 ); if ( st->core == TCX_20_CORE ) { @@ -645,7 +645,7 @@ void stereo_tcx_core_dec( st->last_is_cng = 0; /* Postfiltering */ - post_decoder( st, synth_buf, pit_gain, pitch, signal_out, st->p_bpf_noise_buf_float); + post_decoder_flt( st, synth_buf, pit_gain, pitch, signal_out, st->p_bpf_noise_buf_float); if ( signal_outFB ) { @@ -685,9 +685,9 @@ void stereo_tcx_core_dec( if ( st->hFdCngDec != NULL && ( st->sr_core == INT_FS_12k8 || st->sr_core == INT_FS_16k ) && st->total_brate <= MAX_ACELP_BRATE ) { - noisy_speech_detection( st->hFdCngDec, st->VAD && st->m_frame_type == ACTIVE_FRAME, signal_out ); + noisy_speech_detection_flt( st->hFdCngDec, st->VAD && st->m_frame_type == ACTIVE_FRAME, signal_out ); - st->hFdCngDec->hFdCngCom->likelihood_noisy_speech = 0.99f * st->hFdCngDec->hFdCngCom->likelihood_noisy_speech + 0.01f * (float) st->hFdCngDec->hFdCngCom->flag_noisy_speech; + st->hFdCngDec->hFdCngCom->likelihood_noisy_speech_flt = 0.99f * st->hFdCngDec->hFdCngCom->likelihood_noisy_speech_flt + 0.01f * (float) st->hFdCngDec->hFdCngCom->flag_noisy_speech; st->lp_noise_float = st->hFdCngDec->lp_noise_float; @@ -697,11 +697,11 @@ void stereo_tcx_core_dec( { float buffer[L_FRAME16k]; lerp_flt( signal_outFB, buffer, st->L_frame, hTcxDec->L_frameTCX ); - ApplyFdCng( buffer, NULL, NULL, NULL, st, st->bfi, 0 ); + ApplyFdCng_flt( buffer, NULL, NULL, NULL, st, st->bfi, 0 ); } else { - ApplyFdCng( signal_out, NULL, NULL, NULL, st, st->bfi, 0 ); + ApplyFdCng_flt( signal_out, NULL, NULL, NULL, st, st->bfi, 0 ); } } @@ -715,19 +715,19 @@ void stereo_tcx_core_dec( /* Clear memory for secondary channel CNA */ set_f( hStereoCng->olapBufferSynth22, 0.0f, st->hFdCngDec->hFdCngCom->frameSize / 2 ); } - expand_range( st->hFdCngDec->msPsd_float, psd_part, st->hFdCngDec->nFFTpart_shaping ); - scalebands( psd_part, st->hFdCngDec->part_shaping, st->hFdCngDec->nFFTpart_shaping, st->hFdCngDec->midband_shaping, st->hFdCngDec->nFFTpart_shaping, st->hFdCngDec->hFdCngCom->stopFFTbin - st->hFdCngDec->hFdCngCom->startBand, psd, 1 ); + expand_range_flt( st->hFdCngDec->msPsd_float, psd_part, st->hFdCngDec->nFFTpart_shaping ); + scalebands_flt( psd_part, st->hFdCngDec->part_shaping, st->hFdCngDec->nFFTpart_shaping, st->hFdCngDec->midband_shaping, st->hFdCngDec->nFFTpart_shaping, st->hFdCngDec->hFdCngCom->stopFFTbin - st->hFdCngDec->hFdCngCom->startBand, psd, 1 ); generate_stereo_masking_noise( signal_out, st, hStereoTD, flag_sec_CNA, 0, hStereoCng, nchan_out ); } else if ( st->element_mode != IVAS_CPE_DFT ) { - generate_masking_noise( signal_out, st->hFdCngDec->hFdCngCom, st->hFdCngDec->hFdCngCom->frameSize, 0, 0, 0, st->element_mode, hStereoCng, nchan_out ); + generate_masking_noise_flt( signal_out, st->hFdCngDec->hFdCngCom, st->hFdCngDec->hFdCngCom->frameSize, 0, 0, 0, st->element_mode, hStereoCng, nchan_out ); } } if ( st->element_mode == IVAS_CPE_TD && st->idchan == 0 ) { - ApplyFdCng( signal_out, NULL, NULL, NULL, st, st->bfi, 0 ); + ApplyFdCng_flt( signal_out, NULL, NULL, NULL, st, st->bfi, 0 ); } } @@ -779,7 +779,7 @@ static void dec_prm_tcx( *--------------------------------------------------------------------------------*/ /* Modes (ACE_GC, ACE_UC, TCX20, TCX10...) */ - getTCXMode( st, st, 0 /* <- MCT_flag */ ); + getTCXMode_ivas( st, st, 0 /* <- MCT_flag */ ); /* last_core for error concealment */ if ( !st->use_partial_copy && st->element_mode != IVAS_CPE_MDCT ) @@ -812,7 +812,7 @@ static void dec_prm_tcx( { if ( st->element_mode != IVAS_CPE_MDCT ) { - getTCXWindowing( st->core, st->last_core, st->element_mode, st->hTcxCfg, st ); + getTCXWindowing_ivas( st->core, st->last_core, st->element_mode, st->hTcxCfg, st ); } st->flagGuidedAcelp = 0; @@ -827,7 +827,7 @@ static void dec_prm_tcx( * LPC parameters *--------------------------------------------------------------------------------*/ - getLPCparam( st, param_lpc, st, -1, 0 ); + getLPCparam_ivas( st, param_lpc, st, -1, 0 ); bits_common = st->next_bit_pos - start_bit_pos; @@ -838,7 +838,7 @@ static void dec_prm_tcx( if ( st->use_partial_copy == 0 ) { - getTCXparam( st, st, hm_cfg, param, bits_common, start_bit_pos, NULL, NULL, NULL, -1 ); + getTCXparam_ivas( st, st, hm_cfg, param, bits_common, start_bit_pos, NULL, NULL, NULL, -1 ); } if ( !st->use_partial_copy ) @@ -891,7 +891,7 @@ static void stereo_tcx_dec_mode_switch_reconf( } /* Reconfigure Core */ - mode_switch_decoder_LPD( st, st->bwidth, st->bits_frame_nominal * FRAMES_PER_SEC, st->last_bits_frame_nominal * FRAMES_PER_SEC, frame_size_index, MCT_flag, last_element_mode ); + mode_switch_decoder_LPD_flt( st, st->bwidth, st->bits_frame_nominal * FRAMES_PER_SEC, st->last_bits_frame_nominal * FRAMES_PER_SEC, frame_size_index, MCT_flag, last_element_mode ); return; } diff --git a/lib_dec/ivas_td_low_rate_dec.c b/lib_dec/ivas_td_low_rate_dec.c index 7b5115c36bf3f57c84142e63d7bece062bd41df5..a481cdca4b8b3d995120750f4d978459d63c39fc 100644 --- a/lib_dec/ivas_td_low_rate_dec.c +++ b/lib_dec/ivas_td_low_rate_dec.c @@ -226,7 +226,7 @@ void decod_gen_2sbfr( * Decode pitch lag *----------------------------------------------------------------------*/ - *pt_pitch = pit_decode( st, st->core_brate, 0, L_frame, i_subfr, GENERIC, &pitch_limit_flag, &T0, &T0_frac, &T0_min, &T0_max, 2 * L_SUBFR, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf ); + *pt_pitch = pit_decode_flt( st, st->core_brate, 0, L_frame, i_subfr, GENERIC, &pitch_limit_flag, &T0, &T0_frac, &T0_min, &T0_max, 2 * L_SUBFR, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf ); tbe_celp_exc_flt( st->element_mode, st->idchan, bwe_exc, L_frame, 2 * L_SUBFR, i_subfr, T0, T0_frac, &error, st->tdm_LRTD_flag ); @@ -234,7 +234,7 @@ void decod_gen_2sbfr( * Find the adaptive codebook vector *--------------------------------------------------------------*/ - pred_lt4( &exc[i_subfr], &exc[i_subfr], T0, T0_frac, 2 * L_SUBFR + 1, inter4_2, L_INTERPOL2, PIT_UP_SAMP ); + pred_lt4_flt( &exc[i_subfr], &exc[i_subfr], T0, T0_frac, 2 * L_SUBFR + 1, inter4_2, L_INTERPOL2, PIT_UP_SAMP ); /*--------------------------------------------------------------* * LP filtering of the adaptive excitation diff --git a/lib_dec/lead_deindexing_fx.c b/lib_dec/lead_deindexing_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..195442ac9913aadcfae2e9c3017fd321587c77e0 --- /dev/null +++ b/lib_dec/lead_deindexing_fx.c @@ -0,0 +1,298 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include +#include "options.h" /* Compilation switches */ +#include "cnst.h" +#include "rom_com.h" +#include "rom_dec.h" +#include "prot_fx1.h" +#include "prot_fx2.h" + +/*-------------------------------------------------------------------* + * Local function prototype + *-------------------------------------------------------------------*/ +static void fcb_decode_pos_fx(const Word16 index, Word16 pos_vector[], const Word16 pulse_num, const Word16 pos_num); + +/*-------------------------------------------------------------------* + * re8_decode_base_index_fx + * + * Decode RE8 base index + *-------------------------------------------------------------------*/ +void re8_decode_base_index_fx( + const Word16 n, /* i : codebook number (*n is an integer defined in {0,2,3,4,..,n_max}) */ + UWord16 I, /* i : index of c (pointer to unsigned 16-bit word) */ + Word16 *x /* o : point in RE8 (8-dimensional integer vector) */ +) +{ + Word16 i,j,k1,l,m,m1,m2; + Word16 setor_8p_temp[8],setor_8p_temp_1[8],setor_8p_temp_2[8]; + Word16 sign_8p; + Word16 code_level; + const Word16 *a1,*a2; + + Word16 ka; + UWord16 offset; + Word16 code_index; + + Word16 element_a10, element_a11, element_a12; + move16(); + move16(); + element_a11 = 0; + element_a12 = 0; + set16_fx(setor_8p_temp_2, 0, 8); + + IF (LT_16( n, 2 )) + { + FOR (i=0; i<8; i++) + { + x[i]=0; + move16(); + } + } + ELSE + { + if ( GT_32( I, 65519 )) + { + I = 0; + move16(); + } + + /*-------------------------------------------------------------------* + * search for the identifier ka of the absolute leader (table-lookup) + * Q2 is a subset of Q3 - the two cases are considered in the same branch + *-------------------------------------------------------------------*/ + IF (LE_16(n,3)) + { + FOR (i = 1; i < NB_LDQ3; i++) + { + IF (LT_32(I, II3[i])) + { + BREAK; + } + } + ka = AA3[sub(i,1)]; + move16(); + } + ELSE + { + FOR (i = 1; i < NB_LDQ4; i++) + { + IF (LT_32(I, II4[i])) + { + BREAK; + } + } + ka = AA4[sub(i,1)]; + move16(); + } + + /*-------------------------------------------------------* + * decode + *-------------------------------------------------------*/ + a1 = vals_a[ka]; + move16(); + a2 = vals_q[ka]; + move16(); + k1 = a2[0]; + move16(); + code_level = a2[1]; + move16(); + + offset = Is[ka]; + move16(); + code_index = extract_l( L_sub( I, offset ) ); + + sign_8p = s_and(code_index, sub( shl(1,k1), 1 )); + + code_index = shr(code_index, k1); + + m = 0; + move16(); + m1 = 0; + move16(); + m2 = 0; + move16(); + + element_a10 = a1[0]; + move16(); + + SWITCH (code_level) + { + case 4: + + m2 = 1; + move16(); + i = s_and(code_index, 1); + setor_8p_temp_2[0] = 0; + move16(); + + if ( i ) + { + setor_8p_temp_2[0] = 1; + move16(); + } + code_index = shr(code_index, 1); + /* FALLTHRU */ + + case 3: + + m = a2[2]; + move16(); + m1 = a2[3]; + move16(); + + l = select_table22[m1][m]; + move16(); + j = extract_l(L_shr(L_mult0(code_index, mult_avq_tab[l]), shift_avq_tab[l])); + code_index = sub(code_index, extract_l(L_mult0(j, l))); + fcb_decode_pos_fx(code_index,setor_8p_temp_1, m, m1); + + code_index = j; + move16(); + element_a12 = a1[2]; + move16(); + /* FALLTHRU */ + + case 2: + + m = a2[2]; + move16(); + fcb_decode_pos_fx(code_index,setor_8p_temp,8,m); + element_a11 = a1[1]; + move16(); + } + + FOR (i=0; i<8; i++) + { + x[i] = element_a10; + move16(); + } + + FOR (i=0; i 0)) +#else + IF(k1 == 7) +#endif + { + m2 = 7; + move16(); + } + FOR(i = 0; i < m2; i++) + { + IF(x[i] != 0) + { + IF(s_and(shr(sign_8p, m1), 1) != 0) + { + x[i] = sub(0, x[i]); + move16(); + } + m1 = sub(m1, 1); + } + } + + /*--------------------------------------------------------------------* + * recover the sign of last element if needed + *--------------------------------------------------------------------*/ + IF (EQ_16( k1, 7 )) + { + m1 = 0; + move16(); + + FOR (i=0; i<8; i++) + { + m1 = add(m1, x[i]); + } + + IF ( s_and(m1, 3) ) + { + x[7] = sub(0, x[7]); + move16(); + } + } + } +} + +/*-------------------------------------------------------------------* + * fcb_decode_pos_fx + * + * base function for decoding position index + *-------------------------------------------------------------------*/ +static void fcb_decode_pos_fx( + const Word16 index, /* i : Index to decoder */ + Word16 pos_vector[], /* o : Position vector */ + const Word16 pulse_num, /* i : Number of pulses */ + const Word16 pos_num /* i : Number of positions */ +) +{ + Word16 i,k,l; + Word16 temp1,temp2,tmp_loop; + const Word16 *select_table23, *select_table24; + + k = index; + move16(); + l = 0; + move16(); + temp1 = pos_num; + move16(); + temp2 = add( pulse_num, 1 ); + + tmp_loop = sub(pos_num,1); + FOR (i=0; ihSCE[0]->hCoreCoder; hCoreCoder[0]->total_brate = st_ivas->hDecoderConfig->ivas_total_brate; - + hCoreCoder[0]->total_num_bits = st_ivas->num_bits; + hCoreCoder[0]->output_frame_fx = extract_l(Mult_32_16(hCoreCoder[0]->output_Fs, 0x0290)); mdct_switching_dec( hCoreCoder[0] ); for ( ch = 0; ch < MAX_OUTPUT_CHANNELS_IN_DIEGETIC_PAN; ch++ ) { p_output[ch] = st_ivas->p_output_f[ch]; } +#ifndef EVS_FLOAT + Word16 output_16[L_FRAME48k]; +#endif // !EVS_FLOAT /* run the main EVS decoding routine */ if ( hCoreCoder[0]->codec_mode == MODE1 ) { if ( hCoreCoder[0]->Opt_AMR_WB ) { - if ( ( error = amr_wb_dec( hCoreCoder[0], st_ivas->mem_hp20_out[0], p_output[0] ) ) != IVAS_ERR_OK ) +#ifdef EVS_FLOAT + if ( ( error = amr_wb_dec_flt( hCoreCoder[0], st_ivas->mem_hp20_out[0], p_output[0] ) ) != IVAS_ERR_OK ) +#else + if ( ( error = amr_wb_dec_fx(output_16, hCoreCoder[0]) ) != IVAS_ERR_OK ) +#endif { return error; } } else { - if ( ( error = evs_dec( hCoreCoder[0], st_ivas->mem_hp20_out[0], p_output[0], FRAMEMODE_NORMAL ) ) != IVAS_ERR_OK ) +#ifdef EVS_FLOAT + if ( ( error = evs_dec_flt( hCoreCoder[0], st_ivas->mem_hp20_out[0], p_output[0], FRAMEMODE_NORMAL ) ) != IVAS_ERR_OK ) +#else + if ( ( error = evs_dec_fx(hCoreCoder[0], output_16, FRAMEMODE_NORMAL) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -2773,21 +2787,33 @@ static ivas_error evs_dec_main( { if ( hCoreCoder[0]->bfi == 0 ) { - if ( ( error = evs_dec( hCoreCoder[0], st_ivas->mem_hp20_out[0], p_output[0], FRAMEMODE_NORMAL ) ) != IVAS_ERR_OK ) +#ifdef EVS_FLOAT + if ( ( error = evs_dec_flt( hCoreCoder[0], st_ivas->mem_hp20_out[0], p_output[0], FRAMEMODE_NORMAL ) ) != IVAS_ERR_OK ) +#else + if ( ( error = evs_dec_fx(hCoreCoder[0], output_16, FRAMEMODE_NORMAL)) != IVAS_ERR_OK ) +#endif { return error; } } else if ( hCoreCoder[0]->bfi == 2 ) { - if ( ( error = evs_dec( hCoreCoder[0], st_ivas->mem_hp20_out[0], p_output[0], FRAMEMODE_FUTURE ) ) != IVAS_ERR_OK ) +#ifdef EVS_FLOAT + if ( ( error = evs_dec_flt( hCoreCoder[0], st_ivas->mem_hp20_out[0], p_output[0], FRAMEMODE_FUTURE ) ) != IVAS_ERR_OK ) +#else + if ( ( error = evs_dec_fx(hCoreCoder[0], output_16, FRAMEMODE_FUTURE)) != IVAS_ERR_OK ) +#endif { return error; } } else { - if ( ( error = evs_dec( hCoreCoder[0], st_ivas->mem_hp20_out[0], p_output[0], FRAMEMODE_MISSING ) ) != IVAS_ERR_OK ) +#ifdef EVS_FLOAT + if ( ( error = evs_dec_flt( hCoreCoder[0], st_ivas->mem_hp20_out[0], p_output[0], FRAMEMODE_MISSING ) ) != IVAS_ERR_OK ) +#else + if ( ( error = evs_dec_fx(hCoreCoder[0], output_16, FRAMEMODE_MISSING)) != IVAS_ERR_OK ) +#endif { return error; } @@ -2795,7 +2821,6 @@ static ivas_error evs_dec_main( } st_ivas->BER_detect = hCoreCoder[0]->BER_detect; - if ( st_ivas->renderer_type == RENDERER_NON_DIEGETIC_DOWNMIX ) { mixer_left = ( st_ivas->hDecoderConfig->non_diegetic_pan_gain + 1.f ) * 0.5f; @@ -2803,7 +2828,12 @@ static ivas_error evs_dec_main( v_multc( p_output[0], mixer_rigth, p_output[1], nOutSamples ); v_multc( p_output[0], mixer_left, p_output[0], nOutSamples ); } - +#ifndef EVS_FLOAT + for (int i = 0; i < nOutSamples; i++) + { + p_output[0][i] = output_16[i]; + } +#endif if ( !st_ivas->hDecoderConfig->Opt_tsm ) { ivas_jbm_dec_copy_tc_no_tsm( st_ivas, p_output, nOutSamples ); @@ -2820,6 +2850,7 @@ static ivas_error evs_dec_main( else { ivas_syn_output( p_output, nOutSamples, st_ivas->hDecoderConfig->nchan_out, pcmBuf ); + } return IVAS_ERR_OK; diff --git a/lib_dec/lp_exc_d_fx.c b/lib_dec/lp_exc_d_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..bc708244b1a4aeb40f47a8edb6e6e3185f7a13d5 --- /dev/null +++ b/lib_dec/lp_exc_d_fx.c @@ -0,0 +1,87 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include +#include "options.h" /* Compilation switches */ +#include "cnst.h" /* Common constants */ +#include "prot_fx1.h" /* Function prototypes */ +#include "prot_fx2.h" /* Function prototypes */ + +/*======================================================================*/ +/* FUNCTION : lp_filt_exc_dec_fx() */ +/*-----------------------------------------------------------------------*/ +/* PURPOSE : Low-pass filtering of the adaptive exctitation */ +/* */ +/*-----------------------------------------------------------------------*/ +/* INPUT ARGUMENTS : */ +/* _ (Word32) core_brate : Core bitrate Q0 */ +/* _ (Word16) Opt_AMR_WB : flag indicating AMR-WB IO mode Q0 */ +/* _ (Word16) coder_type : coding type Q0 */ +/* _ (Word16) i_subfr : subframe index Q0 */ +/* _ (Word16) L_subfr : subframe size Q0 */ +/*-----------------------------------------------------------------------*/ +/* OUTPUT ARGUMENTS : */ +/*-----------------------------------------------------------------------*/ +/* INPUT OUTPUT ARGUMENTS */ +/* _ (Word16 *) exc : excitation buffer Q0 */ +/*-----------------------------------------------------------------------*/ + +/* */ +/*-----------------------------------------------------------------------*/ +/* RETURN ARGUMENTS : */ +/* _ None */ +/*=======================================================================*/ + +void lp_filt_exc_dec_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + const Word16 codec_mode, /* i : coder mode */ + const Word16 i_subfr, /* i : subframe index */ + const Word16 L_subfr, /* i : subframe size */ + const Word16 L_frame, /* i : frame size */ + Word16 lp_flag, /* i : operation mode signaling */ + Word16 *exc +) +{ + + Word16 i, fac_n, fac_m; + Word16 code[L_FRAME]; + Word32 L_tmp; + + /*-----------------------------------------------------------------* + * Select LP filtering of the adaptive excitation + *-----------------------------------------------------------------*/ + IF(EQ_16(codec_mode, MODE1)) + { + IF(EQ_16(lp_flag, NORMAL_OPERATION)) + { + lp_flag = (Word16)get_next_indice(st_fx, 1); + } + } + IF ( EQ_16(lp_flag, LOW_PASS)) + { + /* pointer positioning to avoid doing it inside the loop */ + test(); + IF(codec_mode ==MODE2 && L_frame==L_FRAME16k) + { + fac_n = 6881/*0.21f Q15*/; + fac_m = 19005/*0.58f Q15*/; + } + ELSE + { + fac_n = 5898/*0.18f Q15*/; + fac_m = 20972/*0.64f Q15*/; + } + + FOR (i=0; i +#include "options.h" /* Compilation switches */ +#include "cnst.h" /* Common constants */ +#include "rom_com.h" /* Static table prototypes */ +#include "prot_fx1.h" /* Function prototypes */ +#include "prot_fx2.h" /* Function prototypes */ +#ifdef LSF_RE_USE_SECONDARY_CHANNEL +#include "ivas_prot.h" +#include "ivas_rom_com.h" +#endif +/*-------------------------------------------------------------------* + * Local functions + *-------------------------------------------------------------------*/ +static void dqlsf_CNG_fx(Decoder_State* st_fx, Word16* lsf_q); + +/*--------------------------------------------------------------------------------------* +* dqlsf_CNG_fx() +* +* LSF de-quantizer for SID frames (uses 28 bits, 4 for VQ, 24 for LVQ) +* +* Note: +* LP-CNG LSF decoder does not need to know the sampling rate, +* the sampling rate data is embedded inside the LSF coefficients. +* If the highest order LSF coefficient (lsf_q[M-1]) is smaller than 6350 then Fs=12.8kHz +* If the highest order LSF coefficient (lsf_q[M-1]) is larger than 6350 then Fs=16kHz +----------------------------------------------------------------------------------------*/ + +static void dqlsf_CNG_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + Word16 *lsf_q /* o : decoded LSFs */ +) +{ + Word16 indice[4]; + Word16 ber_flag; + + indice[0] = (Word16)get_next_indice( st_fx, 4 ); + move16(); + indice[1] = (Word16)get_next_indice( st_fx, LEN_INDICE ); + move16(); + indice[2] = (Word16)get_next_indice( st_fx, LSF_BITS_CNG - 4 - LEN_INDICE ); + move16(); + + /* deindex_lvq_cng decoder does not need to know the sampling rate, the sampling rate data is embedded inside the LSF coefficients */ + ber_flag= + deindex_lvq_cng_fx( &indice[1], lsf_q, indice[0], LSF_BITS_CNG-4, &st_fx->offset_scale1_fx[0][0], &st_fx->offset_scale2_fx[0][0], &st_fx->no_scales_fx[0][0]); + + st_fx->BER_detect = s_or(ber_flag, st_fx->BER_detect); + + /* The sampling frequency of the LP-CNG frame can be determined by checking the value of the highest order LSF coefficient (last coefficient). + If the last decoded LSF coefficient is larger than 6350 the decoded frame is WB2 with sampling rate of 16 kHz + otherwise it is sampled at 12.8kHz and contains either NB or WB LSF data. */ + Vr_add(lsf_q, &CNG_SN1_fx[indice[0] * M], lsf_q, M); + + test(); + test(); + test(); + IF ( ((EQ_16(st_fx->L_frame, L_FRAME16k))&&(LE_16(lsf_q[M-1],WB_LIMIT_LSF_FX)))||((LT_16(st_fx->L_frame,L_FRAME16k))&&(GT_16(lsf_q[M-1],WB_LIMIT_LSF_FX)))) + { + st_fx->BER_detect = 1; + move16(); + } + + return; +} + +/*===========================================================================*/ +/* FUNCTION : lsf_dec_fx() */ +/*---------------------------------------------------------------------------*/ +/* PURPOSE : LSF decoder */ +/*---------------------------------------------------------------------------*/ +/* INPUT ARGUMENTS : */ +/* _ (Struct) st_fx : decoder static memory */ +/* _ (Word16) L_frame : length of the frame */ +/* _ (Word16) coder_type : coding type */ +/* _ (Word16) bwidth : input signal bandwidth */ +/*---------------------------------------------------------------------------*/ +/* OUTPUT ARGUMENTS : */ +/* _ (Word16*) Aq : LP filter coefficient Q12 */ +/* _ (Word16*) lsf_new : LP filter coefficient Q(x2.56) */ +/* _ (Word16*) lsp_new : LP filter coefficient Q15 */ +/* _ (Word16*) lsp_mid : LP filter coefficient Q15 */ +/*---------------------------------------------------------------------------*/ + +/* _ (Word16[]) st_fx->lsf_adaptive_mean_fx : FEC - adaptive mean LSF */ +/* vector for FEC Q(x2.56) */ +/* _ (Word16[]) st_fx->mem_AR_fx : AR memory of LSF quantizer */ +/* (past quantized LSFs without mean) Q(x2.56) */ +/* _ (Word16) st_fx->stab_fac_fx : LSF stability factor Q15 */ +/*---------------------------------------------------------------------------*/ +/* RETURN ARGUMENTS : */ +/* _ None */ +/*===========================================================================*/ +void lsf_dec_fx( + Decoder_State *st_fx, /* i/o: State structure */ + const Word16 tc_subfr, /* i : TC subframe index */ + Word16 *Aq, /* o : quantized A(z) for 4 subframes */ + Word16 *LSF_Q_prediction, /* o : LSF prediction mode */ + Word16 *lsf_new, /* o : de-quantized LSF vector */ + Word16 *lsp_new, /* o : de-quantized LSP vector */ + Word16 *lsp_mid, /* o : de-quantized mid-frame LSP vector */ + const Word16 tdm_low_rate_mode /* i : secondary channel low rate mode flag */ +#ifdef LSF_RE_USE_SECONDARY_CHANNEL + ,const Word16 tdm_lsfQ_PCh[M] /* i : Q LSFs for primary channel */ +#endif +) +{ + Word16 i; + Word16 no_param_lpc; + Word16 param_lpc[NPRM_LPC_NEW]; + Word32 L_tmp; + Word16 nBits = 0; + Word16 tmp_old[M+1], tmp_new[M+1]; + Word16 enr_old = 0, enr_new = 0; + Word16 lsf_diff, coder_type; +#ifdef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING + (void)(tdm_low_rate_mode); +#endif + /* initialize */ + coder_type = st_fx->coder_type_fx; + if ( EQ_32(st_fx->core_brate, SID_2k40) ) + { + coder_type = INACTIVE; + move16(); + } + test(); + if ( EQ_16(coder_type, AUDIO) && GT_16( st_fx->GSC_IVAS_mode, 0) ) + { + coder_type = GENERIC; + move16(); + } + no_param_lpc = 0; + nBits = 0; + move16();move16(); + + /* Find the number of bits for LSF quantization */ + IF ( EQ_32(st_fx->core_brate,SID_2k40)) + { + nBits = LSF_BITS_CNG; + move16(); + } + ELSE + { + test(); + IF ( st_fx->nelp_mode_dec_fx == 0 && st_fx->ppp_mode_dec_fx == 0 ) + { + nBits = st_fx->acelp_cfg.lsf_bits; + move16(); + } + ELSE IF ( EQ_16(st_fx->nelp_mode_dec_fx,1)) + { + IF ( EQ_16(coder_type,UNVOICED)) + { + nBits = 30; + move16(); + if ( EQ_16(st_fx->bwidth,NB)) + { + nBits = 32; + move16(); + } + } + } + ELSE IF ( EQ_16(st_fx->ppp_mode_dec_fx,1)) + { + nBits = 26; + move16(); + } + } + + /* LSF de-quantization */ + lsf_end_dec_fx( st_fx, 0, coder_type, st_fx->bwidth, nBits, lsf_new, param_lpc, LSF_Q_prediction, &no_param_lpc); + + /* convert quantized LSFs to LSPs */ + + lsf2lsp_fx(lsf_new, lsp_new, M ,st_fx->sr_core); + /* set seed_acelp used in UC mode */ + test(); + IF (EQ_16(coder_type, UNVOICED) && GT_16(st_fx->element_mode, EVS_MONO)) + { + st_fx->seed_acelp = 0; + move16(); + FOR (i = no_param_lpc - 1; i >= 0; i--) + { + /* rightshift before *seed_acelp+param_lpc[i] to avoid overflows*/ + st_fx->seed_acelp = (int16_t)((((st_fx->seed_acelp) >> 1) + param_lpc[i]) * 31821L + 13849L); + //PMTE() /*IVAS_CODE to be completed */ + } + } + IF ( EQ_32(st_fx->core_brate,SID_2k40)) + { + /* return if SID frame (conversion to A(z) done in the calling function) */ + return; + } + + /*-------------------------------------------------------------------------------------* + * FEC - update adaptive LSF mean vector + *-------------------------------------------------------------------------------------*/ + + FOR (i=0; ilsfoldbfi1_fx[i], 10922); /*Q(x2.56+16)*/ + L_tmp = L_mac(L_tmp, st_fx->lsfoldbfi0_fx[i], 10922); /*Q(x2.56+16)*/ + st_fx->lsf_adaptive_mean_fx[i] = round_fx(L_tmp); /*Q(x2.56)*/ + } + + test(); + test(); + IF ( ( st_fx->prev_bfi && (EQ_16(coder_type,TRANSITION))&&(EQ_16(tc_subfr,sub(st_fx->L_frame,L_SUBFR))))) + { + lsf_diff = 1205; + move16(); /*int_fs / (float)(2*(M+1)); = 470.588 -> 1205 in Q2.56 */ + if( EQ_16(st_fx->L_frame,L_FRAME)) + { + lsf_diff = 964; + move16(); /*int_fs / (float)(2*(M+1)); = 376.47 -> 964 in Q2.56 */ + } + st_fx->lsf_old_fx[0] = lsf_diff; + move16(); + + FOR ( i=1; ilsf_old_fx[i] = add(st_fx->lsf_old_fx[i-1], lsf_diff); + move16(); + } + lsf2lsp_fx( st_fx->lsf_old_fx, st_fx->lsp_old_fx, M, st_fx->sr_core ); + } + /*-------------------------------------------------------------------------------------* + * Mid-frame LSF decoding + * LSP interpolation and conversion of LSPs to A(z) + *-------------------------------------------------------------------------------------*/ + if(st_fx->rate_switching_reset) + { + /*extrapolation in case of unstable LSF convert*/ + Copy(lsp_new,st_fx->lsp_old_fx,M); + Copy(lsf_new,st_fx->lsf_old_fx,M); + } + { + /* Mid-frame LSF decoding */ + lsf_mid_dec_fx( st_fx, lsp_new, coder_type, lsp_mid); + } + test(); + test(); + IF ( !( st_fx->prev_bfi && (EQ_16(coder_type,TRANSITION))&&(EQ_16(tc_subfr,sub(st_fx->L_frame,L_SUBFR))))) + { + IF ( st_fx->prev_bfi) + { + /* check, if LSP interpolation can be relaxed */ + E_LPC_f_lsp_a_conversion( st_fx->lsp_old_fx, tmp_old, M); + enr_old = Enr_1_Az_fx( tmp_old, 2*L_SUBFR ); + + E_LPC_f_lsp_a_conversion( lsp_new, tmp_new, M); + enr_new = Enr_1_Az_fx( tmp_new, 2*L_SUBFR ); + + IF( LT_16(enr_new, mult_r(9830/*0.3 Q15*/,enr_old))) + { + /* OLD CODE : if( st->safety_net == 1), replaced with a decision similar to MODE2 */ + st_fx->relax_prev_lsf_interp_fx = -1; + move16(); + test(); + test(); + test(); + test(); + if ( EQ_16(st_fx->clas_dec, UNVOICED_CLAS)||EQ_16(st_fx->clas_dec,SIN_ONSET)||EQ_16(st_fx->clas_dec,INACTIVE_CLAS)||EQ_16(coder_type,GENERIC)||EQ_16(coder_type,TRANSITION)) + { + st_fx->relax_prev_lsf_interp_fx = 1; + move16(); + } + } + } + } + test(); + IF( EQ_16(st_fx->last_core, HQ_CORE)&&EQ_16(st_fx->core,ACELP_CORE)) + { + /* update old LSPs/LSFs in case of HQ->ACELP core switching */ + Copy( lsp_mid, st_fx->lsp_old_fx, M ); + lsp2lsf_fx( lsp_mid, st_fx->lsf_old_fx, M, st_fx->sr_core); + } +#ifdef ADD_LRTD + IF (EQ_16(tdm_low_rate_mode, 1) && GT_16(coder_type, UNVOICED)) + { + PMT("To be verified") + IF (EQ_16(st_fx->active_cnt_fx, 1) ) + { + Copy(lsp_mid, st_fx->lsp_old, M); + lsp2lsf_fx(lsp_mid, st_fx->lsf_old_fx, M, st_fx->sr_core); + Copy(lsp_new, lsp_mid, M); + } + + /* LSP interpolation and conversion of LSPs to A(z) - two-subframe mode */ + int_lsp4_fx(st_fx->L_frame, st_fx->lsp_old_fx, lsp_mid, lsp_new, Aq, M, -2); + } + ELSE +#endif + { + /* LSP interpolation and conversion of LSPs to A(z) */ + int_lsp4_fx(st_fx->L_frame, st_fx->lsp_old_fx, lsp_mid, lsp_new, Aq, M, st_fx->relax_prev_lsf_interp_fx); + } + /*------------------------------------------------------------------* + * Check LSF stability (distance between old LSFs and current LSFs) + *------------------------------------------------------------------*/ + + st_fx->stab_fac_fx = lsf_stab_fx( lsf_new, st_fx->lsf_old_fx, 0, st_fx->L_frame ); /*Q15*/ + + return; +} +/*========================================================================*/ +/* FUNCTION : lsf_end_dec_fx() */ +/*------------------------------------------------------------------------*/ +/* PURPOSE : De-quantize frame end LSF vector */ +/*------------------------------------------------------------------------*/ +/* INPUT ARGUMENTS : */ +/* _ (Word16) coder_type : coding type */ +/* _ (Word16) bwidth : input signal bandwidth */ +/* _ (Word16) nBits : number of bits used for ISF quantization */ +/* _ (Word32*) grid : Table of 100 grid points for evaluating */ +/* Chebyshev polynomials Q31 */ +/* _ (Word16) int_fs : sampling frequency */ +/* _ (Word32) core_brate : Coding Bit Rate */ +/* _ (Word32*) p_offset_scale1 : offsets for LSF LVQ structure 1st */ +/* 8-dim subvector Q0 */ +/* _ (Word32*) p_offset_scale2 : offsets for LSF LVQ structure 2nd */ +/* 8-dim subvector Q0 */ +/* _ (Word32*) p_offset_scale1_p : offsets for LSF LVQ structure, pred .*/ +/* case, 1st 8-dim subvector Q0 */ +/* _ (Word32*) p_offset_scale2_p : offsets for LSF LVQ structure, */ +/* pred. case, 2nd 8-dim subvector Q0 */ +/* _ (Word16*) p_no_scales : LSF LVQ structure Q0 */ +/* _ (Word16*) p_no_scales_p : LSF LVQ structure Q0 */ +/*------------------------------------------------------------------------*/ +/* INPUT/OUTPUT ARGUMENTS : */ +/* _ (Word16*) mem_AR : quantizer memory for AR model Q(x2.56) */ +/*------------------------------------------------------------------------*/ +/* OUTPUT ARGUMENTS : */ +/* _ (Word16*) qlsf : quantized LSFs in the cosine domain Q(x2.56) */ +/*------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------*/ +/* RETURN ARGUMENTS : */ +/* _ None */ +/*========================================================================*/ + +void lsf_end_dec_fx( + Decoder_State * st, /* i/o: decoder state structure */ + Word16 mode2_flag, + const Word16 coder_type_org, /* i : coding type */ + const Word16 bwidth, /* i : input signal bandwidth */ + const Word16 nBits_in, /* i : number of bits used for ISF quantization*/ + Word16 *qlsf, /* o : quantized LSFs in the cosine domain */ + Word16 *lpc_param, /* i : LPC parameters */ + Word16 *LSF_Q_prediction, /* o : LSF prediction mode */ + Word16 * nb_indices /* o : number of indices */ +#ifdef LSF_RE_USE_SECONDARY_CHANNEL + ,const Word16 tdm_lsfQ_PCh[M] /* i : Q LSFs for primary channel */ +#endif +) +{ + Word16 pred0[M]; /* Prediction for the safety-net quantizer (usually mean)*/ + Word16 pred1[M], pred2[M]; /* Prediction for the predictive quantizer*/ + Word16 stages0; /* Amount of stages used by safety-net quantizer*/ + Word16 stages1; /* Amount of stages used by predictive quantizer*/ + Word16 levels0[MAX_VQ_STAGES]; /* Sizes of different codebook stages for safety-net quantizer*/ + Word16 levels1[MAX_VQ_STAGES]; /* Sizes of different codebook stages for predictive quantizer*/ + Word16 i; + Word16 TCQIdx[M/2+4]; + Word16 bits0[MAX_VQ_STAGES], bits1[MAX_VQ_STAGES]; + Word16 cumleft; + Word16 lindice[MAX_VQ_STAGES+3]; /* Predictor selector needs 1 bit and the LVQ indice uses 3 shorts */ + Word16 mode_lvq, mode_lvq_p; + Word16 safety_net, predmode, stages, *levels; + const Word16 *Bit_alloc1 = NULL, *bits; + Word16 num_bits; + Word16 * p_lpc_param; + + Word16 nBits; + + Word16 coder_type; + Word16 ber_flag; + Word16 flag_1bit_gran; +#ifdef LSF_RE_USE_SECONDARY_CHANNEL + Word16 pred3[M]; +#endif + flag_1bit_gran = (Word16)GT_16(st->element_mode, EVS_MONO); + + nBits = nBits_in; + *nb_indices = 0; + move16();move16();move16(); + + test(); + test(); +#ifdef LSF_RE_USE_SECONDARY_CHANNEL + IF((EQ_16(coder_type_org, GENERIC)) && (EQ_32(st->sr_core,INT_FS_16k)) && (mode2_flag==0) && (st->idchan == 0)) +#else + IF((EQ_16(coder_type_org, GENERIC)) && (EQ_32(st->sr_core,INT_FS_16k)) && (mode2_flag==0)) +#endif + { + /* this bit is used only for primary channel or mono */ + coder_type = (Word16)get_next_indice( st, 1 ); + coder_type = add(coder_type,2); + test(); test(); + if (EQ_16(coder_type, GENERIC) || (EQ_16(coder_type, VOICED) && EQ_16(flag_1bit_gran, 1))) + { + nBits = sub(nBits,1); + } + } + ELSE + { + coder_type = coder_type_org; + move16(); + } + + /*--------------------------------------------------------------------------------* + * LSF de-quantization of SID frames + *--------------------------------------------------------------------------------*/ + + IF ( st->core_brate == SID_2k40 ) + { + dqlsf_CNG_fx( st, qlsf); + sort_fx( qlsf, 0, M-1); + reorder_lsf_fx( qlsf, MODE1_LSF_GAP_FX, M, st->sr_core ); + + return; + } + + + find_pred_mode(&predmode, coder_type, bwidth, st->sr_core, &mode_lvq, &mode_lvq_p, st->total_brate); + /*----------------------------------------------------------------* + * Calculate number of stages and levels for each stage based on the allowed bit allocation + * (subtract one bit for LSF predictor selection) + *----------------------------------------------------------------*/ + lsf_allocate_fx( sub(nBits,shr(predmode,1)), mode_lvq, mode_lvq_p, &stages0, &stages1, levels0, levels1, + bits0, bits1); + + + /*--------------------------------------------------------------------------* + * Select safety_net or predictive mode + *--------------------------------------------------------------------------*/ +#ifdef LSF_RE_USE_SECONDARY_CHANNEL + IF (st->tdm_LRTD_flag == 0 && EQ_16(st->idchan, 1) && tdm_lsfQ_PCh != NULL) + { + /* if secondary channel predmode is set to be > 2 */ + /*predmode += 3;*/ + predmode =add(predmode , 3); + } +#endif + p_lpc_param = lpc_param; + + + move16(); + IF ( predmode == 0 ) + { + safety_net = 1; + move16(); + } + ELSE IF ( predmode == 1 ) + { + safety_net = 0; + move16(); + } + ELSE + { + IF (EQ_16(mode2_flag, 1) || EQ_16(st->core, TCX_20_CORE) || EQ_16(st->core, TCX_10_CORE)) + { + /* read from param_lpc */ + safety_net = p_lpc_param[0]; + move16(); + p_lpc_param++; + *nb_indices = add(*nb_indices, 1); + } + ELSE + { + safety_net = (Word16)get_next_indice( st, 1 ); + } + } + + st->safety_net_fx = safety_net; + move16(); + + /*--------------------------------------------------------------------------* + * Read indices from array + *--------------------------------------------------------------------------*/ +#ifdef LSF_RE_USE_SECONDARY_CHANNEL + /* Make sure there are the correct bit allocations */ + IF (st->idchan == 1 && predmode > 2) + { + PMTE() + /* use same AR prediction bit allocation for intra and inter modes*/ + lsf_allocate(nBits - 1, mode_lvq, 9, &stages0, &stages1, levels0, levels1, bits0, bits1); + stages0 = stages1; + mvs2s(levels1, levels0, stages0); + mvs2s(bits1, bits0, stages0); + } +#endif + + test(); test(); + IF (EQ_32(st->sr_core , INT_FS_16k) && EQ_16(coder_type, VOICED) && flag_1bit_gran == 0) + { + /* BC-TCVQ - only in VOICED_WB@16kHz */ + test(); test(); + IF (EQ_16(st->codec_mode, MODE2) || EQ_16(st->core, TCX_20_CORE) || EQ_16(st->core, TCX_10_CORE)) + { + *nb_indices = 10; + move16(); + move16(); + TCQIdx[0] = safety_net; + FOR (i = 1; i < *nb_indices; i++) + { + TCQIdx[i] = *p_lpc_param++; + move16(); + } + } + ELSE + { + Bit_alloc1 = &BC_TCVQ_BIT_ALLOC_40B[1]; + TCQIdx[0] = safety_net; + move16(); + FOR (i = 0; i < M / 2 + 3; i++) + { + TCQIdx[i + 1] = get_next_indice(st, Bit_alloc1[i]); + move16(); + } + } + } + ELSE + { + IF(safety_net) + { + stages = stages0; + move16(); + levels = levels0; + move16(); + bits = bits0; + move16(); + } + ELSE + { + stages = stages1; + move16(); + levels = levels1; + move16(); + bits = bits1; + move16(); + } + test(); test(); + IF(EQ_16(mode2_flag, 1) || EQ_16(st->core, TCX_20_CORE) || EQ_16(st->core, TCX_10_CORE)) + { + FOR(i = 0; i < stages - 1; i++) + { + num_bits = bits[i]; + move16(); + lindice[i + 1] = *p_lpc_param++; + move16(); + } + + cumleft = levels[stages - 1]; + move16(); + WHILE(cumleft > 0) + { + IF(GT_16(cumleft, LEN_INDICE)) + { + cumleft = sub(cumleft, LEN_INDICE); + } + ELSE + { + cumleft = 0; + move16(); + } + + lindice[i + 1] = *p_lpc_param++; + move16(); + i = add(i,1); + } + *nb_indices = add(*nb_indices , i); + move16(); + } + ELSE + { + FOR(i = 0; i < stages - 1; i++) + { + num_bits = bits[i]; + move16(); + lindice[i + 1] = (Word16)get_next_indice(st, num_bits); + } + + cumleft = levels[sub(stages,1)]; + WHILE(cumleft > 0) + { + IF(GT_16(cumleft, LEN_INDICE)) + { + cumleft = sub(cumleft, LEN_INDICE); + num_bits = LEN_INDICE; + move16(); + } + ELSE + { + num_bits = (Word16)cumleft; + move16(); + cumleft = 0; + move16(); + } + + lindice[i + 1] = (Word16)get_next_indice(st, num_bits); + i = add(i,1); + } + } + } + IF(EQ_16(st->reset_mem_AR,1)) + { + FOR( i=0; imem_AR_fx[i] = ModeMeans_fx[mode_lvq][i]; + move16(); + } + st->reset_mem_AR = 0; + } + + /*------------------------------------------------------------------------------------------* + * De-quantize LSF vector + *------------------------------------------------------------------------------------------*/ + + *LSF_Q_prediction = SAFETY_NET; + move16(); + /* VOICED_WB@16kHz */ + test(); test(); + IF ( EQ_32(st->sr_core, INT_FS_16k) && EQ_16(coder_type,VOICED) && flag_1bit_gran == 0) + { + /* BC-TCVQ decoder */ + safety_net = qlsf_ARSN_tcvq_Dec_16k_fx ( qlsf, TCQIdx, nBits-1 ); + + /* Update mem_MA */ + Copy( qlsf, st->mem_MA_fx, M ); + + IF (safety_net) + { + Copy(ModeMeans_fx[mode_lvq], pred0, M); + } + ELSE + { + FOR(i = 0; i < M; i++) + { + pred0[i] = add(ModeMeans_fx[mode_lvq][i], mult(Predictors_fx[mode_lvq_p][i],(sub(st->mem_AR_fx[i], ModeMeans_fx[mode_lvq][i])))); /* Q(x2.56)*/ + } + *LSF_Q_prediction = AUTO_REGRESSIVE; + move16(); + } + Vr_add( qlsf, pred0, qlsf, M ); + } + ELSE + { + + /* Safety-net */ + Copy( ModeMeans_fx[mode_lvq], pred0, M ); + /* for mem_MA update */ + FOR (i=0; imem_MA_fx[i])); + } +#ifdef LSF_RE_USE_SECONDARY_CHANNEL + /* TD stereo SCh: perform intra-frame prediction with pulling-to-mean */ + if (st->tdm_LRTD_flag == 0 && st->idchan == 1 && tdm_lsfQ_PCh != NULL) + { + tdm_SCh_LSF_intra_pred(st->element_brate, tdm_lsfQ_PCh, pred3); + } +#endif + IF ( safety_net ) + { + /* LVQ */ +#ifdef LSF_RE_USE_SECONDARY_CHANNEL + if (st->tdm_LRTD_flag == 0 && st->idchan == 1 && tdm_lsfQ_PCh != NULL) + { + + /* intra mode*/ + st->BER_detect = st->BER_detect | + vq_dec_lvq(0, qlsf, &lindice[1], stages0, M, 9, /*mode_lvq_p,*/ levels0[stages0 - 1]); + + v_add(qlsf, pred3, qlsf, M); + v_sub(qlsf, pred1, st->mem_MA, M); + } + else +#endif + { + ber_flag = vq_dec_lvq_fx(1, qlsf, &lindice[1], stages0, M, mode_lvq, levels0[stages0 - 1], + &st->offset_scale1_fx[0][0], &st->offset_scale2_fx[0][0], &st->offset_scale1_p_fx[0][0], &st->offset_scale2_p_fx[0][0], + &st->no_scales_fx[0][0], &st->no_scales_p_fx[0][0]); + + st->BER_detect = s_or(st->BER_detect, ber_flag); + Vr_add(qlsf, pred0, qlsf, M); + Vr_subt(qlsf, pred1, st->mem_MA_fx, M); + } + } + ELSE + { +#ifdef LSF_RE_USE_SECONDARY_CHANNEL + IF (EQ_16(predmode, 4)) + { + mode_lvq_p = 9; + predmode = 2; + move16(); move16(); + } +#endif + ber_flag = vq_dec_lvq_fx( 0, qlsf, &lindice[1], stages1, M, mode_lvq_p, levels1[stages1-1], + &st->offset_scale1_fx[0][0], &st->offset_scale2_fx[0][0], &st->offset_scale1_p_fx[0][0], &st->offset_scale2_p_fx[0][0], + &st->no_scales_fx[0][0], &st->no_scales_p_fx[0][0]); + + st->BER_detect = s_or(st->BER_detect, ber_flag); +#ifdef LSF_RE_USE_SECONDARY_CHANNEL + test(); + IF (EQ_16(predmode, 1) || EQ_16(predmode, 4)) /* MA only */ +#else + IF (EQ_16(predmode, 1)) /* MA only */ +#endif + { + Copy(qlsf, st->mem_MA_fx, M); + Vr_add( qlsf, pred1, qlsf, M ); + *LSF_Q_prediction = MOVING_AVERAGE; + move16(); + } + ELSE + { + /* AR */ + FOR ( i=0; imem_AR_fx[i], pred0[i]))); + } + Vr_add( qlsf, pred2, qlsf, M ); + Vr_subt( qlsf, pred1, st->mem_MA_fx, M ); + *LSF_Q_prediction = AUTO_REGRESSIVE; + move16(); + } + } + } + + /*--------------------------------------------------------------------------* + * Sort the quantized vector + * Verify stability + * Update AR-predictor memory + *--------------------------------------------------------------------------*/ + + /* Sort the quantized vector */ + sort_fx( qlsf, 0, M-1 ); + + /* Verify stability */ + reorder_lsf_fx( qlsf, MODE1_LSF_GAP_FX, M, st->sr_core ); + /* Update predictor memory */ + Copy( qlsf, st->mem_AR_fx, M ); + + st->mode_lvq = mode_lvq; + move16(); + + + return; +} + + +/*========================================================================*/ +/* FUNCTION : lsf_mid_dec_fx() */ +/*------------------------------------------------------------------------*/ +/* PURPOSE : Decode mid-frame LSFs */ +/*------------------------------------------------------------------------*/ +/* INPUT ARGUMENTS : */ +/* _ (Word16) coder_type : Coder type */ +/* _ (Word32) core_brate : core bitrate */ +/* _ (Word16[]) lsp_new : quantized LSPs from frame beginning Q15 */ +/* _ (Word16[]) lsp_mid : quantized LSPs from frame end Q15 */ +/*------------------------------------------------------------------------*/ +/* INPUT/OUTPUT ARGUMENTS : */ +/*------------------------------------------------------------------------*/ +/* OUTPUT ARGUMENTS : */ +/* _ (Word16[]) qlsp : quantized LSPs Q15 */ +/*------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------*/ +/* RETURN ARGUMENTS : */ +/* _ None */ +/*========================================================================*/ +void lsf_mid_dec_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + Word16 lsp_new[], /* i : quantized LSPs from frame endSQ15*/ + Word16 coder_type, /* i : Coder type */ + Word16 lsp_mid[] /* o : quantized LSPs Q15*/ +) +{ + Word16 j, idx; + Word16 nb_bits; + Word16 qlsf0[M], qlsf1[M], qlsf[M]; + Word32 L_tmp; + Word16 bad_spacing; + const Word16 *ratio = NULL; + bad_spacing = 0; + move16(); + + + /* Convert LSPs to LSFs */ + lsp2lsf_fx(st_fx->lsp_old_fx, qlsf0, M, st_fx->sr_core); + lsp2lsf_fx( lsp_new, qlsf1, M, st_fx->sr_core); + + /* Codebook selection */ + IF ( EQ_16(st_fx->ppp_mode_dec_fx,1)) + { + nb_bits = 1; + move16(); + ratio = &tbl_mid_voi_wb_1b_fx[0]; + } + ELSE IF ( EQ_16(st_fx->nelp_mode_dec_fx,1)) + { + nb_bits = 4; + move16(); + ratio = &tbl_mid_unv_wb_4b_fx[0]; + } + ELSE + { + nb_bits = st_fx->acelp_cfg.mid_lsf_bits; + move16(); + + /* codebook selection */ + + IF ( EQ_16(coder_type,VOICED)) + { + SWITCH ( nb_bits ) + { + case 5: + { + ratio = tbl_mid_voi_wb_5b_fx; + BREAK; + } + case 4: + { + ratio = tbl_mid_voi_wb_4b_fx; + BREAK; + } + case 1: + { + ratio = tbl_mid_voi_wb_1b_fx; + break; + } + } + } + ELSE IF ( coder_type == UNVOICED ) + { + ratio = tbl_mid_unv_wb_5b_fx; + } + ELSE + { + /* GENERIC, TRANSITION, AUDIO and INACTIVE */ + SWITCH ( nb_bits ) + { + case 5: + { + ratio = tbl_mid_gen_wb_5b_fx; + BREAK; + } +#ifdef IVAS_CODE + case 4: + { + ratio = tbl_mid_gen_wb_4b_fx; + break; + } +#endif + case 2: + { + ratio = tbl_mid_gen_wb_2b_fx; + BREAK; + } + } + } + } + + /* Retrieve mid-frame LSF index */ + idx = (Word16)get_next_indice( st_fx, nb_bits ); + + /* Calculation of mid-LSF vector */ + FOR (j=0; jQ(x2.56+14)*/ + L_tmp = L_mac(L_tmp, ratio[idx*M+j], qlsf1[j]); /*Q(x2.56+14)*/ + qlsf[j] = round_fx(L_shl(L_tmp,2)); /*Q(x2.56)*/ + } + + /* check for incorrect LSF ordering */ + IF ( EQ_16(st_fx->mid_lsf_int_fx, 1)) + { + FOR (j=1; jprev_bfi || ( EQ_16(st_fx->mid_lsf_int_fx, 1) && bad_spacing)) + { + FOR (j=0; j 0 && LT_16(j, M)&<_16(qlsf[j],add(qlsf[j-1],LSF_GAP_MID_FX))) + { + qlsf[j] = add(qlsf[j-1], LSF_GAP_MID_FX); + move16(); + } + } + } + ELSE + { + /* otherwise, use regular LSF spacing and ordering as in the encoder */ + FOR (j=0; j 0 && LT_16(j, M)&<_16(qlsf[j],add(qlsf[j-1],LSF_GAP_MID_FX))) + { + qlsf[j] = add(qlsf[j-1], LSF_GAP_MID_FX); + move16(); + } + } + } + + if ( st_fx->prev_bfi ) + { + /* continue redoing mid-LSF interpolation with 0.4 in order not to propagate the error */ + st_fx->mid_lsf_int_fx = 1; + move16(); + } + + if (st_fx->safety_net_fx ) + { + /* safety-net encountered -> stop redoing mid-LSF interpolation with 0.4 */ + st_fx->mid_lsf_int_fx = 0; + move16(); + } + + reorder_lsf_fx( qlsf, LSF_GAP_MID_FX, M, st_fx->sr_core); + + /* convert back to LSPs */ + lsf2lsp_fx( qlsf, lsp_mid, M, st_fx->sr_core); + + return; +} diff --git a/lib_dec/lsf_msvq_ma_dec.c b/lib_dec/lsf_msvq_ma_dec.c index 0471cdf76dd0446e862d526c1dfb5b08619ee703..6e7288a760e1a5c468b8360c1bee0d708166b00b 100644 --- a/lib_dec/lsf_msvq_ma_dec.c +++ b/lib_dec/lsf_msvq_ma_dec.c @@ -43,12 +43,12 @@ #include "wmc_auto.h" /*---------------------------------------------------------------------* - * lsf_msvq_ma_decprm() + * lsf_msvq_ma_decprm_ivas() * * *---------------------------------------------------------------------*/ -int16_t lsf_msvq_ma_decprm( +int16_t lsf_msvq_ma_decprm_ivas( Decoder_State *st, int16_t *param_lpc ) { @@ -131,12 +131,12 @@ int16_t lsf_msvq_ma_decprm( /*---------------------------------------------------------------------* - * lsf_bctcvq_decprm() + * lsf_bctcvq_decprm_ivas() * * *---------------------------------------------------------------------*/ -int16_t lsf_bctcvq_decprm( +int16_t lsf_bctcvq_decprm_ivas( Decoder_State *st, int16_t *param_lpc ) { @@ -160,13 +160,13 @@ int16_t lsf_bctcvq_decprm( /*---------------------------------------------------------------------* - * D_lsf_tcxlpc() + * D_lsf_tcxlpc_ivas() * * *---------------------------------------------------------------------*/ /*! r: number of indices */ -int16_t D_lsf_tcxlpc( +int16_t D_lsf_tcxlpc_ivas( const int16_t indices[], /* i : VQ indices */ float lsf_q[], /* o : quantized lsf */ Word16 lsp_q_ind[], /* o : quantized lsp (w/o MA prediction) */ @@ -184,7 +184,7 @@ int16_t D_lsf_tcxlpc( NumIndices = 1; - msvq_dec_float( lsf_codebook[narrowband][cdk], lsf_dims, lsf_offs, TCXLPC_NUMSTAGES, M, M, indices + NumIndices, 0, NULL, lsf_q, lsf_q_ind ); + msvq_dec_float(lsf_codebook_flt[narrowband][cdk], lsf_dims_ivas, lsf_offs_ivas, TCXLPC_NUMSTAGES, M, M, indices + NumIndices, 0, NULL, lsf_q, lsf_q_ind ); NumIndices += TCXLPC_NUMSTAGES; @@ -193,7 +193,7 @@ int16_t D_lsf_tcxlpc( /* Only add contribution if flag is enabled */ - msvq_dec_float( lsf_ind_codebook[narrowband][cdk], lsf_ind_dims, lsf_ind_offs, TCXLPC_IND_NUMSTAGES, M, M, indices + NumIndices, 0, NULL, lsf_rem_q, lsf_rem_q_ind ); + msvq_dec_float(lsf_ind_codebook_flt[narrowband][cdk], lsf_ind_dims_ivas, lsf_ind_offs, TCXLPC_IND_NUMSTAGES, M, M, indices + NumIndices, 0, NULL, lsf_rem_q, lsf_rem_q_ind ); NumIndices += TCXLPC_IND_NUMSTAGES; /* Add to MA-removed vector */ @@ -231,13 +231,13 @@ int16_t D_lsf_tcxlpc( /*---------------------------------------------------------------------* - * dec_lsf_tcxlpc() + * dec_lsf_tcxlpc_ivas() * * *---------------------------------------------------------------------*/ /*! r: number of bits read */ -int16_t dec_lsf_tcxlpc( +int16_t dec_lsf_tcxlpc_ivas( Decoder_State *st, /* i/o: Decoder state */ int16_t **indices, /* o : Ptr to VQ indices */ const int16_t narrowband, /* i : narrowband flag */ @@ -262,10 +262,10 @@ int16_t dec_lsf_tcxlpc( } /* Decode independent lsf */ - msvq_dec_float( lsf_codebook[narrowband][cdk], lsf_dims, lsf_offs, TCXLPC_NUMSTAGES, M, M, flag + 1, 0, NULL, lsf_q_ignored, lsf_q_ind ); + msvq_dec_float(lsf_codebook_flt[narrowband][cdk], lsf_dims_ivas, lsf_offs_ivas, TCXLPC_NUMSTAGES, M, M, flag + 1, 0, NULL, lsf_q_ignored, lsf_q_ind ); /* Update flag */ - *flag = lsf_ind_is_active( lsf_q_ind, lsf_means_float[narrowband], narrowband, cdk ); + *flag = lsf_ind_is_active_flt( lsf_q_ind, lsf_means_float[narrowband], narrowband, cdk ); if ( *flag ) { diff --git a/lib_dec/lsf_msvq_ma_dec_fx.c b/lib_dec/lsf_msvq_ma_dec_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..f5ab44b59ac30dac2efabec7a37e3b8721ad6058 --- /dev/null +++ b/lib_dec/lsf_msvq_ma_dec_fx.c @@ -0,0 +1,302 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include +#include +#include "options.h" +#include "cnst.h" +#include "prot_fx1.h" +#include "prot_fx2.h" +#include "basop_util.h" +#include "rom_com.h" + +#ifndef swap + #define swap(x,y,type) {type u__p; u__p=x; x=y; y=u__p;} +#endif +/*---------------------------------------------------------------------* + * lsf_msvq_ma_decprm() + * + * + *---------------------------------------------------------------------*/ + +Word16 lsf_msvq_ma_decprm( Decoder_State * st, Word16 *param_lpc) +{ + Word16 i, nbits_lpc, tmp; + Word16 bits_midlpc; + Word16 bits0[MAX_VQ_STAGES], bits1[MAX_VQ_STAGES], stages0, stages1, stages, + levels0[MAX_VQ_STAGES], levels1[MAX_VQ_STAGES], * bits; + Word16 predmode, mode_lvq, mode_lvq_p, safety_net; + + bits_midlpc=5; + move16(); + + test(); + IF ((EQ_32(st->sr_core, INT_FS_16k))&&(EQ_16(st->coder_type_fx,UNVOICED))) + { + find_pred_mode(&predmode, GENERIC, sub(1, st->narrowBand) /*st->bwidth*/, st->sr_core, + &mode_lvq, &mode_lvq_p, st->total_brate); + move16(); + } + ELSE + { + IF (EQ_16(st->core, TCX_20_CORE)) + { + find_pred_mode(&predmode, AUDIO, sub(1,st->narrowBand)/*st->bwidth*/, st->sr_core, &mode_lvq, &mode_lvq_p, st->total_brate ); + move16(); + } + ELSE + { + find_pred_mode(&predmode, st->coder_type_fx, sub(1, st->narrowBand)/*st->bwidth*/, st->sr_core, &mode_lvq, &mode_lvq_p, st->total_brate ); + move16(); + } + } + lsf_allocate_fx( sub(ENDLSF_NBITS, shr(predmode,1)), mode_lvq, mode_lvq_p, &stages0, &stages1, levels0, levels1, bits0, bits1); + + + nbits_lpc = 0; + move16(); + + IF (EQ_16(predmode, 2)) + { + /* there is choice between SN and AR prediction */ + safety_net = get_next_indice(st, 1); + + IF (EQ_16(safety_net,1)) + { + stages = stages0; + move16(); + bits = bits0; + move16(); + } + ELSE + { + stages = stages1; + move16(); + bits = bits1; + move16(); + } + *param_lpc = safety_net; + move16(); + param_lpc++; + nbits_lpc++; + + } + ELSE + { + stages = stages1; + move16(); + bits = bits1; + move16(); + } + + + tmp = sub(stages,1); + FOR (i=0; icoder_type_fx, VOICED) && st->core==0 && st->acelp_cfg.midLpc) + { + + *param_lpc = get_next_indice(st, bits_midlpc); + nbits_lpc = add(nbits_lpc, bits_midlpc); + } + + return nbits_lpc; +} + + + +Word16 lsf_bctcvq_decprm( + Decoder_State * st, + Word16 *param_lpc +) +{ + Word16 i, nbits_lpc; + Word16 num_par; + const Word16 *bits1; + + num_par = 10; + bits1 = BC_TCVQ_BIT_ALLOC_40B; + + nbits_lpc = 0; + + + FOR (i=0; inext_bit_pos; + move16(); + FOR (i=0; inext_bit_pos, start_bit_pos); +} diff --git a/lib_dec/nelp_dec_fx.c b/lib_dec/nelp_dec_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..9aa4f3ae2b3d41e056a416c666e4fdc8ca844ce8 --- /dev/null +++ b/lib_dec/nelp_dec_fx.c @@ -0,0 +1,404 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include +#include "options.h" /* Compilation switches */ +#include "prot_fx1.h" /* Function prototypes */ +#include "prot_fx2.h" /* Function prototypes */ +#include "rom_com.h" + +/*===================================================================*/ +/* FUNCTION : normalize_arr() */ +/*-------------------------------------------------------------------*/ +/* PURPOSE : Normalize array */ +/* */ +/*-------------------------------------------------------------------*/ +/* GLOBAL INPUT ARGUMENTS : */ +/* _ (Word16*) qf */ +/* _ (Word16*) size */ +/* _ (Word16*) hdr */ +/*-------------------------------------------------------------------*/ +/* OUTPUT ARGUMENTS : */ +/* _ (Word16*) arr : Normalized array */ +/*-------------------------------------------------------------------*/ + +/* _ None */ +/*-------------------------------------------------------------------*/ +/* RETURN ARGUMENTS : */ +/* _ None */ +/*===================================================================*/ +static void normalize_arr(Word16 *arr, Word16 *qf, Word16 size, Word16 hdr) +{ + Word16 i; + Word16 max_s = 0; + + FOR(i = 0; i < size; i++) + { + max_s=s_max(max_s, abs_s(arr[i])); + } + + *qf=norm_s((Word16)max_s); + test(); + IF((*qf == 0)&&(((Word16)max_s)==0)) + { + *qf = 15; + move16(); + } + + *qf = *qf-hdr; + + FOR (i = 0; i < size; i++) + { + arr[i] = shl(arr[i], *qf); + move16(); /* saturation can occur here */ + } + + return; +} + +/*===================================================================*/ +/* FUNCTION : nelp_decoder_fx() */ +/*-------------------------------------------------------------------*/ +/* PURPOSE : NELP decoding for the current frame */ +/* */ +/*-------------------------------------------------------------------*/ +/* GLOBAL INPUT ARGUMENTS : */ +/* _ (Struct) st */ +/* _ (Word16[]) exc_nelp : adapt. excitation/total exc (Q0) */ +/* _ (Word16[]) exc : adapt. excitation exc (Q0) */ +/* _ (Word16) bfi : frame error rate */ +/* _ (Word16) coder_type : coding type */ +/*-------------------------------------------------------------------*/ +/* OUTPUT ARGUMENTS : */ +/* _ (Word16[]) exc_nelp : adapt. excitation/total exc (Q0) */ +/* (Word16[]) gain_buf : floating pitch gain for each subframe */ +/*-------------------------------------------------------------------*/ + +/* _ (Word16[]) shape1_filt_mem_dec : filter memory (Q0) */ +/* _ (Word16[]) shape2_filt_mem_dec : filter memory (Q0) */ +/* _ (Word16[]) shape3_filt_mem_dec : filter memory (Q0) */ +/* _ (Word16[]) bp1_filt_mem_wb_dec : filter memory (Q0) */ +/* _ (Word16[]) bp1_filt_mem_nb_dec : filter memory (Q0) */ +/*-------------------------------------------------------------------*/ +/* RETURN ARGUMENTS : */ +/* _ None */ +/*===================================================================*/ + +void nelp_decoder_fx( Decoder_State *st_fx, Word16 *exc_nelp, Word16 *exc, Word16 *Q_exc, Word16 bfi, const Word16 coder_type + , Word16 *gain_buf + ) +{ + Word16 i, fid = 0; + Word16 ptr[L_FRAME], filtRes[L_FRAME], gain_fac; /*ptr, filtRes - Q0, gain_fac - Q14 */ + Word16 Gains[10]; /* Q0 */ + Word32 Gain, E3, E2; + Word16 BP1_ORDER = 4; + Word16 ptr_tmp[L_FRAME]; /* Q0 */ + Word16 iG1, iG2[2]; + Word16 exp_E2, exp_E3, frac_E2, frac_E3; + Word16 tmp, scale, exp, frac; + Word32 L_tmp, L_tmp1; + Word32 exc_sqr[L_SUBFR]; + Word32 max_exc_sqr; + Word16 n; + Word16 max_val = 0, norm_val = 0; + Word16 qGain=0; + SC_VBR_DEC_HANDLE hSC_VBR; + + hSC_VBR = st_fx->hSC_VBR; + + if (EQ_16(st_fx->last_nelp_mode_dec_fx,1)&&NE_16(st_fx->bwidth,st_fx->last_bwidth)) + { + st_fx->last_nelp_mode_dec_fx = 0; + } + + test(); + test(); + test(); + IF ( EQ_16(coder_type,UNVOICED)&&EQ_16(st_fx->bwidth,NB)) + { + IF (NE_16(st_fx->last_nelp_mode_dec_fx,1)) + { + BP1_ORDER = 7; + move16(); + + set32_fx(hSC_VBR->bp1_filt_mem_nb_dec_fx, 0, BP1_ORDER*2); + } + } + ELSE IF ( EQ_16(coder_type,UNVOICED)&&(EQ_16(st_fx->bwidth,WB)||EQ_16(st_fx->bwidth,SWB))) + { + BP1_ORDER =4; + move16(); + IF (NE_16(st_fx->last_nelp_mode_dec_fx,1)) + { + set16_fx(hSC_VBR->bp1_filt_mem_wb_dec_fx, 0 , BP1_ORDER*2); + } + } + + IF (NE_16(st_fx->last_nelp_mode_dec_fx,1)) + { + set16_fx(hSC_VBR->shape1_filt_mem_dec_fx, 0, 10); + set16_fx(hSC_VBR->shape2_filt_mem_dec_fx, 0, 10); + set16_fx(hSC_VBR->shape3_filt_mem_dec_fx, 0, 10); + } + + IF (bfi == 0) + { + test(); + IF(EQ_16(st_fx->rf_frame_type,RF_NELP)&&EQ_16(st_fx->use_partial_copy,1)) + { + iG1 = st_fx->rf_indx_nelp_iG1; + iG2[0] = st_fx->rf_indx_nelp_iG2[0]; + iG2[1] = st_fx->rf_indx_nelp_iG2[1]; + } + ELSE + { + /* Do Unvoiced/NELP Decoding */ + iG1 =(Word16) get_next_indice( st_fx, 5 ); + move16(); + iG2[0] =(Word16) get_next_indice( st_fx, 6 ); + move16(); + iG2[1] =(Word16) get_next_indice( st_fx, 6 ); + move16(); + } + + test(); + test(); + IF ( EQ_16(coder_type,UNVOICED)&&(EQ_16(st_fx->bwidth,WB)||EQ_16(st_fx->bwidth,SWB))) + { + test(); + IF(EQ_16(st_fx->rf_frame_type,RF_NELP)&&EQ_16(st_fx->use_partial_copy,1)) + { + fid = st_fx->rf_indx_nelp_fid; + } + ELSE + { + fid = (Word16)get_next_indice( st_fx, 2 ); + move16(); + } + } + + *Q_exc = dequantize_uvg_fx(iG1, iG2, Gains, st_fx->bwidth ,1 ); + move16();/* Gains - Q0/Q3 */ + } + ELSE + { + FOR (i=1; i<=L_SUBFR; i++) + { + exc_sqr[i-1] = L_mult0(exc[-i],exc[-i]); + move32();/*2*Q_exc */ + } + max_exc_sqr = L_deposit_l(0); + FOR (i=0; ibwidth,WB)||EQ_16(st_fx->bwidth,SWB))) + { + gain_fac = 19005; + move16(); /* 1.16f - Q14 */ + } + + IF (EQ_16(st_fx->bwidth,WB)||EQ_16(st_fx->bwidth,SWB)) + { + /* Normalize Gains[10] with headroom 4, qGain is the new Q value os Gains, not Q0*/ + /* This is done to avoid internal overflow observed in the wb bp filter below, similar to encoder */ + normalize_arr(Gains, &qGain, 10, 4); + } + + generate_nelp_excitation_fx(&(hSC_VBR->nelp_dec_seed_fx), Gains, ptr, gain_fac); + /* o: ptr = nelp_exc in Q=qGain, qGain = 0 always for NB */ + + test(); + test(); + IF ( EQ_16(coder_type,UNVOICED )&&(EQ_16(st_fx->bwidth,WB)||EQ_16(st_fx->bwidth,SWB))) + { + BP1_ORDER =4; + move16(); + Scale_sig(hSC_VBR->bp1_filt_mem_wb_dec_fx, 2*BP1_ORDER, qGain); /* bring filter prev memory from Q0 to qGain */ + pz_filter_sp_fx(bp1_num_coef_wb_fx, bp1_den_coef_wb_fx, ptr, ptr_tmp, hSC_VBR->bp1_filt_mem_wb_dec_fx, + BP1_ORDER, BP1_ORDER, L_FRAME, (sub(16,BP1_COEF_WB_QF))); + + Scale_sig(hSC_VBR->bp1_filt_mem_wb_dec_fx, 2*BP1_ORDER, -qGain); /* bring filter prev memory from qGain to Q0 */ + Scale_sig(ptr_tmp, L_FRAME, -qGain); /* bring nelp_exc to Q0 */ + Copy(ptr_tmp,ptr,L_FRAME); + } + + test(); + IF ( EQ_16(coder_type,UNVOICED )&&(EQ_16(st_fx->bwidth,NB))) + { + BP1_ORDER = 7; + move16(); + + FOR (i=0; i < L_FRAME; i++ ) + { + max_val = s_max( ptr[i], max_val ); + } + tmp = shl(BP1_ORDER,1); + FOR (i=0; i < tmp; i++ ) + { + max_val = s_max( round_fx( L_shr(hSC_VBR->bp1_filt_mem_nb_dec_fx[i], 16)), max_val ); + } + norm_val = norm_s(max_val); + + norm_val = s_max (0, sub(norm_val, 4)); /* 4 bit head room */ + + norm_val = s_min ( norm_val,8); /* scale only for very low level signals */ + + IF ( norm_val > 0 ) + { + Scale_sig32(hSC_VBR->bp1_filt_mem_nb_dec_fx, shl(BP1_ORDER,1), norm_val) ; + Scale_sig(ptr, L_FRAME, norm_val); + *Q_exc = add( norm_val, *Q_exc ); + } + + BP1_ORDER = 7; + move16(); + pz_filter_dp_fx(bp1_num_coef_nb_fx_order7, bp1_den_coef_nb_fx_order7, ptr, ptr_tmp, hSC_VBR->bp1_filt_mem_nb_dec_fx, + BP1_ORDER, BP1_ORDER, L_FRAME, (sub(16,BP1_COEF_NB_QF_ORDER7))); + + + IF ( norm_val > 0 ) + { + Scale_sig32(hSC_VBR->bp1_filt_mem_nb_dec_fx, shl(BP1_ORDER,1), -norm_val) ; + + } + + Copy(ptr_tmp,ptr,L_FRAME); /*Q_exc */ + } + + E3 = L_deposit_l(1); + FOR (i=0 ; ibwidth,WB)||EQ_16(st_fx->bwidth,SWB))) + { + pz_filter_sp_fx(shape1_num_coef_fx, shape1_den_coef_fx, ptr, ptr_tmp, hSC_VBR->shape1_filt_mem_dec_fx, + 10, 10, L_FRAME, (sub(16,SHAPE1_COEF_QF))); + Copy(ptr_tmp,ptr,L_FRAME); /*Q_exc */ + + SWITCH(fid) + { + case 1: + /* Update other filter memory */ + pz_filter_sp_fx(shape3_num_coef_fx, shape3_den_coef_fx, ptr, filtRes, hSC_VBR->shape3_filt_mem_dec_fx, + 10, 10, L_FRAME, (sub(16,SHAPE3_COEF_QF))); + + /* filter the residual to desired shape */ + pz_filter_sp_fx(shape2_num_coef_fx, shape2_den_coef_fx, ptr, ptr_tmp, hSC_VBR->shape2_filt_mem_dec_fx, + 10, 10, L_FRAME, (sub(16,SHAPE2_COEF_QF))); + + Copy(ptr_tmp,ptr,L_FRAME); /*Q_exc */ + + BREAK; + case 2: + /* Update other filter memory */ + pz_filter_sp_fx(shape2_num_coef_fx, shape2_den_coef_fx, ptr, filtRes, hSC_VBR->shape2_filt_mem_dec_fx, + 10, 10, L_FRAME, (sub(16,SHAPE2_COEF_QF))); + + /* filter the residual to desired shape */ + pz_filter_sp_fx(shape3_num_coef_fx, shape3_den_coef_fx, ptr, ptr_tmp, hSC_VBR->shape3_filt_mem_dec_fx, + 10, 10, L_FRAME, (sub(16,SHAPE3_COEF_QF))); + + Copy(ptr_tmp,ptr,L_FRAME); /*Q_exc */ + + BREAK; + default: + /* Update other filter memory */ + pz_filter_sp_fx(shape2_num_coef_fx, shape2_den_coef_fx, ptr, filtRes, hSC_VBR->shape2_filt_mem_dec_fx, + 10, 10, L_FRAME, (sub(16,SHAPE2_COEF_QF))); + pz_filter_sp_fx(shape3_num_coef_fx, shape3_den_coef_fx, ptr, filtRes, hSC_VBR->shape3_filt_mem_dec_fx, + 10, 10, L_FRAME, (sub(16,SHAPE3_COEF_QF))); + + BREAK; + } + + E2 = L_deposit_l(1); + FOR (i=0 ; i +#include "options.h" /* Compilation switches */ +#include "prot_fx1.h" +#include "prot_fx2.h" +#include "rom_com.h" +#include "enh64.h" + + +#define PK_VQ_NOISE_DELTA ((Word16)3277) /* 0.1 in Q15 */ + +/*------------------------------------------------------------------------* + * Local function prototypes + *------------------------------------------------------------------------*/ +static void dequant_peaks_fx( Decoder_State *st_fx, Word32 *vect_out, const Word32 *peak_gain); +static Word16 hvq_dec_pos_fx(Decoder_State *st_fx, Word16 *pos_vec, const Word16 length, const Word16 num_peaks ); +static Word16 sparse_dec_pos_fx(Decoder_State *st_fx, Word16 *out, const Word16 length ); +static void peak_vq_dec_fx(Decoder_State* st_fx, Word32* coefs_out, const Word32 brate, const Word16 num_bits, const Word16* ynrm, + Word16* R, Word16* vq_peak_idx, Word16* Npeaks, const Word16 core); +/*-------------------------------------------------------------------------- + * hvq_dec_fx() + * + * HVQ decoder + *--------------------------------------------------------------------------*/ + +void hvq_dec_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + const Word16 num_bits, /* i : Number of available bits */ + const Word32 core_brate, /* i : Core bit-rate */ + const Word16 *ynrm, /* i : Envelope coefficients */ + Word16 *R, /* i/o: Bit allocation/updated bit allocation */ + Word16 *noise_level, /* o : Noise level in Q15 */ + Word16 *peak_idx, /* o : Peak position vector */ + Word16 *Npeaks, /* o : Total number of peaks */ + Word32 *coefsq_norm, /* o : Output vector in Q12 */ + const Word16 core /* i : Core */ +) +{ + Word16 i; + Word16 bits; + Word16 noise_level_idx; + + bits = num_bits; + + FOR( i = 0; i < HVQ_BWE_NOISE_BANDS; i++ ) + { + noise_level_idx = get_next_indice( st_fx, 2 ); /* 2-bits => max noise_level-idx = 3 */ + noise_level[i] = i_mult(noise_level_idx, PK_VQ_NOISE_DELTA); + move16();/* max noise_level=3*0.1 => Q15 is good enough */ + + bits = sub(bits, 2); + } + + peak_vq_dec_fx( st_fx, coefsq_norm, core_brate, bits, ynrm, R, peak_idx, + Npeaks, core ); +} + +/*-------------------------------------------------------------------------- + * peak_vq_dec() + * + * Vector de-quantization of MDCT peaks + *--------------------------------------------------------------------------*/ + +static void peak_vq_dec_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + Word32 *coefs_out, /* o : Output coefficient vector Q12 */ + const Word32 core_brate, /* i : Core bitrate */ + const Word16 num_bits, /* i : Number of bits for HVQ */ + const Word16 *ynrm, /* i : Envelope coefficients */ + Word16 *R, /* i/o: Bit allocation/updated bit allocation */ + Word16 *vq_peak_idx, /* o : Peak position vector */ + Word16 *Npeaks, /* o : Number of peaks */ + const Word16 core +) +{ + Word16 vq_peaks, i, j, k, FlagN, hcode_l, diff; + Word16 bin_th, bin_th2, max_peaks, pvq_bands; + Word16 nf_gains_idx[HVQ_NF_GROUPS], pgain_difidx[HVQ_MAX_PEAKS], pvq_norm[MAX_PVQ_BANDS]; + Word16 gain_bits_array[MAX_PVQ_BANDS]; + Word16 pos_bits; + Word32 nf_gains_fx[HVQ_NF_GROUPS], peak_gains_fx[HVQ_MAX_PEAKS]; + Word16 pvq_vector[HVQ_PVQ_BUF_LEN]; + Word16 res_vec[HVQ_THRES_BIN_32k]; + Word16 k_sort[HVQ_MAX_PVQ_WORDS]; + Word16 pvq_inp_vector[HVQ_PVQ_BUF_LEN], pvq_maxpulse[HVQ_MAX_PVQ_WORDS]; + Word16 npulses[MAX_PVQ_BANDS]; + Word16 pvq_bits, Rk[MAX_PVQ_BANDS]; + Word16 fg_pred[NB_SFM_MAX]; + + Word32 *pCoefsOut; + Word16 whiteNoise; + UWord16 dontCare; + Word32 acc; + Word16 *pPvqVector; + Word32 manE_peak, manPeakGains, manPkEnrg; /* Due to very wide dynamic range, use floating point format, i.e., (man, exp) */ + Word16 expE_peak, expPeakGains, expPkEnrg; + Word16 *pSelBnds; + Word16 sel_bnds[HVQ_NUM_SFM_24k]; + Word16 hvq_band_end[MAX_PVQ_BANDS]; + Word16 hvq_band_start[MAX_PVQ_BANDS]; + Word16 hvq_band_width[MAX_PVQ_BANDS]; + Word16 n_sel_bnds; + Word32 normq; + UWord32 lsb; + Word32 tmp; + Word16 nf_seed = RANDOM_INITSEED; + move16(); + + set16_fx( gain_bits_array, 0, MAX_PVQ_BANDS ); + set16_fx( pvq_vector, 0, HVQ_PVQ_BUF_LEN ); + set16_fx( npulses, 0, MAX_PVQ_BANDS ); + set16_fx( pvq_inp_vector, 0, HVQ_PVQ_BUF_LEN ); + + assert((core_brate > HQ_16k40 && core_brate <= HQ_48k) && "HVQ rate not supported"); + //PMT("max_peaks equation needs to be converted") + max_peaks = (Word16)((core_brate * HVQ_PEAKS_PER_DELTA + HVQ_PEAKS_PER_DELTA_OFFS) / HVQ_PEAKS_BPS_DELTA); + /*max_peaks = ((core_brate * HVQ_PEAKS_PER_DELTA / HVQ_PEAKS_BPS_DELTA + HVQ_PEAKS_PER_DELTA_OFFS / HVQ_PEAKS_BPS_DELTA) );*/ +#if 0 + { + #define INV_HVQ_PEAKS_BPS_DELTA_Q31 (Word32)((1.0f/HVQ_PEAKS_BPS_DELTA)*(1<<31)) + #define DELTAINV_HVQ_PEAKS_BPS_DELTA_Q31 (Word32)(((float)HVQ_PEAKS_PER_DELTA/HVQ_PEAKS_BPS_DELTA)*(1<<31)) + + max_peaks = W_round32_s(W_add(W_mult_32_32(HVQ_PEAKS_PER_DELTA_OFFS, INV_HVQ_PEAKS_BPS_DELTA_Q31), W_mult_32_32(core_brate, DELTAINV_HVQ_PEAKS_BPS_DELTA_Q31))); + printf("Fixed point code needed to be completed"); + } +#endif + bin_th = HVQ_THRES_BIN_24k; + bin_th2 = HVQ_THRES_BIN_24k/HVQ_NF_GROUPS; + IF (GE_32(core_brate, HQ_BWE_CROSSOVER_BRATE)) + { + bin_th = HVQ_THRES_BIN_32k; + bin_th2 = HVQ_THRES_BIN_32k/HVQ_NF_GROUPS; + move16(); + } + + /* Get number of peaks */ + vq_peaks = get_next_indice( st_fx, 5 ); + vq_peaks = sub(max_peaks, vq_peaks); + *Npeaks = vq_peaks; + move16(); + diff = 5; + move16(); + + /* safety check in case of bit errors */ + IF( LT_16(*Npeaks, HVQ_MIN_PEAKS)) + { + st_fx->BER_detect = 1; + move16(); + vq_peaks = HVQ_MIN_PEAKS; + move16(); + *Npeaks = HVQ_MIN_PEAKS; + move16(); + } + + /* De-quantize peak positions */ + FOR (i = 0; i < bin_th; i++) + { + res_vec[i] = 0; + move16(); + } + + /* Unpack PVQ codewords */ + pos_bits = hvq_dec_pos_fx(st_fx, res_vec, bin_th, vq_peaks); + diff = add(diff, pos_bits); + + j = 0; + move16(); + test(); + FOR (i = 0; i < bin_th && j < vq_peaks; i++) /* safety check in case of bit errors */ + { + IF ( res_vec[i] != 0) + { + vq_peak_idx[j++] = i; + move16(); + } + } + + /* safety check in case of bit errors */ + IF( LT_16(j, vq_peaks)) + { + st_fx->BER_detect = 1; + move16(); + vq_peaks = sub(j, 1); + *Npeaks = sub(j, 1); + } + + /* Huffman or differential coding */ + FlagN = (Word16) get_next_indice( st_fx, 1 ); + + /* De-quantize peak gains */ + pgain_difidx[0] = get_next_indice( st_fx, GAIN0_BITS ); + + /* safety check in case of bit errors */ + IF( GT_16(pgain_difidx[0], 44)) + { + st_fx->BER_detect = 1; + move16(); + pgain_difidx[0] = 44; + move16(); + } + peak_gains_fx[0] = dicn_pg_fx[pgain_difidx[0]]; /* Q12 */ move32(); + if (res_vec[vq_peak_idx[0]] < 0) + { + peak_gains_fx[0] = L_negate(peak_gains_fx[0]); + move16(); + } + + hcode_l = 0; + move16(); + IF (FlagN) + { + huff_dec_fx( st_fx, vq_peaks-1, MAX_PG_HUFFLEN, NUM_PG_HUFFLEN, hvq_pg_huff_thres, hvq_pg_huff_offset, hvq_pg_huff_tab, &pgain_difidx[1] ); + + FOR (i = 1; i < vq_peaks; i++) + { + hcode_l = add(hcode_l, pgain_huffsizn[pgain_difidx[i]]); + move16();/* indirect addressing*/ + } + } + ELSE + { + FOR (i = 1; i < vq_peaks; i++) + { + pgain_difidx[i] = get_next_indice(st_fx, GAINI_BITS ); + move16(); + hcode_l = add(hcode_l, GAINI_BITS); + } + } + + FOR (i = 1; i < vq_peaks; i++) + { + pgain_difidx[i] = add(pgain_difidx[i], sub(pgain_difidx[i - 1],15)); + move16(); + + /* safety check in case of bit errors */ + test(); + IF( GT_16(pgain_difidx[i], 44)||pgain_difidx[i]<0) + { + st_fx->BER_detect = 1; + move16(); + pgain_difidx[i] = 44; + move16(); + } + + peak_gains_fx[i] = dicn_pg_fx[pgain_difidx[i]]; + move32();/* Q12 move16(); */ + if (res_vec[vq_peak_idx[i]] < 0) + { + peak_gains_fx[i] = L_negate(peak_gains_fx[i]); + move32(); + } + } + + /* Scale up peak gains and accumulate peak energy */ + manE_peak = L_deposit_l(0); + expE_peak = 32; + move16(); + FOR (i = 0; i < vq_peaks; i++) + { + peak_gains_fx[i] = L_shl(peak_gains_fx[i], 2); + move32(); /* Q12 */ + /* Use floating point operation to deal with wide dynamic range. + * 32-bit mantissa is used here. It should be even more accurate than + * the floating-point reference code with 24-bit mantissa! */ + tmp = L_shl(dicn_pg_fx[pgain_difidx[i]], 2); + expPeakGains = norm_l(tmp); + manPeakGains = L_shl(tmp, expPeakGains); + Mpy_32_32_ss(manPeakGains, manPeakGains, &manPkEnrg, &lsb); /* peak_gains square */ + expPkEnrg = shl(expPeakGains, 1); /* Multiply by 2 due to squaring. */ + + floating_point_add(&manE_peak, &expE_peak, manPkEnrg, expPkEnrg); + } + /* Number of bits used for peak gain quantization */ + diff = add(diff, add(FLAGN_BITS + GAIN0_BITS, hcode_l)); + + /* De-quantize peaks */ + FOR (i = 0; i < vq_peaks; i++) + { + dequant_peaks_fx( st_fx, &coefs_out[vq_peak_idx[i]-2], &peak_gains_fx[i]); /* coefs_out in Q12, peak_gains_fx in Q14 */ + diff = add(diff, 9); + } + + FOR (i = 0; i < HVQ_NF_GROUPS; i++) + { + nf_gains_idx[i] = get_next_indice( st_fx, 5 ); + move16(); + nf_gains_fx[i] = L_shr(dicn_fx[nf_gains_idx[i]],1); + move32(); /* nf_gains in Q14 */ + diff = add(diff, 5); + } + pvq_bits = sub(num_bits, diff); + + /* Calculate number of PVQ bands to code and assign bits */ + pvq_bands = hvq_pvq_bitalloc_fx(pvq_bits, core_brate, st_fx->bwidth, ynrm, manE_peak, expE_peak, Rk, R, sel_bnds, + &n_sel_bnds); + + /* safety check in case of bit errors */ + test(); + if (pvq_bands == 0 && EQ_16(st_fx->element_mode, EVS_MONO)) /* PVQ bands may be zero for IVAS */ + { + st_fx->BER_detect = 1; + move16(); + } + + pvq_bits = sub(pvq_bits, i_mult2(HVQ_PVQ_GAIN_BITS, pvq_bands)); + /* Get band limits for concatenated PVQ target */ + hvq_concat_bands_fx(pvq_bands, sel_bnds, n_sel_bnds, hvq_band_start, + hvq_band_width, hvq_band_end); + + FOR (k = 0; k < pvq_bands; k++) + { + k_sort[k] = k; + move16(); + } + + pvq_decode_frame_fx(st_fx, pvq_vector, npulses, pvq_inp_vector, hvq_band_start, hvq_band_end, hvq_band_width, pvq_bands, Rk, pvq_bits, core ); + + + fine_gain_pred_fx( hvq_band_start, hvq_band_end, hvq_band_width, k_sort, npulses, pvq_maxpulse, NULL, + pvq_bands, pvq_vector, pvq_inp_vector, fg_pred, core ); + + fine_gain_dec_fx( st_fx, k_sort, pvq_bands, gain_bits_array, fg_pred); + + apply_gain_fx(k_sort, hvq_band_start, hvq_band_end, pvq_bands, fg_pred, pvq_vector); + + pPvqVector = pvq_vector; + pCoefsOut = coefs_out; + pSelBnds = sel_bnds; + move16(); + FOR (k = 0; k < pvq_bands; k++) + { + pvq_norm[k] = get_next_indice( st_fx, HVQ_PVQ_GAIN_BITS ); + pvq_norm[k] = add(pvq_norm[k], 8); + move16(); + + diff = add(diff, HVQ_PVQ_GAIN_BITS); + + j = 0; + move16(); + IF (GE_16(k, sub(pvq_bands, n_sel_bnds))) + { + i = band_start_harm[*pSelBnds++]; + move16(); + move16(); + pCoefsOut = coefs_out + i; + } + normq = L_add(dicn_fx[pvq_norm[k]], 0); + WHILE (LT_16(j, hvq_band_width[k])) + { + IF (EQ_32(*pCoefsOut, 0)) + { + Mpy_32_16_ss(normq, *pPvqVector++, &acc, &dontCare); /* acc(Q11), normq(Q14), pvq_vector(Q12) */ + *pCoefsOut = L_shl(acc, 12 - 11); /* Q12 */ move32(); + j = add(j, 1); + } + pCoefsOut++; + } + } + + /* Noise fill unqantized coeffs with one gain per group */ + pCoefsOut = &coefs_out[-1]; + FOR (i = 0; i < HVQ_NF_GROUPS; i++) + { + FOR (j = 0; j < bin_th2; j++) + { + IF (*(++pCoefsOut) == 0) + { + whiteNoise = Random(&nf_seed); /* Q15 */ + Mpy_32_16_ss(nf_gains_fx[i], whiteNoise, &acc, &dontCare); /* nf_gains_fx[] in Q14 */ + *pCoefsOut = L_shr(acc, 14-12); /* Q12 */ move32(); + } + } + } + + return; +} + +/*-------------------------------------------------------------------------- + * dequant_peaks() + * + * Reads codebook vector and scales peak + *--------------------------------------------------------------------------*/ + +static void dequant_peaks_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + Word32 *vect_out, /* o : Quantized vector in Q12 */ + const Word32 *peak_gain /* i : Peak gain in Q12 */ +) +{ + Word16 xq[4]; + const Word16 *tmp; + Word16 i, hvq_cb_rev; + Word16 cb_idx, indx; + Word32 absPeakGain1, absPeakGain; + UWord16 dontCare; + + hvq_cb_rev = get_next_indice( st_fx, 1 ); + cb_idx = get_next_indice( st_fx, 8 ); + + indx = shl(cb_idx,2); + IF ( hvq_cb_rev ) + { + indx = add(indx,3); + tmp = &hvq_peak_cb_fx[indx]; + FOR (i = 0; i < 4; i++) + { + xq[i] = *tmp--; /* Q15 */ move16(); + } + } + ELSE + { + tmp = &hvq_peak_cb_fx[indx]; + FOR (i = 0; i < 4; i++) + { + xq[i] = *tmp++; /* Q15 */ move16(); + } + } + + absPeakGain = L_abs(peak_gain[0]); + + IF(vect_out[0] == 0) + { + Mpy_32_16_ss(*peak_gain, xq[0], &vect_out[0], &dontCare); /* vect_out in Q12 */ + Mpy_32_16_ss(*peak_gain, xq[1], &vect_out[1], &dontCare); /* Q12 */ + } + ELSE + { + absPeakGain1 = L_abs(peak_gain[-1]); + IF(LE_32(absPeakGain1, absPeakGain)) + { + Mpy_32_16_ss(*peak_gain, xq[0], &vect_out[0], &dontCare); /* vect_out in Q12 */ + Mpy_32_16_ss(*peak_gain, xq[1], &vect_out[1], &dontCare); /* Q12 */ + } + ELSE + { + IF(vect_out[1] == 0 || (LE_32(absPeakGain1, absPeakGain))) + { + Mpy_32_16_ss(*peak_gain, xq[1], &vect_out[1], &dontCare); + } + } + } + vect_out[2] = *peak_gain; /* vect_out in Q12 */ + Mpy_32_16_ss(*peak_gain, xq[2], &vect_out[3], &dontCare); + Mpy_32_16_ss(*peak_gain, xq[3], &vect_out[4], &dontCare); + + return; +} + + +/*-------------------------------------------------------------------------- + * hvq_dec_pos() + * + * HVQ decode peak positions + *--------------------------------------------------------------------------*/ + +static Word16 hvq_dec_pos_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + Word16 *pos_vec, /* o : decoded peak positions */ + const Word16 length, /* i : length */ + const Word16 num_peaks /* i : number of peaks */ +) +{ + Word16 peak_idx[HVQ_MAX_PEAKS]; + Word16 delta[HVQ_MAX_PEAKS]; + Word16 sign_vec[HVQ_MAX_PEAKS]; + + Word16 mode; + Word16 num_bits, tmp; + Word16 i, j; + + num_bits = 0; + move16(); + set16_fx(pos_vec, 0, length); + + mode = get_next_indice(st_fx, 1); + num_bits = add(num_bits, 1); + + IF (mode == HVQ_CP_DELTA) + { + huff_dec_fx(st_fx, num_peaks, HVQ_CP_HUFF_MAX_CODE, HVQ_CP_HUFF_NUM_LEN, hvq_cp_huff_thres, hvq_cp_huff_offset, hvq_cp_huff_tab, delta); + + FOR (i = 0; i < num_peaks; i++) + { + num_bits = add(num_bits, hvq_cp_huff_len[delta[i]]); + } + + peak_idx[0] = sub(delta[0], HVQ_CP_HUFF_OFFSET); + /* safety check in case of bit errors */ + IF (peak_idx[0] < 2) + { + peak_idx[0] = 2; + move16(); + st_fx->BER_detect = 1; + move16(); + } + FOR (i = 1; i < num_peaks; i++) + { + peak_idx[i] = add(add(delta[i], peak_idx[i-1]), HVQ_CP_HUFF_OFFSET); + move16(); + /* safety check in case of bit errors */ + IF (GE_16(peak_idx[i], HVQ_THRES_BIN_32k)) + { + peak_idx[i] = HVQ_THRES_BIN_32k - 1; + move16(); + st_fx->BER_detect = 1; + move16(); + } + } + + FOR (i = 0; i < num_peaks; i++) + { + pos_vec[peak_idx[i]] = 1; + move16(); + } + } + ELSE + { + tmp = sparse_dec_pos_fx(st_fx, pos_vec, length); + num_bits = add(num_bits, tmp); + } + + FOR (i = 0; i < num_peaks; i++) + { + IF (get_next_indice_1(st_fx) == 0) + { + sign_vec[i] = -1; + move16(); + } + ELSE + { + sign_vec[i] = 1; + move16(); + } + } + num_bits = add(num_bits, num_peaks); + + j = 0; + move16(); + /* safety check in case of bit errors */ + test(); + FOR (i = 0; i < length && j < num_peaks; i++) + { + if (EQ_16(pos_vec[i], 1)) + { + pos_vec[i] = i_mult2(pos_vec[i], sign_vec[j++]); + move16(); + } + } + + return num_bits; +} + +/*-------------------------------------------------------------------------- + * sparse_dec_pos() + * + * Sparse decode positions + *--------------------------------------------------------------------------*/ + +static Word16 sparse_dec_pos_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + Word16* out, /* o : decoded peak positions */ + const Word16 length /* i : length */ +) +{ + Word16 layer2[HVQ_CP_L2_MAX]; + Word16 layer_length; + Word16 i, j, tmp; + Word16 bits; + Word16 idx, val; + + set16_fx(layer2, 0, HVQ_CP_L2_MAX); + set16_fx(out, 0, length); + bits = 0; + move16(); + + /*layer_length = (short)((float)length/HVQ_CP_L1_LEN + 0.5); */ + layer_length = round_fx(L_mult0(length, 13107)); /* 0+16-16, 13107 is 1/5 in Q16 */ + + FOR (i = 0; i < layer_length; i++) + { + layer2[i] = get_next_indice_1(st_fx); + move16(); + } + bits = add(bits, layer_length); + + FOR (j = 0; j < layer_length; j++) + { + IF (EQ_16(layer2[j], 1)) + { + idx = get_next_indice(st_fx, HVQ_CP_MAP_IDX_LEN); + bits = add(bits, HVQ_CP_MAP_IDX_LEN); + + val = hvq_cp_layer1_map5[idx]; + move16(); + test(); /* safety check in case of bit errors */ + IF ( j == 0 && GT_16(val, 4)) /* out[0] and out[1] are invalid positions */ + { + st_fx->BER_detect = 1; + move16(); + val = 4; + move16(); + } + tmp = i_mult2(j, HVQ_CP_L1_LEN); + FOR (i = sub(s_min(i_mult2(add(j,1), HVQ_CP_L1_LEN), length), 1); i >= tmp; i--) + { + out[i] = s_and(val, 1); + move16(); + val = lshr(val, 1); + } + } + } + + return bits; +} diff --git a/lib_dec/pit_dec.c b/lib_dec/pit_dec.c index 2f19d70795ad227e0b8060d4651abfd247a5d67d..6b9c067ba4c0ec4f939855d1706a19de274ee283 100644 --- a/lib_dec/pit_dec.c +++ b/lib_dec/pit_dec.c @@ -43,13 +43,13 @@ #include "wmc_auto.h" /*----------------------------------------------------------* - * pit_decode() + * pit_decode_flt() * * Decode OL pitch lag *----------------------------------------------------------*/ /*! r: floating pitch value */ -float pit_decode( +float pit_decode_flt( Decoder_State *st, /* i/o: decoder state structure */ const int32_t core_brate, /* i : core bitrate */ const int16_t Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ @@ -154,7 +154,7 @@ float pit_decode( st->BER_detect = 1; } - pit_Q_dec( 0, pitch_index, nBits, 4, pit_flag, *limit_flag, T0, T0_frac, T0_min, T0_max, &st->BER_detect ); + pit_Q_dec_flt( 0, pitch_index, nBits, 4, pit_flag, *limit_flag, T0, T0_frac, T0_min, T0_max, &st->BER_detect ); } else if ( coder_type == VOICED ) { @@ -168,7 +168,7 @@ float pit_decode( pit_flag = i_subfr; } - pit_Q_dec( 0, pitch_index, nBits, 4, pit_flag, *limit_flag, T0, T0_frac, T0_min, T0_max, &st->BER_detect ); + pit_Q_dec_flt( 0, pitch_index, nBits, 4, pit_flag, *limit_flag, T0, T0_frac, T0_min, T0_max, &st->BER_detect ); } else if ( st->idchan == 1 && ( tdm_Pitch_reuse_flag == 1 || nBits == 4 ) ) { @@ -195,7 +195,7 @@ float pit_decode( if ( nBits > 0 ) { - pit_Q_dec( 0, pitch_index, nBits, delta, pit_flag, *limit_flag, T0, T0_frac, T0_min, T0_max, &st->BER_detect ); + pit_Q_dec_flt( 0, pitch_index, nBits, delta, pit_flag, *limit_flag, T0, T0_frac, T0_min, T0_max, &st->BER_detect ); } else { @@ -212,11 +212,11 @@ float pit_decode( if ( L_frame == L_FRAME ) { - pit_Q_dec( 0, pitch_index, nBits, 8, pit_flag, *limit_flag, T0, T0_frac, T0_min, T0_max, &st->BER_detect ); + pit_Q_dec_flt( 0, pitch_index, nBits, 8, pit_flag, *limit_flag, T0, T0_frac, T0_min, T0_max, &st->BER_detect ); } else { - pit16k_Q_dec( pitch_index, nBits, *limit_flag, T0, T0_frac, T0_min, T0_max, &st->BER_detect ); + pit16k_Q_dec_flt( pitch_index, nBits, *limit_flag, T0, T0_frac, T0_min, T0_max, &st->BER_detect ); } } } @@ -250,7 +250,7 @@ float pit_decode( pitch_index = get_next_indice( st, nBits ); - pit_Q_dec( 1, pitch_index, nBits, 8, pit_flag, *limit_flag, T0, T0_frac, T0_min, T0_max, &st->BER_detect ); + pit_Q_dec_flt( 1, pitch_index, nBits, 8, pit_flag, *limit_flag, T0, T0_frac, T0_min, T0_max, &st->BER_detect ); } /*-------------------------------------------------------* @@ -264,12 +264,12 @@ float pit_decode( /*---------------------------------------------------------------------* - * abs_pit_dec() + * abs_pit_dec_flt() * * Decode the absolute pitch *---------------------------------------------------------------------*/ -void abs_pit_dec( +void abs_pit_dec_flt( const int16_t fr_steps, /* i : fractional resolution steps (0, 2, 4) */ int16_t pitch_index, /* i : pitch index */ const int16_t limit_flag, /* i : restrained(0) or extended(1) limits */ @@ -406,12 +406,12 @@ void abs_pit_dec( /*---------------------------------------------------------------------* - * delta_pit_dec() + * delta_pit_dec_flt() * * Decode delta pitch *---------------------------------------------------------------------*/ -void delta_pit_dec( +void delta_pit_dec_flt( const int16_t fr_steps, /* i : fractional resolution steps (0, 2, 4) */ const int16_t pitch_index, /* i : pitch index */ int16_t *T0, /* o : integer pitch lag */ @@ -441,12 +441,12 @@ void delta_pit_dec( /*-------------------------------------------------* - * pit_Q_dec() + * pit_Q_dec_flt() * * pitch decoding *-------------------------------------------------*/ -void pit_Q_dec( +void pit_Q_dec_flt( const int16_t Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ const int16_t pitch_index, /* i : pitch index */ const int16_t nBits, /* i : # of Q bits */ @@ -480,7 +480,7 @@ void pit_Q_dec( } else if ( nBits == 9 ) /* absolute decoding with 9 bits */ { - abs_pit_dec( 4, pitch_index, limit_flag, T0, T0_frac ); + abs_pit_dec_flt( 4, pitch_index, limit_flag, T0, T0_frac ); /* find T0_min and T0_max for delta search */ if ( Opt_AMR_WB ) @@ -490,7 +490,7 @@ void pit_Q_dec( } else if ( nBits == 8 ) /* absolute decoding with 8 bits */ { - abs_pit_dec( 2, pitch_index, limit_flag, T0, T0_frac ); + abs_pit_dec_flt( 2, pitch_index, limit_flag, T0, T0_frac ); /* find T0_min and T0_max for delta search */ if ( Opt_AMR_WB ) @@ -500,28 +500,28 @@ void pit_Q_dec( } else if ( nBits == 6 ) /* relative decoding with 6 bits */ { - delta_pit_dec( 4, pitch_index, T0, T0_frac, *T0_min ); + delta_pit_dec_flt( 4, pitch_index, T0, T0_frac, *T0_min ); } else if ( nBits == 5 ) /* relative decoding with 5 bits */ { if ( delta == 8 ) { - delta_pit_dec( 2, pitch_index, T0, T0_frac, *T0_min ); + delta_pit_dec_flt( 2, pitch_index, T0, T0_frac, *T0_min ); } else /* delta == 4 */ { - delta_pit_dec( 4, pitch_index, T0, T0_frac, *T0_min ); + delta_pit_dec_flt( 4, pitch_index, T0, T0_frac, *T0_min ); } } else /* nBits == 4 */ /* relative decoding with 4 bits */ { if ( delta == 8 ) { - delta_pit_dec( 0, pitch_index, T0, T0_frac, *T0_min ); + delta_pit_dec_flt( 0, pitch_index, T0, T0_frac, *T0_min ); } else /* delta == 4 */ { - delta_pit_dec( 2, pitch_index, T0, T0_frac, *T0_min ); + delta_pit_dec_flt( 2, pitch_index, T0, T0_frac, *T0_min ); } } @@ -543,12 +543,12 @@ void pit_Q_dec( } /*-------------------------------------------------* - * pit16k_Q_dec() + * pit16k_Q_dec_flt() * * pitch decoding @16kHz core *-------------------------------------------------*/ -void pit16k_Q_dec( +void pit16k_Q_dec_flt( const int16_t pitch_index, /* i : pitch index */ const int16_t nBits, /* i : # of Q bits */ const int16_t limit_flag, /* i : restrained(0) or extended(1) limits */ @@ -602,7 +602,7 @@ void pit16k_Q_dec( } else /* nBits == 6 */ /* relative decoding with 6 bits */ { - delta_pit_dec( 4, pitch_index, T0, T0_frac, *T0_min ); + delta_pit_dec_flt( 4, pitch_index, T0, T0_frac, *T0_min ); } /* biterror detection mechanism */ @@ -621,13 +621,13 @@ void pit16k_Q_dec( /*----------------------------------------------------------* - * Mode2_pit_decode() + * Mode2_pit_decode_flt() * * Decode pitch lag *----------------------------------------------------------*/ /*! r: floating pitch value */ -float Mode2_pit_decode( +float Mode2_pit_decode_flt( const int16_t coder_type, /* i : coding model */ const int16_t i_subfr, /* i : subframe index */ const int16_t L_subfr, /* i : sub-frame length */ @@ -659,13 +659,13 @@ float Mode2_pit_decode( { if ( i_subfr == 0 ) { - Mode2_abs_pit_dec( T0, T0_frac, T0_res, pt_indice, pit_min, pit_fr1b, pit_min, pit_res_max ); + Mode2_abs_pit_dec_flt( T0, T0_frac, T0_res, pt_indice, pit_min, pit_fr1b, pit_min, pit_res_max ); } else { - limit_T0_voiced( 4, pit_res_max >> 1, *T0, *T0_frac, *T0_res, T0_min, T0_min_frac, T0_max, T0_max_frac, pit_min, pit_max ); + limit_T0_voiced_ivas( 4, pit_res_max >> 1, *T0, *T0_frac, *T0_res, T0_min, T0_min_frac, T0_max, T0_max_frac, pit_min, pit_max ); *T0_res = ( pit_res_max >> 1 ); - Mode2_delta_pit_dec( T0, T0_frac, *T0_res, T0_min, T0_min_frac, pt_indice ); + Mode2_delta_pit_dec_flt( T0, T0_frac, *T0_res, T0_min, T0_min_frac, pt_indice ); } } else if ( coder_type == 2 ) /* 8/5/8/5 (EVS) */ @@ -673,13 +673,13 @@ float Mode2_pit_decode( if ( ( i_subfr == 0 ) || ( i_subfr == 2 * L_subfr ) ) { - Mode2_abs_pit_dec( T0, T0_frac, T0_res, pt_indice, pit_min, pit_fr1b, pit_min, pit_res_max ); + Mode2_abs_pit_dec_flt( T0, T0_frac, T0_res, pt_indice, pit_min, pit_fr1b, pit_min, pit_res_max ); } else { - limit_T0_voiced( 5, pit_res_max >> 1, *T0, *T0_frac, *T0_res, T0_min, T0_min_frac, T0_max, T0_max_frac, pit_min, pit_max ); + limit_T0_voiced_ivas( 5, pit_res_max >> 1, *T0, *T0_frac, *T0_res, T0_min, T0_min_frac, T0_max, T0_max_frac, pit_min, pit_max ); *T0_res = ( pit_res_max >> 1 ); - Mode2_delta_pit_dec( T0, T0_frac, *T0_res, T0_min, T0_min_frac, pt_indice ); + Mode2_delta_pit_dec_flt( T0, T0_frac, *T0_res, T0_min, T0_min_frac, pt_indice ); } } else if ( coder_type == 3 ) /* 9/6/6/6 (HRs- VC) */ @@ -692,13 +692,13 @@ float Mode2_pit_decode( if ( i_subfr == 0 ) { - Mode2_abs_pit_dec( T0, T0_frac, T0_res, pt_indice, pit_min, pit_fr1, pit_fr2, pit_res_max ); + Mode2_abs_pit_dec_flt( T0, T0_frac, T0_res, pt_indice, pit_min, pit_fr1, pit_fr2, pit_res_max ); } else { - limit_T0_voiced( 6, pit_res_max2, *T0, 0, 1, T0_min, T0_min_frac, T0_max, T0_max_frac, pit_min, pit_max ); + limit_T0_voiced_ivas( 6, pit_res_max2, *T0, 0, 1, T0_min, T0_min_frac, T0_max, T0_max_frac, pit_min, pit_max ); *T0_res = pit_res_max2; - Mode2_delta_pit_dec( T0, T0_frac, *T0_res, T0_min, T0_min_frac, pt_indice ); + Mode2_delta_pit_dec_flt( T0, T0_frac, *T0_res, T0_min, T0_min_frac, pt_indice ); } } else if ( coder_type == 4 ) /* 9/6/9/6 (AMRWB) */ @@ -711,39 +711,39 @@ float Mode2_pit_decode( if ( ( i_subfr == 0 ) || ( i_subfr == 2 * L_subfr ) ) { - Mode2_abs_pit_dec( T0, T0_frac, T0_res, pt_indice, pit_min, pit_fr1, pit_fr2, pit_res_max ); + Mode2_abs_pit_dec_flt( T0, T0_frac, T0_res, pt_indice, pit_min, pit_fr1, pit_fr2, pit_res_max ); } else { - limit_T0_voiced( 6, pit_res_max2, *T0, 0, 1, T0_min, T0_min_frac, T0_max, T0_max_frac, pit_min, pit_max ); + limit_T0_voiced_ivas( 6, pit_res_max2, *T0, 0, 1, T0_min, T0_min_frac, T0_max, T0_max_frac, pit_min, pit_max ); *T0_res = pit_res_max2; - Mode2_delta_pit_dec( T0, T0_frac, *T0_res, T0_min, T0_min_frac, pt_indice ); + Mode2_delta_pit_dec_flt( T0, T0_frac, *T0_res, T0_min, T0_min_frac, pt_indice ); } } else if ( coder_type == 8 ) /* 8/5/5/5 (RF all pred mode) */ { if ( i_subfr == 0 ) { - Mode2_abs_pit_dec( T0, T0_frac, T0_res, pt_indice, pit_min, pit_fr1b, pit_min, pit_res_max ); + Mode2_abs_pit_dec_flt( T0, T0_frac, T0_res, pt_indice, pit_min, pit_fr1b, pit_min, pit_res_max ); } else { - limit_T0_voiced( 5, pit_res_max >> 1, *T0, *T0_frac, *T0_res, T0_min, T0_min_frac, T0_max, T0_max_frac, pit_min, pit_max ); + limit_T0_voiced_ivas( 5, pit_res_max >> 1, *T0, *T0_frac, *T0_res, T0_min, T0_min_frac, T0_max, T0_max_frac, pit_min, pit_max ); *T0_res = ( pit_res_max >> 1 ); - Mode2_delta_pit_dec( T0, T0_frac, *T0_res, T0_min, T0_min_frac, pt_indice ); + Mode2_delta_pit_dec_flt( T0, T0_frac, *T0_res, T0_min, T0_min_frac, pt_indice ); } } else if ( coder_type == 9 ) /* 8/0/8/0 (RF gen pred mode) */ { if ( i_subfr == 0 ) { - Mode2_abs_pit_dec( T0, T0_frac, T0_res, pt_indice, pit_min, pit_fr1b, pit_min, pit_res_max ); + Mode2_abs_pit_dec_flt( T0, T0_frac, T0_res, pt_indice, pit_min, pit_fr1b, pit_min, pit_res_max ); } else { - limit_T0_voiced( 4, pit_res_max >> 1, *T0, *T0_frac, *T0_res, T0_min, T0_min_frac, T0_max, T0_max_frac, pit_min, pit_max ); + limit_T0_voiced_ivas( 4, pit_res_max >> 1, *T0, *T0_frac, *T0_res, T0_min, T0_min_frac, T0_max, T0_max_frac, pit_min, pit_max ); *T0_res = ( pit_res_max >> 1 ); - Mode2_delta_pit_dec( T0, T0_frac, *T0_res, T0_min, T0_min_frac, pt_indice ); + Mode2_delta_pit_dec_flt( T0, T0_frac, *T0_res, T0_min, T0_min_frac, pt_indice ); } } else /*RCELP 8 bits pitch delay*/ @@ -762,12 +762,12 @@ float Mode2_pit_decode( /*---------------------------------------------------------------------* - * Mode2_abs_pit_dec() + * Mode2_abs_pit_dec_flt() * * Decode the absolute pitch *---------------------------------------------------------------------*/ -void Mode2_abs_pit_dec( +void Mode2_abs_pit_dec_flt( int16_t *T0, /* o : integer pitch lag */ int16_t *T0_frac, /* o : pitch fraction */ int16_t *T0_res, /* o : pitch resolution */ @@ -812,12 +812,12 @@ void Mode2_abs_pit_dec( /*---------------------------------------------------------------------* - * Routine Mode2_delta_pit_dec() + * Routine Mode2_delta_pit_dec_flt() * * Decode delta pitch *---------------------------------------------------------------------*/ -void Mode2_delta_pit_dec( +void Mode2_delta_pit_dec_flt( int16_t *T0, /* o : integer pitch lag */ int16_t *T0_frac, /* o : pitch fraction */ int16_t T0_res, /* i : pitch resolution */ diff --git a/lib_dec/pit_dec_fx.c b/lib_dec/pit_dec_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..46056e716ccda54ceee578113792379e69be6cba --- /dev/null +++ b/lib_dec/pit_dec_fx.c @@ -0,0 +1,990 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include +#include +#include "options.h" +#include "cnst.h" +#include "prot_fx1.h" +#include "prot_fx2.h" +#include "rom_com.h" + +#define inv_T0_res InvIntTable + +/*----------------------------------------------------------* + * Mode2_pit_decode() + * + * Decode pitch lag + *----------------------------------------------------------*/ + +Word32 Mode2_pit_decode( /* o: floating pitch value */ + const Word16 coder_type, /* i: coding model */ + Word16 i_subfr, /* i: subframe index */ + Word16 L_subfr, + Word16 **pt_indice, /* i/o: quantization indices pointer */ + Word16 *T0, /* i/o: close loop integer pitch */ + Word16 *T0_frac, /* o: close loop fractional part of the pitch */ + Word16 *T0_res, /* i/o: pitch resolution */ + Word16 *T0_min, /* i/o: lower limit for close-loop search */ + Word16 *T0_min_frac, /* i/o: lower limit for close-loop search */ + Word16 *T0_max, /* i/o: higher limit for close-loop search */ + Word16 *T0_max_frac, /* i/o: higher limit for close-loop search */ + Word16 pit_min, + Word16 pit_fr1, + Word16 pit_fr1b, + Word16 pit_fr2, + Word16 pit_max, + Word16 pit_res_max +) +{ + Word32 pitch; + + IF(coder_type == 0) + { + *T0 = L_subfr; + move16(); + *T0_frac = 0; + move16(); + *T0_res = 1; + move16(); + } + ELSE IF(EQ_16(coder_type,1)) /* 8/4/4/4 (EVS) */ + { + IF (i_subfr == 0) + { + Mode2_abs_pit_dec( T0, T0_frac, T0_res, pt_indice, pit_min, pit_fr1b, pit_min, pit_res_max); + } + ELSE + { + limit_T0_voiced( 4, shr(pit_res_max,1), *T0, *T0_frac, *T0_res, T0_min, T0_min_frac, T0_max, T0_max_frac, pit_min, pit_max ); + *T0_res = shr(pit_res_max,1); + move16(); + Mode2_delta_pit_dec( T0, T0_frac, *T0_res, T0_min, T0_min_frac, pt_indice); + } + } + ELSE IF(EQ_16(coder_type,2)) /* 8/5/8/5 (EVS) */ + { + test(); + IF ( ( i_subfr == 0 ) || ( EQ_16(i_subfr,shl(L_subfr,1)))) + { + Mode2_abs_pit_dec( T0, T0_frac, T0_res, pt_indice, pit_min, pit_fr1b, pit_min, pit_res_max); + } + ELSE + { + limit_T0_voiced( 5, shr(pit_res_max,1), *T0, *T0_frac, *T0_res, T0_min, T0_min_frac, T0_max, T0_max_frac, pit_min, pit_max ); + *T0_res = shr(pit_res_max,1); + move16(); + Mode2_delta_pit_dec( T0, T0_frac, *T0_res, T0_min, T0_min_frac, pt_indice); + } + } + ELSE IF(EQ_16(coder_type,3)) /* 9/6/6/6 (HRs- VC) */ + { + Word16 pit_res_max2 = pit_res_max; + if ( EQ_16(pit_min,PIT_MIN_16k)) + { + pit_res_max2 = shr(pit_res_max,1); + } + + IF ( ( i_subfr == 0 ) ) + { + Mode2_abs_pit_dec( T0, T0_frac, T0_res, pt_indice, pit_min, pit_fr1, pit_fr2, pit_res_max); + } + ELSE + { + limit_T0_voiced( 6, pit_res_max2, *T0, 0, 1, T0_min, T0_min_frac, T0_max, T0_max_frac, pit_min, pit_max ); + *T0_res = pit_res_max2; + move16(); + Mode2_delta_pit_dec( T0, T0_frac, *T0_res, T0_min, T0_min_frac, pt_indice); + } + } + ELSE IF(EQ_16(coder_type,4)) /* 9/6/9/6 (AMRWB) */ + { + Word16 pit_res_max2 = pit_res_max; + if ( EQ_16(pit_min,PIT_MIN_16k)) + { + pit_res_max2 = shr(pit_res_max,1); + } + test(); + IF ( ( i_subfr == 0 ) || ( EQ_16(i_subfr,shl(L_subfr,1)))) + { + Mode2_abs_pit_dec( T0, T0_frac, T0_res, pt_indice, pit_min, pit_fr1, pit_fr2, pit_res_max); + } + ELSE + { + limit_T0_voiced( 6, pit_res_max2, *T0, 0, 1, T0_min, T0_min_frac, T0_max, T0_max_frac, pit_min, pit_max ); + *T0_res = pit_res_max2; + move16(); + Mode2_delta_pit_dec( T0, T0_frac, *T0_res, T0_min, T0_min_frac, pt_indice); + } + } + ELSE IF(EQ_16(coder_type,8)) /* 8/5/5/5 (RF all pred mode) */ + { + IF (i_subfr == 0) + { + Mode2_abs_pit_dec( T0, T0_frac, T0_res, pt_indice, pit_min, pit_fr1b, pit_min, pit_res_max); + } + ELSE + { + limit_T0_voiced( 5, shr(pit_res_max,1), *T0, *T0_frac, *T0_res, T0_min, T0_min_frac, T0_max, T0_max_frac, pit_min, pit_max ); + *T0_res = shr(pit_res_max,1); + Mode2_delta_pit_dec( T0, T0_frac, *T0_res, T0_min, T0_min_frac, pt_indice); + } + } + ELSE IF(EQ_16(coder_type,9)) /* 8/0/8/0 (RF gen pred mode) */ + { + IF (i_subfr == 0) + { + Mode2_abs_pit_dec( T0, T0_frac, T0_res, pt_indice, pit_min, pit_fr1b, pit_min, pit_res_max); + } + ELSE + { + limit_T0_voiced( 4, shr(pit_res_max,1), *T0, *T0_frac, *T0_res, T0_min, T0_min_frac, T0_max, T0_max_frac, pit_min, pit_max ); + *T0_res = shr(pit_res_max,1); + Mode2_delta_pit_dec( T0, T0_frac, *T0_res, T0_min, T0_min_frac, pt_indice); + } + } + ELSE + { + assert(0 && "LTP mode not supported"); + } + + /*-------------------------------------------------------* + * Compute floating pitch output + *-------------------------------------------------------*/ + assert(*T0_res > 0 || *T0_res <= 6); + + /*pitch = (float)(*T0) + (float)(*T0_frac)/(float)(*T0_res);*/ /* save subframe pitch values */ + pitch = L_mac(L_deposit_h(*T0), *T0_frac,inv_T0_res[*T0_res]); + + + return pitch; +} + + + +/*---------------------------------------------------------------------* + * Mode2_abs_pit_dec() + * + * Decode the absolute pitch + *---------------------------------------------------------------------*/ + +void Mode2_abs_pit_dec( + Word16 *T0, /* o: integer pitch lag */ + Word16 *T0_frac, /* o: pitch fraction */ + Word16 *T0_res, /* o: pitch resolution */ + Word16 **pt_indice, /* i/o: pointer to Vector of Q indexes */ + Word16 pit_min, + Word16 pit_fr1, + Word16 pit_fr2, + Word16 pit_res_max +) +{ + Word16 index; + Word16 pit_res_max_half, tmp1, tmp2, res; + + index = **pt_indice; + move16(); + (*pt_indice)++; + pit_res_max_half = shr(pit_res_max,1); + + tmp1 = i_mult(sub(pit_fr2,pit_min),pit_res_max); + tmp2 = i_mult(sub(pit_fr1,pit_fr2),pit_res_max_half); + IF (LT_16(index,tmp1)) + { + assert(pit_res_max > 1 && pit_res_max<=6); + + res = pit_res_max; + move16(); + if(EQ_16(pit_res_max,6)) + { + res =shr(res,1); + } + + *T0 = mult(index,inv_T0_res[res]); + if(EQ_16(pit_res_max,6)) + { + *T0 =shr(*T0,1); + } + + *T0 = add(pit_min,*T0); + move16(); + + *T0_frac = sub(index,i_mult(sub(*T0,pit_min),pit_res_max)); + move16(); + *T0_res = pit_res_max; + move16(); + } + ELSE IF (index < add(tmp1,tmp2) ) + { + assert(pit_res_max > 1); + + index = sub(index,tmp1); + *T0 = add(pit_fr2,mult(index,inv_T0_res[pit_res_max_half])); + move16(); + *T0_frac = sub(index, i_mult(sub(*T0,pit_fr2),pit_res_max_half)); + move16(); + *T0_res = pit_res_max_half; + move16(); + } + ELSE + { + *T0 = add(index,sub(pit_fr1,add(tmp1,tmp2))); + move16(); + *T0_frac = 0; + move16(); + *T0_res = 1; + move16(); + } + + return; +} + + +/*---------------------------------------------------------------------* + * Routine Mode2_delta_pit_dec() + * + * Decode delta pitch + *---------------------------------------------------------------------*/ +void Mode2_delta_pit_dec( + Word16 *T0, /* o: integer pitch lag */ + Word16 *T0_frac, /* o: pitch fraction */ + Word16 T0_res, /* i: pitch resolution */ + Word16 *T0_min, /* i/o: delta search min */ + Word16 *T0_min_frac, /* i: delta search min */ + Word16 **pt_indice /* i/o: pointer to Vector of Q indexes */ +) +{ + Word16 index, res; + + assert(T0_res > 1 && T0_res<=6); + + res = T0_res; + move16(); + if(EQ_16(T0_res,6)) + { + res =shr(res,1); + } + + index = **pt_indice; + move16(); + (*pt_indice)++; + + + *T0 = mult(add(index,*T0_min_frac),inv_T0_res[res]); + if(EQ_16(T0_res,6)) + { + *T0 =shr(*T0,1); + } + + *T0 = add(*T0_min,*T0); + move16(); + + *T0_frac = add(index, sub(*T0_min_frac, i_mult(sub(*T0,*T0_min),T0_res))); + + return; +} + + +/*======================================================================*/ +/* FUNCTION : pit_decode_fx() */ +/*-----------------------------------------------------------------------*/ +/* PURPOSE : calculate pitch value */ +/* */ +/*-----------------------------------------------------------------------*/ +/* INPUT ARGUMENTS : */ +/* _ (Word32) core_brate : Core bitrate Q0 */ +/* _ (Word16) Opt_AMR_WB : flag indicating AMR-WB IO mode Q0 */ +/* _ (Word16) L_frame : length of the frame Q0 */ +/* _ (Word16) i_subfr : length of the frame Q0 */ +/* _ (Word16) coder_type : coding type Q0 */ +/* _ (Word16) L_subfr : subframe length */ +/*-----------------------------------------------------------------------*/ +/* OUTPUT ARGUMENTS : */ +/* _ (Word16 *) T0 : close loop integer pitch */ +/* _ (Word16 *) T0_frac : close loop fractional part of the pitch */ +/* _ (Word16 ) pitch : pitch value Q6 */ +/*-----------------------------------------------------------------------*/ +/* INPUT OUTPUT ARGUMENTS */ +/* _ (Word16 *) T0_min : delta search min for sf 2 & 4 */ +/* _ (Word16 *) T0_max : delta search max for sf 2 & 4 */ +/*-----------------------------------------------------------------------*/ +/* RETURN ARGUMENTS : */ +/* _ (Word16 ) pitch : close loop integer pitch Q6 */ +/*=======================================================================*/ + + +Word16 pit_decode_fx( /* o : floating pitch value */ + Decoder_State *st_fx, /* i/o: decoder state structure */ + const Word32 core_brate, /* i : core bitrate */ + const Word16 Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ + const Word16 L_frame, /* i : length of the frame */ + Word16 i_subfr, /* i : subframe index */ + const Word16 coder_type, /* i : coding type */ + Word16 *limit_flag, /* i/o: restrained(0) or extended(1) Q limits */ + Word16 *T0, /* o : close loop integer pitch */ + Word16 *T0_frac, /* o : close loop fractional part of the pitch */ + Word16 *T0_min, /* i/o: delta search min for sf 2 & 4 */ + Word16 *T0_max, /* i/o: delta search max for sf 2 & 4 */ + const Word16 L_subfr /* i : subframe length */ +#ifdef ADD_LRTD + , const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ + const Word16 tdm_Pri_pitch_buf[] /* i : primary channel pitch buffer */ +#endif +) +{ + Word16 pitch; /*Q2*/ + Word16 pitch_index, nBits, pit_flag; + + pitch_index = 0; + + /*----------------------------------------------------------------* + * Set pit_flag = 0 for every subframe with absolute pitch search + *----------------------------------------------------------------*/ + pit_flag = i_subfr; + move16(); + + if (EQ_16(i_subfr,PIT_DECODE_2XL_SUBFR)) + { + pit_flag = 0; + move16(); + } + + /*-------------------------------------------------------* + * Retrieve the pitch index + *-------------------------------------------------------*/ + IF( !Opt_AMR_WB ) + { + /*----------------------------------------------------------------* + * pitch Q: Set limit_flag to 0 for restrained limits, and 1 for extended limits + *----------------------------------------------------------------*/ + test(); + test(); + IF( i_subfr == 0 ) + { + *limit_flag = 1; + move16(); + + if( EQ_16(coder_type,VOICED)) + { + *limit_flag = 2; + move16(); /* double-extended limits */ + } + test(); + if( EQ_16(coder_type,GENERIC )&&EQ_32(core_brate,ACELP_7k20)) + { + *limit_flag = 0; + move16(); + } + } + ELSE IF( EQ_16(i_subfr,2*L_SUBFR)&&EQ_32(coder_type,GENERIC)&&LE_32(core_brate,ACELP_13k20)) + { + if( GT_16(*T0,shr(add(PIT_FR1_EXTEND_8b, PIT_MIN),1) )) + { + *limit_flag = 0; + move16(); + } + } + + /*-------------------------------------------------------* + * Retrieve the number of Q bits + *-------------------------------------------------------*/ + + nBits = 0; + move16(); + IF( NE_16(coder_type, AUDIO)) + { + /* find the number of bits */ + nBits = st_fx->acelp_cfg.pitch_bits[shr(i_subfr,6)]; + move16(); + pitch_index = (Word16)get_next_indice( st_fx, nBits ); + move16(); + } + + /*-------------------------------------------------------* + * Pitch decoding in AUDIO mode + * (both ACELP@12k8 and ACELP@16k cores) + *-------------------------------------------------------*/ + IF( EQ_16(coder_type, AUDIO)) + { + test(); + if( EQ_16(L_subfr,L_FRAME/2)&&i_subfr!=0) + { + pit_flag = L_SUBFR; + move16(); + } + if( pit_flag == 0 ) + { + nBits = 10; + move16(); + } + if( pit_flag != 0 ) + { + nBits = 6; + move16(); + } + + pitch_index = (Word16)get_next_indice( st_fx, nBits ); + move16(); + + test(); + test(); + IF( EQ_16(L_subfr,L_FRAME/2)&&i_subfr!=0&&GE_16(pitch_index,32)) /* safety check in case of bit errors */ + { + pitch_index = shr(pitch_index,1); + move16(); + st_fx->BER_detect = 1; + move16(); + } + + pit_Q_dec_fx( 0, pitch_index, nBits, 4, pit_flag, *limit_flag, T0, T0_frac, T0_min, T0_max, &st_fx->BER_detect ); + } + ELSE IF( EQ_16(coder_type,VOICED)) + { + /*-------------------------------------------------------* + * Pitch decoding in VOICED mode + * (ACELP@12k8 core only) + *-------------------------------------------------------*/ + if( EQ_16(i_subfr,2*L_SUBFR)) + { + pit_flag = i_subfr; + move16(); + } + + pit_Q_dec_fx( 0, pitch_index, nBits, 4, pit_flag, *limit_flag, T0, T0_frac, T0_min, T0_max, &st_fx->BER_detect ); + } +#ifdef ADD_LRTD + ELSE IF ( EQ_16(st_fx->idchan, 1) && (EQ_16(tdm_Pitch_reuse_flag, 1) || EQ_16(nBits,4) ) ) + { + test(); test(); + /*-------------------------------------------------------* + * Pitch decoding with reusing of primary channel information + *-------------------------------------------------------*/ + Word16 loc_T0, loc_frac, delta, pit_tmp1, pit_tmp2, isubfridx; + + delta = 4; + pit_flag = L_SUBFR; + move16(); move16(); + isubfridx = shr(i_subfr, 6); + IF ( EQ_16(L_subfr, 2 * L_SUBFR ) ) + { + move16(); move16(); + pit_tmp1 = tdm_Pri_pitch_buf[isubfridx]; /*tdm_Pri_pitch_buf in Q6 ->pit_tmp1 and 2 in Q6 too */ + pit_tmp2 = tdm_Pri_pitch_buf[shr(add(i_subfr, 1), 6)]; + /*loc_T0 = (int16_t)(0.5f * tdm_Pri_pitch_buf[i_subfr / L_SUBFR] + 0.5f * tdm_Pri_pitch_buf[(i_subfr + L_SUBFR) / L_SUBFR]);*/ + loc_T0 = mac_r( L_mult(16384, pit_tmp1, 16384, pit_tmp2) ); + /*loc_frac = (int16_t)(((0.5f * tdm_Pri_pitch_buf[i_subfr / L_SUBFR] + 0.5f * tdm_Pri_pitch_buf[(i_subfr + L_SUBFR) / L_SUBFR]) - loc_T0) * 4.0f);*/ + } + ELSE + { + /*loc_T0 = (int16_t)tdm_Pri_pitch_buf[i_subfr / L_SUBFR];*/ + loc_T0 = tdm_Pri_pitch_buf[isubfridx]; /*Q6*/ + /*loc_frac = (int16_t)((tdm_Pri_pitch_buf[i_subfr / L_SUBFR] - loc_T0) * 4.0f);*/ + } + loc_frac = shr(sub(loc_T0, shl(shr(loc_T0, 6), 6)), 4)); /* Final result in Q 2*/ + loc_T0 = shr (loc_T0, 6); /*Q6 -> Q0*/ + + + limit_T0_fx(L_FRAME, delta, pit_flag, *limit_flag, loc_T0, loc_frac, T0_min, T0_max); + + IF (nBits > 0) + { + pit_Q_dec_fx(0, pitch_index, nBits, delta, pit_flag, *limit_flag, T0, T0_frac, T0_min, T0_max, &st_fx->BER_detect); + } + ELSE + { + *T0 = loc_T0; + *T0_frac = loc_frac; + move16(); + move16(); + } +printf("function not tested yet\n"); + } +#endif + ELSE + { + /*-------------------------------------------------------* + * Pitch decoding in GENERIC mode + * (both ACELP@12k8 and ACELP@16k cores) + *-------------------------------------------------------*/ + IF( EQ_16(L_frame,L_FRAME)) + { + pit_Q_dec_fx( 0, pitch_index, nBits, 8, pit_flag, *limit_flag, T0, T0_frac, T0_min, T0_max, &st_fx->BER_detect ); + } + ELSE + { + pit16k_Q_dec_fx( pitch_index, nBits, *limit_flag, T0, T0_frac, T0_min, T0_max, &st_fx->BER_detect ); + } + } + } + + /*-------------------------------------------------------* + * Pitch decoding in AMR-WB IO mode + *-------------------------------------------------------*/ + + ELSE + { + *limit_flag = 0; + move16(); + test(); + test(); + IF( i_subfr == 0 || ( EQ_16(i_subfr, 2*L_SUBFR)&&EQ_32(core_brate,ACELP_8k85))) + { + nBits = 8; + move16(); + } + ELSE + { + nBits = 5; + move16(); + } + IF( GT_32(core_brate, ACELP_8k85)) + { + nBits = 6; + move16(); + test(); + if( i_subfr == 0 || EQ_16(i_subfr, 2*L_SUBFR)) + { + nBits = 9; + move16(); + } + } + + pitch_index = (Word16)get_next_indice( st_fx, nBits ); + + pit_Q_dec_fx( 1, pitch_index, nBits, 8, pit_flag, *limit_flag, T0, T0_frac, T0_min, T0_max, &st_fx->BER_detect ); + } + + /*-------------------------------------------------------* + * Compute floating pitch output + *-------------------------------------------------------*/ + + pitch = shl(add(shl(*T0,2),*T0_frac),4); /* save subframe pitch values Q6 */ + + return pitch; +} + + +/*----------------------------------------------------------* + * pit_Q_dec_fx() + * + * Decode pitch lag + *----------------------------------------------------------*/ + +void pit_Q_dec_fx( + const Word16 Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ + const Word16 pitch_index, /* i : pitch index */ + const Word16 nBits, /* i : # of Q bits */ + const Word16 delta, /* i : Half the CL searched interval */ + const Word16 pit_flag, /* i : absolute(0) or delta(1) pitch Q */ + const Word16 limit_flag, /* i : restrained(0) or extended(1) Q limits */ + Word16 *T0, /* o : integer pitch lag */ + Word16 *T0_frac, /* o : pitch fraction */ + Word16 *T0_min, /* i/o: delta search min */ + Word16 *T0_max /* i/o: delta search max */ + ,Word16 *BER_detect /* o : BER detect flag */ +) +{ + IF( EQ_16(nBits, 10)) /* absolute decoding with 10 bits */ + { + IF( limit_flag == 0 ) + { + *T0 = add(PIT_MIN,shr(pitch_index,2)); + *T0_frac = sub(pitch_index,shl(sub(*T0,PIT_MIN),2)); + } + ELSE IF( EQ_16(limit_flag,1)) + { + *T0 = add(PIT_MIN_EXTEND,shr(pitch_index,2)); + *T0_frac = sub(pitch_index ,shl(sub(*T0,PIT_MIN_EXTEND),2)); + } + ELSE /* limit_flag == 2 */ + { + *T0 = add(PIT_MIN_DOUBLEEXTEND,shr(pitch_index,2)); + *T0_frac = sub(pitch_index ,shl(sub(*T0,PIT_MIN_DOUBLEEXTEND),2)); + } + } + ELSE IF( EQ_16(nBits, 9)) /* absolute decoding with 9 bits */ + { + abs_pit_dec_fx( 4, pitch_index, limit_flag, T0, T0_frac ); + + /* find T0_min and T0_max for delta search */ + IF( Opt_AMR_WB ) + { + limit_T0_fx( L_FRAME, delta, pit_flag, 0, *T0, 0, T0_min, T0_max ); /* T0_frac==0 to keep IO with AMR-WB */ + } + } + ELSE IF( EQ_16(nBits, 8)) /* absolute decoding with 8 bits */ + { + abs_pit_dec_fx( 2, pitch_index, limit_flag, T0, T0_frac ); + + /* find T0_min and T0_max for delta search */ + IF( Opt_AMR_WB ) + { + limit_T0_fx( L_FRAME, delta, pit_flag, 0, *T0, 0, T0_min, T0_max ); /* T0_frac==0 to keep IO with AMR-WB */ + } + } + ELSE IF( EQ_16(nBits, 6)) /* relative decoding with 6 bits */ + { + delta_pit_dec_fx( 4, pitch_index, T0, T0_frac, *T0_min ); + } + ELSE IF( EQ_16(nBits, 5)) /* relative decoding with 5 bits */ + { + IF( EQ_16(delta,8)) + { + delta_pit_dec_fx( 2, pitch_index, T0, T0_frac, *T0_min ); + } + ELSE /* delta == 4 */ + { + delta_pit_dec_fx( 4, pitch_index, T0, T0_frac, *T0_min ); + } + } + ELSE /* nBits == 4 */ /* relative decoding with 4 bits */ + { + IF( EQ_16(delta,8)) + { + delta_pit_dec_fx( 0, pitch_index, T0, T0_frac, *T0_min ); + } + ELSE /* delta == 4 */ + { + delta_pit_dec_fx( 2, pitch_index, T0, T0_frac, *T0_min ); + } + } + + /* biterror detection mechanism */ + test(); + test(); + IF( GT_16(add((*T0<<2),*T0_frac),add((PIT_MAX<<2),2))&&pit_flag==0&&!Opt_AMR_WB) + { + *T0 = L_SUBFR; + move16(); + *T0_frac = 0; + move16(); + *BER_detect = 1; + move16(); + } + + IF( !Opt_AMR_WB ) + { + /* find T0_min and T0_max for delta search */ + limit_T0_fx( L_FRAME, delta, L_SUBFR, limit_flag, *T0, *T0_frac, T0_min, T0_max ); + } + + return; +} + +/*-------------------------------------------------* + * pit16k_Q_dec() + * + * pitch decoding @16kHz core + *-------------------------------------------------*/ + +void pit16k_Q_dec_fx( + const Word16 pitch_index, /* i : pitch index */ + const Word16 nBits, /* i : # of Q bits */ + const Word16 limit_flag, /* i : restrained(0) or extended(1) limits */ + Word16 *T0, /* o : integer pitch lag */ + Word16 *T0_frac, /* o : pitch fraction */ + Word16 *T0_min, /* i/o: delta search min */ + Word16 *T0_max /* i/o: delta search max */ + ,Word16 *BER_detect /* o : BER detect flag */ +) +{ + Word16 index; + + IF( EQ_16(nBits,10)) /* absolute decoding with 10 bits */ + { + { + IF( LT_16(pitch_index,shl((PIT16k_FR2_EXTEND_10b-PIT16k_MIN_EXTEND),2))) + { + *T0 = add(PIT16k_MIN_EXTEND, shr(pitch_index,2)); + move16(); + *T0_frac = sub(pitch_index, shl(sub(*T0, PIT16k_MIN_EXTEND),2)); + move16(); + } + ELSE + { + index = sub(pitch_index, shl((PIT16k_FR2_EXTEND_10b-PIT16k_MIN_EXTEND),2)); + *T0 = add(PIT16k_FR2_EXTEND_10b, shr(index,1)); + *T0_frac = sub(index, shl(sub(*T0, PIT16k_FR2_EXTEND_10b),1)); + /*(*T0_frac) *= 2;*/ + (*T0_frac) = shl(*T0_frac,1); + + } + } + + } + ELSE IF ( EQ_16(nBits,9)) /* absolute decoding with 9 bits */ + { + { + IF (LT_16(pitch_index,(PIT16k_FR2_EXTEND_9b-PIT16k_MIN_EXTEND)*4)) + { + *T0 = add(PIT16k_MIN_EXTEND, shr(pitch_index,2)); + move16(); + *T0_frac = sub(pitch_index, shl(sub(*T0, PIT16k_MIN_EXTEND),2)); + move16(); + } + ELSE IF (LT_16(pitch_index,( (PIT16k_FR2_EXTEND_9b-PIT16k_MIN_EXTEND)*4 + (PIT16k_FR1_EXTEND_9b-PIT16k_FR2_EXTEND_9b)*2))) + { + index = sub(pitch_index, (PIT16k_FR2_EXTEND_9b-PIT16k_MIN_EXTEND)*4); + *T0 = add(PIT16k_FR2_EXTEND_9b, shr(index,1)); + move16(); + *T0_frac = sub(index, shl(sub(*T0, PIT16k_FR2_EXTEND_9b),1)); + move16(); + (*T0_frac) *= shl((*T0_frac),1); + } + ELSE + { + *T0 = add(pitch_index, PIT16k_FR1_EXTEND_9b - ((PIT16k_FR2_EXTEND_9b-PIT16k_MIN_EXTEND)*4) - ((PIT16k_FR1_EXTEND_9b-PIT16k_FR2_EXTEND_9b)*2)); + move16(); + *T0_frac = 0; + move16(); + } + } + } + ELSE /* nBits == 6 */ /* relative decoding with 6 bits */ + { + delta_pit_dec_fx( 4, pitch_index, T0, T0_frac, *T0_min ); + } + + /* biterror detection mechanism */ + test(); + IF( GT_16(add((*T0<<2),*T0_frac),(PIT16k_MAX<<2))&&GE_16(nBits,9)) + { + *T0 = L_SUBFR; + move16(); + *T0_frac = 0; + move16(); + *BER_detect = 1; + move16(); + } + + /* find T0_min and T0_max for delta search */ + limit_T0_fx( L_FRAME16k, 8, L_SUBFR, limit_flag, *T0, *T0_frac, T0_min, T0_max ); + + return; +} + +/*----------------------------------------------------------* + * abs_pit_dec_fx() + * + * Absolute pitch decoding + *----------------------------------------------------------*/ + +void abs_pit_dec_fx( + const Word16 fr_steps, /* i: fractional resolution steps (0, 2, 4) */ + Word16 pitch_index, /* i: pitch index */ + const Word16 limit_flag, /* i : restrained(0) or extended(1) limits */ + Word16 *T0, /* o: integer pitch lag */ + Word16 *T0_frac /* o: pitch fraction */ +) +{ + Word16 temp; + + IF( limit_flag == 0 ) + { + IF(EQ_16(fr_steps,2)) + { + IF(LT_16(pitch_index,PIT_FR1_8b_MINUS_PIT_MIN_X2)) + { + *T0= add(PIT_MIN,shr(pitch_index,1)); + move16(); + temp = shl(sub(*T0,PIT_MIN),1); + *T0_frac = shl(sub(pitch_index,temp),1); + move16(); + } + ELSE + { + *T0 = add(pitch_index,PIT_FR1_8b_MINUS_PIT_FR1_8b_MINUS_PIT_MIN_X2); + move16(); + *T0_frac = 0; + move16(); + } + } + ELSE IF( EQ_16(fr_steps,4)) + { + IF(LT_16(pitch_index,PIT_FR2_9b_MINUS_PIT_MIN_X4)) + { + *T0= add(PIT_MIN,shr(pitch_index,2)); + move16(); + temp = shl(sub(*T0,PIT_MIN),2); + *T0_frac = sub(pitch_index,temp); + move16(); + } + ELSE IF (LT_16(pitch_index,PIT_DECODE_1)) /*( (PIT_FR2_9b-PIT_MIN)*4 + (PIT_FR1_9b-PIT_FR2_9b)*2) = 440*/ + { + pitch_index = sub(pitch_index,PIT_DECODE_2); /*pitch_index -= (PIT_FR2_9b-PIT_MIN)*4(=376);*/ + *T0 = add(PIT_FR2_9b,shr(pitch_index,1)); + move16(); + temp = shl(sub(*T0,PIT_FR2_9b),1); + *T0_frac = shl(sub(pitch_index,temp),1); + move16(); + } + ELSE + { + *T0 = add(pitch_index,PIT_DECODE_3); + move16(); + *T0_frac = 0; + move16(); + } + } + ELSE /* fr_steps == 0 */ + { + /* not used in the codec */ + } + } + ELSE IF( EQ_16(limit_flag, 1)) /* extended Q range */ + { + IF( EQ_16(fr_steps,2)) + { + IF( LT_16(pitch_index, PIT_FR1_EXT8b_MINUS_PIT_MIN_EXT_X2)) + { + *T0 = add(PIT_MIN_EXTEND, shr(pitch_index,1)); + move16(); + *T0_frac = sub(pitch_index, shl(sub(*T0, PIT_MIN_EXTEND),1)); + *T0_frac = shl(*T0_frac, 1); + move16(); + } + ELSE + { + *T0 = add(pitch_index, sub(PIT_FR1_EXTEND_8b, PIT_FR1_EXT8b_MINUS_PIT_MIN_EXT_X2)); + move16(); + *T0_frac = 0; + move16(); + } + } + ELSE IF( EQ_16(fr_steps,4)) + { + IF( LT_16(pitch_index, PIT_FR2_EXT9b_MINUS_PIT_MIN_EXT_X4)) + { + /**T0 = PIT_MIN_EXTEND + (pitch_index/4);*/ + *T0 = add(PIT_MIN_EXTEND, shr(pitch_index,2)); + move16(); + /**T0_frac = pitch_index - (*T0 - PIT_MIN_EXTEND)*4;*/ + *T0_frac = sub(pitch_index, shl(sub(*T0, PIT_MIN_EXTEND),2)); + move16(); + } + ELSE IF( LT_16(pitch_index,add(PIT_FR2_EXT9b_MINUS_PIT_MIN_EXT_X4, PIT_FR1_EXT9b_MINUS_PIT_FR2_EXT9b_X2))) + { + /*pitch_index -= (PIT_FR2_EXTEND_9b-PIT_MIN_EXTEND)*4;*/ + pitch_index = sub(pitch_index, PIT_FR2_EXT9b_MINUS_PIT_MIN_EXT_X4); + *T0 = add(PIT_FR2_EXTEND_9b, shr(pitch_index,1)); + *T0_frac = sub(pitch_index, shl(sub(*T0, PIT_FR2_EXTEND_9b),1)); + (*T0_frac) = shl(*T0_frac,1); + move16(); + } + ELSE + { + /**T0 = pitch_index + PIT_FR1_EXTEND_9b - ((PIT_FR2_EXTEND_9b-PIT_MIN_EXTEND)*4) - ((PIT_FR1_EXTEND_9b-PIT_FR2_EXTEND_9b)*2);move16();*/ + *T0 = add(pitch_index, PIT_DECODE_7); + move16(); + *T0_frac = 0; + move16(); + } + } + ELSE /* fr_steps == 0 */ + { + /* not used in the codec */ + } + } + ELSE /* limit_flag == 2 */ + { + IF( EQ_16(fr_steps,2)) + { + IF( LT_16(pitch_index,PIT_FR1_DEXT8b_MINUS_PIT_MIN_DEXT_X2)) + { + *T0 = add(PIT_MIN_DOUBLEEXTEND, shr(pitch_index,1)); + move16(); + *T0_frac = sub(pitch_index, shl(sub(*T0, PIT_MIN_DOUBLEEXTEND),1)); + move16(); + *T0_frac = shl(*T0_frac,1); + move16(); + } + ELSE + { + /**T0 = pitch_index + PIT_FR1_DOUBLEEXTEND_8b - ((PIT_FR1_DOUBLEEXTEND_8b-PIT_MIN_DOUBLEEXTEND)*2);move16();*/ + *T0 = add(pitch_index, PIT_DECODE_8); + move16(); + *T0_frac = 0; + move16(); + } + } + ELSE IF( EQ_16(fr_steps,4)) + { + IF( LT_16(pitch_index, PIT_FR2_DEXT9b_MINUS_PIT_MIN_DEXT_X4)) + { + *T0 = add(PIT_MIN_DOUBLEEXTEND, shr(pitch_index,2)); + move16(); + *T0_frac = sub(pitch_index, shl(sub(*T0, PIT_MIN_DOUBLEEXTEND),2)); + move16(); + } + ELSE IF( LT_16(pitch_index,PIT_DECODE_9)) + { + /*pitch_index -= (PIT_FR2_DOUBLEEXTEND_9b-PIT_MIN_DOUBLEEXTEND)*4;move16();*/ + pitch_index = sub(pitch_index , PIT_FR2_DEXT9b_MINUS_PIT_MIN_DEXT_X4); + move16(); + *T0 = add(PIT_FR2_DOUBLEEXTEND_9b, shr(pitch_index,1)); + move16(); + *T0_frac = sub(pitch_index, shl(sub(*T0, PIT_FR2_DOUBLEEXTEND_9b),1)); + move16(); + (*T0_frac) = shl(*T0_frac,1); + move16(); + } + ELSE + { + *T0 = add(pitch_index, PIT_DECODE_10); + move16(); + *T0_frac = 0; + move16(); + } + } + ELSE /* fr_steps == 0 */ + { + /* not used in the codec */ + } + } + + return; +} + +/*----------------------------------------------------------* + * delta_pit_dec_fx() + * + * Delta pitch decoding + *----------------------------------------------------------*/ + +void delta_pit_dec_fx( + const Word16 fr_steps, /* i : fractional resolution steps (0, 2, 4) */ + const Word16 pitch_index, /* i : pitch index */ + Word16 *T0, /* o : integer pitch lag */ + Word16 *T0_frac, /* o : pitch fraction */ + const Word16 T0_min /* i : delta search min */ +) +{ + + Word16 temp; + IF( fr_steps == 0 ) + { + *T0 = add(T0_min,pitch_index); + move16(); + *T0_frac = 0; + move16(); + } + ELSE IF( EQ_16(fr_steps,2)) + { + *T0 = add(T0_min,shr(pitch_index,1)); + move16(); + temp = shl(sub(*T0,T0_min),1); + *T0_frac = shl(sub(pitch_index,temp),1); + move16(); + } + ELSE IF ( EQ_16(fr_steps,4)) + { + *T0 = add(T0_min,shr(pitch_index,2)); + move16(); + temp = shl(sub(*T0,T0_min),2); + *T0_frac = sub(pitch_index,temp); + move16(); + } + + return; +} diff --git a/lib_dec/pitch_extr.c b/lib_dec/pitch_extr.c index 209370d2f2d27fe5880ace741332fe0038013fa4..7538dac3ba2291e47c4a2580ee547611625f9da7 100644 --- a/lib_dec/pitch_extr.c +++ b/lib_dec/pitch_extr.c @@ -49,7 +49,7 @@ * Pitch prediction for frame erasure using linear fitting * *-----------------------------------------------------------------*/ -void pitch_pred_linear_fit( +void pitch_pred_linear_fit_flt( const int16_t nbLostCmpt, /* i : bfi counter */ const int16_t last_good, /* i : last classification type */ float *old_pitch_buf, /* i : pitch lag buffer */ @@ -325,7 +325,7 @@ void pitch_pred_linear_fit( } -void get_subframe_pitch( +void get_subframe_pitch_flt( const int16_t nSubframes, /* i : number of subframes */ float pitchStart, /* i : starting pitch lag (in subframe -1) */ float pitchEnd, /* i : ending pitch lag (in subframe nSubframes-1) */ diff --git a/lib_dec/pitch_extr_fx.c b/lib_dec/pitch_extr_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..0a2e3751bf153f313be3ba03c9f804f8186b7b9a --- /dev/null +++ b/lib_dec/pitch_extr_fx.c @@ -0,0 +1,325 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + + +#include +#include +#include "options.h" +#include "cnst.h" +#include "prot_fx1.h" +#include "prot_fx2.h" +#include "basop_util.h" + + + +/*-------------------------------------------------------------------* + * - num x 32768 + * ------------------- Q15 + * PIT_MAX x Fact + *-------------------------------------------------------------------*/ + +#define PIT_MAX_DIV_8k(num, fact) ( -(num * 32768) / (PIT_MAX_12k8 * fact) ) +#define PIT_MAX_DIV_12k8(num, fact) ( -(num * 32768) / (PIT_MAX_12k8 * fact) ) +#define PIT_MAX_DIV_16k(num, fact) ( -(num * 32768) / (PIT_MAX_16k * fact) ) + + +/*-----------------------------------------------------------------* + * Pitch prediction for frame erasure using linear fitting * + *-----------------------------------------------------------------*/ +/*port is up to date with trunk 38840*/ +void pitch_pred_linear_fit( + const Word16 /*short*/ bfi_cnt, /* i: bfi counter */ /*Q0 */ + const Word16 /*short*/ last_good, /* i: last classification type */ /*Q0 */ + Word32 /*float*/ *old_pitch_buf, /* i: pitch lag buffer */ /*Q16*/ + Word32 /*float*/ *old_fpitch, /* i: */ /*Q16*/ + Word32 /*float*/ *T0_out, /* o: estimated close loop pitch */ /*Q16*/ + Word16 /* int*/ pit_min, /* i: Minimum pitch lag */ /*Q0 */ + Word16 /* int*/ pit_max, /* i: Maximum pitch lag */ /*Q0 */ + Word16 /*float*/ *mem_pitch_gain, /* i: pitch gain [0] is the most recent subfr gain */ /*Q14*/ + Word16 /* int*/ limitation, + Word8 /*short*/ plc_use_future_lag, /* i: */ /*Q0 */ + Word16 /*short*/ *extrapolationFailed,/* o: flag if extrap decides not to change the pitch */ /*Q0 */ + Word16 nb_subfr /* i: number of ACELP subframes*/ +) +{ + Word32 pit, a, b, pita, pitb; + Word16 sum0; + Word32 T0; + Word32 mdy, dy[5]; + Word16 lcor; + Word16 imax, i; + Word16 pg[8]; /* local buffer for pitch gain*/ + Word32 ml[8]; /* local buffer for mem_lag*/ + Word16 const timeWeight[5] = {20480/*1.25f Q14*/, 18432/*1.125f Q14*/, 16384/*1.f Q14*/, 14336/*0.875f Q14*/, 12288/*.75f Q14*/}; /*Q14*/ + Word16 no_subfr_pred; + Word16 a1, a2, a3, a4, a5, tmpa, tmpb, b1, b2, b3, b4, b5; + Word16 a_e, b_e, sum0_q; + Word32 mem_lag[2*NB_SUBFR16k+2]; + + + /* Inverse the order the pitch lag memory */ + IF ( EQ_16(nb_subfr, 4)) + { + FOR (i = 0; i < 2*NB_SUBFR+2; i++) + { + mem_lag[i] = old_pitch_buf[2*NB_SUBFR+1 - i]; + move32(); + } + } + ELSE /* L_frame == L_FRAME16k */ + { + FOR (i = 0; i < 2*NB_SUBFR16k+2; i++) + { + mem_lag[i] = old_pitch_buf[2*NB_SUBFR16k+1 - i]; + move32(); + } + } + move16(); + move16(); + move16(); + move16(); + move16(); /*timeweight*/ + + IF (LT_16(pit_max,extract_h(*old_fpitch)) ) + { + *extrapolationFailed = 1; + *T0_out = pit_max; + return; + } + + move16(); + lcor = 5; + T0 = L_deposit_l(0); + + test(); + test(); + IF (EQ_16(bfi_cnt , 1)&&GE_16(last_good,UNVOICED_TRANSITION)&<_16(last_good,ONSET)) + { + move16(); + no_subfr_pred = 4; + if (plc_use_future_lag!=0) + { + move16(); + no_subfr_pred = 2; + } + + /* copy to local buffers, depending on availability of info about future subframes */ + Copy(mem_pitch_gain+no_subfr_pred-2,pg,8); + Copy32(mem_lag+no_subfr_pred-2,ml,8); + + mdy = L_deposit_l(0); + + FOR (i = (sub(lcor,1)); i >= 0; i--) + { + move32(); + dy[i] = L_sub(ml[i] , ml[i+1]); + mdy = L_add(mdy , dy[i]); + } + + /*---------------------------------------------------* + * remove maximum variation + *---------------------------------------------------*/ + move16(); + imax = 0; + pita = L_abs(dy[0]); + FOR (i = 1; i Q9*/),mult_r(pg[3],16384/*Q12->Q11*/))/*Q5*/; + a4 = mac_r(L_mac(L_mult( mult_r(-12*2048,pg[0])/*Q8*/,pg[3] /*Q12*/)/*Q5+16*/,mult_r(-6*2048,pg[1])/*Q8*/,pg[3]/*Q12*/)/*Q5+16*/,mult_r(-2*2048,pg[2])/*Q8*/,pg[3]/*Q12*/)/*Q5*/; + a3 = mac_r(L_mac(L_mult( mult_r(-8*2048,pg[0]) /*Q8*/,pg[2]),mult_r(-3*2048,pg[1])/*Q8*/,pg[2]),mult_r(pg[2],4096/*Q12->Q9*/),mult_r(pg[3],16384/*12->Q11*/));/*Q5*/ + a2 = mac_r(L_mac(L_mult( mult_r(2*2048,pg[1]) /*Q8*/,pg[2])/*Q5+16*/,mult_r(2*2048,pg[1])/*Q8*/,pg[3])/*Q5+16*/,mult_r(-4*2048,pg[0])/*Q8*/,pg[1]/*Q12*/)/*Q5*/; + a1 = mac_r(L_mac(L_mult( mult_r(3*2048,pg[0]) /*Q8*/,pg[1])/*Q5+16*/,mult_r(4*2048,pg[0])/*Q8*/,pg[2]/*Q12*/)/*Q5+16*/,mult_r(3*2048,pg[0])/*Q8*/,pg[3]/*Q12*/)/*Q5*/; + + a = L_mac(L_mac(L_mac(L_mac(L_mult(a1 + , round_fx(L_shl(ml[0],4)))/*Q4*/ + , round_fx(L_shl(ml[1],4)) /*Q4*/, a2) + , round_fx(L_shl(ml[2],4)) /*Q4*/, a3) + , round_fx(L_shl(ml[3],4)) /*Q4*/, a4) + , round_fx(L_shl(ml[4],4)) /*Q4*/, a5); /*Q-6+16 = Q10*/ + + a_e = norm_l(a); + a = L_shl(a, a_e); + + a1 = BASOP_Util_Divide3216_Scale(L_negate(a), /* Numerator */ /*scalefactor 21*/ + sum0, /* Denominator*/ /*scalefactor 10*/ + &tmpa); /* scalefactor for result */ + + /* Float: + b=(( pg[1]+2*pg[2]+3*pg[3]+4*pg[4])*pg[0] *//*b1*//* + *ml[0] + + (( pg[2]+2*pg[3]+3*pg[4])*pg[1]-pg[1]*pg[0]) *//*b2*//* + *ml[1] + + ( -2*pg[2]*pg[0]-pg[2]*pg[1]+(pg[3]+2*pg[4])*pg[2]) *//*b3*//* + *ml[2] + + ( -3*pg[3]*pg[0]-2*pg[3]*pg[1]-pg[3]*pg[2]+pg[4]*pg[3]) *//*b4*//* + *ml[3] + + ( -4*pg[4]*pg[0]-3*pg[4]*pg[1]-2*pg[4]*pg[2]-pg[4]*pg[3]) *//*b5*//* + *ml[4] )/sum0; MAC(22);MULT(9);DIV(1);*/ + + /*magic numbers in Q13 if not DIRECTLY marked otherwise*/ + b1 = mac_r(L_mac(L_mac(L_mult(mult_r(pg[1],pg[0]),32768/4)/*Q7+16*/,mult_r(2*8192,pg[0])/*Q10*/,pg[2]/*Q12*/)/*Q7+16*/,mult_r(3*8192,pg[0])/*Q10*/,pg[3]/*Q12*/)/*Q7+16*/, /*mult_r(4*8192,pg[0])*/ pg[0]/*Q10*/,pg[4]/*Q12*/)/*Q7*/; + b2 = mac_r(L_mac(L_mac(L_mult(mult_r(pg[2],pg[1]),32768/4)/*Q7+16*/,mult_r(2*8192,pg[1]),pg[3]),mult_r(3*8192,pg[1]),pg[4])/*Q7+16*/,mult_r(pg[1],-32768/2/*Q12->Q12*/),mult_r(pg[0],32768/2/*Q12->Q10*/))/*Q7*/; + b3 = mac_r(L_mac(L_mac(L_mult(mult_r(-2*8192,pg[0]),pg[2])/*Q7+16*/,mult_r(pg[2],-32768/2),mult_r(pg[1],32768/2)),mult_r(pg[3],32768/2),mult_r(pg[2],32768/2))/*Q5+16*/,mult_r(2*8192,pg[2]),pg[4])/*Q7*/; + b4 = mac_r(L_mac(L_mac(L_mult(mult_r(-3*8192,pg[0]),pg[3]),mult_r(-2*8192,pg[1]),pg[3]),mult_r(-32768/2,pg[3]),mult_r(32768/2,pg[2])),mult_r(32768/2,pg[4]),mult_r(32768/2,pg[3]));/*Q7*/ + b5 = mac_r(L_mac(L_mac(L_mult(mult_r(-32768/*(-4*8192)*/,pg[0]),pg[4]),mult_r(-3*8192,pg[1]),pg[4]),mult_r(-2*8192,pg[2]),pg[4]),mult_r(-32768/2,pg[4]),mult_r(32768/2,pg[3]))/*Q7*/; + + b = L_mac(L_mac(L_mac(L_mac(L_mult(b1 + , round_fx(L_shl(ml[0],4)))/*Q4*/ + , round_fx(L_shl(ml[1],4)) /*Q4*/, b2) + , round_fx(L_shl(ml[2],4)) /*Q4*/, b3) + , round_fx(L_shl(ml[3],4)) /*Q4*/, b4) + , round_fx(L_shl(ml[4],4)) /*Q4*/, b5); /*Q-4+16 = Q12*/ + /*predict pitch for 4th future subframe*/ + + b_e = norm_l(b); + b = L_shl(b, b_e); + + b1 = BASOP_Util_Divide3216_Scale(b, /* Numerator */ /*scalefactor 19*/ + sum0, /* Denominator*/ /*scalefactor 10*/ + &tmpb); /* scalefactor for result*/ + + /*pit = a + b * ((float)no_subfr_pred + (float)nb_subfr);*/ + pita = L_shl( L_deposit_l(a1),add(add(sum0_q, 16-10+1),sub(tmpa, a_e)))/*Q16*/; + pitb = L_shl_r(L_mult(b1/*Q15*/,add(no_subfr_pred,nb_subfr)/*Q0*/ ),add(add(sum0_q, 16-12),sub(tmpb, b_e))); + pit = L_add( pita , pitb ); /*Q16*/ + + T0 = L_add(pit, 0); + + /*limit pitch to allowed range*/ + + T0 = L_min(L_deposit_h(pit_max),T0); + T0 = L_max(L_deposit_h(pit_min),T0); + + move16(); + *extrapolationFailed = 0; + } + ELSE + { + T0 = L_deposit_l(0); + *extrapolationFailed = 1; + move16(); + } + } + ELSE + { + + T0 = L_deposit_l(0); + move16(); + *extrapolationFailed = 1; + } + } + ELSE + { + T0 = L_add(*old_fpitch, 0); + move16(); + *extrapolationFailed = 1; + } + move32(); + *T0_out = T0; + + return; +} + +/* up to date with rev 8158*/ +void get_subframe_pitch( + Word16 nSubframes, /* i: number of subframes */ /* Q0 */ + Word32 pitchStart, /* i: starting pitch lag (in subframe -1) */ /*15Q16*/ + Word32 pitchEnd, /* i: ending pitch lag (in subframe nSubframes-1) */ /*15Q16*/ + Word32 *pitchBuf /* o: interpolated pitch lag per subframe */ /*15Q16*/ +) +{ + Word16 i,s; + Word32 pitchDelta; + + assert((nSubframes > 0) && (pitchBuf != NULL) && (pitchStart >= 0) && (pitchEnd > 0)); + + /*pitchDelta = (pitchEnd - pitchStart)/nSubframes;*/ + pitchDelta = L_deposit_l(BASOP_Util_Divide3216_Scale(L_sub(pitchEnd,pitchStart),nSubframes, &s));/*Q15*/ + pitchDelta = L_shl(pitchDelta,add(s,1));/*Q16*/ + pitchBuf[0] = L_add(pitchStart,pitchDelta); + FOR (i = 1; i < nSubframes; i++) + { + pitchBuf[i] = L_add(pitchBuf[i-1] , pitchDelta); + move32(); + } +} + diff --git a/lib_dec/post_dec.c b/lib_dec/post_dec.c index f54dba875cc21995ca9e79fa5b0708d2dec1dbea..fa578364e609aef300753324372fa40dc7b0696a 100644 --- a/lib_dec/post_dec.c +++ b/lib_dec/post_dec.c @@ -49,12 +49,12 @@ static void bass_pf_1sf_delay( float *syn, const int16_t *T_sf, const float *gai /*---------------------------------------------------------------------* - * post_decoder() + * post_decoder_flt() * * Perform post-processing *---------------------------------------------------------------------*/ -void post_decoder( +void post_decoder_flt( Decoder_State *st, /* i/o: decoder memory state pointer */ float synth_buf[], const float pit_gain[], @@ -105,8 +105,8 @@ void post_decoder( L_subfr = st->L_frame / st->nb_subfr; residu( A, M, synth, synth_buf, L_subfr ); syn_filt( A, M, synth_buf, synth2, L_subfr, st->hPFstat->mem_stp_flt + L_SYN_MEM - M, 0 ); - scale_st( synth, synth2, &st->hPFstat->gain_prec_flt, L_subfr, -1 ); - blend_subfr2( synth2 + L_subfr / 2, synth + L_subfr / 2, synth2 + L_subfr / 2 ); + scale_st_ivas( synth, synth2, &st->hPFstat->gain_prec_flt, L_subfr, -1 ); + blend_subfr2_flt( synth2 + L_subfr / 2, synth + L_subfr / 2, synth2 + L_subfr / 2 ); } } else @@ -133,12 +133,12 @@ void post_decoder( if ( st->bwidth == NB ) { st->hPFstat->on = 1; - nb_post_filt( L_frame, L_SUBFR, st->hPFstat, &tmp, 0, synth_buf, st->mem_Aq_float, pitch_buf, GENERIC, st->BER_detect, st->lp_noise_float > LP_NOISE_THRESH_FLT ? 1 : ( ( st->core != ACELP_CORE ) || ( st->coder_type == UNVOICED ) ) ); + nb_post_filt_ivas( L_frame, L_SUBFR, st->hPFstat, &tmp, 0, synth_buf, st->mem_Aq_float, pitch_buf, GENERIC, st->BER_detect, st->lp_noise_float > LP_NOISE_THRESH_FLT ? 1 : ( ( st->core != ACELP_CORE ) || ( st->coder_type == UNVOICED ) ) ); } else { st->hPFstat->on = 0; - nb_post_filt( L_frame, L_SUBFR, st->hPFstat, &tmp, 0, synth_buf, st->mem_Aq_float, pitch_buf, AUDIO, st->BER_detect, st->lp_noise_float > LP_NOISE_THRESH_FLT ? 1 : ( ( st->core != ACELP_CORE ) || ( st->coder_type == UNVOICED ) ) ); + nb_post_filt_ivas( L_frame, L_SUBFR, st->hPFstat, &tmp, 0, synth_buf, st->mem_Aq_float, pitch_buf, AUDIO, st->BER_detect, st->lp_noise_float > LP_NOISE_THRESH_FLT ? 1 : ( ( st->core != ACELP_CORE ) || ( st->coder_type == UNVOICED ) ) ); } @@ -157,12 +157,12 @@ void post_decoder( if ( st->bwidth >= WB ) { st->hPFstat->on = 1; - formant_post_filt( st->hPFstat, synth, st->mem_Aq_float, synth2, L_frame, L_SUBFR, st->lp_noise_float, brate, 0 ); + formant_post_filt_ivas( st->hPFstat, synth, st->mem_Aq_float, synth2, L_frame, L_SUBFR, st->lp_noise_float, brate, 0 ); } else { st->hPFstat->on = 0; - formant_post_filt( st->hPFstat, synth, st->mem_Aq_float, synth2, L_frame, L_SUBFR, st->lp_noise_float, brate, 1 ); + formant_post_filt_ivas( st->hPFstat, synth, st->mem_Aq_float, synth2, L_frame, L_SUBFR, st->lp_noise_float, brate, 1 ); } } @@ -341,12 +341,12 @@ static void bass_pf_1sf_delay( return; } /*---------------------------------------------------------------------* - * cldfb_synth_set_bandsToZero() + * cldfb_synth_set_bandsToZero_flt() * * *---------------------------------------------------------------------*/ -void cldfb_synth_set_bandsToZero( +void cldfb_synth_set_bandsToZero_flt( Decoder_State *st, float **rAnalysis, float **iAnalysis, diff --git a/lib_dec/post_dec_fx.c b/lib_dec/post_dec_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..bc093265f4f35dd5293f02cde5e8cd79578c04dc --- /dev/null +++ b/lib_dec/post_dec_fx.c @@ -0,0 +1,643 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include +#include +#include "options.h" +#include "prot_fx1.h" +#include "prot_fx2.h" +#include "basop_util.h" + + +/*---------------------------------------------------------------------* + * Function prototypes + *---------------------------------------------------------------------*/ + +static void bass_pf_1sf_delay( Word16 *syn, Word16 *T_sf, Word16 *gainT_sf, Word16 l_frame, + Word16 l_subfr, Word16 *bpf_noise_buf, Word16 *gain_factor_param, + Word8 disable_bpf, Word32 *lp_error_ener, Word32 *mem_error ); + +/*---------------------------------------------------------------------* + * post_decoder() + * + * Perform post-processing + *---------------------------------------------------------------------*/ + +void post_decoder( + Decoder_State *st, + Word16 synth_buf[], + Word16 pit_gain[], + Word16 pitch[], + Word16 signal_out[], + Word16 *bpf_noise_buf +) +{ + Word16 L_frame, nb_subfr; + Word16 *synth, *synth2; + Word16 pfstat_on_previous; + Word16 pitch_gain_adjust[NB_SUBFR16k]; + Word16 tmp, tmp_noise; + Word16 synth2_pe[L_FRAME_MAX]; + Word16 synth_buf2[PIT_MAX_16k+1+L_FRAME_MAX+M]; + Word32 bitrate; + Word8 tmp8; + BPF_DEC_HANDLE hBPF; + Word16 coder_type = st->coder_type_fx; + + move16(); +// if (st->hPFstat != NULL || st->hBPF == NULL) +// { +//#ifdef DEBUGGING +// IVAS_ERROR(IVAS_ERR_INTERNAL, "ERROR::: In function post_decoder, at least one post filter handle is not initialized, at frame %d\n", frame); +//#endif +// return; +// } + hBPF = st->hBPF; + L_frame = st->L_frame; + move16(); + nb_subfr = st->nb_subfr; + move16(); + pfstat_on_previous = st->hPFstat->on; + move16(); + st->hPFstat->on = 0; + move16(); + + bitrate = L_add(st->total_brate, 0); + if(st->core_brate <= SID_2k40) + { + bitrate = L_add(st->last_active_brate, 0); + } + + + /*Adapt Bpf: copy old and current adapt bpf parameters*/ + set16_fx(pitch_gain_adjust, st->bpf_gain_param, nb_subfr); + + synth = synth_buf + st->hTcxDec->old_synth_len; + synth2 = synth_buf2 + NBPSF_PIT_MAX; + Copy(hBPF->pst_old_syn_fx, synth_buf2, NBPSF_PIT_MAX ); + + IF ( st->tcxonly != 0 ) + { + Copy( synth, synth2, L_frame ); + IF ( pfstat_on_previous ) + { + Copy( st->hPFstat->mem_pf_in+L_SYN_MEM-M, synth-M, M ); + Residu3_fx ( st->old_Aq_12_8_fx, synth, synth_buf, L_SUBFR, 1 ); + E_UTIL_synthesis ( 1, st->old_Aq_12_8_fx, synth_buf, synth2, L_SUBFR, st->hPFstat->mem_stp+L_SYN_MEM-M, 0, M ); + scale_st ( synth, synth2, &st->hPFstat->gain_prec, L_SUBFR ); + blend_subfr2(synth2+L_SUBFR/2, synth+L_SUBFR/2, synth2+L_SUBFR/2); + } + } + ELSE + { + /*Formant enhancement*/ + IF ( EQ_16(st->last_bwidth,NB)) + { + Copy( synth, synth2_pe, L_frame ); + tmp = synth[-1]; + move16(); + + preemph_copy_fx( synth2_pe, synth2_pe, st->preemph_fac, L_frame, &tmp); + + tmp = 0; + move16(); + test(); + test(); + if ((GT_32(st->lp_noise, LP_NOISE_THRESH))|| + (st->core != ACELP_CORE) || + (EQ_16(coder_type, UNVOICED))) + { + tmp = 1; + move16(); + } + + if(pfstat_on_previous==0) + { + st->hPFstat->reset = 1; + move16(); + } + IF ( EQ_16(st->bwidth,NB)) + { + st->hPFstat->on = 1; + move16(); + tmp_noise = 0; + nb_post_filt( L_frame, st->hPFstat, &tmp_noise, 0, synth2_pe, st->mem_Aq, pitch, GENERIC, st->BER_detect, tmp ); + } + ELSE + { + st->hPFstat->on = 0; + move16(); + tmp_noise = 0; + nb_post_filt( L_frame, st->hPFstat, &tmp_noise, 0, synth2_pe, st->mem_Aq, pitch, AUDIO, st->BER_detect, tmp ); + } + Copy(synth2_pe, synth2, L_frame); + + tmp = synth2[-1]; + move16(); + deemph_fx( synth2, st->preemph_fac, L_frame, &tmp ); + } + ELSE + { + if(pfstat_on_previous==0) + { + st->hPFstat->reset = 1; + move16(); + } + IF ( GE_16(st->last_bwidth,WB)) + { + st->hPFstat->on = 1; + move16(); + formant_post_filt( st->hPFstat, synth, st->mem_Aq, synth2, L_frame, st->lp_noise, bitrate, 0 ); + } + ELSE + { + st->hPFstat->on = 0; + move16(); + formant_post_filt( st->hPFstat, synth, st->mem_Aq, synth2, L_frame, st->lp_noise, bitrate, 1 ); + } + } + + /*Bass Post-filter */ + tmp8 = 0; + move16(); + test(); + if( GT_32(st->lp_noise,LP_NOISE_THRESH)&&st->narrowBand) + { + tmp8 = 1; + move16(); + } + bass_pf_1sf_delay( synth2, pitch, pit_gain, L_frame, L_SUBFR, bpf_noise_buf, pitch_gain_adjust, + tmp8, &(st->lp_error_ener), &(st->mem_error) ); + } + + /* Output */ + Copy( synth2, signal_out, L_frame ); + + /* Update synth2 memory */ + Copy( synth_buf2 + L_frame, hBPF->pst_old_syn_fx, NBPSF_PIT_MAX ); + + + return; +} + + +/*---------------------------------------------------------------------* + * bass_pf_1sf_delay() + * + * Perform low-frequency postfiltering + *---------------------------------------------------------------------*/ + +static void bass_pf_1sf_delay( + Word16 *syn, /* (i) : 12.8kHz synthesis to postfilter Q0 */ + Word16 *T_sf, /* (i) : Pitch period for all subframes (T_sf[16]) Q0 */ + Word16 *gainT_sf, /* (i) : Pitch gain for all subframes (gainT_sf[16]) Q14 */ + Word16 l_frame, /* (i) : frame length (should be multiple of l_subfr) Q0 */ + Word16 l_subfr, /* (i) : sub-frame length (60/64) Q0 */ + Word16 *bpf_noise_buf, /* (i) : harmoninc filtered signal Q0 */ + Word16 *gain_factor_param, /* (i) : gain factor param 0-> no BPF, 3-> full BPF */ + Word8 disable_bpf, + Word32 *lp_error_ener, + Word32 *mem_error +) +{ + Word16 i, sf, i_subfr, T, lg, s1, st, tmp16; + Word16 gain; + Word32 tmp, nrg, lp_error, tmp32; + Word32 ener2; + + assert(bpf_noise_buf != NULL); + + sf = 0; + move16(); + lp_error = L_shl(*mem_error, 0); + + FOR (i_subfr = 0; i_subfr < l_frame; i_subfr += l_subfr) + { + T = T_sf[sf]; + move16(); + + lg = sub(sub(l_frame, T), i_subfr); + if (lg < 0) + { + lg = 0; + move16(); + } + if (lg > l_subfr) + { + lg = l_subfr; + move16(); + } + + test(); + IF (disable_bpf == 0 && gainT_sf[sf] > 0) + { + /* get headroom for used part of syn */ + tmp16 = add(l_subfr, T); + if (lg>0) + { + tmp16 = add(lg, shl(T, 1)); + } + s1 = getScaleFactor16(syn + sub(i_subfr, T), tmp16); + s1 = sub(s1, 3); + + tmp = L_deposit_l(1); + nrg = L_deposit_l(1); + + IF (lg > 0) + { + + { + Word64 tmp64 = W_deposit32_l( tmp ); + Word64 nrg64 = W_deposit32_l( nrg ); + FOR (i = 0; i < lg; i++) + { + tmp32 = L_mult(syn[i+i_subfr-T], 0x4000); + tmp32 = L_mac(tmp32, syn[i+i_subfr+T], 0x4000); + tmp16 = round_fx(L_shl(tmp32, s1)); /* Q0+s1 */ + + tmp64 = W_mac0_16_16(tmp64, shl(syn[i+i_subfr], s1), tmp16); /* Q0+2*s1 */ + nrg64 = W_mac0_16_16(nrg64, tmp16, tmp16); /* Q0+2*s1 */ + } + tmp = W_sat_l(tmp64); + nrg = W_sat_l(nrg64); + } + + } + + IF (LT_16(lg, l_subfr)) + { + + { + Word64 tmp64 = W_deposit32_l( tmp ); + Word64 nrg64 = W_deposit32_l( nrg ); + FOR (i = lg; i < l_subfr; i++) + { + tmp16 = shl(syn[i+i_subfr-T], s1); /* Q0+s1 */ + tmp64 = W_mac0_16_16(tmp64, shl(syn[i+i_subfr], s1), tmp16); /* Q0+2*s1 */ + nrg64 = W_mac0_16_16(nrg64, tmp16, tmp16); /* Q0+2*s1 */ + } + tmp = W_sat_l(tmp64); + nrg = W_sat_l(nrg64); + } + + } + + /* gain = tmp/nrg; */ + gain = BASOP_Util_Divide3232_Scale(tmp, nrg, &tmp16); + BASOP_SATURATE_WARNING_OFF_EVS; +#ifdef BASOP_NOGLOB + gain = shl_sat(gain, tmp16); /* Q15 */ +#else + gain = shl(gain, tmp16); /* Q15 */ +#endif + BASOP_SATURATE_WARNING_ON_EVS; + + if (gain < 0) + { + gain = 0; + move16(); + } + + st = sub(norm_l(lp_error), 3); + test(); + if ((LT_16(st, s1))&&(lp_error!=0)) + { + s1 = st; + move16(); + } + + ener2 = L_deposit_l(0); + + IF (lg > 0) + { + + { + Word64 ener2_64 = W_deposit32_l( ener2 ); + FOR (i = 0; i < lg; i++) + { + tmp32 = L_msu0(0, gain, syn[i+i_subfr-T]); + tmp32 = L_msu0(tmp32, gain, syn[i+i_subfr+T]); +#ifdef BASOP_NOGLOB + tmp16 = mac_r_sat(tmp32, gain, syn[i+i_subfr]); /* Q0 */ +#else + tmp16 = mac_r(tmp32, gain, syn[i+i_subfr]); /* Q0 */ +#endif + lp_error = Mpy_32_16_1(lp_error, 29491/*0.9f Q15*/); + lp_error = L_mac(lp_error, tmp16, 0x1000); /* Q13 */ + + tmp16 = round_fx(L_shl(lp_error, s1)); /* Q0+s1-3 */ + ener2_64 = W_mac0_16_16(ener2_64, tmp16, tmp16); /* Q0+(s1-3)*2 */ + } + ener2 = W_sat_l(ener2_64); + } + + } + + IF (LT_16(lg, l_subfr)) + { + + { + Word64 ener2_64 = W_deposit32_l( ener2 ); + FOR (i = lg; i < l_subfr; i++) + { + tmp32 = L_mult0(gain, syn[i+i_subfr]); + tmp32 = L_msu0(tmp32, gain, syn[i+i_subfr-T]); /* Q0 */ + tmp16 = round_fx(tmp32); + + lp_error = Mpy_32_16_1(lp_error, 29491/*0.9f Q15*/); + lp_error = L_mac(lp_error, tmp16, 0x1000); /* Q13 */ + + tmp16 = round_fx(L_shl(lp_error, s1)); /* Q0+s1-3 */ + ener2_64 = W_mac0_16_16(ener2_64, tmp16, tmp16); /* Q0+(s1-3)*2 */ + } + ener2 = W_sat_l(ener2_64); + } + + } + + st = shl(sub(s1, 3), 1); + + IF (ener2 > 0) + { + ener2 = L_shr(BASOP_Util_Log2(ener2), 9); /* 15Q16 */ + ener2 = L_add(ener2, L_deposit_h(sub(31, st))); + } + ELSE + { + ener2 = L_add(0xFFF95B2C, 0); /* log2(0.01) (15Q16) */ + } + + *lp_error_ener = L_add(Mpy_32_16_1(L_sub(*lp_error_ener, ener2), 32440/*0.99f Q15*/), ener2); /* 15Q16 */ + + st = add(st, 6); + ener2 = L_sub(*lp_error_ener, L_deposit_h(sub(31, st))); + IF (ener2 >= 0) + { + tmp16 = add(extract_h(ener2), 1); + ener2 = L_sub(ener2, L_deposit_h(tmp16)); + tmp = L_shr(tmp, tmp16); + nrg = L_shr(nrg, tmp16); + } + ener2 = BASOP_Util_InvLog2(L_shl(ener2, 9)); /* Q0+2*s1 */ + + tmp32 = L_add(L_shr(nrg, 1), L_shr(ener2, 1)); + if (tmp32 == 0) tmp32 = L_deposit_l(1); + tmp16 = BASOP_Util_Divide3232_Scale(tmp, tmp32, &st); + BASOP_SATURATE_WARNING_OFF_EVS; +#ifdef BASOP_NOGLOB + tmp16 = shl_sat(tmp16, sub(st, 2)); /* Q15 */ +#else + tmp16 = shl(tmp16, sub(st, 2)); /* Q15 */ +#endif + + if (GT_16(tmp16, 16384/*0.5f Q15*/)) + { + tmp16 = 16384/*0.5f Q15*/; + move16(); + } + if (tmp16 < 0) + { + tmp16 = 0; + move16(); + } + BASOP_SATURATE_WARNING_ON_EVS; + + /*Adjust gain*/ + /* full gain = gainLTP*0.5*/ + /* adaptive gain = gainLTP*0.5*max(0.5f*gain_factor_param[sf],0.125f)*/ + tmp16 = round_fx(L_shl(L_mult0(tmp16, s_max(shl(gain_factor_param[sf],2),1)),13)); + + + /* calculate noise based on voiced pitch */ + IF (lg > 0) + { + FOR (i = 0; i < lg; i++) + { + tmp32 = L_msu0(0, tmp16, syn[i+i_subfr-T]); + tmp32 = L_msu0(tmp32, tmp16, syn[i+i_subfr+T]); + tmp32 = L_mac(tmp32, tmp16, syn[i+i_subfr]); + bpf_noise_buf[i+i_subfr] = round_fx(tmp32); /* Q0 */ + } + } + + IF (LT_16(lg, l_subfr)) + { + FOR (i = lg; i < l_subfr; i++) + { + tmp32 = L_mult0(tmp16, syn[i+i_subfr]); + tmp32 = L_msu0(tmp32, tmp16, syn[i+i_subfr-T]); + bpf_noise_buf[i+i_subfr] = round_fx(tmp32); /* Q0 */ + } + } + } + ELSE + { + set16_fx(bpf_noise_buf+i_subfr, 0, l_subfr); + } + + sf = add(sf, 1); + } + + *mem_error = lp_error; + move32(); + + + return; +} + +/*---------------------------------------------------------------------* + * cldfb_synth_set_bandsToZero() + * + * + *---------------------------------------------------------------------*/ + +void cldfb_synth_set_bandsToZero( + Decoder_State *st, + Word32 **rAnalysis, + Word32 **iAnalysis, + const Word16 nTimeSlots, + const CLDFB_SCALE_FACTOR scaleFactor +) +{ + Word32 nrgQ31; + Word32 nrg_band[CLDFB_NO_CHANNELS_MAX], tempQ31, max_nrg; + Word16 realQ1, imagQ1, flag, offset, WBcnt; + Word16 perc_detect, perc_miss; + Word16 i, k, tmp1, tmp2, tmp3, tmp, update_perc; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + + + realQ1 = 0; + move16(); + imagQ1 = 0; + move16(); + + set32_fx( nrg_band, 0, CLDFB_NO_CHANNELS_MAX ); + max_nrg = 0; + + offset = 250; + WBcnt = 20; + perc_miss = 13107; /*0.80 in Q14*/ + perc_detect = 14746; /*0.90 in Q14*/ + + IF(EQ_16(st->VAD,1)) + { + st->active_frame_cnt_bwddec = add(st->active_frame_cnt_bwddec,1); + st->total_frame_cnt_bwddec = add(st->total_frame_cnt_bwddec,1); + if(GT_16(st->active_frame_cnt_bwddec, 99)) + { + st->active_frame_cnt_bwddec = 100; + move16(); + } + if(GT_16(st->total_frame_cnt_bwddec, 500)) + { + st->total_frame_cnt_bwddec = 500; + move16(); + } + + FOR (i = 0; i < (st->cldfbSyn_fx->no_channels - st->cldfbSyn_fx->bandsToZero); i++) + { + nrgQ31 = 0; + move32(); + FOR (k = 0; k < nTimeSlots; k++) + { + /* use 16-bit precision of real and imag buffers */ + realQ1 = extract_l(L_shr(rAnalysis[k][i], 31-(15+scaleFactor.lb_scale)+3)); + imagQ1 = extract_l(L_shr(iAnalysis[k][i], 31-(15+scaleFactor.lb_scale)+3)); /* Q(-3), headroom */ +#ifdef BASOP_NOGLOB + nrgQ31 = L_mac0_o(nrgQ31, realQ1, realQ1, &Overflow); + nrgQ31 = L_mac0_o(nrgQ31, imagQ1, imagQ1, &Overflow); /* keep in Q(-6) */ +#else + nrgQ31 = L_mac0(nrgQ31, realQ1, realQ1); + nrgQ31 = L_mac0(nrgQ31, imagQ1, imagQ1); /* keep in Q(-6) */ +#endif + } + nrg_band[i] = (nrgQ31); + move16(); + test(); + if(GT_32(nrg_band[i], max_nrg)&&GE_16(i,11)) + { + max_nrg = nrg_band[i]; + move16(); + } + } + FOR(; i < st->cldfbSyn_fx->no_channels; i++) + { + nrg_band[i] = 0; + move16(); + } + + nrgQ31 = 0; + move16(); + FOR(i = 2; i < 9; i++) + { + nrgQ31 = L_add(nrgQ31, Mult_32_16(nrg_band[i], 4681)); + } + + tempQ31 = L_shr(nrgQ31,9); + + st->avg_nrg_LT = L_add(Mult_32_16(st->avg_nrg_LT, 32440), Mult_32_16(tempQ31, 327)); /*0.99*avg_nrg_LT + 0.01*tempQ31*/ + update_perc = 1; + move16(); + if(st->ini_frame >= 25 && tempQ31 < Mult_32_16(st->avg_nrg_LT, 164)) + { + update_perc = 0; + move16(); + } + + flag = 1; + move16(); + if(max_nrg >= tempQ31) + { + flag = 0; + move16(); + } + + FOR(i = 0; i < WBcnt-1; i++) + { + st->flag_buffer[i] = st->flag_buffer[i+1]; + move16(); + } + st->flag_buffer[WBcnt-1] = flag; + move16(); + + /*long term percentage*/ + IF(EQ_16(update_perc, 1)) + { + IF(flag != 0) + { + tmp1 = sub(16384, st->perc_bwddec); /*Q14*/ + + tmp = norm_s(st->active_frame_cnt_bwddec); + tmp3 = shl(st->active_frame_cnt_bwddec, tmp); /*Qtmp*/ + + tmp2 = div_s(16384,tmp3); /* 1/active_frames in Q15 + Q14 - Qtmp = Q29 - Qtmp */ + tmp2 = mult_r(tmp2, tmp1); /*(1-perc)*(1/active_frames) in Q14 + Q29 - Qtmp - Q15 = Q28 - Qtmp*/ + st->perc_bwddec = add(st->perc_bwddec, shl(tmp2, sub(tmp, 14))); /* Q14 */ + } + ELSE + { + tmp1 = (st->perc_bwddec); /*Q14*/ + + tmp = norm_s(st->active_frame_cnt_bwddec); + tmp3 = shl(st->active_frame_cnt_bwddec, tmp); /*Qtmp*/ + + tmp2 = div_s(16384,tmp3); /* 1/active_frames in Q15 + Q14 - Qtmp = Q29 - Qtmp */ + tmp2 = mult_r(tmp2, tmp1); /*(perc)*(1/active_frames) in Q14 + Q29 - Qtmp - Q15 = Q28 - Qtmp*/ + st->perc_bwddec = sub(st->perc_bwddec, shl(tmp2, sub(tmp, 14))); /* Q14 */ + } + } + test(); + IF(GT_16(st->total_frame_cnt_bwddec, offset)&>_16(st->active_frame_cnt_bwddec,50)) + { + IF( (st->perc_bwddec >= perc_detect || (st->perc_bwddec >= perc_miss && st->last_flag_filter_NB)) && (sum16_fx(st->flag_buffer, WBcnt) != 0)) /*decision hysterysis*/ + { + st->cldfbSyn_fx->bandsToZero = sub( st->cldfbSyn_fx->no_channels, 10 ); + move16(); + st->last_flag_filter_NB = 1; + move16(); /*VAD processing must be dependent on hysterysis, as if hysterysis fails, but threshold passes, we dont want next vad frames to have NB only*/ + } + ELSE + { + st->last_flag_filter_NB = 0; + move16(); + } + } + ELSE + { + st->last_flag_filter_NB = 0; + move16(); + } + IF(sum16_fx(st->flag_buffer, WBcnt) == 0) + { + st->perc_bwddec = 0; + st->active_frame_cnt_bwddec = 0; + move16(); + st->total_frame_cnt_bwddec = 0; + move16(); + st->last_flag_filter_NB = 0; + move16(); + } + } + ELSE + { + IF(st->last_flag_filter_NB == 1) + { + st->cldfbSyn_fx->bandsToZero = st->last_active_bandsToZero_bwdec; + move16(); + } + st->total_frame_cnt_bwddec = add(st->total_frame_cnt_bwddec, 1); + if(GT_16(st->total_frame_cnt_bwddec, 500)) + { + st->total_frame_cnt_bwddec = 500; + move16(); + } + } + + st->last_active_bandsToZero_bwdec = st->cldfbSyn_fx->bandsToZero; + + return; +} diff --git a/lib_dec/ppp_dec_fx.c b/lib_dec/ppp_dec_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..9f15cfba8f8be2ce8bd19c1a5591664570a089cf --- /dev/null +++ b/lib_dec/ppp_dec_fx.c @@ -0,0 +1,359 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include +#include "options.h" +#include "prot_fx1.h" +#include "prot_fx2.h" +#include "rom_com.h" + + /*===================================================================*/ + /* FUNCTION : struct DTFS_fx::dequant_cw_fx () */ + /*-------------------------------------------------------------------*/ + /* PURPOSE : Dequantize QPPP prototype */ + /*-------------------------------------------------------------------*/ + /* INPUT ARGUMENTS : */ + /* _ (Word16) pl: previous lag */ + /* _ (Word16) p_idx: Power index */ + /* _ (Word16[]) a_idx: Amplitude indices, 2 words */ + /* _ (struct DTFS_fx) X : prototype in polar domain */ + /* (Word16) lag: length of prototype */ + /*-------------------------------------------------------------------*/ + /* OUTPUT ARGUMENTS : */ + /* _ (struct DTFS_fx) X : prototype in polar domain */ + /* (Word16) lag: length of prototype in time domain */ + /* (Word16 []) a: amplitude of harmonics, normalized */ + /* (Word16) Q: norm factor of a */ + /* _ (Word16[]) curr_erb: Quantized current ERB, Q13 */ + /*-------------------------------------------------------------------*/ + /* INPUT/OUTPUT ARGUMENTS : */ + /* _ (Word16[]) lasterb: ERB history for differential */ + /* quantization, Q13 */ + /* _ (Word16) Lgain: low band power history, log domain, Q11 */ + /* _ (Word16) Hgain: high band power history, log domain, Q11 */ + /*-------------------------------------------------------------------*/ + /* RETURN ARGUMENTS : _ None. */ + /*-------------------------------------------------------------------*/ + /* CALLED FROM : TX/RX */ + /*===================================================================*/ + +static void DTFS_dequant_cw_fx( + Word16 pl_fx, /* i : Previous lag */ + Word16 POWER_IDX_fx, /* i : POWER index */ + const Word16* AMP_IDX_fx, /* i : Amp Shape index */ + Word16* lastLgainD_fx, /* i/o: low band last gain */ + Word16* lastHgainD_fx, /* i/o: high band last gain */ + Word16* lasterbD_fx, /* i/o: last frame ERB vector */ + DTFS_STRUCTURE* X_fx, /* o : DTFS structure dequantized */ + Word16 num_erb_fx +) + +{ + Word16 tmp_fx, mfreq_fx[NUM_ERB_WB], curr_erb_fx[NUM_ERB_WB]; + const Word16* PowerCB_fx = NULL; + Word16 slot_fx[NUM_ERB_WB]; + Word16 Ql, Qh, n; + Word32 Ltemp_fx, logLag_fx; + Word16 exp, frac, exp1; + Word32 L_tmp, L_temp; + Word32 L_tmp2; + + IF(num_erb_fx == NUM_ERB_NB) + { + PowerCB_fx = PowerCB_NB_fx; + move16(); + } + ELSE IF(num_erb_fx == NUM_ERB_WB) + { + PowerCB_fx = PowerCB_WB_fx; + move16(); + } + + /* Amplitude Dequantization */ + + erb_add_fx(curr_erb_fx, X_fx->lag_fx, lasterbD_fx, pl_fx, AMP_IDX_fx, num_erb_fx); + + curr_erb_fx[0] = mult_r(curr_erb_fx[1], 9830);/* 0.3 inQ15 leaves curr_erb in Q13 */ + curr_erb_fx[sub(num_erb_fx, 2)] = mult_r(curr_erb_fx[sub(num_erb_fx, 3)], 9830);/* Q13 */ + + move16(); + + curr_erb_fx[sub(num_erb_fx, 1)] = 0; + + erb_slot_fx(X_fx->lag_fx, slot_fx, mfreq_fx, num_erb_fx); + + /* mfreq normalized (2.56) in Q15 */ + DTFS_erb_inv_fx(curr_erb_fx, slot_fx, mfreq_fx, X_fx, num_erb_fx); + + + /* Back up the lasterbD memory after power normalization */ + + DTFS_setEngyHarm_fx(236, 2828, 0, 2828, 1, 0, &Ql, X_fx); + DTFS_setEngyHarm_fx(2828, X_fx->upper_cut_off_freq_of_interest_fx, 2828, X_fx->upper_cut_off_freq_fx, 1, 0, &Qh, X_fx); + + /* Need to unify the Q factors of both bands */ + X_fx->Q = s_min(Ql, Qh); /* set Q factor to be the smaller one */ + n = sub(Ql, Qh); /* compare band Q factors */ + + + + + /* This logic adjusts difference between Q formats of both bands */ + IF(n < 0) + rshiftHarmBand_fx(X_fx, 2828, X_fx->upper_cut_off_freq_fx, n); + ELSE IF(n > 0) + rshiftHarmBand_fx(X_fx, 0, 2828, sub(Qh, Ql)); + + DTFS_to_erb_fx(*X_fx, lasterbD_fx); + + + /* Power Dequantization */ + + tmp_fx = shl(POWER_IDX_fx, 1); /* tmp=2*POWER_IDX */ +#ifdef BASOP_NOGLOB + *lastLgainD_fx = add_sat(*lastLgainD_fx, PowerCB_fx[tmp_fx]); /* Q11 */ + *lastHgainD_fx = add_sat(*lastHgainD_fx, PowerCB_fx[tmp_fx + 1]); /* Q11 */ +#else + *lastLgainD_fx = add(*lastLgainD_fx, PowerCB_fx[tmp_fx]); /* Q11 */ + *lastHgainD_fx = add(*lastHgainD_fx, PowerCB_fx[tmp_fx + 1]); /* Q11 */ +#endif + L_tmp = L_deposit_h(X_fx->lag_fx); /* Q16 */ + exp = norm_l(L_tmp); + L_tmp = L_shl(L_tmp, exp); + frac = Log2_norm_lc(L_tmp); + exp = sub(30, add(exp, 16)); + L_tmp = Mpy_32_16(exp, frac, 12330);/* Q13 */ /* 10*log10(2) in Q12*/ + Ltemp_fx = L_shl(L_tmp, 10);/* Q23 */ + + + logLag_fx = Mult_32_16(Ltemp_fx, 0x6666); /* logLag=log10(lag), Q26 */ + + Ltemp_fx = L_sub(L_shr(L_deposit_h(*lastLgainD_fx), 1), logLag_fx); /* Ltemp=Lgain-log10(lag), Q26 */ + + /* Lacc_fx=dsp_pow10(Ltemp_fx); : Lacc=10^Lgain/lag, Q15 */ + + L_tmp = Mult_32_16(Ltemp_fx, 27213); /* 3.321928 in Q13 */ + L_tmp = L_shr(L_tmp, 8); /* Q16 */ + frac = L_Extract_lc(L_tmp, &exp1); /* Extract exponent */ + L_tmp = Pow2(14, frac); + exp1 = sub(exp1, 14); +#ifdef BASOP_NOGLOB + L_temp = L_shl_sat(L_tmp, add(exp1, 15) ); /* Q15 */ +#else + L_temp = L_shl(L_tmp, add(exp1, 15)); /* Q15 */ +#endif + L_tmp2 = L_temp; + if (GE_32(L_temp, 2147483647)) + { + L_temp = L_shl(L_tmp, 15); /*Q(15-exp1) */ + } + + n = norm_l(L_temp); + Ltemp_fx = L_shl(L_temp, n); /* Ltemp in Q(15+n) or Q(15 - exp1 +n) */ + + IF(GE_32(L_tmp2, 2147483647)) + { + DTFS_setEngyHarm_fx(236, 2828, 0, 2828, Ltemp_fx, add(15, sub(n, exp1)), &Ql, X_fx); + } + ELSE + { + DTFS_setEngyHarm_fx(236, 2828, 0, 2828, Ltemp_fx, add(15,n), &Ql, X_fx); + } + + Ltemp_fx = L_sub(L_shr(L_deposit_h(*lastHgainD_fx), 1), logLag_fx); /* Ltemp=Hgain-log10(lag), Q26 */ + /* Lacc_fx=dsp_pow10(Ltemp_fx); : Lacc=10^Hgain/lag, Q15 */ + L_tmp = Mult_32_16(Ltemp_fx, 27213); /* 3.321928 in Q13 */ /* Q24 */ + L_tmp = L_shr(L_tmp, 8); /* Q16 */ + frac = L_Extract_lc(L_tmp, &exp1); /* Extract exponent */ + L_tmp = Pow2(14, frac); + exp1 = sub(exp1, 14); + L_temp = L_shl(L_tmp, exp1 + 15); /* Q15 */ + + L_tmp2 = L_temp; + if (GE_32(L_temp, 2147483647)) + { + L_temp = L_shl(L_tmp, 15); /*Q(15-exp1) */ + } + + + n = norm_l(L_temp); + Ltemp_fx = L_shl(L_temp, n); /* Ltemp in Q(15+n) or Q(15 - exp1 +n) */ + + IF(GE_32(L_tmp2, 2147483647)) + { + DTFS_setEngyHarm_fx(2828, X_fx->upper_cut_off_freq_of_interest_fx, 2828, X_fx->upper_cut_off_freq_fx, Ltemp_fx, add(15, sub(n, exp1)), &Qh, X_fx); + } + ELSE + { + DTFS_setEngyHarm_fx(2828, X_fx->upper_cut_off_freq_of_interest_fx,2828, X_fx->upper_cut_off_freq_fx, Ltemp_fx, add(15, n), &Qh, X_fx); + } + + + /* Need to unify the Q factors of both bands */ + X_fx->Q = s_min(Ql, Qh); /* set Q factor to be the smaller one */ + n = sub(Ql, Qh); /* compare band Q factors */ + + + + IF(n < 0) + rshiftHarmBand_fx(X_fx, 2828, X_fx->upper_cut_off_freq_fx, n); + ELSE IF(n > 0) + rshiftHarmBand_fx(X_fx, 0, 2828, sub(Qh, Ql)); +} +/*===================================================================*/ +/* FUNCTION : void ppp_quarter_decoder_fx () */ +/*-------------------------------------------------------------------*/ +/* PURPOSE : */ +/*-------------------------------------------------------------------*/ +/* INPUT ARGUMENTS : */ +/* _ Word16 bfi_fx - Q0 bad frame indicator */ +/* _ const Word16 *curr_lpc_fx - Q12 current frame LPC */ +/* _ Word16 *exc_fx - Q0 previous frame excitation */ +/* _ Word16 prevCW_lag_fx - Q0 Previous lag */ +/* _ (struct DTFS_fx) PREV_CW_D_FX : prototype in polar domain */ +/* (Word16) lag: length of prototype in time domain */ +/* (Word16 []) a: amplitude of harmonics, normalized */ +/* (Word16) Q: norm factor of a */ +/*-------------------------------------------------------------------*/ +/* OUTPUT ARGUMENTS : */ +/* _ Decoder_State_fx *st_fx: */ +/* _ Word16 *pitch - Q6 floating pitch values for each subframe */ +/* _ Word16 *out_fx - Q0 residual signal */ +/*-------------------------------------------------------------------*/ +/* INPUT/OUTPUT ARGUMENTS : */ +/* _ Decoder_State_fx *st_fx: */ +/* _ lsp_old_fx - Q15 */ +/* _ st_fx->dtfs_dec_xxxx */ +/* _ gainp_ppp Q14 */ +/* _ lastLgainD_fx - Q11 */ +/* _ lastHgainD_fx - Q11 */ +/* _ lasterbD_fx - Q13 */ +/* _ (struct DTFS_fx) CURRCW_Q_DTFS_FX : prototype in polar domain*/ +/* (Word16) lag: length of prototype in time domain */ +/* (Word16 []) a: amplitude of harmonics, normalized */ +/* (Word16) Q: norm factor of a */ +/* _ Word16 *pitch_buf_fx - Q6 fixed pitch values for each subframe */ +/* _ Word16 *exc_fx - Q0 previous frame excitation */ +/*-------------------------------------------------------------------*/ +/* RETURN ARGUMENTS : */ +/* _ None */ +/*-------------------------------------------------------------------*/ +/* CALLED FROM : RX */ +/*===================================================================*/ +ivas_error ppp_quarter_decoder_fx( + DTFS_STRUCTURE *CURRCW_Q_DTFS_FX, /* i/o: Current CW DTFS */ + Word16 prevCW_lag_fx, /* i : Previous lag */ + Word16 *lastLgainD_fx, /* i/o: Last gain lowband Q11 */ + Word16 *lastHgainD_fx, /* i/o: Last gain highwband Q11 */ + Word16 *lasterbD_fx, /* i/o: Last ERB vector Q13 */ + Word16 bfi, /* i : FER flag */ + Word16 *S_fx, /* i : sine table, Q15 */ + Word16 *C_fx, /* i : cosine table, Q15 */ + DTFS_STRUCTURE PREV_CW_D_FX, /* i : Previous DTFS */ + Decoder_State *st_fx +) +{ + DTFS_STRUCTURE *PREVDTFS_FX; + Word16 AMP_IDX_fx[2]; + Word16 temp_pl_fx = prevCW_lag_fx, temp_l_fx = CURRCW_Q_DTFS_FX->lag_fx; + Word16 temp_fx; + Word16 l_fx = CURRCW_Q_DTFS_FX->lag_fx; + Word16 POWER_IDX_fx; + Word16 Erot_fx = 0; + Word16 num_erb_fx = 24; + Word32 temp32d_fx,temp32n_fx; + Word32 L_tmp, L_tmp1; + Word16 tmp, exp; + ivas_error error; + + error = IVAS_ERR_OK; + move16(); + IF ((error = DTFS_new_fx(&PREVDTFS_FX)) != IVAS_ERR_OK) + { + return error; + } + + IF ( EQ_16(CURRCW_Q_DTFS_FX->upper_cut_off_freq_fx,4000 )) + { + num_erb_fx = 22; + move16(); + } + ELSE IF ( EQ_16(CURRCW_Q_DTFS_FX->upper_cut_off_freq_fx,6400)) + { + num_erb_fx = 24; + move16(); + } + + DTFS_copy_fx(PREVDTFS_FX, PREV_CW_D_FX); + IF (bfi == 0) + { + POWER_IDX_fx =(Word16) get_next_indice( st_fx, 6); + move16(); + AMP_IDX_fx[0] =(Word16) get_next_indice( st_fx, 6); + move16(); + AMP_IDX_fx[1] =(Word16) get_next_indice( st_fx, 6); + move16(); + + /* Amplitude Dequantization */ + /*This normalization and de-normalization is done to avoid division by 12800. And this logic is used only in + dequant_cw. So upper cut-off frequencies need to be multiplied by a factor2.56. + This logic of normalisation is not employed in adjustlag, hence denormalisation is necessury.*/ + /*As the upper cut of freqencies are normalized to 12800, we have to multiply upper cut off freq by + 2.56(1/12800 in Q15) */ + temp32n_fx = L_mult(CURRCW_Q_DTFS_FX->upper_cut_off_freq_fx,10486);/* Q0+Q27 = Q28 */ + CURRCW_Q_DTFS_FX->upper_cut_off_freq_fx = (Word16)L_shr(temp32n_fx,13);/*Q15 */ + temp32n_fx = L_mult(CURRCW_Q_DTFS_FX->upper_cut_off_freq_of_interest_fx,10486);/* Q0+Q27 = Q28 */ + CURRCW_Q_DTFS_FX->upper_cut_off_freq_of_interest_fx = (Word16)L_shr(temp32n_fx,13);/*Q15 */ + + DTFS_dequant_cw_fx(prevCW_lag_fx,POWER_IDX_fx,AMP_IDX_fx,lastLgainD_fx,lastHgainD_fx,lasterbD_fx,CURRCW_Q_DTFS_FX,num_erb_fx); + /*De-normalize cut off frequencies */ + + temp32n_fx = L_shl((Word32)CURRCW_Q_DTFS_FX->upper_cut_off_freq_fx,13);/*Q28 */ + CURRCW_Q_DTFS_FX->upper_cut_off_freq_fx = (Word16)find_remd(temp32n_fx, 20971,&temp32d_fx); + temp32n_fx = L_shl((Word32)CURRCW_Q_DTFS_FX->upper_cut_off_freq_of_interest_fx,13);/*Q28 */ + CURRCW_Q_DTFS_FX->upper_cut_off_freq_of_interest_fx = (Word16)find_remd(temp32n_fx, 20971,&temp32d_fx); + } + + /* Copying phase spectrum over */ + DTFS_adjustLag_fx(PREVDTFS_FX,l_fx); + + temp_fx = sub(L_FRAME,temp_l_fx); /*Q0 */ + + exp = norm_s(temp_pl_fx); + tmp = div_s(shl(1,sub(14,exp)),temp_pl_fx); /*Q(29-exp) */ + L_tmp = L_mult(temp_fx,tmp); /*Q(31-exp); +1 due to /2 */ + L_tmp = L_shl(L_tmp,sub(exp,15)); /*Q16 */ + + exp = norm_s(temp_l_fx); + tmp = div_s(shl(1,sub(14,exp)),temp_l_fx); /*Q(29-exp) */ + L_tmp1 = L_mult(temp_fx,tmp); /*Q(31-exp); +1 due to /2 */ + L_tmp1 = L_shl(L_tmp1,sub(exp,15)); /*Q16 */ + + L_tmp = L_add(L_tmp,L_tmp1); /*Q16 */ + + tmp = lshr(extract_l(L_tmp),1); /*Q15 */ + L_tmp = L_mult(temp_l_fx,tmp); /*Q16 */ + temp_fx = rint_new_fx(L_tmp); + Erot_fx = sub(temp_l_fx,temp_fx); /*Q0 */ + + Q2phaseShift_fx(PREVDTFS_FX,shl(Erot_fx,2),CURRCW_Q_DTFS_FX->lag_fx,S_fx,C_fx); + IF ( EQ_16(bfi,1)) + { + DTFS_car2pol_fx(CURRCW_Q_DTFS_FX); + } + /*Phase copying is done through copy_phase instead of car2pol and pol2car */ + copy_phase_fx(PREVDTFS_FX,*CURRCW_Q_DTFS_FX,CURRCW_Q_DTFS_FX); + + { + temp_fx = (Word16) get_next_indice( st_fx, 3 ); + + temp_fx = sub(temp_fx,3); + temp_fx = shl(temp_fx,2);/*Q2 */ + Q2phaseShift_fx(CURRCW_Q_DTFS_FX,temp_fx,CURRCW_Q_DTFS_FX->lag_fx,S_fx,C_fx); + } + + count_free(PREVDTFS_FX); + return error; +} + diff --git a/lib_dec/pvq_core_dec_fx.c b/lib_dec/pvq_core_dec_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..634215f08fc0002a0b8724613abcb489a95850ab --- /dev/null +++ b/lib_dec/pvq_core_dec_fx.c @@ -0,0 +1,587 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include +#include "options.h" /* Compilation switches */ +#include "cnst.h" /* Common constants */ +#include "prot_fx1.h" /* Function prototypes */ +#include "prot_fx2.h" /* Function prototypes */ +#include "rom_com.h" /* Static table prototypes */ + +/*-------------------------------------------------------------------* + * Local prototypes + * + *-------------------------------------------------------------------*/ +static Word16 get_pvq_splits_fx(Decoder_State* st_fx, PVQ_DEC_HANDLE hPVQ, const Word16 band_bits, const Word16 sfmsize, Word16* bits); +static void densitySymbolIndexDecode_fx(Decoder_State* st_fx, PVQ_DEC_HANDLE hPVQ, const Word16 density, const Word16 opp_sz, const Word16 near_sz, Word16* index_phi); +/*-------------------------------------------------------------------* + * pvq_decode_band() + * + *-------------------------------------------------------------------*/ +static void pvq_decode_band_fx( + Decoder_State *st_fx, /* i/o: Decoder state */ + PVQ_DEC_HANDLE hPVQ, /* i/o: PVQ decoder handle */ + Word16* pulse_vector, /* i/o: decoded integer shape vector */ + Word16* npulses, /* i/o: number of pulses */ + Word16* coefs_quant, /* i/o: decoded coefficients buffer */ + const Word16 sfmsize, /* i : band length */ + const Word16 band_bits, /* i : assigned bit budget */ + Word16* bits_left, /* i/o: number of bits / bits remaining */ + const Word16 strict_bits /* i : Conservative rounding flag */ +) +{ + + Word16 K_val; + + Word16 j, Np; + Word16 part_start[MAX_SPLITS+1], dim_part[MAX_SPLITS+1], bits_part[MAX_SPLITS+1]; + Word16 pool_tot, pool_part, dim_parts; + Word16 g_part[MAX_SPLITS]; + Word16 g_part_neg[MAX_SPLITS]; + Word16 sg_part[MAX_SPLITS+1]; + Word16 idx_sort[MAX_SPLITS+1]; + Word16 js, band_bits_tot, split_bit; + + Np = get_pvq_splits_fx(st_fx, hPVQ, band_bits, sfmsize, &split_bit); + band_bits_tot = sub(band_bits, split_bit); + + dim_parts = extract_h(L_mult(negate(sfmsize),lim_neg_inv_tbl_fx[Np])); + set16_fx(dim_part, dim_parts, sub(Np, 1)); + dim_part[Np-1] = sub(sfmsize, i_mult2(dim_parts, sub(Np, 1))); + move16(); + + part_start[0] = 0; + move16(); + FOR (j = 1; j < Np; j++) + { + part_start[j] = add(part_start[j-1], dim_part[j-1]); + move16(); + } + + /* Encode energies */ + set16_fx( g_part_neg, -32768, Np ); + IF( GT_16(Np, 1)) + { + decode_energies_fx( st_fx, hPVQ, Np, dim_part, bits_part, g_part_neg, band_bits_tot, bits_left, sfmsize, strict_bits ); + } + ELSE + { + bits_part[0] = band_bits_tot; + move16(); + } + + pool_tot = 0; + move16(); + pool_part = 0; + move16(); + BASOP_SATURATE_WARNING_OFF_EVS + FOR (j = 0; j < Np; j++) + { + g_part[j] = negate(g_part_neg[j]); + } + BASOP_SATURATE_WARNING_ON_EVS + srt_vec_ind16_fx(g_part, sg_part, idx_sort, Np); + FOR(j = 0; j < Np; j++) + { + js = idx_sort[Np-1-j]; + pool_part = shrtCDivSignedApprox(pool_tot, sub(Np, j) ); + bits_part[js] = s_max(0, s_min(add(bits_part[js], pool_part), 256)); + move16(); + + conservativeL1Norm_fx(dim_part[js],bits_part[js], strict_bits, *bits_left, pool_tot , *npulses, /* inputs */ + &K_val, bits_left, &pool_tot, npulses); /* outputs */ + + IF( K_val > 0 ) + { + + pvq_decode_fx(st_fx, hPVQ, coefs_quant + part_start[js], pulse_vector + part_start[js], + K_val, dim_part[js], g_part_neg[js]); + } + ELSE + { + set16_fx(coefs_quant + part_start[js], 0, dim_part[js]); + set16_fx(pulse_vector + part_start[js], 0, dim_part[js]); + } + } + + return; +} + +void pvq_decode_frame_fx( + Decoder_State *st_fx, + Word16 *coefs_quant, /* o : quantized coefficients */ + Word16 *npulses, /* o : number of pulses per band */ + Word16 *pulse_vector, /* o : non-normalized pulse shapes */ + const Word16 *sfm_start, /* i : indices of first coefficients in the bands */ + const Word16 *sfm_end, /* i : indices of last coefficients in the bands */ + const Word16 *sfmsize, /* i : band sizes */ + const Word16 nb_sfm, /* i : total number of bands */ + const Word16 *R, /* i : bitallocation per band */ + const Word16 pvq_bits, /* i : number of bits avaiable */ + const Word16 core /* i : core */ +) +{ + Word16 i, j; + Word16 band_bits, bits_left; + Word16 bit_pool = 0; + Word16 coded_bands, bands_to_code; + Word16 bits; + Word16 R_sort[NB_SFM]; + Word16 is, i_sort[NB_SFM]; + Word16 strict_bits; + PVQ_DEC_DATA pvq_dec; + PVQ_DEC_HANDLE hPVQ = &pvq_dec; + + rc_dec_init_fx(st_fx, hPVQ, pvq_bits); + + bits = shl(sub(pvq_bits, RC_BITS_RESERVED), 3); + + bands_to_code = 0; + move16(); + FOR (i = 0; i < nb_sfm; i++) + { + if (R[i] > 0) + { + bands_to_code = add(bands_to_code, 1); + } + } + + IF (core == ACELP_CORE) + { + strict_bits = PVQ_CONS; + move16(); + srt_vec_ind16_fx (R, R_sort, i_sort, nb_sfm); + } + ELSE + { + strict_bits = PVQ_NEAREST; + move16(); + FOR (i = 0; i < nb_sfm; i++) + { + i_sort[i] = i; + move16(); + } + } + + coded_bands = 0; + move16(); + FOR (i = 0; i < nb_sfm; i++) + { + is = i_sort[i]; + move16(); + IF(R[is] > 0) + { + bandBitsAdjustment_fx(hPVQ->rc_num_bits, hPVQ->rc_range, bits, bands_to_code, bands_to_code-coded_bands, sfmsize[is] ,R[is], bit_pool, /* inputs */ + &band_bits, &bits_left, &bit_pool); /* outputs */ + + pvq_decode_band_fx( st_fx, hPVQ, &pulse_vector[sfm_start[is]], &npulses[is], + &coefs_quant[sfm_start[is]], sfmsize[is], band_bits, + &bits_left, strict_bits); + + /* Updates */ + coded_bands = add(coded_bands, 1); + } + ELSE + { + FOR (j = sfm_start[is]; j < sfm_end[is]; j++) + { + coefs_quant[j] = 0; + move16(); + pulse_vector[j] = 0; + move16(); + } + } + } + + rc_dec_finish_fx(st_fx, hPVQ); +} + +/*-------------------------------------------------------------------* + * pvq_core_dec() + * + *-------------------------------------------------------------------*/ + +Word16 pvq_core_dec_fx( + Decoder_State *st_fx, + const Word16 *sfm_start, + const Word16 *sfm_end, + const Word16 *sfmsize, + Word16 coefs_quant[], /* o : output MDCT */ + Word16 *Q_coefs, + Word16 bits_tot, + Word16 nb_sfm, + Word16 *R, /* Q3 */ + Word16 *Rs, + Word16 *npulses, + Word16 *maxpulse, + const Word16 core +) +{ + Word16 i; + Word16 R_upd; + Word16 ord[NB_SFM_MAX]; + Word16 pulse_vector[L_FRAME48k]; + Word16 pvq_bits; + Word16 gain_bits_array[NB_SFM]; + Word16 fg_pred[NB_SFM_MAX]; + + IF (st_fx->hHQ_core != NULL) + { + st_fx->hHQ_core->ber_occured_in_pvq = 0; + move16(); + } + + R_upd = shl(bits_tot, 3); + assign_gain_bits_fx( core, nb_sfm, sfmsize, R, gain_bits_array, &R_upd ); + + pvq_bits = shr(R_upd, 3); + + pvq_decode_frame_fx(st_fx, coefs_quant, npulses, pulse_vector, sfm_start, + sfm_end, sfmsize, nb_sfm, R, pvq_bits, core ); + + IF( Rs != NULL ) + { + FOR(i = 0; i < nb_sfm; i++) + { + if (npulses[i] <= 0) + { + Rs[i] = 0; + move16(); /* Update Rs in case no pulses were assigned */ + } + } + } + + FOR (i=0; i < nb_sfm; i++) + { + ord[i] = i; + move16(); + if (npulses[i] <= 0) + { + R[i] = 0; + move16(); /* Update in case no pulses were assigned */ + } + } + + get_max_pulses_fx( sfm_start, sfm_end, ord, npulses, nb_sfm, pulse_vector, maxpulse ); + + fine_gain_pred_fx( sfm_start, sfm_end, sfmsize, ord, npulses, maxpulse, R, + nb_sfm, coefs_quant, pulse_vector, fg_pred, core ); + + fine_gain_dec_fx( st_fx, ord, nb_sfm, gain_bits_array, fg_pred); + IF(st_fx->hHQ_core != NULL) + { + IF(st_fx->hHQ_core->ber_occured_in_pvq != 0) + { + set16_fx(fg_pred, 1, nb_sfm); /* low complex ECU action in case of detetected BER in PVQ decoding */ + } + } + apply_gain_fx(ord, sfm_start, sfm_end, nb_sfm, fg_pred, coefs_quant); + *Q_coefs = 12; + + return bits_tot; +} + +/*-------------------------------------------------------------------* + * decode_energies() + * + *-------------------------------------------------------------------*/ +void decode_energies_fx( + Decoder_State *st_fx, + PVQ_DEC_HANDLE hPVQ, /* i/o: PVQ decoder handle */ + Word16 Np, + Word16 *dim_part, + Word16 *bits_part, + Word16 *g_part, /* Q15 */ + short qband, + Word16 *bits_left, + Word16 dim, + const Word16 strict_bits +) +{ + Word16 density; + Word16 i, l_Np, r_Np; + Word16 l_bits, r_bits, l_dim, r_dim; + Word16 il, ir; + Word16 oppRQ3, qzero; + Word16 l_gain, r_gain; + Word16 index_phi=-1; + + l_Np = shr(Np, 1); + r_Np = sub(Np, l_Np); + + l_bits = 0; + move16(); + l_dim = 0; + move16(); + FOR (i = 0; i < l_Np; i++) + { + l_dim = add(l_dim, dim_part[i]); + } + r_dim = sub(dim, l_dim); + + obtainEnergyQuantizerDensity_fx(dim, qband, &density); + rangeCoderFinalizationFBits_fx(hPVQ->rc_num_bits, hPVQ->rc_range, &qzero); + + densitySymbolIndexDecode_fx( st_fx, hPVQ, density, r_dim, l_dim, &index_phi); + densityAngle2RmsProjDec_fx(density, index_phi, &ir, &il, &oppRQ3); + + + + + l_gain = il; /* Q15 */ move16(); + r_gain = ir; /* Q15 */ move16(); + + FOR (i = 0; i < l_Np; i++) + { + g_part[i] = mult_r(l_gain, g_part[i]); + move16(); + } + + FOR (i = l_Np; i < Np; i++) + { + g_part[i] = mult_r(r_gain, g_part[i]); + move16(); + } + + NearOppSplitAdjustment_fx( qband, qzero, hPVQ->rc_num_bits, hPVQ->rc_range, *bits_left, + strict_bits, Np, dim_part[0], dim_part[Np-1], + l_dim, r_dim, oppRQ3, + &l_bits, &r_bits, bits_left); + + + IF (GT_16(l_Np, 1)) + { + decode_energies_fx( st_fx, hPVQ, l_Np, dim_part, bits_part, g_part, l_bits, bits_left, l_dim, strict_bits ); + } + ELSE + { + bits_part[0] = l_bits; + move16(); + } + + IF (GT_16(r_Np, 1)) + { + decode_energies_fx( st_fx, hPVQ, r_Np, &dim_part[l_Np], &bits_part[l_Np], &g_part[l_Np], r_bits, bits_left, r_dim, strict_bits ); + } + ELSE + { + bits_part[1] = r_bits; + move16(); + } + + return; +} + +/*-------------------------------------------------------------------* + * densitySymbolIndexDecode() + * + *-------------------------------------------------------------------*/ +static void densitySymbolIndexDecode_fx( + Decoder_State *st_fx, + PVQ_DEC_HANDLE hPVQ, /* i/o: PVQ decoder handle */ + const Word16 density, + const Word16 opp_sz, + const Word16 near_sz, + Word16 *index_phi +) +{ + Word16 density1, density2; + Word32 tmp1; + Word16 tmp2; + Word16 c, density_alpha, density_c; + Word32 sym_freq, cum_freq, tot, dec_freq; + Word16 angle, expo, r; + UWord16 lsb; + Word32 acc; + Word16 alpha=0; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + IF( s_and((Word16)0xFFFE, density) == 0 ) + { + /* odd density exit */ + *index_phi = -1; + return; + } + + sym_freq = L_deposit_l(1); + + angle = atan2_fx(SQRT_DIM_fx[opp_sz], SQRT_DIM_fx[near_sz]); +#ifdef BASOP_NOGLOB + angle = shl_o(angle, 1, &Overflow); +#else + angle = shl(angle, 1); +#endif + angle = mult_r(angle, 20861); + c = mult_r(density, angle); + density_c = sub(density, c); + + tot = L_mac0(1L, density, add(density, 1)); + IF (c == 0) + { + dec_freq = rc_decode_fx(&st_fx->BER_detect, hPVQ, tot); + + density1 = add(density, 1); + acc = L_mult0(density1, density1); + acc = L_sub(acc, dec_freq); + alpha = add(getSqrtWord32(acc), density1); + sym_freq = L_mac(1L, sub(density, alpha), 1); + cum_freq = L_mac0(L_mult(alpha, density), alpha, 1); + } + ELSE IF (EQ_16(c, density)) + { + dec_freq = rc_decode_fx(&st_fx->BER_detect, hPVQ, tot); + + alpha = getSqrtWord32(dec_freq); + sym_freq = L_add(L_shl(alpha, 1), 1); + cum_freq = L_mult0(alpha, alpha); + } + ELSE + { + acc = L_mult0(density, c); + Mpy_32_16_ss(acc, density_c, &acc, &lsb); + acc = L_or(L_shl(acc, 16), L_and(lsb, 0xffffL)); /* Concatenate acc and lsb forming 48 bits; upshift 16 bits; keep 32 MSB. */ + acc = L_shr(acc, 1); /* Compensate fractional mode multiply (Mpy_32_16_ss) */ + tot = L_add(L_add(acc, (Word32)density), 1L); + + dec_freq = rc_decode_fx(&st_fx->BER_detect, hPVQ, tot); + + acc = L_mult0(sub(density_c, 1), density_c); + Mpy_32_16_ss(acc, c, &acc, &lsb); + acc = L_or(L_shl(acc, 16), L_and(lsb, 0xffffL)); /* Concatenate acc and lsb forming 48 bits; upshift 16 bits; keep 32 MSB. */ + acc = L_shr(acc, 1); /* Compensate fractional mode multiply (Mpy_32_16_ss) */ + acc = L_add(acc, L_add(density, 1)); + acc = L_sub(acc, L_add(c, 1)); + acc = L_sub(tot, acc); + IF (LT_32(dec_freq, acc )) + { + acc = L_add((Word32)density_c, L_shl(dec_freq, 2)); + acc = L_sub(acc, 2); + Mpy_32_16_ss(acc, density_c, &acc, &lsb); + acc = L_or(L_shl(acc, 16), L_and(lsb, 0xffffL)); /* Concatenate acc and lsb forming 48 bits; upshift 16 bits; keep 32 MSB. */ + acc = L_shr(acc, 1); /* Compensate fractional mode multiply (Mpy_32_16_ss) */ + acc = L_add(acc, 1); + tmp2 = getSqrtWord32(acc); + acc = L_add(density_c, tmp2); + acc = L_sub(acc, 1); + r = ratio(acc, L_shl(density_c,1), &expo); + alpha = shr(r, add(14, expo)); + + acc = L_mult(alpha, density_c); + sym_freq = L_add(acc, 1); + acc = L_mult0(sub(alpha, 1), density_c); + acc = L_add(acc, 1); + cum_freq = L_mult0(alpha, extract_l(acc)); + } + ELSE + { + density1 = add(density, 1); + density2 = add(shl(density, 1), 1); + + acc = L_mult0(density, density1); + Mpy_32_16_ss(acc, c, &acc, &lsb); + acc = L_or(L_shl(acc, 16), L_and(lsb, 0xffffL)); /* Concatenate acc and lsb forming 48-bit; upshift 16 bits; keep 32 MSB. */ + acc = L_shr(acc, 1); /* Compensate fractional mode multiply (Mpy_32_16_ss) */ + acc = L_add(density1, acc); + acc = L_add(dec_freq, acc); + acc = L_sub(tot, acc); + Mpy_32_16_ss(acc, c, &acc, &lsb); + acc = L_or(L_shl(acc, 16), L_and(lsb, 0xffffL)); + acc = L_shr(acc, 1 - 2); + + tmp2 = extract_l(L_mac0(1L, c, density2)); + tmp1 = L_mult0(tmp2, tmp2); + tmp1 = L_add(tmp1, acc); + tmp2 = getSqrtWord32(tmp1); /* floor */ + if (L_msu0(tmp1, tmp2, tmp2) != 0) + { + tmp2 = add(tmp2, 1); /* convert to ceil */ + } + + acc = L_mult0(c, density2); + acc = L_add(acc, 1); + acc = L_sub(acc, tmp2); + r = ratio(acc, L_shl(c, 1), &expo); + alpha = shr(r, add(14, expo)); + + density_alpha = sub(density, alpha); + sym_freq = L_mac(1L, density_alpha, c); + acc = L_mult0(density_alpha, add(density_alpha, 1)); + Mpy_32_16_ss(acc, c, &acc, &lsb); + acc = L_or(L_shl(acc, 16), L_and(lsb, 0xffffL)); /* Concatenate acc and lsb forming 48-bit; upshift 16 bits; keep 32 MSB. */ + acc = L_shr(acc, 1); /* Compensate fractional mode multiply (Mpy_32_16_ss) */ + acc = L_sub(acc, alpha); + acc = L_add(acc, density1); + cum_freq = L_sub(tot, acc); + } + } + + rc_dec_update_fx(st_fx, hPVQ, cum_freq, sym_freq); + *index_phi = alpha; + return; +} + + +/*--------------------------------------------------------------------------* + * get_pvq_splits() + * + * Retrieve the number of segments + *--------------------------------------------------------------------------*/ + +static Word16 get_pvq_splits_fx( /* o : Number of segments */ + Decoder_State *st_fx, /* i/o: Decoder state */ + PVQ_DEC_HANDLE hPVQ, /* i/o: PVQ decoder handle */ + const Word16 band_bits, /* i : Band bit budget */ + const Word16 sfmsize, /* i : Band width */ + Word16 *bits /* o : Used bits */ +) +{ + Word16 Np, i; + Word32 acc, flag; + + IF (band_bits == 0) + { + Np = 1; + move16(); + } + ELSE + { + acc = L_mult0(band_bits, 0x7a44); + Np = extract_l(L_shr(acc, 23)); /* Get integer part. */ + if (L_and(acc, 0x7fffffL) != 0) /* If fractional part != 0, add 1. */ + { + Np = add(Np, 1); /* ceiling operation */ + } + } + *bits = 0; + move16(); + IF (LT_16(Np, MAX_SPLITS)) + { + acc = L_mult0(8*THR_ADD_SPLIT, sfmsize); + IF (GT_32(band_bits, acc)) + { + flag = rc_dec_bits_fx(st_fx, hPVQ, 1); + *bits = 8; + move16(); + if (flag != 0) + { + Np = add(Np, 1); + } + } + } + /* Check constraints for number of splits */ + /* The following code assumes that PVQ_MAX_BAND_SIZE is 64 */ + i = shr(sfmsize, 6); /* 6 = log2(64) = log2(PVQ_MAX_BAND_SIZE) */ + if (s_and(sfmsize, 0x3f) != 0) + { + i = add(i, 1); /* ceiling operation */ + } + + Np = s_max(i, Np); + Np = s_min(MAX_SPLITS, Np); + Np = s_min(sfmsize, Np); /* The code line assumes that MIN_BAND_SIZE is 1 */ + return Np; +} + + diff --git a/lib_dec/pvq_decode_fx.c b/lib_dec/pvq_decode_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..52037000591142196e024866faf93cf16dcf2ec4 --- /dev/null +++ b/lib_dec/pvq_decode_fx.c @@ -0,0 +1,116 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include +#include "options.h" /* Compilation switches */ +#include "prot_fx1.h" +#include "prot_fx2.h" +#include "rom_com.h" + +/*-------------------------------------------------------------------* +* Function pvq_decode_fx() * +* * +* PVQ subvector decoding algorithm * +*-------------------------------------------------------------------*/ + +void pvq_decode_fx( + Decoder_State *st_fx, + PVQ_DEC_HANDLE hPVQ, /* i/o: PVQ decoder handle */ + Word16 *xq, /* o: decoded vector (Q15) */ + Word16 *y, /* o: decoded vector (non-scaled int) */ + const Word16 k_val, /* i: number of allocated pulses */ + const Word16 dim, /* i: Length of vector */ + const Word16 neg_gain /* i: Gain (negated to fit 1.0 in Q15 as -1.0) */ +) +{ + Word16 i; + + UWord32 h_mem[1+KMAX_NON_DIRECT_FX+1]; /* allocate max offset memory for dim 6 */ + + PvqEntry entry; + + Word16 neg_gain_norm, shift_num,shift_den,shift_tot; + Word32 L_yy,L_isqrt,L_tmp; + + UWord16 u16_tmp; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + + entry = get_size_mpvq_calc_offset_fx(dim, k_val, h_mem); /* get size & prepare H(adaptive table for entry.size=N_MPVQ(dim,k_val) */ + + + IF( NE_16(dim, 1)) + { + entry.lead_sign_ind = (short)rc_dec_bits_fx(st_fx, hPVQ, 1); + entry.index = rc_dec_uniform_fx(st_fx, hPVQ, entry.size); + + IF(st_fx->hHQ_core != NULL) + { + /* safety check in case of bit errors */ + test(); + IF(GE_32(entry.index, entry.size) || st_fx->hHQ_core->ber_occured_in_pvq != 0) + { + st_fx->hHQ_core->ber_occured_in_pvq = 1; + move16(); + st_fx->BER_detect = 1; + move16(); + entry.index = 0; + move16(); /* a zero index will essentially disable PVQ index decompostion complexity */ + } + } + } + ELSE + { + entry.lead_sign_ind = (short)rc_dec_bits_fx(st_fx, hPVQ, 1); /* always a single sign bit */ + entry.index = L_deposit_l(0); + } + + mpvq_decode_vec_fx(&entry, h_mem, y); + + IF( neg_gain == 0 ) + { + FOR(i=0; i +#include "options.h" /* Compilation switches */ +#include "cnst.h" /* Common constants */ +#include "rom_com.h" /* Static table prototypes */ +#include "prot_fx1.h" /* Function prototypes */ +#include "prot_fx2.h" /* Function prototypes */ + + + +/*-------------------------------------------------------------------* + * Local prototypes + *-------------------------------------------------------------------*/ +static Word16 rc_dec_read_fx(Decoder_State *st_fx, PVQ_DEC_HANDLE hPVQ); +/*-------------------------------------------------------------------* + * rc_dec_init() + * + * Initialize range coder + *-------------------------------------------------------------------*/ + +void rc_dec_init_fx( + Decoder_State *st_fx, /* i/o: Decoder State */ + PVQ_DEC_HANDLE hPVQ, /* i/o: PVQ decoder handle */ + Word16 tot_bits /* i : Total bit budget */ +) +{ + Word16 i; + + hPVQ->rc_low = L_deposit_l(0); + hPVQ->rc_range = 0xffffffff; + move32(); + hPVQ->rc_num_bits = 0; + move16(); + hPVQ->rc_offset = add(tot_bits, st_fx->next_bit_pos); + hPVQ->rc_end = hPVQ->rc_offset; + move16(); + + FOR (i = 0; i < 4; i++) + { + hPVQ->rc_low = UL_addNsD(UL_lshl(hPVQ->rc_low, 8), UL_deposit_l(rc_dec_read_fx(st_fx, hPVQ))); + } +} + +/*-------------------------------------------------------------------* + * rc_decode() + * + * Decode symbol + *-------------------------------------------------------------------*/ + +UWord32 rc_decode_fx( /* o : Decoded cumulative frequency */ + Word16* BER_detect, /* o : Bit error detection flag */ + PVQ_DEC_HANDLE hPVQ, /* i/o: PVQ decoder handle */ + UWord32 tot /* i : Total cumulative frequency */ +) +{ + UWord32 inv, lsb, val, UL_tmp1, UL_tmp2; + Word16 exp_num, exp_den, exp; + UWord16 sgn; + + inv = UL_inverse(tot, &exp); + Mpy_32_32_uu(hPVQ->rc_range, inv, &(hPVQ->rc_help), &lsb);/*0+exp-32*/ + hPVQ->rc_help = UL_lshr(hPVQ->rc_help, sub(exp, 32)); + + exp_den = norm_ul(hPVQ->rc_help); + UL_tmp2 = UL_lshl(hPVQ->rc_help, exp_den); + exp_num = sub(norm_ul(hPVQ->rc_low), 1); + UL_tmp1 = UL_lshl(hPVQ->rc_low, exp_num); + exp = add(32, sub(exp_num, exp_den)); + + val = UL_div(UL_tmp1, UL_tmp2); + val = UL_lshr(val, exp); + + UL_tmp1 = UL_Mpy_32_32(val, hPVQ->rc_help); + UL_tmp2 = UL_Mpy_32_32(UL_addNsD(val, 1), hPVQ->rc_help); + UL_tmp1 = UL_subNsD(hPVQ->rc_low, UL_tmp1); + UL_tmp2 = UL_subNsD(hPVQ->rc_low, UL_tmp2); + if (UL_tmp2 < UL_tmp1) + { + val = UL_addNsD(val, 1); + } + + /* safety check in case of bit errors */ + UL_tmp1 = UL_subNs(tot,val,&sgn); + IF ( sgn != 0) + { + *BER_detect = 1; + move16(); + return 0; + } + + return val; +} + +/*-------------------------------------------------------------------* + * rc_dec_update() + * + * Update range coder + *-------------------------------------------------------------------*/ + +void rc_dec_update_fx( + Decoder_State *st_fx, /* i/o: Decoder State */ + PVQ_DEC_HANDLE hPVQ, /* i/o: PVQ decoder handle */ + UWord32 cum_freq, /* i : Cumulative frequency */ + UWord32 sym_freq /* i : Symbol frequency */ +) +{ + hPVQ->rc_low = UL_subNsD(hPVQ->rc_low, UL_Mpy_32_32(cum_freq, hPVQ->rc_help)); /*0+0*/ + hPVQ->rc_range = UL_Mpy_32_32(hPVQ->rc_help, sym_freq); + + WHILE (hPVQ->rc_range < 1<<24) + { + L_sub(0, 0); /* For comparision in while*/ + hPVQ->rc_num_bits = add(hPVQ->rc_num_bits, 8); + hPVQ->rc_low = UL_addNsD(UL_lshl(hPVQ->rc_low, 8), UL_deposit_l(rc_dec_read_fx(st_fx, hPVQ))); + hPVQ->rc_range = UL_lshl(hPVQ->rc_range, 8); + } +} + +/*-------------------------------------------------------------------* + * rc_dec_bits() + * + * Encode bits + *-------------------------------------------------------------------*/ + +Word32 rc_dec_bits_fx( /* i : Decoded value */ + Decoder_State *st_fx, /* i/o: Decoder State */ + PVQ_DEC_HANDLE hPVQ, /* i/o: PVQ decoder handle */ + Word16 bits /* i : Number of bits */ +) +{ + Word32 value; + + hPVQ->rc_num_bits = add(hPVQ->rc_num_bits, bits); + + IF (GT_16(bits, 16)) + { + hPVQ->rc_offset = sub(hPVQ->rc_offset, sub(bits, 16)); + value = UL_lshl(UL_deposit_l(get_indice(st_fx, hPVQ->rc_offset, sub(bits, 16))), 16); + hPVQ->rc_offset = sub(hPVQ->rc_offset, 16); + value = UL_or(value, UL_deposit_l(get_indice(st_fx, hPVQ->rc_offset, 16))); + } + ELSE + { + hPVQ->rc_offset = sub(hPVQ->rc_offset, bits); + value = UL_deposit_l(get_indice(st_fx, hPVQ->rc_offset, bits)); + } + + return value; +} + +/*-------------------------------------------------------------------* + * rc_dec_uniform() + * + * Encode with uniform distribution + *-------------------------------------------------------------------*/ + +UWord32 rc_dec_uniform_fx( /* i : Decoded value */ + Decoder_State *st_fx, /* i/o: Decoder State */ + PVQ_DEC_HANDLE hPVQ, /* i/o: PVQ decoder handle */ + UWord32 tot /* i : Maximum value */ +) +{ + UWord32 value; + Word16 n; + n = sub(32, norm_ul(tot - 1)); + + IF (LE_16(n, 8)) + { + value = rc_decode_fx(&st_fx->BER_detect, hPVQ, tot); + rc_dec_update_fx(st_fx, hPVQ, value, 1); + } + ELSE + { + n = sub(n, 8); + value = rc_decode_fx(&st_fx->BER_detect, hPVQ, UL_addNsD(UL_lshr(tot, n), 1)); + rc_dec_update_fx(st_fx, hPVQ, value, 1); + value = UL_lshl(value, n); + value = UL_or(value, rc_dec_bits_fx(st_fx, hPVQ, n)); + } + + return value; +} + +/*-------------------------------------------------------------------* + * rc_dec_finish() + * + * Finalize range decoder + *-------------------------------------------------------------------*/ + +void rc_dec_finish_fx( + Decoder_State *st_fx, /* i/o: Decoder state */ + PVQ_DEC_HANDLE hPVQ /* i/o: PVQ decoder handle */ +) +{ + st_fx->next_bit_pos = hPVQ->rc_end; +} + +/*-------------------------------------------------------------------* + * rc_dec_read() + * + * Read a byte from bit stream + *-------------------------------------------------------------------*/ + + +static Word16 rc_dec_read_fx( + Decoder_State* st_fx, /* i/o: Decoder state */ + PVQ_DEC_HANDLE hPVQ /* i/o: PVQ decoder handle */ +) +{ + Word16 bits; + + bits = sub(hPVQ->rc_end, st_fx->next_bit_pos ); + + /* If the end of the buffer has been reached, pad the last byte with zeros */ + IF(sub(bits, 8) < 0) + { + return shl(get_next_indice(st_fx, bits), sub(8, bits)); + } + ELSE + { + return get_next_indice(st_fx, 8); + } +} + diff --git a/lib_dec/re8_dec_fx.c b/lib_dec/re8_dec_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..3fabbede3d54fdc1cf798776cf4035fcb26a73b5 --- /dev/null +++ b/lib_dec/re8_dec_fx.c @@ -0,0 +1,73 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include +#include "options.h" /* Compilation switches */ +#include "prot_fx1.h" /* Function prototypes */ +#include "prot_fx2.h" /* Function prototypes */ + +/*-------------------------------------------------------------------------- +* re8_dec_fx() +* +* MULTI-RATE INDEXING OF A POINT y in THE LATTICE RE8 (INDEX DECODING) +* note: the index I is defined as a 32-bit word, but only +* 16 bits are required (long can be replaced by unsigned integer) +*--------------------------------------------------------------------------*/ + +void re8_dec_fx( + Word16 n, /* i : codebook number (*n is an integer defined in {0,2,3,4,..,n_max}) */ + const UWord16 I, /* i : index of c (pointer to unsigned 16-bit word) */ + const Word16 k[], /* i : index of v (8-dimensional vector of binary indices) = Voronoi index */ + Word16 y[] /* o : point in RE8 (8-dimensional integer vector) */ +) +{ + Word16 i, m, v[8]; + + /*------------------------------------------------------------------------* + * decode the sub-indices I and kv[] according to the codebook number n: + * if n=0,2,3,4, decode I (no Voronoi extension) + * if n>4, Voronoi extension is used, decode I and kv[] + *------------------------------------------------------------------------*/ + IF( LE_16(n, 4)) + { + re8_decode_base_index_fx( n, I, y ); + } + ELSE + { + /*--------------------------------------------------------------------* + * compute the Voronoi modulo m = 2^r where r is extension order + *--------------------------------------------------------------------*/ + m = 0; + move16(); + + FOR (; n > 4; n -= 2) + { + m = add(m, 1); + } + + /*--------------------------------------------------------------------* + * decode base codebook index I into c (c is an element of Q3 or Q4) + * [here c is stored in y to save memory] + *--------------------------------------------------------------------*/ + + re8_decode_base_index_fx( n, I, y ); + + /*--------------------------------------------------------------------* + * decode Voronoi index k[] into v + *--------------------------------------------------------------------*/ + re8_k2y_fx( k, m, v ); + + /*--------------------------------------------------------------------* + * reconstruct y as y = m c + v (with m=2^r, r integer >=1) + *--------------------------------------------------------------------*/ + FOR( i=0; i<8; i++ ) + { + /* y[i] = m*y[i] + v[i] */ + y[i] = add(shl(y[i], m), v[i]); + move16(); + } + } + + return; +} diff --git a/lib_dec/rom_dec.c b/lib_dec/rom_dec.c index 11661592f9469d82d6448bbc33c767a650d1ac6d..c86c3d5c883e12df20d9c565dbda32bc4c28ae55 100644 --- a/lib_dec/rom_dec.c +++ b/lib_dec/rom_dec.c @@ -47,7 +47,49 @@ *----------------------------------------------------------------------------------*/ const float h_low[5] = { -0.0125f, 0.1090f, 0.7813f, 0.1090f, -0.0125f }; - +const Word16 H_low[5] = +{ + -410, 3572, 25602, 3572, -410 +}; +const Word16 inv_sqi[15] = +{ + 8192, /* 1/4 */ + 3641, /* 1/9 */ + 2048, /* 1/16 */ + 1311, /* 1/25 */ + 910, /* 1/36 */ + 669, /* 1/49 */ + 512, /* 1/64 */ + 405, /* 1/81 */ + 328, /* 1/100 */ + 271, /* 1/121 */ + 228, /* 1/144 */ + 194, /* 1/169 */ + 167, /* 1/196 */ + 146, /* 1/225 */ + 128 /* 1/256 */ +}; +/*-------------------------------------------------------------------* + * index square used in fec_adapt_codebook + *-------------------------------------------------------------------*/ +const Word16 sqi[15] = +{ + 4, /* 2 */ + 9, /* 3 */ + 16, /* 4 */ + 25, /* 5 */ + 36, /* 6 */ + 49, /* 7 */ + 64, /* 8 */ + 81, /* 9 */ + 100, /* 10 */ + 121, /* 11 */ + 144, /* 12 */ + 169, /* 13 */ + 196, /* 14 */ + 225, /* 15 */ + 256 /* 16 */ +}; /* RE8 related tables */ const int16_t mult_avq_tab[7] = {1,1,1,342,1,1,171}; const int16_t shift_avq_tab[7] = {0,0,1, 10,2,0, 10}; @@ -83,11 +125,38 @@ const float lsf_tab[LPC_SHB_ORDER] = 0.070633653f, 0.11962059f, 0.16925794f, 0.20627696f, 0.24345790f, 0.31293656f, 0.34594478f, 0.38072862f, 0.410051247f, 0.44525622f }; +const Word16 lsf_tab_fx[LPC_SHB_ORDER] = +{ + 2315, 3920, 5546, 6759, 7978, + 10254, 11336, 12476, 13437, 14590 +}; +const Word16 POW_ATT_TABLE0[OFF_FRAMES_LIMIT + 1] = +{ + 32767, 31293, 29885, 28540, 27255, 26029, 24857, 23738, 22670, 21650, + 20675, 19745, 18856, 18007, 17197, 16423, 8211, 4106, 2053, 1026, + 513, 257, 128, 64, 32, 16, 8, 4, 2, 1, 0 +}; +const Word16 POW_ATT_TABLE1[OFF_FRAMES_LIMIT + 1] = +{ + 32767, 31656, 30581, 29543, 28540, 27571, 26635, 25731, 24857, 24013, + 23198, 22410, 21650, 20915, 20205, 19519, 9759, 4880, 2440, 1220, + 610, 305, 152, 76, 38, 19, 10, 5, 2, 1, 0 +}; /* frequency group start bins for transient analysis */ /* 125 375 750 1250 2000 4000 8000 16000 24000 */ const int16_t gw[LGW_MAX] = { 1, 3, 6, 10, 16, 32, 64, 128, 192 }; +const Word16 gw_fx[LGW_MAX] = { 1, 3, 6, 10, 16, 32, 64, 128, 192 }; /* frequency group start bins for transient analysis */ +const Word16 gw_len_inv_fx[LGW_MAX - 1] = /* Q15 */ +{ + 16384, 10923, 8192, 5461, + 2048, 1024, 512, 512, +}; +const Word16 GR_POW_HEADROOM[LGW_MAX] = /* in Q0-- Number of bits down-shifting to prevent from saturation in group power accumulation.*/ +{ + 0, 0, 1, 2, 2, 3, 4, 4, 4 +}; /* 31.25 343.75 718.75 1218.75 1968.75 4000 8000 16000 24000 */ const int16_t ivas_gwlpr[LGW_MAX] = { 1, 3*QUOT_LPR_LTR-1, 6*QUOT_LPR_LTR-1, 10*QUOT_LPR_LTR-1, 16*QUOT_LPR_LTR-1, 32*QUOT_LPR_LTR, 64*QUOT_LPR_LTR, 128*QUOT_LPR_LTR, 192*QUOT_LPR_LTR }; @@ -151,6 +220,66 @@ const float w_hamm16k_2[L_TRANA16k/2] = 0.968694973396140f, 0.976419069472435f, 0.983075174954342f, 0.988647001236375f, 0.993120913125941f, 0.996485962210947f, 0.998733913652397f, 0.999859266336418f }; +const Word16 w_hamm48k_2_fx[L_TRANA48k / 2] = +{ + 2621, 2623, 2630, 2640, 2654, 2672, 2694, 2721, + 2751, 2785, 2824, 2866, 2913, 2963, 3017, 3076, + 3138, 3204, 3274, 3348, 3426, 3507, 3593, 3682, + 3775, 3871, 3972, 4076, 4184, 4295, 4410, 4529, + 4651, 4777, 4906, 5039, 5175, 5314, 5457, 5603, + 5752, 5904, 6060, 6219, 6381, 6546, 6714, 6884, + 7058, 7235, 7414, 7596, 7781, 7969, 8159, 8352, + 8547, 8745, 8945, 9148, 9353, 9560, 9769, 9980, + 10194, 10409, 10627, 10846, 11067, 11290, 11515, 11741, + 11969, 12199, 12430, 12662, 12896, 13131, 13367, 13605, + 13843, 14083, 14323, 14565, 14807, 15050, 15294, 15538, + 15783, 16029, 16275, 16521, 16768, 17015, 17262, 17509, + 17757, 18004, 18251, 18498, 18745, 18991, 19238, 19483, + 19729, 19973, 20217, 20461, 20704, 20945, 21186, 21427, + 21666, 21904, 22140, 22376, 22611, 22844, 23075, 23306, + 23534, 23762, 23987, 24211, 24433, 24653, 24872, 25088, + 25303, 25515, 25725, 25934, 26140, 26343, 26545, 26744, + 26940, 27134, 27326, 27515, 27701, 27884, 28065, 28243, + 28419, 28591, 28760, 28927, 29090, 29250, 29408, 29562, + 29712, 29860, 30004, 30146, 30283, 30418, 30548, 30676, + 30800, 30920, 31037, 31150, 31260, 31366, 31468, 31567, + 31662, 31753, 31840, 31924, 32003, 32079, 32151, 32219, + 32283, 32344, 32400, 32452, 32501, 32545, 32585, 32622, + 32654, 32682, 32707, 32727, 32743, 32755, 32763, 32767 +}; + +const Word16 w_hamm32k_2_fx[L_TRANA32k / 2] = +{ + 2621, 2626, 2640, 2663, 2695, 2736, 2786, 2845, + 2913, 2991, 3077, 3172, 3276, 3388, 3509, 3639, + 3778, 3925, 4080, 4243, 4415, 4595, 4782, 4978, + 5181, 5392, 5610, 5836, 6069, 6309, 6555, 6809, + 7069, 7336, 7609, 7888, 8173, 8464, 8760, 9062, + 9369, 9681, 9998, 10319, 10646, 10976, 11310, 11649, + 11991, 12336, 12685, 13037, 13391, 13749, 14108, 14470, + 14834, 15199, 15566, 15935, 16304, 16674, 17045, 17416, + 17788, 18159, 18530, 18900, 19270, 19639, 20007, 20373, + 20738, 21101, 21461, 21820, 22176, 22529, 22879, 23226, + 23570, 23910, 24247, 24579, 24907, 25231, 25551, 25865, + 26175, 26479, 26778, 27072, 27360, 27642, 27918, 28188, + 28451, 28708, 28958, 29202, 29438, 29667, 29889, 30104, + 30311, 30510, 30702, 30886, 31061, 31229, 31388, 31539, + 31682, 31816, 31942, 32059, 32167, 32266, 32357, 32439, + 32511, 32575, 32630, 32675, 32712, 32739, 32758, 32767 +}; + +const Word16 w_hamm16k_2_fx[L_TRANA16k / 2] = +{ + 2621, 2640, 2695, 2787, 2916, 3080, 3281, 3516, + 3787, 4091, 4429, 4799, 5201, 5633, 6095, 6585, + 7102, 7646, 8214, 8805, 9418, 10051, 10703, 11371, + 12056, 12754, 13464, 14185, 14914, 15650, 16391, 17136, + 17881, 18626, 19369, 20108, 20841, 21566, 22282, 22986, + 23678, 24354, 25015, 25658, 26281, 26883, 27463, 28019, + 28549, 29053, 29529, 29976, 30393, 30780, 31134, 31455, + 31742, 31995, 32213, 32396, 32543, 32653, 32727, 32763 +}; + const float w_hamm_sana48k_2[L_PROT_HAMM_LEN2_48k] = { 0.080000000000000f, 0.080027462973758f, 0.080109848615839f, 0.080247147089046f, 0.080439341999361f, 0.080686410397899f, 0.080988322783646f, 0.081345043106986f, @@ -190,7 +319,45 @@ const float w_hamm_sana48k_2[L_PROT_HAMM_LEN2_48k] = 0.993417713086533f, 0.994237922201026f, 0.995003893384487f, 0.995715535176712f, 0.996372762604660f, 0.996975497192592f, 0.997523666971448f, 0.998017206487434f, 0.998456056809844f, 0.998840165538090f, 0.999169486807964f, 0.999443981297112f, 0.999663616229731f, 0.999828365380479f, 0.999938209077610f, 0.999993134205322f }; - +const Word16 w_hamm_sana48k_2_fx[288] = +{ + 2621, 2622, 2625, 2630, 2636, 2644, 2654, 2666, + 2679, 2694, 2711, 2730, 2751, 2773, 2797, 2823, + 2851, 2881, 2912, 2945, 2980, 3017, 3055, 3095, + 3137, 3180, 3226, 3273, 3321, 3372, 3424, 3478, + 3534, 3591, 3650, 3710, 3773, 3837, 3902, 3970, + 4039, 4109, 4181, 4255, 4330, 4407, 4486, 4566, + 4648, 4731, 4816, 4902, 4990, 5079, 5170, 5263, + 5357, 5452, 5549, 5647, 5747, 5848, 5950, 6054, + 6160, 6266, 6374, 6484, 6595, 6707, 6820, 6935, + 7051, 7168, 7287, 7406, 7527, 7650, 7773, 7898, + 8023, 8150, 8278, 8407, 8538, 8669, 8802, 8935, + 9070, 9205, 9342, 9479, 9618, 9758, 9898, 10040, + 10182, 10325, 10469, 10614, 10760, 10907, 11054, 11202, + 11351, 11501, 11652, 11803, 11955, 12108, 12261, 12415, + 12569, 12725, 12880, 13037, 13194, 13351, 13509, 13668, + 13827, 13986, 14146, 14306, 14467, 14628, 14789, 14951, + 15113, 15276, 15438, 15601, 15765, 15928, 16092, 16256, + 16420, 16584, 16748, 16913, 17077, 17242, 17406, 17571, + 17736, 17901, 18065, 18230, 18394, 18559, 18723, 18888, + 19052, 19216, 19379, 19543, 19706, 19870, 20032, 20195, + 20357, 20519, 20681, 20842, 21003, 21163, 21324, 21483, + 21642, 21801, 21959, 22117, 22274, 22431, 22587, 22742, + 22897, 23052, 23205, 23358, 23511, 23662, 23813, 23963, + 24113, 24261, 24409, 24556, 24702, 24848, 24992, 25136, + 25279, 25421, 25562, 25702, 25841, 25979, 26116, 26252, + 26387, 26521, 26654, 26786, 26917, 27047, 27175, 27303, + 27429, 27554, 27678, 27801, 27923, 28043, 28162, 28280, + 28397, 28512, 28626, 28739, 28850, 28960, 29069, 29177, + 29283, 29387, 29490, 29592, 29693, 29792, 29889, 29985, + 30080, 30173, 30265, 30355, 30444, 30531, 30616, 30700, + 30783, 30864, 30943, 31021, 31097, 31172, 31244, 31316, + 31386, 31454, 31520, 31585, 31648, 31710, 31769, 31827, + 31884, 31939, 31992, 32043, 32093, 32140, 32187, 32231, + 32274, 32315, 32354, 32391, 32427, 32461, 32493, 32524, + 32552, 32579, 32604, 32628, 32649, 32669, 32687, 32703, + 32717, 32730, 32741, 32750, 32757, 32762, 32766, 32767 +}; const float w_hamm_sana32k_2[L_PROT_HAMM_LEN2_32k] = { 0.080000000000000f, 0.080061898522781f, 0.080247577432747f, 0.080556986759243f, 0.080990043232791f, 0.081546630307495f, 0.082226598192408f, 0.083029763891845f, @@ -234,10 +401,36 @@ const float w_hamm_sana16k_2[L_PROT_HAMM_LEN2_16k] = 0.941486723514159f, 0.948653981707932f, 0.955379049234843f, 0.961654649126531f, 0.967473990768381f, 0.972830777247415f, 0.977719212165966f, 0.982134005913770f, 0.986070381391670f, 0.989524079180756f, 0.992491362151336f, 0.994969019506760f, 0.996954370257714f, 0.998445266123226f, 0.999440093855253f, 0.999937776984316f }; +const Word16 swb_hr_inv_frm_len[4] = /* in Q19 */ +{ + 26214, /* 1/(160/8) */ + 13107, /* 1/(320/8) */ + 6554, /* 1/(640/8) */ + 4369 /* 1/(960/8) */ +}; +const Word16 inv_tbl_2n_minus1[] = { -1, -1, /* Bits = 0 and 1 are not used */ + 21845/*Q16*/, + 18725/*Q17*/, + 17476/*Q18*/, + 16913/*Q19*/, + 16644/*Q20*/, + 16513/*Q21*/ +}; /* in Qx */ -/* er_dec_tcx.c */ -const float h_high3_32[L_FIR_FER2] = {-0.0517f, -0.0587f, -0.0820f, -0.1024f, -0.1164f, 0.8786f, -0.1164f, -0.1024f, -0.0820f, -0.0587f, -0.0517f}; -const float h_high3_16[L_FIR_FER2] = { 0.f, -0.0205f, -0.0651f, -0.1256f, -0.1792f, 0.8028f, -0.1792f, -0.1256f, -0.0651f, -0.0205f, 0.f }; +/* er_dec_tcx.c */ +const float h_high3_32_flt[L_FIR_FER2] = {-0.0517f, -0.0587f, -0.0820f, -0.1024f, -0.1164f, 0.8786f, -0.1164f, -0.1024f, -0.0820f, -0.0587f, -0.0517f}; +const float h_high3_16_flt[L_FIR_FER2] = { 0.f, -0.0205f, -0.0651f, -0.1256f, -0.1792f, 0.8028f, -0.1792f, -0.1256f, -0.0651f, -0.0205f, 0.f }; +const Word16 h_high3_32[L_FIR_FER2] = { -1694/*-0.0517f Q15*/, -1923/*-0.0587f Q15*/, -2687/*-0.0820f Q15*/, -3355/*-0.1024f Q15*/, -3814/*-0.1164f Q15*/, 28790/*0.8786f Q15*/, -3814/*-0.1164f Q15*/, -3355/*-0.1024f Q15*/, -2687/*-0.0820f Q15*/, -1923/*-0.0587f Q15*/, -1694/*-0.0517f Q15*/ }; +const Word16 h_high3_16[L_FIR_FER2] = { 0/* 0.f Q15*/, -672/*-0.0205f Q15*/, -2133/*-0.0651f Q15*/, -4116/*-0.1256f Q15*/, -5872/*-0.1792f Q15*/, 26306/*0.8028f Q15*/, -5872/*-0.1792f Q15*/, -4116/*-0.1256f Q15*/, -2133/*-0.0651f Q15*/, -672/*-0.0205f Q15*/, 0/* 0.f Q15*/ }; +const Word16 T_256DIV_L_Frame[] = +{ + 6554 /*L_Frame 640*/ + ,8192 /*L_Frame 512*/ + ,8738 /*L_Frame 480*/ + ,13107/*L_Frame 320*/ + ,16384 /*L_Frame 256*/ + ,26214 /*L_Frame 160*/ +}; /* clang-format on */ diff --git a/lib_dec/rom_dec.h b/lib_dec/rom_dec.h index bbf6759bdbe7ad242bf110a93a913262a5b7fa5f..16a34ca71abd077188d68092c080192b570a3596 100644 --- a/lib_dec/rom_dec.h +++ b/lib_dec/rom_dec.h @@ -42,7 +42,9 @@ #include "cnst.h" extern const float h_low[]; /* LP filter for filtering periodic part of excitation in artificial onset construction after FEC */ - +extern const Word16 H_low[5]; +extern const Word16 inv_sqi[15]; +extern const Word16 sqi[15]; extern const int16_t mult_avq_tab[]; extern const int16_t shift_avq_tab[]; @@ -51,17 +53,33 @@ extern const int16_t hetable[57]; extern const int16_t hestable[15]; extern const float lsf_tab[LPC_SHB_ORDER]; +extern const Word16 lsf_tab_fx[LPC_SHB_ORDER]; +extern const Word16 POW_ATT_TABLE0[]; +extern const Word16 POW_ATT_TABLE1[]; extern const int16_t gw[LGW_MAX]; +extern const Word16 gw_fx[LGW_MAX]; +extern const Word16 gw_len_inv_fx[LGW_MAX - 1]; +extern const Word16 GR_POW_HEADROOM[]; extern const int16_t ivas_gwlpr[LGW_MAX]; +extern const float w_hamm48k_2[L_TRANA48k / 2]; extern const float w_hamm32k_2[L_TRANA32k / 2]; extern const float w_hamm16k_2[L_TRANA16k / 2]; +extern const Word16 w_hamm48k_2_fx[]; +extern const Word16 w_hamm32k_2_fx[]; +extern const Word16 w_hamm16k_2_fx[]; + extern const float w_hamm_sana32k_2[L_PROT_HAMM_LEN2_32k]; extern const float w_hamm_sana16k_2[L_PROT_HAMM_LEN2_16k]; -extern const float w_hamm48k_2[L_TRANA48k / 2]; extern const float w_hamm_sana48k_2[L_PROT_HAMM_LEN2_48k]; +extern const Word16 swb_hr_inv_frm_len[4]; /* in Q19 */ +extern const Word16 inv_tbl_2n_minus1[]; -extern const float h_high3_32[L_FIR_FER2]; -extern const float h_high3_16[L_FIR_FER2]; +extern const Word16 w_hamm_sana48k_2_fx[]; +extern const float h_high3_32_flt[L_FIR_FER2]; +extern const float h_high3_16_flt[L_FIR_FER2]; +extern const Word16 h_high3_32[L_FIR_FER2]; +extern const Word16 h_high3_16[L_FIR_FER2]; +extern const Word16 T_256DIV_L_Frame[]; #endif diff --git a/lib_dec/rst_dec_fx.c b/lib_dec/rst_dec_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..21d28bf27587f27cadf60b58b27bb796ab06c7b0 --- /dev/null +++ b/lib_dec/rst_dec_fx.c @@ -0,0 +1,86 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include "options.h" /* Compilation switches */ +#include "stl.h" +#include "cnst.h" /* Common constants */ +#include "rom_com.h" /* Static table prototypes */ +#include "prot_fx1.h" /* Function prototypes */ +#include "prot_fx2.h" /* Function prototypes */ + +/*----------------------------------------------------------------------------------* + * CNG_reset_dec() + * + * Reset decoder static variables in case of CNG frame + *----------------------------------------------------------------------------------*/ + +void CNG_reset_dec_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + Word16 *pitch_buf, /* o : floating pitch for each subframe */ + Word16 *voice_factors /* o : voicing factors */ +) +{ + Word16 tmp, exp; + Word32 L_tmp; + Copy( UVWB_Ave_fx, st_fx->mem_AR_fx, M ); + set16_fx( st_fx->mem_MA_fx, 0, M ); + /*set16_fx( st_fx->dispMem_fx, 0, 8 );*/ + set16_fx( st_fx->dm_fx.prev_gain_pit , 0, 6 ); + st_fx->dm_fx.prev_gain_code = L_deposit_l(0); + st_fx->dm_fx.prev_state = 0; + move16(); + + st_fx->tilt_code_fx = 0; + move16(); + st_fx->gc_threshold_fx = 0; + move16(); + + /* last good received frame for FEC in ACELP */ + st_fx->clas_dec = UNVOICED_CLAS; + move16(); + st_fx->last_good_fx = UNVOICED_CLAS; + move16(); + + /* LP-filtered pitch gain set to 0 */ + st_fx->lp_gainp_fx = 0; + move16(); + + /* convert CNG energy into CNG gain for ACELP FEC */ + /* st->lp_gainc = sqrt( st->lp_ener ); */ + st_fx->lp_gainc_fx = 0; + move16(); + + IF (st_fx->lp_ener_fx != 0) + { + exp = norm_l(st_fx->lp_ener_fx); /* In Q6 */ + tmp = extract_h(L_shl(st_fx->lp_ener_fx, exp)); + exp = sub(exp, 30-6); + + tmp = div_s(16384, tmp); + L_tmp = L_deposit_h(tmp); + L_tmp = Isqrt_lc(L_tmp, &exp); + + st_fx->lp_gainc_fx = round_fx(L_shl(L_tmp, sub(exp, 12))); /* In Q3 */ + } + /* reset the pitch buffer in case of FRAME_NO_DATA or SID frames */ + IF( EQ_16(st_fx->L_frame,L_FRAME)) + { + set16_fx( pitch_buf, L_SUBFR<<6, NB_SUBFR ); + } + ELSE /* st->L_frame == L_FRAME16k */ + { + set16_fx( pitch_buf, L_SUBFR16k<<6, NB_SUBFR16k ); + } + + set16_fx( voice_factors, 32767, NB_SUBFR16k ); + + /* deactivate bass post-filter */ + st_fx->bpf_off = 1; + move16(); + /* Reset active frame counter */ + st_fx->hTdCngDec->act_cnt2_fx = 0; + move16(); + + return; +} diff --git a/lib_dec/stat_dec.h b/lib_dec/stat_dec.h index d31b3049baaa4fd1313c29bde6712a1c8dd78202..8281b3fba50acea612ec892aa24133700d7894e6 100644 --- a/lib_dec/stat_dec.h +++ b/lib_dec/stat_dec.h @@ -60,6 +60,20 @@ typedef enum FRAMEMODE_FUTURE = 0x2 } FRAME_MODE,frameMode_fx; +typedef enum +{ + TONALMDCTCONCEAL_OK = 0, + + __error_codes_start = -100, + + TONALMDCTCONCEAL_NSAMPLES_LARGER_THAN_MAXBLOCKSIZE, + TONALMDCTCONCEAL_INVALIDPOINTER, + TONALMDCTCONCEAL_UNEXPECTED_ERROR, + + __error_codes_end +} TONALMDCTCONCEAL_ERROR; + + /*---------------------------------------------------------------* * Structure for FD CNG *---------------------------------------------------------------*/ @@ -277,17 +291,28 @@ typedef struct typedef struct { uint16_t numIndexes; - uint16_t indexOfTonalPeak[MAX_NUMBER_OF_IDX]; - uint16_t lowerIndex[MAX_NUMBER_OF_IDX]; - uint16_t upperIndex[MAX_NUMBER_OF_IDX]; + Word16 indexOfTonalPeak[MAX_NUMBER_OF_IDX]; + Word16 lowerIndex[MAX_NUMBER_OF_IDX]; + Word16 upperIndex[MAX_NUMBER_OF_IDX]; Float32 phaseDiff_float[MAX_NUMBER_OF_IDX]; /* This one can be stored with 16 bits in range 0..2*PI */ - Word16 phaseDiff[MAX_NUMBER_OF_IDX]; /* This one can be stored with 16 bits in range 0..2*PI */ - + Float32 phase_currentFramePredicted_float[MAX_NUMBER_OF_IDX * GROUP_LENGTH]; /* This one can be stored with 16 bits in range 0..2*PI, but the code has to be adapted to use moduo(2*PI) after adding */ - Word16 phase_currentFramePredicted[MAX_NUMBER_OF_IDX*GROUP_LENGTH]; /* This one can be stored with 16 bits in range [-pi;pi] 2Q13, but the code has to be adapted to use moduo(2*PI) after adding */ -} TonalComponentsInfo; +} TonalComponentsInfo_float; + +typedef struct +{ + uint16_t numIndexes; + Word16 indexOfTonalPeak[MAX_NUMBER_OF_IDX]; + Word16 lowerIndex[MAX_NUMBER_OF_IDX]; + Word16 upperIndex[MAX_NUMBER_OF_IDX]; + + Word16 phaseDiff[MAX_NUMBER_OF_IDX]; /* This one can be stored with 16 bits in range 0..2*PI */ + + Word16 phase_currentFramePredicted[MAX_NUMBER_OF_IDX*GROUP_LENGTH]; /* This one can be stored with 16 bits in range [-pi;pi] 2Q13, but the code has to be adapted to use moduo(2*PI) after adding */ + +} TonalComponentsInfo_fix; typedef struct tonalmdctconceal { @@ -339,8 +364,11 @@ typedef struct tonalmdctconceal float nFramesLost_float; Word16 nFramesLost; - - TonalComponentsInfo *pTCI; +#if 0 + //Memory ovelap issue +#endif + TonalComponentsInfo_float *pTCI_float; + TonalComponentsInfo_fix *pTCI_fix; } TonalMDCTConceal_INSTANCE, *TonalMDCTConcealPtr; @@ -435,6 +463,7 @@ typedef struct igfdec_instance_struct int16_t infoIGFStartFreq; uint8_t *infoTCXNoise; uint8_t infoTCXNoiseBuf[IGF_START_MX]; + Word16 infoTCXNoise_evs[IGF_START_MX]; int16_t *flag_sparse; int16_t flag_sparseBuf[N_MAX_TCX - IGF_START_MN]; @@ -456,7 +485,14 @@ typedef struct igfdec_instance_struct typedef struct tec_dec_structure { float pGainTemp[CLDFB_NO_COL_MAX]; - float loBuffer[CLDFB_NO_COL_MAX + MAX_TEC_SMOOTHING_DEG]; + float loBuffer_flt[CLDFB_NO_COL_MAX + MAX_TEC_SMOOTHING_DEG]; + + //fixed variable + Word16 pGainTemp_m[CLDFB_NO_COL_MAX]; + Word16 pGainTemp_e[CLDFB_NO_COL_MAX]; + Word16 loBuffer[CLDFB_NO_COL_MAX + MAX_TEC_SMOOTHING_DEG]; + Word16 cldfbExp; + Word16 lastCldfbExp; } TEC_DEC_DATA, *TEC_DEC_HANDLE; @@ -1649,10 +1685,10 @@ typedef struct Decoder_State int16_t last_codec_mode; /* last used codec mode */ uint16_t *bit_stream; /* pointer to bitstream buffer */ - UWord16 *bit_stream_fx; + //UWord16 *bit_stream_fx; int16_t next_bit_pos; /* position of the next bit to be read from the bitstream */ - Word16 next_bit_pos_fx; /* position of the next bit to be read from the bitstream */ + //Word16 next_bit_pos; /* position of the next bit to be read from the bitstream */ Word16 bitstreamformat; /* Bitstream format flag (G.192/MIME/VOIP_G192_RTP/VOIP_RTPDUMP) */ Word16 sdp_hf_only; /* RTP payload format parameter: only Header-Full format without zero padding for size collision avoidance */ @@ -1662,18 +1698,18 @@ typedef struct Decoder_State int16_t BER_detect; /* flag to signal detected bit error in the bitstream */ int32_t output_Fs; /* output sampling rate */ - Word32 output_Fs_fx; /* output sampling rate Q0*/ + //Word32 output_Fs_fx; /* output sampling rate Q0*/ Word16 output_frame_fx; /* Output frame length Q0*/ int32_t total_brate; /* total bitrate in kbps of the codec */ - Word32 total_brate_fx; /* total bitrate in kbps of the codec Q0*/ + //Word32 total_brate_fx; /* total bitrate in kbps of the codec Q0*/ int32_t last_total_brate; /* last total bitrate in kbps of the codec */ - Word32 last_total_brate_fx; /* last total bitrate in kbps of the codec Q0*/ + //Word32 last_total_brate_fx; /* last total bitrate in kbps of the codec Q0*/ int32_t last_total_brate_ber; /* last total bitrate in kbps of the codec - used only when first frame is lost and BER is detected afterwards */ - Word32 last_total_brate_ber_fx; /* last total bitrate in kbps of the codec - used only when first frame is lost and BER is detected afterwards */ + //Word32 last_total_brate_ber_fx; /* last total bitrate in kbps of the codec - used only when first frame is lost and BER is detected afterwards */ int16_t bits_frame_nominal; /* avg bits per frame on active frame */ int32_t last_bits_frame_nominal; /* last avg bits per frame on active frame */ @@ -1682,43 +1718,43 @@ typedef struct Decoder_State int16_t side_bits_frame_channel; /* bits frame channel */ int16_t core; /* core (ACELP_CORE, TCX_20_CORE, TCX_10_CORE, HQ_CORE, AMR_WB_CORE) */ - Word16 core_fx; /* core (ACELP_CORE, TCX_20_CORE, TCX_10_CORE, HQ_CORE, AMR_WB_CORE) */ + //Word16 core_fx; /* core (ACELP_CORE, TCX_20_CORE, TCX_10_CORE, HQ_CORE, AMR_WB_CORE) */ int16_t coder_type; /* coder type */ int16_t transform_type[2]; /* TCX20/10/5 mode in each subframe */ int32_t core_brate; /* core bitrate */ - Word32 core_brate_fx; /* core bitrate */ + //Word32 core_brate_fx; /* core bitrate */ int32_t last_core_brate; /* previous frame core bitrate */ - Word32 last_core_brate_fx; /* previous frame core bitrate Q0*/ + //Word32 last_core_brate_fx; /* previous frame core bitrate Q0*/ int16_t extl; /* extension layer */ - Word16 extl_fx; /* extension layer Q0*/ + //Word16 extl_fx; /* extension layer Q0*/ int16_t extl_orig; /* extension layer */ int16_t last_extl; /* previous extension layer */ - Word16 last_extl_fx; /* previous extension layer Q0*/ + //Word16 last_extl_fx; /* previous extension layer Q0*/ int32_t extl_brate; /* extension layer bitrate */ - Word32 extl_brate_fx; /* extension layer bitrate */ + //Word32 extl_brate_fx; /* extension layer bitrate */ int32_t extl_brate_orig; /* extension layer bitrate */ int16_t L_frame; /* ACELP core internal frame length */ - Word16 L_frame_fx; /* ACELP core internal frame length */ + //Word16 L_frame_fx; /* ACELP core internal frame length */ int16_t bwidth; /* encoded signal bandwidth */ - Word16 bwidth_fx; /* encoded signal bandwidth */ + //Word16 bwidth_fx; /* encoded signal bandwidth */ int16_t Opt_AMR_WB; /* flag indicating AMR-WB IO mode */ - Word16 Opt_AMR_WB_fx; /* flag indicating AMR-WB IO mode Q0*/ + //Word16 Opt_AMR_WB_fx; /* flag indicating AMR-WB IO mode Q0*/ Word16 Opt_VOIP_fx; /* flag indicating VOIP mode with JBM */ int16_t ini_frame; /* initialization frames counter */ - Word16 ini_frame_fx; /* initialization frames counter */ + //Word16 ini_frame_fx; /* initialization frames counter */ int16_t prev_coder_type; /* coding type of last frame */ int16_t low_rate_mode; /* low-rate mode flag */ @@ -1845,15 +1881,15 @@ typedef struct Decoder_State int16_t bfi; /* FEC - bad frame indicator */ - Word16 bfi_fx; /* FEC - bad frame indicator */ + //Word16 bfi_fx; /* FEC - bad frame indicator */ int16_t prev_bfi; /* FEC - previous bad frame indicator */ - Word16 prev_bfi_fx; /* FEC - previous bad frame indicator Q0*/ + //Word16 prev_bfi_fx; /* FEC - previous bad frame indicator Q0*/ int16_t prev_old_bfi; /* FEC - previous old bad frame indicator */ int16_t seed; /* FEC - seed for random generator for excitation */ - Word16 seed_fx; /* FEC - seed for random generator for excitation Q0*/ + //Word16 seed_fx; /* FEC - seed for random generator for excitation Q0*/ float lp_ener_bfi; /* FEC - long-term active-signal average energy */ @@ -1875,13 +1911,13 @@ typedef struct Decoder_State Word16 bfi_pitch_fx; /* FEC - pitch for FEC */ int16_t bfi_pitch_frame; /* FEC - frame length when pitch for FEC is saved */ - Word16 bfi_pitch_frame_fx; /*FEC - frame length when pitch for FEC is saved Q0*/ + //Word16 bfi_pitch_frame_fx; /*FEC - frame length when pitch for FEC is saved Q0*/ float old_pitch_buf[2 * NB_SUBFR16k + 2]; /* FEC - buffer of old subframe pitch values */ Word32 old_pitch_buf_fx[2 * NB_SUBFR16k + 2]; /* FEC - buffer of old subframe pitch values 15Q16 */ int16_t upd_cnt; /* FEC - counter of frames since last update */ - Word16 upd_cnt_fx; /* FEC - counter of frames since last update Q0*/ + //Word16 upd_cnt_fx; /* FEC - counter of frames since last update Q0*/ int16_t scaling_flag; /* FEC - flag to indicate energy control of syn */ @@ -1907,7 +1943,7 @@ typedef struct Decoder_State Word16 lsf_adaptive_mean_fx[M]; /* FEC - adaptive mean LSF vector for FEC (Qx2.56)*/ int16_t decision_hyst; /* FEC - hysteresis of the music/speech decision */ - Word16 decision_hyst_fx; /* FEC - hysteresis of the music/speech decision Q0*/ + //Word16 decision_hyst_fx; /* FEC - hysteresis of the music/speech decision Q0*/ Word16 last_good_fx; /* FEC - clas of last good received Q0*/ Word16 lp_ener_FER_fx; /* FEC - long-term active-signal average energy Q8*/ @@ -1922,7 +1958,7 @@ typedef struct Decoder_State Word16 mem_syn_clas_estim_fx[L_SYN_MEM_CLAS_ESTIM]; /* FEC - memory of the synthesis signal for frame class estimation */ int16_t bpf_off; /* Bass post-filter - do not use BPF when this flag is set to 1 */ - Word16 bpf_off_fx; /* Bass post-filter - do not use BPF when this flag is set to 1 Q0*/ + //Word16 bpf_off_fx; /* Bass post-filter - do not use BPF when this flag is set to 1 Q0*/ BPF_DEC_HANDLE hBPF; /* Bass post-filter handle */ @@ -1955,7 +1991,7 @@ typedef struct Decoder_State Word16 Ng_ener_ST_fx; /* Noise gate - short-term energy Q8*/ int16_t last_L_frame; /* ACELP@16kHz - last value of st->L_frame */ - Word16 last_L_frame_fx; /* ACELP@16kHz - last value of st->L_frame */ + //Word16 last_L_frame_fx; /* ACELP@16kHz - last value of st->L_frame */ float mem_preemp_preQ; /* ACELP@16kHz - prequantizer preemhasis memory */ Word16 mem_preemp_preQ_fx; /* ACELP@16kHz - prequantizer preemhasis memory */ @@ -1986,21 +2022,21 @@ typedef struct Decoder_State *----------------------------------------------------------------------------------*/ int16_t first_CNG; /* DTX/CNG - first CNG frame flag */ - Word16 first_CNG_fx; /* CNG and DTX - first CNG frame flag Q0*/ + //Word16 first_CNG_fx; /* CNG and DTX - first CNG frame flag Q0*/ int16_t cng_type; /* DTX/CNG - flag indicating LP or CLDFB based SID/CNG */ - Word16 cng_type_fx; /* DTX/CNG - flag indicating LP or CLDFB based SID/CNG */ + //Word16 cng_type_fx; /* DTX/CNG - flag indicating LP or CLDFB based SID/CNG */ int16_t last_vad; int32_t last_active_brate; /* DTX/CNG - last active frame bitrate used for CNG_mode control */ - Word32 last_active_brate_fx; /* DTX/CNG - last active frame bitrate used for CNG_mode control */ + //Word32 last_active_brate_fx; /* DTX/CNG - last active frame bitrate used for CNG_mode control */ int16_t last_CNG_L_frame; /* DTX/CNG - last CNG frame length */ - Word16 last_CNG_L_frame_fx; /* DTX/CNG - last CNG frame length */ + //Word16 last_CNG_L_frame_fx; /* DTX/CNG - last CNG frame length */ int16_t CNG_mode; /* DTX/CNG - mode for DTX configuration */ - Word16 CNG_mode_fx; /* DTX/CNG - mode for DTX configuration */ + //Word16 CNG_mode_fx; /* DTX/CNG - mode for DTX configuration */ float lspCNG[M]; /* DTX/CNG - LP filtered ISPs */ Word16 lspCNG_fx[M]; /* CNG and DTX - LP filtered ISPs Q15*/ @@ -2083,13 +2119,13 @@ typedef struct Decoder_State HQ_DEC_HANDLE hHQ_core; int16_t last_core; - Word16 last_core_fx; /*Q0*/ + //Word16 last_core_fx; /*Q0*/ int16_t last_core_from_bs; /* last frame core as coded in TCX bitstream */ Word16 last_core_bs_fx; int16_t last_L_frame_ori; - Word16 last_L_frame_ori_fx; + //Word16 last_L_frame_ori_fx; float previoussynth[L_FRAME48k]; /* note: only 60+111 out of 960 samples are needed in IVAS (for ACELP->TCX switching */ Word16 previoussynth_fx[L_FRAME48k]; @@ -2161,10 +2197,10 @@ typedef struct Decoder_State Word16 attenu_fx; int16_t last_inner_frame; - Word16 last_inner_frame_fx; /* (HQ_CORE) DCT length */ + //Word16 last_inner_frame_fx; /* (HQ_CORE) DCT length */ int16_t last_bwidth; - Word16 last_bwidth_fx; + //Word16 last_bwidth_fx; float t_audio_q[L_FRAME]; Word16 t_audio_q_fx[L_FRAME]; @@ -2476,7 +2512,7 @@ typedef struct Decoder_State int16_t igf; CLDFB_SCALE_FACTOR scaleFactor; - TEMPORAL_ENVELOPE_CODING_DECODER_FX tecDec_fx; + /*----------------------------------------------------------------------------------* * TEC *----------------------------------------------------------------------------------*/ @@ -2485,7 +2521,10 @@ typedef struct Decoder_State int16_t tec_flag; int16_t tfa_flag; TEC_DEC_HANDLE hTECDec; - +#if 0 + //not needed above structure has same variable + TEMPORAL_ENVELOPE_CODING_DECODER_FX tecDec_fx; +#endif /*----------------------------------------------------------------------------------* * IVAS parameters *----------------------------------------------------------------------------------*/ diff --git a/lib_dec/stat_noise_uv_dec_fx.c b/lib_dec/stat_noise_uv_dec_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..d55c10ce746ecedc4d38df8948696f5fdb027458 --- /dev/null +++ b/lib_dec/stat_noise_uv_dec_fx.c @@ -0,0 +1,87 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include +#include "options.h" /* Compilation switches */ +#include "prot_fx1.h" /* Function prototypes */ +#include "prot_fx2.h" /* Function prototypes */ + + +/*---------------------------------------------------------* + * stat_noise_uv_dec() + * + * Modifies excitation signal in UC mode when the noise is stationary + *---------------------------------------------------------*/ +void stat_noise_uv_dec_fx( + Decoder_State *st_fx, /* i/o: Decoder static memory */ + Word16 *lsp_new, /* i : end-frame LSP vector */ + Word16 *lsp_mid, /* i : mid-frame LSP vector */ + Word16 *Aq, /* o : A(z) quantized for the 4 subframes */ + Word16 *exc2 /* i/o: excitation buffer */ + , const Word16 uc_two_stage_flag /* i : flag indicating two-stage UC */ +) +{ + Word16 noisiness = 0, i; + Word32 L_tmp; + Word16 coder_type = st_fx->coder_type_fx; + + + /*-----------------------------------------------------------------* + * Decode the VAD flag + *-----------------------------------------------------------------*/ + test(); + test(); + IF( (EQ_16(coder_type,UNVOICED ) && !uc_two_stage_flag) ||(EQ_16(coder_type,INACTIVE)&&LE_32(st_fx->core_brate,ACELP_9k60))) + { + /* read the noisiness parameter */ + noisiness = (Word16)get_next_indice( st_fx, 5 ); + move16(); + } + + /*-----------------------------------------------------------------* + * Update long-term energies for FEC + * Update LSP vector for CNG + *-----------------------------------------------------------------*/ + IF (EQ_16(coder_type,INACTIVE)) + { + IF (GT_16(st_fx->unv_cnt_fx,20)) + { + /*ftmp = st->lp_gainc * st->lp_gainc;*/ + L_tmp = L_mult0(st_fx->lp_gainc_fx, st_fx->lp_gainc_fx); /*Q3 * Q3 ->Q6*/ + /*st->lp_ener = 0.7f * st->lp_ener + 0.3f * ftmp;*/ + L_tmp = Mult_32_16(L_tmp, 9830); + st_fx->lp_ener_fx = L_add(Mult_32_16(st_fx->lp_ener_fx, 22938), L_tmp); + move16(); /*Q6 + Q6*/ + + FOR( i=0 ; ilspCNG[i] = (float)(0.9f * st->lspCNG[i] + 0.1f * lspnew[i]);*/ + L_tmp = L_mult(lsp_new[i], 3277); + st_fx->lspCNG_fx[i] = mac_r(L_tmp, st_fx->lspCNG_fx[i], 29491); + move16();/*Q15*/ + } + } + ELSE + { + st_fx->unv_cnt_fx = add(st_fx->unv_cnt_fx,1); + } + } + ELSE + { + st_fx->unv_cnt_fx = 0; + move16(); + } + + IF (!st_fx->Opt_AMR_WB) + { + stat_noise_uv_mod_fx( coder_type, noisiness, st_fx->lsp_old_fx, lsp_new, lsp_mid, Aq + ,exc2, st_fx->Q_exc, 0, &st_fx->ge_sm_fx, &st_fx->uv_count_fx, &st_fx->act_count_fx, + st_fx->lspold_s_fx, &st_fx->noimix_seed_fx, &st_fx->min_alpha_fx, + &st_fx->exc_pe_fx, st_fx->core_brate, st_fx->bwidth, + &st_fx->Q_stat_noise, &st_fx->Q_stat_noise_ge ); + } + + + return ; +} diff --git a/lib_dec/swb_bwe_dec.c b/lib_dec/swb_bwe_dec.c index cc835d7d684cf2f56e74fdaddc9ed5df9f158bd5..43906aaf412b12561d1e417be60b57be1ffdda48 100644 --- a/lib_dec/swb_bwe_dec.c +++ b/lib_dec/swb_bwe_dec.c @@ -236,12 +236,12 @@ static int16_t WB_BWE_gain_deq( } /*-------------------------------------------------------------------* - * wb_bwe_dec() + * wb_bwe_dec_flt() * * WB BWE decoder (only for 16kHz signals) *-------------------------------------------------------------------*/ -void wb_bwe_dec( +void wb_bwe_dec_flt( Decoder_State *st, /* i/o: decoder state structure */ const float output[], /* i : synthesis @internal Fs */ float *synth, /* i/o: ACELP core synthesis/final synthesis */ @@ -346,13 +346,13 @@ void wb_bwe_dec( } /*-------------------------------------------------------------------* - * swb_bwe_gain_deq() + * swb_bwe_gain_deq_flt() * * Decoding of SWB parameters *-------------------------------------------------------------------*/ /*! r: BWE class */ -int16_t swb_bwe_gain_deq( +int16_t swb_bwe_gain_deq_flt( Decoder_State *st, /* i/o: decoder state structure */ const int16_t core, /* i : core */ float *SWB_tenv, /* o : time-domain BWE envelope */ @@ -545,12 +545,12 @@ int16_t swb_bwe_gain_deq( } /*-------------------------------------------------------------------* - * swb_bwe_dec() + * swb_bwe_dec_flt() * * SWB BWE decoder *-------------------------------------------------------------------*/ -void swb_bwe_dec( +void swb_bwe_dec_flt( Decoder_State *st, /* i/o: decoder state structure */ const float output[], /* i : synthesis @internal Fs */ const float *synth, /* i : ACELP core synthesis/final synthesis */ @@ -612,7 +612,7 @@ void swb_bwe_dec( else { /* de-quantization */ - mode = swb_bwe_gain_deq( st, ACELP_CORE, SWB_tenv, SWB_fenv, 0, -1 ); + mode = swb_bwe_gain_deq_flt( st, ACELP_CORE, SWB_tenv, SWB_fenv, 0, -1 ); } L = mode == TRANSIENT ? SWB_FENV_TRANS : SWB_FENV; @@ -757,12 +757,12 @@ void swb_bwe_dec( } /*-------------------------------------------------------------------* - * fd_bwe_dec_init() + * fd_bwe_dec_init_flt() * * Initialize FD BWE state structure at the decoder *-------------------------------------------------------------------*/ -void fd_bwe_dec_init( +void fd_bwe_dec_init_flt( FD_BWE_DEC_HANDLE hBWE_FD /* i/o: FD BWE data handle */ ) { diff --git a/lib_dec/swb_bwe_dec_fx.c b/lib_dec/swb_bwe_dec_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..4b539d9498e2500404fe16652ed2a3289c887724 --- /dev/null +++ b/lib_dec/swb_bwe_dec_fx.c @@ -0,0 +1,1116 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include +#include "options.h" +#include "cnst.h" +#include "prot_fx1.h" +#include "prot_fx2.h" +#include "rom_com.h" +#include "rom_enc.h" + +#define MAX_Q_NEW_INPUT 8 +#define Q_WTDA_FX 13 +#define Q_32_BITS 15 + +/*-------------------------------------------------------------------* + * para_pred_bws() + * + * predict SWB parameters for bandwidth switching + *-------------------------------------------------------------------*/ +static +Word16 para_pred_bws_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + Word16 *signal_wb_fx, /* i : wideband frequency signal */ + Word16 *SWB_fenv_fx, /* o : frequency-domain BWE envelope */ + Word16 Q_syn +) +{ + Word16 i, j, k; + Word16 mode; + Word16 tmp, tmp_den, tmp_num; + Word32 L_tmp, L_tmp_max; + Word16 exp; + Word16 *input_hi_fx; + Word32 *mea; + Word16 peak_fx, mag_fx; + Word32 mean_fx[7], peak_32_fx; + Word32 avrg1_fx, avrg2_fx, min_fx; + Word16 att_fx; + Word16 coder_type = st_fx->coder_type_fx; + + mode = NORMAL; + move16(); + + k = 0; + move16(); + input_hi_fx = &signal_wb_fx[SHARP_WIDTH]; + move16(); + FOR(i = 0; i < 7; i ++) + { + peak_fx = 0; + move16(); + mean_fx[i] = 0; + move16(); + FOR(j = 0; j < SHARP_WIDTH; j ++) + { + mag_fx = abs_s(*input_hi_fx); + peak_fx = s_max(peak_fx ,mag_fx); + /*IF (sub(mag_fx, peak_fx) > 0) */ + /*{ */ + /* peak_fx = mag_fx; */ + /*} */ + mean_fx[i] = L_add(mean_fx[i], L_deposit_l(mag_fx)); + move32(); + input_hi_fx ++; + } + + IF(Q_syn < 11) + { + tmp = 1; + move16(); + } + ELSE + { + tmp = 0; + move16(); + if(GT_16(shr(peak_fx, 3), shl(1, Q_syn))) + { + tmp = 1; + move16(); + } + } + IF( tmp > 0) + { + L_tmp = L_msu0(Mult_32_16(L_shl(mean_fx[i], 10), 18432), peak_fx, 4544); + if (L_tmp < 0) + { + k = add(k, 1); + } + } + } + + avrg1_fx = L_deposit_l(0); + avrg2_fx = L_deposit_l(0); + FOR(i=1; i<4; i++) + { + avrg1_fx = L_add(avrg1_fx, mean_fx[i]); + avrg2_fx = L_add(avrg2_fx, mean_fx[i+3]); + } + avrg1_fx = Mult_32_16(avrg1_fx, 10923); + avrg2_fx = Mult_32_16(avrg2_fx, 10923); /* 1/3 -> Q15 -> 10923 */ + + min_fx = L_add(2147483647, 0); /*2^31 */ + peak_32_fx = L_deposit_l(0); + FOR(i = 4; i < 7; i ++) + { + IF(GT_32(mean_fx[i], L_shl(avrg2_fx, 1))) + { + exp = norm_l(mean_fx[i]); + IF(LT_16(exp, 16)) + { + tmp_den = extract_l(L_shr(mean_fx[i], sub(16, exp))); /*Qsyn - 16 + exp */ + tmp_num = extract_l(L_shr(avrg2_fx, sub(15, exp))); /*//Qsyn - 16 + exp */ + } + ELSE + { + tmp_den = extract_l(mean_fx[i]); + tmp_num = extract_l(L_shl(avrg2_fx, 1)); + } + + tmp_den = div_s(1, tmp_den); + + tmp = i_mult(tmp_num, tmp_den); /*Q15 */ + + mean_fx[i] = Mult_32_16(mean_fx[i], tmp); + move32(); + } + min_fx = L_min(min_fx, mean_fx[i]); + peak_32_fx = L_max(peak_32_fx, mean_fx[i]); + /*IF(L_sub(mean_fx[i], min_fx) < 0) */ + /*{ */ + /* min_fx = mean_fx[i]; */ + /*} */ + /*IF(L_sub(mean_fx[i], peak_32_fx) > 0) */ + /*{ */ + /* peak_32_fx = mean_fx[i]; */ + /*} */ + } + + IF(GT_16(st_fx->tilt_wb_fx, 16384)) + { + IF(GT_16(st_fx->tilt_wb_fx, 30720)) + { + min_fx = peak_32_fx; + } + ELSE + { + tmp = extract_l(L_shr(L_mult0(st_fx->tilt_wb_fx, 17476), 14)); /*Q15 */ + min_fx = Mult_32_16(peak_32_fx, tmp); + } + } + + test(); + IF(peak_32_fx == 0 || min_fx == 0) + { + set16_fx(SWB_fenv_fx, 0, SWB_FENV); + } + ELSE + { + exp = norm_l(peak_32_fx); + IF(LT_16(exp, 16)) + { + tmp_den = extract_l(L_shr(peak_32_fx, sub(16, exp))); /*Qsyn - 16 + exp */ + tmp = div_s(16384, tmp_den); /*Q15+14 - (Qsyn - 16 + exp) */ + tmp_num = extract_l(L_shr(min_fx, sub(16, exp))); /*Qsyn - 16 + exp */ + + tmp = extract_l(L_shr(L_mult0(tmp_num, tmp), 14)); /*Q15 */ + } + ELSE + { + tmp_den = extract_l(peak_32_fx); /*Qsyn */ + exp = norm_s(tmp_den); + tmp = div_s(shl(1, sub(14,exp)), tmp_den); /*Q 29-exp - Qsyn */ + tmp_num = extract_l(min_fx); /*Qsyn */ + + tmp = extract_l(L_shr(L_mult0(tmp_num, tmp), sub(14, exp))); /*Q15 */ + } + + j = 0; + move16(); + mea = &mean_fx[4]; + move16(); + L_tmp_max = L_shl(32767, add(Q_syn, 5)); + FOR(i = 0; i < SWB_FENV; i++) + { + IF(j == 5) + { + mea++; + move16(); + j = 0; + move16(); + } + j++; + move16(); + L_tmp = L_min(Mult_32_16(*mea, tmp), L_tmp_max); + SWB_fenv_fx[i] = extract_l(L_shr(L_tmp, add(Q_syn, 5))); + } + } + + j = 0; + move16(); + FOR(i = shr(SWB_FENV, 1); i < SWB_FENV; i++) + { + tmp = sub(32767, i_mult(j, 2341)); + move16(); + SWB_fenv_fx[i] = mult_r(SWB_fenv_fx[i], tmp); + move16(); + j++; + move16(); + } + + IF(GT_32(avrg1_fx, L_shl(avrg2_fx, 3))) + { + FOR(i = 0; i < SWB_FENV; i ++) + { + SWB_fenv_fx[i] = shr(SWB_fenv_fx[i], 1); + move16(); + } + } + + test(); + test(); + test(); + test(); + test(); + IF( NE_16(st_fx->last_core, HQ_CORE)&&EQ_16(st_fx->last_codec_mode,MODE1)&& + (GT_32(st_fx->enerLH_fx, L_shr(st_fx->prev_enerLH_fx, 1)) && LT_32(L_shr(st_fx->enerLH_fx, 1), st_fx->prev_enerLH_fx) ) && + (GT_32(st_fx->enerLL_fx, L_shr(st_fx->prev_enerLL_fx, 1)) && LT_32(L_shr(st_fx->enerLL_fx, 1), st_fx->prev_enerLL_fx) ) ) + { + FOR(i=0; iprev_coder_type_fx, coder_type)&>_16(mult_r(SWB_fenv_fx[i],16384), st_fx->prev_SWB_fenv_fx[i])) + { + /*SWB_fenv_fx[i] = add(mult_r(SWB_fenv_fx[i], 3277), mult_r(st_fx->prev_SWB_fenv_fx[i], 29491)); */ + SWB_fenv_fx[i] = round_fx(L_mac(L_mult(SWB_fenv_fx[i], 3277), st_fx->prev_SWB_fenv_fx[i], 29491)); + } + ELSE + { + /*SWB_fenv_fx[i] = add(mult_r(SWB_fenv_fx[i], st_fx->attenu_fx), mult_r(st_fx->prev_SWB_fenv_fx[i], sub(32767, st_fx->attenu_fx))); */ + SWB_fenv_fx[i] = round_fx(L_mac(L_mult(SWB_fenv_fx[i], st_fx->attenu_fx), st_fx->prev_SWB_fenv_fx[i], sub(32767, st_fx->attenu_fx))); + } + } + + IF(LT_16(st_fx->attenu_fx, 29491)) + { + st_fx->attenu_fx = add(st_fx->attenu_fx, 1638); + move16(); + } + } + ELSE + { + test(); + test(); + test(); + test(); + IF( NE_32(st_fx->core_brate, st_fx->last_core_brate)||(GT_32(st_fx->enerLH_fx,L_shr(st_fx->prev_enerLH_fx,1))&<_32(L_shr(st_fx->enerLH_fx,1),st_fx->prev_enerLH_fx))|| + (GT_32(st_fx->enerLL_fx, L_shr(st_fx->prev_enerLL_fx, 1)) && LT_32(L_shr(st_fx->enerLL_fx, 1), st_fx->prev_enerLL_fx) ) ) + { + FOR(i=0; iprev_SWB_fenv_fx[i])) + { + SWB_fenv_fx[i] = st_fx->prev_SWB_fenv_fx[i]; + move16(); + } + } + } + + FOR(i=0; iprev_SWB_fenv_fx[i], 3277)); */ + SWB_fenv_fx[i] = round_fx(L_mac(L_mult(SWB_fenv_fx[i], 29491), st_fx->prev_SWB_fenv_fx[i], 3277)); + } + st_fx->attenu_fx = 3277; + move16(); + } + + if(GT_16(k, 3)) + { + mode = HARMONIC; + move16(); + } + + + att_fx = i_mult(sub(N_WS2N_FRAMES, st_fx->bws_cnt_fx), 819); + move16();/*15 */ + IF( EQ_16(st_fx->L_frame, L_FRAME16k)) + { + FOR( i = 0; i < 4; i++ ) + { + SWB_fenv_fx[i] = mult_r(SWB_fenv_fx[i], att_fx); + move16(); /*Q1 */ + } + } + + FOR( i=4; icoder_type_fx; + + hBWE_FD = st_fx->hBWE_FD; + + /* MDCT of the core synthesis signal */ + + new_input_fx_exp = *Qpost; + move16(); +#ifdef ADD_IVAS_BWE + if (st->element_mode == IVAS_CPE_DFT && !use_cldfb_for_dft) + { + /* IVAS_fmToDo: wtda() does not support L_FRAME length; thus temporarily resample the signal */ + /* IVAS_fmToDo: delay output[] by 1.25ms ? */ + lerp(output, ysynth, L_FRAME16k, st->L_frame); + + wtda(ysynth, wtda_synth, hBWE_FD->old_wtda_swb, ALDO_WINDOW, ALDO_WINDOW, /*st->L_frame*/ L_FRAME16k); + direct_transform(wtda_synth, ysynth, 0, /*st->L_frame*/ L_FRAME16k, st->element_mode); + } + else +#endif + { + wtda_fx(synth_fx, &new_input_fx_exp, L_wtda_synth_fx, hBWE_FD->L_old_wtda_swb_fx, + &hBWE_FD->old_wtda_swb_fx_exp, ALDO_WINDOW, ALDO_WINDOW, /* window overlap of current frame (0: full, 2: none, or 3: half) */ + output_frame); + *Qpost = sub(new_input_fx_exp, 15); + /* DCT of the ACELP core synthesis */ + direct_transform_fx(L_wtda_synth_fx, ysynth_32, 0, output_frame, &new_input_fx_exp, st_fx->element_mode); + } + /* Convert to 16 Bits (Calc Shift Required to Stay within MAX_Q_NEW_INPUT) */ + scl = sub(16+MAX_Q_NEW_INPUT, new_input_fx_exp); + /* Possible to Upscale? */ + IF (scl > 0) + { + /* Yes */ + /* Calc Room to Upscale */ + Q_syn = Find_Max_Norm32(ysynth_32, output_frame); + /* Stay within MAX_Q_NEW_INPUT */ + scl = s_min(Q_syn, scl); + } + Copy_Scale_sig32_16(ysynth_32, ysynth_fx, output_frame, scl); + Q_syn = add(sub(new_input_fx_exp, 16), scl); + IF( !st_fx->bfi ) + { +#ifdef ADD_IVAS_BWE + IF( st_fx->extl_brate > 0) +#else + IF( EQ_32(st_fx->total_brate, ACELP_13k20)) +#endif + { + /* de-quantization */ + mode = WB_BWE_gain_deq_fx(st_fx, WB_fenv_fx ); + st_fx->last_wb_bwe_ener_fx = mult_r(add(WB_fenv_fx[0], WB_fenv_fx[1]), 16384); + } + ELSE + { + int32_t tmp_brate; + + tmp_brate = st_fx->last_core_brate; +#if 1//def ADD_IVAS_BWE + test(); + IF (EQ_32(st_fx->last_total_brate, ACELP_9k60) && EQ_16(st_fx->last_extl, SWB_TBE ) ) + { + tmp_brate = ACELP_8k00; /* this is needed in order to stay BE wrt. EVS mono */ + move16(); + } +#endif + if( NE_16(st_fx->last_extl, WB_BWE)) + { + st_fx->prev_SWB_fenv_fx[0] = 0; + move16(); + } + + mode = WB_BWE_gain_pred_fx( WB_fenv_fx, ysynth_fx, coder_type, st_fx->prev_coder_type_fx, st_fx->prev_SWB_fenv_fx[0], + voice_factors_fx, pitch_buf_fx, tmp_brate, st_fx->last_wb_bwe_ener_fx, Q_syn + ,st_fx->last_extl, st_fx->tilt_wb_fx); + move16(); + } + } + ELSE + { + /* FEC */ + mode = NORMAL; + move16(); + FOR(i=0; i<2; i++) + { + WB_fenv_fx[i] = mult_r(st_fx->prev_SWB_fenv_fx[i], 24576); + } + } + test(); + IF( NE_16(st_fx->last_extl, WB_BWE)||st_fx->bfi) + { + Copy( WB_fenv_fx, st_fx->prev_SWB_fenv_fx, 2 ); + } + + exp = norm_l(hBWE_FD->prev_Energy_wb_fx); + IF(GT_16(add(st_fx->prev_Q_synth, exp),Q_syn)) + { + hBWE_FD->prev_Energy_wb_fx = L_shr(hBWE_FD->prev_Energy_wb_fx, sub(st_fx->prev_Q_synth, Q_syn)); + } + ELSE + { + Q_syn = add(st_fx->prev_Q_synth, exp); + hBWE_FD->prev_Energy_wb_fx = L_shl(hBWE_FD->prev_Energy_wb_fx, exp); + } + WB_BWE_decoding_fx( ysynth_fx, WB_fenv_fx, ysynth_32, L_FRAME16k, mode, + st_fx->last_extl, &hBWE_FD->prev_Energy_wb_fx, st_fx->prev_SWB_fenv_fx, &hBWE_FD->prev_L_swb_norm_fx, + st_fx->extl, coder_type, st_fx->total_brate, &hBWE_FD->Seed_fx, &hBWE_FD->prev_flag_fx, + st_fx->prev_coder_type_fx, Q_syn, &Q_syn_hb ); + IF ( EQ_32(st_fx->output_Fs, 32000)) + { + set32_fx( &ysynth_32[L_FRAME16k], 0, L_FRAME16k ); + } + ELSE IF ( EQ_32(st_fx->output_Fs, 48000)) + { + set32_fx( &ysynth_32[L_FRAME16k], 0, L_FRAME32k ); + } + Inverse_Transform( ysynth_32, &Q_syn_hb, t_audio32_tmp, 0, output_frame, output_frame, st_fx->element_mode ); + window_ola_fx( t_audio32_tmp, hb_synth_fx, &Q_syn_hb, hBWE_FD->mem_imdct_fx, &hBWE_FD->mem_imdct_exp_fx, output_frame, + ALDO_WINDOW,ALDO_WINDOW, 0,0,0); + +#ifdef ADD_IVAS_BWE + test(); + IF (EQ_16(st_fx->element_mode, IVAS_CPE_DFT) && !use_cldfb_for_dft) + { + /* add HB synth from hf_synth() */ + v_add(hb_synth, synth, hb_synth, output_frame); + } +#endif + hBWE_FD->prev_mode_fx = mode; + st_fx->prev_Q_synth = Q_syn; + return Q_syn_hb; +} +/*-------------------------------------------------------------------* + * swb_bwe_gain_deq() + * + * Decoding of SWB parameters + *-------------------------------------------------------------------*/ +Word16 swb_bwe_gain_deq_fx( /* o : BWE class */ + Decoder_State *st_fx, /* i/o: decoder state structure */ + const Word16 core, /* i : core */ + Word16 *SWB_tenv, /* o : Q0, time-domain BWE envelope */ + Word16 *SWB_fenv, /* o : Q1, frequency-domain BWE envelope */ + const Word16 hr_flag, /* i : high rate flag */ + const Word16 hqswb_clas /* i : HQ BWE class */ +) +{ + Word16 index, mode, n_band; + Word16 indice[6]; + Word16 quant_tmp[SWB_FENV/2], quant_tmp2[SWB_FENV/2]; + Word16 nb_bits[6]; + Word16 nenv; + Word16 tmp,exp,frac; + Word32 L_tmp; + + IF ( hqswb_clas > 0) + { + mode = (Word16)get_next_indice( st_fx, 1 ); + IF (mode == 0) + { + mode = (Word16)get_next_indice( st_fx, 1 ); + } + ELSE + { + mode = HQ_GENERIC_SP_EXC; + move16(); + } + } + ELSE + { + mode = (Word16)get_next_indice( st_fx, 2 ); + } + + test(); + IF( EQ_16(mode,1)&&EQ_16(core,ACELP_CORE)) + { + FOR( n_band = 0; n_band < SWB_TENV; n_band++ ) + { + index = (Word16)get_next_indice(st_fx, 4 ); + SWB_tenv[n_band] = shl(1, index); + move16(); + } + + indice[0] = (Word16)get_next_indice(st_fx, 7 ); + move16(); + indice[1] = (Word16)get_next_indice(st_fx, 6 ); + move16(); + + tmp = shl(indice[0],1); + FOR(n_band = 0; n_band < DIM_TR1; n_band++) + { + /*Env_TR_Cdbk1_fx[ indice[0]*DIM_TR1+n_band]*/ + quant_tmp[2*n_band] = Env_TR_Cdbk1_fx[add(tmp,n_band)];/*Q8 */ move16(); + } + + /*tmp = indice[1]*DIM_TR2*/ + tmp = shl(indice[1],1); + quant_tmp[1] = add(shr(add(quant_tmp[0], quant_tmp[2]),1), Env_TR_Cdbk2_fx[tmp]); + move16();/*Q8 */ + quant_tmp[3] = add(quant_tmp[2],Env_TR_Cdbk2_fx[add(tmp,1)]); + move16();/*Q8 */ + + FOR(n_band = 0; n_band < SWB_FENV_TRANS; n_band++) + { + tmp = add(quant_tmp[n_band], Mean_env_tr_fx[n_band]); /*Q8 */ + + /*-----------------------------------------------------------------* + * SWB_fenv[n_band] = pow(10.0, tmp/40) + * = pow(2, 3.321928*tmp/40) + * = pow(2, 0.0830482*tmp) + *-----------------------------------------------------------------*/ + L_tmp = L_mult(tmp, 21771); /* 0.0830482 in Q18 -> Q27 */ + L_tmp = L_shr(L_tmp, 11); /* From Q27 to Q16 */ + frac = L_Extract_lc(L_tmp, &exp); /* Extract exponent of L_tmp */ + tmp = extract_l(Pow2(13, frac)); + exp = sub(exp, 13); + SWB_fenv[n_band] = shl(tmp, add(exp, 1)); + move16();/*Q1 */ + } + /* in case of band-width switching, attenuate frame gain */ + IF( st_fx->bws_cnt1_fx > 0 ) + { + tmp = i_mult(st_fx->bws_cnt1_fx, 1638); + FOR(n_band = 0; n_band < SWB_TENV; n_band++) + { + SWB_tenv[n_band] = mult_r(SWB_tenv[n_band], tmp); + move16(); + } + + FOR (n_band = 0; n_band < SWB_FENV_TRANS; n_band++) + { + SWB_fenv[n_band] = mult_r(SWB_fenv[n_band], tmp); + move16(); + } + } + } + ELSE + { + nb_bits[0] = 5; + move16(); + nb_bits[1] = 7; + move16(); + nb_bits[2] = 6; + move16(); + nb_bits[3] = 5; + move16(); + + IF ( EQ_16(hr_flag,1)) + { + nb_bits[4] = 5; + move16(); + nenv = SWB_FENV - 2; + move16(); + } + ELSE + { + nb_bits[4] = 6; + move16(); + nenv = SWB_FENV; + move16(); + } + + FOR (n_band = 0; n_band < 5; n_band++) + { + indice[n_band] = (Word16) get_next_indice(st_fx, nb_bits[n_band] ); + move16(); + } + + IF ( EQ_16(hqswb_clas,HQ_GEN_FB)) + { + indice[n_band] = (Word16) get_next_indice(st_fx, 5 ); + move16(); + } + + Copy( &EnvCdbk11_fx[i_mult2(indice[0], DIM11)], quant_tmp, DIM11 ); + Copy( &EnvCdbk1st_fx[i_mult2(indice[1], DIM1ST)], quant_tmp2, DIM1ST ); + Copy( &EnvCdbk2nd_fx[i_mult2(indice[2], DIM2ND)], quant_tmp2+DIM1ST, DIM2ND ); + + FOR( n_band = 0; n_band < DIM11-1; n_band++ ) + { + quant_tmp[n_band] = add(quant_tmp[n_band], quant_tmp2[n_band]); + move16();/*Q8 */ + SWB_fenv[n_band*2] = quant_tmp[n_band]; + move16(); /*Q8 */ + } + + IF ( EQ_16(hr_flag,1)) + { + quant_tmp[6] = add(quant_tmp[6],quant_tmp2[6]); + move16();/*Q8 */ + SWB_fenv[11] = quant_tmp[6]; + move16(); + + Copy( &EnvCdbk3rd_fx[indice[3] * DIM3RD], quant_tmp2, DIM3RD ); + Copy( &EnvCdbk3rd_fx[indice[4] * DIM3RD], quant_tmp2+DIM3RD, DIM3RD ); + + FOR(n_band = 0; n_band < 5; n_band++) + { +#ifdef BASOP_NOGLOB + SWB_fenv[add(shl(n_band,1),1)] = add_sat(shr(add_sat(quant_tmp[n_band], quant_tmp[n_band+1]),1), quant_tmp2[n_band+1]); +#else + SWB_fenv[add(shl(n_band,1),1)] = add(shr(add(quant_tmp[n_band], quant_tmp[n_band+1]),1), quant_tmp2[n_band+1]); +#endif + move16();/*Q8 */ + } + + SWB_fenv[0] = add(SWB_fenv[0], quant_tmp2[0]); + move16();/*Q8 */ + } + ELSE + { + quant_tmp[DIM11-1]=add(quant_tmp[DIM11-1],quant_tmp2[DIM11-1]); + move16();/*Q8 */ + SWB_fenv[(DIM11-1)*2] = quant_tmp[DIM11-1]; + move16(); + + Copy( &EnvCdbk3rd_fx[i_mult2(indice[3], DIM3RD)], quant_tmp2, DIM3RD ); + Copy( &EnvCdbk4th_fx[i_mult2(indice[4], DIM4TH)], quant_tmp2+DIM3RD, DIM4TH ); + + FOR( n_band = 0; n_band < DIM12-1; n_band++ ) + { +#ifdef BASOP_NOGLOB + SWB_fenv[add(shl(n_band,1),1)] = add_sat(shr(add_sat(quant_tmp[n_band],quant_tmp[n_band+1]),1),quant_tmp2[n_band]); +#else + SWB_fenv[add(shl(n_band,1),1)] = add(shr(add(quant_tmp[n_band],quant_tmp[n_band+1]),1),quant_tmp2[n_band]); +#endif + move16();/*Q8 */ + } + + SWB_fenv[n_band*2+1] = add(quant_tmp[n_band],quant_tmp2[n_band]); + move16();/*Q8 */ + } + + FOR( n_band = 0; n_band < nenv; n_band++ ) + { + tmp = add(SWB_fenv[n_band],Mean_env_fx[n_band]); /*Q8 */ + + L_tmp = L_mult(tmp, 21771); /* 0.166096 in Q17 -> Q26 */ + L_tmp = L_shr(L_tmp, 10); /* From Q26 to Q16 */ + frac = L_Extract_lc(L_tmp, &exp); /* Extract exponent of L_tmp */ + + tmp = extract_l(Pow2(13, frac));/* Put 13 as exponent so that */ + /* output of Pow2() will be: */ + /* 16384 < Pow2() <= 32767 */ + exp = sub(exp, 13); + SWB_fenv[n_band] = shl(tmp, add(exp,1)); + move16();/*Q1 */ + } + + IF ( EQ_16(hqswb_clas,HQ_GEN_FB)) + { + Copy( &EnvCdbkFB_fx[i_mult2(indice[5], DIM_FB)], &SWB_fenv[nenv], DIM_FB ); /*Q7 */ + + FOR( n_band = 0; n_band < DIM_FB; n_band++ ) + { + tmp = add(SWB_fenv[add(n_band,nenv)], Mean_env_fb_fx[n_band]); + L_tmp = L_mult(tmp, 21771); /* 0.166096 in Q17 -> Q25 */ + L_tmp = L_shr(L_tmp, 9); /* From Q25 to Q16 */ + frac = L_Extract_lc(L_tmp, &exp); /* Extract exponent of L_tmp */ + + tmp = extract_l(Pow2(13, frac));/* Put 13 as exponent so that */ + /* output of Pow2() will be: */ + /* 16384 < Pow2() <= 32767 */ + exp = sub(exp, 13); + SWB_fenv[add(n_band,nenv)] = shl(tmp, add(exp,1)); + move16(); + } + } + + /* in case of band-width switching, attenuate frame gain */ + } + + return mode; +} + +/*-------------------------------------------------------------------* + * swb_bwe_dec() + * + * SWB BWE decoder + *-------------------------------------------------------------------*/ +Word16 swb_bwe_dec_fx( +#ifdef ADD_IVAS_BWE + const Word16 output[], /* i : suntehsis @ internal Fs */ +#endif + Decoder_State *st_fx, /* i/o: decoder state structure */ + Word16 *synth_fx, /* i/o: ACELP core synthesis/final synthesis (might be rescaled inside wtda() ) */ + Word16 *hb_synth_fx, /* o : SHB synthesis/final synthesis */ +#ifdef ADD_IVAS_BWE + const Word16 use_cldfb_for_dft, /* i : flag to use of CLDFB for DFT Stereo */ +#endif + const Word16 output_frame /* i : frame length */ + ,Word16 * Qpost +) +{ + Word16 i, l_subfr; + Word16 mode; + Word16 frica_flag = 0; + Word16 idxGain; + Word16 Q_syn, Q_syn_hb; + Word16 ysynth_fx[L_FRAME48k]; + Word16 tmp; + Word16 SWB_tenv_fx[SWB_TENV]; + Word32 L_wtda_synth_fx[2*L_FRAME48k], ysynth_32[L_FRAME48k]; + Word16 scl, new_input_fx_exp; + Word32 t_audio32_tmp[L_FRAME48k]; + Word32 SWB_tenv_tmp_fx[SWB_TENV]; + Word32 L_tmp; + Word16 exp, frac; + Word16 fb_ener_adjust_fx = 0; + Word16 SWB_fenv_fx[SWB_FENV]; + Word16 L; + Word16 j = 0; + Word16 ener_adjust_quan_fx; + Word16 tmp2; + Word16 fb_band_begin; + FD_BWE_DEC_HANDLE hBWE_FD; + hBWE_FD = st_fx->hBWE_FD; + + /*---------------------------------------------------------------------* + * SWB BWE decoding + *---------------------------------------------------------------------*/ + /* windowing of the ACELP core synthesis */ + new_input_fx_exp = *Qpost; +#ifdef ADD_IVAS_BWE + if (st->element_mode == IVAS_CPE_DFT && !use_cldfb_for_dft) + { + /* IVAS_fmToDo: wtda() does not support L_FRAME length; thus temporarily resample the signal */ + /* IVAS_fmToDo: delay output[] by 1.25ms ? */ + lerp(output, ysynthIfx, L_FRAME16k, st_fx->L_frame); + + wtda_fx(ysynth_fx, &new_input_fx_exp, L_wtda_synth_fx, hBWE_FD->L_old_wtda_swb_fx, + &hBWE_FD->old_wtda_swb_fx_exp, ALDO_WINDOW, ALDO_WINDOW, /*st->L_frame*/ L_FRAME16k); + direct_transform_fx(L_wtda_synth_fx, ysynth_32, 0, /*st->L_frame*/ L_FRAME16k, &new_input_fx_exp, st_fx->element_mode); + } + else +#endif + { + wtda_fx(synth_fx, &new_input_fx_exp, L_wtda_synth_fx, hBWE_FD->L_old_wtda_swb_fx, + &hBWE_FD->old_wtda_swb_fx_exp, + ALDO_WINDOW, + ALDO_WINDOW, /* window overlap of current frame (0: full, 2: none, or 3: half) */ + output_frame); + *Qpost = sub(new_input_fx_exp, 15); + /* DCT of the ACELP core synthesis */ + direct_transform_fx(L_wtda_synth_fx, ysynth_32, 0, output_frame, &new_input_fx_exp, st_fx->element_mode); + } + /* Convert to 16 Bits (Calc Shift Required to Stay within MAX_Q_NEW_INPUT) */ + scl = sub(16+MAX_Q_NEW_INPUT, new_input_fx_exp); + /* Possible to Upscale? */ + IF (scl > 0) + { + /* Yes */ + /* Calc Room to Upscale */ + Q_syn = Find_Max_Norm32(ysynth_32, output_frame); + /* Stay within MAX_Q_NEW_INPUT */ + scl = s_min(Q_syn, scl); + } + Copy_Scale_sig32_16(ysynth_32, ysynth_fx, output_frame, scl); + Q_syn = add(sub(new_input_fx_exp, 16), scl); + + IF( !st_fx->bfi ) + { + IF( st_fx->bws_cnt_fx > 0 ) + { + /* estimate parameters */ + mode = para_pred_bws_fx( st_fx, ysynth_fx, SWB_fenv_fx, Q_syn); + move16(); + } + ELSE + { + /* de-quantization */ + mode = swb_bwe_gain_deq_fx(st_fx, ACELP_CORE, SWB_tenv_fx, SWB_fenv_fx, 0, -1 ); + move16(); + } + + L = SWB_FENV; + move16(); + if(EQ_16(mode, TRANSIENT)) + { + L = SWB_FENV_TRANS; + move16(); + } + L_tmp = 0; + move16(); + FOR(i=0; iQ(15-exp) */ + st_fx->prev_ener_shb_fx = round_fx(L_shl(L_tmp, add(exp,2))); /*Q1 */ + } + ELSE + { + /* SHB FEC */ + IF( NE_16(hBWE_FD->prev_mode_fx, TRANSIENT)) + { + mode = hBWE_FD->prev_mode_fx; + move16(); + } + ELSE + { + mode = NORMAL; + move16(); + } + + Copy(st_fx->prev_SWB_fenv_fx, SWB_fenv_fx, SWB_FENV ); + } + + /* reconstruction of MDCT spectrum of the error signal */ + set32_fx( ysynth_32, 0, output_frame ); + IF ( EQ_16(st_fx->L_frame, L_FRAME16k)) + { + SWB_BWE_decoding_fx( ysynth_fx, SWB_fenv_fx, ysynth_32, L_FRAME32k-80, mode, &frica_flag, &hBWE_FD->prev_Energy_fx, st_fx->prev_SWB_fenv_fx, + &hBWE_FD->prev_L_swb_norm_fx, st_fx->tilt_wb_fx, &hBWE_FD->Seed_fx, 80, &hBWE_FD->prev_weight_fx, st_fx->extl, Q_syn + ,st_fx->last_extl); + } + ELSE + { + SWB_BWE_decoding_fx( ysynth_fx, SWB_fenv_fx, ysynth_32, L_FRAME32k-80, mode, &frica_flag, &hBWE_FD->prev_Energy_fx, st_fx->prev_SWB_fenv_fx, + &hBWE_FD->prev_L_swb_norm_fx, st_fx->tilt_wb_fx, &hBWE_FD->Seed_fx, 6, &hBWE_FD->prev_weight_fx, st_fx->extl, Q_syn, + st_fx->last_extl); + } + + test(); + IF ( EQ_16(hBWE_FD->prev_frica_flag_fx, 1) && frica_flag==0) + { + FOR( i = 0; i < L_SUBFR; i++ ) + { + tmp = sub(32767, extract_l(L_mult0(i, 512))); /*Q15 */ + hBWE_FD->mem_imdct_fx[i] = mult_r(hBWE_FD->mem_imdct_fx[i], tmp); + move16(); /*Q_synth */ + } + + FOR( ; i < output_frame; i++ ) + { + hBWE_FD->mem_imdct_fx[i] = 0; + move16(); + } + } + + /* decode information */ + IF ( EQ_16(st_fx->extl, FB_BWE)) + { + IF( !st_fx->bfi ) + { + idxGain = (Word16)get_next_indice(st_fx, NUM_BITS_FB_FRAMEGAIN ); + fb_ener_adjust_fx = usdequant_fx(idxGain, FB_GAIN_QLOW_FX, FB_GAIN_QDELTA_FX); /*Q15 */ + } + ELSE if( st_fx->bfi ) + { + fb_ener_adjust_fx = st_fx->prev_fb_ener_adjust_fx; + move16(); + } + + st_fx->prev_fb_ener_adjust_fx = fb_ener_adjust_fx; + move16(); + IF(EQ_16(mode, TRANSIENT)) + { + ener_adjust_quan_fx = shr(fb_ener_adjust_fx, 2); + move16(); /*Q13*/ + } + ELSE + { + IF(SWB_fenv_fx[7] != 0) + { + tmp = div_s(1, SWB_fenv_fx[7]); + move16(); /*Q14*/ +#ifdef BASOP_NOGLOB + ener_adjust_quan_fx = s_min(shr(i_mult_sat(SWB_fenv_fx[13], tmp), 2), 32767); +#else + ener_adjust_quan_fx = s_min(shr(i_mult(SWB_fenv_fx[13], tmp), 2), 32767); +#endif + move16(); /*Q13*/ + } + ELSE + { + ener_adjust_quan_fx = 0; + move16(); /*Q13*/ + } + } + fb_band_begin = FB_BAND_BEGIN; +#ifdef ADD_IVAS_BWE + IF (st_fx->L_frame == L_FRAME) + { + fb_band_begin = FB_BAND_BEGIN_12k8; + } +#endif + FOR( i = fb_band_begin; i < fb_band_begin +DE_OFFSET1; i++ ) + { + tmp = sub(32767, i_mult(j, 1024)); + tmp = mult_r(tmp, ener_adjust_quan_fx); /*Q13*/ + + tmp2 = i_mult(j, 256); /*Q13*/ + tmp2 = mult_r(tmp2, fb_ener_adjust_fx); /*Q13*/ + + tmp = add(tmp, tmp2); /*Q13*/ + ysynth_32[i] = ysynth_32[i-FB_BAND_WIDTH]; + move16(); + ysynth_32[i] = L_shl(Mult_32_16(ysynth_32[i], tmp), 2); + move32();/*15+Q_syn */ + j = add(j, 1); + } + + FOR( ; ielement_mode ); + window_ola_fx( t_audio32_tmp, hb_synth_fx, &Q_syn_hb, hBWE_FD->mem_imdct_fx, &hBWE_FD->mem_imdct_exp_fx, output_frame, ALDO_WINDOW, ALDO_WINDOW, 0,0,0); + l_subfr = mult(output_frame, 8192); + + test(); + IF( EQ_16(mode,TRANSIENT)) + { + FOR(i = 0; i < SWB_TENV; i++) + { + SWB_tenv_tmp_fx[i] = L_mult0(SWB_tenv_fx[i], 26214); + move32();/*Q15 */ + } + + /* time envelope shaping when the current frame is TRANSIENT frame */ + time_envelop_shaping_fx( hb_synth_fx, SWB_tenv_tmp_fx, output_frame, &Q_syn_hb ); + Q_syn_hb = sub(Q_syn_hb, 3); + + hBWE_FD->prev_td_energy_fx = SWB_tenv_fx[3]; + move16(); + } + ELSE IF( EQ_16(frica_flag, 1) && hBWE_FD->prev_frica_flag_fx==0) + { + time_reduce_pre_echo_fx( synth_fx, hb_synth_fx, hBWE_FD->prev_td_energy_fx, l_subfr, *Qpost, Q_syn_hb ); + } + ELSE + { + tmp = i_mult2(3, l_subfr); + L_tmp = L_deposit_l(0); + FOR(i=0; iprev_td_energy_fx = 0; + move16(); + IF(L_tmp != 0) + { + exp = norm_l(L_tmp); + frac = extract_h(L_shl(L_tmp, exp)); + exp = sub(exp, sub(30,shl(Q_syn_hb,1))); + + tmp = div_s(16384, frac); + L_tmp = L_deposit_h(tmp); + L_tmp = Isqrt_lc(L_tmp, &exp); /*Q(31-exp) */ + hBWE_FD->prev_td_energy_fx = round_fx(L_shl(L_tmp, sub(exp,15))); /*Q0 */ + } + } +#ifdef ADD_IVAS_BWE + test(); + IF (EQ_16(st_fx->element_mode, IVAS_CPE_DFT) && !use_cldfb_for_dft) + { + /* add HB synth from hf_synth() */ + v_add(hb_synth, synth, hb_synth, output_frame); + } +#endif + hBWE_FD->prev_frica_flag_fx = frica_flag; + move16(); + hBWE_FD->prev_mode_fx = mode; + move16(); + + return Q_syn_hb; +} + + +/*-------------------------------------------------------------------* +* fd_bwe_dec_init() +* +* Initialize FD BWE state structure at the decoder +*-------------------------------------------------------------------*/ + +void fd_bwe_dec_init( + Decoder_State* st_fx, /* i/o: decoder state structure */ + FD_BWE_DEC_HANDLE hBWE_FD /* i/o: FD BWE data handle */ +) +{ + hBWE_FD->old_wtda_wb_fx_exp = 0; + move16(); + set16_fx(hBWE_FD->old_syn_12k8_16k_fx, 0, NS2SA(16000, DELAY_FD_BWE_ENC_NS)); + set16_fx(hBWE_FD->L_old_wtda_swb_fx, 0, L_FRAME48k); + hBWE_FD->old_wtda_swb_fx_exp = 0; + move16(); + hBWE_FD->mem_imdct_exp_fx = 0; + move16(); + + hBWE_FD->prev_mode_fx = NORMAL; + move16(); + set16_fx(st_fx->prev_SWB_fenv_fx, 0, SWB_FENV); + hBWE_FD->prev_Energy_fx = 0; + move16(); + hBWE_FD->prev_L_swb_norm_fx = 8; + move16(); + hBWE_FD->Seed_fx = 21211; + move16(); + hBWE_FD->prev_frica_flag_fx = 0; + move16(); + set16_fx(hBWE_FD->mem_imdct_fx, 0, L_FRAME48k); + hBWE_FD->prev_td_energy_fx = 0; + move16(); + hBWE_FD->prev_weight_fx = 6554; /*0.2 in Q15*/ move16(); + hBWE_FD->prev_flag_fx = 0; + move16(); + st_fx->last_wb_bwe_ener_fx = 0; + move16(); + hBWE_FD->prev_Energy_wb_fx = L_deposit_l(0); + hBWE_FD->memExp1 = 0; + move16(); + + /* Previous frame LPC initialization for PPP */ + st_fx->prev_Q_synth = 0; + move16(); + + hBWE_FD->mem_deemph_old_syn_fx = 0; + st_fx->prev_fb_ener_adjust_fx = 0; + + return; +} \ No newline at end of file diff --git a/lib_dec/swb_bwe_dec_hr.c b/lib_dec/swb_bwe_dec_hr.c index 065a24c6bdae55440cfbe0ecd140b65c3f76e72d..74f62c6c442c6f70c1a86c62252a10e7368b6690 100644 --- a/lib_dec/swb_bwe_dec_hr.c +++ b/lib_dec/swb_bwe_dec_hr.c @@ -793,12 +793,12 @@ void swb_bwe_dec_hr( } /*-------------------------------------------------------------------* - * hr_bwe_dec_init() + * hr_bwe_dec_init_flt() * * Initialize HR BWE state structure at the decoder *-------------------------------------------------------------------*/ -void hr_bwe_dec_init( +void hr_bwe_dec_init_flt( HR_BWE_DEC_HANDLE hBWE_FD_HR /* i/o: HR BWE data handle */ ) { diff --git a/lib_dec/swb_bwe_dec_hr_fx.c b/lib_dec/swb_bwe_dec_hr_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..666a1aef75f9c46a168f2d8168d14adf2adbfd4c --- /dev/null +++ b/lib_dec/swb_bwe_dec_hr_fx.c @@ -0,0 +1,1551 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ +#include +#include "options.h" /* Compilation switches */ +#include "prot_fx1.h" /* Function prototypes */ +#include "prot_fx2.h" /* Function prototypes */ +#include "rom_com.h" /* Static table prototypes */ +#include "rom_dec.h" /* Static table prototypes */ +#include "cnst.h" /* Static table prototypes */ + +#define Q_GUARD 1 +#define Q_32_BITS 14 /* scaling of 't_audio32' */ +#define MAKE_PSEUDO_FLT(v,e) ((((Word32)(v))<<16) + (e)) + +/*-----------------------------------------------------------* + * Gain_Dequant_HR() + * + * Returns decoded gain quantized between the specified + * range using the specified number of levels. + *-----------------------------------------------------------*/ +/* It would be more efficient (PROM wise) to combine + with gain_dequant_fx(). But for now the 'max' param has + a larger allowed range here (Q13) than in gain_dequant_fx() + where is is in Q15. This applies for the 'min' param too. + Here it is Q6 in gain_dequant_fx() it is Q0. But merging the + two functions would be less efficient (Performance Wise) + since the function here doesn't use 'Log2_norm_lc' at all + versus gain_dequant_fx() which does. */ +static Word16 Gain_Dequant_HR( /* o: decoded gain (Q13) */ + Word16 index, /* i: quantization index */ + const Word16 min, /* i: value of lower limit (Q13) */ + const Word16 bits, /* i: number of bits to dequantize */ + Word16 *exp /* o: exponent of Decoded Gain */ +) +{ + Word32 L_mini, L_fact; + Word16 gain; + Word32 L_temp; + Word16 exp1,exp2, p2_frac,p2_int; + + L_mini=0; /* no complexity counted, just to remove warning */ + L_fact=0; /* no complexity counted, just to remove warning */ + + move32(); + move32(); + IF (EQ_16(min, G_AVQ_MIN_FX)) + { + L_mini = MAKE_PSEUDO_FLT(26214, 15); /* 0.8 in Q15 */ + L_fact = MAKE_PSEUDO_FLT(14145, 11); /* Log2(96) - Log2(0.8) in Q11 */ + } + ELSE IF (EQ_16(min, G_AVQ_MIN_DIV10_FX)) + { + L_mini = MAKE_PSEUDO_FLT(20972, 18); /* 0.8*0.1 in Q18 */ + L_fact = MAKE_PSEUDO_FLT(20949, 11); /* Log2(96) - Log2(0.8*0.1) in Q11 */ + } + ELSE IF (EQ_16(min, G_CODE_MIN_FX)) + { + L_mini = MAKE_PSEUDO_FLT(20972, 20); /* 0.02 in Q20 */ + L_fact = MAKE_PSEUDO_FLT(32628, 12); /* Log2(5) - Log2(0.02) in Q12 */ + } + ELSE IF (EQ_16(min, G_CODE_MIN_TC192_FX)) + { + L_mini = MAKE_PSEUDO_FLT(19661, 15); /* 0.6 in Q15 */ + L_fact = MAKE_PSEUDO_FLT(24963, 12); /* Log2(41) - Log2(0.6) in Q12 */ + } + ELSE IF (EQ_16(min, MIN_GLOB_GAIN_BWE_HR_FX)) + { + L_mini = MAKE_PSEUDO_FLT(24576, 13); /* 3.0 in Q13 */ + L_fact = MAKE_PSEUDO_FLT(30232, 12); /* Log2(500) - Log2(3) in Q12 */ + } + /* levels = 1< 0.5f) ? 1.0f : 0.5f;*/ + /* beta_flt = (alpha_flt - gain_flt)/sub(input_frame, ind2);*/ + temp2 = sub(16384, temp); + if (temp2 < 0) + temp2 = add(temp2, 16384); + temp3 = sub(input_frame, ind2); + /* Inverse 'temp3' */ + temp1 = norm_s(temp3); + temp3 = shl(temp3, temp1); + temp3 = div_s(16384, temp3); + L_Energy2 = L_mult0(temp2, temp3); + temp1 = add(temp1, 1); /* because we used 0.5 (16384) to inverse and not 1.0 (32768) */ + /* Back to Q31 */ + L_Energy2 = L_shr(L_Energy2, temp1); + + FOR( i = ind2; i < input_frame; i++ ) + { +#ifdef BASOP_NOGLOB + hb_synth_fx[i] = mult_r_sat(round_fx_sat(L_Energy), hb_synth_fx[i]); + move16(); + L_Energy = L_add_sat(L_Energy, L_Energy2); +#else + hb_synth_fx[i] = mult_r(round_fx(L_Energy), hb_synth_fx[i]); + move16(); + L_Energy = L_add(L_Energy, L_Energy2); +#endif + } + } + } + + return temp; /* in Q15 */ +} + +/*-------------------------------------------------------------------* + * swb_bwe_dec_hr_fx() + * + * HR SWB BWE decoder + *-------------------------------------------------------------------*/ + +Word16 swb_bwe_dec_hr_fx( /* o : Exponent of SHB synthesis */ + Decoder_State *st_fx, /* i/o: decoder state structure */ + const Word16 *syn_12k8_16k_fx,/* i : ACELP core synthesis @16kHz */ + const Word16 exp, /* i : Exponent of core synthesis */ + Word16 *hb_synth_fx, /* o : SHB synthesis */ + const Word16 output_frame, /* i : frame length */ + const Word16 unbits, /* i : number of core unused bits */ + const Word16 pitch_buf[] /* i : pitch buffer */ +) +{ + Word16 i, j, k, nBits, nBits_total, nBits_block, Nsv, Nsv2, width_noncoded; + Word16 is_transient, tmpS, incr, IsTransient, pos; + Word16 x_norm[NSV_MAX*(WIDTH_BAND+1)], x_norm1[NSV_MAX*(WIDTH_BAND+1)]; + Word32 t_audio32_tmp[L_FRAME48k]; + Word32 t_audio32[L_FRAME48k]; + Word16 t_audio_exp; + Word16 en_band[N_BANDS_BWE_HR]; + Word16 ind1, ind2; + Word32 L_EnergyLT, L_Energy; + Word16 nq[NSV_MAX], nq2[NSV_MAX], nq_tmp[NSV_MAX]; + Word16 alpha; + Word16 temp, temp2, temp3, temp4; + Word16 en_noncoded, min_env, max_env; + Word16 gain_fx = 0, gain2_fx, exp1, exp2; + Word16 len; + Word16 pitch; + Word32 L_temp, L_temp2; + Word32 L_tilt_wb; + Word16 hb_synth_fx_exp; + Word16 *ptr16; + Word32 *ptr32; + Word32 L_ener_all, L_ener_saved; + Word16 ener_all_exp, ener_saved_exp; + Word16 *t_audio, *t_audio_tmp; + Word16 env = 0; + Word16 exp_L, inv_L, frac; + FD_BWE_DEC_HANDLE hBWE_FD; + HR_BWE_DEC_HANDLE hBWE_FD_HR; + + hBWE_FD = st_fx->hBWE_FD; + hBWE_FD_HR = st_fx->hBWE_FD_HR; + + /* Use 't_audio32_tmp' Word32 Buffer as two Word16 Buffers to save local Stack. */ + /* There is no possible overlap so it is ok */ + t_audio = (Word16 *)&t_audio32_tmp[0]; + t_audio_tmp = (Word16 *)&t_audio32_tmp[L_FRAME48k/2]; + + hBWE_FD_HR->bwe_highrate_seed_fx = extract_l(L_mult0(pitch_buf[0],pitch_buf[3])); + + + /*---------------------------------------------------------------------* + * initializations + *---------------------------------------------------------------------*/ + + set16_fx(t_audio, 0, output_frame); + set32_fx(t_audio32, 0, output_frame); + exp2 = 0; + move16(); + Nsv2 = 0; + move16(); + /* only to suppress warnings (no complexity counted) */ + gain2_fx = 0; + move16(); + ind2 = 0; + move16(); + L_ener_saved = 0; + move16(); + ener_saved_exp = 0; + move16(); + + /* reset memories in case that last frame was a different technology */ + test(); + IF( EQ_16(st_fx->last_core, HQ_CORE)||NE_16(st_fx->last_extl,st_fx->extl)) + { + set16_fx(hBWE_FD->L_old_wtda_swb_fx, 0, L_FRAME48k ); + st_fx->hHQ_core->Q_old_wtda = 14; + move16(); + } + + /* calculate SWB BWE bit-budget */ + /* nBits = st->extl_brate/50 + unbits */ + nBits = add(320,unbits); /* st->extl_brate_fx is always 16kbps */ + nBits_total = nBits; + move16(); + + /*---------------------------------------------------------------------* + * calculate tilt of the core synthesis + *---------------------------------------------------------------------*/ + L_tilt_wb = calc_tilt_bwe_fx( syn_12k8_16k_fx, exp, L_FRAME16k ); + L_temp = L_mac(1L, 8192, pitch_buf[0]); + FOR (i = 1; i < NB_SUBFR16k-1; i++) + { + L_temp = L_mac(L_temp, 8192, pitch_buf[i]); + } + pitch = mac_r(L_temp, 8192, pitch_buf[i]); + /* pitch now in Q4 (Q6 div by 4) */ + + /*---------------------------------------------------------------------* + * FEC, or good frame decoding + *---------------------------------------------------------------------*/ + + IF( st_fx->bfi ) + { + is_transient = hBWE_FD_HR->old_is_transient_hr_bwe_fx; + move16(); + + /* Replication of the last spectrum, with an attenuation */ + test(); + test(); + IF( (EQ_16(st_fx->clas_dec, VOICED_CLAS)||EQ_16(st_fx->clas_dec,INACTIVE_CLAS))&&LE_16(st_fx->nbLostCmpt,3)) + { + alpha = 26214; /* 0.80 */ move16(); + t_audio_exp = 0; + move16(); + } + ELSE IF ( is_transient ) + { + alpha = 19661 /* 0.15 */; + move16(); + t_audio_exp = 2; + move16(); + } + ELSE + { + alpha = 19661 /* 0.30 */; + move16(); + t_audio_exp = 1; + move16(); + } + + IF( is_transient ) + { + /* output_frame == L_FRAME48k */ + tmpS = (2*END_FREQ_BWE_FULL_FB/50)/NUM_TIME_SWITCHING_BLOCKS - NUM_TRANS_START_FREQ_COEF; + move16(); + /* set BWE spectrum length */ + if( EQ_16(output_frame, L_FRAME32k)) + { + tmpS = L_FRAME32k/NUM_TIME_SWITCHING_BLOCKS - NUM_TRANS_START_FREQ_COEF; + move16(); + } + + temp = shr(output_frame, 2); + pos = NUM_TRANS_START_FREQ_COEF; + move16(); + ind1 = 0; + move16(); + /* reconstruct */ + len = 0; + move16(); + /* Here t_audio was initialy filled with zeros */ + /* So, after the loop, the Q will be 'Q_32_Bits' */ + FOR( k=0; kt_audio_prev_fx_exp[k], Q_32_BITS); + temp4 = add(temp4, t_audio_exp); + FOR( i=0; it_audio_prev_fx[i + ind1]); + L_temp = L_shr(L_temp, temp4); + t_audio32[pos + i] = L_temp; + move32(); + } + ind1 = add(ind1, tmpS); + pos = add(pos, temp); + } + /* Save transform coefficients for the next frame (needed in case of frame erasures) */ + FOR( k=0; kt_audio_prev_fx + i_mult2(k, tmpS), tmpS, temp4); + hBWE_FD_HR->t_audio_prev_fx_exp[k] = add(Q_32_BITS, temp4); + move16(); + len = add(len, shr(output_frame, 2)); + } + } + ELSE + { + /* output_frame == L_FRAME48k */ + tmpS = 2*END_FREQ_BWE_FULL_FB/50 - NUM_NONTRANS_START_FREQ_COEF; + move16(); + /* set BWE spectrum length */ + if( EQ_16(output_frame, L_FRAME32k)) + { + tmpS = L_FRAME32k - NUM_NONTRANS_START_FREQ_COEF; + move16(); + } + + /* reconstruct */ + /* Here t_audio was initialy filled with zeros */ + /* So, after the loop, the Q will be 'Q_32_Bits' */ + temp4 = sub(hBWE_FD_HR->t_audio_prev_fx_exp[0], Q_32_BITS); + temp4 = add(temp4, t_audio_exp); + ptr32 = &t_audio32[NUM_NONTRANS_START_FREQ_COEF]; + FOR( i=0; it_audio_prev_fx[i]); + L_temp = L_shr(L_temp, temp4); + *ptr32++ = L_temp; + move32(); + } + /* Save transform coefficients for the next frame (needed in case of frame erasures) */ + temp = NUM_NONTRANS_START_FREQ_COEF; + move16(); /* not necessary but improves readability and allows a larger common code path */ + temp4 = Find_Max_Norm32(t_audio32 + temp, tmpS); + Copy_Scale_sig32_16(t_audio32 + temp, hBWE_FD_HR->t_audio_prev_fx, tmpS, temp4); + hBWE_FD_HR->t_audio_prev_fx_exp[0] = add(Q_32_BITS, temp4); + move16(); + } + + hBWE_FD_HR->L_mem_EnergyLT_fx = Mul_flt32_Q15(hBWE_FD_HR->L_mem_EnergyLT_fx, &hBWE_FD_HR->mem_EnergyLT_fx_exp, alpha); + move32(); + hBWE_FD_HR->mem_EnergyLT_fx_exp = add(hBWE_FD_HR->mem_EnergyLT_fx_exp, t_audio_exp); + + /* Set Exponent */ + t_audio_exp = Q_32_BITS; + move16(); + exp_L = norm_s(output_frame); + inv_L = div_s(shl(1,sub(14,exp_L)), output_frame); /*Q(29-exp_L)*/ + + /*Q(st_fx->mem_EnergyLT_fx_exp+29-exp_L-15) -> Q(st_fx->mem_EnergyLT_fx_exp-exp_L+14)*/ + hBWE_FD_HR->L_mem_EnergyLT_fx = Mul_flt32_Q15(hBWE_FD_HR->L_mem_EnergyLT_fx, &hBWE_FD_HR->mem_EnergyLT_fx_exp, inv_L); + move32(); + IF(hBWE_FD_HR->L_mem_EnergyLT_fx != 0) + { + exp1 = norm_l(hBWE_FD_HR->L_mem_EnergyLT_fx); + frac = extract_h(L_shl(hBWE_FD_HR->L_mem_EnergyLT_fx, exp1)); + exp1 = sub(exp1,sub(16,sub(hBWE_FD_HR->mem_EnergyLT_fx_exp,exp_L))); + + temp = div_s(16384, frac); + L_temp = L_deposit_h(temp); + L_temp = Isqrt_lc(L_temp, &exp1); +#ifdef BASOP_NOGLOB + gain_fx = extract_l(L_shl_sat(L_temp, sub(exp1, 2))); /*Q(31-exp + (exp-3)) -> Q13*/ +#else + gain_fx = extract_l(L_shl(L_temp, sub(exp1, 2))); /*Q(31-exp + (exp-3)) -> Q13*/ +#endif + } + + env = 512; + move16(); + } + ELSE + { + /*---------------------------------------------------------------------* + * get transient frame flag + *---------------------------------------------------------------------*/ + + is_transient = (Word16) get_next_indice( st_fx, 1 ); + + IF( is_transient ) + { + nBits = -1; + move16(); /* is_transient flag */ + nBits_block = shr(nBits_total, 2); + nBits = add(nBits, s_and(nBits_total, 3)); + + /* set width of noncoded (blind estimated) spectrum */ + test(); + IF( EQ_16(st_fx->extl, SWB_BWE_HIGHRATE)||EQ_16(output_frame,L_FRAME32k)) + { + width_noncoded = L_FRAME32k/NUM_TIME_SWITCHING_BLOCKS - NUM_TRANS_END_FREQ_COEF; + move16(); + tmpS = L_FRAME32k/NUM_TIME_SWITCHING_BLOCKS - NUM_TRANS_END_FREQ_COEF_EFF; + move16(); + } + ELSE /* st->extl == FB_BWE_HIGHRATE */ + { + width_noncoded = (2*END_FREQ_BWE_FULL_FB/50)/NUM_TIME_SWITCHING_BLOCKS - NUM_TRANS_END_FREQ_COEF; + move16(); + tmpS = (2*END_FREQ_BWE_FULL_FB/50)/NUM_TIME_SWITCHING_BLOCKS - NUM_TRANS_END_FREQ_COEF_EFF; + move16(); + } + + /*---------------------------------------------------------------------* + * transient frames: processing in blocks (subframes) + *---------------------------------------------------------------------*/ + len = 0; + move16(); + FOR( k = 0; k < NUM_TIME_SWITCHING_BLOCKS; k++ ) + { + nBits = add(nBits, nBits_block); + + /*---------------------------------------------------------------------* + * global gain and envelope decoding + *---------------------------------------------------------------------*/ + + /* get global gain */ + ind1 = (Word16) get_next_indice( st_fx, NBITS_GLOB_GAIN_BWE_HR ); + gain_fx = Gain_Dequant_HR( ind1, MIN_GLOB_GAIN_BWE_HR_FX, NBITS_GLOB_GAIN_BWE_HR, &exp1 ); + nBits = sub(nBits, NBITS_GLOB_GAIN_BWE_HR); + + /* get energy per band */ + IF( k == 0 ) + { + ind1 = (Word16)get_next_indice( st_fx, NBITS_ENVELOPE_BWE_HR_TR ); + ind2 = ind1; + move16(); + nBits = sub(nBits, NBITS_ENVELOPE_BWE_HR_TR); + } + ELSE + { + ind1 = (Word16)get_next_indice( st_fx, NBITS_ENVELOPE_BWE_HR_TR - 1 ); + if( GE_16(ind2, 8)) + { + ind1 = add(ind1, NUM_ENVLOPE_CODE_HR_TR2); + } + nBits = sub(nBits, NBITS_ENVELOPE_BWE_HR_TR - 1); + } + + temp = shl(ind1, 1); + en_band[0] = swb_hr_env_code3_fx[temp]; + move16(); + en_band[1] = swb_hr_env_code3_fx[add(temp, 1)]; + move16(); + + /*env = add(shr(en_band[0], 1), shr(en_band[1], 1));*/ + env = mac_r(L_mult(en_band[0], 16384), en_band[1], 16384); + + /*---------------------------------------------------------------------* + * estimate energy of noncoded spectrum (14.4-20kHz) + *---------------------------------------------------------------------*/ + + en_noncoded = en_band[N_BANDS_TRANS_BWE_HR-1]; + move16(); + + IF( EQ_16(st_fx->extl, FB_BWE_HIGHRATE)) + { + ind1 = (Word16)get_next_indice( st_fx, NBITS_HF_GAIN_BWE_HR ); + nBits = sub(nBits, NBITS_HF_GAIN_BWE_HR); + + IF (EQ_16(ind1, 1)) + { + en_noncoded = round_fx(L_mult0(en_noncoded, BWE_HR_TRANS_EN_LIMIT1_FX_Q16)); + } + + IF( EQ_16(ind1, 2)) + { + en_noncoded = round_fx(L_mult0(en_noncoded, BWE_HR_TRANS_EN_LIMIT2_FX_Q16)); + } + + IF( EQ_16(ind1, 3)) + { + en_noncoded = round_fx(L_mult0(en_noncoded, BWE_HR_TRANS_EN_LIMIT3_FX_Q16)); + } + } + + /*---------------------------------------------------------------------* + * AVQ decoding (dequantize normalized spectrum) + *---------------------------------------------------------------------*/ + + Nsv = (NUM_TRANS_END_FREQ_COEF - NUM_TRANS_START_FREQ_COEF) / WIDTH_BAND; + move16(); +#ifdef AVQ_DEMUX + AVQ_demuxdec_fx(st_fx, x_norm, &nBits, Nsv, nq, 0, sub(Nsv,1)); +#else + AVQ_demuxdec_fx( st_fx, x_norm, &nBits, Nsv, nq ); +#endif + temp = add(len, NUM_TRANS_START_FREQ_COEF); + /* 't_audio' in Q8 */ + t_audio_exp = 8; + move16(); + FOR( i=0; i < Nsv*WIDTH_BAND; i++ ) + { + t_audio[temp + i] = shl(x_norm[i], t_audio_exp); + move16(); + } + + /* apply noise-fill */ +#ifdef BASOP_NOGLOB + swb_hr_noise_fill_fx( is_transient, NUM_TRANS_START_FREQ_COEF, NUM_TRANS_END_FREQ_COEF, round_fx_sat(L_shl_sat(L_tilt_wb, 3)), /* Q(24+3-16) -> Q11 */ + pitch, nq, Nsv, &hBWE_FD_HR->bwe_highrate_seed_fx, t_audio+temp, t_audio_exp ); +#else + swb_hr_noise_fill_fx( is_transient, NUM_TRANS_START_FREQ_COEF, NUM_TRANS_END_FREQ_COEF, round_fx(L_shl(L_tilt_wb, 3)), /* Q(24+3-16) -> Q11 */ + pitch, nq, Nsv, &hBWE_FD_HR->bwe_highrate_seed_fx, t_audio+temp, t_audio_exp ); +#endif + /* Go from Q't_audio_exp' on 16 Bits to 'Q_32_BITS' on 32 bits */ + temp2 = i_mult2(WIDTH_BAND, Nsv); + ptr16 = &t_audio[temp]; + move16(); + ptr32 = &t_audio32[temp]; + j = shl(1, sub(Q_32_BITS, t_audio_exp)); + FOR (i = 0; i< temp2; i++) + { + /* put in 'Q_32_BITS' in a 32 Bits */ + L_temp = L_mult0(*ptr16++, j); + *ptr32++ = L_temp; + move32(); + } + + /*---------------------------------------------------------------------* + * reconstruction + *---------------------------------------------------------------------*/ + + temp = add(temp, NUM_TRANS_END_FREQ_COEF_EFF-NUM_TRANS_START_FREQ_COEF); + pos = sub(temp, tmpS); + ptr32 = &t_audio32[temp]; + /* reconstruct 14-16(20) kHz spectrum */ + FOR( j = 0; j < tmpS; j++ ) + { + *ptr32++ = L_shr(t_audio32[pos + j], 1); + move32(); + } + + temp = i_mult2(shr(output_frame, 2), k); + + temp2 = add(NUM_TRANS_START_FREQ_COEF, temp); + ptr32 = &t_audio32[temp2]; + /* envelope denormalization */ + FOR( i=0; it_audio_prev_fx + i_mult2(k, pos), pos, temp4); + hBWE_FD_HR->t_audio_prev_fx_exp[k] = add(Q_32_BITS, temp4); + move16(); + len = add(len, shr(output_frame, 2)); + + /* attenuate HFs in case of band-width switching */ + IF( st_fx->bws_cnt1_fx > 0 ) + { + temp = shr(output_frame, 2); + temp = i_mult(k, temp); + temp = add(NUM_TRANS_START_FREQ_COEF, temp); + temp2 = i_mult(st_fx->bws_cnt1_fx, 1638); /*Q15*/ + + j = (2*END_FREQ_BWE_FULL_FB/50)/NUM_TIME_SWITCHING_BLOCKS - NUM_TRANS_START_FREQ_COEF; + move16(); + if( output_frame == L_FRAME32k ) + { + j = L_FRAME32k/NUM_TIME_SWITCHING_BLOCKS - NUM_TRANS_START_FREQ_COEF; + move16(); + } + + FOR( i=0; iextl, FB_BWE_HIGHRATE)) + { + ind1 = (Word16) get_next_indice( st_fx, NBITS_HF_GAIN_BWE_HR ); + nBits = sub(nBits, NBITS_HF_GAIN_BWE_HR); + + if (EQ_16(ind1, 1)) + { + /* en_noncoded = BWE_HR_NONTRANS_EN_LIMIT1*(0.5*min_env) ==> 0.25*min_env */ + en_noncoded = mult_r(min_env, BWE_HR_NONTRANS_EN_LIMIT2_FX_Q15/2); + } + + IF (EQ_16(ind1, 2)) + { + /* en_noncoded = 2.0*BWE_HR_NONTRANS_EN_LIMIT2*(0.5*min_env) ==> 1.2*min_env */ + en_noncoded = round_fx(L_shl(L_mult(BWE_HR_NONTRANS_EN_LIMIT2_FX_Q14, min_env), 1)); + } + + if (EQ_16(ind1, 3)) + { + /* en_noncoded = 2.0*BWE_HR_NONTRANS_EN_LIMIT3*(0.5*min_env) ==> 0.8*min_env */ + en_noncoded = mult_r(BWE_HR_NONTRANS_EN_LIMIT3_FX_Q15, min_env); + } + } + + /*---------------------------------------------------------------------* + * AVQ decoding (dequantize normalized spectrum) + *---------------------------------------------------------------------*/ + + /* Nsv = i / WIDTH_BAND */ + Nsv = shr(i, 3); +#ifdef AVQ_DEMUX + AVQ_demuxdec_fx( st_fx, x_norm, &nBits, Nsv, nq, 0, sub(Nsv,1) ); +#else + AVQ_demuxdec_fx( st_fx, x_norm, &nBits, Nsv, nq ); +#endif + /*---------------------------------------------------------------------* + * second stage decoding + *---------------------------------------------------------------------*/ + + test(); + IF( GE_16(nBits, 9 + NBITS_GLOB_GAIN_BWE_HR)&&sum16_fx(nq,Nsv)>0) + { + ind1 = (Word16) get_next_indice( st_fx, NBITS_GLOB_GAIN_BWE_HR ); + gain2_fx = Gain_Dequant_HR( ind1, MIN_GLOB_GAIN_BWE_HR_FX, NBITS_GLOB_GAIN_BWE_HR, &exp2 ); + /* gain2_flt *= 0.0625f */ + exp2 = add(exp2, 4); + + /* calculate the number of subbands according to the rest bits */ + IF( GT_16(nBits, 396)) + { + Nsv2 = 33; + move16(); + } + ELSE + { + /* Here what is acheived is an integer divide by 12 with truncation. */ + /* nBits/12 */ + Nsv2 = mult(nBits, 2731); + /* But, we have imprecision of the fraction so correction is necessary. */ + /* We crosscheck if 'Nsv2' is either too high or too low. */ + /* Finally, the result must satisfy: */ + /* Nsv2 * 12 <= nBits (Nsv2 is not too high) AND */ + /* nBits - Nsv2 * 12 < 12 (Nsv2 is the highest divisor) */ + L_temp = L_msu0(L_deposit_l(nBits), 12, Nsv2); + if (GE_32(L_temp, 12L)) + Nsv2 = add(Nsv2, 1); + if (L_temp < 0) + Nsv2 = sub(Nsv2, 1); + } + + nBits = sub(nBits, NBITS_GLOB_GAIN_BWE_HR); +#ifdef AVQ_DEMUX + AVQ_demuxdec_fx( st_fx, x_norm1, &nBits, Nsv2, nq2, 0, sub(Nsv2,1) ); +#else + AVQ_demuxdec_fx( st_fx, x_norm1, &nBits, Nsv2, nq2 ); +#endif + } + + /*---------------------------------------------------------------------* + * dequantization + *---------------------------------------------------------------------*/ + + /* set 't_audio' exp */ + t_audio_exp = 10; + move16(); + FOR( i = 0; i < Nsv*WIDTH_BAND; i++ ) + { + t_audio_tmp[i] = shl(x_norm[i], t_audio_exp); + move16(); + } + + Copy( nq, nq_tmp, Nsv ); + IF( GT_16(Nsv2, Nsv)) + { + /* Safety check, happens rarely */ + set16_fx( nq_tmp + Nsv, 0, sub(Nsv2, Nsv) ); + } + + incr = 0; + move16(); + ptr16 = x_norm1; + temp2 = sub(sub(exp2, 15), t_audio_exp); /* go to Q't_audio' */ + FOR( i=0; i=ind1; i-- ) + { + nq[j] = nq[i]; + move16(); + j = sub(j, 1); + } + + Copy( nq + ind2, nq + ind1, add(WIDTH_BAND, pos) ); + } + } + + /* apply noise-fill */ + IF( LT_16(nBits, 200)) + { + swb_hr_noise_fill_fx(is_transient, NUM_NONTRANS_START_FREQ_COEF, NUM_NONTRANS_END_FREQ_COEF, +#ifdef BASOP_NOGLOB + round_fx_sat(L_shl_sat(L_tilt_wb, 3)), /* Q(24+3-16) -> Q11 */ +#else + round_fx(L_shl(L_tilt_wb, 3)), /* Q(24+3-16) -> Q11 */ +#endif + pitch, nq, Nsv, &hBWE_FD_HR->bwe_highrate_seed_fx, t_audio + NUM_NONTRANS_START_FREQ_COEF, t_audio_exp ); + } + + /* Go from Q't_audio_exp' on 16 Bits to Q16 on 32 bits */ + ptr32 = &t_audio32[NUM_NONTRANS_START_FREQ_COEF]; + j = shl(1, sub(Q_32_BITS, t_audio_exp)); + FOR (i = 0; i < temp4; i++) + { + /* put in 'Q_32_BITS' in a 32 Bits */ + L_temp = L_mult0(*ptr16++, j); + *ptr32++ = L_temp; + move32(); + } + + /*---------------------------------------------------------------------* + * reconstruction + *---------------------------------------------------------------------*/ + + /* smoothing 12.6-12.8kHz */ + test(); + IF( EQ_16(pos, 3)&&LE_16(nBits_total,400)) + { + ptr16 = &t_audio[NUM_NONTRANS_START_FREQ_COEF + 200 - WIDTH_BAND]; + L_temp = L_mac0(1L/* EPSILON */, *ptr16, *ptr16); + FOR (i = 1; i < WIDTH_BAND; i++) + { + ptr16++; + L_temp = L_mac0(L_temp, *ptr16, *ptr16); + } + ptr16++; + L_temp2 = L_mac0(1L/* EPSILON */, *ptr16, *ptr16); + FOR (i = 1; i < WIDTH_BAND; i++) + { + ptr16++; + L_temp2 = L_mac0(L_temp2, *ptr16, *ptr16); + } + L_temp = Sqrt_Ratio32(L_temp, 0, L_temp2, 0, &temp); + + /* if 'temp' is < 0 then it is req to shift right before substracting 1.0 */ + temp2 = s_min(0, temp); + L_temp = L_shl(L_temp, temp2); + /* Energy_flt - i*(Energy_flt-1.0)/8.0 */ + L_temp2 = L_add(L_temp, L_shr(-2147483647L-1L, s_max(0, temp))); /* 1.0 in same Q as Sqrt minus the Guard */ + /* / 8.0 */ + L_temp2 = L_shr(L_temp2, 3+Q_GUARD); + /* Add Guard */ + L_temp = L_shr(L_temp, Q_GUARD); + /* Set Index */ + ptr16 = &t_audio[NUM_NONTRANS_START_FREQ_COEF + 200]; + ptr32 = &t_audio32[NUM_NONTRANS_START_FREQ_COEF + 200]; + /* Set Exponent (relative to t_audio_exp (from 16 bits vector) */ + temp2 = add(sub(temp, temp2), sub(Q_GUARD-(16-Q_32_BITS), t_audio_exp)); + + FOR( i=0; iextl == FB_BWE_HIGHRATE */ + test(); + if( EQ_16(st_fx->extl, SWB_BWE_HIGHRATE)||EQ_16(output_frame,L_FRAME32k)) + { + width_noncoded = L_FRAME32k - NUM_NONTRANS_END_FREQ_COEF; + move16(); + } + + ptr16 = &t_audio[NUM_NONTRANS_END_FREQ_COEF - WIDTH_BAND]; + L_temp = L_mac0(1L/* EPSILON */, *ptr16, *ptr16); + FOR (i = 1; i < WIDTH_BAND; i++) + { + ptr16++; + L_temp = L_mac0(L_temp, *ptr16, *ptr16); + } + + ptr16 = &t_audio[sub(NUM_NONTRANS_END_FREQ_COEF, width_noncoded)]; + L_temp2 = L_mac0(1L/* EPSILON */, *ptr16, *ptr16); + FOR (i = 1; i < WIDTH_BAND; i++) + { + ptr16++; + L_temp2 = L_mac0(L_temp2, *ptr16, *ptr16); + } + L_temp = Sqrt_Ratio32(L_temp, 0, L_temp2, 0, &temp); + + /* So part of the copy can be skipped because the loop that follows */ + /* will take the values from t_audio (16 bits) */ + /* Since 'width_noncoded' is always > WIDTH_BAND, we can substract it from the length */ + /* and adjust the offset accordingly */ + Copy32( t_audio32 + sub(NUM_NONTRANS_END_FREQ_COEF+WIDTH_BAND, width_noncoded), + t_audio32 + NUM_NONTRANS_END_FREQ_COEF+WIDTH_BAND, sub(width_noncoded, WIDTH_BAND) ); + + /* smoothing 14.4-14.8kHz */ + ptr16 = &t_audio[sub(NUM_NONTRANS_END_FREQ_COEF, width_noncoded)]; + ptr32 = &t_audio32[NUM_NONTRANS_END_FREQ_COEF]; + temp = sub(temp, add(t_audio_exp, 16-Q_32_BITS)); + FOR( i=0; iextl,SWB_BWE_HIGHRATE)||LT_16(temp,shl_sat(18022,sub(15-13,temp2)))) /* 2.2 in Q13 == 18022 */ +#else + IF( EQ_16(st_fx->extl,SWB_BWE_HIGHRATE)||LT_16(temp,shl(18022,sub(15-13,temp2)))) /* 2.2 in Q13 == 18022 */ +#endif + { + + /* (en_band_flt[3] - j*(en_band_flt[3]/WIDTH_BAND - en_noncoded_flt/WIDTH_BAND)) */ + L_temp = L_deposit_h(en_band[3]); + L_temp2 = L_mult(sub(en_band[3], en_noncoded), 32768/WIDTH_BAND); + ptr32 = &t_audio32[NUM_NONTRANS_END_FREQ_COEF]; + /* in L_temp/L_temp2, value in Q16+9 */ + FOR( j=0; j Q23 */ + L_temp2 = Mult_32_16(L_temp,32768/160); /* step */ + FOR( j=0; j Q25 */ + L_temp2 = Mult_32_16(L_temp,32768/320); /* step */ + FOR( ; jt_audio_prev_fx, pos, temp4); + hBWE_FD_HR->t_audio_prev_fx_exp[0] = add(Q_32_BITS, temp4); + move16(); + + /* attenuate HFs in case of band-width switching */ + IF( st_fx->bws_cnt1_fx > 0 ) + { + temp = i_mult(st_fx->bws_cnt1_fx, 1638); /*Q15*/ + + j = 2*END_FREQ_BWE_FULL_FB/50 - NUM_NONTRANS_START_FREQ_COEF; + move16(); + if( output_frame == L_FRAME32k ) + { + j = L_FRAME32k - NUM_NONTRANS_START_FREQ_COEF; + move16(); + } + + FOR( i=0; iprev_ener_shb_fx = extract_h(L_shr(L_mult0(32767, env), 7)); + } + ELSE + { + st_fx->prev_ener_shb_fx = extract_h(L_shr(L_mult0(gain_fx, env), 7)); + } + FOR(i=0; iprev_SWB_fenv_fx[i] = st_fx->prev_ener_shb_fx; + move16(); + } + + /*---------------------------------------------------------------------* + * iOLA and iMDCT + *---------------------------------------------------------------------*/ + + t_audio_exp = Q_32_BITS; + + Inverse_Transform( t_audio32, &t_audio_exp, t_audio32_tmp, is_transient, output_frame, output_frame, st_fx->element_mode); + window_ola_fx( t_audio32_tmp, hb_synth_fx, &t_audio_exp, hBWE_FD->L_old_wtda_swb_fx, &st_fx->hHQ_core->Q_old_wtda, output_frame,ALDO_WINDOW, ALDO_WINDOW, 0,0,0); + hb_synth_fx_exp = t_audio_exp; + move16(); + + /*---------------------------------------------------------------------* + * final adjustments + *---------------------------------------------------------------------*/ + + IF( !st_fx->bfi ) + { + IsTransient = 0; + move16(); + L_EnergyLT = L_add(hBWE_FD_HR->L_mem_EnergyLT_fx, 0); + temp4 = hBWE_FD_HR->mem_EnergyLT_fx_exp; + move16(); + pos = 0; + move16(); + + ptr16 = hb_synth_fx; + move16(); + + len = shr(output_frame, 2); /* Divide Frame Len by 4, all (160, 320, 640, 960) are divisible by 4 */ + L_ener_all = L_deposit_l(0); + ener_all_exp = 40; + move16(); /* set to a high exponent */ + + FOR( j=0; j<4; j++ ) + { + L_Energy = Calc_Energy_Autoscaled(ptr16, hb_synth_fx_exp, len, &temp2); + ptr16 += len; + move16(); + /* Normalize Energy */ + temp = norm_l(L_Energy); + L_Energy = L_shl(L_Energy, temp); + /* Update Exponent of 'L_Energy' */ + temp2 = add(temp2, temp); + + /* Normalize Long Term Energy */ + temp = norm_l(L_EnergyLT); + L_EnergyLT = L_shl(L_EnergyLT, temp); + /* Calculate Exponent of Long Term Energy */ + temp = add(temp, temp4); + + /* Divide by 12.5 */ + L_temp = Mult_32_16(L_Energy, 20972); /* 20972 = 1/12.5*32768*8 (*8 to boost precision) */ + temp3 = norm_l(L_temp); + L_temp = L_shl(L_temp, temp3); + temp3 = add(add(temp2, temp3), 3); + /* Energies are Strictly Positive Values and Normalized + (compare exponent and value only if exponent is same) */ + /* Replaces: 'if (Energy_flt > 12.5f * EnergyLT_flt )' */ + temp3 = sub(temp3, temp); + test(); + test(); + IF (temp3 < 0 || (GT_32(L_temp, L_EnergyLT)&&temp3==0)) + { + IsTransient = 1; + move16(); + pos = j; + move16(); + L_ener_saved = L_add(L_ener_all, 0); + ener_saved_exp = ener_all_exp; + move16(); + } + + L_ener_all = Add_flt32_flt32(L_Energy, temp2, L_ener_all, ener_all_exp, &ener_all_exp); + /* 0.25f*Energy_flt */ + temp2 = add(temp2, 2); + /* 0.75f*EnergyLT_flt */ + L_EnergyLT = L_sub(L_EnergyLT, L_shr(L_EnergyLT, 2)); + /* Exponent of 'L_EnergyLT' is 'temp' */ + /* Exponent of 'L_Energy' is 'temp2' */ + /* EnergyLT = 0.75f*EnergyLT + 0.25f*Energy */ + L_EnergyLT = Add_flt32_flt32(L_Energy, temp2, L_EnergyLT, temp, &temp4); + } + + test(); + test(); + test(); + IF( IsTransient != 0 && pos > 0 && LT_32(L_tilt_wb, 16777216L*3/*tilt_wb in Q24*/)&>_16(pitch,500*16/*Q4*/)) + { + Nsv = i_mult2(pos, shr(output_frame, 2)); + + gain_fx = 16384; /* sqrt(1.0) in Q14 */ + /* pos is 1,2 or 3 */ + temp3 = sub(pos, 2); + if (temp3 == 0) + { + gain_fx = 23170; + move16(); /* sqrt(2.0) in Q14 */ + } + + if (temp3 > 0) + { + gain_fx = 28378; + move16(); /* sqrt(3.0) in Q14 */ + } + exp1 = 14; + move16(); + + IF( EQ_16(st_fx->last_extl, st_fx->extl)) + { + L_temp = Div_flt32_flt32( L_ener_saved, ener_saved_exp, hBWE_FD_HR->L_mem_EnergyLT_fx, hBWE_FD_HR->mem_EnergyLT_fx_exp, &temp2 ); + temp3 = sub(temp2, 1); + L_temp2 = Isqrt_lc(L_temp, &temp3); + temp3 = sub(sub(30+31-15+1, temp2), temp3); + + L_temp = Mult_32_16(L_temp2, gain_fx); + temp = norm_l(L_temp); + L_temp2 = L_shl(L_temp, temp); + gain_fx = round_fx(L_temp2); + exp1 = sub(add(temp3, temp), sub(31, exp1)); /* gain_fx is in Q14 */ + } + + L_temp = L_mult0(26214, gain_fx); + /* +16: Because 26214 is 0.2 in Q16 + * -16: Because of round_fx + * -15: To get exponent with ref to Q15 + * +1: Because of L_mult'0' + * and the normalization + */ + exp2 = add(exp1, +16-16-15+1); + temp = norm_l(L_temp); + L_temp = L_shl(L_temp, temp); + exp2 = add(exp2, temp); + temp = round_fx(L_temp); /* Gain is in Q15+x */ + FOR( i=0; i>(19-15+1)); /* 19-15+1 to Bring to Q30 */ + FOR ( i = 0; i < len; i++ ) + { + /* hb_synth[i+Nsv] *= (gain_flt - i*8.0f*(1.0f/output_frame*gain_flt - 1.0f/output_frame)) */ + *ptr16 = round_fx(L_shl(Mult_32_16(L_temp, *ptr16), 1)); + ptr16++; + L_temp = L_sub(L_temp, L_temp2); + } + } + + hBWE_FD_HR->L_mem_EnergyLT_fx = L_EnergyLT; + move32(); + hBWE_FD_HR->mem_EnergyLT_fx_exp = temp4; + move16(); + hBWE_FD_HR->old_is_transient_hr_bwe_fx = is_transient; + move16(); + } + + /* post-processing in case of TD/FD switching */ + test(); + IF( EQ_16(st_fx->last_core, HQ_CORE)||NE_16(st_fx->last_extl,st_fx->extl)) + { + IF( LT_32(L_tilt_wb, 16777216L*3/*tilt_wb in Q24*/)) + { + temp = TD_Postprocess( hb_synth_fx, hb_synth_fx_exp, output_frame, st_fx->last_extl ); + + FOR( i=0; iL_old_wtda_swb_fx[i] = mult_r(hBWE_FD->L_old_wtda_swb_fx[i], temp); + move16(); + } + + tmpS = L_FRAME32k - NUM_NONTRANS_START_FREQ_COEF; + move16(); + if( EQ_16(output_frame,L_FRAME48k)) + { + tmpS = 2*END_FREQ_BWE_FULL_FB/50 - NUM_NONTRANS_START_FREQ_COEF; + move16(); + } + + FOR( i=0; it_audio_prev_fx[i] = mult_r(hBWE_FD_HR->t_audio_prev_fx[i], temp); + move16(); + } + } + } + + return hb_synth_fx_exp; +} + +/*-------------------------------------------------------------------* + * hr_bwe_dec_init() + * + * Initialize HR BWE state structure at the decoder + *-------------------------------------------------------------------*/ + +void hr_bwe_dec_init( + HR_BWE_DEC_HANDLE hBWE_FD_HR /* i/o: HR BWE data handle */ +) +{ + set16_fx(hBWE_FD_HR->t_audio_prev_fx, 0, 2 * END_FREQ_BWE_FULL_FB / 50 - NUM_NONTRANS_START_FREQ_COEF); + set16_fx(hBWE_FD_HR->t_audio_prev_fx_exp, 0, NUM_TIME_SWITCHING_BLOCKS); /* one exp per switching block */ + hBWE_FD_HR->old_is_transient_hr_bwe_fx = 0; + move16(); + hBWE_FD_HR->bwe_highrate_seed_fx = 12345; + move16(); + + hBWE_FD_HR->L_mem_EnergyLT_fx = L_deposit_h(16384); + hBWE_FD_HR->mem_EnergyLT_fx_exp = 40; + move16(); /* set to a high exponent */ + + return; +} diff --git a/lib_dec/swb_bwe_dec_lr_fx.c b/lib_dec/swb_bwe_dec_lr_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..8c5f7eedbaf4174752284a684028e58d1422210b --- /dev/null +++ b/lib_dec/swb_bwe_dec_lr_fx.c @@ -0,0 +1,347 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include "options.h" +#include "cnst.h" +#include "prot_fx1.h" +#include "prot_fx2.h" +#include "rom_com.h" + +/*-------------------------------------------------------------------* + * DecodeSWBGenericParameters() + * + * Decoding of generic subband coding parameters + *-------------------------------------------------------------------*/ + +static void DecodeSWBGenericParameters_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + Word16 *lagIndices_fx, /* o : lowband index for each subband */ + const Word16 nBands_search_fx, /* i : number of subbnads for SSearch */ + const Word16 BANDS_fx, /* i : total number of subbands per frame */ + const Word16 *p2a_flags_fx, /* i : HF tonal flag */ + const Word16 hq_swb_clas_fx /* i : mode of operation HQ_NORMAL or HQ_HARMONIC */ +) +{ + Word16 sb; + + /* lag index for each subband (except last two) */ + FOR (sb = 0; sb < nBands_search_fx; sb++) + { + IF( EQ_16(hq_swb_clas_fx, HQ_HARMONIC)) + { + lagIndices_fx[sb] = get_next_indice(st_fx, bits_lagIndices_mode0_Har[sb]); + move16(); + } + ELSE + { + IF( p2a_flags_fx[BANDS_fx-NB_SWB_SUBBANDS+sb] == 0 ) + { + lagIndices_fx[sb] = get_next_indice(st_fx, bits_lagIndices_modeNormal[sb]); + move16(); + } + ELSE + { + lagIndices_fx[sb] = 0; + move16(); + } + } + } + + return; +} + +/*-------------------------------------------------------------------* + * DecodeSWBSubbands() + * + * Main routine for generic SWB coding + * + * High-frequency subbands are replicated based on the lowband signal using a lowband index denoting + * the selected lowband subband as well as linear and logarithmic domain gains + *-------------------------------------------------------------------*/ + +static void DecodeSWBSubbands_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + HQ_DEC_HANDLE hHQ_core, /* i/o: HQ decoder handle */ + Word32 *L_spectra, /* i/o: MDCT domain spectrum */ + Word16 QsL, /* i : Q value of spectra */ + const Word16 fLenLow_fx, /* i : lowband length */ + const Word16 fLenHigh_fx, /* i : highband length */ + const Word16 nBands_fx, /* i : number of subbands */ + const Word16 *sbWidth_fx, /* i : subband lengths */ + const Word16 *subband_offsets_fx, /* i : subband offsets */ + Word16 *lagIndices_fx, /* i : lowband index for each subband */ + Word16 *lagGains_fx, /* i : first gain for each subband */ + Word16 *QlagGains, /* i : Q value of lagGains */ + Word16 BANDS_fx, /* i : number subbands per frame */ + Word16 *band_start_fx, /* i : band start of each SB */ + Word16 *band_end_fx, /* i : band end of each SB */ + Word32 *L_band_energy, /* i : band energy of each SB */ + Word16 Qbe, /* i : Q value of band energy */ + Word16 *p2a_flags_fx, /* i : HF tonal indicator */ + const Word16 hqswb_clas_fx, /* i : class information */ + const Word16 har_bands_fx, /* i : number of LF harmonic bands */ + const Word16 *subband_search_offset_fx, /* i : Number of harmonic LF bands */ + Word16 *prev_frm_hfe2_fx, /* i/o: */ + Word16 *prev_stab_hfe2_fx, /* i/o: */ + Word16 band_width_fx[], /* i : subband band widths */ + const Word32 L_spectra_ni[], /* i/o: core coder with sparseness filled */ + Word16 *ni_seed_fx /* i/o: random seed for search buffer NI */ +) +{ + Word16 i,k; + + Word16 sspectra_fx[L_FRAME32k]; + Word16 Qss; + + Word16 sspectra_ni_fx[L_FRAME32k], sspectra_diff_fx[L_FRAME32k]; + Word32 L_be_tonal[SWB_HAR_RAN1]; + Word16 ss_min_fx; /* Qss */ + Word32 L_th_g[NB_SWB_SUBBANDS]; + Word16 QbeL; + GainItem_fx pk_sf_fx[N_NBIGGEST_SEARCH_LRG_B]; + Word16 pul_res_fx[NB_SWB_SUBBANDS]; + Word16 g_fx; /* Q11 */ + Word16 imin_fx; + Word16 Qg; + + Word16 lagIndices_real_fx[NB_SWB_SUBBANDS]; + Word32 L_xSynth_har[L_FRAME32k]; /* Qs */ + + Word32 L_temp; + Word16 temp_lo_fx, temp_hi_fx; + + Word16 har_freq_est1; + Word16 har_freq_est2; + Word16 flag_dis; + Word16 pos_max_hfe2; + + + har_freq_est1 = 0; + move16(); + har_freq_est2 = 0; + move16(); + flag_dis = 1; + move16(); + pos_max_hfe2 = 0; + move16(); + + set16_fx(pul_res_fx,0,NB_SWB_SUBBANDS); + + IF( EQ_16(hqswb_clas_fx, HQ_HARMONIC)) + { + pos_max_hfe2 = har_est_fx( L_spectra, fLenLow_fx, &har_freq_est1, &har_freq_est2, &flag_dis, prev_frm_hfe2_fx, subband_search_offset_fx, sbWidth_fx, prev_stab_hfe2_fx ); + noise_extr_corcod_fx(L_spectra, L_spectra_ni, sspectra_fx, sspectra_diff_fx, sspectra_ni_fx, fLenLow_fx, hHQ_core->prev_hqswb_clas_fx, &(hHQ_core->prev_ni_ratio_fx), &Qss); + IF( flag_dis == 0 ) + { + test(); + if( NE_16(har_freq_est2, SWB_HAR_RAN1)||NE_16(har_freq_est2,*prev_frm_hfe2_fx)) + { + har_freq_est2 = add(har_freq_est2, lagIndices_fx[0]); + } + } + + /* Generate HF noise */ + genhf_noise_fx(sspectra_diff_fx, Qss, L_xSynth_har, QsL, sspectra_fx, BANDS_fx, har_bands_fx, har_freq_est2, pos_max_hfe2, pul_res_fx, pk_sf_fx, fLenLow_fx, fLenHigh_fx, sbWidth_fx, lagIndices_fx, subband_offsets_fx, subband_search_offset_fx); + + imin_fx = get_next_indice(st_fx, 2); + move16(); + /* g= pow(10.0f, gain_table_SWB_BWE[imin]) */ + L_temp = L_mult(gain_table_SWB_BWE_fx[imin_fx], 27213); /* Q14+Q13+1=Q28 log(10)/log(2)=3.3219 27213.23(Q13) */ + L_temp = L_shr(L_temp, 12); /* Q28-Q12 -> Q16 */ + temp_lo_fx = L_Extract_lc(L_temp, &temp_hi_fx); + Qg = sub(14, temp_hi_fx); + g_fx = extract_l(Pow2(14, temp_lo_fx)); + g_fx = shl(g_fx, sub(11, Qg)); + + /* tonal energy estimation */ + ton_ene_est_fx( + L_xSynth_har, QsL, L_be_tonal, &QbeL, L_band_energy, Qbe, + band_start_fx, band_end_fx, band_width_fx, fLenLow_fx, fLenHigh_fx, + BANDS_fx, har_bands_fx, g_fx, pk_sf_fx, Qss, pul_res_fx + ); + + /*HF Spectrum Generation*/ + Gettonl_scalfact_fx( + L_xSynth_har, QsL, L_spectra_ni, fLenLow_fx, fLenHigh_fx, har_bands_fx, BANDS_fx, L_band_energy, Qbe, band_start_fx, band_end_fx, + p2a_flags_fx, L_be_tonal, QbeL, pk_sf_fx ,Qss, pul_res_fx); + + IF( flag_dis == 0 ) + { + *prev_frm_hfe2_fx = 0; + move16(); + } + ELSE + { + *prev_frm_hfe2_fx = har_freq_est2; + move16(); + } + + FOR( k = har_bands_fx; k < BANDS_fx; k++ ) + { + FOR( i = band_start_fx[k]; i <= band_end_fx[k]; i++ ) + { + L_spectra[i] = L_xSynth_har[i-fLenLow_fx]; + move32(); /* QsL */ + } + } + } + ELSE IF ( EQ_16(hqswb_clas_fx, HQ_NORMAL)) + { + ss_min_fx = spectrumsmooth_noiseton_fx( + L_spectra, /*QsL,*/ L_spectra_ni, sspectra_fx, sspectra_diff_fx, sspectra_ni_fx, &Qss, fLenLow_fx, ni_seed_fx); + + convert_lagIndices_pls2smp_fx( lagIndices_fx, nBands_fx, lagIndices_real_fx, sspectra_fx, sbWidth_fx, fLenLow_fx ); + FOR (k = 0; k < nBands_fx; k++) + { + if ( EQ_16(p2a_flags_fx[BANDS_fx-NB_SWB_SUBBANDS+k], 1)) + { + lagIndices_real_fx[k] = 0; + move16(); + } + } + + GetlagGains_fx( sspectra_ni_fx, Qss, + &L_band_energy[BANDS_fx-NB_SWB_SUBBANDS], Qbe, + nBands_fx, sbWidth_fx, lagIndices_real_fx, fLenLow_fx, lagGains_fx, QlagGains ); + + FOR(k=0; k Qs */ + } + } + + /* Construct spectrum */ + GetSynthesizedSpecThinOut_fx( + sspectra_ni_fx, Qss, L_xSynth_har, QsL, nBands_fx, sbWidth_fx, + lagIndices_real_fx, lagGains_fx, QlagGains, fLenLow_fx + ); + + /* Level adjustment for the missing bands */ + noiseinj_hf_fx( L_xSynth_har, QsL, L_th_g, L_band_energy, Qbe, hHQ_core->prev_En_sb_fx, + p2a_flags_fx, BANDS_fx, band_start_fx, band_end_fx, fLenLow_fx, fLenHigh_fx); + FOR( k = sub(BANDS_fx, NB_SWB_SUBBANDS); k < BANDS_fx; k++ ) + { + IF( p2a_flags_fx[k] == 0 ) + { + FOR( i = band_start_fx[k]; i <= band_end_fx[k]; i++ ) + { + L_spectra[i] = L_xSynth_har[i-fLenLow_fx]; + move32(); /* QsL */ + } + } + ELSE + { + FOR( i = band_start_fx[k]; i <= band_end_fx[k]; i++ ) + { + L_spectra[i] = L_spectra_ni[i]; + move32(); + } + } + } + } + + return; +} + +/*-------------------------------------------------------------------* + * swb_bwe_dec_lr() + * + * Main decoding routine of SWB BWE for the LR MDCT core + *-------------------------------------------------------------------*/ +void swb_bwe_dec_lr_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + const Word32 L_m_core[], /* i : lowband synthesis */ + const Word16 QsL, /* i : Q value of m_core */ + Word32 L_m[], /* o : highband synthesis with lowband zeroed */ + const Word32 L_total_brate, /* i : total bitrate for selecting subband pattern */ + Word16 BANDS_fx, /* i : Number subbands/Frame */ + Word16 *band_start_fx, /* i : Band Start of each SB */ + Word16 *band_end_fx, /* i : Band end of each SB */ + Word32 *L_band_energy, /* i : Band energy of each SB : Qbe */ + Word16 Qbe, /* i : Q value of band energy */ + Word16 *p2a_flags_fx, /* i : HF tonal Indicator */ + const Word16 hqswb_clas_fx, /* i : class information */ + Word16 lowlength_fx, /* i : Lowband Length */ + Word16 highlength_fx, /* i : Highband Length */ + const Word16 har_bands_fx, /* i : Number of LF harmonic bands */ + Word16 *prev_frm_hfe2_fx, /* i/o: */ + Word16 *prev_stab_hfe2_fx, /* i/o: */ + Word16 band_width_fx[], /* i : subband bandwidth */ + const Word32 L_y2_ni[], /* i/o: Sparse filled corecoder */ + Word16 *ni_seed_fx /* i/o: random seed */ +) +{ + Word16 k; + Word16 nBands_fx; + Word16 nBands_search_fx; + Word16 wBands_fx[NB_SWB_SUBBANDS]; + Word16 lagIndices_fx[NB_SWB_SUBBANDS]; + Word16 lagGains_fx[NB_SWB_SUBBANDS]; + Word16 QlagGains[NB_SWB_SUBBANDS]; + Word16 swb_lowband_fx, swb_highband_fx, allband_fx; + + const Word16 *subband_offsets_fx; + const Word16 *subband_search_offset_fx; + + Word32 *p_L_m; + + subband_search_offset_fx = subband_search_offsets_13p2kbps_Har; + subband_offsets_fx = subband_offsets_sub5_13p2kbps_Har; + + hf_parinitiz_fx(L_total_brate,hqswb_clas_fx,lowlength_fx,highlength_fx,wBands_fx,&subband_search_offset_fx,&subband_offsets_fx,&nBands_fx,&nBands_search_fx,&swb_lowband_fx,&swb_highband_fx); + allband_fx = add(swb_lowband_fx, swb_highband_fx); + move16(); + + /* Decoding of the SWB parameters */ + DecodeSWBGenericParameters_fx( st_fx, lagIndices_fx, nBands_search_fx, BANDS_fx, p2a_flags_fx, hqswb_clas_fx ); + + /* Copy WB synthesis for SWB decoding */ + Copy32( L_m_core, L_m, swb_lowband_fx + swb_highband_fx ); + + /* Generic subband processing */ + DecodeSWBSubbands_fx(st_fx,st_fx->hHQ_core,L_m, QsL,swb_lowband_fx, swb_highband_fx, nBands_fx, wBands_fx, subband_offsets_fx, + lagIndices_fx, lagGains_fx, QlagGains,BANDS_fx, band_start_fx, band_end_fx, + L_band_energy, Qbe, p2a_flags_fx, hqswb_clas_fx, har_bands_fx, subband_search_offset_fx, + prev_frm_hfe2_fx, prev_stab_hfe2_fx, band_width_fx, L_y2_ni, ni_seed_fx); + + p_L_m = &L_m[sub(allband_fx, 1)]; + *p_L_m = Mult_32_16(*p_L_m, 2028); + move32(); + p_L_m--; /* 0.0625 = 2028 (Q15) */ + *p_L_m = Mult_32_16(*p_L_m, 4096); + move32(); + p_L_m--; /* 0.125 = 4096 (Q15) */ + *p_L_m = Mult_32_16(*p_L_m, 8192); + move32(); + p_L_m--; /* 0.25 = 8192 (Q15) */ + *p_L_m = Mult_32_16(*p_L_m, 16384); + move32(); + p_L_m--; /* 0.5 = 16384 (Q15) */ + + /* set low frequencies to zero */ + FOR ( k = 0; k < swb_lowband_fx; k++ ) + { + L_m[k] = L_deposit_l(0); + } + + return; +} diff --git a/lib_dec/swb_tbe_dec.c b/lib_dec/swb_tbe_dec.c index b3efdd7f0ba0947f12f1e4810afd77080086971d..496ba8b8c7b4d2e27d41a43f0821dd73b0afb4a4 100644 --- a/lib_dec/swb_tbe_dec.c +++ b/lib_dec/swb_tbe_dec.c @@ -974,7 +974,7 @@ void swb_tbe_dec( if ( st->extl_brate >= SWB_TBE_2k8 ) { /* SHB LSP interpolation */ - ptr_lsp_interp_coef = interpol_frac_shb; + ptr_lsp_interp_coef = interpol_frac_shb_flt; for ( j = 0; j < 4; j++ ) { for ( i = 0; i < LPC_SHB_ORDER; i++ ) @@ -1801,7 +1801,7 @@ static void dequantizeSHBparams( grid_idx = 0; m_idx = 0; - mvr2r( swb_tbe_lsfvq_cbook_8b + lsf_idx[0] * LPC_SHB_ORDER, Q_lsf, LPC_SHB_ORDER ); + mvr2r( swb_tbe_lsfvq_cbook_8b_flt + lsf_idx[0] * LPC_SHB_ORDER, Q_lsf, LPC_SHB_ORDER ); } else if ( st->rf_flag == 0 && !( ( st->element_mode == EVS_MONO && st->total_brate == ACELP_9k60 ) || ( st->element_mode == EVS_MONO && ( st->total_brate == 0 ) && ( ( st->last_total_brate == ACELP_9k60 ) || ( st->last_total_brate == ACELP_13k20 && st->rf_flag_last ) ) ) ) ) { @@ -1926,7 +1926,7 @@ static void dequantizeSHBparams( mvs2s( hBWE_TD->lsf_idx, lsf_idx, 5 ); grid_idx = 0; m_idx = 0; - mvr2r( swb_tbe_lsfvq_cbook_8b + lsf_idx[0] * LPC_SHB_ORDER, Q_lsf, LPC_SHB_ORDER ); + mvr2r( swb_tbe_lsfvq_cbook_8b_flt + lsf_idx[0] * LPC_SHB_ORDER, Q_lsf, LPC_SHB_ORDER ); } space_lsfs( Q_lsf, LPC_SHB_ORDER ); diff --git a/lib_dec/swb_tbe_dec_fx.c b/lib_dec/swb_tbe_dec_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..8a4b0a12785f1702fd3c93c2c42b72f8f1e58263 --- /dev/null +++ b/lib_dec/swb_tbe_dec_fx.c @@ -0,0 +1,3814 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + + + +#include +#include "options.h" +#include "rom_com.h" +#include "prot_fx1.h" +#include "prot_fx2.h" +#include "rom_dec.h" +#include "stl.h" + +/*-----------------------------------------------------------------* + * Local functions + *-----------------------------------------------------------------*/ + + +static void dequantizeSHBparams_fx_9_1( Decoder_State* st_fx, const Word16 extl, Word32 extl_brate, + Word16* Q_lsf, Word16* Q_subgain, Word32* Q_framegrain, Word16* uv_flag, + Word32* Q_shb_ener_sf_32, Word16* Q_shb_res_gshape, Word16* Q_mixFactors); +static void find_max_mem_dec( Decoder_State* st_fx, Word16* n_mem, Word16 *n_mem2, Word16 *n_mem3 ); +static void rescale_genSHB_mem_dec( Decoder_State* st_fx, Word16 sf ); +static void find_max_mem_wb( Decoder_State* st_fx, Word16* n_mem ); +static void rescale_genWB_mem( Decoder_State* st_fx, Word16 sf ); +static void Dequant_lower_LSF_fx( const Word16 lsf_idx[], Word16 lsf_q[] ); +static void Map_higher_LSF_fx( Word16 lsf_q[], const Word16 m, const Word16 grid_in[] ); +static void Dequant_mirror_point_fx( const Word16 lsf_q[], const Word16 m_idx, Word16* m ); + +/* gain shape concealment code */ +static void gradientGainShape(Decoder_State *st_fx, Word16 *GainShape, Word32 *GainFrame); + +/*-------------------------------------------------------------------* + * find_max_mem_dec() + * + * Find norm and max in TBE memories and past buffers + *-------------------------------------------------------------------*/ +void find_max_mem_dec( + Decoder_State *st_fx, + Word16 *n_mem, + Word16 *n_mem2 + ,Word16 *n_mem3 +) +{ + Word16 i; + Word16 n_mem_32; + Word16 max = 0; + Word32 Lmax = 0; + Word16 tempQ15, max2 = 0; + Word16 max3; + Word32 tempQ32, Lmax3; + TD_BWE_DEC_HANDLE hBWE_TD; + hBWE_TD = st_fx->hBWE_TD; + + /* old BWE exc max */ + FOR( i = 0; i < NL_BUFF_OFFSET; i++ ) + { + tempQ15 = abs_s(hBWE_TD->old_bwe_exc_extended_fx[i] ); + max = s_max( max, tempQ15 ); + } + + /* decimate all-pass steep memory */ + FOR ( i = 0; i < 7; i++ ) + { + tempQ15 = abs_s(hBWE_TD->mem_genSHBexc_filt_down_shb_fx[i] ); + max = s_max(max, tempQ15); + } + + /* -- keep norm of state_lpc_syn_fx, state_syn_shbexc_fx, + and mem_stp_swb_fx separately for 24.4 and 32kbps ----*/ + /* findMaxMem2() inside tbe com */ + FOR ( i = 0; i < LPC_SHB_ORDER; i++ ) + { + tempQ15 = abs_s(hBWE_TD->state_lpc_syn_fx[i] ); + max2 = s_max(max2, tempQ15); + } + + /* findMaxMem2() inside tbe com */ + FOR ( i = 0; i < L_SHB_LAHEAD; i++ ) + { + tempQ15 = abs_s(hBWE_TD->state_syn_shbexc_fx[i] ); + max2 = s_max(max2, tempQ15); + } + + /* findMaxMem2() inside tbe com */ + FOR ( i = 0; i < LPC_SHB_ORDER; i++ ) + { + tempQ15 = abs_s(hBWE_TD->mem_stp_swb_fx[i] ); + max2 = s_max(max2, tempQ15); + } + + /* for total_brate > 16.4kbps, use n_mem2; else account for the max2 for n_mem calculation */ + *n_mem2 = norm_s(max2); + if(max2 == 0) *n_mem2 = 15; + + if(LT_32(st_fx->total_brate, ACELP_24k40)) + { + max = s_max(max, max2); + } + + /* de-emph and pre-emph memory */ + tempQ15 = abs_s(hBWE_TD->tbe_demph_fx ); + max = s_max(max, tempQ15); + + tempQ15 = abs_s(hBWE_TD->tbe_premph_fx ); + max = s_max(max, tempQ15); + + IF( EQ_16(st_fx->extl, FB_TBE)) + { + FOR ( i = 0; i < LPC_SHB_ORDER; i++ ) + { + tempQ15 = abs_s(hBWE_TD->fb_state_lpc_syn_fx[i] ); + max = s_max(max, tempQ15); + } + /* FB de-emph memory */ + tempQ15 = abs_s(hBWE_TD->fb_tbe_demph_fx); + max = s_max(max, tempQ15); + } + /* estimate the norm for 16-bit memories */ + *n_mem = norm_s( max ); + if( max == 0 ) + { + *n_mem = 15; + } + + /* estimate the norm for 32-bit memories */ + Lmax = L_abs(hBWE_TD->mem_csfilt_fx[0] ); /* only element [0] is used in env. shaping */ + + n_mem_32 = norm_l( Lmax ); + if( Lmax == 0 ) + { + n_mem_32 = 31; + } + + tempQ15 = sub( s_min( *n_mem, n_mem_32 ), 1 ); + *n_mem = s_max( tempQ15, 0 ); + + /* --------------------------------------------------------------*/ + /* Find headroom for synthesis stage associated with these memories: + 1. st_fx->syn_overlap_fx + 2. st_fx->genSHBsynth_state_lsyn_filt_shb_local + 3. st_fx->genSHBsynth_Hilbert_Mem_fx (32-bit) */ + max3 = 0; + /* find max in prev overlapSyn */ + FOR ( i = 0; i < L_SHB_LAHEAD; i++ ) + { + tempQ15 = abs_s(hBWE_TD->syn_overlap_fx[i] ); + max3 = s_max(max3, tempQ15); + } + /* find max in prev genSHBsynth_state_lsyn_filt_shb_local_fx */ + FOR ( i = 0; i < 2*ALLPASSSECTIONS_STEEP; i++ ) + { + tempQ15 = abs_s(hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx[i] ); + max3 = s_max(max3, tempQ15); + } + /* find max in prev int_3_over_2_tbemem_dec_fx */ + IF( EQ_32(st_fx->output_Fs, 48000)) + { + FOR ( i = 0; i < INTERP_3_2_MEM_LEN; i++ ) + { + tempQ15 = abs_s(hBWE_TD->int_3_over_2_tbemem_dec_fx[i] ); + max3 = s_max(max3, tempQ15); + } + } + IF( EQ_32(st_fx->output_Fs, 16000)) + { + FOR ( i = 0; i < (2*ALLPASSSECTIONS_STEEP+1); i++ ) + { + tempQ15 = abs_s(hBWE_TD->mem_resamp_HB_32k_fx[i] ); + max3 = s_max(max3, tempQ15); + } + } + /* estimate the norm for 16-bit memories */ + *n_mem3 = norm_s( max3 ); + if( max3 == 0 ) *n_mem3 = 15; + + Lmax3 = 0; + IF(EQ_16(st_fx->L_frame, L_FRAME)) + { + /* find max in prev genSHBsynth_Hilbert_Mem_fx */ + FOR ( i = 0; i < HILBERT_MEM_SIZE; i++ ) + { + tempQ32 = L_abs(hBWE_TD->genSHBsynth_Hilbert_Mem_fx[i] ); + Lmax3 = L_max(Lmax3, tempQ32); + } + } + + /* estimate the norm for 32-bit memories */ + n_mem_32 = norm_l( Lmax3 ); + if( Lmax3 == 0 ) n_mem_32 = 31; + + tempQ15 = sub( s_min( *n_mem3, n_mem_32 ), 2 ); /* very important leave at least 2 bit head room + because of the Hilber transform and Q14 coeffs */ + *n_mem3 = s_max( tempQ15, 0 ); + /* --------------------------------------------------------------*/ +} + +/*-------------------------------------------------------------------* + * rescale_genSHB_mem_dec() + * + * Rescale genSHB memories + *-------------------------------------------------------------------*/ +void rescale_genSHB_mem_dec( + Decoder_State *st_fx, + Word16 sf ) +{ + Word16 i; + TD_BWE_DEC_HANDLE hBWE_TD; + hBWE_TD = st_fx->hBWE_TD; + + FOR( i = 0; i < NL_BUFF_OFFSET; i++ ) + { + hBWE_TD->old_bwe_exc_extended_fx[i] = shl(hBWE_TD->old_bwe_exc_extended_fx[i], sf ); + move16(); + } + + FOR( i = 0; i < 7; i++ ) + { + hBWE_TD->mem_genSHBexc_filt_down_shb_fx[i] = shl(hBWE_TD->mem_genSHBexc_filt_down_shb_fx[i], sf ); + move16(); + } + + /* -- Apply memory scaling for 13.2 and 16.4k bps using sf ----*/ + IF(LT_32(st_fx->total_brate, ACELP_24k40)) + { + FOR ( i = 0; i < LPC_SHB_ORDER; i++ ) + { + hBWE_TD->state_lpc_syn_fx[i] = shl(hBWE_TD->state_lpc_syn_fx[i], sf ); + move16(); + } + + FOR ( i = 0; i < L_SHB_LAHEAD; i++ ) + { + hBWE_TD->state_syn_shbexc_fx[i] = shl(hBWE_TD->state_syn_shbexc_fx[i], sf ); + move16(); + } + } + + IF( EQ_16(st_fx->extl, FB_TBE)) + { + } + hBWE_TD->mem_csfilt_fx[0] = L_shl(hBWE_TD->mem_csfilt_fx[0], sf ); + move32(); + + hBWE_TD->tbe_demph_fx = shl_r(hBWE_TD->tbe_demph_fx, sf ); + move16(); + hBWE_TD->tbe_premph_fx = shl_r(hBWE_TD->tbe_premph_fx, sf ); + move16(); + +} + +void find_max_mem_wb( Decoder_State* st_fx, Word16* n_mem ) +{ + Word16 i; + Word16 max = 0; + Word32 Lmax = 0; + Word16 n_mem_32; + TD_BWE_DEC_HANDLE hBWE_TD; + hBWE_TD = st_fx->hBWE_TD; + + FOR(i = 0; i < NL_BUFF_OFFSET; i++) + { + max = s_max(max, abs_s(hBWE_TD->old_bwe_exc_extended_fx[i])); + } + FOR( i = 0; i < 7; i++ ) + { + + if( abs_s(hBWE_TD->mem_genSHBexc_filt_down_shb_fx[i] ) > max ) + max = abs_s(hBWE_TD->mem_genSHBexc_filt_down_shb_fx[i] ); + } + + FOR( i = 0; i < 7; i++ ) + { + if( abs_s(hBWE_TD->mem_genSHBexc_filt_down_wb2_fx[i] ) > max ) + max = abs_s(hBWE_TD->mem_genSHBexc_filt_down_wb2_fx[i] ); + } + + FOR( i = 0; i < 7; i++ ) + { + + if( abs_s(hBWE_TD->mem_genSHBexc_filt_down_wb3_fx[i] ) > max ) + max = abs_s(hBWE_TD->mem_genSHBexc_filt_down_wb3_fx[i] ); + } + + FOR( i = 0; i < 10; i++ ) + { + + if( abs_s(hBWE_TD->state_lpc_syn_fx[i] ) > max ) + max = abs_s(hBWE_TD->state_lpc_syn_fx[i] ); + } + + FOR( i = 0; i < 5; i++ ) + { + + if( abs_s(hBWE_TD->state_syn_shbexc_fx[i] ) > max ) + max = abs_s(hBWE_TD->state_syn_shbexc_fx[i] ); + } + + IF ( max == 0 ) + { + *n_mem = 15; + move16(); + } + ELSE + { + *n_mem = norm_s( max ); + move16(); + } + + + FOR( i = 0; i < 2; i++ ) + { + + if( L_abs(hBWE_TD->mem_csfilt_fx[i] ) > Lmax ) + Lmax = L_abs(hBWE_TD->mem_csfilt_fx[i] ); + } + + IF ( Lmax == 0 ) + { + n_mem_32 = 31; + move16(); + } + ELSE + { + n_mem_32 = norm_l( Lmax ); + } + + *n_mem = sub( s_min( *n_mem, n_mem_32 ), 1 ); + *n_mem = s_max( *n_mem, 0 ); +} + +void rescale_genWB_mem( Decoder_State* st_fx, Word16 sf ) +{ + Word16 i; + TD_BWE_DEC_HANDLE hBWE_TD; + hBWE_TD = st_fx->hBWE_TD; + + FOR( i = 0; i < NL_BUFF_OFFSET; i++ ) + { + hBWE_TD->old_bwe_exc_extended_fx[i] = shl(hBWE_TD->old_bwe_exc_extended_fx[i], sf ); + move16(); + } + + FOR( i = 0; i < 10; i++ ) + { + hBWE_TD->state_lpc_syn_fx[i] = shl(hBWE_TD->state_lpc_syn_fx[i], sf ); + move16(); + } + + FOR( i = 0; i < 5; i++ ) + { + hBWE_TD->state_syn_shbexc_fx[i] = shl(hBWE_TD->state_syn_shbexc_fx[i], sf ); + move16(); + } + + FOR( i = 0; i < 7; i++ ) + { + hBWE_TD->mem_genSHBexc_filt_down_shb_fx[i] = shl(hBWE_TD->mem_genSHBexc_filt_down_shb_fx[i], sf ); + move16(); + } + + FOR( i = 0; i < 7; i++ ) + { + hBWE_TD->mem_genSHBexc_filt_down_wb2_fx[i] = shl(hBWE_TD->mem_genSHBexc_filt_down_wb2_fx[i], sf ); + move16(); + } + + FOR( i = 0; i < 7; i++ ) + { + hBWE_TD->mem_genSHBexc_filt_down_wb3_fx[i] = shl(hBWE_TD->mem_genSHBexc_filt_down_wb3_fx[i], sf ); + move16(); + } + + FOR( i = 0; i < 2; i++ ) + { + hBWE_TD->mem_csfilt_fx[i] = L_shl(hBWE_TD->mem_csfilt_fx[i], sf ); + move32(); + } +} + + + +void InitSWBdecBuffer_fx( + Decoder_State* st_fx /* i/o: SHB decoder structure */ +) +{ + TD_BWE_DEC_HANDLE hBWE_TD; + hBWE_TD = st_fx->hBWE_TD; + + set16_fx(hBWE_TD->old_bwe_exc_fx, 0, ( PIT16k_MAX * 2 ) ); + hBWE_TD->bwe_seed_fx[0] = 23; + move16(); + hBWE_TD->bwe_seed_fx[1] = 59; + move16(); + + set16_fx(hBWE_TD->old_bwe_exc_extended_fx, 0, NL_BUFF_OFFSET ); + hBWE_TD->bwe_non_lin_prev_scale_fx = 0; + move16(); + + set32_fx(hBWE_TD->genSHBsynth_Hilbert_Mem_fx, 0, HILBERT_MEM_SIZE ); + set16_fx(hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx, 0, 2*ALLPASSSECTIONS_STEEP); /* Interp all pass memory */ + + hBWE_TD->syn_dm_phase_fx = 0; + move16(); + hBWE_TD->prev_fbbwe_ratio_fx = 32767/*1.0f Q15*/; + + /* these are fd-bwe constants */ + hBWE_TD->prev_wb_bwe_frame_pow_fx = 4194l/*0.001f Q22*/; /* Q22 */ + hBWE_TD->prev_swb_bwe_frame_pow_fx = 4194l/*0.001f Q22*/; /* Q22 */ + st_fx->prev_Q_bwe_exc = 31; + move16(); + st_fx->prev_ener_fx_Q = 31; + move16(); + st_fx->prev_Qx = 0; + move16(); + st_fx->prev_frame_pow_exp = 0; + move16(); + st_fx->prev_Q_bwe_syn = 0; + move16(); + st_fx->prev_Q_bwe_syn2 = 0; + move16(); + return; +} + + +void ResetSHBbuffer_Dec_fx( Decoder_State* st_fx /* i/o: SHB encoder structure */ ) +{ + Word16 i; + Word16 f; + Word16 inc; + TD_BWE_DEC_HANDLE hBWE_TD; + hBWE_TD = st_fx->hBWE_TD; + + IF( st_fx->extl != WB_TBE ) + { + f = 1489; + move16(); /* Q15 */ + inc = 1489; + move16(); /* Q15 */ + } + ELSE + { + f = 5461; + move16();/* Q15 */ + inc = 5461; + move16(); /* Q15 */ + } + + /* states for the filters used in generating SHB excitation from WB excitation*/ + set32_fx(hBWE_TD->mem_csfilt_fx, 0, 2 ); + + /* states for the filters used in generating SHB signal from SHB excitation*/ + set16_fx(hBWE_TD->state_syn_shbexc_fx, 0, L_SHB_LAHEAD ); + set16_fx(hBWE_TD->state_lpc_syn_fx, 0, LPC_SHB_ORDER ); + + IF( EQ_16(st_fx->extl, FB_TBE)) + { + set16_fx(hBWE_TD->fb_state_lpc_syn_fx, 0, LPC_SHB_ORDER ); + hBWE_TD->fb_tbe_demph_fx = 0; + move16(); + fb_tbe_reset_synth_fx(hBWE_TD->fbbwe_hpf_mem_fx, hBWE_TD->fbbwe_hpf_mem_fx_Q,&hBWE_TD->prev_fbbwe_ratio_fx ); + } + /* states for the filters used in generating SHB signal from SHB excitation in wideband*/ + set16_fx(hBWE_TD->mem_genSHBexc_filt_down_shb_fx, 0, 2*ALLPASSSECTIONS_STEEP+1); + set16_fx(hBWE_TD->mem_genSHBexc_filt_down_wb2_fx, 0, 2*ALLPASSSECTIONS_STEEP+1); + set16_fx(hBWE_TD->mem_genSHBexc_filt_down_wb3_fx, 0, 2*ALLPASSSECTIONS_STEEP+1); + set16_fx(hBWE_TD->state_lsyn_filt_shb_fx,0, 2 * ALLPASSSECTIONS_STEEP ); + set16_fx(hBWE_TD->state_lsyn_filt_dwn_shb_fx,0, 2 * ALLPASSSECTIONS_STEEP ); + set16_fx(hBWE_TD->state_32and48k_WB_upsample_fx, 0, 2 * ALLPASSSECTIONS_STEEP ); + + /* States for the local synthesis filters */ + set16_fx(hBWE_TD->syn_overlap_fx, 0, L_SHB_LAHEAD ); + + /* States for FEC */ + + IF( st_fx->extl != WB_TBE ) + { + FOR( i = 0; i < LPC_SHB_ORDER; i++ ) + { + hBWE_TD->lsp_prevfrm_fx[i] = f; + move16(); /*Q15*/ + f = add( f, inc ); + move16(); + } + } + ELSE + { + FOR( i = 0; i < LPC_SHB_ORDER_WB; i++ ) + { + hBWE_TD->lsp_prevfrm_fx[i] = f; + move16();/*Q15*/ + f = add( f, inc ); + move16(); + } + FOR( ; ilsp_prevfrm_fx[i] = 0; + move16(); + } + } + hBWE_TD->GainFrame_prevfrm_fx = 0; + move16();/*Q18*/ + hBWE_TD->GainAttn_fx = 32767; + move16();/*Q15*/ + hBWE_TD->tbe_demph_fx = 0; + hBWE_TD->tbe_premph_fx = 0; + set16_fx(hBWE_TD->mem_stp_swb_fx, 0, LPC_SHB_ORDER); + hBWE_TD->gain_prec_swb_fx = 16384;/*Q14 =1*/ + set16_fx( &st_fx->GainShape_Delay[0], 0, NUM_SHB_SUBFR / 2 ); + + set16_fx(hBWE_TD->old_core_synth_fx, 0, L_FRAME16k); + set16_fx(hBWE_TD->old_tbe_synth_fx, 0, L_SHB_TRANSITION_LENGTH); + hBWE_TD->tilt_swb_fec_fx = 0; + move16(); + + return; +} + + + + +/*==========================================================================*/ +/* FUNCTION : void wb_tbe_dec_fx () */ +/*--------------------------------------------------------------------------*/ +/* PURPOSE : WB TBE decoder, 6 - 8 kHz band decoding module */ +/*--------------------------------------------------------------------------*/ +/* INPUT ARGUMENTS : */ +/* _Word16 coder_type i : coding type */ +/* _Word32 *bwe_exc_extended i : bandwidth extended exciatation 2*Q_exc*/ +/* _Word16 Q_exc i : Q format */ +/* _Word16 voice_factors[] i : voicing factors Q15 */ +/*--------------------------------------------------------------------------*/ +/* OUTPUT ARGUMENTS : */ +/* _Word16 *synth o : WB synthesis/final synthesis Q_synth */ +/*--------------------------------------------------------------------------*/ +/* INPUT/OUTPUT ARGUMENTS : */ +/* Decoder_State *st_fx, i/o: decoder state structure */ +/*--------------------------------------------------------------------------*/ +/* RETURN ARGUMENTS : */ +/* _ None */ +/*--------------------------------------------------------------------------*/ +/* CALLED FROM : */ +/*==========================================================================*/ +void wb_tbe_dec_fx( + Decoder_State* st_fx, /* i/o: decoder state structure */ + const Word16 coder_type, /* i : coding type */ + Word32* bwe_exc_extended, /* i : bandwidth extended exciatation 2*Q_exc*/ + const Word16 Q_exc, + const Word16 voice_factors[], /* i : voicing factors */ + Word16* synth, /* o : WB synthesis/final synthesis */ + Word16* Q_synth +) +{ + Word16 i; + Word16 shaped_wb_excitation [ ( L_FRAME16k + L_SHB_LAHEAD )/4 ]; + Word16 shaped_wb_excitation_frac[ L_FRAME16k/4 ]; + Word16 bwe_exc_extended_16[ L_FRAME32k+40 ]; + Word16 exc4kWhtnd [ L_FRAME16k / 4]; + Word16 lsf_wb[ LPC_SHB_ORDER_WB ], lpc_wb[ LPC_SHB_ORDER_WB + 1 ], GainShape[ NUM_SHB_SUBFR ]; + Word32 GainFrame; + Word16 error[ L_FRAME16k ]; + Word16 synth_frac[ L_FRAME16k ]; + Word16 upsampled_synth[ L_FRAME48k ]; + Word32 prev_pow, curr_pow, curr_frame_pow; + Word16 curr_frame_pow_exp; + Word16 temp, scale, n; + Word16 j; + + Word16 Q_bwe_exc, Q_bwe_exc_ext, Qx; + Word16 n_mem, cnt; + Word16 max = 0; + Word32 L_tmp, Lacc, Lscale, Lmax = 0; + Word16 tmp, exp, sc; + Word16 vf_modified[ NB_SUBFR16k ]; + Word16 uv_flag = 0; + Word16 dummy=0; + Word32 dummy2[HILBERT_MEM_SIZE]= {0}; + Word16 f, inc; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + TD_BWE_DEC_HANDLE hBWE_TD; + hBWE_TD = st_fx->hBWE_TD; + + IF( st_fx->bws_cnt_fx == 0 ) + { + /* Initialization */ + set16_fx(GainShape, 11469/*0.35f Q15*/, NUM_SHB_SUBFR); + GainFrame = 1; + + IF( !st_fx->bfi ) + { + IF(EQ_16(st_fx->use_partial_copy,1)) + { + IF(NE_16(st_fx->last_extl, WB_TBE)) + { + hBWE_TD->GainFrame_prevfrm_fx = 0; + hBWE_TD->lsp_prevfrm_fx[0] = 3277/*0.1f Q15*/; + move16(); + FOR (i=1; ilsp_prevfrm_fx[i] = add(hBWE_TD->lsp_prevfrm_fx[i-i], 3277/*0.1f Q15*/); + } + } + Copy(hBWE_TD->lsp_prevfrm_fx, lsf_wb, LPC_SHB_ORDER_LBR_WB ); + set16_fx( GainShape, RECIP_ROOT_EIGHT_FX, NUM_SHB_SUBFR/2 ); + + IF( EQ_16(st_fx->rf_frame_type,RF_NELP)) + { + /* Frame gain */ + st_fx->rf_indx_tbeGainFr = s_and(st_fx->rf_indx_tbeGainFr, 0xF); /* only four LSBs are valid */ + Copy32( SHBCB_FrameGain16_fx + st_fx->rf_indx_tbeGainFr, &GainFrame, 1 ); + IF( EQ_16(st_fx->core,ACELP_CORE)&&EQ_16(st_fx->last_core,ACELP_CORE) + && !st_fx->prev_use_partial_copy && EQ_16(st_fx->prev_coder_type_fx,UNVOICED) + && NE_32(GainFrame, hBWE_TD->GainFrame_prevfrm_fx) && EQ_16(st_fx->last_extl, WB_TBE) ) + { + /*GainFrame = 0.2f*GainFrame + 0.8f*st_fx->GainFrame_prevfrm_fx;*/ + GainFrame = L_add(Mult_32_16(hBWE_TD->GainFrame_prevfrm_fx, 26214), Mult_32_16(GainFrame, 6553)); + } + } + ELSE + { + temp = 0; + move16(); + /* Frame gain */ + SWITCH (st_fx->rf_indx_tbeGainFr) + { + case 0: + GainFrame = 131072; /* 0.5f in Q18 */ + IF(LE_32(hBWE_TD->GainFrame_prevfrm_fx, 327680l/*1.25 Q18*/)) temp = 26214/*0.8 Q15*/; + move16(); + BREAK; + case 1: + GainFrame = 524288; /* 2.0f in Q18 */ + IF(GT_32(hBWE_TD->GainFrame_prevfrm_fx, 327680l/*1.25 Q18*/)&&LE_32(hBWE_TD->GainFrame_prevfrm_fx,786432l/*3 Q18*/)) temp = 26214/*0.8 Q15*/; + move16(); + test(); + BREAK; + case 2: + GainFrame = 1048576;/* 4.0f in Q18 */ + IF(GT_32(hBWE_TD->GainFrame_prevfrm_fx, 786432l/*3 Q18*/)&&LE_32(hBWE_TD->GainFrame_prevfrm_fx,1572864l/*6 Q18*/)) temp = 26214/*0.8 Q15*/; + move16(); + test(); + BREAK; + case 3: + GainFrame = 2097152;/* 8.0f in Q18 */ + IF(GT_32(hBWE_TD->GainFrame_prevfrm_fx, 1572864l/*6 Q18*/)&&LE_32(hBWE_TD->GainFrame_prevfrm_fx,4194304l/*16 Q18*/)) temp = 26214/*0.8 Q15*/; + move16(); + test(); + BREAK; + default: + fprintf(stderr, "RF SWB-TBE gain bits not supported."); + } + IF(EQ_16(st_fx->last_extl, WB_TBE)) + { + + GainFrame = L_add(Mult_32_16(hBWE_TD->GainFrame_prevfrm_fx, temp), Mult_32_16(GainFrame, sub(32767,temp))); + } + IF(EQ_16(st_fx->core,ACELP_CORE)&&EQ_16(st_fx->last_core,ACELP_CORE)) + { + IF(!st_fx->prev_use_partial_copy && EQ_16(st_fx->last_coder_type_fx, VOICED)&&EQ_16(st_fx->rf_frame_type,RF_GENPRED) + && LT_16(st_fx->prev_tilt_code_dec_fx,1497) && GT_16(st_fx->prev_tilt_code_dec_fx,200) ) + { + GainFrame = Mult_32_16(GainFrame,9830); + } + } + } + } + ELSE + { + /* de-quantization */ + dequantizeSHBparams_fx_9_1( st_fx, st_fx->extl, st_fx->extl_brate, lsf_wb, GainShape, &GainFrame, &uv_flag, 0, 0, 0 ); + } + } + ELSE + { + IF( EQ_32( st_fx->extl_brate, WB_TBE_0k35)) + { + Copy(hBWE_TD->lsp_prevfrm_fx, lsf_wb, LPC_SHB_ORDER_LBR_WB ); + } + ELSE + { + Copy(hBWE_TD->lsp_prevfrm_fx, lsf_wb, LPC_SHB_ORDER_WB ); + } + set16_fx( GainShape, RECIP_ROOT_EIGHT_FX, NUM_SHB_SUBFR / 2 ); + + hBWE_TD->GainAttn_fx = mult_r(hBWE_TD->GainAttn_fx, 27853 ); + move16(); + + IF(EQ_16(st_fx->codec_mode, MODE1)) + { + GainFrame = Mult_32_16(hBWE_TD->GainFrame_prevfrm_fx, hBWE_TD->GainAttn_fx ); /*Q18*/ + } + ELSE + { + GainFrame = hBWE_TD->GainFrame_prevfrm_fx; /*Q18*/ + } + } + + IF( st_fx->extl_brate == WB_TBE_0k35 ) + { + /* convert LSPs back into LP coeffs */ + lsp2lpc_fx( lpc_wb + 1, lsf_wb, st_fx->prev_lpc_wb_fx, LPC_SHB_ORDER_LBR_WB ); + set16_fx( lpc_wb + LPC_SHB_ORDER_LBR_WB + 1, 0, ( LPC_SHB_ORDER_WB - LPC_SHB_ORDER_LBR_WB ) ); + FOR( i = 0; i < LPC_SHB_ORDER_WB; i++ ) + { + st_fx->prev_lpc_wb_fx[i] = lpc_wb[i + 1]; + move16(); + } + FOR( i = 1; i < LPC_SHB_ORDER_LBR_WB + 1; i++ ) + { + lpc_wb[i] = negate( lpc_wb[i] ); + move16(); + } + lpc_wb[0] = 4096; + move16(); + } + ELSE + { + /* convert LSPs back into LP coeffs */ + lsp2lpc_fx( lpc_wb + 1, lsf_wb, st_fx->prev_lpc_wb_fx, LPC_SHB_ORDER_WB ); + FOR( i = 0; i < LPC_SHB_ORDER_WB; i++ ) + { + st_fx->prev_lpc_wb_fx[i] = lpc_wb[i + 1]; + move16(); + } + FOR( i = 1; i < LPC_SHB_ORDER_WB + 1; i++ ) + { + lpc_wb[i] = negate( lpc_wb[i] ); + move16(); + } + lpc_wb[0] = 4096; + move16(); + } + + Copy( voice_factors, vf_modified, NB_SUBFR16k ); + IF( coder_type == VOICED ) + { + FOR( i = 1; i < NB_SUBFR; i++ ) + { + vf_modified[i] = add( mult_r( 26214, voice_factors[i] ), mult_r( 6554, voice_factors[i - 1] ) ); /* Q15 */ move16(); + } + IF( st_fx->L_frame != L_FRAME ) + { + vf_modified[4] = add( mult_r( 26214, voice_factors[4] ), mult_r( 6554, voice_factors[3] ) ); /* Q15 */ move16(); + } + } + + /* From low band excitation, generate highband excitation */ + Lmax = 0; + FOR( cnt = 0; cnt < L_FRAME32k; cnt++ ) + { + Lmax = L_max( Lmax, L_abs( bwe_exc_extended[cnt] ) ); + } + Q_bwe_exc = ( Lmax == 0 )?31:norm_l( Lmax ); + Q_bwe_exc = sub( Q_bwe_exc, 1 ); + Q_bwe_exc = add( Q_bwe_exc, add( Q_exc, Q_exc ) ); + + find_max_mem_wb( st_fx, &n_mem ); + + if( sub( Q_bwe_exc, st_fx->prev_Q_bwe_exc ) > n_mem ) + { + Q_bwe_exc = add( st_fx->prev_Q_bwe_exc, n_mem ); + } + + test(); + if( uv_flag && GT_16( Q_bwe_exc, 20 )) + { + Q_bwe_exc = 20; + move16(); /* restrict this to 21 due to the Q factor requireemnt of the random number generator (keep 1 bit headroom) */ + } + + prev_pow = 0; + FOR( i = 0; i < L_SHB_LAHEAD / 4; i++ ) + { + prev_pow = L_mac0( prev_pow, hBWE_TD->state_syn_shbexc_fx[i], hBWE_TD->state_syn_shbexc_fx[i] ); /*Q(2*(st_fx->prev_Q_bwe_exc-16))*/ + } + + rescale_genWB_mem( st_fx, sub( Q_bwe_exc, st_fx->prev_Q_bwe_exc ) ); + + Copy(hBWE_TD->old_bwe_exc_extended_fx, bwe_exc_extended_16, NL_BUFF_OFFSET ); + sc = sub( Q_bwe_exc, add( Q_exc, Q_exc ) ); + FOR( cnt = 0; cnt < L_FRAME32k; cnt++ ) + { + bwe_exc_extended_16[cnt + NL_BUFF_OFFSET] = round_fx( L_shl( bwe_exc_extended[cnt], sc ) ); + } + Copy( bwe_exc_extended_16 + L_FRAME32k, hBWE_TD->old_bwe_exc_extended_fx, NL_BUFF_OFFSET ); + + Copy(hBWE_TD->state_syn_shbexc_fx, shaped_wb_excitation, L_SHB_LAHEAD / 4 ); + + Q_bwe_exc_ext = sub( Q_bwe_exc, 16 ); + + GenShapedWBExcitation_fx( shaped_wb_excitation + L_SHB_LAHEAD / 4, lpc_wb, exc4kWhtnd, hBWE_TD->mem_csfilt_fx, + hBWE_TD->mem_genSHBexc_filt_down_shb_fx, hBWE_TD->mem_genSHBexc_filt_down_wb2_fx, + hBWE_TD->mem_genSHBexc_filt_down_wb3_fx, hBWE_TD->state_lpc_syn_fx, coder_type, + bwe_exc_extended_16, Q_bwe_exc_ext, hBWE_TD->bwe_seed_fx, vf_modified, uv_flag + , st_fx->igf + ); + + curr_pow = 0; + FOR( i = 0; i < L_SHB_LAHEAD / 4; i++ ) + { + curr_pow = L_mac0( curr_pow, shaped_wb_excitation[i + L_SHB_LAHEAD / 4], shaped_wb_excitation[i + + L_SHB_LAHEAD / 4] ); /* Q(2*Q_bwe_exc_ext) */ + } + + if( GT_16( voice_factors[0], 24576 )) + { + curr_pow = L_shr( curr_pow, 2 ); /* Q(2*Q_bwe_exc_ext) */ + } + + Lscale = root_a_over_b_fx( curr_pow, shl_r( Q_bwe_exc_ext, 1 ), prev_pow, + shl_r( sub( st_fx->prev_Q_bwe_exc, 16 ), 1 ), &exp ); + + FOR( i = 0; i < L_SHB_LAHEAD / 4 - 1; i++ ) + { + L_tmp = Mult_32_16( Lscale, shaped_wb_excitation[i] ); /* Q(16-exp+Q_bwe_exc_ext) */ + shaped_wb_excitation[i] = round_fx( L_shl( L_tmp, exp ) ); /* Q_bwe_exc_ext */ + } + Lscale = root_a_fx( Lscale, 31 - exp, &exp ); + L_tmp = Mult_32_16( Lscale, shaped_wb_excitation[L_SHB_LAHEAD / 4 - 1] ); /* Q(16-exp+Q_bwe_exc_ext) */ + shaped_wb_excitation[L_SHB_LAHEAD / 4 - 1] = round_fx( L_shl( L_tmp, exp ) ); /* Q_bwe_exc_ext */ + + /* Update SHB excitation */ + Copy( shaped_wb_excitation + L_FRAME16k / 4, hBWE_TD->state_syn_shbexc_fx, L_SHB_LAHEAD / 4 ); + + + /* Adjust the subframe and frame gain of the synthesized shb signal */ + /* Scale the shaped excitation */ + ScaleShapedWB_fx( SHB_OVERLAP_LEN / 2, shaped_wb_excitation, hBWE_TD->syn_overlap_fx, GainShape, GainFrame, + window_wb_fx, subwin_wb_fx, + Q_bwe_exc_ext + , st_fx->L_frame + , 0 + , &dummy + , dummy + , dummy2 + ); + + max = 0; + FOR( i = 0; i < L_FRAME16k / 4; i++ ) + { + max = s_max( max, shaped_wb_excitation[i] ); /*Q0*/ + } + + IF( max == 0 ) + { + curr_frame_pow = 1; + move16(); + n = 0; + move16(); + } + ELSE + { + n = norm_s( max ); + FOR( i = 0; i < L_FRAME16k / 4; i++ ) + { +#ifdef BASOP_NOGLOB + shaped_wb_excitation_frac[i] = shl_o( shaped_wb_excitation[i], n , &Overflow); /*Q14*/ move16(); +#else + shaped_wb_excitation_frac[i] = shl( shaped_wb_excitation[i], n ); /*Q14*/ move16(); +#endif + } + n = sub( 14, n ); + curr_frame_pow = 1; + FOR( i = 0; i < L_FRAME16k / 4; i++ ) + { +#ifdef BASOP_NOGLOB + L_tmp = L_mult_o( shaped_wb_excitation_frac[i], shaped_wb_excitation_frac[i], &Overflow ); /*Q29*/ + curr_frame_pow = L_add_o( curr_frame_pow, L_shr( L_tmp, 7 ), &Overflow); /*Q22*/ +#else + L_tmp = L_mult( shaped_wb_excitation_frac[i], shaped_wb_excitation_frac[i] ); /*Q29*/ + curr_frame_pow = L_add( curr_frame_pow, L_shr( L_tmp, 7 ) ); /*Q22*/ +#endif + } + } + curr_frame_pow_exp = add( n, n ); + + IF ( GT_16(st_fx->prev_frame_pow_exp, curr_frame_pow_exp)) + { + curr_frame_pow = L_shr( curr_frame_pow, sub( st_fx->prev_frame_pow_exp, curr_frame_pow_exp ) ); + curr_frame_pow_exp = st_fx->prev_frame_pow_exp; + } + ELSE + { + hBWE_TD->prev_wb_bwe_frame_pow_fx = L_shr(hBWE_TD->prev_wb_bwe_frame_pow_fx, sub( curr_frame_pow_exp, st_fx->prev_frame_pow_exp ) ); + } + + test(); + IF( !st_fx->bfi && st_fx->prev_bfi ) + { + IF( GT_32( L_shr( curr_frame_pow, 1 ), hBWE_TD->prev_wb_bwe_frame_pow_fx )) + { + L_tmp = root_a_over_b_fx(hBWE_TD->prev_wb_bwe_frame_pow_fx, 22, curr_frame_pow, 22, &exp ); + scale = round_fx( L_shl( L_tmp, exp ) ); /*Q15*/ + + L_tmp = root_a_fx( L_tmp, 31 - exp, &exp ); + L_tmp = root_a_fx( L_tmp, 31 - exp, &exp ); + L_tmp = root_a_fx( L_tmp, 31 - exp, &exp ); + temp = round_fx( L_shl( L_tmp, exp ) ); /* Q15 */ + } + ELSE + { + scale = temp = 32767; + move16();/* Q15 */ + } + + FOR( j = 0; j < 8; j++ ) + { + GainShape[2 * j] = mult_r( GainShape[2 * j], scale ); + GainShape[2 * j + 1] = mult_r( GainShape[2 * j + 1], scale ); + FOR( i = 0; i < L_FRAME16k / ( 4 * 8 ); i++ ) + { + shaped_wb_excitation[i + j * L_FRAME16k / ( 4 * 8 )] = mult_r( shaped_wb_excitation[i + j * L_FRAME16k / ( 4 * 8 )], scale ); + } + IF( temp > 0 ) + { + IF( LT_16( scale, temp )) + { + scale = div_s( scale, temp ); + } + ELSE + { + scale = 32767; + move16(); + } + } + ELSE + { + scale = 0; + move16(); + } + } + } + + hBWE_TD->prev_wb_bwe_frame_pow_fx = curr_frame_pow; + move32(); + st_fx->prev_frame_pow_exp = curr_frame_pow_exp; + move16(); + + /* generate 16kHz SHB signal (6 - 8 kHz) from 2kHz signal */ + max = 0; + move16(); + FOR( cnt = 0; cnt < ( L_FRAME16k + L_SHB_LAHEAD ) / 4; cnt++ ) + { + if( abs_s( shaped_wb_excitation[cnt] ) > max ) + { + max = abs_s( shaped_wb_excitation[cnt] ); + } + } + Qx = norm_s( max ); + if ( max == 0 ) + { + Qx = 15; + move16(); + } + + Qx = sub( Qx, 1 ); /* 1 bit space for saturation */ + + max = 0; + move16(); + FOR( i = 0; i < 2*ALLPASSSECTIONS_STEEP; i++ ) + { + if( abs_s(hBWE_TD->state_lsyn_filt_shb_fx[i] ) > max ) + max = abs_s(hBWE_TD->state_lsyn_filt_shb_fx[i] ); + } + + FOR( i = 0; i < 2*ALLPASSSECTIONS_STEEP; i++ ) + { + if( abs_s(hBWE_TD->state_lsyn_filt_dwn_shb_fx[i] ) > max ) + max = abs_s(hBWE_TD->state_lsyn_filt_dwn_shb_fx[i] ); + } + + IF( EQ_32(st_fx->output_Fs, 32000)) + { + FOR ( i = 0; i < 2*ALLPASSSECTIONS_STEEP; i++ ) + { + max = s_max(max, abs_s(hBWE_TD->state_32and48k_WB_upsample_fx[i] )); + } + } + IF( EQ_32(st_fx->output_Fs, 48000)) + { + FOR ( i = 0; i < INTERP_3_1_MEM_LEN; i++ ) + { + max = s_max(max, abs_s(hBWE_TD->mem_resamp_HB_fx[i] )); + } + } + n_mem = 15; + if( max != 0 ) + { + n_mem = norm_s( max ); + } + n_mem = s_max( n_mem, 0 ); + + if( sub( Qx, st_fx->prev_Qx ) > n_mem ) + Qx = add( st_fx->prev_Qx, n_mem ); + + FOR( i = 0; i < ( L_FRAME16k + L_SHB_LAHEAD ) / 4; i++ ) + { + shaped_wb_excitation[i] = shl( shaped_wb_excitation[i], Qx ); + move16(); + } + + FOR( i = 0; i < 2*ALLPASSSECTIONS_STEEP; i++ ) + { + hBWE_TD->state_lsyn_filt_shb_fx[i] = shl(hBWE_TD->state_lsyn_filt_shb_fx[i], sub( Qx, st_fx->prev_Qx ) ); + move16(); + } + + FOR( i = 0; i < 2*ALLPASSSECTIONS_STEEP; i++ ) + { + hBWE_TD->state_lsyn_filt_dwn_shb_fx[i] = shl(hBWE_TD->state_lsyn_filt_dwn_shb_fx[i], sub( Qx, st_fx->prev_Qx ) ); + move16(); + } + + GenWBSynth_fx( shaped_wb_excitation, error, hBWE_TD->state_lsyn_filt_shb_fx, hBWE_TD->state_lsyn_filt_dwn_shb_fx ); + + Copy( error + L_FRAME16k - L_SHB_TRANSITION_LENGTH, hBWE_TD->old_tbe_synth_fx, L_SHB_TRANSITION_LENGTH ); + + FOR( i = 0; i < L_FRAME16k; i++ ) + { + synth[i] = mult_r( error[i], 21299 ); + move16(); + } + + max = 0; + move16(); + FOR( cnt = 0; cnt < L_FRAME16k; cnt++ ) + { + max = s_max( max, abs_s( synth[cnt] ) ); + } + + IF( max == 0 ) + { + st_fx->last_wb_bwe_ener_fx = 0; + move16(); + } + ELSE + { + n = norm_s( max ); + FOR( cnt = 0; cnt < L_FRAME16k; cnt++ ) + { + synth_frac[cnt] = shl( synth[cnt], n ); /*Q14*/ move16(); + } + n = sub( sub( 14, n ), Qx ); + + Lacc = 0; + FOR( i = 0; i < L_FRAME16k; i++ ) + { + L_tmp = L_mult( synth_frac[i], synth_frac[i] ); /* Q29 */ + Lacc = L_add( Lacc, L_shr( L_tmp, 7 ) ); /* Q22 */ + } + + L_tmp = Mult_32_16( Lacc, 102 ); /* Q22 */ + exp = norm_l( L_tmp ); +#ifdef BASOP_NOGLOB + tmp = round_fx_o( L_shl_o( L_tmp, exp , &Overflow), &Overflow); +#else + tmp = round_fx( L_shl( L_tmp, exp ) ); +#endif + exp = sub( add( exp, 22 ), 30 ); + tmp = div_s( 16384, tmp ); + L_tmp = Isqrt_lc( L_deposit_h( tmp ), &exp ); /* Q(31-exp) */ + st_fx->last_wb_bwe_ener_fx = round_fx( L_shl( L_tmp, add( exp, n - 12 ) ) ); /* Q3 */ + } + + + IF( EQ_32(st_fx->output_Fs, 32000)) /* 32kHz sampling rate, but only WB output - interpolate */ + { + Scale_sig(hBWE_TD->state_32and48k_WB_upsample_fx, 2*ALLPASSSECTIONS_STEEP, sub( Qx, st_fx->prev_Qx )); + Interpolate_allpass_steep_fx( synth, hBWE_TD->state_32and48k_WB_upsample_fx, L_FRAME16k, upsampled_synth ); + Copy( upsampled_synth, synth, L_FRAME32k ); + } + ELSE IF( EQ_32(st_fx->output_Fs, 48000)) + { + Scale_sig(hBWE_TD->mem_resamp_HB_fx, INTERP_3_1_MEM_LEN, sub( Qx, st_fx->prev_Qx )); + interpolate_3_over_1_allpass_fx( synth, L_FRAME16k, upsampled_synth, hBWE_TD->mem_resamp_HB_fx); + Copy( upsampled_synth, synth, L_FRAME48k ); + } + } + ELSE + { + f = 5461; + move16();/* Q15 */ + inc = 5461; + move16();/* Q15 */ + FOR( i = 0; i < LPC_SHB_ORDER_WB; i++ ) + { + lsf_wb[i] = f; + move16();/*Q15*/ +#ifdef BASOP_NOGLOB + f = add_sat( f, inc ); +#else + f = add( f, inc ); +#endif + move16(); + } + GainFrame = 0; /* Q18 */ + Qx = 0; + Q_bwe_exc = 31; + hBWE_TD->prev_wb_bwe_frame_pow_fx = 4194l/*0.001f Q22*/; /* Q22 */ + st_fx->prev_frame_pow_exp = 0; + move16(); + } + + /* Update previous frame parameters for FEC */ + IF( EQ_32( st_fx->extl_brate, WB_TBE_0k35 ) ) + { + Copy( lsf_wb, hBWE_TD->lsp_prevfrm_fx, LPC_SHB_ORDER_LBR_WB ); + } + ELSE + { + Copy( lsf_wb, hBWE_TD->lsp_prevfrm_fx, LPC_SHB_ORDER_WB ); + } + hBWE_TD->GainFrame_prevfrm_fx = GainFrame; /* Q18 */ + + if( !st_fx->bfi ) + { + hBWE_TD->GainAttn_fx = 32767; + move16(); + } + + *Q_synth = Qx; + move16(); + + st_fx->prev_Q_bwe_exc = Q_bwe_exc; + move16(); + st_fx->prev_Qx = Qx; + move16(); + + return; +} + + + +/*======================================================================================*/ +/* FUNCTION : void swb_tbe_dec_fx () */ +/*--------------------------------------------------------------------------------------*/ +/* PURPOSE : SWB TBE decoder, 6 - 14 kHz (or 7.5 - 15.5 kHz) band decoding module */ +/*--------------------------------------------------------------------------------------*/ +/* INPUT ARGUMENTS : */ +/* _(Word16) coder_type : coding type */ +/* _(Word16*) bwe_exc_extended :bandwidth extended exciatation Q0 */ +/* _(Word16[]) voice_factors :voicing factors Q15 */ +/* _(Word16*) Q_white_exc :Q Format of White Exc */ +/* _(Word16*) Q_synth :Q Format of Synthesis */ +/*--------------------------------------------------------------------------------------*/ +/* OUTPUT ARGUMENTS : */ +/* _(Word16*)synth : SHB synthesis/final synthesis Q_white_exc */ +/* _(Word16*)White_exc16k : shaped white excitation for the FB TBE Q_synth */ +/*--------------------------------------------------------------------------------------*/ +/* INPUT/OUTPUT ARGUMENTS : */ +/* _ Decoder_State *st_fx: : Decoder state structure */ +/*--------------------------------------------------------------------------------------*/ +/* RETURN ARGUMENTS : */ +/* _ None */ +/*--------------------------------------------------------------------------------------*/ +/* CALLED FROM : RX */ +/*======================================================================================*/ +void swb_tbe_dec_fx( + Decoder_State* st_fx, /* i/o: decoder state structure */ + const Word16 coder_type, /* i : coding type */ + Word32* bwe_exc_extended, /* i : bandwidth extended excitation 2*Q_exc */ + Word16 Q_exc, + const Word16 voice_factors[], /* i : voicing factors */ + const Word16 old_syn_12k8_16k[], /* i : low band synthesis */ + Word16* White_exc16k, /* o : shaped white excitation for the FB TBE */ + Word16* Q_white_exc, + Word16* synth, /* o : SHB synthesis/final synthesis */ + Word16* Q_synth, + Word16* pitch_buf /* i : pitch buffer Q6 */ +) +{ + Word16 i; + Word16 shaped_shb_excitation [ L_FRAME16k + L_SHB_LAHEAD ]; + Word16 bwe_exc_extended_16[L_FRAME32k+NL_BUFF_OFFSET]; + Word16 lsf_shb[LPC_SHB_ORDER], lpc_shb[LPC_SHB_ORDER + 1], GainShape[NUM_SHB_SUBFR]; + Word32 GainFrame; + Word16 error[L_FRAME32k]; + Word32 L_ener; + Word16 ener; + Word16 is_fractive; + Word32 prev_pow, curr_pow, Lscale; + Word16 scale; + Word16 exp, tmp; + Word16 j, cnt ; + Word16 n_mem, n_mem2, Qx, sc; + Word16 n_mem3; + Word32 Lmax, L_tmp; + Word16 frac; + + Word32 L_tmp1, L_tmp2; + Word16 expa, expb; + Word16 fraca, fracb; + Word16 GainShape_tmp[NUM_SHB_SUBGAINS]; + Word16 Q_bwe_exc; + Word16 Q_shb; + Word16 vf_modified[NB_SUBFR16k]; + Word16 stemp; + + Word16 tilt_swb_fec; + Word16 Q_bwe_exc_fb; + + Word16 lsp_shb_1[LPC_SHB_ORDER], lsp_shb_2[LPC_SHB_ORDER], lsp_temp[LPC_SHB_ORDER]; + Word16 lpc_shb_sf[4*(LPC_SHB_ORDER+1)]; + const Word16 *ptr_lsp_interp_coef; + Word32 shb_ener_sf_32; + Word16 shb_res_gshape[NB_SUBFR16k]; + Word16 mixFactors; + Word16 vind; + Word16 shb_res_dummy[L_FRAME16k]; + Word16 shaped_shb_excitationTemp[L_FRAME16k]; + Word32 ener_tmp[NUM_SHB_SUBGAINS]; + Word16 pitch_fx; + Word16 l_subframe_fx; + Word16 formant_fac; + Word16 lsf_diff[LPC_SHB_ORDER], w[LPC_SHB_ORDER]; + Word16 refl[M]; + Word16 tilt_para; + Word16 tmp1,tmp2; + Word16 f_fx, inc_fx; + Word32 GainFrame_prevfrm_fx; + + Word16 synth_scale_fx; + Word16 mean_vf; + Word16 exp_ener, inv_ener; + Word32 prev_ener_ratio_fx=0; /* initialize just to avoid compiler warning */ + Word16 max,n,temp,shaped_shb_excitation_frac [ L_FRAME16k + L_SHB_LAHEAD ]; + Word32 curr_frame_pow; + Word16 curr_frame_pow_exp; + Word32 L_prev_ener_shb; + TD_BWE_DEC_HANDLE hBWE_TD; + hBWE_TD = st_fx->hBWE_TD; + + /* initializations */ + GainFrame = L_deposit_l(0); + mixFactors = 0; + move16(); + shb_ener_sf_32 = L_deposit_l(0); + set16_fx( shaped_shb_excitationTemp, 0, L_FRAME16k ); + st_fx->shb_dtx_count_fx = 0; + move16(); + is_fractive = 0; + move16(); + set16_fx( shb_res_gshape, 1638/*0.1f Q14*/, NB_SUBFR16k ); /* Q14 */ + Q_shb = 0; /* high band target Q factor set to zero */ + + L_tmp = calc_tilt_bwe_fx(old_syn_12k8_16k, st_fx->Q_syn2, st_fx->L_frame); +#ifdef BASOP_NOGLOB + tilt_swb_fec = round_fx_sat(L_shl_sat(L_tmp, 3)); +#else + tilt_swb_fec = round_fx(L_shl(L_tmp, 3)); +#endif + /* i: old_syn_12k8_16k in st_fx->Q_syn2 */ + /* o: tilt_swb_fec in Q11 */ + test(); + IF( st_fx->bfi && NE_16(st_fx->clas_dec,UNVOICED_CLAS)) + { + tilt_swb_fec = hBWE_TD->tilt_swb_fec_fx; + move16(); + } + + /* WB/SWB bandwidth switching */ + test(); + test(); + IF( ( GT_16(st_fx->tilt_wb_fx, 10240)&&EQ_16(st_fx->clas_dec,UNVOICED_CLAS))||GT_16(st_fx->tilt_wb_fx,20480)) + { + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( (st_fx->prev_fractive_fx == 0 && + (LT_32( st_fx->prev_enerLH_fx, L_shl( st_fx->enerLH_fx, 1 ) ) && GT_32( st_fx->prev_enerLH_fx, L_shr( st_fx->enerLH_fx, 1 ) ) + && LT_32( st_fx->prev_enerLL_fx, L_shl( st_fx->enerLL_fx, 1 ) ) && GT_32( st_fx->prev_enerLL_fx, L_shr( st_fx->enerLL_fx, 1 ) ) )) + || (EQ_16(st_fx->prev_fractive_fx,1) && + GT_32(L_shr(st_fx->prev_enerLH_fx,2), Mult_32_16(st_fx->enerLH_fx,24576)) ) /* 24576 in Q13*/ + || (GT_32(L_shr(st_fx->enerLL_fx,1), Mult_32_16(st_fx->enerLH_fx, 24576)) && /*24576 = 1.5 in Q14*/ + LT_16(st_fx->tilt_wb_fx, 20480) )/* 20480 = 10 in Q11*/ + ) + { + is_fractive = 0; + move16(); + } + ELSE + { + is_fractive = 1; + move16(); + } + } + + /* WB/SWB bandwidth switching */ + IF( st_fx->bws_cnt_fx > 0 ) + { + f_fx = 1489; /*Q15*/ + inc_fx = 1489; /*Q15*/ + IF(EQ_16(is_fractive, 1)) + { + Copy(lsf_tab_fx, hBWE_TD->lsp_prevfrm_fx, LPC_SHB_ORDER); + } + ELSE + { + FOR (i=0; ilsp_prevfrm_fx[i] = f_fx; + move16(); + f_fx = add(f_fx, inc_fx); + } + } + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( (NE_16(st_fx->last_extl, SWB_TBE)&&NE_16(st_fx->last_extl,FB_TBE)&& + !(L_sub(L_shr(st_fx->prev_enerLH_fx, 1), st_fx->enerLH_fx) < 0 &&L_sub(st_fx->prev_enerLH_fx, L_shr(st_fx->enerLH_fx,1)>0))) + || sub(st_fx->last_core, ACELP_CORE) != 0 + || (sub(st_fx->last_core, ACELP_CORE) == 0 && L_sub(L_abs(L_sub(st_fx->last_core_brate, st_fx->core_brate)), 3600) > 0) + || sub((is_fractive ^ st_fx->prev_fractive_fx), 1) == 0 ) + { + set16_fx( GainShape, 11587, NUM_SHB_SUBFR ); + } + ELSE + { + if(GT_16(hBWE_TD->prev_GainShape_fx, 11587)) + { + hBWE_TD->prev_GainShape_fx = 11587; + move16(); + } + set16_fx( GainShape, hBWE_TD->prev_GainShape_fx, NUM_SHB_SUBFR ); + } + + Copy(hBWE_TD->lsp_prevfrm_fx, lsf_shb, LPC_SHB_ORDER ); + set16_fx( shb_res_gshape, 3277/*0.2f Q14*/, NB_SUBFR16k ); /* Q14 */ + } + ELSE /* No bandwidth switching */ + { + test(); + IF( NE_16(st_fx->last_extl, SWB_TBE)&&NE_16(st_fx->last_extl,FB_TBE)) + { + f_fx = 1489; /*Q15*/ move16(); + inc_fx = 1489; /*Q15*/ move16(); + FOR (i=0; ilsp_prevfrm_fx[i] = f_fx; + move16(); + f_fx = add(f_fx, inc_fx); + } + } + + IF( !st_fx->bfi ) + { + IF(st_fx->use_partial_copy) + { + IF(NE_16(st_fx->last_extl, SWB_TBE)) + { + hBWE_TD->GainFrame_prevfrm_fx = 0; + move16(); + move16(); + move16(); + f_fx = 1489/*0.045454f Q15*/; /*Q15*/ + inc_fx = 1489/*0.045454f Q15*/;; /*Q15*/ + FOR (i=0; ilsp_prevfrm_fx[i] = f_fx; + move16(); + f_fx = add(f_fx, inc_fx); + } + } + Copy(hBWE_TD->lsp_prevfrm_fx, lsf_shb, LPC_SHB_ORDER ); + set16_fx( GainShape, RECIP_ROOT_EIGHT_FX, NUM_SHB_SUBFR ); + + IF( EQ_16(st_fx->rf_frame_type,RF_NELP)) + { + /* Frame gain */ + GainFrame = L_mac( SHB_GAIN_QLOW_FX, st_fx->rf_indx_tbeGainFr, SHB_GAIN_QDELTA_FX ); + move32();/*Q18*/ + L_tmp = Mult_32_16( GainFrame, 27213 ); /*Q16*/ /* 3.321928 in Q13 */ + + frac = L_Extract_lc( L_tmp, &exp ); + L_tmp = Pow2( 30, frac ); + GainFrame = L_shl( L_tmp, sub( exp, 12 ) ); /*Q18*/ + IF( EQ_16(st_fx->core,ACELP_CORE)&&EQ_16(st_fx->last_core,ACELP_CORE) + && !st_fx->prev_use_partial_copy && EQ_16(st_fx->prev_coder_type_fx,UNVOICED) + && NE_32(GainFrame, hBWE_TD->GainFrame_prevfrm_fx) && NE_16(st_fx->next_coder_type,GENERIC) && EQ_16(st_fx->last_extl, SWB_TBE) ) + { + /*GainFrame = 0.2f*GainFrame + 0.8f*st_fx->GainFrame_prevfrm_fx;*/ + GainFrame = L_add(Mult_32_16(hBWE_TD->GainFrame_prevfrm_fx, 26214), Mult_32_16(GainFrame, 6553)); + } + } + ELSE + { + temp = 0; + move16(); + /* Frame gain */ + SWITCH (st_fx->rf_indx_tbeGainFr) + { + case 0: + GainFrame = 131072; /* 0.5f in Q18 */ + IF(LE_32(hBWE_TD->GainFrame_prevfrm_fx, 327680l/*1.25 Q18*/)) temp = 26214/*0.8 Q15*/; + move16(); + BREAK; + case 1: + GainFrame = 524288; /* 2.0f in Q18 */ + IF(GT_32(hBWE_TD->GainFrame_prevfrm_fx, 327680l/*1.25 Q18*/)&&LE_32(hBWE_TD->GainFrame_prevfrm_fx,786432l/*3 Q18*/)) temp = 26214/*0.8 Q15*/; + move16(); + test(); + BREAK; + case 2: + GainFrame = 1048576;/* 4.0f in Q18 */ + IF(GT_32(hBWE_TD->GainFrame_prevfrm_fx, 786432l/*3 Q18*/)&&LE_32(hBWE_TD->GainFrame_prevfrm_fx,1572864l/*6 Q18*/)) temp = 26214/*0.8 Q15*/; + move16(); + test(); + BREAK; + case 3: + GainFrame = 2097152;/* 8.0f in Q18 */ + IF(GT_32(hBWE_TD->GainFrame_prevfrm_fx, 1572864l/*6 Q18*/)&&LE_32(hBWE_TD->GainFrame_prevfrm_fx,4194304l/*16Q18*/)) temp = 26214/*0.8 Q15*/; + move16(); + test(); + BREAK; + default: + fprintf(stderr, "RF SWB-TBE gain bits not supported."); + } + IF(EQ_16(st_fx->last_extl, SWB_TBE)) + { + GainFrame = L_add(Mult_32_16(hBWE_TD->GainFrame_prevfrm_fx, temp), Mult_32_16(GainFrame, sub(32767,temp))); + } + IF(EQ_16(st_fx->core,ACELP_CORE)&&EQ_16(st_fx->last_core,ACELP_CORE)) + { + IF(!st_fx->prev_use_partial_copy && EQ_16(st_fx->last_coder_type_fx, VOICED)&&EQ_16(st_fx->rf_frame_type,RF_GENPRED)&>_32(GainFrame,2097152)&<_32(GainFrame,3059606)) + { + GainFrame = Mult_32_16(GainFrame,9830); + } + } + } + } + ELSE + { + + /* de-quantization */ + dequantizeSHBparams_fx_9_1( st_fx, st_fx->extl, st_fx->extl_brate, lsf_shb, GainShape, &GainFrame, &stemp, + &shb_ener_sf_32, shb_res_gshape, &mixFactors ); + Q_shb = 0; + move16(); + /* o: shb_ener_sf_32 in (2*Q_shb) */ + /* o: shb_res_gshape in Q14 */ + /* o: GainShape Q15 */ + /* o: GainFrame Q18 */ + } + } + ELSE /* FER concealment of TBE parameters */ + { + Copy(hBWE_TD->lsp_prevfrm_fx, lsf_shb, LPC_SHB_ORDER ); + + /* Gain shape concealment */ + IF( EQ_16(st_fx->codec_mode, MODE1)) + { + /* Gradient based GS estimation */ + gradientGainShape(st_fx, GainShape, &GainFrame); + /* o: GainShape[16] in Q15 */ + /* o: GainFrame in Q18 */ + } + ELSE + { + FOR( i = 0; i < NUM_SHB_SUBFR / 4; i++ ) + { + FOR( j = 0; j < 4; j++ ) + { + GainShape[i * 4 + j] = mult_r( st_fx->cummulative_damping, st_fx->GainShape_Delay[4+i]); + move16(); + } + } + IF( GT_16( tilt_swb_fec, 8<<11 )) /* tilt_swb_fec in Q11 */ + { + IF ( EQ_16(st_fx->nbLostCmpt, 1)) + { + GainFrame = Mult_32_16(hBWE_TD->GainFrame_prevfrm_fx, 19661/*0.6f Q15*/); + } + ELSE IF( EQ_16(st_fx->nbLostCmpt, 2)) + { + GainFrame = Mult_32_16(hBWE_TD->GainFrame_prevfrm_fx, 11469/*0.35f Q15*/); + } + ELSE + { + GainFrame = Mult_32_16(hBWE_TD->GainFrame_prevfrm_fx, 6554/*0.2f Q15*/); + } + GainFrame = Mult_32_16( GainFrame, st_fx->cummulative_damping); + } + ELSE + { + GainFrame = hBWE_TD->GainFrame_prevfrm_fx; + move16(); /* gain locking */ + } + } + + /* FER concealment for 24.4kbps and 32kbps */ + test(); + IF(EQ_32(st_fx->total_brate,ACELP_24k40)||EQ_32(st_fx->total_brate,ACELP_32k)) + { + IF(EQ_16(st_fx->codec_mode, MODE1)) + { + /*scale = st->prev1_shb_ener_sf/root_a(st->prev2_shb_ener_sf * st->prev3_shb_ener_sf); */ + L_tmp = L_mult(extract_l(hBWE_TD->prev2_shb_ener_sf_fx), extract_l(hBWE_TD->prev3_shb_ener_sf_fx)); /*Q1*/ + tmp = round_fx(root_a_fx(L_tmp, 1, &exp)); /* Q = 15-exp */ + tmp1 = extract_l(hBWE_TD->prev1_shb_ener_sf_fx); /*Q0*/ + i = sub(norm_s(tmp1), 1); + tmp1 = shl(tmp1, i); /* Qi */ + if(tmp == 0) + { + tmp = 32767/*1.0f Q15*/; + move16(); /*Q15*/ + } + ELSE + { + scale = div_s(tmp1, tmp); /* Q15 - Q(15-exp) + Qi = Qexp+i */ + scale = s_max(scale, 0); + /*scale = st->prev_res_shb_gshape * min(scale, 1.0f); */ +#ifdef BASOP_NOGLOB + tmp = shl_sat(scale, 15 - exp - i); /*Q15*/ +#else + tmp = shl(scale, 15 - exp - i); /*Q15*/ +#endif + } + scale = mult_r(hBWE_TD->prev_res_shb_gshape_fx, tmp); /* Q14 */ + + test(); + IF( GT_32( L_shr(hBWE_TD->prev2_shb_ener_sf_fx, 1), hBWE_TD->prev1_shb_ener_sf_fx )|| + GT_32( L_shr(hBWE_TD->prev3_shb_ener_sf_fx, 1), hBWE_TD->prev2_shb_ener_sf_fx ) ) + { + /* shb_ener_sf_32 = 0.5f * scale * st_fx->prev1_shb_ener_sf_fx; */ + shb_ener_sf_32 = Mult_32_16(hBWE_TD->prev1_shb_ener_sf_fx, scale ); + + if( GT_16(st_fx->nbLostCmpt, 1)) + { + /* shb_ener_sf_32 *= 0.5f; */ + shb_ener_sf_32 = L_shr(shb_ener_sf_32, 1); + } + } + ELSE + { + /* shb_ener_sf = scale * scale * st_fx->prev1_shb_ener_sf_fx; */ + L_tmp = L_mult(scale, scale); /* Q29 */ + shb_ener_sf_32 = L_shl(Mult_32_16(hBWE_TD->prev1_shb_ener_sf_fx, round_fx(L_tmp)), 2); + } + } + ELSE + { + test(); + IF( GT_32( L_shr(hBWE_TD->prev2_shb_ener_sf_fx, 1), hBWE_TD->prev1_shb_ener_sf_fx )|| + GT_32( L_shr(hBWE_TD->prev3_shb_ener_sf_fx, 1), hBWE_TD->prev2_shb_ener_sf_fx ) ) + { + /* shb_ener_sf_32 = 0.5f * st->cummulative_damping * st_fx->prev1_shb_ener_sf_fx; */ + shb_ener_sf_32 = L_shr( Mult_32_16(hBWE_TD->prev1_shb_ener_sf_fx, st_fx->cummulative_damping ), 1 ); + } + ELSE + { + shb_ener_sf_32 = Mult_32_16(hBWE_TD->prev1_shb_ener_sf_fx, st_fx->cummulative_damping ); + } + } + } + + shb_ener_sf_32 = L_max( shb_ener_sf_32, 1l/*1.0f Q0*/ ); + mixFactors = hBWE_TD->prev_mixFactors_fx; + + IF(EQ_16(st_fx->codec_mode, MODE1)) + { + set16_fx( shb_res_gshape, 3277/*0.2f Q14*/, 5 ); /* Q14 */ + } + ELSE + { + set16_fx( shb_res_gshape, 16384/*1.0f Q14*/, 5 ); /* Q14 */ + } + } + } + + /* get the gainshape delay */ + Copy( &st_fx->GainShape_Delay[4], &st_fx->GainShape_Delay[0], NUM_SHB_SUBFR / 4 ); + IF ( (st_fx->rf_flag != 0) || EQ_32(st_fx->total_brate, ACELP_9k60)) + { + FOR( i = 0; i < NUM_SHB_SUBFR / 4; i++ ) + { + st_fx->GainShape_Delay[i + 4] = s_min( s_max( GainShape[i * 4], 3277/*0.1f Q15*/ ), 16384/*0.5f Q15*/ ); + move16(); + } + } + ELSE + { + FOR( i = 0; i < NUM_SHB_SUBFR / 4; i++ ) + { + st_fx->GainShape_Delay[i + 4] = GainShape[i * 4]; + move16(); + } + } + + /* voice factor modification to limit any spurious jumps in the middle of voiced subframes*/ + /* mean(voice_factors[i], 4); */ + L_tmp = L_mult(voice_factors[0], 8192); + L_tmp = L_mac(L_tmp, voice_factors[1], 8192); + L_tmp = L_mac(L_tmp, voice_factors[2], 8192); + mean_vf = mac_r(L_tmp, voice_factors[3], 8192); + + Copy( voice_factors, vf_modified, NB_SUBFR16k ); + + test(); + IF( EQ_16(coder_type, VOICED)||GT_16(mean_vf,13107/*0.4f Q15*/ )) + { + FOR( i = 1; i < NB_SUBFR; i++ ) + { + L_tmp = L_mult(voice_factors[i], 26214/*0.8f Q15*/); + vf_modified[i] = mac_r(L_tmp, voice_factors[i-1], 6554/*0.2f Q15*/); + move16(); + } + IF( NE_16(st_fx->L_frame, L_FRAME)) + { + L_tmp = L_mult(voice_factors[4], 26214/*0.8f Q15*/); + vf_modified[4] = mac_r(L_tmp, voice_factors[3], 6554/*0.2f Q15*/); + move16(); + } + } + + /* convert quantized LSFs to LSPs for interpolation */ + E_LPC_lsf_lsp_conversion(lsf_shb, lsp_shb_2, LPC_SHB_ORDER); + + test(); + IF( EQ_16(st_fx->last_extl, SWB_TBE)||EQ_16(st_fx->last_extl,FB_TBE)) + { + /* SHB LSP values from prev. frame for interpolation */ + Copy(hBWE_TD->swb_lsp_prev_interp_fx, lsp_shb_1, LPC_SHB_ORDER); + } + ELSE + { + /* Use current frame's LSPs; in effect no interpolation */ + Copy(lsp_shb_2, lsp_shb_1, LPC_SHB_ORDER); + } + + test(); + test(); + test(); + IF( st_fx->bws_cnt_fx == 0 && st_fx->bws_cnt1_fx == 0 && st_fx->prev_use_partial_copy == 0 && st_fx->use_partial_copy == 0 ) + { + lsf_diff[0] = 16384; + move16(); /*Q15*/ + lsf_diff[sub(LPC_SHB_ORDER,1)] = 16384; + move16(); /*Q15*/ + FOR(i=1; i < LPC_SHB_ORDER-1; i++) + { + lsf_diff[i] = sub(lsf_shb[i],lsf_shb[sub(i,1)]); + move16(); + } + + a2rc_fx (hBWE_TD->cur_sub_Aq_fx+1, refl, M); + tmp = add(16384, shr(refl[0],1)); /*Q14*/ + tmp1 = mult(27425,tmp); + tmp1 = mult(tmp1,tmp); /*Q10*/ + tmp2 = shr(mult(31715,tmp),2); /*Q10*/ + tilt_para = add(sub(tmp1,tmp2),1335); /*Q10*/ + + test(); + IF(NE_16(st_fx->last_extl,SWB_TBE)&&NE_16(st_fx->last_extl,FB_TBE)) + { + FOR( i=1; iprev_lsf_diff_fx[i-1] = shr(lsf_diff[i], 1); + move16(); + } + } + + IF( LE_32(st_fx->total_brate,ACELP_16k40)) + { + test(); + test(); + test(); + test(); + test(); + IF(!(GT_16(hBWE_TD->prev_tilt_para_fx,5120)&&(EQ_16(coder_type,TRANSITION)||LT_16(tilt_para,1024)))&& + !(((LT_16(hBWE_TD->prev_tilt_para_fx,3072) && GE_16(st_fx->prev_coder_type_fx,VOICED))) && GT_16(tilt_para,5120) )) + { + FOR( i = 1; i < LPC_SHB_ORDER-1; i++ ) + { + IF(LT_16(lsf_diff[i], hBWE_TD->prev_lsf_diff_fx[i-1])) + { + tmp = mult(26214,lsf_diff[i]); + + test(); + IF(hBWE_TD->prev_lsf_diff_fx[i-1] <= 0 || tmp < 0 ) /* safety check in case of bit errors */ + { + st_fx->BER_detect = 1; + move16(); + tmp = 0; + } + ELSE + { + tmp = div_s(tmp,hBWE_TD->prev_lsf_diff_fx[i-1]); + } + + tmp = s_max(tmp,16384); + w[i] = s_min(tmp,32767); + move16(); + } + ELSE + { + tmp = mult(26214,hBWE_TD->prev_lsf_diff_fx[i-1]); + + test(); + IF( lsf_diff[i] <= 0 || tmp < 0 ) /* safety check in case of bit errors */ + { + st_fx->BER_detect = 1; + move16(); + tmp = 0; + } + ELSE + { + tmp = div_s(tmp,lsf_diff[i]); + } + + tmp = s_max(tmp,16384); + w[i] = s_min(tmp,32767); + move16(); + } + } + w[0] = w[1]; + w[sub(LPC_SHB_ORDER,1)] = w[sub(LPC_SHB_ORDER,2)]; + + FOR( i = 0; i < LPC_SHB_ORDER; i++ ) + { + tmp1 = mult(lsp_shb_1[i],sub(32767,w[i])); + tmp2 = mult(lsp_shb_2[i],w[i]); + lsp_temp[i] =add(tmp1,tmp2); + move16(); + } + } + ELSE + { + Copy(lsp_shb_2, lsp_temp, LPC_SHB_ORDER); + } + } + + Copy( lsf_diff + 1, hBWE_TD->prev_lsf_diff_fx, LPC_SHB_ORDER-2 ); + hBWE_TD->prev_tilt_para_fx = tilt_para; + } + ELSE + { + Copy(lsp_shb_2, lsp_temp, LPC_SHB_ORDER); + } + + test(); + IF ( EQ_32(st_fx->total_brate, ACELP_24k40 )||EQ_32(st_fx->total_brate,ACELP_32k)) + { + /* ---------- SHB LSP interpolation ---------- */ + ptr_lsp_interp_coef = interpol_frac_shb; /*Q15*/ + FOR( j = 0; j < 4; j++ ) + { + FOR( i = 0; i < LPC_SHB_ORDER; i++ ) + { + /*lsp_temp_fx[i] = lsp_shb_1_fx[i]*(*ptr_lsp_interp_coef_fx) */ + /* + lsp_shb_2_fx[i]*(*(ptr_lsp_interp_coef_fx+1));*/ + L_tmp = L_mult(lsp_shb_1[i], (*ptr_lsp_interp_coef)); + lsp_temp[i] = mac_r(L_tmp, lsp_shb_2[i], (*(ptr_lsp_interp_coef+1))); + move16(); + } + ptr_lsp_interp_coef += 2; + + /* convert from lsp to lsf */ + /*old code: lsp2lsf_fx(lsp_temp, lsp_temp, LPC_SHB_ORDER, INT_FS_FX); */ /* input lsp_temp_fx in Q15*/ + + tmp = i_mult(j, (LPC_SHB_ORDER+1)); + /* convert LSPs to LP coefficients */ + E_LPC_f_lsp_a_conversion(lsp_temp, lpc_shb_sf+tmp, LPC_SHB_ORDER); + /* Bring the LPCs to Q12 */ + Copy_Scale_sig( lpc_shb_sf+tmp, lpc_shb_sf+tmp, LPC_SHB_ORDER+1, sub(norm_s(lpc_shb_sf[tmp]),2) ); + } + } + /*ELSE*/ + { + /* for 13.2 and 16.4kbps */ + E_LPC_f_lsp_a_conversion(lsp_temp, lpc_shb, LPC_SHB_ORDER); + Copy_Scale_sig( lpc_shb, lpc_shb, LPC_SHB_ORDER+1, sub(norm_s(lpc_shb[0]),2) ); /* Q12 */ + } + + /* Save the SWB LSP values from current frame for interpolation */ + Copy(lsp_shb_2, hBWE_TD->swb_lsp_prev_interp_fx, LPC_SHB_ORDER); + /* lsp_shb_2_fx in Q15 */ + + /* save the shb_ener Q18, prev_resgainshape Q14, and mixFactor Q15 values */ + hBWE_TD->prev3_shb_ener_sf_fx = hBWE_TD->prev2_shb_ener_sf_fx; + hBWE_TD->prev2_shb_ener_sf_fx = hBWE_TD->prev1_shb_ener_sf_fx; + hBWE_TD->prev1_shb_ener_sf_fx = shb_ener_sf_32; + hBWE_TD->prev_res_shb_gshape_fx = shb_res_gshape[4]; + hBWE_TD->prev_mixFactors_fx = mixFactors; + + /* SWB CNG/DTX - update memories */ + Copy( st_fx->lsp_shb_prev_fx, st_fx->lsp_shb_prev_prev_fx, LPC_SHB_ORDER ); /* Q15 */ + Copy( lsf_shb, st_fx->lsp_shb_prev_fx, LPC_SHB_ORDER ); /* Q15 */ + + /* vind = (short)(mixFactors*8.0f); */ + vind = shl(mixFactors,3-15); /* 3 for mpy by 8.0f, -15 to bring it to Q0 */ + /* i: mixFactors in Q15 */ + /* o: vind in Q0 */ + + /* Determine formant PF strength */ + formant_fac = swb_formant_fac_fx( lpc_shb[1], &hBWE_TD->tilt_mem_fx ); + /* o: formant_fac in Q15 */ + + /* -------- start of memory rescaling -------- */ + /* ----- calculate optimum Q_bwe_exc and rescale memories accordingly ----- */ + Lmax = 0; + FOR( cnt = 0; cnt < L_FRAME32k; cnt++ ) + { + Lmax = L_max( Lmax, L_abs( bwe_exc_extended[cnt] ) ); + } + Q_bwe_exc = norm_l( Lmax ); + if(Lmax == 0) + { + Q_bwe_exc = 31; + } + Q_bwe_exc = add( Q_bwe_exc, add( Q_exc, Q_exc ) ); + + /* Account for any outliers in the memories from previous frame for rescaling to avoid saturation */ + find_max_mem_dec( st_fx, &n_mem, &n_mem2, &n_mem3 ); /* for >=24.4, use n_mem2 lpc_syn, shb_20sample, and mem_stp_swb_fx memory */ + + tmp = add( st_fx->prev_Q_bwe_exc, n_mem ); + if( GT_16( Q_bwe_exc, tmp)) + { + Q_bwe_exc = tmp; + } + + /* rescale the memories if Q_bwe_exc is different from previous frame */ + sc = sub( Q_bwe_exc, st_fx->prev_Q_bwe_exc ); + IF( sc != 0 ) + { + rescale_genSHB_mem_dec( st_fx, sc ); + } + + /* rescale the bwe_exc_extended and bring it to 16-bit single precision with dynamic norm */ + Copy(hBWE_TD->old_bwe_exc_extended_fx, bwe_exc_extended_16, NL_BUFF_OFFSET ); + sc = sub( Q_bwe_exc, add( Q_exc, Q_exc ) ); + + FOR( cnt = 0; cnt < L_FRAME32k; cnt++ ) + { +#ifdef BASOP_NOGLOB + bwe_exc_extended_16[cnt + NL_BUFF_OFFSET] = round_fx_sat( L_shl_sat( bwe_exc_extended[cnt], sc ) ); +#else + bwe_exc_extended_16[cnt + NL_BUFF_OFFSET] = round_fx( L_shl( bwe_exc_extended[cnt], sc ) ); +#endif + } + Copy( bwe_exc_extended_16 + L_FRAME32k, hBWE_TD->old_bwe_exc_extended_fx, NL_BUFF_OFFSET ); + + /* state_syn_shbexc_fx is kept at (st_fx->prev_Q_bwe_syn) for 24.4/32kbps or is kept at Q_bwe_exc for 13.2/16.4kbps */ + Copy(hBWE_TD->state_syn_shbexc_fx, shaped_shb_excitation, L_SHB_LAHEAD ); + + /* save the previous Q factor (32-bit) of the buffer */ + st_fx->prev_Q_bwe_exc = Q_bwe_exc; + move16(); + + Q_bwe_exc = sub( Q_bwe_exc, 16 ); /* Q_bwe_exc reflecting the single precision dynamic norm-ed buffers from here */ + + /* -------- end of rescaling memories -------- */ + Q_bwe_exc_fb = st_fx->prev_Q_bwe_exc_fb; + move16(); + + IF( GT_32(st_fx->total_brate, ACELP_32k)) + { + FOR( j = 0; j < 4; j++ ) + { + Copy(lpc_shb, &lpc_shb_sf[j*(LPC_SHB_ORDER+1)], LPC_SHB_ORDER+1); + } + } + + /* Calculate the 6 to 14 kHz (or 7.5 - 15.5 kHz) SHB excitation signal from the low band ACELP core excitation */ + GenShapedSHBExcitation_fx( shaped_shb_excitation + L_SHB_LAHEAD, lpc_shb, White_exc16k, + hBWE_TD->mem_csfilt_fx, hBWE_TD->mem_genSHBexc_filt_down_shb_fx, hBWE_TD->state_lpc_syn_fx, + coder_type, bwe_exc_extended_16, hBWE_TD->bwe_seed_fx, vf_modified, st_fx->extl, + &(hBWE_TD->tbe_demph_fx ), &(hBWE_TD->tbe_premph_fx ), lpc_shb_sf, shb_ener_sf_32, + shb_res_gshape, shb_res_dummy, &vind, formant_fac, hBWE_TD->fb_state_lpc_syn_fx, + &(hBWE_TD->fb_tbe_demph_fx), &Q_bwe_exc, &Q_bwe_exc_fb,Q_shb, n_mem2, st_fx->prev_Q_bwe_syn, st_fx->total_brate, st_fx->prev_bfi ); + + *Q_white_exc = Q_bwe_exc_fb; + IF( EQ_16(st_fx->extl, FB_TBE)) + { + st_fx->prev_Q_bwe_exc_fb = Q_bwe_exc_fb; + move16(); + } + ELSE + { + /*Indirectly a memory reset of FB memories for next frame such that rescaling of memories would lead to 0 due to such high prev. Q value. + 51 because of 31 + 20(shift of Q_bwe_exc_fb before de-emphasis)*/ + st_fx->prev_Q_bwe_exc_fb = 51; + move16(); + } + /* rescale the TBE post proc memory */ + FOR( i = 0; i < LPC_SHB_ORDER; i++ ) + { + hBWE_TD->mem_stp_swb_fx[i] = shl(hBWE_TD->mem_stp_swb_fx[i], Q_bwe_exc - st_fx->prev_Q_bwe_syn); + move16(); + } + + FOR( i = 0; i < L_FRAME16k; i+=L_SUBFR16k ) + { + /* TD BWE post-processing */ + PostShortTerm_fx( &shaped_shb_excitation[L_SHB_LAHEAD+i], lpc_shb, &shaped_shb_excitationTemp[i], hBWE_TD->mem_stp_swb_fx, + hBWE_TD->ptr_mem_stp_swb_fx, &(hBWE_TD->gain_prec_swb_fx), hBWE_TD->mem_zero_swb_fx, formant_fac ); + } + Copy( shaped_shb_excitationTemp, &shaped_shb_excitation[L_SHB_LAHEAD], L_FRAME16k ); /* Q_bwe_exc */ + + tmp = sub(shl(Q_bwe_exc, 1), 31+16); +#ifdef BASOP_NOGLOB + prev_pow = L_shl_sat(1407374848l/*0.00001f Q47*/, tmp); /* 2*(Q_bwe_exc) */ + curr_pow = L_shl_sat(1407374848l/*0.00001f Q47*/, tmp); /* 2*(Q_bwe_exc) */ +#else + prev_pow = L_shl(1407374848l/*0.00001f Q47*/, tmp); /* 2*(Q_bwe_exc) */ + curr_pow = L_shl(1407374848l/*0.00001f Q47*/, tmp); /* 2*(Q_bwe_exc) */ +#endif + FOR( i = 0; i < L_SHB_LAHEAD + 10; i++ ) + { +#ifdef BASOP_NOGLOB + prev_pow = L_mac0_sat( prev_pow, shaped_shb_excitation[i], shaped_shb_excitation[i] ); /*2*Q_bwe_exc*/ + curr_pow = L_mac0_sat( curr_pow, shaped_shb_excitation[i + L_SHB_LAHEAD + 10], shaped_shb_excitation[i+L_SHB_LAHEAD + 10] ); /* 2*Q_bwe_exc */ +#else + prev_pow = L_mac0( prev_pow, shaped_shb_excitation[i], shaped_shb_excitation[i] ); /*2*Q_bwe_exc*/ + curr_pow = L_mac0( curr_pow, shaped_shb_excitation[i + L_SHB_LAHEAD + 10], shaped_shb_excitation[i+L_SHB_LAHEAD + 10] ); /* 2*Q_bwe_exc */ +#endif + } + + if( GT_16( voice_factors[0], 24576/*0.75f Q15*/ )) + { + curr_pow = L_shr( curr_pow, 2 ); /* Q(2*Q_bwe_exc) */ + } + + Lscale = root_a_over_b_fx( curr_pow, + shl(Q_bwe_exc, 1), + prev_pow, + shl(Q_bwe_exc, 1), + &exp ); + + FOR( i = 0; i < L_SHB_LAHEAD; i++ ) + { + L_tmp = Mult_32_16( Lscale, shaped_shb_excitation[i] ); /* Q_bwe_exc + (31-exp) - 15 */ + shaped_shb_excitation[i] = round_fx( L_shl( L_tmp, exp ) ); /* Q_bwe_exc */ + } + IF( exp < 0 ) + { + Lscale = L_shl(Lscale, exp); + exp = 0; + } + FOR( ; i < L_SHB_LAHEAD + 10; i++ ) + { +#ifdef BASOP_NOGLOB + temp = i_mult_sat(sub(i,19), 3277/*0.1f Q15*/); /* Q15 */ + L_tmp1 = Mult_32_16(L_shl_sat(1, sub(31, exp)), temp); /* Q31-exp */ +#else + temp = i_mult(sub(i,19), 3277/*0.1f Q15*/); /* Q15 */ + L_tmp1 = Mult_32_16(L_shl(1, sub(31, exp)), temp); /* Q31-exp */ +#endif + temp = sub(32767/*1.0f Q15*/, temp); + Lscale = L_add(Mult_32_16(Lscale, temp), L_tmp1); + L_tmp = Mult_32_16( Lscale, shaped_shb_excitation[i] ); /* Q_bwe_exc + (31-exp) - 15 */ + shaped_shb_excitation[i] = round_fx( L_shl( L_tmp, exp ) ); /* Q_bwe_exc */ + } + + /* Update SHB excitation */ + Copy( shaped_shb_excitation + L_FRAME16k, hBWE_TD->state_syn_shbexc_fx, L_SHB_LAHEAD ); /* Q_bwe_exc */ + + l_subframe_fx = L_FRAME16k/NUM_SHB_SUBGAINS; + L_ener = 0; + FOR(i = 0; i < NUM_SHB_SUBGAINS; i++) + { + L_tmp = 0; + ener_tmp[i] = 0; + + { + Word64 tmp64 = 0; + move64(); + FOR(j = 0; j < l_subframe_fx; j++) + { + tmp64 = W_mac0_16_16( tmp64, shaped_shb_excitation[i*l_subframe_fx+j], shaped_shb_excitation[i*l_subframe_fx+j] );/* 2*Q_bwe_exc */ + } + L_tmp = W_sat_l(tmp64); + } + + L_tmp = Mult_32_16(L_tmp, 410/*0.0125 Q15*/); /* 2*Q_bwe_exc: ener_tmp_fx in (2*Q_bwe_exc) */ + IF( L_tmp != 0 ) + { + exp = norm_l( L_tmp ); + tmp = extract_h( L_shl( L_tmp, exp ) ); + exp = sub( exp, 30 - (2 * Q_bwe_exc) ); + + tmp = div_s( 16384, tmp ); + L_tmp = L_deposit_h( tmp ); + L_tmp = Isqrt_lc( L_tmp, &exp ); +#ifdef BASOP_NOGLOB + ener_tmp[i] = L_shl_sat( L_tmp, sub(add( exp, shl(Q_bwe_exc,1)),31)); /*2 * Q_bwe_exc: Q31 -exp +exp +2 * Q_bwe_exc -31 */ move32(); + L_ener = L_add_sat(L_ener, L_shr(ener_tmp[i], 2));/* 2*Q_bwe_exc */ +#else + ener_tmp[i] = L_shl( L_tmp, sub(add( exp, shl(Q_bwe_exc,1)),31)); /*2 * Q_bwe_exc: Q31 -exp +exp +2 * Q_bwe_exc -31 */ move32(); + L_ener = L_add(L_ener, L_shr(ener_tmp[i], 2));/* 2*Q_bwe_exc */ +#endif + } + } + ener = s_max(1, round_fx( L_shl( L_ener, sub(19, shl(Q_bwe_exc, 1)) ) )); /* Q3: 2*Q_bwe_exc+19-2*Q_bwe_exc-16 */ + + /* WB/SWB bandwidth switching */ + IF( st_fx->bws_cnt_fx > 0 ) + { + ener = mult(ener, 11587); + /*bandwidth switching should be updated*/ + if( GT_16( st_fx->tilt_swb_fx, 16384 )) + { + st_fx->prev_fractive_fx = 1; + move16(); + } + + IF( is_fractive == 0 ) + { + IF( GT_16( st_fx->tilt_wb_fx, 2048 )) /*assuming st_fx->tilt_wb_fx in Q11*/ + { + st_fx->tilt_wb_fx = 2048; + move16(); + } + ELSE IF( LT_16( st_fx->tilt_wb_fx, 1024 )) + { + st_fx->tilt_wb_fx = 1024; + move16(); + } + test(); + if( st_fx->prev_fractive_fx == 1 && GT_16( st_fx->tilt_wb_fx, 1024 )) + { + st_fx->tilt_wb_fx = 1024; + move16(); + } + } + ELSE + { + IF(GT_16(st_fx->tilt_wb_fx, 8192)) + { + IF(st_fx->prev_fractive_fx == 0) + { + st_fx->tilt_wb_fx = 8192; + } + ELSE + { + st_fx->tilt_wb_fx = 16384; + } + } + ELSE + { + st_fx->tilt_wb_fx = shl(st_fx->tilt_wb_fx, 2); + } + } + + IF(ener != 0) + { + L_tmp = L_shl(L_mult0(ener, st_fx->tilt_wb_fx), sub(st_fx->Q_syn2, 14)); /* 3+11 +st_fx->Q_syn2 -14 = st_fx->Q_syn2*/ + exp_ener = norm_s(ener); + tmp = shl(ener, exp_ener);/*Q(3+exp)*/ + inv_ener = div_s(16384, tmp);/*Q(15+14-3-exp) = 26- exp*/ + + test(); + IF( GT_32(L_tmp, st_fx->enerLH_fx)) /*st_fx->Q_syn2*/ + { +#ifdef BASOP_NOGLOB + st_fx->tilt_wb_fx = extract_h(L_shr_sat(Mult_32_16(st_fx->enerLH_fx, inv_ener), sub(sub(st_fx->Q_syn2, exp_ener),16))); /*Q11*/ +#else + st_fx->tilt_wb_fx = extract_h(L_shr(Mult_32_16(st_fx->enerLH_fx, inv_ener), sub(sub(st_fx->Q_syn2, exp_ener),16))); /*Q11*/ +#endif + /*st_fx->Q_syn2 -1 + 26- exp_ener -15 -(st_fx->Q_syn2 -exp_ener -16 ) -16 +1 -1 = (11) *0.5*/ + } + ELSE IF( LT_32(L_tmp, Mult_32_16(st_fx->enerLH_fx, 1638))&&EQ_16(is_fractive,1)) + { +#ifdef BASOP_NOGLOB + st_fx->tilt_wb_fx = extract_h(L_shr_sat(Mult_32_16(st_fx->enerLH_fx, inv_ener), sub(sub(st_fx->Q_syn2, exp_ener), 15))); /*Q11*/ +#else + st_fx->tilt_wb_fx = extract_h(L_shr(Mult_32_16(st_fx->enerLH_fx, inv_ener), sub(sub(st_fx->Q_syn2, exp_ener), 15))); /*Q11*/ +#endif + /*st_fx->Q_syn2 -1 + 26- exp_ener -15 -(st_fx->Q_syn2 -exp_ener -15 ) -16 = (11) 0.25*/ + } + L_tmp = L_mult0(st_fx->prev_ener_shb_fx, inv_ener); /*Q(1+15+14-3-exp_ener) = 27 -exp_ener*/ + GainFrame_prevfrm_fx = L_shr(L_tmp, sub(9, exp_ener)); /*27 -exp_ener -(9-exp_ener )= Q18*/ + } + ELSE + { + GainFrame_prevfrm_fx = 0; + } + + IF( EQ_16(is_fractive , 1)) + { + GainFrame = L_shl((Word32)st_fx->tilt_wb_fx, 10); + } + ELSE + { + GainFrame = L_shl((Word32)st_fx->tilt_wb_fx, 8); + } + + test(); + IF( EQ_16((is_fractive & st_fx->prev_fractive_fx), 1)&>_32(GainFrame,GainFrame_prevfrm_fx)) + { + GainFrame = L_add(Mult_32_16(GainFrame_prevfrm_fx, 26214), Mult_32_16(GainFrame, 6554));/* 18 +15 -15 = 18*/ + } + ELSE + { + test(); + test(); + test(); + test(); + IF((LT_32(L_shr(st_fx->prev_enerLH_fx, 1), st_fx->enerLH_fx)&& GT_32(st_fx->prev_enerLH_fx,L_shr(st_fx->enerLH_fx,1))) + && (LT_32(L_shr(st_fx->prev_enerLL_fx, 1), st_fx->enerLL_fx) && GT_32(st_fx->prev_enerLL_fx, L_shr(st_fx->enerLL_fx, 1)) ) && (is_fractive ^ st_fx->prev_fractive_fx) == 0) + { + GainFrame = L_add(L_shr(GainFrame, 1), L_shr(GainFrame_prevfrm_fx, 1)); + } + ELSE + { + test(); + IF(is_fractive == 0 && EQ_16(st_fx->prev_fractive_fx, 1)) + { + L_tmp1 = L_shl(Mult_32_16(GainFrame, 3277), 13); /* 31 */ + L_tmp = L_sub(2147483647, L_tmp1); /* 31 */ + GainFrame = L_add(Mult_32_32(GainFrame, L_tmp), Mult_32_32(GainFrame_prevfrm_fx, L_tmp1)); /* 18 */ + } + ELSE + { + GainFrame = L_add(L_shr(GainFrame, 1), L_shr(L_min(GainFrame_prevfrm_fx, GainFrame), 1)); /* 18 */ + } + } + } + + GainFrame = Mult_32_16(GainFrame, i_mult(sub(N_WS2N_FRAMES, st_fx->bws_cnt_fx), 819)); /*Q18*/ + } + ELSE + { + IF(st_fx->bws_cnt1_fx > 0) + { + GainFrame = Mult_32_16(GainFrame, i_mult(st_fx->bws_cnt1_fx, 819)); /*Q18*/ + } + IF(GE_16(st_fx->nbLostCmpt, 1)) + { + ener = s_max(1, ener); + exp_ener = norm_s(ener); + tmp = shl(ener, exp_ener);/*Q(3+exp)*/ + inv_ener = div_s(16384, tmp);/*Q(15+14-3-exp)*/ + prev_ener_ratio_fx = L_shr(L_mult0(st_fx->prev_ener_shb_fx, inv_ener), sub(9, exp_ener)); /*Q: 1+26-exp-9+exp = 18 */ + } + + IF(EQ_16(st_fx->nbLostCmpt, 1)) + { + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( NE_16(st_fx->clas_dec, UNVOICED_CLAS)&&NE_16(st_fx->clas_dec,UNVOICED_TRANSITION)&<_16(hBWE_TD->tilt_swb_fec_fx,16384)&& + ((GT_32(st_fx->enerLL_fx, L_shr(st_fx->prev_enerLL_fx, 1)) && LT_32(L_shr(st_fx->enerLL_fx, 1), st_fx->prev_enerLL_fx) )|| (GT_32(st_fx->enerLH_fx, L_shr(st_fx->prev_enerLH_fx, 1)) && LT_32(L_shr(st_fx->enerLH_fx, 1), st_fx->prev_enerLH_fx)))) + { + IF(GT_32(L_shr(prev_ener_ratio_fx, 2), GainFrame))/*18*/ + { + GainFrame = L_add(Mult_32_16(prev_ener_ratio_fx, 13107), Mult_32_16(GainFrame, 19661));/*18*/ + } + ELSE IF(GT_32(L_shr(prev_ener_ratio_fx, 1), GainFrame)) + { + GainFrame = L_add(Mult_32_16(prev_ener_ratio_fx, 26214), Mult_32_16(GainFrame, 6554)); + } + ELSE + { + GainFrame = L_add(Mult_32_16(prev_ener_ratio_fx, 6554), Mult_32_16(GainFrame, 26214)); + } + + test(); + IF(GT_16(tilt_swb_fec, hBWE_TD->tilt_swb_fec_fx)&& hBWE_TD->tilt_swb_fec_fx>0) + { + exp = norm_s(hBWE_TD->tilt_swb_fec_fx); + tmp = shl(hBWE_TD->tilt_swb_fec_fx, exp);/*Q(11+exp)*/ + tmp = div_s(16384, tmp);/*Q(15+14-11-exp)*/ + tmp = extract_h(L_shl(L_mult0(tmp, st_fx->tilt_wb_fx),sub(exp,1)));/*18 -exp +11 + exp -1 -16 =12; */ + GainFrame = L_shl(Mult_32_16(GainFrame, s_min(tmp, 20480)), 3); /*Q18 = 18 +12 -15 +3 */ + } + + } + ELSE IF( (NE_16(st_fx->clas_dec, UNVOICED_CLAS)||GT_16(hBWE_TD->tilt_swb_fec_fx,16384))&>_32(L_shr(prev_ener_ratio_fx,2),GainFrame)&& + (GT_32(st_fx->enerLL_fx, L_shr(st_fx->prev_enerLL_fx, 1)) || GT_32(st_fx->enerLH_fx, L_shr(st_fx->prev_enerLH_fx, 1)) ) ) + { + GainFrame = L_add(Mult_32_16(prev_ener_ratio_fx, 6554), Mult_32_16(GainFrame, 26214)); + } + } + ELSE IF( GT_16(st_fx->nbLostCmpt, 1)) + { + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF(GT_32(L_shr(prev_ener_ratio_fx, 2), GainFrame)&&((EQ_16(st_fx->codec_mode,MODE1)&>_32(st_fx->enerLL_fx,st_fx->prev_enerLL_fx)&>_32(st_fx->enerLH_fx,st_fx->prev_enerLH_fx))||EQ_16(st_fx->codec_mode,MODE2))) + { + test(); + IF( GT_16(tilt_swb_fec, 20480)&>_16(hBWE_TD->tilt_swb_fec_fx,20480)) + { + GainFrame = L_min(L_add(Mult_32_16(prev_ener_ratio_fx, 26214), Mult_32_16(GainFrame, 6554)), L_shl(Mult_32_16(GainFrame, 16384), 3)); /*Q18*/ + } + ELSE + { + GainFrame = L_min(L_add(Mult_32_16(prev_ener_ratio_fx, 16384), Mult_32_16(GainFrame, 16384)), L_shl(Mult_32_16(GainFrame, 16384), 3)); /*Q18*/ + } + } + ELSE IF(GT_32(prev_ener_ratio_fx, GainFrame)&&((EQ_16(st_fx->codec_mode,MODE1)&>_32(st_fx->enerLL_fx,st_fx->prev_enerLL_fx)&>_32(st_fx->enerLH_fx,st_fx->prev_enerLH_fx))||EQ_16(st_fx->codec_mode,MODE2))) + { + test(); + IF( GT_16(tilt_swb_fec, 20480)&>_16(hBWE_TD->tilt_swb_fec_fx,20480)) + { + GainFrame = L_add(Mult_32_16(prev_ener_ratio_fx, 16384), Mult_32_16(GainFrame, 16384)); + } + ELSE + { + GainFrame = L_add(Mult_32_16(prev_ener_ratio_fx, 6554), Mult_32_16(GainFrame, 26214)); + } + } + } + } + st_fx->prev_fractive_fx = is_fractive; + move16(); + + /* Adjust the subframe and frame gain of the synthesized shb signal */ + IF( EQ_16(st_fx->L_frame, L_FRAME)) + { + /* pitch = 0.25f*sum_s(pitch_buf, 4); */ + L_tmp = L_mult(pitch_buf[0], 8192); + FOR (i=1; itotal_brate, ACELP_24k40)&&EQ_16(st_fx->prev_coder_type_fx,coder_type)&&NE_16(coder_type,UNVOICED)) + || (LE_32(st_fx->total_brate, ACELP_16k40) && (EQ_16(st_fx->prev_coder_type_fx, coder_type) || (EQ_16(st_fx->prev_coder_type_fx, VOICED) && EQ_16(coder_type, GENERIC) ) || (EQ_16(st_fx->prev_coder_type_fx, GENERIC) && EQ_16(coder_type, VOICED) )))) + && GT_16(pitch_fx, 4480 /*70 in Q6*/) && LT_16(st_fx->extl, FB_TBE) ) + { + FOR(i=0; i st_fx->prev_ener_fx*st_fx->prev_GainShape_fx ) */ + L_tmp1 = Mult_32_16(ener_tmp[i], GainShape_tmp[i]); /* (2*Q_bwe_exc) */ + L_tmp2 = Mult_32_16(hBWE_TD->prev_ener_fx, hBWE_TD->prev_GainShape_fx); /* (2*st_fx->prev_ener_fx_Q) */ + tmp = sub(shl(Q_bwe_exc, 1), shl(st_fx->prev_ener_fx_Q, 1)); + L_tmp2 = L_shl(L_tmp2, tmp); /* new Q = (2*Q_bwe_exc) */ + + IF (GT_32(L_tmp1,L_tmp2)) + { + /*GainShape_tmp_fx[i] = 0.5f*(L_tmp2/ener_tmp_fx[i] + GainShape_tmp_fx[i]);*/ + /* tmp = L_tmp2/ener_tmp_fx[i]*/ + L_tmp = L_tmp2; + if(L_tmp2 < 0) + { + L_tmp = L_negate(L_tmp2); + } + + expb = norm_l(L_tmp); + fracb = round_fx(L_shl(L_tmp,expb)); + expb = 30-expb; /* - (2*Q_bwe_exc_ext); */ + + expa = norm_l(ener_tmp[i]); + fraca = extract_h(L_shl(ener_tmp[i],expa)); + expa = 30-expa ; + + scale = shr(sub(fraca,fracb),15); + fracb = shl(fracb,scale); + expb = sub(expb,scale); + + tmp = div_s(fracb,fraca); + exp = sub(sub(expb,expa),1); + tmp = shl(tmp,exp); + GainShape_tmp[i] = add(tmp,shr(GainShape_tmp[i],1));/* Q15 */ + } + + hBWE_TD->prev_ener_fx = ener_tmp[i]; + hBWE_TD->prev_GainShape_fx = GainShape_tmp[i]; + st_fx->prev_ener_fx_Q = Q_bwe_exc; + } + FOR(i=0; iprev_ener_fx_Q = Q_bwe_exc; + move16(); + } + + + /* Back up the Q_bwe_exc associated with shaped_shb_excitation for the next frame*/ + st_fx->prev_Q_bwe_syn = Q_bwe_exc; + move16(); + + /* Scale the shaped excitation */ + ScaleShapedSHB_fx( SHB_OVERLAP_LEN, + shaped_shb_excitation, /* i/o: Q_bwe_exc */ + hBWE_TD->syn_overlap_fx, + GainShape, /* Q15 */ + GainFrame, /* Q18 */ + window_shb_fx, + subwin_shb_fx, + &Q_bwe_exc + , &Qx + , n_mem3 + , st_fx->prev_Q_bwe_syn2 + ); + /* i: GainShape Q15 */ + /* i: GainFrame Q18 */ + /* i: shaped_shb_excitation Q_bwe_exc */ + /* o: shaped_shb_excitation Q_bwe_exc */ + /* o: st_fx->syn_overlap_fx Q_bwe_exc */ + + + max = 0; + FOR( i = 0; i < L_FRAME16k; i++ ) + { + max = s_max( max, shaped_shb_excitation[i] ); /* Q0 */ + } + + IF( max == 0 ) + { + curr_frame_pow = 0; + move16(); + n = 0; + move16(); + } + ELSE + { + n = norm_s( max ); + max = 0; + FOR( i = 0; i < L_FRAME16k; i++ ) + { +#ifdef BASOP_NOGLOB + shaped_shb_excitation_frac[i] = shl_sat( shaped_shb_excitation[i], n ); /*Q_bwe_exc+n*/ move16(); +#else + shaped_shb_excitation_frac[i] = shl( shaped_shb_excitation[i], n ); /*Q_bwe_exc+n*/ move16(); +#endif + } + + curr_frame_pow = 0; + FOR( i = 0; i < L_FRAME16k; i++ ) + { + L_tmp = L_mult0( shaped_shb_excitation_frac[i], shaped_shb_excitation_frac[i] ); /*2*(Q_bwe_exc+n)*/ + curr_frame_pow = L_add( curr_frame_pow, L_shr( L_tmp, 9 ) ); /*2*(Q_bwe_exc+n)-9*/ + } + } + curr_frame_pow_exp = sub(shl(add( Q_bwe_exc, n ), 1), 9); + + + tmp=sub( st_fx->prev_frame_pow_exp, curr_frame_pow_exp ); + IF( tmp > 0 ) /* shifting prev */ + { + IF (GT_16(tmp,32)) + { + st_fx->prev_frame_pow_exp = add(curr_frame_pow_exp,32); + tmp = 32; + } + hBWE_TD->prev_swb_bwe_frame_pow_fx = L_shr(hBWE_TD->prev_swb_bwe_frame_pow_fx, tmp); + st_fx->prev_frame_pow_exp = curr_frame_pow_exp; + move16(); + } + ELSE /* shifting curr */ + { + IF (LT_16(tmp,-32)) + { + curr_frame_pow_exp = sub(st_fx->prev_frame_pow_exp,32); + tmp = -32; + } + curr_frame_pow = L_shr(curr_frame_pow, -tmp); + curr_frame_pow_exp = st_fx->prev_frame_pow_exp; + } + test(); + IF( !st_fx->bfi && st_fx->prev_bfi ) + { + L_tmp = L_shr( curr_frame_pow, 4 ); + L_tmp = Mult_32_16( L_tmp, 17476 ); + + test(); + test(); + IF( ( GT_32( L_shr( curr_frame_pow, 1 ), hBWE_TD->prev_swb_bwe_frame_pow_fx ))&& + ( GT_32(hBWE_TD->prev_swb_bwe_frame_pow_fx, L_tmp ) ) && EQ_16(st_fx->prev_coder_type_fx,UNVOICED) ) + { + L_tmp = root_a_over_b_fx(hBWE_TD->prev_swb_bwe_frame_pow_fx, curr_frame_pow_exp, curr_frame_pow, curr_frame_pow_exp, &exp ); + scale = round_fx( L_shl( L_tmp, exp ) ); /*Q15*/ + + L_tmp = root_a_fx( L_tmp, 31 - exp, &exp ); + L_tmp = root_a_fx( L_tmp, 31 - exp, &exp ); + L_tmp = root_a_fx( L_tmp, 31 - exp, &exp ); + temp = round_fx( L_shl( L_tmp, exp ) ); /*Q15*/ + } + ELSE + { + scale = temp = 32767; + move16();/*Q15*/ + } + FOR( j = 0; j < 8; j++ ) + { + GainShape[2 * j] = mult_r( GainShape[2 * j], scale ); + move16(); + GainShape[2 * j + 1] = mult_r( GainShape[2 * j + 1], scale ); + move16(); + FOR( i = 0; i < L_FRAME16k / 8; i++ ) + { + shaped_shb_excitation[i + j*L_FRAME16k/8] = mult_r( shaped_shb_excitation[i + j*L_FRAME16k/8],scale ); + move16(); + } + + IF( temp > 0 ) + { + /* scale <= temp, due to scale = sqrt( st->prev_swb_bwe_frame_pow_fx/curr_frame_pow ), temp = sqrt( scale, 1.f/8.f ) + and curr_frame_pow > st->prev_swb_bwe_frame_pow_fx -> scale <= 1.0, sqrt(scale, 1.f/8.f) >= scale */ + IF( LT_16( scale, temp )) + { + scale = div_s( scale, temp ); + } + ELSE + { + scale = 32767; + move16(); + } + } + ELSE + { + scale = 0; + move16(); + } + } + } + + /* adjust the FEC frame energy */ + IF( st_fx->bfi ) + { + scale = temp = 4096; + move16();/*Q12*/ + + IF (EQ_16(st_fx->nbLostCmpt,1)) + { + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( GT_32(curr_frame_pow, hBWE_TD->prev_swb_bwe_frame_pow_fx)&& + NE_16(st_fx->prev_coder_type_fx, UNVOICED) && + NE_16(st_fx->last_good_fx,UNVOICED_CLAS) ) + { + L_tmp = root_a_over_b_fx(hBWE_TD->prev_swb_bwe_frame_pow_fx, curr_frame_pow_exp, curr_frame_pow, curr_frame_pow_exp, &exp ); /*31 - exp*/ + scale = round_fx( L_shl( L_tmp, sub(exp,3))); /*Q12*/ + L_tmp = root_a_fx( L_tmp, 31 - exp, &exp ); + L_tmp = root_a_fx( L_tmp, 31 - exp, &exp ); + L_tmp = root_a_fx( L_tmp, 31 - exp, &exp ); + temp = round_fx( L_shl( L_tmp, sub(exp,3))); /*Q12*/ + } + ELSE IF( LT_32(curr_frame_pow, L_shr(hBWE_TD->prev_swb_bwe_frame_pow_fx,1))&&EQ_16(st_fx->nbLostCmpt,1)&& + (GT_32(st_fx->enerLL_fx, L_shr( st_fx->prev_enerLL_fx,1)) || GT_32(st_fx->enerLH_fx, L_shr(st_fx->prev_enerLH_fx,1)) ) && + (EQ_16(st_fx->prev_coder_type_fx ,UNVOICED) || EQ_16(st_fx->last_good_fx, UNVOICED_CLAS) || GT_16(hBWE_TD->tilt_swb_fec_fx , 10240) )) + { + L_tmp = root_a_over_b_fx(hBWE_TD->prev_swb_bwe_frame_pow_fx, curr_frame_pow_exp, curr_frame_pow, curr_frame_pow_exp, &exp ); +#ifdef BASOP_NOGLOB + scale = round_fx_sat( L_shl_sat( L_tmp, sub(exp,3) ) ); /*Q12*/ +#else + scale = round_fx( L_shl( L_tmp, sub(exp,3) ) ); /*Q12*/ +#endif + L_tmp = root_a_fx( L_tmp, 31 - exp, &exp ); + L_tmp = root_a_fx( L_tmp, 31 - exp, &exp ); + L_tmp = root_a_fx( L_tmp, 31 - exp, &exp ); + temp = round_fx( L_shl( L_tmp, sub(exp,3) ) ); /*Q12*/ + } + } + ELSE IF (GT_16(st_fx->nbLostCmpt,1)) + { + test(); + test(); + test(); + test(); + test(); + IF( GT_32(curr_frame_pow , hBWE_TD->prev_swb_bwe_frame_pow_fx)) + { + L_tmp = root_a_over_b_fx(hBWE_TD->prev_swb_bwe_frame_pow_fx, curr_frame_pow_exp, curr_frame_pow, curr_frame_pow_exp, &exp ); + scale = round_fx( L_shl( L_tmp, sub(exp,3) ) ); /*Q12*/ + L_tmp = root_a_fx( L_tmp, 31 - exp, &exp ); + L_tmp = root_a_fx( L_tmp, 31 - exp, &exp ); + L_tmp = root_a_fx( L_tmp, 31 - exp, &exp ); +#ifdef BASOP_NOGLOB + temp = round_fx_sat( L_shl_sat( L_tmp, sub(exp,3) ) ); /*Q12*/ +#else + temp = round_fx( L_shl( L_tmp, sub(exp,3) ) ); /*Q12*/ +#endif + } + ELSE IF( LT_32(curr_frame_pow, L_shr(hBWE_TD->prev_swb_bwe_frame_pow_fx,1))&& + (GT_32(st_fx->enerLL_fx, L_shr( st_fx->prev_enerLL_fx,1)) || GT_32(st_fx->enerLH_fx, L_shr(st_fx->prev_enerLH_fx,1)) ) && + (st_fx->prev_coder_type_fx == UNVOICED || st_fx->last_good_fx == UNVOICED_CLAS || GT_16(hBWE_TD->tilt_swb_fec_fx , 10240)) ) + { + L_tmp = root_a_over_b_fx(hBWE_TD->prev_swb_bwe_frame_pow_fx, curr_frame_pow_exp, curr_frame_pow, curr_frame_pow_exp, &exp ); +#ifdef BASOP_NOGLOB + L_tmp =L_min(L_tmp,L_shl_sat(2,(31 - exp)));/*31 - exp*/ +#else + L_tmp =L_min(L_tmp,L_shl(2,(31 - exp)));/*31 - exp*/ +#endif + scale = round_fx( L_shl( L_tmp, sub(exp,3) )); /*Q12*/ + L_tmp = root_a_fx( L_tmp, 31 - exp, &exp ); + L_tmp = root_a_fx( L_tmp, 31 - exp, &exp ); + L_tmp = root_a_fx( L_tmp, 31 - exp, &exp ); + temp = round_fx( L_shl( L_tmp, sub(exp,3) ) ); /*Q12*/ + } + } + FOR( j = 0; j < 8; j++ ) + { +#ifdef BASOP_NOGLOB + GainShape[2 * j] = shl_sat(mult_r( GainShape[2 * j], scale ),3); +#else + GainShape[2 * j] = shl(mult_r( GainShape[2 * j], scale ),3); +#endif + move16(); /* 15 +12 +3-15 =15*/ +#ifdef BASOP_NOGLOB + GainShape[2 * j + 1] = shl_sat(mult_r( GainShape[2 * j + 1], scale ),3); +#else + GainShape[2 * j + 1] = shl(mult_r( GainShape[2 * j + 1], scale ),3); +#endif + move16(); + FOR( i = 0; i < 40; i++ ) + { + shaped_shb_excitation[add(i,i_mult(j,40))] = shl(mult_r( shaped_shb_excitation[add(i,i_mult(j,40))], scale) ,3); + move16(); /* Q_bwe_exc +12+3 -15 =Q_bwe_exc*/ + } + + IF( temp > 0 ) + { + IF( LT_16( scale, temp )) + { + scale = shr(div_s( scale, temp ),3); + } + ELSE + { + tmp1 = sub(norm_s(scale), 1); + tmp2 = norm_s(temp); + scale = div_s( shl(scale, tmp1), shl(temp, tmp2) ); + scale = shr(scale, add(sub(tmp1, tmp2), 3)); + } + } + ELSE + { + scale = 0; + move16(); + } + } + } + + hBWE_TD->prev_swb_bwe_frame_pow_fx = curr_frame_pow; + move32(); + st_fx->prev_frame_pow_exp = curr_frame_pow_exp; + move16(); + + + { + Word64 prev_ener_shb64 = 0; + move64(); + FOR( i = 0; i < L_FRAME16k; i++ ) + { + prev_ener_shb64 = W_mac0_16_16( prev_ener_shb64, shaped_shb_excitation[i], shaped_shb_excitation[i] ); /* Q0 */ + } + L_prev_ener_shb = W_sat_l(prev_ener_shb64); + } + + + /* st->prev_ener_shb = sqrt(st->prev_ener_shb/L_FRAME16k) */ + L_prev_ener_shb = Mult_32_16( L_prev_ener_shb, 26214 ); /* 2*Q_bwe_exc_mod+8; 26214=(1/L_FRAME16k) in Q23 */ + st_fx->prev_ener_shb_fx = 0; + move16(); + + IF( L_prev_ener_shb != 0 ) + { + exp = norm_l( L_prev_ener_shb ); + tmp = extract_h( L_shl( L_prev_ener_shb, exp ) ); + exp = sub( exp, 30 - ( 2 * Q_bwe_exc + 8 ) ); + + tmp = div_s( 16384, tmp ); + L_tmp = L_deposit_h( tmp ); + L_tmp = Isqrt_lc( L_tmp, &exp ); + st_fx->prev_ener_shb_fx = round_fx( L_shl( L_tmp, sub( exp, 14 ) ) ); /* Q1 */ + } + /* st->prev_SWB_fenv[i] = sqrt(curr_frame_pow/L_FRAME16k); */ + L_tmp = Mult_32_16( curr_frame_pow, 26214 ); /* curr_frame_pow_exp+8; 26214=(1/L_FRAME16k) in Q23 */ + tmp =0; + IF( L_tmp != 0 ) + { + exp = norm_l( L_tmp ); + tmp = extract_h( L_shl( L_tmp, exp ) ); + exp = sub( exp, 30 - ( curr_frame_pow_exp + 8 ) ); + + tmp = div_s( 16384, tmp ); + L_tmp = L_deposit_h( tmp ); + L_tmp = Isqrt_lc( L_tmp, &exp ); + tmp = round_fx( L_shl( L_tmp, sub( exp, 14 ) ) ); /* Q1 */ + } + set16_fx(st_fx->prev_SWB_fenv_fx, tmp, SWB_FENV); /* Q1 */ + + + /* rescale the memories if Q_bwe_exc is different from previous frame */ + sc = sub( Q_bwe_exc, st_fx->prev_Q_bwe_syn2 ); + IF( sc != 0 ) + { + FOR( i = 0; i < 2*ALLPASSSECTIONS_STEEP; i++ ) + { + hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx[i] = shl(hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx[i], sc ); + move16(); + } + + IF(EQ_16(st_fx->L_frame, L_FRAME)) + { + FOR( i = 0; i < HILBERT_MEM_SIZE; i++ ) + { + hBWE_TD->genSHBsynth_Hilbert_Mem_fx[i] = L_shl(hBWE_TD->genSHBsynth_Hilbert_Mem_fx[i], sc ); + move32(); + } + } + IF( st_fx->output_Fs == 48000 ) + { + Scale_sig(hBWE_TD->int_3_over_2_tbemem_dec_fx, INTERP_3_2_MEM_LEN, sc); + } + IF( st_fx->output_Fs == 16000 ) + { + Scale_sig(hBWE_TD->mem_resamp_HB_32k_fx, 2*ALLPASSSECTIONS_STEEP + 1, sc); + } + } + /* i: shaped_shb_excitation[320] in (Q_bwe_exc) */ + /* i/o: st_fx->genSHBsynth_Hilbert_Mem_fx in (Q_bwe_exc) */ + /* i/o: st_fx->genSHBsynth_state_lsyn_filt_shb_local_fx in (Q_bwe_exc) */ + /* o: error in (Qx) */ + GenSHBSynth_fx( shaped_shb_excitation, error, hBWE_TD->genSHBsynth_Hilbert_Mem_fx, + hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx, st_fx->L_frame, &(hBWE_TD->syn_dm_phase_fx ) ); + + Copy( error + L_FRAME32k - L_SHB_TRANSITION_LENGTH, hBWE_TD->old_tbe_synth_fx, L_SHB_TRANSITION_LENGTH ); + + /* resample SHB synthesis (if needed) and scale down */ + synth_scale_fx = 32767; + move16(); /* 1.0 in Q15 */ + if(EQ_16(st_fx->codec_mode,MODE1)) + { + synth_scale_fx = 29491; + move16(); /* 0.9 in Q15 */ + } + + IF( EQ_32(st_fx->output_Fs, 48000)) + { + IF( EQ_32(st_fx->extl,FB_TBE)) + { + tmp = norm_l( GainFrame ); + if(GainFrame == 0) + { + tmp = 31; + } + L_tmp = L_shl(GainFrame,tmp);/* 18 + tmp */ + + tmp1 =0; + FOR( i = 0; i < L_FRAME16k; i++ ) + { + L_tmp1 = Mult_32_16( L_tmp, GainShape[NUM_SHB_SUBFR * i / L_FRAME16k] ); /* Q : 18 + tmp +15 -15*/ + White_exc16k[i] = round_fx( Mult_32_16( L_tmp1, White_exc16k[i] ) );/* 18 + tmp +*Q_white_exc -15 -16 */ + tmp1 = s_max(tmp1,abs_s(White_exc16k[i])); + } + + *Q_white_exc = sub(add(*Q_white_exc, tmp),13); /* *Q_white_exc + 18 + tmp -15 -16 */ + tmp = norm_s( tmp1 ); + if(tmp1 == 0) + { + tmp = 15; + } + + FOR(i=0; iint_3_over_2_tbemem_dec_fx, allpass_poles_3_ov_2 ); + } + ELSE IF( EQ_32(st_fx->output_Fs, 32000)) + { + IF( NE_16(synth_scale_fx,32767)) /* 1.0 in Q15 */ + { + FOR( i = 0; i < L_FRAME32k; i++ ) + { + synth[i] = mult_r( synth_scale_fx, error[i] ); + move16();/*Qx*/ + } + } + ELSE + { + Copy(error, synth, L_FRAME32k); + } + } + ELSE IF( EQ_32(st_fx->output_Fs, 16000)) + { + IF( NE_16(synth_scale_fx,32767)) /* 1.0 in Q15 */ + { + FOR( i = 0; i < L_FRAME32k; i++ ) + { + error[i] = mult_r(error[i],synth_scale_fx); + move16(); + } + } + + Decimate_allpass_steep_fx( error, hBWE_TD->mem_resamp_HB_32k_fx, L_FRAME32k, synth ); + } + + /* Update previous frame parameters for FEC */ + Copy( lsf_shb, hBWE_TD->lsp_prevfrm_fx, LPC_SHB_ORDER ); + IF(EQ_16(st_fx->codec_mode, MODE1)) + { + hBWE_TD->GainFrame_prevfrm_fx = GainFrame; + move16(); /*Q18*/ + hBWE_TD->tilt_swb_fec_fx = tilt_swb_fec; + + if( !st_fx->bfi ) + { + hBWE_TD->GainAttn_fx = 32767; + move16(); + } + } + ELSE + { + IF( !st_fx->bfi ) + { + hBWE_TD->GainFrame_prevfrm_fx = GainFrame; + move16(); /*Q18*/ + hBWE_TD->tilt_swb_fec_fx = tilt_swb_fec; + move16(); + hBWE_TD->GainAttn_fx = 32767; + move16(); + } + } + + hBWE_TD->prev_ener_fx = ener_tmp[NUM_SHB_SUBGAINS-1]; + hBWE_TD->prev_GainShape_fx = GainShape[NUM_SHB_SUBFR-1]; + *Q_synth = Q_bwe_exc; + move16(); + st_fx->prev_Q_bwe_syn2 = Q_bwe_exc; + move16(); + st_fx->prev_Qx = Q_bwe_exc; + move16(); + return; +} + +static void gradientGainShape( + Decoder_State *st_fx, + Word16 *GainShape, + Word32 *GainFrame) +{ + Word16 i,j,tmp; + Word16 GainShapeTemp[NUM_SHB_SUBFR/4]; + Word16 GainGrad0[3]; + Word16 GainGrad1[3]; + Word16 GainGradFEC[4]; + TD_BWE_DEC_HANDLE hBWE_TD; + hBWE_TD = st_fx->hBWE_TD; + + /* the previous frame gainshape gradient and the gainshape gradient pattern for the current frame */ + FOR( j = 0; j < 3; j++ ) + { + GainGrad0[j] = sub( shr( st_fx->GainShape_Delay[j + 1], 1 ), shr( st_fx->GainShape_Delay[j], 1 ) ); + move16();/* Q14 */ + GainGrad1[j] = sub( shr( st_fx->GainShape_Delay[j + 5], 1 ), shr( st_fx->GainShape_Delay[j + 4], 1 ) ); + move16();/* Q14 */ + GainGradFEC[j + 1] = add( mult_r( GainGrad0[j], 13107 ), mult_r( GainGrad1[j], 19660 ) ); + move16(); /* Q14 */ + } + + /* gradient for the first gainshape */ + test(); + test(); + test(); + IF( ( ( GT_16( shr( GainGrad1[2], 1 ), GainGrad1[1] ))&&(GT_16(shr(GainGrad1[1],1),GainGrad1[0])))|| + ( ( LT_16( shr( GainGrad1[2], 1 ), GainGrad1[1] ) ) && ( LT_16( shr( GainGrad1[1], 1 ), GainGrad1[0] ) ) ) ) + { + GainGradFEC[0] = add( mult_r( GainGrad1[1], 3277 ), mult_r( GainGrad1[2], 29490 ) ); + move16(); /* Q14 */ + } + ELSE + { + GainGradFEC[0] = add( mult_r( GainGrad1[0], 6553 ), mult_r( GainGrad1[1], 9830 ) ); + move16(); + GainGradFEC[0] = add( GainGradFEC[0], mult_r( GainGrad1[2], 16384 ) ); + move16(); /* Q14 */ + } + + /* get the first gainshape template */ + test(); + test(); + IF( ( st_fx->prev_coder_type_fx == UNVOICED || st_fx->last_good_fx == UNVOICED_CLAS ) && GainGradFEC[0] > 0 ) + { + GainShapeTemp[0] = add( shr( st_fx->GainShape_Delay[7], 1 ), GainGradFEC[0] ); + move16(); + } + ELSE IF( GainGradFEC[0] > 0 ) + { + GainShapeTemp[0] = add( shr( st_fx->GainShape_Delay[7], 1 ), mult_r( GainGradFEC[0], 16384 ) ); + move16(); /* Q14 */ + } + ELSE + { + GainShapeTemp[0] = shr( st_fx->GainShape_Delay[7], 1 ); + move16();/* Q14 */ + } + + /*Get the second the third and the fourth gainshape template*/ + + tmp = shr( GainGrad1[2], 3 ); /* GainGrad1[2]/8 */ + tmp = mult_r( tmp, 26214 ); /* 0.8 in Q15 tmp*(8/10) */ + + test(); + IF( ( GT_16( tmp, GainGrad1[1] ))&&GainGrad1[1]>0) + { + FOR( i = 1; i < NUM_SHB_SUBFR / 4; i++ ) + { + GainShapeTemp[i] = add( GainShapeTemp[i - 1], mult_r( GainGradFEC[i], 26214 ) ); + move16(); /* GainShapeTemp[i-1] + 0.8* GainShapeTemp[i] */ + GainShapeTemp[i] = s_max( GainShapeTemp[i], 328/*0.01f Q15*/ ); + move16(); + } + } + ELSE + { + test(); + IF( ( GT_16( tmp, GainGrad1[1] ))&&GainGrad1[1]<0) + { + FOR( i = 1; i < NUM_SHB_SUBFR / 4; i++ ) + { + GainShapeTemp[i] = add( GainShapeTemp[i - 1], mult_r( GainGradFEC[i], 6553 ) ); + move16(); /* GainShapeTemp[i-1] + 0.8* GainShapeTemp[i] */ + GainShapeTemp[i] = s_max( GainShapeTemp[i], 328/*0.01f Q15*/ ); + move16(); /* Q14 */ + } + } + ELSE + { + FOR( i = 1; i < NUM_SHB_SUBFR / 4; i++ ) + { + GainShapeTemp[i] = add( GainShapeTemp[i - 1], GainGradFEC[i] ); + move16(); + GainShapeTemp[i] = s_max( GainShapeTemp[i], 328/*0.01f Q15*/ ); + move16(); + } + } + } + + /* Get the gainshape and gain frame for the current frame*/ + test(); + test(); + test(); + IF( ( st_fx->prev_coder_type_fx == UNVOICED || st_fx->last_good_fx == UNVOICED_CLAS ) && st_fx->nbLostCmpt == 1 ) + { + FOR( i = 0; i < NUM_SHB_SUBFR / 4; i++ ) + { + FOR( j = 0; j < 4; j++ ) + { + tmp = mult_r( GainShapeTemp[i], 19660 ); /* GainShapeTemp[i]*0.6 */ + + IF( GT_16( 8192, tmp )) + { + GainShape[i * 4 + j ] = shl( tmp, 2 ); + move16(); /* (GainShapeTemp[i]*0.6)>>1 */ + } + ELSE + { + GainShape[i * 4 + j ] = 32767; + move16(); /* Clipping here to avoid the a huge change of the code due to gain shape change */ + } + } + } + hBWE_TD->GainAttn_fx = mult_r(hBWE_TD->GainAttn_fx, 31129 ); + } + ELSE IF( st_fx->prev_coder_type_fx == UNVOICED || st_fx->last_good_fx == UNVOICED_CLAS ) + { + FOR( i = 0; i < NUM_SHB_SUBFR / 4; i++ ) + { + FOR( j = 0; j < 4; j++ ) + { + IF( LT_16( GainShapeTemp[i], 16384 )) + { + GainShape[i * 4 + j ] = shl( GainShapeTemp[i], 1 ); + move16(); + } + ELSE + { + GainShape[i * 4 + j ] = 32767 ; + move16(); + } + } + } + hBWE_TD->GainAttn_fx = mult_r(hBWE_TD->GainAttn_fx, 31129 ); + } + ELSE IF( st_fx->nbLostCmpt > 1 ) + { + FOR( i = 0; i < NUM_SHB_SUBFR / 4; i++ ) + { + FOR( j = 0; j < 4; j++ ) + { + GainShape[i * 4 + j ] = GainShapeTemp[i]; + move16(); + } + } + hBWE_TD->GainAttn_fx = mult_r(hBWE_TD->GainAttn_fx, 16384 ); + } + ELSE + { + FOR( i = 0; i < NUM_SHB_SUBFR / 4; i++ ) + { + FOR( j = 0; j < 4; j++ ) + { + IF( LT_16( GainShapeTemp[i], 16384 )) + { + GainShape[i * 4 + j] = shl( GainShapeTemp[i], 1 ); + move16(); + } + ELSE + { + GainShape[i * 4 + j] = 32767; + move16(); + } + } + } + hBWE_TD->GainAttn_fx = mult_r(hBWE_TD->GainAttn_fx, 27852 ); + } + + *GainFrame = Mult_32_16(hBWE_TD->GainFrame_prevfrm_fx, hBWE_TD->GainAttn_fx ); /* Q18 */ +} + +/*-------------------------------------------------------------------* + * Dequant_lower_LSF() + * + * Dequantized the lower LSFs + *-------------------------------------------------------------------*/ + + +static void Dequant_lower_LSF_fx( + const Word16 lsf_idx[], /* i : LSF indices */ + Word16 lsf_q[] /* o : Quantized LSFs */ +) +{ + Word16 i; + + lsf_q[0] = lsf_q_cb_fx[0][lsf_idx[0]]; + move16(); + FOR( i = 1; i < NUM_Q_LSF; i++ ) + { + lsf_q[i] = add( lsf_q_cb_fx[i][lsf_idx[i]], lsf_q[i - 1] ); + move16(); + } + + return; +} + +/*-------------------------------------------------------------------* + * Map_higher_LSF() + * + * Map the higher LSFs from the lower LSFs + *-------------------------------------------------------------------*/ + +static void Map_higher_LSF_fx( + Word16 lsf_q[], /* i/o : Quantized lower LSFs */ + const Word16 m, /* i : Mirroring point */ + const Word16 grid_in[] /* i : Input LSF smoohthing grid */ ) +{ + Word16 lsf_map[NUM_MAP_LSF]; + Word16 grid[NUM_MAP_LSF]; + Word16 last_q_lsf; + Word16 lsf_smooth[NUM_MAP_LSF]; + Word16 offset; + Word16 i; + Word16 scale; + + FOR( i = 0; i < NUM_MAP_LSF; i++ ) + { + lsf_map[i] = sub( shl( m, 1 ), lsf_q[NUM_MAP_LSF - 1 - i] ); + move16(); + } + + IF( GT_16( m, MAX_LSF_FX_BY_2 )) + { + offset = lsf_map[0]; + move16(); + scale = div_s( sub( MAX_LSF_FX, m ), m ); + FOR( i = 0; i < NUM_MAP_LSF; i++ ) + { + lsf_map[i] = add( mult_r( sub( lsf_map[i], offset ), scale ), offset ); + move16(); + } + } + + last_q_lsf = lsf_q[NUM_Q_LSF - 1]; + move16(); + scale = sub( MAX_LSF_FX, last_q_lsf ); + + FOR( i = 0; i < NUM_MAP_LSF; i++ ) + { + grid[i] = add( mult_r( grid_in[i], scale ), last_q_lsf ); + move16(); + } + + FOR( i = 0; i < NUM_MAP_LSF; i++ ) + { + lsf_smooth[i] = sub( mult_r( grid_smoothing_fx[i], grid[i] ), + mult_r( lsf_map[i], add( grid_smoothing_fx[i], -32768/*-1.0f Q15*/ ) ) ); + move16(); + } + + FOR( i = 0; i < NUM_MAP_LSF; i++ ) + { + lsf_q[NUM_Q_LSF + i] = lsf_smooth[i]; + move16(); + } + + return; +} + + + + +static void Dequant_mirror_point_fx( + const Word16 lsf_q[], /* i/o : Quantized lower LSFs */ + const Word16 m_idx, /* i : Mirror point index */ Word16* m /* i : Mirroring point */ ) +{ + *m = add( mirror_point_q_cb_fx[m_idx], lsf_q[NUM_Q_LSF - 1] ); + move16(); + + return; +} + + +/*==========================================================================*/ +/* FUNCTION : static void dequantizeSHBparams_fx_9_1 () */ +/*--------------------------------------------------------------------------*/ +/* PURPOSE : Dequantize super highband spectral envolope */ +/* temporal gains and frame gain */ +/*--------------------------------------------------------------------------*/ +/* INPUT ARGUMENTS : */ +/* _Word16 extl i : extension layer */ +/* _Word32 extl_brate i : extensiuon layer bitrate */ +/*--------------------------------------------------------------------------*/ +/* OUTPUT ARGUMENTS : */ +/* _Word16 *Q_lsf, o : SHB LSF from de-quantization Q15 */ +/* _Word16 *Q_subgain, o : SHB subframe gains from de-quantization Q15*/ +/* _Word32 *Q_framegrain o : SHB frame gain from de-quantization Q18 */ +/*--------------------------------------------------------------------------*/ +/* INPUT/OUTPUT ARGUMENTS : */ +/*--------------------------------------------------------------------------*/ +/* RETURN ARGUMENTS : */ +/* _ None */ +/*--------------------------------------------------------------------------*/ +/* CALLED FROM : */ +/*==========================================================================*/ +static void dequantizeSHBparams_fx_9_1( + Decoder_State* st_fx, + const Word16 extl, /* i : extension layer */ + Word32 extl_brate, /* i : extensiuon layer bitrate */ + Word16* Q_lsf, /* o : SHB LSF from de-quantization Q15*/ + Word16* Q_subgain, /* o : SHB subframe gains from de-quantization Q15*/ + Word32* Q_framegrain, /* o : SHB frame gain from de-quantization Q18*/ + Word16* uv_flag, /* o : unvoiced flag*/ + Word32* Q_shb_ener_sf, /* o : Q15 */ + Word16* Q_shb_res_gshape, /* o : Q14 */ + Word16* Q_mixFactors /* o : Q15 */ +) +{ + Word16 i, j, idxLSF, idxSubGain, idxFrameGain; + Word16 Q_combined_gains[NUM_SHB_SUBFR/4]; + Word16 lsf_q[LPC_SHB_ORDER]; + Word16 lsf_idx[NUM_Q_LSF]; + Word16 m_idx, grid_idx; + Word16 m; + Word32 L_tmp; + Word16 tmp, frac, exp; + Word16 idx_shb_fr_gain, idx_res_gs[5], idx_mixFac; + Word16 temp_shb_ener_sf_fx; + TD_BWE_DEC_HANDLE hBWE_TD; + hBWE_TD = st_fx->hBWE_TD; + + /* LSFs */ + + IF( EQ_16( extl, WB_TBE )) + { + IF( EQ_32( extl_brate, WB_TBE_0k35 )) + { + idxFrameGain = hBWE_TD->gFrame_WB_fx; + idxLSF = hBWE_TD->lsf_WB_fx; + + Copy( lbr_wb_bwe_lsfvq_cbook_2bit_fx + idxLSF * LPC_SHB_ORDER_LBR_WB, Q_lsf, LPC_SHB_ORDER_LBR_WB ); + set16_fx( Q_subgain, RECIP_ROOT_EIGHT_FX, NUM_SHB_SUBFR / 2 ); + Copy32( SHBCB_FrameGain16_fx + idxFrameGain, Q_framegrain, 1 ); + } + ELSE + { + *uv_flag = ( Word16 )get_next_indice( st_fx, 1 ); + idxSubGain = ( Word16 )get_next_indice( st_fx, NUM_BITS_SHB_SUBGAINS ); + move16(); + idxFrameGain = ( Word16 )get_next_indice( st_fx, NUM_BITS_SHB_FrameGain ); + move16(); + idxLSF = ( Word16 )get_next_indice( st_fx, NUM_BITS_WB_LSF ); + move16(); + Copy( wb_bwe_lsfvq_cbook_8bit_fx + idxLSF * LPC_SHB_ORDER_WB, Q_lsf, LPC_SHB_ORDER_WB ); + Copy( HBCB_SubGain5bit_fx + idxSubGain * NUM_SHB_SUBFR / 4, Q_combined_gains, NUM_SHB_SUBFR / 4 ); + + FOR( i = 0; i < NUM_SHB_SUBFR / 4; i++ ) + { + + L_tmp = L_mult( Q_combined_gains[i], 21771 ); /*Q26 0.166096 in Q17 */ + L_tmp = L_shr( L_tmp, 10 ); + frac = L_Extract_lc( L_tmp, &exp ); + tmp = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */ + /* output of Pow2() will be: */ + /* 16384 < Pow2() <= 32767 */ + Q_combined_gains[i] = shl( tmp, add( exp, 1 ) ); /* Q15 */ + } + + FOR( i=0; i < NUM_SHB_SUBFR / 2; i+= 2) + { + Q_subgain[i] = Q_combined_gains[i / 2]; + move16(); + Q_subgain[i + 1] = Q_combined_gains[i / 2]; + move16(); + } + + /* frame gain */ + Copy32( SHBCB_FrameGain64_fx + idxFrameGain, Q_framegrain, 1 ); + } + } + ELSE /* SWB TBE DEC */ + { + IF(EQ_16(st_fx->codec_mode,MODE2)) + { + idxSubGain = hBWE_TD->idxSubGains_fx; + idxFrameGain = hBWE_TD->idxFrameGain_fx; + } + ELSE + { + idxSubGain = ( Word16 )get_next_indice( st_fx, NUM_BITS_SHB_SUBGAINS ); + idxFrameGain = ( Word16 )get_next_indice( st_fx, NUM_BITS_SHB_FRAMEGAIN ); + } + + test(); + IF( EQ_32(st_fx->total_brate, ACELP_24k40)||EQ_32(st_fx->total_brate,ACELP_32k)) + { + IF(EQ_16(st_fx->codec_mode,MODE2)) + { + idx_shb_fr_gain = hBWE_TD->idx_shb_fr_gain_fx; + } + ELSE + { + idx_shb_fr_gain = get_next_indice( st_fx, NUM_BITS_SHB_ENER_SF ); + } + temp_shb_ener_sf_fx = usdequant_fx(idx_shb_fr_gain, 0, 86); /* 86 = 0.042f in Q11 = Qin-1 */ + /* o: temp_shb_ener_sf_fx in Q12 */ + + /* *Q_shb_ener_sf = Pow(10.0, temp_shb_ener_sf_fx ); */ + /* = pow(2, 3.321928*temp_shb_ener_sf_fx) */ + L_tmp = L_mult(temp_shb_ener_sf_fx, 27213 ); /* 3.321928 in Q13 -> L_tmp in Q12+Q13+1 = Q26 */ + L_tmp = L_shl( L_tmp, -10 ); /* bring L_tmp from Q26 to Q16 */ + frac = L_Extract_lc( L_tmp, &exp ); /* Extract exponent */ + L_tmp = Pow2(14, frac ); + *Q_shb_ener_sf = L_shl(L_tmp, exp-14+0 ); /* In Q_ener: 2*Q_shb+1, Q_shb = 0; */ + + FOR(i=0; i<5; i++) + { + IF(EQ_16(st_fx->codec_mode,MODE2)) + { + idx_res_gs[i] = hBWE_TD->idx_res_gs_fx[i]; + move16(); + } + ELSE + { + idx_res_gs[i] = get_next_indice( st_fx, NUM_BITS_SHB_RES_GS ); + move16(); + } + Q_shb_res_gshape[i] = usdequant_fx(idx_res_gs[i], + 2048/*0.125f Q14*/, /*2048 = 0.125 in Q14 */ + 1024/*0.125f Q13*/ /*1024 = 0.125 in Q13 */ + ); + move16(); + /* o: Q_shb_res_gshape in Q14 */ + } + + IF(EQ_16(st_fx->codec_mode,MODE2)) + { + idx_mixFac = hBWE_TD->idx_mixFac_fx; + move16(); + } + ELSE + { + idx_mixFac = (Word16)get_next_indice( st_fx, NUM_BITS_SHB_VF ); + } + *Q_mixFactors = usdequant_fx(idx_mixFac, 4096 /* 0.125 in Q15 */, 2048 /* 0.125 in Q14 */); + move16(); + /* o: Q_mixFactors in Q15 */ + } + ELSE + { + *Q_shb_ener_sf = L_deposit_l(0); + *Q_mixFactors = 0; + move16(); + set16_fx(Q_shb_res_gshape, 0, 5); + } + + /* LSFs */ + + + test(); + test(); + test(); + test(); + test(); + IF( (st_fx->rf_flag == 0) && !((EQ_32(st_fx->total_brate, ACELP_9k60))||((st_fx->total_brate==0)&&((EQ_32(st_fx->last_total_brate,ACELP_9k60))||(EQ_32(st_fx->last_total_brate,ACELP_13k20)&&EQ_16(st_fx->rf_flag_last,1)))))) + + { + /* LSFs */ + test(); + test(); + test(); + IF ( EQ_32(extl_brate, SWB_TBE_1k6)||EQ_32(extl_brate,FB_TBE_1k8)||EQ_32(extl_brate,SWB_TBE_2k8)||EQ_32(extl_brate,FB_TBE_3k0)) + { + IF(EQ_16(st_fx->codec_mode,MODE2)) + { + FOR (i = 0; i < NUM_Q_LSF; i++) + { + lsf_idx[i] = hBWE_TD->lsf_idx_fx[i]; + move16(); + + } + } + ELSE + { + FOR (i = 0; i < NUM_Q_LSF; i++) + { + lsf_idx[i] = (Word16)get_next_indice(st_fx, lsf_q_num_bits[i]); + move16(); + } + } + } + Dequant_lower_LSF_fx( lsf_idx, lsf_q ); + + IF(EQ_16(st_fx->codec_mode,MODE2)) + { + m_idx = hBWE_TD->m_idx_fx; + } + ELSE + { + m_idx = (Word16)get_next_indice( st_fx, MIRROR_POINT_BITS ); + move16(); + } + + Dequant_mirror_point_fx( lsf_q, m_idx, &m ); + + /* safety check in case of bit errors */ + IF(GT_16(m, MAX_LSF_FX)) + { + st_fx->BER_detect = 1; + m = MAX_LSF_FX-1; + } + + IF(EQ_16(st_fx->codec_mode,MODE2)) + { + grid_idx = hBWE_TD->grid_idx_fx; + } + ELSE + { + grid_idx = (Word16)get_next_indice( st_fx, NUM_LSF_GRID_BITS ); + move16(); + } + + Map_higher_LSF_fx( lsf_q, m, lsf_grid_fx[grid_idx] ); + + FOR (i = 0; i < LPC_SHB_ORDER; i++) + { + /* safety check in case of bit errors */ + IF(GT_16(lsf_q[LPC_SHB_ORDER - 1 - i], MAX_LSF_FX)) + { + st_fx->BER_detect = 1; + lsf_q[LPC_SHB_ORDER - 1 - i] = MAX_LSF_FX - 1; + } + Q_lsf[i] = sub( 16384, lsf_q[LPC_SHB_ORDER - 1 - i] ); + move16(); + } + } + ELSE + { + set16_fx(lsf_idx, 0, 5); + Copy(hBWE_TD->lsf_idx_fx, lsf_idx, 5); + grid_idx = 0; + m_idx = 0; + Copy(swb_tbe_lsfvq_cbook_8b + lsf_idx[0]*LPC_SHB_ORDER, Q_lsf, LPC_SHB_ORDER); + } + + space_lsfs_fx( Q_lsf, LPC_SHB_ORDER ); + + /* Dequantize subgain indices */ + j = idxSubGain * NUM_SHB_SUBGAINS; + move16(); + FOR( i = 0; i < NUM_SHB_SUBGAINS; i++ ) + { + /* Q_subgain[i] = (float) pow(10.0, SHBCB_SubGain5bit[j++]); */ + + L_tmp = L_mult( SHBCB_SubGain5bit_fx[j++], 27213 ); /*Q28 3.321928 in Q13 */ + L_tmp = L_shr( L_tmp, 12 ); + frac = L_Extract_lc( L_tmp, &exp ); + tmp = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */ + /* output of Pow2() will be: */ + /* 16384 < Pow2() <= 32767 */ + Q_subgain[i] = shl( tmp, add( exp, 1 ) ); /*Q15*/ move16(); + } + + FOR( i = NUM_SHB_SUBFR - 1; i >= 0; i-- ) + { + Q_subgain[i] = Q_subgain[i * NUM_SHB_SUBGAINS / NUM_SHB_SUBFR]; + move16(); + } + + /* Frame gain */ + *Q_framegrain = L_mac( SHB_GAIN_QLOW_FX, idxFrameGain, SHB_GAIN_QDELTA_FX ); + move32();/*Q18*/ + L_tmp = Mult_32_16( *Q_framegrain, 27213 ); /*Q16*/ /* 3.321928 in Q13 */ + frac = L_Extract_lc( L_tmp, &exp ); + L_tmp = Pow2( 30, frac ); + *Q_framegrain = L_shl( L_tmp, sub( exp, 12 ) ); /*Q18*/ + } + + return; +} + +/*-------------------------------------------------------------------* + * fb_tbe_dec() + * + * FB TBE decoder, 14(resp. 15.5) - 20 kHz band decoding module + *-------------------------------------------------------------------*/ +void fb_tbe_dec_fx( + Decoder_State *st, /* i/o: encoder state structure */ + const Word16 fb_exc[], /* i : FB excitation from the SWB part */ + Word16 Q_fb_exc, + Word16 *hb_synth, /* o : high-band synthesis */ + Word16 hb_synth_exp +) + +{ + Word16 i; + Word16 ratio = 0; + Word32 fb_exc_energy = 0; + Word16 fb_synth[L_FRAME48k]; + TD_BWE_DEC_HANDLE hBWE_TD; + hBWE_TD = st->hBWE_TD; + + /* decode FB slope information */ + test(); + test(); + IF ( EQ_16(st->extl,FB_TBE)&&!st->bfi) + { + IF( EQ_16(st->codec_mode,MODE2)) + { + i = hBWE_TD->idxGain_fx; + move16(); + } + ELSE + { + i = (Word16)get_next_indice( st, 4 ); + } +#ifdef BASOP_NOGLOB + ratio = shl_sat(1,i); +#else + ratio = shl(1,i); +#endif + } + ELSE if ( EQ_16(st->extl,FB_TBE)&&st->bfi) + { + ratio = hBWE_TD->prev_fbbwe_ratio_fx; + move16(); + } + fb_exc_energy = sum2_fx_mod(fb_exc,L_FRAME16k); + + /* FB TBE synthesis */ + synthesise_fb_high_band_fx( fb_exc,Q_fb_exc,fb_synth,fb_exc_energy,ratio, st->L_frame, st->bfi, &(hBWE_TD->prev_fbbwe_ratio_fx), hBWE_TD->fbbwe_hpf_mem_fx, hBWE_TD->fbbwe_hpf_mem_fx_Q,hb_synth_exp); + + /* add the fb_synth component to the hb_synth component */ + /* v_add_fx( hb_synth, fb_synth, hb_synth, L_FRAME48k );*/ + FOR (i=0; ihBWE_TD; + + test(); + test(); + test(); + test(); + test(); + IF ( (EQ_16(st_fx->rf_flag,1)||EQ_32(st_fx->total_brate,ACELP_9k60))&&EQ_16(st_fx->bwidth,WB)) + { + /* WB LSF */ + hBWE_TD->lsf_WB_fx = get_next_indice(st_fx, NUM_BITS_LBR_WB_LSF); + + /* WB frame gain */ + hBWE_TD->gFrame_WB_fx = get_next_indice(st_fx, NUM_BITS_SHB_FrameGain_LBR_WB); + } + ELSE IF ( ( GE_32( st_fx->total_brate, ACELP_9k60 ))&&(LE_32(st_fx->total_brate,ACELP_32k))&& + ( ( EQ_16( st_fx->bwidth, SWB ) ) || ( EQ_16( st_fx->bwidth, FB ) ) ) ) + { + test(); + IF( (st_fx->rf_flag == 0) && (GT_32(st_fx->total_brate, ACELP_9k60))) + { + FOR (i = 0; i < NUM_Q_LSF; i++) + { + hBWE_TD->lsf_idx_fx[i] = get_next_indice(st_fx, lsf_q_num_bits[i]); + move16(); + } + + hBWE_TD->m_idx_fx = get_next_indice(st_fx, MIRROR_POINT_BITS); + + hBWE_TD->grid_idx_fx = get_next_indice(st_fx, NUM_LSF_GRID_BITS); + + } + ELSE + { + hBWE_TD->lsf_idx_fx[0] = get_next_indice(st_fx, 8); + move16(); + hBWE_TD->m_idx_fx = 0; + move16(); + hBWE_TD->grid_idx_fx = 0; + move16(); + } + + /* shape gains */ + hBWE_TD->idxSubGains_fx = get_next_indice(st_fx, NUM_BITS_SHB_SUBGAINS); + + /* frame gain */ + hBWE_TD->idxFrameGain_fx = get_next_indice(st_fx, NUM_BITS_SHB_FRAMEGAIN); + + IF ( GE_32( st_fx->total_brate, ACELP_24k40 )) + { + /* sub frame energy*/ + hBWE_TD->idx_shb_fr_gain_fx = get_next_indice(st_fx, NUM_BITS_SHB_ENER_SF); + + /* gain shapes residual */ + FOR (i = 0; i < NB_SUBFR16k; i++) + { + hBWE_TD->idx_res_gs_fx[i] = get_next_indice(st_fx, NUM_BITS_SHB_RES_GS); + move16(); + } + + /* voicing factor */ + hBWE_TD->idx_mixFac_fx = get_next_indice(st_fx, NUM_BITS_SHB_VF); + } + + IF (EQ_16(st_fx->tec_tfa, 1)) + { + st_fx->tec_flag = get_next_indice(st_fx, BITS_TEC); + st_fx->tfa_flag = get_next_indice(st_fx, BITS_TFA); + test(); + IF (st_fx->tfa_flag && st_fx->tec_flag) + { + st_fx->tec_flag = 2; + move16(); + st_fx->tfa_flag = 0; + move16(); + } + } + ELSE + { + st_fx->tec_flag = 0; + move16(); + st_fx->tfa_flag = 0; + move16(); + } + } + + IF ( EQ_16( st_fx->bwidth, FB )) + { + hBWE_TD->idxGain_fx = get_next_indice(st_fx, 4); + } +} + + +/*---------------------------------------------------------------------* +* GenTransition() +* +* Generate a highband transition signal from the gain shape overlap +* buffer to fill the gap caused by the delay alignment buffer when +* switching from TBE to IGF +*---------------------------------------------------------------------*/ +void GenTransition_fx( + const Word16 *input, /* i : gain shape overlap buffer */ + const Word16 *old_hb_synth, /* i : synthesized HB from previous frame */ + Word16 length, /* i : targeted length of transition signal */ + Word16 *output, /* o : synthesized transitions signal */ + Word32 Hilbert_Mem[], /* i/o: memory */ + Word16 state_lsyn_filt_shb_local[],/* i/o: memory */ + Word16 mem_resamp_HB_32k[], /* i/o: memory */ + Word16 *syn_dm_phase, + Word32 target_fs, + Word16 *up_mem, + Word16 rf_flag + , Word32 bitrate +) +{ + Word16 i; + Word16 syn_overlap_32k[L_FRAME32k]; + Word32 L_tmp; + Word16 ol_len = 2*SHB_OVERLAP_LEN; + + /* upsample overlap snippet */ + Interpolate_allpass_steep_fx( input, state_lsyn_filt_shb_local, SHB_OVERLAP_LEN, syn_overlap_32k ); + + /* perform spectral flip and downmix with overlap snippet to match HB synth */ + test(); + IF( (rf_flag != 0) || EQ_32( bitrate, ACELP_9k60 )) + { + flip_and_downmix_generic_fx( syn_overlap_32k, syn_overlap_32k, 2*SHB_OVERLAP_LEN, Hilbert_Mem, + Hilbert_Mem + HILBERT_ORDER1, Hilbert_Mem + (HILBERT_ORDER1+2*HILBERT_ORDER2), + syn_dm_phase ); + } + ELSE + { + FOR(i = 0; i < ol_len; i=i+2) + { + syn_overlap_32k[i] = negate(syn_overlap_32k[i]); + move16(); + syn_overlap_32k[i+1] = syn_overlap_32k[i+1]; + move16(); + } + } + + /* cross fade of overlap snippet and mirrored HB synth from previous frame */ + FOR ( i = 0; i < ol_len; i++ ) + { + L_tmp = L_mult( window_shb_32k_fx[i], old_hb_synth[L_SHB_TRANSITION_LENGTH-1-i] ); + output[i] = mac_r( L_tmp, window_shb_32k_fx[2*L_SHB_LAHEAD-1-i], syn_overlap_32k[i] ); + } + + /* fill transition signal with mirrored HB synth from previous frame to fully fill delay alignment buffer gap */ + FOR ( ; i < length; i++) + { + output[i] = old_hb_synth[L_SHB_TRANSITION_LENGTH-1-i]; + } + + IF ( EQ_32( target_fs, 48000 )) + { + interpolate_3_over_2_allpass_fx( output, length, output, up_mem, allpass_poles_3_ov_2 ); + } + ELSE IF( EQ_32( target_fs, 16000 )) + { + Decimate_allpass_steep_fx( output, mem_resamp_HB_32k, L_FRAME32k, output ); + } + + return; +} + + +/*---------------------------------------------------------------------* + * GenTransition_WB_fx() + * + *---------------------------------------------------------------------*/ + +void GenTransition_WB_fx( + const Word16 *input, /* i : gain shape overlap buffer */ + const Word16 *old_hb_synth, /* i : synthesized HB from previous frame */ + const Word16 prev_Qx, /* i : scaling of old_hb_synth */ + Word16 length, /* i : targeted length of transition signal */ + Word16 *output, /* o : synthesized transitions signal */ + Word16 state_lsyn_filt_shb1[], + Word16 state_lsyn_filt_shb2[], + Word32 output_Fs, + Word16 *up_mem +) +{ + Word16 i; + Word32 L_tmp; + Word16 speech_buf_16k1[L_FRAME16k], speech_buf_16k2[L_FRAME16k]; + Word16 upsampled_synth[L_FRAME48k]; + Word16 input_scaled[SHB_OVERLAP_LEN/2]; + + /* upsample overlap snippet */ + Copy_Scale_sig(input, input_scaled, SHB_OVERLAP_LEN/2, prev_Qx); + Interpolate_allpass_steep_fx( input_scaled, state_lsyn_filt_shb1, SHB_OVERLAP_LEN/2, speech_buf_16k1); + Interpolate_allpass_steep_fx( speech_buf_16k1, state_lsyn_filt_shb2, SHB_OVERLAP_LEN, speech_buf_16k2); + + + /* perform spectral flip and downmix with overlap snippet to match HB synth */ + FOR(i = 0; i < SHB_OVERLAP_LEN; i+=2) + { + speech_buf_16k2[i] = negate(speech_buf_16k2[i]); + speech_buf_16k2[i+1] = speech_buf_16k2[i+1]; + } + + /* cross fade of overlap snippet and mirrored HB synth from previous frame */ + FOR (i=0; ihBWE_TD; + + IF( NE_16(st_fx->last_core,ACELP_CORE)) + { + set16_fx(hBWE_TD->old_bwe_exc_fx, 0, PIT16k_MAX * 2 ); + hBWE_TD->bwe_non_lin_prev_scale_fx = L_deposit_l(0); + st_fx->prev_Q_bwe_exc = 31; + move16(); + } + + test(); + IF( EQ_16(bandwidth, WB)) + { + wb_tbe_extras_reset_fx(hBWE_TD->mem_genSHBexc_filt_down_wb2_fx, hBWE_TD->mem_genSHBexc_filt_down_wb3_fx ); + wb_tbe_extras_reset_synth_fx(hBWE_TD->state_lsyn_filt_shb_fx, hBWE_TD->state_lsyn_filt_dwn_shb_fx, hBWE_TD->state_32and48k_WB_upsample_fx, hBWE_TD->mem_resamp_HB_fx ); + + set16_fx(hBWE_TD->mem_genSHBexc_filt_down_shb_fx, 0, 7 ); + set16_fx(hBWE_TD->state_lpc_syn_fx, 0, 10 ); + set16_fx(hBWE_TD->state_syn_shbexc_fx, 0, L_SHB_LAHEAD/4 ); + set16_fx(hBWE_TD->syn_overlap_fx, 0, L_SHB_LAHEAD ); + set32_fx(hBWE_TD->mem_csfilt_fx, 0, 2 ); + } + ELSE IF( EQ_16(bandwidth, SWB)||EQ_16(bandwidth,FB)) + { + swb_tbe_reset_fx(hBWE_TD->mem_csfilt_fx, hBWE_TD->mem_genSHBexc_filt_down_shb_fx, hBWE_TD->state_lpc_syn_fx, + hBWE_TD->syn_overlap_fx, hBWE_TD->state_syn_shbexc_fx, &(hBWE_TD->tbe_demph_fx), + &(hBWE_TD->tbe_premph_fx), hBWE_TD->mem_stp_swb_fx, &(hBWE_TD->gain_prec_swb_fx) ); + + swb_tbe_reset_synth_fx(hBWE_TD->genSHBsynth_Hilbert_Mem_fx, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx ); + + set16_fx( st_fx->GainShape_Delay, 0, NUM_SHB_SUBFR/2 ); + set16_fx(hBWE_TD->int_3_over_2_tbemem_dec_fx, 0, INTERP_3_2_MEM_LEN); + set16_fx(hBWE_TD->mem_resamp_HB_32k_fx, 0, 2*ALLPASSSECTIONS_STEEP+1 ); + + IF( EQ_16(bandwidth, FB)) + { + st_fx->prev_fb_ener_adjust_fx = 0; + set16_fx(hBWE_TD->fb_state_lpc_syn_fx, 0, LPC_SHB_ORDER ); + hBWE_TD->fb_tbe_demph_fx = 0; + fb_tbe_reset_synth_fx(hBWE_TD->fbbwe_hpf_mem_fx, hBWE_TD->fbbwe_hpf_mem_fx_Q,&hBWE_TD->prev_fbbwe_ratio_fx ); + } + } + + return; +} + + +/*-------------------------------------------------------------------* + * td_bwe_dec_init() + * + * Initialize TD BWE state structure at the decoder + *-------------------------------------------------------------------*/ + +void td_bwe_dec_init_fx( + Decoder_State* st_fx, /* i/o: SHB decoder structure */ + TD_BWE_DEC_HANDLE hBWE_TD, /* i/o: TD BWE data handle */ +#ifdef ADD_IVAS_BWE + const Word16 extl, /* i : BWE extension layer */ +#endif + const Word32 output_Fs /* i : output sampling rate */ +) +{ + int16_t i; + + /* init. SHB buffers */; + InitSWBdecBuffer_fx(st_fx); + + /* reset SHB buffers */ + ResetSHBbuffer_Dec_fx(st_fx); + IF(EQ_32(output_Fs, 48000)) + { + set32_fx(hBWE_TD->fbbwe_hpf_mem_fx[0], 0, 4); + set32_fx(hBWE_TD->fbbwe_hpf_mem_fx[1], 0, 4); + set32_fx(hBWE_TD->fbbwe_hpf_mem_fx[2], 0, 4); + set32_fx(hBWE_TD->fbbwe_hpf_mem_fx[3], 0, 4); + set16_fx(hBWE_TD->fbbwe_hpf_mem_fx_Q, 0, 4); + } + + set16_fx(hBWE_TD->mem_resamp_HB_fx, 0, INTERP_3_1_MEM_LEN); + set16_fx(hBWE_TD->mem_resamp_HB_32k_fx, 0, 2 * ALLPASSSECTIONS_STEEP + 1); + + hBWE_TD->tilt_mem_fx = 0; + move16(); + set16_fx(hBWE_TD->prev_lsf_diff_fx, 16384, LPC_SHB_ORDER - 2); + hBWE_TD->prev_tilt_para_fx = 0; + move16(); + set16_fx(hBWE_TD->cur_sub_Aq_fx, 0, M + 1); + set16_fx(hBWE_TD->int_3_over_2_tbemem_dec_fx, 0, INTERP_3_2_MEM_LEN); + + /* TD BWE post-processing */ + hBWE_TD->ptr_mem_stp_swb_fx = hBWE_TD->mem_stp_swb_fx + LPC_SHB_ORDER - 1; + set16_fx(hBWE_TD->mem_zero_swb_fx, 0, LPC_SHB_ORDER); + + FOR(i = 0; i < LPC_SHB_ORDER; i++) + { + hBWE_TD->swb_lsp_prev_interp_fx[i] = swb_lsp_prev_interp_init[i]; + move16(); + } + + hBWE_TD->prev1_shb_ener_sf_fx = 32767; /* Q15*/ move16(); + hBWE_TD->prev2_shb_ener_sf_fx = 32767; /* Q15*/ move16(); + hBWE_TD->prev3_shb_ener_sf_fx = 32767; /* Q15*/ move16(); + hBWE_TD->prev_res_shb_gshape_fx = 8192; /* 0.125 in Q14*/ move16(); + hBWE_TD->prev_mixFactors_fx = 16384; /* 0.5 in Q15*/ move16(); + hBWE_TD->prev_GainShape_fx = 0; + move16(); + st_fx->prev_Q_bwe_exc_fb = 51; + move16(); + set16_fx(hBWE_TD->fb_state_lpc_syn_fx, 0, LPC_SHB_ORDER); + hBWE_TD->fb_tbe_demph_fx = 0; + move16(); + + + + set16_fx(hBWE_TD->old_hb_synth_fx, 0, L_FRAME48k); + + + hBWE_TD->prev_ener_fx = L_deposit_l(0); + + + return; +} diff --git a/lib_dec/syn_outp_fx.c b/lib_dec/syn_outp_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..ec5cc6bcd6edd03e0c7853dd2a56bc096c53e8eb --- /dev/null +++ b/lib_dec/syn_outp_fx.c @@ -0,0 +1,124 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include +#include "options.h" /* Compilation switches */ +#include "cnst.h" /* Common constants */ +#include "prot_fx1.h" /* Debug prototypes */ +#include "prot_fx2.h" /* Debug prototypes */ + +/*-------------------------------------------------------------------* + * syn_output() + * + * Output synthesis signal with compensation for saturation + *-------------------------------------------------------------------*/ + +void syn_output_fx( + const Word16 codec_mode, /* i : MODE1 or MODE2 */ + Word16 *synth, /* i/o: float synthesis signal */ + const Word16 output_frame, /* i : output frame length */ + Word16 *synth_out, /* o : integer 16 bits synthesis signal */ + const Word16 Q_syn2 /* i : Synthesis scaling factor */ +) +{ + Word16 i, tmp; + Word32 L_tmp; + + /*tmp = sub(Q_syn2, 1); */ + tmp = Q_syn2; + + /*-----------------------------------------------------------------* + * Output synthesis signal with compensation for saturation + *-----------------------------------------------------------------*/ + + test(); + IF( EQ_16(codec_mode, MODE2) || EQ_16(output_frame,L_FRAME8k)) + { + /* integer conversion */ + /*mvr2s( synth, synth_out, output_frame ); */ + FOR (i = 0; i < output_frame; i++) + { + L_tmp = L_deposit_h(synth[i]); + synth_out[i] = round_fx(L_shr(L_tmp, tmp)); + } + } + ELSE + { + Copy_Scale_sig( synth, synth_out, output_frame, negate(tmp) ); + } + + return; +} +/*-------------------------------------------------------------------* + * Local function + * unscale_AGC + * + * Output synthesis signal with compensation for saturation + *-------------------------------------------------------------------*/ +void unscale_AGC( + const Word16 x[], /* i: 16kHz synthesis Qx */ + const Word16 Qx, /* i: scale factor of x */ + Word16 y[], /* o: output vector Q0 */ + Word16 mem[], /* i/o: mem[2] should be init to [0,0] */ + const Word16 n /* i: vector size */ +) +{ + Word16 i, fac, tmp, frame_fac, max_val; + Word32 L_tmp; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + + /*----------------------------------------------------------------* + * calculate AGC factor to avoid saturation + *----------------------------------------------------------------*/ + + max_val = abs_s(x[0]); + FOR (i = 1; i < n; i++) + { + max_val = s_max(max_val, abs_s(x[i])); + } + BASOP_SATURATE_WARNING_OFF_EVS +#ifdef BASOP_NOGLOB + tmp = shl_o(30000, Qx, &Overflow); /* saturation can occur here */ +#else + tmp = shl(30000, Qx); /* saturation can occurs here */ +#endif + BASOP_SATURATE_WARNING_ON_EVS + frame_fac = 0; + move16(); + IF (GT_16(max_val, tmp)) + { + frame_fac = sub(16384, div_s(shr(tmp, 1), max_val)); /* frame fac in Q15 */ + } + + /*----------------------------------------------------------------* + * AGC + *----------------------------------------------------------------*/ + /* update AGC factor (slowly) */ + fac = mac_r(L_mult(32440, mem[0]), 328, frame_fac); + + L_tmp = L_mult(x[0], 16384); + L_tmp = L_msu0(L_tmp, fac, x[0]); + L_tmp = L_msu(L_tmp, fac, mem[1]); + L_tmp = L_shr(L_tmp, -1); /* saturation can occur here */ + + y[0] = round_fx(L_tmp); + + FOR (i = 1; i < n; i++) + { + /* update AGC factor (slowly) */ + fac = mac_r(L_mult(32440, fac), 328, frame_fac); + + L_tmp = L_deposit_h(x[i]); + L_tmp = L_msu(L_tmp, fac, x[i]); + L_tmp = L_msu(L_tmp, fac, x[i-1]); + y[i] = round_fx(L_tmp); + } + + mem[0] = fac; + move16(); + mem[1] = shr(x[sub(i, 1)], 1); + move16(); +} diff --git a/lib_dec/tcq_core_dec.c b/lib_dec/tcq_core_dec.c index 6e0e649839816497b5e1a7e8f4142af2c4ee214a..af5d0f23aeec9e82db15510561bbccdd0c79e515 100644 --- a/lib_dec/tcq_core_dec.c +++ b/lib_dec/tcq_core_dec.c @@ -121,7 +121,7 @@ void tcq_core_LR_dec( /* Bits distribution analysis*/ for ( i = 0; i < BANDS; i++ ) { - if ( L_sub( ar_div( Rk_fx[i], band_width[i] ), 49152 ) >= 0 ) + if ( L_sub( ar_div_ivas( Rk_fx[i], band_width[i] ), 49152 ) >= 0 ) { /* USQ used for high importance bands*/ USQ_TCQ[i] = 1; @@ -155,21 +155,21 @@ void tcq_core_LR_dec( { if ( Rk_fx[j] > 0 ) { - Rk_fx[j] = L_sub( Rk_fx[j], ar_div( bsub_fx, nzb ) ); + Rk_fx[j] = L_sub( Rk_fx[j], ar_div_ivas( bsub_fx, nzb ) ); if ( Rk_fx[j] < 0 ) { - bsub_fx = L_sub( bsub_fx, L_add( ar_div( bsub_fx, nzb ), Rk_fx[j] ) ); + bsub_fx = L_sub( bsub_fx, L_add( ar_div_ivas( bsub_fx, nzb ), Rk_fx[j] ) ); Rk_fx[j] = 0; } else { - bsub_fx = L_sub( bsub_fx, ar_div( bsub_fx, nzb ) ); + bsub_fx = L_sub( bsub_fx, ar_div_ivas( bsub_fx, nzb ) ); } nzb = sub( nzb, 1 ); } } - srt_vec_ind_fx( Rk_fx, Rk_sort_fx, k_sort, BANDS ); + srt_vec_ind_fx_ivas( Rk_fx, Rk_sort_fx, k_sort, BANDS ); #undef WMC_TOOL_SKIP /*read the bits*/ @@ -254,13 +254,13 @@ void tcq_core_LR_dec( else { /*get number of pulses */ - pulsesnum = GetScale_fx( band_width[k_sort[k]], L_add( Rk_fx[k_sort[k]], delta_fx ), &surplus_fx ); + pulsesnum = GetScale_fx_ivas( band_width[k_sort[k]], L_add( Rk_fx[k_sort[k]], delta_fx ), &surplus_fx ); leftbits = L_sub( leftbits, L_add( Rk_fx[k_sort[k]], delta_fx ) ); - decode_position_ari_fx( pardec, band_width[k_sort[k]], pulsesnum, &nz, &positions[band_start[k_sort[k]]] ); - decode_mangitude_tcq_fx( pardec, band_width[k_sort[k]], pulsesnum, nz, &positions[band_start[k_sort[k]]], &inp_vector[band_start[k_sort[k]]], &surplus_fx ); - decode_signs_fx( pardec, band_width[k_sort[k]], &inp_vector[band_start[k_sort[k]]] ); + decode_position_ari_fx_ivas( pardec, band_width[k_sort[k]], pulsesnum, &nz, &positions[band_start[k_sort[k]]] ); + decode_mangitude_tcq_fx_ivas( pardec, band_width[k_sort[k]], pulsesnum, nz, &positions[band_start[k_sort[k]]], &inp_vector[band_start[k_sort[k]]], &surplus_fx ); + decode_signs_fx_ivas( pardec, band_width[k_sort[k]], &inp_vector[band_start[k_sort[k]]] ); } nzbands--; } @@ -289,13 +289,13 @@ void tcq_core_LR_dec( else { - pulsesnum = GetScale_fx( band_width[k_sort[k]], L_add( Rk_fx[k_sort[k]], delta_fx ), &surplus_fx ); + pulsesnum = GetScale_fx_ivas( band_width[k_sort[k]], L_add( Rk_fx[k_sort[k]], delta_fx ), &surplus_fx ); leftbits = L_sub( leftbits, L_add( Rk_fx[k_sort[k]], delta_fx ) ); - decode_position_ari_fx( pardec, band_width[k_sort[k]], pulsesnum, &nz, &positions[band_start[k_sort[k]]] ); - decode_magnitude_usq_fx( pardec, band_width[k_sort[k]], pulsesnum, nz, &positions[band_start[k_sort[k]]], &inp_vector[band_start[k_sort[k]]] ); - decode_signs_fx( pardec, band_width[k_sort[k]], &inp_vector[band_start[k_sort[k]]] ); + decode_position_ari_fx_ivas( pardec, band_width[k_sort[k]], pulsesnum, &nz, &positions[band_start[k_sort[k]]] ); + decode_magnitude_usq_fx_ivas( pardec, band_width[k_sort[k]], pulsesnum, nz, &positions[band_start[k_sort[k]]], &inp_vector[band_start[k_sort[k]]] ); + decode_signs_fx_ivas( pardec, band_width[k_sort[k]], &inp_vector[band_start[k_sort[k]]] ); } nzbands--; } @@ -322,10 +322,10 @@ void tcq_core_LR_dec( divider = 2; } - IF( L_add( L_add( surplus_fx, sepbits ), ar_div( leftbits, divider ) ) < 0 ) + IF( L_add( L_add( surplus_fx, sepbits ), ar_div_ivas( leftbits, divider ) ) < 0 ) { /* Overflow possible => start to distribute negative surplus */ - delta_fx = ar_div( surplus_fx + sepbits, nzbands ); + delta_fx = ar_div_ivas( surplus_fx + sepbits, nzbands ); } else { @@ -366,21 +366,21 @@ void tcq_core_LR_dec( if ( Rk_fx[k_sort[k]] > 0 && USQ_TCQ[k_sort[k]] == 0 ) { /* get number of pulses */ - pulsesnum = GetScale_fx( band_width[k_sort[k]], Rk_fx[k_sort[k]], &surplus_fx ); + pulsesnum = GetScale_fx_ivas( band_width[k_sort[k]], Rk_fx[k_sort[k]], &surplus_fx ); - decode_position_ari_fx( pardec, band_width[k_sort[k]], pulsesnum, &nz, &positions[band_start[k_sort[k]]] ); + decode_position_ari_fx_ivas( pardec, band_width[k_sort[k]], pulsesnum, &nz, &positions[band_start[k_sort[k]]] ); /* decode tcq magniitude and update the surplus bits. */ - decode_mangitude_tcq_fx( pardec, band_width[k_sort[k]], pulsesnum, nz, &positions[band_start[k_sort[k]]], &inp_vector[band_start[k_sort[k]]], &surplus_fx ); - decode_signs_fx( pardec, band_width[k_sort[k]], &inp_vector[band_start[k_sort[k]]] ); + decode_mangitude_tcq_fx_ivas( pardec, band_width[k_sort[k]], pulsesnum, nz, &positions[band_start[k_sort[k]]], &inp_vector[band_start[k_sort[k]]], &surplus_fx ); + decode_signs_fx_ivas( pardec, band_width[k_sort[k]], &inp_vector[band_start[k_sort[k]]] ); } else if ( Rk_fx[k_sort[k]] > 0 && USQ_TCQ[k_sort[k]] == 1 ) { - pulsesnum = GetScale_fx( band_width[k_sort[k]], Rk_fx[k_sort[k]], &surplus_fx ); + pulsesnum = GetScale_fx_ivas( band_width[k_sort[k]], Rk_fx[k_sort[k]], &surplus_fx ); - decode_position_ari_fx( pardec, band_width[k_sort[k]], pulsesnum, &nz, &positions[band_start[k_sort[k]]] ); + decode_position_ari_fx_ivas( pardec, band_width[k_sort[k]], pulsesnum, &nz, &positions[band_start[k_sort[k]]] ); /* decode usq magnitude and don't need to update surplus bits */ - decode_magnitude_usq_fx( pardec, band_width[k_sort[k]], pulsesnum, nz, &positions[band_start[k_sort[k]]], &inp_vector[band_start[k_sort[k]]] ); - decode_signs_fx( pardec, band_width[k_sort[k]], &inp_vector[band_start[k_sort[k]]] ); + decode_magnitude_usq_fx_ivas( pardec, band_width[k_sort[k]], pulsesnum, nz, &positions[band_start[k_sort[k]]], &inp_vector[band_start[k_sort[k]]] ); + decode_signs_fx_ivas( pardec, band_width[k_sort[k]], &inp_vector[band_start[k_sort[k]]] ); } else { @@ -401,13 +401,13 @@ void tcq_core_LR_dec( { if ( Rk_fx[k_sort[k]] > 0 ) { - pulsesnum = GetScale_fx( band_width[k_sort[k]], Rk_fx[k_sort[k]] + delta_fx, &surplus_fx ); + pulsesnum = GetScale_fx_ivas( band_width[k_sort[k]], Rk_fx[k_sort[k]] + delta_fx, &surplus_fx ); - decode_position_ari_fx( pardec, band_width[k_sort[k]], pulsesnum, &nz, &positions[band_start[k_sort[k]]] ); + decode_position_ari_fx_ivas( pardec, band_width[k_sort[k]], pulsesnum, &nz, &positions[band_start[k_sort[k]]] ); /*decode usq magnitude and don't need to update surplus bits*/ - decode_magnitude_usq_fx( pardec, band_width[k_sort[k]], pulsesnum, nz, &positions[band_start[k_sort[k]]], &inp_vector[band_start[k_sort[k]]] ); - decode_signs_fx( pardec, band_width[k_sort[k]], &inp_vector[band_start[k_sort[k]]] ); + decode_magnitude_usq_fx_ivas( pardec, band_width[k_sort[k]], pulsesnum, nz, &positions[band_start[k_sort[k]]], &inp_vector[band_start[k_sort[k]]] ); + decode_signs_fx_ivas( pardec, band_width[k_sort[k]], &inp_vector[band_start[k_sort[k]]] ); #define WMC_TOOL_SKIP nzbands = sub( nzbands, 1 ); @@ -427,7 +427,7 @@ void tcq_core_LR_dec( /* surplus distribution */ if ( surplus_fx > 0 && nzbands > 0 ) { - delta_fx = ar_div( surplus_fx, nzbands ); + delta_fx = ar_div_ivas( surplus_fx, nzbands ); surplus_fx = L_sub( surplus_fx, delta_fx ); } } diff --git a/lib_dec/tcq_core_dec_fx.c b/lib_dec/tcq_core_dec_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..e2acd38825116d5098098bfbb5c0de4b5340bf99 --- /dev/null +++ b/lib_dec/tcq_core_dec_fx.c @@ -0,0 +1,481 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ +#include +#include +#include "options.h" /* Compilation switches */ +#include "cnst.h" /* Common constants */ +#include "rom_com.h" /* Static table prototypes */ +#include "prot_fx1.h" +#include "prot_fx2.h" +/*---------------------------------------------------------------------* + * tcq_core_LR_dec() + * + * Main Generic Audio Decoder Routine for LR-MDCT + *---------------------------------------------------------------------*/ + +void tcq_core_LR_dec_fx( + Decoder_State *st_fx, + Word16 *inp_vector_fx, /* x5 */ + const Word16 bit_budget, + const Word16 BANDS, + const Word16 *band_start, + const Word16 *band_width, + Word32 *Rk_fx, /* Q16 */ + Word16 *npulses, + Word16 *k_sort, + const Word16 *p2a_flags, + const Word16 p2a_bands, + const Word16 *last_bitalloc, + const Word16 input_frame, + const Word16 adjustFlag, + const Word16 *is_transient +) +{ + Word16 i, j, k; + Word32 Rk_sort_fx[NB_SFM]; + Word16 flag_wbnb = 0; + Word16 USQ_TCQ[NB_SFM]; /* TCQ is selected by default*/ + Word16 nb_bytes, pulsesnum, nz; + + Word16 positions_fx[L_FRAME48k]; + Word32 surplus_fx, delta_fx; + Word16 k_num[2]; + Word32 bit_surplus_fx[2]; + ARCODEC ardec_fx, *pardec_fx; + TCQ_BITSTREAM bs_fx, *pbs_fx; + + Word16 nzb = 0; + Word16 nzbands = 0; + Word16 lsbtcq_bits = TCQ_AMP; + Word16 tcq_arbits = 2; + + /* LSB TCQ variables*/ + Word16 dpath[280]; + Word16 bcount = 0; + Word32 bsub_fx = 0; + Word16 mbuffer_fx[560]; + + Word32 leftbits = 0; + Word32 sepbits = 0; + Word32 divider = 0; + +#ifndef BASOP_NOGLOB_DECLARE_LOCAL + if (Overflow == 1) + { + Overflow = 0; /* set overflow flag to zero before entering TCQ functions without any message */ + } +#endif + + /* initialization */ + set16_fx(dpath, 0, 280); + set16_fx( USQ_TCQ, 0, NB_SFM ); + set16_fx(positions_fx, 0, L_FRAME32k); + set16_fx(mbuffer_fx, 0, 560); + + test(); + test(); + IF ( LE_16(input_frame, L_FRAME16k)&&adjustFlag==0&&*is_transient==0) + { + flag_wbnb = 1; + move16(); + lsbtcq_bits = 0; + move16(); + tcq_arbits = 0; + move16(); + } + + pardec_fx = &ardec_fx; + pbs_fx = &bs_fx; + pbs_fx->curPos = 7; + move16(); + pbs_fx->numbits = L_deposit_l(0); + pbs_fx->numByte = L_deposit_l(0); + + /* Bits distribution analysis*/ + FOR ( i = 0; i < BANDS; i++ ) + { + IF (GE_32(ar_div(Rk_fx[i], band_width[i]), 49152)) + { + /* USQ used for high importance bands*/ + USQ_TCQ[i] = 1; + move16(); + } + ELSE + { + /* TCQ used for usual bands*/ + USQ_TCQ[i] = 0; + move16(); + } + if ( Rk_fx[i] > 0 ) + { + nzbands = add(nzbands, 1); + } + } + + FOR ( j = 0; j < BANDS; j++ ) + { + if ( Rk_fx[j] > 0 ) + { + nzb = add(nzb, 1); + } + } + + bsub_fx = L_shl(L_add(tcq_arbits, lsbtcq_bits), 16); + if( bsub_fx > 0) + { + bsub_fx = L_add( bsub_fx, 2048); + } + FOR ( j = BANDS - 1; j >= 0; j-- ) + { + IF ( Rk_fx[j] > 0 ) + { + Rk_fx[j] = L_sub(Rk_fx[j], ar_div(bsub_fx, nzb)); + IF ( Rk_fx[j] < 0) + { + bsub_fx = L_sub(bsub_fx, L_add(ar_div(bsub_fx, nzb), Rk_fx[j])); + Rk_fx[j] = L_deposit_l(0); + } + ELSE + { + bsub_fx = L_sub(bsub_fx, ar_div(bsub_fx, nzb)); + } + nzb = sub(nzb, 1); + } + } + + srt_vec_ind_fx(Rk_fx, Rk_sort_fx, k_sort, BANDS); + + /*read the bits*/ + nb_bytes = shr(bit_budget, 3); + k = sub(bit_budget, shl(nb_bytes, 3)); + FOR ( i = 0; i < nb_bytes; i++ ) + { + pbs_fx->buf[i] = (UWord8)get_next_indice(st_fx, 8); + move16(); + } + + IF ( k > 0 ) + { + Word16 tmp; + tmp = (UWord8)get_next_indice(st_fx, k); + pbs_fx->buf[nb_bytes] = (UWord8)shl(tmp,sub(8,k)); + /* i++; + nb_bytes++; */ + i = add(i, 1); + nb_bytes = add(nb_bytes, 1); + } + /* set two more bytes, which are used to flush the arithmetic coder, to 0 + -> this avoids reading of uninitialized memory */ + nb_bytes = s_min(add(nb_bytes, 2), MAX_SIZEBUF_PBITSTREAM); + FOR ( ; i < nb_bytes; i++ ) + { + pbs_fx->buf[i] = 0; + move16(); + } + + pbs_fx->maxBytes = nb_bytes; + move16(); + + ar_decoder_start_fx(pardec_fx, pbs_fx); + + delta_fx = L_deposit_l(0); + surplus_fx = L_deposit_l(0); + + test(); + test(); + IF( LE_16(input_frame, L_FRAME16k)&&adjustFlag==0&&*is_transient==0) + { + surplus_fx = -131072; + move32();/*16 */ + + bit_allocation_second_fx(Rk_fx, Rk_sort_fx, BANDS, band_width, k_sort, k_num, p2a_flags, p2a_bands, last_bitalloc, input_frame); + + nzbands = 0; + move16(); + FOR ( j = 0; j < BANDS; j++ ) + { + IF( EQ_16(j, k_num[0])||EQ_16(j,k_num[1])) + { + sepbits = L_add( sepbits, Rk_fx[k_sort[j]]); + } + ELSE + { + leftbits = L_add( leftbits, Rk_fx[k_sort[j]]); + if( Rk_fx[k_sort[j]] > 0 ) + { + nzbands = add(nzbands, 1); + } + } + } + + FOR( k = 0; k < BANDS; k++ ) + { + test(); + IF( NE_16(k, k_num[0])&&NE_16(k,k_num[1])) + { + test(); + test(); + IF (Rk_fx[k_sort[k]] > 0 && USQ_TCQ[k_sort[k]] == 0) + { + /* When number of bits per band is less than + arithmetic bits overhead, this band is not encoded. + It may happens when the actual number of bits per + band is near same to estimated number of bits, for + most bands (very unprobable but possible) */ + IF( L_add( Rk_fx[k_sort[k]], delta_fx) < 0 ) + { + pulsesnum = 0; + move16(); + FOR( i = 0; i < band_width[k_sort[k]]; i++ ) + { + inp_vector_fx[band_start[k_sort[k]] + i] = 0; + move16(); + } + IF( surplus_fx != 0 ) + { + /* surplus_fx += (Rk[k_sort[k]] + delta);*/ + surplus_fx = L_add( Rk_fx[k_sort[k]], surplus_fx); + surplus_fx = L_add( delta_fx, surplus_fx); + } + } + ELSE + { + /*get number of pulses */ + pulsesnum = GetScale_fx( band_width[k_sort[k]], + L_add( Rk_fx[k_sort[k]], delta_fx), + &surplus_fx ); + leftbits = L_sub( leftbits, L_add( Rk_fx[k_sort[k]], delta_fx) ); + decode_position_ari_fx( pardec_fx, band_width[k_sort[k]], pulsesnum, &nz, &positions_fx[band_start[k_sort[k]]] ); + /*decode tcq magniitude and update the surplus bits.*/ + decode_mangitude_tcq_fx( pardec_fx, band_width[k_sort[k]], pulsesnum, nz, &positions_fx[band_start[k_sort[k]]], &inp_vector_fx[band_start[k_sort[k]]], &surplus_fx ); + decode_signs_fx( pardec_fx, band_width[k_sort[k]], &inp_vector_fx[band_start[k_sort[k]]] ); + } + nzbands--; + move16(); + } + ELSE IF (Rk_fx[k_sort[k]] > 0 && EQ_16(USQ_TCQ[k_sort[k]], 1)) + { + /* When number of bits per band is less than + arithmetic bits overhead, this band is not encoded. + It may happens when the actual number of bits per + band is near same to estimated number of bits, for + most bands (very unprobable but possible) */ + IF( L_add( Rk_fx[k_sort[k]], delta_fx) < 0 ) + { + pulsesnum = 0; + move16(); + FOR( i = 0; i < band_width[k_sort[k]]; i++ ) + { + inp_vector_fx[band_start[k_sort[k]] + i] = 0; + move16(); + } + IF( surplus_fx != 0 ) + { + surplus_fx = L_add( Rk_fx[k_sort[k]], surplus_fx); + surplus_fx = L_add( delta_fx, surplus_fx); + } + } + ELSE + { + pulsesnum = GetScale_fx(band_width[k_sort[k]], + L_add( Rk_fx[k_sort[k]], delta_fx), + &surplus_fx); + leftbits = L_sub( leftbits, L_add( Rk_fx[k_sort[k]], delta_fx) ); + decode_position_ari_fx( pardec_fx, band_width[k_sort[k]], pulsesnum, &nz, &positions_fx[band_start[k_sort[k]]] ); + /*decode usq magnitude and don't need to update surplus bits*/ + decode_magnitude_usq_fx( pardec_fx, band_width[k_sort[k]], pulsesnum, nz, &positions_fx[band_start[k_sort[k]]], &inp_vector_fx[band_start[k_sort[k]]] ); + decode_signs_fx( pardec_fx, band_width[k_sort[k]], &inp_vector_fx[band_start[k_sort[k]]] ); + } + nzbands--; + move16(); + } + ELSE + { + pulsesnum = 0; + move16(); + FOR ( i = 0; i < band_width[k_sort[k]]; i++ ) + { + inp_vector_fx[band_start[k_sort[k]] + i] = 0; + move16(); + } + } + + npulses[k_sort[k]] = pulsesnum; + move16(); + + delta_fx = L_deposit_l(0); + test(); + IF( Rk_fx[k_sort[k]] > 0 && surplus_fx < 0 ) + { + IF( nzbands <= 1 ) + { + divider = 0; + } + ELSE + { + divider = 2; + } + + IF( L_add( L_add( surplus_fx, sepbits), ar_div( leftbits, divider ) ) < 0 ) + { + /* Overflow possible => start to distribute negative surplus */ + delta_fx = ar_div( surplus_fx + sepbits, nzbands); + } + else + { + delta_fx = 0; + } + surplus_fx = L_sub(surplus_fx, delta_fx); + + } + } + } + + test(); + test(); + test(); + IF (( GT_32(surplus_fx,524288)&&EQ_16(input_frame,L_FRAME8k))||(GT_32(surplus_fx,786432)&&EQ_16(input_frame,L_FRAME16k))) + { + bit_surplus_fx[0] = Mult_32_16(surplus_fx,24576);/* Q16 */ + bit_surplus_fx[1] = Mult_32_16(surplus_fx,8192);/* Q16 */ + } + ELSE + { + bit_surplus_fx[0] = surplus_fx; + move32(); + bit_surplus_fx[1] = L_deposit_l(0); + } + + FOR ( k = 0; k < BANDS; k++ ) + { + FOR ( j = 0; j < 2; j++ ) + { + IF ( EQ_16(k, k_num[j])) + { + Rk_fx[k_sort[k]] = L_add(Rk_fx[k_sort[k]],bit_surplus_fx[j]); + move32(); + + test(); + test(); + IF ( Rk_fx[k_sort[k]] > 0 && USQ_TCQ[k_sort[k]] == 0 ) + { + /* get number of pulses */ + pulsesnum = GetScale_fx( band_width[k_sort[k]], Rk_fx[k_sort[k]], &surplus_fx ); + + decode_position_ari_fx( pardec_fx, band_width[k_sort[k]], pulsesnum, &nz, &positions_fx[band_start[k_sort[k]]] ); + /* decode tcq magniitude and update the surplus bits. */ + decode_mangitude_tcq_fx( pardec_fx, band_width[k_sort[k]], pulsesnum, nz, &positions_fx[band_start[k_sort[k]]], &inp_vector_fx[band_start[k_sort[k]]], &surplus_fx ); + decode_signs_fx( pardec_fx, band_width[k_sort[k]], &inp_vector_fx[band_start[k_sort[k]]] ); + } + ELSE IF( Rk_fx[k_sort[k]] > 0 && USQ_TCQ[k_sort[k]] == 1 ) + { + pulsesnum = GetScale_fx( band_width[k_sort[k]], Rk_fx[k_sort[k]], &surplus_fx ); + + decode_position_ari_fx( pardec_fx, band_width[k_sort[k]], pulsesnum, &nz, &positions_fx[band_start[k_sort[k]]] ); + /* decode usq magnitude and don't need to update surplus bits */ + decode_magnitude_usq_fx( pardec_fx, band_width[k_sort[k]], pulsesnum, nz, &positions_fx[band_start[k_sort[k]]], &inp_vector_fx[band_start[k_sort[k]]] ); + decode_signs_fx( pardec_fx, band_width[k_sort[k]], &inp_vector_fx[band_start[k_sort[k]]] ); + } + ELSE + { + pulsesnum = 0; + move16(); + FOR ( i = 0; i < band_width[k_sort[k]]; i++ ) + { + inp_vector_fx[band_start[k_sort[k]] + i] = 0; + move16(); + } + } + + npulses[k_sort[k]] = pulsesnum; + move16(); + } + } + } + } + ELSE + { + FOR ( k = 0; k < BANDS; k++ ) + { + IF ( Rk_fx[k_sort[k]] > 0 ) + { + pulsesnum = GetScale_fx(band_width[k_sort[k]], Rk_fx[k_sort[k]] + delta_fx, &surplus_fx); + + decode_position_ari_fx( pardec_fx, band_width[k_sort[k]], pulsesnum, &nz, &positions_fx[band_start[k_sort[k]]] ); + + /*decode usq magnitude and don't need to update surplus bits*/ + decode_magnitude_usq_fx( pardec_fx, band_width[k_sort[k]], pulsesnum, nz, &positions_fx[band_start[k_sort[k]]], &inp_vector_fx[band_start[k_sort[k]]] ); + decode_signs_fx( pardec_fx, band_width[k_sort[k]], &inp_vector_fx[band_start[k_sort[k]]] ); + + nzbands = sub(nzbands, 1); + } + ELSE + { + pulsesnum = 0; + move16(); + FOR ( i = 0; i < band_width[k_sort[k]]; i++ ) + { + inp_vector_fx[band_start[k_sort[k]] + i] = 0; + move16(); + } + } + + npulses[k_sort[k]] = pulsesnum; + move16(); + + /* surplus distribution */ + test(); + IF ( surplus_fx > 0 && nzbands > 0 ) + { + delta_fx = ar_div(surplus_fx, nzbands); + surplus_fx = L_sub(surplus_fx, delta_fx); + } + } + } + + /* Load TCQ path from bitstream */ + LoadTCQdata_fx(pardec_fx, dpath, lsbtcq_bits); + + TCQLSBdec_fx(dpath, mbuffer_fx, 2*lsbtcq_bits); + + ar_decoder_done_fx(pardec_fx); + + /* Restore TCQ */ + IF ( !flag_wbnb ) + { + FOR ( k = 0; k < BANDS; k++) + { + IF ( Rk_fx[k_sort[k]] > 0 ) + { + RestoreTCQdec_fx( &inp_vector_fx[ band_start[ k_sort[ k]]], band_width[k_sort[k]], &bcount, mbuffer_fx ); + } + } + } + ELSE + { + FOR( k = 0; k < BANDS; k++) + { + test(); + test(); + IF( Rk_fx[k_sort[k]] > 0 && k != k_num[0] && k != k_num[1] ) + { + RestoreTCQdec_fx( &inp_vector_fx[ band_start[ k_sort[ k]]], band_width[k_sort[k]], &bcount, mbuffer_fx ); + } + } + + FOR ( k = 0; k < BANDS; k++) + { + test(); + test(); + IF ( Rk_fx[k_sort[k]] > 0 && (k == k_num[0] || k == k_num[1]) ) + { + RestoreTCQdec_fx( &inp_vector_fx[ band_start[ k_sort[ k]]], band_width[k_sort[k]], &bcount, mbuffer_fx ); + } + } + } + + + + return; +} diff --git a/lib_dec/tcx_utils_dec.c b/lib_dec/tcx_utils_dec.c index 01bbb3858985038119e63aa783137198415ad67c..c407239b7a3fe431efe94b0a6a2fc99fa137d090 100644 --- a/lib_dec/tcx_utils_dec.c +++ b/lib_dec/tcx_utils_dec.c @@ -43,12 +43,12 @@ #include "wmc_auto.h" /*--------------------------------------------------------------- - * tcx_decoder_memory_update() + * tcx_decoder_memory_update_flt() * * *--------------------------------------------------------------*/ -void tcx_decoder_memory_update( +void tcx_decoder_memory_update_flt( Decoder_State *st, /* i/o: decoder memory state */ const float *xn_buf, /* i/o: mdct output buffer used also as temporary buffer */ float *synthout, /* o : synth */ @@ -100,13 +100,13 @@ void tcx_decoder_memory_update( } /*--------------------------------------------------------------- - * tcx_ari_res_invQ_spec() + * tcx_ari_res_invQ_spec_flt() * * Residual Quantization *--------------------------------------------------------------*/ /*! r: number of bits used (including "bits") */ -int16_t tcx_ari_res_invQ_spec( +int16_t tcx_ari_res_invQ_spec_flt( float x_Q[], /* i/o: quantized spectrum */ const int16_t L_frame, /* i : number of lines */ const int16_t prm[], /* i : bitstream */ @@ -176,12 +176,12 @@ int16_t tcx_ari_res_invQ_spec( /*--------------------------------------------------------------- - * tcx_res_invQ_gain() + * tcx_res_invQ_gain_flt() * * *--------------------------------------------------------------*/ -int16_t tcx_res_invQ_gain( +int16_t tcx_res_invQ_gain_flt( float *gain_tcx, const int16_t *prm, const int16_t resQBits ) @@ -193,11 +193,11 @@ int16_t tcx_res_invQ_gain( { if ( prm[bits] == 0 ) { - *gain_tcx = ( *gain_tcx ) * gain_corr_inv_fac[bits]; + *gain_tcx = ( *gain_tcx ) * gain_corr_inv_fac_flt[bits]; } else { - *gain_tcx = ( *gain_tcx ) * gain_corr_fac[bits]; + *gain_tcx = ( *gain_tcx ) * gain_corr_fac_flt[bits]; } } @@ -206,12 +206,12 @@ int16_t tcx_res_invQ_gain( /*--------------------------------------------------------------- - * tcx_res_invQ_spec() + * tcx_res_invQ_spec_flt() * * *--------------------------------------------------------------*/ -int16_t tcx_res_invQ_spec( +int16_t tcx_res_invQ_spec_flt( float *x, const int16_t L_frame, const int16_t *prm, diff --git a/lib_dec/tcx_utils_dec_fx.c b/lib_dec/tcx_utils_dec_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..a3761f2cb7b279cd111f9bedadcc630e2ff9225b --- /dev/null +++ b/lib_dec/tcx_utils_dec_fx.c @@ -0,0 +1,358 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + + +#include +#include +#include +#include +#include "options.h" +#include "prot_fx1.h" +#include "prot_fx2.h" +#include "rom_basop_util.h" +#include "basop_util.h" +#include "rom_com.h" + +/*--------------------------------------------------------------- + * tcx_decoder_memory_update() + * + * + *--------------------------------------------------------------*/ +void tcx_decoder_memory_update( + Word16 *xn_buf, /* i/o: mdct output buffer used also as temporary buffer */ + Word16 *synthout, /* o: synth */ + Word16 *A, /* i: Quantized LPC coefficients */ + Decoder_State *st, /* i/o: decoder memory state */ + Word8 fb /* i: fullband flag */ +) +{ + Word16 tmp; + Word16 *synth; + Word16 buf[1+M+LFAC+L_FRAME_PLUS]; + Word16 L_frame_glob; + Word16 preemph; + + L_frame_glob = st->L_frame; + preemph = st->preemph_fac; + move16(); + + /* Output synth */ + Copy(xn_buf, synthout, L_frame_glob); + + /* Update synth */ + + synth = buf + M+1; + Copy(st->syn, buf, M+1); + Copy(xn_buf, synth, L_frame_glob); + Copy(synth + sub(L_frame_glob, M+1), st->syn, M+1); + + IF (NE_16(st->element_mode, IVAS_CPE_MDCT)) + { + IF(!fb) /* TV2FhG -> Condition differs from floating point */ + { + + /* Emphasis of synth -> synth_pe */ + tmp = synth[-M - 1]; + move16(); + st->Q_syn = E_UTIL_f_preemph3(synth - M, preemph, add(M, L_frame_glob), &tmp, 1); + st->prev_Q_syn = st->Q_syn = st->Q_syn - 1; + Copy(synth + sub(L_frame_glob, M), st->mem_syn2_fx, M); + Copy(synth + sub(L_frame_glob, L_SYN_MEM), st->mem_syn_r, L_SYN_MEM); + + test(); + IF(st->tcxonly == 0 || LE_16(L_frame_glob, L_FRAME16k)) + { + /* Update excitation */ + IF(NE_16(st->Q_syn + 1, st->Q_exc)) + { + Scale_sig(st->old_exc_fx, L_EXC_MEM_DEC, sub(st->Q_syn + 1, st->Q_exc)); + } + st->Q_exc = st->Q_syn + 1; + st->Q_subfr[0] = st->Q_subfr[1] = st->Q_subfr[2] = st->Q_subfr[3] = st->Q_subfr[4] = st->Q_exc; + + assert(L_frame_glob < L_EXC_MEM_DEC); + Copy(st->old_exc_fx + L_frame_glob, st->old_exc_fx, sub(L_EXC_MEM_DEC, L_frame_glob)); + Residu3_fx(A, synth, st->old_exc_fx + sub(L_EXC_MEM_DEC, L_frame_glob), L_frame_glob, 1); + } + /* Update old_Aq */ + Copy(A, st->old_Aq_12_8_fx, M + 1); + } + } + return; +} + +/* Returns: number of bits used (including "bits") */ +Word16 tcx_ari_res_invQ_spec( + Word32 x_Q[], /* i/o: quantized spectrum Q31-e */ + Word16 x_Q_e, /* i: quantized spectrum exponent Q0 */ + Word16 L_frame, /* i: number of lines Q0 */ + const Word16 prm[], /* i: bitstream Q0 */ + Word16 target_bits, /* i: number of bits available Q0 */ + Word16 bits, /* i: number of bits used so far Q0 */ + Word16 deadzone, /* i: quantizer deadzone Q15 */ + const Word16 x_fac[] /* i: spectrum post-quantization factors Q14 */ +) +{ + Word16 i, j, num_zeros; + Word16 zeros[L_FRAME_PLUS]; + Word16 fac_p, sign; + Word32 L_tmp; + Word16 s; + + + /* Limit the number of residual bits */ + target_bits = s_min(target_bits, NPRM_RESQ); + + + /* Requantize the spectrum line-by-line */ + /* fac_m = deadzone * 0.5f; */ + num_zeros = 0; + move16(); + + FOR (i=0; i < L_frame; i++) + { + IF (GE_16(bits, target_bits)) /* no bits left */ + { + BREAK; + } + + IF (x_Q[i] != 0) + { + sign = x_fac[i]; + move16(); + if (x_Q[i] < 0) sign = negate(sign); + + /* x_Q[i] += sign*(prm[bits++] * 0.5f - fac_m); */ + x_Q[i] = L_sub(x_Q[i], L_shr(L_mult(sign, add(deadzone, lshl(prm[bits], 15))), x_Q_e)); + move32(); + bits = add(bits, 1); + } + ELSE + { + zeros[num_zeros] = i; + move16(); + num_zeros = add(num_zeros, 1); + } + } + + /* Requantize zeroed-lines of the spectrum */ + fac_p = msu_r(1417339264l/*0.33f*2.0f Q31*/, deadzone, 21627/*0.33f*2.0f Q15*/); /* Q15 */ + target_bits = sub(target_bits, 1); /* reserve 1 bit for the check below */ + + s = sub(x_Q_e, 1); + FOR (j = 0; j < num_zeros; j++) + { + IF (GE_16(bits, target_bits)) /* 1 or 0 bits left */ + { + BREAK; + } + + i = zeros[j]; + move16(); + + IF (prm[bits] != 0) + { + bits = add(bits, 1); + L_tmp = L_mult(fac_p, x_fac[i]); /* Q30 */ + if (prm[bits] == 0) L_tmp = L_negate(L_tmp); + x_Q[i] = L_shr(L_tmp, s); + move32(); + } + bits = add(bits, 1); + } + + + return bits; +} +/*--------------------------------------------------------------- + * tcx_res_invQ_gain() + * + * + *--------------------------------------------------------------*/ +Word16 tcx_res_invQ_gain( + Word16 *gain_tcx, + Word16 *gain_tcx_e, + Word16 *prm, + Word16 resQBits +) +{ + Word16 bits; + Word16 gain, tmp1, tmp2; + + + gain = *gain_tcx; + move16(); + + /* make sure we have a bit of headroom */ + IF (GT_16(gain, 0x7000)) + { + gain = shr(gain, 1); + *gain_tcx_e = add(*gain_tcx_e, 1); + move16(); + } + + /*Refine the gain quantization*/ + tmp1 = s_min(resQBits, TCX_RES_Q_BITS_GAIN); + FOR (bits=0; bits < tmp1; bits++) + { + tmp2 = gain_corr_fac[bits]; + move16(); + if (prm[bits] == 0) + { + tmp2 = gain_corr_inv_fac[bits]; + move16(); + } + + gain = mult_r(gain, tmp2); + if (prm[bits] != 0) gain = shl(gain, 1); + } + + *gain_tcx = gain; + move16(); + + + return bits; +} + +/*--------------------------------------------------------------- + * tcx_res_invQ_spec() + * + * + *--------------------------------------------------------------*/ +Word16 tcx_res_invQ_spec( + Word32 *x, + Word16 x_e, + Word16 L_frame, + Word16 *prm, + Word16 resQBits, + Word16 bits, + Word16 sq_round, + const Word16 lf_deemph_factors[] +) +{ + Word16 i; + Word16 fac_m, fac_p; + Word16 lf_deemph_factor, c, s; + Word32 tmp; + + + /* Limit the number of residual bits */ + resQBits = s_min(resQBits, NPRM_RESQ); + + /* Requantize the spectrum line-by-line */ + fac_m = shr(sq_round, 1); + fac_p = sub(0x4000, fac_m); + + lf_deemph_factor = 0x4000; + move16(); + s = sub(x_e, 1); + + FOR (i = 0; i < L_frame; i++) + { + IF (GE_16(bits, resQBits)) + { + BREAK; + } + + test(); + test(); + IF ((x[i] != 0) && ((lf_deemph_factors == NULL) || (GT_16(lf_deemph_factors[i], 0x2000)))) + { + if (lf_deemph_factors != NULL) + { + lf_deemph_factor = lf_deemph_factors[i]; + move16(); + } + + IF (prm[bits] == 0) + { + + /* Debug initialization to catch illegal cases of x[i] */ + tmp = 0; + + if (x[i] > 0) tmp = L_mult(fac_m, lf_deemph_factor); + if (x[i] < 0) tmp = L_mult(fac_p, lf_deemph_factor); + + assert(tmp != 0); + + x[i] = L_sub(x[i], L_shr(tmp, s)); + move32(); + } + ELSE + { + + /* Debug initialization to catch illegal cases of x[i] */ + tmp = 0; + + if (x[i] > 0) tmp = L_mult(fac_p, lf_deemph_factor); + if (x[i] < 0) tmp = L_mult(fac_m, lf_deemph_factor); + + assert(tmp != 0); + + x[i] = L_add(x[i], L_shr(tmp, s)); + move32(); + } + bits = add(bits, 1); + } + } + + /*Quantize zeroed-line of the spectrum*/ + resQBits = sub(resQBits, 1); + + IF (lf_deemph_factors == NULL) + { + FOR (i = 0; i < L_frame; i++) + { + IF (GE_16(bits, resQBits)) + { + BREAK; + } + + IF (x[i] == 0) + { + IF (prm[bits] != 0) + { + bits = add(bits, 1); + + tmp = L_mult(21627/*1.32f Q14*/, fac_p); + if (prm[bits] == 0) tmp = L_negate(tmp); + + x[i] = L_shr(tmp, s); + move32(); + } + bits = add(bits, 1); + } + } + } + ELSE + { + c = sub(21627/*0.66f Q15*/, mult_r(sq_round, 21627/*0.66f Q15*/)); + + FOR (i = 0; i < L_frame; i++) + { + IF (GE_16(bits, resQBits)) + { + BREAK; + } + + test(); + IF ((x[i] == 0) && (GT_16(lf_deemph_factors[i], 0x2000))) + { + IF (prm[bits] != 0) + { + bits = add(bits, 1); + + tmp = L_mult(c, lf_deemph_factors[i]); + if (prm[bits] == 0) tmp = L_negate(tmp); + + x[i] = L_shr(tmp, s); + move32(); + } + bits = add(bits, 1); + } + } + } + + return bits; +} diff --git a/lib_dec/tns_base_dec.c b/lib_dec/tns_base_dec.c index baa4c0dbecbead80f4a2e1a25b23dfb1349d3f5b..c430d29be441deb6bef99f6c0b64927258d06566 100644 --- a/lib_dec/tns_base_dec.c +++ b/lib_dec/tns_base_dec.c @@ -44,12 +44,12 @@ /*---------------------------------------------------------------------* - * ReadTnsData() + * ReadTnsData_ivas() * * *---------------------------------------------------------------------*/ -void ReadTnsData( +void ReadTnsData_ivas( STnsConfig const *pTnsConfig, Decoder_State *st, int16_t *pnBits, @@ -96,12 +96,12 @@ void ReadTnsData( /*---------------------------------------------------------------------* - * DecodeTnsData() + * DecodeTnsData_ivas() * * *---------------------------------------------------------------------*/ -int16_t DecodeTnsData( +int16_t DecodeTnsData_ivas( STnsConfig const *pTnsConfig, const int16_t *stream, int16_t *pnSize, diff --git a/lib_dec/tns_base_dec_fx.c b/lib_dec/tns_base_dec_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..f86ea753a1a998416c213de676ac25e2c2d6ebbf --- /dev/null +++ b/lib_dec/tns_base_dec_fx.c @@ -0,0 +1,156 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + + +#include +#include "options.h" +#include "prot_fx1.h" +#include "prot_fx2.h" +#include +#include "rom_com.h" + +/** Linear prediction analysis/synthesis filter definition. + * @param order filter order. + * @param parCoeff filter (PARCOR) coefficients. + * @param state state of the filter. Must be at least of 'order' size. + * @param x the current input value. + * @return the output of the filter. + */ +typedef Word32 (* TLinearPredictionFilter)(Word16 order, Word16 const parCoeff[], Word32 * state, Word32 x); + +/********************************/ +/* Interface functions */ +/********************************/ +/*---------------------------------------------------------------------* + * ReadTnsData() + * + * + *---------------------------------------------------------------------*/ + +#ifdef IVAS_CODE +void +#else +Word16 +#endif + ReadTnsData( + STnsConfig const * pTnsConfig, + Decoder_State *st, + Word16 * pnBits, + Word16 * stream, + Word16 * pnSize +) +{ + Word16 start_bit_pos; + + + move16(); + start_bit_pos = st->next_bit_pos; + + IF ( GT_16(pTnsConfig->nMaxFilters, 1)) + { +#ifdef IVAS_CODE + IF(pTnsConfig->allowTnsOnWhite) + { + IF(LT_16(pTnsConfig->iFilterBorders[0], 512)) + { + ReadFromBitstream(&tnsEnabledOnWhiteSWBTCX10BitMap, 1, st, &stream, pnSize); + } + ELSE + { + ReadFromBitstream(&tnsEnabledOnWhiteSWBTCX20BitMap, 1, st, &stream, pnSize); + } + } + ELSE +#endif + { + + IF(LT_16(pTnsConfig->iFilterBorders[0], 512)) + { + ReadFromBitstream(&tnsEnabledSWBTCX10BitMap, 1, st, &stream, pnSize); + } + ELSE + { + ReadFromBitstream(&tnsEnabledSWBTCX20BitMap, 1, st, &stream, pnSize); + } + } + } + ELSE + { + ReadFromBitstream(&tnsEnabledWBTCX20BitMap, 1, st, &stream, pnSize); + } + + move16(); + *pnBits = sub(st->next_bit_pos, start_bit_pos); + + +#ifdef IVAS_CODE + return; +#else + return TNS_NO_ERROR; +#endif +} +/*---------------------------------------------------------------------* +* DecodeTnsData() +* +* +*---------------------------------------------------------------------*/ + +Word16 DecodeTnsData( + STnsConfig const * pTnsConfig, + Word16 const * stream, + Word16 * pnSize, + STnsData * pTnsData +) +{ + Word16 result; + + + + ResetTnsData(pTnsData); + + IF ( GT_16(pTnsConfig->nMaxFilters, 1)) + { + +#ifdef IVAS_CODE + IF (pTnsConfig->allowTnsOnWhite) + { + IF(LT_16(pTnsConfig->iFilterBorders[0], 512)) + { + SetParameters(&tnsEnabledOnWhiteSWBTCX10BitMap, 1, pTnsData, &stream, pnSize); + } + ELSE + { + SetParameters(&tnsEnabledOnWhiteSWBTCX20BitMap, 1, pTnsData, &stream, pnSize); + } + } + ELSE +#endif + { + IF(LT_16(pTnsConfig->iFilterBorders[0], 512)) + { + SetParameters(&tnsEnabledSWBTCX10BitMap, 1, pTnsData, &stream, pnSize); + } + ELSE + { + SetParameters(&tnsEnabledSWBTCX20BitMap, 1, pTnsData, &stream, pnSize); + } + } + } + ELSE + { + SetParameters(&tnsEnabledWBTCX20BitMap, 1, pTnsData, &stream, pnSize); + } + + move16(); + result = FALSE; + if (pTnsData->nFilters > 0) + { + move16(); + result = TRUE; + } + + + return result; +} + diff --git a/lib_dec/tonalMDCTconcealment.c b/lib_dec/tonalMDCTconcealment.c index 2d9f4583bc4d9ffd2ff67eef7000c2fc6447218f..1969cf9d72844b7acb3607baa393f3be08aa3e84 100644 --- a/lib_dec/tonalMDCTconcealment.c +++ b/lib_dec/tonalMDCTconcealment.c @@ -49,7 +49,7 @@ /*-------------- public functions -------------------- */ /*******************************************************/ -ivas_error TonalMDCTConceal_Init( +ivas_error TonalMDCTConceal_Init_ivas( TonalMDCTConcealPtr hTonalMDCTConc, const uint16_t nSamples, const uint16_t nSamplesCore, @@ -77,7 +77,7 @@ ivas_error TonalMDCTConceal_Init( hTonalMDCTConc->lastBlockData.blockIsConcealed = 0; hTonalMDCTConc->secondLastBlockData.blockIsConcealed = 0; - hTonalMDCTConc->pTCI = (TonalComponentsInfo *) hTonalMDCTConc->timeDataBuffer_float; + hTonalMDCTConc->pTCI_float = (TonalComponentsInfo_float *) hTonalMDCTConc->timeDataBuffer_float; hTonalMDCTConc->lastPitchLag_float = 0; @@ -100,7 +100,7 @@ ivas_error TonalMDCTConceal_Init( hTonalMDCTConc->curr_noise_nrg = 0.0f; hTonalMDCTConc->faded_signal_nrg = 0.0f; - /* Offset the pointer to the end of buffer, so that pTCI is not destroyed when + /* Offset the pointer to the end of buffer, so that pTCI_float is not destroyed when new time samples are stored in lastPcmOut */ /* just the second half of the second last pcm output is needed */ hTonalMDCTConc->secondLastPcmOut_float = &hTonalMDCTConc->timeDataBuffer_float[( 3 * L_FRAME_MAX ) / 2 - ( 3 * min( L_FRAME_MAX, nSamples ) ) / 2]; @@ -108,13 +108,13 @@ ivas_error TonalMDCTConceal_Init( /* If the second last frame was lost and concealed with tonal PLC, we reuse saved TonalComponentsInfo and don't update pcm buffers */ - assert( sizeof( *hTonalMDCTConc->pTCI ) <= ( hTonalMDCTConc->lastPcmOut_float - hTonalMDCTConc->timeDataBuffer_float) * sizeof( hTonalMDCTConc->timeDataBuffer_float[0] ) ); + assert( sizeof( *hTonalMDCTConc->pTCI_float ) <= ( hTonalMDCTConc->lastPcmOut_float - hTonalMDCTConc->timeDataBuffer_float) * sizeof( hTonalMDCTConc->timeDataBuffer_float[0] ) ); return IVAS_ERR_OK; } -void TonalMDCTConceal_SaveFreqSignal( +void TonalMDCTConceal_SaveFreqSignal_ivas( TonalMDCTConcealPtr hTonalMDCTConc, const float *mdctSpectrum, const uint16_t nNewSamples, @@ -181,7 +181,7 @@ void TonalMDCTConceal_SaveFreqSignal( } -void TonalMDCTConceal_UpdateState( +void TonalMDCTConceal_UpdateState_ivas( TonalMDCTConcealPtr hTonalMDCTConc, const int16_t nNewSamples, const float pitchLag, @@ -225,11 +225,11 @@ static void FindPhases( int16_t l; float *pCurrentPhase; - pCurrentPhase = hTonalMDCTConc->pTCI->phase_currentFramePredicted_float; + pCurrentPhase = hTonalMDCTConc->pTCI_float->phase_currentFramePredicted_float; /* for each index/index group */ - for ( i = 0; i < hTonalMDCTConc->pTCI->numIndexes; i++ ) + for ( i = 0; i < hTonalMDCTConc->pTCI_float->numIndexes; i++ ) { - for ( l = hTonalMDCTConc->pTCI->lowerIndex[i]; l <= hTonalMDCTConc->pTCI->upperIndex[i]; l++ ) + for ( l = hTonalMDCTConc->pTCI_float->lowerIndex[i]; l <= hTonalMDCTConc->pTCI_float->upperIndex[i]; l++ ) { *pCurrentPhase++ = (float) atan2( secondLastMDST[l], secondLastMDCT[l] ); } @@ -257,10 +257,10 @@ static void FindPhaseDifferences( float fractional; float Q, a; - phaseDiff = hTonalMDCTConc->pTCI->phaseDiff_float; - for ( i = 0; i < hTonalMDCTConc->pTCI->numIndexes; i++ ) + phaseDiff = hTonalMDCTConc->pTCI_float->phaseDiff_float; + for ( i = 0; i < hTonalMDCTConc->pTCI_float->numIndexes; i++ ) { - k = hTonalMDCTConc->pTCI->indexOfTonalPeak[i]; + k = hTonalMDCTConc->pTCI_float->indexOfTonalPeak[i]; odft_left = powerSpectrum[k - 1]; odft_right = powerSpectrum[k + 1]; if ( odft_left >= CNST_maxRatio * odft_right ) @@ -339,14 +339,14 @@ static void CalcPowerSpecAndDetectTonalComponents( set_zero( powerSpectrum + hTonalMDCTConc->nSamples, hTonalMDCTConc->nSamplesCore - hTonalMDCTConc->nSamples ); } - DetectTonalComponents( hTonalMDCTConc->pTCI->indexOfTonalPeak, hTonalMDCTConc->pTCI->lowerIndex, hTonalMDCTConc->pTCI->upperIndex, &hTonalMDCTConc->pTCI->numIndexes, hTonalMDCTConc->lastPitchLag_float, pitchLag, + DetectTonalComponents_flt( hTonalMDCTConc->pTCI_float->indexOfTonalPeak, hTonalMDCTConc->pTCI_float->lowerIndex, hTonalMDCTConc->pTCI_float->upperIndex, &hTonalMDCTConc->pTCI_float->numIndexes, hTonalMDCTConc->lastPitchLag_float, pitchLag, hTonalMDCTConc->lastBlockData.spectralData_float, hTonalMDCTConc->lastBlockData.scaleFactors_float, powerSpectrum, nSamples, hTonalMDCTConc->nSamplesCore, floorPowerSpectrum, psychParamsCurrent ); FindPhases( hTonalMDCTConc, secondLastMDCT, secondLastMDST ); FindPhaseDifferences( hTonalMDCTConc, powerSpectrum ); - if ( hTonalMDCTConc->pTCI->numIndexes > 0 ) + if ( hTonalMDCTConc->pTCI_float->numIndexes > 0 ) { hTonalMDCTConc->secondLastPowerSpectrum_float = hTonalMDCTConc->secondLastBlockData.spectralData_float; @@ -363,7 +363,7 @@ static void CalcPowerSpecAndDetectTonalComponents( if ( psychParamsCurrent == NULL ) { nBands = FDNS_NPTS; - mdct_noiseShaping( powerSpectrum, hTonalMDCTConc->nSamplesCore, invScaleFactors, nBands ); + mdct_noiseShaping_flt( powerSpectrum, hTonalMDCTConc->nSamplesCore, invScaleFactors, nBands ); } else { @@ -390,22 +390,22 @@ static void CalcMDXT( int16_t L_frame; L_frame = hTonalMDCTConc->nSamples; - WindowSignal( hTonalMDCTConc->tcx_cfg, hTonalMDCTConc->tcx_cfg->tcx_offsetFB, FULL_OVERLAP, FULL_OVERLAP, &left_overlap, &right_overlap, timeSignal, &L_frame, windowedTimeSignal, 1, 1 ); + WindowSignal_flt( hTonalMDCTConc->tcx_cfg, hTonalMDCTConc->tcx_cfg->tcx_offsetFB, FULL_OVERLAP, FULL_OVERLAP, &left_overlap, &right_overlap, timeSignal, &L_frame, windowedTimeSignal, 1, 1 ); if ( type == 'S' ) { - TCX_MDST( windowedTimeSignal, mdxtOutput, left_overlap, L_frame - ( left_overlap + right_overlap ) / 2, right_overlap, EVS_MONO ); + TCX_MDST_flt( windowedTimeSignal, mdxtOutput, left_overlap, L_frame - ( left_overlap + right_overlap ) / 2, right_overlap, EVS_MONO ); } else { - TCX_MDCT( windowedTimeSignal, mdxtOutput, left_overlap, L_frame - ( left_overlap + right_overlap ) / 2, right_overlap, EVS_MONO ); + TCX_MDCT_flt( windowedTimeSignal, mdxtOutput, left_overlap, L_frame - ( left_overlap + right_overlap ) / 2, right_overlap, EVS_MONO ); } return; } -void TonalMDCTConceal_Detect( +void TonalMDCTConceal_Detect_ivas( const TonalMDCTConcealPtr hTonalMDCTConc, const float pitchLag, int16_t *numIndices, @@ -442,14 +442,14 @@ void TonalMDCTConceal_Detect( } else { - /* If the second last frame was also lost, it is expected that pastTimeSignal could hold a bit different signal (e.g. including fade-out) from the one stored in TonalMDCTConceal_SaveTimeSignal. */ + /* If the second last frame was also lost, it is expected that pastTimeSignal could hold a bit different signal (e.g. including fade-out) from the one stored in TonalMDCTConceal_SaveTimeSignal_ivas. */ /* That is why we reuse the already stored information about the concealed spectrum in the second last frame */ nSamples = hTonalMDCTConc->nNonZeroSamples; mvr2r( hTonalMDCTConc->secondLastPowerSpectrum_float, powerSpectrum, nSamples ); /* Convert from 16 bits to 32 bits */ if ( psychParamsCurrent == NULL ) { nBands = FDNS_NPTS; - mdct_noiseShaping( powerSpectrum, hTonalMDCTConc->nSamplesCore, hTonalMDCTConc->secondLastBlockData.scaleFactors_float, nBands ); + mdct_noiseShaping_flt( powerSpectrum, hTonalMDCTConc->nSamplesCore, hTonalMDCTConc->secondLastBlockData.scaleFactors_float, nBands ); } else { @@ -460,8 +460,8 @@ void TonalMDCTConceal_Detect( v_multc( powerSpectrum + hTonalMDCTConc->nSamplesCore, hTonalMDCTConc->secondLastBlockData.scaleFactors_float[nBands - 1], powerSpectrum + hTonalMDCTConc->nSamplesCore, nSamples - hTonalMDCTConc->nSamplesCore ); v_mult( powerSpectrum, powerSpectrum, powerSpectrum, nSamples ); - RefineTonalComponents( hTonalMDCTConc->pTCI->indexOfTonalPeak, hTonalMDCTConc->pTCI->lowerIndex, hTonalMDCTConc->pTCI->upperIndex, hTonalMDCTConc->pTCI->phaseDiff_float, - hTonalMDCTConc->pTCI->phase_currentFramePredicted_float, &hTonalMDCTConc->pTCI->numIndexes, hTonalMDCTConc->lastPitchLag_float, pitchLag, + RefineTonalComponents_flt( hTonalMDCTConc->pTCI_float->indexOfTonalPeak, hTonalMDCTConc->pTCI_float->lowerIndex, hTonalMDCTConc->pTCI_float->upperIndex, hTonalMDCTConc->pTCI_float->phaseDiff_float, + hTonalMDCTConc->pTCI_float->phase_currentFramePredicted_float, &hTonalMDCTConc->pTCI_float->numIndexes, hTonalMDCTConc->lastPitchLag_float, pitchLag, hTonalMDCTConc->lastBlockData.spectralData_float, hTonalMDCTConc->lastBlockData.scaleFactors_float, powerSpectrum, nSamples, hTonalMDCTConc->nSamplesCore, hTonalMDCTConc->nSamples * hTonalMDCTConc->nSamples / 400.0f /* floorPowerSpectrum */, psychParamsCurrent ); } @@ -469,16 +469,16 @@ void TonalMDCTConceal_Detect( } else { - hTonalMDCTConc->pTCI->numIndexes = 0; + hTonalMDCTConc->pTCI_float->numIndexes = 0; } - *numIndices = hTonalMDCTConc->pTCI->numIndexes; + *numIndices = hTonalMDCTConc->pTCI_float->numIndexes; return; } -void TonalMDCTConceal_InsertNoise( +void TonalMDCTConceal_InsertNoise_ivas( const TonalMDCTConcealPtr hTonalMDCTConc, /*IN */ float *mdctSpectrum, /*OUT*/ const int16_t tonalConcealmentActive, @@ -507,7 +507,7 @@ void TonalMDCTConceal_InsertNoise( rnd = *pSeed; } - /* based on what is done in tcx_noise_filling() */ + /* based on what is done in tcx_noise_filling_flt() */ /* always initialize these to avoid compiler warnings */ tiltFactor = (float) pow( max( 0.375f, tiltCompFactor ), 1.0f / hTonalMDCTConc->lastBlockData.nSamples ); tilt = 1.0f; @@ -574,15 +574,15 @@ void TonalMDCTConceal_InsertNoise( } else { - assert( hTonalMDCTConc->pTCI->numIndexes > 0 ); + assert( hTonalMDCTConc->pTCI_float->numIndexes > 0 ); /* initialize bins of tonal components with zero: basically not necessary, but currently the whole spectrum is rescaled in - mdct_noiseShaping() and then there would be a processing of + mdct_noiseShaping_flt() and then there would be a processing of uninitialized values */ - for ( i = 0; i < hTonalMDCTConc->pTCI->numIndexes; i++ ) + for ( i = 0; i < hTonalMDCTConc->pTCI_float->numIndexes; i++ ) { - for ( l = hTonalMDCTConc->pTCI->lowerIndex[i]; l <= hTonalMDCTConc->pTCI->upperIndex[i]; l++ ) + for ( l = hTonalMDCTConc->pTCI_float->lowerIndex[i]; l <= hTonalMDCTConc->pTCI_float->upperIndex[i]; l++ ) { mdctSpectrum[l] = 0; if ( l < crossOverFreq ) @@ -596,7 +596,7 @@ void TonalMDCTConceal_InsertNoise( /* if fadeout has not started yet, only apply sign scrambling */ if ( crossfadeGain == 1.0f ) { - for ( l = 0; l < hTonalMDCTConc->pTCI->lowerIndex[0]; l++ ) + for ( l = 0; l < hTonalMDCTConc->pTCI_float->lowerIndex[0]; l++ ) { if ( concealment_noise[l] > 0 ) { @@ -607,9 +607,9 @@ void TonalMDCTConceal_InsertNoise( mdctSpectrum[l] = -hTonalMDCTConc->lastBlockData.spectralData_float[l]; } } - for ( i = 1; i < hTonalMDCTConc->pTCI->numIndexes; i++ ) + for ( i = 1; i < hTonalMDCTConc->pTCI_float->numIndexes; i++ ) { - for ( l = hTonalMDCTConc->pTCI->upperIndex[i - 1] + 1; l < hTonalMDCTConc->pTCI->lowerIndex[i]; l++ ) + for ( l = hTonalMDCTConc->pTCI_float->upperIndex[i - 1] + 1; l < hTonalMDCTConc->pTCI_float->lowerIndex[i]; l++ ) { if ( concealment_noise[l] > 0 ) { @@ -622,7 +622,7 @@ void TonalMDCTConceal_InsertNoise( } } - for ( l = hTonalMDCTConc->pTCI->upperIndex[hTonalMDCTConc->pTCI->numIndexes - 1] + 1; l < crossOverFreq; l++ ) + for ( l = hTonalMDCTConc->pTCI_float->upperIndex[hTonalMDCTConc->pTCI_float->numIndexes - 1] + 1; l < crossOverFreq; l++ ) { if ( concealment_noise[l] > 0 ) { @@ -644,7 +644,7 @@ void TonalMDCTConceal_InsertNoise( { g *= (float) sqrt( cngLevelBackgroundTrace_bfi / hTonalMDCTConc->curr_noise_nrg ); - for ( l = 0; l < hTonalMDCTConc->pTCI->lowerIndex[0]; l++ ) + for ( l = 0; l < hTonalMDCTConc->pTCI_float->lowerIndex[0]; l++ ) { x = hTonalMDCTConc->lastBlockData.spectralData_float[l]; y = concealment_noise[l]; @@ -659,9 +659,9 @@ void TonalMDCTConceal_InsertNoise( } hTonalMDCTConc->faded_signal_nrg += mdctSpectrum[l] * mdctSpectrum[l]; } - for ( i = 1; i < hTonalMDCTConc->pTCI->numIndexes; i++ ) + for ( i = 1; i < hTonalMDCTConc->pTCI_float->numIndexes; i++ ) { - for ( l = hTonalMDCTConc->pTCI->upperIndex[i - 1] + 1; l < hTonalMDCTConc->pTCI->lowerIndex[i]; l++ ) + for ( l = hTonalMDCTConc->pTCI_float->upperIndex[i - 1] + 1; l < hTonalMDCTConc->pTCI_float->lowerIndex[i]; l++ ) { x = hTonalMDCTConc->lastBlockData.spectralData_float[l]; y = concealment_noise[l]; @@ -678,7 +678,7 @@ void TonalMDCTConceal_InsertNoise( } } - for ( l = hTonalMDCTConc->pTCI->upperIndex[hTonalMDCTConc->pTCI->numIndexes - 1] + 1; l < crossOverFreq; l++ ) + for ( l = hTonalMDCTConc->pTCI_float->upperIndex[hTonalMDCTConc->pTCI_float->numIndexes - 1] + 1; l < crossOverFreq; l++ ) { x = hTonalMDCTConc->lastBlockData.spectralData_float[l]; y = concealment_noise[l]; @@ -748,8 +748,8 @@ void TonalMDCTConceal_InsertNoise( } else { - assert( hTonalMDCTConc->pTCI->numIndexes > 0 ); - for ( l = 0; l < hTonalMDCTConc->pTCI->lowerIndex[0]; l++ ) + assert( hTonalMDCTConc->pTCI_float->numIndexes > 0 ); + for ( l = 0; l < hTonalMDCTConc->pTCI_float->lowerIndex[0]; l++ ) { x = hTonalMDCTConc->lastBlockData.spectralData_float[l]; rnd = own_random( &rnd ); @@ -759,10 +759,10 @@ void TonalMDCTConceal_InsertNoise( nrgWhiteNoise += mdctSpectrum[l] * mdctSpectrum[l]; } - for ( i = 1; i < hTonalMDCTConc->pTCI->numIndexes; i++ ) + for ( i = 1; i < hTonalMDCTConc->pTCI_float->numIndexes; i++ ) { - tilt *= (float) pow( tiltFactor, hTonalMDCTConc->pTCI->upperIndex[i - 1] - hTonalMDCTConc->pTCI->lowerIndex[i - 1] + 1 ); - for ( l = hTonalMDCTConc->pTCI->upperIndex[i - 1] + 1; l < hTonalMDCTConc->pTCI->lowerIndex[i]; l++ ) + tilt *= (float) pow( tiltFactor, hTonalMDCTConc->pTCI_float->upperIndex[i - 1] - hTonalMDCTConc->pTCI_float->lowerIndex[i - 1] + 1 ); + for ( l = hTonalMDCTConc->pTCI_float->upperIndex[i - 1] + 1; l < hTonalMDCTConc->pTCI_float->lowerIndex[i]; l++ ) { x = hTonalMDCTConc->lastBlockData.spectralData_float[l]; rnd = own_random( &rnd ); @@ -772,9 +772,9 @@ void TonalMDCTConceal_InsertNoise( nrgWhiteNoise += mdctSpectrum[l] * mdctSpectrum[l]; } } - tilt *= (float) pow( tiltFactor, hTonalMDCTConc->pTCI->upperIndex[hTonalMDCTConc->pTCI->numIndexes - 1] - hTonalMDCTConc->pTCI->lowerIndex[hTonalMDCTConc->pTCI->numIndexes - 1] + 1 ); + tilt *= (float) pow( tiltFactor, hTonalMDCTConc->pTCI_float->upperIndex[hTonalMDCTConc->pTCI_float->numIndexes - 1] - hTonalMDCTConc->pTCI_float->lowerIndex[hTonalMDCTConc->pTCI_float->numIndexes - 1] + 1 ); - for ( l = hTonalMDCTConc->pTCI->upperIndex[hTonalMDCTConc->pTCI->numIndexes - 1] + 1; l < crossOverFreq; l++ ) + for ( l = hTonalMDCTConc->pTCI_float->upperIndex[hTonalMDCTConc->pTCI_float->numIndexes - 1] + 1; l < crossOverFreq; l++ ) { x = hTonalMDCTConc->lastBlockData.spectralData_float[l]; rnd = own_random( &rnd ); @@ -787,7 +787,7 @@ void TonalMDCTConceal_InsertNoise( { g *= (float) sqrt( nrgNoiseInLastFrame / nrgWhiteNoise ); } - for ( l = 0; l < hTonalMDCTConc->pTCI->lowerIndex[0]; l++ ) + for ( l = 0; l < hTonalMDCTConc->pTCI_float->lowerIndex[0]; l++ ) { x = hTonalMDCTConc->lastBlockData.spectralData_float[l]; y = mdctSpectrum[l]; @@ -801,9 +801,9 @@ void TonalMDCTConceal_InsertNoise( mdctSpectrum[l] = g * y - crossfadeGain * x; } } - for ( i = 1; i < hTonalMDCTConc->pTCI->numIndexes; i++ ) + for ( i = 1; i < hTonalMDCTConc->pTCI_float->numIndexes; i++ ) { - for ( l = hTonalMDCTConc->pTCI->upperIndex[i - 1] + 1; l < hTonalMDCTConc->pTCI->lowerIndex[i]; l++ ) + for ( l = hTonalMDCTConc->pTCI_float->upperIndex[i - 1] + 1; l < hTonalMDCTConc->pTCI_float->lowerIndex[i]; l++ ) { x = hTonalMDCTConc->lastBlockData.spectralData_float[l]; y = mdctSpectrum[l]; @@ -820,16 +820,16 @@ void TonalMDCTConceal_InsertNoise( } /* initialize bins of tonal components with zero: basically not necessary, but currently the whole spectrum is rescaled in - mdct_noiseShaping() and then there would be a processing of + mdct_noiseShaping_flt() and then there would be a processing of uninitialized values */ - for ( i = 0; i < hTonalMDCTConc->pTCI->numIndexes; i++ ) + for ( i = 0; i < hTonalMDCTConc->pTCI_float->numIndexes; i++ ) { - for ( l = hTonalMDCTConc->pTCI->lowerIndex[i]; l <= hTonalMDCTConc->pTCI->upperIndex[i]; l++ ) + for ( l = hTonalMDCTConc->pTCI_float->lowerIndex[i]; l <= hTonalMDCTConc->pTCI_float->upperIndex[i]; l++ ) { mdctSpectrum[l] = 0; } } - for ( l = hTonalMDCTConc->pTCI->upperIndex[hTonalMDCTConc->pTCI->numIndexes - 1] + 1; l < crossOverFreq; l++ ) + for ( l = hTonalMDCTConc->pTCI_float->upperIndex[hTonalMDCTConc->pTCI_float->numIndexes - 1] + 1; l < crossOverFreq; l++ ) { x = hTonalMDCTConc->lastBlockData.spectralData_float[l]; y = mdctSpectrum[l]; @@ -859,7 +859,7 @@ void TonalMDCTConceal_InsertNoise( } -void TonalMDCTConceal_Apply( +void TonalMDCTConceal_Apply_ivas( TonalMDCTConcealPtr hTonalMDCTConc, /*IN */ float *mdctSpectrum, /*OUT */ const PsychoacousticParameters *psychParamsCurrent ) @@ -873,15 +873,15 @@ void TonalMDCTConceal_Apply( if ( hTonalMDCTConc->lastBlockData.blockIsValid & hTonalMDCTConc->secondLastBlockData.blockIsValid ) { - assert( hTonalMDCTConc->pTCI->numIndexes > 0 ); + assert( hTonalMDCTConc->pTCI_float->numIndexes > 0 ); nSamples = hTonalMDCTConc->nNonZeroSamples; - assert( hTonalMDCTConc->pTCI->upperIndex[hTonalMDCTConc->pTCI->numIndexes - 1] < nSamples ); + assert( hTonalMDCTConc->pTCI_float->upperIndex[hTonalMDCTConc->pTCI_float->numIndexes - 1] < nSamples ); mvr2r( hTonalMDCTConc->secondLastPowerSpectrum_float, powerSpectrum, nSamples ); /* Convert from 16 bits to 32 bits */ if ( psychParamsCurrent == NULL ) { nBands = FDNS_NPTS; - mdct_noiseShaping( powerSpectrum, hTonalMDCTConc->nSamplesCore, hTonalMDCTConc->secondLastBlockData.scaleFactors_float, nBands ); + mdct_noiseShaping_flt( powerSpectrum, hTonalMDCTConc->nSamplesCore, hTonalMDCTConc->secondLastBlockData.scaleFactors_float, nBands ); } else { @@ -891,8 +891,8 @@ void TonalMDCTConceal_Apply( v_multc( powerSpectrum + hTonalMDCTConc->nSamplesCore, hTonalMDCTConc->secondLastBlockData.scaleFactors_float[nBands - 1], powerSpectrum + hTonalMDCTConc->nSamplesCore, nSamples - hTonalMDCTConc->nSamplesCore ); - phaseDiff = hTonalMDCTConc->pTCI->phaseDiff_float; /* if multiple frame loss occurs use the phase from the last frame and continue rotating */ - pCurrentPhase = hTonalMDCTConc->pTCI->phase_currentFramePredicted_float; + phaseDiff = hTonalMDCTConc->pTCI_float->phaseDiff_float; /* if multiple frame loss occurs use the phase from the last frame and continue rotating */ + pCurrentPhase = hTonalMDCTConc->pTCI_float->phase_currentFramePredicted_float; if ( !hTonalMDCTConc->lastBlockData.blockIsConcealed ) { @@ -907,7 +907,7 @@ void TonalMDCTConceal_Apply( } /* for each index group */ - for ( i = 0; i < hTonalMDCTConc->pTCI->numIndexes; i++ ) + for ( i = 0; i < hTonalMDCTConc->pTCI_float->numIndexes; i++ ) { phaseToAdd = hTonalMDCTConc->nFramesLost_float * phaseDiff[i]; @@ -923,7 +923,7 @@ void TonalMDCTConceal_Apply( phaseToAdd += PI2; } - for ( l = hTonalMDCTConc->pTCI->lowerIndex[i]; l <= hTonalMDCTConc->pTCI->upperIndex[i]; l++ ) + for ( l = hTonalMDCTConc->pTCI_float->lowerIndex[i]; l <= hTonalMDCTConc->pTCI_float->upperIndex[i]; l++ ) { const float currentPhase = ( *pCurrentPhase++ ) + phaseToAdd; /* *pCurrentPhase and phaseToAdd are in range -EVS_PI..EVS_PI */ mdctSpectrum[l] = (float) cos( currentPhase ) * powerSpectrum[l]; @@ -937,7 +937,7 @@ void TonalMDCTConceal_Apply( } -void TonalMDCTConceal_SaveTimeSignal( +void TonalMDCTConceal_SaveTimeSignal_ivas( TonalMDCTConcealPtr hTonalMDCTConc, float *timeSignal, const int16_t nNewSamples ) @@ -957,7 +957,7 @@ void TonalMDCTConceal_SaveTimeSignal( return; } -void TonalMdctConceal_create_concealment_noise( +void TonalMdctConceal_create_concealment_noise_ivas( float concealment_noise[L_FRAME48k], CPE_DEC_HANDLE hCPE, const int16_t L_frameTCX, @@ -1012,7 +1012,7 @@ void TonalMdctConceal_create_concealment_noise( max_noise_line = crossOverFreq; if ( st->tonal_mdct_plc_active ) { - max_noise_line = max( max_noise_line, hTonalMDCTConc->pTCI->upperIndex[hTonalMDCTConc->pTCI->numIndexes - 1] + 1 ); + max_noise_line = max( max_noise_line, hTonalMDCTConc->pTCI_float->upperIndex[hTonalMDCTConc->pTCI_float->numIndexes - 1] + 1 ); } /* first lost frame is handled separately */ @@ -1043,7 +1043,7 @@ void TonalMdctConceal_create_concealment_noise( c_inv = sqrtf( 1 - hStereoMdct->lastCoh ); /* pre-compute the noise shape for later weighting of the noise spectra */ - cngNoiseLevelPtr = &hFdCngCom->cngNoiseLevel[0]; + cngNoiseLevelPtr = &hFdCngCom->cngNoiseLevel_flt[0]; inc = ( st->core > TCX_20_CORE ) ? 2 : 1; start_idx = hFdCngCom->startBand / inc; stop_idx = hFdCngCom->stopFFTbin / inc; @@ -1095,7 +1095,7 @@ void TonalMdctConceal_create_concealment_noise( if ( st->tonal_mdct_plc_active ) { - for ( i = crossOverFreq; i < max( crossOverFreq, hTonalMDCTConc->pTCI->lowerIndex[hTonalMDCTConc->pTCI->numIndexes - 1] ); ++i ) + for ( i = crossOverFreq; i < max( crossOverFreq, hTonalMDCTConc->pTCI_float->lowerIndex[hTonalMDCTConc->pTCI_float->numIndexes - 1] ); ++i ) { concealment_noise[i] *= 0.0f; } @@ -1116,7 +1116,7 @@ void TonalMdctConceal_create_concealment_noise( return; } -void TonalMdctConceal_whiten_noise_shape( +void TonalMdctConceal_whiten_noise_shape_ivas( Decoder_State *st, const int16_t L_frame, const TONALMDCTCONC_NOISE_SHAPE_WHITENING_MODE whitening_mode ) @@ -1137,7 +1137,7 @@ void TonalMdctConceal_whiten_noise_shape( inc = ( ( whitening_mode == ON_FIRST_LOST_FRAME ? st->core : st->last_core ) > TCX_20_CORE ) ? 2 : 1; start_idx = hFdCngCom->startBand / inc; stop_idx = L_frame / inc; - noiseLevelPtr = hFdCngCom->cngNoiseLevel; + noiseLevelPtr = hFdCngCom->cngNoiseLevel_flt; set_zero( whitenend_noise_shape, start_idx ); for ( int16_t j = start_idx; j < stop_idx; j++, noiseLevelPtr += inc ) @@ -1162,11 +1162,11 @@ void TonalMdctConceal_whiten_noise_shape( if ( sum_f( scfs_for_shaping, FDNS_NPTS ) > 0.0f ) { sns_shape_spectrum( whitenend_noise_shape, psychParams, scfs_for_shaping, L_frame ); - mvr2r( whitenend_noise_shape + start_idx, hFdCngCom->cngNoiseLevel, stop_idx - start_idx ); + mvr2r( whitenend_noise_shape + start_idx, hFdCngCom->cngNoiseLevel_flt, stop_idx - start_idx ); } else { - set_zero( hFdCngCom->cngNoiseLevel, stop_idx - start_idx ); + set_zero( hFdCngCom->cngNoiseLevel_flt, stop_idx - start_idx ); } pop_wmops(); diff --git a/lib_dec/tonalMDCTconcealment_fx.c b/lib_dec/tonalMDCTconcealment_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..81d81bbf828c4845481bb2e059fdbb7bf47e8e2d --- /dev/null +++ b/lib_dec/tonalMDCTconcealment_fx.c @@ -0,0 +1,1727 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#define _USE_MATH_DEFINES + +#include +#include +#include "options.h" +#include "basop_util.h" +#include "options.h" +#include "typedef.h" +#include "cnst.h" +#include "prot_fx1.h" +#include "prot_fx2.h" +#include "stat_com.h" + + +/************************************************************************************ + * local functions + ************************************************************************************/ + +static void CalcMDXT(const TonalMDCTConcealPtr hTonalMDCTConc, const Word16 type, const Word16 * timeSignal, Word32 * mdxtOutput, Word16 * mdxtOutput_e); +static void CalcPowerSpec(const Word32 * mdctSpec, const Word16 mdctSpec_exp, const Word32 * mdstSpec, const Word16 mdstSpec_exp, const Word16 nSamples, const Word16 floorPowerSpectrum, Word32 * powerSpec, Word16 * powerSpec_exp); +static void CalcPowerSpecAndDetectTonalComponents(TonalMDCTConcealPtr const hTonalMDCTConc, Word32 secondLastMDST[], Word16 secondLastMDST_exp, Word32 secondLastMDCT[], Word16 secondLastMDCT_exp, Word32 const pitchLag); +static void FindPhases(TonalMDCTConcealPtr const hTonalMDCTConc, Word32 secondLastMDCT[], Word32 secondLastMDST[], Word16 diff_exp); +static void FindPhaseDifferences(TonalMDCTConcealPtr const hTonalMDCTConc, Word32 powerSpectrum[]); + + +/*******************************************************/ +/*-------------- public functions -------------------- */ +/*******************************************************/ + +ivas_error TonalMDCTConceal_Init( + TonalMDCTConcealPtr hTonalMDCTConc, + const Word16 nSamples, + const Word16 nSamplesCore, + const Word16 nScaleFactors, + TCX_CONFIG_HANDLE hTcxCfg /* TCX config */ +) +{ + test(); + IF (GT_16(nSamples,L_FRAME_MAX)||GT_16(nScaleFactors,FDNS_NPTS)) + { + assert(nSamples <= L_FRAME_MAX); + assert(nScaleFactors <= FDNS_NPTS); + return (IVAS_ERROR(IVAS_ERR_INTERNAL, "TonalMDCT FEC: Number of samples larger than max. block size\n")); + } + assert((hTonalMDCTConc->nScaleFactors == nScaleFactors) || (hTonalMDCTConc->nSamples != nSamples)); /* If nSamples doesn't change then also nScaleFactors must stay the same */ + + hTonalMDCTConc->tcx_cfg = hTcxCfg; + + hTonalMDCTConc->lastBlockData.spectralData = hTonalMDCTConc->spectralDataBuffers[0]; + move16(); + hTonalMDCTConc->secondLastBlockData.spectralData = hTonalMDCTConc->spectralDataBuffers[1]; + move16(); + hTonalMDCTConc->secondLastPowerSpectrum = hTonalMDCTConc->secondLastBlockData.spectralData; + move16(); + + hTonalMDCTConc->lastBlockData.scaleFactors = hTonalMDCTConc->scaleFactorsBuffers[0]; + move16(); + hTonalMDCTConc->secondLastBlockData.scaleFactors = hTonalMDCTConc->scaleFactorsBuffers[1]; + move16(); + hTonalMDCTConc->lastBlockData.scaleFactors_exp = hTonalMDCTConc->scaleFactorsBuffers_exp[0]; + move16(); + hTonalMDCTConc->secondLastBlockData.scaleFactors_exp = hTonalMDCTConc->scaleFactorsBuffers_exp[1]; + move16(); + + hTonalMDCTConc->lastBlockData.blockIsValid = 0; + move16(); + hTonalMDCTConc->secondLastBlockData.blockIsValid = 0; + move16(); + hTonalMDCTConc->nSamples = 0; + move16(); + hTonalMDCTConc->nScaleFactors = 0; + move16(); + + hTonalMDCTConc->lastBlockData.blockIsConcealed = 0; + move16(); + hTonalMDCTConc->secondLastBlockData.blockIsConcealed = 0; + move16(); + + hTonalMDCTConc->pTCI_fix = (TonalComponentsInfo_fix *)hTonalMDCTConc->timeDataBuffer; + move16(); + + + hTonalMDCTConc->lastPitchLag = L_deposit_l(0); + + IF (NE_16(hTonalMDCTConc->nSamples,nSamples)) + { + hTonalMDCTConc->secondLastBlockData.blockIsValid = 0; + move16(); + hTonalMDCTConc->lastBlockData.blockIsValid = 0; + move16(); + } + + hTonalMDCTConc->nSamples = nSamples; + move16(); + hTonalMDCTConc->nSamplesCore = nSamplesCore; + move16(); + + hTonalMDCTConc->nScaleFactors = nScaleFactors; + move16(); +#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT + PMTE() + set_zero(hTonalMDCTConc->scaleFactorsBackground, FDNS_NPTS); + PsychoacousticParameters_Init(INT_FS_16k, L_FRAME16k, 64, 1, 1, &hTonalMDCTConc->psychParamsTCX20); + PsychoacousticParameters_Init(INT_FS_16k, L_FRAME16k / 2, 64, 0, 1, &hTonalMDCTConc->psychParamsTCX10); + hTonalMDCTConc->psychParams = NULL; + hTonalMDCTConc->scf_fadeout = 1.0f; + hTonalMDCTConc->last_block_nrg = 0.0f; + hTonalMDCTConc->curr_noise_nrg = 0.0f; + hTonalMDCTConc->faded_signal_nrg = 0.0f; + +#endif + /* Offset the pointer to the end of buffer, so that pTCI_fix is not destroyed when + new time samples are stored in lastPcmOut */ move16(); + move16(); + /* just the second half of the second last pcm output is needed */ + hTonalMDCTConc->secondLastPcmOut = &hTonalMDCTConc->timeDataBuffer[sub((3*L_FRAME_MAX)/2,3*(s_min(L_FRAME_MAX, nSamples))/2)]; + hTonalMDCTConc->lastPcmOut = &hTonalMDCTConc->timeDataBuffer[sub((3*L_FRAME_MAX)/2, s_min(L_FRAME_MAX, nSamples)) ]; + + /* If the second last frame was lost, we reuse saved TonalComponentsInfo and don't update pcm buffers */ +#if 1 + //TO do enable when only fix code is present currently disabled due to float array in structure + assert(sizeof(*hTonalMDCTConc->pTCI_fix) <= (hTonalMDCTConc->lastPcmOut-hTonalMDCTConc->timeDataBuffer)*sizeof(hTonalMDCTConc->timeDataBuffer[0])); +#endif + return IVAS_ERR_OK; +} + +void TonalMDCTConceal_SaveFreqSignal( + TonalMDCTConcealPtr hTonalMDCTConc, + const Word32 *mdctSpectrum, + const Word16 mdctSpectrum_exp, + Word16 nNewSamples, + Word16 nNewSamplesCore, + const Word16 *scaleFactors, + const Word16 *scaleFactors_exp, + const Word16 gain_tcx_exp +#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT + ,const int16_t infoIGFStartLine +#endif +) +{ + Word16 * temp; + Word16 nOldSamples, tmp_exp, s, i, max_exp; + + + assert(nNewSamples > 0 && nNewSamples <= 2*L_FRAME_MAX); + + /* Avoid overwriting hTonalMDCTConc->secondLastPowerSpectrum stored in spectralData, + because it is needed if the second last and the current frame are lost + and concealed using the Tonal MDCT PLC */ test(); + IF (!hTonalMDCTConc->lastBlockData.tonalConcealmentActive || NE_16(hTonalMDCTConc->lastBlockData.nSamples,nNewSamples)) + { + IF (LE_16(nNewSamples,L_FRAME_MAX)) + { + /* Shift the buffers */ + temp = hTonalMDCTConc->secondLastBlockData.spectralData; /* Save the pointer */ move16(); + hTonalMDCTConc->secondLastBlockData.spectralData = hTonalMDCTConc->lastBlockData.spectralData; + move16(); + hTonalMDCTConc->lastBlockData.spectralData = temp; + move16(); + + tmp_exp = hTonalMDCTConc->secondLastBlockData.spectralData_exp; /* Save the pointer */ move16(); + hTonalMDCTConc->secondLastBlockData.spectralData_exp = hTonalMDCTConc->lastBlockData.spectralData_exp; + move16(); + hTonalMDCTConc->lastBlockData.spectralData_exp = tmp_exp; + move16(); + + tmp_exp = hTonalMDCTConc->secondLastBlockData.gain_tcx_exp; /* Save the pointer */ move16(); + hTonalMDCTConc->secondLastBlockData.gain_tcx_exp = hTonalMDCTConc->lastBlockData.gain_tcx_exp; + move16(); + hTonalMDCTConc->lastBlockData.gain_tcx_exp = tmp_exp; + move16(); + + tmp_exp = hTonalMDCTConc->secondLastBlockData.scaleFactors_max_e; /* Save the pointer */ move16(); + hTonalMDCTConc->secondLastBlockData.scaleFactors_max_e = hTonalMDCTConc->lastBlockData.scaleFactors_max_e; + move16(); + hTonalMDCTConc->lastBlockData.scaleFactors_max_e = tmp_exp; + move16(); + + temp = hTonalMDCTConc->secondLastBlockData.scaleFactors; + move16(); + hTonalMDCTConc->secondLastBlockData.scaleFactors = hTonalMDCTConc->lastBlockData.scaleFactors; + move16(); + hTonalMDCTConc->lastBlockData.scaleFactors = temp; + move16(); + + temp = hTonalMDCTConc->secondLastBlockData.scaleFactors_exp; + move16(); + hTonalMDCTConc->secondLastBlockData.scaleFactors_exp = hTonalMDCTConc->lastBlockData.scaleFactors_exp; + move16(); + hTonalMDCTConc->lastBlockData.scaleFactors_exp = temp; + move16(); + } + ELSE + { + hTonalMDCTConc->lastBlockData.spectralData = hTonalMDCTConc->spectralDataBuffers[0]; + move16(); + hTonalMDCTConc->secondLastBlockData.spectralData = hTonalMDCTConc->spectralDataBuffers[1]; + move16(); + hTonalMDCTConc->lastBlockData.scaleFactors = hTonalMDCTConc->scaleFactorsBuffers[0]; + move16(); + hTonalMDCTConc->secondLastBlockData.scaleFactors = hTonalMDCTConc->scaleFactorsBuffers[1]; + move16(); + hTonalMDCTConc->lastBlockData.scaleFactors_exp = hTonalMDCTConc->scaleFactorsBuffers_exp[0]; + move16(); + hTonalMDCTConc->secondLastBlockData.scaleFactors_exp = hTonalMDCTConc->scaleFactorsBuffers_exp[1]; + move16(); + } + + nOldSamples = hTonalMDCTConc->lastBlockData.nSamples; + move16(); + hTonalMDCTConc->lastBlockData.nSamples = nNewSamples; + move16(); + hTonalMDCTConc->secondLastBlockData.nSamples = nOldSamples; + move16(); + + nOldSamples = hTonalMDCTConc->lastBlockData.nSamplesCore; + move16(); + hTonalMDCTConc->lastBlockData.nSamplesCore = nNewSamplesCore; + move16(); + hTonalMDCTConc->secondLastBlockData.nSamplesCore = nOldSamples; + move16(); + } + + test(); + IF ((nNewSamples > 0) && (LE_16(nNewSamples,2*L_FRAME_MAX))) + { +#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT + int16_t i; + PMTE() + hTonalMDCTConc->last_block_nrg = 0.0f; + for (i = 0; i < infoIGFStartLine; i++) + { + hTonalMDCTConc->lastBlockData.spectralData[i] = mdctSpectrum[i]; + hTonalMDCTConc->last_block_nrg += mdctSpectrum[i] * mdctSpectrum[i]; + } + for (; i < nNewSamples; i++) + { + hTonalMDCTConc->lastBlockData.spectralData[i] = mdctSpectrum[i]; + } +#else + /* Store new data */ + s = getScaleFactor32(mdctSpectrum, nNewSamples); + + /*Copy(scaleFactors_exp, hTonalMDCTConc->lastBlockData.scaleFactors_exp, hTonalMDCTConc->nScaleFactors);*/ + max_exp = 0; + FOR (i = 0; i < hTonalMDCTConc->nScaleFactors; i++) + { + hTonalMDCTConc->lastBlockData.scaleFactors_exp[i] = scaleFactors_exp[i]; + move16(); + max_exp = s_max(max_exp, scaleFactors_exp[i]); + } + + /*s = sub(s, max_exp);*/ + hTonalMDCTConc->lastBlockData.scaleFactors_max_e = max_exp; + + FOR (i = 0; i < nNewSamples; i++) + { + hTonalMDCTConc->lastBlockData.spectralData[i] = extract_h(L_shl(mdctSpectrum[i], s)); + move16(); + } + hTonalMDCTConc->lastBlockData.spectralData_exp = sub(mdctSpectrum_exp,s); +#endif + move16(); + hTonalMDCTConc->lastBlockData.gain_tcx_exp = gain_tcx_exp; + + Copy(scaleFactors, hTonalMDCTConc->lastBlockData.scaleFactors, hTonalMDCTConc->nScaleFactors); + } + return; +} + +TONALMDCTCONCEAL_ERROR TonalMDCTConceal_UpdateState(TonalMDCTConcealPtr hTonalMDCTConc, + Word16 nNewSamples, + Word32 pitchLag, + Word16 badBlock, + Word8 tonalConcealmentActive + ) +{ + Word8 newBlockIsValid; + + assert(!(!badBlock && tonalConcealmentActive)); + + IF (badBlock) + { + newBlockIsValid = hTonalMDCTConc->lastBlockData.blockIsValid; + move16(); + } + ELSE + { + newBlockIsValid = 0; + move16(); + test(); + if((LE_16(nNewSamples,2*L_FRAME_MAX))&&(nNewSamples>0)) + { + newBlockIsValid = 1; + move16(); + } + } + + /* Shift old state */ move16(); + move16(); + move16(); + hTonalMDCTConc->secondLastBlockData.blockIsConcealed = hTonalMDCTConc->lastBlockData.blockIsConcealed; + hTonalMDCTConc->secondLastBlockData.blockIsValid = hTonalMDCTConc->lastBlockData.blockIsValid; + hTonalMDCTConc->secondLastBlockData.tonalConcealmentActive = hTonalMDCTConc->lastBlockData.tonalConcealmentActive; + + /* Store new state */ move16(); + move16(); + move16(); + hTonalMDCTConc->lastBlockData.blockIsConcealed = badBlock; + hTonalMDCTConc->lastBlockData.blockIsValid = newBlockIsValid; + hTonalMDCTConc->lastBlockData.tonalConcealmentActive = tonalConcealmentActive; + + hTonalMDCTConc->lastPitchLag = pitchLag; + move32(); + + return TONALMDCTCONCEAL_OK; +} +static void FindPhases( /* o: currenc phase [-pi;pi] 2Q13 */ + TonalMDCTConcealPtr const hTonalMDCTConc, /* i: pointer to internal structure */ + Word32 secondLastMDCT[], /* i: MDST spectrum data */ + Word32 secondLastMDST[], /* i: MDCT spectrum data */ + Word16 diff_exp) /* i: exp_MDST - exp_MDCT */ +{ + Word16 i; + Word16 l; + Word16 *pCurrentPhase; + + + + pCurrentPhase = hTonalMDCTConc->pTCI_fix->phase_currentFramePredicted; + /* for each index/index group */ + FOR( i = 0; i < hTonalMDCTConc->pTCI_fix->numIndexes; i++) + { + FOR (l = hTonalMDCTConc->pTCI_fix->lowerIndex[i]; l <= hTonalMDCTConc->pTCI_fix->upperIndex[i]; l++) + { + /* in contrast to the float code, the parameter secondLastMDST[l] + needs not to be negated - due to a different implementation of + the MDST */ + *pCurrentPhase++ = BASOP_util_atan2(secondLastMDST[l], secondLastMDCT[l], diff_exp); + move16(); + } + } + +} + +#define BANDWIDTH 7.0f +#define G 789516047l/*1.0/(2*1.36) Q31*/ +#define MAXRATIO 22938/*44.8f Q9*/ /* Maximum ratio |ODFT[k-1]|/|ODFT[k+1]| is 16.5 dB, that is maximum ratio (for fractional = 0) is (cos(PI/bandwidth)/cos(3PI/bandwidth))^1.36 */ +#define MM 1934815907 /* FL2WORD32(cos(EVS_PI/BANDWIDTH)); */ +#define SS 29166 /* FL2WORD16(cos((3*EVS_PI)/BANDWIDTH)*4); Q17*/ +#define N 931758243 /* FL2WORD32(sin(EVS_PI/BANDWIDTH)); */ +#define J 31946 /* FL2WORD16(sin((3*EVS_PI)/BANDWIDTH)); */ + +static void FindPhaseDifferences( /* o: Phase difference [-pi;pi] 2Q13*/ + TonalMDCTConcealPtr const hTonalMDCTConc, /* i: Pointer to internal structure */ + Word32 powerSpectrum[]) /* i: Power spectrum data */ +{ + Word16 i, k; + Word16 * phaseDiff; + Word16 fractional, sf, sfn, sfd; + Word16 divi, s, j; + Word32 a, Q, L_tmp, m, n; + + s = SS; + move16(); + j = J; + move16(); + + phaseDiff = hTonalMDCTConc->pTCI_fix->phaseDiff; + + FOR (i = 0; i < hTonalMDCTConc->pTCI_fix->numIndexes; i++) + { + m = MM; + move16(); + n = N; + move16(); + + k = hTonalMDCTConc->pTCI_fix->indexOfTonalPeak[i]; + move16(); + + IF (GE_32(Mpy_32_16_1(powerSpectrum[k-1],512/*1.0f Q9*/),Mpy_32_16_1(powerSpectrum[k+1], MAXRATIO))) + { + phaseDiff[i] = 0; /*(float)tan(0.0f*EVS_PI/bandwidth);*/ move16(); + if (s_and(k, 1) != 0) + { + phaseDiff[i] = -12868/*-EVS_PI 3Q12*/; + } + } + ELSE + { + IF (GE_32(Mpy_32_16_1(powerSpectrum[k+1],512/*1.0f Q9*/),Mpy_32_16_1(powerSpectrum[k-1], MAXRATIO))) + { + phaseDiff[i] = 12868/*EVS_PI 3Q12*/; /*(float)tan(2.0f*PI/bandwidth);*/ move16(); + if (s_and(k, 1) != 0) + { + phaseDiff[i] = 0/*0 Q13*/; /*2Q13*/ + } + } + ELSE + { + /*Q = (float)pow(odft_left/odft_right, G); + a = (m - Q * s) / (n + Q * j); + phaseDiff[i] = (float)atan(a) * (bandwidth/2.0f);*/ + /*max divi=44.8 & sf=6*/ + divi = BASOP_Util_Divide3232_uu_1616_Scale(powerSpectrum[k-1],powerSpectrum[k+1], &sf); + Q = BASOP_Util_fPow(L_deposit_h(divi), sf, G, 0, &sf); + L_tmp = Mpy_32_16_1(Q,s); + sfn = sub(sf, 2); + + if (sfn > 0) + { + m = L_shr(m, sfn); + } + IF(sfn < 0) + { + L_tmp = L_shl(L_tmp, sfn); + sfn = 0; + } + + a = L_sub(m, L_tmp); /*sf*/ + + L_tmp = Mpy_32_16_1(Q,j); + IF(sf >= 0) + { + L_tmp = L_shr(L_tmp, 1); + sfd = add(sf,1); + n = L_shr(n,sfd); + } + ELSE + { + sfd = 0; + L_tmp = L_shl(L_tmp, sf); + } + + L_tmp = L_add(n,L_tmp); + fractional = BASOP_util_atan2(a, L_tmp, sub(sfn,sfd)); /*2Q13*/ + L_tmp = L_mult(fractional, 28672/*BANDWIDTH/2.0f Q13*/); /*2Q13*2Q13=4Q27*/ move16(); + + /* fractional is in the range 0..+pi */ + /* we need to stay in the range -2pi..+2pi */ + if(EQ_16(s_and(k,3),1)) + { + L_tmp = L_add(L_tmp, 421657440l/*+1*EVS_PI Q27*/); + } + if(EQ_16(s_and(k,3),2)) + { + L_tmp = L_sub(L_tmp, 843314880l/*+2*EVS_PI=-2*EVS_PI Q27*/); + } + if(EQ_16(s_and(k,3),3)) + { + L_tmp = L_sub(L_tmp, 421657440l/*+3*EVS_PI=-1*EVS_PI Q27*/); + } + phaseDiff[i] = round_fx(L_shl(L_tmp,1)); /*3Q12*/ + } + } + } +} + +static void CalcPowerSpecAndDetectTonalComponents( + TonalMDCTConcealPtr const hTonalMDCTConc, + Word32 secondLastMDST[], + Word16 secondLastMDST_exp, + Word32 secondLastMDCT[], + Word16 secondLastMDCT_exp, + Word32 const pitchLag +#ifdef IVAS_CODE_MDCT_GSHAPE + ,const PsychoacousticParameters* psychParamsCurrent +#endif +) +{ + Word16 nSamples; + Word16 i; + Word16 floorPowerSpectrum; /* Minimum significant value of a spectral line in the power spectrum */ + Word32 powerSpectrum[L_FRAME_MAX]; + Word16 invScaleFactors[FDNS_NPTS]; + Word16 invScaleFactors_exp[FDNS_NPTS]; + Word16 powerSpectrum_exp, tmp_exp, old_exp; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + + + nSamples = hTonalMDCTConc->nNonZeroSamples; + move16(); + + /* It is taken into account that the MDCT is not normalized. */ + floorPowerSpectrum/*Q0*/ = extract_l(Mpy_32_16_1(L_mult0(hTonalMDCTConc->nSamples,hTonalMDCTConc->nSamples),82)); /*1/400 = 82 Q15*/ + powerSpectrum_exp = 0; + move16(); + + CalcPowerSpec(secondLastMDCT, + secondLastMDCT_exp, + secondLastMDST, + secondLastMDST_exp, + nSamples, + floorPowerSpectrum, + powerSpectrum, + &powerSpectrum_exp); + + /* This setting to minimal level is required because the power spectrum is used in the threshold adaptation using the pitch up to hTonalMDCTConc->nSamples. */ + set32_fx(powerSpectrum+nSamples, floorPowerSpectrum, sub(hTonalMDCTConc->nSamples, nSamples)); + /* this setting to zero is needed since the FDNS needs to be called + with hTonalMDCTConc->nSamplesCore; it relevant only for nb; it has no effect + to the output, but memory checker may complain otherwise due to the + usage of uninitialized values */ + IF ( GT_16(hTonalMDCTConc->nSamplesCore, hTonalMDCTConc->nSamples)) + { + set32_fx(powerSpectrum+hTonalMDCTConc->nSamples, 0, sub(hTonalMDCTConc->nSamplesCore, hTonalMDCTConc->nSamples)); + } + + DetectTonalComponents(hTonalMDCTConc->pTCI_fix->indexOfTonalPeak, + hTonalMDCTConc->pTCI_fix->lowerIndex, + hTonalMDCTConc->pTCI_fix->upperIndex, + &hTonalMDCTConc->pTCI_fix->numIndexes, + hTonalMDCTConc->lastPitchLag, + pitchLag, + hTonalMDCTConc->lastBlockData.spectralData, + add(hTonalMDCTConc->lastBlockData.spectralData_exp,hTonalMDCTConc->lastBlockData.gain_tcx_exp), + hTonalMDCTConc->lastBlockData.scaleFactors, + hTonalMDCTConc->lastBlockData.scaleFactors_exp, + hTonalMDCTConc->lastBlockData.scaleFactors_max_e, + powerSpectrum, + nSamples, + hTonalMDCTConc->nSamplesCore, + floorPowerSpectrum); + FindPhases(hTonalMDCTConc, secondLastMDCT, secondLastMDST, sub(secondLastMDST_exp,secondLastMDCT_exp)); + + FindPhaseDifferences(hTonalMDCTConc, powerSpectrum); + + IF (hTonalMDCTConc->pTCI_fix->numIndexes > 0) + { + + hTonalMDCTConc->secondLastPowerSpectrum = hTonalMDCTConc->secondLastBlockData.spectralData; + + /*sqrtFLOAT(powerSpectrum, powerSpectrum, nSamples);*/ + old_exp = powerSpectrum_exp; + powerSpectrum_exp = mult_r(sub(powerSpectrum_exp,2), 1 << 14); /*remove 2 bits of headroom from CalcPowerSpec*/ + FOR (i = 0; i < nSamples; i++) + { + tmp_exp = old_exp; + powerSpectrum[i] = Sqrt32(powerSpectrum[i], &tmp_exp); + powerSpectrum[i] = L_shr(powerSpectrum[i], sub(powerSpectrum_exp, tmp_exp)); + move32(); + } + + FOR (i = 0; i < hTonalMDCTConc->nScaleFactors; i++) + { + move16(); + move16(); + invScaleFactors_exp[i] = hTonalMDCTConc->secondLastBlockData.scaleFactors_exp[i]; + invScaleFactors[i] = Inv16(hTonalMDCTConc->secondLastBlockData.scaleFactors[i], &invScaleFactors_exp[i]); + } + + + /* here mdct_shaping() is intentionally used rather then mdct_shaping_16() */ +#ifdef IVAS_CODE_MDCT_GSHAPE + IF (psychParamsCurrent == NULL) +#endif + { + mdct_shaping(powerSpectrum, hTonalMDCTConc->nSamplesCore, invScaleFactors, invScaleFactors_exp); + } +#ifdef IVAS_CODE_MDCT_GSHAPE + ELSE + { +PMTE() + sns_shape_spectrum(powerSpectrum, psychParamsCurrent, invScaleFactors, hTonalMDCTConc->nSamplesCore); + nBands = psychParamsCurrent->nBands; + } +#endif + FOR (i = hTonalMDCTConc->nSamplesCore; i < nSamples; i++) + { + powerSpectrum[i] = L_shl(Mpy_32_16_1(powerSpectrum[i], invScaleFactors[FDNS_NPTS-1]), invScaleFactors_exp[FDNS_NPTS-1]); + move32(); + } + + /* 16 bits are now enough for storing the power spectrum */ + FOR (i = 0; i < nSamples; i++) + { +#ifdef BASOP_NOGLOB + hTonalMDCTConc->secondLastPowerSpectrum[i] = round_fx_o(powerSpectrum[i], &Overflow); +#else + hTonalMDCTConc->secondLastPowerSpectrum[i] = round_fx(powerSpectrum[i]); +#endif + } + + powerSpectrum_exp = sub(powerSpectrum_exp, hTonalMDCTConc->secondLastBlockData.gain_tcx_exp); + hTonalMDCTConc->secondLastPowerSpectrum_exp = powerSpectrum_exp; + move16(); + } +} + + +static void CalcMDXT( + const TonalMDCTConcealPtr hTonalMDCTConc, + const Word16 type, + const Word16 * timeSignal, + Word32 * mdxtOutput, + Word16 * mdxtOutput_e +) +{ + Word16 windowedTimeSignal[L_FRAME_PLUS+2*L_MDCT_OVLP_MAX]; + Word16 left_overlap, right_overlap, L_frame; + + L_frame = hTonalMDCTConc->nSamples; + move16(); + + WindowSignal(hTonalMDCTConc->tcx_cfg, hTonalMDCTConc->tcx_cfg->tcx_offsetFB, FULL_OVERLAP, + FULL_OVERLAP, &left_overlap, &right_overlap, timeSignal, &L_frame, windowedTimeSignal, 1, 1); + + IF (type == 0) + { + TCX_MDST(windowedTimeSignal, mdxtOutput, mdxtOutput_e, left_overlap, + sub(L_frame, shr(add(left_overlap, right_overlap), 1)), right_overlap, EVS_MONO); + } + ELSE + { + TCX_MDCT(windowedTimeSignal, mdxtOutput, mdxtOutput_e, left_overlap, + sub(L_frame, shr(add(left_overlap, right_overlap), 1)), right_overlap, EVS_MONO); + } +} + +void TonalMDCTConceal_Detect( + const TonalMDCTConcealPtr hTonalMDCTConc, + const Word32 pitchLag, + Word16 * numIndices +#ifdef IVAS_CODE_MDCT_GSHAPE + ,const PsychoacousticParameters* psychParamsCurrent +#endif +) +{ + Word32 secondLastMDST[L_FRAME_MAX]; + Word32 secondLastMDCT[L_FRAME_MAX]; + Word16 secondLastMDCT_exp; + Word32 * powerSpectrum = secondLastMDST; + Word16 i, powerSpectrum_exp, secondLastMDST_exp, s; + Word16 nSamples; + + + nSamples = hTonalMDCTConc->nSamples; + move16(); + secondLastMDST_exp = 16; /*time signal Q-1*/ + secondLastMDCT_exp = 16; /*time signal Q-1*/ + test(); + test(); + test(); + test(); + test(); + IF (hTonalMDCTConc->lastBlockData.blockIsValid && hTonalMDCTConc->secondLastBlockData.blockIsValid + && (EQ_16(hTonalMDCTConc->lastBlockData.nSamples,nSamples) ) && (EQ_16(hTonalMDCTConc->secondLastBlockData.nSamples,nSamples) ) + && (!hTonalMDCTConc->secondLastBlockData.blockIsConcealed || hTonalMDCTConc->secondLastBlockData.tonalConcealmentActive || (pitchLag != 0)) ) + { + /* Safety if the second last frame was concealed and tonal concealment was inactive */ + + IF (hTonalMDCTConc->lastBlockData.blockIsConcealed == 0) + { + IF (hTonalMDCTConc->secondLastBlockData.tonalConcealmentActive == 0) + { + CalcMDXT(hTonalMDCTConc, 0, hTonalMDCTConc->secondLastPcmOut, secondLastMDST, &secondLastMDST_exp); + CalcMDXT(hTonalMDCTConc, 1, hTonalMDCTConc->secondLastPcmOut, secondLastMDCT, &secondLastMDCT_exp); + hTonalMDCTConc->nNonZeroSamples = 0; + FOR (i = 0; i < hTonalMDCTConc->nSamples; i++) + { + if (hTonalMDCTConc->secondLastBlockData.spectralData[i] != 0) + { + hTonalMDCTConc->nNonZeroSamples = i; + move16(); + } + } + + /* 23 is the maximum length of the MA filter in getEnvelope */ + hTonalMDCTConc->nNonZeroSamples = s_min(hTonalMDCTConc->nSamples, add(hTonalMDCTConc->nNonZeroSamples, 23)); + move16(); + nSamples = hTonalMDCTConc->nNonZeroSamples; + move16(); + + s = getScaleFactor32(secondLastMDST, nSamples); + + FOR (i = 0; i < nSamples; i++) + { + secondLastMDST[i] = L_shl(secondLastMDST[i], s); + move32(); + } + secondLastMDST_exp = sub(secondLastMDST_exp, s); + move16(); + s = getScaleFactor32(secondLastMDCT, nSamples); + + FOR (i = 0; i < nSamples; i++) + { + secondLastMDCT[i] = L_shl(secondLastMDCT[i], s); + move32(); + } + secondLastMDCT_exp = sub(secondLastMDCT_exp, s); + move16(); + CalcPowerSpecAndDetectTonalComponents(hTonalMDCTConc, secondLastMDST, secondLastMDST_exp, secondLastMDCT, secondLastMDCT_exp, pitchLag); + } + ELSE + { + /* If the second last frame was also lost, it is expected that pastTimeSignal could hold a bit different signal (e.g. including fade-out) from the one stored in TonalMDCTConceal_SaveTimeSignal. */ + /* That is why we reuse the already stored information about the concealed spectrum in the second last frame */ +#ifdef IVAS_CODE_MDCT_GSHAPE + IF (psychParamsCurrent == NULL) +#endif + { + nSamples = hTonalMDCTConc->nNonZeroSamples; + move16(); + mdct_shaping_16(hTonalMDCTConc->secondLastPowerSpectrum, hTonalMDCTConc->nSamplesCore, nSamples, + hTonalMDCTConc->secondLastBlockData.scaleFactors, hTonalMDCTConc->secondLastBlockData.scaleFactors_exp, + hTonalMDCTConc->secondLastBlockData.scaleFactors_max_e, powerSpectrum); + } +#ifdef IVAS_CODE_MDCT_GSHAPE + ELSE + { + sns_shape_spectrum(powerSpectrum, psychParamsCurrent, hTonalMDCTConc->secondLastBlockData.scaleFactors, hTonalMDCTConc->nSamplesCore); + nBands = psychParamsCurrent->nBands; + } +#endif + powerSpectrum_exp = getScaleFactor32(powerSpectrum, nSamples); + powerSpectrum_exp = sub(powerSpectrum_exp, 3); /*extra 3 bits of headroom for MA filter in getEnvelope*/ + + /* multFLOAT(powerSpectrum, powerSpectrum, powerSpectrum, nSamples); */ + FOR(i = 0; i < nSamples; i++) + { + Word32 const t = L_shl(powerSpectrum[i], powerSpectrum_exp); + powerSpectrum[i] = Mpy_32_32(t, t); + move32(); + } + + RefineTonalComponents(hTonalMDCTConc->pTCI_fix->indexOfTonalPeak, + hTonalMDCTConc->pTCI_fix->lowerIndex, + hTonalMDCTConc->pTCI_fix->upperIndex, + hTonalMDCTConc->pTCI_fix->phaseDiff, + hTonalMDCTConc->pTCI_fix->phase_currentFramePredicted, + &hTonalMDCTConc->pTCI_fix->numIndexes, + hTonalMDCTConc->lastPitchLag, + pitchLag, + hTonalMDCTConc->lastBlockData.spectralData, + add(hTonalMDCTConc->lastBlockData.spectralData_exp,hTonalMDCTConc->lastBlockData.gain_tcx_exp), + hTonalMDCTConc->lastBlockData.scaleFactors, + hTonalMDCTConc->lastBlockData.scaleFactors_exp, + hTonalMDCTConc->lastBlockData.scaleFactors_max_e, + powerSpectrum, + nSamples, + hTonalMDCTConc->nSamplesCore, + extract_l(Mpy_32_16_1(L_mult0(hTonalMDCTConc->nSamples,hTonalMDCTConc->nSamples),82))); /* floorPowerSpectrum */ + + } + } + } + ELSE + { + hTonalMDCTConc->pTCI_fix->numIndexes = 0; + move16(); + } + + *numIndices = hTonalMDCTConc->pTCI_fix->numIndexes; + move16(); + + + return ; +} + +void TonalMDCTConceal_InsertNoise( + const TonalMDCTConcealPtr hTonalMDCTConc, /*IN */ + Word32* mdctSpectrum, /*OUT*/ + Word16* mdctSpectrum_exp, /*OUT*/ + const Word8 tonalConcealmentActive, + Word16* pSeed, /*IN/OUT*/ + const Word16 tiltCompFactor, + Word16 crossfadeGain, +#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT + const Word16concealment_noise[L_FRAME48k], + const float cngLevelBackgroundTrace_bfi, +#endif + const Word16 crossOverFreq +) +{ + Word16 i, ld, fac; + Word16 rnd, exp, exp_last, exp_noise, inv_samples, inv_exp; + Word16 g, tiltFactor, tilt, tmp; + Word32 nrgNoiseInLastFrame, nrgWhiteNoise, L_tmp, L_tmp2; +#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT + float last_block_nrg_correct; +#endif + + g = sub(32767/*1.0f Q15*/,crossfadeGain); + + rnd = 1977; + move16(); + if (hTonalMDCTConc->lastBlockData.blockIsConcealed) + { + rnd = *pSeed; + move16(); + } +#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT + /* based on what is done in tcx_noise_filling() */ + /* always initialize these to avoid compiler warnings */ + tiltFactor = (float)pow(max(0.375f, tiltCompFactor), 1.0f / hTonalMDCTConc->lastBlockData.nSamples); + tilt = 1.0f; + nrgNoiseInLastFrame = 0.0f; + nrgWhiteNoise = 0.0f; + hTonalMDCTConc->faded_signal_nrg = 0.0f; + last_block_nrg_correct = 0.0f; +#endif + IF (hTonalMDCTConc->lastBlockData.blockIsValid == 0) + { + /* may just become active if the very first frame is lost */ + set32_fx(mdctSpectrum, 0, hTonalMDCTConc->nSamples); + *mdctSpectrum_exp = SPEC_EXP_DEC; + } +#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT + else if (concealment_noise != NULL) + { + if (!tonalConcealmentActive) + { + /* if fadeout has not started yet, only apply sign scrambling */ + if (crossfadeGain == 1.0f) + { + for (i = 0; i < crossOverFreq; i++) + { + if (concealment_noise[i] > 0) + { + mdctSpectrum[i] = hTonalMDCTConc->lastBlockData.spectralData[i]; + } + else + { + mdctSpectrum[i] = -hTonalMDCTConc->lastBlockData.spectralData[i]; + } + } + + for (l = crossOverFreq; l < hTonalMDCTConc->lastBlockData.nSamples; l++) + { + mdctSpectrum[l] = hTonalMDCTConc->lastBlockData.spectralData[l]; + } + } + /* actual fadeout is done in this case */ + else + { + g *= (float)sqrt(cngLevelBackgroundTrace_bfi / hTonalMDCTConc->curr_noise_nrg); + + for (i = 0; i < crossOverFreq; i++) + { + x = hTonalMDCTConc->lastBlockData.spectralData[i]; + y = concealment_noise[i]; + + if (y > 0) + { + mdctSpectrum[i] = g * y + crossfadeGain * x; + } + else + { + mdctSpectrum[i] = g * y - crossfadeGain * x; + } + + hTonalMDCTConc->faded_signal_nrg += mdctSpectrum[i] * mdctSpectrum[i]; + } + for (l = crossOverFreq; l < hTonalMDCTConc->lastBlockData.nSamples; l++) + { + mdctSpectrum[l] = 0.0f; + } + } + } + else + { + assert(hTonalMDCTConc->pTCI_fix->numIndexes > 0); + + /* initialize bins of tonal components with zero: basically not + necessary, but currently the whole spectrum is rescaled in + mdct_noiseShaping() and then there would be a processing of + uninitialized values */ + for (i = 0; i < hTonalMDCTConc->pTCI_fix->numIndexes; i++) + { + for (l = hTonalMDCTConc->pTCI_fix->lowerIndex[i]; l <= hTonalMDCTConc->pTCI_fix->upperIndex[i]; l++) + { + mdctSpectrum[l] = 0; + if (l < crossOverFreq) + { + last_block_nrg_correct += hTonalMDCTConc->lastBlockData.spectralData[l] * hTonalMDCTConc->lastBlockData.spectralData[l]; + hTonalMDCTConc->curr_noise_nrg -= concealment_noise[l] * concealment_noise[l]; + } + } + } + + /* if fadeout has not started yet, only apply sign scrambling */ + if (crossfadeGain == 1.0f) + { + for (l = 0; l < hTonalMDCTConc->pTCI_fix->lowerIndex[0]; l++) + { + if (concealment_noise[l] > 0) + { + mdctSpectrum[l] = hTonalMDCTConc->lastBlockData.spectralData[l]; + } + else + { + mdctSpectrum[l] = -hTonalMDCTConc->lastBlockData.spectralData[l]; + } + } + for (i = 1; i < hTonalMDCTConc->pTCI_fix->numIndexes; i++) + { + for (l = hTonalMDCTConc->pTCI_fix->upperIndex[i - 1] + 1; l < hTonalMDCTConc->pTCI_fix->lowerIndex[i]; l++) + { + if (concealment_noise[l] > 0) + { + mdctSpectrum[l] = hTonalMDCTConc->lastBlockData.spectralData[l]; + } + else + { + mdctSpectrum[l] = -hTonalMDCTConc->lastBlockData.spectralData[l]; + } + } + } + + for (l = hTonalMDCTConc->pTCI_fix->upperIndex[hTonalMDCTConc->pTCI_fix->numIndexes - 1] + 1; l < crossOverFreq; l++) + { + if (concealment_noise[l] > 0) + { + mdctSpectrum[l] = hTonalMDCTConc->lastBlockData.spectralData[l]; + } + else + { + mdctSpectrum[l] = -hTonalMDCTConc->lastBlockData.spectralData[l]; + } + } + + for (l = crossOverFreq; l < hTonalMDCTConc->lastBlockData.nSamples; l++) + { + mdctSpectrum[l] = hTonalMDCTConc->lastBlockData.spectralData[l]; + } + } + /* actual fadeout is done in this case */ + else + { + g *= (float)sqrt(cngLevelBackgroundTrace_bfi / hTonalMDCTConc->curr_noise_nrg); + + for (l = 0; l < hTonalMDCTConc->pTCI_fix->lowerIndex[0]; l++) + { + x = hTonalMDCTConc->lastBlockData.spectralData[l]; + y = concealment_noise[l]; + + if (y > 0) + { + mdctSpectrum[l] = g * y + crossfadeGain * x; + } + else + { + mdctSpectrum[l] = g * y - crossfadeGain * x; + } + hTonalMDCTConc->faded_signal_nrg += mdctSpectrum[l] * mdctSpectrum[l]; + } + for (i = 1; i < hTonalMDCTConc->pTCI_fix->numIndexes; i++) + { + for (l = hTonalMDCTConc->pTCI_fix->upperIndex[i - 1] + 1; l < hTonalMDCTConc->pTCI_fix->lowerIndex[i]; l++) + { + x = hTonalMDCTConc->lastBlockData.spectralData[l]; + y = concealment_noise[l]; + + if (y > 0) + { + mdctSpectrum[l] = g * y + crossfadeGain * x; + } + else + { + mdctSpectrum[l] = g * y - crossfadeGain * x; + } + hTonalMDCTConc->faded_signal_nrg += mdctSpectrum[l] * mdctSpectrum[l]; + } + } + + for (l = hTonalMDCTConc->pTCI_fix->upperIndex[hTonalMDCTConc->pTCI_fix->numIndexes - 1] + 1; l < crossOverFreq; l++) + { + x = hTonalMDCTConc->lastBlockData.spectralData[l]; + y = concealment_noise[l]; + + if (y > 0) + { + mdctSpectrum[l] = g * y + crossfadeGain * x; + } + else + { + mdctSpectrum[l] = g * y - crossfadeGain * x; + } + hTonalMDCTConc->faded_signal_nrg += mdctSpectrum[l] * mdctSpectrum[l]; + } + + for (l = crossOverFreq; l < hTonalMDCTConc->lastBlockData.nSamples; l++) + { + mdctSpectrum[l] = 0.0f; + } + } + } + + if (hTonalMDCTConc->faded_signal_nrg > 0.0f && hTonalMDCTConc->curr_noise_nrg > MDCT_ST_PLC_FADEOUT_MIN_NOISE_NRG) + { + float nrg_corr_factor; + + nrg_corr_factor = sqrtf((hTonalMDCTConc->last_block_nrg - last_block_nrg_correct) / hTonalMDCTConc->faded_signal_nrg); + v_multc(mdctSpectrum, nrg_corr_factor, mdctSpectrum, crossOverFreq); + } + } +#endif + ELSE + { +#ifndef IVAS_CODE_CNG_FIX185_PLC_FADEOUT + L_tmp = 805306368l/*0.375f Q31*/; + inv_exp = 15; + move16(); + inv_samples = Inv16(hTonalMDCTConc->lastBlockData.nSamples, &inv_exp); + tiltFactor = round_fx(BASOP_Util_fPow(L_max(L_tmp, L_deposit_h(tiltCompFactor)), 0, L_deposit_h(inv_samples),inv_exp, &exp)); + BASOP_SATURATE_WARNING_OFF_EVS /*next op may result in 32768*/ + tiltFactor = shl(tiltFactor, exp); + BASOP_SATURATE_WARNING_ON_EVS + + tilt = 32767/*1.0f Q15*/; + move16(); + + nrgNoiseInLastFrame = L_deposit_h(0); + nrgWhiteNoise = L_deposit_h(0); + exp_last = exp_noise = 0; +#endif + move16(); + move16(); + IF (!tonalConcealmentActive) + { + ld = sub(14,norm_s(hTonalMDCTConc->lastBlockData.nSamples)); + fac = shr(-32768,ld); + + FOR (i = 0; i < crossOverFreq; i++) + { + Word16 x = hTonalMDCTConc->lastBlockData.spectralData[i]; + Word32 y; + rnd = extract_l(L_mac0(13849, rnd, 31821)); + y = L_mult(tilt,rnd); + + nrgNoiseInLastFrame = L_add(nrgNoiseInLastFrame, Mpy_32_16_1(L_msu(0, x,fac),x)); + x = round_fx(y); + nrgWhiteNoise = L_add(nrgWhiteNoise, Mpy_32_16_1(L_msu(0, x,fac),x)); + + mdctSpectrum[i] = y; /* 15Q16 */ move32(); + + tilt = mult_r(tilt,tiltFactor); + } + + IF (nrgNoiseInLastFrame == 0) + { + set32_fx(mdctSpectrum, 0, crossOverFreq); + *mdctSpectrum_exp = SPEC_EXP_DEC; + } + ELSE + { + exp_last = add(ld,shl(hTonalMDCTConc->lastBlockData.spectralData_exp,1)); + exp_noise = add(ld,30); + + IF (nrgWhiteNoise > 0) + { + ld = norm_l(nrgNoiseInLastFrame); + nrgNoiseInLastFrame = L_shl(nrgNoiseInLastFrame,ld); + exp_last = sub(exp_last,ld); + ld = norm_l(nrgWhiteNoise); + nrgWhiteNoise = L_shl(nrgWhiteNoise,ld); + exp_noise = sub(exp_noise,ld); + + exp = sub(exp_last, exp_noise); + + IF(nrgNoiseInLastFrame > nrgWhiteNoise) + { + nrgNoiseInLastFrame = L_shr(nrgNoiseInLastFrame,1); + exp = add(exp,1); + } + tmp = div_l(nrgNoiseInLastFrame,round_fx(nrgWhiteNoise)); + tmp = Sqrt16(tmp, &exp); + g = mult_r(g,tmp); + + L_tmp = L_deposit_h(0); + ld = sub(hTonalMDCTConc->lastBlockData.spectralData_exp, 15); + exp = sub(ld, exp); + + IF(exp > 0) + { + g = shr(g,exp); + *mdctSpectrum_exp = hTonalMDCTConc->lastBlockData.spectralData_exp; + } + ELSE + { + crossfadeGain = shl(crossfadeGain,exp); + *mdctSpectrum_exp = sub(hTonalMDCTConc->lastBlockData.spectralData_exp,exp); + } + /*make a headroom for mdct_shaping*/ + exp = sub(*mdctSpectrum_exp, SPEC_EXP_DEC); + /* assert(exp < 0);*/ + IF(exp < 0) + { + *mdctSpectrum_exp = SPEC_EXP_DEC; + } + ELSE + { + exp = 0; + } + } + + FOR (i = 0; i < crossOverFreq; i++) + { + Word16 const x = hTonalMDCTConc->lastBlockData.spectralData[i]; + Word32 const y = mdctSpectrum[i]; + + if(g > 0) + { + L_tmp = Mpy_32_16_1(y,g); + } + + L_tmp2 = L_msu(L_tmp,crossfadeGain,x); + if(y > 0) + { + L_tmp2 = L_mac(L_tmp,crossfadeGain,x); + } + mdctSpectrum[i] = L_shl(L_tmp2, exp); + move32(); + } + } + exp = sub(hTonalMDCTConc->lastBlockData.spectralData_exp, sub(*mdctSpectrum_exp,16)); + FOR (i = crossOverFreq; i < hTonalMDCTConc->lastBlockData.nSamples; i++) + { + mdctSpectrum[i] = L_shl(L_deposit_l(hTonalMDCTConc->lastBlockData.spectralData[i]), exp); + move32(); + } + } + ELSE + { + Word16 l; + assert(hTonalMDCTConc->pTCI_fix->numIndexes > 0); + + FOR (l = hTonalMDCTConc->pTCI_fix->lowerIndex[0]; l <= hTonalMDCTConc->pTCI_fix->upperIndex[0]; l++) + { + mdctSpectrum[l] = L_deposit_l(0); + } + + ld = sub(14,norm_s(hTonalMDCTConc->lastBlockData.nSamples)); + fac = shr(-32768,ld); + FOR (l = 0; l < hTonalMDCTConc->pTCI_fix->lowerIndex[0]; l++) + { + Word16 x = hTonalMDCTConc->lastBlockData.spectralData[l]; + Word32 y; + rnd = extract_l(L_mac0(13849, rnd, 31821)); + y = L_mult(tilt,rnd); + + nrgNoiseInLastFrame = L_add(nrgNoiseInLastFrame, Mpy_32_16_1(L_msu(0, x,fac),x)); + x = round_fx(y); + nrgWhiteNoise = L_add(nrgWhiteNoise, Mpy_32_16_1(L_msu(0, x,fac),x)); + + mdctSpectrum[l] = y; /* 15Q16 L_deposit_l(y);*/ move32(); + + tilt = mult_r(tilt,tiltFactor); + } + + FOR (i = 1; i < hTonalMDCTConc->pTCI_fix->numIndexes; i++) + { + /*tilt *= (float)pow(tiltFactor, hTonalMDCTConc->pTCI_fix->upperIndex[i-1]-hTonalMDCTConc->pTCI_fix->lowerIndex[i-1]+1);*/ + tmp= round_fx(BASOP_Util_fPow(L_deposit_h(tiltFactor), 0, L_deposit_h(hTonalMDCTConc->pTCI_fix->upperIndex[i-1]-hTonalMDCTConc->pTCI_fix->lowerIndex[i-1]+1),15, &exp)); + tmp = shl(tmp, exp); + tilt = mult_r(tilt,tmp); + + FOR (l = hTonalMDCTConc->pTCI_fix->lowerIndex[i]; l <= hTonalMDCTConc->pTCI_fix->upperIndex[i]; l++) + { + mdctSpectrum[l] = L_deposit_l(0); + } + + FOR (l = hTonalMDCTConc->pTCI_fix->upperIndex[i-1]+1; l < hTonalMDCTConc->pTCI_fix->lowerIndex[i]; l++) + { + Word16 x = hTonalMDCTConc->lastBlockData.spectralData[l]; + Word32 y; + rnd = extract_l(L_mac0(13849, rnd, 31821)); + y = L_mult(tilt,rnd); + + nrgNoiseInLastFrame = L_add(nrgNoiseInLastFrame, Mpy_32_16_1(L_msu(0, x,fac),x)); + x = round_fx(y); + nrgWhiteNoise = L_add(nrgWhiteNoise, Mpy_32_16_1(L_msu(0, x,fac),x)); + + mdctSpectrum[l] = y; /* 15Q16 L_deposit_l(y);*/ move32(); + + tilt = mult_r(tilt,tiltFactor); + } + } + + tmp = round_fx(BASOP_Util_fPow(L_deposit_h(tiltFactor), 0, L_deposit_h(hTonalMDCTConc->pTCI_fix->upperIndex[hTonalMDCTConc->pTCI_fix->numIndexes-1]-hTonalMDCTConc->pTCI_fix->lowerIndex[hTonalMDCTConc->pTCI_fix->numIndexes-1]+1),15, &exp)); + BASOP_SATURATE_WARNING_OFF_EVS /*next op may result in 32768*/ + tmp = shl(tmp, exp); + BASOP_SATURATE_WARNING_ON_EVS + tilt = mult_r(tilt,tmp); + + FOR (l = add(hTonalMDCTConc->pTCI_fix->upperIndex[hTonalMDCTConc->pTCI_fix->numIndexes-1], 1); l < crossOverFreq; l++) + { + Word16 x = hTonalMDCTConc->lastBlockData.spectralData[l]; + Word32 y; + rnd = extract_l(L_mac0(13849, rnd, 31821)); + y = L_mult(tilt,rnd); + + nrgNoiseInLastFrame = L_add(nrgNoiseInLastFrame, Mpy_32_16_1(L_msu(0, x,fac),x)); + x = round_fx(y); + nrgWhiteNoise = L_add(nrgWhiteNoise, Mpy_32_16_1(L_msu(0, x,fac),x)); + + mdctSpectrum[l] = y; /* 15Q16 L_deposit_l(y);*/ move32(); + + tilt = mult_r(tilt,tiltFactor); + } + + IF (nrgNoiseInLastFrame == 0) + { + set32_fx(mdctSpectrum, 0, crossOverFreq); + *mdctSpectrum_exp = SPEC_EXP_DEC; + } + ELSE + { + exp_last = add(ld,shl(hTonalMDCTConc->lastBlockData.spectralData_exp,1)); + exp_noise = add(ld,shl(15,1)); + + ld = norm_l(nrgNoiseInLastFrame); + nrgNoiseInLastFrame = L_shl(nrgNoiseInLastFrame,ld); + exp_last = sub(exp_last,ld); + ld = norm_l(nrgWhiteNoise); + nrgWhiteNoise = L_shl(nrgWhiteNoise,ld); + exp_noise = sub(exp_noise,ld); + + exp = sub(exp_last, exp_noise); + + IF(nrgNoiseInLastFrame > nrgWhiteNoise) + { + nrgNoiseInLastFrame = L_shr(nrgNoiseInLastFrame,1); + exp = add(exp,1); + } + tmp = div_l(nrgNoiseInLastFrame,round_fx(nrgWhiteNoise)); + tmp = Sqrt16(tmp, &exp); + g = mult_r(g,tmp); + + L_tmp = L_deposit_h(0); + ld = sub(hTonalMDCTConc->lastBlockData.spectralData_exp, 15); + exp = sub(ld, exp); + IF(exp > 0) + { + g = shr(g,exp); + *mdctSpectrum_exp = hTonalMDCTConc->lastBlockData.spectralData_exp; + } + ELSE + { + crossfadeGain = shl(crossfadeGain,exp); + *mdctSpectrum_exp = sub(hTonalMDCTConc->lastBlockData.spectralData_exp,exp); + } + /*make a headroom for mdct_shaping*/ + exp = sub(*mdctSpectrum_exp, SPEC_EXP_DEC); + + + IF(exp < 0) + { + *mdctSpectrum_exp = SPEC_EXP_DEC; + } + ELSE + { + exp = 0; + } + + FOR (l = 0; l < hTonalMDCTConc->pTCI_fix->lowerIndex[0]; l++) + { + Word16 const x = hTonalMDCTConc->lastBlockData.spectralData[l]; + Word32 const y = mdctSpectrum[l]; + + if(g > 0) + { + L_tmp = Mpy_32_16_1(y,g); + } + + L_tmp2 = L_msu(L_tmp,crossfadeGain,x); + if(y > 0) + { + L_tmp2 = L_mac(L_tmp,crossfadeGain,x); + } + mdctSpectrum[l] = L_shl(L_tmp2, exp); + move32(); + } + + FOR (i = 1; i < hTonalMDCTConc->pTCI_fix->numIndexes; i++) + { + FOR (l = hTonalMDCTConc->pTCI_fix->upperIndex[i-1]+1; l < hTonalMDCTConc->pTCI_fix->lowerIndex[i]; l++) + { + Word16 const x = hTonalMDCTConc->lastBlockData.spectralData[l]; + Word32 const y = mdctSpectrum[l]; + + if(g > 0) + { + L_tmp = Mpy_32_16_1(y,g); + } + + L_tmp2 = L_msu(L_tmp,crossfadeGain,x); + if(y > 0) + { + L_tmp2 = L_mac(L_tmp,crossfadeGain,x); + } + mdctSpectrum[l] = L_shl(L_tmp2, exp); + move32(); + } + } + + /* initialize bins of tonal components with zero: basically not + necessary, but currently the whole spectrum is rescaled in + mdct_noiseShaping() and then there would be a processing of + uninitialized values */ + FOR (i = 0; i < hTonalMDCTConc->pTCI_fix->numIndexes; i++) + { + FOR (l = hTonalMDCTConc->pTCI_fix->lowerIndex[i]; l <= hTonalMDCTConc->pTCI_fix->upperIndex[i]; l++) + { + mdctSpectrum[l] = L_deposit_l(0); + } + } + + FOR (l = add(hTonalMDCTConc->pTCI_fix->upperIndex[hTonalMDCTConc->pTCI_fix->numIndexes-1], 1); l < crossOverFreq; l++) + { + Word16 const x = hTonalMDCTConc->lastBlockData.spectralData[l]; + Word32 const y = mdctSpectrum[l]; + + if(g > 0) + { + L_tmp = Mpy_32_16_1(y,g); + } + + L_tmp2 = L_msu(L_tmp,crossfadeGain,x); + if(y > 0) + { + L_tmp2 = L_mac(L_tmp,crossfadeGain,x); + } + mdctSpectrum[l] = L_shl(L_tmp2, exp); + move32(); + } + } + exp = sub(hTonalMDCTConc->lastBlockData.spectralData_exp, sub(*mdctSpectrum_exp,16)); + FOR (l = crossOverFreq; l < hTonalMDCTConc->lastBlockData.nSamples; l++) + { + mdctSpectrum[l] = L_shl(L_deposit_l(hTonalMDCTConc->lastBlockData.spectralData[l]), exp); + move32(); + } + } + } + + *pSeed = rnd; + move16(); + + return ; +} + +void TonalMDCTConceal_Apply( + const TonalMDCTConcealPtr hTonalMDCTConc, /*IN */ + Word32 *mdctSpectrum, /*IN/OUT*/ + Word16 *mdctSpectrum_exp /*IN */ +#ifdef IVAS_CODE_MDCT_GSHAPE + ,const PsychoacousticParameters* psychParamsCurrent) +#endif + ) +{ + Word16 i, l, exp; + Word16 * phaseDiff, * pCurrentPhase; + Word32 phaseToAdd, currentPhase; + Word32 powerSpectrum[L_FRAME_MAX]; + Word16 nSamples; + + + + IF (hTonalMDCTConc->lastBlockData.blockIsValid & hTonalMDCTConc->secondLastBlockData.blockIsValid) + { + assert(hTonalMDCTConc->pTCI_fix->numIndexes > 0); + + nSamples = hTonalMDCTConc->nNonZeroSamples; + move16(); + assert(hTonalMDCTConc->pTCI_fix->upperIndex[hTonalMDCTConc->pTCI_fix->numIndexes-1] < nSamples); + +#ifdef IVAS_CODE_MDCT_GSHAPE + IF (psychParamsCurrent == NULL) +#endif + { + + mdct_shaping_16(hTonalMDCTConc->secondLastPowerSpectrum, hTonalMDCTConc->nSamplesCore, nSamples, + hTonalMDCTConc->secondLastBlockData.scaleFactors, hTonalMDCTConc->secondLastBlockData.scaleFactors_exp, + hTonalMDCTConc->secondLastBlockData.scaleFactors_max_e, powerSpectrum); + } +#ifdef IVAS_CODE_MDCT_GSHAPE + ELSE + { + sns_shape_spectrum(powerSpectrum, psychParamsCurrent, hTonalMDCTConc->secondLastBlockData.scaleFactors, hTonalMDCTConc->nSamplesCore); + nBands = psychParamsCurrent->nBands; + + } +#endif + phaseDiff = hTonalMDCTConc->pTCI_fix->phaseDiff; /* if multiple frame loss occurs use the phase from the last frame and continue rotating */ + pCurrentPhase = hTonalMDCTConc->pTCI_fix->phase_currentFramePredicted; + + exp = sub(*mdctSpectrum_exp, add(add(hTonalMDCTConc->secondLastPowerSpectrum_exp, add(hTonalMDCTConc->secondLastBlockData.gain_tcx_exp,1)),hTonalMDCTConc->secondLastBlockData.scaleFactors_max_e)); + + IF (!hTonalMDCTConc->lastBlockData.blockIsConcealed) + { + if (hTonalMDCTConc->secondLastBlockData.tonalConcealmentActive != 0) + { + hTonalMDCTConc->nFramesLost = add(hTonalMDCTConc->nFramesLost,2); /*Q1*/ move16(); + } + if (hTonalMDCTConc->secondLastBlockData.tonalConcealmentActive == 0) + { + hTonalMDCTConc->nFramesLost = 3; /*Q1*/ move16(); + } + } + /* for each index group */ + FOR (i = 0; i < hTonalMDCTConc->pTCI_fix->numIndexes; i++) + { + /*phaseToAdd = hTonalMDCTConc->nFramesLost*phaseDiff[i]; */ + phaseToAdd = L_mult0(hTonalMDCTConc->nFramesLost,phaseDiff[i]); /*Q1*3Q12=2Q13*/ + /* Move phaseToAdd to range -PI..PI */ + + WHILE (GT_32(phaseToAdd, 25736l/*EVS_PI Q13*/)) + { + phaseToAdd = L_sub(phaseToAdd, 51472l/*2*EVS_PI Q13*/); + } + WHILE (LT_32(phaseToAdd, -25736l/*-EVS_PI Q13*/)) + { + phaseToAdd = L_add(phaseToAdd, 51472l/*2*EVS_PI Q13*/); + } + + FOR (l = hTonalMDCTConc->pTCI_fix->lowerIndex[i]; l <= hTonalMDCTConc->pTCI_fix->upperIndex[i]; l++) + { + /* *pCurrentPhase and phaseToAdd are in range -PI..PI */ + currentPhase = L_mac0(phaseToAdd, (*pCurrentPhase++), 1); /*2Q13+2Q13=3Q13*/ + + if (GT_32(currentPhase, 25736l/*EVS_PI Q13*/)) + { + currentPhase = L_sub(currentPhase, 51472l/*2*EVS_PI Q13*/); + } + if (LT_32(currentPhase, -25736l/*-EVS_PI Q13*/)) + { + currentPhase = L_add(currentPhase, 51472l/*2*EVS_PI Q13*/); + } + /* getCosWord16 returns 1Q14*/ + mdctSpectrum[l] = Mpy_32_16_1(powerSpectrum[l],getCosWord16(extract_l(currentPhase))); + move32(); + mdctSpectrum[l] = L_shr(mdctSpectrum[l], exp); + } + } + } + + hTonalMDCTConc->nFramesLost = add(hTonalMDCTConc->nFramesLost,2); /*Q1*/ move16(); + + return ; +} + +void TonalMDCTConceal_SaveTimeSignal( + TonalMDCTConcealPtr hTonalMDCTConc, + Word16* timeSignal, + Word16 nNewSamples + +) +{ + IF (EQ_16(nNewSamples,hTonalMDCTConc->nSamples)) + { + assert(nNewSamples <= L_FRAME_MAX); + IF (!hTonalMDCTConc->secondLastBlockData.tonalConcealmentActive) + { + Copy(hTonalMDCTConc->lastPcmOut + hTonalMDCTConc->nSamples/2, hTonalMDCTConc->secondLastPcmOut, hTonalMDCTConc->nSamples/2); + } + Copy(timeSignal, hTonalMDCTConc->lastPcmOut, hTonalMDCTConc->nSamples); + } + + return ; +} +static void CalcPowerSpec( + const Word32 * mdctSpec, /* i: MDCT spectrum Q31,mdctSpec_exp */ + const Word16 mdctSpec_exp, /* i: exponent of MDCT spectrum */ + const Word32 * mdstSpec, /* i: MDST spectrum Q31,mdstSpec_exp */ + const Word16 mdstSpec_exp, /* i: exponent of MDST spectrum */ + const Word16 nSamples, /* i: frame size */ + const Word16 floorPowerSpectrum, /* i: lower limit for power spectrum bins Q0 */ + Word32 * powerSpec, /* o: power spectrum */ + Word16 * powerSpec_exp) /* o: exponent of power spectrum */ +{ + Word16 k, s1, s2, tmp; + Word32 x, L_tmp, L_tmp_floor; + + + k = s_max(mdctSpec_exp, mdstSpec_exp); + *powerSpec_exp = add(add(k, k), 3); /*extra 3 bits of headroom for MA filter in getEnvelope*/ move16(); + s1 = sub(*powerSpec_exp, add(mdctSpec_exp, mdctSpec_exp)); + s2 = sub(*powerSpec_exp, add(mdstSpec_exp, mdstSpec_exp)); + + k = sub(31, *powerSpec_exp); + /* If the signal is bellow floor, special care is needed for *powerSpec_exp */ + IF (LT_16(add(16-3, norm_s(floorPowerSpectrum)), k)) /*extra 3 bits of headroom for MA filter in getEnvelope*/ + { + k = sub(k, add(16-3, norm_s(floorPowerSpectrum))); /*extra 3 bits of headroom for MA filter in getEnvelope*/ + *powerSpec_exp = add(*powerSpec_exp, k); + s1 = add(s1, k); + s2 = add(s2, k); + k = add(16-3, norm_s(floorPowerSpectrum)); + } + L_tmp_floor = L_shl(L_deposit_l(floorPowerSpectrum), k); + + tmp = sub(nSamples, 2); + FOR (k = 1; k <= tmp; k++) + { + x = Mpy_32_32(mdctSpec[k], mdctSpec[k]); /*Q31,2*mdctSpec_exp*/ + + L_tmp = Mpy_32_32(mdstSpec[k], mdstSpec[k]); /*Q31,2*mdstSpec_exp*/ + x = L_add(L_shr(x,s1), L_shr(L_tmp,s2)); /*Q31,*powerSpec_exp*/ + + powerSpec[k] = L_max(L_tmp_floor, x); + move32(); + } + + powerSpec[0] = L_shr(powerSpec[1], 1); + move32(); + powerSpec[nSamples-1] = L_shr(powerSpec[nSamples-2], 1); + move32(); + +} +#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT +void TonalMdctConceal_create_concealment_noise( + float concealment_noise[L_FRAME48k], + CPE_DEC_HANDLE hCPE, + const int16_t L_frameTCX, + const int16_t L_frame, + const int16_t idchan, + const int16_t subframe_idx, + const int16_t core, + const int16_t crossfade_gain, + const TONALMDCTCONC_NOISE_GEN_MODE noise_gen_mode) +{ + STEREO_MDCT_DEC_DATA_HANDLE hStereoMdct; + TonalMDCTConcealPtr hTonalMDCTConc; + Decoder_State* st; + HANDLE_FD_CNG_COM hFdCngCom; + int16_t* rnd_c, * rnd; + int16_t crossOverFreq, i, save_rnd_c, max_noise_line; + float c, c_inv; + float noise_shape_buffer[L_FRAME48k]; + int16_t inc, start_idx, stop_idx; + float* cngNoiseLevelPtr; + float last_scf; + + wmops_sub_start("create_conc_noise"); + + hStereoMdct = hCPE->hStereoMdct; + st = hCPE->hCoreCoder[idchan]; + hTonalMDCTConc = st->hTonalMDCTConc; + hFdCngCom = st->hFdCngDec->hFdCngCom; + rnd = &hStereoMdct->noise_seeds_channels[idchan]; + rnd_c = &hStereoMdct->noise_seed_common; + + /* determine start bin for IGF */ + if (st->igf == 0) + { + if (st->narrowBand == 0) + { + /* minimum needed for output with sampling rates lower then the + nominal sampling rate */ + crossOverFreq = min(L_frameTCX, L_frame); + } + else + { + crossOverFreq = L_frameTCX; + } + } + else + { + crossOverFreq = min(st->hIGFDec->infoIGFStartLine, L_frameTCX); + } + + /* for tonal mdct concealment with tonal components above the crossover frequency, conditionally raise the frequency index until which noise is generated */ + max_noise_line = crossOverFreq; + if (st->tonal_mdct_plc_active) + { + max_noise_line = max(max_noise_line, hTonalMDCTConc->pTCI_fix->upperIndex[hTonalMDCTConc->pTCI_fix->numIndexes - 1] + 1); + } + + /* first lost frame is handled separately */ + if (!hTonalMDCTConc->lastBlockData.blockIsConcealed) + { + *rnd = 1977 + idchan; + /* will be set twice when looping over two channels, but does not matter */ + *rnd_c = 1979; + } + + if (crossfade_gain == 1.0f) + { + /* In first frame, noise is weighted with zero anyway, we only need the random numbers for the sign scrambling */ + for (i = 0; i < max_noise_line; i++) + { + *rnd = own_random(rnd); + concealment_noise[i] = *rnd; + } + + wmops_sub_end(); + + return; + } + + save_rnd_c = *rnd_c; + + c = sqrtf(hStereoMdct->lastCoh); + c_inv = sqrtf(1 - hStereoMdct->lastCoh); + + /* pre-compute the noise shape for later weighting of the noise spectra */ + cngNoiseLevelPtr = &hFdCngCom->cngNoiseLevel_flt[0]; + inc = (st->core > TCX_20_CORE) ? 2 : 1; + start_idx = hFdCngCom->startBand / inc; + stop_idx = hFdCngCom->stopFFTbin / inc; + + for (i = 0; i < start_idx; i++) + { + noise_shape_buffer[i] = 0.0f; + } + for (; i < stop_idx; i++, cngNoiseLevelPtr += inc) + { + noise_shape_buffer[i] = sqrtf(*(cngNoiseLevelPtr)); + } + + last_scf = sqrtf(*(cngNoiseLevelPtr - inc)); + + for (; i < max_noise_line; i++) + { + noise_shape_buffer[i] = last_scf; + } + + /* fill the noise vector */ + hTonalMDCTConc->curr_noise_nrg = MDCT_ST_PLC_FADEOUT_MIN_NOISE_NRG; + if (noise_gen_mode == EQUAL_CORES || ((noise_gen_mode == TCX20_IN_0_TCX10_IN_1 && idchan == 0) || (noise_gen_mode == TCX10_IN_0_TCX20_IN_1 && idchan == 1))) + { + /* current channel is TCX20 -> generate noise for "full-length" spectrum */ + for (i = 0; i < max_noise_line; i++) + { + *rnd = own_random(rnd); + *rnd_c = own_random(rnd_c); + + concealment_noise[i] = (c_inv * *rnd + c * *rnd_c) * noise_shape_buffer[i]; + hTonalMDCTConc->curr_noise_nrg += concealment_noise[i] * concealment_noise[i]; + } + } + else /* ( ( noise_gen_mode == TCX10_IN_0_TCX20_IN_1 && idchan == 0 ) || ( noise_gen_mode == TCX20_IN_0_TCX10_IN_1 && idchan == 1 ) ) */ + { + /* current channel is TCX10 and the other is TCX20 -> generate noise for "half-length" spectrum, but "increment" mid seed twice, to have the same seed in mid as the other (TCX20) channel for next frame */ + for (i = 0; i < max_noise_line; i++) + { + *rnd = own_random(rnd); + *rnd_c = own_random(rnd_c); + + concealment_noise[i] = (c_inv * *rnd + c * *rnd_c) * noise_shape_buffer[i]; + hTonalMDCTConc->curr_noise_nrg += concealment_noise[i] * concealment_noise[i]; + + *rnd_c = own_random(rnd_c); + } + } + if (st->tonal_mdct_plc_active) + { + for (i = crossOverFreq; i < max(crossOverFreq, hTonalMDCTConc->pTCI_fix->lowerIndex[hTonalMDCTConc->pTCI_fix->numIndexes - 1]); ++i) + { + concealment_noise[i] *= 0.0f; + } + } + /* restore common seed + - after finishing the first channel + - after a first subframe if the current channel is TCX10 */ + if ((idchan == 0 && (core == TCX_20 || (core == TCX_10 && subframe_idx == 1))) || (core == TCX_10 && subframe_idx == 0)) + { + *rnd_c = save_rnd_c; + } + st->seed_tcx_plc = *rnd; + wmops_sub_end(); + + return; +} +void TonalMdctConceal_whiten_noise_shape( + Decoder_State* st, + const int16_t L_frame, + const TONALMDCTCONC_NOISE_SHAPE_WHITENING_MODE whitening_mode) +{ + int16_t inc, start_idx, stop_idx; + float* noiseLevelPtr, * scfs_bg, * scfs_for_shaping; + HANDLE_FD_CNG_COM hFdCngCom; + float whitenend_noise_shape[L_FRAME16k]; + float scfs_int[FDNS_NPTS]; + const PsychoacousticParameters* psychParams; + + push_wmops("apply_sns_on_noise_shape"); + + scfs_bg = &st->hTonalMDCTConc->scaleFactorsBackground[0]; + psychParams = st->hTonalMDCTConc->psychParams; + hFdCngCom = st->hFdCngDec->hFdCngCom; + + inc = ((whitening_mode == ON_FIRST_LOST_FRAME ? st->core : st->last_core) > TCX_20_CORE) ? 2 : 1; + start_idx = hFdCngCom->startBand / inc; + stop_idx = L_frame / inc; + noiseLevelPtr = hFdCngCom->cngNoiseLevel_flt; + + set_zero(whitenend_noise_shape, start_idx); + for (int16_t j = start_idx; j < stop_idx; j++, noiseLevelPtr += inc) + { + whitenend_noise_shape[j] = *noiseLevelPtr; + } + + if (whitening_mode == ON_FIRST_LOST_FRAME) + { + float scf[SNS_NPTS]; + + sns_compute_scf(whitenend_noise_shape, psychParams, L_frame, scf); + sns_interpolate_scalefactors(scfs_int, scf, ENC); + sns_interpolate_scalefactors(scfs_bg, scf, DEC); + scfs_for_shaping = &scfs_int[0]; + } + else /* whitening_mode == ON_FIRST_GOOD_FRAME */ + { + scfs_for_shaping = &scfs_bg[0]; + } + + if (sum_f(scfs_for_shaping, FDNS_NPTS) > 0.0f) + { + sns_shape_spectrum(whitenend_noise_shape, psychParams, scfs_for_shaping, L_frame); + mvr2r(whitenend_noise_shape + start_idx, hFdCngCom->cngNoiseLevel_flt, stop_idx - start_idx); + } + else + { + set_zero(hFdCngCom->cngNoiseLevel_flt, stop_idx - start_idx); + } + + pop_wmops(); +} +#endif diff --git a/lib_dec/transition_dec.c b/lib_dec/transition_dec.c index b25c7d201c6f2f6d64e61fee8288cb7f664c8f23..80aba8c1f6c7135d2b0c0a43dcd65910142c23d5 100644 --- a/lib_dec/transition_dec.c +++ b/lib_dec/transition_dec.c @@ -215,7 +215,7 @@ void transition_dec( limit_T0( L_FRAME, 8, pit_flag, limit_flag, *T0, 0, T0_min, T0_max ); /* find T0_min and T0_max */ /* Find the adaptive codebook vector - ACELP long-term prediction */ - pred_lt4( &exc[i_subfr], &exc[i_subfr], *T0, *T0_frac, L_SUBFR + 1, inter4_2, L_INTERPOL2, PIT_UP_SAMP ); + pred_lt4_flt( &exc[i_subfr], &exc[i_subfr], *T0, *T0_frac, L_SUBFR + 1, inter4_2, L_INTERPOL2, PIT_UP_SAMP ); offset = tbe_celp_exc_offset_flt( *T0, *T0_frac ); for ( i = 0; i < L_SUBFR * HIBND_ACB_L_FAC; i++ ) @@ -241,7 +241,7 @@ void transition_dec( limit_T0( L_FRAME, 8, pit_flag, limit_flag, *T0, 0, T0_min, T0_max ); /* find T0_min and T0_max */ /* Find the adaptive codebook vector. ACELP long-term prediction */ - pred_lt4( &exc[i_subfr], &exc[i_subfr], *T0, *T0_frac, L_SUBFR + 1, inter4_2, L_INTERPOL2, PIT_UP_SAMP ); + pred_lt4_flt( &exc[i_subfr], &exc[i_subfr], *T0, *T0_frac, L_SUBFR + 1, inter4_2, L_INTERPOL2, PIT_UP_SAMP ); offset = tbe_celp_exc_offset_flt( *T0, *T0_frac ); for ( i = 0; i < L_SUBFR * HIBND_ACB_L_FAC; i++ ) @@ -297,7 +297,7 @@ void transition_dec( } /* Find the adaptive codebook vector. ACELP long-term prediction */ - pred_lt4( &exc[i_subfr], &exc[i_subfr], *T0, *T0_frac, L_SUBFR + 1, inter4_2, L_INTERPOL2, PIT_UP_SAMP ); + pred_lt4_flt( &exc[i_subfr], &exc[i_subfr], *T0, *T0_frac, L_SUBFR + 1, inter4_2, L_INTERPOL2, PIT_UP_SAMP ); offset = tbe_celp_exc_offset_flt( *T0, *T0_frac ); for ( i = 0; i < L_SUBFR * HIBND_ACB_L_FAC; i++ ) @@ -314,10 +314,10 @@ void transition_dec( index = get_next_indice( st, nBits ); - delta_pit_dec( 2, index, T0, T0_frac, *T0_min ); + delta_pit_dec_flt( 2, index, T0, T0_frac, *T0_min ); /* Find the adaptive codebook vector. ACELP long-term prediction */ - pred_lt4( &exc[i_subfr], &exc[i_subfr], *T0, *T0_frac, L_SUBFR + 1, inter4_2, L_INTERPOL2, PIT_UP_SAMP ); + pred_lt4_flt( &exc[i_subfr], &exc[i_subfr], *T0, *T0_frac, L_SUBFR + 1, inter4_2, L_INTERPOL2, PIT_UP_SAMP ); offset = tbe_celp_exc_offset_flt( *T0, *T0_frac ); for ( i = 0; i < L_SUBFR * HIBND_ACB_L_FAC; i++ ) @@ -334,10 +334,10 @@ void transition_dec( { index = get_next_indice( st, nBits ); - pit_Q_dec( 0, index, nBits, 8, pit_flag, limit_flag, T0, T0_frac, T0_min, T0_max, &st->BER_detect ); + pit_Q_dec_flt( 0, index, nBits, 8, pit_flag, limit_flag, T0, T0_frac, T0_min, T0_max, &st->BER_detect ); /* Find the adaptive codebook vector */ - pred_lt4( &exc[i_subfr], &exc[i_subfr], *T0, *T0_frac, L_SUBFR + 1, inter4_2, L_INTERPOL2, PIT_UP_SAMP ); + pred_lt4_flt( &exc[i_subfr], &exc[i_subfr], *T0, *T0_frac, L_SUBFR + 1, inter4_2, L_INTERPOL2, PIT_UP_SAMP ); offset = tbe_celp_exc_offset_flt( *T0, *T0_frac ); for ( i = 0; i < L_SUBFR * HIBND_ACB_L_FAC; i++ ) @@ -429,7 +429,7 @@ void transition_dec( if ( nBits == 10 ) { - pit16k_Q_dec( index, nBits, limit_flag, T0, T0_frac, T0_min, T0_max, &st->BER_detect ); + pit16k_Q_dec_flt( index, nBits, limit_flag, T0, T0_frac, T0_min, T0_max, &st->BER_detect ); } else if ( nBits == 8 ) /* tc_subfr==0 && i_subfr==L_SUBFR */ { @@ -462,7 +462,7 @@ void transition_dec( } else if ( nBits == 6 ) { - delta_pit_dec( 4, index, T0, T0_frac, *T0_min ); + delta_pit_dec_flt( 4, index, T0, T0_frac, *T0_min ); } if ( nBits == 6 ) { @@ -486,7 +486,7 @@ void transition_dec( else { /* Find the adaptive codebook vector - ACELP long-term prediction */ - pred_lt4( &exc[i_subfr], &exc[i_subfr], *T0, *T0_frac, L_SUBFR + 1, inter4_2, L_INTERPOL2, PIT_UP_SAMP ); + pred_lt4_flt( &exc[i_subfr], &exc[i_subfr], *T0, *T0_frac, L_SUBFR + 1, inter4_2, L_INTERPOL2, PIT_UP_SAMP ); for ( i = 0; i < L_SUBFR * 2; i++ ) { @@ -569,11 +569,11 @@ static void tc_dec( if ( nBits == 9 ) { - abs_pit_dec( 4, i, 0, T0, T0_frac ); + abs_pit_dec_flt( 4, i, 0, T0, T0_frac ); } else { - abs_pit_dec( 2, i, 0, T0, T0_frac ); + abs_pit_dec_flt( 2, i, 0, T0, T0_frac ); } } else @@ -589,11 +589,11 @@ static void tc_dec( { if ( tc_subfr == TC_0_0 ) { - delta_pit_dec( 2, i, T0, T0_frac, PIT_MIN - 1 ); + delta_pit_dec_flt( 2, i, T0, T0_frac, PIT_MIN - 1 ); } else { - delta_pit_dec( 0, i, T0, T0_frac, PIT_MIN - 1 ); + delta_pit_dec_flt( 0, i, T0, T0_frac, PIT_MIN - 1 ); } } } @@ -662,7 +662,7 @@ static void tc_dec( * (when appears) *--------------------------------------------------------------*/ - pred_lt4_tc( exc, *T0, *T0_frac, inter4_2, imp_pos, i_subfr ); + pred_lt4_tc_flt( exc, *T0, *T0_frac, inter4_2, imp_pos, i_subfr ); if ( st->hBWE_TD != NULL ) { diff --git a/lib_dec/transition_dec_fx.c b/lib_dec/transition_dec_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..b932044ab7449f18ee1ed7371a30f5fa06acc5f7 --- /dev/null +++ b/lib_dec/transition_dec_fx.c @@ -0,0 +1,921 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ +#include +#include "options.h" /* Compilation switches */ +#include "cnst.h" /* Common constants */ +#include "rom_com.h" /* Static table prototypes */ +#include "prot_fx1.h" /* Function prototypes */ +#include "prot_fx2.h" /* Function prototypes */ +#include "stl.h" + +/*----------------------------------------------------------------------* + * Local function prototypes + *----------------------------------------------------------------------*/ +static void tc_dec_fx( Decoder_State *st_fx, const Word16 L_frame,Word16 exc[], Word16 *T0,Word16 *T0_frac, const Word16 i_subfr, + const Word16 tc_subfr, Word16 *position, Word16 bwe_exc[], Word16 *Q_exc ); +/*======================================================================*/ +/* FUNCTION : transition_dec_fx() */ +/*----------------------------------------------------------------------*/ +/* PURPOSE : Principal function for TC decoding */ +/* */ +/*----------------------------------------------------------------------*/ +/* GLOBAL INPUT ARGUMENTS : */ +/* _ (Word16) L_frame : length of the frame Q0 */ +/* _ (Word16[]) pitch_buf_fx : floating pitch values for each subframe Q6*/ +/* _ (Word16[]) voice_factors_fx: frame error rate Q15 */ +/*-----------------------------------------------------------------------*/ +/* OUTPUT ARGUMENTS : */ +/* _ (Word16[]) exc_fx : adapt. excitation exc (Q0) */ +/* _ (Word16[]) exc2_fx : adapt. excitation/total exc (Q0) */ +/*-----------------------------------------------------------------------*/ + + +/*-----------------------------------------------------------------------*/ +/* RETURN ARGUMENTS : */ +/* _ None */ +/*=======================================================================*/ + +void transition_dec_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + const Word16 Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ + const Word16 L_frame, /* i : length of the frame */ + const Word16 i_subfr, /* i : subframe index */ + const Word16 tc_subfr, /* i : TC subframe index */ + Word16 *Jopt_flag, /* i : joint optimization flag */ + Word16 *exc, /* o : excitation signal */ + Word16 *T0, /* o : close loop integer pitch */ + Word16 *T0_frac, /* o : close loop fractional part of the pitch */ + Word16 *T0_min, /* i/o: delta search min for sf 2 & 4 */ + Word16 *T0_max, /* i/o: delta search max for sf 2 & 4 */ + Word16 **pt_pitch, /* o : floating pitch values */ + Word16 *position, /* i/o: first glottal impulse position in frame */ + Word16 *bwe_exc, /* o : excitation for SWB TBE */ + Word16 *Q_exc /*i/o : scaling of excitation */ +) +{ + Word16 pit_flag, pit_start, pit_limit, index, nBits; + Word16 i, offset,temp,tmp; + Word16 limit_flag; + Word16 i_subfridx; +#ifdef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING + (void)(Opt_AMR_WB); +#endif + + i_subfridx = shr(i_subfr, 6); /*i_subfr / L_SUBFR*/ + /* Set limit_flag to 0 for restrained limits, and 1 for extended limits */ + limit_flag = 0; + + /*---------------------------------------------------------------------* + * zero adaptive contribution (glottal shape codebook search not + * in first subframe(s) ) + *---------------------------------------------------------------------*/ + IF(GT_16(tc_subfr, add(i_subfr,TC_0_192))) + { + set16_fx(&exc[i_subfr], 0, L_SUBFR); + + IF( EQ_16(L_frame,L_FRAME)) + { + set16_fx(&bwe_exc[i_subfr*HIBND_ACB_L_FAC], 0, (Word16) (L_SUBFR*HIBND_ACB_L_FAC)); /* set past excitation buffer to 0 */ + } + ELSE + { + set16_fx(&bwe_exc[i_subfr*2], 0, (Word16) (L_SUBFR*2)); /* set past excitation buffer to 0 */ + } + + *T0 = L_SUBFR; + move16(); + *T0_frac = 0; + move16(); + **pt_pitch = L_SUBFR_Q6; + move16(); + } + + /*---------------------------------------------------------------------* + * glottal shape codebook search + *---------------------------------------------------------------------*/ + + ELSE IF(((GE_16(tc_subfr,i_subfr))&&(LE_16(sub(tc_subfr,i_subfr),TC_0_192)))) + { + set16_fx( exc-L_EXC_MEM, 0, L_EXC_MEM ); /* set past excitation buffer to 0 */ + + IF( EQ_16(L_frame,L_FRAME)) + { + set16_fx( bwe_exc-PIT_MAX*HIBND_ACB_L_FAC, 0, PIT_MAX*HIBND_ACB_L_FAC); /* set past excitation buffer to 0 */ + } + ELSE + { + set16_fx( bwe_exc-PIT16k_MAX*2, 0, PIT16k_MAX*2); /* set past excitation buffer to 0 */ + } + + /* glottal shape codebook contribution construction */ + tc_dec_fx( st_fx, L_frame, exc, T0, T0_frac, i_subfr, tc_subfr, position, bwe_exc, Q_exc ); + **pt_pitch = shl(add(shl(*T0,2),*T0_frac),4); + move16(); /* save subframe pitch values Q6 */ + + *Jopt_flag = 1; + move16(); + } + + /*---------------------------------------------------------------------* + * Regular ACELP Decoding using GENERIC type decoder + * (all subframes following subframe with glottal shape codebook seach) + * - search the position of the 2nd glottal impulse in case that the first + * one is in the 1st subframe (different adaptive contribution + * construction and the pitch period coding is used) + *---------------------------------------------------------------------*/ + + ELSE IF ( LT_16(tc_subfr,i_subfr)) + { + IF( EQ_16(L_frame,L_FRAME)) + { + *Jopt_flag = 1; + move16(); + test(); + IF( (GE_16(sub(i_subfr,tc_subfr),L_SUBFR))&&(LE_16(sub(i_subfr,tc_subfr),L_SUBFR+TC_0_192))) + { + pit_flag = 0; + move16(); + } + ELSE + { + pit_flag = L_SUBFR; + move16(); + } + IF( EQ_16(tc_subfr,TC_0_0)) + { + IF( EQ_16(i_subfr,L_SUBFR)) + { + limit_T0_fx( L_FRAME, 8, pit_flag, limit_flag, *T0, 0, T0_min, T0_max ); + } + pit_flag = 1; + move16(); + } + + /*-----------------------------------------------------------------* + * get number of bits for pitch decoding + *-----------------------------------------------------------------*/ + nBits = st_fx->acelp_cfg.pitch_bits[i_subfridx]; + move16(); + + /*------------------------------------------------------------* + * first glottal impulse is in the 1st subframe + *------------------------------------------------------------*/ + test(); + test(); + test(); + test(); + test(); + test(); + IF( (EQ_16(i_subfr,L_SUBFR))&&(GE_16(tc_subfr,TC_0_128))) + { + /*--------------------------------------------------------* + * second glottal impulse is in the 3rd or 4th subframe + * - build exc[] in 2nd subframe + *--------------------------------------------------------*/ + + *T0 = 2*L_SUBFR; + move16(); + *T0_frac = 0; + move16(); + *Jopt_flag = 0; + move16(); + + /* set adaptive part of exciation for curent subframe to 0 */ + set16_fx( &exc[i_subfr], 0, (Word16)(L_SUBFR+1) ); + set16_fx( &bwe_exc[i_subfr*HIBND_ACB_L_FAC], 0, (Word16)(L_SUBFR*HIBND_ACB_L_FAC) ); + + } + ELSE IF( (EQ_16(i_subfr,L_SUBFR))&&(EQ_16(tc_subfr,TC_0_64))) + { + /*--------------------------------------------------------* + * second glottal impulse is in the 2nd subframe, + * - build exc[] in 2nd subframe + *--------------------------------------------------------*/ + pit_start = PIT_MIN; + move16(); + if (GT_16(PIT_MIN,(*position))) + { + pit_start = sub(L_SUBFR, *position); + } + + pit_start = s_max(pit_start, PIT_MIN ); + pit_limit = add(shl(pit_start,1), *position); + + /* 7 bit pitch DECODER */ + index = (Word16)get_next_indice( st_fx, nBits ); + + *T0 = add(pit_start, shr((index),1)); + move16(); + *T0_frac = shl(sub((index),shl(sub(*T0, pit_start),1)),1); + move16(); + + limit_T0_fx( L_FRAME, 8, pit_flag, limit_flag, *T0, 0, T0_min, T0_max ); /* find T0_min and T0_max */ + + /* Find the adaptive codebook vector - ACELP long-term prediction */ + pred_lt4(&exc[i_subfr], &exc[i_subfr], *T0, *T0_frac, L_SUBFR+1, pitch_inter4_2, L_INTERPOL2, PIT_UP_SAMP); + offset = tbe_celp_exc_offset(*T0, *T0_frac, L_frame); + + move16(); + move16(); /* penality for 2 ptrs initialization */ + + FOR (i=0; iBER_detect = 1; + move16(); + } + + /* Find the adaptive codebook vector. ACELP long-term prediction */ + pred_lt4(&exc[i_subfr], &exc[i_subfr], *T0, *T0_frac, L_SUBFR+1, pitch_inter4_2, L_INTERPOL2, PIT_UP_SAMP); + offset = tbe_celp_exc_offset(*T0, *T0_frac, L_frame); + move16(); + move16(); /* penality for 2 ptrs initialization */ + FOR (i=0; iBER_detect ); + + /* Find the adaptive codebook vector */ + pred_lt4(&exc[i_subfr], &exc[i_subfr], *T0, *T0_frac, L_SUBFR+1, pitch_inter4_2, L_INTERPOL2, PIT_UP_SAMP); + offset = tbe_celp_exc_offset(*T0, *T0_frac, L_frame); + move16(); + move16(); /* penality for 2 ptrs initialization */ + FOR (i=0; iacelp_cfg.ltf_mode, exc); + } + + /*---------------------------------------------------------------------* + * fill the pitch buffer - needed for post-processing and FEC_clas_estim() + *---------------------------------------------------------------------*/ + + **pt_pitch = shl(add(shl(*T0,2),*T0_frac),4); + move16(); /* save subframe pitch values Q6 */ + + test(); + test(); + test(); + test(); + test(); + IF( (GE_16(tc_subfr,2*L_SUBFR))&&(EQ_16(i_subfr,3*L_SUBFR))) + { + tmp = shl(add(shl(*T0,2),*T0_frac),4); + (*pt_pitch) -= 3; + move16(); + **pt_pitch = tmp; + move16(); /*Q6*/ + (*pt_pitch)++; + **pt_pitch = tmp; + move16(); /*Q6*/ + (*pt_pitch) ++; + move16(); + **pt_pitch = tmp; + move16(); /*Q6*/ + (*pt_pitch) ++; + move16(); + } + ELSE IF( (EQ_16(tc_subfr,L_SUBFR))&&(EQ_16(i_subfr,2*L_SUBFR))) + { + tmp = shl(add(shl(*T0,2),*T0_frac),4); + (*pt_pitch) -= 2; + move16(); + **pt_pitch = tmp; + move16(); /*Q6*/ + (*pt_pitch)++; + **pt_pitch = tmp; + move16(); /*Q6*/ + (*pt_pitch) ++; + move16(); + + } + ELSE IF( (EQ_16(tc_subfr,TC_0_64))&&(EQ_16(i_subfr,L_SUBFR))) + { + tmp = shl(add(shl(*T0,2),*T0_frac),4); + (*pt_pitch) -= 1; + move16(); + **pt_pitch = tmp; + move16(); /*Q6*/ + (*pt_pitch)++; + } + ELSE IF( (EQ_16(tc_subfr,TC_0_128))&&(EQ_16(i_subfr,2*L_SUBFR))) + { + tmp = shl(add(shl(*T0,2),*T0_frac),4); + (*pt_pitch) -= 2; + move16(); + **pt_pitch = tmp; + move16(); /*Q6*/ + (*pt_pitch)++; + **pt_pitch = tmp; + move16(); /*Q6*/ + (*pt_pitch) ++; + move16(); + } + ELSE IF( (EQ_16(tc_subfr,TC_0_192))&&(EQ_16(i_subfr,3*L_SUBFR))) + { + tmp = shl(add(shl(*T0,2),*T0_frac),4); + (*pt_pitch) -= 3; + move16(); + **pt_pitch = tmp; + move16(); /*Q6*/ + (*pt_pitch)++; + **pt_pitch = tmp; + move16(); /*Q6*/ + (*pt_pitch) ++; + move16(); + **pt_pitch = tmp; + move16(); /*Q6*/ + (*pt_pitch) ++; + move16(); + } + } + ELSE /* L_frame == L_FRAME16k */ + { + test(); + if( GE_16(i_subfr,2*L_SUBFR)) + { + limit_flag = 1; + move16(); + } + + IF( EQ_16(sub(i_subfr, tc_subfr), L_SUBFR)) + { + limit_T0_fx( L_FRAME16k, 8, 0, limit_flag, *T0, *T0_frac, T0_min, T0_max ); + } + + /*-----------------------------------------------------------------* + * get number of bits and index for pitch decoding + *-----------------------------------------------------------------*/ + nBits = st_fx->acelp_cfg.pitch_bits[i_subfridx]; + move16(); + + index = (Word16)get_next_indice( st_fx, nBits ); + + /*-----------------------------------------------------------------* + * Find adaptive part of excitation, encode pitch period + *-----------------------------------------------------------------*/ + + IF( EQ_16(nBits,10)) + { + pit16k_Q_dec_fx( index, nBits, limit_flag, T0, T0_frac, T0_min, T0_max, &st_fx->BER_detect ); + } + ELSE IF( EQ_16(nBits,8)) /* tc_subfr==0 && i_subfr==L_SUBFR */ + { + /*-----------------------------------------------------------------------------* + * The pitch range is encoded absolutely with 8 bits and is divided as follows: + * PIT16k_MIN to PIT16k_FR2_TC0_2SUBFR-1 resolution 1/4 (frac = 0,1,2 or 3) + * PIT16k_FR2_TC0_2SUBFR to 2*L_SUBFR resolution 1/2 (frac = 0 or 2) + *-----------------------------------------------------------------------------*/ + + IF( LT_16(index,(PIT16k_FR2_TC0_2SUBFR-PIT16k_MIN)*4))/*(PIT16k_FR2_TC0_2SUBFR-PIT16k_MIN)*4*/ + { + *T0 = add(PIT16k_MIN,shr(index,2)); + move16(); + temp = shl(sub(*T0,PIT16k_MIN),2); + move16(); + *T0_frac = sub(index,temp); + move16(); + } + ELSE + { + index = sub(index,(PIT16k_FR2_TC0_2SUBFR-PIT16k_MIN)*4); /* (PIT16k_FR2_TC0_2SUBFR-PIT16k_MIN)*4 */ + *T0 = add(PIT16k_FR2_TC0_2SUBFR,shr(index,1)); + move16(); + temp = shl(sub(*T0,PIT16k_FR2_TC0_2SUBFR),1); + move16(); + *T0_frac = shl(sub(index,temp),1); + move16(); + } + + /* biterror detection mechanism */ + IF( GT_16(add((*T0<<2),*T0_frac),((2*L_SUBFR)<<2))) + { + *T0 = L_SUBFR; + move16(); + *T0_frac = 0; + move16(); + st_fx->BER_detect = 1; + move16(); + } + } + ELSE IF( EQ_16(nBits,6)) + { + delta_pit_dec_fx( 4, index, T0, T0_frac, *T0_min ); + } + IF( EQ_16(nBits,6)) + { + limit_T0_fx( L_FRAME16k, 8, L_SUBFR, limit_flag, *T0, *T0_frac, T0_min, T0_max ); /* find T0_min and T0_max */ + } + + /*-----------------------------------------------------------------* + * - find the adaptive codebook vector + * - LP filtering of the adaptive excitation (if non-zero) + *-----------------------------------------------------------------*/ + test(); + IF( (EQ_16(i_subfr,L_SUBFR))&&(EQ_16(*T0,2*L_SUBFR))) + { + /* no adaptive excitation in the second subframe */ + set16_fx( &exc[i_subfr], 0, L_SUBFR+1 ); + get_next_indice( st_fx, 1 ); /* this bit is actually not needed */ + set16_fx( &bwe_exc[i_subfr * 2], 0, L_SUBFR * 2 ); + } + ELSE + { + /* Find the adaptive codebook vector - ACELP long-term prediction */ + pred_lt4(&exc[i_subfr], &exc[i_subfr], *T0, *T0_frac, L_SUBFR+1, pitch_inter4_2, L_INTERPOL2, PIT_UP_SAMP); + offset = tbe_celp_exc_offset(*T0, *T0_frac, L_frame); + move16(); + move16(); /* penalty for 2 ptrs initialization */ + FOR (i=0; iacelp_cfg.ltf_mode, exc ); + *Jopt_flag = 1; + move16(); + } + + **pt_pitch = shl(add(shl(*T0,2),*T0_frac),4); + move16(); /* save subframe pitch values Q6 */ + + /*---------------------------------------------------------------------* + * fill the pitch buffer - needed for post-processing and FEC_clas_estim() + *---------------------------------------------------------------------*/ + test(); + test(); + IF( (EQ_16(sub(i_subfr, tc_subfr),L_SUBFR))||(tc_subfr==0&&EQ_16(i_subfr,2*L_SUBFR))) + { + /*index = i_subfr/L_SUBFR;*/ + index = shr(i_subfr,6); + + /*Ptr */ + (*pt_pitch) -= index; + move16(); + + FOR( i=0; iacelp_cfg.pitch_bits[shr(i_subfr,6)]; + move16(); + /*----------------------------------------------------------------* + * decode parameter T0 (pitch period) + *----------------------------------------------------------------*/ + IF( EQ_16(L_frame,L_FRAME)) + { + test(); + test(); + test(); + test(); + test(); + IF ( ((i_subfr == 0) && ((tc_subfr == 0) || (EQ_16(tc_subfr,TC_0_64))||(EQ_16(tc_subfr,TC_0_128))||(EQ_16(tc_subfr,TC_0_192))))||(EQ_16(tc_subfr,L_SUBFR))) + { + *T0 = L_SUBFR; + move16(); + *T0_frac = 0; + move16(); + } + ELSE IF( (tc_subfr == 3*L_SUBFR) ) + { + i = (Word16)get_next_indice( st_fx, nBits ); + + IF( EQ_16(nBits,9)) + { + abs_pit_dec_fx( 4, i, 0, T0, T0_frac ); + } + ELSE + { + abs_pit_dec_fx( 2, i, 0, T0, T0_frac ); + } + } + ELSE + { + i = (Word16)get_next_indice( st_fx, nBits ); + move16(); + + IF( i == 0 ) + { + *T0 = L_SUBFR; + move16(); + *T0_frac = 0; + move16(); + } + ELSE + { + IF( EQ_16(tc_subfr,TC_0_0)) + { + delta_pit_dec_fx( 2, i, T0, T0_frac, PIT_MIN-1 ); + } + ELSE + { + delta_pit_dec_fx( 0, i, T0, T0_frac, PIT_MIN-1 ); + } + } + } + } + ELSE /* L_frame == L_FRAME16k */ + { + i = (Word16)get_next_indice( st_fx, nBits ); + move16(); + + IF( EQ_16(nBits,10)) + { + IF( LT_16(i,(PIT16k_FR2_EXTEND_10b-PIT16k_MIN_EXTEND)*4)) + { + *T0 = add(PIT16k_MIN_EXTEND,shr(i,2)); + move16(); + temp = shl(sub(*T0,PIT16k_MIN_EXTEND),2); + *T0_frac = sub(i,temp); + move16(); + } + ELSE + { + index = sub(i,shl(sub(PIT16k_FR2_EXTEND_10b,PIT16k_MIN_EXTEND),2)); + *T0 = add(PIT16k_FR2_EXTEND_10b,shr(index,1)); + *T0_frac = sub(index ,shl(sub(*T0,PIT16k_FR2_EXTEND_10b),1)); + (*T0_frac) = shl(*T0_frac,1); + } + } + ELSE IF( EQ_16(nBits,6)) + { + *T0 = add(PIT16k_MIN ,shr(i,1)); + move16(); + *T0_frac = sub(i,shl(sub(*T0,PIT16k_MIN),1)); + *T0_frac = shl(*T0_frac,1); + move16(); + } + } + + /*----------------------------------------------------------------* + * decode other TC parameters + *----------------------------------------------------------------*/ + + imp_shape = (Word16)get_next_indice( st_fx, 3 ); + move16(); + imp_pos = (Word16)get_next_indice( st_fx, 6 ); + move16(); + imp_sign = (Word16)get_next_indice( st_fx, 1 ); + move16(); + imp_gain = (Word16)get_next_indice( st_fx, 3 ); + move16(); + + /*----------------------------------------------------------------* + * - restore gain_trans + * - build glottal codebook contribution + *----------------------------------------------------------------*/ + + gain_trans = tbl_gain_trans_tc_fx[imp_gain]; + move16(); + test(); + if( imp_sign == 0 ) + { + gain_trans = negate(gain_trans); + } + + /* local max for scaling need */ + /* maximum of impulse always takes 15 bits (except impulse #7 wich is using 14 bits) */ + + tempS = 4; + move16(); + test(); + if (LE_16(imp_gain, 3)) + { + tempS = 7; + move16(); + } + + /* build glottal codebook contribution */ + sc = add(13-15, tempS); /* scaling of curent exc */ + sc = sub(*Q_exc, sc); + + pt_shape = &Glottal_cdbk_fx[add(sub(i_mult2(imp_shape, L_IMPULSE), imp_pos), L_IMPULSE2)]; + move16(); + + j = s_max(0, sub(imp_pos, L_IMPULSE2)); + move16(); /* penalty for exc + i_subfr initialisation */ + FOR (i = 0; i < j; i++) + { + exc[i+i_subfr] = 0; + move16(); + } + j = s_min(L_SUBFR, add(imp_pos, L_IMPULSE2)); + FOR (; i <= j; i++) + { +#ifdef BASOP_NOGLOB + exc[i+i_subfr] = round_fx_o(L_shl_o(L_mult_o(pt_shape[i], gain_trans, &Overflow), sc, &Overflow), &Overflow); /* (Qx * Q14 ) */ +#else + exc[i+i_subfr] = round_fx(L_shl(L_mult(pt_shape[i], gain_trans), sc)); /* (Qx * Q14 ) */ +#endif + } + FOR (; i < L_SUBFR; i++) + { + exc[i+i_subfr] = 0; + move16(); + } + + /*--------------------------------------------------------------* + * adapt. search of the second impulse in the same subframe + * (when appears) + *--------------------------------------------------------------*/ + + pred_lt4_tc_fx( exc, *T0, *T0_frac, inter4_2_fx, imp_pos, i_subfr ); + IF (st_fx->hBWE_TD != NULL) + { + IF(EQ_16(L_frame, L_FRAME)) + { + interp_code_5over2_fx(&exc[i_subfr], &bwe_exc[i_subfr * HIBND_ACB_L_FAC], L_SUBFR); + } + ELSE + { + interp_code_4over2_fx(&exc[i_subfr], &bwe_exc[i_subfr * 2], L_SUBFR); + } + } + *position = add(imp_pos, i_subfr); + move16(); + return; +} + +/*-------------------------------------------------------------------* + * tc_classif_fx() + * + * TC subframe classification decoding + *-------------------------------------------------------------------*/ + +Word16 tc_classif_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + const Word16 L_frame /* i : length of the frame */ +) +{ + Word16 tc_subfr, indice; +#ifdef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING + (void)(L_frame); +#endif + IF( EQ_16(st_fx->L_frame, L_FRAME)) + { + if ( get_next_indice( st_fx, 1 ) ) + { + tc_subfr = TC_0_0; + move16(); + } + ELSE + { + IF ( get_next_indice( st_fx, 1 ) ) + { + tc_subfr = 0; + move16(); + + IF ( get_next_indice( st_fx, 1 ) ) + { + tc_subfr = TC_0_192; + move16(); + } + ELSE + { + tc_subfr = TC_0_128; + move16(); + if ( get_next_indice( st_fx, 1 ) ) + { + tc_subfr = TC_0_64; + move16(); + } + } + } + ELSE + { + IF ( get_next_indice( st_fx, 1 ) ) + { + tc_subfr = L_SUBFR; + move16(); + } + ELSE + { + tc_subfr = 3*L_SUBFR; + move16(); + if ( get_next_indice( st_fx, 1 ) ) + { + tc_subfr = 2*L_SUBFR; + move16(); + } + } + } + } + } + ELSE /* L_frame == L_FRAME16k */ + { + indice = (Word16) get_next_indice( st_fx, 2 ); + + IF( LT_16(indice,3)) + { + tc_subfr = shl(indice, 6); + } + ELSE + { + tc_subfr = 4*L_SUBFR; + move16(); + if( get_next_indice( st_fx, 1 ) == 0 ) + { + tc_subfr = 3*L_SUBFR; + move16(); + } + } + } + + return( tc_subfr ); +} diff --git a/lib_dec/updt_dec.c b/lib_dec/updt_dec.c index 2e75f82b03db2b2232372267bef3565dee7c8dec..f63c9657ee7a096f1f7b0cc9f761c0e8e720c613 100644 --- a/lib_dec/updt_dec.c +++ b/lib_dec/updt_dec.c @@ -319,7 +319,7 @@ void updt_IO_switch_dec( /* AMR-WB IO init */ mvr2r( st->hAmrwb_IO->lt_diff_etot, tmpF, MAX_LT ); - amr_wb_dec_init( st->hAmrwb_IO ); + amr_wb_dec_init_flt( st->hAmrwb_IO ); mvr2r( tmpF, st->hAmrwb_IO->lt_diff_etot, MAX_LT ); hf_synth_amr_wb_reset( st->hAmrwb_IO, st->hBWE_zero ); @@ -654,12 +654,12 @@ void updt_dec_common( } /*-------------------------------------------------------------------* - * update_decoder_LPD_cng() + * update_decoder_LPD_cng_flt() * * *--------------------------------------------------------------------*/ -void update_decoder_LPD_cng( +void update_decoder_LPD_cng_flt( Decoder_State *st, float *timeDomainBuffer, float *A, @@ -729,7 +729,7 @@ void update_decoder_LPD_cng( /* Reset acelp memories */ set_zero( st->dispMem, 8 ); - st->tilt_code = TILT_CODE; + st->tilt_code = TILT_CODE_FLT; st->gc_threshold = 0.0f; /* Update ace/tcx mode */ @@ -772,7 +772,7 @@ void update_decoder_LPD_cng( pf_gain[0] = pf_gain[1] = pf_gain[2] = pf_gain[3] = pf_gain[4] = 0.f; st->bpf_gain_param = 0; - post_decoder( st, buf_synth, pf_gain, pf_pitch, timeDomainBuffer, bpf_noise_buf ); + post_decoder_flt( st, buf_synth, pf_gain, pf_pitch, timeDomainBuffer, bpf_noise_buf ); return; } diff --git a/lib_dec/updt_dec_fx.c b/lib_dec/updt_dec_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..6f85992883a436629f74521eff1fb75fbc7eb600 --- /dev/null +++ b/lib_dec/updt_dec_fx.c @@ -0,0 +1,931 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include +#include +#include "options.h" +#include "cnst.h" /* Common constants */ +#include "rom_com.h" /* Static table prototypes */ +#include "prot_fx1.h" /* Function prototypes */ +#include "prot_fx2.h" /* Function prototypes */ + +/*-------------------------------------------------------------------* + * updt_dec() + * + * Common updates (all frame types) + *-------------------------------------------------------------------*/ +void updt_dec_fx( + Decoder_State *st_fx, /* i/o: state structure */ + const Word16 *old_exc_fx, /* i : buffer of excitation */ + const Word16 *pitch_buf_fx, /* i : floating pitch values for each subframe */ + const Word16 Es_pred, /* i : predicited scaled innovation energy */ + const Word16 *Aq, /* i : A(z) quantized for all subframes */ + const Word16 *lsf_new_fx, /* i : current frame LSF vector */ + const Word16 *lsp_new_fx, /* i : current frame LSP vector */ + const Word16 voice_factors[], /* i : voicing factors */ + const Word16 *old_bwe_exc_fx, /* i : buffer of excitation */ + const Word16 *gain_buf /* i : floating pitch gain for each subframe Q14*/ +) +{ + Word16 i, len; + HQ_DEC_HANDLE hHQ_core; + TD_BWE_DEC_HANDLE hBWE_TD; + hBWE_TD = st_fx->hBWE_TD; + hHQ_core = st_fx->hHQ_core; + + /* update old excitation buffer */ + Copy( &old_exc_fx[st_fx->L_frame], st_fx->old_exc_fx, L_EXC_MEM_DEC ); + IF( !st_fx->Opt_AMR_WB && hBWE_TD != NULL) + { + Copy( &old_bwe_exc_fx[L_FRAME32k], hBWE_TD->old_bwe_exc_fx, PIT16k_MAX * 2 ); + } + + /* update old LSP and LSF vector */ + Copy( lsf_new_fx, st_fx->lsf_old_fx, M ); + Copy( lsp_new_fx, st_fx->lsp_old_fx, M ); + + /* update last coding type */ + st_fx->last_coder_type_fx = st_fx->coder_type_fx; + test(); + test(); + test(); + if( EQ_16(st_fx->coder_type_fx,INACTIVE) || (EQ_16(st_fx->bpf_off,1) && NE_16(st_fx->coder_type_fx,AUDIO) && NE_16(st_fx->coder_type_fx,TRANSITION))) + { + st_fx->last_coder_type_fx = UNVOICED; + move16(); + } + test(); + test(); + IF (st_fx->hGSCDec != NULL ) + { + IF ((NE_16(st_fx->coder_type_fx, AUDIO) || st_fx->Last_GSC_noisy_speech_flag_fx != 0) && st_fx->hGSCDec->Last_GSC_pit_band_idx_fx > 0) + { + st_fx->hGSCDec->Last_GSC_pit_band_idx_fx = 0; + move16(); /*The temporal contribution of the GSC is meaningless after 1 frame lost for inactive & unvoiced content */ + } + } + + /* this ensures that st_fx->last_coder_type_fx is never set to INACTIVE in case of AVQ inactive because the FEC does not distinguish between GSC inactive and AVQ inactive */ + + test(); + if( GT_32(st_fx->total_brate,ACELP_24k40) && EQ_16(st_fx->coder_type_fx,INACTIVE)) + { + st_fx->last_coder_type_fx = GENERIC; + move16(); + } + test(); + test(); + test(); + IF( EQ_16(st_fx->Opt_AMR_WB,1) && EQ_16(st_fx->coder_type_fx,INACTIVE) && + NE_32(st_fx->core_brate,SID_1k75) && NE_32(st_fx->core_brate,FRAME_NO_DATA)) + { + /* overwrite previous coding type to help FEC */ + st_fx->last_coder_type_fx = UNVOICED; + move16(); + st_fx->last_voice_factor_fx = voice_factors[NB_SUBFR-1]; + move16(); + } + + IF( !st_fx->Opt_AMR_WB ) + { + /* update voicing factor of TBE to help FEC */ + + st_fx->last_voice_factor_fx = voice_factors[NB_SUBFR16k-1]; + move16(); + if( EQ_16(st_fx->L_frame,L_FRAME)) + { + st_fx->last_voice_factor_fx = voice_factors[NB_SUBFR-1]; + move16(); + } + } + test(); + IF(st_fx->hGSCDec != NULL && st_fx->coder_type_fx != AUDIO && st_fx->coder_type_fx != INACTIVE) + { + st_fx->hGSCDec->noise_lev_fx = NOISE_LEVEL_SP3; + move16(); + set16_fx(st_fx->hGSCDec->old_y_gain_fx, 0, MBANDS_GN); + + FOR(i = 0; i < L_FRAME; i++) + { + Word16 tmp_seed = st_fx->hGSCDec->seed_tcx_fx; + move16(); + st_fx->hGSCDec->Last_GSC_spectrum_fx[i] = shr_r(Random(&tmp_seed), 5); + move16(); /*Q10*/ + } + } + + /* update last GSC SWB speech flag for FEC */ + st_fx->Last_GSC_noisy_speech_flag_fx = st_fx->GSC_noisy_speech_fx; + move16(); + + /* update counter for FEC pitch estimate */ + st_fx->upd_cnt = add(st_fx->upd_cnt,1); + + st_fx->upd_cnt = s_min(st_fx->upd_cnt, MAX_UPD_CNT); + + len = shr(st_fx->L_frame,6); + Copy32( &st_fx->old_pitch_buf_fx[len], st_fx->old_pitch_buf_fx, len ); + FOR ( i = 0; i < len; i++ ) + { + st_fx->old_pitch_buf_fx[len+i] = L_mult0(pitch_buf_fx[i], 1<<10); + move32(); + } + Copy( &st_fx->mem_pitch_gain[2], &st_fx->mem_pitch_gain[st_fx->L_frame/L_SUBFR+2], st_fx->L_frame/L_SUBFR ); + IF (EQ_16(st_fx->L_frame , L_FRAME)) + { + st_fx->mem_pitch_gain[2] = gain_buf[3]; + move16(); + st_fx->mem_pitch_gain[3] = gain_buf[2]; + move16(); + st_fx->mem_pitch_gain[4] = gain_buf[1]; + move16(); + st_fx->mem_pitch_gain[5] = gain_buf[0]; + move16(); + } + ELSE + { + st_fx->mem_pitch_gain[2] = gain_buf[4]; + move16(); + st_fx->mem_pitch_gain[3] = gain_buf[3]; + move16(); + st_fx->mem_pitch_gain[4] = gain_buf[2]; + move16(); + st_fx->mem_pitch_gain[5] = gain_buf[1]; + move16(); + st_fx->mem_pitch_gain[6] = gain_buf[0]; + move16(); + } + + + /* FEC - update adaptive LSF mean vector */ + Copy( st_fx->lsfoldbfi0_fx, st_fx->lsfoldbfi1_fx, M ); + Copy( lsf_new_fx, st_fx->lsfoldbfi0_fx, M ); + + /* update of pitch and voicing information for HQ FEC */ + IF(hHQ_core != NULL) + { + IF(NE_16(st_fx->last_core, HQ_CORE)) + { + hHQ_core->HqVoicing_fx = 1; + move16(); + test(); + if (!st_fx->Opt_AMR_WB && EQ_16(st_fx->coder_type_fx, UNVOICED)) + { + hHQ_core->HqVoicing_fx = 0; + move16(); + } + } + } + + /* SC-VBR */ + st_fx->old_ppp_mode_fx = st_fx->last_ppp_mode_dec_fx; + move16(); + st_fx->last_ppp_mode_dec_fx = st_fx->ppp_mode_dec_fx; + move16(); + st_fx->last_nelp_mode_dec_fx = st_fx->nelp_mode_dec_fx; + move16(); + st_fx->last_vbr_hw_BWE_disable_dec_fx = st_fx->vbr_hw_BWE_disable_dec_fx; + move16(); + + /*core switching updates*/ + Copy( &Aq[(st_fx->L_frame/L_SUBFR-1)*(M+1)], st_fx->old_Aq_12_8_fx, M+1 ); + st_fx->old_Es_pred_fx = Es_pred; + move16(); + + return; +} + +/*-------------------------------------------------------------------* + * updt_IO_switch() + * + * Common updates for AMR-WB IO mode and EVS primary switching + *-------------------------------------------------------------------*/ +void updt_IO_switch_dec_fx( + const Word16 output_frame, /* i : output frame length */ + Decoder_State *st_fx /* o : Decoder static variables structure */ +) +{ + Word16 xsp_tmp[M]; + Word16 tmp_buf[MAX_LT]; + FD_BWE_DEC_HANDLE hBWE_FD; + TD_BWE_DEC_HANDLE hBWE_TD; + + hBWE_TD = st_fx->hBWE_TD; + hBWE_FD = st_fx->hBWE_FD; + + IF( EQ_16(st_fx->last_core,AMR_WB_CORE)) /* switching to EVS primary mode */ + { + /* AMR-WB IO mode uses ISF(ISP), but EVS primary mode mode LSF(LSP) */ + Copy( stable_LSP_fx, xsp_tmp, M ); + isf2lsf_fx( st_fx->lsf_old_fx, st_fx->lsf_old_fx, xsp_tmp); + Copy( stable_LSP_fx, xsp_tmp, M ); + /*isp2lsp( st->lsp_old, st->lsp_old, xsp_tmp, M, grid100 );*/ + isp2lsp_fx( st_fx->lsp_old_fx, st_fx->lsp_old_fx, xsp_tmp, M); + + /* AMR-WB IO mode uses ISF(ISP), but EVS primary mode uses LSF(LSP) */ + Copy( stable_LSP_fx, xsp_tmp, M ); + /*isp2lsp( st->lspCNG, st->lspCNG, xsp_tmp, M, grid100 );*/ + isp2lsp_fx( st_fx->lspCNG_fx, st_fx->lspCNG_fx, xsp_tmp, M); + IF(st_fx->hTdCngDec != NULL) + { + st_fx->hTdCngDec->old_enr_index_fx = s_min(shl(st_fx->hTdCngDec->old_enr_index_fx, 1), 127); + } + /* reset TD BWE buffers */ + st_fx->last_voice_factor_fx = 0; + IF(hBWE_TD != NULL) + { + set16_fx(hBWE_TD->old_bwe_exc_fx, 0, PIT16k_MAX * 2); + set16_fx(hBWE_TD->old_bwe_exc_extended_fx, 0, NL_BUFF_OFFSET); + hBWE_TD->bwe_non_lin_prev_scale_fx = 0; + move16(); + move16(); + + wb_tbe_extras_reset_fx(hBWE_TD->mem_genSHBexc_filt_down_wb2_fx, hBWE_TD->mem_genSHBexc_filt_down_wb3_fx); + wb_tbe_extras_reset_synth_fx(hBWE_TD->state_lsyn_filt_shb_fx, hBWE_TD->state_lsyn_filt_dwn_shb_fx, hBWE_TD->state_32and48k_WB_upsample_fx, hBWE_TD->mem_resamp_HB_fx); + IF( GE_16(output_frame,L_FRAME32k)) + { + swb_tbe_reset_fx(hBWE_TD->mem_csfilt_fx, hBWE_TD->mem_genSHBexc_filt_down_shb_fx, hBWE_TD->state_lpc_syn_fx, + hBWE_TD->syn_overlap_fx, hBWE_TD->state_syn_shbexc_fx, &hBWE_TD->tbe_demph_fx, &hBWE_TD->tbe_premph_fx + , hBWE_TD->mem_stp_swb_fx,&(hBWE_TD->gain_prec_swb_fx) ); + set16_fx( st_fx->GainShape_Delay, 0, NUM_SHB_SUBFR/2 ); + swb_tbe_reset_synth_fx(hBWE_TD->genSHBsynth_Hilbert_Mem_fx, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx ); + } + + IF( EQ_16(output_frame,L_FRAME48k)) + { + st_fx->prev_fb_ener_adjust_fx = 0; + move16(); + set16_fx(hBWE_TD->fb_state_lpc_syn_fx, 0, LPC_SHB_ORDER ); + hBWE_TD->fb_tbe_demph_fx = 0; + fb_tbe_reset_synth_fx(hBWE_TD->fbbwe_hpf_mem_fx, hBWE_TD->fbbwe_hpf_mem_fx_Q,&hBWE_TD->prev_fbbwe_ratio_fx ); + } + hBWE_FD->prev_Energy_wb_fx = L_deposit_l(0); + hBWE_FD->prev_weight_fx = 6554; + } + move16(); + + IF(hBWE_FD != NULL) + { + /* reset FD BWE buffers */ + hBWE_FD->prev_mode_fx = NORMAL; + move16(); + hBWE_FD->prev_Energy_fx = 0; + move16(); + hBWE_FD->prev_L_swb_norm_fx = 8; + move16(); + hBWE_FD->prev_frica_flag_fx = 0; + move16(); + set16_fx(hBWE_FD->mem_imdct_fx, 0, L_FRAME48k); + hBWE_FD->prev_td_energy_fx = 0; + move16(); + set16_fx(hBWE_FD->L_old_wtda_swb_fx, 0, L_FRAME48k); + } + /* HQ core buffers */ + set16_fx( st_fx->delay_buf_out_fx, 0, HQ_DELTA_MAX*HQ_DELAY_COMP ); + + /* reset the unvoiced/audio signal improvement memories */ + IF(st_fx->hGSCDec != NULL) + { + st_fx->hGSCDec->seed_tcx_fx = 15687; + } + move16(); + st_fx->hAmrwb_IO->UV_cnt_fx = 30; + st_fx->hAmrwb_IO->LT_UV_cnt_fx = (60<<6); + + move16(); + move16(); + + st_fx->use_acelp_preq = 0; + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + if (EQ_16(st_fx->last_flag_filter_NB, 1)) + { + st_fx->cldfbSyn_fx->bandsToZero = 0; + } + st_fx->last_active_bandsToZero_bwdec = 0; + st_fx->perc_bwddec = 0; + st_fx->last_flag_filter_NB = 0; + st_fx->active_frame_cnt_bwddec = 0; + set16_fx(st_fx->flag_buffer, 0, 20); + } + ELSE /* switching to AMR-WB IO mode */ + { + /* ISF Q memories */ + set16_fx( st_fx->mem_MA_fx, 0, M ); + + /* AMR-WB IO mode uses ISF(ISP), but EVS primary mode LSF(LSP) */ + Copy( stable_ISP_fx, xsp_tmp, M ); + lsf2isf_fx( st_fx->lsf_old_fx, st_fx->lsf_old_fx, xsp_tmp, M); + Copy( stable_ISP_fx, xsp_tmp, M ); + lsp2isp_fx( st_fx->lsp_old_fx, st_fx->lsp_old_fx, xsp_tmp, M); + + /* AMR-WB IO mode uses ISF(ISP), but EVS primary mode LSF(LSP) */ + Copy( stable_ISP_fx, xsp_tmp, M ); + lsp2isp_fx( st_fx->lspCNG_fx, st_fx->lspCNG_fx, xsp_tmp, M); + + IF(st_fx->hTdCngDec != NULL) + { + st_fx->hTdCngDec->old_enr_index_fx = s_max(s_min(shr(st_fx->hTdCngDec->old_enr_index_fx, 1), 63), 0); + } + + /* HF synthesis memories */ + st_fx->Ng_ener_ST_fx = -51*256; /*Q8*/ move16(); + + /* reset the unvoiced/audio signal improvement memories */ + IF(st_fx->hGSCDec != NULL) + { + st_fx->hGSCDec->seed_tcx_fx = 15687; + } + + Copy(st_fx->hAmrwb_IO->lt_diff_etot_fx, tmp_buf, MAX_LT); + amr_wb_dec_init(st_fx->hAmrwb_IO); + Copy(tmp_buf, st_fx->hAmrwb_IO->lt_diff_etot_fx, MAX_LT); + hf_synth_amr_wb_reset_fx(st_fx->hBWE_zero, st_fx->hAmrwb_IO); + + st_fx->psf_lp_noise_fx = round_fx(L_shl(st_fx->lp_noise,1)); + + /* reset VBR signalling */ + st_fx->last_ppp_mode_dec_fx = 0; + move16(); + st_fx->last_nelp_mode_dec_fx = 0; + move16(); + st_fx->ppp_mode_dec_fx = 0; + move16(); + st_fx->nelp_mode_dec_fx = 0; + move16(); + } + + /* CNG - reset */ + IF(st_fx->hTdCngDec != NULL) + { + st_fx->hTdCngDec->ho_hist_size_fx = 0; + } + move16(); + + /* LSF Q memories */ + Copy( UVWB_Ave_fx, st_fx->mem_AR_fx, M ); + + /* FEC - update adaptive LSF mean vector */ + Copy( st_fx->lsf_old_fx, st_fx->lsfoldbfi0_fx, M ); + Copy( st_fx->lsf_old_fx, st_fx->lsfoldbfi1_fx, M ); + Copy( st_fx->lsf_old_fx, st_fx->lsf_adaptive_mean_fx, M ); + + return; +} + +/*-------------------------------------------------------------------* + * updt_bw_switching() + * + * Updates for BW switching + *-------------------------------------------------------------------*/ + +void updt_bw_switching_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + const Word16 *synth, /* i : float synthesis signal */ + const Word16 Qpost +) +{ + test(); + IF(st_fx->output_Fs == 32000 && st_fx->bwidth == SWB) + { +#ifdef BASOP_NOGLOB + st_fx->tilt_swb_fx = round_fx_sat(L_shl_sat(calc_tilt_bwe_fx(synth, Qpost, L_FRAME32k), 3)); +#else + st_fx->tilt_swb_fx = round_fx(L_shl(calc_tilt_bwe_fx(synth, Qpost, L_FRAME32k), 3)); +#endif + } + + st_fx->prev_enerLH_fx = st_fx->enerLH_fx; + move32(); + st_fx->prev_enerLL_fx = st_fx->enerLL_fx; + move32(); + st_fx->last_bwidth = st_fx->bwidth; + move32(); + + IF( EQ_16(st_fx->core, ACELP_CORE)) + { + st_fx->last_inner_frame = L_FRAME32k; + move16(); + test(); + if( EQ_16(st_fx->bwidth, WB)&&st_fx->bws_cnt_fx==0) + { + st_fx->last_inner_frame = L_FRAME16k; + move16(); + } + } + ELSE + { + test(); + test(); + test(); + IF( !(GE_16(st_fx->last_inner_frame, L_FRAME16k)&&LE_16(inner_frame_tbl[st_fx->bwidth],L_FRAME16k)&&st_fx->bws_cnt_fx>0&<_16(st_fx->bws_cnt_fx,N_WS2N_FRAMES))) + { + st_fx->last_inner_frame = inner_frame_tbl[st_fx->bwidth]; + move16(); + } + } + st_fx->prev_bws_cnt_fx = st_fx->bws_cnt_fx; + move16(); + return; +} + +/*-------------------------------------------------------------------* + * updt_dec_common() + * + * Common updates for MODE1 and MODE2 + *-------------------------------------------------------------------*/ + +void updt_dec_common_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + Word16 hq_core_type_fx, /* i : HQ core type */ + const Word16 concealWholeFrameTmp, /* i : concealWholeFrameTmp flag */ + const Word16 *synth, /* i : decoded synthesis */ + const Word16 Qpostd /* i : Synthesis Q value */ + +) +{ + Word16 i; + Word32 L_tmp; + + TCX_DEC_HANDLE hTcxDec; + hTcxDec = st_fx->hTcxDec; + + st_fx->last_codec_mode = st_fx->codec_mode; + move16(); + st_fx->last_extl = st_fx->extl; + move16(); + st_fx->last_L_frame = st_fx->L_frame; + move16(); + + st_fx->prev_old_bfi_fx = st_fx->prev_bfi; + st_fx->prev_bfi = st_fx->bfi; + move16(); + if (NE_16(st_fx->core, AMR_WB_CORE)) + { + st_fx->old_bfi_cnt_fx = st_fx->nbLostCmpt; + move16(); + } + move16(); + st_fx->last_con_tcx = st_fx->con_tcx; + move16(); + st_fx->con_tcx = 0; + + move16(); + if(st_fx->hHQ_nbfec != NULL) + { + st_fx->hHQ_nbfec->prev_last_core_fx = st_fx->last_core; + } + if(st_fx->hTcxDec != NULL) + { + hTcxDec->tcxConceal_recalc_exc = 0; + move16(); + } + test();test(); + IF( (GE_16(st_fx->rf_frame_type,RF_TCXFD) && LE_16(st_fx->rf_frame_type,RF_TCXTD2) && st_fx->use_partial_copy && st_fx->bfi) || !st_fx->bfi) + { + test();test(); + test(); test(); + if( st_fx->bfi && (LE_16(st_fx->last_good_fx, UNVOICED_TRANSITION)) && (GT_16(st_fx->clas_dec,UNVOICED_TRANSITION)) && st_fx->last_con_tcx && st_fx->hTcxDec != NULL) + { + hTcxDec->tcxConceal_recalc_exc = 1; + move16(); + } + st_fx->last_good_fx = st_fx->clas_dec; + move16(); + } + IF (st_fx->use_partial_copy) + { + st_fx->prev_rf_frame_type = st_fx->rf_frame_type; + } + ELSE + { + st_fx->prev_rf_frame_type = INACTIVE; + } + + if (EQ_16(st_fx->m_frame_type, ACTIVE_FRAME) && (st_fx->bfi!=1 || st_fx->use_partial_copy!=0)) + { + st_fx->rf_flag_last = st_fx->rf_flag; + } + + IF( EQ_16(st_fx->codec_mode,MODE1)) + { + test(); + if( !st_fx->bfi && (st_fx->core_brate > SID_2k40 || (GT_32(st_fx->core_brate, SID_1k75) && EQ_16(st_fx->core, AMR_WB_CORE)))) + { + move16(); + st_fx->last_active_brate = st_fx->total_brate; + } + + move16(); + move16(); + st_fx->last_core = st_fx->core; + if (st_fx->hHQ_core != NULL) + { + st_fx->hHQ_core->last_hq_core_type_fx = hq_core_type_fx; + } + } + ELSE IF( EQ_16(st_fx->codec_mode,MODE2)) + { + test(); + if ((!st_fx->bfi) && (st_fx->last_is_cng==0)) + { + move16(); + st_fx->last_active_brate = st_fx->total_brate; + } + /* INFO: moved from update_decoder_LPD_cng() */ + if (NE_16(st_fx->m_frame_type,ACTIVE_FRAME)) + { + move16(); + st_fx->last_is_cng = 1; + } + + + if (!st_fx->bfi) + { + st_fx->last_core = st_fx->core; + } + move16(); + move16(); + st_fx->last_core_bfi = st_fx->core; /* also required for clean channel decoding */ + } + move16(); + st_fx->last_core_brate = st_fx->core_brate; + + /* save synthesis for core switching */ + test(); + IF (EQ_16(st_fx->element_mode, EVS_MONO) && NE_16(st_fx->core, AMR_WB_CORE)) + { + Copy_Scale_sig(synth + NS2SA_fx2(st_fx->output_Fs, ACELP_LOOK_NS + DELAY_BWE_TOTAL_NS), st_fx->old_synth_sw_fx, NS2SA_fx2(st_fx->output_Fs, FRAME_SIZE_NS - ACELP_LOOK_NS - DELAY_BWE_TOTAL_NS), st_fx->hHQ_core->Q_old_postdec); + } + test(); + test(); + test(); +#ifdef IVAS_CODE + /* Store long-term estimates of stab_fac and log energy diff to estimate env_stab in case of core switch ACELP/TCX->HQ */ + if (st->element_mode != EVS_MONO) + { + output_frame = NS2SA(st->output_Fs, FRAME_SIZE_NS); + log_energy = log2f((sum2_f(synth, output_frame) / output_frame) + 1.0f); + log_energy_diff = fabsf(st->log_energy_old - log_energy); + st->log_energy_old = log_energy; + st->log_energy_diff_lt = ENV_SMOOTH_FAC * log_energy_diff + (1.0f - ENV_SMOOTH_FAC) * st->log_energy_diff_lt; + if (st->core == HQ_CORE) + { + st->stab_fac = min(1, (STAB_FAC_EST1 + (STAB_FAC_EST2 * st->hHQ_core->mem_env_delta) + (STAB_FAC_EST3 * st->log_energy_diff_lt))); + st->stab_fac = max(0, st->stab_fac); + } + st->stab_fac_smooth_lt = ENV_SMOOTH_FAC * st->stab_fac + (1.0f - ENV_SMOOTH_FAC) * st->stab_fac_smooth_lt; + } +#endif + IF( ((LE_32(st_fx->core_brate,SID_2k40))&&EQ_16(st_fx->cng_type,FD_CNG)) + || (st_fx->tcxonly && EQ_16(st_fx->codec_mode,MODE2)) + ) + + { + /* reset LP memories */ + set16_fx( st_fx->mem_MA_fx,0, M ); + IF( EQ_32(st_fx->sr_core,INT_FS_16k)) + { + Copy( GEWB2_Ave_fx, st_fx->mem_AR_fx, M ); + } + ELSE + { + Copy( GEWB_Ave_fx, st_fx->mem_AR_fx, M ); + } + } + IF(EQ_16(st_fx->codec_mode, MODE2)) + { + test(); + IF(EQ_16(st_fx->use_partial_copy, 1) && EQ_16(st_fx->rf_frame_type, RF_NELP)) + { + st_fx->last_nelp_mode_dec_fx = 1; + } + ELSE + { + st_fx->last_nelp_mode_dec_fx = 0; + } + } + + st_fx->prev_use_partial_copy = st_fx->use_partial_copy; + move16(); + + st_fx->prev_tilt_code_dec_fx = 0; + move16(); + + st_fx->prev_Q_exc = st_fx->Q_exc; + move16(); + + L_tmp = L_mult(st_fx->tilt_code_dec_fx[0], 4096); + FOR(i = 1; i < NB_SUBFR; i++) + { + L_tmp = L_mac(L_tmp, st_fx->tilt_code_dec_fx[i], 4096); + } + st_fx->prev_tilt_code_dec_fx = round_fx(L_tmp); + + IF (EQ_16(st_fx->core, HQ_CORE)) + { + st_fx->prev_coder_type_fx = GENERIC; + } + ELSE IF (NE_16(st_fx->core, AMR_WB_CORE) ) + { + st_fx->prev_coder_type_fx = st_fx->coder_type_fx; + } + + test(); + IF((GT_32(st_fx->core_brate, SID_2k40) || (GT_32(st_fx->core_brate, SID_1k75) && EQ_16(st_fx->core, AMR_WB_CORE))) && EQ_16(st_fx->first_CNG, 1) && st_fx->hTdCngDec != NULL) + { + if (GE_16(st_fx->hTdCngDec->act_cnt_fx, BUF_DEC_RATE)) + { + st_fx->hTdCngDec->act_cnt_fx = 0; + move16(); + } + + st_fx->hTdCngDec->act_cnt_fx = add(st_fx->hTdCngDec->act_cnt_fx, 1); + + test(); + if ((EQ_16(st_fx->hTdCngDec->act_cnt_fx, BUF_DEC_RATE)) && (st_fx->hTdCngDec->ho_hist_size_fx > 0)) + { + st_fx->hTdCngDec->ho_hist_size_fx = sub(st_fx->hTdCngDec->ho_hist_size_fx, 1); + } + + st_fx->hTdCngDec->act_cnt2_fx = add(st_fx->hTdCngDec->act_cnt2_fx, 1); + if (GE_16(st_fx->hTdCngDec->act_cnt2_fx, MIN_ACT_CNG_UPD)) + { + st_fx->hTdCngDec->act_cnt2_fx = MIN_ACT_CNG_UPD; + move16(); + } + } + + test(); + test(); + if (LE_32(st_fx->core_brate, SID_2k40) && st_fx->first_CNG == 0 && (EQ_16(st_fx->cng_type, LP_CNG) || EQ_16(st_fx->element_mode, IVAS_CPE_MDCT))) + { + st_fx->first_CNG = 1; + move16(); + } + + /* update bandwidth switching parameters */ + test(); test(); + st_fx->last_flag_cna = st_fx->flag_cna; + move16(); + if (st_fx->hFdCngDec_fx != NULL) + { + st_fx->hFdCngDec_fx->hFdCngCom->frame_type_previous = st_fx->m_frame_type; + move16(); + } + + if (GT_16(st_fx->element_mode, EVS_MONO)) + { + st_fx->m_old_frame_type = st_fx->m_frame_type; + } + + /* update bandwidth switching parameters */ + IF ( EQ_16(st_fx->core, AMR_WB_CORE)) + { + st_fx->last_bwidth = WB; + + st_fx->prev_bws_cnt_fx = 0; + st_fx->bws_cnt_fx = 0; + st_fx->bws_cnt1_fx = 0; + move16();move16();move16();move16(); + + } + ELSE IF(EQ_16(st_fx->codec_mode, MODE1) && ((GT_32(st_fx->core_brate, SID_2k40)) || (EQ_16(st_fx->element_mode, EVS_MONO)))) + { + updt_bw_switching_fx(st_fx, synth, Qpostd); + } + ELSE + { + st_fx->last_bwidth = st_fx->bwidth; + st_fx->prev_bws_cnt_fx = st_fx->bws_cnt_fx; + move32(); + move16(); + } + + /* synchronisation of CNG seeds*/ + test(); + test(); + IF(st_fx->hTdCngDec != NULL && (st_fx->bfi || (NE_32(st_fx->core_brate, FRAME_NO_DATA) && NE_32(st_fx->core_brate, SID_2k40))) && NE_16(st_fx->core, AMR_WB_CORE)) + { + Random(&(st_fx->hTdCngDec->cng_seed_fx)); + Random(&(st_fx->hTdCngDec->cng_ener_seed_fx)); + } + + test();test();test(); + IF(st_fx->hTcxDec != NULL && st_fx->enablePlcWaveadjust && !concealWholeFrameTmp && NE_16(st_fx->core, AMR_WB_CORE)) + { + /* update the parameters used in waveform adjustment */ + concealment_update2_x(synth, &st_fx->plcInfo, hTcxDec->L_frameTCX); + } + + st_fx->last_total_brate_ber = st_fx->total_brate; + move32(); + if (st_fx->bfi == 0) + { + st_fx->last_total_brate = st_fx->total_brate; + st_fx->last_bits_frame_nominal = st_fx->bits_frame_nominal; + move32(); + } + st_fx->last_low_rate_mode = st_fx->low_rate_mode; move16(); + if (LT_16(st_fx->ini_frame, MAX_FRAME_COUNTER)) + { + st_fx->ini_frame = add(st_fx->ini_frame,1); + } + + return; +} + + +/*-------------------------------------------------------------------* + * update_decoder_LPD_cng() + * + * + *--------------------------------------------------------------------*/ + +void update_decoder_LPD_cng( + Decoder_State *st, + Word16 coder_type, + Word16 *timeDomainBuffer, + Word16 *A, + Word16 *bpf_noise_buf +) +{ + Word16 i; + Word16 lsp[M], lsf[M]; + Word16 *synth, synth_buf[M+1+L_FRAME_MAX+L_FRAME_MAX/2], tmp; + Word16 buf_synth[OLD_SYNTH_SIZE_DEC+L_FRAME_MAX+M]; + Word16 pf_pitch[NB_SUBFR16k]; + Word16 pf_gain[NB_SUBFR16k]; + Word16 pitch[NB_SUBFR16k]; + TCX_DEC_HANDLE hTcxDec; + + hTcxDec = st->hTcxDec; + synth = synth_buf + (1 + M); + + /* LPC order */ + move16(); + + /* LPC -> LSP */ + E_LPC_a_lsp_conversion( A, lsp, st->lsp_old_fx, M ); + + /* LSP -> LSF */ + IF(EQ_16(st->L_frame, L_FRAME16k)) + { + lsp2lsf_fx( lsp, lsf, M, INT_FS_16k_FX ); + } + ELSE + { + E_LPC_lsp_lsf_conversion( lsp, lsf, M ); + } + + IF(hTcxDec != NULL) + { + Copy(hTcxDec->old_synth, buf_synth, hTcxDec->old_synth_len); + Copy(timeDomainBuffer, buf_synth + hTcxDec->old_synth_len, st->L_frame); + + /* Update synth memory */ + + move16(); + + Copy(st->syn, synth_buf, 1 + M); + Copy(timeDomainBuffer, synth, st->L_frame); + Copy(synth + st->L_frame - (1 + M), st->syn, 1 + M); + Copy(hTcxDec->old_synth + st->L_frame, hTcxDec->old_synth, hTcxDec->old_synth_len - st->L_frame); + Copy(synth, hTcxDec->old_synth + hTcxDec->old_synth_len - st->L_frame, st->L_frame); + bufferCopyFx(synth + st->L_frame - (st->L_frame / 2), hTcxDec->old_syn_Overl, st->L_frame / 2, 0 /*Qf_syn*/, -1 /*Qf_old_xnq*/, 0, 0 /*Q_old_xnq*/); + + hTcxDec->tcxltp_last_gain_unmodified = 0; + hTcxDec->envWeighted = 0; + } + + /* Update pe-synth memory */ + move16(); + tmp = synth[-(1+M)]; + + st->Q_syn = E_UTIL_f_preemph3( synth-M, st->preemph_fac, M+st->L_frame, &tmp, 1 ); + st->prev_Q_syn = st->Q_syn = st->Q_syn - 1; + Copy( synth+st->L_frame-M, st->mem_syn2_fx, M ); + Copy( synth+st->L_frame-L_SYN_MEM, st->mem_syn_r, L_SYN_MEM ); + + /* Update excitation memory */ + assert(st->L_frame < L_EXC_MEM_DEC); + IF(NE_16(add(st->Q_syn,1),st->Q_exc)) + { + Scale_sig(st->old_exc_fx, L_EXC_MEM_DEC, sub(add(st->Q_syn,1),st->Q_exc)); + } + st->Q_exc = st->Q_syn + 1; + Copy( st->old_exc_fx+st->L_frame, st->old_exc_fx, sub(L_EXC_MEM_DEC,st->L_frame) ); + Residu3_fx( A, synth, st->old_exc_fx+L_EXC_MEM_DEC-st->L_frame, st->L_frame, 1 ); + + /* Update LPC-related memories */ + + Copy( lsp, st->lsp_old_fx, M ); + Copy( lsf, st->lsf_old_fx, M ); + Copy( lsp, st->lspold_uw, M ); + Copy( lsf, st->lsfold_uw, M ); + move16(); + move16(); + Copy( A, st->old_Aq_12_8_fx, M+1 ); + st->old_Es_pred_fx=0; + + /* Reset acelp memories */ + + move16(); + st->dm_fx.prev_gain_code = L_deposit_l(0); + set16_fx(st->dm_fx.prev_gain_pit, 0, 6); + st->dm_fx.prev_state = 0; + + move16(); + move16(); + st->tilt_code_fx = TILT_CODE; + st->gc_threshold_fx = 0; + + /* Update ace/tcx mode */ + st->core = ACELP_CORE; + move16(); + move16(); + move16(); + st->last_is_cng = 1; + move16(); + + /* Reset TCX overlap */ + move16(); + move16(); + if (st->hTcxCfg != NULL) + { + st->hTcxCfg->tcx_curr_overlap_mode = st->hTcxCfg->tcx_last_overlap_mode = ALDO_WINDOW; + } + /* For BBWE and Postfilter */ + + Copy( A, &(st->mem_Aq[0]), M+1 ); + Copy( A, &(st->mem_Aq[(M+1)]), M+1 ); + Copy( A, &(st->mem_Aq[2*(M+1)]), M+1 ); + Copy( A, &(st->mem_Aq[3*(M+1)]), M+1 ); + IF( EQ_16(st->L_frame, L_FRAME16k)) + { + Copy( A, &(st->mem_Aq[4*(M+1)]), M+1 ); + } + + /* Update for concealment */ + move16(); + move16(); + st->nbLostCmpt = 0; + st->prev_old_bfi_fx = 0; + + FOR (i=0; ilsf_adaptive_mean_fx[i] = add( mult_r(st->lsfoldbfi1_fx[i], 10923/*1.0f/3.0f Q15*/), add( mult_r(st->lsfoldbfi0_fx[i], 10923/*1.0f/3.0f Q15*/), mult_r(lsf[i], 10923/*1.0f/3.0f Q15*/) ) ); + st->lsfoldbfi1_fx[i] = st->lsfoldbfi0_fx[i]; + st->lsfoldbfi0_fx[i] = lsf[i]; + } + + set16_fx(pitch, shl(L_SUBFR, 6), NB_SUBFR16k); + + FEC_clas_estim_fx( + st, + /*Opt_AMR_WB*/0, /*A*/ + st->L_frame, + &(st->clas_dec), + coder_type, + pitch, + synth, + &st->lp_ener_FER_fx, + /**decision_hyst*/NULL, /* i/o: hysteresis of the music/speech decision */ + /**UV_cnt*/ NULL, /* i/o: number of consecutives frames classified as UV */ + /**LT_UV_cnt*/ NULL, /* i/o: long term consecutives frames classified as UV */ + /**Last_ener*/ NULL, /* i/o: last_energy frame */ + /**locattack*/ NULL, /* i/o: detection of attack (mainly to localized speech burst) */ + /**lt_diff_etot*/NULL, /* i/o: long-term total energy variation */ + /**amr_io_class*/ NULL, /* i/o: classification for AMR-WB IO mode */ + /*bitrate*/ 0 , /* i : Decoded bitrate */ + st->Q_syn, /* i : Synthesis scaling */ + /**class_para*/ NULL, /* o : classification para. fmerit1 */ + st->mem_syn_clas_estim_fx, /* i/o: memory of the synthesis signal for frame class estimation */ + &st->classifier_Q_mem_syn, /*i/o : exponent for memory of synthesis signal for frame class estimation */ + -32768/*-1.f Q15*/, /* i : LTP Gain */ + 0/*CLASSIFIER_ACELP*/, /* i : signal classifier mode */ + 0/*bfi*/, /* i : bad frame indicator */ + st->last_core_brate, /* i : bitrate of previous frame */ + -1 + ); + + /* Postfiltering */ + set16_fx(pf_pitch, L_SUBFR, NB_SUBFR16k); + set16_fx(pf_gain, 0, NB_SUBFR16k); + st->bpf_gain_param=0; + move16(); + + post_decoder( st, buf_synth, pf_gain, pf_pitch, timeDomainBuffer, bpf_noise_buf ); + + return; +} + diff --git a/lib_dec/vlpc_1st_dec.c b/lib_dec/vlpc_1st_dec.c index cc7b33bc9a5754ffb867eb9ba2a35d4e51e0262e..867cd18b800106aa0d6d163dd4e718bc53335593 100644 --- a/lib_dec/vlpc_1st_dec.c +++ b/lib_dec/vlpc_1st_dec.c @@ -42,12 +42,12 @@ #include "wmc_auto.h" /*------------------------------------------------------------------* - * vlpc_1st_dec() + * vlpc_1st_dec_flt() * * *------------------------------------------------------------------*/ -void vlpc_1st_dec( +void vlpc_1st_dec_flt( const int16_t index, /* i : codebook index */ float *lsfq, /* i/o: i:prediction o:quantized lsf */ const int32_t sr_core ) @@ -58,7 +58,7 @@ void vlpc_1st_dec( assert( index < 256 ); - p_dico = &dico_lsf_abs_8b[index * M]; + p_dico = &dico_lsf_abs_8b_flt[index * M]; for ( i = 0; i < M; i++ ) { lsfq[i] += scale * *p_dico++; diff --git a/lib_dec/vlpc_1st_dec_fx.c b/lib_dec/vlpc_1st_dec_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..49751d984244f512ae6c57d587daf93d201af89d --- /dev/null +++ b/lib_dec/vlpc_1st_dec_fx.c @@ -0,0 +1,32 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include +#include +#include "options.h" +#include "prot_fx1.h" +#include "prot_fx2.h" +#include "rom_com.h" + + +void vlpc_1st_dec( + Word16 index, /* input: codebook index */ + Word16 *lsfq) /* i/o: i:prediction o:quantized lsf */ +{ + Word16 i; + const Word16 *p_dico; + + + + assert(index < 256); + p_dico = &dico_lsf_abs_8b[index * M]; + FOR (i = 0; i < M; i++) + { + lsfq[i] = add(lsfq[i], *p_dico); + move16(); + p_dico++; + } + + +} diff --git a/lib_dec/vlpc_2st_dec.c b/lib_dec/vlpc_2st_dec.c index 58dc89554ed896023df72e59826172f94d6301f9..bd45b65bf2d63da4f1d2f8b10ad57798b5f6fa8b 100644 --- a/lib_dec/vlpc_2st_dec.c +++ b/lib_dec/vlpc_2st_dec.c @@ -40,12 +40,12 @@ #include "wmc_auto.h" /*------------------------------------------------------------------* - * vlpc_2st_dec() + * vlpc_2st_dec_flt() * * *------------------------------------------------------------------*/ -void vlpc_2st_dec( +void vlpc_2st_dec_flt( float *lsfq, /* i/o: i:1st stage o:1st+2nd stage */ int16_t *indx, /* i : index[] (4 bits per words) */ const int16_t mode, /* i : 0=abs, >0=rel */ @@ -58,10 +58,10 @@ void vlpc_2st_dec( float scale = ( (float) sr_core ) / INT_FS_12k8; /* weighting from the 1st stage */ - lsf_weight_2st( lsfq, w, mode, sr_core ); + lsf_weight_2st_flt( lsfq, w, mode, sr_core ); /* quantize */ - AVQ_dec_lpc( indx, xq, 2 ); + AVQ_dec_lpc_ivas( indx, xq, 2 ); /* quantized lsf */ for ( i = 0; i < M; i++ ) diff --git a/lib_dec/vlpc_2st_dec_fx.c b/lib_dec/vlpc_2st_dec_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..ae35bc31a8f36758831b033683fb8d01dd8f0a2f --- /dev/null +++ b/lib_dec/vlpc_2st_dec_fx.c @@ -0,0 +1,61 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include +#include +#include "options.h" +#include "prot_fx1.h" +#include "prot_fx2.h" + +void vlpc_2st_dec( + Word16 *lsfq, /* i/o: i:1st stage o:1st+2nd stage */ + Word16 *indx, /* i : index[] (4 bits per words) */ + Word16 mode, /* i : 0=abs, >0=rel */ + Word32 sr_core /* i : internal sampling rate */ +) +{ + Word16 i; + Word16 w[M]; + Word16 xq[M]; + Word16 gap; + + + + /* weighting from the 1st stage */ + lsf_weight_2st(lsfq, w, mode); + + /* quantize */ + AVQ_dec_lpc(indx, xq, 2); + + /* quantized lsf */ + + FOR (i=0; i +#include "options.h" +#include "prot_fx1.h" +#include "prot_fx2.h" +#include "rom_com.h" +#include "log2.h" + +/*===================================================================*/ +/* FUNCTION : void ppp_voiced_decoder_fx () */ +/*-------------------------------------------------------------------*/ +/* PURPOSE : */ +/*-------------------------------------------------------------------*/ +/* INPUT ARGUMENTS : */ +/* _ Word16 bfi_fx - Q0 bad frame indicator */ +/* _ const Word16 *lpc2_fx - Q12 current frame LPC */ +/* _ Word16 *exc_fx - Q0 previous frame excitation */ +/*-------------------------------------------------------------------*/ +/* OUTPUT ARGUMENTS : */ +/* _ Decoder_State *st_fx: */ +/* _ lastLgainD_fx - Q11 */ +/* _ lastHgainD_fx - Q11 */ +/* _ lasterbD_fx - Q13 */ +/* _ Word16 *pitch - Q6 floating pitch values for each subframe */ +/* _ Word16 *out_fx - Q0 residual signal */ +/*-------------------------------------------------------------------*/ +/* INPUT/OUTPUT ARGUMENTS : */ +/* _ Decoder_State *st_fx: */ +/* _ lsp_old_fx - Q15 */ +/* _ st_fx->dtfs_dec_xxxx */ +/* _ a nd b in st_fx->dtfs_dec_Q */ +/* rest all in Q0 */ +/* _ gainp_ppp Q14 */ +/* _ Word16 *pitch_buf_fx - Q6 fixed pitch values for each subframe */ +/*-------------------------------------------------------------------*/ +/* RETURN ARGUMENTS : */ +/* _ None */ +/*-------------------------------------------------------------------*/ +/* CALLED FROM : RX */ +/*===================================================================*/ +ivas_error ppp_voiced_decoder_fx( + Decoder_State *st_fx, /* i/o: state structure */ + Word16 *out_fx, /* o : residual signal */ + const Word16 *lpc2_fx, /* i : current frame LPC */ + Word16 *exc_fx, /* i : previous frame excitation */ + Word16 *pitch, /* o : floating pitch values for each subframe */ + Word16 bfi /* i : Frame error rate */ +) +{ + Word16 k, delta_lag_D = 0,temp,Ql,Qh,diff; + Word16 upper_cut_off_freq_of_interest = 0, upper_cut_off_freq = 0; + Word16 pl, l,n,rem_fx; + Word16 temp_l_fx, temp_pl_fx,interp_delay_fx[3]; + Word32 logLag,Ltemp_q,Ltemp,rem32,temp32_fx,tempnH_fx; + Word16 exp,tmp; + Word32 L_tmp; + DTFS_STRUCTURE* TMPDTFS_FX; + DTFS_STRUCTURE* CURRP_Q_D_FX; + DTFS_STRUCTURE* dtfs_temp_fx; + Word16 pf_temp1[MAXLAG_WI]; /*maynot need more than MAXLAG_WI/2+1 */ + Word16 pf_temp2[MAXLAG_WI]; + Word16 pf_temp[MAXLAG_WI]; + Word16 pf_n2[MAXLAG_WI]; + Word16 S_fx[4*PIT_MAX+1], C_fx[4*PIT_MAX+1]; + Word16 temp_Fs; + SC_VBR_DEC_HANDLE hSC_VBR; + + hSC_VBR = st_fx->hSC_VBR; + + ivas_error error; + + error = IVAS_ERR_OK; + + IF ((error = DTFS_new_fx(&TMPDTFS_FX)) != IVAS_ERR_OK) + { + IVAS_ERROR(error, "Error creating DTFS structure"); + } + IF ((error = DTFS_new_fx(&CURRP_Q_D_FX)) != IVAS_ERR_OK) + { + IVAS_ERROR(error, "Error creating DTFS structure"); + } + IF ((error = DTFS_new_fx(&dtfs_temp_fx)) != IVAS_ERR_OK) + { + IVAS_ERROR(error, "Error creating DTFS structure"); + } + + test(); + IF (EQ_16(st_fx->bwidth,WB)||EQ_16(st_fx->bwidth,SWB)) + { + upper_cut_off_freq_of_interest = 0x2800; + move16();/*4000 normalized to 12800 in Q15 */ + upper_cut_off_freq = 0x4000; + move16();/*6400 normalized to 12800 in Q15 */ + } + ELSE IF (EQ_16(st_fx->bwidth,NB)) + { + upper_cut_off_freq_of_interest = 0x2100; + move16();/*3300 normalized to 12800 in Q15 */ + upper_cut_off_freq = 0x2800; + move16(); + } + + temp_Fs = 8000; + + if ( EQ_16( st_fx->bwidth, WB)) + { + temp_Fs = 16000; + move16(); + } + + + + /* Initialization */ + IF (hSC_VBR->firstTime_voiceddec_fx) + { + hSC_VBR->firstTime_voiceddec_fx=0; + move16(); + + /* (st_fx->PREV_CW_D) = DTFS_new();*/ + hSC_VBR->dtfs_dec_lag_fx = 0; + move16(); + hSC_VBR->dtfs_dec_nH_fx = 0; + move16(); + hSC_VBR->dtfs_dec_nH_4kHz_fx = 0; + move16(); + hSC_VBR->dtfs_dec_upper_cut_off_freq_of_interest_fx = 3300; + move16(); + hSC_VBR->dtfs_dec_upper_cut_off_freq_fx = 4000; + move16(); + + FOR(k = 0; k < MAXLAG_WI; k++) + { + hSC_VBR->dtfs_dec_a_fx[k] = 0; + move16(); + hSC_VBR->dtfs_dec_b_fx[k] = 0; + move16(); + } + hSC_VBR->dtfs_dec_Q = 0; + move16(); + } + + pl = s_min(rint_new_fx(st_fx->old_pitch_buf_fx[(2*NB_SUBFR)-1]),MAX_LAG_PIT); + delta_lag_D = (Word16) get_next_indice( st_fx, 5 ); + + + l = s_min(MAX_LAG_PIT,add(pl,sub(delta_lag_D,11))); + + + temp_pl_fx = pl; + move16(); + temp_l_fx = l; + move16(); + + IF (NE_16(temp_pl_fx,temp_l_fx)) + { + FOR(k=0; klast_coder_type_fx,UNVOICED)) + { + pl = l; + move16(); /* if prev frame was sil/uv*/ + } + + temp = mult(shl(l,3),30310);/*Q3+14+1-16 = Q2 30310 is 1.85 in Q14 */ + + IF( temp >= 0 ) + { + temp = add(temp,2); + } + ELSE + { + temp = sub(temp,2); + } + temp = shr(temp,2);/*Q0 */ + + if (GT_16(pl,temp)) + { + pl = shr(pl,1); + } + + temp = mult(shl(l,3),8857);/*Q3+14+1-16 = Q2 8847 is 0.54 in Q14 */ + IF( temp >= 0 ) + { + temp = add(temp,2); + } + ELSE + { + temp = sub(temp,2); + } + temp = shr(temp,2);/*Q0 */ + + test(); + if (LE_16(shl(pl,1),PIT_MAX)&&LE_16(pl,temp)) + { + pl = shl(pl,1); + } + + /* Restoring PPP memories when the last frame is non-PPP or full-rate PPP */ + IF (NE_16(st_fx->last_ppp_mode_dec_fx,1)) + { + + GetSinCosTab_fx(pl, S_fx, C_fx); + DTFS_to_fs_fx(exc_fx-pl, pl, dtfs_temp_fx, temp_Fs, 0, S_fx, C_fx); + + hSC_VBR->ph_offset_D_fx = 0 ; + move16(); + + /* Copy over PREV_CW_D into TMPDTFS */ + DTFS_copy_fx(TMPDTFS_FX, *dtfs_temp_fx); + + DTFS_car2pol_fx(TMPDTFS_FX); + + /*st_fx->lastLgainD = (float) log10(TMPDTFS->lag*DTFS_setEngyHarm(92.0,1104.5,0.0,1104.5,1.0,TMPDTFS)); */ + + L_tmp = L_deposit_h(TMPDTFS_FX->lag_fx);/*Q16 */ + exp = norm_l(L_tmp); + tmp = Log2_norm_lc(L_shl(L_tmp,exp)); + exp = (30-exp-16); + L_tmp = Mpy_32_16(exp,tmp,12330);/* Q13 */ /* 10*log10(2) in Q12*/ + logLag = L_shl(L_tmp, 10);/*Q23 */ + + Ltemp_q=L_shl(L_mult(shl(TMPDTFS_FX->Q,1),24660),9); /* Ltemp_q=2Q*10log10(2), Q23 */ + /* Process low band */ + Ltemp=DTFS_setEngyHarm_fx(236,2828,0,2828,1,0,&Ql,TMPDTFS_FX);/* Ltemp in 2*TMP.Q */ + /* Compensate for Q factor of energy to get log10(lag*eng) */ + + + Ltemp=log10_fx(Ltemp); /* Ltemp=10log10(eng), Q23 */ +#ifdef BASOP_NOGLOB + Ltemp=L_add_sat(L_sub_sat(Ltemp,Ltemp_q),logLag); /* Ltemp=10*log10(lag*eng), Q23 */ + hSC_VBR->lastLgainD_fx = round_fx_sat(L_shl_sat((Word32)Mpy_32_16(extract_h(Ltemp), extract_l(Ltemp), 0x6666), 1)); /* Q11 */ +#else + Ltemp=L_add(L_sub(Ltemp,Ltemp_q),logLag); /* Ltemp=10*log10(lag*eng), Q23 */ + hSC_VBR->lastLgainD_fx = round_fx(L_shl((Word32)Mpy_32_16(extract_h(Ltemp), extract_l(Ltemp), 0x6666), 1)); /* Q11 */ +#endif + + + + /* Process high band */ + Ltemp=DTFS_setEngyHarm_fx(2828,upper_cut_off_freq_of_interest,2828,upper_cut_off_freq,1,0,&Qh,TMPDTFS_FX); + + + Ltemp=log10_fx(Ltemp); +#ifdef BASOP_NOGLOB + Ltemp=L_add_sat(L_sub_sat(Ltemp,Ltemp_q),logLag); /* Ltemp=10*log10(lag*eng), Q23 */ + hSC_VBR->lastHgainD_fx=round_fx_sat(L_shl_sat((Word32)Mpy_32_16(extract_h(Ltemp),extract_l(Ltemp),0x6666),1)); /* Q11 */ +#else + Ltemp=L_add(L_sub(Ltemp,Ltemp_q),logLag); /* Ltemp=10*log10(lag*eng), Q23 */ + hSC_VBR->lastHgainD_fx=round_fx(L_shl((Word32)Mpy_32_16(extract_h(Ltemp),extract_l(Ltemp),0x6666),1)); /* Q11 */ +#endif + + + /* Need to unify the Q factors of both bands */ + TMPDTFS_FX->Q=s_min(Ql,Qh); /* set Q factor to be the smaller one */ + n=sub(Ql,Qh); /* compare band Q factors */ + + /*This logic adjusts difference between Q formats of both bands */ + IF (n<0) + { + rshiftHarmBand_fx(TMPDTFS_FX,2828, upper_cut_off_freq,n); + } + ELSE IF (n>0) + { + rshiftHarmBand_fx(TMPDTFS_FX,0, 2828, sub(Qh,Ql)); + } + + DTFS_to_erb_fx(*TMPDTFS_FX, hSC_VBR->lasterbD_fx); + + } + ELSE + { + /* Copy DTFS related parameters from 'st' to 'dtfs_temp' structure */ + dtfs_temp_fx->lag_fx = hSC_VBR->dtfs_dec_lag_fx; + move16(); + dtfs_temp_fx->nH_fx = hSC_VBR->dtfs_dec_nH_fx; + move16(); + dtfs_temp_fx->nH_4kHz_fx = hSC_VBR->dtfs_dec_nH_4kHz_fx; + move16(); + dtfs_temp_fx->upper_cut_off_freq_of_interest_fx = hSC_VBR->dtfs_dec_upper_cut_off_freq_of_interest_fx; + move16(); + dtfs_temp_fx->upper_cut_off_freq_fx = hSC_VBR->dtfs_dec_upper_cut_off_freq_fx; + move16(); + + Copy(hSC_VBR->dtfs_dec_a_fx, dtfs_temp_fx->a_fx, MAXLAG_WI); + Copy(hSC_VBR->dtfs_dec_b_fx, dtfs_temp_fx->b_fx, MAXLAG_WI); + dtfs_temp_fx->Q = hSC_VBR->dtfs_dec_Q; + move16(); + } + + CURRP_Q_D_FX->lag_fx = l; + move16(); + + /* safety check in case of bit errors */ + IF( CURRP_Q_D_FX->lag_fx <= 0 ) + { + CURRP_Q_D_FX->lag_fx = 1; + move16(); + st_fx->BER_detect = 1; + move16(); + } + + /* compute nH for lag */ + Ltemp = L_shl((Word32)upper_cut_off_freq,13);/*Q28 */ + upper_cut_off_freq = (Word16)find_remd(Ltemp, 20971,&rem32);/*denormalize upper_cut_off_freq */ + + + + /* temp32_fx = (Word32)divide_dp((Word40)819200,(Word40)L_shl((Word32)CURRP_Q_D_FX->lag_fx,6),-23,1);//Q6 */ + exp = norm_s(CURRP_Q_D_FX->lag_fx); + tmp = div_s(shl(1,sub(14,exp)),CURRP_Q_D_FX->lag_fx);/*29-exp */ + L_tmp =L_shl(L_mult0(tmp,12800),exp - 7); + temp32_fx = round_fx(L_tmp); + diff = round_fx(L_shl(temp32_fx,16-6));/*Q0 */ + + CURRP_Q_D_FX->nH_fx = find_rem(upper_cut_off_freq,diff,&rem_fx);/*Q0 */ + + exp = norm_s(diff); + tmp = div_s(shl(1,sub(14,exp)),diff);/*29-exp */ + L_tmp = L_shl(L_mult0(4000,tmp),exp - 7); + tempnH_fx = extract_h(L_tmp); + CURRP_Q_D_FX->nH_4kHz_fx = round_fx(L_shl(tempnH_fx,16-6));/*Q0 */ + + + IF(GE_16(sub(upper_cut_off_freq,shr((Word16)L_mult(diff,CURRP_Q_D_FX->nH_fx),1)),diff)) + { + CURRP_Q_D_FX->nH_fx = add(CURRP_Q_D_FX->nH_fx,1); + } + tempnH_fx = L_mult0(extract_l(temp32_fx),CURRP_Q_D_FX->nH_4kHz_fx);/* */ + tempnH_fx = L_sub((Word32)256000,tempnH_fx);/*Q6 */ + + if(GE_32(tempnH_fx,temp32_fx)) + { + CURRP_Q_D_FX->nH_4kHz_fx = add(CURRP_Q_D_FX->nH_4kHz_fx,1); + } + + CURRP_Q_D_FX->upper_cut_off_freq_fx = dtfs_temp_fx->upper_cut_off_freq_fx; + move16(); + CURRP_Q_D_FX->upper_cut_off_freq_of_interest_fx = dtfs_temp_fx->upper_cut_off_freq_of_interest_fx; + move16(); + GetSinCosTab_fx(CURRP_Q_D_FX->lag_fx,S_fx,C_fx); + + IF ( bfi == 0 ) + { + IF((error = ppp_quarter_decoder_fx(CURRP_Q_D_FX, dtfs_temp_fx->lag_fx, &(hSC_VBR->lastLgainD_fx), + &(hSC_VBR->lastHgainD_fx), hSC_VBR->lasterbD_fx, bfi, S_fx, C_fx, *dtfs_temp_fx, st_fx)) != IVAS_ERR_OK) + { + return error; + } + } + + IF ((error = WIsyn_fx(*dtfs_temp_fx, CURRP_Q_D_FX, lpc2_fx, &(hSC_VBR->ph_offset_D_fx), out_fx, (Word16)L_FRAME, 0, + S_fx, C_fx, pf_temp1, pf_temp2, pf_temp, pf_n2)) != IVAS_ERR_OK) + { + return error; + } + + DTFS_copy_fx(dtfs_temp_fx, *CURRP_Q_D_FX); + + /* Copy DTFS related parameters from 'dtfs_temp' to 'st' structure */ + hSC_VBR->dtfs_dec_lag_fx = dtfs_temp_fx->lag_fx; + move16(); + hSC_VBR->dtfs_dec_nH_fx = dtfs_temp_fx->nH_fx; + move16(); + hSC_VBR->dtfs_dec_nH_4kHz_fx = dtfs_temp_fx->nH_4kHz_fx; + move16(); + hSC_VBR->dtfs_dec_upper_cut_off_freq_of_interest_fx = dtfs_temp_fx->upper_cut_off_freq_of_interest_fx; + move16(); + hSC_VBR->dtfs_dec_upper_cut_off_freq_fx = dtfs_temp_fx->upper_cut_off_freq_fx; + move16(); + + Copy(dtfs_temp_fx->a_fx, hSC_VBR->dtfs_dec_a_fx, MAXLAG_WI); + Copy(dtfs_temp_fx->b_fx, hSC_VBR->dtfs_dec_b_fx, MAXLAG_WI); + + hSC_VBR->dtfs_dec_Q = dtfs_temp_fx->Q; + move16(); + + count_free(TMPDTFS_FX); + count_free(CURRP_Q_D_FX); + count_free(dtfs_temp_fx); + + return IVAS_ERR_OK; +} +/*---------------------------------------------------------------------* +* sc_vbr_dec_init() +* +* Initialize SC-VBR decoder +*---------------------------------------------------------------------*/ +void sc_vbr_dec_init( + SC_VBR_DEC_HANDLE hSC_VBR /* i/o: SC-VBR decoder handle */ +) +{ + hSC_VBR->nelp_dec_seed_fx = 0; + hSC_VBR->firstTime_voiceddec_fx = 1; + + /* DTFS variables */ + set16_fx(hSC_VBR->dtfs_dec_a_fx, 0, MAXLAG_WI); + set16_fx(hSC_VBR->dtfs_dec_b_fx, 0, MAXLAG_WI); + hSC_VBR->dtfs_dec_lag_fx = 0; + hSC_VBR->dtfs_dec_nH_fx = 0; + hSC_VBR->dtfs_dec_nH_4kHz_fx = 0; + hSC_VBR->dtfs_dec_upper_cut_off_freq_of_interest_fx = 0; + hSC_VBR->dtfs_dec_upper_cut_off_freq_fx = 0; + hSC_VBR->ph_offset_D_fx = 0; + hSC_VBR->lastLgainD_fx = 0; + hSC_VBR->lastHgainD_fx = 0; + set16_fx(hSC_VBR->lasterbD_fx, 0, NUM_ERB_WB); + + /* NELP decoder variables */ + set32_fx(hSC_VBR->bp1_filt_mem_nb_dec_fx, 0, 14); + set16_fx(hSC_VBR->bp1_filt_mem_wb_dec_fx, 0, 8); + set16_fx(hSC_VBR->shape1_filt_mem_dec_fx, 0, 10); + set16_fx(hSC_VBR->shape2_filt_mem_dec_fx, 0, 10); + set16_fx(hSC_VBR->shape3_filt_mem_dec_fx, 0, 10); + + return; +} diff --git a/lib_dec/waveadjust_fec_dec.c b/lib_dec/waveadjust_fec_dec.c index ba242e064f9174e99a5eb10b960abb97c61249c9..dabb16b28f8d896f3386861c247a72dcd177ce80 100644 --- a/lib_dec/waveadjust_fec_dec.c +++ b/lib_dec/waveadjust_fec_dec.c @@ -642,12 +642,12 @@ void waveform_adj2( /*-------------------------------------------------------------------* - * set_state() + * set_state_ivas() * * *-------------------------------------------------------------------*/ -void set_state( +void set_state_ivas( int16_t *state, const int16_t num, const int16_t N ) @@ -768,7 +768,7 @@ void concealment_update( if ( core == TCX_20_CORE ) { - set_state( hPlcInfo->Transient, core, MAX_POST_LEN ); + set_state_ivas( hPlcInfo->Transient, core, MAX_POST_LEN ); for ( i = 0; i < hPlcInfo->L_frameTCX; i++ ) { @@ -777,18 +777,18 @@ void concealment_update( if ( !bfi ) { - set_state( hPlcInfo->TCX_Tonality, tonality, DEC_STATE_LEN ); + set_state_ivas( hPlcInfo->TCX_Tonality, tonality, DEC_STATE_LEN ); } } else { if ( subframe == 0 ) { - set_state( hPlcInfo->Transient, core, MAX_POST_LEN ); + set_state_ivas( hPlcInfo->Transient, core, MAX_POST_LEN ); if ( !bfi ) { - set_state( hPlcInfo->TCX_Tonality, tonality, DEC_STATE_LEN ); + set_state_ivas( hPlcInfo->TCX_Tonality, tonality, DEC_STATE_LEN ); } } /* don't store the second subframe during frameloss; in diff --git a/lib_dec/waveadjust_fec_dec_fx.c b/lib_dec/waveadjust_fec_dec_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..ee49407974892554e24e7873b68985f54baaeca9 --- /dev/null +++ b/lib_dec/waveadjust_fec_dec_fx.c @@ -0,0 +1,1627 @@ +/*==================================================================================== + EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 + ====================================================================================*/ + +#include +#include +#include +#include +#include "prot_fx1.h" +#include "prot_fx2.h" +#include "basop_util.h" +#include "stat_com.h" +#include "rom_com.h" +#include "stl.h" /* FOR wmc_tool */ + +void get_maxConv_and_pitch_x(Word16 *s_LP, Word16 s, Word16 e, Word16 N, + Word32 *maxConv, Word16 *maxConv_bits, Word16 *pitch); +Word16 get_voicing_x(Word16 *s_LP, Word16 pitch, Word32 covMax,Word16 maxConv_bits, Word16 Framesize); +Word32 con_Log10(Word32 i_s32Val, Word16 i_s16Q); + + +Word16 vadmin(Word16 a, Word16 b) +{ + return s_min(a, b); +} + +void set_state(Word16 *state, Word16 num, Word16 N) +{ + Word16 i, tmp; + + tmp = sub(N, 1); + FOR (i = 0; i < tmp; i++) + { + state[i] = state[i+1]; + move16(); + } + state[tmp] = num; + move16(); +} + +void concealment_update_x(Word16 bfi, Word16 curr_mode, Word16 tonality, Word32 *invkoef, Word16 *invkoef_scale, void *_plcInfo) +{ + T_PLCInfo *plcInfo = (T_PLCInfo*)_plcInfo; + Word32 *data_reci2 = plcInfo->data_reci2_fx; + Word16 *tcx_tonality = plcInfo->TCX_Tonality; + Word16 FrameSize = plcInfo->FrameSize; + Word16 subframe = plcInfo->subframe_fx; + Word16 i; + move16(); + move16(); + IF (EQ_16(curr_mode ,1)) + { + set_state(plcInfo->Transient, curr_mode, MAX_POST_LEN); + + FOR (i = 0; i < FrameSize; i++) + { + data_reci2[i] = invkoef[i]; + move32(); + + } + plcInfo->data_reci2_scale = *invkoef_scale; + move16(); + IF (!bfi) + { + set_state(tcx_tonality, tonality, DEC_STATE_LEN); + } + } + ELSE + { + + IF (EQ_16(subframe,0)) + { + set_state(plcInfo->Transient, curr_mode, MAX_POST_LEN); + + IF (!bfi) + { + set_state(tcx_tonality, tonality, DEC_STATE_LEN); + } + } + /* don't store the second subframe during frameloss; in + pitch_search_fx(), low_freq_rate is derived on the last good + TCX-10 spectrum */ + test(); + IF (!bfi || EQ_16(subframe,0)) + { + + Word32 *ptr = data_reci2+subframe; + Word16 FrameSize2 = shr(FrameSize,1); + + FOR (i = 0; i < FrameSize2; i++) + { + ptr[i] = invkoef[i]; + move32(); + } + + plcInfo->data_reci2_scale = *invkoef_scale; + move16(); + } + } + return; +} + +static Word16 zero_pass_w32_x(const Word16 *s, const Word16 N) +{ + Word16 i; + Word32 temp, zp = L_deposit_l(0); + + FOR (i = 1; i < N; i++) + { + temp = L_mac0(-1L, s[i],s[i-1]); + zp = L_sub(zp, L_shr(temp,31)); + } + return extract_l(zp); +} + +Word16 Sqrt_x_fast(Word32 value) +{ + Word16 norm; + Word16 result, index; + + norm = sub(23, norm_l(value)); + index = extract_l( L_shr_r(value, add(norm, s_and(norm, 1)))); + result = shr(sqrt_table_pitch_search[index], sub(11, shr(add(norm,1),1))); + return result; +} + +Word32 dot_w32_accuracy_x(Word16 *s1, Word16 *s2, Word16 nbits, Word16 N) +{ + Word16 i; + Word32 eng = L_deposit_l(0), temp; + + FOR (i = 0; i < N; i++) + { + temp = L_mult0(s1[i], s2[i]); + eng = L_add(eng, L_shr(temp,nbits)); + } + + return eng; +} + + +Word16 int_div_s_x(Word16 a, Word16 b) +{ + Word16 result = 0; + Word16 norm, left=0, i; + move16(); + move16(); + test(); + IF (LT_16(a,b)||b==0) + { + return 0; + } + ELSE + { + a = add(a, shr(b,1)); + norm = sub(norm_s(b),norm_s(a)); + + FOR (i = norm; i>= 0; i--) + { + left = shr(a, i); + result = shl(result,1); + IF (GE_16(left,b)) + { + result = add(result,1); + left= sub(left, b); + a = add(shl(left,i), s_and(a, sub(shl(1,i),1))); + } + } + } + + return result; +} + +Word16 GetW32Norm_x(Word32 *s, Word16 N) +{ + Word32 smax = L_deposit_l(0); + Word16 smax_norm, i; + + FOR (i = 0; i < N; i++) + { + smax = L_or(smax, L_abs(s[i])); + } + + smax_norm = norm_l(smax); + + return smax_norm; +} + +Word16 harmo_x(Word32 *X, Word16 Framesize, Word16 pitch) +{ + Word16 h, k, result = 0; + Word32 ener = L_deposit_l(0), ener_harmo = L_deposit_l(0); + Word16 norm1, d1, d2; + Word16 ener_w, ener_harmo_w; + Word16 nbits = sub(15, norm_s(Framesize)); + move16(); + norm1 = GetW32Norm_x(X, Framesize); + + FOR (k = 1; k < 9; k++) + { + h = sub(int_div_s_x(extract_l(L_mult(k, Framesize)), pitch),1); + + d1 = extract_h(L_shl(X[h], norm1)); + d2 = extract_h(L_shl(X[h+1],norm1)); + + ener_harmo = L_add(ener_harmo, + L_shr(L_mac0(L_mult0(d1, d1), d2, d2),nbits)); + } + + FOR (k = 0; k < Framesize; k++) + { + d1 = extract_h(L_shl(X[k],norm1)); + ener = L_add(ener, L_shr(L_mult0(d1, d1),nbits)); + } + + norm1 = norm_l(ener); + ener_w = extract_h(L_shl(ener,norm1)); + ener_harmo_w = extract_h(L_shl(ener_harmo,norm1)); + + IF (GE_32(ener_harmo ,ener)) + { + return 32767; + } + test(); + IF ((ener_harmo_w <= 0)||(ener_w <= 0)) + { + return 0; + } + result = div_s(ener_harmo_w, ener_w); + return result; +} + +static +Word16 get_low_freq_eng_rate_x(Word32 *mdct_data, + Word16 curr_mode, + Word16 N) +{ + Word16 N1, N2, i; + Word32 low_eng = L_deposit_l(0), eng = L_deposit_l(0), smax = L_deposit_l(0); + Word16 nbits, temp, norm = 0; + move16(); + N1 = 30; + N2 = N; + move16(); + move16(); + IF (EQ_16(2 ,curr_mode)) + { + N1 = shr(30,1); + N2 = shr(N,1); + } + + nbits = sub(15, norm_s(N2)); + + FOR (i = 0; i < N2; i++) + { + smax = L_or(smax, L_abs(mdct_data[i])); + } + + norm = norm_l(smax); + + FOR (i = 0; i < N1; i++) + { + temp = extract_h(L_shl(mdct_data[i], norm)); + low_eng = L_add(low_eng, L_shr(L_mult0(temp, temp),nbits)); + } + + FOR (i = N1; i < N2; i++) + { + temp = extract_h(L_shl(mdct_data[i], norm)); + eng = L_add(eng, L_shr(L_mult0(temp, temp),nbits)); + } + eng = L_add(low_eng, eng); + + /* IF (low_eng<(eng+EPSILON)*0.02) return 1;ELSE return 0; */ + /* smax=eng*0.02 */ + smax = L_shr(Mpy_32_16_1(eng, 5243), 3); + + return (L_sub(low_eng,smax) <= 0); +} + +void LpFilter2_x(Word16 *x, Word16 *y, Word16 N) +{ + Word16 i; + Word16 smax, norm; + Word16 a1 = 5898; /* W16(0.18f); */ + Word16 a2 = 20971; /* W16(0.64f); */ + move16(); + move16(); + smax=0; + move16(); + FOR (i = 0; i < N; i++) + { + smax = s_or(smax, abs_s(x[i])); + } + norm = norm_s(smax); + + y[0] = mult(shl(x[0],norm), a1); + move16(); + y[1] = add(mult(y[0], a2),mult(shl(x[1],norm), a1)); + move16(); + + FOR (i = 2; i < N; i++) + { + /* 5898*2+20971=32767 -->no overflow */ + y[i] = add(mult(y[i-2],a1), add(mult(y[i-1],a2), mult(shl(x[i],norm),a1))); + move16(); + } +} + +void sig_tilt_x(Word16 *s, Word16 FrameSize, Word32 *enr1, Word32 *enr2) +{ + Word16 subFrameSize, shIFt; + Word16 *p1, *p2; + Word16 nbits; + + subFrameSize = shr(FrameSize, 2); + p1 = s+subFrameSize; + p2 = s+sub(subFrameSize, 2); + + shIFt = sub(FrameSize, subFrameSize); + nbits = sub(15, norm_s(shIFt)); + *enr1 = dot_w32_accuracy_x(p1, p2, nbits, shIFt); + move32(); + *enr2 = dot_w32_accuracy_x(p1, p1, nbits, shIFt); + move32(); +} + +void get_maxConv_and_pitch_x(Word16 *s_LP, Word16 s, Word16 e, Word16 N, + Word32 *maxConv, Word16 *maxConv_bits, Word16 *pitch) +{ + Word16 t, cov_size, size = N; + Word32 tmp_sigma = L_deposit_l(0), cov_max_sigma = L_deposit_l(0); + Word16 nbits,tmp_pitch=0; + Word32 r1_high, r2_high; + UWord16 r1_low, r2_low; + Word32 tmp_sigma_last = L_deposit_l(0); /* not needed, just to avoid compiler warning */ + Word16 cov_size_last = N; /* not needed, just to avoid compiler warning */ + Word32 cov_max_sigma_tmp = L_deposit_l(0); + Word16 size_tmp = N; + move16(); + move16(); + nbits = sub(15, norm_s(sub(N, s))); + + FOR (t = s; t < e; t++) + { + cov_size = sub(N,t); + tmp_sigma = dot_w32_accuracy_x(s_LP, s_LP+t, nbits, cov_size); + + IF (GT_16(t,s)) /* don't use the first value */ + { + Mpy_32_16_ss(tmp_sigma , cov_size_last, &r1_high, &r1_low); + Mpy_32_16_ss(tmp_sigma_last, cov_size , &r2_high, &r2_low); + /* tmp_sigma > tmp_sigma_last */ + test(); + test(); + move16(); + move16(); /* moves are for the (Word32) casts */ + IF((GT_32(r1_high, r2_high))|| + (EQ_32(r1_high, r2_high) && GT_32((Word32)r1_low, (Word32)r2_low) )) + { + /* store the current cov, if it is larger than the last one */ + cov_max_sigma_tmp = tmp_sigma; + move32(); + size_tmp = cov_size; + move16(); + } + ELSE + { + Mpy_32_16_ss(cov_max_sigma , size_tmp, &r1_high, &r1_low); + Mpy_32_16_ss(cov_max_sigma_tmp, size , &r2_high, &r2_low); + /* cov_max_sigma < cov_max_sigma_tmp */ + test(); + test(); + move16(); + move16(); /* moves are for the (Word32) casts */ + IF((LT_32(r1_high, r2_high))|| + (EQ_32(r1_high, r2_high) && LT_32((Word32)r1_low, (Word32)r2_low))) + { + /* otherwise */ + /* use the last value of cov, being a max */ + cov_max_sigma = cov_max_sigma_tmp; + move32(); + size = cov_size; + move16(); + /* and use the last index as pitch */ + tmp_pitch = sub(t,1); + } + } + } + tmp_sigma_last = tmp_sigma; + move32(); + cov_size_last = cov_size; + move16(); + } + *pitch = tmp_pitch; + move16(); + *maxConv = cov_max_sigma; + move32(); + *maxConv_bits = nbits; + move16(); +} + +Word16 get_voicing_x(Word16 *s_LP, Word16 pitch, Word32 covMax,Word16 maxConv_bits, Word16 Framesize) +{ + Word32 eng1 = L_deposit_l(0), eng2 = L_deposit_l(0); + Word16 voicing, norm; + Word16 tmpLen, nbits; + Word16 eng1_w, eng2_w; + + IF (covMax <= 0) + { + return 0; + } + ELSE + { + tmpLen = sub(Framesize, pitch); + nbits = maxConv_bits; + move16(); + + eng1 = dot_w32_accuracy_x(s_LP, s_LP, nbits, tmpLen); + eng2 = dot_w32_accuracy_x(s_LP+pitch, s_LP+pitch, nbits, tmpLen); + + norm = sub(norm_l(L_or(eng1, L_or(eng2, covMax))),1); + eng1 = L_shl(eng1, norm); + eng2 = L_shl(eng2, norm); + covMax = L_shl(covMax, norm); + + eng1_w = Sqrt_x_fast(eng1); + eng2_w = Sqrt_x_fast(eng2); + + eng1 = L_mult0(eng1_w, eng2_w); + norm = norm_l(eng1); + eng1_w = extract_h(L_shl(eng1, norm)); + eng2_w = extract_h(L_shl(covMax, norm)); + + IF (GE_32(covMax , eng1)) + { + return 32767; + } + test(); + IF ((eng2_w <= 0)||(eng1_w <= 0)) + { + return 0; + } + voicing = div_s(eng2_w, eng1_w); + + return voicing; + } +} + +void pitch_modify_x(Word16 *s_LP, Word16 *voicing, Word16 *pitch, Word16 FrameSize) +{ + Word32 eng1, eng2, eng3; + Word16 shIFt = shr(*pitch ,1); + Word16 tmpLen, nbits, norm, voicing2; + Word16 eng1_w, eng2_w; + + tmpLen = sub(FrameSize, shIFt); + nbits = sub(15, norm_s(tmpLen)); + + eng1 = dot_w32_accuracy_x(s_LP+shIFt, s_LP+shIFt, nbits, tmpLen); + eng2 = dot_w32_accuracy_x(s_LP, s_LP, nbits, tmpLen); + eng3 = dot_w32_accuracy_x(s_LP+shIFt, s_LP, nbits, tmpLen); + + IF (eng3 <= 0) + { + return ; + } + + norm = sub(norm_l(L_or(eng1, L_or(eng2, eng3))),1); + eng1 = L_shl(eng1, norm); + eng2 = L_shl(eng2, norm); + eng3 = L_shl(eng3, norm); + + eng1_w = Sqrt_x_fast(eng1); + eng2_w = Sqrt_x_fast(eng2); + + eng1 = L_mult0(eng1_w, eng2_w); + + norm = norm_l(eng1); +#ifdef BASOP_NOGLOB + eng1_w = extract_h(L_shl_sat(eng1, norm)); + eng2_w = extract_h(L_shl_sat(eng3, norm)); +#else + eng1_w = extract_h(L_shl(eng1, norm)); + eng2_w = extract_h(L_shl(eng3, norm)); +#endif + + IF (GE_32(eng3,eng1)) + { + voicing2 = 32767; + move16(); + } + ELSE { test(); + IF ((eng2_w <= 0)||(eng1_w <= 0)) + { + voicing2 = 0; + move16(); + } + ELSE { + voicing2 = div_s(eng2_w, eng1_w); + } + } + + IF (GT_16(voicing2, *voicing)) + { + *pitch = shIFt; + move16(); + *voicing = voicing2; + move16(); + } +} + +Word16 Is_Periodic_x(Word32 *mdct_data, Word16 cov_max, Word16 zp, Word32 ener, + Word32 ener_mean, Word16 pitch, Word16 Framesize) +{ + Word16 flag =0; + Word16 harm; + move16(); + test(); + test(); + test(); + IF (LT_32(ener, L_shl(50,8))||(LT_32(ener,L_sub(ener_mean,L_shl(8,8))) + && LT_16(cov_max, 29491) )) + { + flag = 0; + move16(); + } + ELSE IF (GT_16(cov_max, 26214)) + { + flag = 1; + move16(); + } + ELSE IF (GT_16(zp, 100)) + { + flag = 0; + move16(); + } + ELSE IF (LT_32(ener, L_sub(ener_mean,L_shl(6,8)))) + { + flag = 0; + move16(); + } + ELSE IF (GT_32(ener, L_add(ener_mean, L_shl(1,8)))&>_16(cov_max,19661)) + { + flag = 1; + move16(); + } + ELSE + { + harm = harmo_x(mdct_data, Framesize, pitch); + flag = 1; + move16(); + if (LT_16(harm, 22938)) + { + flag = 0; + move16(); + } + } + + return flag; +} + +Word16 get_conv_relation_x(Word16 *s_LP, Word16 shIFt, Word16 N) +{ + Word32 eng1,eng2, eng3; + Word16 eng1_w, eng2_w; + Word16 tmp, norm, nbits; + + nbits = sub(15, norm_s(N)); + eng3 = dot_w32_accuracy_x(s_LP, s_LP+shIFt, nbits, N); + + IF (eng3 <= 0) + { + return 0; + } + + eng1 = dot_w32_accuracy_x(s_LP+shIFt, s_LP+shIFt, nbits, N); + eng2 = dot_w32_accuracy_x(s_LP, s_LP, nbits, N); + + norm = sub(norm_l(L_or(eng1, L_or(eng2, eng3))),1); + eng1 = L_shl(eng1, norm); + eng2 = L_shl(eng2, norm); + eng3 = L_shl(eng3, norm); + + eng1_w = Sqrt_x_fast(eng1); + eng2_w = Sqrt_x_fast(eng2); + + eng1 = L_mult0(eng1_w, eng2_w); + + norm = norm_l(eng1); + eng1_w = extract_h(L_shl(eng1, norm)); + eng2_w = extract_h(L_shl(eng3, norm)); + + IF (GE_32(eng3, eng1)) + { + return 32767; + } + test(); + IF ((eng2_w <= 0)||(eng1_w <= 0)) + { + return 0; + } + + tmp = div_s(eng2_w, eng1_w); + + return tmp; +} + +static +Word16 pitch_search_fx(Word16 *s, /* lastPcmOut */ + Word16 *outx_new, + Word16 Framesize, + Word16 *voicing, + Word16 zp, + Word32 ener, + Word32 ener_mean, + Word32 *mdct_data, + Word16 curr_mode + ) +{ + Word16 pitch = 0; + Word32 cov_max = L_deposit_l(0), tilt_enr1, tilt_enr2; + Word16 s_LP[L_FRAME_MAX]; + Word16 start_pos, end_pos; + Word16 low_freq_rate_result; + Word16 flag = 0, zp_current; + Word32 *mdctPtr; + Word16 curr_frmsize; + Word16 cov_max_bits=0; + Word16 i; + move16(); + move16(); + move16(); + *voicing = 0; + move16(); + curr_frmsize = Framesize; + move16(); + if (EQ_16(2, curr_mode)) + { + curr_frmsize = shr(Framesize, 1); + } + + zp_current = zero_pass_w32_x(outx_new, curr_frmsize); + + if (EQ_16(2, curr_mode)) + { + zp_current = shl(zp_current,1); + } + IF (LE_16(Framesize, 256)) + { + IF (GT_16(zp_current, 70)) + { + return 0; + } + } + ELSE + { + IF (GT_16(zp_current, 105)) + { + return 0; + } + } + + mdctPtr = mdct_data; + if (EQ_16(2, curr_mode)) + { + mdctPtr = mdct_data + shr(Framesize,1); + } + + low_freq_rate_result = get_low_freq_eng_rate_x(mdctPtr, + curr_mode, + Framesize); + + IF(low_freq_rate_result) + { + return 0; + } + + LpFilter2_x(s, s_LP, Framesize); + sig_tilt_x(s_LP, Framesize, &tilt_enr1, &tilt_enr2); + IF (LE_16(Framesize, 320)) + { + test(); + IF ((0==tilt_enr2) || + (LT_32(tilt_enr1, L_shr(tilt_enr2, 1)) )) + { + return 0; + } + } + ELSE + { + test(); + IF ((0==tilt_enr2) || + (LT_32(tilt_enr1, Mpy_32_16_1(tilt_enr2, 22938)) )) + { + return 0; + } + } + + IF (LE_16(Framesize, 320)) + { + start_pos = extract_l(L_shr(L_mac0(0x80, 34, Framesize), 8)); + end_pos = extract_l(L_shr(L_mac0(0x2 , 3, Framesize), 2)); + get_maxConv_and_pitch_x(s_LP, start_pos, end_pos, Framesize, &cov_max, &cov_max_bits, &pitch); + *voicing = get_voicing_x(s_LP, pitch, cov_max, cov_max_bits, Framesize); + move16(); + pitch_modify_x(s_LP, voicing, &pitch, Framesize); + } + ELSE + { + Word16 s_tmp[L_FRAME_MAX]; + Word16 Framesize_tmp; + Word16 pitch_tmp[3]; + Word16 cov_size; + + Framesize_tmp = shr(Framesize, 1); + FOR (i = 0; i < Framesize_tmp; i++) + { + s_tmp[i] = s_LP[2*i]; + move16(); + } + + start_pos = extract_l( L_shr(L_mac0(0x80, 34, Framesize_tmp), 8)); + end_pos = extract_l( L_shr(L_mac0(0x2, 3, Framesize_tmp), 2)); + + cov_max = L_deposit_l(0); + pitch = 0; + move16(); + get_maxConv_and_pitch_x(s_tmp, start_pos, end_pos, Framesize_tmp, &cov_max, &cov_max_bits, &pitch); + + IF (pitch > 0) + { + pitch_tmp[0] = 0; + move16(); + if (GT_16(shl(pitch, 1), 1)) + { + pitch_tmp[0] = sub(shl(pitch, 1), 1); + move16(); + } + pitch_tmp[1] = shl(pitch, 1); + move16(); + pitch_tmp[2] = add(shl(pitch, 1), 1); + move16(); + start_pos = 0; + move16(); + pitch = 0; + move16(); + FOR (i = 0; i < 3; i++) + { + cov_size = sub(Framesize, pitch_tmp[i]); + end_pos = get_conv_relation_x(s_LP, pitch_tmp[i], cov_size); + IF (GT_16(end_pos, start_pos)) + { + start_pos = end_pos; + move16(); + pitch = pitch_tmp[i]; + move16(); + } + } + *voicing = start_pos; + move16(); + } + } + + IF (pitch > 0) + { + flag = Is_Periodic_x(mdct_data, *voicing, zp, ener, ener_mean, pitch, Framesize); + } + if (flag == 0 ) + { + pitch = 0; + move16(); + } + return pitch; +} + +void concealment_init_x(Word16 N, void *_plcInfo) +{ + T_PLCInfo *plcInfo = (T_PLCInfo*)_plcInfo; + Word16 i; + + plcInfo->FrameSize = N; + move16(); + plcInfo->Pitch_fx = 0; + move16(); + plcInfo->T_bfi_fx = 0; + move16(); + plcInfo->outx_new_n1_fx = 0; + move16(); + plcInfo->nsapp_gain_fx = 0; + move16(); + plcInfo->nsapp_gain_n_fx = 0; + move16(); + plcInfo->ener_mean_fx = L_deposit_l(15213); /*Q8 59.4260f*256*/ + plcInfo->ener_fx = L_deposit_l(0); + plcInfo->zp_fx = N; + move16(); + plcInfo->recovery_gain = 0; + move16(); + plcInfo->step_concealgain_fx = 0; + move16(); + plcInfo->concealment_method = TCX_NONTONAL; + move16(); + plcInfo->subframe_fx = 0; + move16(); + plcInfo->nbLostCmpt = L_deposit_l(0); + plcInfo->seed = 21845; + move16(); + + FOR (i = 0; i < TCX_TONALITY_INIT_CNT; i++) + { + plcInfo->TCX_Tonality[i] = 1; + move16(); + } + FOR (i = TCX_TONALITY_INIT_CNT; i < DEC_STATE_LEN; i++) + { + plcInfo->TCX_Tonality[i] = 0; + move16(); + } + + FOR (i = 0; i < MAX_POST_LEN; i++) + { + plcInfo->Transient[i] = 1; + move16(); + } + + FOR (i = 0; i < L_FRAME_MAX; i++) + { + plcInfo->data_reci2_fx[i] = L_deposit_l(0); + } + return; +} + +static Word16 own_random_fix( /* o : output random value */ + Word16 *seed /* i/o: random seed */ +) +{ + *seed = extract_l(L_mac0(13849L, *seed , 31821)); + return(*seed); +} + +void concealment_decode_fix(Word16 curr_mode, Word32 *invkoef, Word16 *invkoef_scale,void *_plcInfo) +{ + T_PLCInfo *plcInfo = (T_PLCInfo*)_plcInfo; + Word16 i; + Word16 N = plcInfo->FrameSize; + Word16 *seed = &(plcInfo->seed); + Word16 sign; + move16(); + IF (plcInfo->concealment_method == TCX_NONTONAL) /* #define TCX_NONTONAL 0 */ + { + IF (EQ_16(curr_mode, 1)) + { + /* copy the data of the last frame */ + mvr2r_Word32(plcInfo->data_reci2_fx, invkoef, N); + *invkoef_scale = plcInfo->data_reci2_scale; + move16(); + /* sign randomization */ + FOR (i = 0; i < N; i++) + { + sign = add(shl(shr(own_random_fix(seed),15),1),1); + if(EQ_16(sign,-1)) + { + invkoef[i] = L_negate(invkoef[i]); + move32(); + } + } + } + } + return; +} + + +Word16 Spl_GetScalingSquare_x(const Word16 *in_vector, const Word16 in_vector_length, Word16 times) +{ + Word16 nbits = sub(15, norm_s(times))/*Spl_GetSizeInBits_x(times)*/; + Word16 i; + Word16 smax = -1; + Word16 sabs; + const Word16 *sptr = in_vector; + Word16 t; + move16(); + FOR (i = in_vector_length; i > 0; i--) + { + + sabs = abs_s(*sptr); + sptr++; + smax = s_max(sabs, smax); + + } + + t = norm_l(L_mult0(smax, smax)); + + IF (smax == 0) + { + return 0; /* Since norm(0) returns 0 */ + } + ELSE + { + nbits = sub(nbits, t); + nbits = s_max(0,nbits); + + return nbits; + } +} + + +Word32 Spl_Energy_x(const Word16* vector, const Word16 vector_length, Word16* scale_factor) +{ + Word32 en = L_deposit_l(0); + Word32 i; + Word16 scaling = Spl_GetScalingSquare_x(vector, vector_length, vector_length); + + FOR (i = 0; i < vector_length; i++) + { + en = L_add(en,L_shr(L_mult0(vector[i], vector[i]), scaling)); + } + + move32(); + *scale_factor = scaling; + + return en; +} + +void Log10OfEnergy_x(const Word16 *s, Word32 *enerlogval, const Word16 len) +{ + Word32 energy = L_deposit_l(0), tmp2 = L_deposit_l(0); + Word16 shfts = 0; + Word32 Log10_energy = L_deposit_l(0), Log10_len = L_deposit_l(0); + move16(); + energy = Spl_Energy_x(s, len, &shfts);/* Q:-shfts */ + IF (energy > 0) + { + Log10_energy = con_Log10(energy, negate(shfts)); /* Q25 */ + Log10_len = con_Log10(L_deposit_l(len), 0); /* Q25 */ + tmp2 = L_sub(Log10_energy,Log10_len); /* Q25 */ + tmp2 = Mpy_32_16_1(tmp2,20480); /* Q11->10 Q=25+11-15=21 */ + *enerlogval = L_shr(tmp2,13); /* Q8 */ move32(); + } + ELSE + { + *enerlogval = -25600; + move32(); + } + +} + +static Word32 fnLog2(Word32 L_Input) +{ + + Word16 swC0 = -0x2b2a, swC1 = 0x7fc5, swC2 = -0x54d0; + Word16 siShIFtCnt, swInSqrd, swIn; + Word32 LwIn; + move16(); + move16(); + move16(); + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + /* normalize input and store shIFts required */ + /* ----------------------------------------- */ + + siShIFtCnt = norm_l(L_Input); + LwIn = L_shl(L_Input, siShIFtCnt); + siShIFtCnt = add(siShIFtCnt, 1); + siShIFtCnt = negate(siShIFtCnt); + + /* calculate x*x*c0 */ + /* ---------------- */ + + swIn = extract_h(LwIn); + swInSqrd = mult_r(swIn, swIn); + LwIn = L_mult(swInSqrd, swC0); + + /* add x*c1 */ + /* --------- */ + + LwIn = L_mac(LwIn, swIn, swC1); + + /* add c2 */ + /* ------ */ + + LwIn = L_add(LwIn, L_deposit_h(swC2)); + + /* apply *(4/32) */ + /* ------------- */ + + LwIn = L_shr(LwIn, 3); + LwIn = L_and(LwIn, 0x03ffffff); + siShIFtCnt = shl(siShIFtCnt, 10); + LwIn = L_add(LwIn, L_deposit_h(siShIFtCnt)); + + /* return log2 */ + /* ----------- */ + + return (LwIn); +} + +static Word32 fnLog10(Word32 L_Input) +{ + + Word16 Scale = 9864; /* 0.30103 = log10(2) */ + Word32 LwIn; + move16(); + /*_________________________________________________________________________ + | | + | Executable Code | + |_________________________________________________________________________| + */ + + /* 0.30103*log2(x) */ + /* ------------------- */ + + LwIn = fnLog2(L_Input); + LwIn = Mpy_32_16_1(LwIn, Scale); + + return (LwIn); +} + +Word32 con_Log10(Word32 i_s32Val, Word16 i_s16Q) +{ + Word32 s32Out; + Word32 s32Correct; /* corrected (31-q)*log10(2) */ + const Word16 s16Log10_2 = 19728; /* log10(2)~Q16 */ move16(); + + IF(0 == i_s32Val) + { + return EVS_LW_MIN; + } + + s32Out = fnLog10(i_s32Val); /* (2^26)*log10(a) */ + + s32Correct = L_mult(sub(31,i_s16Q), s16Log10_2); /* q = 17 */ + s32Correct = L_shl(s32Correct, 8); /* q = 25 */ + s32Out = L_shr(s32Out, 1); /* q = 25 */ + + s32Out = L_add(s32Out, s32Correct); + + return s32Out; +} + +void concealment_update2_x(const Word16 *outx_new, void *_plcInfo, const Word16 FrameSize) +{ + T_PLCInfo *plcInfo = (T_PLCInfo*)_plcInfo; + + plcInfo->zp_fx = zero_pass_w32_x(outx_new, FrameSize); + move16(); + + Log10OfEnergy_x(outx_new, &plcInfo->ener_fx, FrameSize); /* Q8 */ + test(); + IF (LT_16(plcInfo->zp_fx, 100)&>_32(plcInfo->ener_fx,L_shl(50,8))) + { + plcInfo->ener_mean_fx = L_add(Mpy_32_16_1(plcInfo->ener_mean_fx ,32112/* 0.98 Q15 */), + Mpy_32_16_1(plcInfo->ener_fx , 655/* 0.02 Q15 */)); + move32(); + } + return; +} + +static Word16 array_max_indx_fx(Word16 *s, Word16 N) +{ + Word16 i, indx = 0; + move16(); + FOR (i = 0; i < N; i++) + { + if (GT_16(s[i], s[indx])) + { + indx = i; + move16(); + } + } + return indx; +} + +Word16 ffr_getSfWord16( /* o: measured headroom in range [0..15], 0 IF all x[i] == 0 */ + Word16 *x, /* i: array containing 16-bit data */ + Word16 len_x) /* i: length of the array to scan */ +{ + Word16 i, i_min, i_max; + Word16 x_min, x_max; + + + x_max = 0; + move16(); + x_min = 0; + move16(); + FOR (i = 0; i < len_x; i++) + { + if (x[i] >= 0) + x_max = s_max(x_max,x[i]); + if (x[i] < 0) + x_min = s_min(x_min,x[i]); + } + + i_max = 0x10; + move16(); + i_min = 0x10; + move16(); + + if (x_max != 0) + i_max = norm_s(x_max); + + if (x_min != 0) + i_min = norm_s(x_min); + + i = s_and(s_min(i_max, i_min),0xF); + + + return i; +} + +static Word16 OverlapAdd_fx(Word16 *pitch125_data, Word16 *sbuf, + Word16 n, Word16 pitch, Word16 Framesize) +{ + Word16 n1,n2,s,s16MaxCoefNorm,s16MaxCoefNorm2,tmp16; + Word16 i; + Word16 pitch125 =extract_l(L_shr(L_add(L_add(L_deposit_h(pitch), L_mult(pitch, 8192)), 32768) ,16)); + Word16 Loverlap = sub(pitch125,pitch); + Word16 Framesize_sub_n = sub(Framesize, n); + + n1 = Framesize_sub_n; + move16(); + n2 = Framesize_sub_n; + move16(); + if(LT_16(Loverlap, Framesize_sub_n)) + { + n1 = Loverlap; + move16(); + } + if(LT_16(pitch125, Framesize_sub_n)) + { + n2 = pitch125; + move16(); + } + s16MaxCoefNorm = sub(ffr_getSfWord16(sbuf+n, n1),1); + s16MaxCoefNorm2 = ffr_getSfWord16(pitch125_data, n1); + Loverlap = s_max(1, Loverlap); + tmp16 =BASOP_Util_Divide1616_Scale(1, Loverlap,&s); + FOR (i = 0; i < n1; i++) + { + Word16 tmp; + Word16 dat; + dat= shl(sbuf[n+i],s16MaxCoefNorm); + tmp = extract_l(L_shl(L_mult0(i, tmp16), s)); /* q15 */ + sbuf[n+i] = round_fx(L_add(L_shr(L_mult(dat, sub(32767,tmp)),s16MaxCoefNorm), + L_shr(L_mult(shl(pitch125_data[i],s16MaxCoefNorm2),tmp),s16MaxCoefNorm2))); + } + + FOR (i = n1; i < n2; i++) + { + sbuf[n+i] = pitch125_data[i]; + move16(); + } + + pitch = add(n, pitch); + + return pitch; +} + +static void add_noise (Word16 * const sbuf, + Word16 * const outx_new_n1, + Word16 const* const noise_seg, + Word16 const Len, + Word16 * const gain, + Word16 const* const gain_n, + Word8 const firstFrame) +{ + Word16 i; + Word16 temp_OUT; + + IF( !firstFrame ) + { +#ifdef BASOP_NOGLOB + temp_OUT = sub_sat(noise_seg[0], mult((*outx_new_n1),22282/* 0.68 Q15 */)); + sbuf[0] = add_sat(sbuf[0], mult((temp_OUT), *gain)); + move16(); + *gain = mac_r_sat(L_mult_sat(32439/* 0.99 Q15 */,*gain),328/* 0.01 Q15 */,*gain_n); +#else + temp_OUT = sub(noise_seg[0], mult((*outx_new_n1),22282/* 0.68 Q15 */)); + sbuf[0] = add(sbuf[0], mult((temp_OUT), *gain)); + move16(); + *gain = mac_r(L_mult(32439/* 0.99 Q15 */,*gain),328/* 0.01 Q15 */,*gain_n); +#endif + } + + FOR( i = 1; i < Len; i++ ) + { +#ifdef BASOP_NOGLOB + temp_OUT = sub_sat(noise_seg[i], mult((noise_seg[i-1]),22282/* 0.68 Q15 */)); + sbuf[i] = add_sat(sbuf[i], mult((temp_OUT), *gain)); + move16(); + *gain = mac_r_sat(L_mult(32439/* 0.99 Q15 */,*gain),328/* 0.01 Q15 */,*gain_n); +#else + temp_OUT = sub(noise_seg[i], mult((noise_seg[i-1]),22282/* 0.68 Q15 */)); + sbuf[i] = add(sbuf[i], mult((temp_OUT), *gain)); + move16(); + *gain = mac_r(L_mult(32439/* 0.99 Q15 */,*gain),328/* 0.01 Q15 */,*gain_n); +#endif + } + + *outx_new_n1 = noise_seg[i-1]; /*q0*/ + + return; +} + +static +Word16 waveform_adj_fix(Word16 *overlapbuf, + Word16 *outdata2, + Word16 *outx_new, + Word16 *data_noise, + Word16 *outx_new_n1, + Word16 *nsapp_gain, + Word16 *nsapp_gain_n, + Word16 Framesize, + Word8 T_bfi, + Word16 voicing, + Word16 curr_mode, + Word16 pitch) +{ + Word16 i, zp1, zp2,Framesizediv2,s16MaxCoefNorm; + Word16 sbuf[L_FRAME_MAX]; + Word16 tmp; + + Framesizediv2=shr(Framesize,1); + zp1 = zero_pass_w32_x(outdata2, Framesizediv2); + zp2 = zero_pass_w32_x(outdata2+Framesizediv2, Framesizediv2); + + /* judge if the pitch is usable */ + tmp = 1; + move16(); + if (GT_16(zp1, 1)) + { + tmp = zp1; + move16(); + } + IF (LT_16(shl(tmp,2), zp2)) + { + move16(); + return 0; + } + + /* adjust the pitch value */ + test(); + test(); + test(); + IF (T_bfi && (LE_16(pitch , Framesizediv2)) + && (GT_16(Framesize ,256)) && (EQ_16(curr_mode , 1))) + { + Word16 i1 = 0, i2 = 0; + Word16 pos1, pos2, pos3; + move16(); + move16(); + i1 = add(1 , array_max_indx_fx(outx_new, pitch)); + i2 = add(1 , array_max_indx_fx(outx_new+pitch, pitch)); + + pos1 = add(i2,sub(pitch,i1)); + pos3 = add(pos1, mult(pos1, 8192/* 0.25 Q15 */)); + pos2 = add(pitch,mult(pitch, 8192/* 0.25 Q15 */)); + + test(); + test(); + IF ((LT_16(pos1,pos2))&&(GT_16(pos3,pitch))&&(LT_16(pos1,Framesizediv2))) + { + pitch = add(i2,sub(pitch,i1)); + } + } + + { + Word16 pitch125 = 0, Loverlap = 0, n = 0; + Word16 pitch125_data[L_FRAME_MAX]; + move16(); + move16(); + pitch125 = extract_l((L_shr(L_add(L_add(L_deposit_h(pitch), L_mult(pitch, 8192)), 32768) ,16))); + Loverlap = sub(pitch125,pitch); + FOR (i = 0; i < pitch; i++) + { + pitch125_data[i] = outdata2[Framesize-pitch+i]; + move16(); + } + FOR (i = 0; i < Loverlap; i++) + { + pitch125_data[pitch+i] = outx_new[i]; + move16(); + } + FOR (i = 0; i < Framesize; i++) + { + sbuf[i] = outx_new[i]; + move16(); + } + + { + Word16 pitch125a1; + Word16 tmp_buf[2*L_FRAME_MAX], *p_tmp = tmp_buf+1; + + FOR (i = 0; i < pitch125; i++) + { + p_tmp[i] = pitch125_data[i]; + move16(); + } + + p_tmp[-1] = outdata2[Framesize-pitch-1]; + move16(); + p_tmp[pitch125] = outx_new[Loverlap]; + move16(); + pitch125a1 = add(pitch125,1); + s16MaxCoefNorm = sub(ffr_getSfWord16(p_tmp-1, pitch125a1),1); + FOR (i = 0; i < pitch125a1; i++) + { + p_tmp[i-1] = shl(p_tmp[i-1],s16MaxCoefNorm); + move16(); + } + FOR (i = 0; i < pitch125; i++) + { +#ifdef BASOP_NOGLOB + pitch125_data[i] = round_fx_sat(L_shr_sat(L_add_sat((L_mult(p_tmp[i], 20972)),L_mac_sat(L_mult(p_tmp[i-1], 5898),p_tmp[i+1],5898)),s16MaxCoefNorm)); +#else + pitch125_data[i] = round_fx(L_shr(L_add((L_mult(p_tmp[i], 20972)),L_mac(L_mult(p_tmp[i-1], 5898),p_tmp[i+1],5898)),s16MaxCoefNorm)); +#endif + } + } + + WHILE (LT_16(n, Framesize)) /* periodical extension */ + { + n = OverlapAdd_fx(pitch125_data,sbuf,n,pitch,Framesize); + } + + /* maximum pitch lag is 3/4 Framesize; pitch125_data is reused for + temporary storage, since outdata2 (holding the pcm data of the + last good frame) is still needed and overlapbuf overlaps outdata2 */ + Copy(&sbuf[Framesize/4], pitch125_data, (3*Framesize)/4); + + *nsapp_gain = 0; + move16(); + *nsapp_gain_n = sub(32767 ,shr(voicing,1)); /* q15 */ + tmp = Framesize; + move16(); + /* use last good signal for noise generation */ + add_noise(sbuf, outx_new_n1, outdata2, tmp, nsapp_gain, nsapp_gain_n, 1); + /* save current (noisy) output from IMDCT */ + mvr2r_Word16(outx_new, data_noise, tmp); + /* overlapbuf can now be filled with sbuf, needed for subsequently lost frames */ + Copy(pitch125_data, &overlapbuf[Framesize/4], (3*Framesize)/4); + } + FOR (i = 0; i < Framesize; i++) + { + outx_new[i] = sbuf[i]; + move16(); + } + return pitch; +} + +void waveform_adj2_fix( Word16 *overlapbuf, + Word16 *outx_new, + Word16 *data_noise, + Word16 *outx_new_n1, + Word16 *nsapp_gain, + Word16 *nsapp_gain_n, + Word16 *recovery_gain, + Word16 step_concealgain, + Word16 pitch, + Word16 Framesize, + Word16 delay, + Word16 bfi_cnt, + Word16 bfi + ) +{ + Word16 i, n,tablescale,ratio, + dat,Framesizesubn,Framesizesubp,tmp16,s,ptable,temp_OUT,s16MaxCoefNorm,s16MaxCoefNorm2; + Word16 sbuf[L_FRAME_MAX]; + + n=0; + move16(); + Framesizesubn = sub(Framesize,n); + Framesizesubp = sub(Framesize,pitch); + IF (pitch > 0) + { + WHILE (Framesizesubn>0) + { + /* periodical extension */ + Word16 tmp = vadmin(pitch, Framesizesubn); + FOR (i = 0; i < tmp; i++) + { + sbuf[n+i] = overlapbuf[Framesizesubp+i]; + move16(); + } + n = add(n, pitch); + Framesizesubn = sub(Framesize,n); + } + + FOR (i = 0; i < Framesize; i++) + { + overlapbuf[i] = sbuf[i]; + move16(); + } + + { + Word16 size = Framesize; + Word16* noise_ptr = data_noise; + + /* use last (noisy) output from IMDCT for noise generation */ + add_noise(sbuf, outx_new_n1, noise_ptr, size, nsapp_gain, nsapp_gain_n, 0); + + /* save current (noisy) output from IMDCT */ + IF( bfi ) + { + mvr2r_Word16(outx_new, noise_ptr, size); + } + } + test(); + IF (EQ_16(bfi_cnt ,4)||bfi==0) + { + SWITCH ( Framesize) + { + case 160: + { + tablescale =8; + move16(); + ptable = 26214; /* (Word16)(32767*256/160.0+0.5); q7+15 */ move16(); + BREAK; + } + case 320: + { + tablescale =9; + move16(); + ptable = 26214; /* (Word16)(32767*256/320.0+0.5); q8+15 */ move16(); + BREAK; + } + case 512: + { + tablescale =10; + move16(); + ptable = 32767; /* q9+15 */ move16(); + BREAK; + } + case 640: + { + tablescale =10; + move16(); + ptable = 26214; /* (Word16)(32767*512/640.0+0.5); q9+15 */ move16(); + BREAK; + } + default: /* 960 */ + { + tablescale =10; + move16(); + ptable = 17456; /* (Word16)(32767*512/960.0); q9+15 */ move16(); + BREAK; + } + } + IF (bfi == 0) /* overlap-and-add */ + { + Word16 gain_zero_start = 10000; + move16(); + + IF (step_concealgain > 0) + { + gain_zero_start = BASOP_Util_Divide1616_Scale(*recovery_gain, step_concealgain,&s); + gain_zero_start= shl(gain_zero_start, sub(s,14)); /* q0 */ + gain_zero_start= add(gain_zero_start,1); + } + + IF (delay > 0) + { + Framesize = sub(Framesize,delay); + } + + s16MaxCoefNorm = sub(ffr_getSfWord16(sbuf, Framesize),1); + s16MaxCoefNorm2 = ffr_getSfWord16(outx_new, Framesize); + tmp16 = vadmin(gain_zero_start, Framesize); + FOR (i = 0; i < tmp16; i++) + { + ratio = extract_l(L_shr(L_mult(i, ptable), tablescale)); + dat= shl(sbuf[i],s16MaxCoefNorm); + temp_OUT= mult(*recovery_gain, sub(32767,ratio)); + outx_new[i]= round_fx(L_add(L_shr(L_mult(temp_OUT,dat ),s16MaxCoefNorm-1), L_shr(L_mult(shl(outx_new[i],s16MaxCoefNorm2),ratio),s16MaxCoefNorm2))); + move16(); + *recovery_gain =sub(*recovery_gain,shr_r(step_concealgain,1)); /* q14 */ + } + FOR (i = gain_zero_start; i < Framesize; i++) + { + ratio = extract_l(L_shr(L_mult(i, ptable), tablescale)); + outx_new[i] = round_fx(L_shr(L_mult(shl(outx_new[i],s16MaxCoefNorm2),ratio),s16MaxCoefNorm2)); + + } + + if (*recovery_gain < 0) + { + *recovery_gain = 0; + move16(); + } + } + ELSE + { + /* overlap-and-add */ + Word16 tmp; + s16MaxCoefNorm = sub(ffr_getSfWord16(sbuf, Framesize),1); + s16MaxCoefNorm2 = ffr_getSfWord16(outx_new, Framesize); + FOR (i = 0; i < Framesize; i++) + { + dat = shl(sbuf[i], s16MaxCoefNorm); + tmp = extract_l(L_shr(L_mult(i, ptable), tablescale)); + outx_new[i] = round_fx(L_add(L_shr(L_mult(dat, sub(32767,tmp)),s16MaxCoefNorm), L_shr(L_mult(shl(outx_new[i],s16MaxCoefNorm2),tmp),s16MaxCoefNorm2))); + } + } + } + ELSE + { + FOR (i = 0; i < Framesize; i++) + { + outx_new[i] = sbuf[i]; + move16(); + } + } + } + return; +} + +void concealment_signal_tuning_fx(Word16 bfi, Word16 curr_mode, Word16 *outx_new_fx, void *_plcInfo, Word16 nbLostCmpt, Word16 pre_bfi, Word16 *OverlapBuf_fx, Word16 past_core_mode, Word16 *outdata2_fx, Decoder_State *st) +{ + T_PLCInfo *plcInfo = (T_PLCInfo*)_plcInfo; + Word16 FrameSize = plcInfo->FrameSize; + Word16 Pitch = plcInfo->Pitch_fx; + Word16 voicing_fx = 0; + move16(); + move16(); + move16(); + move16(); + IF (bfi) + { + + test(); + IF (st->enablePlcWaveadjust && plcInfo->concealment_method == TCX_NONTONAL) /* #define TCX_NONTONAL 0 */ + { + + IF (EQ_16(nbLostCmpt, 1)) + { + plcInfo->Pitch_fx = pitch_search_fx(outdata2_fx, + outx_new_fx, + FrameSize, + &voicing_fx, + plcInfo->zp_fx, + (plcInfo->ener_fx), + (plcInfo->ener_mean_fx), + plcInfo->data_reci2_fx, + curr_mode + ); + move16(); + + IF (plcInfo->Pitch_fx) /* waveform adjustment for the first lost frame */ + { + plcInfo->Pitch_fx = waveform_adj_fix(OverlapBuf_fx, + outdata2_fx, + outx_new_fx, + plcInfo->data_noise, + &plcInfo->outx_new_n1_fx, + &plcInfo->nsapp_gain_fx, + &plcInfo->nsapp_gain_n_fx, + FrameSize, + plcInfo->T_bfi_fx, + voicing_fx, + curr_mode, + plcInfo->Pitch_fx); + move16(); + } + } + ELSE IF (LT_16(nbLostCmpt, 5)) /* waveform adjustment for the 2nd~4th lost frame */ + { + waveform_adj2_fix(OverlapBuf_fx, + outx_new_fx, + plcInfo->data_noise, + &plcInfo->outx_new_n1_fx, + &plcInfo->nsapp_gain_fx, + &plcInfo->nsapp_gain_n_fx, + &plcInfo->recovery_gain, + plcInfo->step_concealgain_fx, + Pitch, + FrameSize, + 0, + nbLostCmpt, + bfi); + } + } + plcInfo->T_bfi_fx = 1; + move16(); + } + ELSE + { + test(); + test(); + test(); + IF (pre_bfi && + past_core_mode != 0 && + GE_32(st->last_total_brate, 48000) && + EQ_16(st->last_codec_mode, MODE2) ) + { + IF (plcInfo->concealment_method == TCX_NONTONAL) /* #define TCX_NONTONAL 0 */ + { + IF (LT_32(plcInfo->nbLostCmpt, 4)) /* smoothing of the concealed signal with the good signal */ + { + waveform_adj2_fix(OverlapBuf_fx, + outx_new_fx, + plcInfo->data_noise, + &plcInfo->outx_new_n1_fx, + &plcInfo->nsapp_gain_fx, + &plcInfo->nsapp_gain_n_fx, + &plcInfo->recovery_gain, + plcInfo->step_concealgain_fx, + Pitch, + FrameSize, + 0, + add(extract_l(plcInfo->nbLostCmpt), 1), + bfi); + } + } + } + ELSE + { + plcInfo->T_bfi_fx = 0; + move16(); + } + } + return; +} diff --git a/lib_enc/ACcontextMapping_enc.c b/lib_enc/ACcontextMapping_enc.c index ff345d69e857ea9e34fa81b76c8770a1b8420941..a2f890bc8c288e0d7842bb6516edc88e1dfcf90b 100644 --- a/lib_enc/ACcontextMapping_enc.c +++ b/lib_enc/ACcontextMapping_enc.c @@ -164,13 +164,13 @@ void ACcontextMapping_encode2_no_mem_s17_LC( if ( hm_cfg ) { - a1_i = get_next_coeff_mapped( ii, &p1, &idx1, hm_cfg ); - b1_i = get_next_coeff_mapped( ii, &p2, &idx2, hm_cfg ); + a1_i = get_next_coeff_mapped_ivas( ii, &p1, &idx1, hm_cfg ); + b1_i = get_next_coeff_mapped_ivas( ii, &p2, &idx2, hm_cfg ); } else { - a1_i = get_next_coeff_unmapped( ii, &idx1 ); - b1_i = get_next_coeff_unmapped( ii, &idx2 ); + a1_i = get_next_coeff_unmapped_ivas( ii, &idx1 ); + b1_i = get_next_coeff_unmapped_ivas( ii, &idx2 ); } idx = min( idx1, idx2 ); @@ -298,13 +298,13 @@ void ACcontextMapping_encode2_no_mem_s17_LC( if ( idx1 & 1 ) { /* update first context */ - c[p1] = update_mixed_context( c[p1], (int16_t) abs( x[a1_i] ) ); + c[p1] = update_mixed_context_ivas( c[p1], (int16_t) abs( x[a1_i] ) ); } if ( idx2 & 1 ) { /* update second context */ - c[p2] = update_mixed_context( c[p2], (int16_t) abs( x[b1_i] ) ); + c[p2] = update_mixed_context_ivas( c[p2], (int16_t) abs( x[b1_i] ) ); } } } /*end of the 2-tuples loop*/ @@ -519,13 +519,13 @@ int16_t ACcontextMapping_encode2_estimate_no_mem_s17_LC( { if ( hm_cfg ) { - a1_i = get_next_coeff_mapped( ii, &p1, &idx1, hm_cfg ); - b1_i = get_next_coeff_mapped( ii, &p2, &idx2, hm_cfg ); + a1_i = get_next_coeff_mapped_ivas( ii, &p1, &idx1, hm_cfg ); + b1_i = get_next_coeff_mapped_ivas( ii, &p2, &idx2, hm_cfg ); } else { - a1_i = get_next_coeff_unmapped( ii, &idx1 ); - b1_i = get_next_coeff_unmapped( ii, &idx2 ); + a1_i = get_next_coeff_unmapped_ivas( ii, &idx1 ); + b1_i = get_next_coeff_unmapped_ivas( ii, &idx2 ); } idx = min( idx1, idx2 ); @@ -631,13 +631,13 @@ int16_t ACcontextMapping_encode2_estimate_no_mem_s17_LC( if ( idx1 & 1 ) { /* update first context */ - c[p1] = update_mixed_context( c[p1], (int16_t) abs( x[a1_i] ) ); + c[p1] = update_mixed_context_ivas( c[p1], (int16_t) abs( x[a1_i] ) ); } if ( idx2 & 1 ) { /* update second context */ - c[p2] = update_mixed_context( c[p2], (int16_t) abs( x[b1_i] ) ); + c[p2] = update_mixed_context_ivas( c[p2], (int16_t) abs( x[b1_i] ) ); } } } /*end of the 2-tuples loop*/ @@ -771,8 +771,8 @@ void RCcontextMapping_encode2_no_mem_s17_LCS( for ( k = 0; k < lastnz; k += 2 ) { - a1_i = get_next_coeff_mapped( ii, &p1, &idx1, hm_cfg ); - b1_i = get_next_coeff_mapped( ii, &p2, &idx2, hm_cfg ); + a1_i = get_next_coeff_mapped_ivas( ii, &p1, &idx1, hm_cfg ); + b1_i = get_next_coeff_mapped_ivas( ii, &p2, &idx2, hm_cfg ); idx = min( idx1, idx2 ); @@ -845,13 +845,13 @@ void RCcontextMapping_encode2_no_mem_s17_LCS( if ( idx1 & 1 ) { /* update first context */ - c[p1] = update_mixed_context( c[p1], (int16_t) abs( x[a1_i] ) ); + c[p1] = update_mixed_context_ivas( c[p1], (int16_t) abs( x[a1_i] ) ); } if ( idx2 & 1 ) { /* update second context */ - c[p2] = update_mixed_context( c[p2], (int16_t) abs( x[b1_i] ) ); + c[p2] = update_mixed_context_ivas( c[p2], (int16_t) abs( x[b1_i] ) ); } } @@ -1099,8 +1099,8 @@ int16_t RCcontextMapping_encode2_estimate_no_mem_s17_LCS( /* Main Loop through the 2-tuples */ for ( k = 0; k < lastnz; k += 2 ) { - a1_i = get_next_coeff_mapped( ii, &p1, &idx1, hm_cfg ); - b1_i = get_next_coeff_mapped( ii, &p2, &idx2, hm_cfg ); + a1_i = get_next_coeff_mapped_ivas( ii, &p1, &idx1, hm_cfg ); + b1_i = get_next_coeff_mapped_ivas( ii, &p2, &idx2, hm_cfg ); idx = min( idx1, idx2 ); @@ -1183,13 +1183,13 @@ int16_t RCcontextMapping_encode2_estimate_no_mem_s17_LCS( if ( idx1 & 1 ) { /* update first context */ - c[p1] = update_mixed_context( c[p1], (int16_t) abs( x[a1_i] ) ); + c[p1] = update_mixed_context_ivas( c[p1], (int16_t) abs( x[a1_i] ) ); } if ( idx2 & 1 ) { /* update second context */ - c[p2] = update_mixed_context( c[p2], (int16_t) abs( x[b1_i] ) ); + c[p2] = update_mixed_context_ivas( c[p2], (int16_t) abs( x[b1_i] ) ); } } diff --git a/lib_enc/acelp_core_enc.c b/lib_enc/acelp_core_enc.c index 1f71ccd66e839231e7a1474ae4738d532bbf6d4b..7c203ca64d299edf91e87e173f4c1c179d8324a7 100644 --- a/lib_enc/acelp_core_enc.c +++ b/lib_enc/acelp_core_enc.c @@ -302,7 +302,7 @@ ivas_error acelp_core_enc( generate_comfort_noise_enc( st ); - FdCng_exc( st->hFdCngEnc->hFdCngCom, &st->hDtxEnc->CNG_mode, st->L_frame, st->lsp_old, st->hDtxEnc->first_CNG, st->hDtxEnc->lspCNG, Aq, lsp_new, lsf_new, exc, exc2, bwe_exc ); + FdCng_exc_flt( st->hFdCngEnc->hFdCngCom, &st->hDtxEnc->CNG_mode, st->L_frame, st->lsp_old, st->hDtxEnc->first_CNG, st->hDtxEnc->lspCNG, Aq, lsp_new, lsf_new, exc, exc2, bwe_exc ); mvr2r( exc2, exc3, st->L_frame ); if ( st->core_brate == SID_2k40 ) @@ -365,7 +365,7 @@ ivas_error acelp_core_enc( if ( !nelp_mode && !ppp_mode ) { - config_acelp1( ENC, st->total_brate, st->core_brate, st->core, st->extl, st->extl_brate, st->L_frame, st->GSC_noisy_speech, &( st->acelp_cfg ), hBstr->nb_bits_tot, st->coder_type, tc_subfr, 0, &nb_bits, unbits, st->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); + config_acelp1_IVAS( ENC, st->total_brate, st->core_brate, st->core, st->extl, st->extl_brate, st->L_frame, st->GSC_noisy_speech, &( st->acelp_cfg ), hBstr->nb_bits_tot, st->coder_type, tc_subfr, 0, &nb_bits, unbits, st->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); } /*-----------------------------------------------------------------* @@ -485,7 +485,7 @@ ivas_error acelp_core_enc( { tc_classif_enc( st->L_frame, &tc_subfr, &position, attack_flag, st->pitch[0], res ); - config_acelp1( ENC, st->total_brate, st->core_brate, st->core, st->extl, st->extl_brate, st->L_frame, -1, &( st->acelp_cfg ), hBstr->nb_bits_tot, st->coder_type, tc_subfr, 1, NULL, unbits, st->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); + config_acelp1_IVAS( ENC, st->total_brate, st->core_brate, st->core, st->extl, st->extl_brate, st->L_frame, -1, &( st->acelp_cfg ), hBstr->nb_bits_tot, st->coder_type, tc_subfr, 1, NULL, unbits, st->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); } /*---------------------------------------------------------------* @@ -543,7 +543,7 @@ ivas_error acelp_core_enc( lsf_syn_mem_restore( st, tilt_code_bck, gc_threshold_bck, clip_var_bck, next_force_sf_bck, lsp_new, lsp_mid, clip_var, mem_AR, mem_MA, lsp_new_bck, lsp_mid_bck, Bin_E, Bin_E_old, mem_syn_bck, mem_w0_bck, streaklimit, pstreaklen ); /* Configure ACELP bit allocation */ - config_acelp1( ENC, st->total_brate, st->core_brate, st->core, st->extl, st->extl_brate, st->L_frame, -1, &( st->acelp_cfg ), hBstr->nb_bits_tot, st->coder_type, tc_subfr, 0, &nb_bits, unbits, 0, &uc_two_stage_flag, 0, 0, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); + config_acelp1_IVAS( ENC, st->total_brate, st->core_brate, st->core, st->extl, st->extl_brate, st->L_frame, -1, &( st->acelp_cfg ), hBstr->nb_bits_tot, st->coder_type, tc_subfr, 0, &nb_bits, unbits, 0, &uc_two_stage_flag, 0, 0, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); /* redo LSF quantization */ lsf_enc( st, lsf_new, lsp_new, lsp_mid, Aq, tdm_low_rate_mode, 0, NULL ); diff --git a/lib_enc/acelp_core_switch_enc.c b/lib_enc/acelp_core_switch_enc.c index 8b4803e8386e20cada9b1027d835b3add4a2110f..b896ee7c1343e0ae14f2708d2030756ac695bf87 100644 --- a/lib_enc/acelp_core_switch_enc.c +++ b/lib_enc/acelp_core_switch_enc.c @@ -129,7 +129,7 @@ void acelp_core_switch_enc( * Excitation encoding *----------------------------------------------------------------*/ - config_acelp1( ENC, st->total_brate, cbrate, st->core, -1, -1, st->last_L_frame, -1, &( st->acelp_cfg ), hBstr->nb_bits_tot, GENERIC, -1, -1, &j, &i, st->element_mode, &i /*dummy*/, 0 /*tdm_lp_reuse_flag*/, 0 /*tdm_low_rate_mode*/, st->idchan, st->active_cnt, 0 /*tdm_Pitch_reuse_flag*/, 0, 0 /*GSC_IVAS_mode*/ ); + config_acelp1_IVAS( ENC, st->total_brate, cbrate, st->core, -1, -1, st->last_L_frame, -1, &( st->acelp_cfg ), hBstr->nb_bits_tot, GENERIC, -1, -1, &j, &i, st->element_mode, &i /*dummy*/, 0 /*tdm_lp_reuse_flag*/, 0 /*tdm_low_rate_mode*/, st->idchan, st->active_cnt, 0 /*tdm_Pitch_reuse_flag*/, 0, 0 /*GSC_IVAS_mode*/ ); encod_gen_voic_core_switch( st, st->last_L_frame, inp, Aq, A, T_op, st->voicing, exc, cbrate ); @@ -257,7 +257,7 @@ static void encod_gen_voic_core_switch( * Find adaptive exitation *-----------------------------------------------------------------*/ - pred_lt4( exc, exc, T0, T0_frac, L_SUBFR + 1, inter4_2, L_INTERPOL2, PIT_UP_SAMP ); + pred_lt4_flt( exc, exc, T0, T0_frac, L_SUBFR + 1, inter4_2, L_INTERPOL2, PIT_UP_SAMP ); /*-----------------------------------------------------------------* * Gain clipping test to avoid unstable synthesis on frame erasure @@ -322,7 +322,7 @@ static void encod_gen_voic_core_switch( * long term prediction on the 2nd sub frame *-----------------------------------------------------------------*/ - pred_lt4( &exc[L_SUBFR], &exc[L_SUBFR], T0, T0_frac, L_SUBFR + 1, inter4_2, L_INTERPOL2, PIT_UP_SAMP ); + pred_lt4_flt( &exc[L_SUBFR], &exc[L_SUBFR], T0, T0_frac, L_SUBFR + 1, inter4_2, L_INTERPOL2, PIT_UP_SAMP ); for ( i = 0; i < L_SUBFR; i++ ) { diff --git a/lib_enc/ari_enc.c b/lib_enc/ari_enc.c index b2e692bc168e98536b40c52e828677928d94dc55..018d75155300597c33aa2083e259a183493417a8 100644 --- a/lib_enc/ari_enc.c +++ b/lib_enc/ari_enc.c @@ -149,8 +149,8 @@ int16_t ari_encode_14bits_ext( low = s->low; range = high - low + 1; - high = low + mul_sbc_14bits( range, cum_freq[symbol] ) - 1; - low += mul_sbc_14bits( range, cum_freq[symbol + 1] ); + high = low + mul_sbc_14bits_ivas( range, cum_freq[symbol] ) - 1; + low += mul_sbc_14bits_ivas( range, cum_freq[symbol + 1] ); bits_to_follow = s->bits_to_follow; @@ -227,8 +227,8 @@ int16_t ari_encode_14bits_range( low = s->low; range = high - low; - high = low + mul_sbc_14bits( range, cum_freq_high ); - low += mul_sbc_14bits( range, cum_freq_low ); + high = low + mul_sbc_14bits_ivas( range, cum_freq_high ); + low += mul_sbc_14bits_ivas( range, cum_freq_low ); bits_to_follow = s->bits_to_follow; diff --git a/lib_enc/ari_hm_enc.c b/lib_enc/ari_hm_enc.c index d37bdd92cd0a996210de2ba3a29f9906e7154ca6..5f421e352f8f101eb3abab9833407c019fa91220 100644 --- a/lib_enc/ari_hm_enc.c +++ b/lib_enc/ari_hm_enc.c @@ -435,7 +435,7 @@ static float tcx_hm_get_re( ne[i] = env[i]; } - tcx_hm_modify_envelope( gain, lag, fract_res, p, ne, L_frame ); + tcx_hm_modify_envelope_ivas( gain, lag, fract_res, p, ne, L_frame ); /* Normalize */ G = 0; @@ -582,11 +582,11 @@ void tcx_hm_analyse( prm_hm[1] = SearchPeriodicityIndex( fspec, abs_spectrum, L_frame, targetBits - *hm_bits, LtpPitchLag, LtpGain, &RelativeScore ); /* Convert the index to lag */ - UnmapIndex( prm_hm[1], L_frame >= 256, LtpPitchLag, ( targetBits - *hm_bits <= kSmallerLagsTargetBitsThreshold ) || ( L_frame < 256 ), &fract_res, &tmpL ); + UnmapIndex_ivas( prm_hm[1], L_frame >= 256, LtpPitchLag, ( targetBits - *hm_bits <= kSmallerLagsTargetBitsThreshold ) || ( L_frame < 256 ), &fract_res, &tmpL ); lag = (int16_t) tmpL; /* Render harmonic model */ - tcx_hm_render( lag, fract_res, p ); + tcx_hm_render_ivas( lag, fract_res, p ); /* Calculate and quantize gain */ gain = 0; @@ -598,14 +598,14 @@ void tcx_hm_analyse( { prm_hm[0] = 1; /* flag: on */ - *hm_bits += CountIndexBits( L_frame >= 256, prm_hm[1] ); + *hm_bits += CountIndexBits_ivas( L_frame >= 256, prm_hm[1] ); if ( coder_type == VOICED ) { *hm_bits += kTcxHmNumGainBits; } - tcx_hm_modify_envelope( gain, lag, fract_res, p, env, L_frame ); + tcx_hm_modify_envelope_ivas( gain, lag, fract_res, p, env, L_frame ); } else { diff --git a/lib_enc/arith_coder_enc.c b/lib_enc/arith_coder_enc.c index d200fc9a99aa61795d1336f9deda8160601c275a..95cb833682d9df1ca1d317a580396a87f25d2efa 100644 --- a/lib_enc/arith_coder_enc.c +++ b/lib_enc/arith_coder_enc.c @@ -161,7 +161,7 @@ static float tcx_arith_find_max_scale( const int16_t L_frame, /* i : number of spectral lines */ const Word16 envelope[], /* i : scaled envelope (Q15-e) */ const Word16 envelope_e, /* i : scaled envelope exponent (Q0) */ - const Word16 exps[], /* i : expfp(-(integer)envelope[]/2) */ + const Word16 exps[], /* i : expfp_evs(-(integer)envelope[]/2) */ const float deadzone /* i : deadzone (0.5f = no deadzone) */ ) { @@ -207,26 +207,26 @@ static float tcx_arith_find_max_scale( q = (int16_t) ceil( ( ( limit - log( 1.0f - ( exps[k] / PCM16_TO_FLT_FAC ) * ( exps[k] / PCM16_TO_FLT_FAC ) ) ) / ( envelope[k] * envelope_scale ) - 1 ) / 2.0f ); /* Refinement: get the exact q */ - powfp_odd2( exps[k], q, &tmpi1, &tmpi2 ); + powfp_odd2_evs( exps[k], q, &tmpi1, &tmpi2 ); if ( tmpi1 - tmpi2 >= 2 ) { /* q may be too low */ - powfp_odd2( exps[k], q + 1, &tmpi1, &tmpi2 ); + powfp_odd2_evs( exps[k], q + 1, &tmpi1, &tmpi2 ); while ( tmpi1 - tmpi2 >= 2 ) { ++q; - powfp_odd2( exps[k], q + 1, &tmpi1, &tmpi2 ); + powfp_odd2_evs( exps[k], q + 1, &tmpi1, &tmpi2 ); } } else { /* q is too high */ --q; - powfp_odd2( exps[k], q, &tmpi1, &tmpi2 ); + powfp_odd2_evs( exps[k], q, &tmpi1, &tmpi2 ); while ( tmpi1 - tmpi2 < 2 ) { --q; - powfp_odd2( exps[k], q, &tmpi1, &tmpi2 ); + powfp_odd2_evs( exps[k], q, &tmpi1, &tmpi2 ); } } @@ -279,7 +279,7 @@ static float tcx_arith_rateloop( const int16_t L_frame, /* i : number of spectral lines */ const Word16 envelope[], /* i : scaled envelope (Q15-e) */ const Word16 envelope_e, /* i : scaled envelope exponent (Q0) */ - const Word16 exps[], /* i : expfp(-(integer)envelope[]/2) */ + const Word16 exps[], /* i : expfp_evs(-(integer)envelope[]/2) */ const int16_t target_bits, /* i : target bit budget */ const float deadzone, /* i : deadzone (0.5f = no deadzone) */ const int16_t deadzone_flags[], /* i : line-wise deadzone control */ @@ -442,7 +442,7 @@ static int16_t tcx_arith_encode( const int16_t signs[], /* i : signs */ const int16_t kMax, /* i : number of nonzero spectral lines to code */ const int16_t L_frame, /* i : nominal number of spectral lines */ - const Word16 exps[], /* i : expfp(-(integer)envelope[]/2) */ + const Word16 exps[], /* i : expfp_evs(-(integer)envelope[]/2) */ const int16_t target_bits, /* i : target bit budget */ int16_t prm[] /* o : bitstream */ ) @@ -468,11 +468,11 @@ static int16_t tcx_arith_encode( else { /* q_abs_spectrum[k] != 0 */ - powfp_odd2( exps[k], (Word16) q_abs_spectrum[k], &tmpi1, &tmpi2 ); + powfp_odd2_evs( exps[k], (Word16) q_abs_spectrum[k], &tmpi1, &tmpi2 ); while ( tmpi1 < tmpi2 + 2 ) { --q_abs_spectrum[k]; - powfp_odd2( exps[k], (Word16) q_abs_spectrum[k], &tmpi1, &tmpi2 ); + powfp_odd2_evs( exps[k], (Word16) q_abs_spectrum[k], &tmpi1, &tmpi2 ); } bp = ari_encode_14bits_range( prm, bp, target_bits, &as, tmpi2 >> 1, tmpi1 >> 1 ); bp = ari_encode_14bits_sign( prm, bp, target_bits, &as, signs[k] ); @@ -492,7 +492,7 @@ static int16_t tcx_arith_encode( --q_abs_spectrum[k]; /* Retry encoding */ - powfp_odd2( exps[k], (Word16) q_abs_spectrum[k], &tmpi1, &tmpi2 ); + powfp_odd2_evs( exps[k], (Word16) q_abs_spectrum[k], &tmpi1, &tmpi2 ); bp = ari_encode_14bits_range( prm, bp, target_bits, &as, tmpi2 >> 1, tmpi1 >> 1 ); bp = ari_encode_14bits_sign( prm, bp, target_bits, &as, signs[k] ); if ( as.high > as.low ) /* Success */ @@ -609,7 +609,7 @@ void tcx_arith_encode_envelope( gamma_uw = 1.0f / st->gamma_flt; #define WMC_TOOL_SKIP - tcx_arith_render_envelope( A_ind, L_frame, L_spec, FL2WORD16( hTcxCfg->preemph_fac_flt), FL2WORD16( gamma_w ), FL2WORD16( 0.5f * gamma_uw ), env ); + tcx_arith_render_envelope_flt( A_ind, L_frame, L_spec, FL2WORD16( hTcxCfg->preemph_fac_flt), FL2WORD16( gamma_w ), FL2WORD16( 0.5f * gamma_uw ), env ); #undef WMC_TOOL_SKIP for ( k = 0; k < L_spec; ++k ) @@ -644,13 +644,13 @@ void tcx_arith_encode_envelope( L_spec_core = min( L_spec_core, st->hIGFEnc->infoStartLine ); } envelope = (Word16 *) env; - tcx_arith_scale_envelope( L_spec, L_spec_core, env, target_bits, low_complexity, envelope, &envelope_e ); + tcx_arith_scale_envelope_flt( L_spec, L_spec_core, env, target_bits, low_complexity, envelope, &envelope_e ); #define WMC_TOOL_SKIP tmp = sub( envelope_e, 1 ); FOR( k = 0; k < L_spec; k++ ) { - exponents[k] = expfp( negate( envelope[k] ), tmp ); + exponents[k] = expfp_evs( negate( envelope[k] ), tmp ); } #undef WMC_TOOL_SKIP scale = tcx_arith_rateloop( spectrum, L_spec, envelope, envelope_e, exponents, target_bits, deadzone, deadzone_flags, &( hTcxEnc->tcx_target_bits_fac_flt) ); diff --git a/lib_enc/cng_enc.c b/lib_enc/cng_enc.c index de5c00b71e83c63138cc88b20e690edd967e5e6d..7f3a3531744d052636fc2c76700c7ff07435321d 100644 --- a/lib_enc/cng_enc.c +++ b/lib_enc/cng_enc.c @@ -310,7 +310,7 @@ void CNG_enc( } else { - hDtxEnc->CNG_mode = get_cng_mode( hDtxEnc->last_active_brate ); + hDtxEnc->CNG_mode = get_cng_mode_ivas( hDtxEnc->last_active_brate ); } } @@ -1022,7 +1022,7 @@ static int16_t shb_DTX( { att = 0.0f; - apply_scale( &att, st->hFdCngEnc->hFdCngCom->CngBandwidth, st->hFdCngEnc->hFdCngCom->CngBitrate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO ); + apply_scale_flt( &att, st->hFdCngEnc->hFdCngCom->CngBandwidth, st->hFdCngEnc->hFdCngCom->CngBitrate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO ); } else { diff --git a/lib_enc/cod_ace.c b/lib_enc/cod_ace.c index fda2e140bee5a4f49495b0c81a5093c537da84c5..62f79b79a1b7b7a43adf46dffc5d1a42d85b283a 100644 --- a/lib_enc/cod_ace.c +++ b/lib_enc/cod_ace.c @@ -97,7 +97,7 @@ void coder_acelp( acelp_cfg = &( st->acelp_cfg ); /* Configure ACELP */ - BITS_ALLOC_config_acelp( target_bits, st->coder_type, acelp_cfg, st->narrowBand, st->nb_subfr ); + BITS_ALLOC_config_acelp_IVAS( target_bits, st->coder_type, acelp_cfg, st->narrowBand, st->nb_subfr ); /*------------------------------------------------------------------------* * Initialize buffers * @@ -221,22 +221,22 @@ void coder_acelp( { if ( T0_res == ( st->pit_res_max >> 1 ) ) { - pred_lt4( &exc[i_subfr], &exc[i_subfr], T0, T0_frac << 1, L_SUBFR + 1, inter6_2, PIT_L_INTERPOL6_2, PIT_UP_SAMP6 ); + pred_lt4_flt( &exc[i_subfr], &exc[i_subfr], T0, T0_frac << 1, L_SUBFR + 1, inter6_2, PIT_L_INTERPOL6_2, PIT_UP_SAMP6 ); } else { - pred_lt4( &exc[i_subfr], &exc[i_subfr], T0, T0_frac, L_SUBFR + 1, inter6_2, PIT_L_INTERPOL6_2, PIT_UP_SAMP6 ); + pred_lt4_flt( &exc[i_subfr], &exc[i_subfr], T0, T0_frac, L_SUBFR + 1, inter6_2, PIT_L_INTERPOL6_2, PIT_UP_SAMP6 ); } } else { if ( T0_res == ( st->pit_res_max >> 1 ) ) { - pred_lt4( &exc[i_subfr], &exc[i_subfr], T0, T0_frac << 1, L_SUBFR + 1, inter4_2, L_INTERPOL2, PIT_UP_SAMP ); + pred_lt4_flt( &exc[i_subfr], &exc[i_subfr], T0, T0_frac << 1, L_SUBFR + 1, inter4_2, L_INTERPOL2, PIT_UP_SAMP ); } else { - pred_lt4( &exc[i_subfr], &exc[i_subfr], T0, T0_frac, L_SUBFR + 1, inter4_2, L_INTERPOL2, PIT_UP_SAMP ); + pred_lt4_flt( &exc[i_subfr], &exc[i_subfr], T0, T0_frac, L_SUBFR + 1, inter4_2, L_INTERPOL2, PIT_UP_SAMP ); } } diff --git a/lib_enc/cod_tcx.c b/lib_enc/cod_tcx.c index d9ee76c79630064fdb4d595fd6d69a08d90e06dd..555199a9863db3209db4e85344cce525c331a48b 100644 --- a/lib_enc/cod_tcx.c +++ b/lib_enc/cod_tcx.c @@ -67,7 +67,7 @@ void HBAutocorrelation( * Windowing * *-----------------------------------------------------------*/ - WindowSignal( hTcxCfg, hTcxCfg->tcx_offset, left_overlap_mode, right_overlap_mode, &left_overlap, &right_overlap, speech, &L_frame, xn_buf, 1, 0 ); + WindowSignal_flt( hTcxCfg, hTcxCfg->tcx_offset, left_overlap_mode, right_overlap_mode, &left_overlap, &right_overlap, speech, &L_frame, xn_buf, 1, 0 ); /*-----------------------------------------------------------* * Autocorrelation * @@ -745,7 +745,7 @@ void ShapeSpectrum( weight_a( A, Ap, gamma1, M ); - lpc2mdct( Ap, M, gainlpc, FDNS_NPTS, 0 ); + lpc2mdct_flt( Ap, M, gainlpc, FDNS_NPTS, 0 ); mdct_preShaping( spectrum, L_frame, gainlpc ); @@ -1217,15 +1217,15 @@ void QuantizeTCXSpectrum( PeriodicityIndex = SearchPeriodicityIndex( spectrum, NULL, L_spec, sqTargetBits, LtpPitchLag, hTcxEnc->tcxltp ? hTcxEnc->tcxltp_gain_flt : -1.0f, &RelativeScore ); - NumIndexBits = CountIndexBits( L_spec >= 256, PeriodicityIndex ); + NumIndexBits = CountIndexBits_ivas( L_spec >= 256, PeriodicityIndex ); if ( st->element_mode > EVS_MONO ) { - ConfigureContextHm( L_spec, sqTargetBits - NumIndexBits, PeriodicityIndex, LtpPitchLag, hm_cfg ); + ConfigureContextHm_ivas( L_spec, sqTargetBits - NumIndexBits, PeriodicityIndex, LtpPitchLag, hm_cfg ); } else { - ConfigureContextHm( L_spec, sqTargetBits, PeriodicityIndex, LtpPitchLag, hm_cfg ); + ConfigureContextHm_ivas( L_spec, sqTargetBits, PeriodicityIndex, LtpPitchLag, hm_cfg ); } /* Quantize original spectrum */ @@ -1535,7 +1535,7 @@ void QuantizeTCXSpectrum( if ( !st->tcxonly ) { - AdaptLowFreqDeemph( spectrum, hTcxEnc->tcx_lpc_shaped_ari, gainlpc, L_frame, lf_deemph_fact ); + AdaptLowFreqDeemph_flt( spectrum, hTcxEnc->tcx_lpc_shaped_ari, gainlpc, L_frame, lf_deemph_fact ); } assert( x_orig != spectrum ); @@ -1605,7 +1605,7 @@ void QuantizeTCXSpectrum( { if ( hTcxEnc->tcxltp && ( hTcxEnc->tcxltp_gain_flt > 0.0f ) && !hTcxEnc->fUseTns[frame_cnt] ) { - PsychAdaptLowFreqDeemph( spectrum, gainlpc, NULL ); + PsychAdaptLowFreqDeemph_flt( spectrum, gainlpc, NULL ); } } } @@ -1670,7 +1670,7 @@ void InternalTCXDecoder( noiseTransWidth = GetTransWidth( st->tcxonly, ( L_frame == st->L_frame >> 1 ), hTcxEnc->tcxltp_gain_flt, ( st->hTcxCfg->ctx_hm && st->last_core != ACELP_CORE && hm_active ) ); assert( st->element_mode != IVAS_CPE_MDCT ); - tcx_noise_filling( spectrum, nf_seed, iStart, noiseFillingBorder, noiseTransWidth, L_frame, hTcxEnc->noiseTiltFactor_flt, fac_ns, NULL, st->element_mode ); + tcx_noise_filling_flt( spectrum, nf_seed, iStart, noiseFillingBorder, noiseTransWidth, L_frame, hTcxEnc->noiseTiltFactor_flt, fac_ns, NULL, st->element_mode ); } if ( st->total_brate < ACELP_13k20 || st->rf_mode ) @@ -1698,7 +1698,7 @@ void InternalTCXDecoder( } else { - mdct_noiseShaping( spectrum, L_frame, gainlpc, FDNS_NPTS ); + mdct_noiseShaping_flt( spectrum, L_frame, gainlpc, FDNS_NPTS ); } /*-----------------------------------------------------------* @@ -1733,7 +1733,7 @@ void InternalTCXDecoder( if ( st->hTcxCfg->fIsTNSAllowed ) { - SetTnsConfig( st->hTcxCfg, st->core == TCX_20_CORE, ( st->last_core == ACELP_CORE ) && ( frame_cnt == 0 ) ); + SetTnsConfig_flt( st->hTcxCfg, st->core == TCX_20_CORE, ( st->last_core == ACELP_CORE ) && ( frame_cnt == 0 ) ); /* Apply TNS to get the reconstructed signal */ if ( hTcxEnc->fUseTns[frame_cnt] != 0 ) @@ -1790,18 +1790,18 @@ void InternalTCXDecoder( { if ( st->hTcxCfg->tcx_last_overlap_mode == MIN_OVERLAP ) { - TCX_MDCT_Inverse( spectrum + w * L_spec_TCX5, win, L_ola, L_win - L_ola, L_ola, st->element_mode ); + TCX_MDCT_Inverse_flt( spectrum + w * L_spec_TCX5, win, L_ola, L_win - L_ola, L_ola, st->element_mode ); } else { - TCX_MDCT_Inverse( spectrum + w * L_spec_TCX5, win, L_ola, L_win - L_ola, L_ola, st->element_mode ); + TCX_MDCT_Inverse_flt( spectrum + w * L_spec_TCX5, win, L_ola, L_win - L_ola, L_ola, st->element_mode ); } - tcx_windowing_synthesis_current_frame( win, st->hTcxCfg->tcx_aldo_window_2_flt, st->hTcxCfg->tcx_mdct_window_half_flt, st->hTcxCfg->tcx_mdct_window_minimum_flt, L_ola, st->hTcxCfg->tcx_mdct_window_half_length, st->hTcxCfg->tcx_mdct_window_min_length, w == 0 && st->last_core == ACELP_CORE, ( w > 0 ) || ( w == 0 && tcx_last_overlap_mode == 2 ) ? MIN_OVERLAP : st->hTcxCfg->tcx_last_overlap_mode, st->hTcxEnc->acelp_zir_flt, st->hTcxEnc->Txnq_flt, NULL, Aq_old, st->hTcxCfg->tcx_mdct_window_trans_flt, L_win, tcx_offset < 0 ? -tcx_offset : 0, ( w > 0 ) ? 1 : st->last_core, 0, 0 ); + tcx_windowing_synthesis_current_frame_flt( win, st->hTcxCfg->tcx_aldo_window_2_flt, st->hTcxCfg->tcx_mdct_window_half_flt, st->hTcxCfg->tcx_mdct_window_minimum_flt, L_ola, st->hTcxCfg->tcx_mdct_window_half_length, st->hTcxCfg->tcx_mdct_window_min_length, w == 0 && st->last_core == ACELP_CORE, ( w > 0 ) || ( w == 0 && tcx_last_overlap_mode == 2 ) ? MIN_OVERLAP : st->hTcxCfg->tcx_last_overlap_mode, st->hTcxEnc->acelp_zir_flt, st->hTcxEnc->Txnq_flt, NULL, Aq_old, st->hTcxCfg->tcx_mdct_window_trans_flt, L_win, tcx_offset < 0 ? -tcx_offset : 0, ( w > 0 ) ? 1 : st->last_core, 0, 0 ); if ( w > 0 ) { - tcx_windowing_synthesis_past_frame( xn_buf + tcx_offset - ( L_ola >> 1 ) + w * L_win, st->hTcxCfg->tcx_aldo_window_1_trunc_flt, st->hTcxCfg->tcx_mdct_window_half_flt, st->hTcxCfg->tcx_mdct_window_minimum_flt, L_ola, st->hTcxCfg->tcx_mdct_window_half_length, st->hTcxCfg->tcx_mdct_window_min_length, 2 ); + tcx_windowing_synthesis_past_frame_flt( xn_buf + tcx_offset - ( L_ola >> 1 ) + w * L_win, st->hTcxCfg->tcx_aldo_window_1_trunc_flt, st->hTcxCfg->tcx_mdct_window_half_flt, st->hTcxCfg->tcx_mdct_window_minimum_flt, L_ola, st->hTcxCfg->tcx_mdct_window_half_length, st->hTcxCfg->tcx_mdct_window_min_length, 2 ); } /* add part of current sub-window overlapping with previous window */ @@ -1829,18 +1829,18 @@ void InternalTCXDecoder( overlap = st->hTcxCfg->tcx_mdct_window_delay; /* 1st TCX-5 window, special MDCT with minimum overlap on right side */ - TCX_MDCT_Inverse( spectrum, win + L_win, 0, L_win - ( L_ola >> 1 ), L_ola, st->element_mode ); + TCX_MDCT_Inverse_flt( spectrum, win + L_win, 0, L_win - ( L_ola >> 1 ), L_ola, st->element_mode ); /* copy new sub-window region not overlapping with previous window */ mvr2r( win + L_win, xn_buf + ( overlap >> 1 ), L_win + ( L_ola >> 1 ) ); /* 2nd TCX-5 window, regular MDCT with minimum overlap on both sides */ - TCX_MDCT_Inverse( spectrum + L_spec_TCX5, win, L_ola, L_win - L_ola, L_ola, st->element_mode ); + TCX_MDCT_Inverse_flt( spectrum + L_spec_TCX5, win, L_ola, L_win - L_ola, L_ola, st->element_mode ); - tcx_windowing_synthesis_current_frame( win, st->hTcxCfg->tcx_aldo_window_2_flt, st->hTcxCfg->tcx_mdct_window_half_flt, st->hTcxCfg->tcx_mdct_window_minimum_flt, L_ola, st->hTcxCfg->tcx_mdct_window_half_length, st->hTcxCfg->tcx_mdct_window_min_length, 0, /* left_rect */ + tcx_windowing_synthesis_current_frame_flt( win, st->hTcxCfg->tcx_aldo_window_2_flt, st->hTcxCfg->tcx_mdct_window_half_flt, st->hTcxCfg->tcx_mdct_window_minimum_flt, L_ola, st->hTcxCfg->tcx_mdct_window_half_length, st->hTcxCfg->tcx_mdct_window_min_length, 0, /* left_rect */ 2, /* left_mode */ st->hTcxEnc->acelp_zir_flt, st->hTcxEnc->Txnq_flt, NULL, Aq_old, st->hTcxCfg->tcx_mdct_window_trans_flt, L_win, tcx_offset < 0 ? -tcx_offset : 0, 1, /* not st->last_core */ 0, 0 ); - tcx_windowing_synthesis_past_frame( xn_buf + ( overlap >> 1 ) + L_win - ( L_ola >> 1 ), st->hTcxCfg->tcx_aldo_window_1_trunc_flt, st->hTcxCfg->tcx_mdct_window_half_flt, st->hTcxCfg->tcx_mdct_window_minimum_flt, L_ola, st->hTcxCfg->tcx_mdct_window_half_length, st->hTcxCfg->tcx_mdct_window_min_length, 2 ); + tcx_windowing_synthesis_past_frame_flt( xn_buf + ( overlap >> 1 ) + L_win - ( L_ola >> 1 ), st->hTcxCfg->tcx_aldo_window_1_trunc_flt, st->hTcxCfg->tcx_mdct_window_half_flt, st->hTcxCfg->tcx_mdct_window_minimum_flt, L_ola, st->hTcxCfg->tcx_mdct_window_half_length, st->hTcxCfg->tcx_mdct_window_min_length, 2 ); /* add part of current sub-window overlapping with previous window */ v_add( win, xn_buf + ( overlap >> 1 ) + L_win - ( L_ola >> 1 ), xn_buf + ( overlap >> 1 ) + L_win - ( L_ola >> 1 ), L_ola ); @@ -1854,14 +1854,14 @@ void InternalTCXDecoder( xn_buf[overlap - 1 - w] = -1.0f * xn_buf[w]; } - tcx_windowing_synthesis_current_frame( xn_buf, st->hTcxCfg->tcx_aldo_window_2_flt, st->hTcxCfg->tcx_mdct_window_half_flt, st->hTcxCfg->tcx_mdct_window_minimum_flt, overlap, /*st->hTcxCfg->tcx_mdct_window_length*/ st->hTcxCfg->tcx_mdct_window_half_length, st->hTcxCfg->tcx_mdct_window_min_length, st->last_core == ACELP_CORE, 0, /* left_mode */ st->hTcxEnc->acelp_zir_flt, st->hTcxEnc->Txnq_flt, NULL, Aq_old, st->hTcxCfg->tcx_mdct_window_trans_flt, L_win, tcx_offset < 0 ? -tcx_offset : 0, st->last_core, 0, 0 ); + tcx_windowing_synthesis_current_frame_flt( xn_buf, st->hTcxCfg->tcx_aldo_window_2_flt, st->hTcxCfg->tcx_mdct_window_half_flt, st->hTcxCfg->tcx_mdct_window_minimum_flt, overlap, /*st->hTcxCfg->tcx_mdct_window_length*/ st->hTcxCfg->tcx_mdct_window_half_length, st->hTcxCfg->tcx_mdct_window_min_length, st->last_core == ACELP_CORE, 0, /* left_mode */ st->hTcxEnc->acelp_zir_flt, st->hTcxEnc->Txnq_flt, NULL, Aq_old, st->hTcxCfg->tcx_mdct_window_trans_flt, L_win, tcx_offset < 0 ? -tcx_offset : 0, st->last_core, 0, 0 ); } else { /* default, i.e. maximum overlap, single transform, no grouping */ - TCX_MDCT_Inverse( spectrum, xn_buf, overlap, L_frame - overlap, overlap, st->element_mode ); + TCX_MDCT_Inverse_flt( spectrum, xn_buf, overlap, L_frame - overlap, overlap, st->element_mode ); - tcx_windowing_synthesis_current_frame( xn_buf, st->hTcxCfg->tcx_aldo_window_2_flt, st->hTcxCfg->tcx_mdct_window_half_flt, st->hTcxCfg->tcx_mdct_window_minimum_flt, overlap, /*st->hTcxCfg->tcx_mdct_window_length*/ st->hTcxCfg->tcx_mdct_window_half_length, st->hTcxCfg->tcx_mdct_window_min_length, st->last_core == ACELP_CORE, ( frame_cnt > 0 ) && ( tcx_last_overlap_mode == 0 ) && ( st->last_core != ACELP_CORE ) ? 2 : tcx_last_overlap_mode, st->hTcxEnc->acelp_zir_flt, st->hTcxEnc->Txnq_flt, NULL, Aq_old, st->hTcxCfg->tcx_mdct_window_trans_flt, st->L_frame >> 2, tcx_offset < 0 ? -tcx_offset : 0, st->last_core, 0, 0 ); + tcx_windowing_synthesis_current_frame_flt( xn_buf, st->hTcxCfg->tcx_aldo_window_2_flt, st->hTcxCfg->tcx_mdct_window_half_flt, st->hTcxCfg->tcx_mdct_window_minimum_flt, overlap, /*st->hTcxCfg->tcx_mdct_window_length*/ st->hTcxCfg->tcx_mdct_window_half_length, st->hTcxCfg->tcx_mdct_window_min_length, st->last_core == ACELP_CORE, ( frame_cnt > 0 ) && ( tcx_last_overlap_mode == 0 ) && ( st->last_core != ACELP_CORE ) ? 2 : tcx_last_overlap_mode, st->hTcxEnc->acelp_zir_flt, st->hTcxEnc->Txnq_flt, NULL, Aq_old, st->hTcxCfg->tcx_mdct_window_trans_flt, st->L_frame >> 2, tcx_offset < 0 ? -tcx_offset : 0, st->last_core, 0, 0 ); } /* tcx_last_overlap_mode != FULL_OVERLAP */ } @@ -1881,11 +1881,11 @@ void InternalTCXDecoder( } else { - TCX_MDCT_Inverse( spectrum, xn_buf, overlap, L_frame - overlap, overlap, st->element_mode ); + TCX_MDCT_Inverse_flt( spectrum, xn_buf, overlap, L_frame - overlap, overlap, st->element_mode ); /* Windowing, overlap and add */ /* Window current frame */ - tcx_windowing_synthesis_current_frame( xn_buf, st->hTcxCfg->tcx_aldo_window_2_flt, st->hTcxCfg->tcx_mdct_window_half_flt, st->hTcxCfg->tcx_mdct_window_minimum_flt, overlap, /*st->hTcxCfg->tcx_mdct_window_length*/ st->hTcxCfg->tcx_mdct_window_half_length, st->hTcxCfg->tcx_mdct_window_min_length, st->last_core == ACELP_CORE, st->hTcxCfg->tcx_last_overlap_mode, /*left mode*/ st->hTcxEnc->acelp_zir_flt, st->hTcxEnc->Txnq_flt, NULL, Aq_old, st->hTcxCfg->tcx_mdct_window_trans_flt, st->L_frame >> 1, tcx_offset < 0 ? -tcx_offset : 0, st->last_core, 0, 0 ); + tcx_windowing_synthesis_current_frame_flt( xn_buf, st->hTcxCfg->tcx_aldo_window_2_flt, st->hTcxCfg->tcx_mdct_window_half_flt, st->hTcxCfg->tcx_mdct_window_minimum_flt, overlap, /*st->hTcxCfg->tcx_mdct_window_length*/ st->hTcxCfg->tcx_mdct_window_half_length, st->hTcxCfg->tcx_mdct_window_min_length, st->last_core == ACELP_CORE, st->hTcxCfg->tcx_last_overlap_mode, /*left mode*/ st->hTcxEnc->acelp_zir_flt, st->hTcxEnc->Txnq_flt, NULL, Aq_old, st->hTcxCfg->tcx_mdct_window_trans_flt, st->L_frame >> 1, tcx_offset < 0 ? -tcx_offset : 0, st->last_core, 0, 0 ); } } /* TCX-20/TCX-10 and TCX-only */ @@ -1911,7 +1911,7 @@ void InternalTCXDecoder( tcx_last_overlap_mode = 2; /* use minimum overlap between the two TCX-10 windows */ } - tcx_windowing_synthesis_past_frame( st->hTcxEnc->Txnq_flt, st->hTcxCfg->tcx_aldo_window_1_trunc_flt, st->hTcxCfg->tcx_mdct_window_half_flt, st->hTcxCfg->tcx_mdct_window_minimum_flt, overlap, st->hTcxCfg->tcx_mdct_window_half_length, st->hTcxCfg->tcx_mdct_window_min_length, ( tcx_last_overlap_mode == 0 || st->hTcxCfg->tcx_last_overlap_mode == MIN_OVERLAP ) ? st->hTcxCfg->tcx_last_overlap_mode : tcx_last_overlap_mode ); + tcx_windowing_synthesis_past_frame_flt( st->hTcxEnc->Txnq_flt, st->hTcxCfg->tcx_aldo_window_1_trunc_flt, st->hTcxCfg->tcx_mdct_window_half_flt, st->hTcxCfg->tcx_mdct_window_minimum_flt, overlap, st->hTcxCfg->tcx_mdct_window_half_length, st->hTcxCfg->tcx_mdct_window_min_length, ( tcx_last_overlap_mode == 0 || st->hTcxCfg->tcx_last_overlap_mode == MIN_OVERLAP ) ? st->hTcxCfg->tcx_last_overlap_mode : tcx_last_overlap_mode ); for ( i = 0; i < overlap; i++ ) { @@ -1926,7 +1926,7 @@ void InternalTCXDecoder( mvr2r( xn_buf + L_frame - nz, st->hTcxEnc->old_out, nz + overlap ); set_zero( st->hTcxEnc->old_out + nz + overlap, nz ); - tcx_windowing_synthesis_past_frame( st->hTcxEnc->old_out + nz, st->hTcxCfg->tcx_aldo_window_1_trunc_flt, st->hTcxCfg->tcx_mdct_window_half_flt, st->hTcxCfg->tcx_mdct_window_minimum_flt, overlap, st->hTcxCfg->tcx_mdct_window_half_length, st->hTcxCfg->tcx_mdct_window_min_length, st->hTcxCfg->tcx_curr_overlap_mode ); + tcx_windowing_synthesis_past_frame_flt( st->hTcxEnc->old_out + nz, st->hTcxCfg->tcx_aldo_window_1_trunc_flt, st->hTcxCfg->tcx_mdct_window_half_flt, st->hTcxCfg->tcx_mdct_window_minimum_flt, overlap, st->hTcxCfg->tcx_mdct_window_half_length, st->hTcxCfg->tcx_mdct_window_min_length, st->hTcxCfg->tcx_curr_overlap_mode ); if ( st->hTcxCfg->tcx_curr_overlap_mode == FULL_OVERLAP ) { @@ -2062,16 +2062,16 @@ void coder_tcx( if ( st->hTcxCfg->tcx_last_overlap_mode == TRANSITION_OVERLAP ) { - WindowSignal( hTcxCfg, hTcxCfg->tcx_offsetFB, hTcxCfg->tcx_last_overlap_mode, hTcxCfg->tcx_curr_overlap_mode, &left_overlap, &right_overlap, st->hTcxEnc->speech_TCX_flt, &L_frame, win, 1, 1 ); + WindowSignal_flt( hTcxCfg, hTcxCfg->tcx_offsetFB, hTcxCfg->tcx_last_overlap_mode, hTcxCfg->tcx_curr_overlap_mode, &left_overlap, &right_overlap, st->hTcxEnc->speech_TCX_flt, &L_frame, win, 1, 1 ); /* Compute MDCT for xn_buf[] */ - TCX_MDCT( win, spectrum, left_overlap, L_frame - ( left_overlap + right_overlap ) / 2, right_overlap, st->element_mode ); + TCX_MDCT_flt( win, spectrum, left_overlap, L_frame - ( left_overlap + right_overlap ) / 2, right_overlap, st->element_mode ); } else { wtda( st->hTcxEnc->new_speech_TCX_flt, win, NULL, hTcxCfg->tcx_last_overlap_mode, hTcxCfg->tcx_curr_overlap_mode, L_frame ); - WindowSignal( hTcxCfg, hTcxCfg->tcx_offsetFB, hTcxCfg->tcx_last_overlap_mode == ALDO_WINDOW ? FULL_OVERLAP : hTcxCfg->tcx_last_overlap_mode, hTcxCfg->tcx_curr_overlap_mode == ALDO_WINDOW ? FULL_OVERLAP : hTcxCfg->tcx_curr_overlap_mode, &left_overlap, &right_overlap, st->hTcxEnc->speech_TCX_flt, &L_frame, winMDST, 1, 1 ); + WindowSignal_flt( hTcxCfg, hTcxCfg->tcx_offsetFB, hTcxCfg->tcx_last_overlap_mode == ALDO_WINDOW ? FULL_OVERLAP : hTcxCfg->tcx_last_overlap_mode, hTcxCfg->tcx_curr_overlap_mode == ALDO_WINDOW ? FULL_OVERLAP : hTcxCfg->tcx_curr_overlap_mode, &left_overlap, &right_overlap, st->hTcxEnc->speech_TCX_flt, &L_frame, winMDST, 1, 1 ); edct( win, spectrum, L_frame, st->element_mode ); @@ -2098,7 +2098,7 @@ void coder_tcx( if ( hTcxCfg->fIsTNSAllowed ) { - SetTnsConfig( hTcxCfg, L_frame_glob == st->L_frame, st->last_core == ACELP_CORE ); + SetTnsConfig_flt( hTcxCfg, L_frame_glob == st->L_frame, st->last_core == ACELP_CORE ); TNSAnalysis( hTcxCfg, L_frame, L_spec, TCX_20, st->last_core == ACELP_CORE, spectrum, NULL, -1, hTcxEnc->tnsData, hTcxEnc->fUseTns, &st->hIGFEnc->tns_predictionGain_flt); } diff --git a/lib_enc/core_enc_init.c b/lib_enc/core_enc_init.c index d41dc89474ea12994f8798a895d743d0e2cb5858..16d158bea3b0a13b7df5cc57e6a5833e1be54fe6 100644 --- a/lib_enc/core_enc_init.c +++ b/lib_enc/core_enc_init.c @@ -69,10 +69,10 @@ void init_coder_ace_plus( int16_t L_subfr; /* Bitrate */ - st->tcxonly = getTcxonly( st->element_mode, st->total_brate, MCT_flag, st->is_ism_format ); + st->tcxonly = getTcxonly_ivas( st->element_mode, st->total_brate, MCT_flag, st->is_ism_format ); /* Core Sampling Rate */ - st->sr_core = getCoreSamplerateMode2( st->element_mode, st->total_brate, st->bwidth, st->flag_ACELP16k, st->rf_mode, st->is_ism_format ); + st->sr_core = getCoreSamplerateMode2_flt( st->element_mode, st->total_brate, st->bwidth, st->flag_ACELP16k, st->rf_mode, st->is_ism_format ); st->fscale = sr2fscale( st->sr_core ); /* Narrowband? */ @@ -560,7 +560,7 @@ static void init_acelp( st->rate_switching_reset = 1; if ( hLPDmem != NULL ) { - hLPDmem->tilt_code_flt = TILT_CODE; + hLPDmem->tilt_code_flt = TILT_CODE_FLT; set_zero( hLPDmem->old_exc_flt, L_EXC_MEM ); set_zero( hLPDmem->syn_flt, 1 + M ); hLPDmem->mem_w0_flt = 0.0f; @@ -630,7 +630,7 @@ static void init_acelp( /*reset partly some memories*/ if ( hLPDmem != NULL ) { - hLPDmem->tilt_code_flt = TILT_CODE; + hLPDmem->tilt_code_flt = TILT_CODE_FLT; set_zero( hLPDmem->old_exc_flt, L_EXC_MEM ); /*Resamp others memories*/ diff --git a/lib_enc/core_enc_ol.c b/lib_enc/core_enc_ol.c index 4d9de5fa62cafbe0fd1a4452725acc2de2d8bd67..88824218a87802b29dc46cd4aecf0d9727d846ae 100644 --- a/lib_enc/core_enc_ol.c +++ b/lib_enc/core_enc_ol.c @@ -503,10 +503,10 @@ void core_encode_openloop( v_sub( lsf_uq_rf, lsf_q_1st_rf, lsf_q_d_rf, M ); /* second stage vq */ - closest_centroid_rf( lsf_q_d_rf, w_rf, lsf_q_diff_cb_8b_rf, ( 1 << 8 ), M, &hRF->rf_indx_lsf[0][1] ); + closest_centroid_rf( lsf_q_d_rf, w_rf, lsf_q_diff_cb_8b_rf_flt, ( 1 << 8 ), M, &hRF->rf_indx_lsf[0][1] ); /* quantized lsf from two stages */ - v_add( lsf_q_1st_rf, lsf_q_diff_cb_8b_rf + M * hRF->rf_indx_lsf[0][1], lsf_q_rf, M ); + v_add( lsf_q_1st_rf, lsf_q_diff_cb_8b_rf_flt + M * hRF->rf_indx_lsf[0][1], lsf_q_rf, M ); v_sort_float( lsf_q_rf, 0, M - 1 ); reorder_lsf( lsf_q_rf, LSF_GAP, M, st->sr_core ); @@ -782,7 +782,7 @@ void core_acelp_tcx20_switching( xn_buf[L_frame + i] *= st->hTcxCfg->tcx_mdct_window_flt[overlap - 1 - i]; } - TCX_MDCT( xn_buf, x, overlap, L_frame - overlap, overlap, st->element_mode ); + TCX_MDCT_flt( xn_buf, x, overlap, L_frame - overlap, overlap, st->element_mode ); for ( i = 0; i < L_frame; i++ ) { @@ -791,7 +791,7 @@ void core_acelp_tcx20_switching( weight_a( A_q_tcx, Ap, st->gamma_flt, M ); - lpc2mdct( Ap, M, gainlpc, FDNS_NPTS, 0 ); + lpc2mdct_flt( Ap, M, gainlpc, FDNS_NPTS, 0 ); mdct_preShaping( x, L_frame, gainlpc ); diff --git a/lib_enc/core_enc_reconf.c b/lib_enc/core_enc_reconf.c index 87cfe57898a707a1a1f3849e2279da669719ccbe..71412af247ad80d520a438172138979b6795ee30 100644 --- a/lib_enc/core_enc_reconf.c +++ b/lib_enc/core_enc_reconf.c @@ -55,7 +55,7 @@ void core_coder_reconfig( int16_t bwidth, i, index; /*Configuration of ACELP*/ - BITS_ALLOC_init_config_acelp( st->total_brate, st->narrowBand, st->nb_subfr, &( st->acelp_cfg ) ); + BITS_ALLOC_init_config_acelp_IVAS( st->total_brate, st->narrowBand, st->nb_subfr, &( st->acelp_cfg ) ); /*Configuration of partial copy*/ if ( st->Opt_RF_ON ) diff --git a/lib_enc/core_enc_switch.c b/lib_enc/core_enc_switch.c index e446ee8e211a1085f8ae6da73ea5d1cd82883d71..280e5d815a855ab55b8db60349cdf9e67e5c0bc2 100644 --- a/lib_enc/core_enc_switch.c +++ b/lib_enc/core_enc_switch.c @@ -66,7 +66,7 @@ void core_coder_mode_switch( } /* force active frame for the first frame when switching from high bitrates when DTX is enabled*/ - sr_core = getCoreSamplerateMode2( st->element_mode, st->total_brate, st->bwidth, st->flag_ACELP16k, st->rf_mode, st->is_ism_format ); + sr_core = getCoreSamplerateMode2_flt( st->element_mode, st->total_brate, st->bwidth, st->flag_ACELP16k, st->rf_mode, st->is_ism_format ); fscale = sr2fscale( sr_core ); @@ -76,7 +76,7 @@ void core_coder_mode_switch( switchWB = 1; /*force init when coming from MODE1*/ } - tcxonly_tmp = getTcxonly( st->element_mode, st->total_brate, MCT_flag, st->is_ism_format ); + tcxonly_tmp = getTcxonly_ivas( st->element_mode, st->total_brate, MCT_flag, st->is_ism_format ); if ( tcxonly_tmp != st->tcxonly ) { @@ -88,7 +88,7 @@ void core_coder_mode_switch( st->sr_core = sr_core; st->L_frame = (int16_t) ( sr_core / FRAMES_PER_SEC ); - st->tcxonly = getTcxonly( st->element_mode, st->total_brate, MCT_flag, st->is_ism_format ); + st->tcxonly = getTcxonly_ivas( st->element_mode, st->total_brate, MCT_flag, st->is_ism_format ); st->bits_frame_nominal = (int16_t) ( (float) st->L_frame / (float) st->fscale * (float) FSCALE_DENOM / 128.0f * (float) st->total_brate / 100.0f + 0.49f ); @@ -101,7 +101,7 @@ void core_coder_mode_switch( } st->hTcxCfg->tcx_coded_lines = getNumTcxCodedLines( st->bwidth ); - st->hTcxCfg->bandwidth_flt = getTcxBandwidth( st->bwidth ); + st->hTcxCfg->bandwidth_flt = getTcxBandwidth_flt( st->bwidth ); st->hTcxCfg->tcxRateLoopOpt = ( st->tcxonly ) ? 2 : 0; st->hTcxCfg->tcxRateLoopOpt = ( st->element_mode == IVAS_CPE_MDCT ) ? 3 : st->hTcxCfg->tcxRateLoopOpt; st->hTcxCfg->ctx_hm = getCtxHm( st->element_mode, st->total_brate, st->rf_mode ); @@ -113,9 +113,9 @@ void core_coder_mode_switch( if ( st->hTcxCfg->fIsTNSAllowed ) { - InitTnsConfigs( st->bwidth, st->hTcxCfg->tcx_coded_lines, st->hTcxCfg->tnsConfig, st->hIGFEnc->infoStopFrequency, st->total_brate, st->element_mode, MCT_flag ); + InitTnsConfigs_flt( st->bwidth, st->hTcxCfg->tcx_coded_lines, st->hTcxCfg->tnsConfig, st->hIGFEnc->infoStopFrequency, st->total_brate, st->element_mode, MCT_flag ); - SetAllowTnsOnWhite( st->hTcxCfg->tnsConfig, st->element_mode == IVAS_CPE_MDCT ); + SetAllowTnsOnWhite_flt( st->hTcxCfg->tnsConfig, st->element_mode == IVAS_CPE_MDCT ); } if ( st->bwidth == NB ) diff --git a/lib_enc/core_enc_updt.c b/lib_enc/core_enc_updt.c index 4b94705998975fd884018d0a13287f83137df740..cb0caf7aa81ba27df19b241862a1a55bef5f2c26 100644 --- a/lib_enc/core_enc_updt.c +++ b/lib_enc/core_enc_updt.c @@ -184,7 +184,7 @@ void core_encode_update_cng( /* Reset acelp memories */ set_zero( hLPDmem->dispMem_flt, 8 ); - hLPDmem->tilt_code_flt = TILT_CODE; + hLPDmem->tilt_code_flt = TILT_CODE_FLT; hLPDmem->gc_threshold_flt = 0.0f; /* Update ace/tcx mode */ diff --git a/lib_enc/detect_transient_fx.c b/lib_enc/detect_transient_fx.c index bab7a501fb9d9b8f86a6548e3be46496382ccd61..6d3957921b08a763046f205188ae6f50c50a6f9f 100644 --- a/lib_enc/detect_transient_fx.c +++ b/lib_enc/detect_transient_fx.c @@ -36,7 +36,7 @@ #include #include "options.h" /* Compilation switches */ #include "cnst.h" /* Common constants */ -#include "rom_com_fx.h" /* Static table prototypes */ +#include "rom_com.h" /* Static table prototypes */ #include "prot_fx2.h" /* Function prototypes */ /*--------------------------------------------------------------------------*/ diff --git a/lib_enc/enc_acelp_tcx_main.c b/lib_enc/enc_acelp_tcx_main.c index 338d87cc699bffcefc526a4f9b7077cd0a8c4e1f..80a0f2840313a3bfce1f90b2727b233e91b612df 100644 --- a/lib_enc/enc_acelp_tcx_main.c +++ b/lib_enc/enc_acelp_tcx_main.c @@ -120,7 +120,7 @@ void enc_acelp_tcx_main( generate_comfort_noise_enc( st ); /* Update Core Encoder */ - core_encode_update_cng( st, st->hFdCngEnc->hFdCngCom->timeDomainBuffer, st->hFdCngEnc->hFdCngCom->A_cng, Aw ); + core_encode_update_cng( st, st->hFdCngEnc->hFdCngCom->timeDomainBuffer_flt, st->hFdCngEnc->hFdCngCom->A_cng_flt, Aw ); } /* coreSwitching update of Mode 1 parameters in the last frame */ diff --git a/lib_enc/enc_amr_wb.c b/lib_enc/enc_amr_wb.c index 2b78444a396b212ec5bd9cb443a3c17e00089cef..7e023b81e43536b02075efb54924746cfe486d97 100644 --- a/lib_enc/enc_amr_wb.c +++ b/lib_enc/enc_amr_wb.c @@ -154,7 +154,7 @@ void encod_amr_wb( * Find adaptive exitation *-----------------------------------------------------------------*/ - pred_lt4( &exc[i_subfr], &exc[i_subfr], T0, T0_frac, L_SUBFR + 1, inter4_2, L_INTERPOL2, PIT_UP_SAMP ); + pred_lt4_flt( &exc[i_subfr], &exc[i_subfr], T0, T0_frac, L_SUBFR + 1, inter4_2, L_INTERPOL2, PIT_UP_SAMP ); /*-----------------------------------------------------------------* * Gain clipping test to avoid unstable synthesis on frame erasure diff --git a/lib_enc/enc_gen_voic.c b/lib_enc/enc_gen_voic.c index ed4c56face6cdab05526a2b5fda5f9f6b140b058..4d051806358e58049019ff665c6c4f512315b2b0 100644 --- a/lib_enc/enc_gen_voic.c +++ b/lib_enc/enc_gen_voic.c @@ -171,7 +171,7 @@ void encod_gen_voic( * Find adaptive exitation *-----------------------------------------------------------------*/ - pred_lt4( &exc[i_subfr], &exc[i_subfr], T0, T0_frac, L_SUBFR + 1, inter4_2, L_INTERPOL2, PIT_UP_SAMP ); + pred_lt4_flt( &exc[i_subfr], &exc[i_subfr], T0, T0_frac, L_SUBFR + 1, inter4_2, L_INTERPOL2, PIT_UP_SAMP ); /*-----------------------------------------------------------------* * Gain clipping test to avoid unstable synthesis on frame erasure diff --git a/lib_enc/enc_gen_voic_rf.c b/lib_enc/enc_gen_voic_rf.c index 8df1450e5746ce195b4e2e9d78ff636fc9a40761..f5be07e787bb36842886915e0ad31ef655f40cc4 100644 --- a/lib_enc/enc_gen_voic_rf.c +++ b/lib_enc/enc_gen_voic_rf.c @@ -40,6 +40,7 @@ #include "prot.h" #include "rom_com.h" #include "wmc_auto.h" +#include "prot_fx2.h" /*-------------------------------------------------------------------* * reset_rf_indices() @@ -263,11 +264,11 @@ void coder_acelp_rf( /* find ACB excitation */ if ( T0_res == ( st->pit_res_max >> 1 ) ) /* st->pit_res_max is 4 for 12.8kHz core */ { - pred_lt4( &exc_rf[i_subfr], &exc_rf[i_subfr], T0, T0_frac << 1, L_SUBFR + 1, inter4_2, L_INTERPOL2, PIT_UP_SAMP ); + pred_lt4_flt( &exc_rf[i_subfr], &exc_rf[i_subfr], T0, T0_frac << 1, L_SUBFR + 1, inter4_2, L_INTERPOL2, PIT_UP_SAMP ); } else { - pred_lt4( &exc_rf[i_subfr], &exc_rf[i_subfr], T0, T0_frac, L_SUBFR + 1, inter4_2, L_INTERPOL2, PIT_UP_SAMP ); + pred_lt4_flt( &exc_rf[i_subfr], &exc_rf[i_subfr], T0, T0_frac, L_SUBFR + 1, inter4_2, L_INTERPOL2, PIT_UP_SAMP ); } diff --git a/lib_enc/enc_pit_exc.c b/lib_enc/enc_pit_exc.c index 8decea877eef021dc30b8e02dca7bc1fc2852ecc..e85da412b2bf8a70feaf8f3c12e2857e2f020344 100644 --- a/lib_enc/enc_pit_exc.c +++ b/lib_enc/enc_pit_exc.c @@ -204,7 +204,7 @@ void enc_pit_exc( * Find adaptive exitation *-----------------------------------------------------------------*/ - pred_lt4( &exc[i_subfr], &exc[i_subfr], *T0, *T0_frac, L_subfr + 1, inter4_2, L_INTERPOL2, PIT_UP_SAMP ); + pred_lt4_flt( &exc[i_subfr], &exc[i_subfr], *T0, *T0_frac, L_subfr + 1, inter4_2, L_INTERPOL2, PIT_UP_SAMP ); /*-----------------------------------------------------------------* * Gain clipping test to avoid unstable synthesis on frame erasure diff --git a/lib_enc/enc_prm.c b/lib_enc/enc_prm.c index 92dc8268b9cd746cf7a735f527fe0304275f49ff..279c4c0d885621fc8258a4089ce26e1488b847a2 100644 --- a/lib_enc/enc_prm.c +++ b/lib_enc/enc_prm.c @@ -441,7 +441,7 @@ void writeTCXparam( if ( st->hTcxCfg->fIsTNSAllowed ) { - SetTnsConfig( st->hTcxCfg, core == TCX_20_CORE, ( last_core == ACELP_CORE ) && ( k == 0 ) ); + SetTnsConfig_flt( st->hTcxCfg, core == TCX_20_CORE, ( last_core == ACELP_CORE ) && ( k == 0 ) ); if ( no_param_tns ) { diff --git a/lib_enc/evs_enc.c b/lib_enc/evs_enc.c index 40ed558c60d7c5930a51d3ddca1b8fb28b8f07b5..95ce15b38b3a624bf5aedb7456d6273262a53087 100644 --- a/lib_enc/evs_enc.c +++ b/lib_enc/evs_enc.c @@ -119,7 +119,7 @@ ivas_error evs_enc( st->rate_switching_reset = 0; st->idchan = 0; - st->flag_ACELP16k = set_ACELP_flag( EVS_MONO, -1, st->total_brate, 0, 0, -1, -1 ); + st->flag_ACELP16k = set_ACELP_flag_IVAS( EVS_MONO, -1, st->total_brate, 0, 0, -1, -1 ); /*----------------------------------------------------------------* * set input samples buffer @@ -157,8 +157,8 @@ ivas_error evs_enc( if ( st->last_core == AMR_WB_CORE ) { updt_IO_switch_enc( st, input_frame ); - cldfb_reset_memory( st->cldfbAnaEnc ); - cldfb_reset_memory( st->cldfbSynTd ); + cldfb_reset_memory_ivas( st->cldfbAnaEnc ); + cldfb_reset_memory_ivas( st->cldfbSynTd ); } /*---------------------------------------------------------------------* diff --git a/lib_enc/ext_sig_ana.c b/lib_enc/ext_sig_ana.c index 4812ec243bc4ebe286973372ad10fade46176ef0..217b431d59aa990f5162392deadd7b5d50f2e7a3 100644 --- a/lib_enc/ext_sig_ana.c +++ b/lib_enc/ext_sig_ana.c @@ -220,13 +220,13 @@ void core_signal_analysis_high_bitrate( if ( st->element_mode != IVAS_CPE_MDCT ) { /* Windowing of the 2xTCX5 subframes or 1xTCX10 or 1xTCX20 */ - WindowSignal( st->hTcxCfg, st->hTcxCfg->tcx_offsetFB, overlap_mode[frameno] == ALDO_WINDOW ? FULL_OVERLAP : overlap_mode[frameno], overlap_mode[frameno + 1] == ALDO_WINDOW ? FULL_OVERLAP : overlap_mode[frameno + 1], &left_overlap, &right_overlap, &hTcxEnc->speech_TCX_flt[frameno * tcx10SizeFB], &L_subframe, mdstWin, 1, 1 ); + WindowSignal_flt( st->hTcxCfg, st->hTcxCfg->tcx_offsetFB, overlap_mode[frameno] == ALDO_WINDOW ? FULL_OVERLAP : overlap_mode[frameno], overlap_mode[frameno + 1] == ALDO_WINDOW ? FULL_OVERLAP : overlap_mode[frameno + 1], &left_overlap, &right_overlap, &hTcxEnc->speech_TCX_flt[frameno * tcx10SizeFB], &L_subframe, mdstWin, 1, 1 ); } } else { /* Windowing of the 2xTCX5 subframes or 1xTCX10 or 1xTCX20 */ - WindowSignal( st->hTcxCfg, st->hTcxCfg->tcx_offsetFB, overlap_mode[frameno], overlap_mode[frameno + 1], &left_overlap, &right_overlap, &hTcxEnc->speech_TCX_flt[frameno * tcx10SizeFB], &L_subframe, tcx20Win, st->element_mode != IVAS_CPE_MDCT, 1 ); + WindowSignal_flt( st->hTcxCfg, st->hTcxCfg->tcx_offsetFB, overlap_mode[frameno], overlap_mode[frameno + 1], &left_overlap, &right_overlap, &hTcxEnc->speech_TCX_flt[frameno * tcx10SizeFB], &L_subframe, tcx20Win, st->element_mode != IVAS_CPE_MDCT, 1 ); if ( windowed_samples != NULL ) /* save windowed speech_TCX_flt samples */ { @@ -265,9 +265,9 @@ void core_signal_analysis_high_bitrate( for ( i = 0; i < 2; i++ ) { - WindowSignal( st->hTcxCfg, folding_offset, i == 0 ? RECTANGULAR_OVERLAP : MIN_OVERLAP, i == 1 ? RECTANGULAR_OVERLAP : MIN_OVERLAP, &left_overlap, &right_overlap, tcx20Win + i * tcx5SizeFB, &L_subframe, tcx5Win, st->element_mode != IVAS_CPE_MDCT, 1 ); + WindowSignal_flt( st->hTcxCfg, folding_offset, i == 0 ? RECTANGULAR_OVERLAP : MIN_OVERLAP, i == 1 ? RECTANGULAR_OVERLAP : MIN_OVERLAP, &left_overlap, &right_overlap, tcx20Win + i * tcx5SizeFB, &L_subframe, tcx5Win, st->element_mode != IVAS_CPE_MDCT, 1 ); - TCX_MDCT( tcx5Win, hTcxEnc->spectrum[frameno] + i * tcx5SizeFB, left_overlap, L_subframe - ( left_overlap + right_overlap ) / 2, right_overlap, st->element_mode ); + TCX_MDCT_flt( tcx5Win, hTcxEnc->spectrum[frameno] + i * tcx5SizeFB, left_overlap, L_subframe - ( left_overlap + right_overlap ) / 2, right_overlap, st->element_mode ); /* high-band gain control in case of BWS */ if ( st->bwidth_sw_cnt > 0 ) @@ -297,7 +297,7 @@ void core_signal_analysis_high_bitrate( } } - TCX_MDCT( tcx20Win, hTcxEnc->spectrum[frameno], left_overlap, L_subframe - ( left_overlap + right_overlap ) / 2, right_overlap, st->element_mode ); + TCX_MDCT_flt( tcx20Win, hTcxEnc->spectrum[frameno], left_overlap, L_subframe - ( left_overlap + right_overlap ) / 2, right_overlap, st->element_mode ); } /* high-band gain control in case of BWS */ @@ -328,7 +328,7 @@ void core_signal_analysis_high_bitrate( else { /* Windowing for the MDST */ - WindowSignal( st->hTcxCfg, st->hTcxCfg->tcx_offsetFB, overlap_mode[frameno] == ALDO_WINDOW ? FULL_OVERLAP : overlap_mode[frameno], overlap_mode[frameno + 1] == ALDO_WINDOW ? FULL_OVERLAP : overlap_mode[frameno + 1], &left_overlap, &right_overlap, &hTcxEnc->speech_TCX_flt[frameno * tcx10SizeFB], &L_subframe, mdstWin, 0, 1 ); + WindowSignal_flt( st->hTcxCfg, st->hTcxCfg->tcx_offsetFB, overlap_mode[frameno] == ALDO_WINDOW ? FULL_OVERLAP : overlap_mode[frameno], overlap_mode[frameno + 1] == ALDO_WINDOW ? FULL_OVERLAP : overlap_mode[frameno + 1], &left_overlap, &right_overlap, &hTcxEnc->speech_TCX_flt[frameno * tcx10SizeFB], &L_subframe, mdstWin, 0, 1 ); } if ( transform_type[frameno] == TCX_5 ) @@ -359,9 +359,9 @@ void core_signal_analysis_high_bitrate( for ( i = 0; i < 2; i++ ) { - WindowSignal( st->hTcxCfg, folding_offset, i == 0 ? RECTANGULAR_OVERLAP : MIN_OVERLAP, i == 1 ? RECTANGULAR_OVERLAP : MIN_OVERLAP, &left_overlap, &right_overlap, mdstWin + i * tcx5SizeFB, &L_subframe, tcx5Win, 0, 1 ); + WindowSignal_flt( st->hTcxCfg, folding_offset, i == 0 ? RECTANGULAR_OVERLAP : MIN_OVERLAP, i == 1 ? RECTANGULAR_OVERLAP : MIN_OVERLAP, &left_overlap, &right_overlap, mdstWin + i * tcx5SizeFB, &L_subframe, tcx5Win, 0, 1 ); - TCX_MDST( tcx5Win, mdst_spectrum[frameno] + i * tcx5SizeFB, left_overlap, L_subframe - ( left_overlap + right_overlap ) / 2, right_overlap, st->element_mode ); + TCX_MDST_flt( tcx5Win, mdst_spectrum[frameno] + i * tcx5SizeFB, left_overlap, L_subframe - ( left_overlap + right_overlap ) / 2, right_overlap, st->element_mode ); /* high-band gain control in case of BWS */ if ( st->bwidth_sw_cnt > 0 ) { @@ -387,7 +387,7 @@ void core_signal_analysis_high_bitrate( } } - TCX_MDST( mdstWin, mdst_spectrum[frameno], left_overlap, L_subframe - ( left_overlap + right_overlap ) / 2, right_overlap, st->element_mode ); + TCX_MDST_flt( mdstWin, mdst_spectrum[frameno], left_overlap, L_subframe - ( left_overlap + right_overlap ) / 2, right_overlap, st->element_mode ); } /* high-band gain control in case of BWS */ diff --git a/lib_enc/fd_cng_enc.c b/lib_enc/fd_cng_enc.c index 214a15cf0c38486af417d95ed8cfb929669533dc..e6a2d155387c16c488868264e6f89fd06619a5ae 100644 --- a/lib_enc/fd_cng_enc.c +++ b/lib_enc/fd_cng_enc.c @@ -68,7 +68,7 @@ ivas_error createFdCngEnc( return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for FD CNG ENC structure" ); } - if ( ( error = createFdCngCom( &( hs->hFdCngCom ) ) ) != IVAS_ERR_OK ) + if ( ( error = createFdCngCom_flt( &( hs->hFdCngCom ) ) ) != IVAS_ERR_OK ) { return error; } @@ -94,7 +94,7 @@ void initFdCngEnc( HANDLE_FD_CNG_COM hsCom = hFdCngEnc->hFdCngCom; /* Initialize common */ - initFdCngCom( hsCom, scale ); + initFdCngCom_flt( hsCom, scale ); /* Configure the Noise Estimator */ hsCom->numSlots = 16; @@ -119,13 +119,13 @@ void initFdCngEnc( hsCom->nFFTpart = 20; } - initPartitions( sidparts_encoder_noise_est, SIZE_SIDPARTS_ENC_NOISE_EST, hsCom->startBand, hsCom->stopBand, hsCom->part, &hsCom->npart, hsCom->midband, hsCom->psize, hsCom->psize_inv, 0 ); + initPartitions_flt( sidparts_encoder_noise_est, SIZE_SIDPARTS_ENC_NOISE_EST, hsCom->startBand, hsCom->stopBand, hsCom->part, &hsCom->npart, hsCom->midband, hsCom->psize_flt, hsCom->psize_inv_flt, 0 ); hsCom->nCLDFBpart = hsCom->npart - hsCom->nFFTpart; for ( j = 0; j < hsCom->nCLDFBpart; j++ ) { hsCom->CLDFBpart[j] = hsCom->part[j + hsCom->nFFTpart] - ( 256 - hsCom->startBand ); - hsCom->CLDFBpsize_inv[j] = hsCom->psize_inv[j + hsCom->nFFTpart]; + hsCom->CLDFBpsize_inv_flt[j] = hsCom->psize_inv_flt[j + hsCom->nFFTpart]; } /* Initialize the Noise Estimator */ @@ -225,7 +225,7 @@ void configureFdCngEnc( hFdCngEnc->startBandDec = hsCom->startBand; hFdCngEnc->stopBandDec = hsCom->FdCngSetup.sidPartitions[hsCom->FdCngSetup.numPartitions - 1] + 1; - initPartitions( hsCom->FdCngSetup.sidPartitions, hsCom->FdCngSetup.numPartitions, hFdCngEnc->startBandDec, hFdCngEnc->stopBandDec, hFdCngEnc->partDec, &hFdCngEnc->npartDec, hFdCngEnc->midbandDec, psizeDec, psize_invDec, 0 ); + initPartitions_flt( hsCom->FdCngSetup.sidPartitions, hsCom->FdCngSetup.numPartitions, hFdCngEnc->startBandDec, hFdCngEnc->stopBandDec, hFdCngEnc->partDec, &hFdCngEnc->npartDec, hFdCngEnc->midbandDec, psizeDec, psize_invDec, 0 ); if ( hFdCngEnc->stopFFTbinDec == 160 ) { @@ -243,14 +243,14 @@ void configureFdCngEnc( switch ( hsCom->fftlen ) { case 512: - hsCom->fftSineTab = NULL; - hsCom->olapWinAna = olapWinAna512; - hsCom->olapWinSyn = olapWinSyn256; + hsCom->fftSineTab_flt = NULL; + hsCom->olapWinAna_flt = olapWinAna512; + hsCom->olapWinSyn_flt = olapWinSyn256; break; case 640: - hsCom->fftSineTab = fftSineTab640; - hsCom->olapWinAna = olapWinAna640; - hsCom->olapWinSyn = olapWinSyn320; + hsCom->fftSineTab_flt = fftSineTab640; + hsCom->olapWinAna_flt = olapWinAna640; + hsCom->olapWinSyn_flt = olapWinSyn320; break; default: assert( !"Unsupported FFT length for FD-based CNG" ); @@ -277,7 +277,7 @@ void deleteFdCngEnc( if ( hsEnc != NULL ) { - deleteFdCngCom( &( hsEnc->hFdCngCom ) ); + deleteFdCngCom_flt( &( hsEnc->hFdCngCom ) ); free( hsEnc ); *hFdCngEnc = NULL; } @@ -335,7 +335,7 @@ void resetFdCngEnc( { st->fd_cng_reset_flag = 1; st->hFdCngEnc->hFdCngCom->msFrCnt_init_counter = 0; - st->hFdCngEnc->hFdCngCom->init_old = FLT_MAX; + st->hFdCngEnc->hFdCngCom->init_old_flt = FLT_MAX; } else if ( st->fd_cng_reset_flag > 0 && st->fd_cng_reset_flag < 10 ) { @@ -369,11 +369,11 @@ void perform_noise_estimation_enc( int16_t regularStopBand = hFdCngEnc->hFdCngCom->regularStopBand; int16_t numSlots = hFdCngEnc->hFdCngCom->numSlots; float numSlots_inv = 1.f / (float) numSlots; /*enough if done only once*/ - float *periodog = hFdCngEnc->hFdCngCom->periodog; - float *ptr_per = periodog; + float *periodog_flt = hFdCngEnc->hFdCngCom->periodog_flt; + float *ptr_per = periodog_flt; int16_t npart = hFdCngEnc->hFdCngCom->npart; int16_t nFFTpart = hFdCngEnc->hFdCngCom->nFFTpart; - float *psize = hFdCngEnc->hFdCngCom->psize; + float *psize_flt = hFdCngEnc->hFdCngCom->psize_flt; float *msPeriodog = hFdCngEnc->msPeriodog; float *msNoiseEst = hFdCngEnc->msNoiseEst; @@ -398,7 +398,7 @@ void perform_noise_estimation_enc( } else { - scaleEB = numSlots_inv * hFdCngEnc->hFdCngCom->scalingFactor; + scaleEB = numSlots_inv * hFdCngEnc->hFdCngCom->scalingFactor_flt; } /* preemphasis compensation and grouping of per bin energies into msPeriodog */ @@ -418,18 +418,18 @@ void perform_noise_estimation_enc( /* Adjust filterbank to the desired frequency resolution by averaging over spectral partitions for SID transmission */ if ( numCoreBands < regularStopBand ) { - bandcombinepow( periodog, regularStopBand - numCoreBands, hFdCngEnc->hFdCngCom->CLDFBpart, hFdCngEnc->hFdCngCom->nCLDFBpart, hFdCngEnc->hFdCngCom->CLDFBpsize_inv, &msPeriodog[nFFTpart] ); + bandcombinepow_flt( periodog_flt, regularStopBand - numCoreBands, hFdCngEnc->hFdCngCom->CLDFBpart, hFdCngEnc->hFdCngCom->nCLDFBpart, hFdCngEnc->hFdCngCom->CLDFBpsize_inv_flt, &msPeriodog[nFFTpart] ); } /* Compress MS inputs */ - compress_range( msPeriodog, msLogPeriodog, npart ); + compress_range_flt( msPeriodog, msLogPeriodog, npart ); /* Call the minimum statistics routine for noise estimation */ - minimum_statistics( npart, nFFTpart, psize, msLogPeriodog, hFdCngEnc->msNoiseFloor, msLogNoiseEst, hFdCngEnc->msAlpha, hFdCngEnc->msPsd, hFdCngEnc->msPsdFirstMoment, hFdCngEnc->msPsdSecondMoment, hFdCngEnc->msMinBuf, hFdCngEnc->msBminWin, hFdCngEnc->msBminSubWin, hFdCngEnc->msCurrentMin, hFdCngEnc->msCurrentMinOut, hFdCngEnc->msCurrentMinSubWindow, hFdCngEnc->msLocalMinFlag, hFdCngEnc->msNewMinFlag, hFdCngEnc->msPeriodogBuf, &( hFdCngEnc->msPeriodogBufPtr ), hFdCngEnc->hFdCngCom, + minimum_statistics_flt( npart, nFFTpart, psize_flt, msLogPeriodog, hFdCngEnc->msNoiseFloor, msLogNoiseEst, hFdCngEnc->msAlpha, hFdCngEnc->msPsd, hFdCngEnc->msPsdFirstMoment, hFdCngEnc->msPsdSecondMoment, hFdCngEnc->msMinBuf, hFdCngEnc->msBminWin, hFdCngEnc->msBminSubWin, hFdCngEnc->msCurrentMin, hFdCngEnc->msCurrentMinOut, hFdCngEnc->msCurrentMinSubWindow, hFdCngEnc->msLocalMinFlag, hFdCngEnc->msNewMinFlag, hFdCngEnc->msPeriodogBuf, &( hFdCngEnc->msPeriodogBufPtr ), hFdCngEnc->hFdCngCom, ENC, ( hCPE == NULL ) ? 0 : hCPE->element_mode ); /* Expand MS outputs */ - expand_range( msLogNoiseEst, msNoiseEst, npart ); + expand_range_flt( msLogNoiseEst, msNoiseEst, npart ); return; } @@ -569,8 +569,8 @@ void FdCng_encodeSID( } else { /* EVS_MONO tables */ - msvq_enc( cdk_37bits, NULL, NULL, v, levels_37bits, FD_CNG_maxC_37bits, FD_CNG_stages_37bits, w, N, FD_CNG_maxN_37bits, 0, NULL, indices ); - msvq_dec_float( cdk_37bits, NULL, NULL, FD_CNG_stages_37bits, N, FD_CNG_maxN_37bits, indices, 0, NULL, v, NULL ); + msvq_enc(cdk_37bits_flt, NULL, NULL, v, levels_37bits, FD_CNG_maxC_37bits, FD_CNG_stages_37bits, w, N, FD_CNG_maxN_37bits, 0, NULL, indices ); + msvq_dec_float(cdk_37bits_flt, NULL, NULL, FD_CNG_stages_37bits, N, FD_CNG_maxN_37bits, indices, 0, NULL, v, NULL ); } @@ -586,11 +586,11 @@ void FdCng_encodeSID( /* Apply bitrate-dependant scale */ if ( st->element_mode > EVS_MONO ) { - apply_scale( &gain, hFdCngCom->CngBandwidth, hFdCngCom->CngBitrate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO ); + apply_scale_flt( &gain, hFdCngCom->CngBandwidth, hFdCngCom->CngBitrate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO ); } else { - apply_scale( &gain, hFdCngCom->CngBandwidth, hFdCngCom->CngBitrate, scaleTableMono, SIZE_SCALE_TABLE_MONO ); + apply_scale_flt( &gain, hFdCngCom->CngBandwidth, hFdCngCom->CngBitrate, scaleTableMono, SIZE_SCALE_TABLE_MONO ); } /* Quantize gain */ @@ -612,18 +612,18 @@ void FdCng_encodeSID( for ( i = 0; i < N; i++ ) { - hFdCngCom->sidNoiseEst[i] = (float) pow( 10.f, ( v[i] + gain ) / 10.f ); + hFdCngCom->sidNoiseEst_flt[i] = (float) pow( 10.f, ( v[i] + gain ) / 10.f ); } /* NB last band energy compensation */ if ( hFdCngCom->CngBandwidth == NB ) { - hFdCngCom->sidNoiseEst[N - 1] *= NB_LAST_BAND_SCALE_FLT; + hFdCngCom->sidNoiseEst_flt[N - 1] *= NB_LAST_BAND_SCALE_FLT; } if ( hFdCngCom->CngBandwidth == SWB && hFdCngCom->CngBitrate <= ACELP_13k20 ) { - hFdCngCom->sidNoiseEst[N - 1] *= SWB_13k2_LAST_BAND_SCALE_FLT; + hFdCngCom->sidNoiseEst_flt[N - 1] *= SWB_13k2_LAST_BAND_SCALE_FLT; } /* Write bitstream */ @@ -651,9 +651,9 @@ void FdCng_encodeSID( } /* Interpolate the bin/band-wise levels from the partition levels */ - scalebands( hFdCngCom->sidNoiseEst, hFdCngEnc->partDec, hFdCngEnc->npartDec, hFdCngEnc->midbandDec, hFdCngEnc->nFFTpartDec, hFdCngEnc->stopBandDec - hFdCngEnc->startBandDec, hFdCngCom->cngNoiseLevel, 1 ); + scalebands_flt( hFdCngCom->sidNoiseEst_flt, hFdCngEnc->partDec, hFdCngEnc->npartDec, hFdCngEnc->midbandDec, hFdCngEnc->nFFTpartDec, hFdCngEnc->stopBandDec - hFdCngEnc->startBandDec, hFdCngCom->cngNoiseLevel_flt, 1 ); - lpc_from_spectrum( hFdCngCom, hFdCngEnc->startBandDec, hFdCngEnc->stopFFTbinDec, preemph_fac ); + lpc_from_spectrum_flt( hFdCngCom, hFdCngEnc->startBandDec, hFdCngEnc->stopFFTbinDec, preemph_fac ); return; } @@ -674,21 +674,21 @@ void generate_comfort_noise_enc( float *ptr_i; HANDLE_FD_CNG_ENC hFdCngEnc = st->hFdCngEnc; HANDLE_FD_CNG_COM hFdCngCom = hFdCngEnc->hFdCngCom; - float *cngNoiseLevel = hFdCngCom->cngNoiseLevel; - float *ptr_level = cngNoiseLevel; + float *cngNoiseLevel_flt = hFdCngCom->cngNoiseLevel_flt; + float *ptr_level = cngNoiseLevel_flt; int16_t *seed = &( hFdCngCom->seed ); float scale = 1.f; - float *fftBuffer = hFdCngCom->fftBuffer; - float *timeDomainOutput = hFdCngCom->timeDomainBuffer; + float *fftBuffer = hFdCngCom->fftBuffer_flt; + float *timeDomainOutput = hFdCngCom->timeDomainBuffer_flt; float preemph_fac = st->preemph_fac_flt; int16_t tcx_transition = 0; float enr; /* Generate Gaussian random noise in real and imaginary parts of the FFT bins - Amplitudes are adjusted to the estimated noise level cngNoiseLevel in each bin */ + Amplitudes are adjusted to the estimated noise level cngNoiseLevel_flt in each bin */ if ( hFdCngEnc->startBandDec == 0 ) { - rand_gauss( &fftBuffer[0], seed ); + rand_gauss_flt( &fftBuffer[0], seed ); fftBuffer[0] *= (float) sqrt( scale * *ptr_level ); /* DC component in FFT */ ptr_level++; ptr_r = fftBuffer + 2; @@ -701,14 +701,14 @@ void generate_comfort_noise_enc( } ptr_i = ptr_r + 1; - for ( ; ptr_level < cngNoiseLevel + hFdCngEnc->stopFFTbinDec - hFdCngEnc->startBandDec; ptr_level++ ) + for ( ; ptr_level < cngNoiseLevel_flt + hFdCngEnc->stopFFTbinDec - hFdCngEnc->startBandDec; ptr_level++ ) { /* Real part in FFT bins */ - rand_gauss( ptr_r, seed ); + rand_gauss_flt( ptr_r, seed ); ( *ptr_r ) *= (float) sqrt( ( scale * *ptr_level ) * 0.5f ); ptr_r += 2; /* Imaginary part in FFT bins */ - rand_gauss( ptr_i, seed ); + rand_gauss_flt( ptr_i, seed ); ( *ptr_i ) *= (float) sqrt( ( scale * *ptr_level ) * 0.5f ); ptr_i += 2; } @@ -722,7 +722,7 @@ void generate_comfort_noise_enc( /* If previous frame is active, reset the overlap-add buffer */ if ( st->last_core_brate > SID_2k40 ) { - set_f( hFdCngCom->olapBufferSynth, 0.0f, hFdCngCom->fftlen ); + set_f( hFdCngCom->olapBufferSynth_flt, 0.0f, hFdCngCom->fftlen ); if ( ( st->last_core > ACELP_CORE && st->codec_mode == MODE2 ) || st->codec_mode == MODE1 ) { @@ -731,13 +731,13 @@ void generate_comfort_noise_enc( } /* Perform STFT synthesis */ - SynthesisSTFT( fftBuffer, timeDomainOutput, hFdCngCom->olapBufferSynth, hFdCngCom->olapWinSyn, tcx_transition, hFdCngCom, -1, -1 ); + SynthesisSTFT_flt( fftBuffer, timeDomainOutput, hFdCngCom->olapBufferSynth_flt, hFdCngCom->olapWinSyn_flt, tcx_transition, hFdCngCom, -1, -1 ); if ( st->hTdCngEnc != NULL ) { /* update CNG excitation energy for LP_CNG */ /* calculate the residual signal energy */ - enr = cng_energy( st->element_mode, st->bwidth, st->hDtxEnc->CNG_mode, st->hTdCngEnc->CNG_att, hFdCngCom->exc_cng, hFdCngCom->frameSize ); + enr = cng_energy( st->element_mode, st->bwidth, st->hDtxEnc->CNG_mode, st->hTdCngEnc->CNG_att, hFdCngCom->exc_cng_flt, hFdCngCom->frameSize ); st->hTdCngEnc->lp_ener = (float) ( 0.8f * st->hTdCngEnc->lp_ener + 0.2f * pow( 2.0f, enr ) ); } @@ -752,7 +752,7 @@ void generate_comfort_noise_enc( if ( st->last_core > ACELP_CORE ) { - tcx_windowing_synthesis_current_frame( timeDomainOutput, st->hTcxCfg->tcx_mdct_window_flt, /*Keep sine windows for limiting Time modulation*/ + tcx_windowing_synthesis_current_frame_flt( timeDomainOutput, st->hTcxCfg->tcx_mdct_window_flt, /*Keep sine windows for limiting Time modulation*/ st->hTcxCfg->tcx_mdct_window_half_flt, st->hTcxCfg->tcx_mdct_window_minimum_flt, st->hTcxCfg->tcx_mdct_window_length, st->hTcxCfg->tcx_mdct_window_half_length, st->hTcxCfg->tcx_mdct_window_min_length, 0, st->hTcxCfg->tcx_last_overlap_mode == ALDO_WINDOW ? FULL_OVERLAP : st->hTcxCfg->tcx_last_overlap_mode, NULL, NULL, NULL, NULL, NULL, N / 2, st->hTcxCfg->tcx_offset < 0 ? -st->hTcxCfg->tcx_offset : 0, 1, 0, 0 ); if ( st->hTcxCfg->last_aldo ) @@ -764,7 +764,7 @@ void generate_comfort_noise_enc( } else { - tcx_windowing_synthesis_past_frame( st->hTcxEnc->Txnq_flt, st->hTcxCfg->tcx_aldo_window_1_trunc_flt, st->hTcxCfg->tcx_mdct_window_half_flt, st->hTcxCfg->tcx_mdct_window_minimum_flt, st->hTcxCfg->tcx_mdct_window_length, st->hTcxCfg->tcx_mdct_window_half_length, st->hTcxCfg->tcx_mdct_window_min_length, st->hTcxCfg->tcx_last_overlap_mode ); + tcx_windowing_synthesis_past_frame_flt( st->hTcxEnc->Txnq_flt, st->hTcxCfg->tcx_aldo_window_1_trunc_flt, st->hTcxCfg->tcx_mdct_window_half_flt, st->hTcxCfg->tcx_mdct_window_minimum_flt, st->hTcxCfg->tcx_mdct_window_length, st->hTcxCfg->tcx_mdct_window_half_length, st->hTcxCfg->tcx_mdct_window_min_length, st->hTcxCfg->tcx_last_overlap_mode ); for ( i = 0; i < st->hTcxCfg->tcx_mdct_window_length; i++ ) { @@ -787,7 +787,7 @@ void generate_comfort_noise_enc( for ( i = 0; i < N; i++ ) { - rand_gauss( &( noise[i] ), &( seed_loc ) ); + rand_gauss_flt( &( noise[i] ), &( seed_loc ) ); gain += noise[i] * noise[i]; } @@ -806,7 +806,7 @@ void generate_comfort_noise_enc( for ( i = 0; i < N / 2; i++ ) { - timeDomainOutput[i] += noise[i] * hFdCngCom->olapWinSyn[N / 2 + i]; + timeDomainOutput[i] += noise[i] * hFdCngCom->olapWinSyn_flt[N / 2 + i]; } } } @@ -968,7 +968,7 @@ void stereoFdCngCoherence( pt_fftR += L_FFT; } - sts[0]->hFdCngEnc->hFdCngCom->coherence = sqrtf( ( mem[0] * mem[0] + mem[1] * mem[1] ) / ( mem[2] * mem[3] ) ); + sts[0]->hFdCngEnc->hFdCngCom->coherence_flt = sqrtf( ( mem[0] * mem[0] + mem[1] * mem[1] ) / ( mem[2] * mem[3] ) ); return; } @@ -1017,7 +1017,7 @@ void FdCngEncodeMDCTStereoSID( sts[ch] = hCPE->hCoreCoder[ch]; lr_in_ptr[ch] = &sts[ch]->hFdCngEnc->msNoiseEst[0]; ms_ptr[ch] = &logNoiseEst[ch][0]; - lr_out_ptr[ch] = &sts[ch]->hFdCngEnc->hFdCngCom->sidNoiseEst[0]; + lr_out_ptr[ch] = &sts[ch]->hFdCngEnc->hFdCngCom->sidNoiseEst_flt[0]; } N = sts[0]->hFdCngEnc->npartDec; set_f( weights, 1.f, NPART ); @@ -1137,7 +1137,7 @@ void FdCngEncodeMDCTStereoSID( gain[ch] += ms_ptr[ch][p]; } gain[ch] = ( E[ch] - gain[ch] ) / (float) N; - apply_scale( &gain[ch], sts[ch]->hFdCngEnc->hFdCngCom->CngBandwidth, sts[ch]->element_brate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO ); + apply_scale_flt( &gain[ch], sts[ch]->hFdCngEnc->hFdCngCom->CngBandwidth, sts[ch]->element_brate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO ); /* quantize gain */ gain_idx[ch] = (int16_t) floor( gain[ch] * 1.5f + GAIN_Q_OFFSET_IVAS + .5f ); @@ -1158,15 +1158,15 @@ void FdCngEncodeMDCTStereoSID( } /* scale bands and get scalefactors */ - scalebands( lr_out_ptr[ch], hFdCngEnc->partDec, N, hFdCngEnc->midbandDec, hFdCngEnc->nFFTpartDec, hFdCngEnc->stopBandDec - hFdCngEnc->startBandDec, hFdCngCom->cngNoiseLevel, 1 ); + scalebands_flt( lr_out_ptr[ch], hFdCngEnc->partDec, N, hFdCngEnc->midbandDec, hFdCngEnc->nFFTpartDec, hFdCngEnc->stopBandDec - hFdCngEnc->startBandDec, hFdCngCom->cngNoiseLevel_flt, 1 ); - lpc_from_spectrum( hFdCngCom, hFdCngEnc->startBandDec, hFdCngEnc->stopFFTbinDec, sts[ch]->preemph_fac_flt); + lpc_from_spectrum_flt( hFdCngCom, hFdCngEnc->startBandDec, hFdCngEnc->stopFFTbinDec, sts[ch]->preemph_fac_flt); sts[ch]->hDtxEnc->last_CNG_L_frame = sts[ch]->L_frame; } /* quantize channel coherence */ - coh_idx = (int16_t) floor( sts[0]->hFdCngEnc->hFdCngCom->coherence * 15.f + 0.5f ); + coh_idx = (int16_t) floor( sts[0]->hFdCngEnc->hFdCngCom->coherence_flt * 15.f + 0.5f ); coh_idx = max( 0, min( coh_idx, 15 ) ); /* ---- Write SID bitstream ---- */ @@ -1244,7 +1244,7 @@ void FdCngEncodeDiracMDCTStereoSID( N[ch] = sts[ch]->hFdCngEnc->npartDec; lr_in_ptr[ch] = &sts[ch]->hFdCngEnc->msNoiseEst[0]; ms_ptr[ch] = &logNoiseEst[ch][0]; - lr_out_ptr[ch] = &sts[ch]->hFdCngEnc->hFdCngCom->sidNoiseEst[0]; + lr_out_ptr[ch] = &sts[ch]->hFdCngEnc->hFdCngCom->sidNoiseEst_flt[0]; } set_f( weights, 1.f, NPART ); @@ -1299,7 +1299,7 @@ void FdCngEncodeDiracMDCTStereoSID( /* compute M gain */ gain[0] = sum_f( ms_ptr[0], N[0] ); gain[0] = ( E[0] - gain[0] ) / (float) N[0]; - apply_scale( &gain[0], sts[0]->hFdCngEnc->hFdCngCom->CngBandwidth, sts[0]->hDtxEnc->last_active_brate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO ); + apply_scale_flt( &gain[0], sts[0]->hFdCngEnc->hFdCngCom->CngBandwidth, sts[0]->hDtxEnc->last_active_brate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO ); /* quantize gain */ gain_idx[0] = (int16_t) floor( gain[0] * 1.5f + GAIN_Q_OFFSET_IVAS + .5f ); @@ -1333,14 +1333,14 @@ void FdCngEncodeDiracMDCTStereoSID( } /* scale bands and get scalefactors */ - scalebands( lr_out_ptr[ch], hFdCngEnc->partDec, N[ch], hFdCngEnc->midbandDec, hFdCngEnc->nFFTpartDec, hFdCngEnc->stopBandDec - hFdCngEnc->startBandDec, hFdCngCom->cngNoiseLevel, 1 ); + scalebands_flt( lr_out_ptr[ch], hFdCngEnc->partDec, N[ch], hFdCngEnc->midbandDec, hFdCngEnc->nFFTpartDec, hFdCngEnc->stopBandDec - hFdCngEnc->startBandDec, hFdCngCom->cngNoiseLevel_flt, 1 ); - lpc_from_spectrum( hFdCngCom, hFdCngEnc->startBandDec, hFdCngEnc->stopFFTbinDec, sts[ch]->preemph_fac_flt); + lpc_from_spectrum_flt( hFdCngCom, hFdCngEnc->startBandDec, hFdCngEnc->stopFFTbinDec, sts[ch]->preemph_fac_flt); sts[ch]->hDtxEnc->last_CNG_L_frame = sts[ch]->L_frame; } - sts[0]->hFdCngEnc->hFdCngCom->coherence = 0.0f; - sts[1]->hFdCngEnc->hFdCngCom->coherence = 0.0f; + sts[0]->hFdCngEnc->hFdCngCom->coherence_flt = 0.0f; + sts[1]->hFdCngEnc->hFdCngCom->coherence_flt = 0.0f; /* ---- Write SID bitstream ---- */ diff --git a/lib_enc/guided_plc_enc.c b/lib_enc/guided_plc_enc.c index 4869f242156aebd72b7c7762fe97750d53e8d3c9..f247c1765dc93929f0e639f0c875e173a66fb54a 100644 --- a/lib_enc/guided_plc_enc.c +++ b/lib_enc/guided_plc_enc.c @@ -91,7 +91,7 @@ static void coderLookAheadInnovation( *------------------------------------------------------------------------*/ /* find LP residual signal for look-ahead part */ - getLookAheadResSig( speechLookAhead, A, exc, L_frame, L_subfr, M, 2 ); + getLookAheadResSig_flt( speechLookAhead, A, exc, L_frame, L_subfr, M, 2 ); /* Initialize excitation buffer */ prev_pitch = st->T0_4th; @@ -141,7 +141,7 @@ static void getConcealedlsf( { float *lsf = memDecState->lsf_con_flt; - dlpc_bfi( L_frame, &lsf[0], memDecState->lsfold, last_good, 1 /*assumes packet loss */, memDecState->mem_MA, memDecState->mem_AR_flt, &( memDecState->stab_fac ), memDecState->lsf_adaptive_mean, 1, NULL, 0, NULL, NULL, lsfBase ); + dlpc_bfi_flt( L_frame, &lsf[0], memDecState->lsfold, last_good, 1 /*assumes packet loss */, memDecState->mem_MA, memDecState->mem_AR_flt, &( memDecState->stab_fac ), memDecState->lsf_adaptive_mean, 1, NULL, 0, NULL, NULL, lsfBase ); return; } @@ -205,12 +205,12 @@ void encoderSideLossSimulation( /* Decoder State Update */ lsf2lsp( lsf_q, lspLocal, M, st->sr_core ); - lsfBase = PlcGetlsfBase( st->lpcQuantization, st->narrowBand, st->sr_core ); + lsfBase = PlcGetlsfBase_flt( st->lpcQuantization, st->narrowBand, st->sr_core ); mvr2r( st->mem_MA, hPlc_Ext->mem_MA, M ); /* lsf parameter processing for concealment */ - updatelsfForConcealment( hPlc_Ext, lsf_q ); + updatelsfForConcealment_flt( hPlc_Ext, lsf_q ); hPlc_Ext->stab_fac = stab_fac; /* Update Decoder State for the loss simulation at the next frame */ @@ -235,7 +235,7 @@ void encoderSideLossSimulation( speechLookAhead = &( st->speech_enc_pe_flt[L_frame] ); /* lsf concealment simulation */ - getConcealedLP( hPlc_Ext, AqCon, lsfBase, st->sr_core, st->clas, L_frame ); + getConcealedLP_flt( hPlc_Ext, AqCon, lsfBase, st->sr_core, st->clas, L_frame ); /* apply encoder side PLC simulation */ hPlc_Ext->pit_min = st->pit_min; @@ -296,7 +296,7 @@ int16_t encSideSpecPowDiffuseDetector( { mvr2r( lsf_con, lsf_mod, M ); - modify_lsf( lsf_mod, M, sr_core, 1 ); + modify_lsf_flt( lsf_mod, M, sr_core, 1 ); cum_dist1 = 0; cum_dist2 = 0; diff --git a/lib_enc/hq_core_enc.c b/lib_enc/hq_core_enc.c index e84dcb01fe5c16d01ec5c6a216eb1523bf380b51..857c8fa9d6807fc43c774a07773445798ee01c6e 100644 --- a/lib_enc/hq_core_enc.c +++ b/lib_enc/hq_core_enc.c @@ -113,9 +113,9 @@ void hq_core_enc( left_overlap = -1; right_overlap = -1; - WindowSignal( st->hTcxCfg, st->hTcxCfg->tcx_offsetFB, TRANSITION_OVERLAP, FULL_OVERLAP, &left_overlap, &right_overlap, st->hTcxEnc->speech_TCX_flt, &L_spec, wtda_audio, 1, 1 ); + WindowSignal_flt( st->hTcxCfg, st->hTcxCfg->tcx_offsetFB, TRANSITION_OVERLAP, FULL_OVERLAP, &left_overlap, &right_overlap, st->hTcxEnc->speech_TCX_flt, &L_spec, wtda_audio, 1, 1 ); - TCX_MDCT( wtda_audio, t_audio, left_overlap, L_spec - ( left_overlap + right_overlap ) / 2, right_overlap, st->element_mode ); + TCX_MDCT_flt( wtda_audio, t_audio, left_overlap, L_spec - ( left_overlap + right_overlap ) / 2, right_overlap, st->element_mode ); inner_frame = inner_frame_tbl[st->bwidth]; L_spec = l_spec_ext_tbl[st->bwidth]; @@ -253,16 +253,16 @@ void hq_core_enc( Aq_old[0] = 1; /* Code taken from InternalTCXDecoder() */ - TCX_MDCT_Inverse( t_audio, wtda_audio, overlap, L_frame - overlap, overlap, st->element_mode ); + TCX_MDCT_Inverse_flt( t_audio, wtda_audio, overlap, L_frame - overlap, overlap, st->element_mode ); /* Window current frame */ - tcx_windowing_synthesis_current_frame( wtda_audio, st->hTcxCfg->tcx_aldo_window_2_flt, st->hTcxCfg->tcx_mdct_window_half_flt, st->hTcxCfg->tcx_mdct_window_minimum_flt, overlap, /*st->hTcxCfg->tcx_mdct_window_length*/ st->hTcxCfg->tcx_mdct_window_half_length, st->hTcxCfg->tcx_mdct_window_min_length, st->last_core == ACELP_CORE, st->hTcxCfg->tcx_last_overlap_mode, /*left mode*/ st->hTcxEnc->acelp_zir_flt, st->hTcxEnc->Txnq_flt, NULL, Aq_old, st->hTcxCfg->tcx_mdct_window_trans_flt, st->L_frame >> 1, tcx_offset < 0 ? -tcx_offset : 0, st->last_core, 0, 0 ); + tcx_windowing_synthesis_current_frame_flt( wtda_audio, st->hTcxCfg->tcx_aldo_window_2_flt, st->hTcxCfg->tcx_mdct_window_half_flt, st->hTcxCfg->tcx_mdct_window_minimum_flt, overlap, /*st->hTcxCfg->tcx_mdct_window_length*/ st->hTcxCfg->tcx_mdct_window_half_length, st->hTcxCfg->tcx_mdct_window_min_length, st->last_core == ACELP_CORE, st->hTcxCfg->tcx_last_overlap_mode, /*left mode*/ st->hTcxEnc->acelp_zir_flt, st->hTcxEnc->Txnq_flt, NULL, Aq_old, st->hTcxCfg->tcx_mdct_window_trans_flt, st->L_frame >> 1, tcx_offset < 0 ? -tcx_offset : 0, st->last_core, 0, 0 ); /*Compute windowed synthesis in case of switching to ALDO windows in next frame*/ mvr2r( wtda_audio + L_frame - nz, st->hTcxEnc->old_out, nz + overlap ); set_zero( st->hTcxEnc->old_out + nz + overlap, nz ); - tcx_windowing_synthesis_past_frame( st->hTcxEnc->old_out + nz, st->hTcxCfg->tcx_aldo_window_1_trunc_flt, st->hTcxCfg->tcx_mdct_window_half_flt, st->hTcxCfg->tcx_mdct_window_minimum_flt, overlap, st->hTcxCfg->tcx_mdct_window_half_length, st->hTcxCfg->tcx_mdct_window_min_length, FULL_OVERLAP ); + tcx_windowing_synthesis_past_frame_flt( st->hTcxEnc->old_out + nz, st->hTcxCfg->tcx_aldo_window_1_trunc_flt, st->hTcxCfg->tcx_mdct_window_half_flt, st->hTcxCfg->tcx_mdct_window_minimum_flt, overlap, st->hTcxCfg->tcx_mdct_window_half_length, st->hTcxCfg->tcx_mdct_window_min_length, FULL_OVERLAP ); for ( i = 0; i < nz; i++ ) { diff --git a/lib_enc/igf_enc.c b/lib_enc/igf_enc.c index 1166a4d4602b01d427694cbbd8a8c0d0b7e921e2..03943bdd3e3bcd5be47074ed500eebee708adce2 100644 --- a/lib_enc/igf_enc.c +++ b/lib_enc/igf_enc.c @@ -1213,11 +1213,11 @@ static void IGF_Whitening( hPrivateData->prevSFM_FIR_flt[p] = tmp; hPrivateData->prevSFM_IIR_flt[p] = SFM; - if ( SFM > hGrid->whiteningThreshold[1][p] ) + if ( SFM > hGrid->whiteningThreshold_flt[1][p] ) { hPrivateData->igfCurrWhiteningLevel[p] = IGF_WHITENING_STRONG; } - else if ( SFM > hGrid->whiteningThreshold[0][p] ) + else if ( SFM > hGrid->whiteningThreshold_flt[0][p] ) { hPrivateData->igfCurrWhiteningLevel[p] = IGF_WHITENING_MID; } @@ -1238,8 +1238,8 @@ static void IGF_Whitening( { /* check whether change in whitening level should be allowed or not (if SFM is inside a certain margin around thresholds) */ if ( hPrivateData->igfCurrWhiteningLevel[p] != hPrivateData->igfPrevWhiteningLevel[p] && - ( ( SFM > hGrid->whiteningThreshold[0][p] - 0.15f && SFM < hGrid->whiteningThreshold[0][p] + 0.15f ) || - ( SFM > hGrid->whiteningThreshold[1][p] - 0.15f && SFM < hGrid->whiteningThreshold[1][p] + 0.15f ) ) ) + ( ( SFM > hGrid->whiteningThreshold_flt[0][p] - 0.15f && SFM < hGrid->whiteningThreshold_flt[0][p] + 0.15f ) || + ( SFM > hGrid->whiteningThreshold_flt[1][p] - 0.15f && SFM < hGrid->whiteningThreshold_flt[1][p] + 0.15f ) ) ) { float mean_past_SFM = 0.f; int16_t countable = 0; @@ -1670,7 +1670,7 @@ void IGFEncSetMode( set_f( hPrivateData->SFM_sb, 0.f, IGF_MAX_SFB ); set_f( hPrivateData->SFM_tb, 0.f, IGF_MAX_SFB ); - if ( IGFCommonFuncsIGFConfiguration( total_brate, bwidth, element_mode, &hPrivateData->igfInfo, rf_mode ) ) + if (IGFCommonFuncsIGFConfiguration_flt( total_brate, bwidth, element_mode, &hPrivateData->igfInfo, rf_mode ) ) { IGFSCFEncoderOpen( &hPrivateData->hIGFSCFArithEnc, &hPrivateData->igfInfo, total_brate, bwidth, element_mode, rf_mode ); diff --git a/lib_enc/igf_scf_enc.c b/lib_enc/igf_scf_enc.c index 3c97808ef009009358ddd03f654d8676ba8cc353..e2a290afb7df58aec6dc39b151bec4e4e2bc8fcf 100644 --- a/lib_enc/igf_scf_enc.c +++ b/lib_enc/igf_scf_enc.c @@ -74,7 +74,7 @@ void IGFSCFEncoderOpen( hPublicData->scfCountLongBlock[2] = hIgfInfo->grid[2].swb_offset_len - 1; hPublicData->t = 0; /* protect against the invalid request of starting encoding with a dependent block */ - IGFCommonFuncsIGFGetCFTables( total_brate, bwidth, element_mode, rf_mode, &hPublicData->cf_se00, &hPublicData->cf_se01, &hPublicData->cf_off_se01, &hPublicData->cf_se02, &hPublicData->cf_off_se02, &hPublicData->cf_se10, &hPublicData->cf_off_se10, &hPublicData->cf_se11, &hPublicData->cf_off_se11 ); + IGFCommonFuncsIGFGetCFTables_flt( total_brate, bwidth, element_mode, rf_mode, &hPublicData->cf_se00, &hPublicData->cf_se01, &hPublicData->cf_off_se01, &hPublicData->cf_se02, &hPublicData->cf_off_se02, &hPublicData->cf_se10, &hPublicData->cf_off_se10, &hPublicData->cf_se11, &hPublicData->cf_off_se11 ); return; } diff --git a/lib_enc/init_enc.c b/lib_enc/init_enc.c index a6d9373ea858ed6bd72a6b5ea5e784832a1a464a..17faa5019012e0cb75b510e07854772dd07b72e8 100644 --- a/lib_enc/init_enc.c +++ b/lib_enc/init_enc.c @@ -102,7 +102,7 @@ ivas_error init_encoder( st->coder_type_raw = VOICED; st->last_coder_type_raw = st->coder_type_raw; - st->flag_ACELP16k = set_ACELP_flag( st->element_mode, st->total_brate, st->total_brate, idchan, 0, -1, -1 ); + st->flag_ACELP16k = set_ACELP_flag_IVAS( st->element_mode, st->total_brate, st->total_brate, idchan, 0, -1, -1 ); st->is_ism_format = 0; if ( ism_mode != ISM_MODE_NONE ) @@ -499,7 +499,7 @@ ivas_error init_encoder( if ( ( st->element_mode != IVAS_CPE_MDCT && idchan == 0 ) || ( st->element_mode == IVAS_CPE_MDCT && st->Opt_DTX_ON ) ) { - if ( ( error = openCldfb( &st->cldfbAnaEnc, CLDFB_ANALYSIS, st->input_Fs, CLDFB_PROTOTYPE_1_25MS ) ) != IVAS_ERR_OK ) + if ( ( error = openCldfb_ivas( &st->cldfbAnaEnc, CLDFB_ANALYSIS, st->input_Fs, CLDFB_PROTOTYPE_1_25MS ) ) != IVAS_ERR_OK ) { return error; } @@ -600,7 +600,7 @@ ivas_error init_encoder( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD BWE\n" ) ); } - if ( ( error = openCldfb( &st->cldfbSynTd, CLDFB_SYNTHESIS, 16000, CLDFB_PROTOTYPE_1_25MS ) ) != IVAS_ERR_OK ) + if ( ( error = openCldfb_ivas( &st->cldfbSynTd, CLDFB_SYNTHESIS, 16000, CLDFB_PROTOTYPE_1_25MS ) ) != IVAS_ERR_OK ) { return error; } @@ -917,8 +917,8 @@ void destroy_cldfb_encoder( Encoder_State *st /* i/o: Encoder static variables structure */ ) { - deleteCldfb( &st->cldfbSynTd ); - deleteCldfb( &st->cldfbAnaEnc ); + deleteCldfb_ivas( &st->cldfbSynTd ); + deleteCldfb_ivas( &st->cldfbAnaEnc ); deleteFdCngEnc( &st->hFdCngEnc ); diff --git a/lib_enc/ivas_core_pre_proc.c b/lib_enc/ivas_core_pre_proc.c index dc93ba5bed1c54df11aa0bb0eb7747c12e1594d1..b2af43fe5c1254f3b4415a05dcfbea6452733043 100644 --- a/lib_enc/ivas_core_pre_proc.c +++ b/lib_enc/ivas_core_pre_proc.c @@ -238,7 +238,7 @@ ivas_error pre_proc_ivas( st->total_brate = st->bits_frame_nominal * FRAMES_PER_SEC; SetModeIndex( st, st->last_bits_frame_nominal * FRAMES_PER_SEC, last_element_mode, MCT_flag ); - st->sr_core = getCoreSamplerateMode2( element_mode, st->total_brate, st->bwidth, st->flag_ACELP16k, st->rf_mode, st->is_ism_format ); + st->sr_core = getCoreSamplerateMode2_flt( element_mode, st->total_brate, st->bwidth, st->flag_ACELP16k, st->rf_mode, st->is_ism_format ); st->total_brate = total_brate_tmp; st->L_frame = (int16_t) ( st->sr_core / FRAMES_PER_SEC ); diff --git a/lib_enc/ivas_core_pre_proc_front.c b/lib_enc/ivas_core_pre_proc_front.c index 0033fba1803ae44d97016d4c0997a2f4951d8b61..eea16127f502d7c34e83069c10bb5e1c27a37823 100644 --- a/lib_enc/ivas_core_pre_proc_front.c +++ b/lib_enc/ivas_core_pre_proc_front.c @@ -289,12 +289,12 @@ ivas_error pre_proc_front_ivas( if ( element_mode == IVAS_SCE || ( element_mode == IVAS_CPE_MDCT && st->Opt_DTX_ON ) ) { - analysisCldfbEncoder( st, signal_in, input_frame, realBuffer, imagBuffer, enerBuffer ); + analysisCldfbEncoder_ivas( st, signal_in, input_frame, realBuffer, imagBuffer, enerBuffer ); } else if ( ( element_mode == IVAS_CPE_TD && st->idchan == 0 ) || ( st->idchan == 1 && st->tdm_LRTD_flag ) ) { /* cldfb analysis only for pri. channel */ - analysisCldfbEncoder( st, signal_in - NS2SA( input_Fs, L_MEM_RECALC_TBE_NS ), input_frame, realBuffer, imagBuffer, enerBuffer ); + analysisCldfbEncoder_ivas( st, signal_in - NS2SA( input_Fs, L_MEM_RECALC_TBE_NS ), input_frame, realBuffer, imagBuffer, enerBuffer ); } else if ( element_mode == IVAS_CPE_DFT ) { diff --git a/lib_enc/ivas_cpe_enc.c b/lib_enc/ivas_cpe_enc.c index 9e2da33be094b221806ad058c972f5de4ab4ef60..9b8f5b4dd3763640b58e22811b4c7cc9690e2b75 100644 --- a/lib_enc/ivas_cpe_enc.c +++ b/lib_enc/ivas_cpe_enc.c @@ -402,7 +402,7 @@ ivas_error ivas_cpe_enc( { int32_t internal_Fs; - internal_Fs = getTcxonly( IVAS_CPE_MDCT, sts[0]->bits_frame_nominal * FRAMES_PER_SEC, 0, sts[0]->is_ism_format ) == 0 ? INT_FS_16k : max( INT_FS_16k, sts[0]->sr_core ); + internal_Fs = getTcxonly_ivas( IVAS_CPE_MDCT, sts[0]->bits_frame_nominal * FRAMES_PER_SEC, 0, sts[0]->is_ism_format ) == 0 ? INT_FS_16k : max( INT_FS_16k, sts[0]->sr_core ); /* iDFT at input sampling rate */ stereo_dft_enc_synthesize( hCPE->hStereoDft, sts[0]->input, 0, input_Fs, input_Fs, 0 ); @@ -529,11 +529,11 @@ ivas_error ivas_cpe_enc( { if ( ( sts[0]->core_brate == SID_2k40 || sts[0]->core_brate == FRAME_NO_DATA ) && hCPE->element_mode == IVAS_CPE_DFT ) { - sts[n]->flag_ACELP16k = set_ACELP_flag( hCPE->element_mode, hCPE->element_brate, sts[n]->core_brate, n, sts[0]->tdm_LRTD_flag, sts[n]->bwidth, sts[n]->cng_type ); + sts[n]->flag_ACELP16k = set_ACELP_flag_IVAS( hCPE->element_mode, hCPE->element_brate, sts[n]->core_brate, n, sts[0]->tdm_LRTD_flag, sts[n]->bwidth, sts[n]->cng_type ); } else { - sts[n]->flag_ACELP16k = set_ACELP_flag( hCPE->element_mode, hCPE->element_brate, sts[n]->total_brate, n, sts[0]->tdm_LRTD_flag, sts[n]->bwidth, sts[n]->cng_type ); + sts[n]->flag_ACELP16k = set_ACELP_flag_IVAS( hCPE->element_mode, hCPE->element_brate, sts[n]->total_brate, n, sts[0]->tdm_LRTD_flag, sts[n]->bwidth, sts[n]->cng_type ); } } diff --git a/lib_enc/ivas_ism_enc.c b/lib_enc/ivas_ism_enc.c index 5f34a92a9d84fad9f321f7144ca78127e64a66a8..039cee60eb3ebbde6eca6a015aa8ac65f87cfd49 100644 --- a/lib_enc/ivas_ism_enc.c +++ b/lib_enc/ivas_ism_enc.c @@ -314,7 +314,7 @@ ivas_error ivas_ism_enc( /* set ACELP@12k8 / ACELP@16k flag for flexible ACELP core */ if ( st->core_brate == SID_2k40 || st->core_brate == FRAME_NO_DATA ) { - st->flag_ACELP16k = set_ACELP_flag( IVAS_SCE, hSCE->element_brate, st->core_brate, 0, 0, -1, -1 ); + st->flag_ACELP16k = set_ACELP_flag_IVAS( IVAS_SCE, hSCE->element_brate, st->core_brate, 0, 0, -1, -1 ); } else if ( st->low_rate_mode ) { @@ -322,7 +322,7 @@ ivas_error ivas_ism_enc( } else { - st->flag_ACELP16k = set_ACELP_flag( IVAS_SCE, hSCE->element_brate, st->total_brate, 0, 0, -1, -1 ); + st->flag_ACELP16k = set_ACELP_flag_IVAS( IVAS_SCE, hSCE->element_brate, st->total_brate, 0, 0, -1, -1 ); } /* modify the coder_type depending on the total_brate per channel */ diff --git a/lib_enc/ivas_masa_enc.c b/lib_enc/ivas_masa_enc.c index bc6993bc042586f087053d29388cb7b9a1c00af4..cd75734fac4e8cc6b4481636d374452dc7434cc3 100644 --- a/lib_enc/ivas_masa_enc.c +++ b/lib_enc/ivas_masa_enc.c @@ -122,7 +122,7 @@ ivas_error ivas_masa_enc_open( for ( i = 0; i < hMasa->data.num_Cldfb_instances; i++ ) { - if ( ( error = openCldfb( &( hMasa->data.cldfbAnaEnc[i] ), CLDFB_ANALYSIS, hEncoderConfig->input_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) + if ( ( error = openCldfb_ivas( &( hMasa->data.cldfbAnaEnc[i] ), CLDFB_ANALYSIS, hEncoderConfig->input_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) { return error; } @@ -206,7 +206,7 @@ void ivas_masa_enc_close( for ( i = 0; i < ( *hMasa )->data.num_Cldfb_instances; i++ ) { - deleteCldfb( &( ( *hMasa )->data.cldfbAnaEnc[i] ) ); + deleteCldfb_ivas( &( ( *hMasa )->data.cldfbAnaEnc[i] ) ); } if ( ( *hMasa )->data.hOmasaData != NULL ) @@ -626,7 +626,7 @@ void ivas_masa_estimate_energy( { for ( i = 0; i < nchan_transport; i++ ) { - cldfbAnalysis_ts( &( data_f[i][l_ts * ts] ), Input_RealBuffer[i], Input_ImagBuffer[i], l_ts, hMasa->data.cldfbAnaEnc[i] ); + cldfbAnalysis_ts_ivas( &( data_f[i][l_ts * ts] ), Input_RealBuffer[i], Input_ImagBuffer[i], l_ts, hMasa->data.cldfbAnaEnc[i] ); } for ( band_m_idx = 0; band_m_idx < MASA_FREQUENCY_BANDS; band_m_idx++ ) diff --git a/lib_enc/ivas_mdct_core_enc.c b/lib_enc/ivas_mdct_core_enc.c index 09ede7a09486be41ba4a966313fdcdcac0d0e5c8..c0461bd097557eb27dcd422a20b2b9c06e0b03e8 100644 --- a/lib_enc/ivas_mdct_core_enc.c +++ b/lib_enc/ivas_mdct_core_enc.c @@ -272,7 +272,7 @@ static void kernel_switch_update_transforms( int16_t i, leftOverlap = 0, rightOverlap = 0; const float *left_win, *right_win; - tcx_get_windows( hTcxCfg, (int16_t) windowedTimeSignal[0], (int16_t) windowedTimeSignal[1], &leftOverlap, &left_win, &rightOverlap, &right_win, 1 ); + tcx_get_windows_flt( hTcxCfg, (int16_t) windowedTimeSignal[0], (int16_t) windowedTimeSignal[1], &leftOverlap, &left_win, &rightOverlap, &right_win, 1 ); if ( speech_TCX != NULL && tcxTransType != TCX_20 && (int16_t) windowedTimeSignal[0] == FULL_OVERLAP && s - leftOverlap > minWindowLen ) { for ( i = minWindowLen; i >= 0; i-- ) /* outer left folding of shortened long ALDO slope */ @@ -295,7 +295,7 @@ static void kernel_switch_update_transforms( s = hTcxCfg->tcx5SizeFB; /* obtain 1st TCX5 again */ nSubframes *= 2; - WindowSignal( hTcxCfg, leftOverlap / 2, RECTANGULAR_OVERLAP, MIN_OVERLAP, &leftOverlap, &rightOverlap, windowedTimeSignal + 2, &s, tcx5Win, 0, 1 ); + WindowSignal_flt( hTcxCfg, leftOverlap / 2, RECTANGULAR_OVERLAP, MIN_OVERLAP, &leftOverlap, &rightOverlap, windowedTimeSignal + 2, &s, tcx5Win, 0, 1 ); kernel_switch_trafo( tcx5Win, sigR, leftOverlap, s /* L_subfr. */ - ( leftOverlap + rightOverlap ) / 2, rightOverlap, kernelType ); if ( kernelType & 1 ) /* 2nd TCX5 is kernelType 3 */ diff --git a/lib_enc/ivas_omasa_enc.c b/lib_enc/ivas_omasa_enc.c index 404c1537d08d6d3fecc186183964cb25e6756c7f..1444c5650e2f05f2dea21cd23f68013df77356b4 100644 --- a/lib_enc/ivas_omasa_enc.c +++ b/lib_enc/ivas_omasa_enc.c @@ -87,7 +87,7 @@ ivas_error ivas_omasa_enc_open( hOMasa->num_Cldfb_instances = numAnalysisChannels; for ( i = 0; i < hOMasa->num_Cldfb_instances; i++ ) { - if ( ( error = openCldfb( &( hOMasa->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, st_ivas->hEncoderConfig->input_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) + if ( ( error = openCldfb_ivas( &( hOMasa->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, st_ivas->hEncoderConfig->input_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) { return error; } @@ -166,7 +166,7 @@ void ivas_omasa_enc_close( for ( i = 0; i < ( *hOMasa )->num_Cldfb_instances; i++ ) { - deleteCldfb( &( ( *hOMasa )->cldfbAnaEnc[i] ) ); + deleteCldfb_ivas( &( ( *hOMasa )->cldfbAnaEnc[i] ) ); } for ( i = 0; i < DIRAC_NUM_DIMS; i++ ) @@ -804,7 +804,7 @@ static void ivas_omasa_param_est_enc( { for ( i = 0; i < nchan_ism; i++ ) { - cldfbAnalysis_ts( &( data_f[i][l_ts * ts] ), Chnl_RealBuffer[i], Chnl_ImagBuffer[i], l_ts, hOMasa->cldfbAnaEnc[i] ); + cldfbAnalysis_ts_ivas( &( data_f[i][l_ts * ts] ), Chnl_RealBuffer[i], Chnl_ImagBuffer[i], l_ts, hOMasa->cldfbAnaEnc[i] ); } /* Compute energy */ @@ -966,7 +966,7 @@ static void ivas_omasa_energy_and_ratio_est( { for ( i = 0; i < nchan_ism; i++ ) { - cldfbAnalysis_ts( &( data_f[i][l_ts * ts] ), Chnl_RealBuffer[i], Chnl_ImagBuffer[i], l_ts, hOMasa->cldfbAnaEnc[i] ); + cldfbAnalysis_ts_ivas( &( data_f[i][l_ts * ts] ), Chnl_RealBuffer[i], Chnl_ImagBuffer[i], l_ts, hOMasa->cldfbAnaEnc[i] ); } /* Compute energy */ diff --git a/lib_enc/ivas_sce_enc.c b/lib_enc/ivas_sce_enc.c index c72feda1dc6bb3dc16847c0f714a38446f4c3278..db4960d4ac67f70ac50709d3b3ba8c6af90217cb 100644 --- a/lib_enc/ivas_sce_enc.c +++ b/lib_enc/ivas_sce_enc.c @@ -233,7 +233,7 @@ ivas_error ivas_sce_enc( /* set ACELP@12k8 / ACELP@16k flag for flexible ACELP core */ if ( st->core_brate == SID_2k40 || st->core_brate == FRAME_NO_DATA ) { - st->flag_ACELP16k = set_ACELP_flag( IVAS_SCE, hSCE->element_brate, st->core_brate, 0, 0, -1, -1 ); + st->flag_ACELP16k = set_ACELP_flag_IVAS( IVAS_SCE, hSCE->element_brate, st->core_brate, 0, 0, -1, -1 ); } else if ( st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ && st->low_rate_mode ) { @@ -241,7 +241,7 @@ ivas_error ivas_sce_enc( } else { - st->flag_ACELP16k = set_ACELP_flag( IVAS_SCE, hSCE->element_brate, st->total_brate, 0, 0, -1, -1 ); + st->flag_ACELP16k = set_ACELP_flag_IVAS( IVAS_SCE, hSCE->element_brate, st->total_brate, 0, 0, -1, -1 ); } /* modify the coder_type depending on the total_brate per channel */ diff --git a/lib_enc/ivas_stereo_dft_enc.c b/lib_enc/ivas_stereo_dft_enc.c index 3463af2da3574e909977898a5e52c52f72d29925..b1dcb02668a27a1433de090b1685a28512672414 100644 --- a/lib_enc/ivas_stereo_dft_enc.c +++ b/lib_enc/ivas_stereo_dft_enc.c @@ -310,7 +310,7 @@ static void stereo_dft_enc_open( /*Init. DFT sizes*/ hStereoDft->NFFT = (int16_t) ( STEREO_DFT_N_MAX_ENC * input_Fs / 48000 ); hStereoDft->dft_ovl = (int16_t) ( STEREO_DFT_OVL_MAX * input_Fs / 48000 ); - mdct_window_sine( win, input_Fs, hStereoDft->dft_ovl, FULL_OVERLAP, IVAS_CPE_DFT ); + mdct_window_sine_flt( win, input_Fs, hStereoDft->dft_ovl, FULL_OVERLAP, IVAS_CPE_DFT ); hStereoDft->win_ana_energy = (float) hStereoDft->N - hStereoDft->dft_ovl; hStereoDft->win_ana_energy += 2 * sum_f( win, hStereoDft->dft_ovl ); @@ -1707,7 +1707,7 @@ void stereo_dft_enc_res( } /* MDCT analysis */ - TCX_MDCT( win, MDCT_RES, STEREO_DFT_OVL_8k, L_FRAME8k - STEREO_DFT_OVL_8k, STEREO_DFT_OVL_8k, IVAS_CPE_DFT ); + TCX_MDCT_flt( win, MDCT_RES, STEREO_DFT_OVL_8k, L_FRAME8k - STEREO_DFT_OVL_8k, STEREO_DFT_OVL_8k, IVAS_CPE_DFT ); /*Compute the DMX to RES for each band*/ max_snr = 0.f; /*minimum gain for residual coding -> no coding*/ diff --git a/lib_enc/ivas_stereo_switching_enc.c b/lib_enc/ivas_stereo_switching_enc.c index 9d5d7abde116c8500a272531593ae3fcd6e43450..1862535c36532274590e9be65839e1faea95b682 100644 --- a/lib_enc/ivas_stereo_switching_enc.c +++ b/lib_enc/ivas_stereo_switching_enc.c @@ -179,7 +179,7 @@ static void deallocate_CoreCoder_enc( if ( st->cldfbAnaEnc != NULL ) { - deleteCldfb( &st->cldfbAnaEnc ); + deleteCldfb_ivas( &st->cldfbAnaEnc ); } if ( st->hBWE_TD != NULL ) @@ -190,7 +190,7 @@ static void deallocate_CoreCoder_enc( if ( st->cldfbSynTd != NULL ) { - deleteCldfb( &st->cldfbSynTd ); + deleteCldfb_ivas( &st->cldfbSynTd ); } if ( st->hBWE_FD != NULL ) @@ -352,8 +352,8 @@ ivas_error stereo_memory_enc( if ( hCPE->last_element_mode == IVAS_CPE_MDCT && ( hCPE->element_mode == IVAS_CPE_DFT || hCPE->element_mode == IVAS_CPE_TD ) ) { /* Deallocate MDCT CNG structures */ - deleteCldfb( &hCPE->hCoreCoder[0]->cldfbAnaEnc ); - deleteCldfb( &hCPE->hCoreCoder[1]->cldfbAnaEnc ); + deleteCldfb_ivas( &hCPE->hCoreCoder[0]->cldfbAnaEnc ); + deleteCldfb_ivas( &hCPE->hCoreCoder[1]->cldfbAnaEnc ); if ( hCPE->element_mode == IVAS_CPE_DFT ) { @@ -403,7 +403,7 @@ ivas_error stereo_memory_enc( /* allocate CLDFB for primary channel */ if ( st->cldfbAnaEnc == NULL ) { - if ( ( error = openCldfb( &st->cldfbAnaEnc, CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_1_25MS ) ) != IVAS_ERR_OK ) + if ( ( error = openCldfb_ivas( &st->cldfbAnaEnc, CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_1_25MS ) ) != IVAS_ERR_OK ) { return error; } @@ -419,7 +419,7 @@ ivas_error stereo_memory_enc( if ( st->cldfbSynTd == NULL ) { - if ( ( error = openCldfb( &st->cldfbSynTd, CLDFB_SYNTHESIS, 16000, CLDFB_PROTOTYPE_1_25MS ) ) != IVAS_ERR_OK ) + if ( ( error = openCldfb_ivas( &st->cldfbSynTd, CLDFB_SYNTHESIS, 16000, CLDFB_PROTOTYPE_1_25MS ) ) != IVAS_ERR_OK ) { return error; } @@ -549,7 +549,7 @@ ivas_error stereo_memory_enc( for ( i = 0; i < CPE_CHANNELS; i++ ) { st = hCPE->hCoreCoder[i]; - if ( ( error = openCldfb( &st->cldfbAnaEnc, CLDFB_ANALYSIS, st->input_Fs, CLDFB_PROTOTYPE_1_25MS ) ) != IVAS_ERR_OK ) + if ( ( error = openCldfb_ivas( &st->cldfbAnaEnc, CLDFB_ANALYSIS, st->input_Fs, CLDFB_PROTOTYPE_1_25MS ) ) != IVAS_ERR_OK ) { return error; } @@ -726,7 +726,7 @@ void stereo_switching_enc( if ( sts[0]->cldfbSynTd != NULL ) { - cldfb_reset_memory( sts[0]->cldfbSynTd ); + cldfb_reset_memory_ivas( sts[0]->cldfbSynTd ); sts[0]->currEnergyLookAhead = 6.1e-5f; } @@ -745,7 +745,7 @@ void stereo_switching_enc( if ( sts[1]->cldfbSynTd != NULL ) { - cldfb_reset_memory( sts[1]->cldfbSynTd ); + cldfb_reset_memory_ivas( sts[1]->cldfbSynTd ); sts[1]->currEnergyLookAhead = 6.1e-5f; } } diff --git a/lib_enc/ivas_stereo_td_enc.c b/lib_enc/ivas_stereo_td_enc.c index 7a72d612e8c634285d659a8ae2d0c6980c5c2e36..38f39454628132fcc383a080a0328a3fdcbfe57a 100644 --- a/lib_enc/ivas_stereo_td_enc.c +++ b/lib_enc/ivas_stereo_td_enc.c @@ -182,7 +182,7 @@ ivas_error stereo_set_tdm( /* deallocate CLDFB ana for secondary channel */ if ( st->cldfbAnaEnc != NULL ) { - deleteCldfb( &st->cldfbAnaEnc ); + deleteCldfb_ivas( &st->cldfbAnaEnc ); } /* deallocate BWEs for secondary channel */ @@ -194,7 +194,7 @@ ivas_error stereo_set_tdm( st->hBWE_TD = NULL; } - deleteCldfb( &st->cldfbSynTd ); + deleteCldfb_ivas( &st->cldfbSynTd ); if ( st->hBWE_FD != NULL ) { @@ -229,7 +229,7 @@ ivas_error stereo_set_tdm( /* allocate CLDFB ana for secondary channel */ if ( st->cldfbAnaEnc == NULL ) { - if ( ( error = openCldfb( &st->cldfbAnaEnc, CLDFB_ANALYSIS, st->input_Fs, CLDFB_PROTOTYPE_1_25MS ) ) != IVAS_ERR_OK ) + if ( ( error = openCldfb_ivas( &st->cldfbAnaEnc, CLDFB_ANALYSIS, st->input_Fs, CLDFB_PROTOTYPE_1_25MS ) ) != IVAS_ERR_OK ) { return error; } @@ -243,7 +243,7 @@ ivas_error stereo_set_tdm( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD BWE\n" ) ); } - if ( ( error = openCldfb( &st->cldfbSynTd, CLDFB_SYNTHESIS, 16000, CLDFB_PROTOTYPE_1_25MS ) ) != IVAS_ERR_OK ) + if ( ( error = openCldfb_ivas( &st->cldfbSynTd, CLDFB_SYNTHESIS, 16000, CLDFB_PROTOTYPE_1_25MS ) ) != IVAS_ERR_OK ) { return error; } diff --git a/lib_enc/ivas_tcx_core_enc.c b/lib_enc/ivas_tcx_core_enc.c index 325e20b76155e5ec824ac567d0b1f769f9c694da..f0c42d041d44827da5d5b2cad671c8470aa642ac 100644 --- a/lib_enc/ivas_tcx_core_enc.c +++ b/lib_enc/ivas_tcx_core_enc.c @@ -77,7 +77,7 @@ void stereo_tcx_init_enc( } /*sampling rate*/ - st->sr_core = getCoreSamplerateMode2( st->element_mode, st->bits_frame_nominal * FRAMES_PER_SEC, st->bwidth, st->flag_ACELP16k, st->rf_mode, st->is_ism_format ); + st->sr_core = getCoreSamplerateMode2_flt( st->element_mode, st->bits_frame_nominal * FRAMES_PER_SEC, st->bwidth, st->flag_ACELP16k, st->rf_mode, st->is_ism_format ); st->fscale = sr2fscale( st->sr_core ); /*frame size*/ @@ -105,9 +105,9 @@ void stereo_tcx_init_enc( } if ( !prev_IsTNSAllowed && st->hTcxCfg->fIsTNSAllowed && st->element_mode == IVAS_CPE_DFT ) /* may happen in unified stereo when switching stereo technologies */ { - InitTnsConfigs( st->bwidth, st->hTcxCfg->tcx_coded_lines, st->hTcxCfg->tnsConfig, st->hIGFEnc->infoStopFrequency, st->bits_frame_nominal * FRAMES_PER_SEC, st->element_mode, 0 ); + InitTnsConfigs_flt( st->bwidth, st->hTcxCfg->tcx_coded_lines, st->hTcxCfg->tnsConfig, st->hIGFEnc->infoStopFrequency, st->bits_frame_nominal * FRAMES_PER_SEC, st->element_mode, 0 ); - SetAllowTnsOnWhite( st->hTcxCfg->tnsConfig, 0 ); + SetAllowTnsOnWhite_flt( st->hTcxCfg->tnsConfig, 0 ); } st->core_brate = st->total_brate; @@ -600,7 +600,7 @@ int16_t ivas_acelp_tcx20_switching( { overlap = L_LOOK_12k8; tcx_offset = ( overlap >> 1 ); - mdct_window_sine( window, INT_FS_12k8, overlap, FULL_OVERLAP, st->element_mode ); + mdct_window_sine_flt( window, INT_FS_12k8, overlap, FULL_OVERLAP, st->element_mode ); if ( st->last_core == ACELP_CORE ) { @@ -630,7 +630,7 @@ int16_t ivas_acelp_tcx20_switching( xn_buf[L_frame + i] *= window[overlap - 1 - i]; } - TCX_MDCT( xn_buf, x, overlap, L_frame - overlap, overlap, st->element_mode ); + TCX_MDCT_flt( xn_buf, x, overlap, L_frame - overlap, overlap, st->element_mode ); for ( i = 0; i < L_frame; i++ ) { @@ -640,7 +640,7 @@ int16_t ivas_acelp_tcx20_switching( weight_a( A_q_tcx, Ap, GAMMA1_FLT, M ); - lpc2mdct( Ap, M, gainlpc, FDNS_NPTS, 0 ); + lpc2mdct_flt( Ap, M, gainlpc, FDNS_NPTS, 0 ); mdct_preShaping( x, L_frame, gainlpc ); @@ -693,7 +693,7 @@ int16_t ivas_acelp_tcx20_switching( /*Approximate SNR of TCX*/ set_f( x, sqrtf( ener ), L_frame ); - mdct_noiseShaping( x, L_frame, gainlpc, FDNS_NPTS ); + mdct_noiseShaping_flt( x, L_frame, gainlpc, FDNS_NPTS ); if ( st->last_core != ACELP_CORE ) { diff --git a/lib_enc/ivas_td_low_rate_enc.c b/lib_enc/ivas_td_low_rate_enc.c index 825e01a254d1f62796f5ebc1a2617efb8c2c25b8..fee3d325c9a591dae355169b598e326960f2241f 100644 --- a/lib_enc/ivas_td_low_rate_enc.c +++ b/lib_enc/ivas_td_low_rate_enc.c @@ -252,7 +252,7 @@ void encod_gen_2sbfr( * Find adaptive exitation *-----------------------------------------------------------------*/ - pred_lt4( &exc[i_subfr], &exc[i_subfr], T0, T0_frac, 2 * L_SUBFR + 1, inter4_2, L_INTERPOL2, PIT_UP_SAMP ); + pred_lt4_flt( &exc[i_subfr], &exc[i_subfr], T0, T0_frac, 2 * L_SUBFR + 1, inter4_2, L_INTERPOL2, PIT_UP_SAMP ); /*-----------------------------------------------------------------* * Gain clipping test to avoid unstable synthesis on frame erasure diff --git a/lib_enc/lsf_enc.c b/lib_enc/lsf_enc.c index 81268825d3bc26e535f9390695503452e3bcfdf0..46a1e0c35e1a0cbd9ec8e7b731ca142b30d58ba5 100644 --- a/lib_enc/lsf_enc.c +++ b/lib_enc/lsf_enc.c @@ -361,7 +361,7 @@ static void lsfq_CNG( /* quantize the difference with LVQ */ mslvq_cng( idx_cv, dd, qlsf, ddq, idx_lead_cng, idx_scale_cng, wghts ); - index_lvq( ddq, idx_lead_cng, idx_scale_cng, START_CNG + idx_cv, idx_lvq, 0 ); + index_lvq( ddq, idx_lead_cng, idx_scale_cng, START_CNG_IVAS + idx_cv, idx_lvq, 0 ); v_add( qlsf, &CNG_SN1[idx_cv * M], qlsf, M ); /* write the VQ index to the bitstream */ diff --git a/lib_enc/lsf_msvq_ma_enc.c b/lib_enc/lsf_msvq_ma_enc.c index 8607f1d51b682a3d53af951925fbb73a6ec27b9c..5aa9fae1ff4db89d819397dae0b5de7db2323bef 100644 --- a/lib_enc/lsf_msvq_ma_enc.c +++ b/lib_enc/lsf_msvq_ma_enc.c @@ -743,13 +743,13 @@ int16_t Q_lsf_tcxlpc( } - msvq_enc( lsf_codebook[narrowband][cdk], lsf_dims, lsf_offs, lsf, lsf_numlevels, kMaxC, TCXLPC_NUMSTAGES, weights, M, M, 0, NULL, indices + NumIndices ); - msvq_dec_float( lsf_codebook[narrowband][cdk], lsf_dims, lsf_offs, TCXLPC_NUMSTAGES, M, M, indices + NumIndices, 0, NULL, lsf_q, lsf_q_ind ); + msvq_enc(lsf_codebook_flt[narrowband][cdk], lsf_dims_ivas, lsf_offs_ivas, lsf, lsf_numlevels, kMaxC, TCXLPC_NUMSTAGES, weights, M, M, 0, NULL, indices + NumIndices ); + msvq_dec_float(lsf_codebook_flt[narrowband][cdk], lsf_dims_ivas, lsf_offs_ivas, TCXLPC_NUMSTAGES, M, M, indices + NumIndices, 0, NULL, lsf_q, lsf_q_ind ); NumIndices += TCXLPC_NUMSTAGES; /* Update flag */ - indices[0] = lsf_ind_is_active( lsf_q_ind, lsf_means_float[narrowband], narrowband, cdk ); + indices[0] = lsf_ind_is_active_flt( lsf_q_ind, lsf_means_float[narrowband], narrowband, cdk ); /* Get residual vector */ for ( i = 0; i < M; ++i ) @@ -757,13 +757,13 @@ int16_t Q_lsf_tcxlpc( lsf_rem[i] = ( pred[i] + lsf[i] ) - ( lsf_means_float[narrowband][i] + lsf_q_ind[i] / (float) ( 2.0f * 1.28f ) ); } /* Quantize using extra stage(s) */ - msvq_enc( lsf_ind_codebook[narrowband][cdk], lsf_ind_dims, lsf_ind_offs, lsf_rem, lsf_ind_numlevels, kMaxC, TCXLPC_IND_NUMSTAGES, weights, M, M, 0, NULL, indices + NumIndices ); + msvq_enc( lsf_ind_codebook_flt[narrowband][cdk], lsf_ind_dims_ivas, lsf_ind_offs, lsf_rem, lsf_ind_numlevels, kMaxC, TCXLPC_IND_NUMSTAGES, weights, M, M, 0, NULL, indices + NumIndices ); /* Only add contribution if flag is enabled */ if ( indices[0] ) { /* Decode */ - msvq_dec_float( lsf_ind_codebook[narrowband][cdk], lsf_ind_dims, lsf_ind_offs, TCXLPC_IND_NUMSTAGES, M, M, indices + NumIndices, 0, NULL, lsf_rem_q, lsf_rem_q_ind ); + msvq_dec_float( lsf_ind_codebook_flt[narrowband][cdk], lsf_ind_dims_ivas, lsf_ind_offs, TCXLPC_IND_NUMSTAGES, M, M, indices + NumIndices, 0, NULL, lsf_rem_q, lsf_rem_q_ind ); NumIndices += TCXLPC_IND_NUMSTAGES; /* Add to MA-removed vector */ diff --git a/lib_enc/mslvq_enc.c b/lib_enc/mslvq_enc.c index e4e98ea1e63e79e1b27af55cc2f97aedffb34973..f4f40a5afb8d3ccdc72f2bd4ddc67489e01fa851 100644 --- a/lib_enc/mslvq_enc.c +++ b/lib_enc/mslvq_enc.c @@ -229,7 +229,7 @@ float mslvq_cng( mode = LVQ_COD_MODES + idx_cv; /* for CNG there is only one bitrate but several quantizer structures, depending on the previous VQ stage */ - mode_glb = START_CNG + idx_cv; + mode_glb = START_CNG_IVAS + idx_cv; p_sigma = sigma_MSLVQ[mode]; p_inv_sigma = inv_sigma_MSLVQ[mode]; diff --git a/lib_enc/pit_enc.c b/lib_enc/pit_enc.c index d8d51e2a1b7a977b89fc5cc2ea6e488482e8db62..f2af3a585ad9c530d49b7d25814eee251657b7c0 100644 --- a/lib_enc/pit_enc.c +++ b/lib_enc/pit_enc.c @@ -1165,11 +1165,11 @@ void Mode2_pit_encode( { if ( i_subfr == 0 ) { - limit_T0_voiced( 4, pit_res_max >> 1, T_op[0], 0, 1, T0_min, T0_min_frac, T0_max, T0_max_frac, pit_min, pit_max ); + limit_T0_voiced_ivas( 4, pit_res_max >> 1, T_op[0], 0, 1, T0_min, T0_min_frac, T0_max, T0_max_frac, pit_min, pit_max ); } else { - limit_T0_voiced( 4, pit_res_max >> 1, *T0, *T0_frac, *T0_res, T0_min, T0_min_frac, T0_max, T0_max_frac, pit_min, pit_max ); + limit_T0_voiced_ivas( 4, pit_res_max >> 1, *T0, *T0_frac, *T0_res, T0_min, T0_min_frac, T0_max, T0_max_frac, pit_min, pit_max ); } *T0 = E_GAIN_closed_loop_search( exc, xn, h1, *T0_min, *T0_min_frac, *T0_max, *T0_max_frac, pit_res_max >> 1, T0_frac, T0_res, pit_res_max, i_subfr, pit_min, pit_min, pit_fr1b, L_SUBFR ); @@ -1188,15 +1188,15 @@ void Mode2_pit_encode( if ( i_subfr == 0 ) { - limit_T0_voiced( 5, pit_res_max >> 1, T_op[0], 0, 1, T0_min, T0_min_frac, T0_max, T0_max_frac, pit_min, pit_max ); + limit_T0_voiced_ivas( 5, pit_res_max >> 1, T_op[0], 0, 1, T0_min, T0_min_frac, T0_max, T0_max_frac, pit_min, pit_max ); } else if ( i_subfr == 2 * L_SUBFR ) { - limit_T0_voiced( 5, pit_res_max >> 1, T_op[1], 0, 1, T0_min, T0_min_frac, T0_max, T0_max_frac, pit_min, pit_max ); + limit_T0_voiced_ivas( 5, pit_res_max >> 1, T_op[1], 0, 1, T0_min, T0_min_frac, T0_max, T0_max_frac, pit_min, pit_max ); } else { - limit_T0_voiced( 5, pit_res_max >> 1, *T0, *T0_frac, *T0_res, T0_min, T0_min_frac, T0_max, T0_max_frac, pit_min, pit_max ); + limit_T0_voiced_ivas( 5, pit_res_max >> 1, *T0, *T0_frac, *T0_res, T0_min, T0_min_frac, T0_max, T0_max_frac, pit_min, pit_max ); } *T0 = E_GAIN_closed_loop_search( exc, xn, h1, *T0_min, *T0_min_frac, *T0_max, *T0_max_frac, pit_res_max >> 1, T0_frac, T0_res, pit_res_max, pit_flag, pit_min, pit_min, pit_fr1b, L_SUBFR ); @@ -1227,7 +1227,7 @@ void Mode2_pit_encode( } else { - limit_T0_voiced( 6, pit_res_max2, *T0, 0, 1, T0_min, T0_min_frac, T0_max, T0_max_frac, pit_min, pit_max ); + limit_T0_voiced_ivas( 6, pit_res_max2, *T0, 0, 1, T0_min, T0_min_frac, T0_max, T0_max_frac, pit_min, pit_max ); } *T0 = E_GAIN_closed_loop_search( exc, xn, h1, *T0_min, *T0_min_frac, *T0_max, *T0_max_frac, pit_res_max2, T0_frac, T0_res, pit_res_max, i_subfr, pit_min, pit_fr2, pit_fr1, L_SUBFR ); @@ -1259,7 +1259,7 @@ void Mode2_pit_encode( } else { - limit_T0_voiced( 6, pit_res_max2, *T0, 0, 1, T0_min, T0_min_frac, T0_max, T0_max_frac, pit_min, pit_max ); + limit_T0_voiced_ivas( 6, pit_res_max2, *T0, 0, 1, T0_min, T0_min_frac, T0_max, T0_max_frac, pit_min, pit_max ); } *T0 = E_GAIN_closed_loop_search( exc, xn, h1, *T0_min, *T0_min_frac, *T0_max, *T0_max_frac, pit_res_max2, T0_frac, T0_res, pit_res_max, pit_flag, pit_min, pit_fr2, pit_fr1, L_SUBFR ); @@ -1277,11 +1277,11 @@ void Mode2_pit_encode( { if ( i_subfr == 0 ) { - limit_T0_voiced( 5, pit_res_max >> 1, T_op[0], 0, 1, T0_min, T0_min_frac, T0_max, T0_max_frac, pit_min, pit_max ); + limit_T0_voiced_ivas( 5, pit_res_max >> 1, T_op[0], 0, 1, T0_min, T0_min_frac, T0_max, T0_max_frac, pit_min, pit_max ); } else { - limit_T0_voiced( 5, pit_res_max >> 1, *T0, *T0_frac, *T0_res, T0_min, T0_min_frac, T0_max, T0_max_frac, pit_min, pit_max ); + limit_T0_voiced_ivas( 5, pit_res_max >> 1, *T0, *T0_frac, *T0_res, T0_min, T0_min_frac, T0_max, T0_max_frac, pit_min, pit_max ); } *T0 = E_GAIN_closed_loop_search( exc, xn, h1, *T0_min, *T0_min_frac, *T0_max, *T0_max_frac, pit_res_max >> 1, T0_frac, T0_res, pit_res_max, i_subfr, pit_min, pit_min, pit_fr1b, L_SUBFR ); @@ -1298,11 +1298,11 @@ void Mode2_pit_encode( { if ( i_subfr == 0 ) { - limit_T0_voiced( 4, pit_res_max >> 1, T_op[0], 0, 1, T0_min, T0_min_frac, T0_max, T0_max_frac, pit_min, pit_max ); + limit_T0_voiced_ivas( 4, pit_res_max >> 1, T_op[0], 0, 1, T0_min, T0_min_frac, T0_max, T0_max_frac, pit_min, pit_max ); } else { - limit_T0_voiced( 4, pit_res_max >> 1, *T0, *T0_frac, *T0_res, T0_min, T0_min_frac, T0_max, T0_max_frac, pit_min, pit_max ); + limit_T0_voiced_ivas( 4, pit_res_max >> 1, *T0, *T0_frac, *T0_res, T0_min, T0_min_frac, T0_max, T0_max_frac, pit_min, pit_max ); } *T0 = E_GAIN_closed_loop_search( exc, xn, h1, *T0_min, *T0_min_frac, *T0_max, *T0_max_frac, pit_res_max >> 1, T0_frac, T0_res, pit_res_max, i_subfr, pit_min, pit_min, pit_fr1b, L_SUBFR ); diff --git a/lib_enc/pitch_ol2.c b/lib_enc/pitch_ol2.c index fdeefb83fa8619ca4126383994f5916ea4d9c9dc..6835cbeb3cadb044b16515c6963a073f9ea62355 100644 --- a/lib_enc/pitch_ol2.c +++ b/lib_enc/pitch_ol2.c @@ -149,7 +149,7 @@ void pitch_ol2( } *pitch_fr = t0 + (float) fraction / 4.0f; - pred_lt4( pt_wsp, wsp_fr, t0, fraction, L_SUBFR, E_ROM_inter4_1, 4, PIT_UP_SAMP ); + pred_lt4_flt( pt_wsp, wsp_fr, t0, fraction, L_SUBFR, E_ROM_inter4_1, 4, PIT_UP_SAMP ); enr_wsp = dotp( pt_wsp, pt_wsp, L_SUBFR ) + 0.01f; enr_old = dotp( wsp_fr, wsp_fr, L_SUBFR ) + 0.01f; diff --git a/lib_enc/pre_proc.c b/lib_enc/pre_proc.c index 6199c8a10d1be19662da959a0422e6862db87654..2b36173e2bfa9223c001b140d2a3fbb1db9b49f7 100644 --- a/lib_enc/pre_proc.c +++ b/lib_enc/pre_proc.c @@ -164,7 +164,7 @@ void pre_proc( st->prevEnergyHF = st->currEnergyHF; - analysisCldfbEncoder( st, signal_in, input_frame, realBuffer, imagBuffer, enerBuffer ); + analysisCldfbEncoder_ivas( st, signal_in, input_frame, realBuffer, imagBuffer, enerBuffer ); /*----------------------------------------------------------------* * Change the sampling frequency to 12.8 kHz @@ -594,7 +594,7 @@ void pre_proc( else { SetModeIndex( st, st->last_total_brate, EVS_MONO, 0 ); - st->sr_core = getCoreSamplerateMode2( EVS_MONO, st->total_brate, st->bwidth, st->flag_ACELP16k, st->rf_mode, 0 ); + st->sr_core = getCoreSamplerateMode2_flt( EVS_MONO, st->total_brate, st->bwidth, st->flag_ACELP16k, st->rf_mode, 0 ); st->L_frame = (int16_t) ( st->sr_core / FRAMES_PER_SEC ); st->encoderLookahead_enc = NS2SA( st->sr_core, ACELP_LOOK_NS ); st->encoderPastSamples_enc = ( st->L_frame * 9 ) >> 4; diff --git a/lib_enc/qlpc_stoch.c b/lib_enc/qlpc_stoch.c index 05e7d8ec00a9e00b22b5829bd189eec3d29bfd39..82c8ef3e58fa542bfff251a17e3e71db682e5405 100644 --- a/lib_enc/qlpc_stoch.c +++ b/lib_enc/qlpc_stoch.c @@ -164,7 +164,7 @@ void lpc_quantization( midlsf_enc( st->lsf_old, lsf_q, lsfmid, &lsfmid_idx, M, st->Bin_E_old, st->narrowBand, st->sr_core, coder_type ); param_lpc[nb_indices++] = lsfmid_idx; - midlsf_dec( st->lsf_old, lsf_q, lsfmid_idx, lsfmid_q, M, coder_type, NULL, 0, 1 ); + midlsf_dec_flt( st->lsf_old, lsf_q, lsfmid_idx, lsfmid_q, M, coder_type, NULL, 0, 1 ); reorder_lsf( lsfmid_q, LSF_GAP_MID, M, st->sr_core ); lsf2lsp( lsfmid_q, lspmid_q, M, st->sr_core ); diff --git a/lib_enc/stat_enc.h b/lib_enc/stat_enc.h index 2290475a1f1c2c6cad70b662afe48ddc16fc2283..20cdde9c4ebf7a91d9b1fc847bf4dba8f90d2eb7 100644 --- a/lib_enc/stat_enc.h +++ b/lib_enc/stat_enc.h @@ -1484,7 +1484,6 @@ typedef struct enc_core_structure BSTR_ENC_HANDLE hBstr; /* encoder bitstream handle */ Word16 last_enerBuffer_exp; - Word16 next_bit_pos_fx; /* position of the next bit to be written in the bitstream */ int16_t bitstreamformat; /* Bitstream format flag (G.192/MIME) */ int32_t input_Fs; /* input signal sampling frequency in Hz */ @@ -1538,9 +1537,9 @@ typedef struct enc_core_structure //Word16 last_bwidth_fx; /* input signal bandwidth in the previous frame */ //Word16 last_bwidth_cng_fx; /* input signal bandwidth in the previous inactive frame */ //Word16 L_frame_fx; /* ACELP core internal frame length */ - //Word16 Opt_AMR_WB_fx; /* flag indicating AMR-WB IO mode */ + //Word16 Opt_AMR_WB; /* flag indicating AMR-WB IO mode */ //Word16 Opt_DTX_ON_fx; /* flag indicating DTX operation */ - //Word16 cng_type_fx; /* flag indicating LP or CLDFB based SID/CNG */ + //Word16 cng_type; /* flag indicating LP or CLDFB based SID/CNG */ //Word16 active_fr_cnt_fx; /* counter of active frames */ //Word16 Opt_SC_VBR_fx; /* flag indicating SC-VBR mode */ //Word16 last_Opt_SC_VBR_fx; /* flag indicating SC-VBR mode in the last frame */ diff --git a/lib_enc/subband_fft.c b/lib_enc/subband_fft.c index 638a6d63f830bc1e24cf4575d3e9e201c9296d50..7b7b330dfa9f45cac2cc74ba5f8092f264706d33 100644 --- a/lib_enc/subband_fft.c +++ b/lib_enc/subband_fft.c @@ -43,12 +43,12 @@ /*-------------------------------------------------------------------* - * fft16() + * fft16_flt() * * *-------------------------------------------------------------------*/ -static void fft16( float *r_samp, float *i_samp ) +static void fft16_flt( float *r_samp, float *i_samp ) { int16_t i, j, N, Nv2, nm1, k; float tmpr[16], tmpi[16]; @@ -185,7 +185,7 @@ void subband_FFT( tmpi[j] = Si[j][i]; } - fft16( tmpr, tmpi ); + fft16_flt( tmpr, tmpi ); for ( j = 0; j < 16; j++ ) { diff --git a/lib_enc/swb_pre_proc.c b/lib_enc/swb_pre_proc.c index 7038d964df7d77c0f96dd1f9109083c80f52741a..913a14719e40f341e6b4075626b545ded926b8a5 100644 --- a/lib_enc/swb_pre_proc.c +++ b/lib_enc/swb_pre_proc.c @@ -623,7 +623,7 @@ void swb_pre_proc( thr = icbwe_thr_TDM; regV = icbwe_regressionValuesTDM; - cldfbSynthesis( realBufferFlipped, imagBufferFlipped, shb_speech, -1, st->cldfbSynTd ); + cldfbSynthesis_ivas( realBufferFlipped, imagBufferFlipped, shb_speech, -1, st->cldfbSynTd ); } if ( st->element_mode >= IVAS_CPE_DFT && hCPE->hStereoICBWE != NULL ) diff --git a/lib_enc/swb_tbe_enc.c b/lib_enc/swb_tbe_enc.c index 0b2193fb91232874e3e740f5c6bb980bb2add46e..eabd6be07233a659f6bcb88c4cb111cf7c7c9821 100644 --- a/lib_enc/swb_tbe_enc.c +++ b/lib_enc/swb_tbe_enc.c @@ -708,8 +708,8 @@ void swb_tbe_enc( weights_lsp[4] *= 0.909091f; /* 8-bit VQ, 10 dimension */ - i = closest_centroid( lsf_shb, weights_lsp, swb_tbe_lsfvq_cbook_8b, 256, LPC_SHB_ORDER ); - mvr2r( swb_tbe_lsfvq_cbook_8b + i * LPC_SHB_ORDER, lsf_shb, LPC_SHB_ORDER ); + i = closest_centroid( lsf_shb, weights_lsp, swb_tbe_lsfvq_cbook_8b_flt, 256, LPC_SHB_ORDER ); + mvr2r( swb_tbe_lsfvq_cbook_8b_flt + i * LPC_SHB_ORDER, lsf_shb, LPC_SHB_ORDER ); set_s( hBWE_TD->lsf_idx, 0, NUM_Q_LSF ); @@ -722,7 +722,7 @@ void swb_tbe_enc( hBWE_TD->lsf_idx[0] = i; } - mvr2r( swb_tbe_lsfvq_cbook_8b + i * LPC_SHB_ORDER, lsf_shb, LPC_SHB_ORDER ); + mvr2r( swb_tbe_lsfvq_cbook_8b_flt + i * LPC_SHB_ORDER, lsf_shb, LPC_SHB_ORDER ); } else { @@ -816,7 +816,7 @@ void swb_tbe_enc( if ( st->extl_brate >= SWB_TBE_2k8 ) { /* SHB LSP interpolation */ - ptr_lsp_interp_coef = interpol_frac_shb; + ptr_lsp_interp_coef = interpol_frac_shb_flt; for ( j = 0; j < 4; j++ ) { for ( i = 0; i < LPC_SHB_ORDER; i++ ) diff --git a/lib_enc/tcq_core_enc.c b/lib_enc/tcq_core_enc.c index be8325bf24b63e13fb477d0cea83e3a641ee6b0c..106e92988185799ecea3b4574d54ddf3033574a2 100644 --- a/lib_enc/tcq_core_enc.c +++ b/lib_enc/tcq_core_enc.c @@ -151,7 +151,7 @@ ivas_error tcq_core_LR_enc( /* Bits distribution analysis */ for ( i = 0; i < BANDS; i++ ) { - if ( L_sub( ar_div( Rk_fx[i], sfmsize[i] ), 49152 ) >= 0 ) + if ( L_sub( ar_div_ivas( Rk_fx[i], sfmsize[i] ), 49152 ) >= 0 ) { /* USQ used for high importance bands*/ USQ_TCQ[i] = 1; @@ -185,21 +185,21 @@ ivas_error tcq_core_LR_enc( { if ( Rk_fx[j] > 0 ) { - Rk_fx[j] = L_sub( Rk_fx[j], ar_div( bsub_fx, nzb ) ); + Rk_fx[j] = L_sub( Rk_fx[j], ar_div_ivas( bsub_fx, nzb ) ); if ( Rk_fx[j] < 0 ) { - bsub_fx = L_sub( bsub_fx, L_add( ar_div( bsub_fx, nzb ), Rk_fx[j] ) ); + bsub_fx = L_sub( bsub_fx, L_add( ar_div_ivas( bsub_fx, nzb ), Rk_fx[j] ) ); Rk_fx[j] = 0; } else { - bsub_fx = L_sub( bsub_fx, ar_div( bsub_fx, nzb ) ); + bsub_fx = L_sub( bsub_fx, ar_div_ivas( bsub_fx, nzb ) ); } nzb = sub( nzb, 1 ); } } - srt_vec_ind_fx( Rk_fx, Rk_sort_fx, k_sort, BANDS ); + srt_vec_ind_fx_ivas( Rk_fx, Rk_sort_fx, k_sort, BANDS ); #undef WMC_TOOL_SKIP /* Quantize spectral band shapes using TCQ */ @@ -248,9 +248,9 @@ ivas_error tcq_core_LR_enc( npulses[k_sort[k]] = (int16_t) pulses; - encode_position_ari_fx( parenc, &coefs_norm_dec[sfm_start[k_sort[k]]], size, &est_frame_bits_fx ); - encode_magnitude_tcq_fx( parenc, &coefs_norm_dec[sfm_start[k_sort[k]]], size, npulses[k_sort[k]], (int16_t) nzp, savedstates, &est_frame_bits_fx ); - encode_signs_fx( parenc, &coefs_norm_dec[sfm_start[k_sort[k]]], size, (int16_t) nzp, &est_frame_bits_fx ); + encode_position_ari_fx_ivas( parenc, &coefs_norm_dec[sfm_start[k_sort[k]]], size, &est_frame_bits_fx ); + encode_magnitude_tcq_fx_ivas( parenc, &coefs_norm_dec[sfm_start[k_sort[k]]], size, npulses[k_sort[k]], (int16_t) nzp, savedstates, &est_frame_bits_fx ); + encode_signs_fx_ivas( parenc, &coefs_norm_dec[sfm_start[k_sort[k]]], size, (int16_t) nzp, &est_frame_bits_fx ); nzbands--; } /* Have USQ coded band */ @@ -262,9 +262,9 @@ ivas_error tcq_core_LR_enc( npulses[k_sort[k]] = (int16_t) pulses; - encode_position_ari_fx( parenc, &coefs_norm_dec[sfm_start[k_sort[k]]], size, &est_frame_bits_fx ); - encode_magnitude_usq_fx( parenc, &coefs_norm_dec[sfm_start[k_sort[k]]], size, npulses[k_sort[k]], (int16_t) nzp, &est_frame_bits_fx ); - encode_signs_fx( parenc, &coefs_norm_dec[sfm_start[k_sort[k]]], size, (int16_t) nzp, &est_frame_bits_fx ); + encode_position_ari_fx_ivas( parenc, &coefs_norm_dec[sfm_start[k_sort[k]]], size, &est_frame_bits_fx ); + encode_magnitude_usq_fx_ivas( parenc, &coefs_norm_dec[sfm_start[k_sort[k]]], size, npulses[k_sort[k]], (int16_t) nzp, &est_frame_bits_fx ); + encode_signs_fx_ivas( parenc, &coefs_norm_dec[sfm_start[k_sort[k]]], size, (int16_t) nzp, &est_frame_bits_fx ); nzbands--; } @@ -286,10 +286,10 @@ ivas_error tcq_core_LR_enc( divider = 2; } - IF( L_add( L_add( surplus_fx, sepbits ), ar_div( leftbits, divider ) ) < 0 ) + IF( L_add( L_add( surplus_fx, sepbits ), ar_div_ivas( leftbits, divider ) ) < 0 ) { /* Overflow possible => start to distribute negative surplus */ - delta_fx = ar_div( surplus_fx + sepbits, nzbands ); + delta_fx = ar_div_ivas( surplus_fx + sepbits, nzbands ); } else { @@ -337,9 +337,9 @@ ivas_error tcq_core_LR_enc( npulses[k_sort[k]] = (int16_t) pulses; - encode_position_ari_fx( parenc, &coefs_norm_dec[sfm_start[k_sort[k]]], size, &est_frame_bits_fx ); - encode_magnitude_tcq_fx( parenc, &coefs_norm_dec[sfm_start[k_sort[k]]], size, npulses[k_sort[k]], (int16_t) nzp, savedstates, &est_frame_bits_fx ); - encode_signs_fx( parenc, &coefs_norm_dec[sfm_start[k_sort[k]]], size, (int16_t) nzp, &est_frame_bits_fx ); + encode_position_ari_fx_ivas( parenc, &coefs_norm_dec[sfm_start[k_sort[k]]], size, &est_frame_bits_fx ); + encode_magnitude_tcq_fx_ivas( parenc, &coefs_norm_dec[sfm_start[k_sort[k]]], size, npulses[k_sort[k]], (int16_t) nzp, savedstates, &est_frame_bits_fx ); + encode_signs_fx_ivas( parenc, &coefs_norm_dec[sfm_start[k_sort[k]]], size, (int16_t) nzp, &est_frame_bits_fx ); } /* Have USQ coded band */ else if ( Rk_fx[k_sort[k]] > 0 && sub( USQ_TCQ[k_sort[k]], 1 ) == 0 ) @@ -350,9 +350,9 @@ ivas_error tcq_core_LR_enc( npulses[k_sort[k]] = (int16_t) pulses; - encode_position_ari_fx( parenc, &coefs_norm_dec[sfm_start[k_sort[k]]], size, &est_frame_bits_fx ); - encode_magnitude_usq_fx( parenc, &coefs_norm_dec[sfm_start[k_sort[k]]], size, npulses[k_sort[k]], (int16_t) nzp, &est_frame_bits_fx ); - encode_signs_fx( parenc, &coefs_norm_dec[sfm_start[k_sort[k]]], size, (int16_t) nzp, &est_frame_bits_fx ); + encode_position_ari_fx_ivas( parenc, &coefs_norm_dec[sfm_start[k_sort[k]]], size, &est_frame_bits_fx ); + encode_magnitude_usq_fx_ivas( parenc, &coefs_norm_dec[sfm_start[k_sort[k]]], size, npulses[k_sort[k]], (int16_t) nzp, &est_frame_bits_fx ); + encode_signs_fx_ivas( parenc, &coefs_norm_dec[sfm_start[k_sort[k]]], size, (int16_t) nzp, &est_frame_bits_fx ); } else /* Then have zero block */ { @@ -377,9 +377,9 @@ ivas_error tcq_core_LR_enc( GetISCScale( &coefs_quant[sfm_start[k_sort[k]]], size, L_add( Rk_fx[k_sort[k]], delta_fx ), &coefs_norm_dec[sfm_start[k_sort[k]]], &step_scale[k_sort[k]], &surplus_fx, &pulses, savedstates, 1, &nzp, &bcount, abuffer, mbuffer, sbuffer ); npulses[k_sort[k]] = (int16_t) pulses; - encode_position_ari_fx( parenc, &coefs_norm_dec[sfm_start[k_sort[k]]], size, &est_frame_bits_fx ); - encode_magnitude_usq_fx( parenc, &coefs_norm_dec[sfm_start[k_sort[k]]], size, npulses[k_sort[k]], (int16_t) nzp, &est_frame_bits_fx ); - encode_signs_fx( parenc, &coefs_norm_dec[sfm_start[k_sort[k]]], size, (int16_t) nzp, &est_frame_bits_fx ); + encode_position_ari_fx_ivas( parenc, &coefs_norm_dec[sfm_start[k_sort[k]]], size, &est_frame_bits_fx ); + encode_magnitude_usq_fx_ivas( parenc, &coefs_norm_dec[sfm_start[k_sort[k]]], size, npulses[k_sort[k]], (int16_t) nzp, &est_frame_bits_fx ); + encode_signs_fx_ivas( parenc, &coefs_norm_dec[sfm_start[k_sort[k]]], size, (int16_t) nzp, &est_frame_bits_fx ); /* nzbands--; */ nzbands = sub( (int16_t) nzbands, 1 ); } @@ -392,7 +392,7 @@ ivas_error tcq_core_LR_enc( /* Surplus distribution */ if ( surplus_fx > 0 && nzbands > 0 ) { - delta_fx = ar_div( surplus_fx, nzbands ); + delta_fx = ar_div_ivas( surplus_fx, nzbands ); surplus_fx = L_sub( surplus_fx, delta_fx ); } } diff --git a/lib_enc/tcx_ltp_enc.c b/lib_enc/tcx_ltp_enc.c index e9b1112d61bd2f787f5b1cfe5024782940f9834d..50232a7841fef4b44ee915da3766174d4db19873 100644 --- a/lib_enc/tcx_ltp_enc.c +++ b/lib_enc/tcx_ltp_enc.c @@ -444,7 +444,7 @@ void tcx_ltp_encode( } /* Find predicted signal */ - predict_signal( speech, pred_speech, hTcxEnc->tcxltp_pitch_int, hTcxEnc->tcxltp_pitch_fr, st->pit_res_max, L_frame ); + predict_signal_flt( speech, pred_speech, hTcxEnc->tcxltp_pitch_int, hTcxEnc->tcxltp_pitch_fr, st->pit_res_max, L_frame ); /* Find gain */ tcx_ltp_find_gain( speech, pred_speech, L_frame, &hTcxEnc->tcxltp_gain_flt, <p_param[2] ); @@ -528,7 +528,7 @@ void tcx_ltp_encode( if ( hTcxEnc->tcxltp_gain_flt > 0.f ) { - predict_signal( speech - M, buf_zir, hTcxEnc->tcxltp_pitch_int, hTcxEnc->tcxltp_pitch_fr, st->pit_res_max, M ); + predict_signal_flt( speech - M, buf_zir, hTcxEnc->tcxltp_pitch_int, hTcxEnc->tcxltp_pitch_fr, st->pit_res_max, M ); } else { diff --git a/lib_enc/tcx_utils_enc.c b/lib_enc/tcx_utils_enc.c index ad2e2855811440bd412322d81509b70a751275d3..444a2b177b27d952ea81c974f205c6e15c543c55 100644 --- a/lib_enc/tcx_utils_enc.c +++ b/lib_enc/tcx_utils_enc.c @@ -185,7 +185,7 @@ void AnalyzePowerSpectrum( iStart = 0; iEnd = L_frameTCX; - TCX_MDST( signal, powerSpec, left_overlap, L_frameTCX - ( left_overlap + right_overlap ) / 2, right_overlap, st->element_mode ); + TCX_MDST_flt( signal, powerSpec, left_overlap, L_frameTCX - ( left_overlap + right_overlap ) / 2, right_overlap, st->element_mode ); if ( st->narrowBand ) { @@ -1249,12 +1249,12 @@ int16_t tcx_res_Q_gain( if ( sqGain < gain_reQ ) { prm[bits] = 0; - gain_reQ *= gain_corr_inv_fac[bits]; + gain_reQ *= gain_corr_inv_fac_flt[bits]; } else { prm[bits] = 1; - gain_reQ *= gain_corr_fac[bits]; + gain_reQ *= gain_corr_fac_flt[bits]; } if ( bits < sqTargetBits ) { diff --git a/lib_enc/transition_enc.c b/lib_enc/transition_enc.c index c02e94047802c3fe6a040505c00cce4d591bffc1..8b39e72ab0b2279fce9b73208172c2cf2603f536 100644 --- a/lib_enc/transition_enc.c +++ b/lib_enc/transition_enc.c @@ -41,6 +41,7 @@ #include "rom_com.h" #include "prot.h" #include "wmc_auto.h" +#include "prot_fx2.h" /*-----------------------------------------------------------------* * Local function prototypes @@ -327,7 +328,7 @@ void transition_enc( push_indice( hBstr, IND_PITCH, index, nBits ); /* Find the adaptive codebook vector - ACELP long-term prediction */ - pred_lt4( &exc[i_subfr], &exc[i_subfr], *T0, *T0_frac, L_SUBFR + 1, inter4_2, L_INTERPOL2, PIT_UP_SAMP ); + pred_lt4_flt( &exc[i_subfr], &exc[i_subfr], *T0, *T0_frac, L_SUBFR + 1, inter4_2, L_INTERPOL2, PIT_UP_SAMP ); offset = tbe_celp_exc_offset_flt( *T0, *T0_frac ); for ( i = 0; i < L_SUBFR * HIBND_ACB_L_FAC; i++ ) @@ -367,7 +368,7 @@ void transition_enc( push_indice( hBstr, IND_PITCH, index, nBits ); /* Find the adaptive codebook vector - ACELP long-term prediction */ - pred_lt4( &exc[i_subfr], &exc[i_subfr], *T0, *T0_frac, L_SUBFR + 1, inter4_2, L_INTERPOL2, PIT_UP_SAMP ); + pred_lt4_flt( &exc[i_subfr], &exc[i_subfr], *T0, *T0_frac, L_SUBFR + 1, inter4_2, L_INTERPOL2, PIT_UP_SAMP ); offset = tbe_celp_exc_offset_flt( *T0, *T0_frac ); for ( i = 0; i < L_SUBFR * HIBND_ACB_L_FAC; i++ ) @@ -423,7 +424,7 @@ void transition_enc( push_indice( hBstr, IND_PITCH, index, nBits ); /* Find the adaptive codebook vector - ACELP long-term prediction */ - pred_lt4( &exc[i_subfr], &exc[i_subfr], *T0, *T0_frac, L_SUBFR + 1, inter4_2, L_INTERPOL2, PIT_UP_SAMP ); + pred_lt4_flt( &exc[i_subfr], &exc[i_subfr], *T0, *T0_frac, L_SUBFR + 1, inter4_2, L_INTERPOL2, PIT_UP_SAMP ); offset = tbe_celp_exc_offset_flt( *T0, *T0_frac ); for ( i = 0; i < L_SUBFR * HIBND_ACB_L_FAC; i++ ) @@ -444,7 +445,7 @@ void transition_enc( push_indice( hBstr, IND_PITCH, index, nBits ); /* Find the adaptive codebook vector - ACELP long-term prediction */ - pred_lt4( &exc[i_subfr], &exc[i_subfr], *T0, *T0_frac, L_SUBFR + 1, inter4_2, L_INTERPOL2, PIT_UP_SAMP ); + pred_lt4_flt( &exc[i_subfr], &exc[i_subfr], *T0, *T0_frac, L_SUBFR + 1, inter4_2, L_INTERPOL2, PIT_UP_SAMP ); offset = tbe_celp_exc_offset_flt( *T0, *T0_frac ); for ( i = 0; i < L_SUBFR * HIBND_ACB_L_FAC; i++ ) @@ -474,7 +475,7 @@ void transition_enc( pit_Q_enc( hBstr, 0, nBits, 8, pit_flag, limit_flag, *T0, *T0_frac, T0_min, T0_max ); /* Find the adaptive codebook vector - ACELP long-term prediction */ - pred_lt4( &exc[i_subfr], &exc[i_subfr], *T0, *T0_frac, L_SUBFR + 1, inter4_2, L_INTERPOL2, PIT_UP_SAMP ); + pred_lt4_flt( &exc[i_subfr], &exc[i_subfr], *T0, *T0_frac, L_SUBFR + 1, inter4_2, L_INTERPOL2, PIT_UP_SAMP ); offset = tbe_celp_exc_offset_flt( *T0, *T0_frac ); for ( i = 0; i < L_SUBFR * HIBND_ACB_L_FAC; i++ ) @@ -657,7 +658,7 @@ void transition_enc( else { /* Find the adaptive codebook vector - ACELP long-term prediction */ - pred_lt4( &exc[i_subfr], &exc[i_subfr], *T0, *T0_frac, L_SUBFR + 1, inter4_2, L_INTERPOL2, PIT_UP_SAMP ); + pred_lt4_flt( &exc[i_subfr], &exc[i_subfr], *T0, *T0_frac, L_SUBFR + 1, inter4_2, L_INTERPOL2, PIT_UP_SAMP ); for ( i = 0; i < L_SUBFR * 2; i++ ) { @@ -823,7 +824,7 @@ static void tc_enc( * (when appears) *--------------------------------------------------------------*/ - pred_lt4_tc( exc, *T0, *T0_frac, inter4_2, imp_pos, i_subfr ); + pred_lt4_tc_flt( exc, *T0, *T0_frac, inter4_2, imp_pos, i_subfr ); if ( st->hBWE_TD != NULL ) { diff --git a/lib_enc/updt_enc.c b/lib_enc/updt_enc.c index 674403f7ce4190e869b12581393544be5d5444a6..9ce40f78bfa6d207df0a0e0daec52c0d914541cd 100644 --- a/lib_enc/updt_enc.c +++ b/lib_enc/updt_enc.c @@ -354,7 +354,7 @@ void updt_enc_common( { st->hTdCngEnc->CNG_att = 0.0f; - apply_scale( &st->hTdCngEnc->CNG_att, st->hFdCngEnc->hFdCngCom->CngBandwidth, st->hFdCngEnc->hFdCngCom->CngBitrate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO ); + apply_scale_flt( &st->hTdCngEnc->CNG_att, st->hFdCngEnc->hFdCngCom->CngBandwidth, st->hFdCngEnc->hFdCngCom->CngBitrate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO ); } } } @@ -390,7 +390,7 @@ void updt_enc_common( { st->codec_mode = MODE2; - st->sr_core = getCoreSamplerateMode2( EVS_MONO, st->total_brate, st->bwidth, st->flag_ACELP16k, st->rf_mode, 0 ); + st->sr_core = getCoreSamplerateMode2_flt( EVS_MONO, st->total_brate, st->bwidth, st->flag_ACELP16k, st->rf_mode, 0 ); st->L_frame = (int16_t) ( st->sr_core / FRAMES_PER_SEC ); diff --git a/lib_enc/vlpc_1st_cod.c b/lib_enc/vlpc_1st_cod.c index 84afcd8164b47459e25fe430a704bf8c4b990874..b0a57526ee7a864f15e79cae66d9be246a5a7031 100644 --- a/lib_enc/vlpc_1st_cod.c +++ b/lib_enc/vlpc_1st_cod.c @@ -113,7 +113,7 @@ int16_t vlpc_1st_cod( } dist_min = 1.0e30f; - p_dico = dico_lsf_abs_8b; + p_dico = dico_lsf_abs_8b_flt; index = 0; for ( i = 0; i < 256; i++ ) @@ -134,7 +134,7 @@ int16_t vlpc_1st_cod( } /* quantized vector */ - p_dico = &dico_lsf_abs_8b[index * M]; + p_dico = &dico_lsf_abs_8b_flt[index * M]; for ( j = 0; j < M; j++ ) { diff --git a/lib_enc/vlpc_2st_cod.c b/lib_enc/vlpc_2st_cod.c index 2197c13c41ef28c884e41cae163f09fc322c6a49..6b34b65b2677d13e61575c493f3c786bb88525c4 100644 --- a/lib_enc/vlpc_2st_cod.c +++ b/lib_enc/vlpc_2st_cod.c @@ -63,7 +63,7 @@ int16_t vlpc_2st_cod( /* 0 bit with true weighting: save 0.5 bit */ - lsf_weight_2st( lsf, w, 1, sr_core ); + lsf_weight_2st_flt( lsf, w, 1, sr_core ); for ( i = 0; i < M; i++ ) { @@ -91,7 +91,7 @@ int16_t vlpc_2st_cod( } /* weighting from the 1st stage */ - lsf_weight_2st( lsfq, w, mode, sr_core ); + lsf_weight_2st_flt( lsfq, w, mode, sr_core ); /* find lsf residual */ diff --git a/lib_rend/ivas_dirac_ana.c b/lib_rend/ivas_dirac_ana.c index f848b59ce34da419e38673a41a75beba8d99dadd..667a0a47de8338aedb22dff6be6355b8366cdc65 100644 --- a/lib_rend/ivas_dirac_ana.c +++ b/lib_rend/ivas_dirac_ana.c @@ -100,7 +100,7 @@ ivas_error ivas_dirac_ana_open( hDirAC->num_Cldfb_instances = numAnalysisChannels; for ( i = 0; i < hDirAC->num_Cldfb_instances; i++ ) { - if ( ( error = openCldfb( &( hDirAC->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) + if ( ( error = openCldfb_ivas( &( hDirAC->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) { return error; } @@ -176,7 +176,7 @@ void ivas_dirac_ana_close( for ( i = 0; i < ( *hDirAC )->num_Cldfb_instances; i++ ) { - deleteCldfb( &( ( *hDirAC )->cldfbAnaEnc[i] ) ); + deleteCldfb_ivas( &( ( *hDirAC )->cldfbAnaEnc[i] ) ); } for ( i = 0; i < DIRAC_NUM_DIMS; i++ ) @@ -303,7 +303,7 @@ static void ivas_dirac_param_est_ana( { for ( i = 0; i < numAnalysisChannels; i++ ) { - cldfbAnalysis_ts( &( data_f[i][l_ts * ts] ), Foa_RealBuffer[i], Foa_ImagBuffer[i], l_ts, hDirAC->cldfbAnaEnc[i] ); + cldfbAnalysis_ts_ivas( &( data_f[i][l_ts * ts] ), Foa_RealBuffer[i], Foa_ImagBuffer[i], l_ts, hDirAC->cldfbAnaEnc[i] ); } /* Compute omni energy for metadata processing */ diff --git a/lib_rend/ivas_dirac_dec_binaural_functions.c b/lib_rend/ivas_dirac_dec_binaural_functions.c index 988b655d60d82541a0d3195ff3769eb5a8ffdb42..9897756c965e869067fd78ee31d24f1110e2b936 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions.c @@ -559,7 +559,7 @@ static void ivas_dirac_dec_binaural_internal( { if ( ch == 0 || nchan_transport == 2 ) { - cldfbAnalysis_ts( + cldfbAnalysis_ts_ivas( &( st_ivas->hTcBuffer->tc[ch][nBins * slot + offsetSamples] ), Cldfb_RealBuffer_in[ch][slot], Cldfb_ImagBuffer_in[ch][slot], @@ -636,7 +636,7 @@ static void ivas_dirac_dec_binaural_internal( { for ( ch = BINAURAL_CHANNELS; ch < ( 2 * BINAURAL_CHANNELS ); ch++ ) { - cldfbAnalysis_ts( + cldfbAnalysis_ts_ivas( &( st_ivas->hTcBuffer->tc[ch][nBins * slot + offsetSamples] ), Cldfb_RealBuffer_in[ch][slot], Cldfb_ImagBuffer_in[ch][slot], @@ -1597,7 +1597,7 @@ static void ivas_dirac_dec_binaural_process_output( outSlotImPr = &( outSlotIm[0] ); /* Inverse filter bank */ - cldfbSynthesis( &outSlotRePr, &outSlotImPr, &( output_f[chA][nBins * slot + offsetSamples] ), nBins, cldfbSynDec[chA] ); + cldfbSynthesis_ivas( &outSlotRePr, &outSlotImPr, &( output_f[chA][nBins * slot + offsetSamples] ), nBins, cldfbSynDec[chA] ); } } @@ -2647,7 +2647,7 @@ static void ivas_masa_ext_rend_parambin_internal( { if ( ch == 0 || nchan_transport == 2 ) { - cldfbAnalysis_ts( + cldfbAnalysis_ts_ivas( &( output_f[ch][nBins * slot] ), Cldfb_RealBuffer_in[ch][slot], Cldfb_ImagBuffer_in[ch][slot], diff --git a/lib_rend/ivas_dirac_rend.c b/lib_rend/ivas_dirac_rend.c index b998b9636ebc828fc988ca3fb9ef32304aefa2b1..ef756204fde276d4afbe788da2b136ba0c718514 100644 --- a/lib_rend/ivas_dirac_rend.c +++ b/lib_rend/ivas_dirac_rend.c @@ -2226,7 +2226,7 @@ static void ivas_masa_ext_dirac_render_sf( /* CLDFB Analysis*/ for ( ch = 0; ch < nchan_transport; ch++ ) { - cldfbAnalysis_ts( &( output_f[ch][hSpatParamRendCom->num_freq_bands * index_slot] ), + cldfbAnalysis_ts_ivas( &( output_f[ch][hSpatParamRendCom->num_freq_bands * index_slot] ), Cldfb_RealBuffer[ch][0], Cldfb_ImagBuffer[ch][0], hSpatParamRendCom->num_freq_bands, @@ -2451,7 +2451,7 @@ static void ivas_masa_ext_dirac_render_sf( RealBuffer[i] = Cldfb_RealBuffer[idx_in][i]; ImagBuffer[i] = Cldfb_ImagBuffer[idx_in][i]; } - cldfbSynthesis( RealBuffer, ImagBuffer, &( output_f[ch][index_slot * hSpatParamRendCom->num_freq_bands] ), hSpatParamRendCom->num_freq_bands * hSpatParamRendCom->subframe_nbslots[subframe_idx], hMasaExtRend->cldfbSynRend[idx_in] ); + cldfbSynthesis_ivas( RealBuffer, ImagBuffer, &( output_f[ch][index_slot * hSpatParamRendCom->num_freq_bands] ), hSpatParamRendCom->num_freq_bands * hSpatParamRendCom->subframe_nbslots[subframe_idx], hMasaExtRend->cldfbSynRend[idx_in] ); idx_in++; } } diff --git a/lib_rend/ivas_masa_merge.c b/lib_rend/ivas_masa_merge.c index 434dca3fbf0ac939e8b848361377220259c989c2..27cf31a9fb598d54d858eb440a03fdb0feddb115 100644 --- a/lib_rend/ivas_masa_merge.c +++ b/lib_rend/ivas_masa_merge.c @@ -332,7 +332,7 @@ ivas_error masaPrerendOpen( hMasaPrerend->num_Cldfb_instances = numTransports; for ( i = 0; i < hMasaPrerend->num_Cldfb_instances; i++ ) { - if ( ( error = openCldfb( &( hMasaPrerend->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) + if ( ( error = openCldfb_ivas( &( hMasaPrerend->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) { return error; } @@ -381,7 +381,7 @@ void masaPrerendClose( for ( i = 0; i < ( *hMasaPrerendPtr )->num_Cldfb_instances; i++ ) { - deleteCldfb( &( ( *hMasaPrerendPtr )->cldfbAnaEnc[i] ) ); + deleteCldfb_ivas( &( ( *hMasaPrerendPtr )->cldfbAnaEnc[i] ) ); } free( ( *hMasaPrerendPtr )->hMasaOut ); diff --git a/lib_rend/ivas_mcmasa_ana.c b/lib_rend/ivas_mcmasa_ana.c index d0dd9787d37faf58272f9cf974e1031dbdbd6d98..4187f1d360dd856011121372261afdee5f16de82 100644 --- a/lib_rend/ivas_mcmasa_ana.c +++ b/lib_rend/ivas_mcmasa_ana.c @@ -170,7 +170,7 @@ ivas_error ivas_mcmasa_ana_open( hMcMasa->num_Cldfb_instances = numAnalysisChannels; for ( i = 0; i < hMcMasa->num_Cldfb_instances; i++ ) { - if ( ( error = openCldfb( &( hMcMasa->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) + if ( ( error = openCldfb_ivas( &( hMcMasa->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) { return error; } @@ -318,7 +318,7 @@ void ivas_mcmasa_ana_close( for ( i = 0; i < ( *hMcMasa )->num_Cldfb_instances; i++ ) { - deleteCldfb( &( ( *hMcMasa )->cldfbAnaEnc[i] ) ); + deleteCldfb_ivas( &( ( *hMcMasa )->cldfbAnaEnc[i] ) ); } /* intensity 3-dim */ @@ -492,7 +492,7 @@ void ivas_mcmasa_param_est_ana( { for ( i = 0; i < numAnalysisChannels; i++ ) { - cldfbAnalysis_ts( &( data_f[i][l_ts * ts] ), Chnl_RealBuffer[i], Chnl_ImagBuffer[i], l_ts, hMcMasa->cldfbAnaEnc[i] ); + cldfbAnalysis_ts_ivas( &( data_f[i][l_ts * ts] ), Chnl_RealBuffer[i], Chnl_ImagBuffer[i], l_ts, hMcMasa->cldfbAnaEnc[i] ); } /* Compute channel-based energy for metadata processing */ diff --git a/lib_rend/ivas_omasa_ana.c b/lib_rend/ivas_omasa_ana.c index dd29384c6a372e0b43515f45d67bd4e8a30a5765..8c4c5a458438e712f2e9cf2d0d75bd59d6b23fbb 100644 --- a/lib_rend/ivas_omasa_ana.c +++ b/lib_rend/ivas_omasa_ana.c @@ -102,7 +102,7 @@ ivas_error ivas_omasa_ana_open( hOMasa->num_Cldfb_instances = numAnalysisChannels; for ( i = 0; i < hOMasa->num_Cldfb_instances; i++ ) { - if ( ( error = openCldfb( &( hOMasa->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) + if ( ( error = openCldfb_ivas( &( hOMasa->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) { return error; } @@ -202,7 +202,7 @@ void ivas_omasa_ana_close( for ( i = 0; i < ( *hOMasa )->num_Cldfb_instances; i++ ) { - deleteCldfb( &( ( *hOMasa )->cldfbAnaEnc[i] ) ); + deleteCldfb_ivas( &( ( *hOMasa )->cldfbAnaEnc[i] ) ); } for ( i = 0; i < DIRAC_NUM_DIMS; i++ ) @@ -340,7 +340,7 @@ static void ivas_omasa_param_est_ana( { for ( i = 0; i < nchan_ism; i++ ) { - cldfbAnalysis_ts( &( data_f[i][l_ts * ts] ), Chnl_RealBuffer[i], Chnl_ImagBuffer[i], l_ts, hOMasa->cldfbAnaEnc[i] ); + cldfbAnalysis_ts_ivas( &( data_f[i][l_ts * ts] ), Chnl_RealBuffer[i], Chnl_ImagBuffer[i], l_ts, hOMasa->cldfbAnaEnc[i] ); } /* Compute channel-based energy for metadata processing */ diff --git a/lib_rend/ivas_reverb_utils.c b/lib_rend/ivas_reverb_utils.c index 3bdc9b2af982b45c4f7e125bc66d9006ec679d48..6078044d8076efe7794b453f335c1148f0d517c4 100644 --- a/lib_rend/ivas_reverb_utils.c +++ b/lib_rend/ivas_reverb_utils.c @@ -310,15 +310,15 @@ static ivas_error get_IR_from_filter_taps( } } - if ( ( error = openCldfb( &handle_cldfb_analysis, CLDFB_ANALYSIS, sampling_rate, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) + if ( ( error = openCldfb_ivas( &handle_cldfb_analysis, CLDFB_ANALYSIS, sampling_rate, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) { return error; } - if ( ( error = openCldfb( &handle_cldfb_synthesis_l, CLDFB_SYNTHESIS, sampling_rate, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) + if ( ( error = openCldfb_ivas( &handle_cldfb_synthesis_l, CLDFB_SYNTHESIS, sampling_rate, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) { return error; } - if ( ( error = openCldfb( &handle_cldfb_synthesis_r, CLDFB_SYNTHESIS, sampling_rate, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) + if ( ( error = openCldfb_ivas( &handle_cldfb_synthesis_r, CLDFB_SYNTHESIS, sampling_rate, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) { return error; } @@ -329,7 +329,7 @@ static ivas_error get_IR_from_filter_taps( float *ppRealBuf[1]; float *ppImagBuf[1]; - cldfbAnalysis_ts( &dirac_pls[input_sample_idx], real_buffer_in, imag_buffer_in, block_len, handle_cldfb_analysis ); + cldfbAnalysis_ts_ivas( &dirac_pls[input_sample_idx], real_buffer_in, imag_buffer_in, block_len, handle_cldfb_analysis ); /* Perform convolution */ @@ -346,11 +346,11 @@ static ivas_error get_IR_from_filter_taps( ppRealBuf[0] = out_CLDFB_real[0]; ppImagBuf[0] = out_CLDFB_imag[0]; - cldfbSynthesis( ppRealBuf, ppImagBuf, &pOut_l[output_sample_idx], block_len, handle_cldfb_synthesis_l ); + cldfbSynthesis_ivas( ppRealBuf, ppImagBuf, &pOut_l[output_sample_idx], block_len, handle_cldfb_synthesis_l ); ppRealBuf[0] = out_CLDFB_real[1]; ppImagBuf[0] = out_CLDFB_imag[1]; - cldfbSynthesis( ppRealBuf, ppImagBuf, &pOut_r[output_sample_idx], block_len, handle_cldfb_synthesis_r ); + cldfbSynthesis_ivas( ppRealBuf, ppImagBuf, &pOut_r[output_sample_idx], block_len, handle_cldfb_synthesis_r ); if ( input_sample_idx == 0 ) { @@ -363,9 +363,9 @@ static ivas_error get_IR_from_filter_taps( } } - deleteCldfb( &handle_cldfb_analysis ); - deleteCldfb( &handle_cldfb_synthesis_l ); - deleteCldfb( &handle_cldfb_synthesis_r ); + deleteCldfb_ivas( &handle_cldfb_analysis ); + deleteCldfb_ivas( &handle_cldfb_synthesis_l ); + deleteCldfb_ivas( &handle_cldfb_synthesis_r ); return IVAS_ERR_OK; } diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 4ffc2cc076de0b07214f364119acc08d6d715e1d..c6f6b4b4169a40877ef3f126fbd35a9861db1d65 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -5807,7 +5807,7 @@ static void renderMasaToMasa( { for ( i = 0; i < numAnalysisChannels; i++ ) { - cldfbAnalysis_ts( &( tmpBuffer[i][l_ts * ts] ), Chan_RealBuffer[i], Chan_ImagBuffer[i], l_ts, masaInput->hMasaPrerend->cldfbAnaEnc[i] ); + cldfbAnalysis_ts_ivas( &( tmpBuffer[i][l_ts * ts] ), Chan_RealBuffer[i], Chan_ImagBuffer[i], l_ts, masaInput->hMasaPrerend->cldfbAnaEnc[i] ); } /* Compute channel energy for metadata processing */ @@ -6986,7 +6986,7 @@ static ivas_error initMasaExtRenderer( { for ( i = 0; i < hMasaExtRend->nchan_input; i++ ) { - if ( ( error = openCldfb( &( hMasaExtRend->cldfbAnaRend[i] ), CLDFB_ANALYSIS, *inputMasa->base.ctx.pOutSampleRate, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) + if ( ( error = openCldfb_ivas( &( hMasaExtRend->cldfbAnaRend[i] ), CLDFB_ANALYSIS, *inputMasa->base.ctx.pOutSampleRate, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) { return error; } @@ -6994,7 +6994,7 @@ static ivas_error initMasaExtRenderer( for ( i = 0; i < hMasaExtRend->nchan_output; i++ ) { - if ( ( error = openCldfb( &( hMasaExtRend->cldfbSynRend[i] ), CLDFB_SYNTHESIS, *inputMasa->base.ctx.pOutSampleRate, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) + if ( ( error = openCldfb_ivas( &( hMasaExtRend->cldfbSynRend[i] ), CLDFB_SYNTHESIS, *inputMasa->base.ctx.pOutSampleRate, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) { return error; } @@ -7059,7 +7059,7 @@ static void freeMasaExtRenderer( { if ( hMasaExtRend->cldfbAnaRend[i] != NULL ) { - deleteCldfb( &hMasaExtRend->cldfbAnaRend[i] ); + deleteCldfb_ivas( &hMasaExtRend->cldfbAnaRend[i] ); } } @@ -7067,7 +7067,7 @@ static void freeMasaExtRenderer( { if ( hMasaExtRend->cldfbSynRend[i] != NULL ) { - deleteCldfb( &hMasaExtRend->cldfbSynRend[i] ); + deleteCldfb_ivas( &hMasaExtRend->cldfbSynRend[i] ); } }