diff --git a/packages/core/strudel.mjs b/packages/core/strudel.mjs index d8e6d525..ec1eaa2e 100644 --- a/packages/core/strudel.mjs +++ b/packages/core/strudel.mjs @@ -583,7 +583,7 @@ class Pattern { return this.innerBind(id); } - squeezeJoin() { + _squeezeJoin() { const pat_of_pats = this; function query(state) { const haps = pat_of_pats.query(state); @@ -607,15 +607,19 @@ class Pattern { const context = inner.combineContext(outer); return new Hap(whole, part, inner.value, context); } - return innerHaps.map(innerHap => munge(outerHap, innerHap)) + return innerHaps.map((innerHap) => munge(outerHap, innerHap)); } const result = flatten(haps.map(flatHap)); // remove undefineds - return result.filter(x => x); + return result.filter((x) => x); } return new Pattern(query); } + _squeezeBind(func) { + return this.fmap(func)._squeezeJoin(); + } + _apply(func) { return func(this); } @@ -678,7 +682,16 @@ class Pattern { } _ply(factor) { - return this.fmap(x => pure(x)._fast(factor)).squeezeJoin() + return this.fmap((x) => pure(x)._fast(factor))._squeezeJoin(); + } + + _chop(n) { + const slices = Array.from({length: n}, (x, i) => i); + const slice_objects = slices.map(i => ({begin: i/n, end: (i+1)/n})); + const func = function(o) { + return(sequence(slice_objects.map(slice_o => Object.assign({}, o, slice_o)))) + } + return(this._squeezeBind(func)); } // cpm = cycles per minute @@ -878,6 +891,7 @@ Pattern.prototype.patternified = [ 'fast', 'slow', 'ply', + 'chop', 'cpm', 'early', 'late', @@ -885,7 +899,7 @@ Pattern.prototype.patternified = [ 'legato', 'velocity', 'segment', - 'color' + 'color', ]; // methods that create patterns, which are added to patternified Pattern methods Pattern.prototype.factories = { pure, stack, slowcat, fastcat, cat, timeCat, sequence, polymeter, pm, polyrhythm, pr }; diff --git a/packages/core/test/pattern.test.mjs b/packages/core/test/pattern.test.mjs index 88d18f32..9ebd7813 100644 --- a/packages/core/test/pattern.test.mjs +++ b/packages/core/test/pattern.test.mjs @@ -491,10 +491,10 @@ describe('Pattern', function() { ) }) }) - describe("squeezeJoin", () => { + describe("_squeezeJoin", () => { it("Can squeeze", () => { assert.deepStrictEqual( - sequence("a", ["a","a"]).fmap(a => fastcat("b", "c")).squeezeJoin().firstCycle(), + sequence("a", ["a","a"]).fmap(a => fastcat("b", "c"))._squeezeJoin().firstCycle(), sequence(["b", "c"],[["b", "c"],["b", "c"]]).firstCycle() ) }) @@ -507,4 +507,27 @@ describe('Pattern', function() { ) }) }) + describe("chop", () => { + it("Can _chop(2)", () => { + assert.deepStrictEqual( + sequence({sound: "a"}, {sound: "b"})._chop(2).firstCycle(), + sequence({sound: "a", begin: 0, end: 0.5}, + {sound: "a", begin: 0.5, end: 1}, + {sound: "b", begin: 0, end: 0.5}, + {sound: "b", begin: 0.5, end: 1} + ).firstCycle() + ); + }); + it("Can chop(2,3)", () => { + assert.deepStrictEqual( + pure({sound: "a"}).fast(2).chop(2,3)._sortEventsByPart().firstCycle(), + sequence([{sound: "a", begin: 0, end: 0.5}, + {sound: "a", begin: 0.5, end: 1}], + [{sound: "a", begin: 0, end: 1/3}, + {sound: "a", begin: 1/3, end: 2/3}, + {sound: "a", begin: 2/3, end: 1} + ])._sortEventsByPart().firstCycle() + ) + }) + }) })