BHT MIDIBHT MIDI
This is a plugin for Construct 2 by Scirra. Last updated: April 4 2014

This plugin provides the ability to play MIDI files within Construct 2. It provides a means of playing/pausing/stopping files, changing instruments, and managing channels. You should be somewhat familiar with MIDI to use this plugin.

Caveat emptor (warning)
At present this is still an experimental mechanism. It is not a robust solution to providing complete MIDI support across all browsers/platforms. MIDI really needs much more support underneath for this to work fully. This plugin is a first step in that direction, but you will need to test any usage early to see if it meets the needs of your target platform(s). Deficiencies will be noted throughout the document with a caveat emptor notice.

Introduction
The plugin supports two implementations of the MIDI interface. c2midi, which uses the C2 Audio plugin to play all sounds, and webmidi, which uses the OS interface if there is one.
c2midi
For c2midi you provide ALL of the sound file for an instruments you want to have generate sound for your music files. You must provide every note if you want complete cross-platform/browser support. A smaller subset of platforms/browsers can use a smaller sampling of notes, and interpolate the missing notes, but only if the Web Audio API is supported. c2midi uses a variation of the soundfont mechanism typically used to generate sounds for MIDI, but at present there is no support to looping samples, which typically takes a very short sound and loops it indefinitely until the note stops. This limits which instruments can be used unless you can generate your own looping sample for the maximum note length required by your song(s). <I haven't tried this myself yet, so you are on your own with this one.>

Always keep in mind that this plugin uses the Audio plugin, so all limitations of the Audio plugin also apply here. It also uses the Function plugin for listener functionality.

webmidi
For webmidi the host OS is used to generate the sounds, but only if it supports this functionality. This generally means desktop platforms only. Having said that, there is a MIDI interface available for the iPod, but I have no experience with this and have no idea how or if it will work with this implementation. There is also another issue with webmidi; there is no native support for MIDI by any browser, so you must install a browser-plugin called JAZZ. That means unfortunately that any person wanting to play your game will also have to install this plugin. Sadly there is no way around this at present, so keep this in mind for your project/target audience.

Having said that, this is the fastest way to get started, as you don't need any of your own soundfonts to get started, and can take advantage of the Windows MIDI driver to get going quickly.

Caveat emptor - please be aware that generating music on the fly is an expensive operation. I don't recommend using MIDI as a memory saving alternative to standard sound files. Unless you are aiming at desktop systems only, you have to provide all on the sound files for all of the notes, for all of the instruments that you want to support for your music. Generating and timing all of those notes, up to 16 channels worth, can also place a strain on many slower platforms. As stated before, be sure to test your game early against any supported platform. MIDI may not be a suitable solution for all cases.
Installing
Drag the C2ADDON file onto the Construct GUI to install the plugin.
Things to keep in mind
1) All values are ZERO based. This can be a bit confusing, in MIDI terms, as documentation likes to keep things human-friendly, by starting at ONE. Computers always start at zero, however, and all MIDI internals do start at zero, so everything in this interface does too. Commonly drums play on channel 10, but internally this is actually channel 9 - keep this in mind!
2) If you don't provide a sound file for every instruments every note, interpolation is attempted. This will not always work. Only if the Web Audio API is supported, will this work.
Properties
Player buffer size
This controls how many NoteOn events are processed at a once. By default 100 NoteOn events are processed together, and when the last have occurred, the next batch of events is processed. There may be times when there is an advantage to altering this number. Typically it should not be changed.
Note-off decay
In order to make notes sound more realistic, rather than turn off a note immediately, this small delay is added and the note fades over this period. Default is: 0.2s, which seems reasonable.
Conditions
On interface loaded
It takes some time to load the MIDI interface. When the imnterface has finished loading this trigger/condition occurs. No other calls should be made to the plugin until this condition is true.
On file loaded
When a file is loaded, it takes time to download it from the server. When the file is fully downloaded, this trigger/condition becomes true. Player calls should not be made until the file has finished downloading and this condition is true.
Is MIDI Player playing
This condition will be true while the Player is playing a MIDI file.
Actions
MIDI Commands
Load by interface(Interface, Device index)
Load the appropriate underlying MIDI interface. There are several implementations of MIDI available. The plugin implements two: "csmidi", and "webmidi". "c2Midi" is the C2-friendly mechanism that uses the Audio plugin to generate all of the sounds. You provide the sound files, and a mapping from file to note, and the plugin manages playing the correct sound at the appropriate time, to play the music file.
"webmidi" is a lower interface that lets you talk to the OS-native MIDI driver, that can either play a simulator, or send commands directly to a MIDI device.
Caveat emptor
Talking to the OS MIDI driver is not supported by any browser automatically at the moment. You will need to load an external browser-plugin called JAZZ, to get this to work. Sadly this means anyone trying to play your game will also have to install this plugin - there is no work around for this yet. The 'device index' is only use by "webmidi" to indicate which OS MIDI interface to use. 0 is typically the built-in-simulator. 1 would be any MIDI hardware interface that is plugged into the computer.
Set volume(Channel, Volume)
Set the volume of a given channel. Note: MIDI uses the values 0 to 127 for volume, where 127 is the highest volume setting.
Play a note(Channel, Note, Velocity, Delay)
On the given channel, play a numerical note, with a given velocity, after the given delay. Notes range from 0-127. Velocity ranges from 0 to 127. Velocity only translates to a volume level - no attempt to mimic any kind of attack is made. Delay is in seconds - can be a fraction of a second. (Internally you can go as low a 1ms).
Stop playing a note(Channel, Note, Delay)
On the given channel, stop playing a numerical note, after the given delay.
Play a key(Channel, Key, velocity, Delay)
On the given channel, play a text-based note/key, with a given velocity, after the given delay. Keys range from A0 to C8. reference
Stop playing a key(Channel, Note, Delay)
On the given channel, stop playing a text-based note/key, after the given delay.
Play a (note) chord(Channel, Chord, Velocity, Delay)
On the given channel, play a numerical chord (list of notes, comma separated), with a given velocity, after the given delay.
Stop playing a (note) chord(Channel, Chord, Delay)
On the given channel, stop playing a numerical chord (list of notes, comma separated), after the given delay.
Play a (key) chord(Channel, Chord, Velocity, Delay)
On the given channel, play a text-based chord (list of keys, comma separated), with a given velocity, after the given delay.
Stop playing a (key) chord(Channel, Chord, Delay)
On the given channel, stop playing a text-based chord (list of keys, comma separated), after the given delay.
MIDI Player
Load a file(Name)
Start loading a MIDI file. The condition On file loaded will be triggered when the file is loaded and ready to play.
Start(Loop)
Start playing the currently loaded MIDI file, with the given looping setting: looping off or looping on.
Resume
Resume playimg a paused MIDI file.
Pause
Pause the currently playing MIDI file.
Stop
Stop playing the currently playing MIDI file.
Add listener(Callback)
Add a callback function to listen to internal MIDI events, as they occur. As each event occurs when the MIDI Player is runniong, the event will be sent, with all of its parameters to the callback funtion so you can process it and do as you wish with it (trigger a piano key sprite, for instance). The call back send raw data to you. The format is:
TBD
Remove listener(Callback)
Remove the callback listener.
Load a user MIDI file(Data)
Load a MIDI file in base64 format.If the file is coming over the web outside of Construct, it may be in this format, so you can use this call to load it.
MIDI Patches
Configure an instrument(GMIndex, Prefix, Volume, Note naming, Known notes)
This loads all of the General MIDI sound files that make up a patch (soundfont) that will be used when playing MIDI files.All note-sounds are loaded from the Sounds folder in Construct, using a specific naming format. Each sound file will begin with the given prefix, followed by the note numerical values, or key names, as either individual notes, or ranges of notes. The name number can be names or numbers, not both. For example, for patch number 0, the prefix could be 000_, and the notes named A0-C8. So all files following this pattern (000_A0, 000_B0, 000_C1, etc) will be loaded.
There is no special trigger for this, as the built-in Audio plugins All preloads complete is used, since these are just sound files, being loaded by the Audio plugin. This call just does the preload calls for you.
There is a volume setting per patch also, as soundfonts can originate from various sounces and you may have to manage each patch's volume separately to get them playing at a similar volume level.
Caveat emptor - in my experiments, I had to add a small delay before checking this condition, otherwise it can trigger too quickly and you won't get all notes loaded before they can be played.
Configure a drum kit mapping()
This is almost exactly the same as the instruments call, except drums are managed separately from instruments.
Program change(Channel, Patch)
For the given channel, set it's current patch/instrument/soundfont.
Expressions
MIDI Player
CurrentTime
The current time of the MIDI player.
EndTime
The time that the MIDI Player/file will end.
IsPlaying
True if the MIDI Player is playing.
Utilities
KeyToNote(Key)
Convert a Key string (like 'C4') to it's MIDI numeric value ('C4'=60). The range is A0 to C8.
NoteToKey(Note)
Convert a MIDI numeric value to it's Key string (60='C4').
GetInputs
Gets a semi-colon delimited list of MIDI input devices.
GetOutputs
Gets a semi-colon delimited list of MIDI output devices.
InterfaceSupported(Name)
True is the named interface is supported.
CurrentInterface
Returns the name of the current interface.
MIDI File
Tempo
Returns the tempo, of the current MIDI file, in beats-per-minute.