f@5: /*
f@5:
f@5: Copyright (C) 2016 Queen Mary University of London
f@5: Author: Fiore Martin
f@5:
f@5: This file is part of Collidoscope.
f@5:
f@5: Collidoscope is free software: you can redistribute it and/or modify
f@5: it under the terms of the GNU General Public License as published by
f@5: the Free Software Foundation, either version 3 of the License, or
f@5: (at your option) any later version.
f@5:
f@5: This program is distributed in the hope that it will be useful,
f@5: but WITHOUT ANY WARRANTY; without even the implied warranty of
f@5: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
f@5: GNU General Public License for more details.
f@5:
f@5: You should have received a copy of the GNU General Public License
f@5: along with this program. If not, see .
f@5: */
f@5:
f@0: #pragma once
f@0:
f@0: namespace collidoscope {
f@0:
f@2:
f@2: /*
f@2: * An ASR envelope with linear shape. It is modeled after the STK envelope classes.
f@2: * The tick() method advances the computation of the envelope one sample and returns the computed sample
f@2: * The class is templated for the type of the samples that each tick of the envelope produces.
f@2: *
f@2: * Client classes can set/get the current state of the envelope with the
f@2: * respective getter/setter methods
f@2: *
f@2: */
f@0: template
f@0: class EnvASR
f@0: {
f@0: public:
f@0:
f@3: /** Possible states of the envelope. Idle means the envelope ouputs 0 */
f@0: enum class State {
f@0: eAttack,
f@0: eSustain,
f@0: eRelease,
f@0: eIdle // before attack after release
f@0: };
f@0:
f@0: EnvASR( T sustainLevel, T attackTime, T releaseTime, std::size_t sampleRate ) :
f@0: mSustainLevel( sustainLevel ),
f@0: mState( State::eIdle ),
f@0: mValue( 0 )
f@0:
f@0: {
f@0: if ( attackTime <= 0 )
f@0: attackTime = T( 0.001 );
f@0:
f@0: if ( releaseTime <= 0 )
f@0: releaseTime = T( 0.001 );
f@0:
f@0: mAttackRate = T( 1.0 ) / (attackTime * sampleRate);
f@0: mReleaseRate = T( 1.0 ) / (releaseTime * sampleRate);
f@0: }
f@0:
f@3: /** Produces one sample worth of envelope */
f@0: T tick()
f@0: {
f@0:
f@0: switch ( mState )
f@0: {
f@0:
f@0: case State::eIdle: {
f@0: mValue = 0;
f@0: };
f@0: break;
f@0:
f@0: case State::eAttack: {
f@0: mValue += mAttackRate;
f@0: if ( mValue >= mSustainLevel ){
f@0: mValue = mSustainLevel;
f@0: mState = State::eSustain;
f@0: }
f@0: };
f@0: break;
f@0:
f@0: case State::eRelease:
f@0: mValue -= mReleaseRate;
f@0: if ( mValue <= 0 ){
f@0: mValue = 0;
f@0: mState = State::eIdle;
f@0: }
f@0: break;
f@0: default:
f@0: break;
f@0: }
f@0:
f@0: return mValue;
f@0:
f@0: }
f@0:
f@0: State getState() const
f@0: {
f@0: return mState;
f@0: }
f@0:
f@0: void setState( State state )
f@0: {
f@0: mState = state;
f@0: }
f@0:
f@0: private:
f@0: T mSustainLevel;
f@0: T mAttackRate;
f@0: T mReleaseRate;
f@0:
f@0: // output
f@0: T mValue;
f@0:
f@0: State mState;
f@0:
f@0: };
f@0:
f@0:
f@2: }