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.

181 lines
4.2KB

  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-2011.
  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. }
  30. void ADSR :: sampleRateChanged( StkFloat newRate, StkFloat oldRate )
  31. {
  32. if ( !ignoreSampleRateChange_ ) {
  33. attackRate_ = oldRate * attackRate_ / newRate;
  34. decayRate_ = oldRate * decayRate_ / newRate;
  35. releaseRate_ = oldRate * releaseRate_ / newRate;
  36. }
  37. }
  38. void ADSR :: keyOn()
  39. {
  40. if ( target_ <= 0.0 ) target_ = 1.0;
  41. state_ = ATTACK;
  42. }
  43. void ADSR :: keyOff()
  44. {
  45. target_ = 0.0;
  46. state_ = RELEASE;
  47. // FIXED October 2010 - Nick Donaldson
  48. // Need to make release rate relative to current value!!
  49. // Only update if we have set a TIME rather than a RATE,
  50. // in which case releaseTime_ will be -1
  51. if ( releaseTime_ > 0.0 )
  52. releaseRate_ = value_ / ( releaseTime_ * Stk::sampleRate() );
  53. }
  54. void ADSR :: setAttackRate( StkFloat rate )
  55. {
  56. if ( rate < 0.0 ) {
  57. oStream_ << "ADSR::setAttackRate: argument must be >= 0.0!";
  58. handleError( StkError::WARNING ); return;
  59. }
  60. attackRate_ = rate;
  61. }
  62. void ADSR :: setAttackTarget( StkFloat target )
  63. {
  64. if ( target < 0.0 ) {
  65. oStream_ << "ADSR::setAttackTarget: negative target not allowed!";
  66. handleError( StkError::WARNING ); return;
  67. }
  68. target_ = target;
  69. }
  70. void ADSR :: setDecayRate( StkFloat rate )
  71. {
  72. if ( rate < 0.0 ) {
  73. oStream_ << "ADSR::setDecayRate: negative rates not allowed!";
  74. handleError( StkError::WARNING ); return;
  75. }
  76. decayRate_ = rate;
  77. }
  78. void ADSR :: setSustainLevel( StkFloat level )
  79. {
  80. if ( level < 0.0 ) {
  81. oStream_ << "ADSR::setSustainLevel: negative level not allowed!";
  82. handleError( StkError::WARNING ); return;
  83. }
  84. sustainLevel_ = level;
  85. }
  86. void ADSR :: setReleaseRate( StkFloat rate )
  87. {
  88. if ( rate < 0.0 ) {
  89. oStream_ << "ADSR::setReleaseRate: negative rates not allowed!";
  90. handleError( StkError::WARNING ); return;
  91. }
  92. releaseRate_ = rate;
  93. // Set to negative value so we don't update the release rate on keyOff()
  94. releaseTime_ = -1.0;
  95. }
  96. void ADSR :: setAttackTime( StkFloat time )
  97. {
  98. if ( time <= 0.0 ) {
  99. oStream_ << "ADSR::setAttackTime: negative or zero times not allowed!";
  100. handleError( StkError::WARNING ); return;
  101. }
  102. attackRate_ = 1.0 / ( time * Stk::sampleRate() );
  103. }
  104. void ADSR :: setDecayTime( StkFloat time )
  105. {
  106. if ( time <= 0.0 ) {
  107. oStream_ << "ADSR::setDecayTime: negative or zero times not allowed!";
  108. handleError( StkError::WARNING ); return;
  109. }
  110. decayRate_ = (1.0 - sustainLevel_) / ( time * Stk::sampleRate() );
  111. }
  112. void ADSR :: setReleaseTime( StkFloat time )
  113. {
  114. if ( time <= 0.0 ) {
  115. oStream_ << "ADSR::setReleaseTime: negative or zero times not allowed!";
  116. handleError( StkError::WARNING ); return;
  117. }
  118. releaseRate_ = sustainLevel_ / ( time * Stk::sampleRate() );
  119. releaseTime_ = time;
  120. }
  121. void ADSR :: setAllTimes( StkFloat aTime, StkFloat dTime, StkFloat sLevel, StkFloat rTime )
  122. {
  123. this->setAttackTime( aTime );
  124. this->setDecayTime( dTime );
  125. this->setSustainLevel( sLevel );
  126. this->setReleaseTime( rTime );
  127. }
  128. void ADSR :: setTarget( StkFloat target )
  129. {
  130. if ( target < 0.0 ) {
  131. oStream_ << "ADSR::setTarget: negative target not allowed!";
  132. handleError( StkError::WARNING ); return;
  133. }
  134. target_ = target;
  135. this->setSustainLevel( target_ );
  136. if ( value_ < target_ ) state_ = ATTACK;
  137. if ( value_ > target_ ) state_ = DECAY;
  138. }
  139. void ADSR :: setValue( StkFloat value )
  140. {
  141. state_ = SUSTAIN;
  142. target_ = value;
  143. value_ = value;
  144. this->setSustainLevel( value );
  145. lastFrame_[0] = value;
  146. }
  147. } // stk namespace