Skip to main content

Python parser and MIDI generator for the Alda music programming language

Project description

aldakit

PyPI version Python 3.10+ License: MIT

A zero-dependency Python parser and MIDI generator for the Alda music programming language[^1].

[^1]: Includes a rich repl and native MIDI support via bundled prompt-toolkit and libremidi respectively.

Installation

Requires Python 3.10+

pip install aldakit

Or with uv:

uv add aldakit

Quick Start

Command Line

# Evaluate inline code
aldakit -e "piano: c d e f g"

# Interactive REPL
aldakit repl

# Play an Alda file (examples available in the repository)
aldakit examples/twinkle.alda

# Export to MIDI file
aldakit examples/bach-prelude.alda -o bach.mid

Python API

from aldakit import parse, generate_midi, LibremidiBackend

# Parse Alda source code
ast = parse("""
piano:
  (tempo 120)
  o4 c4 d e f | g a b > c
""")

# Generate MIDI sequence
sequence = generate_midi(ast)

# Save to file
backend = LibremidiBackend()
backend.save(sequence, "output.mid")

# Or play directly
with LibremidiBackend() as backend:
    backend.play(sequence)

CLI Reference

aldakit [-h] [--version] [-e CODE] [-o FILE] [--port NAME]
       [--stdin] [--parse-only] [--no-wait] [-v]
       {repl,ports,play} [file]

Subcommands

Command Description
repl Interactive REPL with syntax highlighting and auto-completion
ports List available MIDI output ports
play Play an Alda file or code (default behavior)

Options

Option Description
file Alda file to play (use - for stdin)
-e, --eval CODE Evaluate Alda code directly
-o, --output FILE Save to MIDI file instead of playing
--port NAME MIDI output port name
--stdin Read from stdin (blank line to play)
--parse-only Print AST without playing
--no-wait Don't wait for playback to finish
-v, --verbose Verbose output

Examples

# Interactive REPL with syntax highlighting
aldakit repl

# List available MIDI ports
aldakit ports

# Play with verbose output
aldakit -v examples/jazz.alda

# Read from stdin
echo "piano: c d e f g" | aldakit -

# Parse and show AST
aldakit --parse-only -e "piano: c/e/g"

# Export to MIDI file
aldakit examples/twinkle.alda -o twinkle.mid

Interactive REPL

The REPL provides an interactive environment for composing and playing Alda code:

aldakit repl

Features:

  • Syntax highlighting
  • Auto-completion for instruments (3+ characters)
  • Command history (persistent across sessions)
  • Multi-line paste (use platform-specific paste: ctrl-v, shift-ctrl-v, cmd-v, etc.)
  • Multi-line input (Alt+Enter)
  • MIDI playback control (Ctrl+C to stop)

REPL Commands:

  • :help - Show help
  • :quit - Exit REPL
  • :ports - List MIDI ports
  • :instruments - List available instruments
  • :tempo [BPM] - Show/set default tempo
  • :stop - Stop playback

Alda Syntax Reference

Notes and Rests

piano:
  c d e f g a b   # Notes
  r               # Rest
  c4 d8 e16       # With duration (4=quarter, 8=eighth, etc.)
  c4. d4..        # Dotted notes
  c500ms d2s      # Milliseconds and seconds

Accidentals

c+    # Sharp
c-    # Flat
c_    # Natural
c++   # Double sharp

Octaves

o4 c    # Set octave to 4
> c     # Octave up
< c     # Octave down

Chords

c/e/g           # C major chord
c1/e/g          # Whole note chord
c/e/g/>c        # With octave change

Ties and Slurs

c1~1            # Tied notes (duration adds)
c4~d~e~f        # Slurred notes (legato)

Parts

piano: c d e

violin "v1": c d e    # With alias

violin/viola/cello "strings":   # Multi-instrument
  c d e

Attributes

(tempo 120)     # Set tempo (BPM)
(tempo! 120)    # Global tempo

(vol 80)        # Volume (0-100)
(volume 80)

(quant 90)      # Quantization/legato (0-100)

(panning 50)    # Pan (0=left, 100=right)

# Dynamic markings
(pp) (p) (mp) (mf) (f) (ff)

Variables

riff = c8 d e f g4

piano:
  riff riff > riff

Repeats

c*4             # Repeat note 4 times
[c d e]*4       # Repeat sequence
[c d e f]*8     # 8 times

