commit ba9b6c50a833149e21f0f1f838db455f5513faf5
parent 252953fde9d6eef498b7f9728477eff13055b089
Author: jatinchowdhury18 <jatinchowdhury18@users.noreply.github.com>
Date: Sat, 18 Apr 2020 20:58:15 -0700
Add chew processing
Diffstat:
7 files changed, 188 insertions(+), 0 deletions(-)
diff --git a/Plugin/CHOWTapeModel.jucer b/Plugin/CHOWTapeModel.jucer
@@ -8,6 +8,12 @@
<GROUP id="{0178B10A-4A61-796A-5AB2-915D32AF6EEE}" name="Source">
<FILE id="Xn3V5v" name="gui.xml" compile="0" resource="1" file="Source/gui.xml"/>
<GROUP id="{43BBFC88-4D0A-01B8-2635-3748470B94F4}" name="Processors">
+ <GROUP id="{2F544AA2-63D9-E54A-A753-2E6249E85E60}" name="Chew">
+ <FILE id="S5eP4b" name="ChewProcessor.cpp" compile="1" resource="0"
+ file="Source/Processors/Chew/ChewProcessor.cpp"/>
+ <FILE id="shEGgj" name="ChewProcessor.h" compile="0" resource="0" file="Source/Processors/Chew/ChewProcessor.h"/>
+ <FILE id="gw6Axu" name="Dropout.h" compile="0" resource="0" file="Source/Processors/Chew/Dropout.h"/>
+ </GROUP>
<GROUP id="{344B63D7-2DBC-F9D2-ACD7-1B0671D4D024}" name="Degrade">
<FILE id="ac7jRp" name="DegradeFilter.h" compile="0" resource="0" file="Source/Processors/Degrade/DegradeFilter.h"/>
<FILE id="qWC1GC" name="DegradeNoise.h" compile="0" resource="0" file="Source/Processors/Degrade/DegradeNoise.h"/>
diff --git a/Plugin/Source/PluginProcessor.cpp b/Plugin/Source/PluginProcessor.cpp
@@ -25,6 +25,7 @@ ChowtapeModelAudioProcessor::ChowtapeModelAudioProcessor()
vts (*this, nullptr, Identifier ("Parameters"), createParameterLayout()),
hysteresis (vts),
degrade (vts),
+ chewer (vts),
flutter (vts)
{
for (int ch = 0; ch < 2; ++ch)
@@ -48,6 +49,7 @@ AudioProcessorValueTreeState::ParameterLayout ChowtapeModelAudioProcessor::creat
LossFilter::createParameterLayout (params);
Flutter::createParameterLayout (params);
DegradeProcessor::createParameterLayout (params);
+ ChewProcessor::createParameterLayout (params);
return { params.begin(), params.end() };
}
@@ -120,6 +122,7 @@ void ChowtapeModelAudioProcessor::prepareToPlay (double sampleRate, int samplesP
inGain.prepareToPlay (sampleRate, samplesPerBlock);
hysteresis.prepareToPlay (sampleRate, samplesPerBlock);
degrade.prepareToPlay (sampleRate, samplesPerBlock);
+ chewer.prepare (sampleRate, samplesPerBlock);
for (int ch = 0; ch < 2; ++ch)
lossFilter[ch]->prepare ((float) sampleRate, samplesPerBlock);
@@ -169,6 +172,7 @@ void ChowtapeModelAudioProcessor::processBlock (AudioBuffer<float>& buffer, Midi
inGain.processBlock (buffer, midiMessages);
hysteresis.processBlock (buffer, midiMessages);
degrade.processBlock (buffer, midiMessages);
+ chewer.processBlock (buffer);
flutter.processBlock (buffer, midiMessages);
diff --git a/Plugin/Source/PluginProcessor.h b/Plugin/Source/PluginProcessor.h
@@ -16,6 +16,7 @@
#include "Processors/Loss_Effects/LossFilter.h"
#include "Processors/Timing_Effects/Flutter.h"
#include "Processors/Degrade/DegradeProcessor.h"
+#include "Processors/Chew/ChewProcessor.h"
//==============================================================================
/**
@@ -69,6 +70,7 @@ private:
GainProcessor inGain;
HysteresisProcessor hysteresis;
DegradeProcessor degrade;
+ ChewProcessor chewer;
std::unique_ptr<LossFilter> lossFilter[2];
Flutter flutter;
GainProcessor outGain;
diff --git a/Plugin/Source/Processors/Chew/ChewProcessor.cpp b/Plugin/Source/Processors/Chew/ChewProcessor.cpp
@@ -0,0 +1,56 @@
+#include "ChewProcessor.h"
+
+ChewProcessor::ChewProcessor (AudioProcessorValueTreeState& vts)
+{
+ depth = vts.getRawParameterValue ("chew_depth");
+ freq = vts.getRawParameterValue ("chew_freq");
+}
+
+void ChewProcessor::createParameterLayout (std::vector<std::unique_ptr<RangedAudioParameter>>& params)
+{
+ params.push_back (std::make_unique<AudioParameterFloat> ("chew_depth", "Depth", 0.0f, 1.0f, 0.0f));
+ params.push_back (std::make_unique<AudioParameterFloat> ("chew_freq", "Freq", 0.0f, 1.0f, 0.0f));
+}
+
+void ChewProcessor::prepare (double sr, int samplesPerBlock)
+{
+ sampleRate = (float) sr;
+
+ dropout.prepare (samplesPerBlock);
+
+ isCrinkled = false;
+ samplesUntilChange = getDryTime();
+ sampleCounter = 0;
+}
+
+void ChewProcessor::processBlock (AudioBuffer<float>& buffer)
+{
+ if (*depth == 0.0f)
+ return;
+
+ if (sampleCounter >= samplesUntilChange)
+ {
+ sampleCounter = 0;
+ isCrinkled = ! isCrinkled;
+
+ if (isCrinkled) // start crinkle
+ {
+ mix = 1.0f;
+ power = 0.5f; //depth->control->get();
+ samplesUntilChange = getWetTime();
+ }
+ else // end crinkle
+ {
+ mix = 0.0f;
+ power = 0.0f;
+ samplesUntilChange = getDryTime();
+ }
+ }
+
+ dropout.setMix (mix);
+ dropout.setPow (1.0f + 4.0f * power);
+
+ dropout.process (buffer);
+
+ sampleCounter += buffer.getNumSamples();
+}
diff --git a/Plugin/Source/Processors/Chew/ChewProcessor.h b/Plugin/Source/Processors/Chew/ChewProcessor.h
@@ -0,0 +1,45 @@
+#ifndef CHEWPROCESSOR_H_INCLUDED
+#define CHEWPROCESSOR_H_INCLUDED
+
+#include "Dropout.h"
+
+class ChewProcessor
+{
+public:
+ ChewProcessor (AudioProcessorValueTreeState& vts);
+
+ static void createParameterLayout (std::vector<std::unique_ptr<RangedAudioParameter>>& params);
+
+ void prepare (double sr, int samplesPerBlock);
+ void processBlock (AudioBuffer<float>& buffer);
+
+private:
+ float* depth = nullptr;
+ float* freq = nullptr;
+
+ float mix = 0.0f;
+ float power = 0.0f;
+
+ Dropout dropout;
+
+ Random random;
+ int samplesUntilChange = 1000;
+ bool isCrinkled = false;
+ int sampleCounter = 0;
+
+ float sampleRate = 44100.0f;
+
+ inline int getDryTime()
+ {
+ return random.nextInt (Range<int> ((int) ((1.0 - *freq) * sampleRate), (int) ((2 - 1.8 * *freq) * sampleRate)));
+ }
+
+ inline int getWetTime()
+ {
+ return random.nextInt (Range<int> ((int) ((0.05 + 0.05f * *depth) * sampleRate), (int) ((0.8 + 0.8 * *depth) * sampleRate)));
+ }
+
+ JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ChewProcessor)
+};
+
+#endif // CHEWPROCESSOR_H_INCLUDED
diff --git a/Plugin/Source/Processors/Chew/Dropout.h b/Plugin/Source/Processors/Chew/Dropout.h
@@ -0,0 +1,75 @@
+#ifndef DROPOUT_H_INCLUDED
+#define DROPOUT_H_INCLUDED
+
+#include "JuceHeader.h"
+
+class Dropout
+{
+public:
+ Dropout() {}
+
+ void setMix (float newMix) { curMix = newMix; }
+ void setPow (float newPow) { power = newPow; }
+
+ void prepare (int maxBufferSize)
+ {
+ dryBuffer.setSize (2, maxBufferSize);
+
+ prevMix = curMix;
+ }
+
+ void process (AudioBuffer<float>& buffer)
+ {
+ if (curMix == 0.0f)
+ return;
+
+ // copy dry buffer
+ for (int ch = 0; ch < buffer.getNumChannels(); ++ch)
+ {
+ dryBuffer.copyFrom (ch, 0, buffer.getReadPointer (ch), buffer.getNumSamples());
+
+ auto* x = buffer.getWritePointer (ch);
+ for (int n = 0; n < buffer.getNumSamples(); ++n)
+ x[n] = dropout (x[n]);
+ }
+
+ if (curMix == prevMix)
+ {
+ buffer.applyGain (curMix);
+
+ for (int ch = 0; ch < buffer.getNumChannels(); ++ch)
+ buffer.addFrom (ch, 0, dryBuffer.getReadPointer (ch), buffer.getNumSamples(), (1.0f - curMix));
+ }
+ else
+ {
+ buffer.applyGainRamp (0, buffer.getNumSamples(), prevMix, curMix);
+
+ for (int ch = 0; ch < buffer.getNumChannels(); ++ch)
+ buffer.addFromWithRamp (ch, 0, dryBuffer.getReadPointer (ch), buffer.getNumSamples(), (1.0f - prevMix), (1.0f - curMix));
+
+ prevMix = curMix;
+ }
+ }
+
+ inline float dropout (float x)
+ {
+ float sign = 0.0f;
+ if (x < 0.0f)
+ sign = -1.0f;
+ else if (x > 0.0f)
+ sign = 1.0f;
+
+ return std::powf (abs (x), power) * sign / power;
+ }
+
+private:
+ float curMix = 0.0f;
+ float prevMix = curMix;
+ float power = 1.0f;
+
+ AudioBuffer<float> dryBuffer;
+
+ JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Dropout)
+};
+
+#endif // DROPOUT_H_INCLUDED
diff --git a/Plugin/Source/gui.xml b/Plugin/Source/gui.xml
Binary files differ.