Here we go. A nicer implementation

This commit is contained in:
Valentin Boettcher 2018-03-26 19:28:09 +02:00
parent 0efe0731d1
commit 256ef71491
9 changed files with 111 additions and 52 deletions

View file

@ -31,7 +31,7 @@ namespace Avtk
{ {
ClipSelector::ClipSelector( int _x, int _y, int _w, int _h, 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) Fl_Button(_x, _y, _w, _h)
{ {
copy_label(_label); copy_label(_label);
@ -232,7 +232,41 @@ void ClipSelector::resize(int X, int Y, int W, int H)
redraw(); 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) int ClipSelector::handle(int event)
{ {
@ -245,11 +279,7 @@ int ClipSelector::handle(int event)
case FL_PUSH: case FL_PUSH:
highlight = 1; highlight = 1;
{ {
// calculate the clicked clip number findClipNum();
int clipHeight = (h / numClips);
int clipNum = ( (Fl::event_y() ) - y ) / clipHeight;
if (clipNum >= numClips)
clipNum = numClips -1; // fix for clicking the lowest pixel
// handle right clicks: popup menu // handle right clicks: popup menu
if ( Fl::event_state(FL_BUTTON3) ) { if ( Fl::event_state(FL_BUTTON3) ) {
@ -269,13 +299,25 @@ int ClipSelector::handle(int event)
{ "Save" }, { "Save" },
{ "Special"}, { "Special"},
{ "Beats", 0, 0, 0, FL_SUBMENU | FL_MENU_DIVIDER }, { "Beats", 0, 0, 0, FL_SUBMENU | FL_MENU_DIVIDER },
{"1 "}, {"1 ", 0, setLengthCb, (void*)1,0},
{"2"}, {"2 ", 0, setLengthCb, (void*)2,0},
{"4"}, {"4 ", 0, setLengthCb, (void*)4,0},
{"8"}, {"8 ", 0, setLengthCb, (void*)8,0},
{"16"}, {"16 ", 0, setLengthCb, (void*)16,0},
{"32"}, {"32 ", 0, setLengthCb, (void*)32,0},
{"64"}, {"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}, {0},
//{ "Record" }, //{ "Record" },
{ "Use as tempo" }, { "Use as tempo" },
@ -302,27 +344,6 @@ int ClipSelector::handle(int event)
free(tmp); free(tmp);
gui->selectSaveSample( ID, clipNum ); 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 ) { } else if ( strcmp(m->label(), "Use as tempo") == 0 ) {
EventLooperUseAsTempo e (ID, clipNum); EventLooperUseAsTempo e (ID, clipNum);
writeToDspRingbuffer( &e ); writeToDspRingbuffer( &e );
@ -338,6 +359,8 @@ int ClipSelector::handle(int event)
// for a clip to become 0 // for a clip to become 0
EventGridState e( ID, clipNum, GridLogic::STATE_EMPTY ); EventGridState e( ID, clipNum, GridLogic::STATE_EMPTY );
writeToDspRingbuffer( &e ); writeToDspRingbuffer( &e );
} else {
m->do_callback(this, m->user_data());
} }
} else { } else {
if ( _master ) { if ( _master ) {

View file

@ -104,6 +104,11 @@ public:
int handle(int event); int handle(int event);
void resize(int X, int Y, int W, int H); void resize(int X, int Y, int W, int H);
int findClipNum();
int getLastClipNum();
private:
int clipNum;
}; };
} // Avtk } // Avtk

View file

@ -79,6 +79,7 @@ enum EVENT_TYPE {
GRID_SELECT_CLIP_ENABLE, // enable selecting a clip from the grid GRID_SELECT_CLIP_ENABLE, // enable selecting a clip from the grid
GRID_SELECT_CLIP_EVENT, // a press / release on the selected clip GRID_SELECT_CLIP_EVENT, // a press / release on the selected clip
GRID_SELECT_NEW_CHOSEN, // a different clip is now "special" GRID_SELECT_NEW_CHOSEN, // a different clip is now "special"
EVENT_LOOPER_BARS_TO_RECORD, // choose how many bars to record
/// Track /// Track
TRACK_JACKSEND, TRACK_JACKSEND,
@ -267,6 +268,25 @@ public:
EventGridSelectNewChosen(int t = -1, int s = -1):track(t),scene(s) {} 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 class EventQuit : public EventBase
{ {
public: public:

View file

@ -224,7 +224,6 @@ void handleDspEvents()
break; break;
} }
case Event::LOOPER_LOAD: { case Event::LOOPER_LOAD: {
if ( availableRead >= sizeof(EventLooperLoad) ) { if ( availableRead >= sizeof(EventLooperLoad) ) {
EventLooperLoad ev; EventLooperLoad ev;
@ -266,8 +265,12 @@ void handleDspEvents()
} }
break; 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: { case Event::LOOPER_LOOP_USE_AS_TEMPO: {
if ( availableRead >= sizeof(EventLooperUseAsTempo) ) { if ( availableRead >= sizeof(EventLooperUseAsTempo) ) {
EventLooperUseAsTempo ev; EventLooperUseAsTempo ev;

View file

@ -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) void Logic::looperUseAsTempo(int t, int s)
{ {
size_t clipBeats = jack->getLooper( t )->getClip( s )->getBeats(); size_t clipBeats = jack->getLooper( t )->getClip( s )->getBeats();

View file

@ -62,6 +62,7 @@ public:
void trackJackSend(int t, float vol); void trackJackSend(int t, float vol);
void looperUseAsTempo(int track, int scene); void looperUseAsTempo(int track, int scene);
void looperClipLenght(int track, int scene, int lenght); void looperClipLenght(int track, int scene, int lenght);
void looperBarsToRecord(int track, int scene, int bars);
}; };
#endif // LUPPP_LOGIC_H #endif // LUPPP_LOGIC_H

View file

@ -110,7 +110,7 @@ void Looper::process(unsigned int nframes, Buffers* buffers)
// handle state of clip, and do what needs doing: // handle state of clip, and do what needs doing:
// record into buffer, play from buffer, etc // record into buffer, play from buffer, etc
if ( clips[clip]->recording() ) { 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); clips[clip]->queuePlay(true);
if ( clips[clip]->recordSpaceAvailable() < LOOPER_SAMPLES_BEFORE_REQUEST && if ( clips[clip]->recordSpaceAvailable() < LOOPER_SAMPLES_BEFORE_REQUEST &&

View file

@ -60,8 +60,6 @@ void LooperClip::init()
_playhead = 0; _playhead = 0;
_recordhead = 0; _recordhead = 0;
} }
void LooperClip::save() 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) void LooperClip::record(int count, float* L, float* R)
@ -249,12 +251,8 @@ size_t LooperClip::audioBufferSize()
void LooperClip::setBeats(int beats) void LooperClip::setBeats(int beats)
{ {
if ( _buffer ) { if ( _buffer ) {
if(_buffer->getBeats() == 0)
setWantedBeats( beats );
_buffer->setBeats( beats ); _buffer->setBeats( beats );
} else { }
setWantedBeats( beats );
}
} }
int LooperClip::getBeats() int LooperClip::getBeats()

View file

@ -116,9 +116,9 @@ public:
///reset the play head to zero. Does nothing when recording ///reset the play head to zero. Does nothing when recording
void setPlayHead(float ph); void setPlayHead(float ph);
void setWantedBeats(int beats); void setBarsToRecord(int bars);
int getBeatsToRecord();
int getWantedBeats(); int getBarsToRecord();
#ifdef BUILD_TESTS #ifdef BUILD_TESTS
// used only in test cases // used only in test cases