Skip to content

Commit

Permalink
Implement SonicWeave Interchange importer
Browse files Browse the repository at this point in the history
Update sonic-weave dependency.
Update moment-of-symmetry dependency.

ref #34
  • Loading branch information
frostburn committed Jul 14, 2024
1 parent 1a2989c commit 8105bdb
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 25 deletions.
32 changes: 10 additions & 22 deletions package-lock.json

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

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@
"isomorphic-qwerty": "^0.0.2",
"ji-lattice": "^0.2.0",
"jszip": "^3.10.1",
"moment-of-symmetry": "^0.8.2",
"moment-of-symmetry": "^0.8.3",
"pinia": "^2.1.7",
"qs": "^6.12.0",
"sonic-weave": "^0.10.3",
"sonic-weave": "^0.10.4",
"sw-synth": "^0.1.0",
"values.js": "^2.1.1",
"vue": "^3.3.4",
Expand Down
9 changes: 9 additions & 0 deletions src/components/NewScale.vue
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ const SubharmonicSeriesModal = defineAsyncComponent(
const element = ref<typeof DropdownGroup | null>(null)
const scalaFile = ref<HTMLInputElement | null>(null)
const anamarkFile = ref<HTMLInputElement | null>(null)
const xendevsFile = ref<HTMLInputElement | null>(null)
const showConcordanceShellModal = ref(false)
const showCpsModal = ref(false)
Expand Down Expand Up @@ -145,6 +146,7 @@ defineExpose({ blur })
<li class="divider"></li>
<a href="#" @click="scalaFile!.click()"><li>Import .scl</li></a>
<a href="#" @click="anamarkFile!.click()"><li>Import .tun</li></a>
<a href="#" @click="xendevsFile!.click()"><li>Import .swi</li></a>
<li class="divider"></li>
<a href="#" @click="clearScale"><li>Clear scale</li></a>
<a href="#" @click="showPresetModal = true"><li>Load preset scale</li></a>
Expand All @@ -166,6 +168,13 @@ defineExpose({ blur })
style="display: none"
@change="doImport('anamark', $event)"
/>
<input
type="file"
ref="xendevsFile"
accept=".swi"
style="display: none"
@change="doImport('xendevs', $event)"
/>

<Teleport to="body">
<!-- v-if is required to prevent premature asyncs while :show makes the focus watcher trigger -->
Expand Down
35 changes: 35 additions & 0 deletions src/importers/__tests__/xen-devs.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { describe, it, expect } from 'vitest'

import { SonicWeaveInterchangeImporter } from '../xen-devs'

describe('SonicWeave Interchange importer', () => {
it('can parse text', () => {
const importer = new SonicWeaveInterchangeImporter()
const { sourceText, name } = importer.parseText(`
(* Created using SWI exporter unit test v0.0.0 *)
"Unit Test Scale"
1 = [1 3 1 1>@Hz.2.5.11
[1/12> "" niente
[1 1 -1> "" niente
[4/5> "" niente
[0 -1 1> "" niente
[531.234049066756>@rc "" niente
[-20 20 -5> "" niente
[1> "" niente
`)

expect(name).toBe('Unit Test Scale')
expect(sourceText).toBe(`"Unit Test Scale"
1/1 = 440 Hz
1\\12
6/5
4\\5
5/3
531.2340490667464r¢
3486784401/3276800000
2`)
})
})
4 changes: 3 additions & 1 deletion src/importers/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import type { ImportResult } from '@/importers/base'
import { AnaMarkImporter } from '@/importers/anamark'
import { ScalaImporter } from '@/importers/scala'
import { SonicWeaveInterchangeImporter } from '@/importers/xen-devs'

const IMPORTERS = {
scalascl: ScalaImporter,
anamark: AnaMarkImporter
anamark: AnaMarkImporter,
xendevs: SonicWeaveInterchangeImporter
}

export type ImporterKey = keyof typeof IMPORTERS
Expand Down
23 changes: 23 additions & 0 deletions src/importers/xen-devs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { TextImporter, type ImportResult } from '@/importers/base'
import { RootContext, getSourceVisitor, parseAST } from 'sonic-weave'

// Specs: https://github.com/xenharmonic-devs/sonic-weave/blob/main/documentation/interchange.md
export class SonicWeaveInterchangeImporter extends TextImporter {
parseText(input: string): ImportResult {
const ast = parseAST(input)
const visitor = getSourceVisitor(false)
visitor.executeProgram(ast)
for (const interval of visitor.currentScale) {
// Strip interchange format
interval.node = undefined
if (interval.isRelative() && interval.value.isFractional()) {
interval.domain = 'linear'
}
}
const result = {
name: visitor.rootContext?.title,
sourceText: visitor.expand(new RootContext())
}
return result
}
}

0 comments on commit 8105bdb

Please sign in to comment.