Simple interaction with audioworkler
This commit is contained in:
@@ -4,7 +4,7 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinJsCompilerType.IR
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||
|
||||
plugins {
|
||||
kotlin("multiplatform") version "1.7.20"
|
||||
kotlin("multiplatform") version "1.8.10"
|
||||
application
|
||||
}
|
||||
|
||||
@@ -62,11 +62,11 @@ kotlin {
|
||||
}
|
||||
|
||||
application {
|
||||
mainClass.set("nl.astraeus.application.ServerKt")
|
||||
mainClass.set("ServerKt")
|
||||
}
|
||||
|
||||
tasks.named<Copy>("jvmProcessResources") {
|
||||
val jsBrowserDistribution = tasks.named("jsBrowserDistribution")
|
||||
val jsBrowserDistribution = tasks.named("jsBrowserDevelopmentWebpack")
|
||||
from(jsBrowserDistribution)
|
||||
from(tasks.named("jsAudioWorkletBrowserDistribution"))
|
||||
}
|
||||
@@ -74,4 +74,4 @@ tasks.named<Copy>("jvmProcessResources") {
|
||||
tasks.named<JavaExec>("run") {
|
||||
dependsOn(tasks.named<Jar>("jvmJar"))
|
||||
classpath(tasks.named<Jar>("jvmJar"))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,9 @@ import org.w3c.dom.MessagePort
|
||||
import kotlin.math.PI
|
||||
import kotlin.math.sin
|
||||
|
||||
const val PI2 = PI * 2
|
||||
const val NOTE_LENGTH = 2500
|
||||
|
||||
@ExperimentalJsExport
|
||||
@JsExport
|
||||
object WorkletProcessor {
|
||||
@@ -16,6 +19,8 @@ object WorkletProcessor {
|
||||
var note = Note.C2
|
||||
var offset = 0.0
|
||||
|
||||
var note_length = 2500
|
||||
|
||||
@JsName("setPort")
|
||||
fun setPort(port: MessagePort) {
|
||||
WorkletProcessor.port = port
|
||||
@@ -26,17 +31,25 @@ object WorkletProcessor {
|
||||
fun onMessage(message: MessageEvent) {
|
||||
console.log("WorkletProcessor: Received message", message)
|
||||
|
||||
when (message.data) {
|
||||
"start" -> {
|
||||
println("Start worklet!")
|
||||
val data = message.data
|
||||
if (data is String) {
|
||||
val parts = data.split("\n")
|
||||
when (parts[0]) {
|
||||
"start" -> {
|
||||
println("Start worklet!")
|
||||
}
|
||||
|
||||
"stop" -> {
|
||||
|
||||
}
|
||||
|
||||
"set_note_length" -> {
|
||||
note_length = parts[1].toInt()
|
||||
}
|
||||
|
||||
else ->
|
||||
console.error("Don't kow how to handle message", message)
|
||||
}
|
||||
|
||||
"stop" -> {
|
||||
|
||||
}
|
||||
|
||||
else ->
|
||||
console.error("Don't kow how to handle message", message)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,10 +59,14 @@ object WorkletProcessor {
|
||||
var delta = note.sampleDelta
|
||||
|
||||
for (sample in 0 until samples) {
|
||||
var value = sin(offset * 2 * PI)
|
||||
var value = sin(offset * PI2) +
|
||||
sin(offset * 2 * PI2) * 0.5 +
|
||||
sin(offset * 3 * PI2) * 0.25 +
|
||||
sin(offset * 4 * PI2) * 0.15
|
||||
offset += delta
|
||||
|
||||
val noteProgress = tmpCounter % 5000
|
||||
// new note every NOTE_LENGTH samples
|
||||
val noteProgress = tmpCounter % note_length
|
||||
if (noteProgress == 0) {
|
||||
note = note.transpose(1)
|
||||
if (note == Note.C7) {
|
||||
@@ -57,7 +74,8 @@ object WorkletProcessor {
|
||||
}
|
||||
delta = note.sampleDelta
|
||||
}
|
||||
value *= (1.0 - noteProgress / 5000.0)
|
||||
// simple envelop from max to 0 every note
|
||||
value *= (1.0 - noteProgress / note_length.toDouble())
|
||||
|
||||
left[sample] = value
|
||||
right[sample] = value
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
import kotlinx.browser.document
|
||||
import handler.AudioWorkletHandler
|
||||
|
||||
fun main() {
|
||||
AudioWorkletHandler.loadCode()
|
||||
|
||||
println("Ok")
|
||||
|
||||
document.getElementById("clicker")?.also {
|
||||
it.addEventListener("click", {
|
||||
AudioWorkletHandler.createContext {
|
||||
println("Created context")
|
||||
|
||||
AudioWorkletHandler.start()
|
||||
}
|
||||
}, "")
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package nl.astraeus
|
||||
|
||||
import kotlinx.browser.document
|
||||
import nl.astraeus.handler.AudioWorkletHandler
|
||||
import org.w3c.dom.HTMLInputElement
|
||||
|
||||
fun main() {
|
||||
AudioWorkletHandler.loadCode()
|
||||
@@ -18,4 +19,17 @@ fun main() {
|
||||
}, "")
|
||||
}
|
||||
|
||||
print("get noteLength")
|
||||
document.getElementById("noteLength")?.also {
|
||||
println("Set noteLength event")
|
||||
it.addEventListener("change", {
|
||||
println("Set noteLength 1")
|
||||
val target = it.target
|
||||
if (target is HTMLInputElement) {
|
||||
println("Set noteLength 2")
|
||||
AudioWorkletHandler.setNoteLength(target.value.toInt())
|
||||
}
|
||||
}, "")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -159,4 +159,7 @@ object AudioWorkletHandler : AudioWorklet(
|
||||
audioWorkletMessagePort?.postMessage("start")
|
||||
}
|
||||
|
||||
fun setNoteLength(length: Int) {
|
||||
audioWorkletMessagePort?.postMessage("set_note_length\n$length")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,14 @@
|
||||
.button_div {
|
||||
margin: 1em;
|
||||
}
|
||||
|
||||
.button {
|
||||
padding: 3px 5px;
|
||||
background-color: red;
|
||||
}
|
||||
background-color: #2c008f;
|
||||
color: white;
|
||||
font-size: large;
|
||||
}
|
||||
|
||||
input {
|
||||
margin: 1em;
|
||||
}
|
||||
|
||||
@@ -14,15 +14,31 @@ fun HTML.index() {
|
||||
}
|
||||
body {
|
||||
div {
|
||||
+"Hello from Ktor"
|
||||
+"We need a button to start because we can only start audio from a user event"
|
||||
}
|
||||
div("button_div") {
|
||||
span("button") {
|
||||
id = "clicker"
|
||||
|
||||
+"Start"
|
||||
}
|
||||
}
|
||||
div {
|
||||
id = "root"
|
||||
+ "An example of how to interact with the audioworklet:"
|
||||
}
|
||||
span("button") {
|
||||
id = "clicker"
|
||||
|
||||
+ "Start"
|
||||
div {
|
||||
label {
|
||||
htmlFor = "noteLength"
|
||||
+"Note length (in samples):"
|
||||
}
|
||||
input {
|
||||
id = "noteLength"
|
||||
type = InputType.number
|
||||
value = "2500"
|
||||
min = "1"
|
||||
max = "100000"
|
||||
step = "100"
|
||||
}
|
||||
}
|
||||
script(src = "/static/kotlin-audioworklet.js") {}
|
||||
}
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
package nl.astraeus.application
|
||||
|
||||
import io.ktor.http.HttpStatusCode
|
||||
import io.ktor.server.application.*
|
||||
import io.ktor.server.engine.embeddedServer
|
||||
import io.ktor.server.html.*
|
||||
import io.ktor.server.http.content.*
|
||||
import io.ktor.server.netty.Netty
|
||||
import io.ktor.server.routing.*
|
||||
import kotlinx.html.*
|
||||
|
||||
fun HTML.index() {
|
||||
head {
|
||||
title("Hello from Ktor!")
|
||||
link("static/worklet.css", "stylesheet" ,"text/css")
|
||||
}
|
||||
body {
|
||||
div {
|
||||
+"Hello from Ktor"
|
||||
}
|
||||
div {
|
||||
id = "root"
|
||||
}
|
||||
span("button") {
|
||||
id = "clicker"
|
||||
|
||||
+ "Start"
|
||||
}
|
||||
script(src = "/static/kotlin-audioworklet.js") {}
|
||||
}
|
||||
}
|
||||
|
||||
fun main() {
|
||||
embeddedServer(Netty, port = 8080, host = "127.0.0.1") {
|
||||
routing {
|
||||
get("/") {
|
||||
call.respondHtml(HttpStatusCode.OK, HTML::index)
|
||||
}
|
||||
static("/static") {
|
||||
resources()
|
||||
}
|
||||
}
|
||||
}.start(wait = true)
|
||||
}
|
||||
Reference in New Issue
Block a user