Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

weave and weaveWith #465

Merged
merged 3 commits into from
Feb 18, 2023
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
8 changes: 1 addition & 7 deletions packages/core/euclid.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,9 @@ This program is free software: you can redistribute it and/or modify it under th
*/

import { Pattern, timeCat, register, silence } from './pattern.mjs';
import { rotate, flatten } from './util.mjs';
import { rotate, flatten, splitAt, zipWith } 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;
Expand Down
31 changes: 30 additions & 1 deletion packages/core/pattern.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -977,7 +977,7 @@ export class Pattern {
}

//////////////////////////////////////////////////////////////////////
// functions relating to chords/patterns of lists
// functions relating to chords/patterns of lists/lists of patterns

// returns Array<Hap[]> where each list of haps satisfies eq
function groupHapsBy(eq, haps) {
Expand Down Expand Up @@ -1026,6 +1026,35 @@ addToPrototype('arp', function (pat) {
return this.arpWith((haps) => pat.fmap((i) => haps[i % haps.length]));
});

/**
* Takes a time duration followed by one or more patterns, and shifts the given patterns in time, so they are
* distributed equally over the given time duration. They are then combined with the pattern 'weave' is called on, after it has been stretched out (i.e. slowed down by) the time duration.
* @name weave
* @memberof Pattern
* @example pan(saw).weave(4, s("bd(3,8)"), s("~ sd"))
* @example n("0 1 2 3 4 5 6 7").weave(8, s("bd(3,8)"), s("~ sd"))
*/

addToPrototype('weave', function (t, ...pats) {
return this.weaveWith(t, ...pats.map((x) => set.out(x)));
});

/**
* Like 'weave', but accepts functions rather than patterns, which are applied to the pattern.
* @name weaveWith
* @memberof Pattern
*/

addToPrototype('weaveWith', function (t, ...funcs) {
const pat = this;
const l = funcs.length;
t = Fraction(t);
if (l == 0) {
return silence;
}
return stack(...funcs.map((func, i) => pat.inside(t, func).early(Fraction(i).div(l))))._slow(t);
});

//////////////////////////////////////////////////////////////////////
// compose matrix functions

Expand Down
5 changes: 5 additions & 0 deletions packages/core/test/pattern.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -981,4 +981,9 @@ describe('Pattern', () => {
// sameFirst(s('bd').apply(set.squeeze.n(3).fast(2)), s('bd').set.squeeze.n(3).fast(2));
});
});
describe('weave', () => {
it('Can distribute patterns along a pattern', () => {
sameFirst(n(0, 1).weave(2, s('bd', silence), s(silence, 'sd')), sequence(s('bd').n(0), s('sd').n(1)));
});
});
});
6 changes: 6 additions & 0 deletions packages/core/util.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -206,3 +206,9 @@ export function parseFractional(numOrString) {
}

export const fractionalArgs = (fn) => mapArgs(fn, parseFractional);

export const splitAt = function (index, value) {
return [value.slice(0, index), value.slice(index)];
};

export const zipWith = (f, xs, ys) => xs.map((n, i) => f(n, ys[i]));
42 changes: 42 additions & 0 deletions test/__snapshots__/examples.test.mjs.snap
Original file line number Diff line number Diff line change
Expand Up @@ -4231,6 +4231,48 @@ exports[`runs examples > example "vowel" example index 0 1`] = `
]
`;

exports[`runs examples > example "weave" example index 0 1`] = `
[
"[ 0/1 → 1/8 | pan:0.015625 s:bd ]",
"[ 3/8 → 1/2 | pan:0.109375 s:bd ]",
"[ 3/4 → 7/8 | pan:0.203125 s:bd ]",
"[ 1/1 → 9/8 | pan:0.265625 s:bd ]",
"[ 11/8 → 3/2 | pan:0.359375 s:bd ]",
"[ 7/4 → 15/8 | pan:0.453125 s:bd ]",
"[ 2/1 → 17/8 | pan:0.515625 s:bd ]",
"[ 19/8 → 5/2 | pan:0.609375 s:bd ]",
"[ 11/4 → 23/8 | pan:0.703125 s:bd ]",
"[ 3/1 → 25/8 | pan:0.765625 s:bd ]",
"[ 27/8 → 7/2 | pan:0.859375 s:bd ]",
"[ 15/4 → 31/8 | pan:0.953125 s:bd ]",
"[ 1/2 → 1/1 | pan:0.6875 s:sd ]",
"[ 3/2 → 2/1 | pan:0.9375 s:sd ]",
"[ 5/2 → 3/1 | pan:0.1875 s:sd ]",
"[ 7/2 → 4/1 | pan:0.4375 s:sd ]",
]
`;

exports[`runs examples > example "weave" example index 1 1`] = `
[
"[ 0/1 → 1/8 | n:0 s:bd ]",
"[ 3/8 → 1/2 | n:0 s:bd ]",
"[ 3/4 → 7/8 | n:0 s:bd ]",
"[ 1/1 → 9/8 | n:1 s:bd ]",
"[ 11/8 → 3/2 | n:1 s:bd ]",
"[ 7/4 → 15/8 | n:1 s:bd ]",
"[ 2/1 → 17/8 | n:2 s:bd ]",
"[ 19/8 → 5/2 | n:2 s:bd ]",
"[ 11/4 → 23/8 | n:2 s:bd ]",
"[ 3/1 → 25/8 | n:3 s:bd ]",
"[ 27/8 → 7/2 | n:3 s:bd ]",
"[ 15/4 → 31/8 | n:3 s:bd ]",
"[ 1/2 → 1/1 | n:4 s:sd ]",
"[ 3/2 → 2/1 | n:5 s:sd ]",
"[ 5/2 → 3/1 | n:6 s:sd ]",
"[ 7/2 → 4/1 | n:7 s:sd ]",
]
`;

exports[`runs examples > example "webdirt" example index 0 1`] = `
[
"[ 0/1 → 1/8 | s:bd n:0 ]",
Expand Down