Skip to content

Compact Notation

This content is for v0.7. Switch to the latest version for up-to-date documentation.

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];