/* * iLBC - a library for the iLBC codec * * StateSearchW.c - The iLBC low bit rate speech codec. * * Adapted by Steve Underwood from the reference * iLBC code supplied in RFC3951. * * Original code Copyright (C) The Internet Society (2004). * All changes to produce this version Copyright (C) 2008 by Steve Underwood * All Rights Reserved. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * $Id: StateSearchW.c,v 1.2 2008/03/06 12:27:37 steveu Exp $ */ /*! \file */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include "ilbc.h" #include "constants.h" #include "filter.h" #include "helpfun.h" #include "StateSearchW.h" /*----------------------------------------------------------------* * predictive noise shaping encoding of scaled start state * (subrutine for StateSearchW) *---------------------------------------------------------------*/ void AbsQuantW(ilbc_encode_state_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[ILBC_LPC_FILTERORDER + STATE_SHORT_LEN_30MS]; float toQ; float xq; int n; int index; /* initialization of buffer for filtering */ memset(syntOutBuf, 0, ILBC_LPC_FILTERORDER*sizeof(float)); /* initialization of pointer for filtering */ syntOut = &syntOutBuf[ILBC_LPC_FILTERORDER]; /* synthesis and weighting filters on input */ if (state_first) { AllPoleFilter(in, weightDenum, SUBL, ILBC_LPC_FILTERORDER); } else { AllPoleFilter(in, weightDenum, iLBCenc_inst->state_short_len - SUBL, ILBC_LPC_FILTERORDER); } /* encoding loop */ for (n = 0; n < len; n++) { /* time update of filter coefficients */ if ((state_first) && (n == SUBL)) { syntDenum += (ILBC_LPC_FILTERORDER + 1); weightDenum += (ILBC_LPC_FILTERORDER + 1); /* synthesis and weighting filters on input */ AllPoleFilter(&in[n], weightDenum, len - n, ILBC_LPC_FILTERORDER); } else if ((state_first == 0) && (n == (iLBCenc_inst->state_short_len - SUBL))) { syntDenum += (ILBC_LPC_FILTERORDER + 1); weightDenum += (ILBC_LPC_FILTERORDER + 1); /* synthesis and weighting filters on input */ AllPoleFilter(&in[n], weightDenum, len - n, ILBC_LPC_FILTERORDER); } /* prediction of synthesized and weighted input */ syntOut[n] = 0.0f; AllPoleFilter(&syntOut[n], weightDenum, 1, ILBC_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, ILBC_LPC_FILTERORDER); } } /*----------------------------------------------------------------* * encoding of start state *---------------------------------------------------------------*/ void StateSearchW(ilbc_encode_state_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; float maxVal; float tmpbuf[ILBC_LPC_FILTERORDER + 2*STATE_SHORT_LEN_30MS]; float *tmp; float numerator[ILBC_LPC_FILTERORDER + 1]; float foutbuf[ILBC_LPC_FILTERORDER + 2*STATE_SHORT_LEN_30MS]; float *fout; int k; float qmax; float scal; /* initialization of buffers and filter coefficients */ memset(tmpbuf, 0, ILBC_LPC_FILTERORDER*sizeof(float)); memset(foutbuf, 0, ILBC_LPC_FILTERORDER*sizeof(float)); for (k = 0; k < ILBC_LPC_FILTERORDER; k++) numerator[k] = syntDenum[ILBC_LPC_FILTERORDER - k]; numerator[ILBC_LPC_FILTERORDER] = syntDenum[0]; tmp = &tmpbuf[ILBC_LPC_FILTERORDER]; fout = &foutbuf[ILBC_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, ILBC_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 = fabsf(maxVal); /* encoding of the maximum amplitude value */ if (maxVal < 10.0f) maxVal = 10.0f; maxVal = log10f(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 = powf(10.0f, maxVal); scal = 4.5f/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); }