mirror of
https://github.com/vale981/openAV-Luppp
synced 2025-03-05 09:01:39 -05:00
-DSP to GUI messaging implemented, looper progress shown in GUI
This commit is contained in:
parent
8da75fc397
commit
238ff21d70
10 changed files with 201 additions and 46 deletions
|
@ -22,6 +22,7 @@ namespace Event
|
||||||
RECORD,
|
RECORD,
|
||||||
|
|
||||||
LOOPER_STATE,
|
LOOPER_STATE,
|
||||||
|
LOOPER_PROGRESS,
|
||||||
LOOPER_LOOP_LENGTH,
|
LOOPER_LOOP_LENGTH,
|
||||||
|
|
||||||
METRONOME_ACTIVE,
|
METRONOME_ACTIVE,
|
||||||
|
@ -66,6 +67,18 @@ class EventLooperState : public EventBase
|
||||||
EventLooperState(int t, Looper::State s) : track(t), state(s){}
|
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
|
class EventLooperLoopLength : public EventBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -6,18 +6,18 @@
|
||||||
#include <jack/ringbuffer.h>
|
#include <jack/ringbuffer.h>
|
||||||
|
|
||||||
extern char* processDspMem;
|
extern char* processDspMem;
|
||||||
extern char* processOscMem;
|
extern char* processGuiMem;
|
||||||
|
|
||||||
extern jack_ringbuffer_t* rbToDsp;
|
extern jack_ringbuffer_t* rbToDsp;
|
||||||
//extern jack_ringbuffer_t* ringbufferDspToGui;
|
extern jack_ringbuffer_t* rbToGui;
|
||||||
|
|
||||||
// to process events in the ringbuffer
|
// to process events in the ringbuffer
|
||||||
extern void handleDspEvents();
|
extern void handleDspEvents();
|
||||||
//extern void handleGuiEvents();
|
extern void handleGuiEvents();
|
||||||
|
|
||||||
// to write events to the ringbuffer
|
// to write events to the ringbuffer
|
||||||
extern void writeToDspRingbuffer(EventBase* e);
|
extern void writeToDspRingbuffer(EventBase* e);
|
||||||
//extern void writeToGuiRingbuffer(EventBase* e);
|
extern void writeToGuiRingbuffer(EventBase* e);
|
||||||
|
|
||||||
#endif // LUPPP_EVENT_HANDLER_H
|
#endif // LUPPP_EVENT_HANDLER_H
|
||||||
|
|
||||||
|
|
112
src/eventhandlergui.cxx
Normal file
112
src/eventhandlergui.cxx
Normal 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
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include <FL/Fl.H>
|
#include <FL/Fl.H>
|
||||||
#include <FL/Fl_Group.H>
|
#include <FL/Fl_Group.H>
|
||||||
#include <FL/Fl_Slider.H>
|
#include <FL/Fl_Slider.H>
|
||||||
|
#include <FL/Fl_Progress.H>
|
||||||
|
|
||||||
#include "avtk/avtk_dial.h"
|
#include "avtk/avtk_dial.h"
|
||||||
#include "avtk/avtk_button.h"
|
#include "avtk/avtk_button.h"
|
||||||
|
@ -70,7 +71,9 @@ class GTrack : public Fl_Group
|
||||||
|
|
||||||
dial1(x+15, y +155, 24, 24, "A"),
|
dial1(x+15, y +155, 24, 24, "A"),
|
||||||
dial2(x+45, y +155, 24, 24, "B"),
|
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++;
|
ID = privateID++;
|
||||||
|
|
||||||
|
@ -81,6 +84,9 @@ class GTrack : public Fl_Group
|
||||||
button5.callback( gtrack_button_callback, &ID );
|
button5.callback( gtrack_button_callback, &ID );
|
||||||
button6.callback( gtrack_button_callback, &ID );
|
button6.callback( gtrack_button_callback, &ID );
|
||||||
|
|
||||||
|
progress.maximum(1.0f);
|
||||||
|
progress.minimum(0.0f);
|
||||||
|
|
||||||
end(); // close the group
|
end(); // close the group
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,8 +95,6 @@ class GTrack : public Fl_Group
|
||||||
free(title);
|
free(title);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private:
|
|
||||||
int ID;
|
int ID;
|
||||||
|
|
||||||
char* title;
|
char* title;
|
||||||
|
@ -104,10 +108,11 @@ class GTrack : public Fl_Group
|
||||||
Avtk::Button button5;
|
Avtk::Button button5;
|
||||||
Avtk::Button button6;
|
Avtk::Button button6;
|
||||||
|
|
||||||
Avtk::Dial dial1;
|
Avtk::Dial dial1;
|
||||||
Avtk::Dial dial2;
|
Avtk::Dial dial2;
|
||||||
Avtk::Dial dial3;
|
Avtk::Dial dial3;
|
||||||
|
|
||||||
|
Fl_Progress progress;
|
||||||
|
|
||||||
static int privateID;
|
static int privateID;
|
||||||
};
|
};
|
||||||
|
|
16
src/gui.cxx
16
src/gui.cxx
|
@ -10,6 +10,14 @@ int GMasterTrack::privateID = 0;
|
||||||
|
|
||||||
using namespace std;
|
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() :
|
Gui::Gui() :
|
||||||
window(1200,280)
|
window(1200,280)
|
||||||
{
|
{
|
||||||
|
@ -37,8 +45,16 @@ Gui::Gui() :
|
||||||
window.end();
|
window.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GTrack* Gui::getTrack(int id)
|
||||||
|
{
|
||||||
|
return tracks.at(id);
|
||||||
|
}
|
||||||
|
|
||||||
int Gui::show()
|
int Gui::show()
|
||||||
{
|
{
|
||||||
window.show();
|
window.show();
|
||||||
|
|
||||||
|
gui_static_read_rb( this);
|
||||||
|
|
||||||
return Fl::run();
|
return Fl::run();
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ class Gui
|
||||||
public:
|
public:
|
||||||
Gui();
|
Gui();
|
||||||
int show();
|
int show();
|
||||||
|
GTrack* getTrack(int id);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Fl_Double_Window window;
|
Fl_Double_Window window;
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
#include "looper.hxx"
|
#include "looper.hxx"
|
||||||
|
|
||||||
#include "jack.hxx"
|
#include "jack.hxx"
|
||||||
|
#include "eventhandler.hxx"
|
||||||
|
|
||||||
extern Jack* jack;
|
extern Jack* jack;
|
||||||
|
|
||||||
void Looper::setState(State s)
|
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];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include "buffers.hxx"
|
#include "buffers.hxx"
|
||||||
|
|
||||||
#include "observer/observer.hxx"
|
#include "observer/observer.hxx"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
@ -92,35 +91,7 @@ class Looper : public Observer // for notifications
|
||||||
|
|
||||||
void setState(State s);
|
void setState(State s);
|
||||||
|
|
||||||
void process(int nframes, Buffers* buffers)
|
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];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int track;
|
int track;
|
||||||
|
|
14
src/main.cxx
14
src/main.cxx
|
@ -14,11 +14,13 @@
|
||||||
|
|
||||||
|
|
||||||
char* processDspMem = 0;
|
char* processDspMem = 0;
|
||||||
char* processOscMem = 0;
|
char* processGuiMem = 0;
|
||||||
|
|
||||||
jack_ringbuffer_t* rbToDsp = 0;
|
jack_ringbuffer_t* rbToDsp = 0;
|
||||||
jack_ringbuffer_t* rbToGui = 0;
|
jack_ringbuffer_t* rbToGui = 0;
|
||||||
|
|
||||||
|
// global static pointers, for access from EventHandlerGui and EventHandlerDsp
|
||||||
|
Gui * gui = 0;
|
||||||
Jack* jack = 0;
|
Jack* jack = 0;
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
|
@ -28,16 +30,16 @@ int main()
|
||||||
|
|
||||||
// allocate data to read from
|
// allocate data to read from
|
||||||
processDspMem = (char*)malloc( sizeof(EventBase) );
|
processDspMem = (char*)malloc( sizeof(EventBase) );
|
||||||
processOscMem = (char*)malloc( sizeof(EventBase) );
|
processGuiMem = (char*)malloc( sizeof(EventBase) );
|
||||||
|
|
||||||
rbToDsp = jack_ringbuffer_create( 2000 * sizeof(EventBase));
|
rbToDsp = jack_ringbuffer_create( 5000 * sizeof(EventBase));
|
||||||
rbToGui = jack_ringbuffer_create( 2000 * sizeof(EventBase));
|
rbToGui = jack_ringbuffer_create( 5000 * sizeof(EventBase));
|
||||||
|
|
||||||
|
|
||||||
jack = new Jack();
|
jack = new Jack();
|
||||||
jack->activate();
|
jack->activate();
|
||||||
|
|
||||||
Gui gui;
|
gui = new Gui();
|
||||||
gui.show();
|
gui->show();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
1
wscript
1
wscript
|
@ -23,6 +23,7 @@ def build(bld):
|
||||||
'src/main.cxx',
|
'src/main.cxx',
|
||||||
'src/jack.cxx',
|
'src/jack.cxx',
|
||||||
'src/looper.cxx',
|
'src/looper.cxx',
|
||||||
|
'src/eventhandlergui.cxx',
|
||||||
'src/eventhandlerdsp.cxx']
|
'src/eventhandlerdsp.cxx']
|
||||||
|
|
||||||
bld.program(source = sources, target='luppp5', use='JACK NTK')
|
bld.program(source = sources, target='luppp5', use='JACK NTK')
|
||||||
|
|
Loading…
Add table
Reference in a new issue