mirror of
https://github.com/eliasstepanik/strudel.git
synced 2026-01-11 21:58:37 +00:00
log + drawLine
This commit is contained in:
parent
e747c0b060
commit
9e2e5ce581
24
packages/core/drawLine.mjs
Normal file
24
packages/core/drawLine.mjs
Normal 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;
|
||||
@ -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.“
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -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
|
||||
|
||||
9
packages/core/test/fraction.test.mjs
Normal file
9
packages/core/test/fraction.test.mjs
Normal 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');
|
||||
});
|
||||
});
|
||||
@ -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) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user