log + drawLine

This commit is contained in:
Felix Roos 2022-04-23 23:28:43 +02:00
parent e747c0b060
commit 9e2e5ce581
6 changed files with 70 additions and 3 deletions

View File

@ -0,0 +1,24 @@
import { gcd } from './fraction.mjs';
function drawLine(pat) {
let s = '';
let c = 0;
while (s.length < 60) {
const haps = pat.queryArc(c, c + 1);
const durations = haps.map((hap) => hap.duration);
const totalSlots = gcd(...durations).inverse();
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('');
});
s += '|';
++c;
}
return s;
}
export default drawLine;

View File

@ -72,6 +72,12 @@ const fraction = (n) => {
return Fraction(n);
};
export const gcd = (...fractions) => {
return fractions.reduce((gcd, fraction) => gcd.gcd(fraction), fraction(1));
};
fraction._original = Fraction;
export default fraction;
// "If you concern performance, cache Fraction.js objects and pass arrays/objects.“

View File

@ -24,7 +24,7 @@ export class Hap {
}
get duration() {
return this.whole.end.sub(this.whole.begin).valueOf();
return this.whole.end.sub(this.whole.begin);
}
wholeOrPart() {

View File

@ -4,6 +4,7 @@ import Hap from './hap.mjs';
import State from './state.mjs';
import { isNote, toMidi, compose, removeUndefineds, flatten, id, listRange, curry, mod } from './util.mjs';
import drawLine from './drawLine.mjs';
export class Pattern {
// the following functions will get patternFactories as nested functions:
@ -563,6 +564,17 @@ export class Pattern {
return this._withContext((context) => ({ ...context, color }));
}
log() {
return this._withEvent((e) => {
return e.setContext({ ...e.context, logs: (e.context?.logs || []).concat([e.show()]) });
});
}
drawLine() {
console.log(drawLine(this));
return this;
}
_segment(rate) {
return this.struct(pure(true)._fast(rate));
}
@ -803,7 +815,20 @@ Pattern.prototype.patternified = [
'velocity',
];
// methods that create patterns, which are added to patternified Pattern methods
Pattern.prototype.factories = { pure, stack, slowcat, fastcat, cat, timeCat, sequence, seq, polymeter, pm, polyrhythm, pr };
Pattern.prototype.factories = {
pure,
stack,
slowcat,
fastcat,
cat,
timeCat,
sequence,
seq,
polymeter,
pm,
polyrhythm,
pr,
};
// the magic happens in Pattern constructor. Keeping this in prototype enables adding methods from the outside (e.g. see tonal.ts)
// Elemental patterns

View File

@ -0,0 +1,9 @@
import Fraction, { gcd } from '../fraction.mjs';
import { strict as assert } from 'assert';
describe('gcd', () => {
it('should work', () => {
const F = Fraction._original;
assert.equal(gcd(F(1 / 6), F(1 / 4)).toFraction(), '1/12');
});
});

View File

@ -29,7 +29,7 @@ function useRepl({ tune, defaultSynth, autolink = true, onEvent, onDraw }) {
return onDraw;
}
}, [activeCode, onDraw]);
// cycle hook to control scheduling
const cycle = useCycle({
onDraw,
@ -37,6 +37,9 @@ function useRepl({ tune, defaultSynth, autolink = true, onEvent, onDraw }) {
(time, event, currentTime) => {
try {
onEvent?.(event);
if (event.context.logs?.length) {
event.context.logs.forEach(pushLog);
}
const { onTrigger, velocity } = event.context;
if (!onTrigger) {
if (defaultSynth) {