2013-05-15 02:55:51 +01:00
|
|
|
|
|
|
|
|
|
|
|
#include "looper.hxx"
|
|
|
|
|
|
|
|
#include "jack.hxx"
|
2013-05-16 13:38:46 +01:00
|
|
|
#include "eventhandler.hxx"
|
|
|
|
|
2013-05-15 04:05:36 +01:00
|
|
|
extern Jack* jack;
|
2013-05-15 02:55:51 +01:00
|
|
|
|
|
|
|
void Looper::setState(State s)
|
|
|
|
{
|
2013-05-16 16:31:22 +01:00
|
|
|
if ( state == STATE_RECORDING )
|
|
|
|
{
|
|
|
|
stopRecordOnBar = true;
|
|
|
|
}
|
|
|
|
|
2013-05-16 01:38:11 +01:00
|
|
|
// ensure we're not setting eg PLAY_QUEUED, if we're already PLAYING
|
|
|
|
if ( static_cast<int>(s) != static_cast<int>(state) + 1)
|
2013-05-15 02:55:51 +01:00
|
|
|
{
|
2013-05-16 01:38:11 +01:00
|
|
|
state = s;
|
2013-05-16 16:31:22 +01:00
|
|
|
|
|
|
|
if (state == STATE_RECORDING)
|
|
|
|
{
|
|
|
|
numBeats = 0;
|
|
|
|
}
|
2013-05-15 02:55:51 +01:00
|
|
|
}
|
|
|
|
}
|
2013-05-16 01:38:11 +01:00
|
|
|
|
2013-05-16 13:38:46 +01:00
|
|
|
void Looper::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 )
|
|
|
|
{
|
2013-05-16 16:14:14 +01:00
|
|
|
out[i] += sample[playPoint];
|
2013-05-16 13:38:46 +01:00
|
|
|
}
|
2013-05-16 16:14:14 +01:00
|
|
|
// always update playPoint, even when not playing sound.
|
|
|
|
// it updates the UI of progress
|
|
|
|
playPoint++;
|
2013-05-16 13:38:46 +01:00
|
|
|
}
|
|
|
|
|
2013-05-16 16:31:22 +01:00
|
|
|
float prog = (float(playPoint) / (fpb*numBeats));
|
|
|
|
|
|
|
|
/*
|
2013-05-16 16:14:14 +01:00
|
|
|
if ( track == 0 )
|
2013-05-16 16:31:22 +01:00
|
|
|
cout << prog << " playPoint " << playPoint << " endPoint " << endPoint
|
|
|
|
<< " fpb*numBeats " << fpb * numBeats << endl;
|
|
|
|
*/
|
2013-05-16 16:14:14 +01:00
|
|
|
EventLooperProgress e(track, prog );
|
2013-05-16 13:38:46 +01:00
|
|
|
writeToGuiRingbuffer( &e );
|
|
|
|
}
|
|
|
|
|
2013-05-16 16:31:22 +01:00
|
|
|
// stopRecordOnBar ensures we record right up to the bar measure
|
2013-05-16 16:14:14 +01:00
|
|
|
else if ( state == STATE_RECORDING || stopRecordOnBar )
|
2013-05-16 13:38:46 +01:00
|
|
|
{
|
|
|
|
for(int i = 0; i < nframes; i++)
|
|
|
|
{
|
|
|
|
if ( lastWrittenSampleIndex < 44100 * 60 )
|
|
|
|
{
|
|
|
|
sample[lastWrittenSampleIndex++] = in[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2013-05-16 15:17:49 +01:00
|
|
|
|
|
|
|
|
|
|
|
void Looper::bar()
|
|
|
|
{
|
2013-05-16 16:14:14 +01:00
|
|
|
stopRecordOnBar = false;
|
|
|
|
|
2013-05-16 16:31:22 +01:00
|
|
|
if ( playedBeats >= numBeats )
|
2013-05-16 15:17:49 +01:00
|
|
|
{
|
2013-05-16 16:31:22 +01:00
|
|
|
playPoint = 0;
|
|
|
|
playedBeats = 0;
|
2013-05-16 15:17:49 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if ( state == STATE_PLAY_QUEUED )
|
|
|
|
{
|
|
|
|
EventGuiPrint e( "Looper Q->Playing" );
|
|
|
|
writeToGuiRingbuffer( &e );
|
|
|
|
state = STATE_PLAYING;
|
|
|
|
playPoint = 0;
|
|
|
|
endPoint = lastWrittenSampleIndex;
|
|
|
|
}
|
|
|
|
if ( state == STATE_RECORD_QUEUED && state != STATE_RECORDING )
|
|
|
|
{
|
|
|
|
EventGuiPrint e( "Looper Q->Recording" );
|
|
|
|
writeToGuiRingbuffer( &e );
|
|
|
|
|
|
|
|
state = STATE_RECORDING;
|
|
|
|
playPoint = 0;
|
|
|
|
endPoint = 0;
|
|
|
|
lastWrittenSampleIndex = 0;
|
|
|
|
}
|
|
|
|
if ( state == STATE_PLAY_QUEUED && state != STATE_STOPPED )
|
|
|
|
{
|
|
|
|
EventGuiPrint e( "Looper Q->Stopped" );
|
|
|
|
writeToGuiRingbuffer( &e );
|
|
|
|
|
|
|
|
state = STATE_STOPPED;
|
|
|
|
endPoint = lastWrittenSampleIndex;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-05-16 16:14:14 +01:00
|
|
|
void Looper::beat()
|
|
|
|
{
|
2013-05-16 16:31:22 +01:00
|
|
|
if (state == STATE_RECORDING)
|
2013-05-16 16:14:14 +01:00
|
|
|
{
|
2013-05-16 16:31:22 +01:00
|
|
|
numBeats++;
|
2013-05-16 16:14:14 +01:00
|
|
|
}
|
2013-05-16 16:31:22 +01:00
|
|
|
playedBeats++; // only reset if we're on the last beat of a loop
|
2013-05-16 16:14:14 +01:00
|
|
|
}
|
|
|
|
|
2013-05-16 15:17:49 +01:00
|
|
|
void Looper::setLoopLength(float l)
|
|
|
|
{
|
|
|
|
numBeats *= l;
|
|
|
|
|
2013-05-16 16:31:22 +01:00
|
|
|
// smallest loop = 4 beats
|
|
|
|
if ( numBeats < 4 )
|
|
|
|
numBeats = 4;
|
2013-05-16 15:17:49 +01:00
|
|
|
|
|
|
|
char buffer [50];
|
|
|
|
sprintf (buffer, "Looper loop lenght = %i", numBeats );
|
|
|
|
EventGuiPrint e( buffer );
|
|
|
|
writeToGuiRingbuffer( &e );
|
|
|
|
}
|