Classic Computer Magazine Archive COMPUTE! ISSUE 94 / MARCH 1988 / PAGE 55

The Beginner's Page

C. Regena

Making Music With BASIC

I enjoy programming music on the computer. Since I am a former piano teacher, I have been able to use the computer for tutorial and drill programs. With the computer's exact tones and timing, I also use the computer to play written music so I can hear how it's supposed sound.

I would have liked to present a music program this month—however, sound commands are different among the various versions of BASIC. Each computer has its own special music features. So my advice is to read the manual that comes with your computer. Here, I'm going to review some of the more common BASIC sound commands. Unfortunately, because many early versions of BASIC do not support sound, these examples do not work on the Commodore 64 or Apple II family of computers.

Sounding Off

BEEP—available on the Amiga and IBM PC/PCjr—is probably the easiest command to use when you want to produce a sound. Some computers, such as the Apple II, Atari ST, and Commodore 128, use PRINT CHR$(7) to produce a bell or beep sound. The Atari eight-bit computers use PRINT CHR$(253). Whenever you want a short tone, such as a prompting tone, you can use BEEP. You may also use it for a game sound.

Most computers have a SOUND command, although the parameters vary from computer to computer. Here are some examples:

SOUND frequency, duration, volume, voice

SOUND voice, note, tone, loudness

Atari ST
voice, volunte, note, octave, duration

Commodore 128
SOUND voice frequency, duration

IBM PC and compatibles
SOUND frequency, duration

IBM PCjr with Cartridge BASIC
SOUND frequency, duration, volume, voice

The Commodore 128's SOUND command includes several optional parameters, such as waveform and pulse width, that are not listed above. In each case, parameters may be numeric constants or numeric variables, and there are certain limits for each parameter.

The Amiga and IBM SOUND statements use frequency numbers in cycles per second, or hertz (Hz), that produce a certain tone—frequencies with which many musicians are already familiar. For example, 440 Hz create what we hear as the note A.

Duration is a number often denoting the number of "clock ticks" that a particular sound lasts. You may need to experiment a little to see which numbers correspond to the timing you want. Because the eight-bit Atari SOUND command does not have a duration parameter, you must time the sound's duration yourself, using something like a FOR-NEXT loop. To turn the sound off with the Atari, use a SOUND command specifying a volume of 0.

Here is an example of how you can use SOUND to write music.

110 SOUND 523, 20
120 SOUND 659, 20
130 SOUND 784, 20
105 DURATION = 90
110 FOR I = 1 TO DIRATION : SOUND 0, 121, 10, 15, : NEXT I
115 FOR I = 1 TO 10 : NEXT I
120 FOR I = 1 TO DURATION : SOUND 0, 96, 10, 15, : NEXT I
125 FOR I = 1 TO 10 : NEXT I
130 FOR I = 1 TO DURATION : SOUND 0, 81, 10, 15 : NEXT
135 FOR I = 1 TO 10 : NEXT I
140 SOUND 0, 0, 0, 0
110 SOUND 1, 15, 1, 4, 20
120 SOUND 1, 15, 5, 4, 20
130 SOUND 1, 15, 8, 4, 20
110 SOUND 1, 4291, 20
120 SOUND 1, 5407, 20
130 SOUND 1, 6430, 20

The voice parameter is available on computers that have more than one voice—computers on which you can hear more than one note at a time. For example, here's how to play a chord using three voices:

110 SOUND 523, 30, 10, 0
120 SOUND 659, 30, 20, 1
130 SOUND 784, 30, 30, 2
105 FOR DURATION = 1 TO 90
110 SOUND 0, 121, 10, 15
120 SOUND 1, 96, 10, 15
130 SOUND 2, 81, 10, 15
150 SOUND 0, 0, 0, 0
160 SOUND 1, 0, 0, 0
170 SOUND 2, 0, 0, 0
110 SOUND 1, 15, 1, 4, 10
120 SOUND 2, 15, 5, 4, 20
130 SOUND 3, 15, 8, 4, 30
110 SOUND 1, 4291, 60
120 SOUND 2, 5407, 60
130 SOUND 3, 6430, 60
110 SOUND 523, 30, 10, 0
120 SOUND 659, 30, 10, 1
130 SOUND 784, 30, 10, 2

Playing Music

The IBM PC/PCjr and compatibles have a PLAY command. (The Commodore 128 has a PLAY statement as well, but the options are quite different.) This command can be used to play simple melodies using the letter names of notes—A, B, C, D, E, F, and G. As you get more experienced, you will find that there are more options in the PLAY command.

There are certain default values for the PLAY command, but you can change them by adding options. You may add a sharp to a note by using the character # or +, and you may add a flat by using the - character. The octave number can be specified with O, such as O3, indicating the middle-C range. (Make sure you use the letter O and not the number 0.) You may also change the octave by using > to go to the next higher octave and < to go to the next lower one.

The command PLAY "MN" plays normal notes (a slight pause between notes). The string "ML" indicates legato, or notes smoothly connected; "MS" plays staccato notes.

You use L to indicate the length of notes. Actually, you indicate what fraction the note should be. For example, L1 is a whole note, L2 is a half note, L4 is a quarter note, and L8 is an eighth note. The L option affects all the notes that follow. L8C plays C as an eighth note. A shorter form is to simply follow the note name with a number and not use the L. For example, C8 also indicates C as an eighth note.

P is used for a pause or rest, and you specify the length just as in the L option. P4 is a quarter-note rest.

There is a default tempo, but if you want to go slower, use T followed by the number of quarter notes per minute, such as T88. You may change the volume by using V followed by a number.

I like to use variables in the PLAY statement. When you use a numeric variable, you need to use the equal sign before the variable name and a semicolon after the variable name. For example, PLAY "O = H; GEC" plays the notes G, E, and C in the octave specified by the variable H.

You may define a string variable to be a series of notes and then use that string in the PLAY command. To execute a string variable, use "X". For example, PLAY "XA$;" plays the notes defined in string A$. Note that there is a semicolon after the string name. Here is an example of PLAY using variables. The octave is set using a FOR-NEXT loop, and the actual notes are stored in S$.

110 S$ = "CDEFGAB"
120 FOR C = 1 TO 6

130 PLAY "O = C; XS$; ; "
140 NEXT C

You may use string variables for storing musical phrases. For example, you might set up A$ for the first musical phrase, B$ for the second phrase, and C$ for the third phrase (have you ever heard of ABCA format?). This way, you can piece your music together. Here is a simple example:

110 A$ = "GGFE"
120 B$ = "EEFG"
130 C$ = "FEDC"
140 PLAY "XA$; XB$; XC$; XA$;"