The idea of software is to create interactive data manipulation interfaces, right? The "underlying code" that manages an interface doesn't have have to be written, edited, or even seen by a Max designer / programmer. The built-in objects themselves are C programs prewritten by experts, each providing simple to advanced interactivity or other functionality, with the ability to accept messages and commands that change their attributes, cause them to send out additional commands or messages to other objects, and so on. About 50 of the built-in objects are directly / graphically interactive; the rest (several hundred, with new ones being written all the time) are functional "black boxes" which manage parts of the data flow by providing some sort of specialized calculation or other task.
Here is a picture of a prototype "script" in Max which, among many other uses, could easily be used to modulate the volume of a sound channel for a specified interval. It's a small collection of objects ("interactive variable containers") -- all of which are directly interactive (except the addition object, which performs the calculation). There are several connections drawn between them (connections in "code-speak" might be :: how variables pass and share values among each other, and into and out of functions like the addition object here). It's completely functional and only took a few short seconds to put together.
A note about the versions of Max ... the new functionality and appearance of Max 5 is incredible :: it really is a complete overhaul from the earlier versions. One of the new improvements is the ability for nearly all objects to have transparency levels, which really helps get away from the admittedly flat, blocky appearance of Max 4 and previous. But that's only one of a whole slew of essential improvements in the program, which you can read about on the Cycling '74 website.
|
Max 4
![]() |
Two numerical values are added (either one could be negative as well, thus decreasing instead of increasing the result) ... the value is applied to the slider ... the slider's value is displayed in the number box at bottom, for an update or for additional interactivity / connections. If one uses this for audio, connecting the signals is a simple matter -- just draw the desired connections from your source(s). Souces could be audio file playback, input from a microphone, synthesized waveforms, etc ... ... ... Of course, this interface is just a way to control a small set of numbers -- no reason to have it only be used to control audio, as it could perform any "digital-media task", that is based upon numbers, that one wishes (read: ANY). Automating and recording changing values is a breeze in Max, as are saving and re-loading these sets of data. This releases the user from direct, single-control interaction, allowing one to perform multiple interactions at once, or trigger future events to happen in a timed, event-based, or generative manner. |
Max 5
![]() |
Not only will this easy-to-understand interface be a snap to configure, the possibilities within that one action (modulation of volume) now are plentiful, rather than simply jumping to the new volume, then jumping back. ANY kind of pattern of modulation you can imagine can be created, edited, automated, and recorded using Max, because graphical control and storage of numbers is Max's whole purpose. The comparison of time spent scripting something like this function (and learning HOW to script something like this, which is the lion's share of the time spent in development) like this in a code-based language versus graphically creating it in Max is truly absurd ... ... ... ... ...
do... you... speak... computer? ..................... ... Consider the following sample Lingo (Director) script, one of the many such scripts I created for the Audio Mixer 2.0 project. It performs a similar function to the Max interface above. Computer languages, and the code written in them, vary considerably ... but the underlying logic is pretty consistent. Getting a feel for how this short sample code "reads" will give a good introduction to general programming logic, and looks fairly similar to many other languages aside from some language-specific syntax differences (for example, many languages require semicolons at the end of lines, but Lingo does not). Code-based languages DO form the basis of all things computer, so they *are* important for many things, and can provide functionality that is difficult or impossible to do otherwise. Higher-level languages like Max are specifically designed to allow users to bypass code and work on a graphical level -- with the added benefit of being able to incorporate Java, Javascript, and C, should one wish. This means that the unique language / environment that is Max is extensible virtually endlessly, as users create more objects and patches using it.
On to the Lingo script:
Anything with dashes preceding it are comments and have no function except to provide information about what's happening in the code.
----- Sample Code Fragment
----- Controls one of the Audio Modulation functions
----- in Audio Mixer 2.0 -- press a key and the volume is modulated while the key
is held down
if the keyPressed
= "a" then
c = 1
----- this variable is local and used as a placeholder
in the modulation subroutine
----- this, and the key pressed, are the only variables that need changing in
the copied code
----- 7 copies, total of 8 channels...with any one of 5 modulation modes each...40
total mini-routines
if modType[c] = "volUp" then
x = integer(modVolAmt[c] * 2.2)
y = sprite(19).locH
z = y + x
sound(c).volume = vol[c] + x
----- this actually changes the channel's volume setting
----- and gets information about the volume slider's position on the screen
startTimer
repeat while the timer < modRate[c]
if chanSel[c] = 1 then
sprite(19).locH = z
if sprite(19).locH > 504 then sprite(19).locH=504
updateStage
----- this updates the position of the volume slider for
a specified interval
end if
sprite(c + 20).blend = integer(99 - 10 - (modVolAmt[c] / 1.8))
updateStage
end repeat
----- this is the repeated loop where the channel's volume
is temporarily increased,
----- for the duration of the modulation length
sound(c).volume
= vol[c]
sprite(19).locH = y
sprite(c + 20).blend = 99
----- here it resets to the original volume level
else if modType[c] = "volDown" then
----- etc........on to the next fragment
This is one of 40 similar code fragments dealing with just the Volume Modulation functionality of the mixer. The overall project has hundreds of such fragments dealing with dozens of functions. And, although one can get a lot of mileage out of copying and pasting, or with just changing a value or a variable here and there, these scripts (and, really, ANY code-based language) still are, at their heart, laborious to create, maintain, and debug. That being said, Lingo is a very readable and functional language which I thoroughly enjoyed exploring at the time. The problem is that it simply takes way too long, with too much trial-and-error using code, to "get stuff to do stuff" ! !
Anyone interested in mashing media should take a good look at what MMJ can do, then see if they want to start patching. It can be pretty addictive for the brain, and it always spawns new ideas for creation and interaction.