Update to new iLBC codec

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

View File

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

View File

@@ -1,101 +1,109 @@
/****************************************************************** /******************************************************************
iLBC Speech Coder ANSI-C Source Code iLBC Speech Coder ANSI-C Source Code
FrameClassify.c FrameClassify.c
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/
******************************************************************/
#include "iLBC_define.h"
#include "iLBC_define.h"
#include "FrameClassify.h" /*---------------------------------------------------------------*
* Classification of subframes to localize start state
/*----------------------------------------------------------------* *--------------------------------------------------------------*/
* Classification of subframes to localize start state
*---------------------------------------------------------------*/ int FrameClassify( /* index to the max-energy sub-frame */
iLBC_Enc_Inst_t *iLBCenc_inst,
int FrameClassify( /* index to the max-energy sub frame */ /* (i/o) the encoder state structure */
float *residual /* (i) lpc residual signal */ float *residual /* (i) lpc residual signal */
){ ) {
float max_ssqEn, fssqEn[NSUB], bssqEn[NSUB], *pp; float max_ssqEn, fssqEn[NSUB_MAX], bssqEn[NSUB_MAX], *pp;
int n, l, max_ssqEn_n; int n, l, max_ssqEn_n;
const float ssqEn_win[NSUB-1]={(float)0.8,(float)0.9, const float ssqEn_win[NSUB_MAX-1]={(float)0.8,(float)0.9,
(float)1.0,(float)0.9,(float)0.8}; (float)1.0,(float)0.9,(float)0.8};
const float sampEn_win[5]={(float)1.0/(float)6.0, const float sampEn_win[5]={(float)1.0/(float)6.0,
(float)2.0/(float)6.0, (float)3.0/(float)6.0, (float)2.0/(float)6.0, (float)3.0/(float)6.0,
(float)4.0/(float)6.0, (float)5.0/(float)6.0}; (float)4.0/(float)6.0, (float)5.0/(float)6.0};
/* init the front and back energies to zero */ /* init the front and back energies to zero */
memset(fssqEn, 0, NSUB*sizeof(float)); memset(fssqEn, 0, NSUB_MAX*sizeof(float));
memset(bssqEn, 0, NSUB*sizeof(float)); memset(bssqEn, 0, NSUB_MAX*sizeof(float));
/* Calculate front of first seqence */ /* Calculate front of first seqence */
n=0; n=0;
pp=residual; pp=residual;
for(l=0;l<5;l++){
fssqEn[n] += sampEn_win[l] * (*pp) * (*pp);
pp++; for (l=0; l<5; l++) {
} fssqEn[n] += sampEn_win[l] * (*pp) * (*pp);
for(l=5;l<SUBL;l++){ pp++;
fssqEn[n] += (*pp) * (*pp); }
pp++; 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++) { /* Calculate front and back of all middle sequences */
pp=residual+n*SUBL;
for(l=0;l<5;l++){ for (n=1; n<iLBCenc_inst->nsub-1; n++) {
fssqEn[n] += sampEn_win[l] * (*pp) * (*pp); pp=residual+n*SUBL;
bssqEn[n] += (*pp) * (*pp); for (l=0; l<5; l++) {
pp++; fssqEn[n] += sampEn_win[l] * (*pp) * (*pp);
} bssqEn[n] += (*pp) * (*pp);
for(l=5;l<SUBL-5;l++){ pp++;
fssqEn[n] += (*pp) * (*pp); }
bssqEn[n] += (*pp) * (*pp); for (l=5; l<SUBL-5; l++) {
pp++; fssqEn[n] += (*pp) * (*pp);
} bssqEn[n] += (*pp) * (*pp);
for(l=SUBL-5;l<SUBL;l++){ pp++;
fssqEn[n] += (*pp) * (*pp); }
bssqEn[n] += sampEn_win[SUBL-l-1] * (*pp) * (*pp); for (l=SUBL-5; l<SUBL; l++) {
pp++; fssqEn[n] += (*pp) * (*pp);
} bssqEn[n] += sampEn_win[SUBL-l-1] * (*pp) * (*pp);
} pp++;
}
/* Calculate back of last seqence */ }
n=NSUB-1; /* Calculate back of last seqence */
pp=residual+n*SUBL;
for(l=0;l<SUBL-5;l++){ n=iLBCenc_inst->nsub-1;
bssqEn[n] += (*pp) * (*pp); pp=residual+n*SUBL;
pp++; for (l=0; l<SUBL-5; l++) {
} bssqEn[n] += (*pp) * (*pp);
for(l=SUBL-5;l<SUBL;l++){ pp++;
bssqEn[n] += sampEn_win[SUBL-l-1] * (*pp) * (*pp); }
pp++; for (l=SUBL-5; l<SUBL; l++) {
} bssqEn[n] += sampEn_win[SUBL-l-1] * (*pp) * (*pp);
pp++;
/* find the index to the weighted 80 sample with }
most energy */
/* find the index to the weighted 80 sample with
max_ssqEn=(fssqEn[0]+bssqEn[1])*ssqEn_win[0]; most energy */
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[n-1]+bssqEn[n]) * max_ssqEn=(fssqEn[0]+bssqEn[1])*ssqEn_win[l];
ssqEn_win[n-1]; max_ssqEn_n=1;
max_ssqEn_n=n; for (n=2; n<iLBCenc_inst->nsub; n++) {
}
} l++;
return max_ssqEn_n;
} if ((fssqEn[n-1]+bssqEn[n])*ssqEn_win[l] > max_ssqEn) {
max_ssqEn=(fssqEn[n-1]+bssqEn[n]) *
ssqEn_win[l];
max_ssqEn_n=n;
}
}
return max_ssqEn_n;
}

View File

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

View File

