Skip to main content

Visual MIDI controller mapper that exports a JSON profile for programmatic control of hardware controllers.

Project description

midicraft

Visual editor for mapping the physical layout of a MIDI controller (buttons, knobs, pad grids...) and exporting a self-contained JSON profile that can be used to programmatically control the device — send LED colors, react to inputs — from any code, without midicraft.

Installation

pip install midicraft

Launch

midicraft

How it works

  1. Recreate the physical layout of your controller on the canvas (drag & drop from the palette)
  2. Map each element to its MIDI binding via MIDI learn (click Learn, press the physical control)
  3. Assign LED behaviors per element from the catalog or define custom color→value tables
  4. Save the profile as JSON

The exported profile is self-sufficient: it contains everything needed to drive the controller from external code.

JSON profile format

Example of a mapped button:

{
  "element_type": "grid_button",
  "control_id": "46e33976",
  "label": "Clip 1",
  "x": 0, "y": 0, "width": 1.0, "height": 1.0,
  "binding": { "kind": "NOTE", "number": 36, "channel": 0 },
  "led_behavior_key": "CUSTOM",
  "parent_id": null,
  "custom_led_values": [
    ["Orange blinking", 12],
    ["Green solid", 3],
    ["Off", 0]
  ]
}
  • binding: how to address the control — kind (NOTE or CONTROL_CHANGE), number, channel (0-indexed)
  • custom_led_values: color label → MIDI value pairs
  • control_id: internal unique identifier, also used to link children via parent_id

Using the profile from Python:

import mido, json

profile = json.load(open("my_controller.json"))
out = mido.open_output("CMD LC-1")

# Light up "Clip 1" in orange blinking
btn = next(e for e in profile["elements"] if e["label"] == "Clip 1")
value = dict(btn["custom_led_values"])["Orange blinking"]  # 12
out.send(mido.Message("note_on", channel=btn["binding"]["channel"],
                       note=btn["binding"]["number"], velocity=value))

Architecture

  • Separate MIDI thread: listens to the input port continuously, classifies each message and pushes it into a thread-safe queue.Queue. Never touches Tkinter widgets directly.
  • Main thread (Tkinter): drains the queue at a regular interval (root.after(15, ...)) and updates the UI.
  • LED catalog decoupled from layout: an element references a behavior by key, not by duplicating values. Two buttons on the same controller can reference completely different behaviors.
  • Grid coordinates, not pixels: x/y/width/height are expressed in logical grid units, converted to pixels only at render time. A profile remains valid regardless of display size.

Canvas features

  • Drag & drop from the palette onto the canvas (with ghost preview)
  • Smooth element movement with grid snap on release, collision detection
  • Scroll: scrollbars + mousewheel (Shift+wheel for horizontal)
  • N×M grid groups (1×5, 4×4, 8×8...) that move as one block, with individually mappable cells
  • Pre-fill grids with buttons or knobs at creation time
  • MIDI learn per element/cell
  • Visual flash on MIDI input in normal mode

License

Copyright (c) 2026 Mehdi.A — AGPL-3.0-or-later

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

midicraft-0.3.0.tar.gz (48.9 kB view details)

Uploaded Source

Built Distribution

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

midicraft-0.3.0-py3-none-any.whl (51.7 kB view details)

Uploaded Python 3

File details

Details for the file midicraft-0.3.0.tar.gz.

File metadata

  • Download URL: midicraft-0.3.0.tar.gz
  • Upload date:
  • Size: 48.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.15

File hashes

Hashes for midicraft-0.3.0.tar.gz
Algorithm Hash digest
SHA256 4f9a00fea988ec4190347b2a46dadf02d9f85b90988a73481ad1fbc4779631a9
MD5 1bca6beacd2cf9974ceb2c27534ca215
BLAKE2b-256 86702b5ed9b42c6e1be9489a6aa9504b4f3bb5f88ca3f6748da788522ebd41bc

See more details on using hashes here.

File details

Details for the file midicraft-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: midicraft-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 51.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.15

File hashes

Hashes for midicraft-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 36ae0031ce69a2bf5e2351a50702f15f67cfa2738f517949e30c5637d6cabe80
MD5 612377c002957f0fbbcab25133644ef0
BLAKE2b-256 80f2f18b101668e9a7046e0a233db386540636f0beb4ddfe0cfb4030f2049856

See more details on using hashes here.

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