Skip to content

Commit

Permalink
Make automos() work with absurd scales
Browse files Browse the repository at this point in the history
Generalize Diamond-mos nominals.

ref #324
  • Loading branch information
frostburn committed May 21, 2024
1 parent 4b5c872 commit b976423
Show file tree
Hide file tree
Showing 7 changed files with 41 additions and 39 deletions.
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@
"vitest": "^1.4.0"
},
"dependencies": {
"moment-of-symmetry": "^0.6.0",
"moment-of-symmetry": "^0.7.0",
"xen-dev-utils": "^0.7.0"
},
"engines": {
Expand Down
28 changes: 2 additions & 26 deletions src/diamond-mos.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export type MosConfig = {
/**
* Relative scale from J onwards. Echelon depends on J. Use equave to reach higher octave numbers.
*/
scale: Map<MosNominal, TimeMonzo>;
scale: Map<string, TimeMonzo>;
/**
* Intervals for relative notation. Use period to reach larger intervals.
*/
Expand Down Expand Up @@ -100,36 +100,12 @@ export type SplitMosAccidental = {
accidental: Accidental | MosAccidental;
};

/**
* Diamond-mos nominals from J to Z.
*
* The number of valid nominals corresponds to the size of the MOS scale and repeats every equave.
*/
export type MosNominal =
| 'J'
| 'K'
| 'L'
| 'M'
| 'N'
| 'O'
| 'P'
| 'Q'
| 'R'
| 'S'
| 'T'
| 'U'
| 'V'
| 'W'
| 'X'
| 'Y'
| 'Z';

/**
* Absolute Diamond-mos pitch.
*/
export type AbsoluteMosPitch = {
type: 'AbsolutePitch';
nominal: MosNominal;
nominal: string;
accidentals: SplitMosAccidental[];
octave: number;
};
Expand Down
12 changes: 11 additions & 1 deletion src/grammars/sonic-weave.pegjs
Original file line number Diff line number Diff line change
Expand Up @@ -1509,8 +1509,17 @@ PitchNominal 'pitch nominal'
/ 'ome'
// Some pitches like M3 or S9 are inaccessible due to other rules and require accidentals to disambiguate.
// Absurd nominals like SQRT#4 also require accidentals to disambiguate.
AbsolutePitch
= nominal: PitchNominal accidentals: Accidental* octave: SignedBasicInteger {
= nominal: $[J-Z]|2..| accidentals: Accidental+ octave: SignedBasicInteger {
return {
type: 'AbsolutePitch',
nominal,
accidentals,
octave,
};
}
/ nominal: PitchNominal accidentals: Accidental* octave: SignedBasicInteger {
return {
type: 'AbsolutePitch',
nominal,
Expand Down Expand Up @@ -1562,6 +1571,7 @@ ArrowFunction
// This rule is a faster version of the part of (FJS / AbsoluteFJS / (SquareSuperparticular)) which overlaps with identifiers.
ReservedPattern
= [sqQ]? (AugmentedToken+ / [mMnP]) [0-9]+ 'ms'? ([_v] [0-9])*
/ [J-Z]|2..| [sqQxdb_ae]+ [0-9]+ ([_v] [0-9])*
/ PitchNominal [sqQxdb_ae]* [0-9]+ ([_v] [0-9])*
// TODO: Figure out where to put this
Expand Down
18 changes: 18 additions & 0 deletions src/parser/__tests__/source.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1776,4 +1776,22 @@ describe('SonicWeave parser', () => {
'1\\1',
]);
});

it('supports large MOS scales', () => {
const scale = expand(`
MOS 42L 7s
JK_4
JT♮4
KQ&4
J5
i => i str(nedji(i, niente, 91))
`);
expect(scale).toEqual([
'MOS {LLLLLLsLLLLLLsLLLLLLsLLLLLLsLLLLLLsLLLLLLsLLLLLLs;L=2^2/91;s=2^1/91}',
'JK_4 "34\\\\91"',
'JT♮4 "51\\\\91"',
'KQ&4 "78\\\\91"',
'J5 "91\\\\91"',
]);
});
});
4 changes: 2 additions & 2 deletions src/parser/mos.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {TimeMonzo, TimeReal} from '../monzo';
import {ExpressionVisitor} from './expression';
import {MosMonzo, MosOptions, generateNotation, mos} from 'moment-of-symmetry';
import {Interval} from '../interval';
import {MosConfig, MosDegree, MosNominal} from '../diamond-mos';
import {MosConfig, MosDegree} from '../diamond-mos';
import {ONE, TWO, ZERO} from '../utils';

const TWO_MONZO = new TimeMonzo(ZERO, [ONE]);
Expand Down Expand Up @@ -148,7 +148,7 @@ export class Tardigrade {
const semiam = am.sqrt() as TimeMonzo;
const r = (m: MosMonzo) =>
realize(m, large as TimeMonzo, small as TimeMonzo);
const scale = notation.scale as unknown as Map<MosNominal, TimeMonzo>;
const scale = notation.scale as unknown as Map<string, TimeMonzo>;
for (const [key, value] of notation.scale) {
scale.set(key, r(value));
}
Expand Down
8 changes: 3 additions & 5 deletions src/stdlib/builtin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import {
setNumberOfComponents,
} from '../monzo';
import {type ExpressionVisitor} from '../parser';
import {MosOptions, mos} from 'moment-of-symmetry';
import {MosOptions, mos, nthNominal} from 'moment-of-symmetry';
import {expressionToString} from '../ast';
import {
BasisElement,
Expand Down Expand Up @@ -72,7 +72,7 @@ import {
factorColor as pubFactorColor,
compare,
} from './public';
import {MosNominal, scaleMonzos} from '../diamond-mos';
import {scaleMonzos} from '../diamond-mos';
const {version: VERSION} = require('../../package.json');

// === Library ===
Expand Down Expand Up @@ -1941,9 +1941,7 @@ function automos(this: ExpressionVisitor) {
type: 'AbsoluteFJS',
pitch: {
type: 'AbsolutePitch',
nominal: String.fromCharCode(
'J'.charCodeAt(0) + mmod(i + 1, monzos.length)
) as MosNominal,
nominal: nthNominal(mmod(i + 1, monzos.length)),
accidentals: [{accidental: '♮', fraction: ''}],
octave: i === monzos.length - 1 ? 5 : 4,
},
Expand Down

0 comments on commit b976423

Please sign in to comment.