There are two basic ways to use the ATARI Computer sound system: static and dynamic. Static sound generation is the simpler of the two; the program sets a few sound generators, turns to other activities for a while, and then turns them off. Dynamic sound generation is more difficult; the computer must continuously update the sound generators during program execution. For example:
|Static Sound||Dynamic Sound|
|SOUND 0,120,8,8|| FOR X=0 TO 255
Static sound is normally limited to beeps, clicks, and buzzes. There are exceptions. Two examples are the programs given as special effects in the sections on high-pass filters and 16 bit sound. Another way to obtain interesting effects is to use interference, as in this example:
SOUND 0,255,10,8 SOUND 1,254,10,8
The strange effect is a result of closely phased peaks and valleys. Examine Figure 7-11. It shows two channels independently running sine waves at slightly different frequencies, and their sum. The sum curve shows the strange interference pattern created when these two channels are added.
Figure 7-11 Two sine waves at different frequencies and their sum
Figure 7-11 shows that at some points in time the waves are assisting each other, and at other points, they interfere with each other. Adding the volumes of two waves whose peaks coincide will yield a wave with twice the strength or volume. Similarly adding the volumes of two waves while one is at maximum and the other is at minimum will result in a cancellation of both of them. On the graph of the sum curve, we can see this effect. Toward the ends of the graph, volume increases since both channels' peaks and valleys are close together, almost doubling the sound. Toward the middle of the graph, the waves oppose each other and the resulting wave is flat. An interesting project might be writing a program to plot interaction patterns of 2, 3, and 4 channels as in Figure 7-11. You might discover some unique sounds.
The slighter the difference in frequency between the two channels, the longer the pattern of repetition. To understand this, draw some graphs similar to Figure 7-11 and study the interaction. As an example, try the following statements:
SOUND 0,255,10,8 SOUND 1,254,10,8 SOUND 1,253,10,8 SOUND 1,252,10,8
As the difference in frequency grows, the period of repetition decreases.
More complex sound effects normally require the use of dynamic sound techniques. Three methods of dynamic sound generation are available to the ATARI 400/800 programmer: sound in BASIC, 60-Hz interrupt sound, and sound in machine code.
BASIC is somewhat limited in its handling of sound generation. As you may have noticed, the SOUND statement kills any special AUDCTL setting. This problem can be avoided by poking values directly into the sound registers rather than using the SOUND statement.
In addition, BASIC is limited on account of its speed. If the program is not completely dedicated to sound generation, there is seldom enough processor time to do more than static sound or choppy dynamic sound. The only alternative is to temporarily halt all other processing while generating sound.
Another problem can occur when using the computer to play music on more than one channel. If all four channels are used, the time separation between the first sound statement and the fourth can be substantial enough to make a noticeable delay between the different channels.
The following program presents a solution to this problem:
CH7PRG1.BAS 10 SOUND 0,0,0,0:DIM SIMUL$(16) 20 RESTORE 9999:X=1 25 READ Q:IF Q<>-1 THEN SIMUL$(X)=CHR$(Q):X=X+1:GOTO 25 27 RESTORE 100 30 READ F1,C1,F2,C2,F3,C3,F4,C4 40 IF F1=-1 THEN END 50 X=USR(ADR(SIMUL$),F1,C1,F2,C2,F3,C3,F4,C4) 55 FOR X=0 TO 150:NEXT X 60 GOTO 30 100 DATA 182,168,0,0,0,0,0,0 110 DATA 162,168,182,166,0,0,0,0 120 DATA 144,168,162,166,35,166,0,0 130 DATA 128,168,144,166,40,166,35,166 140 DATA 121,168,128,166,45,166,40,166 150 DATA 108,168,121,166,47,166,45,166 160 DATA 96,168,108,166,53,166,47,166 170 DATA 91,168,96,166,60,166,53,166 999 DATA -1,0,0,0,0,0,0,0 9000 REM 9010 REM 9020 REM this data contains the machine lang. program, 9030 REM and is read into SIMUL$ 9999 DATA 104,133,203,162,0,104,104,157,0,210,232,228,203,208,246,96,-1
In this program, SIMUL$ is a tiny machine language program that pokes all four sound channels very quickly. A BASIC program using SIMUL$ can rapidly manipulate all four channels. Any program can call SIMUL$ by putting the sound register values inside the USR function in line 50 of the demonstration program. The parameters should be ordered as shown, with the control register value following the frequency register value, and repeating this ordering one to four times, once for each sound channel to be set.
As a speed consideration as well as a convenience, SIMUL$ allows you to specify sound for less than four channels; i.e., 1, 2, and 3 or 1 and 2, or just channel 1. Simply don't put the unused parameters inside the USR function.
SIMUL$ offers another distinct advantage to the BASIC programmer. As mentioned earlier, the AUDCTL register is reset upon execution of any SOUND statement in BASIC. However, using SIMUL$, no SOUND statements are executed, and thus the AUDCTL setting is retained.
There is another, but impractical, method of sound generation in BASIC. This method uses the volume-only bit of any of the four audio control registers. Type in and run the following program:
SOUND 0,0,0,0 10 POKE 53761,16:POKE 53761,31:GOTO 10
This program sets the volume-only bit in channel 1 and modulates the volume from 0 to 15 as fast as BASIC can. This program uses all of the processing time available to BASIC, yet it produces only a low buzz.
This technique is probably the most versatile and practical of all methods available to the ATARI Computer programmer.
Precisely every 60th of a second, the computer hardware automatically generates an interrupt. When this happens, the computer temporarily leaves the mainline program, (the program running on the system; i.e., BASIC, STAR RAIDERS™). It then executes an interrupt service routine, which is a small routine designed specifically for servicing these interrupts. When the interrupt service routine finishes, it executes a special machine language instruction that restores the computer to the interrupted program. This all occurs in such a way (if done properly) that the program executing is not affected, and in fact has no idea that it ever stopped!
The interrupt service routine currently resident on the ATARI 400/800 Computer simply maintains timers, translates controller information, and performs miscellaneous other chores requiring regular attention.
Before the interrupt service routine returns to the mainline program, it can be made to execute any user routine; i.e., your sound generation routine. This is ideal for sound generation since the timing is precisely controlled, and especially since another program can be executing without paying heed to the sound generator. Even more impressive is its versatility. Because it is a machine language program, the interrupt sound program will lend itself equally well to a mainline program written in any language - BASIC, assembler, FORTH, PASCAL. In fact, the sound generator will require few, if any, modifications to work with another program or even another language.
A table-driven routine offers maximum flexibility and simplicity for such a purpose. “Table-driven” refers to a type of program that accesses data tables in memory for its information. In the case of the sound generator, the data tables would contain the frequency values and possibly the audio control register values. The routine would simply read the next entries in the data table, and put them into their respective audio registers. Using this method, notes could change as often as 60 times per second, fast enough for most applications.
Once such a program has been written and placed in memory (say, at location $600), you need to install it as a part of the 60-Hz interrupt service routine. This is accomplished by a method known as vector stealing.
Memory locations $224,$225 contain the address of a small routine called XITVBL (eXIT Vertical BLank Interrupt service routine). XITVBL is designed to be executed after all 60-Hz interrupt processing is complete, restoring the computer to the mainline program as previously discussed.
The procedure to install your sound routine is as follows:
Steps 3-6 are all required to change the value of $224,$225 without error. The routine called is SETVBV (SET Vertical Blank Vectors), which will simply put the address of your routine into locations $224,$225. Once installed, the system will work as follows when an interrupt occurs:
If you do not wish to implement such a program yourself, there is one available from the Atari Program Exchange. The package is called INSOMNIA (Interrupt Sound Initializer/Alterer). It allows creation and modification of sound data while you listen. It is accompanied by an interrupt sound generator that is table driven and compatible with any language.