A lightweight, focused MIDI library for Python
Project description
Overview
PicoMidi provides core MIDI protocol functionality with a clean, type-safe API. Built for developers who need reliable MIDI message handling without the bloat.
Features
- Type-safe MIDI values:
Note,Velocity,ControlValue,ProgramNumber,PitchBendValue - Message classes:
NoteOn,NoteOff,ControlChange,ProgramChange,PitchBend - Parser: Convert raw MIDI bytes to message objects
- Utilities: Value conversions, validation, formatting, timing calculations
- Core constants: Status bytes, channels, bitmasks
Installation
pip install picomidi
Quick Start
Creating Messages
from picomidi import NoteOn, NoteOff, ControlChange, ProgramChange, PitchBend
from picomidi.core import Channel, Note, Velocity, ControlValue, ProgramNumber, PitchBendValue
# Create a Note On message (Middle C, full velocity, channel 1)
note_on = NoteOn(
channel=Channel.CH1,
note=Note(60), # Middle C
velocity=Velocity(127)
)
# Convert to bytes
bytes_data = note_on.to_bytes() # b'\x90<\x7f'
# Convert to hex string
hex_str = note_on.to_hex_string() # "90 3C 7F"
Using Note Names
from picomidi.core import Note
# Create note from name
note = Note.from_name("C4") # Middle C
note = Note.from_name("A#3") # A sharp, octave 3
note = Note.from_name("Bb5") # B flat, octave 5
# Convert to name
name = note.to_name() # "C4"
name = note.to_name(use_sharps=False) # "Db4" instead of "C#4"
Parsing Messages
from picomidi.parser import Parser
parser = Parser()
# Feed raw MIDI bytes
raw_bytes = b'\x90<\x7f' # Note On message
for message in parser.feed(raw_bytes):
print(message) # NoteOn(channel=1, note=Note(C4), velocity=127)
print(message.to_hex_string()) # "90 3C 7F"
Value Conversions
from picomidi.utils.conversion import (
combine_7bit_msb_lsb,
split_14bit_to_7bit,
clamp_midi_value
)
# Combine two 7-bit values into 14-bit
msb, lsb = 0x40, 0x20
value_14bit = combine_7bit_msb_lsb(msb, lsb) # 8256
# Split 14-bit value
msb, lsb = split_14bit_to_7bit(value_14bit) # (64, 32)
# Clamp values
clamped = clamp_midi_value(200) # 127 (max MIDI value)
Timing Calculations
from picomidi.utils.timing import (
bpm_to_microseconds_per_quarter,
ticks_to_milliseconds
)
# Convert BPM to microseconds per quarter note (for MIDI files)
usec = bpm_to_microseconds_per_quarter(120) # 500000
# Convert ticks to milliseconds
ms = ticks_to_milliseconds(
ticks=480,
ticks_per_beat=480,
bpm=120
) # 1000.0 (1 second)
Project Structure
picomidi/
├── core/ # Core protocol definitions
│ ├── bitmask.py # Bit masks
│ ├── constant.py # MIDI constants
│ ├── status.py # Status bytes
│ ├── channel.py # Channel handling
│ └── types.py # Type-safe value classes
├── message/ # Message classes
│ ├── base.py # Base message class
│ └── channel_voice/ # Channel voice messages
├── parser/ # Message parsing
│ └── parser.py # Parser implementation
└── utils/ # Utilities
├── conversion.py # Value conversions
├── validation.py # Value validation
├── formatting.py # Message formatting
└── timing.py # Timing calculations
Design Principles
- Lightweight: Minimal dependencies, focused on core MIDI protocol
- Type-safe: Use dataclasses and type hints throughout
- Composable: Messages can be easily combined and extended
- Well-tested: Each module should have comprehensive tests
- Documented: Clear docstrings and examples
License
This project is licensed under the MIT License - see the LICENSE file for details.
Made with ❤️ for the MIDI community
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file picomidi-0.1.0.tar.gz.
File metadata
- Download URL: picomidi-0.1.0.tar.gz
- Upload date:
- Size: 9.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
89f3d2c814fd8a6096ca642c8fd007bc82c48caec44b136b43912c82a9747b0f
|
|
| MD5 |
6694c6c07a1d68ddda35fd0b0b7d07a5
|
|
| BLAKE2b-256 |
432b27558dd5ba2a4e11fd9a46cccad5152a38aee84cd39c0da095651f520a01
|
Provenance
The following attestation bundles were made for picomidi-0.1.0.tar.gz:
Publisher:
python-publish.yml on markxbrooks/PicoMidi
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
picomidi-0.1.0.tar.gz -
Subject digest:
89f3d2c814fd8a6096ca642c8fd007bc82c48caec44b136b43912c82a9747b0f - Sigstore transparency entry: 825540078
- Sigstore integration time:
-
Permalink:
markxbrooks/PicoMidi@26306832419449257fa69b21b70ba55cf0408695 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/markxbrooks
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@26306832419449257fa69b21b70ba55cf0408695 -
Trigger Event:
release
-
Statement type:
File details
Details for the file picomidi-0.1.0-py3-none-any.whl.
File metadata
- Download URL: picomidi-0.1.0-py3-none-any.whl
- Upload date:
- Size: 8.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6f287af8b9a846357a43451e210d94a7009400a8dc70b2271a60c62829185c0d
|
|
| MD5 |
3d6904719ac1778bde5d5bd519ca083f
|
|
| BLAKE2b-256 |
9b355442bcee3625becffa2c15fd2fc3bb90af4c5dff42a307322e004d1a3718
|
Provenance
The following attestation bundles were made for picomidi-0.1.0-py3-none-any.whl:
Publisher:
python-publish.yml on markxbrooks/PicoMidi
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
picomidi-0.1.0-py3-none-any.whl -
Subject digest:
6f287af8b9a846357a43451e210d94a7009400a8dc70b2271a60c62829185c0d - Sigstore transparency entry: 825540128
- Sigstore integration time:
-
Permalink:
markxbrooks/PicoMidi@26306832419449257fa69b21b70ba55cf0408695 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/markxbrooks
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@26306832419449257fa69b21b70ba55cf0408695 -
Trigger Event:
release
-
Statement type: