From dd03ad6c140f2ee45bc845054262f7ca85f290f0 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sun, 24 Apr 2022 00:34:04 +0200 Subject: [PATCH] support stack in drawLine --- packages/core/drawLine.mjs | 52 +++++++++++++++++++--------- packages/core/test/drawLine.test.mjs | 24 ++++++++++++- 2 files changed, 59 insertions(+), 17 deletions(-) diff --git a/packages/core/drawLine.mjs b/packages/core/drawLine.mjs index 05c857de..cf380fd2 100644 --- a/packages/core/drawLine.mjs +++ b/packages/core/drawLine.mjs @@ -1,26 +1,46 @@ import { gcd } from './fraction.mjs'; -// TODO: make it work for stacked patterns + support silence - function drawLine(pat, chars = 60) { - let s = ''; let c = 0; - while (s.length < chars) { + let lines = ['']; + const slots = []; + while (lines[0].length < chars) { const haps = pat.queryArc(c, c + 1); - const durations = haps.map((hap) => hap.duration); + const durations = haps.filter((hap) => hap.hasOnset()).map((hap) => hap.duration); const totalSlots = gcd(...durations).inverse(); - s += '|'; - haps.forEach((hap) => { - const duration = hap.whole.end.sub(hap.whole.begin); - const slots = totalSlots.mul(duration); - s += Array(slots.valueOf()) - .fill() - .map((_, i) => (!i ? hap.value : '-')) - .join(''); - }); - ++c; + slots.push(totalSlots); + const minDuration = durations.reduce((a, b) => a.min(b), durations[0]); + lines = lines.map((line) => line + '|'); + + for (let i = 0; i < totalSlots; i++) { + const step = c * totalSlots + i; + const [begin, end] = [minDuration.mul(step), minDuration.mul(step + 1)]; + const matches = haps.filter((hap) => hap.whole.begin.lte(begin) && hap.whole.end.gte(end)); + const missingLines = matches.length - lines.length; + if (missingLines > 0) { + console.log(c, 'missingLines', missingLines); + const emptyCycles = + '|' + + new Array(c) + .fill() + .map((_, l) => Array(slots[l]).fill('.').join('')) + .join('|') + + Array(i).fill('.').join(''); + lines = lines.concat(Array(missingLines).fill(emptyCycles)); + } + lines = lines.map((line, i) => { + const hap = matches[i]; + if (hap) { + const isOnset = hap.whole.begin.eq(begin); + const char = isOnset ? '' + hap.value : '-'; + return line + char; + } + return line + '.'; + }); + } + c++; } - return s; + return lines.join('\n'); } export default drawLine; diff --git a/packages/core/test/drawLine.test.mjs b/packages/core/test/drawLine.test.mjs index d697c793..f7b4fca3 100644 --- a/packages/core/test/drawLine.test.mjs +++ b/packages/core/test/drawLine.test.mjs @@ -1,4 +1,4 @@ -import { fastcat } from '../pattern.mjs'; +import { fastcat, stack } from '../pattern.mjs'; import { strict as assert } from 'assert'; import drawLine from '../drawLine.mjs'; @@ -7,5 +7,27 @@ describe('drawLine', () => { assert.equal(drawLine(fastcat(0, [1, 2]), 10), '|0-12|0-12'); assert.equal(drawLine(fastcat(0, [1, 2, 3]), 10), '|0--123|0--123'); assert.equal(drawLine(fastcat(0, 1, [2, 3]), 10), '|0-1-23|0-1-23'); + assert.equal( + drawLine(fastcat(0, stack(1, 2)), 10), + `|01|01|01|01 +|.2|.2|.2|.2`, + ); + assert.equal( + drawLine(fastcat(0, 1, stack(2, 3)), 10), + `|012|012|012 +|..3|..3|..3`, + ); + assert.equal( + drawLine(fastcat(0, stack(1, 2, 3)), 10), + `|01|01|01|01 +|.2|.2|.2|.2 +|.3|.3|.3|.3`, + ); + assert.equal( + drawLine(fastcat(0, 1, stack(2, 3, 4)), 10), + `|012|012|012 +|..3|..3|..3 +|..4|..4|..4`, + ); }); });