Code: Select all
EnableExplicit
;-Enumerations
Enumeration Windows
#MainWindow
#DeviceWindow
EndEnumeration
Enumeration Gadgets
#tg1
#tg2
#tg3
#tg4
#tg5
#sg1
#sg2
#sg3
#lg1
EndEnumeration
Enumeration Shortcuts
#ReturnShotcut
#F1Shortcut
EndEnumeration
Enumeration Timers
#Timer1
#Timer2
EndEnumeration
;-Procedures
Procedure PitchBend(hmo.i, channel.i, n.i)
midiOutShortMsg_(hmo, Val("$00" + RSet(Hex(n & $7F), 2, "0") + RSet(Hex(n >> 7), 2, "0") + "E" + Hex(channel))) ; E = 1110 PITCH BEND
EndProcedure
Procedure ProgramChange(hmo.i, channel.i, n.i)
midiOutShortMsg_(hmo, Val("$0000" + RSet(Hex(n), 2, "0") + "C" + Hex(channel))) ; C = 1100 PROGRAMM CHANGE
EndProcedure
Procedure controlchange(hmo.i, channel.i, n.i, v.i)
midiOutShortMsg_(hmo, Val("$00" + RSet(Hex(v), 2, "0") + RSet(Hex(n), 2, "0") + "B" + Hex(channel))) ; B = 1011 CONTROLLER
EndProcedure
Procedure playnote(hmo.i, channel.i, n.i, v.i)
midiOutShortMsg_(hmo, Val("$00" + RSet(Hex(v), 2, "0") + RSet(Hex(n), 2, "0") + "9" + Hex(channel))) ; 9 = 1001 NOTE ON
EndProcedure
Procedure stopnote(hmo.i, channel.i, n.i)
midiOutShortMsg_(hmo, Val("$0000" + RSet(Hex(n), 2, "0") + "8" + Hex(channel))) ; 8 = 1000 NOTE OFF
EndProcedure
Procedure SysEXVolume(hmo.i, Volume.i)
Protected *SysExBuffer
Protected MIDIHeader.MIDIHDR
If Volume > $3FFF
Volume = $3FFF
EndIf
*SysExBuffer = AllocateMemory(8)
If *SysExBuffer
PokeA(*SysExBuffer + 0, $F0) ; SysEx
PokeA(*SysExBuffer + 1, $7F) ; Realtime
PokeA(*SysExBuffer + 2, $7F) ; Channel (disregard)
PokeA(*SysExBuffer + 3, $04) ; SubID (Device Control)
PokeA(*SysExBuffer + 4, $01) ; SubID2 (Master Volume)
PokeA(*SysExBuffer + 5, Volume & $7F) ; Volume lower 7 bits
PokeA(*SysExBuffer + 6, Volume >> 7) ; Volume upper 7 bits
PokeA(*SysExBuffer + 7, $F7) ; SysEx End
;ShowMemoryViewer(*SysExBuffer, MemorySize(*SysExBuffer))
MIDIHeader\lpData = *SysExBuffer
MIDIHeader\dwBufferLength = MemorySize(*SysExBuffer)
MIDIHeader\dwFlags = 0
midiOutPrepareHeader_(hmo, @MIDIHeader, SizeOf(MIDIHDR))
;CopyMemory(*SysExBuffer, MIDIHeader\lpData, MemorySize(*SysExBuffer))
midiOutLongMsg_(hmo, @MIDIheader, SizeOf(MIDIHDR))
FreeMemory(*SysExBuffer)
EndIf
EndProcedure
Procedure stop(hmo.i, channel.i)
Protected r.i
For r = 50 To 73
stopnote(hmo, channel, r)
Next
RemoveWindowTimer(#MainWindow, #Timer1)
EndProcedure
Procedure play(hmo.i, channel.i)
Protected.i r
controlchange(hmo, channel, 10, GetGadgetState(#sg2)) ; 10 = pan
programchange(hmo, channel, Val(GetGadgetText(#sg1)))
stop(hmo, channel)
AddWindowTimer(#MainWindow, #Timer1, 2000)
If GetGadgetState(#tg5) = 1
AddWindowTimer(#MainWindow, #Timer2, 5)
EndIf
pitchbend(hmo, channel, $2000)
For r = 50 To 71 Step 3
playnote(hmo, channel, r, 70)
Delay(30)
Next
EndProcedure
Procedure dispositivo(hmo.i)
Protected.i iNumDev, around, w, k, Result
Protected aa$
Protected moc.MIDIOUTCAPS
midiOutClose_(hmo)
OpenWindow(#DeviceWindow, 0, 0, 300, 400, "Select a Midi Port")
iNumDev = midiOutGetNumDevs_()
TextGadget(#tg1, 10, 10, 280, 20, Str(iNumDev) + " MIDI out devices.")
ListViewGadget(#lg1, 10, 40, 280, 330)
For around = 0 To iNumDev - 1
midiOutGetDevCaps_(around, moc, SizeOf(MIDIOUTCAPS))
AddGadgetItem(#lg1, around, Str(around) + " " + PeekS(@moc\szPname[0], #MAXPNAMELEN))
Next
SetActiveGadget(#lg1)
SetGadgetState(#lg1, 0)
AddKeyboardShortcut(#DeviceWindow, #PB_Shortcut_Return, #ReturnShotcut)
EndProcedure
;-Main
Define.i Result, Event, DeviceId, hmo, channel, p
OpenWindow(#MainWindow, 0, 0, 300, 300, "Playing a simple frase")
TextGadget(#tg2, 10, 10, 150, 20, "Instrument number:")
SpinGadget(#sg1, 200, 10, 40, 20, 0, 127, #PB_Spin_Numeric)
SetActiveGadget(#sg1)
SetGadgetText(#sg1, "4")
SetActiveGadget(#sg1)
TextGadget(#tg3, 10, 50, 150, 20, "Balance:")
TrackBarGadget(#sg2, 120, 50, 150, 20, 0, 128)
SetGadgetState(#sg2, 64)
TextGadget(#tg4, 10, 100, 100, 20, "SysexVolume:")
SpinGadget(#sg3, 120, 100, 150, 20, 0, 16383, #PB_Spin_Numeric)
SetGadgetText(#sg3, "16383")
CheckBoxGadget(#tg5, 10, 150, 100, 20, "Pitch Bend:")
AddKeyboardShortcut(#MainWindow, #PB_Shortcut_Return, #ReturnShotcut)
AddKeyboardShortcut(#MainWindow, #PB_Shortcut_F1, #F1Shortcut)
PostEvent(#PB_Event_Menu, #MainWindow, #F1Shortcut)
;-EventLoop
Repeat
Event = WaitWindowEvent()
Select EventWindow()
;-MainWindowEvents
Case #MainWindow
Select Event
Case #PB_Event_CloseWindow
Break
Case #PB_Event_Gadget
Select EventGadget()
Case #sg1
SetGadgetText(#sg1, Str(GetGadgetState(#sg1)))
Case #sg2
SetGadgetText(#sg2, Str(GetGadgetState(#sg2)))
EndSelect
Case #PB_Event_Timer
Select EventTimer()
Case #Timer1
stop(hmo, channel)
RemoveWindowTimer(#MainWindow, #Timer2)
Case #Timer2
p = p + 1
PitchBend(hmo, channel, $2000 + p)
If p = $1FFF Or p = -$1FFF
RemoveWindowTimer(#MainWindow, #Timer2)
EndIf
EndSelect
Case #PB_Event_Menu
Select EventMenu()
Case #ReturnShotcut
If GetGadgetText(#sg3) <> ""
SysEXVolume(hmo, Val(GetGadgetText(#sg3)))
EndIf
play(hmo, channel)
p = 0
Case #F1Shortcut
DisableWindow(#MainWindow, #True)
dispositivo(hmo)
EndSelect
EndSelect
;-DeviceWindowEvents
Case #DeviceWindow
Select Event
Case #PB_Event_CloseWindow
CloseWindow(#DeviceWindow)
DisableWindow(#MainWindow, #False)
SetActiveWindow(#MainWindow)
Case #PB_Event_Menu
DeviceId = GetGadgetState(#lg1)
If EventMenu() = #ReturnShotcut And DeviceId > -1
result = midiOutOpen_(@hmo, DeviceId, #Null, #Null, #CALLBACK_NULL)
;two old lines removed from here
PostEvent(#PB_Event_CloseWindow, #DeviceWindow, 0)
EndIf
EndSelect
EndSelect
ForEver