'File name: 4-V Librarian 'Description: SYSTEM Exclusive MIDI patch editor/librarian for 4-Voice Interface 'Original Date: 3/3/90 By: Joe Paradiso ' 'This program uses MIDIBASIC in the 'QuickBASIC  environment. 'MIDIBASIC is a trademark of ALTECH SYSTEMS 'QuickBASIC is a trademark of MICROSOFT Corporation 'Joe Paradiso is his own trademark '----------------------------------------------------------------- ' This program needs the file '4-v DS' that is created by the program ' "4-v DSInit". If it isn't around, that program should be run (with the ' Interface connected) to create the file. '----------------------------------------------------------------- ' ' Initialize BASIC ' CLEAR ,90000!,5000 ' 'set the compiled% variable to "1" before compiling ' compiled% = 1 'Toggle for compiled/interpreted versions (1 = compiler) FOR i%=1 TO PEEK(&H910) libname$=libname$+CHR$(PEEK(&H910+i%)) NEXT IF compiled% THEN LIBRARY libname$ ELSE LIBRARY "MIDIBASIC" ' DEFINT A-Z OPTION BASE 1 '----------------------------------------------------------------- ' MIDIBASIC Variables halfMeg% = 0 oneMeg% = 1 twoMeg%= 2 modem% = 3 printer% = 4 ClearIn% = 5 ClearOut% = 6 mode% = 0 count%= 0 result% = 0 loHiMode% = 1 maxBufferSize% = -1 ' 64K buffer checkon = 2 checkoff = 1 port% = modem% nsel2 = 1 clockRate% = oneMeg% ' Ntd% = 5 Npchl% = 1 Npage% = 0 En% = 0 Filenick$ = "----" Filename$ = Filenick$ Mxp% = 1 Chnl% = 1 ' noDataFlag = 0 dumpflag=noDataFlag ' ' '----------------------------------------------------------------- ' SyxEx DATA Formats ' string buffer variable used by GetMIDI to retrieve singel bytes temp1$ = SPACE$(1) '----------------------------------------------------------------- ' Sysex dump request Formats ' DSRRequestSize% = 7 'size of DSR Dump SysEx request ' DIM DSRRequest(DSRRequestSize%) 'Array to hold 7 byte dump request message DSRRequest(1) = &HF0 'SysEx DSRRequest(2) = &H10 'Oberheim ID DSRRequest(3) = &H77 'JAP Interface code DSRRequest(4) = &H0 'Full dump request DSRRequest(5) = &H0 'Blank byte DSRRequest(6) = &H7F 'Dump data structures DSRRequest(7) = &HF7 'Last byte: EOX ' '----------------------------------------------------------------- ' initialization main window ' ' get menu bar height, screen height and screen width for global use screenW%=SYSTEM(5) screenH%=SYSTEM(6) menuBarH%=PEEKW(&HBAA) 'menu bar height Mac global variable ' ' Open SysEx Lab's window. TitleH%=20 'height of window type 1 title bar height%=screenH%-(menuBarH%+TitleH%+10) centerWindow 1,"4-Voice Librarian",height%,screenW%-10,1,1/2 ' CALL TEXTFACE(1) PRINT " --- 4-Voice Interface Patch Editor & Librarian ---" PRINT CALL TEXTFACE(0) PRINT "If you use the Jambox, Make sure to turn echo off" PRINT "before doing any up/downlink operations!!!!" PRINT ' ' Initialize data structures from file ' ON ERROR GOTO Badfile PRINT "Initializing from file '4-V DS' ........." OPEN "4-V DS" FOR INPUT AS #2 ' INPUT #2,Npchm%,NL0%,NL1M% PRINT "# Patches: ";Npchm;" #L0 Entries: ";NL0%;"Max. #L1 Entries: ";NL1M% ' DIM L0T$(NL0%),L1T$(NL1M%,NL0%),L1F%(NL1M%,NL0%),L1L%(NL1M%,NL0%) DIM NL1%(NL0%),Dpch%(NL1M%,NL0%),Cpch%(NL1M%,NL0%) DIM Pchd%(NL1M%,NL0%,Npchm%),Pcht$(Npchm%),Pcht1$(Npchm%) ' FOR j = 1 TO NL0% INPUT #2,L0T$(j) INPUT #2,NL1%(j) FOR k = 1 TO NL1%(j) INPUT #2,L1T$(k,j) INPUT #2,L1F%(k,j) INPUT #2,L1L%(k,j) NEXT k NEXT j ' INPUT #2,Nopt% DIM Opt$(Nopt%) PRINT "# Options in Table: ";Nopt% FOR j = 1 TO Nopt% INPUT #2,Opt$(j) NEXT j ' Ntp% = 0 FOR j = 1 TO NL0% Ntp% = Ntp% + NL1%(j) FOR k = 1 TO NL1%(j) INPUT #2,Dpch%(k,j) Cpch%(k,j) = Dpch%(k,j) NEXT k NEXT j Ntp% = Ntp% + 10 ' Correct for title/Pnum ' Dtit$ = "((BLANK))" Ctit$ = Dtit$ PRINT PRINT "I n i t i a l i z a t i o n C o m p l e t e d ! ! ! ! !" CLOSE #2 ON ERROR GOTO 0 ' FOR n = 1 TO Npchm% FOR m = 1 TO NL0% FOR k = 1 TO NL1%(m) Pchd%(k,m,n) = Dpch%(k,m) NEXT k NEXT m Pcht$(n) = Dtit$ NEXT n ' '----------------------------------------------------------------- GOSUB SetUpMenus GOSUB INITMIDI ' '----------------------------------------------------------------- ' main loop WHILE 1 ON MENU GOSUB DoMenu :MENU ON ON BREAK GOSUB DoBreak :BREAK ON WEND '----------------------------------------------------------------- ' Badfile: PRINT "Initialization Error!!!" Ie1% = ERR IF Ie1% = 53 THEN PRINT "Can't locate file '4-V DS'" ELSEIF Ie1% > 51 THEN PRINT "File error on '4-V DS'; Error #: ";Ie1% ELSE PRINT "Error #: ";Ie1% END IF ' PRINT "Re-run program '4-V DSInit' to re-create file, and name it '4-V DS'" INPUT "Hit to stop Program";A$ RESUME DoBreak ' '----------------------------------------------------------------- SetUpMenus: GOSUB SetupFileMenu GOSUB SetupEditMenu GOSUB SetUpDownLinkMenu GOSUB SetupPatchMenu GOSUB SetUpPrintMenu GOSUB SetUpMIDIMenu RETURN ' '--------------------------------------------------------------- ' SetupFileMenu: MENU 1,0,1,"File" MENU 1,1,1,"Open/Load All" :cmdkey 1,1,"O" MENU 1,2,1,"Open/Load Patch" :cmdkey 1,2,"T" MENU 1,3,1,"Save" :cmdkey 1,3,"S" MENU 1,4,1,"Quit" :cmdkey 1,4,"Q" RETURN ' '--------------------------------------------------------------- ' SetupEditMenu: MENU 2,0,1,"Edit" MENU 2,1,1,"Undo" :cmdkey 2,1,"Z" MENU 2,2,0,"-" MENU 2,3,1,"Cut" :cmdkey 2,3,"X" MENU 2,4,1,"Copy" :cmdkey 2,4,"C" MENU 2,5,1,"Paste" :cmdkey 2,5,"V" MENU 2,6,1,"Clear" MENU 2,7,0,"-" ' Assume that the Edit menu is already there MENU 2,8,1,"Copy Patch" :cmdkey 2,8,"H" MENU 2,9,1,"Paste Patch" :cmdkey 2,9,"I" MENU 2,10,0,"-" Ixl% = 0 ' SetPgCopy: MENU 2,11,Ixl%,"Copy Page" :cmdkey 2,11,"J" MENU 2,12,Ixl%,"Paste Page" :cmdkey 2,12,"K" ' RETURN ' '--------------------------------------------------------------- ' SetUpDownLinkMenu: MENU 3,0,1,"Up/Downlink" MENU 3,1,1,"Uplink All" MENU 3,2,1,"Uplink Patch" :cmdkey 3,2,"U" MENU 3,3,1,"Uplink Current Patch" :cmdkey 3,3,"/" MENU 3,4,0,"-" MENU 3,5,1,"Downlink All" MENU 3,6,1,"Downlink Patch" :cmdkey 3,5,"D" MENU 3,7,1,"Downlink Patch & Load" :cmdkey 3,6,"L" MENU 3,8,1,"Downlink Current Patch" :cmdkey 3,8,"," ' RETURN ' '--------------------------------------------------------------- ' SetupPatchMenu: MENU 4,0,1,"Patch" MENU 4,1,1,"Show Titles" :cmdkey 4,1,"T" MENU 4,2,0,"-" MENU 4,3,1,"Load Patch" :cmdkey 4,3,"A" MENU 4,4,1,"Next Patch" :cmdkey 4,4,"N" MENU 4,5,1,"Previous Patch" :cmdkey 4,5,"P" MENU 4,6,0,"-" MENU 4,7,1,"Title/Patch#" :cmdkey 4,7,"0" ' N1$ = "0" N3% = 7 N2% = ASC(N1$) FOR k = 1 TO NL0% N2% = N2% + 1 N3% = N3% + 1 N1C$ = CHR$(N2%) MENU 4,N3%,1,L0T$(k) :cmdkey 4,N3%,N1C$ NEXT k MENU 4,N3%+1,0,"-" MENU 4,N3%+2,0,"Edit Item" :cmdkey 4,N3%+2,"E" NEditItem% = N3% + 2 ' RETURN ' '--------------------------------------------------------------- ' SetUpPrintMenu: MENU 5,0,1,"Print" MENU 5,1,1,"Titles" MENU 5,2,1,"Page" MENU 5,3,1,"Patch" MENU 5,4,1,"All Patches" MENU 5,5,0,"-" MENU 5,6,1,"FF After Pages" Ifff = 0 ' RETURN ' '--------------------------------------------------------------- ' SetUpMIDIMenu: ModemCheck = 2 PrinterCheck = 1 halfMegCheck = 1 oneMegCheck =2 twoMegCheck = 3 MENU 6,0,1, "MIDI" MENU 6,1,2,"Modem" MENU 6,2,1, "Printer" MENU 6,3,0,"-" MENU 6,4,1, ".5 MHz" MENU 6,5,2,"1 MHz" MENU 6,6,1, "2 MHz" MENU 6,7,0,"-" MENU 6,8,1,"Clear MIDI" RETURN ' '--------------------------------------------------------------- ' DoMenu: MenuID= MENU(0) menuitem= MENU(1) SELECT CASE MenuID CASE 1 : GOSUB FileCmd 'File menu CASE 2 : GOSUB EditCmd 'Edit menu CASE 3 : GOSUB UDLinkCmd 'Up/Downlink menu CASE 4 : GOSUB PatchCmd 'Patch menu CASE 5 : GOSUB PrintCmd 'Print menu CASE 6 : GOSUB MIDICmd 'MIDI menu CASE ELSE 'ignore any other menu PRINT "Unknown menuID:" MenuID END SELECT MENU 'restore unhighlighted state RETURN '----------------------------------------------------------------- FileCmd: SELECT CASE menuitem ' CASE 1 'Open/All Filename$ = FILES$(1,"TEXT") IF Filename$ <> "" THEN OPEN Filename$ FOR INPUT AS #1 GOSUB Aliasq CLS FOR n = 1 TO Npchm% INPUT #1,Nkk0%,Pcht$(n) IF (EOF(1)) GOTO eeff PRINT "Patch# ";Nkk0%,"Title: ";Pcht$(n) FOR m = 1 TO NL0% FOR k = 1 TO NL1%(m) INPUT #1,Pchd%(k,m,n) IF (EOF(1)) GOTO eeff NEXT k NEXT m NEXT n eeff: CLOSE #1 Npage% = 0 MENU 4,NEditItem%,0 MENU 4,Mxp%,1 MENU 4,1,2 MENU 2,11,0 MENU 2,12,0 Mxp% = 1 END IF GOSUB ShoPage ' CASE 2 'Open/Patch Filename$ = FILES$(1,"TEXT") IF Filename$ <> "" THEN OPEN Filename$ FOR INPUT AS #1 GOSUB Aliasq CLS Nlp% = 0 FOR n = 1 TO Npchm% INPUT #1,Nkk0%,Pcht1$(n) IF (EOF(1)) GOTO eegg ' print "Patch# ";Nkk0%,"Title: ";Pcht1$(n) FOR m = 1 TO NL0% FOR k = 1 TO NL1%(m) INPUT #1,nn% IF (EOF(1)) GOTO eegg NEXT k NEXT m Nlp% = Nlp% + 1 NEXT n eegg: CLOSE #1 CLS Lqqt% = 1 PRINT "File: "; CALL TEXTFACE(1) PRINT Filenick$; CALL TEXTFACE(0) PRINT " Available Patches...." PRINT "---------------------------------------------------" PRINT GOSUB PrtTit PRINT CALL TEXTFACE(1) INPUT "Enter patch# to Load:";IPLL% CALL TEXTFACE(0) IF (IPLL% > 0) AND (IPLL% <= Nlp%) THEN CALL TEXTFACE(1) INPUT "Enter Destination Patch# in memory:";Npchl% CALL TEXTFACE(0) IF (Npchl% > 0) AND (Npchl% <= Npchm%) THEN OPEN Filename$ FOR INPUT AS #1 FOR n = 1 TO IPLL% INPUT #1,N0,Pcht$(Npchl%) FOR m = 1 TO NL0% FOR k = 1 TO NL1%(m) INPUT #1,Pchd%(k,m,Npchl%) NEXT k NEXT m NEXT n CLOSE #1 END IF END IF END IF GOSUB ShoPage ' CASE 3 'Save All Filename$ = FILES$(0,"Save Patches Where??") IF Filename$ <> "" THEN OPEN Filename$ FOR OUTPUT AS #1 GOSUB Aliasq CLS FOR n = 1 TO Npchm% PRINT "Saving Patch# ";n,Pcht$(n) WRITE #1,n,Pcht$(n) FOR m = 1 TO NL0% FOR k = 1 TO NL1%(m) WRITE #1,Pchd%(k,m,n) NEXT k NEXT m NEXT n CLOSE #1 NAME Filename$ AS Filename$,"TEXT" ' Select Edit filetype END IF GOSUB ShoPage ' CASE 4 'Quit GOTO DoBreak ' CASE ELSE PRINT "Undefined menu item:";menuitem ' END SELECT ' RETURN ' '----------------------------------------------------------------- ' Aliasq: ' Pull off only base filename; no path LL% = LEN(Filename$) Filenick$ = "" FOR k = 1 TO LL% Idchr% = LL% - k + 1 A$ = MID$(Filename$,Idchr%,1) IF A$ = ":" THEN RETURN Filenick$ = A$ + Filenick$ NEXT k RETURN ' '----------------------------------------------------------------- ' Waitx: ' Wait some time (1 sec?) start! = TIMER IF start! > 86399& GOTO Waitx w11: NXT! = TIMER dlt% = NXT! - start! IF dlt% < 2 GOTO w11 ' for nnq = 1 to 2000 ' delay for MIDI Time Piece ' r = sin(nnq*.001) ' next nnq RETURN ' '----------------------------------------------------------------- ' PrtTit: ' Prints out all Patch Titles nicely N1% = Nlp%/Ntd% N2% = N1% * Ntd% IF (N2% < Nlp%) THEN N1% = N1% + 1 FOR n = 1 TO N1% N3% = (n - 1) * Ntd% + 1 N4% = N3% + Ntd% - 1 Itbb% = 0 FOR m = N3% TO N4% IF m <= Nlp% THEN IF Lqqt% = 0 THEN IF m = Npchl% THEN PRINT TAB(Itbb%); CALL TEXTFACE(1) PRINT m; CALL TEXTFACE(0) PRINT TAB(Itbb% + 5); CALL TEXTFACE(1) PRINT Pcht$(m); CALL TEXTFACE(0) ELSE PRINT TAB(Itbb%);m;TAB(Itbb% + 5);Pcht$(m); END IF ELSE PRINT TAB(Itbb%);m;TAB(Itbb% + 5);Pcht1$(m); END IF END IF Itbb% = Itbb% + 15 NEXT m PRINT NEXT n RETURN ' '----------------------------------------------------------------- ' EditCmd: IF menuitem < 8 THEN RETURN ' Ignore standard items IF menuitem > 10 AND Npage% = 0 THEN ' No page selected BEEP RETURN END IF ' SELECT CASE menuitem - 7 ' CASE 1 'Copy Patch Ctit$ = Pcht$(Npchl%) FOR m = 1 TO NL0% FOR k = 1 TO NL1%(m) Cpch%(k,m) = Pchd%(k,m,Npchl%) NEXT k NEXT m ' CASE 2 'Paste Patch Pcht$(Npchl%) = Ctit$ FOR m = 1 TO NL0% FOR k = 1 TO NL1%(m) Pchd%(k,m,Npchl%) = Cpch%(k,m) NEXT k NEXT m GOSUB ShoPage ' CASE 4 'Copy Page IF Npage% > 0 THEN IF Npage% = 1 THEN Ctit$ = Pcht$(Npchl%) ELSE FOR k = 1 TO NL1%(Npage%-1) Cpch%(k,Npage%-1) = Pchd%(k,Npage%-1,Npchl%) NEXT k END IF END IF ' CASE 5 'Paste Page IF Npage% > 0 THEN IF Npage% = 1 THEN Pcht$(Npchl%) = Ctit$ ELSE FOR k = 1 TO NL1%(Npage%-1) Pchd%(k,Npage%-1,Npchl%) = Cpch%(k,Npage%-1) NEXT k END IF GOSUB ShoPage END IF ' CASE ELSE PRINT "Unknown menuitem: ";menuitem ' END SELECT ' RETURN ' '----------------------------------------------------------------- ' UDLinkCmd: SELECT CASE menuitem ' CASE 1 'UpLink All CLS PRINT "Uplinking all Patches; Starting Load....." DSR6% = 100 ' Code to uplink all patches DSR4% = 0 ' Uplink DSRRequestSize% = 7 GOSUB DmpRqst Nexpt% = 13 GOSUB SysExh NQQ% = 0 FOR n = 1 TO Npchm% P1L% = n GOSUB ReadIn PRINT n;" "; NQQ% = NQQ% + 1 IF NQQ% >= 10 THEN NQQ% = 0 PRINT END IF NEXT n PRINT CALL MIDIin(En%) Npage% = 0 MENU 4,NEditItem%,0 MENU 4,Mxp%,1 MENU 4,1,2 MENU 2,11,0 MENU 2,12,0 Mxp% = 1 GOSUB ShoPage ' CASE 2 ' UpLink Patch Npchd% = Npchl% Mkw: WINDOW 2,"UpLink",(70,200)-(430,350),2 CALL TEXTFACE(1) PRINT " "; CALL TEXTFACE(5) PRINT "Patch Load/Store" CALL TEXTFACE(1) Npchlc$ = STR$(Npchd%) EDIT FIELD 1,Npchlc$,(5,50)-(55,65) Npchld$ = STR$(Npchl%) EDIT FIELD 2,Npchld$,(5,100)-(55,115) CALL MOVETO(70,62) PRINT "Interface Patch# to Load" CALL MOVETO(70,112) PRINT "As Patch# in File" BUTTON 1,1,"OK",(320,130)-(350,145) CALL TEXTFACE(0) Idle1: Act = DIALOG(0) IF (Act <> 1) AND (Act <> 6) GOTO Idle1 Npchl% = VAL(EDIT$(2)) Npchd% = VAL(EDIT$(1)) Lgd% = 0 IF (Npchl% > Npchm%) THEN Npchl% = Npchm% BEEP Lgd% = 1 END IF IF (Npchd% > Npchm%) THEN Npchd% = Npchm% BEEP Lgd% = 1 END IF IF (Npchl% < 1) THEN Npchl% = 1 BEEP Lgd% = 1 END IF IF (Npchd% < 1) THEN Npchd% = 1 BEEP Lgd% = 1 END IF WINDOW CLOSE 2 IF Lgd% = 1 GOTO Mkw DSR6% = Npchd% - 1 DSR4% = 0 DSRRequestSize% = 7 CLS GOSUB DmpRqst Nexpt% = 13 GOSUB SysExh P1L% = Npchl% GOSUB ReadIn CALL MIDIin(En%) GOSUB ShoPage ' CASE 3 ' UpLink current Patch Npchd% = Npchl% DSR6% = 101 ' code to uplink all patches DSR4% = 0 DSRRequestSize% = 7 CLS GOSUB DmpRqst Nexpt% = 13 GOSUB SysExh P1L% = Npchl% GOSUB ReadIn CALL MIDIin(En%) GOSUB ShoPage ' CASE 5 'Downlink All CLS PRINT "DownLinking All Patches; Starting Load......" DSR6% = 100 DSR4% = 1 DSRRequestSize% = 6 GOSUB DmpRqst Junk$ = SPACE$(6) result% = 0 ggx: CALL GetMIDI(Junk$,0,count%,result%) ' Cut off echos IF count% <> 0 GOTO contx GOSUB Waitx GOTO ggx contx: NQQ% = 0 FOR n = 1 TO Npchm% P1L% = n Npchd% = n GOSUB RdOut PRINT n;" "; NQQ% = NQQ% + 1 IF NQQ% >= 10 THEN NQQ% = 0 PRINT END IF NEXT n PRINT GOSUB VerifyAckNak GOSUB ShoPage ' CASE 8 'Downlink current patch Npchd% = Npchl% DSR6% = 101 DSR4% = 1 DSRRequestSize% = 6 CLS GOSUB DmpRqst Junk$ = SPACE$(6) result% = 0 gg1: CALL GetMIDI(Junk$,0,count%,result%) ' Cut off echos IF count% <> 0 GOTO cont1 GOSUB Waitx GOTO gg1 cont1: P1L% = Npchl% GOSUB RdOut PRINT "Patch sent out" GOSUB VerifyAckNak GOSUB ShoPage ' CASE ELSE IF menuitem = 6 OR menuitem = 7 THEN 'Downlink Patch Npchd% = Npchl% Mkw1: WINDOW 2,"DownLink",(70,200)-(430,350),2 CALL TEXTFACE(1) PRINT " "; CALL TEXTFACE(5) PRINT "Patch DownLoad from File" CALL TEXTFACE(1) Npchlc$ = STR$(Npchd%) EDIT FIELD 1,Npchlc$,(5,50)-(55,65) Npchld$ = STR$(Npchl%) EDIT FIELD 2,Npchld$,(5,100)-(55,115) CALL MOVETO(70,62) PRINT "Patch# in File" CALL MOVETO(70,112) PRINT "To Load as Patch# in Interface" BUTTON 1,1,"OK",(320,130)-(350,145) CALL TEXTFACE(0) Idle2: Act = DIALOG(0) IF (Act <> 1) AND (Act <> 6) GOTO Idle2 Npchl% = VAL(EDIT$(1)) Npchd% = VAL(EDIT$(2)) Lgd% = 0 IF (Npchl% > Npchm%) THEN Npchl% = Npchm% BEEP Lgd% = 1 END IF IF (Npchd% > Npchm%) THEN Npchd% = Npchm% BEEP Lge% = 1 END IF IF (Npchl% < 1) THEN Npchl% = 1 BEEP Lgd% = 1 END IF IF (Npchd% < 1) THEN Npchd% = 1 BEEP Lgd% = 1 END IF WINDOW CLOSE 2 IF Lgd% = 1 GOTO Mkw1 DSR6% = Npchd% - 1 DSR4% = 1 DSRRequestSize% = 6 CLS GOSUB DmpRqst Junk$ = SPACE$(6) result% = 0 gg2: CALL GetMIDI(Junk$,0,count%,result%) ' Cut off echos IF count% <> 0 GOTO cont2 GOSUB Waitx GOTO gg2 cont2: P1L% = Npchl% GOSUB RdOut PRINT "Patch sent out..." GOSUB VerifyAckNak IF menuitem = 7 THEN L1% = &HC0 + Chnl% CALL MIDIOut(L1%) L1% = Npchd% - 1 CALL MIDIOut(L1%) END IF GOSUB ShoPage END IF ' END SELECT ' RETURN ' '----------------------------------------------------------------- ' ReadIn: 'Read Patch data from Interface Chu$ = SPACE$(Ntp%) result% = 0 CALL GetMIDI(Chu$,1,count%,result%) IF result% = 1 THEN Tout: BEEP PRINT "MIDI Time-Out" PRINT "Too many Patches for Interface!!" PRINT "Patch attempted is:";P1L% INPUT " to continue:";A$ GOSUB ClearMIDI RETURN END IF Pcht$(P1L%) = MID$(Chu$,2,9) L% = 11 FOR k = 1 TO NL0% FOR j = 1 TO NL1%(k) A$ = MID$(Chu$,L%,1) Pchd%(j,k,P1L%) = ASC(A$) L% = L% + 1 NEXT j NEXT k RETURN ' '----------------------------------------------------------------- ' RdOut: 'Write Patch data to Interface Np% = Npchd% - 1 Chu$ = CHR$(Np%) Chu$ = Chu$ + Pcht$(P1L%) FOR k = 1 TO NL0% FOR j = 1 TO NL1%(k) Chu$ = Chu$ + CHR$(Pchd%(j,k,P1L%)) NEXT j NEXT k IF LEN(Chu$) <> Ntp% THEN BEEP PRINT "String Length:";LEN(Chu$);" Expected:";Ntp% INPUT " to continue:";A$ RETURN END IF CALL SendMIDI(Chu$,1) for nnq = 1 to 1000 ' delay for MIDI Time Piece r = sin(nnq*.001) next nnq result% = 0 icc% = 0 gg3: CALL incount(icc%) ' PRINT "Input Count on Echo:";icc% Chu$ = SPACE$(icc%) CALL GetMIDI(Chu$,1,count%,result%) ' Cut OFF echoes IF result% <> 0 GOTO cont3 GOSUB Waitx GOTO gg3 cont3: RETURN ' '----------------------------------------------------------------- ' VerifyAckNak: ' Terminate Write sequence and check Interface response PRINT NF7% = &HF7 CALL MIDIOut(NF7%) Chu$ = SPACE$(7) result% = 0 CALL GetMIDI(Chu$,0,count%,result%) IF result% = 1 THEN PRINT "Timed out on Ack/Nak Wait" INPUT " to continue:";A$ GOSUB ClearMIDI RETURN END IF PRINT "Ack/Nak Response: "; FOR i = 2 TO 7 A$ = MID$(Chu$,i,1) Ich% = ASC(A$) PRINT HEX$(Ich%);" "; IF i = 4 THEN Chnl% = Ich% IF i = 5 THEN Irsp% = Ich% NEXT i PRINT IF Irsp% = &H7E THEN BEEP PRINT "Problem... NAK received from Interface!!" PRINT "Turn write-protect off on Interface!" ELSEIF Irsp% = &H7F THEN PRINT "Load Accepted... ACK received from Interface" ELSE PRINT "Strange code: ";HEX$(Irsp%);" Recieved as ACK/NAK" END IF PRINT INPUT " to continue:";A$ RETURN END ' '----------------------------------------------------------------- ' PatchCmd: ' SELECT CASE menuitem ' CASE 1 ' Show Titles Npage% = 0 MENU 4,NEditItem%,0 MENU 4,Mxp%,1 MENU 4,menuitem,2 MENU 2,11,0 MENU 2,12,0 Mxp% = menuitem GOSUB ShoPage ' CASE 3 ' Load Patch# GOSUB GetPatch ' CASE 4 ' Next Patch Npchl% = Npchl + 1 IF Npchl% > Npchm% THEN BEEP Npchl% = Npchm% ELSE GOSUB ShoPage END IF ' CASE 5 ' Previous Patch Npchl% = Npchl% - 1 IF Npchl% <= 0 THEN BEEP Npchl% = 1 ELSE GOSUB ShoPage END IF ' CASE ELSE ' Change or Edit Page Mx% = menuitem - 6 IF Mx% <= 0 THEN 'Illegal value BEEP BEEP RETURN END IF ' IF Mx% <= NL0% + 1 THEN 'Change Page Npage% = Mx% MENU 4,NEditItem%,1 MENU 4,Mxp%,1 MENU 4,menuitem,2 MENU 2,11,1 MENU 2,12,1 Mxp% = menuitem GOSUB ShoPage ' ELSEIF menuitem = NEditItem% THEN ' Edit Page IF Npage% > 0 THEN ' IF Npage% = 1 THEN 'Title Page Wwx: WINDOW 2,"Patch Title Edit",(70,200)-(430,350),2 CALL TEXTFACE(1) PRINT " "; CALL TEXTFACE(5) PRINT "Edit Title of Patch# ";Npchl% CALL TEXTFACE(1) EDIT FIELD 1,Pcht$(Npchl%),(140,80)-(250,95) BUTTON 1,1,"OK",(320,130)-(350,145) CALL TEXTFACE(0) Idle3: Act = DIALOG(0) IF (Act <> 1) AND (Act <> 6) GOTO Idle3 C1$ = EDIT$(1) C1$ = UCASE$(C1$) WINDOW CLOSE 2 L1 = LEN(C1$) IF L1 > 9 THEN BEEP Pcht$(Npchl%) = "" FOR n = 1 TO 9 A$ = MID$(C1$,n,1) IF A$ = "" THEN A$ = " " Pcht$(Npchl%) = Pcht$(Npchl%) + A$ NEXT n IF L1 > 9 GOTO Wwx GOSUB ShoPage RETURN END IF ' Npp% = Npage% - 1 ' DATA Page CALL TEXTFACE(1) PRINT INPUT "Enter Item# to Edit:";Ie1% IF Ie1% > NL1%(Npp%) THEN Ie1% = NL1%(Npp) IF Ie1% <= 0 THEN Ie1% = 1 CALL TEXTFACE(0) Wwy: WINDOW 2,"Patch Item Edit",(70,200)-(430,350),2 PRINT " "; CALL TEXTFACE(5) PRINT L0T$(Npp%) CALL TEXTFACE(0) PRINT PRINT "Item Title: "; CALL TEXTFACE(1) PRINT L1T$(Ie1%,Npp%) ' IF L1F%(Ie1%,Npp%) > 0 THEN ' Character Options PRINT CALL TEXTFACE(0) PRINT "Options:"; PRINT " "; CALL TEXTFACE(1) FOR k = 0 TO L1L%(Ie1%,Npp%) PRINT Opt$(L1F%(Ie1%,Npp%) + k);" "; NEXT k Ipr% = L1F%(Ie1%,Npp%) + Pchd%(Ie1%,Npp%,Npchl%) IF Ipr% > Nopt% THEN Ipr% = Nopt% CALL MOVETO(70,114) PRINT "Current Value:" EDIT FIELD 1,Opt$(Ipr%),(180,100)-(260,115) BUTTON 1,1,"OK",(320,130)-(350,145) CALL TEXTFACE(0) Idle4: Act = DIALOG(0) IF (Act <> 1) AND (Act <> 6) GOTO Idle4 C1$ = EDIT$(1) C1$ = UCASE$(C1$) WINDOW CLOSE 2 It% = -1 FOR k = 0 TO L1L%(Ie1%,Npp%) IF C1$ = Opt$(L1F(Ie1%,Npp%) + k) THEN It% = k NEXT k IF It% = -1 THEN BEEP GOTO Wwy END IF Pchd%(Ie1%,Npp%,Npchl%) = It% GOSUB ShoPage RETURN ELSE ' PRINT ' Numeric Input Iofq% = -L1F%(Ie1%,Npp%) LuL% = L1L%(Ie1%,Npp%) IF (LuL% = -1) THEN LuL% = 255 CALL TEXTFACE(0) PRINT "Lower Limit:"; CALL TEXTFACE(1) PRINT Iofq% CALL TEXTFACE(0) PRINT "Upper Limit:"; CALL TEXTFACE(1) PRINT LuL% + Iofq% Nstuf$ = STR$(Pchd%(Ie1%,Npp%,Npchl%) + Iofq%) CALL TEXTFACE(1) CALL MOVETO(70,114) PRINT "Current Value:" EDIT FIELD 1,Nstuf$,(180,100)-(240,115) BUTTON 1,1,"OK",(320,130)-(350,145) CALL TEXTFACE(0) Idle5: Act = DIALOG(0) IF (Act <> 1) AND (Act <> 6) GOTO Idle5 C1$ = EDIT$(1) WINDOW CLOSE 2 Pchd%(Ie1%,Npp%,Npchl%) = VAL(C1$) - Iofq% IF Pchd%(Ie1%,Npp%,Npchl%) < 0 THEN BEEP Pchd%(Ie1%,Npp%,Npchl%) = 0 GOTO Wwy END IF IF Pchd%(Ie1%,Npp%,Npchl%) > LuL% THEN BEEP Pchd%(Ie1%,Npp%,Npchl%) = LuL% GOTO Wwy END IF GOSUB ShoPage RETURN END IF END IF ' END IF ' END SELECT ' RETURN ' '----------------------------------------------------------------- ' GetPatch: PRINT PRINT Ippc: INPUT "Enter Patch# to Load:";Npchl% IF Npchl% > Npchm% THEN BEEP GOTO Ippc END IF IF Npchl <= 0 THEN BEEP GOTO Ippc END IF GOSUB ShoPage RETURN ' '----------------------------------------------------------------- ' ShoPage: IF Npage% = 0 THEN ' Show all Titles CLS PRINT "Filename: "; CALL TEXTFACE(1) PRINT Filenick$;" "; CALL TEXTFACE(0) CALL TEXTFACE(4) PRINT "Resident Patches currently Loaded" CALL TEXTFACE(0) PRINT "---------------------------------------------------------------------------------" PRINT Lqqt% = 0 Nlp% = Npchm% GOSUB PrtTit RETURN END IF ' IF Npage% = 1 THEN 'Patch title,# CLS PRINT "Filename: "; CALL TEXTFACE(1) PRINT Filenick$;" "; CALL TEXTFACE(0) CALL TEXTFACE(4) PRINT "Title & Patch Number" CALL TEXTFACE(0) PRINT "-------------------------------------------------------------" LOCATE 12,1 PRINT PRINT " Patch #"; CALL TEXTFACE(1) PRINT Npchl% CALL TEXTFACE(0) PRINT PRINT PRINT " Title: "; CALL TEXTFACE(1) PRINT Pcht$(Npchl%) CALL TEXTFACE(0) RETURN END IF ' Npp% = Npage% - 1 IF (Npp% <= NL0%) THEN CLS PRINT "Filename: "; CALL TEXTFACE(1) PRINT Filenick$;" "; CALL TEXTFACE(0) PRINT "Patch# ";Npchl%;" "; CALL TEXTFACE(1) PRINT Pcht$(Npchl%) CALL TEXTFACE(0) PRINT "-------------------------------------------------------------" PRINT CALL TEXTFACE(4) PRINT "Page# ";Npp%; CALL TEXTFACE(0) PRINT " "; CALL TEXTFACE(4) PRINT "Title: "; CALL TEXTFACE(5) PRINT L0T$(Npp%) CALL TEXTFACE(0) PRINT CALL TEXTSIZE(9) FOR K0% = 1 TO NL1%(Npp%) I0% = 0 IF L1F%(K0%,Npp%) < 0 THEN I0% = -L1F%(K0%,Npp%) IF L1F%(K0%,Npp%) > 0 THEN I0X% = L1F%(K0%,Npp%) + Pchd%(K0%,Npp%,Npchl%) IF I0X% > Nopt% THEN I0X% = Nopt% Opxx$ = Opt$(I0X%) ELSE Opxx$ = "" END IF PRINT K0%,L1T$(K0%,Npp%),Pchd%(K0%,Npp%,Npchl%) + I0%,Opxx$ NEXT K0% CALL TEXTSIZE(12) RETURN ' ELSE BEEP 'Menuitem out of range END IF ' RETURN ' '----------------------------------------------------------------- ' PrintCmd: IF menuitem <> 6 THEN OPEN "LPT1:" FOR OUTPUT AS #2 Pnpch% = Npchl% END IF ' SELECT CASE menuitem ' CASE 1 'Print titles Npprt% = 0 GOSUB PrtPage ' CASE 2 'Print current Page Npprt% = Npage% GOSUB PrtPage ' CASE 3 'Print current Patch FOR Npprt% = 2 TO NL0% + 1 GOSUB PrtPage IF Ifff = 1 THEN PRINT #2,CHR$(12) 'Form Feed ELSE PRINT #2, PRINT #2, PRINT #2, END IF NEXT Npprt% ' CASE 4 'Print all patches PRINT CALL TEXTFACE(0) INPUT "Start printing at patch#: ";IBGP% INPUT "Stop printing at patch#: ";ISGP% CALL TEXTFACE(0) IF ISGP% > Npchm% THEN ISGP% = Npchm% IF IBGP% < 1 THEN IBGP% = 1 FOR Pnpch% = IGBP% TO ISGP% FOR Npprt% = 2 TO NL0% + 1 GOSUB PrtPage IF Ifff = 1 THEN PRINT #2,CHR$(12) 'Form Feed ELSE PRINT #2, PRINT #2, PRINT #2, END IF NEXT Npprt% NEXT Pnpch% PRINT ' CASE 6 'Toggle FF char. Ifff = 1 - Ifff MENU 5,6,Ifff+1 RETURN ' CASE ELSE 'Bad code BEEP ' END SELECT ' CLOSE #2 RETURN ' '----------------------------------------------------------------- ' PrtPage: IF Npprt% = 0 THEN ' Show all Titles PRINT #2,"Filename: "; CALL TEXTFACE(1) PRINT #2,Filenick$;" "; CALL TEXTFACE(0) CALL TEXTFACE(4) PRINT #2,"Resident Patches currently Loaded" CALL TEXTFACE(0) PRINT #2,"---------------------------------------------------------------------------------" PRINT #2, Nlp% = Npchm% GOSUB PrtTip RETURN END IF ' IF Npprt% = 1 THEN 'Patch title,# PRINT #2,"Filename: "; CALL TEXTFACE(1) PRINT #2,Filenick$;" "; CALL TEXTFACE(0) CALL TEXTFACE(4) PRINT #2,"Title & Patch Number" CALL TEXTFACE(0) PRINT #2,"-------------------------------------------------------------" LOCATE 12,1 PRINT #2, PRINT #2," Patch #"; CALL TEXTFACE(1) PRINT #2,Pnpch% CALL TEXTFACE(0) PRINT #2, PRINT #2, PRINT #2," Title: "; CALL TEXTFACE(1) PRINT #2,Pcht$(Pnpch%) CALL TEXTFACE(0) RETURN END IF ' Npp% = Npprt% - 1 IF (Npp% <= NL0%) THEN PRINT #2,"Filename: "; CALL TEXTFACE(1) PRINT #2,Filenick$;" "; CALL TEXTFACE(0) PRINT #2,"Patch# ";Pnpch%;" "; CALL TEXTFACE(1) PRINT #2,Pcht$(Pnpch%) CALL TEXTFACE(0) PRINT #2,"-------------------------------------------------------------" PRINT #2, PRINT #2, CALL TEXTFACE(4) PRINT #2,"Page# ";Npp%; CALL TEXTFACE(0) PRINT #2," "; CALL TEXTFACE(4) PRINT #2,"Title: "; CALL TEXTFACE(5) PRINT #2,L0T$(Npp%) CALL TEXTFACE(0) PRINT #2, FOR K0% = 1 TO NL1%(Npp%) I0% = 0 IF L1F%(K0%,Npp%) < 0 THEN I0% = -L1F%(K0%,Npp%) IF L1F%(K0%,Npp%) > 0 THEN I0X% = L1F%(K0%,Npp%) + Pchd%(K0%,Npp%,Pnpch%) IF I0X% > Nopt% THEN I0X% = Nopt% Opxx$ = Opt$(I0X%) ELSE Opxx$ = "" END IF PRINT #2,K0%,L1T$(K0%,Npp%),Pchd%(K0%,Npp%,Pnpch%) + I0%,Opxx$ NEXT K0% RETURN ' ELSE BEEP 'Menuitem out of range END IF ' RETURN ' '----------------------------------------------------------------- ' PrtTip: ' print #2s out all Patch Titles nicely on Lpt N1% = Nlp%/Ntd% N2% = N1% * Ntd% IF (N2% < Nlp%) THEN N1% = N1% + 1 FOR n = 1 TO N1% N3% = (n - 1) * Ntd% + 1 N4% = N3% + Ntd% - 1 Itbb% = 0 FOR m = N3% TO N4% PRINT #2,TAB(Itbb%);m;TAB(Itbb% + 5);Pcht$(m); Itbb% = Itbb% + 15 NEXT m PRINT #2, NEXT n RETURN ' '----------------------------------------------------------------- ' MIDICmd: SELECT CASE menuitem CASE 1 :GOSUB DoModem CASE 2 :GOSUB DoPrinter CASE 4 : GOSUB DoHalfMeg CASE 5 :GOSUB DoOneMeg CASE 6 :GOSUB DoTwoMeg CASE 8 :GOSUB ClearMIDI CASE ELSE PRINT "Undefined menu item." END SELECT PRINT "Reseting Interface" CALL MIDIPort(clockRate%) 'reset the MIDI clock rate CALL MIDIPort(port%) 'reset the MIDI port RETURN '----------------------------------------------------------------- DoBreak: PRINT PRINT "Leaving 4-Voice Patch Editor/Librarian...." ' use this to close MIDIBASIC when compiled as a stand-alone application ' IF compiled% THEN CALL Libterm CALL Libterm STOP '----------------------------------------------------------------- SysExh: ' Read sysex dump header from Interface Nxh$ = SPACE$(Nexpt) ' Total bytes read in echo of old cmd. (7) plus new header (6) count% = 0 result% = 0 CALL GetMIDI(Nxh$,0,count%,result%) IF result% = 1 THEN PRINT "Time-out in getting Sysex Header" PRINT "Count is:";count% GOSUB ClearMIDI END IF PRINT "Header Return: "; FOR n = 1 TO 13 A$ = MID$(Nxh$,n,1) PRINT HEX$(ASC(A$));" "; NEXT n PRINT RETURN ' '--------------------------------------------------------------- DmpRqst: DSRRequest(6) = DSR6% DSRRequest(4) = DSR4% PRINT ,"Sending Dump Request "; GOSUB ClearMIDI ByteCount = DSRRequestSize% FOR j = 1 TO ByteCount X% = DSRRequest(j) MIDIOut X% PRINT " " HEX$(X%); NEXT j PRINT RETURN '--------------------------------------------------------------- 'MIDI MENU Item Subroutines ' '--------------------------------------------------------------- ' DoModem: 'PRINT "Modem is not implemented" MENU 6,1,checkon 'reset modem item check mark MENU 6,2, checkoff 'reset printer item checmark port% = modem% RETURN ' '--------------------------------------------------------------- ' DoPrinter: 'PRINT "Printer is not implemented" MENU 6,1,checkoff 'reset modem item check mark MENU 6,2, checkon 'reset printer item checmark port% = printer% RETURN '--------------------------------------------------------------- ' DoHalfMeg: 'PRINT ".5 mHz is not implemented" MENU 6,4,checkon 'reset .5 mHz item check mark MENU 6,5, checkoff 'reset 1 mHz item checmark MENU 6,6, checkoff 'reset 2 mHz item checmark clockRate% = halfMeg% RETURN '--------------------------------------------------------------- ' DoOneMeg: ' PRINT "1 mHz is not implemented" MENU 6,4,checkoff 'reset .5 mHz item check mark MENU 6,5, checkon 'reset 1 mHz item checmark MENU 6,6, checkoff 'reset 2 mHz item checmark clockRate% = oneMeg% RETURN '--------------------------------------------------------------- ' DoTwoMeg: ' PRINT "2 mHz is not implemented" MENU 6,4,checkoff 'reset .5 mHz item check mark MENU 6,5, checkoff 'reset 1 mHz item checmark MENU 6,6, checkon 'reset 2 mHz item checmark clockRate% = twoMeg% RETURN INITMIDI: CALL MIDIopen(maxBufferSize%,maxBufferSize%) CALL MIDIFilter(1,254,254,0) 'Filter out active sensing !! CALL MIDIPort(clockRate%) CALL MIDIPort(port%) GOSUB ClearMIDI RETURN ClearMIDI: CALL MIDI(ClearIn%) CALL MIDI(ClearOut%) RETURN '---------------------------------------------------------------------- ' window routine SUB centerWindow(id%,Title$,high%,wide%,type%,fract!)STATIC SELECT CASE ABS(type%) CASE 1 :overt%=18 :overb%=2 CASE 2 :overt%=8 :overb%=8 CASE ELSE :overt%=0 :overb%=0 END SELECT left%=(SYSTEM(5)-(wide%))/2 top%=PEEKW(&HBAA)+overt%*fract!+(SYSTEM(6)-(PEEKW(&HBAA)+high%+overb%))*fract! WINDOW id%,Title$,(left%,top%)-(left%+wide%,top%+high%),type% END SUB