86 lines
2.1 KiB
JavaScript
86 lines
2.1 KiB
JavaScript
class BytebeatProcessor extends AudioWorkletProcessor {
|
|
constructor() {
|
|
super()
|
|
|
|
this.t = 0
|
|
this.a = 8
|
|
this.b = 16
|
|
this.c = 32
|
|
this.d = 64
|
|
this.formula = null
|
|
this.compiledFormula = null
|
|
this.sampleRate = 8000
|
|
this.duration = 4
|
|
this.loopLength = this.sampleRate * this.duration
|
|
this.error = false
|
|
|
|
this.port.onmessage = (event) => {
|
|
const { type, value } = event.data
|
|
switch (type) {
|
|
case 'formula':
|
|
this.setFormula(value)
|
|
break
|
|
case 'variables':
|
|
this.a = value.a ?? this.a
|
|
this.b = value.b ?? this.b
|
|
this.c = value.c ?? this.c
|
|
this.d = value.d ?? this.d
|
|
break
|
|
case 'reset':
|
|
this.t = 0
|
|
break
|
|
case 'loopLength':
|
|
this.loopLength = value
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
setFormula(formulaString) {
|
|
try {
|
|
this.compiledFormula = new Function('t', 'a', 'b', 'c', 'd', `return ${formulaString}`)
|
|
this.formula = formulaString
|
|
this.error = false
|
|
} catch (e) {
|
|
console.error('Failed to compile bytebeat formula:', e)
|
|
this.error = true
|
|
this.compiledFormula = null
|
|
}
|
|
}
|
|
|
|
process(inputs, outputs) {
|
|
const output = outputs[0]
|
|
|
|
if (output.length > 0) {
|
|
const outputChannel = output[0]
|
|
|
|
for (let i = 0; i < outputChannel.length; i++) {
|
|
if (!this.compiledFormula || this.error) {
|
|
outputChannel[i] = 0
|
|
} else {
|
|
try {
|
|
const value = this.compiledFormula(this.t, this.a, this.b, this.c, this.d)
|
|
const byteValue = value & 0xFF
|
|
outputChannel[i] = (byteValue - 128) / 128
|
|
} catch (e) {
|
|
outputChannel[i] = 0
|
|
if (!this.error) {
|
|
console.error('Bytebeat runtime error:', e)
|
|
this.error = true
|
|
}
|
|
}
|
|
}
|
|
|
|
this.t++
|
|
if (this.loopLength > 0 && this.t >= this.loopLength) {
|
|
this.t = 0
|
|
}
|
|
}
|
|
}
|
|
|
|
return true
|
|
}
|
|
}
|
|
|
|
registerProcessor('bytebeat-processor', BytebeatProcessor)
|