From 3c7aa9114486a0eee633dd9a5ecb6e23fdded86f Mon Sep 17 00:00:00 2001 From: Lumi Pakkanen Date: Tue, 14 May 2024 20:10:14 +0300 Subject: [PATCH] Store full MOS config for reconstruction --- src/context.ts | 18 ++------ src/diamond-mos.ts | 12 +++++ src/parser/__tests__/source.spec.ts | 68 +++++++++++++++++++++++++++++ src/parser/mos.ts | 3 ++ 4 files changed, 87 insertions(+), 14 deletions(-) diff --git a/src/context.ts b/src/context.ts index af469d6d..e45a2385 100644 --- a/src/context.ts +++ b/src/context.ts @@ -2,8 +2,7 @@ import {SonicWeaveValue} from './stdlib'; import {Interval} from './interval'; import {TimeMonzo} from './monzo'; import {ZERO} from './utils'; -import {MosConfig, scaleMonzos} from './diamond-mos'; -import {stepString} from './words'; +import {MosConfig} from './diamond-mos'; /** * Root context of a SonicWeave runtime containing the scale title, root pitch, value of the 'up' inflection etc. @@ -168,18 +167,9 @@ export class RootContext { lines.push(`/ = ${this.lift.toString()}`); } if (this.mosConfig) { - const monzos = scaleMonzos(this.mosConfig); - const ss = stepString(monzos); - let large: TimeMonzo; - let small: TimeMonzo; - if (ss.startsWith('L')) { - large = monzos[0]; - small = large.div(this.mosConfig.am) as TimeMonzo; - } else { - small = monzos[0]; - large = small.mul(this.mosConfig.am) as TimeMonzo; - } - lines.push(`MOS {${ss};L=${large};s=${small}}`); + lines.push( + `MOS {${this.mosConfig.pattern};L=${this.mosConfig.large};s=${this.mosConfig.small}}` + ); } return lines.join('\n'); } diff --git a/src/diamond-mos.ts b/src/diamond-mos.ts index 81bb5c56..946f654c 100644 --- a/src/diamond-mos.ts +++ b/src/diamond-mos.ts @@ -58,6 +58,18 @@ export type MosConfig = { * Intervals for relative notation. Use period to reach larger intervals. */ degrees: MosDegree[]; + /** + * Pattern for reconstructing the MOS declaration. + */ + pattern: string; + /** + * Value of the large step. + */ + large: TimeMonzo; + /** + * Value of the small step. + */ + small: TimeMonzo; }; /** diff --git a/src/parser/__tests__/source.spec.ts b/src/parser/__tests__/source.spec.ts index 687f7b56..d9a671cc 100644 --- a/src/parser/__tests__/source.spec.ts +++ b/src/parser/__tests__/source.spec.ts @@ -1652,4 +1652,72 @@ describe('SonicWeave parser', () => { 145.94801056814464, 165.55065597696213, 176.31825099920434, 200, ]); }); + + it('allows you to call the smaller step L in MOS declaration', () => { + const scale = expand(` + MOS { + 3L 2s + L = 9/8 + } + automos() + relative + linear + `); + expect(scale).toEqual([ + 'MOS {LLsLs;L=9/8;s=32/27}', + '9/8', + '81/64', + '3/2', + '27/16', + '2', + ]); + }); + + it('allows you to create negative steps', () => { + const scale = expand(` + MOS { + 6L 1s + L = 9/8 + } + automos() + relative + linear + `); + expect(scale).toEqual([ + 'MOS {LLLLLLs;L=9/8;s=524288/531441}', + '9/8', + '81/64', + '729/512', + '6561/4096', + '59049/32768', + '531441/262144', + '2', + ]); + }); + + it('preserves equalized MOS declaration', () => { + const scale = expand(` + MOS { + 5L 2s + L = 1\\7 + } + M1ms + M2ms + P3ms + P4ms + M5ms + M6ms + P7ms + `); + expect(scale).toEqual([ + 'MOS {LLLsLLs;L=2^1/7;s=2^1/7}', + 'M1ms', + 'M2ms', + 'P3ms', + 'P4ms', + 'M5ms', + 'M6ms', + 'P7ms', + ]); + }); }); diff --git a/src/parser/mos.ts b/src/parser/mos.ts index 4d85bb2d..0f15d2ac 100644 --- a/src/parser/mos.ts +++ b/src/parser/mos.ts @@ -148,6 +148,9 @@ export class Tardigrade { period: r(notation.period), scale, degrees, + pattern: this.pattern, + large, + small, }; }