Classic Computer Magazine Archive COMPUTE! ISSUE 71 / APRIL 1986 / PAGE 114

programming TIProgramming the TI


C.Regena


Creating Rhythms

A year ago, in the March 1985 issue of COMPUTE!, I published a program called "Drum Practice" for the TI-99/4A. That program was limited to quarter notes and quarter rests and the rhythms listed in DATA statements. This month, I'm offering a more complex program. You can create the rhythm for one measure by choosing notes and rests, and then the computer will play the rhythm for eight measures.
    Lines 110-190 print the instructions. The different kinds of notes and rests available will appear at the bottom of the screen. You can use the arrow keys (on S and D) to move the red marker left or right to make your selection, then press the ENTER key. Your choice will then be printed on the staff above.
    The available notes are a quarter note, two eighth notes together, one eighth note, two sixteenth notes, a dotted eighth note with a sixteenth note, a quarter rest, and an eighth rest.
    Line 200 sets the time T equal to 75. If you want the rhythm to play faster decrease this number which represents the duration of a sixteenth note. Lines 210-240 read in from data (lines 260-330) the definitions for the graphic characters and define the characters from numbers 91 to 128. Line 340 defines R for a row number for the staff. Lines 350-360 define the red arrow used as a marker under the notes to be selected.
    Lines 370-390 define variables in an array for the seven possible choices. Line 400 contains the data for this loop. For each of the choices from 1 to 7, D(C) is a value representing the counts-4 for one count, 2 for a half count. This variable is used to make sure the user makes a valid choice. For example, the computer will not allow a quarter note to be chosen if only a half of a count is left in the measure. COL(C) is the column and is used to place the red marker.

The Rhythm Track
S$(C) represents the durations when the rhythm is played. A sixteenth note factor is 1, so the quarter note is 4. Two eighth notes are 22, and one eighth note is 2. The two sixteenth notes are 11, and a dotted eighth with a sixteenth are 31. The rests are W and H. As the notes and rests are chosen, the string RHY$ will add on values of S$ (line 870).
    Lines 1250-1390 play the rhythm. Line 1270 finds the length L of the string RHY$. Line 1280 starts the loop for L number of times. Line 1290 looks at one character at a time of RHY$. If the character A$ is a letter, a rest is indicated so a frequency of 9999 with a volume of 30 is used. If A$ is a number, that number is used as a factor times the previously defined T for the duration in the CALL SOUND statement, line 1310. If you prefer a different sound, change the frequency numbers in line 1310. 1 used the noise of -5 plus the frequency of 330. Line 1370 stops the sound so you can hear the different notes. The measure is played eight times.
    Lines 420-440 wait for you to press ENTER before the program continues. Lines 460-500 clear the screen and print the notes using the redefined symbols. The lowercase y and z are typed by releasing the ALPHA LOCK key. Most of the symbols are typed by using the function key. Lines 510-630 draw the staff.
    Lines 650-690 initialize variables for choosing the notes. COUNT and CHECK are used to determine how many notes and rests can be used in the measure. This measure is 4/4 time. A sixteenth note has a value of 1, so the COUNT will go up to 16. CHECK is how many points are remaining in the measure. These numbers are used to verify which notes and rests can be used in the measure.
    PLACE is the column number where the note or rest will start being drawn on the staff. The first note will start in column 8. PLACE is incremented depending on which note or set of notes is chosen. Lines 690-820 are the lines to get the user's choice. Line 730 makes sure the left arrow key (S), the right arrow key (D), or the ENTER key is chosen; all other keys are ignored by branching back to the CALL KEY statement. C is the choice number, and COL(C) is the column where the red marker appears for the choice.

