diff stk/src/ADSR.cpp @ 0:4606bd505630 tip

first import
author Fiore Martin <f.martin@qmul.ac.uk>
date Sat, 13 Jun 2015 15:08:10 +0100
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stk/src/ADSR.cpp	Sat Jun 13 15:08:10 2015 +0100
@@ -0,0 +1,180 @@
+/***************************************************/
+/*! \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--2014.
+*/
+/***************************************************/
+
+#include "../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 )
+{
+}
+
+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