mirror of
https://github.com/eliasstepanik/strudel-docker.git
synced 2026-01-11 21:58:31 +00:00
Merge pull request #369 from tidalcycles/docs
document more functions + change arp join
This commit is contained in:
commit
1015bb0fdc
17
index.mjs
Normal file
17
index.mjs
Normal file
@ -0,0 +1,17 @@
|
||||
// this barrel export is currently only used to find undocumented exports
|
||||
export * from './packages/core/index.mjs';
|
||||
export * from './packages/csound/index.mjs';
|
||||
export * from './packages/embed/index.mjs';
|
||||
export * from './packages/eval/index.mjs';
|
||||
export * from './packages/midi/index.mjs';
|
||||
export * from './packages/mini/index.mjs';
|
||||
export * from './packages/osc/index.mjs';
|
||||
export * from './packages/react/index.mjs';
|
||||
export * from './packages/serial/index.mjs';
|
||||
export * from './packages/soundfonts/index.mjs';
|
||||
export * from './packages/tonal/index.mjs';
|
||||
export * from './packages/tone/index.mjs';
|
||||
export * from './packages/transpiler/index.mjs';
|
||||
export * from './packages/webaudio/index.mjs';
|
||||
export * from './packages/webdirt/index.mjs';
|
||||
export * from './packages/xen/index.mjs';
|
||||
1303
package-lock.json
generated
1303
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -22,6 +22,7 @@
|
||||
"lint": "eslint . --ext mjs,js --quiet",
|
||||
"codeformat": "prettier --write .",
|
||||
"format-check": "prettier --check .",
|
||||
"report-undocumented": "node undocumented.mjs > undocumented.json",
|
||||
"check": "npm run format-check && npm run lint && npm run test",
|
||||
"iclc": "cd paper && pandoc --template=pandoc/iclc.html --citeproc --number-sections iclc2023.md -o iclc2023.html && pandoc --template=pandoc/iclc.latex --citeproc --number-sections iclc2023.md -o iclc2023.pdf"
|
||||
},
|
||||
@ -49,6 +50,7 @@
|
||||
"@vitest/ui": "^0.25.7",
|
||||
"c8": "^7.12.0",
|
||||
"canvas": "^2.11.0",
|
||||
"dependency-tree": "^9.0.0",
|
||||
"eslint": "^8.28.0",
|
||||
"events": "^3.3.0",
|
||||
"gh-pages": "^4.0.0",
|
||||
|
||||
@ -8,13 +8,10 @@ import createClock from './zyklus.mjs';
|
||||
import { logger } from './logger.mjs';
|
||||
|
||||
export class Cyclist {
|
||||
worker;
|
||||
pattern;
|
||||
started = false;
|
||||
cps = 1; // TODO
|
||||
getTime;
|
||||
phase = 0;
|
||||
constructor({ interval, onTrigger, onToggle, onError, getTime, latency = 0.1 }) {
|
||||
this.started = false;
|
||||
this.cps = 1; // TODO
|
||||
this.phase = 0;
|
||||
this.getTime = getTime;
|
||||
this.onToggle = onToggle;
|
||||
this.latency = latency;
|
||||
|
||||
@ -23,7 +23,6 @@ export const setStringParser = (parser) => (stringParser = parser);
|
||||
|
||||
/** @class Class representing a pattern. */
|
||||
export class Pattern {
|
||||
_Pattern = true; // this property is used to detect if a pattern that fails instanceof Pattern is an instance of another Pattern
|
||||
/**
|
||||
* Create a pattern. As an end user, you will most likely not create a Pattern directly.
|
||||
*
|
||||
@ -31,6 +30,7 @@ export class Pattern {
|
||||
*/
|
||||
constructor(query) {
|
||||
this.query = query;
|
||||
this._Pattern = true; // this property is used to detect if a pattern that fails instanceof Pattern is an instance of another Pattern
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
@ -39,8 +39,11 @@ export class Pattern {
|
||||
/**
|
||||
* Returns a new pattern, with the function applied to the value of
|
||||
* each hap. It has the alias {@link Pattern#fmap}.
|
||||
* @param {Function} func
|
||||
* @synonyms fmap
|
||||
* @param {Function} func to to apply to the value
|
||||
* @returns Pattern
|
||||
* @example
|
||||
* "0 1 2".withValue(v => v + 10).log()
|
||||
*/
|
||||
withValue(func) {
|
||||
return new Pattern((state) => this.query(state).map((hap) => hap.withValue(func)));
|
||||
@ -53,10 +56,15 @@ export class Pattern {
|
||||
return this.withValue(func);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assumes 'this' is a pattern of functions, and given a function to
|
||||
* resolve wholes, applies a given pattern of values to that
|
||||
* pattern of functions.
|
||||
* @param {Function} whole_func
|
||||
* @param {Function} func
|
||||
* @returns Pattern
|
||||
*/
|
||||
appWhole(whole_func, pat_val) {
|
||||
// Assumes 'this' is a pattern of functions, and given a function to
|
||||
// resolve wholes, applies a given pattern of values to that
|
||||
// pattern of functions.
|
||||
const pat_func = this;
|
||||
const query = function (state) {
|
||||
const hap_funcs = pat_func.query(state);
|
||||
@ -679,6 +687,7 @@ export class Pattern {
|
||||
* Layers the result of the given function(s). Like {@link Pattern.superimpose}, but without the original pattern:
|
||||
* @name layer
|
||||
* @memberof Pattern
|
||||
* @synonyms apply
|
||||
* @returns Pattern
|
||||
* @example
|
||||
* "<0 2 4 6 ~ 4 ~ 2 0!3 ~!5>*4"
|
||||
@ -724,9 +733,10 @@ export class Pattern {
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the given pattern(s) to the current pattern. Synonyms: .sequence .fastcat
|
||||
* Appends the given pattern(s) to the current pattern.
|
||||
* @name seq
|
||||
* @memberof Pattern
|
||||
* @synonyms sequence, fastcat
|
||||
* @example
|
||||
* s("hh*2").seq(
|
||||
* note("c2(3,8)")
|
||||
@ -737,9 +747,10 @@ export class Pattern {
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the given pattern(s) to the next cycle. Synonym: .slowcat
|
||||
* Appends the given pattern(s) to the next cycle.
|
||||
* @name cat
|
||||
* @memberof Pattern
|
||||
* @synonyms slowcat
|
||||
* @example
|
||||
* s("hh*2").cat(
|
||||
* note("c2(3,8)")
|
||||
@ -822,15 +833,25 @@ Pattern.prototype.collect = function () {
|
||||
);
|
||||
};
|
||||
|
||||
// applies func to each array of congruent haps
|
||||
/**
|
||||
* Selects indices in in stacked notes.
|
||||
* @example
|
||||
* note("<[c,eb,g]!2 [c,f,ab] [d,f,ab]>")
|
||||
* .arpWith(haps => haps[2])
|
||||
* */
|
||||
Pattern.prototype.arpWith = function (func) {
|
||||
return this.collect()
|
||||
.fmap((v) => reify(func(v)))
|
||||
.squeezeJoin()
|
||||
.innerJoin()
|
||||
.withHap((h) => new Hap(h.whole, h.part, h.value.value, h.combineContext(h.value)));
|
||||
};
|
||||
|
||||
// applies pattern of indices to each array of congruent haps
|
||||
/**
|
||||
* Selects indices in in stacked notes.
|
||||
* @example
|
||||
* note("<[c,eb,g]!2 [c,f,ab] [d,f,ab]>")
|
||||
* .arp("0 [0,2] 1 [0,2]").slow(2)
|
||||
* */
|
||||
Pattern.prototype.arp = function (pat) {
|
||||
return this.arpWith((haps) => pat.fmap((i) => haps[i % haps.length]));
|
||||
};
|
||||
@ -990,9 +1011,6 @@ function _composeOp(a, b, func) {
|
||||
/**
|
||||
* Applies the given structure to the pattern:
|
||||
*
|
||||
* @name struct
|
||||
* @memberof Pattern
|
||||
* @returns Pattern
|
||||
* @example
|
||||
* note("c3,eb3,g3")
|
||||
* .struct("x ~ x ~ ~ x ~ x ~ ~ ~ x ~ x ~ ~")
|
||||
@ -1004,18 +1022,37 @@ function _composeOp(a, b, func) {
|
||||
Pattern.prototype.structAll = function (...args) {
|
||||
return this.keep.out(...args);
|
||||
};
|
||||
/**
|
||||
* Returns silence when mask is 0 or "~"
|
||||
*
|
||||
* @example
|
||||
* note("c [eb,g] d [eb,g]").mask("<1 [0 1]>").slow(2)
|
||||
*/
|
||||
Pattern.prototype.mask = function (...args) {
|
||||
return this.keepif.in(...args);
|
||||
};
|
||||
Pattern.prototype.maskAll = function (...args) {
|
||||
return this.keep.in(...args);
|
||||
};
|
||||
/**
|
||||
* Resets the pattern to the start of the cycle for each onset of the reset pattern.
|
||||
*
|
||||
* @example
|
||||
* s("<bd lt> sd, hh*4").reset("<x@3 x(3,8)>")
|
||||
*/
|
||||
Pattern.prototype.reset = function (...args) {
|
||||
return this.keepif.trig(...args);
|
||||
};
|
||||
Pattern.prototype.resetAll = function (...args) {
|
||||
return this.keep.trig(...args);
|
||||
};
|
||||
/**
|
||||
* Restarts the pattern for each onset of the restart pattern.
|
||||
* While reset will only reset the current cycle, restart will start from cycle 0.
|
||||
*
|
||||
* @example
|
||||
* s("<bd lt> sd, hh*4").restart("<x@3 x(3,8)>")
|
||||
*/
|
||||
Pattern.prototype.restart = function (...args) {
|
||||
return this.keepif.trigzero(...args);
|
||||
};
|
||||
@ -1029,6 +1066,7 @@ export const polyrhythm = stack;
|
||||
export const pr = stack;
|
||||
|
||||
// methods that create patterns, which are added to patternified Pattern methods
|
||||
// TODO: remove? this is only used in old transpiler (shapeshifter)
|
||||
Pattern.prototype.factories = {
|
||||
pure,
|
||||
stack,
|
||||
@ -1098,6 +1136,7 @@ export function reify(thing) {
|
||||
/** The given items are played at the same time at the same length.
|
||||
*
|
||||
* @return {Pattern}
|
||||
* @synonyms polyrhythm, pr
|
||||
* @example
|
||||
* stack(g3, b3, [e4, d4]).note() // "g3,b3,[e4,d4]".note()
|
||||
*/
|
||||
@ -1152,24 +1191,10 @@ export function slowcatPrime(...pats) {
|
||||
return new Pattern(query).splitQueries();
|
||||
}
|
||||
|
||||
/** Concatenation: as with {@link slowcat}, but squashes a cycle from each pattern into one cycle
|
||||
*
|
||||
* Synonyms: {@link Pattern.seq}, {@link Pattern.sequence}
|
||||
*
|
||||
* @param {...any} items - The items to concatenate
|
||||
* @return {Pattern}
|
||||
* @example
|
||||
* fastcat(e5, b4, [d5, c5])
|
||||
* // sequence(e5, b4, [d5, c5])
|
||||
* // seq(e5, b4, [d5, c5])
|
||||
*/
|
||||
export function fastcat(...pats) {
|
||||
return slowcat(...pats)._fast(pats.length);
|
||||
}
|
||||
|
||||
/** The given items are con**cat**enated, where each one takes one cycle. Synonym: slowcat
|
||||
/** The given items are con**cat**enated, where each one takes one cycle.
|
||||
*
|
||||
* @param {...any} items - The items to concatenate
|
||||
* @synonyms slowcat
|
||||
* @return {Pattern}
|
||||
* @example
|
||||
* cat(e5, b4, [d5, c5]).note() // "<e5 b4 [d5 c5]>".note()
|
||||
@ -1196,12 +1221,17 @@ export function timeCat(...timepats) {
|
||||
return stack(...pats);
|
||||
}
|
||||
|
||||
export function fastcat(...pats) {
|
||||
return slowcat(...pats)._fast(pats.length);
|
||||
}
|
||||
|
||||
/** See {@link fastcat} */
|
||||
export function sequence(...pats) {
|
||||
return fastcat(...pats);
|
||||
}
|
||||
|
||||
/** Like **cat**, but the items are crammed into one cycle. Synonyms: fastcat, sequence
|
||||
/** Like **cat**, but the items are crammed into one cycle.
|
||||
* @synonyms fastcat, sequence
|
||||
* @example
|
||||
* seq(e5, b4, [d5, c5]).note() // "e5 b4 [d5 c5]".note()
|
||||
*
|
||||
@ -1257,7 +1287,7 @@ export function polymeterSteps(steps, ...args) {
|
||||
|
||||
/**
|
||||
* Combines the given lists of patterns with the same pulse. This will create so called polymeters when different sized sequences are used.
|
||||
* @name polymeter
|
||||
* @synonyms pm
|
||||
* @example
|
||||
* polymeter(["c", "eb", "g"], ["c2", "g2"]).note()
|
||||
* // "{c eb g, c2 g2}".note()
|
||||
@ -1435,23 +1465,27 @@ export const range = register('range', function (min, max, pat) {
|
||||
});
|
||||
|
||||
/**
|
||||
* Assumes a numerical pattern, containing unipolar values in the range 0 ..
|
||||
* 1. Returns a new pattern with values scaled to the given min/max range,
|
||||
* Assumes a numerical pattern, containing unipolar values in the range 0 .. 1
|
||||
* Returns a new pattern with values scaled to the given min/max range,
|
||||
* following an exponential curve.
|
||||
* @param {Number} min
|
||||
* @param {Number} max
|
||||
* @name rangex
|
||||
* @memberof Pattern
|
||||
* @returns Pattern
|
||||
* @example
|
||||
* s("bd sd,hh*4").cutoff(sine.rangex(500,2000).slow(4))
|
||||
*/
|
||||
export const rangex = register('rangex', function (min, max, pat) {
|
||||
return pat._range(Math.log(min), Math.log(max)).fmap(Math.exp);
|
||||
});
|
||||
|
||||
/**
|
||||
* Assumes a numerical pattern, containing bipolar values in the range -1 ..
|
||||
* 1. Returns a new pattern with values scaled to the given min/max range.
|
||||
* @param {Number} min
|
||||
* @param {Number} max
|
||||
* Assumes a numerical pattern, containing bipolar values in the range -1 .. 1
|
||||
* Returns a new pattern with values scaled to the given min/max range.
|
||||
* @name range2
|
||||
* @memberof Pattern
|
||||
* @returns Pattern
|
||||
* @example
|
||||
* s("bd sd,hh*4").cutoff(sine2.range2(500,2000).slow(4))
|
||||
*/
|
||||
export const range2 = register('range2', function (min, max, pat) {
|
||||
return pat.fromBipolar()._range(min, max);
|
||||
@ -1460,8 +1494,16 @@ export const range2 = register('range2', function (min, max, pat) {
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Structural and temporal transformations
|
||||
|
||||
// Compress each cycle into the given timespan, leaving a gap
|
||||
/** Compress each cycle into the given timespan, leaving a gap
|
||||
* @example
|
||||
* cat(
|
||||
* s("bd sd").compress(.25,.75),
|
||||
* s("~ bd sd ~")
|
||||
* )
|
||||
*/
|
||||
export const compress = register('compress', function (b, e, pat) {
|
||||
b = Fraction(b);
|
||||
e = Fraction(e);
|
||||
if (b.gt(e) || b.gt(1) || e.gt(1) || b.lt(0) || e.lt(0)) {
|
||||
return silence;
|
||||
}
|
||||
@ -1472,6 +1514,13 @@ export const { compressSpan, compressspan } = register(['compressSpan', 'compres
|
||||
return pat._compress(span.begin, span.end);
|
||||
});
|
||||
|
||||
/**
|
||||
* speeds up a pattern like fast, but rather than it playing multiple times as fast would it instead leaves a gap in the remaining space of the cycle. For example, the following will play the sound pattern "bd sn" only once but compressed into the first half of the cycle, i.e. twice as fast.
|
||||
* @name fastGap
|
||||
* @synonyms fastgap
|
||||
* @example
|
||||
* s("bd sd").fastGap(2)
|
||||
*/
|
||||
export const { fastGap, fastgap } = register(['fastGap', 'fastgap'], function (factor, pat) {
|
||||
// A bit fiddly, to drop zero-width queries at the start of the next cycle
|
||||
const qf = function (span) {
|
||||
@ -1502,10 +1551,14 @@ export const { fastGap, fastgap } = register(['fastGap', 'fastgap'], function (f
|
||||
return pat.withQuerySpanMaybe(qf).withHap(ef).splitQueries();
|
||||
});
|
||||
|
||||
// Similar to compress, but doesn't leave gaps, and the 'focus' can be
|
||||
// bigger than a cycle
|
||||
|
||||
/**
|
||||
* Similar to compress, but doesn't leave gaps, and the 'focus' can be bigger than a cycle
|
||||
* @example
|
||||
* s("bd hh sd hh").focus(1/4, 3/4)
|
||||
*/
|
||||
export const focus = register('focus', function (b, e, pat) {
|
||||
b = Fraction(b);
|
||||
e = Fraction(e);
|
||||
return pat._fast(Fraction(1).div(e.sub(b))).late(b.cyclePos());
|
||||
});
|
||||
|
||||
@ -1513,6 +1566,10 @@ export const { focusSpan, focusspan } = register(['focusSpan', 'focusspan'], fun
|
||||
return pat._focus(span.begin, span.end);
|
||||
});
|
||||
|
||||
/** The ply function repeats each event the given number of times.
|
||||
* @example
|
||||
* s("bd ~ sd cp").ply("<1 2 3>")
|
||||
*/
|
||||
export const ply = register('ply', function (factor, pat) {
|
||||
return pat.fmap((x) => pure(x)._fast(factor)).squeezeJoin();
|
||||
});
|
||||
@ -1521,6 +1578,7 @@ export const ply = register('ply', function (factor, pat) {
|
||||
* Speed up a pattern by the given factor. Used by "*" in mini notation.
|
||||
*
|
||||
* @name fast
|
||||
* @synonyms density
|
||||
* @memberof Pattern
|
||||
* @param {number | Pattern} factor speed up factor
|
||||
* @returns Pattern
|
||||
@ -1537,6 +1595,7 @@ export const { fast, density } = register(['fast', 'density'], function (factor,
|
||||
* Slow down a pattern over the given number of cycles. Like the "/" operator in mini notation.
|
||||
*
|
||||
* @name slow
|
||||
* @synonyms sparsity
|
||||
* @memberof Pattern
|
||||
* @param {number | Pattern} factor slow down factor
|
||||
* @returns Pattern
|
||||
@ -1547,12 +1606,22 @@ export const { slow, sparsity } = register(['slow', 'sparsity'], function (facto
|
||||
return pat._fast(Fraction(1).div(factor));
|
||||
});
|
||||
|
||||
// Should these really be in alphabetical order? a shame to split
|
||||
// fast/slow, inside/outside..
|
||||
/**
|
||||
* Carries out an operation 'inside' a cycle.
|
||||
* @example
|
||||
* "0 1 2 3 4 3 2 1".inside(4, rev).scale('C major').note()
|
||||
* // "0 1 2 3 4 3 2 1".slow(4).rev().fast(4).scale('C major').note()
|
||||
*/
|
||||
export const inside = register('inside', function (factor, f, pat) {
|
||||
return f(pat._slow(factor))._fast(factor);
|
||||
});
|
||||
|
||||
/**
|
||||
* Carries out an operation 'outside' a cycle.
|
||||
* @example
|
||||
* "<[0 1] 2 [3 4] 5>".outside(4, rev).scale('C major').note()
|
||||
* // "<[0 1] 2 [3 4] 5>".fast(4).rev().slow(4).scale('C major').note()
|
||||
*/
|
||||
export const outside = register('outside', function (factor, f, pat) {
|
||||
return f(pat._fast(factor))._slow(factor);
|
||||
});
|
||||
@ -1607,11 +1676,16 @@ export const { firstOf, every } = register(['firstOf', 'every'], function (n, fu
|
||||
* @example
|
||||
* "<c3 eb3 g3>".scale('C minor').apply(scaleTranspose("0,2,4")).note()
|
||||
*/
|
||||
// TODO: remove or dedupe with layer?
|
||||
export const apply = register('apply', function (func, pat) {
|
||||
return func(pat);
|
||||
});
|
||||
|
||||
// cpm = cycles per minute
|
||||
/**
|
||||
* Plays the pattern at the given cycles per minute.
|
||||
* @example
|
||||
* s("<bd sd>,hh*2").cpm(90) // = 90 bpm
|
||||
*/
|
||||
// TODO - global clock
|
||||
export const cpm = register('cpm', function (cpm, pat) {
|
||||
return pat._fast(cpm / 60);
|
||||
@ -1647,6 +1721,13 @@ export const late = register('late', function (offset, pat) {
|
||||
return pat._early(Fraction(0).sub(offset));
|
||||
});
|
||||
|
||||
/**
|
||||
* Plays a portion of a pattern, specified by the beginning and end of a time span. The new resulting pattern is played over the time period of the original pattern:
|
||||
*
|
||||
* @example
|
||||
* s("bd*2 hh*3 [sd bd]*2 perc").zoom(0.25, 0.75)
|
||||
* // s("hh*3 [sd bd]*2") // equivalent
|
||||
*/
|
||||
export const zoom = register('zoom', function (s, e, pat) {
|
||||
e = Fraction(e);
|
||||
s = Fraction(s);
|
||||
|
||||
@ -124,7 +124,8 @@ let sampleCache = { current: undefined };
|
||||
export const samples = async (sampleMap, baseUrl = sampleMap._base || '') => {
|
||||
if (typeof sampleMap === 'string') {
|
||||
if (sampleMap.startsWith('github:')) {
|
||||
const [_, path] = sampleMap.split('github:');
|
||||
let [_, path] = sampleMap.split('github:');
|
||||
path = path.endsWith('/') ? path.slice(0, -1) : path;
|
||||
sampleMap = `https://raw.githubusercontent.com/${path}/strudel.json`;
|
||||
}
|
||||
if (typeof fetch !== 'function') {
|
||||
|
||||
@ -822,6 +822,32 @@ exports[`runs examples > example "apply" example index 0 1`] = `
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "arp" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/2 | note:c ]",
|
||||
"[ 1/2 → 1/1 | note:c ]",
|
||||
"[ 1/2 → 1/1 | note:g ]",
|
||||
"[ 1/1 → 3/2 | note:eb ]",
|
||||
"[ 3/2 → 2/1 | note:c ]",
|
||||
"[ 3/2 → 2/1 | note:g ]",
|
||||
"[ 2/1 → 5/2 | note:c ]",
|
||||
"[ 5/2 → 3/1 | note:c ]",
|
||||
"[ 5/2 → 3/1 | note:g ]",
|
||||
"[ 3/1 → 7/2 | note:eb ]",
|
||||
"[ 7/2 → 4/1 | note:c ]",
|
||||
"[ 7/2 → 4/1 | note:g ]",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "arpWith" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/1 | note:g ]",
|
||||
"[ 1/1 → 2/1 | note:g ]",
|
||||
"[ 2/1 → 3/1 | note:ab ]",
|
||||
"[ 3/1 → 4/1 | note:ab ]",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "attack" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/2 | note:c3 attack:0 ]",
|
||||
@ -1063,6 +1089,19 @@ exports[`runs examples > example "coarse" example index 0 1`] = `
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "compress" example index 0 1`] = `
|
||||
[
|
||||
"[ 1/4 → 1/2 | s:bd ]",
|
||||
"[ 1/2 → 3/4 | s:sd ]",
|
||||
"[ 5/4 → 3/2 | s:bd ]",
|
||||
"[ 3/2 → 7/4 | s:sd ]",
|
||||
"[ 9/4 → 5/2 | s:bd ]",
|
||||
"[ 5/2 → 11/4 | s:sd ]",
|
||||
"[ 13/4 → 7/2 | s:bd ]",
|
||||
"[ 7/2 → 15/4 | s:sd ]",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "cosine" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/8 | note:Eb4 ]",
|
||||
@ -1132,6 +1171,31 @@ exports[`runs examples > example "cosine" example index 0 1`] = `
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "cpm" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 2/3 | s:bd ]",
|
||||
"[ 0/1 → 1/3 | s:hh ]",
|
||||
"[ 1/3 → 2/3 | s:hh ]",
|
||||
"[ (2/3 → 1/1) ⇝ 4/3 | s:sd ]",
|
||||
"[ 2/3 → 1/1 | s:hh ]",
|
||||
"[ 2/3 ⇜ (1/1 → 4/3) | s:sd ]",
|
||||
"[ 1/1 → 4/3 | s:hh ]",
|
||||
"[ 4/3 → 2/1 | s:bd ]",
|
||||
"[ 4/3 → 5/3 | s:hh ]",
|
||||
"[ 5/3 → 2/1 | s:hh ]",
|
||||
"[ 2/1 → 8/3 | s:sd ]",
|
||||
"[ 2/1 → 7/3 | s:hh ]",
|
||||
"[ 7/3 → 8/3 | s:hh ]",
|
||||
"[ (8/3 → 3/1) ⇝ 10/3 | s:bd ]",
|
||||
"[ 8/3 → 3/1 | s:hh ]",
|
||||
"[ 8/3 ⇜ (3/1 → 10/3) | s:bd ]",
|
||||
"[ 3/1 → 10/3 | s:hh ]",
|
||||
"[ 10/3 → 4/1 | s:sd ]",
|
||||
"[ 10/3 → 11/3 | s:hh ]",
|
||||
"[ 11/3 → 4/1 | s:hh ]",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "crush" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/2 | s:bd crush:16 ]",
|
||||
@ -1659,6 +1723,19 @@ exports[`runs examples > example "fast" example index 0 1`] = `
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "fastGap" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/4 | s:bd ]",
|
||||
"[ 1/4 → 1/2 | s:sd ]",
|
||||
"[ 1/1 → 5/4 | s:bd ]",
|
||||
"[ 5/4 → 3/2 | s:sd ]",
|
||||
"[ 2/1 → 9/4 | s:bd ]",
|
||||
"[ 9/4 → 5/2 | s:sd ]",
|
||||
"[ 3/1 → 13/4 | s:bd ]",
|
||||
"[ 13/4 → 7/2 | s:sd ]",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "fastcat" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/3 | e5 ]",
|
||||
@ -1722,6 +1799,43 @@ exports[`runs examples > example "floor" example index 0 1`] = `
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "focus" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/8 | s:sd ]",
|
||||
"[ 1/8 → 1/4 | s:hh ]",
|
||||
"[ 1/4 → 3/8 | s:bd ]",
|
||||
"[ 3/8 → 1/2 | s:hh ]",
|
||||
"[ 1/2 → 5/8 | s:sd ]",
|
||||
"[ 5/8 → 3/4 | s:hh ]",
|
||||
"[ 3/4 → 7/8 | s:bd ]",
|
||||
"[ 7/8 → 1/1 | s:hh ]",
|
||||
"[ 1/1 → 9/8 | s:sd ]",
|
||||
"[ 9/8 → 5/4 | s:hh ]",
|
||||
"[ 5/4 → 11/8 | s:bd ]",
|
||||
"[ 11/8 → 3/2 | s:hh ]",
|
||||
"[ 3/2 → 13/8 | s:sd ]",
|
||||
"[ 13/8 → 7/4 | s:hh ]",
|
||||
"[ 7/4 → 15/8 | s:bd ]",
|
||||
"[ 15/8 → 2/1 | s:hh ]",
|
||||
"[ 2/1 → 17/8 | s:sd ]",
|
||||
"[ 17/8 → 9/4 | s:hh ]",
|
||||
"[ 9/4 → 19/8 | s:bd ]",
|
||||
"[ 19/8 → 5/2 | s:hh ]",
|
||||
"[ 5/2 → 21/8 | s:sd ]",
|
||||
"[ 21/8 → 11/4 | s:hh ]",
|
||||
"[ 11/4 → 23/8 | s:bd ]",
|
||||
"[ 23/8 → 3/1 | s:hh ]",
|
||||
"[ 3/1 → 25/8 | s:sd ]",
|
||||
"[ 25/8 → 13/4 | s:hh ]",
|
||||
"[ 13/4 → 27/8 | s:bd ]",
|
||||
"[ 27/8 → 7/2 | s:hh ]",
|
||||
"[ 7/2 → 29/8 | s:sd ]",
|
||||
"[ 29/8 → 15/4 | s:hh ]",
|
||||
"[ 15/4 → 31/8 | s:bd ]",
|
||||
"[ 31/8 → 4/1 | s:hh ]",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "freq" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/4 | freq:220 s:superzow ]",
|
||||
@ -1863,6 +1977,43 @@ exports[`runs examples > example "hresonance" example index 0 1`] = `
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "inside" example index 0 1`] = `
|
||||
[
|
||||
"[ 1/8 → 1/4 | note:C3 ]",
|
||||
"[ 0/1 → 1/8 | note:D3 ]",
|
||||
"[ 3/8 → 1/2 | note:E3 ]",
|
||||
"[ 1/4 → 3/8 | note:F3 ]",
|
||||
"[ 5/8 → 3/4 | note:G3 ]",
|
||||
"[ 1/2 → 5/8 | note:F3 ]",
|
||||
"[ 7/8 → 1/1 | note:E3 ]",
|
||||
"[ 3/4 → 7/8 | note:D3 ]",
|
||||
"[ 9/8 → 5/4 | note:C3 ]",
|
||||
"[ 1/1 → 9/8 | note:D3 ]",
|
||||
"[ 11/8 → 3/2 | note:E3 ]",
|
||||
"[ 5/4 → 11/8 | note:F3 ]",
|
||||
"[ 13/8 → 7/4 | note:G3 ]",
|
||||
"[ 3/2 → 13/8 | note:F3 ]",
|
||||
"[ 15/8 → 2/1 | note:E3 ]",
|
||||
"[ 7/4 → 15/8 | note:D3 ]",
|
||||
"[ 17/8 → 9/4 | note:C3 ]",
|
||||
"[ 2/1 → 17/8 | note:D3 ]",
|
||||
"[ 19/8 → 5/2 | note:E3 ]",
|
||||
"[ 9/4 → 19/8 | note:F3 ]",
|
||||
"[ 21/8 → 11/4 | note:G3 ]",
|
||||
"[ 5/2 → 21/8 | note:F3 ]",
|
||||
"[ 23/8 → 3/1 | note:E3 ]",
|
||||
"[ 11/4 → 23/8 | note:D3 ]",
|
||||
"[ 25/8 → 13/4 | note:C3 ]",
|
||||
"[ 3/1 → 25/8 | note:D3 ]",
|
||||
"[ 27/8 → 7/2 | note:E3 ]",
|
||||
"[ 13/4 → 27/8 | note:F3 ]",
|
||||
"[ 29/8 → 15/4 | note:G3 ]",
|
||||
"[ 7/2 → 29/8 | note:F3 ]",
|
||||
"[ 31/8 → 4/1 | note:E3 ]",
|
||||
"[ 15/4 → 31/8 | note:D3 ]",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "irand" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/8 | note:Bb3 ]",
|
||||
@ -2099,6 +2250,20 @@ exports[`runs examples > example "lsize" example index 0 1`] = `
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "mask" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/2 | note:c ]",
|
||||
"[ 1/2 → 1/1 | note:eb ]",
|
||||
"[ 1/2 → 1/1 | note:g ]",
|
||||
"[ 1/1 → 3/2 | note:d ]",
|
||||
"[ 3/2 → 2/1 | note:eb ]",
|
||||
"[ 3/2 → 2/1 | note:g ]",
|
||||
"[ 3/1 → 7/2 | note:d ]",
|
||||
"[ 7/2 → 4/1 | note:eb ]",
|
||||
"[ 7/2 → 4/1 | note:g ]",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "mul" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/3 | freq:150 ]",
|
||||
@ -2304,6 +2469,17 @@ exports[`runs examples > example "orbit" example index 0 1`] = `
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "outside" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/1 | note:A3 ]",
|
||||
"[ 3/2 → 2/1 | note:F3 ]",
|
||||
"[ 1/1 → 3/2 | note:G3 ]",
|
||||
"[ 2/1 → 3/1 | note:E3 ]",
|
||||
"[ 7/2 → 4/1 | note:C3 ]",
|
||||
"[ 3/1 → 7/2 | note:D3 ]",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "pan" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/4 | s:bd pan:0.5 ]",
|
||||
@ -2354,6 +2530,32 @@ exports[`runs examples > example "perlin" example index 0 1`] = `
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "ply" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/4 | s:bd ]",
|
||||
"[ 1/2 → 3/4 | s:sd ]",
|
||||
"[ 3/4 → 1/1 | s:cp ]",
|
||||
"[ 1/1 → 9/8 | s:bd ]",
|
||||
"[ 9/8 → 5/4 | s:bd ]",
|
||||
"[ 3/2 → 13/8 | s:sd ]",
|
||||
"[ 13/8 → 7/4 | s:sd ]",
|
||||
"[ 7/4 → 15/8 | s:cp ]",
|
||||
"[ 15/8 → 2/1 | s:cp ]",
|
||||
"[ 2/1 → 25/12 | s:bd ]",
|
||||
"[ 25/12 → 13/6 | s:bd ]",
|
||||
"[ 13/6 → 9/4 | s:bd ]",
|
||||
"[ 5/2 → 31/12 | s:sd ]",
|
||||
"[ 31/12 → 8/3 | s:sd ]",
|
||||
"[ 8/3 → 11/4 | s:sd ]",
|
||||
"[ 11/4 → 17/6 | s:cp ]",
|
||||
"[ 17/6 → 35/12 | s:cp ]",
|
||||
"[ 35/12 → 3/1 | s:cp ]",
|
||||
"[ 3/1 → 13/4 | s:bd ]",
|
||||
"[ 7/2 → 15/4 | s:sd ]",
|
||||
"[ 15/4 → 4/1 | s:cp ]",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "polymeter" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/3 | note:c ]",
|
||||
@ -2469,6 +2671,64 @@ exports[`runs examples > example "range" example index 0 1`] = `
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "range2" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/2 | s:bd cutoff:1537.0125742738173 ]",
|
||||
"[ 1/2 → 1/1 | s:sd cutoff:1942.909649383465 ]",
|
||||
"[ 0/1 → 1/4 | s:hh cutoff:1396.3177415120963 ]",
|
||||
"[ 1/4 → 1/2 | s:hh cutoff:1666.6776747647016 ]",
|
||||
"[ 1/2 → 3/4 | s:hh cutoff:1873.602209226909 ]",
|
||||
"[ 3/4 → 1/1 | s:hh cutoff:1985.5889603024227 ]",
|
||||
"[ 1/1 → 3/2 | s:bd cutoff:1942.909649383465 ]",
|
||||
"[ 3/2 → 2/1 | s:sd cutoff:1537.0125742738173 ]",
|
||||
"[ 1/1 → 5/4 | s:hh cutoff:1985.5889603024227 ]",
|
||||
"[ 5/4 → 3/2 | s:hh cutoff:1873.602209226909 ]",
|
||||
"[ 3/2 → 7/4 | s:hh cutoff:1666.6776747647016 ]",
|
||||
"[ 7/4 → 2/1 | s:hh cutoff:1396.3177415120965 ]",
|
||||
"[ 2/1 → 5/2 | s:bd cutoff:962.9874257261828 ]",
|
||||
"[ 5/2 → 3/1 | s:sd cutoff:557.0903506165351 ]",
|
||||
"[ 2/1 → 9/4 | s:hh cutoff:1103.6822584879037 ]",
|
||||
"[ 9/4 → 5/2 | s:hh cutoff:833.3223252352985 ]",
|
||||
"[ 5/2 → 11/4 | s:hh cutoff:626.3977907730911 ]",
|
||||
"[ 11/4 → 3/1 | s:hh cutoff:514.4110396975773 ]",
|
||||
"[ 3/1 → 7/2 | s:bd cutoff:557.090350616535 ]",
|
||||
"[ 7/2 → 4/1 | s:sd cutoff:962.9874257261822 ]",
|
||||
"[ 3/1 → 13/4 | s:hh cutoff:514.4110396975772 ]",
|
||||
"[ 13/4 → 7/2 | s:hh cutoff:626.397790773091 ]",
|
||||
"[ 7/2 → 15/4 | s:hh cutoff:833.3223252352984 ]",
|
||||
"[ 15/4 → 4/1 | s:hh cutoff:1103.6822584879035 ]",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "rangex" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/2 | s:bd cutoff:1303.7646214531312 ]",
|
||||
"[ 1/2 → 1/1 | s:sd cutoff:1897.2102033890155 ]",
|
||||
"[ 0/1 → 1/4 | s:hh cutoff:1144.7958299590086 ]",
|
||||
"[ 1/4 → 1/2 | s:hh cutoff:1469.7494449054268 ]",
|
||||
"[ 1/2 → 3/4 | s:hh cutoff:1779.4971377133336 ]",
|
||||
"[ 3/4 → 1/1 | s:hh cutoff:1973.5393435463043 ]",
|
||||
"[ 1/1 → 3/2 | s:bd cutoff:1897.2102033890155 ]",
|
||||
"[ 3/2 → 2/1 | s:sd cutoff:1303.7646214531312 ]",
|
||||
"[ 1/1 → 5/4 | s:hh cutoff:1973.5393435463043 ]",
|
||||
"[ 5/4 → 3/2 | s:hh cutoff:1779.4971377133336 ]",
|
||||
"[ 3/2 → 7/4 | s:hh cutoff:1469.7494449054268 ]",
|
||||
"[ 7/4 → 2/1 | s:hh cutoff:1144.7958299590086 ]",
|
||||
"[ 2/1 → 5/2 | s:bd cutoff:767.0096147304824 ]",
|
||||
"[ 5/2 → 3/1 | s:sd cutoff:527.0897226958216 ]",
|
||||
"[ 2/1 → 9/4 | s:hh cutoff:873.5182063301246 ]",
|
||||
"[ 9/4 → 5/2 | s:hh cutoff:680.3880780266911 ]",
|
||||
"[ 5/2 → 11/4 | s:hh cutoff:561.9565094018676 ]",
|
||||
"[ 11/4 → 3/1 | s:hh cutoff:506.70385835991164 ]",
|
||||
"[ 3/1 → 7/2 | s:bd cutoff:527.0897226958216 ]",
|
||||
"[ 7/2 → 4/1 | s:sd cutoff:767.0096147304824 ]",
|
||||
"[ 3/1 → 13/4 | s:hh cutoff:506.7038583599112 ]",
|
||||
"[ 13/4 → 7/2 | s:hh cutoff:561.9565094018676 ]",
|
||||
"[ 7/2 → 15/4 | s:hh cutoff:680.3880780266911 ]",
|
||||
"[ 15/4 → 4/1 | s:hh cutoff:873.5182063301246 ]",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "rarely" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/8 | s:hh ]",
|
||||
@ -2527,6 +2787,35 @@ exports[`runs examples > example "release" example index 0 1`] = `
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "reset" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/2 | s:bd ]",
|
||||
"[ 1/2 → 1/1 | s:sd ]",
|
||||
"[ 0/1 → 1/4 | s:hh ]",
|
||||
"[ 1/4 → 1/2 | s:hh ]",
|
||||
"[ 1/2 → 3/4 | s:hh ]",
|
||||
"[ 3/4 → 1/1 | s:hh ]",
|
||||
"[ 1/1 → 3/2 | s:lt ]",
|
||||
"[ 3/2 → 2/1 | s:sd ]",
|
||||
"[ 1/1 → 5/4 | s:hh ]",
|
||||
"[ 5/4 → 3/2 | s:hh ]",
|
||||
"[ 3/2 → 7/4 | s:hh ]",
|
||||
"[ 7/4 → 2/1 | s:hh ]",
|
||||
"[ 2/1 → 5/2 | s:bd ]",
|
||||
"[ 5/2 → 3/1 | s:sd ]",
|
||||
"[ 2/1 → 9/4 | s:hh ]",
|
||||
"[ 9/4 → 5/2 | s:hh ]",
|
||||
"[ 5/2 → 11/4 | s:hh ]",
|
||||
"[ 11/4 → 3/1 | s:hh ]",
|
||||
"[ 3/1 → 25/8 | s:lt ]",
|
||||
"[ 3/1 → 25/8 | s:hh ]",
|
||||
"[ 27/8 → 7/2 | s:lt ]",
|
||||
"[ 27/8 → 7/2 | s:hh ]",
|
||||
"[ 15/4 → 31/8 | s:lt ]",
|
||||
"[ 15/4 → 31/8 | s:hh ]",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "resonance" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/2 | s:bd cutoff:2000 resonance:0 ]",
|
||||
@ -2556,6 +2845,35 @@ exports[`runs examples > example "resonance" example index 0 1`] = `
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "restart" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/2 | s:bd ]",
|
||||
"[ 1/2 → 1/1 | s:sd ]",
|
||||
"[ 0/1 → 1/4 | s:hh ]",
|
||||
"[ 1/4 → 1/2 | s:hh ]",
|
||||
"[ 1/2 → 3/4 | s:hh ]",
|
||||
"[ 3/4 → 1/1 | s:hh ]",
|
||||
"[ 1/1 → 3/2 | s:lt ]",
|
||||
"[ 3/2 → 2/1 | s:sd ]",
|
||||
"[ 1/1 → 5/4 | s:hh ]",
|
||||
"[ 5/4 → 3/2 | s:hh ]",
|
||||
"[ 3/2 → 7/4 | s:hh ]",
|
||||
"[ 7/4 → 2/1 | s:hh ]",
|
||||
"[ 2/1 → 5/2 | s:bd ]",
|
||||
"[ 5/2 → 3/1 | s:sd ]",
|
||||
"[ 2/1 → 9/4 | s:hh ]",
|
||||
"[ 9/4 → 5/2 | s:hh ]",
|
||||
"[ 5/2 → 11/4 | s:hh ]",
|
||||
"[ 11/4 → 3/1 | s:hh ]",
|
||||
"[ 3/1 → 25/8 | s:bd ]",
|
||||
"[ 3/1 → 25/8 | s:hh ]",
|
||||
"[ 27/8 → 7/2 | s:bd ]",
|
||||
"[ 27/8 → 7/2 | s:hh ]",
|
||||
"[ 15/4 → 31/8 | s:bd ]",
|
||||
"[ 15/4 → 31/8 | s:hh ]",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "rev" example index 0 1`] = `
|
||||
[
|
||||
"[ 3/4 → 1/1 | note:c3 ]",
|
||||
@ -3418,3 +3736,53 @@ exports[`runs examples > example "when" example index 0 1`] = `
|
||||
"[ 11/3 → 4/1 | note:50 ]",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "withValue" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/3 | 10 ]",
|
||||
"[ 1/3 → 2/3 | 11 ]",
|
||||
"[ 2/3 → 1/1 | 12 ]",
|
||||
"[ 1/1 → 4/3 | 10 ]",
|
||||
"[ 4/3 → 5/3 | 11 ]",
|
||||
"[ 5/3 → 2/1 | 12 ]",
|
||||
"[ 2/1 → 7/3 | 10 ]",
|
||||
"[ 7/3 → 8/3 | 11 ]",
|
||||
"[ 8/3 → 3/1 | 12 ]",
|
||||
"[ 3/1 → 10/3 | 10 ]",
|
||||
"[ 10/3 → 11/3 | 11 ]",
|
||||
"[ 11/3 → 4/1 | 12 ]",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "zoom" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/6 | s:hh ]",
|
||||
"[ 1/6 → 1/3 | s:hh ]",
|
||||
"[ 1/3 → 1/2 | s:hh ]",
|
||||
"[ 1/2 → 5/8 | s:sd ]",
|
||||
"[ 3/4 → 7/8 | s:sd ]",
|
||||
"[ 5/8 → 3/4 | s:bd ]",
|
||||
"[ 7/8 → 1/1 | s:bd ]",
|
||||
"[ 1/1 → 7/6 | s:hh ]",
|
||||
"[ 7/6 → 4/3 | s:hh ]",
|
||||
"[ 4/3 → 3/2 | s:hh ]",
|
||||
"[ 3/2 → 13/8 | s:sd ]",
|
||||
"[ 7/4 → 15/8 | s:sd ]",
|
||||
"[ 13/8 → 7/4 | s:bd ]",
|
||||
"[ 15/8 → 2/1 | s:bd ]",
|
||||
"[ 2/1 → 13/6 | s:hh ]",
|
||||
"[ 13/6 → 7/3 | s:hh ]",
|
||||
"[ 7/3 → 5/2 | s:hh ]",
|
||||
"[ 5/2 → 21/8 | s:sd ]",
|
||||
"[ 11/4 → 23/8 | s:sd ]",
|
||||
"[ 21/8 → 11/4 | s:bd ]",
|
||||
"[ 23/8 → 3/1 | s:bd ]",
|
||||
"[ 3/1 → 19/6 | s:hh ]",
|
||||
"[ 19/6 → 10/3 | s:hh ]",
|
||||
"[ 10/3 → 7/2 | s:hh ]",
|
||||
"[ 7/2 → 29/8 | s:sd ]",
|
||||
"[ 15/4 → 31/8 | s:sd ]",
|
||||
"[ 29/8 → 15/4 | s:bd ]",
|
||||
"[ 31/8 → 4/1 | s:bd ]",
|
||||
]
|
||||
`;
|
||||
|
||||
285
undocumented.json
Normal file
285
undocumented.json
Normal file
@ -0,0 +1,285 @@
|
||||
{
|
||||
"/home/felix/projects/strudel/packages/core/fraction.mjs": [
|
||||
"gcd"
|
||||
],
|
||||
"/home/felix/projects/strudel/packages/core/timespan.mjs": [
|
||||
"TimeSpan"
|
||||
],
|
||||
"/home/felix/projects/strudel/packages/core/hap.mjs": [
|
||||
"Hap"
|
||||
],
|
||||
"/home/felix/projects/strudel/packages/core/state.mjs": [
|
||||
"State"
|
||||
],
|
||||
"/home/felix/projects/strudel/packages/core/util.mjs": [
|
||||
"isNoteWithOctave",
|
||||
"isNote",
|
||||
"tokenizeNote",
|
||||
"toMidi",
|
||||
"fromMidi",
|
||||
"freqToMidi",
|
||||
"valueToMidi",
|
||||
"_mod",
|
||||
"getPlayableNoteValue",
|
||||
"getFrequency",
|
||||
"rotate",
|
||||
"pipe",
|
||||
"compose",
|
||||
"flatten",
|
||||
"id",
|
||||
"constant",
|
||||
"listRange",
|
||||
"curry",
|
||||
"parseNumeral",
|
||||
"mapArgs",
|
||||
"numeralArgs",
|
||||
"parseFractional",
|
||||
"fractionalArgs"
|
||||
],
|
||||
"/home/felix/projects/strudel/packages/core/value.mjs": [
|
||||
"unionWithObj",
|
||||
"valued",
|
||||
"Value",
|
||||
"map"
|
||||
],
|
||||
"/home/felix/projects/strudel/packages/core/drawLine.mjs": [],
|
||||
"/home/felix/projects/strudel/packages/core/logger.mjs": [
|
||||
"logKey",
|
||||
"logger"
|
||||
],
|
||||
"/home/felix/projects/strudel/packages/core/pattern.mjs": [
|
||||
"setStringParser",
|
||||
"isPattern",
|
||||
"reify",
|
||||
"set",
|
||||
"keep",
|
||||
"keepif",
|
||||
"mod",
|
||||
"pow",
|
||||
"band",
|
||||
"bor",
|
||||
"bxor",
|
||||
"blshift",
|
||||
"brshift",
|
||||
"lt",
|
||||
"gt",
|
||||
"lte",
|
||||
"gte",
|
||||
"eq",
|
||||
"eqt",
|
||||
"ne",
|
||||
"net",
|
||||
"and",
|
||||
"or",
|
||||
"func",
|
||||
"register",
|
||||
"compressSpan",
|
||||
"compressspan",
|
||||
"focusSpan",
|
||||
"focusspan",
|
||||
"zoomArc",
|
||||
"zoomarc",
|
||||
"linger",
|
||||
"segment",
|
||||
"invert",
|
||||
"inv",
|
||||
"hush",
|
||||
"palindrome",
|
||||
"juxBy",
|
||||
"juxby",
|
||||
"jux",
|
||||
"stutWith",
|
||||
"stutwith",
|
||||
"stut",
|
||||
"echowith",
|
||||
"iterback",
|
||||
"chunkback",
|
||||
"bypass",
|
||||
"duration",
|
||||
"color",
|
||||
"colour",
|
||||
"striate"
|
||||
],
|
||||
"/home/felix/projects/strudel/packages/core/controls.mjs": [],
|
||||
"/home/felix/projects/strudel/packages/core/euclid.mjs": [
|
||||
"euclidrot",
|
||||
"euclidLegatoRot"
|
||||
],
|
||||
"/home/felix/projects/strudel/packages/core/signal.mjs": [
|
||||
"steady",
|
||||
"signal",
|
||||
"isaw",
|
||||
"isaw2",
|
||||
"saw2",
|
||||
"sine2",
|
||||
"cosine2",
|
||||
"square2",
|
||||
"tri2",
|
||||
"time",
|
||||
"_brandBy",
|
||||
"brandBy",
|
||||
"brand",
|
||||
"_irand",
|
||||
"__chooseWith",
|
||||
"randcat",
|
||||
"wchoose",
|
||||
"wchooseCycles",
|
||||
"perlinWith",
|
||||
"degradeByWith",
|
||||
"undegrade"
|
||||
],
|
||||
"/home/felix/projects/strudel/packages/core/speak.mjs": [
|
||||
"speak"
|
||||
],
|
||||
"/home/felix/projects/strudel/packages/core/evaluate.mjs": [
|
||||
"evalScope",
|
||||
"evaluate"
|
||||
],
|
||||
"/home/felix/projects/strudel/packages/core/zyklus.mjs": [],
|
||||
"/home/felix/projects/strudel/packages/core/cyclist.mjs": [
|
||||
"Cyclist"
|
||||
],
|
||||
"/home/felix/projects/strudel/packages/core/time.mjs": [
|
||||
"getTime",
|
||||
"setTime"
|
||||
],
|
||||
"/home/felix/projects/strudel/packages/core/repl.mjs": [
|
||||
"repl"
|
||||
],
|
||||
"/home/felix/projects/strudel/packages/core/draw.mjs": [
|
||||
"getDrawContext",
|
||||
"cleanupDraw"
|
||||
],
|
||||
"/home/felix/projects/strudel/packages/core/animate.mjs": [
|
||||
"x",
|
||||
"y",
|
||||
"w",
|
||||
"h",
|
||||
"a",
|
||||
"r",
|
||||
"fill",
|
||||
"smear",
|
||||
"rescale",
|
||||
"moveXY",
|
||||
"zoomIn"
|
||||
],
|
||||
"/home/felix/projects/strudel/packages/core/pianoroll.mjs": [
|
||||
"pianoroll"
|
||||
],
|
||||
"/home/felix/projects/strudel/packages/core/ui.mjs": [
|
||||
"backgroundImage",
|
||||
"cleanupUi"
|
||||
],
|
||||
"/home/felix/projects/strudel/packages/core/gist.js": [],
|
||||
"/home/felix/projects/strudel/packages/core/index.mjs": [],
|
||||
"/home/felix/projects/strudel/packages/eval/shift-traverser/index.js": [],
|
||||
"/home/felix/projects/strudel/packages/eval/shapeshifter.mjs": [
|
||||
"addMiniLocations",
|
||||
"minifyStrings",
|
||||
"wrappedAsync",
|
||||
"shouldAddReturn"
|
||||
],
|
||||
"/home/felix/projects/strudel/packages/eval/evaluate.mjs": [
|
||||
"evaluate"
|
||||
],
|
||||
"/home/felix/projects/strudel/packages/eval/index.mjs": [],
|
||||
"/home/felix/projects/strudel/packages/midi/midi.mjs": [
|
||||
"WebMidi",
|
||||
"enableWebMidi"
|
||||
],
|
||||
"/home/felix/projects/strudel/packages/midi/index.mjs": [],
|
||||
"/home/felix/projects/strudel/packages/mini/krill-parser.js": [],
|
||||
"/home/felix/projects/strudel/packages/mini/mini.mjs": [
|
||||
"patternifyAST",
|
||||
"mini",
|
||||
"h",
|
||||
"minify"
|
||||
],
|
||||
"/home/felix/projects/strudel/packages/mini/index.mjs": [],
|
||||
"/home/felix/projects/strudel/packages/soundfonts/fontloader.mjs": [
|
||||
"getFontBufferSource",
|
||||
"getFontPitch"
|
||||
],
|
||||
"/home/felix/projects/strudel/packages/soundfonts/list.mjs": [
|
||||
"instruments",
|
||||
"drums",
|
||||
"instrumentNames"
|
||||
],
|
||||
"/home/felix/projects/strudel/packages/soundfonts/sfumato.mjs": [
|
||||
"loadSoundfont"
|
||||
],
|
||||
"/home/felix/projects/strudel/packages/soundfonts/index.mjs": [],
|
||||
"/home/felix/projects/strudel/packages/tonal/tonal.mjs": [],
|
||||
"/home/felix/projects/strudel/packages/tonal/voicings.mjs": [
|
||||
"voicingRegistry",
|
||||
"setVoicingRange"
|
||||
],
|
||||
"/home/felix/projects/strudel/packages/tonal/index.mjs": [],
|
||||
"/home/felix/projects/strudel/packages/tone/tone.mjs": [
|
||||
"Tone",
|
||||
"getDefaultSynth",
|
||||
"tone",
|
||||
"amsynth",
|
||||
"duosynth",
|
||||
"fmsynth",
|
||||
"membrane",
|
||||
"metal",
|
||||
"monosynth",
|
||||
"noise",
|
||||
"pluck",
|
||||
"polysynth",
|
||||
"sampler",
|
||||
"players",
|
||||
"synth",
|
||||
"vol",
|
||||
"lowpass",
|
||||
"highpass",
|
||||
"adsr",
|
||||
"out"
|
||||
],
|
||||
"/home/felix/projects/strudel/packages/tone/index.mjs": [],
|
||||
"/home/felix/projects/strudel/packages/transpiler/transpiler.mjs": [
|
||||
"transpiler"
|
||||
],
|
||||
"/home/felix/projects/strudel/packages/transpiler/index.mjs": [
|
||||
"evaluate"
|
||||
],
|
||||
"/home/felix/projects/strudel/packages/webaudio/feedbackdelay.mjs": [],
|
||||
"/home/felix/projects/strudel/packages/webaudio/reverb.mjs": [],
|
||||
"/home/felix/projects/strudel/packages/webaudio/sampler.mjs": [
|
||||
"getCachedBuffer",
|
||||
"getSampleBufferSource",
|
||||
"loadBuffer",
|
||||
"reverseBuffer",
|
||||
"getLoadedBuffer",
|
||||
"resetLoadedSamples",
|
||||
"getLoadedSamples"
|
||||
],
|
||||
"/home/felix/projects/strudel/packages/webaudio/vowel.mjs": [
|
||||
"vowelFormant"
|
||||
],
|
||||
"/home/felix/projects/strudel/packages/webaudio/webaudio.mjs": [
|
||||
"getAudioContext",
|
||||
"panic",
|
||||
"initAudio",
|
||||
"initAudioOnFirstClick",
|
||||
"webaudioOutput",
|
||||
"webaudioOutputTrigger"
|
||||
],
|
||||
"/home/felix/projects/strudel/packages/webaudio/index.mjs": [],
|
||||
"/home/felix/projects/strudel/packages/webdirt/webdirt.mjs": [
|
||||
"loadWebDirt"
|
||||
],
|
||||
"/home/felix/projects/strudel/packages/webdirt/index.mjs": [],
|
||||
"/home/felix/projects/strudel/packages/xen/xen.mjs": [
|
||||
"edo",
|
||||
"xen",
|
||||
"tuning"
|
||||
],
|
||||
"/home/felix/projects/strudel/packages/xen/tunejs.js": [],
|
||||
"/home/felix/projects/strudel/packages/xen/tune.mjs": [
|
||||
"tune"
|
||||
],
|
||||
"/home/felix/projects/strudel/packages/xen/index.mjs": [],
|
||||
"/home/felix/projects/strudel/index.mjs": []
|
||||
}
|
||||
82
undocumented.mjs
Normal file
82
undocumented.mjs
Normal file
@ -0,0 +1,82 @@
|
||||
import { readFile } from 'node:fs/promises';
|
||||
import { dirname, resolve } from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
import { parse } from 'acorn';
|
||||
import dependencyTree from 'dependency-tree';
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
function getExports(code) {
|
||||
// parse it with acorn
|
||||
let ast;
|
||||
try {
|
||||
ast = parse(code, {
|
||||
ecmaVersion: 11,
|
||||
sourceType: 'module',
|
||||
});
|
||||
} catch (err) {
|
||||
return [`acorn parse error: ${err.name}: ${err.messsage}`];
|
||||
}
|
||||
|
||||
// find all names exported in the file
|
||||
return ast.body
|
||||
.filter((node) => node?.type === 'ExportNamedDeclaration')
|
||||
.map((node) => {
|
||||
const { declaration } = node;
|
||||
if (!declaration) {
|
||||
// e.g. "export { Fraction, controls }"
|
||||
return [];
|
||||
}
|
||||
switch (declaration.type) {
|
||||
case 'VariableDeclaration':
|
||||
return declaration.declarations
|
||||
.map((d) => {
|
||||
switch (d.id.type) {
|
||||
case 'Identifier':
|
||||
return d.id.name;
|
||||
case 'ObjectPattern':
|
||||
return d.id.properties.map((p) => p.value.name);
|
||||
default:
|
||||
return 'unknown declaration: ' + declaration;
|
||||
}
|
||||
})
|
||||
.flat();
|
||||
default:
|
||||
// FunctionDeclaration, ClassDeclaration
|
||||
return declaration.id.name;
|
||||
}
|
||||
})
|
||||
.flat();
|
||||
}
|
||||
|
||||
function isDocumented(name, docs) {
|
||||
return docs.find(
|
||||
(d) => d.name === name || d.tags?.find((t) => t.title === 'synonyms' && t.value.split(', ').includes(name)),
|
||||
);
|
||||
}
|
||||
|
||||
async function getUndocumented(path, docs) {
|
||||
try {
|
||||
// load the code of pattern.mjs as a string
|
||||
const code = await readFile(path, 'utf8');
|
||||
return getExports(code).filter((name) => !isDocumented(name, docs));
|
||||
} catch (err) {
|
||||
return [`parse error: ${err.name}: ${err.message}`];
|
||||
}
|
||||
}
|
||||
|
||||
// read doc.json file
|
||||
const { docs } = JSON.parse(await readFile(resolve(__dirname, 'doc.json'), 'utf8'));
|
||||
|
||||
const paths = dependencyTree.toList({
|
||||
filename: 'index.mjs',
|
||||
// filename: 'packages/core/index.mjs',
|
||||
directory: resolve(__dirname),
|
||||
filter: (path) => !path.includes('node_modules'),
|
||||
});
|
||||
// const paths = ['../packages/core/pattern.mjs', '../packages/core/hap.mjs'].map((rel) => resolve(__dirname, rel));
|
||||
|
||||
const undocumented = Object.fromEntries(
|
||||
await Promise.all(paths.map(async (path) => [path, await getUndocumented(path, docs)])),
|
||||
);
|
||||
|
||||
console.log(JSON.stringify(undocumented, null, 2));
|
||||
@ -12,7 +12,7 @@ const { headings, githubEditUrl } = Astro.props as Props;
|
||||
const currentPage = Astro.url.pathname;
|
||||
---
|
||||
|
||||
<nav aria-labelledby="grid-right">
|
||||
<nav aria-labelledby="grid-right" class="w-64">
|
||||
<TableOfContents client:media="(min-width: 50em)" headings={headings} currentPage={currentPage} />
|
||||
<MoreMenu editHref={githubEditUrl} />
|
||||
</nav>
|
||||
|
||||
@ -62,6 +62,7 @@ export const SIDEBAR: Sidebar = {
|
||||
{ text: 'Control Parameters', link: 'functions/value-modifiers' },
|
||||
{ text: 'Signals', link: 'learn/signals' },
|
||||
{ text: 'Conditional Modifiers', link: 'learn/conditional-modifiers' },
|
||||
{ text: 'Accumulation', link: 'learn/accumulation' },
|
||||
{ text: 'Tonal Modifiers', link: 'learn/tonal' },
|
||||
],
|
||||
More: [
|
||||
@ -74,6 +75,7 @@ export const SIDEBAR: Sidebar = {
|
||||
{ text: 'REPL', link: 'technical-manual/repl' },
|
||||
{ text: 'Docs', link: 'technical-manual/docs' },
|
||||
{ text: 'Testing', link: 'technical-manual/testing' },
|
||||
// { text: 'Internals', link: 'technical-manual/internals' },
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
@ -2,12 +2,15 @@ import jsdoc from '../../../doc.json'; // doc.json is built with `npm run jsdoc-
|
||||
const docs = jsdoc.docs.reduce((acc, obj) => Object.assign(acc, { [obj.longname]: obj }), {});
|
||||
import { MiniRepl } from './MiniRepl';
|
||||
|
||||
const getTag = (title, item) => item.tags?.find((t) => t.title === title)?.text;
|
||||
|
||||
export function JsDoc({ name, h = 3, hideDescription }) {
|
||||
const item = docs[name];
|
||||
if (!item) {
|
||||
console.warn('Not found: ' + name);
|
||||
return <div />;
|
||||
}
|
||||
const synonyms = getTag('synonyms', item)?.split(', ') || [];
|
||||
const CustomHeading = `h${h}`;
|
||||
const description = item.description.replaceAll(/\{@link ([a-zA-Z\.]+)?#?([a-zA-Z]*)\}/g, (_, a, b) => {
|
||||
// console.log(_, 'a', a, 'b', b);
|
||||
@ -16,7 +19,16 @@ export function JsDoc({ name, h = 3, hideDescription }) {
|
||||
return (
|
||||
<>
|
||||
{!!h && <CustomHeading>{item.longname}</CustomHeading>}
|
||||
{!hideDescription && <div dangerouslySetInnerHTML={{ __html: description }} />}
|
||||
{!hideDescription && (
|
||||
<>
|
||||
{!!synonyms.length && (
|
||||
<span>
|
||||
Synonyms: <code>{synonyms.join(', ')}</code>
|
||||
</span>
|
||||
)}
|
||||
<div dangerouslySetInnerHTML={{ __html: description }} />
|
||||
</>
|
||||
)}
|
||||
<ul>
|
||||
{item.params?.map((param, i) => (
|
||||
<li key={i}>
|
||||
|
||||
@ -131,6 +131,14 @@ This group of functions allows to modify the value of events.
|
||||
|
||||
<JsDoc client:idle name="Pattern.range" h={0} />
|
||||
|
||||
## rangex
|
||||
|
||||
<JsDoc client:idle name="Pattern.rangex" h={0} />
|
||||
|
||||
## range2
|
||||
|
||||
<JsDoc client:idle name="Pattern.range2" h={0} />
|
||||
|
||||
# Custom Parameters
|
||||
|
||||
You can also create your own parameters:
|
||||
|
||||
30
website/src/pages/learn/accumulation.mdx
Normal file
30
website/src/pages/learn/accumulation.mdx
Normal file
@ -0,0 +1,30 @@
|
||||
---
|
||||
title: Accumulation Modifiers
|
||||
description: Strudel Tutorial - Coding syntax
|
||||
layout: ../../layouts/MainLayout.astro
|
||||
---
|
||||
|
||||
import { MiniRepl } from '../../docs/MiniRepl';
|
||||
import { JsDoc } from '../../docs/JsDoc';
|
||||
|
||||
# Accumulation Modifiers
|
||||
|
||||
## superimpose
|
||||
|
||||
<JsDoc client:idle name="Pattern.superimpose" h={0} />
|
||||
|
||||
## layer
|
||||
|
||||
<JsDoc client:idle name="Pattern.layer" h={0} />
|
||||
|
||||
## off
|
||||
|
||||
<JsDoc client:idle name="Pattern.off" h={0} />
|
||||
|
||||
## echo
|
||||
|
||||
<JsDoc client:idle name="Pattern.echo" h={0} />
|
||||
|
||||
## echoWith
|
||||
|
||||
<JsDoc client:idle name="Pattern.echoWith" h={0} />
|
||||
@ -73,7 +73,8 @@ You can also use the keyboard shortcut `cmd-/` to toggle comments on and off.
|
||||
Ok, so what about the content inside the quotes (e.g. `"a3 c#4 e4 a4"`)?
|
||||
In JavaScript, as in most programming languages, this content is referred to as being a [_string_](<https://en.wikipedia.org/wiki/String_(computer_science)>).
|
||||
A string is simply a sequence of individual characters.
|
||||
In TidalCycles, strings are used to write _patterns_ using the mini-notation, and you may hear the phrase _pattern string_ from time to time.
|
||||
In TidalCycles, double quoted strings are used to write _patterns_ using the mini-notation, and you may hear the phrase _pattern string_ from time to time.
|
||||
If you want to create a regular string and not a pattern, you can use single quotes, e.g. `'C minor'` will not be parsed as Mini Notation.
|
||||
|
||||
The good news is, that this covers 99% of the JavaScript syntax needed for Strudel!
|
||||
|
||||
|
||||
@ -8,36 +8,46 @@ import { JsDoc } from '../../docs/JsDoc';
|
||||
|
||||
# Conditional Modifiers
|
||||
|
||||
## every
|
||||
## lastOf
|
||||
|
||||
<JsDoc client:idle name="Pattern.every" h={0} />
|
||||
<JsDoc client:idle name="Pattern.lastOf" h={0} />
|
||||
|
||||
## firstOf
|
||||
|
||||
<JsDoc client:idle name="Pattern.firstOf" h={0} />
|
||||
|
||||
## when
|
||||
|
||||
<JsDoc client:idle name="Pattern.when" h={0} />
|
||||
|
||||
# Accumulation Modifiers
|
||||
## chunk
|
||||
|
||||
## stack
|
||||
<JsDoc client:idle name="Pattern.chunk" h={0} />
|
||||
|
||||
<JsDoc client:idle name="Pattern.stack" h={0} />
|
||||
### chunkBack
|
||||
|
||||
## superimpose
|
||||
<JsDoc client:idle name="Pattern.chunkBack" h={0} />
|
||||
|
||||
<JsDoc client:idle name="Pattern.superimpose" h={0} />
|
||||
## arp
|
||||
|
||||
## layer
|
||||
<JsDoc client:idle name="Pattern#arp" h={0} />
|
||||
|
||||
<JsDoc client:idle name="Pattern.layer" h={0} />
|
||||
## arpWith 🧪
|
||||
|
||||
## off
|
||||
<JsDoc client:idle name="Pattern#arpWith" h={0} />
|
||||
|
||||
<JsDoc client:idle name="Pattern.off" h={0} />
|
||||
## struct
|
||||
|
||||
## echo
|
||||
<JsDoc client:idle name="Pattern#struct" h={0} />
|
||||
|
||||
<JsDoc client:idle name="Pattern.echo" h={0} />
|
||||
## mask
|
||||
|
||||
## echoWith
|
||||
<JsDoc client:idle name="Pattern#mask" h={0} />
|
||||
|
||||
<JsDoc client:idle name="Pattern.echoWith" h={0} />
|
||||
## reset
|
||||
|
||||
<JsDoc client:idle name="Pattern#reset" h={0} />
|
||||
|
||||
## restart
|
||||
|
||||
<JsDoc client:idle name="Pattern#restart" h={0} />
|
||||
|
||||
@ -17,7 +17,7 @@ These are the equivalents used by the Mini Notation:
|
||||
| `cat(x, y)` | `"<x y>"` |
|
||||
| `seq(x, y)` | `"x y"` |
|
||||
| `stack(x, y)` | `"x,y"` |
|
||||
| `timeCat([3,x],[2,y])` | `"x@2 y@2"` |
|
||||
| `timeCat([3,x],[2,y])` | `"x@3 y@2"` |
|
||||
| `polymeter([a, b, c], [x, y])` | `"{a b c, x y}"` |
|
||||
| `polymeterSteps(2, x, y, z)` | `"{x y z}%2"` |
|
||||
| `silence` | `"~"` |
|
||||
|
||||
@ -39,11 +39,15 @@ Before diving deeper into the details, here is a flavour of how the mini-notatio
|
||||
]/16\`)`}
|
||||
/>
|
||||
|
||||
Note that the snippet above is enclosed in backticks (`), which allows you to write multi-line strings.
|
||||
## Mini Notation Format
|
||||
|
||||
The snippet above is enclosed in backticks (`), which allows you to write multi-line strings.
|
||||
|
||||
You can also use regular double quotes (`"`) for single line mini-notation, as we have done already.
|
||||
|
||||
# Sequences of events in a cycle
|
||||
If you do just want to get a regular string that is _not_ parsed as mini-notation, use single quotes (`'`).
|
||||
|
||||
## Sequences of events in a cycle
|
||||
|
||||
We can play more notes by separating them with spaces:
|
||||
|
||||
@ -64,7 +68,7 @@ Taking the two examples above, we have four and eight events respectively, and s
|
||||
This is perhaps counter-intuitive if you are used to adding notes in a sequencer or piano roll and the overall length increasing.
|
||||
But, it will begin to make sense as we go through more elements of mini-notation.
|
||||
|
||||
# Division
|
||||
## Division
|
||||
|
||||
We can slow the sequence down by enclosing it in brackets and dividing it by a number (`/2`):
|
||||
|
||||
@ -75,7 +79,7 @@ You can also use decimal numbers for any tempo you like (`/2.75`).
|
||||
|
||||
<MiniRepl client:idle tune={`note("[e5 b4 d5 c5]/2.75")`} />
|
||||
|
||||
# Angle Brackets
|
||||
## Angle Brackets
|
||||
|
||||
Using angle brackets `<>`, we can define the sequence length based on the number of events:
|
||||
|
||||
@ -93,7 +97,7 @@ The advantage of the angle brackets, is that we can add more events without need
|
||||
|
||||
This is more similar to traditional music sequencers and piano rolls, where adding a note increases the perceived overall duration.
|
||||
|
||||
# Multiplication
|
||||
## Multiplication
|
||||
|
||||
Contrary to division, a sequence can be sped up by multiplying it by a number using the asterisk symbol (`*`):
|
||||
|
||||
@ -107,7 +111,7 @@ As with divisions, multiplications can be decimal (`*2.75`):
|
||||
|
||||
Actually, this is not true, but this will be [fixed](https://github.com/tidalcycles/strudel/issues/314) :)
|
||||
|
||||
# Subdividing time with bracket nesting
|
||||
## Subdividing time with bracket nesting
|
||||
|
||||
To create more interesting rhythms, you can _nest_ or _enclose_ sequences (put sequences inside sequences) with brackets `[]`, like this:
|
||||
|
||||
@ -125,13 +129,13 @@ This is a very simple change to make, but it has profound consequences.
|
||||
Remember what we said earlier about how the cycles in tidal stay the same length, and the individual event lengths are divided up in this cycle?
|
||||
Well, what this means is that in TidalCycles, not only can you divide time any way you want, and you can also subdivide time any way you want!
|
||||
|
||||
# Rests
|
||||
## Rests
|
||||
|
||||
The "~" represents a rest, and will create silence between other events:
|
||||
|
||||
<MiniRepl client:idle tune={`note("[b4 [~ c5] d5 e5]")`} />
|
||||
|
||||
# Parallel / polyphony
|
||||
## Parallel / polyphony
|
||||
|
||||
Using commas, we can play chords.
|
||||
The following are the same:
|
||||
@ -143,7 +147,7 @@ But to play multiple chords in a sequence, we have to wrap them in brackets:
|
||||
|
||||
<MiniRepl client:idle tune={`note("<[g3,b3,e4] [a3,c3,e4] [b3,d3,f#4] [b3,e4,g4]>")`} />
|
||||
|
||||
# Elongation
|
||||
## Elongation
|
||||
|
||||
With the "@" symbol, we can specify temporal "weight" of a sequence child:
|
||||
|
||||
@ -151,7 +155,7 @@ With the "@" symbol, we can specify temporal "weight" of a sequence child:
|
||||
|
||||
Here, the first chord has a weight of 2, making it twice the length of the other chords. The default weight is 1.
|
||||
|
||||
# Replication
|
||||
## Replication
|
||||
|
||||
Using "!" we can repeat without speeding up:
|
||||
|
||||
@ -159,7 +163,7 @@ Using "!" we can repeat without speeding up:
|
||||
|
||||
In essence, the `x!n` is like a shortcut for `[x*n]@n`.
|
||||
|
||||
# Mini-notation review
|
||||
## Mini-notation review
|
||||
|
||||
To recap what we've learned so far, compare the following patterns:
|
||||
|
||||
@ -171,7 +175,7 @@ To recap what we've learned so far, compare the following patterns:
|
||||
<MiniRepl client:idle tune={`note("<[g3,b3,e4]@2 [a3,c3,e4] [b3,d3,f#4]>")`} />
|
||||
<MiniRepl client:idle tune={`note("<[g3,b3,e4]!2 [a3,c3,e4] [b3,d3,f#4]>")`} />
|
||||
|
||||
# Euclidian rhythms
|
||||
## Euclidian rhythms
|
||||
|
||||
Using round brackets after an event, we can create rhythmical sub-divisions based on three parameters: `beats`, `segments` and `offset`.
|
||||
This algorithm can be found in many different types of music software, and is often referred to as a [Euclidean rhythm](https://en.wikipedia.org/wiki/Euclidean_rhythm) sequencer, after computer scientist Godfriend Toussaint.
|
||||
@ -198,7 +202,7 @@ Note that since the example above does not use the third `offset` parameter, it
|
||||
|
||||
Let's look at those three parameters in detail.
|
||||
|
||||
## Beats
|
||||
### Beats
|
||||
|
||||
`beats`: the first parameter controls how may beats will be played.
|
||||
Compare these:
|
||||
@ -207,7 +211,7 @@ Compare these:
|
||||
<MiniRepl client:idle tune={`s("bd(5,8)")`} />
|
||||
<MiniRepl client:idle tune={`s("bd(7,8)")`} />
|
||||
|
||||
## Segments
|
||||
### Segments
|
||||
|
||||
`segments`: the second parameter controls the total amount of segments the beats will be distributed over:
|
||||
|
||||
@ -215,7 +219,7 @@ Compare these:
|
||||
<MiniRepl client:idle tune={`s("bd(3,8)")`} />
|
||||
<MiniRepl client:idle tune={`s("bd(3,13)")`} />
|
||||
|
||||
## Offsets
|
||||
### Offsets
|
||||
|
||||
`offset`: the third (optional) parameter controls the starting position for distributing the beats.
|
||||
We need a secondary rhythm to hear the difference:
|
||||
@ -224,7 +228,7 @@ We need a secondary rhythm to hear the difference:
|
||||
<MiniRepl client:idle tune={`s("bd(3,8,3), hh cp")`} />
|
||||
<MiniRepl client:idle tune={`s("bd(3,8,5), hh cp")`} />
|
||||
|
||||
# Mini-notation exercise
|
||||
## Mini-notation exercise
|
||||
|
||||
The most fun thing about the mini-notation, is that everything you have just learned can be combined in various ways!
|
||||
|
||||
|
||||
@ -38,10 +38,6 @@ Some of these have equivalent operators in the Mini Notation:
|
||||
|
||||
<JsDoc client:idle name="Pattern.legato" h={0} />
|
||||
|
||||
## struct
|
||||
|
||||
<JsDoc client:idle name="Pattern.struct" h={0} />
|
||||
|
||||
## euclid
|
||||
|
||||
<JsDoc client:idle name="Pattern.euclid" h={0} />
|
||||
@ -66,10 +62,30 @@ Some of these have equivalent operators in the Mini Notation:
|
||||
|
||||
<JsDoc client:idle name="Pattern.iterBack" h={0} />
|
||||
|
||||
## chunk
|
||||
## ply
|
||||
|
||||
<JsDoc client:idle name="Pattern.chunk" h={0} />
|
||||
<JsDoc client:idle name="ply" h={0} />
|
||||
|
||||
### chunkBack
|
||||
## compress
|
||||
|
||||
<JsDoc client:idle name="Pattern.chunkBack" h={0} />
|
||||
<JsDoc client:idle name="compress" h={0} />
|
||||
|
||||
## zoom
|
||||
|
||||
<JsDoc client:idle name="zoom" h={0} />
|
||||
|
||||
## fastGap
|
||||
|
||||
<JsDoc client:idle name="fastGap" h={0} />
|
||||
|
||||
## inside
|
||||
|
||||
<JsDoc client:idle name="inside" h={0} />
|
||||
|
||||
## outside
|
||||
|
||||
<JsDoc client:idle name="outside" h={0} />
|
||||
|
||||
## cpm
|
||||
|
||||
<JsDoc client:idle name="cpm" h={0} />
|
||||
|
||||
265
website/src/pages/technical-manual/internals.mdx
Normal file
265
website/src/pages/technical-manual/internals.mdx
Normal file
@ -0,0 +1,265 @@
|
||||
---
|
||||
title: Internals
|
||||
layout: ../../layouts/MainLayout.astro
|
||||
---
|
||||
|
||||
import { MiniRepl } from '../../docs/MiniRepl';
|
||||
import { JsDoc } from '../../docs/JsDoc';
|
||||
|
||||
# Internal Functions
|
||||
|
||||
These functions are more low level, probably not needed by the live coder.
|
||||
|
||||
# Haskell-style functor, applicative and monadic operations
|
||||
|
||||
## withValue
|
||||
|
||||
<JsDoc client:idle name="Pattern#withValue" h={0} />
|
||||
|
||||
## appWhole
|
||||
|
||||
<JsDoc client:idle name="Pattern#appWhole" h={0} />
|
||||
|
||||
## appBoth
|
||||
|
||||
<JsDoc client:idle name="Pattern#appBoth" h={0} />
|
||||
|
||||
## appLeft
|
||||
|
||||
<JsDoc client:idle name="Pattern#appLeft" h={0} />
|
||||
|
||||
## appRight
|
||||
|
||||
<JsDoc client:idle name="Pattern#appRight" h={0} />
|
||||
|
||||
## bindWhole
|
||||
|
||||
<JsDoc client:idle name="Pattern#bindWhole" h={0} />
|
||||
|
||||
## bind
|
||||
|
||||
<JsDoc client:idle name="Pattern#bind" h={0} />
|
||||
|
||||
## join
|
||||
|
||||
<JsDoc client:idle name="Pattern#join" h={0} />
|
||||
|
||||
## outerBind
|
||||
|
||||
<JsDoc client:idle name="Pattern#outerBind" h={0} />
|
||||
|
||||
## outerJoin
|
||||
|
||||
<JsDoc client:idle name="Pattern#outerJoin" h={0} />
|
||||
|
||||
## innerBind
|
||||
|
||||
<JsDoc client:idle name="Pattern#innerBind" h={0} />
|
||||
|
||||
## innerJoin
|
||||
|
||||
<JsDoc client:idle name="Pattern#innerJoin" h={0} />
|
||||
|
||||
## trigJoin
|
||||
|
||||
<JsDoc client:idle name="Pattern#trigJoin" h={0} />
|
||||
|
||||
## trigzeroJoin
|
||||
|
||||
<JsDoc client:idle name="Pattern#trigzeroJoin" h={0} />
|
||||
|
||||
## squeezeJoin
|
||||
|
||||
<JsDoc client:idle name="Pattern#squeezeJoin" h={0} />
|
||||
|
||||
## squeezeBind
|
||||
|
||||
<JsDoc client:idle name="Pattern#squeezeBind" h={0} />
|
||||
|
||||
# Utility methods mainly for internal use
|
||||
|
||||
## queryArc
|
||||
|
||||
<JsDoc client:idle name="Pattern#queryArc" h={0} />
|
||||
|
||||
## splitQueries
|
||||
|
||||
<JsDoc client:idle name="Pattern#splitQueries" h={0} />
|
||||
|
||||
## withQuerySpan
|
||||
|
||||
<JsDoc client:idle name="Pattern#withQuerySpan" h={0} />
|
||||
|
||||
## withQuerySpanMaybe
|
||||
|
||||
<JsDoc client:idle name="Pattern#withQuerySpanMaybe" h={0} />
|
||||
|
||||
## withQueryTime
|
||||
|
||||
<JsDoc client:idle name="Pattern#withQueryTime" h={0} />
|
||||
|
||||
## withHapSpan
|
||||
|
||||
<JsDoc client:idle name="Pattern#withHapSpan" h={0} />
|
||||
|
||||
## withHapTime
|
||||
|
||||
<JsDoc client:idle name="Pattern#withHapTime" h={0} />
|
||||
|
||||
## withHaps
|
||||
|
||||
<JsDoc client:idle name="Pattern#withHaps" h={0} />
|
||||
|
||||
## withHap
|
||||
|
||||
<JsDoc client:idle name="Pattern#withHap" h={0} />
|
||||
|
||||
## setContext
|
||||
|
||||
<JsDoc client:idle name="Pattern#setContext" h={0} />
|
||||
|
||||
## withContext
|
||||
|
||||
<JsDoc client:idle name="Pattern#setContext" h={0} />
|
||||
|
||||
## stripContext
|
||||
|
||||
<JsDoc client:idle name="Pattern#stripContext" h={0} />
|
||||
|
||||
## withLocation
|
||||
|
||||
<JsDoc client:idle name="Pattern#withLocation" h={0} />
|
||||
|
||||
## withMiniLocation
|
||||
|
||||
<JsDoc client:idle name="Pattern#withMiniLocation" h={0} />
|
||||
|
||||
## filterHaps
|
||||
|
||||
<JsDoc client:idle name="Pattern#filterHaps" h={0} />
|
||||
|
||||
## filterValues
|
||||
|
||||
<JsDoc client:idle name="Pattern#filterValues" h={0} />
|
||||
|
||||
## removeUndefineds
|
||||
|
||||
<JsDoc client:idle name="Pattern#filterValues" h={0} />
|
||||
|
||||
## onsetsOnly
|
||||
|
||||
<JsDoc client:idle name="Pattern#onsetsOnly" h={0} />
|
||||
|
||||
## discreteOnly
|
||||
|
||||
<JsDoc client:idle name="Pattern#discreteOnly" h={0} />
|
||||
|
||||
## defragmentHaps
|
||||
|
||||
<JsDoc client:idle name="Pattern#defragmentHaps" h={0} />
|
||||
|
||||
## firstCycle
|
||||
|
||||
<JsDoc client:idle name="Pattern#firstCycle" h={0} />
|
||||
|
||||
## firstCycleValues
|
||||
|
||||
<JsDoc client:idle name="Pattern#firstCycleValues" h={0} />
|
||||
|
||||
## showFirstCycle
|
||||
|
||||
<JsDoc client:idle name="Pattern#showFirstCycle" h={0} />
|
||||
|
||||
## sortHapsByPart
|
||||
|
||||
<JsDoc client:idle name="Pattern#sortHapsByPart" h={0} />
|
||||
|
||||
## asNumber
|
||||
|
||||
<JsDoc client:idle name="Pattern#sortHapsByPart" h={0} />
|
||||
|
||||
# Operators
|
||||
|
||||
- \_opIn
|
||||
- \_opOut
|
||||
- \_opMix
|
||||
- \_opSqueeze
|
||||
- \_opSqueezeOut
|
||||
- \_opTrig
|
||||
- \_opTrigzero
|
||||
|
||||
# Other
|
||||
|
||||
## onTrigger
|
||||
|
||||
<JsDoc client:idle name="Pattern#onTrigger" h={0} />
|
||||
|
||||
## log
|
||||
|
||||
<JsDoc client:idle name="Pattern#log" h={0} />
|
||||
|
||||
## logValues
|
||||
|
||||
<JsDoc client:idle name="Pattern#logValues" h={0} />
|
||||
|
||||
## drawLine
|
||||
|
||||
<JsDoc client:idle name="Pattern#drawLine" h={0} />
|
||||
|
||||
## collect
|
||||
|
||||
# Functions
|
||||
|
||||
## groupHapsBy
|
||||
|
||||
<JsDoc client:idle name="groupHapsBy" h={0} />
|
||||
|
||||
## pure
|
||||
|
||||
<JsDoc client:idle name="pure" h={0} />
|
||||
|
||||
## reify
|
||||
|
||||
<JsDoc client:idle name="reify" h={0} />
|
||||
|
||||
## slowcatPrime
|
||||
|
||||
<JsDoc client:idle name="slowcatPrime" h={0} />
|
||||
|
||||
## isPattern
|
||||
|
||||
<JsDoc client:idle name="isPattern" h={0} />
|
||||
|
||||
## register
|
||||
|
||||
<JsDoc client:idle name="register" h={0} />
|
||||
|
||||
## toBipolar
|
||||
|
||||
<JsDoc client:idle name="toBipolar" h={0} />
|
||||
|
||||
## fromBipolar
|
||||
|
||||
<JsDoc client:idle name="fromBipolar" h={0} />
|
||||
|
||||
## compressSpan
|
||||
|
||||
<JsDoc client:idle name="compressSpan" h={0} />
|
||||
|
||||
## focus
|
||||
|
||||
<JsDoc client:idle name="focus" h={0} />
|
||||
|
||||
## focusSpan
|
||||
|
||||
## \_composeOp
|
||||
|
||||
# Composers
|
||||
|
||||
```
|
||||
set keep keepif add sub mul div mod pow band bor bxor blshift brshift lt gt lte gte eq eqt ne net and or func
|
||||
```
|
||||
|
||||
```
|
||||
In Out Mix Squeeze SqueezeOut Trig Trigzero
|
||||
```
|
||||
@ -857,7 +857,7 @@ export const arpoon = `// licensed with CC BY-NC-SA 4.0 https://creativecommons.
|
||||
await samples('github:tidalcycles/Dirt-Samples/master')
|
||||
|
||||
"<<Am7 C^7> C7 F^7 [Fm7 E7b9]>".voicings('lefthand')
|
||||
.arp("[0,3] 2 [1,3] 2".fast(3)).legato(2)
|
||||
.arp("[0,3] 2 [1,3] 2".fast(3).lastOf(4, fast(2))).legato(2)
|
||||
.add(perlin.range(0,0.2)).sub("<0 -12>/8")
|
||||
.note().cutoff(perlin.range(500,4000)).resonance(12)
|
||||
.gain("<.5 .8>*16")
|
||||
@ -867,5 +867,5 @@ await samples('github:tidalcycles/Dirt-Samples/master')
|
||||
.s('piano').clip(1)
|
||||
.stack("<<A1 C2>!2 F2 [F2 E2]>".add.out("0 -5".fast(2)).add("0,.12").note().s('sawtooth').clip(1).cutoff(300))
|
||||
.slow(4)
|
||||
.stack(s("bd*4, [~ [hh hh? hh?]]*2,~ [sd ~ [sd:2? bd?]]").arp("0|1").bank('RolandTR909').gain(.5).slow(2))
|
||||
.stack(s("bd*4, [~ [hh hh? hh?]]*2,~ [sd ~ [sd:2? bd?]]").bank('RolandTR909').gain(.5).slow(2))
|
||||
`;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user