zynaddsubfx

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

commit cca7937c098fa5b7251bce98c93b55f703399cce
parent 10b7437b8ec86e5df53e93b7a1a114824dbd2e0f
Author: fundamental <mark.d.mccurry@gmail.com>
Date:   Sun, 11 Jul 2010 18:13:53 -0400

SUBnote: Removing redundancy in legatonote

Diffstat:
Msrc/Synth/SUBnote.cpp | 231++++++++++++++++++++-----------------------------------------------------------
Msrc/Synth/SUBnote.h | 13+++----------
2 files changed, 61 insertions(+), 183 deletions(-)

diff --git a/src/Synth/SUBnote.cpp b/src/Synth/SUBnote.cpp @@ -20,9 +20,9 @@ */ -#include <math.h> -#include <stdlib.h> -#include <stdio.h> +#include <cmath> +#include <cstdlib> +#include <cstdio> #include "../globals.h" #include "SUBnote.h" #include "../Misc/Util.h" @@ -37,9 +37,14 @@ SUBnote::SUBnote(SUBnoteParameters *parameters, :SynthNote(freq, velocity, portamento_, midinote, besilent) { ready = false; - pars = parameters; ctl = ctl_; + NoteEnabled= ON; + setup(freq, velocity, portamento_, midinote); +} + +void SUBnote::setup(REALTYPE freq, REALTYPE velocity, int portamento_, int midinote, bool legato) +{ portamento = portamento_; NoteEnabled = ON; volume = pow(0.1, 3.0 * (1.0 - pars->PVolume / 96.0)); //-60 dB .. 0 dB @@ -48,10 +53,12 @@ SUBnote::SUBnote(SUBnoteParameters *parameters, panning = pars->PPanning / 127.0; else panning = RND; - numstages = pars->Pnumstages; - stereo = pars->Pstereo; - start = pars->Pstart; - firsttick = 1; + if(!legato) { + numstages = pars->Pnumstages; + stereo = pars->Pstereo; + start = pars->Pstart; + firsttick = 1; + } int pos[MAX_SUB_HARMONICS]; if(pars->Pfixedfreq == 0) @@ -82,20 +89,30 @@ SUBnote::SUBnote(SUBnoteParameters *parameters, pars->PGlobalFilterVelocityScaleFunction) - 1); - GlobalFilterL = NULL; - GlobalFilterR = NULL; - GlobalFilterEnvelope = NULL; + if(!legato) { + GlobalFilterL = NULL; + GlobalFilterR = NULL; + GlobalFilterEnvelope = NULL; + } //select only harmonics that desire to compute - numharmonics = 0; + int harmonics = 0; for(int n = 0; n < MAX_SUB_HARMONICS; n++) { if(pars->Phmag[n] == 0) continue; if(n * basefreq > SAMPLE_RATE / 2.0) break; //remove the freqs above the Nyquist freq - pos[numharmonics++] = n; + pos[harmonics++] = n; + } + if(!legato) + firstnumharmonics = numharmonics = harmonics; + else { + if(harmonics > firstnumharmonics) + numharmonics = firstnumharmonics; + else + numharmonics = harmonics; } - firstnumharmonics = numharmonics; //(gf)Useful in legato mode. + if(numharmonics == 0) { NoteEnabled = OFF; @@ -103,9 +120,11 @@ SUBnote::SUBnote(SUBnoteParameters *parameters, } - lfilter = new bpfilter[numstages * numharmonics]; - if(stereo != 0) - rfilter = new bpfilter[numstages * numharmonics]; + if(!legato) { + lfilter = new bpfilter[numstages * numharmonics]; + if(stereo != 0) + rfilter = new bpfilter[numstages * numharmonics]; + } //how much the amplitude is normalised (because the harmonics) REALTYPE reduceamp = 0.0; @@ -167,172 +186,38 @@ SUBnote::SUBnote(SUBnoteParameters *parameters, oldpitchwheel = 0; oldbandwidth = 64; - if(pars->Pfixedfreq == 0) - initparameters(basefreq); - else - initparameters(basefreq / 440.0 * freq); + if(!legato) { + if(pars->Pfixedfreq == 0) + initparameters(basefreq); + else + initparameters(basefreq / 440.0 * freq); + } + else { + if(pars->Pfixedfreq == 0) + freq = basefreq; + else + freq *= basefreq / 440.0; + + if(pars->PGlobalFilterEnabled != 0) { + globalfiltercenterq = pars->GlobalFilter->getq(); + GlobalFilterFreqTracking = pars->GlobalFilter->getfreqtracking(basefreq); + } + } oldamplitude = newamplitude; ready = true; } - -// legatonote: This function is (mostly) a copy of SUBnote(...) and -// initparameters(...) stuck together with some lines removed so that -// it only alter the already playing note (to perform legato). It is -// possible I left stuff that is not required for this. -void SUBnote::legatonote(REALTYPE freq, - REALTYPE velocity, - int portamento_, - int midinote, - bool externcall) +void SUBnote::legatonote(REALTYPE freq, REALTYPE velocity, int portamento_, + int midinote, bool externcall) { // Manage legato stuff if(legato.update(freq, velocity, portamento_, midinote, externcall)) return; - portamento = portamento_; - - volume = pow(0.1, 3.0 * (1.0 - pars->PVolume / 96.0)); //-60 dB .. 0 dB - volume *= VelF(velocity, pars->PAmpVelocityScaleFunction); - if(pars->PPanning != 0) - panning = pars->PPanning / 127.0; - else - panning = RND; - - ///start=pars->Pstart; - - int pos[MAX_SUB_HARMONICS]; - - if(pars->Pfixedfreq == 0) - basefreq = freq; - else { - basefreq = 440.0; - int fixedfreqET = pars->PfixedfreqET; - if(fixedfreqET != 0) { //if the frequency varies according the keyboard note - REALTYPE tmp = - (midinote - - 69.0) / 12.0 * (pow(2.0, (fixedfreqET - 1) / 63.0) - 1.0); - if(fixedfreqET <= 64) - basefreq *= pow(2.0, tmp); - else - basefreq *= pow(3.0, tmp); - } - } - REALTYPE detune = getdetune(pars->PDetuneType, - pars->PCoarseDetune, - pars->PDetune); - basefreq *= pow(2.0, detune / 1200.0); //detune - - //global filter - GlobalFilterCenterPitch = pars->GlobalFilter->getfreq() //center freq - + (pars->PGlobalFilterVelocityScale / 127.0 * 6.0) //velocity sensing - * (VelF(velocity, - pars->PGlobalFilterVelocityScaleFunction) - - 1); - - - int legatonumharmonics = 0; - for(int n = 0; n < MAX_SUB_HARMONICS; n++) { - if(pars->Phmag[n] == 0) - continue; - if(n * basefreq > SAMPLE_RATE / 2.0) - break; //remove the freqs above the Nyquist freq - pos[legatonumharmonics++] = n; - } - if(legatonumharmonics > firstnumharmonics) - numharmonics = firstnumharmonics; - else - numharmonics = legatonumharmonics; - - if(numharmonics == 0) { - NoteEnabled = OFF; - return; - } - - - //how much the amplitude is normalised (because the harmonics) - REALTYPE reduceamp = 0.0; - - for(int n = 0; n < numharmonics; n++) { - REALTYPE freq = basefreq * (pos[n] + 1); - - //the bandwidth is not absolute(Hz); it is relative to frequency - REALTYPE bw = - pow(10, (pars->Pbandwidth - 127.0) / 127.0 * 4) * numstages; - - //Bandwidth Scale - bw *= pow(1000 / freq, (pars->Pbwscale - 64.0) / 64.0 * 3.0); - - //Relative BandWidth - bw *= pow(100, (pars->Phrelbw[pos[n]] - 64.0) / 64.0); - - if(bw > 25.0) - bw = 25.0; - - //try to keep same amplitude on all freqs and bw. (empirically) - REALTYPE gain = sqrt(1500.0 / (bw * freq)); - - REALTYPE hmagnew = 1.0 - pars->Phmag[pos[n]] / 127.0; - REALTYPE hgain; - - switch(pars->Phmagtype) { - case 1: - hgain = exp(hmagnew * log(0.01)); - break; - case 2: - hgain = exp(hmagnew * log(0.001)); - break; - case 3: - hgain = exp(hmagnew * log(0.0001)); - break; - case 4: - hgain = exp(hmagnew * log(0.00001)); - break; - default: - hgain = 1.0 - hmagnew; - } - gain *= hgain; - reduceamp += hgain; - - for(int nph = 0; nph < numstages; nph++) { - REALTYPE amp = 1.0; - if(nph == 0) - amp = gain; - initfilter(lfilter[nph + n * numstages], freq, bw, amp, hgain); - if(stereo != 0) - initfilter(rfilter[nph + n * numstages], freq, bw, amp, hgain); - } - } - - if(reduceamp < 0.001) - reduceamp = 1.0; - volume /= reduceamp; - - oldpitchwheel = 0; - oldbandwidth = 64; - - if(pars->Pfixedfreq == 0) - freq = basefreq; - else - freq *= basefreq / 440.0; - - - /////////////// - // Altered initparameters(...) content: - - if(pars->PGlobalFilterEnabled != 0) { - globalfiltercenterq = pars->GlobalFilter->getq(); - GlobalFilterFreqTracking = pars->GlobalFilter->getfreqtracking(basefreq); - } - - // end of the altered initparameters function content. - /////////////// - - oldamplitude = newamplitude; + setup(freq, velocity, portamento_, midinote, true); } - SUBnote::~SUBnote() { if(NoteEnabled != OFF) @@ -370,7 +255,7 @@ void SUBnote::computefiltercoefs(bpfilter &filter, { if(freq > SAMPLE_RATE / 2.0 - 200.0) freq = SAMPLE_RATE / 2.0 - 200.0; - ; + REALTYPE omega = 2.0 * PI * freq / SAMPLE_RATE; REALTYPE sn = sin(omega); @@ -532,7 +417,7 @@ void SUBnote::computecurrentparameters() gain); } } - ; + oldbandwidth = ctl->bandwidth.data; oldpitchwheel = ctl->pitchwheel.data; } diff --git a/src/Synth/SUBnote.h b/src/Synth/SUBnote.h @@ -33,13 +33,8 @@ class SUBnote :public SynthNote { public: - SUBnote(SUBnoteParameters *parameters, - Controller *ctl_, - REALTYPE freq, - REALTYPE velocity, - int portamento_, - int midinote, - bool besilent); + SUBnote(SUBnoteParameters *parameters, Controller *ctl_, REALTYPE freq, + REALTYPE velocity, int portamento_, int midinote, bool besilent); ~SUBnote(); void legatonote(REALTYPE freq, REALTYPE velocity, int portamento_, @@ -50,6 +45,7 @@ class SUBnote :public SynthNote int finished() const; private: + void setup(REALTYPE freq, REALTYPE velocity, int portamento_, int midinote, bool legato=false); void computecurrentparameters(); void initparameters(REALTYPE freq); void KillNote(); @@ -107,8 +103,5 @@ class SUBnote :public SynthNote REALTYPE globalfiltercenterq; }; - - - #endif