mididings - Documentation
Table of Contents
Basics
mididings configuration files are just Python scripts, although mididings uses some of Python's features in ways
for which they weren't intended ;)
Basically, the MIDI processing setup is defined in Python, while the actual event processing is done entirely
in C++. It is however possible to explicitly call back into Python, if necessary.
Functions
config(**kwargs)
Changes global mididings settings. This should be called only once, before constructing any processing units.
Possible keyword arguments are:
- client_name: MIDI client name to be used.
- in_ports/out_ports: Integers indicating the number of input/output ports to create (named in_n
or out_n), or lists of port names, in which case the list's length determines the number of ports.
- data_offset: 1 (default) or 0. Determines whether program, port and channel numbers will be
in the range 1-128 or 0-127.
- octave_offset: Default is 2, meaning that "Middle C" is designated as C3.
- start_delay: The number of seconds before sending any MIDI events (i.e. switching to the first patch).
A small value like 0.5 can be used to give tools like qjackctl's patchbay time to connect the ports.
A value of 0 instructs mididings to wait for the user to press enter. Default is None.
run(patch)
Starts the actual MIDI processing. This is usually the last function called by a mididings script.
run_patches(patches, control=None, pre=None, post=None)
- patches: A dictionary with program numbers as keys, and patches as values.
Values can also be tuple with two items, the first being an init-patch that's executed once every time the
patch is selected, and the second being the actual patch that processes incoming events.
- control: The "control" patch, which is always active, and run in parallel to the current patch.
- pre/post: Allows processing to take place before/after every patch. Does not affect
the control patch.
switch_patch(number)
Switches to another patch. This function is similar to the PatchSwitch() object, but can be called from Python.
Making connections
A >> B
Connects two units in series. Incoming MIDI events will be processed by unit A first, then by unit B.
If the event is filtered out by unit A, it is not processed any further, and unit B will not be called.
[ A, B, ... ]
Connects two or more units in parallel. All units will be called with identical copies of incoming MIDI
events. The output will be the sum of all the units' outputs.
{ T1: A, T2: B, ... }
Splits by event type. Equivalent to [ Filter(T1) >> A, Filter(T2) >> B, ... ].
Units
These are the basic building blocks from which you can build your patches. They can roughly be divided into 4 categories:
- Filters: These units filter by some property of the MIDI event. If the event matches, it's passed
unmodified, otherwise it's discarded.
Events of different types (e.g. a note event going through a CtrlFilter) are also discarded.
Filters can be inverted by prepending operator ~.
- Splits: Basically just combinations of multiple filters of the same kind.
- Modifiers: These units change some property of the MIDI event.
- Miscellaneous: Anything that doesn't fit into any of the other categories :)
Filters
Filter(type, ...)
Filters by one or more event types.
Types must be one of: NOTE, NOTEON, NOTEOFF, CTRL, PITCHBEND, PROGRAM.
PortFilter(port, ...)
ChannelFilter(channel, ...)
Filters by event port or channel.
KeyFilter(key)
KeyFilter(lower, upper)
KeyFilter(range)
Filters by key or key-range. Keys can be MIDI note numbers or note names (e.g. 'g#3').
Ranges can be 2-tuples of note numbers, or note names (e.g. 'g#3:c6').
VelocityFilter(min, max)
Filters by note velocity.
CtrlFilter(num, ...)
Filters by CC number.
CtrlValueFilter(value)
CtrlValueFilter(min, max)
Filters by CC value.
ProgFilter(num, ...)
Filters by PC number.
Splits
PortSplit({port: units, ...})
ChannelSplit({channel: units, ...})
Splits by port or channel.
KeySplit(key, units_lower, units_upper)
KeySplit({(lower, upper): units, ...})
KeySplit({range: units, ...})
Splits by key. Non-note events are sent to all units.
VelocitySplit(threshold, units_lower, units_upper)
VelocitySplit({(min, max): units, ...})
Splits by velocity. Non-note events are sent to all units.
Modifiers
Port(port)
Channel(channel)
Changes port or channel.
Transpose(offset)
Transposes all note events.
Velocity(offset)
VelocityFixed(value)
Changes velocity, either by adding an offset, or by setting it to a fixed value.
VelocityCurve(gamma)
Applies a "gamma"-curve to all velocity values.
VelocityGradient(note_lower, note_upper, value_lower, value_upper)
VelocityGradientFixed(note_lower, note_upper, value_lower, value_upper)
Changes velocity, using a gradient from lower to upper.
CtrlRange(num, out_min, out_max, in_min=0, in_max=127)
Maps controller range in to out.
CtrlChange(num, value)
CtrlChange(port, channel, num, value)
ProgChange(program)
ProgChange(port, channel, program)
Changes the type of the event.
If port and channel are omitted, the values of the input event are used.
To "reuse" values from the incoming event, the following constants can be used in place of any parameter:
EVENT_PORT, EVENT_CHANNEL, EVENT_DATA1, EVENT_DATA2, EVENT_NOTE, EVENT_VELOCITY, EVENT_PARAM, EVENT_VALUE, EVENT_PROGRAM.
Miscellaneous
Pass()
Does nothing.
Discard()
Discards all events.
PatchSwitch()
PatchSwitch(number)
Switches to another patch.
number should be a patch number, or one of the EVENT_* constants.
Without parameters, the program number of the incoming event (should be a program change) will be used.
Call(function)
Calls a python function, with the event as its only argument.
The event is an object with the following attributes, all of which can be both read and written:
- type_: The event type, one of NOTEON, NOTEOFF, CTRL, PITCHBEND, PROGRAM.
- port_: The event port.
- channel_: The event channel.
- data1, data2: Data bytes, meaning depends on event type.
There are also aliases for these attributes, some of which are only meaningful for certain types of events:
- port: Event port. Unlike port_, this value is affected by the data_offset setting.
- channel: Event channel. Unlike channel_, this value is affected by the data_offset setting.
- note: Note number, alias for data1.
- velocity: Note velocity, alias for data2.
- param: Controller number, alias for data1.
- value: Controller parameter, alias for data2.
- program: Program number, alias for data2. Unlike data2, this value is affected by the data_offset setting.
The function should return True to continue processing the event, or False to discard it.
Print()
Print(name)
Prints event data.
Sanitize()
Makes sure the event is a valid MIDI message. Events with invalid port, channel, controller, program or note number are
discarded, note velocity and controller values are confined to the range 0-127.
Examples