// $Id$ // // On-line normalization. This block is intended to replace our // standard off-line normalization in which means and variances are // calculated over an entire data set and then applied to the data // prior to MLP training to generate zero-mean, unit-variance // features. This block uses a single-pole low-pass filter // (with user-specifiable time constant) to estimate the signal mean // on-line. This mean is subtracted off, then a second single // low-pass filter (again, with user-specifiable time constant), // preceded by a squaring operation, is used to estimate the signal // variance. The zero-mean signal is divided by the square root of // this estimate, plus a small epsilon to prevent divide-by-zero // problems. Because the filters used have relatively long time // constants and we may be processing relatively short files, a // history mechanism is employed so that the filter state from a // previous utterance may be used to initialize the filters for the // current utterance. On termination, the filter state may be written // to a history file for use by later runs. // // $Log$ // #ifndef Online_Norm_h_INCLUDED #define Online_Norm_h_INCLUDED #include #include "Blocker.h" #include "Matrix.h" #include "Vector.h" class Online_Norm : public Blocker { public: // Note that the taus are specified in milliseconds. // Online_Norm(const size_t a_IOBlocking, const size_t a_numChannels, const float a_samplingFrequency, const float a_meanLPtau, const float a_varLPtau, const float a_epsilon, const char* a_inHistoryFileName, const char* a_outHistoryFileName) : IOBlocking(a_IOBlocking), numChannels(a_numChannels), samplingFrequency(a_samplingFrequency), meanLPtau(a_meanLPtau), varLPtau(a_varLPtau), epsilon(a_epsilon), inHistoryFileName(a_inHistoryFileName), outHistoryFileName(a_outHistoryFileName), meanLP_a1(exp(-1000.0 / (samplingFrequency * meanLPtau))), meanLP_b0(1.0 - meanLP_a1), varLP_a1(exp(-1000.0 / (samplingFrequency * varLPtau))), varLP_b0(1.0 - varLP_a1), meanLPstate(new float[numChannels]), varLPstate(new float[numChannels]), result(new float[numChannels * IOBlocking]) { // Initialize filter states // if (inHistoryFileName == 0) { for (size_t i = 0; i < numChannels; i++) { meanLPstate[i] = 0.0f; varLPstate[i] = 0.0f; } } else { readHistory(); } }; ~Online_Norm() { if (outHistoryFileName != 0) { writeHistory(); } delete [] meanLPstate; delete [] varLPstate; delete [] result; }; const CMatrix processBlock(const CMatrix in, bool& lastTime); private: const size_t IOBlocking; // Max # of data points we'll get at once const size_t numChannels; // # of channels of data const float samplingFrequency; // data sampling rate const float meanLPtau; // tau for LPF that estimates mean const float varLPtau; // tau for LPF that estimates variance const float epsilon; // Fudge factor to prevent divide-by-0 const char* inHistoryFileName; // name of history file to read const char* outHistoryFileName; // name of history file to write // Filter coefficients for the lowpass filters used to estimate the // mean and variance. The filters are simple single-pole lowpass // filters that compute the function // // y(t) = a1 * y(t-1) + b0 * x(t) // // where y is the filter output and x is the filter input. // const float meanLP_a1; const float meanLP_b0; const float varLP_a1; const float varLP_b0; float* meanLPstate; // output of mean-estimating LPF float* varLPstate; // output of variance-estimating LPF float* result; // buffer for output of processing // function to initialize filter states from a history file // void readHistory(); // function to write filter states to a history file // void writeHistory(); }; #endif // Online_Norm_h_INCLUDED