A.33. iCBSearch.h
/****************************************************************** iLBC Speech Coder ANSI-C Source Code iCBSearch.h Copyright (C) The Internet Society (2004). All Rights Reserved. ******************************************************************/ #ifndef __iLBC_ICBSEARCH_H #define __iLBC_ICBSEARCH_H
void iCBSearch( iLBC_Enc_Inst_t *iLBCenc_inst, /* (i) the encoder state structure */ int *index, /* (o) Codebook indices */ int *gain_index,/* (o) Gain quantization indices */ float *intarget,/* (i) Target vector for encoding */ float *mem, /* (i) Buffer for codebook construction */ int lMem, /* (i) Length of buffer */ int lTarget, /* (i) Length of vector */ int nStages, /* (i) Number of codebook stages */ float *weightDenum, /* (i) weighting filter coefficients */ float *weightState, /* (i) weighting filter state */ int block /* (i) the sub-block number */ ); #endifA.34. iCBSearch.c
/****************************************************************** iLBC Speech Coder ANSI-C Source Code iCBSearch.c Copyright (C) The Internet Society (2004). All Rights Reserved. ******************************************************************/ #include <math.h> #include <string.h> #include "iLBC_define.h" #include "gainquant.h" #include "createCB.h" #include "filter.h" #include "constants.h" /*----------------------------------------------------------------* * Search routine for codebook encoding and gain quantization. *---------------------------------------------------------------*/ void iCBSearch( iLBC_Enc_Inst_t *iLBCenc_inst, /* (i) the encoder state structure */ int *index, /* (o) Codebook indices */ int *gain_index,/* (o) Gain quantization indices */
float *intarget,/* (i) Target vector for encoding */ float *mem, /* (i) Buffer for codebook construction */ int lMem, /* (i) Length of buffer */ int lTarget, /* (i) Length of vector */ int nStages, /* (i) Number of codebook stages */ float *weightDenum, /* (i) weighting filter coefficients */ float *weightState, /* (i) weighting filter state */ int block /* (i) the sub-block number */ ){ int i, j, icount, stage, best_index, range, counter; float max_measure, gain, measure, crossDot, ftmp; float gains[CB_NSTAGES]; float target[SUBL]; int base_index, sInd, eInd, base_size; int sIndAug=0, eIndAug=0; float buf[CB_MEML+SUBL+2*LPC_FILTERORDER]; float invenergy[CB_EXPAND*128], energy[CB_EXPAND*128]; float *pp, *ppi=0, *ppo=0, *ppe=0; float cbvectors[CB_MEML]; float tene, cene, cvec[SUBL]; float aug_vec[SUBL]; memset(cvec,0,SUBL*sizeof(float)); /* Determine size of codebook sections */ base_size=lMem-lTarget+1; if (lTarget==SUBL) { base_size=lMem-lTarget+1+lTarget/2; } /* setup buffer for weighting */ memcpy(buf,weightState,sizeof(float)*LPC_FILTERORDER); memcpy(buf+LPC_FILTERORDER,mem,lMem*sizeof(float)); memcpy(buf+LPC_FILTERORDER+lMem,intarget,lTarget*sizeof(float)); /* weighting */ AllPoleFilter(buf+LPC_FILTERORDER, weightDenum, lMem+lTarget, LPC_FILTERORDER); /* Construct the codebook and target needed */ memcpy(target, buf+LPC_FILTERORDER+lMem, lTarget*sizeof(float)); 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. */ filteredCBvecs(cbvectors, buf+LPC_FILTERORDER, lMem); /* The Main Loop over stages */ for (stage=0; stage<nStages; stage++) { range = search_rangeTbl[block][stage]; /* initialize search measure */ max_measure = (float)-10000000.0; gain = (float)0.0; best_index = 0; /* Compute cross dot product between the target and the CB memory */ crossDot=0.0; pp=buf+LPC_FILTERORDER+lMem-lTarget; for (j=0; j<lTarget; j++) { crossDot += target[j]*(*pp++); } if (stage==0) { /* Calculate energy in the first block of 'lTarget' samples. */ ppe = energy; ppi = buf+LPC_FILTERORDER+lMem-lTarget-1; ppo = buf+LPC_FILTERORDER+lMem-1; *ppe=0.0; pp=buf+LPC_FILTERORDER+lMem-lTarget; for (j=0; j<lTarget; j++) { *ppe+=(*pp)*(*pp++); } if (*ppe>0.0) { invenergy[0] = (float) 1.0 / (*ppe + EPS); } else { invenergy[0] = (float) 0.0;
} ppe++; measure=(float)-10000000.0; if (crossDot > 0.0) { measure = crossDot*crossDot*invenergy[0]; } } else { measure = crossDot*crossDot*invenergy[0]; } /* check if measure is better */ ftmp = crossDot*invenergy[0]; if ((measure>max_measure) && (fabs(ftmp)<CB_MAXGAIN)) { best_index = 0; max_measure = measure; gain = ftmp; } /* loop over the main first codebook section, full search */ for (icount=1; icount<range; icount++) { /* calculate measure */ crossDot=0.0; pp = buf+LPC_FILTERORDER+lMem-lTarget-icount; for (j=0; j<lTarget; j++) { crossDot += target[j]*(*pp++); } if (stage==0) { *ppe++ = energy[icount-1] + (*ppi)*(*ppi) - (*ppo)*(*ppo); ppo--; ppi--; if (energy[icount]>0.0) { invenergy[icount] = (float)1.0/(energy[icount]+EPS); } else { invenergy[icount] = (float) 0.0; }
measure=(float)-10000000.0; if (crossDot > 0.0) { measure = crossDot*crossDot*invenergy[icount]; } } else { measure = crossDot*crossDot*invenergy[icount]; } /* check if measure is better */ ftmp = crossDot*invenergy[icount]; if ((measure>max_measure) && (fabs(ftmp)<CB_MAXGAIN)) { best_index = icount; max_measure = measure; gain = ftmp; } } /* Loop over augmented part in the first codebook * section, full search. * The vectors are interpolated. */ if (lTarget==SUBL) { /* Search for best possible cb vector and compute the CB-vectors' energy. */ searchAugmentedCB(20, 39, stage, base_size-lTarget/2, target, buf+LPC_FILTERORDER+lMem, &max_measure, &best_index, &gain, energy, invenergy); } /* set search range for following codebook sections */ base_index=best_index; /* unrestricted search */ if (CB_RESRANGE == -1) { sInd=0; eInd=range-1; sIndAug=20; eIndAug=39; }
/* restricted search around best index from first codebook section */ else { /* Initialize search indices */ sIndAug=0; eIndAug=0; sInd=base_index-CB_RESRANGE/2; eInd=sInd+CB_RESRANGE; if (lTarget==SUBL) { if (sInd<0) { sIndAug = 40 + sInd; eIndAug = 39; sInd=0; } else if ( base_index < (base_size-20) ) { if (eInd > range) { sInd -= (eInd-range); eInd = range; } } else { /* base_index >= (base_size-20) */ if (sInd < (base_size-20)) { sIndAug = 20; sInd = 0; eInd = 0; eIndAug = 19 + CB_RESRANGE; if(eIndAug > 39) { eInd = eIndAug-39; eIndAug = 39; } } else { sIndAug = 20 + sInd - (base_size-20); eIndAug = 39; sInd = 0; eInd = CB_RESRANGE - (eIndAug-sIndAug+1); } } } else { /* lTarget = 22 or 23 */ if (sInd < 0) { eInd -= sInd;
sInd = 0; } if(eInd > range) { sInd -= (eInd - range); eInd = range; } } } /* search of higher codebook section */ /* index search range */ counter = sInd; sInd += base_size; eInd += base_size; if (stage==0) { ppe = energy+base_size; *ppe=0.0; pp=cbvectors+lMem-lTarget; for (j=0; j<lTarget; j++) { *ppe+=(*pp)*(*pp++); } ppi = cbvectors + lMem - 1 - lTarget; ppo = cbvectors + lMem - 1; for (j=0; j<(range-1); j++) { *(ppe+1) = *ppe + (*ppi)*(*ppi) - (*ppo)*(*ppo); ppo--; ppi--; ppe++; } } /* loop over search range */ for (icount=sInd; icount<eInd; icount++) { /* calculate measure */ crossDot=0.0; pp=cbvectors + lMem - (counter++) - lTarget; for (j=0;j<lTarget;j++) {
crossDot += target[j]*(*pp++); } if (energy[icount]>0.0) { invenergy[icount] =(float)1.0/(energy[icount]+EPS); } else { invenergy[icount] =(float)0.0; } if (stage==0) { measure=(float)-10000000.0; if (crossDot > 0.0) { measure = crossDot*crossDot* invenergy[icount]; } } else { measure = crossDot*crossDot*invenergy[icount]; } /* check if measure is better */ ftmp = crossDot*invenergy[icount]; if ((measure>max_measure) && (fabs(ftmp)<CB_MAXGAIN)) { best_index = icount; max_measure = measure; gain = ftmp; } } /* Search the augmented CB inside the limited range. */ if ((lTarget==SUBL)&&(sIndAug!=0)) { searchAugmentedCB(sIndAug, eIndAug, stage, 2*base_size-20, target, cbvectors+lMem, &max_measure, &best_index, &gain, energy, invenergy); } /* record best index */ index[stage] = best_index; /* gain quantization */ if (stage==0){
if (gain<0.0){ gain = 0.0; } if (gain>CB_MAXGAIN) { gain = (float)CB_MAXGAIN; } gain = gainquant(gain, 1.0, 32, &gain_index[stage]); } else { if (stage==1) { gain = gainquant(gain, (float)fabs(gains[stage-1]), 16, &gain_index[stage]); } else { gain = gainquant(gain, (float)fabs(gains[stage-1]), 8, &gain_index[stage]); } } /* Extract the best (according to measure) codebook vector */ if (lTarget==(STATE_LEN-iLBCenc_inst->state_short_len)) { if (index[stage]<base_size) { pp=buf+LPC_FILTERORDER+lMem-lTarget-index[stage]; } else { pp=cbvectors+lMem-lTarget- index[stage]+base_size; } } else { if (index[stage]<base_size) { if (index[stage]<(base_size-20)) { pp=buf+LPC_FILTERORDER+lMem- lTarget-index[stage]; } else { createAugmentedVec(index[stage]-base_size+40, buf+LPC_FILTERORDER+lMem,aug_vec); pp=aug_vec; } } else { int filterno, position; filterno=index[stage]/base_size; position=index[stage]-filterno*base_size;
if (position<(base_size-20)) { pp=cbvectors+filterno*lMem-lTarget- index[stage]+filterno*base_size; } else { createAugmentedVec( index[stage]-(filterno+1)*base_size+40, cbvectors+filterno*lMem,aug_vec); pp=aug_vec; } } } /* Subtract the best codebook vector, according to measure, from the target vector */ for (j=0;j<lTarget;j++) { cvec[j] += gain*(*pp); target[j] -= gain*(*pp++); } /* record quantized gain */ gains[stage]=gain; }/* end of Main Loop. for (stage=0;... */ /* Gain adjustment for energy matching */ cene=0.0; 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; }
A.35. LPCdecode.h
/****************************************************************** iLBC Speech Coder ANSI-C Source Code LPC_decode.h Copyright (C) The Internet Society (2004). All Rights Reserved. ******************************************************************/ #ifndef __iLBC_LPC_DECODE_H #define __iLBC_LPC_DECODE_H void LSFinterpolate2a_dec( float *a, /* (o) lpc coefficients for a sub-frame */ float *lsf1, /* (i) first lsf coefficient vector */ float *lsf2, /* (i) second lsf coefficient vector */ float coef, /* (i) interpolation weight */ int length /* (i) length of lsf vectors */ ); void SimplelsfDEQ( 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 coefficients */ float *lsfdeq, /* (i) dequantized lsf coefficients */ int length, /* (i) length of lsf coefficient vector */ iLBC_Dec_Inst_t *iLBCdec_inst /* (i) the decoder state structure */ ); #endif
A.36. LPCdecode.c
/****************************************************************** iLBC Speech Coder ANSI-C Source Code LPC_decode.c Copyright (C) The Internet Society (2004). All Rights Reserved. ******************************************************************/ #include <math.h> #include <string.h> #include "helpfun.h" #include "lsf.h" #include "iLBC_define.h" #include "constants.h" /*---------------------------------------------------------------* * interpolation of lsf coefficients for the decoder *--------------------------------------------------------------*/ void LSFinterpolate2a_dec( float *a, /* (o) lpc coefficients for a sub-frame */ float *lsf1, /* (i) first lsf coefficient vector */ float *lsf2, /* (i) second lsf coefficient vector */ float coef, /* (i) interpolation weight */ int length /* (i) length of lsf vectors */ ){ float lsftmp[LPC_FILTERORDER]; interpolate(lsftmp, lsf1, lsf2, coef, length); lsf2a(a, lsftmp); } /*---------------------------------------------------------------* * obtain dequantized lsf coefficients from quantization index *--------------------------------------------------------------*/ void SimplelsfDEQ( float *lsfdeq, /* (o) dequantized lsf coefficients */ int *index, /* (i) quantization index */ int lpc_n /* (i) number of LPCs */ ){ int i, j, pos, cb_pos;
/* decode first LSF */ pos = 0; cb_pos = 0; for (i = 0; i < LSF_NSPLIT; i++) { for (j = 0; j < dim_lsfCbTbl[i]; j++) { lsfdeq[pos + j] = lsfCbTbl[cb_pos + (long)(index[i])*dim_lsfCbTbl[i] + j]; } pos += dim_lsfCbTbl[i]; cb_pos += size_lsfCbTbl[i]*dim_lsfCbTbl[i]; } if (lpc_n>1) { /* decode last LSF */ pos = 0; cb_pos = 0; for (i = 0; i < LSF_NSPLIT; i++) { for (j = 0; j < dim_lsfCbTbl[i]; j++) { lsfdeq[LPC_FILTERORDER + pos + j] = lsfCbTbl[cb_pos + (long)(index[LSF_NSPLIT + i])* dim_lsfCbTbl[i] + j]; } pos += dim_lsfCbTbl[i]; cb_pos += size_lsfCbTbl[i]*dim_lsfCbTbl[i]; } } } /*----------------------------------------------------------------* * obtain synthesis and weighting filters form lsf coefficients *---------------------------------------------------------------*/ void DecoderInterpolateLSF( float *syntdenum, /* (o) synthesis filter coefficients */ float *weightdenum, /* (o) weighting denumerator coefficients */ float *lsfdeq, /* (i) dequantized lsf coefficients */ int length, /* (i) length of lsf coefficient vector */ iLBC_Dec_Inst_t *iLBCdec_inst /* (i) the decoder state structure */ ){ int i, pos, lp_length; float lp[LPC_FILTERORDER + 1], *lsfdeq2;
lsfdeq2 = lsfdeq + length; lp_length = length + 1; if (iLBCdec_inst->mode==30) { /* sub-frame 1: Interpolation between old and first */ LSFinterpolate2a_dec(lp, iLBCdec_inst->lsfdeqold, lsfdeq, lsf_weightTbl_30ms[0], length); memcpy(syntdenum,lp,lp_length*sizeof(float)); bwexpand(weightdenum, lp, LPC_CHIRP_WEIGHTDENUM, lp_length); /* sub-frames 2 to 6: interpolation between first and last LSF */ pos = lp_length; for (i = 1; i < 6; i++) { LSFinterpolate2a_dec(lp, lsfdeq, lsfdeq2, lsf_weightTbl_30ms[i], length); memcpy(syntdenum + pos,lp,lp_length*sizeof(float)); bwexpand(weightdenum + pos, lp, LPC_CHIRP_WEIGHTDENUM, lp_length); pos += lp_length; } } else { pos = 0; for (i = 0; i < iLBCdec_inst->nsub; i++) { LSFinterpolate2a_dec(lp, iLBCdec_inst->lsfdeqold, lsfdeq, lsf_weightTbl_20ms[i], length); memcpy(syntdenum+pos,lp,lp_length*sizeof(float)); bwexpand(weightdenum+pos, lp, LPC_CHIRP_WEIGHTDENUM, lp_length); pos += lp_length; } } /* update memory */ if (iLBCdec_inst->mode==30) memcpy(iLBCdec_inst->lsfdeqold, lsfdeq2, length*sizeof(float)); else memcpy(iLBCdec_inst->lsfdeqold, lsfdeq, length*sizeof(float)); }
A.37. LPCencode.h
/****************************************************************** iLBC Speech Coder ANSI-C Source Code LPCencode.h Copyright (C) The Internet Society (2004). All Rights Reserved. ******************************************************************/ #ifndef __iLBC_LPCENCOD_H #define __iLBC_LPCENCOD_H 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 */ ); #endifA.38. LPCencode.c
/****************************************************************** iLBC Speech Coder ANSI-C Source Code LPCencode.c Copyright (C) The Internet Society (2004). All Rights Reserved. ******************************************************************/ #include <string.h> #include "iLBC_define.h" #include "helpfun.h" #include "lsf.h" #include "constants.h"
/*----------------------------------------------------------------* * lpc analysis (subrutine to LPCencode) *---------------------------------------------------------------*/ void SimpleAnalysis( float *lsf, /* (o) lsf coefficients */ float *data, /* (i) new data vector */ iLBC_Enc_Inst_t *iLBCenc_inst /* (i/o) the encoder state structure */ ){ int k, is; float temp[BLOCKL_MAX], lp[LPC_FILTERORDER + 1]; float lp2[LPC_FILTERORDER + 1]; float r[LPC_FILTERORDER + 1]; is=LPC_LOOKBACK+BLOCKL_MAX-iLBCenc_inst->blockl; memcpy(iLBCenc_inst->lpc_buffer+is,data, iLBCenc_inst->blockl*sizeof(float)); /* No lookahead, last window is asymmetric */ for (k = 0; k < iLBCenc_inst->lpc_n; k++) { is = LPC_LOOKBACK; if (k < (iLBCenc_inst->lpc_n - 1)) { window(temp, lpc_winTbl, iLBCenc_inst->lpc_buffer, BLOCKL_MAX); } else { window(temp, lpc_asymwinTbl, iLBCenc_inst->lpc_buffer + is, BLOCKL_MAX); } autocorr(r, temp, BLOCKL_MAX, LPC_FILTERORDER); window(r, r, lpc_lagwinTbl, LPC_FILTERORDER + 1); levdurb(lp, temp, r, LPC_FILTERORDER); bwexpand(lp2, lp, LPC_CHIRP_SYNTDENUM, LPC_FILTERORDER+1); a2lsf(lsf + k*LPC_FILTERORDER, lp2); } is=LPC_LOOKBACK+BLOCKL_MAX-iLBCenc_inst->blockl; memmove(iLBCenc_inst->lpc_buffer, iLBCenc_inst->lpc_buffer+LPC_LOOKBACK+BLOCKL_MAX-is, is*sizeof(float)); } /*----------------------------------------------------------------*
* lsf interpolator and conversion from lsf to a coefficients * (subrutine to SimpleInterpolateLSF) *---------------------------------------------------------------*/ 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 */ long length /* (i) length of coefficient vectors */ ){ float lsftmp[LPC_FILTERORDER]; interpolate(lsftmp, lsf1, lsf2, coef, length); lsf2a(a, lsftmp); } /*----------------------------------------------------------------* * lsf interpolator (subrutine to LPCencode) *---------------------------------------------------------------*/ void SimpleInterpolateLSF( float *syntdenum, /* (o) the synthesis filter denominator resulting from the quantized interpolated lsf */ float *weightdenum, /* (o) the weighting filter denominator resulting from the unquantized interpolated lsf */ float *lsf, /* (i) the unquantized lsf coefficients */ float *lsfdeq, /* (i) the dequantized lsf coefficients */ float *lsfold, /* (i) the unquantized lsf coefficients of 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; 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); }A.39. lsf.h
/****************************************************************** iLBC Speech Coder ANSI-C Source Code lsf.h Copyright (C) The Internet Society (2004). All Rights Reserved. ******************************************************************/ #ifndef __iLBC_LSF_H #define __iLBC_LSF_H void a2lsf( float *freq,/* (o) lsf coefficients */ float *a /* (i) lpc coefficients */ ); void lsf2a( float *a_coef, /* (o) lpc coefficients */ float *freq /* (i) lsf coefficients */ ); #endifA.40. lsf.c
/****************************************************************** iLBC Speech Coder ANSI-C Source Code lsf.c Copyright (C) The Internet Society (2004). All Rights Reserved. ******************************************************************/ #include <string.h>
#include <math.h> #include "iLBC_define.h" /*----------------------------------------------------------------* * conversion from lpc coefficients to lsf coefficients *---------------------------------------------------------------*/ void a2lsf( 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)0.00079375}; float step; int step_idx; int lsp_index; float p[LPC_HALFORDER]; float q[LPC_HALFORDER]; float p_pre[LPC_HALFORDER]; float q_pre[LPC_HALFORDER]; float old_p, old_q, *old; float *pq_coef; float omega, old_omega; int i; float hlp, hlp1, hlp2, hlp3, hlp4, hlp5; for (i=0; i<LPC_HALFORDER; i++) { p[i] = (float)-1.0 * (a[i + 1] + a[LPC_FILTERORDER - i]); q[i] = a[LPC_FILTERORDER - i] - a[i + 1]; } p_pre[0] = (float)-1.0 - p[0]; p_pre[1] = - p_pre[0] - p[1]; p_pre[2] = - p_pre[1] - p[2]; p_pre[3] = - p_pre[2] - p[3]; p_pre[4] = - p_pre[3] - p[4]; p_pre[4] = p_pre[4] / 2; q_pre[0] = (float)1.0 - q[0]; q_pre[1] = q_pre[0] - q[1]; q_pre[2] = q_pre[1] - q[2]; q_pre[3] = q_pre[2] - q[3]; q_pre[4] = q_pre[3] - q[4]; q_pre[4] = q_pre[4] / 2; omega = 0.0;
old_omega = 0.0; old_p = FLOAT_MAX; old_q = FLOAT_MAX; /* Here we loop through lsp_index to find all the LPC_FILTERORDER roots for omega. */ for (lsp_index = 0; lsp_index<LPC_FILTERORDER; lsp_index++) { /* Depending on lsp_index being even or odd, we alternatively solve the roots for the two LSP equations. */ if ((lsp_index & 0x1) == 0) { pq_coef = p_pre; old = &old_p; } else { pq_coef = q_pre; old = &old_q; } /* Start with low resolution grid */ for (step_idx = 0, step = steps[step_idx]; step_idx < LSF_NUMBER_OF_STEPS;){ /* cos(10piw) + pq(0)cos(8piw) + pq(1)cos(6piw) + pq(2)cos(4piw) + pq(3)cod(2piw) + pq(4) */ hlp = (float)cos(omega * TWO_PI); hlp1 = (float)2.0 * hlp + pq_coef[0]; hlp2 = (float)2.0 * hlp * hlp1 - (float)1.0 + pq_coef[1]; 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 (fabs(hlp5) >= fabs(*old)) { freq[lsp_index] = omega - step; } else { freq[lsp_index] = omega; }
if ((*old) >= 0.0){ *old = (float)-1.0 * FLOAT_MAX; } else { *old = FLOAT_MAX; } omega = old_omega; step_idx = 0; step_idx = LSF_NUMBER_OF_STEPS; } else { if (step_idx == 0) { old_omega = omega; } step_idx++; omega -= steps[step_idx]; /* Go back one grid step */ step = steps[step_idx]; } } else { /* increment omega until they are of different sign, and we know there is at least one root between omega and old_omega */ *old = hlp5; omega += step; } } } 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 */ float *freq /* (i) lsf coefficients */
){ int i, j; float hlp; float p[LPC_HALFORDER], q[LPC_HALFORDER]; float a[LPC_HALFORDER + 1], a1[LPC_HALFORDER], a2[LPC_HALFORDER]; float b[LPC_HALFORDER + 1], b1[LPC_HALFORDER], b2[LPC_HALFORDER]; for (i=0; i<LPC_FILTERORDER; i++) { freq[i] = freq[i] * PI2; } /* Check input for ill-conditioned cases. This part is not found in the TIA standard. It involves the following 2 IF 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 the other "freq" values slightly */ if ((freq[0] <= 0.0) || (freq[LPC_FILTERORDER - 1] >= 0.5)){ if (freq[0] <= 0.0) { freq[0] = (float)0.022; } if (freq[LPC_FILTERORDER - 1] >= 0.5) { freq[LPC_FILTERORDER - 1] = (float)0.499; } hlp = (freq[LPC_FILTERORDER - 1] - freq[0]) / (float) (LPC_FILTERORDER - 1); for (i=1; i<LPC_FILTERORDER; i++) { freq[i] = freq[i - 1] + hlp; } } memset(a1, 0, LPC_HALFORDER*sizeof(float)); memset(a2, 0, LPC_HALFORDER*sizeof(float)); memset(b1, 0, LPC_HALFORDER*sizeof(float)); 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. Note that for this code p[i] specifies the coefficients used in .Q_A(z) while q[i] specifies the coefficients used in .P_A(z) */ for (i=0; i<LPC_HALFORDER; i++) { p[i] = (float)cos(TWO_PI * freq[2 * i]); q[i] = (float)cos(TWO_PI * freq[2 * i + 1]); } a[0] = 0.25; b[0] = 0.25; for (i= 0; i<LPC_HALFORDER; i++) { a[i + 1] = a[i] - 2 * p[i] * a1[i] + a2[i]; b[i + 1] = b[i] - 2 * q[i] * b1[i] + b2[i]; a2[i] = a1[i]; a1[i] = a[i]; b2[i] = b1[i]; b1[i] = b[i]; } for (j=0; j<LPC_FILTERORDER; j++) { if (j == 0) { a[0] = 0.25; b[0] = -0.25; } else { a[0] = b[0] = 0.0; } for (i=0; i<LPC_HALFORDER; i++) { a[i + 1] = a[i] - 2 * p[i] * a1[i] + a2[i]; b[i + 1] = b[i] - 2 * q[i] * b1[i] + b2[i]; a2[i] = a1[i]; 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; }
A.41. packing.h
/****************************************************************** iLBC Speech Coder ANSI-C Source Code packing.h Copyright (C) The Internet Society (2004). All Rights Reserved. ******************************************************************/ #ifndef __PACKING_H #define __PACKING_H void packsplit( int *index, /* (i) the value to split */ int *firstpart, /* (o) the value specified by most significant bits */ int *rest, /* (o) the value specified by least significant bits */ int bitno_firstpart, /* (i) number of bits in most significant part */ int bitno_total /* (i) number of bits in full range of value */ ); void packcombine( int *index, /* (i/o) the msb value in the combined value out */ int rest, /* (i) the lsb value */ int bitno_rest /* (i) the number of bits in the lsb part */ ); void dopack( unsigned char **bitstream, /* (i/o) on entrance pointer to place in bitstream to pack new data, on exit pointer to place in bitstream to pack future data */ int index, /* (i) the value to pack */ int bitno, /* (i) the number of bits that the value will fit within */ int *pos /* (i/o) write position in the current byte */ );
void unpack( unsigned char **bitstream, /* (i/o) on entrance pointer to place in bitstream to unpack new data from, on exit pointer to place in bitstream to unpack future data from */ int *index, /* (o) resulting value */ int bitno, /* (i) number of bits used to represent the value */ int *pos /* (i/o) read position in the current byte */ ); #endifA.42. packing.c
/****************************************************************** iLBC Speech Coder ANSI-C Source Code packing.c Copyright (C) The Internet Society (2004). All Rights Reserved. ******************************************************************/ #include <math.h> #include <stdlib.h> #include "iLBC_define.h" #include "constants.h" #include "helpfun.h" #include "string.h" /*----------------------------------------------------------------* * splitting an integer into first most significant bits and * remaining least significant bits *---------------------------------------------------------------*/ void packsplit( int *index, /* (i) the value to split */ int *firstpart, /* (o) the value specified by most significant bits */ int *rest, /* (o) the value specified by least significant bits */
int bitno_firstpart, /* (i) number of bits in most significant part */ int bitno_total /* (i) number of bits in full range of value */ ){ int bitno_rest = bitno_total-bitno_firstpart; *firstpart = *index>>(bitno_rest); *rest = *index-(*firstpart<<(bitno_rest)); } /*----------------------------------------------------------------* * combining a value corresponding to msb's with a value * corresponding to lsb's *---------------------------------------------------------------*/ void packcombine( int *index, /* (i/o) the msb value in the combined value out */ int rest, /* (i) the lsb value */ int bitno_rest /* (i) the number of bits in the lsb part */ ){ *index = *index<<bitno_rest; *index += rest; } /*----------------------------------------------------------------* * packing of bits into bitstream, i.e., vector of bytes *---------------------------------------------------------------*/ void dopack( unsigned char **bitstream, /* (i/o) on entrance pointer to place in bitstream to pack new data, on exit pointer to place in bitstream to pack future data */ int index, /* (i) the value to pack */ int bitno, /* (i) the number of bits that the value will fit within */ int *pos /* (i/o) write position in the current byte */ ){ int posLeft; /* Clear the bits before starting in a new byte */ if ((*pos)==0) {
**bitstream=0; } while (bitno>0) { /* Jump to the next byte if end of this byte is reached*/ if (*pos==8) { *pos=0; (*bitstream)++; **bitstream=0; } posLeft=8-(*pos); /* Insert index into the bitstream */ if (bitno <= posLeft) { **bitstream |= (unsigned char)(index<<(posLeft-bitno)); *pos+=bitno; bitno=0; } else { **bitstream |= (unsigned char)(index>>(bitno-posLeft)); *pos=8; index-=((index>>(bitno-posLeft))<<(bitno-posLeft)); bitno-=posLeft; } } } /*----------------------------------------------------------------* * 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 unpack new data from, on exit pointer to place in bitstream to unpack future data from */ int *index, /* (o) resulting value */ int bitno, /* (i) number of bits used to represent the value */ int *pos /* (i/o) read position in the current byte */
){ int BitsLeft; *index=0; while (bitno>0) { /* move forward in bitstream when the end of the byte is reached */ if (*pos==8) { *pos=0; (*bitstream)++; } BitsLeft=8-(*pos); /* Extract bits to index */ if (BitsLeft>=bitno) { *index+=((((**bitstream)<<(*pos)) & 0xFF)>>(8-bitno)); *pos+=bitno; bitno=0; } else { if ((8-bitno)>0) { *index+=((((**bitstream)<<(*pos)) & 0xFF)>> (8-bitno)); *pos=8; } else { *index+=(((int)(((**bitstream)<<(*pos)) & 0xFF))<< (bitno-8)); *pos=8; } bitno-=BitsLeft; } } }A.43. StateConstructW.h
/****************************************************************** iLBC Speech Coder ANSI-C Source Code StateConstructW.h
Copyright (C) The Internet Society (2004). All Rights Reserved. ******************************************************************/ #ifndef __iLBC_STATECONSTRUCTW_H #define __iLBC_STATECONSTRUCTW_H void StateConstructW( int idxForMax, /* (i) 6-bit index for the quantization of max amplitude */ int *idxVec, /* (i) vector of quantization indexes */ float *syntDenum, /* (i) synthesis filter denumerator */ float *out, /* (o) the decoded state vector */ int len /* (i) length of a state vector */ ); #endifA.44. StateConstructW.c
/****************************************************************** iLBC Speech Coder ANSI-C Source Code StateConstructW.c Copyright (C) The Internet Society (2004). All Rights Reserved. ******************************************************************/ #include <math.h> #include <string.h> #include "iLBC_define.h" #include "constants.h" #include "filter.h" /*----------------------------------------------------------------* * decoding of the start state *---------------------------------------------------------------*/ void StateConstructW( int idxForMax, /* (i) 6-bit index for the quantization of max amplitude */ int *idxVec, /* (i) vector of quantization indexes */ float *syntDenum, /* (i) synthesis filter denumerator */
float *out, /* (o) the decoded state vector */ int len /* (i) length of a state vector */ ){ float maxVal, tmpbuf[LPC_FILTERORDER+2*STATE_LEN], *tmp, numerator[LPC_FILTERORDER+1]; float foutbuf[LPC_FILTERORDER+2*STATE_LEN], *fout; int k,tmpi; /* decoding of the maximum value */ maxVal = state_frgqTbl[idxForMax]; maxVal = (float)pow(10,maxVal)/(float)4.5; /* initialization of buffers and coefficients */ memset(tmpbuf, 0, LPC_FILTERORDER*sizeof(float)); memset(foutbuf, 0, LPC_FILTERORDER*sizeof(float)); for (k=0; k<LPC_FILTERORDER; k++) { numerator[k]=syntDenum[LPC_FILTERORDER-k]; } numerator[LPC_FILTERORDER]=syntDenum[0]; tmp = &tmpbuf[LPC_FILTERORDER]; fout = &foutbuf[LPC_FILTERORDER]; /* decoding of the sample values */ for (k=0; k<len; k++) { tmpi = len-1-k; /* maxVal = 1/scal */ tmp[k] = maxVal*state_sq3Tbl[idxVec[tmpi]]; } /* circular convolution with all-pass filter */ memset(tmp+len, 0, len*sizeof(float)); ZeroPoleFilter(tmp, numerator, syntDenum, 2*len, LPC_FILTERORDER, fout); for (k=0;k<len;k++) { out[k] = fout[len-1-k]+fout[2*len-1-k]; } }
A.45. StateSearchW.h
/****************************************************************** iLBC Speech Coder ANSI-C Source Code StateSearchW.h Copyright (C) The Internet Society (2004). All Rights Reserved. ******************************************************************/ #ifndef __iLBC_STATESEARCHW_H #define __iLBC_STATESEARCHW_H void AbsQuantW( iLBC_Enc_Inst_t *iLBCenc_inst, /* (i) Encoder instance */ float *in, /* (i) vector to encode */ float *syntDenum, /* (i) denominator of synthesis filter */ float *weightDenum, /* (i) denominator of weighting filter */ int *out, /* (o) vector of quantizer indexes */ int len, /* (i) length of vector to encode and vector of quantizer indexes */ int state_first /* (i) position of start state in the 80 vec */ ); void StateSearchW( iLBC_Enc_Inst_t *iLBCenc_inst, /* (i) Encoder instance */ float *residual,/* (i) target residual vector */ float *syntDenum, /* (i) lpc synthesis filter */ float *weightDenum, /* (i) weighting filter denuminator */ int *idxForMax, /* (o) quantizer index for maximum amplitude */ int *idxVec, /* (o) vector of quantization indexes */ int len, /* (i) length of all vectors */ int state_first /* (i) position of start state in the 80 vec */ ); #endif
A.46. StateSearchW.c
/****************************************************************** iLBC Speech Coder ANSI-C Source Code StateSearchW.c Copyright (C) The Internet Society (2004). All Rights Reserved. ******************************************************************/ #include <math.h> #include <string.h> #include "iLBC_define.h" #include "constants.h" #include "filter.h" #include "helpfun.h" /*----------------------------------------------------------------* * predictive noise shaping encoding of scaled start state * (subrutine for StateSearchW) *---------------------------------------------------------------*/ void AbsQuantW( iLBC_Enc_Inst_t *iLBCenc_inst, /* (i) Encoder instance */ float *in, /* (i) vector to encode */ float *syntDenum, /* (i) denominator of synthesis filter */ float *weightDenum, /* (i) denominator of weighting filter */ int *out, /* (o) vector of quantizer indexes */ int len, /* (i) length of vector to encode and vector of quantizer indexes */ int state_first /* (i) position of start state in the 80 vec */ ){ float *syntOut; float syntOutBuf[LPC_FILTERORDER+STATE_SHORT_LEN_30MS]; float toQ, xq; int n; int index; /* initialization of buffer for filtering */ memset(syntOutBuf, 0, LPC_FILTERORDER*sizeof(float));
/* initialization of pointer for filtering */ syntOut = &syntOutBuf[LPC_FILTERORDER]; /* synthesis and weighting filters on input */ if (state_first) { AllPoleFilter (in, weightDenum, SUBL, LPC_FILTERORDER); } else { AllPoleFilter (in, weightDenum, iLBCenc_inst->state_short_len-SUBL, LPC_FILTERORDER); } /* encoding loop */ for (n=0; n<len; n++) { /* time update of filter coefficients */ if ((state_first)&&(n==SUBL)){ syntDenum += (LPC_FILTERORDER+1); weightDenum += (LPC_FILTERORDER+1); /* synthesis and weighting filters on input */ AllPoleFilter (&in[n], weightDenum, len-n, LPC_FILTERORDER); } else if ((state_first==0)&& (n==(iLBCenc_inst->state_short_len-SUBL))) { syntDenum += (LPC_FILTERORDER+1); weightDenum += (LPC_FILTERORDER+1); /* synthesis and weighting filters on input */ AllPoleFilter (&in[n], weightDenum, len-n, LPC_FILTERORDER); } /* prediction of synthesized and weighted input */ syntOut[n] = 0.0; AllPoleFilter (&syntOut[n], weightDenum, 1, LPC_FILTERORDER); /* quantization */ toQ = in[n]-syntOut[n];
sort_sq(&xq, &index, toQ, state_sq3Tbl, 8); out[n]=index; syntOut[n] = state_sq3Tbl[out[n]]; /* update of the prediction filter */ AllPoleFilter(&syntOut[n], weightDenum, 1, LPC_FILTERORDER); } } /*----------------------------------------------------------------* * encoding of start state *---------------------------------------------------------------*/ void StateSearchW( iLBC_Enc_Inst_t *iLBCenc_inst, /* (i) Encoder instance */ float *residual,/* (i) target residual vector */ float *syntDenum, /* (i) lpc synthesis filter */ float *weightDenum, /* (i) weighting filter denuminator */ int *idxForMax, /* (o) quantizer index for maximum amplitude */ int *idxVec, /* (o) vector of quantization indexes */ int len, /* (i) length of all vectors */ int state_first /* (i) position of start state in the 80 vec */ ){ float dtmp, maxVal; float tmpbuf[LPC_FILTERORDER+2*STATE_SHORT_LEN_30MS]; float *tmp, numerator[1+LPC_FILTERORDER]; float foutbuf[LPC_FILTERORDER+2*STATE_SHORT_LEN_30MS], *fout; int k; float qmax, scal; /* initialization of buffers and filter coefficients */ memset(tmpbuf, 0, LPC_FILTERORDER*sizeof(float)); memset(foutbuf, 0, LPC_FILTERORDER*sizeof(float)); for (k=0; k<LPC_FILTERORDER; k++) { numerator[k]=syntDenum[LPC_FILTERORDER-k]; } numerator[LPC_FILTERORDER]=syntDenum[0]; tmp = &tmpbuf[LPC_FILTERORDER]; fout = &foutbuf[LPC_FILTERORDER]; /* circular convolution with the all-pass filter */
memcpy(tmp, residual, len*sizeof(float)); memset(tmp+len, 0, len*sizeof(float)); ZeroPoleFilter(tmp, numerator, syntDenum, 2*len, LPC_FILTERORDER, fout); for (k=0; k<len; k++) { fout[k] += fout[k+len]; } /* identification of the maximum amplitude value */ maxVal = fout[0]; for (k=1; k<len; k++) { if (fout[k]*fout[k] > maxVal*maxVal){ maxVal = fout[k]; } } maxVal=(float)fabs(maxVal); /* encoding of the maximum amplitude value */ if (maxVal < 10.0) { maxVal = 10.0; } maxVal = (float)log10(maxVal); 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); }
A.47. syntFilter.h
/****************************************************************** iLBC Speech Coder ANSI-C Source Code syntFilter.h Copyright (C) The Internet Society (2004). All Rights Reserved. ******************************************************************/ #ifndef __iLBC_SYNTFILTER_H #define __iLBC_SYNTFILTER_H void syntFilter( float *Out, /* (i/o) Signal to be filtered */ float *a, /* (i) LP parameters */ int len, /* (i) Length of signal */ float *mem /* (i/o) Filter state */ ); #endifA.48. syntFilter.c
/****************************************************************** iLBC Speech Coder ANSI-C Source Code syntFilter.c Copyright (C) The Internet Society (2004). All Rights Reserved. ******************************************************************/ #include "iLBC_define.h" /*----------------------------------------------------------------* * LP synthesis filter. *---------------------------------------------------------------*/ void syntFilter( float *Out, /* (i/o) Signal to be filtered */ float *a, /* (i) LP parameters */ int len, /* (i) Length of signal */
float *mem /* (i/o) Filter state */ ){ int i, j; float *po, *pi, *pa, *pm; po=Out; /* Filter first part using memory from past */ for (i=0; i<LPC_FILTERORDER; i++) { pi=&Out[i-1]; pa=&a[1]; pm=&mem[LPC_FILTERORDER-1]; for (j=1; j<=i; j++) { *po-=(*pa++)*(*pi--); } for (j=i+1; j<LPC_FILTERORDER+1; j++) { *po-=(*pa++)*(*pm--); } po++; } /* Filter last part where the state is entirely in the output vector */ for (i=LPC_FILTERORDER; i<len; i++) { pi=&Out[i-1]; pa=&a[1]; for (j=1; j<LPC_FILTERORDER+1; j++) { *po-=(*pa++)*(*pi--); } po++; } /* Update state vector */ memcpy(mem, &Out[len-LPC_FILTERORDER], LPC_FILTERORDER*sizeof(float)); }
Authors' Addresses
Soren Vang Andersen Department of Communication Technology Aalborg University Fredrik Bajers Vej 7A 9200 Aalborg Denmark Phone: ++45 9 6358627 EMail: sva@kom.auc.dk Alan Duric Telio AS Stoperigt. 2 Oslo, N-0250 Norway Phone: +47 21673555 EMail: alan.duric@telio.no Henrik Astrom Global IP Sound AB Olandsgatan 42 Stockholm, S-11663 Sweden Phone: +46 8 54553040 EMail: henrik.astrom@globalipsound.com Roar Hagen Global IP Sound AB Olandsgatan 42 Stockholm, S-11663 Sweden Phone: +46 8 54553040 EMail: roar.hagen@globalipsound.com
W. Bastiaan Kleijn Global IP Sound AB Olandsgatan 42 Stockholm, S-11663 Sweden Phone: +46 8 54553040 EMail: bastiaan.kleijn@globalipsound.com Jan Linden Global IP Sound Inc. 900 Kearny Street, suite 500 San Francisco, CA-94133 USA Phone: +1 415 397 2555 EMail: jan.linden@globalipsound.com
Full Copyright Statement Copyright (C) The Internet Society (2004). This document is subject to the rights, licenses and restrictions contained in BCP 78, and except as set forth therein, the authors retain all their rights. This document and the information contained herein are provided on an "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Intellectual Property The IETF takes no position regarding the validity or scope of any Intellectual Property Rights or other rights that might be claimed to pertain to the implementation or use of the technology described in this document or the extent to which any license under such rights might or might not be available; nor does it represent that it has made any independent effort to identify any such rights. Information on the IETF's procedures with respect to rights in IETF Documents can be found in BCP 78 and BCP 79. Copies of IPR disclosures made to the IETF Secretariat and any assurances of licenses to be made available, or the result of an attempt made to obtain a general license or permission for the use of such proprietary rights by implementers or users of this specification can be obtained from the IETF on-line IPR repository at http://www.ietf.org/ipr. The IETF invites any interested party to bring to its attention any copyrights, patents or patent applications, or other proprietary rights that may cover technology that may be required to implement this standard. Please address the information to the IETF at ietf- ipr@ietf.org. Acknowledgement Funding for the RFC Editor function is currently provided by the Internet Society.