From 7fe29916f7b576d0c226179e9f84a79a27d5ab78 Mon Sep 17 00:00:00 2001 From: rnentjes Date: Thu, 27 Mar 2025 19:33:43 +0100 Subject: [PATCH] Refactor MainView and enhance View management Replaced `MainView` object with a `Views` singleton for better modularity and lazy initialization. Adjusted CSS structure, updated dependencies, and improved FM/AM modulation logic for greater flexibility. Additionally, upgraded Kotlin multiplatform version and added inline source mapping. --- .../nl/astraeus/vst/chip/ChipProcessor.kt | 6 +- build.gradle.kts | 24 ++------ settings.common.gradle.kts | 2 +- .../kotlin/nl/astraeus/vst/chip/Main.kt | 16 +++-- .../astraeus/vst/chip/audio/VstChipWorklet.kt | 16 ++--- .../kotlin/nl/astraeus/vst/chip/midi/Midi.kt | 4 +- .../nl/astraeus/vst/chip/view/MainView.kt | 60 ++++++++++--------- .../astraeus/vst/chip/ws/WebsocketClient.kt | 4 +- 8 files changed, 66 insertions(+), 66 deletions(-) diff --git a/audio-worklet/src/jsMain/kotlin/nl/astraeus/vst/chip/ChipProcessor.kt b/audio-worklet/src/jsMain/kotlin/nl/astraeus/vst/chip/ChipProcessor.kt index 5e4f515..039c719 100644 --- a/audio-worklet/src/jsMain/kotlin/nl/astraeus/vst/chip/ChipProcessor.kt +++ b/audio-worklet/src/jsMain/kotlin/nl/astraeus/vst/chip/ChipProcessor.kt @@ -73,7 +73,7 @@ class VstChipProcessor : AudioWorkletProcessor() { var waveform = Waveform.SINE.ordinal var volume = 0.75f var dutyCycle = 0.5 - var fmFreq = 0.0 + var fmFreq = 0.5 var fmAmp = 0.0 var amFreq = 0.0 var amAmp = 0.0 @@ -340,8 +340,10 @@ class VstChipProcessor : AudioWorkletProcessor() { } var cycleOffset = note.cycleOffset + val fmMult = sin(currentTime * fmFreq * midiNote.freq * 2f * PI2) * fmAmp val fmModulation = - sampleDelta + (sin(fmFreq * 1000f * PI2 * (note.sample / sampleRate.toDouble())).toFloat() * (100f * fmAmp * sampleDelta)) + sampleDelta * fmMult //+ (sin(fmFreq * 1000f * PI2 * (note.sample / sampleRate.toDouble())).toFloat() * (100f * fmAmp * sampleDelta)) + val amModulation = 1f + (sin(sampleLength * amFreq * 1000f * PI2 * note.sample) * amAmp).toFloat() diff --git a/build.gradle.kts b/build.gradle.kts index f6f7b19..c20eed9 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -25,6 +25,7 @@ kotlin { commonWebpackConfig { outputFileName = "vst-chip-worklet-ui.js" sourceMaps = true + devtool = "inline-source-map" } distribution { @@ -56,14 +57,16 @@ kotlin { val commonMain by getting { dependencies { //base - implementation("nl.astraeus:kotlin-css-generator:1.0.10") - implementation("nl.astraeus:vst-ui-base:1.2.0") + //implementation("nl.astraeus:kotlin-css-generator:1.0.10") + api("nl.astraeus:vst-ui-base:2.0.0-SNAPSHOT") implementation("nl.astraeus:midi-arrays:0.3.2") } } val jsMain by getting { dependencies { + /* implementation("nl.astraeus:kotlin-komponent:1.2.4") + */ } } val jsTest by getting { @@ -77,22 +80,7 @@ kotlin { implementation("nl.astraeus:vst-ui-base:1.0.1-SNAPSHOT") } }*/ - val jvmMain by getting { - dependencies { - //base - implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.6.0") - - implementation("io.undertow:undertow-core:2.3.14.Final") - implementation("io.undertow:undertow-websockets-jsr:2.3.14.Final") - implementation("org.jboss.xnio:xnio-nio:3.8.16.Final") - - implementation("org.xerial:sqlite-jdbc:3.46.0.0") - implementation("com.zaxxer:HikariCP:4.0.3") - implementation("nl.astraeus:simple-jdbc-stats:1.6.1") - - implementation("org.jetbrains.kotlinx:kotlinx-html-jvm:0.11.0") - } - } + val jvmMain by getting } } diff --git a/settings.common.gradle.kts b/settings.common.gradle.kts index ededdda..2a6468b 100644 --- a/settings.common.gradle.kts +++ b/settings.common.gradle.kts @@ -1,6 +1,6 @@ pluginManagement { plugins { - kotlin("multiplatform") version "2.1.0" + kotlin("multiplatform") version "2.1.10" } repositories { gradlePluginPortal() diff --git a/src/jsMain/kotlin/nl/astraeus/vst/chip/Main.kt b/src/jsMain/kotlin/nl/astraeus/vst/chip/Main.kt index d15f86e..b289a7d 100644 --- a/src/jsMain/kotlin/nl/astraeus/vst/chip/Main.kt +++ b/src/jsMain/kotlin/nl/astraeus/vst/chip/Main.kt @@ -9,12 +9,20 @@ import nl.astraeus.vst.chip.view.MainView import nl.astraeus.vst.chip.ws.WebsocketClient import nl.astraeus.vst.ui.css.CssSettings -fun main() { - CssSettings.shortId = false - CssSettings.preFix = "vst-chip" +object Views { + val mainView by lazy { + MainView() + } + init { + CssSettings.shortId = false + CssSettings.preFix = "vst" + } +} + +fun main() { Komponent.unsafeMode = UnsafeMode.UNSAFE_SVG_ONLY - Komponent.create(document.body!!, MainView) + Komponent.create(document.body!!, Views.mainView) Midi.start() diff --git a/src/jsMain/kotlin/nl/astraeus/vst/chip/audio/VstChipWorklet.kt b/src/jsMain/kotlin/nl/astraeus/vst/chip/audio/VstChipWorklet.kt index 9bbbdbb..0554361 100644 --- a/src/jsMain/kotlin/nl/astraeus/vst/chip/audio/VstChipWorklet.kt +++ b/src/jsMain/kotlin/nl/astraeus/vst/chip/audio/VstChipWorklet.kt @@ -4,7 +4,7 @@ package nl.astraeus.vst.chip.audio import nl.astraeus.midi.message.TimedMidiMessage import nl.astraeus.vst.chip.PatchDTO -import nl.astraeus.vst.chip.view.MainView +import nl.astraeus.vst.chip.Views import nl.astraeus.vst.chip.view.WaveformView import org.khronos.webgl.Float32Array import org.w3c.dom.MessageEvent @@ -40,7 +40,7 @@ object VstChipWorklet : AudioNode( 0xb0 + midiChannel, 0x47, (value * 127).toInt() ) } - var fmModFreq = 0.0 + var fmModFreq = 1.0 set(value) { field = value super.postMessage( @@ -168,32 +168,32 @@ object VstChipWorklet : AudioNode( when (knob) { 0x46.toByte() -> { volume = value / 127.0 - MainView.requestUpdate() + Views.mainView.requestUpdate() } 0x4a.toByte() -> { dutyCycle = value / 127.0 - MainView.requestUpdate() + Views.mainView.requestUpdate() } 0x40.toByte() -> { fmModFreq = value / 127.0 - MainView.requestUpdate() + Views.mainView.requestUpdate() } 0x41.toByte() -> { fmModAmp = value / 127.0 - MainView.requestUpdate() + Views.mainView.requestUpdate() } 0x42.toByte() -> { amModFreq = value / 127.0 - MainView.requestUpdate() + Views.mainView.requestUpdate() } 0x43.toByte() -> { amModAmp = value / 127.0 - MainView.requestUpdate() + Views.mainView.requestUpdate() } } } diff --git a/src/jsMain/kotlin/nl/astraeus/vst/chip/midi/Midi.kt b/src/jsMain/kotlin/nl/astraeus/vst/chip/midi/Midi.kt index 76e3256..32aa8ee 100644 --- a/src/jsMain/kotlin/nl/astraeus/vst/chip/midi/Midi.kt +++ b/src/jsMain/kotlin/nl/astraeus/vst/chip/midi/Midi.kt @@ -2,9 +2,9 @@ package nl.astraeus.vst.chip.midi import kotlinx.browser.window import nl.astraeus.midi.message.TimedMidiMessage +import nl.astraeus.vst.chip.Views import nl.astraeus.vst.chip.audio.AudioContextHandler import nl.astraeus.vst.chip.audio.VstChipWorklet -import nl.astraeus.vst.chip.view.MainView import org.khronos.webgl.Uint8Array import org.khronos.webgl.get @@ -68,7 +68,7 @@ object Midi { outputs.add(output) } - MainView.requestUpdate() + Views.mainView.requestUpdate() }, { e -> println("Failed to get MIDI access - $e") diff --git a/src/jsMain/kotlin/nl/astraeus/vst/chip/view/MainView.kt b/src/jsMain/kotlin/nl/astraeus/vst/chip/view/MainView.kt index bf72574..b774793 100644 --- a/src/jsMain/kotlin/nl/astraeus/vst/chip/view/MainView.kt +++ b/src/jsMain/kotlin/nl/astraeus/vst/chip/view/MainView.kt @@ -37,6 +37,7 @@ import nl.astraeus.komp.Komponent import nl.astraeus.komp.currentElement import nl.astraeus.midi.message.TimedMidiMessage import nl.astraeus.midi.message.getCurrentTime +import nl.astraeus.vst.chip.Views import nl.astraeus.vst.chip.audio.VstChipWorklet import nl.astraeus.vst.chip.audio.VstChipWorklet.midiChannel import nl.astraeus.vst.chip.midi.Midi @@ -61,7 +62,7 @@ object WaveformView: Komponent() { } fun onAnimationFrame(time: Double) { - if (MainView.started) { + if (Views.mainView.started) { VstChipWorklet.postMessage("start_recording") } @@ -98,7 +99,7 @@ object WaveformView: Komponent() { } } -object MainView : Komponent(), CssName { +class MainView : Komponent() { private var messages: MutableList = ArrayList() var started = false @@ -275,7 +276,7 @@ object MainView : Komponent(), CssName { value = VstChipWorklet.fmModFreq, label = "FM Freq", minValue = 0.0, - maxValue = 1.0, + maxValue = 2.0, step = 5.0 / 127.0, width = 100, height = 120, @@ -420,18 +421,19 @@ object MainView : Komponent(), CssName { } } - object MainDivCss : CssName - object ActiveCss : CssName - object ButtonCss : CssName - object ButtonBarCss : CssName - object SelectedCss : CssName - object NoteBarCss : CssName - object StartSplashCss : CssName - object StartBoxCss : CssName - object StartButtonCss : CssName - object ControlsCss : CssName + companion object MainViewCss : CssName() { + object MainDivCss : CssName() + object ActiveCss : CssName() + object ButtonCss : CssName() + object ButtonBarCss : CssName() + object SelectedCss : CssName() + object NoteBarCss : CssName() + object StartSplashCss : CssName() + object StartBoxCss : CssName() + object StartButtonCss : CssName() + object ControlsCss : CssName() - private fun css() { + private fun css() { defineCss { select("*") { select("*:before") { @@ -530,23 +532,23 @@ object MainView : Komponent(), CssName { backgroundColor(Css.currentStyle.mainBackgroundColor) } } - } - - private fun Style.commonButton() { - display(Display.inlineBlock) - padding(1.rem) - backgroundColor(Css.currentStyle.buttonBackgroundColor) - borderColor(Css.currentStyle.buttonBorderColor) - borderWidth(Css.currentStyle.buttonBorderWidth) - color(Css.currentStyle.mainFontColor) - - hover { - backgroundColor(Css.currentStyle.buttonBackgroundColor.hover()) } - and(SelectedCss.cls()) { - backgroundColor(Css.currentStyle.buttonBackgroundColor.hover().hover().hover()) + + private fun Style.commonButton() { + display(Display.inlineBlock) + padding(1.rem) + backgroundColor(Css.currentStyle.buttonBackgroundColor) + borderColor(Css.currentStyle.buttonBorderColor) + borderWidth(Css.currentStyle.buttonBorderWidth) + color(Css.currentStyle.mainFontColor) + + hover { + backgroundColor(Css.currentStyle.buttonBackgroundColor.hover()) + } + and(SelectedCss.cls()) { + backgroundColor(Css.currentStyle.buttonBackgroundColor.hover().hover().hover()) + } } } - } diff --git a/src/jsMain/kotlin/nl/astraeus/vst/chip/ws/WebsocketClient.kt b/src/jsMain/kotlin/nl/astraeus/vst/chip/ws/WebsocketClient.kt index 725f441..ee8381d 100644 --- a/src/jsMain/kotlin/nl/astraeus/vst/chip/ws/WebsocketClient.kt +++ b/src/jsMain/kotlin/nl/astraeus/vst/chip/ws/WebsocketClient.kt @@ -4,9 +4,9 @@ package nl.astraeus.vst.chip.ws import kotlinx.browser.window import nl.astraeus.vst.chip.PatchDTO +import nl.astraeus.vst.chip.Views import nl.astraeus.vst.chip.audio.VstChipWorklet import nl.astraeus.vst.chip.midi.Midi -import nl.astraeus.vst.chip.view.MainView import org.w3c.dom.MessageEvent import org.w3c.dom.WebSocket import org.w3c.dom.events.Event @@ -90,7 +90,7 @@ object WebsocketClient { Midi.setInput(patch.midiId, patch.midiName) VstChipWorklet.load(patch) - MainView.requestUpdate() + Views.mainView.requestUpdate() } } }