Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove ValueBuffer #7297

Open
wants to merge 83 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 56 commits
Commits
Show all changes
83 commits
Select commit Hold shift + click to select a range
822d81e
Make ValueBuffer unsigned
Snowiiii Mar 27, 2024
95f142f
change to size_t
Snowiiii Mar 28, 2024
6cccf71
Remove ValueBuffer
Snowiiii Mar 29, 2024
193b4ef
Delete settings.json
Snowiiii Mar 29, 2024
bc15840
Merge branch 'master' into master
Snowiiii Mar 29, 2024
2157e93
Switch to clamp
Snowiiii Apr 1, 2024
0dd2559
Fix: macOS CI
Snowiiii Apr 1, 2024
a8f4147
Merge branch 'master' into valuebuffer-removal
Rossmaxx May 31, 2024
8889f20
style fixup
Rossmaxx Jun 5, 2024
dfd7af9
directly use float in MixHelpers.cpp
Rossmaxx Jun 5, 2024
71aa14f
added size boundaries and cast to float*
Rossmaxx Jun 5, 2024
e331a7a
missed a ,
Rossmaxx Jun 5, 2024
c8c482c
Fixed vector passing by pointer.
Rossmaxx Jun 5, 2024
3fdaaf3
Fixed clamping mistake with ,
Rossmaxx Jun 5, 2024
ddb18ce
Try fixing the clamp further.
Rossmaxx Jun 5, 2024
0ac7ae5
Removed clamp
Rossmaxx Jun 6, 2024
4702449
remove unused buffer size parameters
Rossmaxx Jun 6, 2024
9b003d6
fixed style in dual filter where I missed previously
Rossmaxx Jun 6, 2024
7d2293c
missed removing this bufferSize
Rossmaxx Jun 6, 2024
c824e59
Update CPU to Pentium 4 for win32 builds (#6155)
softrabbit May 29, 2024
bbb9ea5
Update upload-artifacts actions (#7263)
messmerd May 29, 2024
0f2866a
update veal submodule
FyiurAmron May 29, 2024
fe7efa9
Redesign file browser searching (#7130)
sakertooth May 30, 2024
10ba45d
Don't recalculate the song length for every added TCO while loading (…
softrabbit May 30, 2024
090bcd6
Add macOS arm64 builds (#7285)
tresf May 31, 2024
1bd9709
fixed position line disappearing when zoomed out (#7296)
BoredGuy1 May 31, 2024
ecc8a66
Resizable mixer channels/strips (#7293)
michaelgregorius May 31, 2024
2ae9ad4
Adjust rendering of BarModelEditor (#7299)
michaelgregorius May 31, 2024
7d00c7c
Add peak indicators (#7295)
michaelgregorius Jun 1, 2024
4eb16a8
Change the wording of Instrument Plugin Dialogue (#7301)
AW1534 Jun 1, 2024
5a2d89d
Modernize compiler and linker flags (#7255)
Rossmaxx Jun 2, 2024
204490e
Merge branch 'master' into valuebuffer-removal
Rossmaxx Jun 15, 2024
2e8375d
remove vector include
Rossmaxx Jun 15, 2024
ac25875
code review
Rossmaxx Jun 15, 2024
18b31bb
partially revert previous commit because of issues
Rossmaxx Jun 15, 2024
2638d33
one more suggestion from saker
Rossmaxx Jun 15, 2024
0e897ca
Revert "one more suggestion from saker"
Rossmaxx Jun 15, 2024
f42cd93
moved valueAt to the header
Rossmaxx Jun 15, 2024
f1f6720
fix compilation on bass booster
Rossmaxx Jun 15, 2024
e248d66
fix delay too.
Rossmaxx Jun 15, 2024
577c7ce
Missed a db2lin call
Rossmaxx Jun 19, 2024
d6b6922
Hopefully this fixes the macro
Rossmaxx Jun 19, 2024
0af9a0e
clamping + const
Rossmaxx Jun 21, 2024
ba96005
Merge branch 'LMMS:master' into valuebuffer-removal
Rossmaxx Jun 21, 2024
406b2c6
unconst it
Rossmaxx Jun 21, 2024
1a86d69
missed a ;
Rossmaxx Jun 21, 2024
1148c6c
fix clamping type deduction error
Rossmaxx Jun 27, 2024
147d7f4
Style format `DrumSynth` (#7189)
Monospace-V Jun 22, 2024
20bdaf4
Fix MSVC warnings up to level 2 (#7329)
DomClark Jun 22, 2024
f72b81e
Remove `MemoryHelper` (#7335)
Rossmaxx Jun 24, 2024
4e056e8
Fix uninitialized compressor values (#7343)
LostRobotMusic Jun 24, 2024
d2b7318
Add Granular Pitch Shifter effect (#7328)
LostRobotMusic Jun 26, 2024
6b5769b
Fix pitch shifter glide 0 division (#7348)
LostRobotMusic Jun 26, 2024
fe76398
Fix bad Granular Pitch Shifter init values (#7354)
LostRobotMusic Jun 27, 2024
6a826d2
granular pitch shifter
Rossmaxx Jun 27, 2024
591e9c1
Merge branch 'master' into valuebuffer-removal
Rossmaxx Jun 27, 2024
a3c7968
attempted fix at msvc "import"
Rossmaxx Jun 27, 2024
0887831
Add inline.
Rossmaxx Jun 29, 2024
0da8581
Revert "Add inline."
JohannesLorenz Jun 29, 2024
c5e21b7
Attempt to fix Windows linker issue
JohannesLorenz Jun 29, 2024
338d8ee
Fixup
JohannesLorenz Jun 29, 2024
ba81dbb
remove unimplemented valueAt function from AutomatableModel class
Rossmaxx Jul 1, 2024
e963217
Merge branch 'master' into valuebuffer-removal
Rossmaxx Jul 1, 2024
f146ef1
Try reverting johannes' fix
Rossmaxx Jul 1, 2024
b314702
insignificant newline changes to reduce diff
Rossmaxx Jul 1, 2024
fec2d73
remove mingw-std-threads
Rossmaxx Jul 1, 2024
2343636
it's float
Rossmaxx Jul 1, 2024
d420beb
fix reading null buffer concerns
Rossmaxx Jul 1, 2024
c1824d3
use assert
Rossmaxx Jul 1, 2024
da540a8
remove extra args. this might fix it
Rossmaxx Jul 1, 2024
cc17ebe
minor fixup on assert
Rossmaxx Jul 1, 2024
9718dde
Revert "Try reverting johannes' fix"
Rossmaxx Jul 1, 2024
b3366b1
added header
Rossmaxx Jul 1, 2024
649e7ef
Whitespace style fixups
Rossmaxx Jul 1, 2024
05b6e74
This should fix it
Rossmaxx Jul 2, 2024
dd9f963
invalid fix revert
Rossmaxx Jul 3, 2024
a444185
Revert johannes' fix again
Rossmaxx Jul 3, 2024
80eb248
remove extra vb
Rossmaxx Jul 3, 2024
60696b5
I'll try messmerd's function
Rossmaxx Jul 3, 2024
f41eb55
Remove usage of data() where not needed
Rossmaxx Jul 3, 2024
477cbee
moved 2 lines below in waveshaper
Rossmaxx Jul 3, 2024
7043718
remove usage of data() in peakcontroller
Rossmaxx Jul 3, 2024
9e0c928
typo fix
Rossmaxx Jul 3, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 12 additions & 3 deletions include/AutomatableModel.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
#include "JournallingObject.h"
#include "Model.h"
#include "TimePos.h"
#include "ValueBuffer.h"
#include "ModelVisitor.h"


Expand Down Expand Up @@ -174,7 +173,7 @@ class LMMS_EXPORT AutomatableModel : public Model, public JournallingObject

//! @brief Function that returns sample-exact data as a ValueBuffer
//! @return pointer to model's valueBuffer when s.ex.data exists, NULL otherwise
ValueBuffer * valueBuffer();
std::vector<float>* valueBuffer();

template<class T>
T initValue() const
Expand Down Expand Up @@ -210,6 +209,9 @@ class LMMS_EXPORT AutomatableModel : public Model, public JournallingObject
//! @brief Returns value applied with the inverse of this model's scale type
float inverseScaledValue( float value ) const;

//! @brief Returns the value at a buffer, if buffer not exists, returns fixed value
float valueAt(size_t index);
Rossmaxx marked this conversation as resolved.
Show resolved Hide resolved

void setInitValue( const float value );

void setAutomatedValue( const float value );
Expand Down Expand Up @@ -406,7 +408,7 @@ public slots:
ControllerConnection* m_controllerConnection;


ValueBuffer m_valueBuffer;
std::vector<float> m_valueBuffer;
long m_lastUpdatedPeriod;
static long s_periodCounter;

Expand Down Expand Up @@ -435,6 +437,13 @@ template <typename T> class LMMS_EXPORT TypedAutomatableModel : public Automatab
return AutomatableModel::value<T>( frameOffset );
}

float valueAt(size_t index, int frameOffset = 0)
{
const auto buffer = valueBuffer();
size_t clampedIndex = std::clamp<size_t>(index, 0, buffer->size());
return buffer ? (*buffer)[clampedIndex] : value(frameOffset);
Rossmaxx marked this conversation as resolved.
Show resolved Hide resolved
}

T initValue() const
{
return AutomatableModel::initValue<T>();
Expand Down
5 changes: 2 additions & 3 deletions include/Controller.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
#include "Engine.h"
#include "Model.h"
#include "JournallingObject.h"
#include "ValueBuffer.h"

namespace lmms
{
Expand Down Expand Up @@ -70,7 +69,7 @@ class LMMS_EXPORT Controller : public Model, public JournallingObject

virtual float currentValue( int _offset );
// The per-controller get-value-in-buffers function
virtual ValueBuffer * valueBuffer();
virtual std::vector<float>* valueBuffer();

inline bool isSampleExact() const
{
Expand Down Expand Up @@ -155,7 +154,7 @@ public slots:
// buffer for storing sample-exact values in case there
// are more than one model wanting it, so we don't have to create it
// again every time
ValueBuffer m_valueBuffer;
std::vector<float> m_valueBuffer;
// when we last updated the valuebuffer - so we know if we have to update it
long m_bufferLastUpdated;

Expand Down
3 changes: 1 addition & 2 deletions include/ControllerConnection.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@

#include "Controller.h"
#include "JournallingObject.h"
#include "ValueBuffer.h"

#include <vector>

Expand Down Expand Up @@ -73,7 +72,7 @@ class LMMS_EXPORT ControllerConnection : public QObject, public JournallingObjec
return m_controller->currentValue( _offset );
}

ValueBuffer * valueBuffer()
std::vector<float>* valueBuffer()
{
return m_controller->valueBuffer();
}
Expand Down
3 changes: 1 addition & 2 deletions include/LadspaControl.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@

#include "AutomatableModel.h"
#include "TempoSyncKnobModel.h"
#include "ValueBuffer.h"

namespace lmms
{
Expand All @@ -55,7 +54,7 @@ class LMMS_EXPORT LadspaControl : public Model, public JournallingObject
~LadspaControl() override = default;

LADSPA_Data value();
ValueBuffer * valueBuffer();
std::vector<float>* valueBuffer();
void setValue( LADSPA_Data _value );
void setLink( bool _state );

Expand Down
14 changes: 9 additions & 5 deletions include/MixHelpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@

#include "lmms_basics.h"


namespace lmms
{

class ValueBuffer;
namespace MixHelpers
{

Expand All @@ -55,19 +55,23 @@ void addMultiplied( sampleFrame* dst, const sampleFrame* src, float coeffSrc, in
void addSwappedMultiplied( sampleFrame* dst, const sampleFrame* src, float coeffSrc, int frames );

/*! \brief Add samples from src multiplied by coeffSrc and coeffSrcBuf to dst */
void addMultipliedByBuffer( sampleFrame* dst, const sampleFrame* src, float coeffSrc, ValueBuffer * coeffSrcBuf, int frames );
void addMultipliedByBuffer(sampleFrame* dst, const sampleFrame* src, float coeffSrc,
float* coeffSrcBuf, int frames);

/*! \brief Add samples from src multiplied by coeffSrc and coeffSrcBuf to dst */
void addMultipliedByBuffers( sampleFrame* dst, const sampleFrame* src, ValueBuffer * coeffSrcBuf1, ValueBuffer * coeffSrcBuf2, int frames );
void addMultipliedByBuffers(sampleFrame* dst, const sampleFrame* src,
float* coeffSrcBuf1, float* coeffSrcBuf2, int frames);

/*! \brief Same as addMultiplied, but sanitize output (strip out infs/nans) */
void addSanitizedMultiplied( sampleFrame* dst, const sampleFrame* src, float coeffSrc, int frames );

/*! \brief Add samples from src multiplied by coeffSrc and coeffSrcBuf to dst - sanitized version */
void addSanitizedMultipliedByBuffer( sampleFrame* dst, const sampleFrame* src, float coeffSrc, ValueBuffer * coeffSrcBuf, int frames );
void addSanitizedMultipliedByBuffer(sampleFrame* dst, const sampleFrame* src, float coeffSrc,
float* coeffSrcBuf, int frames);

/*! \brief Add samples from src multiplied by coeffSrc and coeffSrcBuf to dst - sanitized version */
void addSanitizedMultipliedByBuffers( sampleFrame* dst, const sampleFrame* src, ValueBuffer * coeffSrcBuf1, ValueBuffer * coeffSrcBuf2, int frames );
void addSanitizedMultipliedByBuffers(sampleFrame* dst, const sampleFrame* src,
float* coeffSrcBuf1, float* coeffSrcBuf2, int frames);

/*! \brief Add samples from src multiplied by coeffSrcLeft/coeffSrcRight to dst */
void addMultipliedStereo( sampleFrame* dst, const sampleFrame* src, float coeffSrcLeft, float coeffSrcRight, int frames );
Expand Down
58 changes: 0 additions & 58 deletions include/ValueBuffer.h

This file was deleted.

17 changes: 7 additions & 10 deletions plugins/Amplifier/Amplifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
#include "embed.h"
#include "plugin_export.h"

#include <cmath>

namespace lmms
{

Expand Down Expand Up @@ -65,17 +67,12 @@ bool AmplifierEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frames)
const float d = dryLevel();
const float w = wetLevel();

const ValueBuffer* volumeBuf = m_ampControls.m_volumeModel.valueBuffer();
const ValueBuffer* panBuf = m_ampControls.m_panModel.valueBuffer();
const ValueBuffer* leftBuf = m_ampControls.m_leftModel.valueBuffer();
const ValueBuffer* rightBuf = m_ampControls.m_rightModel.valueBuffer();

for (fpp_t f = 0; f < frames; ++f)
for (size_t f = 0; f < frames; ++f)
{
const float volume = (volumeBuf ? volumeBuf->value(f) : m_ampControls.m_volumeModel.value()) * 0.01f;
const float pan = (panBuf ? panBuf->value(f) : m_ampControls.m_panModel.value()) * 0.01f;
const float left = (leftBuf ? leftBuf->value(f) : m_ampControls.m_leftModel.value()) * 0.01f;
const float right = (rightBuf ? rightBuf->value(f) : m_ampControls.m_rightModel.value()) * 0.01f;
const float volume = m_ampControls.m_volumeModel.valueAt(f) * 0.01f;
const float pan = m_ampControls.m_panModel.valueAt(f) * 0.01f;
const float left = m_ampControls.m_leftModel.valueAt(f) * 0.01f;
const float right = m_ampControls.m_rightModel.valueAt(f) * 0.01f;

const float panLeft = std::min(1.0f, 1.0f - pan);
const float panRight = std::min(1.0f, 1.0f + pan);
Expand Down
6 changes: 3 additions & 3 deletions plugins/BassBooster/BassBooster.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,18 +85,18 @@ bool BassBoosterEffect::processAudioBuffer( sampleFrame* buf, const fpp_t frames
if( m_bbControls.m_ratioModel.isValueChanged() ) { changeRatio(); }

const float const_gain = m_bbControls.m_gainModel.value();
const ValueBuffer *gainBuffer = m_bbControls.m_gainModel.valueBuffer();
const auto* gainBuffer = m_bbControls.m_gainModel.valueBuffer();
Rossmaxx marked this conversation as resolved.
Show resolved Hide resolved

double outSum = 0.0;
const float d = dryLevel();
const float w = wetLevel();

for( fpp_t f = 0; f < frames; ++f )
for(size_t f = 0; f < frames; ++f)
{
float gain = const_gain;
if (gainBuffer) {
//process period using sample exact data
gain = gainBuffer->value( f );
gain = m_bbControls.m_gainModel.valueAt(f);
}
//float gain = gainBuffer ? gainBuffer[f] : gain;
m_bbFX.leftFX().setGain( gain );
Expand Down
16 changes: 8 additions & 8 deletions plugins/Delay/DelayEffect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,18 +98,18 @@ bool DelayEffect::processAudioBuffer( sampleFrame* buf, const fpp_t frames )
float amplitude = m_delayControls.m_lfoAmountModel.value() * sr;
float lfoTime = 1.0 / m_delayControls.m_lfoTimeModel.value();
float feedback = m_delayControls.m_feedbackModel.value();
ValueBuffer *lengthBuffer = m_delayControls.m_delayTimeModel.valueBuffer();
ValueBuffer *feedbackBuffer = m_delayControls.m_feedbackModel.valueBuffer();
ValueBuffer *lfoTimeBuffer = m_delayControls.m_lfoTimeModel.valueBuffer();
ValueBuffer *lfoAmountBuffer = m_delayControls.m_lfoAmountModel.valueBuffer();
auto* lengthBuffer = m_delayControls.m_delayTimeModel.valueBuffer();
auto* lfoAmountBuffer = m_delayControls.m_lfoAmountModel.valueBuffer();
auto* feedbackBuffer = m_delayControls.m_feedbackModel.valueBuffer();
auto* lfoTimeBuffer = m_delayControls.m_lfoTimeModel.valueBuffer();
int lengthInc = lengthBuffer ? 1 : 0;
int amplitudeInc = lfoAmountBuffer ? 1 : 0;
int lfoTimeInc = lfoTimeBuffer ? 1 : 0;
int feedbackInc = feedbackBuffer ? 1 : 0;
float *lengthPtr = lengthBuffer ? &( lengthBuffer->values()[ 0 ] ) : &length;
float *amplitudePtr = lfoAmountBuffer ? &( lfoAmountBuffer->values()[ 0 ] ) : &amplitude;
float *lfoTimePtr = lfoTimeBuffer ? &( lfoTimeBuffer->values()[ 0 ] ) : &lfoTime;
float *feedbackPtr = feedbackBuffer ? &( feedbackBuffer->values()[ 0 ] ) : &feedback;
float* lengthPtr = lengthBuffer ? lengthBuffer->data() : &length;
float* amplitudePtr = lfoAmountBuffer ? lfoAmountBuffer->data() : &amplitude;
float* lfoTimePtr = lfoTimeBuffer ? lfoTimeBuffer->data() : &lfoTime;
float* feedbackPtr = feedbackBuffer ? feedbackBuffer->data() : &feedback;

if( m_delayControls.m_outGainModel.isValueChanged() )
{
Expand Down
28 changes: 14 additions & 14 deletions plugins/DualFilter/DualFilter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,13 +107,13 @@ bool DualFilterEffect::processAudioBuffer( sampleFrame* buf, const fpp_t frames
float gain2 = m_dfControls.m_gain2Model.value();
float mix = m_dfControls.m_mixModel.value();

ValueBuffer *cut1Buffer = m_dfControls.m_cut1Model.valueBuffer();
ValueBuffer *res1Buffer = m_dfControls.m_res1Model.valueBuffer();
ValueBuffer *gain1Buffer = m_dfControls.m_gain1Model.valueBuffer();
ValueBuffer *cut2Buffer = m_dfControls.m_cut2Model.valueBuffer();
ValueBuffer *res2Buffer = m_dfControls.m_res2Model.valueBuffer();
ValueBuffer *gain2Buffer = m_dfControls.m_gain2Model.valueBuffer();
ValueBuffer *mixBuffer = m_dfControls.m_mixModel.valueBuffer();
auto* cut1Buffer = m_dfControls.m_cut1Model.valueBuffer();
auto* res1Buffer = m_dfControls.m_res1Model.valueBuffer();
auto* gain1Buffer = m_dfControls.m_gain1Model.valueBuffer();
auto* cut2Buffer = m_dfControls.m_cut2Model.valueBuffer();
auto* res2Buffer = m_dfControls.m_res2Model.valueBuffer();
auto* gain2Buffer = m_dfControls.m_gain2Model.valueBuffer();
auto* mixBuffer = m_dfControls.m_mixModel.valueBuffer();
Rossmaxx marked this conversation as resolved.
Show resolved Hide resolved

int cut1Inc = cut1Buffer ? 1 : 0;
int res1Inc = res1Buffer ? 1 : 0;
Expand All @@ -123,13 +123,13 @@ bool DualFilterEffect::processAudioBuffer( sampleFrame* buf, const fpp_t frames
int gain2Inc = gain2Buffer ? 1 : 0;
int mixInc = mixBuffer ? 1 : 0;

float *cut1Ptr = cut1Buffer ? &( cut1Buffer->values()[ 0 ] ) : &cut1;
float *res1Ptr = res1Buffer ? &( res1Buffer->values()[ 0 ] ) : &res1;
float *gain1Ptr = gain1Buffer ? &( gain1Buffer->values()[ 0 ] ) : &gain1;
float *cut2Ptr = cut2Buffer ? &( cut2Buffer->values()[ 0 ] ) : &cut2;
float *res2Ptr = res2Buffer ? &( res2Buffer->values()[ 0 ] ) : &res2;
float *gain2Ptr = gain2Buffer ? &( gain2Buffer->values()[ 0 ] ) : &gain2;
float *mixPtr = mixBuffer ? &( mixBuffer->values()[ 0 ] ) : &mix;
float* cut1Ptr = cut1Buffer ? cut1Buffer->data() : &cut1;
float* res1Ptr = res1Buffer ? res1Buffer->data() : &res1;
float* gain1Ptr = gain1Buffer ? gain1Buffer->data() : &gain1;
float* cut2Ptr = cut2Buffer ? cut2Buffer->data() : &cut2;
float* res2Ptr = res2Buffer ? res2Buffer->data() : &res2;
float* gain2Ptr = gain2Buffer ? gain2Buffer->data() : &gain2;
float* mixPtr = mixBuffer ? mixBuffer->data() : &mix;

const bool enabled1 = m_dfControls.m_enabled1Model.value();
const bool enabled2 = m_dfControls.m_enabled2Model.value();
Expand Down
8 changes: 3 additions & 5 deletions plugins/GranularPitchShifter/GranularPitchShifterEffect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,193 +60,191 @@
}


bool GranularPitchShifterEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frames)
{
if (!isEnabled() || !isRunning()) { return false; }

const float d = dryLevel();
const float w = wetLevel();

const ValueBuffer* pitchBuf = m_granularpitchshifterControls.m_pitchModel.valueBuffer();
const ValueBuffer* pitchSpreadBuf = m_granularpitchshifterControls.m_pitchSpreadModel.valueBuffer();

const float size = m_granularpitchshifterControls.m_sizeModel.value();
const float shape = m_granularpitchshifterControls.m_shapeModel.value();
const float jitter = m_granularpitchshifterControls.m_jitterModel.value();
const float twitch = m_granularpitchshifterControls.m_twitchModel.value();
const float spray = m_granularpitchshifterControls.m_sprayModel.value();
const float spraySpread = m_granularpitchshifterControls.m_spraySpreadModel.value();
const float density = m_granularpitchshifterControls.m_densityModel.value();
const float glide = m_granularpitchshifterControls.m_glideModel.value();
const int minLatency = m_granularpitchshifterControls.m_minLatencyModel.value() * m_sampleRate;
const float densityInvRoot = std::sqrt(1.f / density);
const float feedback = m_granularpitchshifterControls.m_feedbackModel.value();
const float fadeLength = 1.f / m_granularpitchshifterControls.m_fadeLengthModel.value();
const bool prefilter = m_granularpitchshifterControls.m_prefilterModel.value();

if (glide != m_oldGlide)
{
m_oldGlide = glide;
m_glideCoef = glide > 0 ? std::exp(-1 / (glide * m_sampleRate)) : 0;
}

const float shapeK = cosWindowApproxK(shape);
const int sizeSamples = m_sampleRate / size;
const float waitMult = sizeSamples / (density * 2);

for (fpp_t f = 0; f < frames; ++f)
{
const double pitch = (pitchBuf ? pitchBuf->value(f) : m_granularpitchshifterControls.m_pitchModel.value()) * (1. / 12.);
const double pitchSpread = (pitchSpreadBuf ? pitchSpreadBuf->value(f) : m_granularpitchshifterControls.m_pitchSpreadModel.value()) * (1. / 24.);
const double pitch = m_granularpitchshifterControls.m_pitchModel.valueAt(f) * (1. / 12.);
Rossmaxx marked this conversation as resolved.
Show resolved Hide resolved
const double pitchSpread = m_granularpitchshifterControls.m_pitchSpreadModel.valueAt(f) * (1. / 24.);


// interpolate pitch depending on glide
for (int i = 0; i < 2; ++i)
{
double targetVal = pitch + pitchSpread * (i ? 1. : -1.);

if (targetVal == m_truePitch[i]) { continue; }
m_updatePitches = true;

m_truePitch[i] = m_glideCoef * m_truePitch[i] + (1. - m_glideCoef) * targetVal;
// we crudely lock the pitch to the target value once it gets close enough, so we can save on CPU
if (std::abs(targetVal - m_truePitch[i]) < GlideSnagRadius) { m_truePitch[i] = targetVal; }
}

// this stuff is computationally expensive, so we should only do it when necessary
if (m_updatePitches)
{
m_updatePitches = false;

std::array<double, 2> speed = {
std::exp2(m_truePitch[0]),
std::exp2(m_truePitch[1])
};
std::array<double, 2> ratio = {
speed[0] / m_speed[0],
speed[1] / m_speed[1]
};

for (int i = 0; i < m_grainCount; ++i)
{
for (int j = 0; j < 2; ++j)
{
m_grains[i].grainSpeed[j] *= ratio[j];

// we unfortunately need to do extra stuff to ensure these don't shoot past the write index...
if (m_grains[i].grainSpeed[j] > 1)
{
double distance = m_writePoint - m_grains[i].readPoint[j] - SafetyLatency;
if (distance <= 0) { distance += m_ringBufLength; }
double grainSpeedRequired = ((m_grains[i].grainSpeed[j] - 1.) / distance) * (1. - m_grains[i].phase);
m_grains[i].phaseSpeed[j] = std::max(m_grains[i].phaseSpeed[j], grainSpeedRequired);
}
}
}
m_speed[0] = speed[0];
m_speed[1] = speed[1];

// prevent aliasing by lowpassing frequencies that the pitch shifting would push above nyquist
m_prefilter[0].setCoefs(m_sampleRate, std::min(m_nyquist / static_cast<float>(speed[0]), m_nyquist) * PrefilterBandwidth);
m_prefilter[1].setCoefs(m_sampleRate, std::min(m_nyquist / static_cast<float>(speed[1]), m_nyquist) * PrefilterBandwidth);
}

std::array<float, 2> s = {0, 0};
std::array<float, 2> filtered = {buf[f][0], buf[f][1]};

// spawn a new grain if it's time
if (++m_timeSinceLastGrain >= m_nextWaitRandomization * waitMult)
{
m_timeSinceLastGrain = 0;
double randThing = (fast_rand()/static_cast<double>(FAST_RAND_MAX) * 2. - 1.);
m_nextWaitRandomization = std::exp2(randThing * twitch);
double grainSpeed = 1. / std::exp2(randThing * jitter);

std::array<float, 2> sprayResult = {0, 0};
if (spray > 0)
{
sprayResult[0] = (fast_rand() / static_cast<float>(FAST_RAND_MAX)) * spray * m_sampleRate;
sprayResult[1] = linearInterpolate(
sprayResult[0],
(fast_rand() / static_cast<float>(FAST_RAND_MAX)) * spray * m_sampleRate,
spraySpread);
}

std::array<int, 2> readPoint;
int latency = std::max(static_cast<int>(std::max(sizeSamples * (std::max(m_speed[0], m_speed[1]) * grainSpeed - 1.), 0.) + SafetyLatency), minLatency);
for (int i = 0; i < 2; ++i)
{
readPoint[i] = m_writePoint - latency - sprayResult[i];
if (readPoint[i] < 0) { readPoint[i] += m_ringBufLength; }
}
const double phaseInc = 1. / sizeSamples;
m_grains.push_back(Grain(grainSpeed * m_speed[0], grainSpeed * m_speed[1], phaseInc, phaseInc, readPoint[0], readPoint[1]));
++m_grainCount;
}

for (int i = 0; i < m_grainCount; ++i)
{
m_grains[i].phase += std::max(m_grains[i].phaseSpeed[0], m_grains[i].phaseSpeed[1]);
if (m_grains[i].phase >= 1)
{
// grain is done, delete it
std::swap(m_grains[i], m_grains[m_grainCount-1]);
m_grains.pop_back();
--i;
--m_grainCount;
continue;
}

m_grains[i].readPoint[0] += m_grains[i].grainSpeed[0];
m_grains[i].readPoint[1] += m_grains[i].grainSpeed[1];
if (m_grains[i].readPoint[0] >= m_ringBufLength) { m_grains[i].readPoint[0] -= m_ringBufLength; }
if (m_grains[i].readPoint[1] >= m_ringBufLength) { m_grains[i].readPoint[1] -= m_ringBufLength; }

const float fadePos = std::clamp((-std::abs(-2.f * static_cast<float>(m_grains[i].phase) + 1.f) + 0.5f) * fadeLength + 0.5f, 0.f, 1.f);
const float windowVal = cosHalfWindowApprox(fadePos, shapeK);
s[0] += getHermiteSample(m_grains[i].readPoint[0], 0) * windowVal;
s[1] += getHermiteSample(m_grains[i].readPoint[1], 1) * windowVal;
}

// note that adding two signals together, when uncorrelated, results in a signal power multiplication of sqrt(2), not 2
s[0] *= densityInvRoot;
s[1] *= densityInvRoot;

// 1-pole highpass for DC offset removal, to make feedback safer
s[0] -= (m_dcVal[0] = (1.f - m_dcCoeff) * s[0] + m_dcCoeff * m_dcVal[0]);
s[1] -= (m_dcVal[1] = (1.f - m_dcCoeff) * s[1] + m_dcCoeff * m_dcVal[1]);

// cheap safety saturator to protect against infinite feedback
if (feedback > 0)
{
s[0] = safetySaturate(s[0]);
s[1] = safetySaturate(s[1]);
}

if (++m_writePoint >= m_ringBufLength)
{
m_writePoint = 0;
}
if (prefilter)
{
filtered[0] = m_prefilter[0].process(filtered[0]);
filtered[1] = m_prefilter[1].process(filtered[1]);
}

m_ringBuf[m_writePoint][0] = filtered[0] + s[0] * feedback;
m_ringBuf[m_writePoint][1] = filtered[1] + s[1] * feedback;

buf[f][0] = d * buf[f][0] + w * s[0];
buf[f][1] = d * buf[f][1] + w * s[1];
}

if (m_sampleRateNeedsUpdate)
{
m_sampleRateNeedsUpdate = false;
changeSampleRate();
}

return isRunning();
}

Check notice on line 247 in plugins/GranularPitchShifter/GranularPitchShifterEffect.cpp

View check run for this annotation

codefactor.io / CodeFactor

plugins/GranularPitchShifter/GranularPitchShifterEffect.cpp#L63-L247

Complex Method

void GranularPitchShifterEffect::changeSampleRate()
{
Expand Down
5 changes: 2 additions & 3 deletions plugins/LadspaEffect/LadspaEffect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
#include "LadspaControl.h"
#include "LadspaSubPluginFeatures.h"
#include "AutomationClip.h"
#include "ValueBuffer.h"
#include "Song.h"

#include "embed.h"
Expand Down Expand Up @@ -173,10 +172,10 @@ bool LadspaEffect::processAudioBuffer( sampleFrame * _buf,
break;
case BufferRate::AudioRateInput:
{
ValueBuffer * vb = pp->control->valueBuffer();
auto* vb = pp->control->valueBuffer();
if( vb )
{
memcpy( pp->buffer, vb->values(), frames * sizeof(float) );
memcpy(pp->buffer, vb->data(), frames * sizeof(float));
}
else
{
Expand Down
Loading
Loading