You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

137 lines
3.6KB

  1. /***************************************************/
  2. /*! \class FormSwep
  3. \brief STK sweepable formant filter class.
  4. This class implements a formant (resonance) which can be "swept"
  5. over time from one frequency setting to another. It provides
  6. methods for controlling the sweep rate and target frequency.
  7. by Perry R. Cook and Gary P. Scavone, 1995--2017.
  8. */
  9. /***************************************************/
  10. #include "FormSwep.h"
  11. #include <cmath>
  12. namespace stk {
  13. FormSwep :: FormSwep( void )
  14. {
  15. frequency_ = 0.0;
  16. radius_ = 0.0;
  17. targetGain_ = 1.0;
  18. targetFrequency_ = 0.0;
  19. targetRadius_ = 0.0;
  20. deltaGain_ = 0.0;
  21. deltaFrequency_ = 0.0;
  22. deltaRadius_ = 0.0;
  23. sweepState_ = 0.0;
  24. sweepRate_ = 0.002;
  25. dirty_ = false;
  26. b_.resize( 3, 0.0 );
  27. a_.resize( 3, 0.0 );
  28. a_[0] = 1.0;
  29. inputs_.resize( 3, 1, 0.0 );
  30. outputs_.resize( 3, 1, 0.0 );
  31. Stk::addSampleRateAlert( this );
  32. }
  33. FormSwep :: ~FormSwep()
  34. {
  35. Stk::removeSampleRateAlert( this );
  36. }
  37. void FormSwep :: sampleRateChanged( StkFloat newRate, StkFloat oldRate )
  38. {
  39. if ( !ignoreSampleRateChange_ ) {
  40. oStream_ << "FormSwep::sampleRateChanged: you may need to recompute filter coefficients!";
  41. handleError( StkError::WARNING );
  42. }
  43. }
  44. void FormSwep :: setResonance( StkFloat frequency, StkFloat radius )
  45. {
  46. #if defined(_STK_DEBUG_)
  47. if ( frequency < 0.0 || frequency > 0.5 * Stk::sampleRate() ) {
  48. oStream_ << "FormSwep::setResonance: frequency argument (" << frequency << ") is out of range!";
  49. handleError( StkError::WARNING ); return;
  50. }
  51. if ( radius < 0.0 || radius >= 1.0 ) {
  52. oStream_ << "FormSwep::setResonance: radius argument (" << radius << ") is out of range!";
  53. handleError( StkError::WARNING ); return;
  54. }
  55. #endif
  56. radius_ = radius;
  57. frequency_ = frequency;
  58. a_[2] = radius * radius;
  59. a_[1] = -2.0 * radius * cos( TWO_PI * frequency / Stk::sampleRate() );
  60. // Use zeros at +- 1 and normalize the filter peak gain.
  61. b_[0] = 0.5 - 0.5 * a_[2];
  62. b_[1] = 0.0;
  63. b_[2] = -b_[0];
  64. }
  65. void FormSwep :: setStates( StkFloat frequency, StkFloat radius, StkFloat gain )
  66. {
  67. dirty_ = false;
  68. if ( frequency_ != frequency || radius_ != radius )
  69. this->setResonance( frequency, radius );
  70. gain_ = gain;
  71. targetFrequency_ = frequency;
  72. targetRadius_ = radius;
  73. targetGain_ = gain;
  74. }
  75. void FormSwep :: setTargets( StkFloat frequency, StkFloat radius, StkFloat gain )
  76. {
  77. if ( frequency < 0.0 || frequency > 0.5 * Stk::sampleRate() ) {
  78. oStream_ << "FormSwep::setTargets: frequency argument (" << frequency << ") is out of range!";
  79. handleError( StkError::WARNING ); return;
  80. }
  81. if ( radius < 0.0 || radius >= 1.0 ) {
  82. oStream_ << "FormSwep::setTargets: radius argument (" << radius << ") is out of range!";
  83. handleError( StkError::WARNING ); return;
  84. }
  85. dirty_ = true;
  86. startFrequency_ = frequency_;
  87. startRadius_ = radius_;
  88. startGain_ = gain_;
  89. targetFrequency_ = frequency;
  90. targetRadius_ = radius;
  91. targetGain_ = gain;
  92. deltaFrequency_ = frequency - frequency_;
  93. deltaRadius_ = radius - radius_;
  94. deltaGain_ = gain - gain_;
  95. sweepState_ = 0.0;
  96. }
  97. void FormSwep :: setSweepRate( StkFloat rate )
  98. {
  99. if ( rate < 0.0 || rate > 1.0 ) {
  100. oStream_ << "FormSwep::setSweepRate: argument (" << rate << ") is out of range!";
  101. handleError( StkError::WARNING ); return;
  102. }
  103. sweepRate_ = rate;
  104. }
  105. void FormSwep :: setSweepTime( StkFloat time )
  106. {
  107. if ( time <= 0.0 ) {
  108. oStream_ << "FormSwep::setSweepTime: argument (" << time << ") must be > 0.0!";
  109. handleError( StkError::WARNING ); return;
  110. }
  111. this->setSweepRate( 1.0 / ( time * Stk::sampleRate() ) );
  112. }
  113. } // stk namespace