Bird File Loader (app/loader/)
Parsing and loading .bird music notation files into the Tracktion Engine.
Architecture
Files
| File | Purpose |
|---|---|
BirdLoader.cpp/.h | Core parser: .bird text → BirdParseResult → populateEdit() → te::Edit. Contains the tokenizer, section parser, note/velocity/pattern resolvers, and arrangement logic. |
BirdFileOps.cpp | File I/O operations: reading/writing .bird files, content validation, scheduling reloads with debouncing. |
Entitlements.plist | macOS app sandbox entitlements for file system access. |
Key Data Structures
BirdParseResult
Output of parse() — contains all data needed to populate a Tracktion Edit:
tracks— channel definitions (name, plugin keyword, FX, strip, type)sections— section definitions with per-channel note/velocity/pattern dataarrangement— ordered list of(sectionName, barCount)pairsglobalBars— default bar count (frombtoken)key— project key signature
Parse → Edit Pipeline
- Parse (background thread): Tokenizes
.birdtext line-by-line, resolves durations to ticks, expands chord names to MIDI pitches, handles velocity cycling and relative offsets - Populate (message thread): Creates/reuses Tracktion tracks, loads plugins by keyword lookup, creates MIDI clips per section, inserts notes at computed tick positions
Design Principles
- Background parsing —
parse()is thread-safe and does no JUCE/Tracktion calls. OnlypopulateEdit()touches the engine (must be on message thread). - Keyword → plugin mapping — Plugin keywords (e.g.,
mini,kick,surge) are resolved to full plugin names via a lookup table in the parser. Seedocumentation/bird.mdfor the keyword list. - Incremental reload —
scheduleReload()debounces rapid edits (from the AI copilot or bird file panel) to avoid re-parsing on every keystroke. - Section offsets — Each section’s bar position in the arrangement determines the absolute beat offset for its MIDI clips. This arithmetic is critical for correct playback.
Extending
To add a new.bird token:
- Add parsing logic in
BirdLoader::parse()— handle the new token in the line tokenizer - Store the parsed data in
BirdParseResult - Apply it in
populateEdit()when creating Tracktion clips/tracks - Document the token in
documentation/bird.md