首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >关于AudioWorkletProcessor.process运行多长时间的思考

关于AudioWorkletProcessor.process运行多长时间的思考
EN

Stack Overflow用户
提问于 2021-10-19 01:05:46
回答 1查看 236关注 0票数 1

因为根据https://developer.mozilla.org/en-US/docs/Web/API/AudioWorkletProcessor/process,对AudioWorkletProcessor.process的调用是同步的,所以当执行时间太长时会发生什么,例如,超过1秒?是否会在下一次呼叫中跳过某些音频样本?或者样本会在某处排队吗?我找不到关于这方面的文档。

EN

回答 1

Stack Overflow用户

发布于 2021-10-27 00:06:19

实时AudioContext通常对特定的物理音频输出设备是严格的。因此,AudioContextcurrentTime由该音频输出设备的硬件时钟驱动。

如果AudioContext不知何故未能及时交付样本,结果将是静默。通常情况下,如果在不应该出现的地方突然出现了一点静默,就会听到滴答声。渲染时间太长的样本将用于下一个渲染量,如果它们恰好在那时准备就绪。

不过,在一些样本无法及时交付的情况下,浏览器如何推进currentTime是有区别的。Firefox似乎不会统计任何丢失的样本,而Chrome会按进度计算音频硬件输出的所有样本,包括那些无法及时渲染的样本。

为了测试这一点,我创建了一个可以在主线程中暂停或阻塞的AudioWorkletProcessor

代码语言:javascript
复制
class BlockableProcessor extends AudioWorkletProcessor {
    constructor () {
        super();

        this.int32Array = null;
        this.port.onmessage = ({ data }) => this.int32Array = data;
    }

    process() {
        if (this.int32Array !== null) {
            while (Atomics.load(this.int32Array, 0) === 0) {
                Atomics.store(this.int32Array, 1, currentTime);
            }

            Atomics.store(this.int32Array, 1, currentTime);
        }

        return true;
    }
}

registerProcessor('blockable-processor', BlockableProcessor);

BlockableProcessor期望收到一个SharedArrayBuffer,它使用该the检查是否应该阻止process()函数。它还使用它将currentTime传回主线程。

它可以像这样使用:

代码语言:javascript
复制
const audioWorkletNode = new AudioWorkletNode(
    audioContext,
    'blockable-processor'
);
const sharedArrayBuffer = new SharedArrayBuffer(8);
const int32Array = new Int32Array(sharedArrayBuffer);

Atomics.store(int32Array, 0, 1);
Atomics.store(int32Array, 1, 0);

audioWorkletNode.port.postMessage(int32Array);
audioWorkletNode.connect(audioContext.destination);

可以通过将SharedArrayBuffer的第一个值设置为0来阻止它。

代码语言:javascript
复制
Atomics.store(int32Array, 0, 0);

同样,可以通过再次将其设置为1来再次解除阻塞。

代码语言:javascript
复制
Atomics.store(int32Array, 0, 1);

也可以从主线程上的AudioWorkletProcessor中读取编写的currentTime

代码语言:javascript
复制
Atomics.load(int32Array, 1);

使用这个设置,我能够看到Chrome (v95)和Firefox (v93)在主线程和工作面板上都停止了时间进度,以防处理器被阻塞。

当它被解锁时,火狐继续它停止的地方,Chrome继续它应该在的地方,如果一切都按预期进行的话。

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

https://stackoverflow.com/questions/69624052

复制
相关文章

相似问题

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