From 3070b2904ac384c301664098914fd97cba63ae6e Mon Sep 17 00:00:00 2001 From: Harry van Haaren Date: Fri, 8 Aug 2014 13:54:18 +0100 Subject: [PATCH] -Implemented Transport Play/Stop, and UI button --- src/diskreader.cxx | 2 +- src/event.hxx | 13 +++++++++++++ src/eventhandlerdsp.cxx | 9 +++++++++ src/gmastertrack.cxx | 28 ++++++++++++++++++++++++++-- src/gmastertrack.hxx | 1 + src/jack.cxx | 23 +++++++++++------------ src/main.cxx | 5 +++-- src/timemanager.cxx | 15 +++++++++++++-- src/timemanager.hxx | 7 +++++++ 9 files changed, 84 insertions(+), 19 deletions(-) diff --git a/src/diskreader.cxx b/src/diskreader.cxx index ba09ab6..2df38d0 100644 --- a/src/diskreader.cxx +++ b/src/diskreader.cxx @@ -538,7 +538,7 @@ int DiskReader::readScenes(int t, cJSON* track) // get metadata for Clip cJSON* clip = cJSON_GetArrayItem( clips, s ); - if ( !strcmp(clip->valuestring, "") == 0 ) + if ( strcmp(clip->valuestring, "") != 0 ) { stringstream sampleFilePath; sampleFilePath << sessionPath << "/audio/" << clip->valuestring; diff --git a/src/event.hxx b/src/event.hxx index 87d9a57..20634a2 100644 --- a/src/event.hxx +++ b/src/event.hxx @@ -30,6 +30,7 @@ #include "looper.hxx" #include "gridlogic.hxx" +#include "transport.hxx" #pragma GCC diagnostic ignored "-Wunused-parameter" @@ -97,7 +98,9 @@ namespace Event LOOPER_LOOP_LENGTH, LOOPER_LOOP_USE_AS_TEMPO, + /// Transport etc METRONOME_ACTIVE, + TRANSPORT, /// rolling or stopped TIME_BPM, TIME_BAR_BEAT, @@ -149,6 +152,16 @@ class EventBase virtual const char* name(){return 0;} }; +class EventTransportState : public EventBase +{ + public: + int type() { return int(TRANSPORT); } + uint32_t size() { return sizeof(EventTransportState); } + TRANSPORT_STATE ts; + EventTransportState(): ts( TRANSPORT_STOPPED ){} + EventTransportState( TRANSPORT_STATE t): ts(t){} +}; + class EventControllerBindingMade : public EventBase { public: diff --git a/src/eventhandlerdsp.cxx b/src/eventhandlerdsp.cxx index 1ac7018..c2463d3 100644 --- a/src/eventhandlerdsp.cxx +++ b/src/eventhandlerdsp.cxx @@ -81,6 +81,15 @@ void handleDspEvents() } break; } + + // ======== TRANSPORT == + case Event::TRANSPORT: { + if ( availableRead >= sizeof(EventTransportState) ) { + EventTransportState ev; + jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventTransportState) ); + jack->getTimeManager()->setTransportState( ev.ts ); + } break; } + // ========= SAVE ===== case Event::STATE_SAVE: { if ( availableRead >= sizeof(EventStateSave) ) { diff --git a/src/gmastertrack.cxx b/src/gmastertrack.cxx index 67847e2..a310332 100644 --- a/src/gmastertrack.cxx +++ b/src/gmastertrack.cxx @@ -107,6 +107,26 @@ static void gmastertrack_mixVol_callback(Fl_Widget *w, void *data) //printf("MIX dial\n"); } +static void gmastertrack_transport_callback(Fl_Widget *w, void *data) +{ + Avtk::LightButton* b = (Avtk::LightButton*)w; + if( b->value() ) + { + EventTransportState e = EventTransportState( TRANSPORT_ROLLING ); + writeToDspRingbuffer( &e ); + w->label( "Stop" ); + b->value( 0 ); + } + else + { + EventTransportState e = EventTransportState( TRANSPORT_STOPPED ); + writeToDspRingbuffer( &e ); + w->label( "Play" ); + b->value( 1 ); + } + +} + static void gmastertrack_button_callback(Fl_Widget *w, void *data) { if ( strcmp( w->label(), "Metro" ) == 0 ) @@ -138,8 +158,9 @@ GMasterTrack::GMasterTrack(int x, int y, int w, int h, const char* l ) : source(x+5, y+26, 140, 100, ""), volBox(x+5, y+422, 140, 172, ""), - tapTempo ( x + w * 2/4.f - 18, y + 426 + 41 * 0, 44,38, "Tap"), - metronomeButton( x + w * 2/4.f - 18, y + 426 + 41 * 1, 44, 38,"Metro"), + transport ( x + w * 2/4.f - 18, y + 426 + 26 * 0, 44,24, "Stop" ), + tapTempo ( x + w * 2/4.f - 18, y + 426 + 26 * 1, 44,24, "Tap" ), + metronomeButton( x + w * 2/4.f - 18, y + 426 + 26 * 2, 44,24,"Metro"), tempoDial ( x + w * 2/4.f - 18, y + 426 + 41 * 2, 45, 36,"BPM"), returnVol ( x + w * 2/4.f - 18, y + 426 + 41 * 3, 45, 36,"Return"), @@ -166,7 +187,10 @@ GMasterTrack::GMasterTrack(int x, int y, int w, int h, const char* l ) : inputVolume.callback( gmastertrack_inputVolume_callback, 0 ); + transport.callback( gmastertrack_transport_callback, &ID ); + tapTempo.callback( gmastertrack_button_callback, &ID ); + metronomeButton.callback( gmastertrack_button_callback, 0 ); tempoDial.callback( gmastertrack_tempoDial_callback, 0 ); diff --git a/src/gmastertrack.hxx b/src/gmastertrack.hxx index cf1202b..06f5c13 100644 --- a/src/gmastertrack.hxx +++ b/src/gmastertrack.hxx @@ -88,6 +88,7 @@ class GMasterTrack : public Fl_Group Avtk::Box source; Avtk::Box volBox; + Avtk::Button transport; Avtk::Button tapTempo; Avtk::LightButton metronomeButton; Avtk::Dial tempoDial; diff --git a/src/jack.cxx b/src/jack.cxx index be76611..b8ea143 100644 --- a/src/jack.cxx +++ b/src/jack.cxx @@ -345,6 +345,17 @@ int Jack::process (jack_nframes_t nframes) buffers.audio[Buffers::JACK_SIDECHAIN_KEY] = (float*)jack_port_get_buffer(sidechainKeyOutput,nframes); buffers.audio[Buffers::JACK_SIDECHAIN_SIGNAL]=(float*)jack_port_get_buffer(sidechainSignalOutput,nframes); + // clear the buffers + memset( buffers.audio[Buffers::JACK_MASTER_OUT_L] , 0, sizeof(float) * nframes ); + memset( buffers.audio[Buffers::JACK_MASTER_OUT_R] , 0, sizeof(float) * nframes ); + memset( buffers.audio[Buffers::MASTER_OUT_L] , 0, sizeof(float) * nframes ); + memset( buffers.audio[Buffers::MASTER_OUT_R] , 0, sizeof(float) * nframes ); + memset( buffers.audio[Buffers::HEADPHONES_OUT] , 0, sizeof(float) * nframes ); + memset( buffers.audio[Buffers::SEND] , 0, sizeof(float) * nframes ); + memset( buffers.audio[Buffers::SIDECHAIN_KEY] , 0, sizeof(float) * nframes ); + memset( buffers.audio[Buffers::SIDECHAIN_SIGNAL] , 0, sizeof(float) * nframes ); + + //buffers.midi [Buffers::MASTER_MIDI_INPUT] = (void*) jack_port_get_buffer( masterMidiInput, nframes ); /// init buffers for each MidiIO @@ -394,18 +405,6 @@ void Jack::processFrames(int nframes) return; } - // clear the buffers - memset( buffers.audio[Buffers::JACK_MASTER_OUT_L] , 0, sizeof(float) * nframes ); - memset( buffers.audio[Buffers::JACK_MASTER_OUT_R] , 0, sizeof(float) * nframes ); - memset( buffers.audio[Buffers::MASTER_OUT_L] , 0, sizeof(float) * nframes ); - memset( buffers.audio[Buffers::MASTER_OUT_R] , 0, sizeof(float) * nframes ); - memset( buffers.audio[Buffers::HEADPHONES_OUT] , 0, sizeof(float) * nframes ); - memset( buffers.audio[Buffers::SEND] , 0, sizeof(float) * nframes ); - memset( buffers.audio[Buffers::SIDECHAIN_KEY] , 0, sizeof(float) * nframes ); - memset( buffers.audio[Buffers::SIDECHAIN_SIGNAL] , 0, sizeof(float) * nframes ); - - - /// process each MidiIO registered MIDI port for(unsigned int i = 0; i < midiIO.size(); i++ ) { diff --git a/src/main.cxx b/src/main.cxx index 6caaef9..a44306f 100644 --- a/src/main.cxx +++ b/src/main.cxx @@ -87,7 +87,7 @@ int main(int argc, char** argv) rbToDsp = jack_ringbuffer_create( 5000 * sizeof(EventBase)); rbToGui = jack_ringbuffer_create( 5000 * sizeof(EventBase)); - + #ifdef BUILD_TESTS LUPPP_NOTE("Built with BUILD_TESTS enabled"); if ( runTests ) @@ -115,8 +115,8 @@ int main(int argc, char** argv) // running tests == quitting after testing finishes return testResult; } -#endif +#endif // Create a GUI, check for NSM integration gui = new Gui( argv[0] ); @@ -134,6 +134,7 @@ int main(int argc, char** argv) gui->show(); + return 0; } diff --git a/src/timemanager.cxx b/src/timemanager.cxx index 30d7525..5cc6d10 100644 --- a/src/timemanager.cxx +++ b/src/timemanager.cxx @@ -33,7 +33,8 @@ extern Jack* jack; using namespace std; TimeManager::TimeManager(): - observers() + observers(), + transportState( TRANSPORT_ROLLING ) { samplerate = jack->getSamplerate(); // 120 BPM default @@ -144,12 +145,22 @@ int TimeManager::getNframesToBeat() return -1; //beatFrameCountdown; } +void TimeManager::setTransportState( TRANSPORT_STATE s ) +{ + transportState = s; +} + void TimeManager::process(Buffers* buffers) { // time signature? //buffers->transportPosition->beats_per_bar = 4; //buffers->transportPosition->beat_type = 4; + if ( transportState == TRANSPORT_STOPPED ) + { + return; + } + int nframes = buffers->nframes; totalFrameCounter += nframes; @@ -221,7 +232,7 @@ void TimeManager::process(Buffers* buffers) buffers->transportPosition->beat = (beatCounter % 4) + 1; // beats 1-4 float part = float( fpb-beatFrameCountdown) / fpb; - buffers->transportPosition->tick = part > 1.0f? 0.9999 : part*1920; + buffers->transportPosition->tick = part > 1.0f? 0.9999*1920 : part*1920; buffers->transportPosition->frame = totalFrameCounter; diff --git a/src/timemanager.hxx b/src/timemanager.hxx index 4d0b4ce..51fa8f9 100644 --- a/src/timemanager.hxx +++ b/src/timemanager.hxx @@ -23,6 +23,7 @@ #include #include "buffers.hxx" +#include "transport.hxx" #include "eventhandler.hxx" #include "observer/time.hxx" @@ -53,10 +54,16 @@ class TimeManager /// returns the number of samples till beat if a beat exists in this process /// Otherwise returns nframes int getNframesToBeat(); + + /// TRANSPORT_STATE is defined in transport.hxx + void setTransportState( TRANSPORT_STATE s ); private: int samplerate; + /// the "state" of the transport: rolling or stopped + TRANSPORT_STATE transportState; + /// number of frames per beat float fpb;