Ports
A Mido port is an object that can send and/or receive messages.
You can open a port by calling one of the open methods, for example:
>>> inport = mido.open_input('SH-201')
>>> outport = mido.open_output('Integra-7')
Now you can receive messages on the input port and send messages on the output port:
>>> msg = inport.receive()
>>> outport.send(msg)
The message is copied by send()
, so you can safely modify your
original message without causing breakage in other parts of the
system.
In this case, the ports are device ports, and are connected to some
sort of (physical or virtual) MIDI device, but a port can be
anything. For example, you can use a MultiPort
to receive messages
from multiple ports as if they were one:
from mido.ports import MultiPort
...
multi = MultiPort([inport1, inport2, inport3])
for msg in multi:
print(msg)
This will receive messages from all ports and print them out. Another example is a socket port, which is a wrapper around a TCP/IP socket.
No matter how the port is implemented internally or what it does, it will look and behave like any other Mido port, so all kinds of ports can be used interchangeably.
Warning
Sending and receiving messages is thread safe. Opening and closing ports and listing port names are not.
Common
How to open a port depends on the port type. Device ports (PortMidi, RtMidi and others defined in backends) are opened with the open functions, for example:
port = mido.open_output()
Input and I/O ports (which support both input and output) are opened
with open_input()
and open_ioport()
respectively. If you call
these without a port name like above, you will get the - system
specific - default port. You can override this by setting the
MIDO_DEFAULT_OUTPUT
etc. environment variables.
To get a list of available ports, you can do:
>>> mido.get_output_names()
['SH-201', 'Integra-7']
and then:
>>> port = mido.open_output('Integra-7')
There are corresponding functions for input and I/O ports.
To learn how to open other kinds of ports, see documentation of the relevant port type.
The port name is available in port.name
.
To close a port, call:
port.close()
or use the with
statement to have the port closed automatically:
with mido.open_input() as port:
for message in port:
do_something_with(message)
You can check if the port is closed with:
if port.closed:
print("Yup, it's closed.")
If the port is already closed, calling close()
will simply do nothing.
Output
Output ports basically only have one method:
outport.send(message)
This will send the message immediately. (Well, the port can choose to do whatever it wants with the message, but at least it’s sent from Mido’s point of view.)
There are also a couple of utility methods:
outport.reset()
This will send “all notes off” and “reset all controllers” on every channel. This is used to reset everything to the default state, for example after playing back a song or messing around with controllers.
If you pass autoreset=True
to the constructor, reset()
will be
called when the port closes:
with mido.open_output('Integra-7') as outport:
for msg in inport:
outport.send(msg)
# reset() is called here
outport.close() # or here
Sometimes notes hang because a note_off
has not been sent. To
(abruptly) stop all sounding notes, you can call:
outport.panic()
This will not reset controllers. Unlike reset()
, the notes will
not be turned off gracefully, but will stop immediately with no regard
to decay time.
Input
To iterate over incoming messages:
for msg in port:
print(msg)
This will iterate over messages as they arrive on the port until the port closes. (So far only socket ports actually close by themselves. This happens if the other end disconnects.)
You can also do non-blocking iteration:
for msg in port.iter_pending():
print(msg)
This will iterate over all messages that have already arrived. It is typically used in main loops where you want to do something else while you wait for messages:
while True:
for msg in port.iter_pending():
print(msg)
do_other_stuff()
In an event based system like a GUI where you don’t write the main loop you can install a handler that’s called periodically. Here’s an example for GTK:
def callback(self):
for msg in self.inport:
print(msg)
gobject.timeout_add_seconds(timeout, callback)
To get a bit more control you can receive messages one at a time:
msg = port.receive()
This will block until a message arrives. To get a message only if one is available, you can use poll():
msg = port.poll()
This will return None
immediately if no message is available.
Deprecated since version 1.2: There used to be a pending()
method which returned the number of
pending messages.
It was removed for three reasons:
with
poll()
anditer_pending()
it is no longer necessaryit was unreliable when multithreading and for some ports it doesn’t even make sense
it made the internal method API confusing. _send() sends a message so _receive() should receive a message.
Callbacks
Instead of manually reading from the port you can install a callback function which will be called for every message that arrives.
Here’s a simple callback function:
def print_message(message):
print(message)
To install the callback you can either pass it when you create the
port or later by setting the callback
attribute:
port = mido.open_input(callback=print_message)
port.callback = print_message
...
port.callback = another_function
Warning
Since the callback runs in a different thread you may need to use locks or other synchronization mechanisms to keep your main program and the callback from stepping on each other’s toes.
Calling receive()
, __iter__()
, or iter_pending()
on a port
with a callback will raise an exception:
ValueError: a callback is set for this port
To clear the callback:
port.callback = None
This will return the port to normal.
API
Todo
Add abstract code to describe these interfaces.
Common Methods and Attributes
close()
Closes the port. If the port is already closed this will simply do nothing.
name
Name of the port or None
.
closed
True
if the port is closed.
Output Port Methods
send(message)
Sends a message.
reset()
Sends “all notes off” and “reset all controllers” on all channels.
panic()
Sends “all sounds off” on all channels. This will abruptly end all sounding notes.
Input Port Methods
receive(block=True)
Receives a message. This will block until it returns a message. If
block=False
is passed it will instead return None
if there is
no message.
poll()
Returns a message, or None
if there are no pending messages.
iter_pending()
Iterates through pending messages.
__iter__()
Iterates through messages as they arrive on the port until the port closes.
Socket Ports - MIDI over TCP/IP
About
Socket ports allows you to send MIDI messages over a computer network.
The protocol is a simple MIDI bytes stream over TCP.
Warning
It is not rtpmidi!
Caveats
The data is sent over an unencrypted channel. Also, the default server allows connections from any host and also accepts arbitrary sysex messages, which could allow anyone to for example overwrite patches on your synths (or worse). Use only on trusted networks.
If you need more security, you can build a custom server with a whitelist of clients allowed to connect.
If timing is critical, latency and jitter (especially on wireless networks) may make socket ports unusable.
Sending Messages to a Server
First, let’s import some things:
from mido.sockets import PortServer, connect
After that, a simple server is only two lines:
for message in PortServer('localhost', 8080):
print(message)
You can then connect to the server and send it messages:
output = connect('localhost', 8080):
output.send(message)
Each end of the connection behaves like a normal Mido I/O port, with all the usual methods.
The host may be an host name or IP address (as a string). It may also be ‘’, in which case connections are accepted from any IP address on the computer.
Todo
Test and clarify “Any IP address on the computer”. Does this mean only local adresses can connect or that any connection from any network is allowed?
Turning Things on their Head
If you want the server to send messages the client, you can instead do:
server = PortServer('localhost', 8080):
while True:
server.send(message)
...
and then on the client side:
for message in connect('localhost', 8080):
print(message)
The client will now print any message that the server sends. Each message that the server sends will be received by all connected clients.
Under the Hood
The examples above use the server and client ports as normal Mido I/O ports. This makes it easy to write simple servers, but you don’t have any control on connections and the way messages are sent and received.
To get more control,you can ignore all the other methods of the
PortServer
object and use only accept()
. Here’s a simple
server implemented this way:
with PortServer('localhost', 8080) as server:
while True:
client = server.accept()
for message in client:
print(message)
accept()
waits for a client to connect, and returns a SocketPort
object which is connected to the SocketPort
object returned by
connect()
on the other end.
The server above has one weakness: it only allows one connection at a
time. You can get around this by using accept(block=False)
. This
will return a SocketPort
if there’s a connection waiting and None
if
there is connection yet.
Todo
Clarify “Connection waiting” vs “There is a connection yet”.
Using this you can write the server any way you like, for example:
with PortServer('localhost', 8080) as server:
clients = []
while True:
# Handle connections.
client = server.accept(block=False)
if client:
print('Connection from {}'.format(client.name))
clients.append(client)
for i, client in reversed(enumerate(clients)):
if client.closed:
print('{} disconnected'.format(client.name))
del clients[i]
# Receive messages.
for client in clients:
for message in client.iter_pending()
print('Received {} from {}'.format(message, client))
# Do other things
...
Possible Future Additions
Optional HTTP-style headers could be added. As long as these are 7-bit ASCII, they will be counted as data bytes and ignored by clients or servers who don’t expect them.
Writing a New or Custom Port
The Mido port API allows you to write new ports to do practically anything.
A new port type can be defined by subclassing one of the base classes and overriding one or more methods. Here’s an example:
from mido.ports import BaseOutput
class PrintPort(BaseOutput):
def _send(message):
print(message)
>>> port = PrintPort()
>>> port.send(msg)
note_on channel=0 note=0 velocity=64 time=0
_send()
will be called by send()
, and is responsible for
actually sending the message somewhere (or in this case print it out).
Overridable Methods
There are four overridable methods (all of them default to doing nothing):
``_open(self, **kwargs)``
Should do whatever is necessary to initialize the port (for example opening a MIDI device.)
Called by
__init__()
. Thename
attribute is already set when_open()
is called, but you will get the rest of the keyword arguments.If your port takes a different set of arguments or has other special needs, you can override
__init__()
instead.
_close(self)
Should clean up whatever resources the port has allocated (such as closing a MIDI device).
Called by
close()
if the port is not already closed.
_send(self, message)
(Output ports only.)
Should send the message (or do whatever else that makes sense).
Called by
send()
if the port is open and the message is a Mido message. (You don’t need any type checking here.)Raise IOError if something goes wrong.
_receive(self, block=True)
(Input ports only.)
Should return a message if there is one available.
If
block=True
it should block until a message is available and then return it.If
block=False
it should return a message orNone
if there is no message yet. If you returnNone
the enclosingpending()
method will checkself._messages
and return one from there.Note
Prior to 1.2.0 ``_receive()
would put messages inself._messages
(usually via the parser) and rely onreceive()
to return them to the user.Since this was not thread safe the API was changed in 1.2.0 to allow the
_receive()
to return a message. The old behavior is still supported, so old code will work as before.Raise IOError if something goes wrong.
Each method corresponds to the public method of the same name, and will be called by that method. The outer method will take care of many things, so the inner method only needs to do the very minimum. The outer method also provides the doc string, so you don’t have to worry about that.
The base classes are BaseInput
, BaseOutput
and BaseIOPort
(which is a subclass of the other two.)
Locking
The calls to _receive()
and _send()
will are protected by a
lock, left.lock
. As a result all send and receive will be thread
safe.
Note
If your _receive()
function actually blocks instead of
letting the parent class handle it poll()
will not
work. The two functions are protected by the same lock, so
when receive()
blocks it will also block other threads
calling poll()
. In this case you need to implement your
own locking.
If you want to implement your own thread safety you can set the
_locking
attribute in your class:
class MyInput(ports.BaseInput):
_locking = False
...
An example of this is mido.backends.rtmidi
where the callback is
used to feed an internal queue that receive()
reads from.
Examples
An full example of a device port for the imaginary MIDI library
fjopp
:
import fjopp
from mido.ports import BaseIOPort
# This defines an I/O port.
class FjoppPort(BaseIOPort):
def _open(self, **kwargs):
self._device = fjopp.open_device(self.name)
def _close(self):
self._device.close()
def _send(self, message):
self.device.write(message.bytes())
def _receive(self, block=True):
while True:
data = self.device.read()
if data:
self._parser.feed(data)
else:
return
If fjopp
supports blocking read, you can do this to actually block
on the device instead of letting receive()
and friends poll and
wait for you:
def _receive(self, block=True):
if block:
# Actually block on the device.
# (``read_blocking()`` will always return some data.)
while not ``self._messages``:
data = self._device.read_blocking()
self._parser.feed(data)
else:
# Non-blocking read like above.
while True:
data = self.device.read()
if data:
self._parser.feed(data)
This can be used for any kind of port that wants to block on a pipe,
an socket or another input source. Note that Mido will still use
polling and waiting when receiving from multiple ports (for example in
a MultiPort
).
If you want separate input and output classes, but the _open()
and
_close()
methods have a lot in common, you can implement this
using a mix-in.
Sometimes it’s useful to know inside the methods whether the port
supports input or output. The way to do this is to check for the
methods `send()
and receive()
, for example:
def _open(self, **kwargs):
if hasattr(self, 'send'):
# This is an output port.
if hasattr(self, 'receive'):
# This is an input port.
if hasattr(self, 'send') and hasattr(self, 'receive'):
# This is an I/O port.
Attributes
A port has some attributes that can be useful inside your methods.
name
The name of the port. The value is device specific and does not have to be unique. It can have any value, but must be a string or
None
.This is set by
__init__()
.
closed
True if the port is closed. You don’t have to worry about this inside your methods.
_messages
This is a
collections.deque
of messages that have been read and are ready to be received. This is a shortcut to_parser.messages
.
_device_type
(Optional.)
If this attribute exists, it’s a string which will be used in
__repr__()
. If it doesn’t exist, the class name will be used instead.