mirror of
https://github.com/eliasstepanik/strudel-docker.git
synced 2026-01-27 13:38:40 +00:00
Experimental rejig of the pattern composers.
Now `restart` is `setRestart`, use `constRestart` for the old behavior. Same for `reset`.
This commit is contained in:
parent
08f8a7a17c
commit
5c3f095ef2
@ -135,6 +135,11 @@ export class Pattern {
|
|||||||
return this._filterEvents((hap) => hap.hasOnset());
|
return this._filterEvents((hap) => hap.hasOnset());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
discreteOnly() {
|
||||||
|
// removes continuous events that don't have a 'whole' timespan
|
||||||
|
return this._filterEvents((hap) => hap.whole);
|
||||||
|
}
|
||||||
|
|
||||||
_appWhole(whole_func, pat_val) {
|
_appWhole(whole_func, pat_val) {
|
||||||
// Assumes 'this' is a pattern of functions, and given a function to
|
// Assumes 'this' is a pattern of functions, and given a function to
|
||||||
// resolve wholes, applies a given pattern of values to that
|
// resolve wholes, applies a given pattern of values to that
|
||||||
@ -247,13 +252,13 @@ export class Pattern {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
_opLeft(other, func) {
|
_op(other, func) {
|
||||||
return this.fmap(func).appLeft(reify(other));
|
return this.fmap(func).appLeft(reify(other));
|
||||||
}
|
}
|
||||||
_opRight(other, func) {
|
_opFlip(other, func) {
|
||||||
return this.fmap(func).appRight(reify(other));
|
return this.fmap(func).appRight(reify(other));
|
||||||
}
|
}
|
||||||
_opBoth(other, func) {
|
_opSect(other, func) {
|
||||||
return this.fmap(func).appBoth(reify(other));
|
return this.fmap(func).appBoth(reify(other));
|
||||||
}
|
}
|
||||||
_opSqueeze(other, func) {
|
_opSqueeze(other, func) {
|
||||||
@ -265,6 +270,14 @@ export class Pattern {
|
|||||||
const otherPat = reify(other);
|
const otherPat = reify(other);
|
||||||
return otherPat.fmap((a) => thisPat.fmap((b) => func(b)(a)))._squeezeJoin();
|
return otherPat.fmap((a) => thisPat.fmap((b) => func(b)(a)))._squeezeJoin();
|
||||||
}
|
}
|
||||||
|
_opReset(other, func) {
|
||||||
|
const otherPat = reify(other);
|
||||||
|
return otherPat.fmap((b) => this.fmap((a) => func(a)(b)))._resetJoin();
|
||||||
|
}
|
||||||
|
_opRestart(other, func) {
|
||||||
|
const otherPat = reify(other);
|
||||||
|
return otherPat.fmap((b) => this.fmap((a) => func(a)(b)))._restartJoin();
|
||||||
|
}
|
||||||
|
|
||||||
_asNumber(silent = false) {
|
_asNumber(silent = false) {
|
||||||
return this._withEvent((event) => {
|
return this._withEvent((event) => {
|
||||||
@ -382,6 +395,33 @@ export class Pattern {
|
|||||||
return this.innerBind(id);
|
return this.innerBind(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_resetJoin(restart=false) {
|
||||||
|
const pat_of_pats = this;
|
||||||
|
return new Pattern((state) => {
|
||||||
|
return pat_of_pats
|
||||||
|
.discreteOnly()
|
||||||
|
.query(state)
|
||||||
|
.map((outer_hap) => {
|
||||||
|
return outer_hap.value
|
||||||
|
.late(restart ? outer_hap.whole.begin : outer_hap.whole.begin.cyclePos())
|
||||||
|
.query(state)
|
||||||
|
.map((inner_hap) =>
|
||||||
|
new Hap(
|
||||||
|
inner_hap.whole ? inner_hap.whole.intersection(outer_hap.whole) : undefined,
|
||||||
|
inner_hap.part.intersection(outer_hap.part),
|
||||||
|
inner_hap.value,
|
||||||
|
).setContext(outer_hap.combineContext(inner_hap)),
|
||||||
|
)
|
||||||
|
.filter((hap) => hap.part);
|
||||||
|
})
|
||||||
|
.flat();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
_restartJoin() {
|
||||||
|
return this._resetJoin(true);
|
||||||
|
}
|
||||||
|
|
||||||
_squeezeJoin() {
|
_squeezeJoin() {
|
||||||
const pat_of_pats = this;
|
const pat_of_pats = this;
|
||||||
function query(state) {
|
function query(state) {
|
||||||
@ -721,21 +761,6 @@ export class Pattern {
|
|||||||
_velocity(velocity) {
|
_velocity(velocity) {
|
||||||
return this._withContext((context) => ({ ...context, velocity: (context.velocity || 1) * velocity }));
|
return this._withContext((context) => ({ ...context, velocity: (context.velocity || 1) * velocity }));
|
||||||
}
|
}
|
||||||
|
|
||||||
restart(pat) {
|
|
||||||
pat = reify(pat);
|
|
||||||
return new Pattern((state) =>
|
|
||||||
pat
|
|
||||||
.query(state)
|
|
||||||
.map((event) => {
|
|
||||||
const resetSpan = new TimeSpan(event.part.begin.sub(event.whole.begin), event.duration);
|
|
||||||
return this.query(new State(resetSpan)).map((hap) =>
|
|
||||||
hap.withSpan((s) => s.withTime((t) => t.add(event.whole.begin))).setContext(hap.combineContext(event)),
|
|
||||||
);
|
|
||||||
})
|
|
||||||
.flat(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// pattern composers
|
// pattern composers
|
||||||
@ -757,6 +782,23 @@ const composers = {
|
|||||||
},
|
},
|
||||||
id,
|
id,
|
||||||
],
|
],
|
||||||
|
const: [
|
||||||
|
(a) => (b) => {
|
||||||
|
// If an object is involved, do a union, discarding matching keys from a.
|
||||||
|
// Otherwise, just return b.
|
||||||
|
if (a instanceof Object || b instanceof Object) {
|
||||||
|
if (!a instanceof Object) {
|
||||||
|
a = { value: a };
|
||||||
|
}
|
||||||
|
if (!b instanceof Object) {
|
||||||
|
b = { value: b };
|
||||||
|
}
|
||||||
|
return Object.assign({}, b, a);
|
||||||
|
}
|
||||||
|
return a;
|
||||||
|
},
|
||||||
|
id,
|
||||||
|
],
|
||||||
add: [(a) => (b) => a + b, (x) => x._asNumber()],
|
add: [(a) => (b) => a + b, (x) => x._asNumber()],
|
||||||
sub: [(a) => (b) => a - b, (x) => x._asNumber()],
|
sub: [(a) => (b) => a - b, (x) => x._asNumber()],
|
||||||
mul: [(a) => (b) => a * b, (x) => x._asNumber()],
|
mul: [(a) => (b) => a * b, (x) => x._asNumber()],
|
||||||
@ -764,21 +806,14 @@ const composers = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
for (const [name, op] of Object.entries(composers)) {
|
for (const [name, op] of Object.entries(composers)) {
|
||||||
Pattern.prototype[name] = function (...other) {
|
for (const opType of ['', 'Flip', 'Sect', 'Squeeze', 'SqueezeFlip', 'Reset', 'Restart']) {
|
||||||
return op[1](this)._opLeft(sequence(other), op[0]);
|
Pattern.prototype[name + opType] = function (...other) {
|
||||||
};
|
return op[1](this)['_op' + opType](sequence(other), op[0]);
|
||||||
Pattern.prototype[name + 'Flip'] = function (...other) {
|
};
|
||||||
return op[1](this)._opRight(sequence(other), op[0]);
|
if (name === "set" && opType !== '') {
|
||||||
};
|
Pattern.prototype[opType.toLowerCase()] = Pattern.prototype[name + opType];
|
||||||
Pattern.prototype[name + 'Sect'] = function (...other) {
|
}
|
||||||
return op[1](this)._opBoth(sequence(other), op[0]);
|
}
|
||||||
};
|
|
||||||
Pattern.prototype[name + 'Squeeze'] = function (...other) {
|
|
||||||
return op[1](this)._opSqueeze(sequence(other), op[0]);
|
|
||||||
};
|
|
||||||
Pattern.prototype[name + 'SqueezeFlip'] = function (...other) {
|
|
||||||
return op[1](this)._opSqueezeFlip(sequence(other), op[0]);
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// methods of Pattern that get callable factories
|
// methods of Pattern that get callable factories
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user