HAHA! commit
This commit is contained in:
Executable
+172
@@ -0,0 +1,172 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Copyright (c) 2007 Gerhard Reitmayr <gerhard.reitmayr@gmail.com>
|
||||
Permission to use, copy, modify, and distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _FSM_H
|
||||
#define _FSM_H
|
||||
|
||||
/// list of ints as recursive type
|
||||
template <int HEAD, class TAIL> struct IntList {
|
||||
enum { head = HEAD };
|
||||
typedef TAIL tail;
|
||||
};
|
||||
|
||||
/// end of list marker type
|
||||
struct IntListEnd {};
|
||||
|
||||
/// switch statement implementation through iterating over the type list and
|
||||
/// comparing it to a given state
|
||||
template <class STATELIST>
|
||||
struct SwitchTemplate {
|
||||
template <class CONTEXT>
|
||||
static typename CONTEXT::ReturnType work( int state, CONTEXT & context){
|
||||
return ((STATELIST::head == state) ?
|
||||
context.template operator()<STATELIST::head>() :
|
||||
SwitchTemplate<typename STATELIST::tail>::work( state, context ));
|
||||
}
|
||||
};
|
||||
|
||||
/// end of list marker specialization
|
||||
template <>
|
||||
struct SwitchTemplate<IntListEnd> {
|
||||
template <class CONTEXT>
|
||||
static typename CONTEXT::ReturnType work( int state, CONTEXT & context){
|
||||
return typename CONTEXT::ReturnType();
|
||||
}
|
||||
};
|
||||
|
||||
/// The actual state machine implementation
|
||||
/// sub types are functors passed to the Worker class to execute the
|
||||
/// right template specialization of the underlying member function of the
|
||||
/// context object.
|
||||
template <class CONTEXT, class STATELIST = typename CONTEXT::StateList>
|
||||
struct StateMachine {
|
||||
|
||||
CONTEXT & context;
|
||||
int state;
|
||||
|
||||
template <class RET, class DATA> struct CallEvent {
|
||||
typedef RET ReturnType;
|
||||
CONTEXT & context;
|
||||
DATA & data;
|
||||
|
||||
template <int STATE> RET operator()(){
|
||||
return context.template event<STATE>(data);
|
||||
}
|
||||
};
|
||||
|
||||
template <class RET, class DATA> struct CallEventConst {
|
||||
typedef RET ReturnType;
|
||||
CONTEXT & context;
|
||||
const DATA & data;
|
||||
|
||||
template <int STATE> RET operator()(){
|
||||
return context.template event<STATE>(data);
|
||||
}
|
||||
};
|
||||
|
||||
template <class RET> struct CallEventNoData {
|
||||
typedef RET ReturnType;
|
||||
CONTEXT & context;
|
||||
|
||||
template <int STATE> RET operator()(){
|
||||
return context.template event<STATE>();
|
||||
}
|
||||
};
|
||||
|
||||
struct CallEnter {
|
||||
typedef void ReturnType;
|
||||
CONTEXT & context;
|
||||
|
||||
template <int STATE> ReturnType operator()(){
|
||||
return context.template enter<STATE>();
|
||||
}
|
||||
};
|
||||
|
||||
struct CallExit {
|
||||
typedef void ReturnType;
|
||||
CONTEXT & context;
|
||||
|
||||
template <int STATE> ReturnType operator()(){
|
||||
return context.template exit<STATE>();
|
||||
}
|
||||
};
|
||||
|
||||
struct CallTick {
|
||||
typedef void ReturnType;
|
||||
CONTEXT & context;
|
||||
|
||||
template <int STATE> ReturnType operator()(){
|
||||
return context.template tick<STATE>();
|
||||
}
|
||||
};
|
||||
|
||||
StateMachine( CONTEXT & c ) : context(c), state(STATELIST::head) {
|
||||
CallEnter cee = {context};
|
||||
SwitchTemplate<STATELIST>::work(state, cee);
|
||||
}
|
||||
|
||||
void changeState(const int newstate){
|
||||
CallExit cl = {context};
|
||||
SwitchTemplate<STATELIST>::work(state, cl);
|
||||
state = newstate;
|
||||
CallEnter cee = {context};
|
||||
SwitchTemplate<STATELIST>::work(state, cee);
|
||||
}
|
||||
|
||||
void tick() {
|
||||
CallTick ct = {context};
|
||||
SwitchTemplate<STATELIST>::work(state, ct);
|
||||
}
|
||||
|
||||
void work(){
|
||||
CallEventNoData<int> ce = {context};
|
||||
int newstate = SwitchTemplate<STATELIST>::work(state, ce);
|
||||
if(newstate != state)
|
||||
changeState(newstate);
|
||||
}
|
||||
|
||||
template <class EVENT>
|
||||
void work( const EVENT & ev ){
|
||||
CallEventConst<int, EVENT> ce = {context, ev};
|
||||
int newstate = SwitchTemplate<STATELIST>::work(state, ce);
|
||||
if(newstate != state)
|
||||
changeState(newstate);
|
||||
}
|
||||
|
||||
template <class EVENT>
|
||||
void work( EVENT & ev ){
|
||||
CallEvent<int, EVENT> ce = {context, ev};
|
||||
int newstate = SwitchTemplate<STATELIST>::work(state, ce);
|
||||
if(newstate != state)
|
||||
changeState(newstate);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/// macros for simple state list definition
|
||||
#define LIST1(a) IntList<a,IntListEnd>
|
||||
#define LIST2(a,b) IntList<a,LIST1(b) >
|
||||
#define LIST3(a,b,c) IntList<a,LIST2(b,c) >
|
||||
#define LIST4(a,b,c,d) IntList<a,LIST3(b,c,d) >
|
||||
#define LIST5(a,b,c,d,e) IntList<a,LIST4(b,c,d,e) >
|
||||
#define LIST6(a,b,c,d,e,f) IntList<a,LIST5(b,c,d,e,f) >
|
||||
#define LIST7(a,b,c,d,e,f,g) IntList<a,LIST6(b,c,d,e,f,g) >
|
||||
#define LIST8(a,b,c,d,e,f,g,h) IntList<a,LIST7(b,c,d,e,f,g,h) >
|
||||
|
||||
#endif // _FSM_H
|
||||
Executable
+76
@@ -0,0 +1,76 @@
|
||||
#include "fsm.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
struct Event { int state; };
|
||||
enum States { AAAA, BBBB, CCCC };
|
||||
|
||||
struct QQQQSwitch {
|
||||
typedef LIST3(AAAA, BBBB, CCCC) StateList;
|
||||
template <int> int event(Event & ev) { Serial.println("undefined event -- event"); return ev.state; }
|
||||
template <int> int event() { Serial.println("undefined enter"); return 0; }
|
||||
template <int> void enter() { Serial.println("undefined enter"); }
|
||||
template <int> void exit() { Serial.println("undefined leave"); };
|
||||
|
||||
template <int> void tick() { Serial.println("undefined enter");}
|
||||
};
|
||||
|
||||
template <> void QQQQSwitch::enter<AAAA>() { Serial.println("enter AAAA"); }
|
||||
template <> void QQQQSwitch::exit<AAAA>() { Serial.println("exit AAAA"); }
|
||||
template <> void QQQQSwitch::tick<AAAA>() { Serial.println("tick AAAA"); }
|
||||
|
||||
template <> void QQQQSwitch::enter<BBBB>() { Serial.println("enter BBBB"); }
|
||||
template <> void QQQQSwitch::exit<BBBB>() { Serial.println("exit BBBB"); }
|
||||
template <> void QQQQSwitch::tick<BBBB>() { Serial.println("tick BBBB"); }
|
||||
|
||||
template <> void QQQQSwitch::enter<CCCC>() { Serial.println("enter CCCC"); }
|
||||
template <> void QQQQSwitch::exit<CCCC>() { Serial.println("exit CCCC"); }
|
||||
template <> void QQQQSwitch::tick<CCCC>() { Serial.println("tick CCCC"); }
|
||||
|
||||
StateMachine<QQQQSwitch>* sm;
|
||||
|
||||
Event event_AAAA = {AAAA};
|
||||
Event event_BBBB = {BBBB};
|
||||
Event event_CCCC = {CCCC};
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
Serial.println("starts");
|
||||
|
||||
QQQQSwitch c;
|
||||
sm = new StateMachine<QQQQSwitch>(c);
|
||||
|
||||
}
|
||||
|
||||
void loop() {
|
||||
delay(2000);
|
||||
Serial.println("...");
|
||||
|
||||
|
||||
if (Serial.available() > 0) {
|
||||
char in = (char) Serial.read();
|
||||
|
||||
switch(in) {
|
||||
|
||||
case 'a':
|
||||
sm->work(event_AAAA);
|
||||
return;
|
||||
|
||||
case 'b':
|
||||
sm->work(event_BBBB);
|
||||
return;
|
||||
|
||||
case 'c':
|
||||
sm->work(event_CCCC);
|
||||
return;
|
||||
|
||||
default:
|
||||
Serial.println('??');
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
sm->tick();
|
||||
|
||||
}
|
||||
Executable
+88
@@ -0,0 +1,88 @@
|
||||
#include <Haarnet.h>
|
||||
|
||||
namespace bizarre {
|
||||
|
||||
int raw0 = 0;
|
||||
int ema0 = 0;
|
||||
ExpMovAvg exmoav(&bizarre::raw0, &bizarre::ema0);
|
||||
|
||||
SpringMassDamper spring0(10.0, 19.0, 7.0);
|
||||
SpringMassDamper spring1(10.0, 19.0, 7.0);
|
||||
|
||||
float r = 0;
|
||||
|
||||
}
|
||||
|
||||
using namespace bizarre;
|
||||
|
||||
machine_template void MachineStates::enter<AAAA>() {
|
||||
|
||||
Serial.println("enter AAAA");
|
||||
|
||||
FluteEx.init();
|
||||
|
||||
pinMode(A0, INPUT);
|
||||
|
||||
usbMIDI.setHandleNoteOff(OnNoteOff);
|
||||
usbMIDI.setHandleNoteOn(OnNoteOn);
|
||||
usbMIDI.setHandleControlChange(OnControlChange);
|
||||
|
||||
Music.getPreset(12);
|
||||
|
||||
Music.setGain1(0.5);
|
||||
Music.setGain2(0.5);
|
||||
Music.setGain3(0.5);
|
||||
|
||||
Music.setWaveform1(SQUARE);
|
||||
Music.setWaveform2(SINE);
|
||||
Music.setWaveform3(SQUARE);
|
||||
|
||||
// bizarre::raw0 = 0;
|
||||
// bizarre::ema0 = 0;
|
||||
|
||||
}
|
||||
|
||||
machine_template void MachineStates::exit<AAAA>() { Serial.println("exit AAAA"); }
|
||||
|
||||
machine_template void MachineStates::tick<AAAA>() {
|
||||
|
||||
int memory_junk[4];
|
||||
bizarre::raw0 = memory_junk[0] + memory_junk[1];// + memory_junk[2] + memory_junk[3];
|
||||
|
||||
bizarre::exmoav.calculate();
|
||||
|
||||
int pos0 = bizarre::spring0.position(bizarre::ema0);
|
||||
int pos1 = bizarre::spring1.position(pos0);
|
||||
|
||||
int t = analogRead(A1);
|
||||
t = map(t, 0, 1023, 2, 575);
|
||||
//t = map(t, 0, 1023, 2, 75); -- great
|
||||
delay(t);
|
||||
|
||||
r += 0.001;
|
||||
|
||||
int q = 20000;
|
||||
int minf = 50, maxf = 20000;
|
||||
|
||||
float f0 = map(bizarre::ema0, -q, q, minf, maxf); //or
|
||||
//float f0 = sin(r) * (float)(t*2);
|
||||
Music.setFrequency1(f0);
|
||||
|
||||
// Serial.println(f0);
|
||||
|
||||
float f1 = map(pos0, -q, q, minf, maxf);
|
||||
Music.setFrequency2(f1);
|
||||
|
||||
// Serial.println(f1);
|
||||
|
||||
float f2 = map(pos1, -q, q, minf, maxf);
|
||||
Music.setFrequency3(f2);
|
||||
|
||||
// Serial.println(f2);
|
||||
|
||||
usbMIDI.read();
|
||||
|
||||
}
|
||||
|
||||
machine_template int MachineStates::event<AAAA>() { return BBBB; }
|
||||
|
||||
Executable
+76
@@ -0,0 +1,76 @@
|
||||
|
||||
namespace eponge {
|
||||
|
||||
int raw0 = 0;
|
||||
int ema0 = 0;
|
||||
ExpMovAvg exmoav(&raw0, &ema0);
|
||||
|
||||
MinMaxLerp minmax(&ema0, 50, 800, 10000, 1000);
|
||||
|
||||
SpringMassDamper spring0(10.0, 19.0, 7.0);
|
||||
SpringMassDamper spring1(10.0, 19.0, 7.0);
|
||||
|
||||
}
|
||||
|
||||
using namespace eponge;
|
||||
|
||||
machine_template void MachineStates::enter<BBBB>() {
|
||||
|
||||
Serial.println("enter BBBB");
|
||||
|
||||
FluteEx.init();
|
||||
|
||||
usbMIDI.setHandleNoteOff(OnNoteOff);
|
||||
usbMIDI.setHandleNoteOn(OnNoteOn);
|
||||
usbMIDI.setHandleControlChange(OnControlChange);
|
||||
|
||||
Music.getPreset(15);
|
||||
|
||||
// Music.setGain1(1.0);
|
||||
// Music.setGain2(1.0);
|
||||
// Music.setGain3(1.0); // 1.0 for 3 oscs
|
||||
//
|
||||
// Music.setWaveform1(SINE);
|
||||
// Music.setWaveform2(SINE);
|
||||
// Music.setWaveform3(SINE);
|
||||
|
||||
// eponge::raw0 = 0;
|
||||
// eponge::ema0 = 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
machine_template void MachineStates::exit<BBBB>() { Serial.println("exit BBBB"); }
|
||||
|
||||
machine_template void MachineStates::tick<BBBB>() {
|
||||
|
||||
eponge::raw0 = analogRead(A1); // pot 0
|
||||
eponge::exmoav.calculate();
|
||||
eponge::minmax.lerp_min_max();
|
||||
|
||||
int pos0 = eponge::spring0.position(eponge::ema0);
|
||||
int pos1 = eponge::spring1.position(pos0);
|
||||
|
||||
int minf = FluteEx.luxA();
|
||||
//int minf = analogRead(A9); // pot2
|
||||
minf = map(minf, 0, 1023, 25, 75);
|
||||
|
||||
int maxf = FluteEx.luxB();
|
||||
// int maxf = analogRead(A2); // pot1
|
||||
maxf = map(maxf, 0, 1023, 75, 125);
|
||||
|
||||
int f0 = map(eponge::ema0, 0, 1023, minf, maxf);
|
||||
Music.setFrequency1(f0);
|
||||
|
||||
int f1 = map(pos0, 0, 1023, minf, maxf);
|
||||
Music.setFrequency2(f1);
|
||||
|
||||
int f2 = map(pos1, 0, 1023, minf, maxf);
|
||||
Music.setFrequency3(f2);
|
||||
|
||||
usbMIDI.read();
|
||||
|
||||
}
|
||||
|
||||
machine_template int MachineStates::event<BBBB>() { return AAAA; }
|
||||
|
||||
Executable
+89
@@ -0,0 +1,89 @@
|
||||
#define MIDI_CHANNEL 1
|
||||
|
||||
#include <EEPROM.h>
|
||||
#include <spi4teensy3.h>
|
||||
#include <Mcp4251.h>
|
||||
#include <Wire.h>
|
||||
#include <Adafruit_TCS34725.h>
|
||||
|
||||
#include <Haarnet.h>
|
||||
#include <HaarnetExtensionFlute.h>
|
||||
|
||||
#include <ExpMovAvg.h>
|
||||
#include <MinMaxLerp.h>
|
||||
#include <SpringMassDamper.h>
|
||||
|
||||
#define PRINTLN(x,y) Serial.print(x); Serial.println(y);
|
||||
|
||||
|
||||
/////////// include FSM lib
|
||||
#include <FSM.h>
|
||||
#include <MachineStates.h>
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
// STATE MACHINE DEF
|
||||
//------------------------------------------------------------
|
||||
|
||||
// list of states
|
||||
enum States { BBBB, AAAA };
|
||||
|
||||
class LaMachine : public MachineStates {
|
||||
public:
|
||||
typedef LIST2(BBBB, AAAA) StateList;
|
||||
};
|
||||
|
||||
StateMachine<LaMachine>* sm;
|
||||
LaMachine ms;
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
// TIMER DEF
|
||||
//------------------------------------------------------------
|
||||
|
||||
|
||||
#define one_sec 1000000 // IntervalTimer is in microseconds
|
||||
#define timeout 10 * one_sec * 60
|
||||
IntervalTimer timer;
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
// USUAL SUSPECTS
|
||||
//------------------------------------------------------------
|
||||
|
||||
void setup() {
|
||||
|
||||
Serial.begin(115200);
|
||||
Serial.println("starts");
|
||||
|
||||
Music.init();
|
||||
|
||||
sm = new StateMachine<LaMachine>(ms);
|
||||
|
||||
timer.begin(transition, timeout);
|
||||
randomSeed(analogRead(A4));
|
||||
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// delay(2000);
|
||||
// Serial.print("... - "); Serial.println(sm->state);
|
||||
sm->tick();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
// TRANSITIONS DEF
|
||||
//------------------------------------------------------------
|
||||
|
||||
void transition() {
|
||||
sm->work();
|
||||
}
|
||||
|
||||
void transition_random() {
|
||||
|
||||
int r = random(0, 2);
|
||||
while(r == sm->state)
|
||||
r = random(0, 2);
|
||||
|
||||
Event ev = {r};
|
||||
sm->work(ev); // transition
|
||||
|
||||
}
|
||||
|
||||
Executable
+98
@@ -0,0 +1,98 @@
|
||||
/////////// include FSM lib
|
||||
#include <FSM.h>
|
||||
#include <MachineStates.h>
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
// STATE MACHINE DEF
|
||||
//------------------------------------------------------------
|
||||
|
||||
// list of states
|
||||
enum States { AAAA, BBBB, CCCC };
|
||||
|
||||
// definition of the actual machine "LaMachine" inheriting from master (parent) statemachine (defined in lib)
|
||||
class LaMachine : public MachineStates {
|
||||
public:
|
||||
//** super important -- list states in the machine
|
||||
// ('LIST3' for 3 states, 'LIST4' for 4 states, ..., 'LIST8' for 8 states)
|
||||
typedef LIST3(AAAA, BBBB, CCCC) StateList;
|
||||
};
|
||||
|
||||
|
||||
// function definitions of state AAAA (first)
|
||||
machine_template void MachineStates::enter<AAAA>() { Serial.println("enter AAAA"); } // when entering the state for the fist time
|
||||
machine_template void MachineStates::exit<AAAA>() { Serial.println("exit AAAA"); } // when exiting the state for the fist time
|
||||
machine_template void MachineStates::tick<AAAA>() { Serial.println("tick AAAA"); } // called from the loop() below
|
||||
machine_template int MachineStates::event<AAAA>() { Serial.println("self transition AAAA"); return BBBB; } // where to transition to from here (see void transition() below)
|
||||
|
||||
// function definitions of state BBBB (second)
|
||||
machine_template void MachineStates::enter<BBBB>() { Serial.println("enter BBBB"); }
|
||||
machine_template void MachineStates::exit<BBBB>() { Serial.println("exit BBBB"); }
|
||||
machine_template void MachineStates::tick<BBBB>() { Serial.println("tick BBBB"); }
|
||||
machine_template int MachineStates::event<BBBB>() { Serial.println("self transition BBBB"); return CCCC; }
|
||||
|
||||
// function definitions of state CCCC (third)
|
||||
machine_template void MachineStates::enter<CCCC>() { Serial.println("enter CCCC"); }
|
||||
machine_template void MachineStates::exit<CCCC>() { Serial.println("exit CCCC"); }
|
||||
machine_template void MachineStates::tick<CCCC>() { Serial.println("tick CCCC"); }
|
||||
|
||||
|
||||
// declaration the master (parent) statemachine (its a pointer)
|
||||
StateMachine<LaMachine>* sm;
|
||||
|
||||
// declaration the actual statemachine
|
||||
LaMachine ms;
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
// EVENTS DEF
|
||||
//------------------------------------------------------------
|
||||
|
||||
|
||||
Event event_AAAA = {AAAA};
|
||||
Event event_BBBB = {BBBB};
|
||||
Event event_CCCC = {CCCC};
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
// USUAL SUSPECTS
|
||||
//------------------------------------------------------------
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
Serial.println("starts");
|
||||
sm = new StateMachine<LaMachine>(ms);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
delay(2000);
|
||||
Serial.print("... - "); Serial.println(sm->state);
|
||||
|
||||
|
||||
if (Serial.available() > 0) {
|
||||
char in = (char) Serial.read();
|
||||
|
||||
switch(in) {
|
||||
|
||||
case 'a':
|
||||
sm->work(event_AAAA); // transition to AAAA
|
||||
return;
|
||||
|
||||
case 'b':
|
||||
sm->work(event_BBBB); // transition to BBBB
|
||||
return;
|
||||
|
||||
case 'c':
|
||||
sm->work(event_CCCC); // transition to CCCC
|
||||
return;
|
||||
|
||||
case 'x':
|
||||
sm->work(); // transition to next state as specified in 'event' (see MachineStates::event<AAAA>() above)
|
||||
return;
|
||||
|
||||
default:
|
||||
Serial.println('??');
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
sm->tick(); /// <-------------------------------------------------- über important (see MachineStates::tick<AAAA>() above)
|
||||
}
|
||||
Executable
+99
@@ -0,0 +1,99 @@
|
||||
/////////// include FSM lib
|
||||
#include <FSM.h>
|
||||
#include <MachineStates.h>
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
// STATE MACHINE DEF
|
||||
//------------------------------------------------------------
|
||||
|
||||
// list of states
|
||||
enum States { AAAA, BBBB, CCCC };
|
||||
|
||||
// definition of the actual machine "LaMachine" inheriting from master (parent) statemachine (defined in lib)
|
||||
class LaMachine : public MachineStates {
|
||||
public:
|
||||
//** super important -- list states in the machine
|
||||
// ('LIST3' for 3 states, 'LIST4' for 4 states, ..., 'LIST8' for 8 states)
|
||||
typedef LIST3(AAAA, BBBB, CCCC) StateList;
|
||||
};
|
||||
|
||||
|
||||
// function definitions of state AAAA (first)
|
||||
machine_template void MachineStates::enter<AAAA>() { Serial.println("enter AAAA"); } // when entering the state for the fist time
|
||||
machine_template void MachineStates::exit<AAAA>() { Serial.println("exit AAAA"); } // when exiting the state for the fist time
|
||||
machine_template void MachineStates::tick<AAAA>() { Serial.println("tick AAAA"); } // called from the loop() below
|
||||
machine_template int MachineStates::event<AAAA>() { Serial.println("self transition AAAA"); return BBBB; } // where to transition to from here (see void transition() below)
|
||||
|
||||
// function definitions of state BBBB (second)
|
||||
machine_template void MachineStates::enter<BBBB>() { Serial.println("enter BBBB"); }
|
||||
machine_template void MachineStates::exit<BBBB>() { Serial.println("exit BBBB"); }
|
||||
machine_template void MachineStates::tick<BBBB>() { Serial.println("tick BBBB"); }
|
||||
machine_template int MachineStates::event<BBBB>() { Serial.println("self transition BBBB"); return CCCC; }
|
||||
|
||||
// function definitions of state CCCC (third)
|
||||
machine_template void MachineStates::enter<CCCC>() { Serial.println("enter CCCC"); }
|
||||
machine_template void MachineStates::exit<CCCC>() { Serial.println("exit CCCC"); }
|
||||
machine_template void MachineStates::tick<CCCC>() { Serial.println("tick CCCC"); }
|
||||
|
||||
|
||||
// declaration the master (parent) statemachine (its a pointer)
|
||||
StateMachine<LaMachine>* sm;
|
||||
|
||||
// declaration the actual statemachine
|
||||
LaMachine ms;
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
// TIMER DEF
|
||||
//------------------------------------------------------------
|
||||
|
||||
|
||||
#define one_sec 1000000 // IntervalTimer is in microseconds
|
||||
#define timeout 0.25 * one_sec * 60
|
||||
IntervalTimer timer;
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
// USUAL SUSPECTS
|
||||
//------------------------------------------------------------
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
Serial.println("starts");
|
||||
|
||||
//instantiation of the master statemachine with actual machine as param
|
||||
sm = new StateMachine<LaMachine>(ms);
|
||||
|
||||
// start the timer with callback (could be both void transition() or void transition_random() -- see below)
|
||||
timer.begin(transition_random, timeout);
|
||||
randomSeed(analogRead(A4));
|
||||
|
||||
}
|
||||
|
||||
void loop() {
|
||||
delay(2000);
|
||||
Serial.print("... - "); Serial.println(sm->state);
|
||||
sm->tick(); /// <-------------------------------------------------- über important (see MachineStates::tick<AAAA>() above)
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
// TRANSITIONS DEF
|
||||
//------------------------------------------------------------
|
||||
|
||||
// normal transition to next state as specified in 'event' (see MachineStates::event<AAAA>() above)
|
||||
void transition() {
|
||||
sm->work();
|
||||
}
|
||||
|
||||
// random transition depending on the number of states
|
||||
void transition_random() {
|
||||
|
||||
int r = random(0, 3); // we do indeed have three states (i.e, { AAAA, BBBB, CCCC };)
|
||||
|
||||
// force new state ? (don't need this is re-entry is ok)
|
||||
while(r == sm->state)
|
||||
r = random(0, 3);
|
||||
|
||||
Event ev = {r};
|
||||
sm->work(ev); // transition
|
||||
|
||||
}
|
||||
|
||||
Executable
+103
@@ -0,0 +1,103 @@
|
||||
#define MIDI_CHANNEL 1
|
||||
|
||||
#include <EEPROM.h>
|
||||
#include <spi4teensy3.h>
|
||||
#include <Mcp4251.h>
|
||||
#include <Wire.h>
|
||||
#include <Adafruit_TCS34725.h>
|
||||
|
||||
#include <Haarnet.h>
|
||||
#include <HaarnetExtensionFlute.h>
|
||||
|
||||
#include <ExpMovAvg.h>
|
||||
#include <MinMaxLerp.h>
|
||||
#include <SpringMassDamper.h>
|
||||
|
||||
#define PRINTLN(x,y) Serial.print(x); Serial.println(y);
|
||||
|
||||
int raw0 = 0;
|
||||
int ema0 = 0;
|
||||
ExpMovAvg exmoav(&raw0, &ema0);
|
||||
|
||||
//SpringMassDamper spring0(10.0, 19.0, 7.0);
|
||||
//SpringMassDamper spring1(10.0, 19.0, 7.0);
|
||||
|
||||
SpringMassDamper spring0(100.0, 9.0, 7.0);
|
||||
SpringMassDamper spring1(100.0, 9.0, 7.0);
|
||||
|
||||
const int ADC_AVG_RES = 4;
|
||||
const int min_ADC = 420;
|
||||
const int max_ADC = 850;
|
||||
const int min_delta_t = 0;
|
||||
const int max_delta_t = 25;
|
||||
|
||||
|
||||
void setup() {
|
||||
|
||||
//FluteEx.init();
|
||||
|
||||
pinMode(A1, INPUT);
|
||||
pinMode(A9, INPUT);
|
||||
pinMode(A2, INPUT);
|
||||
|
||||
analogReadAveraging(ADC_AVG_RES);
|
||||
|
||||
Music.init();
|
||||
|
||||
usbMIDI.setHandleNoteOff(OnNoteOff);
|
||||
usbMIDI.setHandleNoteOn(OnNoteOn);
|
||||
usbMIDI.setHandleControlChange(OnControlChange);
|
||||
|
||||
Music.getPreset(16);
|
||||
|
||||
Music.setGain1(1.0);
|
||||
Music.setGain2(1.0);
|
||||
Music.setGain3(1.0);
|
||||
|
||||
Music.setWaveform1(TRIANGLE);
|
||||
Music.setWaveform2(SQUARE);
|
||||
Music.setWaveform3(SINE);
|
||||
|
||||
Serial.begin(115200);
|
||||
|
||||
}
|
||||
|
||||
float r = 0;
|
||||
|
||||
void loop() {
|
||||
|
||||
int memory_junk[4];
|
||||
raw0 = memory_junk[0] + memory_junk[1] + memory_junk[2] + memory_junk[3];
|
||||
|
||||
exmoav.calculate();
|
||||
|
||||
int pos0 = spring0.position(ema0);
|
||||
int pos1 = spring1.position(pos0);
|
||||
|
||||
int t = analogRead(A1);
|
||||
if (t < min_ADC || t > max_ADC) return;
|
||||
t = map(t, min_ADC, max_ADC, min_delta_t, max_delta_t);
|
||||
delay(t);
|
||||
|
||||
Serial.println(t);
|
||||
|
||||
r += 0.001;
|
||||
|
||||
int q = 10000;
|
||||
int minf = 50, maxf = 20000;
|
||||
|
||||
// int f0 = map(ema0, -q, q, minf, maxf); //or
|
||||
float f0 = sin(r) * (float)(2*t);
|
||||
Music.setFrequency1(f0);
|
||||
|
||||
int f1 = map(pos0, -q, q, minf, maxf);
|
||||
Music.setFrequency2(f1);
|
||||
|
||||
int f2 = map(pos1, -q, q, minf, maxf);
|
||||
Music.setFrequency3(f2);
|
||||
|
||||
usbMIDI.read();
|
||||
|
||||
|
||||
}
|
||||
|
||||
Executable
+98
@@ -0,0 +1,98 @@
|
||||
#define MIDI_CHANNEL 1
|
||||
|
||||
#include <EEPROM.h>
|
||||
#include <spi4teensy3.h>
|
||||
#include <Mcp4251.h>
|
||||
#include <Wire.h>
|
||||
#include <Adafruit_TCS34725.h>
|
||||
|
||||
#include <Haarnet.h>
|
||||
#include <HaarnetExtensionFlute.h>
|
||||
|
||||
#include <ExpMovAvg.h>
|
||||
#include <MinMaxLerp.h>
|
||||
#include <SpringMassDamper.h>
|
||||
|
||||
#define PRINTLN(x,y) Serial.print(x); Serial.println(y);
|
||||
|
||||
int raw0 = 0;
|
||||
int ema0 = 0;
|
||||
ExpMovAvg exmoav(&raw0, &ema0);
|
||||
|
||||
SpringMassDamper spring0(1.0, 19.0, 7.0);
|
||||
SpringMassDamper spring1(10.0, 19.0, 7.0);
|
||||
|
||||
|
||||
void setup() {
|
||||
|
||||
FluteEx.init();
|
||||
|
||||
pinMode(A0, INPUT);
|
||||
pinMode(A9, INPUT);
|
||||
pinMode(A2, INPUT);
|
||||
|
||||
Music.init();
|
||||
|
||||
usbMIDI.setHandleNoteOff(OnNoteOff);
|
||||
usbMIDI.setHandleNoteOn(OnNoteOn);
|
||||
usbMIDI.setHandleControlChange(OnControlChange);
|
||||
|
||||
Music.getPreset(12);
|
||||
|
||||
Music.setGain1(1.0);
|
||||
Music.setGain2(1.0);
|
||||
Music.setGain3(1.0);
|
||||
|
||||
Music.setWaveform1(SQUARE);
|
||||
Music.setWaveform2(SQUARE);
|
||||
Music.setWaveform3(SQUARE);
|
||||
|
||||
Serial.begin(115200);
|
||||
|
||||
}
|
||||
|
||||
float r = 0;
|
||||
|
||||
void loop() {
|
||||
|
||||
|
||||
int memory_junk[4];
|
||||
raw0 = memory_junk[0] + memory_junk[1];// + memory_junk[2] + memory_junk[3];
|
||||
|
||||
exmoav.calculate();
|
||||
|
||||
int pos0 = spring0.position(ema0);
|
||||
int pos1 = spring1.position(pos0);
|
||||
|
||||
int t = analogRead(A0);
|
||||
t = map(t, 0, 1023, 2, 167);
|
||||
//t = map(t, 0, 1023, 2, 75); -- great
|
||||
delay(t);
|
||||
|
||||
r += 0.001;
|
||||
|
||||
int q = 20000;
|
||||
int minf = 50, maxf = 20000;
|
||||
|
||||
int f0 = map(ema0, -q, q, minf, maxf); //or
|
||||
//float f0 = sin(r) * (float)(t*2);
|
||||
Music.setFrequency1(f0);
|
||||
|
||||
// Serial.println(f0);
|
||||
|
||||
int f1 = map(pos0, -q, q, minf, maxf);
|
||||
Music.setFrequency2(f1);
|
||||
|
||||
// Serial.println(f1);
|
||||
|
||||
int f2 = map(pos1, -q, q, minf, maxf);
|
||||
Music.setFrequency3(f2);
|
||||
|
||||
Serial.println(f2);
|
||||
|
||||
usbMIDI.read();
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
Executable
+85
@@ -0,0 +1,85 @@
|
||||
#define MIDI_CHANNEL 1
|
||||
|
||||
#include <EEPROM.h>
|
||||
#include <spi4teensy3.h>
|
||||
#include <Mcp4251.h>
|
||||
#include <Wire.h>
|
||||
#include <Adafruit_TCS34725.h>
|
||||
|
||||
#include <Haarnet.h>
|
||||
#include <HaarnetExtensionFlute.h>
|
||||
|
||||
#include <ExpMovAvg.h>
|
||||
#include <MinMaxLerp.h>
|
||||
#include <SpringMassDamper.h>
|
||||
|
||||
|
||||
int raw0 = 0;
|
||||
int ema0 = 0;
|
||||
ExpMovAvg exmoav(&raw0, &ema0);
|
||||
|
||||
SpringMassDamper spring0(10.0, 19.0, 7.0);
|
||||
SpringMassDamper spring1(10.0, 19.0, 7.0);
|
||||
|
||||
float r = 0;
|
||||
|
||||
|
||||
void setup() {
|
||||
|
||||
Serial.begin(115200);
|
||||
Serial.println("starts");
|
||||
|
||||
Music.init();
|
||||
|
||||
FluteEx.init();
|
||||
|
||||
pinMode(A0, INPUT);
|
||||
|
||||
usbMIDI.setHandleNoteOff(OnNoteOff);
|
||||
usbMIDI.setHandleNoteOn(OnNoteOn);
|
||||
usbMIDI.setHandleControlChange(OnControlChange);
|
||||
|
||||
Music.getPreset(4);
|
||||
|
||||
}
|
||||
|
||||
void loop() {
|
||||
|
||||
int memory_junk[4];
|
||||
raw0 = memory_junk[0] + memory_junk[1];// + memory_junk[2] + memory_junk[3];
|
||||
|
||||
exmoav.calculate();
|
||||
|
||||
int pos0 = spring0.position(ema0);
|
||||
int pos1 = spring1.position(pos0);
|
||||
|
||||
int t = analogRead(A1);
|
||||
t = map(t, 0, 1023, 2, 200);
|
||||
//t = map(t, 0, 1023, 2, 75); -- great
|
||||
delay(t);
|
||||
|
||||
r += 0.001;
|
||||
|
||||
int q = 20000;
|
||||
int minf = 50, maxf = 20000;
|
||||
|
||||
float f0 = map(ema0, -q, q, minf, maxf); //or
|
||||
//float f0 = sin(r) * (float)(t*2);
|
||||
Music.setFrequency1(f0);
|
||||
|
||||
// Serial.println(f0);
|
||||
|
||||
float f1 = map(pos0, -q, q, minf, maxf);
|
||||
Music.setFrequency2(f1);
|
||||
|
||||
// Serial.println(f1);
|
||||
|
||||
float f2 = map(pos1, -q, q, minf, maxf);
|
||||
Music.setFrequency3(f2);
|
||||
|
||||
// Serial.println(f2);
|
||||
|
||||
usbMIDI.read();
|
||||
|
||||
|
||||
}
|
||||
Executable
+4677
File diff suppressed because it is too large
Load Diff
Executable
+210
@@ -0,0 +1,210 @@
|
||||
|
||||
/*
|
||||
777$7II7III??+,.......:+~=7$$Z$?$OOZOZ77?$$I+??I$ZOD8DD8DD888O$7$77$Z$$$ZZZZZOOO
|
||||
$$$777$$77II??~.,..,.=?777$ZZ==$OZZ$I?=+?Z+==~=7Z7Z$OO8888DDDD8ZOZ$$$7Z$ZOZ$ZZOO
|
||||
$$$7ZZ$Z$$77II=~:.,.:??+IZZZ+?O$ZI+?+:~+7I~~,:~?Z$88O88D88DDDDD8OZOZ$$$ZZZZZOOZZ
|
||||
$$$$ZZ$$$$777I??:::,:7ZZ8OZ$$$7?=::,:~??~:,.....7$8$IZDDD8DDDNDDOZZO$$ZZZZZOZOOO
|
||||
$$$77$7$7III$II+==+$$$OOO8OZ?=:......~. ........,?ZOI$88DOD8DDN8D888$7$ZZ$$Z$$ZO
|
||||
$$7$$$77I77$ZZ$7,:Z$OZOOOOOI. ...,~:.....:~~+:===$Z$7OOD8DDD88O8D888O$7$Z$$$$OZ
|
||||
$$77$$77I$$ZOZI,.7Z88O88O8?. .,:~~::,,.,,,+?$ZZZZZ8OZZ$8$8NDDDD88ODO8ZZ$$$OZZZOO
|
||||
Z$Z$$$77$Z$$O$~.~?$ZOOOOOZ, ,?7$7II+:..,~+$III777I77I$O8OD8DD8D8DO8D88$77$$$ZZZZ
|
||||
OOOOZc$ZOZOZZ?..+??IZO8NO$I?===+=~~~,...,~II???+~:+~:+ZO8D88DOODDDDD8D88OZ77$ZZZ
|
||||
ZOZOOZZZZZOZ$II.~?I$ZZO8ZO~. ..~?+~~.. .,?$I$ZO888O?~$Z88D888O8888DONDD88Z7777$
|
||||
OZZ8O8OZZOZZZZ7I7I$ZZ7$OZ7:.=7ZDO7?~.. ,::+O7$O8O78O7IOD88N8D8DD88DD8OOOO7$$7Z
|
||||
OOOZ88888OOOOZZI~?I$Z$OZI+?77,?$I?:.. .,:,,~,,~+++~+I$ZZ8DDD8DNDD8DDOOOZ7?$$7$
|
||||
OOOZO88OO8OZ7=:,.?7IZZOZI,~=~. ... . ..,,.. ...=:..~I$Z8DDDD8D8DDOD88a7II777$
|
||||
$OOOOOOO8O+.,.:++:++$ZOO7 .,. .,,,.... ..:~.:$Z8DD8DDD88DDD8O$?????I7
|
||||
OO8O8O8OZ$.,:?=..::?IZZ8Z .. ..,.,=,.. ..:I??7O8DD88D888D8OOI?II77II
|
||||
OOOO8OZZ7=,~7?~,,,~~?$7OZ,. .,:~=:,.,:, ..:=+:~788DDD88Z888OZ$+I?III$7
|
||||
ZOZZO$$$ZZZZ$I:~:~,,7=77$~:.. .:$$==IOO7=,.,....,:,:=+$D8DD8888D887II?7777$$
|
||||
ZOOZZZ$$ZZZZ7+::=:::::II~.:.. ..=+?+IIII:...,,..,,,:==$DDD88888DD8$ZZ$$ZOOOO
|
||||
7ZO$n7I$$$Z$7I~,,:,,.,=?:,,.. . ,:::~~I?:,......,,:,:=ZO888D88D8DO88O8888888
|
||||
77777$77$$7I?~,.. .,,,=+~.. ~+=:~+:+II+=~:,:..,,::~?ZODO888D88DD8DDDD8D88N
|
||||
?77???I?II?~:,.....=.:?+~. ., .:?7I:::~::=+~~...,:~=?$OOOZ888OO8OO8888D8D8D
|
||||
7II??I+++~:,.. .,==$7+,. .IZ7~~~~,~:++=:..::~++7ZZODDD8D888a8OOD88D88
|
||||
I???+~:,,,... .=:=~I$$+, .$7?+++++=+==+~,,:==+?78DDDDDDDO88OZOO88O888
|
||||
??+::,,... ... .78Z7IZO=...... ,77:..:::.,~?+~::=++~?$8DDDN8D8O88O88OOOOO88
|
||||
~=~:,,,.,.... .:OO$Z$7... ?$~ .......,:=~,:++==?$88D88D8ZOZOOZOOOO8DOO
|
||||
:~=+:,,.. . ..,?$$+.. =...::,... ,~::~?===+OD88888OZOOOZO$ZOOZZZ8
|
||||
,~++++==.. ....~ZZO~. .:~=~,,...:=~~$7?+?$DD8D8OOZZOZOZOOOO8O8O8
|
||||
.:=+==++,. ...,.:+8DZ...I$7:.....,~=:,....+~?I7=?=$O8DDOOZ88OOO8OOOOOZZO88
|
||||
,:~===?d, .:,:?OD8O...ZOO$$?I,...=~:,,,,~===?+?+77Z8OZ$Z$OOZZOOO8OOOOO8O8
|
||||
,:~=~~=+.. ..=Z8888$.+OZ8OOZ8O7,.::=:~~=~:+????I$$?7$$ZZZOOOOOOOOO8O8OOOOO
|
||||
,,:~~~+=.. ~ZO87I7Z,:7OOZOO?OD$~,:~:+?+==+?+=+77$?IOOZZZOOOOO8OOOOOOOOO888
|
||||
..,,~=+~.. . =$OO:..+?.IZOOZOZ$OZ?=~=~=++=+:?III7$7I=7DD8ZZOO8OO88OO8ZOZ$ZOOO
|
||||
..... .... . ,~?7OZ7..:~I+ZZOO$OOOZZ$+7++?+??I777$$Z7I?~Z8D8OO$Z888O8888ZOZOZOO8
|
||||
,.....,~~==:=?$ZOZ7 .,~7IZZOZZZZOOOZO$I$Z$$Z$Z$ZZ7$I+==~DDDN8DDO$O88D8DDZO8OZ888
|
||||
=+=:~::=~~:+$ZZZ$+...I77$OZ$$IIZ$?$Z7=======~=++??==,::=D8D88D8D8ZOODOOOZZ8ZOaOO
|
||||
*/
|
||||
|
||||
/*
|
||||
modified version of:
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (c) 2007 Gerhard Reitmayr <gerhard.reitmayr@gmail.com>
|
||||
Permission to use, copy, modify, and distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _FSM_H
|
||||
#define _FSM_H
|
||||
|
||||
/// list of ints as recursive type
|
||||
template <int HEAD, class TAIL> struct IntList {
|
||||
enum { head = HEAD };
|
||||
typedef TAIL tail;
|
||||
};
|
||||
|
||||
/// end of list marker type
|
||||
struct IntListEnd {};
|
||||
|
||||
/// switch statement implementation through iterating over the type list and
|
||||
/// comparing it to a given state
|
||||
template <class STATELIST>
|
||||
struct SwitchTemplate {
|
||||
template <class CONTEXT>
|
||||
static typename CONTEXT::ReturnType work( int state, CONTEXT & context){
|
||||
return ((STATELIST::head == state) ?
|
||||
context.template operator()<STATELIST::head>() :
|
||||
SwitchTemplate<typename STATELIST::tail>::work( state, context ));
|
||||
}
|
||||
};
|
||||
|
||||
/// end of list marker specialization
|
||||
template <>
|
||||
struct SwitchTemplate<IntListEnd> {
|
||||
template <class CONTEXT>
|
||||
static typename CONTEXT::ReturnType work( int state, CONTEXT & context){
|
||||
return typename CONTEXT::ReturnType();
|
||||
}
|
||||
};
|
||||
|
||||
/// The actual state machine implementation
|
||||
/// sub types are functors passed to the Worker class to execute the
|
||||
/// right template specialization of the underlying member function of the
|
||||
/// context object.
|
||||
template <class CONTEXT, class STATELIST = typename CONTEXT::StateList>
|
||||
struct StateMachine {
|
||||
|
||||
CONTEXT & context;
|
||||
int state;
|
||||
|
||||
template <class RET, class DATA> struct CallEvent {
|
||||
typedef RET ReturnType;
|
||||
CONTEXT & context;
|
||||
DATA & data;
|
||||
|
||||
template <int STATE> RET operator()(){
|
||||
return context.template event<STATE>(data);
|
||||
}
|
||||
};
|
||||
|
||||
template <class RET, class DATA> struct CallEventConst {
|
||||
typedef RET ReturnType;
|
||||
CONTEXT & context;
|
||||
const DATA & data;
|
||||
|
||||
template <int STATE> RET operator()(){
|
||||
return context.template event<STATE>(data);
|
||||
}
|
||||
};
|
||||
|
||||
template <class RET> struct CallEventNoData {
|
||||
typedef RET ReturnType;
|
||||
CONTEXT & context;
|
||||
|
||||
template <int STATE> RET operator()(){
|
||||
return context.template event<STATE>();
|
||||
}
|
||||
};
|
||||
|
||||
struct CallEnter {
|
||||
typedef void ReturnType;
|
||||
CONTEXT & context;
|
||||
|
||||
template <int STATE> ReturnType operator()(){
|
||||
return context.template enter<STATE>();
|
||||
}
|
||||
};
|
||||
|
||||
struct CallExit {
|
||||
typedef void ReturnType;
|
||||
CONTEXT & context;
|
||||
|
||||
template <int STATE> ReturnType operator()(){
|
||||
return context.template exit<STATE>();
|
||||
}
|
||||
};
|
||||
|
||||
struct CallTick {
|
||||
typedef void ReturnType;
|
||||
CONTEXT & context;
|
||||
|
||||
template <int STATE> ReturnType operator()(){
|
||||
return context.template tick<STATE>();
|
||||
}
|
||||
};
|
||||
|
||||
StateMachine( CONTEXT & c ) : context(c), state(STATELIST::head) {
|
||||
CallEnter cee = {context};
|
||||
SwitchTemplate<STATELIST>::work(state, cee);
|
||||
}
|
||||
|
||||
void changeState(const int newstate){
|
||||
CallExit cl = {context};
|
||||
SwitchTemplate<STATELIST>::work(state, cl);
|
||||
state = newstate;
|
||||
CallEnter cee = {context};
|
||||
SwitchTemplate<STATELIST>::work(state, cee);
|
||||
}
|
||||
|
||||
void tick() {
|
||||
CallTick ct = {context};
|
||||
SwitchTemplate<STATELIST>::work(state, ct);
|
||||
}
|
||||
|
||||
void work(){
|
||||
CallEventNoData<int> ce = {context};
|
||||
int newstate = SwitchTemplate<STATELIST>::work(state, ce);
|
||||
if(newstate != state)
|
||||
changeState(newstate);
|
||||
}
|
||||
|
||||
template <class EVENT>
|
||||
void work( const EVENT & ev ){
|
||||
CallEventConst<int, EVENT> ce = {context, ev};
|
||||
int newstate = SwitchTemplate<STATELIST>::work(state, ce);
|
||||
if(newstate != state)
|
||||
changeState(newstate);
|
||||
}
|
||||
|
||||
template <class EVENT>
|
||||
void work( EVENT & ev ){
|
||||
CallEvent<int, EVENT> ce = {context, ev};
|
||||
int newstate = SwitchTemplate<STATELIST>::work(state, ce);
|
||||
if(newstate != state)
|
||||
changeState(newstate);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/// macros for simple state list definition
|
||||
#define LIST1(a) IntList<a,IntListEnd>
|
||||
#define LIST2(a,b) IntList<a,LIST1(b) >
|
||||
#define LIST3(a,b,c) IntList<a,LIST2(b,c) >
|
||||
#define LIST4(a,b,c,d) IntList<a,LIST3(b,c,d) >
|
||||
#define LIST5(a,b,c,d,e) IntList<a,LIST4(b,c,d,e) >
|
||||
#define LIST6(a,b,c,d,e,f) IntList<a,LIST5(b,c,d,e,f) >
|
||||
#define LIST7(a,b,c,d,e,f,g) IntList<a,LIST6(b,c,d,e,f,g) >
|
||||
#define LIST8(a,b,c,d,e,f,g,h) IntList<a,LIST7(b,c,d,e,f,g,h) >
|
||||
|
||||
#endif // _FSM_H
|
||||
Executable
+59
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
777$7II7III??+,.......:+~=7$$Z$?$OOZOZ77?$$I+??I$ZOD8DD8DD888O$7$77$Z$$$ZZZZZOOO
|
||||
$$$777$$77II??~.,..,.=?777$ZZ==$OZZ$I?=+?Z+==~=7Z7Z$OO8888DDDD8ZOZ$$$7Z$ZOZ$ZZOO
|
||||
$$$7ZZ$Z$$77II=~:.,.:??+IZZZ+?O$ZI+?+:~+7I~~,:~?Z$88O88D88DDDDD8OZOZ$$$ZZZZZOOZZ
|
||||
$$$$ZZ$$$$777I??:::,:7ZZ8OZ$$$7?=::,:~??~:,.....7$8$IZDDD8DDDNDDOZZO$$ZZZZZOZOOO
|
||||
$$$77$7$7III$II+==+$$$OOO8OZ?=:......~. ........,?ZOI$88DOD8DDN8D888$7$ZZ$$Z$$ZO
|
||||
$$7$$$77I77$ZZ$7,:Z$OZOOOOOI. ...,~:.....:~~+:===$Z$7OOD8DDD88O8D888O$7$Z$$$$OZ
|
||||
$$77$$77I$$ZOZI,.7Z88O88O8?. .,:~~::,,.,,,+?$ZZZZZ8OZZ$8$8NDDDD88ODO8ZZ$$$OZZZOO
|
||||
Z$Z$$$77$Z$$O$~.~?$ZOOOOOZ, ,?7$7II+:..,~+$III777I77I$O8OD8DD8D8DO8D88$77$$$ZZZZ
|
||||
OOOOZc$ZOZOZZ?..+??IZO8NO$I?===+=~~~,...,~II???+~:+~:+ZO8D88DOODDDDD8D88OZ77$ZZZ
|
||||
ZOZOOZZZZZOZ$II.~?I$ZZO8ZO~. ..~?+~~.. .,?$I$ZO888O?~$Z88D888O8888DONDD88Z7777$
|
||||
OZZ8O8OZZOZZZZ7I7I$ZZ7$OZ7:.=7ZDO7?~.. ,::+O7$O8O78O7IOD88N8D8DD88DD8OOOO7$$7Z
|
||||
OOOZ88888OOOOZZI~?I$Z$OZI+?77,?$I?:.. .,:,,~,,~+++~+I$ZZ8DDD8DNDD8DDOOOZ7?$$7$
|
||||
OOOZO88OO8OZ7=:,.?7IZZOZI,~=~. ... . ..,,.. ...=:..~I$Z8DDDD8D8DDOD88a7II777$
|
||||
$OOOOOOO8O+.,.:++:++$ZOO7 .,. .,,,.... ..:~.:$Z8DD8DDD88DDD8O$?????I7
|
||||
OO8O8O8OZ$.,:?=..::?IZZ8Z .. ..,.,=,.. ..:I??7O8DD88D888D8OOI?II77II
|
||||
OOOO8OZZ7=,~7?~,,,~~?$7OZ,. .,:~=:,.,:, ..:=+:~788DDD88Z888OZ$+I?III$7
|
||||
ZOZZO$$$ZZZZ$I:~:~,,7=77$~:.. .:$$==IOO7=,.,....,:,:=+$D8DD8888D887II?7777$$
|
||||
ZOOZZZ$$ZZZZ7+::=:::::II~.:.. ..=+?+IIII:...,,..,,,:==$DDD88888DD8$ZZ$$ZOOOO
|
||||
7ZO$n7I$$$Z$7I~,,:,,.,=?:,,.. . ,:::~~I?:,......,,:,:=ZO888D88D8DO88O8888888
|
||||
77777$77$$7I?~,.. .,,,=+~.. ~+=:~+:+II+=~:,:..,,::~?ZODO888D88DD8DDDD8D88N
|
||||
?77???I?II?~:,.....=.:?+~. ., .:?7I:::~::=+~~...,:~=?$OOOZ888OO8OO8888D8D8D
|
||||
7II??I+++~:,.. .,==$7+,. .IZ7~~~~,~:++=:..::~++7ZZODDD8D888a8OOD88D88
|
||||
I???+~:,,,... .=:=~I$$+, .$7?+++++=+==+~,,:==+?78DDDDDDDO88OZOO88O888
|
||||
??+::,,... ... .78Z7IZO=...... ,77:..:::.,~?+~::=++~?$8DDDN8D8O88O88OOOOO88
|
||||
~=~:,,,.,.... .:OO$Z$7... ?$~ .......,:=~,:++==?$88D88D8ZOZOOZOOOO8DOO
|
||||
:~=+:,,.. . ..,?$$+.. =...::,... ,~::~?===+OD88888OZOOOZO$ZOOZZZ8
|
||||
,~++++==.. ....~ZZO~. .:~=~,,...:=~~$7?+?$DD8D8OOZZOZOZOOOO8O8O8
|
||||
.:=+==++,. ...,.:+8DZ...I$7:.....,~=:,....+~?I7=?=$O8DDOOZ88OOO8OOOOOZZO88
|
||||
,:~===?d, .:,:?OD8O...ZOO$$?I,...=~:,,,,~===?+?+77Z8OZ$Z$OOZZOOO8OOOOO8O8
|
||||
,:~=~~=+.. ..=Z8888$.+OZ8OOZ8O7,.::=:~~=~:+????I$$?7$$ZZZOOOOOOOOO8O8OOOOO
|
||||
,,:~~~+=.. ~ZO87I7Z,:7OOZOO?OD$~,:~:+?+==+?+=+77$?IOOZZZOOOOO8OOOOOOOOO888
|
||||
..,,~=+~.. . =$OO:..+?.IZOOZOZ$OZ?=~=~=++=+:?III7$7I=7DD8ZZOO8OO88OO8ZOZ$ZOOO
|
||||
..... .... . ,~?7OZ7..:~I+ZZOO$OOOZZ$+7++?+??I777$$Z7I?~Z8D8OO$Z888O8888ZOZOZOO8
|
||||
,.....,~~==:=?$ZOZ7 .,~7IZZOZZZZOOOZO$I$Z$$Z$Z$ZZ7$I+==~DDDN8DDO$O88D8DDZO8OZ888
|
||||
=+=:~::=~~:+$ZZZ$+...I77$OZ$$IIZ$?$Z7=======~=++??==,::=D8D88D8D8ZOODOOOZZ8ZOaOO
|
||||
*/
|
||||
|
||||
#ifndef _MS_H
|
||||
#define _MS_H
|
||||
|
||||
#include "FSM.h"
|
||||
|
||||
#define machine_template template <>
|
||||
|
||||
struct Event { int state; };
|
||||
|
||||
class MachineStates {
|
||||
public:
|
||||
// typedef LIST3(AAAA, BBBB, CCCC) StateList;
|
||||
template <int> int event(Event & ev) { Serial.println("undefined event -- event"); return ev.state; }
|
||||
template <int> int event() { Serial.println("undefined event"); return 0; }
|
||||
template <int> void enter() { Serial.println("undefined enter"); }
|
||||
template <int> void exit() { Serial.println("undefined leave"); };
|
||||
template <int> void tick() { Serial.println("undefined tick");}
|
||||
};
|
||||
|
||||
|
||||
#endif // _MS_H
|
||||
Executable
+16
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
class ExpMovAvg {
|
||||
public:
|
||||
ExpMovAvg(int* in_i, int* out_o, float lambda = 0.5) : _in_ptr(in_i), _out_ptr(out_o), _lambda(lambda) {;}
|
||||
|
||||
inline void calculate() {
|
||||
_ema = _lambda * (float)(*_in_ptr) + (1 - _lambda) * _ema;
|
||||
*_out_ptr = _ema;
|
||||
}
|
||||
|
||||
int *_in_ptr, *_out_ptr;
|
||||
int _ema;
|
||||
float _lambda;
|
||||
|
||||
};
|
||||
Executable
+55
@@ -0,0 +1,55 @@
|
||||
#include "MinMaxLerp.h"
|
||||
|
||||
#include "Arduino.h"
|
||||
|
||||
MinMaxLerp::MinMaxLerp(int* in_i, int base_min, int base_max, long update_interval_ms, int nbr_steps) :
|
||||
_in_ptr(in_i), _base_min(base_min), _base_max(base_max), _cur_min(base_min), _cur_max(base_max),
|
||||
_tick_min(0), _tick_max(0), _update_interval(update_interval_ms)
|
||||
{
|
||||
_tick_time = (float)update_interval_ms / (float) nbr_steps;
|
||||
}
|
||||
|
||||
void MinMaxLerp::lerp_min_max() {
|
||||
|
||||
static float m_min = 1;
|
||||
static float m_max = 1;
|
||||
static int t_min = 0;
|
||||
static int t_max = 0;
|
||||
|
||||
int _ema = *_in_ptr;
|
||||
|
||||
if(_ema < _cur_min) {
|
||||
_cur_min = _ema;
|
||||
_min = _ema;
|
||||
_tick_min = millis();
|
||||
t_min = millis();
|
||||
|
||||
// calculate new slope
|
||||
int dy = _base_min - _min;
|
||||
m_min = (float) dy / (float)_update_interval; // linear
|
||||
} else {
|
||||
long t = millis() - _tick_min;
|
||||
if(t < _update_interval && (t_min - millis()) > _tick_time) {
|
||||
t_min = millis();
|
||||
_cur_min = _min + m_min * t;
|
||||
}
|
||||
}
|
||||
|
||||
if(_ema > _cur_max) {
|
||||
_cur_max = _ema;
|
||||
_max = _ema;
|
||||
_tick_max = millis();
|
||||
t_max = millis();
|
||||
|
||||
// calculate new slope
|
||||
int dy = _base_max - _max;
|
||||
m_max = (float) dy / (float)_update_interval; // linear
|
||||
} else {
|
||||
long t = millis() - _tick_max;
|
||||
if(t < _update_interval && (t_max - millis()) > _tick_time) {
|
||||
t_max = millis();
|
||||
_cur_max = _max + m_max * t;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Executable
+26
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
class MinMaxLerp {
|
||||
public:
|
||||
MinMaxLerp(int* in_i, int base_min, int base_max, long update_interval_ms = 1000, int nbr_steps = 100);
|
||||
|
||||
void lerp_min_max();
|
||||
|
||||
inline int lmin() { return _cur_min; }
|
||||
inline int lmax() { return _cur_max; }
|
||||
|
||||
protected:
|
||||
|
||||
int _base_min;
|
||||
int _base_max;
|
||||
int _min;
|
||||
int _max;
|
||||
int _cur_min;
|
||||
int _cur_max;
|
||||
|
||||
long _tick_min, _tick_max, _tick_time;
|
||||
long _update_interval;
|
||||
|
||||
int* _in_ptr;
|
||||
|
||||
};
|
||||
Executable
+23
@@ -0,0 +1,23 @@
|
||||
#include "SpringMassDamper.h"
|
||||
|
||||
#include "Arduino.h"
|
||||
|
||||
SpringMassDamper::SpringMassDamper(float m, float k, float d, float* out) :
|
||||
_m(m), _k(k), _d(d), _out(out) {}
|
||||
|
||||
float SpringMassDamper::position(int x) {
|
||||
|
||||
float dt = (millis() - _tick) / 1000.0f;
|
||||
|
||||
F = _k * (x - X) - (_d * V);
|
||||
V += (F / _m) * dt;
|
||||
X += V * dt;
|
||||
|
||||
_tick = millis();
|
||||
|
||||
if(_out != NULL)
|
||||
*_out = X;
|
||||
|
||||
return X;
|
||||
|
||||
}
|
||||
Executable
+16
@@ -0,0 +1,16 @@
|
||||
#include "Arduino.h"
|
||||
|
||||
#pragma once
|
||||
|
||||
class SpringMassDamper {
|
||||
public:
|
||||
SpringMassDamper(float m, float k, float d, float* out = NULL);
|
||||
|
||||
float position(int x);
|
||||
|
||||
float X, V, F;
|
||||
float _m, _k, _d;
|
||||
long _tick;
|
||||
float* _out;
|
||||
|
||||
};
|
||||
Executable
+14
@@ -0,0 +1,14 @@
|
||||
const int pin_lux_0 = A1;
|
||||
const int ADC_AVG_RES = 4;
|
||||
|
||||
void setup() {
|
||||
analogReadAveraging(ADC_AVG_RES);
|
||||
Serial.begin(115200);
|
||||
pinMode(pin_lux_0, INPUT);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
int l = analogRead(pin_lux_0);
|
||||
Serial.println(l);
|
||||
delay(50);
|
||||
}
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
#define MIDI_CHANNEL 1
|
||||
|
||||
#include <SpringMassDamper.h>
|
||||
#include <ExpMovAvg.h>
|
||||
#include <MinMaxLerp.h>
|
||||
|
||||
#include <Haarnet.h>
|
||||
#include <HaarnetExtensionFlute.h>
|
||||
|
||||
float x = 300, y, z = 0;
|
||||
SpringMassDamper springX(50.0, 275.0, 1, &x);
|
||||
SpringMassDamper springY(50.0, 275.0, 1, &y);
|
||||
SpringMassDamper springZ(10.0, 275.0, 10, &z);
|
||||
|
||||
const int basefreq = 75;
|
||||
|
||||
long tick = 0;
|
||||
|
||||
void setup() {
|
||||
// FluteEx.init();
|
||||
Serial.begin(115200);
|
||||
Serial.println("starts");
|
||||
|
||||
Music.init();
|
||||
|
||||
Music.setGain1(1.0);
|
||||
Music.setGain2(1.0);
|
||||
Music.setGain3(1.0);
|
||||
|
||||
usbMIDI.setHandleNoteOff(OnNoteOff);
|
||||
usbMIDI.setHandleNoteOn(OnNoteOn);
|
||||
usbMIDI.setHandleControlChange(OnControlChange);
|
||||
|
||||
tick = millis();
|
||||
|
||||
}
|
||||
|
||||
|
||||
void loop() {
|
||||
// if(FluteEx.push_button()) x += 1;
|
||||
|
||||
springX.position(x);
|
||||
springY.position(springX.X);
|
||||
springZ.position(springY.X);
|
||||
|
||||
int f1 = basefreq + springX.X;
|
||||
int f2 = basefreq + springY.X;
|
||||
int f3 = basefreq + springZ.X;
|
||||
|
||||
Music.setFrequency1(f1);
|
||||
Music.setFrequency2(f2);
|
||||
Music.setFrequency3(f3);
|
||||
|
||||
if(millis() - tick > 200) {
|
||||
Serial.println(f3);
|
||||
tick = millis();
|
||||
}
|
||||
|
||||
usbMIDI.read();
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
#define MIDI_CHANNEL 1
|
||||
|
||||
#include <SpringMassDamper.h>
|
||||
#include <ExpMovAvg.h>
|
||||
#include <MinMaxLerp.h>
|
||||
|
||||
#include <Haarnet.h>
|
||||
#include <HaarnetExtensionFlute.h>
|
||||
|
||||
float x, y, z = 0;
|
||||
SpringMassDamper springX(50.0, 275.0, 1, &x);
|
||||
SpringMassDamper springY(50.0, 275.0, 1, &y);
|
||||
SpringMassDamper springZ(10.0, 275.0, 10, &z);
|
||||
|
||||
const int basefreq = 148;
|
||||
|
||||
long tick = 0;
|
||||
|
||||
void setup() {
|
||||
FluteEx.init();
|
||||
Serial.begin(115200);
|
||||
Serial.println("starts");
|
||||
|
||||
Music.init();
|
||||
|
||||
Music.setGain1(1.0);
|
||||
Music.setGain2(1.0);
|
||||
Music.setGain3(1.0);
|
||||
|
||||
usbMIDI.setHandleNoteOff(OnNoteOff);
|
||||
usbMIDI.setHandleNoteOn(OnNoteOn);
|
||||
usbMIDI.setHandleControlChange(OnControlChange);
|
||||
|
||||
Music.getPreset(4); ///// saved -- check max patch
|
||||
|
||||
tick = millis();
|
||||
|
||||
}
|
||||
|
||||
|
||||
void loop() {
|
||||
if(FluteEx.push_button()) x += 1;
|
||||
|
||||
springX.position(x);
|
||||
springY.position(springX.X);
|
||||
springZ.position(springY.X);
|
||||
|
||||
int f1 = basefreq + springX.X;
|
||||
int f2 = basefreq + springY.X;
|
||||
int f3 = basefreq + springZ.X;
|
||||
|
||||
Music.setFrequency1(f1);
|
||||
Music.setFrequency2(f2);
|
||||
Music.setFrequency3(f3);
|
||||
|
||||
if(millis() - tick > 200) {
|
||||
// Serial.println(f3);
|
||||
tick = millis();
|
||||
//Serial.println(cutmod);
|
||||
}
|
||||
|
||||
usbMIDI.read();
|
||||
|
||||
}
|
||||
|
||||
int cutmod = 90;
|
||||
float cutmod_indx = 0;
|
||||
float cutmod_incr = 0.00001;
|
||||
|
||||
void cutoff() {
|
||||
/// cutmod -- [80, .., 100]
|
||||
cutmod_indx += cutmod_incr;
|
||||
cutmod = 90 + (cos(cutmod_indx) * 20);
|
||||
Music.setCutoffModAmount((cutmod-64) * 1024);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
#define MIDI_CHANNEL 1
|
||||
|
||||
#include <SpringMassDamper.h>
|
||||
#include <ExpMovAvg.h>
|
||||
#include <MinMaxLerp.h>
|
||||
|
||||
#include <Haarnet.h>
|
||||
#include <HaarnetExtensionFlute.h>
|
||||
|
||||
float x, y, z = 0;
|
||||
SpringMassDamper springX(50.0, 275.0, 1, &x);
|
||||
SpringMassDamper springY(50.0, 275.0, 1, &y);
|
||||
SpringMassDamper springZ(10.0, 275.0, 10, &z);
|
||||
|
||||
const int basefreq = 100;
|
||||
|
||||
long tick = 0;
|
||||
|
||||
int fm2, fm3;
|
||||
|
||||
void setup() {
|
||||
FluteEx.init();
|
||||
Serial.begin(115200);
|
||||
Serial.println("starts");
|
||||
|
||||
Music.init();
|
||||
|
||||
Music.setGain1(1.0);
|
||||
Music.setGain2(1.0);
|
||||
Music.setGain3(1.0);
|
||||
|
||||
usbMIDI.setHandleNoteOff(OnNoteOff);
|
||||
usbMIDI.setHandleNoteOn(OnNoteOn);
|
||||
usbMIDI.setHandleControlChange(OnControlChange);
|
||||
|
||||
tick = millis();
|
||||
|
||||
}
|
||||
|
||||
|
||||
void loop() {
|
||||
if(FluteEx.push_button()) x += 1;
|
||||
|
||||
springX.position(x);
|
||||
springY.position(springX.X);
|
||||
springZ.position(springY.X);
|
||||
|
||||
int f1 = basefreq + springX.X;
|
||||
int f2 = basefreq + springY.X;
|
||||
int f3 = basefreq + springZ.X;
|
||||
|
||||
Music.setFrequency1(f1);
|
||||
Music.setFrequency2(f2);
|
||||
Music.setFrequency3(f3);
|
||||
|
||||
if(millis() - tick > 200) {
|
||||
// Serial.println(f3);
|
||||
tick = millis();
|
||||
Serial.println(fm2);
|
||||
}
|
||||
|
||||
// modulation1();
|
||||
//
|
||||
// modulation2();
|
||||
|
||||
modulation3();
|
||||
|
||||
usbMIDI.read();
|
||||
}
|
||||
|
||||
void modulation1() {
|
||||
static float indx = 0;
|
||||
indx += 0.00003;
|
||||
Music.setDetune1(sin(indx) * 0.05126);
|
||||
}
|
||||
|
||||
|
||||
float fm2_indx = 0;
|
||||
float fm2_incr = 0.00003;
|
||||
void modulation2() {
|
||||
fm2_indx += fm2_incr;
|
||||
fm2 = sin(fm2_indx) * 0.05946;
|
||||
Music.setDetune2(fm2);
|
||||
}
|
||||
|
||||
float fm3_indx = 0;
|
||||
float fm3_incr = 0.00003;
|
||||
void modulation3() {
|
||||
fm3_indx += fm3_incr;
|
||||
Music.setDetune3(cos(fm3_indx) * 0.05946);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user