Files
vst-string/src/jsMain/kotlin/nl/astraeus/vst/chip/audio/AudioModule.kt
2024-06-26 14:10:03 +02:00

91 lines
1.9 KiB
Kotlin

package nl.astraeus.vst.chip.audio
import nl.astraeus.vst.chip.AudioWorkletNode
import nl.astraeus.vst.chip.AudioWorkletNodeParameters
import nl.astraeus.vst.chip.audio.AudioContextHandler.audioContext
import org.w3c.dom.MessageEvent
import org.w3c.dom.MessagePort
enum class ModuleStatus {
INIT,
LOADING,
READY
}
class AudioModule(
val jsFile: String
) {
var status = ModuleStatus.INIT
var module: dynamic = null
fun load(action: () -> Unit = {}) {
if (module == null && status == ModuleStatus.INIT) {
status = ModuleStatus.LOADING
module = audioContext.audioWorklet.addModule(
jsFile
)
module.then {
status = ModuleStatus.READY
action()
}
} else if (status == ModuleStatus.READY) {
action()
} else {
console.log("Module not yet loaded")
}
}
}
abstract class AudioNode(
val jsFile: String,
val processorName: String,
val numberOfInputs: Int = 0,
val outputChannelCount: Array<Int> = arrayOf(2),
val destination: dynamic = null,
val outputIndex: Int = 0,
val inputIndex: Int = 0
) {
val module = AudioModule(jsFile)
var created = false
var node: dynamic = null
var port: MessagePort? = null
abstract fun onMessage(message: MessageEvent)
open fun postMessage(msg: Any) {
if (port == null) {
console.log("postMessage port is NULL!")
}
port?.postMessage(msg)
}
// call from user gesture
fun create(done: (node: dynamic) -> Unit) {
module.load {
node = AudioWorkletNode(
audioContext,
processorName,
AudioWorkletNodeParameters(
numberOfInputs,
outputChannelCount
)
)
if (destination == null) {
node.connect(audioContext.destination)
} else {
node.connect(destination, outputIndex, inputIndex)
}
node.port.onmessage = ::onMessage
port = node.port as? MessagePort
created = true
done(node)
}
}
}