It's Timing That Counts
Line 830 makes sure the choice is valid. The D timing value must be less than or equal to the number of sixteenth counts available. If the choice is not valid, the program plays an "uh-oh" sound and branches back to line 720, which is the CALL KEY statement to get another choice. Line 870 increments the RHY$ string with the appropriate timing factors. Line 880 branches to the proper place for drawing the notes or rest and incrementing PLACE.
    Lines 1220-1240 increment the COUNT and recalculate the CHECK time. If the measure is not full, the program goes back to get another choice. Lines 1250-1390 play the measure eight times. To stop the program, press FCTN BREAK.
    If you have trouble running this program and get an error message in 220, 230, or 380, the actual cause of the error is most likely in the DATA statements of lines 260-330 or line 400.
    All notes are placed at the E space of the staff, representing a snare drum rhythm. You may add to the program by including bass drum notes, cymbal rhythms, and tom-toms. To use this program for a melody instrument, you can use the up and down keys to move the note on the staff, then use a variable frequency to play the note.
    You may use the general idea of this program in choosing items to go with a different theme of graph ics, not music-perhaps building a game or drawing a picture by choosing different shapes.

Rhythms

100 REM RHYTHMS
110 CALL CLEAR
120 PRINT TAB(10);"RHYTHMS"
130 PRINT ::"CHOOSE THE NOT
    ES FROM THE"
140 PRINT :"BOTTOM OF THE S
    CREEN BY"
150 PRINT :"USING THE LEFT
    AND RIGHT"
160 PRINT :"ARROW KEYS TO M
    OVE AND"
170 PRINT :"THE ENTER KEY T
    O SELECT."
180 PRINT ::"WHEN THE MEASU
    RE IS COMPLETE"
190 PRINT :"YOU WILL HEAR T
    HE RHYTHM."
200 T=75
210 FOR C=91 TO 128
220 READ C$
230 CALL CHAR(C,C$)
240 NEXT C
250 REM DATA FOR CHARACTER
    S
260 DATA 00000F080F080808,0
    000F808F8080808,0808083
    8F9E8,0000FF0107010101,
    10080C1830300804,1C2020
    1008
270 DATA 000000000000FFD0,D
    0D0FFD0D4D0FFD0,D4D0FFD
    0D0D0FF,000000000000FF,
    0000FF000000FF,00000000
    0000FF0B
280 DATA 0B0BFF0B2B0BFF0B,2
    B0BFFOB0B0BFF,000000000
    000FF10,2424447E0404FF1
    ,102424447EO4FF,0000080
    80808FF08
290 REM
300 DATA 0808FF78F870FF,000
    00F080808FF08,0000F8080
    808FF08,0000080C0A09FF0
    8,00000F080F08FF08
310 DATA 0000F808F808FF08,0
    000FF010701FF01,0000FF6
    27E04FF1,1020FF000000FF
    ,0808FF78F978FF,10080C1
    830300804
320 DATA 1C20201008,0000080
    808080808,08080878FB7,0
    0000F0808080808,0000F80
    808080808,0000080C0A090
    808
330 DATA 627E020408102,0101
    FF0FlF0EFF,0101010FlF0E
