-Updated engine to record / playback loop

main
Harry van Haaren 2013-05-13 22:04:12 +01:00
parent 40724e3bca
commit a94ac55fbd
9 changed files with 176 additions and 16 deletions

5
debug.sh Executable file
View File

@ -0,0 +1,5 @@
#!/bin/bash
cd .build/
gdb ./luppp5

21
src/buffers.hxx Normal file
View File

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

View File

@ -11,6 +11,8 @@
*/ */
#include "looper.hxx"
namespace Event namespace Event
{ {
enum { enum {
@ -18,6 +20,8 @@ namespace Event
PLAY_SAMPLE, PLAY_SAMPLE,
MASTER_VOL, MASTER_VOL,
RECORD, 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 class EventLoadSample : public EventBase
{ {
public: public:

View File

@ -56,6 +56,12 @@ void handleDspEvents()
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventRecord) ); jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventRecord) );
//jack->setRecord( ev.track, ev.record ); //jack->setRecord( ev.track, ev.record );
} break; } } 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: default:
{ {
// just do nothing // just do nothing

View File

@ -2,6 +2,8 @@
#ifndef LUPPP_G_TRACK_H #ifndef LUPPP_G_TRACK_H
#define LUPPP_G_TRACK_H #define LUPPP_G_TRACK_H
#include <iostream>
#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>
@ -10,6 +12,26 @@
#include "avtk/avtk_button.h" #include "avtk/avtk_button.h"
#include "avtk/avtk_background.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 class GTrack : public Fl_Group
{ {
public: public:
@ -18,8 +40,8 @@ class GTrack : public Fl_Group
title( strdup(l) ), title( strdup(l) ),
bg( x, y , w, h, title ), bg( x, y , w, h, title ),
button1(x + 5, y + 24, 18, 18,"1"), button1(x + 5, y + 24, 100, 18,"Rec"),
button2(x + 5, y + 44, 18, 18,"2"), button2(x + 5, y + 44, 100, 18,"Play"),
button3(x + 5, y + 64, 18, 18,"3"), button3(x + 5, y + 64, 18, 18,"3"),
button4(x + 5, y + 84, 18, 18,"4"), button4(x + 5, y + 84, 18, 18,"4"),
button5(x + 5, y +104, 18, 18,"5"), 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"), dial2(x+45, y +155, 24, 24, "B"),
dial3(x+75, y +155, 24, 24, "C") dial3(x+75, y +155, 24, 24, "C")
{ {
button1.callback( button_callback, 0 );
button2.callback( button_callback, 0 );
end(); // close the group end(); // close the group
} }

View File

@ -38,6 +38,8 @@ Jack::Jack()
{ {
cerr << "Jack() error setting process callback" << endl; 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 // pre-zero output buffers
memset( buffers.audio[Buffers::MASTER_OUTPUT], 0, sizeof(float) * nframes ); memset( buffers.audio[Buffers::MASTER_OUTPUT], 0, sizeof(float) * nframes );
loopers.at(0)->process(nframes, &buffers );
/*
float* input = buffers.audio[Buffers::MASTER_INPUT]; float* input = buffers.audio[Buffers::MASTER_INPUT];
float* output = buffers.audio[Buffers::MASTER_OUTPUT]; float* output = buffers.audio[Buffers::MASTER_OUTPUT];
@ -66,6 +71,7 @@ int Jack::process (jack_nframes_t nframes)
{ {
*output++ = *input++; *output++ = *input++;
} }
*/
return false; return false;
} }

View File

@ -11,24 +11,14 @@
*/ */
// Library // Library
#include <vector>
#include <cstring> #include <cstring>
#include <jack/jack.h> #include <jack/jack.h>
#include <jack/midiport.h> #include <jack/midiport.h>
class Buffers #include "looper.hxx"
{
public: using namespace std;
Buffers()
{
memset( audio, 0, sizeof(float*)*2);
}
float* audio[2];
enum BUFFER {
MASTER_OUTPUT = 0,
MASTER_INPUT,
};
};
class Jack class Jack
{ {
@ -38,10 +28,17 @@ class Jack
void activate(); void activate();
int getBuffersize(); int getBuffersize();
int getSamplerate(); int getSamplerate();
void setLooperState(int, Looper::State s)
{
loopers.at(0)->setState(s);
}
private: private:
Buffers buffers; Buffers buffers;
vector<Looper*> loopers;
int nframes; int nframes;
int samplerate; int samplerate;

0
src/looper.cxx Normal file
View File

85
src/looper.hxx Normal file
View File

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