staticconstword16_tSIDqLSPInitialValues[NB_LSP_COEFF]={31441,27566,21458,13612,4663,-4663,-13612,-21458,-27566,-31441};/* in Q0.15 the initials values for the previous qLSP buffer */
/* Use L1 and L2(parameter for first and second stage vector of LSF quantizer) to retrieve LSP using subset index to address the complete L1 and L2L3 codebook */
/* received parameter is -(10*log10(meanE) -90) so retrieve mean energy : 10^((param+90)/10) */
/* but expected parameter is a gain applied to single sample so sqrt of previous result */
receivedSIDGainLog=ADD32(-bitStream[0],90);
if(receivedSIDGainLog>66){
receivedSIDGainLog=66;/* noise level shall not be too high in any case */
}/* receivedSIDGainLog is param+90 in Q0 */
receivedSIDGainLog=MULT16_16(receivedSIDGainLog,680);/* 680 is 1/(10*log10(2)) in Q11 -> receivedSIDGainLog is ((param+90)/10)/log10(2) = log2(meanE) in Q11 */
receivedSIDGainLog=g729Exp2_Q11Q16(receivedSIDGainLog);/* receivedSIDGainLog in meanE in Q16 */
if(receivedSIDGainLog>0){/* avoid arithmetic problem if energy is too low */
CNGChannelContext->receivedSIDGain=(word16_t)(SHR(g729Sqrt_Q0Q7(receivedSIDGainLog),12));/* output of sqrt in Q15, result needed in Q3 */
CNGChannelContext->qLSP[i]=g729Cos_Q13Q15(currentqLSF[i]);/* ouput in Q0.15 */
LPCoefficients[i]=-SHL(k[i-1],16);/* current coeff in Q31 while older one in Q27*/
for(j=1;j<i;j++){
LPCoefficients[j]=MAC32_32_Q31(LPCoefficients[j],LPCoefficients[i],previousIterationLPCoefficients[i-j]);/*LPCoefficients in Q27 except for LPCoefficients[i] in Q31 */
}
LPCoefficients[i]=SHR(LPCoefficients[i],4);
}
/* convert with rounding the LP Coefficients form Q27 to Q12, ignore first coefficient which is always 1 */
/* Use L1 and L2(parameter for first and second stage vector of LSF quantizer) to retrieve LSP using subset index to address the complete L1 and L2L3 codebook */
CNGChannelContext->qLSP[i]=g729Cos_Q13Q15(currentqLSF[i]);/* ouput in Q0.15 */
}
}
}/* Note: Itu implementation have information to sort missing and untransmitted packets and perform reconstruction of missed SID packet when it detects it, we cannot differentiate lost vs untransmitted packet so we don't do it */
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 */
/* 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 */
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 */
if(i==2){/* parameter k[1] from eq8 in 3.2.2 needed by VAD */
*reflectionCoefficient=LPCoefficients[i];
}
reflectionCoefficients[i-1]=LPCoefficients[i];/* k[1] is needed by VAD others by RFC3389 RTP payload for Comfort Noise spectral information encoding */
//acc=SUB32(g729Log2_Q0Q16(residualEnergy),ADD32(676458,(int32_t)(residualEnergyScale<<16)));/* -676458 is log2(aw/(NCur*80)) acc is log2(E') in Q16 aw=0.125*/
//acc=SUB32(g729Log2_Q0Q16(residualEnergy),ADD32(610922,(int32_t)(residualEnergyScale<<16)));/* -676458 is log2(aw/(NCur*80)) acc is log2(E') in Q16 aw=0.25*/
acc=SUB32(g729Log2_Q0Q16(residualEnergy),ADD32(479849,(int32_t)(residualEnergyScale<<16)));/* -479849 is log2(aw/(NCur*80)) acc is log2(E') in Q16 aw = 1 */
acc=SUB32(g729Log2_Q0Q16(residualEnergy),ADD32(479849,(int32_t)(residualEnergyScale<<16)));/* -479849 is log2(aw/(NCur*80)) acc is log2(E') in Q16 aw = 1 as we use unlagged autocorrelation coefficients */
acc=SHR32(acc,1);/* acc = log2(E') in Q15 */
acc=MULT16_32_Q15(INV_LOG2_10_Q15,acc);/* acc log10(E') in Q15 */
autoCorrelation2LP(summedAutocorrelationCoefficients,LPCoefficients,&reflectionCoefficient,&residualEnergy);/* output residualEnergy with the same scale of input summedAutocorrelationCoefficients */
autoCorrelation2LP(summedAutocorrelationCoefficients,LPCoefficients,reflectionCoefficients,&residualEnergy);/* output residualEnergy with the same scale of input summedAutocorrelationCoefficients */
/* determine type of frame SID or untrasmitted */
if(DTXChannelContext->previousVADflag==1){/* if previous frame was active : we must generate a SID frame spec B.10 */
/* compute past average LP filter coefficients Ap in B4.2.2 */
autoCorrelation2LP(SIDLPCAutocorrelationCoefficients,pastAverageLPCoefficients,&pastAverageReflectionCoefficient,&pastAverageResidualEnergy);/* output residualEnergy with the same scale of input summedAutocorrelationCoefficients */
autoCorrelation2LP(SIDLPCAutocorrelationCoefficients,pastAverageLPCoefficients,pastAverageReflectionCoefficients,&pastAverageResidualEnergy);/* output residualEnergy with the same scale of input summedAutocorrelationCoefficients */
/* select coefficients according to eq B.17 we have Ap in SIDLPCoefficients and At in LPCoefficients, store result, in Q12 in SIDLPCoefficients */
/* check distance beetwen currently used filter and past filter : compute LPCoefficentAutocorrelation for the past average filter */
DTXChannelContext->decodedLogEnergy=decodedLogEnergy;/* store frame mean energy for RFC3389 payload generation */
if(compareLPCFilters(DTXChannelContext->SIDLPCoefficientAutocorrelation,summedAutocorrelationCoefficients,residualEnergy,THRESHOLD3_IN_Q20)==0){/* use the past average filter */
/* generate LSP coefficient using the past LP coefficients */
@ -137,7 +137,7 @@ void bcg729Encoder(bcg729EncoderChannelContextStruct *encoderChannelContext, int
word16_timpulseResponseInput[L_SUBFRAME];/* input buffer for the impulse response computation: in Q12, 1 followed by all zeros see spec A3.5*/
/* used for VAD */
word32_treflectionCoefficient=0;/* in Q31, computed during LP generation */
word32_treflectionCoefficients[NB_LSP_COEFF];/* in Q31, computed during LP generation, reflectionCoefficients[1] is requested by VAD, the others are stored in context if we cover RFC3389 payload generation */
word32_tautoCorrelationCoefficients[NB_LSP_COEFF+3];/* if VAD is enabled we must compute 13 coefficients, 11 otherwise but used only internally by computeLP function in that case */
word32_tnoLagAutoCorrelationCoefficients[NB_LSP_COEFF+3];/* DTX must have access to autocorrelation Coefficients on which lag windowing as not been applied */
int8_tautoCorrelationCoefficientsScale;/* autocorrelation coefficients are normalised by computeLP, must get their scaling factor */
@ -148,7 +148,7 @@ void bcg729Encoder(bcg729EncoderChannelContextStruct *encoderChannelContext, int
/* use the whole signal Buffer for windowing and autocorrelation */
/* autoCorrelation Coefficients are computed and used internally, in case of VAD we must compute and retrieve 13 coefficients, compute only 11 when VAD is disabled */
/* call encodeSIDFrame even if it is a voice frame as it will update DTXContext with current VADflag */
/* call encodeSIDFrame even if it is a voice frame as it will update DTXContext with current VADflag : TODO : move updateDTXContext in the encodeSIDFrame as part of the update is performed in it anyway */
/* decodedLogEnergy is the frame mean energy, range [-12,66[, RFC3389 ask for DBov value, max mean energy would be 10log10(2^15*2^15) -> 90 so -90 to switch to DBov */
/* use last reflection coefficients stored in DTX context and convert them as specified in RFC3389 : Ni = (ki in Q15)/258 + 127 */
for(i=0;i<NB_LSP_COEFF;i++){
payload[i+1]=(uint8_t)ADD16((word16_t)SHR(MULT16_32_Q15(127/* 1/258 in Q15 */,-encoderChannelContext->DTXChannelContext->reflectionCoefficients[i]),16),127);/* ki in Q31 * (1/258 in Q15) -> result in Q31, shift right by 16 -> Q15 */
/* increase LOOP_N to increase input length and perform a more accurate profiling or perf measurement */
#define LOOP_N 1
intj;
for(j=0;j<LOOP_N;j++){
/* perf measurement */
/*** loop over input file ***/
while(fscanf(fpInput,"%hd,%hd,%hd,%hd,%hd,%hd,%hd,%hd,%hd,%hd,%hd,%hd,%hd,%hd,%hd,%hd,%hd",&(inputBuffer[0]),&(inputBuffer[1]),&(inputBuffer[2]),&(inputBuffer[3]),&(inputBuffer[4]),&(inputBuffer[5]),&(inputBuffer[6]),&(inputBuffer[7]),&(inputBuffer[8]),&(inputBuffer[9]),&(inputBuffer[10]),&(inputBuffer[11]),&(inputBuffer[12]),&(inputBuffer[13]),&(inputBuffer[14]),&(inputBuffer[15]),&(inputBuffer[16]))==17)/* index 4 and 5 are inverted to get P0 in 4 and P1 in 5 in the array */
{/* input buffer contains the parameters and in [15] the frame erasure flag */
inti;
uint8_tbitStreamLength;
framesNbr++;
if(inputBuffer[16]==1){/* active frame */
parametersArray2BitStream(inputBuffer,bitStream);
bitStreamLength=10;
}else{/* SID frame */
if(inputBuffer[16]==0){/* non transmitted frame */
@ -98,21 +98,25 @@ int main(int argc, char *argv[] )
while(fscanf(fpInput,"%hd,%hd,%hd,%hd,%hd,%hd,%hd,%hd,%hd,%hd,%hd,%hd,%hd,%hd,%hd,%hd,%hd",&(inputBuffer[0]),&(inputBuffer[1]),&(inputBuffer[2]),&(inputBuffer[3]),&(inputBuffer[4]),&(inputBuffer[5]),&(inputBuffer[6]),&(inputBuffer[7]),&(inputBuffer[8]),&(inputBuffer[9]),&(inputBuffer[10]),&(inputBuffer[11]),&(inputBuffer[12]),&(inputBuffer[13]),&(inputBuffer[14]),&(inputBuffer[15]),&(inputBuffer[16]))==17)/* index 4 and 5 are inverted to get P0 in 4 and P1 in 5 in the array */
{/* input buffer contains the parameters and in [15] the frame erasure flag */
inti;
uint8_tbitStreamLength;
framesNbr++;
if(inputBuffer[16]==1){/* active frame */
parametersArray2BitStream(inputBuffer,bitStream);
bitStreamLength=10;
}else{/* SID frame */
if(inputBuffer[16]==0){/* non transmitted frame */