Files
termidi/typings/mido/midifiles/midifiles.pyi
T

155 lines
5.5 KiB
Python
Raw Normal View History

2026-04-26 00:51:40 +08:00
"""
MIDI file reading and playback.
References:
http://home.roadrunner.com/~jgglatt/
http://home.roadrunner.com/~jgglatt/tech/miditech.htm
http://home.roadrunner.com/~jgglatt/tech/midifile.htm
http://www.sonicspot.com/guide/midifiles.html
http://www.ccarh.org/courses/253/assignment/midifile/
https://code.google.com/p/binasc/wiki/mainpage
http://stackoverflow.com/questions/2984608/midi-delta-time
http://www.recordingblogs.com/sa/tabid/82/EntryId/44/MIDI-Part-XIII-Delta-time-a
http://www.sonicspot.com/guide/midifiles.html
"""
from collections.abc import Callable, Generator, Iterable, Sequence
from numbers import Real
from typing import IO, Literal, Never, Self, overload
from ..messages import BaseMessage, Message
from .meta import MetaMessage, UnknownMetaMessage
from .tracks import MidiTrack
type _RealNumber = int | float | Real
# The default tempo is 120 BPM.
# (500000 microseconds per beat (quarter note).)
DEFAULT_TEMPO: int = 500000
DEFAULT_TICKS_PER_BEAT: int = 480
# Maximum message length to attempt to read.
MAX_MESSAGE_LENGTH: int = 1000000
def print_byte(byte: int, pos: int = 0) -> None: ...
class DebugFileWrapper:
def __init__(self, file: IO[bytes]) -> None: ...
def read(self, size: int) -> bytes: ...
def tell(self) -> int: ...
def read_byte(self: IO[bytes]) -> int: ...
def read_bytes(infile: IO[bytes], size: int) -> list[int]: ...
def read_chunk_header(infile: IO[bytes]) -> tuple[str, int]: ...
def read_file_header(infile: IO[bytes]) -> tuple[int, int, int]: ...
def read_message(
infile: IO[bytes], status_byte: int, peek_data: Sequence[int], delta: int, clip: bool = False
) -> Message: ...
def read_sysex(infile: IO[bytes], delta: int, clip: bool = False) -> Message: ...
def read_variable_int(infile: IO[bytes]) -> int: ...
def read_meta_message(infile: IO[bytes], delta: int) -> MetaMessage | UnknownMetaMessage: ...
def read_track(infile: IO[bytes], debug: bool = False, clip: bool = False) -> MidiTrack: ...
def write_chunk(outfile: IO[bytes], name: bytes, data: bytes) -> None:
"""Write an IFF chunk to the file.
`name` must be a bytestring."""
def write_track(outfile: IO[bytes], track: Iterable[BaseMessage]) -> None: ...
def get_seconds_per_tick(tempo: _RealNumber, ticks_per_beat: _RealNumber) -> float: ...
class MidiFile:
filename: str | None
type: Literal[0, 1, 2]
ticks_per_beat: int
charset: str
debug: bool
clip: bool
tracks: list[MidiTrack]
def __init__(
self,
filename: str | None = ...,
file: IO[bytes] | None = ...,
type: Literal[0, 1, 2] = 1,
ticks_per_beat: int = DEFAULT_TICKS_PER_BEAT, # noqa: PYI011
charset: str = "latin1",
debug: bool = False,
clip: bool = False,
tracks: list[MidiTrack] | None = ...,
) -> None: ...
@property
def merged_track(self) -> MidiTrack: ...
@merged_track.deleter
def merged_track(self) -> None: ...
def add_track(self, name: str | None = ...) -> MidiTrack:
"""Add a new track to the file.
This will create a new `MidiTrack` object and append it to the
track list.
"""
@property
def length(self) -> int | float:
"""Playback time in seconds.
This will be computed by going through every message in every
track and adding up delta times.
"""
def __iter__(self) -> Generator[Message | MetaMessage | UnknownMetaMessage, Never]: ...
@overload
def play(
self, meta_messages: Literal[False] = False, now: Callable[[], float] = ...
) -> Generator[Message, Never]: ...
@overload
def play(
self, meta_messages: bool, now: Callable[[], float] = ...
) -> Generator[Message | MetaMessage | UnknownMetaMessage, Never]: ...
def play(
self, meta_messages: bool = False, now: Callable[[], float] = ...
) -> Generator[Message | MetaMessage | UnknownMetaMessage, Never]:
"""Play back all tracks.
The generator will sleep between each message by
default. Messages are yielded with correct timing. The time
attribute is set to the number of seconds slept since the
previous message.
By default you will only get normal MIDI messages. Pass
`meta_messages=True` if you also want meta messages.
You will receive copies of the original messages, so you can
safely modify them without ruining the tracks.
By default the system clock is used for the timing of yielded
MIDI events. To use a different clock (e.g. to synchronize to
an audio stream), pass `now=time_fn` where `time_fn` is a zero
argument function that yields the current time in seconds.
"""
def save(self, filename: str | None = ..., file: IO[bytes] | None = ...) -> None:
"""Save to a file.
If file is passed the data will be saved to that file. This is
typically an in-memory file or and already open file like `sys.stdout`.
If filename is passed the data will be saved to that file.
Raises `ValueError` if both file and filename are None,
or if a type 0 file has != one track.
"""
def print_tracks(self, meta_only: bool = False) -> None:
"""Prints out all messages in a .midi file.
May take argument `meta_only` to show only meta messages.
Use:
`print_tracks()` -> will print all messages
`print_tracks(meta_only=True)` -> will print only MetaMessages
"""
def __enter__(self) -> Self: ...
def __exit__(self, type: object, value: object, traceback: object) -> Literal[False]: ...