| 
							- /*
 -   ZynAddSubFX - a software synthesizer
 - 
 -   LFO.cpp - LFO implementation
 -   Copyright (C) 2002-2005 Nasca Octavian Paul
 -   Author: Nasca Octavian Paul
 - 
 -   This program is free software; you can redistribute it and/or modify
 -   it under the terms of version 2 of the GNU General Public License
 -   as published by the Free Software Foundation.
 - 
 -   This program 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 (version 2 or later) for more details.
 - 
 -   You should have received a copy of the GNU General Public License (version 2)
 -   along with this program; if not, write to the Free Software Foundation,
 -   Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 - 
 - */
 - 
 - #include "LFO.h"
 - #include "../Misc/Util.h"
 - 
 - #include <stdlib.h>
 - #include <stdio.h>
 - #include <math.h>
 - 
 - LFO::LFO(LFOParams *lfopars, float basefreq)
 - {
 -     if(lfopars->Pstretch == 0)
 -         lfopars->Pstretch = 1;
 -     float lfostretch = powf(basefreq / 440.0f,
 -                             (lfopars->Pstretch - 64.0f) / 63.0f);           //max 2x/octave
 - 
 -     float lfofreq =
 -         (powf(2, lfopars->Pfreq * 10.0f) - 1.0f) / 12.0f * lfostretch;
 -     incx = fabs(lfofreq) * synth->buffersize_f / synth->samplerate_f;
 - 
 -     if(lfopars->Pcontinous == 0) {
 -         if(lfopars->Pstartphase == 0)
 -             x = RND;
 -         else
 -             x = fmod((lfopars->Pstartphase - 64.0f) / 127.0f + 1.0f, 1.0f);
 -     }
 -     else {
 -         float tmp = fmod(lfopars->time * incx, 1.0f);
 -         x = fmod((lfopars->Pstartphase - 64.0f) / 127.0f + 1.0f + tmp, 1.0f);
 -     }
 - 
 -     //Limit the Frequency(or else...)
 -     if(incx > 0.49999999f)
 -         incx = 0.499999999f;
 - 
 - 
 -     lfornd = lfopars->Prandomness / 127.0f;
 -     if(lfornd < 0.0f)
 -         lfornd = 0.0f;
 -     else
 -     if(lfornd > 1.0f)
 -         lfornd = 1.0f;
 - 
 - //    lfofreqrnd=powf(lfopars->Pfreqrand/127.0f,2.0f)*2.0f*4.0f;
 -     lfofreqrnd = powf(lfopars->Pfreqrand / 127.0f, 2.0f) * 4.0f;
 - 
 -     switch(lfopars->fel) {
 -         case 1:
 -             lfointensity = lfopars->Pintensity / 127.0f;
 -             break;
 -         case 2:
 -             lfointensity = lfopars->Pintensity / 127.0f * 4.0f;
 -             break; //in octave
 -         default:
 -             lfointensity = powf(2, lfopars->Pintensity / 127.0f * 11.0f) - 1.0f; //in centi
 -             x -= 0.25f; //chance the starting phase
 -             break;
 -     }
 - 
 -     amp1     = (1 - lfornd) + lfornd * RND;
 -     amp2     = (1 - lfornd) + lfornd * RND;
 -     lfotype  = lfopars->PLFOtype;
 -     lfodelay = lfopars->Pdelay / 127.0f * 4.0f; //0..4 sec
 -     incrnd   = nextincrnd = 1.0f;
 -     freqrndenabled = (lfopars->Pfreqrand != 0);
 -     computenextincrnd();
 -     computenextincrnd(); //twice because I want incrnd & nextincrnd to be random
 - }
 - 
 - LFO::~LFO()
 - {}
 - 
 - /*
 -  * LFO out
 -  */
 - float LFO::lfoout()
 - {
 -     float out;
 -     switch(lfotype) {
 -         case 1: //LFO_TRIANGLE
 -             if((x >= 0.0f) && (x < 0.25f))
 -                 out = 4.0f * x;
 -             else
 -             if((x > 0.25f) && (x < 0.75f))
 -                 out = 2 - 4 * x;
 -             else
 -                 out = 4.0f * x - 4.0f;
 -             break;
 -         case 2: //LFO_SQUARE
 -             if(x < 0.5f)
 -                 out = -1;
 -             else
 -                 out = 1;
 -             break;
 -         case 3: //LFO_RAMPUP
 -             out = (x - 0.5f) * 2.0f;
 -             break;
 -         case 4: //LFO_RAMPDOWN
 -             out = (0.5f - x) * 2.0f;
 -             break;
 -         case 5: //LFO_EXP_DOWN 1
 -             out = powf(0.05f, x) * 2.0f - 1.0f;
 -             break;
 -         case 6: //LFO_EXP_DOWN 2
 -             out = powf(0.001f, x) * 2.0f - 1.0f;
 -             break;
 -         default:
 -             out = cosf(x * 2.0f * PI); //LFO_SINE
 -     }
 - 
 - 
 -     if((lfotype == 0) || (lfotype == 1))
 -         out *= lfointensity * (amp1 + x * (amp2 - amp1));
 -     else
 -         out *= lfointensity * amp2;
 -     if(lfodelay < 0.00001f) {
 -         if(freqrndenabled == 0)
 -             x += incx;
 -         else {
 -             float tmp = (incrnd * (1.0f - x) + nextincrnd * x);
 -             if(tmp > 1.0f)
 -                 tmp = 1.0f;
 -             else
 -             if(tmp < 0.0f)
 -                 tmp = 0.0f;
 -             x += incx * tmp;
 -         }
 -         if(x >= 1) {
 -             x    = fmod(x, 1.0f);
 -             amp1 = amp2;
 -             amp2 = (1 - lfornd) + lfornd * RND;
 - 
 -             computenextincrnd();
 -         }
 -     }
 -     else
 -         lfodelay -= synth->buffersize_f / synth->samplerate_f;
 -     return out;
 - }
 - 
 - /*
 -  * LFO out (for amplitude)
 -  */
 - float LFO::amplfoout()
 - {
 -     float out;
 -     out = 1.0f - lfointensity + lfoout();
 -     if(out < -1.0f)
 -         out = -1.0f;
 -     else
 -     if(out > 1.0f)
 -         out = 1.0f;
 -     return out;
 - }
 - 
 - 
 - void LFO::computenextincrnd()
 - {
 -     if(freqrndenabled == 0)
 -         return;
 -     incrnd     = nextincrnd;
 -     nextincrnd = powf(0.5f, lfofreqrnd) + RND * (powf(2.0f, lfofreqrnd) - 1.0f);
 - }
 
 
  |