Skip to content

Compact Notation

Resonon’s compact notation provides concise modifiers for rhythm specification. These modifiers let you repeat, extend, or replicate elements without verbose nesting.

The fast modifier repeats an element n times within its time slot, making it play faster:

[bd*2] // bd plays twice in the cycle
[bd sd*2] // bd once, sd twice (in same space as bd)
[C4*3 D4] // C4 plays 3 times in first half, D4 once in second

*n is equivalent to nesting:

// These are equivalent:
[bd*2]
[[bd bd]]
// And these:
[bd sd*2]
[bd [sd sd]]

Fractional values are allowed. *1.5 repeats the element 1.5 times in its slot — the first instance plays in full, the second plays only the first half:

[bd*1.5 sd] // bd plays 1.5 times in the first half
[C4*2.5 D4] // C4 plays 2.5 times in its slot

The weight modifier gives an element n times its normal time slot, making it longer:

[bd@2 sd] // bd gets 2/3 of cycle, sd gets 1/3
[C4 _@2 D4] // C4 1/4, rest 1/2, D4 1/4
[bd@3 sd@1] // bd gets 3/4, sd gets 1/4

Weight affects time distribution, not repetition. Each element plays once, just for longer.

Weights are relative. The total time is divided proportionally:

PatternWeightsDistribution
[bd@2 sd]2 + 1 = 3bd: 2/3, sd: 1/3
[bd@3 sd@1]3 + 1 = 4bd: 3/4, sd: 1/4
[a@1 b@2 c@1]1 + 2 + 1 = 4a: 1/4, b: 2/4, c: 1/4

Fractional weights work the same way:

PatternWeightsDistribution
[bd@1.5 sd]1.5 + 1 = 2.5bd: 3/5, sd: 2/5
[bd@0.5 sd@1.5]0.5 + 1.5 = 2bd: 1/4, sd: 3/4

The replicate modifier creates n separate copies of an element, each in its own slot:

[bd!4] // bd bd bd bd (4 separate slots)
[bd!2 sd!2] // bd bd sd sd (4 total slots)
[C4!2 D4] // C4 C4 D4 (3 equal slots)

Unlike *n which speeds up within one slot, !n creates more slots at normal speed.

The slow modifier makes an element play at 1/n speed, effectively stretching it over n cycles:

[C4 D4 E4]/2 // Pattern spans 2 cycles
[bd sd]/4 // Pattern spans 4 cycles

/n is equivalent to calling .slow(n) on the pattern.

Fractional values are allowed:

[C4 D4 E4]/1.5 // Pattern spans 1.5 cycles

The velocity marker sets how hard a note is played. Syntax: note^velocity, where velocity is an integer from 0 to 127:

[C4^120 D4^40] // C4 loud, D4 soft
[C4^127 C4^80 C4^40] // Decreasing velocity

Velocity works on notes, numbers, and chords:

Element typeExampleDescription
NoteC4^100Note with velocity 100
Number60^90MIDI number with velocity 90
ChordC4:maj^80Chord with velocity 80 (all notes)

Accent patterns use high and low velocities to create rhythmic emphasis:

// Accent on beat 1
[C4^120 C4^60 C4^60 C4^60]
// Ghost notes on a snare
[_ sd^40 _ sd^110]
// Crescendo over 4 notes
[C4^30 D4^60 E4^90 F4^120]

Velocity goes before Euclidean params and modifiers in the element syntax:

[C4^100*2] // Velocity 100, played twice fast
[C4^80(3,8)] // Velocity 80, Euclidean rhythm
[bd^110!4] // Loud kick replicated 4 times

Inline chord notation lets you write chords directly in patterns. Syntax: Root:Quality, where Root is a note and Quality is a chord type:

[C4:maj E4:min] // C major then E minor
[C4:maj7 F4:maj7 G4:7 C4:maj7] // Jazz progression

Resonon supports these chord qualities, listed by category:

Triads:

QualityNotes (from C)Aliases
majC E G
minC Eb Gm
dimC Eb Gb
augC E Ab

Sevenths:

QualityNotes (from C)Aliases
7C E G Bbdom, dom7
maj7C E G B
min7C Eb G Bbm7
dim7C Eb Gb A
aug7C E Ab Bb

Extended:

QualityNotes (from C)Aliases
9C E G Bb D
maj9C E G B D
min9C Eb G Bb Dm9
add9C E G D

Sixths:

QualityNotes (from C)Aliases
6C E G A
min6C Eb G Am6

Suspended and Power:

QualityNotes (from C)
sus2C D G
sus4C F G
5C G

Append ~n for inversions. Positive values move the lowest notes up an octave, negative values move the highest notes down:

