aboutsummaryrefslogtreecommitdiff
path: root/buffer_override
diff options
context:
space:
mode:
Diffstat (limited to 'buffer_override')
-rwxr-xr-xbuffer_override/bufferoverride.hpp227
-rwxr-xr-xbuffer_override/bufferoverrideFormalities.cpp183
-rwxr-xr-xbuffer_override/bufferoverrideProcess.cpp253
-rw-r--r--buffer_override/bufferoverride~.pd64
-rwxr-xr-xbuffer_override/makefile46
5 files changed, 773 insertions, 0 deletions
diff --git a/buffer_override/bufferoverride.hpp b/buffer_override/bufferoverride.hpp
new file mode 100755
index 0000000..513a678
--- /dev/null
+++ b/buffer_override/bufferoverride.hpp
@@ -0,0 +1,227 @@
+/*------------------- by Marc Poirier ][ March 2001 -------------------*/
+
+
+#ifndef __bufferoverride
+#define __bufferoverride
+
+#include "dfxmisc.h"
+#include "lfo.h"
+#include "TempoRateTable.h"
+
+#include "flext.h"
+
+//-----------------------------------------------------------------------------
+// these are the plugin parameters:
+enum
+{
+ kDivisor,
+ kBuffer,
+ kBufferTempoSync,
+ kBufferInterrupt,
+
+ kDivisorLFOrate,
+ kDivisorLFOdepth,
+ kDivisorLFOshape,
+ kDivisorLFOtempoSync,
+ kBufferLFOrate,
+ kBufferLFOdepth,
+ kBufferLFOshape,
+ kBufferLFOtempoSync,
+
+ kSmooth,
+ kDryWetMix,
+
+ kPitchbend,
+ kMidiMode,
+
+ kTempo,
+
+ NUM_PARAMETERS
+};
+
+//-----------------------------------------------------------------------------
+// constants & macros
+
+#define DIVISOR_MIN 1.92f
+#define DIVISOR_MAX 222.0f
+#define bufferDivisorScaled(A) ( paramRangeSquaredScaled((A), DIVISOR_MIN, DIVISOR_MAX) )
+#define bufferDivisorUnscaled(A) ( paramRangeSquaredUnscaled((A), DIVISOR_MIN, DIVISOR_MAX) )
+
+#define BUFFER_MIN 1.0f
+#define BUFFER_MAX 999.0f
+#define forcedBufferSizeScaled(A) ( paramRangeSquaredScaled((1.0f-(A)), BUFFER_MIN, BUFFER_MAX) )
+#define forcedBufferSizeUnscaled(A) ( 1.0f - paramRangeSquaredUnscaled((A), BUFFER_MIN, BUFFER_MAX) )
+#define forcedBufferSizeSamples(A) ( (long)(forcedBufferSizeScaled((A)) * SAMPLERATE * 0.001f) )
+
+#define TEMPO_MIN 57.0f
+#define TEMPO_MAX 480.0f
+#define tempoScaled(A) ( paramRangeScaled((A), TEMPO_MIN, TEMPO_MAX) )
+#define tempoUnscaled(A) ( paramRangeUnscaled((A), TEMPO_MIN, TEMPO_MAX) )
+
+#define LFO_RATE_MIN 0.03f
+#define LFO_RATE_MAX 21.0f
+#define LFOrateScaled(A) ( paramRangeSquaredScaled((A), LFO_RATE_MIN, LFO_RATE_MAX) )
+#define LFOrateUnscaled(A) ( paramRangeSquaredUnscaled((A), LFO_RATE_MIN, LFO_RATE_MAX) )
+
+#define normalize(f,a,b) ((((f < b) ? f : b) > a) ? f : a)
+
+
+// you need this stuff to get some maximum buffer size & allocate for that
+// this is 42 bpm - should be sufficient
+#define MIN_ALLOWABLE_BPS 0.7f
+
+
+//-----------------------------------------------------------------------------
+class bufferoverrideProgram
+{
+friend class bufferoverride;
+public:
+ bufferoverrideProgram();
+ ~bufferoverrideProgram();
+private:
+ float *param;
+ char *name;
+};
+
+
+//-----------------------------------------------------------------------------
+
+class bufferoverride : public flext_dsp {
+
+ FLEXT_HEADER(bufferoverride, flext_dsp)
+
+public:
+ bufferoverride(int argc, t_atom *argv);
+ ~bufferoverride();
+
+ virtual void m_signal(int, t_sample *const *, t_sample *const *);
+ virtual void m_help();
+
+protected:
+ void doTheProcess(float **inputs, float **outputs, long sampleFrames, bool replacing);
+ void updateBuffer(long samplePos);
+
+ void heedbufferoverrideEvents(long samplePos);
+ float getDivisorParameterFromNote(int currentNote);
+ float getDivisorParameterFromPitchbend(int pitchbendByte);
+
+ void initPresets();
+ void createAudioBuffers();
+
+ // the parameters
+ float fDivisor, fBuffer, fBufferTempoSync, fBufferInterrupt, fSmooth,
+ fDryWetMix, fPitchbend, fMidiMode, fTempo;
+
+ long currentForcedBufferSize; // the size of the larger, imposed buffer
+ // these store the forced buffer
+ float *buffer1;
+
+ long writePos; // the current sample position within the forced buffer
+
+ long minibufferSize; // the current size of the divided "mini" buffer
+ long prevMinibufferSize; // the previous size
+ long readPos; // the current sample position within the minibuffer
+ float currentBufferDivisor; // the current value of the divisor with LFO possibly applied
+
+ float numLFOpointsDivSR; // the number of LFO table points divided by the sampling rate
+
+ float currentTempoBPS; // tempo in beats per second
+ TempoRateTable *tempoRateTable; // a table of tempo rate values
+ long hostCanDoTempo; // my semi-booly dude who knows something about the host's VstTimeInfo implementation
+ bool needResync;
+
+ long SUPER_MAX_BUFFER;
+ float SAMPLERATE;
+
+ long smoothDur, smoothcount; // total duration & sample counter for the minibuffer transition smoothing period
+ float smoothStep; // the gain increment for each sample "step" during the smoothing period
+ float sqrtFadeIn, sqrtFadeOut; // square root of the smoothing gains, for equal power crossfading
+ float smoothFract;
+
+ bool divisorWasChangedByHand; // for MIDI trigger mode - tells us to respect the fDivisor value
+ bool divisorWasChangedByMIDI; // tells the GUI that the divisor displays need updating
+
+ LFO *divisorLFO, *bufferLFO;
+
+ float fadeOutGain, fadeInGain, realFadePart, imaginaryFadePart; // for trig crossfading
+
+
+
+
+
+
+
+ virtual void suspend();
+
+ // flext
+
+ FLEXT_CALLBACK_F(setDivisor)
+ void setDivisor(float f) {
+ fDivisor = bufferDivisorUnscaled(normalize(f,DIVISOR_MIN,DIVISOR_MAX));
+ }
+
+ FLEXT_CALLBACK_F(setBuffer)
+ void setBuffer(float f) {
+ fBuffer = forcedBufferSizeUnscaled(normalize(f,BUFFER_MIN,BUFFER_MAX));
+ }
+
+/* FLEXT_CALLBACK_F(setBufferTempoSync)
+ void setBufferTempoSync(float f) {
+ fBufferTempoSync = normalize(f,0,1);
+ }
+
+ FLEXT_CALLBACK_F(setBufferInterrupt)
+ void setBufferInterrupt(float f) {
+ fBufferInterrupt = normalize(f,0,1);
+ }
+
+ FLEXT_CALLBACK_F(setSmooth)
+ void setSmooth(float f) {
+ fSmooth = normalize(f,0,1);
+ }
+
+ FLEXT_CALLBACK_F(setDryWetMix)
+ void setDryWetMix(float f) {
+ fDryWetMix = normalize(f,0,1);
+ }
+*/
+ FLEXT_CALLBACK_F(setTempo)
+ void setTempo(float f) {
+ fTempo = normalize(f,0,1);
+ }
+
+ FLEXT_CALLBACK_F(setDivisorLFOrate)
+ void setDivisorLFOrate(float f) {
+ divisorLFO->fRate = paramSteppedUnscaled(f, NUM_TEMPO_RATES);
+ }
+
+ FLEXT_CALLBACK_F(setDivisorLFOdepth)
+ void setDivisorLFOdepth(float f) {
+ divisorLFO->fDepth = normalize(f,0,1);
+ }
+
+ FLEXT_CALLBACK_F(setDivisorLFOshape)
+ void setDivisorLFOshape(float f) {
+ divisorLFO->fShape = LFOshapeUnscaled(normalize(f,0,7));
+ }
+
+
+ FLEXT_CALLBACK_F(setBufferLFOrate)
+ void setBufferLFOrate(float f) {
+ bufferLFO->fRate = paramSteppedUnscaled(f, NUM_TEMPO_RATES);
+ }
+
+ FLEXT_CALLBACK_F(setBufferLFOdepth)
+ void setBufferLFOdepth(float f) {
+ bufferLFO->fDepth = normalize(f,0,1);
+ }
+
+ FLEXT_CALLBACK_F(setBufferLFOshape)
+ void setBufferLFOshape(float f) {
+ bufferLFO->fShape = LFOshapeUnscaled(normalize(f,0,7));
+ }
+
+
+};
+
+#endif
diff --git a/buffer_override/bufferoverrideFormalities.cpp b/buffer_override/bufferoverrideFormalities.cpp
new file mode 100755
index 0000000..428a7b5
--- /dev/null
+++ b/buffer_override/bufferoverrideFormalities.cpp
@@ -0,0 +1,183 @@
+/*------------------- by Marc Poirier ][ March 2001 -------------------*/
+
+#ifndef __bufferoverride
+#include "bufferoverride.hpp"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+
+
+//-------------------------------------------------------------------------
+// titles of each parameter
+/*
+ fDivisor "buffer divisor"
+ fBuffer "forced buffer size"
+ fBufferTempoSync "forced buffer tempo sync"
+ fBufferInterrupt "stuck buffer"
+ fDivisorLFOrate "divisor LFO rate"
+ fDivisorLFOdepth "divisor LFO depth"
+ fDivisorLFOshape "divisor LFO shape"
+ fDivisorLFOtempoSync "divisor LFO tempo sync"
+ fBufferLFOrate "buffer LFO rate"
+ fBufferLFOdepth "buffer LFO depth"
+ fBufferLFOshape "buffer LFO shape"
+ fBufferLFOtempoSync "buffer LFO tempo sync"
+ fSmooth "smooth"
+ fDryWetMix "dry/wet mix"
+ fPitchbend "pitchbend"
+ fTempo "tempo"
+*/
+
+
+//-----------------------------------------------------------------------------
+// initializations & such
+
+bufferoverride::bufferoverride(int argc, t_atom *argv) {
+
+ buffer1 = NULL;
+
+ SUPER_MAX_BUFFER = (long) ((44100.0f / MIN_ALLOWABLE_BPS) * 4.0f);
+
+ // allocate memory for these structures
+ tempoRateTable = new TempoRateTable;
+ divisorLFO = new LFO;
+ bufferLFO = new LFO;
+
+ suspend();
+ initPresets();
+
+ fTempo = tempoUnscaled(120.0f);
+ currentTempoBPS = tempoScaled(fTempo) / 60.0f;
+
+
+ post("_ ____bufferoverride~ --_ - __ _____");
+
+ SAMPLERATE = (int) Samplerate();
+// blocksize = Blocksize();
+
+/* fTomsound = (float)GetFloat(argv[0]); // creation arguments
+ fQuality = (float)GetFloat(argv[1]); // [ yet they default to reasonable values ]
+ drymix = (float)GetFloat(argv[2]);
+ ireplace = (int)GetFloat(argv[3]);*/
+
+ AddInSignal();
+ AddInFloat(9);
+ AddOutSignal(); // 1 audio out [ == AddOutSignal(1) ]
+
+ SetupInOut(); // set up inlets and outlets.
+ // Must get called once!
+
+ // Now we need to bind the handler function to our
+ // inlets,
+
+/* fDivisor "buffer divisor"
+ fBuffer "forced buffer size"
+ fBufferTempoSync "forced buffer tempo sync"
+ fBufferInterrupt "stuck buffer"
+ fDivisorLFOrate "divisor LFO rate"
+ fDivisorLFOdepth "divisor LFO depth"
+ fDivisorLFOshape "divisor LFO shape"
+ fDivisorLFOtempoSync "divisor LFO tempo sync"
+ fBufferLFOrate "buffer LFO rate"
+ fBufferLFOdepth "buffer LFO depth"
+ fBufferLFOshape "buffer LFO shape"
+ fBufferLFOtempoSync "buffer LFO tempo sync"
+ fSmooth "smooth"
+ fDryWetMix "dry/wet mix"
+ fPitchbend "pitchbend"
+ fTempo "tempo"
+
+*/
+ FLEXT_ADDMETHOD( 1,setDivisor);
+ FLEXT_ADDMETHOD( 2,setBuffer);
+ FLEXT_ADDMETHOD( 3,setTempo);
+ FLEXT_ADDMETHOD( 4,setDivisorLFOrate);
+ FLEXT_ADDMETHOD( 5,setDivisorLFOdepth);
+ FLEXT_ADDMETHOD( 6,setDivisorLFOshape);
+ FLEXT_ADDMETHOD( 7,setBufferLFOrate);
+ FLEXT_ADDMETHOD( 8,setBufferLFOdepth);
+ FLEXT_ADDMETHOD( 9,setBufferLFOshape);
+
+ post("_ ____ ____ _");
+
+}
+
+
+// GIMME class:
+FLEXT_NEW_TILDE_G("bufferoverride~", bufferoverride)
+
+
+//-------------------------------------------------------------------------
+bufferoverride::~bufferoverride() {
+
+ // deallocate the memory from these arrays
+ if (buffer1) delete[] buffer1;
+ if (tempoRateTable) delete tempoRateTable;
+ if (divisorLFO) delete divisorLFO;
+ if (bufferLFO) delete bufferLFO;
+
+
+}
+
+//-------------------------------------------------------------------------
+void bufferoverride::suspend()
+{
+ // setting the values like this will restart the forced buffer in the next process()
+ currentForcedBufferSize = 1;
+ writePos = readPos = 1;
+ minibufferSize = 1;
+ prevMinibufferSize = 0;
+ smoothcount = smoothDur = 0;
+ sqrtFadeIn = sqrtFadeOut = 1.0f;
+
+ divisorLFO->reset();
+ bufferLFO->reset();
+}
+
+//-------------------------------------------------------------------------
+void bufferoverride::createAudioBuffers() {
+
+ // update the sample rate value
+ SAMPLERATE = (float)Samplerate();
+ // just in case the host responds with something wacky
+ if (SAMPLERATE <= 0.0f)
+ SAMPLERATE = 44100.0f;
+ long oldMax = SUPER_MAX_BUFFER;
+ SUPER_MAX_BUFFER = (long) ((SAMPLERATE / MIN_ALLOWABLE_BPS) * 4.0f);
+
+ // if the sampling rate (& therefore the max buffer size) has changed,
+ // then delete & reallocate the buffers according to the sampling rate
+ if (SUPER_MAX_BUFFER != oldMax) {
+ if (buffer1 != NULL)
+ delete[] buffer1;
+ buffer1 = NULL;
+ }
+
+ if (buffer1 == NULL) buffer1 = new float[SUPER_MAX_BUFFER];
+}
+
+
+//-------------------------------------------------------------------------
+void bufferoverride::initPresets()
+{
+
+ fDivisor = bufferDivisorUnscaled(27.0f);
+ fBuffer = forcedBufferSizeUnscaled(81.0f);
+ fBufferTempoSync = 0.0f;
+ fBufferInterrupt = 1.0f;
+ fSmooth = 0.06f;
+ fDryWetMix = 1.0f;
+ fTempo = 0.0f;
+
+ divisorLFO->fRate = paramSteppedUnscaled(6.6f, NUM_TEMPO_RATES);
+ divisorLFO->fDepth = 0.333f;
+ divisorLFO->fShape = LFOshapeUnscaled(kSineLFO);
+ divisorLFO->fTempoSync = 1.0f;
+ bufferLFO->fRate = 0.0f;
+ bufferLFO->fDepth = 0.06f;
+ bufferLFO->fShape = LFOshapeUnscaled(kSawLFO);
+ bufferLFO->fTempoSync = 1.0f;
+}
+
diff --git a/buffer_override/bufferoverrideProcess.cpp b/buffer_override/bufferoverrideProcess.cpp
new file mode 100755
index 0000000..5877020
--- /dev/null
+++ b/buffer_override/bufferoverrideProcess.cpp
@@ -0,0 +1,253 @@
+/*------------------- by Marc Poirier ][ March 2001 -------------------*/
+
+#ifndef __bufferoverride
+#include "bufferoverride.hpp"
+#endif
+
+
+
+//-----------------------------------------------------------------------------
+void bufferoverride::updateBuffer(long samplePos)
+{
+ bool doSmoothing = true; // but in some situations, we shouldn't
+ float divisorLFOvalue, bufferLFOvalue; // the current output values of the LFOs
+ long prevForcedBufferSize; // the previous forced buffer size
+
+
+ readPos = 0; // reset for starting a new minibuffer
+ prevMinibufferSize = minibufferSize;
+ prevForcedBufferSize = currentForcedBufferSize;
+
+ //--------------------------PROCESS THE LFOs----------------------------
+ // update the LFOs' positions to the current position
+ divisorLFO->updatePosition(prevMinibufferSize);
+ bufferLFO->updatePosition(prevMinibufferSize);
+ // Then get the current output values of the LFOs, which also updates their positions once more.
+ // Scale the 0.0 - 1.0 LFO output values to 0.0 - 2.0 (oscillating around 1.0).
+ divisorLFOvalue = processLFOzero2two(divisorLFO);
+ bufferLFOvalue = 2.0f - processLFOzero2two(bufferLFO); // inverting it makes more pitch sense
+ // & then update the stepSize for each LFO, in case the LFO parameters have changed
+ if (onOffTest(divisorLFO->fTempoSync))
+ divisorLFO->stepSize = currentTempoBPS * (tempoRateTable->getScalar(divisorLFO->fRate)) * numLFOpointsDivSR;
+ else
+ divisorLFO->stepSize = LFOrateScaled(divisorLFO->fRate) * numLFOpointsDivSR;
+ if (onOffTest(bufferLFO->fTempoSync))
+ bufferLFO->stepSize = currentTempoBPS * (tempoRateTable->getScalar(bufferLFO->fRate)) * numLFOpointsDivSR;
+ else
+ bufferLFO->stepSize = LFOrateScaled(bufferLFO->fRate) * numLFOpointsDivSR;
+
+ //---------------------------CALCULATE FORCED BUFFER SIZE----------------------------
+ // check if it's the end of this forced buffer
+ if (writePos >= currentForcedBufferSize)
+ {
+ writePos = 0; // start up a new forced buffer
+
+ // check on the previous forced & minibuffers; don't smooth if the last forced buffer wasn't divided
+ if (prevMinibufferSize >= currentForcedBufferSize)
+ doSmoothing = false;
+ else
+ doSmoothing = true;
+
+ // now update the the size of the current force buffer
+ if ( onOffTest(fBufferTempoSync) && // the user wants to do tempo sync / beat division rate
+ (currentTempoBPS > 0.0f) ) // avoid division by zero
+ {
+ currentForcedBufferSize = (long) ( SAMPLERATE / (currentTempoBPS * tempoRateTable->getScalar(fBuffer)) );
+ // set this true so that we make sure to do the measure syncronisation later on
+ }
+ else
+ currentForcedBufferSize = forcedBufferSizeSamples(fBuffer);
+ // apply the buffer LFO to the forced buffer size
+ currentForcedBufferSize = (long) ((float)currentForcedBufferSize * bufferLFOvalue);
+ // really low tempos & tempo rate values can cause huge forced buffer sizes,
+ // so prevent going outside of the allocated buffer space
+ if (currentForcedBufferSize > SUPER_MAX_BUFFER)
+ currentForcedBufferSize = SUPER_MAX_BUFFER;
+ if (currentForcedBufferSize < 2)
+ currentForcedBufferSize = 2;
+
+ // untrue this so that we don't do the measure sync calculations again unnecessarily
+ needResync = false;
+ }
+
+ //-----------------------CALCULATE THE DIVISOR-------------------------
+ currentBufferDivisor = bufferDivisorScaled(fDivisor);
+ // apply the divisor LFO to the divisor value if there's an "active" divisor (i.e. 2 or greater)
+ if (currentBufferDivisor >= 2.0f)
+ {
+ currentBufferDivisor *= divisorLFOvalue;
+ // now it's possible that the LFO could make the divisor less than 2,
+ // which will essentially turn the effect off, so we stop the modulation at 2
+ if (currentBufferDivisor < 2.0f)
+ currentBufferDivisor = 2.0f;
+ }
+
+ //-----------------------CALCULATE THE MINIBUFFER SIZE-------------------------
+ // this is not a new forced buffer starting up
+ if (writePos > 0)
+ {
+ // if it's allowed, update the minibuffer size midway through this forced buffer
+ if (onOffTest(fBufferInterrupt))
+ minibufferSize = (long) ( (float)currentForcedBufferSize / currentBufferDivisor );
+ // if it's the last minibuffer, then fill up the forced buffer to the end
+ // by extending this last minibuffer to fill up the end of the forced buffer
+ long remainingForcedBuffer = currentForcedBufferSize - writePos;
+ if ( (minibufferSize*2) >= remainingForcedBuffer )
+ minibufferSize = remainingForcedBuffer;
+ }
+ // this is a new forced buffer just beginning, act accordingly, do bar sync if necessary
+ else {
+ // because there isn't really any division (given my implementation) when the divisor is < 2
+ if (currentBufferDivisor < 2.0f) minibufferSize = currentForcedBufferSize;
+ else minibufferSize = (long) ( (float)currentForcedBufferSize / currentBufferDivisor );
+ }
+
+ //-----------------------CALCULATE SMOOTHING DURATION-------------------------
+ // no smoothing if the previous forced buffer wasn't divided
+ if (!doSmoothing)
+ smoothcount = smoothDur = 0;
+ else
+ {
+ smoothDur = (long) (fSmooth * (float)minibufferSize);
+ long maxSmoothDur;
+ // if we're just starting a new forced buffer,
+ // then the samples beyond the end of the previous one are not valid
+ if (writePos <= 0)
+ maxSmoothDur = prevForcedBufferSize - prevMinibufferSize;
+ // otherwise just make sure that we don't go outside of the allocated arrays
+ else
+ maxSmoothDur = SUPER_MAX_BUFFER - prevMinibufferSize;
+ if (smoothDur > maxSmoothDur)
+ smoothDur = maxSmoothDur;
+ smoothcount = smoothDur;
+ smoothStep = 1.0f / (float)(smoothDur+1); // the gain increment for each smoothing step
+
+ fadeOutGain = cosf(PI/(float)(4*smoothDur));
+ fadeInGain = sinf(PI/(float)(4*smoothDur));
+ realFadePart = (fadeOutGain * fadeOutGain) - (fadeInGain * fadeInGain); // cosf(3.141592/2/n)
+ imaginaryFadePart = 2.0f * fadeOutGain * fadeInGain; // sinf(3.141592/2/n)
+ }
+}
+
+void bufferoverride::m_signal(int n, float *const *in, float *const *out) {
+ // directly move everything to the vst part
+ doTheProcess((float **)in, (float **)out, (long)n, true);
+} // end m_signal
+
+
+void bufferoverride::m_help() {
+}
+
+//---------------------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------------------
+void bufferoverride::doTheProcess(float **inputs, float **outputs, long sampleFrames, bool replacing)
+{
+
+//-------------------------SAFETY CHECK----------------------
+
+ // there must have not been available memory or something (like WaveLab goofing up),
+ // so try to allocate buffers now
+ if ((buffer1 == NULL)) createAudioBuffers();
+
+ // if the creation failed, then abort audio processing
+ if (buffer1 == NULL) return;
+
+
+//-------------------------INITIALIZATIONS----------------------
+ // this is a handy value to have during LFO calculations & wasteful to recalculate at every sample
+ numLFOpointsDivSR = NUM_LFO_POINTS_FLOAT / SAMPLERATE;
+ divisorLFO->pickTheLFOwaveform();
+ bufferLFO->pickTheLFOwaveform();
+
+ // calculate this scaler value to minimize calculations later during processOutput()
+// float inputGain = 1.0f - fDryWetMix;
+// float outputGain = fDryWetMix;
+ float inputGain = sqrtf(1.0f - fDryWetMix);
+ float outputGain = sqrtf(fDryWetMix);
+
+
+//-----------------------TEMPO STUFF---------------------------
+ // figure out the current tempo if we're doing tempo sync
+ if ( onOffTest(fBufferTempoSync) ||
+ (onOffTest(divisorLFO->fTempoSync) || onOffTest(bufferLFO->fTempoSync)) )
+ {
+ // calculate the tempo at the current processing buffer
+ if ( (fTempo > 0.0f) || (hostCanDoTempo != 1) ) // get the tempo from the user parameter
+ {
+ currentTempoBPS = tempoScaled(fTempo) / 60.0f;
+ needResync = false; // we don't want it true if we're not syncing to host tempo
+ }
+ else // get the tempo from the host
+ {
+/* timeInfo = getTimeInfo(kBeatSyncTimeInfoFlags);
+ if (timeInfo)
+ {
+ if (kVstTempoValid & timeInfo->flags)
+ currentTempoBPS = (float)timeInfo->tempo / 60.0f;
+ else
+ currentTempoBPS = tempoScaled(fTempo) / 60.0f;
+// currentTempoBPS = ((float)tempoAt(reportCurrentPosition())) / 600000.0f;
+ // but zero & negative tempos are bad, so get the user tempo value instead if that happens
+ if (currentTempoBPS <= 0.0f)
+ currentTempoBPS = tempoScaled(fTempo) / 60.0f;
+ //
+ // check if audio playback has just restarted & reset buffer stuff if it has (for measure sync)
+ if (timeInfo->flags & kVstTransportChanged)
+ {
+ needResync = true;
+ currentForcedBufferSize = 1;
+ writePos = 1;
+ minibufferSize = 1;
+ prevMinibufferSize = 0;
+ smoothcount = smoothDur = 0;
+ }
+ }
+ else // do the same stuff as above if the timeInfo gets a null pointer
+ {
+*/ currentTempoBPS = tempoScaled(fTempo) / 60.0f;
+ needResync = false; // we don't want it true if we're not syncing to host tempo
+// }
+ }
+ }
+
+
+//-----------------------AUDIO STUFF---------------------------
+ // here we begin the audio output loop, which has two checkpoints at the beginning
+ for (long samplecount = 0; (samplecount < sampleFrames); samplecount++)
+ {
+ // check if it's the end of this minibuffer
+ if (readPos >= minibufferSize)
+ updateBuffer(samplecount);
+
+ // store the latest input samples into the buffers
+ buffer1[writePos] = inputs[0][samplecount];
+
+ // get the current output without any smoothing
+ float out1 = buffer1[readPos];
+
+ // and if smoothing is taking place, get the smoothed audio output
+ if (smoothcount > 0)
+ {
+ out1 = (out1 * fadeInGain) + (buffer1[readPos+prevMinibufferSize] * fadeOutGain);
+
+ smoothcount--;
+
+ fadeInGain = (fadeOutGain * imaginaryFadePart) + (fadeInGain * realFadePart);
+ fadeOutGain = (realFadePart * fadeOutGain) - (imaginaryFadePart * fadeInGain);
+ }
+
+ // write the output samples into the output stream
+ if (replacing)
+ {
+ outputs[0][samplecount] = (out1 * outputGain) + (inputs[0][samplecount] * inputGain);
+ }
+ else
+ {
+ outputs[0][samplecount] += (out1 * outputGain) + (inputs[0][samplecount] * inputGain);
+ }
+
+ // increment the position trackers
+ readPos++;
+ writePos++;
+ }
+}
diff --git a/buffer_override/bufferoverride~.pd b/buffer_override/bufferoverride~.pd
new file mode 100644
index 0000000..abe90d9
--- /dev/null
+++ b/buffer_override/bufferoverride~.pd
@@ -0,0 +1,64 @@
+#N canvas 219 54 847 752 10;
+#X obj 254 503 bufferoverride~;
+#X floatatom 276 285 5 0 0;
+#X floatatom 287 303 5 0 0;
+#X floatatom 322 330 5 0 0;
+#X floatatom 265 267 5 1 3000;
+#X floatatom 367 331 5 0 0;
+#X floatatom 411 332 5 0 0;
+#X floatatom 409 383 5 0 0;
+#X floatatom 452 383 5 0 0;
+#X floatatom 495 383 5 0 0;
+#X obj 226 637 dac~ 1 2;
+#X obj 254 591 *~;
+#X obj 277 591 *~;
+#X obj 332 542 vsl 15 128 0 100 0 0 empty empty volume 0 -8 1 8 -143491
+-262144 -1 4600 1;
+#X obj 254 199 readsf~ 2;
+#X msg 287 160 1;
+#X msg 508 122 0;
+#X msg 291 123 open ../../dresscode/0/3.wav;
+#X obj 393 160 t b;
+#X obj 391 186 delay 100;
+#X obj 321 159 delay 100;
+#X text 546 124 stop this shit;
+#X text 327 264 Divisor :: 1.92-222.0f;
+#X text 334 283 Buffer :: 1.00-999.0f;
+#X text 341 302 Tempo :: 57.00-480.00f;
+#X text 458 332 lfo 1 rate - depth - shape;
+#X text 547 383 lfo 2 rate - depth - shape;
+#X text 491 349 0-21 - 0-1f - 0-7i;
+#X text 590 401 0-21 - 0-1f - 0-7i;
+#X text 390 504 creation arguments > not til noww;
+#X text 29 23 ::- bufferoverrride~ orginally by destroy fx ported by
+martin pi;
+#X text 565 564 there are some values that might get played with in
+future versions not handled in here [ lack of time ] sorry ___ pi;
+#X text 456 586;
+#X text 381 26 more from dfx :: http://smartelectronix.com/~destroyfx
+;
+#X text 473 43 more from pi :: http://attacksyour.net/pi;
+#X connect 0 0 11 0;
+#X connect 0 0 12 0;
+#X connect 1 0 0 2;
+#X connect 2 0 0 3;
+#X connect 3 0 0 4;
+#X connect 4 0 0 1;
+#X connect 5 0 0 5;
+#X connect 6 0 0 6;
+#X connect 7 0 0 7;
+#X connect 8 0 0 8;
+#X connect 9 0 0 9;
+#X connect 11 0 10 0;
+#X connect 12 0 10 1;
+#X connect 13 0 12 1;
+#X connect 13 0 11 1;
+#X connect 14 0 0 0;
+#X connect 14 2 20 0;
+#X connect 15 0 14 0;
+#X connect 16 0 14 0;
+#X connect 17 0 14 0;
+#X connect 17 0 18 0;
+#X connect 18 0 19 0;
+#X connect 19 0 15 0;
+#X connect 20 0 17 0;
diff --git a/buffer_override/makefile b/buffer_override/makefile
new file mode 100755
index 0000000..192f56d
--- /dev/null
+++ b/buffer_override/makefile
@@ -0,0 +1,46 @@
+CXX=g++
+CFLAGS=-O6 -mcpu=pentiumpro -g -ggdb
+FLAGS=-DPD
+
+FLEXTPATH=/usr/local/lib/pd/externs/flext
+DFXINC=../dfx-library
+
+INCLUDES=/usr/local/lib/pd/include $(FLEXTPATH) $(DFXINC)
+FLEXTLIB=$(FLEXTPATH)/flext.a
+
+LIBS=m
+
+PDEXTRA=/usr/local/lib/pd/extra
+
+TARGET=bufferoverride~.pd_linux
+
+SRCS=bufferoverrideFormalities.cpp bufferoverrideProcess.cpp $(DFXINC)/lfo.cpp $(DFXINC)/TempoRateTable.cpp
+
+all: $(TARGET)
+
+%.o : %.cpp
+ $(CXX) -c $(CFLAGS) $(FLAGS) $(patsubst %,-I%,$(INCLUDES)) $< -o $@
+
+$(DFXINC)/%.o : $(DFXINC)/%.cpp
+ $(CXX) -c $(CFLAGS) $(FLAGS) $(patsubst %,-I%,$(INCLUDES)) $< -o $@
+
+$(TARGET) : $(patsubst %.cpp,%.o,$(SRCS)) $(FLEXTLIB)
+ $(CXX) $(LDFLAGS) -shared $^ $(patsubst %,-l%,$(LIBS)) -o $@
+ strip --strip-unneeded $@
+ chmod 755 $@
+
+install: $(TARGET)
+ chown root.root $^
+ cp $^ $(PDEXTRA)
+
+.PHONY: clean
+clean:
+ rm -f *.o $(TARGET)
+
+
+
+
+
+
+
+