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.

159 lines
4.0KB

  1. /***************************************************/
  2. /*! \class Brass
  3. \brief STK simple brass instrument class.
  4. This class implements a simple brass instrument
  5. waveguide model, a la Cook (TBone, HosePlayer).
  6. This is a digital waveguide model, making its
  7. use possibly subject to patents held by
  8. Stanford University, Yamaha, and others.
  9. Control Change Numbers:
  10. - Lip Tension = 2
  11. - Slide Length = 4
  12. - Vibrato Frequency = 11
  13. - Vibrato Gain = 1
  14. - Volume = 128
  15. by Perry R. Cook and Gary P. Scavone, 1995--2017.
  16. */
  17. /***************************************************/
  18. #include "Brass.h"
  19. #include "SKINImsg.h"
  20. #include <cmath>
  21. namespace stk {
  22. Brass :: Brass( StkFloat lowestFrequency )
  23. {
  24. if ( lowestFrequency <= 0.0 ) {
  25. oStream_ << "Brass::Brass: argument is less than or equal to zero!";
  26. handleError( StkError::FUNCTION_ARGUMENT );
  27. }
  28. unsigned long nDelays = (unsigned long) ( Stk::sampleRate() / lowestFrequency );
  29. delayLine_.setMaximumDelay( nDelays + 1 );
  30. lipFilter_.setGain( 0.03 );
  31. dcBlock_.setBlockZero();
  32. adsr_.setAllTimes( 0.005, 0.001, 1.0, 0.010 );
  33. vibrato_.setFrequency( 6.137 );
  34. vibratoGain_ = 0.0;
  35. maxPressure_ = 0.0;
  36. lipTarget_ = 0.0;
  37. this->clear();
  38. // This is necessary to initialize variables.
  39. this->setFrequency( 220.0 );
  40. }
  41. Brass :: ~Brass( void )
  42. {
  43. }
  44. void Brass :: clear( void )
  45. {
  46. delayLine_.clear();
  47. lipFilter_.clear();
  48. dcBlock_.clear();
  49. }
  50. void Brass :: setFrequency( StkFloat frequency )
  51. {
  52. #if defined(_STK_DEBUG_)
  53. if ( frequency <= 0.0 ) {
  54. oStream_ << "Brass::setFrequency: argument is less than or equal to zero!";
  55. handleError( StkError::WARNING ); return;
  56. }
  57. #endif
  58. // Fudge correction for filter delays.
  59. slideTarget_ = ( Stk::sampleRate() / frequency * 2.0 ) + 3.0;
  60. delayLine_.setDelay( slideTarget_ ); // play a harmonic
  61. lipTarget_ = frequency;
  62. lipFilter_.setResonance( frequency, 0.997 );
  63. }
  64. void Brass :: setLip( StkFloat frequency )
  65. {
  66. #if defined(_STK_DEBUG_)
  67. if ( frequency <= 0.0 ) {
  68. oStream_ << "Brass::setLip: argument is less than or equal to zero!";
  69. handleError( StkError::WARNING ); return;
  70. }
  71. #endif
  72. lipFilter_.setResonance( frequency, 0.997 );
  73. }
  74. void Brass :: startBlowing( StkFloat amplitude, StkFloat rate )
  75. {
  76. if ( amplitude <= 0.0 || rate <= 0.0 ) {
  77. oStream_ << "Brass::startBlowing: one or more arguments is less than or equal to zero!";
  78. handleError( StkError::WARNING ); return;
  79. }
  80. adsr_.setAttackRate( rate );
  81. maxPressure_ = amplitude;
  82. adsr_.keyOn();
  83. }
  84. void Brass :: stopBlowing( StkFloat rate )
  85. {
  86. if ( rate <= 0.0 ) {
  87. oStream_ << "Brass::stopBlowing: argument is less than or equal to zero!";
  88. handleError( StkError::WARNING ); return;
  89. }
  90. adsr_.setReleaseRate( rate );
  91. adsr_.keyOff();
  92. }
  93. void Brass :: noteOn( StkFloat frequency, StkFloat amplitude )
  94. {
  95. this->setFrequency( frequency );
  96. this->startBlowing( amplitude, amplitude * 0.001 );
  97. }
  98. void Brass :: noteOff( StkFloat amplitude )
  99. {
  100. this->stopBlowing( amplitude * 0.005 );
  101. }
  102. void Brass :: controlChange( int number, StkFloat value )
  103. {
  104. #if defined(_STK_DEBUG_)
  105. if ( Stk::inRange( value, 0.0, 128.0 ) == false ) {
  106. oStream_ << "Brass::controlChange: value (" << value << ") is out of range!";
  107. handleError( StkError::WARNING ); return;
  108. }
  109. #endif
  110. StkFloat normalizedValue = value * ONE_OVER_128;
  111. if (number == __SK_LipTension_) { // 2
  112. StkFloat temp = lipTarget_ * pow( 4.0, (2.0 * normalizedValue) - 1.0 );
  113. this->setLip( temp );
  114. }
  115. else if (number == __SK_SlideLength_) // 4
  116. delayLine_.setDelay( slideTarget_ * (0.5 + normalizedValue) );
  117. else if (number == __SK_ModFrequency_) // 11
  118. vibrato_.setFrequency( normalizedValue * 12.0 );
  119. else if (number == __SK_ModWheel_ ) // 1
  120. vibratoGain_ = normalizedValue * 0.4;
  121. else if (number == __SK_AfterTouch_Cont_) // 128
  122. adsr_.setTarget( normalizedValue );
  123. #if defined(_STK_DEBUG_)
  124. else {
  125. oStream_ << "Brass::controlChange: undefined control number (" << number << ")!";
  126. handleError( StkError::WARNING );
  127. }
  128. #endif
  129. }
  130. } // stk namespace