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.2.tar.gz (9.2 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.2-py3-none-any.whl (8.3 kB view details)

Uploaded Python 3

File details

Details for the file picomidi-0.1.2.tar.gz.

File metadata

  • Download URL: picomidi-0.1.2.tar.gz
  • Upload date:
  • Size: 9.2 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.2.tar.gz
Algorithm Hash digest
SHA256 a9c12e428a87cba30fd1566856c4d71749c248d12b747783ed1c753f3b8d546f
MD5 6569d4e50d7dd72db8557e5503668cd2
BLAKE2b-256 b5f45dbe82ac6aed643b361661c0295f8038446872c3b2ee61a708d1b0d31432

See more details on using hashes here.

Provenance

The following attestation bundles were made for picomidi-0.1.2.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.2-py3-none-any.whl.

File metadata

  • Download URL: picomidi-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 8.3 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.2-py3-none-any.whl
Algorithm Hash digest
SHA256 9a19b06dab78a3b35cb7ccccbbd0e3b4715cb52321b0d8d6d4185c8c9790954b
MD5 4a840b62df1aadaf3b1c58bede301f4b
BLAKE2b-256 6e2404143d9e26cc05a47dc1d611c82fab46974184b7422ec15c67f1bac7a0bd

See more details on using hashes here.

Provenance

The following attestation bundles were made for picomidi-0.1.2-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