340 R=5
350 CALL CHAR(136,"10387CFE
    1010101")
360 CALL COLOR(14,7,1)
370 FOR C=1 TO 7
380 READ D(C),COL(C),S$(C)
390 NEXT C
400 DATA 4,4,4,4,8,22,2,12,
    2,2,15,11,4,19,31,4,24,
    W,2,28,H
410 REM
420 PRINT ::"PRESS <ENTER>
    TO START."
430 CALL KEY(0,K,S)
440 IF K<>13 THEN 430
450 REM  DRAW NOTES
460 CALL CLEAR
470 PRINT " y   {:  }  [\
    (^   _"
480 PRINT " z   zz  z  zz
    zz
490 CALL HCHAR(23,20,128)
500 PRINT
510 REM DRAW STAFF
520 CALL HCHAR(R,3,97)
530 CALL HCHAR(R  ,3,98)
540 CALL HCHAR(R  ,3,99)
550 CALL HCHAR(R,4,100,22)
560 CALL HCHAR(R+1,4,101,22
    )
570 CALL HCHAR(R+2,4,101,22
    )
580 CALL HCHAR(R,26,102)
590 CALL HCHAR(R+1,26,103)
600 CALL HCHAR(R+2,26,104)
610 CALL HCHAR(R,5,105)
620 CALL HCHAR(R+1,5,106)
630 CALL HCHAR(R+2,5,107)
640 REM CHOOSE NOTES
650 COUNT=0
660 CHECK=16
670 PLACE=8
680 RHY$=""
690 C=1
700 CALL HCHAR(23,COL(C),13
    6)
710 CALL SOUND(100,1400,2)
720 CALL KEY(0,K,S)
730 IF (K<>13)*(K<>83)*(K<>
    68)THEN 720
740 CALL HCHAR(23,COL(C),32
    )
750 IF K<>83 THEN 780
760 C=C-1
770 IF C>=1 THEN 700 ELSE 6
    90
780 IF K<>68 THEN 830
790 C=C+1
800 IF C<=7 THEN 700
810 C=7
820 GOTO 700
830 IF D(C)<=CHECK THEN 870
840 CALL SOUND(150,330,2)
850 CALL SOUND(150,262,2)
860 GOTO 700
870 RHY$=RHY$&S$(C)
880 ON C GOTO 890,930,990,1
    030,1090,1150,1190
890 CALL HCHAR(R,PLACE,108)
900 CALL HCHAR(R+1,PLACE,10
    9)
910 PLACE=PLACE+3
920 GOTO 1220
930 CALL HCHAR(R,PLACE,110)
940 CALL HCHAR(R+1,PLACE,10
    9)
950 CALL HCHAR(R,PLACE+1,11
    1)
960 CALL HCHAR(R+1,PLACE+1,
    109)
970 PLACE=PLACE+3
980 GOTO 1220
990 CALL HCHAR(R,PLACE,112)
1000 CALL HCHAR(R+1,PLACE,1
     09)
1010 PLACE=PLACE+2
1020 GOTO 1220
1030 CALL HCHAR(R,PLACE,113
     )
1040 CALL HCHAR(R+1,PLACE,1
     09)
1050 CALL HCHAR(R,PLACE+1,1
     14)
1060 CALL HCHAR(R+1,PLACE+1
     ,109)
1070 PLACE=PLACE+2
1080 GOTO 1220
1090 CALL HCHAR(R,PLACE,110
     )
1100 CALL HCHAR(R+1,PLACE,1
     18)
1110 CALL HCHAR(R,PLACE+1,1
     15)
1120 CALL HCHAR(R+1,PLACE+1
     ,127)
1130 PLACE=PLACE+3
1140 GOTO 1220
1150 CALL HCHAR(R+1,PLACE,1
     19)
1160 CALL HCHAR(R+2,PLACE,1
     20)
1170 PLACE=PLACE+3
1180 GOTO 1220
1190 CALL HCHAR(R+1,PLACE,1
     16)
1200 CALL HCHAR(R+2,PLACE,1
     17)
1210 PLACE=PLACE+2
1220 COUNT=COUNT+D(C)
1230 CHECK=16-COUNT
1240 IF COUNT<16 THEN 700
1250 REM  PLAY RHYTHM
1260 FOR TIME=1 TO 8
1270 L=LEN(RHY$)
1280 FOR M=1 TO L
1290 A$=SEG$(RHY$,M,1)
1300 IF (A$="W")+(A$="H")TH
     EN 1330
1310 CALL SOUND(T*VAL(A$),-
     5,2,330,4)
1320 GOTO 1370
1330 REST =T
1340 IF A$="H" THEN 1360
1350 REST=REST*2
1360 CALL SOUND(REST,9999,3
     0)
1370 CALL SOUND(1,9999,30)
1380 NEXT M
1390 NEXT TIME
1400 FOR DEL=1 TO 500
1410 NEXT DEL
1420 GOTO 460
1430 END