FreeCalypso > hg > gsm-codec-lib
view libgsmhr1/dtx_dec.c @ 598:5809165fb140
libgsmhr1: integrate DTX functions for speech decoder
| author | Mychaela Falconia <falcon@freecalypso.org> |
|---|---|
| date | Thu, 04 Dec 2025 09:51:11 +0000 |
| parents | |
| children | c7c03231002d |
line wrap: on
line source
/*************************************************************************** * * File Name: dtx_dec.c * * Derivation: this module is the subset of GSM 06.06 dtx.c * reduced to decoder functions that aren't in dtx_rxfe.c, i.e., * apply only to the full decoder and not the TFO transform. * **************************************************************************/ /*________________________________________________________________________ | | | Include Files | |________________________________________________________________________| */ #include <string.h> #include "typedefs.h" #include "namespace.h" #include "mathhalf.h" #include "mathdp31.h" #include "dec_func.h" #include "dec_state.h" #include "dtx_const.h" #include "dtx_dec.h" /*________________________________________________________________________ | | | Defines | |________________________________________________________________________| */ #define ASHIFT 4 #define ASCALE 0x0800 /*________________________________________________________________________ | | | DTX Rom Tables | |________________________________________________________________________| */ /* interpolation curve for comfort noise (i*1/12) i=1..12 */ static const Shortword psrCNNewFactor[12] = { 0x0aaa, 0x1554, 0x1ffe, 0x2aa8, 0x3552, 0x3ffc, 0x4aa6, 0x5550, 0x5ffa, 0x6aa4, 0x754e, 0x7fff }; /* * This function is a fragment from original rxInterpR0Lpc(): * init or update CN interpolation endpoints on CNIFIRSTSID * or CNICONT. */ void Init_CN_interpolation(struct gsmhr_decoder_state *st, Shortword deco_mode, Shortword new_R0, const Shortword *pswNewKs) { st->swR0OldCN = st->swOldR0Dec; st->swR0NewCN = new_R0; if (deco_mode == CNIFIRSTSID) { rcToCorrDpL(ASHIFT, ASCALE, st->pswOldFrmKsDec, st->pL_OldCorrSeq); } else { memcpy(st->pL_OldCorrSeq, st->pL_CorrSeq, sizeof(st->pL_CorrSeq)); } rcToCorrDpL(ASHIFT, ASCALE, pswNewKs, st->pL_NewCorrSeq); } /* * This function is a fragment from original rxInterpR0Lpc(): * interpolate R0 for CN output. */ Shortword CN_Interpolate_R0(struct gsmhr_decoder_state *st) { return linInterpSidShort(st->swR0NewCN, st->swR0OldCN, st->swRxDTXState); } /* * This function is a fragment from original rxInterpR0Lpc(): * interpolate LPC for CN output. */ void CN_Interpolate_LPC(struct gsmhr_decoder_state *st, Shortword *pswNewKs) { int i; /* linearly interpolate between the two sets of correlation coefs */ /* -------------------------------------------------------------- */ for (i = 0; i < NP + 1; i++) { st->pL_CorrSeq[i] = linInterpSid(st->pL_NewCorrSeq[i], st->pL_OldCorrSeq[i], st->swRxDTXState); } /* Generate this frames K's (overwrite input) */ /* ------------------------------------------ */ aFlatRcDp(st->pL_CorrSeq, pswNewKs); } /************************************************************************* * * FUNCTION NAME: linInterpSid * * PURPOSE: * * Linearly interpolate between two input numbers based on what the * current DtxState is. * * INPUTS: * * L_New - longword more current value * * L_Old - longword oldest value * * swDtxState - state is 0 at the transmitted SID Frame. * * * OUTPUTS: * * none * * RETURN VALUE: * * A value between old and new inputs with dtxState+1/12 of the new * (dtxState+1)-12/12 of the old * * *************************************************************************/ Longword linInterpSid(Longword L_New, Longword L_Old, Shortword swDtxState) { /*_________________________________________________________________________ | | | Automatic Variables | |_________________________________________________________________________| */ Shortword swOldFactor; /*_________________________________________________________________________ | | | Executable Code | |_________________________________________________________________________| */ /* old factor = (1.0 - newFactor) */ /* ------------------------------ */ swOldFactor = sub(0x7fff, psrCNNewFactor[swDtxState]); swOldFactor = add(0x1, swOldFactor); /* contributions from new and old */ /* ------------------------------ */ L_New = L_mpy_ls(L_New, psrCNNewFactor[swDtxState]); L_Old = L_mpy_ls(L_Old, swOldFactor); return (L_add(L_New, L_Old)); } /************************************************************************* * * FUNCTION NAME: linInterpSidShort * * PURPOSE: * * Linearly interpolate between two input numbers based on what * the current DtxState is. * * INPUTS: * * swNew - 16 bit, more current value * * swOld - 16 bit, oldest value * * swDtxState - state is 0 at the transmitted SID Frame. * * * OUTPUTS: * * none * * RETURN VALUE: * * A value between old and new inputs with dtxState+1/12 of the new * (dtxState+1)-12/12 of the old * *************************************************************************/ Shortword linInterpSidShort(Shortword swNew, Shortword swOld, Shortword swDtxState) { /*_________________________________________________________________________ | | | Automatic Variables | |_________________________________________________________________________| */ Shortword swOldFactor; Longword L_New, L_Old; /*_________________________________________________________________________ | | | Executable Code | |_________________________________________________________________________| */ /* old factor = (1.0 - newFactor) */ /* ------------------------------ */ swOldFactor = sub(0x7fff, psrCNNewFactor[swDtxState]); swOldFactor = add(0x1, swOldFactor); /* contributions from new and old */ /* ------------------------------ */ L_New = L_mult(swNew, psrCNNewFactor[swDtxState]); L_Old = L_mult(swOld, swOldFactor); return (round(L_add(L_New, L_Old))); }
