Skip to main content

aldakit

PyPI version Python 3.10+ License: MIT

A Python parser and MIDI generator for the Alda music programming language, with no install-time dependencies1.

Features

  • Alda Parser - Full parser for the Alda music language with AST generation

  • MIDI Playback - Low-latency playback via libremidi (CoreMIDI, ALSA, WinMM)

  • Audio Playback - Built-in synthesis via TinySoundFont (no external synth required)

  • MIDI Export - Save compositions as Standard MIDI Files

  • Audio Export - Render a score to a WAV file, many times faster than real time

  • MIDI Import - Load MIDI files and convert to Alda notation

  • Alda Export - Serialize any AST back to Alda source, round-trip safe

  • Real-time Transcription - Record from MIDI keyboards and convert to Alda

  • Programmatic Composition - Build music with Python using the compose module

  • Music Theory - Scale, chord, and interval utilities

  • Transformers - Transpose, invert, augment, diminish, and more

  • Generative Music - Markov chains, L-systems, cellular automata, Euclidean rhythms

  • Interactive REPL - Syntax highlighting, auto-completion, and live playback

  • Score Checking - aldakit lint and aldakit info report what will sound wrong before you play it

  • SoundFont Management - Find, download and verify SoundFonts from the CLI

  • CLI Tools - Play, transcribe, and convert from the command line

Installation

Requires Python 3.10+

pip install aldakit

Or with uv:

uv add aldakit

Quick Start

Command Line

# Interactive REPL (default when no args)
aldakit

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

# Play an Alda file
aldakit play examples/twinkle.alda

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

# Use built-in audio (TinySoundFont) instead of MIDI
aldakit play -sf ~/Music/sf2/FluidR3_GM.sf2 examples/twinkle.alda
aldakit repl -sf ~/Music/sf2/FluidR3_GM.sf2

# Use audio backend with pre-configured soundfont (from config or env)
aldakit play -a examples/twinkle.alda
aldakit repl -a

# Create virtual MIDI port with custom name
aldakit repl -vp MyMIDI

# Get a SoundFont for the built-in audio backend
aldakit soundfont install

# Inspect or check a score without playing it
aldakit info examples/twinkle.alda
aldakit lint examples/twinkle.alda

Python API

import aldakit

# Play directly
aldakit.play("piano: c d e f g")

# Save to MIDI file
aldakit.save("piano: c d e f g", "output.mid")

# Render to audio, faster than real time and without an audio device
aldakit.render("piano: c d e f g", "output.wav")

# Play from file
aldakit.play_file("song.alda")

# List available MIDI ports
print(aldakit.list_ports())

For more control, use the Score class:

from aldakit import Score

score = Score("""
piano:
  (tempo 120)
  o4 c4 d e f | g a b > c
""")

# Play, blocking until finished
score.play(port="FluidSynth")

# Or play in the background and keep control of the playback
handle = score.play(port="FluidSynth", wait=False)
handle.is_playing()
handle.stop()

# Save to file
score.save("output.mid")

# Render to a WAV file
score.render("output.wav")

# Access internals
print(f"Duration: {score.duration}s")
print(score.ast)   # Parsed AST
print(score.midi)  # MIDI sequence

Concurrent Playback

Layer multiple sequences for polyphonic REPL-style playback:

from aldakit.midi.backends import LibremidiBackend

# Create backend with concurrent mode (default)
backend = LibremidiBackend(concurrent=True)

# Play multiple sequences - they layer on top of each other
backend.play(score1.midi)  # Starts immediately
backend.play(score2.midi)  # Layers on top of score1
backend.play(score3.midi)  # Up to 8 concurrent slots

# Check status
print(f"Active slots: {backend.active_slots}")
print(f"Playing: {backend.is_playing()}")

# Wait for all playback to complete
backend.wait()

# Or stop all playback immediately
backend.stop()

# Sequential mode - each play waits for previous to finish
backend.concurrent_mode = False
backend.play(score1.midi)  # Plays first
backend.play(score2.midi)  # Waits, then plays second

MIDI Import

Import existing MIDI files and work with them as Alda:

from aldakit import Score

# Import a MIDI file
score = Score.from_midi_file("recording.mid")

# Or use from_file (auto-detects .mid/.midi)
score = Score.from_file("song.mid")

# View as Alda source
print(score.to_alda())
# piano:
# o4 c4 d e f | g a b > c

# Play the imported MIDI
score.play()

# Export to Alda file
score.save("song.alda")

# Re-export to MIDI
score.save("output.mid")

# Import with custom quantization grid
# Default is 0.25 (16th notes), use 0.5 for 8th notes
score = Score.from_midi_file("recording.mid", quantize_grid=0.5)

Features:

  • Multi-track MIDI files (each channel becomes a separate part, and stays on its own channel when played or re-exported)

  • Channel 10 is imported as a midi-percussion part

  • Tempo detection and preservation

  • General MIDI instrument mapping across all 128 programs

  • Chord detection for simultaneous notes

  • Configurable timing quantization

Real-Time MIDI Transcription

Record MIDI input from a keyboard or controller:

import aldakit

# List available MIDI input ports
print(aldakit.list_input_ports())

# Record for 10 seconds from the first available port
score = aldakit.transcribe(duration=10)

# Play back what was recorded
score.play()

# Export to Alda source
print(score.to_alda())

# Record with options
score = aldakit.transcribe(
    duration=30,
    port_name="My MIDI Keyboard",
    instrument="piano",
    tempo=120,
    quantize_grid=0.25,  # Quantize to 16th notes
)

For more control, use TranscribeSession:

from aldakit.midi.transcriber import TranscribeSession

session = TranscribeSession(quantize_grid=0.25, default_tempo=120)

# Set a callback for note events (optional)
session.on_note(lambda pitch, vel, on: print(f"Note: {pitch}, vel={vel}, on={on}"))

# Start recording
session.start()

# Poll periodically (in a loop or timer)
import time
for _ in range(100):
    session.poll()
    time.sleep(0.1)

# Stop and get the recorded notes
seq = session.stop()
print(seq.to_alda())

Programmatic Composition

Build music programmatically using the compose module:

from aldakit import Score
from aldakit.compose import part, note, rest, chord, seq, tempo, volume

# Create a score from compose elements
score = Score.from_elements(
    part("piano"),
    tempo(120),
    note("c", duration=4),
    note("d"),
    note("e"),
    chord("c", "e", "g", duration=2),
)
score.play()

# Builder pattern with method chaining
score = (
    Score.from_elements(part("violin"))
    .with_tempo(90)
    .add(note("g", duration=8), note("a"), note("b"))
)

# Note transformations
c = note("c", duration=4)
c_sharp = c.sharpen()           # C#
c_up_octave = c.transpose(12)   # Up one octave

