From: Andreas Eversberg Date: Sun, 31 Mar 2013 10:52:55 +0000 (+0200) Subject: Store states of HR codec X-Git-Url: http://git.eversberg.eu/gitweb.cgi?p=lcr.git;a=commitdiff_plain;h=337b89412c5a969fa0177d146009b2aefb8c4b1f Store states of HR codec This is required, if multiple HR calls are made, because HR codec uses global variables. These global variables are stored after encoding/decoding and recalled before coding/decoding. --- diff --git a/libgsmhr/libgsmhr.c b/libgsmhr/libgsmhr.c index d018c90..d6f6813 100644 --- a/libgsmhr/libgsmhr.c +++ b/libgsmhr/libgsmhr.c @@ -32,9 +32,108 @@ #define EXPORT __attribute__((visibility("default"))) +#define EHF_MASK 0x0008 /* Encoder Homing Frame pattern */ +#define LMAX 142 /* largest lag (integer sense) */ +#define CG_INT_MACS 6 /* Number of multiply-accumulates in + * one interpolation */ +#define NUM_CLOSED 3 /* maximum number of lags searched */ +#define LPCSTARTINDEX 25 /* where the LPC analysis window + * starts */ +#define INBUFFSZ LPCSTARTINDEX + A_LEN /* input buffer size */ +#define LTP_LEN 147 /* maximum ltp lag */ +#define LSMAX (LMAX + CG_INT_MACS/2) +#define HNW_BUFF_LEN LSMAX + + extern Shortword swOldR0; + extern Shortword swOldR0Index; + + extern struct NormSw psnsWSfrmEngSpace[]; + + extern Shortword pswHPFXState[]; + extern Shortword pswHPFYState[]; + extern Shortword pswOldFrmKs[]; + extern Shortword pswOldFrmAs[]; + extern Shortword pswOldFrmSNWCoefs[]; + extern Shortword pswWgtSpeechSpace[]; + + extern Shortword pswSpeech[]; /* input speech */ + + extern Shortword swPtch; + + extern Shortword pswAnalysisState[NP]; + + extern Shortword pswWStateNum[NP], + pswWStateDenom[NP]; + + + extern Shortword pswLtpStateBase[LTP_LEN + S_LEN]; + extern Shortword pswHState[NP]; + extern Shortword pswHNWState[HNW_BUFF_LEN]; + extern Shortword gswPostFiltAgcGain, + gpswPostFiltStateNum[NP], + gpswPostFiltStateDenom[NP], + swPostEmphasisState, + pswSynthFiltState[NP], + pswOldFrmKsDec[NP], + pswOldFrmAsDec[NP], + pswOldFrmPFNum[NP], + pswOldFrmPFDenom[NP], + swOldR0Dec, + pswLtpStateBaseDec[LTP_LEN + S_LEN], + pswPPreState[LTP_LEN + S_LEN]; + + extern Shortword swMuteFlagOld; /* error concealment */ + + extern Longword plSubfrEnergyMem[4]; /* error concealment */ + extern Shortword swLevelMem[4], + lastR0, /* error concealment */ + pswLastGood[18], /* error concealment */ + swState, + swLastFlag; /* error concealment */ struct gsmhr { int dec_reset_flg; + + struct { + Shortword swOldR0; + Shortword swOldR0Index; + struct NormSw psnsWSfrmEngSpace[2 * N_SUB]; + Shortword pswHPFXState[4]; + Shortword pswHPFYState[4]; + Shortword pswOldFrmKs[NP]; + Shortword pswOldFrmAs[NP]; + Shortword pswOldFrmSNWCoefs[NP]; + Shortword pswWgtSpeechSpace[F_LEN + LMAX + CG_INT_MACS / 2]; + Shortword pswSpeech[INBUFFSZ]; /* input speech */ + Shortword swPtch; + Shortword pswAnalysisState[NP]; + Shortword pswWStateNum[NP], + pswWStateDenom[NP]; + Shortword pswLtpStateBase[LTP_LEN + S_LEN]; + Shortword pswHState[NP]; + Shortword pswHNWState[HNW_BUFF_LEN]; + } encoder; + struct { + Shortword gswPostFiltAgcGain, + gpswPostFiltStateNum[NP], + gpswPostFiltStateDenom[NP], + swPostEmphasisState, + pswSynthFiltState[NP], + pswOldFrmKsDec[NP], + pswOldFrmAsDec[NP], + pswOldFrmPFNum[NP], + pswOldFrmPFDenom[NP], + swOldR0Dec, + pswLtpStateBaseDec[LTP_LEN + S_LEN], + pswPPreState[LTP_LEN + S_LEN]; + Shortword swMuteFlagOld; + Longword plSubfrEnergyMem[4]; + Shortword swLevelMem[4], + lastR0, + pswLastGood[18], + swState, + swLastFlag; + } decoder; }; EXPORT struct gsmhr * @@ -63,6 +162,25 @@ gsmhr_encode(struct gsmhr *state, int16_t *hr_params, const int16_t *pcm) int enc_reset_flg; Shortword pcm_b[F_LEN]; + /* recall state */ + swOldR0 = swOldR0; + swOldR0Index = swOldR0Index; + memcpy(psnsWSfrmEngSpace, state->encoder.psnsWSfrmEngSpace, sizeof(struct NormSw) * 2 * N_SUB); + memcpy(pswHPFXState, state->encoder.pswHPFXState, sizeof(Shortword) * 4); + memcpy(pswHPFYState, state->encoder.pswHPFYState, sizeof(Shortword) * 4); + memcpy(pswOldFrmKs, state->encoder.pswOldFrmKs, sizeof(Shortword) * NP); + memcpy(pswOldFrmAs, state->encoder.pswOldFrmAs, sizeof(Shortword) * NP); + memcpy(pswOldFrmSNWCoefs, state->encoder.pswOldFrmSNWCoefs, sizeof(Shortword) * NP); + memcpy(pswWgtSpeechSpace, state->encoder.pswWgtSpeechSpace, sizeof(Shortword) * F_LEN + LMAX + CG_INT_MACS / 2); + memcpy(pswSpeech, state->encoder.pswSpeech, sizeof(Shortword) * INBUFFSZ); + swPtch = state->encoder.swPtch; + memcpy(pswAnalysisState, state->encoder.pswAnalysisState, sizeof(Shortword) * NP); + memcpy(pswWStateNum, state->encoder.pswWStateNum, sizeof(Shortword) * NP); + memcpy(pswWStateDenom, state->encoder.pswWStateDenom, sizeof(Shortword) * NP); + memcpy(pswLtpStateBase, state->encoder.pswLtpStateBase, sizeof(Shortword) * LTP_LEN + S_LEN); + memcpy(pswHState, state->encoder.pswHState, sizeof(Shortword) * NP); + memcpy(pswHNWState, state->encoder.pswHNWState, sizeof(Shortword) * HNW_BUFF_LEN); + memcpy(pcm_b, pcm, F_LEN*sizeof(int16_t)); enc_reset_flg = encoderHomingFrameTest(pcm_b); @@ -72,6 +190,25 @@ gsmhr_encode(struct gsmhr *state, int16_t *hr_params, const int16_t *pcm) if (enc_reset_flg) resetEnc(); + /* store state */ + state->encoder.swOldR0 = swOldR0; + state->encoder.swOldR0Index = swOldR0Index; + memcpy(state->encoder.psnsWSfrmEngSpace, psnsWSfrmEngSpace, sizeof(struct NormSw) * 2 * N_SUB); + memcpy(state->encoder.pswHPFXState, pswHPFXState, sizeof(Shortword) * 4); + memcpy(state->encoder.pswHPFYState, pswHPFYState, sizeof(Shortword) * 4); + memcpy(state->encoder.pswOldFrmKs, pswOldFrmKs, sizeof(Shortword) * NP); + memcpy(state->encoder.pswOldFrmAs, pswOldFrmAs, sizeof(Shortword) * NP); + memcpy(state->encoder.pswOldFrmSNWCoefs, pswOldFrmSNWCoefs, sizeof(Shortword) * NP); + memcpy(state->encoder.pswWgtSpeechSpace, pswWgtSpeechSpace, sizeof(Shortword) * F_LEN + LMAX + CG_INT_MACS / 2); + memcpy(state->encoder.pswSpeech, pswSpeech, sizeof(Shortword) * INBUFFSZ); + state->encoder.swPtch = swPtch; + memcpy(state->encoder.pswAnalysisState, pswAnalysisState, sizeof(Shortword) * NP); + memcpy(state->encoder.pswWStateNum, pswWStateNum, sizeof(Shortword) * NP); + memcpy(state->encoder.pswWStateDenom, pswWStateDenom, sizeof(Shortword) * NP); + memcpy(state->encoder.pswLtpStateBase, pswLtpStateBase, sizeof(Shortword) * LTP_LEN + S_LEN); + memcpy(state->encoder.pswHState, pswHState, sizeof(Shortword) * NP); + memcpy(state->encoder.pswHNWState, pswHNWState, sizeof(Shortword) * HNW_BUFF_LEN); + return 0; } @@ -84,6 +221,27 @@ gsmhr_decode(struct gsmhr *state, int16_t *pcm, const int16_t *hr_params) int dec_reset_flg; Shortword hr_params_b[22]; + /* recall state */ + gswPostFiltAgcGain = state->decoder.gswPostFiltAgcGain; + memcpy(gpswPostFiltStateNum, state->decoder.gpswPostFiltStateNum, sizeof(Shortword) * NP); + memcpy(gpswPostFiltStateDenom, state->decoder.gpswPostFiltStateDenom, sizeof(Shortword) * NP); + swPostEmphasisState = state->decoder.swPostEmphasisState; + memcpy(pswSynthFiltState, state->decoder.pswSynthFiltState, sizeof(Shortword) * NP); + memcpy(pswOldFrmKsDec, state->decoder.pswOldFrmKsDec, sizeof(Shortword) * NP); + memcpy(pswOldFrmAsDec, state->decoder.pswOldFrmAsDec, sizeof(Shortword) * NP); + memcpy(pswOldFrmPFNum, state->decoder.pswOldFrmPFNum, sizeof(Shortword) * NP); + memcpy(pswOldFrmPFDenom, state->decoder.pswOldFrmPFDenom, sizeof(Shortword) * NP); + swOldR0Dec = state->decoder.swOldR0Dec; + memcpy(pswLtpStateBaseDec, state->decoder.pswLtpStateBaseDec, sizeof(Shortword) * LTP_LEN + S_LEN); + memcpy(pswPPreState, state->decoder.pswPPreState, sizeof(Shortword) * LTP_LEN + S_LEN); + swMuteFlagOld = state->decoder.swMuteFlagOld; + memcpy(plSubfrEnergyMem, state->decoder.plSubfrEnergyMem, sizeof(Longword) * 4); + memcpy(swLevelMem, state->decoder.swLevelMem, sizeof(Shortword) * 4); + lastR0 = state->decoder.lastR0; + memcpy(pswLastGood, state->decoder.pswLastGood, sizeof(Shortword) * 18); + swState = state->decoder.swState; + swLastFlag = state->decoder.swLastFlag; + memcpy(hr_params_b, hr_params, 22*sizeof(int16_t)); if (state->dec_reset_flg) @@ -107,5 +265,26 @@ gsmhr_decode(struct gsmhr *state, int16_t *pcm, const int16_t *hr_params) state->dec_reset_flg = dec_reset_flg; + /* store state */ + state->decoder.gswPostFiltAgcGain = gswPostFiltAgcGain; + memcpy(state->decoder.gpswPostFiltStateNum, gpswPostFiltStateNum, sizeof(Shortword) * NP); + memcpy(state->decoder.gpswPostFiltStateDenom, gpswPostFiltStateDenom, sizeof(Shortword) * NP); + state->decoder.swPostEmphasisState = swPostEmphasisState; + memcpy(state->decoder.pswSynthFiltState, pswSynthFiltState, sizeof(Shortword) * NP); + memcpy(state->decoder.pswOldFrmKsDec, pswOldFrmKsDec, sizeof(Shortword) * NP); + memcpy(state->decoder.pswOldFrmAsDec, pswOldFrmAsDec, sizeof(Shortword) * NP); + memcpy(state->decoder.pswOldFrmPFNum, pswOldFrmPFNum, sizeof(Shortword) * NP); + memcpy(state->decoder.pswOldFrmPFDenom, pswOldFrmPFDenom, sizeof(Shortword) * NP); + state->decoder.swOldR0Dec = swOldR0Dec; + memcpy(state->decoder.pswLtpStateBaseDec, pswLtpStateBaseDec, sizeof(Shortword) * LTP_LEN + S_LEN); + memcpy(state->decoder.pswPPreState, pswPPreState, sizeof(Shortword) * LTP_LEN + S_LEN); + state->decoder.swMuteFlagOld = swMuteFlagOld; + memcpy(state->decoder.plSubfrEnergyMem, plSubfrEnergyMem, sizeof(Longword) * 4); + memcpy(state->decoder.swLevelMem, swLevelMem, sizeof(Shortword) * 4); + state->decoder.lastR0 = lastR0; + memcpy(state->decoder.pswLastGood, pswLastGood, sizeof(Shortword) * 18); + state->decoder.swState = swState; + state->decoder.swLastFlag = swLastFlag; + return 0; }