Skip to content
This repository was archived by the owner on Jun 19, 2025. It is now read-only.
Open
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
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
"@eslint/eslintrc": "^3.2.0",
"@eslint/js": "^9.19.0",
"@tauri-apps/cli": "^2.2.7",
"@vitest/coverage-v8": "3.0.4",
"@vitest/ui": "^3.0.4",
"acorn": "^8.14.0",
"dependency-tree": "^11.0.1",
Expand Down
10 changes: 10 additions & 0 deletions packages/core/pattern.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -1244,6 +1244,16 @@ export function reify(thing) {
return pure(thing);
}

/** Takes a list of patterns, and returns a pattern of lists.
*/
export function sequenceP(pats) {
let result = pure([]);
for (const pat of pats) {
result = result.bind((list) => pat.fmap((v) => list.concat([v])));
}
return result;
}

/** The given items are played at the same time at the same length.
*
* @return {Pattern}
Expand Down
33 changes: 24 additions & 9 deletions packages/core/signal.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ This program is free software: you can redistribute it and/or modify it under th
*/

import { Hap } from './hap.mjs';
import { Pattern, fastcat, pure, register, reify, silence, stack } from './pattern.mjs';
import { Pattern, fastcat, pure, register, reify, silence, stack, sequenceP } from './pattern.mjs';
import Fraction from './fraction.mjs';

import { id, keyAlias, getCurrentKeyboardState } from './util.mjs';
Expand Down Expand Up @@ -203,7 +203,8 @@ const timeToIntSeed = (x) => xorwise(Math.trunc(_frac(x / 300) * 536870912));

const intSeedToRand = (x) => (x % 536870912) / 536870912;

const timeToRand = (x) => Math.abs(intSeedToRand(timeToIntSeed(x)));
// Set first random value to be 0.5, otherwise it would be 0. https://github.com/tidalcycles/strudel/issues/1293
const timeToRand = (x) => (x === 0 ? 0.5 : Math.abs(intSeedToRand(timeToIntSeed(x))));

