diff --git a/documentation/BUILTIN.md b/documentation/BUILTIN.md index 8ad77f4..e11f9ee 100644 --- a/documentation/BUILTIN.md +++ b/documentation/BUILTIN.md @@ -73,7 +73,7 @@ Obtain a non-negative integer that is the Unicode code point value of the charac Return the color of the interval. ### commaBasis(*temperament*) -Obtain the comma basis (null space) of a temperament. +Obtain the comma basis (null space) of a temperament or a val. ### commaList(*commas*, *basisOrLimit*, *weights*, *pureEquaves*, *fullPrimeLimit*) Construct a Temperament instance from an array of commas. Optional weights are applied multiplicatively on top of Tenney weights. Optionally equaves are normalized to pure. Optionally the full prime limit is assumed based on the commas. @@ -280,7 +280,7 @@ Obtain a "best effort" short string representing a primitive value. Vectorizes o Map a riff over the given/current scale producing a new scale. ### mappingBasis(*temperament*) -Obtain the mapping generators (preimage) of a temperament with period first. See `generatorsOf` for the tempered generators. +Obtain the mapping generators (preimage) of a temperament or a val with period first. See `generatorsOf` for the tempered generators. ### maximum(*...args*) Obtain the argument with the maximum value. diff --git a/src/parser/__tests__/temper.spec.ts b/src/parser/__tests__/temper.spec.ts index 6367c2d..d6836cf 100644 --- a/src/parser/__tests__/temper.spec.ts +++ b/src/parser/__tests__/temper.spec.ts @@ -329,6 +329,20 @@ describe('Features related to tempering', () => { expect(scale).toEqual(['1901.783 "3"', '583.905 "7/5"', '1200. "2"']); }); + it('obtains the period of a single val', () => { + const scale = expand(`{ + const [period] = mappingBasis(11@.5) + period str(period) + 11@ + }`); + expect(scale).toEqual(['1\\11 "16/15"']); + }); + + it('breaks a val into its comma basis', () => { + const scale = expand('[...commaBasis(11@.5)]'); + expect(scale).toEqual(['144/125', '135/128']); + }); + it('knows miracle is miracle', () => { const yup = evaluate( 'Temperament([10@.7, 21@.7]) == commaList([S15, S7-S8])' diff --git a/src/stdlib/builtin/temper.ts b/src/stdlib/builtin/temper.ts index 5dadcd7..1673e03 100644 --- a/src/stdlib/builtin/temper.ts +++ b/src/stdlib/builtin/temper.ts @@ -299,22 +299,29 @@ periodsOf.__doc__ = 'Obtain the number of periods per equave in a temperament.'; periodsOf.__node__ = builtinNode(periodsOf); function mappingBasis(this: ExpressionVisitor, temperament: SonicWeaveValue) { + if (temperament instanceof Val) { + temperament = builtinTemperament.bind(this)(temperament); + } if (!(temperament instanceof Temperament)) { throw new Error('A temperament is required.'); } return temperament.preimage; } mappingBasis.__doc__ = - 'Obtain the mapping generators (preimage) of a temperament with period first. See `generatorsOf` for the tempered generators.'; + 'Obtain the mapping generators (preimage) of a temperament or a val with period first. See `generatorsOf` for the tempered generators.'; mappingBasis.__node__ = builtinNode(mappingBasis); function commaBasis(this: ExpressionVisitor, temperament: SonicWeaveValue) { + if (temperament instanceof Val) { + temperament = builtinTemperament.bind(this)(temperament); + } if (!(temperament instanceof Temperament)) { throw new Error('A temperament is required.'); } return temperament.commaBasis; } -commaBasis.__doc__ = 'Obtain the comma basis (null space) of a temperament.'; +commaBasis.__doc__ = + 'Obtain the comma basis (null space) of a temperament or a val.'; commaBasis.__node__ = builtinNode(commaBasis); function PrimeMapping(