Audio plugin host https://kx.studio/carla
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.

109 lines
2.9KB

  1. /***************************************************/
  2. /*! \class Twang
  3. \brief STK enhanced plucked string class.
  4. This class implements an enhanced plucked-string
  5. physical model, a la Jaffe-Smith, Smith,
  6. Karjalainen and others. It includes a comb
  7. filter to simulate pluck position. The tick()
  8. function takes an input sample, which is added
  9. to the delayline input. This can be used to
  10. implement commuted synthesis (if the input
  11. samples are derived from the impulse response of
  12. a body filter) or feedback (as in an electric
  13. guitar model).
  14. This is a digital waveguide model, making its
  15. use possibly subject to patents held by Stanford
  16. University, Yamaha, and others.
  17. by Perry R. Cook and Gary P. Scavone, 1995-2011.
  18. */
  19. /***************************************************/
  20. #include "Twang.h"
  21. namespace stk {
  22. Twang :: Twang( StkFloat lowestFrequency )
  23. {
  24. if ( lowestFrequency <= 0.0 ) {
  25. oStream_ << "Twang::Twang: argument is less than or equal to zero!";
  26. handleError( StkError::FUNCTION_ARGUMENT );
  27. }
  28. this->setLowestFrequency( lowestFrequency );
  29. std::vector<StkFloat> coefficients( 2, 0.5 );
  30. loopFilter_.setCoefficients( coefficients );
  31. lastFrame_.resize( 1, 1, 0.0 );
  32. loopGain_ = 0.995;
  33. pluckPosition_ = 0.4;
  34. this->setFrequency( 220.0 );
  35. }
  36. Twang :: ~Twang( void )
  37. {
  38. }
  39. void Twang :: clear( void )
  40. {
  41. delayLine_.clear();
  42. combDelay_.clear();
  43. loopFilter_.clear();
  44. lastFrame_[0] = 0.0;
  45. }
  46. void Twang :: setLowestFrequency( StkFloat frequency )
  47. {
  48. unsigned long nDelays = (unsigned long) ( Stk::sampleRate() / frequency );
  49. delayLine_.setMaximumDelay( nDelays + 1 );
  50. combDelay_.setMaximumDelay( nDelays + 1 );
  51. }
  52. void Twang :: setFrequency( StkFloat frequency )
  53. {
  54. #if defined(_STK_DEBUG_)
  55. if ( frequency <= 0.0 ) {
  56. oStream_ << "Twang::setFrequency: argument is less than or equal to zero!";
  57. handleError( StkError::WARNING ); return;
  58. }
  59. #endif
  60. // Delay = length - filter delay.
  61. StkFloat delay = ( Stk::sampleRate() / frequency ) - loopFilter_.phaseDelay( frequency );
  62. delayLine_.setDelay( delay );
  63. this->setLoopGain( loopGain_ );
  64. // Set the pluck position, which puts zeroes at position * length.
  65. combDelay_.setDelay( 0.5 * pluckPosition_ * delay );
  66. }
  67. void Twang :: setLoopGain( StkFloat loopGain )
  68. {
  69. if ( loopGain < 0.0 || loopGain >= 1.0 ) {
  70. oStream_ << "Twang::setLoopGain: parameter is out of range!";
  71. handleError( StkError::WARNING ); return;
  72. }
  73. loopGain_ = loopGain;
  74. StkFloat gain = loopGain_ + (frequency_ * 0.000005);
  75. if ( gain >= 1.0 ) gain = 0.99999;
  76. loopFilter_.setGain( gain );
  77. }
  78. void Twang :: setPluckPosition( StkFloat position )
  79. {
  80. if ( position < 0.0 || position > 1.0 ) {
  81. oStream_ << "Twang::setPluckPosition: argument (" << position << ") is out of range!";
  82. handleError( StkError::WARNING ); return;
  83. }
  84. pluckPosition_ = position;
  85. }
  86. } // stk namespace