149 lines
3.6 KiB
Kotlin
149 lines
3.6 KiB
Kotlin
@file:OptIn(ExperimentalJsExport::class)
|
|
|
|
import org.khronos.webgl.Float64Array
|
|
import org.khronos.webgl.get
|
|
import org.khronos.webgl.set
|
|
import org.w3c.dom.MessageEvent
|
|
import org.w3c.dom.MessagePort
|
|
import kotlin.math.PI
|
|
import kotlin.math.sin
|
|
|
|
@ExperimentalJsExport
|
|
@JsExport
|
|
object WorkletProcessor {
|
|
var port: MessagePort? = null
|
|
|
|
var offsets = Array(5) { 0.0 }
|
|
var counter: Int = 0
|
|
var baseNote = Note.C2
|
|
val CARRAY = arrayOf(
|
|
Note.C1,
|
|
Note.C2,
|
|
Note.C3,
|
|
Note.C4,
|
|
Note.C5,
|
|
Note.C6,
|
|
Note.C7,
|
|
Note.C8,
|
|
)
|
|
|
|
@JsName("setPort")
|
|
fun setPort(port: MessagePort) {
|
|
WorkletProcessor.port = port
|
|
WorkletProcessor.port?.onmessage = WorkletProcessor::onMessage
|
|
}
|
|
|
|
@JsName("onMessage")
|
|
fun onMessage(message: MessageEvent) {
|
|
console.log("WorkletProcessor: Received message", message)
|
|
|
|
when (message.data) {
|
|
"start" -> {
|
|
println("Start worklet!")
|
|
}
|
|
|
|
"stop" -> {
|
|
|
|
}
|
|
|
|
else ->
|
|
console.error("Don't kow how to handle message", message)
|
|
}
|
|
}
|
|
|
|
@JsName("process")
|
|
fun process(samples: Int, left: Float64Array, right: Float64Array) {
|
|
var first = true
|
|
for (index in offsets.indices) {
|
|
var offset = offsets[index]
|
|
var tmpCounter = counter
|
|
var offsetNote = baseNote.transpose(index * 12)
|
|
var delta = offsetNote.sampleDelta
|
|
|
|
for (sample in 0 until samples) {
|
|
var value = sin(offset * 2 * PI)
|
|
offset += delta
|
|
|
|
val noteProgress = tmpCounter % 5000
|
|
if (noteProgress == 0) {
|
|
offsetNote = offsetNote.transpose(1)
|
|
if (offsetNote in CARRAY) {
|
|
offsetNote = offsetNote.transpose(-12)
|
|
}
|
|
delta = offsetNote.sampleDelta
|
|
}
|
|
value *= (1.0 - noteProgress / 5000.0)
|
|
|
|
if (first) {
|
|
left[sample] = value
|
|
right[sample] = value
|
|
} else {
|
|
left[sample] = left[sample] + value
|
|
right[sample] = right[sample] + value
|
|
}
|
|
tmpCounter++
|
|
}
|
|
|
|
offsets[index] = offset
|
|
first = false
|
|
}
|
|
|
|
var tmpCounter = counter
|
|
for (sample in 0 until samples) {
|
|
if (tmpCounter % 5000 == 0) {
|
|
baseNote = baseNote.transpose(1)
|
|
if (baseNote in CARRAY) {
|
|
baseNote = baseNote.transpose(-12)
|
|
}
|
|
}
|
|
tmpCounter++
|
|
}
|
|
counter += samples
|
|
|
|
val nrOffsets = offsets.size
|
|
for (sample in 0 until samples) {
|
|
left[sample] = left[sample] / nrOffsets
|
|
right[sample] = right[sample] / nrOffsets
|
|
}
|
|
|
|
/* for (sample in 0 until samples) {
|
|
val noteProgress = counter % 5000
|
|
if (noteProgress == 0) {
|
|
baseNote = baseNote.transpose(1)
|
|
if (baseNote == Note.C3s) {
|
|
baseNote = Note.C2
|
|
}
|
|
}
|
|
var value = 0.0
|
|
var volumeAdjust = (Note.C3.ordinal - baseNote.ordinal) / 12.0
|
|
for (index in 0 until offsets.size) {
|
|
offsets[index] = (offsets[index] + (baseNote.transpose(index * 12).sampleDelta)) % 1.0
|
|
|
|
var partValue = sin(offsets[index] * 2 * PI)
|
|
if (index == 0) {
|
|
partValue *= volumeAdjust
|
|
} else if (index == offsets.size - 1) {
|
|
partValue *= (1.0 - volumeAdjust)
|
|
}
|
|
|
|
value += partValue
|
|
|
|
}
|
|
|
|
value /= offsets.size
|
|
// simple amplitude
|
|
value *= if (noteProgress < 0.1) {
|
|
(noteProgress / 500.0)
|
|
} else {
|
|
(1.0 - (noteProgress - 0.1) / 4500.0)
|
|
}
|
|
|
|
left[sample] = value
|
|
right[sample] = value
|
|
|
|
counter++
|
|
}*/
|
|
}
|
|
|
|
}
|