www.pudn.com > ETSI_ES_202_212_software.rar > preProc.c
/*=============================================================================== * ETSI ES 202 212 Distributed Speech Recognition * Extended Advanced Front-End Feature Extraction Algorithm & Compression Algorithm * Speech Reconstruction Algorithm. * C-language software implementation * Version 1.1.1 October, 2003 *===============================================================================*/ /*------------------------------------------------------------------------------- * * FILE NAME: preProc.c * PURPOSE: Implementation of speech signal preprocessing for pitch * estimation and voicing classification * *-------------------------------------------------------------------------------*/ #include#include #include #include #include "preProc.h" #ifndef FALSE #define FALSE 0 #endif #ifndef TRUE #define TRUE (!FALSE) #endif /* ======================================================================= FILTER COEFFICIENTS ====================================================================== */ #define HPF_ORDER 6 /* * Sixth order Butterworth high-pass filter * coefficients (1200 Hz cut-off frequency) */ /* Denominator */ static float pfHpfA_8kHz[7] = { 1.00000000, -2.37972104, 2.91040657, -2.05513144, 0.87792390, -0.20986545, 0.02183157 }; static float pfHpfA_11kHz[7] = { 1.00000000000000, -3.36067979080750, 5.06982907485034, -4.27873732337721, 2.10853144888207, -0.57109866030671, 0.06610536478028 }; static float pfHpfA_16kHz[7] = { 1.00000000000000, -4.18238957916850, 7.49161108458765, -7.31359596689075, 4.08934993183312, -1.23852537177671, 0.15842763255178 }; /* Numerator */ static float pfHpfB_8kHz[7] = { 0.14773250, -0.88639500, 2.21598750, -2.95464999, 2.21598749, -0.88639500, 0.14773250 }; static float pfHpfB_11kHz[7] = { 0.25710908848444, -1.54265453090663, 3.85663632726659, -5.14218176968878, 3.85663632726659, -1.54265453090663, 0.25710908848444 }; static float pfHpfB_16kHz[7] = { 0.39802968073138, -2.38817808438830, 5.97044521097075, -7.96059361462766, 5.97044521097075, -2.38817808438830, 0.39802968073138 }; /* * Normally used Low-pass filter coefficients. * Combination of a * sixth order butterworth filter (800 Hz cut-off * frequency) and a low frequency emphasis filter * with coefficients B = [1.0 -0.6], A = [1.0 -0.9] */ #define LPF_ORDER 7 /* Denominator */ static float pfLpfA_8kHz[8] = { 1.00000000, -4.47943480, 8.88015848, -10.05821568, 6.99836861, -2.98181953, 0.71850318, -0.07538083 }; static float pfLpfA_11kHz[8] = { 1.00000000000000, -5.16457301342956, 11.60327150757658, -14.68045002998683, 11.28039703154784, -5.25795344738947, 1.37514936680065, -0.15553999870817 }; static float pfLpfA_16kHz[8] = { 1.00000000000000, -5.73713549885214, 14.19729645263144, -19.63612073482969, 16.38673682892475, -8.24809503698812, 2.31775924387808, -0.28041380978170 }; /* Numerator */ static float pfLpfB_8kHz[8] = { 0.0003405377, 0.0018389033, 0.0038821292, 0.0037459142, 0.0010216130, -0.0010216130, -0.0008853979, -0.0002043226 }; static float pfLpfB_11kHz[8] = { 0.00006475945579, 0.00034263580465, 0.00069586625626, 0.00060637516431, 0.00005297323484, -0.00030025721678, -0.00021076612482, -0.00004592093010 }; static float pfLpfB_16kHz[8] = { 0.00000857655707, 0.00004459809678, 0.00008748088215, 0.00006861245659, -0.00000857655707, -0.00005145934244, -0.00003259091688, -0.00000686124566 }; /* * Low-pass filter coefficients used in presence of * low band noise: * sixth order butterworth filter (800 Hz cut-off * frequency). * No low frequency emphasis. */ #define LPF_ORDER_NO_LB_EMPH 6 /* Denominator */ static float pfLpfA_8kHz_NoLbEmph[7] = { 1.00000000, -3.57943480, 5.65866717, -4.96541523, 2.52949491, -0.70527411, 0.08375648 }; static float pfLpfA_11kHz_NoLbEmph[7] = { 1.00000000000000, -4.23729801342957, 7.67413099217370, -7.56442021421899, 4.26609927740795, -1.30210623993103, 0.16773880316861 }; static float pfLpfA_16kHz_NoLbEmph[7] = { 1.00000000000000, -4.78713549885213, 9.64951772872192, -10.46907889254388, 6.44111188100808, -2.12903875003046, 0.29517243134916 }; /* Numerator */ static float pfLpfB_8kHz_NoLbEmph[7] = { 0.00034054, 0.00204323, 0.00510806, 0.00681075, 0.00510806, 0.00204323, 0.00034054 }; static float pfLpfB_11kHz_NoLbEmph[7] = { 0.00006475945579, 0.00038855673475, 0.00097139183688, 0.00129518911584, 0.00097139183688, 0.00038855673475, 0.00006475945579 }; static float pfLpfB_16kHz_NoLbEmph[7] = { 0.00000857655707, 0.00005145934244, 0.00012864835610, 0.00017153114146, 0.00012864835610, 0.00005145934244, 0.00000857655707 }; /* ==================================================================== INTERNAL FUNCTIONS ===================================================================== */ /*---------------------------------------------------------------------------- * FUNCTION NAME: filter * * PURPOSE: Applies a pole-zero (recursive) filter * * INPUT: * pfB[0:iOrder] - Coefficients corresponding to the * numerator polynominal * pfA[0:iOrder] - Coefficients corresponding to the * denominator polynomial * iOrder - Filter order * pfInp[-iOrder:iLen-1] - Input array * iLen - Input array length (for new samples) * * INPUT/OUTPUT * pfOut[-iOrder:iLen-1] - Filteres array * * RETURN VALUE * none * *---------------------------------------------------------------------------*/ static void filter(float *pfB, float *pfA, int iOrder, float *pfInp, int iLen, float *pfOut) { int i,j; for (i = 0; i < iLen; i++) { pfOut[i] = pfB[0] * pfInp[i]; for(j = 1; j <= iOrder; j++) { pfOut[i] += (pfB[j] * pfInp[i-j]); pfOut[i] -= (pfA[j] * pfOut[i-j]); } } } /* ==================================================================== EXTERNAL FUNCTIONS ===================================================================== */ /*---------------------------------------------------------------------------- * FUNCTION NAME: pre_process * * PURPOSE: To pre-process a speech frame for pitch extraction and * classification purposes * * INPUT: * iFrameLength - frame length * iFrameShift - frame shift * iHistoryLength - offset used to pass the processed signal to * EstimatePitch() * iDownSampFactor - downsampling factor * pfInpSpeech - Input speech buffer * iSamplingFrequency - sampling frequency in Hz * iFirstFrameFlag - Flag to indicate the first frame * iLowBandNoiseFlag - low-band noise presence flag * OUTPUT * pfUBSpeech - Upper Band speech * pfProcSpeech - Lower Band speech * pfDownSampledProcSpeech - downsampled version of pfProcSpeech * * RETURN VALUE * none * *---------------------------------------------------------------------------*/ void pre_process(int iFrameLength, int iFrameShift, int iHistoryLength, int iDownSampFactor, float *pfInpSpeech, int iSamplingFrequency, int iFirstFrameFlag, int iLowBandNoiseFlag, float *pfUBSpeech, float *pfProcSpeech, float *pfDownSampledProcSpeech) { int i, j; int iOrder, iLpfOrder; int iLength; float *pfHpfA,*pfHpfB,*pfLpfA,*pfLpfB; /* Select filters */ switch (iSamplingFrequency) { case 8000: pfHpfA = pfHpfA_8kHz; pfHpfB = pfHpfB_8kHz; if (iLowBandNoiseFlag) { pfLpfA = pfLpfA_8kHz_NoLbEmph; pfLpfB = pfLpfB_8kHz_NoLbEmph; } else { pfLpfA = pfLpfA_8kHz; pfLpfB = pfLpfB_8kHz; } break; case 11000: pfHpfA = pfHpfA_11kHz; pfHpfB = pfHpfB_11kHz; if (iLowBandNoiseFlag) { pfLpfA = pfLpfA_11kHz_NoLbEmph; pfLpfB = pfLpfB_11kHz_NoLbEmph; } else { pfLpfA = pfLpfA_11kHz; pfLpfB = pfLpfB_11kHz; } break; case 16000: pfHpfA = pfHpfA_16kHz; pfHpfB = pfHpfB_16kHz; if (iLowBandNoiseFlag) { pfLpfA = pfLpfA_16kHz_NoLbEmph; pfLpfB = pfLpfB_16kHz_NoLbEmph; } else { pfLpfA = pfLpfA_16kHz; pfLpfB = pfLpfB_16kHz; } break; default: return; } if (iLowBandNoiseFlag) iLpfOrder = LPF_ORDER_NO_LB_EMPH; else iLpfOrder = LPF_ORDER; /* * Process the first frame */ if (iFirstFrameFlag == TRUE) { iLength = iFrameLength-iFrameShift; /* * Perform HPF to obtain the Upper Band Speech */ iOrder = HPF_ORDER; for (i = 0; i < iOrder; i++) { pfInpSpeech[iFrameLength-iLength-1-i] = 0.0; pfUBSpeech[iFrameLength-iLength-1-i] = 0.0; } filter(pfHpfB,pfHpfA,iOrder,pfInpSpeech+iFrameLength-iLength, iLength,pfUBSpeech+iFrameLength-iLength); /* * Perform LPF to get processed speech */ iOrder = iLpfOrder; for (i = 0; i < iOrder; i++) { pfInpSpeech[iFrameLength-iLength-1-i] = 0.0; pfProcSpeech[iHistoryLength+iFrameLength-iLength-1-i] = 0.0; } filter(pfLpfB,pfLpfA,iOrder,pfInpSpeech+iFrameLength-iLength, iLength,pfProcSpeech+iHistoryLength+iFrameLength-iLength); } else { /* * Process the following frames */ iLength = iFrameShift; /* * Perform HPF to obtain the Upper Band Speech */ iOrder = HPF_ORDER; for (i = 0; i < iFrameLength-iLength; i++) { pfUBSpeech[i] = pfUBSpeech[i+iLength]; } filter(pfHpfB,pfHpfA,iOrder,pfInpSpeech+iFrameLength-iLength, iLength,pfUBSpeech+iFrameLength-iLength); /* * Perform LPF to get processed speech */ iOrder = iLpfOrder; for (i = 0; i < iHistoryLength+iFrameLength-iLength; i++) { pfProcSpeech[i] = pfProcSpeech[i+iLength]; } filter(pfLpfB,pfLpfA,iOrder,pfInpSpeech+iFrameLength-iLength, iLength,pfProcSpeech+iHistoryLength+iFrameLength-iLength); } for (i=0, j=0; i < iHistoryLength+iFrameLength; i+=iDownSampFactor, j++) pfDownSampledProcSpeech[j] = pfProcSpeech[i]; return; }