mirror of
https://github.com/vale981/openAV-Luppp
synced 2025-03-04 16:51:37 -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,
|
||||
|
||||
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:
|
||||
|
|
|
@ -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
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_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;
|
||||
};
|
||||
|
|
16
src/gui.cxx
16
src/gui.cxx
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ class Gui
|
|||
public:
|
||||
Gui();
|
||||
int show();
|
||||
GTrack* getTrack(int id);
|
||||
|
||||
private:
|
||||
Fl_Double_Window window;
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
14
src/main.cxx
14
src/main.cxx
|
@ -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();
|
||||
|
||||
}
|
||||
|
|
1
wscript
1
wscript
|
@ -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')
|
||||
|
|
Loading…
Add table
Reference in a new issue