-Working on sample loading, most of infrastructure in place, need to send event

main
Harry van Haaren 2013-05-19 23:57:12 +01:00
parent 1120f3782b
commit 8eec3e1426
11 changed files with 159 additions and 21 deletions

54
src/audiobuffer.hxx Normal file
View File

@ -0,0 +1,54 @@
#ifndef LUPPP_AUDIOBUFFER_H
#define LUPPP_AUDIOBUFFER_H
// System
#include <vector>
// AudioBuffer stores float samples in a big vector. The vector can be
// accessed only by const reference, so its state is immutable
class AudioBuffer
{
public:
AudioBuffer()
{
ID = privateID++;
}
~AudioBuffer();
int getID()
{
return ID;
}
int getBeats()
{
return numBeats;
}
void setBeats(int b)
{
numBeats = b;
}
std::vector<float>& get()
{
return buffer;
}
void nonRtSetSample(std::vector<float>& sample)
{
buffer.swap(sample);
}
protected:
static int privateID;
int ID;
int numBeats;
std::vector<float> buffer;
};
#endif

View File

@ -21,6 +21,7 @@ namespace Event
MASTER_VOL,
RECORD,
LOOPER_LOAD,
LOOPER_STATE,
LOOPER_PROGRESS,
LOOPER_LOOP_LENGTH,
@ -96,18 +97,18 @@ class EventLooperLoopLength : public EventBase
EventLooperLoopLength(int t, float s) : track(t), scale(s){}
};
class EventLoadSample : public EventBase
class EventLooperLoad : public EventBase
{
public:
int type() { return int(LOAD_SAMPLE); }
uint32_t size() { return sizeof(EventLoadSample); }
uint32_t size() { return sizeof(EventLooperLoad); }
AudioBuffer* audioBufferPtr;
int track;
int clip;
AudioBuffer* audioBuffer;
EventLoadSample(AudioBuffer* a)
{
audioBufferPtr = a;
}
EventLooperLoad(){}
EventLooperLoad(int t, int c, AudioBuffer* ab) : track(t), clip(c), audioBuffer(ab) {}
};
class EventPlaySample : public EventBase

View File

