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
*
* 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
* the GNU General Public License
@@ -33,6 +33,8 @@
#include "ilbc_slin_ex.h"
#define USE_ILBC_ENHANCER 0
#define ILBC_MS 30
/* #define ILBC_MS 20 */
AST_MUTEX_DEFINE_STATIC(localuser_lock);
static int localusecnt=0;
@@ -61,7 +63,7 @@ static struct ast_translator_pvt *lintoilbc_new(void)
if (tmp) {
/* Shut valgrind up */
memset(&tmp->enc, 0, sizeof(tmp->enc));
initEncode(&tmp->enc);
initEncode(&tmp->enc, ILBC_MS);
tmp->tail = 0;
localusecnt++;
}
@@ -75,7 +77,7 @@ static struct ast_translator_pvt *ilbctolin_new(void)
if (tmp) {
/* Shut valgrind up */
memset(&tmp->dec, 0, sizeof(tmp->dec));
initDecode(&tmp->dec, USE_ILBC_ENHANCER);
initDecode(&tmp->dec, ILBC_MS, USE_ILBC_ENHANCER);
tmp->tail = 0;
localusecnt++;
}

View File

@@ -5,25 +5,25 @@
FrameClassify.c
Copyright (c) 2001,
Global IP Sound AB.
All rights reserved.
Copyright (C) The Internet Society (2004).
All Rights Reserved.
******************************************************************/
#include "iLBC_define.h"
#include "FrameClassify.h"
/*----------------------------------------------------------------*
/*---------------------------------------------------------------*
* 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 max_ssqEn, fssqEn[NSUB], bssqEn[NSUB], *pp;
) {
float max_ssqEn, fssqEn[NSUB_MAX], bssqEn[NSUB_MAX], *pp;
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};
const float sampEn_win[5]={(float)1.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 */
memset(fssqEn, 0, NSUB*sizeof(float));
memset(bssqEn, 0, NSUB*sizeof(float));
memset(fssqEn, 0, NSUB_MAX*sizeof(float));
memset(bssqEn, 0, NSUB_MAX*sizeof(float));
/* Calculate front of first seqence */
n=0;
pp=residual;
for(l=0;l<5;l++){
for (l=0; l<5; l++) {
fssqEn[n] += sampEn_win[l] * (*pp) * (*pp);
pp++;
}
for(l=5;l<SUBL;l++){
for (l=5; l<SUBL; l++) {
fssqEn[n] += (*pp) * (*pp);
pp++;
}
/* 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;
for(l=0;l<5;l++){
for (l=0; l<5; l++) {
fssqEn[n] += sampEn_win[l] * (*pp) * (*pp);
bssqEn[n] += (*pp) * (*pp);
pp++;
}
for(l=5;l<SUBL-5;l++){
for (l=5; l<SUBL-5; l++) {
fssqEn[n] += (*pp) * (*pp);
bssqEn[n] += (*pp) * (*pp);
pp++;
}
for(l=SUBL-5;l<SUBL;l++){
for (l=SUBL-5; l<SUBL; l++) {
fssqEn[n] += (*pp) * (*pp);
bssqEn[n] += sampEn_win[SUBL-l-1] * (*pp) * (*pp);
pp++;
@@ -70,13 +72,13 @@ int FrameClassify( /* index to the max-energy sub frame */
/* Calculate back of last seqence */
n=NSUB-1;
n=iLBCenc_inst->nsub-1;
pp=residual+n*SUBL;
for(l=0;l<SUBL-5;l++){
for (l=0; l<SUBL-5; l++) {
bssqEn[n] += (*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);
pp++;
}
@@ -84,13 +86,19 @@ int FrameClassify( /* index to the max-energy sub frame */
/* find the index to the weighted 80 sample with
most energy */
max_ssqEn=(fssqEn[0]+bssqEn[1])*ssqEn_win[0];
max_ssqEn_n=1;
for (n=2;n<NSUB;n++) {
if (iLBCenc_inst->mode==20) l=1;
else l=0;
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]) *
ssqEn_win[n-1];
ssqEn_win[l];
max_ssqEn_n=n;
}
}

View File

@@ -5,16 +5,19 @@
FrameClassify.h
Copyright (c) 2001,
Global IP Sound AB.
All rights reserved.
Copyright (C) The Internet Society (2004).
All Rights Reserved.
******************************************************************/
#ifndef __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 */
);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -5,51 +5,66 @@
constants.c
Copyright (c) 2001,
Global IP Sound AB.
All rights reserved.
Copyright (C) The Internet Society (2004).
All Rights Reserved.
******************************************************************/
#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 */
int ulp_lsf_bitsTbl[6][ULP_CLASSES+2]={
{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};
/* 20 ms frame */
int ulp_extra_cb_indexTbl[CB_NSTAGES][ULP_CLASSES+2]={
{4,2,1,0,0},{0,0,7,0,0},{0,0,7,0,0}};
int ulp_extra_cb_gainTbl[CB_NSTAGES][ULP_CLASSES+2]={
{1,1,3,0,0},{1,1,2,0,0},{0,0,3,0,0}};
int ulp_cb_indexTbl[NASUB][CB_NSTAGES][ULP_CLASSES+2]={
{{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}}};
int ulp_cb_gainTbl[NASUB][CB_NSTAGES][ULP_CLASSES+2]={
{{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}}};
const iLBC_ULP_Inst_t ULP_20msTbl = {
/* LSF */
{ {6,0,0,0,0}, {7,0,0,0,0}, {7,0,0,0,0},
{0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}},
/* Start state location, gain and samples */
{2,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 */
{{6,0,1,0,0}, {0,0,7,0,0}, {0,0,7,0,0}},
{{2,0,3,0,0}, {1,1,2,0,0}, {0,0,3,0,0}},
/* CB index and CB gain */
{ {{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 */
@@ -85,6 +100,8 @@ float state_sq3Tbl[8] = {
float state_frgqTbl[64] = {
(float)1.000085, (float)1.071695, (float)1.140395,
(float)1.206868, (float)1.277188, (float)1.351503,
(float)1.429380, (float)1.500727, (float)1.569049,
(float)1.639599, (float)1.707071, (float)1.781531,
(float)1.840799, (float)1.901550, (float)1.956695,
@@ -109,15 +126,18 @@ float state_frgqTbl[64] = {
/* 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 memLfTbl[NASUB]={147,147,147,147};
int memLfTbl[NASUB_MAX]={147,147,147,147};
/* expansion filter(s) */
float cbfiltersTbl[CB_FILTERLEN]={
(float)-0.033691, (float)0.083740, (float)-0.144043,
(float)0.713379, (float)0.806152, (float)-0.184326,
(float)0.108887, (float)-0.034180};
(float)-0.034180, (float)0.108887, (float)-0.184326,
(float)0.806152, (float)0.713379, (float)-0.144043,
(float)0.083740, (float)-0.033691
};
/* Gain Quantization */
@@ -136,6 +156,8 @@ float gain_sq4Tbl[16]={
float gain_sq5Tbl[32]={
(float)0.037476, (float)0.075012, (float)0.112488,
(float)0.150024, (float)0.187500, (float)0.224976,
(float)0.262512, (float)0.299988, (float)0.337524,
(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)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)(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 */
float lpc_winTbl[BLOCKL]={
float lpc_winTbl[BLOCKL_MAX]={
(float)0.000183, (float)0.000671, (float)0.001526,
(float)0.002716, (float)0.004242, (float)0.006104,
(float)0.008301, (float)0.010834, (float)0.013702,
(float)0.016907, (float)0.020416, (float)0.024261,
(float)0.028442, (float)0.032928, (float)0.037750,
(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.687561, (float)0.675415, (float)0.663147,
(float)0.650787, (float)0.638306, (float)0.625732,
(float)0.613068, (float)0.600342, (float)0.587524,
(float)0.574677, (float)0.561768, (float)0.548798,
(float)0.535828, (float)0.522797, (float)0.509766,
@@ -268,7 +296,7 @@ float lpc_winTbl[BLOCKL]={
};
/* Asymmetric LPC window */
float lpc_asymwinTbl[BLOCKL]={
float lpc_asymwinTbl[BLOCKL_MAX]={
(float)0.000061, (float)0.000214, (float)0.000458,
(float)0.000824, (float)0.001282, (float)0.001831,
(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.265564, (float)0.271881, (float)0.278259,
(float)0.284668, (float)0.291107, (float)0.297607,
(float)0.304138, (float)0.310730, (float)0.317322,
(float)0.323975, (float)0.330658, (float)0.337372,
(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
};
/* Lag window for LPC */
float lpc_lagwinTbl[LPC_FILTERORDER + 1]={
(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.380493, (float)0.608643, (float)0.861084,
(float)0.222778, (float)0.426147, (float)0.676514,
(float)0.407471, (float)0.700195, (float)1.053101,
(float)0.218384, (float)0.377197, (float)0.669922,
(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.920166, (float)1.119385, (float)1.486206,
(float)0.894409, (float)1.539063, (float)1.828979,
(float)1.283691, (float)1.543335, (float)1.858276,
(float)0.676025, (float)0.933105, (float)1.490845,
(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.859009, (float)1.016602, (float)1.191895,
(float)0.843994, (float)1.131104, (float)1.645020,
(float)1.189697, (float)1.702759, (float)1.894409,
(float)1.346680, (float)1.763184, (float)2.066040,
(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.734619, (float)1.940552, (float)2.306030, (float)2.826416,
(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)2.001465, (float)2.307617, (float)2.552734, (float)2.811890,
(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.824951, (float)2.267456, (float)2.514526, (float)2.747925,
(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.562866, (float)2.135986, (float)2.471680, (float)2.687256,
(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.916870, (float)2.135132, (float)2.568237, (float)2.826050,
(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)2.088501, (float)2.402710, (float)2.667358, (float)2.890259,
(float)1.545044, (float)1.819214, (float)2.324097, (float)2.692993,

View File

@@ -5,9 +5,10 @@
constants.h
Copyright (c) 2001,
Global IP Sound AB.
All rights reserved.
Copyright (C) The Internet Society (2004).
All Rights Reserved.
******************************************************************/
@@ -16,27 +17,11 @@
#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 */
extern int ulp_lsf_bitsTbl[6][ULP_CLASSES+2];
extern int ulp_start_bitsTbl[];
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];
extern const iLBC_ULP_Inst_t ULP_20msTbl;
extern const iLBC_ULP_Inst_t ULP_30msTbl;
/* high pass filters */
@@ -57,7 +42,8 @@ extern float lsfCbTbl[];
extern float lsfmeanTbl[];
extern int dim_lsfCbTbl[];
extern int size_lsfCbTbl[];
extern float lsf_weightTbl[];
extern float lsf_weightTbl_30ms[];
extern float lsf_weightTbl_20ms[];
/* state quantization tables */
@@ -72,10 +58,13 @@ extern float gain_sq5Tbl[];
/* adaptive codebook definitions */
extern int search_rangeTbl[5][CB_NSTAGES];
extern int memLfTbl[];
extern int stMemLTbl;
extern float cbfiltersTbl[CB_FILTERLEN];
/* enhancer definitions */
extern float polyphaserTbl[];

View File

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

View File

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

View File

@@ -5,50 +5,63 @@
doCPLC.c
Copyright (c) 2001,
Global IP Sound AB.
All rights reserved.
Copyright (C) The Internet Society (2004).
All Rights Reserved.
******************************************************************/
#include <math.h>
#include <string.h>
#include <stdio.h>
#include "iLBC_define.h"
#include "doCPLC.h"
/*----------------------------------------------------------------*
* Compute cross correlation and pitch gain for pitch prediction
* of last subframe at given lag.
*---------------------------------------------------------------*/
static void compCorr(
void compCorr(
float *cc, /* (o) cross correlation coefficient */
float *gc, /* (o) gain */
float *pm,
float *buffer, /* (i) signal buffer */
int lag, /* (i) pitch lag */
int bLen, /* (i) length of buffer */
int sRange /* (i) correlation search length */
){
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;
ftmp2 = 0.0;
ftmp3 = 0.0;
for (i=0; i<sRange; i++) {
ftmp1 += buffer[bLen-sRange+i] *
buffer[bLen-sRange+i-lag];
ftmp2 += buffer[bLen-sRange+i-lag] *
buffer[bLen-sRange+i-lag];
ftmp3 += buffer[bLen-sRange+i] *
buffer[bLen-sRange+i];
}
if (ftmp2 > 0.0) {
*cc = ftmp1*ftmp1/ftmp2;
*gc = (float)fabs(ftmp1/ftmp2);
*pm=(float)fabs(ftmp1)/
((float)sqrt(ftmp2)*(float)sqrt(ftmp3));
}
else {
*cc = 0.0;
*gc = 0.0;
*pm=0.0;
}
}
@@ -70,235 +83,176 @@ void doThePLC(
){
int lag=20, randlag;
float gain, maxcc;
float gain_comp, maxcc_comp;
int i, pick, offset;
float ftmp, ftmp1, randvec[BLOCKL], pitchfact;
float use_gain;
float gain_comp, maxcc_comp, per, max_per;
int i, pick, use_lag;
float ftmp, randvec[BLOCKL_MAX], pitchfact, energy;
/* Packet Loss */
if (PLI == 1) {
(*iLBCdec_inst).consPLICount += 1;
iLBCdec_inst->consPLICount += 1;
/* if previous frame not lost,
determine pitch pred. gain */
if ((*iLBCdec_inst).prevPLI != 1) {
if (iLBCdec_inst->prevPLI != 1) {
/* Search around the previous lag to find the
best pitch period */
lag=inlag-3;
compCorr(&maxcc, &gain, (*iLBCdec_inst).prevResidual,
lag, BLOCKL, 60);
compCorr(&maxcc, &gain, &max_per,
iLBCdec_inst->prevResidual,
lag, iLBCdec_inst->blockl, 60);
for (i=inlag-2;i<=inlag+3;i++) {
compCorr(&maxcc_comp, &gain_comp,
(*iLBCdec_inst).prevResidual,
i, BLOCKL, 60);
compCorr(&maxcc_comp, &gain_comp, &per,
iLBCdec_inst->prevResidual,
i, iLBCdec_inst->blockl, 60);
if (maxcc_comp>maxcc) {
maxcc=maxcc_comp;
gain=gain_comp;
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 {
lag=(*iLBCdec_inst).prevLag;
gain=(*iLBCdec_inst).prevGain;
lag=iLBCdec_inst->prevLag;
max_per=iLBCdec_inst->per;
}
/* Attenuate signal and scale down pitch pred gain if
several frames lost consecutively */
/* downscaling */
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) {
gain *= (float)0.9;
}
iLBCdec_inst->blockl>4*320)
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) {
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);
/* avoid repetition of same pitch cycle */
use_lag=lag;
if (lag<80) {
use_lag=2*lag;
}
/* compute concealed residual */
(*iLBCdec_inst).energy = 0.0;
for (i=0; i<BLOCKL; i++) {
energy = 0.0;
for (i=0; i<iLBCdec_inst->blockl; i++) {
/* noise component */
(*iLBCdec_inst).seed=((*iLBCdec_inst).seed*69069L+1) &
iLBCdec_inst->seed=(iLBCdec_inst->seed*69069L+1) &
(0x80000000L-1);
randlag = 50 + ((signed long) (*iLBCdec_inst).seed)%70;
randlag = 50 + ((signed long) iLBCdec_inst->seed)%70;
pick = i - randlag;
if (pick < 0) {
randvec[i] = gain *
(*iLBCdec_inst).prevResidual[BLOCKL+pick];
randvec[i] =
iLBCdec_inst->prevResidual[
iLBCdec_inst->blockl+pick];
} else {
randvec[i] = gain * randvec[pick];
randvec[i] = randvec[pick];
}
/* pitch repeatition component */
pick = i - lag;
pick = i - use_lag;
if (pick < 0) {
PLCresidual[i] = gain *
(*iLBCdec_inst).prevResidual[BLOCKL+pick];
PLCresidual[i] =
iLBCdec_inst->prevResidual[
iLBCdec_inst->blockl+pick];
} 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]);
(*iLBCdec_inst).energy += PLCresidual[i] *
PLCresidual[i];
energy += PLCresidual[i] * PLCresidual[i];
}
/* less than 30 dB, use only noise */
if (sqrt((*iLBCdec_inst).energy/(float)BLOCKL) < 30.0) {
(*iLBCdec_inst).energy = 0.0;
if (sqrt(energy/(float)iLBCdec_inst->blockl) < 30.0) {
gain=0.0;
for (i=0; i<BLOCKL; i++) {
for (i=0; i<iLBCdec_inst->blockl; 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;
PLClpc[0]=(float)1.0;
for (i=1; i<LPC_FILTERORDER+1; i++) {
PLClpc[i] = ftmp * (*iLBCdec_inst).prevLpc[i];
ftmp *= PLC_BWEXPAND;
}
memcpy(PLClpc,iLBCdec_inst->prevLpc,
(LPC_FILTERORDER+1)*sizeof(float));
}
/* 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 */
else {
memcpy(PLCresidual, decresidual, BLOCKL*sizeof(float));
memcpy(PLCresidual, decresidual,
iLBCdec_inst->blockl*sizeof(float));
memcpy(PLClpc, lpc, (LPC_FILTERORDER+1)*sizeof(float));
iLBCdec_inst->consPLICount = 0;
}
/* update state */
(*iLBCdec_inst).prevLag = lag;
(*iLBCdec_inst).prevGain = gain;
(*iLBCdec_inst).prevPLI = PLI;
memcpy((*iLBCdec_inst).prevLpc, PLClpc,
if (PLI) {
iLBCdec_inst->prevLag = lag;
iLBCdec_inst->per=max_per;
}
iLBCdec_inst->prevPLI = PLI;
memcpy(iLBCdec_inst->prevLpc, PLClpc,
(LPC_FILTERORDER+1)*sizeof(float));
memcpy((*iLBCdec_inst).prevResidual, PLCresidual,
BLOCKL*sizeof(float));
memcpy(iLBCdec_inst->prevResidual, PLCresidual,
iLBCdec_inst->blockl*sizeof(float));
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -5,16 +5,14 @@
helpfun.c
Copyright (c) 2001,
Global IP Sound AB.
All rights reserved.
Copyright (C) The Internet Society (2004).
All Rights Reserved.
******************************************************************/
#include <math.h>
#include "iLBC_define.h"
#include "helpfun.h"
#include "constants.h"
/*----------------------------------------------------------------*
@@ -25,7 +23,8 @@ void autocorr(
float *r, /* (o) autocorrelation vector */
const float *x, /* (i) 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;
float sum;
@@ -39,11 +38,13 @@ void autocorr(
}
}
/*----------------------------------------------------------------*
* window multiplication
*---------------------------------------------------------------*/
void lbc_window(
void window(
float *z, /* (o) the windowed data */
const float *x, /* (i) the original data vector */
const float *y, /* (i) the window */
@@ -61,8 +62,8 @@ void lbc_window(
*---------------------------------------------------------------*/
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 *r, /* (i) autocorrelation vector */
int order /* (i) order of lpc filter */
@@ -92,6 +93,8 @@ void levdurb(
sum = a[i+1] + k[m] * a[m - i];
a[m - i] += k[m] * a[i+1];
a[i+1] = sum;
}
a[m+1] = k[m];
}
@@ -104,8 +107,10 @@ void levdurb(
void interpolate(
float *out, /* (o) the interpolated vector */
float *in1, /* (i) the first vector for the interpolation */
float *in2, /* (i) the second vector for the interpolation */
float *in1, /* (i) the first vector for the
interpolation */
float *in2, /* (i) the second vector for the
interpolation */
float coef, /* (i) interpolation weights */
int length /* (i) length of all vectors */
){
@@ -123,7 +128,8 @@ void interpolate(
*---------------------------------------------------------------*/
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
expansion */
float coef, /* (i) the bandwidth expansion factor */
@@ -143,6 +149,8 @@ void bwexpand(
/*----------------------------------------------------------------*
* vector quantization
*---------------------------------------------------------------*/
void vq(
@@ -197,6 +205,8 @@ void SplitVQ(
int cb_pos, X_pos, i;
cb_pos = 0;
X_pos= 0;
for (i = 0; i < nsplit; i++) {
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 */
float *lsf, /* (i) a table of lsf vectors */
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;
float tmp;
static float eps=(float)0.039; /* 50 Hz */
static float eps2=(float)0.0195;
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*/
for (n=0;n<Nit;n++) { /* Run through a couple of times */
for (m=0;m<NoAn;m++) { /* Number of analyses per frame */
for (k=0;k<(dim-1);k++) {
for (n=0; n<Nit; n++) { /* Run through a couple of times */
for (m=0; m<NoAn; m++) { /* Number of analyses per frame */
for (k=0; k<(dim-1); k++) {
pos=m*dim+k;
if ((lsf[pos+1]-lsf[pos])<eps) {

View File

@@ -5,9 +5,8 @@
helpfun.h
Copyright (c) 2001,
Global IP Sound AB.
All rights reserved.
Copyright (C) The Internet Society (2004).
All Rights Reserved.
******************************************************************/
@@ -18,16 +17,19 @@ void autocorr(
float *r, /* (o) autocorrelation vector */
const float *x, /* (i) 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 */
const float *x, /* (i) the original data vector */
const float *y, /* (i) the window */
int N /* (i) length of all vectors */
);
void levdurb(
float *a, /* (o) lpc coefficient vector starting
with 1.0 */
@@ -38,14 +40,17 @@ void levdurb(
void interpolate(
float *out, /* (o) the interpolated vector */
float *in1, /* (i) the first vector for the interpolation */
float *in2, /* (i) the second vector for the interpolation */
float *in1, /* (i) the first vector for the
interpolation */
float *in2, /* (i) the second vector for the
interpolation */
float coef, /* (i) interpolation weights */
int length /* (i) length of all vectors */
);
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
expansion */
float coef, /* (i) the bandwidth expansion factor */
@@ -78,6 +83,8 @@ void sort_sq(
int *index, /* (o) the quantization index */
float x, /* (i) the value to quantize */
const float *cb,/* (i) 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 */
float *lsf, /* (i) a table of lsf vectors */
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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -5,9 +5,8 @@
iLBC_decode.c
Copyright (c) 2001,
Global IP Sound AB.
All rights reserved.
Copyright (C) The Internet Society (2004).
All Rights Reserved.
******************************************************************/
@@ -22,7 +21,6 @@
#include "helpfun.h"
#include "constants.h"
#include "packing.h"
#include "iLBC_decode.h"
#include "string.h"
#include "enhancer.h"
#include "hpOutput.h"
@@ -35,77 +33,116 @@
short initDecode( /* (o) Number of decoded
samples */
iLBC_Dec_Inst_t *iLBCdec_inst, /* (i/o) Decoder instance */
int mode, /* (i) frame size mode */
int use_enhancer /* (i) 1 to use enhancer
0 to run without
enhancer */
){
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));
memcpy((*iLBCdec_inst).lsfdeqold, lsfmeanTbl,
LPC_FILTERORDER*sizeof(float));
memset((*iLBCdec_inst).old_syntdenum, 0,
((LPC_FILTERORDER + 1)*NSUB)*sizeof(float));
for (i=0; i<NSUB; i++)
(*iLBCdec_inst).old_syntdenum[i*(LPC_FILTERORDER+1)]=1.0;
memset(iLBCdec_inst->old_syntdenum, 0,
((LPC_FILTERORDER + 1)*NSUB_MAX)*sizeof(float));
for (i=0; i<NSUB_MAX; i++)
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).prevGain = 0.0;
(*iLBCdec_inst).consPLICount = 0;
(*iLBCdec_inst).prevPLI = 0;
(*iLBCdec_inst).prevLpc[0] = 1.0;
memset((*iLBCdec_inst).prevLpc+1,0,
iLBCdec_inst->prevLag = 120;
iLBCdec_inst->per = 0.0;
iLBCdec_inst->consPLICount = 0;
iLBCdec_inst->prevPLI = 0;
iLBCdec_inst->prevLpc[0] = 1.0;
memset(iLBCdec_inst->prevLpc+1,0,
LPC_FILTERORDER*sizeof(float));
memset((*iLBCdec_inst).prevResidual, 0, BLOCKL*sizeof(float));
(*iLBCdec_inst).seed=777;
memset(iLBCdec_inst->prevResidual, 0, BLOCKL_MAX*sizeof(float));
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;
memset((*iLBCdec_inst).enh_buf, 0, ENH_BUFL*sizeof(float));
iLBCdec_inst->use_enhancer = use_enhancer;
memset(iLBCdec_inst->enh_buf, 0, ENH_BUFL*sizeof(float));
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;
return (BLOCKL);
return (iLBCdec_inst->blockl);
}
/*----------------------------------------------------------------*
* 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 */
int start, /* (i) location of start state */
int idxForMax, /* (i) codebook index for the maximum
value */
int *idxVec, /* (i) codebook indexes for the samples
in the start state */
float *syntdenum, /* (i) the decoded synthesis filter
coefficients */
int *cb_index, /* (i) the indexes for the adaptive
codebook */
int *gain_index, /* (i) the indexes for the corresponding
gains */
int *extra_cb_index,/* (i) the indexes for the adaptive
codebook part of start state */
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
int start, /* (i) location of start
state */
int idxForMax, /* (i) codebook index for the
maximum value */
int *idxVec, /* (i) codebook indexes for the
samples in the start
state */
float *syntdenum, /* (i) the decoded synthesis
filter coefficients */
int *cb_index, /* (i) the indexes for the
adaptive codebook */
int *gain_index, /* (i) the indexes for the
corresponding gains */
int *extra_cb_index, /* (i) the indexes for the
adaptive codebook part
of start state */
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 */
){
float reverseDecresidual[BLOCKL], mem[CB_MEML];
float reverseDecresidual[BLOCKL_MAX], mem[CB_MEML];
int k, meml_gotten, Nfor, Nback, i;
int diff, start_pos;
int subcount, subframe;
diff = STATE_LEN - STATE_SHORT_LEN;
diff = STATE_LEN - iLBCdec_inst->state_short_len;
if (state_first == 1) {
start_pos = (start-1)*SUBL;
@@ -117,20 +154,25 @@ static void Decode(
StateConstructW(idxForMax, idxVec,
&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 */
/* setup memory */
memset(mem, 0, (CB_MEML-STATE_SHORT_LEN)*sizeof(float));
memcpy(mem+CB_MEML-STATE_SHORT_LEN, decresidual+start_pos,
STATE_SHORT_LEN*sizeof(float));
memset(mem, 0,
(CB_MEML-iLBCdec_inst->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 */
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,
stMemLTbl, diff, CB_NSTAGES);
@@ -139,15 +181,16 @@ static void Decode(
/* create reversed vectors for prediction */
for(k=0; k<diff; k++ ){
for (k=0; k<diff; 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 */
meml_gotten = STATE_SHORT_LEN;
for( k=0; k<meml_gotten; k++){
meml_gotten = iLBCdec_inst->state_short_len;
for (k=0; k<meml_gotten; k++){
mem[CB_MEML-1-k] = decresidual[start_pos + k];
}
memset(mem, 0, (CB_MEML-k)*sizeof(float));
@@ -160,20 +203,22 @@ static void Decode(
/* 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];
}
}
/* counter for predicted subframes */
/* counter for predicted sub-frames */
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 */
@@ -181,7 +226,7 @@ static void Decode(
memcpy(mem+CB_MEML-STATE_LEN, decresidual+(start-1)*SUBL,
STATE_LEN*sizeof(float));
/* loop over subframes to encode */
/* loop over sub-frames to encode */
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;
if( Nback > 0 ){
if ( Nback > 0 ) {
/* 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;
}
for( k=0; k<meml_gotten; k++) {
for (k=0; k<meml_gotten; k++) {
mem[CB_MEML-1-k] = decresidual[(start-1)*SUBL + k];
}
memset(mem, 0, (CB_MEML-k)*sizeof(float));
/* loop over subframes to decode */
for (subframe=0; subframe<Nback; subframe++) {
/* construct decoded vector */
@@ -249,7 +295,7 @@ static void Decode(
/* 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] =
reverseDecresidual[i];
}
@@ -267,24 +313,28 @@ void iLBC_decode(
int mode /* (i) 0: bad packet, PLC,
1: normal */
){
float data[BLOCKL];
float lsfdeq[LPC_FILTERORDER*LPC_N];
float PLCresidual[BLOCKL], PLClpc[LPC_FILTERORDER + 1];
float zeros[BLOCKL], one[LPC_FILTERORDER + 1];
float data[BLOCKL_MAX];
float lsfdeq[LPC_FILTERORDER*LPC_N_MAX];
float PLCresidual[BLOCKL_MAX], PLClpc[LPC_FILTERORDER + 1];
float zeros[BLOCKL_MAX], one[LPC_FILTERORDER + 1];
int k, i, start, idxForMax, pos, lastpart, ulp;
int lag, ilag;
float cc, maxcc;
int idxVec[STATE_LEN];
int check;
int gain_index[NASUB*CB_NSTAGES], 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[NASUB_MAX*CB_NSTAGES],
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];
int state_first;
int last_bit;
unsigned char *pbytes;
float weightdenum[(LPC_FILTERORDER + 1)*NSUB];
float weightdenum[(LPC_FILTERORDER + 1)*NSUB_MAX];
int order_plus_one;
float syntdenum[NSUB*(LPC_FILTERORDER+1)];
float decresidual[BLOCKL];
float syntdenum[NSUB_MAX*(LPC_FILTERORDER+1)];
float decresidual[BLOCKL_MAX];
if (mode>0) { /* the data are good */
@@ -295,27 +345,27 @@ void iLBC_decode(
/* 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;
}
start=0;
state_first=0;
idxForMax=0;
for (k=0; k<STATE_SHORT_LEN; k++) {
for (k=0; k<iLBCdec_inst->state_short_len; k++) {
idxVec[k]=0;
}
for (k=0;k<CB_NSTAGES;k++) {
for (k=0; k<CB_NSTAGES; k++) {
extra_cb_index[k]=0;
}
for (k=0;k<CB_NSTAGES;k++) {
for (k=0; k<CB_NSTAGES; k++) {
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++) {
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++) {
gain_index[i*CB_NSTAGES+k]=0;
}
@@ -326,75 +376,93 @@ void iLBC_decode(
for (ulp=0; ulp<3; ulp++) {
/* LSF */
for (k=0;k<6;k++) {
for (k=0; k<LSF_NSPLIT*iLBCdec_inst->lpc_n; k++){
unpack( &pbytes, &lastpart,
ulp_lsf_bitsTbl[k][ulp], &pos);
iLBCdec_inst->ULP_inst->lsf_bits[k][ulp], &pos);
packcombine(&lsf_i[k], lastpart,
ulp_lsf_bitsTbl[k][ulp]);
iLBCdec_inst->ULP_inst->lsf_bits[k][ulp]);
}
/* Start block info */
unpack( &pbytes, &lastpart,
ulp_start_bitsTbl[ulp], &pos);
iLBCdec_inst->ULP_inst->start_bits[ulp], &pos);
packcombine(&start, lastpart,
ulp_start_bitsTbl[ulp]);
iLBCdec_inst->ULP_inst->start_bits[ulp]);
unpack( &pbytes, &lastpart,
ulp_startfirst_bitsTbl[ulp], &pos);
iLBCdec_inst->ULP_inst->startfirst_bits[ulp], &pos);
packcombine(&state_first, lastpart,
ulp_startfirst_bitsTbl[ulp]);
iLBCdec_inst->ULP_inst->startfirst_bits[ulp]);
unpack( &pbytes, &lastpart,
ulp_scale_bitsTbl[ulp], &pos);
iLBCdec_inst->ULP_inst->scale_bits[ulp], &pos);
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,
ulp_state_bitsTbl[ulp], &pos);
iLBCdec_inst->ULP_inst->state_bits[ulp], &pos);
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,
ulp_extra_cb_indexTbl[k][ulp], &pos);
iLBCdec_inst->ULP_inst->extra_cb_index[k][ulp],
&pos);
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,
ulp_extra_cb_gainTbl[k][ulp], &pos);
iLBCdec_inst->ULP_inst->extra_cb_gain[k][ulp],
&pos);
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++) {
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,
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++) {
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 */
if( (start<1) || (start>5) )
iLBCdec_inst->ULP_inst->cb_gain[i][k][ulp],
&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;
if (mode==1) { /* No bit errors was detected,
@@ -405,36 +473,41 @@ void iLBC_decode(
/* decode the lsf */
SimplelsfDEQ(lsfdeq, lsf_i);
check=LSF_check(lsfdeq, LPC_FILTERORDER, LPC_N);
SimplelsfDEQ(lsfdeq, lsf_i, iLBCdec_inst->lpc_n);
check=LSF_check(lsfdeq, LPC_FILTERORDER,
iLBCdec_inst->lpc_n);
DecoderInterpolateLSF(syntdenum, weightdenum,
lsfdeq, LPC_FILTERORDER, iLBCdec_inst);
Decode(decresidual, start, idxForMax, idxVec,
syntdenum, cb_index, gain_index,
Decode(iLBCdec_inst, decresidual, start, idxForMax,
idxVec, syntdenum, cb_index, gain_index,
extra_cb_index, extra_gain_index,
state_first);
/* preparing the plc for a future loss! */
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);
memcpy(decresidual, PLCresidual, BLOCKL*sizeof(float));
memcpy(decresidual, PLCresidual,
iLBCdec_inst->blockl*sizeof(float));
}
}
if (mode == 0) {
/* 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 */
memset(zeros, 0, BLOCKL*sizeof(float));
memset(zeros, 0, BLOCKL_MAX*sizeof(float));
one[0] = 1;
memset(one+1, 0, LPC_FILTERORDER*sizeof(float));
@@ -443,75 +516,100 @@ void iLBC_decode(
doThePLC(PLCresidual, PLClpc, 1, zeros, one,
(*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;
for (i = 0; i < NSUB; i++) {
for (i = 0; i < iLBCdec_inst->nsub; i++) {
memcpy(syntdenum+(i*order_plus_one), PLClpc,
order_plus_one*sizeof(float));
}
}
if ((*iLBCdec_inst).use_enhancer == 1) {
if (iLBCdec_inst->use_enhancer == 1) {
/* post filtering */
(*iLBCdec_inst).last_lag =
iLBCdec_inst->last_lag =
enhancerInterface(data, decresidual, iLBCdec_inst);
/* 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++) {
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,
syntdenum + (i-2)*(LPC_FILTERORDER+1), SUBL,
(*iLBCdec_inst).syntMem);
iLBCdec_inst->syntMem);
}
}
} else {
/* Find last lag */
lag = 20;
maxcc = xCorrCoef(&decresidual[BLOCKL-ENH_BLOCKL],
&decresidual[BLOCKL-ENH_BLOCKL-lag], ENH_BLOCKL);
maxcc = xCorrCoef(&decresidual[BLOCKL_MAX-ENH_BLOCKL],
&decresidual[BLOCKL_MAX-ENH_BLOCKL-lag], ENH_BLOCKL);
for (ilag=21; ilag<120; ilag++) {
cc = xCorrCoef(&decresidual[BLOCKL-ENH_BLOCKL],
&decresidual[BLOCKL-ENH_BLOCKL-ilag], ENH_BLOCKL);
cc = xCorrCoef(&decresidual[BLOCKL_MAX-ENH_BLOCKL],
&decresidual[BLOCKL_MAX-ENH_BLOCKL-ilag],
ENH_BLOCKL);
if (cc > maxcc) {
maxcc = cc;
lag = ilag;
}
}
(*iLBCdec_inst).last_lag = lag;
iLBCdec_inst->last_lag = lag;
/* copy data and run synthesis filter */
memcpy(data, decresidual, BLOCKL*sizeof(float));
for (i=0; i < NSUB; i++) {
memcpy(data, decresidual,
iLBCdec_inst->blockl*sizeof(float));
for (i=0; i < iLBCdec_inst->nsub; i++) {
syntFilter(data + i*SUBL,
syntdenum + i*(LPC_FILTERORDER+1), SUBL,
(*iLBCdec_inst).syntMem);
iLBCdec_inst->syntMem);
}
}
/* high pass filtering on output if desired, otherwise
copy to out */
/*hpOutput(data, BLOCKL, decblock, (*iLBCdec_inst).hpomem);*/
memcpy(decblock,data,BLOCKL*sizeof(float));
hpOutput(data, iLBCdec_inst->blockl,
decblock,iLBCdec_inst->hpomem);
memcpy((*iLBCdec_inst).old_syntdenum, syntdenum,
NSUB*(LPC_FILTERORDER+1)*sizeof(float));
/* memcpy(decblock,data,iLBCdec_inst->blockl*sizeof(float));*/
memcpy(iLBCdec_inst->old_syntdenum, syntdenum,
iLBCdec_inst->nsub*(LPC_FILTERORDER+1)*sizeof(float));
iLBCdec_inst->prev_enh_pl=0;
if (mode==0) { /* PLC was used */
iLBCdec_inst->prev_enh_pl=1;
}

View File

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

View File

@@ -5,9 +5,8 @@
iLBC_define.h
Copyright (c) 2001,
Global IP Sound AB.
All rights reserved.
Copyright (C) The Internet Society (2004).
All Rights Reserved.
******************************************************************/
#include <string.h>
@@ -18,12 +17,19 @@
/* general codec settings */
#define FS (float)8000.0
#define BLOCKL 240
#define NSUB 6
#define NASUB 4
#define BLOCKL_20MS 160
#define BLOCKL_30MS 240
#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 STATE_LEN 80
#define STATE_SHORT_LEN 58
#define STATE_SHORT_LEN_30MS 58
#define STATE_SHORT_LEN_20MS 57
/* LPC settings */
@@ -31,13 +37,16 @@
#define LPC_CHIRP_SYNTDENUM (float)0.9025
#define LPC_CHIRP_WEIGHTDENUM (float)0.4222
#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_BW (float)60.0
#define LPC_WN (float)1.0001
#define LSF_NSPLIT 3
#define LSF_NUMBER_OF_STEPS 4
#define LPC_HALFORDER LPC_FILTERORDER/2
#define LPC_HALFORDER (LPC_FILTERORDER/2)
/* cb settings */
@@ -47,7 +56,7 @@
#define CB_FILTERLEN 2*4
#define CB_HALFFILTERLEN 4
#define CB_RESRANGE 34
#define CB_MAXGAIN (float) 1.3
#define CB_MAXGAIN (float)1.3
/* enhancer */
@@ -57,29 +66,21 @@
in said second sequence */
#define ENH_SLOP 2 /* max difference estimated and
correct pitch period */
#define ENH_PLOCSL 20 /* pitch-estimates and
pitch-locations buffer length */
#define ENH_PLOCSL 20 /* pitch-estimates and pitch-
locations buffer length */
#define ENH_OVERHANG 2
#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_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_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_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 */
#define FILTERORDER_DS 7
@@ -88,13 +89,17 @@
/* 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 BYTE_LEN 8
#define ULP_CLASSES 3
/* help parameters */
#define FLOAT_MAX (float)1.0e37
#define EPS (float)2.220446049250313e-016
#define PI (float)3.14159265358979323846
@@ -103,9 +108,34 @@
#define TWO_PI (float)6.283185307
#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 */
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 */
float anaMem[LPC_FILTERORDER];
@@ -114,7 +144,7 @@ typedef struct iLBC_Enc_Inst_t_ {
float lsfdeqold[LPC_FILTERORDER];
/* signal buffer for LP analysis */
float lpc_buffer[LPC_LOOKBACK + BLOCKL];
float lpc_buffer[LPC_LOOKBACK + BLOCKL_MAX];
/* state of input HP filter */
float hpimem[4];
@@ -123,6 +153,20 @@ typedef struct iLBC_Enc_Inst_t_ {
/* type definition decoder instance */
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 */
float syntMem[LPC_FILTERORDER];
@@ -134,13 +178,13 @@ typedef struct iLBC_Dec_Inst_t_ {
/* PLC state information */
int prevLag, consPLICount, prevPLI, prev_enh_pl;
float prevGain, prevLpc[LPC_FILTERORDER+1];
float prevResidual[NSUB*SUBL];
float energy;
float prevLpc[LPC_FILTERORDER+1];
float prevResidual[NSUB_MAX*SUBL];
float per;
unsigned long seed;
/* previous synthesis filter parameters */
float old_syntdenum[(LPC_FILTERORDER + 1)*NSUB];
float old_syntdenum[(LPC_FILTERORDER + 1)*NSUB_MAX];
/* state of output HP filter */
float hpomem[4];

View File

@@ -5,13 +5,13 @@
iLBC_encode.c
Copyright (c) 2001,
Global IP Sound AB.
All rights reserved.
Copyright (C) The Internet Society (2004).
All Rights Reserved.
******************************************************************/
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include "iLBC_define.h"
@@ -22,7 +22,6 @@
#include "helpfun.h"
#include "constants.h"
#include "packing.h"
#include "iLBC_encode.h"
#include "iCBSearch.h"
#include "iCBConstruct.h"
#include "hpInput.h"
@@ -33,9 +32,40 @@
* Initiation of encoder instance.
*---------------------------------------------------------------*/
short initEncode( /* (o) Number of bytes encoded */
iLBC_Enc_Inst_t *iLBCenc_inst /* (i/o) Encoder instance */
short initEncode( /* (o) Number of bytes
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,
LPC_FILTERORDER*sizeof(float));
memcpy((*iLBCenc_inst).lsfold, lsfmeanTbl,
@@ -43,10 +73,10 @@ short initEncode( /* (o) Number of bytes encoded */
memcpy((*iLBCenc_inst).lsfdeqold, lsfmeanTbl,
LPC_FILTERORDER*sizeof(float));
memset((*iLBCenc_inst).lpc_buffer, 0,
LPC_LOOKBACK*sizeof(float));
(LPC_LOOKBACK+BLOCKL_MAX)*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(
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
state */
){
float data[BLOCKL];
float residual[BLOCKL], reverseResidual[BLOCKL];
float data[BLOCKL_MAX];
float residual[BLOCKL_MAX], reverseResidual[BLOCKL_MAX];
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 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;
int diff, start_pos, state_first;
float en1, en2;
int index, ulp, firstpart;
int subcount, subframe;
float weightState[LPC_FILTERORDER];
float syntdenum[NSUB*(LPC_FILTERORDER+1)];
float weightdenum[NSUB*(LPC_FILTERORDER+1)];
float decresidual[BLOCKL];
float syntdenum[NSUB_MAX*(LPC_FILTERORDER+1)];
float weightdenum[NSUB_MAX*(LPC_FILTERORDER+1)];
float decresidual[BLOCKL_MAX];
/* high pass filtering of input signal if such is not done
prior to calling this function */
/*hpInput(block, BLOCKL, data, (*iLBCenc_inst).hpimem);*/
hpInput(block, iLBCenc_inst->blockl,
data, (*iLBCenc_inst).hpimem);
/* otherwise simply copy */
memcpy(data,block,BLOCKL*sizeof(float));
/*memcpy(data,block,iLBCenc_inst->blockl*sizeof(float));*/
/* LPC of hp filtered input data */
LPCencode(syntdenum, weightdenum, lsf_i, data,
iLBCenc_inst);
LPCencode(syntdenum, weightdenum, lsf_i, data, iLBCenc_inst);
/* 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)],
SUBL, &residual[n*SUBL], (*iLBCenc_inst).anaMem);
SUBL, &residual[n*SUBL], iLBCenc_inst->anaMem);
}
/* find state location */
start = FrameClassify(residual);
start = FrameClassify(iLBCenc_inst, residual);
/* check if state should be in first or last part of the
two subframes */
diff = STATE_LEN - STATE_SHORT_LEN;
diff = STATE_LEN - iLBCenc_inst->state_short_len;
en1 = 0;
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];
}
en2 = 0;
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];
}
if (en1 > en2) {
state_first = 1;
start_pos = (start-1)*SUBL;
@@ -130,14 +167,14 @@ void iLBC_encode(
/* scalar quantization of state */
StateSearchW(&residual[start_pos],
StateSearchW(iLBCenc_inst, &residual[start_pos],
&syntdenum[(start-1)*(LPC_FILTERORDER+1)],
&weightdenum[(start-1)*(LPC_FILTERORDER+1)], &idxForMax,
idxVec, STATE_SHORT_LEN, state_first);
idxVec, iLBCenc_inst->state_short_len, state_first);
StateConstructW(idxForMax, idxVec,
&syntdenum[(start-1)*(LPC_FILTERORDER+1)],
&decresidual[start_pos], STATE_SHORT_LEN);
&decresidual[start_pos], iLBCenc_inst->state_short_len);
/* predictive quantization in state */
@@ -145,74 +182,82 @@ void iLBC_encode(
/* setup memory */
memset(mem, 0, (CB_MEML-STATE_SHORT_LEN)*sizeof(float));
memcpy(mem+CB_MEML-STATE_SHORT_LEN, decresidual+start_pos,
STATE_SHORT_LEN*sizeof(float));
memset(mem, 0,
(CB_MEML-iLBCenc_inst->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));
/* encode subframes */
/* encode sub-frames */
iCBSearch(extra_cb_index, extra_gain_index,
&residual[start_pos+STATE_SHORT_LEN],
iCBSearch(iLBCenc_inst, extra_cb_index, extra_gain_index,
&residual[start_pos+iLBCenc_inst->state_short_len],
mem+CB_MEML-stMemLTbl,
stMemLTbl, diff, CB_NSTAGES,
&weightdenum[start*(LPC_FILTERORDER+1)], weightState, 0);
&weightdenum[start*(LPC_FILTERORDER+1)],
weightState, 0);
/* construct decoded vector */
iCBConstruct(&decresidual[start_pos+STATE_SHORT_LEN],
extra_cb_index, extra_gain_index, mem+CB_MEML-stMemLTbl,
iCBConstruct(
&decresidual[start_pos+iLBCenc_inst->state_short_len],
extra_cb_index, extra_gain_index,
mem+CB_MEML-stMemLTbl,
stMemLTbl, diff, CB_NSTAGES);
}
else { /* put adaptive part in the beginning */
/* create reversed vectors for prediction */
for(k=0; k<diff; k++ ){
reverseResidual[k] = residual[(start+1)*SUBL -1
-(k+STATE_SHORT_LEN)];
for (k=0; k<diff; k++) {
reverseResidual[k] = residual[(start+1)*SUBL-1
-(k+iLBCenc_inst->state_short_len)];
}
/* setup memory */
meml_gotten = STATE_SHORT_LEN;
for( k=0; k<meml_gotten; k++){
meml_gotten = iLBCenc_inst->state_short_len;
for (k=0; k<meml_gotten; k++) {
mem[CB_MEML-1-k] = decresidual[start_pos + k];
}
memset(mem, 0, (CB_MEML-k)*sizeof(float));
memset(weightState, 0, LPC_FILTERORDER*sizeof(float));
/* encode subframes */
/* encode sub-frames */
iCBSearch(extra_cb_index, extra_gain_index,
reverseResidual, mem+CB_MEML-stMemLTbl, stMemLTbl, diff,
CB_NSTAGES, &weightdenum[(start-1)*(LPC_FILTERORDER+1)],
iCBSearch(iLBCenc_inst, extra_cb_index, extra_gain_index,
reverseResidual, mem+CB_MEML-stMemLTbl, stMemLTbl,
diff, CB_NSTAGES,
&weightdenum[(start-1)*(LPC_FILTERORDER+1)],
weightState, 0);
/* construct decoded vector */
iCBConstruct(reverseDecresidual, extra_cb_index,
extra_gain_index, mem+CB_MEML-stMemLTbl, stMemLTbl, diff,
CB_NSTAGES);
extra_gain_index, mem+CB_MEML-stMemLTbl, stMemLTbl,
diff, CB_NSTAGES);
/* 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];
}
}
/* counter for predicted subframes */
/* counter for predicted sub-frames */
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 */
@@ -221,18 +266,21 @@ void iLBC_encode(
STATE_LEN*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++) {
/* encode subframe */
/* encode sub-frame */
iCBSearch(cb_index+subcount*CB_NSTAGES,
iCBSearch(iLBCenc_inst, cb_index+subcount*CB_NSTAGES,
gain_index+subcount*CB_NSTAGES,
&residual[(start+1+subframe)*SUBL],
mem+CB_MEML-memLfTbl[subcount], memLfTbl[subcount],
SUBL, CB_NSTAGES,
&weightdenum[(start+1+subframe)*(LPC_FILTERORDER+1)],
mem+CB_MEML-memLfTbl[subcount],
memLfTbl[subcount], SUBL, CB_NSTAGES,
&weightdenum[(start+1+subframe)*
(LPC_FILTERORDER+1)],
weightState, subcount+1);
/* construct decoded vector */
@@ -240,8 +288,8 @@ void iLBC_encode(
iCBConstruct(&decresidual[(start+1+subframe)*SUBL],
cb_index+subcount*CB_NSTAGES,
gain_index+subcount*CB_NSTAGES,
mem+CB_MEML-memLfTbl[subcount], memLfTbl[subcount],
SUBL, CB_NSTAGES);
mem+CB_MEML-memLfTbl[subcount],
memLfTbl[subcount], SUBL, CB_NSTAGES);
/* update memory */
@@ -256,17 +304,17 @@ void iLBC_encode(
}
/* backward prediction of subframes */
/* backward prediction of sub-frames */
Nback = start-1;
if( Nback > 0 ){
if ( Nback > 0 ) {
/* create reverse order vectors */
for( n=0; n<Nback; n++ ){
for( k=0; k<SUBL; k++ ){
for (n=0; n<Nback; n++) {
for (k=0; k<SUBL; k++) {
reverseResidual[n*SUBL+k] =
residual[(start-1)*SUBL-1-n*SUBL-k];
reverseDecresidual[n*SUBL+k] =
@@ -274,32 +322,35 @@ void iLBC_encode(
}
}
/* 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;
}
for( k=0; k<meml_gotten; k++) {
for (k=0; k<meml_gotten; k++) {
mem[CB_MEML-1-k] = decresidual[(start-1)*SUBL + k];
}
memset(mem, 0, (CB_MEML-k)*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++) {
/* encode subframe */
/* encode sub-frame */
iCBSearch(cb_index+subcount*CB_NSTAGES,
iCBSearch(iLBCenc_inst, cb_index+subcount*CB_NSTAGES,
gain_index+subcount*CB_NSTAGES,
&reverseResidual[subframe*SUBL],
mem+CB_MEML-memLfTbl[subcount], memLfTbl[subcount],
SUBL, CB_NSTAGES,
&weightdenum[(start-2-subframe)*(LPC_FILTERORDER+1)],
mem+CB_MEML-memLfTbl[subcount],
memLfTbl[subcount], SUBL, CB_NSTAGES,
&weightdenum[(start-2-subframe)*
(LPC_FILTERORDER+1)],
weightState, subcount+1);
/* construct decoded vector */
@@ -324,8 +375,10 @@ void iLBC_encode(
/* 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] =
reverseDecresidual[i];
}
}
@@ -344,104 +397,117 @@ void iLBC_encode(
for (ulp=0; ulp<3; ulp++) {
/* 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],
ulp_lsf_bitsTbl[k][ulp],
ulp_lsf_bitsTbl[k][ulp]+
ulp_lsf_bitsTbl[k][ulp+1]+
ulp_lsf_bitsTbl[k][ulp+2]);
iLBCenc_inst->ULP_inst->lsf_bits[k][ulp],
iLBCenc_inst->ULP_inst->lsf_bits[k][ulp]+
iLBCenc_inst->ULP_inst->lsf_bits[k][ulp+1]+
iLBCenc_inst->ULP_inst->lsf_bits[k][ulp+2]);
dopack( &pbytes, firstpart,
ulp_lsf_bitsTbl[k][ulp], &pos);
iLBCenc_inst->ULP_inst->lsf_bits[k][ulp], &pos);
}
/* Start block info */
packsplit(&start, &firstpart, &start,
ulp_start_bitsTbl[ulp],
ulp_start_bitsTbl[ulp]+
ulp_start_bitsTbl[ulp+1]+
ulp_start_bitsTbl[ulp+2]);
iLBCenc_inst->ULP_inst->start_bits[ulp],
iLBCenc_inst->ULP_inst->start_bits[ulp]+
iLBCenc_inst->ULP_inst->start_bits[ulp+1]+
iLBCenc_inst->ULP_inst->start_bits[ulp+2]);
dopack( &pbytes, firstpart,
ulp_start_bitsTbl[ulp], &pos);
iLBCenc_inst->ULP_inst->start_bits[ulp], &pos);
packsplit(&state_first, &firstpart, &state_first,
ulp_startfirst_bitsTbl[ulp],
ulp_startfirst_bitsTbl[ulp]+
ulp_startfirst_bitsTbl[ulp+1]+
ulp_startfirst_bitsTbl[ulp+2]);
iLBCenc_inst->ULP_inst->startfirst_bits[ulp],
iLBCenc_inst->ULP_inst->startfirst_bits[ulp]+
iLBCenc_inst->ULP_inst->startfirst_bits[ulp+1]+
iLBCenc_inst->ULP_inst->startfirst_bits[ulp+2]);
dopack( &pbytes, firstpart,
ulp_startfirst_bitsTbl[ulp], &pos);
iLBCenc_inst->ULP_inst->startfirst_bits[ulp], &pos);
packsplit(&idxForMax, &firstpart, &idxForMax,
ulp_scale_bitsTbl[ulp], ulp_scale_bitsTbl[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]+
iLBCenc_inst->ULP_inst->scale_bits[ulp+1]+
iLBCenc_inst->ULP_inst->scale_bits[ulp+2]);
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,
ulp_state_bitsTbl[ulp],
ulp_state_bitsTbl[ulp]+
ulp_state_bitsTbl[ulp+1]+
ulp_state_bitsTbl[ulp+2]);
iLBCenc_inst->ULP_inst->state_bits[ulp],
iLBCenc_inst->ULP_inst->state_bits[ulp]+
iLBCenc_inst->ULP_inst->state_bits[ulp+1]+
iLBCenc_inst->ULP_inst->state_bits[ulp+2]);
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++) {
packsplit(extra_cb_index+k, &firstpart,
extra_cb_index+k,
ulp_extra_cb_indexTbl[k][ulp],
ulp_extra_cb_indexTbl[k][ulp]+
ulp_extra_cb_indexTbl[k][ulp+1]+
ulp_extra_cb_indexTbl[k][ulp+2]);
iLBCenc_inst->ULP_inst->extra_cb_index[k][ulp],
iLBCenc_inst->ULP_inst->extra_cb_index[k][ulp]+
iLBCenc_inst->ULP_inst->extra_cb_index[k][ulp+1]+
iLBCenc_inst->ULP_inst->extra_cb_index[k][ulp+2]);
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++) {
packsplit(extra_gain_index+k, &firstpart,
extra_gain_index+k,
ulp_extra_cb_gainTbl[k][ulp],
ulp_extra_cb_gainTbl[k][ulp]+
ulp_extra_cb_gainTbl[k][ulp+1]+
ulp_extra_cb_gainTbl[k][ulp+2]);
iLBCenc_inst->ULP_inst->extra_cb_gain[k][ulp],
iLBCenc_inst->ULP_inst->extra_cb_gain[k][ulp]+
iLBCenc_inst->ULP_inst->extra_cb_gain[k][ulp+1]+
iLBCenc_inst->ULP_inst->extra_cb_gain[k][ulp+2]);
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++) {
packsplit(cb_index+i*CB_NSTAGES+k, &firstpart,
cb_index+i*CB_NSTAGES+k,
ulp_cb_indexTbl[i][k][ulp],
ulp_cb_indexTbl[i][k][ulp]+
ulp_cb_indexTbl[i][k][ulp+1]+
ulp_cb_indexTbl[i][k][ulp+2]);
iLBCenc_inst->ULP_inst->cb_index[i][k][ulp],
iLBCenc_inst->ULP_inst->cb_index[i][k][ulp]+
iLBCenc_inst->ULP_inst->cb_index[i][k][ulp+1]+
iLBCenc_inst->ULP_inst->cb_index[i][k][ulp+2]);
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++) {
packsplit(gain_index+i*CB_NSTAGES+k, &firstpart,
gain_index+i*CB_NSTAGES+k,
ulp_cb_gainTbl[i][k][ulp],
ulp_cb_gainTbl[i][k][ulp]+
ulp_cb_gainTbl[i][k][ulp+1]+
ulp_cb_gainTbl[i][k][ulp+2]);
iLBCenc_inst->ULP_inst->cb_gain[i][k][ulp],
iLBCenc_inst->ULP_inst->cb_gain[i][k][ulp]+
iLBCenc_inst->ULP_inst->cb_gain[i][k][ulp+1]+
iLBCenc_inst->ULP_inst->cb_gain[i][k][ulp+2]);
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);
}

View File

@@ -5,9 +5,8 @@
iLBC_encode.h
Copyright (c) 2001,
Global IP Sound AB.
All rights reserved.
Copyright (C) The Internet Society (2004).
All Rights Reserved.
******************************************************************/
@@ -16,13 +15,18 @@
#include "iLBC_define.h"
short initEncode( /* (o) Number of bytes encoded */
iLBC_Enc_Inst_t *iLBCenc_inst /* (i/o) Encoder instance */
short initEncode( /* (o) Number of bytes
encoded */
iLBC_Enc_Inst_t *iLBCenc_inst, /* (i/o) Encoder instance */
int mode /* (i) frame size mode */
);
void iLBC_encode(
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
state */
);
@@ -30,3 +34,4 @@ void iLBC_encode(
#endif

View File

@@ -5,9 +5,8 @@
lsf.c
Copyright (c) 2001,
Global IP Sound AB.
All rights reserved.
Copyright (C) The Internet Society (2004).
All Rights Reserved.
******************************************************************/
@@ -15,7 +14,6 @@
#include <math.h>
#include "iLBC_define.h"
#include "lsf.h"
/*----------------------------------------------------------------*
* conversion from lpc coefficients to lsf coefficients
@@ -34,6 +32,8 @@ void a2lsf(
float p[LPC_HALFORDER];
float q[LPC_HALFORDER];
float p_pre[LPC_HALFORDER];
float q_pre[LPC_HALFORDER];
float old_p, old_q, *old;
float *pq_coef;
@@ -41,7 +41,7 @@ void a2lsf(
int i;
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]);
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
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
alternatively solve the roots for the two LSP equations. */
@@ -88,6 +88,8 @@ void a2lsf(
for (step_idx = 0, step = steps[step_idx];
step_idx < LSF_NUMBER_OF_STEPS;){
/* cos(10piw) + pq(0)cos(8piw) + pq(1)cos(6piw) +
pq(2)cos(4piw) + pq(3)cod(2piw) + pq(4) */
@@ -142,10 +144,12 @@ void a2lsf(
*old = hlp5;
omega += step;
}
}
}
for (i = 0; i < LPC_FILTERORDER; i++) {
for (i = 0; i<LPC_FILTERORDER; i++) {
freq[i] = freq[i] * TWO_PI;
}
}
@@ -161,10 +165,12 @@ void lsf2a(
int i, j;
float hlp;
float p[LPC_HALFORDER], q[LPC_HALFORDER];
float a[LPC_HALFORDER + 1], a1[LPC_HALFORDER], a2[LPC_HALFORDER];
float b[LPC_HALFORDER + 1], b1[LPC_HALFORDER], b2[LPC_HALFORDER];
float a[LPC_HALFORDER + 1], a1[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;
}
@@ -191,9 +197,11 @@ void lsf2a(
hlp = (freq[LPC_FILTERORDER - 1] - freq[0]) /
(float) (LPC_FILTERORDER - 1);
for (i = 1; i < LPC_FILTERORDER; i++) {
for (i=1; i<LPC_FILTERORDER; i++) {
freq[i] = freq[i - 1] + hlp;
}
}
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
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]);
q[i] = (float)cos(TWO_PI * freq[2 * i + 1]);
}
@@ -217,7 +225,7 @@ void lsf2a(
a[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];
b[i + 1] = b[i] - 2 * q[i] * b1[i] + b2[i];
a2[i] = a1[i];
@@ -226,7 +234,7 @@ void lsf2a(
b1[i] = b[i];
}
for (j = 0; j < LPC_FILTERORDER; j++){
for (j=0; j<LPC_FILTERORDER; j++) {
if (j == 0) {
a[0] = 0.25;
@@ -235,7 +243,7 @@ void lsf2a(
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];
b[i + 1] = b[i] - 2 * q[i] * b1[i] + b2[i];
a2[i] = a1[i];
@@ -248,6 +256,8 @@ void lsf2a(
}
a_coef[0] = 1.0;
}

View File

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

View File

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

View File

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

View File

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

View File

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