/*** Compute the polynomials coefficients according to spec 3.2.3 eq15 ***/
word32_tf1[6];
word32_tf2[6];/* coefficients for polynomials F1 anf F2 in Q12 for computation, then converted in Q15 for the Chebyshev Polynomial function */
uint8_tnumberOfRootFound=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_tpreviousCx;
word32_tCx;/* 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_tnumberOfRootFound=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_tpreviousCx=ChebyshevPolynomial(cosW0pi[0],polynomialCoefficients);/* compute the first point and store it as the previous value for polynomial */
word32_tCx;/* 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 */
/*** compute the coefficients for the two MA Predictors ***/
intL0;
word32_tweightedMeanSquareError[L0_RANGE];
word16_tL1index[L0_RANGE];
word16_tL2index[L0_RANGE];
word16_tL3index[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_ttargetVector[NB_LSP_COEFF];/* vector to be quantized in Q13 */
word32_tmeanSquareDiff=MAXINT32;
word16_tquantizedVector[NB_LSP_COEFF];/* in Q13, the current state of quantized vector */
for(i=0;i<NB_LSP_COEFF;i++){
word32_tacc=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_tmeanSquareDiff=MAXINT32;
for(i=0;i<L1_RANGE;i++){
word32_tacc=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_tquantizedVector[NB_LSP_COEFF];/* in Q13, the current state of quantized vector */
@ -206,8 +207,6 @@ void LSPQuantization(bcg729EncoderChannelContextStruct *encoderChannelContext, w
}
/*** Compute the quantized LSF from the L coefficients ***/
word16_tquantizerOutput[NB_LSP_COEFF];
word16_tqLSF[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 */
/* 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 */
word16_tadaptativeCodebookVector[L_SUBFRAME];/* as the adaptativeCodebookVector is computed in the excitation vector, use this buffer to backup the one giving the highest numerator */
word32_tcorrelation=0;
/* search the fractionnal part to get the best correlation */
/* we already have in excitationVector for fracPitchDelay = 0 the adaptativeCodebookVector (see specA.3.7) */
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 */
/* 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 */
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 */
/* 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 */
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 */
*fixedCodebookGain=MULT16_16_Q15(*fixedCodebookGain,32113);/* *0.98 in Q15 */
/* And update the previousGainPredictionError according to spec 4.4.3 */
inti;
word32_tcurrentGainPredictionError=0;
for(i=0;i<4;i++){
currentGainPredictionError=ADD32(currentGainPredictionError,decoderChannelContext->previousGainPredictionError[i]);/* previousGainPredictionError in Q3.10-> Sum in Q5.10 (on 32 bits) */
*adaptativeCodebookGain=ADD16(GACodebook[GA][0],GBCodebook[GB][0]);/* result in Q1.14 */
/* Fixed Codebook: MA code-gain prediction */
word32_tpredictedFixedCodebookGain=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_tfixedCodebookGainCorrectionFactor=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 */
/* 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 */
@ -162,14 +169,14 @@ void bcg729Encoder(bcg729EncoderChannelContextStruct *encoderChannelContext, int
computeWeightedSpeech(encoderChannelContext->signalCurrentFrame,qLPCoefficients,weightedqLPCoefficients,&(encoderChannelContext->weightedInputSignal[MAXIMUM_INT_PITCH_DELAY]),&(encoderChannelContext->excitationVector[L_PAST_EXCITATION]));/* weightedInputSignal contains MAXIMUM_INT_PITCH_DELAY values from previous frame, points to current frame */
/*** Compute the impulse response : filter a subframe long buffer filled with unit and only zero through the 1/weightedqLPCoefficients as in spec A.3.5 ***/
word16_timpulseResponseBuffer[NB_LSP_COEFF+L_SUBFRAME];/* impulseResponseBuffer in Q12, need NB_LSP_COEFF as past value to go through filtering function */
word16_tfilteredAdaptativeCodebookVector[NB_LSP_COEFF+L_SUBFRAME];/* in Q0, the first NB_LSP_COEFF words are set to zero and used by filter only */
word64_tgainQuantizationXy,gainQuantizationYy;/* used to store in Q0 values reused in gain quantization */
word16_tfixedCodebookVector[L_SUBFRAME];/* in Q13 */
word16_tconvolvedFixedCodebookVector[L_SUBFRAME];/* in Q12 */
word16_tquantizedAdaptativeCodebookGain;/* in Q14 */
word16_tquantizedFixedCodebookGain;/* in Q1 */
memset(impulseResponseBuffer,0,(NB_LSP_COEFF)*sizeof(word16_t));/* set the past values to zero */
@ -197,7 +209,6 @@ void bcg729Encoder(bcg729EncoderChannelContextStruct *encoderChannelContext, int
/*** Adaptative Codebook search : compute the intPitchDelay, fracPitchDelay and associated parameter, compute also the adaptative codebook vector used to generate the excitation ***/
/* after this call, the excitationVector[L_PAST_EXCITATION + subFrameIndex] contains the adaptative codebook vector as in spec 3.7.1 */
word64_tgainQuantizationXy,gainQuantizationYy;/* used to store in Q0 values reused in gain quantization */
word16_tadaptativeCodebookGain=computeAdaptativeCodebookGain(&(encoderChannelContext->targetSignal[NB_LSP_COEFF]),&(filteredAdaptativeCodebookVector[NB_LSP_COEFF]),&gainQuantizationXy,&gainQuantizationYy);/* gain in Q14 */
adaptativeCodebookGain=computeAdaptativeCodebookGain(&(encoderChannelContext->targetSignal[NB_LSP_COEFF]),&(filteredAdaptativeCodebookVector[NB_LSP_COEFF]),&gainQuantizationXy,&gainQuantizationYy);/* gain in Q14 */
/* increase parameters index and compute P0 if needed */
parametersIndex++;
@ -222,15 +230,11 @@ void bcg729Encoder(bcg729EncoderChannelContextStruct *encoderChannelContext, int
}
/*** Fixed Codebook Search : compute the parameters for fixed codebook and the regular and convolved version of the fixed codebook vector ***/
word16_tfixedCodebookVector[L_SUBFRAME];/* in Q13 */
word16_tconvolvedFixedCodebookVector[L_SUBFRAME];/* in Q12 */
word16_tscaledWeightedInputSignalBuffer[MAXIMUM_INT_PITCH_DELAY+L_FRAME];/* this buffer might store the scaled version of input Signal, if scaling is not needed, it is not used */
word16_t*scaledWeightedInputSignal;/* points to the begining of present frame either scaled or directly the input signal */
intoverflowScale=PSHR(31-countLeadingZeros((word32_t)(autocorrelation>>31)),1);/* count number of bits needed over the 31 bits allowed and divide by 2 to get the right scaling for the signal */
overflowScale=PSHR(31-countLeadingZeros((word32_t)(autocorrelation>>31)),1);/* count number of bits needed over the 31 bits allowed and divide by 2 to get the right scaling for the signal */
/* according to ITU code comments, the normalisedCorrelationMax values fit on 16 bits when in Q0, so keep them in Q8 on 32 bits shall not give any overflow */
/* compute the target signal for fixed codebook spec 3.8.1 eq50 : fixedCodebookTargetSignal[i] = targetSignal[i] - (adaptativeCodebookGain * filteredAdaptativeCodebookVector[i]) */
word16_tfixedCodebookTargetSignal[L_SUBFRAME];
word32_tcorrelationSignal32[L_SUBFRAME];/* on 32 bits in Q12 */
word16_tcorrelationSignal[L_SUBFRAME];/* normalised to fit on 13 bits */
word32_tcorrelationSignalMax=0;
word32_tabscCrrelationSignal32;
uint16_tcorrelationSignalMaxNorm;
intcorrelationSignalSign[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_tPhi[L_SUBFRAME][L_SUBFRAME];
intm3Base;
inti0=0,i1=0,i2=0,i3=0;
word32_tcorrelationSquareMax=-1;
word32_tenergyMax=1;
intm0=0,m1=0,m2=0,m3=0;
intmSwitch[2][4]={{2,3,0,1},{3,0,1,2}};
intmIndex;
intjx=0;
/* compute the target signal for fixed codebook spec 3.8.1 eq50 : fixedCodebookTargetSignal[i] = targetSignal[i] - (adaptativeCodebookGain * filteredAdaptativeCodebookVector[i]) */
for(i=0;i<L_SUBFRAME;i++){
fixedCodebookTargetSignal[i]=MSU16_16_Q14(targetSignal[i],filteredAdaptativeCodebookVector[i],adaptativeCodebookGain);/* adaptativeCodebookGain in Q14, other values in Q0 */
}
@ -65,22 +83,19 @@ void fixedCodebookSearch(word16_t targetSignal[], word16_t impulseResponse[], in
}
/* compute the correlation signal as in spec 3.8.1 eq52 */
word32_tcorrelationSignal32[L_SUBFRAME];/* on 32 bits in Q12 */
word16_tcorrelationSignal[L_SUBFRAME];/* normalised to fit on 13 bits */
/* first compute the diagonal Phi(x,x) : Phi(39,39) = h[0]^2 # Phi(38,38) = Phi(39,39)+h[1]^2 */
/* this diagonal must be divided by 2 according to spec 3.8.1 eq57 */
word32_tacc=0;
for(i=0,iComp=L_SUBFRAME-1;i<L_SUBFRAME;i++,iComp--){/* i in [0..39], iComp in [39..0] */
acc=MAC16_16(acc,impulseResponse[i],impulseResponse[i]);/* impulseResponse in Q12 -> acc in Q24 */
Phi[iComp][iComp]=SHR(acc,1);/* divide by 2: eq57*/
}
/* check for possible overflow: Phi will be summed 10 times, so max Phi (by construction Phi[0][0]*2 is the max of Phi-> 2*Phi[0][0]*10 must be < 0x7fff ffff -> Phi[0][0]< 0x06666666 - otherwise scale Phi)*/
uint16_tPhiScaling=0;
if(Phi[0][0]>0x6666666){
PhiScaling=3-countLeadingZeros((Phi[0][0]<<1)+0x3333333);/* complement 0xccccccc adding 0x3333333 to shift by one when max(2*Phi[0][0]) is in 0x0fffffff < max < 0xcccccc */
/*** Compute the predicted gain as in spec 3.9.1 eq71 in Q6 ***/
word16_tpredictedFixedCodebookGain=(word16_t)(SHR32(MACodeGainPrediction(encoderChannelContext->previousGainPredictionError,fixedCodebookVector),12));/* in Q16 -> Q4 range [3,1830] */
predictedFixedCodebookGain=(word16_t)(SHR32(MACodeGainPrediction(encoderChannelContext->previousGainPredictionError,fixedCodebookVector),12));/* in Q16 -> Q4 range [3,1830] */
/*** preselection spec 3.9.2 ***/
/* Note: spec just says to select the best 50% of each vector, ITU code go through magical constant computation to select the begining of a continuous range */
/* much more simple here : vector are ordened in growing order so just select 2 (4 for Gb) indexes before the first value to be superior to the best gain previously computed */
uint16_tindexBaseGa=0;
uint16_tindexBaseGb=0;
while(indexBaseGa<6&&bestFixedCodebookGain>(MULT16_16_Q14(GACodebook[indexBaseGa][1],predictedFixedCodebookGain))){/* bestFixedCodebookGain> in Q2, GACodebook in Q12 *predictedFixedCodebookGain in Q4 -> Q16-14 */
/*** Compute the signal energy ∑r(n)*r(n) and delayed signal energy ∑rk(n)*rk(n) which shall be used to compute gl spec 4.2.1 eq81, eq 82 and eq83 ***/
word32_tresidualSignalEnergy=0;/* in Q-4 */
word32_tdelayedResidualSignalEnergy=0;/* in Q-4 */
delayedResidualSignal=&(scaledResidualSignal[-bestIntPitchDelay]);/* in Q-2, points to the residual signal delayed to give the higher correlation: rk(n) */
rh1=MULT16_32_Q15(GAMMA_T,rh1);/* GAMMA_T in Q15, rh1 in Q24*/
word16_ttiltCompensationGain=(word16_t)SATURATE((word32_t)(DIV32(rh1,PSHR(rh0,12))),MAXINT16);/* rh1 in Q24, PSHR(rh0,12) in Q12 -> tiltCompensationGain in Q12 */
tiltCompensationGain=(word16_t)SATURATE((word32_t)(DIV32(rh1,PSHR(rh0,12))),MAXINT16);/* rh1 in Q24, PSHR(rh0,12) in Q12 -> tiltCompensationGain in Q12 */
/* compute the sum of squares of fixedCodebookVector in Q26 */
inti;
word32_tfixedCodebookVectorSquaresSum=0;
word32_tacc;
for(i=0;i<L_SUBFRAME;i++){
if(fixedCodebookVector[i]!=0){/* as most of the codebook vector is egal to 0, it worth checking it to avoid useless multiplications */
/* fixedCodebookVector in Q1.13 and final sum in range [4, 8.48] (4 values filled with abs values: 1,1,1.8 and 1.8 in the vector give max value of sum) */