home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Crawly Crypt Collection 2
/
crawlyvol2.bin
/
sound
/
psslib2
/
psslib.lst
< prev
next >
Wrap
File List
|
1994-05-08
|
171KB
|
4,786 lines
' ***********************************************************************
' YAMAHA PATCH EDITOR/LIBRARIAN FOR THE PSS PORTASOUND SERIES *
' *
' PROGRAMMED IN GFA BASIC 3.07 *
' BY MICHAEL SILVERSTEIN *
' *
' VERSION: 2.00 *
' DATE: 07/20/92 *
' FIXED CHECK_CONNECTION ROUTINE - PROGRAM RUNS *
' SLIGHTLY SLOWER DUE TO CLEARING MIDI BUFFER TO *
' PROPERLY HANDLE ACTIVE SENSING. *
' ADDED MALLOC ROUTINES FOR BETTER VERSATILITY. *
' DELETED OLD C ROUTINES AND USED GFA ROUTINES TO *
' CHANGE SYSTEM MIDI BUFFER SIZE VIA XBIOS 14. *
' DATE: 06/19/93 *
' DELETED THE USAGE OF THE RESERVE COMMAND WHEN *
' PERFORMING AN EXEC TO THE LZH ARCHIVER FOR *
' COMPATABILITY WITH CODEHEAD'S MIDI SPY. *
' NOW USING THE COMPILER $M COMMAND! *
' ADDED CHANNELIZATION WHEN SENDING PROGRAM CHANGES *
' AND/OR THE PATCHES TO THE SYNTH (I.E. BANK 1 IS *
' CHANNEL 1, BANK 2 IS CHANNEL 2, ETC.) *
' TURNED MOUSE OFF WHEN DOING A VERBOSE LIST OF THE *
' SYSTEM MIDI ARCHIVE. *
' DATE: 07/21/93 *
' INCREASED COMPILER ($M) DIRECTIVE SINCE RECEIVING *
' MIDI CAUSED HELP/DIALOG BOXES TO CAUSE ERRORS. *
' DATE: 01/28/94 *
' COMPILED WITH INTERRUPTS (I+) SET FOR LESS CHANCE *
' OF RECEIVE CHECKSUM ERRORS WHEN MANY TSR'S ARE *
' LOADED IN AUTO FOLDER. ALSO, FIXED A BUG WHICH *
' CAUSED THE PROGRAM TO HANG WHEN ATTEMPTING TO *
' QUIT.
' DATE: 04/24/94 *
' ADDED EXPORTING OF PATCH WHEN SAVING. A FILE WILL *
' BE CREATED WITH A .SYX EXTENSION. THIS WILL *
' INCLUDE THE SYSEX HEADER/TAILOR BYTES TO BE USED *
' WITH OTHER MIDI PROGRAMS, SEQUENCERS. *
' *
' ADDED IMPORTING/EXPORTING CUSTOM DRUMMER INFO *
' (THE LAST SYSEX MESSAGE) BY UPDATING THE SYSTEM *
' MIDI BUFFER TO 13,800 BYTES. THESE FUNCTIONS WILL*
' ALSO USE THE FILE SELECTOR TO LOAD OR SAVE A *
' DRUMMER FILE WITH A .SYX EXTENSION. THE ONLINE *
' HELP AND KEYBOARD EQUIVALENTS WERE MODIFIED TO *
' REFLECT THESE CHANGES. NOTE THAT IMPORTING WORKS *
' FOR PATCHES AS WELL AS THE CUSTOM DRUMMER. *
' *
' RESTORING THE ORIGINAL MIDI BUFFER IS NOW ITS OWN *
' ROUTINE AND IS CALLED AFTER A SUCCESSFUL RECEPTION*
' OF MIDI DATA. THIS WAS DONE SINCE THE MIDI BUFFER*
' WAS NOT GETTING RESTORED CORRECTLY WHEN QUITTING *
' THE PROGRAM DUE TO TOO MANY CHANGES WITH THE *
' SYSTEM BUFFER. *
' *
' NOW USING THE EVNT_TIMER (AES) LIBRARY ROUTINE *
' WHEN CHECKING FOR ACTIVE SENSING. THIS WAS FOUND *
' TO WORK MUCH BETTER SINCE THE PAUSE COMMAND WAS *
' CAUSING TOO MUCH DELAY WITH GFA MENU SELECTIONS. *
' *
' A NEW AUDITION MODE WAS IMPLEMENTED WHICH WILL *
' PLAY 3 MIDI NOTES WHEN ISSUING A 'SEND' COMMAND *
' TO THE YAMAHA. THIS MODE MAY BE TOGGLED AND AN *
' INPUT DIALOG BOX ALLOWS YOU TO SPECIFY THE TOTAL *
' TIME (IN SECONDS)TO AUDITION EACH NOTE, WITH *
' VALUES OF 3, 9, 21 AND 30 SECONDS AS CHOICE *
' OPTIONS. A KEY EQUIVALENT FEATUE IS ALSO *
' SUPPORTED AND A POPUP STATUS DISPLAY WILL INDICATE*
' WHEN EACH NOTE (LOW, MEDIUM, HIGH) NOTE IS SENT. *
' *
' FINALLY FIXED THE 'FILE DOESN'T EXIST' BUG WHEN *
' USING THE FILESELECT CALL TO GET A PATCH NAME OR *
' .SYX FILE. IF THE NAME DOESN'T EXIST, THE ROUTINE*
' WILL KEEP LOOPING UNTIL A VALID NAME IS ENTERED *
' OR THE USER CAN BAIL OUT VIA THE CANCEL BUTTON. *
' *
' UPDATED CERTAIN SCREENS SUPPORTING HI REZ MONO- *
' CHROME. *
' *
' MADE SURE THAT A .SYX DOESN'T ACCIDENTALLY GET *
' DELETED IF USER SELECTS TO LOAD A PATCH (FROM *
' ARCHIVE). AN ERROR MESSAGE IS DISPLAYED TO USE *
' IMPORT FOR THIS FEATURE. *
' ***********************************************************************
'
' ***********************************************************************
' CHECK REZ, INITIALIZE GEM MENU, MOUSE POINTER, ETC.
' ***********************************************************************
'
rez=XBIOS(4)
IF rez=0 THEN
ALERT 3,"Sorry, this program does not|run in low resolution",1,"OK",b
END
ENDIF
GRAPHMODE 1 ! mode for text graphics
DEFMOUSE 3 ! pointing hand mouse cursor
init_buffer ! initialize system MIDI buffer array
init_parameters ! initialize all Patch parameters
midi.buff.adr=0 ! initialize system midi buffer address
auditon_flag=FALSE ! initialize audition flag to OFF
midi_delay=0 ! initialize note on delay value to OFF
$m200000 ! reserve 200K for PSSLIB and LHA
no_connection=TRUE ! initialize MIDI connection flag to ON
DIM m$(100) ! setup for GEM menu
m$(0)="Desk "
m$(1)=" About Program "
m$(2)="-----------------------"
m$(3)="1"
m$(4)="2"
m$(5)="3"
m$(6)="4"
m$(7)="5"
m$(8)="6"
m$(9)=""
m$(10)="File"
m$(11)=" Load Patch "
m$(12)=" Save Patch "
m$(13)=" Delete Patch "
m$(14)=" Build Patch "
m$(15)=" Verbose Directory"
m$(16)=" Quit "
m$(17)=""
m$(18)="Buffer"
m$(19)=" View in Bytes "
m$(20)=""
m$(21)="MIDI"
m$(22)=" Send Bank 1 "
m$(23)=" Send Bank 2 "
m$(24)=" Send Bank 3 "
m$(25)=" Send Bank 4 "
m$(26)=" Send Bank 5 "
s$="modulation"
m$(27)="----------------"
m$(28)=" Receive Bank 1 "
m$(29)=" Receive Bank 2 "
m$(30)=" Receive Bank 3 "
m$(31)=" Receive Bank 4 "
m$(32)=" Receive Bank 5 "
m$(33)="----------------"
m$(34)=" Import .SYX "
m$(35)=" Export Drum "
m$(36)="----------------"
m$(37)=" Audition "
m$(38)=""
m$(39)="Modulation"
m$(40)=" Leveling "
m$(41)=" AM/FM "
m$(42)=""
m$(43)="Modulator"
m$(44)=" Define Waveform "
m$(45)=" Tuning "
m$(46)=" Frequency Multiplier"
t$="midilation"
m$(47)=" LKS/RKS "
m$(48)=" Enveloping "
m$(49)=""
m$(50)="Carrier"
m$(51)=" Define Waveform "
m$(52)=" Tuning "
m$(53)=" Frequency Multiplier"
m$(54)=" LKS/RKS "
m$(55)=" Enveloping "
m$(56)=""
m$(57)="Help "
m$(58)=" General"
m$(59)=" File "
m$(60)=" Buffer "
m$(61)=" MIDI "
m$(62)=" Modulation"
m$(63)=" Modulator/Carrier"
m$(64)=" Key Equivalents"
MENU m$() ! Display Menu
IF s$<>t$
demo_mode=TRUE
ELSE
demo_mode=FALSE
ENDIF
about_editor_librarian
check_viewmode
' ***********************************************************************
' TURN OFF SAVE,MIDI EDIT PARAMETERS
' ***********************************************************************
MENU 12,2
FOR i=39 TO 55
MENU i,2
NEXT i
' ***********************************************************************
' XFER PROGRAM CONTROL TO GEM MENU
' ***********************************************************************
ON MENU GOSUB main
DO
check_connection !Check for MIDI connection
IF audition_flag
MENU 37,1 !Toggle Audition Mode (checked)
ELSE
MENU 37,0 !Toggle Audition Mode (unchecked)
ENDIF
ON MENU KEY GOSUB key_value !Check Key Equivalents
ON MENU
SHOWM !Show mouse pointer
LOOP
' ***********************************************************************
' MAIN GEM MENU ROUTINE - CALL ROUTINES BASED ON PULL DOWN MENUS
' ***********************************************************************
PROCEDURE main
button=MENU(0)
MENU OFF
SELECT button
CASE 1
about_editor_librarian
CASE 16
' ***********************************************************************
' Quit Selection
' ***********************************************************************
ALERT 2,"Are you Sure?",1,"yes|no",b
SELECT b
CASE 1
END
CASE 2
ENDSELECT
CASE 14
' ***********************************************************************
' Build Selection
' ***********************************************************************
init_buffer ! reinitialize system MIDI buffer
check_viewmode
CASE 19
' ***********************************************************************
' View Selection
' ***********************************************************************
flag=NOT (flag) ! complement viewmode flag
IF m$(19)=" View in Bytes " THEN ! change view mode according to flag
m$(19)=" View Parameters "
view_bytes
ELSE
IF m$(19)=" View Parameters " THEN
m$(19)=" View in Bytes "
view_parameters
ENDIF
ENDIF
CASE 45
' ***********************************************************************
' Tune Modulator Selection(Fine/Course Detune)
' ***********************************************************************
tune_modulator(cdt_mod,d1r_mod,am_en_mod)
PAUSE 10
check_viewmode
CASE 52
' ***********************************************************************
' Tune Carrier Selection(Fine/Course Detune)
' ***********************************************************************
tune_carrier(cdt_car,d1r_car,am_en_car)
PAUSE 10
check_viewmode
CASE 46
' ***********************************************************************
' Frequency Multiply Modulator Selection
' ***********************************************************************
freq_modulator ! Frequency Multiply Modulator
PAUSE 10
check_viewmode
CASE 53
' ***********************************************************************
' Frequency Multiply Carrier Selection
' ***********************************************************************
freq_carrier ! Frequency Multiply Carrier
PAUSE 10
check_viewmode
CASE 40
' ***********************************************************************
' Leveling Selection
' ***********************************************************************
leveling ! Do leveling parameters
PAUSE 10
check_viewmode
CASE 47
' ***********************************************************************
' Level/Rate Key Scale Modulator Selection
' ***********************************************************************
lks_rks_modulator(rks_mod,atk_mod)
check_viewmode
CASE 54
' ***********************************************************************
' Level/Rate Key Scale Carrier Selection
' ***********************************************************************
lks_rks_carrier(rks_car,atk_car)
PAUSE 10
check_viewmode
' ***********************************************************************
' Enveloping for Modulator Selection
' ***********************************************************************
CASE 48
envelope_mod(rks_mod,atk_mod,d1r_mod,am_en_mod,cdt_mod,d2r_mod,wavform_mod)
PAUSE 10
check_viewmode
CASE 55
' ***********************************************************************
' Enveloping for Carrier Selection
' ***********************************************************************
envelope_car(rks_car,atk_car,d1r_car,am_en_car,cdt_car,d2r_car,wavform_car)
PAUSE 10
check_viewmode
CASE 44
' ***********************************************************************
' Define Basic Waveform Shape for Modulator Selection
' ***********************************************************************
wave_mod(wavform_mod,d2r_mod)
PAUSE 10
check_viewmode
CASE 51
' ***********************************************************************
' Define Basic Waveform Shape for Carrier Selection
' ***********************************************************************
wave_car(wavform_car,d2r_car)
PAUSE 10
check_viewmode
CASE 41
' ***********************************************************************
' AM/FM Parameters Selection
' ***********************************************************************
am_fm
PAUSE 10
check_viewmode
CASE 22
' ***********************************************************************
' Send Midi Patch Buffer to Bank 1 Selection
' ***********************************************************************
send_1
'
CASE 23
' ***********************************************************************
' Send Midi Patch Buffer to Bank 2 Selection
' ***********************************************************************
send_2
'
CASE 24
' ***********************************************************************
' Send Midi Patch Buffer to Bank 3 Selection
' ***********************************************************************
send_3
'
CASE 25
' ***********************************************************************
' Send Midi Patch Buffer to Bank 4 Selection
' ***********************************************************************
send_4
'
CASE 26
' ***********************************************************************
' Send Midi Patch Buffer to Bank 5 Selection
' ***********************************************************************
send_5
'
CASE 28
' ***********************************************************************
' Receive from Banks 1 thru 5 to MIDI Patch Buffer Selections
' ***********************************************************************
bank=1
midi_ready_prompt(bank) ! receive from bank 1 to buffer
CASE 29
bank=2
midi_ready_prompt(bank) ! receive from bank 2 to buffer
CASE 30
bank=3
midi_ready_prompt(bank) ! receive from bank 3 to buffer
CASE 31
bank=4
midi_ready_prompt(bank) ! receive from bank 4 to buffer
CASE 32
bank=5
midi_ready_prompt(bank) ! receive from bank 5 to buffer
CASE 34
' ***********************************************************************
' Import Custom Drummer or Patch .SYX SYSEX files
' ***********************************************************************
send_drummer
check_viewmode
CASE 35
' ***********************************************************************
' Export Yamaha Custom Drummer to .SYX SYSEX file
' ***********************************************************************
receive_drummer
check_viewmode
CASE 37
' ***********************************************************************
' Configure Audition Mode when sending out MIDI patch data
' ***********************************************************************
IF audition_flag THEN
MENU 37,0 !Toggle Audition Menu check off
audition_flag=FALSE !Clear Audition Flag
midi_delay=0
ELSE
MENU 37,1 !Toggle Audition Menu check on
audition_flag=TRUE !Set Audition Flag
delay_note_on(midi_delay) !Get note on delay value
ENDIF
CASE 12
' ***********************************************************************
' Save Patch to Disk Archive Selection
' ***********************************************************************
IF demo_mode
ALERT 1,"Sorry, this is a DEMO!|You cannot save your work.",1,"Will pay!",b
ELSE
patch_save
check_viewmode
ENDIF
CASE 11
' ***********************************************************************
' Load Patch from Disk Archive Selection
' ***********************************************************************
patch_load
check_viewmode
CASE 13
' ***********************************************************************
' Delete Patch from Disk Archive Selection
' ***********************************************************************
patch_delete
check_viewmode
CASE 15
' ***********************************************************************
' Verbose directory from Disk Archive Selection
' ***********************************************************************
verbose
check_viewmode
CASE 58
about_general
CASE 59
about_file
CASE 60
about_buffer
CASE 61
about_midi
CASE 62
about_modulation
CASE 63
about_mod_car
CASE 64
about_key_equiv
ENDSELECT
'
' ***********************************************************************
' TURN OFF/ON APPROPRIATE SELECTIONS BASED ON THE MAIN DROP-DOWN MENU
' SELECTIONS.
' ***********************************************************************
SELECT button
CASE 11 TO 14 ! turn off 'save' when 'load' 'save'
MENU 12,2 ! 'build','delete
ENDSELECT
SELECT button
CASE 39 TO 55 ! turn off 'load' 'delete' and 'receive'
MENU 11,2 ! when editing all parameters
MENU 13,2
FOR i=28 TO 32 ! turn off Receive MIDI banks
MENU i,2
NEXT i
MENU 35,2 !turn off Receive Custom Drummer
ENDSELECT
SELECT button
CASE 22 TO 26 ! turn on 'load 'delete' and 'receive'
MENU 11,3 ! after sending to Yamaha
MENU 13,3
FOR i=28 TO 32
MENU i,3
NEXT i
MENU 35,3
ENDSELECT
SELECT button
CASE 28 TO 32 ! turn off 'load 'delete'and 'build' after
MENU 11,2 ! receiving from Yamaha
MENU 13,2
MENU 14,2
ENDSELECT
RETURN
'
' ***********************************************************************
' CHECK FOR YAMAHA KEYBOARD INSTRUMENT
' ***********************************************************************
'
PROCEDURE check_connection
'
buffer$=INPMID$ ! clear midi buffer
timer=EVNT_TIMER(300) ! delay 300ms for active sense
IF INP?(3)=-1 THEN ! turn on 'send' and 'receive' when
active_sense$=HEX$(INP(3))
IF active_sense$="FE" THEN
FOR i=22 TO 37 ! Yamaha is turned on or plugged in
MENU i,3
NEXT i
no_connection=FALSE ! clear flag
ENDIF
ELSE
FOR i=22 TO 37 ! Yamaha is not turned on or plugged in
MENU i,2
NEXT i
no_connection=TRUE ! set flag
audition_flag=FALSE ! clear flag
ENDIF
'
RETURN
'
' ***********************************************************************
' KEY-VALUE SIMULATES THE GEM DROP DOWN MENU WITH KEYBOARD EQUIVALENT KEYS.
' THIS IS ACCOMPLISHED VIA OBTAINING SCAN CODES,ASCII CODES (MENU(14)
' AND ALT/CONTROL CODES (MENU (13) OF AN INPUT KEY AND PERFORMING A MOD
' 256 TO GET THE ASCII CODE AND A DIV 256 TO GET THE SCAN CODE.
' ***********************************************************************
'
PROCEDURE key_value
'
x=MENU(13)
y=MENU(14)
z=256
IF (y MOD z=49) AND (y DIV z=109) !Numeric 1
SELECT no_connection
CASE -1
ALERT 1,"No MIDI connection!|Check power or MIDI chords.",1,"OK",b
GOTO end_key_value
CASE 0
OUT 3,&HC0
OUT 3,100
CLS
MENU m$()
PRINT AT(25,15);"Sent Program Change to Bank 1.";
ENDSELECT
ENDIF
IF (y MOD z=50) AND (y DIV z=110) !Numeric 2
SELECT no_connection
CASE -1
ALERT 1,"No MIDI connection!|Check power or MIDI chords.",1,"OK",b
GOTO end_key_value
CASE 0
OUT 3,&HC0
OUT 3,101
CLS
MENU m$()
PRINT AT(25,15);"Sent Program Change to Bank 2.";
ENDSELECT
ENDIF
IF (y MOD z=51) AND (y DIV z=111) !Numeric 3
SELECT no_connection
CASE -1
ALERT 1,"No MIDI connection!|Check power or MIDI chords.",1,"OK",b
GOTO end_key_value
CASE 0
OUT 3,&HC0
OUT 3,102
CLS
MENU m$()
PRINT AT(25,15);"Sent Program Change to Bank 3.";
ENDSELECT
ENDIF
IF (y MOD z=52) AND (y DIV z=106) !Numeric 4
SELECT no_connection
CASE -1
ALERT 1,"No MIDI connection!|Check power or MIDI chords.",1,"OK",b
GOTO end_key_value
CASE 0
OUT 3,&HC0
OUT 3,103
CLS
MENU m$()
PRINT AT(25,15);"Sent Program Change to Bank 4.";
ENDSELECT
ENDIF
IF (y MOD z=53) AND (y DIV z=107) !Numeric 5
SELECT no_connection
CASE -1
ALERT 1,"No MIDI connection!|Check power or MIDI chords.",1,"OK",b
GOTO end_key_value
CASE 0
OUT 3,&HC0
OUT 3,104
CLS
MENU m$()
PRINT AT(25,15);"Sent Program Change to Bank 5.";
ENDSELECT
ENDIF
IF (x=0) AND (y MOD z=0) AND (y DIV z=59) !F1
SELECT no_connection
CASE -1
ALERT 1,"No MIDI connection!|Check power or MIDI chords.",1,"OK",b
GOTO end_key_value
CASE 0
send_1
CLS
MENU m$()
PRINT AT(25,15);"Sent buffer to Bank 1. ";
ENDSELECT
ENDIF
IF (x=0) AND (y MOD z=0) AND (y DIV z=60) !F2
SELECT no_connection
CASE -1
ALERT 1,"No MIDI connection!|Check power or MIDI chords.",1,"OK",b
GOTO end_key_value
CASE 0
send_2
CLS
MENU m$()
PRINT AT(25,15);"Sent buffer to Bank 2. ";
ENDSELECT
ENDIF
IF (x=0) AND (y MOD z=0) AND (y DIV z=61) !F3
SELECT no_connection
CASE -1
ALERT 1,"No MIDI connection!|Check power or MIDI chords.",1,"OK",b
GOTO end_key_value
CASE 0
send_3
CLS
MENU m$()
PRINT AT(25,15);"Sent buffer to Bank 3. ";
ENDSELECT
ENDIF
IF (x=0) AND (y MOD z=0) AND (y DIV z=62) !F4
SELECT no_connection
CASE -1
ALERT 1,"No MIDI connection!|Check power or MIDI chords.",1,"OK",b
GOTO end_key_value
CASE 0
send_4
CLS
MENU m$()
PRINT AT(25,15);"Sent buffer to Bank 4. ";
ENDSELECT
ENDIF
IF (x=0) AND (y MOD z=0) AND (y DIV z=63) !F5
SELECT no_connection
CASE -1
ALERT 1,"No MIDI connection!|Check power or MIDI chords.",1,"OK",b
GOTO end_key_value
CASE 0
send_5
CLS
MENU m$()
PRINT AT(25,15);"Sent buffer to Bank 5. ";
ENDSELECT
ENDIF
IF (x=0) AND (y MOD z=0) AND (y DIV z=64) !F6
SELECT no_connection
CASE -1
ALERT 1,"No MIDI connection!|Check power or MIDI chords.",1,"OK",b
GOTO end_key_value
CASE 0
send_drummer
check_viewmode
ENDSELECT
ENDIF
IF (x=8) AND (y MOD z=0) AND (y DIV z=59) !Alt-F1
SELECT no_connection
CASE -1
ALERT 1,"No MIDI connection!|Check power or MIDI chords.",1,"OK",b
GOTO end_key_value
CASE 0
bank=1
midi_ready_prompt(bank) !Receive from bank 1
MENU 11,2 ! receiving from Yamaha
MENU 13,2
MENU 14,2
ENDSELECT
ENDIF
IF (x=8) AND (y MOD z=0) AND (y DIV z=60) !Alt-F2
SELECT no_connection
CASE -1
ALERT 1,"No MIDI connection!|Check power or MIDI chords.",1,"OK",b
GOTO end_key_value
CASE 0
bank=2
midi_ready_prompt(bank) !Receive from bank 2
MENU 11,2
MENU 13,2
MENU 14,2
ENDSELECT
ENDIF
IF (x=8) AND (y MOD z=0) AND (y DIV z=61) !Alt-F3
SELECT no_connection
CASE -1
ALERT 1,"No MIDI connection!|Check power or MIDI chords.",1,"OK",b
GOTO end_key_value
CASE 0
bank=3
midi_ready_prompt(bank) !Receive from bank 3
MENU 11,2
MENU 13,2
MENU 14,2
ENDSELECT
ENDIF
IF (x=8) AND (y MOD z=0) AND (y DIV z=62) !Alt-F4
SELECT no_connection
CASE -1
ALERT 1,"No MIDI connection!|Check power or MIDI chords.",1,"OK",b
GOTO end_key_value
CASE 0
bank=4
midi_ready_prompt(bank) !Receive from bank 4
MENU 11,2
MENU 13,2
MENU 14,2
ENDSELECT
ENDIF
IF (x=8) AND (y MOD z=0) AND (y DIV z=63) !Alt-F5
SELECT no_connection
CASE -1
ALERT 1,"No MIDI connection!|Check power or MIDI chords.",1,"OK",b
GOTO end_key_value
CASE 0
bank=5
midi_ready_prompt(bank) !Receive from bank 5
MENU 11,2
MENU 13,2
MENU 14,2
ENDSELECT
ENDIF
IF (x=8) AND (y MOD z=0) AND (y DIV z=64) !Alt-F6
SELECT no_connection
CASE -1
ALERT 1,"No MIDI connection!|Check power or MIDI chords.",1,"OK",b
GOTO end_key_value
CASE 0
receive_drummer
CLS
MENU m$()
check_viewmode
ENDSELECT
ENDIF
IF (x=0) AND ((y MOD z=118) OR (y MOD z=86)) AND (y DIV z=47) !'v or V' key
flag=NOT (flag) ! complement viewmode flag
IF m$(19)=" View in Bytes " THEN ! change view mode according to flag
m$(19)=" View Parameters "
view_bytes
ELSE
IF m$(19)=" View Parameters " THEN
m$(19)=" View in Bytes "
view_parameters
ENDIF
ENDIF
ENDIF
IF (x=4) AND (y MOD z=22) AND (y DIV z=47) !'CNTL-v' key
ALERT 2,"Verbose Directory?",1,"yes|no",b
SELECT b
CASE 1
verbose
check_viewmode
CASE 2
ENDSELECT
ENDIF
IF ((y MOD z=108) OR (y MOD z=76)) AND (y DIV z=38) !'l or L' key
ALERT 2,"Load Patch?",1,"yes|no",b
SELECT b
CASE 1
patch_load
check_viewmode
CASE 2
ENDSELECT
MENU 12,2
ENDIF
IF ((y MOD z=115) OR (y MOD z=83)) AND (y DIV z=31) !'s or S' key
ALERT 2,"Save Patch?",1,"yes|no",b
SELECT b
CASE 1
IF demo_mode
ALERT 1,"Sorry, this is a DEMO!|You cannot save your work.",1,"Will pay!",b
ELSE
patch_save
check_viewmode
ENDIF
CASE 2
ENDSELECT
MENU 12,2
ENDIF
IF ((y MOD z=97) OR (y MOD z=65)) AND (y DIV z=30) !'a or A' key
SELECT no_connection
CASE -1
ALERT 1,"No MIDI connection!|Check power or MIDI chords.",1,"OK",b
audition_flag=FALSE
midi_delay=0
GOTO end_key_value
CASE 0
IF audition_flag=FALSE
ALERT 2,"Audition Mode checked?",1,"yes|no",b
SELECT b
CASE 1
MENU 37,1 !Toggle Audition Menu check on
audition_flag=TRUE !Set Audition Flag
CLS
HIDEM
PRINT AT(20,9);"Enter delay value selection:"
PRINT AT(20,11);"<numeric key 1> 3 seconds"
PRINT AT(20,12);"<numeric key 2> 9 seconds"
PRINT AT(20,13);"<numeric key 3> 21 seconds"
PRINT AT(20,14);"<numeric key 4> 30 seconds"
DO
KEYGET key
EXIT IF key=7143473 OR key=7209010 OR key=7274547 OR key=6946868
LOOP
SELECT key
CASE 7143473
midi_delay=1
CASE 7209010
midi_delay=2
CASE 7274547
midi_delay=3
CASE 6946868
midi_delay=4
ENDSELECT
CLS
MENU m$()
PRINT AT(9,9);"Audition delay time will be";
SELECT midi_delay
CASE 1
PRINT " 3 seconds (1 second between notes)"
CASE 2
PRINT " 9 seconds (3 seconds between notes)"
CASE 3
PRINT " 21 seconds (7 seconds between notes)"
CASE 4
PRINT " 30 seconds (10 seconds between notes)"
ENDSELECT
CASE 2
ENDSELECT
ELSE
ALERT 2,"Audition Mode unchecked?",1,"yes|no",b
SELECT b
CASE 1
MENU 37,1 !Toggle Audition Menu check on
audition_flag=FALSE !Set Audition Flag
midi_delay=0
CASE 2
ENDSELECT
ENDIF
MENU 12,2
ENDSELECT
ENDIF
IF ((y MOD z=98) OR (y MOD z=66)) AND (y DIV z=48) !'b or B' key
ALERT 2,"Build Patch?",1,"yes|no",b
SELECT b
CASE 1
init_buffer
check_viewmode
CASE 2
ENDSELECT
MENU 12,2
ENDIF
IF ((y MOD z=100) OR (y MOD z=68)) AND (y DIV z=32) !'d or D' key
ALERT 2,"Delete Patch?",1,"yes|no",b
SELECT b
CASE 1
patch_delete
check_viewmode
CASE 2
ENDSELECT
MENU 12,2
ENDIF
IF ((y MOD z=113) OR (y MOD z=81)) AND (y DIV z=16) !'q or Q' key
ALERT 2,"Are you Sure?",1,"yes|no",b
SELECT b
CASE 1
END
CASE 2
ENDSELECT
ENDIF
IF (x=0) AND (y MOD z=0) AND (y DIV z=98) !'HELP' key
about_general
ENDIF
IF (x=4) AND (y MOD z=0) AND (y DIV z=98) !'CNTL-HELP' key
about_file
ENDIF
IF (x=2) AND (y MOD z=0) AND (y DIV z=98) !'LSHIFT-HELP' key
about_buffer
ENDIF
IF (x=1) AND (y MOD z=0) AND (y DIV z=98) !'RSHIFT-HELP' key
about_midi
ENDIF
IF (x=6) AND (y MOD z=0) AND (y DIV z=98) !'CNTL-LSHIFT-HELP' key
about_modulation
ENDIF
IF (x=5) AND (y MOD z=0) AND (y DIV z=98) !'CNTL-RSHIFT-HELP' key
about_mod_car
ENDIF
IF (x=0) AND ((y MOD z=107) OR (y MOD z=75)) AND (y DIV z=37) !'k or K' key
about_key_equiv
ENDIF
IF (x=0) AND ((y MOD z=112) OR (y MOD z=80)) AND (y DIV z=25) !'p or P' key
about_editor_librarian
ENDIF
'
'
end_key_value:
DEFMOUSE 3
RETURN
'
' ***********************************************************************
' DISPLAY A POP-UP BOX LISTING ALL KEYBOARD EQUIVALENTS FOR GEM DROPDOWN
' ***********************************************************************
'
PROCEDURE about_key_equiv
'
x=120
y=30
lx=60
rx=610
IF rez=1
ty=15
ELSE
ty=10
ENDIF
by=180
IF rez=2
ty=ty+20
by=by+by+30-ty
y=70
ENDIF
SGET tempuse$
DEFFILL 0,2,8
DEFLINE 1,2
growbox(lx,ty,30,30,lx,ty,rx-lx,by-ty)
PBOX lx,ty,rx,by
BOX lx,ty,rx,by
DEFLINE 1,1
BOX lx+5,ty+2,rx-5,by-2
IF rez=1
DEFTEXT 1,9,0,6
ELSE
DEFTEXT 1,9,0,13
ENDIF
TEXT x,y,"FILE COMMANDS"
PRINT AT(10,6);"L - Load Patch"
PRINT AT(10,7);"S - Save Patch"
PRINT AT(10,9);"B - Build Patch"
PRINT AT(10,8);"D - Delete Patch"
PRINT AT(10,10);"CNTL/V - Verbose List"
PRINT AT(10,11);"Q - Quit Program"
IF rez=1
TEXT x,y+70,"BUFFER"
ELSE
TEXT x,y+120,"BUFFER"
ENDIF
PRINT AT(10,14);"V - Toggle View Mode"
PRINT AT(10,17);"K - This Screen"
PRINT AT(10,19);"UNDO - Clear Screen"
IF rez=1
TEXT x+220,y-2,"MIDI COMMANDS"
ELSE
TEXT x+220,y-10,"MIDI COMMANDS"
ENDIF
PRINT AT(35,5);"F1 - F5 - Send Banks 1 - 5"
PRINT AT(35,6);"ALT/F1 - ALT/F5 - Receive Banks 1 - 5"
PRINT AT(35,7);"F6 - Import Custom Drummer/.SYX"
PRINT AT(35,8);"ALT/F6 - Export Custom Drummer"
PRINT AT(35,9);"1 - 5(numeric keypad) - Change Voice Bank"
PRINT AT(35,10);"A - Set/Clear Audition Mode"
IF rez=1
TEXT x+220,y+62,"HELP"
ELSE
TEXT x+220,y+122,"HELP"
ENDIF
PRINT AT(35,14);"HELP - General"
PRINT AT(35,15);"CNTL/HELP - File"
PRINT AT(35,16);"LSHIFT/HELP - Buffer"
PRINT AT(35,17);"RSHIFT/HELP - MIDI"
PRINT AT(35,18);"CNTL/LSHIFT/HELP - Modulation"
PRINT AT(35,19);"CNTL/RSHIFT/HELP - Modulator/Carrier"
PRINT AT(35,20);"{-->} - Page Up"
PRINT AT(35,21);"{<--} - Page Down"
PRINT AT(35,22);"P - Program Credits"
HIDEM
a=MOUSEX
b=MOUSEY
DO
KEYTEST key
EXIT IF (MOUSEX<>a AND MOUSEY<>b) OR ((key=274792448) OR (key=6356992))
LOOP
SPUT tempuse$
shrinkbox(lx,ty,30,30,lx,ty,rx-lx,by-ty)
CLR tempuse$
DEFTEXT 1,0,0,10
check_viewmode
'
RETURN
'
' ***********************************************************************
' DISPLAY A POP-UP BOX INDICATING PROGRAM CREDITS
' ***********************************************************************
'
PROCEDURE about_editor_librarian
'
lx=100
rx=539
ty=15
by=199
IF rez=2
by=by+by-ty
ENDIF
SGET tempuse$
DIM linstyle%(14),credline$(14)
linstyle%(0)=1
linstyle%(1)=1
linstyle%(2)=0
linstyle%(3)=0
linstyle%(4)=4
linstyle%(5)=4
linstyle%(6)=4
linstyle%(7)=0
linstyle%(8)=0
linstyle%(9)=0
linstyle%(10)=0
linstyle%(11)=4
linstyle%(12)=4
linstyle%(13)=4
credline$(1)=" FOR THE PORTASOUND SERIES"
credline$(2)=" Version 2.0 "
credline$(3)=""
credline$(4)=" Programmed in GFA BASIC 3.07"
credline$(5)=" copyright 1991,1992,1993,1994"
credline$(6)=" by Mike Silverstein"
credline$(7)=""
credline$(8)="If you like this MIDI shareware program,"
credline$(9)="Please send a $7.00 contribution to:"
credline$(10)=""
credline$(11)=" Mike Silverstein"
credline$(12)=" 555 Rosewood Ave. #306"
credline$(13)=" Camarillo, CA 93010"
DEFFILL 0,2,8
DEFLINE 1,2
growbox(lx,ty,20,20,lx,ty,rx-lx,by-ty)
PBOX lx,ty,rx,by
BOX lx,ty,rx,by
DEFLINE 1,1
BOX lx+5,ty+2,rx-5,by-2
IF rez=2
DEFTEXT 1,linstyle%(0),0,13
offset=22
ELSE
DEFTEXT 1,linstyle%(0),0,7
offset=10
ENDIF
IF rez=2
TEXT lx+55,ty+20,"YAMAHA PSS PATCH EDITOR/LIBRARIAN"
ELSE
TEXT lx+55,ty+15,"YAMAHA PSS PATCH EDITOR/LIBRARIAN"
ENDIF
FOR x=1 TO 6
DEFTEXT 1,linstyle%(x)
TEXT lx+55,(ty+25+(x)*offset),credline$(x)
NEXT x
FOR x=7 TO 9
DEFTEXT 1,linstyle%(x),0,6
TEXT lx+55,(ty+25+(x)*offset),credline$(x)
NEXT x
FOR x=10 TO 13
DEFTEXT 1,linstyle%(x),0,4
TEXT lx+55,(ty+25+(x)*offset),credline$(x)
NEXT x
DEFTEXT 1,1,0,6
IF demo_mode
TEXT lx+182,by-9,"Continue DEMO"
ELSE
TEXT lx+182,by-9,"Continue REGISTERED"
ENDIF
DEFLINE 1,2
BOX lx+175,by-19,rx-186,by-4
HIDEM
a=MOUSEX
b=MOUSEY
DO
KEYTEST key
EXIT IF (MOUSEX<>a AND MOUSEY<>b) OR ((key=274792448) OR (key=6356992))
LOOP
'
DEFFILL 1,2,8
PBOX lx+175,by-19,rx-186,by-4
ERASE linstyle%()
ERASE credline$()
SPUT tempuse$
CLR tempuse$,junk$
shrinkbox(lx,ty,20,5,lx,ty,rx-lx,by-ty)
'
RETURN
'
' ***********************************************************************
' THE NEXT 5 ROUTINES WILL PLACE THE BANK NUMBER IN THE ARRAY BASED ON
' THE DROP-DOWN MENU SELECTION. IT THEN CALLS THE CHECKSUM ROUTINE,
' SENDS THE PATCH, AND SENDS A PROGRAM CHANGE TO THE YAMAHA BASED ON THE
' BANK NUMBER. IF THE AUDITION MODE IS SET, THEN THE PATCH DATA
' CORRESPONDING TO THE CHANNEL/BANK # WILL BE PLAYED ACCORDINGLY.
' ***********************************************************************
'
PROCEDURE send_1
'
a(5)=0 !store bank #1
checksum !calculate checksum byte
send_patch !send the patch
OUT 3,&HC0 !send bank 1 program change
OUT 3,100
IF audition_flag=TRUE
PAUSE 20
OUT 3,&H90 !MIDI note on, channel 1
OUT 3,36 !Play a C1, channel 1
OUT 3,64 !Medium Velocity
pitch=1
popup_audition(pitch)
OUT 3,&H80 !MIDI note off, channel 1
OUT 3,36 !Release C1, channel 1
OUT 3,64 !Medium Velocity
OUT 3,&H90 !MIDI note on, channel 1
OUT 3,60 !Play a C3,channel 1
OUT 3,64 !Medium Velocity
pitch=2
popup_audition(pitch)
OUT 3,&H80 !MIDI note off,channel 1
OUT 3,60 !Release C3, channel 1
OUT 3,64 !Medium Velocity
OUT 3,&H90 !MIDI note on, channel 1
OUT 3,84 !Play a C5, channel 1
OUT 3,64 !Medium Velocity
pitch=3
popup_audition(pitch)
OUT 3,&H80 !MIDI note off, channel 1
OUT 3,84 !Release C5, channel 1
OUT 3,64 !Medium Velocity
ENDIF
'
RETURN
'
PROCEDURE send_2
'
a(5)=1 !store bank #2
checksum !calculate checksum byte
send_patch !send the patch
OUT 3,&HC1 !send bank 2 program change
OUT 3,101
IF audition_flag=TRUE
PAUSE 20
OUT 3,&H91 !MIDI note on, channel 2
OUT 3,36 !Play a C1, channel 2
OUT 3,64 !Medium Velocity
pitch=1
popup_audition(pitch)
OUT 3,&H81 !MIDI note off, channel 2
OUT 3,36 !Release C1, channel 2
OUT 3,64 !Medium Velocity
OUT 3,&H91 !MIDI note on, channel 2
OUT 3,60 !Play a C3,channel 2
OUT 3,64 !Medium Velocity
pitch=2
popup_audition(pitch)
OUT 3,&H81 !MIDI note off,channel 2
OUT 3,60 !Release C3, channel 2
OUT 3,64 !Medium Velocity
OUT 3,&H91 !MIDI note on, channel 2
OUT 3,84 !Play a C5, channel 2
OUT 3,64 !Medium Velocity
pitch=3
popup_audition(pitch)
OUT 3,&H81 !MIDI note off, channel 2
OUT 3,84 !Release C5, channel 2
OUT 3,64 !Medium Velocity
ENDIF
'
RETURN
'
PROCEDURE send_3
'
a(5)=2 !store bank #3
checksum !calculate checksum byte
send_patch !send the patch
OUT 3,&HC2 !send bank 3 program change
OUT 3,102
IF audition_flag=TRUE
PAUSE 20
OUT 3,&H92 !MIDI note on, channel 3
OUT 3,36 !Play a C1, channel 3
OUT 3,64 !Medium Velocity
pitch=1
popup_audition(pitch)
OUT 3,&H82 !MIDI note off, channel 3
OUT 3,36 !Release C1, channel 3
OUT 3,64 !Medium Velocity
OUT 3,&H92 !MIDI note on, channel 3
OUT 3,60 !Play a C3,channel 3
OUT 3,64 !Medium Velocity
pitch=2
popup_audition(pitch)
OUT 3,&H82 !MIDI note off,channel 3
OUT 3,60 !Release C3, channel 3
OUT 3,64 !Medium Velocity
OUT 3,&H92 !MIDI note on, channel 3
OUT 3,84 !Play a C5, channel 3
OUT 3,64 !Medium Velocity
pitch=3
popup_audition(pitch)
OUT 3,&H82 !MIDI note off, channel 3
OUT 3,84 !Release C5, channel 3
OUT 3,64 !Medium Velocity
ENDIF
'
RETURN
'
PROCEDURE send_4
'
a(5)=3 !store bank #4
checksum !calculate checksum byte
send_patch !send the patch
OUT 3,&HC3 !send bank 4 program change
OUT 3,103
IF audition_flag=TRUE
PAUSE 20
OUT 3,&H93 !MIDI note on, channel 4
OUT 3,36 !Play a C1, channel 4
OUT 3,64 !Medium Velocity
pitch=1
popup_audition(pitch)
OUT 3,&H83 !MIDI note off, channel 4
OUT 3,36 !Release C1, channel 4
OUT 3,64 !Medium Velocity
OUT 3,&H93 !MIDI note on, channel 4
OUT 3,60 !Play a C3,channel 4
OUT 3,64 !Medium Velocity
pitch=2
popup_audition(pitch)
OUT 3,&H83 !MIDI note off,channel 4
OUT 3,60 !Release C3, channel 4
OUT 3,64 !Medium Velocity
OUT 3,&H93 !MIDI note on, channel 4
OUT 3,84 !Play a C5, channel 4
OUT 3,64 !Medium Velocity
pitch=3
popup_audition(pitch)
OUT 3,&H83 !MIDI note off, channel 4
OUT 3,84 !Release C5, channel 4
OUT 3,64 !Medium Velocity
ENDIF
'
RETURN
'
PROCEDURE send_5
'
a(5)=4 !store bank #5
checksum !calculate checksum byte
send_patch !send the patch
OUT 3,&HC4 !send bank 5 program change
OUT 3,104
IF audition_flag=TRUE
PAUSE 20
OUT 3,&H94 !MIDI note on, channel 5
OUT 3,36 !Play a C1, channel 5
OUT 3,64 !Medium Velocity
pitch=1
popup_audition(pitch)
OUT 3,&H84 !MIDI note off, channel 5
OUT 3,36 !Release C1, channel 5
OUT 3,64 !Medium Velocity
OUT 3,&H94 !MIDI note on, channel 5
OUT 3,60 !Play a C3,channel 5
OUT 3,64 !Medium Velocity
pitch=2
popup_audition(pitch)
OUT 3,&H84 !MIDI note off,channel 5
OUT 3,60 !Release C3, channel 5
OUT 3,64 !Medium Velocity
OUT 3,&H94 !MIDI note on, channel 5
OUT 3,84 !Play a C5, channel 5
OUT 3,64 !Medium Velocity
pitch=3
popup_audition(pitch)
OUT 3,&H84 !MIDI note off, channel 5
OUT 3,84 !Release C5, channel 5
OUT 3,64 !Medium Velocity
ENDIF
'
RETURN
'
' ***********************************************************************
' MIDI-READY-PROMPT ALERTS THE USER TO PREPARE THE YAMAHA INSTRUMENT FOR
' A MEMORY BULK DUMP TO THE ST. BASED ON THE BUTTON READ FROM THE
' DROP-DOWN MENU, THE APPROPRIATE RECEIVE ROUTINE IS CALLED. THE VIEW
' BUFFER IS THEN DISPLAYED DEPENDING ON THE CURRENT VIEW MODE. THIS ALSO
' OCCURS WHEN THE USER BAILS OUT OF THE BULK DUMP ROUTINES.
' ***********************************************************************
'
PROCEDURE midi_ready_prompt(VAR bank)
'
ALERT 1,"Is Yamaha Keyboard Ready?",1,"yes|no",receive_prompt
SELECT receive_prompt
CASE 1
ALERT 1,"Please transmit via Bulk Dump.",1,"OK",ok_prompt
SELECT bank
CASE 1
receive_1
check_viewmode
CASE 2
receive_2
check_viewmode
CASE 3
receive_3
check_viewmode
CASE 4
receive_4
check_viewmode
CASE 5
receive_5
check_viewmode
ENDSELECT
CASE 2 ! User bailed out
check_viewmode
ENDSELECT
DEFMOUSE 3 ! reinitialize mouse to pointing hand
'
RETURN
'
' ***********************************************************************
' THE NEXT 5 ROUTINES SET THE BANK NUMBER BASED ON THE DROP-DOWN MENU
' SELECTION. THE RECEIVE-MIDI ROUTINE IS CALLED WITH THE PROPER BANK
' NUMBER PASSED, A 4 SECOND DELAY IS ISSUED TO ALLOW TIME FOR THE ENTIRE
' BULK DUMP TO GET THROUGH, AND A PROGRAM CHANGE IS SENT BASED ON THE
' BANK NUMBER.
' ***********************************************************************
'
PROCEDURE receive_1
'
bank_number=0
receive_midi(bank_number)
DELAY 4
OUT 3,&HC0 !send bank 1 program change
OUT 3,100
'
RETURN
'
PROCEDURE receive_2
'
bank_number=1
receive_midi(bank_number)
DELAY 4
OUT 3,&HC1 !send bank 2 program change
OUT 3,101
'
RETURN
'
PROCEDURE receive_3
'
bank_number=2
receive_midi(bank_number)
DELAY 4
OUT 3,&HC2 !send bank 3 program change
OUT 3,102
'
RETURN
'
PROCEDURE receive_4
'
bank_number=3
receive_midi(bank_number)
DELAY 4
OUT 3,&HC3 !send bank 4 program change
OUT 3,103
'
RETURN
'
PROCEDURE receive_5
'
bank_number=4
receive_midi(bank_number)
DELAY 4
OUT 3,&HC4 !send bank 5 program change
OUT 3,104
'
RETURN
'
' ***********************************************************************
' RECEIVE-MIDI CALLS CHANGE-MIDI-BUFF TO REDEFINE THE SIZE OF THE SYSTEM
' MIDI BUFFER TO ALLOW FOR A 512 BYTE BULK DUMP OF ALL PATCH SOUNDS. IT
' THEN SETS UP AN ARRAY FOR READING INCOMING SYSTEM EXCLUSIVE MIDI DATA.
' A FLAG IS USED TO SET UP A LOOP WHERE A SPECIFIC 4 BYTE SEQUENCE IS
' USED TO DETERMINE WHICH BANK TO RECEIVE BASED ON THE BANK NUMBER
' SELECTED FROM THE DROP-DOWN MENU. ONCE THIS SEQUENCE IS DETERMINED,
' THE NEXT 65 BYTES WILL CONTAIN ALL DATA PARAMETERS FOR THE PATCH
' INCLUDING A CHECKSUM BYTE. THE RECEIVE-CHECKSUM ROUTINE IS CALLED
' AND THE INCOMING MIDI ARRAY BUFFER IS ERASED FOR THE NEXT TIME THRU.
' FINALLY, THE RECEIVED PATCH IS PROCESSED INTO THE SYSTEM GFA BASIC
' PARAMETER VALUES. DURING RECEPTION, THE USER IS NOTIFIED THAT THE
' INCOMING MIDI DATA IS BEING RECEIVED.
' ***********************************************************************
'
PROCEDURE receive_midi(bank_number)
'
CLS !clear screen
LOCATE 25,15
PRINT "Waiting for MIDI.........." !display user prompt for bulk dump
midi.buff.size=512 !new size = 512 bytes for patches
change_midi_buff(midi.buff.size) !redefine system MIDI buffsize
DIM p(70) !Initialize incoming MIDI array
receive_flag=FALSE !clear loop flag
WHILE NOT receive_flag !Search for 4 byte sequence
IF HEX$(INP(3))="76" THEN
IF HEX$(INP(3))="0" THEN
IF HEX$(INP(3))="0" THEN
IF HEX$(INP(3))=STR$(bank_number) THEN
FOR i=1 TO 65 !Collect all patch data
p(i)=INP(3)
PRINT AT(30,0);"RECEIVING......."; !Notify user
PRINT AT(30,0);" ";
NEXT i
receive_flag=TRUE !set loop flag
PRINT AT(30,0);"RECEIVED BANK ";STR$(bank_number+1);
ENDIF
ENDIF
ENDIF
ENDIF
WEND
n=6 !point to 1st byte in buffer
sum=bank_number !checksum includes bank #
receive_checksum !copy MIDI array to system buff and checksum
ERASE p() !erase MIDI array for next time thru
receiving=TRUE !set flag for file checking
received=TRUE !set flag for editing parameters
process_data !process all bytes to GFA parameter values
received=FALSE !reset flag for editing parameters
restore_midi_buffer
'
RETURN
'
' ***********************************************************************
' CHANGE-MIDI-BUFF REDEFINES THE ATARI DEFAULT BUFFER (128 BYTES) TO
' A NEW SIZE SO THAT A MEMORY BULK DUMP MAY BE PROPERLY RECEIVED INTO
' THE SYSTEM MIDI ARRAY. - Not called anymore!!
' ***********************************************************************
'
PROCEDURE change_midi_buff(midi.buff.size)
'
midi.ptr=XBIOS(14,2) !get system MIDI buffer data record
midi.buff.adr=LPEEK(midi.ptr) !get address of original buffer
ERASE midi.buff() !clear the default size
DIM midi.buff(midi.buff.size-1) !change size to a new value
LPOKE midi.ptr,VARPTR(midi.buff(0)) !point to starting address
DPOKE midi.ptr+4,(midi.buff.size) !write new size
DPOKE midi.ptr+6,0 !buffer head
DPOKE midi.ptr+8,0 !buffer tail
DPOKE midi.ptr+10,0 !low mark (not used)
DPOKE midi.ptr+12,(midi.buff.size-1) !high mark (not used)
PRINT AT(1,1);"Established a ";midi.buff.size;" byte MIDI buffer."
' PRINT AT(25,15);"Waiting for MIDI.........." !display prompt for bulk dump
'
RETURN
'
PROCEDURE restore_midi_buffer
'
old.adr=XBIOS(14,2) ! get system MIDI data record
LPOKE old.adr,midi.buff.adr ! point to default address
DPOKE old.adr+4,128 ! restore default size back
DPOKE old.adr+6,0 ! restore other old values
DPOKE old.adr+8,0
DPOKE old.adr+10,0
DPOKE old.adr+12,127
'
RETURN
'
PROCEDURE receive_drummer
' ***********************************************************************
' RECEIVE_DRUMMER - THIS ROUTINE PROMPTS THE USER TO PLACE THE
' SYNTHESIZER IN BULK DUMP MODE. IT THEN CALLS CHANGE_MIDI_BUFF TO
' SET A NEW SIZE FOR THE SYSTEM MIDI BUFFER TO A SIZE THAT WILL ALLOW
' CUSTOM DRUMMER INFO (THE LAST SYSEX MESSAGE, AFTER 13 KBYTES OR SO).
' AFTER THE USER DOES THE MEMORY BULK DUMP, AN ARRAY WILL BE FILLED
' WITH THE DRUMMER DATA AND THE FILE SELECTOR WILL BE USED TO SAVE THE
' ARRAY CONTAINING CUSTOM DRUMMER INFO TO A DISK FILE WITH A .SYX
' EXTENSION.
' ***********************************************************************
'
ALERT 1,"Is Yamaha Keyboard Ready?",1,"yes|no",receive_prompt
SELECT receive_prompt
CASE 1
ALERT 1,"Please transmit via Bulk Dump.",1,"OK",ok_prompt
CLS !clear screen
LOCATE 25,15
PRINT "Waiting for Drum Info....." !display user prompt for bulk dump
midi.buff.size=13800 !new size = 14K bytes for drummer
change_midi_buff(midi.buff.size) !redefine system MIDI buffsize
DIM d(687) !Initialize incoming MIDI array
receive_flag=FALSE !clear loop flag
WHILE NOT receive_flag !Search for 4 byte sequence
IF HEX$(INP(3))="76" THEN
IF HEX$(INP(3))="3" THEN
FOR i=1 TO 686 !Collect all patch data
d(i)=INP(3)
PRINT AT(30,0);"RECEIVING......."; !Notify user
PRINT AT(30,0);" ";
NEXT i
receive_flag=TRUE !set loop flag
ENDIF
ENDIF
WEND
restore_midi_buffer
n=686 ! set array size
DIM b(690)
b(0)=240 ! define MIDI Status byte (&HF0)
b(1)=67 ! define MIDI Instrument ID for Yamaha (&H43)
b(2)=118 ! define MIDI Class byte (&H76)
b(3)=3 ! define MIDI Format # (&H03)
FOR i=4 TO 690
b(i)=d(i-3)
NEXT i
n=0 !point to beginning of buffer
patch_buffer=MALLOC(690) !reserve 690 bytes for export
FOR i=1 TO 690 !clear patch buffer
POKE patch_buffer,0
INC patch_buffer
NEXT i
patch_buffer=patch_buffer-690 !reset pointer
FOR i=1 TO 690
POKE patch_buffer,b(n) !write MIDI parameters to buffer
INC patch_buffer !update buffer pointer
INC n !update data pointer
NEXT i
patch_buffer=patch_buffer-690 !reset buffer pointer
path$=DIR$(0)
FILESELECT path$+"\*.*","",patch_name$ !call file selector
IF RIGHT$(patch_name$)="\" OR patch_name$="" THEN
GOTO end_drummer_save !skip for OK or Cancel button
ENDIF
BSAVE patch_name$+".SYX",patch_buffer,690 !save to disk
'
end_drummer_save:
VOID MFREE(patch_buffer) !free buffer area
ERASE d()
ERASE b()
'
CASE 2 ! User bailed out
check_viewmode
ENDSELECT
RETURN
'
' ***********************************************************************
' SEND_DRUMMER - THIS ROUTINE SENDS A SYSEX CUSTOM DRUMMER MESSAGE BY
' FIRST PROMPTING THE USER TO SELECT A .SYX FILE. IT THEN CHECKS TO
' MAKE SURE THAT THE FIRST BYTE IS A VALID F0 (START OF SYSEX) AND THEN
' SENDS ALL 690 BYTES WHICH MAKE UP THE CUSTOM DRUMMER MESSAGE. NOTE
' THAT THE .SYX FILE CAN ALSO BE A PATCH FILE AS WELL. IF THE AUDITION
' MODE IS SET, THEN IF ITS PATCH DATA, THE CORRESPONDING BANK/CHANNEL #
' WILL BE PLAYED. IF ITS DRUM DATA, THEN MIDI START/STOP COMMANDS WILL
' BE ISSUED APPROPRIATELY.
' ***********************************************************************
'
PROCEDURE send_drummer
n=0
DIM b(690)
patch_buffer=MALLOC(690) !reserve 690 bytes for patch
FOR i=1 TO 690 !clear buffer
POKE patch_buffer,0
INC patch_buffer
NEXT i
patch_buffer=patch_buffer-690 !reset pointer
do_import:
path$=DIR$(0)
FILESELECT path$+"\*.*","",patch_name$ !call file selector"
IF RIGHT$(patch_name$)="\" OR patch_name$="" THEN
GOTO end_drummer_load !skip for OK or Cancel button
ENDIF
IF NOT EXIST(patch_name$) !check for user error
CLS
PRINT "Error: File Doesn't exist!!!"
GOTO do_import
ENDIF
BLOAD patch_name$,patch_buffer !load patch from disk
FOR i=0 TO 689
b(n)=PEEK(patch_buffer) !write MIDI parameters to buffer
INC patch_buffer !update buffer pointer
INC n !update data pointer
NEXT i
IF HEX$(b(0))<>"F0" THEN !Check for start of SYSEX
ALERT 1,"File error!.",1,"OK",ok_prompt
GOTO end_drummer_load
ENDIF
patch_buffer=patch_buffer-690 !reset pointer
CLS !clear screen
LOCATE 25,15
PRINT "Sending SYX Info....." !display user prompt for bulk dump
n=0 !point to beginning of buffer
OUT 3,&HFC !Send MIDI STOP
IF b(3)=3 THEN
limit=689 !Must be drummer info
ELSE
limit=71 !Must be patch info
ENDIF
FOR i=0 TO limit
OUT 3,b(n) !send all SYSEX data bytes to synth
INC n
NEXT i
IF b(3)=3 THEN
OUT 3,&HFA !Send MIDI START if custom drummer
ENDIF
IF b(5)=0 AND limit=71 THEN
OUT 3,&HC0 !send bank 1 program change
OUT 3,100
IF audition_flag=TRUE
PAUSE 20
OUT 3,&H90 !MIDI note on, channel 1
OUT 3,36 !Play a C1, channel 1
OUT 3,64 !Medium Velocity
pitch=1
popup_audition(pitch)
OUT 3,&H80 !MIDI note off, channel 1
OUT 3,36 !Release C1, channel 1
OUT 3,64 !Medium Velocity
OUT 3,&H90 !MIDI note on, channel 1
OUT 3,60 !Play a C3,channel 1
OUT 3,64 !Medium Velocity
pitch=2
popup_audition(pitch)
OUT 3,&H80 !MIDI note off,channel 1
OUT 3,60 !Release C3, channel 1
OUT 3,64 !Medium Velocity
OUT 3,&H90 !MIDI note on, channel 1
OUT 3,84 !Play a C5, channel 1
OUT 3,64 !Medium Velocity
pitch=3
popup_audition(pitch)
OUT 3,&H80 !MIDI note off, channel 1
OUT 3,84 !Release C5, channel 1
OUT 3,64 !Medium Velocity
ENDIF
ENDIF
IF b(5)=1 AND limit=71 THEN
OUT 3,&HC1 !send bank 2 program change
OUT 3,101
IF audition_flag=TRUE
PAUSE 20
OUT 3,&H91 !MIDI note on, channel 2
OUT 3,36 !Play a C1, channel 2
OUT 3,64 !Medium Velocity
pitch=1
popup_audition(pitch)
OUT 3,&H81 !MIDI note off, channel 2
OUT 3,36 !Release C1, channel 2
OUT 3,64 !Medium Velocity
OUT 3,&H91 !MIDI note on, channel 2
OUT 3,60 !Play a C3,channel 1
OUT 3,64 !Medium Velocity
pitch=2
popup_audition(pitch)
OUT 3,&H81 !MIDI note off,channel 2
OUT 3,60 !Release C3, channel 2
OUT 3,64 !Medium Velocity
OUT 3,&H91 !MIDI note on, channel 2
OUT 3,84 !Play a C5, channel 2
OUT 3,64 !Medium Velocity
pitch=3
popup_audition(pitch)
OUT 3,&H81 !MIDI note off, channel 2
OUT 3,84 !Release C5, channel 2
OUT 3,64 !Medium Velocity
ENDIF
ENDIF
IF b(5)=2 AND limit=71 THEN
OUT 3,&HC2 !send bank 3 program change
OUT 3,102
IF audition_flag=TRUE
PAUSE 20
OUT 3,&H92 !MIDI note on, channel 3
OUT 3,36 !Play a C1, channel 3
OUT 3,64 !Medium Velocity
pitch=1
popup_audition(pitch)
OUT 3,&H82 !MIDI note off, channel 3
OUT 3,36 !Release C1, channel 3
OUT 3,64 !Medium Velocity
OUT 3,&H92 !MIDI note on, channel 3
OUT 3,60 !Play a C3,channel 3
OUT 3,64 !Medium Velocity
pitch=2
popup_audition(pitch)
OUT 3,&H82 !MIDI note off,channel 3
OUT 3,60 !Release C3, channel 3
OUT 3,64 !Medium Velocity
OUT 3,&H92 !MIDI note on, channel 3
OUT 3,84 !Play a C5, channel 3
OUT 3,64 !Medium Velocity
pitch=3
popup_audition(pitch)
OUT 3,&H82 !MIDI note off, channel 3
OUT 3,84 !Release C5, channel 3
OUT 3,64 !Medium Velocity
ENDIF
ENDIF
IF b(5)=3 AND limit=71 THEN
OUT 3,&HC3 !send bank 4 program change
OUT 3,103
IF audition_flag=TRUE
PAUSE 20
OUT 3,&H93 !MIDI note on, channel 4
OUT 3,36 !Play a C1, channel 4
OUT 3,64 !Medium Velocity
pitch=1
popup_audition(pitch)
OUT 3,&H83 !MIDI note off, channel 4
OUT 3,36 !Release C1, channel 4
OUT 3,64 !Medium Velocity
OUT 3,&H93 !MIDI note on, channel 4
OUT 3,60 !Play a C3,channel 4
OUT 3,64 !Medium Velocity
pitch=2
popup_audition(pitch)
OUT 3,&H83 !MIDI note off,channel 4
OUT 3,60 !Release C3, channel 4
OUT 3,64 !Medium Velocity
OUT 3,&H93 !MIDI note on, channel 4
OUT 3,84 !Play a C5, channel 4
OUT 3,64 !Medium Velocity
pitch=3
popup_audition(pitch)
OUT 3,&H83 !MIDI note off, channel 4
OUT 3,84 !Release C5, channel 4
OUT 3,64 !Medium Velocity
ENDIF
ENDIF
IF b(5)=4 AND limit=71 THEN
OUT 3,&HC4 !send bank 5 program change
OUT 3,104
IF audition_flag=TRUE
PAUSE 20
OUT 3,&H94 !MIDI note on, channel 5
OUT 3,36 !Play a C1, channel 5
OUT 3,64 !Medium Velocity
pitch=1
popup_audition(pitch)
OUT 3,&H84 !MIDI note off, channel 5
OUT 3,36 !Release C1, channel 5
OUT 3,64 !Medium Velocity
OUT 3,&H94 !MIDI note on, channel 5
OUT 3,60 !Play a C3,channel 5
OUT 3,64 !Medium Velocity
pitch=2
popup_audition(pitch)
OUT 3,&H84 !MIDI note off,channel 5
OUT 3,60 !Release C3, channel 5
OUT 3,64 !Medium Velocity
OUT 3,&H94 !MIDI note on, channel 5
OUT 3,84 !Play a C5, channel 5
OUT 3,64 !Medium Velocity
pitch=3
popup_audition(pitch)
OUT 3,&H84 !MIDI note off, channel 5
OUT 3,84 !Release C5, channel 5
OUT 3,64 !Medium Velocity
ENDIF
ENDIF
end_drummer_load:
VOID MFREE(patch_buffer) !free buffer area
receiving=TRUE !set flag to clear filename from patch buffer
ERASE b()
DEFMOUSE 3
RETURN
'
' ***********************************************************************
' RECEIVE-CHECKSUM TRANSFERS THE RECEIVED MIDI ARRAY TO THE SYSTEM MIDI
' BUFFER AND PERFORMS A 7 BIT CHECKSUM TO INSURE DATA INTEGRITY OVER
' THE MIDI CABLES. AN ALERT BOX IS DISPLAYED FOR AN ERROR CONDITION.
' ***********************************************************************
'
PROCEDURE receive_checksum
'
FOR i=1 TO 66 !Copy received MIDI array to buffer
a(n)=p(i)
EXIT IF n=70
sum=sum+a(n) !add all data elements including bank number
INC n
NEXT i
IF sum MOD 128<>0
checksum=128-(sum AND &H7F) !checksum is 7 bits 2's complement
ELSE
checksum=0 !insure checksum is not multiple of 128
ENDIF
IF a(70)<>checksum THEN !71st element points to checksum byte
ALERT 1,"Checksum Error!",1,"OK",b
ENDIF
'
RETURN
'
' ***********************************************************************
' CHECKSUM WILL CALCULATE THE REQUIRED 7 BIT 2'S COMPLEMENT OFF ALL
' DATA ELEMENTS IN THE SYSTEM BUFFER EXCEPT THE 4 BYTE HEADER. EACH
' ELEMENT IS ADDED TO THE SUM VARIABLE WHICH AND THE 8TH BIT IS MASKED
' OFF. THE RESULT IS STORED IN THE 71ST ELEMENT OF THE 72 BYTE PATCH
' BUFFER FOR TRANSMISSION TO THE YAMAHA INSTRUMENT. THIS ROUTINE INSURES
' THAT IF THE TOTAL SUM IS A MULTIPLE OF 128 (80 HEX), THE CHECKSUM IS 0.
' ***********************************************************************
'
PROCEDURE checksum
'
n=4 !point to 1st data element in buffer
sum=0 !initialize sum
FOR i=1 TO 66
sum=sum+a(n) !add all data bytes
INC n
NEXT i
IF sum MOD 128<>0
checksum=128-(sum AND &H7F) !checksum is 7 bits 2's complement
ELSE
checksum=0 !insure sum is not a multiple of 128
ENDIF
a(70)=checksum !store result
RETURN
'
' ***********************************************************************
' SEND-PATCH SENDS THE ENTIRE 72 BYTE PATCH TO THE PROPER BANK OF THE
' YAMAHA BASED ON THE DROP-DOWN MENU SELECTION.
' ***********************************************************************
'
PROCEDURE send_patch
'
n=0 !point to beginning of buffer
FOR i=1 TO 72
OUT 3,a(n) !send all 72 data bytes
INC n
NEXT i
'
RETURN
'
' ***********************************************************************
' PATCH-SAVE WILL SAVE THE 64 BYTES OF MIDI PATCH DATA TO A FILE WHICH
' IS ATTACHED TO THE SYSTEM ARCHIVE FILE. THIS IS DONE BY ALLOCATING
' A 64 BYTE PATCH BUFFER WHERE EACH PARAMETER IN THE SYSTEM ARRAY BUFFER
' IS TRANSFERRED TO THE PATCH BUFFER. A FILESELECTOR IS USED TO ENTER
' A NAME FOR THE PATCH AND THEN THE LZH ARCHIVER IS SET UP TO MOVE THE
' PATCH FILE TO THE SYSTEM ARCHIVE FILE. THE USER CAN ALSO ENTER A
' BRIEF DESCRIPTION OF THE PATCH SOUND VIA ARCHIVE COMMENTING. THE
' CHECK-LZH ROUTINE IS CALLED TO MAKE SURE THE APPROPRIATE ARCHIVE FILE
' EXISTS IN THE PROPER DIRECTORY.
' ***********************************************************************
'
PROCEDURE patch_save
'
n=6 !point to 1st data element
patch_buffer=MALLOC(64) !reserve 64 bytes for patch
FOR i=1 TO 64 !clear patch buffer
POKE patch_buffer,0
INC patch_buffer
NEXT i
patch_buffer=patch_buffer-64 !reset pointer
FOR i=6 TO 69
POKE patch_buffer,a(n) !write MIDI parameters to buffer
INC patch_buffer !update buffer pointer
INC n !update data pointer
NEXT i
patch_buffer=patch_buffer-64 !reset buffer pointer
check_lzh(lzh$,patch_file$,not_found) !check for LZH archiver utility
IF not_found THEN
GOTO end_patch_save !skip for file not found
ENDIF
path$=DIR$(0)
FILESELECT path$+"\*.*","",patch_name$ !call file selector
IF RIGHT$(patch_name$)="\" OR patch_name$="" THEN
GOTO end_patch_save !skip for OK or Cancel button
ENDIF
BSAVE patch_name$,patch_buffer,64 !save to disk
CLS
HIDEM
c$="mc "+patch_file$+" "+patch_name$ !move file with comments
a$=CHR$(LEN(c$))+c$+CHR$(0) !make command line
EXEC 0,lzh$,a$,"" !call lzh archive utility
SHOWM
VOID MFREE(patch_buffer) !free buffer area
' ***********************************************************************
' Export Selection
' ***********************************************************************
ALERT 2,"Export to SYX?",1,"yes|no",b
SELECT b
CASE 1
n=0 !point to beginning of buffer
patch_buffer=MALLOC(72) !reserve 72 bytes for export
FOR i=1 TO 72 !clear patch buffer
POKE patch_buffer,0
INC patch_buffer
NEXT i
patch_buffer=patch_buffer-72 !reset pointer
FOR i=1 TO 72
POKE patch_buffer,a(n) !write MIDI parameters to buffer
INC patch_buffer !update buffer pointer
INC n !update data pointer
NEXT i
patch_buffer=patch_buffer-72 !reset buffer pointer
BSAVE patch_name$+".SYX",patch_buffer,72 !save to disk
CASE 2
ENDSELECT
'
end_patch_save:
VOID MFREE(patch_buffer) !free buffer area
DEFMOUSE 3 !reset mouse cursor to pointing hand
RETURN
'
' ***********************************************************************
' PATCH-LOAD WILL LOAD A PATCH FROM THE SYSTEM ARCHIVE FILE INTO THE
' SYSTEM ARRAY BY
' ALLOWING THE USER TO ENTER THE PATCH FILE VIA THE FILE SELECTOR.
' THE SELECTED FILE IS EXTRACTED AND TRANSFERRED TO THE SYSTEM ARRAY AND
' DELETED FROM DISK. THE SYSTEM ARRAY IS THEN PROCESSED VIA PROCESS-DATA.
' ***********************************************************************
'
PROCEDURE patch_load
'
n=6 !point to 1st data element
patch_buffer=MALLOC(64) !reserve 64 bytes for patch
FOR i=1 TO 64 !clear patch buffer
POKE patch_buffer,0
INC patch_buffer
NEXT i
patch_buffer=patch_buffer-64 !reset pointer
CLS
HIDEM
check_lzh(lzh$,patch_file$,not_found) !check for LZH archive utility
IF not_found THEN
GOTO end_patch_load !skip for file not found
ENDIF
do_lzh:
path$=DIR$(0)
get.path(oldpath$) !get current drive and path
FILESELECT path$+"\*.*","",patch_name$ !call file selector"
IF RIGHT$(patch_name$)="\" OR patch_name$="" THEN
GOTO end_patch_load !skip for OK or Cancel button
ENDIF
c$="x "+patch_file$+" "+patch_name$ !get file to extract
a$=CHR$(LEN(c$))+c$+CHR$(0) !make command line
EXEC 0,lzh$,a$,"" !call LZH archive utility
SHOWM
IF NOT EXIST(patch_name$) !check for user error
CLS
PRINT AT(1,1);"Error: File Doesn't exist!!!"
GOTO do_lzh
ENDIF
BLOAD patch_name$,patch_buffer !load patch from disk
LET loaded=TRUE
FOR i=1 TO 64
a(n)=PEEK(patch_buffer) !write MIDI parameters to buffer
INC patch_buffer !update buffer pointer
INC n !update data pointer
NEXT i
patch_buffer=patch_buffer-64 !reset buffer pointer
n=6 !point to 1st data element
IF HEX$(a(n))="F0"
PRINT AT(20,15);"FILE ERROR! - Use Import Selection for .SYX files"
PRINT AT(20,17);"<Press Left mouse to continue...>"
DO
LOOP UNTIL MOUSEK=1
GOTO end_patch_load
ENDIF
get.path(newpath$) !see if path has changed
IF newpath$=oldpath$
KILL patch_name$ !delete patch file from disk
ENDIF
process_data !process all bytes to GFA parameters
'
end_patch_load:
VOID MFREE(patch_buffer) !free buffer area
DEFMOUSE 3 !reset mouse cursor to pointing hand
'
RETURN
'
PROCEDURE get.path(VAR default.path$)
LOCAL default.drive,default.drive$
CLR default.path$
default.drive=GEMDOS(&H19)
default.drive$=CHR$(default.drive+65)
default.path$=DIR$(default.drive+1)
IF default.path$<>""
default.path$=default.drive$+":"+default.path$+"\"
ELSE
default.path$=default.drive$+":\"
ENDIF
RETURN
'
' ***********************************************************************
' PATCH-DELETE WILL DELETE A PATCH FROM THE SYSTEM ARCHIVE FILE USING
' THE SAME METHODS AS LOADING AND SAVING.
' ***********************************************************************
'
PROCEDURE patch_delete
'
CLS
HIDEM
check_lzh(lzh$,patch_file$,not_found) !check for LZH archive utility
IF not_found THEN
GOTO end_patch_delete !skip for file not found
ENDIF
path$=DIR$(0)
FILESELECT path$+"\*.*","",patch_name$ !call file selector
IF RIGHT$(patch_name$)="\" OR patch_name$="" THEN
GOTO end_patch_delete !skip for OK or Cancel button
ENDIF
c$="d "+patch_file$+" "+patch_name$ ! get file to delete
a$=CHR$(LEN(c$))+c$+CHR$(0) !make command line
lzh$="lha.ttp" !path for LZH
EXEC 0,lzh$,a$,"" !call LZH archive utility
deleted=TRUE
SHOWM
'
end_patch_delete:
DEFMOUSE 3 !reset mouse cursor to pointing hand
'
RETURN
'
' ***********************************************************************
' VERBOSE WILL PERFORM A VERBOSE DIRECTORY ON THE SYSTEM ARCHIVE FILE
' WHERE EACH PATCH WILL BE DISPLAYED ALONG WITH ITS DATE/TIMESTAMP AND
' ALL COMMENT DESCRIPTIONS.
' ***********************************************************************
'
PROCEDURE verbose
'
CLS
HIDEM !Hide the mouse
check_lzh(lzh$,patch_file$,not_found) !check for LZH archive utility
IF not_found THEN
GOTO end_verbose !skip for file not found
ENDIF
c$="vch "+patch_file$ !lha verbose listing w/comments
a$=CHR$(LEN(c$))+c$+CHR$(0) !make command line
EXEC 0,lzh$,a$,"" !call LZH archive utility
'
end_verbose:
SHOWM !show the mouse as a pointing hand
DEFMOUSE 3
RETURN
'
' ***********************************************************************
' CHECK-LZH WILL MAKE SURE THAT THE BOTH THE LHA.TTP ARCHIVE UTILITY AS
' WELL AS THE PATCHES.LZH SYSTEM ARCHIVE FILE EXISTS IN THE PROPER
' DIRECTORY. ALERT BOXES ARE IMPLEMENTED IN THE CASE WHERE THESE FILES
' DON'T EXIST AND ALL SYSTEM FILE OPERATIONS ARE BYPASSED IN THIS INSTANCE.
' ***********************************************************************
'
PROCEDURE check_lzh(VAR lzh$,patch_file$,not_found)
'
not_found=FALSE !clear flag
path$=DIR$(0) !get current path
lzh_file$="lha.ttp"
x=FSFIRST(lzh_file$,0) !make sure LHA.TTP exists
IF x<>0 THEN
ALERT 1,"LHA.TTP was not found",1,"OK",b
not_found=TRUE !set flag
ELSE
lzh$=lzh_file$
ENDIF
patch_file$="patches.lzh"
y=FSFIRST(patch_file$,0) !make sure PATCHES.LZH exists
IF y<>0 THEN
ALERT 1,"The Archive, PATCHES.LZH|was not found",1,"OK",b
not_found=TRUE !set flag
ENDIF
'
RETURN
'
' ***********************************************************************
' CHECK-VIEWMODE WILL DISPLAY THE SYSTEM ARRAY IN EITHER HEX BYTES OR
' MIDI PARAMETERS DEPENDING UPON THE VIEWFLAG SETTING.
' ***********************************************************************
'
PROCEDURE check_viewmode
'
IF flag THEN
view_bytes
ELSE
view_parameters
ENDIF
'
RETURN
'
' ***********************************************************************
' VIEW-PARAMETERS WILL FORMAT THE SCREEN TO DISPLAY ALL SYSTEM PARAMETER
' VALUES BY CONVERTING THE PARAMETER VALUE TO A STRING VIA STR$. BOTH
' COLOR AND MONOCHROME SCREEN DISPLAYS ARE SUPPORTED (WITH A SLIGHT
' DIFFERENCE IN PRESENTATION). ANY MOUSE MOVEMENT WILL EXIT THE SCREEN
' DISPLAY AND RETURN TO THE GEM MENU.
' ***********************************************************************
'
PROCEDURE view_parameters
'
CLS
MENU m$()
a=MOUSEX
b=MOUSEY
IF rez=1 THEN
DEFTEXT 3,9,0,6
TEXT 20,20,"MODULATION"
ELSE
DEFTEXT 2,1,0,10
TEXT 20,50,"MODULATION"
ENDIF
IF rez=1 THEN
DEFTEXT 2,9,0,6
TEXT 0,35,"LEVELING:"
ENDIF
PRINT AT(1,7);"Modulation Level"
PRINT AT(19,7);"= ";STR$(mod_level)
PRINT AT(1,8);"Total Level"
PRINT AT(19,8);"= ";STR$(total_level)
PRINT AT(1,9);"Feedback Level"
PRINT AT(19,9);"= ";STR$(fb_level)
IF rez=1 THEN
TEXT 0,86,"AM:"
ENDIF
PRINT AT(1,13);"AM Sensitivity"
PRINT AT(19,13);"= ";STR$(ams)
IF rez=1 THEN
TEXT 0,120,"FM:"
ENDIF
PRINT AT(1,17);"FM(Vibrato) Enable"
IF fm_en=0
fm_en$="OFF"
ENDIF
PRINT AT(19,17);"= ";fm_en$
PRINT AT(1,18);"FM Sensitivity"
PRINT AT(19,18);"= ";STR$(pms)
PRINT AT(1,19);"FM Delay Time"
PRINT AT(19,19);"= ";STR$(fm_delay)
PRINT AT(1,20);"Sustain Enable"
IF sus_en=0
sus_en$="OFF"
ENDIF
PRINT AT(19,20);"= ";sus_en$
IF rez=1 THEN
DEFTEXT 3,9,0,6
TEXT 220,20,"MODULATOR"
ELSE
DEFTEXT 2,1,0,10
TEXT 225,50,"MODULATOR"
ENDIF
DEFTEXT 2,5,0,6
SELECT wavform_mod_last
CASE 0
IF rez=1 THEN
TEXT 190,35,"WAVEFORM = SINE WAVE"
ELSE
TEXT 190,80,"WAVEFORM = SINE WAVE"
ENDIF
CASE 1
IF rez=1 THEN
TEXT 190,35,"WAVEFORM = SQUARE WAVE"
ELSE
TEXT 190,80,"WAVEFORM = SQUARE WAVE"
ENDIF
CASE 2
IF rez=1 THEN
TEXT 190,35,"WAVEFORM = HALF SINE WAVE"
ELSE
TEXT 190,80,"WAVEFORM = HALF SINE WAVE"
ENDIF
CASE 3
IF rez=1 THEN
TEXT 190,35,"WAVEFORM = HALF SQUARE WAVE"
ELSE
TEXT 190,80,"WAVEFORM = HALF SQUARE WAVE"
ENDIF
ENDSELECT
IF rez=1 THEN
DEFTEXT 2,9,0,6
TEXT 190,45,"TUNING:"
ENDIF
PRINT AT(25,7);"Fine Detune"
PRINT AT(47,7);"= ";STR$(dt_mod_last)
IF cdt_mod_last=0
cdt_mod$="OFF"
ELSE
cdt_mod$="ON"
ENDIF
PRINT AT(25,8);"Course Detune"
PRINT AT(47,8);"= ";cdt_mod$
IF rez=1 THEN
TEXT 190,70,"FREQUENCY:"
ENDIF
PRINT AT(25,10);"Frequency Multiplier"
PRINT AT(47,10);"= ";STR$(freq_mod_last)
IF rez=1 THEN
TEXT 190,86,"LKS/RKS:"
ENDIF
PRINT AT(25,12);"Level Key Scale Hi"
PRINT AT(47,12);"= ";STR$(lks_hi_mod_last)
PRINT AT(25,13);"Level Key Scale Lo"
PRINT AT(47,13);"= ";STR$(lks_lo_mod_last)
PRINT AT(25,14);"Rate Key Scale"
PRINT AT(47,14);"= ";STR$(rks_mod_last)
IF rez=1 THEN
TEXT 190,120,"ENVELOPE PARAMETERS:"
ENDIF
PRINT AT(25,17);"Attack Rate"
PRINT AT(47,17);"= ";STR$(atk_mod_last)
PRINT AT(25,18);"Decay 1 Rate"
PRINT AT(47,18);"= ";STR$(d1r_mod_last)
PRINT AT(25,19);"Decay 1 Level"
PRINT AT(47,19);"= ";STR$(d1l_mod_last)
PRINT AT(25,20);"Decay 2 Rate"
PRINT AT(47,20);"= ";STR$(d2r_mod_last)
PRINT AT(25,21);"Release Rate"
PRINT AT(47,21);"= ";STR$(rr_mod_last)
PRINT AT(25,22);"Sustain Release Rate"
PRINT AT(47,22);"= ";STR$(srr_mod_last)
PRINT AT(25,23);"AM Enable"
IF am_en_mod_last=0
am_en_mod$="OFF"
ELSE
am_en_mod$="ON"
ENDIF
PRINT AT(47,23);"= ";am_en_mod$
IF rez=1 THEN
DEFTEXT 3,9,0,6
TEXT 475,20,"CARRIER"
ELSE
DEFTEXT 2,1,0,10
TEXT 475,50,"CARRIER"
ENDIF
DEFTEXT 2,5,0,6
SELECT wavform_car_last
CASE 0
IF rez=1 THEN
TEXT 420,35,"WAVEFORM = SINE WAVE"
ELSE
TEXT 420,80,"WAVEFORM = SINE WAVE"
ENDIF
CASE 1
IF rez=1 THEN
TEXT 420,35,"WAVEFORM = SQUARE WAVE"
ELSE
TEXT 420,80,"WAVEFORM = SQUARE WAVE"
ENDIF
CASE 2
IF rez=1 THEN
TEXT 420,35,"WAVEFORM = HALF SINE WAVE"
ELSE
TEXT 420,80,"WAVEFORM = HALF SINE WAVE"
ENDIF
CASE 3
IF rez=1 THEN
TEXT 420,35,"WAVEFORM = HALF SQUARE WAVE"
ELSE
TEXT 420,80,"WAVEFORM = HALF SQUARE WAVE"
ENDIF
ENDSELECT
IF rez=1 THEN
DEFTEXT 2,9,0,6
TEXT 420,45,"TUNING:"
ENDIF
PRINT AT(54,7);"Fine Detune"
PRINT AT(76,7);"= ";STR$(dt_car_last)
PRINT AT(54,8);"Course Detune"
IF cdt_car_last=0
cdt_car$="OFF"
ELSE
cdt_car$="ON"
ENDIF
PRINT AT(76,8);"= ";cdt_car$
IF rez=1 THEN
TEXT 420,70,"FREQUENCY:"
ENDIF
PRINT AT(54,10);"Frequency Multiplier"
PRINT AT(76,10);"= ";STR$(freq_car_last)
IF rez=1 THEN
TEXT 420,86,"LKS/RKS:"
ENDIF
PRINT AT(54,12);"Level Key Scale Hi"
PRINT AT(76,12);"= ";STR$(lks_hi_car_last)
PRINT AT(54,13);"Level Key Scale Lo"
PRINT AT(76,13);"= ";STR$(lks_lo_car_last)
PRINT AT(54,14);"Rate Key Scale"
PRINT AT(76,14);"= ";STR$(rks_car_last)
IF rez=1 THEN
TEXT 420,120,"ENVELOPE PARAMETERS:"
ENDIF
PRINT AT(54,17);"Attack Rate"
PRINT AT(76,17);"= ";STR$(atk_car_last)
PRINT AT(54,18);"Decay 1 Rate"
PRINT AT(76,18);"= ";STR$(d1r_car_last)
PRINT AT(54,19);"Decay 1 Level"
PRINT AT(76,19);"= ";STR$(d1l_car_last)
PRINT AT(54,20);"Decay 2 Rate"
PRINT AT(76,20);"= ";STR$(d2r_car_last)
PRINT AT(54,21);"Release Rate"
PRINT AT(76,21);"= ";STR$(rr_car_last)
PRINT AT(54,22);"Sustain Release Rate"
PRINT AT(76,22);"= ";STR$(srr_car_last)
PRINT AT(54,23);"AM Enable"
IF am_en_car_last=0
am_en_car$="OFF"
ELSE
am_en_car$="ON"
ENDIF
PRINT AT(76,23);"= ";am_en_car$
DEFTEXT 1,0,0,10 !define text for larger screen font
'
RETURN
'
' ***********************************************************************
' PROCESS-DATA WILL PROCESS ALL MIDI SYSTEM EXCLUSIVE DATA EITHER IF IT
' WAS RECEIVED FROM THE YAMAHA INSTRUMENT OR LOADED FROM DISK. EACH
' DATA PARAMETER IS TRANSLATED INTO ITS PROPER DECIMAL FORMAT VIA BIT
' MANIPULATION OF EACH ELEMENT IN THE SYSTEM ARRAY. THE CLEANUP ROUTINE
' IS CALLED AT THE END IN ORDER TO ENSURE DATA INTEGRITY WITH ALL DATA
' BYTES THAT HAVE COMBINATIONS OF PATCH PARAMETERS.
' ***********************************************************************
'
PROCEDURE process_data
'
n=6 !point to 1st data element in system array
signflag=BTST(a(n),3) !check sign bit of fine detune mod
IF NOT signflag THEN !if 0, just store value
dt_mod_last=a(n)
ELSE
dt_mod_last=-(BCLR(a(n),3)) !else, fine detune mod is negative
ENDIF
'
freq_mod_last=a(n+1) !store frequency mod value
'
signflag=BTST(a(n+2),3) !check sign bit of fine detune car
IF NOT signflag THEN !if 0, just store value
dt_car_last=a(n+2)
ELSE
dt_car_last=-(BCLR(a(n+2),3)) !else, fine detune car is negative
ENDIF
'
freq_car_last=a(n+3) !store frequency car value
'
IF a(n+4)=7 AND a(n+5)=15 THEN !check for null mod level
mod_level=0
ELSE
mod_level=99-(SHL(a(n+4),4)+a(n+5)) !mod level is 99 -[16*MSB+LSB]
ENDIF
IF a(n+6)=7 AND a(n+7)=15 THEN !check for null total level
total_level=0
ELSE
total_level=99-(SHL(a(n+6),4)+a(n+7)) !total level is 99 -[16*MSB+LSB]
ENDIF
'
lks_hi_mod_last=a(n+8) !store lks hi mod value
lks_lo_mod_last=a(n+9) !store lks lo mod value
'
lks_hi_car_last=a(n+10) !store lks hi car value
lks_lo_car_last=a(n+11) !store lks lo car value
'
' ***********************************************************************
' RKS = N/4 WITH MSB OF ATK MASKED OFF
' ATK = MSB [N*16 WITH RKS MASKED OFF] + LSB
' ***********************************************************************
rks_mod_last=SHR(a(n+12) AND &HC,2)
atk_mod_last=SHL(a(n+12) AND &H3,4)+a(n+13)
'
rks_car_last=SHR(a(n+14) AND &HC,2)
atk_car_last=SHL(a(n+14) AND &H3,4)+a(n+15)
'
' ***********************************************************************
' AM_EN = N/8 WITH BOTH CDT AND MSB OF D1R MASKED OFF
' CDT = N/4 WITH BOTH AM_EN AND MSB OF D1R MASKED OFF
' D1R = MSB [N*16 WITH AM_EN AND CDT MASKED OFF] + LSB
' ***********************************************************************
am_en_mod_last=SHR(a(n+16) AND &H8,3)
cdt_mod_last=SHR(a(n+16) AND &H4,2)
d1r_mod_last=SHL(a(n+16) AND &H3,4)+a(n+17)
'
am_en_car_last=SHR(a(n+18) AND &H8,3)
cdt_car_last=SHR(a(n+18) AND &H4,2)
d1r_car_last=SHL(a(n+18) AND &H3,4)+a(n+19)
'
' ***********************************************************************
' WAVEFORM = N/4 WITH MSB OF D2R MASKED OFF
' D2R = MSB [N*16 WITH WAVEFORM MASKED OFF] + LSB
' ***********************************************************************
wavform_mod_last=SHR(a(n+20) AND &HC,2)
d2r_mod_last=SHL(a(n+20) AND &H3,4)+a(n+21)
'
wavform_car_last=SHR(a(n+22) AND &HC,2)
d2r_car_last=SHL(a(n+22) AND &H3,4)+a(n+23)
'
d1l_mod_last=a(n+24) !store d1l mod value
rr_mod_last=a(n+25) !store rr mod value
d1l_car_last=a(n+26) !store d1l car value
rr_car_last=a(n+27) !store rr car value
'
' ***********************************************************************
' FB LEVEL = MSB [N*2 WITH LAST BIT MASKED OFF]
' + LSB [N/8 WITH LAST 3 BITS MASKED OFF]
' ***********************************************************************
fb_level=(SHL(a(n+28),1) AND &H7)+(SHR(a(n+29),3) AND &H1)
'
pms=a(n+30) AND &H7 !store pms value and mask off don't cares
ams=a(n+31) AND &H3 !store ams value and mask off don't cares
'
srr_mod_last=a(n+39) !store srr mod value
srr_car_last=a(n+41) !store srr car value
'
' ***********************************************************************
' FM DELAY = MSB [N*16] + LSB
' FM EN = N/8 WITH SUS EN MASKED OFF
' SUS EN = N/4 WITH FM EN MASKED OFF
' ***********************************************************************
fm_delay=SHL(a(n+42),4)+a(n+43)
fm_en=SHR(a(n+46),3) AND &H1
IF fm_en=0
fm_en$="OFF"
ELSE
fm_en$="ON"
ENDIF
sus_en=SHR(a(n+46),2) AND &H1
IF sus_en=0
sus_en$="OFF"
ELSE
sus_en$="ON"
ENDIF
IF received ! Save screen if receiving
SGET screen$
ENDIF
cleanup
IF received ! Screen indicates that bank was received
SPUT screen$
ENDIF
'
RETURN
'
' ***********************************************************************
' CLEANUP MAKES SURE THAT ALL SYSTEM DATA BYTES THAT HAVE COMBINATIONS
' OF MIDI PARAMETERS ARE PROPERLY UPDATED WITH THEIR LAST VALUES BY
' CALLING THOSE RELEVANT ROUTINES WHICH SET THE LAST VALUE. THIS WILL
' OCCUR WHEN LOADING FROM DISK OR RECEIVING FROM THE YAMAHA INSTRUMENT.
' ***********************************************************************
'
PROCEDURE cleanup
'
' ***********************************************************************
' UPDATE BYTES 12,14 WITH LAST RKS VALUES
' ***********************************************************************
'
lks_rks_modulator(rks_mod,atk_mod)
lks_rks_carrier(rks_car,atk_car)
'
' ***********************************************************************
' UPDATE BYTES 16,18 WITH LAST CDT VALUES
' ***********************************************************************
'
tune_modulator(cdt_mod,d1r_mod,am_en_mod)
tune_carrier(cdt_car,d1r_car,am_en_car)
'
' ***********************************************************************
' UPDATE BYTES 20,22 WITH LAST WAVEFORM VALUES
' ***********************************************************************
'
wave_mod(wavform_mod,d2r_mod)
wave_car(wavform_car,d2r_car)
'
' ***********************************************************************
' UPDATE BYTES 12,14,16,18,20,22 WITH LAST ATK,AM_EN,D1R,D2R VALUES
' ***********************************************************************
'
envelope_mod(rks_mod,atk_mod,d1r_mod,am_en_mod,cdt_mod,d2r_mod,wavform_mod)
envelope_car(rks_car,atk_car,d1r_car,am_en_car,cdt_car,d2r_car,wavform_car)
'
LET loaded=FALSE !reset flag
'
RETURN
'
' ***********************************************************************
' INIT-BUFFER INITIALIZES THE 72 BYTE SYSTEM MIDI ARRAY USED TO HOLD
' ALL PATCH PARAMETERS.
' ***********************************************************************
'
PROCEDURE init_buffer
'
n=71 ! set array size
ERASE a()
DIM a(71)
a(0)=240 ! define MIDI Status byte (&HF0)
a(1)=67 ! define MIDI Instrument ID for Yamaha (&H43)
a(2)=118 ! define MIDI Class byte (&H76)
a(3)=0 ! define MIDI Format # (&H00)
a(4)=0 ! define MSB of Bank # (always 0)
a(71)=247 ! define MIDI EOX tail byte (&HF7)
a(10)=7 ! initialize leveling bytes to 0 leveling
a(11)=15
a(12)=7
a(13)=15
'
RETURN
'
' ***********************************************************************
' INIT-PARAMETERS IS CALLED ONCE AT THE BEGINNING OF PROGRAM TO INITIALIZE
' ALL SYSEX MIDI PARAMETERS.
' ***********************************************************************
'
PROCEDURE init_parameters
'
CLR mod_level ! Clear all MIDI Sysex parameters
CLR total_level
CLR fb_level
CLR ams
CLR fm_en
CLR pms
CLR fm_delay
CLR sus_en
CLR wavform_mod_last
CLR dt_mod_last
CLR cdt_mod_last
CLR freq_mod_last
CLR lks_hi_mod_last
CLR lks_lo_mod_last
CLR rks_mod_last
CLR atk_mod_last
CLR d1r_mod_last
CLR d1l_mod_last
CLR d2r_mod_last
CLR rr_mod_last
CLR srr_mod_last
CLR am_en_mod_last
CLR wavform_car_last
CLR dt_car_last
CLR cdt_car_last
CLR freq_car_last
CLR lks_hi_car_last
CLR lks_lo_car_last
CLR rks_car_last
CLR atk_car_last
CLR d1r_car_last
CLR d1l_car_last
CLR d2r_car_last
CLR rr_car_last
CLR srr_car_last
CLR am_en_car_last
'
RETURN
'
' ***********************************************************************
' VIEW-BYTES IS USED TO DISPLAY IN HEXADECIMAL ALL 64 CURRENT MIDI SYSEX
' PARAMETERS WHEN IT IS SELECTED FROM THE DROP-DOWN MENU. IF THE
' BUFFER WAS LOADED FROM DISK, THE FILENAME WILL ALSO BE SHOWN. IF THE
' BUFFER WAS RECEIVED FROM THE YAMAHA OR EDITED FROM SCRATCH, THE USER
' IS INFORMED THAT THE BUFFER IS CURRENTLY UNNAMED.
' ***********************************************************************
'
PROCEDURE view_bytes
'
CLS ! Clear Screen
MENU m$() ! Display GEM menu
lx=25 ! Implement box routine
ty=60
rx=590
by=110
DEFFILL 0,2,8
IF rez=2
by=by+by-ty
DEFTEXT 1,0,0,13
ENDIF
PBOX lx,ty,rx,by
DEFLINE 1,3
BOX lx,ty,rx,by
DEFLINE 1,1
BOX lx+8,ty+2,rx-8,by-2
n=6 ! Point to first element of MIDI SYSEX data
x=8 ! position patch table
IF rez=1 ! check screen resolution
y=10
ELSE
y=6
ENDIF
LOCATE x,y
FOR i=1 TO 4
FOR j=1 TO 16 ! Display 4 rows by 16 columns
byte$=HEX$(a(n)) ! Get value in hex
INC n ! point to next data array element
EXIT IF n=71 ! Display a total of 64 data bytes
PRINT "0";byte$;" "; ! display MIDI parameter in hex (byte form)
NEXT j
PRINT
INC y
LOCATE x,y ! reposition cursor
NEXT i
IF patch_name$="" OR receiving OR deleted THEN
PRINT AT(27,17);"Buffer = Unnamed Patch";
ELSE
PRINT AT(27,17);"Buffer = ";patch_name$;
ENDIF
receiving=FALSE ! reset flag
deleted=FALSE ! reset flag
patch_name$="" ! clear file name
DEFTEXT 1,0,0,10 !define text for larger screen font
'
RETURN
'
' ***********************************************************************
' THE NEXT SET OF ROUTINES PERTAIN TO EDITING ALL SYSTEM EXCLUSIVE
' PATCH PARAMETERS AND ARE SELECTED VIA THE DROP-DOWN MENUS. FOR THOSE
' ITEMS THAT ARE PART OF THE MODULATOR/CARRIER SECTIONS, IN GENERAL,
' THE CURRENT VALUE IS SET TO THE LAST VALUE (EITHER LOADED FROM DISK,
' RECEIVED FROM YAMAHA INSTRUMENT, OR PREVIOUSLY SELECTED) AND A ROUTINE
' TO OBTAIN THE PARAMETER VALUES IN DECIMAL VIA THE MOUSE IS CALLED.
' ONCE THE VALUE IS STORED, THE LAST VALUE IS NOW THE CURRENT VALUE FOR
' THE NEXT TIME THRU. THE SYSTEM MIDI ARRAY IS UPDATED VIA SPECIFIC
' BIT MANIPULATION FOR EACH PARAMETER. FOR BOTH LEVELING, AM/FM
' PARAMETERS, NO EXTRA ROUTINE IS CALLED WHICH IS WHY ITS GROUPED INTO
' ITS OWN SECTION (NOTE: THESE PARAMETERS EFFECT THE PATCH SOUND AS A
' WHOLE RATHER THAN BEING SPLIT INTO THE MODULATOR AND CARRIER.)
' ***********************************************************************
'
' ***********************************************************************
' TUNE-MODULATOR WILL IMPLEMENT BOTH FINE AND COURSE DE-TUNING OF THE
' MODULATOR PART OF THE SOUND PATCH. THE FINE DE-TUNE ROUTINE IS CALLED
' TO OBTAIN THE DECIMAL VALUE. IF THE VALUE IS NEGATIVE, THE SIGN BIT
' IS SET IN THE SYSTEM MIDI ARRAY ELEMENT. FOR COURSE DE-TUNING, A BIT
' IS LEFT-SHIFTED 2 TIMES AND CHECKED AGAINST THE CURRENT AM EN/D1R(MSB)
' VALUES AN STORED IN THE SYSTEM MIDI ARRAY ELEMENT.
' ***********************************************************************
'
PROCEDURE tune_modulator(VAR cdt_mod,d1r_mod,am_en_mod)
'
CLS ! clear the screen
MENU m$() ! show GEM menu
dt_mod=dt_mod_last ! get last value for display
cdt_mod=cdt_mod_last
IF cdt_mod=0
cdt_mod$="OFF"
ELSE
cdt_mod$="ON"
ENDIF
IF loaded OR received THEN ! Exit if just updating last values
GOTO end_tune_mod
ENDIF
fine_detune(dt_mod,cdt_mod$) ! calculate new dt parameter
n=6 ! fine detune mod is byte 06
IF dt_mod>=0 THEN ! Sharped tuning case
a(n)=dt_mod ! just store new value
dt_mod_last=dt_mod ! Save value
ELSE ! Flat tuning case
r=ABS(dt_mod) ! Get absolute value
dt_mod_last=dt_mod ! Save value
a(n)=r OR &H8 ! OR value with sign bit
ENDIF
n=22 ! course detune mod is 2nd bit of byte 16
IF cdt_mod$="OFF"
cdt_mod=0
ELSE
cdt_mod=1
ENDIF
IF d1r_mod=0 AND am_en_mod=0 THEN
a(n)=SHL(cdt_mod,2) ! cdt_mod:shift left 2x
ELSE
IF d1r_mod=0 AND am_en_mod<>0 THEN
a(n)=(SHL(cdt_mod,2)) OR (SHL(am_en_mod,3))
ELSE
IF d1r_mod>15 AND am_en_mod<>0 THEN
a(n)=(SHL(cdt_mod,2)) OR (SHL(am_en_mod,3)) OR (SHR(d1r_mod,4))
ELSE
a(n)=(SHL(cdt_mod,2)) OR (SHR(d1r_mod,4)) ! d1r_mod:shift right 4 x
ENDIF
ENDIF
ENDIF
cdt_mod_last=cdt_mod ! Save value
'
end_tune_mod:
RETURN
'
' ***********************************************************************
' TUNE-CARRIER EFFECTS THE CARRIER PART OF THE SOUND PATCH. SEE THE
' PREVIOUS ROUTINE FOR A DETAILED DESCRIPTION.
' ***********************************************************************
'
PROCEDURE tune_carrier(VAR cdt_car,d1r_car,am_en_car)
'
CLS ! clear the screen
MENU m$() ! show GEM menu
dt_car=dt_car_last ! get last value for display
cdt_car=cdt_car_last
IF cdt_car=0
cdt_car$="OFF"
ELSE
cdt_car$="ON"
ENDIF
IF loaded OR received THEN ! Exit if just updating last values
GOTO end_tune_car
ENDIF
fine_detune(dt_car,cdt_car$) ! calculate new dt parameter
n=8 ! fine detune carrier is byte 08
IF dt_car>=0 THEN ! Sharped tuning case
a(n)=dt_car ! store new value
dt_car_last=dt_car ! Save value
ELSE ! Flat tuning case
r=ABS(dt_car) ! Get absolute value
dt_car_last=dt_car ! Save value
a(n)=r OR &H8 ! OR value with sign bit
ENDIF
n=24 ! course detune car is 2nd bit of byte 18
IF cdt_car$="OFF"
cdt_car=0
ELSE
cdt_car=1
ENDIF
IF d1r_car=0 AND am_en_car=0 THEN
a(n)=SHL(cdt_car,2) ! cdt_car:shift left 2x
ELSE
IF d1r_car=0 AND am_en_car<>0 THEN
a(n)=(SHL(cdt_car,2)) OR (SHL(am_en_car,3))
ELSE
IF d1r_car>15 AND am_en_car<>0 THEN
a(n)=(SHL(cdt_car,2)) OR (SHL(am_en_car,3)) OR (SHR(d1r_car,4))
ELSE
a(n)=(SHL(cdt_car,2)) OR (SHR(d1r_car,4)) ! d1r_car:shift right 4 x
ENDIF
ENDIF
ENDIF
cdt_car_last=cdt_car ! Save value
'
end_tune_car:
RETURN
'
' ***********************************************************************
' FREQ-MODULATOR WILL IMPLEMENT THE FREQUENCY MODULATION MULTIPLIER
' PARAMETER BY CALLING MULT-FREQ TO OBTAIN THE DECIMAL VALUE. THIS IS
' THEN STORED IN THE SYSTEM MIDI ARRAY ELEMENT.
' ***********************************************************************
'
PROCEDURE freq_modulator
'
CLS
MENU m$() ! show GEM menu
n=7 ! frequency multiplier is byte 07
freq_mod=freq_mod_last ! get last value for display
mult_freq(freq_mod) ! calculate new frequency parameter
a(n)=freq_mod ! store new value
freq_mod_last=freq_mod ! save for display
'
RETURN
'
' ***********************************************************************
' FREQ-CARRIER WILL IMPLEMENT THE FREQUENCY CARRIER MULTIPLIER PARAMETER
' BY CALLING MULT-FREQ TO OBTAIN THE DECIMAL VALUE. THIS IS THEN STORED
' IN THE SYSTEM MIDI ARRAY ELEMENT.
' ***********************************************************************
'
PROCEDURE freq_carrier
'
CLS
MENU m$() ! show GEM menu
n=9 ! frequency multiplier is byte 09
freq_car=freq_car_last ! get last value for display
mult_freq(freq_car) ! calculate new frequency parameter
a(n)=freq_car ! store new value
freq_car_last=freq_car ! save for display
'
RETURN
'
' ***********************************************************************
' LKS-RKS-MODULATOR WILL IMPLEMENT BOTH LKS AND RKS PARAMETER VALUES BY
' CALLING LKS-RKS TO OBTAIN THE DECIMAL VALUES. THE LKS HI AND LKS LO
' PARAMETERS ARE STORED IN THE SYSTEM MIDI ARRAY ELEMENTS. THE RKS
' VALUE IS LEFT-SHIFTED TWICE AND CHECKED AGAINST THE MSB ATTACK RATE
' VALUE WHICH IS THEN STORED IN THE SYSTEM MIDI ARRAY ELEMENT.
' ***********************************************************************
'
PROCEDURE lks_rks_modulator(VAR rks_mod,atk_mod)
'
CLS ! clear screen
MENU m$() ! show GEM menu
lks_hi_mod=lks_hi_mod_last ! get last values
lks_lo_mod=lks_lo_mod_last
rks_mod=rks_mod_last
IF loaded OR received THEN ! Exit if just updating last value
GOTO end_lks_rks_mod
ENDIF
lks_rks(lks_hi_mod,lks_lo_mod,rks_mod) ! calculate new lks/rks mod values
lks_hi_mod_last=lks_hi_mod ! save values
lks_lo_mod_last=lks_lo_mod
rks_mod_last=rks_mod
n=14 ! lks lo mod is byte 0E
a(n)=lks_hi_mod ! store new value
INC n ! lks hi mod is byte 0F
a(n)=lks_lo_mod ! store new value
n=18 ! rks mod is 1st 2 bits of byte 12
IF atk_mod=0 THEN
a(n)=SHL(rks_mod_last,2) ! shift left 2x
ELSE
a(n)=(SHL(rks_mod_last,2)) OR (SHR(atk_mod,4))
ENDIF
'
end_lks_rks_mod:
RETURN
'
' ***********************************************************************
' LKS-RKS-CARRIER EFFECTS THE CARRIER PORTION OF THE SOUND PATCH. SEE
' THE ABOVE ROUTINE FOR A DETAILED DESCRIPTION.
' ***********************************************************************
'
PROCEDURE lks_rks_carrier(VAR rks_car,atk_car)
'
CLS
MENU m$()
lks_hi_car=lks_hi_car_last
lks_lo_car=lks_lo_car_last
rks_car=rks_car_last
IF loaded OR received THEN
GOTO end_lks_rks_car
ENDIF
lks_rks(lks_hi_car,lks_lo_car,rks_car)
lks_hi_car_last=lks_hi_car
lks_lo_car_last=lks_lo_car
rks_car_last=rks_car
n=16 ! lks lo car is byte 10
a(n)=lks_hi_car ! store new value
INC n ! lks hi car is byte 11
a(n)=lks_lo_car ! store new value
n=20 ! rks car is 1st 2 bits of byte 14
IF a(n)=0 THEN
a(n)=SHL(rks_car,2) ! shift left 2x
ELSE
a(n)=(SHL(rks_car,2)) OR (SHR(atk_car,4))
ENDIF
'
end_lks_rks_car:
RETURN
'
' ***********************************************************************
' ENVELOPE-MOD WILL IMPLEMENT ALL PARAMETERS PERTAINING TO THE MODULATOR'S
' ENVELOPING REQUIREMENTS WHICH INCLUDES THE ATTACK RATE, DECAY 1 RATE,
' DECAY 1 LEVEL, DECAY 2 RATE, RELEASE RATE, AND SUSTAIN RELEASE RATE IF
' SUSTAIN IS ENABLED. AFTER CALLING THE ENVELOPE ROUTINE TO OBTAIN THE
' DECIMAL VALUES THE MSB'S ARE CHECKED AGAINST THOSE PARAMETERS WHOSE
' VALUES ARE INCLUDED (ATK,D1R,D2R) AND EACH VALUE, AFTER THE PROPER
' BIT MANIPULATION, IS STORED IN THE SYSTEM MIDI ARRAY ELEMENT. THE D1L,
' RR, AND SRR VALUES DO NOT REQUIRE ANY BIT MANIPULATION SO THEY ARE
' JUST STORED.
' ***********************************************************************
'
PROCEDURE envelope_mod(VAR rks_mod,atk_mod,d1r_mod,am_en_mod,cdt_mod,d2r_mod,wavform_mod)
'
CLS
MENU m$()
atk_mod=atk_mod_last
d1r_mod=d1r_mod_last
d1l_mod=d1l_mod_last
d2r_mod=d2r_mod_last
rr_mod=rr_mod_last
srr_mod=srr_mod_last
am_en_mod=am_en_mod_last
IF am_en_mod=0
am_en_mod$="OFF"
ELSE
am_en_mod$="ON"
ENDIF
IF loaded OR received THEN ! Exit if just updating last values
GOTO end_envelope_mod
ENDIF
envelope(atk_mod,d1r_mod,d1l_mod,d2r_mod,rr_mod,srr_mod,am_en_mod$)
atk_mod_last=atk_mod
d1r_mod_last=d1r_mod
d1l_mod_last=d1l_mod
d2r_mod_last=d2r_mod
rr_mod_last=rr_mod
srr_mod_last=srr_mod
IF am_en_mod$="OFF"
am_en_mod=0
ELSE
am_en_mod=1
ENDIF
am_en_mod_last=am_en_mod
n=18 ! atk rate MSB is last 2 bits of byte 12
IF atk_mod>15 THEN ! if attack rate is more than 4 bits
a(n)=(SHR(atk_mod,4)) OR (SHL(rks_mod,2))
ELSE
a(n)=SHL(rks_mod,2) !shift left 2x
ENDIF
INC n ! atk rate LSB is byte 13
a(n)=atk_mod AND &HF ! mask off upper bits to get LSB result
n=22 ! d1r rate MSB is last 2 bits of byte 16
' AM enable is MS bit of byte 16 also
IF d1r_mod>15 AND am_en_mod<>0 THEN
a(n)=(SHR(d1r_mod,4)) OR (SHL(cdt_mod,2)) OR (SHL(am_en_mod,3))
' d1r:shift right 4x cdt: shift left 2x am_en: shift left 3x
ELSE
IF d1r_mod>15 AND am_en_mod=0 THEN
a(n)=(SHR(d1r_mod,4)) OR (SHL(cdt_mod,2))
ELSE
IF d1r_mod<16 AND am_en_mod<>0 THEN
a(n)=(SHL(am_en_mod,3)) OR (SHL(cdt_mod,2))
ELSE
a(n)=SHL(cdt_mod,2)
ENDIF
ENDIF
ENDIF
INC n ! d1r rate LSB is byte 17
a(n)=d1r_mod AND &HF ! mask off upper bits to get LSB result
n=26 ! d2r rate MSB is byte 1A
IF d2r_mod>15 THEN
a(n)=(SHR(d2r_mod,4)) OR (SHL(wavform_mod,2)) ! same as above
ELSE
a(n)=SHL(wavform_mod,2)
ENDIF
INC n ! d2r rate LSB is byte 1B
a(n)=d2r_mod AND &HF ! mask off upper bits to get LSB result
n=30 ! d1l rate is byte 1E
a(n)=d1l_mod ! store value
INC n ! release rate is byte 1F
a(n)=rr_mod ! store value
n=45 ! sustain release rate is byte 2D
a(n)=srr_mod ! store value
'
end_envelope_mod:
RETURN
'
' ***********************************************************************
' ENVELOPE-CAR EFFECTS THE CARRIER PORTION OF THE SOUND PATCH. SEE THE
' ABOVE ROUTINE FOR A DETAILED DESCRIPTION.
' ***********************************************************************
'
PROCEDURE envelope_car(VAR rks_car,atk_car,d1r_car,am_en_car,cdt_car,d2r_car,wavform_car)
'
CLS
MENU m$()
atk_car=atk_car_last
d1r_car=d1r_car_last
d1l_car=d1l_car_last
d2r_car=d2r_car_last
rr_car=rr_car_last
srr_car=srr_car_last
am_en_car=am_en_car_last
IF am_en_car=0
am_en_car$="OFF"
ELSE
am_en_car$="ON"
ENDIF
IF loaded OR received THEN ! Exit if just updating last values
GOTO end_envelope_car
ENDIF
envelope(atk_car,d1r_car,d1l_car,d2r_car,rr_car,srr_car,am_en_car$)
atk_car_last=atk_car
d1r_car_last=d1r_car
d1l_car_last=d1l_car
d2r_car_last=d2r_car
rr_car_last=rr_car
srr_car_last=srr_car
IF am_en_car$="OFF"
am_en_car=0
ELSE
am_en_car=1
ENDIF
am_en_car_last=am_en_car
n=20 ! atk rate MSB is last 2 bits of byte 14
IF atk_car>15 THEN ! if attack rate is more than 4 bits
a(n)=(SHR(atk_car,4)) OR (SHL(rks_car,2))
ELSE
a(n)=SHL(rks_car,2) !shift left 2x
ENDIF
INC n ! atk rate LSB is byte 15
a(n)=atk_car AND &HF ! mask off upper bits to get LSB result
n=24 ! d1r rate MSB is byte 18
' AM enable is MS bit of byte 18 also
IF d1r_car>15 AND am_en_car<>0 THEN
a(n)=(SHR(d1r_car,4)) OR (SHL(cdt_car,2)) OR (SHL(am_en_car,3))
' d1r:shift right 4x cdt: shift left 2x am_en: shift left 3x
ELSE
IF d1r_car>15 AND am_en_car=0 THEN
a(n)=(SHR(d1r_car,4)) OR (SHL(cdt_car,2))
ELSE
IF d1r_car<16 AND am_en_car<>0 THEN
a(n)=(SHL(am_en_car,3)) OR (SHL(cdt_car,2))
ELSE
a(n)=SHL(cdt_car,2)
ENDIF
ENDIF
ENDIF
INC n ! d1r rate LSB is byte 19
a(n)=d1r_car AND &HF ! mask off upper bits to get LSB result
n=28 ! d2r rate MSB is byte 1C
IF d2r_car>15 THEN
a(n)=(SHR(d2r_car,4)) OR (SHL(wavform_car,2)) ! same as above
ELSE
a(n)=SHL(wavform_car,2)
ENDIF
INC n ! d2r rate LSB is byte 1D
a(n)=d2r_car AND &HF ! mask off upper bits to get LSB result
n=32 ! d1l rate is byte 20
a(n)=d1l_car ! store value
INC n ! release rate is byte 21
a(n)=rr_car ! store value
n=47 ! sustain release rate is byte 2F
a(n)=srr_car
'
end_envelope_car:
RETURN
'
' ***********************************************************************
' WAVE-MOD IMPLEMENTS THE PROPER WAVEFORM FOR THE MOULATOR PORTION OF THE
' SOUND PATCH BY CALLING THE GENERATE-WAVE ROUTINE TO OBTAIN 4 POSSIBLE
' WAVEFORM CHOICES. THIS VALUE IS THEN LEFT-SHIFTED TWICE AND CHECKED
' AGAINST THE MSB OF THE D2R VALUE AND THEN PLACED IN THE SYSTEM MIDI
' ARRAY ELEMENT.
' ***********************************************************************
'
PROCEDURE wave_mod(VAR wavform_mod,d2r_mod)
'
CLS
MENU m$()
wavform_mod=wavform_mod_last
IF loaded OR received THEN ! Exit if just updating values
GOTO end_wave_mod
ENDIF
generate_wave(wavform_mod)
wavform_mod_last=wavform_mod
n=26
IF d2r_mod=0 THEN
a(n)=SHL(wavform_mod,2)
ELSE
a(n)=(SHL(wavform_mod,2)) OR (SHR(d2r_mod,4))
ENDIF
'
end_wave_mod:
RETURN
'
' ***********************************************************************
' WAVE-CAR EFFECTS THE CARRIER PORTION OF THE SOUND PATCH. SEE THE
' ABOVE ROUTINE FOR A DETAILED DESCRIPTION.
' ***********************************************************************
'
PROCEDURE wave_car(VAR wavform_car,d2r_car)
'
CLS
MENU m$()
wavform_car=wavform_car_last
IF loaded OR received THEN
GOTO end_wave_car
ENDIF
generate_wave(wavform_car)
wavform_car_last=wavform_car
n=28
IF d2r_car=0 THEN
a(n)=SHL(wavform_car,2)
ELSE
a(n)=(SHL(wavform_car,2)) OR (SHR(d2r_car,4))
ENDIF
'
end_wave_car:
RETURN
'
' ***********************************************************************
' THE NEXT SET OF ROUTINES OBTAIN A PARAMETER IN DECIMAL FORM BASED ON
' MOUSE ENTRIES. FIRST, A VALUE IS INITIALIZED TO 0 IF IT WAS NEVER
' UPDATED. A DISPLAY PROMPT IS SHOWN WITH A GRAPHICAL BOX IN WHICH CASE
' THE USER WILL USE THE LEFT MOUSE BUTTON TO INCREMENT OR RIGHT MOUSE
' BUTTON TO DECREMENT A DECIMAL VALUE BASED ON A GIVEN MINIMUM AND
' MAXIMUM RANGE. EACH ROUTINE IS EXITED WHEN BOTH MOUSE BUTTONS ARE
' DEPRESSED. THE FOLLOWING PROVIDES INFORMATION ON THE MINIMUM AND
' MAXIMUM RANGE VALUES FOR EACH PARAMETER:
'
' FINE DE-TUNE - -7 TO 7
' COURSE DE-TUNE - 0 OR 1
' FREQUENCY MULTIPLIER - 0 TO 15
' MODULATION LEVEL - 0 TO 99
' TOTAL LEVEL - 0 TO 99
' FEEDBACK LEVEL - 0 TO 7
' AMPLITUDE MOULATION SENSITIVITY - 0 TO 3
' FM(VIBRATO) ENABLE - 0 OR 1
' FREQUENCY MODULATION SENSITIVITY - 0 TO 7
' FM DELAY TIME- 0 TO 127
' SUSTAIN ENABLE - 0 OR 1
' LEVEL KEY SCALE HI - 0 TO 15
' LEVEL KEY SCALE LO - 0 TO 15
' RATE KEY SCALE - 0 TO 3
' ATTACK RATE - 0 TO 63
' DECAY 1 RATE - 0 TO 63
' DECAY 1 LEVEL - 0 TO 15
' DECAY 2 RATE - 0 TO 63
' RELEASE RATE - 0 TO 15
' SUSTAIN RELEASE RATE - 0 TO 15
'
' THE CREATE-BOX/REDRAW-BOX ROUTINES ARE CALLED EACH TIME THE VALUE
' CHANGES WITH THE 4 X,Y COORDINATES OF EACH BOX BEING PASSED TO
' EACH ROUTINE. BOTH THE LEVELING, AM/FM ROUTINES CALCULATE THE
' SYSTEM MIDI ARRAY ELEMENTS.
' ***********************************************************************
'
PROCEDURE fine_detune(VAR dt,cdt$)
'
IF dt=0 THEN
dt$="0" !reinitialize fine detune if not used
ENDIF
fdt$="Fine Detune:"
x0=350
y0=36
x1=400
y1=60 !dt box coordinates
dt$=STR$(dt)
create_box(fdt$,dt$,x0,y0,x1,y1)
cdt_prompt$="Course Detune:"
v0=350
w0=76
v1=410
w1=100 ! cdt box coordinates
create_box(cdt_prompt$,cdt$,v0,w0,v1,w1)
DO
a=MOUSEX !get mouse coordinates
b=MOUSEY
IF MOUSEK=1 !left mouse button
IF a>x0 AND b>y0 AND a<x1 AND b<y1
IF dt<7 THEN
INC dt !increment fine detune
dt$=STR$(dt)
redraw_box(dt$,x0,y0,x1,y1)
PAUSE 10 !delay for mouse button
ENDIF
ELSE
IF a>v0 AND b>w0 AND a<v1 AND b<w1
cdt$="ON"
redraw_box(cdt$,v0,w0,v1,w1)
PAUSE 10 !delay for mouse button
ENDIF
ENDIF
ELSE
IF MOUSEK=2 THEN !right mouse button
IF a>x0 AND b>y0 AND a<x1 AND b<y1
IF dt>-7 THEN
DEC dt !decrement detune
dt$=STR$(dt)
redraw_box(dt$,x0,y0,x1,y1)
PAUSE 10 !delay for mouse button
ENDIF
ELSE
IF a>v0 AND b>w0 AND a<v1 AND b<w1
cdt$="OFF"
redraw_box(cdt$,v0,w0,v1,w1)
PAUSE 10 !delay for mouse button
ENDIF
ENDIF
ENDIF
ENDIF
EXIT IF MOUSEK=3 !exit loop for both buttons
LOOP
RETURN
'
PROCEDURE mult_freq(VAR freq)
'
IF freq=0 THEN
freq$="0" !reinitialize frequency multiplier
ENDIF
freqprompt$="Frequency Mulitplier:"
x0=350
y0=36
x1=400
y1=60 !freq box coordinates
freq$=STR$(freq)
create_box(freqprompt$,freq$,x0,y0,x1,y1)
DO
a=MOUSEX !get mouse coordinates
b=MOUSEY
IF MOUSEK=1 !left mouse button
IF a>x0 AND b>y0 AND a<x1 AND b<y1
IF freq<15 THEN
INC freq !increment multiplier
freq$=STR$(freq)
redraw_box(freq$,x0,y0,x1,y1)
PAUSE 10 !delay for mouse button
ENDIF
ENDIF
ELSE
IF MOUSEK=2 THEN !right mouse button
IF a>x0 AND b>y0 AND a<x1 AND b<y1
IF freq>0 THEN
DEC freq !decrement multiplier
freq$=STR$(freq)
redraw_box(freq$,x0,y0,x1,y1)
PAUSE 10 !delay for mouse button
ENDIF
ENDIF
ENDIF
ENDIF
EXIT IF MOUSEK=3 !exit loop for both buttons
LOOP
RETURN
'
PROCEDURE leveling
'
CLS
MENU m$()
IF mod_level=0 THEN
mod_level$="0" !reinitialize modulation leveling
ENDIF
IF total_level=0 THEN
total_level$="0" !reinitialize total leveling
ENDIF
IF fb_level=0 THEN
fb_level$="0" !reinitialize feedback leveling
ENDIF
mod_level_prompt$="Modulation level:"
x0=350
y0=36
x1=400
y1=60 !mod level box coordinates
mod_level$=STR$(mod_level)
create_box(mod_level_prompt$,mod_level$,x0,y0,x1,y1)
total_level_prompt$="Total level:"
v0=350
w0=76
v1=400
w1=100 !total level box coordinates
total_level$=STR$(total_level)
create_box(total_level_prompt$,total_level$,v0,w0,v1,w1)
fb_level_prompt$="Feedback level:"
t0=350
u0=116
t1=400
u1=140 !total level box coordinates
fb_level$=STR$(fb_level)
create_box(fb_level_prompt$,fb_level$,t0,u0,t1,u1)
DO
a=MOUSEX !get mouse coordinates
b=MOUSEY
IF MOUSEK=1 !left mouse button
IF a>x0 AND b>y0 AND a<x1 AND b<y1
IF mod_level<99 THEN
INC mod_level !increment mod level
mod_level$=STR$(mod_level)
redraw_box(mod_level$,x0,y0,x1,y1)
PAUSE 3 !delay for mouse button
ENDIF
ELSE
IF a>v0 AND b>w0 AND a<v1 AND b<w1
IF total_level<99 THEN
INC total_level !increment total level
total_level$=STR$(total_level)
redraw_box(total_level$,v0,w0,v1,w1)
PAUSE 3 !delay for mouse button
ENDIF
ELSE
IF a>t0 AND b>u0 AND a<t1 AND b<u1
IF fb_level<7 THEN
INC fb_level !increment feedback level
fb_level$=STR$(fb_level)
redraw_box(fb_level$,t0,u0,t1,u1)
PAUSE 10 !delay for mouse button
ENDIF
ENDIF
ENDIF
ENDIF
ELSE
IF MOUSEK=2 THEN !right mouse button
IF a>x0 AND b>y0 AND a<x1 AND b<y1
IF mod_level>0 THEN
DEC mod_level !decrement mod level
mod_level$=STR$(mod_level)
redraw_box(mod_level$,x0,y0,x1,y1)
PAUSE 3 !delay for mouse button
ENDIF
ELSE
IF a>v0 AND b>w0 AND a<v1 AND b<w1
IF total_level>0 THEN
DEC total_level !decrement total level
total_level$=STR$(total_level)
redraw_box(total_level$,v0,w0,v1,w1)
PAUSE 3 !delay for mouse button
ENDIF
ELSE
IF a>t0 AND b>u0 AND a<t1 AND b<u1
IF fb_level>0 THEN
DEC fb_level !decrement feedback level
fb_level$=STR$(fb_level)
redraw_box(fb_level$,t0,u0,t1,u1)
PAUSE 10 !delay for mouse button
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
EXIT IF MOUSEK=3 !exit loop for both buttons
LOOP
n=10 !modulation leveling (MSB) is byte 0A
new_mod_level=99-mod_level !calculate values
new_total_level=99-total_level
IF new_mod_level=99 THEN !for null value byte 0A--> 07
temp=7
ELSE
temp=(new_mod_level AND &HF0)/16 !temp:shift right 4x/mask 4 lower bits
ENDIF
a(n)=temp !store split value
INC n !modulation leveling (LSB) is byte 0B
IF new_mod_level=99 THEN !for null value byte 0B --> 0F
temp=15
ELSE
temp=new_mod_level AND &HF !temp:mask upper 4 bits
ENDIF
a(n)=temp !store split value
INC n !total leveling (MSB) is byte 0C
IF new_total_level=99 THEN
temp=7
ELSE
temp=(new_total_level AND &HF0)/16
ENDIF
a(n)=temp
INC n !modulation leveling (LSB) is byte 0D
IF new_total_level=99 THEN
temp=15
ELSE
temp=new_total_level AND &HF
ENDIF
a(n)=temp
n=34 !feedback leveling (MSB) is byte 22
a(n)=(fb_level AND &H6)/2 !MSB:mask 1st 2 bits shift right 1x
INC n !feedback leveling (LSB) is byte 23
a(n)=(fb_level AND &H1)*8 !LSB:mask last bit shift left 3x
'
RETURN
'
PROCEDURE am_fm
'
CLS
MENU m$()
IF ams=0 THEN
ams$="0" !reinitialize AM sensitivity
ENDIF
IF fm_en=0 THEN
fm_en$="OFF" !reinitialize FM enable
ELSE
fm_en$="ON"
ENDIF
IF pms=0 THEN
pms$="0" !reinitialize FM sensitivity
ENDIF
IF fm_delay=0 THEN
fm_delay$="0" !reinitialize FM delay time
ENDIF
IF sus_en=0 THEN
sus_en$="OFF" !reinitialize sustain enable
ELSE
sus_en$="ON"
ENDIF
ams_prompt$="AM Sensitivity:"
x0=350
y0=20
x1=400
y1=44 !ams box coordinates
ams$=STR$(ams)
create_box(ams_prompt$,ams$,x0,y0,x1,y1)
fm_en_prompt$="FM enable:"
v0=350
w0=50
v1=410
w1=74 !fm en box coordinates
create_box(fm_en_prompt$,fm_en$,v0,w0,v1,w1)
pms_prompt$="FM Sensitivity:"
t0=350
u0=80
t1=400
u1=104 !pms box coordinates
pms$=STR$(pms)
create_box(pms_prompt$,pms$,t0,u0,t1,u1)
fm_delay_prompt$="FM delay:"
r0=350
s0=110
r1=420
s1=134 !fm delay box coordinates
fm_delay$=STR$(fm_delay)
create_box(fm_delay_prompt$,fm_delay$,r0,s0,r1,s1)
sus_en_prompt$="Sustain Enable:"
p0=350
q0=140
p1=410
q1=164 !sustain en box coordinates
create_box(sus_en_prompt$,sus_en$,p0,q0,p1,q1)
DO
a=MOUSEX !get mouse coordinates
b=MOUSEY
IF MOUSEK=1 !left mouse button
IF a>x0 AND b>y0 AND a<x1 AND b<y1
IF ams<3 THEN
INC ams !increment ams
ams$=STR$(ams)
redraw_box(ams$,x0,y0,x1,y1)
PAUSE 10 !delay for mouse button
ENDIF
ELSE
IF a>v0 AND b>w0 AND a<v1 AND b<w1
fm_en$="ON"
redraw_box(fm_en$,v0,w0,v1,w1)
PAUSE 10 !delay for mouse button
ELSE
IF a>t0 AND b>u0 AND a<t1 AND b<u1
IF pms<7 THEN
INC pms !increment pms
pms$=STR$(pms)
redraw_box(pms$,t0,u0,t1,u1)
PAUSE 10 !delay for mouse button
ENDIF
ELSE
IF a>r0 AND b>s0 AND a<r1 AND b<s1
IF fm_delay<127 THEN
INC fm_delay !increment fm delay
fm_delay$=STR$(fm_delay)
redraw_box(fm_delay$,r0,s0,r1,s1)
PAUSE 3 !delay for mouse button
ENDIF
ELSE
IF a>p0 AND b>q0 AND a<p1 AND b<q1
sus_en$="ON"
redraw_box(sus_en$,p0,q0,p1,q1)
PAUSE 10 !delay for mouse button
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ELSE
IF MOUSEK=2 !right mouse button
IF a>x0 AND b>y0 AND a<x1 AND b<y1
IF ams>0 THEN
DEC ams !decrement ams
ams$=STR$(ams)
redraw_box(ams$,x0,y0,x1,y1)
PAUSE 10 !delay for mouse button
ENDIF
ELSE
IF a>v0 AND b>w0 AND a<v1 AND b<w1
fm_en$="OFF"
redraw_box(fm_en$,v0,w0,v1,w1)
PAUSE 10 !delay for mouse button
ELSE
IF a>t0 AND b>u0 AND a<t1 AND b<u1
IF pms>0 THEN
DEC pms !decrement pms
pms$=STR$(pms)
redraw_box(pms$,t0,u0,t1,u1)
PAUSE 10 !delay for mouse button
ENDIF
ELSE
IF a>r0 AND b>s0 AND a<r1 AND b<s1
IF fm_delay>0 THEN
DEC fm_delay !decrement fm delay
fm_delay$=STR$(fm_delay)
redraw_box(fm_delay$,r0,s0,r1,s1)
PAUSE 3 !delay for mouse button
ENDIF
ELSE
IF a>p0 AND b>q0 AND a<p1 AND b<q1
sus_en$="OFF"
redraw_box(sus_en$,p0,q0,p1,q1)
PAUSE 10 !delay for mouse button
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
EXIT IF MOUSEK=3
LOOP
n=37
' Amplitude Modulation Sensitivity is byte 25
a(n)=ams
' Pitch Modulation Sensitivity is byte 24
DEC n
a(n)=pms
n=48
' FM delay time are bytes 30 & 31
a(n)=SHR((fm_delay AND &HF0),4)
INC n
a(n)=fm_delay AND &HF
n=52
' FM Enable/Sustain Enable is first 2 bits of byte 34
IF fm_en$="OFF" THEN
fm_en=0
ELSE
fm_en=1
ENDIF
IF sus_en$="OFF" THEN
sus_en=0
ELSE
sus_en=1
ENDIF
a(n)=SHL(fm_en,3) OR SHL(sus_en,2)
'
RETURN
'
PROCEDURE lks_rks(VAR lks_hi,lks_lo,rks)
'
IF lks_hi=0 THEN
lks_hi$="0" !reinitialize level key scaling hi
ENDIF
IF lks_lo=0 THEN
lks_lo$="0" !reinitialize level key scaling lo
ENDIF
IF rks=0 THEN
rks$="0" !reinitialize rate key scaling
ENDIF
lks_hi_prompt$="Level Key Scale hi:"
x0=350
y0=36
x1=400
y1=60 !lks hi box coordinates
lks_hi$=STR$(lks_hi)
create_box(lks_hi_prompt$,lks_hi$,x0,y0,x1,y1)
lks_lo_prompt$="Level Key Scale lo:"
v0=350
w0=76
v1=400
w1=100 !lks lo box coordinates
lks_lo$=STR$(lks_lo)
create_box(lks_lo_prompt$,lks_lo$,v0,w0,v1,w1)
rks_prompt$="Rate Key Scale:"
t0=350
u0=116
t1=400
u1=140 !rks box coordinates
rks$=STR$(rks)
create_box(rks_prompt$,rks$,t0,u0,t1,u1)
DO
a=MOUSEX !get mouse coordinates
b=MOUSEY
IF MOUSEK=1 !left mouse button
IF a>x0 AND b>y0 AND a<x1 AND b<y1
IF lks_hi<15 THEN
INC lks_hi !increment lks hi
lks_hi$=STR$(lks_hi)
redraw_box(lks_hi$,x0,y0,x1,y1)
PAUSE 10 !delay for mouse button
ENDIF
ELSE
IF a>v0 AND b>w0 AND a<v1 AND b<w1
IF lks_lo<15 THEN
INC lks_lo !increment lks lo
lks_lo$=STR$(lks_lo)
redraw_box(lks_lo$,v0,w0,v1,w1)
PAUSE 10 !delay for mouse button
ENDIF
ELSE
IF a>t0 AND b>u0 AND a<t1 AND b<u1
IF rks<3 THEN
INC rks !increment rks
rks$=STR$(rks)
redraw_box(rks$,t0,u0,t1,u1)
PAUSE 10 !delay for mouse button
ENDIF
ENDIF
ENDIF
ENDIF
ELSE
IF MOUSEK=2 !right mouse button
IF a>x0 AND b>y0 AND a<x1 AND b<y1
IF lks_hi>0 THEN
DEC lks_hi !decrement lks hi
lks_hi$=STR$(lks_hi)
redraw_box(lks_hi$,x0,y0,x1,y1)
PAUSE 10 !delay for mouse button
ENDIF
ELSE
IF a>v0 AND b>w0 AND a<v1 AND b<w1
IF lks_lo>0 THEN
DEC lks_lo !decrement lks lo
lks_lo$=STR$(lks_lo)
redraw_box(lks_lo$,v0,w0,v1,w1)
PAUSE 10 !delay for mouse button
ENDIF
ELSE
IF a>t0 AND b>u0 AND a<t1 AND b<u1
IF rks>0 THEN
DEC rks !decrement rks
rks$=STR$(rks)
redraw_box(rks$,t0,u0,t1,u1)
PAUSE 10 !delay for mouse button
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
EXIT IF MOUSEK=3 !exit loop for both buttons
LOOP
RETURN
'
PROCEDURE envelope(VAR atk,d1r,d1l,d2r,rr,srr,am_en$)
'
IF rez=2 THEN
CLS
ENDIF
BOX 0,10,410,185
IF atk=0 THEN
atk$="0" !reinitialize attack rate
ENDIF
IF d1r=0 THEN
d1r$="0" !reinitialize decay 1 rate
ENDIF
IF d1l=0 THEN
d1l$="0" !reinitialize decay 1 level
ENDIF
IF d2r=0 THEN
d2r$="0" !reinitialize decay 2 rate
ENDIF
IF rr=0 THEN
rr$="0" !reinitialize release rate
ENDIF
IF srr=0 THEN
srr$="0" !reinitialize sustain release rate
ENDIF
atk_prompt$="Attack Rate:"
x0=350
y0=10
x1=410
y1=35 !atk box coordinates
atk$=STR$(atk)
create_box(atk_prompt$,atk$,x0,y0,x1,y1)
d1r_prompt$="Decay 1 Rate:"
v0=350
w0=35
v1=410
w1=60 !d1r box coordinates
d1r$=STR$(d1r)
create_box(d1r_prompt$,d1r$,v0,w0,v1,w1)
d1l_prompt$="Decay 1 Level:"
t0=350
u0=60
t1=410
u1=85 !d1l box coordinates
d1l$=STR$(d1l)
create_box(d1l_prompt$,d1l$,t0,u0,t1,u1)
d2r_prompt$="Decay 2 Rate:"
r0=350
s0=85
r1=410
s1=110 !d2r box coordinates
d2r$=STR$(d2r)
create_box(d2r_prompt$,d2r$,r0,s0,r1,s1)
rr_prompt$="Release Rate:"
p0=350
q0=110
p1=410
q1=135 !rr box coordinates
rr$=STR$(rr)
create_box(rr_prompt$,rr$,p0,q0,p1,q1)
srr_prompt$="Sustain Release Rate:"
n0=350
o0=135
n1=410
o1=160 !srr box coordinates
srr$=STR$(srr)
create_box(srr_prompt$,srr$,n0,o0,n1,o1)
am_en_prompt$="AM Enable:"
l0=350
m0=160
l1=410
m1=185 !am en box coordinates
create_box(am_en_prompt$,am_en$,l0,m0,l1,m1)
DO
a=MOUSEX !get mouse coordinates
b=MOUSEY
IF MOUSEK=1 !left mouse button
IF a>x0 AND b>y0 AND a<x1 AND b<y1
IF atk<63 THEN
INC atk !increment atk
atk$=STR$(atk)
redraw_box(atk$,x0,y0,x1,y1)
PAUSE 3 !delay for mouse button
ENDIF
ELSE
IF a>v0 AND b>w0 AND a<v1 AND b<w1
IF d1r<63 THEN
INC d1r !increment d1r
d1r$=STR$(d1r)
redraw_box(d1r$,v0,w0,v1,w1)
PAUSE 3 !delay for mouse button
ENDIF
ELSE
IF a>t0 AND b>u0 AND a<t1 AND b<u1
IF d1l<15 THEN
INC d1l !increment d1l
d1l$=STR$(d1l)
redraw_box(d1l$,t0,u0,t1,u1)
PAUSE 10 !delay for mouse button
ENDIF
ELSE
IF a>r0 AND b>s0 AND a<r1 AND b<s1
IF d2r<63 THEN
INC d2r !increment d2r
d2r$=STR$(d2r)
redraw_box(d2r$,r0,s0,r1,s1)
PAUSE 3 !delay for mouse button
ENDIF
ELSE
IF a>p0 AND b>q0 AND a<p1 AND b<q1
IF rr<15 THEN
INC rr !increment rr
rr$=STR$(rr)
redraw_box(rr$,p0,q0,p1,q1)
PAUSE 10 !delay for mouse button
ENDIF
ELSE
IF a>n0 AND b>o0 AND a<n1 AND b<o1
IF srr<15 THEN
INC srr !increment srr
srr$=STR$(srr)
redraw_box(srr$,n0,o0,n1,o1)
PAUSE 10 !delay for mouse button
ENDIF
ELSE
IF a>l0 AND b>m0 AND a<l1 AND b<m1
am_en$="ON"
redraw_box(am_en$,l0,m0,l1,m1)
PAUSE 10 !delay for mouse button
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ELSE
IF MOUSEK=2 !right mouse button
IF a>x0 AND b>y0 AND a<x1 AND b<y1
IF atk>0 THEN
DEC atk !decrement atk
atk$=STR$(atk)
redraw_box(atk$,x0,y0,x1,y1)
PAUSE 3 !delay for mouse button
ENDIF
ELSE
IF a>v0 AND b>w0 AND a<v1 AND b<w1
IF d1r>0 THEN
DEC d1r !decrement d1r
d1r$=STR$(d1r)
redraw_box(d1r$,v0,w0,v1,w1)
PAUSE 3 !delay for mouse button
ENDIF
ELSE
IF a>t0 AND b>u0 AND a<t1 AND b<u1
IF d1l>0 THEN
DEC d1l !decrement d1l
d1l$=STR$(d1l)
redraw_box(d1l$,t0,u0,t1,u1)
PAUSE 10 !delay for mouse button
ENDIF
ELSE
IF a>r0 AND b>s0 AND a<r1 AND b<s1
IF d2r>0 THEN
DEC d2r !decrement d2r
d2r$=STR$(d2r)
redraw_box(d2r$,r0,s0,r1,s1)
PAUSE 3 !delay for mouse button
ENDIF
ELSE
IF a>p0 AND b>q0 AND a<p1 AND b<q1
IF rr>0 THEN
DEC rr !decrement rr
rr$=STR$(rr)
redraw_box(rr$,p0,q0,p1,q1)
PAUSE 10 !delay for mouse button
ENDIF
ELSE
IF a>n0 AND b>o0 AND a<n1 AND b<o1
IF srr>0 THEN
DEC srr !decrement srr
srr$=STR$(srr)
redraw_box(srr$,n0,o0,n1,o1)
PAUSE 10 !delay for mouse button
ENDIF
ELSE
IF a>l0 AND b>m0 AND a<l1 AND b<m1
am_en$="OFF"
redraw_box(am_en$,l0,m0,l1,m1)
PAUSE 10 !delay for mouse button
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
EXIT IF MOUSEK=3 !exit for both buttons
LOOP
RETURN
'
PROCEDURE generate_wave(VAR wavform)
'
lx=190
rx=450
ty=45
by=180
'
SGET tempuse$
GRAPHMODE 1
DEFFILL 1,2,2
DEFTEXT 1,0,0,6
DEFLINE 1,3
growbox(lx,ty,10,10,lx,ty,rx-lx,by-ty)
PBOX lx,ty,rx,by
BOX lx,ty,rx,by
DEFLINE 1,1
TEXT lx+30,ty+10," Waveform Shape "
DEFFILL 1,2,8
PBOX lx+25,ty+25,rx-200,ty+40
PBOX lx+25,ty+45,rx-200,ty+60
PBOX lx+25,ty+65,rx-200,by-55
PBOX lx+25,by-50,rx-200,by-35
PBOX lx+115,by-20,rx-110,by-5
DEFFILL 0,2,8
PBOX lx+25,ty+25,rx-203,ty+39
PBOX lx+25,ty+45,rx-203,ty+59
PBOX lx+25,ty+65,rx-203,by-56
PBOX lx+25,by-50,rx-203,by-36
PBOX lx+115,by-20,rx-113,by-6
BOX lx+25,ty+25,rx-203,ty+39
BOX lx+27,ty+27,rx-205,ty+37
BOX lx+25,ty+45,rx-203,ty+59
BOX lx+27,ty+47,rx-205,ty+57
BOX lx+25,ty+65,rx-203,by-56
BOX lx+27,ty+67,rx-205,ty+77
BOX lx+25,by-50,rx-203,by-36
BOX lx+27,by-48,rx-205,by-38
BOX lx+115,by-20,rx-113,by-6
BOX lx+117,by-18,rx-115,by-8
TEXT lx+38,ty+35,"1"
TEXT lx+38,ty+55,"2"
TEXT lx+38,by-60,"3"
TEXT lx+38,by-40,"4"
TEXT lx+124,by-10,"OK"
TEXT lx+68,ty+35," Sine Wave "
TEXT lx+68,ty+55," Half Sine Wave "
TEXT lx+68,by-60," Square Wave "
TEXT lx+68,by-40," Half Square Wave "
CLR choice1,choice2,choice3,choice4,choice5
REPEAT
x=MOUSEX
y=MOUSEY
k=MOUSEK
IF x>lx+27 AND x<rx-205 AND y>ty+27 AND y<ty+37 AND k=1
wavform=0
IF choice1=1
DEFTEXT 1
GRAPHMODE 1
DEFLINE 1,1
DEFFILL 1,2,8
PBOX lx+25,ty+25,rx-200,ty+40
DEFFILL 0,2,8
PBOX lx+25,ty+25,rx-203,ty+39
BOX lx+25,ty+25,rx-203,ty+39
BOX lx+27,ty+27,rx-205,ty+37
TEXT lx+38,ty+35,"1"
choice1=0
ELSE
GRAPHMODE 2
choice1=1
DEFFILL 0,2,8
PBOX lx+25,ty+25,rx-200,ty+40
DEFFILL 1,2,8
PBOX lx+25,ty+25,rx-203,ty+39
DEFLINE 0,1
GRAPHMODE 3
BOX lx+27,ty+27,rx-205,ty+37
DEFTEXT 0
TEXT lx+38,ty+35,"1"
ENDIF
ENDIF
IF x>lx+27 AND x<rx-205 AND y>ty+47 AND y<ty+57 AND k=1
wavform=2
IF choice2=1
DEFTEXT 1
GRAPHMODE 1
DEFLINE 1,1
DEFFILL 1,2,8
PBOX lx+25,ty+45,rx-200,ty+60
DEFFILL 0,2,8
PBOX lx+25,ty+45,rx-203,ty+59
BOX lx+25,ty+45,rx-203,ty+59
BOX lx+27,ty+47,rx-205,ty+57
TEXT lx+38,ty+55,"2"
choice2=0
ELSE
GRAPHMODE 2
choice2=1
DEFFILL 0,2,8
PBOX lx+25,ty+45,rx-200,ty+60
DEFFILL 1,2,8
PBOX lx+25,ty+45,rx-203,ty+59
DEFLINE 0,1
GRAPHMODE 3
BOX lx+27,ty+47,rx-205,ty+57
DEFTEXT 0
TEXT lx+38,ty+55,"2"
ENDIF
ENDIF
IF x>lx+27 AND x<rx-205 AND y>ty+67 AND y<ty+77 AND k=1
wavform=1
IF choice3=1
DEFTEXT 1
GRAPHMODE 1
DEFLINE 1,1
DEFFILL 1,2,8
PBOX lx+25,ty+65,rx-200,by-55
DEFFILL 0,2,8
PBOX lx+25,ty+65,rx-203,by-56
BOX lx+25,ty+65,rx-203,by-56
BOX lx+27,ty+67,rx-205,ty+77
TEXT lx+38,by-60,"3"
choice3=0
ELSE
GRAPHMODE 2
choice3=1
DEFFILL 0,2,8
PBOX lx+25,ty+65,rx-200,by-55
DEFFILL 1,2,8
PBOX lx+25,ty+65,rx-203,by-56
DEFLINE 0,1
GRAPHMODE 3
BOX lx+27,ty+67,rx-205,ty+77
DEFTEXT 0
TEXT lx+38,by-60,"3"
ENDIF
ENDIF
IF x>lx+27 AND x<rx-203 AND y>by-48 AND y<by-28 AND k=1
wavform=3
IF choice4=1
DEFTEXT 1
GRAPHMODE 1
DEFLINE 1,1
DEFFILL 1,2,8
PBOX lx+25,by-50,rx-200,by-35
DEFFILL 0,2,8
PBOX lx+25,by-50,rx-203,by-36
BOX lx+25,by-50,rx-203,by-36
BOX lx+27,by-48,rx-205,by-38
TEXT lx+38,by-40,"4"
choice4=0
ELSE
GRAPHMODE 2
choice4=1
DEFFILL 0,2,8
PBOX lx+25,by-50,rx-200,by-35
DEFFILL 1,2,8
PBOX lx+25,by-50,rx-203,by-36
DEFLINE 0,1
GRAPHMODE 3
BOX lx+27,by-48,rx-205,by-38
DEFTEXT 0
TEXT lx+38,by-40,"4"
ENDIF
ENDIF
IF x>lx+117 AND x<rx-115 AND y>by-18 AND y<by-8 AND k=1
choice5=1
ENDIF
PAUSE 10
UNTIL choice5<>0
PAUSE 5
GRAPHMODE 1
DEFLINE 1
DEFTEXT 1
SPUT tempuse$
shrinkbox(lx,ty,20,5,lx,ty,rx-lx,by-ty)
CLR tempuse$
RETURN
'
PROCEDURE delay_note_on(VAR delay)
'
lx=190
rx=450
ty=45
by=180
'
SGET tempuse$
GRAPHMODE 1
DEFFILL 1,2,2
DEFTEXT 1,0,0,6
DEFLINE 1,3
growbox(lx,ty,10,10,lx,ty,rx-lx,by-ty)
PBOX lx,ty,rx,by
BOX lx,ty,rx,by
DEFLINE 1,1
TEXT lx+30,ty+10," MIDI Note On Delay: "
DEFFILL 1,2,8
PBOX lx+25,ty+25,rx-200,ty+40
PBOX lx+25,ty+45,rx-200,ty+60
PBOX lx+25,ty+65,rx-200,by-55
PBOX lx+25,by-50,rx-200,by-35
PBOX lx+115,by-20,rx-110,by-5
DEFFILL 0,2,8
PBOX lx+25,ty+25,rx-203,ty+39
PBOX lx+25,ty+45,rx-203,ty+59
PBOX lx+25,ty+65,rx-203,by-56
PBOX lx+25,by-50,rx-203,by-36
PBOX lx+115,by-20,rx-113,by-6
BOX lx+25,ty+25,rx-203,ty+39
BOX lx+27,ty+27,rx-205,ty+37
BOX lx+25,ty+45,rx-203,ty+59
BOX lx+27,ty+47,rx-205,ty+57
BOX lx+25,ty+65,rx-203,by-56
BOX lx+27,ty+67,rx-205,ty+77
BOX lx+25,by-50,rx-203,by-36
BOX lx+27,by-48,rx-205,by-38
BOX lx+115,by-20,rx-113,by-6
BOX lx+117,by-18,rx-115,by-8
TEXT lx+38,ty+35,"1"
TEXT lx+38,ty+55,"2"
TEXT lx+38,by-60,"3"
TEXT lx+38,by-40,"4"
TEXT lx+124,by-10,"OK"
TEXT lx+68,ty+35," 3 seconds "
TEXT lx+68,ty+55," 9 seconds "
TEXT lx+68,by-60," 21 seconds "
TEXT lx+68,by-40," 30 seconds "
CLR choice1,choice2,choice3,choice4,choice5,delay
REPEAT
x=MOUSEX
y=MOUSEY
k=MOUSEK
a=MENU(14)
b=256
IF x>lx+27 AND x<rx-205 AND y>ty+27 AND y<ty+37 AND k=1
delay=1
IF choice1=1
DEFTEXT 1
GRAPHMODE 1
DEFLINE 1,1
DEFFILL 1,2,8
PBOX lx+25,ty+25,rx-200,ty+40
DEFFILL 0,2,8
PBOX lx+25,ty+25,rx-203,ty+39
BOX lx+25,ty+25,rx-203,ty+39
BOX lx+27,ty+27,rx-205,ty+37
TEXT lx+38,ty+35,"1"
choice1=0
ELSE
GRAPHMODE 2
choice1=1
DEFFILL 0,2,8
PBOX lx+25,ty+25,rx-200,ty+40
DEFFILL 1,2,8
PBOX lx+25,ty+25,rx-203,ty+39
DEFLINE 0,1
GRAPHMODE 3
BOX lx+27,ty+27,rx-205,ty+37
DEFTEXT 0
TEXT lx+38,ty+35,"1"
ENDIF
ENDIF
IF x>lx+27 AND x<rx-205 AND y>ty+47 AND y<ty+57 AND k=1
delay=2
IF choice2=1
DEFTEXT 1
GRAPHMODE 1
DEFLINE 1,1
DEFFILL 1,2,8
PBOX lx+25,ty+45,rx-200,ty+60
DEFFILL 0,2,8
PBOX lx+25,ty+45,rx-203,ty+59
BOX lx+25,ty+45,rx-203,ty+59
BOX lx+27,ty+47,rx-205,ty+57
TEXT lx+38,ty+55,"2"
choice2=0
ELSE
GRAPHMODE 2
choice2=1
DEFFILL 0,2,8
PBOX lx+25,ty+45,rx-200,ty+60
DEFFILL 1,2,8
PBOX lx+25,ty+45,rx-203,ty+59
DEFLINE 0,1
GRAPHMODE 3
BOX lx+27,ty+47,rx-205,ty+57
DEFTEXT 0
TEXT lx+38,ty+55,"2"
ENDIF
ENDIF
IF x>lx+27 AND x<rx-205 AND y>ty+67 AND y<ty+77 AND k=1
delay=3
IF choice3=1
DEFTEXT 1
GRAPHMODE 1
DEFLINE 1,1
DEFFILL 1,2,8
PBOX lx+25,ty+65,rx-200,by-55
DEFFILL 0,2,8
PBOX lx+25,ty+65,rx-203,by-56
BOX lx+25,ty+65,rx-203,by-56
BOX lx+27,ty+67,rx-205,ty+77
TEXT lx+38,by-60,"3"
choice3=0
ELSE
GRAPHMODE 2
choice3=1
DEFFILL 0,2,8
PBOX lx+25,ty+65,rx-200,by-55
DEFFILL 1,2,8
PBOX lx+25,ty+65,rx-203,by-56
DEFLINE 0,1
GRAPHMODE 3
BOX lx+27,ty+67,rx-205,ty+77
DEFTEXT 0
TEXT lx+38,by-60,"3"
ENDIF
ENDIF
IF x>lx+27 AND x<rx-203 AND y>by-48 AND y<by-28 AND k=1
delay=4
IF choice4=1
DEFTEXT 1
GRAPHMODE 1
DEFLINE 1,1
DEFFILL 1,2,8
PBOX lx+25,by-50,rx-200,by-35
DEFFILL 0,2,8
PBOX lx+25,by-50,rx-203,by-36
BOX lx+25,by-50,rx-203,by-36
BOX lx+27,by-48,rx-205,by-38
TEXT lx+38,by-40,"4"
choice4=0
ELSE
GRAPHMODE 2
choice4=1
DEFFILL 0,2,8
PBOX lx+25,by-50,rx-200,by-35
DEFFILL 1,2,8
PBOX lx+25,by-50,rx-203,by-36
DEFLINE 0,1
GRAPHMODE 3
BOX lx+27,by-48,rx-205,by-38
DEFTEXT 0
TEXT lx+38,by-40,"4"
ENDIF
ENDIF
IF x>lx+117 AND x<rx-115 AND y>by-18 AND y<by-8 AND k=1
choice5=1
ENDIF
PAUSE 10
UNTIL choice5<>0
PAUSE 5
IF delay=0
delay=1
ENDIF
GRAPHMODE 1
DEFLINE 1
DEFTEXT 1
SPUT tempuse$
shrinkbox(lx,ty,20,5,lx,ty,rx-lx,by-ty)
CLR tempuse$
RETURN
'
PROCEDURE popup_audition(pitch)
lx=124
rx=516
ty=64
by=84
'
'
IF rez=2
offset=10
ty=ty-10
by=by+10
ENDIF
SGET tempuse$
DEFFILL 0,2,8
IF rez=2
DEFTEXT 1,0,0,13
ELSE
DEFTEXT 1,0,0,6
ENDIF
DEFLINE 1,3
growbox(lx,ty,10,10,lx,ty,rx-lx,by-ty)
PBOX lx,ty,rx,by
BOX lx,ty,rx,by
DEFLINE 1,1
BOX lx+8,ty+2,rx-8,by-2
IF rez=2
IF pitch=1
TEXT lx+35,ty+4+9+offset,"Auditioning Patch Sound Bank(low pitch)"
ENDIF
IF pitch=2
TEXT lx+35,ty+4+9+offset,"Auditioning Patch Sound Bank(medium pitch)"
ENDIF
IF pitch=3
TEXT lx+35,ty+4+9+offset,"Auditioning Patch Sound Bank(high pitch)"
ENDIF
ELSE
IF pitch=1
TEXT lx+35,ty+4+9,"Auditioning Patch Sound Bank(low pitch)"
ENDIF
IF pitch=2
TEXT lx+35,ty+4+9,"Auditioning Patch Sound Bank(medium pitch)"
ENDIF
IF pitch=3
TEXT lx+35,ty+4+9,"Auditioning Patch Sound Bank(high pitch)"
ENDIF
ENDIF
SELECT midi_delay
CASE 1
DELAY 1 !Delay 1 second between notes
CASE 2
DELAY 3 !Delay 3 seconds between notes
CASE 3
DELAY 7 !Delay 7 seconds between notes
CASE 4
DELAY 10 !Delay 10 seconds between notes
ENDSELECT
'
SPUT tempuse$
CLR tempuse$
PAUSE 5
shrinkbox(lx,ty,20,5,lx,ty,rx-lx,by-ty)
RETURN
'
' ***********************************************************************
' THE FOLLOWING ROUTINES DISPLAY ONLINE HELP FOR MOST PROGRAM FUNCTIONS
' IN THE FORM OF POP-UP BOXES.
' ***********************************************************************
'
PROCEDURE about_general
'
lx=94
rx=575
ty=14
by=175
'
DIM helpbox$(47)
helpbox$(1)="Welcome to the Yamaha Patch Editor/Librarian for"
helpbox$(2)="the PSS Portasound Series. This help section"
helpbox$(3)="will provide basic information on GEM menu commands"
helpbox$(4)="and also provide an understanding of the System"
helpbox$(5)="Exclusive (SYSEX) MIDI data that is supported with"
helpbox$(6)="this keyboard instrument."
helpbox$(7)=""
helpbox$(8)="Your Yamaha keyboard instrument consists of highly"
helpbox$(9)="complex digital tone generator components that are"
helpbox$(10)="capable of producing a multitude of voice instru-"
helpbox$(11)="ments which may be stored in any of five voice"
helpbox$(12)="banks. A total of 100 voices are permanently stored"
helpbox$(13)="in the instrument and were all preset at the factory."
helpbox$(14)="An on board digital synthesizer allows you to edit"
helpbox$(15)="any voice instrument which can be stored in the voice"
helpbox$(16)="banks without any MIDI capability."
helpbox$(17)=""
helpbox$(18)="This program is designed to easily assist you in cre-"
helpbox$(19)="ating/editing/modifying any instrument voice (patch)."
helpbox$(20)="The power of the MIDI interface allows the use of a"
helpbox$(21)="computer to control 'patch editing' at a much higher"
helpbox$(22)="level. Your Yamaha keyboard instrument provides only"
helpbox$(23)="basic editing capabilities in modifying an internal"
helpbox$(24)="voice, however, there are limitations. This program"
helpbox$(25)="introduces several editing capabilities that cannot"
helpbox$(26)="be performed with the on board digital synthesizer."
helpbox$(27)="In addition, it is convenient to easily load and save"
helpbox$(28)="all patches to/from disk. With the aid of the LHA"
helpbox$(29)="archiving utility, the program is complemented with"
helpbox$(30)="a simple librarian interface, complete with patch de-"
helpbox$(31)="scription capability (comments) and easy retrieval of"
helpbox$(32)="stored patches in the system archive file, PATCHES.LZH"
helpbox$(33)=""
helpbox$(34)="The SYSEX messages within the Yamaha keyboard"
helpbox$(35)="instrument consist of the 5 voice banks, Song Memory"
helpbox$(36)="(both melody 1-5 and chord 1-5), and the Custom"
helpbox$(37)="Drummer. It is the Song Memory itself which makes"
helpbox$(38)="up most of the SYSEX data (over 12 Kbytes) and"
helpbox$(39)="PSSLIB currently supports everything but this for now."
helpbox$(40)=""
helpbox$(41)="The rest of this help section provides basic program"
helpbox$(42)="operation and definitions of all patch editing para-"
helpbox$(43)="meters. All parameters that effect the Modulator will"
helpbox$(44)="basically effect the tonal quality of the sound patch."
helpbox$(45)="All parameters that effect the Carrier will basically"
helpbox$(46)="effect the overall sound quality as well as the volume"
helpbox$(47)="of the sound patch."
lineno=DIM?(helpbox$())
do_helpbox
ERASE helpbox$()
VOID FRE(0)
PAUSE 20
'
RETURN
'
PROCEDURE about_file
'
lx=124
rx=516
ty=14
by=175
'
DIM helpbox$(36)
helpbox$(1)="Load Patch - loads a patch from the system"
helpbox$(2)="archive file into memory. Use the standard"
helpbox$(3)="item selector to select the desired patch"
helpbox$(4)="sound. PSSLIB will prompt you if the patch"
helpbox$(5)="doesn't exist within the archive, in which"
helpbox$(6)="case, you may select a correct existing one."
helpbox$(7)="Use the Verbose option to get a current"
helpbox$(8)="listing of all valid patch names."
helpbox$(9)=""
helpbox$(10)="Save Patch - saves a patch from memory to"
helpbox$(11)="the system archive file. You may use up "
helpbox$(12)="to 50 characters to describe the patch "
helpbox$(13)="sound. Enter a new patch name via the "
helpbox$(14)="standard item selector. You may also"
helpbox$(15)="export the patch to be used with other "
helpbox$(16)="MIDI programs, if desired. The file will"
helpbox$(17)="saved with a .SYX extension."
helpbox$(18)=""
helpbox$(19)="Delete Patch - deletes a patch from the "
helpbox$(20)="system archive file. Use the standard"
helpbox$(21)="item selector to permanently delete the"
helpbox$(22)="patch sound from the system archive."
helpbox$(23)=" "
helpbox$(24)="Build Patch - clears the MIDI patch buffer"
helpbox$(25)="and allows you to build up a sound in"
helpbox$(26)="segments via each MIDI parameter group."
helpbox$(27)=""
helpbox$(28)="Verbose Directory - displays a listing of"
helpbox$(29)="all patch sounds within the system archive"
helpbox$(30)="file. Use CNTL/S and CNTL/Q to halt the"
helpbox$(31)="screen display while viewing the list. When"
helpbox$(32)="the list is done, press any key to return"
helpbox$(33)="to the GEM menus."
helpbox$(34)=""
helpbox$(35)="Quit - Quits the program and returns to "
helpbox$(36)="the GEM desktop"
lineno=DIM?(helpbox$())
do_helpbox
ERASE helpbox$()
VOID FRE(0)
PAUSE 20
'
RETURN
'
PROCEDURE about_buffer
'
lx=124
rx=550
ty=14
by=175
'
DIM helpbox$(17)
helpbox$(1)="View Parameters - displays all current MIDI"
helpbox$(2)="Patch Parameters in memory. There are 3"
helpbox$(3)="columns showing the Overall Modulation,"
helpbox$(4)="Modulator characteristics, and Carrier charac-"
helpbox$(5)="teristics of the patch sound."
helpbox$(6)=""
helpbox$(7)="View Buffer - displays all current MIDI Patch"
helpbox$(8)="Parameters in memory in hexadecimal format."
helpbox$(9)="This is how they appear when being sent or re-"
helpbox$(10)="ceived from the Yamaha keyboard instrument. The"
helpbox$(11)="current patch file name will also appear if it"
helpbox$(12)="was just previously loaded from disk."
helpbox$(13)="Note: The View Parameters mode is the default"
helpbox$(14)="viewing mode. Selecting a viewing mode from the"
helpbox$(15)="GEM menu will toggle between the two modes. You"
helpbox$(16)="may also use this function to guarantee that all"
helpbox$(17)="menu selections are available."
lineno=DIM?(helpbox$())
do_helpbox
ERASE helpbox$()
VOID FRE(0)
PAUSE 20
'
RETURN
'
PROCEDURE about_midi
'
lx=94
rx=555
ty=14
by=175
'
DIM helpbox$(80)
helpbox$(1)="Send Bank (1 - 5) - sends the current patch buffer"
helpbox$(2)="in memory to the patch bank of the Yamaha keyboard"
helpbox$(3)="instrument based on the menu selection. The "
helpbox$(4)="instrument will auto-switch to the selected bank as"
helpbox$(5)="long as it is in Voice mode. An ERR will be dis-"
helpbox$(6)="played on the Yamaha keyboard instrument for any MIDI"
helpbox$(7)="transmission errors."
helpbox$(8)=""
helpbox$(9)="Receive Bank (1 - 5) - receives a patch bank from the"
helpbox$(10)="Yamaha keyboard instrument and places it into memory."
helpbox$(11)="Two alert boxes are shown to allow you to prepare the"
helpbox$(12)="keyboard for transmission via the Memory Bulk Dump."
helpbox$(13)="After responding to the alert boxes, the monitor "
helpbox$(14)="screen will note that a 512 byte MIDI transmission"
helpbox$(15)="buffer was established. At the middle of the screen,"
helpbox$(16)="the message,'Waiting for MIDI.....' indicates that"
helpbox$(17)="you may now perform the bulk dump. Press the"
helpbox$(18)="'TRANSMIT CH./MEMORY BULK DUMP' twice (Note: the"
helpbox$(19)="display LED's will flash) and press the '+' button"
helpbox$(20)="once. The bottom of the screen will indicate that"
helpbox$(21)="MIDI data is being received. After reception, it"
helpbox$(22)="will indicate the bank that was received. There will"
helpbox$(23)="be a slight delay to allow the rest of the bulk dump"
helpbox$(24)="to occur. The Yamaha keyboard instrument will now"
helpbox$(25)="auto-switch to the selected received bank and the "
helpbox$(26)="current viewing mode will be displayed."
helpbox$(27)=""
helpbox$(28)="Import Custom Drummer/.SYX - loads and sends a .SYX"
helpbox$(29)="file via the standard file selector. If the file is"
helpbox$(30)="a voice patch (72 bytes), the patch will be routed"
helpbox$(31)="to the bank defined within the file (it is best to"
helpbox$(32)="name these with a 1-5 to match the corresponding"
helpbox$(33)="bank number). AN ERR will appear on the Yamaha if"
helpbox$(34)="a MIDI transmission error occurred. If the Yamaha"
helpbox$(35)="is already in Keyboard Assign mode [c.00], the"
helpbox$(36)="Custom Drummer will auto play if it is turned on,"
helpbox$(37)="otherwise, the current Rhythm Style will play since"
helpbox$(38)="this selection issues MIDI Start/MIDI Stop commands"
helpbox$(39)="which turns the drum machine either on or off."
helpbox$(40)=""
helpbox$(41)="Export Custom Drummer - receives and saves the Custom"
helpbox$(42)="Drummer Info to disk. Do a Memory BULK DUMP on the"
helpbox$(43)="synthesizer the same as receiving a bank. The System"
helpbox$(44)="MIDI buffer will be changed to 13800 bytes since this"
helpbox$(45)="is the last message to be received. (It may also take"
helpbox$(46)="up to 20 seconds or so, be patient!) Then, save it to"
helpbox$(47)="it to disk via the standard file selector."
helpbox$(48)=""
helpbox$(49)="Audition - selecting this option will allow you to"
helpbox$(50)="play 3 notes (low C, middle C, high C) when issuing"
helpbox$(51)="any MIDI Send command, which includes importing a"
helpbox$(52)=".SYX file. A dialog box will allow you 4 choices"
helpbox$(53)="for defining a MIDI Delay Value:"
helpbox$(54)=""
helpbox$(55)=" 3 seconds ( 1 sec between each note)"
helpbox$(56)=" 9 seconds ( 3 sec between each note)"
helpbox$(57)="21 seconds ( 7 sec between each note)"
helpbox$(58)="30 seconds (10 sec bewteen each note)"
helpbox$(59)=""
helpbox$(60)="The purpose of auditioning is to aid in selecting"
helpbox$(61)="the right combination of patch parameters before"
helpbox$(62)="saving. It is also convenient if your keyboard"
helpbox$(63)="is not close to your computer. The 3 C notes used"
helpbox$(64)="at different pitches should help especially with"
helpbox$(65)="AM sounds and Level Key Scaling (See Modulator/"
helpbox$(66)="Carrier). Once a delay value is specified, when"
helpbox$(67)="you issue any MIDI Send command, a popup dialog"
helpbox$(68)="will indicate the Low, Medium and High values"
helpbox$(69)="when they are sent."
helpbox$(70)=""
helpbox$(71)="Continually selecting the Audition option will"
helpbox$(72)="toggle the Audition Mode, that is, it turns on"
helpbox$(73)="and off indicated by a checkmark in front of the"
helpbox$(74)="option menu."
helpbox$(75)=""
helpbox$(76)=""
helpbox$(77)="Note: All of these MIDI functions will not be"
helpbox$(78)="initially selectable either if the Yamaha keyboard "
helpbox$(79)="instrument is turned off or not plugged into the ST "
helpbox$(80)="via the proper MIDI chords."
lineno=DIM?(helpbox$())
do_helpbox
ERASE helpbox$()
VOID FRE(0)
PAUSE 20
'
RETURN
'
PROCEDURE about_modulation
'
lx=94
rx=555
ty=14
by=175
'
DIM helpbox$(55)
helpbox$(1)="This patch parameter group is used to effect the"
helpbox$(2)="overall modulation of a patch sound. It is divided"
helpbox$(3)="into 2 subgroups: Leveling and AM/FM Functions."
helpbox$(4)=""
helpbox$(5)="Leveling - use this to enter all modulation leveling"
helpbox$(6)="functions via the mouse buttons."
helpbox$(7)=""
helpbox$(8)="Modulation Level - use this to increase or decrease"
helpbox$(9)="the Modulator's overall volume effect on the Carrier"
helpbox$(10)="signal. The allowable range is from 0 to 99."
helpbox$(11)=""
helpbox$(12)=""
helpbox$(13)="Total Level - use this to increase or decrease the"
helpbox$(14)="Carrier signal's volume, which will effectively"
helpbox$(15)="change the total patch sound volume. The allowable"
helpbox$(16)="range is from 0 to 99."
helpbox$(17)=""
helpbox$(18)="Feedback Level - use this to increase or decrease"
helpbox$(19)="how much the Modulator signal modulates itself. The"
helpbox$(20)="allowable range is from 0 to 7."
helpbox$(21)=""
helpbox$(22)="AM/FM - use this to enter any Amplitude Modulation"
helpbox$(23)="and/or Frequency Modulation functions to the patch"
helpbox$(24)="sound via the mouse buttons."
helpbox$(25)="AM Sensitivity - use this to increase or decrease"
helpbox$(26)="the amount of 'warble' to the patch sound. It will"
helpbox$(27)="only take effect when AM is enabled on either the"
helpbox$(28)="Modulator or the Carrier or both. The allowable"
helpbox$(29)="range is from 0 to 3."
helpbox$(30)=""
helpbox$(31)="FM enable - use this to toggle the Vibrato effect"
helpbox$(32)="of the patch sound. When 'ON', the Vibrato LED"
helpbox$(33)="under 'EFFECT' of the Yamaha keyboard instrument"
helpbox$(34)="should be lit."
helpbox$(35)=""
helpbox$(36)=""
helpbox$(37)="FM Sensitivity - use this to increase or decrease"
helpbox$(38)="the amount of Vibrato used when FM is enabled. This"
helpbox$(39)="also effects the overall 'pitch warble' of the "
helpbox$(40)="patch sound and is also referred to as the Pitch"
helpbox$(41)="Modulation Sensitivity. The allowable range is"
helpbox$(42)="from 0 to 7."
helpbox$(43)=""
helpbox$(44)="FM Delay Time - use this to increase or decrease "
helpbox$(45)="a time interval from when a note is pressed to when"
helpbox$(46)="the Vibrato will take effect when FM is enabled."
helpbox$(47)="The allowable range is from 0 to 127."
helpbox$(48)=""
helpbox$(49)="Sustain Enable - use this to toggle the Sustain"
helpbox$(50)="effect of the patch sound. When 'ON', the"
helpbox$(51)="Sustain LED under 'EFFECT' of the Yamaha keyboard"
helpbox$(52)="instrument should be lit. This function will"
helpbox$(53)="allow the Sustain Release Rate to override the"
helpbox$(54)="standard Release Rate in the Envelope parameter"
helpbox$(55)="group."
lineno=DIM?(helpbox$())
do_helpbox
ERASE helpbox$()
VOID FRE(0)
PAUSE 20
'
RETURN
'
PROCEDURE about_mod_car
'
lx=94
rx=555
ty=14
by=175
'
DIM helpbox$(111)
helpbox$(1)="These patch parameter groups modify certain aspects"
helpbox$(2)="of the Modulator signal and the Carrier signal de-"
helpbox$(3)="pending on which item is selected. There are 5 "
helpbox$(4)="subgroups pertaining to each signal."
helpbox$(5)=""
helpbox$(6)="Define Waveform - Selecting this function will cause"
helpbox$(7)="a standard radio box to appear allowing you to select"
helpbox$(8)="the shape of the signal. There are 4 choices which"
helpbox$(9)="include Sine Wave, Half Sine Wave, Square Wave, and"
helpbox$(10)="Half Square Wave (Note: a Square Wave translates to"
helpbox$(11)="a Squared Sine Wave). Clicking on OK after choosing"
helpbox$(12)="a shape will return to the GEM menu."
helpbox$(13)="Tuning - use this to allow for editing all detuning"
helpbox$(14)="functions associated with each signal via the mouse"
helpbox$(15)="buttons."
helpbox$(16)=""
helpbox$(17)="Fine Detune - use this to finely increase or decrease"
helpbox$(18)="the signal's pitch. A positive number will make"
helpbox$(19)="the pitch sound sharper, a negative number will make"
helpbox$(20)="the pitch sound flatter. The allowable range is from"
helpbox$(21)="-7 to +7."
helpbox$(22)=""
helpbox$(23)="Course Detune - use this to cause the signal's pitch"
helpbox$(24)="to become way out of tune. It is either OFF or ON."
helpbox$(25)="Frequency Multiplier - use this to increase or"
helpbox$(26)="decrease the frequency of the signal. A value of"
helpbox$(27)="1 is equivalent to the standard pitch of the signal."
helpbox$(28)="Doubling the value will raise the pitch by 1 octave."
helpbox$(29)="Setting the value to 0 will lower the standard"
helpbox$(30)="pitch of the signal by 1 octave. The allowable"
helpbox$(31)="range is from 0 to 15."
helpbox$(32)=""
helpbox$(33)="LKS/RKS - use this to allow the editing of Level Key"
helpbox$(34)="Scaling and Rate Key Scaling functions associated"
helpbox$(35)="with each signal via the mouse buttons."
helpbox$(36)=""
helpbox$(37)="Level Key Scale Hi/Lo - use both of these functions"
helpbox$(38)="to increase or decrease the volume of each signal as"
helpbox$(39)="you go up or down the keyboard scale. The MIDI note"
helpbox$(40)="[C3] or middle C has no effect. LKS Lo effects all"
helpbox$(41)="notes below C3 and LKS Hi effects all notes above"
helpbox$(42)="C3. A value of 0 on both functions turns Level Key"
helpbox$(43)="Scaling off. The allowable range for both functions"
helpbox$(44)="is from 0 to 15. Low values on LKS Lo will moder-"
helpbox$(45)="ately decrease the volume as you approach C3. As you"
helpbox$(46)="increase the value, the volume will decrease less "
helpbox$(47)="and less until you reach 8. Now, high values on LKS"
helpbox$(48)="Lo will moderately increase the volume as you "
helpbox$(49)="approach C3 and as you decrease this value, the"
helpbox$(50)="volume will increase less and less until you reach 8."
helpbox$(51)=""
helpbox$(52)="LKS Hi works quite differently. Bear in mind that"
helpbox$(53)="since the frequency's signal is higher above C3, the"
helpbox$(54)="overall volume effect is less noticeable. Values"
helpbox$(55)="1 thru 3 will slightly increase the volume from C3"
helpbox$(56)="onward with 1 being the most noticeable."
helpbox$(57)="Values 4 thru 10 will slightly decrease the volume"
helpbox$(58)="from C3 onward in a linear fashion with 10 being"
helpbox$(59)="the most noticeable. Values 11 thru 15 will slightly"
helpbox$(60)="decrease the volume from C3 onward in more of an"
helpbox$(61)="exponential fashion with 15 being the most no-."
helpbox$(62)="ticeable."
helpbox$(63)=""
helpbox$(64)="The Level Key Scale function works best with the"
helpbox$(65)="Frequency Mulitplier set to very low values."
helpbox$(66)=""
helpbox$(67)="Rate Key Scale - use this to increase or decrease"
helpbox$(68)="the rate of the signal's attack and decay functions."
helpbox$(69)="As you move up the keyboard scale, this effect will"
helpbox$(70)="cause the attack and decay to become more rapid at"
helpbox$(71)="high values. The allowable range is from 0 to 3."
helpbox$(72)=""
helpbox$(73)="Enveloping - use this to allow for editing all"
helpbox$(74)="envelope functions to the signal via the mouse"
helpbox$(75)="buttons."
helpbox$(76)=""
helpbox$(77)="Attack Rate - use this to increase or decrease the"
helpbox$(78)="rate at which the signal will build up to its highest"
helpbox$(79)="peak level. The allowable range is from 0 - 63."
helpbox$(80)=""
helpbox$(81)="Decay 1 Rate - once the signal is at its highest peak"
helpbox$(82)="level, use this to increase or decrease the amount of"
helpbox$(83)="time it takes for the signal to fade off while con-"
helpbox$(84)="tinuously holding down the note on the keyboard "
helpbox$(85)="instrument. The allowable range is from 0 to 63."
helpbox$(86)=""
helpbox$(87)="Decay 1 Level - this defines the 1st volume level at"
helpbox$(88)="which the signal will drop from highest peak. The "
helpbox$(89)="allowable range is from 0 to 15."
helpbox$(90)=""
helpbox$(91)="Decay 2 Rate - once the signal has reached the decay"
helpbox$(92)="1 level, use this to control the time it takes for"
helpbox$(93)="the signal to finally fade off to silence while "
helpbox$(94)="holding down the note on the keyboard instrument."
helpbox$(95)="The allowable range is from 0 to 63."
helpbox$(96)=""
helpbox$(97)="Release Rate - use this to increase or decrease the"
helpbox$(98)="rate at which the sound fades off to silence when"
helpbox$(99)="releasing the note on the keyboard instrument. This"
helpbox$(100)="will only occur when both the Decay 1/Decay 2"
helpbox$(101)="rates are set at low values and when Sustain is"
helpbox$(102)="off (under AM/FM). The allowable range is from"
helpbox$(103)="0 to 15."
helpbox$(104)=""
helpbox$(105)="Sustain Release Rate - this replaces the Release"
helpbox$(106)="Rate when Sustain is turned on via AM/FM control."
helpbox$(107)="The allowable range is from 0 to 15."
helpbox$(109)="AM Enable - use this to toggle the Amplitude "
helpbox$(110)="Modulation for each signal and allow the 'warble'"
helpbox$(111)="to take effect in AM Sensitivity."
lineno=DIM?(helpbox$())
do_helpbox
ERASE helpbox$()
VOID FRE(0)
PAUSE 20
'
RETURN
'
PROCEDURE do_helpbox
'
HIDEM
CLR offset
SGET tempuse$ !Save screen
CLS
MENU m$() !show GEM Menus
DEFFILL 0,2,8
IF rez=1
DEFTEXT 1,0,0,6 !define screen font
ELSE
lx=lx-70 !redefine for monochrome display
rx=rx-70
ty=ty+50
by=by+161
offset=10
DEFTEXT 1,0,0,13
ENDIF
growbox(lx,ty,10,10,lx,ty,rx-lx,by-ty) !Make pop-up box
PBOX lx,ty,rx,by
DEFLINE 1,3
BOX lx,ty,rx,by
DEFLINE 1,1
BOX lx+8,ty+2,rx-8,by-2
IF rez=1
TEXT lx+12,by-5,"Left-{Page Down}|Right-{Page Up}|Both-Exit"
ELSE
TEXT lx+90,by+20,"Left-{Page Down}|Right-{Page Up}|Both-Exit"
ENDIF
'
pointer=1 ! initialize page pointer
pages=INT((lineno-1)/12) ! define 12 lines per page
overflow=(lineno-1) MOD 12 ! define overflow flag
IF overflow>0
pages=pages+1 ! increment page for over 12 lines
ENDIF
drawlines ! draw the page
DO
m=MOUSEK
KEYTEST key
IF m=2 OR ((key=4915200) OR (key=273350656)) !Left arrow or right mouse
IF pointer>1
DEC pointer !decrement pointer
drawlines !draw previous page
ENDIF
ELSE
pointer=pointer
ENDIF
IF m=1 OR ((key=5046272) OR (key=273481728)) !Right arrow or left mouse
IF pointer<pages
INC pointer !increment pointer
drawlines !draw next page
ELSE
pointer=pointer
ENDIF
ENDIF
EXIT IF m=3 OR (key=6356992 OR key=274792448) !UNDO or both
LOOP
SPUT tempuse$ !get previous screen
CLR tempuse$,offset
shrinkbox(lx,ty,20,5,lx,ty,rx-lx,by-ty) ! Undo pop-up box
DEFTEXT 1,0,0,10 !reinitialize screen font
'
RETURN
'
PROCEDURE drawlines
'
PBOX lx+10,ty+6,rx-11,by-15
startloop=(pointer*12)-12
FOR drawlines=1 TO 12
EXIT IF drawlines+startloop>lineno-1
TEXT lx+26,(ty+11)+10*drawlines+(offset*drawlines),helpbox$(startloop+drawlines)
NEXT drawlines
IF pointer>9 THEN
IF rez=1
TEXT 30,30," "
TEXT 30,30,"Page "+STR$(pointer)
ELSE
TEXT 30,35," "
TEXT 30,35,"Page "+STR$(pointer)
ENDIF
ELSE
IF pointer<10 THEN
IF rez=1
TEXT 30,30," "
TEXT 30,30,"Page "+STR$(pointer)
ELSE
TEXT 30,35," "
TEXT 30,35,"Page "+STR$(pointer)
ENDIF
ELSE
TEXT 30,30,"Page "+STR$(pointer)
ENDIF
ENDIF
IF rez=1
TEXT 40,40,"of "+STR$(pages)
ELSE
TEXT 40,55,"of "+STR$(pages)
ENDIF
RETURN
' These are the GEM™ GRAF_GROWBOX & GRAF_SHRINKBOX Routines
' Init stands for Initial(X,Y,Height) and Fin stands for Final(X,Y,Height)
'
PROCEDURE growbox(init_x%,init_y%,init_w%,init_h%,fin_x%,fin_y%,fin_w%,fin_h%)
'
DPOKE GINTIN,init_x%
DPOKE GINTIN+2,init_y%
DPOKE GINTIN+4,init_w%
DPOKE GINTIN+6,init_h%
DPOKE GINTIN+8,fin_x%
DPOKE GINTIN+10,fin_y%
DPOKE GINTIN+12,fin_w%
DPOKE GINTIN+14,fin_h%
GEMSYS 73
'
RETURN
'
PROCEDURE shrinkbox(fin_x%,fin_y%,fin_w%,fin_h%,init_x%,init_y%,init_w%,init_h%)
'
DPOKE GINTIN,fin_x%
DPOKE GINTIN+2,fin_y%
DPOKE GINTIN+4,fin_w%
DPOKE GINTIN+6,fin_h%
DPOKE GINTIN+8,init_x%
DPOKE GINTIN+10,init_y%
DPOKE GINTIN+12,init_w%
DPOKE GINTIN+14,init_h%
GEMSYS 74
'
RETURN
'
PROCEDURE create_box(prompt$,value$,x0,y0,x1,y1)
'
TEXT 1,((y0+y1)/2)+3,prompt$
TEXT x0+20,y0+20,value$
BOX x0,y0,x1,y1
'
RETURN
'
PROCEDURE redraw_box(value$,x0,y0,x1,y1)
'
DEFFILL 0,2,8
PBOX x0+1,y0+1,x1-1,y1-1
SHOWM
TEXT x0+20,y0+20,value$
'
RETURN