PortMidi
Portable Real-Time MIDI Library.
BaH.Portmidi is a BlitzMax implementation of Portmidi, a platform independent library for MIDI.
Using Portmidi
The Portmidi module is built around the use of callbacks.
The main type, TPortMidi is initialized with two of them. An error callback, and a read callback. You need to implement these functions to allow Portmidi to inform you when something happens.
The read function is called when MIDI Input data becomes available for a particular stream.
The error function is called when Portmidi determines that something has gone wrong.
A minimal example might look like :
Function err(errorNumber:Int, errorString:String)
Print "Oops - " + errorString
End
End Function
Function read(stream:TPortMidiStream, length:Int, messages:TMidiMessage[])
Print length + " messages available"
End Function
Local midi:TPortMidi = TPortMidi.Create(err, read)
If midi Then
midi.openInput(0)
While Not KeyDown(key_escape)
WaitEvent
Wend
End If
A TMidiMessage represents a MIDI event sent by a MIDI device - for example, a keyboard key press.
The fields... status, data1 and data2, provide the message details.
A single read() event can have multiple message parts. You can use length to determine how many messages are available to process.
Do not use the length of the messages array as this may be larger than the number of actual available messages. (The array is static and grows when required, but isn't reset in an effort to keep it efficient).
SysEx
You can send and receive a SysEx message via the sendReceiveSysEx() method of TPortMidi. This method takes another callback function as a parameter, which will be called once the SysEx reply from the device is received. The receive part of this runs on the same background timer as the rest of the module, and so you can continue with your app while data is received from the device.
Local data:String = Chr($F0) + Chr($7E) + Chr($00) + Chr($06) + Chr($01) + Chr($F7)
midi.sendReceiveSysEx(1, 3, data, Null, sysexCallback)
' hang around and wait for the end...
While Not KeyDown(key_escape)
WaitEvent
Wend
End
Function sysexCallback(recMessage:String, userData:Object)
' .....
End Function
Constants
| Const PM_FILT_ACTIVE:Int |
| Description | filter active sensing messages ($FE) |
| Const PM_FILT_AFTERTOUCH:Int |
| Description | filter both channel And poly aftertouch. |
| Const PM_FILT_CHANNEL_AFTERTOUCH:Int |
| Description | filter channel aftertouch (most midi controllers use this) ($D0-$DF)*/ |
| Const PM_FILT_CLOCK:Int |
| Description | filter clock messages (CLOCK $F8, START $FA, STOP $FC, And Continue $FB) |
| Const PM_FILT_CONTROL:Int |
| Description | Control Changes (CC's) ($B0-$BF)*/ |
| Const PM_FILT_FD:Int |
| Description | filter undefined FD messages. |
| Const PM_FILT_MTC:Int |
| Description | MIDI Time Code ($F1)*/ |
| Const PM_FILT_NOTE:Int |
| Description | filter note-on And note-off ($90-$9F And $80-$8F. |
| Const PM_FILT_PITCHBEND:Int |
| Description | Pitch Bender ($E0-$EF*/ |
| Const PM_FILT_PLAY:Int |
| Description | filter play messages (start $FA, stop $FC, Continue $FB) |
| Const PM_FILT_POLY_AFTERTOUCH:Int |
| Description | per-note aftertouch ($A0-$AF) |
| Const PM_FILT_PROGRAM:Int |
| Description | Program changes ($C0-$CF) |
| Const PM_FILT_REALTIME:Int |
| Description | filter all real-time messages. |
| Const PM_FILT_RESET:Int |
| Description | filter reset messages ($FF) |
| Const PM_FILT_SONG_POSITION:Int |
| Description | Song Position ($F2) |
| Const PM_FILT_SONG_SELECT:Int |
| Description | Song Select ($F3)*/ |
| Const PM_FILT_SYSTEMCOMMON:Int |
| Description | All System Common messages (mtc, song position, song Select, tune request) |
| Const PM_FILT_TICK:Int |
| Description | filter tick messages ($F9) |
| Const PM_FILT_TUNE:Int |
| Description | Tuning request ($F6)*/ |
| Const PM_FILT_UNDEFINED:Int |
| Description | filter undefined real-time messages. |
| Const pmNoDevice:Int |
| Description | The device Id value the represents "No Device". |
Types
| Type TMidiMessage |
| Description | A midi event message part. |
| Field data1:Int |
| Description | Message data 1. |
| Field data2:Int |
| Description | Message data 2. |
| Field raw:Int |
| Description | The raw message data. |
| Information | status, data1 and data2 derive from this value. |
| Field status:Int |
| Description | Message status. |
| Field timestamp:Int |
| Description | Timestamp. |
| Type TPortMidi |
| Description | PortMidi main Type. |
| Method close(deviceId:Int) |
| Description | Closes the specified midi stream. |
| Method device:TPortMidiStream(deviceId:Int) |
| Description | Returns the TPortMidiStream device for the specified deviceId. |
| Method deviceCount:Int() |
| Description | Returns the number of midi devices (input and output) |
| Method deviceName:String(deviceIndex:Int) |
| Description | The name of the specified device. |
| Method getDefaultOutputDeviceId:Int() |
| Description | Returns the default output device ID or pmNoDevice if there are no devices. |
| Method interface:String(deviceIndex:Int) |
| Description | The underlying API name. |
| Method openOutput:Int(deviceId:Int) |
| Description | Opens an output stream for the specified deviceId. |
| Method outputDeviceCount:Int() |
| Description | The number of output devices. |
| Method outputDeviceName:String(outputIndex:Int) |
| Description | The name of the output device, by outputIndex. |
| Method sendReceiveSysEx:Int(inputId:Int, outputId:Int, sendData:String, userData:Object, .. |
| Description | Performs a SysEx send/recieve on the specified output and input devices. |
| Information | sendData is the data you wish to send to the device.
userData is an optional object that will be passed to the callback.
callback is a function that is called on completion of the recieved data. |
| Method setFilter:Int(deviceId:Int, filter:Int) |
| Description | Sets filters on an open input stream to drop selected input types. |
| Information | By default, only active sensing messages are filtered.
To prohibit, say, active sensing and sysex messages, call with PM_FILT_ACTIVE | PM_FILT_SYSEX.
Available filters are : PM_FILT_ACTIVE, PM_FILT_SYSEX, PM_FILT_CLOCK, PM_FILT_PLAY,
PM_FILT_TICK, PM_FILT_FD, PM_FILT_UNDEFINED, PM_FILT_RESET, PM_FILT_REALTIME,
PM_FILT_NOTE, PM_FILT_CHANNEL_AFTERTOUCH, PM_FILT_POLY_AFTERTOUCH, PM_FILT_AFTERTOUCH,
PM_FILT_PROGRAM, PM_FILT_CONTROL, PM_FILT_PITCHBEND, PM_FILT_MTC, PM_FILT_SONG_POSITION,
PM_FILT_SONG_SELECT, PM_FILT_TUNE and PM_FILT_SYSTEMCOMMON.
|
| Function Create:TPortMidi(errCallback( errorNumber:Int, errorString:String), .. |
| Description | Creates a new PortMidi instance. |
| Information | Initializes PortMidi, and gets details of available devices. |
| Type TPortMidiStream |
| Description | A PortMidi stream/device. |
| Method close() |
| Description | Closes an open stream. |
| Method interface:String() |
| Description | Returns the underlying midi API name. |
| Method isOpen:Int() |
| Description | Returns True if the stream is open. |
| Method name:String() |
| Description | Returns the device name. |
| Method setFilter:Int(filter:Int) |
| Description | Sets filters on the open input stream to drop selected input types. |
Module Information
| Version | 1.03 |
| Author | Ross Bencina, Phil Burk, Roger B. Dannenberg |
| Copyright | Phil Burk, Ross Bencina, Roger B. Dannenberg |
| Credits | Wrapper - Initial implementation : Nigel Brown |
| Credits | Wrapper - 1.00+ Type based/Hook/Callback : Bruce A Henderson |
| License | Free |
| Modserver | BRL |
| History | 1.03 |
| History | Documentation improvements. |
| History | 1.02 |
| History | Update to 17-Jan-07 portmidi release. |
| History | New filters for setFilter(). |
| History | Added sendReceiveSysEx and openOutput methods, and new sysex handler. |
| History | 1.01 |
| History | Added TMidiMessage type. |
| History | Rewrite of the event buffer handling to use the new type. |
| History | More functionality. Improved documentation. |
| History | 1.00 Release |
| History | First release using portmidi sdk |
| CC_OPTS | -DUSE_DLL_FOR_CLEANUP |
| CC_OPTS | -DNEWBUFFER |