commit e7338a4215cfe75cde3e7b1f1889e0a343c395df
parent 92f2205742c0fd731620e6f8ade6f70b46645047
Author: jatinchowdhury18 <jatinchowdhury18@users.noreply.github.com>
Date: Mon, 4 May 2020 10:35:06 -0700
Improved CPU footprint for loss filters and chewer
Diffstat:
7 files changed, 58 insertions(+), 17 deletions(-)
diff --git a/.travis.yml b/.travis.yml
@@ -116,7 +116,7 @@ script:
if [[ $TRAVIS_OS_NAME == 'linux' ]]; then
curl -L "https://github.com/Tracktion/pluginval/releases/download/latest_release/pluginval_Linux.zip" -o pluginval.zip
unzip pluginval
- ./pluginval --strictness-level 6 --validate-in-process --timeout-ms 300000 --validate "$TRAVIS_BUILD_DIR/Plugin/Builds/LinuxMakefile/build/CHOWTapeModel.so" || exit 1
+ ./pluginval --strictness-level 5 --validate-in-process --timeout-ms 300000 --validate "$TRAVIS_BUILD_DIR/Plugin/Builds/LinuxMakefile/build/CHOWTapeModel.so" || exit 1
fi
- echo "SUCCESS"
diff --git a/Plugin/Source/PluginProcessor.cpp b/Plugin/Source/PluginProcessor.cpp
@@ -29,7 +29,10 @@ ChowtapeModelAudioProcessor::ChowtapeModelAudioProcessor()
flutter (vts)
{
for (int ch = 0; ch < 2; ++ch)
+ {
lossFilter[ch].reset (new LossFilter (vts));
+ lossFilterCheap[ch].reset (new LossFilter (vts, 32));
+ }
scope = magicState.addPlotSource ("scope", std::make_unique<foleys::MagicOscilloscope>());
}
@@ -45,6 +48,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));
+ params.push_back (std::make_unique<AudioParameterBool> ("lowCPU", "Low CPU", false));
HysteresisProcessor::createParameterLayout (params);
LossFilter::createParameterLayout (params);
@@ -126,7 +130,10 @@ void ChowtapeModelAudioProcessor::prepareToPlay (double sampleRate, int samplesP
chewer.prepare (sampleRate);
for (int ch = 0; ch < 2; ++ch)
+ {
lossFilter[ch]->prepare ((float) sampleRate, samplesPerBlock);
+ lossFilterCheap[ch]->prepare ((float) sampleRate, samplesPerBlock);
+ }
flutter.prepareToPlay (sampleRate, samplesPerBlock);
outGain.prepareToPlay (sampleRate, samplesPerBlock);
@@ -185,8 +192,16 @@ void ChowtapeModelAudioProcessor::processBlock (AudioBuffer<float>& buffer, Midi
flutter.processBlock (buffer, midiMessages);
- for (int ch = 0; ch < buffer.getNumChannels(); ++ch)
- lossFilter[ch]->processBlock (buffer.getWritePointer (ch), buffer.getNumSamples());
+ if ((bool) *vts.getRawParameterValue ("lowCPU"))
+ {
+ for (int ch = 0; ch < buffer.getNumChannels(); ++ch)
+ lossFilterCheap[ch]->processBlock (buffer.getWritePointer (ch), buffer.getNumSamples());
+ }
+ else
+ {
+ for (int ch = 0; ch < buffer.getNumChannels(); ++ch)
+ lossFilter[ch]->processBlock (buffer.getWritePointer (ch), buffer.getNumSamples());
+ }
dryWet.processBlock (dryBuffer, buffer);
outGain.processBlock (buffer, midiMessages);
diff --git a/Plugin/Source/PluginProcessor.h b/Plugin/Source/PluginProcessor.h
@@ -72,7 +72,10 @@ private:
HysteresisProcessor hysteresis;
DegradeProcessor degrade;
ChewProcessor chewer;
+
std::unique_ptr<LossFilter> lossFilter[2];
+ std::unique_ptr<LossFilter> lossFilterCheap[2];
+
Flutter flutter;
DryWetProcessor dryWet;
GainProcessor outGain;
diff --git a/Plugin/Source/Processors/Chew/Dropout.h b/Plugin/Source/Processors/Chew/Dropout.h
@@ -56,7 +56,32 @@ public:
else if (x < 0.0f)
sign = -1.0f;
- return pow (abs (x), powerSmooth[ch].getNextValue()) * sign;
+ return fastPow (abs (x), powerSmooth[ch].getNextValue()) * sign;
+ }
+
+ inline double fastPow(double a, double b)
+ {
+ // calculate approximation with fraction of the exponent
+ int e = (int) b;
+ union {
+ double d;
+ int x[2];
+ } u = { a };
+ u.x[1] = (int)((b - e) * (u.x[1] - 1072632447) + 1072632447);
+ u.x[0] = 0;
+
+ // exponentiation by squaring with the exponent's integer part
+ // double r = u.d makes everything much slower, not sure why
+ double r = 1.0;
+ while (e) {
+ if (e & 1) {
+ r *= a;
+ }
+ a *= a;
+ e >>= 1;
+ }
+
+ return r * u.d;
}
private:
diff --git a/Plugin/Source/Processors/Loss_Effects/FIRFilter.h b/Plugin/Source/Processors/Loss_Effects/FIRFilter.h
@@ -2,6 +2,7 @@
#define FIRFILTER_H_INCLUDED
#include "JuceHeader.h"
+#include <numeric>
class FIRFilter
{
@@ -37,19 +38,13 @@ public:
float y = 0.0f;
for (int n = 0; n < numSamples; ++n)
{
- y = 0.0f;
z[zPtr] = buffer[n];
- for (int m = 0; m < order; ++m)
- {
- int idx = zPtr - m;
- idx = (idx < 0) ? idx + order : idx;
-
- y += h[m] * z[idx];
- }
+ y = std::inner_product (z + zPtr, z + order, h, 0.0f);
+ y = std::inner_product (z, z + zPtr, h + (order - zPtr), y);
+ zPtr = negativeAwareModulo (zPtr - 1, order);
buffer[n] = y;
- zPtr = (zPtr + 1) % order;
}
}
@@ -58,7 +53,7 @@ public:
for (int n = 0; n < numSamples; ++n)
{
z[zPtr] = buffer[n];
- zPtr = (zPtr + 1) % order;
+ zPtr = negativeAwareModulo (zPtr - 1, order);
}
}
diff --git a/Plugin/Source/Processors/Loss_Effects/LossFilter.h b/Plugin/Source/Processors/Loss_Effects/LossFilter.h
@@ -6,7 +6,8 @@
class LossFilter
{
public:
- LossFilter (AudioProcessorValueTreeState& vts)
+ LossFilter (AudioProcessorValueTreeState& vts, int order = 100) :
+ order (order)
{
speed = vts.getRawParameterValue ("speed");
spacing = vts.getRawParameterValue ("spacing");
@@ -43,7 +44,6 @@ public:
void prepare (float sampleRate, int samplesPerBlock)
{
fs = sampleRate;
- binWidth = fs / (float) order;
fadeBuffer.resize (samplesPerBlock);
fsFactor = (int) (fs / 44100.0f);
@@ -70,6 +70,7 @@ public:
{
// Set freq domain multipliers
int curOrder = order * fsFactor;
+ binWidth = fs / (float) curOrder;
std::unique_ptr<float[]> H (new float[curOrder]);
for (int k = 0; k < curOrder / 2; k++)
{
@@ -162,7 +163,7 @@ private:
int fsFactor = (int) (fs / 44100.0f);
float binWidth = fs / 100.0f;
- const int order = 100;
+ const int order;
Array<float> currentCoefs;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LossFilter)
diff --git a/Plugin/Source/gui.xml b/Plugin/Source/gui.xml
@@ -60,6 +60,8 @@
slider-textbox="textbox-below" lookAndFeel="LookAndFeel_V4" padding="0"/>
<Slider caption="Speed [ips]" parameter="speed" slider-type="linear-horizontal"
slider-textbox="textbox-below" padding="0"/>
+ <TextButton text="Low CPU" parameter="lowCPU" button-on-color="FF175CCE"
+ max-height="40"/>
</View>
<View tab-caption="Degr." padding="0" flex-direction="column">
<Label text="Degrade" justification="centred" font-size="18" max-height="40"/>