-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
{
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:

View File

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

View File

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

View File

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

View File

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