Skip to content

Commit

Permalink
Merge branch 'tidalcycles:main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
edcrub authored Aug 25, 2024
2 parents 0fe62cd + 812ed6b commit 1642e81
Show file tree
Hide file tree
Showing 2 changed files with 145 additions and 1 deletion.
46 changes: 45 additions & 1 deletion packages/core/signal.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ const timeToRand = (x) => Math.abs(intSeedToRand(timeToIntSeed(x)));
const timeToRandsPrime = (seed, n) => {
const result = [];
// eslint-disable-next-line
for (let i = 0; i < n; ++n) {
for (let i = 0; i < n; ++i) {
result.push(intSeedToRand(seed));
seed = xorwise(seed);
}
Expand All @@ -159,6 +159,50 @@ const timeToRands = (t, n) => timeToRandsPrime(timeToIntSeed(t), n);
*/
export const run = (n) => saw.range(0, n).floor().segment(n);

export const randrun = (n) => {
return signal((t) => {
// Without adding 0.5, the first cycle is always 0,1,2,3,...
const rands = timeToRands(t.floor().add(0.5), n);
const nums = rands
.map((n, i) => [n, i])
.sort((a, b) => a[0] > b[0] - a[0] < b[0])
.map((x) => x[1]);
const i = t.cyclePos().mul(n).floor() % n;
return nums[i];
})._segment(n);
};

const _rearrangeWith = (ipat, n, pat) => {
const pats = [...Array(n).keys()].map((i) => pat.zoom(Fraction(i).div(n), Fraction(i + 1).div(n)));
return ipat.fmap((i) => pats[i].repeatCycles(n)._fast(n)).innerJoin();
};

/**
* @name shuffle
* Slices a pattern into the given number of parts, then plays those parts in random order.
* Each part will be played exactly once per cycle.
* @example
* note("c d e f").sound("piano").shuffle(4)
* @example
* note("c d e f".shuffle(4), "g").sound("piano")
*/
export const shuffle = register('shuffle', (n, pat) => {
return _rearrangeWith(randrun(n), n, pat);
});

/**
* @name scramble
* Slices a pattern into the given number of parts, then plays those parts at random. Similar to `shuffle`,
* but parts might be played more than once, or not at all, per cycle.
* @example
* note("c d e f").sound("piano").scramble(4)
* @example
* note("c d e f".scramble(4), "g").sound("piano")
*/
export const scramble = register('scramble', (n, pat) => {
return _rearrangeWith(_irand(n)._segment(n), n, pat);
});

/**
* A continuous pattern of random numbers, between 0 and 1.
*
Expand Down
100 changes: 100 additions & 0 deletions test/__snapshots__/examples.test.mjs.snap
Original file line number Diff line number Diff line change
Expand Up @@ -6637,6 +6637,56 @@ exports[`runs examples > example "scope" example index 0 1`] = `
]
`;

exports[`runs examples > example "scramble
Slices a pattern into the given number of parts, then plays those parts at random. Similar to \`shuffle\`,
but parts might be played more than once, or not at all, per cycle." example index 0 1`] = `
[
"[ 0/1 → 1/4 | note:e s:piano ]",
"[ 1/4 → 1/2 | note:d s:piano ]",
"[ 1/2 → 3/4 | note:c s:piano ]",
"[ 3/4 → 1/1 | note:d s:piano ]",
"[ 1/1 → 5/4 | note:e s:piano ]",
"[ 5/4 → 3/2 | note:c s:piano ]",
"[ 3/2 → 7/4 | note:d s:piano ]",
"[ 7/4 → 2/1 | note:e s:piano ]",
"[ 2/1 → 9/4 | note:f s:piano ]",
"[ 9/4 → 5/2 | note:f s:piano ]",
"[ 5/2 → 11/4 | note:c s:piano ]",
"[ 11/4 → 3/1 | note:c s:piano ]",
"[ 3/1 → 13/4 | note:d s:piano ]",
"[ 13/4 → 7/2 | note:d s:piano ]",
"[ 7/2 → 15/4 | note:f s:piano ]",
"[ 15/4 → 4/1 | note:e s:piano ]",
]
`;

exports[`runs examples > example "scramble
Slices a pattern into the given number of parts, then plays those parts at random. Similar to \`shuffle\`,
but parts might be played more than once, or not at all, per cycle." example index 1 1`] = `
[
"[ 0/1 → 1/8 | note:e s:piano ]",
"[ 1/8 → 1/4 | note:d s:piano ]",
"[ 1/4 → 3/8 | note:c s:piano ]",
"[ 3/8 → 1/2 | note:d s:piano ]",
"[ 1/2 → 1/1 | note:g s:piano ]",
"[ 1/1 → 9/8 | note:e s:piano ]",
"[ 9/8 → 5/4 | note:c s:piano ]",
"[ 5/4 → 11/8 | note:d s:piano ]",
"[ 11/8 → 3/2 | note:e s:piano ]",
"[ 3/2 → 2/1 | note:g s:piano ]",
"[ 2/1 → 17/8 | note:f s:piano ]",
"[ 17/8 → 9/4 | note:f s:piano ]",
"[ 9/4 → 19/8 | note:c s:piano ]",
"[ 19/8 → 5/2 | note:c s:piano ]",
"[ 5/2 → 3/1 | note:g s:piano ]",
"[ 3/1 → 25/8 | note:d s:piano ]",
"[ 25/8 → 13/4 | note:d s:piano ]",
"[ 13/4 → 27/8 | note:f s:piano ]",
"[ 27/8 → 7/2 | note:e s:piano ]",
"[ 7/2 → 4/1 | note:g s:piano ]",
]
`;

exports[`runs examples > example "segment" example index 0 1`] = `
[
"[ 0/1 → 1/24 | note:40.25 ]",
Expand Down Expand Up @@ -6853,6 +6903,56 @@ exports[`runs examples > example "shape" example index 0 1`] = `
]
`;

exports[`runs examples > example "shuffle
Slices a pattern into the given number of parts, then plays those parts in random order.
Each part will be played exactly once per cycle." example index 0 1`] = `
[
"[ 0/1 → 1/4 | note:c s:piano ]",
"[ 1/4 → 1/2 | note:d s:piano ]",
"[ 1/2 → 3/4 | note:e s:piano ]",
"[ 3/4 → 1/1 | note:f s:piano ]",
"[ 1/1 → 5/4 | note:c s:piano ]",
"[ 5/4 → 3/2 | note:d s:piano ]",
"[ 3/2 → 7/4 | note:e s:piano ]",
"[ 7/4 → 2/1 | note:f s:piano ]",
"[ 2/1 → 9/4 | note:c s:piano ]",
"[ 9/4 → 5/2 | note:d s:piano ]",
"[ 5/2 → 11/4 | note:e s:piano ]",
"[ 11/4 → 3/1 | note:f s:piano ]",
"[ 3/1 → 13/4 | note:c s:piano ]",
"[ 13/4 → 7/2 | note:d s:piano ]",
"[ 7/2 → 15/4 | note:e s:piano ]",
"[ 15/4 → 4/1 | note:f s:piano ]",
]
`;

exports[`runs examples > example "shuffle
Slices a pattern into the given number of parts, then plays those parts in random order.
Each part will be played exactly once per cycle." example index 1 1`] = `
[
"[ 0/1 → 1/8 | note:c s:piano ]",
"[ 1/8 → 1/4 | note:d s:piano ]",
"[ 1/4 → 3/8 | note:e s:piano ]",
"[ 3/8 → 1/2 | note:f s:piano ]",
"[ 1/2 → 1/1 | note:g s:piano ]",
"[ 1/1 → 9/8 | note:c s:piano ]",
"[ 9/8 → 5/4 | note:d s:piano ]",
"[ 5/4 → 11/8 | note:e s:piano ]",
"[ 11/8 → 3/2 | note:f s:piano ]",
"[ 3/2 → 2/1 | note:g s:piano ]",
"[ 2/1 → 17/8 | note:c s:piano ]",
"[ 17/8 → 9/4 | note:d s:piano ]",
"[ 9/4 → 19/8 | note:e s:piano ]",
"[ 19/8 → 5/2 | note:f s:piano ]",
"[ 5/2 → 3/1 | note:g s:piano ]",
"[ 3/1 → 25/8 | note:c s:piano ]",
"[ 25/8 → 13/4 | note:d s:piano ]",
"[ 13/4 → 27/8 | note:e s:piano ]",
"[ 27/8 → 7/2 | note:f s:piano ]",
"[ 7/2 → 4/1 | note:g s:piano ]",
]
`;

exports[`runs examples > example "silence" example index 0 1`] = `[]`;

exports[`runs examples > example "sine" example index 0 1`] = `
Expand Down

0 comments on commit 1642e81

Please sign in to comment.