When we want to create “notes” we need not only to worry about pitch and duration, the traditional parameters of “Western music”, but also about the dynamic shape of a note. When we talk about organs and synthesizers, we need to automate the dynamic response to our key presses and releases. When we press a key we get a “note on” message which consists of a pitch and a velocity that ranges from 1 to 127 depending on the speed/strength with which the key was pressed. When we release a key we get a “note off” message which consists of the same pitch and a velocity of 0. Thus, note offs are easy to recognize as they always end with a zero.
The shape of notes as modeled in most organs and synths is generally represented by the Attack-Decay-Sustain-Release, or ADSR, model. The idea is that sounds have an “attack” or initial burst of energy that “decays” to a “sustain” level of energy, which is held until it is finally “released” towards silence once the key is released and the note off message is sent.
The general scheme of the ADSR model is the following:
The two events obtained from the user are “note on” and “note off” events, so the rest of events are automated according to this structure. Note ons will produce the ADS sequence and Note offs will produce the R event.
We will create an abstraction called [adsr~] by creating a new file and saving it with that name. The input will be only the velocity, so let’s start with an inlet. To distinguish between note on and note off events, we can use a [sel 0] object. Note off velocities will produce a bang, and note on velocities will be routed to the rightmost outlet.We divide note on velocities by 127 to bring the maximum velocity to 1. Thus our patch begins as shown in the right.
Before we move on, we need to consider what our output will be. Because we are controlling amplitude with line segments, we’ll use a [line~] object whose signal we’ll output through an [outlet~] object. We’ll use the velocity value to scale our [adsr~] by multiplying it by the output of [line~].
Note On Event
attack
As mentioned earlier, each note on event will trigger an “attack” line segment and after this, a “decay” line segment. Thus we use a [t b b f] event as shown on the left. We are now ready to program our first line segment or attack. We’ll use a variable called “A” which we will send from the main patch, so our attack event will go to 1 in “A” seconds as shown in the right.
At this point, we have created our “attack” line segment.
decay
We now need to automate the decay line segment. The decay segment starts after the attack segment has reached 1, so we need to delay the start of the decay by the duration of the attack using the [del] object.
Once the time has passed, delay will output a bang. The target of the decay line segment is the sustain value which is given by the variable “S” in dB, so we need to use the [dbtorms] object. The time in which we need to reach the target is that specified in the decay or “D” variable.
Thus the ramp to reach sustain is shown in the patch on the right.
Sustain and Release
Once the sustain value has been reach at the end of the decay segment, the abstraction literally sustains this value waiting to receive a note off. Once the note off is received the release line segment is triggered. The target of the release segment is zero, or silence, and the duration of the segment is given by the “R” variable. The note then, will sound for “R” milliseconds after the key has been released.
However, there is a risk that the sound might go on forever. As shown in the image on the right, if the note off happens before the decay segment has begun, then the [del] object will still occur as scheduled and will cancel the release and move to the sustain value and there is no way to stop this until a new note cancels it. Therefore, we need to let the [del] object know that the note has ended and that it does not need to continue with its automated action. To do this, we use the note off event to send the “stop” message to the [del] object and thus prevent it from banging at the end of the delay time.
adsr~ abstraction
The final [adsr~] patch is shown below. Remember this is an abstraction so to load it in a patch in the same way you create an object, it needs to be in the search path of your patch. The first and easiest way to do this is to put it in the same folder than the patch in which you want to load this abstraction. Can you add it to your additive organ patch?