10 ' randpldr (for gwbasic, ega display, mpu-401 interface) 20 ' to gen. random patterns and play drums. R.L.Barns with G.L. mods 8/1/90 30 ' will make 4 bars of 4/4 with smallest interval of 1/16 note 40 ' will make 10 tracks of this, 50 ' the first 5 with constant density and the sec. 5 with dec. density. 60 ' the kick drum plays on every beat (not shown in display) 70 ' note-off not sent since percussion 80 ' instrument note numbers are for the RX-120 drum machine. 90 ' port read after each write for OP-4001 ACK even in uart mode. 100 ' timing loops used, calibrated by measuring cpu speed when run 110 ' (timing fairly accurate on 10mhz AT, will be off a bit otherwise) 120 KEY OFF:DEFINT A-Z 'integers for speed 130 DIM IT(20, 80) '20 tracks, 80 sixteenths in sequence table 140 DIM INAME$(20),INST(10),V(10) 'instrument names,notes,velocities 150 DIM Q(10) 'instrument play/quiet flags toggled from keyboard 160 DIM PS(17) 'screen positions for bar lines 170 ' percussion instrument note numbers 180 DATA 45, 52, 46, 62, 51, 70, 69, 68, 67, 77, 78 190 FOR I = 0 TO 10:READ INST(I):NEXT 200 'instrument names 210 DATA "..KickBase" :'not randomized 220 DATA "0 Snare", "1 Rim shot","2 Ride(cup)","3 Rim sh(tap)","4 Hi Timbales" 230 DATA "5 Lo Timbales","6 Hi Bongo","7 Lo Bongo","8 Cuica(hi)","9 Whistle" 240 FOR I = 0 TO 10:READ INAME$(I):NEXT 250 DATA 58, 88,88,88,88,88,88,88,88,88,88 :'instrument velocities 260 FOR I = 0 TO 10:READ V(I):NEXT 270 'vertical bar locations on 640 X 350 screen 280 DATA 4,36,68,100,132,164,196,228,260,292,324,356,388,420,452,484,517 290 FOR I=1 TO 17:READ PS(I):NEXT 300 ' 310 WHILE INP(817)<128:X=INP(816):WEND 'initial flush 320 OUT 817, 255:WHILE INP(817)<128:X=INP(816):WEND 'reset MPU 330 OUT 817, 63:WHILE INP(817)<128:X=INP(816):WEND 'set UART mode 340 ' 350 DRUM=1 'initial default drum channel 360 TEMPO=120 'initial default tempo 370 NOMEAS=1 'initial default number of measures 380 'setup menu 390 SCREEN 0:CLS:COLOR 10,9:LOCATE 8,10:PRINT " Barns' Random Drummer":PRINT 400 'input drum channel 410 COLOR 10,8:LOCATE 10,1:PRINT "Enter MIDI drum channel (default=";DRUM;:INPUT ")";X 420 IF X<0 OR X>16 THEN BEEP:GOTO 410 ELSE IF X THEN DRUM=X 430 NOTEON=143+DRUM 'midi note-on status 440 'enter number of measures 450 LOCATE 12,1:PRINT "How many measures (1 to 4, default";NOMEAS;:INPUT ")";X 460 IF X<0 OR X>4 THEN BEEP:GOTO 450 ELSE IF X THEN NOMEAS=X 470 LOCATE 14,1:PRINT "Tempo (default=";TEMPO;:INPUT ")";X:IF X THEN TEMPO=X 480 LOOPCT =(2526 - 21*TEMPO + .042*TEMPO*TEMPO)*2/3'time delay loop length 490 IF LOOPCT<1 THEN BEEP:GOTO 470 500 'measure cpu speed and adjust timing loop accordingly (983 @ 10mhz AT) 510 IF CPU!=0 THEN PRINT "calibrating...":Q$=TIME$:WHILE TIME$=Q$:WEND:Q$=TIME$:WHILE TIME$=Q$:I=I+1:WEND:CPU!=I/983! 520 LOOPCT=LOOPCT*CPU! 530 ' 540 'display rythm pattern header 550 SCREEN 9 '640 x 350 screen (use 100 on AT&T 6300) 560 CLS:COLOR 10,9:LOCATE 1,1:PRINT "Random Drummer" 570 LOCATE 4,1:PRINT "1 2 3 4 5 Meas." 580 LOCATE 5,1:PRINT "1...2...3...4...1...2...3...4...1...2...3...4...1...2...3...4...1 Beat" 590 FOR U = 0 TO 10:LOCATE 6+U,67:PRINT INAME$(U);:NEXT 'instrument names 600 ' 610 'generate and display sequences 620 RANDOMIZE TIMER:FRCT! = .8 'initial cut-off for pos. result 630 'kick base fixed on the beat, not randomized or selectable 640 LOCATE 6,1:FOR MEAS=0 TO 3:FOR BEAT=0 TO 3:N=MEAS*16+4*BEAT+1 650 IT(0,N)=1:PRINT TAB(N) "X";:NEXT BEAT:NEXT MEAS 660 FOR I = 1 TO 10 'Other 10 instruments, randomize 670 CT = 0 680 IF I > 4 THEN FRCT! = FRCT! + .02 'reduce no. of events in lower tracks 690 LOCATE 6+I,1 700 FOR MEAS = NOMEAS-1 TO 0 STEP -1 710 FOR BEAT = 3 TO 0 STEP -1 720 FOR SIXT = 4 TO 1 STEP -1:N=16*MEAS+4*BEAT+SIXT 730 PL = 0 740 IF RND > FRCT! THEN 750 ELSE 770 750 CT = CT + 1:PRINT TAB(N) "X";:PL = 1:IT(I, N) = PL 'instrument track IT 760 GOTO 780 770 IF SIXT = 1 THEN 790 ELSE PRINT TAB(N) "."; 780 LOCATE 6+I,1 790 NEXT SIXT:NEXT BEAT:NEXT MEAS:PRINT:NEXT I 800 FOR J = 1 TO 17:LINE (PS(J),79)-(PS(J), 235):NEXT 'write vert bar lines 810 ' 820 'initialize keyboard selections and display instructions 830 LOCATE 19,1 840 PRINT "Number keys ( * key for all) toggle instr's on/off; SPACE to stop. " 850 FOR J=0 TO 10:Q(J)=1:NEXT 'initially play all instruments 860 ' 870 ' play while polling on the beat for keyboard for selections 880 WHILE 1:N=0:FOR MEAS = 1 TO NOMEAS:FOR BEAT = 0 TO 3 'n=note count 890 Q$ = INKEY$:IF Q$ <> "" THEN 1010 900 FOR SIXT = 1 TO 4:N=N+1:FOR TIM = 0 TO LOOPCT:NEXT TIM 'delay 910 FOR J=0 TO 10:IF IT(J,N) AND Q(J) THEN 930 'find first note to play 920 NEXT J:GOTO 970 'all mute so skip 930 WHILE INP(817) AND 64:WEND:OUT 816,NOTEON:X=INP(816) 'note-on, once for all 940 FOR I =J TO 10 'send note,velocity when enabled for this sixteenth 950 IF IT(I,N) AND Q(I) THEN WHILE INP(817) AND 64:WEND:OUT 816,INST(I):X=INP(816):WHILE INP(817) AND 64:WEND:OUT 816,V(I):X=INP(816) 960 NEXT I 970 NEXT SIXT:NEXT BEAT:NEXT MEAS:WEND 980 ' 990 ' respond to keys pressed during play 1000 'toggle all instruments (kickbase allways plays) 1010 IF Q$ = "*" THEN X=0:FOR J=1 TO 10:X=X OR Q(J):NEXT J:X=X XOR 1:FOR J=1 TO 10:Q(J)=X:NEXT J:GOTO 880 1020 'toggle individual instrument 1030 IF Q$>CHR$(47) AND Q$" " THEN 880 'ignore input errors 1050 'pause and display new menu 1060 LOCATE 19,1:PRINT "SPACE to resume, ENTER for new pattern, ESC to set length/tempo, Q to end." 1070 Q$=INPUT$(1):IF Q$=" " THEN 830 'resume current pattern 1080 IF Q$=CHR$(13) THEN 620 're-randomize same setup 1090 IF Q$=CHR$(27) THEN 390 'return to setup menu 1100 IF Q$="Q" OR Q$="q" THEN OUT 817,255:WHILE INP(817)<128:X=INP(816):WEND:SCREEN 0:CLS:SYSTEM 'reset,exit 1110 BEEP:GOTO 1070 'input error