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.

104 lines
2.7KB

  1. /***************************************************/
  2. /*! \class BiQuad
  3. \brief STK biquad (two-pole, two-zero) filter class.
  4. This class implements a two-pole, two-zero digital filter.
  5. Methods are provided for creating a resonance or notch in the
  6. frequency response while maintaining a constant filter gain.
  7. by Perry R. Cook and Gary P. Scavone, 1995--2017.
  8. */
  9. /***************************************************/
  10. #include "BiQuad.h"
  11. #include <cmath>
  12. namespace stk {
  13. BiQuad :: BiQuad() : Filter()
  14. {
  15. b_.resize( 3, 0.0 );
  16. a_.resize( 3, 0.0 );
  17. b_[0] = 1.0;
  18. a_[0] = 1.0;
  19. inputs_.resize( 3, 1, 0.0 );
  20. outputs_.resize( 3, 1, 0.0 );
  21. Stk::addSampleRateAlert( this );
  22. }
  23. BiQuad :: ~BiQuad()
  24. {
  25. Stk::removeSampleRateAlert( this );
  26. }
  27. void BiQuad :: setCoefficients( StkFloat b0, StkFloat b1, StkFloat b2, StkFloat a1, StkFloat a2, bool clearState )
  28. {
  29. b_[0] = b0;
  30. b_[1] = b1;
  31. b_[2] = b2;
  32. a_[1] = a1;
  33. a_[2] = a2;
  34. if ( clearState ) this->clear();
  35. }
  36. void BiQuad :: sampleRateChanged( StkFloat newRate, StkFloat oldRate )
  37. {
  38. if ( !ignoreSampleRateChange_ ) {
  39. oStream_ << "BiQuad::sampleRateChanged: you may need to recompute filter coefficients!";
  40. handleError( StkError::WARNING );
  41. }
  42. }
  43. void BiQuad :: setResonance( StkFloat frequency, StkFloat radius, bool normalize )
  44. {
  45. #if defined(_STK_DEBUG_)
  46. if ( frequency < 0.0 || frequency > 0.5 * Stk::sampleRate() ) {
  47. oStream_ << "BiQuad::setResonance: frequency argument (" << frequency << ") is out of range!";
  48. handleError( StkError::WARNING ); return;
  49. }
  50. if ( radius < 0.0 || radius >= 1.0 ) {
  51. oStream_ << "BiQuad::setResonance: radius argument (" << radius << ") is out of range!";
  52. handleError( StkError::WARNING ); return;
  53. }
  54. #endif
  55. a_[2] = radius * radius;
  56. a_[1] = -2.0 * radius * cos( TWO_PI * frequency / Stk::sampleRate() );
  57. if ( normalize ) {
  58. // Use zeros at +- 1 and normalize the filter peak gain.
  59. b_[0] = 0.5 - 0.5 * a_[2];
  60. b_[1] = 0.0;
  61. b_[2] = -b_[0];
  62. }
  63. }
  64. void BiQuad :: setNotch( StkFloat frequency, StkFloat radius )
  65. {
  66. #if defined(_STK_DEBUG_)
  67. if ( frequency < 0.0 || frequency > 0.5 * Stk::sampleRate() ) {
  68. oStream_ << "BiQuad::setNotch: frequency argument (" << frequency << ") is out of range!";
  69. handleError( StkError::WARNING ); return;
  70. }
  71. if ( radius < 0.0 ) {
  72. oStream_ << "BiQuad::setNotch: radius argument (" << radius << ") is negative!";
  73. handleError( StkError::WARNING ); return;
  74. }
  75. #endif
  76. // This method does not attempt to normalize the filter gain.
  77. b_[2] = radius * radius;
  78. b_[1] = (StkFloat) -2.0 * radius * cos( TWO_PI * (double) frequency / Stk::sampleRate() );
  79. }
  80. void BiQuad :: setEqualGainZeroes( void )
  81. {
  82. b_[0] = 1.0;
  83. b_[1] = 0.0;
  84. b_[2] = -1.0;
  85. }
  86. } // stk namespace