mirror of
https://github.com/eliasstepanik/strudel-docker.git
synced 2026-01-13 22:58:34 +00:00
Merge pull request #1125 from tidalcycles/viz-doc
doc: visual functions + refactor onPaint
This commit is contained in:
commit
364f511a7c
@ -140,27 +140,25 @@ export class StrudelMirror {
|
||||
this.root = root;
|
||||
this.miniLocations = [];
|
||||
this.widgets = [];
|
||||
this.painters = [];
|
||||
this.drawTime = drawTime;
|
||||
this.drawContext = drawContext;
|
||||
this.onDraw = onDraw || this.draw;
|
||||
this.id = id || s4();
|
||||
|
||||
this.drawer = new Drawer((haps, time) => {
|
||||
this.drawer = new Drawer((haps, time, _, painters) => {
|
||||
const currentFrame = haps.filter((hap) => hap.isActive(time));
|
||||
this.highlight(currentFrame, time);
|
||||
this.onDraw(haps, time, this.painters);
|
||||
this.onDraw(haps, time, painters);
|
||||
}, drawTime);
|
||||
|
||||
this.prebaked = prebake();
|
||||
autodraw && this.drawFirstFrame();
|
||||
|
||||
this.repl = repl({
|
||||
...replOptions,
|
||||
id,
|
||||
onToggle: (started) => {
|
||||
replOptions?.onToggle?.(started);
|
||||
if (started) {
|
||||
this.adjustDrawTime();
|
||||
this.drawer.start(this.repl.scheduler);
|
||||
// stop other repls when this one is started
|
||||
document.dispatchEvent(
|
||||
@ -171,20 +169,11 @@ export class StrudelMirror {
|
||||
} else {
|
||||
this.drawer.stop();
|
||||
updateMiniLocations(this.editor, []);
|
||||
cleanupDraw(false);
|
||||
cleanupDraw(true, id);
|
||||
}
|
||||
},
|
||||
beforeEval: async () => {
|
||||
cleanupDraw();
|
||||
this.painters = [];
|
||||
const self = this;
|
||||
// this is similar to repl.mjs > injectPatternMethods
|
||||
// maybe there is a solution without prototype hacking, but hey, it works
|
||||
// we need to do this befor every eval to make sure it works with multiple StrudelMirror's side by side
|
||||
Pattern.prototype.onPaint = function (onPaint) {
|
||||
self.painters.push(onPaint);
|
||||
return this;
|
||||
};
|
||||
cleanupDraw(true, id);
|
||||
await this.prebaked;
|
||||
await replOptions?.beforeEval?.();
|
||||
},
|
||||
@ -198,8 +187,11 @@ export class StrudelMirror {
|
||||
updateWidgets(this.editor, widgets);
|
||||
updateMiniLocations(this.editor, this.miniLocations);
|
||||
replOptions?.afterEval?.(options);
|
||||
this.adjustDrawTime();
|
||||
this.drawer.invalidate();
|
||||
// if no painters are set (.onPaint was not called), then we only need the present moment (for highlighting)
|
||||
const drawTime = options.pattern.getPainters().length ? this.drawTime : [0, 0];
|
||||
this.drawer.setDrawTime(drawTime);
|
||||
// invalidate drawer after we've set the appropriate drawTime
|
||||
this.drawer.invalidate(this.repl.scheduler);
|
||||
},
|
||||
});
|
||||
this.editor = initEditor({
|
||||
@ -234,13 +226,8 @@ export class StrudelMirror {
|
||||
};
|
||||
document.addEventListener('start-repl', this.onStartRepl);
|
||||
}
|
||||
// adjusts draw time depending on if there are painters
|
||||
adjustDrawTime() {
|
||||
// when no painters are set, [0,0] is enough (just highlighting)
|
||||
this.drawer.setDrawTime(this.painters.length ? this.drawTime : [0, 0]);
|
||||
}
|
||||
draw(haps, time) {
|
||||
this.painters?.forEach((painter) => painter(this.drawContext, time, haps, this.drawTime));
|
||||
draw(haps, time, painters) {
|
||||
painters?.forEach((painter) => painter(this.drawContext, time, haps, this.drawTime));
|
||||
}
|
||||
async drawFirstFrame() {
|
||||
if (!this.onDraw) {
|
||||
@ -252,7 +239,7 @@ export class StrudelMirror {
|
||||
await this.repl.evaluate(this.code, false);
|
||||
this.drawer.invalidate(this.repl.scheduler, -0.001);
|
||||
// draw at -0.001 to avoid haps at 0 to be visualized as active
|
||||
this.onDraw?.(this.drawer.visibleHaps, -0.001, this.painters);
|
||||
this.onDraw?.(this.drawer.visibleHaps, -0.001, this.drawer.painters);
|
||||
} catch (err) {
|
||||
console.warn('first frame could not be painted');
|
||||
}
|
||||
|
||||
2
packages/codemirror/themes/algoboy.mjs
vendored
2
packages/codemirror/themes/algoboy.mjs
vendored
@ -12,7 +12,7 @@ export const settings = {
|
||||
gutterBackground: 'transparent',
|
||||
gutterForeground: '#0f380f',
|
||||
light: true,
|
||||
customStyle: '.cm-line { line-height: 1 }',
|
||||
// customStyle: '.cm-line { line-height: 1 }',
|
||||
};
|
||||
export default createTheme({
|
||||
theme: 'light',
|
||||
|
||||
2
packages/codemirror/themes/teletext.mjs
vendored
2
packages/codemirror/themes/teletext.mjs
vendored
@ -17,7 +17,7 @@ export const settings = {
|
||||
lineBackground: '#00000040',
|
||||
gutterBackground: 'transparent',
|
||||
gutterForeground: '#8a919966',
|
||||
customStyle: '.cm-line { line-height: 1 }',
|
||||
// customStyle: '.cm-line { line-height: 1 }',
|
||||
};
|
||||
|
||||
let punctuation = colorD;
|
||||
|
||||
@ -191,7 +191,7 @@ export const { attack, att } = registerControl('attack', 'att');
|
||||
* note("c e g b g e")
|
||||
* .fm(4)
|
||||
* .fmh("<1 2 1.5 1.61>")
|
||||
* .scope()
|
||||
* ._scope()
|
||||
*
|
||||
*/
|
||||
export const { fmh } = registerControl(['fmh', 'fmi'], 'fmh');
|
||||
@ -205,7 +205,7 @@ export const { fmh } = registerControl(['fmh', 'fmi'], 'fmh');
|
||||
* @example
|
||||
* note("c e g b g e")
|
||||
* .fm("<0 1 2 8 32>")
|
||||
* .scope()
|
||||
* ._scope()
|
||||
*
|
||||
*/
|
||||
export const { fmi, fm } = registerControl(['fmi', 'fmh'], 'fm');
|
||||
@ -221,7 +221,7 @@ export const { fmi, fm } = registerControl(['fmi', 'fmh'], 'fm');
|
||||
* .fmdecay(.2)
|
||||
* .fmsustain(0)
|
||||
* .fmenv("<exp lin>")
|
||||
* .scope()
|
||||
* ._scope()
|
||||
*
|
||||
*/
|
||||
export const { fmenv } = registerControl('fmenv');
|
||||
@ -234,7 +234,7 @@ export const { fmenv } = registerControl('fmenv');
|
||||
* note("c e g b g e")
|
||||
* .fm(4)
|
||||
* .fmattack("<0 .05 .1 .2>")
|
||||
* .scope()
|
||||
* ._scope()
|
||||
*
|
||||
*/
|
||||
export const { fmattack } = registerControl('fmattack');
|
||||
@ -248,7 +248,7 @@ export const { fmattack } = registerControl('fmattack');
|
||||
* .fm(4)
|
||||
* .fmdecay("<.01 .05 .1 .2>")
|
||||
* .fmsustain(.4)
|
||||
* .scope()
|
||||
* ._scope()
|
||||
*
|
||||
*/
|
||||
export const { fmdecay } = registerControl('fmdecay');
|
||||
@ -262,7 +262,7 @@ export const { fmdecay } = registerControl('fmdecay');
|
||||
* .fm(4)
|
||||
* .fmdecay(.1)
|
||||
* .fmsustain("<1 .75 .5 0>")
|
||||
* .scope()
|
||||
* ._scope()
|
||||
*
|
||||
*/
|
||||
export const { fmsustain } = registerControl('fmsustain');
|
||||
@ -392,7 +392,7 @@ export const { loop } = registerControl('loop');
|
||||
* @synonyms loopb
|
||||
* @example
|
||||
* s("space").loop(1)
|
||||
* .loopBegin("<0 .125 .25>").scope()
|
||||
* .loopBegin("<0 .125 .25>")._scope()
|
||||
*/
|
||||
export const { loopBegin, loopb } = registerControl('loopBegin', 'loopb');
|
||||
/**
|
||||
@ -405,7 +405,7 @@ export const { loopBegin, loopb } = registerControl('loopBegin', 'loopb');
|
||||
* @synonyms loope
|
||||
* @example
|
||||
* s("space").loop(1)
|
||||
* .loopEnd("<1 .75 .5 .25>").scope()
|
||||
* .loopEnd("<1 .75 .5 .25>")._scope()
|
||||
*/
|
||||
export const { loopEnd, loope } = registerControl('loopEnd', 'loope');
|
||||
/**
|
||||
@ -800,10 +800,12 @@ export const { fanchor } = registerControl('fanchor');
|
||||
* @example
|
||||
* note("a e")
|
||||
* .vib("<.5 1 2 4 8 16>")
|
||||
* ._scope()
|
||||
* @example
|
||||
* // change the modulation depth with ":"
|
||||
* note("a e")
|
||||
* .vib("<.5 1 2 4 8 16>:12")
|
||||
* ._scope()
|
||||
*/
|
||||
export const { vib, vibrato, v } = registerControl(['vib', 'vibmod'], 'vibrato', 'v');
|
||||
/**
|
||||
@ -824,10 +826,12 @@ export const { noise } = registerControl('noise');
|
||||
* @example
|
||||
* note("a e").vib(4)
|
||||
* .vibmod("<.25 .5 1 2 12>")
|
||||
* ._scope()
|
||||
* @example
|
||||
* // change the vibrato frequency with ":"
|
||||
* note("a e")
|
||||
* .vibmod("<.25 .5 1 2 12>:8")
|
||||
* ._scope()
|
||||
*/
|
||||
export const { vibmod, vmod } = registerControl(['vibmod', 'vib'], 'vmod');
|
||||
export const { hcutoff, hpf, hp } = registerControl(['hcutoff', 'hresonance', 'hpenv'], 'hpf', 'hp');
|
||||
|
||||
@ -8,8 +8,19 @@ import createClock from './zyklus.mjs';
|
||||
import { logger } from './logger.mjs';
|
||||
|
||||
export class Cyclist {
|
||||
constructor({ interval, onTrigger, onToggle, onError, getTime, latency = 0.1, setInterval, clearInterval }) {
|
||||
constructor({
|
||||
interval,
|
||||
onTrigger,
|
||||
onToggle,
|
||||
onError,
|
||||
getTime,
|
||||
latency = 0.1,
|
||||
setInterval,
|
||||
clearInterval,
|
||||
beforeStart,
|
||||
}) {
|
||||
this.started = false;
|
||||
this.beforeStart = beforeStart;
|
||||
this.cps = 0.5;
|
||||
this.num_ticks_since_cps_change = 0;
|
||||
this.lastTick = 0; // absolute time when last tick (clock callback) happened
|
||||
@ -82,7 +93,8 @@ export class Cyclist {
|
||||
this.started = v;
|
||||
this.onToggle?.(v);
|
||||
}
|
||||
start() {
|
||||
async start() {
|
||||
await this.beforeStart?.();
|
||||
this.num_ticks_since_cps_change = 0;
|
||||
this.num_cycles_at_cps_change = 0;
|
||||
if (!this.pattern) {
|
||||
@ -103,10 +115,10 @@ export class Cyclist {
|
||||
this.lastEnd = 0;
|
||||
this.setStarted(false);
|
||||
}
|
||||
setPattern(pat, autostart = false) {
|
||||
async setPattern(pat, autostart = false) {
|
||||
this.pattern = pat;
|
||||
if (autostart && !this.started) {
|
||||
this.start();
|
||||
await this.start();
|
||||
}
|
||||
}
|
||||
setCps(cps = 0.5) {
|
||||
|
||||
@ -37,11 +37,11 @@ function safeEval(str, options = {}) {
|
||||
return Function(body)();
|
||||
}
|
||||
|
||||
export const evaluate = async (code, transpiler) => {
|
||||
export const evaluate = async (code, transpiler, transpilerOptions) => {
|
||||
let meta = {};
|
||||
if (transpiler) {
|
||||
// transform syntactically correct js code to semantically usable code
|
||||
const transpiled = transpiler(code);
|
||||
const transpiled = transpiler(code, transpilerOptions);
|
||||
code = transpiled.output;
|
||||
meta = transpiled;
|
||||
}
|
||||
|
||||
@ -94,6 +94,14 @@ export class Pattern {
|
||||
return result;
|
||||
}
|
||||
|
||||
// runs func on query state
|
||||
withState(func) {
|
||||
return this.withHaps((haps, state) => {
|
||||
func(state);
|
||||
return haps;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* see `withValue`
|
||||
* @noAutocomplete
|
||||
@ -2523,7 +2531,7 @@ export function _polymeterListSteps(steps, ...args) {
|
||||
* @param {any[]} patterns one or more patterns
|
||||
* @example
|
||||
* // the same as "{c d, e f g}%4"
|
||||
* s_polymeterSteps(4, "c d", "e f g")
|
||||
* s_polymeterSteps(4, "c d", "e f g").note()
|
||||
*/
|
||||
export function s_polymeterSteps(steps, ...args) {
|
||||
if (args.length == 0) {
|
||||
@ -2541,8 +2549,8 @@ export function s_polymeterSteps(steps, ...args) {
|
||||
* *EXPERIMENTAL* - Combines the given lists of patterns with the same pulse, creating polymeters when different sized sequences are used.
|
||||
* @synonyms pm
|
||||
* @example
|
||||
* // The same as "{c eb g, c2 g2}"
|
||||
* s_polymeter("c eb g", "c2 g2")
|
||||
* // The same as note("{c eb g, c2 g2}")
|
||||
* s_polymeter("c eb g", "c2 g2").note()
|
||||
*
|
||||
*/
|
||||
export function s_polymeter(...args) {
|
||||
@ -2571,6 +2579,8 @@ export function s_polymeter(...args) {
|
||||
/** Sequences patterns like `seq`, but each pattern has a length, relative to the whole.
|
||||
* This length can either be provided as a [length, pattern] pair, or inferred from
|
||||
* the pattern's 'tactus', generally inferred by the mininotation. Has the alias `timecat`.
|
||||
* @name s_cat
|
||||
* @synonyms timeCat, timecat
|
||||
* @return {Pattern}
|
||||
* @example
|
||||
* s_cat([3,"e3"],[1, "g3"]).note()
|
||||
|
||||
@ -10,6 +10,7 @@ export function repl({
|
||||
defaultOutput,
|
||||
onEvalError,
|
||||
beforeEval,
|
||||
beforeStart,
|
||||
afterEval,
|
||||
getTime,
|
||||
transpiler,
|
||||
@ -19,6 +20,7 @@ export function repl({
|
||||
sync = false,
|
||||
setInterval,
|
||||
clearInterval,
|
||||
id,
|
||||
}) {
|
||||
const state = {
|
||||
schedulerError: undefined,
|
||||
@ -32,6 +34,10 @@ export function repl({
|
||||
started: false,
|
||||
};
|
||||
|
||||
const transpilerOptions = {
|
||||
id,
|
||||
};
|
||||
|
||||
const updateState = (update) => {
|
||||
Object.assign(state, update);
|
||||
state.isDirty = state.code !== state.activeCode;
|
||||
@ -48,6 +54,7 @@ export function repl({
|
||||
},
|
||||
setInterval,
|
||||
clearInterval,
|
||||
beforeStart,
|
||||
};
|
||||
|
||||
// NeoCyclist uses a shared worker to communicate between instances, which is not supported on mobile chrome
|
||||
@ -64,9 +71,10 @@ export function repl({
|
||||
return silence;
|
||||
};
|
||||
|
||||
const setPattern = (pattern, autostart = true) => {
|
||||
const setPattern = async (pattern, autostart = true) => {
|
||||
pattern = editPattern?.(pattern) || pattern;
|
||||
scheduler.setPattern(pattern, autostart);
|
||||
await scheduler.setPattern(pattern, autostart);
|
||||
return pattern;
|
||||
};
|
||||
setTime(() => scheduler.now()); // TODO: refactor?
|
||||
|
||||
@ -139,9 +147,10 @@ export function repl({
|
||||
try {
|
||||
updateState({ code, pending: true });
|
||||
await injectPatternMethods();
|
||||
setTime(() => scheduler.now()); // TODO: refactor?
|
||||
await beforeEval?.({ code });
|
||||
shouldHush && hush();
|
||||
let { pattern, meta } = await _evaluate(code, transpiler);
|
||||
let { pattern, meta } = await _evaluate(code, transpiler, transpilerOptions);
|
||||
if (Object.keys(pPatterns).length) {
|
||||
pattern = stack(...Object.values(pPatterns));
|
||||
}
|
||||
@ -153,7 +162,7 @@ export function repl({
|
||||
throw new Error(message + (typeof evaluated === 'function' ? ', did you forget to call a function?' : '.'));
|
||||
}
|
||||
logger(`[eval] code updated`);
|
||||
setPattern(pattern, autostart);
|
||||
pattern = await setPattern(pattern, autostart);
|
||||
updateState({
|
||||
miniLocations: meta?.miniLocations || [],
|
||||
widgets: meta?.widgets || [],
|
||||
|
||||
@ -36,8 +36,8 @@ function stopAnimationFrame(id) {
|
||||
delete animationFrames[id];
|
||||
}
|
||||
}
|
||||
function stopAllAnimations() {
|
||||
Object.keys(animationFrames).forEach((id) => stopAnimationFrame(id));
|
||||
function stopAllAnimations(replID) {
|
||||
Object.keys(animationFrames).forEach((id) => (!replID || id.startsWith(replID)) && stopAnimationFrame(id));
|
||||
}
|
||||
|
||||
let memory = {};
|
||||
@ -72,18 +72,25 @@ Pattern.prototype.draw = function (fn, options) {
|
||||
return this;
|
||||
};
|
||||
|
||||
export const cleanupDraw = (clearScreen = true) => {
|
||||
export const cleanupDraw = (clearScreen = true, id) => {
|
||||
const ctx = getDrawContext();
|
||||
clearScreen && ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.width);
|
||||
stopAllAnimations();
|
||||
if (window.strudelScheduler) {
|
||||
clearInterval(window.strudelScheduler);
|
||||
}
|
||||
clearScreen && ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
|
||||
stopAllAnimations(id);
|
||||
};
|
||||
|
||||
Pattern.prototype.onPaint = function () {
|
||||
console.warn('[draw] onPaint was not overloaded. Some drawings might not work');
|
||||
return this;
|
||||
Pattern.prototype.onPaint = function (painter) {
|
||||
return this.withState((state) => {
|
||||
if (!state.controls.painters) {
|
||||
state.controls.painters = [];
|
||||
}
|
||||
state.controls.painters.push(painter);
|
||||
});
|
||||
};
|
||||
|
||||
Pattern.prototype.getPainters = function () {
|
||||
let painters = [];
|
||||
this.queryArc(0, 0, { painters });
|
||||
return painters;
|
||||
};
|
||||
|
||||
// const round = (x) => Math.round(x * 1000) / 1000;
|
||||
@ -122,6 +129,7 @@ export class Drawer {
|
||||
this.visibleHaps = [];
|
||||
this.lastFrame = null;
|
||||
this.drawTime = drawTime;
|
||||
this.painters = [];
|
||||
this.framer = new Framer(
|
||||
() => {
|
||||
if (!this.scheduler) {
|
||||
@ -146,7 +154,7 @@ export class Drawer {
|
||||
// add new haps with onset (think right edge bars scrolling in)
|
||||
.concat(haps.filter((h) => h.hasOnset()));
|
||||
const time = phase - lookahead;
|
||||
onDraw(this.visibleHaps, time, this);
|
||||
onDraw(this.visibleHaps, time, this, this.painters);
|
||||
},
|
||||
(err) => {
|
||||
console.warn('draw error', err);
|
||||
@ -164,11 +172,13 @@ export class Drawer {
|
||||
t = t ?? scheduler.now();
|
||||
this.scheduler = scheduler;
|
||||
let [_, lookahead] = this.drawTime;
|
||||
// +0.1 = workaround for weird holes in query..
|
||||
const [begin, end] = [Math.max(t, 0), t + lookahead + 0.1];
|
||||
// remove all future haps
|
||||
this.visibleHaps = this.visibleHaps.filter((h) => h.whole.begin < t);
|
||||
this.painters = []; // will get populated by .onPaint calls attached to the pattern
|
||||
// query future haps
|
||||
const futureHaps = scheduler.pattern.queryArc(begin, end); // +0.1 = workaround for weird holes in query..
|
||||
const futureHaps = scheduler.pattern.queryArc(begin, end, { painters: this.painters });
|
||||
// append future haps
|
||||
this.visibleHaps = this.visibleHaps.concat(futureHaps);
|
||||
}
|
||||
|
||||
@ -67,6 +67,7 @@ Pattern.prototype.pianoroll = function (options = {}) {
|
||||
* Displays a midi-style piano roll
|
||||
*
|
||||
* @name pianoroll
|
||||
* @synonyms punchcard
|
||||
* @param {Object} options Object containing all the optional following parameters as key value pairs:
|
||||
* @param {integer} cycles number of cycles to be displayed at the same time - defaults to 4
|
||||
* @param {number} playhead location of the active notes on the time axis - 0 to 1, defaults to 0.5
|
||||
@ -94,7 +95,11 @@ Pattern.prototype.pianoroll = function (options = {}) {
|
||||
* @param {boolean} autorange automatically calculate the minMidi and maxMidi parameters - 0 by default
|
||||
*
|
||||
* @example
|
||||
* note("C2 A2 G2").euclid(5,8).s('piano').clip(1).color('salmon').pianoroll({vertical:1, labels:1})
|
||||
* note("c2 a2 eb2")
|
||||
* .euclid(5,8)
|
||||
* .s('sawtooth')
|
||||
* .lpenv(4).lpf(300)
|
||||
* ._pianoroll({ labels: 1 })
|
||||
*/
|
||||
export function pianoroll({
|
||||
time,
|
||||
@ -113,7 +118,7 @@ export function pianoroll({
|
||||
maxMidi = 90,
|
||||
autorange = 0,
|
||||
timeframe: timeframeProp,
|
||||
fold = 0,
|
||||
fold = 1,
|
||||
vertical = 0,
|
||||
labels = false,
|
||||
fill = 1,
|
||||
@ -266,7 +271,7 @@ export function getDrawOptions(drawTime, options = {}) {
|
||||
let [lookbehind, lookahead] = drawTime;
|
||||
lookbehind = Math.abs(lookbehind);
|
||||
const cycles = lookahead + lookbehind;
|
||||
const playhead = lookbehind / cycles;
|
||||
const playhead = cycles !== 0 ? lookbehind / cycles : 0;
|
||||
return { fold: 1, ...options, cycles, playhead };
|
||||
}
|
||||
|
||||
|
||||
@ -113,6 +113,23 @@ export function pitchwheel({
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a pitch circle to visualize frequencies within one octave
|
||||
* @name pitchwheel
|
||||
* @param {number} hapcircles
|
||||
* @param {number} circle
|
||||
* @param {number} edo
|
||||
* @param {string} root
|
||||
* @param {number} thickness
|
||||
* @param {number} hapRadius
|
||||
* @param {string} mode
|
||||
* @param {number} margin
|
||||
* @example
|
||||
* n("0 .. 12").scale("C:chromatic")
|
||||
* .s("sawtooth")
|
||||
* .lpf(500)
|
||||
* ._pitchwheel()
|
||||
*/
|
||||
Pattern.prototype.pitchwheel = function (options = {}) {
|
||||
let { ctx = getDrawContext(), id = 1 } = options;
|
||||
return this.tag(id).onPaint((_, time, haps) =>
|
||||
|
||||
@ -125,6 +125,33 @@ function drawSpiral(options) {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays a spiral visual.
|
||||
*
|
||||
* @name spiral
|
||||
* @param {Object} options Object containing all the optional following parameters as key value pairs:
|
||||
* @param {number} stretch controls the rotations per cycle ratio, where 1 = 1 cycle / 360 degrees
|
||||
* @param {number} size the diameter of the spiral
|
||||
* @param {number} thickness line thickness
|
||||
* @param {string} cap style of line ends: butt (default), round, square
|
||||
* @param {string} inset number of rotations before spiral starts (default 3)
|
||||
* @param {string} playheadColor color of playhead, defaults to white
|
||||
* @param {number} playheadLength length of playhead in rotations, defaults to 0.02
|
||||
* @param {number} playheadThickness thickness of playheadrotations, defaults to thickness
|
||||
* @param {number} padding space around spiral
|
||||
* @param {number} steady steadyness of spiral vs playhead. 1 = spiral doesn't move, playhead does.
|
||||
* @param {number} activeColor color of active segment. defaults to foreground of theme
|
||||
* @param {number} inactiveColor color of inactive segments. defaults to gutterForeground of theme
|
||||
* @param {boolean} colorizeInactive wether or not to colorize inactive segments, defaults to 0
|
||||
* @param {boolean} fade wether or not past and future should fade out. defaults to 1
|
||||
* @param {boolean} logSpiral wether or not the spiral should be logarithmic. defaults to 0
|
||||
* @example
|
||||
* note("c2 a2 eb2")
|
||||
* .euclid(5,8)
|
||||
* .s('sawtooth')
|
||||
* .lpenv(4).lpf(300)
|
||||
* ._spiral({ steady: .96 })
|
||||
*/
|
||||
Pattern.prototype.spiral = function (options = {}) {
|
||||
return this.onPaint((ctx, time, haps, drawTime) => drawSpiral({ ctx, time, haps, drawTime, ...options }));
|
||||
};
|
||||
|
||||
@ -69,6 +69,7 @@ export function transpiler(input, options = {}) {
|
||||
to: node.end,
|
||||
index,
|
||||
type,
|
||||
id: options.id,
|
||||
};
|
||||
emitWidgets && widgets.push(widgetConfig);
|
||||
return this.replace(widgetWithLocation(node, widgetConfig));
|
||||
@ -162,7 +163,7 @@ export function getWidgetID(widgetConfig) {
|
||||
// that means, if we use the index index of line position as id, less garbage is generated
|
||||
// return `widget_${widgetConfig.to}`; // more gargabe
|
||||
//return `widget_${widgetConfig.index}_${widgetConfig.to}`; // also more garbage
|
||||
return `widget_${widgetConfig.type}_${widgetConfig.index}`; // less garbage
|
||||
return `${widgetConfig.id || ''}_widget_${widgetConfig.type}_${widgetConfig.index}`; // less garbage
|
||||
}
|
||||
|
||||
function widgetWithLocation(node, widgetConfig) {
|
||||
|
||||
@ -130,7 +130,7 @@ Pattern.prototype.fscope = function (config = {}) {
|
||||
* @param {number} pos y-position relative to screen height. 0 = top, 1 = bottom of screen
|
||||
* @param {number} trigger amplitude value that is used to align the scope. defaults to 0.
|
||||
* @example
|
||||
* s("sawtooth").scope()
|
||||
* s("sawtooth")._scope()
|
||||
*/
|
||||
let latestColor = {};
|
||||
Pattern.prototype.tscope = function (config = {}) {
|
||||
|
||||
@ -2717,175 +2717,175 @@ exports[`runs examples > example "floor" example index 0 1`] = `
|
||||
|
||||
exports[`runs examples > example "fm" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/6 | note:c fmi:0 analyze:1 ]",
|
||||
"[ 1/6 → 1/3 | note:e fmi:0 analyze:1 ]",
|
||||
"[ 1/3 → 1/2 | note:g fmi:0 analyze:1 ]",
|
||||
"[ 1/2 → 2/3 | note:b fmi:0 analyze:1 ]",
|
||||
"[ 2/3 → 5/6 | note:g fmi:0 analyze:1 ]",
|
||||
"[ 5/6 → 1/1 | note:e fmi:0 analyze:1 ]",
|
||||
"[ 1/1 → 7/6 | note:c fmi:1 analyze:1 ]",
|
||||
"[ 7/6 → 4/3 | note:e fmi:1 analyze:1 ]",
|
||||
"[ 4/3 → 3/2 | note:g fmi:1 analyze:1 ]",
|
||||
"[ 3/2 → 5/3 | note:b fmi:1 analyze:1 ]",
|
||||
"[ 5/3 → 11/6 | note:g fmi:1 analyze:1 ]",
|
||||
"[ 11/6 → 2/1 | note:e fmi:1 analyze:1 ]",
|
||||
"[ 2/1 → 13/6 | note:c fmi:2 analyze:1 ]",
|
||||
"[ 13/6 → 7/3 | note:e fmi:2 analyze:1 ]",
|
||||
"[ 7/3 → 5/2 | note:g fmi:2 analyze:1 ]",
|
||||
"[ 5/2 → 8/3 | note:b fmi:2 analyze:1 ]",
|
||||
"[ 8/3 → 17/6 | note:g fmi:2 analyze:1 ]",
|
||||
"[ 17/6 → 3/1 | note:e fmi:2 analyze:1 ]",
|
||||
"[ 3/1 → 19/6 | note:c fmi:8 analyze:1 ]",
|
||||
"[ 19/6 → 10/3 | note:e fmi:8 analyze:1 ]",
|
||||
"[ 10/3 → 7/2 | note:g fmi:8 analyze:1 ]",
|
||||
"[ 7/2 → 11/3 | note:b fmi:8 analyze:1 ]",
|
||||
"[ 11/3 → 23/6 | note:g fmi:8 analyze:1 ]",
|
||||
"[ 23/6 → 4/1 | note:e fmi:8 analyze:1 ]",
|
||||
"[ 0/1 → 1/6 | note:c fmi:0 ]",
|
||||
"[ 1/6 → 1/3 | note:e fmi:0 ]",
|
||||
"[ 1/3 → 1/2 | note:g fmi:0 ]",
|
||||
"[ 1/2 → 2/3 | note:b fmi:0 ]",
|
||||
"[ 2/3 → 5/6 | note:g fmi:0 ]",
|
||||
"[ 5/6 → 1/1 | note:e fmi:0 ]",
|
||||
"[ 1/1 → 7/6 | note:c fmi:1 ]",
|
||||
"[ 7/6 → 4/3 | note:e fmi:1 ]",
|
||||
"[ 4/3 → 3/2 | note:g fmi:1 ]",
|
||||
"[ 3/2 → 5/3 | note:b fmi:1 ]",
|
||||
"[ 5/3 → 11/6 | note:g fmi:1 ]",
|
||||
"[ 11/6 → 2/1 | note:e fmi:1 ]",
|
||||
"[ 2/1 → 13/6 | note:c fmi:2 ]",
|
||||
"[ 13/6 → 7/3 | note:e fmi:2 ]",
|
||||
"[ 7/3 → 5/2 | note:g fmi:2 ]",
|
||||
"[ 5/2 → 8/3 | note:b fmi:2 ]",
|
||||
"[ 8/3 → 17/6 | note:g fmi:2 ]",
|
||||
"[ 17/6 → 3/1 | note:e fmi:2 ]",
|
||||
"[ 3/1 → 19/6 | note:c fmi:8 ]",
|
||||
"[ 19/6 → 10/3 | note:e fmi:8 ]",
|
||||
"[ 10/3 → 7/2 | note:g fmi:8 ]",
|
||||
"[ 7/2 → 11/3 | note:b fmi:8 ]",
|
||||
"[ 11/3 → 23/6 | note:g fmi:8 ]",
|
||||
"[ 23/6 → 4/1 | note:e fmi:8 ]",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "fmattack" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/6 | note:c fmi:4 fmattack:0 analyze:1 ]",
|
||||
"[ 1/6 → 1/3 | note:e fmi:4 fmattack:0 analyze:1 ]",
|
||||
"[ 1/3 → 1/2 | note:g fmi:4 fmattack:0 analyze:1 ]",
|
||||
"[ 1/2 → 2/3 | note:b fmi:4 fmattack:0 analyze:1 ]",
|
||||
"[ 2/3 → 5/6 | note:g fmi:4 fmattack:0 analyze:1 ]",
|
||||
"[ 5/6 → 1/1 | note:e fmi:4 fmattack:0 analyze:1 ]",
|
||||
"[ 1/1 → 7/6 | note:c fmi:4 fmattack:0.05 analyze:1 ]",
|
||||
"[ 7/6 → 4/3 | note:e fmi:4 fmattack:0.05 analyze:1 ]",
|
||||
"[ 4/3 → 3/2 | note:g fmi:4 fmattack:0.05 analyze:1 ]",
|
||||
"[ 3/2 → 5/3 | note:b fmi:4 fmattack:0.05 analyze:1 ]",
|
||||
"[ 5/3 → 11/6 | note:g fmi:4 fmattack:0.05 analyze:1 ]",
|
||||
"[ 11/6 → 2/1 | note:e fmi:4 fmattack:0.05 analyze:1 ]",
|
||||
"[ 2/1 → 13/6 | note:c fmi:4 fmattack:0.1 analyze:1 ]",
|
||||
"[ 13/6 → 7/3 | note:e fmi:4 fmattack:0.1 analyze:1 ]",
|
||||
"[ 7/3 → 5/2 | note:g fmi:4 fmattack:0.1 analyze:1 ]",
|
||||
"[ 5/2 → 8/3 | note:b fmi:4 fmattack:0.1 analyze:1 ]",
|
||||
"[ 8/3 → 17/6 | note:g fmi:4 fmattack:0.1 analyze:1 ]",
|
||||
"[ 17/6 → 3/1 | note:e fmi:4 fmattack:0.1 analyze:1 ]",
|
||||
"[ 3/1 → 19/6 | note:c fmi:4 fmattack:0.2 analyze:1 ]",
|
||||
"[ 19/6 → 10/3 | note:e fmi:4 fmattack:0.2 analyze:1 ]",
|
||||
"[ 10/3 → 7/2 | note:g fmi:4 fmattack:0.2 analyze:1 ]",
|
||||
"[ 7/2 → 11/3 | note:b fmi:4 fmattack:0.2 analyze:1 ]",
|
||||
"[ 11/3 → 23/6 | note:g fmi:4 fmattack:0.2 analyze:1 ]",
|
||||
"[ 23/6 → 4/1 | note:e fmi:4 fmattack:0.2 analyze:1 ]",
|
||||
"[ 0/1 → 1/6 | note:c fmi:4 fmattack:0 ]",
|
||||
"[ 1/6 → 1/3 | note:e fmi:4 fmattack:0 ]",
|
||||
"[ 1/3 → 1/2 | note:g fmi:4 fmattack:0 ]",
|
||||
"[ 1/2 → 2/3 | note:b fmi:4 fmattack:0 ]",
|
||||
"[ 2/3 → 5/6 | note:g fmi:4 fmattack:0 ]",
|
||||
"[ 5/6 → 1/1 | note:e fmi:4 fmattack:0 ]",
|
||||
"[ 1/1 → 7/6 | note:c fmi:4 fmattack:0.05 ]",
|
||||
"[ 7/6 → 4/3 | note:e fmi:4 fmattack:0.05 ]",
|
||||
"[ 4/3 → 3/2 | note:g fmi:4 fmattack:0.05 ]",
|
||||
"[ 3/2 → 5/3 | note:b fmi:4 fmattack:0.05 ]",
|
||||
"[ 5/3 → 11/6 | note:g fmi:4 fmattack:0.05 ]",
|
||||
"[ 11/6 → 2/1 | note:e fmi:4 fmattack:0.05 ]",
|
||||
"[ 2/1 → 13/6 | note:c fmi:4 fmattack:0.1 ]",
|
||||
"[ 13/6 → 7/3 | note:e fmi:4 fmattack:0.1 ]",
|
||||
"[ 7/3 → 5/2 | note:g fmi:4 fmattack:0.1 ]",
|
||||
"[ 5/2 → 8/3 | note:b fmi:4 fmattack:0.1 ]",
|
||||
"[ 8/3 → 17/6 | note:g fmi:4 fmattack:0.1 ]",
|
||||
"[ 17/6 → 3/1 | note:e fmi:4 fmattack:0.1 ]",
|
||||
"[ 3/1 → 19/6 | note:c fmi:4 fmattack:0.2 ]",
|
||||
"[ 19/6 → 10/3 | note:e fmi:4 fmattack:0.2 ]",
|
||||
"[ 10/3 → 7/2 | note:g fmi:4 fmattack:0.2 ]",
|
||||
"[ 7/2 → 11/3 | note:b fmi:4 fmattack:0.2 ]",
|
||||
"[ 11/3 → 23/6 | note:g fmi:4 fmattack:0.2 ]",
|
||||
"[ 23/6 → 4/1 | note:e fmi:4 fmattack:0.2 ]",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "fmdecay" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/6 | note:c fmi:4 fmdecay:0.01 fmsustain:0.4 analyze:1 ]",
|
||||
"[ 1/6 → 1/3 | note:e fmi:4 fmdecay:0.01 fmsustain:0.4 analyze:1 ]",
|
||||
"[ 1/3 → 1/2 | note:g fmi:4 fmdecay:0.01 fmsustain:0.4 analyze:1 ]",
|
||||
"[ 1/2 → 2/3 | note:b fmi:4 fmdecay:0.01 fmsustain:0.4 analyze:1 ]",
|
||||
"[ 2/3 → 5/6 | note:g fmi:4 fmdecay:0.01 fmsustain:0.4 analyze:1 ]",
|
||||
"[ 5/6 → 1/1 | note:e fmi:4 fmdecay:0.01 fmsustain:0.4 analyze:1 ]",
|
||||
"[ 1/1 → 7/6 | note:c fmi:4 fmdecay:0.05 fmsustain:0.4 analyze:1 ]",
|
||||
"[ 7/6 → 4/3 | note:e fmi:4 fmdecay:0.05 fmsustain:0.4 analyze:1 ]",
|
||||
"[ 4/3 → 3/2 | note:g fmi:4 fmdecay:0.05 fmsustain:0.4 analyze:1 ]",
|
||||
"[ 3/2 → 5/3 | note:b fmi:4 fmdecay:0.05 fmsustain:0.4 analyze:1 ]",
|
||||
"[ 5/3 → 11/6 | note:g fmi:4 fmdecay:0.05 fmsustain:0.4 analyze:1 ]",
|
||||
"[ 11/6 → 2/1 | note:e fmi:4 fmdecay:0.05 fmsustain:0.4 analyze:1 ]",
|
||||
"[ 2/1 → 13/6 | note:c fmi:4 fmdecay:0.1 fmsustain:0.4 analyze:1 ]",
|
||||
"[ 13/6 → 7/3 | note:e fmi:4 fmdecay:0.1 fmsustain:0.4 analyze:1 ]",
|
||||
"[ 7/3 → 5/2 | note:g fmi:4 fmdecay:0.1 fmsustain:0.4 analyze:1 ]",
|
||||
"[ 5/2 → 8/3 | note:b fmi:4 fmdecay:0.1 fmsustain:0.4 analyze:1 ]",
|
||||
"[ 8/3 → 17/6 | note:g fmi:4 fmdecay:0.1 fmsustain:0.4 analyze:1 ]",
|
||||
"[ 17/6 → 3/1 | note:e fmi:4 fmdecay:0.1 fmsustain:0.4 analyze:1 ]",
|
||||
"[ 3/1 → 19/6 | note:c fmi:4 fmdecay:0.2 fmsustain:0.4 analyze:1 ]",
|
||||
"[ 19/6 → 10/3 | note:e fmi:4 fmdecay:0.2 fmsustain:0.4 analyze:1 ]",
|
||||
"[ 10/3 → 7/2 | note:g fmi:4 fmdecay:0.2 fmsustain:0.4 analyze:1 ]",
|
||||
"[ 7/2 → 11/3 | note:b fmi:4 fmdecay:0.2 fmsustain:0.4 analyze:1 ]",
|
||||
"[ 11/3 → 23/6 | note:g fmi:4 fmdecay:0.2 fmsustain:0.4 analyze:1 ]",
|
||||
"[ 23/6 → 4/1 | note:e fmi:4 fmdecay:0.2 fmsustain:0.4 analyze:1 ]",
|
||||
"[ 0/1 → 1/6 | note:c fmi:4 fmdecay:0.01 fmsustain:0.4 ]",
|
||||
"[ 1/6 → 1/3 | note:e fmi:4 fmdecay:0.01 fmsustain:0.4 ]",
|
||||
"[ 1/3 → 1/2 | note:g fmi:4 fmdecay:0.01 fmsustain:0.4 ]",
|
||||
"[ 1/2 → 2/3 | note:b fmi:4 fmdecay:0.01 fmsustain:0.4 ]",
|
||||
"[ 2/3 → 5/6 | note:g fmi:4 fmdecay:0.01 fmsustain:0.4 ]",
|
||||
"[ 5/6 → 1/1 | note:e fmi:4 fmdecay:0.01 fmsustain:0.4 ]",
|
||||
"[ 1/1 → 7/6 | note:c fmi:4 fmdecay:0.05 fmsustain:0.4 ]",
|
||||
"[ 7/6 → 4/3 | note:e fmi:4 fmdecay:0.05 fmsustain:0.4 ]",
|
||||
"[ 4/3 → 3/2 | note:g fmi:4 fmdecay:0.05 fmsustain:0.4 ]",
|
||||
"[ 3/2 → 5/3 | note:b fmi:4 fmdecay:0.05 fmsustain:0.4 ]",
|
||||
"[ 5/3 → 11/6 | note:g fmi:4 fmdecay:0.05 fmsustain:0.4 ]",
|
||||
"[ 11/6 → 2/1 | note:e fmi:4 fmdecay:0.05 fmsustain:0.4 ]",
|
||||
"[ 2/1 → 13/6 | note:c fmi:4 fmdecay:0.1 fmsustain:0.4 ]",
|
||||
"[ 13/6 → 7/3 | note:e fmi:4 fmdecay:0.1 fmsustain:0.4 ]",
|
||||
"[ 7/3 → 5/2 | note:g fmi:4 fmdecay:0.1 fmsustain:0.4 ]",
|
||||
"[ 5/2 → 8/3 | note:b fmi:4 fmdecay:0.1 fmsustain:0.4 ]",
|
||||
"[ 8/3 → 17/6 | note:g fmi:4 fmdecay:0.1 fmsustain:0.4 ]",
|
||||
"[ 17/6 → 3/1 | note:e fmi:4 fmdecay:0.1 fmsustain:0.4 ]",
|
||||
"[ 3/1 → 19/6 | note:c fmi:4 fmdecay:0.2 fmsustain:0.4 ]",
|
||||
"[ 19/6 → 10/3 | note:e fmi:4 fmdecay:0.2 fmsustain:0.4 ]",
|
||||
"[ 10/3 → 7/2 | note:g fmi:4 fmdecay:0.2 fmsustain:0.4 ]",
|
||||
"[ 7/2 → 11/3 | note:b fmi:4 fmdecay:0.2 fmsustain:0.4 ]",
|
||||
"[ 11/3 → 23/6 | note:g fmi:4 fmdecay:0.2 fmsustain:0.4 ]",
|
||||
"[ 23/6 → 4/1 | note:e fmi:4 fmdecay:0.2 fmsustain:0.4 ]",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "fmenv" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/6 | note:c fmi:4 fmdecay:0.2 fmsustain:0 fmenv:exp analyze:1 ]",
|
||||
"[ 1/6 → 1/3 | note:e fmi:4 fmdecay:0.2 fmsustain:0 fmenv:exp analyze:1 ]",
|
||||
"[ 1/3 → 1/2 | note:g fmi:4 fmdecay:0.2 fmsustain:0 fmenv:exp analyze:1 ]",
|
||||
"[ 1/2 → 2/3 | note:b fmi:4 fmdecay:0.2 fmsustain:0 fmenv:exp analyze:1 ]",
|
||||
"[ 2/3 → 5/6 | note:g fmi:4 fmdecay:0.2 fmsustain:0 fmenv:exp analyze:1 ]",
|
||||
"[ 5/6 → 1/1 | note:e fmi:4 fmdecay:0.2 fmsustain:0 fmenv:exp analyze:1 ]",
|
||||
"[ 1/1 → 7/6 | note:c fmi:4 fmdecay:0.2 fmsustain:0 fmenv:lin analyze:1 ]",
|
||||
"[ 7/6 → 4/3 | note:e fmi:4 fmdecay:0.2 fmsustain:0 fmenv:lin analyze:1 ]",
|
||||
"[ 4/3 → 3/2 | note:g fmi:4 fmdecay:0.2 fmsustain:0 fmenv:lin analyze:1 ]",
|
||||
"[ 3/2 → 5/3 | note:b fmi:4 fmdecay:0.2 fmsustain:0 fmenv:lin analyze:1 ]",
|
||||
"[ 5/3 → 11/6 | note:g fmi:4 fmdecay:0.2 fmsustain:0 fmenv:lin analyze:1 ]",
|
||||
"[ 11/6 → 2/1 | note:e fmi:4 fmdecay:0.2 fmsustain:0 fmenv:lin analyze:1 ]",
|
||||
"[ 2/1 → 13/6 | note:c fmi:4 fmdecay:0.2 fmsustain:0 fmenv:exp analyze:1 ]",
|
||||
"[ 13/6 → 7/3 | note:e fmi:4 fmdecay:0.2 fmsustain:0 fmenv:exp analyze:1 ]",
|
||||
"[ 7/3 → 5/2 | note:g fmi:4 fmdecay:0.2 fmsustain:0 fmenv:exp analyze:1 ]",
|
||||
"[ 5/2 → 8/3 | note:b fmi:4 fmdecay:0.2 fmsustain:0 fmenv:exp analyze:1 ]",
|
||||
"[ 8/3 → 17/6 | note:g fmi:4 fmdecay:0.2 fmsustain:0 fmenv:exp analyze:1 ]",
|
||||
"[ 17/6 → 3/1 | note:e fmi:4 fmdecay:0.2 fmsustain:0 fmenv:exp analyze:1 ]",
|
||||
"[ 3/1 → 19/6 | note:c fmi:4 fmdecay:0.2 fmsustain:0 fmenv:lin analyze:1 ]",
|
||||
"[ 19/6 → 10/3 | note:e fmi:4 fmdecay:0.2 fmsustain:0 fmenv:lin analyze:1 ]",
|
||||
"[ 10/3 → 7/2 | note:g fmi:4 fmdecay:0.2 fmsustain:0 fmenv:lin analyze:1 ]",
|
||||
"[ 7/2 → 11/3 | note:b fmi:4 fmdecay:0.2 fmsustain:0 fmenv:lin analyze:1 ]",
|
||||
"[ 11/3 → 23/6 | note:g fmi:4 fmdecay:0.2 fmsustain:0 fmenv:lin analyze:1 ]",
|
||||
"[ 23/6 → 4/1 | note:e fmi:4 fmdecay:0.2 fmsustain:0 fmenv:lin analyze:1 ]",
|
||||
"[ 0/1 → 1/6 | note:c fmi:4 fmdecay:0.2 fmsustain:0 fmenv:exp ]",
|
||||
"[ 1/6 → 1/3 | note:e fmi:4 fmdecay:0.2 fmsustain:0 fmenv:exp ]",
|
||||
"[ 1/3 → 1/2 | note:g fmi:4 fmdecay:0.2 fmsustain:0 fmenv:exp ]",
|
||||
"[ 1/2 → 2/3 | note:b fmi:4 fmdecay:0.2 fmsustain:0 fmenv:exp ]",
|
||||
"[ 2/3 → 5/6 | note:g fmi:4 fmdecay:0.2 fmsustain:0 fmenv:exp ]",
|
||||
"[ 5/6 → 1/1 | note:e fmi:4 fmdecay:0.2 fmsustain:0 fmenv:exp ]",
|
||||
"[ 1/1 → 7/6 | note:c fmi:4 fmdecay:0.2 fmsustain:0 fmenv:lin ]",
|
||||
"[ 7/6 → 4/3 | note:e fmi:4 fmdecay:0.2 fmsustain:0 fmenv:lin ]",
|
||||
"[ 4/3 → 3/2 | note:g fmi:4 fmdecay:0.2 fmsustain:0 fmenv:lin ]",
|
||||
"[ 3/2 → 5/3 | note:b fmi:4 fmdecay:0.2 fmsustain:0 fmenv:lin ]",
|
||||
"[ 5/3 → 11/6 | note:g fmi:4 fmdecay:0.2 fmsustain:0 fmenv:lin ]",
|
||||
"[ 11/6 → 2/1 | note:e fmi:4 fmdecay:0.2 fmsustain:0 fmenv:lin ]",
|
||||
"[ 2/1 → 13/6 | note:c fmi:4 fmdecay:0.2 fmsustain:0 fmenv:exp ]",
|
||||
"[ 13/6 → 7/3 | note:e fmi:4 fmdecay:0.2 fmsustain:0 fmenv:exp ]",
|
||||
"[ 7/3 → 5/2 | note:g fmi:4 fmdecay:0.2 fmsustain:0 fmenv:exp ]",
|
||||
"[ 5/2 → 8/3 | note:b fmi:4 fmdecay:0.2 fmsustain:0 fmenv:exp ]",
|
||||
"[ 8/3 → 17/6 | note:g fmi:4 fmdecay:0.2 fmsustain:0 fmenv:exp ]",
|
||||
"[ 17/6 → 3/1 | note:e fmi:4 fmdecay:0.2 fmsustain:0 fmenv:exp ]",
|
||||
"[ 3/1 → 19/6 | note:c fmi:4 fmdecay:0.2 fmsustain:0 fmenv:lin ]",
|
||||
"[ 19/6 → 10/3 | note:e fmi:4 fmdecay:0.2 fmsustain:0 fmenv:lin ]",
|
||||
"[ 10/3 → 7/2 | note:g fmi:4 fmdecay:0.2 fmsustain:0 fmenv:lin ]",
|
||||
"[ 7/2 → 11/3 | note:b fmi:4 fmdecay:0.2 fmsustain:0 fmenv:lin ]",
|
||||
"[ 11/3 → 23/6 | note:g fmi:4 fmdecay:0.2 fmsustain:0 fmenv:lin ]",
|
||||
"[ 23/6 → 4/1 | note:e fmi:4 fmdecay:0.2 fmsustain:0 fmenv:lin ]",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "fmh" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/6 | note:c fmi:4 fmh:1 analyze:1 ]",
|
||||
"[ 1/6 → 1/3 | note:e fmi:4 fmh:1 analyze:1 ]",
|
||||
"[ 1/3 → 1/2 | note:g fmi:4 fmh:1 analyze:1 ]",
|
||||
"[ 1/2 → 2/3 | note:b fmi:4 fmh:1 analyze:1 ]",
|
||||
"[ 2/3 → 5/6 | note:g fmi:4 fmh:1 analyze:1 ]",
|
||||
"[ 5/6 → 1/1 | note:e fmi:4 fmh:1 analyze:1 ]",
|
||||
"[ 1/1 → 7/6 | note:c fmi:4 fmh:2 analyze:1 ]",
|
||||
"[ 7/6 → 4/3 | note:e fmi:4 fmh:2 analyze:1 ]",
|
||||
"[ 4/3 → 3/2 | note:g fmi:4 fmh:2 analyze:1 ]",
|
||||
"[ 3/2 → 5/3 | note:b fmi:4 fmh:2 analyze:1 ]",
|
||||
"[ 5/3 → 11/6 | note:g fmi:4 fmh:2 analyze:1 ]",
|
||||
"[ 11/6 → 2/1 | note:e fmi:4 fmh:2 analyze:1 ]",
|
||||
"[ 2/1 → 13/6 | note:c fmi:4 fmh:1.5 analyze:1 ]",
|
||||
"[ 13/6 → 7/3 | note:e fmi:4 fmh:1.5 analyze:1 ]",
|
||||
"[ 7/3 → 5/2 | note:g fmi:4 fmh:1.5 analyze:1 ]",
|
||||
"[ 5/2 → 8/3 | note:b fmi:4 fmh:1.5 analyze:1 ]",
|
||||
"[ 8/3 → 17/6 | note:g fmi:4 fmh:1.5 analyze:1 ]",
|
||||
"[ 17/6 → 3/1 | note:e fmi:4 fmh:1.5 analyze:1 ]",
|
||||
"[ 3/1 → 19/6 | note:c fmi:4 fmh:1.61 analyze:1 ]",
|
||||
"[ 19/6 → 10/3 | note:e fmi:4 fmh:1.61 analyze:1 ]",
|
||||
"[ 10/3 → 7/2 | note:g fmi:4 fmh:1.61 analyze:1 ]",
|
||||
"[ 7/2 → 11/3 | note:b fmi:4 fmh:1.61 analyze:1 ]",
|
||||
"[ 11/3 → 23/6 | note:g fmi:4 fmh:1.61 analyze:1 ]",
|
||||
"[ 23/6 → 4/1 | note:e fmi:4 fmh:1.61 analyze:1 ]",
|
||||
"[ 0/1 → 1/6 | note:c fmi:4 fmh:1 ]",
|
||||
"[ 1/6 → 1/3 | note:e fmi:4 fmh:1 ]",
|
||||
"[ 1/3 → 1/2 | note:g fmi:4 fmh:1 ]",
|
||||
"[ 1/2 → 2/3 | note:b fmi:4 fmh:1 ]",
|
||||
"[ 2/3 → 5/6 | note:g fmi:4 fmh:1 ]",
|
||||
"[ 5/6 → 1/1 | note:e fmi:4 fmh:1 ]",
|
||||
"[ 1/1 → 7/6 | note:c fmi:4 fmh:2 ]",
|
||||
"[ 7/6 → 4/3 | note:e fmi:4 fmh:2 ]",
|
||||
"[ 4/3 → 3/2 | note:g fmi:4 fmh:2 ]",
|
||||
"[ 3/2 → 5/3 | note:b fmi:4 fmh:2 ]",
|
||||
"[ 5/3 → 11/6 | note:g fmi:4 fmh:2 ]",
|
||||
"[ 11/6 → 2/1 | note:e fmi:4 fmh:2 ]",
|
||||
"[ 2/1 → 13/6 | note:c fmi:4 fmh:1.5 ]",
|
||||
"[ 13/6 → 7/3 | note:e fmi:4 fmh:1.5 ]",
|
||||
"[ 7/3 → 5/2 | note:g fmi:4 fmh:1.5 ]",
|
||||
"[ 5/2 → 8/3 | note:b fmi:4 fmh:1.5 ]",
|
||||
"[ 8/3 → 17/6 | note:g fmi:4 fmh:1.5 ]",
|
||||
"[ 17/6 → 3/1 | note:e fmi:4 fmh:1.5 ]",
|
||||
"[ 3/1 → 19/6 | note:c fmi:4 fmh:1.61 ]",
|
||||
"[ 19/6 → 10/3 | note:e fmi:4 fmh:1.61 ]",
|
||||
"[ 10/3 → 7/2 | note:g fmi:4 fmh:1.61 ]",
|
||||
"[ 7/2 → 11/3 | note:b fmi:4 fmh:1.61 ]",
|
||||
"[ 11/3 → 23/6 | note:g fmi:4 fmh:1.61 ]",
|
||||
"[ 23/6 → 4/1 | note:e fmi:4 fmh:1.61 ]",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "fmsustain" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/6 | note:c fmi:4 fmdecay:0.1 fmsustain:1 analyze:1 ]",
|
||||
"[ 1/6 → 1/3 | note:e fmi:4 fmdecay:0.1 fmsustain:1 analyze:1 ]",
|
||||
"[ 1/3 → 1/2 | note:g fmi:4 fmdecay:0.1 fmsustain:1 analyze:1 ]",
|
||||
"[ 1/2 → 2/3 | note:b fmi:4 fmdecay:0.1 fmsustain:1 analyze:1 ]",
|
||||
"[ 2/3 → 5/6 | note:g fmi:4 fmdecay:0.1 fmsustain:1 analyze:1 ]",
|
||||
"[ 5/6 → 1/1 | note:e fmi:4 fmdecay:0.1 fmsustain:1 analyze:1 ]",
|
||||
"[ 1/1 → 7/6 | note:c fmi:4 fmdecay:0.1 fmsustain:0.75 analyze:1 ]",
|
||||
"[ 7/6 → 4/3 | note:e fmi:4 fmdecay:0.1 fmsustain:0.75 analyze:1 ]",
|
||||
"[ 4/3 → 3/2 | note:g fmi:4 fmdecay:0.1 fmsustain:0.75 analyze:1 ]",
|
||||
"[ 3/2 → 5/3 | note:b fmi:4 fmdecay:0.1 fmsustain:0.75 analyze:1 ]",
|
||||
"[ 5/3 → 11/6 | note:g fmi:4 fmdecay:0.1 fmsustain:0.75 analyze:1 ]",
|
||||
"[ 11/6 → 2/1 | note:e fmi:4 fmdecay:0.1 fmsustain:0.75 analyze:1 ]",
|
||||
"[ 2/1 → 13/6 | note:c fmi:4 fmdecay:0.1 fmsustain:0.5 analyze:1 ]",
|
||||
"[ 13/6 → 7/3 | note:e fmi:4 fmdecay:0.1 fmsustain:0.5 analyze:1 ]",
|
||||
"[ 7/3 → 5/2 | note:g fmi:4 fmdecay:0.1 fmsustain:0.5 analyze:1 ]",
|
||||
"[ 5/2 → 8/3 | note:b fmi:4 fmdecay:0.1 fmsustain:0.5 analyze:1 ]",
|
||||
"[ 8/3 → 17/6 | note:g fmi:4 fmdecay:0.1 fmsustain:0.5 analyze:1 ]",
|
||||
"[ 17/6 → 3/1 | note:e fmi:4 fmdecay:0.1 fmsustain:0.5 analyze:1 ]",
|
||||
"[ 3/1 → 19/6 | note:c fmi:4 fmdecay:0.1 fmsustain:0 analyze:1 ]",
|
||||
"[ 19/6 → 10/3 | note:e fmi:4 fmdecay:0.1 fmsustain:0 analyze:1 ]",
|
||||
"[ 10/3 → 7/2 | note:g fmi:4 fmdecay:0.1 fmsustain:0 analyze:1 ]",
|
||||
"[ 7/2 → 11/3 | note:b fmi:4 fmdecay:0.1 fmsustain:0 analyze:1 ]",
|
||||
"[ 11/3 → 23/6 | note:g fmi:4 fmdecay:0.1 fmsustain:0 analyze:1 ]",
|
||||
"[ 23/6 → 4/1 | note:e fmi:4 fmdecay:0.1 fmsustain:0 analyze:1 ]",
|
||||
"[ 0/1 → 1/6 | note:c fmi:4 fmdecay:0.1 fmsustain:1 ]",
|
||||
"[ 1/6 → 1/3 | note:e fmi:4 fmdecay:0.1 fmsustain:1 ]",
|
||||
"[ 1/3 → 1/2 | note:g fmi:4 fmdecay:0.1 fmsustain:1 ]",
|
||||
"[ 1/2 → 2/3 | note:b fmi:4 fmdecay:0.1 fmsustain:1 ]",
|
||||
"[ 2/3 → 5/6 | note:g fmi:4 fmdecay:0.1 fmsustain:1 ]",
|
||||
"[ 5/6 → 1/1 | note:e fmi:4 fmdecay:0.1 fmsustain:1 ]",
|
||||
"[ 1/1 → 7/6 | note:c fmi:4 fmdecay:0.1 fmsustain:0.75 ]",
|
||||
"[ 7/6 → 4/3 | note:e fmi:4 fmdecay:0.1 fmsustain:0.75 ]",
|
||||
"[ 4/3 → 3/2 | note:g fmi:4 fmdecay:0.1 fmsustain:0.75 ]",
|
||||
"[ 3/2 → 5/3 | note:b fmi:4 fmdecay:0.1 fmsustain:0.75 ]",
|
||||
"[ 5/3 → 11/6 | note:g fmi:4 fmdecay:0.1 fmsustain:0.75 ]",
|
||||
"[ 11/6 → 2/1 | note:e fmi:4 fmdecay:0.1 fmsustain:0.75 ]",
|
||||
"[ 2/1 → 13/6 | note:c fmi:4 fmdecay:0.1 fmsustain:0.5 ]",
|
||||
"[ 13/6 → 7/3 | note:e fmi:4 fmdecay:0.1 fmsustain:0.5 ]",
|
||||
"[ 7/3 → 5/2 | note:g fmi:4 fmdecay:0.1 fmsustain:0.5 ]",
|
||||
"[ 5/2 → 8/3 | note:b fmi:4 fmdecay:0.1 fmsustain:0.5 ]",
|
||||
"[ 8/3 → 17/6 | note:g fmi:4 fmdecay:0.1 fmsustain:0.5 ]",
|
||||
"[ 17/6 → 3/1 | note:e fmi:4 fmdecay:0.1 fmsustain:0.5 ]",
|
||||
"[ 3/1 → 19/6 | note:c fmi:4 fmdecay:0.1 fmsustain:0 ]",
|
||||
"[ 19/6 → 10/3 | note:e fmi:4 fmdecay:0.1 fmsustain:0 ]",
|
||||
"[ 10/3 → 7/2 | note:g fmi:4 fmdecay:0.1 fmsustain:0 ]",
|
||||
"[ 7/2 → 11/3 | note:b fmi:4 fmdecay:0.1 fmsustain:0 ]",
|
||||
"[ 11/3 → 23/6 | note:g fmi:4 fmdecay:0.1 fmsustain:0 ]",
|
||||
"[ 23/6 → 4/1 | note:e fmi:4 fmdecay:0.1 fmsustain:0 ]",
|
||||
]
|
||||
`;
|
||||
|
||||
@ -4042,19 +4042,19 @@ exports[`runs examples > example "loopAtCps" example index 0 1`] = `
|
||||
|
||||
exports[`runs examples > example "loopBegin" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/1 | s:space loop:1 loopBegin:0 analyze:1 ]",
|
||||
"[ 1/1 → 2/1 | s:space loop:1 loopBegin:0.125 analyze:1 ]",
|
||||
"[ 2/1 → 3/1 | s:space loop:1 loopBegin:0.25 analyze:1 ]",
|
||||
"[ 3/1 → 4/1 | s:space loop:1 loopBegin:0 analyze:1 ]",
|
||||
"[ 0/1 → 1/1 | s:space loop:1 loopBegin:0 ]",
|
||||
"[ 1/1 → 2/1 | s:space loop:1 loopBegin:0.125 ]",
|
||||
"[ 2/1 → 3/1 | s:space loop:1 loopBegin:0.25 ]",
|
||||
"[ 3/1 → 4/1 | s:space loop:1 loopBegin:0 ]",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "loopEnd" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/1 | s:space loop:1 loopEnd:1 analyze:1 ]",
|
||||
"[ 1/1 → 2/1 | s:space loop:1 loopEnd:0.75 analyze:1 ]",
|
||||
"[ 2/1 → 3/1 | s:space loop:1 loopEnd:0.5 analyze:1 ]",
|
||||
"[ 3/1 → 4/1 | s:space loop:1 loopEnd:0.25 analyze:1 ]",
|
||||
"[ 0/1 → 1/1 | s:space loop:1 loopEnd:1 ]",
|
||||
"[ 1/1 → 2/1 | s:space loop:1 loopEnd:0.75 ]",
|
||||
"[ 2/1 → 3/1 | s:space loop:1 loopEnd:0.5 ]",
|
||||
"[ 3/1 → 4/1 | s:space loop:1 loopEnd:0.25 ]",
|
||||
]
|
||||
`;
|
||||
|
||||
@ -5085,34 +5085,34 @@ exports[`runs examples > example "phasersweep" example index 0 1`] = `
|
||||
|
||||
exports[`runs examples > example "pianoroll" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/8 | note:C2 s:piano clip:1 color:salmon ]",
|
||||
"[ (1/4 → 1/3) ⇝ 3/8 | note:C2 s:piano clip:1 color:salmon ]",
|
||||
"[ 1/4 ⇜ (1/3 → 3/8) | note:A2 s:piano clip:1 color:salmon ]",
|
||||
"[ 3/8 → 1/2 | note:A2 s:piano clip:1 color:salmon ]",
|
||||
"[ (5/8 → 2/3) ⇝ 3/4 | note:A2 s:piano clip:1 color:salmon ]",
|
||||
"[ 5/8 ⇜ (2/3 → 3/4) | note:G2 s:piano clip:1 color:salmon ]",
|
||||
"[ 3/4 → 7/8 | note:G2 s:piano clip:1 color:salmon ]",
|
||||
"[ 1/1 → 9/8 | note:C2 s:piano clip:1 color:salmon ]",
|
||||
"[ (5/4 → 4/3) ⇝ 11/8 | note:C2 s:piano clip:1 color:salmon ]",
|
||||
"[ 5/4 ⇜ (4/3 → 11/8) | note:A2 s:piano clip:1 color:salmon ]",
|
||||
"[ 11/8 → 3/2 | note:A2 s:piano clip:1 color:salmon ]",
|
||||
"[ (13/8 → 5/3) ⇝ 7/4 | note:A2 s:piano clip:1 color:salmon ]",
|
||||
"[ 13/8 ⇜ (5/3 → 7/4) | note:G2 s:piano clip:1 color:salmon ]",
|
||||
"[ 7/4 → 15/8 | note:G2 s:piano clip:1 color:salmon ]",
|
||||
"[ 2/1 → 17/8 | note:C2 s:piano clip:1 color:salmon ]",
|
||||
"[ (9/4 → 7/3) ⇝ 19/8 | note:C2 s:piano clip:1 color:salmon ]",
|
||||
"[ 9/4 ⇜ (7/3 → 19/8) | note:A2 s:piano clip:1 color:salmon ]",
|
||||
"[ 19/8 → 5/2 | note:A2 s:piano clip:1 color:salmon ]",
|
||||
"[ (21/8 → 8/3) ⇝ 11/4 | note:A2 s:piano clip:1 color:salmon ]",
|
||||
"[ 21/8 ⇜ (8/3 → 11/4) | note:G2 s:piano clip:1 color:salmon ]",
|
||||
"[ 11/4 → 23/8 | note:G2 s:piano clip:1 color:salmon ]",
|
||||
"[ 3/1 → 25/8 | note:C2 s:piano clip:1 color:salmon ]",
|
||||
"[ (13/4 → 10/3) ⇝ 27/8 | note:C2 s:piano clip:1 color:salmon ]",
|
||||
"[ 13/4 ⇜ (10/3 → 27/8) | note:A2 s:piano clip:1 color:salmon ]",
|
||||
"[ 27/8 → 7/2 | note:A2 s:piano clip:1 color:salmon ]",
|
||||
"[ (29/8 → 11/3) ⇝ 15/4 | note:A2 s:piano clip:1 color:salmon ]",
|
||||
"[ 29/8 ⇜ (11/3 → 15/4) | note:G2 s:piano clip:1 color:salmon ]",
|
||||
"[ 15/4 → 31/8 | note:G2 s:piano clip:1 color:salmon ]",
|
||||
"[ 0/1 → 1/8 | note:c2 s:sawtooth lpenv:4 cutoff:300 ]",
|
||||
"[ (1/4 → 1/3) ⇝ 3/8 | note:c2 s:sawtooth lpenv:4 cutoff:300 ]",
|
||||
"[ 1/4 ⇜ (1/3 → 3/8) | note:a2 s:sawtooth lpenv:4 cutoff:300 ]",
|
||||
"[ 3/8 → 1/2 | note:a2 s:sawtooth lpenv:4 cutoff:300 ]",
|
||||
"[ (5/8 → 2/3) ⇝ 3/4 | note:a2 s:sawtooth lpenv:4 cutoff:300 ]",
|
||||
"[ 5/8 ⇜ (2/3 → 3/4) | note:eb2 s:sawtooth lpenv:4 cutoff:300 ]",
|
||||
"[ 3/4 → 7/8 | note:eb2 s:sawtooth lpenv:4 cutoff:300 ]",
|
||||
"[ 1/1 → 9/8 | note:c2 s:sawtooth lpenv:4 cutoff:300 ]",
|
||||
"[ (5/4 → 4/3) ⇝ 11/8 | note:c2 s:sawtooth lpenv:4 cutoff:300 ]",
|
||||
"[ 5/4 ⇜ (4/3 → 11/8) | note:a2 s:sawtooth lpenv:4 cutoff:300 ]",
|
||||
"[ 11/8 → 3/2 | note:a2 s:sawtooth lpenv:4 cutoff:300 ]",
|
||||
"[ (13/8 → 5/3) ⇝ 7/4 | note:a2 s:sawtooth lpenv:4 cutoff:300 ]",
|
||||
"[ 13/8 ⇜ (5/3 → 7/4) | note:eb2 s:sawtooth lpenv:4 cutoff:300 ]",
|
||||
"[ 7/4 → 15/8 | note:eb2 s:sawtooth lpenv:4 cutoff:300 ]",
|
||||
"[ 2/1 → 17/8 | note:c2 s:sawtooth lpenv:4 cutoff:300 ]",
|
||||
"[ (9/4 → 7/3) ⇝ 19/8 | note:c2 s:sawtooth lpenv:4 cutoff:300 ]",
|
||||
"[ 9/4 ⇜ (7/3 → 19/8) | note:a2 s:sawtooth lpenv:4 cutoff:300 ]",
|
||||
"[ 19/8 → 5/2 | note:a2 s:sawtooth lpenv:4 cutoff:300 ]",
|
||||
"[ (21/8 → 8/3) ⇝ 11/4 | note:a2 s:sawtooth lpenv:4 cutoff:300 ]",
|
||||
"[ 21/8 ⇜ (8/3 → 11/4) | note:eb2 s:sawtooth lpenv:4 cutoff:300 ]",
|
||||
"[ 11/4 → 23/8 | note:eb2 s:sawtooth lpenv:4 cutoff:300 ]",
|
||||
"[ 3/1 → 25/8 | note:c2 s:sawtooth lpenv:4 cutoff:300 ]",
|
||||
"[ (13/4 → 10/3) ⇝ 27/8 | note:c2 s:sawtooth lpenv:4 cutoff:300 ]",
|
||||
"[ 13/4 ⇜ (10/3 → 27/8) | note:a2 s:sawtooth lpenv:4 cutoff:300 ]",
|
||||
"[ 27/8 → 7/2 | note:a2 s:sawtooth lpenv:4 cutoff:300 ]",
|
||||
"[ (29/8 → 11/3) ⇝ 15/4 | note:a2 s:sawtooth lpenv:4 cutoff:300 ]",
|
||||
"[ 29/8 ⇜ (11/3 → 15/4) | note:eb2 s:sawtooth lpenv:4 cutoff:300 ]",
|
||||
"[ 15/4 → 31/8 | note:eb2 s:sawtooth lpenv:4 cutoff:300 ]",
|
||||
]
|
||||
`;
|
||||
|
||||
@ -5234,6 +5234,63 @@ exports[`runs examples > example "pickF" example index 1 1`] = `
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "pitchwheel" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/13 | note:C3 s:sawtooth cutoff:500 ]",
|
||||
"[ 1/13 → 2/13 | note:Db3 s:sawtooth cutoff:500 ]",
|
||||
"[ 2/13 → 3/13 | note:D3 s:sawtooth cutoff:500 ]",
|
||||
"[ 3/13 → 4/13 | note:Eb3 s:sawtooth cutoff:500 ]",
|
||||
"[ 4/13 → 5/13 | note:E3 s:sawtooth cutoff:500 ]",
|
||||
"[ 5/13 → 6/13 | note:F3 s:sawtooth cutoff:500 ]",
|
||||
"[ 6/13 → 7/13 | note:Gb3 s:sawtooth cutoff:500 ]",
|
||||
"[ 7/13 → 8/13 | note:G3 s:sawtooth cutoff:500 ]",
|
||||
"[ 8/13 → 9/13 | note:Ab3 s:sawtooth cutoff:500 ]",
|
||||
"[ 9/13 → 10/13 | note:A3 s:sawtooth cutoff:500 ]",
|
||||
"[ 10/13 → 11/13 | note:Bb3 s:sawtooth cutoff:500 ]",
|
||||
"[ 11/13 → 12/13 | note:B3 s:sawtooth cutoff:500 ]",
|
||||
"[ 12/13 → 1/1 | note:C4 s:sawtooth cutoff:500 ]",
|
||||
"[ 1/1 → 14/13 | note:C3 s:sawtooth cutoff:500 ]",
|
||||
"[ 14/13 → 15/13 | note:Db3 s:sawtooth cutoff:500 ]",
|
||||
"[ 15/13 → 16/13 | note:D3 s:sawtooth cutoff:500 ]",
|
||||
"[ 16/13 → 17/13 | note:Eb3 s:sawtooth cutoff:500 ]",
|
||||
"[ 17/13 → 18/13 | note:E3 s:sawtooth cutoff:500 ]",
|
||||
"[ 18/13 → 19/13 | note:F3 s:sawtooth cutoff:500 ]",
|
||||
"[ 19/13 → 20/13 | note:Gb3 s:sawtooth cutoff:500 ]",
|
||||
"[ 20/13 → 21/13 | note:G3 s:sawtooth cutoff:500 ]",
|
||||
"[ 21/13 → 22/13 | note:Ab3 s:sawtooth cutoff:500 ]",
|
||||
"[ 22/13 → 23/13 | note:A3 s:sawtooth cutoff:500 ]",
|
||||
"[ 23/13 → 24/13 | note:Bb3 s:sawtooth cutoff:500 ]",
|
||||
"[ 24/13 → 25/13 | note:B3 s:sawtooth cutoff:500 ]",
|
||||
"[ 25/13 → 2/1 | note:C4 s:sawtooth cutoff:500 ]",
|
||||
"[ 2/1 → 27/13 | note:C3 s:sawtooth cutoff:500 ]",
|
||||
"[ 27/13 → 28/13 | note:Db3 s:sawtooth cutoff:500 ]",
|
||||
"[ 28/13 → 29/13 | note:D3 s:sawtooth cutoff:500 ]",
|
||||
"[ 29/13 → 30/13 | note:Eb3 s:sawtooth cutoff:500 ]",
|
||||
"[ 30/13 → 31/13 | note:E3 s:sawtooth cutoff:500 ]",
|
||||
"[ 31/13 → 32/13 | note:F3 s:sawtooth cutoff:500 ]",
|
||||
"[ 32/13 → 33/13 | note:Gb3 s:sawtooth cutoff:500 ]",
|
||||
"[ 33/13 → 34/13 | note:G3 s:sawtooth cutoff:500 ]",
|
||||
"[ 34/13 → 35/13 | note:Ab3 s:sawtooth cutoff:500 ]",
|
||||
"[ 35/13 → 36/13 | note:A3 s:sawtooth cutoff:500 ]",
|
||||
"[ 36/13 → 37/13 | note:Bb3 s:sawtooth cutoff:500 ]",
|
||||
"[ 37/13 → 38/13 | note:B3 s:sawtooth cutoff:500 ]",
|
||||
"[ 38/13 → 3/1 | note:C4 s:sawtooth cutoff:500 ]",
|
||||
"[ 3/1 → 40/13 | note:C3 s:sawtooth cutoff:500 ]",
|
||||
"[ 40/13 → 41/13 | note:Db3 s:sawtooth cutoff:500 ]",
|
||||
"[ 41/13 → 42/13 | note:D3 s:sawtooth cutoff:500 ]",
|
||||
"[ 42/13 → 43/13 | note:Eb3 s:sawtooth cutoff:500 ]",
|
||||
"[ 43/13 → 44/13 | note:E3 s:sawtooth cutoff:500 ]",
|
||||
"[ 44/13 → 45/13 | note:F3 s:sawtooth cutoff:500 ]",
|
||||
"[ 45/13 → 46/13 | note:Gb3 s:sawtooth cutoff:500 ]",
|
||||
"[ 46/13 → 47/13 | note:G3 s:sawtooth cutoff:500 ]",
|
||||
"[ 47/13 → 48/13 | note:Ab3 s:sawtooth cutoff:500 ]",
|
||||
"[ 48/13 → 49/13 | note:A3 s:sawtooth cutoff:500 ]",
|
||||
"[ 49/13 → 50/13 | note:Bb3 s:sawtooth cutoff:500 ]",
|
||||
"[ 50/13 → 51/13 | note:B3 s:sawtooth cutoff:500 ]",
|
||||
"[ 51/13 → 4/1 | note:C4 s:sawtooth cutoff:500 ]",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "ply" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/4 | s:bd ]",
|
||||
@ -6196,67 +6253,67 @@ exports[`runs examples > example "s_cat" example index 1 1`] = `
|
||||
|
||||
exports[`runs examples > example "s_polymeter" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/3 | c ]",
|
||||
"[ 0/1 → 1/3 | c2 ]",
|
||||
"[ 1/3 → 2/3 | eb ]",
|
||||
"[ 1/3 → 2/3 | g2 ]",
|
||||
"[ 2/3 → 1/1 | g ]",
|
||||
"[ 2/3 → 1/1 | c2 ]",
|
||||
"[ 1/1 → 4/3 | c ]",
|
||||
"[ 1/1 → 4/3 | g2 ]",
|
||||
"[ 4/3 → 5/3 | eb ]",
|
||||
"[ 4/3 → 5/3 | c2 ]",
|
||||
"[ 5/3 → 2/1 | g ]",
|
||||
"[ 5/3 → 2/1 | g2 ]",
|
||||
"[ 2/1 → 7/3 | c ]",
|
||||
"[ 2/1 → 7/3 | c2 ]",
|
||||
"[ 7/3 → 8/3 | eb ]",
|
||||
"[ 7/3 → 8/3 | g2 ]",
|
||||
"[ 8/3 → 3/1 | g ]",
|
||||
"[ 8/3 → 3/1 | c2 ]",
|
||||
"[ 3/1 → 10/3 | c ]",
|
||||
"[ 3/1 → 10/3 | g2 ]",
|
||||
"[ 10/3 → 11/3 | eb ]",
|
||||
"[ 10/3 → 11/3 | c2 ]",
|
||||
"[ 11/3 → 4/1 | g ]",
|
||||
"[ 11/3 → 4/1 | g2 ]",
|
||||
"[ 0/1 → 1/3 | note:c ]",
|
||||
"[ 0/1 → 1/3 | note:c2 ]",
|
||||
"[ 1/3 → 2/3 | note:eb ]",
|
||||
"[ 1/3 → 2/3 | note:g2 ]",
|
||||
"[ 2/3 → 1/1 | note:g ]",
|
||||
"[ 2/3 → 1/1 | note:c2 ]",
|
||||
"[ 1/1 → 4/3 | note:c ]",
|
||||
"[ 1/1 → 4/3 | note:g2 ]",
|
||||
"[ 4/3 → 5/3 | note:eb ]",
|
||||
"[ 4/3 → 5/3 | note:c2 ]",
|
||||
"[ 5/3 → 2/1 | note:g ]",
|
||||
"[ 5/3 → 2/1 | note:g2 ]",
|
||||
"[ 2/1 → 7/3 | note:c ]",
|
||||
"[ 2/1 → 7/3 | note:c2 ]",
|
||||
"[ 7/3 → 8/3 | note:eb ]",
|
||||
"[ 7/3 → 8/3 | note:g2 ]",
|
||||
"[ 8/3 → 3/1 | note:g ]",
|
||||
"[ 8/3 → 3/1 | note:c2 ]",
|
||||
"[ 3/1 → 10/3 | note:c ]",
|
||||
"[ 3/1 → 10/3 | note:g2 ]",
|
||||
"[ 10/3 → 11/3 | note:eb ]",
|
||||
"[ 10/3 → 11/3 | note:c2 ]",
|
||||
"[ 11/3 → 4/1 | note:g ]",
|
||||
"[ 11/3 → 4/1 | note:g2 ]",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "s_polymeterSteps" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/4 | c ]",
|
||||
"[ 0/1 → 1/4 | e ]",
|
||||
"[ 1/4 → 1/2 | d ]",
|
||||
"[ 1/4 → 1/2 | f ]",
|
||||
"[ 1/2 → 3/4 | c ]",
|
||||
"[ 1/2 → 3/4 | g ]",
|
||||
"[ 3/4 → 1/1 | d ]",
|
||||
"[ 3/4 → 1/1 | e ]",
|
||||
"[ 1/1 → 5/4 | c ]",
|
||||
"[ 1/1 → 5/4 | f ]",
|
||||
"[ 5/4 → 3/2 | d ]",
|
||||
"[ 5/4 → 3/2 | g ]",
|
||||
"[ 3/2 → 7/4 | c ]",
|
||||
"[ 3/2 → 7/4 | e ]",
|
||||
"[ 7/4 → 2/1 | d ]",
|
||||
"[ 7/4 → 2/1 | f ]",
|
||||
"[ 2/1 → 9/4 | c ]",
|
||||
"[ 2/1 → 9/4 | g ]",
|
||||
"[ 9/4 → 5/2 | d ]",
|
||||
"[ 9/4 → 5/2 | e ]",
|
||||
"[ 5/2 → 11/4 | c ]",
|
||||
"[ 5/2 → 11/4 | f ]",
|
||||
"[ 11/4 → 3/1 | d ]",
|
||||
"[ 11/4 → 3/1 | g ]",
|
||||
"[ 3/1 → 13/4 | c ]",
|
||||
"[ 3/1 → 13/4 | e ]",
|
||||
"[ 13/4 → 7/2 | d ]",
|
||||
"[ 13/4 → 7/2 | f ]",
|
||||
"[ 7/2 → 15/4 | c ]",
|
||||
"[ 7/2 → 15/4 | g ]",
|
||||
"[ 15/4 → 4/1 | d ]",
|
||||
"[ 15/4 → 4/1 | e ]",
|
||||
"[ 0/1 → 1/4 | note:c ]",
|
||||
"[ 0/1 → 1/4 | note:e ]",
|
||||
"[ 1/4 → 1/2 | note:d ]",
|
||||
"[ 1/4 → 1/2 | note:f ]",
|
||||
"[ 1/2 → 3/4 | note:c ]",
|
||||
"[ 1/2 → 3/4 | note:g ]",
|
||||
"[ 3/4 → 1/1 | note:d ]",
|
||||
"[ 3/4 → 1/1 | note:e ]",
|
||||
"[ 1/1 → 5/4 | note:c ]",
|
||||
"[ 1/1 → 5/4 | note:f ]",
|
||||
"[ 5/4 → 3/2 | note:d ]",
|
||||
"[ 5/4 → 3/2 | note:g ]",
|
||||
"[ 3/2 → 7/4 | note:c ]",
|
||||
"[ 3/2 → 7/4 | note:e ]",
|
||||
"[ 7/4 → 2/1 | note:d ]",
|
||||
"[ 7/4 → 2/1 | note:f ]",
|
||||
"[ 2/1 → 9/4 | note:c ]",
|
||||
"[ 2/1 → 9/4 | note:g ]",
|
||||
"[ 9/4 → 5/2 | note:d ]",
|
||||
"[ 9/4 → 5/2 | note:e ]",
|
||||
"[ 5/2 → 11/4 | note:c ]",
|
||||
"[ 5/2 → 11/4 | note:f ]",
|
||||
"[ 11/4 → 3/1 | note:d ]",
|
||||
"[ 11/4 → 3/1 | note:g ]",
|
||||
"[ 3/1 → 13/4 | note:c ]",
|
||||
"[ 3/1 → 13/4 | note:e ]",
|
||||
"[ 13/4 → 7/2 | note:d ]",
|
||||
"[ 13/4 → 7/2 | note:f ]",
|
||||
"[ 7/2 → 15/4 | note:c ]",
|
||||
"[ 7/2 → 15/4 | note:g ]",
|
||||
"[ 15/4 → 4/1 | note:d ]",
|
||||
"[ 15/4 → 4/1 | note:e ]",
|
||||
]
|
||||
`;
|
||||
|
||||
@ -6554,10 +6611,10 @@ exports[`runs examples > example "scaleTranspose" example index 0 1`] = `
|
||||
|
||||
exports[`runs examples > example "scope" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/1 | s:sawtooth analyze:1 ]",
|
||||
"[ 1/1 → 2/1 | s:sawtooth analyze:1 ]",
|
||||
"[ 2/1 → 3/1 | s:sawtooth analyze:1 ]",
|
||||
"[ 3/1 → 4/1 | s:sawtooth analyze:1 ]",
|
||||
"[ 0/1 → 1/1 | s:sawtooth ]",
|
||||
"[ 1/1 → 2/1 | s:sawtooth ]",
|
||||
"[ 2/1 → 3/1 | s:sawtooth ]",
|
||||
"[ 3/1 → 4/1 | s:sawtooth ]",
|
||||
]
|
||||
`;
|
||||
|
||||
@ -7158,6 +7215,39 @@ exports[`runs examples > example "speed" example index 1 1`] = `
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "spiral" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/8 | note:c2 s:sawtooth lpenv:4 cutoff:300 ]",
|
||||
"[ (1/4 → 1/3) ⇝ 3/8 | note:c2 s:sawtooth lpenv:4 cutoff:300 ]",
|
||||
"[ 1/4 ⇜ (1/3 → 3/8) | note:a2 s:sawtooth lpenv:4 cutoff:300 ]",
|
||||
"[ 3/8 → 1/2 | note:a2 s:sawtooth lpenv:4 cutoff:300 ]",
|
||||
"[ (5/8 → 2/3) ⇝ 3/4 | note:a2 s:sawtooth lpenv:4 cutoff:300 ]",
|
||||
"[ 5/8 ⇜ (2/3 → 3/4) | note:eb2 s:sawtooth lpenv:4 cutoff:300 ]",
|
||||
"[ 3/4 → 7/8 | note:eb2 s:sawtooth lpenv:4 cutoff:300 ]",
|
||||
"[ 1/1 → 9/8 | note:c2 s:sawtooth lpenv:4 cutoff:300 ]",
|
||||
"[ (5/4 → 4/3) ⇝ 11/8 | note:c2 s:sawtooth lpenv:4 cutoff:300 ]",
|
||||
"[ 5/4 ⇜ (4/3 → 11/8) | note:a2 s:sawtooth lpenv:4 cutoff:300 ]",
|
||||
"[ 11/8 → 3/2 | note:a2 s:sawtooth lpenv:4 cutoff:300 ]",
|
||||
"[ (13/8 → 5/3) ⇝ 7/4 | note:a2 s:sawtooth lpenv:4 cutoff:300 ]",
|
||||
"[ 13/8 ⇜ (5/3 → 7/4) | note:eb2 s:sawtooth lpenv:4 cutoff:300 ]",
|
||||
"[ 7/4 → 15/8 | note:eb2 s:sawtooth lpenv:4 cutoff:300 ]",
|
||||
"[ 2/1 → 17/8 | note:c2 s:sawtooth lpenv:4 cutoff:300 ]",
|
||||
"[ (9/4 → 7/3) ⇝ 19/8 | note:c2 s:sawtooth lpenv:4 cutoff:300 ]",
|
||||
"[ 9/4 ⇜ (7/3 → 19/8) | note:a2 s:sawtooth lpenv:4 cutoff:300 ]",
|
||||
"[ 19/8 → 5/2 | note:a2 s:sawtooth lpenv:4 cutoff:300 ]",
|
||||
"[ (21/8 → 8/3) ⇝ 11/4 | note:a2 s:sawtooth lpenv:4 cutoff:300 ]",
|
||||
"[ 21/8 ⇜ (8/3 → 11/4) | note:eb2 s:sawtooth lpenv:4 cutoff:300 ]",
|
||||
"[ 11/4 → 23/8 | note:eb2 s:sawtooth lpenv:4 cutoff:300 ]",
|
||||
"[ 3/1 → 25/8 | note:c2 s:sawtooth lpenv:4 cutoff:300 ]",
|
||||
"[ (13/4 → 10/3) ⇝ 27/8 | note:c2 s:sawtooth lpenv:4 cutoff:300 ]",
|
||||
"[ 13/4 ⇜ (10/3 → 27/8) | note:a2 s:sawtooth lpenv:4 cutoff:300 ]",
|
||||
"[ 27/8 → 7/2 | note:a2 s:sawtooth lpenv:4 cutoff:300 ]",
|
||||
"[ (29/8 → 11/3) ⇝ 15/4 | note:a2 s:sawtooth lpenv:4 cutoff:300 ]",
|
||||
"[ 29/8 ⇜ (11/3 → 15/4) | note:eb2 s:sawtooth lpenv:4 cutoff:300 ]",
|
||||
"[ 15/4 → 31/8 | note:eb2 s:sawtooth lpenv:4 cutoff:300 ]",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`runs examples > example "splice" example index 0 1`] = `
|
||||
[
|
||||
"[ 0/1 → 1/8 | speed:1 unit:c begin:0 end:0.125 _slices:8 s:breaks165 ]",
|
||||
|
||||
@ -122,6 +122,19 @@ strudel.Pattern.prototype.midi = function () {
|
||||
return this;
|
||||
};
|
||||
|
||||
strudel.Pattern.prototype._scope = function () {
|
||||
return this;
|
||||
};
|
||||
strudel.Pattern.prototype._spiral = function () {
|
||||
return this;
|
||||
};
|
||||
strudel.Pattern.prototype._pitchwheel = function () {
|
||||
return this;
|
||||
};
|
||||
strudel.Pattern.prototype._pianoroll = function () {
|
||||
return this;
|
||||
};
|
||||
|
||||
const uiHelpersMocked = {
|
||||
backgroundImage: id,
|
||||
};
|
||||
|
||||
@ -78,6 +78,7 @@ export const SIDEBAR: Sidebar = {
|
||||
More: [
|
||||
{ text: 'Recipes', link: 'recipes/recipes' },
|
||||
{ text: 'Mini-Notation', link: 'learn/mini-notation' },
|
||||
{ text: 'Visual Feedback', link: 'learn/visual-feedback' },
|
||||
{ text: 'Offline', link: 'learn/pwa' },
|
||||
{ text: 'Patterns', link: 'technical-manual/patterns' },
|
||||
{ text: 'Music metadata', link: 'learn/metadata' },
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
import { useState, useRef, useCallback, useMemo, useEffect } from 'react';
|
||||
import { Icon } from './Icon';
|
||||
import { silence, noteToMidi, _mod } from '@strudel/core';
|
||||
import { getPunchcardPainter } from '@strudel/draw';
|
||||
import { clearHydra } from '@strudel/hydra';
|
||||
import { getDrawContext, getPunchcardPainter } from '@strudel/draw';
|
||||
import { transpiler } from '@strudel/transpiler';
|
||||
import { getAudioContext, webaudioOutput, initAudioOnFirstClick } from '@strudel/webaudio';
|
||||
import { StrudelMirror } from '@strudel/codemirror';
|
||||
@ -28,24 +29,29 @@ export function MiniRepl({
|
||||
claviature,
|
||||
claviatureLabels,
|
||||
maxHeight,
|
||||
autodraw,
|
||||
drawTime,
|
||||
}) {
|
||||
const code = tunes ? tunes[0] : tune;
|
||||
const id = useMemo(() => s4(), []);
|
||||
const canvasId = useMemo(() => `canvas-${id}`, [id]);
|
||||
const shouldDraw = !!punchcard || !!claviature;
|
||||
const shouldShowCanvas = !!punchcard;
|
||||
const drawTime = punchcard ? [0, 4] : [0, 0];
|
||||
const canvasId = shouldShowCanvas ? useMemo(() => `canvas-${id}`, [id]) : null;
|
||||
autodraw = !!punchcard || !!claviature || !!autodraw;
|
||||
drawTime = drawTime ?? punchcard ? [0, 4] : [-2, 2];
|
||||
if (claviature) {
|
||||
drawTime = [0, 0];
|
||||
}
|
||||
const [activeNotes, setActiveNotes] = useState([]);
|
||||
|
||||
const init = useCallback(({ code, shouldDraw }) => {
|
||||
const drawContext = shouldDraw ? document.querySelector('#' + canvasId)?.getContext('2d') : null;
|
||||
const init = useCallback(({ code, autodraw }) => {
|
||||
const drawContext = canvasId ? document.querySelector('#' + canvasId)?.getContext('2d') : getDrawContext();
|
||||
|
||||
const editor = new StrudelMirror({
|
||||
id,
|
||||
defaultOutput: webaudioOutput,
|
||||
getTime: () => getAudioContext().currentTime,
|
||||
transpiler,
|
||||
autodraw: !!shouldDraw,
|
||||
autodraw,
|
||||
root: containerRef.current,
|
||||
initialCode: '// LOADING',
|
||||
pattern: silence,
|
||||
@ -56,7 +62,7 @@ export function MiniRepl({
|
||||
pat = pat.onTrigger(onTrigger, false);
|
||||
}
|
||||
if (claviature) {
|
||||
editor?.painters.push((ctx, time, haps, drawTime) => {
|
||||
pat = pat.onPaint((ctx, time, haps, drawTime) => {
|
||||
const active = haps
|
||||
.map((hap) => hap.value.note)
|
||||
.filter(Boolean)
|
||||
@ -65,7 +71,7 @@ export function MiniRepl({
|
||||
});
|
||||
}
|
||||
if (punchcard) {
|
||||
editor?.painters.push(getPunchcardPainter({ labels: !!punchcardLabels }));
|
||||
pat = pat.punchcard({ labels: !!punchcardLabels });
|
||||
}
|
||||
return pat;
|
||||
},
|
||||
@ -73,7 +79,12 @@ export function MiniRepl({
|
||||
onUpdateState: (state) => {
|
||||
setReplState({ ...state });
|
||||
},
|
||||
beforeEval: () => audioReady, // not doing this in prebake to make sure viz is drawn
|
||||
onToggle: (playing) => {
|
||||
if (!playing) {
|
||||
clearHydra();
|
||||
}
|
||||
},
|
||||
beforeStart: () => audioReady,
|
||||
afterEval: ({ code }) => setVersionDefaultsFrom(code),
|
||||
});
|
||||
// init settings
|
||||
@ -152,7 +163,7 @@ export function MiniRepl({
|
||||
ref={(el) => {
|
||||
if (!editorRef.current) {
|
||||
containerRef.current = el;
|
||||
init({ code, shouldDraw });
|
||||
init({ code, autodraw });
|
||||
}
|
||||
}}
|
||||
></div>
|
||||
|
||||
@ -11,15 +11,15 @@ import { JsDoc } from '../../docs/JsDoc';
|
||||
The following functions will return a pattern.
|
||||
These are the equivalents used by the Mini Notation:
|
||||
|
||||
| function | mini |
|
||||
| ------------------------------ | ---------------- |
|
||||
| `cat(x, y)` | `"<x y>"` |
|
||||
| `seq(x, y)` | `"x y"` |
|
||||
| `stack(x, y)` | `"x,y"` |
|
||||
| `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` | `"~"` |
|
||||
| function | mini |
|
||||
| -------------------------------- | ---------------- |
|
||||
| `cat(x, y)` | `"<x y>"` |
|
||||
| `seq(x, y)` | `"x y"` |
|
||||
| `stack(x, y)` | `"x,y"` |
|
||||
| `s_cat([3,x],[2,y])` | `"x@3 y@2"` |
|
||||
| `s_polymeter([a, b, c], [x, y])` | `"{a b c, x y}"` |
|
||||
| `s_polymeterSteps(2, x, y, z)` | `"{x y z}%2"` |
|
||||
| `silence` | `"~"` |
|
||||
|
||||
## cat
|
||||
|
||||
@ -45,21 +45,21 @@ As a chained function:
|
||||
|
||||
<JsDoc client:idle name="Pattern.stack" h={0} hideDescription />
|
||||
|
||||
## timeCat
|
||||
## s_cat
|
||||
|
||||
<JsDoc client:idle name="timeCat" h={0} />
|
||||
<JsDoc client:idle name="s_cat" h={0} />
|
||||
|
||||
## arrange
|
||||
|
||||
<JsDoc client:idle name="arrange" h={0} />
|
||||
|
||||
## polymeter
|
||||
## s_polymeter
|
||||
|
||||
<JsDoc client:idle name="polymeter" h={0} />
|
||||
<JsDoc client:idle name="s_polymeter" h={0} />
|
||||
|
||||
## polymeterSteps
|
||||
## s_polymeterSteps
|
||||
|
||||
<JsDoc client:idle name="polymeterSteps" h={0} />
|
||||
<JsDoc client:idle name="s_polymeterSteps" h={0} />
|
||||
|
||||
## silence
|
||||
|
||||
|
||||
@ -18,7 +18,7 @@ The basic waveforms are `sine`, `sawtooth`, `square` and `triangle`, which can b
|
||||
client:idle
|
||||
tune={`note("c2 <eb2 <g2 g1>>".fast(2))
|
||||
.sound("<sawtooth square triangle sine>")
|
||||
.scope()`}
|
||||
._scope()`}
|
||||
/>
|
||||
|
||||
If you don't set a `sound` but a `note` the default value for `sound` is `triangle`!
|
||||
@ -28,23 +28,23 @@ If you don't set a `sound` but a `note` the default value for `sound` is `triang
|
||||
You can also use noise as a source by setting the waveform to: `white`, `pink` or `brown`. These are different
|
||||
flavours of noise, here written from hard to soft.
|
||||
|
||||
<MiniRepl client:idle tune={`sound("<white pink brown>").scope()`} />
|
||||
<MiniRepl client:idle tune={`sound("<white pink brown>")._scope()`} />
|
||||
|
||||
Here's a more musical example of how to use noise for hihats:
|
||||
|
||||
<MiniRepl
|
||||
client:idle
|
||||
tune={`sound("bd*2,<white pink brown>*8")
|
||||
.decay(.04).sustain(0).scope()`}
|
||||
.decay(.04).sustain(0)._scope()`}
|
||||
/>
|
||||
|
||||
Some amount of pink noise can also be added to any oscillator by using the `noise` paremeter:
|
||||
|
||||
<MiniRepl client:idle tune={`note("c3").noise("<0.1 0.25 0.5>").scope()`} />
|
||||
<MiniRepl client:idle tune={`note("c3").noise("<0.1 0.25 0.5>")._scope()`} />
|
||||
|
||||
You can also use the `crackle` type to play some subtle noise crackles. You can control noise amount by using the `density` parameter:
|
||||
|
||||
<MiniRepl client:idle tune={`s("crackle*4").density("<0.01 0.04 0.2 0.5>".slow(2)).scope()`} />
|
||||
<MiniRepl client:idle tune={`s("crackle*4").density("<0.01 0.04 0.2 0.5>".slow(2))._scope()`} />
|
||||
|
||||
### Additive Synthesis
|
||||
|
||||
@ -55,7 +55,7 @@ To tame the harsh sound of the basic waveforms, we can set the `n` control to li
|
||||
tune={`note("c2 <eb2 <g2 g1>>".fast(2))
|
||||
.sound("sawtooth")
|
||||
.n("<32 16 8 4>")
|
||||
.scope()`}
|
||||
._scope()`}
|
||||
/>
|
||||
|
||||
When the `n` control is used on a basic waveform, it defines the number of harmonic partials the sound is getting.
|
||||
@ -65,7 +65,7 @@ You can also set `n` directly in mini notation with `sound`:
|
||||
client:idle
|
||||
tune={`note("c2 <eb2 <g2 g1>>".fast(2))
|
||||
.sound("sawtooth:<32 16 8 4>")
|
||||
.scope()`}
|
||||
._scope()`}
|
||||
/>
|
||||
|
||||
Note for tidal users: `n` in tidal is synonymous to `note` for synths only.
|
||||
@ -119,13 +119,14 @@ Any sample preceded by the `wt_` prefix will be loaded as a wavetable. This mean
|
||||
|
||||
<MiniRepl
|
||||
client:idle
|
||||
tune={`samples('github:Bubobubobubobubo/Dough-Waveforms/main/');
|
||||
|
||||
tune={`samples('bubo:waveforms');
|
||||
note("<[g3,b3,e4]!2 [a3,c3,e4] [b3,d3,f#4]>")
|
||||
.n("<1 2 3 4 5 6 7 8 9 10>/2").room(0.5).size(0.9)
|
||||
.s('wt_flute').velocity(0.25).often(n => n.ply(2))
|
||||
.release(0.125).decay("<0.1 0.25 0.3 0.4>").sustain(0)
|
||||
.cutoff(2000).scope({}).cutoff("<1000 2000 4000>").fast(4)`}
|
||||
.cutoff(2000).cutoff("<1000 2000 4000>").fast(4)
|
||||
._scope()
|
||||
`}
|
||||
/>
|
||||
|
||||
## ZZFX
|
||||
@ -159,7 +160,7 @@ It has 20 parameters in total, here is a snippet that uses all:
|
||||
.tremolo(0) // 0-1 lfo volume modulation amount
|
||||
//.duration(.2) // overwrite strudel event duration
|
||||
//.gain(1) // change volume
|
||||
.scope() // vizualise waveform (not zzfx related)
|
||||
._scope() // vizualise waveform (not zzfx related)
|
||||
`}
|
||||
/>
|
||||
|
||||
|
||||
100
website/src/pages/learn/visual-feedback.mdx
Normal file
100
website/src/pages/learn/visual-feedback.mdx
Normal file
@ -0,0 +1,100 @@
|
||||
---
|
||||
title: Visual Feedback
|
||||
layout: ../../layouts/MainLayout.astro
|
||||
---
|
||||
|
||||
import { MiniRepl } from '../../docs/MiniRepl';
|
||||
import { JsDoc } from '../../docs/JsDoc';
|
||||
|
||||
# Visual Feedback
|
||||
|
||||
There are several function that add visual feedback to your patterns.
|
||||
|
||||
## Mini Notation Highlighting
|
||||
|
||||
When you write mini notation with "double quotes" or \`backticks\`, the active parts of the mini notation will be highlighted:
|
||||
|
||||
<MiniRepl
|
||||
client:idle
|
||||
tune={`n("<0 2 1 3 2>*8")
|
||||
.scale("<A1 D2>/4:minor:pentatonic")
|
||||
.s("supersaw").lpf(300).lpenv("<4 3 2>\*4")`}
|
||||
/>
|
||||
|
||||
You can change the color as well, even pattern it:
|
||||
|
||||
<MiniRepl
|
||||
client:idle
|
||||
tune={`n("<0 2 1 3 2>*8")
|
||||
.scale("<A1 D2>/4:minor:pentatonic")
|
||||
.s("supersaw").lpf(300).lpenv("<4 3 2>*4")
|
||||
.color("cyan magenta")`}
|
||||
/>
|
||||
|
||||
## Global vs Inline Visuals
|
||||
|
||||
The following functions all come with in 2 variants.
|
||||
|
||||
**Without prefix**: renders the visual to the background of the page:
|
||||
|
||||
<MiniRepl client:idle tune={`note("c a f e").color("white").punchcard()`} />
|
||||
|
||||
**With `_` prefix**: renders the visual inside the code. Allows for multiple visuals
|
||||
|
||||
<MiniRepl client:idle tune={`note("c a f e").color("white")._punchcard()`} />
|
||||
|
||||
Here we see the 2 variants for `punchcard`. The same goes for all others below.
|
||||
To improve readability the following demos will all use the inline variant.
|
||||
|
||||
## Punchcard / Pianoroll
|
||||
|
||||
These 2 functions render a pianoroll style visual.
|
||||
The only difference between the 2 is that `pianoroll` will render the pattern directly,
|
||||
while `punchcard` will also take the transformations into account that occur afterwards:
|
||||
|
||||
<MiniRepl
|
||||
client:idle
|
||||
tune={`note("c a f e").color("white")
|
||||
._punchcard()
|
||||
.color("cyan")`}
|
||||
autodraw
|
||||
/>
|
||||
|
||||
Here, the `color` is still visible in the visual, even if it is applied after `_punchcard`.
|
||||
On the contrary, the color is not visible when using `_pianoroll`:
|
||||
|
||||
<MiniRepl
|
||||
client:idle
|
||||
tune={`note("c a f e").color("white")
|
||||
._pianoroll()
|
||||
.color("cyan")`}
|
||||
autodraw
|
||||
/>
|
||||
|
||||
import Box from '@components/Box.astro';
|
||||
|
||||
<br />
|
||||
|
||||
<Box>
|
||||
|
||||
`punchcard` is less resource intensive because it uses the same data as used for the mini notation highlighting.
|
||||
|
||||
</Box>
|
||||
|
||||
The visual can be customized by passing options. Those options are the same for both functions.
|
||||
|
||||
What follows is the API doc of all the options you can pass:
|
||||
|
||||
<JsDoc client:idle name="pianoroll" h={0} />
|
||||
|
||||
## Spiral
|
||||
|
||||
<JsDoc client:idle name="spiral" h={0} />
|
||||
|
||||
## Scope
|
||||
|
||||
<JsDoc client:idle name="scope" h={0} />
|
||||
|
||||
## Pitchwheel
|
||||
|
||||
<JsDoc client:idle name="pitchwheel" h={0} />
|
||||
@ -154,7 +154,7 @@ Can you guess what they do?
|
||||
tune={`stack(
|
||||
note("[~ [<[d3,a3,f4]!2 [d3,bb3,g4]!2> ~]]*2")
|
||||
.sound("gm_electric_guitar_muted"),
|
||||
sound("<bd rim>").bank("RolandTR707")
|
||||
sound("bd rim").bank("RolandTR707")
|
||||
).delay(".5")`}
|
||||
/>
|
||||
|
||||
@ -202,7 +202,7 @@ Add a delay too!
|
||||
tune={`stack(
|
||||
note("[~ [<[d3,a3,f4]!2 [d3,bb3,g4]!2> ~]]*2")
|
||||
.sound("gm_electric_guitar_muted").delay(.5),
|
||||
sound("<bd rim>").bank("RolandTR707").delay(.5),
|
||||
sound("bd rim").bank("RolandTR707").delay(.5),
|
||||
n("<4 [3@3 4] [<2 0> ~@16] ~>")
|
||||
.scale("D4:minor").sound("gm_accordion:2")
|
||||
.room(2).gain(.5)
|
||||
@ -216,7 +216,7 @@ Let's add a bass to make this complete:
|
||||
tune={`stack(
|
||||
note("[~ [<[d3,a3,f4]!2 [d3,bb3,g4]!2> ~]]*2")
|
||||
.sound("gm_electric_guitar_muted").delay(.5),
|
||||
sound("<bd rim>").bank("RolandTR707").delay(.5),
|
||||
sound("bd rim").bank("RolandTR707").delay(.5),
|
||||
n("<4 [3@3 4] [<2 0> ~@16] ~>")
|
||||
.scale("D4:minor").sound("gm_accordion:2")
|
||||
.room(2).gain(.4),
|
||||
@ -266,7 +266,7 @@ By the way, inside Mini-Notation, `fast` is `*` and `slow` is `/`.
|
||||
|
||||
Instead of changing values stepwise, we can also control them with signals:
|
||||
|
||||
<MiniRepl client:visible tune={`sound("hh*32").gain(sine)`} punchcard punchcardLabels={false} />
|
||||
<MiniRepl client:visible tune={`sound("hh*16").gain(sine)`} punchcard punchcardLabels={false} />
|
||||
|
||||
<Box>
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user