diff --git a/include/DummyEffect.h b/include/DummyEffect.h index e2e649ab5..718cdc1a1 100644 --- a/include/DummyEffect.h +++ b/include/DummyEffect.h @@ -98,6 +98,7 @@ public: m_originalPluginData( originalPluginData ) { setName(); + setDontRun(true); } ~DummyEffect() override = default; @@ -107,9 +108,9 @@ public: 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 diff --git a/include/Effect.h b/include/Effect.h index 34f8be00a..322969047 100644 --- a/include/Effect.h +++ b/include/Effect.h @@ -63,9 +63,8 @@ public: 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 { @@ -175,13 +174,19 @@ public: 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; @@ -212,6 +217,16 @@ protected: 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, diff --git a/plugins/Amplifier/Amplifier.cpp b/plugins/Amplifier/Amplifier.cpp index 2f4e57f77..005b1e44f 100644 --- a/plugins/Amplifier/Amplifier.cpp +++ b/plugins/Amplifier/Amplifier.cpp @@ -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(); @@ -90,9 +88,7 @@ bool AmplifierEffect::processAudioBuffer(SampleFrame* buf, const fpp_t frames) outSum += currentFrame.sumOfSquaredAmplitudes(); } - checkGate(outSum / frames); - - return isRunning(); + return outSum; } diff --git a/plugins/Amplifier/Amplifier.h b/plugins/Amplifier/Amplifier.h index 8be938001..6c8abac8d 100644 --- a/plugins/Amplifier/Amplifier.h +++ b/plugins/Amplifier/Amplifier.h @@ -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 { diff --git a/plugins/BassBooster/BassBooster.cpp b/plugins/BassBooster/BassBooster.cpp index f12fd6ace..36684ac12 100644 --- a/plugins/BassBooster/BassBooster.cpp +++ b/plugins/BassBooster/BassBooster.cpp @@ -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() ) { @@ -106,9 +102,7 @@ bool BassBoosterEffect::processAudioBuffer( SampleFrame* buf, const fpp_t frames outSum += currentFrame.sumOfSquaredAmplitudes(); } - checkGate( outSum / frames ); - - return isRunning(); + return outSum; } diff --git a/plugins/BassBooster/BassBooster.h b/plugins/BassBooster/BassBooster.h index 64c4e354d..73b8c9822 100644 --- a/plugins/BassBooster/BassBooster.h +++ b/plugins/BassBooster/BassBooster.h @@ -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 { diff --git a/plugins/Bitcrush/Bitcrush.cpp b/plugins/Bitcrush/Bitcrush.cpp index ea1c43acb..2cac638a5 100644 --- a/plugins/Bitcrush/Bitcrush.cpp +++ b/plugins/Bitcrush/Bitcrush.cpp @@ -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() ) { @@ -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; } diff --git a/plugins/Bitcrush/Bitcrush.h b/plugins/Bitcrush/Bitcrush.h index 009c7c02d..e1280a973 100644 --- a/plugins/Bitcrush/Bitcrush.h +++ b/plugins/Bitcrush/Bitcrush.h @@ -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 ); diff --git a/plugins/Compressor/Compressor.cpp b/plugins/Compressor/Compressor.cpp index c04893361..0d05ae538 100755 --- a/plugins/Compressor/Compressor.cpp +++ b/plugins/Compressor/Compressor.cpp @@ -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(); @@ -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) diff --git a/plugins/Compressor/Compressor.h b/plugins/Compressor/Compressor.h index af322de97..89e1fc12b 100755 --- a/plugins/Compressor/Compressor.h +++ b/plugins/Compressor/Compressor.h @@ -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 { diff --git a/plugins/CrossoverEQ/CrossoverEQ.cpp b/plugins/CrossoverEQ/CrossoverEQ.cpp index 2142d040c..f7f83a1c9 100644 --- a/plugins/CrossoverEQ/CrossoverEQ.cpp +++ b/plugins/CrossoverEQ/CrossoverEQ.cpp @@ -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() ) { @@ -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() diff --git a/plugins/CrossoverEQ/CrossoverEQ.h b/plugins/CrossoverEQ/CrossoverEQ.h index 078e51c21..c11e11dc4 100644 --- a/plugins/CrossoverEQ/CrossoverEQ.h +++ b/plugins/CrossoverEQ/CrossoverEQ.h @@ -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 { diff --git a/plugins/Delay/DelayEffect.cpp b/plugins/Delay/DelayEffect.cpp index 4e90c0fa8..06cc7aba8 100644 --- a/plugins/Delay/DelayEffect.cpp +++ b/plugins/Delay/DelayEffect.cpp @@ -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(); @@ -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() diff --git a/plugins/Delay/DelayEffect.h b/plugins/Delay/DelayEffect.h index b7e2cfef0..f62638872 100644 --- a/plugins/Delay/DelayEffect.h +++ b/plugins/Delay/DelayEffect.h @@ -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; diff --git a/plugins/Dispersion/Dispersion.cpp b/plugins/Dispersion/Dispersion.cpp index a2fada615..64cde0e22 100644 --- a/plugins/Dispersion/Dispersion.cpp +++ b/plugins/Dispersion/Dispersion.cpp @@ -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(); @@ -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; } diff --git a/plugins/Dispersion/Dispersion.h b/plugins/Dispersion/Dispersion.h index e3d5d4b5c..cfac487d2 100644 --- a/plugins/Dispersion/Dispersion.h +++ b/plugins/Dispersion/Dispersion.h @@ -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 { diff --git a/plugins/DualFilter/DualFilter.cpp b/plugins/DualFilter/DualFilter.cpp index b337e1003..b396de1a2 100644 --- a/plugins/DualFilter/DualFilter.cpp +++ b/plugins/DualFilter/DualFilter.cpp @@ -77,23 +77,18 @@ DualFilterEffect::~DualFilterEffect() -bool DualFilterEffect::processAudioBuffer( SampleFrame* buf, const fpp_t frames ) +double DualFilterEffect::processImpl(SampleFrame* buf, const fpp_t frames) { - if( !isEnabled() || !isRunning () ) - { - return( false ); - } - double outSum = 0.0; const float d = dryLevel(); const float w = wetLevel(); - if( m_dfControls.m_filter1Model.isValueChanged() || m_filter1changed ) + if( m_dfControls.m_filter1Model.isValueChanged() || m_filter1changed ) { m_filter1->setFilterType( static_cast::FilterType>(m_dfControls.m_filter1Model.value()) ); m_filter1changed = true; } - if( m_dfControls.m_filter2Model.isValueChanged() || m_filter2changed ) + if( m_dfControls.m_filter2Model.isValueChanged() || m_filter2changed ) { m_filter2->setFilterType( static_cast::FilterType>(m_dfControls.m_filter2Model.value()) ); m_filter2changed = true; @@ -213,9 +208,7 @@ bool DualFilterEffect::processAudioBuffer( SampleFrame* buf, const fpp_t frames mixPtr += mixInc; } - checkGate( outSum / frames ); - - return isRunning(); + return outSum; } void DualFilterEffect::onEnabledChanged() diff --git a/plugins/DualFilter/DualFilter.h b/plugins/DualFilter/DualFilter.h index 6c53f61ef..ca46383ba 100644 --- a/plugins/DualFilter/DualFilter.h +++ b/plugins/DualFilter/DualFilter.h @@ -40,7 +40,8 @@ class DualFilterEffect : public Effect public: DualFilterEffect( Model* parent, const Descriptor::SubPluginFeatures::Key* key ); ~DualFilterEffect() override; - bool processAudioBuffer( SampleFrame* buf, const fpp_t frames ) override; + + double processImpl(SampleFrame* buf, const fpp_t frames) override; EffectControls* controls() override { diff --git a/plugins/DynamicsProcessor/DynamicsProcessor.cpp b/plugins/DynamicsProcessor/DynamicsProcessor.cpp index 5b251a6f0..2436bfd33 100644 --- a/plugins/DynamicsProcessor/DynamicsProcessor.cpp +++ b/plugins/DynamicsProcessor/DynamicsProcessor.cpp @@ -91,15 +91,8 @@ inline void DynProcEffect::calcRelease() } -bool DynProcEffect::processAudioBuffer( SampleFrame* _buf, - const fpp_t _frames ) +double DynProcEffect::processImpl(SampleFrame* buf, const fpp_t frames) { - if( !isEnabled() || !isRunning () ) - { -//apparently we can't keep running after the decay value runs out so we'll just set the peaks to zero - m_currentPeak[0] = m_currentPeak[1] = DYN_NOISE_FLOOR; - return( false ); - } //qDebug( "%f %f", m_currentPeak[0], m_currentPeak[1] ); // variables for effect @@ -140,9 +133,9 @@ bool DynProcEffect::processAudioBuffer( SampleFrame* _buf, } } - for( fpp_t f = 0; f < _frames; ++f ) + for (fpp_t f = 0; f < frames; ++f) { - auto s = std::array{_buf[f][0], _buf[f][1]}; + auto s = std::array{buf[f][0], buf[f][1]}; // apply input gain s[0] *= inputGain; @@ -210,17 +203,19 @@ bool DynProcEffect::processAudioBuffer( SampleFrame* _buf, s[1] *= outputGain; // mix wet/dry signals - _buf[f][0] = d * _buf[f][0] + w * s[0]; - _buf[f][1] = d * _buf[f][1] + w * s[1]; - out_sum += _buf[f][0] * _buf[f][0] + _buf[f][1] * _buf[f][1]; + buf[f][0] = d * buf[f][0] + w * s[0]; + buf[f][1] = d * buf[f][1] + w * s[1]; + out_sum += buf[f][0] * buf[f][0] + buf[f][1] * buf[f][1]; } - checkGate( out_sum / _frames ); - - return( isRunning() ); + return out_sum; } - +void DynProcEffect::sleepImpl() +{ + // Apparently we can't keep running after the decay value runs out so we'll just set the peaks to zero + m_currentPeak[0] = m_currentPeak[1] = DYN_NOISE_FLOOR; +} diff --git a/plugins/DynamicsProcessor/DynamicsProcessor.h b/plugins/DynamicsProcessor/DynamicsProcessor.h index 970690d8d..f46489952 100644 --- a/plugins/DynamicsProcessor/DynamicsProcessor.h +++ b/plugins/DynamicsProcessor/DynamicsProcessor.h @@ -42,8 +42,9 @@ public: DynProcEffect( Model * _parent, const Descriptor::SubPluginFeatures::Key * _key ); ~DynProcEffect() override; - bool processAudioBuffer( SampleFrame* _buf, - const fpp_t _frames ) override; + + double processImpl(SampleFrame* buf, const fpp_t frames) override; + void sleepImpl() override; EffectControls * controls() override { diff --git a/plugins/Eq/EqEffect.cpp b/plugins/Eq/EqEffect.cpp index 662b85a8e..52dad6ee5 100644 --- a/plugins/Eq/EqEffect.cpp +++ b/plugins/Eq/EqEffect.cpp @@ -64,7 +64,7 @@ EqEffect::EqEffect( Model *parent, const Plugin::Descriptor::SubPluginFeatures:: -bool EqEffect::processAudioBuffer( SampleFrame* buf, const fpp_t frames ) +double EqEffect::processImpl(SampleFrame* buf, const fpp_t frames) { const int sampleRate = Engine::audioEngine()->outputSampleRate(); @@ -131,13 +131,6 @@ bool EqEffect::processAudioBuffer( SampleFrame* buf, const fpp_t frames ) m_lp481.setParameters( sampleRate, lpFreq, lpRes, 1 ); - - - if( !isEnabled() || !isRunning () ) - { - return( false ); - } - if( m_eqControls.m_outGainModel.isValueChanged() ) { m_outGain = dbfsToAmp(m_eqControls.m_outGainModel.value()); @@ -151,9 +144,9 @@ bool EqEffect::processAudioBuffer( SampleFrame* buf, const fpp_t frames ) m_eqControls.m_inProgress = true; double outSum = 0.0; - for( fpp_t f = 0; f < frames; ++f ) + for (fpp_t f = 0; f < frames; ++f) { - 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]; } const float outGain = m_outGain; @@ -268,8 +261,6 @@ bool EqEffect::processAudioBuffer( SampleFrame* buf, const fpp_t frames ) m_eqControls.m_outPeakL = m_eqControls.m_outPeakL < outPeak[0] ? outPeak[0] : m_eqControls.m_outPeakL; m_eqControls.m_outPeakR = m_eqControls.m_outPeakR < outPeak[1] ? outPeak[1] : m_eqControls.m_outPeakR; - checkGate( outSum / frames ); - if(m_eqControls.m_analyseOutModel.value( true ) && outSum > 0 && m_eqControls.isViewVisible() ) { m_eqControls.m_outFftBands.analyze( buf, frames ); @@ -281,7 +272,8 @@ bool EqEffect::processAudioBuffer( SampleFrame* buf, const fpp_t frames ) } m_eqControls.m_inProgress = false; - return isRunning(); + + return outSum; } diff --git a/plugins/Eq/EqEffect.h b/plugins/Eq/EqEffect.h index ca0ebb1b9..a97d1ddea 100644 --- a/plugins/Eq/EqEffect.h +++ b/plugins/Eq/EqEffect.h @@ -40,7 +40,9 @@ class EqEffect : public Effect public: EqEffect( Model * parent , const Descriptor::SubPluginFeatures::Key * key ); ~EqEffect() override = default; - bool processAudioBuffer( SampleFrame* buf, const fpp_t frames ) override; + + double processImpl(SampleFrame* buf, const fpp_t frames) override; + EffectControls * controls() override { return &m_eqControls; diff --git a/plugins/Flanger/FlangerEffect.cpp b/plugins/Flanger/FlangerEffect.cpp index 184df161e..7ffe26c70 100644 --- a/plugins/Flanger/FlangerEffect.cpp +++ b/plugins/Flanger/FlangerEffect.cpp @@ -85,12 +85,8 @@ FlangerEffect::~FlangerEffect() -bool FlangerEffect::processAudioBuffer( SampleFrame* buf, const fpp_t frames ) +double FlangerEffect::processImpl(SampleFrame* buf, const fpp_t frames) { - if( !isEnabled() || !isRunning () ) - { - return( false ); - } double outSum = 0.0; const float d = dryLevel(); const float w = wetLevel(); @@ -127,10 +123,10 @@ bool FlangerEffect::processAudioBuffer( SampleFrame* buf, const fpp_t frames ) buf[f][0] = ( d * dryS[0] ) + ( w * buf[f][0] ); buf[f][1] = ( d * dryS[1] ) + ( w * buf[f][1] ); - 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; } diff --git a/plugins/Flanger/FlangerEffect.h b/plugins/Flanger/FlangerEffect.h index 4b0246e7e..387d62d00 100644 --- a/plugins/Flanger/FlangerEffect.h +++ b/plugins/Flanger/FlangerEffect.h @@ -41,7 +41,9 @@ class FlangerEffect : public Effect public: FlangerEffect( Model* parent , const Descriptor::SubPluginFeatures::Key* key ); ~FlangerEffect() override; - bool processAudioBuffer( SampleFrame* buf, const fpp_t frames ) override; + + double processImpl(SampleFrame* buf, const fpp_t frames) override; + EffectControls* controls() override { return &m_flangerControls; diff --git a/plugins/GranularPitchShifter/GranularPitchShifterEffect.cpp b/plugins/GranularPitchShifter/GranularPitchShifterEffect.cpp index 2b182991f..bceecf9f5 100755 --- a/plugins/GranularPitchShifter/GranularPitchShifterEffect.cpp +++ b/plugins/GranularPitchShifter/GranularPitchShifterEffect.cpp @@ -60,10 +60,8 @@ GranularPitchShifterEffect::GranularPitchShifterEffect(Model* parent, const Desc } -bool GranularPitchShifterEffect::processAudioBuffer(SampleFrame* buf, const fpp_t frames) +double GranularPitchShifterEffect::processImpl(SampleFrame* buf, const fpp_t frames) { - if (!isEnabled() || !isRunning()) { return false; } - const float d = dryLevel(); const float w = wetLevel(); @@ -93,6 +91,7 @@ bool GranularPitchShifterEffect::processAudioBuffer(SampleFrame* buf, const fpp_ const float shapeK = cosWindowApproxK(shape); const int sizeSamples = m_sampleRate / size; const float waitMult = sizeSamples / (density * 2); + double outSum = 0.0; for (fpp_t f = 0; f < frames; ++f) { @@ -237,6 +236,7 @@ bool GranularPitchShifterEffect::processAudioBuffer(SampleFrame* buf, const fpp_ buf[f][0] = d * buf[f][0] + w * s[0]; buf[f][1] = d * buf[f][1] + w * s[1]; + outSum += buf[f].sumOfSquaredAmplitudes(); } if (m_sampleRateNeedsUpdate) @@ -245,7 +245,7 @@ bool GranularPitchShifterEffect::processAudioBuffer(SampleFrame* buf, const fpp_ changeSampleRate(); } - return isRunning(); + return outSum; } void GranularPitchShifterEffect::changeSampleRate() diff --git a/plugins/GranularPitchShifter/GranularPitchShifterEffect.h b/plugins/GranularPitchShifter/GranularPitchShifterEffect.h index 0f94168b7..5700772ea 100755 --- a/plugins/GranularPitchShifter/GranularPitchShifterEffect.h +++ b/plugins/GranularPitchShifter/GranularPitchShifterEffect.h @@ -48,7 +48,8 @@ class GranularPitchShifterEffect : public Effect public: GranularPitchShifterEffect(Model* parent, const Descriptor::SubPluginFeatures::Key* key); ~GranularPitchShifterEffect() override = default; - bool processAudioBuffer(SampleFrame* buf, const fpp_t frames) override; + + double processImpl(SampleFrame* buf, const fpp_t frames) override; EffectControls* controls() override { diff --git a/plugins/LOMM/LOMM.cpp b/plugins/LOMM/LOMM.cpp index 7c4574cd1..5d8fc7147 100644 --- a/plugins/LOMM/LOMM.cpp +++ b/plugins/LOMM/LOMM.cpp @@ -101,13 +101,8 @@ void LOMMEffect::changeSampleRate() } -bool LOMMEffect::processAudioBuffer(SampleFrame* buf, const fpp_t frames) +double LOMMEffect::processImpl(SampleFrame* buf, const fpp_t frames) { - if (!isEnabled() || !isRunning()) - { - return false; - } - if (m_needsUpdate || m_lommControls.m_split1Model.isValueChanged()) { m_lp1.setLowpass(m_lommControls.m_split1Model.value()); @@ -121,7 +116,7 @@ bool LOMMEffect::processAudioBuffer(SampleFrame* buf, const fpp_t frames) } m_needsUpdate = false; - float outSum = 0.f; + double outSum = 0.0; const float d = dryLevel(); const float w = wetLevel(); @@ -423,11 +418,10 @@ bool LOMMEffect::processAudioBuffer(SampleFrame* buf, const fpp_t frames) buf[f][0] = d * buf[f][0] + w * s[0]; buf[f][1] = d * buf[f][1] + w * s[1]; - outSum += buf[f][0] + buf[f][1]; + outSum += buf[f].sumOfSquaredAmplitudes(); } - checkGate(outSum / frames); - return isRunning(); + return outSum; } extern "C" diff --git a/plugins/LOMM/LOMM.h b/plugins/LOMM/LOMM.h index 783233c5f..3dc5c77ce 100644 --- a/plugins/LOMM/LOMM.h +++ b/plugins/LOMM/LOMM.h @@ -45,7 +45,8 @@ class LOMMEffect : public Effect public: LOMMEffect(Model* parent, const Descriptor::SubPluginFeatures::Key* key); ~LOMMEffect() override = default; - bool processAudioBuffer(SampleFrame* buf, const fpp_t frames) override; + + double processImpl(SampleFrame* buf, const fpp_t frames) override; EffectControls* controls() override { diff --git a/plugins/LadspaEffect/LadspaEffect.cpp b/plugins/LadspaEffect/LadspaEffect.cpp index 75c79ad21..6c3b8fbbd 100644 --- a/plugins/LadspaEffect/LadspaEffect.cpp +++ b/plugins/LadspaEffect/LadspaEffect.cpp @@ -129,26 +129,20 @@ void LadspaEffect::changeSampleRate() -bool LadspaEffect::processAudioBuffer( SampleFrame* _buf, - const fpp_t _frames ) +double LadspaEffect::processImpl(SampleFrame* buf, const fpp_t frames) { m_pluginMutex.lock(); - if( !isOkay() || dontRun() || !isRunning() || !isEnabled() ) - { - m_pluginMutex.unlock(); - return( false ); - } - auto frames = _frames; - SampleFrame* o_buf = nullptr; - QVarLengthArray sBuf(_frames); + auto outFrames = frames; + SampleFrame* outBuf = nullptr; + QVarLengthArray sBuf(frames); if( m_maxSampleRate < Engine::audioEngine()->outputSampleRate() ) { - o_buf = _buf; - _buf = sBuf.data(); - sampleDown( o_buf, _buf, m_maxSampleRate ); - frames = _frames * m_maxSampleRate / + outBuf = buf; + buf = sBuf.data(); + sampleDown(outBuf, buf, m_maxSampleRate); + outFrames = frames * m_maxSampleRate / Engine::audioEngine()->outputSampleRate(); } @@ -163,11 +157,9 @@ bool LadspaEffect::processAudioBuffer( SampleFrame* _buf, switch( pp->rate ) { case BufferRate::ChannelIn: - for( fpp_t frame = 0; - frame < frames; ++frame ) + for (fpp_t frame = 0; frame < outFrames; ++frame) { - pp->buffer[frame] = - _buf[frame][channel]; + pp->buffer[frame] = buf[frame][channel]; } ++channel; break; @@ -176,7 +168,7 @@ bool LadspaEffect::processAudioBuffer( SampleFrame* _buf, ValueBuffer * vb = pp->control->valueBuffer(); if( vb ) { - memcpy( pp->buffer, vb->values(), frames * sizeof(float) ); + memcpy(pp->buffer, vb->values(), outFrames * sizeof(float)); } else { @@ -185,11 +177,9 @@ bool LadspaEffect::processAudioBuffer( SampleFrame* _buf, // This only supports control rate ports, so the audio rates are // treated as though they were control rate by setting the // port buffer to all the same value. - for( fpp_t frame = 0; - frame < frames; ++frame ) + for (fpp_t frame = 0; frame < outFrames; ++frame) { - pp->buffer[frame] = - pp->value; + pp->buffer[frame] = pp->value; } } break; @@ -218,7 +208,7 @@ bool LadspaEffect::processAudioBuffer( SampleFrame* _buf, // Process the buffers. for( ch_cnt_t proc = 0; proc < processorCount(); ++proc ) { - (m_descriptor->run)( m_handles[proc], frames ); + (m_descriptor->run)(m_handles[proc], outFrames); } // Copy the LADSPA output buffers to the LMMS buffer. @@ -238,11 +228,9 @@ bool LadspaEffect::processAudioBuffer( SampleFrame* _buf, case BufferRate::ControlRateInput: break; case BufferRate::ChannelOut: - for( fpp_t frame = 0; - frame < frames; ++frame ) + for (fpp_t frame = 0; frame < outFrames; ++frame) { - _buf[frame][channel] = d * _buf[frame][channel] + w * pp->buffer[frame]; - out_sum += _buf[frame][channel] * _buf[frame][channel]; + buf[frame][channel] = d * buf[frame][channel] + w * pp->buffer[frame]; } ++channel; break; @@ -255,17 +243,19 @@ bool LadspaEffect::processAudioBuffer( SampleFrame* _buf, } } - if( o_buf != nullptr ) + if (outBuf != nullptr) { - sampleBack( _buf, o_buf, m_maxSampleRate ); + sampleBack(buf, outBuf, m_maxSampleRate); } - checkGate( out_sum / frames ); + for (fpp_t frame = 0; frame < frames; ++frame) + { + out_sum += buf[frame].sumOfSquaredAmplitudes(); + } - - bool is_running = isRunning(); m_pluginMutex.unlock(); - return( is_running ); + + return out_sum; } diff --git a/plugins/LadspaEffect/LadspaEffect.h b/plugins/LadspaEffect/LadspaEffect.h index d5b93d4e2..8bd4195e7 100644 --- a/plugins/LadspaEffect/LadspaEffect.h +++ b/plugins/LadspaEffect/LadspaEffect.h @@ -47,9 +47,8 @@ public: const Descriptor::SubPluginFeatures::Key * _key ); ~LadspaEffect() override; - bool processAudioBuffer( SampleFrame* _buf, - const fpp_t _frames ) override; - + double processImpl(SampleFrame* buf, const fpp_t frames) override; + void setControl( int _control, LADSPA_Data _data ); EffectControls * controls() override diff --git a/plugins/Lv2Effect/Lv2Effect.cpp b/plugins/Lv2Effect/Lv2Effect.cpp index d6b89a229..4df40b60f 100644 --- a/plugins/Lv2Effect/Lv2Effect.cpp +++ b/plugins/Lv2Effect/Lv2Effect.cpp @@ -68,9 +68,8 @@ Lv2Effect::Lv2Effect(Model* parent, const Descriptor::SubPluginFeatures::Key *ke -bool Lv2Effect::processAudioBuffer(SampleFrame* buf, const fpp_t frames) +double Lv2Effect::processImpl(SampleFrame* buf, const fpp_t frames) { - if (!isEnabled() || !isRunning()) { return false; } Q_ASSERT(frames <= static_cast(m_tmpOutputSmps.size())); m_controls.copyBuffersFromLmms(buf, frames); @@ -95,9 +94,8 @@ bool Lv2Effect::processAudioBuffer(SampleFrame* buf, const fpp_t frames) auto r = static_cast(buf[f][1]); outSum += l*l + r*r; } - checkGate(outSum / frames); - return isRunning(); + return outSum; } diff --git a/plugins/Lv2Effect/Lv2Effect.h b/plugins/Lv2Effect/Lv2Effect.h index bc81eb590..882a57fa8 100644 --- a/plugins/Lv2Effect/Lv2Effect.h +++ b/plugins/Lv2Effect/Lv2Effect.h @@ -42,7 +42,8 @@ public: */ Lv2Effect(Model* parent, const Descriptor::SubPluginFeatures::Key* _key); - bool processAudioBuffer( SampleFrame* buf, const fpp_t frames ) override; + double processImpl(SampleFrame* buf, const fpp_t frames) override; + EffectControls* controls() override { return &m_controls; } Lv2FxControls* lv2Controls() { return &m_controls; } diff --git a/plugins/MultitapEcho/MultitapEcho.cpp b/plugins/MultitapEcho/MultitapEcho.cpp index ecc1d8f30..14795601f 100644 --- a/plugins/MultitapEcho/MultitapEcho.cpp +++ b/plugins/MultitapEcho/MultitapEcho.cpp @@ -94,13 +94,8 @@ void MultitapEchoEffect::runFilter( SampleFrame* dst, SampleFrame* src, StereoOn } -bool MultitapEchoEffect::processAudioBuffer( SampleFrame* buf, const fpp_t frames ) +double MultitapEchoEffect::processImpl(SampleFrame* buf, const fpp_t frames) { - if( !isEnabled() || !isRunning () ) - { - return( false ); - } - double outSum = 0.0; const float d = dryLevel(); const float w = wetLevel(); @@ -158,10 +153,8 @@ bool MultitapEchoEffect::processAudioBuffer( SampleFrame* buf, const fpp_t frame 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; } diff --git a/plugins/MultitapEcho/MultitapEcho.h b/plugins/MultitapEcho/MultitapEcho.h index d6e981fbd..a0e00ad73 100644 --- a/plugins/MultitapEcho/MultitapEcho.h +++ b/plugins/MultitapEcho/MultitapEcho.h @@ -40,7 +40,8 @@ class MultitapEchoEffect : public Effect public: MultitapEchoEffect( Model* parent, const Descriptor::SubPluginFeatures::Key* key ); ~MultitapEchoEffect() override; - bool processAudioBuffer( SampleFrame* buf, const fpp_t frames ) override; + + double processImpl(SampleFrame* buf, const fpp_t frames) override; EffectControls* controls() override { diff --git a/plugins/PeakControllerEffect/PeakControllerEffect.cpp b/plugins/PeakControllerEffect/PeakControllerEffect.cpp index 886036095..f58972bea 100644 --- a/plugins/PeakControllerEffect/PeakControllerEffect.cpp +++ b/plugins/PeakControllerEffect/PeakControllerEffect.cpp @@ -93,37 +93,29 @@ PeakControllerEffect::~PeakControllerEffect() } -bool PeakControllerEffect::processAudioBuffer( SampleFrame* _buf, - const fpp_t _frames ) +double PeakControllerEffect::processImpl(SampleFrame* buf, const fpp_t frames) { PeakControllerEffectControls & c = m_peakControls; - // This appears to be used for determining whether or not to continue processing - // audio with this effect - if( !isEnabled() || !isRunning() ) - { - return false; - } - // RMS: double sum = 0; if( c.m_absModel.value() ) { - for (auto i = std::size_t{0}; i < _frames; ++i) + for (auto i = std::size_t{0}; i < frames; ++i) { // absolute value is achieved because the squares are > 0 - sum += _buf[i][0]*_buf[i][0] + _buf[i][1]*_buf[i][1]; + sum += buf[i][0] * buf[i][0] + buf[i][1] * buf[i][1]; } } else { - for (auto i = std::size_t{0}; i < _frames; ++i) + for (auto i = std::size_t{0}; i < frames; ++i) { // the value is absolute because of squaring, // so we need to correct it - sum += _buf[i][0] * _buf[i][0] * sign( _buf[i][0] ) - + _buf[i][1] * _buf[i][1] * sign( _buf[i][1] ); + sum += buf[i][0] * buf[i][0] * sign(buf[i][0]) + + buf[i][1] * buf[i][1] * sign(buf[i][1]); } } @@ -131,19 +123,19 @@ bool PeakControllerEffect::processAudioBuffer( SampleFrame* _buf, // this will mute the output after the values were measured if( c.m_muteModel.value() ) { - for (auto i = std::size_t{0}; i < _frames; ++i) + for (auto i = std::size_t{0}; i < frames; ++i) { - _buf[i][0] = _buf[i][1] = 0.0f; + buf[i][0] = buf[i][1] = 0.0f; } } - float curRMS = sqrt_neg( sum / _frames ); + float curRMS = sqrt_neg( sum / frames ); const float tres = c.m_tresholdModel.value(); const float amount = c.m_amountModel.value() * c.m_amountMultModel.value(); curRMS = qAbs( curRMS ) < tres ? 0.0f : curRMS; m_lastSample = qBound( 0.0f, c.m_baseModel.value() + amount * curRMS, 1.0f ); - return isRunning(); + return -1.0; } diff --git a/plugins/PeakControllerEffect/PeakControllerEffect.h b/plugins/PeakControllerEffect/PeakControllerEffect.h index dc6e507f3..47122d25f 100644 --- a/plugins/PeakControllerEffect/PeakControllerEffect.h +++ b/plugins/PeakControllerEffect/PeakControllerEffect.h @@ -41,8 +41,8 @@ public: PeakControllerEffect( Model * parent, const Descriptor::SubPluginFeatures::Key * _key ); ~PeakControllerEffect() override; - bool processAudioBuffer( SampleFrame* _buf, - const fpp_t _frames ) override; + + double processImpl(SampleFrame* buf, const fpp_t frames) override; EffectControls * controls() override { diff --git a/plugins/ReverbSC/ReverbSC.cpp b/plugins/ReverbSC/ReverbSC.cpp index 2def88d1d..9ca93f927 100644 --- a/plugins/ReverbSC/ReverbSC.cpp +++ b/plugins/ReverbSC/ReverbSC.cpp @@ -75,13 +75,8 @@ ReverbSCEffect::~ReverbSCEffect() sp_destroy(&sp); } -bool ReverbSCEffect::processAudioBuffer( SampleFrame* buf, const fpp_t frames ) +double ReverbSCEffect::processImpl(SampleFrame* buf, const fpp_t frames) { - if( !isEnabled() || !isRunning () ) - { - return( false ); - } - double outSum = 0.0; const float d = dryLevel(); const float w = wetLevel(); @@ -120,13 +115,10 @@ bool ReverbSCEffect::processAudioBuffer( SampleFrame* buf, const fpp_t frames ) buf[f][0] = d * buf[f][0] + w * dcblkL * outGain; buf[f][1] = d * buf[f][1] + w * dcblkR * 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; } void ReverbSCEffect::changeSampleRate() diff --git a/plugins/ReverbSC/ReverbSC.h b/plugins/ReverbSC/ReverbSC.h index f3c196f5b..a5c47ac8e 100644 --- a/plugins/ReverbSC/ReverbSC.h +++ b/plugins/ReverbSC/ReverbSC.h @@ -45,7 +45,8 @@ class ReverbSCEffect : public Effect public: ReverbSCEffect( Model* parent, const Descriptor::SubPluginFeatures::Key* key ); ~ReverbSCEffect() override; - bool processAudioBuffer( SampleFrame* buf, const fpp_t frames ) override; + + double processImpl(SampleFrame* buf, const fpp_t frames) override; EffectControls* controls() override { diff --git a/plugins/SpectrumAnalyzer/Analyzer.cpp b/plugins/SpectrumAnalyzer/Analyzer.cpp index dc2108eb9..2298f6722 100644 --- a/plugins/SpectrumAnalyzer/Analyzer.cpp +++ b/plugins/SpectrumAnalyzer/Analyzer.cpp @@ -77,7 +77,7 @@ Analyzer::~Analyzer() } // Take audio data and pass them to the spectrum processor. -bool Analyzer::processAudioBuffer(SampleFrame* buffer, const fpp_t frame_count) +double Analyzer::processImpl(SampleFrame* buf, const fpp_t frames) { // Measure time spent in audio thread; both average and peak should be well under 1 ms. #ifdef SA_DEBUG @@ -91,14 +91,12 @@ bool Analyzer::processAudioBuffer(SampleFrame* buffer, const fpp_t frame_count) } #endif - if (!isEnabled() || !isRunning ()) {return false;} - // Skip processing if the controls dialog isn't visible, it would only waste CPU cycles. if (m_controls.isViewVisible()) { // To avoid processing spikes on audio thread, data are stored in // a lockless ringbuffer and processed in a separate thread. - m_inputBuffer.write(buffer, frame_count, true); + m_inputBuffer.write(buf, frames, true); } #ifdef SA_DEBUG audio_time = std::chrono::high_resolution_clock::now().time_since_epoch().count() - audio_time; @@ -107,7 +105,7 @@ bool Analyzer::processAudioBuffer(SampleFrame* buffer, const fpp_t frame_count) if (audio_time / 1000000.0 > m_max_execution) {m_max_execution = audio_time / 1000000.0;} #endif - return isRunning(); + return -1.0; } diff --git a/plugins/SpectrumAnalyzer/Analyzer.h b/plugins/SpectrumAnalyzer/Analyzer.h index da87ffd35..a47621bc6 100644 --- a/plugins/SpectrumAnalyzer/Analyzer.h +++ b/plugins/SpectrumAnalyzer/Analyzer.h @@ -45,7 +45,8 @@ public: Analyzer(Model *parent, const Descriptor::SubPluginFeatures::Key *key); ~Analyzer() override; - bool processAudioBuffer(SampleFrame* buffer, const fpp_t frame_count) override; + double processImpl(SampleFrame* buf, const fpp_t frames) override; + EffectControls *controls() override {return &m_controls;} SaProcessor *getProcessor() {return &m_processor;} diff --git a/plugins/StereoEnhancer/StereoEnhancer.cpp b/plugins/StereoEnhancer/StereoEnhancer.cpp index 261c897df..a96d86376 100644 --- a/plugins/StereoEnhancer/StereoEnhancer.cpp +++ b/plugins/StereoEnhancer/StereoEnhancer.cpp @@ -82,28 +82,21 @@ StereoEnhancerEffect::~StereoEnhancerEffect() -bool StereoEnhancerEffect::processAudioBuffer( SampleFrame* _buf, - const fpp_t _frames ) +double StereoEnhancerEffect::processImpl(SampleFrame* buf, const fpp_t frames) { - // This appears to be used for determining whether or not to continue processing // audio with this effect double out_sum = 0.0; - if( !isEnabled() || !isRunning() ) - { - return( false ); - } - const float d = dryLevel(); const float w = wetLevel(); - for( fpp_t f = 0; f < _frames; ++f ) + for( fpp_t f = 0; f < frames; ++f ) { // copy samples into the delay buffer - m_delayBuffer[m_currFrame][0] = _buf[f][0]; - m_delayBuffer[m_currFrame][1] = _buf[f][1]; + m_delayBuffer[m_currFrame][0] = buf[f][0]; + m_delayBuffer[m_currFrame][1] = buf[f][1]; // Get the width knob value from the Stereo Enhancer effect float width = m_seFX.wideCoeff(); @@ -118,26 +111,25 @@ bool StereoEnhancerEffect::processAudioBuffer( SampleFrame* _buf, } //sample_t s[2] = { _buf[f][0], _buf[f][1] }; //Vanilla - auto s = std::array{_buf[f][0], m_delayBuffer[frameIndex][1]}; //Chocolate + auto s = std::array{buf[f][0], m_delayBuffer[frameIndex][1]}; //Chocolate m_seFX.nextSample( s[0], s[1] ); - _buf[f][0] = d * _buf[f][0] + w * s[0]; - _buf[f][1] = d * _buf[f][1] + w * s[1]; - out_sum += _buf[f][0]*_buf[f][0] + _buf[f][1]*_buf[f][1]; + buf[f][0] = d * buf[f][0] + w * s[0]; + buf[f][1] = d * buf[f][1] + w * s[1]; + out_sum += buf[f][0] * buf[f][0] + buf[f][1] * buf[f][1]; // Update currFrame m_currFrame += 1; m_currFrame %= DEFAULT_BUFFER_SIZE; } - checkGate( out_sum / _frames ); if( !isRunning() ) { clearMyBuffer(); } - return( isRunning() ); + return out_sum; } diff --git a/plugins/StereoEnhancer/StereoEnhancer.h b/plugins/StereoEnhancer/StereoEnhancer.h index 861187f8f..3f59aa784 100644 --- a/plugins/StereoEnhancer/StereoEnhancer.h +++ b/plugins/StereoEnhancer/StereoEnhancer.h @@ -40,8 +40,8 @@ public: StereoEnhancerEffect( Model * parent, const Descriptor::SubPluginFeatures::Key * _key ); ~StereoEnhancerEffect() override; - bool processAudioBuffer( SampleFrame* _buf, - const fpp_t _frames ) override; + + double processImpl(SampleFrame* buf, const fpp_t frames) override; EffectControls * controls() override { diff --git a/plugins/StereoMatrix/StereoMatrix.cpp b/plugins/StereoMatrix/StereoMatrix.cpp index c4384fddd..c56e740ad 100644 --- a/plugins/StereoMatrix/StereoMatrix.cpp +++ b/plugins/StereoMatrix/StereoMatrix.cpp @@ -64,44 +64,33 @@ StereoMatrixEffect::StereoMatrixEffect( -bool StereoMatrixEffect::processAudioBuffer( SampleFrame* _buf, - const fpp_t _frames ) +double StereoMatrixEffect::processImpl(SampleFrame* buf, const fpp_t frames) { - - // This appears to be used for determining whether or not to continue processing - // audio with this effect - if( !isEnabled() || !isRunning() ) - { - return( false ); - } - double out_sum = 0.0; - for( fpp_t f = 0; f < _frames; ++f ) + for( fpp_t f = 0; f < frames; ++f ) { const float d = dryLevel(); const float w = wetLevel(); - sample_t l = _buf[f][0]; - sample_t r = _buf[f][1]; + sample_t l = buf[f][0]; + sample_t r = buf[f][1]; // Init with dry-mix - _buf[f][0] = l * d; - _buf[f][1] = r * d; + buf[f][0] = l * d; + buf[f][1] = r * d; // Add it wet - _buf[f][0] += ( m_smControls.m_llModel.value( f ) * l + + buf[f][0] += ( m_smControls.m_llModel.value( f ) * l + m_smControls.m_rlModel.value( f ) * r ) * w; - _buf[f][1] += ( m_smControls.m_lrModel.value( f ) * l + + buf[f][1] += ( m_smControls.m_lrModel.value( f ) * l + m_smControls.m_rrModel.value( f ) * r ) * w; - out_sum += _buf[f][0]*_buf[f][0] + _buf[f][1]*_buf[f][1]; + out_sum += buf[f][0] * buf[f][0] + buf[f][1] * buf[f][1]; } - checkGate( out_sum / _frames ); - - return( isRunning() ); + return out_sum; } diff --git a/plugins/StereoMatrix/StereoMatrix.h b/plugins/StereoMatrix/StereoMatrix.h index a254264f8..5e3d8190c 100644 --- a/plugins/StereoMatrix/StereoMatrix.h +++ b/plugins/StereoMatrix/StereoMatrix.h @@ -39,8 +39,8 @@ public: StereoMatrixEffect( Model * parent, const Descriptor::SubPluginFeatures::Key * _key ); ~StereoMatrixEffect() override = default; - bool processAudioBuffer( SampleFrame* _buf, - const fpp_t _frames ) override; + + double processImpl(SampleFrame* buf, const fpp_t frames) override; EffectControls* controls() override { diff --git a/plugins/Vectorscope/Vectorscope.cpp b/plugins/Vectorscope/Vectorscope.cpp index c94eb5d28..63e2b7f6d 100644 --- a/plugins/Vectorscope/Vectorscope.cpp +++ b/plugins/Vectorscope/Vectorscope.cpp @@ -58,18 +58,17 @@ Vectorscope::Vectorscope(Model *parent, const Plugin::Descriptor::SubPluginFeatu // Take audio data and store them for processing and display in the GUI thread. -bool Vectorscope::processAudioBuffer(SampleFrame* buffer, const fpp_t frame_count) +double Vectorscope::processImpl(SampleFrame* buf, const fpp_t frames) { - if (!isEnabled() || !isRunning ()) {return false;} - // Skip processing if the controls dialog isn't visible, it would only waste CPU cycles. if (m_controls.isViewVisible()) { // To avoid processing spikes on audio thread, data are stored in // a lockless ringbuffer and processed in a separate thread. - m_inputBuffer.write(buffer, frame_count); + m_inputBuffer.write(buf, frames); } - return isRunning(); + + return -1.0; } diff --git a/plugins/Vectorscope/Vectorscope.h b/plugins/Vectorscope/Vectorscope.h index 66d20e639..9d8cb70ff 100644 --- a/plugins/Vectorscope/Vectorscope.h +++ b/plugins/Vectorscope/Vectorscope.h @@ -39,7 +39,8 @@ public: Vectorscope(Model *parent, const Descriptor::SubPluginFeatures::Key *key); ~Vectorscope() override = default; - bool processAudioBuffer(SampleFrame* buffer, const fpp_t frame_count) override; + double processImpl(SampleFrame* buf, const fpp_t frames) override; + EffectControls *controls() override {return &m_controls;} LocklessRingBuffer *getBuffer() {return &m_inputBuffer;} diff --git a/plugins/VstEffect/VstEffect.cpp b/plugins/VstEffect/VstEffect.cpp index ecb8240c8..a06f2188d 100644 --- a/plugins/VstEffect/VstEffect.cpp +++ b/plugins/VstEffect/VstEffect.cpp @@ -71,51 +71,37 @@ VstEffect::VstEffect( Model * _parent, } setDisplayName( m_key.attributes["file"].section( ".dll", 0, 0 ).isEmpty() ? m_key.name : m_key.attributes["file"].section( ".dll", 0, 0 ) ); + + setDontRun(true); } -bool VstEffect::processAudioBuffer( SampleFrame* _buf, const fpp_t _frames ) +double VstEffect::processImpl(SampleFrame* buf, const fpp_t frames) { - if( !isEnabled() || !isRunning () ) + assert(m_plugin != nullptr); + assert(frames <= DEFAULT_BUFFER_SIZE); + static thread_local auto tempBuf = std::array(); + + std::memcpy(tempBuf.data(), buf, sizeof(SampleFrame) * frames); + if (m_pluginMutex.tryLock(Engine::getSong()->isExporting() ? -1 : 0)) { - return false; + m_plugin->process(tempBuf.data(), tempBuf.data()); + m_pluginMutex.unlock(); } - if( m_plugin ) + double outSum = 0.0; + const float w = wetLevel(); + const float d = dryLevel(); + for (fpp_t f = 0; f < frames; ++f) { - const float d = dryLevel(); -#ifdef __GNUC__ - SampleFrame buf[_frames]; -#else - SampleFrame* buf = new SampleFrame[_frames]; -#endif - memcpy( buf, _buf, sizeof( SampleFrame ) * _frames ); - if (m_pluginMutex.tryLock(Engine::getSong()->isExporting() ? -1 : 0)) - { - m_plugin->process( buf, buf ); - m_pluginMutex.unlock(); - } - - double out_sum = 0.0; - const float w = wetLevel(); - for( fpp_t f = 0; f < _frames; ++f ) - { - _buf[f][0] = w*buf[f][0] + d*_buf[f][0]; - _buf[f][1] = w*buf[f][1] + d*_buf[f][1]; - } - for( fpp_t f = 0; f < _frames; ++f ) - { - out_sum += _buf[f][0]*_buf[f][0] + _buf[f][1]*_buf[f][1]; - } -#ifndef __GNUC__ - delete[] buf; -#endif - - checkGate( out_sum / _frames ); + buf[f][0] = w * tempBuf[f][0] + d * buf[f][0]; + buf[f][1] = w * tempBuf[f][1] + d * buf[f][1]; + outSum += buf[f][0] * buf[f][0] + buf[f][1] * buf[f][1]; } - return isRunning(); + + return outSum; } @@ -137,11 +123,13 @@ void VstEffect::openPlugin( const QString & _plugin ) if( m_plugin->failed() ) { m_plugin.clear(); + setDontRun(true); delete tf; collectErrorForUI( VstPlugin::tr( "The VST plugin %1 could not be loaded." ).arg( _plugin ) ); return; } + setDontRun(false); delete tf; m_key.attributes["file"] = _plugin; diff --git a/plugins/VstEffect/VstEffect.h b/plugins/VstEffect/VstEffect.h index c3f6e8091..121891760 100644 --- a/plugins/VstEffect/VstEffect.h +++ b/plugins/VstEffect/VstEffect.h @@ -45,8 +45,7 @@ public: const Descriptor::SubPluginFeatures::Key * _key ); ~VstEffect() override = default; - bool processAudioBuffer( SampleFrame* _buf, - const fpp_t _frames ) override; + double processImpl(SampleFrame* buf, const fpp_t frames) override; EffectControls * controls() override { diff --git a/plugins/WaveShaper/WaveShaper.cpp b/plugins/WaveShaper/WaveShaper.cpp index 373785408..1be6aa9ee 100644 --- a/plugins/WaveShaper/WaveShaper.cpp +++ b/plugins/WaveShaper/WaveShaper.cpp @@ -66,14 +66,8 @@ WaveShaperEffect::WaveShaperEffect( Model * _parent, -bool WaveShaperEffect::processAudioBuffer( SampleFrame* _buf, - const fpp_t _frames ) +double WaveShaperEffect::processImpl(SampleFrame* buf, const fpp_t frames) { - if( !isEnabled() || !isRunning () ) - { - return( false ); - } - // variables for effect int i = 0; @@ -94,9 +88,9 @@ bool WaveShaperEffect::processAudioBuffer( SampleFrame* _buf, const float *inputPtr = inputBuffer ? &( inputBuffer->values()[ 0 ] ) : &input; const float *outputPtr = outputBufer ? &( outputBufer->values()[ 0 ] ) : &output; - for( fpp_t f = 0; f < _frames; ++f ) + for (fpp_t f = 0; f < frames; ++f) { - auto s = std::array{_buf[f][0], _buf[f][1]}; + auto s = std::array{buf[f][0], buf[f][1]}; // apply input gain s[0] *= *inputPtr; @@ -138,17 +132,15 @@ bool WaveShaperEffect::processAudioBuffer( SampleFrame* _buf, s[1] *= *outputPtr; // mix wet/dry signals - _buf[f][0] = d * _buf[f][0] + w * s[0]; - _buf[f][1] = d * _buf[f][1] + w * s[1]; - out_sum += _buf[f][0] * _buf[f][0] + _buf[f][1] * _buf[f][1]; + buf[f][0] = d * buf[f][0] + w * s[0]; + buf[f][1] = d * buf[f][1] + w * s[1]; + out_sum += buf[f][0] * buf[f][0] + buf[f][1] * buf[f][1]; outputPtr += outputInc; inputPtr += inputInc; } - checkGate( out_sum / _frames ); - - return( isRunning() ); + return out_sum; } diff --git a/plugins/WaveShaper/WaveShaper.h b/plugins/WaveShaper/WaveShaper.h index 4c9d6e962..e300a0ba2 100644 --- a/plugins/WaveShaper/WaveShaper.h +++ b/plugins/WaveShaper/WaveShaper.h @@ -40,8 +40,8 @@ public: WaveShaperEffect( Model * _parent, const Descriptor::SubPluginFeatures::Key * _key ); ~WaveShaperEffect() override = default; - bool processAudioBuffer( SampleFrame* _buf, - const fpp_t _frames ) override; + + double processImpl(SampleFrame* buf, const fpp_t frames) override; EffectControls * controls() override { diff --git a/src/core/Effect.cpp b/src/core/Effect.cpp index b6b284051..e321d917d 100644 --- a/src/core/Effect.cpp +++ b/src/core/Effect.cpp @@ -122,6 +122,25 @@ void Effect::loadSettings( const QDomElement & _this ) +bool Effect::processAudioBuffer(SampleFrame* buf, const fpp_t frames) +{ + if (!isOkay() || dontRun() || !isEnabled() || !isRunning()) + { + sleepImpl(); + return false; + } + + const auto outSum = processImpl(buf, frames); + if (outSum >= 0) + { + checkGate(outSum / frames); + } + + return isRunning(); +} + + + Effect * Effect::instantiate( const QString& pluginName, Model * _parent,