AnalogTapeModel

Physical modelling signal processing for analog tape recording
Log | Files | Refs | Submodules | README | LICENSE

commit 8aa69fb4aa508ff191d5de2a28ce9915bc6188d9
parent 846baf026bdb5684c0b787c458126f580a9edab9
Author: jatinchowdhury18 <jatinchowdhury18@gmail.com>
Date:   Thu, 19 May 2022 14:45:31 +0100

Fix glitches happening with degrade effect at small block sizes (#266)


Diffstat:
MPlugin/Source/Processors/Chew/Dropout.h | 2+-
MPlugin/Source/Processors/Degrade/DegradeProcessor.cpp | 26+++++++++++++++++++++++++-
MPlugin/Source/Processors/Degrade/DegradeProcessor.h | 5+++++
MPlugin/Source/Processors/Hysteresis/HysteresisProcessor.cpp | 2+-
4 files changed, 32 insertions(+), 3 deletions(-)

diff --git a/Plugin/Source/Processors/Chew/Dropout.h b/Plugin/Source/Processors/Chew/Dropout.h @@ -49,7 +49,7 @@ public: inline float dropout (float x, size_t ch) { - auto sign = (float) chowdsp::sign (x); + auto sign = (float) chowdsp::Math::sign (x); return pow (abs (x), powerSmooth[ch].getNextValue()) * sign; } diff --git a/Plugin/Source/Processors/Degrade/DegradeProcessor.cpp b/Plugin/Source/Processors/Degrade/DegradeProcessor.cpp @@ -58,17 +58,41 @@ void DegradeProcessor::prepareToPlay (double sampleRate, int samplesPerBlock, in levelDetector.prepare ({ sampleRate, (uint32) samplesPerBlock, (uint32) numChannels }); gainProc.prepareToPlay (sampleRate, samplesPerBlock); bypass.prepare (samplesPerBlock, numChannels, bypass.toBool (onOffParam)); + + sampleCounter = 0; } void DegradeProcessor::processBlock (AudioBuffer<float>& buffer, MidiBuffer& midi) { + const auto numChannels = buffer.getNumChannels(); + const auto numSamples = buffer.getNumSamples(); + for (int i = 0; i < numSamples;) + { + int samplesToProcess = jmin (smallBlockSize, numSamples - i); + + auto&& smallBuffer = AudioBuffer<float> { buffer.getArrayOfWritePointers(), numChannels, i, samplesToProcess }; + processShortBlock (smallBuffer, midi); + + i += samplesToProcess; + } +} + +void DegradeProcessor::processShortBlock (AudioBuffer<float>& buffer, MidiBuffer& midi) +{ if (! bypass.processBlockIn (buffer, bypass.toBool (onOffParam))) return; const auto numChannels = buffer.getNumChannels(); const auto numSamples = buffer.getNumSamples(); - cookParams(); + sampleCounter += numSamples; + if (sampleCounter >= smallBlockSize) + { + cookParams(); + sampleCounter = 0; + } + + noiseBuffer.setSize (numChannels, numSamples, false, false, true); noiseBuffer.clear(); dsp::AudioBlock<float> block (buffer); diff --git a/Plugin/Source/Processors/Degrade/DegradeProcessor.h b/Plugin/Source/Processors/Degrade/DegradeProcessor.h @@ -18,6 +18,8 @@ public: void processBlock (AudioBuffer<float>& buffer, MidiBuffer& midi); private: + void processShortBlock (AudioBuffer<float>& buffer, MidiBuffer& midi); + std::atomic<float>* point1xParam = nullptr; std::atomic<float>* onOffParam = nullptr; std::atomic<float>* depthParam = nullptr; @@ -40,6 +42,9 @@ private: BypassProcessor bypass; + static constexpr int smallBlockSize = 2048; + int sampleCounter = 0; + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DegradeProcessor) }; diff --git a/Plugin/Source/Processors/Hysteresis/HysteresisProcessor.cpp b/Plugin/Source/Processors/Hysteresis/HysteresisProcessor.cpp @@ -174,7 +174,7 @@ void HysteresisProcessor::prepareToPlay (double sampleRate, int samplesPerBlock, #if HYSTERESIS_USE_SIMD const auto maxOSBlockSize = (uint32) samplesPerBlock * 16; - const auto numVecChannels = chowdsp::ceiling_divide ((size_t) numChannels, Vec2::size()); + const auto numVecChannels = chowdsp::Math::ceiling_divide ((size_t) numChannels, Vec2::size()); interleavedBlock = dsp::AudioBlock<Vec2> (interleavedBlockData, numVecChannels, maxOSBlockSize); zeroBlock = dsp::AudioBlock<double> (zeroData, Vec2::size(), maxOSBlockSize); zeroBlock.clear();