Mercurial > hg > audiostuff
diff intercom/ilbc/LPCdecode.c @ 2:13be24d74cd2
import intercom-0.4.1
author | Peter Meerwald <pmeerw@cosy.sbg.ac.at> |
---|---|
date | Fri, 25 Jun 2010 09:57:52 +0200 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/intercom/ilbc/LPCdecode.c Fri Jun 25 09:57:52 2010 +0200 @@ -0,0 +1,145 @@ + + /****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + LPC_decode.c + + Copyright (C) The Internet Society (2004). + All Rights Reserved. + + ******************************************************************/ + +#include <math.h> +#include <string.h> + +#include "helpfun.h" +#include "lsf.h" +#include "iLBC_define.h" +#include "constants.h" + + /*---------------------------------------------------------------* + * interpolation of lsf coefficients for the decoder + *--------------------------------------------------------------*/ + +void LSFinterpolate2a_dec(float *a, /* (o) lpc coefficients for a sub-frame */ + float *lsf1, /* (i) first lsf coefficient vector */ + float *lsf2, /* (i) second lsf coefficient vector */ + float coef, /* (i) interpolation weight */ + int length /* (i) length of lsf vectors */ + ) +{ + float lsftmp[LPC_FILTERORDER]; + + interpolate(lsftmp, lsf1, lsf2, coef, length); + lsf2a(a, lsftmp); +} + + /*---------------------------------------------------------------* + * obtain dequantized lsf coefficients from quantization index + *--------------------------------------------------------------*/ + +void SimplelsfDEQ(float *lsfdeq, /* (o) dequantized lsf coefficients */ + int *index, /* (i) quantization index */ + int lpc_n /* (i) number of LPCs */ + ) +{ + int i, j, pos, cb_pos; + + + + + + /* decode first LSF */ + + pos = 0; + cb_pos = 0; + for (i = 0; i < LSF_NSPLIT; i++) { + for (j = 0; j < dim_lsfCbTbl[i]; j++) { + lsfdeq[pos + j] = lsfCbTbl[cb_pos + + (long) (index[i]) * dim_lsfCbTbl[i] + j]; + } + pos += dim_lsfCbTbl[i]; + cb_pos += size_lsfCbTbl[i] * dim_lsfCbTbl[i]; + } + + if (lpc_n > 1) { + + /* decode last LSF */ + + pos = 0; + cb_pos = 0; + for (i = 0; i < LSF_NSPLIT; i++) { + for (j = 0; j < dim_lsfCbTbl[i]; j++) { + lsfdeq[LPC_FILTERORDER + pos + j] = + lsfCbTbl[cb_pos + + (long) (index[LSF_NSPLIT + i]) * dim_lsfCbTbl[i] + j]; + } + pos += dim_lsfCbTbl[i]; + cb_pos += size_lsfCbTbl[i] * dim_lsfCbTbl[i]; + } + } +} + + /*----------------------------------------------------------------* + * obtain synthesis and weighting filters form lsf coefficients + *---------------------------------------------------------------*/ + +void DecoderInterpolateLSF(float *syntdenum, /* (o) synthesis filter coefficients */ + float *weightdenum, /* (o) weighting denumerator + coefficients */ + float *lsfdeq, /* (i) dequantized lsf coefficients */ + int length, /* (i) length of lsf coefficient vector */ + iLBC_Dec_Inst_t * iLBCdec_inst + /* (i) the decoder state structure */ + ) +{ + int i, pos, lp_length; + float lp[LPC_FILTERORDER + 1], *lsfdeq2; + + + + + + + lsfdeq2 = lsfdeq + length; + lp_length = length + 1; + + if (iLBCdec_inst->mode == 30) { + /* sub-frame 1: Interpolation between old and first */ + + LSFinterpolate2a_dec(lp, iLBCdec_inst->lsfdeqold, lsfdeq, + lsf_weightTbl_30ms[0], length); + memcpy(syntdenum, lp, lp_length * sizeof(float)); + bwexpand(weightdenum, lp, LPC_CHIRP_WEIGHTDENUM, lp_length); + + /* sub-frames 2 to 6: interpolation between first + and last LSF */ + + pos = lp_length; + for (i = 1; i < 6; i++) { + LSFinterpolate2a_dec(lp, lsfdeq, lsfdeq2, + lsf_weightTbl_30ms[i], length); + memcpy(syntdenum + pos, lp, lp_length * sizeof(float)); + bwexpand(weightdenum + pos, lp, LPC_CHIRP_WEIGHTDENUM, lp_length); + pos += lp_length; + } + } else { + pos = 0; + for (i = 0; i < iLBCdec_inst->nsub; i++) { + LSFinterpolate2a_dec(lp, iLBCdec_inst->lsfdeqold, + lsfdeq, lsf_weightTbl_20ms[i], length); + memcpy(syntdenum + pos, lp, lp_length * sizeof(float)); + bwexpand(weightdenum + pos, lp, LPC_CHIRP_WEIGHTDENUM, lp_length); + pos += lp_length; + } + } + + /* update memory */ + + if (iLBCdec_inst->mode == 30) + memcpy(iLBCdec_inst->lsfdeqold, lsfdeq2, length * sizeof(float)); + else + memcpy(iLBCdec_inst->lsfdeqold, lsfdeq, length * sizeof(float)); + +}