Cram (Tuplets)

{c d e}4        # Triplet in quarter note
{c d e f g}2    # Quintuplet in half note
{c {d e} f}4    # Nested cram

Voices

piano:
  V1: c4 d e f
  V2: e4 f g a
  V0:           # End voices

Markers

piano:
  c d e f
  %chorus
  g a b > c

violin:
  @chorus       # Jump to chorus marker
  e f g a

Supported Instruments

All 128 General MIDI instruments are supported. Common examples:

  • piano, acoustic-grand-piano
  • violin, viola, cello, contrabass
  • flute, oboe, clarinet, bassoon
  • trumpet, trombone, french-horn, tuba
  • acoustic-guitar, electric-guitar-clean, electric-bass
  • choir, strings, brass-section

See midi/types.py for the complete mapping.

MIDI Backend

aldakit uses libremidi via nanobind for cross-platform MIDI I/O:

  • Low-latency realtime playback
  • Virtual MIDI port support (AldaPyMIDI), makes it easy to just send to your DAW.
  • Pure Python MIDI file writing (no external dependencies)
  • Cross-platform: macOS (CoreMIDI), Linux (ALSA), Windows (WinMM)
  • Supports hardware and software/virtual MIDI ports (FluidSynth, IAC Driver, etc.)
from aldakit import LibremidiBackend

backend = LibremidiBackend()

# List available ports
print(backend.list_output_ports())

# Play to virtual port (visible in DAWs like Ableton Live)
backend.play(sequence)

# Save to MIDI file
backend.save(sequence, "output.mid")

MIDI Playback Setup

Virtual Port (Recommended)

When no hardware MIDI ports are available, aldakit creates a virtual port named "AldaPyMIDI". This port is visible to DAWs and other MIDI software:

  1. Start the REPL: aldakit repl
  2. In your DAW (Ableton Live, Logic Pro, etc.), look for "AldaPyMIDI" in MIDI input settings
  3. Play code in the REPL - notes will be sent to your DAW

Software Synthesizer (FluidSynth)

For high-quality General MIDI playback without hardware, use FluidSynth:

# Install FluidSynth (macOS)
brew install fluidsynth

# Install FluidSynth (Debian/Ubuntu)
sudo apt install fluidsynth 

# Download a SoundFont (e.g., FluidR3_GM.sf2)
# eg. sudo apt install fluid-soundfont-gm
# Place in ~/Music/sf2/

# Start FluidSynth with CoreMIDI (macOS)
fluidsynth -a coreaudio -m coremidi ~/Music/sf2/FluidR3_GM.sf2

# In another terminal, start aldakit
aldakit repl
# aldakit> piano: c d e f g

A helper script is available in the repository:

# Set the SoundFont directory (add to your shell profile)
export ALDAPY_SF2_DIR=~/Music/sf2

# Run with default SoundFont (FluidR3_GM.sf2)
python scripts/fluidsynth-gm.py

# Or specify a SoundFont directly
python scripts/fluidsynth-gm.py /path/to/soundfont.sf2

# List available SoundFonts
python scripts/fluidsynth-gm.py --list

Hardware MIDI

Connect a USB MIDI interface or synthesizer, then:

# List available ports
aldakit ports

# Play to a specific port
aldakit --port "My MIDI Device" examples/twinkle.alda

MIDI File Export

If you don't have MIDI playback set up, export to a file:

# Save to MIDI file
aldakit examples/twinkle.alda -o twinkle.mid

# Open with default app
open twinkle.mid

Development

Setup

git clone https://github.com/shakfu/aldakit.git
cd aldakit
make  # Build the libremidi extension

Run Tests

make test
# or
uv run pytest tests/ -v

Architecture

aldakit architecture

License

MIT

See Also

  • Alda - The original Alda language and reference implementation
  • Alda Cheat Sheet - Syntax reference
  • Extending aldakit - Design document for programmatic API
  • libremidi - A modern C++ MIDI 1 / MIDI 2 real-time & file I/O library. Supports Windows, macOS, Linux and WebMIDI.
  • nanobind - a tiny and efficient C++/Python bindings

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

aldakit-0.1.3.tar.gz (1.2 MB view details)

Uploaded Source

Built Distributions

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

aldakit-0.1.3-cp314-cp314-macosx_15_0_arm64.whl (569.6 kB view details)

