Audio as Code

Make your first piece

The quickest route is to give Audio as Code to your coding agent. On the website, choose Copy agent prompt, paste it into the agent, and describe the music. The copied instructions include the actual source download and portable skill. Your agent sets up the framework locally and delivers the audio and editable project. You do not need to learn Python first.

Start with the website's listening pairs: The classic follows a credited public-domain score; Reimagined gives it a new arrangement by an AI agent. Compare the instruments, rhythm and mood, then open the editable scores. Both versions are synthesized from code. See the score credits and generator.

For example: "My puzzle game's mushroom shop needs a 20-second cue: curious marimba, a sleepy bass and one very important bell. Keep the score so we can change it later." After listening: "Keep the melody, lose half the bells, and give the ending another second."

The agent guide explains the handoff and revisions. If you already have the source, tell your agent to read skills/audio-as-code/SKILL.md in that folder and compose your brief. If it cannot fetch files, use Download source, extract the ZIP, and give it the folder.

You receive WAV, MIDI, an editable JSON score, composer source when used, and a render report. The coding agent needs shell access and Python 3.10+. First-time dependency installation needs network access or cached packages; rendering is then offline. The framework has no bundled AI model and needs no provider API key.

Developer route#

Prefer to work directly? The rest of this page walks through the same local framework. Audio as Code synthesizes instruments entirely from code: no recorded samples or SoundFonts. The website plays pre-rendered examples; Python does not run in your browser. The package is not published to a registry. Add it from Git to an existing Python project, or use the source download for a standalone composition workspace.

Add to an existing Python project#

From an existing project managed by uv, with Git installed:

shell
uv add "audio-as-code @ git+https://github.com/joaoCarvalho1000/audio-as-code.git"
uv run --locked aac --version
uv run --locked aac instruments
uv run --locked aac schema

Keep pyproject.toml and uv.lock with your project. The lock records the resolved Git commit and dependency versions; uv run --locked reuses that environment. To select a specific revision, append @FULL_COMMIT_SHA to the .git URL, replacing the placeholder with a verified full commit. This is a source install, not a registry package. It requires network access on first installation.

Give your agent this brief once installed:

text
Use the Audio as Code dependency in this project. Run uv run --locked aac
instruments and schema to discover its current contract. Compose an original
12-second exploration game loop with marimba, electric piano and bass. Save the
composer and editable JSON score in a fresh output folder. Validate and inspect
export readiness, then render WAV and export MIDI with their reports. Check the
actual duration and loop join. Tell me whether you could listen to it. Keep the
seed, melody and duration fixed when I request a revision.

Continue at step 2, using uv run --locked before the aac and Python commands. Save your composer in your own project. The portable skill has the complete composition and delivery workflow. When using a pinned revision, read the skill at that same revision; the installed CLI and schema are authoritative. The Git dependency installs the Python library and CLI; use the source workspace below if you also want the bundled tutorial scripts and examples.

1. Install from the source folder#

Open a terminal in the folder that contains pyproject.toml.

With uv (recommended)

shell
uv sync --locked
uv run aac --version
uv run aac instruments

This uses uv.lock, creates a local environment and installs the development tools. Prefix each command below with uv run, for example uv run aac demo -o output/song.json or uv run python first.py.

Without uv

shell
python -m venv .venv

On Windows, run .venv/Scripts/python.exe -m pip install -e .; on macOS/Linux, run .venv/bin/python -m pip install -e .. No activation is necessary. Replace aac below with .venv/Scripts/python.exe -m audio_as_code on Windows or .venv/bin/python -m audio_as_code on macOS/Linux. Use that same environment's Python to run composer scripts.

The install downloads NumPy, Pydantic and mido. Editable installation means source changes take effect without reinstalling. aac instruments returns JSON with playable IDs, supported controls and model limitations.

2. Render the built-in demo#

