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