mirror of
https://codeberg.org/armin/saftpumpe.git
synced 2026-09-01 04:10:46 +02:00
add bypass parameter and DSP bypass logic
This commit is contained in:
parent
a82649e41e
commit
bd9aa2fa67
2 changed files with 58 additions and 4 deletions
|
|
@ -21,11 +21,17 @@ SaftpumpeProcessor::SaftpumpeProcessor()
|
|||
std::make_unique<juce::AudioParameterFloat>(
|
||||
mixID, "Mix", juce::NormalisableRange<float>(0.0f, 1.0f, 0.01f), 1.0f),
|
||||
std::make_unique<juce::AudioParameterFloat>(
|
||||
autoReleaseID, "Auto Release", juce::NormalisableRange<float>(0.0f, 1.0f, 0.01f), 1.0f)
|
||||
autoReleaseID, "Auto Release", juce::NormalisableRange<float>(0.0f, 1.0f, 0.01f), 1.0f),
|
||||
std::make_unique<juce::AudioParameterBool>(
|
||||
bypassID, "Bypass", false)
|
||||
})
|
||||
{
|
||||
inputScope.fill(0.0f);
|
||||
outputScope.fill(0.0f);
|
||||
fftInput.fill(0.0f);
|
||||
fftOutput.fill(0.0f);
|
||||
inputSpectrum.fill(0.0f);
|
||||
outputSpectrum.fill(0.0f);
|
||||
}
|
||||
|
||||
SaftpumpeProcessor::~SaftpumpeProcessor() {}
|
||||
|
|
@ -36,6 +42,7 @@ void SaftpumpeProcessor::prepareToPlay(double sampleRate, int samplesPerBlock) {
|
|||
compressorL.reset();
|
||||
compressorR.reset();
|
||||
scopeIndex = 0;
|
||||
fftIndex = 0;
|
||||
}
|
||||
|
||||
void SaftpumpeProcessor::releaseResources() {}
|
||||
|
|
@ -51,6 +58,8 @@ void SaftpumpeProcessor::processBlock(juce::AudioBuffer<float>& buffer, juce::Mi
|
|||
|
||||
updateCompressorParams();
|
||||
|
||||
bool bypassed = parameters.getRawParameterValue(bypassID)->load() > 0.5f;
|
||||
|
||||
float maxInput = 0.0f;
|
||||
float maxOutput = 0.0f;
|
||||
float maxGR = 0.0f;
|
||||
|
|
@ -67,9 +76,16 @@ void SaftpumpeProcessor::processBlock(juce::AudioBuffer<float>& buffer, juce::Mi
|
|||
if (absIn > maxInput) maxInput = absIn;
|
||||
|
||||
inputScope[scopeIndex] = inL;
|
||||
fftInput[fftIndex] = inL;
|
||||
|
||||
float outL = compressorL.processSample(inL);
|
||||
float outR = compressorR.processSample(inR);
|
||||
float outL, outR;
|
||||
if (bypassed) {
|
||||
outL = inL;
|
||||
outR = inR;
|
||||
} else {
|
||||
outL = compressorL.processSample(inL);
|
||||
outR = compressorR.processSample(inR);
|
||||
}
|
||||
|
||||
channelDataL[sample] = outL;
|
||||
if (channelDataR) channelDataR[sample] = outR;
|
||||
|
|
@ -77,11 +93,33 @@ void SaftpumpeProcessor::processBlock(juce::AudioBuffer<float>& buffer, juce::Mi
|
|||
float absOut = std::max(std::abs(outL), std::abs(outR));
|
||||
if (absOut > maxOutput) maxOutput = absOut;
|
||||
|
||||
float gr = std::abs(compressorL.getGainReduction());
|
||||
float gr = bypassed ? 0.0f : std::abs(compressorL.getGainReduction());
|
||||
if (gr > maxGR) maxGR = gr;
|
||||
|
||||
outputScope[scopeIndex] = outL;
|
||||
fftOutput[fftIndex] = outL;
|
||||
scopeIndex = (scopeIndex + 1) % scopeSize;
|
||||
fftIndex++;
|
||||
|
||||
if (fftIndex >= fftSize) {
|
||||
fftIndex = 0;
|
||||
|
||||
auto computeSpectrum = [&](const std::array<float, fftSize>& input,
|
||||
std::array<float, fftSize / 2>& spectrum) {
|
||||
std::array<float, fftSize * 2> buf{};
|
||||
std::copy(input.begin(), input.end(), buf.begin());
|
||||
window.multiplyWithWindowingTable(buf.data(), fftSize);
|
||||
fft.performFrequencyOnlyForwardTransform(buf.data(), true);
|
||||
for (int i = 0; i < fftSize / 2; ++i) {
|
||||
float db = (buf[i] > 0.00001f) ? 20.0f * std::log10(buf[i]) : -100.0f;
|
||||
float norm = juce::jlimit(0.0f, 1.0f, (db + 80.0f) / 80.0f);
|
||||
spectrum[i] = spectrum[i] * 0.7f + norm * 0.3f;
|
||||
}
|
||||
};
|
||||
|
||||
computeSpectrum(fftInput, inputSpectrum);
|
||||
computeSpectrum(fftOutput, outputSpectrum);
|
||||
}
|
||||
}
|
||||
|
||||
currentInputLevel = currentInputLevel * 0.8f + (maxInput > 0.0001f ? 20.0f * std::log10(maxInput) : -100.0f) * 0.2f;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#pragma once
|
||||
#include <juce_audio_processors/juce_audio_processors.h>
|
||||
#include <juce_dsp/juce_dsp.h>
|
||||
#include "CompressorDSP.h"
|
||||
|
||||
class SaftpumpeProcessor : public juce::AudioProcessor {
|
||||
|
|
@ -39,6 +40,7 @@ public:
|
|||
static constexpr const char* makeupID = "makeup";
|
||||
static constexpr const char* mixID = "mix";
|
||||
static constexpr const char* autoReleaseID = "autoRelease";
|
||||
static constexpr const char* bypassID = "bypass";
|
||||
|
||||
juce::AudioProcessorValueTreeState parameters;
|
||||
|
||||
|
|
@ -46,11 +48,25 @@ public:
|
|||
float getInputLevel() const { return currentInputLevel; }
|
||||
float getOutputLevel() const { return currentOutputLevel; }
|
||||
|
||||
bool isSpectrumMode() const { return spectrumMode; }
|
||||
void setSpectrumMode(bool on) { spectrumMode = on; }
|
||||
|
||||
static constexpr int scopeSize = 512;
|
||||
std::array<float, scopeSize> inputScope{};
|
||||
std::array<float, scopeSize> outputScope{};
|
||||
int scopeIndex = 0;
|
||||
|
||||
static constexpr int fftOrder = 10;
|
||||
static constexpr int fftSize = 1 << fftOrder;
|
||||
std::array<float, fftSize> fftInput{};
|
||||
std::array<float, fftSize> fftOutput{};
|
||||
int fftIndex = 0;
|
||||
juce::dsp::FFT fft{ fftOrder };
|
||||
juce::dsp::WindowingFunction<float> window{ fftSize, juce::dsp::WindowingFunction<float>::hann, true };
|
||||
std::array<float, fftSize / 2> inputSpectrum{};
|
||||
std::array<float, fftSize / 2> outputSpectrum{};
|
||||
bool spectrumMode = false;
|
||||
|
||||
private:
|
||||
CompressorDSP compressorL;
|
||||
CompressorDSP compressorR;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue