Skip to content

Commit

Permalink
wip -- attempt to get cross-fading to work with 3 effects. We are swi…
Browse files Browse the repository at this point in the history
…tching between them in the right order, but there's glitching
  • Loading branch information
vberthiaume committed Dec 14, 2024
1 parent 5cac7f4 commit 0e13942
Showing 1 changed file with 76 additions and 29 deletions.
105 changes: 76 additions & 29 deletions source/DSP/PhatEffectsProcessor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ enum class EffectType
{
verb = 0,
chorus,
// phaser,
phaser,
transitioning
};

Expand Down Expand Up @@ -73,9 +73,13 @@ class EffectsCrossfadeProcessor
//TODO: probagate back the failure to change the effect
//first reverse the smoothedGain. If we're not at one of the extremes, we got a double click which we'll ignore
if (smoothedGain.getTargetValue() == 1.)
{
smoothedGain.setTargetValue (0.);
}
else if (smoothedGain.getTargetValue() == 0.)
{
smoothedGain.setTargetValue (1.);
}
else
{
jassertfalse;
Expand All @@ -85,6 +89,8 @@ class EffectsCrossfadeProcessor
if (curEffect == EffectType::verb)
curEffect = EffectType::chorus;
else if (curEffect == EffectType::chorus)
curEffect = EffectType::phaser;
else if (curEffect == EffectType::phaser)
curEffect = EffectType::verb;
else
jassertfalse;
Expand All @@ -101,52 +107,57 @@ class EffectsCrossfadeProcessor

void process (const juce::AudioBuffer<T>& previousEffectBuffer,
const juce::AudioBuffer<T>& nextEffectBuffer,
juce::AudioBuffer<T>& outputBuffer)
juce::AudioBuffer<T>& outputBuffer)
{
jassert (previousEffectBuffer.getNumChannels() == nextEffectBuffer.getNumChannels() && nextEffectBuffer.getNumChannels() == outputBuffer.getNumChannels());
jassert (previousEffectBuffer.getNumSamples() == nextEffectBuffer.getNumSamples() && nextEffectBuffer.getNumSamples() == outputBuffer.getNumSamples());

const auto channels = outputBuffer.getNumChannels();
const auto samples = outputBuffer.getNumSamples();
//TODO: compare floating points bro?
const auto needToInverse = smoothedGain.getTargetValue() == 1;
const auto samples = outputBuffer.getNumSamples();

for (int channel = 0; channel < channels; ++channel)
if (const auto needToInverse = smoothedGain.getTargetValue() == 1; needToInverse)
{
for (int sample = 0; sample < samples; ++sample)
for (int channel = 0; channel < channels; ++channel)
{
//TODO: get this outta the loop lmao
if (needToInverse)
for (int sample = 0; sample < samples; ++sample)
{
//get individual samples
// Get individual samples
const auto prev = previousEffectBuffer.getSample (channel, sample);
const auto next = nextEffectBuffer.getSample (channel, sample);

//mix and send to output
const auto gain = 1 - smoothedGain.getNextValue();
auto output = prev * gain + next * (1.0 - gain);
// Mix and send to output
const auto gain = 1 - smoothedGain.getNextValue();
const auto output = static_cast<T> (prev * gain + next * (1 - gain));
outputBuffer.setSample (channel, sample, static_cast<T> (output));
}
else
}
}
else
{
for (int channel = 0; channel < channels; ++channel)
{
for (int sample = 0; sample < samples; ++sample)
{
//get individual samples
// Get individual samples
const auto prev = nextEffectBuffer.getSample (channel, sample);
const auto next = previousEffectBuffer.getSample (channel, sample);

//mix and send to output
const auto gain = smoothedGain.getNextValue();
auto output = prev * gain + next * (1.0 - gain);
// Mix and send to output
const auto gain = smoothedGain.getNextValue();
const auto output = static_cast<T> (prev * gain + next * (1 - gain));
outputBuffer.setSample (channel, sample, static_cast<T> (output));
}
}
}
}

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

//TODO: this needs to be stored and retreived from the state
EffectType curEffect = EffectType::verb;

private:
juce::SmoothedValue<T, juce::ValueSmoothingTypes::Linear> smoothedGain;

//TODO: this needs to be stored and retrieved from the state
//EffectType curEffect = EffectType::verb;
};

//==================================================
Expand Down Expand Up @@ -190,6 +201,14 @@ class EffectsProcessor
{
chorusWrapper->processor.setRate (static_cast<T> (99.9) * newValue);
}
else if (curEffect == EffectType::phaser)
{
phaserWrapper->processor.setRate (static_cast<T> (99.9) * newValue);
}
else
{
jassertfalse;
}
}
else if (parameterID == ProPhatParameterIds::effectParam2ID.getParamID())
{
Expand All @@ -203,6 +222,15 @@ class EffectsProcessor
chorusWrapper->processor.setDepth (newValue);
chorusWrapper->processor.setMix (newValue);
}
else if (curEffect == EffectType::phaser)
{
phaserWrapper->processor.setDepth (newValue);
phaserWrapper->processor.setMix (newValue);
}
else
{
jassertfalse;
}
}
else
jassertfalse; //unknown effect parameter!
Expand All @@ -222,17 +250,34 @@ class EffectsProcessor
{
//copy the OG buffer into the individual processor ones
fade_buffer1 = buffer;
fade_buffer2 = buffer;

//make the individual blocks and process
auto audioBlock1 { juce::dsp::AudioBlock<T> (fade_buffer1).getSubBlock ((size_t) startSample, (size_t) numSamples) };
auto context1 { juce::dsp::ProcessContextReplacing<T> (audioBlock1) };
//TODO: this needs to use the current and the next effect
verbWrapper->process (context1);

fade_buffer2 = buffer;
auto audioBlock2 { juce::dsp::AudioBlock<T> (fade_buffer2).getSubBlock ((size_t) startSample, (size_t) numSamples) };
auto context2 { juce::dsp::ProcessContextReplacing<T> (audioBlock2) };
chorusWrapper->process (context2);

//do the crossfade based on the actual current effect -- which is actually now the NEXT effect lol
const auto nextEffect = effectCrossFader.curEffect;
switch (nextEffect)
{
case EffectType::verb:
phaserWrapper->process (context1);
verbWrapper->process (context2);
break;
case EffectType::chorus:
verbWrapper->process (context1);
chorusWrapper->process (context2);
break;
case EffectType::phaser:
chorusWrapper->process (context1);
phaserWrapper->process (context2);
break;
case EffectType::transitioning:
default:
jassertfalse;
break;
}

//crossfade the 2 effects
effectCrossFader.process (fade_buffer1, fade_buffer2, buffer);
Expand All @@ -247,12 +292,14 @@ class EffectsProcessor
verbWrapper->process (context);
else if (currentEffectType == EffectType::chorus)
chorusWrapper->process (context);
else if (currentEffectType == EffectType::phaser)
phaserWrapper->process (context);
else
jassertfalse; //unknown effect!!
}

private:
std::unique_ptr<EffectProcessorWrapper<juce::dsp::Chorus<T>, T>> chorusWrapper;
std::unique_ptr<EffectProcessorWrapper<juce::dsp::Chorus<T>, T>> chorusWrapper;

std::unique_ptr<EffectProcessorWrapper<juce::dsp::Phaser<T>, T>> phaserWrapper;

Expand Down

0 comments on commit 0e13942

Please sign in to comment.