Beat-oriented functionality (#976)
* annotate pure values with their value, allowing single mininotation values to maintain their labels as pure * Don't use any 'patternified' arguments if they're all 'pure' * allow pattern weights (roughly, beats-per-cycle) to be inferred where possible, including from mininotation and across many transformations (e.g. `fast` with a 'pure' factor) * Add `beatCat`, similar to `timeCat` but funkier * `silence` has a weight of 1, add alternative `nothing` with a weight of 0, and `gap` function with weight argument * preserve weight across applicative operations (weight comes with the structure) * add `stack` alternatives that take advantage of pattern weights to align patterns differently - `stackLeft`, `stackRight`, `stackCentre`, `stackExpand`, with `stackBy` with an argument for patterning the alignment.
This commit is contained in:
parent
d102e1dbbc
commit
398533877c
8 changed files with 1391 additions and 1381 deletions
|
|
@ -92,16 +92,16 @@ export function patternifyAST(ast, code, onEnter, offset = 0) {
|
|||
return strudel.stack(...children);
|
||||
}
|
||||
if (alignment === 'polymeter_slowcat') {
|
||||
const aligned = children.map((child) => child._slow(strudel.Fraction(child.__weight ?? 1)));
|
||||
const aligned = children.map((child) => child._slow(child.weight));
|
||||
return strudel.stack(...aligned);
|
||||
}
|
||||
if (alignment === 'polymeter') {
|
||||
// polymeter
|
||||
const stepsPerCycle = ast.arguments_.stepsPerCycle
|
||||
? enter(ast.arguments_.stepsPerCycle).fmap((x) => strudel.Fraction(x))
|
||||
: strudel.pure(strudel.Fraction(children.length > 0 ? children[0].__weight : 1));
|
||||
: strudel.pure(strudel.Fraction(children.length > 0 ? children[0].weight : 1));
|
||||
|
||||
const aligned = children.map((child) => child.fast(stepsPerCycle.fmap((x) => x.div(child.__weight || 1))));
|
||||
const aligned = children.map((child) => child.fast(stepsPerCycle.fmap((x) => x.div(child.weight))));
|
||||
return strudel.stack(...aligned);
|
||||
}
|
||||
if (alignment === 'rand') {
|
||||
|
|
@ -112,13 +112,18 @@ export function patternifyAST(ast, code, onEnter, offset = 0) {
|
|||
}
|
||||
const weightedChildren = ast.source_.some((child) => !!child.options_?.weight);
|
||||
if (weightedChildren) {
|
||||
const weightSum = ast.source_.reduce((sum, child) => sum + (child.options_?.weight || 1), 0);
|
||||
const pat = strudel.timeCat(...ast.source_.map((child, i) => [child.options_?.weight || 1, children[i]]));
|
||||
pat.__weight = weightSum;
|
||||
const weightSum = ast.source_.reduce(
|
||||
(sum, child) => sum.add(child.options_?.weight || strudel.Fraction(1)),
|
||||
strudel.Fraction(0),
|
||||
);
|
||||
const pat = strudel.timeCat(
|
||||
...ast.source_.map((child, i) => [child.options_?.weight || strudel.Fraction(1), children[i]]),
|
||||
);
|
||||
pat.weight = weightSum;
|
||||
return pat;
|
||||
}
|
||||
const pat = strudel.sequence(...children);
|
||||
pat.__weight = children.length;
|
||||
pat.weight = children.length;
|
||||
return pat;
|
||||
}
|
||||
case 'element': {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue