diff options
| author | mick grierson <mickgrierson@gmail.com> | 2016-12-19 22:35:23 +0000 |
|---|---|---|
| committer | mick grierson <mickgrierson@gmail.com> | 2016-12-19 22:35:23 +0000 |
| commit | cfb9046eec768c76baa4c0711870bb255c86ef4a (patch) | |
| tree | 0fdfcc93fe645e3f54662bf59d3fefb7f337c60c | |
| parent | 17fd15bf2e9cf1163d40d98286abd60378fd9df9 (diff) | |
Fixing errors in new envelope functions. maxiEnvelope now has a ramp function, a ramps function that takes time / value pairs from a std::vector, an adsr and ar that all sync directly to the samplerate. They all take params in seconds. This makes it easier for javascript users when I transpile with emscripten. Wait what?
| -rwxr-xr-x | main.cpp | 76 | ||||
| -rw-r--r-- | maximilian.cpp | 114 | ||||
| -rwxr-xr-x | maximilian.h | 16 |
3 files changed, 169 insertions, 37 deletions
@@ -3,20 +3,88 @@ maxiOsc myOsc; maxiEnvelope myEnv; int counter; -double tv[8] = {1,1,0,1,1,2,0,4}; +double vals[12]={1,0.1,0.5,0.0,1.5,0.0,0.1,1,1.0,0.15,1.0,0.1}; +std::vector<double> rampsA(vals, vals+12); + void setup() {//some inits - + + myEnv.note(true); + } void play(double *output) {//this is where the magic happens. Very slow magic. + counter++; + if (counter ==0 || counter % 330400==0) { + myEnv.note(true); + } - double out = myEnv.ramps(tv); - output[0]=myOsc.sinewave(440)*out; + double out = myEnv.ramps(rampsA); + output[0]=myOsc.sinewave(440)*out; + output[1]=output[0]; } + +//#include "maximilian.h" +// +//maxiOsc myOsc; +//maxiEnvelope myEnv; +//int counter; +// +//void setup() { +// cout << myEnv.trigger << endl; +//} +// +//void play(double *output) { +// +// +// if (counter ==0 || counter % 88201==0) { +// myEnv.note(true); +// } +// +// if (counter % 44100==0) { +// myEnv.note(false); +// } +// +// counter++; +// +// double out = myEnv.adsr(); +// +// output[0]=myOsc.sinewave(440)*out; +// +// output[1]=output[0]; +// +//} + +//#include "maximilian.h" +// +//maxiOsc myOsc; +//maxiEnvelope myEnv; +//int counter; +// +//void setup() { +// cout << myEnv.trigger << endl; +//} +// +//void play(double *output) { +// +// +// if (counter ==0 || counter % 88200==0) { +// myEnv.note(true); +// } +// +// +// counter++; +// +// double out = myEnv.ar(1,1); +// +// output[0]=myOsc.sinewave(440)*out; +// +// output[1]=output[0]; +// +//} diff --git a/maximilian.cpp b/maximilian.cpp index ca3517d..5609aad 100644 --- a/maximilian.cpp +++ b/maximilian.cpp @@ -364,6 +364,8 @@ double maxiOsc::triangle(double frequency) { } +// don't use this nonsense. Use ramps instead. +// ..er... I mean "This method is deprecated" double maxiEnvelope::line(int numberofsegments,double segments[1000]) { //This is a basic multi-segment ramp generator that you can use for more or less anything. //However, it's not that intuitive. @@ -399,13 +401,23 @@ double maxiEnvelope::line(int numberofsegments,double segments[1000]) { // //} -double maxiEnvelope::ramp(double startVal, double endVal, double duration, int trigger1){ - +void maxiEnvelope::note(bool noteOn) { + + if (noteOn) trigger=1; + if (noteOn==false) trigger=0; + +} + +double maxiEnvelope::ramp(double startVal, double endVal, double duration){ + if (trigger!=0) { phase=startVal; + isPlaying=true; trigger=0; } + if (isPlaying) { + if (startVal<endVal) { phase += ((endVal-startVal)/(maxiSettings::sampleRate/(1./duration))); if ( phase >= endVal ) phase = endVal; @@ -416,41 +428,90 @@ double maxiEnvelope::ramp(double startVal, double endVal, double duration, int t if ( phase <= endVal ) phase = endVal; } return(phase); + } else { + + return(0); + + } + } -double maxiEnvelope::ramps(double rampsArray[1000], int trigger1){ +double maxiEnvelope::ramps(std::vector<double> rampsArray){ if (trigger!=0) { valindex=0; - endVal=rampsArray[valindex]; + endVal=rampsArray[valindex+1]; + isPlaying=true; trigger=0; - + } - if (phase<endVal) { - phase += ((endVal-startVal)/(maxiSettings::sampleRate/(1./rampsArray[valindex+1]))); - if ( phase >= endVal ) { - startVal=phase; - valindex+=2; - endVal=rampsArray[valindex]; + if (isPlaying) { + + if (valindex>0 && rampsArray[valindex-1]==rampsArray[valindex+1]) { + period += (1/(maxiSettings::sampleRate/(1./rampsArray[valindex]))); + if (period>=1) { + phase=endVal; + startVal=phase; + if (valindex+2<rampsArray.size()){ + valindex+=2; + endVal=rampsArray[valindex+1]; + period=0; + } + } output=phase; } - } - - if (phase > endVal) { - phase += ((endVal-startVal)/(maxiSettings::sampleRate/(1./rampsArray[valindex+1]))); - if ( phase <= endVal ) { - startVal=phase; - valindex+=2; - endVal=rampsArray[valindex]; + + if (valindex==0 && output==endVal) { + period += (1/(maxiSettings::sampleRate/(1./rampsArray[valindex]))); + if (period>=1) { + phase=endVal; + startVal=phase; + if (valindex+2<rampsArray.size()){ + valindex+=2; + endVal=rampsArray[valindex+1]; + period=0; + } + } output=phase; } - } - return(phase); + + if (phase<endVal) { + phase += ((endVal-startVal)/(maxiSettings::sampleRate/(1./rampsArray[valindex]))); + if ( phase >= endVal ) { + phase=endVal; + startVal=phase; + if (valindex+2<rampsArray.size()){ + valindex+=2; + endVal=rampsArray[valindex+1]; + + } + } + output=phase; + } + + if (phase > endVal) { + phase += ((endVal-startVal)/(maxiSettings::sampleRate/(1./rampsArray[valindex]))); + if ( phase <= endVal ) { + phase=endVal; + startVal=phase; + if (valindex+2<rampsArray.size()){ + valindex+=2; + endVal=rampsArray[valindex+1]; + + } + } output=phase; + } + + return(output); + } else { + + return(0); + } } -double maxiEnvelope::ar(double attack, double release,int trigger1) { +double maxiEnvelope::ar(double attack, double release) { if (trigger!=0) { phase=0; @@ -475,18 +536,19 @@ double maxiEnvelope::ar(double attack, double release,int trigger1) { } -double maxiEnvelope::adsr(double attack, double decay, double sustain, double release, int trigger1) { +double maxiEnvelope::adsr(double attack, double decay, double sustain, double release) { - if (trigger!=0 && !releaseMode && !decayMode && !sustainMode) { - phase=0; + if (trigger!=0 && !attackMode && !decayMode && !sustainMode && !releaseMode) { + phase=0.; releaseMode=false; decayMode=false; sustainMode=false; attackMode=true; } - if (phase<1 && attackMode) { + if (attackMode) { phase += ((1)/(maxiSettings::sampleRate/(1./attack))); + if ( phase >= 1 ) { phase=1; attackMode=false; diff --git a/maximilian.h b/maximilian.h index fa53428..54dec4b 100755 --- a/maximilian.h +++ b/maximilian.h @@ -109,27 +109,29 @@ public: class maxiEnvelope { - double period; + double period=0; double output; double phase; double startVal; double endVal; double currentval; double nextval; + bool noteOn; bool releaseMode; bool decayMode; bool sustainMode; - bool attackMode=true; + bool attackMode; int isPlaying; public: - int trigger=1; + int trigger; double line(int numberofsegments,double segments[100]); - double ramp(double startVal=0, double endVal=1, double duration=1, int trigger=1); - double ramps(double rampsArray[1000], int trigger=1); - double ar(double attack=0.1, double release=0.1,int trigger=1); - double adsr(double attack=0.1, double decay=0.1, double sustain=0.1, double release=0.1,int trigger=1); + double ramp(double startVal=0, double endVal=1, double duration=1); + double ramps(std::vector<double> rampsArray); + double ar(double attack=0.1, double release=0.1); + double adsr(double attack=0.1, double decay=0.1, double sustain=0.1, double release=0.1); // void trigger(int index,double amp); + void note(bool noteOn=false); int valindex; double amplitude; |
