Skip to content

Commit

Permalink
Apply formatting to interval matrix row headers
Browse files Browse the repository at this point in the history
Add fraction formatting option.

ref #687
  • Loading branch information
frostburn committed May 18, 2024
1 parent 6b77029 commit 09e5e6a
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 8 deletions.
4 changes: 2 additions & 2 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
@@ -1,6 +1,6 @@
{
"name": "scale-workshop",
"version": "3.0.0-beta.28",
"version": "3.0.0-beta.29",
"scripts": {
"dev": "vite",
"build": "run-p type-check \"build-only {@}\" --",
Expand Down
4 changes: 4 additions & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ export const FIFTH_12TET = new Interval(
TimeMonzo.fromEqualTemperament('7/12', 2, DEFAULT_NUMBER_OF_COMPONENTS),
'logarithmic'
)
export const UNISON = new Interval(
TimeMonzo.fromFraction(1, DEFAULT_NUMBER_OF_COMPONENTS),
'linear'
)

export const INTERVALS_12TET = [...Array(12).keys()].map(
(i) =>
Expand Down
47 changes: 42 additions & 5 deletions src/views/AnalysisView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,17 @@ import ScaleLineInput from '@/components/ScaleLineInput.vue'
import { computed, reactive, ref } from 'vue'
import { useAudioStore } from '@/stores/audio'
import { useStateStore } from '@/stores/state'
import type { Interval } from 'sonic-weave'
import { literalToString, type Interval } from 'sonic-weave'
import { useScaleStore } from '@/stores/scale'
import { mmod } from 'xen-dev-utils'
import { OCTAVE } from '@/constants'
import { Fraction, mmod } from 'xen-dev-utils'
import { OCTAVE, UNISON } from '@/constants'
const audio = useAudioStore()
const state = useStateStore()
const scale = useScaleStore()
const cellFormat = ref<'best' | 'cents' | 'decimal'>('best')
const cellFormat = ref<'best' | 'fraction' | 'cents' | 'decimal'>('best')
const simplifyTolerance = ref(3.5)
const showOptions = ref(false)
const trailLongevity = ref(70)
const maxOtonalRoot = ref(16)
Expand Down Expand Up @@ -67,6 +68,22 @@ const strokeStyle = computed(() => {
// While interval.name suffices for the tuning table
// we want more accurate results here.
function formatMatrixCell(interval: Interval) {
if (cellFormat.value === 'fraction') {
if (interval.value.isFractional()) {
const node = interval.value.asFractionLiteral()
if (node) {
return literalToString(node)
}
}
try {
return (
'~' +
new Fraction(interval.valueOf()).simplifyRelative(simplifyTolerance.value).toFraction()
)
} catch {
return '?'
}
}
if (cellFormat.value === 'cents') {
return interval.totalCents(true).toFixed(1)
}
Expand Down Expand Up @@ -203,7 +220,12 @@ function highlight(y?: number, x?: number) {
</tr>
<tr v-for="(row, i) of matrixRows" :key="i">
<th :class="{ held: heldScaleDegrees.has(i) }">
{{ scale.labels[mmod(i - 1, scale.labels.length)] }}
<template v-if="cellFormat === 'best'">
{{ scale.labels[mmod(i - 1, scale.labels.length)] }}
</template>
<template v-else>
{{ formatMatrixCell(i ? scale.relativeIntervals[i - 1] : UNISON) }}
</template>
</th>
<td
v-for="(name, j) of row"
Expand Down Expand Up @@ -233,6 +255,11 @@ function highlight(y?: number, x?: number) {
<label for="format-best">Default</label>
</span>

<span>
<input type="radio" id="format-fraction" value="fraction" v-model="cellFormat" />
<label for="format-fraction">Fraction</label>
</span>

<span>
<input type="radio" id="format-cents" value="cents" v-model="cellFormat" />
<label for="format-cents">Cents</label>
Expand Down Expand Up @@ -260,6 +287,16 @@ function highlight(y?: number, x?: number) {
<label for="indexing-one">1-indexing</label>
</span>
</div>
<div class="control">
<label for="simplify-tolerance">Fraction approximation tolerance in cents</label>
<input
id="simplify-tolerance"
type="number"
min="0.1"
step="0.1"
v-model="simplifyTolerance"
/>
</div>
<div class="control">
<label for="max-matrix-width">Maximum matrix width</label>
<input
Expand Down

0 comments on commit 09e5e6a

Please sign in to comment.