By Gary S. Hall | Thu, 13 Oct 2011
In the early 1980s, I had the pleasure of conceiving and designing a
true classic, the Lexicon PCM42 digital delay. At that time, I was
interested in using looping delays that could be beat-synchronized with
drum machines and arpeggiators, and I incorporated some of my ideas
into the '42. With the resources of Lexicon, I was also able to build a
great-sounding delay for general use. The original '42 became nearly a
studio standard; a used PCM42 fetches a higher price today than it did
when it was new.
I've always taken pride in having created the PCM42. I felt, and
still feel, that there's a special richness and immediacy in creating
music with long delay loops with feedback, and I'm pleased to claim my
little bit of history in this area.
Recently, I've been thinking about what I would do if I were to
redesign the PCM42. Among the things the PCM42 would need most is the
ability to dial in delay times as beats per minute and note values.
There would be other changes, as well:
My updated PCM42 would be entirely software, built with a
“construction kit” such as Cycling '74's Max/MSP.
It would be a live-performance environment, with analog inputs and
outputs.
Delay loops would be beat-synchronized, with options for master or
slave operation.
It would be semimodular, with multiple units that could be connected
in series or in parallel in any combination.
The device would offer multispeaker surround outputs as an
option.
I found that I can do all of this within the Max/MSP environment,
and I'm pleased with the musical results I'm getting. In this article,
I'll give you a full working multichannel real-time looping device with
sophisticated features, and I'll show you exactly how to build it. You
can build the system from scratch or just download the completed
program from the EM Web site for instant fun.
THE MAX/MSP ENVIRONMENT
Max/MSP, published by Cycling '74, is a visual programming language
for both music and audio. Originally developed by Miller Puckette, Max
has been available since 1991. Max offers something that I've never
found elsewhere: a complete software “construction set” of
basic I/O, control, and processing routines that can be connected to
create any function imaginable. It is truly the visual programming
language of MIDI.
A couple of years ago, Max took a huge step forward with the
introduction of MSP (Max Signal Processing). An integral part of the
Max 4.0 package, MSP extends the concept of Max into native audio
processing, a tremendously exciting development that makes it possible
to create arbitrarily complex effects processors and signal generators
at will.
One of the nice things that Max has always offered is its free
run-time engine. With it, any Max program (called a Patcher) can be
loaded and run by anyone. Controls in the user interface are fully
active, but no changes can be made to the Patcher itself. Thanks to
this policy, Max/MSP developers can distribute their work freely.
HARDWARE AND SOFTWARE
Max/MSP runs exclusively on the Macintosh, although a PC version is
under development. OS 8.6 or higher is required (I run OS 9.1), but OS
X is not yet supported.
The device we'll build is a real-time audio processor designed to
work with live audio inputs, so a stereo or (preferably) multichannel
audio interface is needed. Max/MSP supports ASIO and Apple Sound
Manager drivers. I've used the program successfully with an Emagic EMI
2/6 and a Mark of the Unicorn 828.
Because it is based on long delay loops, the Patcher we're going to
create is memory hungry. It doesn't require much for essential
operation, but the more delays you use and the longer they are, the
more memory you will need. As a benchmark, if you run at a 44.1 kHz
sampling rate, eight seconds of delay memory (equivalent to four bars
at 120 bpm) consumes about 5.6 MB.
To run the Patcher, you need some form of Max/MSP. Readers who
already own Max/MSP can jump right in, of course, but if you don't yet
have the program, you can download the free Max run-time engine or the
complete Max package from Cycling '74's Web site (www.cycling74.com).
Running the virtual delay unit is fun and (I hope) musical, but what
I really want to do in this article is show you how to modify and
customize the program to meet your own needs, as well as to create your
own processing and synthesis programs from scratch. This is the
excitement of Max/MSP, and you should definitely give it a try.
Luckily, Cycling '74 allows you to download the complete program for
a free 30-day trial. That's easily enough time for you to work through
this example and some of the excellent tutorial material that is
included with the download. Within your 30 days, you can do anything
you want; after that the program will refuse to operate until you get
an authorization code from the manufacturer. It's a good and fair
system. I offer one caution, though. If you're running the trial
version, do not try to change your system date and time. That
will cause the program to immediately time out.
The Max/MSP Patchers shown in this article are
available for download as a single archive from the EM Web site. To help in coordination,
Patchers are identified according to the figure in which they appear.
To get the most from this article, get Max/MSP (demo or full version)
and build these Patchers yourself in addition to studying the
downloadable versions. If you like, however, you can also download the
Max/MSP run-time environment and use any or all of these Patchers as
they are.
FIG. 1: Max/MSP''s Audio Through Patcher accepts a stereo signal from the audio interface and passes it directly to the audio output. To understand Max and the operation of these example Patchers, pay special attention to the comments.
MAX/MSP AUDIO PROGRAMMING
In an article such as this, there's no way to describe the complete
ins and outs of programming with Max and MSP. For that, the best source
is the excellent documentation, tutorials, and Help system that come
with the package (also see the review of Max 4.0/MSP 2.0 in the April
2002 issue). But let's take a look at the basic principles of
operation.
In Max, low-level functional blocks, which are called Objects, are
connected together in Patchers. Fig. 1 shows a simple Patcher
that passes stereo audio from input to output. Notice the descriptive
text that appears alongside the Patcher itself. Comments such as those
can be instructive to someone attempting to use your Patchers or to you
to remind you how a Patcher works. You can download and run this
Patcher, but the best way to learn is to build it from scratch in
Max/MSP.
There are three kinds of Objects used here. The “adc~”
Object gets input from the audio interface, “stereo by
default.” Audio data is transferred from the outputs of adc~ to
the inputs of the “dac~” Object by virtual patch cords. The
dac~ Object outputs stereo audio to the audio interface.
The remaining Object in this Patcher is a message box that contains
the word start. A start message is required to initiate
processing of audio. To make the Patcher operate, click on the start
message. A separate stop message can be used to halt processing.
There's an important distinction in Max/MSP between Objects that
handle audio data and those that deal with control and MIDI
information. Max Objects for control and MIDI process data only when
stimulated by the user interface or incoming messages. MSP audio
Objects, on the other hand, process audio data continuously.
FIG. 2: The Through with Gain Control Patcher adds stereo gain control to the simple Audio Through. The initial gain is 0.5, but the gain can be controlled by click dragging on the number box.
MSP audio-processing Objects are distinguished by a tilde
(“~”) sign after their names. In many cases, Objects of the
same name are available in control and audio form. For example, the
Object “*” will multiply two numbers, whereas the Object
“*~” multiplies numbers in a continuous stream of audio
data for gain control and modulation, as shown in Fig. 2.
Note that Max supports the Apple Sound Manager and ASIO drivers. To
use your ASIO interface, put the driver into the ASIO Drivers folder in
the Max application folder. Then, open the DSP Status window by
double-clicking on an adc~ or dac~ Object in any Patcher (or by
selecting DSP Status in the Options menu) and make the appropriate
selections for your interface.
FIG. 3: When a Max/MSP Patcher is unlocked, the Object toolbar appears at the top of the window. Although there are a large number of different Max/MSP Objects available, the seven leftmost items in the toolbar are the ones that are essential to nearly any project.
To build and modify Patchers in Max, you unlock the Patcher window
by clicking on the lock icon next to the Close box. If you're running
the Patchers with the free Max run-time application, that icon doesn't
appear. Try creating a new, empty Patcher. With the Patcher window
unlocked, you will find that it is easy to get started by dragging
Objects from the upper toolbar and then connecting their outlets (which
are found along the bottom of each Object) to the inlets of other
Objects. When you drag from the Object tool, which is leftmost in the
toolbar, into the main Patcher window, a handy index of the available
Objects pops up, and it is sorted into functional groups (see Fig.
3).
FIG. 4: The Help window for any Max or MSP Object is a completely commentated working Patcher that illustrates the full function and options for that Object.
Max/MSP uses a Help system that I really like. When a Patcher window
is unlocked, you can pick any Object and then go to the Help menu and
get a Help screen specific to that Object. The Object Help window is
itself an active Max Patcher that illustrates the full function and
options for that Object, complete with comments. You can run the Help
Patcher Object as is, or you can unlock it and modify it to see how the
Object behaves. Fig. 4 shows the Max Help window for the adc~
Object.
BASIC AUDIO DELAY
Now we can have some fun. In Max/MSP an audio delay line requires
two separate Objects, which are “tapin~” and
“tapout~.” Tapin~ creates the delay unit and uses a numeric
argument that defines the maximum delay in milliseconds. You then
connect the output of the tapin~ to tapout~'s input. Tapout~ has a
numeric argument that defines the actual audio delay; that can be
changed by sending a number to the Object's input.
FIG. 5: This Patcher is a simple audio delay line with variable delay time. Left and right audio inputs are mixed together, delayed, and then distributed to both audio outputs.
In the Patcher shown in Fig. 5, the left and right audio
inputs are connected to the input of tapin~. In Max/MSP, audio sources
connected to the same input are summed together at unity gain, which
makes audio mixing easy.
FIG. 6: This version of the delay line adds controls for feedback gain as well as level controls for direct and delayed audio. The decimal points in the arguments for the audio multiply (*~) Objects and in the number boxes that set the gains are necessary to make those Objects work in fractional values, in this case zero to unity gain.
If you run the Basic Audio Delay Patcher, you'll find that it does
in fact delay audio. However, audio delay is not much fun unless you
have a way to mix it with the direct signal and to feed the delayed
signal back to the input with some attenuation. Fig. 6 shows an
audio delay that provides those functions.
At this point, a couple of notes about numbers in Max/MSP are in
order. There are two kinds of numbers available: integer numbers (0, 1,
2, and so on) and floating-point numbers (floats) that can have
noninteger values (0.5, for example). By default, Max uses integers.
Audio gains, though, are usually fractional (in a range of 0 to 1.0,
typically), so it's important to use Object types that are
compatible.
Arithmetic Objects such as the *~ Object are made compatible with
floating-point numbers by entering an initial argument with a decimal
point. Similarly, number boxes such as those we're using to vary the
gain values come in two types. These are represented separately in
Max's toolbar and are denoted by a decimal point in the floating-point
number box.
FIG. 7: The Number Inspector (select the number box and hit Command + I on keyboard) defines important properties of the integer or floating point number box, including the number range. Defining the range of each box appropriately will help to make your audio patches behave as you intended.
It's also important to limit audio gains to appropriate values,
usually unity. To limit the range of values in a number box, unlock the
Patcher, select the number box in question, and hit Command + I on the
Mac keyboard. This opens a dialog that controls the numeric range, as
well as other properties of the number box (see Fig. 7).
By the way, if your audio interface provides a direct-monitoring
path, you can delete the portion of the Patcher that feeds the direct
signal to the output. That is a better way to monitor the direct sound,
because routing audio through the computer always entails at least a
few milliseconds of latency.
FIG. 8: This figure shows the audio delay line function encapsulated in a Max Patcher Object. Double clicking on the Object labeled “patcher delayline” will open the second window, revealing the contents of that Patcher Object. Inlet and outlet Objects are used to designate inputs and outputs to appear on the completed Patcher Object.
KEEP IT CLEAN
I will now reveal to you the secret of making useful programs with
Max/MSP: make sure you keep your Patchers neat. That's the difference
between a hacked-up Patcher that falls apart and a complete, usable,
and maintainable program. Keep your Patchers organized, and you can do
anything you want.
Max provides excellent facilities to build complex functions with
good organization, visual sense, and flexible design of the user
interface. To start with, you can encapsulate an entire Patcher in a
single Object. When you make a new Patcher Object, a subwindow
automatically opens where you can construct an entire function and link
it into a larger Patcher.
Fig. 8 shows our delay module with the core delay function
incorporated into such a subpatch. Inputs and outputs are defined in
the subpatch by using “inlet” and “outlet”
Objects, which appear like the inputs and outputs of a native Max
Object. When configuring a subpatch in this way, it's a very good idea
to add labels for the inlets and outlets. Number boxes inside the
Subpatcher are handy for debugging, as well.
I also cleaned up our patches by using right-angle lines for patch
cords instead of diagonals. To do that, select the item Segmented Patch
Cords in the Options menu. When connecting Objects, you can create
breaks by clicking on the cords with the mouse. I use segmented patch
cords in all of my work with Max, restricting use of diagonal cords to
short runs where segmented cords would be awkward.
It also helps to organize Objects that connect to each other into
vertical columns or horizontal rows using the Align Objects command.
Simply select all of the Objects to be aligned and use the keyboard
shortcut (Command + Y) to snap the selected Objects into line.
FIG. 9: The knob Object can be used to set gains instead of number boxes. Knob Objects in Max output numbers ranging from 0 to 127. To use these to set gain at a maximum value of unity, it is necessary to divide the raw output by 127, using a floating point divide, as indicated by the decimal point in each divide Object.
Number boxes are also not the ideal way to control audio gain. Max
provides slider and knob Objects for more conventional audio control.
Fig. 9 shows our patch with knobs instead of number boxes for
the gain parameters. The knob Object outputs numbers from 0 to 127, but
the gain-control multiplier needs to see a range of 0 to 1.0. To
convert, divide the knob output by a fixed value of 127 using a
floating-point divide so decimal values between 0 and 1.0 will be
output.
FIG. 10: The Hide on Lock command in the Object menu is a powerful means of maintaining Patchers so that they look clean and neat to the end user, with wiring and Objects that the user doesn''t need to see hidden from view.
Another way to help maintain visual organization is to hide
connections and Objects that the end user doesn't need to see. To do
that in Max, unlock the Patcher, select the item or items you wish to
conceal, and then select the command Hide on Lock from the Object menu.
When you relock the Patcher, all of the Objects that were selected will
be concealed, as shown on the right of Fig. 10. All patch cords
and Objects that the user doesn't need to see are now hidden from
view.
I elected to leave the delayline Patcher Object visible for two
reasons. The first is that in order to edit a Patcher Object, you have
to double-click on it while the main Patcher is locked. If the Patcher
Object is hidden, you can't do that. Second, it is also helpful to
embed the main function of a Patcher in a single Patcher Object and
then keep that Object visible. For one thing, it helps to remind me of
what that particular Patcher does for a living.
Making your Patchers orderly is an art, and you should adopt the
practice from the start of your work with Max. Spaghetti Patchers get
out of hand very quickly.
FIG. 11: The loadbang Object triggers specific actions when the Patcher is opened, ensuring that the Patcher always comes up in a known, useful state.
MAKE IT NICE
It's a good idea for you to include some initialization so that your
Patchers come up running in a known state. An Object called
“loadbang” can help make your Patchers initialize properly.
Fig. 11 shows the previous version of the delayline Patcher with
initialization added to load a known set of values and to start audio
processing automatically.
In the Patcher shown in Fig. 11, I've unhidden some of the Objects
and cords and added notes to make clear what's happening there.
Whenever the Patcher is opened, loadbang sends out a trigger pulse
called a bang. In this case, the bang goes to two separate
places.
The first is to a Max preset Object. This is one of Max's magic
functions, storing a preset for an entire Patcher window. In this
illustration, a preset has been loaded into “memory 1.”
Loadbang triggers the message box, sending the number “1”
and loading that setup.
At the same time, loadbang triggers the “delay 500”
Object. After a half second, this Object sends the start message to
begin audio processing. That ensures that the whole Patcher is up and
running before processing begins.
FIG. 12: This Patcher fragment converts a bpm value into a delay value corresponding to a 16th note at the designated tempo. The send Object allows this value to be conveniently routed to any number of destinations.
ADDING BEAT SYNC
So far we've managed to create a fairly well-behaved audio delay
line with an uncluttered user interface. You're probably thinking that
there must be more to life than this.
There is. The good news is that because we've built up our delay
line from scratch, we understand it well, and we are in a position to
customize it however we like. To fulfill my original wish list, the
next thing we are going to add is a way to synchronize delays with a
defined tempo. The simplest way to do that is to provide a means for
entering a tempo value in beats per minute (bpm) and then change the
entry of delay time so that delays are expressed as a number of defined
units, such as 16th notes.
Entering a tempo value is easy; it's just a number box. The trick is
to convert the bpm number to a value in milliseconds per unit of time
(we will use the 16th note for this). This value is then fed to the
delay line, which next multiplies it by the defined number of delay
units to get the actual delay value in milliseconds, as required by the
tapout~ Object.
Fig. 12 shows a Patcher fragment that lets the user enter a
tempo in bpm and converts it into a delay value corresponding to a 16th
note in 4/4 time. This fragment will be incorporated into our delayline
Patcher to provide simple beat synchronization. Take a moment to look
over the diagram and read the notes in this example, as some things
happening there may not be completely obvious.
To calculate the value in milliseconds, first divide the number of
milliseconds in a minute (60 times 1,000, or 60,000) by the bpm value
entered by the user. To get the 16th-note value, divide the
quarter-note result by four. We can achieve the same thing in fewer
steps by using 15,000 (60,000 divided by 4) as the dividend.
In this case, the Max divide (“/”) Object doesn't quite
work as we'd like it to, so we have to do a little bit of extra work.
In the Max / Object, the left input accepts the dividend value, which
in this case is fixed at 15,000. To make sure this value gets loaded on
startup, a loadbang Object is connected to a message box containing the
value 15,000, and this is connected to the / Object's left input.
FIG. 13: The delayline Patcher Object must be modified to calculate a final delay value from the 16th note value generated by the bpm master calculation and a multiple of that pulse entered by the user.
The bpm value entered by the user becomes the divisor and is sent to
the right-hand input of the / Object. However, in Max the computation
of a value is triggered by the receipt of a number or a bang at the
left input. We can enter values all day at the right input, but no new
values for the output will be generated until we send a message to the
left input. This is the function of the “button” Object,
which is connected to the bpm entry box. When this Object receives any
message, it generates a bang in response. The bang output is connected
to the left input of the / Object, and that causes it to generate a new
value whenever the user enters a new value for bpm.
If you've built this Patcher fragment from scratch, you may also
have noticed that it doesn't work right away. That is because the value
“15,000” is not actually transmitted until the Patcher is
saved, closed, and reopened. You can get around that by locking the
Patcher and clicking on the message box, which triggers it to send its
message to the / Object. After that all entries of bpm will generate a
new value in the number box connected to the output of the /
Object.
The final output of this fragment is provided by the
“send” Object. Send and “receive” Objects are
among Max's great gifts to help keep your complex Patchers legible and
maintainable. Send and receive Objects always have a name. Any message
sent to the input of a send Object will be routed automatically to any
receive Object that has the same name. That makes it easy to send a
single message to multiple destinations. Because we plan to create
multiple delay lines tied to the same tempo, it's appropriate to use
the send and receive Objects.
FIG. 14: This is the complete delay line with beat sync calculation. All Objects and patch cords have been unhidden to help in tracing, and a single loadbang Object is used.
Now that we've derived a time value corresponding to a 16th-note
pulse, we need to modify our delayline Patcher to receive this value
and calculate delay times as a multiple of it. Fig. 13 shows the
Max code that does that, first as a fragment and then incorporated into
our delayline Patcher Object. Fig. 14 shows the complete Patcher
that includes the bpm delay setting as well as specification of delays
as a number of 16th-note units.
FIG. 15: This version of the delay has been further simplified by incorporating I/O and control scaling into the delayline Patcher Object. This makes it easy to create additional delay sections by copying and pasting.
MULTIPLE MODULES
Although this seems like a lot of work just to get an audio delay
line, now the real fun can begin. Thanks to the wonders of software, we
can turn our single delay loop into any number of delays, all
synchronized to a common tempo.
Before doing that, we need to simplify our Patcher a little more by
moving some of the functions that remain outside the delayline Patcher
Object inside, as shown in Fig. 15. By moving the audio I/O and
scaling for the controls into the Patcher Object, we've made our main
delay section compact and self-contained.
FIG. 16: To duplicate delay lines, unlock the Patcher, select all the Objects to be copied, and hit Command + D on the keyboard. It is usually necessary to do some initialization of parameters after duplication.
It now becomes quite easy for us to duplicate the delay section
using standard Duplicate or Copy-and-Paste commands (see Fig.
16). All you have to do is unlock the Patcher, select all the items
in the Delay 1 unit, and hit Command + D. The selected items are
duplicated, and you can move them as a group and change the label as
needed.
When you duplicate a group of Objects, they come up without any
parameter values set, so it's necessary to go to the controls and set
them to something useful. You also need to reenter the bpm value so
that it gets transmitted to the new, duplicate module. After doing
those things, Shift-click on the first button in the preset Object we
added earlier to create a valid setup that will be loaded the next time
the modified Patcher is opened.
FIG. 17: The selector~ Object provides an easy way to select an audio input by a numeric value. Combined with the umenu Object, it becomes easy to control audio signal routing in a multidelay Patcher.
INPUT SIGNAL ROUTING
Hopefully, you're now enjoying playing your instruments through your
new dual-synchronized audio-loop delay. You may be thinking that it's
kind of lame, though, because both delays get the same input, and the
delays come back from both speakers equally.
There are any number of ways to control signal routing in Max,
including drawing patch cords from point to point. For Patchers such as
the one we created, I prefer to use pop-up menus to choose an input for
each delay section. Fig. 17 shows our first delay unit modified
to let the user choose from a list of inputs, along with a fragment
that shows the changes needed with the delayline Patcher Object to
accommodate menu selection. (Patcher Objects appear in brackets in the
title bar of the edit window to indicate that you're editing a
Subpatcher within a larger patch rather than a standalone Patcher.)
FIG. 18: The umenu Inspector allows you to enter a text list, delimited with commas, for the pop up menu. When an Object is selected, umenu outputs a number corresponding to that item''s position in the list, starting with 0.
The user menu (“umenu”) Object provides a pop-up list
that is defined in the Object's Inspector dialog (accessed by selecting
the Object and then pressing Command + I), as shown in Fig. 18.
Items in the list are delimited by commas. When the user clicks on the
umenu Object, this list of items pops up. When an item is selected,
umenu outputs a number corresponding to the item's position in the
list, starting with 0.
Within the delayline Object, an audio “selector~” Object
controls the actual audio source routed to tapin~. The selector~
provides some number of inputs, defined by the number that follows the
name, and one input for control. The number routed from the user menu
goes to the left-hand input of the selector~. Selector~ routes one
signal at a time to its output, depending on the number sent to the
left-hand control input. An input of 0 switches all signals off.
Up to this point, we've used the adc~ Object in its default Stereo
mode. But this Object can accommodate any number of inputs from a
physical interface; simply list the inputs in the Object's name. To
illustrate, adc~ is set up in Fig. 18 to accommodate four
inputs. It could just as easily be 8 or 16 ins.
You can also route the output of one delay unit to another's input
by using send~ and receive~ Objects, which are the audio equivalents of
the send-receive pair that we used for the master tempo. Space
precludes detailing that in this article.
FIG. 19: You can create as many delay sections as you wish, all synced to the same bpm value. In this example, each section is fed by a different analog input, but you can also have a single source going to multiple delay sections.
Now that you have a way to set different inputs for each delay unit,
you might want to create even more iterations of the core delay, as
shown in Fig. 19. Go ahead and have some fun with it.
PANNING AND MIXING
FIG. 20: A simple left right pan can be built using a knob control and simple arithmetic to create complementary control signals for each channel.
The last step we're going to take with our multisynced delay Patcher
is to add output panning, first in stereo and then (for those with the
means and inclination) in quad. For simplicity's sake, we'll stick with
straight linear panning. Cycling '74 provides some excellent examples
of equal-power panners and other variations in the user documents, and
these are well worth studying and implementing. For the purpose of this
exercise, though, we'll keep it simple.
Fig. 20 shows our main delay section with a stereo pan pot
added, along with the portions of the delayline Patcher Object that are
changed to accommodate it. The key here is the creation of two gain
control signals from the single pan-pot output, accomplished by
subtracting the maximum control range (127) and then multiplying by -1
to invert. After that both signals are scaled and sent to a pair of
audio multipliers that implement the actual pan.
FIG. 21: Four channel panning is a little more complex because left right and front back controls must be created separately.
Our last trick will be to do the same in quad. Max provides a
convenient x-y control that makes doing that easy. To make the actual
panning work, we first have to create the left and right pan outputs
and then use four additional audio multiplies to implement front-rear
panning separately for left and right (see Fig. 21).
Fig. 22 shows the final result (well, a final result) of our
efforts: a group of four long audio delays that are coordinated
precisely with a common tempo. Try this Patcher out with slow-attacking
guitar, synths, vocals, and so forth. You are guaranteed a spacious
experience, especially if you can listen in quad! Of course, there's no
reason to limit yourself to four modules. You can add as many as you
like, until processing power or memory runs out.
FIG. 22: With the full version of the multidelay Patcher, you can route and control as many delays as you like, with full 4 channel panning and common tempo sync.
MAKING IT YOUR OWN
We've come a fair distance with our quad multibeat-synced delay
lines, but the real purpose of this article has been to get you
comfortable with creating and modifying audio-processing Patchers in
Max/MSP. You should now be able to build your own creative
signal-processing tools. Even starting with the Patcher presented here,
you have ample room for expansion. Here are a few ideas if you want to
continue exploring on your own.
Add a function to accept a tapped tempo to define bpm.
Add a MIDI-clock output to drive external sequencers, drum machines,
and the like at the designated tempo.
Add a MIDI-clock input. (Take note: this is actually harder than it
sounds!)
Modify the signal routing so one delay unit can feed into
another.
Add MIDI-control inputs so all parameters can be changed with a MIDI
control surface.
Add audio recording so you can grab your jams on the fly.
Add time-based automation so all control moves can be recorded.
All of this is possible within Max and MSP, although some tricks are
more difficult than others. The real excitement will be in generating
and implementing your own concepts. With Max/MSP there's simply no need
to be limited by what's available in current fixed-function products,
because you can build anything you like, on the spot, and totally from
scratch if need be!
Gary S. Hall consults, writes, and composes from his home
base in Alameda, California, and from custom remote facilities in Bahia
and the Utah outback.