Commit 860c8544 authored by Ghislain MARY's avatar Ghislain MARY

Fix compilation for Windows Phone 8.

parent 1caaaee1
......@@ -23,13 +23,19 @@
typedef struct bcg729DecoderChannelContextStruct_struct bcg729DecoderChannelContextStruct;
#include <stdint.h>
#ifdef _MSC_VER
#define BCG729_VISIBILITY
#else
#define BCG729_VISIBILITY __attribute__ ((visibility ("default")))
#endif
/*****************************************************************************/
/* initBcg729DecoderChannel : create context structure and initialise it */
/* return value : */
/* - the decoder channel context data */
/* */
/*****************************************************************************/
__attribute__ ((visibility ("default"))) bcg729DecoderChannelContextStruct *initBcg729DecoderChannel();
BCG729_VISIBILITY bcg729DecoderChannelContextStruct *initBcg729DecoderChannel();
/*****************************************************************************/
/* closeBcg729DecoderChannel : free memory of context structure */
......@@ -37,7 +43,7 @@ __attribute__ ((visibility ("default"))) bcg729DecoderChannelContextStruct *init
/* -(i) decoderChannelContext : the channel context data */
/* */
/*****************************************************************************/
__attribute__ ((visibility ("default"))) void closeBcg729DecoderChannel(bcg729DecoderChannelContextStruct *decoderChannelContext);
BCG729_VISIBILITY void closeBcg729DecoderChannel(bcg729DecoderChannelContextStruct *decoderChannelContext);
/*****************************************************************************/
/* bcg729Decoder : */
......@@ -48,5 +54,5 @@ __attribute__ ((visibility ("default"))) void closeBcg729DecoderChannel(bcg729De
/* -(o) signal : a decoded frame 80 samples (16 bits PCM) */
/* */
/*****************************************************************************/
__attribute__ ((visibility ("default"))) void bcg729Decoder(bcg729DecoderChannelContextStruct *decoderChannelContext, uint8_t bitStream[], uint8_t frameErasureFlag, int16_t signal[]);
BCG729_VISIBILITY void bcg729Decoder(bcg729DecoderChannelContextStruct *decoderChannelContext, uint8_t bitStream[], uint8_t frameErasureFlag, int16_t signal[]);
#endif /* ifndef DECODER_H */
......@@ -23,13 +23,19 @@
#include <stdint.h>
typedef struct bcg729EncoderChannelContextStruct_struct bcg729EncoderChannelContextStruct;
#ifdef _MSC_VER
#define BCG729_VISIBILITY
#else
#define BCG729_VISIBILITY __attribute__ ((visibility ("default")))
#endif
/*****************************************************************************/
/* initBcg729EncoderChannel : create context structure and initialise it */
/* return value : */
/* - the encoder channel context data */
/* */
/*****************************************************************************/
__attribute__ ((visibility ("default"))) bcg729EncoderChannelContextStruct *initBcg729EncoderChannel();
BCG729_VISIBILITY bcg729EncoderChannelContextStruct *initBcg729EncoderChannel();
/*****************************************************************************/
/* closeBcg729EncoderChannel : free memory of context structure */
......@@ -37,7 +43,7 @@ __attribute__ ((visibility ("default"))) bcg729EncoderChannelContextStruct *init
/* -(i) encoderChannelContext : the channel context data */
/* */
/*****************************************************************************/
__attribute__ ((visibility ("default"))) void closeBcg729EncoderChannel(bcg729EncoderChannelContextStruct *encoderChannelContext);
BCG729_VISIBILITY void closeBcg729EncoderChannel(bcg729EncoderChannelContextStruct *encoderChannelContext);
/*****************************************************************************/
/* bcg729Encoder : */
......@@ -48,5 +54,5 @@ __attribute__ ((visibility ("default"))) void closeBcg729EncoderChannel(bcg729En
/* on 80 bits (5 16bits words) */
/* */
/*****************************************************************************/
__attribute__ ((visibility ("default"))) void bcg729Encoder(bcg729EncoderChannelContextStruct *encoderChannelContext, int16_t inputFrame[], uint8_t bitStream[]);
BCG729_VISIBILITY void bcg729Encoder(bcg729EncoderChannelContextStruct *encoderChannelContext, int16_t inputFrame[], uint8_t bitStream[]);
#endif /* ifndef ENCODER_H */
......@@ -59,7 +59,7 @@
/* - the log2(x) in Q16 on 32 bits */
/* */
/*****************************************************************************/
static inline word32_t g729Log2_Q0Q16(word32_t x)
static BCG729_INLINE word32_t g729Log2_Q0Q16(word32_t x)
{
/* first get the integer part and put it in the 16 MSB of return value (in Q16) */
uint16_t leadingZeros = countLeadingZeros(x); /* note: MSB is excluded as considered as sign bit */
......@@ -103,7 +103,7 @@ static inline word32_t g729Log2_Q0Q16(word32_t x)
/* - exp2(x) in Q16 on 32 bits */
/* */
/*****************************************************************************/
static inline word32_t g729Exp2_Q11Q16(word16_t x)
static BCG729_INLINE word32_t g729Exp2_Q11Q16(word16_t x)
{
int integer;
word16_t frac;
......@@ -134,11 +134,12 @@ static inline word32_t g729Exp2_Q11Q16(word16_t x)
/* - sqrt(x) in Q7 on 32 bits */
/* */
/*****************************************************************************/
static inline word32_t g729Sqrt_Q0Q7(word32_t x)
static BCG729_INLINE word32_t g729Sqrt_Q0Q7(word32_t x)
{
if (x==0) return 0;
int k;
word32_t rt;
if (x==0) return 0;
/* set x in Q14 in range [0.25,1[ */
k = (18-countLeadingZeros(x))>>1;
x = VSHR32(x, (k<<1)); /* x = x.2^-2k */
......@@ -159,7 +160,7 @@ static inline word32_t g729Sqrt_Q0Q7(word32_t x)
/* - 1/sqrt(x) in Q31 on 32 bits in range [43341/2^31, MAXINT32] */
/* */
/*****************************************************************************/
static inline word32_t g729InvSqrt_Q0Q31(word32_t x)
static BCG729_INLINE word32_t g729InvSqrt_Q0Q31(word32_t x)
{
if (x==1) return MAXINT32;
return (word32_t)(DIV32_32_Q24(g729Sqrt_Q0Q7(x),x)); /* sqrt(x) in Q7 + Q24 -> Q31 */
......@@ -185,7 +186,7 @@ static inline word32_t g729InvSqrt_Q0Q31(word32_t x)
/* - cos(x) in Q0.15 on 16 bits in range [-1, 1[ */
/* */
/*****************************************************************************/
static inline word16_t g729Cos_Q13Q15(word16_t x)
static BCG729_INLINE word16_t g729Cos_Q13Q15(word16_t x)
{
/* input var x in Q2.13 and in ]0, Pi[ */
word16_t x2,xScaled;
......@@ -231,22 +232,22 @@ static inline word16_t g729Cos_Q13Q15(word16_t x)
/* - atan(x) in Q2.13 on 16 bits in range ]-Pi/2(12868), Pi/2(12868)[ */
/* */
/*****************************************************************************/
static inline word16_t g729Atan_Q15Q13(word32_t x)
static BCG729_INLINE word16_t g729Atan_Q15Q13(word32_t x)
{
/* constants for rational polynomial */
word32_t angle;
word16_t x2;
int highSegment = 0;
int sign = 0;
int complement = 0;
/* make argument positive */
int sign = 0;
if (x < 0) {
x = NEG16(x);
sign = 1;
}
/* limit argument to 0..1 */
int complement = 0;
if(x > ONE_IN_Q15){
complement = 1;
x = DIV32(ONE_IN_Q30, x); /* 1/x in Q15 */
......@@ -295,7 +296,7 @@ static inline word16_t g729Atan_Q15Q13(word32_t x)
/* - asin(x) in Q2.13 on 16 bits in range ]-Pi/2(12868), Pi/2(12868)[ */
/* */
/*****************************************************************************/
static inline word16_t g729Asin_Q15Q13(word16_t x)
static BCG729_INLINE word16_t g729Asin_Q15Q13(word16_t x)
{
return g729Atan_Q15Q13(DIV32(SHL(x,15), PSHR(g729Sqrt_Q0Q7(SUB32(ONE_IN_Q30, MULT16_16(x,x))),7))); /* atan(x/sqrt(1.0 - x*x)) */
}
......@@ -308,7 +309,7 @@ static inline word16_t g729Asin_Q15Q13(word16_t x)
/* - acos(x) in Q2.13 on 16 bits in range ]0, Pi(25736)[ */
/* */
/*****************************************************************************/
static inline word16_t g729Acos_Q15Q13(word16_t x)
static BCG729_INLINE word16_t g729Acos_Q15Q13(word16_t x)
{
return(HALF_PI_Q13 - g729Asin_Q15Q13(x));
}
......
......@@ -21,6 +21,13 @@
#ifndef UTILS_H
#define UTILS_H
#ifdef _MSC_VER
#define BCG729_INLINE __inline
#else
#define BCG729_INLINE inline
#endif
/*****************************************************************************/
/* insertionSort : sort an array in growing order using insertion algorithm */
/* parameters : */
......@@ -87,10 +94,10 @@ void correlateVectors (word16_t x[], word16_t y[], word32_t c[]);
/* - number of heading zeros(MSB excluded. Ex: 0x0080 00000 returns 7) */
/* */
/*****************************************************************************/
static inline uint16_t countLeadingZeros(word32_t x)
static BCG729_INLINE uint16_t countLeadingZeros(word32_t x)
{
if (x==0) return 31;
uint16_t leadingZeros = 0;
if (x==0) return 31;
while (x<(word32_t)0x40000000) {
leadingZeros++;
x <<=1;
......
......@@ -94,21 +94,53 @@ static MSFilterMethod filter_methods[]={
};
#define MS_BCG729_DEC_ID MS_FILTER_PLUGIN_ID
#define MS_BCG729_DEC_NAME "MSBCG729Dec"
#define MS_BCG729_DEC_DESCRIPTION "G729 audio decoder filter"
#define MS_BCG729_DEC_CATEGORY MS_FILTER_DECODER
#define MS_BCG729_DEC_ENC_FMT "G729"
#define MS_BCG729_DEC_NINPUTS 1
#define MS_BCG729_DEC_NOUTPUTS 1
#define MS_BCG729_DEC_FLAGS MS_FILTER_IS_PUMP
#ifndef _MSC_VER
MSFilterDesc ms_bcg729_dec_desc={
.id=MS_FILTER_PLUGIN_ID, /* from Allfilters.h*/
.name="MSBCG729Dec",
.text="G729 decoder filter.",
.category=MS_FILTER_DECODER,
.enc_fmt="G729",
.ninputs=1, /*number of inputs*/
.noutputs=1, /*number of outputs*/
.id=MS_BCG729_DEC_ID,
.name=MS_BCG729_DEC_NAME,
.text=MS_BCG729_DEC_DESCRIPTION,
.category=MS_BCG729_DEC_CATEGORY,
.enc_fmt=MS_BCG729_DEC_ENC_FMT,
.ninputs=MS_BCG729_DEC_NINPUTS, /*number of inputs*/
.noutputs=MS_BCG729_DEC_NOUTPUTS, /*number of outputs*/
.init=filter_init,
.preprocess=filter_preprocess,
.process=filter_process,
.postprocess=filter_postprocess,
.uninit=filter_uninit,
.methods=filter_methods,
.flags=MS_FILTER_IS_PUMP
.flags=MS_BCG729_DEC_FLAGS
};
#else
MSFilterDesc ms_bcg729_dec_desc={
MS_BCG729_DEC_ID,
MS_BCG729_DEC_NAME,
MS_BCG729_DEC_DESCRIPTION,
MS_BCG729_DEC_CATEGORY,
MS_BCG729_DEC_ENC_FMT,
MS_BCG729_DEC_NINPUTS,
MS_BCG729_DEC_NOUTPUTS,
filter_init,
filter_preprocess,
filter_process,
filter_postprocess,
filter_uninit,
filter_methods,
MS_BCG729_DEC_FLAGS
};
#endif
MS_FILTER_DESC_EXPORT(ms_bcg729_dec_desc)
......@@ -32,8 +32,9 @@ struct bcg729Encoder_struct {
};
static void filter_init(MSFilter *f){
struct bcg729Encoder_struct* obj;
f->data = ms_new0(struct bcg729Encoder_struct,1);
struct bcg729Encoder_struct* obj= (struct bcg729Encoder_struct*) f->data;
obj = (struct bcg729Encoder_struct*) f->data;
obj->ptime=20;
obj->max_ptime=100;
}
......@@ -119,29 +120,70 @@ static MSFilterMethod filter_methods[]={
};
#define MS_BCG729_ENC_ID MS_FILTER_PLUGIN_ID
#define MS_BCG729_ENC_NAME "MSBCG729Enc"
#define MS_BCG729_ENC_DESCRIPTION "G729 audio encoder filter"
#define MS_BCG729_ENC_CATEGORY MS_FILTER_ENCODER
#define MS_BCG729_ENC_ENC_FMT "G729"
#define MS_BCG729_ENC_NINPUTS 1
#define MS_BCG729_ENC_NOUTPUTS 1
#define MS_BCG729_ENC_FLAGS 0
#ifndef _MSC_VER
MSFilterDesc ms_bcg729_enc_desc={
.id=MS_FILTER_PLUGIN_ID, /* from Allfilters.h*/
.name="MSBCG729Enc",
.text="G729 audio encoder filter.",
.category=MS_FILTER_ENCODER,
.enc_fmt="G729",
.ninputs=1, /*number of inputs*/
.noutputs=1, /*number of outputs*/
.id=MS_BCG729_ENC_ID,
.name=MS_BCG729_ENC_NAME,
.text=MS_BCG729_ENC_DESCRIPTION,
.category=MS_BCG729_ENC_CATEGORY,
.enc_fmt=MS_BCG729_ENC_ENC_FMT,
.ninputs=MS_BCG729_ENC_NINPUTS, /*number of inputs*/
.noutputs=MS_BCG729_ENC_NOUTPUTS, /*number of outputs*/
.init=filter_init,
.preprocess=filter_preprocess,
.process=filter_process,
.postprocess=filter_postprocess,
.uninit=filter_uninit,
.methods=filter_methods
.methods=filter_methods,
.flags=MS_BCG729_ENC_FLAGS
};
#else
MSFilterDesc ms_bcg729_enc_desc={
MS_BCG729_ENC_ID,
MS_BCG729_ENC_NAME,
MS_BCG729_ENC_DESCRIPTION,
MS_BCG729_ENC_CATEGORY,
MS_BCG729_ENC_ENC_FMT,
MS_BCG729_ENC_NINPUTS,
MS_BCG729_ENC_NOUTPUTS,
filter_init,
filter_preprocess,
filter_process,
filter_postprocess,
filter_uninit,
filter_methods,
MS_BCG729_ENC_FLAGS
};
#endif
MS_FILTER_DESC_EXPORT(ms_bcg729_enc_desc)
#ifdef _MSC_VER
#define MS_PLUGIN_DECLARE(type) __declspec(dllexport) type
#else
#define MS_PLUGIN_DECLARE(type) type
#endif
extern MSFilterDesc ms_bcg729_dec_desc;
#ifndef VERSION
#define VERSION "debug"
#endif
void libmsbcg729_init(){
MS_PLUGIN_DECLARE(void) libmsbcg729_init(void){
ms_filter_register(&ms_bcg729_enc_desc);
ms_filter_register(&ms_bcg729_dec_desc);
ms_message(" libmsbcg729 " VERSION " plugin loaded");
......
......@@ -42,10 +42,14 @@ static const word16_t cosW0pi[NB_COMPUTED_VALUES_CHEBYSHEV_POLYNOMIAL]; /* cos(w
int LP2LSPConversion(word16_t LPCoefficients[], word16_t LSPCoefficients[])
{
uint8_t i;
/*** Compute the polynomials coefficients according to spec 3.2.3 eq15 ***/
word32_t f1[6];
word32_t f2[6]; /* coefficients for polynomials F1 anf F2 in Q12 for computation, then converted in Q15 for the Chebyshev Polynomial function */
uint8_t numberOfRootFound = 0; /* used to check the final number of roots found and exit the loop on each polynomial computation when we have 10 roots */
word32_t *polynomialCoefficients;
word32_t previousCx;
word32_t Cx; /* value of Chebyshev Polynomial at current point in Q15 */
/*** Compute the polynomials coefficients according to spec 3.2.3 eq15 ***/
f1[0] = ONE_IN_Q12; /* values 0 are not part of the output, they are just used for computation purpose */
f2[0] = ONE_IN_Q12;
/* for (i = 0; i< 5; i++) { */
......@@ -64,10 +68,8 @@ int LP2LSPConversion(word16_t LPCoefficients[], word16_t LSPCoefficients[])
/*** Compute at each step(50 steps for the AnnexA version) the Chebyshev polynomial to find the 10 roots ***/
/* start using f1 polynomials coefficients and altern with f2 after founding each root (spec 3.2.3 eq13 and eq14) */
uint8_t numberOfRootFound = 0; /* used to check the final number of roots found and exit the loop on each polynomial computation when we have 10 roots */
word32_t *polynomialCoefficients = f1; /* start with f1 coefficients */
word32_t previousCx = ChebyshevPolynomial(cosW0pi[0], polynomialCoefficients); /* compute the first point and store it as the previous value for polynomial */
word32_t Cx; /* value of Chebyshev Polynomial at current point in Q15 */
polynomialCoefficients = f1; /* start with f1 coefficients */
previousCx = ChebyshevPolynomial(cosW0pi[0], polynomialCoefficients); /* compute the first point and store it as the previous value for polynomial */
for (i=1; i<NB_COMPUTED_VALUES_CHEBYSHEV_POLYNOMIAL; i++) {
Cx = ChebyshevPolynomial(cosW0pi[i], polynomialCoefficients);
......@@ -78,8 +80,9 @@ int LP2LSPConversion(word16_t LPCoefficients[], word16_t LSPCoefficients[])
word16_t xHigh = cosW0pi[i];
word16_t xMean;
for (j=0; j<2; j++) {
word32_t middleCx;
xMean = (word16_t)SHR(ADD32(xLow, xHigh), 1);
word32_t middleCx = ChebyshevPolynomial(xMean, polynomialCoefficients); /* compute the polynome for the value in the middle of current interval */
middleCx = ChebyshevPolynomial(xMean, polynomialCoefficients); /* compute the polynome for the value in the middle of current interval */
if ((previousCx^middleCx)&0x10000000) { /* check signe change by XOR on the value of first bit */
xHigh = xMean;
......
......@@ -53,16 +53,23 @@ void initLSPQuantization(bcg729EncoderChannelContextStruct *encoderChannelContex
void LSPQuantization(bcg729EncoderChannelContextStruct *encoderChannelContext, word16_t LSPCoefficients[], word16_t qLSPCoefficients[], uint16_t parameters[])
{
int i,j;
word16_t LSF[NB_LSP_COEFF]; /* LSF coefficients in Q2.13 range [0, Pi[ */
word16_t weights[NB_LSP_COEFF]; /* weights in Q11 */
word16_t weightsThreshold[NB_LSP_COEFF]; /* store in Q13 the threshold used to compute the weights */
int L0;
word32_t weightedMeanSquareError[L0_RANGE];
word16_t L1index[L0_RANGE];
word16_t L2index[L0_RANGE];
word16_t L3index[L0_RANGE];
word16_t quantizerOutput[NB_LSP_COEFF];
word16_t qLSF[NB_LSP_COEFF];
/*** compute LSF in Q2.13 : lsf = arcos(lsp) range [0, Pi[ spec 3.2.4 eq18 ***/
word16_t LSF[NB_LSP_COEFF]; /* LSF coefficients in Q2.13 range [0, Pi[ */
for (i=0; i<NB_LSP_COEFF; i++) {
LSF[i] = g729Acos_Q15Q13(LSPCoefficients[i]);
}
/*** compute the weights vector as in spec 3.2.4 eq22 ***/
word16_t weights[NB_LSP_COEFF]; /* weights in Q11 */
word16_t weightsThreshold[NB_LSP_COEFF]; /* store in Q13 the threshold used to compute the weights */
weightsThreshold[0] = SUB16(LSF[1], OO4PIPLUS1_IN_Q13);
for (i=1; i<NB_LSP_COEFF-1; i++) {
weightsThreshold[i] = SUB16(SUB16(LSF[i+1], LSF[i-1]), ONE_IN_Q13);
......@@ -81,16 +88,12 @@ void LSPQuantization(bcg729EncoderChannelContextStruct *encoderChannelContext, w
weights[5] = MULT16_16_Q14(weights[5], ONE_POINT_2_IN_Q14);
/*** compute the coefficients for the two MA Predictors ***/
int L0;
word32_t weightedMeanSquareError[L0_RANGE];
word16_t L1index[L0_RANGE];
word16_t L2index[L0_RANGE];
word16_t L3index[L0_RANGE];
for (L0=0; L0<L0_RANGE; L0++) {
/* compute the target Vector (l) to be quantized as in spec 3.2.4 eq23 */
word16_t targetVector[NB_LSP_COEFF]; /* vector to be quantized in Q13 */
word32_t meanSquareDiff = MAXINT32;
word16_t quantizedVector[NB_LSP_COEFF]; /* in Q13, the current state of quantized vector */
for (i=0; i<NB_LSP_COEFF; i++) {
word32_t acc = SHL(LSF[i],15); /* acc in Q2.28 */
for (j=0; j<MA_MAX_K; j++) {
......@@ -100,7 +103,6 @@ void LSPQuantization(bcg729EncoderChannelContextStruct *encoderChannelContext, w
}
/* find closest match for predictionError (minimize mean square diff) in L1 codebook */
word32_t meanSquareDiff = MAXINT32;
for (i=0; i<L1_RANGE; i++) {
word32_t acc = 0;
for (j=0; j<NB_LSP_COEFF; j++) {
......@@ -154,7 +156,6 @@ void LSPQuantization(bcg729EncoderChannelContextStruct *encoderChannelContext, w
/* compute the quantized vector L1+L2/L3 and rearrange it as specified in spec 3.2.4(first the higher part (L2) and then the lower part (L3)) */
/* Note: according to the spec, the rearrangement shall be done on each candidate while looking for best match, but the ITU code does it after picking the best match and so we do */
word16_t quantizedVector[NB_LSP_COEFF]; /* in Q13, the current state of quantized vector */
for (i=0; i<NB_LSP_COEFF/2; i++) {
quantizedVector[i] = ADD16(L1[L1index[L0]][i], L2L3[L2index[L0]][i]);
}
......@@ -206,8 +207,6 @@ void LSPQuantization(bcg729EncoderChannelContextStruct *encoderChannelContext, w
}
/*** Compute the quantized LSF from the L coefficients ***/
word16_t quantizerOutput[NB_LSP_COEFF];
word16_t qLSF[NB_LSP_COEFF];
/* reconstruct vector from the codebooks using the selected parameters spec 3.2.4 eq19 */
for (i=0; i<NB_LSP_COEFF/2; i++) {
quantizerOutput[i] = ADD16(L1[parameters[1]][i], L2L3[parameters[2]][i]); /* codebooks are in Q2.13 for L1 and Q0.13 for L2L3, due to actual values stored in the codebooks, result in Q2.13 */
......
......@@ -59,13 +59,13 @@ void adaptativeCodebookSearch(word16_t excitationVector[], int16_t *intPitchDela
int16_t *intPitchDelay, int16_t *fracPitchDelay, uint16_t *pitchDelayCodeword, uint16_t subFrameIndex)
{
int i,j;
word32_t backwardFilteredTargetSignal[L_SUBFRAME];
word32_t correlationMax = MININT32;
/* compute the backward Filtered Target Signal as specified in A.3.7: correlation of target signal and impulse response */
correlateVectors(targetSignal, impulseResponse, backwardFilteredTargetSignal); /* targetSignal in Q0, impulseResponse in Q12 -> backwardFilteredTargetSignal in Q12 */
/* maximise the sum as in spec A.3.7, eq A.7 */
word32_t correlationMax = MININT32;
for (i=*intPitchDelayMin; i<=*intPitchDelayMax; i++) {
word32_t correlation = 0;
for (j=0; j<L_SUBFRAME; j++) {
......@@ -87,6 +87,7 @@ void adaptativeCodebookSearch(word16_t excitationVector[], int16_t *intPitchDela
if (!(subFrameIndex==0 && *intPitchDelay>=85)) {
/* compute the fracPitchDelay*/
word16_t adaptativeCodebookVector[L_SUBFRAME]; /* as the adaptativeCodebookVector is computed in the excitation vector, use this buffer to backup the one giving the highest numerator */
word32_t correlation=0;
/* search the fractionnal part to get the best correlation */
/* we already have in excitationVector for fracPitchDelay = 0 the adaptativeCodebookVector (see specA.3.7) */
correlationMax = 0;
......@@ -98,7 +99,6 @@ void adaptativeCodebookSearch(word16_t excitationVector[], int16_t *intPitchDela
/* Fractionnal part = -1 */
generateAdaptativeCodebookVector(excitationVector, *intPitchDelay, -1);
word32_t correlation=0;
for (i=0; i<L_SUBFRAME; i++) {
correlation = MAC16_32_Q12(correlation, excitationVector[i], backwardFilteredTargetSignal[i]);
}
......@@ -167,6 +167,9 @@ void adaptativeCodebookSearch(word16_t excitationVector[], int16_t *intPitchDela
void generateAdaptativeCodebookVector(word16_t excitationVector[], int16_t intPitchDelay, int16_t fracPitchDelay)
{
int n,i,j;
word16_t *delayedExcitationVector;
word16_t *b30Increased;
word16_t *b30Decreased;
/* fracPitchDelay is in range [-1, 1], convert it to [0,2] needed by eqA.8 */
fracPitchDelay = -fracPitchDelay;
......@@ -176,9 +179,9 @@ void generateAdaptativeCodebookVector(word16_t excitationVector[], int16_t intPi
}
/**/
word16_t *delayedExcitationVector = &(excitationVector[-intPitchDelay]); /* delayedExcitationVector is used to address the excitation vector at index -intPitchDelay (-k in eq40) */
word16_t *b30Increased = &(b30[fracPitchDelay]); /* b30 increased points to b30[fracPitchDelay] : b30[t] in eq40. b30 in Q15 */
word16_t *b30Decreased = &(b30[3-fracPitchDelay]); /* b30 decreased points to b30[-fracPitchDelay] : b30[3-t] in eq40. b30 in Q15 */
delayedExcitationVector = &(excitationVector[-intPitchDelay]); /* delayedExcitationVector is used to address the excitation vector at index -intPitchDelay (-k in eq40) */
b30Increased = &(b30[fracPitchDelay]); /* b30 increased points to b30[fracPitchDelay] : b30[t] in eq40. b30 in Q15 */
b30Decreased = &(b30[3-fracPitchDelay]); /* b30 decreased points to b30[-fracPitchDelay] : b30[3-t] in eq40. b30 in Q15 */
for (n=0; n<L_SUBFRAME; n++) {
......
......@@ -41,6 +41,8 @@
word16_t computeAdaptativeCodebookGain(word16_t targetSignal[], word16_t filteredAdaptativeCodebookVector[], word64_t *gainQuantizationXy, word64_t *gainQuantizationYy)
{
int i;
word32_t gain;
*gainQuantizationXy = 0; /* contains the scalar product targetSignal, filteredAdaptativeCodebookVector : numerator */
*gainQuantizationYy = 0; /* contains the scalar product filteredAdaptativeCodebookVector^2 : denominator */
......@@ -56,7 +58,7 @@ word16_t computeAdaptativeCodebookGain(word16_t targetSignal[], word16_t filtere
}
/* output shall be in Q14 */
word32_t gain = DIV64(SHL64(*gainQuantizationXy,14),*gainQuantizationYy); /* gain in Q14 */
gain = DIV64(SHL64(*gainQuantizationXy,14),*gainQuantizationYy); /* gain in Q14 */
/* check if it is not above 1.2 */
if (gain>ONE_POINT_2_IN_Q14) {
......
......@@ -37,11 +37,18 @@
void computeLP(word16_t signal[], word16_t LPCoefficientsQ12[])
{
int i,j;
word16_t windowedSignal[L_LP_ANALYSIS_WINDOW];
word32_t autoCorrelationCoefficient[NB_LSP_COEFF+1];
word64_t acc64=0; /* acc on 64 bits */
int rightShiftToNormalise=0;
word32_t previousIterationLPCoefficients[NB_LSP_COEFF+1]; /* to compute a[]*/
word32_t LPCoefficients[NB_LSP_COEFF+1]; /* in Q4.27 */
word32_t sum = 0; /* in Q27 */
word32_t E = 0; /* in Q31 */
/*********************************************************************/
/* Compute the windowed signal according to spec 3.2.1 eq4 */
/*********************************************************************/
word16_t windowedSignal[L_LP_ANALYSIS_WINDOW];
for (i=0; i<L_LP_ANALYSIS_WINDOW; i++) {
windowedSignal[i] = MULT16_16_P15(signal[i], wlp[i]); /* signal in Q0, wlp in Q0.15, windowedSignal in Q0 */
}
......@@ -49,11 +56,9 @@ void computeLP(word16_t signal[], word16_t LPCoefficientsQ12[])
/*********************************************************************************/
/* Compute the autoCorrelation coefficients r[0..10] according to spec 3.2.1 eq5 */
/*********************************************************************************/
word32_t autoCorrelationCoefficient[NB_LSP_COEFF+1];
/* Compute autoCorrelationCoefficient[0] first as it is the highest number and normalise it on 32 bits then apply the same normalisation to the other coefficients */
/* autoCorrelationCoefficient are normalised on 32 bits and then considered as Q31 in range [-1,1[ */
/* autoCorrelationCoefficient[0] is computed on 64 bits as it is likely to overflow 32 bits */
word64_t acc64=0; /* acc on 64 bits */
for (i=0; i<L_LP_ANALYSIS_WINDOW; i++) {
acc64 = MAC64(acc64, windowedSignal[i], windowedSignal[i]);
}
......@@ -61,7 +66,6 @@ void computeLP(word16_t signal[], word16_t LPCoefficientsQ12[])
acc64 = 1; /* spec 3.2.1: To avoid arithmetic problems for low-level input signals the value of r(0) has a lower boundary of r(0) = 1.0 */
}
/* normalise the acc64 on 32 bits */
int rightShiftToNormalise=0;
if (acc64>MAXINT32) {
do {
acc64 = SHR(acc64,1);
......@@ -125,11 +129,6 @@ void computeLP(word16_t signal[], word16_t LPCoefficientsQ12[])
/* set to Q27 at the end of current iteration */
/* */
/*********************************************************************************/
word32_t previousIterationLPCoefficients[NB_LSP_COEFF+1]; /* to compute a[]*/
word32_t LPCoefficients[NB_LSP_COEFF+1]; /* in Q4.27 */
word32_t sum = 0; /* in Q27 */
word32_t E = 0; /* in Q31 */
/* init */
LPCoefficients[0] = ONE_IN_Q27;
LPCoefficients[1] = -DIV32_32_Q27(autoCorrelationCoefficient[1], autoCorrelationCoefficient[0]); /* result in Q27(but<1) */
......
......@@ -47,6 +47,8 @@ void computeWeightedSpeech(word16_t inputSignal[], word16_t qLPCoefficients[], w
/* finally get the weightedInputSignal[n] = LPResidualSignal[n] - ∑(i=1..10)qLP'[i]*weightedInputSignal[n-i] spec A3.3.3 eqA.2 */
int i,j;
word16_t weightedqLPLowPassCoefficients[NB_LSP_COEFF]; /* in Q12 */
/*** compute LPResisualSignal (spec A3.3.3 eqA.3) in Q0 ***/
/* compute residual signal for the first subframe: use the first 10 qLPCoefficients */
for (i=0; i<L_SUBFRAME; i++) {
......@@ -67,7 +69,6 @@ void computeWeightedSpeech(word16_t inputSignal[], word16_t qLPCoefficients[], w
/*** compute weightedqLPLowPassCoefficients and weightedInputSignal for first subframe ***/
/* spec A3.3.3 a' = weightedqLPLowPassCoefficients[i] = weightedqLP[i] - 0.7*weightedqLP[i-1] */
word16_t weightedqLPLowPassCoefficients[NB_LSP_COEFF]; /* in Q12 */
weightedqLPLowPassCoefficients[0] = SUB16(weightedqLPCoefficients[0],O7_IN_Q12); /* weightedqLP[-1] = 1 -> weightedqLPLowPassCoefficients[0] = weightedqLPCoefficients[0] - 0.7 */
for (i=1; i<NB_LSP_COEFF; i++) {
weightedqLPLowPassCoefficients[i] = SUB16(weightedqLPCoefficients[i], MULT16_16_Q12(weightedqLPCoefficients[i-1], O7_IN_Q12));
......
......@@ -55,6 +55,9 @@ void decodeAdaptativeCodeVector(bcg729DecoderChannelContextStruct *decoderChanne
int16_t *intPitchDelay, word16_t *excitationVector)
{
int16_t fracPitchDelay;
word16_t *excitationVectorMinusK; /* pointer to u(-k) */
int n;
/*** Compute the Pitch Delay from the Codebook index ***/
/* fracPitchDelay is computed in the range -1,0,1 */
if (subFrameIndex == 0 ) { /* first subframe */
......@@ -114,8 +117,6 @@ void decodeAdaptativeCodeVector(bcg729DecoderChannelContextStruct *decoderChanne
/* v the adaptative codebook vector */
/* b30 an interpolation filter */
word16_t *excitationVectorMinusK; /* pointer to u(-k) */
/* scale fracPichDelay from -1,0.1 to 0,1,2 */
if (fracPitchDelay==1) {
excitationVectorMinusK = &(excitationVector[-(*intPitchDelay+1)]); /* fracPitchDelay being positive -> increase by one the integer part and set to 2 the fractional part : -(k+1/3) -> -(k+1)+2/3 */
......@@ -125,7 +126,6 @@ void decodeAdaptativeCodeVector(bcg729DecoderChannelContextStruct *decoderChanne
excitationVectorMinusK = &(excitationVector[-(*intPitchDelay)]); /* -(k-1/3) -> -k+1/3 or -(k) -> -k*/
}
int n;
for (n=0; n<L_SUBFRAME; n++) { /* loop over the whole subframe */
word16_t *excitationVectorNMinusK = &(excitationVectorMinusK[n]); /* point to u(n-k), unscaled value, full range */
word16_t *excitationVectorNMinusKPlusOne = &(excitationVectorMinusK[n+1]); /* point to u(n-k+1), unscaled value, full range */
......
......@@ -38,6 +38,7 @@ void decodeFixedCodeVector(uint16_t signs, uint16_t positions, int16_t intPitchD
{
uint16_t positionsArray[4];
uint16_t jx;
int i;
/* get the positions into an array: mapping according to eq62 and table7 in spec 3.8 */
positionsArray[0] = (positions&(uint16_t)7)*5; /* m0 = 5*C, do not use macro here as whatever fixed or floating point computation we use, these are integers */
......@@ -51,7 +52,6 @@ void decodeFixedCodeVector(uint16_t signs, uint16_t positions, int16_t intPitchD
positionsArray[3] = ((positions&(uint16_t)7)*5) + 3 + jx; /* m3 = 5*C + 3 + jx, do not use macro here as whatever fixed or floating point computation we use, these are integers */
/* initialise the output Vector */
int i;
for (i=0; i<L_SUBFRAME; i++) {
fixedCodebookVector[i]=0;
}
......
......@@ -55,8 +55,14 @@ void initDecodeGains(bcg729DecoderChannelContextStruct *decoderChannelContext)
void decodeGains (bcg729DecoderChannelContextStruct *decoderChannelContext, uint16_t GA, uint16_t GB, word16_t *fixedCodebookVector, uint8_t frameErasureFlag,
word16_t *adaptativeCodebookGain, word16_t *fixedCodebookGain)
{
word32_t predictedFixedCodebookGain;
word16_t fixedCodebookGainCorrectionFactor;
/* check the erasure flag */
if (frameErasureFlag != 0) { /* we have a frame erasure, proceed as described in spec 4.4.2 */
int i;
word32_t currentGainPredictionError =0;
/* adaptativeCodebookGain as in eq94 */
if (*adaptativeCodebookGain < 16384) { /* last subframe gain < 1 in Q14 */
*adaptativeCodebookGain = MULT16_16_Q15(*adaptativeCodebookGain, 29491 ); /* *0.9 in Q15 */
......@@ -67,8 +73,6 @@ void decodeGains (bcg729DecoderChannelContextStruct *decoderChannelContext, uint
*fixedCodebookGain = MULT16_16_Q15(*fixedCodebookGain, 32113 ); /* *0.98 in Q15 */
/* And update the previousGainPredictionError according to spec 4.4.3 */
int i;
word32_t currentGainPredictionError =0;
for (i=0; i<4; i++) {
currentGainPredictionError = ADD32(currentGainPredictionError, decoderChannelContext->previousGainPredictionError[i]); /* previousGainPredictionError in Q3.10-> Sum in Q5.10 (on 32 bits) */
}
......@@ -98,10 +102,10 @@ void decodeGains (bcg729DecoderChannelContextStruct *decoderChannelContext, uint
*adaptativeCodebookGain = ADD16(GACodebook[GA][0], GBCodebook[GB][0]); /* result in Q1.14 */
/* Fixed Codebook: MA code-gain prediction */
word32_t predictedFixedCodebookGain = MACodeGainPrediction(decoderChannelContext->previousGainPredictionError, fixedCodebookVector); /* predictedFixedCodebookGain on 32 bits in Q11.16 */
predictedFixedCodebookGain = MACodeGainPrediction(decoderChannelContext->previousGainPredictionError, fixedCodebookVector); /* predictedFixedCodebookGain on 32 bits in Q11.16 */
/* get fixed codebook gain correction factor(gama) from the codebooks GA and GB according to eq74 */
word16_t fixedCodebookGainCorrectionFactor = ADD16(GACodebook[GA][1], GBCodebook[GB][1]); /* result in Q3.12 (range [0.185, 5.05])*/
fixedCodebookGainCorrectionFactor = ADD16(GACodebook[GA][1], GBCodebook[GB][1]); /* result in Q3.12 (range [0.185, 5.05])*/
/* compute fixedCodebookGain according to eq74 */
*fixedCodebookGain = (word16_t)PSHR(MULT16_32_Q12(fixedCodebookGainCorrectionFactor, predictedFixedCodebookGain), 15); /* Q11.16*Q3.12 -> Q14.16, shift by 15 to get a Q14.1 which fits on 16 bits */
......
......@@ -65,6 +65,8 @@ void decodeLSP(bcg729DecoderChannelContextStruct *decoderChannelContext, uint16_
if (frameErased == 0) { /* frame is ok, proceed according to 3.2.4 section of the doc */
word32_t acc; /* Accumulator in Q2.28 */
/*** doc 3.2.4 eq(19) ***/
/* get the L codewords from the codebooks L1, L2 and L3 */
/* for easier implementation, L2 and L3 5 dimensional codebooks have been stored in one 10 dimensional L2L3 codebook */
......@@ -90,7 +92,6 @@ void decodeLSP(bcg729DecoderChannelContextStruct *decoderChannelContext, uint16_
/* currentqLSF and previousLCodeWord in Q2.13 */
/* MAPredictor and MAPredictorSum in Q0.15 with MAPredictorSum[MA switch][i]+Sum[j=0-3](MAPredictor[MA switch][j][i])=1 -> acc will end up being in Q2.28*/
/* Note : previousLCodeWord array containing the last 4 code words is updated during this phase */
word32_t acc; /* Accumulator in Q2.28 */
for (i=0; i<NB_LSP_COEFF; i++) {
acc = MULT16_16(MAPredictorSum[L[0]][i], currentqLSF[i]);
......@@ -134,12 +135,13 @@ void decodeLSP(bcg729DecoderChannelContextStruct *decoderChannelContext, uint16_
} else { /* frame erased indicator is set, proceed according to section 4.4 of the specs */
word32_t acc; /* acc in Q2.28 */
/* restore the qLSF of last valid frame */
for (i=0; i<NB_LSP_COEFF; i++) {
currentqLSF[i] = decoderChannelContext->lastqLSF[i];
}
word32_t acc; /* acc in Q2.28 */
/* compute back the codewords from the qLSF and store them in the previousLCodeWord buffer */
for (i=0; i<NB_LSP_COEFF; i++) { /* currentqLSF and previousLCodeWord in Q2.13, MAPredictor in Q0.15 and invMAPredictorSum in Q3.12 */
acc = SHL(decoderChannelContext->lastqLSF[i],15); /* Q2.13 -> Q2.28 */
......
......@@ -99,6 +99,19 @@ void bcg729Decoder(bcg729DecoderChannelContextStruct *decoderChannelContext, uin
int i;
uint16_t parameters[NB_PARAMETERS];
/* internal buffers which we do not need to keep between calls */
word16_t qLSP[NB_LSP_COEFF]; /* store the qLSP coefficients in Q0.15 */
word16_t interpolatedqLSP[NB_LSP_COEFF]; /* store the interpolated qLSP coefficient in Q0.15 */
word16_t LP[2*NB_LSP_COEFF]; /* store the 2 sets of LP coefficients in Q12 */
int16_t intPitchDelay; /* store the Pitch Delay in and out of decodeAdaptativeCodeVector, in for decodeFixedCodeVector */
word16_t fixedCodebookVector[L_SUBFRAME]; /* the fixed Codebook Vector in Q1.13*/
word16_t postFilteredSignal[L_SUBFRAME]; /* store the postfiltered signal in Q0 */
uint8_t parityErrorFlag;
int subframeIndex;
int parametersIndex = 4; /* this is used to select the right parameter according to the subframe currently computed, start pointing to P1 */
int LPCoefficientsIndex = 0; /* this is used to select the right LP Coefficients according to the subframe currently computed */
/*** parse the bitstream and get all parameter into an array as in spec 4 - Table 8 ***/
/* parameters buffer mapping : */
/* 0 -> L0 (1 bit) */
......@@ -124,14 +137,6 @@ void bcg729Decoder(bcg729DecoderChannelContextStruct *decoderChannelContext, uin
}
}
/* internal buffers which we do not need to keep between calls */