Skip to main content

A stateful python interface for USB MIDI controllers.

Project description

Padbound

A general, stateful python interface for MIDI controllers that abstracts hardware differences behind a simple API.

Overview

Padbound provides a high-level abstraction over MIDI controllers, allowing applications to work with three fundamental control types (toggles, momentary triggers, continuous controls) and RGB colors without dealing with raw MIDI messages.

Features

  • Three Control Types: Toggle, Momentary, and Continuous controls with unified API
  • Progressive State Discovery: Honest representation of hardware limitations (knobs/faders start in "unknown" state)
  • Capability-Based API: Validates hardware support before attempting operations
  • Thread-Safe: Safe concurrent access from callbacks and main thread
  • Plugin Architecture: Extensible system for supporting different controllers
  • Callback System: Global, per-control, and type-based callbacks with error isolation
  • Bank Support: Handles controllers with bank switching (when supported)
  • Strict/Permissive Modes: Choose between errors or warnings for unsupported operations

Installation

pip install padbound

Quick Start

from padbound import Controller, ControlType

# Auto-detect and connect to controller
with Controller(plugin='auto', auto_connect=True) as controller:
    # Register callback for a specific pad
    controller.on_control('pad_1', lambda state: print(f"Pad 1: {state.is_on}"))

    # Register callback for all continuous controls (knobs/faders)
    def on_continuous(control_id, state):
        if state.is_discovered:
            print(f"{control_id}: {state.normalized_value:.2f}")
    controller.on_type(ControlType.CONTINUOUS, on_continuous)

    # Main loop
    while True:
        controller.process_events()

Examples

See the examples/ directory for controller-specific demos:

  • demo_akai_lpd8.py - AKAI LPD8 MK2
  • demo_akai_apc_mini_mk2.py - AKAI APC mini MK2
  • demo_presonus_atom.py - PreSonus ATOM
  • demo_xjam.py - Xjam
  • demo_x_touch_mini.py - Behringer X-Touch Mini

Callback Registration

from padbound import Controller, ControlType

with Controller(plugin='auto', auto_connect=True) as controller:
    # Per-control callback
    controller.on_control('pad_1', lambda state: print(f"Pad 1: {state.is_on}"))

    # Per-type callback (all toggles, all continuous, etc.)
    controller.on_type(ControlType.TOGGLE, lambda cid, state: print(f"{cid} toggled"))

    # Per-category callback (e.g., all transport buttons)
    controller.on_category('transport', lambda cid, state: print(f"Transport: {cid}"))

    # Global callback (all controls)
    controller.on_global(lambda cid, state: print(f"Any control: {cid}"))

    while True:
        controller.process_events()

Setting Control State

from padbound import Controller

with Controller(plugin='auto', auto_connect=True) as controller:
    # Set pad LED color and state
    if controller.can_set_state('pad_1', is_on=True, color='red'):
        controller.set_state('pad_1', is_on=True, color='red')

    # Query control state
    state = controller.get_state('pad_1')
    if state:
        print(f"Pad 1 is {'on' if state.is_on else 'off'}")

Using Configuration

from padbound import Controller, ControllerConfig, BankConfig, ControlConfig, ControlType

# Configure pad colors and types
config = ControllerConfig(banks={
    'bank_1': BankConfig(controls={
        'pad_1': ControlConfig(type=ControlType.TOGGLE, color='red', off_color='dim_red'),
        'pad_2': ControlConfig(type=ControlType.MOMENTARY, color='green'),
    })
})

with Controller(plugin='auto', config=config, auto_connect=True) as controller:
    while True:
        controller.process_events()

Supported Controllers

Capability Comparison

Controller Pads Knobs/Encoders Faders Buttons RGB LEDs LED Modes Banks Persistent Config Special Features
AKAI LPD8 MK2 8 8 knobs ✓ Full Solid 4 (HW) ✓ SysEx Multi-signal pads (NOTE/CC/PC)
AKAI APC mini MK2 64 9 17 ✓ Full Solid/Pulse/Blink 1 Fader position discovery
PreSonus ATOM 16 4 20 ✓ Full Solid/Pulse/Blink 8 (HW) Native Control mode, encoder acceleration
Xjam 16 6 3 (HW) ✓ SysEx Multi-signal pads, multiple encoder modes
X-Touch Mini 16 8 + buttons 1 Single Solid 2 (HW) Deferred LED feedback, auto-reflecting encoder rings