const timeToRandsPrime = (seed, n) => {
const result = [];
Expand Down Expand Up @@ -433,19 +434,30 @@ export const chooseCycles = (...xs) => chooseInWith(rand.segment(1), xs);
export const randcat = chooseCycles;

const _wchooseWith = function (pat, ...pairs) {
// A list of patterns of values
const values = pairs.map((pair) => reify(pair[0]));

// A list of weight patterns
const weights = [];
let accum = 0;

let total = pure(0);
for (const pair of pairs) {
accum += pair[1];
weights.push(accum);
// 'add' accepts either values or patterns of values here, so no need
// to explicitly reify
total = total.add(pair[1]);
// accumulate our list of weight patterns
weights.push(total);
}
const total = accum;
// a pattern of lists of weights
const weightspat = sequenceP(weights);

// Takes a number from 0-1, returns a pattern of patterns of values
const match = function (r) {
const find = r * total;
return values[weights.findIndex((x) => x > find, weights)];
const findpat = total.mul(r);
return weightspat.fmap((weights) => (find) => values[weights.findIndex((x) => x > find, weights)]).appLeft(findpat);
};
return pat.fmap(match);
// This returns a pattern of patterns.. The innerJoin is in wchooseCycles
return pat.bind(match);
};

const wchooseWith = (...args) => _wchooseWith(...args).outerJoin();
Expand All @@ -467,6 +479,9 @@ export const wchoose = (...pairs) => wchooseWith(rand, ...pairs);
* wchooseCycles(["bd",10], ["hh",1], ["sd",1]).s().fast(8)
* @example
* wchooseCycles(["bd bd bd",5], ["hh hh hh",3], ["sd sd sd",1]).fast(4).s()
* @example
* // The probability can itself be a pattern
* wchooseCycles(["bd(3,8)","<5 0>"], ["hh hh hh",3]).fast(4).s()
*/
export const wchooseCycles = (...pairs) => _wchooseWith(rand.segment(1), ...pairs).innerJoin();

Expand Down
95 changes: 95 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

77 changes: 65 additions & 12 deletions test/__snapshots__/examples.test.mjs.snap
Original file line number Diff line number Diff line change
Expand Up @@ -5724,18 +5724,18 @@ exports[`runs examples > example "penv" example index 0 1`] = `

exports[`runs examples > example "perlin" example index 0 1`] = `
[
"[ 0/1 → 1/8 | s:hh cutoff:500 ]",
"[ 0/1 → 1/4 | s:bd cutoff:500 ]",
"[ 1/8 → 1/4 | s:hh cutoff:562.5486401770559 ]",
"[ 1/4 → 3/8 | s:hh cutoff:903.3554895067937 ]",
"[ 1/4 → 1/2 | s:bd cutoff:903.3554895067937 ]",
"[ 3/8 → 1/2 | s:hh cutoff:1572.364329119182 ]",
"[ 1/2 → 5/8 | s:hh cutoff:2448.2831191271544 ]",
"[ 1/2 → 3/4 | s:bd cutoff:2448.2831191271544 ]",
"[ 5/8 → 3/4 | s:hh cutoff:3324.2019091351267 ]",
"[ 3/4 → 7/8 | s:hh cutoff:3993.210748747515 ]",
"[ 3/4 → 1/1 | s:bd cutoff:3993.210748747515 ]",
"[ 7/8 → 1/1 | s:hh cutoff:4334.017598077253 ]",
"[ 0/1 → 1/8 | s:hh cutoff:4250 ]",
"[ 0/1 → 1/4 | s:bd cutoff:4250 ]",
"[ 1/8 → 1/4 | s:hh cutoff:4252.352717325493 ]",
"[ 1/4 → 3/8 | s:hh cutoff:4265.171895756794 ]",
"[ 1/4 → 1/2 | s:bd cutoff:4265.171895756794 ]",
"[ 3/8 → 1/2 | s:hh cutoff:4290.3361308769945 ]",
"[ 1/2 → 5/8 | s:hh cutoff:4323.283119127154 ]",
"[ 1/2 → 3/4 | s:bd cutoff:4323.283119127154 ]",
"[ 5/8 → 3/4 | s:hh cutoff:4356.230107377314 ]",
"[ 3/4 → 7/8 | s:hh cutoff:4381.394342497515 ]",
"[ 3/4 → 1/1 | s:bd cutoff:4381.394342497515 ]",
"[ 7/8 → 1/1 | s:hh cutoff:4394.213520928815 ]",
"[ 1/1 → 9/8 | s:hh cutoff:4396.566238254309 ]",
"[ 1/1 → 5/4 | s:bd cutoff:4396.566238254309 ]",
"[ 9/8 → 5/4 | s:hh cutoff:4449.536839055554 ]",
Expand Down Expand Up @@ -9687,6 +9687,59 @@ exports[`runs examples > example "wchooseCycles" example index 1 1`] = `
]
`;

exports[`runs examples > example "wchooseCycles" example index 2 1`] = `
[
"[ 0/1 → 1/32 | s:bd ]",
"[ 3/32 → 1/8 | s:bd ]",
"[ 3/16 → 7/32 | s:bd ]",
"[ 1/4 → 1/3 | s:hh ]",
"[ 1/3 → 5/12 | s:hh ]",
"[ 5/12 → 1/2 | s:hh ]",
"[ 1/2 → 7/12 | s:hh ]",
"[ 7/12 → 2/3 | s:hh ]",
"[ 2/3 → 3/4 | s:hh ]",
"[ 3/4 → 5/6 | s:hh ]",
"[ 5/6 → 11/12 | s:hh ]",
"[ 11/12 → 1/1 | s:hh ]",
"[ 1/1 → 33/32 | s:bd ]",
"[ 35/32 → 9/8 | s:bd ]",
"[ 19/16 → 39/32 | s:bd ]",
"[ 5/4 → 4/3 | s:hh ]",
"[ 4/3 → 17/12 | s:hh ]",
"[ 17/12 → 3/2 | s:hh ]",
"[ 3/2 → 49/32 | s:bd ]",
"[ 51/32 → 13/8 | s:bd ]",
"[ 27/16 → 55/32 | s:bd ]",
"[ 7/4 → 11/6 | s:hh ]",
"[ 11/6 → 23/12 | s:hh ]",
"[ 23/12 → 2/1 | s:hh ]",
"[ 2/1 → 25/12 | s:hh ]",
"[ 25/12 → 13/6 | s:hh ]",
"[ 13/6 → 9/4 | s:hh ]",
"[ 9/4 → 7/3 | s:hh ]",
"[ 7/3 → 29/12 | s:hh ]",
"[ 29/12 → 5/2 | s:hh ]",
"[ 5/2 → 81/32 | s:bd ]",
"[ 83/32 → 21/8 | s:bd ]",
"[ 43/16 → 87/32 | s:bd ]",
"[ 11/4 → 17/6 | s:hh ]",
"[ 17/6 → 35/12 | s:hh ]",
"[ 35/12 → 3/1 | s:hh ]",
"[ 3/1 → 97/32 | s:bd ]",
"[ 99/32 → 25/8 | s:bd ]",
"[ 51/16 → 103/32 | s:bd ]",
"[ 13/4 → 10/3 | s:hh ]",
"[ 10/3 → 41/12 | s:hh ]",
"[ 41/12 → 7/2 | s:hh ]",
"[ 7/2 → 43/12 | s:hh ]",
"[ 43/12 → 11/3 | s:hh ]",
"[ 11/3 → 15/4 | s:hh ]",
"[ 15/4 → 23/6 | s:hh ]",
"[ 23/6 → 47/12 | s:hh ]",
"[ 47/12 → 4/1 | s:hh ]",
]
`;

exports[`runs examples > example "when" example index 0 1`] = `
[
"[ 0/1 → 1/3 | note:c3 ]",
Expand Down
Loading