@@ -1,122 +1,151 @@
/****************************************************************** /******************************************************************
iLBC Speech Coder ANSI-C Source Code iLBC Speech Coder ANSI-C Source Code
LPC_decode.c LPC_decode.c
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/
******************************************************************/
#include <math.h>
#include <math.h> #include <string.h>
#include <string.h>
#include "helpfun.h"
#include "helpfun.h" #include "lsf.h"
#include "lsf.h" #include "iLBC_define.h"
#include "iLBC_define.h" #include "constants.h"
#include "constants.h"
#include "LPCdecode.h" /*---------------------------------------------------------------*
* interpolation of lsf coefficients for the decoder
/*----------------------------------------------------------------* *--------------------------------------------------------------*/
* interpolation of lsf coefficients for the decoder
*---------------------------------------------------------------*/ void LSFinterpolate2a_dec(
float *a, /* (o) lpc coefficients for a sub-frame */
void LSFinterpolate2a_dec( float *lsf1, /* (i) first lsf coefficient vector */
float *a, /* (o) lpc coefficients for a sub frame */
float *lsf1, /* (i) first lsf coefficient vector */
float *lsf2, /* (i) second lsf coefficient vector */ float *lsf2, /* (i) second lsf coefficient vector */
float coef, /* (i) interpolation weight */ float coef, /* (i) interpolation weight */
int length /* (i) length of lsf vectors */ int length /* (i) length of lsf vectors */
){ ){
float lsftmp[LPC_FILTERORDER]; float lsftmp[LPC_FILTERORDER];
interpolate(lsftmp, lsf1, lsf2, coef, length); interpolate(lsftmp, lsf1, lsf2, coef, length);
lsf2a(a, lsftmp); lsf2a(a, lsftmp);
} }
/*----------------------------------------------------------------* /*---------------------------------------------------------------*
* obtain dequantized lsf coefficients from quantization index * obtain dequantized lsf coefficients from quantization index
*---------------------------------------------------------------*/ *--------------------------------------------------------------*/
void SimplelsfDEQ( void SimplelsfDEQ(
float *lsfdeq, /* (o) dequantized lsf coefficients */ float *lsfdeq, /* (o) dequantized lsf coefficients */
int *index /* (i) quantization index */ int *index, /* (i) quantization index */
){ int lpc_n /* (i) number of LPCs */
int i,j, pos, cb_pos; ){
int i, j, pos, cb_pos;
/* decode first LSF */
/* decode first LSF */
pos = 0;
cb_pos = 0; pos = 0;
for (i = 0; i < LSF_NSPLIT; i++) { cb_pos = 0;
for (j = 0; j < dim_lsfCbTbl[i]; j++) { for (i = 0; i < LSF_NSPLIT; i++) {
lsfdeq[pos + j] = lsfCbTbl[cb_pos + for (j = 0; j < dim_lsfCbTbl[i]; j++) {
(long)(index[i])*dim_lsfCbTbl[i] + j]; lsfdeq[pos + j] = lsfCbTbl[cb_pos +
} (long)(index[i])*dim_lsfCbTbl[i] + j];
pos += dim_lsfCbTbl[i]; }
cb_pos += size_lsfCbTbl[i]*dim_lsfCbTbl[i]; pos += dim_lsfCbTbl[i];
} cb_pos += size_lsfCbTbl[i]*dim_lsfCbTbl[i];
}
/* decode last LSF */
if (lpc_n>1) {
pos = 0;
cb_pos = 0; /* decode last LSF */
for (i = 0; i < LSF_NSPLIT; i++) {
for (j = 0; j < dim_lsfCbTbl[i]; j++) { pos = 0;
lsfdeq[LPC_FILTERORDER + pos + j] = lsfCbTbl[cb_pos + cb_pos = 0;
(long)(index[LSF_NSPLIT + i])*dim_lsfCbTbl[i] + j]; for (i = 0; i < LSF_NSPLIT; i++) {
} for (j = 0; j < dim_lsfCbTbl[i]; j++) {
pos += dim_lsfCbTbl[i]; lsfdeq[LPC_FILTERORDER + pos + j] =
cb_pos += size_lsfCbTbl[i]*dim_lsfCbTbl[i]; lsfCbTbl[cb_pos +
} (long)(index[LSF_NSPLIT + i])*
} dim_lsfCbTbl[i] + j];
}
/*----------------------------------------------------------------* pos += dim_lsfCbTbl[i];
* obtain synthesis and weighting filters form lsf coefficients cb_pos += size_lsfCbTbl[i]*dim_lsfCbTbl[i];
*---------------------------------------------------------------*/ }
}
void DecoderInterpolateLSF( }
float *syntdenum, /* (o) synthesis filter coefficients */
float *weightdenum, /* (o) weighting denumerator /*----------------------------------------------------------------*
coefficients */
float *lsfdeq, /* (i) dequantized lsf coefficients */
int length, /* (i) length of lsf coefficient vector */ * obtain synthesis and weighting filters form lsf coefficients
iLBC_Dec_Inst_t *iLBCdec_inst *---------------------------------------------------------------*/
/* (i) the decoder state structure */
){ void DecoderInterpolateLSF(
int i, pos, lp_length; float *syntdenum, /* (o) synthesis filter coefficients */
float lp[LPC_FILTERORDER + 1], *lsfdeq2; float *weightdenum, /* (o) weighting denumerator
coefficients */
lsfdeq2 = lsfdeq + length; float *lsfdeq, /* (i) dequantized lsf coefficients */
lp_length = length + 1; int length, /* (i) length of lsf coefficient vector */
iLBC_Dec_Inst_t *iLBCdec_inst
/* subframe 1: Interpolation between old and first */ /* (i) the decoder state structure */
){
LSFinterpolate2a_dec(lp, (*iLBCdec_inst).lsfdeqold, lsfdeq, int i, pos, lp_length;
lsf_weightTbl[0], length); float lp[LPC_FILTERORDER + 1], *lsfdeq2;
memcpy(syntdenum,lp,lp_length*sizeof(float));
bwexpand(weightdenum, lp, LPC_CHIRP_WEIGHTDENUM, lp_length); lsfdeq2 = lsfdeq + length;
lp_length = length + 1;
/* subframes 2 to 6: interpolation between first and last
LSF */ if (iLBCdec_inst->mode==30) {
/* sub-frame 1: Interpolation between old and first */
pos = lp_length;
for (i = 1; i < 6; i++) { LSFinterpolate2a_dec(lp, iLBCdec_inst->lsfdeqold, lsfdeq,
LSFinterpolate2a_dec(lp, lsfdeq, lsfdeq2, lsf_weightTbl[i], lsf_weightTbl_30ms[0], length);
length); memcpy(syntdenum,lp,lp_length*sizeof(float));
memcpy(syntdenum + pos,lp,lp_length*sizeof(float)); bwexpand(weightdenum, lp, LPC_CHIRP_WEIGHTDENUM,
bwexpand(weightdenum + pos, lp, lp_length);
LPC_CHIRP_WEIGHTDENUM, lp_length);
pos += lp_length; /* sub-frames 2 to 6: interpolation between first
} and last LSF */
/* update memory */ pos = lp_length;
for (i = 1; i < 6; i++) {
memcpy((*iLBCdec_inst).lsfdeqold, lsfdeq2, length*sizeof(float)); LSFinterpolate2a_dec(lp, lsfdeq, lsfdeq2,
lsf_weightTbl_30ms[i], length);
} memcpy(syntdenum + pos,lp,lp_length*sizeof(float));
bwexpand(weightdenum + pos, lp,
LPC_CHIRP_WEIGHTDENUM, lp_length);
pos += lp_length;
}
}
else {
pos = 0;
for (i = 0; i < iLBCdec_inst->nsub; i++) {
LSFinterpolate2a_dec(lp, iLBCdec_inst->lsfdeqold,
lsfdeq, lsf_weightTbl_20ms[i], length);
memcpy(syntdenum+pos,lp,lp_length*sizeof(float));
bwexpand(weightdenum+pos, lp, LPC_CHIRP_WEIGHTDENUM,
lp_length);
pos += lp_length;
}
}
/* update memory */
if (iLBCdec_inst->mode==30)
memcpy(iLBCdec_inst->lsfdeqold, lsfdeq2,
length*sizeof(float));
else
memcpy(iLBCdec_inst->lsfdeqold, lsfdeq,
length*sizeof(float));
}

View File

@@ -1,42 +1,44 @@
/****************************************************************** /******************************************************************
iLBC Speech Coder ANSI-C Source Code iLBC Speech Coder ANSI-C Source Code
LPC_decode.h LPC_decode.h
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/
******************************************************************/
#ifndef __iLBC_LPC_DECODE_H
#ifndef __iLBC_LPC_DECODE_H #define __iLBC_LPC_DECODE_H
#define __iLBC_LPC_DECODE_H
void LSFinterpolate2a_dec(
void LSFinterpolate2a_dec(
float *a, /* (o) lpc coefficients for a sub frame */
float *lsf1, /* (i) first lsf coefficient vector */ float *a, /* (o) lpc coefficients for a sub-frame */
float *lsf2, /* (i) second lsf coefficient vector */ float *lsf1, /* (i) first lsf coefficient vector */
float coef, /* (i) interpolation weight */ float *lsf2, /* (i) second lsf coefficient vector */
int length /* (i) length of lsf vectors */ float coef, /* (i) interpolation weight */
); int length /* (i) length of lsf vectors */
);
void SimplelsfDEQ(
float *lsfdeq, /* (o) dequantized lsf coefficients */ void SimplelsfDEQ(
int *index /* (i) quantization index */ float *lsfdeq, /* (o) dequantized lsf coefficients */
); int *index, /* (i) quantization index */
int lpc_n /* (i) number of LPCs */
void DecoderInterpolateLSF( );
float *syntdenum, /* (o) synthesis filter coefficients */
float *weightdenum, /* (o) weighting denumerator void DecoderInterpolateLSF(
coefficients */ float *syntdenum, /* (o) synthesis filter coefficients */
float *lsfdeq, /* (i) dequantized lsf coefficients */ float *weightdenum, /* (o) weighting denumerator
int length, /* (i) length of lsf coefficient vector */ coefficients */
iLBC_Dec_Inst_t *iLBCdec_inst float *lsfdeq, /* (i) dequantized lsf coefficients */
/* (i) the decoder state structure */ int length, /* (i) length of lsf coefficient vector */
); iLBC_Dec_Inst_t *iLBCdec_inst
/* (i) the decoder state structure */
#endif );
#endif

View File

@@ -1,185 +1,227 @@
/****************************************************************** /******************************************************************
iLBC Speech Coder ANSI-C Source Code iLBC Speech Coder ANSI-C Source Code
LPCencode.c LPCencode.c
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/
******************************************************************/
#include <string.h>
#include <string.h>
#include "iLBC_define.h"
#include "helpfun.h" #include "iLBC_define.h"
#include "lsf.h" #include "helpfun.h"
#include "constants.h" #include "lsf.h"
#include "LPCencode.h" #include "constants.h"
/*----------------------------------------------------------------* /*----------------------------------------------------------------*
* lpc analysis (subrutine to LPCencode) * lpc analysis (subrutine to LPCencode)
*---------------------------------------------------------------*/ *---------------------------------------------------------------*/
static void SimpleAnalysis( void SimpleAnalysis(
float *lsf, /* (o) lsf coefficients */ float *lsf, /* (o) lsf coefficients */
float *data, /* (i) new data vector */ float *data, /* (i) new data vector */
float *lpc_buffer /* (i) buffer containing old data */ iLBC_Enc_Inst_t *iLBCenc_inst
){ /* (i/o) the encoder state structure */
int k, is; ){
float temp[BLOCKL], lp[LPC_FILTERORDER + 1]; int k, is;
float lp2[LPC_FILTERORDER + 1]; float temp[BLOCKL_MAX], lp[LPC_FILTERORDER + 1];
float r[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;
/* No lookahead, last window is asymmetric */ memcpy(iLBCenc_inst->lpc_buffer+is,data,
iLBCenc_inst->blockl*sizeof(float));
for (k = 0; k < LPC_N; k++) {
/* No lookahead, last window is asymmetric */
is = LPC_LOOKBACK;
for (k = 0; k < iLBCenc_inst->lpc_n; k++) {
if (k < (LPC_N - 1)) {
lbc_window(temp, lpc_winTbl, lpc_buffer, BLOCKL); is = LPC_LOOKBACK;
} else {
lbc_window(temp, lpc_asymwinTbl, lpc_buffer + is, BLOCKL); if (k < (iLBCenc_inst->lpc_n - 1)) {
} window(temp, lpc_winTbl,
iLBCenc_inst->lpc_buffer, BLOCKL_MAX);
autocorr(r, temp, BLOCKL, LPC_FILTERORDER); } else {
lbc_window(r, r, lpc_lagwinTbl, LPC_FILTERORDER + 1); window(temp, lpc_asymwinTbl,
iLBCenc_inst->lpc_buffer + is, BLOCKL_MAX);
levdurb(lp, temp, r, LPC_FILTERORDER); }
bwexpand(lp2, lp, LPC_CHIRP_SYNTDENUM, LPC_FILTERORDER+1);
autocorr(r, temp, BLOCKL_MAX, LPC_FILTERORDER);
a2lsf(lsf + k*LPC_FILTERORDER, lp2); window(r, r, lpc_lagwinTbl, LPC_FILTERORDER + 1);
}
memcpy(lpc_buffer, lpc_buffer+BLOCKL, levdurb(lp, temp, r, LPC_FILTERORDER);
LPC_LOOKBACK*sizeof(float)); bwexpand(lp2, lp, LPC_CHIRP_SYNTDENUM, LPC_FILTERORDER+1);
}
a2lsf(lsf + k*LPC_FILTERORDER, lp2);
/*----------------------------------------------------------------* }
* lsf interpolator and conversion from lsf to a coefficients is=LPC_LOOKBACK+BLOCKL_MAX-iLBCenc_inst->blockl;
* (subrutine to SimpleInterpolateLSF) memmove(iLBCenc_inst->lpc_buffer,
*---------------------------------------------------------------*/ iLBCenc_inst->lpc_buffer+LPC_LOOKBACK+BLOCKL_MAX-is,
is*sizeof(float));
static 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 */ * lsf interpolator and conversion from lsf to a coefficients
long length /* (i) length of coefficient vectors */ * (subrutine to SimpleInterpolateLSF)
){ *---------------------------------------------------------------*/
float lsftmp[LPC_FILTERORDER];
void LSFinterpolate2a_enc(
interpolate(lsftmp, lsf1, lsf2, coef, length); float *a, /* (o) lpc coefficients */
lsf2a(a, lsftmp); 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 */
* lsf interpolator (subrutine to LPCencode) long length /* (i) length of coefficient vectors */
*---------------------------------------------------------------*/ ){
float lsftmp[LPC_FILTERORDER];
static void SimpleInterpolateLSF(
float *syntdenum, /* (o) the synthesis filter denominator interpolate(lsftmp, lsf1, lsf2, coef, length);
resulting from the quantized lsf2a(a, lsftmp);
interpolated lsf */ }
float *weightdenum, /* (o) the weighting filter denominator
resulting from the unquantized /*----------------------------------------------------------------*
interpolated lsf */ * lsf interpolator (subrutine to LPCencode)
float *lsf, /* (i) the unquantized lsf coefficients */ *---------------------------------------------------------------*/
float *lsfdeq, /* (i) the dequantized lsf coefficients */
float *lsfold, /* (i) the unquantized lsf coefficients of void SimpleInterpolateLSF(
the previous signal frame */ float *syntdenum, /* (o) the synthesis filter denominator
float *lsfdeqold, /* (i) the dequantized lsf coefficients of resulting from the quantized
the previous signal frame */ interpolated lsf */
int length /* (i) should equate FILTERORDER */ float *weightdenum, /* (o) the weighting filter denominator
){ resulting from the unquantized
int i, pos, lp_length; interpolated lsf */
float lp[LPC_FILTERORDER + 1], *lsf2, *lsfdeq2; float *lsf, /* (i) the unquantized lsf coefficients */
float *lsfdeq, /* (i) the dequantized lsf coefficients */
lsf2 = lsf + length; float *lsfold, /* (i) the unquantized lsf coefficients of
lsfdeq2 = lsfdeq + length; the previous signal frame */
float *lsfdeqold, /* (i) the dequantized lsf coefficients of
the previous signal frame */
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;
lsf2 = lsf + length;
lsfdeq2 = lsfdeq + length;
lp_length = length + 1; 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
set of lsf coefficients */
pos = lp_length;
for (i = 1; i < NSUB; i++) {
LSFinterpolate2a_enc(lp, lsfdeq, lsfdeq2,
lsf_weightTbl[i], length);
memcpy(syntdenum + pos,lp,lp_length*sizeof(float));
LSFinterpolate2a_enc(lp, lsf, lsf2,
lsf_weightTbl[i], length);
bwexpand(weightdenum + pos, lp,
LPC_CHIRP_WEIGHTDENUM, lp_length);
pos += lp_length;
}
/* update memory */
memcpy(lsfold, lsf2, length*sizeof(float));
memcpy(lsfdeqold, lsfdeq2, length*sizeof(float));
}
/*----------------------------------------------------------------*
* lsf quantizer (subrutine to LPCencode)
*---------------------------------------------------------------*/
static void SimplelsfQ(
float *lsfdeq, /* (o) dequantized lsf coefficients
(dimension FILTERORDER) */
int *index, /* (o) quantization index */
float *lsf /* (i) the lsf coefficient vector to be
quantized (dimension FILTERORDER ) */
){
/* Quantize first LSF with memoryless split VQ */
SplitVQ(lsfdeq, index, lsf, lsfCbTbl, LSF_NSPLIT,
dim_lsfCbTbl, size_lsfCbTbl);
/* Quantize second LSF with memoryless split VQ */
SplitVQ(lsfdeq + LPC_FILTERORDER, index + LSF_NSPLIT,
lsf + LPC_FILTERORDER, lsfCbTbl, LSF_NSPLIT,
dim_lsfCbTbl, size_lsfCbTbl);
}
/*----------------------------------------------------------------*
* lpc encoder
*---------------------------------------------------------------*/
void LPCencode(
float *syntdenum, /* (i/o) synthesis filter 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];
int change=0;
SimpleAnalysis(lsf, data, (*iLBCenc_inst).lpc_buffer);
SimplelsfQ(lsfdeq, lsf_index, lsf);
change=LSF_check(lsfdeq, LPC_FILTERORDER, LPC_N);
SimpleInterpolateLSF(syntdenum, weightdenum,
lsf, lsfdeq, (*iLBCenc_inst).lsfold,
(*iLBCenc_inst).lsfdeqold, LPC_FILTERORDER);
}
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 < iLBCenc_inst->nsub; i++) {
LSFinterpolate2a_enc(lp, lsfdeq, lsfdeq2,
lsf_weightTbl_30ms[i], length);
memcpy(syntdenum + pos,lp,lp_length*sizeof(float));
LSFinterpolate2a_enc(lp, lsf, lsf2,
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)
*---------------------------------------------------------------*/
void SimplelsfQ(
float *lsfdeq, /* (o) dequantized lsf coefficients
(dimension FILTERORDER) */
int *index, /* (o) quantization index */
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);
}
}
/*----------------------------------------------------------------*
* lpc encoder
*---------------------------------------------------------------*/
void LPCencode(
float *syntdenum, /* (i/o) synthesis filter 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_MAX];
float lsfdeq[LPC_FILTERORDER * LPC_N_MAX];
int change=0;
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, iLBCenc_inst);
}

View File

@@ -1,30 +1,29 @@
/****************************************************************** /******************************************************************
iLBC Speech Coder ANSI-C Source Code iLBC Speech Coder ANSI-C Source Code
LPCencode.h LPCencode.h
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/
******************************************************************/
#ifndef __iLBC_LPCENCOD_H
#ifndef __iLBC_LPCENCOD_H #define __iLBC_LPCENCOD_H
#define __iLBC_LPCENCOD_H
void LPCencode(
void LPCencode( float *syntdenum, /* (i/o) synthesis filter coefficients
float *syntdenum, /* (i/o) synthesis filter coefficients before/after encoding */
before/after encoding */ float *weightdenum, /* (i/o) weighting denumerator coefficients
float *weightdenum, /* (i/o) weighting denumerator coefficients before/after encoding */
before/after encoding */ int *lsf_index, /* (o) lsf quantization index */
int *lsf_index, /* (o) lsf quantization index */ float *data, /* (i) lsf coefficients to quantize */
float *data, /* (i) lsf coefficients to quantize */ iLBC_Enc_Inst_t *iLBCenc_inst
iLBC_Enc_Inst_t *iLBCenc_inst /* (i/o) the encoder state structure */
/* (i/o) the encoder state structure */ );
);
#endif
#endif

View File

@@ -1,73 +1,75 @@
/****************************************************************** /******************************************************************
iLBC Speech Coder ANSI-C Source Code
StateConstructW.c iLBC Speech Coder ANSI-C Source Code
Copyright (c) 2001, StateConstructW.c
Global IP Sound AB.
All rights reserved. Copyright (C) The Internet Society (2004).
All Rights Reserved.
******************************************************************/
******************************************************************/
#include <math.h>
#include <string.h> #include <math.h>
#include <string.h>
#include "iLBC_define.h"
#include "constants.h" #include "iLBC_define.h"
#include "filter.h" #include "constants.h"
#include "StateConstructW.h" #include "filter.h"
/*----------------------------------------------------------------* /*----------------------------------------------------------------*
* decoding of the start state * decoding of the start state
*---------------------------------------------------------------*/ *---------------------------------------------------------------*/
void StateConstructW( void StateConstructW(
int idxForMax, /* (i) 6-bit index for the quantization of int idxForMax, /* (i) 6-bit index for the quantization of
max amplitude */ max amplitude */
int *idxVec, /* (i) vector of quantization indexes */ int *idxVec, /* (i) vector of quantization indexes */
float *syntDenum, /* (i) synthesis filter denumerator */ float *syntDenum, /* (i) synthesis filter denumerator */
float *out, /* (o) the decoded state vector */ float *out, /* (o) the decoded state vector */
int len /* (i) length of a state vector */ int len /* (i) length of a state vector */
){ ){
float maxVal, tmpbuf[LPC_FILTERORDER+2*STATE_LEN], *tmp, float maxVal, tmpbuf[LPC_FILTERORDER+2*STATE_LEN], *tmp,
numerator[LPC_FILTERORDER+1]; numerator[LPC_FILTERORDER+1];
float foutbuf[LPC_FILTERORDER+2*STATE_LEN], *fout; float foutbuf[LPC_FILTERORDER+2*STATE_LEN], *fout;
int k,tmpi; int k,tmpi;
/* decoding of the maximum value */ /* decoding of the maximum value */
maxVal = state_frgqTbl[idxForMax]; maxVal = state_frgqTbl[idxForMax];
maxVal = (float)pow(10,maxVal)/(float)4.5; maxVal = (float)pow(10,maxVal)/(float)4.5;
/* initialization of buffers and coefficients */ /* initialization of buffers and coefficients */
memset(tmpbuf, 0, LPC_FILTERORDER*sizeof(float)); memset(tmpbuf, 0, LPC_FILTERORDER*sizeof(float));
memset(foutbuf, 0, LPC_FILTERORDER*sizeof(float)); memset(foutbuf, 0, LPC_FILTERORDER*sizeof(float));
for(k=0; k<LPC_FILTERORDER; k++){ for (k=0; k<LPC_FILTERORDER; k++) {
numerator[k]=syntDenum[LPC_FILTERORDER-k]; numerator[k]=syntDenum[LPC_FILTERORDER-k];
} }
numerator[LPC_FILTERORDER]=syntDenum[0]; numerator[LPC_FILTERORDER]=syntDenum[0];
tmp = &tmpbuf[LPC_FILTERORDER]; tmp = &tmpbuf[LPC_FILTERORDER];
fout = &foutbuf[LPC_FILTERORDER]; fout = &foutbuf[LPC_FILTERORDER];
/* decoding of the sample values */ /* decoding of the sample values */
for(k=0; k<len; k++){ for (k=0; k<len; k++) {
tmpi = len-1-k; tmpi = len-1-k;
/* maxVal = 1/scal */ /* maxVal = 1/scal */
tmp[k] = maxVal*state_sq3Tbl[idxVec[tmpi]];
}
tmp[k] = maxVal*state_sq3Tbl[idxVec[tmpi]];
/* circular convolution with all-pass filter */ }
memset(tmp+len, 0, len*sizeof(float)); /* circular convolution with all-pass filter */
ZeroPoleFilter(tmp, numerator, syntDenum, 2*len,
LPC_FILTERORDER, fout); memset(tmp+len, 0, len*sizeof(float));
for(k=0;k<len;k++){ ZeroPoleFilter(tmp, numerator, syntDenum, 2*len,
out[k] = fout[len-1-k]+fout[2*len-1-k]; LPC_FILTERORDER, fout);
} for (k=0;k<len;k++) {
} out[k] = fout[len-1-k]+fout[2*len-1-k];
}
}

View File

@@ -1,28 +1,27 @@
/****************************************************************** /******************************************************************
iLBC Speech Coder ANSI-C Source Code iLBC Speech Coder ANSI-C Source Code
StateConstructW.h StateConstructW.h
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/
******************************************************************/
#ifndef __iLBC_STATECONSTRUCTW_H
#ifndef __iLBC_STATECONSTRUCTW_H #define __iLBC_STATECONSTRUCTW_H
#define __iLBC_STATECONSTRUCTW_H
void StateConstructW(
void StateConstructW( int idxForMax, /* (i) 6-bit index for the quantization of
int idxForMax, /* (i) 6-bit index for the quantization of max amplitude */
max amplitude */ int *idxVec, /* (i) vector of quantization indexes */
int *idxVec, /* (i) vector of quantization indexes */ float *syntDenum, /* (i) synthesis filter denumerator */
float *syntDenum, /* (i) synthesis filter denumerator */ float *out, /* (o) the decoded state vector */
float *out, /* (o) the decoded state vector */ int len /* (i) length of a state vector */
int len /* (i) length of a state vector */ );
);
#endif
#endif

View File

@@ -1,178 +1,193 @@
/****************************************************************** /******************************************************************
iLBC Speech Coder ANSI-C Source Code iLBC Speech Coder ANSI-C Source Code
StateSearchW.c StateSearchW.c
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/
******************************************************************/
#include <math.h>
#include <math.h> #include <string.h>
#include <string.h>
#include "iLBC_define.h"
#include "iLBC_define.h" #include "constants.h"
#include "constants.h" #include "filter.h"
#include "filter.h" #include "helpfun.h"
#include "helpfun.h"
#include "StateSearchW.h" /*----------------------------------------------------------------*
* predictive noise shaping encoding of scaled start state
/*----------------------------------------------------------------* * (subrutine for StateSearchW)
* predictive noise shaping encoding of scaled start state *---------------------------------------------------------------*/
* (subrutine for StateSearchW)
*---------------------------------------------------------------*/ void AbsQuantW(
iLBC_Enc_Inst_t *iLBCenc_inst,
void AbsQuantW( /* (i) Encoder instance */
float *in, /* (i) vector to encode */ float *in, /* (i) vector to encode */
float *syntDenum, /* (i) denominator of synthesis filter */ float *syntDenum, /* (i) denominator of synthesis filter */
float *weightDenum, /* (i) denominator of weighting filter */ float *weightDenum, /* (i) denominator of weighting filter */
int *out, /* (o) vector of quantizer indexes */ int *out, /* (o) vector of quantizer indexes */
int len, /* (i) length of vector to encode and int len, /* (i) length of vector to encode and
vector of quantizer indexes */ vector of quantizer indexes */
int state_first /* (i) position of start state in the int state_first /* (i) position of start state in the
80 vec */ 80 vec */
){ ){
float *syntOut, syntOutBuf[LPC_FILTERORDER+STATE_SHORT_LEN]; float *syntOut;
float toQ, xq; float syntOutBuf[LPC_FILTERORDER+STATE_SHORT_LEN_30MS];
int n; float toQ, xq;
int index; int n;
int index;
/* initialization of buffer for filtering */
/* initialization of buffer for filtering */
memset(syntOutBuf, 0, LPC_FILTERORDER*sizeof(float));
memset(syntOutBuf, 0, LPC_FILTERORDER*sizeof(float));
/* initialization of pointer for filtering */
syntOut = &syntOutBuf[LPC_FILTERORDER];
/* initialization of pointer for filtering */
/* synthesis and weighting filters on input */
syntOut = &syntOutBuf[LPC_FILTERORDER];
if (state_first) {
AllPoleFilter (in, weightDenum, SUBL, LPC_FILTERORDER); /* synthesis and weighting filters on input */
} else {
AllPoleFilter (in, weightDenum, STATE_SHORT_LEN-SUBL, if (state_first) {
LPC_FILTERORDER); AllPoleFilter (in, weightDenum, SUBL, LPC_FILTERORDER);
} } else {
AllPoleFilter (in, weightDenum,
/* encoding loop */ iLBCenc_inst->state_short_len-SUBL,
LPC_FILTERORDER);
for(n=0;n<len;n++){ }
/* time update of filter coefficients */ /* encoding loop */
if ((state_first)&&(n==SUBL)){ for (n=0; n<len; n++) {
syntDenum += (LPC_FILTERORDER+1);
weightDenum += (LPC_FILTERORDER+1); /* time update of filter coefficients */
/* synthesis and weighting filters on input */ if ((state_first)&&(n==SUBL)){
AllPoleFilter (&in[n], weightDenum, len-n, syntDenum += (LPC_FILTERORDER+1);
LPC_FILTERORDER); weightDenum += (LPC_FILTERORDER+1);
} else if ((state_first==0)&&(n==(STATE_SHORT_LEN-SUBL))) { /* synthesis and weighting filters on input */
syntDenum += (LPC_FILTERORDER+1); AllPoleFilter (&in[n], weightDenum, len-n,
weightDenum += (LPC_FILTERORDER+1); LPC_FILTERORDER);
/* synthesis and weighting filters on input */ } else if ((state_first==0)&&
AllPoleFilter (&in[n], weightDenum, len-n, (n==(iLBCenc_inst->state_short_len-SUBL))) {
LPC_FILTERORDER); syntDenum += (LPC_FILTERORDER+1);
weightDenum += (LPC_FILTERORDER+1);
}
/* synthesis and weighting filters on input */
/* prediction of synthesized and weighted input */ AllPoleFilter (&in[n], weightDenum, len-n,
LPC_FILTERORDER);
syntOut[n] = 0.0;
AllPoleFilter (&syntOut[n], weightDenum, 1, LPC_FILTERORDER); }
/* quantization */ /* prediction of synthesized and weighted input */
toQ = in[n]-syntOut[n]; syntOut[n] = 0.0;
sort_sq(&xq, &index, toQ, state_sq3Tbl, 8); AllPoleFilter (&syntOut[n], weightDenum, 1,
out[n]=index; LPC_FILTERORDER);
syntOut[n] = state_sq3Tbl[out[n]];
/* quantization */
/* update of the prediction filter */
toQ = in[n]-syntOut[n];
AllPoleFilter(&syntOut[n], weightDenum, 1, LPC_FILTERORDER); sort_sq(&xq, &index, toQ, state_sq3Tbl, 8);
} out[n]=index;
} syntOut[n] = state_sq3Tbl[out[n]];
/*----------------------------------------------------------------* /* update of the prediction filter */
* encoding of start state
*---------------------------------------------------------------*/
void StateSearchW( AllPoleFilter(&syntOut[n], weightDenum, 1,
float *residual,/* (i) target residual vector */ LPC_FILTERORDER);
float *syntDenum, /* (i) lpc synthesis filter */ }
float *weightDenum, /* (i) weighting filter denuminator */ }
int *idxForMax, /* (o) quantizer index for maximum
amplitude */ /*----------------------------------------------------------------*
int *idxVec, /* (o) vector of quantization indexes */ * encoding of start state
int len, /* (i) length of all vectors */ *---------------------------------------------------------------*/
int state_first /* (i) position of start state in the
80 vec */ void StateSearchW(
){ iLBC_Enc_Inst_t *iLBCenc_inst,
float dtmp, maxVal, tmpbuf[LPC_FILTERORDER+2*STATE_SHORT_LEN]; /* (i) Encoder instance */
float *tmp, numerator[1+LPC_FILTERORDER]; float *residual,/* (i) target residual vector */
float foutbuf[LPC_FILTERORDER+2*STATE_SHORT_LEN], *fout; float *syntDenum, /* (i) lpc synthesis filter */
int k; float *weightDenum, /* (i) weighting filter denuminator */
float qmax, scal; int *idxForMax, /* (o) quantizer index for maximum
amplitude */
/* initialization of buffers and filter coefficients */ int *idxVec, /* (o) vector of quantization indexes */
int len, /* (i) length of all vectors */
memset(tmpbuf, 0, LPC_FILTERORDER*sizeof(float)); int state_first /* (i) position of start state in the
memset(foutbuf, 0, LPC_FILTERORDER*sizeof(float)); 80 vec */
for(k=0; k<LPC_FILTERORDER; k++){ ){
numerator[k]=syntDenum[LPC_FILTERORDER-k]; float dtmp, maxVal;
} float tmpbuf[LPC_FILTERORDER+2*STATE_SHORT_LEN_30MS];
numerator[LPC_FILTERORDER]=syntDenum[0]; float *tmp, numerator[1+LPC_FILTERORDER];
tmp = &tmpbuf[LPC_FILTERORDER]; float foutbuf[LPC_FILTERORDER+2*STATE_SHORT_LEN_30MS], *fout;
fout = &foutbuf[LPC_FILTERORDER]; int k;
float qmax, scal;
/* circular convolution with the all-pass filter */
/* initialization of buffers and filter coefficients */
memcpy(tmp, residual, len*sizeof(float));
memset(tmp+len, 0, len*sizeof(float)); memset(tmpbuf, 0, LPC_FILTERORDER*sizeof(float));
ZeroPoleFilter(tmp, numerator, syntDenum, 2*len, memset(foutbuf, 0, LPC_FILTERORDER*sizeof(float));
LPC_FILTERORDER, fout); for (k=0; k<LPC_FILTERORDER; k++) {
for(k=0;k<len;k++){ numerator[k]=syntDenum[LPC_FILTERORDER-k];
fout[k] += fout[k+len]; }
} numerator[LPC_FILTERORDER]=syntDenum[0];
tmp = &tmpbuf[LPC_FILTERORDER];
/* identification of the maximum amplitude value */ fout = &foutbuf[LPC_FILTERORDER];
maxVal = fout[0]; /* circular convolution with the all-pass filter */
for(k=1; k<len; k++){
memcpy(tmp, residual, len*sizeof(float));
if(fout[k]*fout[k] > maxVal*maxVal){ memset(tmp+len, 0, len*sizeof(float));
maxVal = fout[k]; ZeroPoleFilter(tmp, numerator, syntDenum, 2*len,
} LPC_FILTERORDER, fout);
} for (k=0; k<len; k++) {
maxVal=(float)fabs(maxVal); fout[k] += fout[k+len];
}
/* encoding of the maximum amplitude value */
/* identification of the maximum amplitude value */
if(maxVal < 10.0){
maxVal = 10.0; maxVal = fout[0];
}
maxVal = (float)log10(maxVal);
sort_sq(&dtmp, idxForMax, maxVal, state_frgqTbl, 64); for (k=1; k<len; k++) {
/* decoding of the maximum amplitude representation value, if (fout[k]*fout[k] > maxVal*maxVal){
and corresponding scaling of start state */ maxVal = fout[k];
}
maxVal=state_frgqTbl[*idxForMax]; }
qmax = (float)pow(10,maxVal); maxVal=(float)fabs(maxVal);
scal = (float)(4.5)/qmax;
for(k=0;k<len;k++){ /* encoding of the maximum amplitude value */
fout[k] *= scal;
} if (maxVal < 10.0) {
maxVal = 10.0;
/* predictive noise shaping encoding of scaled start state */ }
maxVal = (float)log10(maxVal);
AbsQuantW(fout,syntDenum,weightDenum,idxVec, len, state_first); sort_sq(&dtmp, idxForMax, maxVal, state_frgqTbl, 64);
}
/* decoding of the maximum amplitude representation value,
and corresponding scaling of start state */
maxVal=state_frgqTbl[*idxForMax];
qmax = (float)pow(10,maxVal);
scal = (float)(4.5)/qmax;
for (k=0; k<len; k++){
fout[k] *= scal;
}
/* predictive noise shaping encoding of scaled start state */
AbsQuantW(iLBCenc_inst, fout,syntDenum,
weightDenum,idxVec, len, state_first);
}

View File

@@ -1,43 +1,48 @@
/****************************************************************** /******************************************************************
iLBC Speech Coder ANSI-C Source Code iLBC Speech Coder ANSI-C Source Code
StateSearchW.h StateSearchW.h
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/
******************************************************************/
#ifndef __iLBC_STATESEARCHW_H
#ifndef __iLBC_STATESEARCHW_H #define __iLBC_STATESEARCHW_H
#define __iLBC_STATESEARCHW_H
void AbsQuantW(
void AbsQuantW( iLBC_Enc_Inst_t *iLBCenc_inst,
float *in, /* (i) vector to encode */ /* (i) Encoder instance */
float *syntDenum, /* (i) denominator of synthesis filter */ float *in, /* (i) vector to encode */
float *weightDenum, /* (i) denominator of weighting filter */ float *syntDenum, /* (i) denominator of synthesis filter */
int *out, /* (o) vector of quantizer indexes */ float *weightDenum, /* (i) denominator of weighting filter */
int len, /* (i) length of vector to encode and int *out, /* (o) vector of quantizer indexes */
vector of quantizer indexes */ int len, /* (i) length of vector to encode and
int state_first /* (i) position of start state in the vector of quantizer indexes */
80 vec */ int state_first /* (i) position of start state in the
); 80 vec */
);
void StateSearchW(
float *residual,/* (i) target residual vector */ void StateSearchW(
float *syntDenum, /* (i) lpc synthesis filter */ iLBC_Enc_Inst_t *iLBCenc_inst,
float *weightDenum, /* (i) weighting filter denuminator */ /* (i) Encoder instance */
int *idxForMax, /* (o) quantizer index for maximum float *residual,/* (i) target residual vector */
amplitude */ float *syntDenum, /* (i) lpc synthesis filter */
int *idxVec, /* (o) vector of quantization indexes */ float *weightDenum, /* (i) weighting filter denuminator */
int len, /* (i) length of all vectors */ int *idxForMax, /* (o) quantizer index for maximum
int state_first /* (i) position of start state in the amplitude */
80 vec */ int *idxVec, /* (o) vector of quantization indexes */
); int len, /* (i) length of all vectors */
int state_first /* (i) position of start state in the
#endif
80 vec */
);
#endif

View File

@@ -1,69 +1,70 @@
/****************************************************************** /******************************************************************
iLBC Speech Coder ANSI-C Source Code iLBC Speech Coder ANSI-C Source Code
anaFilter.c anaFilter.c
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/
******************************************************************/
#include <string.h>
#include <string.h> #include "iLBC_define.h"
#include "iLBC_define.h"
#include "anaFilter.h" /*----------------------------------------------------------------*
* LP analysis filter.
/*----------------------------------------------------------------*
* LP analysis filter.
*---------------------------------------------------------------*/ *---------------------------------------------------------------*/
void anaFilter( void anaFilter(
float *In, /* (i) Signal to be filtered */ float *In, /* (i) Signal to be filtered */
float *a, /* (i) LP parameters */ float *a, /* (i) LP parameters */
int len,/* (i) Length of signal */ int len,/* (i) Length of signal */
float *Out, /* (o) Filtered signal */ float *Out, /* (o) Filtered signal */
float *mem /* (i/o) Filter state */ float *mem /* (i/o) Filter state */
){ ){
int i, j; int i, j;
float *po, *pi, *pm, *pa; float *po, *pi, *pm, *pa;
po = Out; po = Out;
/* Filter first part using memory from past */ /* Filter first part using memory from past */
for (i=0;i<LPC_FILTERORDER;i++) { for (i=0; i<LPC_FILTERORDER; i++) {
pi = &In[i]; pi = &In[i];
pm = &mem[LPC_FILTERORDER-1]; pm = &mem[LPC_FILTERORDER-1];
pa = a; pa = a;
*po=0.0; *po=0.0;
for (j=0;j<=i;j++) { for (j=0; j<=i; j++) {
*po+=(*pa++)*(*pi--); *po+=(*pa++)*(*pi--);
} }
for (j=i+1;j<LPC_FILTERORDER+1;j++) { for (j=i+1; j<LPC_FILTERORDER+1; j++) {
*po+=(*pa++)*(*pm--);
} *po+=(*pa++)*(*pm--);
po++; }
} po++;
}
/* Filter last part where the state is entierly
in the input vector */ /* Filter last part where the state is entierly
in the input vector */
for (i=LPC_FILTERORDER;i<len;i++) {
pi = &In[i]; for (i=LPC_FILTERORDER; i<len; i++) {
pa = a; pi = &In[i];
*po=0.0; pa = a;
for (j=0;j<LPC_FILTERORDER+1;j++) { *po=0.0;
*po+=(*pa++)*(*pi--); for (j=0; j<LPC_FILTERORDER+1; j++) {
} *po+=(*pa++)*(*pi--);
po++; }
} po++;
}
/* Update state vector */
/* Update state vector */
memcpy(mem, &In[len-LPC_FILTERORDER],
LPC_FILTERORDER*sizeof(float)); memcpy(mem, &In[len-LPC_FILTERORDER],
} LPC_FILTERORDER*sizeof(float));
}

View File

@@ -1,27 +1,26 @@
/****************************************************************** /******************************************************************
iLBC Speech Coder ANSI-C Source Code iLBC Speech Coder ANSI-C Source Code
anaFilter.h anaFilter.h
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/
******************************************************************/
#ifndef __iLBC_ANAFILTER_H
#ifndef __iLBC_ANAFILTER_H #define __iLBC_ANAFILTER_H
#define __iLBC_ANAFILTER_H
void anaFilter(
void anaFilter( float *In, /* (i) Signal to be filtered */
float *In, /* (i) Signal to be filtered */ float *a, /* (i) LP parameters */
float *a, /* (i) LP parameters */ int len,/* (i) Length of signal */
int len,/* (i) Length of signal */ float *Out, /* (o) Filtered signal */
float *Out, /* (o) Filtered signal */ float *mem /* (i/o) Filter state */
float *mem /* (i/o) Filter state */ );
);
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,85 +1,74 @@
/****************************************************************** /******************************************************************
iLBC Speech Coder ANSI-C Source Code iLBC Speech Coder ANSI-C Source Code
constants.h constants.h
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/
******************************************************************/
#ifndef __iLBC_CONSTANTS_H
#define __iLBC_CONSTANTS_H #ifndef __iLBC_CONSTANTS_H
#define __iLBC_CONSTANTS_H
#include "iLBC_define.h"
#include "iLBC_define.h"
/* bit allocation */
extern int lsf_bitsTbl[]; /* ULP bit allocation */
extern int start_bitsTbl;
extern int scale_bitsTbl; extern const iLBC_ULP_Inst_t ULP_20msTbl;
extern int state_bitsTbl; extern const iLBC_ULP_Inst_t ULP_30msTbl;
extern int cb_bitsTbl[5][CB_NSTAGES];
extern int search_rangeTbl[5][CB_NSTAGES]; /* high pass filters */
extern int gain_bitsTbl[];
extern float hpi_zero_coefsTbl[];
/* ULP bit allocation */ extern float hpi_pole_coefsTbl[];
extern float hpo_zero_coefsTbl[];
extern int ulp_lsf_bitsTbl[6][ULP_CLASSES+2]; extern float hpo_pole_coefsTbl[];
extern int ulp_start_bitsTbl[];
extern int ulp_startfirst_bitsTbl[]; /* low pass filters */
extern int ulp_scale_bitsTbl[]; extern float lpFilt_coefsTbl[];
extern int ulp_state_bitsTbl[];
extern int ulp_extra_cb_indexTbl[CB_NSTAGES][ULP_CLASSES+2]; /* LPC analysis and quantization */
extern int ulp_extra_cb_gainTbl[CB_NSTAGES][ULP_CLASSES+2];
extern int ulp_cb_indexTbl[NASUB][CB_NSTAGES][ULP_CLASSES+2]; extern float lpc_winTbl[];
extern int ulp_cb_gainTbl[NASUB][CB_NSTAGES][ULP_CLASSES+2]; extern float lpc_asymwinTbl[];
extern float lpc_lagwinTbl[];
/* high pass filters */ extern float lsfCbTbl[];
extern float lsfmeanTbl[];
extern float hpi_zero_coefsTbl[]; extern int dim_lsfCbTbl[];
extern float hpi_pole_coefsTbl[]; extern int size_lsfCbTbl[];
extern float hpo_zero_coefsTbl[]; extern float lsf_weightTbl_30ms[];
extern float hpo_pole_coefsTbl[]; extern float lsf_weightTbl_20ms[];
/* low pass filters */ /* state quantization tables */
extern float lpFilt_coefsTbl[];
extern float state_sq3Tbl[];
/* LPC analysis and quantization */ extern float state_frgqTbl[];
extern float lpc_winTbl[]; /* gain quantization tables */
extern float lpc_asymwinTbl[];
extern float lpc_lagwinTbl[]; extern float gain_sq3Tbl[];
extern float lsfCbTbl[]; extern float gain_sq4Tbl[];
extern float lsfmeanTbl[]; extern float gain_sq5Tbl[];
extern int dim_lsfCbTbl[];
extern int size_lsfCbTbl[]; /* adaptive codebook definitions */
extern float lsf_weightTbl[];
extern int search_rangeTbl[5][CB_NSTAGES];
/* state quantization tables */ extern int memLfTbl[];
extern int stMemLTbl;
extern float state_sq3Tbl[]; extern float cbfiltersTbl[CB_FILTERLEN];
extern float state_frgqTbl[];
/* gain quantization tables */
/* enhancer definitions */
extern float gain_sq3Tbl[];
extern float gain_sq4Tbl[]; extern float polyphaserTbl[];
extern float gain_sq5Tbl[]; extern float enh_plocsTbl[];
/* adaptive codebook definitions */ #endif
extern int memLfTbl[];
extern int stMemLTbl;
extern float cbfiltersTbl[CB_FILTERLEN];
/* enhancer definitions */
extern float polyphaserTbl[];
extern float enh_plocsTbl[];
#endif

View File

@@ -1,208 +1,215 @@
/******************************************************************
iLBC Speech Coder ANSI-C Source Code /******************************************************************
createCB.c iLBC Speech Coder ANSI-C Source Code
Copyright (c) 2001, createCB.c
Global IP Sound AB.
All rights reserved. Copyright (C) The Internet Society (2004).
All Rights Reserved.
******************************************************************/
******************************************************************/
#include "iLBC_define.h"
#include "constants.h" #include "iLBC_define.h"
#include "createCB.h" #include "constants.h"
#include <string.h> #include <string.h>
#include <math.h> #include <math.h>
/*----------------------------------------------------------------* /*----------------------------------------------------------------*
* Construct an additional codebook vector by filtering the * Construct an additional codebook vector by filtering the
* initial codebook buffer. This vector is then used to expand * initial codebook buffer. This vector is then used to expand
* the codebook with an additional section. * the codebook with an additional section.
*---------------------------------------------------------------*/ *---------------------------------------------------------------*/
void filteredCBvecs( void filteredCBvecs(
float *cbvectors, /* (o) Codebook vectors for the higher float *cbvectors, /* (o) Codebook vectors for the
section */ higher section */
float *mem, /* (i) Buffer to create codebook vector from float *mem, /* (i) Buffer to create codebook
*/ vector from */
int lMem /* (i) Length of buffer */ int lMem /* (i) Length of buffer */
){ ){
int j, k; int j, k;
float *pp, *pp1; float *pp, *pp1;
float tempbuff2[CB_MEML+CB_FILTERLEN]; float tempbuff2[CB_MEML+CB_FILTERLEN];
float *pos; float *pos;
memset(tempbuff2, 0, (CB_HALFFILTERLEN-1)*sizeof(float)); memset(tempbuff2, 0, (CB_HALFFILTERLEN-1)*sizeof(float));
memcpy(&tempbuff2[CB_HALFFILTERLEN-1], mem, lMem*sizeof(float)); memcpy(&tempbuff2[CB_HALFFILTERLEN-1], mem, lMem*sizeof(float));
memset(&tempbuff2[lMem+CB_HALFFILTERLEN-1], 0, memset(&tempbuff2[lMem+CB_HALFFILTERLEN-1], 0,
(CB_HALFFILTERLEN+1)*sizeof(float)); (CB_HALFFILTERLEN+1)*sizeof(float));
/* Create codebook vector for higher section by filtering */ /* Create codebook vector for higher section by filtering */
/* do filtering */ /* do filtering */
pos=cbvectors; pos=cbvectors;
memset(pos, 0, lMem*sizeof(float)); memset(pos, 0, lMem*sizeof(float));
for (k=0; k<lMem; k++) { for (k=0; k<lMem; k++) {
pp=&tempbuff2[k]; pp=&tempbuff2[k];
pp1=&cbfiltersTbl[0]; pp1=&cbfiltersTbl[CB_FILTERLEN-1];
for (j=0;j<CB_FILTERLEN;j++) { for (j=0;j<CB_FILTERLEN;j++) {
(*pos)+=(*pp++)*(*pp1++); (*pos)+=(*pp++)*(*pp1--);
} }
pos++; pos++;
} }
} }
/*----------------------------------------------------------------*
* Search the augmented part of the codebook to find the best
* measure. /*----------------------------------------------------------------*
*----------------------------------------------------------------*/ * Search the augmented part of the codebook to find the best
* measure.
void searchAugmentedCB( *----------------------------------------------------------------*/
int low, /* (i) Start index for the search */
int high, /* (i) End index for the search */ void searchAugmentedCB(
int stage, /* (i) Current stage */ int low, /* (i) Start index for the search */
int startIndex, /* (i) Codebook index for the first int high, /* (i) End index for the search */
aug vector */ int stage, /* (i) Current stage */
float *target, /* (i) Target vector for encoding */ int startIndex, /* (i) Codebook index for the first
float *buffer, /* (i) Pointer to the end of the buffer for aug vector */
augmented codebook construction */ float *target, /* (i) Target vector for encoding */
float *max_measure, /* (i/o) Currently maximum measure */ float *buffer, /* (i) Pointer to the end of the buffer for
int *best_index,/* (o) Currently the best index */ augmented codebook construction */
float *gain, /* (o) Currently the best gain */ float *max_measure, /* (i/o) Currently maximum measure */
float *energy, /* (o) Energy of augmented codebook int *best_index,/* (o) Currently the best index */
vectors */ float *gain, /* (o) Currently the best gain */
float *invenergy/* (o) Inv energy of augmented codebook float *energy, /* (o) Energy of augmented codebook
vectors */ vectors */
) { float *invenergy/* (o) Inv energy of augmented codebook
int lagcount, ilow, j, tmpIndex; vectors */
float *pp, *ppo, *ppi, *ppe, crossDot, alfa; ) {
float weighted, measure, nrjRecursive; int icount, ilow, j, tmpIndex;
float ftmp; float *pp, *ppo, *ppi, *ppe, crossDot, alfa;
float weighted, measure, nrjRecursive;
/* Compute the energy for the first (low-5) float ftmp;
noninterpolated samples */
nrjRecursive = (float) 0.0; /* Compute the energy for the first (low-5)
pp = buffer - low + 1; noninterpolated samples */
for (j=0; j<(low-5); j++) { nrjRecursive = (float) 0.0;
nrjRecursive += ( (*pp)*(*pp) ); pp = buffer - low + 1;
pp++; for (j=0; j<(low-5); j++) {
} nrjRecursive += ( (*pp)*(*pp) );
ppe = buffer - low; pp++;
}
ppe = buffer - low;
for (lagcount=low; lagcount<=high; lagcount++) {
/* Index of the codebook vector used for retrieving for (icount=low; icount<=high; icount++) {
energy values */
tmpIndex = startIndex+lagcount-20; /* Index of the codebook vector used for retrieving
energy values */
ilow = lagcount-4; tmpIndex = startIndex+icount-20;
/* Update the energy recursively to save complexity */ ilow = icount-4;
nrjRecursive = nrjRecursive + (*ppe)*(*ppe);
ppe--; /* Update the energy recursively to save complexity */
energy[tmpIndex] = nrjRecursive; nrjRecursive = nrjRecursive + (*ppe)*(*ppe);
ppe--;
/* Compute cross dot product for the first (low-5) samples */ energy[tmpIndex] = nrjRecursive;
crossDot = (float) 0.0;
pp = buffer-lagcount; /* Compute cross dot product for the first (low-5)
for (j=0; j<ilow; j++) { samples */
crossDot += target[j]*(*pp++); crossDot = (float) 0.0;
}
/* interpolation */ pp = buffer-icount;
alfa = (float) 0.2; for (j=0; j<ilow; j++) {
ppo = buffer-4; crossDot += target[j]*(*pp++);
ppi = buffer-lagcount-4; }
for (j=ilow; j<lagcount; j++) {
weighted = ((float)1.0-alfa)*(*ppo)+alfa*(*ppi); /* interpolation */
ppo++; alfa = (float) 0.2;
ppi++; ppo = buffer-4;
energy[tmpIndex] += weighted*weighted; ppi = buffer-icount-4;
crossDot += target[j]*weighted; for (j=ilow; j<icount; j++) {
alfa += (float)0.2; weighted = ((float)1.0-alfa)*(*ppo)+alfa*(*ppi);
} ppo++;
ppi++;
/* Compute energy and cross dot product for the energy[tmpIndex] += weighted*weighted;
remaining samples */ crossDot += target[j]*weighted;
pp = buffer - lagcount; alfa += (float)0.2;
for (j=lagcount; j<SUBL; j++) { }
energy[tmpIndex] += (*pp)*(*pp);
crossDot += target[j]*(*pp++); /* Compute energy and cross dot product for the
} remaining samples */
pp = buffer - icount;
if(energy[tmpIndex]>0.0) { for (j=icount; j<SUBL; j++) {
invenergy[tmpIndex]=(float)1.0/(energy[tmpIndex]+EPS); energy[tmpIndex] += (*pp)*(*pp);
} else { crossDot += target[j]*(*pp++);
invenergy[tmpIndex] = (float) 0.0; }
}
if (energy[tmpIndex]>0.0) {
if (stage==0) { invenergy[tmpIndex]=(float)1.0/(energy[tmpIndex]+EPS);
measure = (float)-10000000.0; } else {
invenergy[tmpIndex] = (float) 0.0;
if (crossDot > 0.0) { }
measure = crossDot*crossDot*invenergy[tmpIndex];
} if (stage==0) {
} measure = (float)-10000000.0;
else {
measure = crossDot*crossDot*invenergy[tmpIndex]; if (crossDot > 0.0) {
} measure = crossDot*crossDot*invenergy[tmpIndex];
}
/* check if measure is better */ }
ftmp = crossDot*invenergy[tmpIndex]; else {
measure = crossDot*crossDot*invenergy[tmpIndex];
if ((measure>*max_measure) && (fabs(ftmp)<CB_MAXGAIN)) { }
*best_index = tmpIndex;
*max_measure = measure; /* check if measure is better */
*gain = ftmp; ftmp = crossDot*invenergy[tmpIndex];
}
} if ((measure>*max_measure) && (fabs(ftmp)<CB_MAXGAIN)) {
} *best_index = tmpIndex;
*max_measure = measure;
*gain = ftmp;
/*----------------------------------------------------------------* }
* Recreate a specific codebook vector from the augmented part. }
* }
*----------------------------------------------------------------*/
void createAugmentedVec(
int index, /* (i) Index for the augmented vector
to be created */ /*----------------------------------------------------------------*
float *buffer, /* (i) Pointer to the end of the buffer for * Recreate a specific codebook vector from the augmented part.
augmented codebook construction */ *
float *cbVec/* (o) The construced codebook vector */ *----------------------------------------------------------------*/
) {
int ilow, j; void createAugmentedVec(
float *pp, *ppo, *ppi, alfa, alfa1, weighted; int index, /* (i) Index for the augmented vector
to be created */
ilow = index-5; float *buffer, /* (i) Pointer to the end of the buffer for
augmented codebook construction */
/* copy the first noninterpolated part */ float *cbVec/* (o) The construced codebook vector */
) {
pp = buffer-index; int ilow, j;
memcpy(cbVec,pp,sizeof(float)*index); float *pp, *ppo, *ppi, alfa, alfa1, weighted;
/* interpolation */ ilow = index-5;
alfa1 = (float)0.2; /* copy the first noninterpolated part */
alfa = 0.0;
ppo = buffer-5; pp = buffer-index;
ppi = buffer-index-5; memcpy(cbVec,pp,sizeof(float)*index);
for (j=ilow; j<index; j++) {
weighted = ((float)1.0-alfa)*(*ppo)+alfa*(*ppi); /* interpolation */
ppo++;
ppi++; alfa1 = (float)0.2;
cbVec[j] = weighted; alfa = 0.0;
alfa += alfa1; ppo = buffer-5;
} ppi = buffer-index-5;
for (j=ilow; j<index; j++) {
/* copy the second noninterpolated part */ weighted = ((float)1.0-alfa)*(*ppo)+alfa*(*ppi);
ppo++;
pp = buffer - index; ppi++;
memcpy(cbVec+index,pp,sizeof(float)*(SUBL-index)); cbVec[j] = weighted;
} alfa += alfa1;
}
/* copy the second noninterpolated part */
pp = buffer - index;
memcpy(cbVec+index,pp,sizeof(float)*(SUBL-index));
}

View File

@@ -1,55 +1,56 @@
/****************************************************************** /******************************************************************
iLBC Speech Coder ANSI-C Source Code
createCB.h iLBC Speech Coder ANSI-C Source Code
Copyright (c) 2001, createCB.h
Global IP Sound AB.
All rights reserved. Copyright (C) The Internet Society (2004).
All Rights Reserved.
******************************************************************/
******************************************************************/
#ifndef __iLBC_CREATECB_H
#define __iLBC_CREATECB_H #ifndef __iLBC_CREATECB_H
#define __iLBC_CREATECB_H
void filteredCBvecs(
float *cbvectors, /* (o) Codebook vector for the void filteredCBvecs(
higher section */ float *cbvectors, /* (o) Codebook vector for the
float *mem, /* (i) Buffer to create codebook higher section */
vectors from */ float *mem, /* (i) Buffer to create codebook
int lMem /* (i) Length of buffer */ vectors from */
); int lMem /* (i) Length of buffer */
);
void searchAugmentedCB(
int low, /* (i) Start index for the search */ void searchAugmentedCB(
int high, /* (i) End index for the search */ int low, /* (i) Start index for the search */
int stage, /* (i) Current stage */ int high, /* (i) End index for the search */
int startIndex, /* (i) CB index for the first int stage, /* (i) Current stage */
augmented vector */ int startIndex, /* (i) CB index for the first
float *target, /* (i) Target vector for encoding */ augmented vector */
float *buffer, /* (i) Pointer to the end of the float *target, /* (i) Target vector for encoding */
buffer for augmented codebook float *buffer, /* (i) Pointer to the end of the
construction */ buffer for augmented codebook
float *max_measure, /* (i/o) Currently maximum measure */ construction */
int *best_index,/* (o) Currently the best index */ float *max_measure, /* (i/o) Currently maximum measure */
float *gain, /* (o) Currently the best gain */ int *best_index,/* (o) Currently the best index */
float *energy, /* (o) Energy of augmented float *gain, /* (o) Currently the best gain */
codebook vectors */ float *energy, /* (o) Energy of augmented
float *invenergy/* (o) Inv energy of aug codebook codebook vectors */
vectors */ float *invenergy/* (o) Inv energy of aug codebook
); vectors */
);
void createAugmentedVec(
int index, /* (i) Index for the aug vector void createAugmentedVec(
to be created */ int index, /* (i) Index for the aug vector
float *buffer, /* (i) Pointer to the end of the to be created */
buffer for augmented codebook float *buffer, /* (i) Pointer to the end of the
construction */ buffer for augmented codebook
float *cbVec /* (o) The construced codebook vector */ construction */
); float *cbVec /* (o) The construced codebook vector */
);
#endif
#endif

View File

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

View File

@@ -1,31 +1,32 @@
/****************************************************************** /******************************************************************
iLBC Speech Coder ANSI-C Source Code iLBC Speech Coder ANSI-C Source Code
doCPLC.h doCPLC.h
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/
******************************************************************/
#ifndef __iLBC_DOLPC_H
#define __iLBC_DOLPC_H #ifndef __iLBC_DOLPC_H
#define __iLBC_DOLPC_H
void doThePLC(
float *PLCresidual, /* (o) concealed residual */ void doThePLC(
float *PLClpc, /* (o) concealed LP parameters */ float *PLCresidual, /* (o) concealed residual */
int PLI, /* (i) packet loss indicator float *PLClpc, /* (o) concealed LP parameters */
0 - no PL, 1 = PL */ int PLI, /* (i) packet loss indicator
float *decresidual, /* (i) decoded residual */ 0 - no PL, 1 = PL */
float *lpc, /* (i) decoded LPC (only used for no PL) */ float *decresidual, /* (i) decoded residual */
int inlag, /* (i) pitch lag */ float *lpc, /* (i) decoded LPC (only used for no PL) */
iLBC_Dec_Inst_t *iLBCdec_inst int inlag, /* (i) pitch lag */
/* (i/o) decoder instance */ iLBC_Dec_Inst_t *iLBCdec_inst
); /* (i/o) decoder instance */
);
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,34 +1,33 @@
/****************************************************************** /******************************************************************
iLBC Speech Coder ANSI-C Source Code iLBC Speech Coder ANSI-C Source Code
enhancer.h enhancer.h
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/
******************************************************************/
#ifndef __ENHANCER_H
#ifndef __ENHANCER_H #define __ENHANCER_H
#define __ENHANCER_H
#include "iLBC_define.h"
#include "iLBC_define.h"
float xCorrCoef(
float xCorrCoef( float *target, /* (i) first array */
float *target, /* (i) first array */ float *regressor, /* (i) second array */
float *regressor, /* (i) second array */ int subl /* (i) dimension arrays */
int subl /* (i) dimension arrays */ );
);
int enhancerInterface(
int enhancerInterface( float *out, /* (o) the enhanced recidual signal */
float *out, /* (o) the enhanced recidual signal */ float *in, /* (i) the recidual signal to enhance */
float *in, /* (i) the recidual signal to enhance */ iLBC_Dec_Inst_t *iLBCdec_inst
iLBC_Dec_Inst_t *iLBCdec_inst /* (i/o) the decoder state structure */
/* (i/o) the decoder state structure */ );
);
#endif
#endif

View File

@@ -1,162 +1,167 @@
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
filter.c
Copyright (c) 2001,
Global IP Sound AB.
All rights reserved.
******************************************************************/
#include "iLBC_define.h"
#include "filter.h"
/*----------------------------------------------------------------* /******************************************************************
* all-pole filter
*---------------------------------------------------------------*/ iLBC Speech Coder ANSI-C Source Code
void AllPoleFilter( filter.c
float *InOut, /* (i/o) on entrance InOut[-orderCoef] to
InOut[-1] contain the state of the filter Copyright (C) The Internet Society (2004).
(delayed samples). InOut[0] to All Rights Reserved.
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 #include "iLBC_define.h"
be 1.0 */
int lengthInOut,/* (i) number of input/output samples */ /*----------------------------------------------------------------*
int orderCoef /* (i) number of filter coefficients */ * all-pole filter
){ *---------------------------------------------------------------*/
int n,k;
void AllPoleFilter(
for(n=0;n<lengthInOut;n++){ float *InOut, /* (i/o) on entrance InOut[-orderCoef] to
for(k=1;k<=orderCoef;k++){ InOut[-1] contain the state of the
*InOut -= Coef[k]*InOut[-k]; filter (delayed samples). InOut[0] to
} InOut[lengthInOut-1] contain the filter
InOut++; 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
* all-zero filter 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 int n,k;
input samples */
float *Coef,/* (i) filter coefficients (Coef[0] is assumed for(n=0;n<lengthInOut;n++){
to be 1.0) */ for(k=1;k<=orderCoef;k++){
int lengthInOut,/* (i) number of input/output samples */ *InOut -= Coef[k]*InOut[-k];
int orderCoef, /* (i) number of filter coefficients */ }
float *Out /* (i/o) on entrance Out[-orderCoef] to Out[-1] InOut++;
contain the filter state, on exit Out[0] }
to Out[lengthInOut-1] contain filtered }
samples */
){ /*----------------------------------------------------------------*
int n,k; * all-zero filter
*---------------------------------------------------------------*/
for(n=0;n<lengthInOut;n++){
*Out = Coef[0]*In[0]; void AllZeroFilter(
for(k=1;k<=orderCoef;k++){ float *In, /* (i) In[0] to In[lengthInOut-1] contain
*Out += Coef[k]*In[-k]; filter input samples */
} float *Coef,/* (i) filter coefficients (Coef[0] is assumed
Out++; to be 1.0) */
In++; 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 the filter state, on exit Out[0]
/*----------------------------------------------------------------* to Out[lengthInOut-1] contain filtered
* pole-zero filter samples */
*---------------------------------------------------------------*/ ){
int n,k;
void ZeroPoleFilter(
float *In, /* (i) In[0] to In[lengthInOut-1] contain filter for(n=0;n<lengthInOut;n++){
input samples In[-orderCoef] to In[-1] *Out = Coef[0]*In[0];
contain state of all-zero section */ for(k=1;k<=orderCoef;k++){
float *ZeroCoef,/* (i) filter coefficients for all-zero *Out += Coef[k]*In[-k];
section (ZeroCoef[0] is assumed to }
be 1.0) */
float *PoleCoef,/* (i) filter coefficients for all-pole section
(ZeroCoef[0] is assumed to be 1.0) */ Out++;
int lengthInOut,/* (i) number of input/output samples */ In++;
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 */ * pole-zero filter
){ *---------------------------------------------------------------*/
AllZeroFilter(In,ZeroCoef,lengthInOut,orderCoef,Out);
AllPoleFilter(Out,PoleCoef,lengthInOut,orderCoef); 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
* downsample (LP filter and decimation) section */
*---------------------------------------------------------------*/ float *ZeroCoef,/* (i) filter coefficients for all-zero
section (ZeroCoef[0] is assumed to
void DownSample ( be 1.0) */
float *In, /* (i) input samples */ float *PoleCoef,/* (i) filter coefficients for all-pole section
float *Coef, /* (i) filter coefficients */ (ZeroCoef[0] is assumed to be 1.0) */
int lengthIn, /* (i) number of input samples */ int lengthInOut,/* (i) number of input/output samples */
float *state, /* (i) filter state */ int orderCoef, /* (i) number of filter coefficients */
float *Out /* (o) downsampled output */ float *Out /* (i/o) on entrance Out[-orderCoef] to Out[-1]
){ contain state of all-pole section. On
float o; exit Out[0] to Out[lengthInOut-1]
float *Out_ptr = Out; contain filtered samples */
float *Coef_ptr, *In_ptr; ){
float *state_ptr; AllZeroFilter(In,ZeroCoef,lengthInOut,orderCoef,Out);
int i, j, stop; AllPoleFilter(Out,PoleCoef,lengthInOut,orderCoef);
}
/* LP filter and decimate at the same time */
/*----------------------------------------------------------------*
for (i = DELAY_DS; i < lengthIn; i+=FACTOR_DS) * downsample (LP filter and decimation)
{ *---------------------------------------------------------------*/
Coef_ptr = &Coef[0];
In_ptr = &In[i]; void DownSample (
state_ptr = &state[FILTERORDER_DS-2]; float *In, /* (i) input samples */
float *Coef, /* (i) filter coefficients */
o = (float)0.0; int lengthIn, /* (i) number of input samples */
float *state, /* (i) filter state */
stop = (i < FILTERORDER_DS) ? i + 1 : FILTERORDER_DS; float *Out /* (o) downsampled output */
){
for (j = 0;j < stop; j++) float o;
{ float *Out_ptr = Out;
o += *Coef_ptr++ * (*In_ptr--); float *Coef_ptr, *In_ptr;
} float *state_ptr;
for (j = i + 1; j < FILTERORDER_DS; j++) int i, j, stop;
{
o += *Coef_ptr++ * (*state_ptr--); /* LP filter and decimate at the same time */
}
for (i = DELAY_DS; i < lengthIn; i+=FACTOR_DS)
*Out_ptr++ = o; {
} Coef_ptr = &Coef[0];
In_ptr = &In[i];
/* Get the last part (use zeros as input for the future) */ state_ptr = &state[FILTERORDER_DS-2];
for (i=(lengthIn+FACTOR_DS); i<(lengthIn+DELAY_DS);
i+=FACTOR_DS) {
o = (float)0.0;
o=(float)0.0;
stop = (i < FILTERORDER_DS) ? i + 1 : FILTERORDER_DS;
if (i<lengthIn) {
Coef_ptr = &Coef[0]; for (j = 0; j < stop; j++)
In_ptr = &In[i]; {
for (j=0;j<FILTERORDER_DS;j++) { o += *Coef_ptr++ * (*In_ptr--);
o += *Coef_ptr++ * (*Out_ptr--); }
} for (j = i + 1; j < FILTERORDER_DS; j++)
} else { {
Coef_ptr = &Coef[i-lengthIn]; o += *Coef_ptr++ * (*state_ptr--);
In_ptr = &In[lengthIn-1]; }
for (j=0;j<FILTERORDER_DS-(i-lengthIn);j++) {
o += *Coef_ptr++ * (*In_ptr--); *Out_ptr++ = o;
} }
}
*Out_ptr++ = o; /* Get the last part (use zeros as input for the future) */
}
} for (i=(lengthIn+FACTOR_DS); i<(lengthIn+DELAY_DS);
i+=FACTOR_DS) {
o=(float)0.0;
if (i<lengthIn) {
Coef_ptr = &Coef[0];
In_ptr = &In[i];
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++) {
o += *Coef_ptr++ * (*In_ptr--);
}
}
*Out_ptr++ = o;
}
}

View File

@@ -1,72 +1,73 @@
/****************************************************************** /******************************************************************
iLBC Speech Coder ANSI-C Source Code iLBC Speech Coder ANSI-C Source Code
filter.h filter.h
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/
******************************************************************/
#ifndef __iLBC_FILTER_H
#ifndef __iLBC_FILTER_H #define __iLBC_FILTER_H
#define __iLBC_FILTER_H
void AllPoleFilter(
void AllPoleFilter( float *InOut, /* (i/o) on entrance InOut[-orderCoef] to
float *InOut, /* (i/o) on entrance InOut[-orderCoef] to InOut[-1] contain the state of the
InOut[-1] contain the state of the filter filter (delayed samples). InOut[0] to
(delayed samples). InOut[0] to InOut[lengthInOut-1] contain the filter
InOut[lengthInOut-1] contain the filter input, on en exit InOut[-orderCoef] to
input, on en exit InOut[-orderCoef] to InOut[-1] is unchanged and InOut[0] to
InOut[-1] is unchanged and InOut[0] to InOut[lengthInOut-1] contain filtered
InOut[lengthInOut-1] contain filtered samples */
samples */ float *Coef,/* (i) filter coefficients, Coef[0] is assumed
float *Coef,/* (i) filter coefficients, Coef[0] is assumed to to be 1.0 */
be 1.0 */ int lengthInOut,/* (i) number of input/output samples */
int lengthInOut,/* (i) number of input/output samples */ int orderCoef /* (i) number of filter coefficients */
int orderCoef /* (i) number of filter coefficients */ );
);
void AllZeroFilter(
float *In, /* (i) In[0] to In[lengthInOut-1] contain filter void AllZeroFilter(
input samples */ float *In, /* (i) In[0] to In[lengthInOut-1] contain
float *Coef,/* (i) filter coefficients (Coef[0] is assumed filter input samples */
to be 1.0) */ float *Coef,/* (i) filter coefficients (Coef[0] is assumed
int lengthInOut,/* (i) number of input/output samples */ to be 1.0) */
int orderCoef, /* (i) number of filter coefficients */ int lengthInOut,/* (i) number of input/output samples */
float *Out /* (i/o) on entrance Out[-orderCoef] to Out[-1] int orderCoef, /* (i) number of filter coefficients */
contain the filter state, on exit Out[0] float *Out /* (i/o) on entrance Out[-orderCoef] to Out[-1]
to Out[lengthInOut-1] contain filtered contain the filter state, on exit Out[0]
samples */ to Out[lengthInOut-1] contain filtered
); samples */
);
void ZeroPoleFilter(
float *In, /* (i) In[0] to In[lengthInOut-1] contain filter void ZeroPoleFilter(
input samples In[-orderCoef] to In[-1] float *In, /* (i) In[0] to In[lengthInOut-1] contain filter
contain state of all-zero section */ input samples In[-orderCoef] to In[-1]
float *ZeroCoef,/* (i) filter coefficients for all-zero contain state of all-zero section */
section (ZeroCoef[0] is assumed to float *ZeroCoef,/* (i) filter coefficients for all-zero
be 1.0) */ section (ZeroCoef[0] is assumed to
float *PoleCoef,/* (i) filter coefficients for all-pole section be 1.0) */
(ZeroCoef[0] is assumed to be 1.0) */ float *PoleCoef,/* (i) filter coefficients for all-pole section
int lengthInOut,/* (i) number of input/output samples */ (ZeroCoef[0] is assumed to be 1.0) */
int orderCoef, /* (i) number of filter coefficients */ int lengthInOut,/* (i) number of input/output samples */
float *Out /* (i/o) on entrance Out[-orderCoef] to Out[-1] int orderCoef, /* (i) number of filter coefficients */
contain state of all-pole section. On exit float *Out /* (i/o) on entrance Out[-orderCoef] to Out[-1]
Out[0] to Out[lengthInOut-1] contain contain state of all-pole section. On
filtered samples */ exit Out[0] to Out[lengthInOut-1]
); contain filtered samples */
);
void DownSample (
float *In, /* (i) input samples */ void DownSample (
float *Coef, /* (i) filter coefficients */ float *In, /* (i) input samples */
int lengthIn, /* (i) number of input samples */ float *Coef, /* (i) filter coefficients */
float *state, /* (i) filter state */ int lengthIn, /* (i) number of input samples */
float *Out /* (o) downsampled output */ float *state, /* (i) filter state */
); float *Out /* (o) downsampled output */
);
#endif
#endif

View File

@@ -1,104 +1,106 @@
/****************************************************************** /******************************************************************
iLBC Speech Coder ANSI-C Source Code iLBC Speech Coder ANSI-C Source Code
gainquant.c gainquant.c
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/
******************************************************************/
#include <string.h>
#include <math.h> #include <string.h>
#include "constants.h" #include <math.h>
#include "filter.h" #include "constants.h"
#include "gainquant.h" #include "filter.h"
/*----------------------------------------------------------------* /*----------------------------------------------------------------*
* quantizer for the gain in the gain-shape coding of residual * quantizer for the gain in the gain-shape coding of residual
*---------------------------------------------------------------*/ *---------------------------------------------------------------*/
float gainquant(/* (o) quantized gain value */ float gainquant(/* (o) quantized gain value */
float in, /* (i) gain value */ float in, /* (i) gain value */
float maxIn,/* (i) maximum of gain value */ float maxIn,/* (i) maximum of gain value */
int cblen, /* (i) number of quantization indices */ int cblen, /* (i) number of quantization indices */
int *index /* (o) quantization index */ int *index /* (o) quantization index */
){ ){
int i, tindex; int i, tindex;
float minmeasure,measure, *cb, scale; float minmeasure,measure, *cb, scale;
/* ensure a lower bound on the scaling factor */ /* ensure a lower bound on the scaling factor */
scale=maxIn; scale=maxIn;
if (scale<0.1) { if (scale<0.1) {
scale=(float)0.1; scale=(float)0.1;
} }
/* select the quantization table */ /* select the quantization table */
if (cblen == 8) { if (cblen == 8) {
cb = gain_sq3Tbl; cb = gain_sq3Tbl;
} else if (cblen == 16) { } else if (cblen == 16) {
cb = gain_sq4Tbl; cb = gain_sq4Tbl;
} else { } else {
cb = gain_sq5Tbl; cb = gain_sq5Tbl;
} }
/* select the best index in the quantization table */ /* select the best index in the quantization table */
minmeasure=10000000.0; minmeasure=10000000.0;
tindex=0; tindex=0;
for (i=0;i<cblen;i++) { for (i=0; i<cblen; i++) {
measure=(in-scale*cb[i])*(in-scale*cb[i]); measure=(in-scale*cb[i])*(in-scale*cb[i]);
if (measure<minmeasure) {
tindex=i;
minmeasure=measure;
}
}
*index=tindex;
/* return the quantized value */ if (measure<minmeasure) {
tindex=i;
return scale*cb[tindex]; minmeasure=measure;
} }
}
/*----------------------------------------------------------------* *index=tindex;
* decoder for quantized gains in the gain-shape coding of
* residual /* return the quantized value */
*---------------------------------------------------------------*/
float gaindequant( /* (o) quantized gain value */
int index, /* (i) quantization index */ return scale*cb[tindex];
float maxIn,/* (i) maximum of unquantized gain */ }
int cblen /* (i) number of quantization indices */
){ /*----------------------------------------------------------------*
float scale; * decoder for quantized gains in the gain-shape coding of
* residual
/* obtain correct scale factor */ *---------------------------------------------------------------*/
scale=(float)fabs(maxIn); float gaindequant( /* (o) quantized gain value */
int index, /* (i) quantization index */
if (scale<0.1) { float maxIn,/* (i) maximum of unquantized gain */
scale=(float)0.1; int cblen /* (i) number of quantization indices */
} ){
float scale;
/* select the quantization table and return the decoded value */
/* obtain correct scale factor */
if (cblen==8) {
return scale*gain_sq3Tbl[index]; scale=(float)fabs(maxIn);
} else if (cblen==16) {
return scale*gain_sq4Tbl[index]; if (scale<0.1) {
} scale=(float)0.1;
else if (cblen==32) { }
return scale*gain_sq5Tbl[index];
} /* select the quantization table and return the decoded value */
return 0.0; if (cblen==8) {
} return scale*gain_sq3Tbl[index];
} else if (cblen==16) {
return scale*gain_sq4Tbl[index];
}
else if (cblen==32) {
return scale*gain_sq5Tbl[index];
}
return 0.0;
}

View File

@@ -1,32 +1,31 @@
/****************************************************************** /******************************************************************
iLBC Speech Coder ANSI-C Source Code iLBC Speech Coder ANSI-C Source Code
gainquant.h gainquant.h
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/
******************************************************************/
#ifndef __iLBC_GAINQUANT_H
#ifndef __iLBC_GAINQUANT_H #define __iLBC_GAINQUANT_H
#define __iLBC_GAINQUANT_H
float gainquant(/* (o) quantized gain value */
float gainquant(/* (o) quantized gain value */ float in, /* (i) gain value */
float in, /* (i) gain value */ float maxIn,/* (i) maximum of gain value */
float maxIn,/* (i) maximum of gain value */ int cblen, /* (i) number of quantization indices */
int cblen, /* (i) number of quantization indices */ int *index /* (o) quantization index */
int *index /* (o) quantization index */ );
);
float gaindequant( /* (o) quantized gain value */
float gaindequant( /* (o) quantized gain value */ int index, /* (i) quantization index */
int index, /* (i) quantization index */ float maxIn,/* (i) maximum of unquantized gain */
float maxIn,/* (i) maximum of unquantized gain */ int cblen /* (i) number of quantization indices */
int cblen /* (i) number of quantization indices */ );
);
#endif
#endif

View File

@@ -1,172 +1,180 @@
/****************************************************************** /******************************************************************
iLBC Speech Coder ANSI-C Source Code iLBC Speech Coder ANSI-C Source Code
getCBvec.c getCBvec.c
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/
******************************************************************/
#include "iLBC_define.h"
#include "iLBC_define.h" #include "constants.h"
#include "constants.h" #include <string.h>
#include "getCBvec.h"
#include <string.h> /*----------------------------------------------------------------*
* Construct codebook vector for given index.
/*----------------------------------------------------------------* *---------------------------------------------------------------*/
* Construct codebook vector for given index.
*---------------------------------------------------------------*/ void getCBvec(
float *cbvec, /* (o) Constructed codebook vector */
void getCBvec( float *mem, /* (i) Codebook buffer */
float *cbvec, /* (o) Constructed codebook vector */ int index, /* (i) Codebook index */
float *mem, /* (i) Codebook buffer */ int lMem, /* (i) Length of codebook buffer */
int index, /* (i) Codebook index */ int cbveclen/* (i) Codebook vector length */
int lMem, /* (i) Length of codebook buffer */ ){
int cbveclen/* (i) Codebook vector length */ int j, k, n, memInd, sFilt;
){ float tmpbuf[CB_MEML];
int j, k, n, memInd, sFilt; int base_size;
float tmpbuf[CB_MEML]; int ilow, ihigh;
int base_size; float alfa, alfa1;
int ilow, ihigh;
float alfa, alfa1; /* Determine size of codebook sections */
/* Determine size of codebook sections */ base_size=lMem-cbveclen+1;
base_size=lMem-cbveclen+1; if (cbveclen==SUBL) {
base_size+=cbveclen/2;
if (cbveclen==SUBL) { }
base_size+=cbveclen/2;
} /* No filter -> First codebook section */
/* No filter -> First codebook section */
if (index<lMem-cbveclen+1) { if (index<lMem-cbveclen+1) {
/* first non-interpolated vectors */ /* first non-interpolated vectors */
k=index+cbveclen; k=index+cbveclen;
/* get vector */ /* get vector */
memcpy(cbvec, mem+lMem-k, cbveclen*sizeof(float)); memcpy(cbvec, mem+lMem-k, cbveclen*sizeof(float));
} else if (index < base_size) { } else if (index < base_size) {
k=2*(index-(lMem-cbveclen+1))+cbveclen; k=2*(index-(lMem-cbveclen+1))+cbveclen;
ihigh=k/2; ihigh=k/2;
ilow=ihigh-5; ilow=ihigh-5;
/* Copy first noninterpolated part */ /* Copy first noninterpolated part */
memcpy(cbvec, mem+lMem-k/2, ilow*sizeof(float)); memcpy(cbvec, mem+lMem-k/2, ilow*sizeof(float));
/* interpolation */ /* interpolation */
alfa1=(float)0.2; alfa1=(float)0.2;
alfa=0.0; alfa=0.0;
for (j=ilow; j<ihigh; j++) { for (j=ilow; j<ihigh; j++) {
cbvec[j]=((float)1.0-alfa)*mem[lMem-k/2+j]+ cbvec[j]=((float)1.0-alfa)*mem[lMem-k/2+j]+
alfa*mem[lMem-k+j]; alfa*mem[lMem-k+j];
alfa+=alfa1; alfa+=alfa1;
} }
/* Copy second noninterpolated part */ /* Copy second noninterpolated part */
memcpy(cbvec+ihigh, mem+lMem-k+ihigh, memcpy(cbvec+ihigh, mem+lMem-k+ihigh,
(cbveclen-ihigh)*sizeof(float)); (cbveclen-ihigh)*sizeof(float));
} }
/* Higher codebbok section based on filtering */ /* Higher codebbok section based on filtering */
else { else {
/* first non-interpolated vectors */ /* first non-interpolated vectors */
if (index-base_size<lMem-cbveclen+1) { if (index-base_size<lMem-cbveclen+1) {
float tempbuff2[CB_MEML+CB_FILTERLEN+1]; float tempbuff2[CB_MEML+CB_FILTERLEN+1];
float *pos; float *pos;
float *pp, *pp1; float *pp, *pp1;
memset(tempbuff2, 0, CB_HALFFILTERLEN*sizeof(float)); memset(tempbuff2, 0,
memcpy(&tempbuff2[CB_HALFFILTERLEN], mem, CB_HALFFILTERLEN*sizeof(float));
lMem*sizeof(float)); memcpy(&tempbuff2[CB_HALFFILTERLEN], mem,
memset(&tempbuff2[lMem+CB_HALFFILTERLEN], 0, lMem*sizeof(float));
(CB_HALFFILTERLEN+1)*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;
k=index-base_size+cbveclen;
/* do filtering */ sFilt=lMem-k;
pos=cbvec; memInd=sFilt+1-CB_HALFFILTERLEN;
memset(pos, 0, cbveclen*sizeof(float));
for (n=0; n<cbveclen; n++) { /* do filtering */
pp=&tempbuff2[memInd+n+CB_HALFFILTERLEN]; pos=cbvec;
pp1=&cbfiltersTbl[0]; memset(pos, 0, cbveclen*sizeof(float));
for (j=0;j<CB_FILTERLEN;j++) { for (n=0; n<cbveclen; n++) {
(*pos)+=(*pp++)*(*pp1++); pp=&tempbuff2[memInd+n+CB_HALFFILTERLEN];
} pp1=&cbfiltersTbl[CB_FILTERLEN-1];
pos++; for (j=0; j<CB_FILTERLEN; j++) {
} (*pos)+=(*pp++)*(*pp1--);
} }
pos++;
/* interpolated vectors */ }
}
else {
float tempbuff2[CB_MEML+CB_FILTERLEN+1]; /* interpolated vectors */
float *pos; else {
float *pp, *pp1; float tempbuff2[CB_MEML+CB_FILTERLEN+1];
int i;
float *pos;
memset(tempbuff2, 0, CB_HALFFILTERLEN*sizeof(float)); float *pp, *pp1;
memcpy(&tempbuff2[CB_HALFFILTERLEN], mem, int i;
lMem*sizeof(float));
memset(&tempbuff2[lMem+CB_HALFFILTERLEN], 0, memset(tempbuff2, 0,
(CB_HALFFILTERLEN+1)*sizeof(float)); CB_HALFFILTERLEN*sizeof(float));
memcpy(&tempbuff2[CB_HALFFILTERLEN], mem,
k=2*(index-base_size-(lMem-cbveclen+1))+cbveclen; lMem*sizeof(float));
sFilt=lMem-k; memset(&tempbuff2[lMem+CB_HALFFILTERLEN], 0,
memInd=sFilt+1-CB_HALFFILTERLEN; (CB_HALFFILTERLEN+1)*sizeof(float));
/* do filtering */ k=2*(index-base_size-
pos=&tmpbuf[sFilt]; (lMem-cbveclen+1))+cbveclen;
memset(pos, 0, k*sizeof(float)); sFilt=lMem-k;
for (i=0; i<k; i++) { memInd=sFilt+1-CB_HALFFILTERLEN;
pp=&tempbuff2[memInd+i+CB_HALFFILTERLEN];
pp1=&cbfiltersTbl[0]; /* do filtering */
for (j=0;j<CB_FILTERLEN;j++) { pos=&tmpbuf[sFilt];
(*pos)+=(*pp++)*(*pp1++); memset(pos, 0, k*sizeof(float));
} for (i=0; i<k; i++) {
pos++; pp=&tempbuff2[memInd+i+CB_HALFFILTERLEN];
} pp1=&cbfiltersTbl[CB_FILTERLEN-1];
for (j=0; j<CB_FILTERLEN; j++) {
ihigh=k/2; (*pos)+=(*pp++)*(*pp1--);
ilow=ihigh-5; }
pos++;
/* Copy first noninterpolated part */ }
memcpy(cbvec, tmpbuf+lMem-k/2, ilow*sizeof(float)); ihigh=k/2;
ilow=ihigh-5;
/* interpolation */
alfa1=(float)0.2;
alfa=0.0; /* Copy first noninterpolated part */
for (j=ilow; j<ihigh; j++) {
cbvec[j]=((float)1.0-alfa)* memcpy(cbvec, tmpbuf+lMem-k/2,
tmpbuf[lMem-k/2+j]+alfa*tmpbuf[lMem-k+j]; ilow*sizeof(float));
alfa+=alfa1;
} /* interpolation */
/* Copy second noninterpolated part */ alfa1=(float)0.2;
alfa=0.0;
memcpy(cbvec+ihigh, tmpbuf+lMem-k+ihigh, for (j=ilow; j<ihigh; j++) {
(cbveclen-ihigh)*sizeof(float)); cbvec[j]=((float)1.0-alfa)*
} tmpbuf[lMem-k/2+j]+alfa*tmpbuf[lMem-k+j];
} alfa+=alfa1;
} }
/* Copy second noninterpolated part */
memcpy(cbvec+ihigh, tmpbuf+lMem-k+ihigh,
(cbveclen-ihigh)*sizeof(float));
}
}
}

View File

@@ -1,27 +1,28 @@
/****************************************************************** /******************************************************************
iLBC Speech Coder ANSI-C Source Code iLBC Speech Coder ANSI-C Source Code
getCBvec.h getCBvec.h
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/
******************************************************************/
#ifndef __iLBC_GETCBVEC_H
#ifndef __iLBC_GETCBVEC_H #define __iLBC_GETCBVEC_H
#define __iLBC_GETCBVEC_H
void getCBvec(
float *cbvec, /* (o) Constructed codebook vector */ void getCBvec(
float *mem, /* (i) Codebook buffer */ float *cbvec, /* (o) Constructed codebook vector */
int index, /* (i) Codebook index */ float *mem, /* (i) Codebook buffer */
int lMem, /* (i) Length of codebook buffer */ int index, /* (i) Codebook index */
int cbveclen/* (i) Codebook vector length */ int lMem, /* (i) Length of codebook buffer */
); int cbveclen/* (i) Codebook vector length */
);
#endif
#endif

View File

@@ -1,294 +1,307 @@
/****************************************************************** /******************************************************************
iLBC Speech Coder ANSI-C Source Code iLBC Speech Coder ANSI-C Source Code
helpfun.c helpfun.c
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/
******************************************************************/
#include <math.h>
#include <math.h>
#include "iLBC_define.h"
#include "iLBC_define.h" #include "constants.h"
#include "helpfun.h"
#include "constants.h" /*----------------------------------------------------------------*
* calculation of auto correlation
/*----------------------------------------------------------------* *---------------------------------------------------------------*/
* calculation of auto correlation
*---------------------------------------------------------------*/ void autocorr(
float *r, /* (o) autocorrelation vector */
void autocorr( const float *x, /* (i) data vector */
float *r, /* (o) autocorrelation vector */ int N, /* (i) length of data vector */
const float *x, /* (i) data vector */ int order /* largest lag for calculated
int N, /* (i) length of data vector */ autocorrelations */
int order /* largest lag for calculated autocorrelations */ ){
){ int lag, n;
int lag, n; float sum;
float sum;
for (lag = 0; lag <= order; lag++) {
for (lag = 0; lag <= order; lag++) { sum = 0;
sum = 0; for (n = 0; n < N - lag; n++) {
for (n = 0; n < N - lag; n++) { sum += x[n] * x[n+lag];
sum += x[n] * x[n+lag]; }
} r[lag] = sum;
r[lag] = sum; }
} }
}
/*----------------------------------------------------------------*
* window multiplication /*----------------------------------------------------------------*
*---------------------------------------------------------------*/ * window multiplication
*---------------------------------------------------------------*/
void lbc_window(
float *z, /* (o) the windowed data */ void window(
const float *x, /* (i) the original data vector */ float *z, /* (o) the windowed data */
const float *y, /* (i) the window */ const float *x, /* (i) the original data vector */
int N /* (i) length of all vectors */ const float *y, /* (i) the window */
){ int N /* (i) length of all vectors */
int i; ){
int i;
for (i = 0; i < N; i++) {
z[i] = x[i] * y[i]; for (i = 0; i < N; i++) {
} z[i] = x[i] * y[i];
} }
}
/*----------------------------------------------------------------*
* levinson-durbin solution for lpc coefficients /*----------------------------------------------------------------*
*---------------------------------------------------------------*/ * levinson-durbin solution for lpc coefficients
*---------------------------------------------------------------*/
void levdurb(
float *a, /* (o) lpc coefficient vector starting with 1.0 void levdurb(
*/ float *a, /* (o) lpc coefficient vector starting
float *k, /* (o) reflection coefficients */ with 1.0 */
float *r, /* (i) autocorrelation vector */ float *k, /* (o) reflection coefficients */
int order /* (i) order of lpc filter */ float *r, /* (i) autocorrelation vector */
){ int order /* (i) order of lpc filter */
float sum, alpha; ){
int m, m_h, i; float sum, alpha;
int m, m_h, i;
a[0] = 1.0;
a[0] = 1.0;
if (r[0] < EPS) { /* if r[0] <= 0, set LPC coeff. to zero */
for (i = 0; i < order; i++) { if (r[0] < EPS) { /* if r[0] <= 0, set LPC coeff. to zero */
k[i] = 0; for (i = 0; i < order; i++) {
a[i+1] = 0; k[i] = 0;
} a[i+1] = 0;
} else { }
a[1] = k[0] = -r[1]/r[0]; } else {
alpha = r[0] + r[1] * k[0]; a[1] = k[0] = -r[1]/r[0];
for (m = 1; m < order; m++){ alpha = r[0] + r[1] * k[0];
sum = r[m + 1]; for (m = 1; m < order; m++){
for (i = 0; i < m; i++){ sum = r[m + 1];
sum += a[i+1] * r[m - i]; for (i = 0; i < m; i++){
} sum += a[i+1] * r[m - i];
k[m] = -sum / alpha; }
alpha += k[m] * sum; k[m] = -sum / alpha;
m_h = (m + 1) >> 1; alpha += k[m] * sum;
for (i = 0; i < m_h; i++){ m_h = (m + 1) >> 1;
sum = a[i+1] + k[m] * a[m - i]; for (i = 0; i < m_h; i++){
a[m - i] += k[m] * a[i+1]; sum = a[i+1] + k[m] * a[m - i];
a[i+1] = sum; a[m - i] += k[m] * a[i+1];
} a[i+1] = sum;
a[m+1] = k[m];
}
} }
} a[m+1] = k[m];
}
/*----------------------------------------------------------------* }
* interpolation between vectors }
*---------------------------------------------------------------*/
/*----------------------------------------------------------------*
void interpolate( * interpolation between vectors
float *out, /* (o) the interpolated vector */ *---------------------------------------------------------------*/
float *in1, /* (i) the first vector for the interpolation */
float *in2, /* (i) the second vector for the interpolation */ void interpolate(
float coef, /* (i) interpolation weights */ float *out, /* (o) the interpolated vector */
int length /* (i) length of all vectors */ float *in1, /* (i) the first vector for the
){ interpolation */
int i; float *in2, /* (i) the second vector for the
float invcoef; interpolation */
float coef, /* (i) interpolation weights */
invcoef = (float)1.0 - coef; int length /* (i) length of all vectors */
for (i = 0; i < length; i++) { ){
out[i] = coef * in1[i] + invcoef * in2[i]; int i;
} float invcoef;
}
invcoef = (float)1.0 - coef;
/*----------------------------------------------------------------* for (i = 0; i < length; i++) {
* lpc bandwidth expansion out[i] = coef * in1[i] + invcoef * in2[i];
*---------------------------------------------------------------*/ }
}
void bwexpand(
float *out, /* (o) the bandwidth expanded lpc coefficients */ /*----------------------------------------------------------------*
float *in, /* (i) the lpc coefficients before bandwidth * lpc bandwidth expansion
expansion */ *---------------------------------------------------------------*/
float coef, /* (i) the bandwidth expansion factor */
int length /* (i) the length of lpc coefficient vectors */ void bwexpand(
){ float *out, /* (o) the bandwidth expanded lpc
int i; coefficients */
float chirp; float *in, /* (i) the lpc coefficients before bandwidth
expansion */
chirp = coef; float coef, /* (i) the bandwidth expansion factor */
int length /* (i) the length of lpc coefficient vectors */
out[0] = in[0]; ){
for (i = 1; i < length; i++) { int i;
out[i] = chirp * in[i]; float chirp;
chirp *= coef;
} chirp = coef;
}
out[0] = in[0];
/*----------------------------------------------------------------* for (i = 1; i < length; i++) {
* vector quantization out[i] = chirp * in[i];
*---------------------------------------------------------------*/ chirp *= coef;
}
void vq( }
float *Xq, /* (o) the quantized vector */
int *index, /* (o) the quantization index */ /*----------------------------------------------------------------*
const float *CB,/* (i) the vector quantization codebook */ * vector quantization
float *X, /* (i) the vector to quantize */
int n_cb, /* (i) the number of vectors in the codebook */
int dim /* (i) the dimension of all vectors */ *---------------------------------------------------------------*/
){
int i, j; void vq(
int pos, minindex; float *Xq, /* (o) the quantized vector */
float dist, tmp, mindist; int *index, /* (o) the quantization index */
const float *CB,/* (i) the vector quantization codebook */
pos = 0; float *X, /* (i) the vector to quantize */
mindist = FLOAT_MAX; int n_cb, /* (i) the number of vectors in the codebook */
minindex = 0; int dim /* (i) the dimension of all vectors */
for (j = 0; j < n_cb; j++) { ){
dist = X[0] - CB[pos]; int i, j;
dist *= dist; int pos, minindex;
for (i = 1; i < dim; i++) { float dist, tmp, mindist;
tmp = X[i] - CB[pos + i];
dist += tmp*tmp; pos = 0;
} mindist = FLOAT_MAX;
minindex = 0;
if (dist < mindist) { for (j = 0; j < n_cb; j++) {
mindist = dist; dist = X[0] - CB[pos];
minindex = j; dist *= dist;
} for (i = 1; i < dim; i++) {
pos += dim; tmp = X[i] - CB[pos + i];
} dist += tmp*tmp;
for (i = 0; i < dim; i++) { }
Xq[i] = CB[minindex*dim + i];
} if (dist < mindist) {
*index = minindex; mindist = dist;
} minindex = j;
}
/*----------------------------------------------------------------* pos += dim;
* split vector quantization }
*---------------------------------------------------------------*/ for (i = 0; i < dim; i++) {
Xq[i] = CB[minindex*dim + i];
void SplitVQ( }
float *qX, /* (o) the quantized vector */ *index = minindex;
int *index, /* (o) a vector of indexes for all vector }
codebooks in the split */
float *X, /* (i) the vector to quantize */ /*----------------------------------------------------------------*
const float *CB,/* (i) the quantizer codebook */ * split vector quantization
int nsplit, /* the number of vector splits */ *---------------------------------------------------------------*/
const int *dim, /* the dimension of X and qX */
const int *cbsize /* the number of vectors in the codebook */ void SplitVQ(
){ float *qX, /* (o) the quantized vector */
int cb_pos, X_pos, i; int *index, /* (o) a vector of indexes for all vector
codebooks in the split */
cb_pos = 0; float *X, /* (i) the vector to quantize */
X_pos= 0; const float *CB,/* (i) the quantizer codebook */
for (i = 0; i < nsplit; i++) { int nsplit, /* the number of vector splits */
vq(qX + X_pos, index + i, CB + cb_pos, X + X_pos, const int *dim, /* the dimension of X and qX */
cbsize[i], dim[i]); const int *cbsize /* the number of vectors in the codebook */
X_pos += dim[i]; ){
cb_pos += dim[i] * cbsize[i]; int cb_pos, X_pos, i;
}
} cb_pos = 0;
/*----------------------------------------------------------------*
* scalar quantization X_pos= 0;
*---------------------------------------------------------------*/ for (i = 0; i < nsplit; i++) {
vq(qX + X_pos, index + i, CB + cb_pos, X + X_pos,
void sort_sq( cbsize[i], dim[i]);
float *xq, /* (o) the quantized value */ X_pos += dim[i];
int *index, /* (o) the quantization index */ cb_pos += dim[i] * cbsize[i];
float x, /* (i) the value to quantize */ }
const float *cb,/* (i) the quantization codebook */ }
int cb_size /* (i) the size of the quantization codebook */
){ /*----------------------------------------------------------------*
int i; * scalar quantization
*---------------------------------------------------------------*/
if (x <= cb[0]) {
*index = 0; void sort_sq(
*xq = cb[0]; float *xq, /* (o) the quantized value */
} else { int *index, /* (o) the quantization index */
i = 0; float x, /* (i) the value to quantize */
while ((x > cb[i]) && i < cb_size - 1) { const float *cb,/* (i) the quantization codebook */
i++; int cb_size /* (i) the size of the quantization codebook */
} ){
int i;
if (x > ((cb[i] + cb[i - 1])/2)) {
*index = i; if (x <= cb[0]) {
*xq = cb[i]; *index = 0;
} else { *xq = cb[0];
*index = i - 1; } else {
*xq = cb[i - 1]; i = 0;
} while ((x > cb[i]) && i < cb_size - 1) {
} i++;
} }
/*----------------------------------------------------------------* if (x > ((cb[i] + cb[i - 1])/2)) {
* check for stability of lsf coefficients *index = i;
*---------------------------------------------------------------*/ *xq = cb[i];
} else {
int LSF_check( /* (o) 1 for stable lsf vectors and 0 for *index = i - 1;
nonstable ones */ *xq = cb[i - 1];
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 k,n,m, Nit=2, change=0,pos; /*----------------------------------------------------------------*
float tmp; * check for stability of lsf coefficients
static float eps=(float)0.039; /* 50 Hz */ *---------------------------------------------------------------*/
static float eps2=(float)0.0195;
static float maxlsf=(float)3.14; /* 4000 Hz */ int LSF_check( /* (o) 1 for stable lsf vectors and 0 for
static float minlsf=(float)0.01; /* 0 Hz */ nonstable ones */
float *lsf, /* (i) a table of lsf vectors */
/* LSF separation check*/ int dim, /* (i) the dimension of each lsf vector */
int NoAn /* (i) the number of lsf vectors in the
for (n=0;n<Nit;n++) { /* Run through a couple of times */ table */
for (m=0;m<NoAn;m++) { /* Number of analyses per frame */ ){
for (k=0;k<(dim-1);k++) { int k,n,m, Nit=2, change=0,pos;
pos=m*dim+k; float tmp;
if ((lsf[pos+1]-lsf[pos])<eps) {
static float eps=(float)0.039; /* 50 Hz */
if (lsf[pos+1]<lsf[pos]) { static float eps2=(float)0.0195;
tmp=lsf[pos+1]; static float maxlsf=(float)3.14; /* 4000 Hz */
lsf[pos+1]= lsf[pos]+eps2; static float minlsf=(float)0.01; /* 0 Hz */
lsf[pos]= lsf[pos+1]-eps2;
} else { /* LSF separation check*/
lsf[pos]-=eps2;
lsf[pos+1]+=eps2; for (n=0; n<Nit; n++) { /* Run through a couple of times */
} for (m=0; m<NoAn; m++) { /* Number of analyses per frame */
change=1; for (k=0; k<(dim-1); k++) {
} pos=m*dim+k;
if (lsf[pos]<minlsf) { if ((lsf[pos+1]-lsf[pos])<eps) {
lsf[pos]=minlsf;
change=1; if (lsf[pos+1]<lsf[pos]) {
} tmp=lsf[pos+1];
lsf[pos+1]= lsf[pos]+eps2;
if (lsf[pos]>maxlsf) { lsf[pos]= lsf[pos+1]-eps2;
lsf[pos]=maxlsf; } else {
change=1; lsf[pos]-=eps2;
} lsf[pos+1]+=eps2;
} }
} change=1;
} }
return change; if (lsf[pos]<minlsf) {
} lsf[pos]=minlsf;
change=1;
}
if (lsf[pos]>maxlsf) {
lsf[pos]=maxlsf;
change=1;
}
}
}
}
return change;
}

View File

@@ -1,93 +1,101 @@
/****************************************************************** /******************************************************************
iLBC Speech Coder ANSI-C Source Code iLBC Speech Coder ANSI-C Source Code
helpfun.h helpfun.h
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/
******************************************************************/
#ifndef __iLBC_HELPFUN_H
#ifndef __iLBC_HELPFUN_H #define __iLBC_HELPFUN_H
#define __iLBC_HELPFUN_H
void autocorr(
void autocorr( float *r, /* (o) autocorrelation vector */
float *r, /* (o) autocorrelation vector */ const float *x, /* (i) data vector */
const float *x, /* (i) data vector */ int N, /* (i) length of data vector */
int N, /* (i) length of data vector */ int order /* largest lag for calculated
int order /* largest lag for calculated autocorrelations */ autocorrelations */
); );
void lbc_window( void window(
float *z, /* (o) the windowed data */ float *z, /* (o) the windowed data */
const float *x, /* (i) the original data vector */ const float *x, /* (i) the original data vector */
const float *y, /* (i) the window */ const float *y, /* (i) the window */
int N /* (i) length of all vectors */ int N /* (i) length of all vectors */
); );
void levdurb(
float *a, /* (o) lpc coefficient vector starting
with 1.0 */ void levdurb(
float *k, /* (o) reflection coefficients */ float *a, /* (o) lpc coefficient vector starting
float *r, /* (i) autocorrelation vector */ with 1.0 */
int order /* (i) order of lpc filter */ float *k, /* (o) reflection coefficients */
); float *r, /* (i) autocorrelation vector */
int order /* (i) order of lpc filter */
void interpolate( );
float *out, /* (o) the interpolated vector */
float *in1, /* (i) the first vector for the interpolation */ void interpolate(
float *in2, /* (i) the second vector for the interpolation */ float *out, /* (o) the interpolated vector */
float coef, /* (i) interpolation weights */ float *in1, /* (i) the first vector for the
int length /* (i) length of all vectors */ interpolation */
); float *in2, /* (i) the second vector for the
interpolation */
void bwexpand( float coef, /* (i) interpolation weights */
float *out, /* (o) the bandwidth expanded lpc coefficients */ int length /* (i) length of all vectors */
float *in, /* (i) the lpc coefficients before bandwidth );
expansion */
float coef, /* (i) the bandwidth expansion factor */ void bwexpand(
int length /* (i) the length of lpc coefficient vectors */ float *out, /* (o) the bandwidth expanded lpc
); coefficients */
float *in, /* (i) the lpc coefficients before bandwidth
void vq( expansion */
float *Xq, /* (o) the quantized vector */ float coef, /* (i) the bandwidth expansion factor */
int *index, /* (o) the quantization index */ int length /* (i) the length of lpc coefficient vectors */
const float *CB,/* (i) the vector quantization codebook */ );
float *X, /* (i) the vector to quantize */
int n_cb, /* (i) the number of vectors in the codebook */ void vq(
int dim /* (i) the dimension of all vectors */ float *Xq, /* (o) the quantized vector */
); int *index, /* (o) the quantization index */
const float *CB,/* (i) the vector quantization codebook */
void SplitVQ( float *X, /* (i) the vector to quantize */
float *qX, /* (o) the quantized vector */ int n_cb, /* (i) the number of vectors in the codebook */
int *index, /* (o) a vector of indexes for all vector int dim /* (i) the dimension of all vectors */
codebooks in the split */ );
float *X, /* (i) the vector to quantize */
const float *CB,/* (i) the quantizer codebook */ void SplitVQ(
int nsplit, /* the number of vector splits */ float *qX, /* (o) the quantized vector */
const int *dim, /* the dimension of X and qX */ int *index, /* (o) a vector of indexes for all vector
const int *cbsize /* the number of vectors in the codebook */ codebooks in the split */
); float *X, /* (i) the vector to quantize */
const float *CB,/* (i) the quantizer codebook */
int nsplit, /* the number of vector splits */
void sort_sq( const int *dim, /* the dimension of X and qX */
float *xq, /* (o) the quantized value */ const int *cbsize /* the number of vectors in the codebook */
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 */ void sort_sq(
); float *xq, /* (o) the quantized value */
int *index, /* (o) the quantization index */
int LSF_check( /* (o) 1 for stable lsf vectors and 0 for float x, /* (i) the value to quantize */
nonstable ones */ const float *cb,/* (i) the quantization codebook */
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 cb_size /* (i) the size of the quantization codebook */
); );
#endif 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 */
);
#endif

View File

@@ -1,59 +1,59 @@
/****************************************************************** /******************************************************************
iLBC Speech Coder ANSI-C Source Code iLBC Speech Coder ANSI-C Source Code
hpInput.c hpInput.c
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/
******************************************************************/
#include "constants.h"
#include "constants.h"
#include "hpInput.h" /*----------------------------------------------------------------*
* Input high-pass filter
/*----------------------------------------------------------------* *---------------------------------------------------------------*/
* Input high-pass filter
*---------------------------------------------------------------*/ void hpInput(
float *In, /* (i) vector to filter */
void hpInput( int len, /* (i) length of vector to filter */
float *In, /* (i) vector to filter */ float *Out, /* (o) the resulting filtered vector */
int len, /* (i) length of vector to filter */ float *mem /* (i/o) the filter state */
float *Out, /* (o) the resulting filtered vector */ ){
float *mem /* (i/o) the filter state */ int i;
){ float *pi, *po;
int i;
float *pi, *po; /* all-zero section*/
/* all-zero section*/ pi = &In[0];
po = &Out[0];
pi = &In[0]; for (i=0; i<len; i++) {
po = &Out[0]; *po = hpi_zero_coefsTbl[0] * (*pi);
for (i=0; i<len; i++) { *po += hpi_zero_coefsTbl[1] * mem[0];
*po = hpi_zero_coefsTbl[0] * (*pi); *po += hpi_zero_coefsTbl[2] * mem[1];
*po += hpi_zero_coefsTbl[1] * mem[0];
*po += hpi_zero_coefsTbl[2] * mem[1]; mem[1] = mem[0];
mem[0] = *pi;
mem[1] = mem[0]; po++;
mem[0] = *pi;
po++;
pi++; pi++;
} }
/* all-pole section*/ /* all-pole section*/
po = &Out[0]; po = &Out[0];
for (i=0; i<len; i++) { for (i=0; i<len; i++) {
*po -= hpi_pole_coefsTbl[1] * mem[2]; *po -= hpi_pole_coefsTbl[1] * mem[2];
*po -= hpi_pole_coefsTbl[2] * mem[3]; *po -= hpi_pole_coefsTbl[2] * mem[3];
mem[3] = mem[2]; mem[3] = mem[2];
mem[2] = *po; mem[2] = *po;
po++; po++;
} }
} }

View File

@@ -1,26 +1,27 @@
/****************************************************************** /******************************************************************
iLBC Speech Coder ANSI-C Source Code iLBC Speech Coder ANSI-C Source Code
hpInput.h hpInput.h
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/
******************************************************************/
#ifndef __iLBC_HPINPUT_H
#define __iLBC_HPINPUT_H #ifndef __iLBC_HPINPUT_H
#define __iLBC_HPINPUT_H
void hpInput(
float *In, /* (i) vector to filter */ void hpInput(
int len, /* (i) length of vector to filter */ float *In, /* (i) vector to filter */
float *Out, /* (o) the resulting filtered vector */ int len, /* (i) length of vector to filter */
float *mem /* (i/o) the filter state */ float *Out, /* (o) the resulting filtered vector */
); float *mem /* (i/o) the filter state */
);
#endif
#endif

View File

@@ -1,59 +1,59 @@
/****************************************************************** /******************************************************************
iLBC Speech Coder ANSI-C Source Code iLBC Speech Coder ANSI-C Source Code
hpOutput.c hpOutput.c
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/
******************************************************************/
#include "constants.h"
#include "hpOutput.h" #include "constants.h"
/*----------------------------------------------------------------* /*----------------------------------------------------------------*
* Output high-pass filter * Output high-pass filter
*---------------------------------------------------------------*/ *---------------------------------------------------------------*/
void hpOutput( void hpOutput(
float *In, /* (i) vector to filter */ float *In, /* (i) vector to filter */
int len,/* (i) length of vector to filter */ int len,/* (i) length of vector to filter */
float *Out, /* (o) the resulting filtered vector */ float *Out, /* (o) the resulting filtered vector */
float *mem /* (i/o) the filter state */ float *mem /* (i/o) the filter state */
){ ){
int i; int i;
float *pi, *po; float *pi, *po;
/* all-zero section*/ /* all-zero section*/
pi = &In[0]; pi = &In[0];
po = &Out[0]; po = &Out[0];
for (i=0; i<len; i++) { for (i=0; i<len; i++) {
*po = hpo_zero_coefsTbl[0] * (*pi); *po = hpo_zero_coefsTbl[0] * (*pi);
*po += hpo_zero_coefsTbl[1] * mem[0]; *po += hpo_zero_coefsTbl[1] * mem[0];
*po += hpo_zero_coefsTbl[2] * mem[1]; *po += hpo_zero_coefsTbl[2] * mem[1];
mem[1] = mem[0]; mem[1] = mem[0];
mem[0] = *pi; mem[0] = *pi;
po++; po++;
pi++; pi++;
} }
/* all-pole section*/ /* all-pole section*/
po = &Out[0]; po = &Out[0];
for (i=0; i<len; i++) { for (i=0; i<len; i++) {
*po -= hpo_pole_coefsTbl[1] * mem[2]; *po -= hpo_pole_coefsTbl[1] * mem[2];
*po -= hpo_pole_coefsTbl[2] * mem[3]; *po -= hpo_pole_coefsTbl[2] * mem[3];
mem[3] = mem[2]; mem[3] = mem[2];
mem[2] = *po; mem[2] = *po;
po++; po++;
} }
} }

View File

@@ -1,26 +1,25 @@
/****************************************************************** /******************************************************************
iLBC Speech Coder ANSI-C Source Code iLBC Speech Coder ANSI-C Source Code
hpOutput.h hpOutput.h
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/
******************************************************************/
#ifndef __iLBC_HPOUTPUT_H
#ifndef __iLBC_HPOUTPUT_H #define __iLBC_HPOUTPUT_H
#define __iLBC_HPOUTPUT_H
void hpOutput(
void hpOutput( float *In, /* (i) vector to filter */
float *In, /* (i) vector to filter */ int len,/* (i) length of vector to filter */
int len,/* (i) length of vector to filter */ float *Out, /* (o) the resulting filtered vector */
float *Out, /* (o) the resulting filtered vector */ float *mem /* (i/o) the filter state */
float *mem /* (i/o) the filter state */ );
);
#endif
#endif

View File

@@ -1,105 +1,107 @@
/****************************************************************** /******************************************************************
iLBC Speech Coder ANSI-C Source Code iLBC Speech Coder ANSI-C Source Code
iCBConstruct.c iCBConstruct.c
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/
******************************************************************/
#include <math.h>
#include <math.h>
#include "iLBC_define.h"
#include "iLBC_define.h" #include "gainquant.h"
#include "gainquant.h" #include "getCBvec.h"
#include "getCBvec.h"
#include "iCBConstruct.h" /*----------------------------------------------------------------*
* Convert the codebook indexes to make the search easier
/*----------------------------------------------------------------* *---------------------------------------------------------------*/
* Convert the codebook indexes to make the search easier
*---------------------------------------------------------------*/
void index_conv_enc( void index_conv_enc(
int *index /* (i/o) Codebook indexes */ int *index /* (i/o) Codebook indexes */
){ ){
int k; int k;
for (k=1;k<CB_NSTAGES;k++) { for (k=1; k<CB_NSTAGES; k++) {
if ((index[k]>=108)&&(index[k]<172)) { if ((index[k]>=108)&&(index[k]<172)) {
index[k]-=64; index[k]-=64;
} else if (index[k]>=236) { } else if (index[k]>=236) {
index[k]-=128; index[k]-=128;
} else { } else {
/* ERROR */ /* ERROR */
} }
} }
} }
void index_conv_dec( void index_conv_dec(
int *index /* (i/o) Codebook indexes */ int *index /* (i/o) Codebook indexes */
){ ){
int k; int k;
for (k=1;k<CB_NSTAGES;k++) { for (k=1; k<CB_NSTAGES; k++) {
if ((index[k]>=44)&&(index[k]<108)) { if ((index[k]>=44)&&(index[k]<108)) {
index[k]+=64; index[k]+=64;
} else if ((index[k]>=108)&&(index[k]<128)) { } else if ((index[k]>=108)&&(index[k]<128)) {
index[k]+=128; index[k]+=128;
} else { } else {
/* ERROR */ /* ERROR */
} }
} }
} }
/*----------------------------------------------------------------* /*----------------------------------------------------------------*
* Construct decoded vector from codebook and gains. * Construct decoded vector from codebook and gains.
*---------------------------------------------------------------*/ *---------------------------------------------------------------*/
void iCBConstruct( void iCBConstruct(
float *decvector, /* (o) Decoded vector */ float *decvector, /* (o) Decoded vector */
int *index, /* (i) Codebook indices */ int *index, /* (i) Codebook indices */
int *gain_index,/* (i) Gain quantization indices */ int *gain_index,/* (i) Gain quantization indices */
float *mem, /* (i) Buffer for codevector construction */ float *mem, /* (i) Buffer for codevector construction */
int lMem, /* (i) Length of buffer */ int lMem, /* (i) Length of buffer */
int veclen, /* (i) Length of vector */ int veclen, /* (i) Length of vector */
int nStages /* (i) Number of codebook stages */ int nStages /* (i) Number of codebook stages */
){ ){
int j,k; int j,k;
float gain[CB_NSTAGES]; float gain[CB_NSTAGES];
float cbvec[SUBL]; float cbvec[SUBL];
/* gain de-quantization */ /* gain de-quantization */
gain[0] = gaindequant(gain_index[0], 1.0, 32); gain[0] = gaindequant(gain_index[0], 1.0, 32);
if (nStages > 1) {
gain[1] = gaindequant(gain_index[1],
(float)fabs(gain[0]), 16); if (nStages > 1) {
} gain[1] = gaindequant(gain_index[1],
if (nStages > 2) { (float)fabs(gain[0]), 16);
gain[2] = gaindequant(gain_index[2], }
(float)fabs(gain[1]), 8); if (nStages > 2) {
} gain[2] = gaindequant(gain_index[2],
(float)fabs(gain[1]), 8);
/* codebook vector construction and construction of }
total vector */
/* codebook vector construction and construction of
getCBvec(cbvec, mem, index[0], lMem, veclen); total vector */
for (j=0;j<veclen;j++){
decvector[j] = gain[0]*cbvec[j]; getCBvec(cbvec, mem, index[0], lMem, veclen);
} for (j=0;j<veclen;j++){
if (nStages > 1) { decvector[j] = gain[0]*cbvec[j];
for (k=1; k<nStages; k++) { }
getCBvec(cbvec, mem, index[k], lMem, veclen); if (nStages > 1) {
for (j=0;j<veclen;j++) { for (k=1; k<nStages; k++) {
decvector[j] += gain[k]*cbvec[j]; getCBvec(cbvec, mem, index[k], lMem, veclen);
} for (j=0;j<veclen;j++) {
} decvector[j] += gain[k]*cbvec[j];
} }
} }
}
}

View File

@@ -1,37 +1,38 @@
/****************************************************************** /******************************************************************
iLBC Speech Coder ANSI-C Source Code iLBC Speech Coder ANSI-C Source Code
iCBConstruct.h
Copyright (c) 2001, iCBConstruct.h
Global IP Sound AB.
All rights reserved. Copyright (C) The Internet Society (2004).
All Rights Reserved.
******************************************************************/
******************************************************************/
#ifndef __iLBC_ICBCONSTRUCT_H
#define __iLBC_ICBCONSTRUCT_H #ifndef __iLBC_ICBCONSTRUCT_H
#define __iLBC_ICBCONSTRUCT_H
void index_conv_enc(
int *index /* (i/o) Codebook indexes */ void index_conv_enc(
); int *index /* (i/o) Codebook indexes */
);
void index_conv_dec(
int *index /* (i/o) Codebook indexes */ void index_conv_dec(
); int *index /* (i/o) Codebook indexes */
);
void iCBConstruct(
float *decvector, /* (o) Decoded vector */ void iCBConstruct(
int *index, /* (i) Codebook indices */ float *decvector, /* (o) Decoded vector */
int *gain_index,/* (i) Gain quantization indices */ int *index, /* (i) Codebook indices */
float *mem, /* (i) Buffer for codevector construction */ int *gain_index,/* (i) Gain quantization indices */
int lMem, /* (i) Length of buffer */ float *mem, /* (i) Buffer for codevector construction */
int veclen, /* (i) Length of vector */ int lMem, /* (i) Length of buffer */
int nStages /* (i) Number of codebook stages */ int veclen, /* (i) Length of vector */
); int nStages /* (i) Number of codebook stages */
);
#endif
#endif

View File

@@ -1,464 +1,477 @@
/****************************************************************** /******************************************************************
iLBC Speech Coder ANSI-C Source Code iLBC Speech Coder ANSI-C Source Code
iCBSearch.c iCBSearch.c
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/
******************************************************************/
#include <math.h>
#include <math.h> #include <string.h>
#include <string.h>
#include "iLBC_define.h"
#include "iLBC_define.h" #include "gainquant.h"
#include "iCBSearch.h" #include "createCB.h"
#include "gainquant.h" #include "filter.h"
#include "createCB.h" #include "constants.h"
#include "filter.h"
#include "constants.h" /*----------------------------------------------------------------*
* Search routine for codebook encoding and gain quantization.
/*----------------------------------------------------------------* *---------------------------------------------------------------*/
* Search routine for codebook encoding and gain quantization.
*---------------------------------------------------------------*/ void iCBSearch(
iLBC_Enc_Inst_t *iLBCenc_inst,
void iCBSearch( /* (i) the encoder state structure */
int *index, /* (o) Codebook indices */ int *index, /* (o) Codebook indices */
int *gain_index,/* (o) Gain quantization indices */ int *gain_index,/* (o) Gain quantization indices */
float *intarget,/* (i) Target vector for encoding */ float *intarget,/* (i) Target vector for encoding */
float *mem, /* (i) Buffer for codebook construction */ float *mem, /* (i) Buffer for codebook construction */
int lMem, /* (i) Length of buffer */ int lMem, /* (i) Length of buffer */
int lTarget, /* (i) Length of vector */ int lTarget, /* (i) Length of vector */
int nStages, /* (i) Number of codebook stages */ int nStages, /* (i) Number of codebook stages */
float *weightDenum, /* (i) weighting filter coefficients */ float *weightDenum, /* (i) weighting filter coefficients */
float *weightState, /* (i) weighting filter state */ float *weightState, /* (i) weighting filter state */
int block /* (i) the subblock number */ int block /* (i) the sub-block number */
){ ){
int i, j, icount, stage, best_index, range, counter; int i, j, icount, stage, best_index, range, counter;
float max_measure, gain, measure, crossDot, ftmp; float max_measure, gain, measure, crossDot, ftmp;
float gains[CB_NSTAGES]; float gains[CB_NSTAGES];
float target[SUBL]; float target[SUBL];
int base_index, sInd, eInd, base_size; int base_index, sInd, eInd, base_size;
int sIndAug=0, eIndAug=0; int sIndAug=0, eIndAug=0;
float buf[CB_MEML+SUBL+2*LPC_FILTERORDER]; float buf[CB_MEML+SUBL+2*LPC_FILTERORDER];
float invenergy[CB_EXPAND*128], energy[CB_EXPAND*128];
float *pp, *ppi=0, *ppo=0, *ppe=0;
float cbvectors[CB_MEML]; float invenergy[CB_EXPAND*128], energy[CB_EXPAND*128];
float tene, cene, cvec[SUBL]; float *pp, *ppi=0, *ppo=0, *ppe=0;
float aug_vec[SUBL]; float cbvectors[CB_MEML];
float tene, cene, cvec[SUBL];
memset(cvec,0,SUBL*sizeof(float)); float aug_vec[SUBL];
/* Determine size of codebook sections */ memset(cvec,0,SUBL*sizeof(float));
base_size=lMem-lTarget+1; /* Determine size of codebook sections */
if (lTarget==SUBL) { base_size=lMem-lTarget+1;
base_size=lMem-lTarget+1+lTarget/2;
} if (lTarget==SUBL) {
base_size=lMem-lTarget+1+lTarget/2;
/* setup buffer for weighting */ }
memcpy(buf,weightState,sizeof(float)*LPC_FILTERORDER); /* setup buffer for weighting */
memcpy(buf+LPC_FILTERORDER,mem,lMem*sizeof(float));
memcpy(buf+LPC_FILTERORDER+lMem,intarget,lTarget*sizeof(float)); memcpy(buf,weightState,sizeof(float)*LPC_FILTERORDER);
memcpy(buf+LPC_FILTERORDER,mem,lMem*sizeof(float));
/* weighting */ memcpy(buf+LPC_FILTERORDER+lMem,intarget,lTarget*sizeof(float));
AllPoleFilter(buf+LPC_FILTERORDER, weightDenum, /* weighting */
lMem+lTarget, LPC_FILTERORDER);
AllPoleFilter(buf+LPC_FILTERORDER, weightDenum,
/* Construct the codebook and target needed */ lMem+lTarget, LPC_FILTERORDER);
memcpy(target, buf+LPC_FILTERORDER+lMem, lTarget*sizeof(float)); /* Construct the codebook and target needed */
tene=0.0; memcpy(target, buf+LPC_FILTERORDER+lMem, lTarget*sizeof(float));
for (i=0;i<lTarget;i++) {
tene+=target[i]*target[i]; tene=0.0;
} for (i=0; i<lTarget; i++) {
tene+=target[i]*target[i];
/* Prepare search over one more codebook section. This section }
is created by filtering the original buffer with a filter. */
/* Prepare search over one more codebook section. This section
filteredCBvecs(cbvectors, buf+LPC_FILTERORDER, lMem); is created by filtering the original buffer with a filter. */
/* The Main Loop over stages */ filteredCBvecs(cbvectors, buf+LPC_FILTERORDER, lMem);
for (stage=0;stage<nStages; stage++) { /* The Main Loop over stages */
range = search_rangeTbl[block][stage]; for (stage=0; stage<nStages; stage++) {
/* initialize search measure */ range = search_rangeTbl[block][stage];
max_measure = (float)-10000000.0; /* initialize search measure */
gain = (float)0.0;
best_index = 0; max_measure = (float)-10000000.0;
gain = (float)0.0;
/* Compute cross dot product between the target best_index = 0;
and the CB memory */
/* Compute cross dot product between the target
crossDot=0.0;
pp=buf+LPC_FILTERORDER+lMem-lTarget;
for (j=0; j<lTarget; j++) { and the CB memory */
crossDot += target[j]*(*pp++);
} crossDot=0.0;
pp=buf+LPC_FILTERORDER+lMem-lTarget;
if (stage==0) { for (j=0; j<lTarget; j++) {
crossDot += target[j]*(*pp++);
/* Calculate energy in the first block of }
'lTarget' sampels. */
ppe = energy; if (stage==0) {
ppi = buf+LPC_FILTERORDER+lMem-lTarget-1;
ppo = buf+LPC_FILTERORDER+lMem-1; /* Calculate energy in the first block of
'lTarget' sampels. */
*ppe=0.0; ppe = energy;
pp=buf+LPC_FILTERORDER+lMem-lTarget; ppi = buf+LPC_FILTERORDER+lMem-lTarget-1;
for (j=0; j<lTarget; j++) { ppo = buf+LPC_FILTERORDER+lMem-1;
*ppe+=(*pp)*(*pp);
pp++; *ppe=0.0;
} pp=buf+LPC_FILTERORDER+lMem-lTarget;
for (j=0; j<lTarget; j++) {
if(*ppe>0.0) { *ppe+=(*pp)*(*pp++);
invenergy[0] = (float) 1.0 / (*ppe + EPS); }
} else {
invenergy[0] = (float) 0.0; if (*ppe>0.0) {
} invenergy[0] = (float) 1.0 / (*ppe + EPS);
ppe++; } else {
invenergy[0] = (float) 0.0;
measure=(float)-10000000.0; }
ppe++;
if (crossDot > 0.0) {
measure = crossDot*crossDot*invenergy[0]; measure=(float)-10000000.0;
}
} if (crossDot > 0.0) {
else { measure = crossDot*crossDot*invenergy[0];
measure = crossDot*crossDot*invenergy[0]; }
} }
else {
/* check if measure is better */ measure = crossDot*crossDot*invenergy[0];
ftmp = crossDot*invenergy[0]; }
if ((measure>max_measure) && (fabs(ftmp)<CB_MAXGAIN)) { /* check if measure is better */
best_index = 0; ftmp = crossDot*invenergy[0];
max_measure = measure;
gain = ftmp; if ((measure>max_measure) && (fabs(ftmp)<CB_MAXGAIN)) {
} best_index = 0;
max_measure = measure;
/* loop over lags 40+ in the first codebook section, gain = ftmp;
full search */ }
for (icount=1; icount<range; icount++) { /* loop over the main first codebook section,
full search */
/* calculate measure */
for (icount=1; icount<range; icount++) {
crossDot=0.0;
pp = buf+LPC_FILTERORDER+lMem-lTarget-icount; /* calculate measure */
for (j=0;j<lTarget;j++) {
crossDot += target[j]*(*pp++);
} crossDot=0.0;
pp = buf+LPC_FILTERORDER+lMem-lTarget-icount;
if (stage==0) {
*ppe++ = energy[icount-1] + (*ppi)*(*ppi) - for (j=0; j<lTarget; j++) {
(*ppo)*(*ppo); crossDot += target[j]*(*pp++);
ppo--; }
ppi--;
if (stage==0) {
if(energy[icount]>0.0) { *ppe++ = energy[icount-1] + (*ppi)*(*ppi) -
invenergy[icount] = (*ppo)*(*ppo);
(float)1.0/(energy[icount]+EPS); ppo--;
} else { ppi--;
invenergy[icount] = (float) 0.0;
} if (energy[icount]>0.0) {
invenergy[icount] =
measure=(float)-10000000.0; (float)1.0/(energy[icount]+EPS);
} else {
if (crossDot > 0.0) { invenergy[icount] = (float) 0.0;
measure = crossDot*crossDot*invenergy[icount]; }
}
} measure=(float)-10000000.0;
else {
measure = crossDot*crossDot*invenergy[icount]; if (crossDot > 0.0) {
} measure = crossDot*crossDot*invenergy[icount];
}
/* check if measure is better */ }
ftmp = crossDot*invenergy[icount]; else {
measure = crossDot*crossDot*invenergy[icount];
}
if ((measure>max_measure) && (fabs(ftmp)<CB_MAXGAIN)){
best_index = icount; /* check if measure is better */
max_measure = measure; ftmp = crossDot*invenergy[icount];
gain = ftmp;
} if ((measure>max_measure) && (fabs(ftmp)<CB_MAXGAIN)) {
} best_index = icount;
max_measure = measure;
/* Loop over lags 20-39 in the first codebook section, gain = ftmp;
* full search. }
* The vectors are interpolated. }
*/
/* Loop over augmented part in the first codebook
if(lTarget==SUBL) { * section, full search.
* The vectors are interpolated.
/* Search for best possible lag and compute */
the CB-vectors' energy. */
if (lTarget==SUBL) {
searchAugmentedCB(20, 39, stage, base_size-lTarget/2,
target, buf+LPC_FILTERORDER+lMem, /* Search for best possible cb vector and
&max_measure, &best_index, &gain, energy, invenergy); compute the CB-vectors' energy. */
searchAugmentedCB(20, 39, stage, base_size-lTarget/2,
} target, buf+LPC_FILTERORDER+lMem,
&max_measure, &best_index, &gain, energy,
/* set search range for following codebook sections */ invenergy);
base_index=best_index;
}
/* unrestricted search */
/* set search range for following codebook sections */
if (CB_RESRANGE == -1) {
sInd=0; base_index=best_index;
eInd=range-1;
sIndAug=20; /* unrestricted search */
eIndAug=39;
} if (CB_RESRANGE == -1) {
sInd=0;
/* restriced search around best index from first eInd=range-1;
codebook section */ sIndAug=20;
eIndAug=39;
else { }
/* Initialize search indices */
sIndAug=0; /* restriced search around best index from first
eIndAug=0; codebook section */
sInd=base_index-CB_RESRANGE/2;
eInd=sInd+CB_RESRANGE; else {
/* Initialize search indices */
if(lTarget==SUBL) { sIndAug=0;
eIndAug=0;
if (sInd<0) { sInd=base_index-CB_RESRANGE/2;
eInd=sInd+CB_RESRANGE;
sIndAug = 40 + sInd;
eIndAug = 39; if (lTarget==SUBL) {
sInd=0;
if (sInd<0) {
} else if( base_index < (base_size-20) ) {
sIndAug = 40 + sInd;
if(eInd > range) { eIndAug = 39;
sInd -= (eInd-range); sInd=0;
eInd = range;
} } else if ( base_index < (base_size-20) ) {
} else { /* base_index >= (base_size-20) */
if (eInd > range) {
if(sInd < (base_size-20)) { sInd -= (eInd-range);
sIndAug = 20; eInd = range;
sInd = 0; }
eInd = 0; } else { /* base_index >= (base_size-20) */
eIndAug = 19 + CB_RESRANGE;
if (sInd < (base_size-20)) {
if(eIndAug > 39) { sIndAug = 20;
eInd = eIndAug-39; sInd = 0;
eIndAug = 39; eInd = 0;
} eIndAug = 19 + CB_RESRANGE;
} else {
sIndAug = 20 + sInd - (base_size-20); if(eIndAug > 39) {
eIndAug = 39; eInd = eIndAug-39;
sInd = 0; eIndAug = 39;
eInd = CB_RESRANGE - (eIndAug-sIndAug+1); }
} } else {
} sIndAug = 20 + sInd - (base_size-20);
eIndAug = 39;
} else { /* lTarget = 22 */
if (sInd < 0) { sInd = 0;
eInd -= sInd; eInd = CB_RESRANGE - (eIndAug-sIndAug+1);
sInd = 0; }
} }
if(eInd > range) { } else { /* lTarget = 22 or 23 */
sInd -= (eInd - range);
eInd = range; if (sInd < 0) {
} eInd -= sInd;
} sInd = 0;
} }
/* search of higher codebook section */ if(eInd > range) {
sInd -= (eInd - range);
/* index search range */ eInd = range;
counter = sInd; }
sInd += base_size; }
eInd += base_size; }
/* search of higher codebook section */
if(stage==0) {
ppe = energy+base_size; /* index search range */
*ppe=0.0; counter = sInd;
sInd += base_size;
pp=cbvectors+lMem-lTarget; eInd += base_size;
for (j=0; j<lTarget; j++) {
*ppe+=(*pp)*(*pp);
pp++; if (stage==0) {
} ppe = energy+base_size;
*ppe=0.0;
ppi = cbvectors + lMem - 1 - lTarget;
ppo = cbvectors + lMem - 1; pp=cbvectors+lMem-lTarget;
for (j=0; j<lTarget; j++) {
for(j=0;j<(range-1);j++) { *ppe+=(*pp)*(*pp++);
*(ppe+1) = *ppe + (*ppi)*(*ppi) - (*ppo)*(*ppo); }
ppo--;
ppi--; ppi = cbvectors + lMem - 1 - lTarget;
ppe++; ppo = cbvectors + lMem - 1;
}
} for (j=0; j<(range-1); j++) {
*(ppe+1) = *ppe + (*ppi)*(*ppi) - (*ppo)*(*ppo);
/* loop over search range */ ppo--;
ppi--;
for (icount=sInd; icount<eInd; icount++) { ppe++;
}
/* calculate measure */ }
crossDot=0.0; /* loop over search range */
pp=cbvectors + lMem - (counter++) - lTarget;
for (icount=sInd; icount<eInd; icount++) {
for (j=0;j<lTarget;j++) {
crossDot += target[j]*(*pp++); /* calculate measure */
}
crossDot=0.0;
if(energy[icount]>0.0) {
invenergy[icount] = (float) 1.0/(energy[icount]+EPS);
} else { pp=cbvectors + lMem - (counter++) - lTarget;
invenergy[icount] = (float) 0.0;
} for (j=0;j<lTarget;j++) {
crossDot += target[j]*(*pp++);
if (stage==0) { }
measure=(float)-10000000.0; if (energy[icount]>0.0) {
invenergy[icount] =(float)1.0/(energy[icount]+EPS);
if (crossDot > 0.0) { } else {
measure = crossDot*crossDot* invenergy[icount] =(float)0.0;
invenergy[icount]; }
}
} if (stage==0) {
else {
measure = crossDot*crossDot*invenergy[icount]; measure=(float)-10000000.0;
}
if (crossDot > 0.0) {
/* check if measure is better */ measure = crossDot*crossDot*
ftmp = crossDot*invenergy[icount]; invenergy[icount];
}
if ((measure>max_measure) && (fabs(ftmp)<CB_MAXGAIN)){ }
best_index = icount; else {
max_measure = measure; measure = crossDot*crossDot*invenergy[icount];
gain = ftmp; }
}
} /* check if measure is better */
ftmp = crossDot*invenergy[icount];
/* Search the augmented CB inside the limited range. */
if ((measure>max_measure) && (fabs(ftmp)<CB_MAXGAIN)) {
if ((lTarget==SUBL)&&(sIndAug!=0)) { best_index = icount;
max_measure = measure;
searchAugmentedCB(sIndAug, eIndAug, stage, gain = ftmp;
2*base_size-20, target, cbvectors+lMem, }
&max_measure, &best_index, &gain, energy, invenergy); }
} /* Search the augmented CB inside the limited range. */
/* record best index */ if ((lTarget==SUBL)&&(sIndAug!=0)) {
searchAugmentedCB(sIndAug, eIndAug, stage,
index[stage] = best_index; 2*base_size-20, target, cbvectors+lMem,
&max_measure, &best_index, &gain, energy,
/* gain quantization */ invenergy);
}
if (stage==0){
/* record best index */
if (gain<0.0){
gain = 0.0; index[stage] = best_index;
}
/* gain quantization */
if (gain>CB_MAXGAIN) {
gain = (float)CB_MAXGAIN; if (stage==0){
}
gain = gainquant(gain, 1.0, 32, &gain_index[stage]); if (gain<0.0){
} gain = 0.0;
else {
if (stage==1) {
gain = gainquant(gain, (float)fabs(gains[stage-1]), }
16, &gain_index[stage]);
} else { if (gain>CB_MAXGAIN) {
gain = gainquant(gain, (float)fabs(gains[stage-1]), gain = (float)CB_MAXGAIN;
8, &gain_index[stage]); }
} gain = gainquant(gain, 1.0, 32, &gain_index[stage]);
} }
else {
/* Extract the best (according to measure) codebook vector */ if (stage==1) {
gain = gainquant(gain, (float)fabs(gains[stage-1]),
if(lTarget==(STATE_LEN-STATE_SHORT_LEN)) { 16, &gain_index[stage]);
} else {
if(index[stage]<base_size) { gain = gainquant(gain, (float)fabs(gains[stage-1]),
pp=buf+LPC_FILTERORDER+lMem-lTarget-index[stage]; 8, &gain_index[stage]);
} else { }
pp=cbvectors+lMem-lTarget- }
index[stage]+base_size;
} /* Extract the best (according to measure)
} else { codebook vector */
if (index[stage]<base_size) { if (lTarget==(STATE_LEN-iLBCenc_inst->state_short_len)) {
if (index[stage]<(base_size-20)) {
pp=buf+LPC_FILTERORDER+lMem-lTarget-index[stage]; if (index[stage]<base_size) {
} else { pp=buf+LPC_FILTERORDER+lMem-lTarget-index[stage];
createAugmentedVec(index[stage]-base_size+40, } else {
buf+LPC_FILTERORDER+lMem,aug_vec); pp=cbvectors+lMem-lTarget-
pp=aug_vec; index[stage]+base_size;
} }
} else { } else {
int filterno, lag_val;
if (index[stage]<base_size) {
filterno=index[stage]/base_size; if (index[stage]<(base_size-20)) {
lag_val=index[stage]-filterno*base_size; pp=buf+LPC_FILTERORDER+lMem-
lTarget-index[stage];
} else {
if (lag_val<(base_size-20)) { createAugmentedVec(index[stage]-base_size+40,
pp=cbvectors+filterno*lMem-lTarget- buf+LPC_FILTERORDER+lMem,aug_vec);
index[stage]+filterno*base_size; pp=aug_vec;
} else { }
createAugmentedVec( } else {
index[stage]-(filterno+1)*base_size+40, int filterno, position;
cbvectors+filterno*lMem,aug_vec);
pp=aug_vec; filterno=index[stage]/base_size;
} position=index[stage]-filterno*base_size;
}
}
if (position<(base_size-20)) {
/* Subtract the best codebook vector, according pp=cbvectors+filterno*lMem-lTarget-
to measure, from the target vector */ index[stage]+filterno*base_size;
} else {
for(j=0;j<lTarget;j++){ createAugmentedVec(
cvec[j] += gain*(*pp); index[stage]-(filterno+1)*base_size+40,
target[j] -= gain*(*pp++); cbvectors+filterno*lMem,aug_vec);
} pp=aug_vec;
/* record quantized gain */
}
gains[stage]=gain; }
}
}/* end of Main Loop. for (stage=0;... */
/* Subtract the best codebook vector, according
/* Gain adjustment for energy matching */ to measure, from the target vector */
cene=0.0;
for (i=0;i<lTarget;i++) { for (j=0;j<lTarget;j++) {
cene+=cvec[i]*cvec[i]; cvec[j] += gain*(*pp);
} target[j] -= gain*(*pp++);
j=gain_index[0]; }
for (i=gain_index[0];i<32;i++) { /* record quantized gain */
ftmp=cene*gain_sq5Tbl[i]*gain_sq5Tbl[i];
gains[stage]=gain;
if ((ftmp<(tene*gains[0]*gains[0])) &&
(gain_sq5Tbl[j]<(2.0*gains[0]))) { }/* end of Main Loop. for (stage=0;... */
j=i;
} /* Gain adjustment for energy matching */
} cene=0.0;
gain_index[0]=j; for (i=0; i<lTarget; i++) {
} cene+=cvec[i]*cvec[i];
}
j=gain_index[0];
for (i=gain_index[0]; i<32; i++) {
ftmp=cene*gain_sq5Tbl[i]*gain_sq5Tbl[i];
if ((ftmp<(tene*gains[0]*gains[0])) &&
(gain_sq5Tbl[j]<(2.0*gains[0]))) {
j=i;
}
}
gain_index[0]=j;
}

View File

@@ -1,32 +1,35 @@
/****************************************************************** /******************************************************************
iLBC Speech Coder ANSI-C Source Code iLBC Speech Coder ANSI-C Source Code
iCBSearch.h iCBSearch.h
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/
******************************************************************/
#ifndef __iLBC_ICBSEARCH_H
#ifndef __iLBC_ICBSEARCH_H #define __iLBC_ICBSEARCH_H
#define __iLBC_ICBSEARCH_H
void iCBSearch(
void iCBSearch( iLBC_Enc_Inst_t *iLBCenc_inst,
int *index, /* (o) Codebook indices */ /* (i) the encoder state structure */
int *gain_index,/* (o) Gain quantization indices */ int *index, /* (o) Codebook indices */
float *intarget,/* (i) Target vector for encoding */ int *gain_index,/* (o) Gain quantization indices */
float *mem, /* (i) Buffer for codebook construction */ float *intarget,/* (i) Target vector for encoding */
int lMem, /* (i) Length of buffer */ float *mem, /* (i) Buffer for codebook construction */
int lTarget, /* (i) Length of vector */ int lMem, /* (i) Length of buffer */
int nStages, /* (i) Number of codebook stages */ int lTarget, /* (i) Length of vector */
float *weightDenum, /* (i) weighting filter coefficients */ int nStages, /* (i) Number of codebook stages */
float *weightState, /* (i) weighting filter state */ float *weightDenum, /* (i) weighting filter coefficients */
int block /* (i) the subblock number */
);
float *weightState, /* (i) weighting filter state */
#endif int block /* (i) the sub-block number */
);
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,38 +1,40 @@
/****************************************************************** /******************************************************************
iLBC Speech Coder ANSI-C Source Code iLBC Speech Coder ANSI-C Source Code
iLBC_decode.h iLBC_decode.h
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/
******************************************************************/
#ifndef __iLBC_ILBCDECODE_H
#ifndef __iLBC_ILBCDECODE_H #define __iLBC_ILBCDECODE_H
#define __iLBC_ILBCDECODE_H
#include "iLBC_define.h"
#include "iLBC_define.h"
short initDecode( /* (o) Number of decoded
short initDecode( /* (o) Number of decoded samples */
samples */ iLBC_Dec_Inst_t *iLBCdec_inst, /* (i/o) Decoder instance */
iLBC_Dec_Inst_t *iLBCdec_inst, /* (i/o) Decoder instance */ int mode, /* (i) frame size mode */
int use_enhancer /* (i) 1 to use enhancer int use_enhancer /* (i) 1 to use enhancer
0 to run without 0 to run without
enhancer */ enhancer */
); );
void iLBC_decode( void iLBC_decode(
float *decblock, /* (o) decoded signal block */ float *decblock, /* (o) decoded signal block */
unsigned char *bytes, /* (i) encoded signal bits */ unsigned char *bytes, /* (i) encoded signal bits */
iLBC_Dec_Inst_t *iLBCdec_inst, /* (i/o) the decoder state iLBC_Dec_Inst_t *iLBCdec_inst, /* (i/o) the decoder state
structure */ structure */
int mode /* (i) 0: bad packet, PLC, int mode /* (i) 0: bad packet, PLC,
1: normal */ 1: normal */
); );
#endif
#endif

View File

@@ -1,157 +1,201 @@
/****************************************************************** /******************************************************************
iLBC Speech Coder ANSI-C Source Code iLBC Speech Coder ANSI-C Source Code
iLBC_define.h iLBC_define.h
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/
******************************************************************/ #include <string.h>
#include <string.h>
#ifndef __iLBC_ILBCDEFINE_H
#ifndef __iLBC_ILBCDEFINE_H #define __iLBC_ILBCDEFINE_H
#define __iLBC_ILBCDEFINE_H
/* general codec settings */
/* general codec settings */
#define FS (float)8000.0
#define FS (float)8000.0 #define BLOCKL_20MS 160
#define BLOCKL 240 #define BLOCKL_30MS 240
#define NSUB 6 #define BLOCKL_MAX 240
#define NASUB 4 #define NSUB_20MS 4
#define SUBL 40 #define NSUB_30MS 6
#define STATE_LEN 80 #define NSUB_MAX 6
#define STATE_SHORT_LEN 58 #define NASUB_20MS 2
#define NASUB_30MS 4
/* LPC settings */ #define NASUB_MAX 4
#define SUBL 40
#define LPC_FILTERORDER 10 #define STATE_LEN 80
#define LPC_CHIRP_SYNTDENUM (float)0.9025 #define STATE_SHORT_LEN_30MS 58
#define LPC_CHIRP_WEIGHTDENUM (float)0.4222 #define STATE_SHORT_LEN_20MS 57
#define LPC_LOOKBACK 60
#define LPC_N 2 /* LPC settings */
#define LPC_ASYMDIFF 20
#define LPC_BW (float)60.0 #define LPC_FILTERORDER 10
#define LPC_WN (float)1.0001 #define LPC_CHIRP_SYNTDENUM (float)0.9025
#define LSF_NSPLIT 3 #define LPC_CHIRP_WEIGHTDENUM (float)0.4222
#define LSF_NUMBER_OF_STEPS 4 #define LPC_LOOKBACK 60
#define LPC_HALFORDER LPC_FILTERORDER/2 #define LPC_N_20MS 1
#define LPC_N_30MS 2
/* cb settings */ #define LPC_N_MAX 2
#define LPC_ASYMDIFF 20
#define CB_NSTAGES 3 #define LPC_BW (float)60.0
#define CB_EXPAND 2 #define LPC_WN (float)1.0001
#define CB_MEML 147 #define LSF_NSPLIT 3
#define CB_FILTERLEN 2*4
#define CB_HALFFILTERLEN 4 #define LSF_NUMBER_OF_STEPS 4
#define CB_RESRANGE 34 #define LPC_HALFORDER (LPC_FILTERORDER/2)
#define CB_MAXGAIN (float) 1.3
/* cb settings */
/* enhancer */
#define CB_NSTAGES 3
#define ENH_BLOCKL 80 /* block length */ #define CB_EXPAND 2
#define ENH_BLOCKL_HALF (ENH_BLOCKL/2) #define CB_MEML 147
#define ENH_HL 3 /* 2*ENH_HL+1 is number blocks #define CB_FILTERLEN 2*4
in said second sequence */ #define CB_HALFFILTERLEN 4
#define ENH_SLOP 2 /* max difference estimated and #define CB_RESRANGE 34
correct pitch period */ #define CB_MAXGAIN (float)1.3
#define ENH_PLOCSL 20 /* pitch-estimates and
pitch-locations buffer length */ /* enhancer */
#define ENH_OVERHANG 2
#define ENH_UPS0 4 /* upsampling rate */ #define ENH_BLOCKL 80 /* block length */
#define ENH_FL0 3 /* 2*FLO+1 is the length of each filter */ #define ENH_BLOCKL_HALF (ENH_BLOCKL/2)
#define ENH_VECTL (ENH_BLOCKL+2*ENH_FL0) #define ENH_HL 3 /* 2*ENH_HL+1 is number blocks
#define ENH_CORRDIM (2*ENH_SLOP+1) in said second sequence */
#define ENH_NBLOCKS (BLOCKL/ENH_BLOCKL) #define ENH_SLOP 2 /* max difference estimated and
#define ENH_NBLOCKS_EXTRA 5 correct pitch period */
#define ENH_NBLOCKS_TOT 8 /* ENH_NBLOCKS+ENH_NBLOCKS_EXTRA */ #define ENH_PLOCSL 20 /* pitch-estimates and pitch-
#define ENH_BUFL (ENH_NBLOCKS_TOT)*ENH_BLOCKL locations buffer length */
#define ENH_ALPHA0 (float)0.05 #define ENH_OVERHANG 2
#define ENH_UPS0 4 /* upsampling rate */
/* PLC */ #define ENH_FL0 3 /* 2*FLO+1 is the length of
each filter */
#define PLC_BFIATTENUATE (float)0.9 #define ENH_VECTL (ENH_BLOCKL+2*ENH_FL0)
#define PLC_GAINTHRESHOLD (float)0.5 #define ENH_CORRDIM (2*ENH_SLOP+1)
#define PLC_BWEXPAND (float)0.99 #define ENH_NBLOCKS (BLOCKL_MAX/ENH_BLOCKL)
#define PLC_XT_MIX (float)1.0 #define ENH_NBLOCKS_EXTRA 5
#define PLC_XB_MIX (float)0.0 #define ENH_NBLOCKS_TOT 8 /* ENH_NBLOCKS +
#define PLC_YT_MIX (float)0.95 ENH_NBLOCKS_EXTRA */
#define PLC_YB_MIX (float)0.0 #define ENH_BUFL (ENH_NBLOCKS_TOT)*ENH_BLOCKL
#define ENH_ALPHA0 (float)0.05
/* Down sampling */
/* Down sampling */
#define FILTERORDER_DS 7
#define DELAY_DS 3 #define FILTERORDER_DS 7
#define FACTOR_DS 2 #define DELAY_DS 3
#define FACTOR_DS 2
/* bit stream defs */
/* bit stream defs */
#define NO_OF_BYTES 50
#define STATE_BITS 3 #define NO_OF_BYTES_20MS 38
#define BYTE_LEN 8 #define NO_OF_BYTES_30MS 50
#define ULP_CLASSES 3 #define NO_OF_WORDS_20MS 19
#define NO_OF_WORDS_30MS 25
/* help parameters */ #define STATE_BITS 3
#define BYTE_LEN 8
#define FLOAT_MAX (float)1.0e37 #define ULP_CLASSES 3
#define EPS (float)2.220446049250313e-016
#define PI (float)3.14159265358979323846 /* help parameters */
#define MIN_SAMPLE -32768
#define MAX_SAMPLE 32767
#define TWO_PI (float)6.283185307 #define FLOAT_MAX (float)1.0e37
#define PI2 (float)0.159154943 #define EPS (float)2.220446049250313e-016
#define PI (float)3.14159265358979323846
/* type definition encoder instance */ #define MIN_SAMPLE -32768
typedef struct iLBC_Enc_Inst_t_ { #define MAX_SAMPLE 32767
#define TWO_PI (float)6.283185307
/* analysis filter state */ #define PI2 (float)0.159154943
float anaMem[LPC_FILTERORDER];
/* type definition encoder instance */
/* old lsf parameters for interpolation */ typedef struct iLBC_ULP_Inst_t_ {
float lsfold[LPC_FILTERORDER]; int lsf_bits[6][ULP_CLASSES+2];
float lsfdeqold[LPC_FILTERORDER]; int start_bits[ULP_CLASSES+2];
int startfirst_bits[ULP_CLASSES+2];
/* signal buffer for LP analysis */ int scale_bits[ULP_CLASSES+2];
float lpc_buffer[LPC_LOOKBACK + BLOCKL]; int state_bits[ULP_CLASSES+2];
int extra_cb_index[CB_NSTAGES][ULP_CLASSES+2];
/* state of input HP filter */ int extra_cb_gain[CB_NSTAGES][ULP_CLASSES+2];
float hpimem[4]; int cb_index[NSUB_MAX][CB_NSTAGES][ULP_CLASSES+2];
int cb_gain[NSUB_MAX][CB_NSTAGES][ULP_CLASSES+2];
} iLBC_Enc_Inst_t; } iLBC_ULP_Inst_t;
/* type definition decoder instance */ /* type definition encoder instance */
typedef struct iLBC_Dec_Inst_t_ { typedef struct iLBC_Enc_Inst_t_ {
/* synthesis filter state */
float syntMem[LPC_FILTERORDER]; /* flag for frame size mode */
int mode;
/* old LSF for interpolation */
float lsfdeqold[LPC_FILTERORDER]; /* basic parameters for different frame sizes */
int blockl;
/* pitch lag estimated in enhancer and used in PLC */ int nsub;
int last_lag; int nasub;
int no_of_bytes, no_of_words;
/* PLC state information */ int lpc_n;
int prevLag, consPLICount, prevPLI, prev_enh_pl; int state_short_len;
float prevGain, prevLpc[LPC_FILTERORDER+1]; const iLBC_ULP_Inst_t *ULP_inst;
float prevResidual[NSUB*SUBL];
float energy; /* analysis filter state */
unsigned long seed; float anaMem[LPC_FILTERORDER];
/* previous synthesis filter parameters */ /* old lsf parameters for interpolation */
float old_syntdenum[(LPC_FILTERORDER + 1)*NSUB]; float lsfold[LPC_FILTERORDER];
float lsfdeqold[LPC_FILTERORDER];
/* state of output HP filter */
float hpomem[4]; /* signal buffer for LP analysis */
float lpc_buffer[LPC_LOOKBACK + BLOCKL_MAX];
/* enhancer state information */
int use_enhancer; /* state of input HP filter */
float enh_buf[ENH_BUFL]; float hpimem[4];
float enh_period[ENH_NBLOCKS_TOT];
} iLBC_Enc_Inst_t;
} iLBC_Dec_Inst_t;
/* type definition decoder instance */
#endif 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];
/* old LSF for interpolation */
float lsfdeqold[LPC_FILTERORDER];
/* pitch lag estimated in enhancer and used in PLC */
int last_lag;
/* PLC state information */
int prevLag, consPLICount, prevPLI, prev_enh_pl;
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_MAX];
/* state of output HP filter */
float hpomem[4];
/* enhancer state information */
int use_enhancer;
float enh_buf[ENH_BUFL];
float enh_period[ENH_NBLOCKS_TOT];
} iLBC_Dec_Inst_t;
#endif

View File

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

View File

@@ -1,32 +1,37 @@
/****************************************************************** /******************************************************************
iLBC Speech Coder ANSI-C Source Code iLBC Speech Coder ANSI-C Source Code
iLBC_encode.h iLBC_encode.h
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/
******************************************************************/
#ifndef __iLBC_ILBCENCODE_H
#ifndef __iLBC_ILBCENCODE_H #define __iLBC_ILBCENCODE_H
#define __iLBC_ILBCENCODE_H
#include "iLBC_define.h"
#include "iLBC_define.h"
short initEncode( /* (o) Number of bytes
short initEncode( /* (o) Number of bytes encoded */ encoded */
iLBC_Enc_Inst_t *iLBCenc_inst /* (i/o) Encoder instance */ 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 */ void iLBC_encode(
float *block, /* (o) speech vector to encode */
iLBC_Enc_Inst_t *iLBCenc_inst /* (i/o) the general encoder
state */ unsigned char *bytes, /* (o) encoded data bits iLBC */
); float *block, /* (o) speech vector to
encode */
#endif iLBC_Enc_Inst_t *iLBCenc_inst /* (i/o) the general encoder
state */
);
#endif

View File

@@ -1,253 +1,263 @@
/****************************************************************** /******************************************************************
iLBC Speech Coder ANSI-C Source Code iLBC Speech Coder ANSI-C Source Code
lsf.c lsf.c
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/
******************************************************************/
#include <string.h>
#include <string.h> #include <math.h>
#include <math.h>
#include "iLBC_define.h"
#include "iLBC_define.h"
#include "lsf.h" /*----------------------------------------------------------------*
* conversion from lpc coefficients to lsf coefficients
/*----------------------------------------------------------------* *---------------------------------------------------------------*/
* conversion from lpc coefficients to lsf coefficients
*---------------------------------------------------------------*/ void a2lsf(
float *freq,/* (o) lsf coefficients */
void a2lsf( float *a /* (i) lpc coefficients */
float *freq,/* (o) lsf coefficients */ ){
float *a /* (i) lpc coefficients */ float steps[LSF_NUMBER_OF_STEPS] =
){ {(float)0.00635, (float)0.003175, (float)0.0015875,
float steps[LSF_NUMBER_OF_STEPS] = (float)0.00079375};
{(float)0.00635, (float)0.003175, (float)0.0015875, float step;
(float)0.00079375}; int step_idx;
float step; int lsp_index;
int step_idx; float p[LPC_HALFORDER];
int lsp_index; float q[LPC_HALFORDER];
float p[LPC_HALFORDER]; float p_pre[LPC_HALFORDER];
float q[LPC_HALFORDER];
float p_pre[LPC_HALFORDER];
float q_pre[LPC_HALFORDER]; float q_pre[LPC_HALFORDER];
float old_p, old_q, *old; float old_p, old_q, *old;
float *pq_coef; float *pq_coef;
float omega, old_omega; float omega, old_omega;
int i; int i;
float hlp, hlp1, hlp2, hlp3, hlp4, hlp5; float hlp, hlp1, hlp2, hlp3, hlp4, hlp5;
for (i = 0; i < LPC_HALFORDER; i++){ for (i=0; i<LPC_HALFORDER; i++) {
p[i] = (float)-1.0 * (a[i + 1] + a[LPC_FILTERORDER - i]); p[i] = (float)-1.0 * (a[i + 1] + a[LPC_FILTERORDER - i]);
q[i] = a[LPC_FILTERORDER - i] - a[i + 1]; q[i] = a[LPC_FILTERORDER - i] - a[i + 1];
} }
p_pre[0] = (float)-1.0 - p[0]; p_pre[0] = (float)-1.0 - p[0];
p_pre[1] = - p_pre[0] - p[1]; p_pre[1] = - p_pre[0] - p[1];
p_pre[2] = - p_pre[1] - p[2]; p_pre[2] = - p_pre[1] - p[2];
p_pre[3] = - p_pre[2] - p[3]; p_pre[3] = - p_pre[2] - p[3];
p_pre[4] = - p_pre[3] - p[4]; p_pre[4] = - p_pre[3] - p[4];
p_pre[4] = p_pre[4] / 2; p_pre[4] = p_pre[4] / 2;
q_pre[0] = (float)1.0 - q[0]; q_pre[0] = (float)1.0 - q[0];
q_pre[1] = q_pre[0] - q[1]; q_pre[1] = q_pre[0] - q[1];
q_pre[2] = q_pre[1] - q[2]; q_pre[2] = q_pre[1] - q[2];
q_pre[3] = q_pre[2] - q[3]; q_pre[3] = q_pre[2] - q[3];
q_pre[4] = q_pre[3] - q[4]; q_pre[4] = q_pre[3] - q[4];
q_pre[4] = q_pre[4] / 2; q_pre[4] = q_pre[4] / 2;
omega = 0.0; omega = 0.0;
old_omega = 0.0; old_omega = 0.0;
old_p = FLOAT_MAX; old_p = FLOAT_MAX;
old_q = FLOAT_MAX; old_q = FLOAT_MAX;
/* Here we loop through lsp_index to find all the /* Here we loop through lsp_index to find all the
LPC_FILTERORDER roots for omega. */ LPC_FILTERORDER roots for omega. */
for (lsp_index = 0; lsp_index < LPC_FILTERORDER; lsp_index++){ for (lsp_index = 0; lsp_index<LPC_FILTERORDER; lsp_index++) {
/* Depending on lsp_index being even or odd, we /* Depending on lsp_index being even or odd, we
alternatively solve the roots for the two LSP equations. */ alternatively solve the roots for the two LSP equations. */
if ((lsp_index & 0x1) == 0) { if ((lsp_index & 0x1) == 0) {
pq_coef = p_pre; pq_coef = p_pre;
old = &old_p; old = &old_p;
} else { } else {
pq_coef = q_pre; pq_coef = q_pre;
old = &old_q; old = &old_q;
} }
/* Start with low resolution grid */ /* Start with low resolution grid */
for (step_idx = 0, step = steps[step_idx]; for (step_idx = 0, step = steps[step_idx];
step_idx < LSF_NUMBER_OF_STEPS;){ step_idx < LSF_NUMBER_OF_STEPS;){
/* cos(10piw) + pq(0)cos(8piw) + pq(1)cos(6piw) +
pq(2)cos(4piw) + pq(3)cod(2piw) + pq(4) */
/* cos(10piw) + pq(0)cos(8piw) + pq(1)cos(6piw) +
hlp = (float)cos(omega * TWO_PI); pq(2)cos(4piw) + pq(3)cod(2piw) + pq(4) */
hlp1 = (float)2.0 * hlp + pq_coef[0];
hlp2 = (float)2.0 * hlp * hlp1 - (float)1.0 + hlp = (float)cos(omega * TWO_PI);
pq_coef[1]; hlp1 = (float)2.0 * hlp + pq_coef[0];
hlp3 = (float)2.0 * hlp * hlp2 - hlp1 + pq_coef[2]; hlp2 = (float)2.0 * hlp * hlp1 - (float)1.0 +
hlp4 = (float)2.0 * hlp * hlp3 - hlp2 + pq_coef[3]; pq_coef[1];
hlp5 = hlp * hlp4 - hlp3 + pq_coef[4]; hlp3 = (float)2.0 * hlp * hlp2 - hlp1 + pq_coef[2];
hlp4 = (float)2.0 * hlp * hlp3 - hlp2 + pq_coef[3];
hlp5 = hlp * hlp4 - hlp3 + pq_coef[4];
if (((hlp5 * (*old)) <= 0.0) || (omega >= 0.5)){
if (step_idx == (LSF_NUMBER_OF_STEPS - 1)){ if (((hlp5 * (*old)) <= 0.0) || (omega >= 0.5)){
if (fabs(hlp5) >= fabs(*old)) { if (step_idx == (LSF_NUMBER_OF_STEPS - 1)){
freq[lsp_index] = omega - step;
} else { if (fabs(hlp5) >= fabs(*old)) {
freq[lsp_index] = omega; freq[lsp_index] = omega - step;
} } else {
freq[lsp_index] = omega;
}
if ((*old) >= 0.0){
*old = (float)-1.0 * FLOAT_MAX;
} else { if ((*old) >= 0.0){
*old = FLOAT_MAX; *old = (float)-1.0 * FLOAT_MAX;
} } else {
*old = FLOAT_MAX;
omega = old_omega; }
step_idx = 0;
omega = old_omega;
step_idx = LSF_NUMBER_OF_STEPS; step_idx = 0;
} else {
step_idx = LSF_NUMBER_OF_STEPS;
if (step_idx == 0) { } else {
old_omega = omega;
} if (step_idx == 0) {
old_omega = omega;
step_idx++; }
omega -= steps[step_idx];
step_idx++;
/* Go back one grid step */ omega -= steps[step_idx];
step = steps[step_idx]; /* Go back one grid step */
}
} else { step = steps[step_idx];
}
/* increment omega until they are of different sign, } else {
and we know there is at least one root between omega
and old_omega */ /* increment omega until they are of different sign,
*old = hlp5; and we know there is at least one root between omega
omega += step; and old_omega */
} *old = hlp5;
} omega += step;
} }
for (i = 0; i < LPC_FILTERORDER; i++) {
freq[i] = freq[i] * TWO_PI; }
} }
}
for (i = 0; i<LPC_FILTERORDER; i++) {
/*----------------------------------------------------------------* freq[i] = freq[i] * TWO_PI;
* conversion from lsf coefficients to lpc coefficients }
*---------------------------------------------------------------*/ }
void lsf2a( /*----------------------------------------------------------------*
float *a_coef, /* (o) lpc coefficients */ * conversion from lsf coefficients to lpc coefficients
float *freq /* (i) lsf coefficients */ *---------------------------------------------------------------*/
){
int i, j; void lsf2a(
float hlp; float *a_coef, /* (o) lpc coefficients */
float p[LPC_HALFORDER], q[LPC_HALFORDER]; float *freq /* (i) lsf coefficients */
float a[LPC_HALFORDER + 1], a1[LPC_HALFORDER], a2[LPC_HALFORDER]; ){
float b[LPC_HALFORDER + 1], b1[LPC_HALFORDER], b2[LPC_HALFORDER]; int i, j;
float hlp;
for (i = 0; i < LPC_FILTERORDER; i++) { float p[LPC_HALFORDER], q[LPC_HALFORDER];
freq[i] = freq[i] * PI2; float a[LPC_HALFORDER + 1], a1[LPC_HALFORDER],
} a2[LPC_HALFORDER];
float b[LPC_HALFORDER + 1], b1[LPC_HALFORDER],
/* Check input for ill-conditioned cases. This part is not b2[LPC_HALFORDER];
found in the TIA standard. It involves the following 2 IF
blocks. If "freq" is judged ill-conditioned, then we first for (i=0; i<LPC_FILTERORDER; i++) {
modify freq[0] and freq[LPC_HALFORDER-1] (normally freq[i] = freq[i] * PI2;
LPC_HALFORDER = 10 for LPC applications), then we adjust }
the other "freq" values slightly */
/* Check input for ill-conditioned cases. This part is not
found in the TIA standard. It involves the following 2 IF
if ((freq[0] <= 0.0) || (freq[LPC_FILTERORDER - 1] >= 0.5)){ blocks. If "freq" is judged ill-conditioned, then we first
modify freq[0] and freq[LPC_HALFORDER-1] (normally
LPC_HALFORDER = 10 for LPC applications), then we adjust
if (freq[0] <= 0.0) { the other "freq" values slightly */
freq[0] = (float)0.022;
}
if ((freq[0] <= 0.0) || (freq[LPC_FILTERORDER - 1] >= 0.5)){
if (freq[LPC_FILTERORDER - 1] >= 0.5) {
freq[LPC_FILTERORDER - 1] = (float)0.499; if (freq[0] <= 0.0) {
} freq[0] = (float)0.022;
}
hlp = (freq[LPC_FILTERORDER - 1] - freq[0]) /
(float) (LPC_FILTERORDER - 1);
if (freq[LPC_FILTERORDER - 1] >= 0.5) {
for (i = 1; i < LPC_FILTERORDER; i++) { freq[LPC_FILTERORDER - 1] = (float)0.499;
freq[i] = freq[i - 1] + hlp; }
}
} hlp = (freq[LPC_FILTERORDER - 1] - freq[0]) /
(float) (LPC_FILTERORDER - 1);
memset(a1, 0, LPC_HALFORDER*sizeof(float));
memset(a2, 0, LPC_HALFORDER*sizeof(float)); for (i=1; i<LPC_FILTERORDER; i++) {
memset(b1, 0, LPC_HALFORDER*sizeof(float)); freq[i] = freq[i - 1] + hlp;
memset(b2, 0, LPC_HALFORDER*sizeof(float)); }
memset(a, 0, (LPC_HALFORDER+1)*sizeof(float));
memset(b, 0, (LPC_HALFORDER+1)*sizeof(float));
}
/* p[i] and q[i] compute cos(2*pi*omega_{2j}) and
cos(2*pi*omega_{2j-1} in eqs. 4.2.2.2-1 and 4.2.2.2-2. memset(a1, 0, LPC_HALFORDER*sizeof(float));
Note that for this code p[i] specifies the coefficients memset(a2, 0, LPC_HALFORDER*sizeof(float));
used in .Q_A(z) while q[i] specifies the coefficients used memset(b1, 0, LPC_HALFORDER*sizeof(float));
in .P_A(z) */ memset(b2, 0, LPC_HALFORDER*sizeof(float));
memset(a, 0, (LPC_HALFORDER+1)*sizeof(float));
for (i = 0; i < LPC_HALFORDER; i++){ memset(b, 0, (LPC_HALFORDER+1)*sizeof(float));
p[i] = (float)cos(TWO_PI * freq[2 * i]);
q[i] = (float)cos(TWO_PI * freq[2 * i + 1]); /* p[i] and q[i] compute cos(2*pi*omega_{2j}) and
} cos(2*pi*omega_{2j-1} in eqs. 4.2.2.2-1 and 4.2.2.2-2.
Note that for this code p[i] specifies the coefficients
a[0] = 0.25; used in .Q_A(z) while q[i] specifies the coefficients used
b[0] = 0.25; in .P_A(z) */
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]; p[i] = (float)cos(TWO_PI * freq[2 * i]);
b[i + 1] = b[i] - 2 * q[i] * b1[i] + b2[i]; q[i] = (float)cos(TWO_PI * freq[2 * i + 1]);
a2[i] = a1[i]; }
a1[i] = a[i];
b2[i] = b1[i]; a[0] = 0.25;
b1[i] = b[i]; b[0] = 0.25;
}
for (i= 0; i<LPC_HALFORDER; i++) {
for (j = 0; j < LPC_FILTERORDER; j++){ a[i + 1] = a[i] - 2 * p[i] * a1[i] + a2[i];
b[i + 1] = b[i] - 2 * q[i] * b1[i] + b2[i];
if (j == 0) { a2[i] = a1[i];
a[0] = 0.25; a1[i] = a[i];
b[0] = -0.25; b2[i] = b1[i];
} else { b1[i] = b[i];
a[0] = b[0] = 0.0; }
}
for (j=0; j<LPC_FILTERORDER; j++) {
for (i = 0; i < LPC_HALFORDER; i++){
a[i + 1] = a[i] - 2 * p[i] * a1[i] + a2[i]; if (j == 0) {
b[i + 1] = b[i] - 2 * q[i] * b1[i] + b2[i]; a[0] = 0.25;
a2[i] = a1[i]; b[0] = -0.25;
a1[i] = a[i]; } else {
b2[i] = b1[i]; a[0] = b[0] = 0.0;
b1[i] = b[i]; }
}
for (i=0; i<LPC_HALFORDER; i++) {
a_coef[j + 1] = 2 * (a[LPC_HALFORDER] + b[LPC_HALFORDER]); 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];
a_coef[0] = 1.0; a1[i] = a[i];
} b2[i] = b1[i];
b1[i] = b[i];
}
a_coef[j + 1] = 2 * (a[LPC_HALFORDER] + b[LPC_HALFORDER]);
}
a_coef[0] = 1.0;
}

View File

@@ -1,29 +1,30 @@
/****************************************************************** /******************************************************************
iLBC Speech Coder ANSI-C Source Code iLBC Speech Coder ANSI-C Source Code
lsf.h lsf.h
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/
******************************************************************/
#ifndef __iLBC_LSF_H
#define __iLBC_LSF_H #ifndef __iLBC_LSF_H
#define __iLBC_LSF_H
void a2lsf(
float *freq,/* (o) lsf coefficients */ void a2lsf(
float *a /* (i) lpc coefficients */ float *freq,/* (o) lsf coefficients */
); float *a /* (i) lpc coefficients */
);
void lsf2a(
float *a_coef, /* (o) lpc coefficients */ void lsf2a(
float *freq /* (i) lsf coefficients */ float *a_coef, /* (o) lpc coefficients */
); float *freq /* (i) lsf coefficients */
);
#endif
#endif

View File

@@ -1,170 +1,174 @@
/****************************************************************** /******************************************************************
iLBC Speech Coder ANSI-C Source Code iLBC Speech Coder ANSI-C Source Code
packing.c packing.c
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/
******************************************************************/
#include <math.h>
#include <math.h> #include <stdlib.h>
#include <stdlib.h>
#include "iLBC_define.h"
#include "iLBC_define.h" #include "constants.h"
#include "constants.h" #include "helpfun.h"
#include "helpfun.h" #include "string.h"
#include "string.h"
#include "packing.h" /*----------------------------------------------------------------*
* splitting an integer into first most significant bits and
/*----------------------------------------------------------------* * remaining least significant bits
* splitting an integer into first most significant bits and *---------------------------------------------------------------*/
* remaining least significant bits
*---------------------------------------------------------------*/ void packsplit(
int *index, /* (i) the value to split */
void packsplit( int *firstpart, /* (o) the value specified by most
int *index, /* (i) the value to split */ significant bits */
int *firstpart, /* (o) the value specified by most int *rest, /* (o) the value specified by least
significant bits */ significant bits */
int *rest, /* (o) the value specified by least int bitno_firstpart, /* (i) number of bits in most
significant bits */ significant part */
int bitno_firstpart, /* (i) number of bits in most int bitno_total /* (i) number of bits in full range
significant part */ of value */
int bitno_total /* (i) number of bits in full range ){
of value */ int bitno_rest = bitno_total-bitno_firstpart;
){
int bitno_rest = bitno_total-bitno_firstpart;
*firstpart = *index>>(bitno_rest); *firstpart = *index>>(bitno_rest);
*rest = *index-(*firstpart<<(bitno_rest)); *rest = *index-(*firstpart<<(bitno_rest));
} }
/*----------------------------------------------------------------* /*----------------------------------------------------------------*
* combining a value corresponding to msb's with a value * combining a value corresponding to msb's with a value
* corresponding to lsb's * corresponding to lsb's
*---------------------------------------------------------------*/ *---------------------------------------------------------------*/
void packcombine( void packcombine(
int *index, /* (i/o) the msb value in the int *index, /* (i/o) the msb value in the
combined value out */ combined value out */
int rest, /* (i) the lsb value */ int rest, /* (i) the lsb value */
int bitno_rest /* (i) the number of bits in the int bitno_rest /* (i) the number of bits in the
lsb part */ lsb part */
){ ){
*index = *index<<bitno_rest; *index = *index<<bitno_rest;
*index += rest; *index += rest;
} }
/*----------------------------------------------------------------* /*----------------------------------------------------------------*
* packing of bits into bitstream, i.e., vector of bytes * packing of bits into bitstream, i.e., vector of bytes
*---------------------------------------------------------------*/ *---------------------------------------------------------------*/
void dopack( void dopack(
unsigned char **bitstream, /* (i/o) on entrance pointer to place unsigned char **bitstream, /* (i/o) on entrance pointer to
in bitstream to pack new data, place in bitstream to pack
on exit pointer to place in new data, on exit pointer
bitstream to pack future to place in bitstream to
data */ pack future data */
int index, /* (i) the value to pack */ int index, /* (i) the value to pack */
int bitno, /* (i) the number of bits that the int bitno, /* (i) the number of bits that the
value will fit within */ value will fit within */
int *pos /* (i/o) write position in the int *pos /* (i/o) write position in the
current byte */ current byte */
){ ){
int posLeft; int posLeft;
/* Clear the bits before starting in a new byte */ /* Clear the bits before starting in a new byte */
if ((*pos)==0) { if ((*pos)==0) {
**bitstream=0; **bitstream=0;
} }
while (bitno>0) { while (bitno>0) {
/* Jump to the next byte if end of this byte is reached*/ /* Jump to the next byte if end of this byte is reached*/
if (*pos==8) { if (*pos==8) {
*pos=0; *pos=0;
(*bitstream)++; (*bitstream)++;
**bitstream=0; **bitstream=0;
} }
posLeft=8-(*pos);
/* Insert index into the bitstream */ posLeft=8-(*pos);
if (bitno <= posLeft) { /* Insert index into the bitstream */
**bitstream |= (unsigned char)(index<<(posLeft-bitno));
*pos+=bitno; if (bitno <= posLeft) {
bitno=0; **bitstream |= (unsigned char)(index<<(posLeft-bitno));
} else { *pos+=bitno;
**bitstream |= (unsigned char)(index>>(bitno-posLeft)); bitno=0;
} else {
*pos=8; **bitstream |= (unsigned char)(index>>(bitno-posLeft));
index-=((index>>(bitno-posLeft))<<(bitno-posLeft));
*pos=8;
bitno-=posLeft; index-=((index>>(bitno-posLeft))<<(bitno-posLeft));
}
} bitno-=posLeft;
} }
}
/*----------------------------------------------------------------* }
* unpacking of bits from bitstream, i.e., vector of bytes
*---------------------------------------------------------------*/ /*----------------------------------------------------------------*
* unpacking of bits from bitstream, i.e., vector of bytes
void unpack( *---------------------------------------------------------------*/
unsigned char **bitstream, /* (i/o) on entrance pointer to
place in bitstream to void unpack(
unpack new data from, on unsigned char **bitstream, /* (i/o) on entrance pointer to
exit pointer to place in place in bitstream to
bitstream to unpack future unpack new data from, on
data from */ exit pointer to place in
int *index, /* (o) resulting value */ bitstream to unpack future
int bitno, /* (i) number of bits used to data from */
represent the value */ int *index, /* (o) resulting value */
int *pos /* (i/o) read position in the int bitno, /* (i) number of bits used to
current byte */ represent the value */
){ int *pos /* (i/o) read position in the
int BitsLeft; current byte */
){
*index=0; int BitsLeft;
while (bitno>0) { *index=0;
/* move forward in bitstream when the end of the while (bitno>0) {
byte is reached */
/* move forward in bitstream when the end of the
if (*pos==8) { byte is reached */
*pos=0;
(*bitstream)++; if (*pos==8) {
} *pos=0;
(*bitstream)++;
BitsLeft=8-(*pos); }
/* Extract bits to index */ BitsLeft=8-(*pos);
if (BitsLeft>=bitno) { /* Extract bits to index */
*index+=((((**bitstream)<<(*pos)) & 0xFF)>>(8-bitno));
*pos+=bitno;
bitno=0; if (BitsLeft>=bitno) {
} else { *index+=((((**bitstream)<<(*pos)) & 0xFF)>>(8-bitno));
if ((8-bitno)>0) { *pos+=bitno;
*index+=((((**bitstream)<<(*pos)) & 0xFF)>> bitno=0;
(8-bitno)); } else {
*pos=8;
} else { if ((8-bitno)>0) {
*index+=(((int)(((**bitstream)<<(*pos)) & 0xFF))<< *index+=((((**bitstream)<<(*pos)) & 0xFF)>>
(bitno-8)); (8-bitno));
*pos=8; *pos=8;
} } else {
bitno-=BitsLeft; *index+=(((int)(((**bitstream)<<(*pos)) & 0xFF))<<
} (bitno-8));
} *pos=8;
} }
bitno-=BitsLeft;
}
}
}

View File

@@ -1,65 +1,67 @@
/****************************************************************** /******************************************************************
iLBC Speech Coder ANSI-C Source Code iLBC Speech Coder ANSI-C Source Code
packing.h packing.h
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/
******************************************************************/
#ifndef __PACKING_H
#ifndef __PACKING_H #define __PACKING_H
#define __PACKING_H
void packsplit(
void packsplit( int *index, /* (i) the value to split */
int *index, /* (i) the value to split */ int *firstpart, /* (o) the value specified by most
int *firstpart, /* (o) the value specified by most significant bits */
significant bits */ int *rest, /* (o) the value specified by least
int *rest, /* (o) the value specified by least significant bits */
significant bits */ int bitno_firstpart, /* (i) number of bits in most
int bitno_firstpart, /* (i) number of bits in most significant part */
significant part */ int bitno_total /* (i) number of bits in full range
int bitno_total /* (i) number of bits in full range of value */
of value */ );
);
void packcombine(
void packcombine( int *index, /* (i/o) the msb value in the
int *index, /* (i/o) the msb value in the combined value out */
combined value out */ int rest, /* (i) the lsb value */
int rest, /* (i) the lsb value */ int bitno_rest /* (i) the number of bits in the
int bitno_rest /* (i) the number of bits in the lsb part */
lsb part */ );
);
void dopack(
void dopack( unsigned char **bitstream, /* (i/o) on entrance pointer to
unsigned char **bitstream, /* (i/o) on entrance pointer to place place in bitstream to pack
in bitstream to pack new data, new data, on exit pointer
on exit pointer to place in to place in bitstream to
bitstream to pack future pack future data */
data */ int index, /* (i) the value to pack */
int index, /* (i) the value to pack */ int bitno, /* (i) the number of bits that the
int bitno, /* (i) the number of bits that the value will fit within */
value will fit within */ int *pos /* (i/o) write position in the
int *pos /* (i/o) write position in the current byte */
current byte */ );
);
void unpack(
void unpack( unsigned char **bitstream, /* (i/o) on entrance pointer to
unsigned char **bitstream, /* (i/o) on entrance pointer to place
in bitstream to unpack
new data from, on exit pointer place in bitstream to
to place in bitstream to unpack new data from, on
unpack future data from */ exit pointer to place in
int *index, /* (o) resulting value */ bitstream to unpack future
int bitno, /* (i) number of bits used to data from */
represent the value */ int *index, /* (o) resulting value */
int *pos /* (i/o) read position in the int bitno, /* (i) number of bits used to
current byte */ represent the value */
); int *pos /* (i/o) read position in the
current byte */
#endif );
#endif

View File

@@ -1,66 +1,107 @@
/****************************************************************** /******************************************************************
iLBC Speech Coder ANSI-C Source Code iLBC Speech Coder ANSI-C Source Code
syntFilter.c syntFilter.c
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/
******************************************************************/
#include "iLBC_define.h"
#include "iLBC_define.h"
#include "syntFilter.h" /*----------------------------------------------------------------*
* LP synthesis filter.
/*----------------------------------------------------------------* *---------------------------------------------------------------*/
* LP synthesis filter.
*---------------------------------------------------------------*/ void syntFilter(
float *Out, /* (i/o) Signal to be filtered */
void syntFilter( float *a, /* (i) LP parameters */
float *Out, /* (i/o) Signal to be filtered */ int len, /* (i) Length of signal */
float *a, /* (i) LP parameters */ float *mem /* (i/o) Filter state */
int len, /* (i) Length of signal */ ){
float *mem /* (i/o) Filter state */ int i, j;
){ float *po, *pi, *pa, *pm;
int i, j;
float *po, *pi, *pa, *pm; po=Out;
po=Out; /* Filter first part using memory from past */
/* Filter first part using memory from past */ for (i=0; i<LPC_FILTERORDER; i++) {
pi=&Out[i-1];
for (i=0;i<LPC_FILTERORDER;i++) { pa=&a[1];
pi=&Out[i-1]; pm=&mem[LPC_FILTERORDER-1];
pa=&a[1]; for (j=1; j<=i; j++) {
pm=&mem[LPC_FILTERORDER-1]; *po-=(*pa++)*(*pi--);
for (j=1;j<=i;j++) { }
*po-=(*pa++)*(*pi--); for (j=i+1; j<LPC_FILTERORDER+1; j++) {
} *po-=(*pa++)*(*pm--);
for (j=i+1;j<LPC_FILTERORDER+1;j++) { }
*po-=(*pa++)*(*pm--); po++;
} }
po++;
} /* Filter last part where the state is entierly in
the output vector */
/* 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]; pi=&Out[i-1];
pa=&a[1]; pa=&a[1];
for (j=1;j<LPC_FILTERORDER+1;j++) { for (j=1; j<LPC_FILTERORDER+1; j++) {
*po-=(*pa++)*(*pi--); *po-=(*pa++)*(*pi--);
} }
po++; po++;
} }
/* Update state vector */ /* Update state vector */
memcpy(mem, &Out[len-LPC_FILTERORDER], memcpy(mem, &Out[len-LPC_FILTERORDER],
LPC_FILTERORDER*sizeof(float)); LPC_FILTERORDER*sizeof(float));
} }

View File

@@ -1,26 +1,27 @@
/****************************************************************** /******************************************************************
iLBC Speech Coder ANSI-C Source Code iLBC Speech Coder ANSI-C Source Code
syntFilter.h syntFilter.h
Copyright (c) 2001, Copyright (C) The Internet Society (2004).
Global IP Sound AB. All Rights Reserved.
All rights reserved.
******************************************************************/
******************************************************************/
#ifndef __iLBC_SYNTFILTER_H
#ifndef __iLBC_SYNTFILTER_H #define __iLBC_SYNTFILTER_H
#define __iLBC_SYNTFILTER_H
void syntFilter(
void syntFilter( float *Out, /* (i/o) Signal to be filtered */
float *Out, /* (i/o) Signal to be filtered */ float *a, /* (i) LP parameters */
float *a, /* (i) LP parameters */ int len, /* (i) Length of signal */
int len, /* (i) Length of signal */ float *mem /* (i/o) Filter state */
float *mem /* (i/o) Filter state */
);
);
#endif
#endif