AnalogTapeModel

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

commit 742c0a532a8a2959226717e5fc7df5827cb85ceb
parent f71cb81dc1cb14ccfe1fdd517f5cb662b47c3e9c
Author: jatinchowdhury18 <[email protected]>
Date:   Mon, 27 Apr 2020 23:14:22 -0700

Global dry/wet (#25)

Co-authored-by: jatinchowdhury18 <[email protected]>
Diffstat:
MPlugin/CHOWTapeModel.jucer | 2++
MPlugin/Source/PluginProcessor.cpp | 10++++++++++
MPlugin/Source/PluginProcessor.h | 4++++
APlugin/Source/Processors/DryWetProcessor.h | 47+++++++++++++++++++++++++++++++++++++++++++++++
MPlugin/Source/gui.xml | 4+++-
5 files changed, 66 insertions(+), 1 deletion(-)

diff --git a/Plugin/CHOWTapeModel.jucer b/Plugin/CHOWTapeModel.jucer @@ -44,6 +44,8 @@ <FILE id="cVSIAR" name="Flutter.cpp" compile="1" resource="0" file="Source/Processors/Timing_Effects/Flutter.cpp"/> <FILE id="Wz3lz6" name="Flutter.h" compile="0" resource="0" file="Source/Processors/Timing_Effects/Flutter.h"/> </GROUP> + <FILE id="YNkJOh" name="DryWetProcessor.h" compile="0" resource="0" + file="Source/Processors/DryWetProcessor.h"/> <FILE id="zwLvQ9" name="GainProcessor.h" compile="0" resource="0" file="Source/Processors/GainProcessor.h"/> </GROUP> <FILE id="zPJjtw" name="PluginProcessor.cpp" compile="1" resource="0" diff --git a/Plugin/Source/PluginProcessor.cpp b/Plugin/Source/PluginProcessor.cpp @@ -44,6 +44,7 @@ AudioProcessorValueTreeState::ParameterLayout ChowtapeModelAudioProcessor::creat params.push_back (std::make_unique<AudioParameterFloat> ("ingain", "Input Gain [dB]", -30.0f, 6.0f, 0.0f)); params.push_back (std::make_unique<AudioParameterFloat> ("outgain", "Output Gain [dB]", -30.0f, 30.0f, 0.0f)); + params.push_back (std::make_unique<AudioParameterFloat> ("drywet", "Dry/Wet", 0.0f, 100.0f, 100.0f)); HysteresisProcessor::createParameterLayout (params); LossFilter::createParameterLayout (params); @@ -131,6 +132,10 @@ void ChowtapeModelAudioProcessor::prepareToPlay (double sampleRate, int samplesP outGain.prepareToPlay (sampleRate, samplesPerBlock); scope->prepareToPlay (sampleRate, samplesPerBlock); + + dryWet.setDryWet (*vts.getRawParameterValue ("drywet")); + dryWet.reset(); + dryBuffer.setSize (2, samplesPerBlock); } void ChowtapeModelAudioProcessor::releaseResources() @@ -168,8 +173,12 @@ void ChowtapeModelAudioProcessor::processBlock (AudioBuffer<float>& buffer, Midi inGain.setGain (Decibels::decibelsToGain (*vts.getRawParameterValue ("ingain"))); outGain.setGain (Decibels::decibelsToGain (*vts.getRawParameterValue ("outgain"))); + dryWet.setDryWet (*vts.getRawParameterValue ("drywet")); inGain.processBlock (buffer, midiMessages); + + dryBuffer.makeCopyOf (buffer, true); + hysteresis.processBlock (buffer, midiMessages); chewer.processBlock (buffer); degrade.processBlock (buffer, midiMessages); @@ -179,6 +188,7 @@ void ChowtapeModelAudioProcessor::processBlock (AudioBuffer<float>& buffer, Midi for (int ch = 0; ch < buffer.getNumChannels(); ++ch) lossFilter[ch]->processBlock (buffer.getWritePointer (ch), buffer.getNumSamples()); + dryWet.processBlock (dryBuffer, buffer); outGain.processBlock (buffer, midiMessages); scope->pushSamples (buffer); diff --git a/Plugin/Source/PluginProcessor.h b/Plugin/Source/PluginProcessor.h @@ -17,6 +17,7 @@ #include "Processors/Timing_Effects/Flutter.h" #include "Processors/Degrade/DegradeProcessor.h" #include "Processors/Chew/ChewProcessor.h" +#include "Processors/DryWetProcessor.h" //============================================================================== /** @@ -73,7 +74,10 @@ private: ChewProcessor chewer; std::unique_ptr<LossFilter> lossFilter[2]; Flutter flutter; + DryWetProcessor dryWet; GainProcessor outGain; + + AudioBuffer<float> dryBuffer; foleys::MagicProcessorState magicState { *this, vts }; foleys::MagicPlotSource* scope = nullptr; diff --git a/Plugin/Source/Processors/DryWetProcessor.h b/Plugin/Source/Processors/DryWetProcessor.h @@ -0,0 +1,47 @@ +#ifndef DRYWETPROCESSOR_H_INCLUDED +#define DRYWETPROCESSOR_H_INCLUDED + +#include "JuceHeader.h" + +/** Simple processor to mix dry and wet signals */ +class DryWetProcessor +{ +public: + DryWetProcessor() {} + + void setDryWet (float newDryWet) { dryWet = newDryWet; } + + void reset() { lastDryWet = dryWet; } + + /** + Mix dry and wet buffer. Mixed buffer returned in place of wet buffer + */ + void processBlock (AudioBuffer<float>& dryBuffer, AudioBuffer<float>& wetBuffer) + { + if (lastDryWet == dryWet) + { + wetBuffer.applyGain (dryWet); + for (int ch = 0; ch < wetBuffer.getNumChannels(); ++ch) + wetBuffer.addFrom (ch, 0, dryBuffer.getReadPointer (ch), wetBuffer.getNumSamples(), (1.0f - dryWet)); + } + else + { + for (int ch = 0; ch < wetBuffer.getNumChannels(); ++ch) + { + wetBuffer.applyGainRamp (ch, 0, wetBuffer.getNumSamples(), lastDryWet, dryWet); + wetBuffer.addFromWithRamp (ch, 0, dryBuffer.getReadPointer (ch), wetBuffer.getNumSamples(), + (1.0f - lastDryWet), (1.0f - dryWet)); + } + + lastDryWet = dryWet; + } + } + +private: + float dryWet = 0.0f; + float lastDryWet = 0.0f; + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DryWetProcessor) +}; + +#endif //DRYWETPROCESSOR_H_INCLUDED diff --git a/Plugin/Source/gui.xml b/Plugin/Source/gui.xml @@ -31,10 +31,12 @@ </View> <View background-color="FF7D2C2C" padding="0" margin=""> <View flex-direction="column" margin="5" padding=""> - <Label max-height="40"/> + <Label max-height="5"/> <Slider caption="Input Gain [dB]" parameter="ingain" slider-textbox="textbox-below" slider-type="rotary" max-height="160"/> <ComboBox caption="Oversampling" parameter="os" max-height="70"/> + <Slider caption="Dry/Wet" parameter="drywet" slider-textbox="textbox-below" + slider-type="rotary" max-height="170"/> <Slider caption="Output Gain [dB]" parameter="outgain" slider-textbox="textbox-below" slider-type="rotary" max-height="170"/> </View>