# HG changeset patch # User Mychaela Falconia # Date 1764874702 0 # Node ID 72cdae602d6e9c0fcd0c468b77639b5bc198edab # Parent c7c03231002daa112ae16ef5cdfe62407df1311c libgsmhr1/dec_func.c: rm unused static functions In the original code, sp_dec.c held two kinds of functions: those needed only as part of the decoder, and those used by both decoder and encoder engines. In this library, we have moved the latter class of functions to dec_func.c module. Almost all static functions from the original sp_dec.c, with the exception of aToRc(), are needed only on sp_dec.c side of the new divide - remove them from dec_func.c, where they became dead code. diff -r c7c03231002d -r 72cdae602d6e libgsmhr1/dec_func.c --- a/libgsmhr1/dec_func.c Thu Dec 04 12:49:19 2025 +0000 +++ b/libgsmhr1/dec_func.c Thu Dec 04 18:58:22 2025 +0000 @@ -97,28 +97,9 @@ |_________________________________________________________________________| */ -static void a_sst(Shortword swAshift, Shortword swAscale, - Shortword pswDirectFormCoefIn[], - Shortword pswDirectFormCoefOut[]); - static short aToRc(Shortword swAshift, Shortword pswAin[], Shortword pswRc[]); - static Shortword agcGain(Shortword pswStateCurr[], - struct NormSw snsInSigEnergy, - Shortword swEngyRShft); - - static void lookupVq(Shortword pswVqCodeWds[], Shortword pswRCOut[]); - - static void pitchPreFilt(Shortword pswExcite[], - Shortword swRxGsp0, - Shortword swRxLag, - Shortword swUvCode, - Shortword swSemiBeta, - struct NormSw snsSqrtRs, - Shortword pswExciteOut[], - Shortword pswPPreState[]); - /*_________________________________________________________________________ | | | Local Defines | @@ -606,271 +587,6 @@ /*************************************************************************** * - * FUNCTION NAME: a_sst - * - * PURPOSE: - * - * The purpose of this function is to perform spectral smoothing of the - * direct form filter coefficients - * - * INPUTS: - * - * swAshift - * number of shift for coefficients - * - * swAscale - * scaling factor for coefficients - * - * pswDirectFormCoefIn[0:NP-1] - * - * array of input direct form coefficients - * - * OUTPUTS: - * - * pswDirectFormCoefOut[0:NP-1] - * - * array of output direct form coefficients - * - * RETURN VALUE: - * - * none - * - * DESCRIPTION: - * - * In a_sst() direct form coefficients are converted to - * autocorrelations, and smoothed in that domain. The function is - * used in the spectral postfilter. A description can be found in - * section 3.2.4 as well as in the reference by Y. Tohkura et al. - * "Spectral Smoothing Technique in PARCOR Speech - * Analysis-Synthesis", IEEE Trans. ASSP, vol. ASSP-26, pp. 591-596, - * Dec. 1978. - * - * After smoothing is performed conversion back to direct form - * coefficients is done by calling aFlatRc(), followed by rcToADp(). - * - * The spectral smoothing filter coefficients with bandwidth set to 300 - * and a sampling rate of 8000 be : - * static ShortwordRom psrSST[NP+1] = { 0x7FFF, - * 0x7F5C, 0x7D76, 0x7A5B, 0x7622, 0x70EC, - * 0x6ADD, 0x641F, 0x5CDD, 0x5546, 0x4D86 - * } - * - * REFERENCES: Sub_Clause 4.2.4 of GSM Recomendation 06.20 - * - * KEYWORDS: spectral smoothing, direct form coef, sst, atorc, atocor - * KEYWORDS: levinson - * - *************************************************************************/ - -static void a_sst(Shortword swAshift, Shortword swAscale, - Shortword pswDirectFormCoefIn[], - Shortword pswDirectFormCoefOut[]) -{ - -/*_________________________________________________________________________ - | | - | Local Static Variables | - |_________________________________________________________________________| -*/ - - static const ShortwordRom psrSST[NP + 1] = {0x7FFF, - 0x7F5C, 0x7D76, 0x7A5B, 0x7622, 0x70EC, - 0x6ADD, 0x641F, 0x5CDD, 0x5546, 0x4D86, - }; - -/*_________________________________________________________________________ - | | - | Automatic Variables | - |_________________________________________________________________________| -*/ - - Longword pL_CorrTemp[NP + 1]; - - Shortword pswRCNum[NP], - pswRCDenom[NP]; - - short int siLoopCnt; - -/*_________________________________________________________________________ - | | - | Executable Code | - |_________________________________________________________________________| -*/ - - /* convert direct form coefs to reflection coefs */ - /* --------------------------------------------- */ - - aToRc(swAshift, pswDirectFormCoefIn, pswRCDenom); - - /* convert to autocorrelation coefficients */ - /* --------------------------------------- */ - - rcToCorrDpL(swAshift, swAscale, pswRCDenom, pL_CorrTemp); - - /* do spectral smoothing technique */ - /* ------------------------------- */ - - for (siLoopCnt = 1; siLoopCnt <= NP; siLoopCnt++) - { - pL_CorrTemp[siLoopCnt] = L_mpy_ls(pL_CorrTemp[siLoopCnt], - psrSST[siLoopCnt]); - } - - /* Compute the reflection coefficients via AFLAT */ - /*-----------------------------------------------*/ - - aFlatRcDp(pL_CorrTemp, pswRCNum); - - - /* Convert reflection coefficients to direct form filter coefficients */ - /*-------------------------------------------------------------------*/ - - rcToADp(swAscale, pswRCNum, pswDirectFormCoefOut); -} - -/************************************************************************** - * - * FUNCTION NAME: agcGain - * - * PURPOSE: - * - * Figure out what the agc gain should be to make the energy in the - * output signal match that of the input signal. Used in the post - * filters. - * - * INPUT: - * - * pswStateCurr[0:39] - * Input signal into agc block whose energy is - * to be modified using the gain returned. Signal is not - * modified in this routine. - * - * snsInSigEnergy - * Normalized number with shift count - the energy in - * the input signal. - * - * swEngyRShft - * Number of right shifts to apply to the vectors energy - * to ensure that it remains less than 1.0 - * (swEngyRShft is always positive or zero) - * - * OUTPUT: - * - * none - * - * RETURN: - * - * the agc's gain/2 note DIVIDED by 2 - * - * - * REFERENCES: Sub_Clause 4.2.2 and 4.2.4 of GSM Recomendation 06.20 - * - * KEYWORDS: postfilter, agc, automaticgaincontrol, leveladjust - * - *************************************************************************/ - -static Shortword agcGain(Shortword pswStateCurr[], - struct NormSw snsInSigEnergy, Shortword swEngyRShft) -{ - -/*_________________________________________________________________________ - | | - | Automatic Variables | - |_________________________________________________________________________| -*/ - - Longword L_OutEnergy, - L_AgcGain; - - struct NormSw snsOutEnergy, - snsAgc; - - Shortword swAgcOut, - swAgcShftCnt; - -/*_________________________________________________________________________ - | | - | Executable Code | - |_________________________________________________________________________| -*/ - - /* Calculate the energy in the output vector divided by 2 */ - /*--------------------------------------------------------*/ - - snsOutEnergy.sh = g_corr1s(pswStateCurr, swEngyRShft, &L_OutEnergy); - - /* reduce energy by a factor of 2 */ - snsOutEnergy.sh = add(snsOutEnergy.sh, 1); - - /* if waveform has nonzero energy, find AGC gain */ - /*-----------------------------------------------*/ - - if (L_OutEnergy == 0) - { - swAgcOut = 0; - } - else - { - - snsOutEnergy.man = round(L_OutEnergy); - - /* divide input energy by 2 */ - snsInSigEnergy.man = shr(snsInSigEnergy.man, 1); - - - /* Calculate AGC gain squared */ - /*----------------------------*/ - - snsAgc.man = divide_s(snsInSigEnergy.man, snsOutEnergy.man); - swAgcShftCnt = norm_s(snsAgc.man); - snsAgc.man = shl(snsAgc.man, swAgcShftCnt); - - /* find shift count for G^2 */ - /*--------------------------*/ - - snsAgc.sh = add(sub(snsInSigEnergy.sh, snsOutEnergy.sh), - swAgcShftCnt); - L_AgcGain = L_deposit_h(snsAgc.man); - - - /* Calculate AGC gain */ - /*--------------------*/ - - snsAgc.man = sqroot(L_AgcGain); - - - /* check if 1/2 sqrt(G^2) >= 1.0 */ - /* This is equivalent to checking if shiftCnt/2+1 < 0 */ - /*----------------------------------------------------*/ - - if (add(snsAgc.sh, 2) < 0) - { - swAgcOut = SW_MAX; - } - else - { - - if (0x1 & snsAgc.sh) - { - snsAgc.man = mult(snsAgc.man, SQRT_ONEHALF); - } - - snsAgc.sh = shr(snsAgc.sh, 1); /* shiftCnt/2 */ - snsAgc.sh = add(snsAgc.sh, 1); /* shiftCnt/2 + 1 */ - - if (snsAgc.sh > 0) - { - snsAgc.man = shr(snsAgc.man, snsAgc.sh); - } - swAgcOut = snsAgc.man; - } - } - - return (swAgcOut); -} - -/*************************************************************************** - * * FUNCTION NAME: b_con * * PURPOSE: @@ -1820,152 +1536,6 @@ /*************************************************************************** * - * FUNCTION NAME: lookupVq - * - * PURPOSE: - * - * The purpose of this function is to recover the reflection coeffs from - * the received LPC codewords. - * - * INPUTS: - * - * pswVqCodeWds[0:2] - * - * the codewords for each of the segments - * - * OUTPUTS: - * - * pswRCOut[0:NP-1] - * - * the decoded reflection coefficients - * - * RETURN VALUE: - * - * none. - * - * DESCRIPTION: - * - * For each segment do the following: - * setup the retrieval pointers to the correct vector - * get that vector - * - * REFERENCES: Sub-clause 4.2.3 of GSM Recomendation 06.20 - * - * KEYWORDS: vq, vectorquantizer, lpc - * - *************************************************************************/ - -static void lookupVq(Shortword pswVqCodeWds[], Shortword pswRCOut[]) -{ -/*_________________________________________________________________________ - | | - | Local Constants | - |_________________________________________________________________________| -*/ - -#define LSP_MASK 0x00ff - -/*_________________________________________________________________________ - | | - | Automatic Variables | - |_________________________________________________________________________| -*/ - - short int siSeg, - siIndex, - siVector, - siVector1, - siVector2, - siWordPtr; - - const ShortwordRom *psrQTable; - -/*_________________________________________________________________________ - | | - | Executable Code | - |_________________________________________________________________________| -*/ - - /* for each segment */ - /* ---------------- */ - - for (siSeg = 0; siSeg < QUANT_NUM_OF_TABLES; siSeg++) - { - - siVector = pswVqCodeWds[siSeg]; - siIndex = psvqIndex[siSeg].l; - - if (sub(siSeg, 2) == 0) - { /* segment 3 */ - - /* set table */ - /* --------- */ - - psrQTable = psrQuant3; - - /* set offset into table */ - /* ---------------------- */ - - siWordPtr = add(siVector, siVector); - - /* look up coeffs */ - /* -------------- */ - - siVector1 = psrQTable[siWordPtr]; - siVector2 = psrQTable[siWordPtr + 1]; - - pswRCOut[siIndex - 1] = psrSQuant[shr(siVector1, 8) & LSP_MASK]; - pswRCOut[siIndex] = psrSQuant[siVector1 & LSP_MASK]; - pswRCOut[siIndex + 1] = psrSQuant[shr(siVector2, 8) & LSP_MASK]; - pswRCOut[siIndex + 2] = psrSQuant[siVector2 & LSP_MASK]; - } - else - { /* segments 1 and 2 */ - - /* set tables */ - /* ---------- */ - - if (siSeg == 0) - { - psrQTable = psrQuant1; - } - else - { - psrQTable = psrQuant2; - - } - - /* set offset into table */ - /* --------------------- */ - - siWordPtr = add(siVector, siVector); - siWordPtr = add(siWordPtr, siVector); - siWordPtr = shr(siWordPtr, 1); - - /* look up coeffs */ - /* -------------- */ - - siVector1 = psrQTable[siWordPtr]; - siVector2 = psrQTable[siWordPtr + 1]; - - if ((siVector & 0x0001) == 0) - { - pswRCOut[siIndex - 1] = psrSQuant[shr(siVector1, 8) & LSP_MASK]; - pswRCOut[siIndex] = psrSQuant[siVector1 & LSP_MASK]; - pswRCOut[siIndex + 1] = psrSQuant[shr(siVector2, 8) & LSP_MASK]; - } - else - { - pswRCOut[siIndex - 1] = psrSQuant[siVector1 & LSP_MASK]; - pswRCOut[siIndex] = psrSQuant[shr(siVector2, 8) & LSP_MASK]; - pswRCOut[siIndex + 1] = psrSQuant[siVector2 & LSP_MASK]; - } - } - } -} - -/*************************************************************************** - * * FUNCTION NAME: lpcFir * * PURPOSE: @@ -2915,298 +2485,6 @@ } } -/************************************************************************** - * - * FUNCTION NAME: pitchPreFilt - * - * PURPOSE: - * - * Performs pitch pre-filter on excitation in speech decoder. - * - * INPUTS: - * - * pswExcite[0:39] - * - * Synthetic residual signal to be filtered, a subframe- - * length vector. - * - * ppsrPVecIntFilt[0:9][0:5] ([tap][phase]) - * - * Interpolation filter coefficients. - * - * ppsrSqtrP0[0:2][0:31] ([voicing level-1][gain code]) - * - * Sqrt(P0) look-up table, used to determine pitch - * pre-filtering coefficient. - * - * swRxGsp0 - * - * Coded value from gain quantizer, used to look up - * sqrt(P0). - * - * swRxLag - * - * Full-resolution lag value (fractional lag * - * oversampling factor), used to index pitch pre-filter - * state. - * - * swUvCode - * - * Coded voicing level, used to distinguish between - * voiced and unvoiced conditions, and to look up - * sqrt(P0). - * - * swSemiBeta - * - * The gain applied to the adaptive codebook excitation - * (long-term predictor excitation) limited to a maximum - * of 1.0, used to determine the pitch pre-filter - * coefficient. - * - * snsSqrtRs - * - * The estimate of the energy in the residual, used only - * for scaling. - * - * OUTPUTS: - * - * pswExciteOut[0:39] - * - * The output pitch pre-filtered excitation. - * - * pswPPreState[0:44] - * - * Contains the state of the pitch pre-filter - * - * RETURN VALUE: - * - * none - * - * DESCRIPTION: - * - * If the voicing mode for the frame is unvoiced, then the pitch pre- - * filter state is updated with the input excitation, and the input - * excitation is copied to the output. - * - * If voiced: first the energy in the input excitation is calculated. - * Then, the coefficient of the pitch pre-filter is obtained: - * - * PpfCoef = POST_EPSILON * min(beta, sqrt(P0)). - * - * Then, the pitch pre-filter is performed: - * - * ex_p(n) = ex(n) + PpfCoef * ex_p(n-L) - * - * The ex_p(n-L) sample is interpolated from the surrounding samples, - * even for integer values of L. - * - * Note: The coefficients of the interpolating filter are multiplied - * by PpfCoef, rather multiplying ex_p(n_L) after interpolation. - * - * Finally, the energy in the output excitation is calculated, and - * automatic gain control is applied to the output signal so that - * its energy matches the original. - * - * The pitch pre-filter is described in section 4.2.2. - * - * REFERENCES: Sub-clause 4.2.2 of GSM Recomendation 06.20 - * - * KEYWORDS: prefilter, pitch, pitchprefilter, excitation, residual - * - *************************************************************************/ - -static void pitchPreFilt(Shortword pswExcite[], - Shortword swRxGsp0, - Shortword swRxLag, Shortword swUvCode, - Shortword swSemiBeta, struct NormSw snsSqrtRs, - Shortword pswExciteOut[], - Shortword pswPPreState[]) -{ - -/*_________________________________________________________________________ - | | - | Local Constants | - |_________________________________________________________________________| -*/ - -#define POST_EPSILON 0x2666 - -/*_________________________________________________________________________ - | | - | Local Static Variables | - |_________________________________________________________________________| -*/ - - -/*_________________________________________________________________________ - | | - | Automatic Variables | - |_________________________________________________________________________| -*/ - - Longword L_1, - L_OrigEnergy; - - Shortword swScale, - swSqrtP0, - swIntLag, - swRemain, - swEnergy, - pswInterpCoefs[P_INT_MACS]; - - short int i, - j; - - struct NormSw snsOrigEnergy; - - Shortword *pswPPreCurr = &pswPPreState[LTP_LEN]; - -/*_________________________________________________________________________ - | | - | Executable Code | - |_________________________________________________________________________| -*/ - - /* Initialization */ - /*----------------*/ - - swEnergy = 0; - - /* Check voicing level */ - /*---------------------*/ - - if (swUvCode == 0) - { - - /* Unvoiced: perform one subframe of delay on state, copy input to */ - /* state, copy input to output (if not same) */ - /*-----------------------------------------------------------------*/ - - for (i = 0; i < LTP_LEN - S_LEN; i++) - pswPPreState[i] = pswPPreState[i + S_LEN]; - - for (i = 0; i < S_LEN; i++) - pswPPreState[i + LTP_LEN - S_LEN] = pswExcite[i]; - - if (pswExciteOut != pswExcite) - { - - for (i = 0; i < S_LEN; i++) - pswExciteOut[i] = pswExcite[i]; - } - } - else - { - - /* Voiced: calculate energy in input, filter, calculate energy in */ - /* output, scale */ - /*----------------------------------------------------------------*/ - - /* Get energy in input excitation vector */ - /*---------------------------------------*/ - - swEnergy = add(negate(shl(snsSqrtRs.sh, 1)), 3); - - if (swEnergy > 0) - { - - /* High-energy residual: scale input vector during energy */ - /* calculation. The shift count + 1 of the energy of the */ - /* residual estimate is used as an estimate of the shift */ - /* count needed for the excitation energy */ - /*--------------------------------------------------------*/ - - - snsOrigEnergy.sh = g_corr1s(pswExcite, swEnergy, &L_OrigEnergy); - snsOrigEnergy.man = round(L_OrigEnergy); - - } - else - { - - /* set shift count to zero for AGC later */ - /*---------------------------------------*/ - - swEnergy = 0; - - /* Lower-energy residual: no overflow protection needed */ - /*------------------------------------------------------*/ - - L_OrigEnergy = 0; - for (i = 0; i < S_LEN; i++) - { - - L_OrigEnergy = L_mac(L_OrigEnergy, pswExcite[i], pswExcite[i]); - } - - snsOrigEnergy.sh = norm_l(L_OrigEnergy); - snsOrigEnergy.man = round(L_shl(L_OrigEnergy, snsOrigEnergy.sh)); - } - - /* Determine pitch pre-filter coefficient, and scale the appropriate */ - /* phase of the interpolating filter by it */ - /*-------------------------------------------------------------------*/ - - swSqrtP0 = ppsrSqrtP0[swUvCode - 1][swRxGsp0]; - - if (sub(swSqrtP0, swSemiBeta) > 0) - swScale = swSemiBeta; - else - swScale = swSqrtP0; - - swScale = mult_r(POST_EPSILON, swScale); - - get_ipjj(swRxLag, &swIntLag, &swRemain); - - for (i = 0; i < P_INT_MACS; i++) - pswInterpCoefs[i] = mult_r(ppsrPVecIntFilt[i][swRemain], swScale); - - /* Perform filter */ - /*----------------*/ - - for (i = 0; i < S_LEN; i++) - { - - L_1 = L_deposit_h(pswExcite[i]); - - for (j = 0; j < P_INT_MACS - 1; j++) - { - - L_1 = L_mac(L_1, pswPPreCurr[i - swIntLag - P_INT_MACS / 2 + j], - pswInterpCoefs[j]); - } - - pswPPreCurr[i] = mac_r(L_1, - pswPPreCurr[i - swIntLag + P_INT_MACS / 2 - 1], - pswInterpCoefs[P_INT_MACS - 1]); - } - - /* Get energy in filtered vector, determine automatic-gain-control */ - /* scale factor */ - /*-----------------------------------------------------------------*/ - - swScale = agcGain(pswPPreCurr, snsOrigEnergy, swEnergy); - - /* Scale filtered vector by AGC, put out. NOTE: AGC scale returned */ - /* by routine above is divided by two, hence the shift below */ - /*------------------------------------------------------------------*/ - - for (i = 0; i < S_LEN; i++) - { - - L_1 = L_mult(pswPPreCurr[i], swScale); - L_1 = L_shl(L_1, 1); - pswExciteOut[i] = round(L_1); - } - - /* Update pitch pre-filter state */ - /*-------------------------------*/ - - for (i = 0; i < LTP_LEN; i++) - pswPPreState[i] = pswPPreState[i + S_LEN]; - } -} - /*************************************************************************** * * FUNCTION NAME: r0BasedEnergyShft