mirror of
https://github.com/eliasstepanik/strudel-docker.git
synced 2026-01-11 05:38:34 +00:00
Improve performance of ! (replicate) (#1084)
* Implement ! with weighted repeatCycles * reimplement repeatCycles without array filling
This commit is contained in:
parent
deed379dba
commit
34e9d73908
@ -2310,7 +2310,13 @@ export const { iterBack, iterback } = register(
|
||||
export const { repeatCycles } = register(
|
||||
'repeatCycles',
|
||||
function (n, pat) {
|
||||
return slowcat(...Array(n).fill(pat));
|
||||
return new Pattern(function (state) {
|
||||
const cycle = state.span.begin.sam();
|
||||
const source_cycle = cycle.div(n).sam();
|
||||
const delta = cycle.sub(source_cycle);
|
||||
state = state.withSpan((span) => span.withTime((spant) => spant.sub(delta)));
|
||||
return pat.query(state).map((hap) => hap.withSpan((span) => span.withTime((spant) => spant.add(delta))));
|
||||
}).splitQueries();
|
||||
},
|
||||
true,
|
||||
true,
|
||||
|
||||
@ -295,7 +295,15 @@ function peg$parse(input, options) {
|
||||
var peg$f6 = function(a) { return a };
|
||||
var peg$f7 = function(s) { s.arguments_.alignment = 'polymeter_slowcat'; return s; };
|
||||
var peg$f8 = function(a) { return x => x.options_['weight'] = (x.options_['weight'] ?? 1) + (a ?? 2) - 1 };
|
||||
var peg$f9 = function(a) { return x => x.options_['reps'] = (x.options_['reps'] ?? 1) + (a ?? 2) - 1 };
|
||||
var peg$f9 = function(a) { return x => {const reps = (x.options_['reps'] ?? 1) + (a ?? 2) - 1;
|
||||
x.options_['reps'] = reps;
|
||||
console.log("reps: ", reps)
|
||||
x.options_['ops'] = x.options_['ops'].filter(x => x.type_ !== "replicate");
|
||||
x.options_['ops'].push({ type_: "replicate", arguments_ :{ amount:reps }});
|
||||
x.options_['weight'] = reps;
|
||||
console.log("options: ", x.options_);
|
||||
}
|
||||
};
|
||||
var peg$f10 = function(p, s, r) { return x => x.options_['ops'].push({ type_: "bjorklund", arguments_ :{ pulse: p, step:s, rotation:r }}) };
|
||||
var peg$f11 = function(a) { return x => x.options_['ops'].push({ type_: "stretch", arguments_ :{ amount:a, type: 'slow' }}) };
|
||||
var peg$f12 = function(a) { return x => x.options_['ops'].push({ type_: "stretch", arguments_ :{ amount:a, type: 'fast' }}) };
|
||||
|
||||
@ -135,7 +135,14 @@ op_weight = ws ("@" / "_") a:number?
|
||||
{ return x => x.options_['weight'] = (x.options_['weight'] ?? 1) + (a ?? 2) - 1 }
|
||||
|
||||
op_replicate = ws "!" a:number?
|
||||
{ return x => x.options_['reps'] = (x.options_['reps'] ?? 1) + (a ?? 2) - 1 }
|
||||
{ return x => {// A bit fiddly, to support both x!4 and x!!! as equivalent..
|
||||
const reps = (x.options_['reps'] ?? 1) + (a ?? 2) - 1;
|
||||
x.options_['reps'] = reps;
|
||||
x.options_['ops'] = x.options_['ops'].filter(x => x.type_ !== "replicate");
|
||||
x.options_['ops'].push({ type_: "replicate", arguments_ :{ amount:reps }});
|
||||
x.options_['weight'] = reps;
|
||||
}
|
||||
}
|
||||
|
||||
op_bjorklund = "(" ws p:slice_with_ops ws comma ws s:slice_with_ops ws comma? ws r:slice_with_ops? ws ")"
|
||||
{ return x => x.options_['ops'].push({ type_: "bjorklund", arguments_ :{ pulse: p, step:s, rotation:r }}) }
|
||||
|
||||
@ -27,6 +27,12 @@ const applyOptions = (parent, enter) => (pat, i) => {
|
||||
pat = strudel.reify(pat)[type](enter(amount));
|
||||
break;
|
||||
}
|
||||
case 'replicate': {
|
||||
const { amount } = op.arguments_;
|
||||
pat = strudel.reify(pat);
|
||||
pat = pat._repeatCycles(amount)._fast(amount);
|
||||
break;
|
||||
}
|
||||
case 'bjorklund': {
|
||||
if (op.arguments_.rotation) {
|
||||
pat = pat.euclidRot(enter(op.arguments_.pulse), enter(op.arguments_.step), enter(op.arguments_.rotation));
|
||||
@ -67,26 +73,13 @@ const applyOptions = (parent, enter) => (pat, i) => {
|
||||
return pat;
|
||||
};
|
||||
|
||||
function resolveReplications(ast) {
|
||||
ast.source_ = strudel.flatten(
|
||||
ast.source_.map((child) => {
|
||||
const { reps } = child.options_ || {};
|
||||
if (!reps) {
|
||||
return [child];
|
||||
}
|
||||
delete child.options_.reps;
|
||||
return Array(reps).fill(child);
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
// expects ast from mini2ast + quoted mini string + optional callback when a node is entered
|
||||
export function patternifyAST(ast, code, onEnter, offset = 0) {
|
||||
onEnter?.(ast);
|
||||
const enter = (node) => patternifyAST(node, code, onEnter, offset);
|
||||
switch (ast.type_) {
|
||||
case 'pattern': {
|
||||
resolveReplications(ast);
|
||||
// resolveReplications(ast);
|
||||
const children = ast.source_.map((child) => enter(child)).map(applyOptions(ast, enter));
|
||||
const alignment = ast.arguments_.alignment;
|
||||
const with_tactus = children.filter((child) => child.__tactus_source);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user