From 00edb70a7563cea76c0f26c4c063417dd403b661 Mon Sep 17 00:00:00 2001 From: James Ball Date: Sat, 25 Nov 2023 17:57:35 +0000 Subject: [PATCH] Have envelope control ADSR of MIDI --- Source/MidiComponent.cpp | 5 +++++ Source/PluginProcessor.cpp | 5 ++++- Source/UGen/Env.cpp | 7 ++++--- Source/UGen/EnvCurve.h | 1 - Source/audio/ShapeVoice.cpp | 36 ++++++++++++++++++++++-------------- Source/audio/ShapeVoice.h | 8 +++++++- 6 files changed, 42 insertions(+), 20 deletions(-) diff --git a/Source/MidiComponent.cpp b/Source/MidiComponent.cpp index af6d2a3..2b3d54f 100644 --- a/Source/MidiComponent.cpp +++ b/Source/MidiComponent.cpp @@ -62,6 +62,11 @@ void MidiComponent::handleAsyncUpdate() { 2 ); + { + juce::SpinLock::ScopedLockType lock(audioProcessor.effectsLock); + audioProcessor.adsrEnv = newEnv; + } + envelope.setEnv(newEnv); } diff --git a/Source/PluginProcessor.cpp b/Source/PluginProcessor.cpp index 0daf5ce..8be3e4d 100644 --- a/Source/PluginProcessor.cpp +++ b/Source/PluginProcessor.cpp @@ -716,7 +716,10 @@ void OscirenderAudioProcessor::envelopeChanged(EnvelopeComponent* changedEnvelop EnvCurveList curves = env.getCurves(); if (levels.size() == 4 && times.size() == 3 && curves.size() == 3) { - this->adsrEnv = env; + { + juce::SpinLock::ScopedLockType lock(effectsLock); + this->adsrEnv = env; + } updateIfApproxEqual(attackTime, times[0]); updateIfApproxEqual(attackLevel, levels[1]); updateIfApproxEqual(attackShape, curves[0].getCurve()); diff --git a/Source/UGen/Env.cpp b/Source/UGen/Env.cpp index f09be17..dbac582 100644 --- a/Source/UGen/Env.cpp +++ b/Source/UGen/Env.cpp @@ -221,9 +221,10 @@ float Env::lookup(float time) const throw() float level0 = levels_[stageIndex-1]; float level1 = levels_[stageIndex]; - EnvCurve curve = getCurves()[stageIndex-1]; - EnvCurve::CurveType type = curve.getType(); - float curveValue = curve.getCurve(); + int curveIndex = (stageIndex - 1) % curves_.size(); + + EnvCurve::CurveType type = curves_.data[curveIndex].getType(); + float curveValue = curves_.data[curveIndex].getCurve(); if((lastTime - stageTime)==0.f) { diff --git a/Source/UGen/EnvCurve.h b/Source/UGen/EnvCurve.h index 2209415..6c05a38 100644 --- a/Source/UGen/EnvCurve.h +++ b/Source/UGen/EnvCurve.h @@ -140,7 +140,6 @@ public: /// @} -private: static EnvCurve empty; std::vector data; }; diff --git a/Source/audio/ShapeVoice.cpp b/Source/audio/ShapeVoice.cpp index 5b14ef2..5fc50c7 100644 --- a/Source/audio/ShapeVoice.cpp +++ b/Source/audio/ShapeVoice.cpp @@ -21,7 +21,18 @@ void ShapeVoice::startNote(int midiNoteNumber, float velocity, juce::Synthesiser frameLength = shapeSound->updateFrame(frame); tries++; } - tailOff = 0.0; + adsr = audioProcessor.adsrEnv; + time = 0.0; + releaseTime = 0.0; + endTime = 0.0; + waitingForRelease = true; + std::vector times = adsr.getTimes(); + for (int i = 0; i < times.size(); i++) { + if (i < adsr.getReleaseNode()) { + releaseTime += times[i]; + } + endTime += times[i]; + } if (audioProcessor.midiEnabled->getBoolValue()) { frequency = juce::MidiMessage::getMidiNoteInHertz(midiNoteNumber); } @@ -104,17 +115,17 @@ void ShapeVoice::renderNextBlock(juce::AudioSampleBuffer& outputBuffer, int star x = channels.x; y = channels.y; - if (tailOff > 0.0) { - tailOff *= 0.99999; + time += 1.0 / audioProcessor.currentSampleRate; - if (tailOff < 0.005) { - clearCurrentNote(); - sound = nullptr; - break; - } + if (waitingForRelease) { + time = juce::jmin(time, releaseTime); + } else if (time >= endTime) { + clearCurrentNote(); + sound = nullptr; + break; } - double gain = tailOff == 0.0 ? 1.0 : tailOff; + double gain = audioProcessor.midiEnabled->getBoolValue() ? adsr.lookup(time) : 1.0; if (numChannels >= 2) { outputBuffer.addSample(0, sample, x * gain); @@ -154,11 +165,8 @@ void ShapeVoice::renderNextBlock(juce::AudioSampleBuffer& outputBuffer, int star void ShapeVoice::stopNote(float velocity, bool allowTailOff) { currentlyPlaying = false; - if (allowTailOff) { - if (tailOff == 0.0) { - tailOff = 1.0; - } - } else { + waitingForRelease = false; + if (!allowTailOff) { clearCurrentNote(); sound = nullptr; } diff --git a/Source/audio/ShapeVoice.h b/Source/audio/ShapeVoice.h index d20986f..ba26f2b 100644 --- a/Source/audio/ShapeVoice.h +++ b/Source/audio/ShapeVoice.h @@ -1,6 +1,7 @@ #pragma once #include #include "ShapeSound.h" +#include "../UGen/Env.h" class OscirenderAudioProcessor; class ShapeVoice : public juce::SynthesiserVoice { @@ -34,6 +35,11 @@ private: double lengthIncrement = 0.0; bool currentlyPlaying = false; - double tailOff = 0.0; double frequency = 1.0; + + Env adsr; + double time = 0.0; + double releaseTime = 0.0; + double endTime = 99999999; + bool waitingForRelease = false; };