Legend:

  • HW = Hardware-managed bank switching
  • RGB LEDs: Full = True RGB color support, Single = On/off only
  • LED Modes: Animation/behavior modes supported
  • Persistent Config: Device stores configuration in non-volatile memory

Detailed Controller Information

AKAI LPD8 MK2

Control Surface: 8 RGB pads + 8 knobs
Banks: 4 banks with hardware-based switching
Capabilities:

  • Pad LED Feedback: Full RGB via SysEx
  • Pad LED Modes: Solid
  • Pad Modes: Toggle or momentary (global per bank)
  • Knob Feedback: None (read-only)
  • Configuration: Persistent (SysEx)

AKAI APC mini MK2

Control Surface: 8×8 RGB pad grid + 9 faders + 17 buttons
Banks: Single layer
Capabilities:

  • Pad LED Feedback: Full RGB via SysEx
  • Pad LED Modes: Solid, pulse, blink
  • Pad Modes: Toggle or momentary (per pad)
  • Fader Feedback: None (read-only, initial position discovered)
  • Button LED Feedback: Single-color (red for track, green for scene)
  • Configuration: Volatile

PreSonus ATOM

Control Surface: 16 RGB pads (4×4) + 4 encoders + 20 buttons
Banks: 8 hardware-managed banks (not software-accessible)
Capabilities:

  • Pad LED Feedback: Full RGB via Native Control mode
  • Pad LED Modes: Solid, pulse, breathe
  • Pad Modes: Toggle or momentary (per pad)
  • Encoder Type: Relative with acceleration
  • Encoder Feedback: None (read-only)
  • Button LED Feedback: Single-color
  • Configuration: Volatile

Xjam (ESI/Artesia Pro)

Control Surface: 16 pads + 6 knobs per bank
Banks: 3 banks (Green, Yellow, Red) with synchronized pad/knob switching
Capabilities:

  • Pad LED Feedback: None (hardware-managed)
  • Pad Modes: Toggle or momentary (global)
  • Knob Type: Configurable (absolute or 3 relative modes)
  • Knob Feedback: None (read-only)
  • Configuration: Persistent (SysEx)

Behringer X-Touch Mini

Control Surface: 8 encoders with buttons + 16 pads + 1 fader
Banks: 2 layers (A, B) with hardware switching
Capabilities:

  • Pad LED Feedback: Single-color
  • Pad LED Modes: Solid
  • Pad Modes: Toggle or momentary (per pad)
  • Encoder Type: Absolute
  • Encoder Feedback: LED ring auto-reflects value
  • Encoder Button Feedback: Single-color
  • Fader Feedback: None (read-only)
  • Configuration: Volatile

Documentation

TBD

Acknowledgements

Some protocol information for supported controllers was gathered from:

License

MIT License

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

padbound-0.2.0.tar.gz (223.9 kB view details)

Uploaded Source

Built Distribution

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

padbound-0.2.0-py3-none-any.whl (89.2 kB view details)

Uploaded Python 3

File details

Details for the file padbound-0.2.0.tar.gz.

File metadata

  • Download URL: padbound-0.2.0.tar.gz
  • Upload date:
  • Size: 223.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for padbound-0.2.0.tar.gz
Algorithm Hash digest
SHA256 d78903c1011e3b073a379d2e162b3e356d1190ff218d10a9c181f8c93a0804ac
MD5 fcbad1da15163ba3530a3a4818cb0084
BLAKE2b-256 e65f7bdab8edf25cf77d16a081b78a0136f9fdaa3c6c7492f33dbc15eca4930e

See more details on using hashes here.

Provenance

The following attestation bundles were made for padbound-0.2.0.tar.gz:

Publisher: release-please.yml on uermel/padbound

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

File details

Details for the file padbound-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: padbound-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 89.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for padbound-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e5d908d0a9a06defb34b12cae1dec3682bc2d23ff3f069b436e15ad71feac7ad
MD5 061da61eb5d563d6b0a895c73ab68480
BLAKE2b-256 566566373de1a5b9c6c3caed070bb39962c40205d1c89d1db2da2223547822f1

See more details on using hashes here.

Provenance

The following attestation bundles were made for padbound-0.2.0-py3-none-any.whl:

Publisher: release-please.yml on uermel/padbound

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