Upload files to "Source"
This commit is contained in:
@@ -1,79 +1,47 @@
|
||||
#pragma once
|
||||
|
||||
#include <JuceHeader.h>
|
||||
#include "SynthVoice.h"
|
||||
#include <JuceHeader.h>
|
||||
|
||||
//==============================================================================
|
||||
// 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<juce::Synthesiser*>(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<NeuralSynthVoice*> (v))
|
||||
nv->prepare (spec);
|
||||
if (auto* nv = dynamic_cast<NeuralSynthVoice*>(v))
|
||||
nv->prepare(spec);
|
||||
}
|
||||
|
||||
// Forward the MIDI-buffer overload so MIDI is consumed.
|
||||
void renderNextBlock (juce::AudioBuffer<float>& outputAudio,
|
||||
juce::MidiBuffer& midiMessages,
|
||||
int startSample,
|
||||
int numSamples)
|
||||
{
|
||||
juce::MPESynthesiser::renderNextBlock (outputAudio, midiMessages,
|
||||
startSample, numSamples);
|
||||
}
|
||||
|
||||
// Utility: apply a lambda to all voices
|
||||
template <typename VoiceFunc>
|
||||
void applyToVoices (VoiceFunc&& fn) noexcept
|
||||
void applyToVoices(VoiceFunc&& fn) noexcept
|
||||
{
|
||||
for (auto* v : voices)
|
||||
if (auto* nv = dynamic_cast<NeuralSynthVoice*> (v))
|
||||
fn (nv);
|
||||
fn(dynamic_cast<NeuralSynthVoice*>(v));
|
||||
}
|
||||
|
||||
private:
|
||||
// Keep base rendering behaviour for the sub-block overload.
|
||||
// keep base render
|
||||
using juce::MPESynthesiser::renderNextSubBlock;
|
||||
|
||||
void renderNextSubBlock (juce::AudioBuffer<float>& buffer,
|
||||
void renderNextSubBlock(juce::AudioBuffer<float>& outputAudio,
|
||||
int startSample,
|
||||
int numSamples) override
|
||||
{
|
||||
juce::MPESynthesiser::renderNextSubBlock (buffer, startSample, numSamples);
|
||||
juce::MPESynthesiser::renderNextSubBlock(outputAudio, startSample, numSamples);
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user