#pragma once #include #include // <-- for std::function used by WaveShaper #include "NeuralSharedParams.h" #include "BlepOsc.h" //============================================================================== // A single polyBLEP oscillator voice with per-voice ADSR, filter ADSR, // flanger (delayline), simple delay, chorus, reverb, distortion, EQ, master. class NeuralSynthVoice : public juce::MPESynthesiserVoice { public: explicit NeuralSynthVoice (NeuralSharedParams& sharedParams); // JUCE voice API void prepare (const juce::dsp::ProcessSpec& spec); void renderNextBlock (juce::AudioBuffer& outputBuffer, int startSample, int numSamples) override; void noteStarted() override; void noteStopped (bool allowTailOff) override; void notePitchbendChanged() override; void notePressureChanged() override {} void noteTimbreChanged() override {} void noteKeyStateChanged() override {} // Called from the processor when the GUI waveform param changes void changeWaveform (int wf) { setWaveform (wf); } private: void setWaveform (int waveformType); //=== Processing chain (without oscillator) =============================== using DelayLine = juce::dsp::DelayLine; using IIR = juce::dsp::IIR::Filter; using Gain = juce::dsp::Gain; using WaveShaper = juce::dsp::WaveShaper>; // <-- fix using Chorus = juce::dsp::Chorus; using Reverb = juce::dsp::Reverb; using Limiter = juce::dsp::Limiter; enum ChainIndex { flangerIndex = 0, delayIndex, chorusIndex, reverbIndex, distortionPreGain, distortionIndex, distortionPostLPF, eqLowIndex, eqMidIndex, eqHighIndex, masterIndex, limiterIndex }; using Chain = juce::dsp::ProcessorChain< DelayLine, // flanger DelayLine, // simple delay Chorus, // chorus Reverb, // reverb Gain, // distortion pre-gain (drive) WaveShaper, // distortion waveshaper IIR, // tone / post-EQ for distortion IIR, // EQ low IIR, // EQ mid IIR, // EQ high Gain, // master gain Limiter // safety limiter >; private: NeuralSharedParams& shared; juce::dsp::ProcessSpec spec {}; // ==== Oscillator (polyBLEP) ============================================ BlepOsc osc; std::atomic pendingWaveform {-1}; // set by changeWaveform() // ==== Envelopes & Filter =============================================== juce::ADSR adsr; juce::ADSR filterAdsr; juce::dsp::StateVariableTPTFilter svf; // ==== Chain (FX, EQ, master, limiter) ================================== Chain chain; // ==== Scratch buffer (properly allocated) =============================== juce::AudioBuffer tempBuffer; juce::dsp::AudioBlock tempBlock; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (NeuralSynthVoice) };