Compare commits

..

5 Commits

Author SHA1 Message Date
alex 23c104c1a5 add stepearly/steplate 2025-02-21 09:06:33 +00:00
Alex McLean aabc82bedd Fixes inverted triangle wave by renaming it to itri, making non-inverted tri (#1283)
* add itri / itri2 .. but should tri and itri be swapped??

* swap tri/tri2 with itri/itri2. Add some basic docs for bipolar signals
2025-02-11 15:34:23 +00:00
Alex McLean 84581b22aa Fix for squeezejoin and functions using it, including bite (#1286) 2025-02-11 09:02:34 +00:00
Alex McLean 3575fc3cc8 rename repeat back to extend (#1285) 2025-02-09 15:18:28 +00:00
Alex McLean cf8203a4db mqtt bugfix - connection check (#1282) 2025-02-07 17:11:52 +00:00
11 changed files with 303 additions and 117 deletions
-5
View File
@@ -140,8 +140,3 @@ registerWidget('_spectrum', (id, options = {}, pat) => {
const ctx = getCanvasWidget(id, options).getContext('2d');
return pat.spectrum({ ...options, ctx, id });
});
registerWidget('_cyclecounter', (id, options = {}, pat) => {
const ctx = getCanvasWidget(id, options).getContext('2d');
return pat.cyclecounter({ ...options, ctx, id });
});
+1 -20
View File
@@ -23,8 +23,6 @@ export class Cyclist {
this.beforeStart = beforeStart;
this.cps = 0.5;
this.num_ticks_since_cps_change = 0;
this.loopStart = 0;
this.loopLength = 0;
this.lastTick = 0; // absolute time when last tick (clock callback) happened
this.lastBegin = 0; // query begin of last tick
this.lastEnd = 0; // query end of last tick
@@ -50,10 +48,6 @@ export class Cyclist {
this.lastBegin = begin;
const end = this.num_cycles_at_cps_change + num_cycles_since_cps_change;
this.lastEnd = end;
if (this.loopLength > 0 && this.lastEnd >= this.loopStart + this.loopLength) {
this.lastEnd = this.loopStart + (this.lastEnd % 1);
this.num_ticks_since_cps_change = 0;
}
this.lastTick = phase;
if (phase < t) {
@@ -122,7 +116,7 @@ export class Cyclist {
stop() {
logger('[cyclist] stop');
this.clock.stop();
this.lastEnd = this.loopStart;
this.lastEnd = 0;
this.setStarted(false);
}
async setPattern(pat, autostart = false) {
@@ -138,19 +132,6 @@ export class Cyclist {
this.cps = cps;
this.num_ticks_since_cps_change = 0;
}
setLoop(start = 0, length = 0) {
if (start >= 0 && length >= 0) {
start = Math.floor(start);
length = Math.floor(length);
if (start != this.loopStart || length != this.loopLength) {
this.loopStart = Math.floor(start);
this.loopLength = Math.floor(length);
this.lastEnd = this.loopStart + (this.lastEnd % 1);
this.num_ticks_since_cps_change = 0;
}
}
}
log(begin, end, haps) {
const onsets = haps.filter((h) => h.hasOnset());
console.log(`${begin.toFixed(4)} - ${end.toFixed(4)} ${Array(onsets.length).fill('I').join('')}`);
+34 -8
View File
@@ -388,7 +388,7 @@ export class Pattern {
polyJoin = function () {
const pp = this;
return pp.fmap((p) => p.repeat(pp._steps.div(p._steps))).outerJoin();
return pp.fmap((p) => p.extend(pp._steps.div(p._steps))).outerJoin();
};
polyBind(func) {
@@ -1820,7 +1820,10 @@ export const { fastGap, fastgap } = register(['fastGap', 'fastgap'], function (f
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());
return pat
._early(b.sam())
._fast(Fraction(1).div(e.sub(b)))
._late(b);
});
export const { focusSpan, focusspan } = register(['focusSpan', 'focusspan'], function (span, pat) {
@@ -2771,6 +2774,29 @@ export function stepalt(...groups) {
return result;
}
export const stepearly = register(
'stepearly',
function (t, pat) {
if (!pat._steps) {
return pat;
}
return pat._late(Fraction(t).div(pat._steps));
},
true,
false,
(x) => x.stepJoin(),
);
export const steplate = register(
'steplate',
function (t, pat) {
return pat._stepearly(Fraction(0).sub(t));
},
true,
false,
(x) => x.stepJoin(),
);
/**
* *Experimental*
*
@@ -2845,16 +2871,16 @@ export const drop = stepRegister('drop', function (i, pat) {
/**
* *Experimental*
*
* `repeat` is similar to `fast` in that it 'speeds up' the pattern, but it also increases the step count
* accordingly. So `stepcat("a b".repeat(2), "c d")` would be the same as `"a b a b c d"`, whereas
* `extend` is similar to `fast` in that it increases its density, but it also increases the step count
* accordingly. So `stepcat("a b".extend(2), "c d")` would be the same as `"a b a b c d"`, whereas
* `stepcat("a b".fast(2), "c d")` would be the same as `"[a b] [a b] c d"`.
* @example
* stepcat(
* sound("bd bd - cp").repeat(2),
* sound("bd bd - cp").extend(2),
* sound("bd - sd -")
* ).pace(8)
*/
export const repeat = stepRegister('repeat', function (factor, pat) {
export const extend = stepRegister('extend', function (factor, pat) {
return pat.fast(factor).expand(factor);
});
@@ -3066,8 +3092,8 @@ export const s_sub = drop;
Pattern.prototype.s_sub = Pattern.prototype.drop;
export const s_expand = expand;
Pattern.prototype.s_expand = Pattern.prototype.expand;
export const s_extend = repeat;
Pattern.prototype.s_extend = Pattern.prototype.repeat;
export const s_extend = extend;
Pattern.prototype.s_extend = Pattern.prototype.extend;
export const s_contract = contract;
Pattern.prototype.s_contract = Pattern.prototype.contract;
export const s_tour = tour;
-3
View File
@@ -86,7 +86,6 @@ export function repl({
const toggle = () => scheduler.toggle();
const setCps = (cps) => scheduler.setCps(cps);
const setCpm = (cpm) => scheduler.setCps(cpm / 60);
const setLoop = (start, length) => scheduler.setLoop(start, length);
// TODO - not documented as jsdoc examples as the test framework doesn't simulate enough context for `each` and `all`..
@@ -168,8 +167,6 @@ export function repl({
setcps: setCps,
setCpm,
setcpm: setCpm,
setLoop,
setloop: setLoop,
});
};
+74 -5
View File
@@ -20,9 +20,6 @@ export const signal = (func) => {
return new Pattern(query);
};
export const isaw = signal((t) => 1 - (t % 1));
export const isaw2 = isaw.toBipolar();
/**
* A sawtooth signal between 0 and 1.
*
@@ -36,8 +33,40 @@ export const isaw2 = isaw.toBipolar();
*
*/
export const saw = signal((t) => t % 1);
/**
* A sawtooth signal between -1 and 1 (like `saw`, but bipolar).
*
* @return {Pattern}
*/
export const saw2 = saw.toBipolar();
/**
* A sawtooth signal between 1 and 0 (like `saw`, but flipped).
*
* @return {Pattern}
* @example
* note("<c3 [eb3,g3] g2 [g3,bb3]>*8")
* .clip(isaw.slow(2))
* @example
* n(isaw.range(0,8).segment(8))
* .scale('C major')
*
*/
export const isaw = signal((t) => 1 - (t % 1));
/**
* A sawtooth signal between 1 and -1 (like `saw2`, but flipped).
*
* @return {Pattern}
*/
export const isaw2 = isaw.toBipolar();
/**
* A sine signal between -1 and 1 (like `sine`, but bipolar).
*
* @return {Pattern}
*/
export const sine2 = signal((t) => Math.sin(Math.PI * 2 * t));
/**
@@ -61,6 +90,12 @@ export const sine = sine2.fromBipolar();
*
*/
export const cosine = sine._early(Fraction(1).div(4));
/**
* A cosine signal between -1 and 1 (like `cosine`, but bipolar).
*
* @return {Pattern}
*/
export const cosine2 = sine2._early(Fraction(1).div(4));
/**
@@ -72,6 +107,12 @@ export const cosine2 = sine2._early(Fraction(1).div(4));
*
*/
export const square = signal((t) => Math.floor((t * 2) % 2));
/**
* A square signal between -1 and 1 (like `square`, but bipolar).
*
* @return {Pattern}
*/
export const square2 = square.toBipolar();
/**
@@ -82,9 +123,37 @@ export const square2 = square.toBipolar();
* n(tri.segment(8).range(0,7)).scale("C:minor")
*
*/
export const tri = fastcat(isaw, saw);
export const tri2 = fastcat(isaw2, saw2);
export const tri = fastcat(saw, isaw);
/**
* A triangle signal between -1 and 1 (like `tri`, but bipolar).
*
* @return {Pattern}
*/
export const tri2 = fastcat(saw2, isaw2);
/**
* An inverted triangle signal between 1 and 0 (like `tri`, but flipped).
*
* @return {Pattern}
* @example
* n(itri.segment(8).range(0,7)).scale("C:minor")
*
*/
export const itri = fastcat(isaw, saw);
/**
* An inverted triangle signal between -1 and 1 (like `itri`, but bipolar).
*
* @return {Pattern}
*/
export const itri2 = fastcat(isaw2, saw2);
/**
* A signal representing the cycle time.
*
* @return {Pattern}
*/
export const time = signal(id);
/**
+10
View File
@@ -1265,4 +1265,14 @@ describe('Pattern', () => {
expect(s('bev').chop(8).loopAt(2)._steps).toStrictEqual(Fraction(4));
});
});
describe('bite', () => {
it('works with uneven patterns', () => {
sameFirst(
fastcat(slowcat('a', 'b', 'c', 'd', 'e'), slowcat(1, 2, 3, 4, 5))
.bite(2, stepcat(pure(0), pure(1).expand(2)))
.fast(5),
stepcat(slowcat('a', 'b', 'c', 'd', 'e'), slowcat(1, 2, 3, 4, 5).expand(2)).fast(5),
);
});
});
});
-16
View File
@@ -1,16 +0,0 @@
import { Pattern } from '@strudel/core';
Pattern.prototype.cyclecounter = function (options = {}) {
return this.onPaint((ctx, time, haps, drawTime) => {
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
ctx.font = options.font || '2em monospace';
ctx.fillStyle = options.color || 'red';
ctx.textBaseline = 'bottom';
ctx.textAlign = 'right';
const div = options.div || 1;
ctx.fillText('Cycle' + (div > 1 ? '/' + div : '') + ' ' + ((time / div) >> 0), ctx.canvas.width, ctx.canvas.height);
});
};
-1
View File
@@ -4,4 +4,3 @@ export * from './draw.mjs';
export * from './pianoroll.mjs';
export * from './spiral.mjs';
export * from './pitchwheel.mjs';
export * from './cyclecounter.mjs';
+4 -6
View File
@@ -38,15 +38,10 @@ Pattern.prototype.mqtt = function (
add_meta = true,
) {
const key = host + '-' + client;
let connected = false;
let password_entered = false;
if (!client) {
client = 'strudel-' + String(Math.floor(Math.random() * 1000000));
}
function onConnect() {
console.log('Connected to mqtt broker');
connected = true;
if (password_entered) {
document.cookie = 'mqtt_pass=' + password;
}
@@ -56,6 +51,9 @@ Pattern.prototype.mqtt = function (
if (connections[key]) {
cx = connections[key];
} else {
if (!client) {
client = 'strudel-' + String(Math.floor(Math.random() * 1000000));
}
cx = new Paho.Client(host, client);
connections[key] = cx;
cx.onConnectionLost = onConnectionLost;
@@ -86,7 +84,7 @@ Pattern.prototype.mqtt = function (
return this.withHap((hap) => {
const onTrigger = (t_deprecate, hap, currentTime, cps, targetTime) => {
let msg_topic = topic;
if (!connected) {
if (!cx || !cx.isConnected()) {
return;
}
let message = '';
+178 -51
View File
@@ -3019,6 +3019,33 @@ exports[`runs examples > example "expand" example index 0 1`] = `
]
`;
exports[`runs examples > example "extend" example index 0 1`] = `
[
"[ 0/1 → 1/8 | s:bd ]",
"[ 1/8 → 1/4 | s:bd ]",
"[ 3/8 → 1/2 | s:cp ]",
"[ 1/2 → 5/8 | s:bd ]",
"[ 5/8 → 3/4 | s:bd ]",
"[ 7/8 → 1/1 | s:cp ]",
"[ 1/1 → 9/8 | s:bd ]",
"[ 5/4 → 11/8 | s:sd ]",
"[ 3/2 → 13/8 | s:bd ]",
"[ 13/8 → 7/4 | s:bd ]",
"[ 15/8 → 2/1 | s:cp ]",
"[ 2/1 → 17/8 | s:bd ]",
"[ 17/8 → 9/4 | s:bd ]",
"[ 19/8 → 5/2 | s:cp ]",
"[ 5/2 → 21/8 | s:bd ]",
"[ 11/4 → 23/8 | s:sd ]",
"[ 3/1 → 25/8 | s:bd ]",
"[ 25/8 → 13/4 | s:bd ]",
"[ 27/8 → 7/2 | s:cp ]",
"[ 7/2 → 29/8 | s:bd ]",
"[ 29/8 → 15/4 | s:bd ]",
"[ 31/8 → 4/1 | s:cp ]",
]
`;
exports[`runs examples > example "fanchor" example index 0 1`] = `
[
"[ 0/1 → 1/8 | note:f s:sawtooth cutoff:1000 lpenv:8 fanchor:0 ]",
@@ -4234,6 +4261,96 @@ exports[`runs examples > example "iresponse" example index 0 1`] = `
]
`;
exports[`runs examples > example "isaw" example index 0 1`] = `
[
"[ 0/1 → 1/8 | note:c3 clip:1 ]",
"[ 1/8 → 1/4 | note:eb3 clip:0.9375 ]",
"[ 1/8 → 1/4 | note:g3 clip:0.9375 ]",
"[ 1/4 → 3/8 | note:g2 clip:0.875 ]",
"[ 3/8 → 1/2 | note:g3 clip:0.8125 ]",
"[ 3/8 → 1/2 | note:bb3 clip:0.8125 ]",
"[ 1/2 → 5/8 | note:c3 clip:0.75 ]",
"[ 5/8 → 3/4 | note:eb3 clip:0.6875 ]",
"[ 5/8 → 3/4 | note:g3 clip:0.6875 ]",
"[ 3/4 → 7/8 | note:g2 clip:0.625 ]",
"[ 7/8 → 1/1 | note:g3 clip:0.5625 ]",
"[ 7/8 → 1/1 | note:bb3 clip:0.5625 ]",
"[ 1/1 → 9/8 | note:c3 clip:0.5 ]",
"[ 9/8 → 5/4 | note:eb3 clip:0.4375 ]",
"[ 9/8 → 5/4 | note:g3 clip:0.4375 ]",
"[ 5/4 → 11/8 | note:g2 clip:0.375 ]",
"[ 11/8 → 3/2 | note:g3 clip:0.3125 ]",
"[ 11/8 → 3/2 | note:bb3 clip:0.3125 ]",
"[ 3/2 → 13/8 | note:c3 clip:0.25 ]",
"[ 13/8 → 7/4 | note:eb3 clip:0.1875 ]",
"[ 13/8 → 7/4 | note:g3 clip:0.1875 ]",
"[ 7/4 → 15/8 | note:g2 clip:0.125 ]",
"[ 15/8 → 2/1 | note:g3 clip:0.0625 ]",
"[ 15/8 → 2/1 | note:bb3 clip:0.0625 ]",
"[ 2/1 → 17/8 | note:c3 clip:1 ]",
"[ 17/8 → 9/4 | note:eb3 clip:0.9375 ]",
"[ 17/8 → 9/4 | note:g3 clip:0.9375 ]",
"[ 9/4 → 19/8 | note:g2 clip:0.875 ]",
"[ 19/8 → 5/2 | note:g3 clip:0.8125 ]",
"[ 19/8 → 5/2 | note:bb3 clip:0.8125 ]",
"[ 5/2 → 21/8 | note:c3 clip:0.75 ]",
"[ 21/8 → 11/4 | note:eb3 clip:0.6875 ]",
"[ 21/8 → 11/4 | note:g3 clip:0.6875 ]",
"[ 11/4 → 23/8 | note:g2 clip:0.625 ]",
"[ 23/8 → 3/1 | note:g3 clip:0.5625 ]",
"[ 23/8 → 3/1 | note:bb3 clip:0.5625 ]",
"[ 3/1 → 25/8 | note:c3 clip:0.5 ]",
"[ 25/8 → 13/4 | note:eb3 clip:0.4375 ]",
"[ 25/8 → 13/4 | note:g3 clip:0.4375 ]",
"[ 13/4 → 27/8 | note:g2 clip:0.375 ]",
"[ 27/8 → 7/2 | note:g3 clip:0.3125 ]",
"[ 27/8 → 7/2 | note:bb3 clip:0.3125 ]",
"[ 7/2 → 29/8 | note:c3 clip:0.25 ]",
"[ 29/8 → 15/4 | note:eb3 clip:0.1875 ]",
"[ 29/8 → 15/4 | note:g3 clip:0.1875 ]",
"[ 15/4 → 31/8 | note:g2 clip:0.125 ]",
"[ 31/8 → 4/1 | note:g3 clip:0.0625 ]",
"[ 31/8 → 4/1 | note:bb3 clip:0.0625 ]",
]
`;
exports[`runs examples > example "isaw" example index 1 1`] = `
[
"[ 0/1 → 1/8 | note:D4 ]",
"[ 1/8 → 1/4 | note:C4 ]",
"[ 1/4 → 3/8 | note:B3 ]",
"[ 3/8 → 1/2 | note:A3 ]",
"[ 1/2 → 5/8 | note:G3 ]",
"[ 5/8 → 3/4 | note:F3 ]",
"[ 3/4 → 7/8 | note:E3 ]",
"[ 7/8 → 1/1 | note:D3 ]",
"[ 1/1 → 9/8 | note:D4 ]",
"[ 9/8 → 5/4 | note:C4 ]",
"[ 5/4 → 11/8 | note:B3 ]",
"[ 11/8 → 3/2 | note:A3 ]",
"[ 3/2 → 13/8 | note:G3 ]",
"[ 13/8 → 7/4 | note:F3 ]",
"[ 7/4 → 15/8 | note:E3 ]",
"[ 15/8 → 2/1 | note:D3 ]",
"[ 2/1 → 17/8 | note:D4 ]",
"[ 17/8 → 9/4 | note:C4 ]",
"[ 9/4 → 19/8 | note:B3 ]",
"[ 19/8 → 5/2 | note:A3 ]",
"[ 5/2 → 21/8 | note:G3 ]",
"[ 21/8 → 11/4 | note:F3 ]",
"[ 11/4 → 23/8 | note:E3 ]",
"[ 23/8 → 3/1 | note:D3 ]",
"[ 3/1 → 25/8 | note:D4 ]",
"[ 25/8 → 13/4 | note:C4 ]",
"[ 13/4 → 27/8 | note:B3 ]",
"[ 27/8 → 7/2 | note:A3 ]",
"[ 7/2 → 29/8 | note:G3 ]",
"[ 29/8 → 15/4 | note:F3 ]",
"[ 15/4 → 31/8 | note:E3 ]",
"[ 31/8 → 4/1 | note:D3 ]",
]
`;
exports[`runs examples > example "iter" example index 0 1`] = `
[
"[ 0/1 → 1/4 | note:A3 ]",
@@ -4276,6 +4393,43 @@ exports[`runs examples > example "iterBack" example index 0 1`] = `
]
`;
exports[`runs examples > example "itri" example index 0 1`] = `
[
"[ 0/1 → 1/8 | note:C4 ]",
"[ 1/8 → 1/4 | note:Bb3 ]",
"[ 1/4 → 3/8 | note:G3 ]",
"[ 3/8 → 1/2 | note:Eb3 ]",
"[ 1/2 → 5/8 | note:C3 ]",
"[ 5/8 → 3/4 | note:Eb3 ]",
"[ 3/4 → 7/8 | note:G3 ]",
"[ 7/8 → 1/1 | note:Bb3 ]",
"[ 1/1 → 9/8 | note:C4 ]",
"[ 9/8 → 5/4 | note:Bb3 ]",
"[ 5/4 → 11/8 | note:G3 ]",
"[ 11/8 → 3/2 | note:Eb3 ]",
"[ 3/2 → 13/8 | note:C3 ]",
"[ 13/8 → 7/4 | note:Eb3 ]",
"[ 7/4 → 15/8 | note:G3 ]",
"[ 15/8 → 2/1 | note:Bb3 ]",
"[ 2/1 → 17/8 | note:C4 ]",
"[ 17/8 → 9/4 | note:Bb3 ]",
"[ 9/4 → 19/8 | note:G3 ]",
"[ 19/8 → 5/2 | note:Eb3 ]",
"[ 5/2 → 21/8 | note:C3 ]",
"[ 21/8 → 11/4 | note:Eb3 ]",
"[ 11/4 → 23/8 | note:G3 ]",
"[ 23/8 → 3/1 | note:Bb3 ]",
"[ 3/1 → 25/8 | note:C4 ]",
"[ 25/8 → 13/4 | note:Bb3 ]",
"[ 13/4 → 27/8 | note:G3 ]",
"[ 27/8 → 7/2 | note:Eb3 ]",
"[ 7/2 → 29/8 | note:C3 ]",
"[ 29/8 → 15/4 | note:Eb3 ]",
"[ 15/4 → 31/8 | note:G3 ]",
"[ 31/8 → 4/1 | note:Bb3 ]",
]
`;
exports[`runs examples > example "jux" example index 0 1`] = `
[
"[ 0/1 → 1/8 | s:bd pan:0 ]",
@@ -6490,33 +6644,6 @@ exports[`runs examples > example "release" example index 0 1`] = `
]
`;
exports[`runs examples > example "repeat" example index 0 1`] = `
[
"[ 0/1 → 1/8 | s:bd ]",
"[ 1/8 → 1/4 | s:bd ]",
"[ 3/8 → 1/2 | s:cp ]",
"[ 1/2 → 5/8 | s:bd ]",
"[ 5/8 → 3/4 | s:bd ]",
"[ 7/8 → 1/1 | s:cp ]",
"[ 1/1 → 9/8 | s:bd ]",
"[ 5/4 → 11/8 | s:sd ]",
"[ 3/2 → 13/8 | s:bd ]",
"[ 13/8 → 7/4 | s:bd ]",
"[ 15/8 → 2/1 | s:cp ]",
"[ 2/1 → 17/8 | s:bd ]",
"[ 17/8 → 9/4 | s:bd ]",
"[ 19/8 → 5/2 | s:cp ]",
"[ 5/2 → 21/8 | s:bd ]",
"[ 11/4 → 23/8 | s:sd ]",
"[ 3/1 → 25/8 | s:bd ]",
"[ 25/8 → 13/4 | s:bd ]",
"[ 27/8 → 7/2 | s:cp ]",
"[ 7/2 → 29/8 | s:bd ]",
"[ 29/8 → 15/4 | s:bd ]",
"[ 31/8 → 4/1 | s:cp ]",
]
`;
exports[`runs examples > example "repeatCycles" example index 0 1`] = `
[
"[ 0/1 → 1/4 | note:34 s:gm_acoustic_guitar_nylon ]",
@@ -8999,38 +9126,38 @@ exports[`runs examples > example "transpose" example index 1 1`] = `
exports[`runs examples > example "tri" example index 0 1`] = `
[
"[ 0/1 → 1/8 | note:C4 ]",
"[ 1/8 → 1/4 | note:Bb3 ]",
"[ 0/1 → 1/8 | note:C3 ]",
"[ 1/8 → 1/4 | note:Eb3 ]",
"[ 1/4 → 3/8 | note:G3 ]",
"[ 3/8 → 1/2 | note:Eb3 ]",
"[ 1/2 → 5/8 | note:C3 ]",
"[ 5/8 → 3/4 | note:Eb3 ]",
"[ 3/8 → 1/2 | note:Bb3 ]",
"[ 1/2 → 5/8 | note:C4 ]",
"[ 5/8 → 3/4 | note:Bb3 ]",
"[ 3/4 → 7/8 | note:G3 ]",
"[ 7/8 → 1/1 | note:Bb3 ]",
"[ 1/1 → 9/8 | note:C4 ]",
"[ 9/8 → 5/4 | note:Bb3 ]",
"[ 7/8 → 1/1 | note:Eb3 ]",
"[ 1/1 → 9/8 | note:C3 ]",
"[ 9/8 → 5/4 | note:Eb3 ]",
"[ 5/4 → 11/8 | note:G3 ]",
"[ 11/8 → 3/2 | note:Eb3 ]",
"[ 3/2 → 13/8 | note:C3 ]",
"[ 13/8 → 7/4 | note:Eb3 ]",
"[ 11/8 → 3/2 | note:Bb3 ]",
"[ 3/2 → 13/8 | note:C4 ]",
"[ 13/8 → 7/4 | note:Bb3 ]",
"[ 7/4 → 15/8 | note:G3 ]",
"[ 15/8 → 2/1 | note:Bb3 ]",
"[ 2/1 → 17/8 | note:C4 ]",
"[ 17/8 → 9/4 | note:Bb3 ]",
"[ 15/8 → 2/1 | note:Eb3 ]",
"[ 2/1 → 17/8 | note:C3 ]",
"[ 17/8 → 9/4 | note:Eb3 ]",
"[ 9/4 → 19/8 | note:G3 ]",
"[ 19/8 → 5/2 | note:Eb3 ]",
"[ 5/2 → 21/8 | note:C3 ]",
"[ 21/8 → 11/4 | note:Eb3 ]",
"[ 19/8 → 5/2 | note:Bb3 ]",
"[ 5/2 → 21/8 | note:C4 ]",
"[ 21/8 → 11/4 | note:Bb3 ]",
"[ 11/4 → 23/8 | note:G3 ]",
"[ 23/8 → 3/1 | note:Bb3 ]",
"[ 3/1 → 25/8 | note:C4 ]",
"[ 25/8 → 13/4 | note:Bb3 ]",
"[ 23/8 → 3/1 | note:Eb3 ]",
"[ 3/1 → 25/8 | note:C3 ]",
"[ 25/8 → 13/4 | note:Eb3 ]",
"[ 13/4 → 27/8 | note:G3 ]",
"[ 27/8 → 7/2 | note:Eb3 ]",
"[ 7/2 → 29/8 | note:C3 ]",
"[ 29/8 → 15/4 | note:Eb3 ]",
"[ 27/8 → 7/2 | note:Bb3 ]",
"[ 7/2 → 29/8 | note:C4 ]",
"[ 29/8 → 15/4 | note:Bb3 ]",
"[ 15/4 → 31/8 | note:G3 ]",
"[ 31/8 → 4/1 | note:Bb3 ]",
"[ 31/8 → 4/1 | note:Eb3 ]",
]
`;
+2 -2
View File
@@ -100,9 +100,9 @@ Earlier versions of many of these functions had `s_` prefixes, and the `pace` fu
<JsDoc client:idle name="contract" h={0} />
### repeat
### extend
<JsDoc client:idle name="repeat" h={0} />
<JsDoc client:idle name="extend" h={0} />
### take