Line segment control functions

Image

The line~ object is intended for use as a control signal for audio. You don’t listen to line~ directly, but it’s very effective as a controller/modifier/modulator of other signals. A pair of numbers (i.e. a two-item space-separated list of numbers) tells line~ a destination value and a time (in milliseconds) to get to that value. For example, the message 0.99 100 tells line~ to change its signal value from whatever it currently is to 0.99, moving linearly sample-by-sample toward 0.99 over the course of 100 milliseconds, calculating the intermediate signal value for each sample along the way. The result is a smoothly changing signal.

You can also send line~ a list that has more than two numbers. Every two numbers in the list are viewed as a “destination value / transition time” pair. The output of line~ follows the instructions of the first pair of numbers, then immediately follows the second pair, and so on. Thus, one can create a variety of control function shapes by specifying the destination value and transition time for each line segment.

In this patch, try clicking on the message box that says “example of a guitar-like pluck”. The amplitude of the sound goes to full (0.99) in 1 millisecond, dies by -12 dB (to 0.25) in the next 99 milliseconds, dies another -14 dB (to 0.05) in the next 900 milliseconds, and then fades entirely to 0 in 3000 ms. The result is a 4-second note with roughly the amplitude envelope of a plucked string.

The message box just below that, labeled “fade-in, stay, fade-out”, describes a very slow fade-in and fade-out. It goes to an amplitude of 0.5 in 2 seconds, stays there for 3 seconds, then fades to 0 in 5 seconds. The same sort of line segment function can also be used to control other aspects of a sound. The message box labeled “line segment control of frequency” specifies frequency values (to send a constantly changing frequency to cycle~) instead of amplitude values. It causes the frequency of the message box to jump immediately to 220 Hz, glide to 660 Hz in 3 seconds, shoot quickly down to 110 Hz in 5 milliseconds, then glide up to 440 Hz in about 7 seconds.

The function object allows you to draw a line segment function by clicking at the desired breakpoints. You can set the domain of that function (the total time of of the x axis) in the object’s Inspector or with a setdomainmessage. In this example, we have set the function‘s domain to 10 seconds (10,000 ms). When the object receives a bang, it sends out its second outlet a list of destination value / transition time pairs that are designed to go to aline~ object, and that correspond to the shape of the drawn function. So, in this example we use one button to trigger the function to send a 10-second line segment function to the line~ that controls amplitude at the same time as we trigger the message box to send a 10-second function to the line~ that controls the frequency of the cycle~. The result is continuous modulation of the oscillator’s frequency and its amplitude.

For more on the use of line segment control functions, see the chapters on the Algorithmic Composition blog, titled “Line-segment control function” and “Control function as a recognizable shape“.

It’s worth pointing out that the cycle~ object in this example uses 512 samples of a stored waveform in a buffer~ instead of its default cosine waveform. By giving a cycle~ object the same name as a buffer~, you instruct it to look at 512 samples of that buffer~ for its wavetable. The waveform being used in this example is one cycle of an electric guitar chord.

Linear note movement

Image

The line object interpolates linearly from its current value to some new destination value, ramping over a specified period of time, reporting its intermediate values along the way. In this example, we instruct line to ramp toward a given destination value, arriving there in 2 seconds, sending out a report of its progress (the intermediate values as it goes toward the destination) 12 times per second (i.e., once every 83.333 milliseconds). If you want line to do this sort of ramping behavior, you always need to give it a new destination time in its second inlet before you give it a destination value in its left inlet. Alternatively, you can give it all the information as a space-separated listof numbers, as is done here.

If you want to do a nonlinear mapping that you can’t easily describe with an arithmetic formula, it’s often best just to look up values in a stored array, also known as a “lookup table”. You can describe a nonlinear function over time by stepping through the values in a table. In the left inlet you specify the location that you want to access within the table (with location indices numbered starting at 0), and table sends out the value that’s stored at that location. In this example, we stored a synthetic musical scale in the table. (Double-click on the table object to see a graph of its contents.) To store that information as part of the patch, you have to check the “Save Data With Patcher” option in the table‘s Inspector. Then, to play only notes that belong to that scale from cello low C (MIDI 36) to flute high C (MIDI 96), we just need to read through table indices 0 to 35.

Linear fade-in/out of audio

Image

 

The line~ object is useful for providing a control signal. It interpolates linearly sample-by-sample to a new signal value over a specified period of time, then stays at that new value until it is instructed to change. It expects to receive a transition time in its right inlet (a ramp time), followed by a destination value in its left inlet. Alternatively, you can provide both values as a single two-item list. Its initial default value is 0. In this example, we use line~to provide a control signal (multiplier) to the *~ object in order to turn the amplitude of a sine wave up and down. When line~ receives the message 1 1000 it progresses to 1 over the course of 1 second, and when it gets the message 0 1000 it ramps back down to 0 in one second.

Line segment control functions

Image

 

In some past examples (e.g., Example 5 from 2011) you can see how the line~ object interpolates sample-by-sample in a straight line from one value to another. You provide it with a pair of numbers — a destination value to go to, and an amount of time in which to get there — and it changes gradually (linearly) to that destination value in that amount of time.

This example shows that you can actually provide line~ with a longer list of numbers, and it will break the list up into pairs of numbers — each pair representing a destination value and a ramp time — and will enact each pair one after the other. This results in a control shape that’s made up of a series of line segments instead of a single straight line.

You can make a large variety of shapes with various lists. In this example we just use two shapes: one for the frequency of an oscillator and another for that oscillator’s amplitude. (Notice that each of the two line~ objects has a typed-in argument specifying its initial value. When audio is first turned on, the oscillator’s frequency is 1000 Hz and its amplitude is 0, because those are the signal values being provided by the line~ objects.) When you click on the button, you trigger both message boxes, sending the lists to the two line~ objects.

The frequency goes from 1000 Hz to 2000 Hz (one octave higher) in 3000 milliseconds (3 seconds), then drops two octaves to 500 Hz in 500 ms (1/2 second), then returns to 1000 Hz in 1500 ms. The amplitude fades quickly up to .7 in just 50 ms, then drops by -12 dB to 0.175 in 1950 ms, then goes up about 9 dB to 0.5 in 1000 ms (all that in the same amount of time that the frequency is going up one octave), then goes up another 6 dB to 0.99 in 500 ms, fades down about -40 dB to 0.01 in 1450 ms, and then goes completely to 0 in the last 50 ms. These two “envelopes” — a frequency shape and an amplitude shape — each take the same total amount of time (5 seconds) but are not identical. (N.B. Because the scope~ objects need to gather audio samples before drawing them, the visual display lags somewhat behind what you hear.)