#pragma once #include #include #include #include "Params.h" #include "Wavetable.h" #include "SynthVoice.h" #include "LFO.h" #include "FXProcessor.h" #include "ModulationMatrix.h" #include "MacroControls.h" namespace serum { // =========================================================================== // The synthesis engine: a fixed pool of voices, four global LFOs, a wavetable // library and the FX rack. Owns all per-block DSP and MIDI handling. // =========================================================================== class Engine { public: Engine(); void prepare (double sampleRate, int blockSize, juce::AudioProcessorValueTreeState& apvts); void reset(); void processBlock (juce::AudioBuffer& buffer, juce::MidiBuffer& midi, juce::AudioProcessorValueTreeState& apvts, juce::AudioPlayHead* playhead); // MIDI void noteOn (int noteNumber, float velocity01); void noteOff (int noteNumber); void allNotesOff(); // Control-state accessors: hold getControlLock() while reading or editing. const juce::CriticalSection& getControlLock() const { return controlLock; } ModulationMatrix& getMatrix() { return matrix; } MacroControls& getMacros() { return macros; } const std::array& getLfos() const { return controlLfos; } const WavetableLibrary& getWavetables() const { return wavetables; } void setLfoShapeData (int index, const std::vector& data, int steps); int getActiveVoiceCount() const { return activeVoiceCount.load (std::memory_order_relaxed); } private: std::array voices; std::array lfos, controlLfos; WavetableLibrary wavetables; FXProcessor fx; ModulationMatrix matrix, audioMatrix; MacroControls macros, audioMacros; juce::CriticalSection controlLock; struct ParameterValue { std::atomic* source; float value; }; std::unordered_map parameterValues; double sr = 44100.0; int blockSize = 512; double bpm = 120.0; float pitchBend = 0.0f; float modWheel = 0.0f; juce::uint64 noteCounter = 0; std::atomic activeVoiceCount { 0 }; juce::AudioBuffer mixBuffer; SynthVoice* findFreeVoice(); SynthVoice* stealVoice(); void captureControls(); float v (const char* id) const; int vic (const char* id, int maxValue) const; void readOscParams (const paramIds::Oscillator& ids, OscParams& out) const; }; } // namespace serum