mirror of
https://github.com/vale981/openAV-Luppp
synced 2025-03-05 17:11:40 -05:00
-Refactoring Looper into LooperClip
This commit is contained in:
parent
d3cbd3c516
commit
3f60cb52a6
9 changed files with 90 additions and 70 deletions
|
@ -27,7 +27,6 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "../looper.hxx"
|
|
||||||
#include "../gclipselectoraction.hxx"
|
#include "../gclipselectoraction.hxx"
|
||||||
|
|
||||||
#include "../worker.hxx"
|
#include "../worker.hxx"
|
||||||
|
@ -126,8 +125,9 @@ class ClipSelector : public Fl_Button
|
||||||
/** converts the Looper::State into the UI represnted ClipSelector state.
|
/** converts the Looper::State into the UI represnted ClipSelector state.
|
||||||
* It puts some of the data into clips[], and stores unique state into the class.
|
* It puts some of the data into clips[], and stores unique state into the class.
|
||||||
**/
|
**/
|
||||||
void setState( int clipNum, Looper::State s )
|
void setState( int clipNum, int )
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
switch(s)
|
switch(s)
|
||||||
{
|
{
|
||||||
case Looper::STATE_PLAYING:
|
case Looper::STATE_PLAYING:
|
||||||
|
@ -162,6 +162,7 @@ class ClipSelector : public Fl_Button
|
||||||
printf("clipSelector setState() clip %i = CLIP_QUEUED\n", clipNum);
|
printf("clipSelector setState() clip %i = CLIP_QUEUED\n", clipNum);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
redraw();
|
redraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -353,13 +354,16 @@ class ClipSelector : public Fl_Button
|
||||||
}
|
}
|
||||||
else if ( strcmp(m->label(), "Record") == 0 )
|
else if ( strcmp(m->label(), "Record") == 0 )
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
//recordingClip = clipNum;
|
//recordingClip = clipNum;
|
||||||
EventLooperState e = EventLooperState( ID, clipNum, Looper::STATE_RECORD_QUEUED);
|
EventLooperState e = EventLooperState( ID, clipNum, Looper::STATE_RECORD_QUEUED);
|
||||||
writeToDspRingbuffer( &e );
|
writeToDspRingbuffer( &e );
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
// decide action to take based on current state of clip
|
// decide action to take based on current state of clip
|
||||||
if ( clips[clipNum].queued() )
|
if ( clips[clipNum].queued() )
|
||||||
{
|
{
|
||||||
|
@ -384,7 +388,7 @@ class ClipSelector : public Fl_Button
|
||||||
{
|
{
|
||||||
playingClip = -1;
|
playingClip = -1;
|
||||||
}
|
}
|
||||||
*/
|
*
|
||||||
else if ( clips[clipNum].loaded() )
|
else if ( clips[clipNum].loaded() )
|
||||||
{
|
{
|
||||||
EventLooperState e = EventLooperState( ID, clipNum, Looper::STATE_PLAY_QUEUED);
|
EventLooperState e = EventLooperState( ID, clipNum, Looper::STATE_PLAY_QUEUED);
|
||||||
|
@ -400,6 +404,7 @@ class ClipSelector : public Fl_Button
|
||||||
{
|
{
|
||||||
printf("avtk clipSelector handle click: no state triggered");
|
printf("avtk clipSelector handle click: no state triggered");
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
switch( clips[clipNum].state )
|
switch( clips[clipNum].state )
|
||||||
|
|
|
@ -4,5 +4,7 @@
|
||||||
|
|
||||||
#define NTRACKS 8
|
#define NTRACKS 8
|
||||||
|
|
||||||
|
#define MAX_BUFFER_SIZE 1024
|
||||||
|
|
||||||
#endif // LUPPP_CONFIG_H
|
#endif // LUPPP_CONFIG_H
|
||||||
|
|
||||||
|
|
|
@ -111,9 +111,10 @@ class EventLooperState : public EventBase
|
||||||
|
|
||||||
int track;
|
int track;
|
||||||
int scene;
|
int scene;
|
||||||
Looper::State state;
|
//Looper::State state;
|
||||||
|
|
||||||
EventLooperState(){}
|
EventLooperState(){}
|
||||||
EventLooperState(int t, int sc, Looper::State s) : track(t), scene(sc), state(s){}
|
//EventLooperState(int t, int sc, Looper::State s) : track(t), scene(sc), state(s){}
|
||||||
};
|
};
|
||||||
|
|
||||||
class EventLooperProgress : public EventBase
|
class EventLooperProgress : public EventBase
|
||||||
|
|
|
@ -55,7 +55,7 @@ void handleDspEvents()
|
||||||
if ( availableRead >= sizeof(EventLooperState) ) {
|
if ( availableRead >= sizeof(EventLooperState) ) {
|
||||||
EventLooperState ev;
|
EventLooperState ev;
|
||||||
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventLooperState) );
|
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventLooperState) );
|
||||||
jack->setLooperState( ev.track, ev.scene, ev.state );
|
//jack->setLooperState( ev.track, ev.scene, ev.state );
|
||||||
} break; }
|
} break; }
|
||||||
case Event::LOOPER_LOOP_LENGTH: {
|
case Event::LOOPER_LOOP_LENGTH: {
|
||||||
if ( availableRead >= sizeof(EventLooperLoopLength) ) {
|
if ( availableRead >= sizeof(EventLooperLoopLength) ) {
|
||||||
|
|
|
@ -50,13 +50,13 @@ void handleGuiEvents()
|
||||||
if ( availableRead >= sizeof(EventLooperState) ) {
|
if ( availableRead >= sizeof(EventLooperState) ) {
|
||||||
EventLooperState ev;
|
EventLooperState ev;
|
||||||
jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventLooperState) );
|
jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventLooperState) );
|
||||||
gui->getTrack(ev.track)->getClipSelector()->setState(ev.scene, ev.state);
|
//gui->getTrack(ev.track)->getClipSelector()->setState(ev.scene, ev.state);
|
||||||
//jack->setLooperState( ev.track, ev.state );
|
//jack->setLooperState( ev.track, ev.state );
|
||||||
} break; }
|
} break; }
|
||||||
case Event::LOOPER_LOOP_LENGTH: {
|
case Event::LOOPER_LOOP_LENGTH: {
|
||||||
if ( availableRead >= sizeof(EventLooperLoopLength) ) {
|
if ( availableRead >= sizeof(EventLooperLoopLength) ) {
|
||||||
EventLooperLoopLength ev;
|
//EventLooperLoopLength ev;
|
||||||
jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventLooperLoopLength) );
|
//jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventLooperLoopLength) );
|
||||||
//jack->setLooperLoopLength( ev.track, ev.scale );
|
//jack->setLooperLoopLength( ev.track, ev.scale );
|
||||||
} break; }
|
} break; }
|
||||||
case Event::LOOPER_PROGRESS: {
|
case Event::LOOPER_PROGRESS: {
|
||||||
|
|
|
@ -9,6 +9,7 @@ extern void luppp_tooltip(std::string s);
|
||||||
|
|
||||||
void gtrack_button_callback(Fl_Widget *w, void *data)
|
void gtrack_button_callback(Fl_Widget *w, void *data)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
int track = 0;
|
int track = 0;
|
||||||
if ( data )
|
if ( data )
|
||||||
track = *(int*)data;
|
track = *(int*)data;
|
||||||
|
@ -59,4 +60,5 @@ void gtrack_button_callback(Fl_Widget *w, void *data)
|
||||||
{
|
{
|
||||||
cout << __FILE__ << __LINE__ << " Error: unknown command string" << endl;
|
cout << __FILE__ << __LINE__ << " Error: unknown command string" << endl;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,14 +39,16 @@ class Jack
|
||||||
int getBuffersize();
|
int getBuffersize();
|
||||||
int getSamplerate();
|
int getSamplerate();
|
||||||
|
|
||||||
|
/*
|
||||||
void setLooperState(int t, int sc, Looper::State s)
|
void setLooperState(int t, int sc, Looper::State s)
|
||||||
{
|
{
|
||||||
loopers.at(t)->setState(s);
|
loopers.at(t)->setState(s);
|
||||||
loopers.at(t)->setScene(sc);
|
loopers.at(t)->setScene(sc);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
void setLooperLoopLength(int t, float l)
|
void setLooperLoopLength(int t, float l)
|
||||||
{
|
{
|
||||||
loopers.at(t)->setLoopLength(l);
|
//loopers.at(t)->setLoopLength(l);
|
||||||
}
|
}
|
||||||
Looper* getLooper(int t)
|
Looper* getLooper(int t)
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
#include "looper.hxx"
|
#include "looper.hxx"
|
||||||
|
|
||||||
|
#include "config.hxx"
|
||||||
|
|
||||||
#include "jack.hxx"
|
#include "jack.hxx"
|
||||||
#include "audiobuffer.hxx"
|
#include "audiobuffer.hxx"
|
||||||
#include "eventhandler.hxx"
|
#include "eventhandler.hxx"
|
||||||
|
@ -11,7 +13,6 @@ extern Jack* jack;
|
||||||
|
|
||||||
Looper::Looper(int t) :
|
Looper::Looper(int t) :
|
||||||
track(t),
|
track(t),
|
||||||
state(STATE_STOPPED),
|
|
||||||
scene(0),
|
scene(0),
|
||||||
fpb(120),
|
fpb(120),
|
||||||
gain(1.f),
|
gain(1.f),
|
||||||
|
@ -25,36 +26,29 @@ Looper::Looper(int t) :
|
||||||
uiUpdateCounter(44100/30)
|
uiUpdateCounter(44100/30)
|
||||||
{
|
{
|
||||||
// pre-zero the internal sample
|
// pre-zero the internal sample
|
||||||
for(int i = 0; i < 10; i++)
|
tmpRecordBuffer = (float*)malloc( sizeof(float) * MAX_BUFFER_SIZE );
|
||||||
{
|
memset( tmpRecordBuffer, 0, sizeof(float) * MAX_BUFFER_SIZE );
|
||||||
//memset( sample[int(i)][0], 0, SAMPLE_SIZE );
|
|
||||||
}
|
|
||||||
sample = &samples[0][0];
|
|
||||||
|
|
||||||
printf("Looper ID %i\n" , track );
|
printf("Looper ID %i\n" , track );
|
||||||
|
|
||||||
|
|
||||||
// init faust pitch shift variables
|
// init faust pitch shift variables
|
||||||
fSamplingFreq = 44100;
|
fSamplingFreq = 44100;
|
||||||
IOTA = 0;
|
IOTA = 0;
|
||||||
|
for ( int i = 0; i < MAX_BUFFER_SIZE; i++)
|
||||||
int bufferSize = 1024;
|
|
||||||
|
|
||||||
for ( int i = 0; i < bufferSize; i++)
|
|
||||||
tmpBuffer.push_back(0.f);
|
tmpBuffer.push_back(0.f);
|
||||||
|
|
||||||
for (int i=0; i<65536; i++)
|
for (int i=0; i<65536; i++)
|
||||||
fVec0[i] = 0;
|
fVec0[i] = 0;
|
||||||
|
for (int i=0; i<2; i++)
|
||||||
|
fRec0[i] = 0;
|
||||||
semitoneShift = 0.0f;
|
semitoneShift = 0.0f;
|
||||||
windowSize = 1000;
|
windowSize = 1000;
|
||||||
crossfadeSize = 1000;
|
crossfadeSize = 1000;
|
||||||
|
|
||||||
for (int i=0; i<2; i++)
|
|
||||||
fRec0[i] = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Looper::midi(unsigned char* data)
|
void Looper::midi(unsigned char* data)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
if ( data[0] - 144 == track )
|
if ( data[0] - 144 == track )
|
||||||
{
|
{
|
||||||
switch ( data[1] )
|
switch ( data[1] )
|
||||||
|
@ -87,19 +81,18 @@ void Looper::midi(unsigned char* data)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Looper::setScene( int sc )
|
void Looper::setScene( int sc )
|
||||||
{
|
{
|
||||||
// update Looper to play different scene
|
// update Looper to play different scene
|
||||||
scene = sc;
|
scene = sc;
|
||||||
sample = samples[scene];
|
//sample = samples[scene];
|
||||||
}
|
}
|
||||||
|
|
||||||
void Looper::setState( State s)
|
//void Looper::setState( State s) {
|
||||||
{
|
/*
|
||||||
// quantize recording to next bar event
|
// quantize recording to next bar event
|
||||||
if ( state == STATE_RECORDING )
|
if ( state == STATE_RECORDING )
|
||||||
{
|
{
|
||||||
|
@ -107,10 +100,12 @@ void Looper::setState( State s)
|
||||||
}
|
}
|
||||||
state = s;
|
state = s;
|
||||||
updateControllers();
|
updateControllers();
|
||||||
}
|
} */
|
||||||
|
|
||||||
|
|
||||||
void Looper::updateControllers()
|
void Looper::updateControllers()
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
if (state == STATE_RECORD_QUEUED )
|
if (state == STATE_RECORD_QUEUED )
|
||||||
{
|
{
|
||||||
numBeats = 0;
|
numBeats = 0;
|
||||||
|
@ -147,10 +142,12 @@ void Looper::updateControllers()
|
||||||
EventLooperProgress e(track, 0 );
|
EventLooperProgress e(track, 0 );
|
||||||
writeToGuiRingbuffer( &e );
|
writeToGuiRingbuffer( &e );
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void Looper::setSample(int sc, AudioBuffer* ab)
|
void Looper::setSample(int sc, AudioBuffer* ab)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
vector<float>& buf = ab->getData();
|
vector<float>& buf = ab->getData();
|
||||||
if ( buf.size() > SAMPLE_SIZE )
|
if ( buf.size() > SAMPLE_SIZE )
|
||||||
{
|
{
|
||||||
|
@ -177,10 +174,12 @@ void Looper::setSample(int sc, AudioBuffer* ab)
|
||||||
|
|
||||||
//memcpy( &sample[0], &buf[0], buf.size() ); // copy sample data to pre-allocated buffer
|
//memcpy( &sample[0], &buf[0], buf.size() ); // copy sample data to pre-allocated buffer
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void Looper::process(int nframes, Buffers* buffers)
|
void Looper::process(int nframes, Buffers* buffers)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
float* in = buffers->audio[Buffers::MASTER_INPUT];
|
float* in = buffers->audio[Buffers::MASTER_INPUT];
|
||||||
|
|
||||||
// FIXME:
|
// FIXME:
|
||||||
|
@ -237,6 +236,7 @@ void Looper::process(int nframes, Buffers* buffers)
|
||||||
|
|
||||||
void Looper::bar()
|
void Looper::bar()
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
int barTmpState = state;
|
int barTmpState = state;
|
||||||
// queue stop recording -> stop recording, now calculate beats in loop
|
// queue stop recording -> stop recording, now calculate beats in loop
|
||||||
if ( stopRecordOnBar )
|
if ( stopRecordOnBar )
|
||||||
|
@ -290,32 +290,21 @@ void Looper::bar()
|
||||||
{
|
{
|
||||||
updateControllers();
|
updateControllers();
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void Looper::beat()
|
void Looper::beat()
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
if (state == STATE_RECORDING || stopRecordOnBar )
|
if (state == STATE_RECORDING || stopRecordOnBar )
|
||||||
{
|
{
|
||||||
numBeats++;
|
numBeats++;
|
||||||
}
|
}
|
||||||
playedBeats++;
|
playedBeats++;
|
||||||
|
*
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void Looper::setLoopLength(float l)
|
|
||||||
{
|
|
||||||
numBeats = l * 4;
|
|
||||||
|
|
||||||
// smallest loop = 4 beats
|
|
||||||
if ( numBeats < 4 )
|
|
||||||
numBeats = 4;
|
|
||||||
|
|
||||||
char buffer [50];
|
|
||||||
sprintf (buffer, "Looper %i loop lenght = %i", track, numBeats );
|
|
||||||
EventGuiPrint e( buffer );
|
|
||||||
writeToGuiRingbuffer( &e );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Looper::pitchShift(int count, float* input, float* output)
|
void Looper::pitchShift(int count, float* input, float* output)
|
||||||
{
|
{
|
||||||
float fSlow0 = windowSize;
|
float fSlow0 = windowSize;
|
||||||
|
|
|
@ -9,8 +9,6 @@
|
||||||
#include "audioprocessor.hxx"
|
#include "audioprocessor.hxx"
|
||||||
#include "observer/observer.hxx"
|
#include "observer/observer.hxx"
|
||||||
|
|
||||||
#define SAMPLE_SIZE 44100*20
|
|
||||||
|
|
||||||
class AudioBuffer;
|
class AudioBuffer;
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
@ -28,26 +26,10 @@ using namespace std;
|
||||||
* pre-allocated buffers while it is still quite simple.
|
* pre-allocated buffers while it is still quite simple.
|
||||||
*
|
*
|
||||||
* Each clip has its properties like length and bars/beats, so the Looper knows
|
* Each clip has its properties like length and bars/beats, so the Looper knows
|
||||||
* to dynamically stretch / process the audio appropriately.
|
* to dynamically stretch / process the audio appropriately. Controllers and the
|
||||||
|
* UI are updated from this data.
|
||||||
**/
|
**/
|
||||||
class LooperClip
|
class LooperClip
|
||||||
{
|
|
||||||
public:
|
|
||||||
LooperClip()
|
|
||||||
{
|
|
||||||
buffer = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setRequestedBuffer( AudioBuffer* ab )
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
AudioBuffer* buffer;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Looper : public Observer, public AudioProcessor
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum State {
|
enum State {
|
||||||
|
@ -59,6 +41,43 @@ class Looper : public Observer, public AudioProcessor
|
||||||
STATE_STOP_QUEUED,
|
STATE_STOP_QUEUED,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
LooperClip()
|
||||||
|
{
|
||||||
|
_loaded = false;
|
||||||
|
_buffer = 0;
|
||||||
|
_state = STATE_STOPPED;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setRequestedBuffer( AudioBuffer* ab )
|
||||||
|
{
|
||||||
|
// here we copy the data from the existing buffer into the new one,
|
||||||
|
// and send the old one away to be deallocated.
|
||||||
|
}
|
||||||
|
|
||||||
|
bool loaded(){return _loaded;}
|
||||||
|
State state(){return _state;}
|
||||||
|
|
||||||
|
// Set
|
||||||
|
void clipLength(int l){_clipLenght = l;}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool _loaded;
|
||||||
|
State _state;
|
||||||
|
AudioBuffer* _buffer;
|
||||||
|
|
||||||
|
// Clip Properties
|
||||||
|
int _clipLenght;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Looper
|
||||||
|
* The class which reads from LooperClips, and reads/ writes the data using the
|
||||||
|
* track buffer. Scene recording / playback is the essential functionality here.
|
||||||
|
**/
|
||||||
|
class Looper : public Observer, public AudioProcessor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
|
||||||
Looper(int t);
|
Looper(int t);
|
||||||
|
|
||||||
void setSample(int c, AudioBuffer* ab);
|
void setSample(int c, AudioBuffer* ab);
|
||||||
|
@ -71,15 +90,15 @@ class Looper : public Observer, public AudioProcessor
|
||||||
void setFpb(int f) { fpb = f; }
|
void setFpb(int f) { fpb = f; }
|
||||||
|
|
||||||
void setScene( int sc );
|
void setScene( int sc );
|
||||||
void setState( State s);
|
//void setState( State s);
|
||||||
void setLoopLength(float l);
|
|
||||||
|
|
||||||
void updateControllers();
|
void updateControllers();
|
||||||
void process(int nframes, Buffers* buffers);
|
void process(int nframes, Buffers* buffers);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const int track;
|
const int track;
|
||||||
State state;
|
//State state;
|
||||||
int scene;
|
int scene;
|
||||||
|
|
||||||
int fpb;
|
int fpb;
|
||||||
|
@ -91,7 +110,7 @@ class Looper : public Observer, public AudioProcessor
|
||||||
int endPoint, lastWrittenSampleIndex;
|
int endPoint, lastWrittenSampleIndex;
|
||||||
float playPoint;
|
float playPoint;
|
||||||
float* sample;
|
float* sample;
|
||||||
float samples[10][SAMPLE_SIZE];
|
float* tmpRecordBuffer;
|
||||||
|
|
||||||
// Pitch Shifting
|
// Pitch Shifting
|
||||||
void pitchShift(int count, float* input, float* output);
|
void pitchShift(int count, float* input, float* output);
|
||||||
|
|
Loading…
Add table
Reference in a new issue