A complete-song source lets one score play another score's full arranged performance through its own filters and effects. Design: Complete Song Source.
import "my-score" as station
receiver = patch {
source = songSource station.film 24s |> lpf 6000Hz,
gain = 0.5
}
radioTrack = play receiver (!"c4" |> slow 8) |> phraseOrigin "entry" |> once
station.film must be a directly imported public song { … } binding with a finite arrange … |> once. Its own tempo, meter, key, tuning, seed, patterns, scene automation, buses and mixer are preserved. Selective imports work too. Ordinary imports continue to reuse individual parts. In the browser workbench, missing shipped song modules are fetched during preparation. Saved import snapshots and edited module buffers take precedence.
24s is the source position at parent transport zero. The source advances by one second per parent transport second, including while its track is inactive. A later note or scene entry reads the current position; it does not restart the recording. Negative offsets delay the beginning. Positions before the beginning or after the prepared ending return silence. Offsets must be constant seconds, within ±600. Note pitch does not transpose a complete-song source.
A voice still follows the usual note lifetime and release rules. Use an entry-origin note with a duration matching the station visit, as in radio-from-modules.volta. Leaving a scene stops new notes; it does not abruptly kill a held note or its release.
Preparation and controls#
The child module is embedded in the parent's IR and its complete arrangement is rendered when prepared, with two seconds of release tail. No manually exported song file or cut excerpt is needed. The normal sample manifest supplies any recordings the child uses. Desktop and browser use the same Rust renderer. Desktop preparation runs through the existing background bake worker; the browser uses its offline worker. The audio callback only reads stereo PCM.
Changing the imported score and recompiling rebuilds its source. Desktop preparation caches by child IR and relevant audio dependency contents; changing a sample's contents also invalidates the cache. Multiple reads of one song share its prepared buffer. The browser does not persist a disk cache. History captures the child IR and its external audio inputs, and rebuilds the derived complete-song buffers when restored. It does not serialize another copy of each prepared full performance.
The child's written automation plays as rendered. Parent filters, gain, pan, width and effects stay live. Child instrument parameters cannot be controlled live through this boundary in this first version.
The prepared audio keeps the child's rendered output level; the parent applies its own normal gain and mixer stages afterward. It is not automatically normalized to match another station. Balance the receiver tracks in the parent.
Current limits#
- A finite child arrangement is required. Interactive graph songs and looping arrangements are not supported by this first version.
- Hosted plugins, neural processors, live Magenta instruments and live input cannot be prepared here.
- Each child is limited to ten minutes; nesting is limited to four levels.
- Preparation takes time and memory proportional to the songs' duration. The initial render must finish before a newly added station is audible.
- This is prepared full-song playback. Running independent child instruments live and exposing their controls is a separate future extension.