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.

77 lines
2.1KB

  1. /***************************************************/
  2. /*! \class TwoPole
  3. \brief STK two-pole filter class.
  4. This class implements a two-pole digital filter. A method is
  5. provided for creating a resonance in the frequency response while
  6. maintaining a nearly constant filter gain.
  7. by Perry R. Cook and Gary P. Scavone, 1995--2017.
  8. */
  9. /***************************************************/
  10. #include "TwoPole.h"
  11. #include <cmath>
  12. namespace stk {
  13. TwoPole :: TwoPole( void )
  14. {
  15. b_.resize( 1 );
  16. a_.resize( 3 );
  17. inputs_.resize( 1, 1, 0.0 );
  18. outputs_.resize( 3, 1, 0.0 );
  19. b_[0] = 1.0;
  20. a_[0] = 1.0;
  21. Stk::addSampleRateAlert( this );
  22. }
  23. TwoPole :: ~TwoPole()
  24. {
  25. Stk::removeSampleRateAlert( this );
  26. }
  27. void TwoPole :: sampleRateChanged( StkFloat newRate, StkFloat oldRate )
  28. {
  29. if ( !ignoreSampleRateChange_ ) {
  30. oStream_ << "TwoPole::sampleRateChanged: you may need to recompute filter coefficients!";
  31. handleError( StkError::WARNING );
  32. }
  33. }
  34. void TwoPole :: setResonance( StkFloat frequency, StkFloat radius, bool normalize )
  35. {
  36. #if defined(_STK_DEBUG_)
  37. if ( frequency < 0.0 || frequency > 0.5 * Stk::sampleRate() ) {
  38. oStream_ << "TwoPole::setResonance: frequency argument (" << frequency << ") is out of range!";
  39. handleError( StkError::WARNING ); return;
  40. }
  41. if ( radius < 0.0 || radius >= 1.0 ) {
  42. oStream_ << "TwoPole::setResonance: radius argument (" << radius << ") is out of range!";
  43. handleError( StkError::WARNING ); return;
  44. }
  45. #endif
  46. a_[2] = radius * radius;
  47. a_[1] = (StkFloat) -2.0 * radius * cos(TWO_PI * frequency / Stk::sampleRate());
  48. if ( normalize ) {
  49. // Normalize the filter gain ... not terribly efficient.
  50. StkFloat real = 1 - radius + (a_[2] - radius) * cos(TWO_PI * 2 * frequency / Stk::sampleRate());
  51. StkFloat imag = (a_[2] - radius) * sin(TWO_PI * 2 * frequency / Stk::sampleRate());
  52. b_[0] = sqrt( pow(real, 2) + pow(imag, 2) );
  53. }
  54. }
  55. void TwoPole :: setCoefficients( StkFloat b0, StkFloat a1, StkFloat a2, bool clearState )
  56. {
  57. b_[0] = b0;
  58. a_[1] = a1;
  59. a_[2] = a2;
  60. if ( clearState ) this->clear();
  61. }
  62. } // stk namespace