pytakt.midiio module

This module defines functions for real-time MIDI input/output and timers.

Devices

In Pytakt, devices to send MIDI messages (MIDI interface or application port) are called output devices, and devices to receive MIDI messages are called input devices. A list of available devices can be found with the show_devices() function. Each device is assigned an integer device number.

There is a special device called the loopback device (not shown in show_devices()). The loopback device is an output device and moreover an input device, and can receive messages sent to them by itself. It is normally used for sending and receiving LoopBackEvent’s, but can also be used for other events.

To use a device, it must be opened in advance. However, the loopback device is always available and does not need to be opened.

For input and output each, there is a currently selected device. The initial choice of this is platform specific. However, by setting the environment variables PYTAKT_OUTPUT_DEVICE and PYTAKT_INPUT_DEVICE to a string recognized by find_output_device() or find_input_device(), the initial choice can be changed.

Input and Output Queues

Inside the module, there is a queue for storing messages, which are byte sequences converted from events with Event.to_message(), for input and output each. Each message is given a timestamp and a track number. When an event is sent to an output device via the queue_event() function, the event is converted to a message, placed in the output queue, and then kept until the sending time before it is actually sent to the device. Messages from input devices are first placed in the input queue, where they are kept until retrieved by the recv_event() function. There is no limit on the size of the queues.

Timer

The module has a timer that indicates the time since the module was imported. The unit of time is the tick (a floating-point value equal to 1/480th of a quarter note), and the relationship between seconds and ticks is determined by two values: tempo (beats per minute, BPM) and tempo scale, with the following formula:

ticks = seconds * tempo * tempo_scale / 60 * 480

By default, the tempo is set to 125 BPM and the tempo scale is set to 1, thus establishing the relationship 1 tick = 1 msec. Tempo can be changed dynamically by sending a TempoEvent to any of the output devices, and the tempo scale can be changed by calling the set_tempo_scale() function.

current_output_device() int

Returns the device number of the currently selected output device.

current_input_device() int

Returns the device number of the currently selected input device.

find_output_device(dev) int

Get the output device number based on a device description.

Parameters:

dev (int, str, list, tuple) – Device description. If it is an integer, it is recognized as the device number. If it is a string representing an integer, it is converted to an integer, which is then recognized as the device number. For other forms of a string, it means a device where the string matches all or part of its device name (and whichever has the smallest device number if there are multiple matched devices). The string may be multiple device descriptions separated by semicolons, in which case the first one whose existence is confirmed is valid. If the argument is a list or tuple where each element is an integer or a string without a semicolon, it is examined starting from the first element in the same manner as a single element, and the first device whose existence is confirmed becomes valid. If no device is found, an exception is raised.

Returns:

Output device number

Examples

  • find_output_device(1)

  • find_output_device('1')

  • find_output_device('TiMidity; MIDI Mapper')

  • find_output_device([2, 0])

output_devices() List[str]

Get a list of the device names of all the output devices.

set_output_device(dev) None

Specifies dev as the currently selected output device.

Parameters:

dev – Device description recognized by find_output_device().

open_output_device(dev=None) None

Open the output device dev. This may take a little time depending on the device.

Parameters:

dev – Target output device. If None, the currently selected output device is used; otherwise, the target device is the result of calling find_output_device() with this as an argument.

close_output_device(dev=None) None

Close the output device dev.

Parameters:

dev – Target output device. If None, the currently selected output device is used; otherwise, the target device is the result of calling find_output_device() with this as argument.

is_opened_output_device(dev) bool

Returns true if the output device dev is opened, or false otherwise.

Parameters:

dev – Device description that can be recognized by find_output_device().

find_input_device(dev) int

Get the input device number based on a device description.

Parameters:

dev (int, str, list, tuple) – Device description in the same format as find_output_device().

input_devices() List[str]

Get a list of the device names of all the input devices.

set_input_device(dev) None

Specifies dev as currently selected input device.

Parameters:

dev – Device description recognized by find_intput_device().

open_input_device(dev=None) None

Open the input device dev.

The input device inserts received messages into the input queue only while it is open, and discards messages while it is closed. To avoid unintended message accumulation in the input queue, openings should be limited to the necessary period of time.

Parameters:

dev – Target input device. If None, the currently selected input device is used; otherwise, the target device is the result of calling find_input_device() with this as an argument.

close_input_device(dev=None) None

Close the input device dev.

Parameters:

dev – Target input device. If None, the currently selected input device is used; otherwise, the target device is the result of calling find_input_device() with this as argument.

is_opened_input_device(dev) bool

Returns true if the input device dev is opened, or false otherwise.

Parameters:

dev – Device description that can be recognized by find_input_device().

show_devices() None

Show the list of all the available devices.

current_time() float

Returns the current time.

Returns:

Time in ticks, being 0 when the module was imported.

current_tempo_scale() float

Returns the current tempo scale value.

