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.

164 lines
4.4KB

  1. /***************************************************/
  2. /*! \Class Flute
  3. \brief STK flute physical model class.
  4. This class implements a simple flute
  5. physical model, as discussed by Karjalainen,
  6. Smith, Waryznyk, etc. The jet model uses
  7. a polynomial, a la Cook.
  8. This is a digital waveguide model, making its
  9. use possibly subject to patents held by Stanford
  10. University, Yamaha, and others.
  11. Control Change Numbers:
  12. - Jet Delay = 2
  13. - Noise Gain = 4
  14. - Vibrato Frequency = 11
  15. - Vibrato Gain = 1
  16. - Breath Pressure = 128
  17. by Perry R. Cook and Gary P. Scavone, 1995--2017.
  18. */
  19. /***************************************************/
  20. #include "Flute.h"
  21. #include "SKINImsg.h"
  22. namespace stk {
  23. Flute :: Flute( StkFloat lowestFrequency )
  24. {
  25. if ( lowestFrequency <= 0.0 ) {
  26. oStream_ << "Flute::Flute: argument is less than or equal to zero!";
  27. handleError( StkError::FUNCTION_ARGUMENT );
  28. }
  29. unsigned long nDelays = (unsigned long) ( Stk::sampleRate() / lowestFrequency );
  30. boreDelay_.setMaximumDelay( nDelays + 1 );
  31. jetDelay_.setMaximumDelay( nDelays + 1 );
  32. jetDelay_.setDelay( 49.0 );
  33. vibrato_.setFrequency( 5.925 );
  34. filter_.setPole( 0.7 - ( 0.1 * 22050.0 / Stk::sampleRate() ) );
  35. dcBlock_.setBlockZero();
  36. adsr_.setAllTimes( 0.005, 0.01, 0.8, 0.010 );
  37. endReflection_ = 0.5;
  38. jetReflection_ = 0.5;
  39. noiseGain_ = 0.15; // Breath pressure random component.
  40. vibratoGain_ = 0.05; // Breath periodic vibrato component.
  41. jetRatio_ = 0.32;
  42. maxPressure_ = 0.0;
  43. this->clear();
  44. this->setFrequency( 220.0 );
  45. }
  46. Flute :: ~Flute( void )
  47. {
  48. }
  49. void Flute :: clear( void )
  50. {
  51. jetDelay_.clear();
  52. boreDelay_.clear();
  53. filter_.clear();
  54. dcBlock_.clear();
  55. }
  56. void Flute :: setFrequency( StkFloat frequency )
  57. {
  58. #if defined(_STK_DEBUG_)
  59. if ( frequency <= 0.0 ) {
  60. oStream_ << "Flute::setFrequency: argument is less than or equal to zero!";
  61. handleError( StkError::WARNING ); return;
  62. }
  63. #endif
  64. // We're overblowing here.
  65. lastFrequency_ = frequency * 0.66666;
  66. // Account for filter delay and one sample "lastOut" delay
  67. // (previously approximated as 2.0 samples). The tuning is still
  68. // not perfect but I'm not sure why. Also, we are not accounting
  69. // for the dc blocking filter delay.
  70. StkFloat delay = Stk::sampleRate() / lastFrequency_ - filter_.phaseDelay( lastFrequency_ ) - 1.0;
  71. boreDelay_.setDelay( delay );
  72. jetDelay_.setDelay( delay * jetRatio_ );
  73. }
  74. void Flute :: setJetDelay( StkFloat aRatio )
  75. {
  76. jetRatio_ = aRatio;
  77. jetDelay_.setDelay( boreDelay_.getDelay() * aRatio ); // Scaled by ratio.
  78. }
  79. void Flute :: startBlowing( StkFloat amplitude, StkFloat rate )
  80. {
  81. if ( amplitude <= 0.0 || rate <= 0.0 ) {
  82. oStream_ << "Flute::startBlowing: one or more arguments is less than or equal to zero!";
  83. handleError( StkError::WARNING ); return;
  84. }
  85. adsr_.setAttackRate( rate );
  86. maxPressure_ = amplitude / (StkFloat) 0.8;
  87. adsr_.keyOn();
  88. }
  89. void Flute :: stopBlowing( StkFloat rate )
  90. {
  91. if ( rate <= 0.0 ) {
  92. oStream_ << "Flute::stopBlowing: argument is less than or equal to zero!";
  93. handleError( StkError::WARNING ); return;
  94. }
  95. adsr_.setReleaseRate( rate );
  96. adsr_.keyOff();
  97. }
  98. void Flute :: noteOn( StkFloat frequency, StkFloat amplitude )
  99. {
  100. this->setFrequency( frequency );
  101. this->startBlowing( 1.1 + (amplitude * 0.20), amplitude * 0.02 );
  102. outputGain_ = amplitude + 0.001;
  103. }
  104. void Flute :: noteOff( StkFloat amplitude )
  105. {
  106. this->stopBlowing( amplitude * 0.02 );
  107. }
  108. void Flute :: controlChange( int number, StkFloat value )
  109. {
  110. #if defined(_STK_DEBUG_)
  111. if ( Stk::inRange( value, 0.0, 128.0 ) == false ) {
  112. oStream_ << "Flute::controlChange: value (" << value << ") is out of range!";
  113. handleError( StkError::WARNING ); return;
  114. }
  115. #endif
  116. StkFloat normalizedValue = value * ONE_OVER_128;
  117. if (number == __SK_JetDelay_) // 2
  118. this->setJetDelay( (StkFloat) (0.08 + (0.48 * normalizedValue)) );
  119. else if (number == __SK_NoiseLevel_) // 4
  120. noiseGain_ = ( normalizedValue * 0.4);
  121. else if (number == __SK_ModFrequency_) // 11
  122. vibrato_.setFrequency( normalizedValue * 12.0);
  123. else if (number == __SK_ModWheel_) // 1
  124. vibratoGain_ = ( normalizedValue * 0.4 );
  125. else if (number == __SK_AfterTouch_Cont_) // 128
  126. adsr_.setTarget( normalizedValue );
  127. #if defined(_STK_DEBUG_)
  128. else {
  129. oStream_ << "Flute::controlChange: undefined control number (" << number << ")!";
  130. handleError( StkError::WARNING );
  131. }
  132. #endif
  133. }
  134. } // stk namespace