Browse Source

Fix overflow in encoder

+ do not left shift a negative int(undefined behaviour in C standard)
+ update test patterns
keep-around/176be6f49d4b5e342919d44a0989db7094af3642
Johan Pascal 5 years ago
parent
commit
5c19a144dc
16 changed files with 61 additions and 52 deletions
  1. +5
    -5
      src/LP2LSPConversion.c
  2. +1
    -1
      src/LPSynthesisFilter.c
  3. +8
    -8
      src/LSPQuantization.c
  4. +1
    -1
      src/cng.c
  5. +4
    -4
      src/computeLP.c
  6. +2
    -2
      src/computeWeightedSpeech.c
  7. +0
    -2
      src/decoder.c
  8. +5
    -5
      src/fixedCodebookSearch.c
  9. +12
    -2
      src/fixedPointMacros.h
  10. +3
    -3
      src/g729FixedPointMath.h
  11. +5
    -5
      src/gainQuantization.c
  12. +2
    -2
      src/postFilter.c
  13. +2
    -2
      src/qLSP2LP.c
  14. +2
    -0
      src/typedef.h
  15. +1
    -1
      src/utils.c
  16. +8
    -9
      test/testCampaignAll.cmake

+ 5
- 5
src/LP2LSPConversion.c View File

@ -60,8 +60,8 @@ int LP2LSPConversion(word16_t LPCoefficients[], word16_t LSPCoefficients[])
}
/* convert the coefficients from Q12 to Q15 to be used by the Chebyshev Polynomial function (f1/2[0] aren't used so they are not converted) */
for (i=1; i<6; i++) {
f1[i] = SHL(f1[i], 3);
f2[i] = SHL(f2[i], 3);
f1[i] = SSHL(f1[i], 3);
f2[i] = SSHL(f2[i], 3);
}
/*** Compute at each step(50 steps for the AnnexA version) the Chebyshev polynomial to find the 10 roots ***/
@ -100,7 +100,7 @@ int LP2LSPConversion(word16_t LPCoefficients[], word16_t LSPCoefficients[])
/* linear interpolation for better root accuracy */
/* xMean = xLow - (xHigh-xLow)* previousCx/(Cx-previousCx); */
xMean = (word16_t)SUB32(xLow, MULT16_32_Q15(SUB32(xHigh, xLow), DIV32(SHL(previousCx, 14), SHR(SUB32(Cx, previousCx), 1)))); /* Cx are in Q2.15 so we can shift them left 14 bits, the denominator is shifted righ by 1 so the division result is in Q15 */
xMean = (word16_t)SUB32(xLow, MULT16_32_Q15(SUB32(xHigh, xLow), DIV32(SSHL(SATURATE(previousCx, MAXINT17), 14), SHR(SUB32(Cx, previousCx), 1)))); /* Cx are in Q2.15 so we can shift them left 14 bits, the denominator is shifted righ by 1 so the division result is in Q15 */
/* recompute previousCx with the new coefficients */
previousCx = ChebyshevPolynomial(xMean, polynomialCoefficients);
@ -132,11 +132,11 @@ word32_t ChebyshevPolynomial(word16_t x, word32_t f[])
{
/* bk in Q15*/
word32_t bk;
word32_t bk1 = ADD32(SHL(x,1), f[1]); /* init: b4=2x+f1 */
word32_t bk1 = ADD32(SSHL(x,1), f[1]); /* init: b4=2x+f1 */
word32_t bk2 = ONE_IN_Q15; /* init: b5=1 */
uint8_t k;
for (k=3; k>0; k--) { /* at the end of loop execution we have b1 in bk1 and b2 in bk2 */
bk = SUB32(ADD32(SHL(MULT16_32_Q15(x,bk1), 1), f[5-k]), bk2); /* bk = 2*x*bk1 − bk2 + f(5-k) all in Q15*/
bk = SUB32(ADD32(SSHL(MULT16_32_Q15(x,bk1), 1), f[5-k]), bk2); /* bk = 2*x*bk1 − bk2 + f(5-k) all in Q15*/
bk2 = bk1;
bk1 = bk;
}


+ 1
- 1
src/LPSynthesisFilter.c View File

@ -36,7 +36,7 @@ void LPSynthesisFilter (word16_t *excitationVector, word16_t *LPCoefficients, wo
int i;
/* compute excitationVector[i] - Sum0-9(LPCoefficients[j]*reconstructedSpeech[i-j]) */
for (i=0; i<L_SUBFRAME; i++) {
word32_t acc = SHL(excitationVector[i],12); /* acc get the first term of the sum, in Q12 (excitationVector is in Q0)*/
word32_t acc = SSHL(excitationVector[i],12); /* acc get the first term of the sum, in Q12 (excitationVector is in Q0)*/
int j;
for (j=0; j<NB_LSP_COEFF; j++) {
acc = MSU16_16(acc, LPCoefficients[j], reconstructedSpeech[i-j-1]);


+ 8
- 8
src/LSPQuantization.c View File

@ -52,11 +52,11 @@ void noiseLSPQuantization(word16_t previousqLSF[MA_MAX_K][NB_LSP_COEFF], word16_
int i,j;
int L0;
word16_t LSF[NB_LSP_COEFF]; /* LSF coefficients in Q2.13 range [0, Pi[ */
word16_t weights[NB_LSP_COEFF]; /* weights in Q11 */
uword16_t weights[NB_LSP_COEFF]; /* weights in Q11 */
word16_t weightsThreshold[NB_LSP_COEFF]; /* store in Q13 the threshold used to compute the weights */
word16_t L1index[L0_RANGE];
word16_t L2index[L0_RANGE];
word32_t weightedMeanSquareError[L0_RANGE];
uword32_t weightedMeanSquareError[L0_RANGE];
word16_t quantizerOutput[NB_LSP_COEFF];
word16_t qLSF[NB_LSP_COEFF];
@ -169,8 +169,8 @@ void noiseLSPQuantization(word16_t previousqLSF[MA_MAX_K][NB_LSP_COEFF], word16_
/* compute the weighted mean square distance using the final quantized vector according to eq21 */
weightedMeanSquareError[L0]=0;
for (i=0; i<NB_LSP_COEFF; i++) {
word16_t difftargetVectorQuantizedVector = SATURATE(MULT16_16_Q15(SUB32(targetVector[i], quantizedVector[i]), noiseMAPredictorSum[L0][i]), MAXINT16); /* targetVector and quantizedVector in Q13 -> result in Q13 */
weightedMeanSquareError[L0] = MAC16_16(weightedMeanSquareError[L0], difftargetVectorQuantizedVector, MULT16_16_Q11(difftargetVectorQuantizedVector, weights[i])); /* weights in Q11, diff in Q13 */
uword16_t difftargetVectorQuantizedVector = USATURATE(ABS(MULT16_16_Q15(SUB32(targetVector[i], quantizedVector[i]), noiseMAPredictorSum[L0][i])), MAXUINT16); /* targetVector and quantizedVector in Q13 -> result in Q13 */
weightedMeanSquareError[L0] = UMAC16_16(weightedMeanSquareError[L0], difftargetVectorQuantizedVector, MULT16_16_Q11(difftargetVectorQuantizedVector, weights[i])); /* weights in Q11, diff in Q13 */
}
@ -257,10 +257,10 @@ void LSPQuantization(bcg729EncoderChannelContextStruct *encoderChannelContext, w
{
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 */
uword16_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];
uword32_t weightedMeanSquareError[L0_RANGE];
word16_t L1index[L0_RANGE];
word16_t L2index[L0_RANGE];
word16_t L3index[L0_RANGE];
@ -391,8 +391,8 @@ void LSPQuantization(bcg729EncoderChannelContextStruct *encoderChannelContext, w
/* compute the weighted mean square distance using the final quantized vector according to eq21 */
weightedMeanSquareError[L0]=0;
for (i=0; i<NB_LSP_COEFF; i++) {
word16_t difftargetVectorQuantizedVector = SATURATE(MULT16_16_Q15(SUB32(targetVector[i], quantizedVector[i]), MAPredictorSum[L0][i]), MAXINT16); /* targetVector and quantizedVector in Q13 -> result in Q13 */
weightedMeanSquareError[L0] = MAC16_16(weightedMeanSquareError[L0], difftargetVectorQuantizedVector, MULT16_16_Q11(difftargetVectorQuantizedVector, weights[i])); /* weights in Q11, diff in Q13 */
uword16_t difftargetVectorQuantizedVector = USATURATE(ABS(MULT16_16_Q15(SUB32(targetVector[i], quantizedVector[i]), MAPredictorSum[L0][i])), MAXUINT16); /* targetVector and quantizedVector in Q13 -> result in Q13 */
weightedMeanSquareError[L0] = UMAC16_16(weightedMeanSquareError[L0], difftargetVectorQuantizedVector, MULT16_16_Q11(difftargetVectorQuantizedVector, weights[i])); /* weights in Q11, diff in Q13 */
}
}


+ 1
- 1
src/cng.c View File

@ -199,7 +199,7 @@ void computeComfortNoiseExcitationVector(word16_t targetGain, uint16_t *randomGe
delta = g729Sqrt_Q0Q7((word32_t)delta); /* delta in Q(7-deltaScaleFactor/2)*/
/* scale b (Ei) to the same scale */
Ei = VSHR32(Ei, deltaScaleFactor/2-7);
Ei = SVSHR32(Ei, deltaScaleFactor/2-7);
/* compute the two roots and pick the one with smaller absolute value */
/* roots are (-b +-sqrt(delta))/a. We always have a=4, divide by four when rescaling from Q(7-deltaScaleFactor) to Q0 the final result */


+ 4
- 4
src/computeLP.c View File

@ -71,7 +71,7 @@ void autoCorrelation2LP(word32_t autoCorrelationCoefficients[], word16_t LPCoeff
/* init */
LPCoefficients[0] = ONE_IN_Q27;
LPCoefficients[1] = -DIV32_32_Q27(autoCorrelationCoefficients[1], autoCorrelationCoefficients[0]); /* result in Q27(but<1) */
reflectionCoefficients[0] = SHL(LPCoefficients[1],4); /* k[0] is -r1/r0 in Q31 */
reflectionCoefficients[0] = SSHL(LPCoefficients[1],4); /* k[0] is -r1/r0 in Q31 */
/* E = r0(1 - a[1]^2) in Q31 */
E = MULT32_32_Q31(autoCorrelationCoefficients[0], SUB32(ONE_IN_Q31, MULT32_32_Q23(LPCoefficients[1], LPCoefficients[1]))); /* LPCoefficient[1] is in Q27, using a Q23 operation will result in a Q31 variable */
@ -86,7 +86,7 @@ void autoCorrelation2LP(word32_t autoCorrelationCoefficients[], word16_t LPCoeff
for (j=1; j<i; j++) {
sum = MAC32_32_Q31(sum, LPCoefficients[j], autoCorrelationCoefficients[i-j]);/* LPCoefficients in Q27, autoCorrelation in Q31 -> result in Q27 -> sum in Q27 */
}
sum = ADD32(SHL(sum, 4), autoCorrelationCoefficients[i]); /* set sum in Q31 and add r[0] */
sum = ADD32(SSHL(sum, 4), autoCorrelationCoefficients[i]); /* set sum in Q31 and add r[0] */
/* a[i] = -sum/E */
LPCoefficients[i] = -DIV32_32_Q31(sum,E); /* LPCoefficient of current iteration is in Q31 for now, it will be set to Q27 at the end of this iteration */
@ -165,7 +165,7 @@ void computeLP(word16_t signal[], word16_t LPCoefficientsQ12[], word32_t reflect
autoCorrelationCoefficients[0] = acc64;
} else {
rightShiftToNormalise = -countLeadingZeros((word32_t)acc64);
autoCorrelationCoefficients[0] = SHL((word32_t)acc64, -rightShiftToNormalise);
autoCorrelationCoefficients[0] = SSHL((word32_t)acc64, -rightShiftToNormalise);
}
/* give current autoCorrelation coefficients scale to the output */
@ -190,7 +190,7 @@ void computeLP(word16_t signal[], word16_t LPCoefficientsQ12[], word32_t reflect
acc32 = MAC16_16(acc32, windowedSignal[j], windowedSignal[j-i]);
}
/* normalise it */
autoCorrelationCoefficients[i] = SHL(acc32, -rightShiftToNormalise);
autoCorrelationCoefficients[i] = SSHL(acc32, -rightShiftToNormalise);
}
}


+ 2
- 2
src/computeWeightedSpeech.c View File

@ -50,7 +50,7 @@ void computeWeightedSpeech(word16_t inputSignal[], word16_t qLPCoefficients[], w
/*** 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++) {
word32_t acc = SHL((word32_t)inputSignal[i], 12); /* inputSignal in Q0 is shifted to set acc in Q12 */
word32_t acc = SSHL((word32_t)inputSignal[i], 12); /* inputSignal in Q0 is shifted to set acc in Q12 */
for (j=0; j<NB_LSP_COEFF; j++) {
acc = MAC16_16(acc, qLPCoefficients[j],inputSignal[i-j-1]); /* qLPCoefficients in Q12, inputSignal in Q0 -> acc in Q12 */
}
@ -58,7 +58,7 @@ void computeWeightedSpeech(word16_t inputSignal[], word16_t qLPCoefficients[], w
}
/* compute residual signal for the second subframe: use the second part of qLPCoefficients */
for (i=L_SUBFRAME; i<L_FRAME; i++) {
word32_t acc = SHL((word32_t)inputSignal[i], 12); /* inputSignal in Q0 is shifted to set acc in Q12 */
word32_t acc = SSHL((word32_t)inputSignal[i], 12); /* inputSignal in Q0 is shifted to set acc in Q12 */
for (j=0; j<NB_LSP_COEFF; j++) {
acc = MAC16_16(acc, qLPCoefficients[NB_LSP_COEFF+j],inputSignal[i-j-1]); /* qLPCoefficients in Q12, inputSignal in Q0 -> acc in Q12 */
}


+ 0
- 2
src/decoder.c View File

@ -36,8 +36,6 @@
#include "postProcessing.h"
#include "cng.h"
#include "stdio.h"
/* buffers allocation */
static const word16_t previousqLSPInitialValues[NB_LSP_COEFF] = {30000, 26000, 21000, 15000, 8000, 0, -8000,-15000,-21000,-26000}; /* in Q0.15 the initials values for the previous qLSP buffer */


+ 5
- 5
src/fixedCodebookSearch.c View File

@ -60,7 +60,7 @@ void fixedCodebookSearch(word16_t targetSignal[], word16_t impulseResponse[], in
int correlationSignalSign[L_SUBFRAME]; /* to store the sign of each correlationSignal element */
/* build the matrix Ф' : impulseResponse correlation matrix spec 3.8.1 eq51, eq56 and eq57 */
/* correlationSignal turns to absolute values and sign of elements is stored in correlationSignalSign */
word32_t Phi[L_SUBFRAME][L_SUBFRAME];
word32_t Phi[L_SUBFRAME][L_SUBFRAME] = {0};
int m3Base;
int i0=0, i1=0, i2=0, i3=0;
word32_t correlationSquareMax = -1;
@ -207,10 +207,10 @@ void fixedCodebookSearch(word16_t targetSignal[], word16_t impulseResponse[], in
}
/* set the four pulses, in Q13 */
fixedCodebookVector[i0] = SHL((word16_t)correlationSignalSign[i0], 13);
fixedCodebookVector[i1] = SHL((word16_t)correlationSignalSign[i1], 13);
fixedCodebookVector[i2] = SHL((word16_t)correlationSignalSign[i2], 13);
fixedCodebookVector[i3] = SHL((word16_t)correlationSignalSign[i3], 13);
fixedCodebookVector[i0] = SSHL((word16_t)correlationSignalSign[i0], 13);
fixedCodebookVector[i1] = SSHL((word16_t)correlationSignalSign[i1], 13);
fixedCodebookVector[i2] = SSHL((word16_t)correlationSignalSign[i2], 13);
fixedCodebookVector[i3] = SSHL((word16_t)correlationSignalSign[i3], 13);
/* adapt it according to eq48 */
for (i=intPitchDelay; i<L_SUBFRAME; i++) {


+ 12
- 2
src/fixedPointMacros.h View File

@ -22,25 +22,33 @@
#define EXTEND32(x) ((word32_t)(x))
#define NEG16(x) (-(x))
#define NEG32(x) (-(x))
#define NEG64(x) (-(x))
/*** shifts ***/
#define SHR(a,shift) ((a) >> (shift))
#define SHL(a,shift) ((word32_t)(a) << (shift))
/* Signed shift left, C standard claims shifting left a negative value lead to undetermined status,
* recent compiler shall not have any problem, but just in case, shift a positive value and back */
#define SSHL(a,shift) ((a < 0)?(NEG32((word32_t)(NEG32(a)) << (shift))):((word32_t)(a) << (shift)))
#define USHL(a,shift) ((uword32_t)(a) << (shift))
/* shift right with rounding: used to extract the integer value of a Qa number */
#define PSHR(a,shift) (SHR((a)+((EXTEND32(1)<<((shift))>>1)),shift))
/* shift right with checking on sign of shift value */
#define VSHR32(a, shift) (((shift)>0) ? SHR32(a, shift) : SHL32(a, -(shift)))
#define SVSHR32(a, shift) (((shift)>0) ? SHR32((word32_t)(a), shift) : SSHL((word32_t)(a), -(shift)))
#define SHR16(a,shift) ((a) >> (shift))
#define SHL16(a,shift) ((a) << (shift))
#define SHR32(a,shift) ((a) >> (shift))
#define SHL32(a,shift) ((a) << (shift))
#define SHR64(a,shift) ((a) >> (shift))
#define SHL64(a,shift) ((a) << (shift))
#define SSHL64(a,shift) ((a < 0)?(NEG64((word64_t)(NEG64(a)) << (shift))):((word64_t)(a) << (shift)))
/* avoid overflows: a+1 is used to check on negative value because range of a 2n signed bits int is -2pow(n) - 2pow(n)-1 */
/* SATURATE Macro shall be called with MAXINT(nbits). Ex: SATURATE(x,MAXINT16) with MAXINT16 defined to 2pow(16) - 1 */
#define SATURATE(x,a) (((x)>(a) ? (a) : (x)<-(a+1) ? -(a+1) : (x)))
/* same but for unsigned values only */
#define USATURATE(x,a) ((x)>(a) ? (a) : (x))
/* absolute value */
#define ABS(a) (((a)>0) ? (a) : -(a))
@ -49,6 +57,7 @@
#define ADD16(a,b) ((word16_t)((word16_t)(a)+(word16_t)(b)))
#define SUB16(a,b) ((word16_t)(a)-(word16_t)(b))
#define ADD32(a,b) ((word32_t)(a)+(word32_t)(b))
#define UADD32(a,b) ((uword32_t)(a)+(uword32_t)(b))
#define SUB32(a,b) ((word32_t)(a)-(word32_t)(b))
/*** Multiplications/Accumulations ***/
@ -58,6 +67,7 @@
#define MULT16_32(a,b) ((word32_t)((word16_t)(a))*((word32_t)(b)))
#define UMULT16_16(a,b) ((uword32_t)((word32_t)(a))*((word32_t)(b)))
#define MAC16_16(c,a,b) (ADD32((c),MULT16_16((a),(b))))
#define UMAC16_16(c,a,b) (UADD32((c),UMULT16_16((a),(b))))
#define MSU16_16(c,a,b) (SUB32((c),MULT16_16((a),(b))))
#define DIV32(a,b) (((word32_t)(a))/((word32_t)(b)))
#define UDIV32(a,b) (((uword32_t)(a))/((uword32_t)(b)))
@ -117,8 +127,8 @@
/* Divisions: input numbers with similar scale(Q) output according to operation. Warning: Make use of 64 bits variables */
#define DIV32_32_Q24(a,b) (((word64_t)(a)<<24)/((word32_t)(b)))
#define DIV32_32_Q27(a,b) (((word64_t)(a)<<27)/((word32_t)(b)))
#define DIV32_32_Q31(a,b) (((word64_t)(a)<<31)/((word32_t)(b)))
#define DIV32_32_Q27(a,b) ((SSHL64((word64_t)(a),27))/((word32_t)(b)))
#define DIV32_32_Q31(a,b) ((SSHL64((word64_t)(a),31))/((word32_t)(b)))
#define MULT32_32_Q23(a,b) ((word32_t)(SHR64(((word64_t)a*(word64_t)b),23)))


+ 3
- 3
src/g729FixedPointMath.h View File

@ -139,7 +139,7 @@ static BCG729_INLINE word32_t g729Sqrt_Q0Q7(uword32_t x)
if (x==0) return 0;
/* set x in Q14 in range [0.25,1[ */
k = (19-unsignedCountLeadingZeros(x))>>1;
x = VSHR32(x, (k<<1)); /* x = x.2^-2k */
x = VSHR32(x, k*2); /* x = x.2^-2k */
/* sqrt(x) ~= 0.22178 + 1.29227*x - 0.77070*x^2 + 0.25659*x^3 (for .25 < x < 1) */
/* consider x as in Q14: y = x.2^(-2k-14) -> and give sqrt(y).2^14 = sqrt(x).2^(-k-7).2^14 */
@ -254,7 +254,7 @@ static BCG729_INLINE word16_t g729Atan_Q15Q13(word32_t x)
if(x > KtanPI12){
highSegment = 1;
/* x = (x - k)/(1 + k*x); */
x = DIV32(SHL(SUB32(x, KtanPI6), 15), ADD32(MULT16_16_Q15(KtanPI6, x), ONE_IN_Q15));
x = DIV32(SSHL(SUB32(x, KtanPI6), 15), ADD32(MULT16_16_Q15(KtanPI6, x), ONE_IN_Q15));
}
/* argument is now < tan(15 degrees) */
@ -295,7 +295,7 @@ static BCG729_INLINE word16_t g729Atan_Q15Q13(word32_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)) */
return g729Atan_Q15Q13(DIV32(SSHL(x,15), PSHR(g729Sqrt_Q0Q7(SUB32(ONE_IN_Q30, MULT16_16(x,x))),7))); /* atan(x/sqrt(1.0 - x*x)) */
}
/*****************************************************************************/


+ 5
- 5
src/gainQuantization.c View File

@ -142,7 +142,7 @@ void gainQuantization(bcg729EncoderChannelContextStruct *encoderChannelContext,
numeratorH = (numeratorH>0)?numeratorH:-numeratorH;
numeratorNorm = countLeadingZeros(numeratorH);
if (numeratorNorm >= 9) {
bestAdaptativeCodebookGain = (word32_t)(DIV64(SHL64(numerator,9), denominator)); /* bestAdaptativeCodebookGain in Q9 */
bestAdaptativeCodebookGain = (word32_t)(DIV64(SSHL64(numerator,9), denominator)); /* bestAdaptativeCodebookGain in Q9 */
} else {
word64_t shiftedDenominator = SHR64(denominator, 9-numeratorNorm);
if (shiftedDenominator>0) { /* can't shift left by 9 the numerator, can we shift right by 9-numeratorNorm the denominator without hiting 0 */
@ -159,7 +159,7 @@ void gainQuantization(bcg729EncoderChannelContextStruct *encoderChannelContext,
numeratorNorm = countLeadingZeros(numeratorH);
if (numeratorNorm >= 14) {
bestFixedCodebookGain = (word32_t)(DIV64(SHL64(numerator,14), denominator));
bestFixedCodebookGain = (word32_t)(DIV64(SSHL64(numerator,14), denominator));
} else {
word64_t shiftedDenominator = SHR64(denominator, 14-numeratorNorm); /* bestFixedCodebookGain in Q14 */
if (shiftedDenominator>0) { /* can't shift left by 9 the numerator, can we shift right by 9-numeratorNorm the denominator without hiting 0 */
@ -190,9 +190,9 @@ void gainQuantization(bcg729EncoderChannelContextStruct *encoderChannelContext,
if (indexBaseGb>0) indexBaseGb--;
/*** test all possibilities of Ga and Gb indexes and select the best one ***/
xy = -SHL(xy,1); /* xy term is always used with a -2 factor */
xz = -SHL(xz,1); /* xz term is always used with a -2 factor */
yz = SHL(yz,1); /* yz term is always used with a 2 factor */
xy = -SSHL(xy,1); /* xy term is always used with a -2 factor */
xz = -SSHL(xz,1); /* xz term is always used with a -2 factor */
yz = SSHL(yz,1); /* yz term is always used with a 2 factor */
for (i=0; i<4; i++) {
for (j=0; j<8; j++) {


+ 2
- 2
src/postFilter.c View File

@ -100,7 +100,7 @@ void postFilter(bcg729DecoderChannelContextStruct *decoderChannelContext, word16
scaledResidualSignal = &(decoderChannelContext->scaledResidualSignalBuffer[MAXIMUM_INT_PITCH_DELAY+subframeIndex]);
for (i=0; i<L_SUBFRAME; i++) {
word32_t acc = SHL((word32_t)reconstructedSpeech[i], 12); /* reconstructedSpeech in Q0 shifted to set acc in Q12 */
word32_t acc = SSHL((word32_t)reconstructedSpeech[i], 12); /* reconstructedSpeech in Q0 shifted to set acc in Q12 */
for (j=0; j<NB_LSP_COEFF; j++) {
acc = MAC16_16(acc, LPGammaNCoefficients[j],reconstructedSpeech[i-j-1]); /* LPGammaNCoefficients in Q12, reconstructedSpeech in Q0 -> acc in Q12 */
}
@ -219,7 +219,7 @@ void postFilter(bcg729DecoderChannelContextStruct *decoderChannelContext, word16
hf[0] = 4096; /* 1 in Q12 as LPGammaNCoefficients and LPGammaDCoefficient doesn't contain the first element which is 1 and past values of hf are 0 */
for (i=1; i<11; i++) {
word32_t acc = (word32_t)SHL(LPGammaNCoefficients[i-1],12); /* LPGammaNCoefficients in Q12 -> acc in Q24 */
word32_t acc = (word32_t)SSHL(LPGammaNCoefficients[i-1],12); /* LPGammaNCoefficients in Q12 -> acc in Q24 */
for (j=0; j<NB_LSP_COEFF && j<i; j++) { /* j<i to avoid access to negative index of hf(past values are 0 anyway) */
acc = MSU16_16(acc, LPGammaDCoefficients[j], hf[i-j-1]); /* LPGammaDCoefficient in Q12, hf in Q12 -> Q24 TODO: Possible overflow?? */
}


+ 2
- 2
src/qLSP2LP.c View File

@ -82,13 +82,13 @@ void computePolynomialCoefficients(word16_t qLSP[], word32_t f[])
/* Note : index of qLSP are -1 respect of what is in the spec because qLSP array is indexed from 0-9 and not 1-10 */
for (i=2; i<6; i++) {
/* spec: f[i] = 2(f[i-2] - qLSP[2i-1]*f[i-1]) */
f[i] = SHL(SUB32(f[i-2], MULT16_32_P15(qLSP[2*i-2], f[i-1])),1); /* with qLSP in Q0.15 and f in Q24 */
f[i] = SSHL(SUB32(f[i-2], MULT16_32_P15(qLSP[2*i-2], f[i-1])),1); /* with qLSP in Q0.15 and f in Q24 */
for (j=i-1; j>1; j--) { /* case of j=1 is just doing f[1] -= 2*qLSP[2i-1], done after the loop in order to avoid reference to f[-1] */
/* spec: f[j] = f[j] -2*qLSP[2i-i]*f[j-1] + f[j-2] (all right terms refer to the value at the previous iteration on i indexed loop) */
f[j] = ADD32(f[j], SUB32(f[j-2], MULT16_32_P14(qLSP[2*i-2], f[j-1]))); /* qLPS in Q0.15 and f in Q24, using MULT16_32_P14 instead of P15 does the *2 on qLSP. Result in Q24 */
}
/* f[1] -= 2*qLSP[2i-1] */
f[1] = SUB32(f[1], SHL(qLSP[2*i-2],10)); /* qLSP in Q0.15, must be shift by 9 to get in Q24 and one more to be *2 */
f[1] = SUB32(f[1], SSHL(qLSP[2*i-2],10)); /* qLSP in Q0.15, must be shift by 9 to get in Q24 and one more to be *2 */
}
return;
}

+ 2
- 0
src/typedef.h View File

@ -178,6 +178,8 @@ struct bcg729EncoderChannelContextStruct_struct {
/* MAXINTXX define the maximum signed integer value on XX bits(2^(XX-1) - 1) */
/* used to check on overflows in fixed point mode */
#define MAXINT16 0x7fff
#define MAXUINT16 0xffff
#define MAXINT17 0xffff
#define MAXINT28 0x7ffffff
#define MAXINT29 0xfffffff
#define MININT32 0x80000000


+ 1
- 1
src/utils.c View File

@ -131,7 +131,7 @@ void synthesisFilter(word16_t inputSignal[], word16_t filterCoefficients[], word
{
int i;
for (i=0; i<L_SUBFRAME; i++) {
word32_t acc = SHL(inputSignal[i],12); /* acc get the first term of the sum, in Q12 (inputSignal is in Q0)*/
word32_t acc = SSHL(inputSignal[i],12); /* acc get the first term of the sum, in Q12 (inputSignal is in Q0)*/
int j;
for (j=0; j<NB_LSP_COEFF; j++) {
acc = MSU16_16(acc, filterCoefficients[j], filteredSignal[i-j-1]); /* filterCoefficients in Q12 and signal in Q0 -> acc in Q12 */


+ 8
- 9
test/testCampaignAll.cmake View File

@ -6,24 +6,23 @@
if [ ! -d "patterns" ]; then
rm -f ./bcg729-patterns.zip
# no pattern directory: download it from
# http://www.belledonne-communications.com/downloads/bcg729-patterns.zip
wget http://www.belledonne-communications.com/bc-downloads/bcg729-patterns.zip
if [ -e bcg729-patterns.zip ]; then
wget http://linphone.org/bc-downloads/bcg729-patterns-v1.1.0.zip
if [ -e bcg729-patterns-v1.1.0.zip ]; then
# check file
if [[ `openssl md5 bcg729-patterns.zip | grep -c ee5702e17cff8484d1396e6f23f84305` -ne 0 ]]; then
if [[ `openssl md5 bcg729-patterns-v1.1.0.zip | grep -c f223c39eb471350124e56978760858f7` -ne 0 ]]; then
# file ok, unzip it
unzip bcg729-patterns.zip
unzip bcg729-patterns-v1.1.0.zip
if [[ $? -ne 0 ]]; then
echo "Error: unable to unzip correctly bcg729-patterns.zip, try to do it manually"
echo "Error: unable to unzip correctly bcg729-patterns-v1.1.0.zip, try to do it manually"
else
rm bcg729-patterns.zip
rm bcg729-patterns-v1.1.0.zip
fi
else
echo "Error: bad checksum on bcg729-patterns.zip downloaded from http://www.belledonne-communications.com/bc-downloads/.\nTry again"
echo "Error: bad checksum on bcg729-patterns-v1.1.0.zip downloaded from http://linphone.org/bc-downloads/.\nTry again"
exit 1
fi
else
echo "Error: Unable to download bcg729-patterns.zip pattern archive from http://www.belledonne-communications.com/bc-downloads/"
echo "Error: Unable to download bcg729-patterns-v1.1.0.zip pattern archive from http://linphone.org/bc-downloads/"
exit 1
fi
fi


Loading…
Cancel
Save