#pragma once #include "SynthVoice.h" #include class NeuralAudioEngine : public juce::MPESynthesiser { public: static constexpr int maxNumVoices = 8; explicit NeuralAudioEngine(NeuralSharedParams& sp) { // Create MPE voices for (int i = 0; i < maxNumVoices; ++i) addVoice(new NeuralSynthVoice(sp)); // <-- takes MPESynthesiserVoice* // MPE synths do not use addSound(); note events are routed via MPE zones. setVoiceStealingEnabled(true); } void prepare(const juce::dsp::ProcessSpec& spec) noexcept { setCurrentPlaybackSampleRate(spec.sampleRate); for (auto* v : voices) if (auto* nv = dynamic_cast(v)) nv->prepare(spec); } template void applyToVoices(VoiceFunc&& fn) noexcept { for (auto* v : voices) fn(dynamic_cast(v)); } private: // keep base render using juce::MPESynthesiser::renderNextSubBlock; void renderNextSubBlock(juce::AudioBuffer& outputAudio, int startSample, int numSamples) override { juce::MPESynthesiser::renderNextSubBlock(outputAudio, startSample, numSamples); } };