This program lets you hear the various voices provided by the MIDI synthesiser on your PC; the fidelity of the sounds will vary according to the type of sound card installed. The program was adapted from a version written in Liberty BASIC and deliberately has the same look-and-feel as the original.
Download MIDITEST.BBC | Run MIDITEST.EXE |
---|
REM. MIDI voice tester in BBC BASIC for Windows, RTR 25-Oct-2004
INSTALL @lib$+"WINLIB2"
INSTALL @lib$+"WINLIB5"
INSTALL @lib$+"FNUSING"
MODE 20 : REM WindowWidth = 800 : WindowHeight = 600
COLOUR 0,100,100,1
CLS
SYS "SetWindowText", @hwnd%, "Instruments and Sounds"
hb1% = FN_button("Fast Range", 160, 460, 100, 32, 101, 0)
hb2% = FN_button("Slow Range", 280, 460, 100, 32, 102, 0)
hb3% = FN_button("Single Note", 400, 460, 110, 32, 103, 0)
hb4% = FN_button("Music Scale", 530, 460, 110, 32, 104, 0)
hb5% = FN_button(" Do Re Mi ", 160, 520, 100, 32, 105, 0)
hb6% = FN_button(" Mi Re Do ", 280, 520, 100, 32, 106, 0)
hb7% = FN_button("Voice List ", 400, 520, 110, 32, 107, 0)
hb8% = FN_button("*** QUIT **", 530, 520, 110, 32, 108, 0)
SelectBox% = FN_newdialog("Select",110,180,310,47,8,400)
PROC_pushbutton(SelectBox%,"Quit",2,246,9,32,19,0)
PROC_static(SelectBox%,"Select Voice",100,10,3,64,12,0)
PROC_combobox(SelectBox%,"",109,10,16,147,350,3)
PROC_static(SelectBox%,"Select an Instrument or Sound. If necessary turn up your speakers.",102,50,37,240,12,0)
NoteBox% = FN_newdialog("Single note",50,50,128,56,8,300)
PROC_pushbutton(NoteBox%,"Play",201,48,37,30,16,1)
PROC_editbox(NoteBox%,"",202,22,19,20,15,&80)
PROC_editbox(NoteBox%,"",203,85,19,20,15,&80)
PROC_static(NoteBox%,"Duration 1-10000",204,5,6,64,12,0)
PROC_static(NoteBox%,"Pitch 1-127",205,76,6,64,12,0)
ON CLOSE PROCcleanup : QUIT
ON ERROR SYS "MessageBox", @hwnd%, REPORT$, 0, 0 : PROCcleanup : QUIT
COLOUR 15
*font arial,24,b
PRINT TAB(7,2)"Instrumental Voices and Sound Effects"
*font arial,10
PRINT TAB(30,8)"adapted by Richard Russell ver. 1.0 July 2004 using BBC BASIC for Windows"
*font arial,18,b
PRINT TAB(20,6)"Select a voice then the effects"
COLOUR 11
REM read instrument names into array
DIM ins$(128), voice(128), tone(20)
PROCrestoreinfo
FOR vc = 1 TO 128
READ ins$(vc)
NEXT vc
PROCrestorenotes
FOR n = 1 TO 15
READ tone(n)
NEXT n
PROC_showdialog(SelectBox%)
REM populate combobox
FOR vc = 1 TO 128
SYS "SendDlgItemMessage", !SelectBox%, 109, &143, 0, ins$(vc)
NEXT vc
REM initial selection
SYS "SendDlgItemMessage", !SelectBox%, 109, &14E, 0, 0
PROCsblast
voice% = 0 : REM first data
voice$ = ins$(voice%+1)
PRINT TAB(24-LEN(voice$)/2,8) "Current Voice No. ";voice%+1;" ";voice$
Click% = 0
ON SYS Click% = @wparam% AND &FFFF : RETURN
REPEAT
temp% = INKEY(2)
SWAP Click%, temp%
CASE temp% OF
WHEN 101: PROCrange(20, voice%)
WHEN 102: PROCrange(100, voice%)
WHEN 103: PROC_showdialog(NoteBox%)
WHEN 104: PROCsels(1, 15, 1, voice%, 300)
WHEN 105: PROCsels(8, 10, 1, voice%, 600)
WHEN 106: PROCsels(10, 8, -1, voice%, 600)
WHEN 107: PROClist
WHEN 108: PROCcleanup : QUIT
WHEN 109:
SYS "SendDlgItemMessage", !SelectBox%, 109, &147, 0, 0 TO voice%
voice$ = ins$(voice%+1)
PRINT TAB(5,8) SPC(100)
PRINT TAB(24-LEN(voice$)/2,8) "Current Voice No. ";voice%+1;" ";voice$
WHEN 201:
SYS "GetDlgItemInt", !NoteBox%, 202, 0, 0 TO duration%
SYS "GetDlgItemInt", !NoteBox%, 203, 0, 0 TO pitch%
IF duration%<1 OR duration%>10000 OR pitch%<1 OR pitch%>127 THEN
SYS "MessageBox", @hwnd%, "Invalid entry!", "- Notice -", 48
ELSE
PROCnewNote(pitch%, voice%, duration%)
ENDIF
ENDCASE
UNTIL !SelectBox% = 0
PROCcleanup
QUIT
DEF PROCrange(len%, voice%)
LOCAL note%
FOR note% = 50 TO 100
PROCnewNote(note%, voice%, len%)
NEXT note%
ENDPROC
DEF PROCsels(start%, last%, stp%, voice%, sndlen%)
LOCAL n%, note%
FOR n% = start% TO last% STEP stp%
note% = tone(n%)
PROCnewNote(note%, voice%, sndlen%)
NEXT
ENDPROC
DEF PROCsblast : LOCAL ret%
REM open midi device and obtain handle
REM midi functions return 0 if successful
SYS "midiOutOpen", ^hMidiOut%, -1, 0, 0, 0 TO ret%
IF ret% ERROR 100, "Failed to open MIDI output device"
ENDPROC
DEF PROCnewNote(note%, voice%, len%)
PROCdoChange(voice%)
PROCplayNewNote(note%) : REM play new note
SYS "Sleep", len%
PROCstopPlay(note%) : REM stop note
ENDPROC
DEF PROCplayNewNote(note%): REM play new note
LOCAL event%, low%, velocity%, hi%, dwMsg%
event%=144 : REM event 144 = play on channel 1
low%=(note%*256)+event%
velocity%=127
hi%=velocity%<<16
dwMsg%=low%+hi%
SYS "midiOutShortMsg", hMidiOut%, dwMsg%
ENDPROC
DEF PROCstopPlay(note%) : REM stop note from playing
LOCAL event%, dwMsg%
event%=128 : REM event 128 = stop play
dwMsg%=(note%*256)+event%
SYS "midiOutShortMsg",hMidiOut%, dwMsg%
ENDPROC
DEF PROCdoChange(voice%) : REM signal a voice change
LOCAL event%, velocity%, low%, hi%, dwMsg%
event%=192 : REM event 192 = change
velocity%=127
low%=(voice%*256)+event%
hi%=velocity%<<16
dwMsg%=low%+hi%
SYS "midiOutShortMsg",hMidiOut%, dwMsg%
ENDPROC
DEF PROCcleanup : REM remove buttons, dialogues, close midi device
hb1% += 0 : IF hb1% PROC_closewindow(hb1%)
hb2% += 0 : IF hb2% PROC_closewindow(hb2%)
hb3% += 0 : IF hb3% PROC_closewindow(hb3%)
hb4% += 0 : IF hb4% PROC_closewindow(hb4%)
hb5% += 0 : IF hb5% PROC_closewindow(hb5%)
hb6% += 0 : IF hb6% PROC_closewindow(hb6%)
hb7% += 0 : IF hb7% PROC_closewindow(hb7%)
hb8% += 0 : IF hb8% PROC_closewindow(hb8%)
SelectBox% += 0 : IF SelectBox% PROC_closedialog(SelectBox%)
NoteBox% += 0 : IF NoteBox% PROC_closedialog(NoteBox%)
hMidiOut% += 0 : IF hMidiOut% SYS "midiOutClose", hMidiOut%
ENDPROC
DEF PROClist
LOCAL file%, row%, col%, n%, line$
file% = OPENOUT"Voice list."
FOR row% = 0 TO 31
line$ = ""
FOR col% = 0 TO 3
n% = col%*32+row%+1
line$ += FNusing("###",n%)+" "+LEFT$(ins$(n%)+STRING$(21," "),21)
NEXT col%
PRINT #file%,line$
BPUT #file%,10
NEXT row%
PRINT #file%,""
BPUT#file%,10
PRINT#file%, "Note some programs allocate a number 1 less."
BPUT#file%,10
CLOSE #file%
*NOTEPAD "Voice list."
*DEL "Voice list."
ENDPROC
REM list of 128 voices, in order of their MIDI indexes
DEF PROCrestoreinfo
RESTORE +1
DATA "Grand Piano","Bright Grand","Electric Grand","Honky Tonk"
DATA "Rhodes","Chorus Piano","Harpsichord","Clavichord"
DATA "Celesta","Glockenspiel","Music Box","Vibraphone"
DATA "Marimba","Xylophone","Tubular Bells","Dulcimer"
DATA "Hammond Organ","Percussion Organ","Rock Organ"
DATA "Church Organ","Reed Organ","Accordian","Harmonica"
DATA "Tango Accordian","Acoustic Nylon Guitar"
DATA "Acoustic Steel Guitar","Electric Jazz Guitar"
DATA "Electric Clean Guitar","Electric Mute Guitar"
DATA "Overdrive Guitar","Distorted Guitar","Guitar Harmonic"
DATA "Acoustic Bass","Electric Bass Finger","Electric Bass Pick"
DATA "Fretless Bass","Slap Bass One","Slap Bass Two"
DATA "Synth Bass One","Synth Bass Two","Violin","Viola","Cello"
DATA "Contrabass","Tremolo Strings","Pizzicato Strings"
DATA "Orchestra Harp","Timpani","String Ensemble One"
DATA "String Ensemble Two","Synth Strings One","Synth Strings Two"
DATA "Choir Ahhs","Voice Oohs","Synth Voice","Orchestra Hit"
DATA "Trumpet","Trombone","Tuba","Mute Trumpet","French Horn"
DATA "Brass Section","Synth Brass One","Synth Brass Two"
DATA "Soprano Sax","Alto Sax","Tenor Sax","Baritone Sax","Oboe"
DATA "English Horn","Bassoon","Clarinet","Piccolo","Flute"
DATA "Recorder","Pan Flute","Bottle Blow","Shakuhachi","Whistle"
DATA "Ocarina","Square Wave","Sawtooth","Calliope","Chiff Lead"
DATA "Charang","Solo Synth VX","Brite Saw","Brass and Lead"
DATA "Fantasia Pad","Warm Pad","Poly Synth Pad","Space Vox Pad"
DATA "Bowed Glass Pad","Metal Pad","Halo Pad","Sweep Pad"
DATA "Ice Rain","Sound Track","Crystal","Atmosphere","Brightness"
DATA "Goblin","Echo Drops","Star Theme","Sitar","Banjo","Shamisen"
DATA "Koto","Kalimba","Bagpipe","Fiddle","Shanai"
DATA "Tinkle Bell","Agogo","Steel Drums","Wood Block","Taiko Drum"
DATA "Melodic Tom","Synth Drum","Rev Cymbal"
DATA "Guitar Fret Noise","Breath Noise","Sea Shore","Bird Tweet"
DATA "Phone Ring","Helicopter","Applause","Gunshot"
ENDPROC
DEF PROCrestorenotes
RESTORE +1
DATA 48,50,52,53,55,57,59,60,62,64,65,67,69,71,72
ENDPROC
REM C D E F G A B C D E F G A B C