Update to new iLBC codec

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@3997 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
Mark Spencer
2004-10-14 05:15:48 +00:00
parent 7c4337dc91
commit d4ff9abc61
48 changed files with 6976 additions and 6482 deletions

View File

@@ -3,11 +3,11 @@
* *
* Translate between signed linear and Internet Low Bitrate Codec * Translate between signed linear and Internet Low Bitrate Codec
* *
* The iLBC code is from The IETF code base and is copyright GlobalSound, AB * The iLBC code is from The IETF code base and is copyright The Internet Society (2004)
* *
* Copyright (C) 1999, Mark Spencer * Copyright (C) 1999-2004, Digium, Inc.
* *
* Mark Spencer <markster@linux-support.net> * Mark Spencer <markster@digium.com>
* *
* This program is free software, distributed under the terms of * This program is free software, distributed under the terms of
* the GNU General Public License * the GNU General Public License
@@ -33,6 +33,8 @@
#include "ilbc_slin_ex.h" #include "ilbc_slin_ex.h"
#define USE_ILBC_ENHANCER 0 #define USE_ILBC_ENHANCER 0
#define ILBC_MS 30
/* #define ILBC_MS 20 */
AST_MUTEX_DEFINE_STATIC(localuser_lock); AST_MUTEX_DEFINE_STATIC(localuser_lock);
static int localusecnt=0; static int localusecnt=0;
@@ -61,7 +63,7 @@ static struct ast_translator_pvt *lintoilbc_new(void)
if (tmp) { if (tmp) {
/* Shut valgrind up */ /* Shut valgrind up */
memset(&tmp->enc, 0, sizeof(tmp->enc)); memset(&tmp->enc, 0, sizeof(tmp->enc));
initEncode(&tmp->enc); initEncode(&tmp->enc, ILBC_MS);
tmp->tail = 0; tmp->tail = 0;
localusecnt++; localusecnt++;
} }
@@ -75,7 +77,7 @@ static struct ast_translator_pvt *ilbctolin_new(void)
if (tmp) { if (tmp) {
/* Shut valgrind up */ /* Shut valgrind up */
memset(&tmp->dec, 0, sizeof(tmp->dec)); memset(&tmp->dec, 0, sizeof(tmp->dec));
initDecode(&tmp->dec, USE_ILBC_ENHANCER); initDecode(&tmp->dec, ILBC_MS, USE_ILBC_ENHANCER);
tmp->tail = 0; tmp->tail = 0;
localusecnt++; localusecnt++;
} }

View File

@@ -5,25 +5,25 @@
FrameClassify.c FrameClassify.c
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/ ******************************************************************/
#include "iLBC_define.h" #include "iLBC_define.h"
#include "FrameClassify.h"
/*----------------------------------------------------------------* /*---------------------------------------------------------------*
* Classification of subframes to localize start state * Classification of subframes to localize start state
*---------------------------------------------------------------*/ *--------------------------------------------------------------*/
int FrameClassify( /* index to the max-energy sub frame */ int FrameClassify( /* index to the max-energy sub-frame */
iLBC_Enc_Inst_t *iLBCenc_inst,
/* (i/o) the encoder state structure */
float *residual /* (i) lpc residual signal */ float *residual /* (i) lpc residual signal */
){ ) {
float max_ssqEn, fssqEn[NSUB], bssqEn[NSUB], *pp; float max_ssqEn, fssqEn[NSUB_MAX], bssqEn[NSUB_MAX], *pp;
int n, l, max_ssqEn_n; int n, l, max_ssqEn_n;
const float ssqEn_win[NSUB-1]={(float)0.8,(float)0.9, const float ssqEn_win[NSUB_MAX-1]={(float)0.8,(float)0.9,
(float)1.0,(float)0.9,(float)0.8}; (float)1.0,(float)0.9,(float)0.8};
const float sampEn_win[5]={(float)1.0/(float)6.0, const float sampEn_win[5]={(float)1.0/(float)6.0,
(float)2.0/(float)6.0, (float)3.0/(float)6.0, (float)2.0/(float)6.0, (float)3.0/(float)6.0,
@@ -31,37 +31,39 @@ int FrameClassify( /* index to the max-energy sub frame */
/* init the front and back energies to zero */ /* init the front and back energies to zero */
memset(fssqEn, 0, NSUB*sizeof(float)); memset(fssqEn, 0, NSUB_MAX*sizeof(float));
memset(bssqEn, 0, NSUB*sizeof(float)); memset(bssqEn, 0, NSUB_MAX*sizeof(float));
/* Calculate front of first seqence */ /* Calculate front of first seqence */
n=0; n=0;
pp=residual; pp=residual;
for(l=0;l<5;l++){
for (l=0; l<5; l++) {
fssqEn[n] += sampEn_win[l] * (*pp) * (*pp); fssqEn[n] += sampEn_win[l] * (*pp) * (*pp);
pp++; pp++;
} }
for(l=5;l<SUBL;l++){ for (l=5; l<SUBL; l++) {
fssqEn[n] += (*pp) * (*pp); fssqEn[n] += (*pp) * (*pp);
pp++; pp++;
} }
/* Calculate front and back of all middle sequences */ /* Calculate front and back of all middle sequences */
for(n=1;n<NSUB-1;n++) { for (n=1; n<iLBCenc_inst->nsub-1; n++) {
pp=residual+n*SUBL; pp=residual+n*SUBL;
for(l=0;l<5;l++){ for (l=0; l<5; l++) {
fssqEn[n] += sampEn_win[l] * (*pp) * (*pp); fssqEn[n] += sampEn_win[l] * (*pp) * (*pp);
bssqEn[n] += (*pp) * (*pp); bssqEn[n] += (*pp) * (*pp);
pp++; pp++;
} }
for(l=5;l<SUBL-5;l++){ for (l=5; l<SUBL-5; l++) {
fssqEn[n] += (*pp) * (*pp); fssqEn[n] += (*pp) * (*pp);
bssqEn[n] += (*pp) * (*pp); bssqEn[n] += (*pp) * (*pp);
pp++; pp++;
} }
for(l=SUBL-5;l<SUBL;l++){ for (l=SUBL-5; l<SUBL; l++) {
fssqEn[n] += (*pp) * (*pp); fssqEn[n] += (*pp) * (*pp);
bssqEn[n] += sampEn_win[SUBL-l-1] * (*pp) * (*pp); bssqEn[n] += sampEn_win[SUBL-l-1] * (*pp) * (*pp);
pp++; pp++;
@@ -70,13 +72,13 @@ int FrameClassify( /* index to the max-energy sub frame */
/* Calculate back of last seqence */ /* Calculate back of last seqence */
n=NSUB-1; n=iLBCenc_inst->nsub-1;
pp=residual+n*SUBL; pp=residual+n*SUBL;
for(l=0;l<SUBL-5;l++){ for (l=0; l<SUBL-5; l++) {
bssqEn[n] += (*pp) * (*pp); bssqEn[n] += (*pp) * (*pp);
pp++; pp++;
} }
for(l=SUBL-5;l<SUBL;l++){ for (l=SUBL-5; l<SUBL; l++) {
bssqEn[n] += sampEn_win[SUBL-l-1] * (*pp) * (*pp); bssqEn[n] += sampEn_win[SUBL-l-1] * (*pp) * (*pp);
pp++; pp++;
} }
@@ -84,13 +86,19 @@ int FrameClassify( /* index to the max-energy sub frame */
/* find the index to the weighted 80 sample with /* find the index to the weighted 80 sample with
most energy */ most energy */
max_ssqEn=(fssqEn[0]+bssqEn[1])*ssqEn_win[0]; if (iLBCenc_inst->mode==20) l=1;
max_ssqEn_n=1; else l=0;
for (n=2;n<NSUB;n++) {
if ((fssqEn[n-1]+bssqEn[n])*ssqEn_win[n-1] > max_ssqEn) { max_ssqEn=(fssqEn[0]+bssqEn[1])*ssqEn_win[l];
max_ssqEn_n=1;
for (n=2; n<iLBCenc_inst->nsub; n++) {
l++;
if ((fssqEn[n-1]+bssqEn[n])*ssqEn_win[l] > max_ssqEn) {
max_ssqEn=(fssqEn[n-1]+bssqEn[n]) * max_ssqEn=(fssqEn[n-1]+bssqEn[n]) *
ssqEn_win[n-1]; ssqEn_win[l];
max_ssqEn_n=n; max_ssqEn_n=n;
} }
} }

View File

@@ -5,16 +5,19 @@
FrameClassify.h FrameClassify.h
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/ ******************************************************************/
#ifndef __iLBC_FRAMECLASSIFY_H #ifndef __iLBC_FRAMECLASSIFY_H
#define __iLBC_FRAMECLASSIFY_H #define __iLBC_FRAMECLASSIFY_H
int FrameClassify( /* Index to the max-energy sub frame */ int FrameClassify( /* index to the max-energy sub-frame */
iLBC_Enc_Inst_t *iLBCenc_inst,
/* (i/o) the encoder state structure */
float *residual /* (i) lpc residual signal */ float *residual /* (i) lpc residual signal */
); );

View File

@@ -5,9 +5,8 @@
LPC_decode.c LPC_decode.c
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/ ******************************************************************/
@@ -18,15 +17,16 @@
#include "lsf.h" #include "lsf.h"
#include "iLBC_define.h" #include "iLBC_define.h"
#include "constants.h" #include "constants.h"
#include "LPCdecode.h"
/*----------------------------------------------------------------* /*---------------------------------------------------------------*
* interpolation of lsf coefficients for the decoder * interpolation of lsf coefficients for the decoder
*---------------------------------------------------------------*/ *--------------------------------------------------------------*/
void LSFinterpolate2a_dec( void LSFinterpolate2a_dec(
float *a, /* (o) lpc coefficients for a sub frame */ float *a, /* (o) lpc coefficients for a sub-frame */
float *lsf1, /* (i) first lsf coefficient vector */ float *lsf1, /* (i) first lsf coefficient vector */
float *lsf2, /* (i) second lsf coefficient vector */ float *lsf2, /* (i) second lsf coefficient vector */
float coef, /* (i) interpolation weight */ float coef, /* (i) interpolation weight */
int length /* (i) length of lsf vectors */ int length /* (i) length of lsf vectors */
@@ -37,15 +37,16 @@ void LSFinterpolate2a_dec(
lsf2a(a, lsftmp); lsf2a(a, lsftmp);
} }
/*----------------------------------------------------------------* /*---------------------------------------------------------------*
* obtain dequantized lsf coefficients from quantization index * obtain dequantized lsf coefficients from quantization index
*---------------------------------------------------------------*/ *--------------------------------------------------------------*/
void SimplelsfDEQ( void SimplelsfDEQ(
float *lsfdeq, /* (o) dequantized lsf coefficients */ float *lsfdeq, /* (o) dequantized lsf coefficients */
int *index /* (i) quantization index */ int *index, /* (i) quantization index */
int lpc_n /* (i) number of LPCs */
){ ){
int i,j, pos, cb_pos; int i, j, pos, cb_pos;
/* decode first LSF */ /* decode first LSF */
@@ -60,21 +61,28 @@ void SimplelsfDEQ(
cb_pos += size_lsfCbTbl[i]*dim_lsfCbTbl[i]; cb_pos += size_lsfCbTbl[i]*dim_lsfCbTbl[i];
} }
if (lpc_n>1) {
/* decode last LSF */ /* decode last LSF */
pos = 0; pos = 0;
cb_pos = 0; cb_pos = 0;
for (i = 0; i < LSF_NSPLIT; i++) { for (i = 0; i < LSF_NSPLIT; i++) {
for (j = 0; j < dim_lsfCbTbl[i]; j++) { for (j = 0; j < dim_lsfCbTbl[i]; j++) {
lsfdeq[LPC_FILTERORDER + pos + j] = lsfCbTbl[cb_pos + lsfdeq[LPC_FILTERORDER + pos + j] =
(long)(index[LSF_NSPLIT + i])*dim_lsfCbTbl[i] + j]; lsfCbTbl[cb_pos +
(long)(index[LSF_NSPLIT + i])*
dim_lsfCbTbl[i] + j];
} }
pos += dim_lsfCbTbl[i]; pos += dim_lsfCbTbl[i];
cb_pos += size_lsfCbTbl[i]*dim_lsfCbTbl[i]; cb_pos += size_lsfCbTbl[i]*dim_lsfCbTbl[i];
} }
}
} }
/*----------------------------------------------------------------* /*----------------------------------------------------------------*
* obtain synthesis and weighting filters form lsf coefficients * obtain synthesis and weighting filters form lsf coefficients
*---------------------------------------------------------------*/ *---------------------------------------------------------------*/
@@ -93,29 +101,50 @@ void DecoderInterpolateLSF(
lsfdeq2 = lsfdeq + length; lsfdeq2 = lsfdeq + length;
lp_length = length + 1; lp_length = length + 1;
/* subframe 1: Interpolation between old and first */ if (iLBCdec_inst->mode==30) {
/* sub-frame 1: Interpolation between old and first */
LSFinterpolate2a_dec(lp, (*iLBCdec_inst).lsfdeqold, lsfdeq, LSFinterpolate2a_dec(lp, iLBCdec_inst->lsfdeqold, lsfdeq,
lsf_weightTbl[0], length); lsf_weightTbl_30ms[0], length);
memcpy(syntdenum,lp,lp_length*sizeof(float)); memcpy(syntdenum,lp,lp_length*sizeof(float));
bwexpand(weightdenum, lp, LPC_CHIRP_WEIGHTDENUM, lp_length); bwexpand(weightdenum, lp, LPC_CHIRP_WEIGHTDENUM,
lp_length);
/* subframes 2 to 6: interpolation between first and last /* sub-frames 2 to 6: interpolation between first
LSF */ and last LSF */
pos = lp_length; pos = lp_length;
for (i = 1; i < 6; i++) { for (i = 1; i < 6; i++) {
LSFinterpolate2a_dec(lp, lsfdeq, lsfdeq2, lsf_weightTbl[i], LSFinterpolate2a_dec(lp, lsfdeq, lsfdeq2,
length); lsf_weightTbl_30ms[i], length);
memcpy(syntdenum + pos,lp,lp_length*sizeof(float)); memcpy(syntdenum + pos,lp,lp_length*sizeof(float));
bwexpand(weightdenum + pos, lp, bwexpand(weightdenum + pos, lp,
LPC_CHIRP_WEIGHTDENUM, lp_length); LPC_CHIRP_WEIGHTDENUM, lp_length);
pos += 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 */ /* update memory */
memcpy((*iLBCdec_inst).lsfdeqold, lsfdeq2, length*sizeof(float));
if (iLBCdec_inst->mode==30)
memcpy(iLBCdec_inst->lsfdeqold, lsfdeq2,
length*sizeof(float));
else
memcpy(iLBCdec_inst->lsfdeqold, lsfdeq,
length*sizeof(float));
} }

View File

@@ -5,9 +5,8 @@
LPC_decode.h LPC_decode.h
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/ ******************************************************************/
@@ -15,7 +14,9 @@
#define __iLBC_LPC_DECODE_H #define __iLBC_LPC_DECODE_H
void LSFinterpolate2a_dec( void LSFinterpolate2a_dec(
float *a, /* (o) lpc coefficients for a sub frame */
float *a, /* (o) lpc coefficients for a sub-frame */
float *lsf1, /* (i) first lsf coefficient vector */ float *lsf1, /* (i) first lsf coefficient vector */
float *lsf2, /* (i) second lsf coefficient vector */ float *lsf2, /* (i) second lsf coefficient vector */
float coef, /* (i) interpolation weight */ float coef, /* (i) interpolation weight */
@@ -24,7 +25,8 @@ void LSFinterpolate2a_dec(
void SimplelsfDEQ( void SimplelsfDEQ(
float *lsfdeq, /* (o) dequantized lsf coefficients */ float *lsfdeq, /* (o) dequantized lsf coefficients */
int *index /* (i) quantization index */ int *index, /* (i) quantization index */
int lpc_n /* (i) number of LPCs */
); );
void DecoderInterpolateLSF( void DecoderInterpolateLSF(

View File

@@ -5,71 +5,80 @@
LPCencode.c LPCencode.c
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/ ******************************************************************/
#include <string.h> #include <string.h>
#include "iLBC_define.h" #include "iLBC_define.h"
#include "helpfun.h" #include "helpfun.h"
#include "lsf.h" #include "lsf.h"
#include "constants.h" #include "constants.h"
#include "LPCencode.h"
/*----------------------------------------------------------------* /*----------------------------------------------------------------*
* lpc analysis (subrutine to LPCencode) * lpc analysis (subrutine to LPCencode)
*---------------------------------------------------------------*/ *---------------------------------------------------------------*/
static void SimpleAnalysis( void SimpleAnalysis(
float *lsf, /* (o) lsf coefficients */ float *lsf, /* (o) lsf coefficients */
float *data, /* (i) new data vector */ float *data, /* (i) new data vector */
float *lpc_buffer /* (i) buffer containing old data */ iLBC_Enc_Inst_t *iLBCenc_inst
/* (i/o) the encoder state structure */
){ ){
int k, is; int k, is;
float temp[BLOCKL], lp[LPC_FILTERORDER + 1]; float temp[BLOCKL_MAX], lp[LPC_FILTERORDER + 1];
float lp2[LPC_FILTERORDER + 1]; float lp2[LPC_FILTERORDER + 1];
float r[LPC_FILTERORDER + 1]; float r[LPC_FILTERORDER + 1];
memcpy(lpc_buffer+LPC_LOOKBACK,data,BLOCKL*sizeof(float)); is=LPC_LOOKBACK+BLOCKL_MAX-iLBCenc_inst->blockl;
memcpy(iLBCenc_inst->lpc_buffer+is,data,
iLBCenc_inst->blockl*sizeof(float));
/* No lookahead, last window is asymmetric */ /* No lookahead, last window is asymmetric */
for (k = 0; k < LPC_N; k++) { for (k = 0; k < iLBCenc_inst->lpc_n; k++) {
is = LPC_LOOKBACK; is = LPC_LOOKBACK;
if (k < (LPC_N - 1)) { if (k < (iLBCenc_inst->lpc_n - 1)) {
lbc_window(temp, lpc_winTbl, lpc_buffer, BLOCKL); window(temp, lpc_winTbl,
iLBCenc_inst->lpc_buffer, BLOCKL_MAX);
} else { } else {
lbc_window(temp, lpc_asymwinTbl, lpc_buffer + is, BLOCKL); window(temp, lpc_asymwinTbl,
iLBCenc_inst->lpc_buffer + is, BLOCKL_MAX);
} }
autocorr(r, temp, BLOCKL, LPC_FILTERORDER); autocorr(r, temp, BLOCKL_MAX, LPC_FILTERORDER);
lbc_window(r, r, lpc_lagwinTbl, LPC_FILTERORDER + 1); window(r, r, lpc_lagwinTbl, LPC_FILTERORDER + 1);
levdurb(lp, temp, r, LPC_FILTERORDER); levdurb(lp, temp, r, LPC_FILTERORDER);
bwexpand(lp2, lp, LPC_CHIRP_SYNTDENUM, LPC_FILTERORDER+1); bwexpand(lp2, lp, LPC_CHIRP_SYNTDENUM, LPC_FILTERORDER+1);
a2lsf(lsf + k*LPC_FILTERORDER, lp2); a2lsf(lsf + k*LPC_FILTERORDER, lp2);
} }
memcpy(lpc_buffer, lpc_buffer+BLOCKL, is=LPC_LOOKBACK+BLOCKL_MAX-iLBCenc_inst->blockl;
LPC_LOOKBACK*sizeof(float)); memmove(iLBCenc_inst->lpc_buffer,
iLBCenc_inst->lpc_buffer+LPC_LOOKBACK+BLOCKL_MAX-is,
is*sizeof(float));
} }
/*----------------------------------------------------------------* /*----------------------------------------------------------------*
* lsf interpolator and conversion from lsf to a coefficients * lsf interpolator and conversion from lsf to a coefficients
* (subrutine to SimpleInterpolateLSF) * (subrutine to SimpleInterpolateLSF)
*---------------------------------------------------------------*/ *---------------------------------------------------------------*/
static void LSFinterpolate2a_enc( void LSFinterpolate2a_enc(
float *a, /* (o) lpc coefficients */ float *a, /* (o) lpc coefficients */
float *lsf1,/* (i) first set of lsf coefficients */ float *lsf1,/* (i) first set of lsf coefficients */
float *lsf2,/* (i) second set of lsf coefficients */ float *lsf2,/* (i) second set of lsf coefficients */
float coef, /* (i) weighting coefficient to use between lsf1 float coef, /* (i) weighting coefficient to use between
and lsf2 */ lsf1 and lsf2 */
long length /* (i) length of coefficient vectors */ long length /* (i) length of coefficient vectors */
){ ){
float lsftmp[LPC_FILTERORDER]; float lsftmp[LPC_FILTERORDER];
@@ -82,7 +91,7 @@ static void LSFinterpolate2a_enc(
* lsf interpolator (subrutine to LPCencode) * lsf interpolator (subrutine to LPCencode)
*---------------------------------------------------------------*/ *---------------------------------------------------------------*/
static void SimpleInterpolateLSF( void SimpleInterpolateLSF(
float *syntdenum, /* (o) the synthesis filter denominator float *syntdenum, /* (o) the synthesis filter denominator
resulting from the quantized resulting from the quantized
interpolated lsf */ interpolated lsf */
@@ -95,7 +104,9 @@ static void SimpleInterpolateLSF(
the previous signal frame */ the previous signal frame */
float *lsfdeqold, /* (i) the dequantized lsf coefficients of float *lsfdeqold, /* (i) the dequantized lsf coefficients of
the previous signal frame */ the previous signal frame */
int length /* (i) should equate FILTERORDER */ int length, /* (i) should equate LPC_FILTERORDER */
iLBC_Enc_Inst_t *iLBCenc_inst
/* (i/o) the encoder state structure */
){ ){
int i, pos, lp_length; int i, pos, lp_length;
float lp[LPC_FILTERORDER + 1], *lsf2, *lsfdeq2; float lp[LPC_FILTERORDER + 1], *lsf2, *lsfdeq2;
@@ -104,56 +115,85 @@ static void SimpleInterpolateLSF(
lsfdeq2 = lsfdeq + length; lsfdeq2 = lsfdeq + length;
lp_length = length + 1; lp_length = length + 1;
/* subframe 1: Interpolation between old and first set of if (iLBCenc_inst->mode==30) {
lsf coefficients */ /* sub-frame 1: Interpolation between old and first
LSFinterpolate2a_enc(lp, lsfdeqold, lsfdeq,
lsf_weightTbl[0], length);
memcpy(syntdenum,lp,lp_length*sizeof(float));
LSFinterpolate2a_enc(lp, lsfold, lsf, lsf_weightTbl[0], length);
bwexpand(weightdenum, lp, LPC_CHIRP_WEIGHTDENUM, lp_length);
/* subframe 2 to 6: Interpolation between first and second
set of lsf coefficients */ set of lsf coefficients */
LSFinterpolate2a_enc(lp, lsfdeqold, lsfdeq,
lsf_weightTbl_30ms[0], length);
memcpy(syntdenum,lp,lp_length*sizeof(float));
LSFinterpolate2a_enc(lp, lsfold, lsf,
lsf_weightTbl_30ms[0], length);
bwexpand(weightdenum, lp, LPC_CHIRP_WEIGHTDENUM, lp_length);
/* sub-frame 2 to 6: Interpolation between first
and second set of lsf coefficients */
pos = lp_length; pos = lp_length;
for (i = 1; i < NSUB; i++) { for (i = 1; i < iLBCenc_inst->nsub; i++) {
LSFinterpolate2a_enc(lp, lsfdeq, lsfdeq2, LSFinterpolate2a_enc(lp, lsfdeq, lsfdeq2,
lsf_weightTbl[i], length); lsf_weightTbl_30ms[i], length);
memcpy(syntdenum + pos,lp,lp_length*sizeof(float)); memcpy(syntdenum + pos,lp,lp_length*sizeof(float));
LSFinterpolate2a_enc(lp, lsf, lsf2, LSFinterpolate2a_enc(lp, lsf, lsf2,
lsf_weightTbl[i], length); lsf_weightTbl_30ms[i], length);
bwexpand(weightdenum + pos, lp, bwexpand(weightdenum + pos, lp,
LPC_CHIRP_WEIGHTDENUM, lp_length); LPC_CHIRP_WEIGHTDENUM, lp_length);
pos += lp_length; pos += lp_length;
} }
}
else {
pos = 0;
for (i = 0; i < iLBCenc_inst->nsub; i++) {
LSFinterpolate2a_enc(lp, lsfdeqold, lsfdeq,
lsf_weightTbl_20ms[i], length);
memcpy(syntdenum+pos,lp,lp_length*sizeof(float));
LSFinterpolate2a_enc(lp, lsfold, lsf,
lsf_weightTbl_20ms[i], length);
bwexpand(weightdenum+pos, lp,
LPC_CHIRP_WEIGHTDENUM, lp_length);
pos += lp_length;
}
}
/* update memory */ /* update memory */
if (iLBCenc_inst->mode==30) {
memcpy(lsfold, lsf2, length*sizeof(float)); memcpy(lsfold, lsf2, length*sizeof(float));
memcpy(lsfdeqold, lsfdeq2, length*sizeof(float)); memcpy(lsfdeqold, lsfdeq2, length*sizeof(float));
}
else {
memcpy(lsfold, lsf, length*sizeof(float));
memcpy(lsfdeqold, lsfdeq, length*sizeof(float));
}
} }
/*----------------------------------------------------------------* /*----------------------------------------------------------------*
* lsf quantizer (subrutine to LPCencode) * lsf quantizer (subrutine to LPCencode)
*---------------------------------------------------------------*/ *---------------------------------------------------------------*/
static void SimplelsfQ( void SimplelsfQ(
float *lsfdeq, /* (o) dequantized lsf coefficients float *lsfdeq, /* (o) dequantized lsf coefficients
(dimension FILTERORDER) */ (dimension FILTERORDER) */
int *index, /* (o) quantization index */ int *index, /* (o) quantization index */
float *lsf /* (i) the lsf coefficient vector to be float *lsf, /* (i) the lsf coefficient vector to be
quantized (dimension FILTERORDER ) */ quantized (dimension FILTERORDER ) */
int lpc_n /* (i) number of lsf sets to quantize */
){ ){
/* Quantize first LSF with memoryless split VQ */ /* Quantize first LSF with memoryless split VQ */
SplitVQ(lsfdeq, index, lsf, lsfCbTbl, LSF_NSPLIT, SplitVQ(lsfdeq, index, lsf, lsfCbTbl, LSF_NSPLIT,
dim_lsfCbTbl, size_lsfCbTbl); dim_lsfCbTbl, size_lsfCbTbl);
if (lpc_n==2) {
/* Quantize second LSF with memoryless split VQ */ /* Quantize second LSF with memoryless split VQ */
SplitVQ(lsfdeq + LPC_FILTERORDER, index + LSF_NSPLIT, SplitVQ(lsfdeq + LPC_FILTERORDER, index + LSF_NSPLIT,
lsf + LPC_FILTERORDER, lsfCbTbl, LSF_NSPLIT, lsf + LPC_FILTERORDER, lsfCbTbl, LSF_NSPLIT,
dim_lsfCbTbl, size_lsfCbTbl); dim_lsfCbTbl, size_lsfCbTbl);
}
} }
/*----------------------------------------------------------------* /*----------------------------------------------------------------*
@@ -163,23 +203,25 @@ static void SimplelsfQ(
void LPCencode( void LPCencode(
float *syntdenum, /* (i/o) synthesis filter coefficients float *syntdenum, /* (i/o) synthesis filter coefficients
before/after encoding */ before/after encoding */
float *weightdenum, /* (i/o) weighting denumerator coefficients float *weightdenum, /* (i/o) weighting denumerator
before/after encoding */ coefficients before/after
encoding */
int *lsf_index, /* (o) lsf quantization index */ int *lsf_index, /* (o) lsf quantization index */
float *data, /* (i) lsf coefficients to quantize */ float *data, /* (i) lsf coefficients to quantize */
iLBC_Enc_Inst_t *iLBCenc_inst iLBC_Enc_Inst_t *iLBCenc_inst
/* (i/o) the encoder state structure */ /* (i/o) the encoder state structure */
){ ){
float lsf[LPC_FILTERORDER * LPC_N]; float lsf[LPC_FILTERORDER * LPC_N_MAX];
float lsfdeq[LPC_FILTERORDER * LPC_N]; float lsfdeq[LPC_FILTERORDER * LPC_N_MAX];
int change=0; int change=0;
SimpleAnalysis(lsf, data, (*iLBCenc_inst).lpc_buffer); SimpleAnalysis(lsf, data, iLBCenc_inst);
SimplelsfQ(lsfdeq, lsf_index, lsf); SimplelsfQ(lsfdeq, lsf_index, lsf, iLBCenc_inst->lpc_n);
change=LSF_check(lsfdeq, LPC_FILTERORDER, LPC_N); change=LSF_check(lsfdeq, LPC_FILTERORDER, iLBCenc_inst->lpc_n);
SimpleInterpolateLSF(syntdenum, weightdenum, SimpleInterpolateLSF(syntdenum, weightdenum,
lsf, lsfdeq, (*iLBCenc_inst).lsfold, lsf, lsfdeq, iLBCenc_inst->lsfold,
(*iLBCenc_inst).lsfdeqold, LPC_FILTERORDER); iLBCenc_inst->lsfdeqold, LPC_FILTERORDER, iLBCenc_inst);
} }

View File

@@ -5,9 +5,8 @@
LPCencode.h LPCencode.h
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/ ******************************************************************/

View File

@@ -1,13 +1,14 @@
/****************************************************************** /******************************************************************
iLBC Speech Coder ANSI-C Source Code iLBC Speech Coder ANSI-C Source Code
StateConstructW.c StateConstructW.c
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/ ******************************************************************/
@@ -17,7 +18,6 @@
#include "iLBC_define.h" #include "iLBC_define.h"
#include "constants.h" #include "constants.h"
#include "filter.h" #include "filter.h"
#include "StateConstructW.h"
/*----------------------------------------------------------------* /*----------------------------------------------------------------*
* decoding of the start state * decoding of the start state
@@ -45,7 +45,7 @@ void StateConstructW(
memset(tmpbuf, 0, LPC_FILTERORDER*sizeof(float)); memset(tmpbuf, 0, LPC_FILTERORDER*sizeof(float));
memset(foutbuf, 0, LPC_FILTERORDER*sizeof(float)); memset(foutbuf, 0, LPC_FILTERORDER*sizeof(float));
for(k=0; k<LPC_FILTERORDER; k++){ for (k=0; k<LPC_FILTERORDER; k++) {
numerator[k]=syntDenum[LPC_FILTERORDER-k]; numerator[k]=syntDenum[LPC_FILTERORDER-k];
} }
numerator[LPC_FILTERORDER]=syntDenum[0]; numerator[LPC_FILTERORDER]=syntDenum[0];
@@ -54,9 +54,11 @@ void StateConstructW(
/* decoding of the sample values */ /* decoding of the sample values */
for(k=0; k<len; k++){ for (k=0; k<len; k++) {
tmpi = len-1-k; tmpi = len-1-k;
/* maxVal = 1/scal */ /* maxVal = 1/scal */
tmp[k] = maxVal*state_sq3Tbl[idxVec[tmpi]]; tmp[k] = maxVal*state_sq3Tbl[idxVec[tmpi]];
} }
@@ -65,7 +67,7 @@ void StateConstructW(
memset(tmp+len, 0, len*sizeof(float)); memset(tmp+len, 0, len*sizeof(float));
ZeroPoleFilter(tmp, numerator, syntDenum, 2*len, ZeroPoleFilter(tmp, numerator, syntDenum, 2*len,
LPC_FILTERORDER, fout); LPC_FILTERORDER, fout);
for(k=0;k<len;k++){ for (k=0;k<len;k++) {
out[k] = fout[len-1-k]+fout[2*len-1-k]; out[k] = fout[len-1-k]+fout[2*len-1-k];
} }
} }

View File

@@ -5,9 +5,8 @@
StateConstructW.h StateConstructW.h
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/ ******************************************************************/

View File

@@ -5,9 +5,8 @@
StateSearchW.c StateSearchW.c
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/ ******************************************************************/
@@ -18,7 +17,6 @@
#include "constants.h" #include "constants.h"
#include "filter.h" #include "filter.h"
#include "helpfun.h" #include "helpfun.h"
#include "StateSearchW.h"
/*----------------------------------------------------------------* /*----------------------------------------------------------------*
* predictive noise shaping encoding of scaled start state * predictive noise shaping encoding of scaled start state
@@ -26,6 +24,8 @@
*---------------------------------------------------------------*/ *---------------------------------------------------------------*/
void AbsQuantW( void AbsQuantW(
iLBC_Enc_Inst_t *iLBCenc_inst,
/* (i) Encoder instance */
float *in, /* (i) vector to encode */ float *in, /* (i) vector to encode */
float *syntDenum, /* (i) denominator of synthesis filter */ float *syntDenum, /* (i) denominator of synthesis filter */
float *weightDenum, /* (i) denominator of weighting filter */ float *weightDenum, /* (i) denominator of weighting filter */
@@ -35,7 +35,8 @@ void AbsQuantW(
int state_first /* (i) position of start state in the int state_first /* (i) position of start state in the
80 vec */ 80 vec */
){ ){
float *syntOut, syntOutBuf[LPC_FILTERORDER+STATE_SHORT_LEN]; float *syntOut;
float syntOutBuf[LPC_FILTERORDER+STATE_SHORT_LEN_30MS];
float toQ, xq; float toQ, xq;
int n; int n;
int index; int index;
@@ -44,6 +45,8 @@ void AbsQuantW(
memset(syntOutBuf, 0, LPC_FILTERORDER*sizeof(float)); memset(syntOutBuf, 0, LPC_FILTERORDER*sizeof(float));
/* initialization of pointer for filtering */ /* initialization of pointer for filtering */
syntOut = &syntOutBuf[LPC_FILTERORDER]; syntOut = &syntOutBuf[LPC_FILTERORDER];
@@ -53,13 +56,14 @@ void AbsQuantW(
if (state_first) { if (state_first) {
AllPoleFilter (in, weightDenum, SUBL, LPC_FILTERORDER); AllPoleFilter (in, weightDenum, SUBL, LPC_FILTERORDER);
} else { } else {
AllPoleFilter (in, weightDenum, STATE_SHORT_LEN-SUBL, AllPoleFilter (in, weightDenum,
iLBCenc_inst->state_short_len-SUBL,
LPC_FILTERORDER); LPC_FILTERORDER);
} }
/* encoding loop */ /* encoding loop */
for(n=0;n<len;n++){ for (n=0; n<len; n++) {
/* time update of filter coefficients */ /* time update of filter coefficients */
@@ -71,7 +75,8 @@ void AbsQuantW(
AllPoleFilter (&in[n], weightDenum, len-n, AllPoleFilter (&in[n], weightDenum, len-n,
LPC_FILTERORDER); LPC_FILTERORDER);
} else if ((state_first==0)&&(n==(STATE_SHORT_LEN-SUBL))) { } else if ((state_first==0)&&
(n==(iLBCenc_inst->state_short_len-SUBL))) {
syntDenum += (LPC_FILTERORDER+1); syntDenum += (LPC_FILTERORDER+1);
weightDenum += (LPC_FILTERORDER+1); weightDenum += (LPC_FILTERORDER+1);
@@ -84,7 +89,8 @@ void AbsQuantW(
/* prediction of synthesized and weighted input */ /* prediction of synthesized and weighted input */
syntOut[n] = 0.0; syntOut[n] = 0.0;
AllPoleFilter (&syntOut[n], weightDenum, 1, LPC_FILTERORDER); AllPoleFilter (&syntOut[n], weightDenum, 1,
LPC_FILTERORDER);
/* quantization */ /* quantization */
@@ -95,7 +101,10 @@ void AbsQuantW(
/* update of the prediction filter */ /* update of the prediction filter */
AllPoleFilter(&syntOut[n], weightDenum, 1, LPC_FILTERORDER);
AllPoleFilter(&syntOut[n], weightDenum, 1,
LPC_FILTERORDER);
} }
} }
@@ -104,6 +113,8 @@ void AbsQuantW(
*---------------------------------------------------------------*/ *---------------------------------------------------------------*/
void StateSearchW( void StateSearchW(
iLBC_Enc_Inst_t *iLBCenc_inst,
/* (i) Encoder instance */
float *residual,/* (i) target residual vector */ float *residual,/* (i) target residual vector */
float *syntDenum, /* (i) lpc synthesis filter */ float *syntDenum, /* (i) lpc synthesis filter */
float *weightDenum, /* (i) weighting filter denuminator */ float *weightDenum, /* (i) weighting filter denuminator */
@@ -114,9 +125,10 @@ void StateSearchW(
int state_first /* (i) position of start state in the int state_first /* (i) position of start state in the
80 vec */ 80 vec */
){ ){
float dtmp, maxVal, tmpbuf[LPC_FILTERORDER+2*STATE_SHORT_LEN]; float dtmp, maxVal;
float tmpbuf[LPC_FILTERORDER+2*STATE_SHORT_LEN_30MS];
float *tmp, numerator[1+LPC_FILTERORDER]; float *tmp, numerator[1+LPC_FILTERORDER];
float foutbuf[LPC_FILTERORDER+2*STATE_SHORT_LEN], *fout; float foutbuf[LPC_FILTERORDER+2*STATE_SHORT_LEN_30MS], *fout;
int k; int k;
float qmax, scal; float qmax, scal;
@@ -124,7 +136,7 @@ void StateSearchW(
memset(tmpbuf, 0, LPC_FILTERORDER*sizeof(float)); memset(tmpbuf, 0, LPC_FILTERORDER*sizeof(float));
memset(foutbuf, 0, LPC_FILTERORDER*sizeof(float)); memset(foutbuf, 0, LPC_FILTERORDER*sizeof(float));
for(k=0; k<LPC_FILTERORDER; k++){ for (k=0; k<LPC_FILTERORDER; k++) {
numerator[k]=syntDenum[LPC_FILTERORDER-k]; numerator[k]=syntDenum[LPC_FILTERORDER-k];
} }
numerator[LPC_FILTERORDER]=syntDenum[0]; numerator[LPC_FILTERORDER]=syntDenum[0];
@@ -137,16 +149,18 @@ void StateSearchW(
memset(tmp+len, 0, len*sizeof(float)); memset(tmp+len, 0, len*sizeof(float));
ZeroPoleFilter(tmp, numerator, syntDenum, 2*len, ZeroPoleFilter(tmp, numerator, syntDenum, 2*len,
LPC_FILTERORDER, fout); LPC_FILTERORDER, fout);
for(k=0;k<len;k++){ for (k=0; k<len; k++) {
fout[k] += fout[k+len]; fout[k] += fout[k+len];
} }
/* identification of the maximum amplitude value */ /* identification of the maximum amplitude value */
maxVal = fout[0]; maxVal = fout[0];
for(k=1; k<len; k++){
if(fout[k]*fout[k] > maxVal*maxVal){
for (k=1; k<len; k++) {
if (fout[k]*fout[k] > maxVal*maxVal){
maxVal = fout[k]; maxVal = fout[k];
} }
} }
@@ -154,7 +168,7 @@ void StateSearchW(
/* encoding of the maximum amplitude value */ /* encoding of the maximum amplitude value */
if(maxVal < 10.0){ if (maxVal < 10.0) {
maxVal = 10.0; maxVal = 10.0;
} }
maxVal = (float)log10(maxVal); maxVal = (float)log10(maxVal);
@@ -166,13 +180,14 @@ void StateSearchW(
maxVal=state_frgqTbl[*idxForMax]; maxVal=state_frgqTbl[*idxForMax];
qmax = (float)pow(10,maxVal); qmax = (float)pow(10,maxVal);
scal = (float)(4.5)/qmax; scal = (float)(4.5)/qmax;
for(k=0;k<len;k++){ for (k=0; k<len; k++){
fout[k] *= scal; fout[k] *= scal;
} }
/* predictive noise shaping encoding of scaled start state */ /* predictive noise shaping encoding of scaled start state */
AbsQuantW(fout,syntDenum,weightDenum,idxVec, len, state_first); AbsQuantW(iLBCenc_inst, fout,syntDenum,
weightDenum,idxVec, len, state_first);
} }

View File

@@ -5,9 +5,8 @@
StateSearchW.h StateSearchW.h
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/ ******************************************************************/
@@ -15,6 +14,8 @@
#define __iLBC_STATESEARCHW_H #define __iLBC_STATESEARCHW_H
void AbsQuantW( void AbsQuantW(
iLBC_Enc_Inst_t *iLBCenc_inst,
/* (i) Encoder instance */
float *in, /* (i) vector to encode */ float *in, /* (i) vector to encode */
float *syntDenum, /* (i) denominator of synthesis filter */ float *syntDenum, /* (i) denominator of synthesis filter */
float *weightDenum, /* (i) denominator of weighting filter */ float *weightDenum, /* (i) denominator of weighting filter */
@@ -26,6 +27,8 @@ void AbsQuantW(
); );
void StateSearchW( void StateSearchW(
iLBC_Enc_Inst_t *iLBCenc_inst,
/* (i) Encoder instance */
float *residual,/* (i) target residual vector */ float *residual,/* (i) target residual vector */
float *syntDenum, /* (i) lpc synthesis filter */ float *syntDenum, /* (i) lpc synthesis filter */
float *weightDenum, /* (i) weighting filter denuminator */ float *weightDenum, /* (i) weighting filter denuminator */
@@ -34,6 +37,8 @@ void StateSearchW(
int *idxVec, /* (o) vector of quantization indexes */ int *idxVec, /* (o) vector of quantization indexes */
int len, /* (i) length of all vectors */ int len, /* (i) length of all vectors */
int state_first /* (i) position of start state in the int state_first /* (i) position of start state in the
80 vec */ 80 vec */
); );

View File

@@ -5,18 +5,18 @@
anaFilter.c anaFilter.c
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/ ******************************************************************/
#include <string.h> #include <string.h>
#include "iLBC_define.h" #include "iLBC_define.h"
#include "anaFilter.h"
/*----------------------------------------------------------------* /*----------------------------------------------------------------*
* LP analysis filter. * LP analysis filter.
*---------------------------------------------------------------*/ *---------------------------------------------------------------*/
void anaFilter( void anaFilter(
@@ -33,15 +33,16 @@ void anaFilter(
/* Filter first part using memory from past */ /* Filter first part using memory from past */
for (i=0;i<LPC_FILTERORDER;i++) { for (i=0; i<LPC_FILTERORDER; i++) {
pi = &In[i]; pi = &In[i];
pm = &mem[LPC_FILTERORDER-1]; pm = &mem[LPC_FILTERORDER-1];
pa = a; pa = a;
*po=0.0; *po=0.0;
for (j=0;j<=i;j++) { for (j=0; j<=i; j++) {
*po+=(*pa++)*(*pi--); *po+=(*pa++)*(*pi--);
} }
for (j=i+1;j<LPC_FILTERORDER+1;j++) { for (j=i+1; j<LPC_FILTERORDER+1; j++) {
*po+=(*pa++)*(*pm--); *po+=(*pa++)*(*pm--);
} }
po++; po++;
@@ -50,11 +51,11 @@ void anaFilter(
/* Filter last part where the state is entierly /* Filter last part where the state is entierly
in the input vector */ in the input vector */
for (i=LPC_FILTERORDER;i<len;i++) { for (i=LPC_FILTERORDER; i<len; i++) {
pi = &In[i]; pi = &In[i];
pa = a; pa = a;
*po=0.0; *po=0.0;
for (j=0;j<LPC_FILTERORDER+1;j++) { for (j=0; j<LPC_FILTERORDER+1; j++) {
*po+=(*pa++)*(*pi--); *po+=(*pa++)*(*pi--);
} }
po++; po++;

View File

@@ -5,9 +5,8 @@
anaFilter.h anaFilter.h
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/ ******************************************************************/

View File

@@ -5,51 +5,66 @@
constants.c constants.c
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/ ******************************************************************/
#include "iLBC_define.h" #include "iLBC_define.h"
/* bit allocation */
int lsf_bitsTbl[6]={6,7,7,6,7,7};
int start_bitsTbl=3;
int scale_bitsTbl=6;
int state_bitsTbl=3;
int cb_bitsTbl[5][CB_NSTAGES]={{7,7,7},{8,7,7},
{8,8,8},{8,8,8},{8,8,8}};
int search_rangeTbl[5][CB_NSTAGES]={{58,58,58}, {108,44,44},
{108,108,108}, {108,108,108}, {108,108,108}};
int gain_bitsTbl[3]={5,4,3};
/* ULP bit allocation */ /* ULP bit allocation */
int ulp_lsf_bitsTbl[6][ULP_CLASSES+2]={ /* 20 ms frame */
{6,0,0,0,0},{7,0,0,0,0},
{7,0,0,0,0},{6,0,0,0,0},
{7,0,0,0,0},{7,0,0,0,0}};
int ulp_start_bitsTbl[ULP_CLASSES+2]={3,0,0,0,0};
int ulp_startfirst_bitsTbl[ULP_CLASSES+2]={1,0,0,0,0};
int ulp_scale_bitsTbl[ULP_CLASSES+2]={6,0,0,0,0};
int ulp_state_bitsTbl[ULP_CLASSES+2]={0,1,2,0,0};
int ulp_extra_cb_indexTbl[CB_NSTAGES][ULP_CLASSES+2]={ const iLBC_ULP_Inst_t ULP_20msTbl = {
{4,2,1,0,0},{0,0,7,0,0},{0,0,7,0,0}}; /* LSF */
int ulp_extra_cb_gainTbl[CB_NSTAGES][ULP_CLASSES+2]={ { {6,0,0,0,0}, {7,0,0,0,0}, {7,0,0,0,0},
{1,1,3,0,0},{1,1,2,0,0},{0,0,3,0,0}}; {0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}},
int ulp_cb_indexTbl[NASUB][CB_NSTAGES][ULP_CLASSES+2]={ /* Start state location, gain and samples */
{{6,1,1,0,0},{0,0,7,0,0},{0,0,7,0,0}}, {2,0,0,0,0},
{{0,7,1,0,0},{0,0,8,0,0},{0,0,8,0,0}}, {1,0,0,0,0},
{{0,7,1,0,0},{0,0,8,0,0},{0,0,8,0,0}}, {6,0,0,0,0},
{{0,7,1,0,0},{0,0,8,0,0},{0,0,8,0,0}}}; {0,1,2,0,0},
int ulp_cb_gainTbl[NASUB][CB_NSTAGES][ULP_CLASSES+2]={ /* extra CB index and extra CB gain */
{{1,2,2,0,0},{1,2,1,0,0},{0,0,3,0,0}}, {{6,0,1,0,0}, {0,0,7,0,0}, {0,0,7,0,0}},
{{0,2,3,0,0},{0,2,2,0,0},{0,0,3,0,0}}, {{2,0,3,0,0}, {1,1,2,0,0}, {0,0,3,0,0}},
{{0,1,4,0,0},{0,1,3,0,0},{0,0,3,0,0}}, /* CB index and CB gain */
{{0,1,4,0,0},{0,1,3,0,0},{0,0,3,0,0}}}; { {{7,0,1,0,0}, {0,0,7,0,0}, {0,0,7,0,0}},
{{0,0,8,0,0}, {0,0,8,0,0}, {0,0,8,0,0}},
{{0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}},
{{0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}}},
{ {{1,2,2,0,0}, {1,1,2,0,0}, {0,0,3,0,0}},
{{1,1,3,0,0}, {0,2,2,0,0}, {0,0,3,0,0}},
{{0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}},
{{0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}}}
};
/* 30 ms frame */
const iLBC_ULP_Inst_t ULP_30msTbl = {
/* LSF */
{ {6,0,0,0,0}, {7,0,0,0,0}, {7,0,0,0,0},
{6,0,0,0,0}, {7,0,0,0,0}, {7,0,0,0,0}},
/* Start state location, gain and samples */
{3,0,0,0,0},
{1,0,0,0,0},
{6,0,0,0,0},
{0,1,2,0,0},
/* extra CB index and extra CB gain */
{{4,2,1,0,0}, {0,0,7,0,0}, {0,0,7,0,0}},
{{1,1,3,0,0}, {1,1,2,0,0}, {0,0,3,0,0}},
/* CB index and CB gain */
{ {{6,1,1,0,0}, {0,0,7,0,0}, {0,0,7,0,0}},
{{0,7,1,0,0}, {0,0,8,0,0}, {0,0,8,0,0}},
{{0,7,1,0,0}, {0,0,8,0,0}, {0,0,8,0,0}},
{{0,7,1,0,0}, {0,0,8,0,0}, {0,0,8,0,0}}},
{ {{1,2,2,0,0}, {1,2,1,0,0}, {0,0,3,0,0}},
{{0,2,3,0,0}, {0,2,2,0,0}, {0,0,3,0,0}},
{{0,1,4,0,0}, {0,1,3,0,0}, {0,0,3,0,0}},
{{0,1,4,0,0}, {0,1,3,0,0}, {0,0,3,0,0}}}
};
/* HP Filters */ /* HP Filters */
@@ -85,6 +100,8 @@ float state_sq3Tbl[8] = {
float state_frgqTbl[64] = { float state_frgqTbl[64] = {
(float)1.000085, (float)1.071695, (float)1.140395, (float)1.000085, (float)1.071695, (float)1.140395,
(float)1.206868, (float)1.277188, (float)1.351503, (float)1.206868, (float)1.277188, (float)1.351503,
(float)1.429380, (float)1.500727, (float)1.569049, (float)1.429380, (float)1.500727, (float)1.569049,
(float)1.639599, (float)1.707071, (float)1.781531, (float)1.639599, (float)1.707071, (float)1.781531,
(float)1.840799, (float)1.901550, (float)1.956695, (float)1.840799, (float)1.901550, (float)1.956695,
@@ -109,15 +126,18 @@ float state_frgqTbl[64] = {
/* CB tables */ /* CB tables */
int search_rangeTbl[5][CB_NSTAGES]={{58,58,58}, {108,44,44},
{108,108,108}, {108,108,108}, {108,108,108}};
int stMemLTbl=85; int stMemLTbl=85;
int memLfTbl[NASUB]={147,147,147,147}; int memLfTbl[NASUB_MAX]={147,147,147,147};
/* expansion filter(s) */ /* expansion filter(s) */
float cbfiltersTbl[CB_FILTERLEN]={ float cbfiltersTbl[CB_FILTERLEN]={
(float)-0.033691, (float)0.083740, (float)-0.144043, (float)-0.034180, (float)0.108887, (float)-0.184326,
(float)0.713379, (float)0.806152, (float)-0.184326, (float)0.806152, (float)0.713379, (float)-0.144043,
(float)0.108887, (float)-0.034180}; (float)0.083740, (float)-0.033691
};
/* Gain Quantization */ /* Gain Quantization */
@@ -136,6 +156,8 @@ float gain_sq4Tbl[16]={
float gain_sq5Tbl[32]={ float gain_sq5Tbl[32]={
(float)0.037476, (float)0.075012, (float)0.112488, (float)0.037476, (float)0.075012, (float)0.112488,
(float)0.150024, (float)0.187500, (float)0.224976, (float)0.150024, (float)0.187500, (float)0.224976,
(float)0.262512, (float)0.299988, (float)0.337524, (float)0.262512, (float)0.299988, (float)0.337524,
(float)0.375000, (float)0.412476, (float)0.450012, (float)0.375000, (float)0.412476, (float)0.450012,
@@ -178,16 +200,20 @@ float lsfmeanTbl[LPC_FILTERORDER] = {
(float)1.850586, (float)2.137817, (float)2.481445, (float)1.850586, (float)2.137817, (float)2.481445,
(float)2.777344}; (float)2.777344};
float lsf_weightTbl[6] = {(float)(1.0/2.0), (float)1.0, float lsf_weightTbl_30ms[6] = {(float)(1.0/2.0), (float)1.0,
(float)(2.0/3.0), (float)(2.0/3.0),
(float)(1.0/3.0), (float)0.0, (float)0.0}; (float)(1.0/3.0), (float)0.0, (float)0.0};
float lsf_weightTbl_20ms[4] = {(float)(3.0/4.0), (float)(2.0/4.0),
(float)(1.0/4.0), (float)(0.0)};
/* Hanning LPC window */ /* Hanning LPC window */
float lpc_winTbl[BLOCKL]={ float lpc_winTbl[BLOCKL_MAX]={
(float)0.000183, (float)0.000671, (float)0.001526, (float)0.000183, (float)0.000671, (float)0.001526,
(float)0.002716, (float)0.004242, (float)0.006104, (float)0.002716, (float)0.004242, (float)0.006104,
(float)0.008301, (float)0.010834, (float)0.013702, (float)0.008301, (float)0.010834, (float)0.013702,
(float)0.016907, (float)0.020416, (float)0.024261, (float)0.016907, (float)0.020416, (float)0.024261,
(float)0.028442, (float)0.032928, (float)0.037750, (float)0.028442, (float)0.032928, (float)0.037750,
(float)0.042877, (float)0.048309, (float)0.054047, (float)0.042877, (float)0.048309, (float)0.054047,
@@ -242,6 +268,8 @@ float lpc_winTbl[BLOCKL]={
(float)0.723206, (float)0.711487, (float)0.699585, (float)0.723206, (float)0.711487, (float)0.699585,
(float)0.687561, (float)0.675415, (float)0.663147, (float)0.687561, (float)0.675415, (float)0.663147,
(float)0.650787, (float)0.638306, (float)0.625732, (float)0.650787, (float)0.638306, (float)0.625732,
(float)0.613068, (float)0.600342, (float)0.587524, (float)0.613068, (float)0.600342, (float)0.587524,
(float)0.574677, (float)0.561768, (float)0.548798, (float)0.574677, (float)0.561768, (float)0.548798,
(float)0.535828, (float)0.522797, (float)0.509766, (float)0.535828, (float)0.522797, (float)0.509766,
@@ -268,7 +296,7 @@ float lpc_winTbl[BLOCKL]={
}; };
/* Asymmetric LPC window */ /* Asymmetric LPC window */
float lpc_asymwinTbl[BLOCKL]={ float lpc_asymwinTbl[BLOCKL_MAX]={
(float)0.000061, (float)0.000214, (float)0.000458, (float)0.000061, (float)0.000214, (float)0.000458,
(float)0.000824, (float)0.001282, (float)0.001831, (float)0.000824, (float)0.001282, (float)0.001831,
(float)0.002472, (float)0.003235, (float)0.004120, (float)0.002472, (float)0.003235, (float)0.004120,
@@ -296,6 +324,8 @@ float lpc_asymwinTbl[BLOCKL]={
(float)0.246918, (float)0.253082, (float)0.259308, (float)0.246918, (float)0.253082, (float)0.259308,
(float)0.265564, (float)0.271881, (float)0.278259, (float)0.265564, (float)0.271881, (float)0.278259,
(float)0.284668, (float)0.291107, (float)0.297607, (float)0.284668, (float)0.291107, (float)0.297607,
(float)0.304138, (float)0.310730, (float)0.317322, (float)0.304138, (float)0.310730, (float)0.317322,
(float)0.323975, (float)0.330658, (float)0.337372, (float)0.323975, (float)0.330658, (float)0.337372,
(float)0.344147, (float)0.350922, (float)0.357727, (float)0.344147, (float)0.350922, (float)0.357727,
@@ -351,6 +381,8 @@ float lpc_asymwinTbl[BLOCKL]={
(float)0.233459, (float)0.156433, (float)0.078461 (float)0.233459, (float)0.156433, (float)0.078461
}; };
/* Lag window for LPC */ /* Lag window for LPC */
float lpc_lagwinTbl[LPC_FILTERORDER + 1]={ float lpc_lagwinTbl[LPC_FILTERORDER + 1]={
(float)1.000100, (float)0.998890, (float)0.995569, (float)1.000100, (float)0.998890, (float)0.995569,
@@ -404,6 +436,8 @@ float lsfCbTbl[64 * 3 + 128 * 3 + 128 * 4] = {
(float)0.275757, (float)0.420776, (float)0.598755, (float)0.275757, (float)0.420776, (float)0.598755,
(float)0.380493, (float)0.608643, (float)0.861084, (float)0.380493, (float)0.608643, (float)0.861084,
(float)0.222778, (float)0.426147, (float)0.676514, (float)0.222778, (float)0.426147, (float)0.676514,
(float)0.407471, (float)0.700195, (float)1.053101, (float)0.407471, (float)0.700195, (float)1.053101,
(float)0.218384, (float)0.377197, (float)0.669922, (float)0.218384, (float)0.377197, (float)0.669922,
(float)0.313232, (float)0.454102, (float)0.600952, (float)0.313232, (float)0.454102, (float)0.600952,
@@ -458,6 +492,8 @@ float lsfCbTbl[64 * 3 + 128 * 3 + 128 * 4] = {
(float)0.841797, (float)1.055664, (float)1.249268, (float)0.841797, (float)1.055664, (float)1.249268,
(float)0.920166, (float)1.119385, (float)1.486206, (float)0.920166, (float)1.119385, (float)1.486206,
(float)0.894409, (float)1.539063, (float)1.828979, (float)0.894409, (float)1.539063, (float)1.828979,
(float)1.283691, (float)1.543335, (float)1.858276, (float)1.283691, (float)1.543335, (float)1.858276,
(float)0.676025, (float)0.933105, (float)1.490845, (float)0.676025, (float)0.933105, (float)1.490845,
(float)0.821289, (float)1.491821, (float)1.739868, (float)0.821289, (float)1.491821, (float)1.739868,
@@ -512,6 +548,8 @@ float lsfCbTbl[64 * 3 + 128 * 3 + 128 * 4] = {
(float)0.823975, (float)1.450806, (float)1.917725, (float)0.823975, (float)1.450806, (float)1.917725,
(float)0.859009, (float)1.016602, (float)1.191895, (float)0.859009, (float)1.016602, (float)1.191895,
(float)0.843994, (float)1.131104, (float)1.645020, (float)0.843994, (float)1.131104, (float)1.645020,
(float)1.189697, (float)1.702759, (float)1.894409, (float)1.189697, (float)1.702759, (float)1.894409,
(float)1.346680, (float)1.763184, (float)2.066040, (float)1.346680, (float)1.763184, (float)2.066040,
(float)0.980469, (float)1.253784, (float)1.441650, (float)0.980469, (float)1.253784, (float)1.441650,
@@ -566,6 +604,8 @@ float lsfCbTbl[64 * 3 + 128 * 3 + 128 * 4] = {
(float)1.746826, (float)2.057373, (float)2.320190, (float)2.800781, (float)1.746826, (float)2.057373, (float)2.320190, (float)2.800781,
(float)1.734619, (float)1.940552, (float)2.306030, (float)2.826416, (float)1.734619, (float)1.940552, (float)2.306030, (float)2.826416,
(float)1.786255, (float)2.204468, (float)2.457520, (float)2.795288, (float)1.786255, (float)2.204468, (float)2.457520, (float)2.795288,
(float)1.861084, (float)2.170532, (float)2.414551, (float)2.763672, (float)1.861084, (float)2.170532, (float)2.414551, (float)2.763672,
(float)2.001465, (float)2.307617, (float)2.552734, (float)2.811890, (float)2.001465, (float)2.307617, (float)2.552734, (float)2.811890,
(float)1.784424, (float)2.124146, (float)2.381592, (float)2.645508, (float)1.784424, (float)2.124146, (float)2.381592, (float)2.645508,
@@ -620,6 +660,8 @@ float lsfCbTbl[64 * 3 + 128 * 3 + 128 * 4] = {
(float)1.621094, (float)2.028198, (float)2.431030, (float)2.664673, (float)1.621094, (float)2.028198, (float)2.431030, (float)2.664673,
(float)1.824951, (float)2.267456, (float)2.514526, (float)2.747925, (float)1.824951, (float)2.267456, (float)2.514526, (float)2.747925,
(float)1.994263, (float)2.229126, (float)2.475220, (float)2.833984, (float)1.994263, (float)2.229126, (float)2.475220, (float)2.833984,
(float)1.746338, (float)2.011353, (float)2.588257, (float)2.826904, (float)1.746338, (float)2.011353, (float)2.588257, (float)2.826904,
(float)1.562866, (float)2.135986, (float)2.471680, (float)2.687256, (float)1.562866, (float)2.135986, (float)2.471680, (float)2.687256,
(float)1.748901, (float)2.083496, (float)2.460938, (float)2.686279, (float)1.748901, (float)2.083496, (float)2.460938, (float)2.686279,
@@ -674,6 +716,8 @@ float lsfCbTbl[64 * 3 + 128 * 3 + 128 * 4] = {
(float)1.499756, (float)1.867554, (float)2.341064, (float)2.578857, (float)1.499756, (float)1.867554, (float)2.341064, (float)2.578857,
(float)1.916870, (float)2.135132, (float)2.568237, (float)2.826050, (float)1.916870, (float)2.135132, (float)2.568237, (float)2.826050,
(float)1.498047, (float)1.711182, (float)2.223267, (float)2.755127, (float)1.498047, (float)1.711182, (float)2.223267, (float)2.755127,
(float)1.808716, (float)1.997559, (float)2.256470, (float)2.758545, (float)1.808716, (float)1.997559, (float)2.256470, (float)2.758545,
(float)2.088501, (float)2.402710, (float)2.667358, (float)2.890259, (float)2.088501, (float)2.402710, (float)2.667358, (float)2.890259,
(float)1.545044, (float)1.819214, (float)2.324097, (float)2.692993, (float)1.545044, (float)1.819214, (float)2.324097, (float)2.692993,

View File

@@ -5,9 +5,10 @@
constants.h constants.h
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/ ******************************************************************/
@@ -16,27 +17,11 @@
#include "iLBC_define.h" #include "iLBC_define.h"
/* bit allocation */
extern int lsf_bitsTbl[];
extern int start_bitsTbl;
extern int scale_bitsTbl;
extern int state_bitsTbl;
extern int cb_bitsTbl[5][CB_NSTAGES];
extern int search_rangeTbl[5][CB_NSTAGES];
extern int gain_bitsTbl[];
/* ULP bit allocation */ /* ULP bit allocation */
extern int ulp_lsf_bitsTbl[6][ULP_CLASSES+2]; extern const iLBC_ULP_Inst_t ULP_20msTbl;
extern int ulp_start_bitsTbl[]; extern const iLBC_ULP_Inst_t ULP_30msTbl;
extern int ulp_startfirst_bitsTbl[];
extern int ulp_scale_bitsTbl[];
extern int ulp_state_bitsTbl[];
extern int ulp_extra_cb_indexTbl[CB_NSTAGES][ULP_CLASSES+2];
extern int ulp_extra_cb_gainTbl[CB_NSTAGES][ULP_CLASSES+2];
extern int ulp_cb_indexTbl[NASUB][CB_NSTAGES][ULP_CLASSES+2];
extern int ulp_cb_gainTbl[NASUB][CB_NSTAGES][ULP_CLASSES+2];
/* high pass filters */ /* high pass filters */
@@ -57,7 +42,8 @@ extern float lsfCbTbl[];
extern float lsfmeanTbl[]; extern float lsfmeanTbl[];
extern int dim_lsfCbTbl[]; extern int dim_lsfCbTbl[];
extern int size_lsfCbTbl[]; extern int size_lsfCbTbl[];
extern float lsf_weightTbl[]; extern float lsf_weightTbl_30ms[];
extern float lsf_weightTbl_20ms[];
/* state quantization tables */ /* state quantization tables */
@@ -72,10 +58,13 @@ extern float gain_sq5Tbl[];
/* adaptive codebook definitions */ /* adaptive codebook definitions */
extern int search_rangeTbl[5][CB_NSTAGES];
extern int memLfTbl[]; extern int memLfTbl[];
extern int stMemLTbl; extern int stMemLTbl;
extern float cbfiltersTbl[CB_FILTERLEN]; extern float cbfiltersTbl[CB_FILTERLEN];
/* enhancer definitions */ /* enhancer definitions */
extern float polyphaserTbl[]; extern float polyphaserTbl[];

View File

@@ -1,19 +1,19 @@
/****************************************************************** /******************************************************************
iLBC Speech Coder ANSI-C Source Code iLBC Speech Coder ANSI-C Source Code
createCB.c createCB.c
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/ ******************************************************************/
#include "iLBC_define.h" #include "iLBC_define.h"
#include "constants.h" #include "constants.h"
#include "createCB.h"
#include <string.h> #include <string.h>
#include <math.h> #include <math.h>
@@ -24,10 +24,10 @@
*---------------------------------------------------------------*/ *---------------------------------------------------------------*/
void filteredCBvecs( void filteredCBvecs(
float *cbvectors, /* (o) Codebook vectors for the higher float *cbvectors, /* (o) Codebook vectors for the
section */ higher section */
float *mem, /* (i) Buffer to create codebook vector from float *mem, /* (i) Buffer to create codebook
*/ vector from */
int lMem /* (i) Length of buffer */ int lMem /* (i) Length of buffer */
){ ){
int j, k; int j, k;
@@ -47,14 +47,16 @@ section */
memset(pos, 0, lMem*sizeof(float)); memset(pos, 0, lMem*sizeof(float));
for (k=0; k<lMem; k++) { for (k=0; k<lMem; k++) {
pp=&tempbuff2[k]; pp=&tempbuff2[k];
pp1=&cbfiltersTbl[0]; pp1=&cbfiltersTbl[CB_FILTERLEN-1];
for (j=0;j<CB_FILTERLEN;j++) { for (j=0;j<CB_FILTERLEN;j++) {
(*pos)+=(*pp++)*(*pp1++); (*pos)+=(*pp++)*(*pp1--);
} }
pos++; pos++;
} }
} }
/*----------------------------------------------------------------* /*----------------------------------------------------------------*
* Search the augmented part of the codebook to find the best * Search the augmented part of the codebook to find the best
* measure. * measure.
@@ -77,7 +79,7 @@ void searchAugmentedCB(
float *invenergy/* (o) Inv energy of augmented codebook float *invenergy/* (o) Inv energy of augmented codebook
vectors */ vectors */
) { ) {
int lagcount, ilow, j, tmpIndex; int icount, ilow, j, tmpIndex;
float *pp, *ppo, *ppi, *ppe, crossDot, alfa; float *pp, *ppo, *ppi, *ppe, crossDot, alfa;
float weighted, measure, nrjRecursive; float weighted, measure, nrjRecursive;
float ftmp; float ftmp;
@@ -93,22 +95,25 @@ void searchAugmentedCB(
ppe = buffer - low; ppe = buffer - low;
for (lagcount=low; lagcount<=high; lagcount++) { for (icount=low; icount<=high; icount++) {
/* Index of the codebook vector used for retrieving /* Index of the codebook vector used for retrieving
energy values */ energy values */
tmpIndex = startIndex+lagcount-20; tmpIndex = startIndex+icount-20;
ilow = lagcount-4; ilow = icount-4;
/* Update the energy recursively to save complexity */ /* Update the energy recursively to save complexity */
nrjRecursive = nrjRecursive + (*ppe)*(*ppe); nrjRecursive = nrjRecursive + (*ppe)*(*ppe);
ppe--; ppe--;
energy[tmpIndex] = nrjRecursive; energy[tmpIndex] = nrjRecursive;
/* Compute cross dot product for the first (low-5) samples */ /* Compute cross dot product for the first (low-5)
samples */
crossDot = (float) 0.0; crossDot = (float) 0.0;
pp = buffer-lagcount;
pp = buffer-icount;
for (j=0; j<ilow; j++) { for (j=0; j<ilow; j++) {
crossDot += target[j]*(*pp++); crossDot += target[j]*(*pp++);
} }
@@ -116,8 +121,8 @@ void searchAugmentedCB(
/* interpolation */ /* interpolation */
alfa = (float) 0.2; alfa = (float) 0.2;
ppo = buffer-4; ppo = buffer-4;
ppi = buffer-lagcount-4; ppi = buffer-icount-4;
for (j=ilow; j<lagcount; j++) { for (j=ilow; j<icount; j++) {
weighted = ((float)1.0-alfa)*(*ppo)+alfa*(*ppi); weighted = ((float)1.0-alfa)*(*ppo)+alfa*(*ppi);
ppo++; ppo++;
ppi++; ppi++;
@@ -128,13 +133,13 @@ void searchAugmentedCB(
/* Compute energy and cross dot product for the /* Compute energy and cross dot product for the
remaining samples */ remaining samples */
pp = buffer - lagcount; pp = buffer - icount;
for (j=lagcount; j<SUBL; j++) { for (j=icount; j<SUBL; j++) {
energy[tmpIndex] += (*pp)*(*pp); energy[tmpIndex] += (*pp)*(*pp);
crossDot += target[j]*(*pp++); crossDot += target[j]*(*pp++);
} }
if(energy[tmpIndex]>0.0) { if (energy[tmpIndex]>0.0) {
invenergy[tmpIndex]=(float)1.0/(energy[tmpIndex]+EPS); invenergy[tmpIndex]=(float)1.0/(energy[tmpIndex]+EPS);
} else { } else {
invenergy[tmpIndex] = (float) 0.0; invenergy[tmpIndex] = (float) 0.0;
@@ -163,6 +168,8 @@ void searchAugmentedCB(
} }
/*----------------------------------------------------------------* /*----------------------------------------------------------------*
* Recreate a specific codebook vector from the augmented part. * Recreate a specific codebook vector from the augmented part.
* *

View File

@@ -1,13 +1,14 @@
/****************************************************************** /******************************************************************
iLBC Speech Coder ANSI-C Source Code iLBC Speech Coder ANSI-C Source Code
createCB.h createCB.h
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/ ******************************************************************/

View File

@@ -5,50 +5,63 @@
doCPLC.c doCPLC.c
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/ ******************************************************************/
#include <math.h> #include <math.h>
#include <string.h> #include <string.h>
#include <stdio.h>
#include "iLBC_define.h" #include "iLBC_define.h"
#include "doCPLC.h"
/*----------------------------------------------------------------* /*----------------------------------------------------------------*
* Compute cross correlation and pitch gain for pitch prediction * Compute cross correlation and pitch gain for pitch prediction
* of last subframe at given lag. * of last subframe at given lag.
*---------------------------------------------------------------*/ *---------------------------------------------------------------*/
static void compCorr( void compCorr(
float *cc, /* (o) cross correlation coefficient */ float *cc, /* (o) cross correlation coefficient */
float *gc, /* (o) gain */ float *gc, /* (o) gain */
float *pm,
float *buffer, /* (i) signal buffer */ float *buffer, /* (i) signal buffer */
int lag, /* (i) pitch lag */ int lag, /* (i) pitch lag */
int bLen, /* (i) length of buffer */ int bLen, /* (i) length of buffer */
int sRange /* (i) correlation search length */ int sRange /* (i) correlation search length */
){ ){
int i; int i;
float ftmp1, ftmp2; float ftmp1, ftmp2, ftmp3;
/* Guard against getting outside buffer */
if ((bLen-sRange-lag)<0) {
sRange=bLen-lag;
}
ftmp1 = 0.0; ftmp1 = 0.0;
ftmp2 = 0.0; ftmp2 = 0.0;
ftmp3 = 0.0;
for (i=0; i<sRange; i++) { for (i=0; i<sRange; i++) {
ftmp1 += buffer[bLen-sRange+i] * ftmp1 += buffer[bLen-sRange+i] *
buffer[bLen-sRange+i-lag]; buffer[bLen-sRange+i-lag];
ftmp2 += buffer[bLen-sRange+i-lag] * ftmp2 += buffer[bLen-sRange+i-lag] *
buffer[bLen-sRange+i-lag]; buffer[bLen-sRange+i-lag];
ftmp3 += buffer[bLen-sRange+i] *
buffer[bLen-sRange+i];
} }
if (ftmp2 > 0.0) { if (ftmp2 > 0.0) {
*cc = ftmp1*ftmp1/ftmp2; *cc = ftmp1*ftmp1/ftmp2;
*gc = (float)fabs(ftmp1/ftmp2); *gc = (float)fabs(ftmp1/ftmp2);
*pm=(float)fabs(ftmp1)/
((float)sqrt(ftmp2)*(float)sqrt(ftmp3));
} }
else { else {
*cc = 0.0; *cc = 0.0;
*gc = 0.0; *gc = 0.0;
*pm=0.0;
} }
} }
@@ -70,235 +83,176 @@ void doThePLC(
){ ){
int lag=20, randlag; int lag=20, randlag;
float gain, maxcc; float gain, maxcc;
float gain_comp, maxcc_comp; float use_gain;
int i, pick, offset; float gain_comp, maxcc_comp, per, max_per;
float ftmp, ftmp1, randvec[BLOCKL], pitchfact; int i, pick, use_lag;
float ftmp, randvec[BLOCKL_MAX], pitchfact, energy;
/* Packet Loss */ /* Packet Loss */
if (PLI == 1) { if (PLI == 1) {
(*iLBCdec_inst).consPLICount += 1; iLBCdec_inst->consPLICount += 1;
/* if previous frame not lost, /* if previous frame not lost,
determine pitch pred. gain */ determine pitch pred. gain */
if ((*iLBCdec_inst).prevPLI != 1) { if (iLBCdec_inst->prevPLI != 1) {
/* Search around the previous lag to find the /* Search around the previous lag to find the
best pitch period */ best pitch period */
lag=inlag-3; lag=inlag-3;
compCorr(&maxcc, &gain, (*iLBCdec_inst).prevResidual, compCorr(&maxcc, &gain, &max_per,
lag, BLOCKL, 60); iLBCdec_inst->prevResidual,
lag, iLBCdec_inst->blockl, 60);
for (i=inlag-2;i<=inlag+3;i++) { for (i=inlag-2;i<=inlag+3;i++) {
compCorr(&maxcc_comp, &gain_comp, compCorr(&maxcc_comp, &gain_comp, &per,
(*iLBCdec_inst).prevResidual, iLBCdec_inst->prevResidual,
i, BLOCKL, 60); i, iLBCdec_inst->blockl, 60);
if (maxcc_comp>maxcc) { if (maxcc_comp>maxcc) {
maxcc=maxcc_comp; maxcc=maxcc_comp;
gain=gain_comp; gain=gain_comp;
lag=i; lag=i;
max_per=per;
} }
} }
if (gain > 1.0) {
gain = 1.0;
}
} }
/* previous frame lost, use recorded lag and gain */ /* previous frame lost, use recorded lag and periodicity */
else { else {
lag=(*iLBCdec_inst).prevLag; lag=iLBCdec_inst->prevLag;
gain=(*iLBCdec_inst).prevGain; max_per=iLBCdec_inst->per;
} }
/* Attenuate signal and scale down pitch pred gain if /* downscaling */
several frames lost consecutively */
use_gain=1.0;
if (iLBCdec_inst->consPLICount*iLBCdec_inst->blockl>320)
use_gain=(float)0.9;
else if (iLBCdec_inst->consPLICount*
iLBCdec_inst->blockl>2*320)
use_gain=(float)0.7;
else if (iLBCdec_inst->consPLICount*
iLBCdec_inst->blockl>3*320)
use_gain=(float)0.5;
else if (iLBCdec_inst->consPLICount*
if ((*iLBCdec_inst).consPLICount > 1) { iLBCdec_inst->blockl>4*320)
gain *= (float)0.9; use_gain=(float)0.0;
}
/* Compute mixing factor of picth repeatition and noise */ /* mix noise and pitch repeatition */
ftmp=(float)sqrt(max_per);
if (ftmp>(float)0.7)
pitchfact=(float)1.0;
else if (ftmp>(float)0.4)
pitchfact=(ftmp-(float)0.4)/((float)0.7-(float)0.4);
else
pitchfact=0.0;
if (gain > PLC_XT_MIX) { /* avoid repetition of same pitch cycle */
pitchfact = PLC_YT_MIX; use_lag=lag;
} else if (gain < PLC_XB_MIX) { if (lag<80) {
pitchfact = PLC_YB_MIX; use_lag=2*lag;
} else {
pitchfact = PLC_YB_MIX + (gain - PLC_XB_MIX) *
(PLC_YT_MIX-PLC_YB_MIX)/(PLC_XT_MIX-PLC_XB_MIX);
} }
/* compute concealed residual */ /* compute concealed residual */
(*iLBCdec_inst).energy = 0.0; energy = 0.0;
for (i=0; i<BLOCKL; i++) { for (i=0; i<iLBCdec_inst->blockl; i++) {
/* noise component */ /* noise component */
(*iLBCdec_inst).seed=((*iLBCdec_inst).seed*69069L+1) & iLBCdec_inst->seed=(iLBCdec_inst->seed*69069L+1) &
(0x80000000L-1); (0x80000000L-1);
randlag = 50 + ((signed long) (*iLBCdec_inst).seed)%70; randlag = 50 + ((signed long) iLBCdec_inst->seed)%70;
pick = i - randlag; pick = i - randlag;
if (pick < 0) { if (pick < 0) {
randvec[i] = gain * randvec[i] =
(*iLBCdec_inst).prevResidual[BLOCKL+pick]; iLBCdec_inst->prevResidual[
iLBCdec_inst->blockl+pick];
} else { } else {
randvec[i] = gain * randvec[pick]; randvec[i] = randvec[pick];
} }
/* pitch repeatition component */ /* pitch repeatition component */
pick = i - use_lag;
pick = i - lag;
if (pick < 0) { if (pick < 0) {
PLCresidual[i] = gain * PLCresidual[i] =
(*iLBCdec_inst).prevResidual[BLOCKL+pick]; iLBCdec_inst->prevResidual[
iLBCdec_inst->blockl+pick];
} else { } else {
PLCresidual[i] = gain * PLCresidual[pick]; PLCresidual[i] = PLCresidual[pick];
} }
/* mix noise and pitch repeatition */ /* mix random and periodicity component */
PLCresidual[i] = (pitchfact * PLCresidual[i] + if (i<80)
PLCresidual[i] = use_gain*(pitchfact *
PLCresidual[i] +
((float)1.0 - pitchfact) * randvec[i]);
else if (i<160)
PLCresidual[i] = (float)0.95*use_gain*(pitchfact *
PLCresidual[i] +
((float)1.0 - pitchfact) * randvec[i]);
else
PLCresidual[i] = (float)0.9*use_gain*(pitchfact *
PLCresidual[i] +
((float)1.0 - pitchfact) * randvec[i]); ((float)1.0 - pitchfact) * randvec[i]);
(*iLBCdec_inst).energy += PLCresidual[i] * energy += PLCresidual[i] * PLCresidual[i];
PLCresidual[i];
} }
/* less than 30 dB, use only noise */ /* less than 30 dB, use only noise */
if (sqrt((*iLBCdec_inst).energy/(float)BLOCKL) < 30.0) { if (sqrt(energy/(float)iLBCdec_inst->blockl) < 30.0) {
(*iLBCdec_inst).energy = 0.0;
gain=0.0; gain=0.0;
for (i=0; i<BLOCKL; i++) { for (i=0; i<iLBCdec_inst->blockl; i++) {
PLCresidual[i] = randvec[i]; PLCresidual[i] = randvec[i];
(*iLBCdec_inst).energy += PLCresidual[i] *
PLCresidual[i];
} }
} }
/* conceal LPC by bandwidth expansion of old LPC */ /* use old LPC */
ftmp=PLC_BWEXPAND; memcpy(PLClpc,iLBCdec_inst->prevLpc,
PLClpc[0]=(float)1.0; (LPC_FILTERORDER+1)*sizeof(float));
for (i=1; i<LPC_FILTERORDER+1; i++) {
PLClpc[i] = ftmp * (*iLBCdec_inst).prevLpc[i];
ftmp *= PLC_BWEXPAND;
}
} }
/* previous frame lost and this frame OK, mixing in
with new frame */
else if ((*iLBCdec_inst).prevPLI == 1) {
lag = (*iLBCdec_inst).prevLag;
gain = (*iLBCdec_inst).prevGain;
/* if pitch pred gain high, do overlap-add */
if (gain >= PLC_GAINTHRESHOLD) {
/* Compute mixing factor of pitch repeatition
and noise */
if (gain > PLC_XT_MIX) {
pitchfact = PLC_YT_MIX;
} else if (gain < PLC_XB_MIX) {
pitchfact = PLC_YB_MIX;
} else {
pitchfact = PLC_YB_MIX + (gain - PLC_XB_MIX) *
(PLC_YT_MIX-PLC_YB_MIX)/(PLC_XT_MIX-PLC_XB_MIX);
}
/* compute concealed residual for 3 subframes */
for (i=0; i<3*SUBL; i++) {
(*iLBCdec_inst).seed=((*iLBCdec_inst).seed*
69069L+1) & (0x80000000L-1);
randlag = 50 + ((signed long)
(*iLBCdec_inst).seed)%70;
/* noise component */
pick = i - randlag;
if (pick < 0) {
randvec[i] = gain *
(*iLBCdec_inst).prevResidual[BLOCKL+pick];
} else {
randvec[i] = gain * randvec[pick];
}
/* pitch repeatition component */
pick = i - lag;
if (pick < 0) {
PLCresidual[i] = gain *
(*iLBCdec_inst).prevResidual[BLOCKL+pick];
} else {
PLCresidual[i] = gain * PLCresidual[pick];
}
/* mix noise and pitch repeatition */
PLCresidual[i] = (pitchfact * PLCresidual[i] +
((float)1.0 - pitchfact) * randvec[i]);
}
/* interpolate concealed residual with actual
residual */
offset = 3*SUBL;
for (i=0; i<offset; i++) {
ftmp1 = (float) (i+1) / (float) (offset+1);
ftmp = (float)1.0 - ftmp1;
PLCresidual[i]=PLCresidual[i]*ftmp+
decresidual[i]*ftmp1;
}
memcpy(PLCresidual+offset, decresidual+offset,
(BLOCKL-offset)*sizeof(float));
} else {
memcpy(PLCresidual, decresidual, BLOCKL*sizeof(float));
}
/* copy LPC */
memcpy(PLClpc, lpc, (LPC_FILTERORDER+1)*sizeof(float));
(*iLBCdec_inst).consPLICount = 0;
}
/* no packet loss, copy input */ /* no packet loss, copy input */
else { else {
memcpy(PLCresidual, decresidual, BLOCKL*sizeof(float)); memcpy(PLCresidual, decresidual,
iLBCdec_inst->blockl*sizeof(float));
memcpy(PLClpc, lpc, (LPC_FILTERORDER+1)*sizeof(float)); memcpy(PLClpc, lpc, (LPC_FILTERORDER+1)*sizeof(float));
iLBCdec_inst->consPLICount = 0;
} }
/* update state */ /* update state */
(*iLBCdec_inst).prevLag = lag; if (PLI) {
(*iLBCdec_inst).prevGain = gain; iLBCdec_inst->prevLag = lag;
(*iLBCdec_inst).prevPLI = PLI; iLBCdec_inst->per=max_per;
memcpy((*iLBCdec_inst).prevLpc, PLClpc, }
iLBCdec_inst->prevPLI = PLI;
memcpy(iLBCdec_inst->prevLpc, PLClpc,
(LPC_FILTERORDER+1)*sizeof(float)); (LPC_FILTERORDER+1)*sizeof(float));
memcpy((*iLBCdec_inst).prevResidual, PLCresidual, memcpy(iLBCdec_inst->prevResidual, PLCresidual,
BLOCKL*sizeof(float)); iLBCdec_inst->blockl*sizeof(float));
} }

View File

@@ -5,9 +5,10 @@
doCPLC.h doCPLC.h
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/ ******************************************************************/

View File

@@ -5,9 +5,8 @@
enhancer.c enhancer.c
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/ ******************************************************************/
@@ -16,16 +15,18 @@
#include "iLBC_define.h" #include "iLBC_define.h"
#include "constants.h" #include "constants.h"
#include "filter.h" #include "filter.h"
#include "enhancer.h"
/*----------------------------------------------------------------* /*----------------------------------------------------------------*
* Find index in array such that the array element with said * Find index in array such that the array element with said
* index is the element of said array closest to "value" * index is the element of said array closest to "value"
* according to the squared-error criterion * according to the squared-error criterion
*---------------------------------------------------------------*/ *---------------------------------------------------------------*/
static void NearestNeighbor( void NearestNeighbor(
int *index, /* (o) index of array element closest to value */ int *index, /* (o) index of array element closest
to value */
float *array, /* (i) data array */ float *array, /* (i) data array */
float value,/* (i) value */ float value,/* (i) value */
int arlength/* (i) dimension of data array */ int arlength/* (i) dimension of data array */
@@ -36,11 +37,11 @@ static void NearestNeighbor(
crit=array[0]-value; crit=array[0]-value;
bestcrit=crit*crit; bestcrit=crit*crit;
*index=0; *index=0;
for(i=1;i<arlength;i++){ for (i=1; i<arlength; i++) {
crit=array[i]-value; crit=array[i]-value;
crit=crit*crit; crit=crit*crit;
if(crit<bestcrit){ if (crit<bestcrit) {
bestcrit=crit; bestcrit=crit;
*index=i; *index=i;
} }
@@ -51,7 +52,7 @@ static void NearestNeighbor(
* compute cross correlation between sequences * compute cross correlation between sequences
*---------------------------------------------------------------*/ *---------------------------------------------------------------*/
static void mycorr1( void mycorr1(
float* corr, /* (o) correlation of seq1 and seq2 */ float* corr, /* (o) correlation of seq1 and seq2 */
float* seq1, /* (i) first sequence */ float* seq1, /* (i) first sequence */
int dim1, /* (i) dimension first seq1 */ int dim1, /* (i) dimension first seq1 */
@@ -60,9 +61,9 @@ static void mycorr1(
){ ){
int i,j; int i,j;
for(i=0;i<=dim1-dim2; i++){ for (i=0; i<=dim1-dim2; i++) {
corr[i]=0.0; corr[i]=0.0;
for(j=0;j<dim2; j++){ for (j=0; j<dim2; j++) {
corr[i] += seq1[i+j] * seq2[j]; corr[i] += seq1[i+j] * seq2[j];
} }
} }
@@ -72,7 +73,9 @@ static void mycorr1(
* upsample finite array assuming zeros outside bounds * upsample finite array assuming zeros outside bounds
*---------------------------------------------------------------*/ *---------------------------------------------------------------*/
static void enh_upsample(
void enh_upsample(
float* useq1, /* (o) upsampled output sequence */ float* useq1, /* (o) upsampled output sequence */
float* seq1,/* (i) unupsampled sequence */ float* seq1,/* (i) unupsampled sequence */
int dim1, /* (i) dimension seq1 */ int dim1, /* (i) dimension seq1 */
@@ -80,23 +83,24 @@ static void enh_upsample(
){ ){
float *pu,*ps; float *pu,*ps;
int i,j,k,q,filterlength,hfl2; int i,j,k,q,filterlength,hfl2;
const float *polyp[ENH_UPS0]; /* pointers to polyphase columns */ const float *polyp[ENH_UPS0]; /* pointers to
polyphase columns */
const float *pp; const float *pp;
/* define pointers for filter */ /* define pointers for filter */
filterlength=2*hfl+1; filterlength=2*hfl+1;
if( filterlength > dim1){ if ( filterlength > dim1 ) {
hfl2=(int) (dim1/2); hfl2=(int) (dim1/2);
for(j=0;j<ENH_UPS0; j++) { for (j=0; j<ENH_UPS0; j++) {
polyp[j]=polyphaserTbl+j*filterlength+hfl-hfl2; polyp[j]=polyphaserTbl+j*filterlength+hfl-hfl2;
} }
hfl=hfl2; hfl=hfl2;
filterlength=2*hfl+1; filterlength=2*hfl+1;
} }
else { else {
for(j=0;j<ENH_UPS0; j++) { for (j=0; j<ENH_UPS0; j++) {
polyp[j]=polyphaserTbl+j*filterlength; polyp[j]=polyphaserTbl+j*filterlength;
} }
} }
@@ -104,12 +108,12 @@ static void enh_upsample(
/* filtering: filter overhangs left side of sequence */ /* filtering: filter overhangs left side of sequence */
pu=useq1; pu=useq1;
for(i=hfl;i<filterlength; i++){ for (i=hfl; i<filterlength; i++) {
for(j=0;j<ENH_UPS0; j++){ for (j=0; j<ENH_UPS0; j++) {
*pu=0.0; *pu=0.0;
pp = polyp[j]; pp = polyp[j];
ps = seq1+i; ps = seq1+i;
for(k=0;k<=i;k++) { for (k=0; k<=i; k++) {
*pu += *ps-- * *pp++; *pu += *ps-- * *pp++;
} }
pu++; pu++;
@@ -118,13 +122,15 @@ static void enh_upsample(
/* filtering: simple convolution=inner products */ /* filtering: simple convolution=inner products */
for(i=filterlength; i<dim1; i++){ for (i=filterlength; i<dim1; i++) {
for(j=0;j<ENH_UPS0; j++){ for (j=0;j<ENH_UPS0; j++){
*pu=0.0; *pu=0.0;
pp = polyp[j]; pp = polyp[j];
ps = seq1+i; ps = seq1+i;
for(k=0;k<filterlength;k++) { for (k=0; k<filterlength; k++) {
*pu += *ps-- * *pp++; *pu += *ps-- * *pp++;
} }
pu++; pu++;
} }
@@ -132,12 +138,12 @@ static void enh_upsample(
/* filtering: filter overhangs right side of sequence */ /* filtering: filter overhangs right side of sequence */
for(q=1; q<=hfl;q++){ for (q=1; q<=hfl; q++) {
for(j=0;j<ENH_UPS0; j++){ for (j=0; j<ENH_UPS0; j++) {
*pu=0.0; *pu=0.0;
pp = polyp[j]+q; pp = polyp[j]+q;
ps = seq1+dim1-1; ps = seq1+dim1-1;
for(k=0;k<filterlength-q;k++) { for (k=0; k<filterlength-q; k++) {
*pu += *ps-- * *pp++; *pu += *ps-- * *pp++;
} }
pu++; pu++;
@@ -154,7 +160,7 @@ static void enh_upsample(
* sampling rate * sampling rate
*---------------------------------------------------------------*/ *---------------------------------------------------------------*/
static void refiner( void refiner(
float *seg, /* (o) segment array */ float *seg, /* (o) segment array */
float *updStartPos, /* (o) updated start point */ float *updStartPos, /* (o) updated start point */
float* idata, /* (i) original data buffer */ float* idata, /* (i) original data buffer */
@@ -167,7 +173,6 @@ static void refiner(
int tloc,tloc2,i,st,en,fraction; int tloc,tloc2,i,st,en,fraction;
float vect[ENH_VECTL],corrVec[ENH_CORRDIM],maxv; float vect[ENH_VECTL],corrVec[ENH_CORRDIM],maxv;
float corrVecUps[ENH_CORRDIM*ENH_UPS0]; float corrVecUps[ENH_CORRDIM*ENH_UPS0];
(void)period;
/* defining array bounds */ /* defining array bounds */
@@ -180,7 +185,9 @@ static void refiner(
} }
searchSegEndPos=estSegPosRounded+ENH_SLOP; searchSegEndPos=estSegPosRounded+ENH_SLOP;
if(searchSegEndPos+ENH_BLOCKL >= idatal) {
if (searchSegEndPos+ENH_BLOCKL >= idatal) {
searchSegEndPos=idatal-ENH_BLOCKL-1; searchSegEndPos=idatal-ENH_BLOCKL-1;
} }
corrdim=searchSegEndPos-searchSegStartPos+1; corrdim=searchSegEndPos-searchSegStartPos+1;
@@ -192,9 +199,9 @@ static void refiner(
corrdim+ENH_BLOCKL-1,idata+centerStartPos,ENH_BLOCKL); corrdim+ENH_BLOCKL-1,idata+centerStartPos,ENH_BLOCKL);
enh_upsample(corrVecUps,corrVec,corrdim,ENH_FL0); enh_upsample(corrVecUps,corrVec,corrdim,ENH_FL0);
tloc=0; maxv=corrVecUps[0]; tloc=0; maxv=corrVecUps[0];
for(i=1;i<ENH_UPS0*corrdim; i++){ for (i=1; i<ENH_UPS0*corrdim; i++) {
if(corrVecUps[i]>maxv){ if (corrVecUps[i]>maxv) {
tloc=i; tloc=i;
maxv=corrVecUps[i]; maxv=corrVecUps[i];
} }
@@ -212,14 +219,14 @@ static void refiner(
} }
st=searchSegStartPos+tloc2-ENH_FL0; st=searchSegStartPos+tloc2-ENH_FL0;
if(st<0){ if (st<0) {
memset(vect,0,-st*sizeof(float)); memset(vect,0,-st*sizeof(float));
memcpy(&vect[-st],idata, (ENH_VECTL+st)*sizeof(float)); memcpy(&vect[-st],idata, (ENH_VECTL+st)*sizeof(float));
} }
else{ else {
en=st+ENH_VECTL; en=st+ENH_VECTL;
if(en>idatal){ if (en>idatal) {
memcpy(vect, &idata[st], memcpy(vect, &idata[st],
(ENH_VECTL-(en-idatal))*sizeof(float)); (ENH_VECTL-(en-idatal))*sizeof(float));
memset(&vect[ENH_VECTL-(en-idatal)], 0, memset(&vect[ENH_VECTL-(en-idatal)], 0,
@@ -234,6 +241,8 @@ static void refiner(
/* compute the segment (this is actually a convolution) */ /* compute the segment (this is actually a convolution) */
mycorr1(seg,vect,ENH_VECTL,polyphaserTbl+(2*ENH_FL0+1)*fraction, mycorr1(seg,vect,ENH_VECTL,polyphaserTbl+(2*ENH_FL0+1)*fraction,
2*ENH_FL0+1); 2*ENH_FL0+1);
} }
@@ -241,7 +250,7 @@ static void refiner(
* find the smoothed output data * find the smoothed output data
*---------------------------------------------------------------*/ *---------------------------------------------------------------*/
static void smath( void smath(
float *odata, /* (o) smoothed output */ float *odata, /* (o) smoothed output */
float *sseq,/* (i) said second sequence of waveforms */ float *sseq,/* (i) said second sequence of waveforms */
int hl, /* (i) 2*hl+1 is sseq dimension */ int hl, /* (i) 2*hl+1 is sseq dimension */
@@ -249,29 +258,29 @@ static void smath(
){ ){
int i,k; int i,k;
float w00,w10,w11,A,B,C,*psseq,err,errs; float w00,w10,w11,A,B,C,*psseq,err,errs;
float surround[BLOCKL]; /* shape contributed by other than float surround[BLOCKL_MAX]; /* shape contributed by other than
current */ current */
float wt[2*ENH_HL+1]; /* waveform weighting to get surround float wt[2*ENH_HL+1]; /* waveform weighting to get
shape */ surround shape */
float denom; float denom;
/* create shape of contribution from all waveforms except the /* create shape of contribution from all waveforms except the
current one */ current one */
for(i=1;i<=2*hl+1; i++) { for (i=1; i<=2*hl+1; i++) {
wt[i-1] = (float)0.5*(1 - (float)cos(2*PI*i/(2*hl+2))); wt[i-1] = (float)0.5*(1 - (float)cos(2*PI*i/(2*hl+2)));
} }
wt[hl]=0.0; /* for clarity, not used */ wt[hl]=0.0; /* for clarity, not used */
for(i=0;i<ENH_BLOCKL; i++) { for (i=0; i<ENH_BLOCKL; i++) {
surround[i]=sseq[i]*wt[0]; surround[i]=sseq[i]*wt[0];
} }
for(k=1;k<hl; k++){ for (k=1; k<hl; k++) {
psseq=sseq+k*ENH_BLOCKL; psseq=sseq+k*ENH_BLOCKL;
for(i=0;i<ENH_BLOCKL; i++) { for(i=0;i<ENH_BLOCKL; i++) {
surround[i]+=psseq[i]*wt[k]; surround[i]+=psseq[i]*wt[k];
} }
} }
for(k=hl+1;k<=2*hl; k++){ for (k=hl+1; k<=2*hl; k++) {
psseq=sseq+k*ENH_BLOCKL; psseq=sseq+k*ENH_BLOCKL;
for(i=0;i<ENH_BLOCKL; i++) { for(i=0;i<ENH_BLOCKL; i++) {
surround[i]+=psseq[i]*wt[k]; surround[i]+=psseq[i]*wt[k];
@@ -282,13 +291,15 @@ static void smath(
w00 = w10 = w11 = 0.0; w00 = w10 = w11 = 0.0;
psseq=sseq+hl*ENH_BLOCKL; /* current block */ psseq=sseq+hl*ENH_BLOCKL; /* current block */
for(i=0;i<ENH_BLOCKL;i++) { for (i=0; i<ENH_BLOCKL;i++) {
w00+=psseq[i]*psseq[i]; w00+=psseq[i]*psseq[i];
w11+=surround[i]*surround[i]; w11+=surround[i]*surround[i];
w10+=surround[i]*psseq[i]; w10+=surround[i]*psseq[i];
} }
if( fabs(w11) < 1.0) {
if (fabs(w11) < 1.0) {
w11=1.0; w11=1.0;
} }
C = (float)sqrt( w00/w11); C = (float)sqrt( w00/w11);
@@ -297,7 +308,7 @@ static void smath(
errs=0.0; errs=0.0;
psseq=sseq+hl*ENH_BLOCKL; psseq=sseq+hl*ENH_BLOCKL;
for(i=0;i<ENH_BLOCKL;i++) { for (i=0; i<ENH_BLOCKL; i++) {
odata[i]=C*surround[i]; odata[i]=C*surround[i];
err=psseq[i]-odata[i]; err=psseq[i]-odata[i];
errs+=err*err; errs+=err*err;
@@ -305,19 +316,19 @@ static void smath(
/* if constraint violated by first try, add constraint */ /* if constraint violated by first try, add constraint */
if( errs > alpha0 * w00){ if (errs > alpha0 * w00) {
if( w00 < 1) { if ( w00 < 1) {
w00=1; w00=1;
} }
denom = (w11*w00-w10*w10)/(w00*w00); denom = (w11*w00-w10*w10)/(w00*w00);
if( denom > 0.0001){ /* eliminates numerical problems if (denom > 0.0001) { /* eliminates numerical problems
for if smooth */ for if smooth */
A = (float)sqrt( (alpha0- alpha0*alpha0/4)/denom); A = (float)sqrt( (alpha0- alpha0*alpha0/4)/denom);
B = -alpha0/2 - A * w10/w00; B = -alpha0/2 - A * w10/w00;
B = B+1; B = B+1;
} }
else{ /* essentially no difference between cycles; else { /* essentially no difference between cycles;
smoothing not needed */ smoothing not needed */
A= 0.0; A= 0.0;
B= 1.0; B= 1.0;
@@ -326,7 +337,7 @@ static void smath(
/* create smoothed sequence */ /* create smoothed sequence */
psseq=sseq+hl*ENH_BLOCKL; psseq=sseq+hl*ENH_BLOCKL;
for(i=0;i<ENH_BLOCKL;i++) { for (i=0; i<ENH_BLOCKL; i++) {
odata[i]=A*surround[i]+B*psseq[i]; odata[i]=A*surround[i]+B*psseq[i];
} }
} }
@@ -336,16 +347,18 @@ static void smath(
* get the pitch-synchronous sample sequence * get the pitch-synchronous sample sequence
*---------------------------------------------------------------*/ *---------------------------------------------------------------*/
static void getsseq( void getsseq(
float *sseq, /* (o) the pitch-synchronous sequence */ float *sseq, /* (o) the pitch-synchronous sequence */
float *idata, /* (i) original data */ float *idata, /* (i) original data */
int idatal, /* (i) dimension of data */ int idatal, /* (i) dimension of data */
int centerStartPos, /* (i) where current block starts */ int centerStartPos, /* (i) where current block starts */
float *period, /* (i) rough-pitch-period array */ float *period, /* (i) rough-pitch-period array */
float *plocs, /* (i) where periods of period array float *plocs, /* (i) where periods of period array
are taken */ are taken */
int periodl, /* (i) dimension period array */ int periodl, /* (i) dimension period array */
int hl /* (i)( 2*hl+1 is the number of sequences */ int hl /* (i) 2*hl+1 is the number of sequences */
){ ){
int i,centerEndPos,q; int i,centerEndPos,q;
float blockStartPos[2*ENH_HL+1]; float blockStartPos[2*ENH_HL+1];
@@ -366,19 +379,18 @@ static void getsseq(
/* past */ /* past */
for(q=hl-1;q>=0;q--) { for (q=hl-1; q>=0; q--) {
blockStartPos[q]=blockStartPos[q+1]-period[lagBlock[q+1]]; blockStartPos[q]=blockStartPos[q+1]-period[lagBlock[q+1]];
NearestNeighbor(lagBlock+q,plocs, NearestNeighbor(lagBlock+q,plocs,
blockStartPos[q]+ENH_BLOCKL_HALF-period[lagBlock[q+1]], blockStartPos[q]+
periodl); ENH_BLOCKL_HALF-period[lagBlock[q+1]], periodl);
if(blockStartPos[q]-ENH_OVERHANG>=0) { if (blockStartPos[q]-ENH_OVERHANG>=0) {
refiner(sseq+q*ENH_BLOCKL,blockStartPos+q,idata,idatal, refiner(sseq+q*ENH_BLOCKL, blockStartPos+q, idata,
centerStartPos,blockStartPos[q], idatal, centerStartPos, blockStartPos[q],
period[lagBlock[q+1]]); period[lagBlock[q+1]]);
} else { } else {
psseq=sseq+q*ENH_BLOCKL; psseq=sseq+q*ENH_BLOCKL;
memset(psseq, 0, ENH_BLOCKL*sizeof(float)); memset(psseq, 0, ENH_BLOCKL*sizeof(float));
} }
@@ -386,19 +398,20 @@ static void getsseq(
/* future */ /* future */
for(i=0;i<periodl;i++) { for (i=0; i<periodl; i++) {
plocs2[i]=plocs[i]-period[i]; plocs2[i]=plocs[i]-period[i];
} }
for(q=hl+1;q<=2*hl;q++) { for (q=hl+1; q<=2*hl; q++) {
NearestNeighbor(lagBlock+q,plocs2, NearestNeighbor(lagBlock+q,plocs2,
blockStartPos[q-1]+ENH_BLOCKL_HALF,periodl); blockStartPos[q-1]+ENH_BLOCKL_HALF,periodl);
blockStartPos[q]=blockStartPos[q-1]+period[lagBlock[q]]; blockStartPos[q]=blockStartPos[q-1]+period[lagBlock[q]];
if( blockStartPos[q]+ENH_BLOCKL+ENH_OVERHANG<idatal) { if (blockStartPos[q]+ENH_BLOCKL+ENH_OVERHANG<idatal) {
refiner(sseq+ENH_BLOCKL*q, blockStartPos+q, idata,
idatal, centerStartPos, blockStartPos[q],
refiner(sseq+ENH_BLOCKL*q,blockStartPos+q,idata,idatal,
centerStartPos,blockStartPos[q],period[lagBlock[q]]);
period[lagBlock[q]]);
} }
else { else {
psseq=sseq+q*ENH_BLOCKL; psseq=sseq+q*ENH_BLOCKL;
@@ -412,7 +425,7 @@ static void getsseq(
* idata+centerStartPos+ENH_BLOCKL-1 * idata+centerStartPos+ENH_BLOCKL-1
*---------------------------------------------------------------*/ *---------------------------------------------------------------*/
static void enhancer( void enhancer(
float *odata, /* (o) smoothed block, dimension blockl */ float *odata, /* (o) smoothed block, dimension blockl */
float *idata, /* (i) data buffer used for enhancing */ float *idata, /* (i) data buffer used for enhancing */
int idatal, /* (i) dimension idata */ int idatal, /* (i) dimension idata */
@@ -452,6 +465,8 @@ float xCorrCoef(
ftmp1 = 0.0; ftmp1 = 0.0;
ftmp2 = 0.0; ftmp2 = 0.0;
for (i=0; i<subl; i++) { for (i=0; i<subl; i++) {
ftmp1 += target[i]*regressor[i]; ftmp1 += target[i]*regressor[i];
ftmp2 += regressor[i]*regressor[i]; ftmp2 += regressor[i]*regressor[i];
@@ -476,97 +491,55 @@ int enhancerInterface(
){ ){
float *enh_buf, *enh_period; float *enh_buf, *enh_period;
int iblock, isample; int iblock, isample;
int lag, ilag, i; int lag=0, ilag, i, ioffset;
float cc, maxcc; float cc, maxcc;
float ftmp1, ftmp2, gain; float ftmp1, ftmp2;
float *inPtr, *enh_bufPtr1, *enh_bufPtr2; float *inPtr, *enh_bufPtr1, *enh_bufPtr2;
float plc_pred[ENH_BLOCKL];
float lpState[6], downsampled[(ENH_NBLOCKS*ENH_BLOCKL+120)/2]; float lpState[6], downsampled[(ENH_NBLOCKS*ENH_BLOCKL+120)/2];
int inLen=ENH_NBLOCKS*ENH_BLOCKL+120; int inLen=ENH_NBLOCKS*ENH_BLOCKL+120;
int start; int start, plc_blockl, inlag;
enh_buf=iLBCdec_inst->enh_buf; enh_buf=iLBCdec_inst->enh_buf;
enh_period=iLBCdec_inst->enh_period; enh_period=iLBCdec_inst->enh_period;
memmove(enh_buf, &enh_buf[iLBCdec_inst->blockl],
(ENH_BUFL-iLBCdec_inst->blockl)*sizeof(float));
memmove(enh_buf, &enh_buf[ENH_NBLOCKS*ENH_BLOCKL], memcpy(&enh_buf[ENH_BUFL-iLBCdec_inst->blockl], in,
(ENH_NBLOCKS_EXTRA*ENH_BLOCKL)*sizeof(float)); iLBCdec_inst->blockl*sizeof(float));
memcpy(&enh_buf[ENH_NBLOCKS_EXTRA*ENH_BLOCKL], in, if (iLBCdec_inst->mode==30)
(ENH_NBLOCKS*ENH_BLOCKL)*sizeof(float)); plc_blockl=ENH_BLOCKL;
else
plc_blockl=40;
if (iLBCdec_inst->prev_enh_pl==1) { /* when 20 ms frame, move processing one block */
/* PLC was performed on the previous packet */ ioffset=0;
if (iLBCdec_inst->mode==20) ioffset=1;
lag = 20; i=3-ioffset;
maxcc = xCorrCoef(in, in+lag, ENH_BLOCKL); memmove(enh_period, &enh_period[i],
for (ilag=21; ilag<120; ilag++) {
cc = xCorrCoef(in, in+ilag, ENH_BLOCKL);
if (cc > maxcc) {
maxcc = cc;
lag = ilag;
}
}
ftmp1 = 0.0;
ftmp2 = 0.0;
for (i=0; i<ENH_BLOCKL; i++) {
ftmp1 += in[i]*in[i+lag];
ftmp2 += in[i+lag]*in[i+lag];
}
if (ftmp1 > 0.0) {
gain=(float)(ftmp1/ftmp2);
}
else {
gain=(float)0.0;
}
if (gain>1.0) {
gain=1.0;
} else if (gain<-1.0) {
gain=-1.0;
}
inPtr=&in[lag-1];
enh_bufPtr1=&enh_buf[ENH_NBLOCKS_EXTRA*ENH_BLOCKL-1];
if (lag>ENH_BLOCKL) {
start=ENH_BLOCKL;
} else {
start=lag;
}
for (isample = start; isample>0; isample--) {
*enh_bufPtr1-- = gain*(*inPtr--);
}
enh_bufPtr2=&enh_buf[ENH_NBLOCKS_EXTRA*ENH_BLOCKL-1];
for (isample = (ENH_BLOCKL-1-lag); isample>=0; isample--) {
*enh_bufPtr1-- = gain*(*enh_bufPtr2--);
}
}
memmove(enh_period, &enh_period[ENH_NBLOCKS],
ENH_NBLOCKS_EXTRA*sizeof(float));
(ENH_NBLOCKS_TOT-i)*sizeof(float));
/* Set state information to the 6 samples right before /* Set state information to the 6 samples right before
the samples to be downsampled. */ the samples to be downsampled. */
memcpy(lpState, enh_buf+ENH_NBLOCKS_EXTRA*ENH_BLOCKL-126, memcpy(lpState,
enh_buf+(ENH_NBLOCKS_EXTRA+ioffset)*ENH_BLOCKL-126,
6*sizeof(float)); 6*sizeof(float));
/* Down sample a factor 2 to save computations */ /* Down sample a factor 2 to save computations */
DownSample(enh_buf+ENH_NBLOCKS_EXTRA*ENH_BLOCKL-120, DownSample(enh_buf+(ENH_NBLOCKS_EXTRA+ioffset)*ENH_BLOCKL-120,
lpFilt_coefsTbl, inLen, lpFilt_coefsTbl, inLen-ioffset*ENH_BLOCKL,
lpState, downsampled); lpState, downsampled);
/* Estimate the pitch in the down sampled domain. */ /* Estimate the pitch in the down sampled domain. */
for(iblock = 0; iblock<ENH_NBLOCKS; iblock++){ for (iblock = 0; iblock<ENH_NBLOCKS-ioffset; iblock++) {
lag = 10; lag = 10;
maxcc = xCorrCoef(downsampled+60+iblock* maxcc = xCorrCoef(downsampled+60+iblock*
@@ -584,17 +557,107 @@ int enhancerInterface(
} }
/* Store the estimated lag in the non-downsampled domain */ /* Store the estimated lag in the non-downsampled domain */
enh_period[iblock+ENH_NBLOCKS_EXTRA] = (float)lag*2; enh_period[iblock+ENH_NBLOCKS_EXTRA+ioffset] = (float)lag*2;
} }
for(iblock = 0; iblock<ENH_NBLOCKS; iblock++){
/* PLC was performed on the previous packet */
if (iLBCdec_inst->prev_enh_pl==1) {
inlag=(int)enh_period[ENH_NBLOCKS_EXTRA+ioffset];
lag = inlag-1;
maxcc = xCorrCoef(in, in+lag, plc_blockl);
for (ilag=inlag; ilag<=inlag+1; ilag++) {
cc = xCorrCoef(in, in+ilag, plc_blockl);
if (cc > maxcc) {
maxcc = cc;
lag = ilag;
}
}
enh_period[ENH_NBLOCKS_EXTRA+ioffset-1]=(float)lag;
/* compute new concealed residual for the old lookahead,
mix the forward PLC with a backward PLC from
the new frame */
inPtr=&in[lag-1];
enh_bufPtr1=&plc_pred[plc_blockl-1];
if (lag>plc_blockl) {
start=plc_blockl;
} else {
start=lag;
}
for (isample = start; isample>0; isample--) {
*enh_bufPtr1-- = *inPtr--;
}
enh_bufPtr2=&enh_buf[ENH_BUFL-1-iLBCdec_inst->blockl];
for (isample = (plc_blockl-1-lag); isample>=0; isample--)
{
*enh_bufPtr1-- = *enh_bufPtr2--;
}
/* limit energy change */
ftmp2=0.0;
ftmp1=0.0;
for (i=0;i<plc_blockl;i++) {
ftmp2+=enh_buf[ENH_BUFL-1-iLBCdec_inst->blockl-i]*
enh_buf[ENH_BUFL-1-iLBCdec_inst->blockl-i];
ftmp1+=plc_pred[i]*plc_pred[i];
}
ftmp1=(float)sqrt(ftmp1/(float)plc_blockl);
ftmp2=(float)sqrt(ftmp2/(float)plc_blockl);
if (ftmp1>(float)2.0*ftmp2 && ftmp1>0.0) {
for (i=0;i<plc_blockl-10;i++) {
plc_pred[i]*=(float)2.0*ftmp2/ftmp1;
}
for (i=plc_blockl-10;i<plc_blockl;i++) {
plc_pred[i]*=(float)(i-plc_blockl+10)*
((float)1.0-(float)2.0*ftmp2/ftmp1)/(float)(10)+
(float)2.0*ftmp2/ftmp1;
}
}
enh_bufPtr1=&enh_buf[ENH_BUFL-1-iLBCdec_inst->blockl];
for (i=0; i<plc_blockl; i++) {
ftmp1 = (float) (i+1) / (float) (plc_blockl+1);
*enh_bufPtr1 *= ftmp1;
*enh_bufPtr1 += ((float)1.0-ftmp1)*
plc_pred[plc_blockl-1-i];
enh_bufPtr1--;
}
}
if (iLBCdec_inst->mode==20) {
/* Enhancer with 40 samples delay */
for (iblock = 0; iblock<2; iblock++) {
enhancer(out+iblock*ENH_BLOCKL, enh_buf,
ENH_BUFL, (5+iblock)*ENH_BLOCKL+40,
ENH_ALPHA0, enh_period, enh_plocsTbl,
ENH_NBLOCKS_TOT);
}
} else if (iLBCdec_inst->mode==30) {
/* Enhancer with 80 samples delay */
for (iblock = 0; iblock<3; iblock++) {
enhancer(out+iblock*ENH_BLOCKL, enh_buf, enhancer(out+iblock*ENH_BLOCKL, enh_buf,
ENH_BUFL, (4+iblock)*ENH_BLOCKL, ENH_BUFL, (4+iblock)*ENH_BLOCKL,
ENH_ALPHA0, enh_period, enh_plocsTbl, ENH_ALPHA0, enh_period, enh_plocsTbl,
ENH_NBLOCKS_TOT); ENH_NBLOCKS_TOT);
} }
}
return (lag*2); return (lag*2);
} }

View File

@@ -5,9 +5,8 @@
enhancer.h enhancer.h
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/ ******************************************************************/

View File

@@ -5,14 +5,14 @@
filter.c filter.c
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/ ******************************************************************/
#include "iLBC_define.h" #include "iLBC_define.h"
#include "filter.h"
/*----------------------------------------------------------------* /*----------------------------------------------------------------*
* all-pole filter * all-pole filter
@@ -20,15 +20,15 @@
void AllPoleFilter( void AllPoleFilter(
float *InOut, /* (i/o) on entrance InOut[-orderCoef] to float *InOut, /* (i/o) on entrance InOut[-orderCoef] to
InOut[-1] contain the state of the filter InOut[-1] contain the state of the
(delayed samples). InOut[0] to filter (delayed samples). InOut[0] to
InOut[lengthInOut-1] contain the filter InOut[lengthInOut-1] contain the filter
input, on en exit InOut[-orderCoef] to input, on en exit InOut[-orderCoef] to
InOut[-1] is unchanged and InOut[0] to InOut[-1] is unchanged and InOut[0] to
InOut[lengthInOut-1] contain filtered InOut[lengthInOut-1] contain filtered
samples */ samples */
float *Coef,/* (i) filter coefficients, Coef[0] is assumed to float *Coef,/* (i) filter coefficients, Coef[0] is assumed
be 1.0 */ to be 1.0 */
int lengthInOut,/* (i) number of input/output samples */ int lengthInOut,/* (i) number of input/output samples */
int orderCoef /* (i) number of filter coefficients */ int orderCoef /* (i) number of filter coefficients */
){ ){
@@ -47,8 +47,8 @@ void AllPoleFilter(
*---------------------------------------------------------------*/ *---------------------------------------------------------------*/
void AllZeroFilter( void AllZeroFilter(
float *In, /* (i) In[0] to In[lengthInOut-1] contain filter float *In, /* (i) In[0] to In[lengthInOut-1] contain
input samples */ filter input samples */
float *Coef,/* (i) filter coefficients (Coef[0] is assumed float *Coef,/* (i) filter coefficients (Coef[0] is assumed
to be 1.0) */ to be 1.0) */
int lengthInOut,/* (i) number of input/output samples */ int lengthInOut,/* (i) number of input/output samples */
@@ -65,6 +65,8 @@ void AllZeroFilter(
for(k=1;k<=orderCoef;k++){ for(k=1;k<=orderCoef;k++){
*Out += Coef[k]*In[-k]; *Out += Coef[k]*In[-k];
} }
Out++; Out++;
In++; In++;
} }
@@ -75,9 +77,10 @@ void AllZeroFilter(
*---------------------------------------------------------------*/ *---------------------------------------------------------------*/
void ZeroPoleFilter( void ZeroPoleFilter(
float *In, /* (i) In[0] to In[lengthInOut-1] contain filter float *In, /* (i) In[0] to In[lengthInOut-1] contain
input samples In[-orderCoef] to In[-1] filter input samples In[-orderCoef] to
contain state of all-zero section */ In[-1] contain state of all-zero
section */
float *ZeroCoef,/* (i) filter coefficients for all-zero float *ZeroCoef,/* (i) filter coefficients for all-zero
section (ZeroCoef[0] is assumed to section (ZeroCoef[0] is assumed to
be 1.0) */ be 1.0) */
@@ -86,9 +89,9 @@ void ZeroPoleFilter(
int lengthInOut,/* (i) number of input/output samples */ int lengthInOut,/* (i) number of input/output samples */
int orderCoef, /* (i) number of filter coefficients */ int orderCoef, /* (i) number of filter coefficients */
float *Out /* (i/o) on entrance Out[-orderCoef] to Out[-1] float *Out /* (i/o) on entrance Out[-orderCoef] to Out[-1]
contain state of all-pole section. On exit contain state of all-pole section. On
Out[0] to Out[lengthInOut-1] contain exit Out[0] to Out[lengthInOut-1]
filtered samples */ contain filtered samples */
){ ){
AllZeroFilter(In,ZeroCoef,lengthInOut,orderCoef,Out); AllZeroFilter(In,ZeroCoef,lengthInOut,orderCoef,Out);
AllPoleFilter(Out,PoleCoef,lengthInOut,orderCoef); AllPoleFilter(Out,PoleCoef,lengthInOut,orderCoef);
@@ -119,11 +122,13 @@ void DownSample (
In_ptr = &In[i]; In_ptr = &In[i];
state_ptr = &state[FILTERORDER_DS-2]; state_ptr = &state[FILTERORDER_DS-2];
o = (float)0.0; o = (float)0.0;
stop = (i < FILTERORDER_DS) ? i + 1 : FILTERORDER_DS; stop = (i < FILTERORDER_DS) ? i + 1 : FILTERORDER_DS;
for (j = 0;j < stop; j++) for (j = 0; j < stop; j++)
{ {
o += *Coef_ptr++ * (*In_ptr--); o += *Coef_ptr++ * (*In_ptr--);
} }
@@ -145,13 +150,13 @@ void DownSample (
if (i<lengthIn) { if (i<lengthIn) {
Coef_ptr = &Coef[0]; Coef_ptr = &Coef[0];
In_ptr = &In[i]; In_ptr = &In[i];
for (j=0;j<FILTERORDER_DS;j++) { for (j=0; j<FILTERORDER_DS; j++) {
o += *Coef_ptr++ * (*Out_ptr--); o += *Coef_ptr++ * (*Out_ptr--);
} }
} else { } else {
Coef_ptr = &Coef[i-lengthIn]; Coef_ptr = &Coef[i-lengthIn];
In_ptr = &In[lengthIn-1]; In_ptr = &In[lengthIn-1];
for (j=0;j<FILTERORDER_DS-(i-lengthIn);j++) { for (j=0; j<FILTERORDER_DS-(i-lengthIn); j++) {
o += *Coef_ptr++ * (*In_ptr--); o += *Coef_ptr++ * (*In_ptr--);
} }
} }

View File

@@ -5,9 +5,8 @@
filter.h filter.h
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/ ******************************************************************/
@@ -16,22 +15,24 @@
void AllPoleFilter( void AllPoleFilter(
float *InOut, /* (i/o) on entrance InOut[-orderCoef] to float *InOut, /* (i/o) on entrance InOut[-orderCoef] to
InOut[-1] contain the state of the filter InOut[-1] contain the state of the
(delayed samples). InOut[0] to filter (delayed samples). InOut[0] to
InOut[lengthInOut-1] contain the filter InOut[lengthInOut-1] contain the filter
input, on en exit InOut[-orderCoef] to input, on en exit InOut[-orderCoef] to
InOut[-1] is unchanged and InOut[0] to InOut[-1] is unchanged and InOut[0] to
InOut[lengthInOut-1] contain filtered InOut[lengthInOut-1] contain filtered
samples */ samples */
float *Coef,/* (i) filter coefficients, Coef[0] is assumed to float *Coef,/* (i) filter coefficients, Coef[0] is assumed
be 1.0 */ to be 1.0 */
int lengthInOut,/* (i) number of input/output samples */ int lengthInOut,/* (i) number of input/output samples */
int orderCoef /* (i) number of filter coefficients */ int orderCoef /* (i) number of filter coefficients */
); );
void AllZeroFilter( void AllZeroFilter(
float *In, /* (i) In[0] to In[lengthInOut-1] contain filter float *In, /* (i) In[0] to In[lengthInOut-1] contain
input samples */ filter input samples */
float *Coef,/* (i) filter coefficients (Coef[0] is assumed float *Coef,/* (i) filter coefficients (Coef[0] is assumed
to be 1.0) */ to be 1.0) */
int lengthInOut,/* (i) number of input/output samples */ int lengthInOut,/* (i) number of input/output samples */
@@ -54,9 +55,9 @@ void ZeroPoleFilter(
int lengthInOut,/* (i) number of input/output samples */ int lengthInOut,/* (i) number of input/output samples */
int orderCoef, /* (i) number of filter coefficients */ int orderCoef, /* (i) number of filter coefficients */
float *Out /* (i/o) on entrance Out[-orderCoef] to Out[-1] float *Out /* (i/o) on entrance Out[-orderCoef] to Out[-1]
contain state of all-pole section. On exit contain state of all-pole section. On
Out[0] to Out[lengthInOut-1] contain exit Out[0] to Out[lengthInOut-1]
filtered samples */ contain filtered samples */
); );
void DownSample ( void DownSample (

View File

@@ -5,9 +5,10 @@
gainquant.c gainquant.c
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/ ******************************************************************/
@@ -15,7 +16,6 @@
#include <math.h> #include <math.h>
#include "constants.h" #include "constants.h"
#include "filter.h" #include "filter.h"
#include "gainquant.h"
/*----------------------------------------------------------------* /*----------------------------------------------------------------*
* quantizer for the gain in the gain-shape coding of residual * quantizer for the gain in the gain-shape coding of residual
@@ -52,7 +52,7 @@ float gainquant(/* (o) quantized gain value */
minmeasure=10000000.0; minmeasure=10000000.0;
tindex=0; tindex=0;
for (i=0;i<cblen;i++) { for (i=0; i<cblen; i++) {
measure=(in-scale*cb[i])*(in-scale*cb[i]); measure=(in-scale*cb[i])*(in-scale*cb[i]);
if (measure<minmeasure) { if (measure<minmeasure) {
@@ -64,6 +64,8 @@ float gainquant(/* (o) quantized gain value */
/* return the quantized value */ /* return the quantized value */
return scale*cb[tindex]; return scale*cb[tindex];
} }

View File

@@ -5,9 +5,8 @@
gainquant.h gainquant.h
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/ ******************************************************************/

View File

@@ -5,15 +5,13 @@
getCBvec.c getCBvec.c
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/ ******************************************************************/
#include "iLBC_define.h" #include "iLBC_define.h"
#include "constants.h" #include "constants.h"
#include "getCBvec.h"
#include <string.h> #include <string.h>
/*----------------------------------------------------------------* /*----------------------------------------------------------------*
@@ -43,6 +41,8 @@ void getCBvec(
/* No filter -> First codebook section */ /* No filter -> First codebook section */
if (index<lMem-cbveclen+1) { if (index<lMem-cbveclen+1) {
/* first non-interpolated vectors */ /* first non-interpolated vectors */
@@ -90,12 +90,15 @@ void getCBvec(
float *pos; float *pos;
float *pp, *pp1; float *pp, *pp1;
memset(tempbuff2, 0, CB_HALFFILTERLEN*sizeof(float)); memset(tempbuff2, 0,
CB_HALFFILTERLEN*sizeof(float));
memcpy(&tempbuff2[CB_HALFFILTERLEN], mem, memcpy(&tempbuff2[CB_HALFFILTERLEN], mem,
lMem*sizeof(float)); lMem*sizeof(float));
memset(&tempbuff2[lMem+CB_HALFFILTERLEN], 0, memset(&tempbuff2[lMem+CB_HALFFILTERLEN], 0,
(CB_HALFFILTERLEN+1)*sizeof(float)); (CB_HALFFILTERLEN+1)*sizeof(float));
k=index-base_size+cbveclen; k=index-base_size+cbveclen;
sFilt=lMem-k; sFilt=lMem-k;
memInd=sFilt+1-CB_HALFFILTERLEN; memInd=sFilt+1-CB_HALFFILTERLEN;
@@ -105,9 +108,9 @@ void getCBvec(
memset(pos, 0, cbveclen*sizeof(float)); memset(pos, 0, cbveclen*sizeof(float));
for (n=0; n<cbveclen; n++) { for (n=0; n<cbveclen; n++) {
pp=&tempbuff2[memInd+n+CB_HALFFILTERLEN]; pp=&tempbuff2[memInd+n+CB_HALFFILTERLEN];
pp1=&cbfiltersTbl[0]; pp1=&cbfiltersTbl[CB_FILTERLEN-1];
for (j=0;j<CB_FILTERLEN;j++) { for (j=0; j<CB_FILTERLEN; j++) {
(*pos)+=(*pp++)*(*pp1++); (*pos)+=(*pp++)*(*pp1--);
} }
pos++; pos++;
} }
@@ -122,13 +125,15 @@ void getCBvec(
float *pp, *pp1; float *pp, *pp1;
int i; int i;
memset(tempbuff2, 0, CB_HALFFILTERLEN*sizeof(float)); memset(tempbuff2, 0,
CB_HALFFILTERLEN*sizeof(float));
memcpy(&tempbuff2[CB_HALFFILTERLEN], mem, memcpy(&tempbuff2[CB_HALFFILTERLEN], mem,
lMem*sizeof(float)); lMem*sizeof(float));
memset(&tempbuff2[lMem+CB_HALFFILTERLEN], 0, memset(&tempbuff2[lMem+CB_HALFFILTERLEN], 0,
(CB_HALFFILTERLEN+1)*sizeof(float)); (CB_HALFFILTERLEN+1)*sizeof(float));
k=2*(index-base_size-(lMem-cbveclen+1))+cbveclen; k=2*(index-base_size-
(lMem-cbveclen+1))+cbveclen;
sFilt=lMem-k; sFilt=lMem-k;
memInd=sFilt+1-CB_HALFFILTERLEN; memInd=sFilt+1-CB_HALFFILTERLEN;
@@ -137,9 +142,9 @@ void getCBvec(
memset(pos, 0, k*sizeof(float)); memset(pos, 0, k*sizeof(float));
for (i=0; i<k; i++) { for (i=0; i<k; i++) {
pp=&tempbuff2[memInd+i+CB_HALFFILTERLEN]; pp=&tempbuff2[memInd+i+CB_HALFFILTERLEN];
pp1=&cbfiltersTbl[0]; pp1=&cbfiltersTbl[CB_FILTERLEN-1];
for (j=0;j<CB_FILTERLEN;j++) { for (j=0; j<CB_FILTERLEN; j++) {
(*pos)+=(*pp++)*(*pp1++); (*pos)+=(*pp++)*(*pp1--);
} }
pos++; pos++;
} }
@@ -147,9 +152,12 @@ void getCBvec(
ihigh=k/2; ihigh=k/2;
ilow=ihigh-5; ilow=ihigh-5;
/* Copy first noninterpolated part */ /* Copy first noninterpolated part */
memcpy(cbvec, tmpbuf+lMem-k/2, ilow*sizeof(float)); memcpy(cbvec, tmpbuf+lMem-k/2,
ilow*sizeof(float));
/* interpolation */ /* interpolation */

View File

@@ -5,15 +5,16 @@
getCBvec.h getCBvec.h
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/ ******************************************************************/
#ifndef __iLBC_GETCBVEC_H #ifndef __iLBC_GETCBVEC_H
#define __iLBC_GETCBVEC_H #define __iLBC_GETCBVEC_H
void getCBvec( void getCBvec(
float *cbvec, /* (o) Constructed codebook vector */ float *cbvec, /* (o) Constructed codebook vector */
float *mem, /* (i) Codebook buffer */ float *mem, /* (i) Codebook buffer */

View File

@@ -5,16 +5,14 @@
helpfun.c helpfun.c
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/ ******************************************************************/
#include <math.h> #include <math.h>
#include "iLBC_define.h" #include "iLBC_define.h"
#include "helpfun.h"
#include "constants.h" #include "constants.h"
/*----------------------------------------------------------------* /*----------------------------------------------------------------*
@@ -25,7 +23,8 @@ void autocorr(
float *r, /* (o) autocorrelation vector */ float *r, /* (o) autocorrelation vector */
const float *x, /* (i) data vector */ const float *x, /* (i) data vector */
int N, /* (i) length of data vector */ int N, /* (i) length of data vector */
int order /* largest lag for calculated autocorrelations */ int order /* largest lag for calculated
autocorrelations */
){ ){
int lag, n; int lag, n;
float sum; float sum;
@@ -39,11 +38,13 @@ void autocorr(
} }
} }
/*----------------------------------------------------------------* /*----------------------------------------------------------------*
* window multiplication * window multiplication
*---------------------------------------------------------------*/ *---------------------------------------------------------------*/
void lbc_window( void window(
float *z, /* (o) the windowed data */ float *z, /* (o) the windowed data */
const float *x, /* (i) the original data vector */ const float *x, /* (i) the original data vector */
const float *y, /* (i) the window */ const float *y, /* (i) the window */
@@ -61,8 +62,8 @@ void lbc_window(
*---------------------------------------------------------------*/ *---------------------------------------------------------------*/
void levdurb( void levdurb(
float *a, /* (o) lpc coefficient vector starting with 1.0 float *a, /* (o) lpc coefficient vector starting
*/ with 1.0 */
float *k, /* (o) reflection coefficients */ float *k, /* (o) reflection coefficients */
float *r, /* (i) autocorrelation vector */ float *r, /* (i) autocorrelation vector */
int order /* (i) order of lpc filter */ int order /* (i) order of lpc filter */
@@ -92,6 +93,8 @@ void levdurb(
sum = a[i+1] + k[m] * a[m - i]; sum = a[i+1] + k[m] * a[m - i];
a[m - i] += k[m] * a[i+1]; a[m - i] += k[m] * a[i+1];
a[i+1] = sum; a[i+1] = sum;
} }
a[m+1] = k[m]; a[m+1] = k[m];
} }
@@ -104,8 +107,10 @@ void levdurb(
void interpolate( void interpolate(
float *out, /* (o) the interpolated vector */ float *out, /* (o) the interpolated vector */
float *in1, /* (i) the first vector for the interpolation */ float *in1, /* (i) the first vector for the
float *in2, /* (i) the second vector for the interpolation */ interpolation */
float *in2, /* (i) the second vector for the
interpolation */
float coef, /* (i) interpolation weights */ float coef, /* (i) interpolation weights */
int length /* (i) length of all vectors */ int length /* (i) length of all vectors */
){ ){
@@ -123,7 +128,8 @@ void interpolate(
*---------------------------------------------------------------*/ *---------------------------------------------------------------*/
void bwexpand( void bwexpand(
float *out, /* (o) the bandwidth expanded lpc coefficients */ float *out, /* (o) the bandwidth expanded lpc
coefficients */
float *in, /* (i) the lpc coefficients before bandwidth float *in, /* (i) the lpc coefficients before bandwidth
expansion */ expansion */
float coef, /* (i) the bandwidth expansion factor */ float coef, /* (i) the bandwidth expansion factor */
@@ -143,6 +149,8 @@ void bwexpand(
/*----------------------------------------------------------------* /*----------------------------------------------------------------*
* vector quantization * vector quantization
*---------------------------------------------------------------*/ *---------------------------------------------------------------*/
void vq( void vq(
@@ -197,6 +205,8 @@ void SplitVQ(
int cb_pos, X_pos, i; int cb_pos, X_pos, i;
cb_pos = 0; cb_pos = 0;
X_pos= 0; X_pos= 0;
for (i = 0; i < nsplit; i++) { for (i = 0; i < nsplit; i++) {
vq(qX + X_pos, index + i, CB + cb_pos, X + X_pos, vq(qX + X_pos, index + i, CB + cb_pos, X + X_pos,
@@ -246,10 +256,13 @@ int LSF_check( /* (o) 1 for stable lsf vectors and 0 for
nonstable ones */ nonstable ones */
float *lsf, /* (i) a table of lsf vectors */ float *lsf, /* (i) a table of lsf vectors */
int dim, /* (i) the dimension of each lsf vector */ int dim, /* (i) the dimension of each lsf vector */
int NoAn /* (i) the number of lsf vectors in the table */ int NoAn /* (i) the number of lsf vectors in the
table */
){ ){
int k,n,m, Nit=2, change=0,pos; int k,n,m, Nit=2, change=0,pos;
float tmp; float tmp;
static float eps=(float)0.039; /* 50 Hz */ static float eps=(float)0.039; /* 50 Hz */
static float eps2=(float)0.0195; static float eps2=(float)0.0195;
static float maxlsf=(float)3.14; /* 4000 Hz */ static float maxlsf=(float)3.14; /* 4000 Hz */
@@ -257,9 +270,9 @@ int LSF_check( /* (o) 1 for stable lsf vectors and 0 for
/* LSF separation check*/ /* LSF separation check*/
for (n=0;n<Nit;n++) { /* Run through a couple of times */ for (n=0; n<Nit; n++) { /* Run through a couple of times */
for (m=0;m<NoAn;m++) { /* Number of analyses per frame */ for (m=0; m<NoAn; m++) { /* Number of analyses per frame */
for (k=0;k<(dim-1);k++) { for (k=0; k<(dim-1); k++) {
pos=m*dim+k; pos=m*dim+k;
if ((lsf[pos+1]-lsf[pos])<eps) { if ((lsf[pos+1]-lsf[pos])<eps) {

View File

@@ -5,9 +5,8 @@
helpfun.h helpfun.h
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/ ******************************************************************/
@@ -18,16 +17,19 @@ void autocorr(
float *r, /* (o) autocorrelation vector */ float *r, /* (o) autocorrelation vector */
const float *x, /* (i) data vector */ const float *x, /* (i) data vector */
int N, /* (i) length of data vector */ int N, /* (i) length of data vector */
int order /* largest lag for calculated autocorrelations */ int order /* largest lag for calculated
autocorrelations */
); );
void lbc_window( void window(
float *z, /* (o) the windowed data */ float *z, /* (o) the windowed data */
const float *x, /* (i) the original data vector */ const float *x, /* (i) the original data vector */
const float *y, /* (i) the window */ const float *y, /* (i) the window */
int N /* (i) length of all vectors */ int N /* (i) length of all vectors */
); );
void levdurb( void levdurb(
float *a, /* (o) lpc coefficient vector starting float *a, /* (o) lpc coefficient vector starting
with 1.0 */ with 1.0 */
@@ -38,14 +40,17 @@ void levdurb(
void interpolate( void interpolate(
float *out, /* (o) the interpolated vector */ float *out, /* (o) the interpolated vector */
float *in1, /* (i) the first vector for the interpolation */ float *in1, /* (i) the first vector for the
float *in2, /* (i) the second vector for the interpolation */ interpolation */
float *in2, /* (i) the second vector for the
interpolation */
float coef, /* (i) interpolation weights */ float coef, /* (i) interpolation weights */
int length /* (i) length of all vectors */ int length /* (i) length of all vectors */
); );
void bwexpand( void bwexpand(
float *out, /* (o) the bandwidth expanded lpc coefficients */ float *out, /* (o) the bandwidth expanded lpc
coefficients */
float *in, /* (i) the lpc coefficients before bandwidth float *in, /* (i) the lpc coefficients before bandwidth
expansion */ expansion */
float coef, /* (i) the bandwidth expansion factor */ float coef, /* (i) the bandwidth expansion factor */
@@ -78,6 +83,8 @@ void sort_sq(
int *index, /* (o) the quantization index */ int *index, /* (o) the quantization index */
float x, /* (i) the value to quantize */ float x, /* (i) the value to quantize */
const float *cb,/* (i) the quantization codebook */ const float *cb,/* (i) the quantization codebook */
int cb_size /* (i) the size of the quantization codebook */ int cb_size /* (i) the size of the quantization codebook */
); );
@@ -85,7 +92,8 @@ int LSF_check( /* (o) 1 for stable lsf vectors and 0 for
nonstable ones */ nonstable ones */
float *lsf, /* (i) a table of lsf vectors */ float *lsf, /* (i) a table of lsf vectors */
int dim, /* (i) the dimension of each lsf vector */ int dim, /* (i) the dimension of each lsf vector */
int NoAn /* (i) the number of lsf vectors in the table */ int NoAn /* (i) the number of lsf vectors in the
table */
); );
#endif #endif

View File

@@ -5,14 +5,12 @@
hpInput.c hpInput.c
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/ ******************************************************************/
#include "constants.h" #include "constants.h"
#include "hpInput.h"
/*----------------------------------------------------------------* /*----------------------------------------------------------------*
* Input high-pass filter * Input high-pass filter
@@ -39,6 +37,8 @@ void hpInput(
mem[1] = mem[0]; mem[1] = mem[0];
mem[0] = *pi; mem[0] = *pi;
po++; po++;
pi++; pi++;
} }

View File

@@ -5,12 +5,13 @@
hpInput.h hpInput.h
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/ ******************************************************************/
#ifndef __iLBC_HPINPUT_H #ifndef __iLBC_HPINPUT_H
#define __iLBC_HPINPUT_H #define __iLBC_HPINPUT_H

View File

@@ -5,14 +5,14 @@
hpOutput.c hpOutput.c
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/ ******************************************************************/
#include "constants.h" #include "constants.h"
#include "hpOutput.h"
/*----------------------------------------------------------------* /*----------------------------------------------------------------*
* Output high-pass filter * Output high-pass filter

View File

@@ -5,9 +5,8 @@
hpOutput.h hpOutput.h
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/ ******************************************************************/

View File

@@ -5,9 +5,8 @@
iCBConstruct.c iCBConstruct.c
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/ ******************************************************************/
@@ -16,18 +15,19 @@
#include "iLBC_define.h" #include "iLBC_define.h"
#include "gainquant.h" #include "gainquant.h"
#include "getCBvec.h" #include "getCBvec.h"
#include "iCBConstruct.h"
/*----------------------------------------------------------------* /*----------------------------------------------------------------*
* Convert the codebook indexes to make the search easier * Convert the codebook indexes to make the search easier
*---------------------------------------------------------------*/ *---------------------------------------------------------------*/
void index_conv_enc( void index_conv_enc(
int *index /* (i/o) Codebook indexes */ int *index /* (i/o) Codebook indexes */
){ ){
int k; int k;
for (k=1;k<CB_NSTAGES;k++) { for (k=1; k<CB_NSTAGES; k++) {
if ((index[k]>=108)&&(index[k]<172)) { if ((index[k]>=108)&&(index[k]<172)) {
index[k]-=64; index[k]-=64;
@@ -44,7 +44,7 @@ void index_conv_dec(
){ ){
int k; int k;
for (k=1;k<CB_NSTAGES;k++) { for (k=1; k<CB_NSTAGES; k++) {
if ((index[k]>=44)&&(index[k]<108)) { if ((index[k]>=44)&&(index[k]<108)) {
index[k]+=64; index[k]+=64;
@@ -76,6 +76,8 @@ void iCBConstruct(
/* gain de-quantization */ /* gain de-quantization */
gain[0] = gaindequant(gain_index[0], 1.0, 32); gain[0] = gaindequant(gain_index[0], 1.0, 32);
if (nStages > 1) { if (nStages > 1) {
gain[1] = gaindequant(gain_index[1], gain[1] = gaindequant(gain_index[1],
(float)fabs(gain[0]), 16); (float)fabs(gain[0]), 16);

View File

@@ -3,11 +3,12 @@
iLBC Speech Coder ANSI-C Source Code iLBC Speech Coder ANSI-C Source Code
iCBConstruct.h iCBConstruct.h
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/ ******************************************************************/

View File

@@ -5,9 +5,8 @@
iCBSearch.c iCBSearch.c
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/ ******************************************************************/
@@ -15,7 +14,6 @@
#include <string.h> #include <string.h>
#include "iLBC_define.h" #include "iLBC_define.h"
#include "iCBSearch.h"
#include "gainquant.h" #include "gainquant.h"
#include "createCB.h" #include "createCB.h"
#include "filter.h" #include "filter.h"
@@ -26,6 +24,8 @@
*---------------------------------------------------------------*/ *---------------------------------------------------------------*/
void iCBSearch( void iCBSearch(
iLBC_Enc_Inst_t *iLBCenc_inst,
/* (i) the encoder state structure */
int *index, /* (o) Codebook indices */ int *index, /* (o) Codebook indices */
int *gain_index,/* (o) Gain quantization indices */ int *gain_index,/* (o) Gain quantization indices */
float *intarget,/* (i) Target vector for encoding */ float *intarget,/* (i) Target vector for encoding */
@@ -35,7 +35,7 @@ void iCBSearch(
int nStages, /* (i) Number of codebook stages */ int nStages, /* (i) Number of codebook stages */
float *weightDenum, /* (i) weighting filter coefficients */ float *weightDenum, /* (i) weighting filter coefficients */
float *weightState, /* (i) weighting filter state */ float *weightState, /* (i) weighting filter state */
int block /* (i) the subblock number */ int block /* (i) the sub-block number */
){ ){
int i, j, icount, stage, best_index, range, counter; int i, j, icount, stage, best_index, range, counter;
float max_measure, gain, measure, crossDot, ftmp; float max_measure, gain, measure, crossDot, ftmp;
@@ -44,6 +44,8 @@ void iCBSearch(
int base_index, sInd, eInd, base_size; int base_index, sInd, eInd, base_size;
int sIndAug=0, eIndAug=0; int sIndAug=0, eIndAug=0;
float buf[CB_MEML+SUBL+2*LPC_FILTERORDER]; float buf[CB_MEML+SUBL+2*LPC_FILTERORDER];
float invenergy[CB_EXPAND*128], energy[CB_EXPAND*128]; float invenergy[CB_EXPAND*128], energy[CB_EXPAND*128];
float *pp, *ppi=0, *ppo=0, *ppe=0; float *pp, *ppi=0, *ppo=0, *ppe=0;
float cbvectors[CB_MEML]; float cbvectors[CB_MEML];
@@ -76,7 +78,7 @@ void iCBSearch(
memcpy(target, buf+LPC_FILTERORDER+lMem, lTarget*sizeof(float)); memcpy(target, buf+LPC_FILTERORDER+lMem, lTarget*sizeof(float));
tene=0.0; tene=0.0;
for (i=0;i<lTarget;i++) { for (i=0; i<lTarget; i++) {
tene+=target[i]*target[i]; tene+=target[i]*target[i];
} }
@@ -87,7 +89,7 @@ void iCBSearch(
/* The Main Loop over stages */ /* The Main Loop over stages */
for (stage=0;stage<nStages; stage++) { for (stage=0; stage<nStages; stage++) {
range = search_rangeTbl[block][stage]; range = search_rangeTbl[block][stage];
@@ -98,6 +100,8 @@ void iCBSearch(
best_index = 0; best_index = 0;
/* Compute cross dot product between the target /* Compute cross dot product between the target
and the CB memory */ and the CB memory */
crossDot=0.0; crossDot=0.0;
@@ -117,11 +121,10 @@ void iCBSearch(
*ppe=0.0; *ppe=0.0;
pp=buf+LPC_FILTERORDER+lMem-lTarget; pp=buf+LPC_FILTERORDER+lMem-lTarget;
for (j=0; j<lTarget; j++) { for (j=0; j<lTarget; j++) {
*ppe+=(*pp)*(*pp); *ppe+=(*pp)*(*pp++);
pp++;
} }
if(*ppe>0.0) { if (*ppe>0.0) {
invenergy[0] = (float) 1.0 / (*ppe + EPS); invenergy[0] = (float) 1.0 / (*ppe + EPS);
} else { } else {
invenergy[0] = (float) 0.0; invenergy[0] = (float) 0.0;
@@ -147,17 +150,19 @@ void iCBSearch(
gain = ftmp; gain = ftmp;
} }
/* loop over lags 40+ in the first codebook section, /* loop over the main first codebook section,
full search */ full search */
for (icount=1; icount<range; icount++) { for (icount=1; icount<range; icount++) {
/* calculate measure */ /* calculate measure */
crossDot=0.0; crossDot=0.0;
pp = buf+LPC_FILTERORDER+lMem-lTarget-icount; pp = buf+LPC_FILTERORDER+lMem-lTarget-icount;
for (j=0;j<lTarget;j++) { for (j=0; j<lTarget; j++) {
crossDot += target[j]*(*pp++); crossDot += target[j]*(*pp++);
} }
@@ -167,7 +172,7 @@ void iCBSearch(
ppo--; ppo--;
ppi--; ppi--;
if(energy[icount]>0.0) { if (energy[icount]>0.0) {
invenergy[icount] = invenergy[icount] =
(float)1.0/(energy[icount]+EPS); (float)1.0/(energy[icount]+EPS);
} else { } else {
@@ -187,27 +192,27 @@ void iCBSearch(
/* check if measure is better */ /* check if measure is better */
ftmp = crossDot*invenergy[icount]; ftmp = crossDot*invenergy[icount];
if ((measure>max_measure) && (fabs(ftmp)<CB_MAXGAIN)) {
if ((measure>max_measure) && (fabs(ftmp)<CB_MAXGAIN)){
best_index = icount; best_index = icount;
max_measure = measure; max_measure = measure;
gain = ftmp; gain = ftmp;
} }
} }
/* Loop over lags 20-39 in the first codebook section, /* Loop over augmented part in the first codebook
* full search. * section, full search.
* The vectors are interpolated. * The vectors are interpolated.
*/ */
if(lTarget==SUBL) { if (lTarget==SUBL) {
/* Search for best possible lag and compute
the CB-vectors' energy. */
/* Search for best possible cb vector and
compute the CB-vectors' energy. */
searchAugmentedCB(20, 39, stage, base_size-lTarget/2, searchAugmentedCB(20, 39, stage, base_size-lTarget/2,
target, buf+LPC_FILTERORDER+lMem, target, buf+LPC_FILTERORDER+lMem,
&max_measure, &best_index, &gain, energy, invenergy); &max_measure, &best_index, &gain, energy,
invenergy);
} }
@@ -234,7 +239,7 @@ void iCBSearch(
sInd=base_index-CB_RESRANGE/2; sInd=base_index-CB_RESRANGE/2;
eInd=sInd+CB_RESRANGE; eInd=sInd+CB_RESRANGE;
if(lTarget==SUBL) { if (lTarget==SUBL) {
if (sInd<0) { if (sInd<0) {
@@ -242,15 +247,15 @@ void iCBSearch(
eIndAug = 39; eIndAug = 39;
sInd=0; sInd=0;
} else if( base_index < (base_size-20) ) { } else if ( base_index < (base_size-20) ) {
if(eInd > range) { if (eInd > range) {
sInd -= (eInd-range); sInd -= (eInd-range);
eInd = range; eInd = range;
} }
} else { /* base_index >= (base_size-20) */ } else { /* base_index >= (base_size-20) */
if(sInd < (base_size-20)) { if (sInd < (base_size-20)) {
sIndAug = 20; sIndAug = 20;
sInd = 0; sInd = 0;
eInd = 0; eInd = 0;
@@ -263,12 +268,14 @@ void iCBSearch(
} else { } else {
sIndAug = 20 + sInd - (base_size-20); sIndAug = 20 + sInd - (base_size-20);
eIndAug = 39; eIndAug = 39;
sInd = 0; sInd = 0;
eInd = CB_RESRANGE - (eIndAug-sIndAug+1); eInd = CB_RESRANGE - (eIndAug-sIndAug+1);
} }
} }
} else { /* lTarget = 22 */ } else { /* lTarget = 22 or 23 */
if (sInd < 0) { if (sInd < 0) {
eInd -= sInd; eInd -= sInd;
@@ -290,20 +297,19 @@ void iCBSearch(
eInd += base_size; eInd += base_size;
if(stage==0) { if (stage==0) {
ppe = energy+base_size; ppe = energy+base_size;
*ppe=0.0; *ppe=0.0;
pp=cbvectors+lMem-lTarget; pp=cbvectors+lMem-lTarget;
for (j=0; j<lTarget; j++) { for (j=0; j<lTarget; j++) {
*ppe+=(*pp)*(*pp); *ppe+=(*pp)*(*pp++);
pp++;
} }
ppi = cbvectors + lMem - 1 - lTarget; ppi = cbvectors + lMem - 1 - lTarget;
ppo = cbvectors + lMem - 1; ppo = cbvectors + lMem - 1;
for(j=0;j<(range-1);j++) { for (j=0; j<(range-1); j++) {
*(ppe+1) = *ppe + (*ppi)*(*ppi) - (*ppo)*(*ppo); *(ppe+1) = *ppe + (*ppi)*(*ppi) - (*ppo)*(*ppo);
ppo--; ppo--;
ppi--; ppi--;
@@ -318,16 +324,18 @@ void iCBSearch(
/* calculate measure */ /* calculate measure */
crossDot=0.0; crossDot=0.0;
pp=cbvectors + lMem - (counter++) - lTarget; pp=cbvectors + lMem - (counter++) - lTarget;
for (j=0;j<lTarget;j++) { for (j=0;j<lTarget;j++) {
crossDot += target[j]*(*pp++); crossDot += target[j]*(*pp++);
} }
if(energy[icount]>0.0) { if (energy[icount]>0.0) {
invenergy[icount] = (float) 1.0/(energy[icount]+EPS); invenergy[icount] =(float)1.0/(energy[icount]+EPS);
} else { } else {
invenergy[icount] = (float) 0.0; invenergy[icount] =(float)0.0;
} }
if (stage==0) { if (stage==0) {
@@ -346,7 +354,7 @@ void iCBSearch(
/* check if measure is better */ /* check if measure is better */
ftmp = crossDot*invenergy[icount]; ftmp = crossDot*invenergy[icount];
if ((measure>max_measure) && (fabs(ftmp)<CB_MAXGAIN)){ if ((measure>max_measure) && (fabs(ftmp)<CB_MAXGAIN)) {
best_index = icount; best_index = icount;
max_measure = measure; max_measure = measure;
gain = ftmp; gain = ftmp;
@@ -356,11 +364,10 @@ void iCBSearch(
/* Search the augmented CB inside the limited range. */ /* Search the augmented CB inside the limited range. */
if ((lTarget==SUBL)&&(sIndAug!=0)) { if ((lTarget==SUBL)&&(sIndAug!=0)) {
searchAugmentedCB(sIndAug, eIndAug, stage, searchAugmentedCB(sIndAug, eIndAug, stage,
2*base_size-20, target, cbvectors+lMem, 2*base_size-20, target, cbvectors+lMem,
&max_measure, &best_index, &gain, energy, invenergy); &max_measure, &best_index, &gain, energy,
invenergy);
} }
/* record best index */ /* record best index */
@@ -373,6 +380,8 @@ void iCBSearch(
if (gain<0.0){ if (gain<0.0){
gain = 0.0; gain = 0.0;
} }
if (gain>CB_MAXGAIN) { if (gain>CB_MAXGAIN) {
@@ -390,11 +399,12 @@ void iCBSearch(
} }
} }
/* Extract the best (according to measure) codebook vector */ /* Extract the best (according to measure)
codebook vector */
if(lTarget==(STATE_LEN-STATE_SHORT_LEN)) { if (lTarget==(STATE_LEN-iLBCenc_inst->state_short_len)) {
if(index[stage]<base_size) { if (index[stage]<base_size) {
pp=buf+LPC_FILTERORDER+lMem-lTarget-index[stage]; pp=buf+LPC_FILTERORDER+lMem-lTarget-index[stage];
} else { } else {
pp=cbvectors+lMem-lTarget- pp=cbvectors+lMem-lTarget-
@@ -404,20 +414,21 @@ void iCBSearch(
if (index[stage]<base_size) { if (index[stage]<base_size) {
if (index[stage]<(base_size-20)) { if (index[stage]<(base_size-20)) {
pp=buf+LPC_FILTERORDER+lMem-lTarget-index[stage]; pp=buf+LPC_FILTERORDER+lMem-
lTarget-index[stage];
} else { } else {
createAugmentedVec(index[stage]-base_size+40, createAugmentedVec(index[stage]-base_size+40,
buf+LPC_FILTERORDER+lMem,aug_vec); buf+LPC_FILTERORDER+lMem,aug_vec);
pp=aug_vec; pp=aug_vec;
} }
} else { } else {
int filterno, lag_val; int filterno, position;
filterno=index[stage]/base_size; filterno=index[stage]/base_size;
lag_val=index[stage]-filterno*base_size; position=index[stage]-filterno*base_size;
if (lag_val<(base_size-20)) { if (position<(base_size-20)) {
pp=cbvectors+filterno*lMem-lTarget- pp=cbvectors+filterno*lMem-lTarget-
index[stage]+filterno*base_size; index[stage]+filterno*base_size;
} else { } else {
@@ -425,6 +436,8 @@ void iCBSearch(
index[stage]-(filterno+1)*base_size+40, index[stage]-(filterno+1)*base_size+40,
cbvectors+filterno*lMem,aug_vec); cbvectors+filterno*lMem,aug_vec);
pp=aug_vec; pp=aug_vec;
} }
} }
} }
@@ -432,7 +445,7 @@ void iCBSearch(
/* Subtract the best codebook vector, according /* Subtract the best codebook vector, according
to measure, from the target vector */ to measure, from the target vector */
for(j=0;j<lTarget;j++){ for (j=0;j<lTarget;j++) {
cvec[j] += gain*(*pp); cvec[j] += gain*(*pp);
target[j] -= gain*(*pp++); target[j] -= gain*(*pp++);
} }
@@ -445,12 +458,12 @@ void iCBSearch(
/* Gain adjustment for energy matching */ /* Gain adjustment for energy matching */
cene=0.0; cene=0.0;
for (i=0;i<lTarget;i++) { for (i=0; i<lTarget; i++) {
cene+=cvec[i]*cvec[i]; cene+=cvec[i]*cvec[i];
} }
j=gain_index[0]; j=gain_index[0];
for (i=gain_index[0];i<32;i++) { for (i=gain_index[0]; i<32; i++) {
ftmp=cene*gain_sq5Tbl[i]*gain_sq5Tbl[i]; ftmp=cene*gain_sq5Tbl[i]*gain_sq5Tbl[i];
if ((ftmp<(tene*gains[0]*gains[0])) && if ((ftmp<(tene*gains[0]*gains[0])) &&

View File

@@ -5,9 +5,8 @@
iCBSearch.h iCBSearch.h
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/ ******************************************************************/
@@ -15,6 +14,8 @@
#define __iLBC_ICBSEARCH_H #define __iLBC_ICBSEARCH_H
void iCBSearch( void iCBSearch(
iLBC_Enc_Inst_t *iLBCenc_inst,
/* (i) the encoder state structure */
int *index, /* (o) Codebook indices */ int *index, /* (o) Codebook indices */
int *gain_index,/* (o) Gain quantization indices */ int *gain_index,/* (o) Gain quantization indices */
float *intarget,/* (i) Target vector for encoding */ float *intarget,/* (i) Target vector for encoding */
@@ -23,8 +24,10 @@ void iCBSearch(
int lTarget, /* (i) Length of vector */ int lTarget, /* (i) Length of vector */
int nStages, /* (i) Number of codebook stages */ int nStages, /* (i) Number of codebook stages */
float *weightDenum, /* (i) weighting filter coefficients */ float *weightDenum, /* (i) weighting filter coefficients */
float *weightState, /* (i) weighting filter state */ float *weightState, /* (i) weighting filter state */
int block /* (i) the subblock number */ int block /* (i) the sub-block number */
); );
#endif #endif

View File

@@ -5,9 +5,8 @@
iLBC_decode.c iLBC_decode.c
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/ ******************************************************************/
@@ -22,7 +21,6 @@
#include "helpfun.h" #include "helpfun.h"
#include "constants.h" #include "constants.h"
#include "packing.h" #include "packing.h"
#include "iLBC_decode.h"
#include "string.h" #include "string.h"
#include "enhancer.h" #include "enhancer.h"
#include "hpOutput.h" #include "hpOutput.h"
@@ -35,77 +33,116 @@
short initDecode( /* (o) Number of decoded short initDecode( /* (o) Number of decoded
samples */ samples */
iLBC_Dec_Inst_t *iLBCdec_inst, /* (i/o) Decoder instance */ iLBC_Dec_Inst_t *iLBCdec_inst, /* (i/o) Decoder instance */
int mode, /* (i) frame size mode */
int use_enhancer /* (i) 1 to use enhancer int use_enhancer /* (i) 1 to use enhancer
0 to run without 0 to run without
enhancer */ enhancer */
){ ){
int i; int i;
memset((*iLBCdec_inst).syntMem, 0, iLBCdec_inst->mode = mode;
if (mode==30) {
iLBCdec_inst->blockl = BLOCKL_30MS;
iLBCdec_inst->nsub = NSUB_30MS;
iLBCdec_inst->nasub = NASUB_30MS;
iLBCdec_inst->lpc_n = LPC_N_30MS;
iLBCdec_inst->no_of_bytes = NO_OF_BYTES_30MS;
iLBCdec_inst->no_of_words = NO_OF_WORDS_30MS;
iLBCdec_inst->state_short_len=STATE_SHORT_LEN_30MS;
/* ULP init */
iLBCdec_inst->ULP_inst=&ULP_30msTbl;
}
else if (mode==20) {
iLBCdec_inst->blockl = BLOCKL_20MS;
iLBCdec_inst->nsub = NSUB_20MS;
iLBCdec_inst->nasub = NASUB_20MS;
iLBCdec_inst->lpc_n = LPC_N_20MS;
iLBCdec_inst->no_of_bytes = NO_OF_BYTES_20MS;
iLBCdec_inst->no_of_words = NO_OF_WORDS_20MS;
iLBCdec_inst->state_short_len=STATE_SHORT_LEN_20MS;
/* ULP init */
iLBCdec_inst->ULP_inst=&ULP_20msTbl;
}
else {
exit(2);
}
memset(iLBCdec_inst->syntMem, 0,
LPC_FILTERORDER*sizeof(float)); LPC_FILTERORDER*sizeof(float));
memcpy((*iLBCdec_inst).lsfdeqold, lsfmeanTbl, memcpy((*iLBCdec_inst).lsfdeqold, lsfmeanTbl,
LPC_FILTERORDER*sizeof(float)); LPC_FILTERORDER*sizeof(float));
memset((*iLBCdec_inst).old_syntdenum, 0, memset(iLBCdec_inst->old_syntdenum, 0,
((LPC_FILTERORDER + 1)*NSUB)*sizeof(float)); ((LPC_FILTERORDER + 1)*NSUB_MAX)*sizeof(float));
for (i=0; i<NSUB; i++) for (i=0; i<NSUB_MAX; i++)
(*iLBCdec_inst).old_syntdenum[i*(LPC_FILTERORDER+1)]=1.0; iLBCdec_inst->old_syntdenum[i*(LPC_FILTERORDER+1)]=1.0;
(*iLBCdec_inst).last_lag = 20; iLBCdec_inst->last_lag = 20;
(*iLBCdec_inst).prevLag = 120; iLBCdec_inst->prevLag = 120;
(*iLBCdec_inst).prevGain = 0.0; iLBCdec_inst->per = 0.0;
(*iLBCdec_inst).consPLICount = 0; iLBCdec_inst->consPLICount = 0;
(*iLBCdec_inst).prevPLI = 0; iLBCdec_inst->prevPLI = 0;
(*iLBCdec_inst).prevLpc[0] = 1.0; iLBCdec_inst->prevLpc[0] = 1.0;
memset((*iLBCdec_inst).prevLpc+1,0, memset(iLBCdec_inst->prevLpc+1,0,
LPC_FILTERORDER*sizeof(float)); LPC_FILTERORDER*sizeof(float));
memset((*iLBCdec_inst).prevResidual, 0, BLOCKL*sizeof(float)); memset(iLBCdec_inst->prevResidual, 0, BLOCKL_MAX*sizeof(float));
(*iLBCdec_inst).seed=777; iLBCdec_inst->seed=777;
memset((*iLBCdec_inst).hpomem, 0, 4*sizeof(float)); memset(iLBCdec_inst->hpomem, 0, 4*sizeof(float));
(*iLBCdec_inst).use_enhancer = use_enhancer; iLBCdec_inst->use_enhancer = use_enhancer;
memset((*iLBCdec_inst).enh_buf, 0, ENH_BUFL*sizeof(float)); memset(iLBCdec_inst->enh_buf, 0, ENH_BUFL*sizeof(float));
for (i=0;i<ENH_NBLOCKS_TOT;i++) for (i=0;i<ENH_NBLOCKS_TOT;i++)
(*iLBCdec_inst).enh_period[i]=(float)40.0; iLBCdec_inst->enh_period[i]=(float)40.0;
iLBCdec_inst->prev_enh_pl = 0; iLBCdec_inst->prev_enh_pl = 0;
return (BLOCKL); return (iLBCdec_inst->blockl);
} }
/*----------------------------------------------------------------* /*----------------------------------------------------------------*
* frame residual decoder function (subrutine to iLBC_decode) * frame residual decoder function (subrutine to iLBC_decode)
*---------------------------------------------------------------*/ *---------------------------------------------------------------*/
static void Decode( void Decode(
iLBC_Dec_Inst_t *iLBCdec_inst, /* (i/o) the decoder state
structure */
float *decresidual, /* (o) decoded residual frame */ float *decresidual, /* (o) decoded residual frame */
int start, /* (i) location of start state */ int start, /* (i) location of start
int idxForMax, /* (i) codebook index for the maximum state */
value */ int idxForMax, /* (i) codebook index for the
int *idxVec, /* (i) codebook indexes for the samples maximum value */
in the start state */ int *idxVec, /* (i) codebook indexes for the
float *syntdenum, /* (i) the decoded synthesis filter samples in the start
coefficients */ state */
int *cb_index, /* (i) the indexes for the adaptive float *syntdenum, /* (i) the decoded synthesis
codebook */ filter coefficients */
int *gain_index, /* (i) the indexes for the corresponding int *cb_index, /* (i) the indexes for the
gains */ adaptive codebook */
int *extra_cb_index,/* (i) the indexes for the adaptive int *gain_index, /* (i) the indexes for the
codebook part of start state */ corresponding gains */
int *extra_gain_index, /* (i) the indexes for the corresponding int *extra_cb_index, /* (i) the indexes for the
gains */ adaptive codebook part
int state_first /* (i) 1 if non adaptive part of start of start state */
state comes first 0 if that part int *extra_gain_index, /* (i) the indexes for the
corresponding gains */
int state_first /* (i) 1 if non adaptive part
of start state comes
first 0 if that part
comes last */ comes last */
){ ){
float reverseDecresidual[BLOCKL], mem[CB_MEML]; float reverseDecresidual[BLOCKL_MAX], mem[CB_MEML];
int k, meml_gotten, Nfor, Nback, i; int k, meml_gotten, Nfor, Nback, i;
int diff, start_pos; int diff, start_pos;
int subcount, subframe; int subcount, subframe;
diff = STATE_LEN - STATE_SHORT_LEN; diff = STATE_LEN - iLBCdec_inst->state_short_len;
if (state_first == 1) { if (state_first == 1) {
start_pos = (start-1)*SUBL; start_pos = (start-1)*SUBL;
@@ -117,20 +154,25 @@ static void Decode(
StateConstructW(idxForMax, idxVec, StateConstructW(idxForMax, idxVec,
&syntdenum[(start-1)*(LPC_FILTERORDER+1)], &syntdenum[(start-1)*(LPC_FILTERORDER+1)],
&decresidual[start_pos], STATE_SHORT_LEN); &decresidual[start_pos], iLBCdec_inst->state_short_len);
if (state_first) { /* put adaptive part in the end */ if (state_first) { /* put adaptive part in the end */
/* setup memory */ /* setup memory */
memset(mem, 0, (CB_MEML-STATE_SHORT_LEN)*sizeof(float)); memset(mem, 0,
memcpy(mem+CB_MEML-STATE_SHORT_LEN, decresidual+start_pos, (CB_MEML-iLBCdec_inst->state_short_len)*sizeof(float));
STATE_SHORT_LEN*sizeof(float)); memcpy(mem+CB_MEML-iLBCdec_inst->state_short_len,
decresidual+start_pos,
iLBCdec_inst->state_short_len*sizeof(float));
/* construct decoded vector */ /* construct decoded vector */
iCBConstruct(&decresidual[start_pos+STATE_SHORT_LEN], iCBConstruct(
&decresidual[start_pos+iLBCdec_inst->state_short_len],
extra_cb_index, extra_gain_index, mem+CB_MEML-stMemLTbl, extra_cb_index, extra_gain_index, mem+CB_MEML-stMemLTbl,
stMemLTbl, diff, CB_NSTAGES); stMemLTbl, diff, CB_NSTAGES);
@@ -139,15 +181,16 @@ static void Decode(
/* create reversed vectors for prediction */ /* create reversed vectors for prediction */
for(k=0; k<diff; k++ ){ for (k=0; k<diff; k++) {
reverseDecresidual[k] = reverseDecresidual[k] =
decresidual[(start+1)*SUBL -1-(k+STATE_SHORT_LEN)]; decresidual[(start+1)*SUBL-1-
(k+iLBCdec_inst->state_short_len)];
} }
/* setup memory */ /* setup memory */
meml_gotten = STATE_SHORT_LEN; meml_gotten = iLBCdec_inst->state_short_len;
for( k=0; k<meml_gotten; k++){ for (k=0; k<meml_gotten; k++){
mem[CB_MEML-1-k] = decresidual[start_pos + k]; mem[CB_MEML-1-k] = decresidual[start_pos + k];
} }
memset(mem, 0, (CB_MEML-k)*sizeof(float)); memset(mem, 0, (CB_MEML-k)*sizeof(float));
@@ -160,20 +203,22 @@ static void Decode(
/* get decoded residual from reversed vector */ /* get decoded residual from reversed vector */
for( k=0; k<diff; k++ ){ for (k=0; k<diff; k++) {
decresidual[start_pos-1-k] = reverseDecresidual[k]; decresidual[start_pos-1-k] = reverseDecresidual[k];
} }
} }
/* counter for predicted subframes */ /* counter for predicted sub-frames */
subcount=0; subcount=0;
/* forward prediction of subframes */ /* forward prediction of sub-frames */
Nfor = NSUB-start-1; Nfor = iLBCdec_inst->nsub-start-1;
if( Nfor > 0 ){
if ( Nfor > 0 ){
/* setup memory */ /* setup memory */
@@ -181,7 +226,7 @@ static void Decode(
memcpy(mem+CB_MEML-STATE_LEN, decresidual+(start-1)*SUBL, memcpy(mem+CB_MEML-STATE_LEN, decresidual+(start-1)*SUBL,
STATE_LEN*sizeof(float)); STATE_LEN*sizeof(float));
/* loop over subframes to encode */ /* loop over sub-frames to encode */
for (subframe=0; subframe<Nfor; subframe++) { for (subframe=0; subframe<Nfor; subframe++) {
@@ -206,27 +251,28 @@ static void Decode(
} }
/* backward prediction of subframes */ /* backward prediction of sub-frames */
Nback = start-1; Nback = start-1;
if( Nback > 0 ){ if ( Nback > 0 ) {
/* setup memory */ /* setup memory */
meml_gotten = SUBL*(NSUB+1-start); meml_gotten = SUBL*(iLBCdec_inst->nsub+1-start);
if ( meml_gotten > CB_MEML ) {
if( meml_gotten > CB_MEML ) {
meml_gotten=CB_MEML; meml_gotten=CB_MEML;
} }
for( k=0; k<meml_gotten; k++) { for (k=0; k<meml_gotten; k++) {
mem[CB_MEML-1-k] = decresidual[(start-1)*SUBL + k]; mem[CB_MEML-1-k] = decresidual[(start-1)*SUBL + k];
} }
memset(mem, 0, (CB_MEML-k)*sizeof(float)); memset(mem, 0, (CB_MEML-k)*sizeof(float));
/* loop over subframes to decode */ /* loop over subframes to decode */
for (subframe=0; subframe<Nback; subframe++) { for (subframe=0; subframe<Nback; subframe++) {
/* construct decoded vector */ /* construct decoded vector */
@@ -249,7 +295,7 @@ static void Decode(
/* get decoded residual from reversed vector */ /* get decoded residual from reversed vector */
for (i = 0; i < SUBL*Nback; i++) for (i=0; i<SUBL*Nback; i++)
decresidual[SUBL*Nback - i - 1] = decresidual[SUBL*Nback - i - 1] =
reverseDecresidual[i]; reverseDecresidual[i];
} }
@@ -267,24 +313,28 @@ void iLBC_decode(
int mode /* (i) 0: bad packet, PLC, int mode /* (i) 0: bad packet, PLC,
1: normal */ 1: normal */
){ ){
float data[BLOCKL]; float data[BLOCKL_MAX];
float lsfdeq[LPC_FILTERORDER*LPC_N]; float lsfdeq[LPC_FILTERORDER*LPC_N_MAX];
float PLCresidual[BLOCKL], PLClpc[LPC_FILTERORDER + 1]; float PLCresidual[BLOCKL_MAX], PLClpc[LPC_FILTERORDER + 1];
float zeros[BLOCKL], one[LPC_FILTERORDER + 1]; float zeros[BLOCKL_MAX], one[LPC_FILTERORDER + 1];
int k, i, start, idxForMax, pos, lastpart, ulp; int k, i, start, idxForMax, pos, lastpart, ulp;
int lag, ilag; int lag, ilag;
float cc, maxcc; float cc, maxcc;
int idxVec[STATE_LEN]; int idxVec[STATE_LEN];
int check; int check;
int gain_index[NASUB*CB_NSTAGES], extra_gain_index[CB_NSTAGES]; int gain_index[NASUB_MAX*CB_NSTAGES],
int cb_index[CB_NSTAGES*NASUB], extra_cb_index[CB_NSTAGES]; extra_gain_index[CB_NSTAGES];
int lsf_i[LSF_NSPLIT*LPC_N]; int cb_index[CB_NSTAGES*NASUB_MAX], extra_cb_index[CB_NSTAGES];
int lsf_i[LSF_NSPLIT*LPC_N_MAX];
int state_first; int state_first;
int last_bit;
unsigned char *pbytes; unsigned char *pbytes;
float weightdenum[(LPC_FILTERORDER + 1)*NSUB]; float weightdenum[(LPC_FILTERORDER + 1)*NSUB_MAX];
int order_plus_one; int order_plus_one;
float syntdenum[NSUB*(LPC_FILTERORDER+1)]; float syntdenum[NSUB_MAX*(LPC_FILTERORDER+1)];
float decresidual[BLOCKL]; float decresidual[BLOCKL_MAX];
if (mode>0) { /* the data are good */ if (mode>0) { /* the data are good */
@@ -295,27 +345,27 @@ void iLBC_decode(
/* Set everything to zero before decoding */ /* Set everything to zero before decoding */
for (k=0;k<6;k++) { for (k=0; k<LSF_NSPLIT*LPC_N_MAX; k++) {
lsf_i[k]=0; lsf_i[k]=0;
} }
start=0; start=0;
state_first=0; state_first=0;
idxForMax=0; idxForMax=0;
for (k=0; k<STATE_SHORT_LEN; k++) { for (k=0; k<iLBCdec_inst->state_short_len; k++) {
idxVec[k]=0; idxVec[k]=0;
} }
for (k=0;k<CB_NSTAGES;k++) { for (k=0; k<CB_NSTAGES; k++) {
extra_cb_index[k]=0; extra_cb_index[k]=0;
} }
for (k=0;k<CB_NSTAGES;k++) { for (k=0; k<CB_NSTAGES; k++) {
extra_gain_index[k]=0; extra_gain_index[k]=0;
} }
for (i=0; i<NASUB; i++) { for (i=0; i<iLBCdec_inst->nasub; i++) {
for (k=0; k<CB_NSTAGES; k++) { for (k=0; k<CB_NSTAGES; k++) {
cb_index[i*CB_NSTAGES+k]=0; cb_index[i*CB_NSTAGES+k]=0;
} }
} }
for (i=0; i<NASUB; i++) { for (i=0; i<iLBCdec_inst->nasub; i++) {
for (k=0; k<CB_NSTAGES; k++) { for (k=0; k<CB_NSTAGES; k++) {
gain_index[i*CB_NSTAGES+k]=0; gain_index[i*CB_NSTAGES+k]=0;
} }
@@ -326,75 +376,93 @@ void iLBC_decode(
for (ulp=0; ulp<3; ulp++) { for (ulp=0; ulp<3; ulp++) {
/* LSF */ /* LSF */
for (k=0;k<6;k++) { for (k=0; k<LSF_NSPLIT*iLBCdec_inst->lpc_n; k++){
unpack( &pbytes, &lastpart, unpack( &pbytes, &lastpart,
ulp_lsf_bitsTbl[k][ulp], &pos); iLBCdec_inst->ULP_inst->lsf_bits[k][ulp], &pos);
packcombine(&lsf_i[k], lastpart, packcombine(&lsf_i[k], lastpart,
ulp_lsf_bitsTbl[k][ulp]); iLBCdec_inst->ULP_inst->lsf_bits[k][ulp]);
} }
/* Start block info */ /* Start block info */
unpack( &pbytes, &lastpart, unpack( &pbytes, &lastpart,
ulp_start_bitsTbl[ulp], &pos); iLBCdec_inst->ULP_inst->start_bits[ulp], &pos);
packcombine(&start, lastpart, packcombine(&start, lastpart,
ulp_start_bitsTbl[ulp]); iLBCdec_inst->ULP_inst->start_bits[ulp]);
unpack( &pbytes, &lastpart, unpack( &pbytes, &lastpart,
ulp_startfirst_bitsTbl[ulp], &pos); iLBCdec_inst->ULP_inst->startfirst_bits[ulp], &pos);
packcombine(&state_first, lastpart, packcombine(&state_first, lastpart,
ulp_startfirst_bitsTbl[ulp]); iLBCdec_inst->ULP_inst->startfirst_bits[ulp]);
unpack( &pbytes, &lastpart, unpack( &pbytes, &lastpart,
ulp_scale_bitsTbl[ulp], &pos); iLBCdec_inst->ULP_inst->scale_bits[ulp], &pos);
packcombine(&idxForMax, lastpart, packcombine(&idxForMax, lastpart,
ulp_scale_bitsTbl[ulp]); iLBCdec_inst->ULP_inst->scale_bits[ulp]);
for (k=0; k<STATE_SHORT_LEN; k++) { for (k=0; k<iLBCdec_inst->state_short_len; k++) {
unpack( &pbytes, &lastpart, unpack( &pbytes, &lastpart,
ulp_state_bitsTbl[ulp], &pos); iLBCdec_inst->ULP_inst->state_bits[ulp], &pos);
packcombine(idxVec+k, lastpart, packcombine(idxVec+k, lastpart,
ulp_state_bitsTbl[ulp]); iLBCdec_inst->ULP_inst->state_bits[ulp]);
} }
/* 22 sample block */ /* 23/22 (20ms/30ms) sample block */
for (k=0;k<CB_NSTAGES;k++) { for (k=0; k<CB_NSTAGES; k++) {
unpack( &pbytes, &lastpart, unpack( &pbytes, &lastpart,
ulp_extra_cb_indexTbl[k][ulp], &pos); iLBCdec_inst->ULP_inst->extra_cb_index[k][ulp],
&pos);
packcombine(extra_cb_index+k, lastpart, packcombine(extra_cb_index+k, lastpart,
ulp_extra_cb_indexTbl[k][ulp]); iLBCdec_inst->ULP_inst->extra_cb_index[k][ulp]);
} }
for (k=0;k<CB_NSTAGES;k++) { for (k=0; k<CB_NSTAGES; k++) {
unpack( &pbytes, &lastpart, unpack( &pbytes, &lastpart,
ulp_extra_cb_gainTbl[k][ulp], &pos); iLBCdec_inst->ULP_inst->extra_cb_gain[k][ulp],
&pos);
packcombine(extra_gain_index+k, lastpart, packcombine(extra_gain_index+k, lastpart,
ulp_extra_cb_gainTbl[k][ulp]); iLBCdec_inst->ULP_inst->extra_cb_gain[k][ulp]);
} }
/* The four 40 sample sub blocks */ /* The two/four (20ms/30ms) 40 sample sub-blocks */
for (i=0; i<NASUB; i++) { for (i=0; i<iLBCdec_inst->nasub; i++) {
for (k=0; k<CB_NSTAGES; k++) { for (k=0; k<CB_NSTAGES; k++) {
unpack( &pbytes, &lastpart, unpack( &pbytes, &lastpart,
ulp_cb_indexTbl[i][k][ulp], &pos); iLBCdec_inst->ULP_inst->cb_index[i][k][ulp],
&pos);
packcombine(cb_index+i*CB_NSTAGES+k, lastpart, packcombine(cb_index+i*CB_NSTAGES+k, lastpart,
ulp_cb_indexTbl[i][k][ulp]); iLBCdec_inst->ULP_inst->cb_index[i][k][ulp]);
} }
} }
for (i=0; i<NASUB; i++) { for (i=0; i<iLBCdec_inst->nasub; i++) {
for (k=0; k<CB_NSTAGES; k++) { for (k=0; k<CB_NSTAGES; k++) {
unpack( &pbytes, &lastpart, unpack( &pbytes, &lastpart,
ulp_cb_gainTbl[i][k][ulp], &pos);
packcombine(gain_index+i*CB_NSTAGES+k, lastpart,
ulp_cb_gainTbl[i][k][ulp]);
}
}
}
/* Check for bit errors */ iLBCdec_inst->ULP_inst->cb_gain[i][k][ulp],
if( (start<1) || (start>5) ) &pos);
packcombine(gain_index+i*CB_NSTAGES+k, lastpart,
iLBCdec_inst->ULP_inst->cb_gain[i][k][ulp]);
}
}
}
/* Extract last bit. If it is 1 this indicates an
empty/lost frame */
unpack( &pbytes, &last_bit, 1, &pos);
/* Check for bit errors or empty/lost frames */
if (start<1)
mode = 0;
if (iLBCdec_inst->mode==20 && start>3)
mode = 0;
if (iLBCdec_inst->mode==30 && start>5)
mode = 0;
if (last_bit==1)
mode = 0; mode = 0;
if (mode==1) { /* No bit errors was detected, if (mode==1) { /* No bit errors was detected,
@@ -405,36 +473,41 @@ void iLBC_decode(
/* decode the lsf */ /* decode the lsf */
SimplelsfDEQ(lsfdeq, lsf_i); SimplelsfDEQ(lsfdeq, lsf_i, iLBCdec_inst->lpc_n);
check=LSF_check(lsfdeq, LPC_FILTERORDER, LPC_N); check=LSF_check(lsfdeq, LPC_FILTERORDER,
iLBCdec_inst->lpc_n);
DecoderInterpolateLSF(syntdenum, weightdenum, DecoderInterpolateLSF(syntdenum, weightdenum,
lsfdeq, LPC_FILTERORDER, iLBCdec_inst); lsfdeq, LPC_FILTERORDER, iLBCdec_inst);
Decode(decresidual, start, idxForMax, idxVec, Decode(iLBCdec_inst, decresidual, start, idxForMax,
syntdenum, cb_index, gain_index, idxVec, syntdenum, cb_index, gain_index,
extra_cb_index, extra_gain_index, extra_cb_index, extra_gain_index,
state_first); state_first);
/* preparing the plc for a future loss! */ /* preparing the plc for a future loss! */
doThePLC(PLCresidual, PLClpc, 0, decresidual, doThePLC(PLCresidual, PLClpc, 0, decresidual,
syntdenum + (LPC_FILTERORDER + 1)*(NSUB - 1), syntdenum +
(LPC_FILTERORDER + 1)*(iLBCdec_inst->nsub - 1),
(*iLBCdec_inst).last_lag, iLBCdec_inst); (*iLBCdec_inst).last_lag, iLBCdec_inst);
memcpy(decresidual, PLCresidual, BLOCKL*sizeof(float)); memcpy(decresidual, PLCresidual,
iLBCdec_inst->blockl*sizeof(float));
} }
} }
if (mode == 0) { if (mode == 0) {
/* the data is bad (either a PLC call /* the data is bad (either a PLC call
* was made or a bit error was detected) * was made or a severe bit error was detected)
*/ */
/* packet loss conceal */ /* packet loss conceal */
memset(zeros, 0, BLOCKL*sizeof(float)); memset(zeros, 0, BLOCKL_MAX*sizeof(float));
one[0] = 1; one[0] = 1;
memset(one+1, 0, LPC_FILTERORDER*sizeof(float)); memset(one+1, 0, LPC_FILTERORDER*sizeof(float));
@@ -443,75 +516,100 @@ void iLBC_decode(
doThePLC(PLCresidual, PLClpc, 1, zeros, one, doThePLC(PLCresidual, PLClpc, 1, zeros, one,
(*iLBCdec_inst).last_lag, iLBCdec_inst); (*iLBCdec_inst).last_lag, iLBCdec_inst);
memcpy(decresidual, PLCresidual, BLOCKL*sizeof(float)); memcpy(decresidual, PLCresidual,
iLBCdec_inst->blockl*sizeof(float));
order_plus_one = LPC_FILTERORDER + 1; order_plus_one = LPC_FILTERORDER + 1;
for (i = 0; i < NSUB; i++) { for (i = 0; i < iLBCdec_inst->nsub; i++) {
memcpy(syntdenum+(i*order_plus_one), PLClpc, memcpy(syntdenum+(i*order_plus_one), PLClpc,
order_plus_one*sizeof(float)); order_plus_one*sizeof(float));
} }
} }
if ((*iLBCdec_inst).use_enhancer == 1) { if (iLBCdec_inst->use_enhancer == 1) {
/* post filtering */ /* post filtering */
(*iLBCdec_inst).last_lag = iLBCdec_inst->last_lag =
enhancerInterface(data, decresidual, iLBCdec_inst); enhancerInterface(data, decresidual, iLBCdec_inst);
/* synthesis filtering */ /* synthesis filtering */
if (iLBCdec_inst->mode==20) {
/* Enhancer has 40 samples delay */
i=0;
syntFilter(data + i*SUBL,
iLBCdec_inst->old_syntdenum +
(i+iLBCdec_inst->nsub-1)*(LPC_FILTERORDER+1),
SUBL, iLBCdec_inst->syntMem);
for (i=1; i < iLBCdec_inst->nsub; i++) {
syntFilter(data + i*SUBL,
syntdenum + (i-1)*(LPC_FILTERORDER+1),
SUBL, iLBCdec_inst->syntMem);
}
} else if (iLBCdec_inst->mode==30) {
/* Enhancer has 80 samples delay */
for (i=0; i < 2; i++) { for (i=0; i < 2; i++) {
syntFilter(data + i*SUBL, syntFilter(data + i*SUBL,
(*iLBCdec_inst).old_syntdenum +
(i+4)*(LPC_FILTERORDER+1), SUBL,
(*iLBCdec_inst).syntMem); iLBCdec_inst->old_syntdenum +
(i+iLBCdec_inst->nsub-2)*(LPC_FILTERORDER+1),
SUBL, iLBCdec_inst->syntMem);
} }
for (i=2; i < NSUB; i++) { for (i=2; i < iLBCdec_inst->nsub; i++) {
syntFilter(data + i*SUBL, syntFilter(data + i*SUBL,
syntdenum + (i-2)*(LPC_FILTERORDER+1), SUBL, syntdenum + (i-2)*(LPC_FILTERORDER+1), SUBL,
(*iLBCdec_inst).syntMem); iLBCdec_inst->syntMem);
}
} }
} else { } else {
/* Find last lag */ /* Find last lag */
lag = 20; lag = 20;
maxcc = xCorrCoef(&decresidual[BLOCKL-ENH_BLOCKL], maxcc = xCorrCoef(&decresidual[BLOCKL_MAX-ENH_BLOCKL],
&decresidual[BLOCKL-ENH_BLOCKL-lag], ENH_BLOCKL); &decresidual[BLOCKL_MAX-ENH_BLOCKL-lag], ENH_BLOCKL);
for (ilag=21; ilag<120; ilag++) { for (ilag=21; ilag<120; ilag++) {
cc = xCorrCoef(&decresidual[BLOCKL-ENH_BLOCKL], cc = xCorrCoef(&decresidual[BLOCKL_MAX-ENH_BLOCKL],
&decresidual[BLOCKL-ENH_BLOCKL-ilag], ENH_BLOCKL); &decresidual[BLOCKL_MAX-ENH_BLOCKL-ilag],
ENH_BLOCKL);
if (cc > maxcc) { if (cc > maxcc) {
maxcc = cc; maxcc = cc;
lag = ilag; lag = ilag;
} }
} }
(*iLBCdec_inst).last_lag = lag; iLBCdec_inst->last_lag = lag;
/* copy data and run synthesis filter */ /* copy data and run synthesis filter */
memcpy(data, decresidual, BLOCKL*sizeof(float)); memcpy(data, decresidual,
for (i=0; i < NSUB; i++) { iLBCdec_inst->blockl*sizeof(float));
for (i=0; i < iLBCdec_inst->nsub; i++) {
syntFilter(data + i*SUBL, syntFilter(data + i*SUBL,
syntdenum + i*(LPC_FILTERORDER+1), SUBL, syntdenum + i*(LPC_FILTERORDER+1), SUBL,
(*iLBCdec_inst).syntMem); iLBCdec_inst->syntMem);
} }
} }
/* high pass filtering on output if desired, otherwise /* high pass filtering on output if desired, otherwise
copy to out */ copy to out */
/*hpOutput(data, BLOCKL, decblock, (*iLBCdec_inst).hpomem);*/ hpOutput(data, iLBCdec_inst->blockl,
memcpy(decblock,data,BLOCKL*sizeof(float)); decblock,iLBCdec_inst->hpomem);
memcpy((*iLBCdec_inst).old_syntdenum, syntdenum, /* memcpy(decblock,data,iLBCdec_inst->blockl*sizeof(float));*/
NSUB*(LPC_FILTERORDER+1)*sizeof(float));
memcpy(iLBCdec_inst->old_syntdenum, syntdenum,
iLBCdec_inst->nsub*(LPC_FILTERORDER+1)*sizeof(float));
iLBCdec_inst->prev_enh_pl=0; iLBCdec_inst->prev_enh_pl=0;
if (mode==0) { /* PLC was used */ if (mode==0) { /* PLC was used */
iLBCdec_inst->prev_enh_pl=1; iLBCdec_inst->prev_enh_pl=1;
} }

View File

@@ -5,9 +5,8 @@
iLBC_decode.h iLBC_decode.h
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/ ******************************************************************/
@@ -19,6 +18,7 @@
short initDecode( /* (o) Number of decoded short initDecode( /* (o) Number of decoded
samples */ samples */
iLBC_Dec_Inst_t *iLBCdec_inst, /* (i/o) Decoder instance */ iLBC_Dec_Inst_t *iLBCdec_inst, /* (i/o) Decoder instance */
int mode, /* (i) frame size mode */
int use_enhancer /* (i) 1 to use enhancer int use_enhancer /* (i) 1 to use enhancer
0 to run without 0 to run without
enhancer */ enhancer */
@@ -33,6 +33,8 @@ void iLBC_decode(
1: normal */ 1: normal */
); );
#endif #endif

View File

@@ -5,9 +5,8 @@
iLBC_define.h iLBC_define.h
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/ ******************************************************************/
#include <string.h> #include <string.h>
@@ -18,12 +17,19 @@
/* general codec settings */ /* general codec settings */
#define FS (float)8000.0 #define FS (float)8000.0
#define BLOCKL 240 #define BLOCKL_20MS 160
#define NSUB 6 #define BLOCKL_30MS 240
#define NASUB 4 #define BLOCKL_MAX 240
#define NSUB_20MS 4
#define NSUB_30MS 6
#define NSUB_MAX 6
#define NASUB_20MS 2
#define NASUB_30MS 4
#define NASUB_MAX 4
#define SUBL 40 #define SUBL 40
#define STATE_LEN 80 #define STATE_LEN 80
#define STATE_SHORT_LEN 58 #define STATE_SHORT_LEN_30MS 58
#define STATE_SHORT_LEN_20MS 57
/* LPC settings */ /* LPC settings */
@@ -31,13 +37,16 @@
#define LPC_CHIRP_SYNTDENUM (float)0.9025 #define LPC_CHIRP_SYNTDENUM (float)0.9025
#define LPC_CHIRP_WEIGHTDENUM (float)0.4222 #define LPC_CHIRP_WEIGHTDENUM (float)0.4222
#define LPC_LOOKBACK 60 #define LPC_LOOKBACK 60
#define LPC_N 2 #define LPC_N_20MS 1
#define LPC_N_30MS 2
#define LPC_N_MAX 2
#define LPC_ASYMDIFF 20 #define LPC_ASYMDIFF 20
#define LPC_BW (float)60.0 #define LPC_BW (float)60.0
#define LPC_WN (float)1.0001 #define LPC_WN (float)1.0001
#define LSF_NSPLIT 3 #define LSF_NSPLIT 3
#define LSF_NUMBER_OF_STEPS 4 #define LSF_NUMBER_OF_STEPS 4
#define LPC_HALFORDER LPC_FILTERORDER/2 #define LPC_HALFORDER (LPC_FILTERORDER/2)
/* cb settings */ /* cb settings */
@@ -47,7 +56,7 @@
#define CB_FILTERLEN 2*4 #define CB_FILTERLEN 2*4
#define CB_HALFFILTERLEN 4 #define CB_HALFFILTERLEN 4
#define CB_RESRANGE 34 #define CB_RESRANGE 34
#define CB_MAXGAIN (float) 1.3 #define CB_MAXGAIN (float)1.3
/* enhancer */ /* enhancer */
@@ -57,29 +66,21 @@
in said second sequence */ in said second sequence */
#define ENH_SLOP 2 /* max difference estimated and #define ENH_SLOP 2 /* max difference estimated and
correct pitch period */ correct pitch period */
#define ENH_PLOCSL 20 /* pitch-estimates and #define ENH_PLOCSL 20 /* pitch-estimates and pitch-
pitch-locations buffer length */ locations buffer length */
#define ENH_OVERHANG 2 #define ENH_OVERHANG 2
#define ENH_UPS0 4 /* upsampling rate */ #define ENH_UPS0 4 /* upsampling rate */
#define ENH_FL0 3 /* 2*FLO+1 is the length of each filter */ #define ENH_FL0 3 /* 2*FLO+1 is the length of
each filter */
#define ENH_VECTL (ENH_BLOCKL+2*ENH_FL0) #define ENH_VECTL (ENH_BLOCKL+2*ENH_FL0)
#define ENH_CORRDIM (2*ENH_SLOP+1) #define ENH_CORRDIM (2*ENH_SLOP+1)
#define ENH_NBLOCKS (BLOCKL/ENH_BLOCKL) #define ENH_NBLOCKS (BLOCKL_MAX/ENH_BLOCKL)
#define ENH_NBLOCKS_EXTRA 5 #define ENH_NBLOCKS_EXTRA 5
#define ENH_NBLOCKS_TOT 8 /* ENH_NBLOCKS+ENH_NBLOCKS_EXTRA */ #define ENH_NBLOCKS_TOT 8 /* ENH_NBLOCKS +
ENH_NBLOCKS_EXTRA */
#define ENH_BUFL (ENH_NBLOCKS_TOT)*ENH_BLOCKL #define ENH_BUFL (ENH_NBLOCKS_TOT)*ENH_BLOCKL
#define ENH_ALPHA0 (float)0.05 #define ENH_ALPHA0 (float)0.05
/* PLC */
#define PLC_BFIATTENUATE (float)0.9
#define PLC_GAINTHRESHOLD (float)0.5
#define PLC_BWEXPAND (float)0.99
#define PLC_XT_MIX (float)1.0
#define PLC_XB_MIX (float)0.0
#define PLC_YT_MIX (float)0.95
#define PLC_YB_MIX (float)0.0
/* Down sampling */ /* Down sampling */
#define FILTERORDER_DS 7 #define FILTERORDER_DS 7
@@ -88,13 +89,17 @@
/* bit stream defs */ /* bit stream defs */
#define NO_OF_BYTES 50 #define NO_OF_BYTES_20MS 38
#define NO_OF_BYTES_30MS 50
#define NO_OF_WORDS_20MS 19
#define NO_OF_WORDS_30MS 25
#define STATE_BITS 3 #define STATE_BITS 3
#define BYTE_LEN 8 #define BYTE_LEN 8
#define ULP_CLASSES 3 #define ULP_CLASSES 3
/* help parameters */ /* help parameters */
#define FLOAT_MAX (float)1.0e37 #define FLOAT_MAX (float)1.0e37
#define EPS (float)2.220446049250313e-016 #define EPS (float)2.220446049250313e-016
#define PI (float)3.14159265358979323846 #define PI (float)3.14159265358979323846
@@ -103,9 +108,34 @@
#define TWO_PI (float)6.283185307 #define TWO_PI (float)6.283185307
#define PI2 (float)0.159154943 #define PI2 (float)0.159154943
/* type definition encoder instance */
typedef struct iLBC_ULP_Inst_t_ {
int lsf_bits[6][ULP_CLASSES+2];
int start_bits[ULP_CLASSES+2];
int startfirst_bits[ULP_CLASSES+2];
int scale_bits[ULP_CLASSES+2];
int state_bits[ULP_CLASSES+2];
int extra_cb_index[CB_NSTAGES][ULP_CLASSES+2];
int extra_cb_gain[CB_NSTAGES][ULP_CLASSES+2];
int cb_index[NSUB_MAX][CB_NSTAGES][ULP_CLASSES+2];
int cb_gain[NSUB_MAX][CB_NSTAGES][ULP_CLASSES+2];
} iLBC_ULP_Inst_t;
/* type definition encoder instance */ /* type definition encoder instance */
typedef struct iLBC_Enc_Inst_t_ { typedef struct iLBC_Enc_Inst_t_ {
/* flag for frame size mode */
int mode;
/* basic parameters for different frame sizes */
int blockl;
int nsub;
int nasub;
int no_of_bytes, no_of_words;
int lpc_n;
int state_short_len;
const iLBC_ULP_Inst_t *ULP_inst;
/* analysis filter state */ /* analysis filter state */
float anaMem[LPC_FILTERORDER]; float anaMem[LPC_FILTERORDER];
@@ -114,7 +144,7 @@ typedef struct iLBC_Enc_Inst_t_ {
float lsfdeqold[LPC_FILTERORDER]; float lsfdeqold[LPC_FILTERORDER];
/* signal buffer for LP analysis */ /* signal buffer for LP analysis */
float lpc_buffer[LPC_LOOKBACK + BLOCKL]; float lpc_buffer[LPC_LOOKBACK + BLOCKL_MAX];
/* state of input HP filter */ /* state of input HP filter */
float hpimem[4]; float hpimem[4];
@@ -123,6 +153,20 @@ typedef struct iLBC_Enc_Inst_t_ {
/* type definition decoder instance */ /* type definition decoder instance */
typedef struct iLBC_Dec_Inst_t_ { typedef struct iLBC_Dec_Inst_t_ {
/* flag for frame size mode */
int mode;
/* basic parameters for different frame sizes */
int blockl;
int nsub;
int nasub;
int no_of_bytes, no_of_words;
int lpc_n;
int state_short_len;
const iLBC_ULP_Inst_t *ULP_inst;
/* synthesis filter state */ /* synthesis filter state */
float syntMem[LPC_FILTERORDER]; float syntMem[LPC_FILTERORDER];
@@ -134,13 +178,13 @@ typedef struct iLBC_Dec_Inst_t_ {
/* PLC state information */ /* PLC state information */
int prevLag, consPLICount, prevPLI, prev_enh_pl; int prevLag, consPLICount, prevPLI, prev_enh_pl;
float prevGain, prevLpc[LPC_FILTERORDER+1]; float prevLpc[LPC_FILTERORDER+1];
float prevResidual[NSUB*SUBL]; float prevResidual[NSUB_MAX*SUBL];
float energy; float per;
unsigned long seed; unsigned long seed;
/* previous synthesis filter parameters */ /* previous synthesis filter parameters */
float old_syntdenum[(LPC_FILTERORDER + 1)*NSUB]; float old_syntdenum[(LPC_FILTERORDER + 1)*NSUB_MAX];
/* state of output HP filter */ /* state of output HP filter */
float hpomem[4]; float hpomem[4];

View File

@@ -5,13 +5,13 @@
iLBC_encode.c iLBC_encode.c
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/ ******************************************************************/
#include <math.h> #include <math.h>
#include <stdlib.h>
#include <string.h> #include <string.h>
#include "iLBC_define.h" #include "iLBC_define.h"
@@ -22,7 +22,6 @@
#include "helpfun.h" #include "helpfun.h"
#include "constants.h" #include "constants.h"
#include "packing.h" #include "packing.h"
#include "iLBC_encode.h"
#include "iCBSearch.h" #include "iCBSearch.h"
#include "iCBConstruct.h" #include "iCBConstruct.h"
#include "hpInput.h" #include "hpInput.h"
@@ -33,9 +32,40 @@
* Initiation of encoder instance. * Initiation of encoder instance.
*---------------------------------------------------------------*/ *---------------------------------------------------------------*/
short initEncode( /* (o) Number of bytes encoded */ short initEncode( /* (o) Number of bytes
iLBC_Enc_Inst_t *iLBCenc_inst /* (i/o) Encoder instance */ encoded */
iLBC_Enc_Inst_t *iLBCenc_inst, /* (i/o) Encoder instance */
int mode /* (i) frame size mode */
){ ){
iLBCenc_inst->mode = mode;
if (mode==30) {
iLBCenc_inst->blockl = BLOCKL_30MS;
iLBCenc_inst->nsub = NSUB_30MS;
iLBCenc_inst->nasub = NASUB_30MS;
iLBCenc_inst->lpc_n = LPC_N_30MS;
iLBCenc_inst->no_of_bytes = NO_OF_BYTES_30MS;
iLBCenc_inst->no_of_words = NO_OF_WORDS_30MS;
iLBCenc_inst->state_short_len=STATE_SHORT_LEN_30MS;
/* ULP init */
iLBCenc_inst->ULP_inst=&ULP_30msTbl;
}
else if (mode==20) {
iLBCenc_inst->blockl = BLOCKL_20MS;
iLBCenc_inst->nsub = NSUB_20MS;
iLBCenc_inst->nasub = NASUB_20MS;
iLBCenc_inst->lpc_n = LPC_N_20MS;
iLBCenc_inst->no_of_bytes = NO_OF_BYTES_20MS;
iLBCenc_inst->no_of_words = NO_OF_WORDS_20MS;
iLBCenc_inst->state_short_len=STATE_SHORT_LEN_20MS;
/* ULP init */
iLBCenc_inst->ULP_inst=&ULP_20msTbl;
}
else {
exit(2);
}
memset((*iLBCenc_inst).anaMem, 0, memset((*iLBCenc_inst).anaMem, 0,
LPC_FILTERORDER*sizeof(float)); LPC_FILTERORDER*sizeof(float));
memcpy((*iLBCenc_inst).lsfold, lsfmeanTbl, memcpy((*iLBCenc_inst).lsfold, lsfmeanTbl,
@@ -43,10 +73,10 @@ short initEncode( /* (o) Number of bytes encoded */
memcpy((*iLBCenc_inst).lsfdeqold, lsfmeanTbl, memcpy((*iLBCenc_inst).lsfdeqold, lsfmeanTbl,
LPC_FILTERORDER*sizeof(float)); LPC_FILTERORDER*sizeof(float));
memset((*iLBCenc_inst).lpc_buffer, 0, memset((*iLBCenc_inst).lpc_buffer, 0,
LPC_LOOKBACK*sizeof(float)); (LPC_LOOKBACK+BLOCKL_MAX)*sizeof(float));
memset((*iLBCenc_inst).hpimem, 0, 4*sizeof(float)); memset((*iLBCenc_inst).hpimem, 0, 4*sizeof(float));
return (NO_OF_BYTES); return (iLBCenc_inst->no_of_bytes);
} }
/*----------------------------------------------------------------* /*----------------------------------------------------------------*
@@ -55,71 +85,78 @@ short initEncode( /* (o) Number of bytes encoded */
void iLBC_encode( void iLBC_encode(
unsigned char *bytes, /* (o) encoded data bits iLBC */ unsigned char *bytes, /* (o) encoded data bits iLBC */
float *block, /* (o) speech vector to encode */ float *block, /* (o) speech vector to
encode */
iLBC_Enc_Inst_t *iLBCenc_inst /* (i/o) the general encoder iLBC_Enc_Inst_t *iLBCenc_inst /* (i/o) the general encoder
state */ state */
){ ){
float data[BLOCKL]; float data[BLOCKL_MAX];
float residual[BLOCKL], reverseResidual[BLOCKL]; float residual[BLOCKL_MAX], reverseResidual[BLOCKL_MAX];
int start, idxForMax, idxVec[STATE_LEN]; int start, idxForMax, idxVec[STATE_LEN];
float reverseDecresidual[BLOCKL], mem[CB_MEML]; float reverseDecresidual[BLOCKL_MAX], mem[CB_MEML];
int n, k, meml_gotten, Nfor, Nback, i, pos; int n, k, meml_gotten, Nfor, Nback, i, pos;
int gain_index[CB_NSTAGES*NASUB], extra_gain_index[CB_NSTAGES];
int cb_index[CB_NSTAGES*NASUB],extra_cb_index[CB_NSTAGES];
int lsf_i[LSF_NSPLIT*LPC_N]; int gain_index[CB_NSTAGES*NASUB_MAX],
extra_gain_index[CB_NSTAGES];
int cb_index[CB_NSTAGES*NASUB_MAX],extra_cb_index[CB_NSTAGES];
int lsf_i[LSF_NSPLIT*LPC_N_MAX];
unsigned char *pbytes; unsigned char *pbytes;
int diff, start_pos, state_first; int diff, start_pos, state_first;
float en1, en2; float en1, en2;
int index, ulp, firstpart; int index, ulp, firstpart;
int subcount, subframe; int subcount, subframe;
float weightState[LPC_FILTERORDER]; float weightState[LPC_FILTERORDER];
float syntdenum[NSUB*(LPC_FILTERORDER+1)]; float syntdenum[NSUB_MAX*(LPC_FILTERORDER+1)];
float weightdenum[NSUB*(LPC_FILTERORDER+1)]; float weightdenum[NSUB_MAX*(LPC_FILTERORDER+1)];
float decresidual[BLOCKL]; float decresidual[BLOCKL_MAX];
/* high pass filtering of input signal if such is not done /* high pass filtering of input signal if such is not done
prior to calling this function */ prior to calling this function */
/*hpInput(block, BLOCKL, data, (*iLBCenc_inst).hpimem);*/ hpInput(block, iLBCenc_inst->blockl,
data, (*iLBCenc_inst).hpimem);
/* otherwise simply copy */ /* otherwise simply copy */
memcpy(data,block,BLOCKL*sizeof(float)); /*memcpy(data,block,iLBCenc_inst->blockl*sizeof(float));*/
/* LPC of hp filtered input data */ /* LPC of hp filtered input data */
LPCencode(syntdenum, weightdenum, lsf_i, data, LPCencode(syntdenum, weightdenum, lsf_i, data, iLBCenc_inst);
iLBCenc_inst);
/* inverse filter to get residual */ /* inverse filter to get residual */
for (n=0; n<NSUB; n++ ) { for (n=0; n<iLBCenc_inst->nsub; n++) {
anaFilter(&data[n*SUBL], &syntdenum[n*(LPC_FILTERORDER+1)], anaFilter(&data[n*SUBL], &syntdenum[n*(LPC_FILTERORDER+1)],
SUBL, &residual[n*SUBL], (*iLBCenc_inst).anaMem); SUBL, &residual[n*SUBL], iLBCenc_inst->anaMem);
} }
/* find state location */ /* find state location */
start = FrameClassify(residual); start = FrameClassify(iLBCenc_inst, residual);
/* check if state should be in first or last part of the /* check if state should be in first or last part of the
two subframes */ two subframes */
diff = STATE_LEN - STATE_SHORT_LEN; diff = STATE_LEN - iLBCenc_inst->state_short_len;
en1 = 0; en1 = 0;
index = (start-1)*SUBL; index = (start-1)*SUBL;
for (i = 0; i < STATE_SHORT_LEN; i++) { for (i = 0; i < iLBCenc_inst->state_short_len; i++) {
en1 += residual[index+i]*residual[index+i]; en1 += residual[index+i]*residual[index+i];
} }
en2 = 0; en2 = 0;
index = (start-1)*SUBL+diff; index = (start-1)*SUBL+diff;
for (i = 0; i < STATE_SHORT_LEN; i++) { for (i = 0; i < iLBCenc_inst->state_short_len; i++) {
en2 += residual[index+i]*residual[index+i]; en2 += residual[index+i]*residual[index+i];
} }
if (en1 > en2) { if (en1 > en2) {
state_first = 1; state_first = 1;
start_pos = (start-1)*SUBL; start_pos = (start-1)*SUBL;
@@ -130,14 +167,14 @@ void iLBC_encode(
/* scalar quantization of state */ /* scalar quantization of state */
StateSearchW(&residual[start_pos], StateSearchW(iLBCenc_inst, &residual[start_pos],
&syntdenum[(start-1)*(LPC_FILTERORDER+1)], &syntdenum[(start-1)*(LPC_FILTERORDER+1)],
&weightdenum[(start-1)*(LPC_FILTERORDER+1)], &idxForMax, &weightdenum[(start-1)*(LPC_FILTERORDER+1)], &idxForMax,
idxVec, STATE_SHORT_LEN, state_first); idxVec, iLBCenc_inst->state_short_len, state_first);
StateConstructW(idxForMax, idxVec, StateConstructW(idxForMax, idxVec,
&syntdenum[(start-1)*(LPC_FILTERORDER+1)], &syntdenum[(start-1)*(LPC_FILTERORDER+1)],
&decresidual[start_pos], STATE_SHORT_LEN); &decresidual[start_pos], iLBCenc_inst->state_short_len);
/* predictive quantization in state */ /* predictive quantization in state */
@@ -145,74 +182,82 @@ void iLBC_encode(
/* setup memory */ /* setup memory */
memset(mem, 0, (CB_MEML-STATE_SHORT_LEN)*sizeof(float)); memset(mem, 0,
memcpy(mem+CB_MEML-STATE_SHORT_LEN, decresidual+start_pos, (CB_MEML-iLBCenc_inst->state_short_len)*sizeof(float));
STATE_SHORT_LEN*sizeof(float)); memcpy(mem+CB_MEML-iLBCenc_inst->state_short_len,
decresidual+start_pos,
iLBCenc_inst->state_short_len*sizeof(float));
memset(weightState, 0, LPC_FILTERORDER*sizeof(float)); memset(weightState, 0, LPC_FILTERORDER*sizeof(float));
/* encode subframes */ /* encode sub-frames */
iCBSearch(extra_cb_index, extra_gain_index, iCBSearch(iLBCenc_inst, extra_cb_index, extra_gain_index,
&residual[start_pos+STATE_SHORT_LEN], &residual[start_pos+iLBCenc_inst->state_short_len],
mem+CB_MEML-stMemLTbl, mem+CB_MEML-stMemLTbl,
stMemLTbl, diff, CB_NSTAGES, stMemLTbl, diff, CB_NSTAGES,
&weightdenum[start*(LPC_FILTERORDER+1)], weightState, 0); &weightdenum[start*(LPC_FILTERORDER+1)],
weightState, 0);
/* construct decoded vector */ /* construct decoded vector */
iCBConstruct(&decresidual[start_pos+STATE_SHORT_LEN], iCBConstruct(
extra_cb_index, extra_gain_index, mem+CB_MEML-stMemLTbl, &decresidual[start_pos+iLBCenc_inst->state_short_len],
extra_cb_index, extra_gain_index,
mem+CB_MEML-stMemLTbl,
stMemLTbl, diff, CB_NSTAGES); stMemLTbl, diff, CB_NSTAGES);
} }
else { /* put adaptive part in the beginning */ else { /* put adaptive part in the beginning */
/* create reversed vectors for prediction */ /* create reversed vectors for prediction */
for(k=0; k<diff; k++ ){ for (k=0; k<diff; k++) {
reverseResidual[k] = residual[(start+1)*SUBL -1 reverseResidual[k] = residual[(start+1)*SUBL-1
-(k+STATE_SHORT_LEN)]; -(k+iLBCenc_inst->state_short_len)];
} }
/* setup memory */ /* setup memory */
meml_gotten = STATE_SHORT_LEN; meml_gotten = iLBCenc_inst->state_short_len;
for( k=0; k<meml_gotten; k++){ for (k=0; k<meml_gotten; k++) {
mem[CB_MEML-1-k] = decresidual[start_pos + k]; mem[CB_MEML-1-k] = decresidual[start_pos + k];
} }
memset(mem, 0, (CB_MEML-k)*sizeof(float)); memset(mem, 0, (CB_MEML-k)*sizeof(float));
memset(weightState, 0, LPC_FILTERORDER*sizeof(float)); memset(weightState, 0, LPC_FILTERORDER*sizeof(float));
/* encode subframes */ /* encode sub-frames */
iCBSearch(extra_cb_index, extra_gain_index, iCBSearch(iLBCenc_inst, extra_cb_index, extra_gain_index,
reverseResidual, mem+CB_MEML-stMemLTbl, stMemLTbl, diff, reverseResidual, mem+CB_MEML-stMemLTbl, stMemLTbl,
CB_NSTAGES, &weightdenum[(start-1)*(LPC_FILTERORDER+1)], diff, CB_NSTAGES,
&weightdenum[(start-1)*(LPC_FILTERORDER+1)],
weightState, 0); weightState, 0);
/* construct decoded vector */ /* construct decoded vector */
iCBConstruct(reverseDecresidual, extra_cb_index, iCBConstruct(reverseDecresidual, extra_cb_index,
extra_gain_index, mem+CB_MEML-stMemLTbl, stMemLTbl, diff, extra_gain_index, mem+CB_MEML-stMemLTbl, stMemLTbl,
CB_NSTAGES); diff, CB_NSTAGES);
/* get decoded residual from reversed vector */ /* get decoded residual from reversed vector */
for( k=0; k<diff; k++ ){ for (k=0; k<diff; k++) {
decresidual[start_pos-1-k] = reverseDecresidual[k]; decresidual[start_pos-1-k] = reverseDecresidual[k];
} }
} }
/* counter for predicted subframes */ /* counter for predicted sub-frames */
subcount=0; subcount=0;
/* forward prediction of subframes */ /* forward prediction of sub-frames */
Nfor = NSUB-start-1; Nfor = iLBCenc_inst->nsub-start-1;
if( Nfor > 0 ){ if ( Nfor > 0 ) {
/* setup memory */ /* setup memory */
@@ -221,18 +266,21 @@ void iLBC_encode(
STATE_LEN*sizeof(float)); STATE_LEN*sizeof(float));
memset(weightState, 0, LPC_FILTERORDER*sizeof(float)); memset(weightState, 0, LPC_FILTERORDER*sizeof(float));
/* loop over subframes to encode */
/* loop over sub-frames to encode */
for (subframe=0; subframe<Nfor; subframe++) { for (subframe=0; subframe<Nfor; subframe++) {
/* encode subframe */ /* encode sub-frame */
iCBSearch(cb_index+subcount*CB_NSTAGES, iCBSearch(iLBCenc_inst, cb_index+subcount*CB_NSTAGES,
gain_index+subcount*CB_NSTAGES, gain_index+subcount*CB_NSTAGES,
&residual[(start+1+subframe)*SUBL], &residual[(start+1+subframe)*SUBL],
mem+CB_MEML-memLfTbl[subcount], memLfTbl[subcount], mem+CB_MEML-memLfTbl[subcount],
SUBL, CB_NSTAGES, memLfTbl[subcount], SUBL, CB_NSTAGES,
&weightdenum[(start+1+subframe)*(LPC_FILTERORDER+1)], &weightdenum[(start+1+subframe)*
(LPC_FILTERORDER+1)],
weightState, subcount+1); weightState, subcount+1);
/* construct decoded vector */ /* construct decoded vector */
@@ -240,8 +288,8 @@ void iLBC_encode(
iCBConstruct(&decresidual[(start+1+subframe)*SUBL], iCBConstruct(&decresidual[(start+1+subframe)*SUBL],
cb_index+subcount*CB_NSTAGES, cb_index+subcount*CB_NSTAGES,
gain_index+subcount*CB_NSTAGES, gain_index+subcount*CB_NSTAGES,
mem+CB_MEML-memLfTbl[subcount], memLfTbl[subcount], mem+CB_MEML-memLfTbl[subcount],
SUBL, CB_NSTAGES); memLfTbl[subcount], SUBL, CB_NSTAGES);
/* update memory */ /* update memory */
@@ -256,17 +304,17 @@ void iLBC_encode(
} }
/* backward prediction of subframes */ /* backward prediction of sub-frames */
Nback = start-1; Nback = start-1;
if( Nback > 0 ){ if ( Nback > 0 ) {
/* create reverse order vectors */ /* create reverse order vectors */
for( n=0; n<Nback; n++ ){ for (n=0; n<Nback; n++) {
for( k=0; k<SUBL; k++ ){ for (k=0; k<SUBL; k++) {
reverseResidual[n*SUBL+k] = reverseResidual[n*SUBL+k] =
residual[(start-1)*SUBL-1-n*SUBL-k]; residual[(start-1)*SUBL-1-n*SUBL-k];
reverseDecresidual[n*SUBL+k] = reverseDecresidual[n*SUBL+k] =
@@ -274,32 +322,35 @@ void iLBC_encode(
} }
} }
/* setup memory */ /* setup memory */
meml_gotten = SUBL*(NSUB+1-start); meml_gotten = SUBL*(iLBCenc_inst->nsub+1-start);
if( meml_gotten > CB_MEML ) { if ( meml_gotten > CB_MEML ) {
meml_gotten=CB_MEML; meml_gotten=CB_MEML;
} }
for( k=0; k<meml_gotten; k++) { for (k=0; k<meml_gotten; k++) {
mem[CB_MEML-1-k] = decresidual[(start-1)*SUBL + k]; mem[CB_MEML-1-k] = decresidual[(start-1)*SUBL + k];
} }
memset(mem, 0, (CB_MEML-k)*sizeof(float)); memset(mem, 0, (CB_MEML-k)*sizeof(float));
memset(weightState, 0, LPC_FILTERORDER*sizeof(float)); memset(weightState, 0, LPC_FILTERORDER*sizeof(float));
/* loop over subframes to encode */ /* loop over sub-frames to encode */
for (subframe=0; subframe<Nback; subframe++) { for (subframe=0; subframe<Nback; subframe++) {
/* encode subframe */ /* encode sub-frame */
iCBSearch(cb_index+subcount*CB_NSTAGES, iCBSearch(iLBCenc_inst, cb_index+subcount*CB_NSTAGES,
gain_index+subcount*CB_NSTAGES, gain_index+subcount*CB_NSTAGES,
&reverseResidual[subframe*SUBL], &reverseResidual[subframe*SUBL],
mem+CB_MEML-memLfTbl[subcount], memLfTbl[subcount], mem+CB_MEML-memLfTbl[subcount],
SUBL, CB_NSTAGES, memLfTbl[subcount], SUBL, CB_NSTAGES,
&weightdenum[(start-2-subframe)*(LPC_FILTERORDER+1)], &weightdenum[(start-2-subframe)*
(LPC_FILTERORDER+1)],
weightState, subcount+1); weightState, subcount+1);
/* construct decoded vector */ /* construct decoded vector */
@@ -324,8 +375,10 @@ void iLBC_encode(
/* get decoded residual from reversed vector */ /* get decoded residual from reversed vector */
for (i = 0; i < SUBL*Nback; i++) { for (i=0; i<SUBL*Nback; i++) {
decresidual[SUBL*Nback - i - 1] = decresidual[SUBL*Nback - i - 1] =
reverseDecresidual[i]; reverseDecresidual[i];
} }
} }
@@ -344,104 +397,117 @@ void iLBC_encode(
for (ulp=0; ulp<3; ulp++) { for (ulp=0; ulp<3; ulp++) {
/* LSF */ /* LSF */
for (k=0;k<6;k++) { for (k=0; k<LSF_NSPLIT*iLBCenc_inst->lpc_n; k++) {
packsplit(&lsf_i[k], &firstpart, &lsf_i[k], packsplit(&lsf_i[k], &firstpart, &lsf_i[k],
ulp_lsf_bitsTbl[k][ulp], iLBCenc_inst->ULP_inst->lsf_bits[k][ulp],
ulp_lsf_bitsTbl[k][ulp]+ iLBCenc_inst->ULP_inst->lsf_bits[k][ulp]+
ulp_lsf_bitsTbl[k][ulp+1]+ iLBCenc_inst->ULP_inst->lsf_bits[k][ulp+1]+
ulp_lsf_bitsTbl[k][ulp+2]); iLBCenc_inst->ULP_inst->lsf_bits[k][ulp+2]);
dopack( &pbytes, firstpart, dopack( &pbytes, firstpart,
ulp_lsf_bitsTbl[k][ulp], &pos); iLBCenc_inst->ULP_inst->lsf_bits[k][ulp], &pos);
} }
/* Start block info */ /* Start block info */
packsplit(&start, &firstpart, &start, packsplit(&start, &firstpart, &start,
ulp_start_bitsTbl[ulp], iLBCenc_inst->ULP_inst->start_bits[ulp],
ulp_start_bitsTbl[ulp]+ iLBCenc_inst->ULP_inst->start_bits[ulp]+
ulp_start_bitsTbl[ulp+1]+ iLBCenc_inst->ULP_inst->start_bits[ulp+1]+
ulp_start_bitsTbl[ulp+2]); iLBCenc_inst->ULP_inst->start_bits[ulp+2]);
dopack( &pbytes, firstpart, dopack( &pbytes, firstpart,
ulp_start_bitsTbl[ulp], &pos); iLBCenc_inst->ULP_inst->start_bits[ulp], &pos);
packsplit(&state_first, &firstpart, &state_first, packsplit(&state_first, &firstpart, &state_first,
ulp_startfirst_bitsTbl[ulp], iLBCenc_inst->ULP_inst->startfirst_bits[ulp],
ulp_startfirst_bitsTbl[ulp]+ iLBCenc_inst->ULP_inst->startfirst_bits[ulp]+
ulp_startfirst_bitsTbl[ulp+1]+ iLBCenc_inst->ULP_inst->startfirst_bits[ulp+1]+
ulp_startfirst_bitsTbl[ulp+2]); iLBCenc_inst->ULP_inst->startfirst_bits[ulp+2]);
dopack( &pbytes, firstpart, dopack( &pbytes, firstpart,
ulp_startfirst_bitsTbl[ulp], &pos); iLBCenc_inst->ULP_inst->startfirst_bits[ulp], &pos);
packsplit(&idxForMax, &firstpart, &idxForMax, packsplit(&idxForMax, &firstpart, &idxForMax,
ulp_scale_bitsTbl[ulp], ulp_scale_bitsTbl[ulp]+ iLBCenc_inst->ULP_inst->scale_bits[ulp],
ulp_scale_bitsTbl[ulp+1]+ulp_scale_bitsTbl[ulp+2]); iLBCenc_inst->ULP_inst->scale_bits[ulp]+
iLBCenc_inst->ULP_inst->scale_bits[ulp+1]+
iLBCenc_inst->ULP_inst->scale_bits[ulp+2]);
dopack( &pbytes, firstpart, dopack( &pbytes, firstpart,
ulp_scale_bitsTbl[ulp], &pos); iLBCenc_inst->ULP_inst->scale_bits[ulp], &pos);
for (k=0; k<STATE_SHORT_LEN; k++) {
for (k=0; k<iLBCenc_inst->state_short_len; k++) {
packsplit(idxVec+k, &firstpart, idxVec+k, packsplit(idxVec+k, &firstpart, idxVec+k,
ulp_state_bitsTbl[ulp], iLBCenc_inst->ULP_inst->state_bits[ulp],
ulp_state_bitsTbl[ulp]+ iLBCenc_inst->ULP_inst->state_bits[ulp]+
ulp_state_bitsTbl[ulp+1]+ iLBCenc_inst->ULP_inst->state_bits[ulp+1]+
ulp_state_bitsTbl[ulp+2]); iLBCenc_inst->ULP_inst->state_bits[ulp+2]);
dopack( &pbytes, firstpart, dopack( &pbytes, firstpart,
ulp_state_bitsTbl[ulp], &pos); iLBCenc_inst->ULP_inst->state_bits[ulp], &pos);
} }
/* 22 sample block */ /* 23/22 (20ms/30ms) sample block */
for (k=0;k<CB_NSTAGES;k++) { for (k=0;k<CB_NSTAGES;k++) {
packsplit(extra_cb_index+k, &firstpart, packsplit(extra_cb_index+k, &firstpart,
extra_cb_index+k, extra_cb_index+k,
ulp_extra_cb_indexTbl[k][ulp], iLBCenc_inst->ULP_inst->extra_cb_index[k][ulp],
ulp_extra_cb_indexTbl[k][ulp]+ iLBCenc_inst->ULP_inst->extra_cb_index[k][ulp]+
ulp_extra_cb_indexTbl[k][ulp+1]+ iLBCenc_inst->ULP_inst->extra_cb_index[k][ulp+1]+
ulp_extra_cb_indexTbl[k][ulp+2]); iLBCenc_inst->ULP_inst->extra_cb_index[k][ulp+2]);
dopack( &pbytes, firstpart, dopack( &pbytes, firstpart,
ulp_extra_cb_indexTbl[k][ulp], &pos); iLBCenc_inst->ULP_inst->extra_cb_index[k][ulp],
&pos);
} }
for (k=0;k<CB_NSTAGES;k++) { for (k=0;k<CB_NSTAGES;k++) {
packsplit(extra_gain_index+k, &firstpart, packsplit(extra_gain_index+k, &firstpart,
extra_gain_index+k, extra_gain_index+k,
ulp_extra_cb_gainTbl[k][ulp], iLBCenc_inst->ULP_inst->extra_cb_gain[k][ulp],
ulp_extra_cb_gainTbl[k][ulp]+ iLBCenc_inst->ULP_inst->extra_cb_gain[k][ulp]+
ulp_extra_cb_gainTbl[k][ulp+1]+ iLBCenc_inst->ULP_inst->extra_cb_gain[k][ulp+1]+
ulp_extra_cb_gainTbl[k][ulp+2]); iLBCenc_inst->ULP_inst->extra_cb_gain[k][ulp+2]);
dopack( &pbytes, firstpart, dopack( &pbytes, firstpart,
ulp_extra_cb_gainTbl[k][ulp], &pos); iLBCenc_inst->ULP_inst->extra_cb_gain[k][ulp],
&pos);
} }
/* The four 40 sample sub blocks */ /* The two/four (20ms/30ms) 40 sample sub-blocks */
for (i=0; i<NASUB; i++) { for (i=0; i<iLBCenc_inst->nasub; i++) {
for (k=0; k<CB_NSTAGES; k++) { for (k=0; k<CB_NSTAGES; k++) {
packsplit(cb_index+i*CB_NSTAGES+k, &firstpart, packsplit(cb_index+i*CB_NSTAGES+k, &firstpart,
cb_index+i*CB_NSTAGES+k, cb_index+i*CB_NSTAGES+k,
ulp_cb_indexTbl[i][k][ulp], iLBCenc_inst->ULP_inst->cb_index[i][k][ulp],
ulp_cb_indexTbl[i][k][ulp]+ iLBCenc_inst->ULP_inst->cb_index[i][k][ulp]+
ulp_cb_indexTbl[i][k][ulp+1]+ iLBCenc_inst->ULP_inst->cb_index[i][k][ulp+1]+
ulp_cb_indexTbl[i][k][ulp+2]); iLBCenc_inst->ULP_inst->cb_index[i][k][ulp+2]);
dopack( &pbytes, firstpart, dopack( &pbytes, firstpart,
ulp_cb_indexTbl[i][k][ulp], &pos); iLBCenc_inst->ULP_inst->cb_index[i][k][ulp],
&pos);
} }
} }
for (i=0; i<NASUB; i++) { for (i=0; i<iLBCenc_inst->nasub; i++) {
for (k=0; k<CB_NSTAGES; k++) { for (k=0; k<CB_NSTAGES; k++) {
packsplit(gain_index+i*CB_NSTAGES+k, &firstpart, packsplit(gain_index+i*CB_NSTAGES+k, &firstpart,
gain_index+i*CB_NSTAGES+k, gain_index+i*CB_NSTAGES+k,
ulp_cb_gainTbl[i][k][ulp], iLBCenc_inst->ULP_inst->cb_gain[i][k][ulp],
ulp_cb_gainTbl[i][k][ulp]+ iLBCenc_inst->ULP_inst->cb_gain[i][k][ulp]+
ulp_cb_gainTbl[i][k][ulp+1]+ iLBCenc_inst->ULP_inst->cb_gain[i][k][ulp+1]+
ulp_cb_gainTbl[i][k][ulp+2]); iLBCenc_inst->ULP_inst->cb_gain[i][k][ulp+2]);
dopack( &pbytes, firstpart, dopack( &pbytes, firstpart,
ulp_cb_gainTbl[i][k][ulp], &pos); iLBCenc_inst->ULP_inst->cb_gain[i][k][ulp],
&pos);
} }
} }
} }
/* set the last unused bit to zero */ /* set the last bit to zero (otherwise the decoder
will treat it as a lost frame) */
dopack( &pbytes, 0, 1, &pos); dopack( &pbytes, 0, 1, &pos);
} }

View File

@@ -5,9 +5,8 @@
iLBC_encode.h iLBC_encode.h
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/ ******************************************************************/
@@ -16,13 +15,18 @@
#include "iLBC_define.h" #include "iLBC_define.h"
short initEncode( /* (o) Number of bytes encoded */ short initEncode( /* (o) Number of bytes
iLBC_Enc_Inst_t *iLBCenc_inst /* (i/o) Encoder instance */ encoded */
iLBC_Enc_Inst_t *iLBCenc_inst, /* (i/o) Encoder instance */
int mode /* (i) frame size mode */
); );
void iLBC_encode( void iLBC_encode(
unsigned char *bytes, /* (o) encoded data bits iLBC */ unsigned char *bytes, /* (o) encoded data bits iLBC */
float *block, /* (o) speech vector to encode */ float *block, /* (o) speech vector to
encode */
iLBC_Enc_Inst_t *iLBCenc_inst /* (i/o) the general encoder iLBC_Enc_Inst_t *iLBCenc_inst /* (i/o) the general encoder
state */ state */
); );
@@ -30,3 +34,4 @@ void iLBC_encode(
#endif #endif

View File

@@ -5,9 +5,8 @@
lsf.c lsf.c
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/ ******************************************************************/
@@ -15,7 +14,6 @@
#include <math.h> #include <math.h>
#include "iLBC_define.h" #include "iLBC_define.h"
#include "lsf.h"
/*----------------------------------------------------------------* /*----------------------------------------------------------------*
* conversion from lpc coefficients to lsf coefficients * conversion from lpc coefficients to lsf coefficients
@@ -34,6 +32,8 @@ void a2lsf(
float p[LPC_HALFORDER]; float p[LPC_HALFORDER];
float q[LPC_HALFORDER]; float q[LPC_HALFORDER];
float p_pre[LPC_HALFORDER]; float p_pre[LPC_HALFORDER];
float q_pre[LPC_HALFORDER]; float q_pre[LPC_HALFORDER];
float old_p, old_q, *old; float old_p, old_q, *old;
float *pq_coef; float *pq_coef;
@@ -41,7 +41,7 @@ void a2lsf(
int i; int i;
float hlp, hlp1, hlp2, hlp3, hlp4, hlp5; float hlp, hlp1, hlp2, hlp3, hlp4, hlp5;
for (i = 0; i < LPC_HALFORDER; i++){ for (i=0; i<LPC_HALFORDER; i++) {
p[i] = (float)-1.0 * (a[i + 1] + a[LPC_FILTERORDER - i]); p[i] = (float)-1.0 * (a[i + 1] + a[LPC_FILTERORDER - i]);
q[i] = a[LPC_FILTERORDER - i] - a[i + 1]; q[i] = a[LPC_FILTERORDER - i] - a[i + 1];
} }
@@ -69,7 +69,7 @@ void a2lsf(
/* Here we loop through lsp_index to find all the /* Here we loop through lsp_index to find all the
LPC_FILTERORDER roots for omega. */ LPC_FILTERORDER roots for omega. */
for (lsp_index = 0; lsp_index < LPC_FILTERORDER; lsp_index++){ for (lsp_index = 0; lsp_index<LPC_FILTERORDER; lsp_index++) {
/* Depending on lsp_index being even or odd, we /* Depending on lsp_index being even or odd, we
alternatively solve the roots for the two LSP equations. */ alternatively solve the roots for the two LSP equations. */
@@ -88,6 +88,8 @@ void a2lsf(
for (step_idx = 0, step = steps[step_idx]; for (step_idx = 0, step = steps[step_idx];
step_idx < LSF_NUMBER_OF_STEPS;){ step_idx < LSF_NUMBER_OF_STEPS;){
/* cos(10piw) + pq(0)cos(8piw) + pq(1)cos(6piw) + /* cos(10piw) + pq(0)cos(8piw) + pq(1)cos(6piw) +
pq(2)cos(4piw) + pq(3)cod(2piw) + pq(4) */ pq(2)cos(4piw) + pq(3)cod(2piw) + pq(4) */
@@ -142,10 +144,12 @@ void a2lsf(
*old = hlp5; *old = hlp5;
omega += step; omega += step;
} }
} }
} }
for (i = 0; i < LPC_FILTERORDER; i++) { for (i = 0; i<LPC_FILTERORDER; i++) {
freq[i] = freq[i] * TWO_PI; freq[i] = freq[i] * TWO_PI;
} }
} }
@@ -161,10 +165,12 @@ void lsf2a(
int i, j; int i, j;
float hlp; float hlp;
float p[LPC_HALFORDER], q[LPC_HALFORDER]; float p[LPC_HALFORDER], q[LPC_HALFORDER];
float a[LPC_HALFORDER + 1], a1[LPC_HALFORDER], a2[LPC_HALFORDER]; float a[LPC_HALFORDER + 1], a1[LPC_HALFORDER],
float b[LPC_HALFORDER + 1], b1[LPC_HALFORDER], b2[LPC_HALFORDER]; a2[LPC_HALFORDER];
float b[LPC_HALFORDER + 1], b1[LPC_HALFORDER],
b2[LPC_HALFORDER];
for (i = 0; i < LPC_FILTERORDER; i++) { for (i=0; i<LPC_FILTERORDER; i++) {
freq[i] = freq[i] * PI2; freq[i] = freq[i] * PI2;
} }
@@ -191,9 +197,11 @@ void lsf2a(
hlp = (freq[LPC_FILTERORDER - 1] - freq[0]) / hlp = (freq[LPC_FILTERORDER - 1] - freq[0]) /
(float) (LPC_FILTERORDER - 1); (float) (LPC_FILTERORDER - 1);
for (i = 1; i < LPC_FILTERORDER; i++) { for (i=1; i<LPC_FILTERORDER; i++) {
freq[i] = freq[i - 1] + hlp; freq[i] = freq[i - 1] + hlp;
} }
} }
memset(a1, 0, LPC_HALFORDER*sizeof(float)); memset(a1, 0, LPC_HALFORDER*sizeof(float));
@@ -209,7 +217,7 @@ void lsf2a(
used in .Q_A(z) while q[i] specifies the coefficients used used in .Q_A(z) while q[i] specifies the coefficients used
in .P_A(z) */ in .P_A(z) */
for (i = 0; i < LPC_HALFORDER; i++){ for (i=0; i<LPC_HALFORDER; i++) {
p[i] = (float)cos(TWO_PI * freq[2 * i]); p[i] = (float)cos(TWO_PI * freq[2 * i]);
q[i] = (float)cos(TWO_PI * freq[2 * i + 1]); q[i] = (float)cos(TWO_PI * freq[2 * i + 1]);
} }
@@ -217,7 +225,7 @@ void lsf2a(
a[0] = 0.25; a[0] = 0.25;
b[0] = 0.25; b[0] = 0.25;
for (i = 0; i < LPC_HALFORDER; i++){ for (i= 0; i<LPC_HALFORDER; i++) {
a[i + 1] = a[i] - 2 * p[i] * a1[i] + a2[i]; a[i + 1] = a[i] - 2 * p[i] * a1[i] + a2[i];
b[i + 1] = b[i] - 2 * q[i] * b1[i] + b2[i]; b[i + 1] = b[i] - 2 * q[i] * b1[i] + b2[i];
a2[i] = a1[i]; a2[i] = a1[i];
@@ -226,7 +234,7 @@ void lsf2a(
b1[i] = b[i]; b1[i] = b[i];
} }
for (j = 0; j < LPC_FILTERORDER; j++){ for (j=0; j<LPC_FILTERORDER; j++) {
if (j == 0) { if (j == 0) {
a[0] = 0.25; a[0] = 0.25;
@@ -235,7 +243,7 @@ void lsf2a(
a[0] = b[0] = 0.0; a[0] = b[0] = 0.0;
} }
for (i = 0; i < LPC_HALFORDER; i++){ for (i=0; i<LPC_HALFORDER; i++) {
a[i + 1] = a[i] - 2 * p[i] * a1[i] + a2[i]; a[i + 1] = a[i] - 2 * p[i] * a1[i] + a2[i];
b[i + 1] = b[i] - 2 * q[i] * b1[i] + b2[i]; b[i + 1] = b[i] - 2 * q[i] * b1[i] + b2[i];
a2[i] = a1[i]; a2[i] = a1[i];
@@ -248,6 +256,8 @@ void lsf2a(
} }
a_coef[0] = 1.0; a_coef[0] = 1.0;
} }

View File

@@ -5,9 +5,10 @@
lsf.h lsf.h
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/ ******************************************************************/

View File

@@ -5,9 +5,8 @@
packing.c packing.c
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/ ******************************************************************/
@@ -18,7 +17,6 @@
#include "constants.h" #include "constants.h"
#include "helpfun.h" #include "helpfun.h"
#include "string.h" #include "string.h"
#include "packing.h"
/*----------------------------------------------------------------* /*----------------------------------------------------------------*
* splitting an integer into first most significant bits and * splitting an integer into first most significant bits and
@@ -38,6 +36,8 @@ void packsplit(
){ ){
int bitno_rest = bitno_total-bitno_firstpart; int bitno_rest = bitno_total-bitno_firstpart;
*firstpart = *index>>(bitno_rest); *firstpart = *index>>(bitno_rest);
*rest = *index-(*firstpart<<(bitno_rest)); *rest = *index-(*firstpart<<(bitno_rest));
} }
@@ -63,11 +63,11 @@ void packcombine(
*---------------------------------------------------------------*/ *---------------------------------------------------------------*/
void dopack( void dopack(
unsigned char **bitstream, /* (i/o) on entrance pointer to place unsigned char **bitstream, /* (i/o) on entrance pointer to
in bitstream to pack new data, place in bitstream to pack
on exit pointer to place in new data, on exit pointer
bitstream to pack future to place in bitstream to
data */ pack future data */
int index, /* (i) the value to pack */ int index, /* (i) the value to pack */
int bitno, /* (i) the number of bits that the int bitno, /* (i) the number of bits that the
value will fit within */ value will fit within */
@@ -92,6 +92,8 @@ void dopack(
**bitstream=0; **bitstream=0;
} }
posLeft=8-(*pos); posLeft=8-(*pos);
/* Insert index into the bitstream */ /* Insert index into the bitstream */
@@ -146,6 +148,8 @@ void unpack(
/* Extract bits to index */ /* Extract bits to index */
if (BitsLeft>=bitno) { if (BitsLeft>=bitno) {
*index+=((((**bitstream)<<(*pos)) & 0xFF)>>(8-bitno)); *index+=((((**bitstream)<<(*pos)) & 0xFF)>>(8-bitno));

View File

@@ -5,9 +5,8 @@
packing.h packing.h
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/ ******************************************************************/
@@ -35,11 +34,11 @@ void packcombine(
); );
void dopack( void dopack(
unsigned char **bitstream, /* (i/o) on entrance pointer to place unsigned char **bitstream, /* (i/o) on entrance pointer to
in bitstream to pack new data, place in bitstream to pack
on exit pointer to place in new data, on exit pointer
bitstream to pack future to place in bitstream to
data */ pack future data */
int index, /* (i) the value to pack */ int index, /* (i) the value to pack */
int bitno, /* (i) the number of bits that the int bitno, /* (i) the number of bits that the
value will fit within */ value will fit within */
@@ -48,11 +47,14 @@ void dopack(
); );
void unpack( void unpack(
unsigned char **bitstream, /* (i/o) on entrance pointer to place unsigned char **bitstream, /* (i/o) on entrance pointer to
in bitstream to unpack
new data from, on exit pointer
to place in bitstream to place in bitstream to
unpack future data from */ unpack new data from, on
exit pointer to place in
bitstream to unpack future
data from */
int *index, /* (o) resulting value */ int *index, /* (o) resulting value */
int bitno, /* (i) number of bits used to int bitno, /* (i) number of bits used to
represent the value */ represent the value */

View File

@@ -5,14 +5,12 @@
syntFilter.c syntFilter.c
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/ ******************************************************************/
#include "iLBC_define.h" #include "iLBC_define.h"
#include "syntFilter.h"
/*----------------------------------------------------------------* /*----------------------------------------------------------------*
* LP synthesis filter. * LP synthesis filter.
@@ -31,14 +29,14 @@ void syntFilter(
/* Filter first part using memory from past */ /* Filter first part using memory from past */
for (i=0;i<LPC_FILTERORDER;i++) { for (i=0; i<LPC_FILTERORDER; i++) {
pi=&Out[i-1]; pi=&Out[i-1];
pa=&a[1]; pa=&a[1];
pm=&mem[LPC_FILTERORDER-1]; pm=&mem[LPC_FILTERORDER-1];
for (j=1;j<=i;j++) { for (j=1; j<=i; j++) {
*po-=(*pa++)*(*pi--); *po-=(*pa++)*(*pi--);
} }
for (j=i+1;j<LPC_FILTERORDER+1;j++) { for (j=i+1; j<LPC_FILTERORDER+1; j++) {
*po-=(*pa++)*(*pm--); *po-=(*pa++)*(*pm--);
} }
po++; po++;
@@ -47,10 +45,12 @@ void syntFilter(
/* Filter last part where the state is entierly in /* Filter last part where the state is entierly in
the output vector */ the output vector */
for (i=LPC_FILTERORDER;i<len;i++) { for (i=LPC_FILTERORDER; i<len; i++) {
pi=&Out[i-1]; pi=&Out[i-1];
pa=&a[1]; pa=&a[1];
for (j=1;j<LPC_FILTERORDER+1;j++) { for (j=1; j<LPC_FILTERORDER+1; j++) {
*po-=(*pa++)*(*pi--); *po-=(*pa++)*(*pi--);
} }
po++; po++;
@@ -64,3 +64,44 @@ void syntFilter(

View File

@@ -5,9 +5,8 @@
syntFilter.h syntFilter.h
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/ ******************************************************************/
@@ -19,6 +18,8 @@ void syntFilter(
float *a, /* (i) LP parameters */ float *a, /* (i) LP parameters */
int len, /* (i) Length of signal */ int len, /* (i) Length of signal */
float *mem /* (i/o) Filter state */ float *mem /* (i/o) Filter state */
); );
#endif #endif