| 
							- /*
 -   ZynAddSubFX - a software synthesizer
 - 
 -   PADnoteParameters.cpp - Parameters for PADnote (PADsynth)
 -   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 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.
 - */
 - #include <cmath>
 - #include "PADnoteParameters.h"
 - #include "FilterParams.h"
 - #include "EnvelopeParams.h"
 - #include "LFOParams.h"
 - #include "../Synth/Resonance.h"
 - #include "../Synth/OscilGen.h"
 - #include "../Misc/WavFile.h"
 - #include "../Misc/Time.h"
 - #include <cstdio>
 - 
 - #include <rtosc/ports.h>
 - #include <rtosc/port-sugar.h>
 - using namespace rtosc;
 - 
 - 
 - #define rObject PADnoteParameters
 - #undef rChangeCb
 - #define rChangeCb if (obj->time) { obj->last_update_timestamp = obj->time->time(); }
 - static const rtosc::Ports realtime_ports =
 - {
 -     rRecurp(FreqLfo, "Frequency LFO"),
 -     rRecurp(AmpLfo,   "Amplitude LFO"),
 -     rRecurp(FilterLfo, "Filter LFO"),
 -     rRecurp(FreqEnvelope, "Frequency Envelope"),
 -     rRecurp(AmpEnvelope, "Amplitude Envelope"),
 -     rRecurp(FilterEnvelope, "Filter Envelope"),
 -     rRecurp(GlobalFilter, "Post Filter"),
 - 
 -     //Volume
 -     rToggle(PStereo,    rShort("stereo"), "Stereo/Mono Mode"),
 -     rParamZyn(PPanning, rShort("panning"), "Left Right Panning"),
 -     rParamZyn(PVolume,  rShort("vol"), "Synth Volume"),
 -     rParamZyn(PAmpVelocityScaleFunction, rShort("sense"), "Amplitude Velocity Sensing function"),
 - 
 -     rParamZyn(Fadein_adjustment, rShort("a.pop."), "Adjustment for anti-pop strategy."),
 - 
 -     //Punch
 -     rParamZyn(PPunchStrength, rShort("strength"), "Punch Strength"),
 -     rParamZyn(PPunchTime,     rShort("time"),     "Length of punch"),
 -     rParamZyn(PPunchStretch,  rShort("stretch"), "How Punch changes with note frequency"),
 -     rParamZyn(PPunchVelocitySensing, rShort("sense"), "Punch Velocity control"),
 - 
 -     //Filter
 -     rParamZyn(PFilterVelocityScale,         rShort("scale"), "Filter Velocity Magnitude"),
 -     rParamZyn(PFilterVelocityScaleFunction, rShort("sense"), "Filter Velocity Function Shape"),
 - 
 -     //Freq
 -     rToggle(Pfixedfreq,     rShort("fixed"),  "Base frequency fixed frequency enable"),
 -     rParamZyn(PfixedfreqET, rShort("f.ET"),   "Equal temeperate control for fixed frequency operation"),
 -     rParamZyn(PBendAdjust,          "Pitch bend adjustment"),
 -     rParamZyn(POffsetHz,    rShort("offset"), "Voice constant offset"),
 -     rParamI(PDetune,        rShort("fine"), rLinear(0, 16383), "Fine Detune"),
 -     rParamI(PCoarseDetune,  rShort("coarse"), "Coarse Detune"),
 -     rParamZyn(PDetuneType,  rShort("type"),
 -             rOptions(L35cents, L10cents, E100cents, E1200cents),
 -             "Magnitude of Detune"),
 - 
 -     {"sample#64:ifb", rProp(internal) rDoc("Nothing to see here"), 0,
 -         [](const char *m, rtosc::RtData &d)
 -         {
 -             PADnoteParameters *p = (PADnoteParameters*)d.obj;
 -             const char *mm = m;
 -             while(!isdigit(*mm))++mm;
 -             unsigned n = atoi(mm);
 -             p->sample[n].size     = rtosc_argument(m,0).i;
 -             p->sample[n].basefreq = rtosc_argument(m,1).f;
 -             p->sample[n].smp      = *(float**)rtosc_argument(m,2).b.data;
 - 
 -             //XXX TODO memory managment (deallocation of smp buffer)
 -         }},
 -     //weird stuff for PCoarseDetune
 -     {"detunevalue:", rMap(unit,cents) rDoc("Get detune value"), NULL,
 -         [](const char *, RtData &d)
 -         {
 -             PADnoteParameters *obj = (PADnoteParameters *)d.obj;
 -             d.reply(d.loc, "f", getdetune(obj->PDetuneType, 0, obj->PDetune));
 -         }},
 -     {"octave::c:i", rProp(parameter) rShort("octave") rLinear(-8,7)
 -         rDoc("Octave note offset"), NULL,
 -         [](const char *msg, RtData &d)
 -         {
 -             PADnoteParameters *obj = (PADnoteParameters *)d.obj;
 -             if(!rtosc_narguments(msg)) {
 -                 int k=obj->PCoarseDetune/1024;
 -                 if (k>=8) k-=16;
 -                 d.reply(d.loc, "i", k);
 -             } else {
 -                 int k=(int) rtosc_argument(msg, 0).i;
 -                 if (k<0) k+=16;
 -                 obj->PCoarseDetune = k*1024 + obj->PCoarseDetune%1024;
 -             }
 -         }},
 -     {"coarsedetune::c:i", rProp(parameter) rShort("coarse") rLinear(-64, 63)
 -         rDoc("Coarse note detune"), NULL,
 -         [](const char *msg, RtData &d)
 -         {
 -             PADnoteParameters *obj = (PADnoteParameters *)d.obj;
 -             if(!rtosc_narguments(msg)) {
 -                 int k=obj->PCoarseDetune%1024;
 -                 if (k>=512) k-=1024;
 -                 d.reply(d.loc, "i", k);
 -             } else {
 -                 int k=(int) rtosc_argument(msg, 0).i;
 -                 if (k<0) k+=1024;
 -                 obj->PCoarseDetune = k + (obj->PCoarseDetune/1024)*1024;
 -             }
 -         }},
 -     {"paste:b", rProp(internal) rDoc("paste port"), 0,
 -     [](const char *m, rtosc::RtData &d){
 -         rObject &paste = **(rObject **)rtosc_argument(m,0).b.data;
 -         rObject &o = *(rObject*)d.obj;
 -         o.pasteRT(paste);}}
 - 
 - };
 - static const rtosc::Ports non_realtime_ports =
 - {
 -     rSelf(PADnoteParameters),
 -     rPresetType,
 -     {"paste:b", rProp(internal) rDoc("paste port"), 0,
 -     [](const char *m, rtosc::RtData &d){
 -         rObject &paste = **(rObject **)rtosc_argument(m,0).b.data;
 -         rObject &o = *(rObject*)d.obj;
 -         o.paste(paste);
 -         //avoid the match to forward the request along
 -         d.matches--;}},
 -     //Harmonic Source Distribution
 -     rRecurp(oscilgen, "Oscillator"),
 -     rRecurp(resonance, "Resonance"),
 - 
 -     //Harmonic Shape
 -     rOption(Pmode, rMap(min, 0), rMap(max, 2), rShort("distribution"), rOptions(bandwidth,discrete,continious),
 -             "Harmonic Distribution Model"),
 -     rOption(Php.base.type, rOptions(Gaussian, Rectanglar, Double Exponential), rShort("shape"),
 -             "Harmonic profile shape"),
 -     rParamZyn(Php.base.par1, rShort("warp"),       "Harmonic shape distribution parameter"),
 -     rParamZyn(Php.freqmult,  rShort("clone"),     "Frequency multiplier on distribution"),
 -     rParamZyn(Php.modulator.par1, rShort("p1"),   "Distribution modulator parameter"),
 -     rParamZyn(Php.modulator.freq, rShort("freq"), "Frequency of modulator parameter"),
 -     rParamZyn(Php.width,     rShort("bandwidth"), "Width of base harmonic"),
 -     rOption(Php.amp.mode,    rShort("mode"),      rOptions(Sum, Mult, Div1, Div2),
 -             "Amplitude harmonic multiplier type"),
 - 
 -     //Harmonic Modulation
 -     rOption(Php.amp.type, rShort("mult"), rOptions(Off, Gauss, Sine, Flat),
 -             "Type of amplitude multipler"),
 -     rParamZyn(Php.amp.par1, rShort("p1"),   "Amplitude multiplier parameter"),
 -     rParamZyn(Php.amp.par2, rShort("p2"),   "Amplitude multiplier parameter"),
 -     rToggle(Php.autoscale,  rShort("auto"), "Autoscaling Harmonics"),
 -     rOption(Php.onehalf, rShort("side"),
 -             rOptions(Full, Upper Half, Lower Half),
 -             "Harmonic cutoff model"),
 - 
 -     //Harmonic Bandwidth
 -     rOption(Pbwscale, rShort("bw scale"),
 -             rOptions(Normal,
 -               EqualHz, Quater,
 -               Half, 75%, 150%,
 -               Double, Inv. Half),
 -             "Bandwidth scaling"),
 - 
 -     //Harmonic Position Modulation
 -     rOption(Phrpos.type,
 -             rOptions(Harmonic, ShiftU, ShiftL, PowerU, PowerL, Sine,
 -                 Power, Shift),
 -             "Harmonic Overtone shifting mode"),
 -     rParamI(Phrpos.par1, rShort("p1"), rLinear(0,255), "Harmonic position parameter"),
 -     rParamI(Phrpos.par2, rShort("p2"), rLinear(0,255), "Harmonic position parameter"),
 -     rParamI(Phrpos.par3, rShort("force h."), rLinear(0,255), "Harmonic position parameter"),
 - 
 -     //Quality
 -     rOption(Pquality.samplesize, rShort("quality"),
 -             rOptions(16k (Tiny), 32k, 64k (Small), 128k,
 -               256k (Normal), 512k, 1M (Big)),
 -             "Size of each wavetable element"),
 -     rOption(Pquality.basenote, rShort("basenote"),
 -             rOptions(C-2, G-2, C-3, G-3, C-4,
 -                 G-4, C-5, G-5, G-6,),
 -             "Base note for wavetable"),
 -     rOption(Pquality.smpoct, rShort("smp/oct"),
 -             rOptions(0.5, 1, 2, 3, 4, 6, 12),
 -             "Samples per octave"),
 -     rParamI(Pquality.oct, rShort("octaves"), rLinear(0,7),
 -             "Number of octaves to sample (above the first sample"),
 - 
 -     {"Pbandwidth::i", rShort("bandwidth") rProp(parameter) rLinear(0,1000) rDoc("Bandwith Of Harmonics"), NULL,
 -         [](const char *msg, rtosc::RtData &d) {
 -             PADnoteParameters *p = ((PADnoteParameters*)d.obj);
 -             if(rtosc_narguments(msg)) {
 -                 p->setPbandwidth(rtosc_argument(msg, 0).i);
 -             } else {
 -                 d.reply(d.loc, "i", p->Pbandwidth);
 -             }}},
 - 
 -     {"bandwidthvalue:", rMap(unit, cents) rDoc("Get Bandwidth"), NULL,
 -         [](const char *, rtosc::RtData &d) {
 -             PADnoteParameters *p = ((PADnoteParameters*)d.obj);
 -             d.reply(d.loc, "f", p->setPbandwidth(p->Pbandwidth));
 -         }},
 - 
 - 
 -     {"nhr:", rProp(non-realtime) rDoc("Returns the harmonic shifts"),
 -         NULL, [](const char *, rtosc::RtData &d) {
 -             PADnoteParameters *p = ((PADnoteParameters*)d.obj);
 -             const unsigned n = p->synth.oscilsize / 2;
 -             float *tmp = new float[n];
 -             *tmp = 0;
 -             for(unsigned i=1; i<n; ++i)
 -                 tmp[i] = p->getNhr(i);
 -             d.reply(d.loc, "b", n*sizeof(float), tmp);
 -             delete[] tmp;}},
 -     {"profile:i", rProp(non-realtime) rDoc("UI display of the harmonic profile"),
 -         NULL, [](const char *m, rtosc::RtData &d) {
 -             PADnoteParameters *p = ((PADnoteParameters*)d.obj);
 -             const int n = rtosc_argument(m, 0).i;
 -             if(n<=0)
 -                 return;
 -             float *tmp = new float[n];
 -             float realbw = p->getprofile(tmp, n);
 -             d.reply(d.loc, "b", n*sizeof(float), tmp);
 -             d.reply(d.loc, "i", (int)realbw);
 -             delete[] tmp;}},
 -     {"harmonic_profile:", rProp(non-realtime) rDoc("UI display of the harmonic profile"),
 -         NULL, [](const char *m, rtosc::RtData &d) {
 -             PADnoteParameters *p = ((PADnoteParameters*)d.obj);
 - #define RES 512
 -             char        types[RES+2] = {0};
 -             rtosc_arg_t args[RES+1];
 -             float tmp[RES];
 -             types[0]  = 'f';
 -             args[0].f = p->getprofile(tmp, RES);
 -             for(int i=0; i<RES; ++i) {
 -                 types[i+1]  = 'f';
 -                 args[i+1].f = tmp[i];
 -             }
 -             d.replyArray(d.loc, types, args);
 - #undef RES
 -         }},
 -     {"needPrepare:", rDoc("Unimplemented Stub"),
 -         NULL, [](const char *, rtosc::RtData&) {}},
 - };
 - #undef rChangeCb
 - 
 - const rtosc::Ports &PADnoteParameters::non_realtime_ports = ::non_realtime_ports;
 - const rtosc::Ports &PADnoteParameters::realtime_ports     = ::realtime_ports;
 - 
 - 
 - const rtosc::MergePorts PADnoteParameters::ports =
 - {
 -     &realtime_ports,
 -     &non_realtime_ports
 - };
 - 
 - 
 - PADnoteParameters::PADnoteParameters(const SYNTH_T &synth_, FFTwrapper *fft_,
 -                                      const AbsTime *time_)
 -         : Presets(), time(time_), last_update_timestamp(0), synth(synth_)
 - {
 -     setpresettype("Ppadsynth");
 - 
 -     fft   = fft_;
 - 
 -     resonance = new Resonance();
 -     oscilgen  = new OscilGen(synth, fft_, resonance);
 -     oscilgen->ADvsPAD = true;
 - 
 -     FreqEnvelope = new EnvelopeParams(0, 0, time_);
 -     FreqEnvelope->ASRinit(64, 50, 64, 60);
 -     FreqLfo = new LFOParams(70, 0, 64, 0, 0, 0, 0, 0, time_);
 - 
 -     AmpEnvelope = new EnvelopeParams(64, 1, time_);
 -     AmpEnvelope->ADSRinit_dB(0, 40, 127, 25);
 -     AmpLfo = new LFOParams(80, 0, 64, 0, 0, 0, 0, 1, time_);
 - 
 -     GlobalFilter   = new FilterParams(2, 94, 40, time_);
 -     FilterEnvelope = new EnvelopeParams(0, 1, time_);
 -     FilterEnvelope->ADSRinit_filter(64, 40, 64, 70, 60, 64);
 -     FilterLfo = new LFOParams(80, 0, 64, 0, 0, 0, 0, 2, time_);
 - 
 -     for(int i = 0; i < PAD_MAX_SAMPLES; ++i)
 -         sample[i].smp = NULL;
 - 
 -     defaults();
 - }
 - 
 - PADnoteParameters::~PADnoteParameters()
 - {
 -     deletesamples();
 -     delete (oscilgen);
 -     delete (resonance);
 - 
 -     delete (FreqEnvelope);
 -     delete (FreqLfo);
 -     delete (AmpEnvelope);
 -     delete (AmpLfo);
 -     delete (GlobalFilter);
 -     delete (FilterEnvelope);
 -     delete (FilterLfo);
 - }
 - 
 - void PADnoteParameters::defaults()
 - {
 -     Pmode = 0;
 -     Php.base.type      = 0;
 -     Php.base.par1      = 80;
 -     Php.freqmult       = 0;
 -     Php.modulator.par1 = 0;
 -     Php.modulator.freq = 30;
 -     Php.width     = 127;
 -     Php.amp.type  = 0;
 -     Php.amp.mode  = 0;
 -     Php.amp.par1  = 80;
 -     Php.amp.par2  = 64;
 -     Php.autoscale = true;
 -     Php.onehalf   = 0;
 - 
 -     setPbandwidth(500);
 -     Pbwscale = 0;
 - 
 -     resonance->defaults();
 -     oscilgen->defaults();
 - 
 -     Phrpos.type = 0;
 -     Phrpos.par1 = 0;
 -     Phrpos.par2 = 0;
 -     Phrpos.par3 = 0;
 - 
 -     Pquality.samplesize = 3;
 -     Pquality.basenote   = 4;
 -     Pquality.oct    = 3;
 -     Pquality.smpoct = 2;
 - 
 -     PStereo = 1; //stereo
 -     /* Frequency Global Parameters */
 -     Pfixedfreq    = 0;
 -     PfixedfreqET  = 0;
 -     PBendAdjust = 88; // 64 + 24
 -     POffsetHz = 64;
 -     PDetune       = 8192; //zero
 -     PCoarseDetune = 0;
 -     PDetuneType   = 1;
 -     FreqEnvelope->defaults();
 -     FreqLfo->defaults();
 - 
 -     /* Amplitude Global Parameters */
 -     PVolume  = 90;
 -     PPanning = 64; //center
 -     PAmpVelocityScaleFunction = 64;
 -     AmpEnvelope->defaults();
 -     AmpLfo->defaults();
 -     Fadein_adjustment = FADEIN_ADJUSTMENT_SCALE;
 -     PPunchStrength = 0;
 -     PPunchTime     = 60;
 -     PPunchStretch  = 64;
 -     PPunchVelocitySensing = 72;
 - 
 -     /* Filter Global Parameters*/
 -     PFilterVelocityScale = 64;
 -     PFilterVelocityScaleFunction = 64;
 -     GlobalFilter->defaults();
 -     FilterEnvelope->defaults();
 -     FilterLfo->defaults();
 - 
 -     deletesamples();
 - }
 - 
 - void PADnoteParameters::deletesample(int n)
 - {
 -     if((n < 0) || (n >= PAD_MAX_SAMPLES))
 -         return;
 - 
 -     delete[] sample[n].smp;
 -     sample[n].smp = NULL;
 -     sample[n].size     = 0;
 -     sample[n].basefreq = 440.0f;
 - }
 - 
 - void PADnoteParameters::deletesamples()
 - {
 -     for(int i = 0; i < PAD_MAX_SAMPLES; ++i)
 -         deletesample(i);
 - }
 - 
 - /*
 -  * Get the harmonic profile (i.e. the frequency distributio of a single harmonic)
 -  */
 - float PADnoteParameters::getprofile(float *smp, int size)
 - {
 -     for(int i = 0; i < size; ++i)
 -         smp[i] = 0.0f;
 -     const int supersample = 16;
 -     float     basepar     = powf(2.0f, (1.0f - Php.base.par1 / 127.0f) * 12.0f);
 -     float     freqmult    = floor(powf(2.0f,
 -                                        Php.freqmult / 127.0f
 -                                        * 5.0f) + 0.000001f);
 - 
 -     float modfreq = floor(powf(2.0f,
 -                                Php.modulator.freq / 127.0f
 -                                * 5.0f) + 0.000001f);
 -     float modpar1 = powf(Php.modulator.par1 / 127.0f, 4.0f) * 5.0f / sqrt(
 -         modfreq);
 -     float amppar1 =
 -         powf(2.0f, powf(Php.amp.par1 / 127.0f, 2.0f) * 10.0f) - 0.999f;
 -     float amppar2 = (1.0f - Php.amp.par2 / 127.0f) * 0.998f + 0.001f;
 -     float width   = powf(150.0f / (Php.width + 22.0f), 2.0f);
 - 
 -     for(int i = 0; i < size * supersample; ++i) {
 -         bool  makezero = false;
 -         float x = i * 1.0f / (size * (float) supersample);
 - 
 -         float origx = x;
 - 
 -         //do the sizing (width)
 -         x = (x - 0.5f) * width + 0.5f;
 -         if(x < 0.0f) {
 -             x = 0.0f;
 -             makezero = true;
 -         }
 -         else
 -         if(x > 1.0f) {
 -             x = 1.0f;
 -             makezero = true;
 -         }
 - 
 -         //compute the full profile or one half
 -         switch(Php.onehalf) {
 -             case 1:
 -                 x = x * 0.5f + 0.5f;
 -                 break;
 -             case 2:
 -                 x = x * 0.5f;
 -                 break;
 -         }
 - 
 -         float x_before_freq_mult = x;
 - 
 -         //do the frequency multiplier
 -         x *= freqmult;
 - 
 -         //do the modulation of the profile
 -         x += sinf(x_before_freq_mult * 3.1415926f * modfreq) * modpar1;
 -         x  = fmod(x + 1000.0f, 1.0f) * 2.0f - 1.0f;
 - 
 - 
 -         //this is the base function of the profile
 -         float f;
 -         switch(Php.base.type) {
 -             case 1:
 -                 f = expf(-(x * x) * basepar);
 -                 if(f < 0.4f)
 -                     f = 0.0f;
 -                 else
 -                     f = 1.0f;
 -                 break;
 -             case 2:
 -                 f = expf(-(fabs(x)) * sqrt(basepar));
 -                 break;
 -             default:
 -                 f = expf(-(x * x) * basepar);
 -                 break;
 -         }
 -         if(makezero)
 -             f = 0.0f;
 - 
 -         float amp = 1.0f;
 -         origx = origx * 2.0f - 1.0f;
 - 
 -         //compute the amplitude multiplier
 -         switch(Php.amp.type) {
 -             case 1:
 -                 amp = expf(-(origx * origx) * 10.0f * amppar1);
 -                 break;
 -             case 2:
 -                 amp = 0.5f
 -                       * (1.0f
 -                          + cosf(3.1415926f * origx * sqrt(amppar1 * 4.0f + 1.0f)));
 -                 break;
 -             case 3:
 -                 amp = 1.0f
 -                       / (powf(origx * (amppar1 * 2.0f + 0.8f), 14.0f) + 1.0f);
 -                 break;
 -         }
 - 
 -         //apply the amplitude multiplier
 -         float finalsmp = f;
 -         if(Php.amp.type != 0)
 -             switch(Php.amp.mode) {
 -                 case 0:
 -                     finalsmp = amp * (1.0f - amppar2) + finalsmp * amppar2;
 -                     break;
 -                 case 1:
 -                     finalsmp *= amp * (1.0f - amppar2) + amppar2;
 -                     break;
 -                 case 2:
 -                     finalsmp = finalsmp
 -                                / (amp + powf(amppar2, 4.0f) * 20.0f + 0.0001f);
 -                     break;
 -                 case 3:
 -                     finalsmp = amp
 -                                / (finalsmp
 -                                   + powf(amppar2, 4.0f) * 20.0f + 0.0001f);
 -                     break;
 -             }
 -         ;
 - 
 -         smp[i / supersample] += finalsmp / supersample;
 -     }
 - 
 -     //normalize the profile (make the max. to be equal to 1.0f)
 -     float max = 0.0f;
 -     for(int i = 0; i < size; ++i) {
 -         if(smp[i] < 0.0f)
 -             smp[i] = 0.0f;
 -         if(smp[i] > max)
 -             max = smp[i];
 -     }
 -     if(max < 0.00001f)
 -         max = 1.0f;
 -     for(int i = 0; i < size; ++i)
 -         smp[i] /= max;
 - 
 -     if(!Php.autoscale)
 -         return 0.5f;
 - 
 -     //compute the estimated perceived bandwidth
 -     float sum = 0.0f;
 -     int   i;
 -     for(i = 0; i < size / 2 - 2; ++i) {
 -         sum += smp[i] * smp[i] + smp[size - i - 1] * smp[size - i - 1];
 -         if(sum >= 4.0f)
 -             break;
 -     }
 - 
 -     float result = 1.0f - 2.0f * i / (float) size;
 -     return result;
 - }
 - 
 - /*
 -  * Compute the real bandwidth in cents and returns it
 -  * Also, sets the bandwidth parameter
 -  */
 - float PADnoteParameters::setPbandwidth(int Pbandwidth)
 - {
 -     this->Pbandwidth = Pbandwidth;
 -     float result = powf(Pbandwidth / 1000.0f, 1.1f);
 -     result = powf(10.0f, result * 4.0f) * 0.25f;
 -     return result;
 - }
 - 
 - /*
 -  * Get the harmonic(overtone) position
 -  */
 - float PADnoteParameters::getNhr(int n)
 - {
 -     float result = 1.0f;
 -     const float par1   = powf(10.0f, -(1.0f - Phrpos.par1 / 255.0f) * 3.0f);
 -     const float par2   = Phrpos.par2 / 255.0f;
 - 
 -     const float n0     = n - 1.0f;
 -     float tmp    = 0.0f;
 -     int   thresh = 0;
 -     switch(Phrpos.type) {
 -         case 1:
 -             thresh = (int)(par2 * par2 * 100.0f) + 1;
 -             if(n < thresh)
 -                 result = n;
 -             else
 -                 result = 1.0f + n0 + (n0 - thresh + 1.0f) * par1 * 8.0f;
 -             break;
 -         case 2:
 -             thresh = (int)(par2 * par2 * 100.0f) + 1;
 -             if(n < thresh)
 -                 result = n;
 -             else
 -                 result = 1.0f + n0 - (n0 - thresh + 1.0f) * par1 * 0.90f;
 -             break;
 -         case 3:
 -             tmp    = par1 * 100.0f + 1.0f;
 -             result = powf(n0 / tmp, 1.0f - par2 * 0.8f) * tmp + 1.0f;
 -             break;
 -         case 4:
 -             result = n0
 -                      * (1.0f
 -                         - par1)
 -                      + powf(n0 * 0.1f, par2 * 3.0f
 -                             + 1.0f) * par1 * 10.0f + 1.0f;
 -             break;
 -         case 5:
 -             result = n0
 -                      + sinf(n0 * par2 * par2 * PI
 -                             * 0.999f) * sqrt(par1) * 2.0f + 1.0f;
 -             break;
 -         case 6:
 -             tmp    = powf(par2 * 2.0f, 2.0f) + 0.1f;
 -             result = n0 * powf(1.0f + par1 * powf(n0 * 0.8f, tmp), tmp) + 1.0f;
 -             break;
 -         case 7:
 -             result = (n + Phrpos.par1 / 255.0f) / (Phrpos.par1 / 255.0f + 1);
 -             break;
 -         default:
 -             result = n;
 -             break;
 -     }
 - 
 -     const float par3 = Phrpos.par3 / 255.0f;
 - 
 -     const float iresult = floor(result + 0.5f);
 -     const float dresult = result - iresult;
 - 
 -     return iresult + (1.0f - par3) * dresult;
 - }
 - 
 - //Transform non zero positive signals into ones with a max of one
 - static void normalize_max(float *f, size_t len)
 - {
 -     float max = 0.0f;
 -     for(unsigned i = 0; i < len; ++i)
 -         if(f[i] > i)
 -             max = f[i];
 -     if(max > 0.000001f)
 -         for(unsigned i = 0; i < len; ++i)
 -             f[i] /= max;
 - }
 - 
 - //Translate Bandwidth scale integer into floating point value
 - static float Pbwscale_translate(char Pbwscale)
 - {
 -         switch(Pbwscale) {
 -             case 0: return 1.0f;
 -             case 1: return 0.0f;
 -             case 2: return 0.25f;
 -             case 3: return 0.5f;
 -             case 4: return 0.75f;
 -             case 5: return 1.5f;
 -             case 6: return 2.0f;
 -             case 7: return -0.5f;
 -             default: return 1.0;
 -         }
 - }
 - 
 - /*
 -  * Generates the long spectrum for Bandwidth mode (only amplitudes are generated; phases will be random)
 -  */
 - 
 - //Requires
 - // - bandwidth scaling power
 - // - bandwidth
 - // - oscilator harmonics at various frequences (oodles of data)
 - // - sampled resonance
 - void PADnoteParameters::generatespectrum_bandwidthMode(float *spectrum,
 -                                                        int size,
 -                                                        float basefreq,
 -                                                        float *profile,
 -                                                        int profilesize,
 -                                                        float bwadjust)
 - {
 -     float harmonics[synth.oscilsize];
 -     memset(spectrum, 0, sizeof(float) * size);
 -     memset(harmonics, 0, sizeof(float) * synth.oscilsize);
 - 
 -     //get the harmonic structure from the oscillator (I am using the frequency amplitudes, only)
 -     oscilgen->get(harmonics, basefreq, false);
 - 
 -     //normalize
 -     normalize_max(harmonics, synth.oscilsize / 2);
 - 
 -     //Constants across harmonics
 -     const float power = Pbwscale_translate(Pbwscale);
 -     const float bandwidthcents = setPbandwidth(Pbandwidth);
 - 
 -     for(int nh = 1; nh < synth.oscilsize / 2; ++nh) { //for each harmonic
 -         const float realfreq = getNhr(nh) * basefreq;
 -         if(realfreq > synth.samplerate_f * 0.49999f)
 -             break;
 -         if(realfreq < 20.0f)
 -             break;
 -         if(harmonics[nh - 1] < 1e-4)
 -             continue;
 - 
 -         //compute the bandwidth of each harmonic
 -         const float bw =
 -             ((powf(2.0f, bandwidthcents / 1200.0f) - 1.0f) * basefreq / bwadjust)
 -             * powf(realfreq / basefreq, power);
 -         const int ibw = (int)((bw / (synth.samplerate_f * 0.5f) * size)) + 1;
 - 
 -         float amp = harmonics[nh - 1];
 -         if(resonance->Penabled)
 -             amp *= resonance->getfreqresponse(realfreq);
 - 
 -         if(ibw > profilesize) { //if the bandwidth is larger than the profilesize
 -             const float rap   = sqrt((float)profilesize / (float)ibw);
 -             const int   cfreq =
 -                 (int) (realfreq
 -                        / (synth.samplerate_f * 0.5f) * size) - ibw / 2;
 -             for(int i = 0; i < ibw; ++i) {
 -                 const int src    = i * rap * rap;
 -                 const int spfreq = i + cfreq;
 -                 if(spfreq < 0)
 -                     continue;
 -                 if(spfreq >= size)
 -                     break;
 -                 spectrum[spfreq] += amp * profile[src] * rap;
 -             }
 -         }
 -         else {  //if the bandwidth is smaller than the profilesize
 -             const float rap = sqrt((float)ibw / (float)profilesize);
 -             const float ibasefreq = realfreq / (synth.samplerate_f * 0.5f) * size;
 -             for(int i = 0; i < profilesize; ++i) {
 -                 const float idfreq = (i / (float)profilesize - 0.5f) * ibw;
 -                 const float freqsum = idfreq + ibasefreq;
 -                 const int   spfreq  = (int)freqsum;
 -                 const float fspfreq = freqsum - spfreq;
 -                 if(spfreq <= 0)
 -                     continue;
 -                 if(spfreq >= size - 1)
 -                     break;
 -                 spectrum[spfreq] += amp * profile[i] * rap
 -                                     * (1.0f - fspfreq);
 -                 spectrum[spfreq + 1] += amp * profile[i] * rap * fspfreq;
 -             }
 -         }
 -     }
 - }
 - 
 - /*
 -  * Generates the long spectrum for non-Bandwidth modes (only amplitudes are generated; phases will be random)
 -  */
 - void PADnoteParameters::generatespectrum_otherModes(float *spectrum,
 -                                                     int size,
 -                                                     float basefreq)
 - {
 -     float harmonics[synth.oscilsize];
 -     memset(spectrum,  0, sizeof(float) * size);
 -     memset(harmonics, 0, sizeof(float) * synth.oscilsize);
 - 
 -     //get the harmonic structure from the oscillator (I am using the frequency amplitudes, only)
 -     oscilgen->get(harmonics, basefreq, false);
 - 
 -     //normalize
 -     normalize_max(harmonics, synth.oscilsize / 2);
 - 
 -     for(int nh = 1; nh < synth.oscilsize / 2; ++nh) { //for each harmonic
 -         const float realfreq = getNhr(nh) * basefreq;
 - 
 -         //take care of interpolation if frequency decreases
 -         if(realfreq > synth.samplerate_f * 0.49999f)
 -             break;
 -         if(realfreq < 20.0f)
 -             break;
 - 
 - 
 -         float amp = harmonics[nh - 1];
 -         if(resonance->Penabled)
 -             amp *= resonance->getfreqresponse(realfreq);
 -         const int cfreq = realfreq / (synth.samplerate_f * 0.5f) * size;
 - 
 -         spectrum[cfreq] = amp + 1e-9;
 -     }
 - 
 -     //In continous mode the spectrum gets additional interpolation between the
 -     //spectral peaks
 -     if(Pmode != 1) { //continous mode
 -         int old = 0;
 -         for(int k = 1; k < size; ++k)
 -             if((spectrum[k] > 1e-10) || (k == (size - 1))) {
 -                 const int   delta  = k - old;
 -                 const float val1   = spectrum[old];
 -                 const float val2   = spectrum[k];
 -                 const float idelta = 1.0f / delta;
 -                 for(int i = 0; i < delta; ++i) {
 -                     const float x = idelta * i;
 -                     spectrum[old + i] = val1 * (1.0f - x) + val2 * x;
 -                 }
 -                 old = k;
 -             }
 -     }
 - }
 - 
 - /*
 -  * Applies the parameters (i.e. computes all the samples, based on parameters);
 -  */
 - void PADnoteParameters::applyparameters()
 - {
 -     applyparameters([]{return false;});
 - }
 - 
 - void PADnoteParameters::applyparameters(std::function<bool()> do_abort)
 - {
 -     if(do_abort())
 -         return;
 -     unsigned max = 0;
 -     sampleGenerator([&max,this]
 -             (unsigned N, PADnoteParameters::Sample &smp) {
 -             delete[] sample[N].smp;
 -             sample[N] = smp;
 -             max = max < N ? N : max;
 -             },
 -             do_abort);
 - 
 -     //Delete remaining unused samples
 -     for(unsigned i = max; i < PAD_MAX_SAMPLES; ++i)
 -         deletesample(i);
 - }
 - 
 - //Requires
 - // - Pquality.samplesize
 - // - Pquality.basenote
 - // - Pquality.oct
 - // - Pquality.smpoct
 - // - spectrum at various frequencies (oodles of data)
 - void PADnoteParameters::sampleGenerator(PADnoteParameters::callback cb,
 -         std::function<bool()> do_abort)
 - {
 -     const int samplesize   = (((int) 1) << (Pquality.samplesize + 14));
 -     const int spectrumsize = samplesize / 2;
 -     float    *spectrum     = new float[spectrumsize];
 -     const int profilesize = 512;
 -     float     profile[profilesize];
 - 
 - 
 -     const float bwadjust = getprofile(profile, profilesize);
 -     float basefreq = 65.406f * powf(2.0f, Pquality.basenote / 2);
 -     if(Pquality.basenote % 2 == 1)
 -         basefreq *= 1.5f;
 - 
 -     int samplemax = Pquality.oct + 1;
 -     int smpoct    = Pquality.smpoct;
 -     if(Pquality.smpoct == 5)
 -         smpoct = 6;
 -     if(Pquality.smpoct == 6)
 -         smpoct = 12;
 -     if(smpoct != 0)
 -         samplemax *= smpoct;
 -     else
 -         samplemax = samplemax / 2 + 1;
 -     if(samplemax == 0)
 -         samplemax = 1;
 - 
 -     //prepare a BIG FFT
 -     FFTwrapper *fft      = new FFTwrapper(samplesize);
 -     fft_t      *fftfreqs = new fft_t[samplesize / 2];
 - 
 -     //this is used to compute frequency relation to the base frequency
 -     float adj[samplemax];
 -     for(int nsample = 0; nsample < samplemax; ++nsample)
 -         adj[nsample] = (Pquality.oct + 1.0f) * (float)nsample / samplemax;
 -     for(int nsample = 0; nsample < samplemax; ++nsample) {
 -         if(do_abort())
 -             goto exit;
 -         const float basefreqadjust =
 -             powf(2.0f, adj[nsample] - adj[samplemax - 1] * 0.5f);
 - 
 -         if(Pmode == 0)
 -             generatespectrum_bandwidthMode(spectrum,
 -                                            spectrumsize,
 -                                            basefreq * basefreqadjust,
 -                                            profile,
 -                                            profilesize,
 -                                            bwadjust);
 -         else
 -             generatespectrum_otherModes(spectrum, spectrumsize,
 -                                         basefreq * basefreqadjust);
 - 
 -         //the last samples contains the first samples
 -         //(used for linear/cubic interpolation)
 -         const int extra_samples = 5;
 -         PADnoteParameters::Sample newsample;
 -         newsample.smp = new float[samplesize + extra_samples];
 - 
 -         newsample.smp[0] = 0.0f;
 -         for(int i = 1; i < spectrumsize; ++i) //randomize the phases
 -             fftfreqs[i] = FFTpolar(spectrum[i], (float)RND * 2 * PI);
 -         //that's all; here is the only ifft for the whole sample;
 -         //no windows are used ;-)
 -         fft->freqs2smps(fftfreqs, newsample.smp);
 - 
 - 
 -         //normalize(rms)
 -         float rms = 0.0f;
 -         for(int i = 0; i < samplesize; ++i)
 -             rms += newsample.smp[i] * newsample.smp[i];
 -         rms = sqrt(rms);
 -         if(rms < 0.000001f)
 -             rms = 1.0f;
 -         rms *= sqrt(262144.0f / samplesize);//262144=2^18
 -         for(int i = 0; i < samplesize; ++i)
 -             newsample.smp[i] *= 1.0f / rms * 50.0f;
 - 
 -         //prepare extra samples used by the linear or cubic interpolation
 -         for(int i = 0; i < extra_samples; ++i)
 -             newsample.smp[i + samplesize] = newsample.smp[i];
 - 
 -         //yield new sample
 -         newsample.size     = samplesize;
 -         newsample.basefreq = basefreq * basefreqadjust;
 -         cb(nsample, newsample);
 -     }
 - exit:
 - 
 -     //Cleanup
 -     delete (fft);
 -     delete[] fftfreqs;
 -     delete[] spectrum;
 - }
 - 
 - void PADnoteParameters::export2wav(std::string basefilename)
 - {
 -     applyparameters();
 -     basefilename += "_PADsynth_";
 -     for(int k = 0; k < PAD_MAX_SAMPLES; ++k) {
 -         if(sample[k].smp == NULL)
 -             continue;
 -         char tmpstr[20];
 -         snprintf(tmpstr, 20, "_%02d", k + 1);
 -         std::string filename = basefilename + std::string(tmpstr) + ".wav";
 -         WavFile     wav(filename, synth.samplerate, 1);
 -         if(wav.good()) {
 -             int nsmps = sample[k].size;
 -             short int *smps = new short int[nsmps];
 -             for(int i = 0; i < nsmps; ++i)
 -                 smps[i] = (short int)(sample[k].smp[i] * 32767.0f);
 -             wav.writeMonoSamples(nsmps, smps);
 -         }
 -     }
 - }
 - 
 - void PADnoteParameters::add2XML(XMLwrapper& xml)
 - {
 -     xml.setPadSynth(true);
 - 
 -     xml.addparbool("stereo", PStereo);
 -     xml.addpar("mode", Pmode);
 -     xml.addpar("bandwidth", Pbandwidth);
 -     xml.addpar("bandwidth_scale", Pbwscale);
 - 
 -     xml.beginbranch("HARMONIC_PROFILE");
 -     xml.addpar("base_type", Php.base.type);
 -     xml.addpar("base_par1", Php.base.par1);
 -     xml.addpar("frequency_multiplier", Php.freqmult);
 -     xml.addpar("modulator_par1", Php.modulator.par1);
 -     xml.addpar("modulator_frequency", Php.modulator.freq);
 -     xml.addpar("width", Php.width);
 -     xml.addpar("amplitude_multiplier_type", Php.amp.type);
 -     xml.addpar("amplitude_multiplier_mode", Php.amp.mode);
 -     xml.addpar("amplitude_multiplier_par1", Php.amp.par1);
 -     xml.addpar("amplitude_multiplier_par2", Php.amp.par2);
 -     xml.addparbool("autoscale", Php.autoscale);
 -     xml.addpar("one_half", Php.onehalf);
 -     xml.endbranch();
 - 
 -     xml.beginbranch("OSCIL");
 -     oscilgen->add2XML(xml);
 -     xml.endbranch();
 - 
 -     xml.beginbranch("RESONANCE");
 -     resonance->add2XML(xml);
 -     xml.endbranch();
 - 
 -     xml.beginbranch("HARMONIC_POSITION");
 -     xml.addpar("type", Phrpos.type);
 -     xml.addpar("parameter1", Phrpos.par1);
 -     xml.addpar("parameter2", Phrpos.par2);
 -     xml.addpar("parameter3", Phrpos.par3);
 -     xml.endbranch();
 - 
 -     xml.beginbranch("SAMPLE_QUALITY");
 -     xml.addpar("samplesize", Pquality.samplesize);
 -     xml.addpar("basenote", Pquality.basenote);
 -     xml.addpar("octaves", Pquality.oct);
 -     xml.addpar("samples_per_octave", Pquality.smpoct);
 -     xml.endbranch();
 - 
 -     xml.beginbranch("AMPLITUDE_PARAMETERS");
 -     xml.addpar("volume", PVolume);
 -     xml.addpar("panning", PPanning);
 -     xml.addpar("velocity_sensing", PAmpVelocityScaleFunction);
 -     xml.addpar("fadein_adjustment", Fadein_adjustment);
 -     xml.addpar("punch_strength", PPunchStrength);
 -     xml.addpar("punch_time", PPunchTime);
 -     xml.addpar("punch_stretch", PPunchStretch);
 -     xml.addpar("punch_velocity_sensing", PPunchVelocitySensing);
 - 
 -     xml.beginbranch("AMPLITUDE_ENVELOPE");
 -     AmpEnvelope->add2XML(xml);
 -     xml.endbranch();
 - 
 -     xml.beginbranch("AMPLITUDE_LFO");
 -     AmpLfo->add2XML(xml);
 -     xml.endbranch();
 - 
 -     xml.endbranch();
 - 
 -     xml.beginbranch("FREQUENCY_PARAMETERS");
 -     xml.addpar("fixed_freq", Pfixedfreq);
 -     xml.addpar("fixed_freq_et", PfixedfreqET);
 -     xml.addpar("bend_adjust", PBendAdjust);
 -     xml.addpar("offset_hz", POffsetHz);
 -     xml.addpar("detune", PDetune);
 -     xml.addpar("coarse_detune", PCoarseDetune);
 -     xml.addpar("detune_type", PDetuneType);
 - 
 -     xml.beginbranch("FREQUENCY_ENVELOPE");
 -     FreqEnvelope->add2XML(xml);
 -     xml.endbranch();
 - 
 -     xml.beginbranch("FREQUENCY_LFO");
 -     FreqLfo->add2XML(xml);
 -     xml.endbranch();
 -     xml.endbranch();
 - 
 -     xml.beginbranch("FILTER_PARAMETERS");
 -     xml.addpar("velocity_sensing_amplitude", PFilterVelocityScale);
 -     xml.addpar("velocity_sensing", PFilterVelocityScaleFunction);
 - 
 -     xml.beginbranch("FILTER");
 -     GlobalFilter->add2XML(xml);
 -     xml.endbranch();
 - 
 -     xml.beginbranch("FILTER_ENVELOPE");
 -     FilterEnvelope->add2XML(xml);
 -     xml.endbranch();
 - 
 -     xml.beginbranch("FILTER_LFO");
 -     FilterLfo->add2XML(xml);
 -     xml.endbranch();
 -     xml.endbranch();
 - }
 - 
 - void PADnoteParameters::getfromXML(XMLwrapper& xml)
 - {
 -     PStereo    = xml.getparbool("stereo", PStereo);
 -     Pmode      = xml.getpar127("mode", 0);
 -     Pbandwidth = xml.getpar("bandwidth", Pbandwidth, 0, 1000);
 -     Pbwscale   = xml.getpar127("bandwidth_scale", Pbwscale);
 - 
 -     if(xml.enterbranch("HARMONIC_PROFILE")) {
 -         Php.base.type = xml.getpar127("base_type", Php.base.type);
 -         Php.base.par1 = xml.getpar127("base_par1", Php.base.par1);
 -         Php.freqmult  = xml.getpar127("frequency_multiplier",
 -                                        Php.freqmult);
 -         Php.modulator.par1 = xml.getpar127("modulator_par1",
 -                                             Php.modulator.par1);
 -         Php.modulator.freq = xml.getpar127("modulator_frequency",
 -                                             Php.modulator.freq);
 -         Php.width    = xml.getpar127("width", Php.width);
 -         Php.amp.type = xml.getpar127("amplitude_multiplier_type",
 -                                       Php.amp.type);
 -         Php.amp.mode = xml.getpar127("amplitude_multiplier_mode",
 -                                       Php.amp.mode);
 -         Php.amp.par1 = xml.getpar127("amplitude_multiplier_par1",
 -                                       Php.amp.par1);
 -         Php.amp.par2 = xml.getpar127("amplitude_multiplier_par2",
 -                                       Php.amp.par2);
 -         Php.autoscale = xml.getparbool("autoscale", Php.autoscale);
 -         Php.onehalf   = xml.getpar127("one_half", Php.onehalf);
 -         xml.exitbranch();
 -     }
 - 
 -     if(xml.enterbranch("OSCIL")) {
 -         oscilgen->getfromXML(xml);
 -         xml.exitbranch();
 -     }
 - 
 -     if(xml.enterbranch("RESONANCE")) {
 -         resonance->getfromXML(xml);
 -         xml.exitbranch();
 -     }
 - 
 -     if(xml.enterbranch("HARMONIC_POSITION")) {
 -         Phrpos.type = xml.getpar127("type", Phrpos.type);
 -         Phrpos.par1 = xml.getpar("parameter1", Phrpos.par1, 0, 255);
 -         Phrpos.par2 = xml.getpar("parameter2", Phrpos.par2, 0, 255);
 -         Phrpos.par3 = xml.getpar("parameter3", Phrpos.par3, 0, 255);
 -         xml.exitbranch();
 -     }
 - 
 -     if(xml.enterbranch("SAMPLE_QUALITY")) {
 -         Pquality.samplesize = xml.getpar127("samplesize", Pquality.samplesize);
 -         Pquality.basenote   = xml.getpar127("basenote", Pquality.basenote);
 -         Pquality.oct    = xml.getpar127("octaves", Pquality.oct);
 -         Pquality.smpoct = xml.getpar127("samples_per_octave",
 -                                          Pquality.smpoct);
 -         xml.exitbranch();
 -     }
 - 
 -     if(xml.enterbranch("AMPLITUDE_PARAMETERS")) {
 -         PVolume  = xml.getpar127("volume", PVolume);
 -         PPanning = xml.getpar127("panning", PPanning);
 -         PAmpVelocityScaleFunction = xml.getpar127("velocity_sensing",
 -                                                    PAmpVelocityScaleFunction);
 -         Fadein_adjustment = xml.getpar127("fadein_adjustment", Fadein_adjustment);
 -         PPunchStrength = xml.getpar127("punch_strength", PPunchStrength);
 -         PPunchTime     = xml.getpar127("punch_time", PPunchTime);
 -         PPunchStretch  = xml.getpar127("punch_stretch", PPunchStretch);
 -         PPunchVelocitySensing = xml.getpar127("punch_velocity_sensing",
 -                                                PPunchVelocitySensing);
 - 
 -         xml.enterbranch("AMPLITUDE_ENVELOPE");
 -         AmpEnvelope->getfromXML(xml);
 -         xml.exitbranch();
 - 
 -         xml.enterbranch("AMPLITUDE_LFO");
 -         AmpLfo->getfromXML(xml);
 -         xml.exitbranch();
 - 
 -         xml.exitbranch();
 -     }
 - 
 -     if(xml.enterbranch("FREQUENCY_PARAMETERS")) {
 -         Pfixedfreq    = xml.getpar127("fixed_freq", Pfixedfreq);
 -         PfixedfreqET  = xml.getpar127("fixed_freq_et", PfixedfreqET);
 -         PBendAdjust  = xml.getpar127("bend_adjust", PBendAdjust);
 -         POffsetHz  = xml.getpar127("offset_hz", POffsetHz);
 -         PDetune       = xml.getpar("detune", PDetune, 0, 16383);
 -         PCoarseDetune = xml.getpar("coarse_detune", PCoarseDetune, 0, 16383);
 -         PDetuneType   = xml.getpar127("detune_type", PDetuneType);
 - 
 -         xml.enterbranch("FREQUENCY_ENVELOPE");
 -         FreqEnvelope->getfromXML(xml);
 -         xml.exitbranch();
 - 
 -         xml.enterbranch("FREQUENCY_LFO");
 -         FreqLfo->getfromXML(xml);
 -         xml.exitbranch();
 -         xml.exitbranch();
 -     }
 - 
 -     if(xml.enterbranch("FILTER_PARAMETERS")) {
 -         PFilterVelocityScale = xml.getpar127("velocity_sensing_amplitude",
 -                                               PFilterVelocityScale);
 -         PFilterVelocityScaleFunction = xml.getpar127(
 -             "velocity_sensing",
 -             PFilterVelocityScaleFunction);
 - 
 -         xml.enterbranch("FILTER");
 -         GlobalFilter->getfromXML(xml);
 -         xml.exitbranch();
 - 
 -         xml.enterbranch("FILTER_ENVELOPE");
 -         FilterEnvelope->getfromXML(xml);
 -         xml.exitbranch();
 - 
 -         xml.enterbranch("FILTER_LFO");
 -         FilterLfo->getfromXML(xml);
 -         xml.exitbranch();
 -         xml.exitbranch();
 -     }
 - }
 - 
 - #define COPY(y) this->y = x.y
 - void PADnoteParameters::paste(PADnoteParameters &x)
 - {
 -     COPY(Pmode);
 - 
 -     COPY(Php.base.type);
 -     COPY(Php.base.par1);
 -     COPY(Php.freqmult);
 -     COPY(Php.modulator.par1);
 -     COPY(Php.modulator.freq);
 -     COPY(Php.width);
 -     COPY(Php.amp.mode);
 -     COPY(Php.amp.type);
 -     COPY(Php.amp.par1);
 -     COPY(Php.amp.par2);
 -     COPY(Php.autoscale);
 -     COPY(Php.onehalf);
 - 
 -     COPY(Pbandwidth);
 -     COPY(Pbwscale);
 - 
 -     COPY(Phrpos.type);
 -     COPY(Phrpos.par1);
 -     COPY(Phrpos.par2);
 -     COPY(Phrpos.par3);
 - 
 -     COPY(Pquality.samplesize);
 -     COPY(Pquality.basenote);
 -     COPY(Pquality.oct);
 -     COPY(Pquality.smpoct);
 - 
 -     oscilgen->paste(*x.oscilgen);
 -     resonance->paste(*x.resonance);
 - 
 -     if ( time ) {
 -         last_update_timestamp = time->time();
 -     }
 - }
 - 
 - void PADnoteParameters::pasteRT(PADnoteParameters &x)
 - {
 -     //Realtime stuff
 - 
 -     COPY(Pfixedfreq);
 - 
 -     COPY(PfixedfreqET);
 -     COPY(PBendAdjust);
 -     COPY(POffsetHz);
 -     COPY(PDetune);
 -     COPY(PCoarseDetune);
 -     COPY(PDetuneType);
 - 
 -     FreqEnvelope->paste(*x.FreqEnvelope);
 -     FreqLfo->paste(*x.FreqLfo);
 - 
 -     COPY(PStereo);
 -     COPY(PPanning);
 -     COPY(PVolume);
 -     COPY(PAmpVelocityScaleFunction);
 - 
 -     AmpEnvelope->paste(*x.AmpEnvelope);
 -     AmpLfo->paste(*x.AmpLfo);
 - 
 -     COPY(Fadein_adjustment);
 -     COPY(PPunchStrength);
 -     COPY(PPunchTime);
 -     COPY(PPunchStretch);
 -     COPY(PPunchVelocitySensing);
 - 
 -     GlobalFilter->paste(*x.GlobalFilter);
 - 
 -     COPY(PFilterVelocityScale);
 -     COPY(PFilterVelocityScaleFunction);
 - 
 -     FilterEnvelope->paste(*x.FilterEnvelope);
 -     FilterLfo->paste(*x.FilterLfo);
 - 
 -     if ( time ) {
 -         last_update_timestamp = time->time();
 -     }
 - }
 - #undef COPY
 
 
  |