首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将模块导入到在其他地方更改的AudioWorkletProcessor中?

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

Stack Overflow用户
提问于 2020-04-06 23:41:23
回答 2查看 2K关注 0票数 3

我试图从另一个模块更改AudioWorkletProcessor使用的值,但是从AudioWorkletProcessor的上下文中,值不会改变,只是保持不变。但是从修改数据的模块中,当查询数据时,数据实际上已经改变了。就像模块有一个完全独立的实例/状态,它保存修饰符(main.js)和读取器(音频-processor.js)的数据(main.js)。

这里有audio-processor.js

代码语言:javascript
复制
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,它包含导入到audio-processor.js中的sawWave()

代码语言:javascript
复制
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页面的输入

代码语言:javascript
复制
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();

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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-04-07 00:17:30

你已经走上正轨了。若要更改AudioWorkletProcessor中的值,可以使用自定义AudioParam或通过MessagePort发送消息。

您的代码不能工作的原因是,从技术上讲,您最终得到了同一个模块的两个实例。AudioWorkletProcessor运行在不同的线程上,无法访问主线程上加载的模块。因此,/src/functions.js被加载了两次。一个实例位于主线程上,另一个实例位于音频线程上。他们每个人都不知道对方的存在。

票数 2
EN

Stack Overflow用户

发布于 2020-05-05 21:34:59

您还可以使用SharedArrayBuffer

在一个模块中创建共享内存对象。

代码语言:javascript
复制
  const length = 100;
  const size = Int32Array.BYTES_PER_ELEMENT * length;
  this.sab = new SharedArrayBuffer(size);
  this.sharedArray = new Int32Array(this.sab);

把它发送到AudioWorkletProcessor

代码语言:javascript
复制
  this.worker.port.postMessage({
      sab: this.sab
  });

AudioWorkletProcessor

代码语言:javascript
复制
this.port.onmessage = event => {
      this.sharedArray = new Int32Array(event.data.sab);
}

现在,两个模块共享相同的数组(this.sharedArray)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61070615

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档