When using a MIDI keyboard, it makes sense to use adsr~ as an envelope generator. That is because adsr~ is triggered by a nonzero number and turned off by zero, and a MIDI keyboard outputs nonzero numbers for note on events, and zero for note off. Moreover, many MIDI keyboard controllers offer knobs or sliders to specifically control envelope parameters, hence a simple ctlin object gives you hands-on control over all parameters of the envelope. A simple example is seen below.

image-title-here

In the image above, the object mtof takes a MIDI note and outputs a frequency. Dividing the velocity by 127 (do not forget to add the dot, otherwise there will be no float output) scales it as a float between 0 and 1, so that adsr~ will respond to the velocity information received from the keyboard. In order to apply the envelope, we multiply both signals together. Remember that multiplying a number between 0 and 1 by another number between 0 and 1 always produces a third number between 0 and 1, so there is no risk of clipping here. Also, the output may be very loud, so it is convenient to include either a gain~ or a live.gain~ object before sending the signal to the speakers.

image-title-here

The second image above shows the contents of the ‘knobs’ subpatcher, where the route object following ctlin should be edited to reflect whichever knobs or sliders from your MIDI keyboard you choose to control the adsr~ parameters, that is, you need to inspect which continuous control number your keyboard is using for each knob and inform the route object accordingly. Be mindful that attack, sustain, and release are measures of time and thus given in milliseconds. In the situation above, all three are being scaled from 0 to 2 seconds (even though an attack of 0 will produce a click, but we neglect that for now). Sustain, on the other hand, controls how loud the sound will be after the decay, hence needs to be a value between 0 and 1. The actual sustain time in this case will be controlled by how long you keep a note pressed on your keyboard. Finally, bear in mind that this simple example is by no means a proper monophonic synthesizer. Its major flaw is that any note off event can turn off any other note on event, even the ones not associated to it. We will soon remedy this nuisance.

There are many musical gestures we can achieve algorithmically which we cannot achieve by performing on a keyboard (and vice-versa). We now investigate how to apply envelopes to signals resulting from processes rather than performances. In an algorithm, the composer has to determine the duration of each event, so even if an ADSR-type envelope is desired, the adsr~ object might not be the best option. The line~ object, on the other hand, produces a piecewise function of arbitrary duration, and in spite of the name, is capable of generating functions of higher degree than just lines. We exemplify a basic application of line~ in Image 1.3 below. In this example we produce random MIDI notes ranging from 48 to at regular intervals given by the metro object. As before, these MIDI note numbers are converted to frequencies before reaching the cycle~ object. A trigger object is used to make sure an envelope is not produced before this frequency value (a float) is sent, otherwise there could be audible changes in oscillation frequency depending on the kind of envelope we use. Here, however, we use a very simple triangular envelope given by the message (0, 1 $1 0 $1). This message reads: go from 0 to 1 over $1 milliseconds, then back to 0 over another $1 milliseconds. Hence if we five the integer box an argument of 500 milliseconds, the metro object will produce two bangs per second and the message object, once banged, will make cycle~ ramp up to 1 over milliseconds, and back to 0 over the same time. The reason the envelope is slightly shorter in length is to avoid clicks.

image-title-here

Constructing envelopes from messages is, however, a very limited approach, for if we wanted to choose from, say, 20 such envelopes, all with arbitrarily many breakpoints, the task of typing messages and managing the lengths of each piece of each function would be extremely tedious. Taking advantage of the visual programming interface in Max, the function object makes creating piecewise functions much easier, and works seamlessly with line~. The example in Image 1.4 is similar to the previous one, only instead of a message, we use a graphical approach given by the function object. The output coming from the second outlet of function is a list that line~ understands, and the message setdomain $1 specifies the duration of the envelope. Note here that, unlike the previous example, there is no need to divide by two, as the relative lengths of each piece of the function are automatically calculated based on the overall duration that is passed through the setdomain message.

image-title-here

News & Events

Subscribe at the bottom of the page to be informed of news as they arrive.

RunloopSound Released on the App Store

Aug 12, 2016

RunloopSound brings the world of Csound to iOS devices. With a gorgeous user interface and complete integration to all major cloud providers, RunloopSound allows you to keep designing incredible sounds wherever you go.

Read more

Unbalanced Connection 57

Feb 19, 2016

The Unbalanced Connection is a semiannual series of concerts hosted by the University of Florida and dedicated to electroacoustic music.

Read more

Society of Composers, Inc.

Mar 15, 2014

Read more

O Guri Takes Over Portugal!

Oct 8, 2012

Read more

Première of O Guri in Bagé

Jul 7, 2011

O Guri is a feature film directed by Zeca Brito whose original music was written by me.

Read more