diff --git a/src/looperclip.cxx b/src/looperclip.cxx new file mode 100644 index 0000000..ecd40b0 --- /dev/null +++ b/src/looperclip.cxx @@ -0,0 +1,154 @@ + +#include "looperclip.hxx" + +#include +#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& 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; +} diff --git a/src/looperclip.hxx b/src/looperclip.hxx index c8732ac..e89e7e0 100644 --- a/src/looperclip.hxx +++ b/src/looperclip.hxx @@ -4,8 +4,8 @@ #include #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& 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; diff --git a/src/trackoutput.cxx b/src/trackoutput.cxx new file mode 100644 index 0000000..f9fa25f --- /dev/null +++ b/src/trackoutput.cxx @@ -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() +{ +} diff --git a/src/trackoutput.hxx b/src/trackoutput.hxx index b4bbbfb..c569951 100644 --- a/src/trackoutput.hxx +++ b/src/trackoutput.hxx @@ -5,6 +5,7 @@ #include #include +#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; diff --git a/wscript b/wscript index d3f1786..4c4565c 100644 --- a/wscript +++ b/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',