Merge remote-tracking branch 'origin/main' into docs

This commit is contained in:
Felix Roos 2023-01-08 23:44:27 +01:00
commit 93f520b941
5 changed files with 310 additions and 230 deletions

View File

@ -1,14 +1,59 @@
/*
euclid.mjs - <short description TODO>
Copyright (C) 2022 Strudel contributors - see <https://github.com/tidalcycles/strudel/blob/main/packages/core/euclid.mjs>
euclid.mjs - Bjorklund/Euclidean/Diaspora rhythms
Copyright (C) 2023 Rohan Drape and strudel contributors
See <https://github.com/tidalcycles/strudel/blob/main/packages/core/euclid.mjs> for authors of this file.
The Bjorklund algorithm implementation is ported from the Haskell Music Theory Haskell module by Rohan Drape -
https://rohandrape.net/?t=hmt
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { Pattern, timeCat, register } from './pattern.mjs';
import bjork from 'bjork';
import { rotate } from './util.mjs';
import { Pattern, timeCat, register, silence } from './pattern.mjs';
import { rotate, flatten } from './util.mjs';
import Fraction from './fraction.mjs';
const splitAt = function (index, value) {
return [value.slice(0, index), value.slice(index)];
};
const zipWith = (f, xs, ys) => xs.map((n, i) => f(n, ys[i]));
const left = function (n, x) {
const [ons, offs] = n;
const [xs, ys] = x;
const [_xs, __xs] = splitAt(offs, xs);
return [
[offs, ons - offs],
[zipWith((a, b) => a.concat(b), _xs, ys), __xs],
];
};
const right = function (n, x) {
const [ons, offs] = n;
const [xs, ys] = x;
const [_ys, __ys] = splitAt(ons, ys);
const result = [
[ons, offs - ons],
[zipWith((a, b) => a.concat(b), xs, _ys), __ys],
];
return result;
};
const _bjork = function (n, x) {
const [ons, offs] = n;
return Math.min(ons, offs) <= 1 ? [n, x] : _bjork(...(ons > offs ? left(n, x) : right(n, x)));
};
const bjork = function (ons, steps) {
const offs = steps - ons;
const x = Array(ons).fill([1]);
const y = Array(offs).fill([0]);
const result = _bjork([ons, offs], [x, y]);
return flatten(result[1][0]).concat(flatten(result[1][1]));
};
/**
* Changes the structure of the pattern to form an euclidean rhythm.
* Euclidian rhythms are rhythms obtained using the greatest common
@ -86,7 +131,7 @@ import Fraction from './fraction.mjs';
*/
const _euclidRot = function (pulses, steps, rotation) {
const b = bjork(steps, pulses);
const b = bjork(pulses, steps);
if (rotation) {
return rotate(b, -rotation);
}
@ -94,11 +139,11 @@ const _euclidRot = function (pulses, steps, rotation) {
};
export const euclid = register('euclid', function (pulses, steps, pat) {
return pat.struct(_euclidRot(steps, pulses, 0));
return pat.struct(_euclidRot(pulses, steps, 0));
});
export const { euclidrot, euclidRot } = register(['euclidrot', 'euclidRot'], function (pulses, steps, rotation, pat) {
return pat.struct(_euclidRot(steps, pulses, rotation));
return pat.struct(_euclidRot(pulses, steps, rotation));
});
/**
@ -111,14 +156,16 @@ export const { euclidrot, euclidRot } = register(['euclidrot', 'euclidRot'], fun
*/
const _euclidLegato = function (pulses, steps, rotation, pat) {
if (pulses < 1) {
return silence;
}
const bin_pat = _euclidRot(pulses, steps, rotation);
const firstOne = bin_pat.indexOf(1);
const gapless = rotate(bin_pat, firstOne)
const gapless = bin_pat
.join('')
.split('1')
.slice(1)
.map((s) => [s.length + 1, true]);
return pat.struct(timeCat(...gapless)).late(Fraction(firstOne).div(steps));
return pat.struct(timeCat(...gapless));
};
export const euclidLegato = register(['euclidLegato'], function (pulses, steps, pat) {

View File

@ -25,7 +25,6 @@
},
"homepage": "https://strudel.tidalcycles.org",
"dependencies": {
"bjork": "^0.0.1",
"fraction.js": "^4.2.0"
},
"gitHead": "0e26d4e741500f5bae35b023608f062a794905c2"

View File

@ -79,6 +79,40 @@ describe('mini', () => {
it('supports patterning euclidean rhythms', () => {
expect(minS('[a(<3 5>, <8 16>)]*2')).toEqual(minS('a(3,8) a(5,16)'));
});
it("reproduces Toussaint's example euclidean algorithms", () => {
const checkEuclid = function (spec, target) {
expect(minS(`x(${spec[0]},${spec[1]})`)).toEqual(minS(target));
};
checkEuclid([1, 2], 'x ~');
checkEuclid([1, 3], 'x ~ ~');
checkEuclid([1, 4], 'x ~ ~ ~');
checkEuclid([4, 12], 'x ~ ~ x ~ ~ x ~ ~ x ~ ~');
checkEuclid([2, 5], 'x ~ x ~ ~');
// checkEuclid([3, 4], "x ~ x x"); // Toussaint is wrong..
checkEuclid([3, 4], 'x x x ~'); // correction
checkEuclid([3, 5], 'x ~ x ~ x');
checkEuclid([3, 7], 'x ~ x ~ x ~ ~');
checkEuclid([3, 8], 'x ~ ~ x ~ ~ x ~');
checkEuclid([4, 7], 'x ~ x ~ x ~ x');
checkEuclid([4, 9], 'x ~ x ~ x ~ x ~ ~');
checkEuclid([4, 11], 'x ~ ~ x ~ ~ x ~ ~ x ~');
// checkEuclid([5, 6], "x ~ x x x x"); // Toussaint is wrong..
checkEuclid([5, 6], 'x x x x x ~'); // correction
checkEuclid([5, 7], 'x ~ x x ~ x x');
checkEuclid([5, 8], 'x ~ x x ~ x x ~');
checkEuclid([5, 9], 'x ~ x ~ x ~ x ~ x');
checkEuclid([5, 11], 'x ~ x ~ x ~ x ~ x ~ ~');
checkEuclid([5, 12], 'x ~ ~ x ~ x ~ ~ x ~ x ~');
// checkEuclid([5, 16], "x ~ ~ x ~ ~ x ~ ~ x ~ ~ x ~ ~ ~ ~"); // Toussaint is wrong..
checkEuclid([5, 16], 'x ~ ~ x ~ ~ x ~ ~ x ~ ~ x ~ ~ ~'); // correction
// checkEuclid([7, 8], "x ~ x x x x x x"); // Toussaint is wrong..
checkEuclid([7, 8], 'x x x x x x x ~'); // Correction
checkEuclid([7, 12], 'x ~ x x ~ x ~ x x ~ x ~');
checkEuclid([7, 16], 'x ~ ~ x ~ x ~ x ~ ~ x ~ x ~ x ~');
checkEuclid([9, 16], 'x ~ x x ~ x ~ x ~ x x ~ x ~ x ~');
checkEuclid([11, 24], 'x ~ ~ x ~ x ~ x ~ x ~ x ~ ~ x ~ x ~ x ~ x ~ x ~');
checkEuclid([13, 24], 'x ~ x x ~ x ~ x ~ x ~ x ~ x x ~ x ~ x ~ x ~ x ~');
});
it('supports the ? operator', () => {
expect(
mini('a?')

View File

@ -2,31 +2,31 @@
exports[`runs examples > example "_euclidRot" example index 0 1`] = `
[
"[ 1/5 → 2/5 | note:c3 ]",
"[ 3/5 → 4/5 | note:c3 ]",
"[ 6/5 → 7/5 | note:c3 ]",
"[ 8/5 → 9/5 | note:c3 ]",
"[ 11/5 → 12/5 | note:c3 ]",
"[ 13/5 → 14/5 | note:c3 ]",
"[ 16/5 → 17/5 | note:c3 ]",
"[ 18/5 → 19/5 | note:c3 ]",
"[ 0/1 → 1/5 | note:c3 ]",
"[ 2/5 → 3/5 | note:c3 ]",
"[ 1/1 → 6/5 | note:c3 ]",
"[ 7/5 → 8/5 | note:c3 ]",
"[ 2/1 → 11/5 | note:c3 ]",
"[ 12/5 → 13/5 | note:c3 ]",
"[ 3/1 → 16/5 | note:c3 ]",
"[ 17/5 → 18/5 | note:c3 ]",
]
`;
exports[`runs examples > example "_euclidRot" example index 1 1`] = `
[
"[ 0/1 → 1/4 | note:c3 ]",
"[ 1/4 → 1/2 | note:c3 ]",
"[ 1/2 → 3/4 | note:c3 ]",
"[ 3/4 → 1/1 | note:c3 ]",
"[ 1/1 → 5/4 | note:c3 ]",
"[ 5/4 → 3/2 | note:c3 ]",
"[ 3/2 → 7/4 | note:c3 ]",
"[ 7/4 → 2/1 | note:c3 ]",
"[ 2/1 → 9/4 | note:c3 ]",
"[ 9/4 → 5/2 | note:c3 ]",
"[ 5/2 → 11/4 | note:c3 ]",
"[ 11/4 → 3/1 | note:c3 ]",
"[ 3/1 → 13/4 | note:c3 ]",
"[ 13/4 → 7/2 | note:c3 ]",
"[ 7/2 → 15/4 | note:c3 ]",
"[ 15/4 → 4/1 | note:c3 ]",
]
`;
@ -49,18 +49,18 @@ exports[`runs examples > example "_euclidRot" example index 2 1`] = `
exports[`runs examples > example "_euclidRot" example index 3 1`] = `
[
"[ 1/7 → 2/7 | note:c3 ]",
"[ 3/7 → 4/7 | note:c3 ]",
"[ 5/7 → 6/7 | note:c3 ]",
"[ 8/7 → 9/7 | note:c3 ]",
"[ 10/7 → 11/7 | note:c3 ]",
"[ 12/7 → 13/7 | note:c3 ]",
"[ 15/7 → 16/7 | note:c3 ]",
"[ 17/7 → 18/7 | note:c3 ]",
"[ 19/7 → 20/7 | note:c3 ]",
"[ 22/7 → 23/7 | note:c3 ]",
"[ 24/7 → 25/7 | note:c3 ]",
"[ 26/7 → 27/7 | note:c3 ]",
"[ 0/1 → 1/7 | note:c3 ]",
"[ 2/7 → 3/7 | note:c3 ]",
"[ 4/7 → 5/7 | note:c3 ]",
"[ 1/1 → 8/7 | note:c3 ]",
"[ 9/7 → 10/7 | note:c3 ]",
"[ 11/7 → 12/7 | note:c3 ]",
"[ 2/1 → 15/7 | note:c3 ]",
"[ 16/7 → 17/7 | note:c3 ]",
"[ 18/7 → 19/7 | note:c3 ]",
"[ 3/1 → 22/7 | note:c3 ]",
"[ 23/7 → 24/7 | note:c3 ]",
"[ 25/7 → 26/7 | note:c3 ]",
]
`;
@ -104,22 +104,22 @@ exports[`runs examples > example "_euclidRot" example index 5 1`] = `
exports[`runs examples > example "_euclidRot" example index 6 1`] = `
[
"[ 1/9 → 2/9 | note:c3 ]",
"[ 1/3 → 4/9 | note:c3 ]",
"[ 5/9 → 2/3 | note:c3 ]",
"[ 7/9 → 8/9 | note:c3 ]",
"[ 10/9 → 11/9 | note:c3 ]",
"[ 4/3 → 13/9 | note:c3 ]",
"[ 14/9 → 5/3 | note:c3 ]",
"[ 16/9 → 17/9 | note:c3 ]",
"[ 19/9 → 20/9 | note:c3 ]",
"[ 7/3 → 22/9 | note:c3 ]",
"[ 23/9 → 8/3 | note:c3 ]",
"[ 25/9 → 26/9 | note:c3 ]",
"[ 28/9 → 29/9 | note:c3 ]",
"[ 10/3 → 31/9 | note:c3 ]",
"[ 32/9 → 11/3 | note:c3 ]",
"[ 34/9 → 35/9 | note:c3 ]",
"[ 0/1 → 1/9 | note:c3 ]",
"[ 2/9 → 1/3 | note:c3 ]",
"[ 4/9 → 5/9 | note:c3 ]",
"[ 2/3 → 7/9 | note:c3 ]",
"[ 1/1 → 10/9 | note:c3 ]",
"[ 11/9 → 4/3 | note:c3 ]",
"[ 13/9 → 14/9 | note:c3 ]",
"[ 5/3 → 16/9 | note:c3 ]",
"[ 2/1 → 19/9 | note:c3 ]",
"[ 20/9 → 7/3 | note:c3 ]",
"[ 22/9 → 23/9 | note:c3 ]",
"[ 8/3 → 25/9 | note:c3 ]",
"[ 3/1 → 28/9 | note:c3 ]",
"[ 29/9 → 10/3 | note:c3 ]",
"[ 31/9 → 32/9 | note:c3 ]",
"[ 11/3 → 34/9 | note:c3 ]",
]
`;
@ -146,26 +146,26 @@ exports[`runs examples > example "_euclidRot" example index 7 1`] = `
exports[`runs examples > example "_euclidRot" example index 8 1`] = `
[
"[ 0/1 → 1/6 | note:c3 ]",
"[ 1/6 → 1/3 | note:c3 ]",
"[ 1/3 → 1/2 | note:c3 ]",
"[ 1/2 → 2/3 | note:c3 ]",
"[ 2/3 → 5/6 | note:c3 ]",
"[ 5/6 → 1/1 | note:c3 ]",
"[ 1/1 → 7/6 | note:c3 ]",
"[ 7/6 → 4/3 | note:c3 ]",
"[ 4/3 → 3/2 | note:c3 ]",
"[ 3/2 → 5/3 | note:c3 ]",
"[ 5/3 → 11/6 | note:c3 ]",
"[ 11/6 → 2/1 | note:c3 ]",
"[ 2/1 → 13/6 | note:c3 ]",
"[ 13/6 → 7/3 | note:c3 ]",
"[ 7/3 → 5/2 | note:c3 ]",
"[ 5/2 → 8/3 | note:c3 ]",
"[ 8/3 → 17/6 | note:c3 ]",
"[ 17/6 → 3/1 | note:c3 ]",
"[ 3/1 → 19/6 | note:c3 ]",
"[ 19/6 → 10/3 | note:c3 ]",
"[ 10/3 → 7/2 | note:c3 ]",
"[ 7/2 → 11/3 | note:c3 ]",
"[ 11/3 → 23/6 | note:c3 ]",
"[ 23/6 → 4/1 | note:c3 ]",
]
`;
@ -196,26 +196,26 @@ exports[`runs examples > example "_euclidRot" example index 9 1`] = `
exports[`runs examples > example "_euclidRot" example index 10 1`] = `
[
"[ 1/8 → 1/4 | note:c3 ]",
"[ 0/1 → 1/8 | note:c3 ]",
"[ 1/4 → 3/8 | note:c3 ]",
"[ 1/2 → 5/8 | note:c3 ]",
"[ 3/8 → 1/2 | note:c3 ]",
"[ 5/8 → 3/4 | note:c3 ]",
"[ 7/8 → 1/1 | note:c3 ]",
"[ 9/8 → 5/4 | note:c3 ]",
"[ 3/4 → 7/8 | note:c3 ]",
"[ 1/1 → 9/8 | note:c3 ]",
"[ 5/4 → 11/8 | note:c3 ]",
"[ 3/2 → 13/8 | note:c3 ]",
"[ 11/8 → 3/2 | note:c3 ]",
"[ 13/8 → 7/4 | note:c3 ]",
"[ 15/8 → 2/1 | note:c3 ]",
"[ 17/8 → 9/4 | note:c3 ]",
"[ 7/4 → 15/8 | note:c3 ]",
"[ 2/1 → 17/8 | note:c3 ]",
"[ 9/4 → 19/8 | note:c3 ]",
"[ 5/2 → 21/8 | note:c3 ]",
"[ 19/8 → 5/2 | note:c3 ]",
"[ 21/8 → 11/4 | note:c3 ]",
"[ 23/8 → 3/1 | note:c3 ]",
"[ 25/8 → 13/4 | note:c3 ]",
"[ 11/4 → 23/8 | note:c3 ]",
"[ 3/1 → 25/8 | note:c3 ]",
"[ 13/4 → 27/8 | note:c3 ]",
"[ 7/2 → 29/8 | note:c3 ]",
"[ 27/8 → 7/2 | note:c3 ]",
"[ 29/8 → 15/4 | note:c3 ]",
"[ 31/8 → 4/1 | note:c3 ]",
"[ 15/4 → 31/8 | note:c3 ]",
]
`;
@ -246,26 +246,26 @@ exports[`runs examples > example "_euclidRot" example index 11 1`] = `
exports[`runs examples > example "_euclidRot" example index 12 1`] = `
[
"[ 1/11 → 2/11 | note:c3 ]",
"[ 3/11 → 4/11 | note:c3 ]",
"[ 5/11 → 6/11 | note:c3 ]",
"[ 7/11 → 8/11 | note:c3 ]",
"[ 9/11 → 10/11 | note:c3 ]",
"[ 12/11 → 13/11 | note:c3 ]",
"[ 14/11 → 15/11 | note:c3 ]",
"[ 16/11 → 17/11 | note:c3 ]",
"[ 18/11 → 19/11 | note:c3 ]",
"[ 20/11 → 21/11 | note:c3 ]",
"[ 23/11 → 24/11 | note:c3 ]",
"[ 25/11 → 26/11 | note:c3 ]",
"[ 27/11 → 28/11 | note:c3 ]",
"[ 29/11 → 30/11 | note:c3 ]",
"[ 31/11 → 32/11 | note:c3 ]",
"[ 34/11 → 35/11 | note:c3 ]",
"[ 36/11 → 37/11 | note:c3 ]",
"[ 38/11 → 39/11 | note:c3 ]",
"[ 40/11 → 41/11 | note:c3 ]",
"[ 42/11 → 43/11 | note:c3 ]",
"[ 0/1 → 1/11 | note:c3 ]",
"[ 2/11 → 3/11 | note:c3 ]",
"[ 4/11 → 5/11 | note:c3 ]",
"[ 6/11 → 7/11 | note:c3 ]",
"[ 8/11 → 9/11 | note:c3 ]",
"[ 1/1 → 12/11 | note:c3 ]",
"[ 13/11 → 14/11 | note:c3 ]",
"[ 15/11 → 16/11 | note:c3 ]",
"[ 17/11 → 18/11 | note:c3 ]",
"[ 19/11 → 20/11 | note:c3 ]",
"[ 2/1 → 23/11 | note:c3 ]",
"[ 24/11 → 25/11 | note:c3 ]",
"[ 26/11 → 27/11 | note:c3 ]",
"[ 28/11 → 29/11 | note:c3 ]",
"[ 30/11 → 31/11 | note:c3 ]",
"[ 3/1 → 34/11 | note:c3 ]",
"[ 35/11 → 36/11 | note:c3 ]",
"[ 37/11 → 38/11 | note:c3 ]",
"[ 39/11 → 40/11 | note:c3 ]",
"[ 41/11 → 42/11 | note:c3 ]",
]
`;
@ -296,92 +296,92 @@ exports[`runs examples > example "_euclidRot" example index 13 1`] = `
exports[`runs examples > example "_euclidRot" example index 14 1`] = `
[
"[ 1/16 → 1/8 | note:c3 ]",
"[ 1/4 → 5/16 | note:c3 ]",
"[ 7/16 → 1/2 | note:c3 ]",
"[ 5/8 → 11/16 | note:c3 ]",
"[ 13/16 → 7/8 | note:c3 ]",
"[ 17/16 → 9/8 | note:c3 ]",
"[ 5/4 → 21/16 | note:c3 ]",
"[ 23/16 → 3/2 | note:c3 ]",
"[ 13/8 → 27/16 | note:c3 ]",
"[ 29/16 → 15/8 | note:c3 ]",
"[ 33/16 → 17/8 | note:c3 ]",
"[ 9/4 → 37/16 | note:c3 ]",
"[ 39/16 → 5/2 | note:c3 ]",
"[ 21/8 → 43/16 | note:c3 ]",
"[ 45/16 → 23/8 | note:c3 ]",
"[ 49/16 → 25/8 | note:c3 ]",
"[ 13/4 → 53/16 | note:c3 ]",
"[ 55/16 → 7/2 | note:c3 ]",
"[ 29/8 → 59/16 | note:c3 ]",
"[ 61/16 → 31/8 | note:c3 ]",
"[ 0/1 → 1/16 | note:c3 ]",
"[ 3/16 → 1/4 | note:c3 ]",
"[ 3/8 → 7/16 | note:c3 ]",
"[ 9/16 → 5/8 | note:c3 ]",
"[ 3/4 → 13/16 | note:c3 ]",
"[ 1/1 → 17/16 | note:c3 ]",
"[ 19/16 → 5/4 | note:c3 ]",
"[ 11/8 → 23/16 | note:c3 ]",
"[ 25/16 → 13/8 | note:c3 ]",
"[ 7/4 → 29/16 | note:c3 ]",
"[ 2/1 → 33/16 | note:c3 ]",
"[ 35/16 → 9/4 | note:c3 ]",
"[ 19/8 → 39/16 | note:c3 ]",
"[ 41/16 → 21/8 | note:c3 ]",
"[ 11/4 → 45/16 | note:c3 ]",
"[ 3/1 → 49/16 | note:c3 ]",
"[ 51/16 → 13/4 | note:c3 ]",
"[ 27/8 → 55/16 | note:c3 ]",
"[ 57/16 → 29/8 | note:c3 ]",
"[ 15/4 → 61/16 | note:c3 ]",
]
`;
exports[`runs examples > example "_euclidRot" example index 15 1`] = `
[
"[ 0/1 → 1/8 | note:c3 ]",
"[ 1/8 → 1/4 | note:c3 ]",
"[ 1/4 → 3/8 | note:c3 ]",
"[ 3/8 → 1/2 | note:c3 ]",
"[ 1/2 → 5/8 | note:c3 ]",
"[ 5/8 → 3/4 | note:c3 ]",
"[ 3/4 → 7/8 | note:c3 ]",
"[ 7/8 → 1/1 | note:c3 ]",
"[ 1/1 → 9/8 | note:c3 ]",
"[ 9/8 → 5/4 | note:c3 ]",
"[ 5/4 → 11/8 | note:c3 ]",
"[ 11/8 → 3/2 | note:c3 ]",
"[ 3/2 → 13/8 | note:c3 ]",
"[ 13/8 → 7/4 | note:c3 ]",
"[ 7/4 → 15/8 | note:c3 ]",
"[ 15/8 → 2/1 | note:c3 ]",
"[ 2/1 → 17/8 | note:c3 ]",
"[ 17/8 → 9/4 | note:c3 ]",
"[ 9/4 → 19/8 | note:c3 ]",
"[ 19/8 → 5/2 | note:c3 ]",
"[ 5/2 → 21/8 | note:c3 ]",
"[ 21/8 → 11/4 | note:c3 ]",
"[ 11/4 → 23/8 | note:c3 ]",
"[ 23/8 → 3/1 | note:c3 ]",
"[ 3/1 → 25/8 | note:c3 ]",
"[ 25/8 → 13/4 | note:c3 ]",
"[ 13/4 → 27/8 | note:c3 ]",
"[ 27/8 → 7/2 | note:c3 ]",
"[ 7/2 → 29/8 | note:c3 ]",
"[ 29/8 → 15/4 | note:c3 ]",
"[ 15/4 → 31/8 | note:c3 ]",
"[ 31/8 → 4/1 | note:c3 ]",
]
`;
exports[`runs examples > example "_euclidRot" example index 16 1`] = `
[
"[ 1/12 → 1/6 | note:c3 ]",
"[ 0/1 → 1/12 | note:c3 ]",
"[ 1/6 → 1/4 | note:c3 ]",
"[ 1/3 → 5/12 | note:c3 ]",
"[ 1/2 → 7/12 | note:c3 ]",
"[ 1/4 → 1/3 | note:c3 ]",
"[ 5/12 → 1/2 | note:c3 ]",
"[ 7/12 → 2/3 | note:c3 ]",
"[ 3/4 → 5/6 | note:c3 ]",
"[ 11/12 → 1/1 | note:c3 ]",
"[ 13/12 → 7/6 | note:c3 ]",
"[ 2/3 → 3/4 | note:c3 ]",
"[ 5/6 → 11/12 | note:c3 ]",
"[ 1/1 → 13/12 | note:c3 ]",
"[ 7/6 → 5/4 | note:c3 ]",
"[ 4/3 → 17/12 | note:c3 ]",
"[ 3/2 → 19/12 | note:c3 ]",
"[ 5/4 → 4/3 | note:c3 ]",
"[ 17/12 → 3/2 | note:c3 ]",
"[ 19/12 → 5/3 | note:c3 ]",
"[ 7/4 → 11/6 | note:c3 ]",
"[ 23/12 → 2/1 | note:c3 ]",
"[ 25/12 → 13/6 | note:c3 ]",
"[ 5/3 → 7/4 | note:c3 ]",
"[ 11/6 → 23/12 | note:c3 ]",
"[ 2/1 → 25/12 | note:c3 ]",
"[ 13/6 → 9/4 | note:c3 ]",
"[ 7/3 → 29/12 | note:c3 ]",
"[ 5/2 → 31/12 | note:c3 ]",
"[ 9/4 → 7/3 | note:c3 ]",
"[ 29/12 → 5/2 | note:c3 ]",
"[ 31/12 → 8/3 | note:c3 ]",
"[ 11/4 → 17/6 | note:c3 ]",
"[ 35/12 → 3/1 | note:c3 ]",
"[ 37/12 → 19/6 | note:c3 ]",
"[ 8/3 → 11/4 | note:c3 ]",
"[ 17/6 → 35/12 | note:c3 ]",
"[ 3/1 → 37/12 | note:c3 ]",
"[ 19/6 → 13/4 | note:c3 ]",
"[ 10/3 → 41/12 | note:c3 ]",
"[ 7/2 → 43/12 | note:c3 ]",
"[ 13/4 → 10/3 | note:c3 ]",
"[ 41/12 → 7/2 | note:c3 ]",
"[ 43/12 → 11/3 | note:c3 ]",
"[ 15/4 → 23/6 | note:c3 ]",
"[ 47/12 → 4/1 | note:c3 ]",
"[ 11/3 → 15/4 | note:c3 ]",
"[ 23/6 → 47/12 | note:c3 ]",
]
`;
@ -420,42 +420,42 @@ exports[`runs examples > example "_euclidRot" example index 17 1`] = `
exports[`runs examples > example "_euclidRot" example index 18 1`] = `
[
"[ 1/16 → 1/8 | note:c3 ]",
"[ 0/1 → 1/16 | note:c3 ]",
"[ 1/8 → 3/16 | note:c3 ]",
"[ 1/4 → 5/16 | note:c3 ]",
"[ 3/8 → 7/16 | note:c3 ]",
"[ 1/2 → 9/16 | note:c3 ]",
"[ 3/16 → 1/4 | note:c3 ]",
"[ 5/16 → 3/8 | note:c3 ]",
"[ 7/16 → 1/2 | note:c3 ]",
"[ 9/16 → 5/8 | note:c3 ]",
"[ 11/16 → 3/4 | note:c3 ]",
"[ 13/16 → 7/8 | note:c3 ]",
"[ 15/16 → 1/1 | note:c3 ]",
"[ 17/16 → 9/8 | note:c3 ]",
"[ 5/8 → 11/16 | note:c3 ]",
"[ 3/4 → 13/16 | note:c3 ]",
"[ 7/8 → 15/16 | note:c3 ]",
"[ 1/1 → 17/16 | note:c3 ]",
"[ 9/8 → 19/16 | note:c3 ]",
"[ 5/4 → 21/16 | note:c3 ]",
"[ 11/8 → 23/16 | note:c3 ]",
"[ 3/2 → 25/16 | note:c3 ]",
"[ 19/16 → 5/4 | note:c3 ]",
"[ 21/16 → 11/8 | note:c3 ]",
"[ 23/16 → 3/2 | note:c3 ]",
"[ 25/16 → 13/8 | note:c3 ]",
"[ 27/16 → 7/4 | note:c3 ]",
"[ 29/16 → 15/8 | note:c3 ]",
"[ 31/16 → 2/1 | note:c3 ]",
"[ 33/16 → 17/8 | note:c3 ]",
"[ 13/8 → 27/16 | note:c3 ]",
"[ 7/4 → 29/16 | note:c3 ]",
"[ 15/8 → 31/16 | note:c3 ]",
"[ 2/1 → 33/16 | note:c3 ]",
"[ 17/8 → 35/16 | note:c3 ]",
"[ 9/4 → 37/16 | note:c3 ]",
"[ 19/8 → 39/16 | note:c3 ]",
"[ 5/2 → 41/16 | note:c3 ]",
"[ 35/16 → 9/4 | note:c3 ]",
"[ 37/16 → 19/8 | note:c3 ]",
"[ 39/16 → 5/2 | note:c3 ]",
"[ 41/16 → 21/8 | note:c3 ]",
"[ 43/16 → 11/4 | note:c3 ]",
"[ 45/16 → 23/8 | note:c3 ]",
"[ 47/16 → 3/1 | note:c3 ]",
"[ 49/16 → 25/8 | note:c3 ]",
"[ 21/8 → 43/16 | note:c3 ]",
"[ 11/4 → 45/16 | note:c3 ]",
"[ 23/8 → 47/16 | note:c3 ]",
"[ 3/1 → 49/16 | note:c3 ]",
"[ 25/8 → 51/16 | note:c3 ]",
"[ 13/4 → 53/16 | note:c3 ]",
"[ 27/8 → 55/16 | note:c3 ]",
"[ 7/2 → 57/16 | note:c3 ]",
"[ 51/16 → 13/4 | note:c3 ]",
"[ 53/16 → 27/8 | note:c3 ]",
"[ 55/16 → 7/2 | note:c3 ]",
"[ 57/16 → 29/8 | note:c3 ]",
"[ 59/16 → 15/4 | note:c3 ]",
"[ 61/16 → 31/8 | note:c3 ]",
"[ 63/16 → 4/1 | note:c3 ]",
"[ 29/8 → 59/16 | note:c3 ]",
"[ 15/4 → 61/16 | note:c3 ]",
"[ 31/8 → 63/16 | note:c3 ]",
]
`;
@ -510,58 +510,58 @@ exports[`runs examples > example "_euclidRot" example index 19 1`] = `
exports[`runs examples > example "_euclidRot" example index 20 1`] = `
[
"[ 0/1 → 1/24 | note:c3 ]",
"[ 1/12 → 1/8 | note:c3 ]",
"[ 1/6 → 5/24 | note:c3 ]",
"[ 1/4 → 7/24 | note:c3 ]",
"[ 1/24 → 1/12 | note:c3 ]",
"[ 1/8 → 1/6 | note:c3 ]",
"[ 5/24 → 1/4 | note:c3 ]",
"[ 7/24 → 1/3 | note:c3 ]",
"[ 3/8 → 5/12 | note:c3 ]",
"[ 11/24 → 1/2 | note:c3 ]",
"[ 13/24 → 7/12 | note:c3 ]",
"[ 5/8 → 2/3 | note:c3 ]",
"[ 17/24 → 3/4 | note:c3 ]",
"[ 1/3 → 3/8 | note:c3 ]",
"[ 5/12 → 11/24 | note:c3 ]",
"[ 1/2 → 13/24 | note:c3 ]",
"[ 7/12 → 5/8 | note:c3 ]",
"[ 2/3 → 17/24 | note:c3 ]",
"[ 3/4 → 19/24 | note:c3 ]",
"[ 5/6 → 7/8 | note:c3 ]",
"[ 11/12 → 23/24 | note:c3 ]",
"[ 1/1 → 25/24 | note:c3 ]",
"[ 13/12 → 9/8 | note:c3 ]",
"[ 7/6 → 29/24 | note:c3 ]",
"[ 5/4 → 31/24 | note:c3 ]",
"[ 19/24 → 5/6 | note:c3 ]",
"[ 7/8 → 11/12 | note:c3 ]",
"[ 23/24 → 1/1 | note:c3 ]",
"[ 25/24 → 13/12 | note:c3 ]",
"[ 9/8 → 7/6 | note:c3 ]",
"[ 29/24 → 5/4 | note:c3 ]",
"[ 31/24 → 4/3 | note:c3 ]",
"[ 11/8 → 17/12 | note:c3 ]",
"[ 35/24 → 3/2 | note:c3 ]",
"[ 37/24 → 19/12 | note:c3 ]",
"[ 13/8 → 5/3 | note:c3 ]",
"[ 41/24 → 7/4 | note:c3 ]",
"[ 4/3 → 11/8 | note:c3 ]",
"[ 17/12 → 35/24 | note:c3 ]",
"[ 3/2 → 37/24 | note:c3 ]",
"[ 19/12 → 13/8 | note:c3 ]",
"[ 5/3 → 41/24 | note:c3 ]",
"[ 7/4 → 43/24 | note:c3 ]",
"[ 11/6 → 15/8 | note:c3 ]",
"[ 23/12 → 47/24 | note:c3 ]",
"[ 2/1 → 49/24 | note:c3 ]",
"[ 25/12 → 17/8 | note:c3 ]",
"[ 13/6 → 53/24 | note:c3 ]",
"[ 9/4 → 55/24 | note:c3 ]",
"[ 43/24 → 11/6 | note:c3 ]",
"[ 15/8 → 23/12 | note:c3 ]",
"[ 47/24 → 2/1 | note:c3 ]",
"[ 49/24 → 25/12 | note:c3 ]",
"[ 17/8 → 13/6 | note:c3 ]",
"[ 53/24 → 9/4 | note:c3 ]",
"[ 55/24 → 7/3 | note:c3 ]",
"[ 19/8 → 29/12 | note:c3 ]",
"[ 59/24 → 5/2 | note:c3 ]",
"[ 61/24 → 31/12 | note:c3 ]",
"[ 21/8 → 8/3 | note:c3 ]",
"[ 65/24 → 11/4 | note:c3 ]",
"[ 7/3 → 19/8 | note:c3 ]",
"[ 29/12 → 59/24 | note:c3 ]",
"[ 5/2 → 61/24 | note:c3 ]",
"[ 31/12 → 21/8 | note:c3 ]",
"[ 8/3 → 65/24 | note:c3 ]",
"[ 11/4 → 67/24 | note:c3 ]",
"[ 17/6 → 23/8 | note:c3 ]",
"[ 35/12 → 71/24 | note:c3 ]",
"[ 3/1 → 73/24 | note:c3 ]",
"[ 37/12 → 25/8 | note:c3 ]",
"[ 19/6 → 77/24 | note:c3 ]",
"[ 13/4 → 79/24 | note:c3 ]",
"[ 67/24 → 17/6 | note:c3 ]",
"[ 23/8 → 35/12 | note:c3 ]",
"[ 71/24 → 3/1 | note:c3 ]",
"[ 73/2437/12 | note:c3 ]",
"[ 25/8 → 19/6 | note:c3 ]",
"[ 77/24 → 13/4 | note:c3 ]",
"[ 79/24 → 10/3 | note:c3 ]",
"[ 27/8 → 41/12 | note:c3 ]",
"[ 83/24 → 7/2 | note:c3 ]",
"[ 85/24 → 43/12 | note:c3 ]",
"[ 29/8 → 11/3 | note:c3 ]",
"[ 89/24 → 15/4 | note:c3 ]",
"[ 10/3 → 27/8 | note:c3 ]",
"[ 41/12 → 83/24 | note:c3 ]",
"[ 7/2 → 85/24 | note:c3 ]",
"[ 43/12 → 29/8 | note:c3 ]",
"[ 11/3 → 89/24 | note:c3 ]",
"[ 15/4 → 91/24 | note:c3 ]",
"[ 23/6 → 31/8 | note:c3 ]",
"[ 47/12 → 95/24 | note:c3 ]",
"[ 91/24 → 23/6 | note:c3 ]",
"[ 31/8 → 47/12 | note:c3 ]",
"[ 95/24 → 4/1 | note:c3 ]",
]
`;
@ -1581,18 +1581,18 @@ exports[`runs examples > example "euclidLegato" example index 0 1`] = `
exports[`runs examples > example "euclidRot" example index 0 1`] = `
[
"[ 1/4 → 5/16 | note:c3 ]",
"[ 9/16 → 5/8 | note:c3 ]",
"[ 15/16 → 1/1 | note:c3 ]",
"[ 5/4 → 21/16 | note:c3 ]",
"[ 25/16 → 13/8 | note:c3 ]",
"[ 31/16 → 2/1 | note:c3 ]",
"[ 9/4 → 37/16 | note:c3 ]",
"[ 41/16 → 21/8 | note:c3 ]",
"[ 47/16 → 3/1 | note:c3 ]",
"[ 13/4 → 53/16 | note:c3 ]",
"[ 57/16 → 29/8 | note:c3 ]",
"[ 63/16 → 4/1 | note:c3 ]",
"[ 3/16 → 1/4 | note:c3 ]",
"[ 1/2 → 9/16 | note:c3 ]",
"[ 7/8 → 15/16 | note:c3 ]",
"[ 19/16 → 5/4 | note:c3 ]",
"[ 3/2 → 25/16 | note:c3 ]",
"[ 15/8 → 31/16 | note:c3 ]",
"[ 35/16 → 9/4 | note:c3 ]",
"[ 5/2 → 41/16 | note:c3 ]",
"[ 23/8 → 47/16 | note:c3 ]",
"[ 51/16 → 13/4 | note:c3 ]",
"[ 7/2 → 57/16 | note:c3 ]",
"[ 31/8 → 63/16 | note:c3 ]",
]
`;

View File

@ -167,9 +167,9 @@ export const sampleDrums = `samples({
}, 'https://loophole-letters.vercel.app/samples/tidal/')
stack(
"<bd!3 bd(3,4,2)>".color('#F5A623'),
"<bd!3 bd(3,4,3)>".color('#F5A623'),
"hh*4".color('#673AB7'),
"~ <sn!3 sn(3,4,1)>".color('#4CAF50')
"~ <sn!3 sn(3,4,2)>".color('#4CAF50')
).s()
.pianoroll({fold:1})
`;
@ -328,7 +328,7 @@ stack(
"<0 1 2 3>(3,8,2)"
.scale(scale)
.off(1/4, scaleTranspose("2,4")),
"<0 4>(5,8)".scale(scale).transpose(-12)
"<0 4>(5,8,-1)".scale(scale).transpose(-12)
)
.velocity(".6 .7".fast(4))
.legato("2")
@ -349,7 +349,7 @@ stack(
.add("<0 1 2 1>").hush(),
n("<0 1 2 3>(3,8,2)")
.off(1/4, add("2,4")),
n("<0 4>(5,8)").sub(7)
n("<0 4>(5,8,-1)").sub(7)
)
.scale(scale)
.gain(".6 .7".fast(4))
@ -363,7 +363,7 @@ stack(
export const echoPiano = `// licensed with CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
// by Felix Roos
"<0 2 [4 6](3,4,1) 3*2>"
"<0 2 [4 6](3,4,2) 3*2>"
.scale('D minor')
.color('salmon')
.off(1/4, x=>x.scaleTranspose(2).color('green'))
@ -425,7 +425,7 @@ stack(
.scale(cat('D minor pentatonic')).note()
.s('bell').gain(.6).delay(.2).delaytime(1/3).delayfeedback(.8),
// bass
"<D2 A2 G2 F2>".euclidLegatoRot(6,8,1).note().s('bass').clip(1).gain(.8)
"<D2 A2 G2 F2>".euclidLegatoRot(6,8,4).note().s('bass').clip(1).gain(.8)
)
.slow(6)
.pianoroll({minMidi:20,maxMidi:120,background:'transparent'})
@ -464,7 +464,7 @@ samples({
}, 'https://freesound.org/data/previews/')
stack(
"-7 0 -7 7".struct("x(5,8,2)").fast(2).sub(7)
"-7 0 -7 7".struct("x(5,8,1)").fast(2).sub(7)
.scale(scales)
.n()
.s("sawtooth,square")
@ -520,7 +520,7 @@ export const meltingsubmarine = `// licensed with CC BY-NC-SA 4.0 https://creati
// by Felix Roos
await samples('github:tidalcycles/Dirt-Samples/master/')
stack(
s("bd:5,[~ <sd:1!3 sd:1(3,4,2)>],hh27(3,4)") // drums
s("bd:5,[~ <sd:1!3 sd:1(3,4,3)>],hh27(3,4,1)") // drums
.speed(perlin.range(.7,.9)) // random sample speed variation
//.hush()
,"<a1 b1*2 a1(3,8) e2>" // bassline
@ -542,7 +542,7 @@ stack(
.cutoff(500) // fixed cutoff
.attack(1) // slowly fade in
//.hush()
,"a4 c5 <e6 a6>".struct("x(5,8)")
,"a4 c5 <e6 a6>".struct("x(5,8,-1)")
.superimpose(x=>x.add(.04)) // add second, slightly detuned voice
.add(perlin.range(0,.5)) // random pitch variation
.n() // wrap in "n"
@ -673,7 +673,7 @@ stack(
.orbit(2).delay(.2).delaytime(".33 | .6 | .166 | .25")
.room(1).gain(.5).mask("<0 1>/8"),
// bell
note(rand.range(0,12).struct("x(5,8)").scale('g2 minor pentatonic')).s('bell').begin(.05)
note(rand.range(0,12).struct("x(5,8,-1)").scale('g2 minor pentatonic')).s('bell').begin(.05)
.delay(.2).degradeBy(.4).gain(.4)
.mask("<1 0>/8")
).slow(5)`;
@ -737,9 +737,9 @@ stack(
.rarely(x=>x.speed(".5").delay(.5))
.end(perlin.range(0.02,.05).slow(8))
.bank('RolandTR909').room(.5)
.gain("0.4,0.4(5,8)"),
.gain("0.4,0.4(5,8,-1)"),
note("<0 2 5 3>".scale('G1 minor')).struct("x(5,8)")
note("<0 2 5 3>".scale('G1 minor')).struct("x(5,8,-1)")
.s('sawtooth').decay(.1).sustain(0),
note("<G4 A4 Bb4 A4>,Bb3,D3").struct("~ x*2").s('square').clip(1)
@ -783,7 +783,7 @@ stack(
s("breath").room(1).shape(.6).chop(16).rev().mask("<x ~@7>")
,
n("0 1").s("east").delay(.5).degradeBy(.8).speed(rand.range(.5,1.5))
).reset("<x@7 x(5,8)>")`;
).reset("<x@7 x(5,8,-1)>")`;
export const juxUndTollerei = `// licensed with CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
// by Felix Roos
@ -824,7 +824,7 @@ instr CoolSynth
out(asig, asig)
endin\`
"<0 2 [4 6](3,4,1) 3*2>"
"<0 2 [4 6](3,4,2) 3*2>"
.off(1/4, add(2))
.off(1/2, add(6))
.scale('D minor')