PLAY A CHORD Now that we have learned to produce a note with proper decay, a chord can be built using the other two channels. Move the cursor back up to TONE PER FINE and over to the right to channel B. Type 193 for an E-note. Move the cursor to channel C and type 163 for a G-note. Move the cursor down to ENABLE and set it to 56, which enables all three channels for tone only. Move the cursor down to AMPLITUDE in the ALL column and type 16 for variable level. This will set the amplitude of all three channels to 16. Type P for play. PLAY TWO CHORDS The Sound Utility also allows you to play six notes simultaneously by setting three notes on one screen and three on a second screen. The three notes you have just played appear on the first screen. Type C and a new screen will appear. Note that the parameters are cleared to zeros. Type C again to return to the first screen. The three notes are still there. 2-15 The screens are oriented to the speakers through which the sounds are played. The chord just played was created for SPEAKER: 1. This designation appears in the upper left hand corner. Type C and note that SPEAKER: 2, in the upper right hand corner, replaced SPEAKER: 1 The next three notes are also C, E, and G notes but on a lower octave. These note values include coarse tune values. Type the values as shown. MAX CHANNEL VAL ALL A B C TONE PER FINE 255 0 209 7 140 TONE PER COARSE 15 0 3 3 2 NOISE PERIOD 31 0 ENABLE 63 56 AMPLITUDE 16 0 (FIX = 0-15/VAR = 16) ENVL PER FINE 255 0 ENVL PER COARSE 255 20 ENVL SHAPE 15 0 Type P for play and listen to the deeper sound of this chord. Now, type B for both speakers and listen to six notes simultaneously. Note that both speaker designations appear at the top of the screen. If the sounds were continuous, R for reset would stop them. Since the notes decay automatically, a reset is not necessary. 3-1 PROGRAMMING Whether you compose music, dialogue or design special effects, your masterpieces are unfinished until they are arranged in a production. What could be more original than to enhance one of your own programs with sounds of your own creation? The Introduction to this manual compared MOCKINGBOARD to the telephone of a friend you wish to call. MOCKINGBDARD may be reached with the appropriate "area code" and "phone number." The "area code" locates MOCKINGBOARD in one of the input/output slots in the back of the Apple. This means that MOCKINGBOARD may be placed in any slot, except 0. The Apple II Reference Manual states that this slot is reserved for RAM, ROM or interface expansion. The sound chip and speech chip do not speak the same language. Therefore, instructions to any chip must go through a translator. This translator is called the 6522 Versatile Interface Adapter or just 6522. There are only four instructions for the sound chips and one for the speech chips which must be translated. THE SOUND CHIPS The Sound Utility program demonstrated all the parameters needed to produce a sound. There are 16 in all: six Tone Period (Fine and Coarse), one Noise Period, one Enable, three Amplitude, two Envelope Period (Fine and Coarse), one Envelope Shape and two unused. When all 16 parameter values are received by the sound chip via the 6522, sound is generated. With the Sound Utility, the cursor is positioned over one of the 14 parameters and a value is typed. For Example, if we wish to set the Tone Period (Fine Tune) for channel A to 145, the cursor is moved to the first row, column A, and 145 is typed in. A similar location called a register address, is also designated on the sound chip for this parameter. Each parameter has its own register address numbered 0 to 15. Table 3-1 shows each parameter and its associated register address. A chart of all registers and their descriptions is provided in Appendix B, page A-3. 3-2 REGISTER ADDRESS SOUND PARAMETERS 0 Tone Period Fine Tune for channel A 1 Tone Period Coarse Tune for channel A 2 Tone Period Fine Tune for channel B 3 Tone Period Coarse Tune for channel B 4 Tone Period Fine Tune for channel C 5 Tone Period Coarse Tune for channel C 6 Noise Period 7 Enable 8 Amplitude for channel A 9 Amplitude for channel B 10 Amplitude for channel C 11 Envelope Period Fine Tune 12 Envelope Period Coarse Tune 13 Envelope Shape 14 & 15 Unused Table 3-1 Sound Chip Registers HOW THE SOUND PARAMETERS ARE SET ON THE CHIP A sample program called TABLE Access Routine, provided on the demonstration disk, illustrates one method of setting sound parameters on the chip. Let's use our earlier example and set the Tone Period Fine Tune for channel A to 145. Table 3-1 indicates that Tone Period Fine Tune for channel A is register address 0. The Table Access Routine is designed to send values to all sixteen registers sequentially, beginning with 0. It first sends MOCKINGBOARD the register address (0) of the data to be sent. Next, it sends MOCKINGBOARD the data (145). The Table Access Routine continues this process until all sixteen register addresses have been sent data. If a parameter does not need to be set, you should send a zero to that register address. 3-3 All information to MOCKINGBOARD flows on one of two direct lines. The first line sends only register addresses and data. But MOCKINGBOARD can not distinguish addresses from data, because the addresses and data are all numerical values. The second line is used to send an instruction identifying what was sent on the other line. Let's use our example to clarify the information flow to MOCKINGBOARD. When 0 is sent on the first line, the second line sends instructions to MOCKINGBOARD that the 0 is a register address. Next, 145 is sent on the first line and the instruction to MOCKINGBOARD that 145 is data, is sent on the second line. The two lines work almost simultaneously. In fact, information may be sent to MOCKINGBOARD continuously, because it flows in only one direction. A separate program called PRIMary Routines (also provided on the disk), contains the four subroutines to handle the instructions to MOCKINGBOARD. They are: INIT subroutine. Initializes or primes MOCKINGBOARD to receive information. The initialization process is done once at the beginning of a program. MOCKINGBOARD must be initialized or sound parameter s sent to it will be ignored. Your program will continue, but no sound will be generated. MOCKINGBOARD does not have to be initialized again during the same program, unless the computer is shut off or the system is reset. LATCH subroutine. Tells MOCKINGBOARD that a register address is being sent to it. WRITE subroutine. Tells MOCKINGBOARD that data (a parameter value) is being sent. RESET subroutine. Clears all sixteen registers to zeros. As a precautionary measure, the registers should be RESET at the start of a program to avoid generation of unexpected sounds. These two programs, Table Access Routine and Primary Routines, work together to send the proper instructions and data to MOCKINGBOARD. The Table Access Routine orchestrates the task. While Primary Routines send instructions to MOCKINGBOARD, it is the Table Access Routine which selects the appropriate instruction to send. 3-4 To understand the principles behind these two programs, let's examine what happens in a mailroom. The parallel between a mailroom and MOCKINGBOARD will clarify how MOCKINGBOARD transfers data for sound generation. mail The mail truck arrives each day at 9.00 am. The mail clerk is prepared to receive the mail at this time each day. MOCKINGBOARD CALL the INIT routine at the beginning of your program. This routine prepares MOCKINGBOARD to receive information mail. The mail is sorted into piles for each mail slot. Each mail slot belongs to a particular individual and is appropriately labelled. MOCKINGBOARD Each sound is described by I 6 sound parameters and those parameters correspond to a particular register on the sound chip. The registers, numbered from 0 to 15, correspond to the mail slots, Each sound parameter is assigned to a register just as a name on the mail associates it with a particular mail slot. The sound parameters are predetermined and stored in memory. mail Before the new mail is placed into the mail slots, each slot is checked to make sure it is empty. MOCKINGBOARD The Table Access Routine RESETs (or clears) all 16 registers as a precaution against unwanted sounds. MAIL The mail is sorted in mail slot order and the slot door for the first pile is opened. MOCKINGBOARD The Table Access Routine sends the register address to MOCKINGBOARD. It also tells the subroutine LATCH (Primary Routines) to send instructions to MOCKINGBOARD to "latch" onto that register so the data will know where to go. MAIL The first pile is retrieved and placed in the opened mail slot. 3-5 MOCKINGBOARD The Table Access Routine retrieves the data for the first register from its place in memory and sends it to MOCKINGBOARD. It also tells the subroutine, WRITE (Primary Routines), to instruct MOCKINGBOARD to place that data into the latched register. mail Each remaining pile of mail is processed in the same manner. The distribution of mail is completed when all the piles have been placed in their respective slots. MOCKINGBOARD The next register is latched and the corresponding data is written to that register. When al 16 registers are filled, MOCKINGBOARD will generate a sound and send it to the speakers. LATCH and WRITE are similar to the standard BASIC programming command, POKE. The address is identified first, then the data to be poked. The data retrieval method used in the Table Access Routine is comparable to the standard programming commands, DATA and READ, where data is retrieved and read into the program for processing. SUMMARY OF PRIMARY ROUTINES AND TABLE ACCESS ROUTINE The Primary Routines consist of four subroutines called INIT, LATCH, WRITE, and RESET. Each subroutine has a specific function in the transmission of instructions to MOCKINGBOARD. These subroutines utilize the instruction line to transmit information to MOCKINGBOARD. Each tells MOCKINGBOARD what to do with the information being transmitted on the address/data line. The Table Access Routine coordinates the flow of information to MOCKINGBOARD by sending information on the address/data line and selecting the appropriate Primary Routines instruction for the address/data sent. As the name of the line indicates, only a register address or data is transmitted on this line. The Table Access Routine also retrieves the data from a memory location where sound parameters are stored. The data can be POKEd into memory at a specific location by READing the data into your program with a Data statement. The data may be stored in any unused memory location, but the Table Access Routine must be told its location. 3-6 The data is POKEd in register address order. Conveniently, the order is sequential. Therefore, the data for the first register is POKEd into the first address of the memory location, then the data for the second register is POKEd into the next consecutive address and so forth until all sixteen have been POKEd. If more than one set of sound parameters are needed, the next set of parameters may be stored immediately following the first set. When the second sound is to be played, the Table Access Routine must know where this set of sound parameters begin (start of first sound plus 16), The two sound chips on MOCKINGBOARD may be accessed separately. Each chip uses the same method of instruction and address/data transmission. At the beginning of this section, we mentioned that the only difference between the two sound chips was that each had its own "phone number." Therefore, both the Primary Routines and Table Access Routines have duplicate sets of code to access each separately. Included in the Primary Routines is another set of four subroutines called INIT2, LATCH2, WRITE2 and RESET2. The Table Access Routine also has a duplicate set of code labelled in a similar manner. SIREN SOUND EFFECT Type this program right on your demonstration disk. (You may leave out the REM (remark) statement, as it serves only to explain the flow of the program.) It is the first sound of a siren. If you are using a fresh disk, you must copy the PRIMary Routines and the TABLE Access Routine onto your disk and run them either before you run the program or within the program itself. (Delete last line of TABLE.) Also, MOCKINGBOARD must be initialized at the beginning, with a CALL 36864 (INIT) and CALL 36908 (INIT2). 5 REM ***DATA FOR SOUND; 145=FINE TUNE; 62=ENABLE; 15=AMPLITUDE 10 DATA 145,0,0,0,0,0,0,62,15,0,0,0,0,0,0,0 18 REM ***STARTING ADDRESS FOR STORAGE OF SOUND DATA 20 A=33024 3-7 25 REM ***READ AND STORE ALL VALUES FOR SOUND IN SEQUENTIAL ORDER STARTING AT LOCATION 33024 ***WHEN X=0, IT IS ADDED TO "A" WHICH IS 33024 TO EQUAL 33024. PLACE THE FIRST DATA FROM LINE 10, 145, INTO LOCATION 33024 30 FOR X=0 TO 15:READ D 40 POKE A+X,D 50 NEXT 75 REM ***USE TEMPORARY LOCATIONS 8 AND 9 TO POINT TO THE STARTING ADDRESS OF SOUND, 33024; CALL TABLE ACCESS ROUTINE TO SEND DATA TO MOCKINGBOARD AND PLAY THE SOUND 80 POKE 8,0:POKE 9,129:CALL 32768 85 REM ***USE DELAY LOOK FOR DURATION OF SOUND 90 FOR T=1 TO 342: NEXT T 145 REM ***CALL RESET TO STOP THE SOUND AND CLEAR REGISTERS 150 CALL 36897 160 END Save and run this program. Lines 5 through 50 place the set of sound parameters sequentially in memory, starting at 33024. Line 80 plays the sound for the period of time designated in line 90. Line 150 stops the sound with a CALL TO RESET. Now, let's add the second part of the siren sound 15 DATA 86,1,0,0,0,0,0,62,15,0,0,0,0,0,0,0 30 FOR X=0 TO 31: READ D 100 POKE 8,16:POKE 9,129: CALL 32768 120 FOR T=1 TO 342:NEXT T Line 15 is the second sound data and line 30 is changed to READ 16 more data. Line 100 plays the second sound. The temporary locations, 8 and 9, 3-8 are changed to point to the second set of sound data. The Table Access Routine is CALLed to send it to MOCKINGBOARD. Line 120 allows us to hear this sound for a given period of time. Save and run this program, Did you hear a siren? This program demonstrates two manipulation techniques, duration (lines 90 and I 20) and sequencing of two or more sounds (lines 80 through 120). A delay loop follows each note because, otherwise, the notes would alternate too quickly for you to hear them. The only difference between the two notes is the tone period registers for channel A, Refer to the chart on musical notes, Appendix E, page A-6. The first note is a middle or 4th octave A with a Tone Period value of 145. The second note falls between F# and G in the third octave; it has a Tone Period value of 342 or a coarse tune of 1 and fine tune of 86. The changes necessary to create these two tones involve only two registers. Therefore, load the base parameters needed to create the notes and change the Tone Period registers as required to alter the note. In addition, lines 70 and l40 places the sound generation in a loop so that the siren will play five times. Here's how to do it. l0 DATA 0,0,0,0,0,0,0,62,l5,0,0,0,0,0,0,0 20 A=33M4 30 FOR X = 0 TO l5: READ D 40 POKE A+X,D 50 NEXT 55 REM ***SET THE POINTERS TO POINT TO LOCATION 33024 60 POKE 8,0: POKE 9,129 65 REM ***REPEAT THE SIEN SEQUENCE FIVE TIMES 70 FOR Z = 1 TO 5 75 REM ***PLAY THE FIRST SOUND 80 POKE 33024,145: P0KE 33025,0:CALL 32768 90 FOR T = 1 TO 342: NEXT T 3-9 95 REM ***PLAY THE SECOND SOUND. CHANGE FIRST REGISTER TO 86 AND SECOND REGISTER TO 1. SINCE TONE PERIOD =342, FINE TUNE = 342-INT(342/256)*256 AND COARSE TUNE TUNE=INT(342/256) 100 POKE 33024,86:POKE 33025,1:CALL 32768 120 FOR T=1 TO 342:NEXT T 135 REM ***IF Z IS LESS THAN 5, PLAY THE SEQUENCE AGAIN 140 NEXT 145 REM ***SHUT THE SOUND OFF 150 CALL 36897 160 END Now, try this same program, but this time make use of the two sound chips and both speakers. The Primary Routines and Table Access Routine have secondary sets of routines to produce sounds out of the second speaker with the other sound chip. You will be able to play one tone through the left speaker and the other through the right. The Table Access Routine uses a temporary memory location to store the beginning address of the sound to be played back. This stored address is referred to as a "pointer" because it points to where the sound data begins. We have already used locations 8 and 9, in our siren example, to store the address for the first sound chip. The second sound chip uses Location 10 and 11. The address is divided into high and low bytes. High byte is calculated by taking the beginning address and dividing it by 256. The resulting whole number is stored in location 9 or 11. Low byte is the remainder from the division and is stored in location 8 or 10. The siren sound effects program stores the data at 33024. When divided by 256, this address equals 129 with no remainder. The 129 is stored in 9 or 11 and 0 is stored in 8 or 10. 3-10 To produce the siren sound through both speakers, set the pointer locations, 10 and 11 to 33024. The pointer for the first sound chip, 8 and 9, also points to this same address. Both chips may utilize data in the same memory location because the data is not affected by use, D <= =>POINTER LOC 8, 9 -> SOUND CHIP 1 -> SPEAKER 1 A T A < = = >POINTER LOC 10, 11 -> SOUND CHIP 2 -> SPEAKER 2 Change the following lines as indicated: 62 POKE l0,0: POKE 1l,l29 100 POKE 33024,86:POKE 33025,1 110 CALL 36897:CALL 32796 130 CALL 3694l Line 110, the CALL to 36897, is the RESET subroutine (Primary Routine) for the first sound chip. This CALL will shut off the first sound chip. If we do not shut off one of the chips, both would produce sound at the same time, and we would create a two-note chord. This CALL was not necessary in the earlier programs because both notes were generated by one sound chip. The second sound wrote over the register values of the first sound. Line 100, the CALL 32768, is dropped and picked up in line 110 as CALL 32796, which is the Table Access Routine for the second sound chip. It plays the second note through the other speaker. Line 130 turns off the second sound with a CALL to RESET2. Note that the pointers (8,9 and 10,11) do not have to be POKEd each time with the address of the sound data. The sound data has not moved from its location; therefore, its address remains the same. -end of part 5-