@ -38,11 +38,12 @@ void handleDspEvents()
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventMasterVol) );
//jack->masterVolume = ev.vol;
} break; }
case Event::LOAD_SAMPLE: {
if ( availableRead >= sizeof(EventLoadSample) ) {
EventLoadSample ev(0);
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventLoadSample) );
//jack->addAudioBuffer( ev.audioBufferPtr );
case Event::LOOPER_LOAD: {
if ( availableRead >= sizeof(EventLooperLoad) ) {
EventLooperLoad ev;
jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventLooperLoad) );
Looper* l = jack->getLooper( ev.track );
} break; }
case Event::PLAY_SAMPLE: {
if ( availableRead >= sizeof(EventPlaySample) ) {

View File

@ -40,12 +40,6 @@ void handleGuiEvents()
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);

View File

@ -8,16 +8,41 @@
#include <FL/Fl_Group.H>
#include <FL/Fl_Slider.H>
#include <FL/Fl_Progress.H>
#include <FL/Fl_Native_File_Chooser.H>
#include "avtk/avtk_dial.h"
#include "avtk/avtk_button.h"
#include "avtk/avtk_background.h"
#include "worker.hxx"
#include "audiobuffer.hxx"
#include "eventhandler.hxx"
using namespace std;
static string choose_file()
{
string path;
Fl_Native_File_Chooser fnfc;
fnfc.title("Pick a file");
fnfc.type(Fl_Native_File_Chooser::BROWSE_FILE);
//fnfc.filter("Wav\t*.wav");
fnfc.directory( getenv("HOME") ); // default directory to use
// Show native chooser
switch ( fnfc.show() ) {
case -1: printf("ERROR: %s\n", fnfc.errmsg()); break; // ERROR
case 1: printf("CANCEL\n"); break; // CANCEL
default: printf("Loading directory: %s\n", fnfc.filename());
// update path and load it
path = fnfc.filename();
break; // FILE CHOSEN
}
return path;
}
static void gtrack_button_callback(Fl_Widget *w, void *data) {
int track = 0;
if ( data )
@ -49,6 +74,13 @@ static void gtrack_button_callback(Fl_Widget *w, void *data) {
EventLooperLoopLength e = EventLooperLoopLength(track, 0.5);
writeToDspRingbuffer( &e );
}
else if ( strcmp( w->label() , "Load" ) == 0 )
{
AudioBuffer* ab = Worker::loadSample( choose_file() );
EventLooperLoad e = EventLooperLoad( track, 0 , ab );
writeToDspRingbuffer( &e );
}
else if ( strcmp( w->label() , "Vol" ) == 0 )
{
@ -73,7 +105,7 @@ class GTrack : public Fl_Group
button4(x + 5, y + 84, 48, 18,"-"),
button5(x +57, y + 84, 48, 18,"+"),
button6(x + 5, y +104, 18, 18,"6"),
button6(x + 5, y +104, 100, 18,"Load"),
volume(x+55-22, y +175, 34, 34, "Vol"),

View File

@ -4,9 +4,12 @@
#include <sstream>
#include "audiobuffer.hxx"
// Hack, move to gtrack.cpp
int GTrack::privateID = 0;
int GMasterTrack::privateID = 0;
int AudioBuffer::privateID = 0;
using namespace std;

View File

@ -43,6 +43,10 @@ class Jack
{
loopers.at(t)->setLoopLength(l);
}
Looper* getLooper(int t)
{
return loopers.at(t);
}
Metronome* getMetronome(){return &metronome;}
TimeManager* getTimeManager(){return &timeManager;}

View File

@ -122,6 +122,17 @@ void Looper::updateControllers()
}
}
void Looper::setSample(int c, int nB, int bS, float* bP)
{
if ( bS > SAMPLE_SIZE )
{
EventGuiPrint e( "Looper setSample() size > incoming sample" );
writeToGuiRingbuffer( &e );
}
numBeats = nB;
memcpy( &sample[0], bP, bS ); // copy sample data to pre-allocated buffer
}
void Looper::process(int nframes, Buffers* buffers)
{
float* in = buffers->audio[Buffers::MASTER_INPUT];

View File

@ -26,6 +26,8 @@ class Looper : public Observer // for notifications
Looper(int t);
void setSample(int c, int nB, int bS, float* bP);
void midi(unsigned char* data);
void bar();

36
src/worker.hxx Normal file
View File

@ -0,0 +1,36 @@
#ifndef LUPPP_WORKER_H
#define LUPPP_WORKER_H
// Library
#include <string>
#include <sndfile.hh>
#include "audiobuffer.hxx"
using namespace std;
namespace Worker
{
static AudioBuffer* loadSample( string path )
{
SndfileHandle infile( path, SFM_READ );
AudioBuffer* ab = new AudioBuffer();
std::vector<float> buf( infile.frames(), 0.f );
infile.read( &buf[0] , infile.frames() );
// read data from file
ab->setBeats(4);
ab->nonRtSetSample( buf );
cout << "Worker: loadSample() " << path << " size: " << infile.frames() << endl;
return ab;
}
}
#endif // LUPPP_WORKER_H

View File

@ -15,7 +15,7 @@ def configure(conf):
conf.check_cfg(package='ntk',at_least_version='1.3',args='--cflags --libs',uselib_store='NTK')
conf.check_cfg(package='jack',at_least_version='0.118',args='--cflags --libs',uselib_store='JACK')
#conf.check_cfg(package='lilv-0',at_least_version='1.0',args='--cflags --libs',uselib_store='LILV')
#conf.check_cfg(package='sndfile',at_least_version='1.0',args='--cflags --libs',uselib_store='SNDFILE')
conf.check_cfg(package='sndfile',at_least_version='1.0',args='--cflags --libs',uselib_store='SNDFILE')
def build(bld):
@ -27,5 +27,5 @@ def build(bld):
'src/eventhandlergui.cxx',
'src/eventhandlerdsp.cxx']
bld.program(source = sources, target='luppp5', use='JACK NTK')
bld.program(source = sources, target='luppp5', use='JACK NTK SNDFILE')