|
- /***************************************************/
- /*! \class ADSR
- \brief STK ADSR envelope class.
-
- This class implements a traditional ADSR (Attack, Decay, Sustain,
- Release) envelope. It responds to simple keyOn and keyOff
- messages, keeping track of its state. The \e state = ADSR::IDLE
- before being triggered and after the envelope value reaches 0.0 in
- the ADSR::RELEASE state. All rate, target and level settings must
- be non-negative. All time settings must be positive.
-
- by Perry R. Cook and Gary P. Scavone, 1995--2017.
- */
- /***************************************************/
-
- #include "ADSR.h"
-
- namespace stk {
-
- ADSR :: ADSR( void )
- {
- target_ = 0.0;
- value_ = 0.0;
- attackRate_ = 0.001;
- decayRate_ = 0.001;
- releaseRate_ = 0.005;
- releaseTime_ = -1.0;
- sustainLevel_ = 0.5;
- state_ = IDLE;
- Stk::addSampleRateAlert( this );
- }
-
- ADSR :: ~ADSR( void )
- {
- Stk::removeSampleRateAlert( this );
- }
-
- void ADSR :: sampleRateChanged( StkFloat newRate, StkFloat oldRate )
- {
- if ( !ignoreSampleRateChange_ ) {
- attackRate_ = oldRate * attackRate_ / newRate;
- decayRate_ = oldRate * decayRate_ / newRate;
- releaseRate_ = oldRate * releaseRate_ / newRate;
- }
- }
-
- void ADSR :: keyOn()
- {
- if ( target_ <= 0.0 ) target_ = 1.0;
- state_ = ATTACK;
- }
-
- void ADSR :: keyOff()
- {
- target_ = 0.0;
- state_ = RELEASE;
-
- // FIXED October 2010 - Nick Donaldson
- // Need to make release rate relative to current value!!
- // Only update if we have set a TIME rather than a RATE,
- // in which case releaseTime_ will be -1
- if ( releaseTime_ > 0.0 )
- releaseRate_ = value_ / ( releaseTime_ * Stk::sampleRate() );
- }
-
- void ADSR :: setAttackRate( StkFloat rate )
- {
- if ( rate < 0.0 ) {
- oStream_ << "ADSR::setAttackRate: argument must be >= 0.0!";
- handleError( StkError::WARNING ); return;
- }
-
- attackRate_ = rate;
- }
-
- void ADSR :: setAttackTarget( StkFloat target )
- {
- if ( target < 0.0 ) {
- oStream_ << "ADSR::setAttackTarget: negative target not allowed!";
- handleError( StkError::WARNING ); return;
- }
-
- target_ = target;
- }
-
- void ADSR :: setDecayRate( StkFloat rate )
- {
- if ( rate < 0.0 ) {
- oStream_ << "ADSR::setDecayRate: negative rates not allowed!";
- handleError( StkError::WARNING ); return;
- }
-
- decayRate_ = rate;
- }
-
- void ADSR :: setSustainLevel( StkFloat level )
- {
- if ( level < 0.0 ) {
- oStream_ << "ADSR::setSustainLevel: negative level not allowed!";
- handleError( StkError::WARNING ); return;
- }
-
- sustainLevel_ = level;
- }
-
- void ADSR :: setReleaseRate( StkFloat rate )
- {
- if ( rate < 0.0 ) {
- oStream_ << "ADSR::setReleaseRate: negative rates not allowed!";
- handleError( StkError::WARNING ); return;
- }
-
- releaseRate_ = rate;
-
- // Set to negative value so we don't update the release rate on keyOff()
- releaseTime_ = -1.0;
- }
-
- void ADSR :: setAttackTime( StkFloat time )
- {
- if ( time <= 0.0 ) {
- oStream_ << "ADSR::setAttackTime: negative or zero times not allowed!";
- handleError( StkError::WARNING ); return;
- }
-
- attackRate_ = 1.0 / ( time * Stk::sampleRate() );
- }
-
- void ADSR :: setDecayTime( StkFloat time )
- {
- if ( time <= 0.0 ) {
- oStream_ << "ADSR::setDecayTime: negative or zero times not allowed!";
- handleError( StkError::WARNING ); return;
- }
-
- decayRate_ = (1.0 - sustainLevel_) / ( time * Stk::sampleRate() );
- }
-
- void ADSR :: setReleaseTime( StkFloat time )
- {
- if ( time <= 0.0 ) {
- oStream_ << "ADSR::setReleaseTime: negative or zero times not allowed!";
- handleError( StkError::WARNING ); return;
- }
-
- releaseRate_ = sustainLevel_ / ( time * Stk::sampleRate() );
- releaseTime_ = time;
- }
-
- void ADSR :: setAllTimes( StkFloat aTime, StkFloat dTime, StkFloat sLevel, StkFloat rTime )
- {
- this->setAttackTime( aTime );
- this->setSustainLevel( sLevel );
- this->setDecayTime( dTime );
- this->setReleaseTime( rTime );
- }
-
- void ADSR :: setTarget( StkFloat target )
- {
- if ( target < 0.0 ) {
- oStream_ << "ADSR::setTarget: negative target not allowed!";
- handleError( StkError::WARNING ); return;
- }
-
- target_ = target;
-
- this->setSustainLevel( target_ );
- if ( value_ < target_ ) state_ = ATTACK;
- if ( value_ > target_ ) state_ = DECAY;
- }
-
- void ADSR :: setValue( StkFloat value )
- {
- state_ = SUSTAIN;
- target_ = value;
- value_ = value;
- this->setSustainLevel( value );
- lastFrame_[0] = value;
- }
-
- } // stk namespace
|