The Extern param does work with 'Winmm'. I can not recall why i put 'Os'!
That site you mentioned is a great source for MIDI info. Infact I based my code from the code examples.
The MidiInOpen is what sets up the callback.
Then;
Prepare the MIDI Header with MidiInPrepareHeader,
Setup buffer with midiInAddBuffer,
finally the midiInStart starts the capturing (using the callback function).
So it is needed!!
In regards to Midi Monitors, it looks like only one callback at a time can capture MIDI info. If another MIDI prog is running like cubase, then it will want to be capturing the data itself using a callback. So MIDI Monitors are not so simple.
I have been checking out how to use the midiConnect function. It may help in some kind of work around.
This is what the PSDK help says about it;
"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."
Here is the purebasic code for my MidiIn.Dll
That site you mentioned is a great source for MIDI info. Infact I based my code from the code examples.
The MidiInOpen is what sets up the callback.
Then;
Prepare the MIDI Header with MidiInPrepareHeader,
Setup buffer with midiInAddBuffer,
finally the midiInStart starts the capturing (using the callback function).
So it is needed!!
In regards to Midi Monitors, it looks like only one callback at a time can capture MIDI info. If another MIDI prog is running like cubase, then it will want to be capturing the data itself using a callback. So MIDI Monitors are not so simple.
I have been checking out how to use the midiConnect function. It may help in some kind of work around.
This is what the PSDK help says about it;
"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."
Here is the purebasic code for my MidiIn.Dll
;Midi In Dll ;Ziltch 2005 Global err #CALLBACK_TYPEMASK.l = $00070000 ; callback type mask ; #CALLBACK_NULL.l = $00000000 ; no callback ; #CALLBACK_WINDOW.l = $00010000 ; dwCallback is a HWND ; #CALLBACK_TASK.l = $00020000 ; dwCallback is a HTASK ; #CALLBACK_FUNCTION.l = $00030000 ; dwCallback is a FARPROC ; ;Global OutStr.s ;Global OutStr2.s #MM_MIM_OPEN = $3C1 #MM_MIM_CLOSE = $3C2 #MM_MIM_DATA = $3C3 #MM_MIM_LONGDATA = $3C4 #MM_MIM_ERROR = $3C5 #MM_MIM_LONGERROR = $3C6 Global MidiBankAddr,SysXFlag Global midiHeader.midiHdr Global MidiINhandle Global BufferSize BufferSize = 1024 Dim SysXBuffer.b(BufferSize) Structure MidiMess ; OutStr.s Midifunct.w MidiNote.w MidiVel.w MidiTimeStamp.l EndStructure Global MidiMessCount.l, MaxMidiMess.l Global MaxMidiMess MaxMidiMess = 64;256 DefType.midimess MidiMessBuff Dim MidiMessBuff.MidiMess(MaxMidiMess) Procedure MidiCallBack(hmIN.l, wMsg.l, dwInstance.l, dwParam1.l, dwParam2.l) ; if dwParam1 & $000000FF < 254 MidiTimeStamp.l = dwParam2 Select wMsg Case #MM_MIM_OPEN OutStr.s = "Open Midi" Case #MM_MIM_CLOSE OutStr.s = "Close Midi" Case #MM_MIM_DATA ;OutStr.s = hex(dwParam1 & $000000FF)+" " + hex( (dwParam1>>8) & $000000FF)+" " + hex( (dwParam1>>16) & $000000FF) ;OutStr2.s = str(dwParam2) If dwParam1 & $000000FF >253 ProcedureReturn EndIf MidiMessCount + 1 MidiMessBuff(MidiMessCount)\Midifunct = dwParam1 & $000000FF MidiMessBuff(MidiMessCount)\MidiNote = (dwParam1>>8) & $000000FF MidiMessBuff(MidiMessCount)\MidiVel = (dwParam1>>16) & $000000FF MidiMessBuff(MidiMessCount)\ MidiTimeStamp= dwParam2 ; MessageRequester("MIDI data", str(MidiMessBuff(MidiMessCount)\Midifunct)) Case #MM_MIM_LONGDATA Case #MM_MIM_ERROR MessageRequester("","MIDI error",0) OutStr.s = "Midi Error" Case #MM_MIM_LONGERROR MessageRequester("","long MIDI error",0) OutStr.s = "Long Midi Error" EndSelect ; endif EndProcedure ProcedureDLL StartLookingMidiIn(MPU401IN) ;Open_Window_Main() midiError = midiInOpen_(@MidiIN, MPU401IN,@MidiCallBack(), 0, #CALLBACK_FUNCTION) MidiINhandle = MidiIN ;debug(MidiIN) ; Store pointer to our input buffer for System Exclusive messages in MIDIHDR midiHeader\lpData =@SysXBuffer.b(0); (LPBYTE)&SysXBuffer[0] ; debug("midiHeader\lpData "+str(midiHeader\lpData )) ; Store its size in the MIDIHDR midiHeader\dwBufferLength = BufferSize;256;SizeOf(SysXBuffer); ; Flags must be set to 0 midiHeader\dwFlags = 0 ; Prepare the buffer and MIDIHDR err = midiInPrepareHeader_(MidiIN, @midiHeader.midiHdr, sizeof(midiHeader)) ;debug(str(err)); If (err=0) ; Queue MIDI input buffer err = midiInAddBuffer_(MidiIN, @midiHeader, sizeof(midiHeader)) ; debug( midiHeader\lpData) If (err=0) ; Start recording Midi err = midiInStart_(MidiIN) EndIf EndIf ; If there was an error above, then print a message ;if (err) ; debug ("error "+str(err)) ;MessageRequester("","MIDI error",0) ;endif ProcedureReturn err EndProcedure ProcedureDLL StopLookingMidiIn() midiInReset_(MidiINhandle) midiInUnprepareHeader_(MidiINhandle, @midiHeader, sizeof(midiHeader)) ; Unprepare the buffer and MIDIHDR. Unpreparing a buffer that has not been prepared is ok midiInClose_(MidiINhandle) EndProcedure ProcedureDLL SetMaxMidiMessages(MaxMidiMsg) MaxMidiMess =MaxMidiMsg EndProcedure ProcedureDLL.l GetMaxMidiMessages() ProcedureReturn MaxMidiMess EndProcedure ProcedureDLL.l LookMidiIn(*MidiBank) If MidiMessCount > MaxMidiMess MessageRequester ("MIDI ERROR", "Recieved "+str(MidiMessCount) +" messages . " + str(MaxMidiMess) +" is max allowed!") MidiMessCount = MaxMidiMess EndIf PokeW(*MidiBank,MidiMessCount) For count = 0 To MidiMessCount-1 PokeW(*MidiBank+(count*12)+2,MidiMessBuff(Count+1)\Midifunct) PokeW(*MidiBank+(count*12)+4,MidiMessBuff(Count+1)\MidiNote) PokeW(*MidiBank+(count*12)+6,MidiMessBuff(Count+1)\MidiVel) PokeL(*MidiBank+(count*12)+8,MidiMessBuff(Count+1)\MidiTimeStamp) MidiMessBuff(Count+1)\Midifunct= 0 MidiMessBuff(Count+1)\MidiNote= 0 MidiMessBuff(Count+1)\MidiVel = 0 MidiMessBuff(Count+1)\MidiTimeStamp = 0 Next MidiMessC.l = MidiMessCount MidiMessCount = 0 ProcedureReturn MidiMessC EndProcedure