Hi, I’m trying to implement some nice glide into my bass synthesiser, but havent found any good resources or examples of people that have done the same. My approach (doesn’t work) so far has been to derive from dsp::MPESynthesiser:
//==============================================================================
class Synth : public juce::MPESynthesiser
{
public:
static constexpr auto maxNumVoices = 1; // Monophonic
Synth()
{
for (auto i = 0; i < maxNumVoices; ++i)
addVoice (new Voice);
setVoiceStealingEnabled (true);
}
Then in the Voice class:
void noteStarted() override
{
auto velocity = getCurrentlyPlayingNote().noteOnVelocity.asUnsignedFloat();
auto freqHz = (float) getCurrentlyPlayingNote().getFrequencyInHertz();
auto& osc = processorChain.get<oscIndex>();
//check if the envelope is finished
if (processorChain.get<envIndex>().getState() == Envelope::Idle)
{
processorChain.get<oscIndex>().reset();
}
osc.setFrequency (freqHz, true);
osc.setVelocity (velocity);
//retrigger envelope
processorChain.get<envIndex>().gate(true);
}
Every time a new buffer is asked for I update the parameters:
void updateParams()
{
.....
auto& osc = processorChain.get<oscIndex>();
osc.setGlide(glideParam->get() * 0.001); //glide in MS so convert to seconds
.....
}
And then in order to implement the glide I copy and pasted the source code from juce::dsp::Oscillator in order to have a member variable glide:
template <typename SampleType>
class OscillatorWithGlide
{
public:
/** Creates an uninitialised oscillator. Call initialise before first use. */
OscillatorWithGlide() = default;
.....
void setGlide(float newGlideInSecs)
{
glideInSecs = newGlideInSecs;
frequency.reset(sampleRate, glideInSecs);
}
.....
private:
float glideInSecs = 0.01;
};
I have tested this and the glide is getting updated properly in the OscillatorWithGlide class, but it is not audible when I actually test. Does anyone know why this might be? Or can you point me to an existing example of a synthesiser implementing monophonic glide?
Amazing Thank you, I will try to implement it and dig a bit to see how it works.
I’m unsure why this is not natively supported in the base dsp::MPESynthesiser
Hi, So I have basically completely implemented your synthesiser. However I am struggling to successfully turn off glide. I’m not sure whether to call setLegato(glideParam->get()) Or setPortamento(glideParam->get()) . And when I do, any new notes added to the note stack do not play. i.e. If I have a C held down, and then press the octave, there will be no output, compared to if glide is on where the note would jump to this new note. I hope that makes sense
setPortamento(false) should be enough to turn it off. You only want to enable one of glissando or portamento at a time. If one of them is enabled, then legato should also have an effect. When you turn off portamento, is your noteRetriggered still getting called?
No, noteRetriggered isn’t getting called. Basically if portamento is off and I add a second note to the one already playing, I expect it to switch instantly to the new note, but for some reason neither noteStarted() nor noteRetriggered() get called when I press a second note. notStopped() does get called, but I can’t see a way to check if there is already a voice on the stack.
Ah, you need to add multiple voice objects to your synth even though it is mono. The playing voice will be fastKilled and the new voice will start. They will slightly overlap for a few ms.
I need to document this, it’s pretty complex how it works.
Hmm, I’m wondering if I’m overcomplicating it for myself, I am making a very specific, simple synth so I might try to go back to the standard juce::MPESynthesiser and override some of the note handling functions to enable Mono glide.