Home Page

Functions And Keywords Page

Alphabetical Index

Next Topic

Previous Topic

Sample Programs

Updates And Corrections


Output Functions

CAL gives us the chance to send information and data to the user and to the MIDI port. Along with these output functions we will also discuss the "format" function which converts variable data into text for sending to functions that places text in TRACK VIEW screen fields (and thus into the sequence file).
 
(message "text" and/or variables)
This function places a message on the status bar at the bottom of the screen. It doesn't interrupt the operation of the program, just displays the message. The message contents can be text in quotes or variables that will display the values in the form of numbers or any mixture of the two. There is an important thing to consider about sending messages to the status bar. While a "forEachEvent" loop is running, CAL has exclusive access to the status bar. However, outside this loop, anything CAL puts there can be overwritten by a Cakewalk internal function message like letting you know that an autosave is going on. Autosaves can happen during CAL programs. For that reason, you can't be assured the message will be there long enough for the user to read it. Needless to say, after the CAL program ends and supposing there are no autosaves, just pointing the mouse at a display field will replace the message with the description of what the cursor is pointing at. If the pointer happens to be over such a spot when CAL stops, any message will be immediately overwritten. This aside, the message is a good way to let the user know where the program is and that it is alive and running, less the user panic during a long loop and think the system has locked up. There is a price to pay for this function; time. It takes longer to run a CAL program if there is constant updating to the status bar. Consider this code fragment:
 
(forEachEvent
    (do
         (message "Processing Event # " (index))
         (if (so on and so on......
CAL will be sending a new message to the screen every time the "forEachEvent" starts a new pass. While this can be a great way of keeping the user transfixed on the status bar as numbers flicker by at a rate too fast to read, It also slows down the system by a fair amount. For small loops it can almost double the execution time of a program. You must weigh the costs and benefits of providing such an ongoing tally message. Remember to leave a space between closing quotes and variables because unlike some versions of BASIC, CAL doesn't format the display of variables and text for you.
 
(pause "text" and/or variables)
This is similar to the "message" function and like it you can display any combination of text and variable content. The difference is that "pause" halts execution of the CAL program and displays a dialog box in the middle of the screen containing the information the user provides in the function statement plus OK and CANCEL buttons. The user must click OK or hit the ENTER key to acknowledge the "pause" box before the program will continue. The user can also click the CANCEL button or hit the ESC key and abort the CAL program completely. By the way, hitting the ESC key at any time in the running of a CAL program will cause it to abort and exit. Besides displaying information critical to the user's decision to continue the program or cancel, the "pause" is a great troubleshooting tool for programmers. If a CAL program isn't acting quite right or if you want to verify the operation of some part of a program, you can place "pause" statements at key locations in the code to display the contents of some important variables and see if things are running as planned. Note this example:
 
(if (> something somevalue)
    (do
         (pause "Reached first test.  somevalue = " somevalue)
         (go on about your business.....
Here a "pause" has been placed at the "else" part of an "if" function to help verify if that function is being called. If it is, the "pause" tells the programmer where the program currently is and what the current value of variable "somevalue" is. After the programmer hits ENTER or clicks OK, the program goes on as if nothing ever happened. By the way, there is a limit of 128 characters for a "pause" message, so if you have allot of information to give out, it may require more than one "pause" box to deliver it.
 
(format "text" and/or variables)
Like the "message" and "pause" functions above, "format" takes any combination of text and variable values and generates an ASCII text string that can be passed to another function or assigned to a "string" variable. Take this example:
 
(int track 0)
(string name "No Note Has Been Found")
(forEachEvent
    (if (== Event.Kind NOTE)
         (do
              (= name (format "Note Number " Note.Key)
              (TrackName name track)
              (++ track)
         )
    )
)
What we have done here is declare an integer variable that we will use for track numbers and initialize it to 0 so it points to the first track (remember, we see tracks 1 through 256 and CAL sees them as tracks 0 through 255). Next we declare a string variable and initialize it to a default text string. Next we enter a "forEachEvent" loop and our "if" function filters out anything except notes. For each note we find, we use format to convert "Note.Key" into a number and combine it with the text string in quotes. The result is assigned to the string variable "name" and using the "TrackName" function, we place this text in the on-screen NAME field for track number "track". Now we increment "track" so that upon the next occurrence of a note it will point to the next track and we loop again. When the program stops, aside whatever else the program containing this fragment does, it will have named tracks for each note in the selected part of the sequence. If you wanted to eliminate the "track" variable all together, you could replace the first two statements after the "if" with this single statement:
 
(TrackName (format "Note Number " Note.Key) track)
 
As a part of this program, you would also likely end up cutting out all of the notes of each pitch and pasting them into the appropriately named tracks. This is useful with percussion tracks where it's convenient to separate each percussion instrument onto its own track so it can be manipulated independently.
 
(sendMIDI port channel kind data1 data2)
You can send a MIDI event during a CAL program with this function. Use "port" as the port number you want to send over. If "port" is set to -1, the function will send the message through all ports. The "chan" variable is the channel number and -1 will set the function to send over all channels. The "kind" constant is one of the recognized event types such as NOTE or CONTROL just like with the "insert" function. Use "data1" and "data2" for the information to be sent. Not all event kinds use both data bytes, and you must use the proper formatting of the data bytes for the event in question. Remember, MIDI data bytes must be between 0 and 127 except for type SYSX (system exclusive message). The SYSX message must be formatted by sending the number 240 for "data1" followed by whatever data is to be sent and then ending with the number 247 as the last byte. Check your synth MIDI implementation specs for details on how to use system exclusive messages with your instrument.
 
Next Topic Top Of Page