cast() & ctx
cast(machine, scale, seq, ctx?, opts?)
Combines a machine, a pitch source, and a sequence into a Pattern that the
engine can schedule.
cast( machine: Machine, scaleOrKit: string | ScalePattern | ChordPattern, seq: Seq, ctx?: IncantoContext, opts?: { id?: string },): PatternArguments
| Argument | Type | Description |
|---|---|---|
machine | Machine | Instrument returned by vasynth(), modal(), etc. |
scale | ScalePattern | ChordPattern | 'drums' | Pitch source. Pass 'drums' for percussion. |
seq | Seq | Sequence from seq() |
ctx | IncantoContext (optional) | Cycle context from the song generator |
opts.id | string (optional) | Explicit phrase ID — overrides the auto-derived identity (machine + scale + DSL) |
Drums mode
Pass 'drums' as the scale argument to use percussion mode. The sequence
degrees are interpreted as hit (x) / rest (.) instead of pitch indices.
Example
function* song(ctx) { const key = scales(4, 'C4:minor') const synth = vasynth({ wave: 'sawtooth', gain: 0.5 }) const kk = kick({ freq: 58, gain: 0.7 })
yield cast(synth, key, seq(4, '0,2,4,~'), ctx) yield cast(kk, 'drums', seq(4, 'x.x...x.'), ctx)}ctx and ctx.cycle
ctx is the context object passed into the song generator each cycle.
ctx.cycle— current cycle number, starting at0ctx.beatsPerCycle— current cycle length in beatsctx.rand()— seeded pseudo-random number, reproducible per seed. Also takes a range and has an integer variant — see Random numbers.ctx.rand()→[0, 1),ctx.rand(max)→[0, max),ctx.rand(min, max)→[min, max)ctx.rand.int(min, max)→ integer in[min, max](both ends inclusive)
Pass ctx to cast() so that the scheduler can track phrase phase correctly.
Modifiers (every2, robin, rev, etc.) advance based on the number of times
the seq has been repeated within the polymeter — not the global cycle number.
Use ctx.cycle directly to switch phrases over time:
if (ctx.cycle % 8 < 4) { yield cast(synth, key, seq(4, '0,2,4,~'), ctx)} else { yield cast(synth, key, seq(4, '7,5,4,2'), ctx)}opts.id — explicit phrase identity
By default, the scheduler identifies each phrase by its machine name, scale, and DSL string. The repetition counter for modifiers (rev, robin, etc.) starts from zero when the phrase first appears, and resets if the phrase is not yielded for one cycle.
Use opts.id to give two phrases with the same DSL an independent counter, or when the DSL string is generated dynamically:
// two phrases with identical DSL tracked independentlyyield cast(synth, key, seq(3, '(rev:0,2,4,5,3)'), ctx, { id: 'melody-a' })yield cast(synth, key, seq(3, '(rev:0,2,4,5,3)'), ctx, { id: 'melody-b' })Bounce uses the same pattern repetition, offsets, articulations, bus routing and machine automation as live playback. Negative offsets in the first cycle are included as a pickup at the beginning of the exported audio. Nested arrays of patterns and control events may be yielded together.
When a sequence repeats more often than a dynamic scale, each repetition resolves
its notes at the song’s current absolute beat. For example,
cast(machine, scales(4, 'C4:major,D4:major'), seq(1, '0'), ctx)
plays C4, C4, D4, D4 in a four-beat cycle. This also applies to scales31.
Current key and chord
Nimbus shows the key and chord in the Header when a pitched note starts, including
inversions such as Dm7/F. Scale-only patterns show their key. Simultaneous
harmonies are listed together; 31EDO harmony is marked explicitly, with ^ / v
representing one-step shifts. Unnamed chord stacks are shown as pitch names.
The display follows scheduled note durations and clears during rests, on Stop, and when Apply or an A/B swap is accepted. The new harmony appears when the new notes start, not when the lookahead scheduler evaluates the code. Instrument release tails and reverb do not extend the display. Percussion and unpitched sample slices do not supply a key.
Library consumers can receive the same resolved information:
const engine = new Incanto({ onHarmony(harmonies) { // Harmony[]: { key: string, chord?: string, edo: 12 | 31 }[] // Empty when no scheduled pitched notes remain, or on stop/swap. renderHarmony(harmonies) },})useIncanto() exposes this array as harmonies. NoteEvent.harmony holds resolved
chord metadata; scale patterns supply Pattern.resolveHarmony(absoluteBeat).
These describe the DSL pitch source, rather than estimating harmony from audio.