Skip to content

arrange()

arrange() maps ctx.cycle to a section in a predefined structure, replacing manual ctx.cycle % N branching with a named, ordered list of sections.

Signature

arrange(ctx: IncantoContext, sections: SectionDef[]): (Pattern | MetaEvent)[]

arrange() returns an array of patterns for the current cycle. Use yield* to spread them into the generator:

yield* arrange(ctx, sections)

SectionDef

FieldTypeDescription
namestringSection label (for readability only)
cyclesnumberHow many cycles this section lasts
patterns(Pattern | MetaEvent)[]Patterns to play in this section
crossfadenumber (optional)For the first N cycles of this section, also yield the previous section’s patterns

Basic example

function* song(ctx) {
const key = scales(4, 'C4:minor')
const bass = vasynth({ wave: 'sawtooth', gain: 0.5 })
const lead = vasynth({ wave: 'square', gain: 0.3 })
const kk = kick({ freq: 55, gain: 0.7 })
const bassLine = cast(bass, key, seq(4, '0,_,3,_,5,_,3,_'), ctx)
const kickPat = cast(kk, 'drums', seq(4, 'x.x.x.x.'), ctx)
const leadLine = cast(lead, key, seq(4, '7,5,4,_,3,_,4,5'), ctx)
yield* arrange(ctx, [
{ name: 'intro', cycles: 8, patterns: [bassLine, kickPat] },
{ name: 'verse', cycles: 16, patterns: [bassLine, kickPat, leadLine] },
{ name: 'chorus', cycles: 8, patterns: [bassLine, kickPat, leadLine] },
])
}

After cycle 31 (8 + 16 + 8 − 1), arrange() loops the last section indefinitely.

Crossfade overlap

Set crossfade on a section to play both that section and the preceding one simultaneously for the first N cycles. Both sections’ patterns must be computed each cycle (they are, since the generator runs per cycle):

yield* arrange(ctx, [
{ name: 'verse', cycles: 16, patterns: [bassLine, pad] },
{
name: 'chorus',
cycles: 8,
patterns: [bassLine, lead],
crossfade: 4, // cycles 16–19: yield verse AND chorus patterns together
},
])

During the crossfade window all patterns play at full volume. Use different gain values on the machines to balance the blend.

Replacing manual branching

Before:

const c = ctx.cycle
if (c < 8) {
yield cast(bass, key, bassSeq, ctx)
} else if (c < 24) {
yield cast(bass, key, bassSeq, ctx)
yield cast(lead, key, leadSeq, ctx)
}

After:

yield* arrange(ctx, [
{ name: 'intro', cycles: 8, patterns: [cast(bass, key, bassSeq, ctx)] },
{ name: 'verse', cycles: 16, patterns: [cast(bass, key, bassSeq, ctx), cast(lead, key, leadSeq, ctx)] },
])