Building an Envelope in Reaktor Core, Part II
IMPLEMENTING THE ENVELOPE STAGES
The Attack, Decay, and Release stages of an envelope all have several things in common structurally. Each one has a starting point, an ending point, and a time that determines how long it takes to move from the start to the finish. In addition, each of these stages has a single output that is somewhere between the starting point and the ending point, and receives a clock input from the larger structure that determines when the stage is active.
[aside title = “Envelopes”]The Attack, Decay, and Release sections are identical[/aside]
The Sustain stage could also be implemented in this way, in theory, with a starting point equal to the ending point, and an arbitrary length of time to travel between the two. However, such an implementation would be wasteful – we’d be calculating unnecessary math whenever the Sustain stage was active. Instead, during the Sustain section, the value of the Sustain knob can simply be stored and sent to the output. In fact, you’ll see later that we can actually ignore the Sustain section altogether!
Okay, let’s get down to brass tacks. We can begin by creating a simple black box version of the Attack, Decay, and Release stages that I outlined above:
Since we’ve already calculated the length of each stage in terms of the sampling rate, let’s assume that the ‘Time’ input is also measured in samples. The ‘Clk’ input, aside from letting us know that the stage is active, also keeps track of the number of samples that have occured since the last MIDI gate value has arrived (both gate on and gate off messages will reset the counter, which is useful for the Release stage).
Therefore, we can fill in our black box macro from above to look something like this:
Keep in mind that this macro should only send a value to the output when a value arrives at the ‘Clk’ input. Therefore, the final calculated value is stored in a latch macro (found in the Expert Macro menu, in the memory section) which is triggered by the incoming clock.
Mostly, our work now becomes simply plugging in the proper values to the inputs of this macro. We outlined many of the specifics in the previous tutorial. For instance, rather than restarting from a value of zero every time, the Attack section can actually use the last previous output from the envelope as it’s starting point. Generally this will be zero, however, in case the envelope is triggered before the previous note is finished, this method will prevent a ‘click’ sound.
Here’s a view of our final Core cell:
Utilizing the basic structure that was designed for last weeks tutorial, we have simply plugged our new envelope stage macro in place and merged together their outputs (only one will be outputting values at any given point in time). A new gate input triggers many things, controlling the start values of all three stages (depending on whether the gate is on or off) and the end time of the Attack stage.
Notice here how the Sustain stage is simply ignored entirely. The reason for this is simple – we don’t need it! Once the Decay section is complete, the envelope is already at the value determined by the Sustain knob. Since the output is already the value we want it to be, we simply do nothing until we receive a Gate off event and begin the Release stage.
Alright, so now we have a working envelope. It is nothing special, of course, and there are many improvements that could be made. For one, this envelope has linear growth and decay, whereas higher quality envelopes generally use exponential curves for the stages. Other features could include: a peak knob that determines the maximum level of the envelope Attack stage; a maximum velocity option to always treat incoming gates at their maximum possible value; adding a looper like the envelopes in Ableton’s Operator synth; a GUI for controlling and visualizing the resulting envelope; etc.
If there is interest, we can cover some of these options in a future tutorial.
Have a Question or Comment About This Tutorial?
Want to ask a question about this tutorial or perhaps you have something to add?
Click through to our forum post about this tutorial and join the conversation!