Skip to main content

A lightweight, focused MIDI library for Python

Project description

PicoMidi Logo

PicoMidi

A lightweight, focused MIDI library for Python

License: MIT Python


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

  1. Lightweight: Minimal dependencies, focused on core MIDI protocol
  2. Type-safe: Use dataclasses and type hints throughout
  3. Composable: Messages can be easily combined and extended
  4. Well-tested: Each module should have comprehensive tests
  5. 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

picomidi-0.1.0.tar.gz (9.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

picomidi-0.1.0-py3-none-any.whl (8.4 kB view details)

Uploaded Python 3

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

Hashes for picomidi-0.1.0.tar.gz
Algorithm Hash digest
SHA256 89f3d2c814fd8a6096ca642c8fd007bc82c48caec44b136b43912c82a9747b0f
MD5 6694c6c07a1d68ddda35fd0b0b7d07a5
BLAKE2b-256 432b27558dd5ba2a4e11fd9a46cccad5152a38aee84cd39c0da095651f520a01

See more details on using hashes here.

Provenance

The following attestation bundles were made for picomidi-0.1.0.tar.gz:

Publisher: python-publish.yml on markxbrooks/PicoMidi

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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

Hashes for picomidi-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 6f287af8b9a846357a43451e210d94a7009400a8dc70b2271a60c62829185c0d
MD5 3d6904719ac1778bde5d5bd519ca083f
BLAKE2b-256 9b355442bcee3625becffa2c15fd2fc3bb90af4c5dff42a307322e004d1a3718

See more details on using hashes here.

Provenance

The following attestation bundles were made for picomidi-0.1.0-py3-none-any.whl:

Publisher: python-publish.yml on markxbrooks/PicoMidi

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page