MidiFire Manual

Version 1.13, July 2018
© 1999-2018 Audeonic Apps

MidiFire - powerful, extendable modular MIDI processing environment for iOS and macOS.

Quick Start

Want to get going fast? Here are the basics:

  • Press the '+' button on top left to expose the scrollable block menu.
  • Touch MIDI inputs, outputs and modules to drop them on to the canvas.
  • Arrange the blocks however you like by touching and dragging them. Use two-fingers to scroll/pinch zoom to adjust and pan the canvas.
  • Connect up the blocks by dragging a line between the arrowed connection points.
  • Configure each module's parameters by touching the 'cog' icon on each block.

Tip - direct links to:  Scenes, Module Summary, Stream Byter, Getting Help

1. Organising Blocks


In MidiFire, a 'block' is a rectangular object on the canvas that represents a MIDI source (input to MidiFire), MIDI destination (output from MidiFire) or a processing module. Blocks are added to the canvas via the 'Block Menu'.

The Block Menu (+)

The Block Menu is expanded by touching/clicking on the circular '+' button at the top left of the canvas.

Block Menu

You add blocks to the canvas by touching their entry in the Block Menu. Scroll the Block Menu to access all the available block types. Each newly added block will be added to the canvas to the right of the Block Menu and will briefly flash in a coloured fashion to alert you to its existence.

Tip - you can touch anywhere on the canvas or the top left '-' to collapse the Block Menu.

Arranging Blocks

Once you have 'dropped' your blocks, you can now arrange them however you like. Simply touch hold (anywhere in the block except on the block's buttons/arrow connectors) and drag the block into position.

Managing Blocks

Each block has a number of visible widgets used for managing the block:


Connecting Blocks

In order for MIDI data to move from block to block, they need to be connected. Typically you would connect MIDI source blocks into modules and then on to MIDI output blocks to create a flow of MIDI in and out of the MidiFire application.

There are two ways to interconnect blocks:

  • Simple drag/connect
  • To connect one block to another, drag your finger/mouse from the input or output connector of the block to a corresponding output or input connector on another block.

  • Multiple touch/connect
  • This is the 'MidiBridge' method, where you touch any input or output connector to 'select' it (it will start flashing yellow). All other blocks' corresponding output or input connectors will change to a cyan colour to indicate they can be connected to the selected block. Simply touch each cyan connector in turn to connect to the selected. Finally, touch the flashing connector again to deselect.

When blocks are connected together, a curved green line will be visible between their connectors:

Connected Blocks

Tip - to remove a connection just 'remake' the connection on already connected blocks.

Configuring Blocks

Modules can be configured by pressing the configure block 'cog' button on the block. This will bring up a moveable panel in which you can set the name of the block to suit. Each module has a different set of configurable parameters and these are described in the relevant module sections further on in this manual.

Set Module Name

The Module Settings panel is dismissed using the 'X' button at top left of the panel or by touching elsewhere on the canvas to dismiss.

Bypassing Blocks

The bypass 'power' button bypasses a module. This means all MIDI data passing through is not altered. A bypassed module is indicated by a red coloured bypass button and the block itself becomes more transparent:

Bypassed Block

To re-activate a bypassed module, just touch the bypass button again.

Removing Blocks

To remove a block from the canvas use the 'X' remove button. You will be prompted to confirm removal before the block is removed. All connections to the removed block are cleared also.

Event Visualisation

As MIDI data is passed through the blocks, they will flash briefly. If the flashing is a yellow colour, then the MIDI data was passed on. If the block flashed red, then that MIDI data was blocked by the module. You can turn off the flashing behaviour via the 'Setup' panel covered later.

2. Navigating the Canvas


The canvas is the area of the screen in which you place blocks but it has some more features:

Pan, Zoom and Scroll

The canvas can be panned/scrolled by dragging your two fingers on a touch device or with a mouse or trackpad on a desktop computer. Use two fingers anywhere on the canvas background to pan up/down and left/right. If using a scroll mouse, the canvas can be scrolled up/down with a scroll wheel, or left/right if your mouse scroll wheel allows that. A trackpad can also be used to pan the canvas.

To zoom the canvas in/out you can use a two finger pinch-zoom gesture on a touch device or trackpad. For desktop computers without a trackpad, you can use the two zoom in/out buttons at the bottom right or the menu zoom command.

To clear the canvas, use the button at bottom right (blank square icon). Use the zoom to fit button next to it (square+arrows icon) to zoom the canvas to fit all modules on the screen automatically.

The Button Bar

At the top right of the canvas is a status indicator with a set of button controls beneath. (Note: Scenes and Setup are covered in their own separate sections below)

Button Bar

Status Indicator/Activity Log

The status indicator shows the last action performed by the user in the application. The colour of the text in the label will be:

  • Green - Positive things
  • Yellow - Less positive things
  • Red - Errors

Touching the status indicator will open up the Activity Log panel which shows all actions performed in the app since it was started along with a timestamp. When blocks are added to the canvas, the name of the block is shown prefixed by '+' in green. Removals are shown prefixed as '-' and in yellow.

The log is currently just a read-only list for informational purposes.

Dismiss the Activity Log using the 'X' or touching the canvas background.


Pressing the 'Help' button will bring up this manual.


Sometimes with MIDI things can go haywire. This is where the 'Panic' button comes in. When pressed, it will issue a standard set of MIDI panic messages (all notes off on all channels) to every MIDI port in the system (whether present on the canvas or not).

When you press the 'Panic' button, MidiFire will suspend all event routing so as not to exascerbate the problem. This is shown by making the whole canvas visibly faded and unable to receive user interaction. The 'Panic' button will also turn a yellow colour.

When you have resolved the problem, press the yellowed 'Panic' button once again to resume event processing and user interaction.

Dismissing Panels/Selections

The canvas can also be used to instantly dismiss all open panels or cancel any connection selections. Just tap anywhere on the canvas background.

3. Managing Scenes


Pressing the 'Scenes' button on the Button Bar will open up the Scenes management panel. A Scene is a snapshot of a canvas that can be loaded, merged, shared or deleted. Internally it is a text file in 'property list' XML format.

Scenes Panel

Each scene in your library is presented as a scrollable list showing the name of the scene and any MIDI program change assignment for that scene.

Saving your Work

As you work on your canvas and block configuration you can save a snapshot at any time to a name of your choice that you can use later:

  • Press 'Scenes' button to open panel
  • Press 'Save' button
  • Enter a name (or modify) for the scene
  • Confirm (optionally) if scene would be overwritten to update

Dirty Scenes

As you make changes to the canvas following a save (or load) the Scenes button will assume a reddish hue to remind you that unsaved changes have been made.

Following a save or load action the Scenes button will revert to its normal colour.

Loading and Merging

Scenes can be re-used in two possible ways:

  • Load
  • Next to each scene name is a separate 'Load' button. Pressing this will load in that scene immediately and entirely; ie. it will clear the canvas first and replace with the contents of that scene. Use the individual Load buttons to switch between your scenes quickly.

    Stored with each scene is the current zoom scale when saved. On 'Load' this zoom scale is honoured.

  • Merge
  • Merging adds the contents of a scene to the canvas without clearing it first. Before you merge a scene, you need to select it in the list first, by touching it - it will highlight in a blue colour. Once selected, pressing the 'Merge' button will add it into the canvas.

    MidiFire will intelligently place your merged scene into the current canvas so as not to cover any existing blocks on the canvas. The scene's zoom scale is not honoured during a merge.

Tip - you can save oft-used snippets of work into separate scenes and then merge them as needed.

Assigning Remote MIDI Control

Scenes can be loaded (not merged) remotely via MIDI Program Change message. Pressing the 'Assign' button on the Scenes Panel will switch to Program Change assign mode. This is indicated with the 'Assign' button taking on a green colour and the individual 'Load' buttons being replaced by program change number selectors:

Assigning Scenes

The first thing you will need to do in order to activate remote MIDI control is to set the 'Scene Channel' value using the dropdown selector next to the (now green) Assign button. By default, Scene Channel is OFF which means that remote control is disabled.

Scene change program change messages can be set to be recognised from a specific channel only (recommended) or (if you really must) on all (OMNI) channels. To prepare for remote control, select a specific channel or 'OMNI' for Scene Channel.

Once the Scene Channel is configured, you then assign a program change number to each of the scenes that you wish to be able to load remotely by setting the program change number using the dropdown in each scene cell.

Note that each scene must have a unique program change number. If you select a number that has already been assigned to a different scene, then the new scene will take on the requested assignment and the previous assigned scene will be marked as unassigned.

Once you have finished assigning program change numbers to scenes, press the 'Assign' button to leave assign mode. At this stage validly assigned program change messages that are received by MidiFire will trigger a scene change, as if the scene's individual 'Load' button had been pressed.

Tip - MidiFire will honour assigned program change messages appearing on any MIDI source whether it is currently displayed on the canvas or not.


You can share your saved scenes with other devices/computers or other MidiFire users using the 'Share' button.

On iOS, the share action invokes the device's inbuilt sharing options that will vary depending on the device. This may include Airdrop, email applications or sharing applications like Dropbox.

Also, on iOS, iTunes sharing is enabled, so you can drag/drop scenes in/out of your device via the Apps > File Sharing area in iTunes. Please note that the app is not informed when you modify the directory remotely. If your newly inserted scenes are not shoing up, close and re-open the Scenes panel to refresh the list.

On macOS pressing the 'Share' button will open the raw library files in the Finder with the currently selected scene file highlighted for you.

To import scenes on an iOS device, MidiFire has registered '.mfr' files as belonging to it and you can download and install these files into MidiFire using the usual iOS mechanisms. Imported scenes will show up in your Scenes panel; they are not loaded automatically.

On macOS to import a scene externally you can use the 'Share' button to open the directory in the Finder and copy your scene into the directory.

Tip - because Scene files are plain text files, they can be shared via websites and imported using your web browser.

Cleaning Up

Finally, if you wish to delete a scene from your library, select it and press the 'Delete' button. You will be asked to confirm deletion. Please note that when you delete a scene the file is removed from your device/computer.

4. Setup


Use the 'Setup' panel to configure application wide settings. These are not stored in scenes.

Scenes Club

Because MidiFire is eminently extendable, we have a whole set of pre-made scenes available directly which may be of interest to you.

Pressing the 'Scenes Club' button will open a new panel showing a list of available scenes, description and author. To download any scene into your library, press the download icon to the right of each scene.

The Scenes Club is hosted on the Internet, so to access and download scenes you do need to be online.

Tip - if you have any scenes which you feel would be useful to others, email them to us and we can distribute them (with attribution) via the Scenes Club.

Virtual MIDI Ports

By default, MidiFire creates one pair of virtual MIDI ports that can be used to send/receive MIDI data to other apps running on your device. For some, this is not enough, so if you would like more separate virtual ports to assist in your workflow then you can have these created for you (as long as you want 4 or 8).

When MidiFire has multiple virtual port pairs configured, the additional ports are numbered individually from 1 to 3 (or 7) so that you can distinguish them easily. You still get to keep the 'MidiFire' default/main port pair which will always be present.

To change the number of virtual port pairs advertisied by MidiFire just make a selection for the 'midifire virtual ports' dropdown.

Event Visualisation

As MIDI data is processed by MidiFire, the ports flash briefly. If you find this annoying or want to improve performance when in the foreground (nothing flashes in the background) turn the flashing off by setting 'event visualisation' to 'no'.

Idle Timeout (iOS)

On iOS to prevent battery drain, MidiFire will automatically suspend itself after a period of inactivity.

You can adjust this timeout from the default 15 minutes to something larger, or if you are brave to 'never' which will disable auto-suspension entirely.

Note that MidiFire will never suspend if the device is powered.

Ignore Active Sense

By default, MidiFire will ignore all Active Sensing MIDI messages on input ports as they are rarely desired in non-hardware environments. If you need to Active Sensing messages to be processed, switch this option to 'no'

Holdover Processing

'Holdover' is a MidiFire feature that keeps track of held notes (or use of the hold pedal) on each external MIDI input and 'freezes' the MidiFire configuration for that specific input while the hold is in effect.

This means that as you make changes to MidiFire on the canvas, (or load a new scene) events from the held MIDI input are not affected by these changes until you let go of all notes and release the hold pedal.

Therefore, you won't get stuck notes or lost pitchbend messages and the like when a new scene is loaded or changes are made to the canvas that might affect these.

Although holdover has been designed to be very efficient, there could be some slight performance loss especially with complex scenes. For those who don't need the holdover processing and wish to save some extra CPU cycles, setting this to 'no' will disable it entirely.

Note, changes made to Stream Byter rules are not frozen, so any changes made to rules will take effect whether a hold is active or not.

Tip - each MIDI input is frozen separately so you can use multiple external inputs (controllers, sequencers) and each will have its own frozen configuration while a hold is active.

Remote Control

You can control some on-screen actions of MidiFire via MIDI command. The actions (buttons, switches or dropdowns) that can be remote controlled are:

  • Panic switch (application)
  • Bypass switch of any module (scene)
  • All 'Channel Strip' dropdowns, except note remap (scene)
  • 'Note/Velocity Split' split point, lower channel and upper channel dropdowns (scene)
  • 'Install Rules' button on Stream Byter (scene)
  • 'Tap Tempo' button and 'Auto Start' dropdown on 'Dynamic Clock' (scene)

Assignments of actions marked as 'scene' above are scene specific and thus saved and restored with a scene. Non scene actions, marked as 'application' above are application wide and saved with application preferences.

MIDI messages (on any specific channel) that can be utilised are:

  • Continuous Controller (except bank select)
  • can control buttons, switches and dropdowns

  • Program Change
  • can control buttons and switches

  • Note On/Off
  • can control buttons and switches

Tip - if you want to trigger controls with MIDI messages other than those listed above (eg. sysex) you can always use a Stream Byter to inject them using an SND +I rule

Remote Control messages can be assigned to actions or learnt via the 'Remote Control' panel found on the Setup panel.

Remote Control Panel

To assign a MIDI message to an action, first select it in the list on the Remote Panel. Note, if the action you wish to assign belongs to a canvas block, then this block will be given a cyan highlight so you can identify which module you are working with (handy when you have multiple modules with the same name).

You can either use the dropdowns at the bottom of the panel to assign the MIDI message to the selected action, or you can turn on 'Learn' using the button and MidiFire will assign the most recently received valid MIDI message to the action. Note that while you are 'Learning', normal remote control is disabled.

If you wish to remove an assignment, select '- none -' as the value for the 'type' dropdown at the bottom.

The following table explains how each remote MIDI message is interpreted for each type of action:


Program Change

Note On/Off



momentary push

momentary push on note on

momentary push if value >= 64


toggles switch

note on turns switch on, note off turns switch off

value 64-127 turns switch on, 0-63 turns switch off


- n/a -

- n/a -

value selects option in a scaled fashion. value 0 is first option, value 127 is last option

Tip - you may assign the same MIDI message to more than one action, so you could bypass a group of modules with the one remote message.

Bluetooth MIDI (some iOS devices)

From within MidiFire you can setup Bluetooth MIDI connections if your iOS device is recent enough to support it.

There are two methods of connectivity accessed by their respective buttons:

  • Connect Device
  • Use this button if you wish to connect your iOS device to a remote Bluetooth MIDI device such as another iOS device or a quicco or yamaha BT01.

  • Host Service
  • If you want to be able to accept incoming Bluetooth MIDI requests from remote devices then you use this button to start being a host.

If Bluetooth MIDI is not supported on your device, then these buttons will be missing. Obviously Bluetooth needs to be turned on in your device. If it's off and you press any of the Bluetooth buttons you will be reminded that you need to turn it on.

Tip - at the bottom of the Setup panel you will find the current version and build number of MidiFire that you have installed. Please pass on those details if you contact us for support.

CoreMIDI Networking (iOS)

MidiFire can be used to initiate CoreMIDI (rtpMIDI) WiFi connections from within the app. Pressing the CoreMIDI Networking button will open up a separate panel for making these connections:

  • remote host/address
  • Enter the hostname or IP address of the remote device/computer that you wish to initiate the connection to. By default this is set to 'localhost' which creates a looped back connection where all events sent to the Network output port are reflected back into the Network input.

    The label for this field will also display the IP address of the device. You can use this address in another device if you wish to connect to this device from MidiFire on that other device.

  • remote port number
  • This is the IP port number that the remote is accepting rtpMIDI connections on. By default this is 5004, which is the standard port number for the first network connection. Generally this value does not need to be changed.

  • auto connect
  • Setting this option to 'yes' will instruct MidiFire to automatically initiate the connection when it starts up the first time.

  • Connect/Disconnect
  • Press this button to manually initiate a conection if not currently connected (button is grey and labelled 'Connect') or disconnect all connections (button is green and labelled 'Disconnect')'.

5. Modules


While you can do very sophisticated routing with just MIDI sources and destinations in MidiFire, the application comes into its own when you introduce modules into the mix. There is a variety of modules included ranging from simple/common, to more niche/purpose built modules to the most complex but powerful Stream Byter that lets you create your own customised modules. Here is a summary of the included modules:

Each module is documented in detail below.

Channel Strip


The Channel Strip module packs the most commonly used MIDI channelisation functions into one handy module. Place this module before MIDI outputs to limit incoming channels, remap outgoing channel, remap and/or transpose notes and convert poly to mono.

  • allowed incoming channel (default: any)
  • Set the specific channel that you want the module to accept. If set to anything other than 'any' the module will block all MIDI events that are not on the selected channel.

  • transpose notes (default: 0 semitones)
  • Transpose all incoming note events by the number of semitones selected in the dropdown.

  • remap note from/to (default: no mapping)
  • Remap incoming notes to different output notes. First select the incoming note you wish to map from on the left. Next select the note you wish to remap to on the right. Repeat for as many notes as you wish to remap.

    Be aware that any remapping happens after any transpose.

  • convert notes to mono (default: no)
  • Switching this on will convert a polyphonic source to mono intelligently and will operate like a mono keyboard from the good old days.

  • outgoing channel remap (default: no)
  • You can remap the outgoing channel of channelised MIDI events to match the channel of a receiver. Handy for remapping the default channel 1 of most controllers to a specific channel.

Tip - on the canvas block, there are two labels that show you the configured channel mapping of the module. The left (info 1) shows the allowed incoming channel number (if any) and the right label (info 2) shows the outgoing channel being remapped to (if configured).

Note/Velocity Strip


The Note/Velocity Split module allows the splitting of an incoming event stream over two user defined MIDI channels. A split can be done on keyboard position (note) or note velocity. Incoming note and aftertouch events are remapped regardless of the channel that these events are on when entering the module.

  • split type (default: note)
  • If this parameter is set to 'note' then the split will operate based on the pitch of the note you select as the split point. All note ons, offs and key aftertouch will be sent to either the lower channel depending upon the pitch of the note.

    Setting this parameter to 'velocity' will send the note (and aftertouch for that note) to either the lower or upper channel depending upon the note's original strike velocity.

  • split point (default: middle C or 64 velocity)
  • This is the value that determines whether the note events will be directed to the lower or upper channel. The split point is the first note or velocity value in the upper range.

  • lower channel (default: 1)
  • Notes whose pitch or velocity (depending upon type parameter) are lower than the split point will be remapped to the channel specified in this parameter.

  • upper channel (default: 2)
  • Notes whose pitch or velocity (depending on type parameter) are greater than or equal to the split point will be remapped to this channel.

  • non-note/aftertouch handling (default: pass unchanged)
  • Other channelised events passing through the splitter (pitchbend, channel pressure, controllers and program changes) can be handled in several different ways depending on the situation.

    If these types of events should not be altered in any way, then set this to 'pass unchanged'. If you wish to block these other events entirely then set this to 'block'

    Alternatively, you can remap these other events to either the lower split channel only, the upper split channel only or have them sent to both upper and lower split channels by selecting these in the dropdown menu.

    All of these other events are affected as a group. If you need finer control (say sending CC A to lower and CC B to upper) then use a Stream Byter beforehand to do the controller remapping and leave this option at the default.

The graphic below the parameters displays the current split point. You can also touch/mouse the graphic to set the split point.

Tip - the split point and upper/lower channel parameters are all remote controllable via MIDI (configured in Remote Control)

Pressure Curve


The Pressure Curve module allows the definition of a velocity curve map that can be applied to incoming notes, key aftertouch or channel pressure. The map can be adjusted point by point or graphically using touch/mouse control.

  • curve type (default: note velocity)
  • This parameter determines what type of events the map curve will be applied to. Either notes, aftertouch (polyphonic per note), channel pressure or controller value can be affected.

  • remap value from/to (default: no (linear) mapping)
  • Remap incoming velocity/aftertouch/controller values to different values. First select the incoming value you wish to map from on the left. Next select the value you wish to remap to on the right. Repeat for as many values as you wish to remap.

Tip - the graphic below the parameters displays the current curve. You can also touch/mouse the graphic to draw or modify the curve.

Event Monitor


The Event Monitor module allows you to see at a glance the MIDI events coming from a port or a module. The canvas block shows the last few events in a compact form. Expanding the module shows all events received in a more detailed form.

Tip - use the 'Clear' button to clear events in the detailed view.

Comment Block


The Comment Block is a non-functional module that you can use to record free-form notes about the canvas. You can add text to the block itself (summary) and more detailed notes in the module's settings.

Tip - Comment Blocks will be saved into scenes.

Protocol Filter


The Protocol Filter module allows you to block or allow a range of MIDI protocol events passing through the module. It does this by marking a range of MIDI events (according to the MIDI data specification) and then allows you to block or only allow events that fall into that range.

  • FROM (hex message)
  • This value shows (and allows you to change) the starting event to which the filter (block/allow) will be applied. If you know the hex of your starting (and ending message) you can just enter it in this field. Alternatively, you can make a selection using the other parameters and the hex field will be updated too.

  • event type, channel, number, value
  • You can use these parameters to specify the MIDI message in a more user friendly way if you prefer. Note that as you change any of these values, the corresponding hex value above changes accordingly. Also, some of the parameter labels will change depending upon the event type selected to make sense MIDI-wise

  • TO (hex message)
  • You mark the end of the range in the same way as the start by adjusting the hex value (or other parameters).

  • Block/Allow (default: Allow)
  • Set whether the filter blocks or only allows your configured range by toggling these two buttons.

Tip - because this works on a horizontal range of hex values, the Protocol Filter is probably not the tool for blocking/allowing specific MIDI channels. Use the Channel Strip or Stream Byter for this.

Dynamic Clock


MidiFire implements the much lauded MidiBus clock via a specialised module. You can control many aspects of the internal clock dynamically via remote control MIDI messages; see further for details of this.

The output of the clock signal varies slightly depending upon how the module is connected:

Clock Connections

  1. The virtual destination/output 'MidiFire Clock' which is presented to other apps by MidiFire will always be an unmodified copy of the clock signal. You do not need to add the 'MidiFire Clock' port to the canvas.
  2. If the Dynamic Clock module is directly connected to a MIDI destination/output (like 'MidiFire 1' in the above diagram), then that MIDI destination will receive the internal clock output directly, bypassing any internal routing in MidiFire. This is the most efficient way of distributing the clock signal to a destination.
  3. If the Dynamic Clock module is indirectly connected to a MIDI destination/output (like MidiFire 2' in the above diagram) then the internal clock signal is first of all fed into the interconnecting module(s) and then routed to the output. This type of connection is made when you want to do something with the clock signal beforehand.
  • tempo
  • Use this field to set a specific tempo manually. You can use decimal fractions like 121.34 if you like and the value can range from very slow to very, very high (how high will depend upon the processing power available on your device)

  • Tap Tempo
  • Tap this button a few times to set the tempo according to how quickly you tap it.

  • Learn Tap
  • You can set up a remote MIDI event to control tap tempo. Press the 'Learn Tap' to arm and the next MIDI event received will be set as the tap tempo trigger. Subsequent MIDI events that match the learnt event are processed as if you had tapped the 'Tap Tempo' button above. Learnt events can (only) be a note on, non zero continuous controller or program change types.

  • learnt tap event
  • This will either show the learnt tap tempo MIDI event, or if you know the hex message of the event you wish to use, you can simply enter that.

  • Auto Start Clock
  • You can tell MidiFire to automatically start the clock as the tempo is being tapped. The number of taps required to start is set using the field menu and the clock will start exactly on the beat after that number of taps. For example, if you set the value to '4' and start tapping, the clock will automatically start on the beat after the 4th tap, ie. on tap 5 (even if you don't tap 5 times).

    Setting this to 'no' (the default) will disable the feature and you will need to start the clock yourself.

The 'bypass' block button is repurposed to play/stop for this module (and the 'power' icon replaced by more transport friendly icons). Tap the start/stop button to start/stop the clock. Note, when the clock is running, the module block becomes yellow.

The left hand info label on the block shows the currently configured (or if running, calculated) BPM. The right label shows where the clock is up to in real world time in hh:mm:ss format.

Tip - the Dynamic Clock module is a clock generator. However, you can still feed (and manipulate and send out) an external clock source from another app or physical port.

Remote Control

The Dynamic Clock responds to a set of MIDI messages to control the transport and tempo. These are described as follows:

  • Tap Tempo (default CC 63 on channel 1)
  • Control the tempo dynamically via tap events. This MIDI event can be set on the configuration panel or learnt (via same panel)

  • Start, Stop and Continue (fixed System Real Time)
  • You can start, continue or stop the clock by sending the standard MIDI start/stop/continue messages (FA, FC and FB respectively in hex)

  • Coarse/Fine tempo adjustment (fixed CC 19 and 51, channel 1)
  • Sending CC 19 on channel 1 will adjust the tempo to an absolute value between 20 and 200 BPM depending on the value byte of the CC (0 = 20, 127 = 200)

    Sending CC 51 on channel 1 will adjust the current coarse tempo from -20 to +20 in tenths of a BPM (0 = -20.0, 127 = +20.0).

  • Tempo increment/decrement (fixed CC 18 and 50, channel 1)
  • Sending CC 18 on channel 1 will increment the current tempo by tenths of a BPM. (ie. value byte 1 = 1/10BPM, 2 = 2/10BPM, 10 = 1BPM, 100 = 10BPM)

    Sending CC 50 on channel 1 will decrement the current tempo by tenths of a BPM. (ie. value byte 1 = 1/10BPM, 2 = 2/10BPM, 10 = 1BPM, 100 = 10BPM)

  • Absolute tempo value (fixed sysex)
  • You can remotely set the clock tempo to an exact BPM value using a sysex message:

    F0 5A <ThousandsHundreds> <TensUnits> <TenthsHundredths> F7
    example: F0 5A 01 25 37 F7 = 125.37 bpm

Remote MIDI control messages can be fed into the Dynamic Clock module directly from other apps by sending the control messages to the 'MidiFire Clock' virtual port which is always listening to these messages. Alternatively, you can feed remote MIDI control messages into the Dynamic Clock by connecting MIDI inputs (or module outputs) to the Dynamic Clock's input connector in the usual fashion. Remote control events are processed whether the clock is running or not.

Tip - you can only ever have one instance of Dynamic Clock on the canvas at one time.

Tip - if you save a scene with the clock currently running, then when you load that scene later, the clock will autostart.

Stream Byter


The Stream Byter started out as a way for us to extend MidiBridge 'out in the field' for customers, but gradually moved to be one of the most used (and infamous) aspects of MidiBridge. Following on from our experiences and suggestions, MidiFire implements a new backwards compatible but much more advanced Stream Byter module.

You use the Stream Byter to program your own custom MIDI processing modules which you can then go on to re-use again and again.

With power comes complexity, so the Stream Byter has a bit of a learning curve and you also need to understand the MIDI protocol. Many customers have mastered the Stream Byter but we do recognise it is somewhat esoteric. Therefore we offer to provide assistance in writing Stream Byter rules via email or via our soapbox forum for those that have better things to do with their time.

If however, you are not daunted by a bit of complexity, then here is 'the gory detail' (that's a nod to the PERL manual) for reference purposes.

Tip - if you're looking for the syntax for specific rules, then here is a handy set of links for you: Stream Byter I, Stream Byter II, Variables/Values, Conditionals, Assign, Send, Maths, Labels

Stream Byter (MidiBridge version)

This first section of the Stream Byter reference covers the MidiBridge version of the Stream Byter to which MidiFire is (almost completely) backwards compatible. This section was lifted (with slight modification) from the MidiBridge manual and we've kept it mostly intact for posterity reasons.

Some of the things you can do with the MidiBridge Stream Byter are:

  • Map any MIDI event to any other MIDI event including type, channel and value.
  • Create up to 128 non-contiguous zones per channel.
  • Create overlapping zones.
  • Split controller messages into channelised zones.
  • Use note events to change scenes.
  • More precise blocking of events than the event filter.

This is hardly an exhaustive list, but with flexibility comes some complexity, and to use the Stream Byter you do need an understanding of the MIDI protocol, but fear not, as because it is possible to paste rules from an email, we can help by designing rulesets for what you are trying to achieve and email them to you.

We have also produced a detailed tutorial for creating Stream Byter rulesets (on our website) and you can also post queries about this (and of course anything MidiBridge related) on our support forum, again, see our website.

Stream Byter

The Stream Byter panel contains an editable text window for you to define rules to match and act on MIDI events. One rule per line is permitted and you can comment your rules by preceding your commentary with a '#' symbol.

Once you have entered your rules, you press the 'Install Rules' button which checks your rules for validity. If any rules are incorrect, these are marked with 'ERR' and are commented out. To fix a rule with an error, simply edit the line (no need to remove the '#ERR' part!) and press the 'Install Rules' button to try again.

Each rule consists of two clauses, separated by one '=' sign.

The clause to the left of the '=' is the input clause where you specify which MIDI events are to be considered.

The clause to the right of the '=' is the output clause where you specify what happens to an event when it matches the input clause.

You can also specify flags at the end of the output clause:

  • +C - clone the incoming message and apply the output clause to the clone.
  • +B - block the incoming message if it matches the input clause
  • +Dnnn - delay the event by nnn milliseconds

Both input and output clauses are constructed by 1,2 or 3 separate hex bytes depending upon the nature of the rule. Here are some simple examples:

# remap all controller events coming in on channel 1 to channel 2
B0 = B1

# clone all controller events coming in on channel 1 to channel 2
B0 = B1 +C

# remap controller 7 on channel 0 to controller 6 on channel 1
B0 07 = B1 06

# remap note C-2 to program change 0 (on channel 1)
90 00 = C0 00

You can also specify wildcards and ranges in the incoming clause:

  • The value 'N' in the first nibble of the first byte represents note on and note offs (ie. 8 or 9)
  • The value 'X' in the first nibble of the first byte represents all event types.
  • The first nibble of the first byte (type) can be set with a range of types to match. (0-F)
  • The value 'X' in the second nibble of the first byte represents any channel.
  • The value 'XX' for the second or third bytes represent any value. (00-7F)
  • The second nibble of the first byte (channel) can be set with a range of channels to match. (0-F)

Here are some examples of wildcards:

# rewrite all events on channel 1 to channel 2
X0 = X1

# rewrite all note on/off messages on channel 1 to channel 2
N0 = X1

# collapse all notes on all channels to channel 1
NX = X0

# block active sense messages
FE = XX +B

# control controllers 6 and 7 with controller 6
BX 06 = XX 07 +C

# rewrite all program changes to program change 1 on same channel
CX XX = XX 01 

You'll note that you can use 'X' and 'XX' wildcards in the output clause. This signifies that the incoming corresponding value of the event is to be preserved.

You can also replace byte 2 with byte 3 (and vice versa) by specifying 'X2' and 'X3' for the values of byte 2 or 3 in the output clause.

You can specify ranges of values using the '-' sign inbetween low and high values for type (8-F), channel (0-F), number (00-7F) and value (00-7F). Examples:

# remap all events on channels 1-8 to channel 9
X0-8 = X9

# limit the max velocity on all notes on channel 2
N1 XX 40-7F = XX XX 40

These examples are quite simple and are to provide a foundation for writing more useful real-world rules. Again, please do look at our tutorial, post to our forum or email us if you would like help in creating custom rules for your requirements. There is no doubt that this module is not for the beginner.

Finally, some caveats to be aware of when writing rules:

  • Rules are evaluated top to bottom and the results of each rule are fed into the next (unless the clone flag is set).
Stream Byter II (MidiFire extensions)

MidiFire extends the MidiBridge Stream Byter with many oft-requested features and incorporates a slightly different way of specifying rules. You can mix and match Stream Byter I and II rules in most circumstances.

Also, in the new freeform module paradigm, you can create multiple Stream Byter modules to operate in series or parallel.

Let's start with some basics:


Each Stream Byter module has it's own set of 4x256 16 bit unsigned integer local variable arrays (prefixed by I, J, K and L) and there is a 1x256 global variable array (prefixed by G) shared among all Stream Byter modules. The current MIDI message being processed is also addressed as an unsigned 8 bit array (max size 65536 bytes) prefixed by the letter M. Each variable letter is followed by a 2 (or 4) letter hex number that marks the position in the array starting from 00. Some examples:

L00        - local array L, 1st index
I2A        - local array I, 43rd index
G72        - global array G, 115th index
M03        - message byte number 4 (counting from 1) 
M1234      - message byte number 4661 (sysex message!)    

A special variable ML contains the length of the current MIDI message, Special variable MC contains the MIDI channel (0-F) of the current message (although this returns F0 if the message is not a channelised message). Special variable MT contains the MIDI type/status ([8-F]0) of the current message (ie. the first nibble of the first byte, with any channel removed). None of these variables can be assigned to; treat as read-only.

Another special variable 'R' returns a random number from 0 to (nnn is hex number or variable)). This variable may not be assigned directly.

Variables can be indirect, much like an indirect cell in excel or a pointer in C. An indirect variable is a variable (as above, except ML/MC/MT) prefixed by G, M or I-L. Again, this might be better shown by example:

GL0  - global array G, index is that of the value stored in variable L0
       (local array L, 1st index)
MG03 - MIDI message array, index is that of the value stored in the variable
G03  - (global array G, 4th index)

Variables can be used in conditional blocks, send commands, assign directives and maths directives (all explained below). Variables cannot be used in Stream Byter 1 rules.

Timer Variables

A special set of 8 'timer' variables, T00 to T07 are also available. These let you do timing calculations inside the Stream Byter.

Each time you refer to a timer variable, the value returned will be the number of milliseconds elapsed since that timer variable was last referenced.

The first time you refer to a timer variable after a scene load, it will return 0 milliseconds.

As the timer variables are 16 bit, the maximum time interval is 65.535 seconds.

Tip - the values of variables are not reset when you press the 'Install Rules' button, but they are reset during a scene load.'


A value is either a variable (as above) or a literal value (00-FFFF)

Conditionals (IF/END)

A conditional block is a set of rules that will only be evaluated/executed if the condition is true. An IF must be terminated by an END to mark the end of the conditional. For example:

# see if the current MIDI message 
# is a program change on MIDI channel 1
IF M0 == C0 # compare 1st msg byte with 'C0' literal
  # do something

The conditional expression (after the IF) is defined as

<value> <operator> <value> [<value> [<value>] [<value>]] [+L]

An operator can be one of:

==, !=, <, <=, >, >=

If more than one value is specified after the operator (max 4) then the left hand value should be a variable and each right hand variable corresponds to an incremental index. Example:

IF M12 == 64 32 G01
  # do something

This compares M12 against 64, M13 against 32 and M14 against G01 and only if all 3 are equal is the condition true. This is useful for identifying specific sysex messages that you wish to modify as they pass through.

Conditionals can be nested to make an 'and':

IF M00 == B0
  IF M01 < 20 30

or in series as an 'or'

IF G0 > 01
IF G0 <= 01

The '+L' flag indicates that the condition is to execute in a loop. When control reaches the matching END, instead of proceeding to the following rule, control is instead passed back to the original IF line where the condition is evaluated again. If the condition is (still) true, then the IF clause is executed again. If the condition is false, control jumps to the next rule after the matching END. Note, to avoid nasty hangs if an infinite loop is accidentally programmed, a looped conditional will not loop more than 128 times. '

Finally, there is a special condition called 'LOAD' which is always true when a module is loaded (either when the app starts or is in a scene that is recalled). This lets you initialise or do stuff before any messages are processed. Inside a LOAD block, the M variable array is not available, since there is no MIDI message:

# inject program change 2/ch1 with 2s delay on load
SND C0 01 +I +D2000
Send (SND)

You use the SND command to issue an arbitrary MIDI message:

SND <value> [<value> {<value> ...}] [+I] [+F] [+Dnnnn]

Here are some examples

SND C0 01     # send PC 1 to module's output
SND M0 M1 7F  # send current message with 3rd byte fixed to 127
SND G0 L0 L1  # send a MIDI message constructed from global/local variables

The maximum number of bytes that can be sent in the one SND rule is 16.

In addition, you can specify an '+I' flag at the end of a SND. Normally a SND just sends the message out of the module into the next. If you specify the +I (inject) flag, then the message is injected 'at the top' as if it was received from the current message's MIDI port (or the MidiFire virtual port in a LOAD block). Use the +I flag to auto-select a scene change (for example).

Normally, MidiFire will check that what you are trying to send is a valid MIDI message. Sometimes, you might wish to make up a long sysex message and need to split over multiple SND lines. You can disable to validation checking using the +F (force) flag.

Finally you can delay the SND by using the +Dnnn flag (where nnn is a decimal value in ms), so +D2000 means with a 2 second delay. Note that if +I is not set, the delay is added as the message leaves MidiFire and goes to CoreMIDI (not delayed as it leaves the module). If the +I flag is set, then MidiFire will wait for the delay time before doing the inject.

Assign (ASS)

Assign is used to set the value(s) of array variables:

ASS <value> = <value> [<value> ...] [+P]

Like conditionals, by specifying multiple values to the right of the '=' is a fast way of setting multiple values in an array:

ASS L0 = 12              # assign '12' to L0
ASS L0 = 01 02 03 04     # assign 01 to L0, 02 to L1, 03 to L2, 04 to L3
ASS G0 = M0              # assign value in M0 to G0
ASS GL0 = 12             # assign '12' to array G indexed by value of L0
ASS K0 = 00 +P           # assign 0 to K0, the value of K0 is preserved

The '+P' flag indicates that the array values being assigned to should be preserved in the scene or between app invocations. When the scene is loaded or the app is restarted, the preserved value will be restored into the array value. You may only specify the +P flag where you are assigning to the global or local arrays directly.

Maths (MAT)

MAT commands are a single assign but with two operands and a mathematical operator:

MAT <variable> = <value> <operator> <value>

operators are:

+, -, *, /, &, |, ^ and %
MAT L0 = L0 + 1  # increment L0 by 1
MAT G0 = L3 % L4 # assign value of L3 modulo value of L4 to variable G0
Set label (SET)

You can set the value of the two 'info' labels on the Stream Byter block using a SET rule:

SET [LB0|LB1] <value>|S<string> [+D] [+N]

Where LB0 is the left label and LB1 is the right label.

Value is as defined above (literal or variable)

You can set the label to an arbitrary string by prefixing with 'S'

The optional +D flag means display the value in decimal (default is hex)

The optional +N flag means display the value as a note name

# set left block label to the hex 32
SET LB0 32

# set right block label to the value stored in byte 3 of the current message
SET LB1 M02 +D 

# set left block label to the string 'ON'

# set right block label to name of incoming note
IF M00 >= 90
  IF M00 <= 9F
	IF M02 > 00
      SET LB1 M01 +N
Advanced Examples

Finally, here are some examples of more advanced ways of using the Stream Byter

# controller value remap table
  ASS L00 = 10 10 10 10 10 10 10 10 12 12 12 12 12 12 12 12
  ASS L10 = 10 10 10 10 10 10 10 10 12 12 12 12 12 12 12 12
  ASS L20 = 10 10 10 10 10 10 10 10 12 12 12 12 12 12 12 12
  ASS L30 = 10 10 10 10 10 10 10 10 12 12 12 12 12 12 12 12
  ASS L40 = 10 10 10 10 10 10 10 10 12 12 12 12 12 12 12 12
  ASS L50 = 10 10 10 10 10 10 10 10 12 12 12 12 12 12 12 12
  ASS L60 = 10 10 10 10 10 10 10 10 12 12 12 12 12 12 12 12
  ASS L70 = 10 10 10 10 10 10 10 10 12 12 12 12 12 12 12 12
# remap value of CH1/CC7
IF M0 == B0 07
  ASS M2 LM2
# when loaded play C3 3 times (looping)
  ASS L0 = 2
  SND 90 3C 40 +I
  SND 80 3C 00 +D500 +I
IF M0 == 90
  IF L0 > 0
    SND 90 3C 40 +I +D1000
    SND 80 3C 00 +I +D1500
  IF L0 != 0
    MAT L0 = L0 - 1

5a. 'Niche' Modules


We have included a few specific purpose modules based on our own ideas and work we have done for other customers. These may be useful to others.

Tracking Clamp


The Tracking Clamp module is designed to reduce the artefacts of MIDI guitar signals (ie. miss-hits). It does this in two ways:

  • Velocity Compression
  • The clamp monitors the incoming MIDI signal and compresses outlying velocity values based on previous notes. This makes your note volumes smoother and miss-hit notes will not stand out so greatly.

  • Artefact Removal
  • The clamp monitors the incoming MIDI signal and blocks notes that are a long way from the previous notes that were played. This reduces the incidence of 'harmonic' miss-hits.

You can set the clamp to perform both velocity compression and artefact removal.

Adjusting the 'degree' parameter changes how many notes are examined to establish the 'norm' and for how long the norm is held in place. Best way to adjust this is with trial and error as playing styles vary.

Tip - when using a MIDI guitar and the Robotic Knob put a clamp before the Robotic Knob to tame the signal.

Robotic Knob


The Robotic Knob module monitors your playing and generates complementary CC messages that can be fed forward to apps or outboard FX to control sound parameters. The Knob can react to note velocity, keyboard position, MIDI guitar fretboard position (eg. Fishman Triple Play) and pitchbend.

The types of things you can do with this module are up to your imagination! You could cross fade between sounds as you move up/down the keyboard/fretboard, open up a delay (and close) as you pitchbend up or increase chorus the softer you play. It's like having a roadie with unlimited fingers automatically adjusting knobs on your gear based on your playing.

Tip - you can have loads of Robotic Knobs all monitoring different aspects of your playing and adjusting in real time for some very crazy control of your sound.

  • trigger type (default: Note On Velocity)
  • The trigger type parameter tells the Robotic Knob what type of event you wish to have monitored. The possible values are:
    • Note On Velocity
    • The Knob will generate CC messages based upon how hard you play notes.

    • Keyboard Position
    • The Knob will generate CC messages based upon where in the MIDI keyboard range you are currently playing (from low to high).

    • FTP Fretboard Position
    • For owners of a Fishman Triple Play unit, this generates CC messages based upon which fret you are currently playing (from 0 to 24).

    • Pitch Bend
    • This generates CC messages based on pitch bend information coming from your controller (from -64 to +64)

  • trigger from, to (default: depends upon type)
  • This parameter specifies the trigger event range that you wish the Knob to react to. Only when incoming events are within that range will CCs be generated.

  • delta limit (default: none)
  • This parameter allows you to set a maximum limit within which CCs will be issued. If the current trigger event is 'delta limit' greater than the previous trigger event, then no complementary CC is generated. You can use this parameter to prevent sudden CC changes when you move a large distance on the fret or keyboard.

  • oob clamp (default: Both)
  • This parameter determines what will happen if a trigger event is outside of the from, to range. If the oob (out of bounds) clamp is full, then events outside of the range will trigger the minimum or maximum CC to be sent. If set to None, then no CC is sent if the trigger is out of range. If set to Lower then the minimum value is sent if the trigger is less than minimum. If set to Upper then the maximum value is sent if less than maximum.

  • output CC, channel (default: CC7, channel 1)
  • Use these two parameters to set the CC number and channel of the complementary CCs that will be issued.

  • initial CC value (default: none)
  • You can set the initial CC value that you want sent when the module is loaded. ie. set the initial CC value on load.

  • output from, to (default: 0 - 127)
  • This sets the range of the value byte of the complementary CCs. The Knob will scale the input event (based on trigger from, to) to this range.

  • output smoothing (default: None)
  • As complementary CCs are generated you can generate 'inbetween' CCs as the CC value moves from one value to another to make smooth graduations in change.

  • smoothing speed (default: Immediate)
  • If output smoothing is enabled then you can specify how quickly the inbetween CCs are issued during the smoothing process. With this you can control how slowly or quickly the complementary CCs ramp up or down.

OSC Exchange


The OSC Exchange accepts OSC data, packages it up into MIDI sysex and then transmits over a MIDI channel to another MidiFire instance which then unpacks and forwards on the OSC messages at the other end.

Use this module to link OSC apps/gear over a wifi, bluetooth, DIN cable or USB MIDI connection (eg. musicIO).

  • udp send port (default: 0)
  • Packaged OSC data received by the module is sent out on this UDP port. If the value is 0, then nothing is sent.

  • udp receive port (default: 0)
  • The module will listen to OSC packets coming from this udp port and then package off and send the OSC data in sysex packets out of the module for forwarding elsewhere. If the value is 0, then the module will not be listening.

  • max MIDI rate (default: 8000 bytes/s)

    In some circumstances you may need to limit the bandwidth used in sending the OSC data. Specify a value here if packets are getting lost, or set it to 0 for no rate limiting at all.

In Conclusion


You've made it to the bottom of what has turned out to be a very long and in-depth manual! If you're still having problems or just have questions, please do contact us at apps@audeonic.com or join us on the Audeonic Soapbox (forum) at http://soapbox.audeonic.com

As a parting note, we hope you find MidiFire useful and would like to thank you for downloading it.

We would really appreciate it if you could take a little bit of time and rate and review MidiFire on the App Store to assist others who may be considering downloading the app and of course (hopefully) augmenting the development team's egos.

Tip - HTML was authored by hand in Dublin, Ireland

-- end