Upload files to "Source"

This commit is contained in:
ed
2025-10-22 16:57:19 +00:00
parent ba5231f29b
commit df0ab9263c
3 changed files with 207 additions and 91 deletions

View File

@@ -1,49 +1,49 @@
#pragma once
//==============================================================================
template <typename SampleType>
class AudioBufferQueue
{
public:
//==============================================================================
static constexpr size_t order = 9;
static constexpr size_t bufferSize = 1U << order;
static constexpr size_t numBuffers = 5;
//==============================================================================
void push(const SampleType* dataToPush, size_t numSamples)
{
jassert(numSamples <= bufferSize);
int start1, size1, start2, size2;
abstractFifo.prepareToWrite(1, start1, size1, start2, size2);
jassert(size1 <= 1);
jassert(size2 == 0);
if (size1 > 0)
juce::FloatVectorOperations::copy(buffers[(size_t)start1].data(), dataToPush, (int)juce::jmin(bufferSize, numSamples));
abstractFifo.finishedWrite(size1);
}
//==============================================================================
void pop(SampleType* outputBuffer)
{
int start1, size1, start2, size2;
abstractFifo.prepareToRead(1, start1, size1, start2, size2);
jassert(size1 <= 1);
jassert(size2 == 0);
if (size1 > 0)
juce::FloatVectorOperations::copy(outputBuffer, buffers[(size_t)start1].data(), (int)bufferSize);
abstractFifo.finishedRead(size1);
}
private:
//==============================================================================
juce::AbstractFifo abstractFifo{ numBuffers };
std::array<std::array<SampleType, bufferSize>, numBuffers> buffers;
#pragma once
//==============================================================================
template <typename SampleType>
class AudioBufferQueue
{
public:
//==============================================================================
static constexpr size_t order = 9;
static constexpr size_t bufferSize = 1U << order;
static constexpr size_t numBuffers = 5;
//==============================================================================
void push(const SampleType* dataToPush, size_t numSamples)
{
jassert(numSamples <= bufferSize);
int start1, size1, start2, size2;
abstractFifo.prepareToWrite(1, start1, size1, start2, size2);
jassert(size1 <= 1);
jassert(size2 == 0);
if (size1 > 0)
juce::FloatVectorOperations::copy(buffers[(size_t)start1].data(), dataToPush, (int)juce::jmin(bufferSize, numSamples));
abstractFifo.finishedWrite(size1);
}
//==============================================================================
void pop(SampleType* outputBuffer)
{
int start1, size1, start2, size2;
abstractFifo.prepareToRead(1, start1, size1, start2, size2);
jassert(size1 <= 1);
jassert(size2 == 0);
if (size1 > 0)
juce::FloatVectorOperations::copy(outputBuffer, buffers[(size_t)start1].data(), (int)bufferSize);
abstractFifo.finishedRead(size1);
}
private:
//==============================================================================
juce::AbstractFifo abstractFifo{ numBuffers };
std::array<std::array<SampleType, bufferSize>, numBuffers> buffers;
};

View File

@@ -1,43 +1,79 @@
#pragma once
#include "SynthVoice.h"
#include <JuceHeader.h>
class NeuralAudioEngine : public juce::MPESynthesiser
{
public:
static constexpr auto maxNumVoices = 4;
//==============================================================================
NeuralAudioEngine(NeuralSharedParams &sp)
{
for (auto i = 0; i < maxNumVoices; ++i)
addVoice(new NeuralSynthVoice(sp));
setVoiceStealingEnabled(true);
}
//==============================================================================
void prepare(const juce::dsp::ProcessSpec& spec) noexcept
{
setCurrentPlaybackSampleRate(spec.sampleRate);
for (auto* v : voices)
dynamic_cast<NeuralSynthVoice*> (v)->prepare(spec);
}
//==============================================================================
template <typename VoiceFunc>
void applyToVoices(VoiceFunc&& fn) noexcept
{
for (auto* v : voices)
fn(dynamic_cast<NeuralSynthVoice*> (v));
}
private:
//==============================================================================
void renderNextSubBlock(juce::AudioBuffer<float>& outputAudio, int startSample, int numSamples) override
{
MPESynthesiser::renderNextSubBlock(outputAudio, startSample, numSamples);
}
};
#pragma once
#include <JuceHeader.h>
#include "SynthVoice.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)
{
// 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)
for (int i = 0; i < maxNumVoices; ++i)
addVoice (new NeuralSynthVoice (sp));
// 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);
}
// Called from processor::prepareToPlay()
void prepare (const juce::dsp::ProcessSpec& spec) noexcept
{
setCurrentPlaybackSampleRate (spec.sampleRate);
for (auto* v : voices)
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
{
for (auto* v : voices)
if (auto* nv = dynamic_cast<NeuralSynthVoice*> (v))
fn (nv);
}
private:
// Keep base rendering behaviour for the sub-block overload.
using juce::MPESynthesiser::renderNextSubBlock;
void renderNextSubBlock (juce::AudioBuffer<float>& buffer,
int startSample,
int numSamples) override
{
juce::MPESynthesiser::renderNextSubBlock (buffer, startSample, numSamples);
}
};

80
Source/BlepOsc.h Normal file
View File

@@ -0,0 +1,80 @@
#pragma once
#include <JuceHeader.h>
enum class BlepWave : int { Sine = 0, Saw, Square, Triangle };
class BlepOsc
{
public:
void prepare (double sampleRate) { sr = sampleRate; resetPhase(); }
void setWave (BlepWave w) { wave = w; }
void setFrequency (float f) { freq = juce::jmax (0.0f, f); inc = freq / (float) sr; }
void resetPhase (float p = 0.0f) { phase = juce::jlimit (0.0f, 1.0f, p); }
inline float process()
{
// phase in [0..1)
float out = 0.0f;
float t = phase;
phase += inc;
if (phase >= 1.0f) phase -= 1.0f;
switch (wave)
{
case BlepWave::Sine: out = std::sin (2.0f * juce::MathConstants<float>::pi * t); break;
case BlepWave::Saw:
{
// naive saw in [-1..1]
float s = 2.0f * t - 1.0f;
// apply BLEP at the discontinuity crossing t=0
s -= polyBlep (t, inc);
out = s;
} break;
case BlepWave::Square:
{
float s = (t < 0.5f ? 1.0f : -1.0f);
// rising edge at 0.0, falling at 0.5
s += polyBlep (t, inc) - polyBlep (std::fmod (t + 0.5f, 1.0f), inc);
out = s;
} break;
case BlepWave::Triangle:
{
// integrate the BLEP square for band-limited tri
float sq = (t < 0.5f ? 1.0f : -1.0f);
sq += polyBlep (t, inc) - polyBlep (std::fmod (t + 0.5f, 1.0f), inc);
// leaky integrator to keep DC under control
z1 = z1 + (sq - z1) * inc;
out = 2.0f * z1; // scale
} break;
}
return out;
}
private:
// PolyBLEP as in Valimäki/Huovilainen
static inline float polyBlep (float t, float dt)
{
// t in [0..1)
if (t < dt)
{
t /= dt;
return t + t - t * t - 1.0f;
}
else if (t > 1.0f - dt)
{
t = (t - 1.0f) / dt;
return t * t + t + t + 1.0f;
}
return 0.0f;
}
double sr = 44100.0;
float freq = 440.0f, inc = 440.0f / 44100.0f;
float phase = 0.0f;
float z1 = 0.0f;
BlepWave wave = BlepWave::Sine;
};