Home Page

Functions And Keywords Page

Alphabetical Index

Next Topic

Previous Topic

Sample Programs

Updates And Corrections

Variables, Constants And Data Types

Data Types

There are five data types in CAL and each is of somewhat different use. The main difference between the types is the size of number it can hold (aside from the "string" type, which is for text). Each can be assigned to a variable of your own making, but which is best for what kind of variable depends on the use to which it will be put. Here's a rundown of the five types listed by the abbreviation you will use when referencing them in a CAL program. Note that they must be spelled exactly as you see them here in order for CAL to recognize them.

This stands for INTEGER and is the most common data type. It can hold a value from positive 32676 to negative 32767. You will use the "int" data type for most of your flags, loop counters, temporary buffers, and just about anything that doesn't involve large values. There is an important exception. If you are going to scale values, that is, take a number and multiply it by some factor and then divide it back down to a smaller number again, don't forget to take into account that the variable must be big enough to hold the temporary results of such scaling even if the final result would be well within the limits of an integer type.
A word is the same number of bits as an integer (16 bits) but goes from 0 to 65536. In other words, it is a positive only value. Note durations are stored as "word" values. Again, if you are going to be playing around with a duration value, you might want to declare a variable larger than this one just in case you send the value over the top at some point before you have a chance to correct it.
Now we have a 32-bit value that can range from roughly positive to negative 2 billion. Here's some room! This is a good variable to declare if you think you will be over-ranging an integer's value during calculations. Also a good variable type for working with note durations that might exceed the limits of a "word" during calculations.
This is the big daddy of variable types. A "double word" is an unsigned 32-bit value that can range from 0 to over 4 billion. Event times are stored as double words. There is no variable type bigger, but none is likely to be needed in that 4 billion ticks at 120 ticks per quarter note would run almost 9 million measures. Even Wagner would have had a hard time writing a score that long!
A string is a series of ASCII characters, or to put it simply, it is text. You can declare strings, build strings and send strings to some functions that use text, but unfortunately, you cannot input a string during the running of a CAL program.

Variables and Constants

There are several built-in variables and constants that CAL provides for our use. The most important for everyday use are the constants that correspond to the types of events in a sequence and the various parameters or data variables that belong to each one. The following list should be memorized if you plan on doing a lot of work in CAL. Again I must stress that you must use exactly the same spelling, capitalization and punctuation format as you see here in order to use them. Note that many CAL internal variables have a period between words, use capital letters in the middle of names and other odd things. As a useful convention, CAL constants are named with all capital letters so they are easy to spot.

Something to keep in mind; if you are writing code that will be using event constants that are only recognized by later versions of CAL, and you want the code to be backwards compatible with earlier versions, don't reference these constants by name but by the number they equal. If you use the name, the versions of CAL that don't support them will give you an error message and refuse to run. On the other hand, if you use the number, then CAL will simply use this number and dismiss the result without issuing an error. For example, suppose you wish to hunt for RPN events in a program that otherwise is just as useful in Cakewalk versions other than 6 or above. If you use a function like:

