--- linuxsampler/trunk/src/engines/gig/EGDecay.h 2005/02/26 02:01:14 411 +++ linuxsampler/trunk/src/engines/gig/EGDecay.h 2005/08/16 17:14:25 738 @@ -5,18 +5,18 @@ * Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck * * Copyright (C) 2005 Christian Schoenebeck * * * - * This program is free software; you can redistribute it and/or modify * + * This library is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * - * This program is distributed in the hope that it will be useful, * + * This library is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the Free Software * + * along with this library; if not, write to the Free Software * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * * MA 02111-1307 USA * ***************************************************************************/ @@ -25,42 +25,78 @@ #define __LS_GIG_EGDECAY_H__ #include "../../common/global.h" - -#if DEBUG_HEADERS -# warning EGDecay.h included -#endif // DEBUG_HEADERS - #include "../../common/RTMath.h" -#include "../common/Event.h" -#include "Engine.h" namespace LinuxSampler { namespace gig { - // just symbol prototyping - class Engine; - - /** - * Decay Envelope Generator + /** @brief Decay Envelope Generator (linear) * - * Simple Envelope Generator with only one stage: 'Decay'. We currently use - * this specific EG only for pitch and thus it's not generalized yet, means - * the initial envelope level (given by 'Depth') will raise / drop in - * 'DecayTime' seconds to a level of exactly 1.0. If the initial level - * ('Depth') is already 1.0, nothing happens. Beside that, the EG just - * multiplies it's levels to the synthesis parameter sequence. + * Simple Envelope Generator with only one stage: 'Decay' which is a + * linear segment. The initial envelope level (given by 'Depth') will + * raise / drop in 'DecayTime' seconds to a level of exactly 1.0. If + * the initial level ('Depth') is already 1.0, nothing happens. */ class EGDecay { public: - EGDecay(gig::Engine* pEngine, Event::destination_t ModulationDestination); - bool Process(uint Samples); - void Trigger(float Depth, double DecayTime, uint Delay); - protected: - gig::Engine* pEngine; - Event::destination_t ModulationDestination; - uint TriggerDelay; ///< number of sample points triggering should be delayed - float Level; - float DecayCoeff; - long DecayStepsLeft; + EGDecay(); + + /** + * Will be called by the voice when the key / voice was + * triggered and initialize the envelope generator. + * + * @param Depth - initial level of the envelope + * @param DecayTime - decay time of the envelope (0.000 - 10.000s) + * @param SampleRate - sample rate of used audio driver + */ + void trigger(float Depth, float DecayTime, unsigned int SampleRate); //FIXME: we should better use 'float' for SampleRate + + /** + * Returns true if envelope is still in stage 'Decay', returns + * false if end of envelope is reached. + */ + inline bool active() { + return (bool) Coeff; + } + + /** + * Advance envelope by \a SamplePoints steps. + */ + inline void increment(const int SamplePoints) { + StepsLeft = RTMath::Max(0, StepsLeft - SamplePoints); + } + + /** + * Returns amount of steps until end of envelope is reached. + */ + inline int toEndLeft() { + return StepsLeft; + } + + /** + * Should be called once the end of the envelope is reached. It + * will neutralize the envelope coefficient to not alter the + * envelope anymore and will set the output level to final level + * of exactly 1.0f. So after this call, render() can still + * safely be called from the sampler's main synthesis loop. + */ + inline void update() { + Level = 1.0f; + Coeff = 0.0f; + } + + /** + * Calculates exactly one level of the envelope. + * + * @returns next envelope level + */ + inline float render() { + return (Level += Coeff); + } + + private: + float Level; ///< current EG output level + float Coeff; ///< linear coefficient for changing the output level in time + int StepsLeft; ///< how many steps left until end is reached }; }} // namespace LinuxSampler::gig