112 lines
3.3 KiB
C++
112 lines
3.3 KiB
C++
#include "FXProcessor.h"
|
|
#include "EffectUnits/Hyper.h"
|
|
#include "EffectUnits/Chorus.h"
|
|
#include "EffectUnits/Flanger.h"
|
|
#include "EffectUnits/Phaser.h"
|
|
#include "EffectUnits/Distortion.h"
|
|
#include "EffectUnits/EQ.h"
|
|
#include "EffectUnits/Compressor.h"
|
|
#include "EffectUnits/Delay.h"
|
|
#include "EffectUnits/Reverb.h"
|
|
|
|
namespace serum
|
|
{
|
|
|
|
FXProcessor::FXProcessor()
|
|
{
|
|
units[0] = std::make_unique<HyperUnit>();
|
|
units[1] = std::make_unique<ChorusUnit>();
|
|
units[2] = std::make_unique<FlangerUnit>();
|
|
units[3] = std::make_unique<PhaserUnit>();
|
|
units[4] = std::make_unique<DistortionUnit>();
|
|
units[5] = std::make_unique<EQUnit>();
|
|
units[6] = std::make_unique<CompressorUnit>();
|
|
units[7] = std::make_unique<DelayUnit>();
|
|
units[8] = std::make_unique<ReverbUnit>();
|
|
}
|
|
|
|
FXProcessor::~FXProcessor() = default;
|
|
|
|
void FXProcessor::prepare (double sampleRate, int maxBlockSize)
|
|
{
|
|
for (auto& u : units)
|
|
u->prepare (sampleRate, maxBlockSize);
|
|
dry.setSize (2, maxBlockSize, false, false, true);
|
|
wet.setSize (2, maxBlockSize, false, false, true);
|
|
reset();
|
|
}
|
|
|
|
void FXProcessor::reset()
|
|
{
|
|
for (auto& u : units)
|
|
u->reset();
|
|
dry.clear();
|
|
wet.clear();
|
|
}
|
|
|
|
juce::String FXProcessor::fxTypeName (int type)
|
|
{
|
|
switch ((FxType) type)
|
|
{
|
|
case FxType::Off: return "Off";
|
|
case FxType::Hyper: return "Hyper";
|
|
case FxType::Chorus: return "Chorus";
|
|
case FxType::Flanger: return "Flanger";
|
|
case FxType::Phaser: return "Phaser";
|
|
case FxType::Distortion: return "Distortion";
|
|
case FxType::EQ: return "EQ";
|
|
case FxType::Compressor: return "Compressor";
|
|
case FxType::Delay: return "Delay";
|
|
case FxType::Reverb: return "Reverb";
|
|
default: return {};
|
|
}
|
|
}
|
|
|
|
void FXProcessor::process (juce::AudioBuffer<float>& buffer, const FxSlotParams* slots, int numSlots)
|
|
{
|
|
const int n = buffer.getNumSamples();
|
|
if (n <= 0)
|
|
return;
|
|
|
|
for (int s = 0; s < numSlots; ++s)
|
|
{
|
|
const FxSlotParams& slot = slots[s];
|
|
if (slot.type == (int) FxType::Off)
|
|
continue;
|
|
|
|
const int unitIdx = slot.type - 1;
|
|
if (unitIdx < 0 || unitIdx >= (int) units.size())
|
|
continue;
|
|
|
|
dry.copyFrom (0, 0, buffer, 0, 0, n);
|
|
dry.copyFrom (1, 1, buffer, 1, 0, n);
|
|
wet.copyFrom (0, 0, buffer, 0, 0, n);
|
|
wet.copyFrom (1, 1, buffer, 1, 0, n);
|
|
|
|
units[(size_t) unitIdx]->process (wet.getWritePointer (0), wet.getWritePointer (1), n, slot.p);
|
|
|
|
const float mix = juce::jlimit (0.0f, 1.0f, slot.mix);
|
|
if (mix >= 1.0f)
|
|
{
|
|
buffer.copyFrom (0, 0, wet, 0, 0, n);
|
|
buffer.copyFrom (1, 0, wet, 1, 0, n);
|
|
}
|
|
else if (mix > 0.0f)
|
|
{
|
|
const float* dL = dry.getReadPointer (0);
|
|
const float* dR = dry.getReadPointer (1);
|
|
const float* wL = wet.getReadPointer (0);
|
|
const float* wR = wet.getReadPointer (1);
|
|
float* oL = buffer.getWritePointer (0);
|
|
float* oR = buffer.getWritePointer (1);
|
|
for (int i = 0; i < n; ++i)
|
|
{
|
|
oL[i] = dL[i] * (1.0f - mix) + wL[i] * mix;
|
|
oR[i] = dR[i] * (1.0f - mix) + wR[i] * mix;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
} // namespace serum
|