Files
NCBM 9009a7c5bc Add type stubs for mido MIDI library
- Created type stubs for various modules in the mido library including messages, midifiles, parser, ports, sockets, syx, tokenizer, and version.
- Implemented type hints for functions and classes to improve type checking and code clarity.
- Added support for MIDI over TCP/IP in sockets module.
- Included methods for reading and writing SYX files in syx module.
- Enhanced the parser functionality with a dedicated Parser class for MIDI byte streams.
- Established a structure for MIDI file handling with MidiFile and MidiTrack classes.
2026-04-26 00:51:40 +08:00

238 lines
6.7 KiB
Python

"""
MIDI Objects for Python
Mido is a library for working with MIDI messages and ports. It's
designed to be as straight forward and Pythonic as possible.
Creating messages:
Message(type, **parameters) -- create a new message
MetaMessage(type, **parameters) -- create a new meta message
UnknownMetaMessage(type_byte, data=None, time=0)
Ports:
open_input(name=None, virtual=False, callback=None) -- open an input port
open_output(name=None, virtual=False, -- open an output port
autoreset=False)
open_ioport(name=None, virtual=False, -- open an I/O port (capable
callback=None, autoreset=False) of both input and output)
get_input_names() -- return a list of names of available input ports
get_output_names() -- return a list of names of available output ports
get_ioport_names() -- return a list of names of available I/O ports
MIDI files:
MidiFile(filename, **kwargs) -- open a MIDI file
MidiTrack() -- a MIDI track
bpm2tempo() -- convert beats per minute to MIDI file tempo
tempo2bpm() -- convert MIDI file tempo to beats per minute
merge_tracks(tracks) -- merge tracks into one track
SYX files:
read_syx_file(filename) -- read a SYX file
write_syx_file(filename, messages,
plaintext=False) -- write a SYX file
Parsing MIDI streams:
parse(bytes) -- parse a single message bytes
(any iterable that generates integers in 0..127)
parse_all(bytes) -- parse all messages bytes
Parser -- MIDI parser class
Parsing objects serialized with str(message):
parse_string(string) -- parse a string containing a message
parse_string_stream(iterable) -- parse strings from an iterable and
generate messages
Sub modules:
ports -- useful tools for working with ports
For more on MIDI, see:
http://www.midi.org/
Getting started:
>>> import mido
>>> m = mido.Message('note_on', note=60, velocity=64)
>>> m
<message note_on channel=0, note=60, velocity=64, time=0>
>>> m.type
'note_on'
>>> m.channel = 6
>>> m.note = 19
>>> m.copy(velocity=120)
<message note_on channel=0, note=60, velocity=64, time=0>
>>> s = mido.Message('sysex', data=[byte for byte in range(5)])
>>> s.data
(0, 1, 2, 3, 4)
>>> s.hex()
'F0 00 01 02 03 04 F7'
>>> len(s)
7
>>> default_input = mido.open_input()
>>> default_input.name
'MPK mini MIDI 1'
>>> output = mido.open_output('SD-20 Part A')
>>>
>>> for message in default_input:
... output.send(message)
>>> get_input_names()
['MPK mini MIDI 1', 'SH-201']
"""
from collections.abc import Callable
from . import ports, sockets
from .backends.backend import Backend
from .messages import (
MAX_PITCHWHEEL,
MAX_SONGPOS,
MIN_PITCHWHEEL,
MIN_SONGPOS,
BaseMessage,
Message,
format_as_string,
parse_string,
parse_string_stream,
)
from .midifiles import (
KeySignatureError,
MetaMessage,
MidiFile,
MidiTrack,
UnknownMetaMessage,
bpm2tempo,
merge_tracks,
second2tick,
tempo2bpm,
tick2second,
)
from .parser import Parser, parse, parse_all
from .syx import read_syx_file, write_syx_file
from .version import version_info
__all__ = [
"MAX_PITCHWHEEL",
"MAX_SONGPOS",
"MIN_PITCHWHEEL",
"MIN_SONGPOS",
"KeySignatureError",
"Message",
"MetaMessage",
"MidiFile",
"MidiTrack",
"Parser",
"UnknownMetaMessage",
"bpm2tempo",
"format_as_string",
"merge_tracks",
"parse",
"parse_all",
"parse_string",
"parse_string_stream",
"ports",
"read_syx_file",
"second2tick",
"sockets",
"tempo2bpm",
"tick2second",
"version_info",
"write_syx_file",
]
def set_backend(name: str | Backend | None = ..., load: bool = False) -> None:
"""Set current backend.
name can be a module name like `'mido.backends.rtmidi'` or
a `Backend` object.
If no name is passed, the default backend will be used.
This will replace all the `open_*()` and `get_*_name()` functions
in top level mido module. The module will be loaded the first
time one of those functions is called."""
backend: Backend
def open_input(
name: str | None = ...,
virtual: bool = False,
callback: Callable[[BaseMessage], object] | None = ...,
**kwargs: object,
) -> ports.BaseInput:
"""Open an input port.
If the environment variable MIDO_DEFAULT_INPUT is set,
it will override the default port.
virtual=False
Passing True opens a new port that other applications can
connect to. Raises IOError if not supported by the backend.
callback=None
A callback function to be called when a new message arrives.
The function should take one argument (the message).
Raises IOError if not supported by the backend.
"""
def open_output(
name: str | None = ..., virtual: bool = False, autoreset: bool = False, **kwargs: object
) -> ports.BaseOutput:
"""Open an output port.
If the environment variable MIDO_DEFAULT_OUTPUT is set,
it will override the default port.
virtual=False
Passing True opens a new port that other applications can
connect to. Raises IOError if not supported by the backend.
autoreset=False
Automatically send all_notes_off and reset_all_controllers
on all channels. This is the same as calling `port.reset()`.
"""
def open_ioport[TIn: ports.BaseInput = ports.BaseInput, TOut: ports.BaseOutput = ports.BaseOutput](
name: str | None = ...,
virtual: bool = False,
callback: Callable[[BaseMessage], object] | None = ...,
autoreset: bool = False,
**kwargs: object,
) -> ports.BaseIOPort | ports.IOPort[TIn, TOut]:
"""Open a port for input and output.
If the environment variable MIDO_DEFAULT_IOPORT is set,
it will override the default port.
virtual=False
Passing True opens a new port that other applications can
connect to. Raises IOError if not supported by the backend.
callback=None
A callback function to be called when a new message arrives.
The function should take one argument (the message).
Raises IOError if not supported by the backend.
autoreset=False
Automatically send all_notes_off and reset_all_controllers
on all channels. This is the same as calling `port.reset()`.
"""
def get_input_names(**kwargs: object) -> list[str]:
"""Return a list of all input port names."""
def get_output_names(**kwargs: object) -> list[str]:
"""Return a list of all output port names."""
def get_ioport_names(**kwargs: object) -> list[str]:
"""Return a list of all I/O port names."""