mirror of
https://codeberg.org/armin/justasample.git
synced 2026-09-01 04:10:48 +02:00
fixes, changes to gitignore
This commit is contained in:
parent
2ab046489f
commit
11d81cf1fd
17 changed files with 1160 additions and 16 deletions
|
|
@ -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();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue