Add calculateTactus() for turning off calculation of tactus in (#1081)

core functions.
Also while I'm here stop fast/slow from manipulating tactus.
This commit is contained in:
Alex McLean 2024-04-29 11:36:10 +01:00 committed by GitHub
parent 47b65846e9
commit 91bb0a1d36
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 44 additions and 22 deletions

View file

@ -27,6 +27,12 @@ import { logger } from './logger.mjs';
let stringParser; let stringParser;
let __tactus = true;
export const calculateTactus = function (x) {
__tactus = x ? true : false;
};
// parser is expected to turn a string into a pattern // parser is expected to turn a string into a pattern
// if set, the reify function will parse all strings with it // if set, the reify function will parse all strings with it
// intended to use with mini to automatically interpret all strings as mini notation // intended to use with mini to automatically interpret all strings as mini notation
@ -60,6 +66,9 @@ export class Pattern {
} }
withTactus(f) { withTactus(f) {
if (!__tactus) {
return this;
}
return new Pattern(this.query, this.tactus === undefined ? undefined : f(this.tactus)); return new Pattern(this.query, this.tactus === undefined ? undefined : f(this.tactus));
} }
@ -149,7 +158,9 @@ export class Pattern {
return span_a.intersection_e(span_b); return span_a.intersection_e(span_b);
}; };
const result = pat_func.appWhole(whole_func, pat_val); const result = pat_func.appWhole(whole_func, pat_val);
result.tactus = lcm(pat_val.tactus, pat_func.tactus); if (__tactus) {
result.tactus = lcm(pat_val.tactus, pat_func.tactus);
}
return result; return result;
} }
@ -1254,7 +1265,9 @@ export function stack(...pats) {
pats = pats.map((pat) => (Array.isArray(pat) ? sequence(...pat) : reify(pat))); pats = pats.map((pat) => (Array.isArray(pat) ? sequence(...pat) : reify(pat)));
const query = (state) => flatten(pats.map((pat) => pat.query(state))); const query = (state) => flatten(pats.map((pat) => pat.query(state)));
const result = new Pattern(query); const result = new Pattern(query);
result.tactus = lcm(...pats.map((pat) => pat.tactus)); if (__tactus) {
result.tactus = lcm(...pats.map((pat) => pat.tactus));
}
return result; return result;
} }
@ -1267,7 +1280,7 @@ function _stackWith(func, pats) {
return pats[0]; return pats[0];
} }
const [left, ...right] = pats.map((pat) => pat.tactus); const [left, ...right] = pats.map((pat) => pat.tactus);
const tactus = left.maximum(...right); const tactus = __tactus ? left.maximum(...right) : undefined;
return stack(...func(tactus, pats)); return stack(...func(tactus, pats));
} }
@ -1347,7 +1360,7 @@ export function slowcat(...pats) {
const offset = span.begin.floor().sub(span.begin.div(pats.length).floor()); const offset = span.begin.floor().sub(span.begin.div(pats.length).floor());
return pat.withHapTime((t) => t.add(offset)).query(state.setSpan(span.withTime((t) => t.sub(offset)))); return pat.withHapTime((t) => t.add(offset)).query(state.setSpan(span.withTime((t) => t.sub(offset))));
}; };
const tactus = lcm(...pats.map((x) => x.tactus)); const tactus = __tactus ? lcm(...pats.map((x) => x.tactus)) : undefined;
return new Pattern(query).splitQueries().setTactus(tactus); return new Pattern(query).splitQueries().setTactus(tactus);
} }
@ -1766,7 +1779,9 @@ export const { focusSpan, focusspan } = register(['focusSpan', 'focusspan'], fun
*/ */
export const ply = register('ply', function (factor, pat) { export const ply = register('ply', function (factor, pat) {
const result = pat.fmap((x) => pure(x)._fast(factor)).squeezeJoin(); const result = pat.fmap((x) => pure(x)._fast(factor)).squeezeJoin();
result.tactus = Fraction(factor).mulmaybe(pat.tactus); if (__tactus) {
result.tactus = Fraction(factor).mulmaybe(pat.tactus);
}
return result; return result;
}); });
@ -1781,16 +1796,19 @@ export const ply = register('ply', function (factor, pat) {
* @example * @example
* s("bd hh sd hh").fast(2) // s("[bd hh sd hh]*2") * s("bd hh sd hh").fast(2) // s("[bd hh sd hh]*2")
*/ */
export const { fast, density } = register(['fast', 'density'], function (factor, pat) { export const { fast, density } = register(
if (factor === 0) { ['fast', 'density'],
return silence; function (factor, pat) {
} if (factor === 0) {
factor = Fraction(factor); return silence;
const fastQuery = pat.withQueryTime((t) => t.mul(factor)); }
const result = fastQuery.withHapTime((t) => t.div(factor)); factor = Fraction(factor);
result.tactus = factor.mulmaybe(pat.tactus); const fastQuery = pat.withQueryTime((t) => t.mul(factor));
return result; return fastQuery.withHapTime((t) => t.div(factor)).setTactus(pat.tactus);
}); },
true,
true,
);
/** /**
* Both speeds up the pattern (like 'fast') and the sample playback (like 'speed'). * Both speeds up the pattern (like 'fast') and the sample playback (like 'speed').
@ -1958,7 +1976,7 @@ export const zoom = register('zoom', function (s, e, pat) {
return nothing; return nothing;
} }
const d = e.sub(s); const d = e.sub(s);
const tactus = pat.tactus.mulmaybe(d); const tactus = __tactus ? pat.tactus.mulmaybe(d) : undefined;
return pat return pat
.withQuerySpan((span) => span.withCycle((t) => t.mul(d).add(s))) .withQuerySpan((span) => span.withCycle((t) => t.mul(d).add(s)))
.withHapSpan((span) => span.withCycle((t) => t.sub(s).div(d))) .withHapSpan((span) => span.withCycle((t) => t.sub(s).div(d)))
@ -2173,7 +2191,7 @@ export const { juxBy, juxby } = register(['juxBy', 'juxby'], function (by, func,
const left = pat.withValue((val) => Object.assign({}, val, { pan: elem_or(val, 'pan', 0.5) - by })); const left = pat.withValue((val) => Object.assign({}, val, { pan: elem_or(val, 'pan', 0.5) - by }));
const right = func(pat.withValue((val) => Object.assign({}, val, { pan: elem_or(val, 'pan', 0.5) + by }))); const right = func(pat.withValue((val) => Object.assign({}, val, { pan: elem_or(val, 'pan', 0.5) + by })));
return stack(left, right).setTactus(lcm(left.tactus, right.tactus)); return stack(left, right).setTactus(__tactus ? lcm(left.tactus, right.tactus) : undefined);
}); });
/** /**
@ -2773,7 +2791,7 @@ export const chop = register('chop', function (n, pat) {
const func = function (o) { const func = function (o) {
return sequence(slice_objects.map((slice_o) => Object.assign({}, o, slice_o))); return sequence(slice_objects.map((slice_o) => Object.assign({}, o, slice_o)));
}; };
return pat.squeezeBind(func).setTactus(Fraction(n).mulmaybe(pat.tactus)); return pat.squeezeBind(func).setTactus(__tactus ? Fraction(n).mulmaybe(pat.tactus) : undefined);
}); });
/** /**
@ -2788,7 +2806,10 @@ export const striate = register('striate', function (n, pat) {
const slices = Array.from({ length: n }, (x, i) => i); const slices = Array.from({ length: n }, (x, i) => i);
const slice_objects = slices.map((i) => ({ begin: i / n, end: (i + 1) / n })); const slice_objects = slices.map((i) => ({ begin: i / n, end: (i + 1) / n }));
const slicePat = slowcat(...slice_objects); const slicePat = slowcat(...slice_objects);
return pat.set(slicePat)._fast(n); return pat
.set(slicePat)
._fast(n)
.setTactus(__tactus ? Fraction(n).mulmaybe(pat.tactus) : undefined);
}); });
/** /**

View file

@ -51,6 +51,7 @@ import {
stackRight, stackRight,
stackCentre, stackCentre,
s_cat, s_cat,
calculateTactus,
} from '../index.mjs'; } from '../index.mjs';
import { steady } from '../signal.mjs'; import { steady } from '../signal.mjs';
@ -1127,8 +1128,8 @@ describe('Pattern', () => {
it('Is correctly preserved/calculated through transformations', () => { it('Is correctly preserved/calculated through transformations', () => {
expect(sequence(0, 1, 2, 3).linger(4).tactus).toStrictEqual(Fraction(4)); expect(sequence(0, 1, 2, 3).linger(4).tactus).toStrictEqual(Fraction(4));
expect(sequence(0, 1, 2, 3).iter(4).tactus).toStrictEqual(Fraction(4)); expect(sequence(0, 1, 2, 3).iter(4).tactus).toStrictEqual(Fraction(4));
expect(sequence(0, 1, 2, 3).fast(4).tactus).toStrictEqual(Fraction(16)); expect(sequence(0, 1, 2, 3).fast(4).tactus).toStrictEqual(Fraction(4));
expect(sequence(0, 1, 2, 3).hurry(4).tactus).toStrictEqual(Fraction(16)); expect(sequence(0, 1, 2, 3).hurry(4).tactus).toStrictEqual(Fraction(4));
expect(sequence(0, 1, 2, 3).rev().tactus).toStrictEqual(Fraction(4)); expect(sequence(0, 1, 2, 3).rev().tactus).toStrictEqual(Fraction(4));
expect(sequence(1).segment(10).tactus).toStrictEqual(Fraction(10)); expect(sequence(1).segment(10).tactus).toStrictEqual(Fraction(10));
expect(sequence(1, 0, 1).invert().tactus).toStrictEqual(Fraction(3)); expect(sequence(1, 0, 1).invert().tactus).toStrictEqual(Fraction(3));
@ -1164,7 +1165,7 @@ describe('Pattern', () => {
expect(stackCentre(fastcat(0, 1, 2), fastcat(3, 4)).tactus).toStrictEqual(Fraction(3)); expect(stackCentre(fastcat(0, 1, 2), fastcat(3, 4)).tactus).toStrictEqual(Fraction(3));
expect(fastcat(0, 1).ply(3).tactus).toStrictEqual(Fraction(6)); expect(fastcat(0, 1).ply(3).tactus).toStrictEqual(Fraction(6));
expect(fastcat(0, 1).setTactus(undefined).ply(3).tactus).toStrictEqual(undefined); expect(fastcat(0, 1).setTactus(undefined).ply(3).tactus).toStrictEqual(undefined);
expect(fastcat(0, 1).fast(3).tactus).toStrictEqual(Fraction(6)); expect(fastcat(0, 1).fast(3).tactus).toStrictEqual(Fraction(2));
expect(fastcat(0, 1).setTactus(undefined).fast(3).tactus).toStrictEqual(undefined); expect(fastcat(0, 1).setTactus(undefined).fast(3).tactus).toStrictEqual(undefined);
}); });
}); });