Skip to content

Commit

Permalink
Move common effect processing code to wrapper method
Browse files Browse the repository at this point in the history
- Introduce `processImpl` and `sleepImpl` methods, and adapt each effect
plugin to use them
- Use double for RMS out sum in Compressor and LOMM
- Run `checkGate` for GranularPitchShifterEffect
- Minor changes to LadspaEffect
- Remove dynamic allocations and VLAs from VstEffect's process method
- Some minor style/formatting fixes
  • Loading branch information
messmerd committed Sep 2, 2024
1 parent 35f350e commit a7e8af6
Show file tree
Hide file tree
Showing 51 changed files with 263 additions and 354 deletions.
5 changes: 3 additions & 2 deletions include/DummyEffect.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ class DummyEffect : public Effect
m_originalPluginData( originalPluginData )
{
setName();
setDontRun(true);
}

~DummyEffect() override = default;
Expand All @@ -107,9 +108,9 @@ class DummyEffect : public Effect
return &m_controls;
}

bool processAudioBuffer( SampleFrame*, const fpp_t ) override
double processImpl(SampleFrame*, const fpp_t) override
{
return false;
return -1.0;
}

const QDomElement& originalPluginData() const
Expand Down
33 changes: 24 additions & 9 deletions include/Effect.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,8 @@ class LMMS_EXPORT Effect : public Plugin
return "effect";
}


virtual bool processAudioBuffer( SampleFrame* _buf,
const fpp_t _frames ) = 0;
//! Returns true if audio was processed and should continue being processed
bool processAudioBuffer(SampleFrame* buf, const fpp_t frames);

