mirror of
https://github.com/eliasstepanik/strudel-docker.git
synced 2026-01-24 03:58:53 +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);
|
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).
|
* 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
|
* @name chunk
|
||||||
|
* @synonyms slowChunk, slowchunk
|
||||||
* @memberof Pattern
|
* @memberof Pattern
|
||||||
* @returns Pattern
|
* @returns Pattern
|
||||||
* @example
|
* @example
|
||||||
* "0 1 2 3".chunk(4, x=>x.add(7)).scale('A minor').note()
|
* "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);
|
const binary = Array(n - 1).fill(false);
|
||||||
binary.unshift(true);
|
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);
|
return pat.when(binary_pat, func);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const chunk = register('chunk', function (n, func, pat) {
|
const { chunk, slowchunk, slowChunk } = register(['chunk', 'slowchunk', 'slowChunk'], function (n, func, pat) {
|
||||||
return _chunk(n, func, pat, false);
|
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);
|
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
|
// TODO - redefine elsewhere in terms of mask
|
||||||
export const bypass = register('bypass', function (on, pat) {
|
export const bypass = register('bypass', function (on, pat) {
|
||||||
on = Boolean(parseInt(on));
|
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`] = `
|
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 ]",
|
"[ 0/1 → 1/4 | note:A4 ]",
|
||||||
"[ 1/4 → 1/2 | note:B3 ]",
|
"[ 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`] = `
|
exports[`runs examples > example "clip" example index 0 1`] = `
|
||||||
[
|
[
|
||||||
"[ 0/1 → 1/4 | note:c s:piano clip:0.5 ]",
|
"[ 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`] = `
|
exports[`runs examples > example "fastGap" example index 0 1`] = `
|
||||||
[
|
[
|
||||||
"[ 0/1 → 1/4 | s:bd ]",
|
"[ 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`] = `
|
exports[`runs examples > example "reset" example index 0 1`] = `
|
||||||
[
|
[
|
||||||
"[ 0/1 → 1/4 | s:hh ]",
|
"[ 0/1 → 1/4 | s:hh ]",
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user