diff --git a/src/controller/apc.cxx b/src/controller/apc.cxx index 1f6859e..2ce0e61 100644 --- a/src/controller/apc.cxx +++ b/src/controller/apc.cxx @@ -10,14 +10,32 @@ AkaiAPC::AkaiAPC() } -void AkaiAPC::record(int t, bool b) +void AkaiAPC::recordArm(int t, bool enabled) { unsigned char data[3]; data[0] = 144 + t; - data[1] = 48; // record LED - data[2] = 127 * b; + data[1] = 48; // record enable LED + data[2] = enabled ? 127 : 0; + jack->writeApcOutput( &data[0] ); +} + +void AkaiAPC::clipSelect(int t, int clip, ClipMode cm) +{ + unsigned char data[3]; + data[0] = 144 + t; + data[1] = 53 + clip; + + switch (cm) + { + case CLIP_MODE_EMPTY: data[2] = 0; break; + case CLIP_MODE_PLAYING: data[2] = 1; break; + case CLIP_MODE_PLAY_QUEUED: data[2] = 2; break; + case CLIP_MODE_RECORDING: data[2] = 3; break; + //case CLIP_MODE_RECORDING: data[2] = 4; break; + case CLIP_MODE_LOADED: data[2] = 5; break; + } + jack->writeApcOutput( &data[0] ); - cout << "record written to JACK" << endl; } void AkaiAPC::mute(int t, bool b) @@ -25,10 +43,6 @@ void AkaiAPC::mute(int t, bool b) } -void AkaiAPC::clipSelect(int t, bool b) -{ - -} void AkaiAPC::volume(int t, float f) { diff --git a/src/controller/apc.hxx b/src/controller/apc.hxx index 74d5f55..066a1e4 100644 --- a/src/controller/apc.hxx +++ b/src/controller/apc.hxx @@ -11,10 +11,10 @@ class AkaiAPC : public Controller AkaiAPC(); void mute(int t, bool b); - void clipSelect(int t, bool b); - - virtual void record(int t, bool b); void volume(int t, float f); + void recordArm(int t, bool b); + void clipSelect(int track, int clip, ClipMode cm); + }; #endif // LUPPP_APC_H diff --git a/src/controller/controller.hxx b/src/controller/controller.hxx index f8a4401..d511c0c 100644 --- a/src/controller/controller.hxx +++ b/src/controller/controller.hxx @@ -6,15 +6,32 @@ class Controller { public: + /* + make a state class for a whole track + class TrackState { + int track; + + }; + */ + + enum ClipMode { + CLIP_MODE_PLAYING, + CLIP_MODE_PLAY_QUEUED, + CLIP_MODE_LOADED, + CLIP_MODE_RECORDING, + CLIP_MODE_RECORD_QUEUED, + CLIP_MODE_EMPTY, + }; + Controller(){}; virtual ~Controller(){}; + //virtual void setTrack(TrackState& t); + virtual void mute(int t, bool b){}; - virtual void clipSelect(int t, bool b){}; - - virtual void record(int t, bool b) = 0; - virtual void volume(int t, float f){}; + virtual void recordArm(int t, bool r){}; + virtual void clipSelect(int track, int clip, ClipMode cm){}; }; #endif // LUPPP_CONTROLLER_H diff --git a/src/controllerupdater.hxx b/src/controllerupdater.hxx index 9e05f73..ef9b0f7 100644 --- a/src/controllerupdater.hxx +++ b/src/controllerupdater.hxx @@ -15,14 +15,6 @@ using namespace std; class ControllerUpdator { public: - enum ClipMode { - CLIP_MODE_PLAYING, - CLIP_MODE_PLAY_QUEUED, - CLIP_MODE_LOADED, - CLIP_MODE_EMPTY, - }; - - ControllerUpdator() { c.push_back( new AkaiAPC() ); @@ -33,17 +25,17 @@ class ControllerUpdator for(int i = 0; i < c.size(); i++) c.at(i)->mute(t,b); } - void clipSelect(int t, ClipMode cm) + void clipSelect(int t, int clip, Controller::ClipMode cm) { for(int i = 0; i < c.size(); i++) - c.at(i)->clipSelect(t,cm); + c.at(i)->clipSelect(t,clip,cm); } - void record(int t, bool r) + void recordArm(int t, bool r) { cout << "record() " << t << " " << r << endl; for(int i = 0; i < c.size(); i++) - c.at(i)->record(t,r); + c.at(i)->recordArm(t,r); } void volume(int t, float v) diff --git a/src/looper.cxx b/src/looper.cxx index 11bf5ef..6fe0e5c 100644 --- a/src/looper.cxx +++ b/src/looper.cxx @@ -4,6 +4,7 @@ #include "jack.hxx" #include "eventhandler.hxx" +#include "controllerupdater.hxx" extern Jack* jack; @@ -70,25 +71,45 @@ void Looper::midi(unsigned char* data) void Looper::setState(State s) { + // quantize recording to next bar event if ( state == STATE_RECORDING ) { stopRecordOnBar = true; } state = s; - + updateControllers(); +} + +void Looper::updateControllers() +{ if (state == STATE_RECORD_QUEUED ) { numBeats = 0; - jack->getControllerUpdator()->record(track, true); + jack->getControllerUpdator()->recordArm(track, true); } else { - jack->getControllerUpdator()->record(track, false); + jack->getControllerUpdator()->recordArm(track, false); } if (state == STATE_PLAY_QUEUED ) { + jack->getControllerUpdator()->clipSelect(track, 0, Controller::CLIP_MODE_PLAY_QUEUED); + } + else if ( state == STATE_PLAYING ) + { + jack->getControllerUpdator()->clipSelect(track, 0, Controller::CLIP_MODE_PLAYING); + } + + if (state == STATE_STOP_QUEUED ) + { + jack->getControllerUpdator()->clipSelect(track, 0, Controller::CLIP_MODE_LOADED); + } + else if ( state == STATE_STOPPED ) + { + jack->getControllerUpdator()->clipSelect(track, 0, Controller::CLIP_MODE_LOADED); + } } void Looper::process(int nframes, Buffers* buffers) @@ -155,6 +176,7 @@ void Looper::process(int nframes, Buffers* buffers) void Looper::bar() { + int barTmpState = state; // queue stop recording -> stop recording, now calculate beats in loop if ( stopRecordOnBar ) { @@ -193,6 +215,11 @@ void Looper::bar() state = STATE_STOPPED; endPoint = lastWrittenSampleIndex; } + + if ( barTmpState != state ) + { + jack->getControllerUpdator()->recordArm( track, state == STATE_RECORDING ? 1 : 0 ); + } } void Looper::beat() diff --git a/src/looper.hxx b/src/looper.hxx index 5cb2c0b..e6d93ae 100644 --- a/src/looper.hxx +++ b/src/looper.hxx @@ -34,6 +34,7 @@ class Looper : public Observer // for notifications void setState(State s); void setLoopLength(float l); + void updateControllers(); void process(int nframes, Buffers* buffers); private: