git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@7221 65c4cc65-6c06-0410-ace0-fbb531ad65f3
153 lines
4.5 KiB
C
153 lines
4.5 KiB
C
|
|
/******************************************************************
|
|
|
|
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 "LPCdecode.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));
|
|
|
|
}
|
|
|
|
|