MIDI test

Miscellaneous Forums/Win32 Discussion/MIDI test

The forum is locked. These are the original blitzbasic.com forums, kept so they can still be read. No new topics, replies or edits can be made here. To join in, head over to the Blitz3D+ forums.

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

;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