(if (== Event.Kind RPN)

CAL versions below 6 will go belly-up. On the other hand, if you write it like this:

(if (== Event.Kind 9)

Cal versions 6and above will still respond true if they find an RPN event and other versions of CAL will simply return results during the comparison that reflect they were either unsuccessful in finding an event that doesn't exist in any sequence that could be loaded into that version of Cakewalk, or they found something they don't know by name but never the less spotted by value.

CAL manages this variable and you should not attempt to assign it a new value. CAL gives it a value based on the specific event in the sequence currently being accessed during a "forEachEvent" loop. The specific number this variable holds is of little importance in that is usually isn't necessary to view or calculate with it. Just for the record, the number it holds will be 144 if the event is a note, 176 if the event is a controller, 224 if the event is a pitch wheel and so on. The reason you don't need to know this (except for compatibility issues as noted above) is that there are constants in CAL (see below) that equal those numbers and all we need to do is see if "Event.Kind" is equal to one or more of them. Note that the two words "Event" and "Kind" have a period and no spaces between them. This will be the case with allot of these CAL variables, so pay attention to this detail.
All events have this parameter. CAL fills it with the "raw" time of whatever event is being evaluated by the "forEachEvent" loop. It can also be assigned a value to change the time of an event or when inserting events. It is of type "dword" and so can be from 0 to over 4 billion.
All events also have a MIDI channel number as part of their data pattern. CAL puts that channel number in this variable when an event is being scanned by the "forEachEvent" loop. There are two things to remember about event channel assignments. First, this channel number will have no baring on what channel the event will be sent over if the track in which it resides has a channel assignment. The track channel will always override the event channel. If the track has no assigned channel, then the event channel determines the final channel it will be sent over. Second, even though we number the MIDI channels from 1 through 16, CAL numbers them one digit lower from 0 to 15. Therefore, if an event or track lists on the screen with a channel assignment of, say, 5, CAL will call it channel 4. This can be confusing, so keep alert to this quirk. As a side note, the same is true for track number assignments. We see tracks 1 through 256 and CAL sees them as 0 through 255. It's a binary thing.
This is one of the constants that allow us to test "Event.Kind" and also to assign the event within an "insert" function. Simply put, "NOTE" always equals the number 144, which is the CAL value for a note event.
This variable is one of the parameters of a "NOTE" event. It contains the pitch number of the note. It is of type "int" or integer and can range in value from 0 to 127. CAL fills in this variable with the pitch value whenever "Event.Kind" equals "NOTE", and you are free to work with, calculate with or even change this value if you want to alter the pitch of the note event.
Here is another parameter of a "NOTE" event. It is of type "int" and contains the velocity of the note. It can range in value from 0 to 127. Like Note.Key, CAL fills in the value for us whenever the current event is a NOTE and we are free to use and change it as we see fit in order to effect the note's velocity.
The duration of the note event is available to us through this variable. It is of type "word", can range from 0 to 65535 and is provided by CAL when the "Event.Kind" equals "NOTE". Changing this value moves the MIDI "note-off" message for that note back and forth in time relative to the "note-on" message.
This is the constant that holds the value 176 for a controller event. Like "NOTE", we use this constant to, among other things, test "Event.Kind" to see if the current event is a controller.
CAL sets this variable with the controller number value for events that are of the "CONTROL" kind. For example, a value of 7 corresponds to a volume controller event and 10 to a pan controller event. Changing this value changes the type of controller we are working with. This variable is of the "int" type and can range from 0 to 127.
The value or strength of a controller event is placed in this variable. It is an "int" and ranges from 0 to 127. Changing this value changes the amount of controller action for this event.
This constant identifies a pitch wheel event. It equals 224.
Here we have a variable that can be positive or negative. It is of type "int" and ranges from 8191 to -8192. When we have a "WHEEL" event, CAL fills in this variable with the pitch bend amount. We are free to change it as we see fit, but remember, be prepared to deal with either a positive or negative value.
This constant equals 192 and denotes a patch change event.
As you might guess, this is the patch number associated with the "PATCH" event. It is an "int" from 0 to 127.
The instrument bank can be found or changed in a PATCH event as well, and this variable contains the bank number. It can range from -1 to 16384 with -1 meaning "undefined".
The key aftertouch event is denoted by this constant of 160. Some synthesizers do not recognize this event, and still others will receive it but not send it.
CAL fills in this variable with the pitch number when it sees a "KEYAFT" event. Like "Note.Key", it is an "int" from 0 to 127 and denotes the pitch or in this case, the physical key number associated with the event.
CAL gives us this value when the "Event.Kind" is a "KEYAFT". Like the "Note.Vel" variable, it is of type "int" and denotes the strength of the aftertouch in values from 0 to 127.
This "Event.Kind" constant is equal to 208 and is the channel aftertouch event. Again, not all synthesizers use it.
The one variable associated with a Channel Aftertouch event holds the strength of the aftertouch. It is an "int" and can be from 0 to 127.

The following constants allow an "Event.Kind" test to locate these events in a sequence, and yet there are no provisions for viewing, accessing or changing the values associated with them. This makes their use rather limited to merely hunting for this type of event but not being able to do anything with it once it has been found except deleting them! Never the less, I list them here mostly because, for many of them, their existence as they relate to CAL is undocumented. These constants are only available in the versions of Cakewalk that support these data types as part of their feature package.

This constant equals 0 and is for a System Exclusive Bank message. Its existence is documented as a CAL constant even though it is impossible to access the data associated with the event. Such manipulations may be possible in versions 6 or above through the StudioWare feature depending on what you intend to do.
These events have the actual bytes to be sent as part of the event data. Again, none of this data is accessible. The constant value is 8.
Text events equal 1. They are sort of like notes you write to yourself and place in the sequence to serve as documentation or reminders. In some cases, you may want to enter lyrics this way instead of using a LYRIC event.
This constant equals 2. The data associated with this event is a single syllable or word that is to be sung at that instant in the song. These lyrics can be displayed during playback.
 An MCI command tells Windows to do something with one of its multimedia devices at that instant in the song. See the user manual or the Windows Multimedia Programmers' Reference for more details. Its constant value is 4.
This value of 3 corresponds to the "Audio" events that can be added to a sequence.
Expression events equal 5, and can be inserted into a sequence in the "STAFF" view. They guide a musician in the performance of a piece.
These events correspond to the Diminuendo and Crescendo marks available in the "STAFF" view. Their constant equals 6.
Chord names can be added to a sequence to assist guitar players following along with the music. These events are entered in the "STAFF" View. The constant equals 7.
The RPN or Registered Parameter Number, which equals 9, and NRPN or Non-Registered Parameter Number, which is 10, are events used by Cakewalk versions 6 and above as sort of controller event shorthand. Cakewalk gathers certain CONTROL events and merges them into RPN and NRPN events to save space among other reasons. Each RPN or NRPN event contains two numbers, a parameter value and a data value, each being a number between 0 and 16383. The fact that the values associated with these events are not available to CAL is a major pain. It is now impossible for a CAL program to, for example, interrogate or alter the pitch bend depth instructions in a sequence because the CONTROL events that effect this parameter are converted into a single RPN event and thus placed out of reach! If access to such controller events is important to you, such as the example of accessing pitch bend depth, then see the section called Tips, Techniques And Work-Arounds under the sub-heading Preventing CAL From Gathering Controller Events for a way around this problem.
If you want to keep the RPN event function and still want a convenient way of changing pitch bend depth from the Event List view, the following chart should prove valuable. To change the bend depth for most General MIDI compatible synthesizers, you would issue 3 controller events. The first would be controller number 100 with a value of 0. The second would be controller number 101 also with a value of 0, and the last would be controller number 6 with a value corresponding to the number of semi tones you want the bend range to have. Some instruments also require a forth controller event to terminate the string. It is controller 38 with a value of 0. The RPN event that does the same thing will have two digits associated with it. The first will be a parameter value of 0 and the second will be a data value number equal to the number of semi tones of bend depth multiplied by 128. For example, if you wanted to set the bend depth to plus or minus an octave, or 12 semi tones, the controller sequence would be:
Controller 100, value of 0
Controller 101, value of 0
Controller 6, value of 12
Controller 38, value of 0 (not always needed)

The same job would be done by the single RPN event having a parameter value of 0 and a data value of 1536. The following chart outlines all RPN data values for bend depth ranges from +/- 1 to +/- 24 semi tones. In all cases, the RPN parameter value is 0.

Bend Depth

(+/- semi tones)

RPN Data Value

(Depth X 128)

1 128
2 256
3 384
4 512
5 640
6 768
7 896
8 1024
9 1152
10 1280
11 1408
12 1536
13 1664
14 1792
15 1920
16 2048
17 2176
18 2304
19 2432
20 2560
21 2688
22 2816
23 2944
24 3072


These next constants have to do with timekeeping and CAL version detection.

This constant is the number of ticks per quarter note the user has selected for keeping time in Cakewalk. The default value Cakewalk provides when it is installed is 120 ticks per quarter note, but can be changed by the user. Because CAL sees time as the number of ticks from the start of the sequence (referred to as "raw" time) and humans see it as the number of measures, beats and ticks in the composition (referred to as M:B:T time), this value is an important factor in equations that must take both time keeping systems into account.
This variable corresponds to the position of the bar cursor in the sequence and holds the value visible in the "NOW" time window on the screen. It's the place where playback would start if the "PLAY" button were clicked on the front panel. It has little use in CAL. There are some strange limitations to the size of numbers this marker variable can hold. Even though it is 32 bits wide, assigning it a number close to that limit can crash some Cakewalk versions earlier than 7. See the section called Tips, Techniques And Work-Arounds under the sub-heading Hidden Traps In The CAL Editor for more information.
This variable is the same as the "From" marker in the Cakewalk front panel. It is the starting point for the "selected" part of a sequence. This value can be changed during the running of a CAL program any place OTHER THAN within a "forEachEvent" loop. This makes sense in that the "forEachEvent" loop operates on events starting at the time stored in "From" and so cannot alter its own starting point. "From" is of type "dword" and so can range from 0 to over 4 billion. If, during a CAL program, you change the value stored in "From" before a "forEachEvent" loop, the loop will start at this new location in the sequence. Thus, you can make the assigning of this variable, and so the starting point of the loop, subject to conditions or calculation results within the program itself. This can be very handy! Keep in mind, however, that just as Cakewalk will not allow you to assign "From" a number larger than the value stored in "Thru", neither will CAL. The offending value will be automatically reassigned to correct the condition.
"Thru" is the same as "From" except, of course, being the end marker of the selected part of a sequence. Everything said above about "From" applies to "Thru".
The final marker variable is really a "read-only" variable. It holds the location of the end of the sequence and thus cannot be changed from within a CAL program.
This constant contains the version of CAL currently running on the user's computer. It's undocumented, but useful as an error checker. A test should be made at the start of every CAL program to make sure the user has the proper version of CAL to run the program. This is most conveniently done using the "include" function to run a small CAL program called NEED20.CAL from within any larger program to check this "VERSION" value and abort if it shows that an incompatible version of CAL is running. If you are creating CAL programs that can only run on higher versions of CAL, you can edit this "NEED20.CAL" program to test for, say, CAL version 3, 4 or so on instead of 2. After the edit, save the new program under a name like "NEED60.CAL" or whatever.
This is a constant that holds a value of 1. This constant is used in functions that require a Boolean value of yes or no in order to signify the selecting or de-selecting of some parameter. For example, if you are setting up an "EditCopy" function, there are arguments that correspond to the check boxes used to set up the EDIT menu COPY command. In order to translate to CAL the act of checking or unchecking these boxes, the corresponding variables will be given a value of 1 for checked or 0 for unchecked. It is allowable to substitute the constants TRUE and FALSE for 1 and 0 in these arguments.
This constant is the other side of the TRUE/FALSE coin. It holds a value of 0. See the definition for TRUE above for details.
Next Topic Top Of Page