-Working on sample loading, most of infrastructure in place, need to send event
This commit is contained in:
parent
1120f3782b
commit
8eec3e1426
11 changed files with 159 additions and 21 deletions
54
src/audiobuffer.hxx
Normal file
54
src/audiobuffer.hxx
Normal 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
|
||||
|
|
@ -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
|
||||
|
|
|
@ -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) ) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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"),
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;}
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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
36
src/worker.hxx
Normal 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
|
4
wscript
4
wscript
|
@ -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')
|
||||
|
||||
|
|
Loading…
Reference in a new issue