diff --git a/packages/core/pattern.mjs b/packages/core/pattern.mjs index 60c10c2e..ec7bc19c 100644 --- a/packages/core/pattern.mjs +++ b/packages/core/pattern.mjs @@ -739,13 +739,20 @@ export class Pattern { const end = cycle.add(span.end.sub(cycle).mul(factor).min(1)); return new TimeSpan(begin, end); }; - const ef = function (span) { - const cycle = span.begin.sam(); - const begin = cycle.add(span.begin.sub(cycle).div(factor).min(1)); - const end = cycle.add(span.end.sub(cycle).div(factor).min(1)); - return new TimeSpan(begin, end); + const ef = function (hap) { + const begin = hap.part.begin; + const end = hap.part.end; + const cycle = begin.sam(); + const beginPos = begin.sub(cycle).div(factor).min(1); + const endPos = end.sub(cycle).div(factor).min(1); + const newPart = new TimeSpan(cycle.add(beginPos), cycle.add(endPos)) + const newWhole = !hap.whole ? undefined : new TimeSpan( + newPart.begin.sub(begin.sub(hap.whole.begin).div(factor)), + newPart.end.add(hap.whole.end.sub(end).div(factor)) + ); + return new Hap(newWhole, newPart, hap.value, hap.context); }; - return this.withQuerySpan(qf).withHapSpan(ef)._splitQueries(); + return this.withQuerySpan(qf)._withHap(ef)._splitQueries(); } // Compress each cycle into the given timespan, leaving a gap diff --git a/packages/core/test/pattern.test.mjs b/packages/core/test/pattern.test.mjs index 850538e3..7720cb76 100644 --- a/packages/core/test/pattern.test.mjs +++ b/packages/core/test/pattern.test.mjs @@ -372,6 +372,11 @@ describe('Pattern', () => { sequence(['a', 'b', 'c'], silence, ['a', 'b', 'c'], silence).firstCycle(), ); }); + it('copes with breaking up events across cycles', () => { + expect(pure('a').slow(2)._fastGap(2)._setContext({}).query(st(0, 2))).toStrictEqual( + [hap(ts(0, 1), ts(0, 0.5), 'a'), hap(ts(0.5, 1.5), ts(1, 1.5), 'a')] + ); + }); }); describe('_compressSpan()', () => { it('Can squash cycles of a pattern into a given timespan', () => {