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.

182 lines
4.3KB

  1. /***************************************************/
  2. /*! \class ADSR
  3. \brief STK ADSR envelope class.
  4. This class implements a traditional ADSR (Attack, Decay, Sustain,
  5. Release) envelope. It responds to simple keyOn and keyOff
  6. messages, keeping track of its state. The \e state = ADSR::IDLE
  7. before being triggered and after the envelope value reaches 0.0 in
  8. the ADSR::RELEASE state. All rate, target and level settings must
  9. be non-negative. All time settings must be positive.
  10. by Perry R. Cook and Gary P. Scavone, 1995--2017.
  11. */
  12. /***************************************************/
  13. #include "ADSR.h"
  14. namespace stk {
  15. ADSR :: ADSR( void )
  16. {
  17. target_ = 0.0;
  18. value_ = 0.0;
  19. attackRate_ = 0.001;
  20. decayRate_ = 0.001;
  21. releaseRate_ = 0.005;
  22. releaseTime_ = -1.0;
  23. sustainLevel_ = 0.5;
  24. state_ = IDLE;
  25. Stk::addSampleRateAlert( this );
  26. }
  27. ADSR :: ~ADSR( void )
  28. {
  29. Stk::removeSampleRateAlert( this );
  30. }
  31. void ADSR :: sampleRateChanged( StkFloat newRate, StkFloat oldRate )
  32. {
  33. if ( !ignoreSampleRateChange_ ) {
  34. attackRate_ = oldRate * attackRate_ / newRate;
  35. decayRate_ = oldRate * decayRate_ / newRate;
  36. releaseRate_ = oldRate * releaseRate_ / newRate;
  37. }
  38. }
  39. void ADSR :: keyOn()
  40. {
  41. if ( target_ <= 0.0 ) target_ = 1.0;
  42. state_ = ATTACK;
  43. }
  44. void ADSR :: keyOff()
  45. {
  46. target_ = 0.0;
  47. state_ = RELEASE;
  48. // FIXED October 2010 - Nick Donaldson
  49. // Need to make release rate relative to current value!!
  50. // Only update if we have set a TIME rather than a RATE,
  51. // in which case releaseTime_ will be -1
  52. if ( releaseTime_ > 0.0 )
  53. releaseRate_ = value_ / ( releaseTime_ * Stk::sampleRate() );
  54. }
  55. void ADSR :: setAttackRate( StkFloat rate )
  56. {
  57. if ( rate < 0.0 ) {
  58. oStream_ << "ADSR::setAttackRate: argument must be >= 0.0!";
  59. handleError( StkError::WARNING ); return;
  60. }
  61. attackRate_ = rate;
  62. }
  63. void ADSR :: setAttackTarget( StkFloat target )
  64. {
  65. if ( target < 0.0 ) {
  66. oStream_ << "ADSR::setAttackTarget: negative target not allowed!";
  67. handleError( StkError::WARNING ); return;
  68. }
  69. target_ = target;
  70. }
  71. void ADSR :: setDecayRate( StkFloat rate )
  72. {
  73. if ( rate < 0.0 ) {
  74. oStream_ << "ADSR::setDecayRate: negative rates not allowed!";
  75. handleError( StkError::WARNING ); return;
  76. }
  77. decayRate_ = rate;
  78. }
  79. void ADSR :: setSustainLevel( StkFloat level )
  80. {
  81. if ( level < 0.0 ) {
  82. oStream_ << "ADSR::setSustainLevel: negative level not allowed!";
  83. handleError( StkError::WARNING ); return;
  84. }
  85. sustainLevel_ = level;
  86. }
  87. void ADSR :: setReleaseRate( StkFloat rate )
  88. {
  89. if ( rate < 0.0 ) {
  90. oStream_ << "ADSR::setReleaseRate: negative rates not allowed!";
  91. handleError( StkError::WARNING ); return;
  92. }
  93. releaseRate_ = rate;
  94. // Set to negative value so we don't update the release rate on keyOff()
  95. releaseTime_ = -1.0;
  96. }
  97. void ADSR :: setAttackTime( StkFloat time )
  98. {
  99. if ( time <= 0.0 ) {
  100. oStream_ << "ADSR::setAttackTime: negative or zero times not allowed!";
  101. handleError( StkError::WARNING ); return;
  102. }
  103. attackRate_ = 1.0 / ( time * Stk::sampleRate() );
  104. }
  105. void ADSR :: setDecayTime( StkFloat time )
  106. {
  107. if ( time <= 0.0 ) {
  108. oStream_ << "ADSR::setDecayTime: negative or zero times not allowed!";
  109. handleError( StkError::WARNING ); return;
  110. }
  111. decayRate_ = (1.0 - sustainLevel_) / ( time * Stk::sampleRate() );
  112. }
  113. void ADSR :: setReleaseTime( StkFloat time )
  114. {
  115. if ( time <= 0.0 ) {
  116. oStream_ << "ADSR::setReleaseTime: negative or zero times not allowed!";
  117. handleError( StkError::WARNING ); return;
  118. }
  119. releaseRate_ = sustainLevel_ / ( time * Stk::sampleRate() );
  120. releaseTime_ = time;
  121. }
  122. void ADSR :: setAllTimes( StkFloat aTime, StkFloat dTime, StkFloat sLevel, StkFloat rTime )
  123. {
  124. this->setAttackTime( aTime );
  125. this->setSustainLevel( sLevel );
  126. this->setDecayTime( dTime );
  127. this->setReleaseTime( rTime );
  128. }
  129. void ADSR :: setTarget( StkFloat target )
  130. {
  131. if ( target < 0.0 ) {
  132. oStream_ << "ADSR::setTarget: negative target not allowed!";
  133. handleError( StkError::WARNING ); return;
  134. }
  135. target_ = target;
  136. this->setSustainLevel( target_ );
  137. if ( value_ < target_ ) state_ = ATTACK;
  138. if ( value_ > target_ ) state_ = DECAY;
  139. }
  140. void ADSR :: setValue( StkFloat value )
  141. {
  142. state_ = SUSTAIN;
  143. target_ = value;
  144. value_ = value;
  145. this->setSustainLevel( value );
  146. lastFrame_[0] = value;
  147. }
  148. } // stk namespace