Initial plugin version

This commit is contained in:
Timothy Scully
2025-06-23 00:16:47 +01:00
commit 01d446af2d
61 changed files with 1658 additions and 0 deletions

107
Source/SynthVoice.cpp Normal file
View File

@@ -0,0 +1,107 @@
#include "SynthVoice.h"
//==============================================================================
NeuralSynthVoice::NeuralSynthVoice(NeuralSharedParams& sp) : shared(sp) {}
//==============================================================================
void NeuralSynthVoice::prepare(const juce::dsp::ProcessSpec& spec)
{
setWaveform(0);
tempBlock = juce::dsp::AudioBlock<float>(heapBlock, spec.numChannels, spec.maximumBlockSize);
processorChain.prepare(spec);
adsr.setSampleRate(spec.sampleRate);
}
//==============================================================================
void NeuralSynthVoice::noteStarted()
{
auto velocity = getCurrentlyPlayingNote().noteOnVelocity.asUnsignedFloat();
auto freqHz = (float)getCurrentlyPlayingNote().getFrequencyInHertz();
processorChain.get<synthIndex>().setFrequency(freqHz, true);
juce::ADSR::Parameters p;
p.attack = shared.attack->load();
p.decay = shared.decay->load();
p.sustain = shared.sustain->load();
p.release = shared.release->load();
adsr.setParameters(p);
adsr.noteOn();
}
//==============================================================================
void NeuralSynthVoice::notePitchbendChanged()
{
auto freqHz = (float)getCurrentlyPlayingNote().getFrequencyInHertz();
processorChain.get<synthIndex>().setFrequency(freqHz, true);
}
//==============================================================================
void NeuralSynthVoice::noteStopped(bool allowTailOff)
{
adsr.noteOff(); //Triggers release phase
}
//==============================================================================
void NeuralSynthVoice::notePressureChanged() {}
void NeuralSynthVoice::noteTimbreChanged() {}
void NeuralSynthVoice::noteKeyStateChanged() {}
//==============================================================================
void NeuralSynthVoice::renderNextBlock(juce::AudioBuffer<float>& outputBuffer, int startSample, int numSamples)
{
if (!adsr.isActive())
clearCurrentNote();
if (waveform != -1) {
setWaveform(waveform);
waveform = -1;
}
auto block = tempBlock.getSubBlock(0, (size_t)numSamples);
block.clear();
juce::dsp::ProcessContextReplacing<float> context(block);
processorChain.process(context);
// 3. Apply ADSR envelope to tempBlock
std::vector<float*> channelPtrs;
for (size_t ch = 0; ch < tempBlock.getNumChannels(); ++ch)
channelPtrs.push_back(tempBlock.getChannelPointer(ch));
juce::AudioBuffer<float> buffer(channelPtrs.data(),
static_cast<int>(tempBlock.getNumChannels()),
static_cast<int>(tempBlock.getNumSamples()));
adsr.applyEnvelopeToBuffer(buffer, 0, numSamples);
juce::dsp::AudioBlock<float>(outputBuffer)
.getSubBlock((size_t)startSample, (size_t)numSamples)
.add(tempBlock);
}
void NeuralSynthVoice::setWaveform(int waveformType)
{
auto& osc = processorChain.template get<synthIndex>();
switch (waveformType)
{
case 0:
osc.initialise([](float x) { return std::sin(x); });
break;
case 1:
osc.initialise([](float x) { return x / juce::MathConstants<float>::pi; }); // Saw
break;
case 2:
osc.initialise([](float x) { return x < 0.0f ? -1.0f : 1.0f; }); // Square
break;
case 3:
osc.initialise([](float x) {
return 2.0f * std::abs(2.0f * (x / juce::MathConstants<float>::twoPi) - 1.0f) - 1.0f;
}); // Triangle
break;
}
}