,
released to the public domain. } { A First-In First-Out circular buffer.
Port of circbuf.c from Microsoft's Windows MIDI monitor example.
I did do a version of this as an object (see Rev 1.1) but it was getting too
complicated and I couldn't see any real benefits to it so I dumped it
for an ordinary memory buffer with pointers.
This unit is a bit C-like, everything is done with pointers and extensive
use is made of the undocumented feature of the Inc() function that
increments pointers by the size of the object pointed to.
All of this could probably be done using Pascal array notation with
range-checking turned off, but I'm not sure it's worth it.
CircbufAlloc -
CircbufFree - Start off the get and put pointers in the same position.
CircbufReadEvent - Reads first event in queue without removing it.
CircbufRemoveEvent - Remove current event from the queue
GlobalSharedLockedAlloc - Allocates in global shared memory, returns pointer and handle
GlobalSharedLockedFree - Allocate the buffer memory
PCircularBuffer
PMidiBufferItem
TCircularBuffer
TMidiBufferItem
function CircbufAlloc( Capacity: Word ): PCircularBuffer;
procedure CircbufFree( PBuffer: PCircularBuffer );
Start off the get and put pointers in the same position. These
will get out of sync as the interrupts start rolling in
function CircbufReadEvent( PBuffer: PCircularBuffer; PEvent: PMidiBufferItem ): Boolean;
Reads first event in queue without removing it.
Returns true if successful, False if no events in queue
function CircbufRemoveEvent( PBuffer: PCircularBuffer ): Boolean;
Remove current event from the queue
function GlobalSharedLockedAlloc( Capacity: Word; var hMem: HGLOBAL ): Pointer;
Allocates in global shared memory, returns pointer and handle
procedure GlobalSharedLockedFree( hMem: HGLOBAL; ptr: Pointer );
Allocate the buffer memory
PCircularBuffer = ^TCircularBuffer
Number of events in buffer
PMidiBufferItem = ^TMidiBufferItem
Pointer to sysex MIDIHDR, nil if not sysex
TCircularBuffer = record
RecordHandle : HGLOBAL;
BufferHandle : HGLOBAL;
pStart : PMidiBufferItem;
pEnd : PMidiBufferItem;
pNextPut : PMidiBufferItem;
pNextGet : PMidiBufferItem;
Error : Word;
Capacity : Word;
EventCount : Word;
end;
MIDI input buffer
TMidiBufferItem = record
timestamp : DWORD;
data : DWORD;
sysex : PMidiHdr;
end;
MIDI input event