Delaying MIDI notes

There are many objects available for delaying events (i.e., for scheduling events to happen at a specific future moment). For timing and scheduling events, the most common object is the metro object (send bang periodically at a specified time interval), which can be used to trigger events, start/stop entire processes, or trigger a counter to step through a table or a coll or any sort of sequence of things. To show the user the passage of time, the clocker object is useful (report elapsed time periodically), as are timer (measure the time between two events) and tempo (count rhythmic units according to a metronomic tempo). For delaying a single bang, use delay; for delaying one or more numbers, use pipe; for delaying an audio signal, use delay~ or the variable delay line objects tapin~ and tapout~; for delaying a video, you would generally use jit.matrixset.

This patch contains a couple of simple examples demonstrating the use of delay and pipe (note that one is for bangs and one is for numbers), plus a slightly more complex example using tempo (to look up numbers in a table at a metronomic rate) and pipe (to echo the notes, and also to provide all the note-offs).

The first program, on the left side of the patch, chooses a number at random from 0 to 127 every 800 milliseconds and plays it as the pitch of a MIDI note. Each number gets displayed, and stored temporarily, in the number box. Each bang from metro that triggers a number also gets delayed by three different delay objects, and those delayed bangs trigger the same number in the number box a few tenths of a second later. What results is a 4-note rhythmic pattern for each pitch.

The second program, in the middle of the patch, illustrates a couple of important concepts. The first concept is that timing is an important aspect of a composition at many structural levels: microscopic (the sample level in audio or the frame level in video), small formal level (notes in music or edits in video), middle formal level (such as a phrase in music), or even at the global formal level (entire sections of a composition, scenes, etc.). Thus, a metro object can be used to generate a very fast sequence of bangs to display frames of video or generate a smooth stream of events, and it can be set moderately fast to generate notes, but it can also be set to a much longer time interval to trigger phrases (sequences of notes or events) or to turn on and off entire complex programs. A second concept is that the same bang that triggers the start of a process can also be used to trigger a delay object to turn off the same process at some designated time in the future. Also, perhaps most commonly, delays can be thought of as echoes or repetitions, either short-term or long-term, either verbatim or with some sort of variation.

At the top of the program is a slow metro that sends a bang every four seconds. The first thing it does is trigger a random number from 0 to 116, a "transposition" value to be stored as the right operand of the + object. Immediately after that, it turns on a faster metro, and it also triggers a delay object. The faster metro chooses random numbers from 0 to 11 at a rate of ten times per second. Those numbers get added to the randomly-chosen transposition value in the + object and used as MIDI pitch values by makenote. After one second of that, the delay object stops the fast metro, thus ending the "phrase" of fast notes. However, the fast pitch values are also all delayed by a pipe object that passes them on two seconds after they were generated, thus performing an echo of every randomly-generated phrase two seconds later.

The third program demonstrates the use of the tempo object, demonstrates the use of the table object, and also shows two uses of the pipe object.

The tempo object is like a combination of metro and counter, but it allows you to specify its rate in particular music-related terms. The first argument of tempo (or a number in its second inlet) specifies its tempo, in quarter notes per minute. The help file and manual page say that the tempo refers to "beats per minute", but it's really much more correct to say that it refers to quarter notes per minute. That's because tempo is biased toward 4/4 meter. It thinks of a measure always as being a whole note, and its tempo refers to the rate of a quarter note. The next two arguments (inlets) are for specifying a "multiplier" and "division", which are probably best thought of as the numerator and denominator of the fraction of a whole note that you want tempo to use as its actual rate of output. For example, in this program, we have specified a tempo (a quarter note rate) of 120 bpm, and we've asked tempo to report 1/8 notes. At a quarter note rate of 120, we would expect eighth notes to occur at a rate of 240; that is, if quarter notes occur every 500 ms, eighth notes occur every 250 ms. This tempo object thus outputs at a time interval of 250 ms, and counts the eighth notes in the 4/4 measure, starting at 0 (as computers often do) and counting up to 7 over the course of a measure. This is comparable to using a metro 250 object to bang a counter 0 7 object.

We use the output of tempo to look up some stored information in two table objects. The table object is what's commonly called a "lookup table" or an "array". You can store an ordered array of numbers, and then look up those numbers by referring to their "index" number (also sometimes called the "address") in the array. In table, the index numbers start from 0, and each location in the array can hold an integer. In the table's Inspector, you can set it to save its contents as part of the patch, so that the stored numbers will always be there the next time you open the patch. When table receives an index number in its left inlet, it sends out the number that is stored at that index location. In this patch, we use one table to store an 8-note pattern of MIDI velocities, and we use another table to store a pattern of pitches. (You can double click on the table objects to see their contents displayed graphically.)

Each time the tempo object sends out the number 0, which is to say at the beginning of each "measure", each cycle of 8 eighth notes, we use a select object to detect that fact, and we trigger a new transposition for the pitch values. The counter object is set to count from 24 up to 41, but its output is then multiplied by 2, so in effect it's actually counting upward by twos, from 48 to 82. Those numbers are used as the base key, the transposition, for the simple melodic pattern contained in the pitch table. Note that the pitch pattern in the table was composed so as to outline an upward tonic major 7 chord followed by a downward secondary dominant 7 chord (V65/ii), thus leading directly into the next iteration which will be transposed a major 2nd higher.

These pitches and velocities are sent to a noteout object to be transmitted as MIDI note-on messages. Each pitch (but not the velocity) is also sent to a pipe 0 0 375 object so that it, along with a 0 representing a note-off velocity, will be sent out 375 ms later to turn each note off. This has a comparable effect to using a makenote object. The pitches and velocities are also sent to a pipe 0 0 8000 object before going on to the other pipe and noteout, which results in a verbatim repetition of all the notes 8 seconds later.