From c6cd4aa15b0111ae5a19b6408b2eb57a29e538a6 Mon Sep 17 00:00:00 2001 From: Nanashi Date: Thu, 27 Jun 2024 19:34:39 +0900 Subject: [PATCH] Update: Update texts for tssln (#174) * Update: Update texts * Update: kotlinUpgradeYarnLock * Fix: Fix around esm import * Code: Format --- README.md | 7 ++- core/build.gradle.kts | 2 +- .../main/kotlin/core/external/ValueTree.kt | 59 ++----------------- core/src/main/kotlin/core/io/Tssln.kt | 21 +++---- core/src/main/kotlin/core/model/ValueTree.kt | 57 ++++++++++++++++++ kotlin-js-store/yarn.lock | 8 +-- src/jsMain/kotlin/ui/strings/Strings.kt | 10 ++-- 7 files changed, 86 insertions(+), 78 deletions(-) create mode 100644 core/src/main/kotlin/core/model/ValueTree.kt diff --git a/README.md b/README.md index 2f5946f..fe4c56e 100644 --- a/README.md +++ b/README.md @@ -11,10 +11,10 @@ and [React](https://github.com/facebook/react). - Supported importing formats: `.vsqx(3/4)`, `.vpr`, `.vsq`, `.mid(VOCALOID)`, `.mid(standard)`, `.ust`, `.ustx`, `.ccs`,`.xml(MusicXML)` - , `.musicxml`, `.svp`, `.s5p`, `.dv`, `.ppsf(NT)`, `.ufdata` + , `.musicxml`, `.svp`, `.s5p`, `.dv`, `.ppsf(NT)`, `.tssln`, `.ufdata` - Supported exporting formats: `.vsqx(4)`, `.vpr`, `.vsq`, `.mid(VOCALOID)`, `.mid(standard)`, `.ust`, `.ustx`, `.ccs`, `.xml(MusicXML)` - , `.svp`, `.s5p`, `.dv`, `.ufdata` + , `.svp`, `.s5p`, `.dv`, `.tssln`, `.ufdata` - Keep information including: tracks, notes, tempo labels, time signatures - Detect and convert Japanese lyrics types - between CV and VCV @@ -37,6 +37,7 @@ and [React](https://github.com/facebook/react). | SVP | ✓ | ✓ | ✓ | | S5P | ✓ | | ✓ | | DV | ✓ | ✓ | ✓ | +| Tssln | ✓ | | | ## Open format published (.ufdata) @@ -48,7 +49,7 @@ If you are developing OSS projects related to singing voice synthesis, you may f ## Contributors [sdercolin](https://github.com/sdercolin), [ghosrt](https://github.com/ghosrt), [shine5402](https://github.com/shine5402), [adlez27](https://github.com/adlez27), [ -General Nuisance](https://github.com/GeneralNuisance0) +General Nuisance](https://github.com/GeneralNuisance0), [sevenc-nanashi](https://github.com/sevenc-nanashi) ## Localization help diff --git a/core/build.gradle.kts b/core/build.gradle.kts index 63c1b94..58a1d2d 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -25,7 +25,7 @@ kotlin { implementation(npm("midi-file", "1.2.4")) implementation(npm("js-yaml", "4.1.0")) implementation( - npm("@sevenc-nanashi/valuetree-ts", "npm:@jsr/sevenc-nanashi__valuetree-ts@0.2.0"), + npm("@sevenc-nanashi/valuetree-ts", "npm:@jsr/sevenc-nanashi__valuetree-ts@0.2.1"), ) } } diff --git a/core/src/main/kotlin/core/external/ValueTree.kt b/core/src/main/kotlin/core/external/ValueTree.kt index 62c18c7..3ebfb9b 100644 --- a/core/src/main/kotlin/core/external/ValueTree.kt +++ b/core/src/main/kotlin/core/external/ValueTree.kt @@ -1,65 +1,14 @@ +@file:JsModule("@sevenc-nanashi/valuetree-ts") + package core.external import org.khronos.webgl.Uint8Array -fun createValueTree(): ValueTree { - return js("{type: '', attributes: {}, children: []}").unsafeCast() -} - -fun baseVariantType(): dynamic { - return js("({type: '', value: undefined})") -} - -fun String.toVariantType(): dynamic { - val value = baseVariantType() - value.type = "string" - value.value = this - - return value -} -fun Int.toVariantType(): dynamic { - val value = baseVariantType() - value.type = "int" - value.value = this - - return value -} -fun Double.toVariantType(): dynamic { - val value = baseVariantType() - value.type = "double" - value.value = this - - return value -} -fun Boolean.toVariantType(): dynamic { - val value = baseVariantType() - if (this) { - value.type = "boolTrue" - value.value = true - } else { - value.type = "boolFalse" - value.value = false - } - - return value -} -fun Uint8Array.toVariantType(): dynamic { - val value = baseVariantType() - value.type = "binary" - value.value = this - - return value -} - external interface ValueTree { var type: String var attributes: dynamic var children: Array } -@JsModule("@sevenc-nanashi/valuetree-ts") -@JsNonModule -external object ValueTreeTs { - fun parseValueTree(text: Uint8Array): ValueTree - fun dumpValueTree(tree: ValueTree): Uint8Array -} +external fun parseValueTree(text: Uint8Array): ValueTree +external fun dumpValueTree(tree: ValueTree): Uint8Array diff --git a/core/src/main/kotlin/core/io/Tssln.kt b/core/src/main/kotlin/core/io/Tssln.kt index 9855d22..4577ddc 100644 --- a/core/src/main/kotlin/core/io/Tssln.kt +++ b/core/src/main/kotlin/core/io/Tssln.kt @@ -3,10 +3,9 @@ package core.io import core.exception.IllegalFileException import core.external.Resources import core.external.ValueTree -import core.external.ValueTreeTs -import core.external.createValueTree +import core.external.dumpValueTree +import core.external.parseValueTree import core.external.structuredClone -import core.external.toVariantType import core.model.ExportResult import core.model.Format import core.model.ImportParams @@ -17,6 +16,8 @@ import core.model.TICKS_IN_BEAT import core.model.Tempo import core.model.TimeSignature import core.model.Track +import core.model.createValueTree +import core.model.toVariantType import core.util.nameWithoutExtension import core.util.readAsArrayBuffer import org.khronos.webgl.Uint8Array @@ -27,7 +28,7 @@ import kotlin.math.floor object Tssln { suspend fun parse(file: File, params: ImportParams): Project { val blob = file.readAsArrayBuffer() - val valueTree = ValueTreeTs.parseValueTree( + val valueTree = parseValueTree( Uint8Array(blob), ) @@ -62,7 +63,7 @@ object Tssln { return trackTrees.mapIndexed { trackIndex, trackTree -> val trackName = trackTree.attributes.Name.value as String val pluginData = trackTree.attributes.PluginData.value as Uint8Array - val pluginDataTree = ValueTreeTs.parseValueTree(pluginData) + val pluginDataTree = parseValueTree(pluginData) if (pluginDataTree.type != "StateInformation") { throw IllegalFileException.IllegalTsslnFile() @@ -110,7 +111,7 @@ object Tssln { private fun parseMasterTrack(trackTree: ValueTree): Pair, List> { val pluginData = trackTree.attributes.PluginData.value as Uint8Array - val pluginDataTree = ValueTreeTs.parseValueTree(pluginData) + val pluginDataTree = parseValueTree(pluginData) if (pluginDataTree.type != "StateInformation") { throw IllegalFileException.IllegalTsslnFile() } @@ -171,7 +172,7 @@ object Tssln { fun generate(project: Project): ExportResult { val baseJson = Resources.tsslnTemplate - val baseTree = ValueTreeTs.parseValueTree(Uint8Array(baseJson)) + val baseTree = parseValueTree(Uint8Array(baseJson)) val tracksTree = baseTree.children.first { it.type == "Tracks" } val baseTrack = tracksTree.children.first { it.attributes.Type.value == 0 } @@ -179,7 +180,7 @@ object Tssln { val tracks = generateTracks(baseTrack, project) tracksTree.children = tracks.toTypedArray() - val result = ValueTreeTs.dumpValueTree(baseTree) + val result = dumpValueTree(baseTree) return ExportResult( Blob(arrayOf(result)), @@ -194,7 +195,7 @@ object Tssln { trackTree.attributes.Name = (track.name).toVariantType() val pluginData = trackTree.attributes.PluginData.value as Uint8Array - val pluginDataTree = ValueTreeTs.parseValueTree(pluginData) + val pluginDataTree = parseValueTree(pluginData) val songTree = pluginDataTree.children.first { it.type == "Song" } @@ -213,7 +214,7 @@ object Tssln { scoreTree.children = newChildren.toTypedArray() - trackTree.attributes.PluginData = (ValueTreeTs.dumpValueTree(pluginDataTree)).toVariantType() + trackTree.attributes.PluginData = dumpValueTree(pluginDataTree).toVariantType() trackTree } diff --git a/core/src/main/kotlin/core/model/ValueTree.kt b/core/src/main/kotlin/core/model/ValueTree.kt new file mode 100644 index 0000000..d425e41 --- /dev/null +++ b/core/src/main/kotlin/core/model/ValueTree.kt @@ -0,0 +1,57 @@ +package core.model + +import core.external.ValueTree +import org.khronos.webgl.Uint8Array + +fun createValueTree(): ValueTree { + return js("{type: '', attributes: {}, children: []}").unsafeCast() +} + +fun baseVariantType(): dynamic { + return js("({type: '', value: undefined})") +} + +fun String.toVariantType(): dynamic { + val value = baseVariantType() + value.type = "string" + value.value = this + + return value +} + +fun Int.toVariantType(): dynamic { + val value = baseVariantType() + value.type = "int" + value.value = this + + return value +} + +fun Double.toVariantType(): dynamic { + val value = baseVariantType() + value.type = "double" + value.value = this + + return value +} + +fun Boolean.toVariantType(): dynamic { + val value = baseVariantType() + if (this) { + value.type = "boolTrue" + value.value = true + } else { + value.type = "boolFalse" + value.value = false + } + + return value +} + +fun Uint8Array.toVariantType(): dynamic { + val value = baseVariantType() + value.type = "binary" + value.value = this + + return value +} diff --git a/kotlin-js-store/yarn.lock b/kotlin-js-store/yarn.lock index 6c7b4b0..b1ffdb1 100644 --- a/kotlin-js-store/yarn.lock +++ b/kotlin-js-store/yarn.lock @@ -472,10 +472,10 @@ estree-walker "^1.0.1" picomatch "^2.2.2" -"@sevenc-nanashi/valuetree-ts@npm:@jsr/sevenc-nanashi__valuetree-ts@0.2.0": - version "0.2.0" - resolved "https://npm.jsr.io/~/11/@jsr/sevenc-nanashi__valuetree-ts/0.2.0.tgz#C54B3DEB79C6EDB635DFF2D1B9E96CA29D513BA8" - integrity sha512-dKhOyTjwUxAlzOzynXhrk41Jb+dYkO/GhffXQoeo5UW/Vh62JfA6N0QKmoy004HJ1sv5SMsMD5Toqqrg9+yRKg== +"@sevenc-nanashi/valuetree-ts@npm:@jsr/sevenc-nanashi__valuetree-ts@0.2.1": + version "0.2.1" + resolved "https://npm.jsr.io/~/11/@jsr/sevenc-nanashi__valuetree-ts/0.2.1.tgz#3495BD76DAEE8C017E6445F318661B6FA8222D58" + integrity sha512-I2ezsDocwuBu9ItJRNZ094Z9DTf1K1SNLfQR8NL2FVDT/YMFrzqPrjilxATwjEK7so8Qw580myZVH5e6/S3V2Q== dependencies: "@jsr/sevenc-nanashi__binaryseeker" "^1.0.0" diff --git a/src/jsMain/kotlin/ui/strings/Strings.kt b/src/jsMain/kotlin/ui/strings/Strings.kt index ff0a85f..c4d3703 100644 --- a/src/jsMain/kotlin/ui/strings/Strings.kt +++ b/src/jsMain/kotlin/ui/strings/Strings.kt @@ -477,15 +477,15 @@ enum class Strings( ), ImportFileSubDescription( en = "Supported file types: VSQX, VPR, VSQ, MID, USTs," + - " USTX, CCS, MUSICXML, XML, SVP, S5P, DV, PPSF(NT), UFDATA", + " USTX, CCS, MUSICXML, XML, SVP, S5P, DV, PPSF(NT), TSSLN, UFDATA", ja = "サポートされているファイル形式:VSQX、VPR、VSQ、MID、UST(複数可)、" + - "USTX、CCS、MUSICXML、XML、SVP、S5P、DV、PPSF(NT)、UFDATA", + "USTX、CCS、MUSICXML、XML、SVP、S5P、DV、PPSF(NT)、TSSLN、UFDATA", zhCN = "支持的文件类型:VSQX、VPR、VSQ、MID、UST(允许复数个)、" + - "USTX、CCS、MUSICXML、XML、SVP、S5P、DV、PPSF(NT)、UFDATA", + "USTX、CCS、MUSICXML、XML、SVP、S5P、DV、PPSF(NT)、TSSLN、UFDATA", ru = "Поддерживаемые форматы файлов: VSQx, VPR, VSQ, MID, UST," + - " USTX, CCS, MusicXML, XML, SVP, S5P, DV, PPSF(NT), UFDATA", + " USTX, CCS, MusicXML, XML, SVP, S5P, DV, PPSF(NT), TSSLN, UFDATA", fr = "Types de fichiers pris en charge : VSQX, VPR, VSQ, MID, USTs," + - " USTX, CCS, MUSICXML, XML, SVP, S5P, DV, PPSF(NT), UFDATA", + " USTX, CCS, MUSICXML, XML, SVP, S5P, DV, PPSF(NT), TSSLN, UFDATA", ), UnsupportedFileTypeImportError( en = "Unsupported file type",