Returns:

Tempo scale value

set_tempo_scale(tempo_scale) None

Changes the tempo scale value.

Parameters:

tempo_scale (float) – tempo scale value (non-negative)

queue_event(ev, time=None, devnum=None) None

Converts an event to a message (a sequence of bytes) and places the message with its sending time and track number on the output queue. The message is sent to the output device when the sending time is reached. There is no blocking (waiting for output) in this function.

Note: When queuing a TempoEvent for a tempo change, the sending time must not be earlier than the current time.

Parameters:
  • ev (Event) – The event to queue. This is converted to a message by the Event.to_message() method and placed on the output queue. If ev is a NoteEvent, two messages, one for note-on and the other for note-off, are placed (the sending time of note-off is that of note-on plus the value of the ‘du’ attribute if it exists or the L attribute otherwise). Even if the event is updated after calling this function, the queued message is not affected.

  • time (ticks, optional) – Specifies the time (in ticks) at which the message is sent. If not specified, the value of the ‘t’ attribute of ev is used.

  • devnum (int, optional) – Specifies the output device number to which the message will be sent. If not specified, the currently selected output device is used. If ev is a LoopBackEvent, the message is always sent to the loopback device regardless of this value.

recv_ready() bool

Returns true if there is a message on the input queue, or false otherwise. If this value is true, it is guaranteed that the next call to recv_event() will not be blocked.

recv_event() Optional[Event]

Receives a message from an input device and returns it as an event. All the opened input devices are subject for receiving. If there is no message in the input queue, it enters a blocking state and waits for the input. Execution is resumed whtn a message arrives or a keyboard interrupt is received.

If a message from the loopback device and a message from a normal input device arrive almost at the same time, the order of receiving may be different from the order of event times.

System messages other than exclusive messages are ignored and cannot be received.

Returns:

The event converted from the received message. Its ‘t’ attribute value is the time the message was received. Returns None when a keyboard interrupt is received.

cancel_events(tk=-1, devnum=None) None

Performs the following two operations on the specified track of the specified device.

  1. Delete all messages in the output queue.

  2. Sends messages to turn off the notes being played and the sustain pedal in use.

Parameters:
  • tk (int, optional) – Specifies the target track number. A value of -1 means all tracks.

  • devnum (int, optional) – Specifies the target output device number. If not specified, the currently selected output device is used. The loopback device cannot be specified.

stop() None

Deletes all messages in the input and output queues, as well as sends messages to turn off the notes being played and the sustain pedal in use. In addition, it will send the MIDI message below to all channels of all opened output devices, attempting to completely stop all sound from the synthesizers.

  • All notes off (control change #123)

  • Sustain pedal control with value 0 (control change #64)

  • All sounds off (control change #120)

This function is automatically called when a keyboard interrupt is received with this module imported.

play(score, dev=None) None

Plays a score. Messages are sent to the output device in sequence according to the events contained in the score. This function does not return until the time corresponding to the duration of the score has elapsed, or until a keyboard interrupt is received.

Parameters:
  • score (Score) – Score to be played. It may be an infinite-length score.

  • dev – Target output device. If None, the currently selected output device is used; otherwise, the target device is the result of calling find_output_device() with this as argument. If the specified device is not opened, it will be opened automatically.

record(indev=None, play=None, outdev=None, metro=None, monitor=False) EventList

Records a performance from an input device and returns an event list. It is also possible to record with a score being played back. This function does not return until the time corresponding to the duration of the playback score has elapsed, or until a keyboard interrupt is received.

Parameters:
  • indev – Target input device. If None, the currently selected input device is used; otherwise, the target device is the result of calling find_input_device() with this as the argument. If the specified device is not opened, it will be opened automatically. Also, it will be closed when returning from this function. If another input device other than this device is already open, events from that device will be recorded as well.

  • play (Score, optional) – The score to be played back simultaneously. It may be an infinite-length score.

  • outdev – The output device for playback. If None, the currently selected output device is used; otherwise, the target device is the result of calling find_output_device() with this as the argument.

  • metro (str, bool or Score, optional) – If specified, a metronome will be sounded. The default metronome assumes that a GM standard rhythmic instrument is assigned to MIDI channel 10. This argument can be a string representing a time signature, such as “3/4”, True (equivalent to “4/4”), or a score to play the metronome sound (e.g., record(metro=mml("ch=10 {A5 {Ab5* Ab5}/3 }@@"))).

  • monitor (bool, optional) – If True, sends messages from the input device to the output device.

Returns:

Recorded score

listen(dev=None) RealTimeStream
monitor(dev=None) None

Displays the sequence of events from the input device. This function does not return until it receives a keyboard interrupt.

Parameters:

dev – Target input device. If None, the currently selected input device is used; otherwise, the target device is the result of calling find_input_device() with this as the argument. If the specified device is not opened, it will be opened automatically. Also, it will be closed when returning from this function.