| 
							- /*
 -   ZynAddSubFX - a software synthesizer
 - 
 -   OscilGen.cpp - Waveform generator for ADnote
 -   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 "OscilGen.h"
 - #include "../Misc/WaveShapeSmps.h"
 - 
 - #include <cassert>
 - #include <stdlib.h>
 - #include <math.h>
 - #include <stdio.h>
 - 
 - 
 - //operations on FFTfreqs
 - inline void clearAll(fft_t *freqs)
 - {
 -     memset(freqs, 0, synth->oscilsize / 2 * sizeof(fft_t));
 - }
 - 
 - inline void clearDC(fft_t *freqs)
 - {
 -     freqs[0] = fft_t(0.0f, 0.0f);
 - }
 - 
 - //return magnitude squared
 - inline float normal(const fft_t *freqs, off_t x)
 - {
 -     return norm(freqs[x]);
 - }
 - 
 - //return magnitude
 - inline float abs(const fft_t *freqs, off_t x)
 - {
 -     return abs(freqs[x]);
 - }
 - 
 - //return angle aka phase from a sine (not cosine wave)
 - inline float arg(const fft_t *freqs, off_t x)
 - {
 -     const fft_t tmp(freqs[x].imag(), freqs[x].real());
 -     return arg(tmp);
 - }
 - 
 - /**
 -  * Take frequency spectrum and ensure values are normalized based upon
 -  * magnitude to 0<=x<=1
 -  */
 - void normalize(fft_t *freqs)
 - {
 -     float normMax = 0.0f;
 -     for(int i = 0; i < synth->oscilsize / 2; ++i) {
 -         //magnitude squared
 -         const float norm = normal(freqs, i);
 -         if(normMax < norm)
 -             normMax = norm;
 -     }
 - 
 -     const float max = sqrt(normMax);
 -     if(max < 1e-8) //data is all ~zero, do not amplify noise
 -         return;
 - 
 -     for(int i = 0; i < synth->oscilsize / 2; ++i)
 -         freqs[i] /= max;
 - }
 - 
 - //Full RMS normalize
 - void rmsNormalize(fft_t *freqs)
 - {
 -     float sum = 0.0f;
 -     for(int i = 1; i < synth->oscilsize / 2; ++i)
 -         sum += normal(freqs, i);
 - 
 -     if(sum < 0.000001f)
 -         return;  //data is all ~zero, do not amplify noise
 - 
 -     const float gain = 1.0f / sqrt(sum);
 - 
 -     for(int i = 1; i < synth->oscilsize / 2; ++i)
 -         freqs[i] *= gain;
 - }
 - 
 - #define DIFF(par) (old ## par != P ## par)
 - 
 - OscilGen::OscilGen(FFTwrapper *fft_, Resonance *res_):Presets()
 - {
 -     assert(fft_);
 - 
 -     setpresettype("Poscilgen");
 -     fft = fft_;
 -     res = res_;
 - 
 - 
 -     tmpsmps = new float[synth->oscilsize];
 -     outoscilFFTfreqs = new fft_t[synth->oscilsize / 2];
 -     oscilFFTfreqs    = new fft_t[synth->oscilsize / 2];
 -     basefuncFFTfreqs = new fft_t[synth->oscilsize / 2];
 - 
 -     randseed = 1;
 -     ADvsPAD  = false;
 - 
 -     defaults();
 - }
 - 
 - OscilGen::~OscilGen()
 - {
 -     delete[] tmpsmps;
 -     delete[] outoscilFFTfreqs;
 -     delete[] basefuncFFTfreqs;
 -     delete[] oscilFFTfreqs;
 - }
 - 
 - 
 - void OscilGen::defaults()
 - {
 -     oldbasefunc = 0;
 -     oldbasepar  = 64;
 -     oldhmagtype = 0;
 -     oldwaveshapingfunction = 0;
 -     oldwaveshaping = 64;
 -     oldbasefuncmodulation     = 0;
 -     oldharmonicshift          = 0;
 -     oldbasefuncmodulationpar1 = 0;
 -     oldbasefuncmodulationpar2 = 0;
 -     oldbasefuncmodulationpar3 = 0;
 -     oldmodulation     = 0;
 -     oldmodulationpar1 = 0;
 -     oldmodulationpar2 = 0;
 -     oldmodulationpar3 = 0;
 - 
 -     for(int i = 0; i < MAX_AD_HARMONICS; ++i) {
 -         hmag[i]    = 0.0f;
 -         hphase[i]  = 0.0f;
 -         Phmag[i]   = 64;
 -         Phphase[i] = 64;
 -     }
 -     Phmag[0]  = 127;
 -     Phmagtype = 0;
 -     if(ADvsPAD)
 -         Prand = 127;       //max phase randomness (usefull if the oscil will be imported to a ADsynth from a PADsynth
 -     else
 -         Prand = 64;  //no randomness
 - 
 -     Pcurrentbasefunc = 0;
 -     Pbasefuncpar     = 64;
 - 
 -     Pbasefuncmodulation     = 0;
 -     Pbasefuncmodulationpar1 = 64;
 -     Pbasefuncmodulationpar2 = 64;
 -     Pbasefuncmodulationpar3 = 32;
 - 
 -     Pmodulation     = 0;
 -     Pmodulationpar1 = 64;
 -     Pmodulationpar2 = 64;
 -     Pmodulationpar3 = 32;
 - 
 -     Pwaveshapingfunction = 0;
 -     Pwaveshaping    = 64;
 -     Pfiltertype     = 0;
 -     Pfilterpar1     = 64;
 -     Pfilterpar2     = 64;
 -     Pfilterbeforews = 0;
 -     Psatype = 0;
 -     Psapar  = 64;
 - 
 -     Pamprandpower = 64;
 -     Pamprandtype  = 0;
 - 
 -     Pharmonicshift      = 0;
 -     Pharmonicshiftfirst = 0;
 - 
 -     Padaptiveharmonics         = 0;
 -     Padaptiveharmonicspower    = 100;
 -     Padaptiveharmonicsbasefreq = 128;
 -     Padaptiveharmonicspar      = 50;
 - 
 -     clearAll(oscilFFTfreqs);
 -     clearAll(basefuncFFTfreqs);
 -     oscilprepared = 0;
 -     oldfilterpars = 0;
 -     oldsapars     = 0;
 -     prepare();
 - }
 - 
 - void OscilGen::convert2sine()
 - {
 -     float  mag[MAX_AD_HARMONICS], phase[MAX_AD_HARMONICS];
 -     float  oscil[synth->oscilsize];
 -     fft_t *freqs = new fft_t[synth->oscilsize / 2];
 - 
 -     get(oscil, -1.0f);
 -     FFTwrapper *fft = new FFTwrapper(synth->oscilsize);
 -     fft->smps2freqs(oscil, freqs);
 -     delete (fft);
 - 
 -     normalize(freqs);
 - 
 -     mag[0]   = 0;
 -     phase[0] = 0;
 -     for(int i = 0; i < MAX_AD_HARMONICS; ++i) {
 -         mag[i]   = abs(freqs, i + 1);
 -         phase[i] = arg(freqs, i + 1);
 -     }
 - 
 -     defaults();
 - 
 -     for(int i = 0; i < MAX_AD_HARMONICS - 1; ++i) {
 -         float newmag   = mag[i];
 -         float newphase = phase[i];
 - 
 -         Phmag[i] = (int) ((newmag) * 64.0f) + 64;
 - 
 -         Phphase[i] = 64 - (int) (64.0f * newphase / PI);
 -         if(Phphase[i] > 127)
 -             Phphase[i] = 127;
 - 
 -         if(Phmag[i] == 64)
 -             Phphase[i] = 64;
 -     }
 -     delete[] freqs;
 -     prepare();
 - }
 - 
 - /*
 -  * Get the base function
 -  */
 - void OscilGen::getbasefunction(float *smps)
 - {
 -     int   i;
 -     float par = (Pbasefuncpar + 0.5f) / 128.0f;
 -     if(Pbasefuncpar == 64)
 -         par = 0.5f;
 - 
 -     float basefuncmodulationpar1 = Pbasefuncmodulationpar1 / 127.0f,
 -           basefuncmodulationpar2 = Pbasefuncmodulationpar2 / 127.0f,
 -           basefuncmodulationpar3 = Pbasefuncmodulationpar3 / 127.0f;
 - 
 -     switch(Pbasefuncmodulation) {
 -         case 1:
 -             basefuncmodulationpar1 =
 -                 (powf(2, basefuncmodulationpar1 * 5.0f) - 1.0f) / 10.0f;
 -             basefuncmodulationpar3 =
 -                 floor((powf(2, basefuncmodulationpar3 * 5.0f) - 1.0f));
 -             if(basefuncmodulationpar3 < 0.9999f)
 -                 basefuncmodulationpar3 = -1.0f;
 -             break;
 -         case 2:
 -             basefuncmodulationpar1 =
 -                 (powf(2, basefuncmodulationpar1 * 5.0f) - 1.0f) / 10.0f;
 -             basefuncmodulationpar3 = 1.0f
 -                                      + floor((powf(2, basefuncmodulationpar3
 -                                                    * 5.0f) - 1.0f));
 -             break;
 -         case 3:
 -             basefuncmodulationpar1 =
 -                 (powf(2, basefuncmodulationpar1 * 7.0f) - 1.0f) / 10.0f;
 -             basefuncmodulationpar3 = 0.01f
 -                                      + (powf(2, basefuncmodulationpar3
 -                                              * 16.0f) - 1.0f) / 10.0f;
 -             break;
 -     }
 - 
 -     base_func func = getBaseFunction(Pcurrentbasefunc);
 - 
 -     for(i = 0; i < synth->oscilsize; ++i) {
 -         float t = i * 1.0f / synth->oscilsize;
 - 
 -         switch(Pbasefuncmodulation) {
 -             case 1:
 -                 t = t * basefuncmodulationpar3 + sinf(
 -                     (t
 -                      + basefuncmodulationpar2) * 2.0f
 -                     * PI) * basefuncmodulationpar1;                              //rev
 -                 break;
 -             case 2:
 -                 t = t + sinf(
 -                     (t * basefuncmodulationpar3
 -                      + basefuncmodulationpar2) * 2.0f
 -                     * PI) * basefuncmodulationpar1;                              //sine
 -                 break;
 -             case 3:
 -                 t = t + powf((1.0f - cosf(
 -                                   (t
 -                                    + basefuncmodulationpar2) * 2.0f
 -                                   * PI)) * 0.5f,
 -                              basefuncmodulationpar3) * basefuncmodulationpar1; //power
 -                 break;
 -         }
 - 
 -         t = t - floor(t);
 - 
 -         if(func)
 -             smps[i] = func(t, par);
 -         else
 -             smps[i] = -sinf(2.0f * PI * i / synth->oscilsize);
 -     }
 - }
 - 
 - 
 - /*
 -  * Filter the oscillator
 -  */
 - void OscilGen::oscilfilter()
 - {
 -     if(Pfiltertype == 0)
 -         return;
 - 
 -     const float par    = 1.0f - Pfilterpar1 / 128.0f;
 -     const float par2   = Pfilterpar2 / 127.0f;
 -     filter_func filter = getFilter(Pfiltertype);
 - 
 -     for(int i = 1; i < synth->oscilsize / 2; ++i)
 -         oscilFFTfreqs[i] *= filter(i, par, par2);
 - 
 -     normalize(oscilFFTfreqs);
 - }
 - 
 - 
 - /*
 -  * Change the base function
 -  */
 - void OscilGen::changebasefunction()
 - {
 -     if(Pcurrentbasefunc != 0) {
 -         getbasefunction(tmpsmps);
 -         fft->smps2freqs(tmpsmps, basefuncFFTfreqs);
 -         clearDC(basefuncFFTfreqs);
 -     }
 -     else //in this case basefuncFFTfreqs are not used
 -         clearAll(basefuncFFTfreqs);
 -     oscilprepared = 0;
 -     oldbasefunc   = Pcurrentbasefunc;
 -     oldbasepar    = Pbasefuncpar;
 -     oldbasefuncmodulation     = Pbasefuncmodulation;
 -     oldbasefuncmodulationpar1 = Pbasefuncmodulationpar1;
 -     oldbasefuncmodulationpar2 = Pbasefuncmodulationpar2;
 -     oldbasefuncmodulationpar3 = Pbasefuncmodulationpar3;
 - }
 - 
 - inline void normalize(float *smps, size_t N)
 - {
 -     //Find max
 -     float max = 0.0f;
 -     for(size_t i = 0; i < N; ++i)
 -         if(max < fabs(smps[i]))
 -             max = fabs(smps[i]);
 -     if(max < 0.00001f)
 -         max = 1.0f;
 - 
 -     //Normalize to +-1
 -     for(size_t i = 0; i < N; ++i)
 -         smps[i] /= max;
 - }
 - 
 - /*
 -  * Waveshape
 -  */
 - void OscilGen::waveshape()
 - {
 -     oldwaveshapingfunction = Pwaveshapingfunction;
 -     oldwaveshaping = Pwaveshaping;
 -     if(Pwaveshapingfunction == 0)
 -         return;
 - 
 -     clearDC(oscilFFTfreqs);
 -     //reduce the amplitude of the freqs near the nyquist
 -     for(int i = 1; i < synth->oscilsize / 8; ++i) {
 -         float gain = i / (synth->oscilsize / 8.0f);
 -         oscilFFTfreqs[synth->oscilsize / 2 - i] *= gain;
 -     }
 -     fft->freqs2smps(oscilFFTfreqs, tmpsmps);
 - 
 -     //Normalize
 -     normalize(tmpsmps, synth->oscilsize);
 - 
 -     //Do the waveshaping
 -     waveShapeSmps(synth->oscilsize, tmpsmps, Pwaveshapingfunction, Pwaveshaping);
 - 
 -     fft->smps2freqs(tmpsmps, oscilFFTfreqs); //perform FFT
 - }
 - 
 - 
 - /*
 -  * Do the Frequency Modulation of the Oscil
 -  */
 - void OscilGen::modulation()
 - {
 -     int i;
 - 
 -     oldmodulation     = Pmodulation;
 -     oldmodulationpar1 = Pmodulationpar1;
 -     oldmodulationpar2 = Pmodulationpar2;
 -     oldmodulationpar3 = Pmodulationpar3;
 -     if(Pmodulation == 0)
 -         return;
 - 
 - 
 -     float modulationpar1 = Pmodulationpar1 / 127.0f,
 -           modulationpar2 = 0.5f - Pmodulationpar2 / 127.0f,
 -           modulationpar3 = Pmodulationpar3 / 127.0f;
 - 
 -     switch(Pmodulation) {
 -         case 1:
 -             modulationpar1 = (powf(2, modulationpar1 * 7.0f) - 1.0f) / 100.0f;
 -             modulationpar3 = floor((powf(2, modulationpar3 * 5.0f) - 1.0f));
 -             if(modulationpar3 < 0.9999f)
 -                 modulationpar3 = -1.0f;
 -             break;
 -         case 2:
 -             modulationpar1 = (powf(2, modulationpar1 * 7.0f) - 1.0f) / 100.0f;
 -             modulationpar3 = 1.0f
 -                              + floor((powf(2, modulationpar3 * 5.0f) - 1.0f));
 -             break;
 -         case 3:
 -             modulationpar1 = (powf(2, modulationpar1 * 9.0f) - 1.0f) / 100.0f;
 -             modulationpar3 = 0.01f
 -                              + (powf(2, modulationpar3 * 16.0f) - 1.0f) / 10.0f;
 -             break;
 -     }
 - 
 -     clearDC(oscilFFTfreqs); //remove the DC
 -     //reduce the amplitude of the freqs near the nyquist
 -     for(i = 1; i < synth->oscilsize / 8; ++i) {
 -         float tmp = i / (synth->oscilsize / 8.0f);
 -         oscilFFTfreqs[synth->oscilsize / 2 - i] *= tmp;
 -     }
 -     fft->freqs2smps(oscilFFTfreqs, tmpsmps);
 -     int    extra_points = 2;
 -     float *in = new float[synth->oscilsize + extra_points];
 - 
 -     //Normalize
 -     normalize(tmpsmps, synth->oscilsize);
 - 
 -     for(i = 0; i < synth->oscilsize; ++i)
 -         in[i] = tmpsmps[i];
 -     for(i = 0; i < extra_points; ++i)
 -         in[i + synth->oscilsize] = tmpsmps[i];
 - 
 -     //Do the modulation
 -     for(i = 0; i < synth->oscilsize; ++i) {
 -         float t = i * 1.0f / synth->oscilsize;
 - 
 -         switch(Pmodulation) {
 -             case 1:
 -                 t = t * modulationpar3
 -                     + sinf((t + modulationpar2) * 2.0f * PI) * modulationpar1; //rev
 -                 break;
 -             case 2:
 -                 t = t
 -                     + sinf((t * modulationpar3
 -                             + modulationpar2) * 2.0f * PI) * modulationpar1; //sine
 -                 break;
 -             case 3:
 -                 t = t + powf((1.0f - cosf(
 -                                   (t + modulationpar2) * 2.0f * PI)) * 0.5f,
 -                              modulationpar3) * modulationpar1; //power
 -                 break;
 -         }
 - 
 -         t = (t - floor(t)) * synth->oscilsize;
 - 
 -         int   poshi = (int) t;
 -         float poslo = t - floor(t);
 - 
 -         tmpsmps[i] = in[poshi] * (1.0f - poslo) + in[poshi + 1] * poslo;
 -     }
 - 
 -     delete [] in;
 -     fft->smps2freqs(tmpsmps, oscilFFTfreqs); //perform FFT
 - }
 - 
 - 
 - /*
 -  * Adjust the spectrum
 -  */
 - void OscilGen::spectrumadjust()
 - {
 -     if(Psatype == 0)
 -         return;
 -     float par = Psapar / 127.0f;
 -     switch(Psatype) {
 -         case 1:
 -             par = 1.0f - par * 2.0f;
 -             if(par >= 0.0f)
 -                 par = powf(5.0f, par);
 -             else
 -                 par = powf(8.0f, par);
 -             break;
 -         case 2:
 -             par = powf(10.0f, (1.0f - par) * 3.0f) * 0.001f;
 -             break;
 -         case 3:
 -             par = powf(10.0f, (1.0f - par) * 3.0f) * 0.001f;
 -             break;
 -     }
 - 
 - 
 -     normalize(oscilFFTfreqs);
 - 
 -     for(int i = 0; i < synth->oscilsize / 2; ++i) {
 -         float mag   = abs(oscilFFTfreqs, i);
 -         float phase = M_PI_2 - arg(oscilFFTfreqs, i);
 - 
 -         switch(Psatype) {
 -             case 1:
 -                 mag = powf(mag, par);
 -                 break;
 -             case 2:
 -                 if(mag < par)
 -                     mag = 0.0f;
 -                 break;
 -             case 3:
 -                 mag /= par;
 -                 if(mag > 1.0f)
 -                     mag = 1.0f;
 -                 break;
 -         }
 -         oscilFFTfreqs[i] = std::polar<fftw_real>(mag, phase);
 -     }
 - }
 - 
 - void OscilGen::shiftharmonics()
 - {
 -     if(Pharmonicshift == 0)
 -         return;
 - 
 -     int   harmonicshift = -Pharmonicshift;
 -     fft_t h;
 - 
 -     if(harmonicshift > 0)
 -         for(int i = synth->oscilsize / 2 - 2; i >= 0; i--) {
 -             int oldh = i - harmonicshift;
 -             if(oldh < 0)
 -                 h = 0.0f;
 -             else
 -                 h = oscilFFTfreqs[oldh + 1];
 -             oscilFFTfreqs[i + 1] = h;
 -         }
 -     else
 -         for(int i = 0; i < synth->oscilsize / 2 - 1; ++i) {
 -             int oldh = i + abs(harmonicshift);
 -             if(oldh >= (synth->oscilsize / 2 - 1))
 -                 h = 0.0f;
 -             else {
 -                 h = oscilFFTfreqs[oldh + 1];
 -                 if(abs(h) < 0.000001f)
 -                     h = 0.0f;
 -             }
 - 
 -             oscilFFTfreqs[i + 1] = h;
 -         }
 - 
 -     clearDC(oscilFFTfreqs);
 - }
 - 
 - /*
 -  * Prepare the Oscillator
 -  */
 - void OscilGen::prepare()
 - {
 -     if((oldbasepar != Pbasefuncpar) || (oldbasefunc != Pcurrentbasefunc)
 -        || DIFF(basefuncmodulation) || DIFF(basefuncmodulationpar1)
 -        || DIFF(basefuncmodulationpar2) || DIFF(basefuncmodulationpar3))
 -         changebasefunction();
 - 
 -     for(int i = 0; i < MAX_AD_HARMONICS; ++i)
 -         hphase[i] = (Phphase[i] - 64.0f) / 64.0f * PI / (i + 1);
 - 
 -     for(int i = 0; i < MAX_AD_HARMONICS; ++i) {
 -         const float hmagnew = 1.0f - fabs(Phmag[i] / 64.0f - 1.0f);
 -         switch(Phmagtype) {
 -             case 1:
 -                 hmag[i] = expf(hmagnew * logf(0.01f));
 -                 break;
 -             case 2:
 -                 hmag[i] = expf(hmagnew * logf(0.001f));
 -                 break;
 -             case 3:
 -                 hmag[i] = expf(hmagnew * logf(0.0001f));
 -                 break;
 -             case 4:
 -                 hmag[i] = expf(hmagnew * logf(0.00001f));
 -                 break;
 -             default:
 -                 hmag[i] = 1.0f - hmagnew;
 -                 break;
 -         }
 - 
 -         if(Phmag[i] < 64)
 -             hmag[i] = -hmag[i];
 -     }
 - 
 -     //remove the harmonics where Phmag[i]==64
 -     for(int i = 0; i < MAX_AD_HARMONICS; ++i)
 -         if(Phmag[i] == 64)
 -             hmag[i] = 0.0f;
 - 
 - 
 -     clearAll(oscilFFTfreqs);
 -     if(Pcurrentbasefunc == 0)   //the sine case
 -         for(int i = 0; i < MAX_AD_HARMONICS - 1; ++i) {
 -             oscilFFTfreqs[i + 1] =
 -                 std::complex<float>(-hmag[i] * sinf(hphase[i] * (i + 1)) / 2.0f,
 -                         hmag[i] * cosf(hphase[i] * (i + 1)) / 2.0f);
 -         }
 -     else
 -         for(int j = 0; j < MAX_AD_HARMONICS; ++j) {
 -             if(Phmag[j] == 64)
 -                 continue;
 -             for(int i = 1; i < synth->oscilsize / 2; ++i) {
 -                 int k = i * (j + 1);
 -                 if(k >= synth->oscilsize / 2)
 -                     break;
 -                 oscilFFTfreqs[k] += basefuncFFTfreqs[i] * std::polar<fftw_real>(
 -                     hmag[j],
 -                     hphase[j] * k);
 -             }
 -         }
 - 
 -     if(Pharmonicshiftfirst != 0)
 -         shiftharmonics();
 - 
 -     if(Pfilterbeforews == 0) {
 -         waveshape();
 -         oscilfilter();
 -     }
 -     else {
 -         oscilfilter();
 -         waveshape();
 -     }
 - 
 -     modulation();
 -     spectrumadjust();
 -     if(Pharmonicshiftfirst == 0)
 -         shiftharmonics();
 - 
 -     clearDC(oscilFFTfreqs);
 - 
 -     oldhmagtype      = Phmagtype;
 -     oldharmonicshift = Pharmonicshift + Pharmonicshiftfirst * 256;
 - 
 -     oscilprepared = 1;
 - }
 - 
 - void OscilGen::adaptiveharmonic(fft_t *f, float freq)
 - {
 -     if(Padaptiveharmonics == 0 /*||(freq<1.0f)*/)
 -         return;
 -     if(freq < 1.0f)
 -         freq = 440.0f;
 - 
 -     fft_t *inf = new fft_t[synth->oscilsize / 2];
 -     for(int i = 0; i < synth->oscilsize / 2; ++i)
 -         inf[i] = f[i];
 -     clearAll(f);
 -     clearDC(inf);
 - 
 -     float hc = 0.0f, hs = 0.0f;
 -     float basefreq = 30.0f * powf(10.0f, Padaptiveharmonicsbasefreq / 128.0f);
 -     float power    = (Padaptiveharmonicspower + 1.0f) / 101.0f;
 - 
 -     float rap = freq / basefreq;
 - 
 -     rap = powf(rap, power);
 - 
 -     bool down = false;
 -     if(rap > 1.0f) {
 -         rap  = 1.0f / rap;
 -         down = true;
 -     }
 - 
 -     for(int i = 0; i < synth->oscilsize / 2 - 2; ++i) {
 -         float h    = i * rap;
 -         int   high = (int)(i * rap);
 -         float low  = fmod(h, 1.0f);
 - 
 -         if(high >= (synth->oscilsize / 2 - 2))
 -             break;
 -         else {
 -             if(down) {
 -                 f[high] =
 -                     std::complex<float>(f[high].real() + inf[i].real() * (1.0f - low),
 -                             f[high].imag() + inf[i].imag() * (1.0f - low));
 - 
 -                 f[high + 1] = std::complex<float>(f[high + 1].real() + inf[i].real() * low,
 -                         f[high + 1].imag() + inf[i].imag() * low);
 -             }
 -             else {
 -                 hc = inf[high].real()
 -                      * (1.0f - low) + inf[high + 1].real() * low;
 -                 hs = inf[high].imag()
 -                      * (1.0f - low) + inf[high + 1].imag() * low;
 -             }
 -             if(fabs(hc) < 0.000001f)
 -                 hc = 0.0f;
 -             if(fabs(hs) < 0.000001f)
 -                 hs = 0.0f;
 -         }
 - 
 -         if(!down) {
 -             if(i == 0) { //corect the aplitude of the first harmonic
 -                 hc *= rap;
 -                 hs *= rap;
 -             }
 -             f[i] = fft_t(hc, hs);
 -         }
 -     }
 - 
 -     f[1] += f[0];
 -     clearDC(f);
 -     delete[] inf;
 - }
 - 
 - void OscilGen::adaptiveharmonicpostprocess(fft_t *f, int size)
 - {
 -     if(Padaptiveharmonics <= 1)
 -         return;
 -     fft_t *inf = new fft_t[size];
 -     float  par = Padaptiveharmonicspar * 0.01f;
 -     par = 1.0f - powf((1.0f - par), 1.5f);
 - 
 -     for(int i = 0; i < size; ++i) {
 -         inf[i] = f[i] * double(par);
 -         f[i]  *= (1.0f - par);
 -     }
 - 
 - 
 -     if(Padaptiveharmonics == 2) { //2n+1
 -         for(int i = 0; i < size; ++i)
 -             if((i % 2) == 0)
 -                 f[i] += inf[i];  //i=0 pt prima armonica,etc.
 -     }
 -     else {  //celelalte moduri
 -         int nh = (Padaptiveharmonics - 3) / 2 + 2;
 -         int sub_vs_add = (Padaptiveharmonics - 3) % 2;
 -         if(sub_vs_add == 0) {
 -             for(int i = 0; i < size; ++i)
 -                 if(((i + 1) % nh) == 0)
 -                     f[i] += inf[i];
 -         }
 -         else
 -             for(int i = 0; i < size / nh - 1; ++i)
 -                 f[(i + 1) * nh - 1] += inf[i];
 -     }
 - 
 -     delete [] inf;
 - }
 - 
 - void OscilGen::newrandseed(unsigned int randseed)
 - {
 -     this->randseed = randseed;
 - }
 - 
 - bool OscilGen::needPrepare(void)
 - {
 -     bool outdated = false;
 - 
 -     //Check function parameters
 -     if((oldbasepar != Pbasefuncpar) || (oldbasefunc != Pcurrentbasefunc)
 -        || DIFF(hmagtype) || DIFF(waveshaping) || DIFF(waveshapingfunction))
 -         outdated = true;
 - 
 -     //Check filter parameters
 -     if(oldfilterpars != Pfiltertype * 256 + Pfilterpar1 + Pfilterpar2 * 65536
 -        + Pfilterbeforews * 16777216) {
 -         outdated      = true;
 -         oldfilterpars = Pfiltertype * 256 + Pfilterpar1 + Pfilterpar2 * 65536
 -                         + Pfilterbeforews * 16777216;
 -     }
 - 
 -     //Check spectrum adjustments
 -     if(oldsapars != Psatype * 256 + Psapar) {
 -         outdated  = true;
 -         oldsapars = Psatype * 256 + Psapar;
 -     }
 - 
 -     //Check function modulation
 -     if(DIFF(basefuncmodulation) || DIFF(basefuncmodulationpar1)
 -        || DIFF(basefuncmodulationpar2) || DIFF(basefuncmodulationpar3))
 -         outdated = true;
 - 
 -     //Check overall modulation
 -     if(DIFF(modulation) || DIFF(modulationpar1)
 -        || DIFF(modulationpar2) || DIFF(modulationpar3))
 -         outdated = true;
 - 
 -     //Check harmonic shifts
 -     if(oldharmonicshift != Pharmonicshift + Pharmonicshiftfirst * 256)
 -         outdated = true;
 - 
 -     return outdated == true || oscilprepared == false;
 - }
 - 
 - /*
 -  * Get the oscillator function
 -  */
 - short int OscilGen::get(float *smps, float freqHz, int resonance)
 - {
 -     if(needPrepare())
 -         prepare();
 - 
 -     int outpos =
 -         (int)((RND * 2.0f
 -                - 1.0f) * synth->oscilsize_f * (Prand - 64.0f) / 64.0f);
 -     outpos = (outpos + 2 * synth->oscilsize) % synth->oscilsize;
 - 
 - 
 -     clearAll(outoscilFFTfreqs);
 - 
 -     int nyquist = (int)(0.5f * synth->samplerate_f / fabs(freqHz)) + 2;
 -     if(ADvsPAD)
 -         nyquist = (int)(synth->oscilsize / 2);
 -     if(nyquist > synth->oscilsize / 2)
 -         nyquist = synth->oscilsize / 2;
 - 
 -     //Process harmonics
 -     {
 -         int realnyquist = nyquist;
 - 
 -         if(Padaptiveharmonics != 0)
 -             nyquist = synth->oscilsize / 2;
 -         for(int i = 1; i < nyquist - 1; ++i)
 -             outoscilFFTfreqs[i] = oscilFFTfreqs[i];
 - 
 -         adaptiveharmonic(outoscilFFTfreqs, freqHz);
 -         adaptiveharmonicpostprocess(&outoscilFFTfreqs[1],
 -                                     synth->oscilsize / 2 - 1);
 - 
 -         nyquist = realnyquist;
 -     }
 - 
 -     if(Padaptiveharmonics)   //do the antialiasing in the case of adaptive harmonics
 -         for(int i = nyquist; i < synth->oscilsize / 2; ++i)
 -             outoscilFFTfreqs[i] = fft_t(0.0f, 0.0f);
 - 
 -     // Randomness (each harmonic), the block type is computed
 -     // in ADnote by setting start position according to this setting
 -     if((Prand > 64) && (freqHz >= 0.0f) && (!ADvsPAD)) {
 -         const float rnd = PI * powf((Prand - 64.0f) / 64.0f, 2.0f);
 -         for(int i = 1; i < nyquist - 1; ++i) //to Nyquist only for AntiAliasing
 -             outoscilFFTfreqs[i] *=
 -                 std::polar<fftw_real>(1.0f, (float)(rnd * i * RND));
 -     }
 - 
 -     //Harmonic Amplitude Randomness
 -     if((freqHz > 0.1f) && (!ADvsPAD)) {
 -         unsigned int realrnd = prng();
 -         sprng(randseed);
 -         float power     = Pamprandpower / 127.0f;
 -         float normalize = 1.0f / (1.2f - power);
 -         switch(Pamprandtype) {
 -             case 1:
 -                 power = power * 2.0f - 0.5f;
 -                 power = powf(15.0f, power);
 -                 for(int i = 1; i < nyquist - 1; ++i)
 -                     outoscilFFTfreqs[i] *= powf(RND, power) * normalize;
 -                 break;
 -             case 2:
 -                 power = power * 2.0f - 0.5f;
 -                 power = powf(15.0f, power) * 2.0f;
 -                 float rndfreq = 2 * PI * RND;
 -                 for(int i = 1; i < nyquist - 1; ++i)
 -                     outoscilFFTfreqs[i] *= powf(fabs(sinf(i * rndfreq)), power)
 -                                            * normalize;
 -                 break;
 -         }
 -         sprng(realrnd + 1);
 -     }
 - 
 -     if((freqHz > 0.1f) && (resonance != 0))
 -         res->applyres(nyquist - 1, outoscilFFTfreqs, freqHz);
 - 
 -     rmsNormalize(outoscilFFTfreqs);
 - 
 -     if((ADvsPAD) && (freqHz > 0.1f)) //in this case the smps will contain the freqs
 -         for(int i = 1; i < synth->oscilsize / 2; ++i)
 -             smps[i - 1] = abs(outoscilFFTfreqs, i);
 -     else {
 -         fft->freqs2smps(outoscilFFTfreqs, smps);
 -         for(int i = 0; i < synth->oscilsize; ++i)
 -             smps[i] *= 0.25f;                     //correct the amplitude
 -     }
 - 
 -     if(Prand < 64)
 -         return outpos;
 -     else
 -         return 0;
 - }
 - 
 - 
 - /*
 -  * Get the spectrum of the oscillator for the UI
 -  */
 - void OscilGen::getspectrum(int n, float *spc, int what)
 - {
 -     if(n > synth->oscilsize / 2)
 -         n = synth->oscilsize / 2;
 - 
 -     for(int i = 1; i < n; ++i) {
 -         if(what == 0)
 -             spc[i - 1] = abs(oscilFFTfreqs, i);
 -         else {
 -             if(Pcurrentbasefunc == 0)
 -                 spc[i - 1] = ((i == 1) ? (1.0f) : (0.0f));
 -             else
 -                 spc[i - 1] = abs(basefuncFFTfreqs, i);
 -         }
 -     }
 - 
 -     if(what == 0) {
 -         for(int i = 0; i < n; ++i)
 -             outoscilFFTfreqs[i] = fft_t(spc[i], spc[i]);
 -         memset(outoscilFFTfreqs + n, 0,
 -                (synth->oscilsize / 2 - n) * sizeof(fft_t));
 -         adaptiveharmonic(outoscilFFTfreqs, 0.0f);
 -         adaptiveharmonicpostprocess(outoscilFFTfreqs, n - 1);
 -         for(int i = 0; i < n; ++i)
 -             spc[i] = outoscilFFTfreqs[i].imag();
 -     }
 - }
 - 
 - 
 - /*
 -  * Convert the oscillator as base function
 -  */
 - void OscilGen::useasbase()
 - {
 -     for(int i = 0; i < synth->oscilsize / 2; ++i)
 -         basefuncFFTfreqs[i] = oscilFFTfreqs[i];
 - 
 -     oldbasefunc = Pcurrentbasefunc = 127;
 -     prepare();
 - }
 - 
 - 
 - /*
 -  * Get the base function for UI
 -  */
 - void OscilGen::getcurrentbasefunction(float *smps)
 - {
 -     if(Pcurrentbasefunc != 0)
 -         fft->freqs2smps(basefuncFFTfreqs, smps);
 -     else
 -         getbasefunction(smps);   //the sine case
 - }
 - 
 - void OscilGen::add2XML(XMLwrapper *xml)
 - {
 -     xml->addpar("harmonic_mag_type", Phmagtype);
 - 
 -     xml->addpar("base_function", Pcurrentbasefunc);
 -     xml->addpar("base_function_par", Pbasefuncpar);
 -     xml->addpar("base_function_modulation", Pbasefuncmodulation);
 -     xml->addpar("base_function_modulation_par1", Pbasefuncmodulationpar1);
 -     xml->addpar("base_function_modulation_par2", Pbasefuncmodulationpar2);
 -     xml->addpar("base_function_modulation_par3", Pbasefuncmodulationpar3);
 - 
 -     xml->addpar("modulation", Pmodulation);
 -     xml->addpar("modulation_par1", Pmodulationpar1);
 -     xml->addpar("modulation_par2", Pmodulationpar2);
 -     xml->addpar("modulation_par3", Pmodulationpar3);
 - 
 -     xml->addpar("wave_shaping", Pwaveshaping);
 -     xml->addpar("wave_shaping_function", Pwaveshapingfunction);
 - 
 -     xml->addpar("filter_type", Pfiltertype);
 -     xml->addpar("filter_par1", Pfilterpar1);
 -     xml->addpar("filter_par2", Pfilterpar2);
 -     xml->addpar("filter_before_wave_shaping", Pfilterbeforews);
 - 
 -     xml->addpar("spectrum_adjust_type", Psatype);
 -     xml->addpar("spectrum_adjust_par", Psapar);
 - 
 -     xml->addpar("rand", Prand);
 -     xml->addpar("amp_rand_type", Pamprandtype);
 -     xml->addpar("amp_rand_power", Pamprandpower);
 - 
 -     xml->addpar("harmonic_shift", Pharmonicshift);
 -     xml->addparbool("harmonic_shift_first", Pharmonicshiftfirst);
 - 
 -     xml->addpar("adaptive_harmonics", Padaptiveharmonics);
 -     xml->addpar("adaptive_harmonics_base_frequency", Padaptiveharmonicsbasefreq);
 -     xml->addpar("adaptive_harmonics_power", Padaptiveharmonicspower);
 - 
 -     xml->beginbranch("HARMONICS");
 -     for(int n = 0; n < MAX_AD_HARMONICS; ++n) {
 -         if((Phmag[n] == 64) && (Phphase[n] == 64))
 -             continue;
 -         xml->beginbranch("HARMONIC", n + 1);
 -         xml->addpar("mag", Phmag[n]);
 -         xml->addpar("phase", Phphase[n]);
 -         xml->endbranch();
 -     }
 -     xml->endbranch();
 - 
 -     if(Pcurrentbasefunc == 127) {
 -         normalize(basefuncFFTfreqs);
 - 
 -         xml->beginbranch("BASE_FUNCTION");
 -         for(int i = 1; i < synth->oscilsize / 2; ++i) {
 -             float xc = basefuncFFTfreqs[i].real();
 -             float xs = basefuncFFTfreqs[i].imag();
 -             if((fabs(xs) > 0.00001f) && (fabs(xs) > 0.00001f)) {
 -                 xml->beginbranch("BF_HARMONIC", i);
 -                 xml->addparreal("cos", xc);
 -                 xml->addparreal("sin", xs);
 -                 xml->endbranch();
 -             }
 -         }
 -         xml->endbranch();
 -     }
 - }
 - 
 - void OscilGen::getfromXML(XMLwrapper *xml)
 - {
 -     Phmagtype = xml->getpar127("harmonic_mag_type", Phmagtype);
 - 
 -     Pcurrentbasefunc = xml->getpar127("base_function", Pcurrentbasefunc);
 -     Pbasefuncpar     = xml->getpar127("base_function_par", Pbasefuncpar);
 - 
 -     Pbasefuncmodulation = xml->getpar127("base_function_modulation",
 -                                          Pbasefuncmodulation);
 -     Pbasefuncmodulationpar1 = xml->getpar127("base_function_modulation_par1",
 -                                              Pbasefuncmodulationpar1);
 -     Pbasefuncmodulationpar2 = xml->getpar127("base_function_modulation_par2",
 -                                              Pbasefuncmodulationpar2);
 -     Pbasefuncmodulationpar3 = xml->getpar127("base_function_modulation_par3",
 -                                              Pbasefuncmodulationpar3);
 - 
 -     Pmodulation     = xml->getpar127("modulation", Pmodulation);
 -     Pmodulationpar1 = xml->getpar127("modulation_par1",
 -                                      Pmodulationpar1);
 -     Pmodulationpar2 = xml->getpar127("modulation_par2",
 -                                      Pmodulationpar2);
 -     Pmodulationpar3 = xml->getpar127("modulation_par3",
 -                                      Pmodulationpar3);
 - 
 -     Pwaveshaping = xml->getpar127("wave_shaping", Pwaveshaping);
 -     Pwaveshapingfunction = xml->getpar127("wave_shaping_function",
 -                                           Pwaveshapingfunction);
 - 
 -     Pfiltertype     = xml->getpar127("filter_type", Pfiltertype);
 -     Pfilterpar1     = xml->getpar127("filter_par1", Pfilterpar1);
 -     Pfilterpar2     = xml->getpar127("filter_par2", Pfilterpar2);
 -     Pfilterbeforews = xml->getpar127("filter_before_wave_shaping",
 -                                      Pfilterbeforews);
 - 
 -     Psatype = xml->getpar127("spectrum_adjust_type", Psatype);
 -     Psapar  = xml->getpar127("spectrum_adjust_par", Psapar);
 - 
 -     Prand = xml->getpar127("rand", Prand);
 -     Pamprandtype  = xml->getpar127("amp_rand_type", Pamprandtype);
 -     Pamprandpower = xml->getpar127("amp_rand_power", Pamprandpower);
 - 
 -     Pharmonicshift = xml->getpar("harmonic_shift",
 -                                  Pharmonicshift,
 -                                  -64,
 -                                  64);
 -     Pharmonicshiftfirst = xml->getparbool("harmonic_shift_first",
 -                                           Pharmonicshiftfirst);
 - 
 -     Padaptiveharmonics = xml->getpar("adaptive_harmonics",
 -                                      Padaptiveharmonics,
 -                                      0,
 -                                      127);
 -     Padaptiveharmonicsbasefreq = xml->getpar(
 -         "adaptive_harmonics_base_frequency",
 -         Padaptiveharmonicsbasefreq,
 -         0,
 -         255);
 -     Padaptiveharmonicspower = xml->getpar("adaptive_harmonics_power",
 -                                           Padaptiveharmonicspower,
 -                                           0,
 -                                           200);
 - 
 - 
 -     if(xml->enterbranch("HARMONICS")) {
 -         Phmag[0]   = 64;
 -         Phphase[0] = 64;
 -         for(int n = 0; n < MAX_AD_HARMONICS; ++n) {
 -             if(xml->enterbranch("HARMONIC", n + 1) == 0)
 -                 continue;
 -             Phmag[n]   = xml->getpar127("mag", 64);
 -             Phphase[n] = xml->getpar127("phase", 64);
 -             xml->exitbranch();
 -         }
 -         xml->exitbranch();
 -     }
 - 
 -     if(Pcurrentbasefunc != 0)
 -         changebasefunction();
 - 
 - 
 -     if(xml->enterbranch("BASE_FUNCTION")) {
 -         for(int i = 1; i < synth->oscilsize / 2; ++i)
 -             if(xml->enterbranch("BF_HARMONIC", i)) {
 -                 basefuncFFTfreqs[i] =
 -                     std::complex<float>(xml->getparreal("cos", 0.0f),
 -                             xml->getparreal("sin", 0.0f));
 -                 xml->exitbranch();
 -             }
 -         xml->exitbranch();
 - 
 -         clearDC(basefuncFFTfreqs);
 -         normalize(basefuncFFTfreqs);
 -     }
 - }
 - 
 - 
 - //Define basic functions
 - #define FUNC(b) float basefunc_ ## b(float x, float a)
 - 
 - FUNC(pulse)
 - {
 -     return (fmod(x, 1.0f) < a) ? -1.0f : 1.0f;
 - }
 - 
 - FUNC(saw)
 - {
 -     if(a < 0.00001f)
 -         a = 0.00001f;
 -     else
 -     if(a > 0.99999f)
 -         a = 0.99999f;
 -     x = fmod(x, 1);
 -     if(x < a)
 -         return x / a * 2.0f - 1.0f;
 -     else
 -         return (1.0f - x) / (1.0f - a) * 2.0f - 1.0f;
 - }
 - 
 - FUNC(triangle)
 - {
 -     x = fmod(x + 0.25f, 1);
 -     a = 1 - a;
 -     if(a < 0.00001f)
 -         a = 0.00001f;
 -     if(x < 0.5f)
 -         x = x * 4 - 1.0f;
 -     else
 -         x = (1.0f - x) * 4 - 1.0f;
 -     x /= -a;
 -     if(x < -1.0f)
 -         x = -1.0f;
 -     if(x > 1.0f)
 -         x = 1.0f;
 -     return x;
 - }
 - 
 - FUNC(power)
 - {
 -     x = fmod(x, 1);
 -     if(a < 0.00001f)
 -         a = 0.00001f;
 -     else
 -     if(a > 0.99999f)
 -         a = 0.99999f;
 -     return powf(x, expf((a - 0.5f) * 10.0f)) * 2.0f - 1.0f;
 - }
 - 
 - FUNC(gauss)
 - {
 -     x = fmod(x, 1) * 2.0f - 1.0f;
 -     if(a < 0.00001f)
 -         a = 0.00001f;
 -     return expf(-x * x * (expf(a * 8) + 5.0f)) * 2.0f - 1.0f;
 - }
 - 
 - FUNC(diode)
 - {
 -     if(a < 0.00001f)
 -         a = 0.00001f;
 -     else
 -     if(a > 0.99999f)
 -         a = 0.99999f;
 -     a = a * 2.0f - 1.0f;
 -     x = cosf((x + 0.5f) * 2.0f * PI) - a;
 -     if(x < 0.0f)
 -         x = 0.0f;
 -     return x / (1.0f - a) * 2 - 1.0f;
 - }
 - 
 - FUNC(abssine)
 - {
 -     x = fmod(x, 1);
 -     if(a < 0.00001f)
 -         a = 0.00001f;
 -     else
 -     if(a > 0.99999f)
 -         a = 0.99999f;
 -     return sinf(powf(x, expf((a - 0.5f) * 5.0f)) * PI) * 2.0f - 1.0f;
 - }
 - 
 - FUNC(pulsesine)
 - {
 -     if(a < 0.00001f)
 -         a = 0.00001f;
 -     x = (fmod(x, 1) - 0.5f) * expf((a - 0.5f) * logf(128));
 -     if(x < -0.5f)
 -         x = -0.5f;
 -     else
 -     if(x > 0.5f)
 -         x = 0.5f;
 -     x = sinf(x * PI * 2.0f);
 -     return x;
 - }
 - 
 - FUNC(stretchsine)
 - {
 -     x = fmod(x + 0.5f, 1) * 2.0f - 1.0f;
 -     a = (a - 0.5f) * 4;
 -     if(a > 0.0f)
 -         a *= 2;
 -     a = powf(3.0f, a);
 -     float b = powf(fabs(x), a);
 -     if(x < 0)
 -         b = -b;
 -     return -sinf(b * PI);
 - }
 - 
 - FUNC(chirp)
 - {
 -     x = fmod(x, 1.0f) * 2.0f * PI;
 -     a = (a - 0.5f) * 4;
 -     if(a < 0.0f)
 -         a *= 2.0f;
 -     a = powf(3.0f, a);
 -     return sinf(x / 2.0f) * sinf(a * x * x);
 - }
 - 
 - FUNC(absstretchsine)
 - {
 -     x = fmod(x + 0.5f, 1) * 2.0f - 1.0f;
 -     a = (a - 0.5f) * 9;
 -     a = powf(3.0f, a);
 -     float b = powf(fabs(x), a);
 -     if(x < 0)
 -         b = -b;
 -     return -powf(sinf(b * PI), 2);
 - }
 - 
 - FUNC(chebyshev)
 - {
 -     a = a * a * a * 30.0f + 1.0f;
 -     return cosf(acosf(x * 2.0f - 1.0f) * a);
 - }
 - 
 - FUNC(sqr)
 - {
 -     a = a * a * a * a * 160.0f + 0.001f;
 -     return -atanf(sinf(x * 2.0f * PI) * a);
 - }
 - 
 - FUNC(spike)
 - {
 -     float b = a * 0.66666; // the width of the range: if a == 0.5, b == 0.33333
 - 
 -     if(x < 0.5) {
 -         if(x < (0.5 - (b / 2.0)))
 -             return 0.0;
 -         else {
 -             x = (x + (b / 2) - 0.5) * (2.0 / b); // shift to zero, and expand to range from 0 to 1
 -             return x * (2.0 / b); // this is the slope: 1 / (b / 2)
 -         }
 -     }
 -     else {
 -         if(x > (0.5 + (b / 2.0)))
 -             return 0.0;
 -         else {
 -             x = (x - 0.5) * (2.0 / b);
 -             return (1 - x) * (2.0 / b);
 -         }
 -     }
 - }
 - 
 - FUNC(circle)
 - {
 -     // a is parameter: 0 -> 0.5 -> 1 // O.5 = circle
 -     float b, y;
 - 
 -     b = 2 - (a * 2); // b goes from 2 to 0
 -     x = x * 4;
 - 
 -     if(x < 2) {
 -         x = x - 1; // x goes from -1 to 1
 -         if((x < -b) || (x > b))
 -             y = 0;
 -         else
 -             y = sqrt(1 - (pow(x, 2) / pow(b, 2)));  // normally * a^2, but a stays 1
 -     }
 -     else {
 -         x = x - 3; // x goes from -1 to 1 as well
 -         if((x < -b) || (x > b))
 -             y = 0;
 -         else
 -             y = -sqrt(1 - (pow(x, 2) / pow(b, 2)));
 -     }
 -     return y;
 - }
 - 
 - typedef float (*base_func)(float, float);
 - 
 - base_func getBaseFunction(unsigned char func)
 - {
 -     if(!func)
 -         return NULL;
 - 
 -     if(func == 127) //should be the custom wave
 -         return NULL;
 - 
 -     func--;
 -     assert(func < 15);
 -     base_func functions[] = {
 -         basefunc_triangle,
 -         basefunc_pulse,
 -         basefunc_saw,
 -         basefunc_power,
 -         basefunc_gauss,
 -         basefunc_diode,
 -         basefunc_abssine,
 -         basefunc_pulsesine,
 -         basefunc_stretchsine,
 -         basefunc_chirp,
 -         basefunc_absstretchsine,
 -         basefunc_chebyshev,
 -         basefunc_sqr,
 -         basefunc_spike,
 -         basefunc_circle,
 -     };
 -     return functions[func];
 - }
 - 
 - //And filters
 - 
 - #define FILTER(x) float osc_ ## x(unsigned int i, float par, float par2)
 - FILTER(lp)
 - {
 -     float gain = powf(1.0f - par * par * par * 0.99f, i);
 -     float tmp  = par2 * par2 * par2 * par2 * 0.5f + 0.0001f;
 -     if(gain < tmp)
 -         gain = powf(gain, 10.0f) / powf(tmp, 9.0f);
 -     return gain;
 - }
 - 
 - FILTER(hp1)
 - {
 -     float gain = 1.0f - powf(1.0f - par * par, i + 1);
 -     return powf(gain, par2 * 2.0f + 0.1f);
 - }
 - 
 - FILTER(hp1b)
 - {
 -     if(par < 0.2f)
 -         par = par * 0.25f + 0.15f;
 -     float gain = 1.0f - powf(1.0f - par * par * 0.999f + 0.001f,
 -                              i * 0.05f * i + 1.0f);
 -     float tmp = powf(5.0f, par2 * 2.0f);
 -     return powf(gain, tmp);
 - }
 - 
 - FILTER(bp1)
 - {
 -     float gain = i + 1 - powf(2, (1.0f - par) * 7.5f);
 -     gain = 1.0f / (1.0f + gain * gain / (i + 1.0f));
 -     float tmp = powf(5.0f, par2 * 2.0f);
 -     gain = powf(gain, tmp);
 -     if(gain < 1e-5)
 -         gain = 1e-5;
 -     return gain;
 - }
 - 
 - FILTER(bs1)
 - {
 -     float gain = i + 1 - powf(2, (1.0f - par) * 7.5f);
 -     gain = powf(atanf(gain / (i / 10.0f + 1)) / 1.57f, 6);
 -     return powf(gain, par2 * par2 * 3.9f + 0.1f);
 - }
 - 
 - FILTER(lp2)
 - {
 -     return (i + 1 >
 -             powf(2, (1.0f - par) * 10) ? 0.0f : 1.0f) * par2 + (1.0f - par2);
 - }
 - 
 - FILTER(hp2)
 - {
 -     if(par == 1)
 -         return 1.0f;
 -     return (i + 1 >
 -             powf(2, (1.0f - par) * 7) ? 1.0f : 0.0f) * par2 + (1.0f - par2);
 - }
 - 
 - FILTER(bp2)
 - {
 -     return (fabs(powf(2,
 -                       (1.0f
 -                        - par)
 -                       * 7)
 -                  - i) > i / 2 + 1 ? 0.0f : 1.0f) * par2 + (1.0f - par2);
 - }
 - 
 - FILTER(bs2)
 - {
 -     return (fabs(powf(2,
 -                       (1.0f
 -                        - par)
 -                       * 7)
 -                  - i) < i / 2 + 1 ? 0.0f : 1.0f) * par2 + (1.0f - par2);
 - }
 - 
 - bool floatEq(float a, float b)
 - {
 -     const float fudge = .01;
 -     return a + fudge > b && a - fudge < b;
 - }
 - 
 - FILTER(cos)
 - {
 -     float tmp = powf(5.0f, par2 * 2.0f - 1.0f);
 -     tmp = powf(i / 32.0f, tmp) * 32.0f;
 -     if(floatEq(par2 * 127.0f, 64.0f))
 -         tmp = i;
 -     float gain = cosf(par * par * PI / 2.0f * tmp);
 -     gain *= gain;
 -     return gain;
 - }
 - 
 - FILTER(sin)
 - {
 -     float tmp = powf(5.0f, par2 * 2.0f - 1.0f);
 -     tmp = powf(i / 32.0f, tmp) * 32.0f;
 -     if(floatEq(par2 * 127.0f, 64.0f))
 -         tmp = i;
 -     float gain = sinf(par * par * PI / 2.0f * tmp);
 -     gain *= gain;
 -     return gain;
 - }
 - 
 - FILTER(low_shelf)
 - {
 -     float p2 = 1.0f - par + 0.2f;
 -     float x  = i / (64.0f * p2 * p2);
 -     if(x < 0.0f)
 -         x = 0.0f;
 -     else
 -     if(x > 1.0f)
 -         x = 1.0f;
 -     float tmp = powf(1.0f - par2, 2.0f);
 -     return cosf(x * PI) * (1.0f - tmp) + 1.01f + tmp;
 - }
 - 
 - FILTER(s)
 - {
 -     unsigned int tmp = (int) (powf(2.0f, (1.0f - par) * 7.2f));
 -     float gain = 1.0f;
 -     if(i == tmp)
 -         gain = powf(2.0f, par2 * par2 * 8.0f);
 -     return gain;
 - }
 - #undef FILTER
 - 
 - typedef float (*filter_func)(unsigned int, float, float);
 - filter_func getFilter(unsigned char func)
 - {
 -     if(!func)
 -         return NULL;
 - 
 -     func--;
 -     assert(func < 13);
 -     filter_func functions[] = {
 -         osc_lp,
 -         osc_hp1,
 -         osc_hp1b,
 -         osc_bp1,
 -         osc_bs1,
 -         osc_lp2,
 -         osc_hp2,
 -         osc_bp2,
 -         osc_bs2,
 -         osc_cos,
 -         osc_sin,
 -         osc_low_shelf,
 -         osc_s
 -     };
 -     return functions[func];
 - }
 
 
  |