MIDI. How to get midiInUnprepareHeader work correctly ?
Posted: Thu Feb 05, 2015 12:49 pm
Hi,
This code is used to recieve sysex-dumps from MIDI-instruments.
Point is that the code in this topic http://www.purebasic.fr/english/viewtop ... 13&t=47391 works fine but only ONCE
Of coarse that is not the intention. I must be able to select/deselect different inputs or at least reselect the same one (if there is only one) after a close input command, and do again a sysex-dumps recieve.
Welll that is not working.
I tried lot's of things and have no clue. To me the problem is in the API-function midiInUnprepareHeader (or midiInAddBuffer).
The source now may look a bit dirty as left all test source inside (to make it less works for others to research the fault, hopefully).
The last setup here is now almost 100% identical to my old G32 (GFA Basic) source code which works very fine, even today on my old XP32 system.
Can anyone check and find out where it goes wrong or would it be a bad PB implementation of midiInUnprepareHeader or midiInAddBuffer ?
I hope not. I really need this, so thanks to all who tries or better find the sollution.
(P.s. I'm a self made 'programmer', maybe you can see that, sorry then...)
This code is used to recieve sysex-dumps from MIDI-instruments.
Point is that the code in this topic http://www.purebasic.fr/english/viewtop ... 13&t=47391 works fine but only ONCE
Of coarse that is not the intention. I must be able to select/deselect different inputs or at least reselect the same one (if there is only one) after a close input command, and do again a sysex-dumps recieve.
Welll that is not working.
I tried lot's of things and have no clue. To me the problem is in the API-function midiInUnprepareHeader (or midiInAddBuffer).
The source now may look a bit dirty as left all test source inside (to make it less works for others to research the fault, hopefully).
The last setup here is now almost 100% identical to my old G32 (GFA Basic) source code which works very fine, even today on my old XP32 system.
Can anyone check and find out where it goes wrong or would it be a bad PB implementation of midiInUnprepareHeader or midiInAddBuffer ?
I hope not. I really need this, so thanks to all who tries or better find the sollution.
(P.s. I'm a self made 'programmer', maybe you can see that, sorry then...)
Code: Select all
; Incoming MIDI Sysex Handler
Global NewList Hsmf_SX.s()
Global MHI.MIDIHDR
Global hMiP0.i = 0
Global s.s
Global *SysexBuffer = AllocateMemory(1024)
MHI\lpData = *SysexBuffer
MHI\dwBufferLength = 1024
Procedure Midi_In_Err(err_idx.i)
Protected ls.s=Space(#MAXERRORLENGTH * 2)
Select err_idx
Case #MMSYSERR_NOERROR : ProcedureReturn #True ;MMSYSERR_NOERROR
Default : midiInGetErrorText_(err_idx, ls, Len(ls))
MessageRequester("MIDI INPUT ERROR",PeekS(@ls),#MB_ICONEXCLAMATION)
ProcedureReturn #False
EndSelect
EndProcedure
Procedure.i MIDI_GetInputDevices(hnd.i)
Protected mic.MIDIINCAPS, Num.i, i.i
Num = midiInGetNumDevs_()
For i = 0 To Num - 1
If #MMSYSERR_NOERROR=midiInGetDevCaps_(i, @mic, SizeOf(MIDIINCAPS))
AddGadgetItem(hnd, -1, PeekS(@mic\szPname))
EndIf
Next i
ProcedureReturn Num
EndProcedure
Procedure MIDICallBack0(hMi.i, wMsg.i, dummy.i , Data1.i, Data2.i)
Protected ls.s
Select wMsg
;Case #MIM_DATA : Debug Data1
Case #MIM_OPEN : Debug "MIDI Input Opened"
Case #MIM_CLOSE : Debug "MIDI Input Closed"
Case #MIM_LONGDATA
For i = 0 To MHI\dwBytesRecorded - 1 ; Read Buffer Sent from LPData
ls = ls + RSet(Hex(PeekB(MHI\lpData + i),#PB_Byte),2,"0")+ " "
If (i % 17)=0
Debug ls
ls=""
EndIf
Next
Debug ls
;**************************************
Debug "*******"
Debug MHI\dwBytesRecorded
midiInAddBuffer_(hMiP0, @MHI, SizeOf(MIDIHDR)) ; Recycle Sysex Buffer
EndSelect
EndProcedure
Procedure oStartsysex(idx.i) ;original setup like used in the link above
midiInOpen_(@hMiP0,idx, @MIDICallBack0(), 0, #CALLBACK_FUNCTION)
Debug "midiInOpened"
Debug hMiP0
;If hMiP0
midiInPrepareHeader_(hMiP0, @MHI, SizeOf(MIDIHDR))
midiInAddBuffer_(hMiP0, @MHI, SizeOf(MIDIHDR))
midiInStart_(hMiP0)
;EndIf
EndProcedure
Procedure Startsysex(idx.i)
;this setup is almost identical to my old G32 (GFA Basic) source code which works very fine
midiInOpen_(@hMiP0,idx, @MIDICallBack0(), 0, #CALLBACK_FUNCTION)
Debug "midiInOpened" ;should be debugged in the callback too
Debug hMiP0
If hMiP0
If midiInStart_(hMiP0)=#MMSYSERR_NOERROR
; MHI\lpData = *SysexBuffer
; MHI\dwBufferLength = 1024
midiInPrepareHeader_(hMiP0, @MHI, SizeOf(MIDIHDR))
midiInAddBuffer_(hMiP0, @MHI, SizeOf(MIDIHDR))
Debug "midiInStart done"
Debug MemorySize(MHI\lpData)
; Else
; Debug "FreeMemory"
; FreeMemory(MHI\lpData)
; MHI\lpData = 0
; MHI\dwBufferLength = 0
EndIf
EndIf
EndProcedure
Procedure oStopsysex()
midiInStop_(hMiP0)
;midiInUnprepareHeader_(hMiP0, @MHI, SizeOf(MIDIHDR))
If midiInUnprepareHeader_(hMiP0,@MHI,SizeOf(MIDIHDR))=#MMSYSERR_NOERROR
Debug "midiInUnprepareHeader MMSYSERR_NOERROR"
EndIf
midiInClose_(hMiP0)
hMiP0=0
EndProcedure
Procedure ooStopsysex(hnd.i)
midiInStop_(hnd)
Debug "midiInStop"
Debug hMiP0
;midiInUnprepareHeader_(hnd, @MHI, SizeOf(MIDIHDR))
err=midiInUnprepareHeader_(hnd,@MHI,SizeOf(MIDIHDR))
If err=#MMSYSERR_NOERROR
Debug "midiInUnprepareHeader MMSYSERR_NOERROR"
Else
Midi_In_Err(err)
EndIf
midiInClose_(hnd)
EndProcedure
Procedure Stopsysex(hnd.i)
;midiInUnprepareHeader_(hnd, @MHI, SizeOf(MIDIHDR))
err=midiInUnprepareHeader_(hnd,@MHI,SizeOf(MIDIHDR))
If err=#MMSYSERR_NOERROR
Debug "midiInUnprepareHeader MMSYSERR_NOERROR"
Else
Midi_In_Err(err)
EndIf
midiInStop_(hnd)
Debug "midiInStop"
Debug hMiP0
midiInReset_(hnd)
Debug "midiInReset"
midiInClose_(hnd) ;should be debugged in the callback too
EndProcedure
OpenWindow(0, 10, 10, 300, 200, "MIDI Test")
lvw_M_In = ListViewGadget(#PB_Any, 5, 30, 200, 150)
btn_close = ButtonGadget(#PB_Any, 220, 100, 60, 20, "No Out")
MIDI_GetInputDevices(lvw_M_In)
Repeat
Event = WaitWindowEvent()
Select Event
Case #PB_Event_Gadget
Select EventGadget()
Case lvw_M_In :
Select EventType():
Case #PB_EventType_LeftClick :
If hMiP0
Stopsysex(hMiP0)
hMiP0=0
EndIf
Startsysex(GetGadgetState(lvw_M_In))
EndSelect
Case btn_close : Stopsysex(hMiP0) : hMiP0=0
EndSelect
EndSelect
Until Event = #PB_Event_CloseWindow
If hMiP0
Stopsysex(hMiP0)
EndIf