inline ch_cnt_t processorCount() const
{
Expand Down Expand Up @@ -175,13 +174,19 @@ class LMMS_EXPORT Effect : public Plugin

protected:
/**
Effects should call this at the end of audio processing
* The main audio processing method that runs when plugin is not asleep
*
* Returns the RMS output sum for use by `checkGate`,
* or -1.0 if `checkGate` should not be called
*/
virtual double processImpl(SampleFrame* buf, const fpp_t frames) = 0;

/**
* Optional method that runs when plugin is sleeping (not enabled,
* not running, not in the Okay state, or in the Don't Run state)
*/
virtual void sleepImpl() {}

If the setting "Keep effects running even without input" is disabled,
after "decay" ms of a signal below "gate", the effect is turned off
and won't be processed again until it receives new audio input
*/
void checkGate( double _out_sum );

gui::PluginView* instantiateView( QWidget * ) override;

Expand Down Expand Up @@ -212,6 +217,16 @@ class LMMS_EXPORT Effect : public Plugin


private:
/**
Effects should call this at the end of audio processing
If the setting "Keep effects running even without input" is disabled,
after "decay" ms of a signal below "gate", the effect is turned off
and won't be processed again until it receives new audio input
*/
void checkGate( double _out_sum );


EffectChain * m_parent;
void resample( int _i, const SampleFrame* _src_buf,
sample_rate_t _src_sr,
Expand Down
8 changes: 2 additions & 6 deletions plugins/Amplifier/Amplifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,8 @@ AmplifierEffect::AmplifierEffect(Model* parent, const Descriptor::SubPluginFeatu
}


bool AmplifierEffect::processAudioBuffer(SampleFrame* buf, const fpp_t frames)
double AmplifierEffect::processImpl(SampleFrame* buf, const fpp_t frames)
{
if (!isEnabled() || !isRunning()) { return false ; }

double outSum = 0.0;
const float d = dryLevel();
const float w = wetLevel();
Expand Down Expand Up @@ -90,9 +88,7 @@ bool AmplifierEffect::processAudioBuffer(SampleFrame* buf, const fpp_t frames)
outSum += currentFrame.sumOfSquaredAmplitudes();
}

checkGate(outSum / frames);

return isRunning();
return outSum;
}


Expand Down
3 changes: 2 additions & 1 deletion plugins/Amplifier/Amplifier.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ class AmplifierEffect : public Effect
public:
AmplifierEffect(Model* parent, const Descriptor::SubPluginFeatures::Key* key);
~AmplifierEffect() override = default;
bool processAudioBuffer(SampleFrame* buf, const fpp_t frames) override;

double processImpl(SampleFrame* buf, const fpp_t frames) override;

EffectControls* controls() override
{
Expand Down
10 changes: 2 additions & 8 deletions plugins/BassBooster/BassBooster.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,8 @@ BassBoosterEffect::BassBoosterEffect( Model* parent, const Descriptor::SubPlugin



bool BassBoosterEffect::processAudioBuffer( SampleFrame* buf, const fpp_t frames )
double BassBoosterEffect::processImpl(SampleFrame* buf, const fpp_t frames)
{
if( !isEnabled() || !isRunning () )
{
return( false );
}
// check out changed controls
if( m_frequencyChangeNeeded || m_bbControls.m_freqModel.isValueChanged() )
{
Expand Down Expand Up @@ -106,9 +102,7 @@ bool BassBoosterEffect::processAudioBuffer( SampleFrame* buf, const fpp_t frames
outSum += currentFrame.sumOfSquaredAmplitudes();
}

checkGate( outSum / frames );

return isRunning();
return outSum;
}


Expand Down
3 changes: 2 additions & 1 deletion plugins/BassBooster/BassBooster.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ class BassBoosterEffect : public Effect
public:
BassBoosterEffect( Model* parent, const Descriptor::SubPluginFeatures::Key* key );
~BassBoosterEffect() override = default;
bool processAudioBuffer( SampleFrame* buf, const fpp_t frames ) override;

double processImpl(SampleFrame* buf, const fpp_t frames) override;

EffectControls* controls() override
{
Expand Down
13 changes: 3 additions & 10 deletions plugins/Bitcrush/Bitcrush.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,13 +100,8 @@ inline float BitcrushEffect::noise( float amt )
return fastRandf( amt * 2.0f ) - amt;
}

bool BitcrushEffect::processAudioBuffer( SampleFrame* buf, const fpp_t frames )
double BitcrushEffect::processImpl(SampleFrame* buf, const fpp_t frames)
{
if( !isEnabled() || !isRunning () )
{
return( false );
}

// update values
if( m_needsUpdate || m_controls.m_rateEnabled.isValueChanged() )
{
Expand Down Expand Up @@ -236,12 +231,10 @@ bool BitcrushEffect::processAudioBuffer( SampleFrame* buf, const fpp_t frames )
}
buf[f][0] = d * buf[f][0] + w * qBound( -m_outClip, lsum, m_outClip ) * m_outGain;
buf[f][1] = d * buf[f][1] + w * qBound( -m_outClip, rsum, m_outClip ) * m_outGain;
outSum += buf[f][0]*buf[f][0] + buf[f][1]*buf[f][1];
outSum += buf[f][0] * buf[f][0] + buf[f][1] * buf[f][1];
}

checkGate( outSum / frames );

return isRunning();
return outSum;
}


Expand Down
5 changes: 3 additions & 2 deletions plugins/Bitcrush/Bitcrush.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,14 @@ class BitcrushEffect : public Effect
public:
BitcrushEffect( Model* parent, const Descriptor::SubPluginFeatures::Key* key );
~BitcrushEffect() override;
bool processAudioBuffer( SampleFrame* buf, const fpp_t frames ) override;

double processImpl(SampleFrame* buf, const fpp_t frames) override;

EffectControls* controls() override
{
return &m_controls;
}

private:
void sampleRateChanged();
float depthCrush( float in );
Expand Down
45 changes: 20 additions & 25 deletions plugins/Compressor/Compressor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -233,31 +233,11 @@ void CompressorEffect::calcMix()



bool CompressorEffect::processAudioBuffer(SampleFrame* buf, const fpp_t frames)
double CompressorEffect::processImpl(SampleFrame* buf, const fpp_t frames)
{
if (!isEnabled() || !isRunning())
{
// Clear lookahead buffers and other values when needed
if (!m_cleanedBuffers)
{
m_yL[0] = m_yL[1] = COMP_NOISE_FLOOR;
m_gainResult[0] = m_gainResult[1] = 1;
m_displayPeak[0] = m_displayPeak[1] = COMP_NOISE_FLOOR;
m_displayGain[0] = m_displayGain[1] = COMP_NOISE_FLOOR;
std::fill(std::begin(m_scLookBuf[0]), std::end(m_scLookBuf[0]), COMP_NOISE_FLOOR);
std::fill(std::begin(m_scLookBuf[1]), std::end(m_scLookBuf[1]), COMP_NOISE_FLOOR);
std::fill(std::begin(m_inLookBuf[0]), std::end(m_inLookBuf[0]), 0);
std::fill(std::begin(m_inLookBuf[1]), std::end(m_inLookBuf[1]), 0);
m_cleanedBuffers = true;
}
return false;
}
else
{
m_cleanedBuffers = false;
}
m_cleanedBuffers = false;

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

Expand Down Expand Up @@ -526,15 +506,30 @@ bool CompressorEffect::processAudioBuffer(SampleFrame* buf, const fpp_t frames)
rOutPeak = s[1] > rOutPeak ? s[1] : rOutPeak;
}

checkGate(outSum / frames);
m_compressorControls.m_outPeakL = lOutPeak;
m_compressorControls.m_outPeakR = rOutPeak;
m_compressorControls.m_inPeakL = lInPeak;
m_compressorControls.m_inPeakR = rInPeak;

return isRunning();
return outSum;
}

void CompressorEffect::sleepImpl()
{
// Clear lookahead buffers and other values when needed
if (!m_cleanedBuffers)
{
m_yL[0] = m_yL[1] = COMP_NOISE_FLOOR;
m_gainResult[0] = m_gainResult[1] = 1;
m_displayPeak[0] = m_displayPeak[1] = COMP_NOISE_FLOOR;
m_displayGain[0] = m_displayGain[1] = COMP_NOISE_FLOOR;
std::fill(std::begin(m_scLookBuf[0]), std::end(m_scLookBuf[0]), COMP_NOISE_FLOOR);
std::fill(std::begin(m_scLookBuf[1]), std::end(m_scLookBuf[1]), COMP_NOISE_FLOOR);
std::fill(std::begin(m_inLookBuf[0]), std::end(m_inLookBuf[0]), 0);
std::fill(std::begin(m_inLookBuf[1]), std::end(m_inLookBuf[1]), 0);
m_cleanedBuffers = true;
}
}

// Regular modulo doesn't handle negative numbers correctly. This does.
inline int CompressorEffect::realmod(int k, int n)
Expand Down
4 changes: 3 additions & 1 deletion plugins/Compressor/Compressor.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@ class CompressorEffect : public Effect
public:
CompressorEffect(Model* parent, const Descriptor::SubPluginFeatures::Key* key);
~CompressorEffect() override = default;
bool processAudioBuffer(SampleFrame* buf, const fpp_t frames) override;

double processImpl(SampleFrame* buf, const fpp_t frames) override;
void sleepImpl() override;

EffectControls* controls() override
{
Expand Down
13 changes: 3 additions & 10 deletions plugins/CrossoverEQ/CrossoverEQ.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,13 +89,8 @@ void CrossoverEQEffect::sampleRateChanged()
}


bool CrossoverEQEffect::processAudioBuffer( SampleFrame* buf, const fpp_t frames )
double CrossoverEQEffect::processImpl(SampleFrame* buf, const fpp_t frames)
{
if( !isEnabled() || !isRunning () )
{
return( false );
}

// filters update
if( m_needsUpdate || m_controls.m_xover12.isValueChanged() )
{
Expand Down Expand Up @@ -199,10 +194,8 @@ bool CrossoverEQEffect::processAudioBuffer( SampleFrame* buf, const fpp_t frames
buf[f][1] = d * buf[f][1] + w * m_work[f][1];
outSum += buf[f][0] * buf[f][0] + buf[f][1] * buf[f][1];
}

checkGate( outSum / frames );

return isRunning();

return outSum;
}

void CrossoverEQEffect::clearFilterHistories()
Expand Down
3 changes: 2 additions & 1 deletion plugins/CrossoverEQ/CrossoverEQ.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ class CrossoverEQEffect : public Effect
public:
CrossoverEQEffect( Model* parent, const Descriptor::SubPluginFeatures::Key* key );
~CrossoverEQEffect() override;
bool processAudioBuffer( SampleFrame* buf, const fpp_t frames ) override;

double processImpl(SampleFrame* buf, const fpp_t frames) override;

EffectControls* controls() override
{
Expand Down
10 changes: 3 additions & 7 deletions plugins/Delay/DelayEffect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,12 +81,8 @@ DelayEffect::~DelayEffect()



bool DelayEffect::processAudioBuffer( SampleFrame* buf, const fpp_t frames )
double DelayEffect::processImpl(SampleFrame* buf, const fpp_t frames)
{
if( !isEnabled() || !isRunning () )
{
return( false );
}
double outSum = 0.0;
const float sr = Engine::audioEngine()->outputSampleRate();
const float d = dryLevel();
Expand Down Expand Up @@ -143,11 +139,11 @@ bool DelayEffect::processAudioBuffer( SampleFrame* buf, const fpp_t frames )
lfoTimePtr += lfoTimeInc;
feedbackPtr += feedbackInc;
}
checkGate( outSum / frames );

m_delayControls.m_outPeakL = peak.left();
m_delayControls.m_outPeakR = peak.right();

return isRunning();
return outSum;
}

void DelayEffect::changeSampleRate()
Expand Down
4 changes: 3 additions & 1 deletion plugins/Delay/DelayEffect.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@ class DelayEffect : public Effect
public:
DelayEffect(Model* parent , const Descriptor::SubPluginFeatures::Key* key );
~DelayEffect() override;
bool processAudioBuffer( SampleFrame* buf, const fpp_t frames ) override;

double processImpl(SampleFrame* buf, const fpp_t frames) override;

EffectControls* controls() override
{
return &m_delayControls;
Expand Down
10 changes: 2 additions & 8 deletions plugins/Dispersion/Dispersion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,8 @@ DispersionEffect::DispersionEffect(Model* parent, const Descriptor::SubPluginFea
}


bool DispersionEffect::processAudioBuffer(SampleFrame* buf, const fpp_t frames)
double DispersionEffect::processImpl(SampleFrame* buf, const fpp_t frames)
{
if (!isEnabled() || !isRunning())
{
return false;
}

double outSum = 0.0;
const float d = dryLevel();
const float w = wetLevel();
Expand Down Expand Up @@ -125,8 +120,7 @@ bool DispersionEffect::processAudioBuffer(SampleFrame* buf, const fpp_t frames)
outSum += buf[f][0] * buf[f][0] + buf[f][1] * buf[f][1];
}

checkGate(outSum / frames);
return isRunning();
return outSum;
}


Expand Down
3 changes: 2 additions & 1 deletion plugins/Dispersion/Dispersion.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ class DispersionEffect : public Effect
public:
DispersionEffect(Model* parent, const Descriptor::SubPluginFeatures::Key* key);
~DispersionEffect() override = default;
bool processAudioBuffer(SampleFrame* buf, const fpp_t frames) override;

double processImpl(SampleFrame* buf, const fpp_t frames) override;

EffectControls* controls() override
{
Expand Down
Loading

0 comments on commit a7e8af6

Please sign in to comment.