SWEET TOOTS
Atari Logo sounds as good as it looks
by KEN HARMS
Atari Logo presents a full array of sound controls - a clear advantage over the generally mute Apple Logos. This article explores Logo sound and presents a sound generating program. You can use this program and your joystick to set up unending combinations of sounds and see the commands needed to put them into your programs.
The ATARI computer probably has the most advanced sound generators built into any home computer. Four voices, modulations for special effects, and easy-to-use commands give the ATARI user full sound support. When Atari was designing Logo, they discovered that many people preferred a wider range of frequencies and greater sound precision over the four-voice feature. Therefore, Logo combines the four voices into two expanded, more controllable voices. And just to be sure you are not disappointed, an automatic "duration" command was added.
Under Logo, these voices are controlled by the TOOT primitive. TOOT requires four inputs -- a voice (0 or 1), a frequency (a number between 14 and approximately 9000, which represents the cycles per second for the note) a volume (a number between 0 and 15), and a duration (a number betureen 1 and 255 giving the numer of sixtieths of a second which the sound will play). If you program in other Atari languages these will be familiar to you. One big difference is the frequency number - Logo gives you super precision and essentially unlimited range. The duration feature is new. No more timing loops! Instead, the Logo TOOT will play each note the exact time you give it while your program is off doing something else.
Like PILOT, Logo supports only the "pure" tones. Although it's a simple matter to develop new Logo commands to exercise the special effects, we'll leave that for another article. Logo compensates, however, by giving us a sound "envelope" command. Imagine a sound plotted on a graph with loudness on one axis and time on the other. The normal ATARI sounds are silent one instant, then full on (at whatever loudness you select) the next. They stay at full strength until turned off, which also occurs instantly. Most sounds in the world are not like this. A piano, for instance. starts at full loudness when the hammer strikes but rapidly tapers off to silence. Engineers call this "decay." Logo's SETENV command allows you to set simple decay rates independently for each of the two voices. Now, you can turn a computer sound into a piano sound with a single instruction!
Enough of the sales pitch! Let's look at the program. The "top level" procedure is START, naturally. It begins by clearing the screen with a "ClearText" command and follows by PRinting the headers. A series of MAKE commands sets up the variables we'll be using later. Logo uses two types of variables - "locals" which are defined in a procedure below the top level, and "globals" which are defined at the top level. Global variables operate in all procedures; locals don't. This means that a local variable name can be used in a second procedure and it won't have the value assigned to it previously. This is nice because you can then patch procedures together without worrying about conflicts. BUT, each time a subprocedure sets up a local variable, it uses up space. Note the MAKE "X comInand in START. That variable is used in nine sub-procedures. When it was a local variable, the program did a "garbage collection" (i.e. stopped to reclaim unneeded space) every four cycles. After I defined it as a global variable at the top level, the program ran 31 cycles between collections!
Drop down a line or two. The (PR [\ \ ]...command illustrates how to get Logo to print a formatted line. The back-slashes save a space, simple. To save exactly two spaces takes ingenuity -- the [ ] gives one space in addition to the one space which Logo forces between all words.
The (PR CHAR 28... line illustrates printing graphic characters on the screen. The CHAR command outputs the character with the ASCII (decimal) value of its input (in this case, 28 is an arrow). Sometimes, you can see that our Logo was developed by people accustomed to the constricted world of Apples (which don't allow you to use the graphics character sets). Oh well, there were some compatibility advantages, I guess.
START yells for TOOTS which promptly reads JOYstick 0 and puts that value in the variable "X. I find it difficult to know when to use quotes and when a colon before a variable name. It boils down to something like this -- when you want to put a value into a variable or to refer to it in general, use the quotes; when you want the value itself in the variable, use the colon. The explanation is in the manual but it requires careful reading.
The next line, IF :X = 6. . . , appears awkward. We didn't say IF JOY 0 = 6 because that doesn't seem to work. It is reasonable to expect that you could use the output of a primitive in an IF statement; but you can't. Use a MAKE earlier, and then the IF.
The same line uses a new command, CHANGE. The power of defining new commands is what Logo is all about. I defined CHANGE (it's listed down below) to take any input value (in this case,:POINTER), increment it by a second number (-1), but, if the new number is less than a minimum (0) make it equal the maximum (7). Conversely, if the new number is greater than the maximum (7), CHANGE makes it into the minimum. Neatest, you can feed the CHANGE any set of values, increments, minimums and maximums. The commmand is used in nearly all the sub-procedures to make sure values for the TOOT and SETENV commands stay in range.
If the JOYstick isn't pulled left or right (values 6 or 2), TOOTS falls through to one of eight subprocedures used to set each variable in the sound system. Most of these are simple procedures and very repetitive -- in fact, just type one and EDIT it to change the name and the variables.
The sub-procedures controlling frequency and duration (SETFRE0 and SETDUR0) illustrate the compound AND NOT operations to control program flow. That sequence says "IF the JOYstick is NOT pressed AND IF the value in variable X is 0, then . . ." It's easier than PILOT's linked conditionals, but placing the AND in front seems awkward. After learning the syntax, however, you can use it to link any number of conditions without typing AND over and over.
As a last tidbit for this column let's look over the CHANGE command. Notice that the "calling procedure," SETENV1 or whatever, gives the CHANGE command and a list of variables. In SETENV1, the first variable is :ENV1, the value to be put into the SETENV command. But when CHANGE starts, it calls that number :VAL. After operating on :VAL to produce :V, CHANGE outputs :V to the MAKE command in SETENV1 which then places it into the variable named "ENV1. Later, this value is used to set the envelope. This ability to pass variables without name conflicts is a powerful feature not found in BASIC or PILOT.
Next month we're in for a treat - a Player/Missile treatment to make PILOT's turtle visible!
Our old department "PILOT Your Atari" becomes LOGO/PILOT with this issue. Ken Harms remains as our Contributing Editor and frequent author in this department, but contributions from others interested in these languages are welcome.