diff --git a/package-lock.json b/package-lock.json
index 9490034b..6b96716e 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -15,9 +15,8 @@
"moment-of-symmetry": "^0.8.2",
"pinia": "^2.1.7",
"qs": "^6.12.0",
- "sonic-weave": "0.9.0",
+ "sonic-weave": "^0.10.1",
"sw-synth": "^0.1.0",
- "temperaments": "^0.5.3",
"values.js": "^2.1.1",
"vue": "^3.3.4",
"vue-router": "^4.3.0",
@@ -2089,18 +2088,6 @@
"node": ">=4.0.0"
}
},
- "node_modules/complex.js": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/complex.js/-/complex.js-2.1.1.tgz",
- "integrity": "sha512-8njCHOTtFFLtegk6zQo0kkVX1rngygb/KQI6z1qZxlFI3scluC+LVTCFbrkWjBv4vvLlbQ9t88IPMC6k95VTTg==",
- "engines": {
- "node": "*"
- },
- "funding": {
- "type": "patreon",
- "url": "https://www.patreon.com/infusion"
- }
- },
"node_modules/computeds": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/computeds/-/computeds-0.0.1.tgz",
@@ -2292,7 +2279,8 @@
"node_modules/decimal.js": {
"version": "10.4.3",
"resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz",
- "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA=="
+ "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==",
+ "dev": true
},
"node_modules/deep-eql": {
"version": "4.1.3",
@@ -2566,11 +2554,6 @@
"node": ">=12"
}
},
- "node_modules/escape-latex": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/escape-latex/-/escape-latex-1.2.0.tgz",
- "integrity": "sha512-nV5aVWW1K0wEiUIEdZ4erkGGH8mDxGyxSeqPzRNtWP7ataw+/olFObw7hujFWlVjNsaDFw5VZ5NzVSIqRgfTiw=="
- },
"node_modules/escape-string-regexp": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
@@ -3144,18 +3127,6 @@
"node": ">= 0.12"
}
},
- "node_modules/fraction.js": {
- "version": "4.3.4",
- "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.4.tgz",
- "integrity": "sha512-pwiTgt0Q7t+GHZA4yaLjObx4vXmmdcS0iSJ19o8d/goUGgItX9UZWKWNnLHehxviD8wU2IWRsnR8cD5+yOJP2Q==",
- "engines": {
- "node": "*"
- },
- "funding": {
- "type": "patreon",
- "url": "https://github.com/sponsors/rawify"
- }
- },
"node_modules/from": {
"version": "0.1.7",
"resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz",
@@ -3787,11 +3758,6 @@
"@pkgjs/parseargs": "^0.11.0"
}
},
- "node_modules/javascript-natural-sort": {
- "version": "0.7.1",
- "resolved": "https://registry.npmjs.org/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz",
- "integrity": "sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw=="
- },
"node_modules/jazz-midi": {
"version": "1.7.9",
"resolved": "https://registry.npmjs.org/jazz-midi/-/jazz-midi-1.7.9.tgz",
@@ -4263,28 +4229,6 @@
"integrity": "sha512-CkYQrPYZfWnu/DAmVCpTSX/xHpKZ80eKh2lAkyA6AJTef6bW+6JpbQZN5rofum7da+SyN1bi5ctTm+lTfcCW3g==",
"dev": true
},
- "node_modules/mathjs": {
- "version": "12.4.1",
- "resolved": "https://registry.npmjs.org/mathjs/-/mathjs-12.4.1.tgz",
- "integrity": "sha512-welnW3khgwYjPYvECFHO+xkCxAx9IKIIPDDWPi8B5rKAvmgoEHnQX9slEmHKZTNaJiE+OS4qrJJcB4sfDn/4sw==",
- "dependencies": {
- "@babel/runtime": "^7.24.0",
- "complex.js": "^2.1.1",
- "decimal.js": "^10.4.3",
- "escape-latex": "^1.2.0",
- "fraction.js": "4.3.4",
- "javascript-natural-sort": "^0.7.1",
- "seedrandom": "^3.0.5",
- "tiny-emitter": "^2.1.0",
- "typed-function": "^4.1.1"
- },
- "bin": {
- "mathjs": "bin/cli.js"
- },
- "engines": {
- "node": ">= 18"
- }
- },
"node_modules/memorystream": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz",
@@ -5366,11 +5310,6 @@
"node": ">=v12.22.7"
}
},
- "node_modules/seedrandom": {
- "version": "3.0.5",
- "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-3.0.5.tgz",
- "integrity": "sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg=="
- },
"node_modules/semver": {
"version": "7.6.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz",
@@ -5502,9 +5441,9 @@
}
},
"node_modules/sonic-weave": {
- "version": "0.9.0",
- "resolved": "https://registry.npmjs.org/sonic-weave/-/sonic-weave-0.9.0.tgz",
- "integrity": "sha512-dBtXA9CEo9/4CCNc5+9k1JMeegSijw3o+SACSzsxo7MpERheNVmpHlGtjjS0PeALoP8E6erwBzHqI83N+ylfqg==",
+ "version": "0.10.1",
+ "resolved": "https://registry.npmjs.org/sonic-weave/-/sonic-weave-0.10.1.tgz",
+ "integrity": "sha512-gDKvywuHQcauy42joWmY6aOPvBr0wMMHoe5Npc+kexwzcaxUBRvrGEu6HI9izx8UGeJyOgGaTmB92VAf/WmQkg==",
"dependencies": {
"moment-of-symmetry": "^0.8.2",
"xen-dev-utils": "^0.11.0"
@@ -5815,32 +5754,6 @@
"url": "https://opencollective.com/unts"
}
},
- "node_modules/temperaments": {
- "version": "0.5.3",
- "resolved": "https://registry.npmjs.org/temperaments/-/temperaments-0.5.3.tgz",
- "integrity": "sha512-+gVFX5vfYOv7fQzd9AKQpgMvaW+ww4bZfmOQ1vktXexfQgbhscC5SAQm1stfWg94ahDf7AkUwVkY2tLQFUj+rw==",
- "dependencies": {
- "mathjs": "^12.4.0",
- "ts-geometric-algebra": "^0.5.1",
- "xen-dev-utils": "^0.2.7"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/frostburn"
- }
- },
- "node_modules/temperaments/node_modules/xen-dev-utils": {
- "version": "0.2.9",
- "resolved": "https://registry.npmjs.org/xen-dev-utils/-/xen-dev-utils-0.2.9.tgz",
- "integrity": "sha512-ngs85djTa5MH9yMomyFg1ZK1eETgtaG6FN5ZvDazyBbGmShuK/gOEWGRemHqm+I2zp3lOGbXlEU/M4SwYl3HLA==",
- "engines": {
- "node": ">=10.6.0"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/frostburn"
- }
- },
"node_modules/text-table": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
@@ -5862,11 +5775,6 @@
"integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==",
"dev": true
},
- "node_modules/tiny-emitter": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz",
- "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q=="
- },
"node_modules/tinybench": {
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.7.0.tgz",
@@ -5960,36 +5868,6 @@
"typescript": ">=4.2.0"
}
},
- "node_modules/ts-geometric-algebra": {
- "version": "0.5.1",
- "resolved": "https://registry.npmjs.org/ts-geometric-algebra/-/ts-geometric-algebra-0.5.1.tgz",
- "integrity": "sha512-7GoWXFQqY8N+RDL9WyD0IzH+XCdpVoaojw0ortWQqSkocHzCVlTTEOuafYS793GtIVcRoiUkbO8QlPykR04F9w==",
- "dependencies": {
- "mathjs": "^11.5.0"
- }
- },
- "node_modules/ts-geometric-algebra/node_modules/mathjs": {
- "version": "11.12.0",
- "resolved": "https://registry.npmjs.org/mathjs/-/mathjs-11.12.0.tgz",
- "integrity": "sha512-UGhVw8rS1AyedyI55DGz9q1qZ0p98kyKPyc9vherBkoueLntPfKtPBh14x+V4cdUWK0NZV2TBwqRFlvadscSuw==",
- "dependencies": {
- "@babel/runtime": "^7.23.2",
- "complex.js": "^2.1.1",
- "decimal.js": "^10.4.3",
- "escape-latex": "^1.2.0",
- "fraction.js": "4.3.4",
- "javascript-natural-sort": "^0.7.1",
- "seedrandom": "^3.0.5",
- "tiny-emitter": "^2.1.0",
- "typed-function": "^4.1.1"
- },
- "bin": {
- "mathjs": "bin/cli.js"
- },
- "engines": {
- "node": ">= 14"
- }
- },
"node_modules/tslib": {
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
@@ -6047,14 +5925,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/typed-function": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/typed-function/-/typed-function-4.1.1.tgz",
- "integrity": "sha512-Pq1DVubcvibmm8bYcMowjVnnMwPVMeh0DIdA8ad8NZY2sJgapANJmiigSUwlt+EgXxpfIv8MWrQXTIzkfYZLYQ==",
- "engines": {
- "node": ">= 14"
- }
- },
"node_modules/typescript": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz",
diff --git a/package.json b/package.json
index 3c3c8f4c..90e0c4a9 100644
--- a/package.json
+++ b/package.json
@@ -22,9 +22,8 @@
"moment-of-symmetry": "^0.8.2",
"pinia": "^2.1.7",
"qs": "^6.12.0",
- "sonic-weave": "0.9.0",
+ "sonic-weave": "^0.10.1",
"sw-synth": "^0.1.0",
- "temperaments": "^0.5.3",
"values.js": "^2.1.1",
"vue": "^3.3.4",
"vue-router": "^4.3.0",
diff --git a/src/__tests__/tempering.spec.ts b/src/__tests__/tempering.spec.ts
deleted file mode 100644
index d2da4220..00000000
--- a/src/__tests__/tempering.spec.ts
+++ /dev/null
@@ -1,72 +0,0 @@
-import { describe, it, expect } from 'vitest'
-
-import {
- makeRank2FromCommas,
- makeRank2FromVals,
- mosPatternsRank2FromCommas,
- mosPatternsRank2FromVals,
- toPrimeMapping
-} from '../tempering'
-import { arraysEqual, PRIME_CENTS, valueToCents } from 'xen-dev-utils'
-import { Subgroup } from 'temperaments'
-import { DEFAULT_NUMBER_OF_COMPONENTS } from '../constants'
-
-describe('Prime map converter', () => {
- it('does (almost) nothing in 5-limit JI', () => {
- const fiveLimit = PRIME_CENTS.slice(0, 3)
- const mapping = toPrimeMapping(fiveLimit, new Subgroup(5))
- expect(mapping[0]).toBeCloseTo(fiveLimit[0])
- expect(mapping[1]).toBeCloseTo(fiveLimit[1])
- expect(mapping[2]).toBeCloseTo(fiveLimit[2])
- expect(mapping.length).toBe(DEFAULT_NUMBER_OF_COMPONENTS)
- expect(mapping[3]).toBeCloseTo(PRIME_CENTS[3])
- })
-
- it('converts a mapping in 2.3.13/5 to 2.3.5.7.11.13...', () => {
- const original = [1200, 1901, 1654]
- const mapping = toPrimeMapping(original, new Subgroup('2.3.13/5'))
- expect(mapping[0]).toBeCloseTo(1200)
- expect(mapping[1]).toBeCloseTo(1901)
- expect(mapping[3]).toBeCloseTo(PRIME_CENTS[3])
- expect(mapping[4]).toBeCloseTo(PRIME_CENTS[4])
- expect(mapping[5] - mapping[2]).toBeCloseTo(1654)
- expect(mapping[6]).toBeCloseTo(PRIME_CENTS[6])
- })
-})
-
-describe('Tempered scale generation', () => {
- it('generates CTE augmented from vals', () => {
- const vals = [3, 12]
- const limit = 5
- const options = {
- constraints: ['2/1']
- }
- const infos = mosPatternsRank2FromVals(vals, limit, undefined, 5, options)
- const sizes = infos.map((info) => info.numberOfLargeSteps + info.numberOfSmallSteps)
- expect(arraysEqual(sizes, [6, 9, 12, 15, 27])).toBeTruthy()
-
- const { generator, period, numPeriods } = makeRank2FromVals(vals, sizes[2], limit, options)
- expect(period).toBeCloseTo(400)
- expect(generator + period).toBeCloseTo(valueToCents(3 / 2))
- expect(numPeriods).toBe(3)
- })
-
- it('generates POTE meantone from a comma', () => {
- const commas = ['81/80']
- const infos = mosPatternsRank2FromCommas(commas, undefined, undefined, 5)
- const sizes = infos.map((info) => info.numberOfLargeSteps + info.numberOfSmallSteps)
- expect(arraysEqual(sizes, [2, 3, 5, 7, 12])).toBeTruthy()
-
- const { generator, period, numPeriods } = makeRank2FromCommas(commas, sizes[3])
- expect(generator).toBeCloseTo(696.239)
- expect(period).toBeCloseTo(1200)
- expect(numPeriods).toBe(1)
- })
-
- it('generates frostburn from a comma', () => {
- const commas = [[-5, 0, 7, -4, 0, 0, 0]]
- const infos = mosPatternsRank2FromCommas(commas, new Subgroup('2.5.7'), undefined, 6)
- const sizes = infos.map((info) => info.numberOfLargeSteps + info.numberOfSmallSteps)
- expect(sizes).toEqual([2, 3, 4, 5, 6, 11])
- })
-})
diff --git a/src/components/PeriodCircle.vue b/src/components/PeriodCircle.vue
index 9835b428..da78a6ba 100644
--- a/src/components/PeriodCircle.vue
+++ b/src/components/PeriodCircle.vue
@@ -109,7 +109,8 @@ const mosLabel = computed(() => {
else if (step === M) countM++
else if (step === L) countL++
}
- return `${countL}L ${countM}M ${countS}s`
+ const n = props.numPeriods
+ return `${n * countL}L ${n * countM}M ${n * countS}s`
}
// There are degenerate edgecases with step variety = 2. Show nothing to avoid implying MOS.
return ''
diff --git a/src/components/modals/generation/RankTwo.vue b/src/components/modals/generation/RankTwo.vue
index 4b71233a..1226c09a 100644
--- a/src/components/modals/generation/RankTwo.vue
+++ b/src/components/modals/generation/RankTwo.vue
@@ -1,15 +1,15 @@
@@ -351,27 +300,7 @@ function generate(expand = true) {
-
-
Advanced options
-{{ rank2.error }}
+- Advanced options -
-+ Advanced options +
+{{ lattice.error }}