AnalogTapeModel

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

commit 74df3320182ff8fa5eb9093d8446fe5ac0233ef5
parent 76605fef68335ea4592add41462105579c6ad055
Author: jatinchowdhury18 <[email protected]>
Date:   Tue, 16 Mar 2021 11:35:57 -0700

Add amplitude envelope to degrade section (#160)

* Add amplitude envelope to degrade section

* Update degradation envelope tooltip

Co-authored-by: jatinchowdhury18 <[email protected]>
Diffstat:
MCHANGELOG.md | 1+
MPlugin/Source/GUI/Assets/gui.xml | 19++++++++++++++-----
MPlugin/Source/GUI/Assets/gui_ios.xml | 19++++++++++++++-----
MPlugin/Source/GUI/OnOffManager.cpp | 2+-
MPlugin/Source/Processors/Degrade/DegradeProcessor.cpp | 32+++++++++++++++++++++++++++++---
MPlugin/Source/Processors/Degrade/DegradeProcessor.h | 8+++++++-
6 files changed, 66 insertions(+), 15 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md @@ -7,6 +7,7 @@ this file. - Added Variance and Drift parameters for Wow control. - Fixed stability issue in tone filters. - Fixed glitches when adjusting loss parameters at large buffer sizes. +- Added Envelope parameter for Degrade section. - Improved parameter names for automation menus. - Added arrows for preset menu. - Fixed GUI freezing bug in Cakewalk. diff --git a/Plugin/Source/GUI/Assets/gui.xml b/Plugin/Source/GUI/Assets/gui.xml @@ -142,14 +142,23 @@ </View> <View tab-caption="Degrade" padding="0" flex-direction="column" background-color="FF31323A" margin="0"> - <View margin="0" padding="0" flex-grow="0.05" background-color="00000000"/> + <View margin="0" padding="0" flex-grow="0.15" background-color="00000000"/> <Slider parameter="deg_depth" caption="Depth" class="Slider" name="Depth" - tooltip="Sets the depth of the tape degradation." padding="0" - margin="0"/> + tooltip="Sets the depth of the tape degradation." + margin="0" slider-type="linear-horizontal" max-height="70"/> + <View margin="0" padding="0" flex-grow="0.1" background-color="00000000"/> <Slider caption="Amount" parameter="deg_amt" class="Slider" name="Amount" - padding="0" margin="0" tooltip="Sets the amount of the tape that is degraded. At large values all of the tape will be affected, at small values only some sections will be affected."/> + margin="0" tooltip="Sets the amount of the tape that is degraded. At large values all of the tape will be affected, at small values only some sections will be affected." + slider-type="linear-horizontal" max-height="70"/> + <View margin="0" padding="0" flex-grow="0.1" background-color="00000000"/> <Slider parameter="deg_var" caption="Variance" class="Slider" name="Variance" - padding="0" margin="0" tooltip="Sets the variance of the tape degradation. Use lower values for uniform degradation, or higher values for variation across different sections of tape."/> + margin="0" tooltip="Sets the variance of the tape degradation. Use lower values for uniform degradation, or higher values for variation across different sections of tape." + slider-type="linear-horizontal" max-height="70"/> + <View margin="0" padding="0" flex-grow="0.1" background-color="00000000"/> + <Slider parameter="deg_env" caption="Envelope" class="Slider" name="Envelope" + margin="0" tooltip="Sets the amount of amplitude envelope applied to the tape degradation. At 0, the degradation will have no envelope." + slider-type="linear-horizontal" max-height="70"/> + <View margin="0" padding="0" flex-grow="0.15" background-color="00000000"/> <PowerButton margin="0" padding="0" background-color="00000000" max-height="25" min-height="20" button-color="ff595c6b" button-on-color="FFEAA92C" parameter="deg_onoff" name="Degrade On/Off" tooltip="Turns the degradation processing on or off."/> diff --git a/Plugin/Source/GUI/Assets/gui_ios.xml b/Plugin/Source/GUI/Assets/gui_ios.xml @@ -142,14 +142,23 @@ </View> <View tab-caption="Degrade" padding="0" flex-direction="column" background-color="FF31323A" margin="0"> - <View margin="0" padding="0" flex-grow="0.05" background-color="00000000"/> + <View margin="0" padding="0" flex-grow="0.15" background-color="00000000"/> <Slider parameter="deg_depth" caption="Depth" class="Slider" name="Depth" - tooltip="Sets the depth of the tape degradation." padding="0" - margin="0"/> + tooltip="Sets the depth of the tape degradation." + margin="0" slider-type="linear-horizontal" max-height="70"/> + <View margin="0" padding="0" flex-grow="0.1" background-color="00000000"/> <Slider caption="Amount" parameter="deg_amt" class="Slider" name="Amount" - padding="0" margin="0" tooltip="Sets the amount of the tape that is degraded. At large values all of the tape will be affected, at small values only some sections will be affected."/> + margin="0" tooltip="Sets the amount of the tape that is degraded. At large values all of the tape will be affected, at small values only some sections will be affected." + slider-type="linear-horizontal" max-height="70"/> + <View margin="0" padding="0" flex-grow="0.1" background-color="00000000"/> <Slider parameter="deg_var" caption="Variance" class="Slider" name="Variance" - padding="0" margin="0" tooltip="Sets the variance of the tape degradation. Use lower values for uniform degradation, or higher values for variation across different sections of tape."/> + margin="0" tooltip="Sets the variance of the tape degradation. Use lower values for uniform degradation, or higher values for variation across different sections of tape." + slider-type="linear-horizontal" max-height="70"/> + <View margin="0" padding="0" flex-grow="0.1" background-color="00000000"/> + <Slider parameter="deg_env" caption="Envelope" class="Slider" name="Envelope" + margin="0" tooltip="Sets the amount of amplitude envelope applied to the tape degradation. At 0, the degradation will have no envelope." + slider-type="linear-horizontal" max-height="70"/> + <View margin="0" padding="0" flex-grow="0.15" background-color="00000000"/> <PowerButton margin="0" padding="0" background-color="00000000" max-height="25" min-height="20" button-color="ff595c6b" button-on-color="FFEAA92C" parameter="deg_onoff" name="Degrade On/Off" tooltip="Turns the degradation processing on or off."/> diff --git a/Plugin/Source/GUI/OnOffManager.cpp b/Plugin/Source/GUI/OnOffManager.cpp @@ -9,7 +9,7 @@ static const std::unordered_map<String, StringArray> triggerMap { { String ("tone_onoff"), StringArray ({ "Bass", "Treble", "Transition Frequency" }) }, { String ("loss_onoff"), StringArray ({ "Gap", "Thickness", "Spacing", "Speed", "3.75 ips", "7.5 ips", "15 ips", "30 ips" }) }, { String ("chew_onoff"), StringArray ({ "Chew Depth", "Chew Frequency", "Chew Variance" }) }, - { String ("deg_onoff"), StringArray ({ "Depth", "Amount", "Variance" }) }, + { String ("deg_onoff"), StringArray ({ "Depth", "Amount", "Variance", "Envelope" }) }, { String ("flutter_onoff"), StringArray ({ "Flutter Depth", "Flutter Rate", "Wow Depth", "Wow Rate", "Wow Variance", "Wow Drift" }) }, }; diff --git a/Plugin/Source/Processors/Degrade/DegradeProcessor.cpp b/Plugin/Source/Processors/Degrade/DegradeProcessor.cpp @@ -6,6 +6,7 @@ DegradeProcessor::DegradeProcessor (AudioProcessorValueTreeState& vts) depthParam = vts.getRawParameterValue ("deg_depth"); amtParam = vts.getRawParameterValue ("deg_amt"); varParam = vts.getRawParameterValue ("deg_var"); + envParam = vts.getRawParameterValue ("deg_env"); } void DegradeProcessor::createParameterLayout (std::vector<std::unique_ptr<RangedAudioParameter>>& params) @@ -14,6 +15,7 @@ void DegradeProcessor::createParameterLayout (std::vector<std::unique_ptr<Ranged params.push_back (std::make_unique<AudioParameterFloat> ("deg_depth", "Degrade Depth", 0.0f, 1.0f, 0.0f)); params.push_back (std::make_unique<AudioParameterFloat> ("deg_amt", "Degrade Amount", 0.0f, 1.0f, 0.0f)); params.push_back (std::make_unique<AudioParameterFloat> ("deg_var", "Degrade Variance", 0.0f, 1.0f, 0.0f)); + params.push_back (std::make_unique<AudioParameterFloat> ("deg_env", "Degrade Envelope", 0.0f, 1.0f, 0.0f)); } void DegradeProcessor::cookParams() @@ -27,6 +29,8 @@ void DegradeProcessor::cookParams() filterProc[ch].setFreq (jmin (freqHz + (*varParam * (freqHz / 0.6f) * (random.nextFloat() - 0.5f)), 0.49f * fs)); } + auto envSkew = 1.0f - std::pow (envParam->load(), 0.8f); + levelDetector.setParameters (10.0f, 20.0f * std::pow (5000.0f / 20.0f, envSkew)); gainProc.setGain (Decibels::decibelsToGain (jmin (gainDB + (*varParam * 36.0f * (random.nextFloat() - 0.5f)), 3.0f))); } @@ -41,6 +45,10 @@ void DegradeProcessor::prepareToPlay (double sampleRate, int samplesPerBlock) filterProc[ch].reset ((float) sampleRate, 20); } + noiseBuffer.setSize (2, samplesPerBlock); + levelBuffer.setSize (1, samplesPerBlock); + + levelDetector.prepare ({ sampleRate, (uint32) samplesPerBlock, 2 }); gainProc.prepareToPlay (sampleRate, samplesPerBlock); bypass.prepare (samplesPerBlock, bypass.toBool (onOffParam)); } @@ -50,12 +58,30 @@ void DegradeProcessor::processBlock (AudioBuffer<float>& buffer, MidiBuffer& mid if (! bypass.processBlockIn (buffer, bypass.toBool (onOffParam))) return; + const auto numChannels = buffer.getNumChannels(); + const auto numSamples = buffer.getNumSamples(); + cookParams(); + noiseBuffer.clear(); + + dsp::AudioBlock<float> block (buffer); + dsp::AudioBlock<float> levelBlock (levelBuffer.getArrayOfWritePointers(), 1, numSamples); + dsp::ProcessContextNonReplacing<float> levelContext (block, levelBlock); + levelDetector.process (levelContext); + auto* levelPtr = levelBuffer.getReadPointer (0); - for (int ch = 0; ch < buffer.getNumChannels(); ++ch) + for (int ch = 0; ch < numChannels; ++ch) { - noiseProc[ch].processBlock (buffer.getWritePointer (ch), buffer.getNumSamples()); - filterProc[ch].process (buffer.getWritePointer (ch), buffer.getNumSamples()); + auto* noisePtr = noiseBuffer.getWritePointer (ch); + noiseProc[ch].processBlock (noisePtr, numSamples); + + if (envParam->load() > 0.0f) + FloatVectorOperations::multiply (noisePtr, levelPtr, numSamples); + + auto* xPtr = buffer.getWritePointer (ch); + FloatVectorOperations::add (xPtr, noisePtr, numSamples); + + filterProc[ch].process (xPtr, numSamples); } gainProc.processBlock (buffer, midi); diff --git a/Plugin/Source/Processors/Degrade/DegradeProcessor.h b/Plugin/Source/Processors/Degrade/DegradeProcessor.h @@ -22,11 +22,17 @@ private: std::atomic<float>* depthParam = nullptr; std::atomic<float>* amtParam = nullptr; std::atomic<float>* varParam = nullptr; + std::atomic<float>* envParam = nullptr; - DegradeNoise noiseProc[2]; DegradeFilter filterProc[2]; GainProcessor gainProc; + AudioBuffer<float> noiseBuffer; + DegradeNoise noiseProc[2]; + + AudioBuffer<float> levelBuffer; + chowdsp::LevelDetector<float> levelDetector; + Random random; float fs = 44100.0f;