Skip to content
This repository was archived by the owner on Jun 19, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions packages/core/pattern.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -2110,6 +2110,24 @@ export const segment = register('segment', function (rate, pat) {
return pat.struct(pure(true)._fast(rate)).setTactus(rate);
});

/**
* The function `swingBy x n` breaks each cycle into `n` slices, and then delays events in the second half of each slice by the amount `x`, which is relative to the size of the (half) slice. So if `x` is 0 it does nothing, `0.5` delays for half the note duration, and 1 will wrap around to doing nothing again. The end result is a shuffle or swing-like rhythm
* @param {number} subdivision
* @param {number} offset
* @example
* s("hh*8").swingBy(1/3, 4)
*/
export const swingBy = register('swingBy', (swing, n, pat) => pat.inside(n, late(seq(0, swing / 2))));

/**
* Shorthand for swingBy with 1/3:
* @param {number} subdivision
* @example
* s("hh*8").swing(4)
* // s("hh*8").swingBy(1/3, 4)
*/
export const swing = register('swing', (n, pat) => pat.swingBy(1 / 3, n));

/**
* Swaps 1s and 0s in a binary pattern.
* @name invert
Expand Down
106 changes: 106 additions & 0 deletions test/__snapshots__/examples.test.mjs.snap
Original file line number Diff line number Diff line change
Expand Up @@ -7298,6 +7298,112 @@ exports[`runs examples > example "sustain" example index 0 1`] = `
]
`;

exports[`runs examples > example "swing" example index 0 1`] = `
[
"[ 0/1 → 1/8 | s:hh ]",
"[ 1/24 ⇜ (1/8 → 1/6) | s:hh ]",
"[ (1/6 → 1/4) ⇝ 7/24 | s:hh ]",
"[ 1/4 → 3/8 | s:hh ]",
"[ 7/24 ⇜ (3/8 → 5/12) | s:hh ]",
"[ (5/12 → 1/2) ⇝ 13/24 | s:hh ]",
"[ 1/2 → 5/8 | s:hh ]",
"[ 13/24 ⇜ (5/8 → 2/3) | s:hh ]",
"[ (2/3 → 3/4) ⇝ 19/24 | s:hh ]",
"[ 3/4 → 7/8 | s:hh ]",
"[ 19/24 ⇜ (7/8 → 11/12) | s:hh ]",
"[ (11/12 → 1/1) ⇝ 25/24 | s:hh ]",
"[ 1/1 → 9/8 | s:hh ]",
"[ 25/24 ⇜ (9/8 → 7/6) | s:hh ]",
"[ (7/6 → 5/4) ⇝ 31/24 | s:hh ]",
"[ 5/4 → 11/8 | s:hh ]",
"[ 31/24 ⇜ (11/8 → 17/12) | s:hh ]",
"[ (17/12 → 3/2) ⇝ 37/24 | s:hh ]",
"[ 3/2 → 13/8 | s:hh ]",
"[ 37/24 ⇜ (13/8 → 5/3) | s:hh ]",
"[ (5/3 → 7/4) ⇝ 43/24 | s:hh ]",
"[ 7/4 → 15/8 | s:hh ]",
"[ 43/24 ⇜ (15/8 → 23/12) | s:hh ]",
"[ (23/12 → 2/1) ⇝ 49/24 | s:hh ]",
"[ 2/1 → 17/8 | s:hh ]",
"[ 49/24 ⇜ (17/8 → 13/6) | s:hh ]",
"[ (13/6 → 9/4) ⇝ 55/24 | s:hh ]",
"[ 9/4 → 19/8 | s:hh ]",
"[ 55/24 ⇜ (19/8 → 29/12) | s:hh ]",
"[ (29/12 → 5/2) ⇝ 61/24 | s:hh ]",
"[ 5/2 → 21/8 | s:hh ]",
"[ 61/24 ⇜ (21/8 → 8/3) | s:hh ]",
"[ (8/3 → 11/4) ⇝ 67/24 | s:hh ]",
"[ 11/4 → 23/8 | s:hh ]",
"[ 67/24 ⇜ (23/8 → 35/12) | s:hh ]",
"[ (35/12 → 3/1) ⇝ 73/24 | s:hh ]",
"[ 3/1 → 25/8 | s:hh ]",
"[ 73/24 ⇜ (25/8 → 19/6) | s:hh ]",
"[ (19/6 → 13/4) ⇝ 79/24 | s:hh ]",
"[ 13/4 → 27/8 | s:hh ]",
"[ 79/24 ⇜ (27/8 → 41/12) | s:hh ]",
"[ (41/12 → 7/2) ⇝ 85/24 | s:hh ]",
"[ 7/2 → 29/8 | s:hh ]",
"[ 85/24 ⇜ (29/8 → 11/3) | s:hh ]",
"[ (11/3 → 15/4) ⇝ 91/24 | s:hh ]",
"[ 15/4 → 31/8 | s:hh ]",
"[ 91/24 ⇜ (31/8 → 47/12) | s:hh ]",
"[ (47/12 → 4/1) ⇝ 97/24 | s:hh ]",
]
`;

exports[`runs examples > example "swingBy" example index 0 1`] = `
[
"[ 0/1 → 1/8 | s:hh ]",
"[ 1/24 ⇜ (1/8 → 1/6) | s:hh ]",
"[ (1/6 → 1/4) ⇝ 7/24 | s:hh ]",
"[ 1/4 → 3/8 | s:hh ]",
"[ 7/24 ⇜ (3/8 → 5/12) | s:hh ]",
"[ (5/12 → 1/2) ⇝ 13/24 | s:hh ]",
"[ 1/2 → 5/8 | s:hh ]",
"[ 13/24 ⇜ (5/8 → 2/3) | s:hh ]",
"[ (2/3 → 3/4) ⇝ 19/24 | s:hh ]",
"[ 3/4 → 7/8 | s:hh ]",
"[ 19/24 ⇜ (7/8 → 11/12) | s:hh ]",
"[ (11/12 → 1/1) ⇝ 25/24 | s:hh ]",
"[ 1/1 → 9/8 | s:hh ]",
"[ 25/24 ⇜ (9/8 → 7/6) | s:hh ]",
"[ (7/6 → 5/4) ⇝ 31/24 | s:hh ]",
"[ 5/4 → 11/8 | s:hh ]",
"[ 31/24 ⇜ (11/8 → 17/12) | s:hh ]",
"[ (17/12 → 3/2) ⇝ 37/24 | s:hh ]",
"[ 3/2 → 13/8 | s:hh ]",
"[ 37/24 ⇜ (13/8 → 5/3) | s:hh ]",
"[ (5/3 → 7/4) ⇝ 43/24 | s:hh ]",
"[ 7/4 → 15/8 | s:hh ]",
"[ 43/24 ⇜ (15/8 → 23/12) | s:hh ]",
"[ (23/12 → 2/1) ⇝ 49/24 | s:hh ]",
"[ 2/1 → 17/8 | s:hh ]",
"[ 49/24 ⇜ (17/8 → 13/6) | s:hh ]",
"[ (13/6 → 9/4) ⇝ 55/24 | s:hh ]",
"[ 9/4 → 19/8 | s:hh ]",
"[ 55/24 ⇜ (19/8 → 29/12) | s:hh ]",
"[ (29/12 → 5/2) ⇝ 61/24 | s:hh ]",
"[ 5/2 → 21/8 | s:hh ]",
"[ 61/24 ⇜ (21/8 → 8/3) | s:hh ]",
"[ (8/3 → 11/4) ⇝ 67/24 | s:hh ]",
"[ 11/4 → 23/8 | s:hh ]",
"[ 67/24 ⇜ (23/8 → 35/12) | s:hh ]",
"[ (35/12 → 3/1) ⇝ 73/24 | s:hh ]",
"[ 3/1 → 25/8 | s:hh ]",
"[ 73/24 ⇜ (25/8 → 19/6) | s:hh ]",
"[ (19/6 → 13/4) ⇝ 79/24 | s:hh ]",
"[ 13/4 → 27/8 | s:hh ]",
"[ 79/24 ⇜ (27/8 → 41/12) | s:hh ]",
"[ (41/12 → 7/2) ⇝ 85/24 | s:hh ]",
"[ 7/2 → 29/8 | s:hh ]",
"[ 85/24 ⇜ (29/8 → 11/3) | s:hh ]",
"[ (11/3 → 15/4) ⇝ 91/24 | s:hh ]",
"[ 15/4 → 31/8 | s:hh ]",
"[ 91/24 ⇜ (31/8 → 47/12) | s:hh ]",
"[ (47/12 → 4/1) ⇝ 97/24 | s:hh ]",
]
`;

exports[`runs examples > example "timecat" example index 0 1`] = `
[
"[ 0/1 → 3/4 | note:e3 ]",
Expand Down
8 changes: 8 additions & 0 deletions website/src/pages/learn/time-modifiers.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -106,4 +106,12 @@ Some of these have equivalent operators in the Mini Notation:

<JsDoc client:idle name="ribbon" h={0} />

## swingBy

<JsDoc client:idle name="swingBy" h={0} />

## swing

<JsDoc client:idle name="swing" h={0} />

Apart from modifying time, there are ways to [Control Parameters](/functions/value-modifiers/).