Commit 6cfcf27f authored by Sandesh Venkatesh's avatar Sandesh Venkatesh
Browse files

Functions in stereo_mdct_core_dec and sub-funcs converted to fxd

[x] Functions is ivas_stereo_mdct_core_dec and related sub
functions converted to fixed point.
[x] ivas_mdct_core_tns_ns function is partially ported and
untested yet. So function call is disabled currently.
parent 3471d7c7
Loading
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -2605,11 +2605,19 @@ void InitPsychLPC(
    const TCX_CONFIG_HANDLE hTcxCfg                             /* i  : TCX configuration handle                */
);

#ifndef IVAS_FLOAT_FIXED
void SetCurrentPsychParams(
    const int16_t core,
    const int16_t last_frame_was_concealed_cng,
    TCX_CONFIG_HANDLE hTcxCfg 
);
#else
void SetCurrentPsychParams(
    const Word16 core,
    const Word16 last_frame_was_concealed_cng,
    TCX_CONFIG_HANDLE hTcxCfg
);
#endif

void stereo_coder_tcx(
    STEREO_MDCT_ENC_DATA_HANDLE hStereoMdct,                    /* i/o: MDCT encoder structure                  */
+44 −0
Original line number Diff line number Diff line
@@ -1154,4 +1154,48 @@ void stereo_icBWE_dec_fx(
  Word16 *Q_syn
  );
  
void decoder_tcx_tns_fx(
    Decoder_State *st,         /* i/o: coder memory state                      */
    const Word16 L_frame_glob, /* i  : frame length                            */
    const Word16 L_spec,
    const Word16 L_frame,
    const Word16 L_frameTCX,
    Word32 x_fx[N_MAX],
    const Word16 fUseTns, /* i  : flag that is set if TNS data is present */
    STnsData *tnsData,
    const Word16 bfi,       /* i  : Bad frame indicator                     */
    const Word16 frame_cnt, /* i  : frame counter in the super frame        */
    const Word16 whitenedDomain );

void ivas_mdct_core_tns_ns_fx(
    CPE_DEC_HANDLE hCPE,                                     /* i/o: CPE decoder structure                  */
    Word16 fUseTns[CPE_CHANNELS][NB_DIV],                   /* i  : two entries for each channel in TCX10  */
    STnsData tnsData[CPE_CHANNELS][NB_DIV],                  /* o  : TNS parameter                          */
    Word32 *x_fx[CPE_CHANNELS][NB_DIV],                          /* o  : synthesis @internal_FS                 */
    Word32 Aq_fx[CPE_CHANNELS][(NB_SUBFR16k + 1) * (M + 1)], /* o  : LP coefficients                        */
    const Word16 MCT_flag,                                   /* i  : hMCT handle allocated (1) or not (0)   */
    Word16 x_e[CPE_CHANNELS][NB_DIV]
);

void decoder_tcx_imdct_fx(
    Decoder_State *st,          /* i/o: coder memory state                      */
    const int16_t L_frame_glob, /* i  : frame length                            */
    const int16_t L_frameTCX_glob,
    const int16_t L_spec,
    const int16_t tcx_offset,
    const int16_t tcx_offsetFB,
    const int16_t L_frame,
    const int16_t L_frameTCX,
    const int16_t left_rect,
    float x[N_MAX],
    float xn_buf[],
    const uint16_t kernelType, /* i  : TCX transform kernel type               */
    const int16_t fUseTns,     /* i  : flag that is set if TNS data is present */
    float synth[],             /* i/o: synth[-M..L_frame]                      */
    float synthFB[],
    const int16_t bfi,                  /* i  :  Bad frame indicator                    */
    const int16_t frame_cnt,            /* i  : frame counter in the super frame        */
    const int16_t sba_dirac_stereo_flag /* i  : signal stereo output for SBA DirAC      */
);

#endif
+20 −0
Original line number Diff line number Diff line
@@ -140,6 +140,7 @@ void InitPsychLPC(
 *
 *-------------------------------------------------------------------*/

#ifndef IVAS_FLOAT_FIXED
void SetCurrentPsychParams(
    const int16_t core,
    const int16_t last_frame_was_concealed_cng,
@@ -157,3 +158,22 @@ void SetCurrentPsychParams(

    return;
}
#else
void SetCurrentPsychParams(
    const Word16 core,
    const Word16 last_frame_was_concealed_cng,
    TCX_CONFIG_HANDLE hTcxCfg )
{
    IF ( EQ_16(hTcxCfg->tcx_last_overlap_mode, TRANSITION_OVERLAP) && EQ_16(last_frame_was_concealed_cng, 0) )
    {
        assert( core == TCX_20_CORE );
        hTcxCfg->psychParamsCurrent = &hTcxCfg->psychParamsTCX20AfterACELP;
    }
    ELSE
    {
        hTcxCfg->psychParamsCurrent = ( EQ_16(core, TCX_10_CORE) ) ? &hTcxCfg->psychParamsTCX10 : &hTcxCfg->psychParamsTCX20;
    }

    return;
}
#endif
+12 −0
Original line number Diff line number Diff line
@@ -3114,6 +3114,18 @@ Word16 ITF_Detect_fx(Word32 const pSpectrum[],
  Word16* curr_order,
  Word16 Q);

Word16 ITF_Detect_ivas_fx(
    const Word32 pSpectrum[],
    const Word16 startLine,
    const Word16 stopLine,
    const Word16 maxOrder,
    Word16* A,
    Word16* Q_A,
    Word16* predictionGain,
    Word16* curr_order,
    Word16 Q
);

void ITF_Apply_fx(Word32 spectrum[],
  Word16 startLine, Word16 stopLine, const Word16* A,
  Word16 Q_A,
+166 −0
Original line number Diff line number Diff line
@@ -468,7 +468,173 @@ Word16 ITF_Detect_fx(
    return 1;
}

Word16 ITF_Detect_ivas_fx(
    const Word32 pSpectrum[],
    const Word16 startLine,
    const Word16 stopLine,
    const Word16 maxOrder,
    Word16* A,
    Word16* Q_A,
    Word16* predictionGain,
    Word16* curr_order,
    Word16 Q   
)
{

    Word16 spectrumLength;
    Word16 const nSubdivisions = MAX_SUBDIVISIONS;
    Word16 iSubdivisions;
    Word16 iStartLine;
    Word16 iEndLine;
    Word16 facs[MAX_SUBDIVISIONS];
    Word16 facs_e[MAX_SUBDIVISIONS]; /* exponents of facs[][] */
    Word16 shifts[MAX_SUBDIVISIONS];
    Word16 tmp, headroom, shift;
    Word32 rxx[ITF_MAX_FILTER_ORDER+1];
    Word16 lag;
    Word32 L_tmp, tmp32;
    Word16 tmpbuf[325];
    Word16 n, i;
#ifdef BASOP_NOGLOB_DECLARE_LOCAL
    Flag Overflow = 0;
#endif

    move16();
    move16();
    move16();

    if (maxOrder <= 0)
    {
        return 0;
    }

    /* Calculate norms for each spectrum part */
    FOR (iSubdivisions = 0; iSubdivisions < nSubdivisions; iSubdivisions++)
    {
        assert((nSubdivisions == 1) || (nSubdivisions == 3));

        tmp = sub(stopLine, startLine);
        iStartLine = imult1616(tmp, iSubdivisions);
        iEndLine = add(iStartLine, tmp);

        if (EQ_16(nSubdivisions, 3))iStartLine=mult(iStartLine,0x2AAB);
        iStartLine = add(iStartLine, startLine);

        if (EQ_16(nSubdivisions, 3))iEndLine=mult(iEndLine,0x2AAB);
        iEndLine = add(iEndLine, startLine);
        headroom = getScaleFactor32(pSpectrum+iStartLine-IGF_START_MN, sub(iEndLine, iStartLine));
        /* Calculate norm of spectrum band */
        L_tmp = Norm32Norm(pSpectrum+iStartLine-IGF_START_MN, headroom, sub(iEndLine, iStartLine), &shift);

        /* Check threshold HLM_MIN_NRG */
        BASOP_SATURATE_WARNING_OFF_EVS;
#ifdef BASOP_NOGLOB
        tmp32 = L_sub(L_shl_o(L_tmp, sub(shift, 24-Q), &Overflow), 4194304l/*HLM_MIN_NRG Q7*/);
#else /* BASOP_NOGLOB */
        tmp32 = L_sub(L_shl(L_tmp, sub(shift, 24-Q)), 4194304l/*HLM_MIN_NRG Q7*/);
#endif
        BASOP_SATURATE_WARNING_ON_EVS;

        /* get pre-shift for autocorrelation */
        tmp = sub(shift, norm_l(L_tmp)); /* exponent for normalized L_tmp */
        tmp = shr(sub(1, tmp), 1); /* pre-shift to apply before autocorrelation */
        shifts[iSubdivisions] = s_min(tmp, headroom);
        move16();

        /* calc normalization factor */
        facs[iSubdivisions] = 0;
        move16();
        facs_e[iSubdivisions] = 0;
        move16();

        if (tmp32 > 0)
        {
            facs[iSubdivisions] = 0x7FFF;
            move16(); /* normalization not needed for one subdivision */
        }

        test();
        IF ((tmp32 > 0) && (GT_16(nSubdivisions, 1)))
        {
            move16();
            facs_e[iSubdivisions] = shl(sub(tmp, shifts[iSubdivisions]), 1);

            tmp = sub(1, shl(tmp, 1)); /* exponent of autocorrelation */
            L_tmp = L_shl(L_tmp, sub(shift, tmp)); /* shift L_tmp to that exponent */

            /* calc factor (with 2 bits headroom for sum of 3 subdivisions) */
            facs[iSubdivisions] = div_s(0x2000, round_fx_o(L_tmp, &Overflow)); /* L_tmp is >= 0x2000000 */ move16();
        }

    }

    /* Calculate normalized autocorrelation for spectrum subdivision and get filter parameters based on it */
    set32_fx(rxx, 0, ITF_MAX_FILTER_ORDER+1);

    spectrumLength = sub(stopLine, startLine);

    FOR (iSubdivisions = 0; iSubdivisions < nSubdivisions; iSubdivisions++)
    {
        IF ( facs[iSubdivisions] == 0 )
        {
            BREAK;
        }


        assert((nSubdivisions == 1) || (nSubdivisions == 3));

        iStartLine = imult1616(spectrumLength, iSubdivisions);
        iEndLine = add(iStartLine, spectrumLength);

        if (EQ_16(nSubdivisions, 3))iStartLine=mult(iStartLine,0x2AAB);
        iStartLine = add(iStartLine, startLine);

        if (EQ_16(nSubdivisions, 3))iEndLine=mult(iEndLine,0x2AAB);
        iEndLine = add(iEndLine, startLine);


        move16();
        shift = shifts[iSubdivisions];

        n = sub(iEndLine, iStartLine);
        assert(n < (Word16)(sizeof(tmpbuf)/sizeof(Word16)));
        FOR (i = 0; i < n; i++)
        {
            tmpbuf[i] = round_fx(L_shl(pSpectrum[iStartLine+i-IGF_START_MN], shift));
        }

        FOR (lag = 0; lag <= maxOrder; lag++)
        {
            n = sub(sub(iEndLine,lag), iStartLine);

            {
                Word64 tmp64 = 0;
                FOR (i = 0; i < n; i++)
                {
                    tmp64 = W_mac0_16_16(tmp64, tmpbuf[i], tmpbuf[i+lag]);
                }
                L_tmp = W_sat_l(tmp64);
            }

            L_tmp = Mpy_32_16_1(L_tmp, facs[iSubdivisions]);
            L_tmp = L_shl(L_tmp, facs_e[iSubdivisions]);

            rxx[lag] = L_add(rxx[lag], L_tmp);
            move32();
        }

    }

    IF ( EQ_16(iSubdivisions,nSubdivisions)) /* meaning there is no subdivision with low energy */
    {
        /* Limit the maximum order to spectrum length/4 */
        ITF_GetFilterParameters_fx(rxx, s_min (maxOrder, shr(spectrumLength,2)), A, Q_A, predictionGain);

        *curr_order = maxOrder;
    }

    return 1;
}
/* Helper functions for Hufmann table coding */


Loading