Skip to content

Commit

Permalink
Idle state fix
Browse files Browse the repository at this point in the history
  • Loading branch information
khrykin committed Sep 13, 2020
1 parent 6b13516 commit d283ea7
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 66 deletions.
26 changes: 12 additions & 14 deletions Source/DSP/MultibandLookupTable.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,6 @@ class MultibandLookupTable {
-pi, pi,
tableSize);
});


}

#pragma mark - Call Operator
Expand All @@ -63,18 +61,18 @@ class MultibandLookupTable {
#pragma mark - Bands Frequencies

static constexpr std::array bandMaxFrequencies
= std::to_array<FloatType>({
60, // Sub
250, // Bass
500, // LowMid
1000, //
2000, // Mid
3000, //
4000, // UpperMid
5000, //
6000, // Presence
20000 // Brilliance
});
= std::to_array<FloatType>({
60, // Sub
250, // Bass
500, // LowMid
1000, //
2000, // Mid
3000, //
4000, // UpperMid
5000, //
6000, // Presence
20000 // Brilliance
});

static constexpr auto numberOfBands = bandMaxFrequencies.size();

Expand Down
11 changes: 5 additions & 6 deletions Source/DSP/Synth.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,8 @@ class Synth : public Synthesiser {
LookupTablesBank<float> lookupTablesBank;

dsp::ProcessorChain<
dsp::Reverb,
dsp::Gain<float>
dsp::Reverb,
dsp::Gain<float>
> fxChain;

#pragma mark - Rendering Audio Output
Expand All @@ -118,8 +118,7 @@ class Synth : public Synthesiser {
lastMasterGain = *parameters.masterGain;
}

inline void applyMasterFxChain(AudioBuffer<float> &outputBuffer, int startSampleIndex, int numSamples) {
// Apply master fx chain
void applyMasterFxChain(AudioBuffer<float> &outputBuffer, int startSampleIndex, int numSamples) {
auto fxBlock = tempBlock.getSubBlock(0, (size_t) numSamples);
fxBlock.copyFrom(outputBuffer, startSampleIndex, 0, numSamples);

Expand All @@ -138,7 +137,7 @@ class Synth : public Synthesiser {
lastReverbGain = *parameters.reverb;

juce::dsp::AudioBlock<float>(outputBuffer)
.getSubBlock((size_t) startSampleIndex, (size_t) numSamples)
.add(tempBlock);
.getSubBlock((size_t) startSampleIndex, (size_t) numSamples)
.add(tempBlock);
}
};
8 changes: 3 additions & 5 deletions Source/DSP/VCAOscillator.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,12 @@ class VCAOscillator {
sampleRate = spec.sampleRate;
}

#pragma mark - Setting & Getting Waveform
#pragma mark - Setting Properties

void setWaveform(Waveform waveform) {
currentWaveform = waveform;
}

#pragma mark - Setting Properties

void setFrequency(ValueType newValue) {
const auto nyquistFrequency = 0.5 * sampleRate;
if (newValue > nyquistFrequency)
Expand Down Expand Up @@ -91,8 +89,8 @@ class VCAOscillator {
double sampleRate = 0;

dsp::ProcessorChain<
Oscillator,
dsp::Gain<ValueType>
Oscillator,
dsp::Gain<ValueType>
> processorChain;

#pragma mark - Accessing Processors
Expand Down
78 changes: 37 additions & 41 deletions Source/DSP/Voice.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class Voice : public SynthesiserVoice, private Timer {
static constexpr auto gainHeadroom = 0.9f;

static constexpr auto minCutoff = 50.0f;
static constexpr auto maxCutoff = 20000.0f;
static constexpr auto maxCutoff = 22000.0f;

static constexpr auto minEnvelopeDurationSeconds = 0.01f;
static constexpr auto maxEnvelopeDurationSeconds = 15.0f;
Expand Down Expand Up @@ -133,10 +133,6 @@ class Voice : public SynthesiserVoice, private Timer {
firstOscillator().setLevel(currentVelocity);
firstOscillator().setLevel(currentVelocity);

MessageManager::callAsync([=] {
std::cout << "frequency: " << currentNoteFrequency << "\n";
});

if (modulationAmount > 0.0f) {
updateModulation();
}
Expand Down Expand Up @@ -188,30 +184,14 @@ class Voice : public SynthesiserVoice, private Timer {
subBlockPosition += subBlockSize;
}

if (!adsr.isActive()) {
if (!adsr.isActive() && !isTimerRunning()) {
noteDidFade();
}
}

dsp::AudioBlock<float>(outputBuffer)
.getSubBlock(startSampleIndex, numSamples)
.add(tempBlock);
}

inline void renderLFOSubBlock(dsp::AudioBlock<float> &subBlock) {
dsp::ProcessContextReplacing<float> context(subBlock);

updateCurrentDSPState();
updateADSRParameters();

auto nextADSRSample = adsr.getNextSample();

updateLevelWithADSRSample(nextADSRSample);
updateFilterWithADSRSample(nextADSRSample);

updateModulation();

processorChain.process(context);
.getSubBlock(startSampleIndex, numSamples)
.add(tempBlock);
}

private:
Expand Down Expand Up @@ -244,10 +224,10 @@ class Voice : public SynthesiserVoice, private Timer {
};

dsp::ProcessorChain<
VCAOscillator<float>,
VCAOscillator<float>,
dsp::LadderFilter<float>,
dsp::Gain<float>
VCAOscillator<float>,
VCAOscillator<float>,
dsp::LadderFilter<float>,
dsp::Gain<float>
> processorChain;

dsp::Oscillator<float> lfo;
Expand Down Expand Up @@ -275,12 +255,28 @@ class Voice : public SynthesiserVoice, private Timer {

#pragma mark - Helper Functions

static inline float analogFactor() {
void renderLFOSubBlock(dsp::AudioBlock<float> &subBlock) {
dsp::ProcessContextReplacing<float> context(subBlock);

updateCurrentDSPState();
updateADSRParameters();

auto nextADSRSample = adsr.getNextSample();

updateLevelWithADSRSample(nextADSRSample);
updateFilterWithADSRSample(nextADSRSample);

updateModulation();

processorChain.process(context);
}

static float analogFactor() {
return (Random::getSystemRandom().nextBool() ? 1.0f : -1.0f)
* maxAnalogFactor * Random::getSystemRandom().nextFloat();
}

static inline double getBendedFrequencyForWheel(int newPitchWheelValue, int currentlyPlayingNote) {
static double getBendedFrequencyForWheel(int newPitchWheelValue, int currentlyPlayingNote) {
auto bendSemitonesValue = pitchWheelSemitonesRange * getBendValueForWheel(newPitchWheelValue);
auto noteFrequency = MidiMessage::getMidiNoteInHertz(currentlyPlayingNote);

Expand All @@ -290,8 +286,8 @@ class Voice : public SynthesiserVoice, private Timer {
return noteFrequency * std::pow(2.0f, 1.0f * bendSemitonesValue / 12);
}

/** Returns bend value in a range of -1.0 to 1.0 */
static inline double getBendValueForWheel(int newPitchWheelValue) {
/** Returns bend value in a range of -1.0 to 1.0 */
static double getBendValueForWheel(int newPitchWheelValue) {
if (newPitchWheelValue >= 0x3fff)
newPitchWheelValue = 0x3fff + 0x1;

Expand All @@ -300,7 +296,7 @@ class Voice : public SynthesiserVoice, private Timer {

#pragma mark - Updating DSP-Related State

inline void updateCurrentDSPState() {
void updateCurrentDSPState() {
if (currentWaveform != Waveform(static_cast<int>(*parameters.oscillatorWaveform))) {
updateOscillatorsWaveform();
}
Expand All @@ -314,21 +310,21 @@ class Voice : public SynthesiserVoice, private Timer {
}
}

inline void updateOscillatorsWaveform() {
void updateOscillatorsWaveform() {
currentWaveform = static_cast<Waveform>(static_cast<int>(*parameters.oscillatorWaveform));

firstOscillator().setWaveform(currentWaveform);
secondOscillator().setWaveform(currentWaveform);
}

inline void updateADSRParameters() {
void updateADSRParameters() {
adsr.setParameters({*parameters.attack,
*parameters.decay,
*parameters.sustain,
*parameters.release});
}

inline void updateOscillatorsFrequency() {
void updateOscillatorsFrequency() {
currentOsc1Frequency = currentNoteFrequency * (1.0f + analogFactor());
currentOsc2AnalogFactor = analogFactor();
currentOsc2Frequency = currentNoteFrequency *
Expand All @@ -340,20 +336,20 @@ class Voice : public SynthesiserVoice, private Timer {
secondOscillator().setFrequency(currentOsc2Frequency);
}

inline void updateFilterDrive() {
void updateFilterDrive() {
currentFilterDrive = *parameters.filterDrive;

filter().setDrive(currentFilterDrive);
}

inline void updateModulation() {
void updateModulation() {
secondOscillator().setFrequency(currentOsc2Frequency
* (1.0 + modulationAmount
* lfo.processSample(0.0f)
* (maxDetuningFactor - defaultDetuningFactor) * maxAnalogFactor));
}

inline void updateFilterWithADSRSample(float nextADSRSample) {
void updateFilterWithADSRSample(float nextADSRSample) {
const auto envelopeCutoffValue = *parameters.cutoffEnvelopeAmount >= 0
? (1.0 - *parameters.cutoffEnvelopeAmount) +
*parameters.cutoffEnvelopeAmount * nextADSRSample
Expand All @@ -369,7 +365,7 @@ class Voice : public SynthesiserVoice, private Timer {
filter().setResonance(envelopeResonanceValue * *parameters.resonance);
}

inline void updateLevelWithADSRSample(float nextADSRSample) {
void updateLevelWithADSRSample(float nextADSRSample) {
auto envelopeVelocityValue = (1.0 - (*parameters.velocityEnvelopeAmount)
* (1.0 - currentVelocity)) * nextADSRSample;

Expand All @@ -391,7 +387,7 @@ class Voice : public SynthesiserVoice, private Timer {

#pragma mark - Bypassing processing

inline void setProcessorsBypassed(bool bypassed) {
void setProcessorsBypassed(bool bypassed) {
processorChain.template setBypassed<osc1Index>(bypassed);
processorChain.template setBypassed<osc2Index>(bypassed);

Expand Down

0 comments on commit d283ea7

Please sign in to comment.