diff options
Diffstat (limited to 'src/lib/midi')
-rw-r--r-- | src/lib/midi/CIRCBUF.PAS | 183 | ||||
-rw-r--r-- | src/lib/midi/DELPHMCB.PAS | 140 | ||||
-rw-r--r-- | src/lib/midi/MIDIDEFS.PAS | 55 | ||||
-rw-r--r-- | src/lib/midi/MIDITYPE.PAS | 90 | ||||
-rw-r--r-- | src/lib/midi/demo/MidiTest.dfm | bin | 1872 -> 0 bytes | |||
-rw-r--r-- | src/lib/midi/demo/Project1.dpr | 13 | ||||
-rw-r--r-- | src/lib/midi/demo/Project1.res | bin | 876 -> 0 bytes | |||
-rw-r--r-- | src/lib/midi/midiComp.cfg | 35 | ||||
-rw-r--r-- | src/lib/midi/midiComp.dpk | 45 | ||||
-rw-r--r-- | src/lib/midi/midiComp.res | bin | 876 -> 0 bytes | |||
-rw-r--r-- | src/lib/midi/readme.txt | 60 |
11 files changed, 0 insertions, 621 deletions
diff --git a/src/lib/midi/CIRCBUF.PAS b/src/lib/midi/CIRCBUF.PAS deleted file mode 100644 index 3ceb4c6e..00000000 --- a/src/lib/midi/CIRCBUF.PAS +++ /dev/null @@ -1,183 +0,0 @@ -{ $Header: /MidiComp/CIRCBUF.PAS 2 10/06/97 7:33 Davec $ } - -{ Written by David Churcher <dchurcher@cix.compulink.co.uk>, - 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. -} - -Unit Circbuf; - -interface - -{$IFDEF FPC} - {$MODE Delphi} - {$H+} // use long strings -{$ENDIF} - -Uses - Windows, - MMSystem; - -type - { MIDI input event } - TMidiBufferItem = record - timestamp: DWORD; { Timestamp in milliseconds after midiInStart } - data: DWORD; { MIDI message received } - sysex: PMidiHdr; { Pointer to sysex MIDIHDR, nil if not sysex } - end; - PMidiBufferItem = ^TMidiBufferItem; - - { MIDI input buffer } - TCircularBuffer = record - RecordHandle: HGLOBAL; { Windows memory handle for this record } - BufferHandle: HGLOBAL; { Windows memory handle for the buffer } - pStart: PMidiBufferItem; { ptr to start of buffer } - pEnd: PMidiBufferItem; { ptr to end of buffer } - pNextPut: PMidiBufferItem; { next location to fill } - pNextGet: PMidiBufferItem; { next location to empty } - Error: Word; { error code from MMSYSTEM functions } - Capacity: Word; { buffer size (in TMidiBufferItems) } - EventCount: Word; { Number of events in buffer } - end; - - PCircularBuffer = ^TCircularBuffer; - -function GlobalSharedLockedAlloc( Capacity: Word; var hMem: HGLOBAL ): Pointer; -procedure GlobalSharedLockedFree( hMem: HGLOBAL; ptr: Pointer ); - -function CircbufAlloc( Capacity: Word ): PCircularBuffer; -procedure CircbufFree( PBuffer: PCircularBuffer ); -function CircbufRemoveEvent( PBuffer: PCircularBuffer ): Boolean; -function CircbufReadEvent( PBuffer: PCircularBuffer; PEvent: PMidiBufferItem ): Boolean; -{ Note: The PutEvent function is in the DLL } - -implementation - -{ Allocates in global shared memory, returns pointer and handle } -function GlobalSharedLockedAlloc( Capacity: Word; var hMem: HGLOBAL ): Pointer; -var - ptr: Pointer; -begin - { Allocate the buffer memory } - hMem := GlobalAlloc(GMEM_SHARE Or GMEM_MOVEABLE Or GMEM_ZEROINIT, Capacity ); - - if (hMem = 0) then - ptr := Nil - else - begin - ptr := GlobalLock(hMem); - if (ptr = Nil) then - GlobalFree(hMem); - end; - - GlobalSharedLockedAlloc := Ptr; -end; - -procedure GlobalSharedLockedFree( hMem: HGLOBAL; ptr: Pointer ); -begin - if (hMem <> 0) then - begin - GlobalUnlock(hMem); - GlobalFree(hMem); - end; -end; - -function CircbufAlloc( Capacity: Word ): PCircularBuffer; -var - NewCircularBuffer: PCircularBuffer; - NewMIDIBuffer: PMidiBufferItem; - hMem: HGLOBAL; -begin - { TODO: Validate circbuf size, <64K } - NewCircularBuffer := - GlobalSharedLockedAlloc( Sizeof(TCircularBuffer), hMem ); - if (NewCircularBuffer <> Nil) then - begin - NewCircularBuffer^.RecordHandle := hMem; - NewMIDIBuffer := - GlobalSharedLockedAlloc( Capacity * Sizeof(TMidiBufferItem), hMem ); - if (NewMIDIBuffer = Nil) then - begin - { TODO: Exception here? } - GlobalSharedLockedFree( NewCircularBuffer^.RecordHandle, - NewCircularBuffer ); - NewCircularBuffer := Nil; - end - else - begin - NewCircularBuffer^.pStart := NewMidiBuffer; - { Point to item at end of buffer } - NewCircularBuffer^.pEnd := NewMidiBuffer; - Inc(NewCircularBuffer^.pEnd, Capacity); - { Start off the get and put pointers in the same position. These - will get out of sync as the interrupts start rolling in } - NewCircularBuffer^.pNextPut := NewMidiBuffer; - NewCircularBuffer^.pNextGet := NewMidiBuffer; - NewCircularBuffer^.Error := 0; - NewCircularBuffer^.Capacity := Capacity; - NewCircularBuffer^.EventCount := 0; - end; - end; - CircbufAlloc := NewCircularBuffer; -end; - -procedure CircbufFree( pBuffer: PCircularBuffer ); -begin - if (pBuffer <> Nil) then - begin - GlobalSharedLockedFree(pBuffer^.BufferHandle, pBuffer^.pStart); - GlobalSharedLockedFree(pBuffer^.RecordHandle, pBuffer); - end; -end; - -{ Reads first event in queue without removing it. - Returns true if successful, False if no events in queue } -function CircbufReadEvent( PBuffer: PCircularBuffer; PEvent: PMidiBufferItem ): Boolean; -var - PCurrentEvent: PMidiBufferItem; -begin - if (PBuffer^.EventCount <= 0) then - CircbufReadEvent := False - else - begin - PCurrentEvent := PBuffer^.PNextget; - - { Copy the object from the "tail" of the buffer to the caller's object } - PEvent^.Timestamp := PCurrentEvent^.Timestamp; - PEvent^.Data := PCurrentEvent^.Data; - PEvent^.Sysex := PCurrentEvent^.Sysex; - CircbufReadEvent := True; - end; -end; - -{ Remove current event from the queue } -function CircbufRemoveEvent(PBuffer: PCircularBuffer): Boolean; -begin - if (PBuffer^.EventCount > 0) then - begin - Dec( Pbuffer^.EventCount); - - { Advance the buffer pointer, with wrap } - Inc( Pbuffer^.PNextGet ); - If (PBuffer^.PNextGet = PBuffer^.PEnd) then - PBuffer^.PNextGet := PBuffer^.PStart; - - CircbufRemoveEvent := True; - end - else - CircbufRemoveEvent := False; -end; - -end. diff --git a/src/lib/midi/DELPHMCB.PAS b/src/lib/midi/DELPHMCB.PAS deleted file mode 100644 index ef0d5451..00000000 --- a/src/lib/midi/DELPHMCB.PAS +++ /dev/null @@ -1,140 +0,0 @@ -{ $Header: /MidiComp/DELPHMCB.PAS 2 10/06/97 7:33 Davec $ } - -{MIDI callback for Delphi, was DLL for Delphi 1} - -unit Delphmcb; - -{ These segment options required for the MIDI callback functions } -{$IFNDEF FPC} -{$C PRELOAD FIXED PERMANENT} -{$ENDIF} - -interface - -{$IFDEF FPC} - {$MODE Delphi} - {$H+} // use long strings -{$ENDIF} - -uses - Windows, - MMsystem, - Circbuf, - MidiDefs, - MidiCons; - -procedure midiHandler( - hMidiIn: HMidiIn; - wMsg: UINT; - dwInstance: DWORD; - dwParam1: DWORD; - dwParam2: DWORD); stdcall; export; -function CircbufPutEvent(PBuffer: PCircularBuffer; PTheEvent: PMidiBufferItem): Boolean; stdcall; export; - -implementation - -{ Add an event to the circular input buffer. } -function CircbufPutEvent(PBuffer: PCircularBuffer; PTheEvent: PMidiBufferItem): Boolean; stdcall; -begin - If (PBuffer^.EventCount < PBuffer^.Capacity) Then - begin - Inc(Pbuffer^.EventCount); - - { Todo: better way of copying this record } - with PBuffer^.PNextput^ do - begin - Timestamp := PTheEvent^.Timestamp; - Data := PTheEvent^.Data; - Sysex := PTheEvent^.Sysex; - end; - - { Move to next put location, with wrap } - Inc(Pbuffer^.PNextPut); - If (PBuffer^.PNextPut = PBuffer^.PEnd) then - PBuffer^.PNextPut := PBuffer^.PStart; - - CircbufPutEvent := True; - end - else - CircbufPutEvent := False; -end; - -{ This is the callback function specified when the MIDI device was opened - by midiInOpen. It's called at interrupt time when MIDI input is seen - by the MIDI device driver(s). See the docs for midiInOpen for restrictions - on the Windows functions that can be called in this interrupt. } -procedure midiHandler( - hMidiIn: HMidiIn; - wMsg: UINT; - dwInstance: DWORD; - dwParam1: DWORD; - dwParam2: DWORD); stdcall; -var - thisEvent: TMidiBufferItem; - thisCtlInfo: PMidiCtlInfo; - thisBuffer: PCircularBuffer; -Begin - case wMsg of - - mim_Open: {nothing}; - - mim_Error: {TODO: handle (message to trigger exception?) }; - - mim_Data, mim_Longdata, mim_Longerror: - { Note: mim_Longerror included because there's a bug in the Maui - input driver that sends MIM_LONGERROR for subsequent buffers when - the input buffer is smaller than the sysex block being received } - - begin - { TODO: Make filtered messages customisable, I'm sure someone wants to - do something with MTC! } - if (dwParam1 <> MIDI_ACTIVESENSING) and - (dwParam1 <> MIDI_TIMINGCLOCK) then - begin - - { The device driver passes us the instance data pointer we - specified for midiInOpen. Use this to get the buffer address - and window handle for the MIDI control } - thisCtlInfo := PMidiCtlInfo(dwInstance); - thisBuffer := thisCtlInfo^.PBuffer; - - { Screen out short messages if we've been asked to } - if ((wMsg <> mim_Data) or (thisCtlInfo^.SysexOnly = False)) - and (thisCtlInfo <> Nil) and (thisBuffer <> Nil) then - begin - with thisEvent do - begin - timestamp := dwParam2; - if (wMsg = mim_Longdata) or - (wMsg = mim_Longerror) then - begin - data := 0; - sysex := PMidiHdr(dwParam1); - end - else - begin - data := dwParam1; - sysex := Nil; - end; - end; - if CircbufPutEvent( thisBuffer, @thisEvent ) then - { Send a message to the control to say input's arrived } - PostMessage(thisCtlInfo^.hWindow, mim_Data, 0, 0) - else - { Buffer overflow } - PostMessage(thisCtlInfo^.hWindow, mim_Overflow, 0, 0); - end; - end; - end; - - mom_Done: { Sysex output complete, dwParam1 is pointer to MIDIHDR } - begin - { Notify the control that its sysex output is finished. - The control should call midiOutUnprepareHeader before freeing the buffer } - PostMessage(PMidiCtlInfo(dwInstance)^.hWindow, mom_Done, 0, dwParam1); - end; - - end; { Case } -end; - -end. diff --git a/src/lib/midi/MIDIDEFS.PAS b/src/lib/midi/MIDIDEFS.PAS deleted file mode 100644 index 4afe56ef..00000000 --- a/src/lib/midi/MIDIDEFS.PAS +++ /dev/null @@ -1,55 +0,0 @@ -{ $Header: /MidiComp/MIDIDEFS.PAS 2 10/06/97 7:33 Davec $ } - -{ Written by David Churcher <dchurcher@cix.compulink.co.uk>, - released to the public domain. } - - -{ Common definitions used by DELPHMID.DPR and the MIDI components. - This must be a separate unit to prevent large chunks of the VCL being - linked into the DLL. } -unit Mididefs; - -interface - -{$IFDEF FPC} - {$MODE Delphi} - {$H+} // use long strings -{$ENDIF} - -uses - Windows, - MMsystem, - Circbuf; - -type - - {-------------------------------------------------------------------} - { This is the information about the control that must be accessed by - the MIDI input callback function in the DLL at interrupt time } - PMidiCtlInfo = ^TMidiCtlInfo; - TMidiCtlInfo = record - hMem: THandle; { Memory handle for this record } - PBuffer: PCircularBuffer; { Pointer to the MIDI input data buffer } - hWindow: HWnd; { Control's window handle } - SysexOnly: Boolean; { Only process System Exclusive input } - end; - - { Information for the output timer callback function, also required at - interrupt time. } - PMidiOutTimerInfo = ^TMidiOutTimerInfo; - TMidiOutTimerInfo = record - hMem: THandle; { Memory handle for this record } - PBuffer: PCircularBuffer; { Pointer to MIDI output data buffer } - hWindow: HWnd; { Control's window handle } - TimeToNextEvent: DWORD; { Delay to next event after timer set } - MIDIHandle: HMidiOut; { MIDI handle to send output to - (copy of component's FMidiHandle property) } - PeriodMin: Word; { Multimedia timer minimum period supported } - PeriodMax: Word; { Multimedia timer maximum period supported } - TimerId: Word; { Multimedia timer ID of current event } - end; - -implementation - - -end. diff --git a/src/lib/midi/MIDITYPE.PAS b/src/lib/midi/MIDITYPE.PAS deleted file mode 100644 index 45b50820..00000000 --- a/src/lib/midi/MIDITYPE.PAS +++ /dev/null @@ -1,90 +0,0 @@ -{ $Header: /MidiComp/MIDITYPE.PAS 2 10/06/97 7:33 Davec $ } - -{ Written by David Churcher <dchurcher@cix.compulink.co.uk>, - released to the public domain. } - - -unit Miditype; - -interface - -{$IFDEF FPC} - {$MODE Delphi} - {$H+} // use long strings -{$ENDIF} - -uses - Classes, - Windows, - Messages, - MMSystem, - MidiDefs, - Circbuf; - -type - {-------------------------------------------------------------------} - { A MIDI input/output event } - TMyMidiEvent = class(TPersistent) - public - MidiMessage: Byte; { MIDI message status byte } - Data1: Byte; { MIDI message data 1 byte } - Data2: Byte; { MIDI message data 2 byte } - Time: DWORD; { Time in ms since midiInOpen } - SysexLength: Word; { Length of sysex data (0 if none) } - Sysex: PChar; { Pointer to sysex data buffer } - destructor Destroy; override; { Frees sysex data buffer if nec. } - end; - PMyMidiEvent = ^TMyMidiEvent; - - {-------------------------------------------------------------------} - { Encapsulates the MIDIHDR with its memory handle and sysex buffer } - PMyMidiHdr = ^TMyMidiHdr; - TMyMidiHdr = class(TObject) - public - hdrHandle: THandle; - hdrPointer: PMIDIHDR; - sysexHandle: THandle; - sysexPointer: Pointer; - constructor Create(BufferSize: Word); - destructor Destroy; override; - end; - -implementation - -{-------------------------------------------------------------------} -{ Free any sysex buffer associated with the event } -destructor TMyMidiEvent.Destroy; -begin - if (Sysex <> Nil) then - Freemem(Sysex, SysexLength); - - inherited Destroy; -end; - -{-------------------------------------------------------------------} -{ Allocate memory for the sysex header and buffer } -constructor TMyMidiHdr.Create(BufferSize:Word); -begin - inherited Create; - - if BufferSize > 0 then - begin - hdrPointer := GlobalSharedLockedAlloc(sizeof(TMIDIHDR), hdrHandle); - sysexPointer := GlobalSharedLockedAlloc(BufferSize, sysexHandle); - - hdrPointer^.lpData := sysexPointer; - hdrPointer^.dwBufferLength := BufferSize; - end; -end; - -{-------------------------------------------------------------------} -destructor TMyMidiHdr.Destroy; -begin - GlobalSharedLockedFree( hdrHandle, hdrPointer ); - GlobalSharedLockedFree( sysexHandle, sysexPointer ); - inherited Destroy; -end; - - - -end. diff --git a/src/lib/midi/demo/MidiTest.dfm b/src/lib/midi/demo/MidiTest.dfm Binary files differdeleted file mode 100644 index 0d0ae182..00000000 --- a/src/lib/midi/demo/MidiTest.dfm +++ /dev/null diff --git a/src/lib/midi/demo/Project1.dpr b/src/lib/midi/demo/Project1.dpr deleted file mode 100644 index 7aa4e512..00000000 --- a/src/lib/midi/demo/Project1.dpr +++ /dev/null @@ -1,13 +0,0 @@ -program Project1; - -uses - Forms, - MidiTest in 'MidiTest.pas' {MidiPlayer}; - -{$R *.RES} - -begin - Application.Initialize; - Application.CreateForm(TMidiPlayer, MidiPlayer); - Application.Run; -end. diff --git a/src/lib/midi/demo/Project1.res b/src/lib/midi/demo/Project1.res Binary files differdeleted file mode 100644 index 2b020d69..00000000 --- a/src/lib/midi/demo/Project1.res +++ /dev/null diff --git a/src/lib/midi/midiComp.cfg b/src/lib/midi/midiComp.cfg deleted file mode 100644 index 8b774c81..00000000 --- a/src/lib/midi/midiComp.cfg +++ /dev/null @@ -1,35 +0,0 @@ --$A+ --$B- --$C+ --$D+ --$E- --$F- --$G+ --$H+ --$I+ --$J+ --$K- --$L+ --$M- --$N+ --$O+ --$P+ --$Q- --$R- --$S- --$T- --$U- --$V+ --$W- --$X+ --$Y- --$Z1 --cg --AWinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE; --H+ --W+ --M --$M16384,1048576 --K$00400000 --LE"d:\program files\borland\delphi5\Projects\Bpl" --LN"d:\program files\borland\delphi5\Projects\Bpl" diff --git a/src/lib/midi/midiComp.dpk b/src/lib/midi/midiComp.dpk deleted file mode 100644 index 7c403eae..00000000 --- a/src/lib/midi/midiComp.dpk +++ /dev/null @@ -1,45 +0,0 @@ -package midiComp;
-
-{$R *.RES}
-{$R 'MidiFile.dcr'}
-{$R 'Midiin.dcr'}
-{$R 'Midiout.dcr'}
-{$R 'MidiScope.dcr'}
-{$ALIGN ON}
-{$ASSERTIONS ON}
-{$BOOLEVAL OFF}
-{$DEBUGINFO ON}
-{$EXTENDEDSYNTAX ON}
-{$IMPORTEDDATA ON}
-{$IOCHECKS ON}
-{$LOCALSYMBOLS ON}
-{$LONGSTRINGS ON}
-{$OPENSTRINGS ON}
-{$OPTIMIZATION ON}
-{$OVERFLOWCHECKS OFF}
-{$RANGECHECKS OFF}
-{$REFERENCEINFO OFF}
-{$SAFEDIVIDE OFF}
-{$STACKFRAMES OFF}
-{$TYPEDADDRESS OFF}
-{$VARSTRINGCHECKS ON}
-{$WRITEABLECONST ON}
-{$MINENUMSIZE 1}
-{$IMAGEBASE $400000}
-{$DESCRIPTION 'Midi related components'}
-{$DESIGNONLY}
-{$IMPLICITBUILD ON}
-
-requires
- vcl50;
-
-contains
- Miditype in 'Miditype.pas',
- Mididefs in 'Mididefs.pas',
- MidiFile in 'MidiFile.pas',
- Midiin in 'Midiin.pas',
- Midiout in 'Midiout.pas',
- MidiScope in 'MidiScope.pas',
- Midicons in 'Midicons.pas';
-
-end.
diff --git a/src/lib/midi/midiComp.res b/src/lib/midi/midiComp.res Binary files differdeleted file mode 100644 index 91fb756e..00000000 --- a/src/lib/midi/midiComp.res +++ /dev/null diff --git a/src/lib/midi/readme.txt b/src/lib/midi/readme.txt deleted file mode 100644 index 7112aecf..00000000 --- a/src/lib/midi/readme.txt +++ /dev/null @@ -1,60 +0,0 @@ - -Midi components - TMidiFile, TMidiScope - TMidiIn and TMidiOut of david Churcher are included because they are used in - the demo application - -Freeware. - -100% source code, demo application. - -Included Components/Classes - -TMidiFile, read a midifile and have the contents available in memory - list of Tracks, track is list of events - - -TMidiScope, show all activity on a midi device - -TMidiIn and TMidiOut of David Churcher are included because they are used -in the demo application - -Midiplayer is a demo application which plays a midifile on a midi output - it is build fairly simple with the included components. The timer is used - to time the midievents. The timing is therefor as good as the windows timer. - - - The header of midifile,midiscope contains help information on the properties/functions - The example Midiplayer gives a good idea how to use the components - -Installation - open midiComp.dpk with file/open - compile and install the package - make sure that the directory where the files are located is in the library path - (tools/environment options/library) - -to run the demo - open project1.dpr in the demo directory and press run. - - - -history -1.0 18-1-1999 first release - -1.1 5-3-1999 update - added some functions for display purposes - improved demo to include event viewer - bpm can be changed - -1.2 24-2-2000 update - added some functions to see the length of a song and ready function to know when playback is ready - -for comments/bugs in these components: - -Frans Bouwmans -fbouwmans@spiditel.nl - -I'm busy building a software music synthesizer, which will be available in source -to the public. If you are interrested in helping me with certain soundmodules -(effects, filters, sound generators) just sent me an email. - |