Add channel selection
This commit is contained in:
@@ -59,6 +59,7 @@ enum class Waveform {
|
|||||||
@ExperimentalJsExport
|
@ExperimentalJsExport
|
||||||
@JsExport
|
@JsExport
|
||||||
class VstChipProcessor : AudioWorkletProcessor() {
|
class VstChipProcessor : AudioWorkletProcessor() {
|
||||||
|
var midiChannel = 0
|
||||||
val notes = Array(POLYPHONICS) {
|
val notes = Array(POLYPHONICS) {
|
||||||
PlayingNote(
|
PlayingNote(
|
||||||
0
|
0
|
||||||
@@ -78,41 +79,58 @@ class VstChipProcessor : AudioWorkletProcessor() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun handleMessage(message: MessageEvent) {
|
private fun handleMessage(message: MessageEvent) {
|
||||||
//console.log("VstChipProcessor: Received message", message)
|
console.log("VstChipProcessor: Received message:", message.data)
|
||||||
|
|
||||||
val data = message.data
|
val data = message.data
|
||||||
|
|
||||||
when (data) {
|
try {
|
||||||
"test_on" -> {
|
when (data) {
|
||||||
playMidi(Int32Array(arrayOf(0x90, 60, 64)))
|
is String -> {
|
||||||
|
if (data.startsWith("set_channel")) {
|
||||||
}
|
val parts = data.split('\n')
|
||||||
"test_off" -> {
|
if (parts.size == 2) {
|
||||||
playMidi(Int32Array(arrayOf(0x90, 60, 0)))
|
midiChannel = parts[1].toInt()
|
||||||
}
|
println("Setting channel: $midiChannel")
|
||||||
is String -> {
|
}
|
||||||
}
|
}
|
||||||
is ArrayBuffer -> {
|
|
||||||
}
|
|
||||||
is Uint8Array -> {
|
|
||||||
val data32 = Int32Array(data.length)
|
|
||||||
for (i in 0 until data.length) {
|
|
||||||
data32[i] = (data[i].toInt() and 0xff)
|
|
||||||
}
|
}
|
||||||
playMidi(data32)
|
|
||||||
|
is Uint8Array -> {
|
||||||
|
val data32 = Int32Array(data.length)
|
||||||
|
for (i in 0 until data.length) {
|
||||||
|
data32[i] = (data[i].toInt() and 0xff)
|
||||||
|
}
|
||||||
|
playMidi(data32)
|
||||||
|
}
|
||||||
|
|
||||||
|
is Int32Array -> {
|
||||||
|
playMidi(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
else ->
|
||||||
|
console.error("Don't kow how to handle message", message)
|
||||||
}
|
}
|
||||||
is Int32Array -> {
|
} catch(e: Exception) {
|
||||||
playMidi(data)
|
console.log(e.message, e)
|
||||||
}
|
|
||||||
else ->
|
|
||||||
console.error("Don't kow how to handle message", message)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun playMidi(bytes: Int32Array) {
|
private fun playMidi(bytes: Int32Array) {
|
||||||
|
console.log("playMidi", bytes)
|
||||||
if (bytes.length > 0) {
|
if (bytes.length > 0) {
|
||||||
|
var cmdByte = bytes[0]
|
||||||
|
val channelCmd = ((cmdByte shr 4) and 0xf) in 0x8 .. 0xe
|
||||||
|
val channel = cmdByte and 0xf
|
||||||
|
println("Channel cmd: $channelCmd")
|
||||||
|
if (channelCmd && channel != midiChannel) {
|
||||||
|
console.log("Wrong channel", midiChannel, bytes)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
cmdByte = cmdByte and 0xf0
|
||||||
|
|
||||||
//console.log("Received", bytes)
|
//console.log("Received", bytes)
|
||||||
when(bytes[0]) {
|
when(cmdByte) {
|
||||||
0x90 -> {
|
0x90 -> {
|
||||||
if (bytes.length == 3) {
|
if (bytes.length == 3) {
|
||||||
val note = bytes[1]
|
val note = bytes[1]
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ buildscript {
|
|||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
kotlin("multiplatform")
|
kotlin("multiplatform")
|
||||||
kotlin("plugin.serialization")
|
|
||||||
id("maven-publish")
|
id("maven-publish")
|
||||||
application
|
application
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
pluginManagement {
|
pluginManagement {
|
||||||
plugins {
|
plugins {
|
||||||
kotlin("multiplatform") version "2.0.0"
|
kotlin("multiplatform") version "2.0.0"
|
||||||
kotlin("plugin.serialization") version "2.0.0"
|
|
||||||
id("org.gradle.toolchains.foojay-resolver-convention") version "0.5.0"
|
id("org.gradle.toolchains.foojay-resolver-convention") version "0.5.0"
|
||||||
}
|
}
|
||||||
repositories {
|
repositories {
|
||||||
|
|||||||
@@ -54,6 +54,9 @@ abstract class AudioNode(
|
|||||||
abstract fun onMessage(message: MessageEvent)
|
abstract fun onMessage(message: MessageEvent)
|
||||||
|
|
||||||
open fun postMessage(msg: Any) {
|
open fun postMessage(msg: Any) {
|
||||||
|
if (port == null) {
|
||||||
|
console.log("postMessage port is NULL!")
|
||||||
|
}
|
||||||
port?.postMessage(msg)
|
port?.postMessage(msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import kotlinx.html.h1
|
|||||||
import kotlinx.html.input
|
import kotlinx.html.input
|
||||||
import kotlinx.html.js.onChangeFunction
|
import kotlinx.html.js.onChangeFunction
|
||||||
import kotlinx.html.js.onClickFunction
|
import kotlinx.html.js.onClickFunction
|
||||||
|
import kotlinx.html.js.onInputFunction
|
||||||
import kotlinx.html.option
|
import kotlinx.html.option
|
||||||
import kotlinx.html.select
|
import kotlinx.html.select
|
||||||
import kotlinx.html.span
|
import kotlinx.html.span
|
||||||
@@ -111,9 +112,11 @@ object MainView : Komponent() {
|
|||||||
input {
|
input {
|
||||||
type = InputType.number
|
type = InputType.number
|
||||||
value = Midi.inputChannel.toString()
|
value = Midi.inputChannel.toString()
|
||||||
onChangeFunction = { event ->
|
onInputFunction = { event ->
|
||||||
val target = event.target as HTMLInputElement
|
val target = event.target as HTMLInputElement
|
||||||
Midi.inputChannel = target.value.toInt()
|
Midi.inputChannel = target.value.toInt()
|
||||||
|
println("onInput channel: ${Midi.inputChannel}")
|
||||||
|
VstChipWorklet.postMessage("set_channel\n${Midi.inputChannel}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -155,7 +158,7 @@ object MainView : Komponent() {
|
|||||||
input {
|
input {
|
||||||
type = InputType.number
|
type = InputType.number
|
||||||
value = Midi.outputChannel.toString()
|
value = Midi.outputChannel.toString()
|
||||||
onChangeFunction = { event ->
|
onInputFunction = { event ->
|
||||||
val target = event.target as HTMLInputElement
|
val target = event.target as HTMLInputElement
|
||||||
Midi.outputChannel = target.value.toInt()
|
Midi.outputChannel = target.value.toInt()
|
||||||
}
|
}
|
||||||
@@ -230,6 +233,8 @@ object MainView : Komponent() {
|
|||||||
margin(1.rem)
|
margin(1.rem)
|
||||||
padding(1.rem)
|
padding(1.rem)
|
||||||
backgroundColor(Css.currentStyle.buttonBackgroundColor)
|
backgroundColor(Css.currentStyle.buttonBackgroundColor)
|
||||||
|
borderColor(Css.currentStyle.buttonBorderColor)
|
||||||
|
borderWidth(Css.currentStyle.buttonBorderWidth)
|
||||||
color(Css.currentStyle.mainFontColor)
|
color(Css.currentStyle.mainFontColor)
|
||||||
|
|
||||||
hover {
|
hover {
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ class StyleDefinition(
|
|||||||
val inputBackgroundColor : Color = mainBackgroundColor.lighten(15),
|
val inputBackgroundColor : Color = mainBackgroundColor.lighten(15),
|
||||||
val buttonBackgroundColor : Color = mainBackgroundColor.lighten(15),
|
val buttonBackgroundColor : Color = mainBackgroundColor.lighten(15),
|
||||||
val buttonBorderColor : Color = mainFontColor.changeAlpha(0.25),
|
val buttonBorderColor : Color = mainFontColor.changeAlpha(0.25),
|
||||||
val buttonBorderWidth : Measurement = 2.px,
|
val buttonBorderWidth : Measurement = 1.px,
|
||||||
)
|
)
|
||||||
|
|
||||||
object NoTextSelectCls : CssName("no-text-select")
|
object NoTextSelectCls : CssName("no-text-select")
|
||||||
|
|||||||
Reference in New Issue
Block a user