mirror of
https://github.com/eliasstepanik/strudel.git
synced 2026-01-10 21:28:31 +00:00
Fix chunk, add fastChunk and repeatCycles (#712)
* Match behaviour of chunk with tidal, add fastChunk for old strudel behaviour. Also adds repeatCycles. fixes #689 * documentation
This commit is contained in:
parent
16bb920011
commit
9ceab0f294
@ -2100,23 +2100,43 @@ export const { iterBack, iterback } = register(['iterBack', 'iterback'], functio
|
||||
return _iter(times, pat, true);
|
||||
});
|
||||
|
||||
/**
|
||||
* Repeats each cycle the given number of times.
|
||||
* @name repeatCycles
|
||||
* @memberof Pattern
|
||||
* @returns Pattern
|
||||
* @example
|
||||
* note(irand(12).add(34)).segment(4).repeatCycles(2).s("gm_acoustic_guitar_nylon")
|
||||
*/
|
||||
const _repeatCycles = function (n, pat) {
|
||||
return slowcat(...Array(n).fill(pat));
|
||||
};
|
||||
|
||||
const { repeatCycles } = register('repeatCycles', _repeatCycles);
|
||||
|
||||
/**
|
||||
* Divides a pattern into a given number of parts, then cycles through those parts in turn, applying the given function to each part in turn (one part per cycle).
|
||||
* @name chunk
|
||||
* @synonyms slowChunk, slowchunk
|
||||
* @memberof Pattern
|
||||
* @returns Pattern
|
||||
* @example
|
||||
* "0 1 2 3".chunk(4, x=>x.add(7)).scale('A minor').note()
|
||||
*/
|
||||
const _chunk = function (n, func, pat, back = false) {
|
||||
const _chunk = function (n, func, pat, back = false, fast = false) {
|
||||
const binary = Array(n - 1).fill(false);
|
||||
binary.unshift(true);
|
||||
const binary_pat = _iter(n, sequence(...binary), back);
|
||||
// Invert the 'back' because we want to shift the pattern forwards,
|
||||
// and so time backwards
|
||||
const binary_pat = _iter(n, sequence(...binary), !back);
|
||||
if (!fast) {
|
||||
pat = pat.repeatCycles(n);
|
||||
}
|
||||
return pat.when(binary_pat, func);
|
||||
};
|
||||
|
||||
export const chunk = register('chunk', function (n, func, pat) {
|
||||
return _chunk(n, func, pat, false);
|
||||
const { chunk, slowchunk, slowChunk } = register(['chunk', 'slowchunk', 'slowChunk'], function (n, func, pat) {
|
||||
return _chunk(n, func, pat, false, false);
|
||||
});
|
||||
|
||||
/**
|
||||
@ -2132,6 +2152,21 @@ export const { chunkBack, chunkback } = register(['chunkBack', 'chunkback'], fun
|
||||
return _chunk(n, func, pat, true);
|
||||
});
|
||||
|
||||
/**
|
||||
* Like `chunk`, but the cycles of the source pattern aren't repeated
|
||||
* for each set of chunks.
|
||||
* @name fastChunk
|
||||
* @synonyms fastchunk
|
||||
* @memberof Pattern
|
||||
* @returns Pattern
|
||||
* @example
|
||||
* "<0 8> 1 2 3 4 5 6 7".fastChunk(4, x => x.color('red')).slow(4).scale("C2:major").note()
|
||||
.s("folkharp")
|
||||
*/
|
||||
const { fastchunk, fastChunk } = register(['fastchunk', 'fastChunk'], function (n, func, pat) {
|
||||
return _chunk(n, func, pat, false, true);
|
||||
});
|
||||
|
||||
// TODO - redefine elsewhere in terms of mask
|
||||
export const bypass = register('bypass', function (on, pat) {
|
||||
on = Boolean(parseInt(on));
|
||||
|
||||
@ -1003,4 +1003,23 @@ describe('Pattern', () => {
|
||||
);
|
||||
});
|
||||
});
|
||||
describe('chunk', () => {
|
||||
it('Processes each cycle of the source pattern multiple times, once for each chunk', () => {
|
||||
expect(sequence(0, 1, 2, 3).slow(2).chunk(2, add(10)).fast(4).firstCycleValues).toStrictEqual([
|
||||
10, 1, 0, 11, 12, 3, 2, 13,
|
||||
]);
|
||||
});
|
||||
});
|
||||
describe('fastChunk', () => {
|
||||
it('Unlike chunk, cycles of the source pattern proceed cycle-by-cycle', () => {
|
||||
expect(sequence(0, 1, 2, 3).slow(2).fastChunk(2, add(10)).fast(4).firstCycleValues).toStrictEqual([
|
||||
10, 1, 2, 13, 10, 1, 2, 13,
|
||||
]);
|
||||
});
|
||||
});
|
||||
describe('repeatCycles', () => {
|
||||
it('Repeats each cycle of the source pattern the given number of times', () => {
|
||||
expect(slowcat(0, 1).repeatCycles(2).fast(6).firstCycleValues).toStrictEqual([0, 0, 1, 1, 0, 0]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -1115,27 +1115,6 @@ exports[`runs examples > example "chop" example index 0 1`] = `
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "chunk" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/4 | note:A4 ]",
|
||||
"[ 1/4 → 1/2 | note:B3 ]",
|
||||
"[ 1/2 → 3/4 | note:C4 ]",
|
||||
"[ 3/4 → 1/1 | note:D4 ]",
|
||||
"[ 1/1 → 5/4 | note:A3 ]",
|
||||
"[ 5/4 → 3/2 | note:B3 ]",
|
||||
"[ 3/2 → 7/4 | note:C4 ]",
|
||||
"[ 7/4 → 2/1 | note:D5 ]",
|
||||
"[ 2/1 → 9/4 | note:A3 ]",
|
||||
"[ 9/4 → 5/2 | note:B3 ]",
|
||||
"[ 5/2 → 11/4 | note:C5 ]",
|
||||
"[ 11/4 → 3/1 | note:D4 ]",
|
||||
"[ 3/1 → 13/4 | note:A3 ]",
|
||||
"[ 13/4 → 7/2 | note:B4 ]",
|
||||
"[ 7/2 → 15/4 | note:C4 ]",
|
||||
"[ 15/4 → 4/1 | note:D4 ]",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "chunkBack" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/4 | note:A4 ]",
|
||||
"[ 1/4 → 1/2 | note:B3 ]",
|
||||
@ -1156,6 +1135,27 @@ exports[`runs examples > example "chunkBack" example index 0 1`] = `
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "chunkBack" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/4 | note:A4 ]",
|
||||
"[ 1/4 → 1/2 | note:B3 ]",
|
||||
"[ 1/2 → 3/4 | note:C4 ]",
|
||||
"[ 3/4 → 1/1 | note:D4 ]",
|
||||
"[ 1/1 → 5/4 | note:A3 ]",
|
||||
"[ 5/4 → 3/2 | note:B3 ]",
|
||||
"[ 3/2 → 7/4 | note:C4 ]",
|
||||
"[ 7/4 → 2/1 | note:D5 ]",
|
||||
"[ 2/1 → 9/4 | note:A3 ]",
|
||||
"[ 9/4 → 5/2 | note:B3 ]",
|
||||
"[ 5/2 → 11/4 | note:C5 ]",
|
||||
"[ 11/4 → 3/1 | note:D4 ]",
|
||||
"[ 3/1 → 13/4 | note:A3 ]",
|
||||
"[ 13/4 → 7/2 | note:B4 ]",
|
||||
"[ 7/2 → 15/4 | note:C4 ]",
|
||||
"[ 15/4 → 4/1 | note:D4 ]",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "clip" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/4 | note:c s:piano clip:0.5 ]",
|
||||
@ -1857,6 +1857,19 @@ exports[`runs examples > example "fast" example index 0 1`] = `
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "fastChunk" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/2 | note:C2 s:folkharp ]",
|
||||
"[ 1/2 → 1/1 | note:D2 s:folkharp ]",
|
||||
"[ 1/1 → 3/2 | note:E2 s:folkharp ]",
|
||||
"[ 3/2 → 2/1 | note:F2 s:folkharp ]",
|
||||
"[ 2/1 → 5/2 | note:G2 s:folkharp ]",
|
||||
"[ 5/2 → 3/1 | note:A2 s:folkharp ]",
|
||||
"[ 3/1 → 7/2 | note:B2 s:folkharp ]",
|
||||
"[ 7/2 → 4/1 | note:C3 s:folkharp ]",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "fastGap" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/4 | s:bd ]",
|
||||
@ -3646,6 +3659,27 @@ exports[`runs examples > example "release" example index 0 1`] = `
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "repeatCycles" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/4 | note:42 s:gm_acoustic_guitar_nylon ]",
|
||||
"[ 1/4 → 1/2 | note:38 s:gm_acoustic_guitar_nylon ]",
|
||||
"[ 1/2 → 3/4 | note:35 s:gm_acoustic_guitar_nylon ]",
|
||||
"[ 3/4 → 1/1 | note:38 s:gm_acoustic_guitar_nylon ]",
|
||||
"[ 1/1 → 5/4 | note:42 s:gm_acoustic_guitar_nylon ]",
|
||||
"[ 5/4 → 3/2 | note:38 s:gm_acoustic_guitar_nylon ]",
|
||||
"[ 3/2 → 7/4 | note:35 s:gm_acoustic_guitar_nylon ]",
|
||||
"[ 7/4 → 2/1 | note:38 s:gm_acoustic_guitar_nylon ]",
|
||||
"[ 2/1 → 9/4 | note:42 s:gm_acoustic_guitar_nylon ]",
|
||||
"[ 9/4 → 5/2 | note:36 s:gm_acoustic_guitar_nylon ]",
|
||||
"[ 5/2 → 11/4 | note:39 s:gm_acoustic_guitar_nylon ]",
|
||||
"[ 11/4 → 3/1 | note:41 s:gm_acoustic_guitar_nylon ]",
|
||||
"[ 3/1 → 13/4 | note:42 s:gm_acoustic_guitar_nylon ]",
|
||||
"[ 13/4 → 7/2 | note:36 s:gm_acoustic_guitar_nylon ]",
|
||||
"[ 7/2 → 15/4 | note:39 s:gm_acoustic_guitar_nylon ]",
|
||||
"[ 15/4 → 4/1 | note:41 s:gm_acoustic_guitar_nylon ]",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "reset" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/4 | s:hh ]",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user