猿问

如何将模块导入在其他地方更改的 AudioWorkletProcessor?

我正在尝试从另一个模块更改 AudioWorkletProcessor 使用的值,但从 AudioWorkletProcessor 的上下文来看,该值不会改变并且保持不变。但是从修改数据的模块来看,当查询到数据时,实际上已经发生了变化。就像有一个完全独立的模块实例/状态,它为修饰符(main.js)和读取器(audio-processor.js)保存数据(functions.js)


在这里我们有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)

这里我们有functions.js,它包含被导入到的 sawWave()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;

}

这里我们有main.js,它处理来自 HTML 页面的输入


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)

}


编辑:我认为你只应该使用AudioWorkletProcessor.port和parameters过程函数中的参数来与之通信?


呼啦一阵风
浏览 320回答 2
2回答

暮色呼如

你已经在正确的轨道上。要更改您内部的值,您AudioWorkletProcessor可以使用自定义AudioParam或通过MessagePort.您的代码不起作用的原因是从技术上讲,您最终会得到同一个模块的两个实例。AudioWorkletProcessor 在不同的线程上运行,并且无法访问在主线程上加载的模块。因此/src/functions.js被加载两次。一个实例存在于主线程上,另一个实例存在于音频线程上。他们每个人都不知道另一个人的存在。

噜噜哒

您还可以使用一个 SharedArrayBuffer在一个模块中创建共享内存对象。&nbsp; const length = 100;&nbsp; const size = Int32Array.BYTES_PER_ELEMENT * length;&nbsp; this.sab = new SharedArrayBuffer(size);&nbsp; this.sharedArray = new Int32Array(this.sab);发送至AudioWorkletProcessor&nbsp; this.worker.port.postMessage({&nbsp; &nbsp; &nbsp; sab: this.sab&nbsp; });在里面AudioWorkletProcessorthis.port.onmessage = event => {&nbsp; &nbsp; &nbsp; this.sharedArray = new Int32Array(event.data.sab);}现在两个模块共享同一个数组 ( this.sharedArray)。
随时随地看视频慕课网APP

相关分类

JavaScript
我要回答