# Repeat syntax
pattern = seq(note("c"), note("d"), note("e"))
repeated = pattern * 4  # Repeat 4 times

# Export to Alda source
print(score.to_alda())  # "violin: (tempo 90) g8 a b"

Available compose elements:

  • Notes: note("c", duration=4, octave=5, accidental="+", dots=1)

  • Rests: rest(duration=4), rest(ms=500)

  • Chords: chord("c", "e", "g"), chord(note("c"), note("e", accidental="+"))

  • Sequences: seq(note("c"), note("d")), Seq.from_alda("c d e")

  • Parts: part("piano"), part("violin", alias="v1")

  • Attributes: tempo(120), volume(80), octave(5), panning(50)

  • Dynamics: pp(), p(), mp(), mf(), f(), ff()

  • Advanced: cram(), voice(), voice_group(), var(), var_ref(), marker(), at_marker()

Accidentals use Alda's characters: "+" (sharp), "-" (flat), "_" (natural), repeated for double accidentals. Anything else raises ValueError.

The octave a note declares is preserved through both to_alda() and MIDI generation. Octave is stateful in Alda, so a note only emits an octave change where the octave actually changes:

from aldakit import Score
from aldakit.compose import part, note

score = Score.from_elements(part("piano"), note("c", octave=5), note("d"))
print(score.to_alda())  # 'piano: o5 c d'
print([n.pitch for n in score.midi.notes])  # [72, 74]

Instrument Names

All 128 General MIDI programs are available under their Alda names. Canonical names carry the midi- prefix, and most have shorter aliases:

midi-acoustic-grand-piano:  # canonical
piano:                      # alias for the same program
midi-square-lead:           # synth lead
midi-percussion:            # drum kit on MIDI channel 10

See docs/alda-language/list-of-instruments.md for the full list. An unrecognised instrument name falls back to acoustic grand piano and reports a warning rather than failing silently:

score = Score("bogus-instrument: c d e")
print([str(d) for d in score.diagnostics])
# ["<input>:1:1: Unknown instrument 'bogus-instrument'; falling back to acoustic grand piano."]

midi-percussion (alias percussion) is placed on MIDI channel 10, where note numbers select drum sounds; key signatures and transposition do not apply to it. Melodic parts never use that channel.

That leaves 15 channels for pitched parts, but a score is not limited to 15 of them: a part only holds a channel while it is sounding, so a part that has finished hands its channel to one that is about to start, and the instrument, pan and volume are set again for the part taking over. This is how examples/all-instruments.alda plays all 128 General MIDI instruments. Scores that fit without reuse keep one channel per part, in declaration order. A diagnostic is reported only when more than 15 pitched parts sound at the same moment, which no amount of reuse can accommodate.

Inspecting and Checking a Score

The problems the generator finds are available as values, not just as CLI output, so a build step or an editor plugin can use them:

from aldakit import inspect_score, lint_score

info = inspect_score("piano: c d e\ncello: c2")
print(info.note_count, info.duration)
for part in info.parts:
    print(part.name, part.instrument, part.channel, part.note_count)

for finding in lint_score("piano: nosuchvar"):
    print(finding.severity, finding.code, finding.message)
    # error undefined-variable Undefined variable 'nosuchvar'.

lint_score() reports unknown instruments and attributes, attribute values out of range, ambiguous instrument instances, undefined variables and markers, notes clamped into the MIDI range, unused and redefined variables, and parts that collide on a channel. Each finding carries a code, a severity and the source position. The aldakit info and aldakit lint commands are thin wrappers over these two functions.

Scales and Chords

Build melodies and harmonies using music theory helpers:

from aldakit import Score
from aldakit.compose import part, tempo
from aldakit.compose import (
    # Scale functions
    scale, scale_notes, scale_degree, mode,
    relative_minor, relative_major,
    # Chord builders
    major, minor, dim, aug, maj7, min7, dom7,
    arpeggiate, invert_chord, voicing,
)

# Get scale pitches
c_major = scale("c", "major")       # ['c', 'd', 'e', 'f', 'g', 'a', 'b']
a_blues = scale("a", "blues")       # ['a', 'c', 'd', 'd+', 'e', 'g']

# Generate scale as playable notes
melody = scale_notes("c", "pentatonic", duration=8)

# Key relationships
rel_min = relative_minor("c")  # 'a' (C major -> A minor)
rel_maj = relative_major("a")  # 'c' (A minor -> C major)

# Build chords
c_maj = major("c")                    # C E G
a_min7 = min7("a")                    # A C E G
g_dom7 = dom7("g", inversion=1)       # B D F G (first inversion)

# Arpeggiate a chord
arp = arpeggiate(maj7("c"), pattern=[0, 1, 2, 3, 2, 1], duration=16)

# Custom voicing (spread chord across octaves)
spread = voicing(major("c"), [3, 4, 5])  # C3 E4 G5

# Create a I-IV-V-I progression
pitches = scale("c", "major")
progression = [
    major(pitches[0], duration=2),  # C major (I)
    major(pitches[3], duration=2),  # F major (IV)
    major(pitches[4], duration=2),  # G major (V)
    major(pitches[0], duration=1),  # C major (I)
]

score = Score.from_elements(
    part("piano"),
    tempo(100),
    *progression,
)
score.play()

Available scales: major, minor, harmonic-minor, melodic-minor, pentatonic, blues, chromatic, whole-tone, dorian, phrygian, lydian, mixolydian, locrian, japanese, arabic, hungarian-minor, spanish, bebop-dominant, bebop-major

Available chords: major, minor, dim, aug, sus2, sus4, maj7, min7, dom7, dim7, half_dim7, min_maj7, aug7, maj6, min6, dom9, maj9, min9, add9, power

Transformers

Transform sequences with pitch and structural operations:

from aldakit.compose import (
    note, seq,
    transpose, invert, reverse, shuffle,
    augment, diminish, fragment, loop, interleave,
    pipe,
)

# Create a motif
motif = seq(note("c", duration=8), note("d", duration=8), note("e", duration=8))

# Pitch transformers
up_fourth = transpose(motif, 5)      # Transpose up 5 semitones
inverted = invert(motif)             # Invert intervals around first note
backwards = reverse(motif)           # Retrograde

# Structural transformers
longer = augment(motif, 2)           # Double durations (8th -> quarter)
shorter = diminish(motif, 2)         # Halve durations (8th -> 16th)
first_two = fragment(motif, 2)       # Take first 2 elements
repeated = loop(motif, 4)            # Repeat 4 times (explicit)

# Chain transformations with pipe
result = pipe(
    motif,
    lambda s: transpose(s, 5),
    reverse,
    lambda s: augment(s, 2),
)

# All transforms preserve to_alda() export
print(result.to_alda())

MIDI Transformers

For post-MIDI-generation processing, use MIDI-level transformers that operate on absolute timing:

from aldakit import Score
from aldakit.midi.transform import (
    quantize, humanize, swing, stretch,
    accent, crescendo, normalize,
    filter_notes, trim, merge,
)

# Get MIDI sequence from a score
score = Score("piano: c d e f g a b > c")
midi_seq = score.midi

# Timing transformers
quantized = quantize(midi_seq, grid=0.25, strength=0.8)  # Snap to quarter-note grid
humanized = humanize(midi_seq, timing=0.02, velocity=10)  # Add subtle variations
swung = swing(midi_seq, grid=0.5, amount=0.3)            # Apply swing feel

# Velocity transformers
accented = accent(midi_seq, pattern=[1.0, 0.5, 0.5, 0.5])  # 4/4 accent pattern
crescendo_seq = crescendo(midi_seq, start_velocity=50, end_velocity=100)
normalized = normalize(midi_seq, target=100)

# Filtering and combining
filtered = filter_notes(midi_seq, lambda n: n.pitch >= 60)  # Keep notes >= middle C
trimmed = trim(midi_seq, start=0.0, end=2.0)               # First 2 seconds
merged = merge(midi_seq, another_seq)                       # Combine sequences

Note: MIDI transformers operate on absolute timing (seconds) and cannot be converted back to Alda notation.

Generative Functions

Create algorithmic compositions with generative functions:

from aldakit import Score
from aldakit.compose import part, tempo
from aldakit.compose.generate import (
    random_walk, euclidean, markov_chain, lsystem, cellular_automaton,
    shift_register, turing_machine,
)

# Random walk melody
melody = random_walk("c", steps=16, intervals=[-2, -1, 1, 2], duration=8, seed=42)

# Euclidean rhythms (e.g., Cuban tresillo: 3 hits over 8 steps)
rhythm = euclidean(hits=3, steps=8, pitch="c", duration=16)

# Markov chain
chain = markov_chain({
    "c": {"d": 0.5, "e": 0.3, "g": 0.2},
    "d": {"e": 0.6, "c": 0.4},
    "e": {"c": 0.5, "g": 0.5},
    "g": {"c": 1.0},
})
markov_melody = chain.generate(start="c", length=16, duration=8, seed=42)

# L-System (Fibonacci pattern)
from aldakit.compose import note, rest
fib = lsystem(
    axiom="A",
    rules={"A": "AB", "B": "A"},
    iterations=5,
    note_map={"A": note("c", duration=8), "B": note("e", duration=8)},
)

# Cellular automaton (Rule 110)
automaton = cellular_automaton(rule=110, width=8, steps=4, pitch_on="c", duration=16)

# Shift register (LFSR) - classic analog sequencer
lfsr = shift_register(16, bits=4, scale=["c", "e", "g", "b"], duration=16)

# Turing Machine - evolving loop (probability=0 for locked, higher for chaos)
turing = turing_machine(32, bits=8, probability=0.1, seed=42)

# Combine into a score
score = Score.from_elements(
    part("piano"),
    tempo(120),
    *melody.elements,
)
score.play()

CLI Reference

aldakit [--version] [-h] {repl,play,eval,info,lint,ports,soundfont,transcribe} ...

Subcommands

Command Description
(none) Opens the interactive REPL (default when no args)
repl Interactive REPL with syntax highlighting and auto-completion
play Play an Alda file
eval Evaluate Alda code directly
info Summarise a score: parts, instruments, channels, duration
render Render a score to a WAV file, faster than real time
lint Report problems in a score without playing it
ports List available MIDI ports (both input and output)
soundfont Find, download and verify SoundFonts for the audio backend
transcribe Record MIDI input and output Alda code

Global Options

Option Description
--version Show version number and exit
-h, --help Show help message

play Subcommand

aldakit play [-v] [-e CODE] [-o FILE] [--port NAME|INDEX] [-sf FILE] [-a] [-vp NAME] [--stdin] [--parse-only] [--no-wait] [--strict] FILE
Option Description
FILE Alda file to play (use - for stdin)
-e, --eval CODE Play Alda code given on the command line instead of a file
-v, --verbose Verbose output
-o, --output FILE Save to MIDI file instead of playing
--port NAME|INDEX MIDI port by name or index (see aldakit ports)
-sf, --soundfont FILE Use TinySoundFont audio backend with specified SoundFont
-a, --audio Use audio backend with pre-configured soundfont
-vp, --virtual-port NAME Custom virtual MIDI port name (default: AldakitMIDI)
--stdin Read from stdin (blank line to play)
--parse-only Print AST without playing
--no-wait Return without waiting for playback to finish (playback stops when the command exits)
--strict Stop with an error on any warning, as Alda does, instead of playing anyway

eval Subcommand

aldakit eval [-v] [-o FILE] [-p NAME|INDEX] [-sf FILE] [-a] [-vp NAME] [--parse-only] [--no-wait] [--strict] CODE
Option Description
CODE Alda code to evaluate
-v, --verbose Verbose output
--parse-only Print AST without playing
--no-wait Return without waiting for playback to finish
-o, --output FILE Save to MIDI file instead of playing
-p, --port NAME|INDEX MIDI port by name or index
-sf, --soundfont FILE Use TinySoundFont audio backend
-a, --audio Use audio backend with pre-configured soundfont
-vp, --virtual-port NAME Custom virtual MIDI port name (default: AldakitMIDI)
--strict Stop with an error on any warning, as Alda does, instead of playing anyway

repl Subcommand

aldakit repl [-v] [--port NAME|INDEX] [-sf FILE] [-a] [-vp NAME] [--sequential] [FILE]
Option Description
FILE Alda file to load on startup (use :play to hear it)
-v, --verbose Verbose output
--port NAME|INDEX MIDI port by name or index
-sf, --soundfont FILE Use TinySoundFont audio backend
-a, --audio Use audio backend with pre-configured soundfont
-vp, --virtual-port NAME Custom virtual MIDI port name (default: AldakitMIDI)
--sequential Start in sequential mode (wait for each input)

soundfont Subcommand

The audio backend needs a General MIDI SoundFont. This finds, fetches and checks them; downloads land in ~/.aldakit/soundfonts/ and are verified against a SHA256 checksum.

aldakit soundfont list              # installed files and the download catalog
aldakit soundfont install           # fetch the default (TimGM6mb, 5.8 MB)
aldakit soundfont install FluidR3_GM --force
aldakit soundfont install --all
aldakit soundfont verify            # re-check the downloaded files
aldakit soundfont path              # print the one playback would use

If you ask for audio playback and no SoundFont can be found, aldakit offers to download one, so the usual first run is a single prompt rather than an error. Non-interactive runs (scripts, CI) get the error instead of a prompt.

info Subcommand

aldakit info song.alda
aldakit info -e "piano: c d e"

Prints the parts, their instruments, MIDI programs, channels and note counts, along with the tempo, duration, variables and markers:

song.alda
  parts:    2
  notes:    5
  duration: 0:02.0 (2.00s)
  tempo:    90 bpm

  part   instrument                 prog  chan   notes
  ---------------------------------------------------
  piano  midi-acoustic-grand-piano     0     0       3
  cello  midi-cello                   42     1       2

render Subcommand

aldakit render song.alda                  # writes song.wav
aldakit render song.alda -o out.wav
aldakit render -e "piano: c d e" -o scale.wav
aldakit render song.alda --gain 0.5 --tail 2

Synthesizes the score with a SoundFont and writes a 16-bit stereo WAV, with no audio device involved and without waiting for the score to play: a two and a half minute score renders in about twelve seconds. The synthesis is the same code path playback uses, so the file and the speakers agree.

Option Description
-o, --output FILE Output file (default: the input file with a .wav suffix)
-sf, --soundfont FILE SoundFont to synthesize with (default: the one playback uses)
-g, --gain GAIN Volume factor, 0.0 to 2.0, where 1.0 is unity
--tail SECONDS Audio rendered after the last note, so release tails are not cut off
--strict Stop with an error on any warning, as Alda does, instead of playing anyway

A mix loud enough to clip is reported along with a gain that will not:

Warning: the mix peaked at 2.15 of full scale and was clipped. Try --gain 0.46.

lint Subcommand

aldakit lint song.alda
aldakit lint -e "piano: c" --strict

Reports what will make a score sound wrong without playing it: unknown instruments, undefined variables and markers, unknown attributes, attribute values out of range, ambiguous instrument instances, notes clamped into the MIDI range, unused variables, and parts that collide on a channel.

Option Description
FILE Alda file to check (use - for stdin)
-e, --eval CODE Check Alda code given on the command line
-q, --quiet Print nothing; report through the exit status
--strict Exit non-zero on warnings as well as errors

Exit status is 0 when clean, 1 when an error was found (or any finding under --strict), and 2 when the score does not parse -- so aldakit lint --strict works as a build step.

transcribe Subcommand

aldakit transcribe [-d SEC] [-i INST] [-t BPM] [-q GRID] [-o FILE] [--port NAME] [--play] [-v] [--alda-notes] [--feel FEEL] [--swing-ratio RATIO]
Option Description
-d, --duration SEC Recording duration in seconds (default: 10)
-i, --instrument NAME Instrument name (default: piano)
-t, --tempo BPM Tempo for quantization (default: 120)
-q, --quantize GRID Quantize grid in beats (default: 0.25 = 16th notes)
-o, --output FILE Save to file (.alda or .mid)
--port NAME MIDI input port name
--play Play back the recording after transcription
-v, --verbose Show notes as they are played
--alda-notes Show notes in Alda notation (with -v)
--feel FEEL Rhythm feel: straight, swing, triplet, quintuplet
--swing-ratio RATIO Swing ratio between 0 and 1 (default: 0.67)

Examples

# Interactive REPL (default when no args)
aldakit
aldakit repl

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

# Play a file
aldakit play examples/jazz.alda
aldakit play -v examples/jazz.alda  # verbose

# Play to a specific port (by index or name)
aldakit play --port 0 examples/twinkle.alda
aldakit play --port FluidSynth examples/twinkle.alda

# Use built-in audio (TinySoundFont) instead of MIDI
aldakit play -sf ~/Music/sf2/FluidR3_GM.sf2 examples/twinkle.alda
aldakit repl -sf ~/Music/sf2/FluidR3_GM.sf2

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

# Parse and show AST
aldakit play --parse-only examples/twinkle.alda
aldakit eval --parse-only "piano: c/e/g"

# Export to MIDI file
aldakit play examples/twinkle.alda -o twinkle.mid
aldakit eval "piano: c d e f g" -o output.mid

# List available MIDI ports
aldakit ports
aldakit ports -o  # output ports only
aldakit ports -i  # input ports only

# Record MIDI input for 10 seconds (default)
aldakit transcribe

# Record from a specific input port
aldakit transcribe --port 0
aldakit transcribe --port "My MIDI Keyboard"

# Record for 30 seconds with verbose note display
aldakit transcribe -d 30 -v

# Record with Alda-style note display
aldakit transcribe -d 10 -v --alda-notes

# Record and save to file
aldakit transcribe -o recording.alda
aldakit transcribe -o recording.mid

# Record and play back
aldakit transcribe --play

# Record with custom settings (swing feel, triplet quantization)
aldakit transcribe -d 20 -t 90 -i guitar --feel triplet --play

Configuration File

aldakit supports INI-format configuration files to set default values for common options. Configuration is loaded from these locations (in priority order):

  1. ./aldakit.ini - Project-local config (current working directory)

  2. ~/.aldakit/config.ini - User config (home directory)

  3. ALDAKIT_SOUNDFONT environment variable (for soundfont only)

CLI arguments always override config file settings.

Example Configuration

Create ~/.aldakit/config.ini:

[aldakit]
# Default SoundFont for audio backend
soundfont = ~/Music/sf2/FluidR3_GM.sf2

# Default backend: "midi" or "audio"
backend = midi

# Default MIDI output port (name or index)
port = FluidSynth

# Default tempo for REPL (BPM)
tempo = 120

# Enable verbose output by default
verbose = false

Available Options

Option Type Default Description
soundfont path none SoundFont path for audio backend
backend string midi midi = external synths/DAWs/virtual port; audio = built-in TinySoundFont
port string none Default MIDI output port name
tempo integer 120 Default tempo for REPL (BPM)
verbose boolean false Enable verbose output

Backend values:

  • midi (default): Uses libremidi for MIDI output. Sends to external synthesizers (FluidSynth, hardware), DAWs, or creates a virtual port ("AldakitMIDI") for routing.

  • audio: Uses built-in TinySoundFont for direct audio output. Requires a soundfont to be configured. No external MIDI setup needed.

Backend Selection Priority

  1. CLI -sf /path/to/soundfont.sf2 forces the audio backend with that SoundFont

  2. CLI -a / --audio forces the audio backend, using a configured or discovered SoundFont

  3. Config backend = audio uses the audio backend

  4. If MIDI output ports are available, use MIDI (default)

  5. If no MIDI ports are available and a SoundFont can be found, use audio

  6. Otherwise create a virtual MIDI port ("AldakitMIDI") and warn that nothing will be heard until a synth or DAW connects to it

A SoundFont counts as available if it is named by -sf, by soundfont in the config file, or by ALDAKIT_SOUNDFONT, or if one is discovered in a standard location such as ~/.aldakit/soundfonts/ or ~/Music/sf2/.

If aldakit play produces no sound, run aldakit ports to see whether any MIDI destination exists. With no ports and no SoundFont, MIDI is being sent to a virtual port that nothing is listening to.

Project-Local Configuration

Create aldakit.ini in your project directory to override user settings:

[aldakit]
# Use audio backend with project-specific SoundFont
backend = audio
soundfont = ./sounds/project-soundfont.sf2
tempo = 140

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:

Command Description
:load FILE Load an Alda file (does not play)
:play [FILE] Play the loaded score, or load and play FILE
:save FILE Save the session to .alda or .mid
:ls [DIR] List Alda files and directories
:cd [DIR] Change directory
:pwd Show the current directory
:clear Forget the session so far
:ports List MIDI ports
:instruments List available instruments
:tempo [BPM] Show/set the default tempo
:stop Stop playback
:status Show playback status
:concurrent / :sequential Switch playback mode
:help Show help
:quit Exit the REPL

Open a file directly from the command line. It is loaded, not played, so the REPL is ready immediately:

$ aldakit repl examples/twinkle.alda
Loaded examples/twinkle.alda (1 part, 42 notes, 28.7s)
Type :play to hear it.

aldakit> :play
Playing examples/twinkle.alda...

Working with files inside the REPL:

aldakit> :ls
  examples/
  sketch.alda
aldakit> :load sketch.alda
Loaded sketch.alda (2 parts, 64 notes, 12.4s)
Type :play to hear it.
aldakit> :play
Playing sketch.alda...
aldakit> piano: c d e f g
aldakit> :save take-2.alda
Saved /home/you/music/take-2.alda

:load never plays: a file can be inspected, saved or edited before it is heard, and opening a long score does not tie up the prompt. :play with no argument replays whatever is loaded; :play FILE is shorthand for loading and playing in one step. Typed input still plays as soon as you press Enter.

:save writes everything accepted during the session -- typed, pasted or loaded -- as a single score. A .mid or .midi extension exports MIDI instead. Note that this is the session's source, not a recording of what you heard: in concurrent mode inputs are layered as they play, whereas the saved file is one score read top to bottom.

A file opened with :load (or given on the command line) keeps its own tempo. The REPL only prepends its default tempo to input you type that does not set one.

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 (percent; above 100 overlaps the next note)

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

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

# Key signatures
(key-sig '(g major))     # G major (F#)
(key-sig '(d minor))     # D minor (Bb)
(key-sig "f+ c+")        # Explicit accidentals

# Transposition
(transpose 5)   # Up 5 semitones
(transpose -2)  # Down 2 semitones (Bb instrument)

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 (AldakitMIDI), 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.)

import aldakit

# List available ports
print(aldakit.list_ports())

# Play to virtual port (visible in DAWs like Ableton Live)
aldakit.play("piano: c d e f g")

# Play to a specific port
aldakit.play("piano: c d e f g", port="FluidSynth")

# Save to MIDI file
aldakit.save("piano: c d e f g", "output.mid")

Audio Backend (Built-in)

For self-contained audio playback without external synthesizers, aldakit includes a built-in audio backend powered by TinySoundFont and miniaudio:

  • Direct audio output (no FluidSynth or DAW required)

  • Cross-platform: macOS (CoreAudio), Linux (ALSA/PulseAudio), Windows (WASAPI)

  • Requires a SoundFont file (.sf2) for instrument sounds

  • Header-only libraries for minimal binary size

Basic Usage

from aldakit import Score

# Play with built-in audio (requires SoundFont)
score = Score("piano: c d e f g")
score.play(backend="audio")

# Specify SoundFont explicitly
score.play(backend="audio", soundfont="/path/to/FluidR3_GM.sf2")

SoundFont Setup

The audio backend requires a General MIDI SoundFont file. aldakit searches these locations automatically:

  • $ALDAKIT_SOUNDFONT environment variable

  • ~/Music/sf2/

  • ~/.aldakit/soundfonts/

  • /usr/share/soundfonts/ (Linux)

Option 1: Download manually

Download a SoundFont and place it in a folder such as ~/Music/sf2/. These are mirrored on aldakit's soundfonts-v1 release, which is where aldakit soundfont install fetches them from:

They are third-party works, not part of aldakit; SOUNDFONT-LICENSES.txt on the same release records each licence in full.

Suggest using a sha256sum (macOs or Linux) or similar to verify file integrity after download:

% sha256sum FluidR3_GM.sf2
74594e8f4250680adf590507a306655a299935343583256f3b722c48a1bc1cb0  FluidR3_GM.sf2

% sha256sum GeneralUser-GS.sf2
c278464b823daf9c52106c0957f752817da0e52964817ff682fe3a8d2f8446ce  GeneralUser-GS.sf2

% sha256sum TimGM6mb.sf2
82475b91a76de15cb28a104707d3247ba932e228bada3f47bba63c6b31aaf7a1  TimGM6mb.sf2

On Windows (PowerShell): Get-FileHash -Algorithm SHA256

Option 2: Auto-download

from aldakit.midi.soundfont import setup_soundfont, setup_all_soundfonts

# Downloads TimGM6mb.sf2 (~6 MB) to ~/.aldakit/soundfonts/
setup_soundfont()

# Or download all available SoundFonts from the catalog
setup_all_soundfonts()

Option 3: Using SoundFontManager

For more control, use the SoundFontManager class:

from aldakit.midi.soundfont import SoundFontManager

manager = SoundFontManager()

# Find existing SoundFont
sf = manager.find()

# List all found SoundFonts
for path in manager.list():
    print(path)

# Download a specific SoundFont (with SHA256 verification)
path = manager.download("FluidR3_GM")

# Download all SoundFonts from catalog
paths = manager.setup_all()

# Verify checksums of downloaded files
results = manager.verify_checksums()
for name, valid in results.items():
    print(f"{name}: {'OK' if valid else 'FAILED'}")

# List available downloads
for name, info in manager.list_available_downloads().items():
    print(f"{name}: {info['size_mb']} MB - {info['description']}")

Option 4: Environment variable

export ALDAKIT_SOUNDFONT=/path/to/your/soundfont.sf2

Using TsfBackend Directly

from aldakit import Score
from aldakit.midi.backends import TsfBackend

# Create backend with specific SoundFont
with TsfBackend(soundfont="~/Music/sf2/FluidR3_GM.sf2") as backend:
    score = Score("piano: c/e/g")
    backend.play(score.midi)
    backend.wait()  # Block until playback completes

# Inspect SoundFont presets
backend = TsfBackend()
print(f"Presets: {backend.preset_count}")
for i in range(min(10, backend.preset_count)):
    print(f"  {i}: {backend.preset_name(i)}")

Audio vs MIDI Backend

Feature Audio (backend="audio") MIDI (backend="midi")
External synth required No Yes (FluidSynth, DAW, hardware)
Setup complexity Just needs SoundFont Requires MIDI routing
Sound quality Depends on SoundFont Depends on synth
DAW integration No Yes (virtual port)
Latency Very low Very low
Effects (reverb, etc.) No Depends on synth

Recommendation: Use backend="audio" for quick playback and standalone use. Use backend="midi" (default) for DAW integration, hardware synths, or when you need effects.

MIDI Playback Setup

When no hardware MIDI ports are available, aldakit creates a virtual port named "AldakitMIDI". 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 "AldakitMIDI" 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 play --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 play 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

Golden Fixtures

Two sets of fixtures pin what the examples produce, so that an unintended change shows up as a reviewable diff rather than as music that quietly sounds different:

  • tests/golden/examples.json pins the notes, channels, programs, timings and velocities of every example. Regenerate with make golden.

  • tests/golden/audio.json pins what they sound like: every example is rendered with a checksum-pinned SoundFont and its loudness per channel, peak and length are compared. This catches what MIDI cannot -- an instrument that never sounds because its program change went to the wrong channel, or a pan that never reached the synthesizer. Regenerate with make golden-audio.

The audio fixtures need the SoundFont they are pinned to, which is not in the repository, so they skip if it is absent:

make soundfont     # downloads TimGM6mb (6 MB, checksum verified)
make test-audio    # fails rather than skips if it is missing

CI runs test-audio on Linux and macOS.

Alda Reference

The golden fixtures record what aldakit does. tests/alda_reference/ records what Alda does: alda export output for every example and shared-suite score. tests/test_alda_reference.py fails when aldakit's MIDI differs, except for the deliberate deviations listed in docs/dev/alda-deviations.md. It does not need Alda installed.

tests/shared_suite/*.expected, the language-agnostic suite other implementations copy, is generated from the same exports with make shared-suite.

A new example needs a reference export, which does need Alda (https://alda.io/install/):

make alda-diff                  # alda and alda-player on PATH
make alda-diff ALDA_DIR=~/alda  # or in a directory

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.

  • TinySoundFont - SoundFont2 synthesizer library in a single C/C++ header

  • miniaudio - Single-header audio playback and capture library

  • nanobind - a tiny and efficient C++/Python bindings

  1. Includes a rich REPL, native MIDI, and built-in audio via bundled prompt-toolkit, libremidi, and TinySoundFont respectively. ↩

Metadata

Release files for aldakit 0.5.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for aldakit 0.5.0
File Size Uploaded
aldakit-0.5.0.tar.gz 2.4 MB Details

Built distributions (wheels)

Table of built distributions (wheels) for aldakit 0.5.0
File
aldakit-0.5.0-cp314-cp314-win_amd64.whl CPython 3.14 CPython 3.14 Windows x86-64 Details
aldakit-0.5.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl CPython 3.14 CPython 3.14 Linux glibc 2.28+ x86-64, Linux glibc 2.27+ x86-64 Details
aldakit-0.5.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl CPython 3.14 CPython 3.14 Linux glibc 2.27+ ARM64, Linux glibc 2.28+ ARM64 Details
aldakit-0.5.0-cp314-cp314-macosx_11_0_x86_64.whl CPython 3.14 CPython 3.14 macOS 11.0+ x86-64 Details
aldakit-0.5.0-cp314-cp314-macosx_11_0_arm64.whl CPython 3.14 CPython 3.14 macOS 11.0+ ARM64 Details
aldakit-0.5.0-cp313-cp313-win_amd64.whl CPython 3.13 CPython 3.13 Windows x86-64 Details
aldakit-0.5.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl CPython 3.13 CPython 3.13 Linux glibc 2.27+ x86-64, Linux glibc 2.28+ x86-64 Details
aldakit-0.5.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl CPython 3.13 CPython 3.13 Linux glibc 2.28+ ARM64, Linux glibc 2.27+ ARM64 Details
aldakit-0.5.0-cp313-cp313-macosx_11_0_x86_64.whl CPython 3.13 CPython 3.13 macOS 11.0+ x86-64 Details
aldakit-0.5.0-cp313-cp313-macosx_11_0_arm64.whl CPython 3.13 CPython 3.13 macOS 11.0+ ARM64 Details
aldakit-0.5.0-cp312-cp312-win_amd64.whl CPython 3.12 CPython 3.12 Windows x86-64 Details
aldakit-0.5.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl CPython 3.12 CPython 3.12 Linux glibc 2.27+ x86-64, Linux glibc 2.28+ x86-64 Details
aldakit-0.5.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl CPython 3.12 CPython 3.12 Linux glibc 2.27+ ARM64, Linux glibc 2.28+ ARM64 Details
aldakit-0.5.0-cp312-cp312-macosx_11_0_x86_64.whl CPython 3.12 CPython 3.12 macOS 11.0+ x86-64 Details
aldakit-0.5.0-cp312-cp312-macosx_11_0_arm64.whl CPython 3.12 CPython 3.12 macOS 11.0+ ARM64 Details
aldakit-0.5.0-cp311-cp311-win_amd64.whl CPython 3.11 CPython 3.11 Windows x86-64 Details
aldakit-0.5.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl CPython 3.11 CPython 3.11 Linux glibc 2.28+ x86-64, Linux glibc 2.27+ x86-64 Details
aldakit-0.5.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl CPython 3.11 CPython 3.11 Linux glibc 2.27+ ARM64, Linux glibc 2.28+ ARM64 Details
aldakit-0.5.0-cp311-cp311-macosx_11_0_x86_64.whl CPython 3.11 CPython 3.11 macOS 11.0+ x86-64 Details
aldakit-0.5.0-cp311-cp311-macosx_11_0_arm64.whl CPython 3.11 CPython 3.11 macOS 11.0+ ARM64 Details
aldakit-0.5.0-cp310-cp310-win_amd64.whl CPython 3.10 CPython 3.10 Windows x86-64 Details
aldakit-0.5.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl CPython 3.10 CPython 3.10 Linux glibc 2.28+ x86-64, Linux glibc 2.27+ x86-64 Details
aldakit-0.5.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl CPython 3.10 CPython 3.10 Linux glibc 2.27+ ARM64, Linux glibc 2.28+ ARM64 Details
aldakit-0.5.0-cp310-cp310-macosx_11_0_x86_64.whl CPython 3.10 CPython 3.10 macOS 11.0+ x86-64 Details
aldakit-0.5.0-cp310-cp310-macosx_11_0_arm64.whl CPython 3.10 CPython 3.10 macOS 11.0+ ARM64 Details

Total release size: 26.0 MB

Release files / aldakit-0.5.0.tar.gz

Download URL aldakit-0.5.0.tar.gz
Size 2.4 MB
Tags Source
SHA-256 checksum
How to use checksums
5d03ee03e0941f67e6f8366edb3217807e6de983f060f10dbb87d7feeb36ec49
BLAKE2b-256 checksum
How to use checksums
f443527ac01dae8487d2674efae5feaa135b88c22816207265cf1287cef55b33
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.2

Release files / aldakit-0.5.0-cp314-cp314-win_amd64.whl

Download URL aldakit-0.5.0-cp314-cp314-win_amd64.whl
Size 1.2 MB
Tags CPython 3.14 Windows x86-64
SHA-256 checksum
How to use checksums
90dcf217a166e90b947350f98b2e3656421daeb80310411812fb80c6045106c3
BLAKE2b-256 checksum
How to use checksums
f3cc554c2347bb716a1cfc1e7901e6756d5cb5bbfd9df70cb40eadae1a01afd6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.2

Release files / aldakit-0.5.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl

Download URL aldakit-0.5.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Size 925.9 kB
Tags CPython 3.14 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
37823329ce36989175ff5706c1fb201e79d124e0973dbe5adccbdf39deaebe14
BLAKE2b-256 checksum
How to use checksums
d4a3d6d9e97270009648b11f6a657cd4f3a68524f50ce1c1c9dfaf50ddf3dc9a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.2

Release files / aldakit-0.5.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl

Download URL aldakit-0.5.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl
Size 913.8 kB
Tags CPython 3.14 Linux glibc 2.27+ ARM64 Linux glibc 2.28+ ARM64
SHA-256 checksum
How to use checksums
77db6f5b6ffda9b690f534b2b0516c0fa1733eefe9a9eecd7c404133697aa6f6
BLAKE2b-256 checksum
How to use checksums
08b1b6f11b15a329b1fcf3221484b8a3334dd9b355e678997c1885166976e586
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.2

Release files / aldakit-0.5.0-cp314-cp314-macosx_11_0_x86_64.whl

Download URL aldakit-0.5.0-cp314-cp314-macosx_11_0_x86_64.whl
Size 862.5 kB
Tags CPython 3.14 macOS 11.0+ x86-64
SHA-256 checksum
How to use checksums
1bcb9b41eaf2b2351f69307f5435047d95c8dcf7b6a8c64feee7313b09776506
BLAKE2b-256 checksum
How to use checksums
36df87111694cb74071e48a88232fdce46e312f2891e642800955a9fdfa4c0f5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.2

Release files / aldakit-0.5.0-cp314-cp314-macosx_11_0_arm64.whl

Download URL aldakit-0.5.0-cp314-cp314-macosx_11_0_arm64.whl
Size 839.4 kB
Tags CPython 3.14 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
c4035d65c9a807031296ba00b7995a2d9605a418cd1d82b6240d6477f371a476
BLAKE2b-256 checksum
How to use checksums
54775a8f5122003f83054dd224211ea8447b7fcc557ea29aa860943c8e8dba40
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.2

Release files / aldakit-0.5.0-cp313-cp313-win_amd64.whl

Download URL aldakit-0.5.0-cp313-cp313-win_amd64.whl
Size 1.2 MB
Tags CPython 3.13 Windows x86-64
SHA-256 checksum
How to use checksums
ce916299c550cb49bebb5025af89945928bf8527548b14e2a5badaa1b4a02578
BLAKE2b-256 checksum
How to use checksums
6e5e5afc30a9e3c9afd5be98ab248736359f19901c4ba7199724c678bb9801b4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.2

Release files / aldakit-0.5.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl

Download URL aldakit-0.5.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Size 926.0 kB
Tags CPython 3.13 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
2eb59a3e16adae03f18162e40eb3a8e475649e6267edf6b045fe08205f714c45
BLAKE2b-256 checksum
How to use checksums
b1eb2660a35a5206effc55db7861d4c8356dd41de8b42a72fbcc37e1ef9e5239
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.2

Release files / aldakit-0.5.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl

Download URL aldakit-0.5.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl
Size 913.5 kB
Tags CPython 3.13 Linux glibc 2.27+ ARM64 Linux glibc 2.28+ ARM64
SHA-256 checksum
How to use checksums
9e4d3bc6f233c29d22d4f7c57f60e9f8456296eb91bc2b550d279fff8a587c78
BLAKE2b-256 checksum
How to use checksums
599c63973b55ca7ca905d4dc0a10354c388ad95157cd381b6225924ba9081e6a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.2

Release files / aldakit-0.5.0-cp313-cp313-macosx_11_0_x86_64.whl

Download URL aldakit-0.5.0-cp313-cp313-macosx_11_0_x86_64.whl
Size 862.3 kB
Tags CPython 3.13 macOS 11.0+ x86-64
SHA-256 checksum
How to use checksums
0682de128fa8e3ba7200a8883454418832e6da673148ed27530f3c0a9bd69525
BLAKE2b-256 checksum
How to use checksums
ff54f38f164a48d24e8d6dcf3a9156ec7656f6fb81bfdd2a612e84cef518117f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.2

Release files / aldakit-0.5.0-cp313-cp313-macosx_11_0_arm64.whl

Download URL aldakit-0.5.0-cp313-cp313-macosx_11_0_arm64.whl
Size 839.2 kB
Tags CPython 3.13 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
a52cb60c9456d54cb7c797ee1f89aef4f741fd3257c3090913f8d9d9c116ac20
BLAKE2b-256 checksum
How to use checksums
efd5d5c96a1404224104f527761d37eae1808741b2815bcc148c66d75c5762f8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.2

Release files / aldakit-0.5.0-cp312-cp312-win_amd64.whl

Download URL aldakit-0.5.0-cp312-cp312-win_amd64.whl
Size 1.2 MB
Tags CPython 3.12 Windows x86-64
SHA-256 checksum
How to use checksums
3506d21b917a173a7a2504d9efdd4363be500e5bcd813ee8718bad804e2ffb95
BLAKE2b-256 checksum
How to use checksums
012eee4dc885112c8a8ac3525ec6c4e30d773c0bfbf38827f62ecede28f791fb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.2

Release files / aldakit-0.5.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl

Download URL aldakit-0.5.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Size 926.1 kB
Tags CPython 3.12 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
0dfa9c59d11e2bd1ad7ac515829e686d38d284c7e4ae02c5d26f8c0dc99ef36c
BLAKE2b-256 checksum
How to use checksums
5380c61e6a5222fd6f68034cd708f0146e0b56898a4c3dfea0e2f4d68356950d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.2

Release files / aldakit-0.5.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl

Download URL aldakit-0.5.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl
Size 913.8 kB
Tags CPython 3.12 Linux glibc 2.27+ ARM64 Linux glibc 2.28+ ARM64
SHA-256 checksum
How to use checksums
b193ec5dcb8b044ce16c30a8b83da26d9ffb2ff3d17dab46853ab4363814dbf3
BLAKE2b-256 checksum
How to use checksums
7fcd024fe9a0ec3c3375db1f4f190a5a4d11bb475ef1509fa4b0fff22b772dc9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.2

Release files / aldakit-0.5.0-cp312-cp312-macosx_11_0_x86_64.whl

Download URL aldakit-0.5.0-cp312-cp312-macosx_11_0_x86_64.whl
Size 862.5 kB
Tags CPython 3.12 macOS 11.0+ x86-64
SHA-256 checksum
How to use checksums
3e66f5b983c2c22de179c8081878cfc3691f8a77cb789774e7e4cf2fd40779a7
BLAKE2b-256 checksum
How to use checksums
ec02a12ee5b8dc6babbc8ceec9834ee9cad3d21c293ff4d21d8d8ff9b0ed900d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.2

Release files / aldakit-0.5.0-cp312-cp312-macosx_11_0_arm64.whl

Download URL aldakit-0.5.0-cp312-cp312-macosx_11_0_arm64.whl
Size 839.3 kB
Tags CPython 3.12 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
8a08eaccecc65e5b7ade695d97ac9c300d96530f5906e806b7f12b3fd3ab1fe4
BLAKE2b-256 checksum
How to use checksums
f00ea978fe6908b9ca833bb7e239cf99f43ca36684e5a892d38d384c4bd1977f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.2

Release files / aldakit-0.5.0-cp311-cp311-win_amd64.whl

Download URL aldakit-0.5.0-cp311-cp311-win_amd64.whl
Size 1.2 MB
Tags CPython 3.11 Windows x86-64
SHA-256 checksum
How to use checksums
981e77d83681ebd34998c92369daf3bb91365dc134d85180df31f58efce3e9a4
BLAKE2b-256 checksum
How to use checksums
e0ab409b4da58b71ecc5048d758c3671ae5793dfafb87822740ebca0b689d1d5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.2

Release files / aldakit-0.5.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl

Download URL aldakit-0.5.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Size 928.2 kB
Tags CPython 3.11 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
90f981b2b3efe7dfbb9aa9af8bbaee6b1c2592e2ef451a8445507380af9eb89e
BLAKE2b-256 checksum
How to use checksums
c4e2a39a4dd5863357115060357dd80a6bb14850297d296c90e3089a5362000e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.2

Release files / aldakit-0.5.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl

Download URL aldakit-0.5.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl
Size 916.0 kB
Tags CPython 3.11 Linux glibc 2.27+ ARM64 Linux glibc 2.28+ ARM64
SHA-256 checksum
How to use checksums
d69e913523a7fd592339b26e1963ef065a0580d1d4d5a0dae8fafd18977da62c
BLAKE2b-256 checksum
How to use checksums
53508ba0d14a11fa8c307dc929868c03d8f4d54e87ed17367936e786446b2c20
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.2

Release files / aldakit-0.5.0-cp311-cp311-macosx_11_0_x86_64.whl

Download URL aldakit-0.5.0-cp311-cp311-macosx_11_0_x86_64.whl
Size 863.6 kB
Tags CPython 3.11 macOS 11.0+ x86-64
SHA-256 checksum
How to use checksums
ca7d02e69003abd725c4417b3c1a3b2c199b960cae59544926e6ee18640f6f4b
BLAKE2b-256 checksum
How to use checksums
47adb73fb529f14e0bb569dcff74fb5c56e3b42376cd25d34a63da80e5efd37e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.2

Release files / aldakit-0.5.0-cp311-cp311-macosx_11_0_arm64.whl

Download URL aldakit-0.5.0-cp311-cp311-macosx_11_0_arm64.whl
Size 841.4 kB
Tags CPython 3.11 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
f919a8e247913b8a116868ccf4d1b90e3512eac65f1a04d5b6d0c0038c8f4d57
BLAKE2b-256 checksum
How to use checksums
b8f7a0a73ff7ec35a7959bf3b38bd8ce9756781661f091eeb795af91751b51ca
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.2

Release files / aldakit-0.5.0-cp310-cp310-win_amd64.whl

Download URL aldakit-0.5.0-cp310-cp310-win_amd64.whl
Size 1.2 MB
Tags CPython 3.10 Windows x86-64
SHA-256 checksum
How to use checksums
972034984a978dd31851d076db660e11bd5247b0702a4741d4b8f2d2fccbedcb
BLAKE2b-256 checksum
How to use checksums
1380d098e1dcb3a6f04a14d6ccf1987a4cdf6a9c758b086e12d3861c6bfcff0d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.2

Release files / aldakit-0.5.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl

Download URL aldakit-0.5.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Size 928.7 kB
Tags CPython 3.10 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
afbb3484beda133f20ee7c1cb39776a0107562cdd206c02c005bb6f0391d3314
BLAKE2b-256 checksum
How to use checksums
e460682476a18c733efcb92705890424fe96f8ddcbc08b32cc8a96273618602f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.2

Release files / aldakit-0.5.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl

Download URL aldakit-0.5.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl
Size 916.3 kB
Tags CPython 3.10 Linux glibc 2.27+ ARM64 Linux glibc 2.28+ ARM64
SHA-256 checksum
How to use checksums
8be399be56ed238e2293efadc0b4fc30bc4dd80256cf73554c75f201d3483e50
BLAKE2b-256 checksum
How to use checksums
db3c4010fad3825149a575f0b4c31e3b78bf18977b9ddf12777fda3020a4fad7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.2

Release files / aldakit-0.5.0-cp310-cp310-macosx_11_0_x86_64.whl

Download URL aldakit-0.5.0-cp310-cp310-macosx_11_0_x86_64.whl
Size 863.8 kB
Tags CPython 3.10 macOS 11.0+ x86-64
SHA-256 checksum
How to use checksums
3558d662b531c39ae371dd8e233f97a35729dbdc3c9ec2a4441829cb5f7819cc
BLAKE2b-256 checksum
How to use checksums
def035a556cd68cfbde29caea0e0798d4f536b2075077caaf36b00bc2c2c40a7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.2

Release files / aldakit-0.5.0-cp310-cp310-macosx_11_0_arm64.whl

Download URL aldakit-0.5.0-cp310-cp310-macosx_11_0_arm64.whl
Size 841.7 kB
Tags CPython 3.10 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
bca681d75870c77c92a85a817e4fc4c29c8772f09acfb0dd513651c3a87147ff
BLAKE2b-256 checksum
How to use checksums
c38680588b19bdc9b9495a4b343049dadeb15ec9e34263f233175cfb977a86d8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.2

Release history Release notifications | RSS feed

This release

0.5.0 This release

26 release files

0.4.0

26 release files

0.3.1

26 release files

0.1.9

26 release files

0.1.8

26 release files

0.1.4

6 release files

0.1.3

6 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page