From 55095ba4e8306dc07035696a08cff9db9136e132 Mon Sep 17 00:00:00 2001 From: tyow Date: Sun, 1 Feb 2026 13:34:22 -0500 Subject: [PATCH] added examples to ftrans --- packages/xen/xen.mjs | 27 +++++++-- test/__snapshots__/examples.test.mjs.snap | 68 +++++++++++++++++++++++ 2 files changed, 89 insertions(+), 6 deletions(-) diff --git a/packages/xen/xen.mjs b/packages/xen/xen.mjs index 3629e5fe4..bd77f75a6 100644 --- a/packages/xen/xen.mjs +++ b/packages/xen/xen.mjs @@ -59,6 +59,8 @@ function xenOffset(xenScale, offset, index = 0) { return xenScale[i] * Math.pow(2, oct); } +const trimFreq = freq => parseFloat(freq.toPrecision(10)); + // accepts a scale name such as 31edo, and a pattern // pattern expected to follow format such that a value can be mapped // to an edostep within the scale. Returns the pattern with @@ -75,7 +77,7 @@ function xenOffset(xenScale, offset, index = 0) { * @tags tonal * @example * // A minor triad in 31edo: - * "0 8 18".xen("31edo").freq().piano() + * "0 8 18".xen("31edo").piano() * @example * // You can also use xen with frequency ratios. * // This is equivalent to the above: @@ -83,11 +85,11 @@ function xenOffset(xenScale, offset, index = 0) { * Math.pow(2, 0/31), * Math.pow(2, 8/31), * Math.pow(2, 18/31), - * ]).freq().piano() + * ]).piano() * @example * // xen also supports all scale names that * // tune does: - * "0 1 2 3 4 5".xen("hexany15").freq() + * "0 1 2 3 4 5".xen("hexany15") * // equiv to: * // "0 1 2 3 4 5".tune("hexany15").mul("220").freq() */ @@ -104,10 +106,10 @@ export const xen = register('xen', function (scaleNameOrRatios, pat) { hVal = isObject ? hVal : { n: hVal }; const { n, value, ...otherValues } = hVal; const scale = getXenScale(scaleNameOrRatios); - let frequency = xenOffset(scale, parseNumeral(hVal.n)); + let freq = xenOffset(scale, parseNumeral(hVal.n)); // 10 is somewhat arbitrary - frequency = parseFloat(frequency.toPrecision(10)); - hap.value = isObject ? { ...otherValues, freq: frequency } : frequency; + freq = trimFreq(freq); + hap.value = isObject ? { ...otherValues, freq } : { freq }; return isEdo(scaleNameOrRatios) ? hap.setContext({ ...hap.context, edoSize: scaleNameOrRatios.match(/^([1-9]+[0-9]*)edo$/)[1] }) : hap; @@ -128,6 +130,18 @@ export const xen = register('xen', function (scaleNameOrRatios, pat) { * @param {number} amt * @param {number} edoSize (optional) * @returns {Pattern} + * + * @example + * "0 1 2".xen("12edo").ftrans("7") + * // n("0 1 2").scale("A:chromatic").trans("7") + * @example + * "0 8 18".xen("31edo").ftrans("<8 -8>") + * @example + * // if you specify the edoSize, it changes the amount of transposition: + * "0 8 18".xen("31edo").ftrans("8:12") + * @example + * // it can also work with frequency values directly + * "200 300 400".ftrans("<0 7:31 7>").freq() */ /* f = frequency (Hz) @@ -159,6 +173,7 @@ export const { ftrans, fTrans, ftranspose, fTranspose } = register( edoSize = 12; } freq = freq * Math.pow(2, numSteps / edoSize); + freq = trimFreq(freq); hap.value = isObject ? { ...otherValues, freq } : freq; return hap.setContext({ ...hap.context, edoSize }); }); diff --git a/test/__snapshots__/examples.test.mjs.snap b/test/__snapshots__/examples.test.mjs.snap index 7d7b12e1a..fef97dea8 100644 --- a/test/__snapshots__/examples.test.mjs.snap +++ b/test/__snapshots__/examples.test.mjs.snap @@ -4950,6 +4950,74 @@ exports[`runs examples > example "fscope" example index 0 1`] = ` ] `; +exports[`runs examples > example "ftranspose" example index 0 1`] = ` +[ + "[ 0/1 → 1/3 | freq:329.6275569 ]", + "[ 1/3 → 2/3 | freq:349.2282315 ]", + "[ 2/3 → 1/1 | freq:369.9944227 ]", + "[ 1/1 → 4/3 | freq:329.6275569 ]", + "[ 4/3 → 5/3 | freq:349.2282315 ]", + "[ 5/3 → 2/1 | freq:369.9944227 ]", + "[ 2/1 → 7/3 | freq:329.6275569 ]", + "[ 7/3 → 8/3 | freq:349.2282315 ]", + "[ 8/3 → 3/1 | freq:369.9944227 ]", + "[ 3/1 → 10/3 | freq:329.6275569 ]", + "[ 10/3 → 11/3 | freq:349.2282315 ]", + "[ 11/3 → 4/1 | freq:369.9944227 ]", +] +`; + +exports[`runs examples > example "ftranspose" example index 1 1`] = ` +[ + "[ 0/1 → 1/3 | freq:263.0921203 ]", + "[ 1/3 → 2/3 | freq:314.6248353 ]", + "[ 2/3 → 1/1 | freq:393.4589706 ]", + "[ 1/1 → 4/3 | freq:183.965981 ]", + "[ 4/3 → 5/3 | freq:220 ]", + "[ 5/3 → 2/1 | freq:275.1244143 ]", + "[ 2/1 → 7/3 | freq:263.0921203 ]", + "[ 7/3 → 8/3 | freq:314.6248353 ]", + "[ 8/3 → 3/1 | freq:393.4589706 ]", + "[ 3/1 → 10/3 | freq:183.965981 ]", + "[ 10/3 → 11/3 | freq:220 ]", + "[ 11/3 → 4/1 | freq:275.1244143 ]", +] +`; + +exports[`runs examples > example "ftranspose" example index 2 1`] = ` +[ + "[ 0/1 → 1/3 | freq:349.2282314 ]", + "[ 1/3 → 2/3 | freq:417.6327085 ]", + "[ 2/3 → 1/1 | freq:522.2770651 ]", + "[ 1/1 → 4/3 | freq:349.2282314 ]", + "[ 4/3 → 5/3 | freq:417.6327085 ]", + "[ 5/3 → 2/1 | freq:522.2770651 ]", + "[ 2/1 → 7/3 | freq:349.2282314 ]", + "[ 7/3 → 8/3 | freq:417.6327085 ]", + "[ 8/3 → 3/1 | freq:522.2770651 ]", + "[ 3/1 → 10/3 | freq:349.2282314 ]", + "[ 10/3 → 11/3 | freq:417.6327085 ]", + "[ 11/3 → 4/1 | freq:522.2770651 ]", +] +`; + +exports[`runs examples > example "ftranspose" example index 3 1`] = ` +[ + "[ 0/1 → 1/3 | freq:200 ]", + "[ 1/3 → 2/3 | freq:300 ]", + "[ 2/3 → 1/1 | freq:400 ]", + "[ 1/1 → 4/3 | freq:233.8861531 ]", + "[ 4/3 → 5/3 | freq:350.8292297 ]", + "[ 5/3 → 2/1 | freq:467.7723062 ]", + "[ 2/1 → 7/3 | freq:299.6614154 ]", + "[ 7/3 → 8/3 | freq:449.4921231 ]", + "[ 8/3 → 3/1 | freq:599.3228308 ]", + "[ 3/1 → 10/3 | freq:200 ]", + "[ 10/3 → 11/3 | freq:300 ]", + "[ 11/3 → 4/1 | freq:400 ]", +] +`; + exports[`runs examples > example "ftype" example index 0 1`] = ` [ "[ 0/1 → 1/8 | note:f s:sawtooth lpenv:4 cutoff:500 ftype:0 resonance:1 ]",