Skip to content

Commit

Permalink
WIP get some sidechain in there
Browse files Browse the repository at this point in the history
more wip

use whole buffer for metere
  • Loading branch information
JoseDiazRohena committed Aug 31, 2024
1 parent 0f46792 commit 631e405
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 20 deletions.
23 changes: 18 additions & 5 deletions libs/tote_bag/dsp/Compressor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ void Compressor::setOversampleMultiplier (const int o)
overSampleMultiplier = o - 1;
}

inline void Compressor::makeMonoSidechain (const juce::dsp::AudioBlock<float>& inAudio, juce::AudioBuffer<float>& scSignal)
inline void Compressor::makeMonoSidechain (const juce::dsp::AudioBlock<float>& inAudio,
juce::AudioBuffer<float>& scSignal)
{
scSignal.clear();
auto* scWritePointer = scSignal.getWritePointer (0);
Expand Down Expand Up @@ -101,7 +102,9 @@ inline float Compressor::calculateGain (float inputSample)

else if (abs (doubleOvershoot) <= W)
{
cvOutput = inputSample + ((1.0f / R - 1.0f) * powf (overshoot + W / 2.0f, 2)) / (2.0f * W);
cvOutput =
inputSample
+ ((1.0f / R - 1.0f) * powf (overshoot + W / 2.0f, 2)) / (2.0f * W);
}
else
{
Expand All @@ -121,9 +124,18 @@ inline float Compressor::getMakeupGain()
return -threshold.get() * (1.0f / ratio.get() - 1.0f) / 2.0f;
}

void Compressor::process (juce::dsp::AudioBlock<float>& inAudio)
void Compressor::process (juce::dsp::AudioBlock<float>& inAudio,
juce::dsp::AudioBlock<float>* SChain)
{
makeMonoSidechain (inAudio, analysisSignal);
if (SChain)
{
makeMonoSidechain (*SChain, analysisSignal);
}
else
{
makeMonoSidechain (inAudio, analysisSignal);
}

auto numSamples = inAudio.getNumSamples();
auto numChannels = inAudio.getNumChannels();

Expand All @@ -132,7 +144,8 @@ void Compressor::process (juce::dsp::AudioBlock<float>& inAudio)
{
auto controlVoltage = juce::Decibels::gainToDecibels (abs (sidechain[sample]));
// TODO: level detector methods should be float or templated
controlVoltage = static_cast<float> (levelDetector.processSampleDecoupledBranched (controlVoltage));
controlVoltage = static_cast<float> (
levelDetector.processSampleDecoupledBranched (controlVoltage));

controlVoltage = calculateGain (controlVoltage);
controlVoltage = juce::Decibels::decibelsToGain (controlVoltage);
Expand Down
2 changes: 1 addition & 1 deletion libs/tote_bag/dsp/Compressor.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class Compressor

float calculateGain (float analysisSample);

void process (juce::dsp::AudioBlock<float>& inAudio);
void process (juce::dsp::AudioBlock<float>& inAudio, juce::dsp::AudioBlock<float>* sidechain = nullptr);

float getMakeupGain();

Expand Down
64 changes: 52 additions & 12 deletions src/PluginProcessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ ValentineAudioProcessor::ValentineAudioProcessor()
#if !JucePlugin_IsMidiEffect
#if !JucePlugin_IsSynth
.withInput ("Input", juce::AudioChannelSet::stereo(), true)
.withInput ("Sidechain", juce::AudioChannelSet::stereo(), true)
#endif
.withOutput ("Output", juce::AudioChannelSet::stereo(), true)
#endif
Expand All @@ -83,6 +84,9 @@ ValentineAudioProcessor::ValentineAudioProcessor()
, presetManager (this)
, processedDelayLine (32)
, cleanDelayLine (32)
, sidechainOversampler (2,
detail::kOversampleFactor,
Oversampling::filterHalfBandPolyphaseIIR)
#endif
{
initializeDSP();
Expand Down Expand Up @@ -253,6 +257,8 @@ void ValentineAudioProcessor::prepareToPlay (double sampleRate, int samplesPerBl

oversampler->reset();
oversampler->initProcessing (static_cast<size_t> (samplesPerBlock));
sidechainOversampler.reset();
sidechainOversampler.initProcessing (static_cast<size_t> (samplesPerBlock));

saturator->reset (sampleRate);
boundedSaturator->reset (sampleRate);
Expand Down Expand Up @@ -308,7 +314,13 @@ void ValentineAudioProcessor::processBlock (juce::AudioBuffer<float>& buffer,
juce::ScopedNoDenormals noDenormals;
auto totalNumInputChannels = getTotalNumInputChannels();
auto totalNumOutputChannels = getTotalNumOutputChannels();
auto bufferSize = buffer.getNumSamples();

auto inputOutputBuffer = getBusBuffer (buffer, true, 0);
auto sideChainBuffer = getBusBuffer (buffer, true, 1);

const auto numMainInputChannels = inputOutputBuffer.getNumChannels();

auto bufferSize = inputOutputBuffer.getNumSamples();
auto currentSamplesPerBlock = bufferSize;

if (latencyChanged.get())
Expand All @@ -321,19 +333,19 @@ void ValentineAudioProcessor::processBlock (juce::AudioBuffer<float>& buffer,
// oversampling latency. Copying into the process buffer after this, then, would undo the
// purpose of the delay: maintaining phase coherence between processed and unprocessed
// signals.
processBuffer.setSize (totalNumOutputChannels,
processBuffer.setSize (numMainInputChannels,
currentSamplesPerBlock,
true,
true,
true);
for (auto channel = 0; channel < totalNumInputChannels; ++channel)
for (auto channel = 0; channel < numMainInputChannels; ++channel)
processBuffer.copyFrom (channel,
0,
buffer.getReadPointer (channel),
buffer.getNumSamples());
inputOutputBuffer.getReadPointer (channel),
inputOutputBuffer.getNumSamples());

prepareInputBuffer (buffer,
totalNumInputChannels,
prepareInputBuffer (inputOutputBuffer,
numMainInputChannels,
totalNumOutputChannels,
currentSamplesPerBlock);

Expand All @@ -357,16 +369,41 @@ void ValentineAudioProcessor::processBlock (juce::AudioBuffer<float>& buffer,
}

auto g = compressValue.get();
for (int i = 0; i < totalNumOutputChannels; ++i)
processBuffer.applyGainRamp (i, 0, bufferSize, currentGain, g);

if (sideChainBuffer.getNumChannels() > 0)
{
for (int i = 0; i < totalNumOutputChannels; ++i)
{
sideChainBuffer.applyGainRamp (i, 0, bufferSize, currentGain, g);
}
}
else
{
for (int i = 0; i < totalNumOutputChannels; ++i)
processBuffer.applyGainRamp (i, 0, bufferSize, currentGain, g);
}

// for (int i = 0; i < totalNumOutputChannels; ++i)
// processBuffer.applyGainRamp (i, 0, bufferSize, currentGain, g);

currentGain = g;

// Upsample then do non-linear processing
juce::dsp::AudioBlock<float> processBlock (processBuffer);
juce::dsp::AudioBlock<float> highSampleRateBlock =
oversampler->processSamplesUp (processBlock);

ffCompressor->process (highSampleRateBlock);
if (sideChainBuffer.getNumChannels() > 0)
{
juce::dsp::AudioBlock<float> sidechain (sideChainBuffer);
juce::dsp::AudioBlock<float> highSampleRateSideChain =
sidechainOversampler.processSamplesUp (sideChainBuffer);
ffCompressor->process (highSampleRateBlock, &highSampleRateSideChain);
}
else
{
ffCompressor->process (highSampleRateBlock);
}

if (saturateOn.get())
{
Expand Down Expand Up @@ -428,11 +465,14 @@ void ValentineAudioProcessor::processBlock (juce::AudioBuffer<float>& buffer,
auto processed = processBuffer.getSample (i, j);
auto unprocessed = buffer.getSample (i, j);

buffer.setSample (i, j, mix * processed + (1.0f - currentMix) * unprocessed);
inputOutputBuffer.setSample (i,
j,
mix * processed
+ (1.0f - currentMix) * unprocessed);
}
}

outputMeterSource.measureBlock (buffer);
outputMeterSource.measureBlock (inputOutputBuffer);
}

void ValentineAudioProcessor::processBlockBypassed (juce::AudioBuffer<float>& buffer,
Expand Down
5 changes: 3 additions & 2 deletions src/PluginProcessor.h
Original file line number Diff line number Diff line change
Expand Up @@ -199,8 +199,8 @@ class ValentineAudioProcessor : public juce::AudioProcessor,
FFCompParameterDefaults[static_cast<size_t> (VParameter::outputClipEnable)]
> 0.5f};
bool clipOnState = clipOn.get();
juce::Atomic<bool> saturateOn = FFCompParameterDefaults[static_cast<size_t> (VParameter::saturateEnable)]
> 0.5f;
juce::Atomic<bool> saturateOn =
FFCompParameterDefaults[static_cast<size_t> (VParameter::saturateEnable)] > 0.5f;
bool saturateOnState = saturateOn.get();

// This is used for, yes you guessed it, processing
Expand All @@ -209,6 +209,7 @@ class ValentineAudioProcessor : public juce::AudioProcessor,
// DSP objects
std::unique_ptr<tote_bag::audio_helpers::SimpleOnePole<float>> dryWetFilter;
std::unique_ptr<Oversampling> oversampler;
Oversampling sidechainOversampler;
std::unique_ptr<Compressor> ffCompressor;
std::unique_ptr<Saturation> saturator;
std::unique_ptr<Saturation> boundedSaturator;
Expand Down

0 comments on commit 631e405

Please sign in to comment.