5 Author: KOL translation and > 64 sysex buffering: Thaddy de Koning
6 Original Author: David Churcher
7 Copyright: released to the public domain
8 Remarks: Well known Great components.
9 Do not confuse this with my project JEDI midi translation for KOL
11 { $Header: /MidiComp/DELPHMCB.PAS 2 10/06/97 7:33 Davec $ }
13 {MIDI callback for Delphi, was DLL for Delphi 1}
19 uses Kol
, windows
, MMsystem
, KolCircbuf
, KolMidiDefs
, KolMidiCons
;
21 procedure midiHandler(
26 dwParam2
: DWORD
); stdcall ;//export;
27 function CircbufPutEvent(PBuffer
: PCircularBuffer
; PTheEvent
: PMidiBufferItem
): Boolean; stdcall; //export;
31 { Add an event to the circular input buffer. }
32 function CircbufPutEvent(PBuffer
: PCircularBuffer
; PTheEvent
: PMidiBufferItem
): Boolean;
34 If (PBuffer
^.EventCount
< PBuffer
^.Capacity
) Then
36 Inc(Pbuffer
^.EventCount
);
38 { Todo: better way of copying this record }
39 with PBuffer
^.PNextput
^ do
41 Timestamp
:= PTheEvent
^.Timestamp
;
42 Data
:= PTheEvent
^.Data
;
43 Sysex
:= PTheEvent
^.Sysex
;
46 { Move to next put location, with wrap }
47 Inc(Pbuffer
^.PNextPut
);
48 If (PBuffer
^.PNextPut
= PBuffer
^.PEnd
) then
49 PBuffer
^.PNextPut
:= PBuffer
^.PStart
;
51 CircbufPutEvent
:= True;
54 CircbufPutEvent
:= False;
57 { This is the callback function specified when the MIDI device was opened
58 by midiInOpen. It's called at interrupt time when MIDI input is seen
59 by the MIDI device driver(s). See the docs for midiInOpen for restrictions
60 on the Windows functions that can be called in this interrupt. }
61 procedure midiHandler(
69 thisEvent
: TMidiBufferItem
;
70 thisCtlInfo
: PMidiCtlInfo
;
71 thisBuffer
: PCircularBuffer
;
78 mim_Error
: {TODO: handle (message to trigger exception?) };
80 mim_Data
, mim_Longdata
, mim_Longerror
:
81 { Note: mim_Longerror included because there's a bug in the Maui
82 input driver that sends MIM_LONGERROR for subsequent buffers when
83 the input buffer is smaller than the sysex block being received }
86 { TODO: Make filtered messages customisable, I'm sure someone wants to
87 do something with MTC! }
88 if (dwParam1
<> MIDI_ACTIVESENSING
) and
89 (dwParam1
<> MIDI_TIMINGCLOCK
) then
92 { The device driver passes us the instance data pointer we
93 specified for midiInOpen. Use this to get the buffer address
94 and window handle for the MIDI control }
95 thisCtlInfo
:= PMidiCtlInfo(dwInstance
);
96 thisBuffer
:= thisCtlInfo
^.PBuffer
;
98 { Screen out short messages if we've been asked to }
99 if ((wMsg
<> mim_Data
) or (thisCtlInfo
^.SysexOnly
= False))
100 and (thisCtlInfo
<> Nil) and (thisBuffer
<> Nil) then
104 timestamp
:= dwParam2
;
105 if (wMsg
= mim_Longdata
) or
106 (wMsg
= mim_Longerror
) then
109 sysex
:= PMidiHdr(dwParam1
);
117 if CircbufPutEvent( thisBuffer
, @thisEvent
) then
118 { Send a message to the control to say input's arrived }
119 PostMessage(thisCtlInfo
^.hWindow
, mim_Data
, 0, 0)
122 PostMessage(thisCtlInfo
^.hWindow
, mim_Overflow
, 0, 0);
127 mom_Done
: { Sysex output complete, dwParam1 is pointer to MIDIHDR }
129 { Notify the control that its sysex output is finished.
130 The control should call midiOutUnprepareHeader before freeing the buffer }
131 PostMessage(PMidiCtlInfo(dwInstance
)^.hWindow
, mom_Done
, 0, dwParam1
);