REM midimaker.bas REM -Hotwrench- INPUT"Enter new file name + .mid",mf$ IF mf$ ="" THEN mf$="midi.mid" a$ =RIGHT$(mf$,4) IF a$ <> ".mid" THEN mf$="midi.mid" start=0 GOSUB SETUP start=1 tempo =120 nlen =127 inst =1 DIM midi[1600] %midi file DIM note$[11] %read in scale FOR t=1 TO 11 READ.NEXT n$ note$[t]=n$ NEXT DIM notehex[11] % read note data FOR t=1 TO 11 READ.NEXT nh notehex[t]=nh NEXT FOR mft=1 TO 22 % read in file header READ.NEXT mh midi[mft]=mh NEXT midi[mft]=0 midi[mft+1]=192 %instrument change midi[mft+2]=inst %instrument 0-127 mft = mft+3 DO DO GR.TOUCH touched,x,y x/=x1 y/=y1 IF touched IF x>700 &y>390 THEN end IF x<100 & y>390 THEN gosub play IF x>340 &x<460 &y>390 THEN gosub settings IF fd=0 IF x>180 & x<240 & y>390 THEN gosub sharp IF y>345 THEN goto nxtnote IF fn>700 THEN gosub SETUP GR.COLOR 255,90,90,255,1 %note color fn=mt+50 mt=mt+100 FOR nt=15 TO 345 STEP 30 % which note IF y>=nt & y<=nt+30 note=12-(nt+15)/30 IF mft=26 THEN midi[mft]=0 % first note time IF mft >26 THEN midi[mft]=nlen %127 time midi[mft+1]=144 % note on midi[mft+2]=notehex[note]+sharp % note midi[mft+3]=127 % volume midi[mft+4]=nlen % time before note off midi[mft+5]=128 %note off midi[mft+6]=notehex[note]+sharp midi[mft+7]=0 mft=mft+8 IF note =1 THEN GR.LINE clne,fn-30,nt+15,fn+30,nt+15 IF sharp =1 % sharp color GR.COLOR 255,255,90,90,1 ELSE GR.COLOR 255,90,90,255,1 END if sharp = 0 GR.HIDE sharpc GR.LINE tail,fn+12,nt-15,fn+12,nt+15 GR.CIRCLE cir,fn,nt+15,15 % draw note GR.COLOR 255,0,0,0,1 GR.TEXT.DRAW nte,fn-8,nt+23,note$[note] GR.COLOR 255,90,90,255,1 GR.RENDER PAUSE 500 END if NEXT nxtnote: END if UNTIL !touched END if UNTIL 0 SETUP: mt=0 % bar count IF start >0 THEN gr.close GR.OPEN 255,255,255,255 GR.COLOR 255,0,0,0,0 GR.SET.STROKE 3 GR.TEXT.SIZE 30 GR.SCREEN W, H X1 = w /800 Y1 = h /480 GR.SCALE X1,Y1 GOSUB drawclef GOSUB drawmeasure GR.COLOR 255,255,90,90,1 %note color GR.CIRCLE sharpc,210,440,20 GR.HIDE sharpc GR.COLOR 255,25,25,25,1 %shadow color GR.RECT rectols,699,419,778,458 % buttons GR.RECT recplays,19,419,99,458 GR.RECT recsetg,339,419,459,458 GR.COLOR 255,190,190,190,1 GR.RECT recexit,700,420,780,460 GR.RECT recplay,20,420,100,460 GR.RECT recsetg,340,420,460,460 GR.COLOR 255,0,0,0,1 GR.TEXT.DRAW etxt,712,450,"Exit GR.TEXT.DRAW ptxt,32,450,"Play" GR.TEXT.DRAW stxt,345,450,"Settings" GR.TEXT.DRAW sharpt,200,450,"#" GR.COLOR 255,90,90,255,1 %note color GR.RENDER RETURN drawmeasure: FOR t = 0 TO 800 STEP 100 %draw measures GR.LINE lne2,t,30,t,270 NEXT RETURN drawclef: FOR t=30 TO 270 STEP 60 %draw treble clef GR.LINE lne1,0,t,800,t NEXT RETURN sharp: sharp =1 GR.SHOW sharpc GR.RENDER RETURN settings: GR.COLOR 200,20,20,255,1 %settings backcolor GR.RECT sett,10,10,220,420 GR.COLOR 255,195,195,195,1 GR.RECT nlbox1 ,20,120,140,160 GR.RECT ibox1 ,20,200,140,240 GR.RECT exbox1,40,340,180,400 GR.RECT tbox1 ,20,40,140,80 GR.COLOR 255,0,0,0,0 GR.TEXT.DRAW tbox,30,110,"Tempo" GR.TEXT.DRAW nlbox,30,190,"Note length" GR.TEXT.DRAW ibox,30,270,"Instrument" GR.RECT setts,10,10,220,420 GR.TEXT.DRAW tbox2,30,70,"- + "+STR$(tempo) GR.TEXT.DRAW nlbox2,30,150,"- + "+STR$(nlen) GR.TEXT.DRAW ibox2,30,230,"- + "+STR$(inst) GR.TEXT.DRAW exbox2,75,380,"Done" ex=0 DO GR.MODIFY tbox2,"text","- + "+ FORMAT$("###",tempo) %STR$(tempo) GR.MODIFY nlbox2,"text","- + "+ FORMAT$("###",nlen) %STR$(nlen) GR.MODIFY ibox2,"text","- + "+ FORMAT$("###",inst) %STR$(inst) GR.RENDER GR.TOUCH setng,x,y x/=x1 y/=y1 IF setng & x>20&x<60 &y>40&y<80 THEN tempo-=8 IF setng & x>60&x<140&y>40&y<80 THEN tempo+=8 IF tempo >255 THEN tempo=255 IF tempo<8 THEN tempo =8 IF setng & x>20 & x<60 & y>120 & y<160 THEN nlen-=8 IF setng & x>60 & x<140 & y>120 & y<160 THEN nlen+=8 IF nlen > 127 THEN nlen=127 IF nlen < 8 THEN nlen =8 IF setng & x>20 & x<60 & y>200 & y<240 THEN inst-=1 IF setng & x>60 & x<140 & y>200 & y<240 THEN inst+=1 IF inst > 127 THEN inst=1 IF inst < 1 THEN inst =127 midi[25]=inst IF x>20 & x<180 & y>360 & y<410 THEN ex=1 UNTIL ex=1 GR.HIDE sett GR.HIDE setts GR.HIDE exbox1 GR.HIDE exbox2 GR.HIDE tbox GR.HIDE tbox1 GR.HIDE tbox2 GR.HIDE nlbox GR.HIDE nlbox1 GR.HIDE nlbox2 GR.HIDE ibox GR.HIDE ibox1 GR.HIDE ibox2 GR.RENDER RETURN play: %write & play !mf$="midi.mid" %file name midi[14]=tempo midI[25]=inst !midi[mft]=127 % all notes off !midi[mft+1]=183 % not needed, uses note off !midi[mft+2]=176 % after every note on !midi[mft+3]=0 % unrem and this will be added !mft=mft+4 % to the end of your file IF fd=0 midi[mft]=0 % end of .mid file midi[mft+1]=255 midi[mft+2]=47 midi[mft+3]=0 mft=mft+4 END if fd=1 mb=mft-22 IF mb>255 %data over 255 lb=MOD(mb,255) hb=(mb-lb)/255 midi[21]=hb midi[22]=lb ELSE midi[22]=mb% mft-22 END if PRINT "writing ";mft;" bytes" BYTE.OPEN w,md,mf$ FOR t = 1 TO mft BYTE.WRITE.BYTE md,midi[t] NEXT BYTE.CLOSE md PRINT "playing ";mf$ AUDIO.LOAD midf, mf$ AUDIO.PLAY midf DO AUDIO.ISDONE isdone PAUSE 500 UNTIL isdone PRINT "done" AUDIO.STOP RETURN !END READ.DATA "c","d","e","f","g","a","b","c","d","e","f" READ.DATA 60,62,64,65,67,69,71,72,74,76,77 READ.DATA 77,84,104,100 % "MThd" READ.DATA 0,0,0,6 % length of remaining header READ.DATA 0,0 % MIDI format: type0 = 0 type1 = 1 READ.DATA 0,1 % number of tracks, type0 has one track READ.DATA 0,255 % tempo, ticks per quarter note READ.DATA 77,84,114,107 % "MTrk" start of track READ.DATA 0,0,0,20 %length of music data + 4 !! note data info byte 1: start time 1st note = 0 byte 2: 144=note on trk 0, 128=note off trk 0 192 = instrument trk 0 byte 3: pitch aka note or instrument byte 4: volume 0-127 !!