I'm trying to change a value that is used by an AudioWorkletProcessor from another module, but from the context of the AudioWorkletProcessor, the value doesn't change and just stays the same. But from the module that modifies the data, when queried upon the data has in fact changed there. It's like there is a completely separate instance/state of the module that holds the data (functions.js) for the modifier (main.js) and the reader (audio-processor.js)
Here we have audio-processor.js
import { sawWave } from "/src/functions.js";
var tick = 0
class AudioProcessor extends AudioWorkletProcessor {
process(inputs, outputs, parameters) {
const output = outputs[0]
output.forEach(channel => {
// emphasis on sawWave function
var value = sawWave(tick) * 0.1;
for (let i = 0; i < channel.length; i++) {
channel[i] = value
}
});
tick++
return true
}
}
registerProcessor('audio-processor', AudioProcessor)
Here we have functions.js
, which is contains sawWave() which is imported into audio-processor.js
let variables = {
// emphasis on this variable
sawWaveFrequency: 1
}
export function setSawFrequency(freq) {
variables.sawWaveFrequency = freq
}
export function sawWave(tick) {
console.log(variables.sawWaveFrequency)
// this function uses the variable defined above and is imported by audio-processor.js
// variables.sawWaveFrequency doesn't change for audio-processor.js when modified from main.js
// so the output will will always be as if variables.sawWaveFrequency = 1
return tick * variables.sawWaveFrequency % 10;
}
Here we have main.js
, which handles input from a HTML page
import { setSawFrequency } from "/src/functions.js";
var audioContext
var whiteNoiseNode
async function init() {
audioContext = new AudioContext()
await audioContext.audioWorklet.addModule("/src/audio-processor.js")
whiteNoiseNode = new AudioWorkletNode(audioContext, 'audio-processor')
}
function play() {
whiteNoiseNode.connect(audioContext.destination)
}
function main() {
document.querySelector("#play").onclick = play;
document.querySelector("#init").onclick = init;
document.querySelector("#slider-mult").oninput = function() {
// this is supposed to change the value, but only does so in the context of main.js and not audio-processor.js
setSawFrequency(this.value);
}
}
main();
EDIT: I take it you're only supposed to use AudioWorkletProcessor.port
and the parameters
parameter in the process function to communicate with it?
You're already on the right track. To change a value inside your AudioWorkletProcessor
you can either use a custom AudioParam
or send a message over the MessagePort
.
The reason why your code doesn't work is that you technically end up with two instances of the same module. The AudioWorkletProcessor runs on a different thread and has no access to the modules that are loaded on the main thread. Therefore /src/functions.js
gets loaded twice. One instance is living on the main thread and the other one is living on the audio thread. Each of them doesn't know that the other exists.