My Next Envelope Generator

I started prototyping my next envelope generator in parallel with the slow-moving VCA unit development. Unlike my previous envelope generators, this one will make envelopes by calculation instead of using an analog circuit. I’ll use microcontroller STM32C092KCT as usual that has a built-in CAN controller.

I expect several advantages with making an envelope generator using a microcontroller:

  • Gate signals can be retrieved from the CAN bus; patching cables are not necessary for receiving gate signals
  • Easy to support velocity
  • Any curves are possible as long as the calculations catch up; it’s possible to do more than ADSR
  • You can save and load parameters

I first implemented fundamental code for the CAN controller. I’ll make this part as a common Analog3 code library later. I then moved onto envelope generation. I start it with the traditional ADSR curves. The STM32C092 controller is missing FPU, so fixed-point calculation is necessary to generate envelopes with sufficient speed. I studied it before, read the article to remember how:

OK now I remember. Calculating an exponential curve is simple; you just repeat next = r * prev where 0 <= r < 1. A more complicated issue is how to calculate the value of decaying ratio r from the knob position k. I tried to map knob position k to decaying ratio r through the curve’s time constant τ. A exponentially-decaying curve can be described as following:

V(t) =V0et/τ

The decaying ratio r is a ratio of values between a small time difference Δt:

r = V0 e (t+Δt)/τ V0et/τ = eΔt/τ

Mapping the knob position to time constant should not be linear for a natural operation feeling. I first try exponential curve as following:

τ = C e αk = e αkβ

Then the relationship between k and r is

r = eΔt/τ = e Δt / e αkβ

which is a bit complex to calculate. But I’ll use this equation for a while until the algorithm to generate envelope becomes clearer. In the equation above, constants α and β are unknown yet. They decide the range of time constants, so I’ll find a suitable pair for comfortable ADSR control by experimentation. I used gnuplot to decide initial values roughly as α = 0.00015 and β = 7.5 with k range 0 to 65535:

gnuplot> plot [k=0:65535] exp(k * 0.00015 - 7.5)
Bash

Then the decaying ratio to the knob positions with updating interval 1ms looks

gnuplot> plot [r=0:65535] exp(-1.e-3/(exp(r * 0.000115 - 7.5)))
Bash

The values get close to 1.0 as the time constant grows. For the shortest time constant, the ratio is less than 0.2 where I expect the generated curve being unnatural. So I presume shorter updating interval is necessary.

to be continued…

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.