diff --git a/Source/AudioEngine.h b/Source/AudioEngine.h index d8e24e1..a6fd169 100644 --- a/Source/AudioEngine.h +++ b/Source/AudioEngine.h @@ -1,79 +1,47 @@ #pragma once -#include #include "SynthVoice.h" +#include -//============================================================================== -// MPESynthesiser wrapper that owns voices, installs a catch-all Sound, -// forwards prepare() to each voice, and renders MIDI blocks. class NeuralAudioEngine : public juce::MPESynthesiser { public: static constexpr int maxNumVoices = 8; - explicit NeuralAudioEngine (NeuralSharedParams& sp) + explicit NeuralAudioEngine(NeuralSharedParams& sp) { - // Call Synthesiser base API explicitly via a base pointer (portable on MSVC). - auto* base = static_cast(this); - base->clearVoices(); - base->clearSounds(); - - // Create voices (MPESynthesiser takes ownership) + // Create MPE voices for (int i = 0; i < maxNumVoices; ++i) - addVoice (new NeuralSynthVoice (sp)); + addVoice(new NeuralSynthVoice(sp)); // <-- takes MPESynthesiserVoice* - // Catch-all Sound so any MIDI note/channel is accepted. - struct AnySound final : public juce::SynthesiserSound - { - bool appliesToNote (int) override { return true; } - bool appliesToChannel (int) override { return true; } - }; - // Use raw pointer for this JUCE API on your version. - base->addSound (new AnySound()); - - // Respond to standard MIDI in non-MPE hosts - enableLegacyMode(); - - setVoiceStealingEnabled (true); + // MPE synths do not use addSound(); note events are routed via MPE zones. + setVoiceStealingEnabled(true); } - // Called from processor::prepareToPlay() - void prepare (const juce::dsp::ProcessSpec& spec) noexcept + void prepare(const juce::dsp::ProcessSpec& spec) noexcept { - setCurrentPlaybackSampleRate (spec.sampleRate); + setCurrentPlaybackSampleRate(spec.sampleRate); for (auto* v : voices) - if (auto* nv = dynamic_cast (v)) - nv->prepare (spec); + if (auto* nv = dynamic_cast(v)) + nv->prepare(spec); } - // Forward the MIDI-buffer overload so MIDI is consumed. - void renderNextBlock (juce::AudioBuffer& outputAudio, - juce::MidiBuffer& midiMessages, - int startSample, - int numSamples) - { - juce::MPESynthesiser::renderNextBlock (outputAudio, midiMessages, - startSample, numSamples); - } - - // Utility: apply a lambda to all voices template - void applyToVoices (VoiceFunc&& fn) noexcept + void applyToVoices(VoiceFunc&& fn) noexcept { for (auto* v : voices) - if (auto* nv = dynamic_cast (v)) - fn (nv); + fn(dynamic_cast(v)); } private: - // Keep base rendering behaviour for the sub-block overload. + // keep base render using juce::MPESynthesiser::renderNextSubBlock; - void renderNextSubBlock (juce::AudioBuffer& buffer, - int startSample, - int numSamples) override + void renderNextSubBlock(juce::AudioBuffer& outputAudio, + int startSample, + int numSamples) override { - juce::MPESynthesiser::renderNextSubBlock (buffer, startSample, numSamples); + juce::MPESynthesiser::renderNextSubBlock(outputAudio, startSample, numSamples); } };