Multichannel Function Generators

MC includes two objects, mc.evolve~ and mc.gradient, for generating repeating time-varying multichannel control functions. The unique feature of these objects is that they allow you to specify function values as ranges; the objects uses these ranges to spread sample values within the range across the space of the output audio channels. The multichannel control signals generated by these objects can be applied to oscillator or filter frequencies, audio levels, or pan positions. It's probably easiest to gain an understanding of how these objects work by looking through some examples.

By connecting the multirange user interface object, you can draw input functions for either mc.evolve~ or mc.gradient as they accept the same input format.

The mc.evolve~ Object

The mc.evolve~ object maps an input driving function from 0 to 1 over a series of ranges in a stored function. The value of the driving function represents an X position where 0 is the beginning and 1 is the end. Each output channel, starting at 1, fills out a range of Y values. As an example, sending two lists 0 0.5 1 and 1 0.5 1 establishes two ranges, one at X position 0 and one at X position 1. If there are three output channels, then the output, regardless of the "X" value of the input driving function, would be a constant multichannel signal containing 0.5, 0.75, and 1.

More interesting time-varying behavior begins when ranges specified at each X position are different. In this example all values at X position 0 are 0.5 because both the low and high range values are 0.5. But at X position 1, the range is from 0 to 1. If you drive mc.evolve~ with a phasor~, the effect of this range specification a diverging series of values that snap back to the middle as the phase resets.

We've used the multirange object to draw this range. Connect the third ("dump") outlet of multirange to the left inlet of mc.evolve~. As you draw new functions, mc.evolve~ will update.

The mc.gradient~ Object

The mc.gradient~ object, like mc.evolve~, generates complex multichannel functions based on a stored set of ranges and an input driving signal.

The mc.gradient~ object divides the X axis of a function into a number of evenly spaced "slices." The number and locations of the slices are determined by the object's @chans attribute. Each slice intersects a function of ranges. A channel's output value is determined by an input signal between 0 and 1 specifying a distance between the low and high range values at a given slice position. In the diagram below, mc.gradient~ is using five channels whose slices are located at X positions 0, 0.25, 0.5, 0.75 and 1. The output for channels 1 and 5 will always be zero, because there is no range at those X positions. However, at slice position 0.5 (channel 3), there is a range between 0.5 and 1.0. When the input signal is 0, channel 3's output will be 0.5, the low end of the range. When the input signal is 0.5, channel 3's output will be 0.75, the midpoint of the range. And then the input signal is 1.0, channel 3's output will be 1.0, the high end of the range.

By default, mc.gradient~ has a function consisting of two points, one at X position 0 and one at X position 1. Both points have Y minimum and maximum values of 0. This means mc.gradient~ will output 0 for all channels given any input signal value. To create the function that corresponds to the above diagram, send mc.gradient~ the message 0.5 0.5 1.0; this means: at X position 0.5, define a range between 0.5 and 1.0. Note that the X position need not correspond with a slice location; this is being done here to create more straightforward illustration of the object's behavior.

In this example, we apply the multichannel output signal produced by mc.gradient~ to the levels of five sawtooth oscillators. The mc.gradient~ object is driven by a phasor~ at 1 Hz.

The meter~ in the example shows that the level of channels 1 and 5 is always zero, while channel 3 has the highest level.

For a smoothly oscillating function output from mc.gradient~, map a cycle~ object to 0 - 1 using a scale~ as shown in this example:

Creating Complexity With Multichannel Function Generators

Both mc.evolve~ and mc.gradient~ are capable of generating complex evolving multichannel control functions. Here are a few ways to achieve complexity beyond the examples shown here:

  • Supply a multichannel signal to the input of mc.gradient~ - each input channel will drive its corresponding output channel indepdently.
  • Each function point supplied to mc.gradient~ can have a fourth "phase" value that defines where the zero input value will start; this allows ranges to move in opposite directions as you move across the space of channel slices. By default the phase starts at the lowest point in the range.
  • Use a more complex non-periodic input function such as one generated by a line~ object.