-Updated engine to record / playback loop
parent
40724e3bca
commit
a94ac55fbd
|
@ -0,0 +1,21 @@
|
|||
|
||||
#ifndef LUPPP_BUFFERS_H
|
||||
#define LUPPP_BUFFERS_H
|
||||
|
||||
class Buffers
|
||||
{
|
||||
public:
|
||||
Buffers()
|
||||
{
|
||||
memset( audio, 0, sizeof(float*)*2);
|
||||
}
|
||||
float* audio[2];
|
||||
|
||||
enum BUFFER {
|
||||
MASTER_OUTPUT = 0,
|
||||
MASTER_INPUT,
|
||||
};
|
||||
};
|
||||
|
||||
#endif // LUPPP_BUFFERS_H
|
||||
|
|
@ -11,6 +11,8 @@
|
|||
|
||||
*/
|
||||
|
||||
#include "looper.hxx"
|
||||
|
||||
namespace Event
|
||||
{
|
||||
enum {
|
||||
|
@ -18,6 +20,8 @@ namespace Event
|
|||
PLAY_SAMPLE,
|
||||
MASTER_VOL,
|
||||
RECORD,
|
||||
|
||||
LOOPER_STATE,
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -47,6 +51,17 @@ class EventMasterVol : public EventBase
|
|||
}
|
||||
};
|
||||
|
||||
class EventLooperState : public EventBase
|
||||
{
|
||||
public:
|
||||
int type() { return int(LOOPER_STATE); }
|
||||
uint32_t size() { return sizeof(EventLooperState); }
|
||||
|
||||
Looper::State state;
|
||||
EventLooperState(){}
|
||||
EventLooperState(Looper::State s) : state(s){}
|
||||
};
|
||||
|
||||
class EventLoadSample : public EventBase
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -56,6 +56,12 @@ void handleDspEvents()
|
|||
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventRecord) );
|
||||
//jack->setRecord( ev.track, ev.record );
|
||||
} break; }
|
||||
case Event::LOOPER_STATE: {
|
||||
if ( availableRead >= sizeof(EventLooperState) ) {
|
||||
EventLooperState ev;
|
||||
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventLooperState) );
|
||||
jack->setLooperState( 0, ev.state );
|
||||
} break; }
|
||||
default:
|
||||
{
|
||||
// just do nothing
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
#ifndef LUPPP_G_TRACK_H
|
||||
#define LUPPP_G_TRACK_H
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <FL/Fl.H>
|
||||
#include <FL/Fl_Group.H>
|
||||
#include <FL/Fl_Slider.H>
|
||||
|
@ -10,6 +12,26 @@
|
|||
#include "avtk/avtk_button.h"
|
||||
#include "avtk/avtk_background.h"
|
||||
|
||||
|
||||
#include "eventhandler.hxx"
|
||||
|
||||
using namespace std;
|
||||
|
||||
static void button_callback(Fl_Widget *w, void *data) {
|
||||
cout << "Button " << w->label() << " clicked" << endl;
|
||||
|
||||
if ( strcmp( w->label() , "Rec" ) == 0 )
|
||||
{
|
||||
EventLooperState e = EventLooperState(Looper::STATE_RECORDING);
|
||||
writeToDspRingbuffer( &e );
|
||||
}
|
||||
else if ( strcmp( w->label() , "Play" ) == 0 )
|
||||
{
|
||||
EventLooperState e = EventLooperState(Looper::STATE_PLAYING);
|
||||
writeToDspRingbuffer( &e );
|
||||
}
|
||||
}
|
||||
|
||||
class GTrack : public Fl_Group
|
||||
{
|
||||
public:
|
||||
|
@ -18,8 +40,8 @@ class GTrack : public Fl_Group
|
|||
title( strdup(l) ),
|
||||
bg( x, y , w, h, title ),
|
||||
|
||||
button1(x + 5, y + 24, 18, 18,"1"),
|
||||
button2(x + 5, y + 44, 18, 18,"2"),
|
||||
button1(x + 5, y + 24, 100, 18,"Rec"),
|
||||
button2(x + 5, y + 44, 100, 18,"Play"),
|
||||
button3(x + 5, y + 64, 18, 18,"3"),
|
||||
button4(x + 5, y + 84, 18, 18,"4"),
|
||||
button5(x + 5, y +104, 18, 18,"5"),
|
||||
|
@ -29,6 +51,9 @@ class GTrack : public Fl_Group
|
|||
dial2(x+45, y +155, 24, 24, "B"),
|
||||
dial3(x+75, y +155, 24, 24, "C")
|
||||
{
|
||||
button1.callback( button_callback, 0 );
|
||||
button2.callback( button_callback, 0 );
|
||||
|
||||
end(); // close the group
|
||||
}
|
||||
|
||||
|
|
|
@ -38,6 +38,8 @@ Jack::Jack()
|
|||
{
|
||||
cerr << "Jack() error setting process callback" << endl;
|
||||
}
|
||||
|
||||
loopers.push_back( new Looper() );
|
||||
}
|
||||
|
||||
|
||||
|
@ -59,6 +61,9 @@ int Jack::process (jack_nframes_t nframes)
|
|||
// pre-zero output buffers
|
||||
memset( buffers.audio[Buffers::MASTER_OUTPUT], 0, sizeof(float) * nframes );
|
||||
|
||||
loopers.at(0)->process(nframes, &buffers );
|
||||
|
||||
/*
|
||||
float* input = buffers.audio[Buffers::MASTER_INPUT];
|
||||
float* output = buffers.audio[Buffers::MASTER_OUTPUT];
|
||||
|
||||
|
@ -66,6 +71,7 @@ int Jack::process (jack_nframes_t nframes)
|
|||
{
|
||||
*output++ = *input++;
|
||||
}
|
||||
*/
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
25
src/jack.hxx
25
src/jack.hxx
|
@ -11,24 +11,14 @@
|
|||
*/
|
||||
|
||||
// Library
|
||||
#include <vector>
|
||||
#include <cstring>
|
||||
#include <jack/jack.h>
|
||||
#include <jack/midiport.h>
|
||||
|
||||
class Buffers
|
||||
{
|
||||
public:
|
||||
Buffers()
|
||||
{
|
||||
memset( audio, 0, sizeof(float*)*2);
|
||||
}
|
||||
float* audio[2];
|
||||
|
||||
enum BUFFER {
|
||||
MASTER_OUTPUT = 0,
|
||||
MASTER_INPUT,
|
||||
};
|
||||
};
|
||||
#include "looper.hxx"
|
||||
|
||||
using namespace std;
|
||||
|
||||
class Jack
|
||||
{
|
||||
|
@ -38,10 +28,17 @@ class Jack
|
|||
void activate();
|
||||
int getBuffersize();
|
||||
int getSamplerate();
|
||||
|
||||
void setLooperState(int, Looper::State s)
|
||||
{
|
||||
loopers.at(0)->setState(s);
|
||||
}
|
||||
|
||||
private:
|
||||
Buffers buffers;
|
||||
|
||||
vector<Looper*> loopers;
|
||||
|
||||
int nframes;
|
||||
int samplerate;
|
||||
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
|
||||
#ifndef LUPPP_LOOPER_H
|
||||
#define LUPPP_LOOPER_H
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "buffers.hxx"
|
||||
|
||||
using namespace std;
|
||||
|
||||
class Looper
|
||||
{
|
||||
public:
|
||||
enum State {
|
||||
STATE_PLAYING = 0,
|
||||
STATE_RECORDING,
|
||||
};
|
||||
|
||||
Looper() :
|
||||
state(STATE_PLAYING),
|
||||
endPoint (0),
|
||||
playPoint (0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void setState(State s)
|
||||
{
|
||||
// quantize?!
|
||||
state = s;
|
||||
|
||||
if ( state == STATE_PLAYING ) // setup PLAY
|
||||
{
|
||||
endPoint = lastWrittenSampleIndex;
|
||||
playPoint = 0;
|
||||
cout << "State = PLAYING, endPoint = " << endPoint << endl;
|
||||
}
|
||||
else if ( state == STATE_RECORDING ) // setup REC
|
||||
{
|
||||
cout << "State = RECORDING" << endl;
|
||||
playPoint = 0;
|
||||
endPoint = 0;
|
||||
lastWrittenSampleIndex = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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 )
|
||||
{
|
||||
playPoint = 0;
|
||||
}
|
||||
out[i] += sample[playPoint++];
|
||||
}
|
||||
}
|
||||
|
||||
else if ( state == STATE_RECORDING )
|
||||
{
|
||||
for(int i = 0; i < nframes; i++)
|
||||
{
|
||||
if ( lastWrittenSampleIndex < 44100 * 60 )
|
||||
{
|
||||
sample[lastWrittenSampleIndex++] = in[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
State state;
|
||||
|
||||
int endPoint, playPoint, lastWrittenSampleIndex;
|
||||
float sample[44100*60];
|
||||
|
||||
};
|
||||
|
||||
#endif // LUPPP_LOOPER_H
|
Loading…
Reference in New Issue