📄 g723_codec.c
字号:
/* Interpolate LSFs, transform to LPCs, Quantize interpolated LPCs Update LSF history in the encoder state variable */ appsLSFInterp_G723_16s(pEncoderState->sidLsf,InterpLsf,QLpc,pEncoderState->prevLsf); /* Update error taming and the combined filter memory on all subframes */ for ( i = 0; i < SFNUM; i ++ ) { /* Update error "taming" parameters defined in [2] and described in the readme file that accompanies the source. The fixed-point reference code appears in the module EXC_LBC.C, routines Test_Err() and Update_Err(). The resulting error "taming" parameters constrain the gain quantization search for the adaptive codebook. */ appsUpdateErrorTaming_G723_16s(EstimatedPitchLag[i], ClosedLoopPitchLagOffset[i], AdaptGainIndex[i], pEncoderState->errorTamingParams, bitRate); /* Update the combined filter memory, Si(z), as described in [1], section 2.19, pp. 14-15. Filter non-recursive and recursive memories are maintained in the encoder state variable buffers pEncoderState->combinedFilterZfir, and pEncoderState->combinedFilterZiir, respectively. */ appsUpdateCombinedFilter_G723_16s(PerceptLpc[i<<1], QLpc[i], PrcptWghtSpchBuf+MAXLAG+(i*SFLEN), pEncoderState->combinedFilterZfir, pEncoderState->combinedFilterZiir); } } /* Process speech (VAD==1) frame */ else { /* LPC interpolation procedure 1. Generate inverse quantized LSFs on subframe 3 2. Interpolate LSFs on all subframes, transform LSF->LPC 3. Store interpolated, quantized LPCs in QLpc */ /* 1. Inverse quantize the LSFs */ InvalidFrame = 0; /* 0 denotes valid frame */ appsLSFQuantInv_G723_32s16s(QLsfIndex, pEncoderState->prevLsf, Lsf, InvalidFrame); /* 2,3. Interpolate LSFs, transform to LPCs, Quantize interpolated LPCs Update LSF history in the encoder state variable */ appsLSFInterp_G723_16s(Lsf,InterpLsf,QLpc,pEncoderState->prevLsf); /* Estimate harmonic noise shaping parameters (L, beta) The HNS primitive estimates the optimal HNS lag, L, and gain, beta, by following the search procedure (Eqs. 14-17 of [1], sec 2.11, p.8). In this procedure, the optimum HNS lag is identified as the correlation lag that maximizes the normalized correlation function, Cpw(j) (Eqs. 14.1, 14.2 of [1], sec. 2.11, p. 8) estimated over a small neighborhood surrounding the open-loop pitch estimate (+/-3 lags). The HNS gain, beta, is derived from the optimal filter gain, perceptually weighted speech energy, and maximimum Cpw value (Eqs. 15-17 of [1], sec. 2.11, p.8). All HNS speech correlations are estimated from the perceptually weighted speech contained in the OLPS analysis buffer */ for ( i = 0; i < SFNUM; i ++ ) ippsHarmonicSearch_G723_16s(OpenLoopPitchLag[i>>1], OLPSAnalysisBuf+MAXLAG+i*SFLEN, &HNSLag[i], &HNSGain[i]); /* Apply harmonic noise shaping filter (on all subframes) Generate the harmonically weighted speech sequence, w(n), by applying the HNS filter (Eq. 18 of [1], sec. 2.11, p. 8) to the perceptually weighted speech sequence, f(n). The output sequence w(n) is stored the buffer SpchAnalysisBuf[]. */ appsApplyHarmonicNoiseShaping_G723_16s(PrcptWghtSpchBuf, SpchAnalysisBuf, HNSLag, HNSGain); /* Initialize "search reservoir" for the ACELP codebook search (5.3 kbps). As described in [1], sec. 2.16, p. 13, the ACELP search has variable complexity, with the number of times that the search can enter the 4th nested loop limited to 600 per frame, or an average of 150 per subframe. The parameter ACELPInnerLoopMaxEntry limits the average number of entries as such, but allows the number of individual subframe entries to vary up or down, i.e., some subframes may have fewer than 150 entries, while others may exceed the limit of 150. This details of this procedure are given in [2], module ext_lbc.c. */ ACELPInnerLoopMaxEntry = 120; /* Adaptive and fixed codebook search procedures */ for ( i = 0; i < SFNUM; i ++ ) { SubframeOffset = (Ipp16s)(i * SFLEN); /* Compute the impulse response of the combined filter, Si(z) This filter (Eq. 19 of [1], sec 2.12, p. 9) combines the quantized, interpolated LPC synthesis filter A(z) (Eq. 10 of [1], sec. 2.7, p.6), the HNS filter, P(z), parameterized by gain beta and lag L (Eq. 13 of [1], sec. 2.11, p. 8), and the perceptual weighting filter, W(z) (Eq. 11 of [1], sec 2.8, p.7). A 60-sample impulse response vector is generated for this filter on each subframe. The resulting impulse response vector is stored in the vector ImpulseResp[]. */ appsComputeImpulseResponse_G723_16s(HNSLag[i], HNSGain[i], PerceptLpc[i<<1], QLpc[i], ImpulseResp); /* Generate the adaptive codebook target signal, t(n) The adaptive codebook target signal, t(n), is generated by subtracting the combined filter (Si(z)) zero-input-response, z(n), from the perceptually weighted and HNS-processed speech w(n), i.e., t(n)=w(n)-z(n). The sequence w(n) (stored in SpchAnalysisBuf[]) was computed by applying the perceptual weighting filter, W(z), and the harmonic noise shaping filter (HNS) to the highpass filtered input speech, x(n). The ZIR sequence z(n) is computed for the combined filter, Si(z), given the data currently in the filter memory, as described in [1], section 2.13, p. 9. Note that SpchAnalysisBuf contains w(n) upon entry to ippsAdaptiveTargetSignal_G723_16s(), and SpchAnalysisBuf contains the target sequence t(n) upon return. */ appsComputeAdaptiveTargetVector_G723_16s(HNSLag[i], HNSGain[i], PerceptLpc[i<<1], QLpc[i], pEncoderState->combinedFilterZfir, pEncoderState->combinedFilterZiir, SpchAnalysisBuf+SubframeOffset); /* Setup for the closed-loop adaptive codebook search First, establish the closed-loop search window (-1,0,+1) surrounding the open-loop pitch lag for subframes 0, 2 and surrounding the previous closed-loop pitch lag for subframes 1,3 */ if ( (i & 1) == 0 ) EstimatedPitchLag[i] = OpenLoopPitchLag[i>>1]; else EstimatedPitchLag[i] = EstimatedPitchLag[i-1]; /* Next, modify the closed-loop search window for open-loop pitch extremes */ if ( (i & 1) == 0 ) { if ( EstimatedPitchLag[i] == 18 ) EstimatedPitchLag[i] += 1; if ( EstimatedPitchLag[i] > 140 ) EstimatedPitchLag[i] = 140; } /* Perform adaptive codebook ("closed-loop") search as described in [1], section 2.14, p. 9. The defining fixed-point reference code for this adaptive codebook search procedure appears in the [2], module EXC_LBC.C, functions Find_Acbk(), Get_Rez(), and Decod_Acbk(). The closed-loop search surrounds the lag defined in EstimatedPitchLag. The vector SpchAnalysisBuf[] contains the target sequence, t(n), that the search attempts to match. ImpulseResp[] contains the impulse response of the combined filter, Si(z), which is used to filter each of the candidate vectors in order to find the closest match. prevExcitation contains the excitation history (essentially the codebook). errorTamingParams is a control parameter used to bound the worst-case error that could occur if the encoder and decoder were to lose synchronization. The error "taming" procedure is defined in the fixed-point reference code [2], and described in the readme file that accompanies the source. The sine detection state is used in the error taming procedure. Bit rate is used to select the appropriate quantization tables. The closed-loop pitch lag, Li, (offset from OLPS) is returned in ClosedLoopPitchLagOffset, and the index to the quantized adaptive codebook gain is returned in AdaptGainIndex. Both return values are stored in vectors indexed by subframe. */ ippsAdaptiveCodebookSearch_G723(EstimatedPitchLag[i], SpchAnalysisBuf+SubframeOffset, ImpulseResp, (pEncoderState->prevExcitation), pEncoderState->errorTamingParams, &ClosedLoopPitchLagOffset[i], &AdaptGainIndex[i], (Ipp16s)i, pEncoderState->sineDtct, bitRate); /* Store closed-loop pitch lag in EstimatedPitchLag such that Li=EstimatedPitchLag+ClosedLoopPitchLagOffset */ if ( (i & 1) == 0 ) { EstimatedPitchLag[i] = EstimatedPitchLag[i] - 1 + ClosedLoopPitchLagOffset[i]; ClosedLoopPitchLagOffset[i] = 1; } /* Synthesize the adaptive codebook vector, p(n), store the result in AdaptCBVect[] The adaptive codebook vector is parameterized by the lag, Li, (EstimatedPitchLag+ClosedLoopPitchLag) and a gain (quantized gain is indexed by AdaptGainIndex). Given these parameters, the synthesis routine indexes the previous excitation history buffer (prevExcitation) as the adaptive "codebook" using the lag, Li, and the gain, Betai. */ ippsDecodeAdaptiveVector_G723_16s(EstimatedPitchLag[i], ClosedLoopPitchLagOffset[i], AdaptGainIndex[i], (pEncoderState->prevExcitation), AdaptCBVect, bitRate); /* Generate the fixed codebook target, r(n)=t(n)-p(n) by filtering the adaptive codebook vector through Si(z), then subtract the output from the sequence t(n) (stored in SpchAnalysisBuf[]). */ appsComputeFixedTargetVector_G723_16s_I(SpchAnalysisBuf+SubframeOffset, AdaptCBVect, ImpulseResp); /* Fixed codebook search procedures */ /* For 6.3 kbps, perform MP-MLQ fixed codebook search as described in [1], section 2.15, pp. 9-11. This primitive implements the analysis-by-synthesis codebook search procedure defined in [2], module EXC_LBC.C, functions Find_Fcbk(), Find_Best(), Gen_Trn(), and Fcbk_Pack(). Upon entry to the MPMLQ search, SpchAnalysisBuf[] contains the search target vector, r(n), EstimatedPitchLag[] contains the pitch indices, L0/L2, that are used to generate the Dirac pulse trains if it turns out that they contribute to reduced MSE, ImpulseResp[] contains the combined filter impulse response, Si(z), and i indicates the subframe. Upon return from the MPMLQ search primitive, FixedCBVect[] contains the fixed codebook excitation vector, FixedCBGrid[] indicates whether the pulse grid starts on sample 0 or 1 (even or odd), the DiracTrainEnable[] binary flag is set to indicate whether or not the Dirac pulse trains were used to insert multiple pulses for short pitch periods, FixedCBQGainIndex[] contains the quantized fixed codebook gain index, FixedCBPulseSign[] contains the pulse signs (+/-), alphak, and FixedCBPulsePos[] contains the pulse positions, mk. There are 6 pulses for even subframes and 5 pulses for odd subframes. */ if ( bitRate == IPP_SPCHBR_6300 ) ippsMPMLQFixedCodebookSearch_G723(EstimatedPitchLag[i], ImpulseResp, SpchAnalysisBuf+SubframeOffset, FixedCBVect, &FixedCBGrid[i], &DiracTrainEnable[i], &FixedCBQGainIndex[i], &FixedCBPulseSign[i], &FixedCBPulsePos[i], (Ipp16s)i); else /* For 5.3 kbps, perform ACELP fixed codebook search as described in [1], section 2.14, p. 11-13. This section implements the ACELP codebook search procedure defined in [2], module EXC_LBC.C, functions search_T0(), ACELP_LBC_code(), Cor_h(), Cor_h_X(), D4i64_LBC(), and G_code(). The ACELP search procedure requires six steps, shown below. */ { /* 1. For closed-loop pitch lags less than 60, modify Si(z) impulse response by applying a pitch-synchronous filter ([1], p.13 paragraph 3). Pitch-synchronous filter lag and gain are tabulated in [2]. Pitch synchronous filter parameters are derived from modified closed-loop pitch lag and gain. The filter is applied only for pitch lags < 60 */ appsPitchSyncFilter_G723_16s_I(ImpulseResp, EstimatedPitchLag[i], ClosedLoopPitchLagOffset[i], AdaptGainIndex[i], &PitchSyncIndex, &PitchSyncGain); /* 2. Compute the Toeplitz covariance matrix, PHI, associated with the Si(z) impulse response as shown in [1], Eq. 29, p. 12. */ ippsToeplizMatrix_G723_16s(ImpulseResp, ImpRespCovarMatrix); /* 3. Compute the cross-correlation, d(j). between the target r(n) and the Si(z) impulse response, h(n), as shown in [1], Eq. 28, p. 12. */ appsACELPCrossCorr_G723_16s(SpchAnalysisBuf+SubframeOffset, ImpulseResp, CrossCorrACELP); /* 4. Apply ACELP search, using the procedure given in [1], Eqs. 30-35, pp. 12-13. Upon entry, CrossCorrACELP contains the correlation sequence d(j), ImpRespCovarMatrix contains the Toeplitz covariance matrix PHI, and ACELPInnerLoopMaxEntry contains the variable complexity search control parameter for the fourth nested loop. Upon return, PulseSignsACELP[] contains the pulse signs (+/-), PulsePosACELP contains the pulse positions, FixedCBGrid[] indicates whether to use the even or odd grid (0 or 1-start sample), and FixedCBVect contains the synthesized fixed excitation vector shape (no gain scaling). */ ippsACELPFixedCodebookSearch_G723_16s(CrossCorrACELP, ImpRespCovarMatrix, PulseSignsACELP[i], PulsePosACELP[i], &FixedCBGrid[i], FixedCBVect, &ACELPInnerLoopMaxEntry); /* 5. Compute and quantize the ACELP codebook gain, as described in [1], p. 13. */ appsACELPGainQuant_G723_16s(SpchAnalysisBuf+SubframeOffset, ImpulseResp, PulseSignsACELP[i], PulsePosACELP[i], &FixedCBQGain[i], &FixedCBQGainIndex[i]); /* 6. Synthesize ACELP excitation vector by applying gain */ appsScaleACELPVector_G723_16s_I(FixedCBVect,FixedCBQGain[i],PitchSyncIndex,PitchSyncGain); /* 7. Encode ACELP fixed vector pulse signs and positions (8 positions possible for each of four pulses) */ appsEncodeACELPVector_G723(PulseSignsACELP[i], PulsePosACELP[i], &(FixedCBPulseSign[i]), &(FixedCBPulsePos[i]));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -