9009a7c5bc
- 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.
82 lines
2.3 KiB
Python
82 lines
2.3 KiB
Python
"""
|
|
MIDI Parser
|
|
|
|
There is no need to use this module directly. All you need is
|
|
available in the top level module.
|
|
"""
|
|
|
|
from collections import deque
|
|
from collections.abc import Generator, Iterable
|
|
from numbers import Integral
|
|
from typing import Never
|
|
|
|
from .messages import Message
|
|
|
|
class Parser:
|
|
"""
|
|
MIDI byte stream parser
|
|
|
|
Parses a stream of MIDI bytes and produces messages.
|
|
|
|
Data can be put into the parser in the form of
|
|
integers, byte arrays or byte strings.
|
|
"""
|
|
|
|
messages: deque[Message]
|
|
|
|
def __init__(self, data: Iterable[int] | None = ...) -> None: ...
|
|
def feed(self, data: Iterable[int]) -> None:
|
|
"""Feed MIDI data to the parser.
|
|
|
|
Accepts any object that produces a sequence of integers in
|
|
range 0..255, such as:
|
|
|
|
```
|
|
[0, 1, 2]
|
|
(0, 1, 2)
|
|
[for i in range(256)]
|
|
(for i in range(256)]
|
|
bytearray()
|
|
```
|
|
"""
|
|
|
|
def feed_byte(self, byte: int | Integral) -> None:
|
|
"""Feed one MIDI byte into the parser.
|
|
|
|
The byte must be an integer in range 0..255.
|
|
"""
|
|
|
|
def get_message(self) -> Message | None:
|
|
"""Get the first parsed message.
|
|
|
|
Returns None if there is no message yet. If you don't want to
|
|
deal with None, you can use `pending()` to see how many messages
|
|
you can get before you get None, or just iterate over the
|
|
parser.
|
|
"""
|
|
|
|
def pending(self) -> int:
|
|
"""Return the number of pending messages."""
|
|
|
|
def __len__(self) -> int:
|
|
"""Return the number of pending messages."""
|
|
|
|
def __iter__(self) -> Generator[Message, Never]:
|
|
"""Yield messages that have been parsed so far."""
|
|
|
|
def parse_all(data: Iterable[int] | None) -> list[Message]:
|
|
"""Parse MIDI data and return a list of all messages found.
|
|
|
|
This is typically used to parse a little bit of data with a few
|
|
messages in it. It's best to use a Parser object for larger
|
|
amounts of data. Also, tt's often easier to use `parse()` if you
|
|
know there is only one message in the data.
|
|
"""
|
|
|
|
def parse(data: Iterable[int] | None) -> Message | None:
|
|
"""Parse MIDI data and return the first message found.
|
|
|
|
Data after the first message is ignored. Use `parse_all()`
|
|
to parse more than one message.
|
|
"""
|