The Atari computer has four independent voices that can vary in pitch by more than three octaves. The tone can vary from very pure to highly distorted. In addition, each voice has its own loudness level, completely independent of the television's volume setting.
SOUND Voice, Pitch, Distortion, Loudness
The first parameter Voice is simple. There are four voices or channels whose numbers range from 0-3. It takes a separate sound statement to activate each channel. Initially, at leas tin BASIC, they are all off at anytime, but anyone can be selectively turned off by setting Pitch, Distortion, and Loudness for that voice to all zeros.
Pitch can vary between 0 -255. The value'N' is used in a divide circuit. For every N pulses coming in, one pulse goes out. As N gets larger, the output pulses become less frequent and make a lower note. A value of 121 produces a middle C tone. A pitch of 60 produces a C tone one octave higher, and a pitch of 243 produces a C tone one octave lower. Pitch values around 3 approach the edge of human hearing and may not be audible on a television speaker that lacks a tweeter.
The Atari computer produces both pure and distorted tones. The term distortion is actually a misnomer. All of the sound waves on the Atari are square waves. Distortion doesn't occur because of a degradation of the wave form like in harmonic audio, but by selectively removing pulses from the waveform. A more appropriate term would be noise. Distortion values of 10 and 14 generate pure tones. Other even-numbered distortion values (0,2,4,6, and 12) introduce different amounts of noise into the pure tone. The quality of the sound depends on both the pitch and the distortion. Some combinations, mainly distortion 12, combine to produce an undistorted secondary tone with harmonic overtones.
Loudness is controlled by the fourth number in the SOUND statement. The value varies from 0 (silent) to 15 (loudest) and is fairly linear for a single voice. The apparent loudness is affected by pitch. High-pitched sounds seem quieter than low-pitched sounds. If you are working with multi-channels, the sum of all four channels should not exceed thirty-two or it will overmodulate the audio output. The sound produced tends to actually lose volume and assume a buzzing quality.
100 SOUND 0,121,10,10 110 FOR I=1 TO 225:NEXT I 120 SOUND 0,0,0,0
100 REM - PISTOL SOUND 110 FOR L=10 TO 4 STEP -0.25 120 SOUND 0,10,0,L 130 NEXT L 100 REM - BONK SOUND FOR KNOCKING OUT BRICK 110 FOR L=15 TO 0 STEP -0.5 120 SOUND 0,20,2,L 130 NEXT LIt is also possible to vary both the pitch and the volume simultaneously in a loop. The following example simulates the sound of a falling bomb. It begins with a high pitch and gradually changes to a low pitch, followed by the thumping sound of an explosion.
100 REM - FALLING OBJECT 110 FOR L=30 TO 200 STEP 3 120 SOUND 0,L,10,L/25 130 FOR K=1 TO L/10:NEXT K 140 NEXT L 150 SOUND 0,20,0,14 160 SOUND 1,255,10,15 170 FOR K=1 TO 150:NEXT K 180 SOUND 1,0,0,0
Most sound effects have to be placed in a larger loop with the graphics or player-missile commands, or motion will stop while the sound routine runs. The problem is that this method often alters the time delays and preset durations of the sound effects. Worse yet, the location of these routines within the program changes the result. This occurs because BASIC must search its line number list whenever it encounters a branch or GOTO instruction. Obviously, it finds line numbers at the beginning of the program before it finds line numbers near the end. The only real solution to the problem is to run your sound routines in the VBlank period, and this approach requires Machine language programming skills.
AUDF1 = $D000 AUDC1 = $D001
AUDF2 = $D002 AUDC2 = $D003
AUDF3 = $D004 AUDC3 = $D005
AUDF4 = 3D006 AUDC4 = $D007
Frequency values range from $00 to $FF. POKEY actually increments this number by one before sending it to its divide by "N" circuit. For every N pulses coming in, one pulse comes out. Thus, the higher the value of N, the lower the tone. The rate of the pulses depends on the POKEY clock.
The AUDC1-4 locations control both distortion and volume. The bit pattern is as follows:
The lower four bits control the volume level (0-15). Zero means no volume, while 15 means as loud as possible. The only constraint here is that the total volume for all four sound channels does not exceed thirty-two. Bit 4 is a volume-only control. Turning this bit on will force the speaker cone out. Trouble is that this by itself won't produce a tone since a tone is produced by repeatedly forcing the cone in and out rapidly. This bit can be useful to advanced sound programmers.
The upper three bits control the distortion. Distortion is produced by first dividing the clock value by the frequency, then masking the output using the various poly counters specified by the bit pattern. The result is finally divided by two. Poly counters or polynomial counters are actually shift registers that produce various degrees of distortion in random but repeatable sequences. Since they are repeatable, they are predictable and are useful for generating sound effects. In general, the tones become more regular or recognizable with fewer and lower poly counters masking the output. The 17bit poly counter is useful for white noise effects like a waterfall, while the 4-bit poly counter is useful for a motor sound.
BIT 7 6 5 0 0 0 5-bit, then 17-bit polys 0 0 1 5-bit poly only 0 1 0 5-bit, then 4-bit polys 0 1 1 5-bit poly only 1 0 0 17-bit poly only 1 0 1 no poly counters (pure tone) 1 1 0 4-bit poly only 1 1 1 oo poly counters (pure tone)
Bit Description 7 Makes the 17-bit poly counter into a 9-bit poly 6 Clock channel one with 1.79 MHz 5 Clock channel three with 1.79 MHz 4 join channels one and two (16 bit) 3 join channels three and four (16 bits) 2 Insert high pass filter into channel one, clocked by channel two 1 Insert high pass filter into channel two, clocked by channel four 0 Switch main clock base from 64 KHz to 15 KHzShifting the 17-bit poly counters to 9-bit poly counters by setting bit 7, will create more repeatable sound patterns rather than white noise-type patterns. Setting the channels to a higher clock frequency (setting bits 5 and 6), will produce higher tones. Likewise, setting the bit 7 from 64 KHz to 15 KHz will produce much lower tones.
If you couple two of the sound channels by setting either bits 3 or 4, you reduce the number of channels to two but gain increased tonal range. Normally, you get a five octave range using the eight bits of a single channel, but the combined 16-bit register increases the tonal range to nine octaves.
Sometimes you may encounter problems POKEing sounds in BASIC or in Machine language without initializing the sound registers. BASIC requires a null sound statement, i.e., SOUND 0,0,0,0. In Machine language you need to store a 0 at AUDCTL ($D208), and a 3 at SKCTL ($D20F).
We use the value of $FF for the note as a flag to indicate the tune is finished. While it could be used to conclude the piece, we use it to reset the pointers to the table so that the music repeats endlessly.
The lengths of the different notes is summarized in the table below:
NOTE JIFFIES Sixteenth 8 Eighth 15 Quarter 30 Half 60 Rest 60
SOUND3 LDA SEXTIME ;CHECK EXPLOSION TIMER FLAG BEQ .1 ;IF AT 0, NO SOUND DEC SEXTIME ;COUNTDOWN LSR ;DIVIDE BY 4 TO GET VOLUME 16-0 LSR STA AUDC4 ;TELL POKEY NEW SOUND VOLUME ;UPPER NIBBLE (DISTORTION = 0) LDA #$40 ;TONE .1 RTSLaser fire can be simulated by rapidly changing the frequency from a high pitch to a lower one in discontinuous jumps while using a distortion set at 6. This produces a more staccato sound than a smooth frequency transition. You can implement this effect by making the timer, SLTIME, short for Set Laser Timer, a function of the frequency. If Frequency = SLTIME * 16, then each time SLTIME is incremented, the tone will jump in increments of 16. Remember, the higher the N in the divide by N he lower the tone. The problem here is that the sound is much too short if to increment simply from 1 to 15. Therefore, a secondary loop delays each tonal jump by 4 cycles. The entire sound routine takes 60 jiffies rather than just 15 jiffies. The flowchart and code are below:
SOUND LDA SLTIME ;CHECK LASER TIMER FLAG BEQ .3 ;IF 0 EXIT CMP #$0F ;TIMER GOES FROM 1 TO 15 BNE .1 LDA #$00 ;TURN SOUND OFF STA AUDF1 STA AUDC1 RTS .1 LDA SLTIME1 ;CHECK DELAY TIMER BNE .2 ;IF NOT 0 COUNTDOWN TILL IT IS LDA DELAY1 ;GET NEW DELAY VALUE STA SLTIME1 ;STORE IT INC SLTIME ;INCREMENT MAIN TIMER ;(THIS IS ALSO OUR FREQUENCY VALUE) .2 DEC SLTIME1 ;OUR FREQUENCY VALUE ASL ;MULTIPLY BY 16 ASL ASL ASL STA AUDFI ;NEW TONE VALUE LDA #$86 ;DISTORTION 8, VOLUME 6 STA AUDC1 .3 RTS