AudioWorkletProcessor: process() 方法

process() 方法是 AudioWorkletProcessor 派生类中用于实现音频处理器工作单元的音频处理算法的方法。

虽然此方法并非 AudioWorkletProcessor 接口的一部分,但任何 AudioWorkletProcessor 的实现都必须提供一个 process() 方法。

该方法由音频渲染线程同步调用,每次处理定向通过处理器相应 AudioWorkletNode 的一个音频块(也称为渲染量)。换句话说,每当有一个新的音频块准备好供您的处理器进行操作时,您的 process() 函数就会被调用。

注意: 目前,音频数据块始终是 128 帧长 — 即,它们包含每个输入通道的 128 个 32 位浮点样本。但是,已有计划修订规范,允许根据具体情况更改音频块的大小(例如,如果音频硬件或 CPU 利用率在使用更大块大小时更有效)。因此,您必须始终检查样本数组的大小,而不是假设特定的固定大小。

此大小甚至可能随时间而改变,因此您不能仅查看第一个块并假设样本缓冲区的大小始终相同。

语法

js
process(inputs, outputs, parameters)

参数

inputs

连接到节点的输入数组,其中每一项又是一个通道数组。每个通道都是一个包含 128 个样本的 Float32Array。例如,inputs[n][m][i] 将访问第 n 个输入、该输入的第 m 个通道以及该通道的第 i 个样本。

每个样本值都在 [-1 .. 1] 范围内。

输入的数量(因此该数组的长度)在节点构造时是固定的(请参阅 AudioWorkletNode)。如果没有任何活动的节点连接到节点的第 n 个输入,则 inputs[n] 将是一个空数组(可用输入通道数为零)。

每个输入中的通道数量可能因 channelCountchannelCountMode 属性而异。

outputs

一个输出数组,其结构与 inputs 参数类似。它旨在在 process() 方法执行期间进行填充。默认情况下,每个输出通道都填充为零 — 除非修改了输出数组,否则处理器将输出静音。

parameters

包含字符串键和 Float32Array 值的对象。对于使用 parameterDescriptors getter 定义的每个自定义 AudioParam,对象中的键是该 AudioParamname,值是 Float32Array。数组的值是通过考虑计划的自动化事件计算得出的。

如果参数的自动化速率为 "a-rate",则数组将包含 128 个值 — 每个值对应当前音频块中的一帧。如果在当前块表示的时间段内没有发生自动化,则数组可能包含一个在整个块中恒定的单个值,而不是 128 个相同的 128 个值。

如果自动化速率为 "k-rate",则数组将包含一个值,该值将用于 128 帧中的每一帧。

返回值

一个布尔值,指示是否强制 AudioWorkletNode 保持活动状态,即使用户代理的内部逻辑否则会决定关闭该节点是安全的。

返回值允许您的处理器影响 AudioWorkletProcessor 及其所属节点的生命周期策略。如果返回值与节点的状态组合导致浏览器决定停止该节点,则 process() 将不再被调用。

返回 true 会强制 Web Audio API 保持节点活动状态,而返回 false 则允许浏览器在节点既不生成新音频数据也不接收通过其输入处理的数据时终止该节点。

最常见的 3 种音频节点类型是:

  1. 输出源。实现此类节点的 AudioWorkletProcessor 应在生成输出时从 process 方法返回 true。一旦已知它不再生成输出,该方法就应返回 false。例如,以 AudioBufferSourceNode 为例 — 此类节点的后台处理器在缓冲区播放时应从 process 方法返回 true,并在缓冲区播放结束时(无法再次调用同一个 AudioBufferSourceNodeplay 方法)开始返回 false
  2. 转换输入的节点。实现此类节点的处理器应从 process 方法返回 false,以允许活动输入节点和对该节点的引用决定它是否可以被垃圾回收。具有此行为的节点示例是 GainNode。一旦没有连接输入并且没有保留引用,增益就无法再应用于任何内容,因此可以安全地进行垃圾回收。
  3. 转换输入但具有所谓的尾部时间(tail-time)的节点 — 这意味着即使在输入断开连接或不活动(生成零通道)之后,它仍会产生一段时间的输出。实现此类节点的处理器应在尾部时间期间从 process 方法返回 true,该时间从输入为空(零通道)开始。此类节点的示例是 DelayNode — 它的尾部时间等于其 delayTime 属性。

注意: 缺少 return 语句意味着该方法返回 undefined,由于这是一个假值,所以相当于返回 false。省略显式的 return 语句可能会导致难以发现的节点问题。

异常

由于 process() 方法由用户实现,因此它可能抛出任何异常。如果抛出未捕获的错误,节点将发出 processorerror 事件,并在其剩余生命周期内输出静音。

示例

在此示例中,我们创建了一个 AudioWorkletProcessor,它向其第一个输出产生白噪声。增益可以通过 customGain 参数进行控制。

js
class WhiteNoiseProcessor extends AudioWorkletProcessor {
  process(inputs, outputs, parameters) {
    // take the first output
    const output = outputs[0];
    // fill each channel with random values multiplied by gain
    output.forEach((channel) => {
      for (let i = 0; i < channel.length; i++) {
        // generate random value for each sample
        // Math.random range is [0; 1); we need [-1; 1]
        // this won't include exact 1 but is fine for now for simplicity
        channel[i] =
          (Math.random() * 2 - 1) *
          // the array can contain 1 or 128 values
          // depending on if the automation is present
          // and if the automation rate is k-rate or a-rate
          (parameters["customGain"].length > 1
            ? parameters["customGain"][i]
            : parameters["customGain"][0]);
      }
    });
    // as this is a source node which generates its own output,
    // we return true so it won't accidentally get garbage-collected
    // if we don't have any references to it in the main thread
    return true;
  }
  // define the customGain parameter used in process method
  static get parameterDescriptors() {
    return [
      {
        name: "customGain",
        defaultValue: 1,
        minValue: 0,
        maxValue: 1,
        automationRate: "a-rate",
      },
    ];
  }
}

规范

规范
Web Audio API
# process

浏览器兼容性

这不是浏览器提供的函数,而是必须在客户端代码中编写的回调函数。

另见