Control Object Tutorials

Christopher Dobrian

revised for IRCAM Max by D. Waxman

This chapter offers 38 tutorials dealing with the control objects of Max. These descriptions correspond to patches with the same numbers in the doc/tutorials directory of the Ircam Max/Fts distribution.


TUTORIAL 01
Hello

New elements: the print object, message boxes, patch cords

Click in the box marked "Hello!" and watch the Max window. This program has two elements: print is a function, or in Max terminology, an object. The print object prints whatever it receives into the Max window. "Hello!" is a message contained in a message box. A message box can contain anything that can be typed. Most often it contains numbers.

Both message boxes and objects can have inlets and outlets. Different objects have different numbers of inlets and outlets. Inlets are indicated by blackened areas on top of an object or message box; outlets are indicated by blackened areas on the bottom. Notice that the print object has no outlet. Its output is the Max window.

Objects are connected by patch cords, which carry information between them.

Thus, the program operates as follows: Clicking on the message box sends the message "hello" out from the outlet, through the patch cord, and into the print object, which prints it in the Max window.

Editing The Patch

The Max program has two modes: locked and unlocked. When a Patcher window is locked, it is a program ready to run. When a Patcher window is unlocked, the patch shown in the window can be modified.

When only a key is showing in the upper left corner of a Patcher window, the window is locked and it cannot be edited. To unlock the window, click on the key. This will make the tool palette appear next to the key. To lock the window again, click on the key once more.

Exercise 1.0

Make a program that prints "Goodbye!" following these directions:

1. Unlock the patch by clicking on the key.

2. Click on the "object" tool[[Eth]]the first tool to the right of the key[[Eth]]and drag a new object down to the bottom right corner of the window. Type the word "print" and click in a blank part of the patch. The object will become a print object.

3. Click on the message box tool in the tool palette[[Eth]]the second tool to the right of the key[[Eth]]and drag a new message box to a place above the print object. Type "Goodbye!" in the message box.

4. Click on the outlet of the message box and drag to the inlet of the print object. This should connect a patch cord from the outlet of the message box to the inlet of the print object.

5. Click on the key to lock the progam. It is now ready to run.


TUTORIAL 02
Bang

New elements: bang

This program contains three separate printing programs. Click on the bang objects in each program and observe the results in the Max window.

The first thing to notice is that two of the print objects have names: x and y. This is a convenience feature so that you can know which print object is printing. If a print object has no name, it is simply called "print" in the Max window. The second important new thing in this window is the button icon, known as bang. It appears as a separate tool in the tools palette (the fourth tool from the left), and is much like a message box that contains the message bang.

Bang is a magic word in Patcher. It is a special message which means "Do it!" A message box will respond to either a direct mouse click or some sort of "Do it!" message (either bang or a number) in its inlet.

In the first program, you can click on the "Gotcha!" message box to print it, or you can click on the bang, which sends a bang message to the inlet of the message box. The result is equivalent.

The second program shows that bang quite literally sends the message bang.

The third program is sort of a puzzler. Clicking on either button produces a printout of "y: bang". If you click on the upper button, though, which bang is supplying the message to the print object? The answer is the lower bang. The upper bang sends a bang message to the lower bang. The lower bang interprets this bang message as "Do it!", and performs its expected function, which is to send a message of bang. The print object prints out what it receives.


TUTORIAL 03
Slider, Number box, and Comment

New elements: slider, number box, comment

The slider is like a potentiometer which produces integer ("fixed point") numbers from 0 to 127. Drag the slider's horizontal bar to see how it works. When you first choose a slider from the tools palette (it looks like a tiny slider), it has 128 values, from 0-127. You can change the length of the slider (and thus its range of values).Note that the slider also has an inlet. It can receive numerical data from another source. This makes it useful not only as a user control tool, but also as a graphic representation of the values being input to its inlet.

The number box (which looks like a message box with a black arrow on the left side) displays numerical values received at its inlet. It responds only to numbers. Notice that when it receives the non-numeric message "Hey!" it prints an error message in the Max window. The number box comes in two versions, integer and floating point (the floating point number box includes a decimal point). Sending a floating point value through an integer number box converts the incoming value to an integer, truncating it and thus removing its fractional part (i.e., rounding it downward). Conversely, sending an integer value through a floating point number box converts it to a float. This does not change its value, only the way it is stored. The number box is a useful tool for testing what value is in a given patchcord. (Good for testing programs as you build them, as well as for showing values while a program is in use.)

Dragging on a number box in run mode causes the number inside to change and be output from the outlet. In addition, one can select a number box by clicking on it and then type a new value for it on the keyboard.

The tool in the palette to the right of the message box (which looks like a message box with a dotted bottom) is a comment box. A comment a way of putting text into a program. It has no effect on the program's functioning. The two main reasons for comments are:

To instruct the user, such as "Click here."

To explain the function of a program or an item in the program.

This is not only helpful to the user of the program, but is also very helpful to yourself as a programmer. You will be amazed how quickly you can forget how your own program works. Get in the habit of adding many explanatory comments as you build programs.

To insert a comment, drag a comment box out of the palette just like any other item, then type in your comment. You can reshape the comment box (or other object boxes) by dragging on its resize point.


TUTORIAL 04
metro and toggle

New elements: the metro object, toggle

Max contains dozens of objects besides the print object. The function of a Max object depends on what is typed inside it. One useful object is called metro, short for metronome. It accepts one argument: an integer number of milliseconds. When the metronome is started it sends out a bang message every x milliseconds until it is stopped.

The metro object has two inlets. The left inlet accepts the messages bang, to start the metronome; stop, to stop it; and numbers: any nonzero number starts the metro. The right inlet can receive a new time argument (an integer number of milliseconds). In this example, we'll only be concerned with the left inlet.

The toggle is a graphic tool (it appears as an X in the palette) which alternately sends out the values 1 and 0. This can be used an on-off switch for objects such as metro. When toggle sends a 1, it shows an X in its box. When it sends a 0, the X disappears. A number box has been inserted in this patch to show its value explicitly.

