freeswitch/libs/ilbc/src/StateSearchW.c

180 lines
6.4 KiB
C

/*
* iLBC - a library for the iLBC codec
*
* StateSearchW.c - The iLBC low bit rate speech codec.
*
* Adapted by Steve Underwood <steveu@coppice.org> 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 <config.h>
#endif
#include <inttypes.h>
#include <math.h>
#include <string.h>
#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);
}