KORG X5D via MIDI (was: Where to hire a programmer)
-
- User
- Posts: 40
- Joined: Wed Oct 06, 2010 9:37 pm
KORG X5D via MIDI (was: Where to hire a programmer)
Hi! I have a non working snippet that I really would like to get in order. Which subforum is a good place to ask for a programmer to debug for money?
Newbie
Re: KORG X5D via MIDI (was: Where to hire a programmer)
I guess this can be the right subforum, assuming it's a PB program.SiggeSvahn wrote: Tue Jan 02, 2024 3:11 pm Hi! I have a non working snippet that I really would like to get in order. Which subforum is a good place to ask for a programmer to debug for money?
But why not just post the snippet and see if people can help you fix it? Or would you rather not circulate the code publicly?
-
- User
- Posts: 40
- Joined: Wed Oct 06, 2010 9:37 pm
Re: KORG X5D via MIDI (was: Where to hire a programmer)
Well, here is the snippet. I use PC Win11 and syntheziser KORG X5D. The portion that should receive a MIDI Bulf Dump does not work. I would pay 200$ to the first person who presents a version that works on my computer.
Code: Select all
;Incoming SYSEX Tryout.
#WinMIDIrequester=1
Enumeration GADGETS
#txtOutputDevices=1
#txtInputDevices
#lgtOutputDevices
#lgtInputDevices
#btnOK
#btnCancel
#frgFrame
#txtVersion
#txttech
#txtMaxVoice
#txtPoly
EndEnumeration
Structure MIDI
MIDIIn.A
MIDIOut.A
Stat.A
Dat1.A
Dat2.A
EndStructure
Global MidiHeader.MIDIHDR
Global hMiP0.l = 0
Global *SysexBuffer = AllocateMemory(4096)
Global _MIDI.MIDI
Global Dim arrSysexMessage.a(9)
Procedure MIDIRequester(*OutDevice, *InDevice)
Define MaxOutDev, MaxInDev, InfoOut.MIDIOUTCAPS,InfoIn.MIDIINCAPS, a, OutDev, InDev, Quit, OK, TmpS.s, EventID
#MOD_WAVETABLE = 6
#MOD_SWSYNTH = 7
#MIDIRequ_InSet = 2
#MIDIRequ_OutSet = 1
#Width = 400
If OpenWindow(#WinMIDIrequester, 0, 0, #Width, 270, "MIDI-Requester Sel MIDI-modem etc slot that you want to use.", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
#Column = (#Width - 20) / 2
#Offset = (#Width / 2) + 5
TextGadget(#txtOutputDevices, 5, 5, #Column, 18, "Output-Device:", #PB_Text_Center | #PB_Text_Border)
ListViewGadget(#lgtOutputDevices, 5, 23, #Column, 100)
MaxOutDev = midiOutGetNumDevs_()
InfoOut.MIDIOUTCAPS
If MaxOutDev
For a = -1 To MaxOutDev - 1
midiOutGetDevCaps_(a, InfoOut, SizeOf(MIDIOUTCAPS))
AddGadgetItem(#lgtOutputDevices, -1, PeekS(@InfoOut\szPname[0], 32))
Next
Else
AddGadgetItem(#lgtOutputDevices, -1, "(no output device)")
DisableGadget(#lgtInputDevices, 1)
EndIf
; MessageRequester("","1")
TextGadget(#txtInputDevices, #Offset, 5, #Column, 18, "Input-Device:", #PB_Text_Center | #PB_Text_Border)
ListViewGadget(#lgtInputDevices, #Offset, 23, #Column, 100)
MaxInDev = midiInGetNumDevs_()
InfoIn.MIDIINCAPS
If MaxInDev
For a = 0 To MaxInDev - 1
midiInGetDevCaps_(a, InfoIn, SizeOf(MIDIINCAPS))
AddGadgetItem(#lgtInputDevices, -1, PeekS(@InfoIn\szPname[0], 32))
Next
Else
AddGadgetItem(#lgtInputDevices, -1, "(no input device)")
DisableGadget(#lgtInputDevices, 1)
EndIf
; MessageRequester("","2")
ButtonGadget(#btnOK, 5, 240, #Column, 24, "&OK")
ButtonGadget(#btnCancel, #Offset, 240, #Column, 24, "&Cancel")
FrameGadget(#frgFrame, 5, 130, #Width - 10, 100, "Info of Output-Device", 0)
TextGadget(#txtVersion, 10, 145, #Width - 20, 18, "Version:")
TextGadget(#txtTech, 10, 165, #Width - 20, 18, "Technology:")
TextGadget(#txtMaxVoice, 10, 185, #Width - 20, 18, "Max. Voices:")
TextGadget(#txtPoly, 10, 205, #Width - 20, 18, "Polyphonie:")
OutDev = 0
InDev = 0
Quit = #False
OK = #False
; MessageRequester("","TEST")
; ======================================================================
Repeat
If GetGadgetState(#lgtOutputDevices) > -1 Or GetGadgetState(#lgtInputDevices) > -1
DisableGadget(#btnOK, 0)
Else
DisableGadget(#btnOK, 1)
EndIf
If InDev <> GetGadgetState(#lgtInputDevices)
InDev = GetGadgetState(#lgtInputDevices)
EndIf
If GetGadgetState(#lgtOutputDevices) <> OutDev
OutDev = GetGadgetState(#lgtOutputDevices)
midiOutGetDevCaps_(OutDev - 1, InfoOut, SizeOf(MIDIOUTCAPS))
SetGadgetText(#txtVersion, "Version: " + Str(InfoOut\vDriverVersion >> 8) + "." + Str(InfoOut\vDriverVersion & $FF))
Select InfoOut\wTechnology
Case #MOD_MIDIPORT : TmpS.s = "Hardware Port"
Case #MOD_SYNTH : TmpS.s = "Synthesizer"
Case #MOD_SQSYNTH : TmpS.s = "Square Wave Synthesizer"
Case #MOD_FMSYNTH : TmpS.s = "FM Synthesizer"
Case #MOD_MAPPER : TmpS.s = "Microsoft MIDI Mapper"
Case #MOD_WAVETABLE : TmpS.s = "Hardware Wavetable Synthesizer"
Case #MOD_SWSYNTH : TmpS.s = "Software Synthesizer"
Default: TmpS.s = "(Error Code " + Str(InfoOut\wTechnology) + ")"
EndSelect
SetGadgetText(#txtTech, "Technology: " + TmpS)
If InfoOut\wVoices = 0 : TmpS.s = "inf" : Else : TmpS.s = Str(InfoOut\wVoices) : EndIf
SetGadgetText(#txtMaxVoice, "Max. Voices: " + TmpS)
If InfoOut\wNotes = 0 : TmpS.s = "inf" : Else : TmpS.s = Str(InfoOut\wNotes) : EndIf
SetGadgetText(#txtPoly, "Polyphonie: " + TmpS)
EndIf
EventID = WaitWindowEvent()
Select EventID
Case #PB_Event_CloseWindow
Quit = #True
OK = #False
Case #PB_Event_Gadget
Select EventGadget()
Case #btnOK
PokeL(*OutDevice, OutDev - 1) ; Trick to return two results (OutDev & InDev)
PokeL(*InDevice, InDev)
Quit = #True
OK = 3
If (OutDev = -1 Or CountGadgetItems(#lgtOutputDevices) = 0) And OK & #MIDIRequ_OutSet
OK ! #MIDIRequ_OutSet : EndIf
If (InDev = -1 Or CountGadgetItems(#lgtInputDevices) = 0) And OK & #MIDIRequ_InSet
OK ! #MIDIRequ_InSet : EndIf
Case #btnCancel
Quit = #True
OK = #False
EndSelect
EndSelect
Until Quit
;==================================================================================
; CloseWindow(#WinMIDIrequester)
ProcedureReturn OK
Else
End
EndIf
EndProcedure
Procedure MIDIInProc(hMIDIIn, WMsg, DuMMy, D1, D2) ;ONLY CALLED ON STARTUP BY ME BUT THE SYNTH CALLS IT ALL THE TIME! It is the callback function for handling incoming MIDI messages.
Define i
If FetchFlag
Debug Hex(D2);Str(D1)
EndIf
With _MIDI
Select WMsg ; process some MIDI in events.
Case #MM_MIM_DATA;The MIM_DATA message is sent to a MIDI input callback function when a MIDI message is received by a MIDI input device.
If D1 & $FF =144
\Stat=(D1 >> 8) & $FF ;Note pitch value.
\Dat1=(D1 >> 16) & $FF ;Velocity value.
If \Dat1
SetWindowTitle(0,"Note On")
Debug "MIDIInProc NOTE ON " + Str(D1) + "; " + Str(\Stat) + "; Velocity: " + Str(\Dat1)
Else
SetWindowTitle(0,"Note Off")
EndIf
ElseIf D1 & $FF = $F0 ; Trying to recieve a SYSEX dump from my synth. The app MIDI-OX can recieve my dumps so my system is working.
Debug "Start of SYSEX!"
If (D1 >> 8) & $FF = $42
Debug "KORG-ID"
EndIf
EndIf
Case #MIM_LONGDATA ; Trying to recieve a SYSEX dump from my synth. The app MIDI-OX can recieve my dumps so my system is working.
Debug "---------- NEW INCOMING SYSEX -----------"
For i = 0 To MidiHeader\dwBytesRecorded - 1 ; Read Buffer Sent from LPData
Debug Hex(arrSysexMessage(i))
Next
; MHI\lpData = @arrSysexMessage() ; MIDI Header pointer to MIDI data.
midiInAddBuffer_(_hMIDIIn, @MidiHeader, SizeOf(MidiHeader)) ; Recycle Sysex Buffer
EndSelect
EndWith
EndProcedure
Procedure MIDIinit(OutDev, InDev, *MIDIInProc=-1,Instrument=0) ;ONLY CALLED ON STARTUP! MIDIinproc default solo show Note on, Note off
Define iMidiInterface.i, i.l,sText.s
If *MIDIinproc=-1:*MIDIinproc=@MIDIinproc():EndIf
; The MidiInProc function is the callback function for handling incoming MIDI messages. MidiInProc is a placeholder for the application-supplied function name.
; The address of this function can be specified in the callback-address parameter of the midiInOpen function.
If midiInOpen_(@_hMIDIIn, InDev, *MIDIInProc, 0, #CALLBACK_FUNCTION) = #MMSYSERR_NOERROR
If midiInStart_(_hMIDIIn) <> #MMSYSERR_NOERROR : MessageRequester("Error","Can't start MIDI IN",0) :End: EndIf
EndIf
; The midiInStart function starts MIDI input on the specified MIDI input device. hMidiIn is the handle to the MIDI input device. This function resets the time stamp to zero;
; time stamp values For subsequently received messages are relative to the time that this function was called. Calling this function when input is already started has no effect,
; and the function returns zero.
midiOutOpen_(@_hMIDIout, OutDev, 0, 0, 0);Öppnar midi-interface. LPHMIDIOUT=lphmo=pointer to an HMIDIOUT handle.
; This location is filled with a handle identifying the opened MIDI output device.
; The handle is used To identify the device in calls To other MIDI output functions. OutDev=uDeviceID=Identifier of the MIDI output device that is to be opened.
; 3rd placeholder = dwCallback and 0 means no callback is desired. 4th placeholder is dwCallbackInstance. Last placeholder is dwFlags=callbackflag.
midiOutShortMsg_(_hMIDIout, 192 | Instrument<<8 ) ; Sends a short MIDI message (here a Patch Change) to the specified MIDI output device. HMIDIOUT=hmo=Handle to the MIDI output device.
; This parameter can also be the handle of a MIDI stream cast To HMIDIOUT.
; The 2nd placeholder is dwMsg=similar to #MM_MIM_DATA above.
If _hMIDIIn And _hMIDIout
If midiConnect_(_hMIDIIn, _hMIDIout, 0);The midiConnect function connects a MIDI input device to a MIDI thru or output device,
; or connects a MIDI thru device To a MIDI output device.
; First inpDeviceHandle, then outpDevHandle, 3rd placeholder must be zero.
MessageRequester("Error","Can't connect MIDI",0) :End
EndIf
EndIf
EndProcedure
MIDIResult = MIDIRequester(@OutDevice, @InDevice)
If MIDIResult & #MIDIRequ_OutSet : Debug "Output device: " + Str(OutDevice) : EndIf
If MIDIResult & #MIDIRequ_InSet : Debug "Input device: " + Str(InDevice) : EndIf
MIDIinit(OutDevice,InDevice);*** Is called only once! ****
OpenWindow(0, 10, 10, 300, 200, "MIDI Test")
Repeat
Event = WaitWindowEvent()
Until Event = #PB_Event_CloseWindow
Newbie
Re: KORG X5D via MIDI (was: Where to hire a programmer)
Nice challenge! I unfortunately don't have a MIDI device to test.SiggeSvahn wrote: Tue Jan 02, 2024 4:30 pm Well, here is the snippet. I use PC Win11 and syntheziser KORG X5D. The portion that should receive a MIDI Bulf Dump does not work. I would pay 200$ to the first person who presents a version that works on my computer.
But what exactly happens with the current code? Does it crash, or do you get an error message?
Last edited by firace on Tue Jan 02, 2024 5:51 pm, edited 1 time in total.
Re: KORG X5D via MIDI (was: Where to hire a programmer)
Some shots in the dark... Could you try the below code?
I've fixed a few things like initializing the MIDI header, and the Sysex buffer.
I've fixed a few things like initializing the MIDI header, and the Sysex buffer.
Code: Select all
;;; firace debugging v0.3
;Incoming SYSEX Tryout.
#WinMIDIrequester=1
Enumeration GADGETS
#txtOutputDevices=1
#txtInputDevices
#lgtOutputDevices
#lgtInputDevices
#btnOK
#btnCancel
#frgFrame
#txtVersion
#txttech
#txtMaxVoice
#txtPoly
EndEnumeration
Structure MIDI
MIDIIn.A
MIDIOut.A
Stat.A
Dat1.A
Dat2.A
EndStructure
Global MidiHeader.MIDIHDR
Global hMiP0.l = 0
Global *SysexBuffer = AllocateMemory(4096)
Global _MIDI.MIDI
Global Dim arrSysexMessage.a(9)
Procedure MIDIRequester(*OutDevice, *InDevice)
Define MaxOutDev, MaxInDev, InfoOut.MIDIOUTCAPS,InfoIn.MIDIINCAPS, a, OutDev, InDev, Quit, OK, TmpS.s, EventID
#MOD_WAVETABLE = 6
#MOD_SWSYNTH = 7
#MIDIRequ_InSet = 2
#MIDIRequ_OutSet = 1
#Width = 400
If OpenWindow(#WinMIDIrequester, 0, 0, #Width, 270, "MIDI-Requester Sel MIDI-modem etc slot that you want to use.", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
#Column = (#Width - 20) / 2
#Offset = (#Width / 2) + 5
TextGadget(#txtOutputDevices, 5, 5, #Column, 18, "Output-Device:", #PB_Text_Center | #PB_Text_Border)
ListViewGadget(#lgtOutputDevices, 5, 23, #Column, 100)
MaxOutDev = midiOutGetNumDevs_()
InfoOut.MIDIOUTCAPS
If MaxOutDev
For a = -1 To MaxOutDev - 1
midiOutGetDevCaps_(a, InfoOut, SizeOf(MIDIOUTCAPS))
AddGadgetItem(#lgtOutputDevices, -1, PeekS(@InfoOut\szPname[0], 32))
Next
Else
AddGadgetItem(#lgtOutputDevices, -1, "(no output device)")
DisableGadget(#lgtInputDevices, 1)
EndIf
; MessageRequester("","1")
TextGadget(#txtInputDevices, #Offset, 5, #Column, 18, "Input-Device:", #PB_Text_Center | #PB_Text_Border)
ListViewGadget(#lgtInputDevices, #Offset, 23, #Column, 100)
MaxInDev = midiInGetNumDevs_()
InfoIn.MIDIINCAPS
If MaxInDev
For a = 0 To MaxInDev - 1
midiInGetDevCaps_(a, InfoIn, SizeOf(MIDIINCAPS))
AddGadgetItem(#lgtInputDevices, -1, PeekS(@InfoIn\szPname[0], 32))
Next
Else
AddGadgetItem(#lgtInputDevices, -1, "(no input device)")
DisableGadget(#lgtInputDevices, 1)
EndIf
; MessageRequester("","2")
ButtonGadget(#btnOK, 5, 240, #Column, 24, "&OK")
ButtonGadget(#btnCancel, #Offset, 240, #Column, 24, "&Cancel")
FrameGadget(#frgFrame, 5, 130, #Width - 10, 100, "Info of Output-Device", 0)
TextGadget(#txtVersion, 10, 145, #Width - 20, 18, "Version:")
TextGadget(#txtTech, 10, 165, #Width - 20, 18, "Technology:")
TextGadget(#txtMaxVoice, 10, 185, #Width - 20, 18, "Max. Voices:")
TextGadget(#txtPoly, 10, 205, #Width - 20, 18, "Polyphonie:")
OutDev = 0
InDev = 0
Quit = #False
OK = #False
; MessageRequester("","TEST")
; ======================================================================
Repeat
If GetGadgetState(#lgtOutputDevices) > -1 Or GetGadgetState(#lgtInputDevices) > -1
DisableGadget(#btnOK, 0)
Else
DisableGadget(#btnOK, 1)
EndIf
If InDev <> GetGadgetState(#lgtInputDevices)
InDev = GetGadgetState(#lgtInputDevices)
EndIf
If GetGadgetState(#lgtOutputDevices) <> OutDev
OutDev = GetGadgetState(#lgtOutputDevices)
midiOutGetDevCaps_(OutDev - 1, InfoOut, SizeOf(MIDIOUTCAPS))
SetGadgetText(#txtVersion, "Version: " + Str(InfoOut\vDriverVersion >> 8) + "." + Str(InfoOut\vDriverVersion & $FF))
Select InfoOut\wTechnology
Case #MOD_MIDIPORT : TmpS.s = "Hardware Port"
Case #MOD_SYNTH : TmpS.s = "Synthesizer"
Case #MOD_SQSYNTH : TmpS.s = "Square Wave Synthesizer"
Case #MOD_FMSYNTH : TmpS.s = "FM Synthesizer"
Case #MOD_MAPPER : TmpS.s = "Microsoft MIDI Mapper"
Case #MOD_WAVETABLE : TmpS.s = "Hardware Wavetable Synthesizer"
Case #MOD_SWSYNTH : TmpS.s = "Software Synthesizer"
Default: TmpS.s = "(Error Code " + Str(InfoOut\wTechnology) + ")"
EndSelect
SetGadgetText(#txtTech, "Technology: " + TmpS)
If InfoOut\wVoices = 0 : TmpS.s = "inf" : Else : TmpS.s = Str(InfoOut\wVoices) : EndIf
SetGadgetText(#txtMaxVoice, "Max. Voices: " + TmpS)
If InfoOut\wNotes = 0 : TmpS.s = "inf" : Else : TmpS.s = Str(InfoOut\wNotes) : EndIf
SetGadgetText(#txtPoly, "Polyphonie: " + TmpS)
EndIf
EventID = WaitWindowEvent()
Select EventID
Case #PB_Event_CloseWindow
Quit = #True
OK = #False
Case #PB_Event_Gadget
Select EventGadget()
Case #btnOK
PokeL(*OutDevice, OutDev - 1) ; Trick to return two results (OutDev & InDev)
PokeL(*InDevice, InDev)
Quit = #True
OK = 3
If (OutDev = -1 Or CountGadgetItems(#lgtOutputDevices) = 0) And OK & #MIDIRequ_OutSet
OK ! #MIDIRequ_OutSet : EndIf
If (InDev = -1 Or CountGadgetItems(#lgtInputDevices) = 0) And OK & #MIDIRequ_InSet
OK ! #MIDIRequ_InSet : EndIf
Case #btnCancel
Quit = #True
OK = #False
EndSelect
EndSelect
Until Quit
;==================================================================================
; CloseWindow(#WinMIDIrequester)
ProcedureReturn OK
Else
End
EndIf
EndProcedure
Procedure MIDIInProc(hMIDIIn, WMsg, DuMMy, D1, D2) ;ONLY CALLED ON STARTUP BY ME BUT THE SYNTH CALLS IT ALL THE TIME! It is the callback function for handling incoming MIDI messages.
Define i
If FetchFlag
Debug Hex(D2);Str(D1)
EndIf
With _MIDI
Select WMsg ; process some MIDI in events.
Case #MM_MIM_DATA;The MIM_DATA message is sent to a MIDI input callback function when a MIDI message is received by a MIDI input device.
If D1 & $FF =144
\Stat=(D1 >> 8) & $FF ;Note pitch value.
\Dat1=(D1 >> 16) & $FF ;Velocity value.
If \Dat1
SetWindowTitle(0,"Note On")
Debug "MIDIInProc NOTE ON " + Str(D1) + "; " + Str(\Stat) + "; Velocity: " + Str(\Dat1)
Else
SetWindowTitle(0,"Note Off")
EndIf
ElseIf D1 & $FF = $F0 ; Trying to recieve a SYSEX dump from my synth. The app MIDI-OX can recieve my dumps so my system is working.
Debug "Start of SYSEX!"
If (D1 >> 8) & $FF = $42
Debug "KORG-ID"
EndIf
EndIf
Case #MIM_LONGDATA ; Trying to recieve a SYSEX dump from my synth. The app MIDI-OX can recieve my dumps so my system is working.
Debug "---------- NEW INCOMING SYSEX -----------"
For i = 0 To MidiHeader\dwBytesRecorded - 1 ; Read Buffer Sent from LPData
Debug Hex(PeekB(*SysexBuffer + i) & $FF)
Next
; MHI\lpData = @arrSysexMessage() ; MIDI Header pointer to MIDI data.
midiInAddBuffer_(_hMIDIIn, @MidiHeader, SizeOf(MidiHeader)) ; Recycle Sysex Buffer
EndSelect
EndWith
EndProcedure
Procedure MIDIinit(OutDev, InDev, *MIDIInProc=-1,Instrument=0) ;ONLY CALLED ON STARTUP! MIDIinproc default solo show Note on, Note off
Define iMidiInterface.i, i.l,sText.s
MIDIHeader\dwFlags = 0
MidiHeader\dwBufferLength = 16384
MidiHeader\lpData = *SysexBuffer
If *MIDIinproc=-1:*MIDIinproc=@MIDIinproc():EndIf
; The MidiInProc function is the callback function for handling incoming MIDI messages. MidiInProc is a placeholder for the application-supplied function name.
; The address of this function can be specified in the callback-address parameter of the midiInOpen function.
If midiInOpen_(@_hMIDIIn, InDev, *MIDIInProc, 0, #CALLBACK_FUNCTION) = #MMSYSERR_NOERROR
midiInPrepareHeader_(_hMIDIIn, @MidiHeader, SizeOf(MidiHeader))
midiInAddBuffer_(_hMIDIIn, @MidiHeader, SizeOf(MidiHeader))
If midiInStart_(_hMIDIIn) <> #MMSYSERR_NOERROR : MessageRequester("Error","Can't start MIDI IN",0) :End: EndIf
EndIf
; The midiInStart function starts MIDI input on the specified MIDI input device. hMidiIn is the handle to the MIDI input device. This function resets the time stamp to zero;
; time stamp values For subsequently received messages are relative to the time that this function was called. Calling this function when input is already started has no effect,
; and the function returns zero.
midiOutOpen_(@_hMIDIout, OutDev, 0, 0, 0);Öppnar midi-interface. LPHMIDIOUT=lphmo=pointer to an HMIDIOUT handle.
; This location is filled with a handle identifying the opened MIDI output device.
; The handle is used To identify the device in calls To other MIDI output functions. OutDev=uDeviceID=Identifier of the MIDI output device that is to be opened.
; 3rd placeholder = dwCallback and 0 means no callback is desired. 4th placeholder is dwCallbackInstance. Last placeholder is dwFlags=callbackflag.
midiOutShortMsg_(_hMIDIout, 192 | Instrument<<8 ) ; Sends a short MIDI message (here a Patch Change) to the specified MIDI output device. HMIDIOUT=hmo=Handle to the MIDI output device.
; This parameter can also be the handle of a MIDI stream cast To HMIDIOUT.
; The 2nd placeholder is dwMsg=similar to #MM_MIM_DATA above.
If _hMIDIIn And _hMIDIout
If midiConnect_(_hMIDIIn, _hMIDIout, 0);The midiConnect function connects a MIDI input device to a MIDI thru or output device,
; or connects a MIDI thru device To a MIDI output device.
; First inpDeviceHandle, then outpDevHandle, 3rd placeholder must be zero.
MessageRequester("Error","Can't connect MIDI",0) :End
EndIf
EndIf
EndProcedure
MIDIResult = MIDIRequester(@OutDevice, @InDevice)
If MIDIResult & #MIDIRequ_OutSet : Debug "Output device: " + Str(OutDevice) : EndIf
If MIDIResult & #MIDIRequ_InSet : Debug "Input device: " + Str(InDevice) : EndIf
MIDIinit(OutDevice,InDevice);*** Is called only once! ****
OpenWindow(0, 10, 10, 300, 200, "MIDI Test")
Repeat
Event = WaitWindowEvent()
Until Event = #PB_Event_CloseWindow
-
- User
- Posts: 40
- Joined: Wed Oct 06, 2010 9:37 pm
Re: KORG X5D via MIDI (was: Where to hire a programmer)
I see you two replies. I have been idle for a while. Just a moment while I connect the cables.firace wrote: Tue Jan 02, 2024 5:03 pmNice challenge! I unfortunately don't have a MIDI device to test.SiggeSvahn wrote: Tue Jan 02, 2024 4:30 pm Well, here is the snippet. I use PC Win11 and syntheziser KORG X5D. The portion that should receive a MIDI Bulf Dump does not work. I would pay 200$ to the first person who presents a version that works on my computer.
But what exactly happens with the current code? Does it crash, or do you get an error message?
Newbie
-
- User
- Posts: 40
- Joined: Wed Oct 06, 2010 9:37 pm
Re: KORG X5D via MIDI (was: Where to hire a programmer)
NICE TRY! Your version is recieving 5 bytes of SYSEX data and then it stops (F0, 42, 30, 36, 23, F7). It is a kind of success so I want to send 200$ through PayPal. I would like it to continuously show what keeps coming from the synth. I have both the keyboard version KORG X5D and the rack version X5DR. Would you be interested in that I send the rack to you so that you could try yourself (tell me your price)?firace wrote: Tue Jan 02, 2024 5:23 pm Some shots in the dark... Could you try the below code?
I've fixed a few things like initializing the MIDI header, and the Sysex buffer.
Code: Select all
;;; firace debugging v0.3 ;Incoming SYSEX Tryout. #WinMIDIrequester=1 Enumeration GADGETS #txtOutputDevices=1 #txtInputDevices #lgtOutputDevices #lgtInputDevices #btnOK #btnCancel #frgFrame #txtVersion #txttech #txtMaxVoice #txtPoly EndEnumeration Structure MIDI MIDIIn.A MIDIOut.A Stat.A Dat1.A Dat2.A EndStructure Global MidiHeader.MIDIHDR Global hMiP0.l = 0 Global *SysexBuffer = AllocateMemory(4096) Global _MIDI.MIDI Global Dim arrSysexMessage.a(9) Procedure MIDIRequester(*OutDevice, *InDevice) Define MaxOutDev, MaxInDev, InfoOut.MIDIOUTCAPS,InfoIn.MIDIINCAPS, a, OutDev, InDev, Quit, OK, TmpS.s, EventID #MOD_WAVETABLE = 6 #MOD_SWSYNTH = 7 #MIDIRequ_InSet = 2 #MIDIRequ_OutSet = 1 #Width = 400 If OpenWindow(#WinMIDIrequester, 0, 0, #Width, 270, "MIDI-Requester Sel MIDI-modem etc slot that you want to use.", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) #Column = (#Width - 20) / 2 #Offset = (#Width / 2) + 5 TextGadget(#txtOutputDevices, 5, 5, #Column, 18, "Output-Device:", #PB_Text_Center | #PB_Text_Border) ListViewGadget(#lgtOutputDevices, 5, 23, #Column, 100) MaxOutDev = midiOutGetNumDevs_() InfoOut.MIDIOUTCAPS If MaxOutDev For a = -1 To MaxOutDev - 1 midiOutGetDevCaps_(a, InfoOut, SizeOf(MIDIOUTCAPS)) AddGadgetItem(#lgtOutputDevices, -1, PeekS(@InfoOut\szPname[0], 32)) Next Else AddGadgetItem(#lgtOutputDevices, -1, "(no output device)") DisableGadget(#lgtInputDevices, 1) EndIf ; MessageRequester("","1") TextGadget(#txtInputDevices, #Offset, 5, #Column, 18, "Input-Device:", #PB_Text_Center | #PB_Text_Border) ListViewGadget(#lgtInputDevices, #Offset, 23, #Column, 100) MaxInDev = midiInGetNumDevs_() InfoIn.MIDIINCAPS If MaxInDev For a = 0 To MaxInDev - 1 midiInGetDevCaps_(a, InfoIn, SizeOf(MIDIINCAPS)) AddGadgetItem(#lgtInputDevices, -1, PeekS(@InfoIn\szPname[0], 32)) Next Else AddGadgetItem(#lgtInputDevices, -1, "(no input device)") DisableGadget(#lgtInputDevices, 1) EndIf ; MessageRequester("","2") ButtonGadget(#btnOK, 5, 240, #Column, 24, "&OK") ButtonGadget(#btnCancel, #Offset, 240, #Column, 24, "&Cancel") FrameGadget(#frgFrame, 5, 130, #Width - 10, 100, "Info of Output-Device", 0) TextGadget(#txtVersion, 10, 145, #Width - 20, 18, "Version:") TextGadget(#txtTech, 10, 165, #Width - 20, 18, "Technology:") TextGadget(#txtMaxVoice, 10, 185, #Width - 20, 18, "Max. Voices:") TextGadget(#txtPoly, 10, 205, #Width - 20, 18, "Polyphonie:") OutDev = 0 InDev = 0 Quit = #False OK = #False ; MessageRequester("","TEST") ; ====================================================================== Repeat If GetGadgetState(#lgtOutputDevices) > -1 Or GetGadgetState(#lgtInputDevices) > -1 DisableGadget(#btnOK, 0) Else DisableGadget(#btnOK, 1) EndIf If InDev <> GetGadgetState(#lgtInputDevices) InDev = GetGadgetState(#lgtInputDevices) EndIf If GetGadgetState(#lgtOutputDevices) <> OutDev OutDev = GetGadgetState(#lgtOutputDevices) midiOutGetDevCaps_(OutDev - 1, InfoOut, SizeOf(MIDIOUTCAPS)) SetGadgetText(#txtVersion, "Version: " + Str(InfoOut\vDriverVersion >> 8) + "." + Str(InfoOut\vDriverVersion & $FF)) Select InfoOut\wTechnology Case #MOD_MIDIPORT : TmpS.s = "Hardware Port" Case #MOD_SYNTH : TmpS.s = "Synthesizer" Case #MOD_SQSYNTH : TmpS.s = "Square Wave Synthesizer" Case #MOD_FMSYNTH : TmpS.s = "FM Synthesizer" Case #MOD_MAPPER : TmpS.s = "Microsoft MIDI Mapper" Case #MOD_WAVETABLE : TmpS.s = "Hardware Wavetable Synthesizer" Case #MOD_SWSYNTH : TmpS.s = "Software Synthesizer" Default: TmpS.s = "(Error Code " + Str(InfoOut\wTechnology) + ")" EndSelect SetGadgetText(#txtTech, "Technology: " + TmpS) If InfoOut\wVoices = 0 : TmpS.s = "inf" : Else : TmpS.s = Str(InfoOut\wVoices) : EndIf SetGadgetText(#txtMaxVoice, "Max. Voices: " + TmpS) If InfoOut\wNotes = 0 : TmpS.s = "inf" : Else : TmpS.s = Str(InfoOut\wNotes) : EndIf SetGadgetText(#txtPoly, "Polyphonie: " + TmpS) EndIf EventID = WaitWindowEvent() Select EventID Case #PB_Event_CloseWindow Quit = #True OK = #False Case #PB_Event_Gadget Select EventGadget() Case #btnOK PokeL(*OutDevice, OutDev - 1) ; Trick to return two results (OutDev & InDev) PokeL(*InDevice, InDev) Quit = #True OK = 3 If (OutDev = -1 Or CountGadgetItems(#lgtOutputDevices) = 0) And OK & #MIDIRequ_OutSet OK ! #MIDIRequ_OutSet : EndIf If (InDev = -1 Or CountGadgetItems(#lgtInputDevices) = 0) And OK & #MIDIRequ_InSet OK ! #MIDIRequ_InSet : EndIf Case #btnCancel Quit = #True OK = #False EndSelect EndSelect Until Quit ;================================================================================== ; CloseWindow(#WinMIDIrequester) ProcedureReturn OK Else End EndIf EndProcedure Procedure MIDIInProc(hMIDIIn, WMsg, DuMMy, D1, D2) ;ONLY CALLED ON STARTUP BY ME BUT THE SYNTH CALLS IT ALL THE TIME! It is the callback function for handling incoming MIDI messages. Define i If FetchFlag Debug Hex(D2);Str(D1) EndIf With _MIDI Select WMsg ; process some MIDI in events. Case #MM_MIM_DATA;The MIM_DATA message is sent to a MIDI input callback function when a MIDI message is received by a MIDI input device. If D1 & $FF =144 \Stat=(D1 >> 8) & $FF ;Note pitch value. \Dat1=(D1 >> 16) & $FF ;Velocity value. If \Dat1 SetWindowTitle(0,"Note On") Debug "MIDIInProc NOTE ON " + Str(D1) + "; " + Str(\Stat) + "; Velocity: " + Str(\Dat1) Else SetWindowTitle(0,"Note Off") EndIf ElseIf D1 & $FF = $F0 ; Trying to recieve a SYSEX dump from my synth. The app MIDI-OX can recieve my dumps so my system is working. Debug "Start of SYSEX!" If (D1 >> 8) & $FF = $42 Debug "KORG-ID" EndIf EndIf Case #MIM_LONGDATA ; Trying to recieve a SYSEX dump from my synth. The app MIDI-OX can recieve my dumps so my system is working. Debug "---------- NEW INCOMING SYSEX -----------" For i = 0 To MidiHeader\dwBytesRecorded - 1 ; Read Buffer Sent from LPData Debug Hex(PeekB(*SysexBuffer + i) & $FF) Next ; MHI\lpData = @arrSysexMessage() ; MIDI Header pointer to MIDI data. midiInAddBuffer_(_hMIDIIn, @MidiHeader, SizeOf(MidiHeader)) ; Recycle Sysex Buffer EndSelect EndWith EndProcedure Procedure MIDIinit(OutDev, InDev, *MIDIInProc=-1,Instrument=0) ;ONLY CALLED ON STARTUP! MIDIinproc default solo show Note on, Note off Define iMidiInterface.i, i.l,sText.s MIDIHeader\dwFlags = 0 MidiHeader\dwBufferLength = 16384 MidiHeader\lpData = *SysexBuffer If *MIDIinproc=-1:*MIDIinproc=@MIDIinproc():EndIf ; The MidiInProc function is the callback function for handling incoming MIDI messages. MidiInProc is a placeholder for the application-supplied function name. ; The address of this function can be specified in the callback-address parameter of the midiInOpen function. If midiInOpen_(@_hMIDIIn, InDev, *MIDIInProc, 0, #CALLBACK_FUNCTION) = #MMSYSERR_NOERROR midiInPrepareHeader_(_hMIDIIn, @MidiHeader, SizeOf(MidiHeader)) midiInAddBuffer_(_hMIDIIn, @MidiHeader, SizeOf(MidiHeader)) If midiInStart_(_hMIDIIn) <> #MMSYSERR_NOERROR : MessageRequester("Error","Can't start MIDI IN",0) :End: EndIf EndIf ; The midiInStart function starts MIDI input on the specified MIDI input device. hMidiIn is the handle to the MIDI input device. This function resets the time stamp to zero; ; time stamp values For subsequently received messages are relative to the time that this function was called. Calling this function when input is already started has no effect, ; and the function returns zero. midiOutOpen_(@_hMIDIout, OutDev, 0, 0, 0);Öppnar midi-interface. LPHMIDIOUT=lphmo=pointer to an HMIDIOUT handle. ; This location is filled with a handle identifying the opened MIDI output device. ; The handle is used To identify the device in calls To other MIDI output functions. OutDev=uDeviceID=Identifier of the MIDI output device that is to be opened. ; 3rd placeholder = dwCallback and 0 means no callback is desired. 4th placeholder is dwCallbackInstance. Last placeholder is dwFlags=callbackflag. midiOutShortMsg_(_hMIDIout, 192 | Instrument<<8 ) ; Sends a short MIDI message (here a Patch Change) to the specified MIDI output device. HMIDIOUT=hmo=Handle to the MIDI output device. ; This parameter can also be the handle of a MIDI stream cast To HMIDIOUT. ; The 2nd placeholder is dwMsg=similar to #MM_MIM_DATA above. If _hMIDIIn And _hMIDIout If midiConnect_(_hMIDIIn, _hMIDIout, 0);The midiConnect function connects a MIDI input device to a MIDI thru or output device, ; or connects a MIDI thru device To a MIDI output device. ; First inpDeviceHandle, then outpDevHandle, 3rd placeholder must be zero. MessageRequester("Error","Can't connect MIDI",0) :End EndIf EndIf EndProcedure MIDIResult = MIDIRequester(@OutDevice, @InDevice) If MIDIResult & #MIDIRequ_OutSet : Debug "Output device: " + Str(OutDevice) : EndIf If MIDIResult & #MIDIRequ_InSet : Debug "Input device: " + Str(InDevice) : EndIf MIDIinit(OutDevice,InDevice);*** Is called only once! **** OpenWindow(0, 10, 10, 300, 200, "MIDI Test") Repeat Event = WaitWindowEvent() Until Event = #PB_Event_CloseWindow
Newbie
Re: KORG X5D via MIDI (was: Where to hire a programmer)
Glad to know I could help!SiggeSvahn wrote: Tue Jan 02, 2024 10:42 pm NICE TRY! Your version is recieving 5 bytes of SYSEX data and then it stops (F0, 42, 30, 36, 23, F7). It is a kind of success so I want to send 200$ through PayPal. I would like it to continuously show what keeps coming from the synth. I have both the keyboard version KORG X5D and the rack version X5DR. Would you be interested in that I send the rack to you so that you could try yourself (tell me your price)?
But I don't have a MIDI keyboard at this time, so I can't do more thorough testing unfortunately.

PS: I just replied to your PM.
Re: KORG X5D via MIDI (was: Where to hire a programmer)
Thanks for the generous reward! Here’s another version with increased buffer size, perhaps it will be able to capture more Sysex data. (untested)
Code: Select all
;;; firace debugging v0.4
;Incoming SYSEX Tryout.
#WinMIDIrequester=1
Enumeration GADGETS
#txtOutputDevices=1
#txtInputDevices
#lgtOutputDevices
#lgtInputDevices
#btnOK
#btnCancel
#frgFrame
#txtVersion
#txttech
#txtMaxVoice
#txtPoly
EndEnumeration
Structure MIDI
MIDIIn.A
MIDIOut.A
Stat.A
Dat1.A
Dat2.A
EndStructure
Global MidiHeader.MIDIHDR
Global hMiP0.l = 0
Global *SysexBuffer = AllocateMemory(65536)
Global _MIDI.MIDI
Global Dim arrSysexMessage.a(9)
Procedure MIDIRequester(*OutDevice, *InDevice)
Define MaxOutDev, MaxInDev, InfoOut.MIDIOUTCAPS,InfoIn.MIDIINCAPS, a, OutDev, InDev, Quit, OK, TmpS.s, EventID
#MOD_WAVETABLE = 6
#MOD_SWSYNTH = 7
#MIDIRequ_InSet = 2
#MIDIRequ_OutSet = 1
#Width = 400
If OpenWindow(#WinMIDIrequester, 0, 0, #Width, 270, "MIDI-Requester Sel MIDI-modem etc slot that you want to use.", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
#Column = (#Width - 20) / 2
#Offset = (#Width / 2) + 5
TextGadget(#txtOutputDevices, 5, 5, #Column, 18, "Output-Device:", #PB_Text_Center | #PB_Text_Border)
ListViewGadget(#lgtOutputDevices, 5, 23, #Column, 100)
MaxOutDev = midiOutGetNumDevs_()
InfoOut.MIDIOUTCAPS
If MaxOutDev
For a = -1 To MaxOutDev - 1
midiOutGetDevCaps_(a, InfoOut, SizeOf(MIDIOUTCAPS))
AddGadgetItem(#lgtOutputDevices, -1, PeekS(@InfoOut\szPname[0], 32))
Next
Else
AddGadgetItem(#lgtOutputDevices, -1, "(no output device)")
DisableGadget(#lgtInputDevices, 1)
EndIf
; MessageRequester("","1")
TextGadget(#txtInputDevices, #Offset, 5, #Column, 18, "Input-Device:", #PB_Text_Center | #PB_Text_Border)
ListViewGadget(#lgtInputDevices, #Offset, 23, #Column, 100)
MaxInDev = midiInGetNumDevs_()
InfoIn.MIDIINCAPS
If MaxInDev
For a = 0 To MaxInDev - 1
midiInGetDevCaps_(a, InfoIn, SizeOf(MIDIINCAPS))
AddGadgetItem(#lgtInputDevices, -1, PeekS(@InfoIn\szPname[0], 32))
Next
Else
AddGadgetItem(#lgtInputDevices, -1, "(no input device)")
DisableGadget(#lgtInputDevices, 1)
EndIf
; MessageRequester("","2")
ButtonGadget(#btnOK, 5, 240, #Column, 24, "&OK")
ButtonGadget(#btnCancel, #Offset, 240, #Column, 24, "&Cancel")
FrameGadget(#frgFrame, 5, 130, #Width - 10, 100, "Info of Output-Device", 0)
TextGadget(#txtVersion, 10, 145, #Width - 20, 18, "Version:")
TextGadget(#txtTech, 10, 165, #Width - 20, 18, "Technology:")
TextGadget(#txtMaxVoice, 10, 185, #Width - 20, 18, "Max. Voices:")
TextGadget(#txtPoly, 10, 205, #Width - 20, 18, "Polyphonie:")
OutDev = 0
InDev = 0
Quit = #False
OK = #False
; MessageRequester("","TEST")
; ======================================================================
Repeat
If GetGadgetState(#lgtOutputDevices) > -1 Or GetGadgetState(#lgtInputDevices) > -1
DisableGadget(#btnOK, 0)
Else
DisableGadget(#btnOK, 1)
EndIf
If InDev <> GetGadgetState(#lgtInputDevices)
InDev = GetGadgetState(#lgtInputDevices)
EndIf
If GetGadgetState(#lgtOutputDevices) <> OutDev
OutDev = GetGadgetState(#lgtOutputDevices)
midiOutGetDevCaps_(OutDev - 1, InfoOut, SizeOf(MIDIOUTCAPS))
SetGadgetText(#txtVersion, "Version: " + Str(InfoOut\vDriverVersion >> 8) + "." + Str(InfoOut\vDriverVersion & $FF))
Select InfoOut\wTechnology
Case #MOD_MIDIPORT : TmpS.s = "Hardware Port"
Case #MOD_SYNTH : TmpS.s = "Synthesizer"
Case #MOD_SQSYNTH : TmpS.s = "Square Wave Synthesizer"
Case #MOD_FMSYNTH : TmpS.s = "FM Synthesizer"
Case #MOD_MAPPER : TmpS.s = "Microsoft MIDI Mapper"
Case #MOD_WAVETABLE : TmpS.s = "Hardware Wavetable Synthesizer"
Case #MOD_SWSYNTH : TmpS.s = "Software Synthesizer"
Default: TmpS.s = "(Error Code " + Str(InfoOut\wTechnology) + ")"
EndSelect
SetGadgetText(#txtTech, "Technology: " + TmpS)
If InfoOut\wVoices = 0 : TmpS.s = "inf" : Else : TmpS.s = Str(InfoOut\wVoices) : EndIf
SetGadgetText(#txtMaxVoice, "Max. Voices: " + TmpS)
If InfoOut\wNotes = 0 : TmpS.s = "inf" : Else : TmpS.s = Str(InfoOut\wNotes) : EndIf
SetGadgetText(#txtPoly, "Polyphonie: " + TmpS)
EndIf
EventID = WaitWindowEvent()
Select EventID
Case #PB_Event_CloseWindow
Quit = #True
OK = #False
Case #PB_Event_Gadget
Select EventGadget()
Case #btnOK
PokeL(*OutDevice, OutDev - 1) ; Trick to return two results (OutDev & InDev)
PokeL(*InDevice, InDev)
Quit = #True
OK = 3
If (OutDev = -1 Or CountGadgetItems(#lgtOutputDevices) = 0) And OK & #MIDIRequ_OutSet
OK ! #MIDIRequ_OutSet : EndIf
If (InDev = -1 Or CountGadgetItems(#lgtInputDevices) = 0) And OK & #MIDIRequ_InSet
OK ! #MIDIRequ_InSet : EndIf
Case #btnCancel
Quit = #True
OK = #False
EndSelect
EndSelect
Until Quit
;==================================================================================
; CloseWindow(#WinMIDIrequester)
ProcedureReturn OK
Else
End
EndIf
EndProcedure
Procedure MIDIInProc(hMIDIIn, WMsg, DuMMy, D1, D2) ;ONLY CALLED ON STARTUP BY ME BUT THE SYNTH CALLS IT ALL THE TIME! It is the callback function for handling incoming MIDI messages.
Define i
If FetchFlag
Debug Hex(D2);Str(D1)
EndIf
With _MIDI
Select WMsg ; process some MIDI in events.
Case #MM_MIM_DATA;The MIM_DATA message is sent to a MIDI input callback function when a MIDI message is received by a MIDI input device.
If D1 & $FF =144
\Stat=(D1 >> 8) & $FF ;Note pitch value.
\Dat1=(D1 >> 16) & $FF ;Velocity value.
If \Dat1
SetWindowTitle(0,"Note On")
Debug "MIDIInProc NOTE ON " + Str(D1) + "; " + Str(\Stat) + "; Velocity: " + Str(\Dat1)
Else
SetWindowTitle(0,"Note Off")
EndIf
ElseIf D1 & $FF = $F0 ; Trying to recieve a SYSEX dump from my synth. The app MIDI-OX can recieve my dumps so my system is working.
Debug "Start of SYSEX!"
If (D1 >> 8) & $FF = $42
Debug "KORG-ID"
EndIf
EndIf
Case #MIM_LONGDATA ; Trying to recieve a SYSEX dump from my synth. The app MIDI-OX can recieve my dumps so my system is working.
Debug "---------- NEW INCOMING SYSEX -----------"
For i = 0 To MidiHeader\dwBytesRecorded - 1 ; Read Buffer Sent from LPData
Debug Hex(PeekB(*SysexBuffer + i) & $FF)
Next
; MHI\lpData = @arrSysexMessage() ; MIDI Header pointer to MIDI data.
midiInAddBuffer_(_hMIDIIn, @MidiHeader, SizeOf(MidiHeader)) ; Recycle Sysex Buffer
EndSelect
EndWith
EndProcedure
Procedure MIDIinit(OutDev, InDev, *MIDIInProc=-1,Instrument=0) ;ONLY CALLED ON STARTUP! MIDIinproc default solo show Note on, Note off
Define iMidiInterface.i, i.l,sText.s
MIDIHeader\dwFlags = 0
MidiHeader\dwBufferLength = 65536
MidiHeader\lpData = *SysexBuffer
If *MIDIinproc=-1:*MIDIinproc=@MIDIinproc():EndIf
; The MidiInProc function is the callback function for handling incoming MIDI messages. MidiInProc is a placeholder for the application-supplied function name.
; The address of this function can be specified in the callback-address parameter of the midiInOpen function.
If midiInOpen_(@_hMIDIIn, InDev, *MIDIInProc, 0, #CALLBACK_FUNCTION) = #MMSYSERR_NOERROR
midiInPrepareHeader_(_hMIDIIn, @MidiHeader, SizeOf(MidiHeader))
midiInAddBuffer_(_hMIDIIn, @MidiHeader, SizeOf(MidiHeader))
If midiInStart_(_hMIDIIn) <> #MMSYSERR_NOERROR : MessageRequester("Error","Can't start MIDI IN",0) :End: EndIf
EndIf
; The midiInStart function starts MIDI input on the specified MIDI input device. hMidiIn is the handle to the MIDI input device. This function resets the time stamp to zero;
; time stamp values For subsequently received messages are relative to the time that this function was called. Calling this function when input is already started has no effect,
; and the function returns zero.
midiOutOpen_(@_hMIDIout, OutDev, 0, 0, 0);Öppnar midi-interface. LPHMIDIOUT=lphmo=pointer to an HMIDIOUT handle.
; This location is filled with a handle identifying the opened MIDI output device.
; The handle is used To identify the device in calls To other MIDI output functions. OutDev=uDeviceID=Identifier of the MIDI output device that is to be opened.
; 3rd placeholder = dwCallback and 0 means no callback is desired. 4th placeholder is dwCallbackInstance. Last placeholder is dwFlags=callbackflag.
midiOutShortMsg_(_hMIDIout, 192 | Instrument<<8 ) ; Sends a short MIDI message (here a Patch Change) to the specified MIDI output device. HMIDIOUT=hmo=Handle to the MIDI output device.
; This parameter can also be the handle of a MIDI stream cast To HMIDIOUT.
; The 2nd placeholder is dwMsg=similar to #MM_MIM_DATA above.
If _hMIDIIn And _hMIDIout
If midiConnect_(_hMIDIIn, _hMIDIout, 0);The midiConnect function connects a MIDI input device to a MIDI thru or output device,
; or connects a MIDI thru device To a MIDI output device.
; First inpDeviceHandle, then outpDevHandle, 3rd placeholder must be zero.
MessageRequester("Error","Can't connect MIDI",0) :End
EndIf
EndIf
EndProcedure
MIDIResult = MIDIRequester(@OutDevice, @InDevice)
If MIDIResult & #MIDIRequ_OutSet : Debug "Output device: " + Str(OutDevice) : EndIf
If MIDIResult & #MIDIRequ_InSet : Debug "Input device: " + Str(InDevice) : EndIf
MIDIinit(OutDevice,InDevice);*** Is called only once! ****
OpenWindow(0, 10, 10, 300, 200, "MIDI Test")
Repeat
Event = WaitWindowEvent()
Until Event = #PB_Event_CloseWindow
Re: KORG X5D via MIDI (was: Where to hire a programmer)
Hey, I've had a bit of time to do some extra debugging and fixed a few more things... I would recommend to try both versions 0.5a and 0.5b (see below) and see which one produces the best result.
Hope this helps!
Hope this helps!
Code: Select all
;;; firace debugging ver 0.5a
;Incoming SYSEX Tryout.
#WinMIDIrequester=1
Enumeration GADGETS
#txtOutputDevices=1
#txtInputDevices
#lgtOutputDevices
#lgtInputDevices
#btnOK
#btnCancel
#frgFrame
#txtVersion
#txttech
#txtMaxVoice
#txtPoly
EndEnumeration
Structure MIDI
MIDIIn.A
MIDIOut.A
Stat.A
Dat1.A
Dat2.A
EndStructure
Global MidiHeader.MIDIHDR
Global hMiP0.l = 0
Global *SysexBuffer = AllocateMemory(65536)
Global _MIDI.MIDI
Global Dim arrSysexMessage.a(9)
Procedure MIDIRequester(*OutDevice, *InDevice)
Define MaxOutDev, MaxInDev, InfoOut.MIDIOUTCAPS,InfoIn.MIDIINCAPS, a, OutDev, InDev, Quit, OK, TmpS.s, EventID
#MOD_WAVETABLE = 6
#MOD_SWSYNTH = 7
#MIDIRequ_InSet = 2
#MIDIRequ_OutSet = 1
#Width = 400
If OpenWindow(#WinMIDIrequester, 0, 0, #Width, 270, "MIDI-Requester Sel MIDI-modem etc slot that you want to use.", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
#Column = (#Width - 20) / 2
#Offset = (#Width / 2) + 5
TextGadget(#txtOutputDevices, 5, 5, #Column, 18, "Output-Device:", #PB_Text_Center | #PB_Text_Border)
ListViewGadget(#lgtOutputDevices, 5, 23, #Column, 100)
MaxOutDev = midiOutGetNumDevs_()
InfoOut.MIDIOUTCAPS
If MaxOutDev
For a = -1 To MaxOutDev - 1
midiOutGetDevCaps_(a, InfoOut, SizeOf(MIDIOUTCAPS))
AddGadgetItem(#lgtOutputDevices, -1, PeekS(@InfoOut\szPname[0], 32))
Next
Else
AddGadgetItem(#lgtOutputDevices, -1, "(no output device)")
DisableGadget(#lgtInputDevices, 1)
EndIf
; MessageRequester("","1")
TextGadget(#txtInputDevices, #Offset, 5, #Column, 18, "Input-Device:", #PB_Text_Center | #PB_Text_Border)
ListViewGadget(#lgtInputDevices, #Offset, 23, #Column, 100)
MaxInDev = midiInGetNumDevs_()
InfoIn.MIDIINCAPS
If MaxInDev
For a = 0 To MaxInDev - 1
midiInGetDevCaps_(a, InfoIn, SizeOf(MIDIINCAPS))
AddGadgetItem(#lgtInputDevices, -1, PeekS(@InfoIn\szPname[0], 32))
Next
Else
AddGadgetItem(#lgtInputDevices, -1, "(no input device)")
DisableGadget(#lgtInputDevices, 1)
EndIf
; MessageRequester("","2")
ButtonGadget(#btnOK, 5, 240, #Column, 24, "&OK")
ButtonGadget(#btnCancel, #Offset, 240, #Column, 24, "&Cancel")
FrameGadget(#frgFrame, 5, 130, #Width - 10, 100, "Info of Output-Device", 0)
TextGadget(#txtVersion, 10, 145, #Width - 20, 18, "Version:")
TextGadget(#txtTech, 10, 165, #Width - 20, 18, "Technology:")
TextGadget(#txtMaxVoice, 10, 185, #Width - 20, 18, "Max. Voices:")
TextGadget(#txtPoly, 10, 205, #Width - 20, 18, "Polyphonie:")
OutDev = 0
InDev = 0
Quit = #False
OK = #False
; MessageRequester("","TEST")
; ======================================================================
Repeat
If GetGadgetState(#lgtOutputDevices) > -1 Or GetGadgetState(#lgtInputDevices) > -1
DisableGadget(#btnOK, 0)
Else
DisableGadget(#btnOK, 1)
EndIf
If InDev <> GetGadgetState(#lgtInputDevices)
InDev = GetGadgetState(#lgtInputDevices)
EndIf
If GetGadgetState(#lgtOutputDevices) <> OutDev
OutDev = GetGadgetState(#lgtOutputDevices)
midiOutGetDevCaps_(OutDev - 1, InfoOut, SizeOf(MIDIOUTCAPS))
SetGadgetText(#txtVersion, "Version: " + Str(InfoOut\vDriverVersion >> 8) + "." + Str(InfoOut\vDriverVersion & $FF))
Select InfoOut\wTechnology
Case #MOD_MIDIPORT : TmpS.s = "Hardware Port"
Case #MOD_SYNTH : TmpS.s = "Synthesizer"
Case #MOD_SQSYNTH : TmpS.s = "Square Wave Synthesizer"
Case #MOD_FMSYNTH : TmpS.s = "FM Synthesizer"
Case #MOD_MAPPER : TmpS.s = "Microsoft MIDI Mapper"
Case #MOD_WAVETABLE : TmpS.s = "Hardware Wavetable Synthesizer"
Case #MOD_SWSYNTH : TmpS.s = "Software Synthesizer"
Default: TmpS.s = "(Error Code " + Str(InfoOut\wTechnology) + ")"
EndSelect
SetGadgetText(#txtTech, "Technology: " + TmpS)
If InfoOut\wVoices = 0 : TmpS.s = "inf" : Else : TmpS.s = Str(InfoOut\wVoices) : EndIf
SetGadgetText(#txtMaxVoice, "Max. Voices: " + TmpS)
If InfoOut\wNotes = 0 : TmpS.s = "inf" : Else : TmpS.s = Str(InfoOut\wNotes) : EndIf
SetGadgetText(#txtPoly, "Polyphonie: " + TmpS)
EndIf
EventID = WaitWindowEvent()
Select EventID
Case #PB_Event_CloseWindow
Quit = #True
OK = #False
Case #PB_Event_Gadget
Select EventGadget()
Case #btnOK
PokeL(*OutDevice, OutDev - 1) ; Trick to return two results (OutDev & InDev)
PokeL(*InDevice, InDev)
Quit = #True
OK = 3
If (OutDev = -1 Or CountGadgetItems(#lgtOutputDevices) = 0) And OK & #MIDIRequ_OutSet
OK ! #MIDIRequ_OutSet : EndIf
If (InDev = -1 Or CountGadgetItems(#lgtInputDevices) = 0) And OK & #MIDIRequ_InSet
OK ! #MIDIRequ_InSet : EndIf
Case #btnCancel
Quit = #True
OK = #False
EndSelect
EndSelect
Until Quit
;==================================================================================
; CloseWindow(#WinMIDIrequester)
ProcedureReturn OK
Else
End
EndIf
EndProcedure
Procedure MIDIInProc(hMIDIIn, WMsg, DuMMy, D1, D2) ;ONLY CALLED ON STARTUP BY ME BUT THE SYNTH CALLS IT ALL THE TIME! It is the callback function for handling incoming MIDI messages.
Define i
If FetchFlag
Debug Hex(D2);Str(D1)
EndIf
With _MIDI
Select WMsg ; process some MIDI in events.
Case #MM_MIM_DATA;The MIM_DATA message is sent to a MIDI input callback function when a MIDI message is received by a MIDI input device.
If D1 & $FF =144
\Stat=(D1 >> 8) & $FF ;Note pitch value.
\Dat1=(D1 >> 16) & $FF ;Velocity value.
If \Dat1
SetWindowTitle(0,"Note On")
Debug "MIDIInProc NOTE ON " + Str(D1) + "; " + Str(\Stat) + "; Velocity: " + Str(\Dat1)
Else
SetWindowTitle(0,"Note Off")
EndIf
ElseIf D1 & $FF = $F0 ; Trying to recieve a SYSEX dump from my synth. The app MIDI-OX can recieve my dumps so my system is working.
Debug "Start of SYSEX!"
If (D1 >> 8) & $FF = $42
Debug "KORG-ID"
EndIf
EndIf
Case #MIM_LONGDATA ; Trying to recieve a SYSEX dump from my synth. The app MIDI-OX can recieve my dumps so my system is working.
Debug "---------- NEW INCOMING SYSEX -----------"
For i = 0 To MidiHeader\dwBytesRecorded - 1 ; Read Buffer Sent from LPData
Debug Hex(PeekB(*SysexBuffer + i) & $FF)
Next
; MHI\lpData = @arrSysexMessage() ; MIDI Header pointer to MIDI data.
midiInAddBuffer_(hMIDIIn, @MidiHeader, SizeOf(MidiHeader)) ; Recycle Sysex Buffer
EndSelect
EndWith
EndProcedure
Procedure MIDIinit(OutDev, InDev, *MIDIInProc=-1,Instrument=0) ;ONLY CALLED ON STARTUP! MIDIinproc default solo show Note on, Note off
Define iMidiInterface.i, i.l,sText.s
MIDIHeader\dwFlags = 0
MidiHeader\dwBufferLength = 65536
MidiHeader\lpData = *SysexBuffer
If *MIDIinproc=-1:*MIDIinproc=@MIDIinproc():EndIf
; The MidiInProc function is the callback function for handling incoming MIDI messages. MidiInProc is a placeholder for the application-supplied function name.
; The address of this function can be specified in the callback-address parameter of the midiInOpen function.
If midiInOpen_(@_hMIDIIn, InDev, *MIDIInProc, 0, #CALLBACK_FUNCTION) = #MMSYSERR_NOERROR
midiInPrepareHeader_(_hMIDIIn, @MidiHeader, SizeOf(MidiHeader))
midiInAddBuffer_(_hMIDIIn, @MidiHeader, SizeOf(MidiHeader))
If midiInStart_(_hMIDIIn) <> #MMSYSERR_NOERROR : MessageRequester("Error","Can't start MIDI IN",0) :End: EndIf
EndIf
; The midiInStart function starts MIDI input on the specified MIDI input device. hMidiIn is the handle to the MIDI input device. This function resets the time stamp to zero;
; time stamp values For subsequently received messages are relative to the time that this function was called. Calling this function when input is already started has no effect,
; and the function returns zero.
midiOutOpen_(@_hMIDIout, OutDev, 0, 0, 0);Öppnar midi-interface. LPHMIDIOUT=lphmo=pointer to an HMIDIOUT handle.
; This location is filled with a handle identifying the opened MIDI output device.
; The handle is used To identify the device in calls To other MIDI output functions. OutDev=uDeviceID=Identifier of the MIDI output device that is to be opened.
; 3rd placeholder = dwCallback and 0 means no callback is desired. 4th placeholder is dwCallbackInstance. Last placeholder is dwFlags=callbackflag.
midiOutShortMsg_(_hMIDIout, 192 | Instrument<<8 ) ; Sends a short MIDI message (here a Patch Change) to the specified MIDI output device. HMIDIOUT=hmo=Handle to the MIDI output device.
; This parameter can also be the handle of a MIDI stream cast To HMIDIOUT.
; The 2nd placeholder is dwMsg=similar to #MM_MIM_DATA above.
If _hMIDIIn And _hMIDIout
If midiConnect_(_hMIDIIn, _hMIDIout, 0);The midiConnect function connects a MIDI input device to a MIDI thru or output device,
; or connects a MIDI thru device To a MIDI output device.
; First inpDeviceHandle, then outpDevHandle, 3rd placeholder must be zero.
MessageRequester("Error","Can't connect MIDI",0) :End
EndIf
EndIf
EndProcedure
MIDIResult = MIDIRequester(@OutDevice, @InDevice)
If MIDIResult & #MIDIRequ_OutSet : Debug "Output device: " + Str(OutDevice) : EndIf
If MIDIResult & #MIDIRequ_InSet : Debug "Input device: " + Str(InDevice) : EndIf
MIDIinit(OutDevice,InDevice);*** Is called only once! ****
OpenWindow(0, 10, 10, 300, 200, "MIDI Test")
Repeat
Event = WaitWindowEvent()
Until Event = #PB_Event_CloseWindow
Code: Select all
;; firace debugging ver 0.5b
;Incoming SYSEX Tryout.
#WinMIDIrequester=1
Enumeration GADGETS
#txtOutputDevices=1
#txtInputDevices
#lgtOutputDevices
#lgtInputDevices
#btnOK
#btnCancel
#frgFrame
#txtVersion
#txttech
#txtMaxVoice
#txtPoly
EndEnumeration
Structure MIDI
MIDIIn.A
MIDIOut.A
Stat.A
Dat1.A
Dat2.A
EndStructure
Global MidiHeader.MIDIHDR
Global hMiP0.l = 0
Global *SysexBuffer = AllocateMemory(4096)
Global _MIDI.MIDI
Global Dim arrSysexMessage.a(9)
Procedure MIDIRequester(*OutDevice, *InDevice)
Define MaxOutDev, MaxInDev, InfoOut.MIDIOUTCAPS,InfoIn.MIDIINCAPS, a, OutDev, InDev, Quit, OK, TmpS.s, EventID
#MOD_WAVETABLE = 6
#MOD_SWSYNTH = 7
#MIDIRequ_InSet = 2
#MIDIRequ_OutSet = 1
#Width = 400
If OpenWindow(#WinMIDIrequester, 0, 0, #Width, 270, "MIDI-Requester Sel MIDI-modem etc slot that you want to use.", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
#Column = (#Width - 20) / 2
#Offset = (#Width / 2) + 5
TextGadget(#txtOutputDevices, 5, 5, #Column, 18, "Output-Device:", #PB_Text_Center | #PB_Text_Border)
ListViewGadget(#lgtOutputDevices, 5, 23, #Column, 100)
MaxOutDev = midiOutGetNumDevs_()
InfoOut.MIDIOUTCAPS
If MaxOutDev
For a = -1 To MaxOutDev - 1
midiOutGetDevCaps_(a, InfoOut, SizeOf(MIDIOUTCAPS))
AddGadgetItem(#lgtOutputDevices, -1, PeekS(@InfoOut\szPname[0], 32))
Next
Else
AddGadgetItem(#lgtOutputDevices, -1, "(no output device)")
DisableGadget(#lgtInputDevices, 1)
EndIf
; MessageRequester("","1")
TextGadget(#txtInputDevices, #Offset, 5, #Column, 18, "Input-Device:", #PB_Text_Center | #PB_Text_Border)
ListViewGadget(#lgtInputDevices, #Offset, 23, #Column, 100)
MaxInDev = midiInGetNumDevs_()
InfoIn.MIDIINCAPS
If MaxInDev
For a = 0 To MaxInDev - 1
midiInGetDevCaps_(a, InfoIn, SizeOf(MIDIINCAPS))
AddGadgetItem(#lgtInputDevices, -1, PeekS(@InfoIn\szPname[0], 32))
Next
Else
AddGadgetItem(#lgtInputDevices, -1, "(no input device)")
DisableGadget(#lgtInputDevices, 1)
EndIf
; MessageRequester("","2")
ButtonGadget(#btnOK, 5, 240, #Column, 24, "&OK")
ButtonGadget(#btnCancel, #Offset, 240, #Column, 24, "&Cancel")
FrameGadget(#frgFrame, 5, 130, #Width - 10, 100, "Info of Output-Device", 0)
TextGadget(#txtVersion, 10, 145, #Width - 20, 18, "Version:")
TextGadget(#txtTech, 10, 165, #Width - 20, 18, "Technology:")
TextGadget(#txtMaxVoice, 10, 185, #Width - 20, 18, "Max. Voices:")
TextGadget(#txtPoly, 10, 205, #Width - 20, 18, "Polyphonie:")
OutDev = 0
InDev = 0
Quit = #False
OK = #False
; MessageRequester("","TEST")
; ======================================================================
Repeat
If GetGadgetState(#lgtOutputDevices) > -1 Or GetGadgetState(#lgtInputDevices) > -1
DisableGadget(#btnOK, 0)
Else
DisableGadget(#btnOK, 1)
EndIf
If InDev <> GetGadgetState(#lgtInputDevices)
InDev = GetGadgetState(#lgtInputDevices)
EndIf
If GetGadgetState(#lgtOutputDevices) <> OutDev
OutDev = GetGadgetState(#lgtOutputDevices)
midiOutGetDevCaps_(OutDev - 1, InfoOut, SizeOf(MIDIOUTCAPS))
SetGadgetText(#txtVersion, "Version: " + Str(InfoOut\vDriverVersion >> 8) + "." + Str(InfoOut\vDriverVersion & $FF))
Select InfoOut\wTechnology
Case #MOD_MIDIPORT : TmpS.s = "Hardware Port"
Case #MOD_SYNTH : TmpS.s = "Synthesizer"
Case #MOD_SQSYNTH : TmpS.s = "Square Wave Synthesizer"
Case #MOD_FMSYNTH : TmpS.s = "FM Synthesizer"
Case #MOD_MAPPER : TmpS.s = "Microsoft MIDI Mapper"
Case #MOD_WAVETABLE : TmpS.s = "Hardware Wavetable Synthesizer"
Case #MOD_SWSYNTH : TmpS.s = "Software Synthesizer"
Default: TmpS.s = "(Error Code " + Str(InfoOut\wTechnology) + ")"
EndSelect
SetGadgetText(#txtTech, "Technology: " + TmpS)
If InfoOut\wVoices = 0 : TmpS.s = "inf" : Else : TmpS.s = Str(InfoOut\wVoices) : EndIf
SetGadgetText(#txtMaxVoice, "Max. Voices: " + TmpS)
If InfoOut\wNotes = 0 : TmpS.s = "inf" : Else : TmpS.s = Str(InfoOut\wNotes) : EndIf
SetGadgetText(#txtPoly, "Polyphonie: " + TmpS)
EndIf
EventID = WaitWindowEvent()
Select EventID
Case #PB_Event_CloseWindow
Quit = #True
OK = #False
Case #PB_Event_Gadget
Select EventGadget()
Case #btnOK
PokeL(*OutDevice, OutDev - 1) ; Trick to return two results (OutDev & InDev)
PokeL(*InDevice, InDev)
Quit = #True
OK = 3
If (OutDev = -1 Or CountGadgetItems(#lgtOutputDevices) = 0) And OK & #MIDIRequ_OutSet
OK ! #MIDIRequ_OutSet : EndIf
If (InDev = -1 Or CountGadgetItems(#lgtInputDevices) = 0) And OK & #MIDIRequ_InSet
OK ! #MIDIRequ_InSet : EndIf
Case #btnCancel
Quit = #True
OK = #False
EndSelect
EndSelect
Until Quit
;==================================================================================
; CloseWindow(#WinMIDIrequester)
ProcedureReturn OK
Else
End
EndIf
EndProcedure
Procedure MIDIInProc(hMIDIIn, WMsg, DuMMy, D1, D2) ;ONLY CALLED ON STARTUP BY ME BUT THE SYNTH CALLS IT ALL THE TIME! It is the callback function for handling incoming MIDI messages.
Define i
If FetchFlag
Debug Hex(D2);Str(D1)
EndIf
With _MIDI
Select WMsg ; process some MIDI in events.
Case #MM_MIM_DATA;The MIM_DATA message is sent to a MIDI input callback function when a MIDI message is received by a MIDI input device.
If D1 & $FF =144
\Stat=(D1 >> 8) & $FF ;Note pitch value.
\Dat1=(D1 >> 16) & $FF ;Velocity value.
If \Dat1
SetWindowTitle(0,"Note On")
Debug "MIDIInProc NOTE ON " + Str(D1) + "; " + Str(\Stat) + "; Velocity: " + Str(\Dat1)
Else
SetWindowTitle(0,"Note Off")
EndIf
ElseIf D1 & $FF = $F0 ; Trying to recieve a SYSEX dump from my synth. The app MIDI-OX can recieve my dumps so my system is working.
Debug "Start of SYSEX!"
If (D1 >> 8) & $FF = $42
Debug "KORG-ID"
EndIf
EndIf
Case #MIM_LONGDATA ; Trying to recieve a SYSEX dump from my synth. The app MIDI-OX can recieve my dumps so my system is working.
Debug "---------- NEW INCOMING SYSEX -----------"
For i = 0 To MidiHeader\dwBytesRecorded - 1 ; Read Buffer Sent from LPData
Debug Hex(PeekB(MidiHeader\lpData + i) & $FF)
Next
; MHI\lpData = @arrSysexMessage() ; MIDI Header pointer to MIDI data.
Debug "Byte count: " + MidiHeader\dwBytesRecorded
If MidiHeader\dwBytesRecorded
midiInAddBuffer_(hMIDIIn, @MidiHeader, SizeOf(MidiHeader)) ; Recycle Sysex Buffer
Endif
EndSelect
EndWith
EndProcedure
Procedure MIDIinit(OutDev, InDev, *MIDIInProc=-1,Instrument=0) ;ONLY CALLED ON STARTUP! MIDIinproc default solo show Note on, Note off
Define iMidiInterface.i, i.l,sText.s
MIDIHeader\dwFlags = 0
MidiHeader\dwBufferLength = 16384
MidiHeader\lpData = *SysexBuffer
If *MIDIinproc=-1:*MIDIinproc=@MIDIinproc():EndIf
; The MidiInProc function is the callback function for handling incoming MIDI messages. MidiInProc is a placeholder for the application-supplied function name.
; The address of this function can be specified in the callback-address parameter of the midiInOpen function.
If midiInOpen_(@_hMIDIIn, InDev, *MIDIInProc, 0, #CALLBACK_FUNCTION) = #MMSYSERR_NOERROR
midiInPrepareHeader_(_hMIDIIn, @MidiHeader, SizeOf(MidiHeader))
midiInAddBuffer_(_hMIDIIn, @MidiHeader, SizeOf(MidiHeader))
If midiInStart_(_hMIDIIn) <> #MMSYSERR_NOERROR : MessageRequester("Error","Can't start MIDI IN",0) :End: EndIf
EndIf
; The midiInStart function starts MIDI input on the specified MIDI input device. hMidiIn is the handle to the MIDI input device. This function resets the time stamp to zero;
; time stamp values For subsequently received messages are relative to the time that this function was called. Calling this function when input is already started has no effect,
; and the function returns zero.
midiOutOpen_(@_hMIDIout, OutDev, 0, 0, 0);Öppnar midi-interface. LPHMIDIOUT=lphmo=pointer to an HMIDIOUT handle.
; This location is filled with a handle identifying the opened MIDI output device.
; The handle is used To identify the device in calls To other MIDI output functions. OutDev=uDeviceID=Identifier of the MIDI output device that is to be opened.
; 3rd placeholder = dwCallback and 0 means no callback is desired. 4th placeholder is dwCallbackInstance. Last placeholder is dwFlags=callbackflag.
midiOutShortMsg_(_hMIDIout, 192 | Instrument<<8 ) ; Sends a short MIDI message (here a Patch Change) to the specified MIDI output device. HMIDIOUT=hmo=Handle to the MIDI output device.
; This parameter can also be the handle of a MIDI stream cast To HMIDIOUT.
; The 2nd placeholder is dwMsg=similar to #MM_MIM_DATA above.
If _hMIDIIn And _hMIDIout
If midiConnect_(_hMIDIIn, _hMIDIout, 0);The midiConnect function connects a MIDI input device to a MIDI thru or output device,
; or connects a MIDI thru device To a MIDI output device.
; First inpDeviceHandle, then outpDevHandle, 3rd placeholder must be zero.
MessageRequester("Error","Can't connect MIDI",0) :End
EndIf
EndIf
EndProcedure
MIDIResult = MIDIRequester(@OutDevice, @InDevice)
If MIDIResult & #MIDIRequ_OutSet : Debug "Output device: " + Str(OutDevice) : EndIf
If MIDIResult & #MIDIRequ_InSet : Debug "Input device: " + Str(InDevice) : EndIf
MIDIinit(OutDevice,InDevice);*** Is called only once! ****
OpenWindow(0, 10, 10, 300, 200, "MIDI Test")
Repeat
Event = WaitWindowEvent()
Until Event = #PB_Event_CloseWindow
Re: KORG X5D via MIDI (was: Where to hire a programmer)
Hi there, I was wondering, did you have a chance to try out the updated code? I’m curious to know if it provides more Sysex data.