What does toggle itself accept as input? The most basic kinds of input are a bang or a direct mouse click (both of these invert the toggle's state, turning it on if it is off and vice versa). Toggle can also receive numbers. The numbers it receives will be passed on through its output, and toggle will remain "on" as long as it receives nonzero numbers. To be turned off it must receive bang, a mouse click, or 0.


TUTORIAL 05
Test 1

Here is a problem to test your understanding of some of the tools explained so far.

Create a Patcher program which, when turned on, prints the phrase "test: 1" every two seconds until it is turned off.

To see the answer, scroll to the right in the Patcher window or enlarge the Patcher window by stretching it to the right.


TUTORIAL 06
+/- Arithmetic

New elements: +, -, /,*,%

Max has an object for each of the basic arithmetic operations, plus a modulo operator (modulo divides the left input number by the right input number and outputs the remainder). Each of these "operators" expects one number in its left input, and the other operand as its argument. The argument can also be supplied in the right inlet.

Both methods are shown in this Patcher window. (Note: Just plugging something into the inlet did not supply an argument automatically. The value has to be be sent through the patch cord, in this case by clicking on the message box.)

These operators give a integer output unless they are coerced into yielding a floating-point output. To coerce a float output, the object must have an argument which contains a decimal point. The two division programs at the bottom right corner of the Patcher window demonstrate this. The first program truncates its answer regardless of whether the input values are int or float. The second program gives a full float output (because its argument contains a decimal point), even if the input values are integers.

A bang can also be received in the left inlet. A bang causes output by repeating the last number received in the left inlet.


TUTORIAL 07
Relations

New elements: <, >, <=,>=, ==, !=

Max also has objects for different "relational operators". Relational operators compare two numbers and determine their relationship: for example, is the first number greater than the second? less than the second? greater than or equal to the second? less than or equal to the second? equal to the second? not equal to the second? If the answer is "Yes", the relational operator outputs the number 1. If the answer is "No" the relational operator outputs the number 0.

Notice that, like with the arithmetic operators, the objects do not generate output until they receive a value in the left inlet. When a value is received in the left inlet, it is compared with the object's argument, or with the last value input to the right inlet. Note that this rule is valid for nearly all Max control objects: the left inlet is the "active" inlet which causes the object to calculate and produce an output.

The select object is a special kind of relational operator. Instead of outputting a yes or no, it passes whatever is received in its left inlet directly out its right outlet unless the input number is equal to its argument, in which case it outputs a bang from its left outlet and nothing out its right outlet. In other words, it selectively bangs rather than passes the value when the value is equal to its argument.

Max's relational operators make integer comparisons; that is, they convert input values to integer before making a comparison. However, relational operators can be coerced to make a float comparison, just as arithmetic operators can be coerced, by typing in a float argument which contains a decimal point. If the relational operator has a decimal argument, it will convert all input values (at either inlet) to float before comparing. In the program at the bottom of the Patcher window, the two message boxes at the top left are connected to the left inlets of all the == objects. The two message boxes at the top right are connected to the right inlets of all the == objects. Try out all the permutations of inputs, and note how the behavior of the float operator differs from the integer operators.


TUTORIAL 08
AND and OR

New elements:&& and ||

The && (AND) and || (OR) objects are "logical operators". The && object asks the question: Are both my left input and my right input nonzero numbers? If the answer is yes, the && object outputs 1; if the answer is no, the && object outputs 0.

The || object asks the question: Is either my left input or my right input a nonzero number? If the answer is yes, the || object outputs 1; if the answer is no the || object outputs 0.

Move the left slider and observe the response of "and" and "or" in the number boxes below. Then change the right slider to a different value and try again with the left slider.

Other objects in Patcher handle bit-level comparisons. They are & for AND and | for OR. We will see these in Tutorial 38.


TUTORIAL 09
Test 2

This is a test.

Open the patch 09-Test2.pat for instructions.


TUTORIAL 10
bangbang and trigger

New elements: bangbang and trigger

The bangbang object creates up to ten outlets, depending on its argument, out of which it sends bang messages. In this patch, bangbang creates three outlets. When a bang is received it will come out of each outlet from right to left.

· Attention! Max objects always ouput from right to left.

The trigger object is quite useful for sending information--a bang, an integer, a float, or a list of numbers--to any number of different places, in a specific order. Whereas the bangbang object can send a bang to any number of different places in a specific order, trigger can take in and output a bang, an integer,a float, or a list of numbers. Furthermore, trigger can convert its input to any other format before outputting. Each outlet can output a different format.

The trigger object has one inlet (which can receive a bang, an integer, a float, or a list of numbers) and a variable number of outlets. The number of outlets is determined by the number of typed-in arguments. Valid arguments are:

b for bang

f for float

i for integer

l (el) for list

The argument determines the format in which the data is sent out the corresponding outlet. If no arguments are specified, the default is two inlets, both sending out integer values (the same as {trigger i i}). If a bang in the inlet is to be converted to an integer or a float-point point number at the output, it is interpreted as 0 (or 0.). The outlets send in order from right to left as is the case with most objects. Click on the messge box and note what is printed in the Max window (and in what order it is printed).


TUTORIAL 11
send and receive

New elements: send and receive

The send and receive objects (it is also possible to call them s and r) transmit information without a patch cord. Each object takes an argument which is a name which it shares with its transmitting counterpart(s). In other words, the name is like a unique radio frequency, and any send or receive object with that name can transmit to or receive from everyone else tuned in.

Any type of message can be transmitted and received by this means: integers, decimals, words, bangs, etc.

The send and receive objects need not be in the same window. This is very valuable since it allows programs to communicate from one Patcher window to another. It is also dangerous because it permits you to send information to places you may not know it's going; so be sure to use unique names for your send and receive objects, in order to avoid unintentional transmission.


TUTORIAL 12
The patcher object

New elements: patcher

The patcher object enables you to encapsulate part of a Max program in its own window. patcher objects may be nested, such that a Max program contains patcher objects which contain patcher objects, etc.

As soon as you create a patcher object, a new Patcher window will open in which you can build a subprogram. To make the subprogram window disappear when you are finished, just close its window and you will be returned to your previous Patcher window. It is not necessary to save the subprogram as an independent file before closing it (unless you want to), because when you save your main program the subprogram will be saved as part of it, just like any other object in the main program.

To open a patcher object and observe its contents, lock the window in which the object resides and double click on the patcher object. It is a good idea to label each patcher object with a descriptive comment to help you remember what it does. (See example.)

If you do save the subprogram (by choosing the "save" command in the "File" menu while the subprogram's window is active), it is saved as a separate file in the same way as any other Patcher program.

Messages can be passed from one window to another by two means. Notice that in the example there are two patcher objects. One has input and outlets, the other does not.

In the first program, information is passed to and from the patcher subprogram by means of s and r objects. In the second program, the patcher subprogram includes an inlet and an outlet (the last two tools in the palette). Putting these items inside the sub-patcher window automatically creates corresponding inlets and outlets on the patcher object in the main program, through which information can be passed.

Why have a patcher object? It enables your program to perform some tasks by calling on a subprogram (which may be enormously complex and large) without having to include all the workings of the subprogram in the same window. In this way you can hide from view any parts of the program which are too large, confusing, ugly, complex, or whatever. Furthermore, this enables you to build many different programs, each one of which performs a different task, which can be rearranged and connected in any way you choose.


TUTORIAL 13
Your object

New elements: none

Any existing Max program can be turned into an object in its own right. Simply create a new object and give it the name of an existing Max program in your current path (see paths), and that object will function in exactly the same way as the named program. For example, in this example the object C_to_F is actually an existing Max program, already saved in a file entitled "C_to_F". It functions just like a patcher object, except that if you want to edit the object you must actually open the file named "C_to_F" (with the "open" command) and edit that file. Double-clicking on the C_to_F object in this program will let you see the inner workings of the object, but will not let you edit them. Notice that the object's window has neither a key nor a palette and the name of the object is in parentheses (to show that it is locked).

This is one of the main strengths of Max. Once you have created a Max program and saved it in a file, you can use it in any other program simply by creating a new object with the same name.

A couple of warnings about creating your own objects:

Warning 1. Your object should not include itself in its patch! For example, if C_to_F contained a C_to_F object, the object would get into a recursive loop searching for itself, with unhappy consequences.

Warning 2. Only put your own objects in Patcher windows that have already been saved. Here's why. When you create a new object, Patcher checks to see if it recognizes the type of object. If not, it looks to see if the name corresponds to an existing Patcher file in your current path. If the Patcher window where you are putting the object has not yet been saved, however, Max has no way of knowing how to find it!

Another suggestion: when you create a Max file for eventual use as a subprogram (object) in another program, you will often need to design it so that you can get data into and out of it. The most obvious way to do that is by including inlets and outlets. Then your object will have input and outlets and can communicate with other objects via patch cords. Your objects can also require typed-in arguments.


TUTORIAL 14
Another Examination

Here's a problem to test your understanding of all that has been explained so far:

Make a program in which the user sees only: a slider, a number, and a patcher object

All the calculations of the program are performed out of sight by the patcher object.

The program should, first of all, convert Celsius to Fahrenheit. Then, for each reading on the slider in the main program (being dragged by the user), the program should:

1. print "adjust: upward" if the temperature is below 68 F

2. print "adjust: downward" if the temperature is above 68 F

3. print "There: Perfect!" if the temperature is exactly 68 F

The program should also print the temperature in degrees Fahrenheit in the format "temperature: X" where X is the Fahrenheit temperature

The answer to the problem can be found by scrolling or expanding the Patcher window to the right. Remember, to see the contents of the patcher object, double-click on it (while the Patcher window is locked).


TUTORIAL 15
notein and noteout

New elements: notein, noteout

The notein object receives note data from an external MIDI source. The noteout object sends note data out through the Ispw card's MIDI port.

The notein object has no inlets. Its input comes from the MIDI port. It has one optional argument, a MIDI channel number. If the argument is not present, then the notein object's reception channel is "omni" (in the parlance of MIDI) and the object has three outlets. The outlets emit, from right to left: channel, velocity, and note. (This is also the temporal order with which they are output from the object.) If an argument is given (as in the upper left example) notein receives only notes which come in on that MIDI channel, and has only two outlets: note and velocity.

Play some notes on the keyboard and observe the output of the notein objects (if nothing happens, check all your MIDI connections).

Notice that each note you play sends two noteon commands to Max, because a noteoff is expressed as a noteon with velocity of 0. Send some notes out of your synthesizer on some MIDI channel other than 1. Notice that the notein object on the left ignores those notes.

The noteout object has no outlets. Its output is the IRCAM Music Workstation MIDI port. It has one optional argument, a MIDI channel number. The noteout object has three inputs, regardless of the presence or absence of an argument. Right to left, the inlets accept: channel, velocity, and note. If an argument is given noteout will send on that MIDI channel. If no argument is present noteout will send on channel 1 by default. A channel number supplied at the right inlet will override either the argument or the default.

The way that the noteout object deals with note and velocity data is characteristic of many objects in Max, and requires some explanation. In the first example, clicking on one of the message boxes sends a list of two integers to the left input of the noteout object. The right integer is interpreted as a velocity value, and the left integer as a note number (pitch). (However, noteout will not accept three integers all in the left input. The channel must be sent separately in the right input.)

The second example shows a different method. Note and velocity values are sent to noteout via individual inlets. This is a little tricky, because when the pitch value is received, noteout plays that note with whatever velocity it most recently received. (If they arrive simultaneously, values will be read right to left. That is, channel is read first, then velocity, then note.) In this second example, try clicking on different velocity values before clicking on the note value, and listen to the effect.

Message Order

When a Max object has more than one inlet, the leftmost inlet is usually the one which "triggers" the object to send its output. Thus, when an object requires two or more numbers in its input (such as pitch and velocity in the noteout object), the leftmost input should be received last to ensure that the other data has already arrived. Often, however, an object accepts both numbers in its leftmost inlet, in the form of a space-separated list (e.g., "76 45"). In this case, the second number is sent to the second inlet from the left, then the first number is sent to the leftmost inlet . This is usually the best way to make sure that two or more numbers arrive in the proper order. Other Patcher objects that behave this way include: bendout, ctlout, pgmout, touchout, arithmetic operators, relational operators, logical and bitwise operators, makenote, sustain, swap, fswap, pipe, line, and table. To change two separate numbers into a single two-number list, or vice versa, see the Control Object Tutorial 24.


TUTORIAL 16
The makenote object

New elements:makenote

Sometimes it is inconvenient to have to follow every note-on with a corresponding note-off. The makenote object takes noteon messages, and after a certain delay follows them with corresponding noteoff statements. The makenote object takes in an integer in its left input, and interprets it as the pitch value of a note-on message. The makenote object takes two arguments: the note-on velocity, and the duration of the note (delay before a corresponding note-off is produced). If no arguments are typed in, these values will be 0 by default. The arguments can also be supplied via the middle and right inlets, respectively. The left inlet is also capable of taking in a list of two or three values (separated by spaces). If it receives a list of more than one value at its left input, it interprets the first value as the pitch, the second as velocity, and the third as duration. If only one value (pitch) is received at the left input, the most recently received values for velocity and duration are used. Move the different sliders; watch and listen to the results.

The stripnote object is the reverse of the makenote object. It passes note-on messages, but not note-off messages. Similarly to makenote, the left inlet of stripnote is also capable of taking in a list of two values. If it receives a list of two values at its left input, it interprets the first value as the pitch and the second as velocity. If only one value (pitch) is received at the left input, the most recently received value for velocity is used. Play some notes and notice the difference in the effect of "stripped" and "unstripped" notes. The stripnote object suppresses all the noteoffs. Suppose you wanted to use the note 60 to toggle some process on and off. Stripnote is valuable to keep the process from being toggled off immediately by the release of the key. Or suppose you want to use the keyboard velocity as a pitch value. Stripnote prevents you from having unwanted 0 values.


TUTORIAL 17
The sustain object

New elements: sustain

The sustain object is a Max version of the sustain pedal on a piano or keyboard. Like stripnote it filters out note-off statements. Unlike stripnote, however, it does not discard them but saves them (while the sustain is turned on), then passes them all through at one time (when the sustain is turned off). The sustain object has three inlets. The left input is for pitch, the middle input is for velocity, and the right input is for on/off commands. The on/off commands are not bang and "stop", however. They are any nonzero integer for "on" and 0 for "off". (Remember that the "toggle" sends "1" and "0".) Just like stripnote, the left inlet of sustain is also capable of taking in a list of two values, separated by a space. If it receives a list of two values at its left input, it interprets the first value as the pitch and the second as velocity. If only one value (pitch) is received at the left input, the most recently received value for velocity is used. The program shown here outputs notes one octave higher than the ones played, and allows the user to sustain the transposed notes independently with the toggle switch.


TUTORIAL 18
Pitch bend

New elements: bendin and bendout

The bendin and bendout objects receive and send pitchbend data. The bendin object has two outlets. The left output is the pitch bend value received, and the right output is the MIDI channel on which it is received. The bendin object has one optional argument, the MIDI channel on which it wants to receive. If an argument is given, the right outlet disappears. If no argument is given, the reception setting is "omni" by default. Likewise, bendout has two inlets. The left input is the pitchbend value to be sent, and the right input is the channel of transmission. The channel can also be specified as an argument to the bendout object. If no channel is specified, the default channel is 1.

In this program, the patch at left is designed to turn a synthesizer's bend wheel into a whole-tone scale-playing tool. (Of course the pitchbend wheel also retains its local pitchbending function if local control is not turned off on the synthesizer.) First, some mathematical calculations are performed on the pitchbend data. Dividing by 4 brings the values into the 0-31 range. (Remember that integer division throws away fractional parts.) Adding 17 changes the range to 17-48. The multiplying by 2 shifts the range to 34-96 (approximately the range of an average synthesizer keyboard), with only even numbers occurring. Now the pitchbend values, instead of going 0, 1, 2, 3, 4, 5, etc., go 34, 34, 34, 34, 36, 36, etc.

This brings up the need for a new, very simple object: change. The change object filters out immediate repetitions; it passes on the value it receives only if it is different from the previous one. In this case, it prevents unwanted repetitions of notes.

The patch at right gives the user a normal pitchbend control, via the slider, since the synthesizer's local pitchbend control has been assigned a new function. Try playing your instrument with one hand on the pitchbend wheel (or the keyboard) and one hand on the slider (or the pitchbend wheel).


TUTORIAL 19
More MIDI in and out

New elements: ctlin, ctlout, pgmin, pgmout, sysexin, gate

This tutorial deals with more objects for receiving and sending three types of MIDI data:

The sysexin object ouputs any system exclusive messages received as raw MIDI data (byte-by-byte, as integers).

The pgmin object outputs program change data from its left outlet. It outputs the MIDI channel on which it received the data from its right output. The pgmin object normally receives on all channels (i.e., "omni" by default), but can be forced to receive on only one channel by typing in an argument. If an argument is typed in, the right outlet disappears. Likewise, pgmout sends out as program change data whatever integers it receives at its left inlet. The channel of transmission can be specified as a typed in argument and/or can be received via the right inlet. The default channel is 1. Note that each synthesizer has its own unique method of numbering its sounds. Some experimentation will probably be necessary to find exactly how MIDI program change data is interpreted by each synthesizer when sending or receiving.

The ctlin oject is similar to pgmin, but has three outlets. The left outlet outputs continuous control values received; the center outlet outputs the controller number (for example, the modulation wheel is controller number 1 on most synthesizers); and the rightmost outlet outputs the channel number on which the data is received. If ctlin has no arguments, it will receive data from controller number 1 on channel number 1, by default. If one argument is given, that argument is the channel of reception, and the channel output disappears automatically. If two arguments are given, they are channel and controller numbers, respectively, and the object will have only one outlet, for the continuous control data. Notice, as an example, that the ctlin object at the upper left corner of the Patcher window has two arguments (channel 1, controller 1) and therefore outputs only the continuous control data. The ctlout object is essentially the inverse of ctlin, but it handles arguments slightly differently. The left inlet receives continuous control values to be sent out; the center inlet receives the controller number (which can also be specified as the first typed-in argument); and the rightmost inlet is the channel number on which the data is to be sent (which can also be specified as the second typed-in argument). If no arguments are typed in or received at the inputs, ctlout sends to controller 0 on channel 1, by default.

The first program turns controller number 1 of the synthesizer (presumably the modulation wheel) into a program selector. The incoming data (from 0-127) is scaled down mathematically to give data from 1-16. Thus, with the modulation wheel, the user can change continuously between the first 16 voices on the synthesizer.

The second program performs the following function: when program number 9 is chosen on the synthesizer, the notes played will be doubled an octave higher. This shows how one can "customize" each voice on the synthesizer in a unique way.

In order to make this program work, a new, very simple object is introduced. The gate object takes values in from its right inlet, and outputs them only when the most recent value in its left inlet is nonzero. If the most recent value in the left inlet is 0, the gate is closed and nothing passes through. In this case, the "==" object will always output 0 (closing the gate) unless the program number is equal to 9. Then the "==" object will output 1, open the gate, and let the octave-transposed notes through to the noteout object. Note: The gate object is "built backward" in a sense. Almost all Patcher objects receive their data and their "trigger to output a value" (a bang, etc.) in their left inlet, and receive their "control" or "test" value (to be stored for reference) in the right inlet. Gate is an exception to this rule.

The following patch is simply a substitute modulation wheel. Since controller 1 has been given a new function by the first program, this slider gives the user normal control of modulation.

The next patch prints out any system exclusive messages that it receives from the synthesizer.

The last patch is a MIDI through. The midiin object receives raw MIDI data. The midiout object takes raw MIDI data and sends it out from the serial port


TUTORIAL 20
Key

New elements: key

Every character that can be typed on the computer keyboard has its own unique numerical code number from 0-127. This code, common to most all computer systems, is called the ASCII code. The key object outputs the ASCII code number of whatever character is typed in on the keyboard. This is particularly useful if you want to use the typewriter keyboard to enter commands to patcher during a performance. For example, in the bottom program the lowercase "z" character is used to toggle a process (which could be anything) on and off, while other key messages are passed on (perhaps to control other processes).

The key object is of relatively little musical use as a note generator, unless you want to explore the musical possiblities of improvising poetry on the typewriter. This program demonstrates a crude but very handy silent MIDI controller, which is sometimes useful while programming, especially if you don't have a MIDI keyboard handy.


TUTORIAL 21
Another test!

Here is a problem to test your understanding of the objects for processing MIDI data:

Make a program which:

a. transposes the incoming note and outputs it

b. provides a slider from -12 to +12 for the user to select the interval of transposition

c. sustains the transposed note(s) as long as the modulation wheel of the synthesizer is active (nonzero)

To see a solution, scroll or expand the Patcher window to the right.


TUTORIAL 22
int and float

New elements: int, float

It is often desirable to store a value for use at a future time. The int and float objects are storage locations. The int object is for storing integer values, while the float object is for storing decimal values.

When creating an int or float object, you can give it an initial value by typing in an argument. If no argument is given, the initial value stored is 0 (or 0.) by default. The stored value can be changed by sending a new value to either of the two inlets. A value in the right inlet replaces the stored value without causing any output. A value received at the left input will replace the old value, and then cause an output.

The patch on the right hand side of this tutorial shows a simple incrementer that counts from 0 by steps of 1. The int is initialized with a starting value of 0 (its argument). When a bang is received at the left inlet, the 0 is output, 1 is added to it, and it is reentered in the right inlet of the int object. Thus the next time a bang is received, 1 will be output and 1 will be added to it, and so on. To reset the counter, click on the message box that sends 0 to the right inlet.


TUTORIAL 23
swap and fswap

New elements: swap, fswap

The swap and fswap objects are related to the int and float objects, respectively. In addition to serving as a storage location, however, swap and fswap also are "managers" which enable you to force two numbers to be transmitted in a certain order.

As with the int and float objects, when swap and fswap receive a value at the right inlet, the value is stored without anything being output. When a swap or fswap object receives a value at its left inlet, however, it stores it and sends it immediately out the right outlet, then sends the value most recently received at the right inlet out the left outlet.

Output occurs whenever:

a. A number is received at the left inlet (as described above).

b. A bang is received at the left inlet (outputting the most recently received values).

c. A list of two numbers (separated by a space) is received at the left input. (Both numbers are stored, as if the first number had been received in the left inlet and the second number had been received at the right inlet; then the first number is sent out the right inlet, and the second number is sent out the left outlet.)

The swap object sends an integer out its right outlet; fswap sends a float out its right outlet. Both objects send an integer out the left inlet. The initial value to be sent out the left outlet can be set by typing it in as an argument to the swap or fswap object. Only one argument (for the left output value) is accepted; the right output value is always initialized to 0 (or 0.) by default. A typed-in argument which contains a decimal point will cause that object always to send a float out the left output instead of an int.

Observe the effects of the swap and fswap objects in these programs by clicking on the button icons and the message boxes, and by adjusting the sliders.


TUTORIAL 24
pack and unpack

New elements: pack, unpack

As has been shown, some objects can receive a list of values (usually two) separated by a space. Transmitting values together in a list (rather than through separate patch cords) is good for assuring that they are received together and in a certain order. The pack object combines several numbers into a single list. The unpack object receives a list of numbers and sends each number out of a separate outlet.

The pack object has two inlets and one outlet if no arguments are given. It expects a single number at each inlet, which it then combines into a space-separated list and sends out its output. When a number is received in the right inlet, it is stored, but nothing is output; when a number is received at the left input, however, it is stored and a list of the values is output. You can "pack" together a list of more than two elements by giving the pack object arguments. The pack object will create an inlet for each argument. The value of the argument will be the initial value of its corresponding member of the list. If you want pack to make a list which includes floating point numbers, you must give it floating point arguments.

Output occurs whenever:

a. A number is received at the left input (as described above).

b. A bang is received at the left input (outputting a list of the most recently received values)

c. A list of numbers (separated by a space) is received at the left input. (The numbers are stored, as if the first number had been received in the left inlet and the second number had been received at the right inlet; then the list is passed to the outlet.)

The unpack object has one inlet and two outlets if no arguments are given. It expects a list of numbers at its inlet. The first number is sent out the left outlet, and the second number out the outlet to the right (and the third out from the oulet to the right of that if three arguments are given). If unpack receives only a single number at its input, it passes it out the left outlet, and sends nothing out the right outlet. (I.e., it does not store and send out a previously received number, the way pack does.)

Obviously, it is important that information be transmitted in the proper format and in the proper order. Objects such as bangbang, trigger, swap, fswap, pack, and unpack exist for that purpose.


TUTORIAL 25
The abs and accum objects

New elements: abs, accum

The abs object can be thought of as an accessory arithmetic operator. It takes an integer at its input and outputs the absolute (i.e. nonnegative) value of that number. Note that it is designed only for integers (it converts floats to ints).

The accum object is like a storage object and an arithmetic operator combined. It stores a number, and accumulates a total as other numbers are added to it or multiplied by it. It outputs the accumulated total when it receives a bang in its left inlet. The accum object has three inlets. A number received in the left inlet replaces the stored value and outputs it. A bang received at the left inlet outputs the currently stored value. A "set" message with some number, received at the left inlet, resets the accum object's value to that number without triggering output. A number received at the middle inlet is added to the value stored in the accum object (without triggering output). A number received at the right inlet is multiplied by the current value of the accum object and stored (without triggering output). Note that if a number with a fractional part (a float) is received at the right inlet, the multiplication is done in floating point arithmetic, but the number stored in the accum object is converted back to an int.

The accum object can be set to store and output floats by typing in a decimal argument.


TUTORIAL 26
Messages

New elements: none

The message box is a powerful tool for managing information (i.e., for putting information in the proper format and sending it in the proper order.) These programs are designed to demonstrate in greater detail how the message box works.

Click on the different message boxes in Program No. 1, and notice what is printed in the Max window. A message box sends its message in two situations:

1. it receives a mouse click

2. it is triggered by a bang or a number at its inlet. It does not accept text (other than bang) as a valid trigger.

The dollar sign ($) is a special character in a message box. It is always followed by an integer, and represents an "argument". When the message is output, the argument will be replaced by the corresponding item received at the message box's inlet. For a demonstration of the use of arguments, click on the message boxes in Program No. 2. The message box gives an error when the first thing it receives is not a number or a bang (such as when it receives the text message "number needed"). In this example, it also gives an error when it is triggered by a bang or a mouse click, since it finds itself unable to convert the arguments into some actual value. When it receives two items at its input, however, and the first (triggering) item is a number, it is satisfied and outputs a message with the correct substitutions. Notice that when it receives the message "3 3.9 4" it ignores the third item (4) because it has no argument "$3". Notice also that both floats and ints can be accepted intact as arguments.

The comma (,) is another special character in message boxes. It is a "message separator", in effect dividing one message into two. In Program No. 3, click on the top two message boxes and watch the Max window. The first message box sends a single message containing two items, "1 2". The second one, with a comma, sends two separate messages, "3", and "4". Now click on the third message box. The comma indicates that there are two separate messages, to be sent one after the other, "1 2" and "3 4".

A backslash character (\) "undoes" the "special" quality of special characters such as "$" and ",". It causes the message box not to evaluate or interpret whatever comes next, but simply to send it on. Click on the fourth message box and notice how the "$" and "," characters are sent on like ordinary text.

Ordinarily, the only way to put a message in a message box is to type it in. However, the special words "set" and "append" can be used in a message box to alter the contents of another message box. When a message box receives the word "set" as the first item in its inlet, it replaces its own contents with whatever follows the word "set".

When a message box receives the word append as the first item in its inlet, it appends (adds on, preceded by a space) whatever follows the word append. Click on the message boxes in Program No. 4 for a demonstration of the words set and append. (Notice that set and append do not trigger the message box they are modifying.)

Program No. 5 demonstrates another special character, the semicolon (;). The first item after a semicolon is interpreted not as part of the message, but rather as the name of a receive object to which the message which follows will be sent. The actual message will be whatever follows, up to the next semicolon (or the end of the message). Therefore, the item that follows a semicolon must be a valid name of an object (i.e., must not begin with a number). Click on the message box and notice what happens to different parts of the message.

Program No. 6 shows two equivalent methods of swapping two numbers in a list. One method uses swap and pack objects; the other method uses arguments in a message box. Note, that the methods would not be equivalent if the numbers were floats. In this case, swap would convert them to integers.


TUTORIAL 27
delay and pipe

New elements: delay, pipe

The delay object (also known as delete) receives a bang at its left input and sends a bang out its output, delayed by the number of milliseconds specified by its argument. Its argument can also be entered via the right inlet.

The pipe object is a delay line for integer values. Integers received in the left inlet are passed out the outlet after first being delayed by a certain number of milliseconds. The amount of the delay can be supplied as a typed-in argument in the pipe object, or can be received in the right inlet.

The pipe and delay objects differ in two important ways:

In other words, delay deals only with the most recent bang it receives, instantly forgetting any previous bangs it may have received. The pipe object, on the other hand, remembers every integer it receives in its left inlet. Each number will be output, delayed by whatever delay time was current (i.e., most recent) when that number went into the "pipe". If, however, pipe receives a "clear" message in its left inlet, its memory is cleared and it forgets (i.e., does not send) whatever numbers may be still in the pipe.

In this program, pipe is used to delay note information, then replay the notes. The modulation wheel (controller No. 1) is used to specify the delay time in milliseconds. To see how the "clear" command works, set a long delay time, play something on the keyboard, then click on the "clear" message before the delayed notes can be played. (N.B. In this example, it is possible that one might clear the pipe after a noteoff (a note-on with velocity of 0) has been input to the pipe but before the corresponding note-off has been output. Thus, using "clear" in this way may leave notes "hung" in the on position.)


TUTORIAL 28
Timer

New elements: timer

The timer object measures the time, in milliseconds, between a bang received in its left inlet and a bang received in its right inlet.A bang received in the left inlet resets the timer to 0. A bang received in the right inlet causes timer to output the number of milliseconds elapsed since the last bang received in the left inlet. (Note that the timer object is an exception to the general rule that output is triggered by input to the leftmost inlet.) The basic operation of timer is demonstrated by the small program in the upper right corner. Click on the two button icons and notice timer's output.

The main program shows timer in action. Incoming MIDI notes pass through a stripnote object (to eliminate noteoffs), then proceed to bangbang. The bangbang object causes timer to output its current value, then resets the timer to 0. Thus, with each note that is played, timer will output the time elapsed since the last note-on was received, then reset and begin timing till the next note is played.

The output of timer is passed through a trigger object that sends the value first to the left inlet of a < object. The < object compares each new time value to the last most recent time value and outputs the result of the test. The trigger object's left output then replaces the value stored in <. In other words, the < object determines whether the time between noteons in increasing or decreasing. If it is decreasing (i.e., the noteons are accelerating), a "1" is output. If the note speed is decelerating or remaining constant, a "0" is output. In this program whenever the note speed is accelerating, the note is doubled at the upper octave. The duration of the doubling note is obtained directly from timer, and will be equal to the time between the last two notes (i.e., the "duration" of the previous note).


TUTORIAL 29
speedlim

New elements: speedlim

The speedlim object limits the speed at which numbers can be sent. The speedlim object takes in integers in its left inlet and passes them out its outlet, but at a rate not faster than the number of milliseconds specified as its argument (or supplied via its right inlet). For example, if speedlim's (current) argument is 250, and speedlim receives two numbers in its left inlet in immediate succession, the second number will be delayed and passed on 250ms after the first number. If more than two numbers are received in a time of 250ms or less, only the last one will be passed on, 250ms after the first one. If the numbers arrive at intervals greater than 250ms, speedlim passes them on without delay. In this program, speedlim is used to limit the speed at which the left slider can send pitchbend data. Adjust the right slider to change the minimum time between pitchbend data sent.


TUTORIAL 30
line

New elements: line

The line object generates a linear interpolation from one number to another. The line object takes two typed-in arguments. The first argument indicates the point of origin--i.e., the number at which the line is to start. The second argument is the time interval, in milliseconds, between values output by line. This can be thought of as the "grain of resolution" or the "sampling rate" of the line being described. The line object has three inlets. The line object's "grain" (the second typed-in argument) can be altered by supplying a new value in the right inlet. Values received in the left and middle inlets specify the "destination point" (the number toward which the line object generates values) and the total time interval within which the line is to be described, respectively. These two values can also be received as a list of two numbers in the left inlet. If a single number is received in the left inlet (without an accompanying value in the middle inlet) it is interpreted as a new destination, to be reached in a time of 0 milliseconds. Since the object is fairly complicated, it is easiest to learn about its operation by observing it in action. So, for example, in this program, clicking on the message box in the upper left corner ("60 2000") will cause the line object to generate numbers going from its origin (0) to its destination (60) every 50 milliseconds (the grain) in a total time of 2 seconds (2000ms). Try it. The slider which receives line object's output is used here simply as a visual display of the output (it corresponds to the sound being produced, as if it were a synthesizer keyboard). Next, click on the message box which reads "0 5000". The line object now produces values going toward 0 in a total time of 5 seconds. Notice that the old destination point, 60, became the new origin point. Any number received as a destination point (i.e., in the leftmost inlet) becomes the new origin point.

If the line object receives a new destination point while it is running, the most recently output number automatically becomes the origin point. This avoids causing line to make sudden jumps to some previous origin point before continuing. Change the line object's grain by adjusting the slider at the right of the program. Click again on the message boxes at the top to restart the line object. Notice how, in this example, the duration of the notes being produced by makenote is always set equal to the grain of the line object. This provides that only one note at a time is played. Overlap of notes could be interesting, and could be caused by setting the makenote object's duration to be always greater than the grain of the line object (say, by interposing a "* 8" object just before makenote's right inlet).


TUTORIAL 31
Introduction to the table object

New elements: table

The table object provides a very useful tool in Max programming: the "array" or "lookup table". In such a table, numbers are stored in a certain order and can be obtained by specifying their "address", their place in the order. The order of numbers in a table is always numbered starting with 0. So, for example, if a table contains the numbers 3, 7, 6, 2, 89, and 3 (in that order), then inputting the number 4 would cause the table object to output 89 (the 5th number in the table, counting from 0).

In this program, the uppermost slider gives input values (addresses) to the left inlet of the table object. The slider below shows the output of the table. Move the top slider slowly up and down, and watch the lower slider.

To see a graph of the table, double-click on the table object. (The x axis of the graph is the addresses, and the y axis is the values.) You can enter new values in this window by drawing (dragging) with the mouse. Draw a graph of your own, then close the "my-table" window and move the right slider as before. Notice that table now outputs your new values.

When you create a new table object in Patcher, a window automatically opens up for you to enter the values by drawing a graph with the mouse. Multiple table objects in the same patch with identical arguments share the same data.

The values read from the table "my-table" are used to play a note on the synthesizer every second (as long as the numbers keep changing). The same values are used continuously to provide pitchbend data. The table can be bypassed by adjusting the lower slider directly.


TUTORIAL 32
More on the table object

New elements: none

Normally, when a single number is received in the left inlet of a table object, it is interpreted as a "read" command; the table object reads the value that corresponds to that address. However, when a number is received in the right inlet, it is a signal that the next value received in the left inlet will be a "write" command. The table object will write the most recent value received in the right inlet into the address specified by the number received in the left inlet. For example, if the number 79 is received in the right inlet, and then the number 34 is received in the left inlet, the value of address 34 will be set to 79. Thus, in this program a y value can be chosen with the rightmost slider. That value will be placed in whatever address is next received in the left inlet.

As is the case with most objects which have two inlets, when a list of two numbers is received in the left inlet, the second number is sent to the right inlet, and then the first number is sent to the left inlet. So, in the case of the table object, a list of two space-separated numbers in the left inlet has exactly the same "writing" effect as if they had been received in different inlets. Therefore, a list of two numbers can be thought of as an "x y" point to be written into the table; it sets address x to value y. This is valuable because any two numbers (such as pitch and velocity from a notein object, or numbers produced by a subprogram you may write) can be used to set the values in a table. In this program, a very simple subprogram (inside the patcher object) sends 128 different pairs of numbers, creating a ramp function in the table.

Sending a bang into the left inlet of a table object will cause it to consider its contents as a probability distribution, and to output the number of one of its addresses. The probability that a given address will be output is dependant on the y value for that address. For example, imagine that a table has only two points (where y is not zero) stored in it: (20, 50) and (35, 100). Sending this table a bang will cause result in an output of either 20 or 35, with 35 being output twice as often.


TUTORIAL 33
The random and split objects

New elements: random, split

Every time the random object receives a bang at its left inlet, it outputs a number chosen at random within a restricted range. The number is always greater-than-or-equal-to 0 and less than whatever number is specified as the object's argument. The argument can either be typed-in or can be supplied via the right inlet.

For example, in this program a bang will cause the random object to output a random number from 0 to 99, inclusive (one of 100 possible values). The argument represents the number of possible values; the maximum possible value is less than that number by 1. The random object outputs only integers, and converts any float arguments to integers. Any argument less than 2 will cause random to output only 0.

The split object takes two integer arguments: a "minimum" value and a "maximum" value. Any number received in the left inlet is evaluated to see if it is within the range specified by the arguments. If it is within the range (inclusive of the minimum and maximum values) it is passed out the left outlet. If it is not within the range, it is passed out the right outlet. The arguments can be either typed-in or provided via the middle and right inlets. (But not as a two-number list in the middle inlet.) In this program the "maximum" argument can be supplied by the slider. If the number that split receives from the random object is from 0 to the "maximum" (inclusive), it will be sent out the left outlet. If the number exceeds the specified maximum, it will be sent out the right outlet. Like the random object, split only outputs integers, and converts any floating point arguments to integers. Unlike random, however, split can deal successfully with arguments and input values which are nonpositive numbers.

In the program, the split object is combined with the random number generator to perform "probabilistic decision-making". If the random number is within the split object's range, a minor third (starting on the random note) is played; if it is out of range, a major third is played. The split object's maximum value is set by the slider.


TUTORIAL 34
The drunk object

New elements: random, split

The operation of the drunk object is best explained by a metaphor. Imagine a drunken man who finds himself in the middle of a long corridor. He begins to walk, without any sense of direction, with steps of irregularly varying size. Each step may potentially be a different size and in either direction. The drunk object lets you specify the end of the hallway and the maximum step size; the drunken output moves about at random within those restrictions.

Each time drunk receives a bang in its left inlet it outputs an integer value, taking a random step up or down within a specified range. The maximum value of drunk's total range is specified as the first argument (or can be supplied via the middle inlet). For example, in this program the value output by drunk will always be somewhere from 0 to 60 (inclusively). The limit to the size of the individual step (i.e, to the amount by which each output value can vary from the preceding one) is specified by the second argument (or can be supplied via the right inlet). The step size will be some number whose absolute value is less than the specified limit. For example, if the second argument is 3, then the step size will be either -2, -1, 0, 1, or 2, chosen at random. The drunk object starts out in the middle of its total range, by default. That is, if the total range is 60 the drunk object will take its first step from 30. If no argument has been given to specify the total range, the default maximum value is 127, and the first step is taken from 64. The drunk object can be forced to output a certain value anywhere within its total range by sending an integer to its left inlet. The drunk object will output that value, and that value will become the new position from which the next step will be taken. Any step size limit less than 2 will cause all steps to be of size 0. If no step size limit is given, either as the second argument or via the right inlet, the default step size limit is 0 (the drunk will go nowhere).

In this program, drunk is used to produce a random meandering of pitches, throughout the normal keyboard range. A metro object (the rate of which is adjusted with the slider marked "note rate") sends bangs to the drunk object as long as the toggle is on. Other sliders limit the step size, or provide new values to drunk.


TUTORIAL 35
Arguments to abstractions

New elements: The # sign

Once you have written and saved a Max program, it can be used as a subprogram (object) in some other Max program. The number of inlets and outlets that your object has is determined by how many inlets and outlets are present in your Max subprogram. In addition, your object can require typed-in arguments. To see an example of how this is done, open the file entitled "my-object". In the "my-object" window there is a "< #1" object. This means that when my-object is used as an object in another Max program, the value of "#1" will be supplied by a typed-in argument in the program that uses the object. (More than one typed-in argument can be required; additional arguments are referred to in the subprogram as "#2", "#3", etc.)

Notice that in the main Patcher window different my-object objects have different typed-in arguments. If you double-click on these objects, a window will open which shows the "#1" replaced by the typed-in argument.

Arguments like this can be very useful for making an object modifiable, and thus more general-purpose. Beware, however: If you do not type the correct number of arguments into your object it will not function.

In this example, my-object takes a bang (or anything else, which will get converted into a bang inside ) in its inlet. The likelihood that a corresponding bang will be sent out its outlet is determined by the typed-in argument, which specifies a percentage of probability. For example, each time the metro object at left sends a bang to the my-object object, the bang has an 80% likelihood of being passed on to the message box. The different metro objects cause the numbers in the message boxes to be sent at different rates, with different likelihoods determined by the my-object objects. The patcher object in this program treats its input as pitch information and transposes it up by a random number of octaves (from 3 to 7) before sending it to makenote and noteout.


TUTORIAL 38
Bitwise operations

New elements: &, |, >>, <<

The & and | objects (known as bitwise AND and bitwise OR) compare two integers in their binary (i.e., base two) form. These bitwise operators compare the individual bits of the binary representation of the numbers, noting which are the same and which are different.

The bitwise operators << and >> (known as "left shift" and "right shift") shift all bits in the binary representation of a number to the left or right by some specified number of bits. These are "low level" programming tasks, and are almost never indispensable in Max, but bitwise operations are occasionally a more computationally efficient means of dealing with numbers.

The bitwise operators & and | have two inlets which accept integers. (If floats are received, they will be converted to integers.) The number received in the left inlet is compared to the most recent number received in the right inlet (or specified as a typed-in argument).

The & object performs a sort of mathematical "intersection" of the bits which are nonzero. That is to say, only if both of the two numbers being compared have a nonzero bit in a certain place, the output will have a nonzero bit in that place. As an example, let's compare the number 7 to the number 5. The binary representations of these two numbers would be 111 and 101, respectively. Both numbers have a 1 in the first and third bit positions, but only one of them has a 1 in the second position. Therefore, the output will have a 1 in the first and third positions only (101), so the output will be 5.

The | object performs a sort of mathematical "union" of the bits which are nonzero. That is to say, if either of the two numbers being compared has a nonzero bit in a certain place, the output will have a nonzero bit in that place. As an example, let's compare the number 14 to the number 9. The binary representations of these two numbers would be 1110 and 1001, respectively. Since at least one of the numbers has a 1 in each of the four bit positions, the output will have a 1 in all four bit positions (1111). Therefore the output will be 15.

Experiment with the sliders above the & and | objects if you have any doubt about how these bitwise operators work. Note that an {& 1} object is a good means of determining if the number entering the left inlet is an odd number. (If it's an odd number, its rightmost bit must be 1, so both numbers being compared will have a 1 in the rightmost bit.)

The bitwise operators << and >> have two inlets which can receive integers. (If floats are received, they will be converted to integers.) The number received in the left inlet is shifted to the left or right by a certain number of bits. The most recent number received in the right inlet (or specified as a typed-in argument) determines the number of bits by which to shift. As an example, if the number 5 (binary 101) is input to a {<< 2} object, it will be shifted two bits to the left, resulting in binary 10100. Therefore the output will be 20 (as if the input had been multiplied by 4). If the number 5 is fed into a {>> 2} object, it will be shifted two bits to the right, resulting in binary 1. Therefore the output will be 1 (as if the input had been divided by 4). Note that bit shifting is a very efficient way to multipy or divide by powers of 2. The size of the shift (the number received in the right inlet or specified as an argument) determines the power of 2 by which the number received in the left inlet will be multiplied or divided.

The patcher object in this program is the same as the one in the last tutorial. It treats its input as pitch information and transposes it up by a random number of octaves (from 3 to 7) before sending it to makenote and noteout.

5