shell
aac demo -o output/song.json
aac validate output/song.json
aac inspect output/song.json
aac render output/song.json -o output/song.wav --report output/report.json
aac midi output/song.json -o output/song.mid

Open output/song.wav in an audio player: it is an eight-bar arrangement with chords, bass, melody and drums. output/song.mid takes the notes into a DAW; output/song.json keeps the score editable. The render report records duration and level checks.

3. Write your first score in Python#

Save this as first.py in the source folder and run python first.py:

python
from audio_as_code import Pattern, Song, Track, export_midi, render

melody = Pattern.sequence(["C4", "E4", "G4", None], step=0.5).repeat(4)
kick = Pattern.sequence([36, None], step=1, gate=0.3).repeat(4)

song = Song(
    title="My first loop",
    bpm=110,
    beats=8,
    seed=42,
    tracks=[
        Track(name="Melody", instrument="pluck", notes=melody.notes, gain=0.5),
        Track(name="Kick", instrument="kick", notes=kick.notes, gain=0.7),
    ],
)

song.save("output/loop.json")
report = render(song, "output/loop.wav")
export_midi(song, "output/loop.mid")
print(report["wav"]["duration_seconds"], report["warnings"])

What the pieces mean:

  • beats=8 is the song length in quarter-note beats: two bars of 4/4. At 110 BPM that is 8 × 60 / 110 ≈ 4.36 seconds. Notes must end by beat 8.
  • Pattern.sequence(steps, step=0.5) places one item per half beat (an eighth note). A string or integer is a pitch, a list is a chord, None is a rest.
  • gate is the fraction of each step a note sounds (default 0.8).
  • .repeat(4) repeats the phrase end to end, keeping trailing rests.
  • seed fixes the generated noise in drums and string excitation, so the same score renders the same audio in the same environment.

4. Or write the score as JSON#

Any language can produce this file. Save it as output/phrase.json:

json
{
  "schema_version": "1",
  "title": "A small phrase",
  "bpm": 120,
  "beats": 4,
  "seed": 7,
  "tracks": [{
    "name": "Lead",
    "instrument": "pluck",
    "gain": 0.6,
    "notes": [
      {"pitch": "C4", "start": 0, "duration": 0.8},
      {"pitch": "E4", "start": 1, "duration": 0.8},
      {"pitch": "G4", "start": 2, "duration": 1.5}
    ]
  }]
}
shell
aac validate output/phrase.json
aac render output/phrase.json -o output/phrase.wav

If validation fails, its message identifies the score problem to fix before rendering. The agent guide explains the full error format for automated workflows.

5. Run the tutorial examples#

Six scripts sit next to these pages in examples/, starting with examples/01_first_score.py. From the source folder they are at docs/site/examples/. The first five write to their own folders under output/docs-examples/, or to a directory you pass as the first argument. The handoff script takes an input score and a new output directory.

ScriptTeachesOutput length
01_first_score.pyPatterns, tracks, WAV + MIDI, report10 s
02_motif_and_progression.pyMotif transposition, chord voicings, bass line, accents18 s
03_song_form.pySections, dynamics, arrangement density, stems89 s
04_expressive_controls.pyTone controls, pan, velocity, drum kit pitches12 s
05_agent_loop.py with agent-score.jsonCLI-only validate → render → revise loop10 s per candidate
06_agent_handoff.pyInspect export readiness, render and deliver files to another creative toolMatches the input score, including tails
shell
python docs/site/examples/01_first_score.py

Rendering is offline and CPU-bound. On the machine used to write these pages, the 89-second form example took about two minutes; short sketches take seconds.

Where to go next#

  • Composition guide: time, pitch, patterns, harmony, form, controls, and mixing.
  • Agent guide: a copyable prompt and the exact tool-call loop for AI agents.
  • Reference: every CLI command, Python function, score field, and report field.
  • llms.txt: a machine-readable index of these resources.

The project is MIT licensed; see the LICENSE file in the source folder.

Next: Composing