So a few months ago, I set out to try to add LFO and Custom Envelope support to Decent Sampler. My desire was to make something that was open-ended and easy to use. My initial idea was that I would add the concept of “modulators” and these could be mapped by sample library developers to anything that knobs or MIDI CC numbers could be assigned to. It sounded so simple!
But then I tried to make it happen, and I realized that having an envelope that would be shared across all key presses would be terrible. Each time you hit a new note, it would effectively re-trigger the envelope for any already playing notes. The same would be true for LFOs, which, depending on the situation, may or may not be desired behavior.
So clearly, we need to have a separate set of envelopes and LFOs for each key-press, and these would need to be kept track of separately.
So I spent another full week building this, but it still wasn’t right. Now we were tracking envelopes and LFOs correctly, but when I started to think about how they would be used and what they would be modulating I ran into trouble again. Here are two obvious use cases for LFOs: 1) modulating effects and 2) modulating group volumes. Of course, there are many more possible use cases, but those two should be enough to illustrate the pitfalls and also to eventually figure out a workable system.
So let’s look at the first of those two: modulating effects. Let’s say that we have a low-pass filter, and we want an envelope that controls that filter’s cutoff. This is a very common use case. Right now, in the version of DecentSampler that everyone has, all effects are global, meaning they apply to all of the sound that comes out of Decent Sampler. If we press two keys down at two different times, and if (as we’ve already said) each keypress is going to have a separate envelope, at any given time we’re going to be at different points within those envelopes, and if those envelopes are tied to the same global effect they are going to be competing with eachother to set and reset values for the same effect. Clearly not what we want. Each key press needs its own set of voice-level effects (each keypress gets its own “voice”). The question then becomes do we introduce a new concept into the Decent Sampler preset format: the concept of the voice-level effect? As you can see, things quickly become complicated.
Next, let’s think about the other scenario, let’s say we have an LFO that is controlling a bunch of group volumes. Right now, the way that the bindings work is reactive. I had stated up top that I wanted the binding system to be essentially the same for modulators like LFO and envelope as the current bining system for knobs and MIDI CC numbers. Let’s say you have a knob that fades between two groups; each time that knob gets moved by the user, the underlying volumes of the group it is bound to gets updated in memory. In other words, the actual values within the XML get changed and if you were to save a preset out it would have those new, changed values. If each keypress/voice is going to have its own instance of an LFO, this model will not work for the same reason that having only one set of effects will not work: if each LFO is bound to the same value in the preset, they will all be setting and resetting the same value. We either need to completely change the way data binding works or we need to maintain a separate, temporary copy of the preset for each keypress voice. When an LFO value for a given voice/keypress gets updated, we need to modify
So what does any of this have to do with MPE? Well, the challenges are very related. The basic premise of MPE is that each keypress gets its own voice. If we were to say, have a CC#1 controlling filter cutoff, we need to make sure that we are tracking filter cutoff separately for each channel (i.e. each keypress/voice). So basically, once the conceptual problems with LFOs and Envelopes get resolved, we will also potentially have MPE support. Of course, only a tiny number of people have ever asked for MPE support, whereas a large number of folks have requested LFOs and Envelopes.
All of this goes to explain why LFOs and MPE have not been added to DecentSampler yet. These architectural concerns are substantial, and the risk of introducing a performance hit or affecting stability is great. The good news is it’s a problem I’m in the process of tackling, I have a working branch for LFO/MPE work, but the bad news is it’s pretty slow going right now especially since I'm also trying to build the sample editor.
If anyone has any advice or ideas about these features, I would love to hear your thoughts!