fixes, changes to gitignore

This commit is contained in:
Armin 2026-07-24 18:03:15 +02:00
commit 11d81cf1fd
17 changed files with 1160 additions and 16 deletions

View file

@ -15,6 +15,10 @@
#include "Effects/Chorus.h"
#include "Effects/Distortion.h"
#include "Effects/Reverb.h"
#include "Effects/ModFilter.h"
#include "Effects/Phaser.h"
#include "Effects/RingMod.h"
#include "LFO.h"
CustomSamplerVoice::CustomSamplerVoice(const SamplerParameters& samplerSound, MTSClient* client, double applicationSampleRate, int expectedBlockSize, bool initSample) :
expectedBlockSize(expectedBlockSize), sampleSound(samplerSound),
@ -66,6 +70,13 @@ void CustomSamplerVoice::initializeSample()
loopLowpass.emplace_back(std::make_unique<LowpassStream>(2 * LANCZOS_WINDOW_SIZE));
endLowpass.emplace_back(std::make_unique<LowpassStream>(2 * LANCZOS_WINDOW_SIZE));
}
// Prepare modulation section
modLFO.prepare(getSampleRate());
modFilter.initialize(sampleSound.sample.getNumChannels(), int(getSampleRate()));
modPhaser.initialize(sampleSound.sample.getNumChannels(), int(getSampleRate()));
modRingMod.initialize(sampleSound.sample.getNumChannels(), int(getSampleRate()));
modLfoBuffer.setSize(1, expectedBlockSize * 2);
}
void CustomSamplerVoice::startNote(int midiNoteNumber, float velocity, juce::SynthesiserSound* sound, int currentPitchWheelPosition)
@ -131,7 +142,17 @@ void CustomSamplerVoice::startNote(int midiNoteNumber, float velocity, juce::Syn
effect.fx->initialize(sampleSound.sample.getNumChannels(), int(getSampleRate()));
effect.fx->updateParams(sampleSound);
}
// Initialize modulation section
modLFO.reset();
modLFO.prepare(getSampleRate());
modFilter.initialize(sampleSound.sample.getNumChannels(), int(getSampleRate()));
modFilter.updateParams(sampleSound, false);
modPhaser.initialize(sampleSound.sample.getNumChannels(), int(getSampleRate()));
modPhaser.updateParams(sampleSound, false);
modRingMod.initialize(sampleSound.sample.getNumChannels(), int(getSampleRate()));
modRingMod.updateParams(sampleSound, false);
updateFXParamsTimer = 0;
// Set the initial state (vc.currentPosition is set before updateSpeedAndPitch)
@ -279,6 +300,23 @@ void CustomSamplerVoice::renderNextBlock(juce::AudioBuffer<float>& outputBuffer,
someFXEnabled = someFXEnabled || effect.enablementSource->get();
}
// Pre-compute LFO values for the block
bool modEnabled = sampleSound.modLfoFilterDepth->get() > 0.f || sampleSound.modLfoSpeedDepth->get() > 0.f
|| sampleSound.modRingModEnabled->get() || sampleSound.modPhaserEnabled->get();
if (modEnabled)
{
float bpm = sampleSound.currentBpm.load();
modLFO.setSync(sampleSound.modLfoSync->get(), bpm,
sampleSound.modLfoSyncDiv->getIndex() == 0 ? 2 : (sampleSound.modLfoSyncDiv->getIndex() == 1 ? 3 : 4));
modLFO.setRate(sampleSound.modLfoRate->get());
modLFO.setWaveform(static_cast<LFOWaveform>(sampleSound.modLfoWaveform->getIndex()));
if (modLfoBuffer.getNumSamples() < numSamples)
modLfoBuffer.setSize(1, numSamples);
for (int i = 0; i < numSamples; i++)
modLfoBuffer.setSample(0, i, modLFO.getNextSample());
}
// Main processing loop
VoiceContext con;
for (auto ch = 0; ch < sampleSound.sample.getNumChannels(); ch++)
@ -352,8 +390,10 @@ void CustomSamplerVoice::renderNextBlock(juce::AudioBuffer<float>& outputBuffer,
if (con.isReleasing)
envelopeBuffer.setSample(ch, i, envelopeBuffer.getSample(ch, i) * exponentialCurve(releaseShape, 1 - con.speedMovedSinceRelease / releaseSmoothing));
// Update the position
con.currentPosition += speed;
// Update the position with optional LFO speed modulation
float lfoVal = modEnabled ? modLfoBuffer.getSample(0, i) : 0.f;
float modulatedSpeed = speed * (1.f + lfoVal * sampleSound.modLfoSpeedDepth->get());
con.currentPosition += modulatedSpeed;
con.speedMovedSinceStart += 1;
if (con.isReleasing)
con.speedMovedSinceRelease += 1;
@ -430,6 +470,43 @@ void CustomSamplerVoice::renderNextBlock(juce::AudioBuffer<float>& outputBuffer,
}
vc = con;
// Apply modulation section (filter, ring mod, phaser) before FX chain
if (modEnabled)
{
float lfoFilterDepth = sampleSound.modLfoFilterDepth->get();
if (lfoFilterDepth > 0.f)
{
float baseCutoff = sampleSound.modFilterCutoff->get();
float avgLfo = 0.f;
for (int i = 0; i < numSamples; i++)
avgLfo += modLfoBuffer.getSample(0, i);
avgLfo /= float(numSamples);
float modulatedCutoff = baseCutoff * std::pow(2.f, avgLfo * lfoFilterDepth * 4.f);
modFilter.setCutoff(modulatedCutoff);
modFilter.setResonance(sampleSound.modFilterResonance->get());
modFilter.process(tempOutputBuffer, numSamples);
}
else
{
modFilter.setCutoff(sampleSound.modFilterCutoff->get());
modFilter.setResonance(sampleSound.modFilterResonance->get());
modFilter.process(tempOutputBuffer, numSamples);
}
if (sampleSound.modRingModEnabled->get())
modRingMod.processWithLFO(tempOutputBuffer, numSamples, modLfoBuffer.getReadPointer(0));
if (sampleSound.modPhaserEnabled->get())
{
float avgLfo = 0.f;
for (int i = 0; i < numSamples; i++)
avgLfo += modLfoBuffer.getSample(0, i);
avgLfo /= float(numSamples);
modPhaser.setDepth(sampleSound.modPhaserDepth->get());
modPhaser.processWithLFO(tempOutputBuffer, numSamples, avgLfo);
}
}
// Check for updated FX order
if (updateFXParamsTimer == UPDATE_PARAMS_LENGTH)
initializeFx();