// Copyright (C) 1999 Jean-Marc Valin #include "BufferedNode.h" #include "Buffer.h" #include "Vector.h" #include #include using namespace std; namespace FD { class CMS; DECLARE_NODE(CMS) /*Node * * @name CMS * @category DSP:TimeFreq * @description Window-type Cepstram Mean Subtraction (CMS) * * @input_name INPUT * @input_type Vector * @input_description Input frames (cepstrum) * * @output_name OUTPUT * @output_type Vector * @output_description CMS output frames * * @parameter_name LENGTH * @parameter_type int * @parameter_description Frame length (number of features) * * @parameter_name LOOKBACK * @parameter_type int * @parameter_description CMS window look-back (number of frames) * * @parameter_name LOOKAHEAD * @parameter_type int * @parameter_description CMS window look-ahead (number of frames) * END*/ #define NEAR_ONE .99999 class CMS : public BufferedNode { int outputID; int inputID; int length; int lookAhead; int lookBack; vector mean; float decrease; float norm; bool init; int accumCount; public: CMS(string nodeName, ParameterSet params) : BufferedNode(nodeName, params) , init(false) { inputID = addInput("INPUT"); outputID = addOutput("OUTPUT"); length = dereference_cast (parameters.get("LENGTH")); inputsCache[inputID].lookBack=dereference_cast (parameters.get("LOOKBACK")); inputsCache[inputID].lookAhead=dereference_cast (parameters.get("LOOKAHEAD")); lookAhead = inputsCache[inputID].lookAhead; lookBack = inputsCache[inputID].lookBack; mean.resize(length); //norm = 1.0/(lookAhead+lookBack); norm = (1-pow(NEAR_ONE,lookAhead+lookBack+1))/(1-NEAR_ONE)/(lookAhead+lookBack+1); //cerr << "norm = " << norm << endl; decrease = pow(NEAR_ONE,lookAhead+lookBack); inOrder = true; } virtual void initialize() { for (int i=0;igetOutput(input.outputID, count); Vector &output = *Vector::alloc(length); out[count] = &output; if (!init) { for (int i=0;igetOutput(input.outputID, count+lookAhead); Vector &curr = object_cast > (nextInputValue); accumCount++; for (int j=0;j &in = object_cast > (inputValue); const Vector *past; const Vector *next; bool can_look_back = false; bool can_look_ahead = false; if (count >= lookBack) { ObjectRef pastInputValue = input.node->getOutput(input.outputID, count-lookBack); can_look_back=true; past = &object_cast > (pastInputValue); } ObjectRef nextInputValue = input.node->getOutput(input.outputID, count+lookAhead); can_look_ahead=true; next = &object_cast > (nextInputValue); for (int i=0;i