mirror of
https://github.com/vale981/openAV-Luppp
synced 2025-03-05 09:01:39 -05:00
-Refactored LooperClip and TrackOutput
This commit is contained in:
parent
f7fce45d4a
commit
ad74c72fea
5 changed files with 288 additions and 223 deletions
154
src/looperclip.cxx
Normal file
154
src/looperclip.cxx
Normal file
|
@ -0,0 +1,154 @@
|
|||
|
||||
#include "looperclip.hxx"
|
||||
|
||||
#include <stdio.h>
|
||||
#include "config.hxx"
|
||||
#include "event.hxx"
|
||||
#include "eventhandler.hxx"
|
||||
#include "audiobuffer.hxx"
|
||||
|
||||
LooperClip::LooperClip()
|
||||
{
|
||||
_loaded = false;
|
||||
_playing = false;
|
||||
_recording = false;
|
||||
|
||||
_buffer = 0; //new AudioBuffer(44100);
|
||||
_newBufferInTransit = false;
|
||||
|
||||
_playhead = 0;
|
||||
_recordhead = 0;
|
||||
}
|
||||
|
||||
/// loads a sample: eg from disk, unloading current sample if necessary
|
||||
void LooperClip::load( AudioBuffer* ab )
|
||||
{
|
||||
_loaded = true;
|
||||
|
||||
if ( _buffer )
|
||||
{
|
||||
EventDeallocateBuffer e( _buffer );
|
||||
writeToGuiRingbuffer( &e );
|
||||
}
|
||||
|
||||
_buffer = ab;
|
||||
|
||||
_playhead = 0;
|
||||
|
||||
// set the endpoint to the buffer's size
|
||||
_recordhead = _buffer->getData().size();
|
||||
}
|
||||
|
||||
void LooperClip::setRequestedBuffer( AudioBuffer* ab )
|
||||
{
|
||||
if ( _buffer )
|
||||
{
|
||||
size_t size = _buffer->getData().size();
|
||||
|
||||
for(size_t i = 0; i < size; i++)
|
||||
{
|
||||
ab->getData().at(i) = _buffer->getData().at( i );
|
||||
}
|
||||
|
||||
EventDeallocateBuffer e( _buffer );
|
||||
writeToGuiRingbuffer( &e );
|
||||
}
|
||||
|
||||
_buffer = ab;
|
||||
|
||||
_newBufferInTransit = false;
|
||||
}
|
||||
|
||||
|
||||
void LooperClip::record(int count, float* L, float* R)
|
||||
{
|
||||
// write "count" samples into current buffer.
|
||||
if ( _buffer )
|
||||
{
|
||||
for(int i = 0; i < count; i++)
|
||||
{
|
||||
_buffer->getData().at( _recordhead ) = *L++;
|
||||
_recordhead++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsigned long LooperClip::recordSpaceAvailable()
|
||||
{
|
||||
if ( _buffer )
|
||||
return _buffer->getData().size() - _recordhead;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t LooperClip::audioBufferSize()
|
||||
{
|
||||
if ( _buffer )
|
||||
{
|
||||
return _buffer->getData().size();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void LooperClip::setBeats(int beats)
|
||||
{
|
||||
if ( _buffer )
|
||||
{
|
||||
_buffer->setBeats( beats );
|
||||
}
|
||||
}
|
||||
|
||||
int LooperClip::getBeats()
|
||||
{
|
||||
if ( _buffer )
|
||||
return _buffer->getBeats();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
long LooperClip::getBufferLenght()
|
||||
{
|
||||
return _recordhead;
|
||||
}
|
||||
|
||||
bool LooperClip::loaded(){return _loaded;}
|
||||
void LooperClip::playing(bool p){_playing = p; _playhead = 0; }
|
||||
bool LooperClip::playing(){return _playing;}
|
||||
bool LooperClip::recording(){return _recording;}
|
||||
void LooperClip::recording(bool r) {_recording = r;}
|
||||
|
||||
void LooperClip::newBufferInTransit(bool n){_newBufferInTransit = n;}
|
||||
bool LooperClip::newBufferInTransit(){return _newBufferInTransit;}
|
||||
|
||||
float LooperClip::getSample(float playSpeed)
|
||||
{
|
||||
if ( _buffer )
|
||||
{
|
||||
if ( _playhead >= _recordhead ||
|
||||
_playhead >= _buffer->getData().size() ||
|
||||
_playhead < 0 )
|
||||
{
|
||||
_playhead = 0;
|
||||
printf("looper resetting playhead\n");
|
||||
}
|
||||
|
||||
std::vector<float>& v = _buffer->getData();
|
||||
float tmp = v.at(_playhead);
|
||||
_playhead += playSpeed;
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
return 0.f;
|
||||
}
|
||||
|
||||
float LooperClip::getProgress()
|
||||
{
|
||||
if ( _buffer && _playing )
|
||||
{
|
||||
float p = float(_playhead) / _recordhead;
|
||||
//printf("LooperClip progress %f\n", p );
|
||||
return p;
|
||||
}
|
||||
return 0.f;
|
||||
}
|
|
@ -4,8 +4,8 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include "config.hxx"
|
||||
#include "eventhandler.hxx"
|
||||
#include "audiobuffer.hxx"
|
||||
|
||||
class AudioBuffer;
|
||||
|
||||
/** LooperClip
|
||||
* Represents each clip that a looper can playback. The core of the audio
|
||||
|
@ -26,154 +26,40 @@
|
|||
class LooperClip
|
||||
{
|
||||
public:
|
||||
LooperClip()
|
||||
{
|
||||
_loaded = false;
|
||||
_playing = false;
|
||||
_recording = false;
|
||||
|
||||
_buffer = 0; //new AudioBuffer(44100);
|
||||
_newBufferInTransit = false;
|
||||
|
||||
_playhead = 0;
|
||||
_recordhead = 0;
|
||||
}
|
||||
LooperClip();
|
||||
|
||||
/// loads a sample: eg from disk, unloading current sample if necessary
|
||||
void load( AudioBuffer* ab )
|
||||
{
|
||||
_loaded = true;
|
||||
|
||||
if ( _buffer )
|
||||
{
|
||||
EventDeallocateBuffer e( _buffer );
|
||||
writeToGuiRingbuffer( &e );
|
||||
}
|
||||
|
||||
_buffer = ab;
|
||||
|
||||
_playhead = 0;
|
||||
|
||||
// set the endpoint to the buffer's size
|
||||
_recordhead = _buffer->getData().size();
|
||||
}
|
||||
void load( AudioBuffer* ab );
|
||||
|
||||
/// used to update the size of the buffer for this looperclip. The current
|
||||
/// data is copied into the new buffer, then the smaller buffer is sent
|
||||
/// for de-allocation
|
||||
void setRequestedBuffer( AudioBuffer* ab )
|
||||
{
|
||||
if ( _buffer )
|
||||
{
|
||||
size_t size = _buffer->getData().size();
|
||||
|
||||
for(size_t i = 0; i < size; i++)
|
||||
{
|
||||
ab->getData().at(i) = _buffer->getData().at( i );
|
||||
}
|
||||
|
||||
EventDeallocateBuffer e( _buffer );
|
||||
writeToGuiRingbuffer( &e );
|
||||
}
|
||||
|
||||
_buffer = ab;
|
||||
|
||||
_newBufferInTransit = false;
|
||||
}
|
||||
void setRequestedBuffer( AudioBuffer* ab );
|
||||
|
||||
void record(int count, float* L, float* R)
|
||||
{
|
||||
// write "count" samples into current buffer.
|
||||
if ( _buffer )
|
||||
{
|
||||
for(int i = 0; i < count; i++)
|
||||
{
|
||||
_buffer->getData().at( _recordhead ) = *L++;
|
||||
_recordhead++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
void record(int count, float* L, float* R);
|
||||
|
||||
unsigned long recordSpaceAvailable()
|
||||
{
|
||||
if ( _buffer )
|
||||
return _buffer->getData().size() - _recordhead;
|
||||
|
||||
return 0;
|
||||
}
|
||||
unsigned long recordSpaceAvailable();
|
||||
|
||||
size_t audioBufferSize()
|
||||
{
|
||||
if ( _buffer )
|
||||
{
|
||||
return _buffer->getData().size();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
size_t audioBufferSize();
|
||||
|
||||
void setBeats(int beats)
|
||||
{
|
||||
if ( _buffer )
|
||||
{
|
||||
_buffer->setBeats( beats );
|
||||
}
|
||||
}
|
||||
void setBeats(int beats);
|
||||
|
||||
int getBeats()
|
||||
{
|
||||
if ( _buffer )
|
||||
return _buffer->getBeats();
|
||||
|
||||
return 0;
|
||||
}
|
||||
int getBeats();
|
||||
|
||||
long getBufferLenght()
|
||||
{
|
||||
return _recordhead;
|
||||
}
|
||||
long getBufferLenght();
|
||||
|
||||
bool loaded(){return _loaded;}
|
||||
void playing(bool p){_playing = p; _playhead = 0; }
|
||||
bool playing(){return _playing;}
|
||||
bool recording(){return _recording;}
|
||||
void recording(bool r) {_recording = r;}
|
||||
bool loaded();
|
||||
void playing(bool p);
|
||||
bool playing();
|
||||
bool recording();
|
||||
void recording(bool r);
|
||||
|
||||
void newBufferInTransit(bool n){_newBufferInTransit = n;}
|
||||
bool newBufferInTransit(){return _newBufferInTransit;}
|
||||
void newBufferInTransit(bool n);
|
||||
bool newBufferInTransit();
|
||||
|
||||
float getSample(float playSpeed)
|
||||
{
|
||||
if ( _buffer )
|
||||
{
|
||||
if ( _playhead >= _recordhead ||
|
||||
_playhead >= _buffer->getData().size() ||
|
||||
_playhead < 0 )
|
||||
{
|
||||
_playhead = 0;
|
||||
printf("looper resetting playhead\n");
|
||||
}
|
||||
|
||||
std::vector<float>& v = _buffer->getData();
|
||||
float tmp = v.at(_playhead);
|
||||
_playhead += playSpeed;
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
return 0.f;
|
||||
}
|
||||
float getSample(float playSpeed);
|
||||
|
||||
float getProgress()
|
||||
{
|
||||
if ( _buffer && _playing )
|
||||
{
|
||||
float p = float(_playhead) / _recordhead;
|
||||
//printf("LooperClip progress %f\n", p );
|
||||
return p;
|
||||
}
|
||||
return 0.f;
|
||||
}
|
||||
float getProgress();
|
||||
|
||||
private:
|
||||
bool _loaded;
|
||||
|
|
104
src/trackoutput.cxx
Normal file
104
src/trackoutput.cxx
Normal file
|
@ -0,0 +1,104 @@
|
|||
|
||||
#include "trackoutput.hxx"
|
||||
|
||||
TrackOutput::TrackOutput(int t, AudioProcessor* ap) :
|
||||
AudioProcessor(),
|
||||
track(t),
|
||||
previousInChain(ap),
|
||||
dbMeter(44100)
|
||||
{
|
||||
//printf("trackOutput ID: %i, ap = ", track );
|
||||
//std::cout << ap << std::endl;
|
||||
|
||||
//_trackBuffer.resize( MAX_BUFFER_SIZE );
|
||||
|
||||
// UI update
|
||||
uiUpdateConstant = 44100 / 30;
|
||||
uiUpdateCounter = 44100 / 30;
|
||||
|
||||
_toReverb = 0.0;
|
||||
_toMaster = 0.8;
|
||||
_toSidechain = 0.0;
|
||||
_toPostSidechain = 0.0;
|
||||
}
|
||||
|
||||
|
||||
void TrackOutput::setMaster(float value)
|
||||
{
|
||||
_toMaster = value;
|
||||
}
|
||||
|
||||
float TrackOutput::getMaster()
|
||||
{
|
||||
return _toMaster;
|
||||
}
|
||||
|
||||
|
||||
void TrackOutput::setSend( int send, float value )
|
||||
{
|
||||
switch( send )
|
||||
{
|
||||
case SEND_REV:
|
||||
_toReverb = value;
|
||||
break;
|
||||
case SEND_SIDE:
|
||||
_toSidechain = value;
|
||||
break;
|
||||
case SEND_POST:
|
||||
_toPostSidechain = value;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void TrackOutput::process(int nframes, Buffers* buffers)
|
||||
{
|
||||
// zero track buffer
|
||||
memset( &_trackBuffer[0], 0, nframes );
|
||||
|
||||
buffers->audio[Buffers::TRACK_0 + track] = &_trackBuffer[0];
|
||||
previousInChain->process( nframes, buffers );
|
||||
|
||||
|
||||
// run the meter
|
||||
float* buf = &_trackBuffer[0];
|
||||
dbMeter.process( nframes, buf, buf );
|
||||
|
||||
if (uiUpdateCounter > uiUpdateConstant )
|
||||
{
|
||||
// FIXME: should be using ControllerUpdater
|
||||
EventTrackSignalLevel e( track, dbMeter.getLeftDB() * _toMaster, dbMeter.getRightDB() * _toMaster );
|
||||
writeToGuiRingbuffer( &e );
|
||||
uiUpdateCounter = 0;
|
||||
}
|
||||
|
||||
uiUpdateCounter += nframes;
|
||||
|
||||
|
||||
// copy audio data into reverb / sidechain / master buffers
|
||||
float* reverb = buffers->audio[Buffers::REVERB];
|
||||
float* sidechain = buffers->audio[Buffers::SIDECHAIN];
|
||||
float* postSidechain = buffers->audio[Buffers::POST_SIDECHAIN];
|
||||
|
||||
float* masterL = buffers->audio[Buffers::MASTER_OUT_L];
|
||||
float* masterR = buffers->audio[Buffers::MASTER_OUT_R];
|
||||
|
||||
for(int i = 0; i < nframes; i++)
|
||||
{
|
||||
float tmp = _trackBuffer[i];
|
||||
|
||||
masterL[i] += tmp * _toMaster;
|
||||
masterR[i] += tmp * _toMaster;
|
||||
|
||||
masterL++;
|
||||
masterR++;
|
||||
|
||||
*reverb++ += tmp * _toReverb;
|
||||
*sidechain++ += tmp * _toSidechain;
|
||||
*postSidechain++ += tmp * _toPostSidechain;
|
||||
}
|
||||
}
|
||||
|
||||
TrackOutput::~TrackOutput()
|
||||
{
|
||||
}
|
|
@ -5,6 +5,7 @@
|
|||
#include <iostream>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "buffers.hxx"
|
||||
#include "config.hxx"
|
||||
#include "audioprocessor.hxx"
|
||||
|
||||
|
@ -14,102 +15,20 @@
|
|||
class TrackOutput : public AudioProcessor
|
||||
{
|
||||
public:
|
||||
TrackOutput(int t, AudioProcessor* ap) :
|
||||
AudioProcessor(),
|
||||
track(t),
|
||||
_trackBuffer( MAX_BUFFER_SIZE, 0.f ),
|
||||
previousInChain(ap),
|
||||
dbMeter(44100)
|
||||
{
|
||||
printf("trackOutput ID: %i, ap = ", track );
|
||||
std::cout << ap << std::endl;
|
||||
|
||||
|
||||
// UI update
|
||||
uiUpdateConstant = 44100 / 30;
|
||||
uiUpdateCounter = 44100 / 30;
|
||||
|
||||
_toReverb = 0.0;
|
||||
_toMaster = 0.8;
|
||||
_toSidechain = 0.0;
|
||||
_toPostSidechain = 0.0;
|
||||
}
|
||||
TrackOutput(int t, AudioProcessor* ap);
|
||||
|
||||
/// set main mix, 0-1
|
||||
void setMaster(float value)
|
||||
{
|
||||
_toMaster = value;
|
||||
}
|
||||
void setMaster(float value);
|
||||
|
||||
float getMaster();
|
||||
|
||||
/// set send
|
||||
void setSend( int send, float value )
|
||||
{
|
||||
switch( send )
|
||||
{
|
||||
case SEND_REV:
|
||||
_toReverb = value;
|
||||
break;
|
||||
case SEND_SIDE:
|
||||
_toSidechain = value;
|
||||
break;
|
||||
case SEND_POST:
|
||||
_toPostSidechain = value;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
void setSend( int send, float value );
|
||||
|
||||
/// copies the track output to master buffer, sidechain & post-side buffer
|
||||
void process(int nframes, Buffers* buffers)
|
||||
{
|
||||
// zero track buffer
|
||||
memset( &_trackBuffer[0], 0, nframes );
|
||||
|
||||
buffers->audio[Buffers::TRACK_0 + track] = &_trackBuffer[0];
|
||||
previousInChain->process( nframes, buffers );
|
||||
|
||||
|
||||
// run the meter
|
||||
float* buf = &_trackBuffer[0];
|
||||
dbMeter.process( nframes, buf, buf );
|
||||
|
||||
if (uiUpdateCounter > uiUpdateConstant )
|
||||
{
|
||||
// FIXME: should be using ControllerUpdater
|
||||
EventTrackSignalLevel e( track, dbMeter.getLeftDB() * _toMaster, dbMeter.getRightDB() * _toMaster );
|
||||
writeToGuiRingbuffer( &e );
|
||||
uiUpdateCounter = 0;
|
||||
}
|
||||
uiUpdateCounter += nframes;
|
||||
|
||||
|
||||
/// copy audio data into reverb / sidechain / master buffers
|
||||
float* reverb = buffers->audio[Buffers::REVERB];
|
||||
float* sidechain = buffers->audio[Buffers::SIDECHAIN];
|
||||
float* postSidechain = buffers->audio[Buffers::POST_SIDECHAIN];
|
||||
|
||||
float* masterL = buffers->audio[Buffers::MASTER_OUT_L];
|
||||
float* masterR = buffers->audio[Buffers::MASTER_OUT_R];
|
||||
|
||||
for(int i = 0; i < nframes; i++)
|
||||
{
|
||||
float tmp = _trackBuffer[i];
|
||||
|
||||
masterL[i] += tmp * _toMaster;
|
||||
masterR[i] += tmp * _toMaster;
|
||||
|
||||
masterL++;
|
||||
masterR++;
|
||||
|
||||
*reverb++ += tmp * _toReverb;
|
||||
*sidechain++ += tmp * _toSidechain;
|
||||
*postSidechain++ += tmp * _toPostSidechain;
|
||||
}
|
||||
}
|
||||
void process(int nframes, Buffers* buffers);
|
||||
|
||||
~TrackOutput()
|
||||
{
|
||||
}
|
||||
~TrackOutput();
|
||||
|
||||
private:
|
||||
int track;
|
||||
|
|
2
wscript
2
wscript
|
@ -25,6 +25,8 @@ def build(bld):
|
|||
'src/jack.cxx',
|
||||
'src/gtrack.cxx',
|
||||
'src/looper.cxx',
|
||||
'src/looperclip.cxx',
|
||||
'src/trackoutput.cxx',
|
||||
|
||||
'src/logic.cxx',
|
||||
'src/gridlogic.cxx',
|
||||
|
|
Loading…
Add table
Reference in a new issue