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,
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 ) {

View file

@ -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

View file

@ -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:

View file

@ -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;

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)
{
size_t clipBeats = jack->getLooper( t )->getClip( s )->getBeats();

View file

@ -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

View file

@ -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 &&

View file

@ -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()

View file

@ -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