Now that you have your player dancing around the screen, let's add some sound effects! They can help to make an exciting animation sequence even better.
When you finish this chapter you'll be able to create some interesting sound effects to go along with the movement of your players. In addition, you'll learn how to maximize the execution speed of these sound routines.
I'm going to begin with a brief discussion of the SOUND statement. If you're already an expert on this, you may wish to skip ahead to "Chords" in this chapter. Otherwise, read on.
THE SOUND STATEMENT
Most Atari BASIC programs use the SOUND statement. It's a powerful statement because it enables you to control the pitch, distortion, and volume for each of four "voices."
Yes, Atari has four voices. Before we get into the details of the SOUND statement, let's consider what is meant by the term "voice." Think of a four-voice choir. In such a choir there are four separate groups of singers. Each group (or "voice") usually sings a separate melody (series of notes). Here are the names and ranges of the different voices in a four-voice choir:
Name of Voice
(Usually sings highest notes)
(Next to the highest notes)
(Next to the lowest notes)
Now back to the SOUND statement. In Atari BASIC the names of the four voices are 0, 1, 2, 3. (Again, notice that we start counting with "0" rather than "1.") Here's how you specify the voice, pitch, distortion, and loudness with a sound statement:
SOUND VOICE, PITCH, DISTORTION, VOLUME
"SOUND" is a key word such as "GOTO." The other items ("VOICE," "PITCH," "DISTORTION," and "VOLUME") are called parameters. Let's call them "palms" for short. In the above example they are variables. Before executing the above statement, you would need to set these variables to appropriate values.
Alternatively, you could use fixed numerical values (constants) or arithmetic expressions in place of those variables. For example, you might write:
SOUND 0,121,10,8 or SOUND 0,5*20+1,10,8
Both statements would cause voice 0 to play the note called "Middle C" since a value of 121="Middle C." (See page 58 in your ATARI BASIC REFERENCE MANUAL for numbers corresponding to the various musical pitches.)
The "10" in the above statement (the third parm) creates a "pure tone"--one with no distortion. Instead of "10," you can use other even numbers between 0 and 14 for various sound effects.
The fourth parm tells Atari how loud you want the sound to be. This value can be between 1 and 15. The higher the number, the louder the sound.
Before we go any further, let's experiment with a few simple SOUND statements. Get your Atari up and running. Then type in this next command just like it is--without a line number:
- When you press RETURN the command will immediately execute. What note will you hear?
Try it. Then enter this command:
- What happened?
The END command can come in handy when you decide you want some peace and quiet for a change.
Move the cursor back up to the SOUND command you entered earlier. (To move the cursor, hold down the CTRL key while pressing the arrow keys.) Try changing the distortion parameter (the third one). Enter various even numbers from 0 to 14. If you hear an effect you like, you may wish to make a note of the SOUND parms. In the same way, experiment with the volume parm by entering various numbers from 1 to 15.
A chord is a combination of musical pitches. It's easy to make chords with the Atari. You simple turn on more than one voice. Try this example. It will produce what musician's call a C-major chord:
One caution: if the total of all the volume parms exceeds 32, an unpleasant "clipped" tone will result.
- In the example above, did I observe this caution? What is the total of the volume parameters in the example?
POKING SOUND PARMS
Because of its ease of use, you may choose to use the SOUND command in your programs. But if you are coding an animation sequence for, say, a game or other simulation, then it may be better to poke sound parms directly into memory. SOUND statements execute more slowly than direct pokes.
Here's how you poke sound parms. To set the pitch of voice 0, simply poke a number into memory location 53760. To set the distortion and volume, first multiply the desired distortion number by 16 and add it to the value for volume. Then poke this one number into 53261.
For example, instead of writing SOUND 0,121,10,8, you would write:
(We poked 168 into 53761 because 16*10+8=168.)
- Now you try it. What POKE commands would be needed to replace this SOUND command?
So far I've shown you only two sound control registers: 53760 and 53761. Here is a more complete list:
|Location||Used to Control|
Pitch of voice 0
Distortion and volume of voice 0
Pitch of voice 1
Distortion and volume of voice 1
Pitch of voice 2
Distortion and volume of voice 2
Pitch of voice 3
Distortion and volume of voice 3
Pitch of all voices
- Look over these locations for a moment. What do the even numbered locations all control? The odd ones?
Now let's try some more experiments. Type in and try out this little sound demo program. Then read on.
Line 60: POKE S0,P0 This is where I specify what pitch to make the sound. S0 is the pitch control register for voice 0. (I initialized S0 to 53760 in the subroutine at line 1000.) P0 will be some value between 1 and 255. That's because you are asked to enter such a number at line 20.
Line 70: POKE DV0,D0 Here I turn on the distortion and volume of voice 0. (I initialized DV0 to 53762 in line 1000. 53762 is the distortion and volume control register for voice 0.) The value contained in D0 was calculated on line 35.
Line 35 D0=16*DIST+VOL Here I set D0 to the value that is derived from the desired distortion and volume. As I mentioned earlier, we do this by first multiplying the desired distortion by 16 and then adding the desired volume. You'll notice that DIST is set at line 30 in response to the prompt "ENTER DISTORTION." I initialized VOL to 8 in line 1000. I could have set it to any value from 0 to 15.
50 FOR P0=1 TO 255 STEP ST This is the beginning of a FOR/NEXT loop. Note the part that says "STEP ST." This command tells the computer how much to increment P0 at each pass through the loop. ST is set at line 30 in response to the prompt "ENTER GLIDING SPEED." If ST is set to, say, 5 then P0 will be set to 1 the first time through the loop, but 6 the second time (since 1+5=6).
- Suppose we set ST to 20. What will P0 equal on the second pass through the loop?
So the higher the value of ST, the bigger change in P0 at each pass through the loop. When ST is set to, say, 1, there will be a slow, smooth gliding pitch. When ST is set to progressively higher values, the sound changes in pitch rapidly and has a shorter duration (since it takes fewer times through the loop to reach 255).
Line 90: POKE DV0,0 This simply turns off the volume for voice 0. I do this so that the sound stops when control returns to the initial prompt at line 20. I could also have turned off the sound by poking a 0 into D0.
If you haven't already done so. I suggest you try experimenting with different values for distortion (DIST) and gliding speed (ST).
Also, you might want to modify the program to make it easier to hear the various sounds being produced. For example you might put a delay on the FOR/NEXT loop. You could do this by adding this line to the program:
75 FOR PAUSE=1 to 100:NEXT PAUSE
Another idea would be to print the value of P0 on the screen so you could observe the values being poked into S0.
USING A LOOP
Notice how I produced a gliding effect by putting the poke statements inside of a loop. In the same way you can put these poke statements within your animation loop. This way, you get a kind of gliding effect as your player or missile moves around the screen.
Let's try this with the moving legs routine we developed in the last chapter. What we will do is create some interesting "traveling sounds" for our player. Whenever the player moves we'll play some sounds. When the player stops, the sound will stop.
Perhaps you have some ideas about how this might be done. If so, you might want to experiment on your own before continuing.
Take a look at the program you entered in the previous chapter (which I called "LEGS.SAV"). One approach to making traveling sounds might be to add a "sound statement" to the "MOVELEGS" subroutine, which begins at line 30.
A simple way to do this would be to use the variable Z to set the pitch of the sound. As you will recall we used Z as a counter to control the display of various running images of our player. When Z was less than 4, we displayed "LEG1$". When Z was in the range of 4 through 6, we displayed "LEG2$," and so on. We added 1 to Z at the beginning of the MOVELEGS routine so that each time the routine was called, Z was greater than before. When Z reached 9, it was reset to 0.
Well, we can make Z do double work. Here's how we might do it with a sound statement:
- Based on what I've said so far, at what line might you insert this sound statement? What would the revised line look like?
Before you continue reading, you might want to revise the "LEGS" program by changing line 30 as we've just discussed.
Suppose you were to use Poke statements to create the sound. First, you might initialize these variables:
- What would S0 stand for? DV0?
- What would line 30 look like if you used Poke statements to create sound?
(Recall that to find the proper value for a distortion of 10 and a volume of 8, we multiply 16 times the distortion. This gives us 160. We then add the volume (8) to 160 to arrive at the DV0 value of 168.)
To give more variety to the sound, you might consider multiplying Z by some number. For example:
POKE S0,Z*TONE:POKE DV0,Z*TONE
With this code, different sounds will be produced depending on the value of TONE. For example if TONE=20 then the first time through the loop Z*TONE will equal 20; the second, 40; the third 60; and so on. The bigger the value in TONE the bigger the jump in pitch that will occur on each pass through the MOVELEGS routine.
At the end of this chapter is a program that will let you experiment with different "traveling sounds" for your player. It is similar to the LEGS program from the previous chapter. I have circled lines that need to be added or changed.
As you will probably notice, the addition of sound to the program slows down the player somewhat. That's one of the trade-offs. The more features you add--like sound, missile firing, collision detection, and so on, the bigger your loop becomes and the slower the animation. That's why I've stressed techniques that will help you maximize execution speed--such as poking values into sound registers and placing frequently executed code early in the program. Of course, machine language is probably the best--although the hardest--way to obtain fast player/missile action.*
Well, speaking of missiles, in our next chapter let's take a look at what they are and how to use them.
*When you're ready to dirty your hands with machine language, look for my new book on Player Missile Graphics in Assembly Language.
Return to Table of Contents | Previous Chapter | Next Chapter