zynaddsubfx

ZynAddSubFX open source synthesizer
Log | Files | Refs | Submodules | LICENSE

EffectLFO.cpp (3011B)


      1 /*
      2   ZynAddSubFX - a software synthesizer
      3 
      4   EffectLFO.cpp - Stereo LFO used by some effects
      5   Copyright (C) 2002-2005 Nasca Octavian Paul
      6   Author: Nasca Octavian Paul
      7 
      8   This program is free software; you can redistribute it and/or
      9   modify it under the terms of the GNU General Public License
     10   as published by the Free Software Foundation; either version 2
     11   of the License, or (at your option) any later version.
     12 */
     13 
     14 #include "EffectLFO.h"
     15 #include "../Misc/Util.h"
     16 
     17 #include <cmath>
     18 #include "../globals.h"
     19 
     20 namespace zyn {
     21 
     22 EffectLFO::EffectLFO(float srate_f, float bufsize_f)
     23     :Pfreq(40),
     24       Prandomness(0),
     25       PLFOtype(0),
     26       Pstereo(64),
     27       xl(0.0f),
     28       xr(0.0f),
     29       ampl1(RND),
     30       ampl2(RND),
     31       ampr1(RND),
     32       ampr2(RND),
     33       lfornd(0.0f),
     34       samplerate_f(srate_f),
     35       buffersize_f(bufsize_f)
     36 {
     37     updateparams();
     38 }
     39 
     40 EffectLFO::~EffectLFO() {}
     41 
     42 //Update the changed parameters
     43 void EffectLFO::updateparams(void)
     44 {
     45     float lfofreq = (powf(2.0f, Pfreq / 127.0f * 10.0f) - 1.0f) * 0.03f;
     46     incx = fabsf(lfofreq) * buffersize_f / samplerate_f;
     47     if(incx > 0.49999999f)
     48         incx = 0.499999999f;  //Limit the Frequency
     49 
     50     lfornd = Prandomness / 127.0f;
     51     lfornd = (lfornd > 1.0f) ? 1.0f : lfornd;
     52 
     53     if(PLFOtype > 1)
     54         PLFOtype = 1;  //this has to be updated if more lfo's are added
     55     lfotype = PLFOtype;
     56     xr      = xl + (Pstereo - 64.0f) / 127.0f + 1.0f;
     57     xr      -= floorf(xr);
     58 }
     59 
     60 
     61 //Compute the shape of the LFO
     62 float EffectLFO::getlfoshape(float x)
     63 {
     64     x = fmodf(x, 1.0f);
     65     float out;
     66     switch(lfotype) {
     67         case 1: //EffectLFO_TRIANGLE
     68             if((x > 0.0f) && (x < 0.25f))
     69                 out = 4.0f * x;
     70             else
     71             if((x > 0.25f) && (x < 0.75f))
     72                 out = 2.0f - 4.0f * x;
     73             else
     74                 out = 4.0f * x - 4.0f;
     75             break;
     76         //when adding more, ensure ::updateparams() gets updated
     77         default:
     78             out = cosf(x * 2.0f * PI); //EffectLFO_SINE // TODO: use M_PI ?
     79     }
     80     return out;
     81 }
     82 
     83 //LFO output
     84 void EffectLFO::effectlfoout(float *outl, float *outr, float phaseOffset)
     85 {
     86     float out;
     87     // left stereo signal
     88     out = getlfoshape(xl+phaseOffset);
     89     if((lfotype == 0) || (lfotype == 1))
     90         out *= (ampl1 + xl * (ampl2 - ampl1));
     91     *outl = (out + 1.0f) * 0.5f;
     92     // update left phase for master lfo
     93     if(phaseOffset==0.0f) {
     94         xl += incx;
     95         if(xl > 1.0f) {
     96             xl   -= 1.0f;
     97             ampl1 = ampl2;
     98             ampl2 = (1.0f - lfornd) + lfornd * RND;
     99         }
    100     }
    101 
    102     // right stereo signal
    103     out = getlfoshape(xr+phaseOffset);
    104     if((lfotype == 0) || (lfotype == 1))
    105         out *= (ampr1 + xr * (ampr2 - ampr1));
    106     *outr = (out + 1.0f) * 0.5f;
    107 
    108     // update right phase for master lfo
    109     if(phaseOffset==0.0f) {
    110         xr += incx;
    111         if(xr > 1.0f) {
    112             xr   -= 1.0f;
    113             ampr1 = ampr2;
    114             ampr2 = (1.0f - lfornd) + lfornd * RND;
    115         }
    116     }
    117 
    118 }
    119 
    120 }