Uploaded CPython 3.14macOS 15.0+ ARM64

aldakit-0.1.3-cp313-cp313-macosx_15_0_arm64.whl (569.6 kB view details)

Uploaded CPython 3.13macOS 15.0+ ARM64

aldakit-0.1.3-cp312-cp312-macosx_15_0_arm64.whl (569.6 kB view details)

Uploaded CPython 3.12macOS 15.0+ ARM64

aldakit-0.1.3-cp311-cp311-macosx_15_0_arm64.whl (570.7 kB view details)

Uploaded CPython 3.11macOS 15.0+ ARM64

aldakit-0.1.3-cp310-cp310-macosx_15_0_arm64.whl (570.8 kB view details)

Uploaded CPython 3.10macOS 15.0+ ARM64

File details

Details for the file aldakit-0.1.3.tar.gz.

File metadata

  • Download URL: aldakit-0.1.3.tar.gz
  • Upload date:
  • Size: 1.2 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.2

File hashes

Hashes for aldakit-0.1.3.tar.gz
Algorithm Hash digest
SHA256 051523bd57c8dccccbbbe99fcf52f28b19b077efda9ed152fd46cb7fed145521
MD5 18f0589dfa7310b3813cc5b703666126
BLAKE2b-256 e1e1eda4f6a291f2bbf586c1c7ef3b637d0de8ded513e0549b44049fe653795e

See more details on using hashes here.

File details

Details for the file aldakit-0.1.3-cp314-cp314-macosx_15_0_arm64.whl.

File metadata

File hashes

Hashes for aldakit-0.1.3-cp314-cp314-macosx_15_0_arm64.whl
Algorithm Hash digest
SHA256 5729cdb0af150f62c23331f6371aca72d126fb15aadb1f3e358d86c9adb8c15d
MD5 fc487bd7cdf95550ab55cf79f79a8720
BLAKE2b-256 331a9dc83b46adbb1602a1d2290988a1869a2c7d263e35dccd6f00b844c3b2af

See more details on using hashes here.

File details

Details for the file aldakit-0.1.3-cp313-cp313-macosx_15_0_arm64.whl.

File metadata

File hashes

Hashes for aldakit-0.1.3-cp313-cp313-macosx_15_0_arm64.whl
Algorithm Hash digest
SHA256 01a4a15f99d4bd5744934f7d0692e8560c4fda57539b46f7384a0d63576875d3
MD5 b183ff71a8647b564838780f9b953c63
BLAKE2b-256 41ce19ff8e4f79320e9015e29af5e08cbfc76a625b8d7efada4a70ef583846a7

See more details on using hashes here.

File details

Details for the file aldakit-0.1.3-cp312-cp312-macosx_15_0_arm64.whl.

File metadata

File hashes

Hashes for aldakit-0.1.3-cp312-cp312-macosx_15_0_arm64.whl
Algorithm Hash digest
SHA256 403198396f1dfca80b58447d799a6dada5beae7b4e64150aa872899ee31741a8
MD5 94c681ad97aeed054fa9485b338433d5
BLAKE2b-256 f3c2ae7a6bfc8f1307fb0ea4f5a440c737402a03801cff99200de980d2f49878

See more details on using hashes here.

File details

Details for the file aldakit-0.1.3-cp311-cp311-macosx_15_0_arm64.whl.

File metadata

File hashes

Hashes for aldakit-0.1.3-cp311-cp311-macosx_15_0_arm64.whl
Algorithm Hash digest
SHA256 c025e214034e40e160397f3ed110204d162bf2e95b1c95d551b89756aa965e22
MD5 c7ad9a1f8f162812b32f5322f0722d87
BLAKE2b-256 bc0b5bb1da1e8d027ddf9a57e3f335f5d8eb045c7b7c51346756f0e465c6420d

See more details on using hashes here.

File details

Details for the file aldakit-0.1.3-cp310-cp310-macosx_15_0_arm64.whl.

File metadata

File hashes

Hashes for aldakit-0.1.3-cp310-cp310-macosx_15_0_arm64.whl
Algorithm Hash digest
SHA256 d3e870caa119e058db859ab1a6e2f982da3b9c5e60247944b7923d2b687c119d
MD5 b00c8891e6690510f0d3d7cd4365e90b
BLAKE2b-256 a27bdd8216def8cc864a9a2ae24c76b84248f4ed8fe33753331818860f33606f

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