diff --git a/src/controller/controller.hxx b/src/controller/controller.hxx index be5e993..cb6b36e 100644 --- a/src/controller/controller.hxx +++ b/src/controller/controller.hxx @@ -66,6 +66,9 @@ class Controller /// FX virtual void trackSend(int t, int send, float v){} virtual void trackSendActive(int t, int send, bool a){} + + virtual void trackJackSend(int t, float v){} + virtual void trackJackSendActivate(int t, bool a){} /// Time virtual void bpm(int bpm){} diff --git a/src/controller/genericmidi.cxx b/src/controller/genericmidi.cxx index d6ffb29..b8d71f1 100644 --- a/src/controller/genericmidi.cxx +++ b/src/controller/genericmidi.cxx @@ -209,6 +209,16 @@ void GenericMIDI::trackSendActive(int t, int send, bool a) } } +void GenericMIDI::trackJackSend(int t, float v) +{ + +} + +void GenericMIDI::trackJackSendActivate(int t, bool a) +{ + +} + /* void GenericMIDI::progress(int t, int s, float f) { diff --git a/src/controller/genericmidi.hxx b/src/controller/genericmidi.hxx index 11482bd..f5841b4 100644 --- a/src/controller/genericmidi.hxx +++ b/src/controller/genericmidi.hxx @@ -75,6 +75,9 @@ class GenericMIDI : public Controller, public MidiIO void trackSend(int t, int send, float v); void trackSendActive(int t, int send, bool a); + + virtual void trackJackSend(int t, float v); + virtual void trackJackSendActivate(int t, bool a); /// footswitch -> scene launch controls void setFootswitchToNextScene(int v); diff --git a/src/controller/guicontroller.cxx b/src/controller/guicontroller.cxx index 6ab9dc5..bc7a5c3 100644 --- a/src/controller/guicontroller.cxx +++ b/src/controller/guicontroller.cxx @@ -95,6 +95,18 @@ void LupppGUI::trackSendActive(int t, int send, bool a) writeToGuiRingbuffer( &e ); } +void LupppGUI::trackJackSend(int t, float v) +{ + EventTrackJackSend e(t,v); + writeToGuiRingbuffer(&e); +} + +void LupppGUI::trackJackSendActivate(int t, bool a) +{ + EventTrackJackSendActivate e(t,a); + writeToGuiRingbuffer(&e); +} + void LupppGUI::setSceneState(int t, int clip, GridLogic::State s) { EventGridState e( t, clip, s ); diff --git a/src/controller/guicontroller.hxx b/src/controller/guicontroller.hxx index 7dfab4c..f346b50 100644 --- a/src/controller/guicontroller.hxx +++ b/src/controller/guicontroller.hxx @@ -41,6 +41,9 @@ class LupppGUI : public Controller void trackSend(int t, int send, float r); void trackSendActive(int t, int send, bool a); + + virtual void trackJackSend(int t, float v); + virtual void trackJackSendActivate(int t, bool a); void bpm(int bpm); void tapTempo( bool b ); diff --git a/src/controllerupdater.cxx b/src/controllerupdater.cxx index d759185..546dcb5 100644 --- a/src/controllerupdater.cxx +++ b/src/controllerupdater.cxx @@ -117,7 +117,19 @@ void ControllerUpdater::setTrackSendActive(int t, int send, bool v) void ControllerUpdater::setTrackSend(int t, int send, float v) { for(unsigned int i = 0; i < c.size(); i++) - c.at(i)->trackSend(t, send, v); + c.at(i)->trackSend(t, send, v); +} + +void ControllerUpdater::setTrackJackSendActive(int t, bool v) +{ + for(unsigned int i = 0; i < c.size(); i++) + c.at(i)->trackJackSendActivate(t, v); +} + +void ControllerUpdater::setTrackJackSend(int t, float v) +{ + for(unsigned int i = 0; i < c.size(); i++) + c.at(i)->trackJackSend(t, v); } void ControllerUpdater::specialScene(int t, int scene) diff --git a/src/controllerupdater.hxx b/src/controllerupdater.hxx index aa2922d..216cb54 100644 --- a/src/controllerupdater.hxx +++ b/src/controllerupdater.hxx @@ -67,6 +67,9 @@ class ControllerUpdater void setTrackSceneProgress(int t, int s, float p); void setTrackSendActive(int t, int send, bool v); void setTrackSend(int t, int send, float v); + + void setTrackJackSendActive(int t, bool v); + void setTrackJackSend(int t, float v); void specialScene(int t, int scene); diff --git a/src/event.cxx b/src/event.cxx index e0337f8..d8e3c3c 100644 --- a/src/event.cxx +++ b/src/event.cxx @@ -28,6 +28,8 @@ const char* EventMasterInputToActive::prettyName = "master:input_to_active"; const char* EventTrackVol::prettyName = "track:volume"; const char* EventTrackSend::prettyName = "track:send"; const char* EventTrackSendActive::prettyName = "track:send_active"; +const char* EventTrackJackSend::prettyName = "track:jack_send"; +const char* EventTrackJackSendActivate::prettyName = "track:jack_send_activate"; const char* EventTrackRecordArm::prettyName = "track:record_arm"; const char* EventTimeBPM::prettyName = "tempo_bpm"; @@ -67,6 +69,8 @@ const char* Event::getPrettyName( int type ) case TRACK_VOLUME:{ return EventTrackVol::prettyName; } case TRACK_SEND:{ return EventTrackSend::prettyName; } case TRACK_SEND_ACTIVE:{ return EventTrackSendActive::prettyName; } + case TRACK_JACKSEND:{ return EventTrackJackSend::prettyName; } + case TRACK_JACKSEND_ACTIVATE:{ return EventTrackJackSendActivate::prettyName; } case TRACK_RECORD_ARM:{ return EventTrackRecordArm::prettyName; } case TIME_BPM:{ return EventTimeBPM::prettyName; } diff --git a/src/event.hxx b/src/event.hxx index 74d08ca..372f3a2 100644 --- a/src/event.hxx +++ b/src/event.hxx @@ -84,6 +84,8 @@ namespace Event GRID_SELECT_NEW_CHOSEN, // a different clip is now "special" /// Track + TRACK_JACKSEND, + TRACK_JACKSEND_ACTIVATE, TRACK_SEND, TRACK_SEND_ACTIVE, TRACK_SIGNAL_LEVEL, @@ -471,6 +473,22 @@ class EventTrackSend : public EventBase EventTrackSend(int t, SEND_TYPE s, float v): track(t), send(s), value(v){} }; +class EventTrackJackSend : public EventBase +{ + public: + int type() { return int(TRACK_JACKSEND); } + uint32_t size() { return sizeof(EventTrackJackSend); } + static const char* prettyName; + const char* name(){ return prettyName; } + + int track; + + float value; + + EventTrackJackSend(){}; + EventTrackJackSend(int t, float v): track(t), value(v){} +}; + class EventTrackSendActive : public EventBase { public: @@ -487,6 +505,20 @@ class EventTrackSendActive : public EventBase EventTrackSendActive(int t, SEND_TYPE s, bool a): track(t), send(s), active(a){} }; +class EventTrackJackSendActivate : public EventBase +{ + public: + int type() { return int(TRACK_JACKSEND_ACTIVATE); } + uint32_t size() { return sizeof(EventTrackJackSendActivate); } + static const char* prettyName; + const char* name(){ return prettyName; } + + int track; + bool active; + + EventTrackJackSendActivate(){}; + EventTrackJackSendActivate(int t, bool a): track(t), active(a){} +}; class EventLooperState : public EventBase { public: diff --git a/src/eventhandlerdsp.cxx b/src/eventhandlerdsp.cxx index 2cd6a0d..25fbb14 100644 --- a/src/eventhandlerdsp.cxx +++ b/src/eventhandlerdsp.cxx @@ -287,6 +287,24 @@ void handleDspEvents() jack->bindingSend = ev.send; jack->bindingActive = ev.active; } break; } + + case Event::TRACK_JACKSEND_ACTIVATE: { + if ( availableRead >= sizeof(EventTrackJackSendActivate) ) { + EventTrackJackSendActivate ev; + jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventTrackJackSendActivate) ); + jack->getLogic()->trackJackSendActivate(ev.track,ev.active); + jack->bindingTrack = ev.track; + + jack->bindingActive = ev.active; + } break; } + + case Event::TRACK_JACKSEND: { + if ( availableRead >= sizeof(EventTrackJackSend) ) { + EventTrackJackSend ev; + jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventTrackJackSend) ); + jack->getLogic()->trackJackSend(ev.track,ev.value); + jack->bindingTrack = ev.track; + } break; } case Event::TRACK_SEND: { if ( availableRead >= sizeof(EventTrackSend) ) { diff --git a/src/eventhandlergui.cxx b/src/eventhandlergui.cxx index d60ea2c..9336fa0 100644 --- a/src/eventhandlergui.cxx +++ b/src/eventhandlergui.cxx @@ -244,6 +244,20 @@ void handleGuiEvents() gui->getTrack(ev.track)->setXSide( ev.value ); } } break; } + + case Event::TRACK_JACKSEND: { + if ( availableRead >= sizeof(EventTrackJackSend) ) { + EventTrackJackSend ev; + jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventTrackJackSend) ); + gui->getTrack(ev.track)->setJackSend(ev.value); + } break; } + + case Event::TRACK_JACKSEND_ACTIVATE: { + if ( availableRead >= sizeof(EventTrackJackSendActivate) ) { + EventTrackJackSendActivate ev; + jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventTrackJackSendActivate) ); + gui->getTrack(ev.track)->setJackSendActivate(ev.active); + } break; } case Event::TRACK_SEND_ACTIVE: { if ( availableRead >= sizeof(EventTrackSendActive) ) { diff --git a/src/gtrack.cxx b/src/gtrack.cxx index 002ec3c..c267127 100644 --- a/src/gtrack.cxx +++ b/src/gtrack.cxx @@ -74,7 +74,7 @@ GTrack::GTrack(int x, int y, int w, int h, const char* l ) : volume.callback( gtrack_vol_cb, this ); - jackSendActivate.setColor( 0, 0.6, 1 ); + jackSendActivate.setColor( 1, 1, 0 ); jackSendActivate.callback(gtrack_jacksendactivate_cb,this); jackSendDial.align(FL_ALIGN_INSIDE); //volBox.color( fl_rgb_color( 0,0,0 ) ); @@ -97,6 +97,15 @@ void GTrack::setSendActive(bool a){ sendActive.value( a ); } void GTrack::setKeyActive(bool a){ keyActive.value( a ); } void GTrack::setRecordActive(bool a){ recordActive.value( a ); } +void GTrack::setJackSend(float s) +{ + jackSendDial.value(s); +} + +void GTrack::setJackSendActivate(bool a) +{ + jackSendActivate.value(a); +} void gtrack_sendDial_cb(Fl_Widget *w, void *data) { @@ -185,5 +194,15 @@ void gtrack_jacksendactivate_cb(Fl_Widget* w,void *data) Avtk::LightButton* d = (Avtk::LightButton*)w; bool b=d->value(); d->value(!b); + if ( b < 0.5 ) + { + EventTrackJackSendActivate e( track->ID, 1.0f ); + writeToDspRingbuffer( &e ); + } + else + { + EventTrackJackSendActivate e( track->ID, 0.0f ); + writeToDspRingbuffer( &e ); + } } diff --git a/src/gtrack.hxx b/src/gtrack.hxx index 64bfdb0..016424d 100644 --- a/src/gtrack.hxx +++ b/src/gtrack.hxx @@ -70,6 +70,8 @@ class GTrack : public Fl_Group void setKeyActive(bool a); void setRecordActive(bool a); + void setJackSend(float s); + void setJackSendActivate(bool a); int ID; diff --git a/src/jack.cxx b/src/jack.cxx index 456c414..d3463c6 100644 --- a/src/jack.cxx +++ b/src/jack.cxx @@ -326,6 +326,20 @@ TrackOutput* Jack::getTrackOutput(int t) return 0; } +JackSendReturn* Jack::getJackSendReturn(int t) +{ + if ( t >= 0 && t < NTRACKS ) + return tracksendreturns.at(t); +#ifdef DEBUG_TRACKS + else + { + printf( "Jack::getTrackOutput() returning 0x0: invalid track requested!\n" ); + } +#endif + + return 0; +} + Looper* Jack::getLooper(int t) { diff --git a/src/jack.hxx b/src/jack.hxx index bef1f2f..f0796fa 100644 --- a/src/jack.hxx +++ b/src/jack.hxx @@ -111,8 +111,9 @@ class Jack int bindingScene; int bindingSend; int bindingActive; - - private: + + JackSendReturn *getJackSendReturn(int t); +private: jack_client_t* client; Buffers buffers; diff --git a/src/jacksendreturn.cxx b/src/jacksendreturn.cxx index b66f42f..8ab7a47 100644 --- a/src/jacksendreturn.cxx +++ b/src/jacksendreturn.cxx @@ -9,6 +9,7 @@ JackSendReturn::JackSendReturn(int trackid, AudioProcessor *prev, jack_client_t m_sendport=jack_port_register(client,name,JACK_DEFAULT_AUDIO_TYPE,JackPortIsOutput,0); sprintf(name, "Return_track_%d\0",trackid); m_returnport=jack_port_register(client,name,JACK_DEFAULT_AUDIO_TYPE,JackPortIsInput,0); + m_active=false; } void JackSendReturn::process(unsigned int nframes, Buffers *buffers) @@ -22,17 +23,25 @@ void JackSendReturn::process(unsigned int nframes, Buffers *buffers) float* ret=(float*)jack_port_get_buffer(m_returnport,(jack_nframes_t)nframes); //Copy result of previous AudioProcessor to send port - memcpy(send,buffers->audio[Buffers::SEND_TRACK_0+m_trackid],nframes*sizeof(float)); + //memcpy(send,buffers->audio[Buffers::SEND_TRACK_0+m_trackid],nframes*sizeof(float)); + for(int i=0;iaudio[Buffers::SEND_TRACK_0+m_trackid][i]; - //Get connection status - bool connected=jack_port_connected(m_returnport); - //Is return port connected? - //Yes then grab the audio data from the connected port - //No: get the audio from the previous AudioProcessor - if(connected) + + if(m_active) memcpy(buffers->audio[Buffers::RETURN_TRACK_0+m_trackid],ret,nframes*sizeof(float)); else memcpy(buffers->audio[Buffers::RETURN_TRACK_0+m_trackid], buffers->audio[Buffers::SEND_TRACK_0+m_trackid],nframes*sizeof(float)); } + +void JackSendReturn::activate(bool act) +{ + m_active=act; +} + +void JackSendReturn::sendVolume(float vol) +{ + m_sendvol=vol; +} diff --git a/src/jacksendreturn.hxx b/src/jacksendreturn.hxx index 3d31ca2..262db94 100644 --- a/src/jacksendreturn.hxx +++ b/src/jacksendreturn.hxx @@ -36,7 +36,14 @@ public: //The process callback virtual void process(unsigned int nframes, Buffers* buffers); + //Activate the return chain. When m_active=true then Buffers::RETURN_TRACK_0+m_trackid gets the data + //from the return port. The send port always send the incoming data + void activate(bool act); + void sendVolume(float vol); + private: + bool m_active; + float m_sendvol; jack_port_t* m_sendport; jack_port_t* m_returnport; int m_trackid; diff --git a/src/logic.cxx b/src/logic.cxx index 783267a..84fd3ba 100644 --- a/src/logic.cxx +++ b/src/logic.cxx @@ -25,7 +25,7 @@ extern Jack* jack; #include "controllerupdater.hxx" #include "trackoutput.hxx" #include "metronome.hxx" - +#include "jacksendreturn.hxx" Logic::Logic() { @@ -128,6 +128,32 @@ void Logic::trackSend(int t, int send, float v) } } +void Logic::trackJackSendActivate(int t, bool active) +{ + if ( t >= 0 && t < NTRACKS ) + { + jack->getJackSendReturn(t)->activate(active); + jack->getControllerUpdater()->setTrackJackSendActive( t, active ); + } + else + { + LUPPP_WARN("invalid track number %i: check controller map has \"track\" field.", t ); + } +} + +void Logic::trackJackSend(int t, float vol) +{ + if ( t >= 0 && t < NTRACKS ) + { + jack->getJackSendReturn(t)->sendVolume(vol); + jack->getControllerUpdater()->setTrackJackSend( t, vol ); + } + else + { + LUPPP_WARN("invalid track number %i: check controller map has \"track\" field.", t ); + } +} + void Logic::looperClipLenght(int t, int s, int l) { if ( t >= 0 && t < NTRACKS ) diff --git a/src/logic.hxx b/src/logic.hxx index 365dbba..5f15c1f 100644 --- a/src/logic.hxx +++ b/src/logic.hxx @@ -56,7 +56,9 @@ class Logic void trackRecordArm(int track, bool armed); void trackSendActive(int track, int send, bool active); void trackSend(int track, int send, float value); - + + void trackJackSendActivate(int t, bool active); + void trackJackSend(int t, float vol); void looperUseAsTempo(int track, int scene); void looperClipLenght(int track, int scene, int lenght); };