treble-lang 0.7.0

A live coding language for treble
Documentation
# treble-lang

The Treble language: parser, session engine, and — behind the `render` feature —
the lowering that turns a buffer into something the engine can play.

`LANGUAGE.md` is the specification and the authority. This file is just how to
run the thing.

## The library

```toml
treble-lang = { git = "https://github.com/MinIndustry/treble-lang.git", tag = "0.4.0" }
```

Parsing has no dependencies beyond `nom`. The engine is *not* pulled in: a tool
that only wants to read a buffer should not pay for a DSP stack.

```rust
let mut session = treble_lang::Session::new();
let result = session.evaluate(source);
if let Some(piece) = session.piece() {
    println!("{} cycles", piece.total_cycles());
}
```

## Rendering

The `render` feature adds `treble_lang::render`, which depends on `treble-core`:

```toml
treble-lang = { …, features = ["render"] }
```

- `render::compile` — mini-notation to events, `def` blocks to instrument
  specs, `fx` names resolved against the engine's registry. Shared with the
  live front end, so a rendered piece and a played performance compile through
  the same code.
- `render::offline` — drives that output through the engine to samples.
- `render::wav` — writes the result, metadata and all.

## The command line

```
cargo install --path . --features render

treble check  piece.rt      # parse, report errors, exit 1 on any
treble info   piece.rt      # sections, arrangement, spans, metadata
treble render piece.rt      # → piece.wav
```

`render` takes `-o/--out`, `-r/--rate`, `-f/--force`, `-q/--quiet`, `--json`,
and `-m/--meta key=value` (repeatable, overrides the file's own tags — handy for
stamping a build date or take number without editing the piece).

`load "<file.trbl>"` lines resolve **beside the piece file** (an absolute path
is used as written; nothing else is searched), so an album of pieces can share
one instrument library. `check` validates the loads too — a broken path or a
loaded file that sounds is reported before any render.

Progress is reported on stderr and the summary on stdout, so `--json` composes:

```
treble render piece.rt --json | jq .renderedSeconds
```

### Metadata

`meta` tags (LANGUAGE.md §8.9) travel into the WAV's `INFO` chunk, so a
rendered piece carries its own title rather than relying on the filename:

```
meta title    "Nocturne for a Slow Machine"
meta composer "F. Grimau"
meta comment  "One collection, three centres."
```

The key set is open. Well-known keys map to their standard tags; anything else
is filed alongside the comment rather than dropped.

## The language server

```
cargo install --path . --features serve
treble serve
```

`serve` speaks LSP on stdin and stdout for an editor: diagnostics (the same
checks as `check`, plus unknown instruments), completion, hover and
go-to-definition on instrument names, and document symbols. On top of LSP it
answers `treble/outline` and `treble/timeline` — the notes of chosen lines as
the renderer schedules them, each pointing back at the step that wrote it —
and plays through the default sound card with `treble/play` and
`treble/stop`. Playback renders the asked-for lines of one section, placed
where the piece first plays it, so a line heard alone sounds as it does in the
render; an edit to a playing piece is re-rendered and swapped in at the next
cycle. The protocol is written down in Quill's `PROTOCOL.md`, the editor it
was built for.

## An example piece

`pieces/nocturne.rt` is a complete five-and-a-half-minute piece — ten sections,
seven instruments defined in the buffer, a theme in three metres, and a
question-and-answer solo. It is the toolchain's end-to-end case:

```
treble check  pieces/nocturne.rt
treble info   pieces/nocturne.rt
treble render pieces/nocturne.rt
```

Renders are reproducible, so the WAV is not kept in the repository — the source
beside it is the artefact.

The analysis examples read its notes rather than its audio:

```
cargo run --features render --example notes   -- pieces/nocturne.rt
cargo run --features render --example clashes -- pieces/nocturne.rt
```