Skip to content

Commit

Permalink
Gate Level Tracking (#318)
Browse files Browse the repository at this point in the history
* Gate processAudio Adapted for Level Tracking I/O

* Gate processAudioBypassed Added

* Apply clang-format

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
  • Loading branch information
RachelMaryamLocke and github-actions[bot] committed Jul 10, 2023
1 parent 1ab0b57 commit 8a6b429
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 19 deletions.
86 changes: 68 additions & 18 deletions src/processors/other/Gate.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "Gate.h"
#include "../BufferHelpers.h"
#include "../ParameterHelpers.h"

class Gate::GateEnvelope
Expand Down Expand Up @@ -146,7 +147,8 @@ ParamLayout Gate::createParameterLayout()

void Gate::prepare (double sampleRate, int samplesPerBlock)
{
levelBuffer.setSize (1, samplesPerBlock);
audioOutBuffer.setSize (2, samplesPerBlock);
levelOutBuffer.setSize (1, samplesPerBlock);

gateEnvelope->prepare (sampleRate, samplesPerBlock);

Expand All @@ -156,33 +158,81 @@ void Gate::prepare (double sampleRate, int samplesPerBlock)

void Gate::processAudio (AudioBuffer<float>& buffer)
{
const auto numChannels = buffer.getNumChannels();
const auto numSamples = buffer.getNumSamples();

// set up level buffer
if (numChannels == 1)
//set up level output
levelOutBuffer.setSize (1, numSamples, false, false, true);
if (inputsConnected.contains (LevelInput))
{
levelBuffer.makeCopyOf (buffer);
BufferHelpers::collapseToMonoBuffer (getInputBuffer (LevelInput), levelOutBuffer);
}
else
{
levelBuffer.setSize (1, numSamples, true, true, false);
levelBuffer.copyFrom (0, 0, buffer, 0, 0, numSamples);
if (inputsConnected.contains (AudioInput))
{
BufferHelpers::collapseToMonoBuffer (getInputBuffer (AudioInput), levelOutBuffer);
}
else
{
levelOutBuffer.clear();
}
}

for (int ch = 1; ch < numChannels; ++ch)
levelBuffer.addFrom (0, 0, buffer, ch, 0, numSamples);
if (inputsConnected.contains (AudioInput))
{
gateEnvelope->setParameters (*threshDBParam, *attackMsParam, *holdMsParam, *releaseMsParam);
gateEnvelope->process (levelOutBuffer);

levelBuffer.applyGain (1.0f / (float) numChannels);
auto& audioInBuffer = getInputBuffer (AudioInput);
const auto numChannels = audioInBuffer.getNumChannels();
audioOutBuffer.setSize (numChannels, numSamples, false, false, true);
for (int ch = 0; ch < numChannels; ++ch)
{
FloatVectorOperations::multiply (audioOutBuffer.getWritePointer (ch), audioInBuffer.getReadPointer (ch), gateEnvelope->gainBlock.getChannelPointer (0), numSamples);
}

auto&& audioOutBlock = dsp::AudioBlock<float> { audioOutBuffer };
makeupGain.setGainDecibels (*makeupDBParam);
makeupGain.process (dsp::ProcessContextReplacing<float> { audioOutBlock });
}
else
{
audioOutBuffer.setSize (1, numSamples, false, false, true);
audioOutBuffer.clear();
}

auto&& levelBlock = dsp::AudioBlock<float> { levelBuffer };
gateEnvelope->setParameters (*threshDBParam, *attackMsParam, *holdMsParam, *releaseMsParam);
gateEnvelope->process (levelBlock);
outputBuffers.getReference (AudioOutput) = &audioOutBuffer;
outputBuffers.getReference (LevelOutput) = &levelOutBuffer;
}

void Gate::processAudioBypassed (AudioBuffer<float>& buffer)
{
const auto numSamples = buffer.getNumSamples();

auto&& block = dsp::AudioBlock<float> { buffer };
for (int ch = 0; ch < numChannels; ++ch)
block.getSingleChannelBlock ((size_t) ch) *= gateEnvelope->gainBlock;
levelOutBuffer.setSize (1, numSamples, false, false, true);
if (inputsConnected.contains (LevelInput)) //make mono and pass samples through
{
const auto& levelInputBuffer = getInputBuffer (LevelInput);
BufferHelpers::collapseToMonoBuffer (levelInputBuffer, levelOutBuffer);
}
else
{
levelOutBuffer.clear();
}

makeupGain.setGainDecibels (*makeupDBParam);
makeupGain.process (dsp::ProcessContextReplacing<float> { block });
if (inputsConnected.contains (AudioInput))
{
const auto& audioInBuffer = getInputBuffer (AudioInput);
const auto numChannels = audioInBuffer.getNumChannels();
audioOutBuffer.setSize (numChannels, numSamples, false, false, true);
for (int ch = 0; ch < numChannels; ++ch)
audioOutBuffer.copyFrom (ch, 0, audioInBuffer, ch % numChannels, 0, numSamples);
}
else
{
audioOutBuffer.setSize (1, numSamples, false, false, true);
audioOutBuffer.clear();
}
outputBuffers.getReference (AudioOutput) = &audioOutBuffer;
outputBuffers.getReference (LevelOutput) = &levelOutBuffer;
}
4 changes: 3 additions & 1 deletion src/processors/other/Gate.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ class Gate : public BaseProcessor

void prepare (double sampleRate, int samplesPerBlock) override;
void processAudio (AudioBuffer<float>& buffer) override;
void processAudioBypassed (AudioBuffer<float>& buffer) override;

enum InputPort
{
Expand All @@ -36,7 +37,8 @@ class Gate : public BaseProcessor
chowdsp::FloatParameter* releaseMsParam = nullptr;
chowdsp::FloatParameter* makeupDBParam = nullptr;

AudioBuffer<float> levelBuffer;
AudioBuffer<float> levelOutBuffer;
AudioBuffer<float> audioOutBuffer;

class GateEnvelope;
std::unique_ptr<GateEnvelope> gateEnvelope;
Expand Down

0 comments on commit 8a6b429

Please sign in to comment.