diff --git a/package-lock.json b/package-lock.json
index 4ea3035b..d53d5302 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,27 +1,27 @@
{
"name": "scale-workshop",
- "version": "3.0.0-beta.24",
+ "version": "3.0.0-beta.25",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "scale-workshop",
- "version": "3.0.0-beta.24",
+ "version": "3.0.0-beta.25",
"dependencies": {
"isomorphic-qwerty": "^0.0.2",
"ji-lattice": "^0.0.3",
"jszip": "^3.10.1",
- "moment-of-symmetry": "^0.4.2",
+ "moment-of-symmetry": "^0.5.2",
"pinia": "^2.1.7",
"qs": "^6.12.0",
- "sonic-weave": "github:xenharmonic-devs/sonic-weave#v0.0.34",
+ "sonic-weave": "github:xenharmonic-devs/sonic-weave#v0.0.36",
"sw-synth": "^0.1.0",
"temperaments": "^0.5.3",
"values.js": "^2.1.1",
"vue": "^3.3.4",
"vue-router": "^4.3.0",
"webmidi": "^3.1.8",
- "xen-dev-utils": "^0.6.1",
+ "xen-dev-utils": "^0.7.0",
"xen-midi": "^0.2.0"
},
"devDependencies": {
@@ -4381,23 +4381,11 @@
}
},
"node_modules/moment-of-symmetry": {
- "version": "0.4.2",
- "resolved": "https://registry.npmjs.org/moment-of-symmetry/-/moment-of-symmetry-0.4.2.tgz",
- "integrity": "sha512-XBzU01kDgQfN0JacGSwMOxJOk5EhwcaojbDQDDdZF/k16ze/VP9X8Cz1Gy8Hmhg+WMu0axfTVP4ufzhoFt0C4g==",
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/moment-of-symmetry/-/moment-of-symmetry-0.5.2.tgz",
+ "integrity": "sha512-omlRHnafyz5ZUfGIy64ISkX2XZsoRq//lFvZ+96zVFVveHrCPrVSKVva4pLBHZeesQrIYxTe7A1Ij6fRQwtffg==",
"dependencies": {
- "xen-dev-utils": "^0.2.8"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/frostburn"
- }
- },
- "node_modules/moment-of-symmetry/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"
+ "xen-dev-utils": "^0.7.0"
},
"funding": {
"type": "github",
@@ -5467,12 +5455,12 @@
}
},
"node_modules/sonic-weave": {
- "version": "0.0.34",
- "resolved": "git+ssh://git@github.com/xenharmonic-devs/sonic-weave.git#d6e4b4f81bf7e2dfa0efccd154d04fad1e26c7b9",
+ "version": "0.0.36",
+ "resolved": "git+ssh://git@github.com/xenharmonic-devs/sonic-weave.git#4e120d3bfed93cf0971c90260dd71f0852f78143",
"license": "MIT",
"dependencies": {
- "moment-of-symmetry": "^0.4.2",
- "xen-dev-utils": "^0.6.1"
+ "moment-of-symmetry": "^0.5.2",
+ "xen-dev-utils": "^0.7.0"
},
"bin": {
"sonic-weave": "bin/sonic-weave.js"
@@ -6616,9 +6604,9 @@
}
},
"node_modules/xen-dev-utils": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/xen-dev-utils/-/xen-dev-utils-0.6.1.tgz",
- "integrity": "sha512-smdLvCIYnAuwGiVdj67kW8kS37gwtUFBF253ukTa4V7BfVglt7HYR9r1EQTCB8FC1J8rdNY++M8TRID+YNsH4A==",
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/xen-dev-utils/-/xen-dev-utils-0.7.0.tgz",
+ "integrity": "sha512-KECBCnnHD9sh4lY0Q6+KcgKVwMBWUOGjEJ/7S8sER2L3BKciy9kLhPFB+LR3z1oQiNS/OI7lv3L4rtPEX5SPUQ==",
"engines": {
"node": ">=10.6.0"
},
diff --git a/package.json b/package.json
index 701f4cbd..6891b5fe 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "scale-workshop",
- "version": "3.0.0-beta.24",
+ "version": "3.0.0-beta.25",
"scripts": {
"dev": "vite",
"build": "run-p type-check \"build-only {@}\" --",
@@ -18,17 +18,17 @@
"isomorphic-qwerty": "^0.0.2",
"ji-lattice": "^0.0.3",
"jszip": "^3.10.1",
- "moment-of-symmetry": "^0.4.2",
+ "moment-of-symmetry": "^0.5.2",
"pinia": "^2.1.7",
"qs": "^6.12.0",
- "sonic-weave": "github:xenharmonic-devs/sonic-weave#v0.0.34",
+ "sonic-weave": "github:xenharmonic-devs/sonic-weave#v0.0.36",
"sw-synth": "^0.1.0",
"temperaments": "^0.5.3",
"values.js": "^2.1.1",
"vue": "^3.3.4",
"vue-router": "^4.3.0",
"webmidi": "^3.1.8",
- "xen-dev-utils": "^0.6.1",
+ "xen-dev-utils": "^0.7.0",
"xen-midi": "^0.2.0"
},
"devDependencies": {
diff --git a/src/character-palette.json b/src/character-palette.json
index 64bded43..c8bb01aa 100644
--- a/src/character-palette.json
+++ b/src/character-palette.json
@@ -27,9 +27,11 @@
"ε": "Interordinal nominal epsilon. ε4
is a semioctave above E4
.",
"ζ": "Interordinal nominal zeta. ζ4
is a semioctave above F4
.",
"η": "Interordinal nominal eta. η4
is a semioctave below G4
.",
+ "φ": "Interordinal nominal phi. φ4
is a semifourth above C4
.",
+ "χ": "Interordinal nominal chi. χ4
is 9/8 above φ4
.",
+ "ψ": "Interordinal nominal psi. ψ4
is a semifourth below C5
.",
+ "ω": "Interordinal nominal omega. ω4
is 9/8 above ψ4
.",
"¢": "Cent. 1¢
is equal to 1\\1200
.",
- "€": "Reciprocal cent. € · 1¢
is 1
.",
- "¶": "Geometric inverse of the Hertz. ¶ · 1Hz
is 1
.",
"µ": "Metric prefix micro. E.g. Period of oscillation 2000 µs
corresponds to frequency of oscillation 500 Hz
.",
"⟨": "Val angle bracket. ⟨12 19 28]
.",
"⟩": "Monzo angle bracket. [-4 4 -1⟩
."
diff --git a/src/stores/tempering.ts b/src/stores/tempering.ts
index e17e48ba..aab9f291 100644
--- a/src/stores/tempering.ts
+++ b/src/stores/tempering.ts
@@ -160,9 +160,13 @@ export const useRank2Store = defineStore('rank2', () => {
const subgroupString = state.subgroupString
// === Computed state ===
- const generatorPerPeriod = computed(
- () => generator.value.totalCents() / period.value.totalCents()
- )
+ const generatorPerPeriod = computed(() => {
+ const p = period.value.totalCents()
+ if (!p) {
+ return 0;
+ }
+ return generator.value.totalCents() / p
+ })
const safeNumPeriods = computed(() => {
const value = Math.abs(parseInt(numPeriods.value as unknown as string, 10))
if (isNaN(value)) {
@@ -170,9 +174,7 @@ export const useRank2Store = defineStore('rank2', () => {
}
return value || 1
})
- const opposite = computed(() =>
- isBright(generatorPerPeriod.value, safeSize.value / safeNumPeriods.value) ? 'dark' : 'bright'
- )
+ const opposite = computed(() => isBright(generatorPerPeriod.value, safeSize.value / safeNumPeriods.value) ? 'dark' : 'bright')
const [mosPatterns, mosPatternsError] = computedAndError(() => {
if (method.value === 'generator') {
@@ -219,19 +221,27 @@ export const useRank2Store = defineStore('rank2', () => {
}, [])
const circlePeriodCents = computed(() => {
+ const p = period.value.totalCents()
+ if (!p || isNaN(p)) {
+ return 0.0001;
+ }
const stretch = parseFloat(periodStretch.value)
if (isNaN(stretch)) {
- return period.value.totalCents()
+ return p
}
- return period.value.totalCents() * Math.exp(stretch)
+ return p * Math.exp(stretch)
})
const circleGeneratorCents = computed(() => {
+ const g = generator.value.totalCents()
+ if (isNaN(g)) {
+ return 0;
+ }
const fine = parseFloat(generatorFineCents.value)
if (isNaN(fine)) {
- return generator.value.totalCents()
+ return g
}
- return generator.value.totalCents() + fine
+ return g + fine
})
const safeSize = computed(