From 256ef71491a90e80302eee81dc7d28601f19485e Mon Sep 17 00:00:00 2001 From: Valentin Boettcher Date: Mon, 26 Mar 2018 19:28:09 +0200 Subject: [PATCH] Here we go. A nicer implementation --- src/avtk/clipselector.cxx | 91 ++++++++++++++++++++++++--------------- src/avtk/clipselector.hxx | 5 +++ src/event.hxx | 20 +++++++++ src/eventhandlerdsp.cxx | 9 ++-- src/logic.cxx | 9 ++++ src/logic.hxx | 1 + src/looper.cxx | 2 +- src/looperclip.cxx | 20 ++++----- src/looperclip.hxx | 6 +-- 9 files changed, 111 insertions(+), 52 deletions(-) diff --git a/src/avtk/clipselector.cxx b/src/avtk/clipselector.cxx index b0ab6bf..568ebaa 100644 --- a/src/avtk/clipselector.cxx +++ b/src/avtk/clipselector.cxx @@ -31,7 +31,7 @@ namespace Avtk { ClipSelector::ClipSelector( int _x, int _y, int _w, int _h, - const char *_label, bool master ) : + const char *_label, bool master ) : Fl_Button(_x, _y, _w, _h) { copy_label(_label); @@ -232,7 +232,41 @@ void ClipSelector::resize(int X, int Y, int W, int H) redraw(); } +void setRecordBarsCb(Fl_Widget *w, void* data) +{ + ClipSelector *track = (ClipSelector*)w; + long bars = (long)data; + if(bars == -2){ + const char* answer = fl_input("Enter a custom number: "); + bars = atoi(answer); + } + EventLooperBarsToRecord e(track->ID, track->getLastClipNum(), bars); + writeToDspRingbuffer( &e ); +} + +void setLengthCb(Fl_Widget *w, void* data) +{ + ClipSelector *track = (ClipSelector*)w; + long beats = (long)data; + EventLooperLoopLength e(track->ID, track->getLastClipNum(), beats); + writeToDspRingbuffer( &e ); +} + +int ClipSelector::findClipNum() { + // calculate the clicked clip number + int clipHeight = (h / numClips); + clipNum = ( (Fl::event_y() ) - y ) / clipHeight; + if (clipNum >= numClips) + clipNum = numClips -1; // fix for clicking the lowest pixel + + return clipNum; +} + +int ClipSelector::getLastClipNum() +{ + return clipNum; +} int ClipSelector::handle(int event) { @@ -245,11 +279,7 @@ int ClipSelector::handle(int event) case FL_PUSH: highlight = 1; { - // calculate the clicked clip number - int clipHeight = (h / numClips); - int clipNum = ( (Fl::event_y() ) - y ) / clipHeight; - if (clipNum >= numClips) - clipNum = numClips -1; // fix for clicking the lowest pixel + findClipNum(); // handle right clicks: popup menu if ( Fl::event_state(FL_BUTTON3) ) { @@ -269,13 +299,25 @@ int ClipSelector::handle(int event) { "Save" }, { "Special"}, { "Beats", 0, 0, 0, FL_SUBMENU | FL_MENU_DIVIDER }, - {"1 "}, - {"2"}, - {"4"}, - {"8"}, - {"16"}, - {"32"}, - {"64"}, + {"1 ", 0, setLengthCb, (void*)1,0}, + {"2 ", 0, setLengthCb, (void*)2,0}, + {"4 ", 0, setLengthCb, (void*)4,0}, + {"8 ", 0, setLengthCb, (void*)8,0}, + {"16 ", 0, setLengthCb, (void*)16,0}, + {"32 ", 0, setLengthCb, (void*)32,0}, + {"64 ", 0, setLengthCb, (void*)64,0}, + {0}, + { "Bars to record", 0, 0, 0, FL_SUBMENU | FL_MENU_DIVIDER}, + {"1 ", 0, setRecordBarsCb, (void*)1,0}, + {"2 ", 0, setRecordBarsCb, (void*)2,0}, + {"3 ", 0, setRecordBarsCb, (void*)3,0}, + {"4 ", 0, setRecordBarsCb, (void*)4,0}, + {"5 ", 0, setRecordBarsCb, (void*)5,0}, + {"6 ", 0, setRecordBarsCb, (void*)6,0}, + {"7 ", 0, setRecordBarsCb, (void*)7,0}, + {"8 ", 0, setRecordBarsCb, (void*)8,0}, + {"Custom", 0, setRecordBarsCb, (void*)-2,0}, + {"Endless", 0, setRecordBarsCb, (void*)-1,0}, {0}, //{ "Record" }, { "Use as tempo" }, @@ -302,27 +344,6 @@ int ClipSelector::handle(int event) free(tmp); gui->selectSaveSample( ID, clipNum ); } - } else if ( strcmp(m->label(), "1 ") == 0 ) { - EventLooperLoopLength e = EventLooperLoopLength(ID, clipNum ,1); - writeToDspRingbuffer( &e ); - } else if ( strcmp(m->label(), "2") == 0 ) { - EventLooperLoopLength e = EventLooperLoopLength(ID, clipNum ,2); - writeToDspRingbuffer( &e ); - } else if ( strcmp(m->label(), "4") == 0 ) { - EventLooperLoopLength e = EventLooperLoopLength(ID, clipNum ,4); - writeToDspRingbuffer( &e ); - } else if ( strcmp(m->label(), "8") == 0 ) { - EventLooperLoopLength e = EventLooperLoopLength(ID, clipNum ,8); - writeToDspRingbuffer( &e ); - } else if ( strcmp(m->label(), "16") == 0 ) { - EventLooperLoopLength e = EventLooperLoopLength(ID, clipNum ,16); - writeToDspRingbuffer( &e ); - } else if ( strcmp(m->label(), "32") == 0 ) { - EventLooperLoopLength e = EventLooperLoopLength(ID, clipNum ,32); - writeToDspRingbuffer( &e ); - } else if ( strcmp(m->label(), "64") == 0 ) { - EventLooperLoopLength e = EventLooperLoopLength(ID, clipNum ,64); - writeToDspRingbuffer( &e ); } else if ( strcmp(m->label(), "Use as tempo") == 0 ) { EventLooperUseAsTempo e (ID, clipNum); writeToDspRingbuffer( &e ); @@ -338,6 +359,8 @@ int ClipSelector::handle(int event) // for a clip to become 0 EventGridState e( ID, clipNum, GridLogic::STATE_EMPTY ); writeToDspRingbuffer( &e ); + } else { + m->do_callback(this, m->user_data()); } } else { if ( _master ) { diff --git a/src/avtk/clipselector.hxx b/src/avtk/clipselector.hxx index 35ba47d..b5eecd4 100644 --- a/src/avtk/clipselector.hxx +++ b/src/avtk/clipselector.hxx @@ -104,6 +104,11 @@ public: int handle(int event); void resize(int X, int Y, int W, int H); + int findClipNum(); + int getLastClipNum(); + +private: + int clipNum; }; } // Avtk diff --git a/src/event.hxx b/src/event.hxx index 8e7c1e3..45ba507 100644 --- a/src/event.hxx +++ b/src/event.hxx @@ -79,6 +79,7 @@ enum EVENT_TYPE { GRID_SELECT_CLIP_ENABLE, // enable selecting a clip from the grid GRID_SELECT_CLIP_EVENT, // a press / release on the selected clip GRID_SELECT_NEW_CHOSEN, // a different clip is now "special" + EVENT_LOOPER_BARS_TO_RECORD, // choose how many bars to record /// Track TRACK_JACKSEND, @@ -267,6 +268,25 @@ public: EventGridSelectNewChosen(int t = -1, int s = -1):track(t),scene(s) {} }; +class EventLooperBarsToRecord : public EventBase +{ +public: + int type() + { + return int(EVENT_LOOPER_BARS_TO_RECORD); + } + uint32_t size() + { + return sizeof(EventLooperBarsToRecord); + } + + int track; + int scene; + int bars; + EventLooperBarsToRecord(int t = -1, int s = -1, int b = -1) : track(t), scene(s), bars(b) {} +}; + + class EventQuit : public EventBase { public: diff --git a/src/eventhandlerdsp.cxx b/src/eventhandlerdsp.cxx index bbfd06b..64a9c09 100644 --- a/src/eventhandlerdsp.cxx +++ b/src/eventhandlerdsp.cxx @@ -224,7 +224,6 @@ void handleDspEvents() break; } - case Event::LOOPER_LOAD: { if ( availableRead >= sizeof(EventLooperLoad) ) { EventLooperLoad ev; @@ -266,8 +265,12 @@ void handleDspEvents() } break; } - - + case Event::EVENT_LOOPER_BARS_TO_RECORD: { + EventLooperBarsToRecord ev; + jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventLooperBarsToRecord) ); + jack->getLogic()->looperBarsToRecord( ev.track, ev.scene, ev.bars ); + break; + } case Event::LOOPER_LOOP_USE_AS_TEMPO: { if ( availableRead >= sizeof(EventLooperUseAsTempo) ) { EventLooperUseAsTempo ev; diff --git a/src/logic.cxx b/src/logic.cxx index af35962..dd9f583 100644 --- a/src/logic.cxx +++ b/src/logic.cxx @@ -152,6 +152,15 @@ void Logic::looperClipLenght(int t, int s, int l) } +void Logic::looperBarsToRecord(int t, int s, int b) +{ + if ( t >= 0 && t < NTRACKS ) { + jack->getLooper( t )->getClip( s )->setBarsToRecord(b); + } else { + LUPPP_WARN("invalid track number %i: check controller map has \"track\" field.", t ); + } +} + void Logic::looperUseAsTempo(int t, int s) { size_t clipBeats = jack->getLooper( t )->getClip( s )->getBeats(); diff --git a/src/logic.hxx b/src/logic.hxx index 1d2006e..19a645b 100644 --- a/src/logic.hxx +++ b/src/logic.hxx @@ -62,6 +62,7 @@ public: void trackJackSend(int t, float vol); void looperUseAsTempo(int track, int scene); void looperClipLenght(int track, int scene, int lenght); + void looperBarsToRecord(int track, int scene, int bars); }; #endif // LUPPP_LOGIC_H diff --git a/src/looper.cxx b/src/looper.cxx index bae7cf1..b05c67c 100644 --- a/src/looper.cxx +++ b/src/looper.cxx @@ -110,7 +110,7 @@ void Looper::process(unsigned int nframes, Buffers* buffers) // handle state of clip, and do what needs doing: // record into buffer, play from buffer, etc if ( clips[clip]->recording() ) { - if(clips[clip]->getWantedBeats() > 0 && clips[clip]->getBeats() >= clips[clip]->getWantedBeats() - 4) + if(clips[clip]->getBeatsToRecord() > 0 && clips[clip]->getBeats() >= clips[clip]->getBeatsToRecord() - 4) clips[clip]->queuePlay(true); if ( clips[clip]->recordSpaceAvailable() < LOOPER_SAMPLES_BEFORE_REQUEST && diff --git a/src/looperclip.cxx b/src/looperclip.cxx index 328768c..e2b6aca 100644 --- a/src/looperclip.cxx +++ b/src/looperclip.cxx @@ -60,8 +60,6 @@ void LooperClip::init() _playhead = 0; _recordhead = 0; - - } void LooperClip::save() @@ -188,14 +186,18 @@ void LooperClip::setPlayHead(float ph) } } -void LooperClip::setWantedBeats(int beats) +void LooperClip::setBarsToRecord(int bars) { - _wantedBeats = beats; + _wantedBeats = bars * 4; // we set bars } -int LooperClip::getWantedBeats() +int LooperClip::getBeatsToRecord() { - return _wantedBeats; + return _wantedBeats; +} + +int LooperClip::getBarsToRecord(){ + return _wantedBeats / 4; } void LooperClip::record(int count, float* L, float* R) @@ -249,12 +251,8 @@ size_t LooperClip::audioBufferSize() void LooperClip::setBeats(int beats) { if ( _buffer ) { - if(_buffer->getBeats() == 0) - setWantedBeats( beats ); _buffer->setBeats( beats ); - } else { - setWantedBeats( beats ); - } + } } int LooperClip::getBeats() diff --git a/src/looperclip.hxx b/src/looperclip.hxx index 872a84e..21b49e8 100644 --- a/src/looperclip.hxx +++ b/src/looperclip.hxx @@ -116,9 +116,9 @@ public: ///reset the play head to zero. Does nothing when recording void setPlayHead(float ph); - void setWantedBeats(int beats); - - int getWantedBeats(); + void setBarsToRecord(int bars); + int getBeatsToRecord(); + int getBarsToRecord(); #ifdef BUILD_TESTS // used only in test cases