<div dir="ltr">I have a custom envelope implementation in my Yarns fork:<br><a href="https://github.com/rcrogers/yarns-loom/blob/main/yarns/envelope.cc">https://github.com/rcrogers/yarns-loom/blob/main/yarns/envelope.cc</a><br><br>Includes user-configurable modulation of ADSR parameters by note-on velocity, plus a "Peak" modulation that changes the height of the A/D peak<br><a href="https://github.com/rcrogers/yarns-loom/blob/main/yarns/part.cc#L815">https://github.com/rcrogers/yarns-loom/blob/main/yarns/part.cc#L815</a><br><br>This started as the much simpler Braids envelope:<br><a href="https://github.com/pichenettes/eurorack/blob/master/braids/envelope.h#L76">https://github.com/pichenettes/eurorack/blob/master/braids/envelope.h#L76</a><br><br>These envelopes are the most CPU-intensive process in the system.  I found that I got better performance by:<br>- Using templated functions to transform conditionality in the main render loop from run-time to compile-time (learned this from <a href="https://pichenettes.github.io/mutable-instruments-documentation/tech_notes/stm32_miscellania/">Emilie Gillet's tips</a>)<br>- Avoiding as much per-sample multiplication as possible. I found that the number of multiplication operations needed to generate one output sample is a pretty good heuristic for CPU cost.<br>    - Rendering a separate envelope per modulation destination (voice timbre, voice gain, voice CV out) with a scale baked in at note start.  This lets you perform modulation by straight addition of samples, instead of having to multiply each sample by a scaling factor per destination.<br>    - Using a <a href="https://github.com/rcrogers/yarns-loom/blob/main/yarns/resources/lookup_tables.py#L128">LUT of phase-dependent bit-shifts</a> to do a "polygonal" approximation from a linear slope to the phase-dependent slope of the approximated curve.  These slopes feed an accumulator, again replacing multiplication with addition<br></div><br><div class="gmail_quote gmail_quote_container"><div dir="ltr" class="gmail_attr">On Thu, Nov 6, 2025 at 5:55 PM chris <<a href="mailto:chris@chrismusic.de">chris@chrismusic.de</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Why not multiply velocity into the attack and sustain target levels <br>
instead of the resulting envelope?<br>
<br>
You get the attack rate approaching behavior for free, and it omits lots <br>
of multiplications for each env sample.<br>
<br>
Am I missing something here?<br>
<br>
<br>
Chris (another one)<br>
<br>
<br>
On 06/11/2025 23:13, Tom Wiltshire wrote:<br>
> Many thanks, Chris.<br>
><br>
> Yes, multiplying the envelope output by velocity will cause an abrupt jump if the envelope isn't at zero. Running the attack to a new higher level is a a neater way of doing it, avoids the problem, and makes a lot of sense. I like it.<br>
><br>
> "Velocity modulation" seems a bit weird to me since MIDI only deals with velocity at note on and note off. At other times, surely some other variable would make more sense? How can you change the velocity of a key press after it's occurred? It seems a bit meaningless. I can see that if "velocity" is simply some variable that is multiplied by the envelope output before it is used, you could modulate it as much as you like in your firmware, but physically, it stops making sense - furthermore it causes the problems you've identified.<br>
><br>
><br>
>> On 6 Nov 2025, at 18:38, Chris McDowell <<a href="mailto:declareupdate@gmail.com" target="_blank">declareupdate@gmail.com</a>> wrote:<br>
>><br>
>> My use of the term "side effects" was sloppy, because I think there's only one and it is the primary effect. An envelope through a VCA can jump abruptly, where this one will only jump as abruptly as the envelope stage rates allow. It will only ever ramp toward new targets.<br>
>><br>
>> If it's a monophonic implementation and in a legato mode with previous notes held, new notes cause the output to ramp toward the new sustain value at the rate of decay. In a non-legato mode, new notes cause the output to ramp toward velocity * 2.0 at the rate of attack.<br>
>><br>
>> If it is a polyphonic synth, it only comes in to play when a voice is stolen. The volume or cutoff or whatever of that voice will ramp toward velocity * 2.0 from wherever it happens to be.<br>
>><br>
>> I had thought for a bit that adding slew to a velocity signal controlling a VCA could be one solution, but what rate to choose for that slew is unclear and it interacts with the rest of the envelope output. I like the simplicity of my envelopes only ever operating via targets and rates.<br>
>><br>
>> This is a limitation I don't love in the Prophet REV2, for example. It welcomes pretty flexible velocity modulation, but it is always an abrupt effect. I have not consciously encountered a velocity implementation like mine in the wild.<br>
>><br>
>> Chris McDowell<br>
>><br>
>><br>
>>> On Nov 6, 2025, at 8:11 AM, Tom Wiltshire <<a href="mailto:tom@electricdruid.net" target="_blank">tom@electricdruid.net</a>> wrote:<br>
>>><br>
>>><br>
>>><br>
>>>> On 6 Nov 2025, at 12:44, Chris McDowell via Synth-diy <<a href="mailto:synth-diy@synth-diy.org" target="_blank">synth-diy@synth-diy.org</a>> wrote:<br>
>>>><br>
>>>> When velocity is involved, I set the attack target to 2 * velocity, and the sustain level to sustain * velocity, instead of multiplying the envelope output by velocity.  this has some side effects but feels a lot more natural to me<br>
>>> Interesting. What's the difference? At first glance, that sounds like it would be the same (at least for constant-time envelopes - I can see constant-rate envelopes would change).<br>
>>><br>
>>><br>
><br>
> ________________________________________________________<br>
> This is the Synth-diy mailing list<br>
> Submit email to: <a href="mailto:Synth-diy@synth-diy.org" target="_blank">Synth-diy@synth-diy.org</a><br>
> View archive at: <a href="https://synth-diy.org/pipermail/synth-diy/" rel="noreferrer" target="_blank">https://synth-diy.org/pipermail/synth-diy/</a><br>
> Check your settings at: <a href="https://synth-diy.org/mailman/listinfo/synth-diy" rel="noreferrer" target="_blank">https://synth-diy.org/mailman/listinfo/synth-diy</a><br>
> Selling or trading? Use <a href="mailto:marketplace@synth-diy.org" target="_blank">marketplace@synth-diy.org</a><br>
________________________________________________________<br>
This is the Synth-diy mailing list<br>
Submit email to: <a href="mailto:Synth-diy@synth-diy.org" target="_blank">Synth-diy@synth-diy.org</a><br>
View archive at: <a href="https://synth-diy.org/pipermail/synth-diy/" rel="noreferrer" target="_blank">https://synth-diy.org/pipermail/synth-diy/</a><br>
Check your settings at: <a href="https://synth-diy.org/mailman/listinfo/synth-diy" rel="noreferrer" target="_blank">https://synth-diy.org/mailman/listinfo/synth-diy</a><br>
Selling or trading? Use <a href="mailto:marketplace@synth-diy.org" target="_blank">marketplace@synth-diy.org</a><br>
</blockquote></div>