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 = 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) } } }