kopia lustrzana https://github.com/jameshball/osci-render
Have envelope control ADSR of MIDI
rodzic
a7169bd8d1
commit
00edb70a75
|
@ -62,6 +62,11 @@ void MidiComponent::handleAsyncUpdate() {
|
||||||
2
|
2
|
||||||
);
|
);
|
||||||
|
|
||||||
|
{
|
||||||
|
juce::SpinLock::ScopedLockType lock(audioProcessor.effectsLock);
|
||||||
|
audioProcessor.adsrEnv = newEnv;
|
||||||
|
}
|
||||||
|
|
||||||
envelope.setEnv(newEnv);
|
envelope.setEnv(newEnv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -716,7 +716,10 @@ void OscirenderAudioProcessor::envelopeChanged(EnvelopeComponent* changedEnvelop
|
||||||
EnvCurveList curves = env.getCurves();
|
EnvCurveList curves = env.getCurves();
|
||||||
|
|
||||||
if (levels.size() == 4 && times.size() == 3 && curves.size() == 3) {
|
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(attackTime, times[0]);
|
||||||
updateIfApproxEqual(attackLevel, levels[1]);
|
updateIfApproxEqual(attackLevel, levels[1]);
|
||||||
updateIfApproxEqual(attackShape, curves[0].getCurve());
|
updateIfApproxEqual(attackShape, curves[0].getCurve());
|
||||||
|
|
|
@ -221,9 +221,10 @@ float Env::lookup(float time) const throw()
|
||||||
float level0 = levels_[stageIndex-1];
|
float level0 = levels_[stageIndex-1];
|
||||||
float level1 = levels_[stageIndex];
|
float level1 = levels_[stageIndex];
|
||||||
|
|
||||||
EnvCurve curve = getCurves()[stageIndex-1];
|
int curveIndex = (stageIndex - 1) % curves_.size();
|
||||||
EnvCurve::CurveType type = curve.getType();
|
|
||||||
float curveValue = curve.getCurve();
|
EnvCurve::CurveType type = curves_.data[curveIndex].getType();
|
||||||
|
float curveValue = curves_.data[curveIndex].getCurve();
|
||||||
|
|
||||||
if((lastTime - stageTime)==0.f)
|
if((lastTime - stageTime)==0.f)
|
||||||
{
|
{
|
||||||
|
|
|
@ -140,7 +140,6 @@ public:
|
||||||
|
|
||||||
/// @} <!-- end Array access and manipulation ----------------------------------------------- -->
|
/// @} <!-- end Array access and manipulation ----------------------------------------------- -->
|
||||||
|
|
||||||
private:
|
|
||||||
static EnvCurve empty;
|
static EnvCurve empty;
|
||||||
std::vector<EnvCurve> data;
|
std::vector<EnvCurve> data;
|
||||||
};
|
};
|
||||||
|
|
|
@ -21,7 +21,18 @@ void ShapeVoice::startNote(int midiNoteNumber, float velocity, juce::Synthesiser
|
||||||
frameLength = shapeSound->updateFrame(frame);
|
frameLength = shapeSound->updateFrame(frame);
|
||||||
tries++;
|
tries++;
|
||||||
}
|
}
|
||||||
tailOff = 0.0;
|
adsr = audioProcessor.adsrEnv;
|
||||||
|
time = 0.0;
|
||||||
|
releaseTime = 0.0;
|
||||||
|
endTime = 0.0;
|
||||||
|
waitingForRelease = true;
|
||||||
|
std::vector<double> 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()) {
|
if (audioProcessor.midiEnabled->getBoolValue()) {
|
||||||
frequency = juce::MidiMessage::getMidiNoteInHertz(midiNoteNumber);
|
frequency = juce::MidiMessage::getMidiNoteInHertz(midiNoteNumber);
|
||||||
}
|
}
|
||||||
|
@ -104,17 +115,17 @@ void ShapeVoice::renderNextBlock(juce::AudioSampleBuffer& outputBuffer, int star
|
||||||
x = channels.x;
|
x = channels.x;
|
||||||
y = channels.y;
|
y = channels.y;
|
||||||
|
|
||||||
if (tailOff > 0.0) {
|
time += 1.0 / audioProcessor.currentSampleRate;
|
||||||
tailOff *= 0.99999;
|
|
||||||
|
|
||||||
if (tailOff < 0.005) {
|
if (waitingForRelease) {
|
||||||
clearCurrentNote();
|
time = juce::jmin(time, releaseTime);
|
||||||
sound = nullptr;
|
} else if (time >= endTime) {
|
||||||
break;
|
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) {
|
if (numChannels >= 2) {
|
||||||
outputBuffer.addSample(0, sample, x * gain);
|
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) {
|
void ShapeVoice::stopNote(float velocity, bool allowTailOff) {
|
||||||
currentlyPlaying = false;
|
currentlyPlaying = false;
|
||||||
if (allowTailOff) {
|
waitingForRelease = false;
|
||||||
if (tailOff == 0.0) {
|
if (!allowTailOff) {
|
||||||
tailOff = 1.0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
clearCurrentNote();
|
clearCurrentNote();
|
||||||
sound = nullptr;
|
sound = nullptr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <JuceHeader.h>
|
#include <JuceHeader.h>
|
||||||
#include "ShapeSound.h"
|
#include "ShapeSound.h"
|
||||||
|
#include "../UGen/Env.h"
|
||||||
|
|
||||||
class OscirenderAudioProcessor;
|
class OscirenderAudioProcessor;
|
||||||
class ShapeVoice : public juce::SynthesiserVoice {
|
class ShapeVoice : public juce::SynthesiserVoice {
|
||||||
|
@ -34,6 +35,11 @@ private:
|
||||||
double lengthIncrement = 0.0;
|
double lengthIncrement = 0.0;
|
||||||
|
|
||||||
bool currentlyPlaying = false;
|
bool currentlyPlaying = false;
|
||||||
double tailOff = 0.0;
|
|
||||||
double frequency = 1.0;
|
double frequency = 1.0;
|
||||||
|
|
||||||
|
Env adsr;
|
||||||
|
double time = 0.0;
|
||||||
|
double releaseTime = 0.0;
|
||||||
|
double endTime = 99999999;
|
||||||
|
bool waitingForRelease = false;
|
||||||
};
|
};
|
||||||
|
|
Ładowanie…
Reference in New Issue