#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(); units[1] = std::make_unique(); units[2] = std::make_unique(); units[3] = std::make_unique(); units[4] = std::make_unique(); units[5] = std::make_unique(); units[6] = std::make_unique(); units[7] = std::make_unique(); units[8] = std::make_unique(); } 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& 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