aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormick grierson <mickgrierson@gmail.com>2016-12-19 22:35:23 +0000
committermick grierson <mickgrierson@gmail.com>2016-12-19 22:35:23 +0000
commitcfb9046eec768c76baa4c0711870bb255c86ef4a (patch)
tree0fdfcc93fe645e3f54662bf59d3fefb7f337c60c
parent17fd15bf2e9cf1163d40d98286abd60378fd9df9 (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-xmain.cpp76
-rw-r--r--maximilian.cpp114
-rwxr-xr-xmaximilian.h16
3 files changed, 169 insertions, 37 deletions
diff --git a/main.cpp b/main.cpp
index ac320ba..e1bc272 100755
--- a/main.cpp
+++ b/main.cpp
@@ -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;