Skip to content

Commit

Permalink
Apply CS margin to variety signature on Analysis tab.
Browse files Browse the repository at this point in the history
Approximate Tenney-tall fractions on Analysis tab.

ref #796
  • Loading branch information
frostburn committed Jul 30, 2024
1 parent 3ab1c45 commit 74c4fc2
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 11 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Change log

## 3.0.1
* Feature: Apply CS margin to variety signature on Analysis tab [#796](https://github.com/xenharmonic-devs/scale-workshop/issues/796)
* Feature: Approximate Tenney-tall fractions on Analysis tab [#796](https://github.com/xenharmonic-devs/scale-workshop/issues/796)
* Regression: Show pitch associated with MIDI base index [#795](https://github.com/xenharmonic-devs/scale-workshop/issues/795)
* Bug fix: Use relative mossteps when J4 doesn't coincide with 1/1 [#794](https://github.com/xenharmonic-devs/scale-workshop/issues/794)

Expand Down
22 changes: 22 additions & 0 deletions src/analysis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,28 @@ export function varietySignature(matrix: Interval[][]) {
return result
}

export function marginVarietySignature(centsMatrix: number[][], margin: number) {
const result: number[] = []
if (!centsMatrix.length) {
return result
}
for (let i = 0; i < centsMatrix[0].length; ++i) {
let variety = 1
for (let j = 1; j < centsMatrix.length; ++j) {
variety++
const cents = centsMatrix[j][i]
for (let k = 0; k < j; ++k) {
if (Math.abs(centsMatrix[k][i] - cents) < margin) {
variety--
break
}
}
}
result.push(variety)
}
return result
}

export function brightnessSignature(centsMatrix: number[][]) {
const totals = centsMatrix.map((row) => row.reduce((prev, cur) => prev + cur, 0))
const minimum = Math.min(...totals)
Expand Down
36 changes: 25 additions & 11 deletions src/views/AnalysisView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
constantStructureViolations,
freeEquallyTemperedChord,
intervalMatrix,
marginVarietySignature,
marginViolations,
rootedEquallyTemperedChord,
varietySignature
Expand Down Expand Up @@ -31,6 +32,7 @@ const entropy = useHarmonicEntropyStore()
const subtab = ref<'matrix' | 'wheels' | 'entropy'>('matrix')
const cellFormat = ref<'best' | 'fraction' | 'cents' | 'et' | 'decimal'>('best')
const simplifyTolerance = ref(3.5)
const fractionMaxHeight = ref(26)
const showOptions = ref(false)
const trailLongevity = ref(70)
const maxOtonalRoot = ref(16)
Expand Down Expand Up @@ -86,31 +88,34 @@ const etDenominator = computed(() => {
// While interval.name suffices for the tuning table
// we want more accurate results here.
function formatMatrixCell(interval: Interval) {
const monzo = interval.value
if (cellFormat.value === 'fraction') {
if (interval.value.isFractional()) {
const node = interval.value.asFractionLiteral()
if (
monzo.isFractional() &&
(!fractionMaxHeight.value || monzo.tenneyHeight() < fractionMaxHeight.value)
) {
const node = monzo.asFractionLiteral()
if (node) {
return literalToString(node)
}
}
try {
return (
'~' +
new Fraction(interval.valueOf()).simplifyRelative(simplifyTolerance.value).toFraction()
'~' + new Fraction(monzo.valueOf()).simplifyRelative(simplifyTolerance.value).toFraction()
)
} catch {
return '?'
}
}
if (cellFormat.value === 'cents') {
return interval.totalCents(true).toFixed(1)
return monzo.totalCents(true).toFixed(1)
}
if (cellFormat.value === 'decimal') {
// Consistent with tuning table localization.
return interval.valueOf().toFixed(3)
return monzo.valueOf().toFixed(3)
}
if (cellFormat.value === 'et') {
const fractionOfEquave = interval.value.log(scaleEquave.value)
const fractionOfEquave = monzo.log(scaleEquave.value)
if (typeof fractionOfEquave === 'number') {
return `~${Math.round(fractionOfEquave * 100)}%`
}
Expand Down Expand Up @@ -139,12 +144,17 @@ const violations = computed(() => {
const margin = state.constantStructureMargin
if (margin) {
return marginViolations(centsMatrix.value, margin)
} else {
return constantStructureViolations(matrix.value)
}
return constantStructureViolations(matrix.value)
})
const variety = computed(() => varietySignature(matrix.value))
const variety = computed(() => {
const margin = state.constantStructureMargin
if (margin) {
return marginVarietySignature(centsMatrix.value, margin)
}
return varietySignature(matrix.value)
})
const brightness = computed(() =>
brightnessSignature(centsMatrix.value).map((b) => Math.round(100 * b))
Expand Down Expand Up @@ -408,6 +418,10 @@ const sSlider = computed({
v-model="simplifyTolerance"
/>
</div>
<div class="control">
<label for="fraction-max-height">Fraction maximum Tenney height in nats (0 = off)</label>
<input id="fraction-max-height" type="number" min="0" v-model="fractionMaxHeight" />
</div>
<div class="control">
<label for="max-matrix-width">Maximum matrix width</label>
<input
Expand All @@ -427,7 +441,7 @@ const sSlider = computed({
<label for="calculate-violators">Show constant structure violations</label>
</div>
<div class="control">
<label for="cs-margin">Constant structure margin in cents</label>
<label for="cs-margin">Constant structure / variety margin in cents</label>
<input id="cs-margin" type="number" min="0" v-model="state.constantStructureMargin" />
</div>
<div class="control checkbox-container">
Expand Down

0 comments on commit 74c4fc2

Please sign in to comment.