Make default alignment configurable
This commit is contained in:
parent
7f2860eb14
commit
6e61f3cdb6
1 changed files with 104 additions and 89 deletions
|
|
@ -1055,91 +1055,88 @@ function _composeOp(a, b, func) {
|
||||||
return func(a, b);
|
return func(a, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make composers
|
// pattern composers
|
||||||
(function () {
|
const COMPOSERS = {
|
||||||
// pattern composers
|
set: [(a, b) => b],
|
||||||
const composers = {
|
keep: [(a) => a],
|
||||||
set: [(a, b) => b],
|
keepif: [(a, b) => (b ? a : undefined)],
|
||||||
keep: [(a) => a],
|
|
||||||
keepif: [(a, b) => (b ? a : undefined)],
|
|
||||||
|
|
||||||
// numerical functions
|
// numerical functions
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Assumes a pattern of numbers. Adds the given number to each item in the pattern.
|
* Assumes a pattern of numbers. Adds the given number to each item in the pattern.
|
||||||
* @name add
|
* @name add
|
||||||
* @memberof Pattern
|
* @memberof Pattern
|
||||||
* @tags math
|
* @tags math
|
||||||
* @example
|
* @example
|
||||||
* // Here, the triad 0, 2, 4 is shifted by different amounts
|
* // Here, the triad 0, 2, 4 is shifted by different amounts
|
||||||
* n("0 2 4".add("<0 3 4 0>")).scale("C:major")
|
* n("0 2 4".add("<0 3 4 0>")).scale("C:major")
|
||||||
* // Without add, the equivalent would be:
|
* // Without add, the equivalent would be:
|
||||||
* // n("<[0 2 4] [3 5 7] [4 6 8] [0 2 4]>").scale("C:major")
|
* // n("<[0 2 4] [3 5 7] [4 6 8] [0 2 4]>").scale("C:major")
|
||||||
* @example
|
* @example
|
||||||
* // You can also use add with notes:
|
* // You can also use add with notes:
|
||||||
* note("c3 e3 g3".add("<0 5 7 0>"))
|
* note("c3 e3 g3".add("<0 5 7 0>"))
|
||||||
* // Behind the scenes, the notes are converted to midi numbers:
|
* // Behind the scenes, the notes are converted to midi numbers:
|
||||||
* // note("48 52 55".add("<0 5 7 0>"))
|
* // note("48 52 55".add("<0 5 7 0>"))
|
||||||
*/
|
*/
|
||||||
add: [numeralArgs((a, b) => a + b)], // support string concatenation
|
add: [numeralArgs((a, b) => a + b)], // support string concatenation
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Like add, but the given numbers are subtracted.
|
* Like add, but the given numbers are subtracted.
|
||||||
* @name sub
|
* @name sub
|
||||||
* @memberof Pattern
|
* @memberof Pattern
|
||||||
* @tags math
|
* @tags math
|
||||||
* @example
|
* @example
|
||||||
* n("0 2 4".sub("<0 1 2 3>")).scale("C4:minor")
|
* n("0 2 4".sub("<0 1 2 3>")).scale("C4:minor")
|
||||||
* // See add for more information.
|
* // See add for more information.
|
||||||
*/
|
*/
|
||||||
sub: [numeralArgs((a, b) => a - b)],
|
sub: [numeralArgs((a, b) => a - b)],
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Multiplies each number by the given factor.
|
* Multiplies each number by the given factor.
|
||||||
* @name mul
|
* @name mul
|
||||||
* @memberof Pattern
|
* @memberof Pattern
|
||||||
* @tags math
|
* @tags math
|
||||||
* @example
|
* @example
|
||||||
* "<1 1.5 [1.66, <2 2.33>]>*4".mul(150).freq()
|
* "<1 1.5 [1.66, <2 2.33>]>*4".mul(150).freq()
|
||||||
*/
|
*/
|
||||||
mul: [numeralArgs((a, b) => a * b)],
|
mul: [numeralArgs((a, b) => a * b)],
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Divides each number by the given factor.
|
* Divides each number by the given factor.
|
||||||
* @name div
|
* @name div
|
||||||
* @memberof Pattern
|
* @memberof Pattern
|
||||||
* @tags math
|
* @tags math
|
||||||
*/
|
*/
|
||||||
div: [numeralArgs((a, b) => a / b)],
|
div: [numeralArgs((a, b) => a / b)],
|
||||||
mod: [numeralArgs(_mod)],
|
mod: [numeralArgs(_mod)],
|
||||||
pow: [numeralArgs(Math.pow)],
|
pow: [numeralArgs(Math.pow)],
|
||||||
log2: [numeralArgs(Math.log2)],
|
log2: [numeralArgs(Math.log2)],
|
||||||
band: [numeralArgs((a, b) => a & b)],
|
band: [numeralArgs((a, b) => a & b)],
|
||||||
bor: [numeralArgs((a, b) => a | b)],
|
bor: [numeralArgs((a, b) => a | b)],
|
||||||
bxor: [numeralArgs((a, b) => a ^ b)],
|
bxor: [numeralArgs((a, b) => a ^ b)],
|
||||||
blshift: [numeralArgs((a, b) => a << b)],
|
blshift: [numeralArgs((a, b) => a << b)],
|
||||||
brshift: [numeralArgs((a, b) => a >> b)],
|
brshift: [numeralArgs((a, b) => a >> b)],
|
||||||
|
|
||||||
// TODO - force numerical comparison if both look like numbers?
|
// TODO - force numerical comparison if both look like numbers?
|
||||||
lt: [(a, b) => a < b],
|
lt: [(a, b) => a < b],
|
||||||
gt: [(a, b) => a > b],
|
gt: [(a, b) => a > b],
|
||||||
lte: [(a, b) => a <= b],
|
lte: [(a, b) => a <= b],
|
||||||
gte: [(a, b) => a >= b],
|
gte: [(a, b) => a >= b],
|
||||||
eq: [(a, b) => a == b],
|
eq: [(a, b) => a == b],
|
||||||
eqt: [(a, b) => a === b],
|
eqt: [(a, b) => a === b],
|
||||||
ne: [(a, b) => a != b],
|
ne: [(a, b) => a != b],
|
||||||
net: [(a, b) => a !== b],
|
net: [(a, b) => a !== b],
|
||||||
and: [(a, b) => a && b],
|
and: [(a, b) => a && b],
|
||||||
or: [(a, b) => a || b],
|
or: [(a, b) => a || b],
|
||||||
|
|
||||||
// bitwise ops
|
// bitwise ops
|
||||||
func: [(a, b) => b(a)],
|
func: [(a, b) => b(a)],
|
||||||
};
|
};
|
||||||
|
|
||||||
const hows = ['In', 'Out', 'Mix', 'Squeeze', 'SqueezeOut', 'Reset', 'Restart', 'Poly'];
|
|
||||||
|
|
||||||
|
const _setupAlignments = () => {
|
||||||
// generate methods to do what and how
|
// generate methods to do what and how
|
||||||
for (const [what, [op, preprocess]] of Object.entries(composers)) {
|
for (const [what, [op, preprocess]] of Object.entries(COMPOSERS)) {
|
||||||
// make plain version, e.g. pat._add(value) adds that plain value
|
// make plain version, e.g. pat._add(value) adds that plain value
|
||||||
// to all the values in pat
|
// to all the values in pat
|
||||||
Pattern.prototype['_' + what] = function (value) {
|
Pattern.prototype['_' + what] = function (value) {
|
||||||
|
|
@ -1148,16 +1145,18 @@ function _composeOp(a, b, func) {
|
||||||
|
|
||||||
// make patternified monster version
|
// make patternified monster version
|
||||||
Object.defineProperty(Pattern.prototype, what, {
|
Object.defineProperty(Pattern.prototype, what, {
|
||||||
|
// Set to configurable so we can update if the default alignment changes
|
||||||
|
configurable: true,
|
||||||
// a getter that returns a function, so 'pat' can be
|
// a getter that returns a function, so 'pat' can be
|
||||||
// accessed by closures that are methods of that function..
|
// accessed by closures that are methods of that function..
|
||||||
get: function () {
|
get: function () {
|
||||||
const pat = this;
|
const pat = this;
|
||||||
|
|
||||||
// wrap the 'in' function as default behaviour
|
// wrap the 'in' function as default behaviour
|
||||||
const wrapper = (...other) => pat[what]['in'](...other);
|
const wrapper = (...other) => pat[what][DEFAULT_ALIGNMENT](...other);
|
||||||
|
|
||||||
// add methods to that function for each behaviour
|
// add methods to that function for each behaviour
|
||||||
for (const how of hows) {
|
for (const how of ALIGNMENTS) {
|
||||||
wrapper[how.toLowerCase()] = function (...other) {
|
wrapper[how.toLowerCase()] = function (...other) {
|
||||||
var howpat = pat;
|
var howpat = pat;
|
||||||
other = sequence(other);
|
other = sequence(other);
|
||||||
|
|
@ -1182,15 +1181,23 @@ function _composeOp(a, b, func) {
|
||||||
return wrapper;
|
return wrapper;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// Default op to 'set', e.g. pat.squeeze(pat2) = pat.set.squeeze(pat2)
|
|
||||||
for (const how of hows) {
|
|
||||||
Pattern.prototype[how.toLowerCase()] = function (...args) {
|
|
||||||
return this.set[how.toLowerCase()](args);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let DEFAULT_ALIGNMENT = 'in';
|
||||||
|
const ALIGNMENTS = ['In', 'Out', 'Mix', 'Squeeze', 'SqueezeOut', 'Reset', 'Restart', 'Poly'];
|
||||||
|
const ALIGNMENT_KEYS = ALIGNMENTS.map((how) => how.toLowerCase());
|
||||||
|
|
||||||
|
// Make composers
|
||||||
|
(function () {
|
||||||
|
_setupAlignments();
|
||||||
|
|
||||||
|
// Default op to 'set', e.g. pat.squeeze(pat2) = pat.set.squeeze(pat2)
|
||||||
|
for (const how of ALIGNMENTS) {
|
||||||
|
Pattern.prototype[how.toLowerCase()] = function (...args) {
|
||||||
|
return this.set[how.toLowerCase()](args);
|
||||||
|
};
|
||||||
|
}
|
||||||
// binary composers
|
// binary composers
|
||||||
/**
|
/**
|
||||||
* Applies the given structure to the pattern:
|
* Applies the given structure to the pattern:
|
||||||
|
|
@ -1249,6 +1256,14 @@ function _composeOp(a, b, func) {
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
export const setDefaultAlignment = (alignment) => {
|
||||||
|
alignment = alignment?.toLowerCase();
|
||||||
|
if (DEFAULT_ALIGNMENT !== alignment && ALIGNMENT_KEYS.includes(alignment)) {
|
||||||
|
DEFAULT_ALIGNMENT = alignment;
|
||||||
|
_setupAlignments();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// aliases
|
// aliases
|
||||||
export const polyrhythm = stack;
|
export const polyrhythm = stack;
|
||||||
export const pr = stack;
|
export const pr = stack;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue