Skip to content

Commit

Permalink
bunch of WIP trying to get the effects changing
Browse files Browse the repository at this point in the history
  • Loading branch information
vberthiaume committed Oct 23, 2024
1 parent 12e4e02 commit ec7f9af
Show file tree
Hide file tree
Showing 5 changed files with 157 additions and 9 deletions.
6 changes: 6 additions & 0 deletions source/DSP/ProPhatProcessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,12 @@ bool ProPhatProcessor::isBusesLayoutSupported (const BusesLayout& layouts) const
}
#endif

void ProPhatProcessor::changeEffect()
{
isUsingDoublePrecision() ? proPhatSynthDouble.changeEffect()
: proPhatSynthFloat.changeEffect();
}

void ProPhatProcessor::processBlock (juce::AudioBuffer<float>& buffer, juce::MidiBuffer& midiMessages)
{
jassert (! isUsingDoublePrecision());
Expand Down
2 changes: 2 additions & 0 deletions source/DSP/ProPhatProcessor.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ class ProPhatProcessor : public juce::AudioProcessor
bool isBusesLayoutSupported (const BusesLayout& layouts) const override;
#endif

void changeEffect();

void processBlock (juce::AudioBuffer<float>&, juce::MidiBuffer&) override;
void processBlock (juce::AudioBuffer<double>&, juce::MidiBuffer&) override;

Expand Down
150 changes: 148 additions & 2 deletions source/DSP/ProPhatSynthesiser.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,141 @@
#include "PhatVerb.h"
#include "../Utility/Helpers.h"

template <std::floating_point T>
class Crossfade
{
public:
enum ActiveBuffer { leftBuffer, rightBuffer };

Crossfade() = default;

/**
Resets the crossfade, setting the sample rate and ramp length.
@param sampleRate The current sample rate.
@param rampLengthInSeconds The duration of the ramp in seconds.
*/
void reset (double sampleRate, double rampLengthInSeconds)
{
smoothedGain.reset (sampleRate, rampLengthInSeconds);
}

/**
Sets the active buffer. I.e. which one should be written to the output.
@param buffer An enum value indicating which buffer to output.
*/
void setActiveBuffer (ActiveBuffer buffer)
{
if (buffer == leftBuffer)
setGain (1.0);
else
setGain (0.0);
}

/**
Applies the crossfade.
Output buffer can be the same buffer as either of the inputs.
All buffers should have the same number of channels and samples as each
other, but if not, then the minimum number of channels/samples will be
used.
@param leftBuffer The left input buffer to read from.
@param rightBuffer The right input buffer to read from.
@param outputBuffer The buffer in which to store the result of the crossfade.
*/
void process (const juce::AudioBuffer<T>& leftBuffer,
const juce::AudioBuffer<T>& rightBuffer,
juce::AudioBuffer<T>& outputBuffer)
{
// find the lowest number of channels available across all buffers
const auto channels = std::min ({ leftBuffer.getNumChannels(),
rightBuffer.getNumChannels(),
outputBuffer.getNumChannels() });

// find the lowest number of samples available across all buffers
const auto samples = std::min ({ leftBuffer.getNumSamples(),
rightBuffer.getNumSamples(),
outputBuffer.getNumSamples() });

for (int channel = 0; channel < channels; ++channel)
{
for (int sample = 0; sample < samples; ++sample)
{
// obtain the input samples from their respective buffers
const auto left = leftBuffer.getSample (channel, sample);
const auto right = rightBuffer.getSample (channel, sample);

// get the next gain value in the smoothed ramp towards target
const auto gain = smoothedGain.getNextValue();

// calculate the output sample as a mix of left and right
auto output = left * gain + right * (1.0 - gain);

// store the output sample value
outputBuffer.setSample (channel, sample, static_cast<T> (output));
}
}
}

private:
/**
Can be used to set a custom gain level to combine the two buffers.
@param gain The gain level of the left buffer.
*/
void setGain (double gain)
{
smoothedGain.setTargetValue (std::clamp (gain, 0.0, 1.0));
}

juce::SmoothedValue<double, juce::ValueSmoothingTypes::Linear> smoothedGain;
};

//==================================================

template <std::floating_point T>
struct Crossfade_Processor
{
PhatProcessorBase<T> processor1;
PhatProcessorBase<T> processor2;
std::vector<float> fade_buffer;

Crossfade<T> effectCrossFader;

void prepare (size_t max_buffer_size) { fade_buffer.reserve (max_buffer_size); } // pre-allocate!

//NOW HERE: I'm not sure if jatin's code here is meant to be working on a copy of the audio or the audio itself
void process (juce::AudioBuffer<T>&buffer, int startSample, int numSamples)
{
auto audioBlock { juce::dsp::AudioBlock<T> (buffer).getSubBlock ((size_t) startSample, (size_t) numSamples) };
const auto context { juce::dsp::ProcessContextReplacing<T> (audioBlock) };

if (use_processor1)
{
processor1.process (buffer);
return;
}
if (use_processor2)
{
processor2.process (buffer);
return;
}

fade_buffer.resize (buffer.size());
std::copy (buffer.begin(), buffer.end(), fade_buffer.begin());

processor1.process (fade_buffer);
processor2.process (buffer);
effectCrossFader.process (buffer, fade_buffer);

return;
}
};


//========================================================

/** The main Synthesiser for the plugin. It uses Constants::numVoices voices (of type ProPhatVoice),
* and one ProPhatSound, which applies to all midi notes. It responds to paramater changes in the
* state via juce::AudioProcessorValueTreeState::Listener().
Expand All @@ -47,6 +182,8 @@ class ProPhatSynthesiser : public juce::Synthesiser

void noteOn (const int midiChannel, const int midiNoteNumber, const float velocity) override;

void changeEffect();

private:
void setEffectParam (juce::StringRef parameterID, float newValue);

Expand All @@ -62,10 +199,12 @@ class ProPhatSynthesiser : public juce::Synthesiser
std::set<int> voicesBeingKilled;

std::unique_ptr<PhatProcessorWrapper<PhatVerbProcessor<T>, T>> verbWrapper;
std::unique_ptr<PhatProcessorWrapper<juce::dsp::Gain<T>, T>> gainWrapper;
std::unique_ptr<PhatProcessorWrapper<juce::dsp::Chorus<T>, T>> chorusWrapper;

std::vector<PhatProcessorBase<T>*> fxChain;

std::unique_ptr<PhatProcessorWrapper<juce::dsp::Gain<T>, T>> gainWrapper;

PhatVerbParameters reverbParams
{
//manually setting all these because we need to set the default room size and wet level to 0 if we want to be able to retrieve
Expand Down Expand Up @@ -110,8 +249,9 @@ ProPhatSynthesiser<T>::ProPhatSynthesiser (juce::AudioProcessorValueTreeState& p
//TODO: make this dynamic
//add effects to processing chain
fxChain.push_back (verbWrapper.get());
fxChain.push_back (gainWrapper.get());
fxChain.push_back (chorusWrapper.get());

fxChain.push_back (gainWrapper.get());
}

template <std::floating_point T>
Expand Down Expand Up @@ -187,6 +327,12 @@ void ProPhatSynthesiser<T>::noteOn (const int midiChannel, const int midiNoteNum
Synthesiser::noteOn (midiChannel, midiNoteNumber, velocity);
}

template <std::floating_point T>
void ProPhatSynthesiser<T>::changeEffect()
{

}

template <std::floating_point T>
void ProPhatSynthesiser<T>::renderVoices (juce::AudioBuffer<T>& outputAudio, int startSample, int numSamples)
{
Expand Down
7 changes: 1 addition & 6 deletions source/UI/ProPhatEditor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -184,12 +184,7 @@ ProPhatEditor::ProPhatEditor (ProPhatProcessor& p)
lfoDestButtons.setSelectedButton ((int) Helpers::getRangedParamValue (processor.state, lfoDestID.getParamID()));

//TODO: make this a button like the ones right above
effectChangeButton.onClick = std::bind (&ProPhatEditor::changeEffect, this);
}

void ProPhatEditor::changeEffect()
{
DBG ("CHANGE DAT EFFECT BRO");
effectChangeButton.onClick = std::bind (&ProPhatProcessor::changeEffect, &processor);
}

ProPhatEditor::~ProPhatEditor ()
Expand Down
1 change: 0 additions & 1 deletion source/UI/ProPhatEditor.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,6 @@ class ProPhatEditor : public juce::AudioProcessorEditor
#endif

bool gotMidi { false };
void changeEffect();

JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ProPhatEditor)
};

0 comments on commit ec7f9af

Please sign in to comment.