C4:maj // Root position: C4 E4 G4
C4:maj~1 // 1st inversion: E4 G4 C5
C4:maj~2 // 2nd inversion: G4 C5 E5
C4:maj7~1 // 1st inversion: E4 G4 B4 C5

Drop voicings use negative values:

C4:maj~-1 // Drop 2: moves 2nd-from-top note down an octave

Velocity applies to all notes in the chord:

[C4:maj^100 G4:min^60] // Loud C major, soft G minor

Chords support the same modifiers as notes:

[C4:maj*2 G4:min] // C major played twice fast, then G minor
[C4:maj@2 G4:7] // C major gets 2/3 time, G7 gets 1/3
[C4:min7(3,8)] // C minor 7th in Euclidean rhythm
[C4:maj!2 F4:maj] // C major twice, then F major
// ii-V-I jazz progression
[D4:min7 G4:7 C4:maj7@2]
// Pop progression: I-V-vi-IV
[C4:maj G4:maj A3:min F4:maj]
// With inversions for smooth voice leading
[C4:maj E4:min~1 F4:maj A3:min~1]

Samples support method calls for transformation directly in pattern notation. Syntax: sample.method():

[bd.loud() sd.soft()] // Loud kick, soft snare
[bd.pitch(12) sd] // Kick pitched up one octave
MethodVelocityDescription
vel(v)CustomSet velocity (0 to infinity)
ghost()0.3Ghost note (quiet)
soft()0.5Soft hit
accent()1.0Accented hit
loud()1.2Loud hit
[bd.loud() sd.ghost() hh.soft() hh.accent()]
[bd.vel(0.7) sd.vel(1.5)]
MethodDescription
pitch(semitones)Pitch shift sample
pan(position)Set stereo position [-1.0 to 1.0]
reverse()Play sample backwards
slice(start, end)Play portion of sample [0-1 range]
[bd.pitch(-5) sd] // Kick down a fifth
[bd.pan(-1) sd.pan(1)] // Kick left, snare right
[bd.reverse() sd] // Reversed kick
[bd.slice(0, 0.5) sd] // First half of kick sample

Chain multiple methods for complex transformations:

[bd.loud().pan(-0.3) sd.soft().pitch(2)]
[hh.ghost().pan(-0.5) hh.ghost().pan(0.5)] // Stereo ghost hats
[bd.loud().reverse() sd.accent().pitch(-12)]

Sample methods work with Euclidean patterns and modifiers:

[bd.loud()*2 sd.soft()] // Loud kick twice fast, soft snare
[hh.ghost()!8] // 8 ghost hi-hats
[bd.pitch(7)(3,8) sd] // Pitched kick in Euclidean rhythm
[bd.loud()@2 sd.accent()] // Loud kick weighted 2:1 against snare
ModifierEffectExampleEquivalent
*nSpeed up (faster)[bd*2][[bd bd]]
/nSlow down[bd sd]/2.slow(2)
@nExtend duration[bd@2 sd]Time weighted 2:1
!nReplicate slots[bd!2][bd bd]
^nSet velocity[C4^100]Note at velocity 100
:qualityInline chord[C4:maj]C major chord
.method()Sample transform[bd.loud()]Loud kick

The full element syntax chains velocity, Euclidean params, and modifiers. The order follows the grammar:

Notes: note^vel(euclid)*mod

C4^100(3,8)*2 // Note, velocity 100, Euclidean 3/8, fast x2

Chords: note:quality~inv^vel(euclid)*mod

C4:min7~1^90(3,8)@2 // Chord, 1st inversion, velocity 90, Euclidean, weighted

Samples: sample.method()(euclid)*mod

bd.loud()(3,8)*2 // Sample, loud, Euclidean 3/8, fast x2
// Accented Euclidean kick with ghost hi-hats
[bd^120(3,8) hh.ghost()!8]
// Chord progression with velocity shaping
[C4:maj7^100 A3:min7^80 D4:min7^90 G4:7^110]
// Polyrhythmic drums with methods and modifiers
[bd.loud()*2 sd.accent(), hh.soft()!6, <_ oh.vel(0.4)>]
use "std/instruments" { Sampler, Kit };
let drums = AudioTrack(
Sampler(Kit("808")),
[bd.loud()*2 sd.accent(), hh.ghost()!8, <_ oh.soft()>]
);
let bass = MidiTrack(1);
bass << [C2^100 _ C2^60 _];
let chords = MidiTrack(2);
chords << [C4:maj7^80@2 F4:maj7^70@2];
let lead = MidiTrack(3);
lead << [E5^110 D5^90 C5^70 D5^100];