/tags/rel-0-1-1/FreeSpeech/audio_blocks/src/CMS.cc

# · C++ · 156 lines · 112 code · 27 blank · 17 comment · 23 complexity · 2259acbd5ef6e24180ea9f36088affec MD5 · raw file

  1. // Copyright (C) 1999 Jean-Marc Valin
  2. //
  3. // This program is free software; you can redistribute it and/or modify
  4. // it under the terms of the GNU General Public License as published by
  5. // the Free Software Foundation; either version 2, or (at your option)
  6. // any later version.
  7. //
  8. // This program is distributed in the hope that it will be useful, but
  9. // WITHOUT ANY WARRANTY; without even the implied warranty of
  10. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. // General Public License for more details.
  12. //
  13. // You should have received a copy of the GNU General Public License
  14. // along with this file. If not, write to the Free Software Foundation,
  15. // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  16. #include <stream.h>
  17. #include "FrameOperation.h"
  18. #include "Buffer.h"
  19. #include "Vector.h"
  20. #include <stdlib.h>
  21. #include <math.h>
  22. class CMS;
  23. //DECLARE_NODE(CMS)
  24. NODE_INFO(CMS,"Signal:DSP", "INPUT", "OUTPUT", "LENGTH:LOOKBACK:LOOKAHEAD")
  25. //float *i_heap = ((float *)malloc( sizeof(float) * 2048))+2047;
  26. class CMS : public FrameOperation {
  27. int inputID;
  28. int inputLength;
  29. int lookAhead;
  30. int lookBack;
  31. float *mean;
  32. float decrease;
  33. float norm;
  34. bool init;
  35. public:
  36. CMS(string nodeName, ParameterSet params)
  37. : FrameOperation(nodeName, params)
  38. , init(false)
  39. {
  40. inputID = addInput("INPUT");
  41. if (parameters.exist("INPUTLENGTH"))
  42. inputLength = dereference_cast<int> (parameters.get("INPUTLENGTH"));
  43. else inputLength = dereference_cast<int> (parameters.get("LENGTH"));
  44. inputsCache[inputID].lookBack=dereference_cast<int> (parameters.get("LOOKBACK"));
  45. inputsCache[inputID].lookAhead=dereference_cast<int> (parameters.get("LOOKAHEAD"));
  46. lookAhead = inputsCache[inputID].lookAhead;
  47. lookBack = inputsCache[inputID].lookBack;
  48. norm = 1.0/(lookAhead+lookBack);
  49. decrease = pow(.999,lookAhead+lookBack);
  50. }
  51. ~CMS() {delete [] mean;}
  52. virtual void specificInitialize()
  53. {
  54. mean = new float [outputLength];
  55. for (int i=0;i<outputLength;i++)
  56. mean[i]=0;
  57. this->FrameOperation::specificInitialize();
  58. }
  59. virtual void reset()
  60. {
  61. for (int i=0;i<outputLength;i++)
  62. mean[i]=0;
  63. init=false;
  64. this->FrameOperation::reset();
  65. }
  66. void calculate(int output_id, int count, Buffer &out)
  67. {
  68. NodeInput input = inputs[inputID];
  69. ObjectRef inputValue = input.node->getOutput(input.outputID, count);
  70. Vector<float> &output = object_cast<Vector<float> > (out[count]);
  71. if (inputValue->status != Object::valid)
  72. {
  73. output.status = inputValue->status;
  74. return;
  75. }
  76. if (!init)
  77. {
  78. for (int i=0;i<lookAhead;i++)
  79. {
  80. ObjectRef nextInputValue = input.node->getOutput(input.outputID, count+lookAhead);
  81. if (nextInputValue->status == Object::valid)
  82. {
  83. Vector<float> &curr = object_cast<Vector<float> > (nextInputValue);
  84. for (int j=0;j<outputLength;j++)
  85. mean[j] += curr[j];
  86. }
  87. }
  88. init=true;
  89. }
  90. const Vector<float> &in = object_cast<Vector<float> > (inputValue);
  91. const Vector<float> *past;
  92. const Vector<float> *next;
  93. bool can_look_back = false;
  94. bool can_look_ahead = false;
  95. if (count >= lookBack)
  96. {
  97. ObjectRef pastInputValue = input.node->getOutput(input.outputID, count-lookBack);
  98. if (pastInputValue->status == Object::valid)
  99. {
  100. can_look_back=true;
  101. past = &object_cast<Vector<float> > (pastInputValue);
  102. }
  103. }
  104. if (1)
  105. {
  106. ObjectRef nextInputValue = input.node->getOutput(input.outputID, count+lookAhead);
  107. if (nextInputValue->status == Object::valid)
  108. {
  109. can_look_ahead=true;
  110. next = &object_cast<Vector<float> > (nextInputValue);
  111. }
  112. }
  113. for (int i=0;i<outputLength;i++)
  114. mean[i]*=.999;
  115. if (can_look_back)
  116. {
  117. for (int i=0;i<outputLength;i++)
  118. mean[i] -= decrease*(*past)[i];
  119. }
  120. if (can_look_ahead)
  121. {
  122. for (int i=0;i<outputLength;i++)
  123. mean[i] += (*next)[i];
  124. }
  125. for (int i=0;i<outputLength;i++)
  126. output[i] = in[i] - norm*mean[i];
  127. output.status = Object::valid;
  128. }
  129. };