-DSP to GUI messaging implemented, looper progress shown in GUI

This commit is contained in:
Harry van Haaren 2013-05-16 13:38:46 +01:00
parent 8da75fc397
commit 238ff21d70
10 changed files with 201 additions and 46 deletions

View file

@ -22,6 +22,7 @@ namespace Event
RECORD,
LOOPER_STATE,
LOOPER_PROGRESS,
LOOPER_LOOP_LENGTH,
METRONOME_ACTIVE,
@ -66,6 +67,18 @@ class EventLooperState : public EventBase
EventLooperState(int t, Looper::State s) : track(t), state(s){}
};
class EventLooperProgress : public EventBase
{
public:
int type() { return int(LOOPER_PROGRESS); }
uint32_t size() { return sizeof(EventLooperProgress); }
int track;
float progress;
EventLooperProgress(){}
EventLooperProgress(int t, float p) : track(t), progress(p) {}
};
class EventLooperLoopLength : public EventBase
{
public:

View file

@ -6,18 +6,18 @@
#include <jack/ringbuffer.h>
extern char* processDspMem;
extern char* processOscMem;
extern char* processGuiMem;
extern jack_ringbuffer_t* rbToDsp;
//extern jack_ringbuffer_t* ringbufferDspToGui;
extern jack_ringbuffer_t* rbToGui;
// to process events in the ringbuffer
extern void handleDspEvents();
//extern void handleGuiEvents();
extern void handleGuiEvents();
// to write events to the ringbuffer
extern void writeToDspRingbuffer(EventBase* e);
//extern void writeToGuiRingbuffer(EventBase* e);
extern void writeToGuiRingbuffer(EventBase* e);
#endif // LUPPP_EVENT_HANDLER_H

112
src/eventhandlergui.cxx Normal file
View file

@ -0,0 +1,112 @@
#ifndef LUPPP_EVENT_HANDLER_DSP_H
#define LUPPP_EVENT_HANDLER_DSP_H
// Library
#include <cstring>
#include <iostream>
#include <jack/ringbuffer.h>
// Internal
#include "gui.hxx"
#include "event.hxx"
#include "eventhandler.hxx"
extern Gui* gui;
using namespace std;
void handleGuiEvents()
{
uint availableRead = jack_ringbuffer_read_space( rbToGui );
while ( availableRead >= sizeof(EventBase) )
{
jack_ringbuffer_peek( rbToGui, (char*)processGuiMem, sizeof(EventBase) );
EventBase* e = (EventBase*)processGuiMem;
// recheck the size against the actual event size
if ( availableRead >= e->size() )
{
//cout << "reading event type " << e->type() << endl;
switch ( e->type() )
{
case Event::MASTER_VOL: {
if ( availableRead >= sizeof(EventMasterVol) ) {
EventMasterVol ev(0);
jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventMasterVol) );
//jack->masterVolume = ev.vol;
} break; }
case Event::LOAD_SAMPLE: {
if ( availableRead >= sizeof(EventLoadSample) ) {
EventLoadSample ev(0);
jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventLoadSample) );
//jack->addAudioBuffer( ev.audioBufferPtr );
} break; }
case Event::PLAY_SAMPLE: {
if ( availableRead >= sizeof(EventPlaySample) ) {
EventPlaySample ev(0,0);
jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventPlaySample) );
//jack->setPlayBuffer( ev.track, ev.bufferID );
} break; }
case Event::METRONOME_ACTIVE: {
if ( availableRead >= sizeof(EventMetronomeActive) ) {
EventMetronomeActive ev(false);
jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventMetronomeActive) );
//jack->getMetronome()->setActive(ev.active);
} break; }
case Event::LOOPER_STATE: {
if ( availableRead >= sizeof(EventLooperState) ) {
EventLooperState ev;
jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventLooperState) );
//jack->setLooperState( ev.track, ev.state );
} break; }
case Event::LOOPER_LOOP_LENGTH: {
if ( availableRead >= sizeof(EventLooperLoopLength) ) {
EventLooperLoopLength ev;
jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventLooperLoopLength) );
//jack->setLooperLoopLength( ev.track, ev.scale );
} break; }
case Event::LOOPER_PROGRESS: {
if ( availableRead >= sizeof(EventLooperProgress) ) {
EventLooperProgress ev;
jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventLooperProgress) );
gui->getTrack(ev.track)->progress.value(ev.progress);
//jack->setLooperLoopLength( ev.track, ev.scale );
} break; }
default:
{
cout << "Unkown message!! Will clog ringbuffer" << endl;
// just do nothing
break;
}
}
}
else
{
// next call will get the half-written event
return;
}
// update available read, and loop over events
availableRead = jack_ringbuffer_read_space( rbToGui );
}
}
void writeToGuiRingbuffer(EventBase* e)
{
if ( jack_ringbuffer_write_space(rbToGui) >= e->size() )
{
jack_ringbuffer_write( rbToGui, (const char*)e, e->size() );
}
else
{
cout << "->GUI ringbuffer full!" << endl;
}
}
#endif // LUPPP_EVENT_HANDLER_DSP_H

View file

@ -7,6 +7,7 @@
#include <FL/Fl.H>
#include <FL/Fl_Group.H>
#include <FL/Fl_Slider.H>
#include <FL/Fl_Progress.H>
#include "avtk/avtk_dial.h"
#include "avtk/avtk_button.h"
@ -70,7 +71,9 @@ class GTrack : public Fl_Group
dial1(x+15, y +155, 24, 24, "A"),
dial2(x+45, y +155, 24, 24, "B"),
dial3(x+75, y +155, 24, 24, "C")
dial3(x+75, y +155, 24, 24, "C"),
progress(x, y, 100, 20, "prog")
{
ID = privateID++;
@ -81,6 +84,9 @@ class GTrack : public Fl_Group
button5.callback( gtrack_button_callback, &ID );
button6.callback( gtrack_button_callback, &ID );
progress.maximum(1.0f);
progress.minimum(0.0f);
end(); // close the group
}
@ -89,8 +95,6 @@ class GTrack : public Fl_Group
free(title);
}
private:
int ID;
char* title;
@ -104,10 +108,11 @@ class GTrack : public Fl_Group
Avtk::Button button5;
Avtk::Button button6;
Avtk::Dial dial1;
Avtk::Dial dial2;
Avtk::Dial dial3;
Avtk::Dial dial1;
Avtk::Dial dial2;
Avtk::Dial dial3;
Fl_Progress progress;
static int privateID;
};

View file

@ -10,6 +10,14 @@ int GMasterTrack::privateID = 0;
using namespace std;
static void gui_static_read_rb(void* inst)
{
//cout << "read gui" << endl;
handleGuiEvents();
Fl::repeat_timeout( 1 / 30.f, &gui_static_read_rb, inst);
}
Gui::Gui() :
window(1200,280)
{
@ -37,8 +45,16 @@ Gui::Gui() :
window.end();
}
GTrack* Gui::getTrack(int id)
{
return tracks.at(id);
}
int Gui::show()
{
window.show();
gui_static_read_rb( this);
return Fl::run();
}

View file

@ -21,6 +21,7 @@ class Gui
public:
Gui();
int show();
GTrack* getTrack(int id);
private:
Fl_Double_Window window;

View file

@ -3,6 +3,8 @@
#include "looper.hxx"
#include "jack.hxx"
#include "eventhandler.hxx"
extern Jack* jack;
void Looper::setState(State s)
@ -15,3 +17,35 @@ void Looper::setState(State s)
}
}
void Looper::process(int nframes, Buffers* buffers)
{
float* in = buffers->audio[Buffers::MASTER_INPUT];
float* out = buffers->audio[Buffers::MASTER_OUTPUT];
if ( state == STATE_PLAYING )
{
for(int i = 0; i < nframes; i++)
{
if ( playPoint < endPoint )
{
out[i] += sample[playPoint++];
}
}
// update UI
EventLooperProgress e(track, float(playPoint) / endPoint );
writeToGuiRingbuffer( &e );
}
else if ( state == STATE_RECORDING )
{
cout << "recording " << endl;
for(int i = 0; i < nframes; i++)
{
if ( lastWrittenSampleIndex < 44100 * 60 )
{
sample[lastWrittenSampleIndex++] = in[i];
}
}
}
}

View file

@ -5,7 +5,6 @@
#include <iostream>
#include "buffers.hxx"
#include "observer/observer.hxx"
using namespace std;
@ -92,35 +91,7 @@ class Looper : public Observer // for notifications
void setState(State s);
void process(int nframes, Buffers* buffers)
{
float* in = buffers->audio[Buffers::MASTER_INPUT];
float* out = buffers->audio[Buffers::MASTER_OUTPUT];
if ( state == STATE_PLAYING )
{
for(int i = 0; i < nframes; i++)
{
if ( playPoint < endPoint )
{
out[i] += sample[playPoint++];
}
}
}
else if ( state == STATE_RECORDING )
{
cout << "recording " << endl;
for(int i = 0; i < nframes; i++)
{
if ( lastWrittenSampleIndex < 44100 * 60 )
{
sample[lastWrittenSampleIndex++] = in[i];
}
}
}
}
void process(int nframes, Buffers* buffers);
private:
int track;

View file

@ -14,11 +14,13 @@
char* processDspMem = 0;
char* processOscMem = 0;
char* processGuiMem = 0;
jack_ringbuffer_t* rbToDsp = 0;
jack_ringbuffer_t* rbToGui = 0;
// global static pointers, for access from EventHandlerGui and EventHandlerDsp
Gui * gui = 0;
Jack* jack = 0;
int main()
@ -28,16 +30,16 @@ int main()
// allocate data to read from
processDspMem = (char*)malloc( sizeof(EventBase) );
processOscMem = (char*)malloc( sizeof(EventBase) );
processGuiMem = (char*)malloc( sizeof(EventBase) );
rbToDsp = jack_ringbuffer_create( 2000 * sizeof(EventBase));
rbToGui = jack_ringbuffer_create( 2000 * sizeof(EventBase));
rbToDsp = jack_ringbuffer_create( 5000 * sizeof(EventBase));
rbToGui = jack_ringbuffer_create( 5000 * sizeof(EventBase));
jack = new Jack();
jack->activate();
Gui gui;
gui.show();
gui = new Gui();
gui->show();
}

View file

@ -23,6 +23,7 @@ def build(bld):
'src/main.cxx',
'src/jack.cxx',
'src/looper.cxx',
'src/eventhandlergui.cxx',
'src/eventhandlerdsp.cxx']
bld.program(source = sources, target='luppp5', use='JACK NTK')