Web 音频 API

W3C 推荐标准,

此版本:
https://www.w3.org/TR/2021/REC-webaudio-20210617/
最新发布版本:
https://www.w3.org/TR/webaudio/
编辑草案:
https://webaudio.github.io/web-audio-api/
以前的版本:
https://www.w3.org/TR/2021/PR-webaudio-20210506/
反馈:
public-audio@w3.org 主题行中带有 “[webaudio] … 消息主题 …” (存档)
实施报告:
https://webaudio.github.io/web-audio-api/implementation-report.html
测试套件:
https://github.com/web-platform-tests/wpt/tree/master/webaudio
问题跟踪:
GitHub
编辑:
(Mozilla (https://www.mozilla.org/))
(Google (https://www.google.com/))
前编辑:
Raymond Toy (至 2018 年 10 月)
Chris Wilson (至 2016 年 1 月)
Chris Rogers (至 2013 年 8 月)

请查看 勘误表 了解自发布以来报告的任何错误或问题。


摘要

本规范描述了一个用于在Web应用程序中处理和合成音频的高级Web API。 主要的范式是一个音频路由图, 其中多个 AudioNode 对象被连接在一起以定义整体音频渲染。 实际的处理将主要在底层实现中进行 (通常是优化的Assembly / C / C++代码), 但也支持直接脚本处理和合成

简介部分介绍了本规范背后的动机。

该API设计用于与Web平台上的其他API和元素一起使用,尤其是: XMLHttpRequest [XHR](使用responseTyperesponse属性)。 对于游戏和交互式应用程序, 预计将与canvas 2D [2dcontext]和WebGL [WEBGL] 3D图形API一起使用。

本文档的状态

本节描述了本文档在发布时的状态。 其他文件可能会取代本文档。 当前W3C出版物的列表和本技术报告的最新修订版 可以在W3C技术报告索引https://www.w3.org/TR/.中找到。

W3C推荐标准是经过广泛共识建立后,由W3C及其成员认可的规范。W3C建议广泛部署此规范作为Web标准。

本文档由Web音频工作组作为推荐标准生产。

未来对本推荐标准的更新可能会纳入新功能

如果您希望对本文档提出意见,请在规范库上提交问题或发送至public-audio@w3.org (订阅, 存档)。

有关实施报告 已经发布。

本文档由在 W3C专利政策 下运行的一个小组生成。 W3C维护着一个公开的专利披露列表 该页面还包括披露专利的说明。 个人如果实际了解认为包含必要权利要求的专利,必须根据W3C专利政策第6节披露信息。

本文档受2020年9月15日W3C流程文件管辖。

有关自上一个草案以来的变更, 请参见变更部分。

简介

到目前为止,网页上的音频技术一直比较原始,直到最近还需要通过像 Flash 和 QuickTime 这样的插件来提供音频服务。HTML5中引入的audio元素非常重要,它允许基本的流媒体音频播放。但它的功能不足以处理更复杂的音频应用程序。对于复杂的基于网页的游戏或交互式应用程序,需要另一种解决方案。本规范的目标之一是包括现代游戏音频引擎中的功能,以及现代桌面音频制作应用程序中的一些混音、处理和滤波任务。

这些API设计时考虑了[webaudio-usecases]中广泛的用例。理想情况下,它应该能够支持任何可以合理地用优化的C++引擎通过脚本控制并在浏览器中运行的用例。话虽如此,现代桌面音频软件可以具有非常先进的功能,其中一些功能使用此系统构建可能会很困难甚至不可能。Apple的Logic Audio就是这样一个应用程序,它支持外部MIDI控制器、任意插件音频效果和合成器、高度优化的直接到磁盘的音频文件读/写、紧密集成的时间拉伸等等。尽管如此,所提出的系统将能够支持一大范围的相对复杂的游戏和交互式应用程序,包括音乐类的。而且它可以很好地补充WebGL提供的更高级的图形功能。API的设计使得以后可以添加更高级的功能。

功能

API支持以下主要功能:

模块化路由

模块化路由允许不同AudioNode对象之间进行任意连接。每个节点可以有输入和/或输出源节点没有输入,只有一个输出。目标节点有一个输入,没有输出。其他节点,如滤波器,可以放置在源节点和目标节点之间。当两个对象连接在一起时,开发人员不需要担心低级流格式细节;正确的事情自然会发生。例如,如果将单声道音频流连接到立体声输入,它应该只是适当地混合到左右声道

在最简单的情况下,单个源可以直接路由到输出。所有路由都在包含单个AudioDestinationNodeAudioContext中进行:

modular routing
模块化路由的简单示例。

为了说明这种简单的路由,以下是播放单个声音的简单示例:

const context = new AudioContext();
        
        function playSound() {
          const source = context.createBufferSource();
          source.buffer = dogBarkingBuffer;
          source.connect(context.destination);
          source.start(0);
        }

这是一个更复杂的示例,包含三个源和一个卷积混响发送,以及最终输出阶段的动态压缩器:

modular routing2
模块化路由的更复杂示例。
let context;let compressor;let reverb;let source1, source2, source3;let lowpassFilter;let waveShaper;let panner;let dry1, dry2, dry3;let wet1, wet2, wet3;let mainDry;let mainWet;function setupRoutingGraph () {  context = new AudioContext();  // 创建效果节点。  lowpassFilter = context.createBiquadFilter();  waveShaper = context.createWaveShaper();  panner = context.createPanner();  compressor = context.createDynamicsCompressor();  reverb = context.createConvolver();  // 创建主干燥和湿。  mainDry = context.createGain();  mainWet = context.createGain();  // 将最终压缩器连接到最终目的地。  compressor.connect(context.destination);  // 将主干燥和湿连接到压缩器。  mainDry.connect(compressor);  mainWet.connect(compressor);  // 将混响连接到主湿。  reverb.connect(mainWet);  // 创建几个源。  source1 = context.createBufferSource();  source2 = context.createBufferSource();  source3 = context.createOscillator();  source1.buffer = manTalkingBuffer;  source2.buffer = footstepsBuffer;  source3.frequency.value = 440;  // 连接source1  dry1 = context.createGain();  wet1 = context.createGain();  source1.connect(lowpassFilter);  lowpassFilter.connect(dry1);  lowpassFilter.connect(wet1);  dry1.connect(mainDry);  wet1.connect(reverb);  // 连接source2  dry2 = context.createGain();  wet2 = context.createGain();  source2.connect(waveShaper);  waveShaper.connect(dry2);  waveShaper.connect(wet2);  dry2.connect(mainDry);  wet2.connect(reverb);  // 连接source3  dry3 = context.createGain();  wet3 = context.createGain();  source3.connect(panner);  panner.connect(dry3);  panner.connect(wet3);  dry3.connect(mainDry);  wet3.connect(reverb);  // 现在启动源。  source1.start(0);  source2.start(0);  source3.start(0);}

模块化路由还允许将AudioNode的输出路由到控制另一个AudioNode行为的AudioParam参数。在这种情况下,节点的输出可以作为调制信号而不是输入信号。

modular routing3
模块化路由,说明一个振荡器调制另一个的频率。
function setupRoutingGraph() {  const context = new AudioContext();  // 创建提供调制信号的低频振荡器  const lfo = context.createOscillator();  lfo.frequency.value = 1.0;  // 创建要被调制的高频振荡器  const hfo = context.createOscillator();  hfo.frequency.value = 440.0;  // 创建一个增益节点,其增益决定调制信号的幅度  const modulationGain = context.createGain();  modulationGain.gain.value = 50;  // 配置图并启动振荡器  lfo.connect(modulationGain);  modulationGain.connect(hfo.detune);  hfo.connect(context.destination);  hfo.start(0);  lfo.start(0);}

API概述

定义的接口有:

Web Audio API中还有几个功能已被弃用但尚未删除,正在等待其替代方案的实施经验:

1. 音频API

1.1. BaseAudioContext 接口

BaseAudioContext

Firefox53+Safari不支持Chrome56+
Opera43+Edge79+
Edge(旧版)不支持IE不支持
Android版Firefox53+iOS版Safari不支持Android版Chrome56+Android WebView56+Samsung Internet6.0+Opera Mobile43+

此接口表示一组AudioNode 对象及其连接。它允许将信号任意路由到AudioDestinationNode。 节点由上下文创建,然后连接在一起。

BaseAudioContext 不能直接实例化,而是由具体接口AudioContext (用于实时渲染)和OfflineAudioContext (用于离线渲染)扩展。

每个BaseAudioContext 都创建了一个内部槽位[[pending promises]],这是一个最初为空的承诺的有序列表。

每个BaseAudioContext 都有一个唯一的 媒体元素事件任务源。 此外,BaseAudioContext 还有两个私有槽位[[rendering thread state]][[control thread state]], 它们的值来自AudioContextState, 并且它们最初都设置为"suspended"

enum AudioContextState {
  "suspended",
  "running",
  "closed"
};
枚举描述
"suspended" 此上下文当前已暂停(上下文时间未继续,音频硬件可能已关闭/释放)。
"running" 音频正在处理。
"closed" 此上下文已被释放,无法再用于处理音频。所有系统音频资源已被释放。
callback DecodeErrorCallback = undefined (DOMException error);

callback DecodeSuccessCallback = undefined (AudioBuffer decodedData);

[Exposed=Window]
interface BaseAudioContext : EventTarget {
  readonly attribute AudioDestinationNode destination;
  readonly attribute float sampleRate;
  readonly attribute double currentTime;
  readonly attribute AudioListener listener;
  readonly attribute AudioContextState state;
  [SameObject, SecureContext]
  readonly attribute AudioWorklet audioWorklet;
  attribute EventHandler onstatechange;

  AnalyserNode createAnalyser ();
  BiquadFilterNode createBiquadFilter ();
  AudioBuffer createBuffer (unsigned long numberOfChannels,
                            unsigned long length,
                            float sampleRate);
  AudioBufferSourceNode createBufferSource ();
  ChannelMergerNode createChannelMerger (optional unsigned long numberOfInputs = 6);
  ChannelSplitterNode createChannelSplitter (
    optional unsigned long numberOfOutputs = 6);
  ConstantSourceNode createConstantSource ();
  ConvolverNode createConvolver ();
  DelayNode createDelay (optional double maxDelayTime = 1.0);
  DynamicsCompressorNode createDynamicsCompressor ();
  GainNode createGain ();
  IIRFilterNode createIIRFilter (sequence<double> feedforward,
                                 sequence<double> feedback);
  OscillatorNode createOscillator ();
  PannerNode createPanner ();
  PeriodicWave createPeriodicWave (sequence<float> real,
                                   sequence<float> imag,
                                   optional PeriodicWaveConstraints constraints = {});
  ScriptProcessorNode createScriptProcessor(
    optional unsigned long bufferSize = 0,
    optional unsigned long numberOfInputChannels = 2,
    optional unsigned long numberOfOutputChannels = 2);
  StereoPannerNode createStereoPanner ();
  WaveShaperNode createWaveShaper ();

  Promise<AudioBuffer> decodeAudioData (
    ArrayBuffer audioData,
    optional DecodeSuccessCallback? successCallback,
    optional DecodeErrorCallback? errorCallback);
};

1.1.1. 属性

BaseAudioContext/audioWorklet

Firefox76+Safari不支持Chrome66+
Opera支持Edge79+
Edge(旧版)不支持IE不支持
Android版Firefox79+iOS版Safari不支持Android版Chrome66+Android WebView66+Samsung Internet9.0+Opera Mobile支持

audioWorklet, 类型为 AudioWorklet, 只读

允许访问 Worklet 对象,该对象可以通过 [HTML]AudioWorklet 定义的算法导入包含 AudioWorkletProcessor 类定义的脚本。

BaseAudioContext/currentTime

所有现行引擎均支持。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge(旧版)12+IE不支持
Android版Firefox25+iOS版Safari6+Android版Chrome18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

currentTime, 类型为 double, 只读

这是最近由上下文的渲染图处理的音频块中紧跟最后一个采样帧的采样帧的时间(以秒为单位)。如果 上下文的渲染图尚未处理音频块,则 currentTime 的值为零。

currentTime 的时间坐标系中,零值对应于图形处理的第一个音频块中的第一个采样帧。在此系统中,流逝的时间对应于由 BaseAudioContext 生成的音频流的流逝时间, 可能不会与系统中的其他时钟同步。(对于 OfflineAudioContext, 由于流不会被任何设备主动播放,因此甚至没有接近实际时间的可能性。)

Web Audio API 中的所有预定时间都是相对于 currentTime 的值。

BaseAudioContext 处于 "running" 状态时, 此属性的值是单调递增的,并由渲染线程按固定增量更新,增量对应于一个 渲染量子。因此,对于正在运行的上下文,currentTime 随着系统处理音频块而稳步增加,并且始终表示下一个要处理的音频块的开始时间。它也是当前状态中任何计划更改可能生效的最早时间。

在控制线程上读取 currentTime 时,必须原子地读取。

BaseAudioContext/destination

所有现行引擎均支持。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge(旧版)12+IE不支持
Android版Firefox25+iOS版Safari6+Android版Chrome18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

destination, 类型为 AudioDestinationNode, 只读

带有单个输入的 AudioDestinationNode, 表示所有音频的最终目的地。通常这将代表实际的音频硬件。所有 AudioNode 正在渲染音频的节点将直接或间接连接到 destination

BaseAudioContext/listener

所有现行引擎均支持。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge(旧版)12+IE不支持
Android版Firefox25+iOS版Safari6+Android版Chrome18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

listener, 类型为 AudioListener, 只读

一个用于 3D 空间化AudioListener

BaseAudioContext/onstatechange

所有现行引擎均支持。

Firefox40+Safari9+Chrome43+
Opera支持Edge79+
Edge(旧版)14+IE不支持
Android版Firefox40+iOS版Safari9+Android版Chrome支持Android WebView支持Samsung Internet支持Opera Mobile支持

onstatechange, 类型为 EventHandler

用于为 BaseAudioContext 设置事件处理程序属性, 当 AudioContext 的状态发生变化时(即对应的 promise 将已解析时)会分派一个事件。类型为 Event 的事件将被分派给事件处理程序,事件处理程序可以直接查询 AudioContext 的状态。新创建的 AudioContext 将始终以 suspended 状态开始,并且每当状态更改为不同状态时,将触发状态更改事件。在触发 oncomplete 事件之前,将触发此事件。

BaseAudioContext/sampleRate

所有现行引擎均支持。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge(旧版)12+IE不支持
Android版Firefox25+iOS版Safari6+Android版Chrome18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

sampleRate, 类型为 float, 只读

BaseAudioContext 处理音频的采样率(每秒采样帧数)。假定上下文中的所有 AudioNode 以此速率运行。在此假设下,不支持实时处理中的采样率转换器或“变速”处理器。 奈奎斯特频率 是此采样率值的一半。

BaseAudioContext/state

所有现行引擎均支持。

Firefox40+Safari9+Chrome43+
Opera支持Edge79+
Edge(旧版)14+IE不支持
Android版Firefox40+iOS版Safari9+Android版Chrome支持Android WebView支持Samsung Internet支持Opera Mobile支持

state, 类型为 AudioContextState, 只读

描述 BaseAudioContext 的当前状态。 获取此属性会返回 [[control thread state]] 插槽的内容。

1.1.2. 方法

BaseAudioContext/createAnalyser

在所有当前引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (Legacy)12+IE
Firefox for Android25+iOS Safari6+Chrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

createAnalyser()

工厂方法 用于 AnalyserNode

无参数。
返回类型: AnalyserNode

BaseAudioContext/createBiquadFilter

在所有当前引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (Legacy)12+IE
Firefox for Android25+iOS Safari6+Chrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

createBiquadFilter()

工厂方法 用于 BiquadFilterNode ,代表一个二阶滤波器,它可以配置为几种常见的滤波器类型。

无参数。
返回类型: BiquadFilterNode

BaseAudioContext/createBuffer

在所有当前引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (Legacy)12+IE
Firefox for Android25+iOS Safari6+Chrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

createBuffer(numberOfChannels, length, sampleRate)

创建指定大小的AudioBuffer。缓冲区中的音频数据将被初始化为零(静音)。 如果任何参数为负值、零或超出其标称范围,则必须抛出 NotSupportedError 异常。

BaseAudioContext.createBuffer() 方法的参数。
参数 类型 可为空 可选 描述
numberOfChannels unsigned long 决定缓冲区将有多少通道。实现必须支持至少32个通道。
length unsigned long 决定缓冲区的大小,以采样帧为单位。这个值必须至少为1。
sampleRate float 描述缓冲区中线性PCM音频数据的采样率,以每秒采样帧数为单位。实现必须支持至少8000到96000的采样率范围。
返回类型: AudioBuffer

BaseAudioContext/createBufferSource

在所有当前引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (Legacy)12+IE
Firefox for Android25+iOS Safari6+Chrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

createBufferSource()

工厂方法 用于 AudioBufferSourceNode

无参数。
返回类型: AudioBufferSourceNode

BaseAudioContext/createChannelMerger

在所有当前引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (Legacy)12+IE
Firefox for Android25+iOS Safari6+Chrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

createChannelMerger(numberOfInputs)

工厂方法用于 ChannelMergerNode 表示一个通道合并器。如果numberOfInputs小于1或大于支持的通道数,则必须抛出IndexSizeError异常。

BaseAudioContext.createChannelMerger(numberOfInputs)方法的参数。
参数 类型 可为空 可选 描述
numberOfInputs unsigned long 确定输入数量。必须支持最多32个值。如果未指定,则使用6
返回类型: ChannelMergerNode

BaseAudioContext/createChannelSplitter

在所有当前的引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (Legacy)12+IE
适用于Android的Firefox25+iOS Safari6+适用于Android的Chrome18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

createChannelSplitter(numberOfOutputs)

工厂方法用于 ChannelSplitterNode 表示一个通道分离器。如果numberOfOutputs小于1或大于支持的通道数,则必须抛出IndexSizeError异常。

BaseAudioContext.createChannelSplitter(numberOfOutputs)方法的参数。
参数 类型 可为空 可选 描述
numberOfOutputs unsigned long 输出数量。必须支持最多32个值。如果未指定,则使用6
返回类型: ChannelSplitterNode

BaseAudioContext/createConstantSource

Firefox52+SafariChrome56+
Opera43+Edge79+
Edge (Legacy)IE
适用于Android的Firefox52+iOS Safari适用于Android的Chrome56+Android WebView56+Samsung Internet6.0+Opera Mobile43+

createConstantSource()

工厂方法用于 ConstantSourceNode

无参数。
返回类型: ConstantSourceNode

BaseAudioContext/createConvolver

在所有当前的引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (Legacy)12+IE
适用于Android的Firefox25+iOS Safari6+适用于Android的Chrome18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

createConvolver()

工厂方法用于 ConvolverNode

无参数。
返回类型: ConvolverNode

BaseAudioContext/createDelay

在所有当前的引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (Legacy)12+IE
适用于Android的Firefox25+iOS Safari6+适用于Android的Chrome18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

createDelay(maxDelayTime)

工厂方法用于 DelayNode。 初始默认延迟时间为0秒。

BaseAudioContext.createDelay(maxDelayTime)方法的参数。
参数 类型 可为空 可选 描述
maxDelayTime double 指定延迟线允许的最大延迟时间(以秒为单位)。如果指定,则此值必须大于零且小于三分钟,否则必须抛出NotSupportedError异常。如果未指定,则使用1
返回类型: DelayNode

BaseAudioContext/createDynamicsCompressor

在所有当前的引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (Legacy)12+IE
适用于Android的Firefox25+iOS Safari6+适用于Android的Chrome18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

createDynamicsCompressor()

工厂方法用于 DynamicsCompressorNode

无参数。
返回类型: DynamicsCompressorNode

BaseAudioContext/createGain

在所有当前的引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (Legacy)12+IE
适用于Android的Firefox25+iOS Safari6+适用于Android的Chrome18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

createGain()

工厂方法用于 GainNode

无参数。
返回类型: GainNode

BaseAudioContext/createIIRFilter

Firefox50+SafariChrome49+
OperaEdge79+
Edge (Legacy)14+IE
适用于Android的Firefox50+iOS Safari适用于Android的Chrome49+Android WebView49+Samsung Internet5.0+Opera Mobile

createIIRFilter(feedforward, feedback)

BaseAudioContext.createIIRFilter()方法的参数。
参数 类型 可为空 可选 描述
feedforward sequence<double> 一个包含IIR滤波器传递函数的前馈(分子)系数的数组。此数组的最大长度为20。如果所有值为零,必须抛出InvalidStateError异常如果数组长度为0或大于20,必须抛出NotSupportedError异常
feedback sequence<double> 一个包含IIR滤波器传递函数的反馈(分母)系数的数组。此数组的最大长度为20。如果数组的第一个元素为0,必须抛出InvalidStateError异常如果数组长度为0或大于20,必须抛出NotSupportedError异常
返回类型: IIRFilterNode

BaseAudioContext/createOscillator

在所有当前的引擎中。

Firefox25+Safari6+Chrome20+
Opera15+Edge79+
Edge (Legacy)12+IE
适用于Android的Firefox25+iOS Safari6+适用于Android的Chrome25+Android WebView37+Samsung Internet1.5+Opera Mobile14+

createOscillator()

工厂方法用于 OscillatorNode

无参数。
返回类型: OscillatorNode

BaseAudioContext/createPanner

在所有当前的引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (Legacy)12+IE
适用于Android的Firefox25+iOS Safari6+适用于Android的Chrome18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

createPanner()

工厂方法用于 PannerNode

无参数。
返回类型: PannerNode

BaseAudioContext/createPeriodicWave

在所有当前的引擎中。

Firefox25+Safari8+Chrome59+
Opera17+Edge79+
Edge (Legacy)12+IE
适用于Android的Firefox25+iOS Safari8+适用于Android的Chrome59+Android WebView59+Samsung Internet7.0+Opera Mobile18+

createPeriodicWave(real, imag, constraints)

工厂方法用于创建 PeriodicWave

调用此方法时,执行以下步骤:
  1. 如果realimag的长度不同,则必须抛出IndexSizeError异常。

  2. o为一个新对象,类型为PeriodicWaveOptions

  3. 分别将传递给此工厂方法的realimag参数设置为o上的同名属性。

  4. o上的disableNormalization属性设置为传递给工厂方法的constraints属性的disableNormalization属性的值。

  5. 构造一个新的PeriodicWavep,将此工厂方法被调用的BaseAudioContext作为第一个参数传递,并传递o

  6. 返回p

BaseAudioContext.createPeriodicWave()方法的参数。
参数 类型 可为空 可选 描述
real sequence<float> 一系列余弦参数。有关更详细的描述,请参阅其real构造函数参数。
imag sequence<float> 一系列正弦参数。有关更详细的描述,请参阅其imag构造函数参数。
constraints PeriodicWaveConstraints 如果未给出,则波形被归一化。否则,波形根据constraints给定的值进行归一化。
返回类型: PeriodicWave
createScriptProcessor(bufferSize, numberOfInputChannels, numberOfOutputChannels)

工厂方法用于创建一个ScriptProcessorNode。此方法已弃用,因为它将被AudioWorkletNode替代。创建一个ScriptProcessorNode以使用脚本进行直接音频处理。如果bufferSizenumberOfInputChannelsnumberOfOutputChannels超出有效范围,则必须抛出IndexSizeError异常。

对于numberOfInputChannelsnumberOfOutputChannels都为零的情况是无效的。在这种情况下,必须抛出IndexSizeError异常。

BaseAudioContext.createScriptProcessor(bufferSize, numberOfInputChannels, numberOfOutputChannels)方法的参数。
参数 类型 可为空 可选 描述
bufferSize unsigned long bufferSize参数决定了缓冲区大小,以采样帧为单位。如果未传入此参数,或者值为0,则实现将为给定环境选择最佳的缓冲区大小,并且在节点的整个生命周期内保持为2的幂次。如果作者明确指定了缓冲区大小,则该值必须是以下值之一:256、512、1024、2048、4096、8192、16384。此值控制onaudioprocess事件的调度频率以及每次调用需要处理的采样帧数量。较低的bufferSize值将导致较低(更好)的延迟。较高的值则有必要避免音频中断和音频故障。建议作者不要指定此缓冲区大小,而是允许实现选择一个好的缓冲区大小,以平衡延迟和音频质量。如果此参数的值不是上述允许的2的幂次之一,必须抛出IndexSizeError异常。
numberOfInputChannels unsigned long 此参数决定此节点输入的通道数量。默认值为2。必须支持多达32个值。如果不支持通道数量,必须抛出NotSupportedError
numberOfOutputChannels unsigned long 此参数决定此节点输出的通道数量。默认值为2。必须支持多达32个值。如果不支持通道数量,必须抛出NotSupportedError
返回类型: ScriptProcessorNode

BaseAudioContext/createStereoPanner

Firefox37+SafariChrome42+
OperaEdge79+
Edge (Legacy)12+IE
适用于Android的Firefox37+iOS Safari适用于Android的ChromeAndroid WebViewSamsung InternetOpera Mobile

createStereoPanner()

工厂方法用于 StereoPannerNode

无参数。
返回类型: StereoPannerNode

BaseAudioContext/createWaveShaper

在所有当前的引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (Legacy)12+IE
适用于Android的Firefox25+iOS Safari6+适用于Android的Chrome18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

createWaveShaper()

工厂方法用于 WaveShaperNode, 表示一种非线性失真。

无参数。
返回类型: WaveShaperNode

BaseAudioContext/decodeAudioData

在所有当前的引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (Legacy)12+IE
适用于Android的Firefox25+iOS Safari6+适用于Android的Chrome18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

decodeAudioData(audioData, successCallback, errorCallback)

异步解码包含在ArrayBuffer中的音频文件数据。例如,可以从XMLHttpRequestresponse属性中加载ArrayBuffer,前提是将responseType设置为"arraybuffer"。音频文件数据可以是audio元素支持的任何格式。传递给decodeAudioData()的缓冲区通过嗅探来确定其内容类型,如[mimesniff]中所述。

虽然与此函数交互的主要方法是通过其promise返回值,但为了兼容旧代码,仍提供了回调参数。

当调用decodeAudioData时,必须在控制线程上执行以下步骤:
  1. 如果this相关全局对象关联的文档不是完全激活的,则返回一个被拒绝的promise,原因是"InvalidStateError"DOMException

  2. 创建一个新的Promise,命名为promise

  3. 如果在IsDetachedBuffer(在[ECMASCRIPT]中描述)上,audioDatafalse,则执行以下步骤:

    1. promise附加到[[pending promises]]

    2. 分离audioDataArrayBuffer。此操作在[ECMASCRIPT]中有描述。如果此操作引发异常,跳至步骤3。

    3. 将解码操作排入队列,在另一个线程上执行。

  4. 否则,执行以下错误步骤:

    1. 创建一个error,类型为DataCloneError

    2. error拒绝promise,并从[[pending promises]]中移除它。

    3. 将一个媒体元素任务排入队列,以调用errorCallback并传入error

  5. 返回promise

当将解码操作排入队列以在另一个线程上执行时,以下步骤必须在不是控制线程渲染线程的线程上执行,称为解码线程

注意:多个解码线程可以并行运行以处理多个decodeAudioData调用。

  1. can decode为布尔标志,初始设置为true。

  2. 尝试使用MIME Sniffing §6.2 匹配音频或视频类型模式来确定audioData的MIME类型。如果音频或视频类型模式匹配算法返回undefined,则将can decode设置为false

  3. 如果can decodetrue,尝试将编码的audioData解码为线性PCM。如果失败,将can decode设置为false

  4. 如果can decodefalse将一个媒体元素任务排入队列,执行以下步骤:

    1. 创建一个error,类型为DOMException,名称为EncodingError

      1. error拒绝promise,并从[[pending promises]]中移除它。

    2. 如果errorCallback存在,则调用errorCallback并传入error

  5. 否则:

    1. 获取结果,表示解码后的线性PCM音频数据,并将其重新采样为BaseAudioContext的采样率(如果与audioData的采样率不同)。

    2. 将一个媒体元素任务排入队列,执行以下步骤:

      1. 将结果保存在buffer中,该buffer是一个AudioBuffer,包含最终结果(可能已执行采样率转换)。

      2. buffer解决promise

      3. 如果successCallback存在,则调用successCallback并传入buffer

BaseAudioContext.decodeAudioData()方法的参数。
参数 类型 可为空 可选 描述
audioData ArrayBuffer 包含压缩音频数据的ArrayBuffer。
successCallback DecodeSuccessCallback? 解码完成时调用的回调函数。此回调函数的唯一参数是表示解码后PCM音频数据的AudioBuffer。
errorCallback DecodeErrorCallback? 解码音频文件出错时调用的回调函数。
返回类型: Promise<AudioBuffer>

1.1.3. 回调 DecodeSuccessCallback() 参数

decodedData, 类型为 AudioBuffer

包含解码后音频数据的 AudioBuffer。

1.1.4. 回调 DecodeErrorCallback() 参数

error, 类型为 DOMException

解码时发生的错误。

1.1.5. 生命周期

一旦创建,AudioContext 将继续播放声音,直到没有声音可播放,或者页面消失。

1.1.6. 缺乏自省或序列化原语

Web Audio API 对音频源调度采取了一种发出后即忘的方式。也就是说,源节点AudioContext的生命周期内为每个音符创建,并且从未明确地从图中移除。这与序列化API不兼容,因为没有可以序列化的稳定节点集合。

此外,拥有一个自省API将允许内容脚本观察垃圾回收。

1.1.7. BaseAudioContext 子类相关的系统资源

子类 AudioContextOfflineAudioContext 应被视为昂贵的对象。创建这些对象可能涉及创建高优先级线程,或使用低延迟的系统音频流,这两者都会影响能耗。通常不需要在一个文档中创建多个 AudioContext

构建或恢复BaseAudioContext子类涉及为该上下文获取系统资源。对于AudioContext,这还需要创建一个系统音频流。这些操作将在上下文开始从其关联的音频图生成输出时返回。

此外,用户代理可以有一个实现定义的最大AudioContext数量,超过此数量后,尝试创建新的AudioContext将失败,抛出 NotSupportedError

suspendclose允许作者释放系统资源,包括线程、进程和音频流。暂停BaseAudioContext允许实现释放其部分资源,并允许稍后通过调用resume继续操作。关闭AudioContext允许实现释放其所有资源,之后将无法再次使用或恢复。

注意:例如,这可能涉及等待音频回调定期触发,或等待硬件准备好进行处理。

1.2. AudioContext 接口

AudioContext

Firefox25+SafariChrome35+
Opera22+Edge79+
Edge (Legacy)12+IE
Firefox for Android25+iOS SafariChrome for Android35+Android WebView37+Samsung Internet3.0+Opera Mobile22+

此接口表示一个音频图,其 AudioDestinationNode 被路由到一个实时输出设备,该设备生成一个针对用户的信号。在大多数 使用情况下,每个文档只使用一个 AudioContext

enum AudioContextLatencyCategory {
    "balanced",
    "interactive",
    "playback"
};
枚举描述
"balanced" 平衡音频输出延迟和功耗。
"interactive" 提供最低的音频输出延迟而不出现故障。这是默认设置。
"playback" 优先考虑持续播放不中断而不是音频输出延迟。最低功耗。
[Exposed=Window]
interface AudioContext : BaseAudioContext {
  constructor (optional AudioContextOptions contextOptions = {});
  readonly attribute double baseLatency;
  readonly attribute double outputLatency;
  AudioTimestamp getOutputTimestamp ();
  Promise<undefined> resume ();
  Promise<undefined> suspend ();
  Promise<undefined> close ();
  MediaElementAudioSourceNode createMediaElementSource (HTMLMediaElement mediaElement);
  MediaStreamAudioSourceNode createMediaStreamSource (MediaStream mediaStream);
  MediaStreamTrackAudioSourceNode createMediaStreamTrackSource (
    MediaStreamTrack mediaStreamTrack);
  MediaStreamAudioDestinationNode createMediaStreamDestination ();
};

一个 AudioContext 被认为是 允许启动 的,前提是用户代理允许上下文状态从 "suspended" 转换为 "running"。 用户代理可能会禁止此初始转换, 并且仅在 AudioContext相关全局对象具有 粘性激活 时允许它。

AudioContext 有一个内部槽:

[[suspended by user]]

一个表示上下文是否由用户代码暂停的布尔标志。 初始值为 false

1.2.1. 构造函数

AudioContext/AudioContext

Firefox25+SafariChrome35+
Opera22+Edge79+
Edge (Legacy)12+IE
Firefox for Android25+iOS SafariChrome for Android35+Android WebView37+Samsung Internet3.0+Opera Mobile22+

AudioContext(contextOptions)

如果 当前设置对象责任文档 不是 完全活动的,则抛出 InvalidStateError 并中止这些步骤。

在创建一个 AudioContext 时,执行以下步骤:
  1. [[control thread state]] 设置为 suspendedAudioContext 上。

  2. [[rendering thread state]] 设置为 suspendedAudioContext 上。

  3. [[pending resume promises]] 成为这个 AudioContext 的一个槽, 它是一个最初为空的有序承诺列表。

  4. 如果给定了 contextOptions,则应用这些选项:

    1. 根据 contextOptions.latencyHint, 设置此 AudioContext 的内部延迟, 如 latencyHint 中描述的那样。

    2. 如果 contextOptions.sampleRate 被指定, 则将此 sampleRate 设置为 此 AudioContext 的值。 否则,使用默认输出设备的采样率。如果选择的采样率与输出设备的采样率不同,则此 AudioContext 必须重新采样 音频输出以匹配输出设备的采样率。

      注意: 如果需要重新采样,则 AudioContext 的延迟可能会受到影响,可能会影响很大。

  5. 如果上下文 允许启动,发送一个 控制消息 以开始处理。

  6. 返回此 AudioContext 对象。

发送一个 控制消息 以开始处理的意思是 执行以下步骤:
  1. 尝试 获取系统资源。 如果失败,中止以下步骤。

  2. [[rendering thread state]] 设置为 runningAudioContext 上。

  3. 排队一个媒体元素任务以执行以下步骤:

    1. state 属性设置为 AudioContextrunning

    2. 排队一个媒体元素任务触发一个事件,名称为 statechangeAudioContext 上。

注意: 遗憾的是,无法以编程方式通知 作者创建 AudioContext 失败。 如果用户代理有访问日志记录机制(如开发者工具控制台)的权限, 建议记录一条信息性消息。

AudioContext.constructor(contextOptions) 方法的参数。
参数 类型 可为空 可选 描述
contextOptions AudioContextOptions 用户指定的选项,用于控制 AudioContext 的构造方式。

1.2.2. 属性

AudioContext/baseLatency

Firefox70+SafariChrome58+
Opera45+Edge79+
Edge (Legacy)IE
Firefox for AndroidiOS SafariChrome for Android58+Android WebView58+Samsung Internet7.0+Opera Mobile43+

baseLatency 类型为 double,只读

这表示由 AudioContext 将音频从 AudioDestinationNode 传递到音频子系统时产生的处理延迟秒数。它不包括由于 AudioDestinationNode 和音频硬件之间的任何其他处理引起的任何额外延迟,尤其不包括音频图本身产生的任何延迟。

例如,如果音频上下文以 44.1 kHz 运行,且 AudioDestinationNode 内部实现双缓冲,并且可以处理和输出每个 渲染量子 的音频,那么处理延迟大约为 \((2\cdot128)/44100 = 5.805 \mathrm{ ms}\)。

AudioContext/outputLatency

仅在一个当前引擎中。

Firefox70+SafariChrome
OperaEdge
Edge (Legacy)IE
Firefox for AndroidiOS SafariChrome for AndroidAndroid WebViewSamsung InternetOpera Mobile

outputLatency 类型为 double,只读

音频输出延迟的秒数估计,即用户代理请求主机系统播放缓冲区的时间与缓冲区中的第一个样本实际上由音频输出设备处理的时间之间的间隔。对于产生声学信号的设备(例如扬声器或耳机),后者时间是指样本的声音发出时间。

outputLatency 属性值取决于平台和连接的硬件音频输出设备。只要连接的音频输出设备保持不变,此 outputLatency 属性值在上下文的生命周期内不会改变。如果更改音频输出设备,则 outputLatency 属性值将相应更新。

1.2.3. 方法

AudioContext/close

在所有当前引擎中。

Firefox40+Safari9+Chrome42+
OperaEdge79+
Edge (Legacy)14+IE
Firefox for Android40+iOS Safari9+Chrome for Android43+Android WebView43+Samsung Internet4.0+Opera Mobile

close()

关闭 AudioContext释放所使用的系统资源。这不会自动释放所有 AudioContext 创建的对象,但会暂停 currentTime 的进程, 并停止处理音频数据。

调用 close 时,执行以下步骤:
  1. 如果 this相关全局对象关联文档 不是 完全活跃,则返回 拒绝的 promise,并带有 InvalidStateError DOMException

  2. promise 成为一个新的 Promise。

  3. 如果 [[control thread state]]AudioContext 上被设置为 closed,则拒绝 promise,并使用 InvalidStateError, 中止这些步骤,并返回 promise

  4. [[control thread state]]AudioContext 上设置为 closed

  5. 排队控制消息 以关闭 AudioContext

  6. 返回 promise

运行控制消息 control message 以关闭 AudioContext 意味着在 渲染线程 上运行这些步骤:
  1. 尝试 释放系统资源

  2. [[rendering thread state]] 设置为 suspended

    这将停止渲染。
  3. 如果该 控制消息 是由于文档卸载而被运行的,则中止该算法。

    在这种情况下,无需通知控制线程。
  4. 排队一个媒体元素任务 以执行以下步骤:

    1. 解析 promise

    2. 如果 state 属性不是 closed

      1. state 属性设置为 closed

      2. 排队一个媒体元素任务触发事件 名为 statechange 的 在 AudioContext 上。

AudioContext 被关闭时,任何 MediaStreamHTMLMediaElement 将不再输出。这就是说,这些将不再产生输出到扬声器或其他输出设备。为了更灵活的行为,考虑使用 HTMLMediaElement.captureStream()

注意: 当一个 AudioContext 已被关闭时,实现可以选择积极地释放比暂停时更多的资源。

无参数。
返回类型: Promise<undefined>

AudioContext/createMediaElementSource

在所有当前引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (Legacy)12+IE
Firefox for Android25+iOS Safari6+Chrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

createMediaElementSource(mediaElement)

创建一个 MediaElementAudioSourceNode, 给定一个 HTMLMediaElement。 调用此方法的结果是 HTMLMediaElement 的音频将被重新路由到 AudioContext 的处理图中。

AudioContext.createMediaElementSource() 方法的参数。
参数 类型 可为空 可选 描述
mediaElement HTMLMediaElement 将被重新路由的媒体元素。
返回类型: MediaElementAudioSourceNode

AudioContext/createMediaStreamDestination

在所有当前引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (Legacy)IE
Firefox for Android25+iOS SafariChrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

createMediaStreamDestination()

创建一个 MediaStreamAudioDestinationNode

无参数。
返回类型: MediaStreamAudioDestinationNode

AudioContext/createMediaStreamSource

在所有当前引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (Legacy)12+IE
Firefox for Android25+iOS SafariChrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

createMediaStreamSource(mediaStream)

创建一个 MediaStreamAudioSourceNode

AudioContext.createMediaStreamSource() 方法的参数。
参数 类型 可为空 可选 描述
mediaStream MediaStream 将作为源的媒体流。
返回类型: MediaStreamAudioSourceNode

AudioContext/createMediaStreamTrackSource

在少于两个当前引擎中。

Firefox68+SafariChrome
OperaEdge
Edge (Legacy)IE
Firefox for Android68+iOS SafariChrome for AndroidAndroid WebViewSamsung InternetOpera Mobile

createMediaStreamTrackSource(mediaStreamTrack)

创建一个 MediaStreamTrackAudioSourceNode

AudioContext.createMediaStreamTrackSource() 方法的参数。
参数 类型 可为空 可选 描述
mediaStreamTrack MediaStreamTrack 将作为源的 MediaStreamTrackkind 属性值必须等于 "audio",否则必须抛出 InvalidStateError 异常。
返回类型: MediaStreamTrackAudioSourceNode

AudioContext/getOutputTimestamp

Firefox70+SafariChrome57+
Opera44+Edge79+
Edge (Legacy)IE
Firefox for AndroidiOS SafariChrome for Android57+Android WebView57+Samsung Internet7.0+Opera Mobile43+

getOutputTimestamp()

返回一个新的 AudioTimestamp 实例, 其中包含两个与上下文相关的音频流位置值:contextTime 成员包含由音频输出设备当前渲染的采样帧的时间(即输出音频流位置),单位与上下文的 currentTime 相同; performanceTime 成员包含估计的时间,这个时间表示与存储的 contextTime 值对应的采样帧由音频输出设备渲染的时刻,单位与 performance.now()(在 [hr-time-3] 中描述)相同。

如果上下文的渲染图尚未处理音频块,则 getOutputTimestamp 调用会返回一个 AudioTimestamp 实例,其中两个成员都包含零。

在上下文的渲染图开始处理音频块之后,它的 currentTime 属性值总是超过从 contextTime 中获取的值 getOutputTimestamp 调用。

getOutputTimestamp 方法返回的值可以用于获取稍后的上下文时间值的性能时间估计:
function outputPerformanceTime(contextTime) {
  const timestamp = context.getOutputTimestamp();
  const elapsedTime = contextTime - timestamp.contextTime;
  return timestamp.performanceTime + elapsedTime * 1000;
}

在上面的例子中,估计的准确性取决于参数值与当前输出音频流位置的接近程度:给定的 contextTime 越接近 timestamp.contextTime,所获得估计的准确性越高。

注意: 上下文的 currentTime 值与从 contextTime 中获取的值之间的差异 getOutputTimestamp 方法调用 不能被认为是可靠的输出延迟估计, 因为 currentTime 可能在不均匀的时间间隔内递增,所以应使用 outputLatency 属性代替。

无参数。
返回类型: AudioTimestamp

AudioContext/resume

在所有当前引擎中。

Firefox40+Safari9+Chrome41+
OperaEdge79+
Edge (Legacy)14+IE
Firefox for AndroidiOS Safari9+Chrome for Android41+Android WebView41+Samsung Internet4.0+Opera Mobile

resume()

恢复 AudioContextcurrentTime 进程,当它已被暂停时。

调用 resume 时, 执行以下步骤:
  1. 如果 this相关全局对象关联文档 不是 完全活跃,则返回 拒绝的 promise,并带有 InvalidStateError DOMException

  2. promise 成为一个新的 Promise。

  3. 如果 [[control thread state]]AudioContext 上被设置为 closed,则拒绝 promise,并使用 InvalidStateError, 中止这些步骤, 并返回 promise

  4. [[suspended by user]] 设置为 false

  5. 如果上下文不 允许启动,则将 promise 添加到 [[pending promises]][[pending resume promises]] 中, 并中止这些步骤,返回 promise

  6. [[control thread state]] 设置为 running

  7. 排队控制消息 以恢复 AudioContext

  8. 返回 promise

运行控制消息 control message 以恢复 AudioContext 意味着在 渲染线程 上运行这些步骤:
  1. 尝试 获取系统资源

  2. [[rendering thread state]] 设置为 running

  3. 启动 渲染音频图

  4. 如果失败, 排队一个媒体元素任务 以执行以下步骤:

    1. 按顺序拒绝所有来自 [[pending resume promises]] 的 promise, 然后清空 [[pending resume promises]]

    2. 此外,从 [[pending promises]] 中移除这些 promise。

  5. 排队一个媒体元素任务 以执行以下步骤:

    1. 按顺序解析所有来自 [[pending resume promises]] 的 promise。

    2. 清空 [[pending resume promises]]。 另外,从 [[pending promises]] 中移除这些 promise。

    3. 解析 promise

    4. 如果 state 属性不为 running

      1. state 属性设置为 running

      2. 排队一个媒体元素任务触发事件 名为 statechange 的 在 AudioContext 上。

无参数。
返回类型: Promise<undefined>

AudioContext/suspend

在所有当前引擎中。

Firefox40+Safari9+Chrome43+
OperaEdge79+
Edge (Legacy)14+IE
Firefox for Android40+iOS Safari9+Chrome for Android43+Android WebView43+Samsung Internet4.0+Opera Mobile

suspend()

暂停 AudioContextcurrentTime 的进度, 允许已经处理的当前上下文处理块播放到目标,然后允许系统释放对音频硬件的占用。当应用程序知道在一段时间内不需要 AudioContext 时,这通常是有用的,并希望暂时释放与 AudioContext 相关的系统资源。当帧缓冲区为空(已交给硬件)时,承诺会被解决,或者如果上下文已经 suspended,则立即解决(无其他效果)。如果上下文已关闭,承诺会被拒绝。

调用 suspend 时,执行以下步骤:
  1. 如果 this相关全局对象关联文档 不是 完全活跃,则返回 拒绝的 promise,并带有 InvalidStateError DOMException

  2. promise 成为一个新的 Promise。

  3. 如果 [[control thread state]]AudioContext 上被设置为 closed,则拒绝 promise,并使用 InvalidStateError, 中止这些步骤, 并返回 promise

  4. promise 添加到 [[pending promises]] 中。

  5. [[suspended by user]] 设置为 true

  6. [[control thread state]]AudioContext 设置为 suspended

  7. 排队控制消息 以暂停 AudioContext

  8. 返回 promise

运行控制消息 control message 以暂停 AudioContext 意味着在 渲染线程 上运行这些步骤:
  1. 尝试 释放系统资源

  2. [[rendering thread state]]AudioContext 设置为 suspended

  3. 排队一个媒体元素任务 以执行以下步骤:

    1. 解析 promise

    2. 如果 state 属性不是 suspended

      1. state 属性设置为 suspended

      2. 排队一个媒体元素任务触发事件 名为 statechange 的 在 AudioContext 上。

AudioContext 被暂停时,MediaStream 将不再输出; 也就是说,数据将由于媒体流的实时特性而丢失。HTMLMediaElement 也将类似地忽略其输出,直到系统恢复。AudioWorkletNodeScriptProcessorNode 将停止调用其处理程序,直到上下文恢复。对于 AnalyserNode 窗口函数,数据被视为连续流 - 即 resume()/suspend() 不会导致 在 AnalyserNode 数据流中出现静音。 特别是,当 AudioContext 被暂停时,重复调用 AnalyserNode 函数必须返回相同的数据。

无参数。
返回类型: Promise<undefined>

1.2.4. AudioContextOptions

AudioContextOptions

Firefox61+SafariChrome60+
Opera?Edge79+
Edge (Legacy)IE
Firefox for Android61+iOS SafariChrome for Android60+Android WebView60+Samsung Internet8.0+Opera Mobile?

The AudioContextOptions 字典用于指定用户指定的 AudioContext 的选项。

dictionary AudioContextOptions {
  (AudioContextLatencyCategory or double) latencyHint = "interactive";
  float sampleRate;
};
1.2.4.1. Dictionary AudioContextOptions 成员

AudioContextOptions/latencyHint

Firefox61+SafariChrome60+
Opera?Edge79+
Edge (Legacy)IE
Firefox for Android61+iOS SafariChrome for Android60+Android WebView60+Samsung Internet8.0+Opera Mobile?

latencyHint, 类型为 (AudioContextLatencyCategory 或 double),默认为 "interactive"

标识播放类型,这会影响音频输出延迟与功耗之间的权衡。

latencyHint 的首选值来自 AudioContextLatencyCategory。 但是,也可以指定一个 double 值来表示延迟秒数,以便更细致地控制延迟与功耗之间的平衡。浏览器可自行解释该值并应用适当的延迟。实际使用的延迟由 AudioContext 的 baseLatency 属性给出。

AudioContextOptions/sampleRate

Firefox61+SafariChrome74+
OperaEdge79+
Edge (Legacy)IE
Firefox for Android61+iOS SafariChrome for Android74+Android WebView74+Samsung Internet11.0+Opera Mobile

sampleRate, 类型为 float

为将要创建的 AudioContext 设置 sampleRate 值。支持的值与 AudioBuffer 的采样率相同。 如果指定的采样率不受支持,NotSupportedError 异常必须被抛出。

如果未指定 sampleRate, 则使用该 AudioContext 输出设备的首选采样率。

1.2.5. AudioTimestamp

dictionary AudioTimestamp {
double contextTime;
DOMHighResTimeStamp performanceTime;
};
1.2.5.1. 字典 AudioTimestamp 成员
contextTime, 类型为 double

表示 BaseAudioContext 的 currentTime 的时间坐标系中的一个点。

performanceTime, 类型为 DOMHighResTimeStamp

表示 Performance 接口实现的时间坐标系中的一个点(详见 [hr-time-3])。

1.3. OfflineAudioContext 接口

OfflineAudioContext

Firefox25+SafariNoneChrome35+
Opera22+Edge79+
Edge (Legacy)12+IENone
Firefox for Android25+iOS SafariNoneChrome for Android35+Android WebView4.4.3+Samsung Internet3.0+Opera Mobile22+

OfflineAudioContext 是一种特殊类型的 BaseAudioContext ,用于(可能)比实时更快地渲染/混音。它不会渲染到音频硬件,而是尽可能快地渲染,并将渲染结果作为 AudioBuffer 的形式返回。

[Exposed=Window]
interface OfflineAudioContext : BaseAudioContext {
  constructor(OfflineAudioContextOptions contextOptions);
  constructor(unsigned long numberOfChannels, unsigned long length, float sampleRate);
  Promise<AudioBuffer> startRendering();
  Promise<undefined> resume();
  Promise<undefined> suspend(double suspendTime);
  readonly attribute unsigned long length;
  attribute EventHandler oncomplete;
};

1.3.1. 构造函数

OfflineAudioContext/OfflineAudioContext

Firefox53+SafariNoneChrome35+
Opera22+Edge79+
Edge (Legacy)NoneIENone
Firefox for Android53+iOS SafariNoneChrome for Android35+Android WebView4.4.3+Samsung Internet3.0+Opera Mobile22+

OfflineAudioContext(contextOptions)

如果 当前设置对象负责的文档 不是 完全激活的,则抛出 InvalidStateError 并中止这些步骤。

c 为一个新的 OfflineAudioContext 对象。 将 c 初始化如下:
  1. c[[控制线程状态]] 设置为 "suspended"

  2. c[[渲染线程状态]] 设置为 "suspended"

  3. 构造一个 AudioDestinationNode ,其 channelCount 设置为 contextOptions.numberOfChannels

OfflineAudioContext.constructor(contextOptions) 方法的参数。
参数 类型 可为空 可选 描述
contextOptions 构建此上下文所需的初始参数。
OfflineAudioContext(numberOfChannels, length, sampleRate)

OfflineAudioContext 可以使用与 AudioContext.createBuffer 相同的参数构造。如果任何参数为负、为零或超出其标称范围,必须抛出 NotSupportedError 异常。

OfflineAudioContext 的构造如下:

new OfflineAudioContext({
numberOfChannels: numberOfChannels,
length: length,
sampleRate: sampleRate
})

如同调用了上述代码。

OfflineAudioContext.constructor(numberOfChannels, length, sampleRate) 方法的参数。
参数 类型 可为空 可选 描述
numberOfChannels unsigned long 确定缓冲区将具有的通道数量。请参阅 createBuffer() ,了解支持的通道数量。
length unsigned long 确定缓冲区的大小,以采样帧为单位。
sampleRate float 描述缓冲区中线性 PCM 音频数据的采样率,以每秒采样帧数表示。请参阅 createBuffer() ,了解有效的采样率。

1.3.2. 属性

OfflineAudioContext/length

FirefoxYesSafariNoneChrome51+
Opera38+Edge79+
Edge (Legacy)14+IENone
Firefox for AndroidYesiOS SafariNoneChrome for Android51+Android WebView51+Samsung Internet5.0+Opera Mobile41+

length, 类型为 unsigned long,只读

缓冲区的大小,以采样帧为单位。此值与构造函数中的 length 参数相同。

OfflineAudioContext/oncomplete

在所有当前引擎中。

Firefox25+Safari6+Chrome25+
Opera15+Edge79+
Edge (Legacy)12+IENone
Firefox for Android25+iOS Safari?Chrome for Android25+Android WebView37+Samsung Internet1.5+Opera Mobile14+

oncomplete, 类型为 EventHandler

类型为 OfflineAudioCompletionEvent 的事件处理程序。 它是 OfflineAudioContext 上触发的最后一个事件。

1.3.3. 方法

OfflineAudioContext/startRendering

在所有当前引擎中。

Firefox25+Safari6+Chrome25+
Opera15+Edge79+
Edge (Legacy)12+IENone
Firefox for Android25+iOS Safari?Chrome for Android25+Android WebView37+Samsung Internet1.5+Opera Mobile14+

startRendering()

根据当前连接和已安排的更改,开始渲染音频。

虽然获取渲染音频数据的主要方法是通过其 promise 返回值,但该实例还会为遗留原因触发名为 complete 的事件。

[[rendering started]] 成为此 OfflineAudioContext 的一个内部槽。 将此槽初始化为 false

当调用 startRendering 时,以下步骤必须在 控制线程 上执行:

  1. 如果 此对象相关全局对象关联文档 不是 完全活跃,则返回 一个被拒绝的 promise 并附上 "InvalidStateError" DOMException
  2. 如果 [[rendering started]] 槽在 OfflineAudioContext 上为 true,则返回一个被拒绝的 promise,并附上 InvalidStateError,并中止这些步骤。
  3. [[rendering started]] 槽设置为 true
  4. promise 为一个新的 promise。
  5. 创建一个新的 AudioBuffer,其通道数、长度和采样率分别等于传递给此实例构造函数中 contextOptions 参数的 numberOfChannelslengthsampleRate 值。 将此缓冲区分配给 OfflineAudioContext 中的内部槽 [[rendered buffer]]
  6. 如果在前述 AudioBuffer 构造函数调用期间抛出了异常,则使用此异常拒绝 promise
  7. 否则,如果缓冲区成功构造,则 开始离线渲染
  8. promise 添加到 [[pending promises]] 中。
  9. 返回 promise
若要 开始离线渲染,以下步骤必须在为此目的创建的 渲染线程 上进行。
  1. 根据当前连接和已安排的更改,开始将 length 采样帧的音频渲染到 [[rendered buffer]] 中。
  2. 对于每个 渲染量子,检查并在必要时 暂停 渲染。
  3. 如果暂停的上下文被恢复,继续渲染缓冲区。
  4. 渲染完成后, 队列一个媒体元素任务 以执行以下步骤:
    1. 使用 [[rendered buffer]] 解析由 startRendering() 创建的 promise
    2. 队列一个媒体元素任务触发一个事件,名为 complete,使用一个实例 OfflineAudioCompletionEvent,其 renderedBuffer 属性设置为 [[rendered buffer]]
无参数。
返回类型: Promise<AudioBuffer>

OfflineAudioContext/resume

仅在一个当前引擎中。

FirefoxNoneSafariNoneChrome49+
Opera36+Edge79+
Edge (Legacy)18IENone
Firefox for AndroidNoneiOS SafariNoneChrome for Android49+Android WebView49+Samsung Internet5.0+Opera Mobile36+

resume()

恢复 OfflineAudioContextcurrentTime 的时间进程,当它已暂停时。

当调用 resume 时,执行以下步骤:
  1. 如果 此对象相关全局对象关联文档 不是 完全活跃,则返回 一个被拒绝的 promise 并附上 "InvalidStateError" DOMException

  2. promise 为一个新的 Promise。

  3. 当以下任一条件为真时,中止这些步骤并使用 InvalidStateError 拒绝 promise

  4. [[control thread state]] 标志设置为 running

  5. 队列一个控制消息 以恢复 OfflineAudioContext

  6. 返回 promise

在 OfflineAudioContext 中运行 控制消息 以恢复 OfflineAudioContext 的操作意味着在 渲染线程 上执行这些步骤:
  1. [[rendering thread state]] 设置为 running

  2. 开始 渲染音频图

  3. 在出现故障的情况下, 队列一个媒体元素任务 以拒绝 promise 并中止剩余步骤。

  4. 队列一个媒体元素任务 以执行以下步骤:

    1. 解析 promise

    2. 如果 OfflineAudioContext 的 state 属性尚未设置为 "running":

      1. 将 OfflineAudioContext 的 state 属性设置为 "running"。

      2. 队列一个媒体元素任务触发一个事件,名为 statechange,并指向 OfflineAudioContext。

无参数。
返回类型: Promise<undefined>

OfflineAudioContext/suspend

仅在一个当前引擎中。

FirefoxNoneSafariNoneChrome49+
Opera36+Edge79+
Edge (Legacy)18IENone
Firefox for AndroidNoneiOS SafariNoneChrome for Android49+Android WebView49+Samsung Internet5.0+Opera Mobile36+

suspend(suspendTime)

计划在指定时间暂停音频上下文的时间进程,并返回一个 promise。在 OfflineAudioContext 上同步操作音频图时,这通常非常有用。

请注意,暂停的最大精度为 渲染量子 的大小,指定的暂停时间 将四舍五入到最接近的 渲染量子 边界。因此,不允许在同一量化帧中安排多个暂停。此外,应在上下文未运行时安排,以确保 精确暂停。

OfflineAudioContext.suspend() 方法的参数。
参数 类型 可为 null 可选 描述
suspendTime double 在指定的时间安排暂停渲染,该时间将量化并四舍五入到 渲染量子 大小。如果量化的帧号
  1. 为负或
  2. 小于或等于当前时间或
  3. 大于或等于总渲染持续时间或
  4. 在同一时间被另一个暂停安排,
则 promise 将因 InvalidStateError 而被拒绝。
返回类型: Promise<undefined>

1.3.4. OfflineAudioContextOptions

此部分指定用于构建 OfflineAudioContext 的选项。

dictionary OfflineAudioContextOptions {
  unsigned long numberOfChannels = 1;
  required unsigned long length;
  required float sampleRate;
};
1.3.4.1. 字典 OfflineAudioContextOptions 成员
length, 类型为 unsigned long

渲染的 AudioBuffer 的长度,以采样帧为单位。

numberOfChannels, 类型为 unsigned long,默认值为 1

OfflineAudioContext 的通道数。

sampleRate, 类型为 float

OfflineAudioContext 的采样率。

1.3.5. OfflineAudioCompletionEvent 接口

OfflineAudioCompletionEvent

在所有当前的引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (传统版)12+IE
Android 版 Firefox25+iOS SafariAndroid 版 Chrome18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

OfflineAudioContext/complete_event

在所有当前的引擎中。

Firefox25+Safari6+Chrome25+
Opera15+Edge79+
Edge (传统版)12+IE
Android 版 Firefox25+iOS SafariAndroid 版 Chrome25+Android WebView37+Samsung Internet1.5+Opera Mobile14+

这是一个 Event 对象,出于兼容性原因被分派给 OfflineAudioContext

OfflineAudioCompletionEvent/OfflineAudioCompletionEvent

在所有当前的引擎中。

Firefox53+SafariChrome57+
Opera42+Edge79+
Edge (传统版)IE
Android 版 Firefox53+iOS SafariAndroid 版 Chrome57+Android WebView57+Samsung Internet6.0+Opera Mobile42+
[Exposed=Window]
interface OfflineAudioCompletionEvent : Event {
  constructor (DOMString type, OfflineAudioCompletionEventInit eventInitDict);
  readonly attribute AudioBuffer renderedBuffer;
};
1.3.5.1. 属性

OfflineAudioCompletionEvent/renderedBuffer

在所有当前的引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (传统版)12+IE
Android 版 Firefox25+iOS SafariAndroid 版 Chrome18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

renderedBuffer, 类型为 AudioBuffer,只读

一个包含渲染音频数据的 AudioBuffer

1.3.5.2. OfflineAudioCompletionEventInit
dictionary OfflineAudioCompletionEventInit : EventInit {
  required AudioBuffer renderedBuffer;
};
1.3.5.2.1. 字典 OfflineAudioCompletionEventInit 成员
renderedBuffer, 类型为 AudioBuffer

赋值给事件的 renderedBuffer 属性的值。

1.4. AudioBuffer 接口

AudioBuffer/AudioBuffer

Firefox53+SafariNoneChrome55+
Opera42+Edge79+
Edge (旧版)NoneIENone
Firefox for Android53+iOS SafariNoneChrome for Android55+Android WebView55+Samsung Internet6.0+Opera Mobile42+

此接口表示一个内存常驻的音频资源。它可以包含一个或多个通道,每个通道都表现为32位浮点 线性PCM值,标称范围为\([-1,1]\),但数值并不限于此范围。通常,PCM数据的长度预期会相对较短(通常少于一分钟)。对于更长的声音,如音乐原声带,应该使用流式传输和 audio 元素以及 MediaElementAudioSourceNode

AudioBuffer 可能会被一个或多个 AudioContext 使用,并且可以在 OfflineAudioContextAudioContext 之间共享。

AudioBuffer 有四个内部槽:

[[number of channels]]

AudioBuffer 的音频通道数量,为无符号长整型。

[[length]]

AudioBuffer 每个通道的长度,为无符号长整型。

[[sample rate]]

AudioBuffer 的采样率,以Hz为单位,为浮点数。

[[internal data]]

保存音频样本数据的数据块

AudioBuffer

在所有当前引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (旧版)12+IENone
Firefox for Android25+iOS Safari6+Chrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile14+
[Exposed=Window]
interface AudioBuffer {
  constructor (AudioBufferOptions options);
  readonly attribute float sampleRate;
  readonly attribute unsigned long length;
  readonly attribute double duration;
  readonly attribute unsigned long numberOfChannels;
  Float32Array getChannelData (unsigned long channel);
  undefined copyFromChannel (Float32Array destination,
                             unsigned long channelNumber,
                             optional unsigned long bufferOffset = 0);
  undefined copyToChannel (Float32Array source,
                           unsigned long channelNumber,
                           optional unsigned long bufferOffset = 0);
};

1.4.1. 构造函数

AudioBuffer(options)
  1. 如果 options 中的任何值超出其标称范围,则抛出 NotSupportedError 异常并中止以下步骤。

  2. b 成为一个新的 AudioBuffer 对象。

  3. 分别将构造函数中传入的 numberOfChannelslengthsampleRate 属性的值分别赋值给内部槽 [[number of channels]][[length]][[sample rate]]

  4. 将此 AudioBuffer 的内部槽 [[internal data]] 设置为调用 CreateByteDataBlock 的结果 ([[length]] * [[number of channels]])

    注意: 这会将底层存储初始化为零。

  5. 返回 b

AudioBuffer.constructor() 方法的参数。
参数 类型 可空 可选 描述
options AudioBufferOptions 一个 AudioBufferOptions, 用于确定此 AudioBuffer 的属性。

1.4.2. 属性

AudioBuffer/duration

在所有当前引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (旧版)12+IENone
Firefox for Android25+iOS Safari6+Chrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

duration, 类型为 double,只读

PCM 音频数据的持续时间,以秒为单位。

通过将 [[length]] 除以 [[sample rate]] 计算得出 AudioBuffer 的值。

AudioBuffer/length

在所有当前引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (旧版)12+IENone
Firefox for Android25+iOS Safari6+Chrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

length, 类型为 unsigned long,只读

PCM 音频数据的长度,以样本帧为单位。必须返回 [[length]] 的值。

AudioBuffer/numberOfChannels

在所有当前引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (旧版)12+IENone
Firefox for Android25+iOS Safari6+Chrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

numberOfChannels, 类型为 unsigned long,只读

离散音频通道的数量。必须返回 [[number of channels]] 的值。

AudioBuffer/sampleRate

在所有当前引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (旧版)12+IENone
Firefox for Android25+iOS Safari6+Chrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

sampleRate, 类型为 float,只读

PCM 音频数据的采样率,以每秒样本数表示。必须返回 [[sample rate]] 的值。

1.4.3. 方法

AudioBuffer/copyFromChannel

Firefox25+SafariNoneChrome43+
Opera30+Edge79+
Edge (旧版)13+IENone
Firefox for Android25+iOS SafariNoneChrome for Android43+Android WebView43+Samsung Internet4.0+Opera Mobile30+

copyFromChannel(destination, channelNumber, bufferOffset)

copyFromChannel() 方法将指定通道的样本从 AudioBuffer 复制到 destination 数组中。

bufferAudioBuffer 具有 \(N_b\) 帧,设 \(N_f\) 为 destination 数组中的元素数量,\(k\) 是 bufferOffset 的值。 然后,从 buffer 复制到 destination 的帧数为 \(\max(0, \min(N_b - k, N_f))\)。如果此值小于 \(N_f\),则 destination 的其余元素将不被修改。

AudioBuffer.copyFromChannel() 方法的参数。
参数 类型 可空 可选 描述
destination Float32Array 通道数据将被复制到的数组。
channelNumber unsigned long 要复制数据的通道的索引。如果 channelNumber 大于或等于 AudioBuffer 的通道数量,则 必须抛出 IndexSizeError 异常
bufferOffset unsigned long 一个可选的偏移量,默认为 0。从此偏移量开始,从 AudioBuffer 复制数据到 destination
返回类型: undefined

AudioBuffer/copyToChannel

Firefox25+SafariNoneChrome43+
Opera30+Edge79+
Edge (旧版)13+IENone
Firefox for Android25+iOS SafariNoneChrome for Android43+Android WebView43+Samsung Internet4.0+Opera Mobile30+

copyToChannel(source, channelNumber, bufferOffset)

copyToChannel() 方法将样本从 source 数组复制到 AudioBuffer 的指定通道。

如果 UnknownError 被抛出,则表示无法将 source 复制到缓冲区。

bufferAudioBuffer 具有 \(N_b\) 帧,设 \(N_f\) 为 source 数组中的元素数量,\(k\) 是 bufferOffset 的值。 然后,从 source 复制到 buffer 的帧数为 \(\max(0, \min(N_b - k, N_f))\)。如果此值小于 \(N_f\),则 buffer 的其余元素将不被修改。

AudioBuffer.copyToChannel() 方法的参数。
参数 类型 可空 可选 描述
source Float32Array 通道数据将被复制到的数组。
channelNumber unsigned long 要复制数据的通道的索引。如果 channelNumber 大于或等于 AudioBuffer 的通道数量,则 必须抛出 IndexSizeError 异常
bufferOffset unsigned long 一个可选的偏移量,默认为 0。从此偏移量开始,从 source 复制数据到 AudioBuffer
返回类型: undefined

AudioBuffer/getChannelData

在所有当前引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (旧版)12+IENone
Firefox for Android25+iOS Safari6+Chrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

getChannelData(channel)

根据 获取内容 中描述的规则,从 [[internal data]] 中获取字节,并在新的 Float32Array 中返回。

如果 UnknownError 被抛出,则表示无法创建 [[internal data]] 或新的 Float32Array

AudioBuffer.getChannelData() 方法的参数。
参数 类型 可空 可选 描述
channel unsigned long 此参数是一个索引,表示要获取数据的特定通道。索引值为 0 表示第一个通道。此索引值必须小于 [[number of channels]],否则必须抛出 IndexSizeError 异常。
返回类型: Float32Array

注意: copyToChannel()copyFromChannel() 方法可以通过传递一个 Float32Array 视图来填充数组的一部分。 当从 AudioBuffer 的通道中读取数据并且数据可以分块处理时, 应优先使用 copyFromChannel() 而不是调用 getChannelData() 并访问生成的数组,因为它可能避免不必要的内存分配和复制。

当某些 API 实现需要 AudioBuffer 的内容时,会调用内部操作 获取 AudioBuffer 的内容。 此操作将不可变的通道数据返回给调用者。

当在 AudioBuffer 上发生 获取内容 操作时,执行以下步骤:
  1. 如果对任何 AudioBufferArrayBuffer 执行操作 IsDetachedBuffer 返回 true,则中止这些步骤,并向调用者返回零长度的通道数据缓冲区。

  2. 分离 所有 ArrayBuffer 以前通过 getChannelData() 返回的数组在这个 AudioBuffer 上。

    注意:由于 AudioBuffer 只能通过 createBuffer() 或通过 AudioBuffer 构造函数创建, 因此不会抛出。

  3. 保留这些 ArrayBuffer 中的基础 [[internal data]] ,并将引用返回给调用者。

  4. 将包含数据副本的 ArrayBuffer 附加到 AudioBuffer 上, 以便在下一次调用 getChannelData() 时返回。

在以下情况下,会调用 获取 AudioBuffer 的内容 操作:

注意: 这意味着在 获取 AudioBuffer 的内容 后,copyToChannel() 不能用于更改正在由 AudioNode 使用的 AudioBuffer 的内容, 因为 AudioNode 将继续使用之前获取的数据。

1.4.4. AudioBufferOptions

这指定了构造 AudioBuffer 时要使用的选项。lengthsampleRate 成员是必需的。

dictionary AudioBufferOptions {
  unsigned long numberOfChannels = 1;
  required unsigned long length;
  required float sampleRate;
};
1.4.4.1. 字典 AudioBufferOptions 成员

此字典成员的允许值受到约束。请参阅 createBuffer()

length, 类型为 unsigned long

缓冲区的长度,以样本帧为单位。请参阅 length 获取约束条件。

numberOfChannels, 类型为 unsigned long,默认为 1

缓冲区的通道数。请参阅 numberOfChannels 获取约束条件。

sampleRate, 类型为 float

缓冲区的采样率,以 Hz 为单位。请参阅 sampleRate 获取约束条件。

1.5. AudioNode 接口

AudioNodeAudioContext 的构建块。 该接口表示音频源、音频目标和中间处理模块。可以将这些模块连接在一起,以形成用于将音频渲染到音频硬件的 处理图。 每个节点可以具有 输入 和/或 输出源节点 没有输入,只有一个输出。 大多数处理节点(如滤波器)将有一个输入和一个输出。每种类型的 AudioNode 在其处理或合成音频的细节上有所不同。 但是一般来说,AudioNode 将处理其输入(如果有的话),并为其输出生成音频(如果有的话)。

每个输出都有一个或多个通道。通道的确切数量取决于特定 AudioNode 的细节。

一个输出可以连接到一个或多个 AudioNode 的输入,因此支持扇出。 一个输入最初没有连接,但可以从一个或多个 AudioNode 输出连接,因此支持扇入。 当调用 connect() 方法将 AudioNode 的输出连接到另一个 AudioNode 的输入时,我们称其为对该输入的 连接

每个 AudioNode输入 在任何给定时间都有特定数量的通道。此数量可能会根据对该输入的 连接 而发生变化。如果输入没有连接,则它有一个静音的通道。

对于每个 输入AudioNode 对该输入的所有连接进行混合。 有关规范要求和详细信息,请参阅 § 4 通道上混和下混

输入的处理和 AudioNode 的内部操作与 AudioContext 时间连续进行,无论节点是否连接输出,也无论这些输出是否最终到达 AudioContextAudioDestinationNode

AudioNode

在所有当前引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (旧版)12+IENone
Firefox for Android25+iOS SafariYesChrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile14+
[Exposed=Window]
interface AudioNode : EventTarget {
  AudioNode connect (AudioNode destinationNode,
                     optional unsigned long output = 0,
                     optional unsigned long input = 0);
  undefined connect (AudioParam destinationParam, optional unsigned long output = 0);
  undefined disconnect ();
  undefined disconnect (unsigned long output);
  undefined disconnect (AudioNode destinationNode);
  undefined disconnect (AudioNode destinationNode, unsigned long output);
  undefined disconnect (AudioNode destinationNode,
                        unsigned long output,
                        unsigned long input);
  undefined disconnect (AudioParam destinationParam);
  undefined disconnect (AudioParam destinationParam, unsigned long output);
  readonly attribute BaseAudioContext context;
  readonly attribute unsigned long numberOfInputs;
  readonly attribute unsigned long numberOfOutputs;
  attribute unsigned long channelCount;
  attribute ChannelCountMode channelCountMode;
  attribute ChannelInterpretation channelInterpretation;
};

1.5.1. AudioNode 创建

AudioNode 可以通过两种方式创建: 使用该特定接口的构造函数,或者使用 BaseAudioContextAudioContext 上的工厂方法

作为 AudioNode 构造函数的第一个参数传递的 BaseAudioContext 被称为要创建的 AudioNode关联 BaseAudioContext。同样地,当使用工厂方法时,关联的 BaseAudioContext 是调用此工厂方法的 BaseAudioContext

要使用工厂方法在 BaseAudioContext c 上创建特定类型 n 的新 AudioNode,执行以下步骤:
  1. noden 类型的新对象。

  2. option 为与此工厂方法关联的接口关联的类型为 关联选项对象 的字典。

  3. 对于传递给工厂方法的每个参数,将 option 上的同名字典成员设置为该参数的值。

  4. 使用 coption 作为参数调用 n 的构造函数。

  5. 返回 node

初始化AudioNode 继承的对象 o 意味着执行以下步骤,给定传递给此接口构造函数的参数 contextdict
  1. o 的关联 BaseAudioContext 设置为 context

  2. 将此特定接口的每个 AudioNode 部分中概述的 numberOfInputsnumberOfOutputschannelCountchannelCountModechannelInterpretation 的默认值设置为此具体接口。

  3. 对于传入的 dict 的每个成员,执行这些步骤,其中 k 为成员的键,v 为其值。 如果执行这些步骤时抛出任何异常,则中止迭代并将异常传播给算法(构造函数或工厂方法)的调用者。

    1. 如果 k 是此接口上 AudioParam 的名称, 则将此 value 属性设置为 v

    2. 否则,如果 k 是此接口上的属性名称,则将与此属性关联的对象设置为 v

工厂方法的 关联接口 是从该方法返回的对象的接口。 接口的 关联选项对象 是可以传递给此接口构造函数的选项对象。

AudioNodeEventTarget,如 [DOM] 中所述。这意味着可以向 AudioNode 分派事件,就像其他 EventTarget 接受事件的方式一样。

enum ChannelCountMode {
  "max",
  "clamped-max",
  "explicit"
};

ChannelCountMode 结合节点的 channelCountchannelInterpretation 值,用于确定控制如何将输入混合到节点的 计算的通道数。计算的通道数如下所示。 有关如何进行混合的更多信息,请参阅 § 4 通道上混和下混

枚举描述
"max" computedNumberOfChannels 是所有连接到输入的通道数的最大值。在此模式下,channelCount 被忽略。
"clamped-max" computedNumberOfChannels 按 "max" 确定, 然后被限制为给定 channelCount 的最大值。
"explicit" computedNumberOfChannels 是由 channelCount 指定的确切值。
enum ChannelInterpretation {
  "speakers",
  "discrete"
};
枚举描述
"speakers" 使用 上混合方程下混合方程。在通道数量不匹配任何这些基本扬声器布局的情况下,恢复到 "discrete"。
"discrete" 上混合通过填充通道直到它们用完,然后将剩余通道清零。下混合通过填充尽可能多的通道,然后丢弃剩余的通道。

1.5.2. AudioNode 尾部时间

AudioNode 可以具有 尾部时间。 这意味着即使 AudioNode 输入静音,输出也可能非静音。

如果 AudioNode 具有内部处理状态,过去的输入会影响未来的输出, 则它们的尾部时间非零。即使输入从非静音过渡到静音后,AudioNode 也可能在计算出的尾部时间内继续产生非静音输出。

1.5.3. AudioNode 生命周期

AudioNode 在以下任一条件成立时, 可以在 渲染量子 期间 主动处理

注意: 这考虑到了具有 尾部时间AudioNode

未处于 主动处理 状态的 AudioNode 输出单通道静音。

1.5.4. 属性

AudioNode/channelCount

在所有当前的引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (Legacy)12+IE
Firefox for Android25+iOS SafariChrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

channelCount, 类型为 unsigned long

channelCount 是在对节点的任何输入连接进行上混和下混时使用的通道数。默认值为 2,除非特定节点的值有特殊规定。此属性对没有输入的节点无效。如果此值设置为零或超过实现的最大通道数,必须抛出 NotSupportedError 异常。

此外,某些节点对通道数的可能值有额外的 channelCount 约束

AudioDestinationNode

行为取决于目标节点是 AudioContext 还是 OfflineAudioContext

AudioContext

通道数必须在 1 到 maxChannelCount 之间。对于任何试图设置超出此范围的计数,必须抛出 IndexSizeError 异常。

OfflineAudioContext

通道数无法更改。对于任何试图更改此值的操作,必须抛出 InvalidStateError 异常。

AudioWorkletNode

请参阅 § 1.32.3.3.2 使用 AudioWorkletNodeOptions 配置通道

ChannelMergerNode

通道数无法更改,对于任何试图更改此值的操作,必须抛出 InvalidStateError 异常。

ChannelSplitterNode

通道数无法更改,对于任何试图更改此值的操作,必须抛出 InvalidStateError 异常。

ConvolverNode

通道数不得大于 2,对于任何试图将其更改为大于 2 的值,必须抛出 NotSupportedError 异常。

DynamicsCompressorNode

通道数不得大于 2,对于任何试图将其更改为大于 2 的值,必须抛出 NotSupportedError 异常。

PannerNode

通道数不得大于 2,对于任何试图将其更改为大于 2 的值,必须抛出 NotSupportedError 异常。

ScriptProcessorNode

通道数无法更改,对于任何试图更改此值的操作,必须抛出 NotSupportedError 异常。

StereoPannerNode

通道数不得大于 2,对于任何试图将其更改为大于 2 的值,必须抛出 NotSupportedError 异常。

有关此属性的更多信息,请参阅 § 4 通道上混和下混

AudioNode/channelCountMode

在所有当前的引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (Legacy)12+IE
Firefox for Android25+iOS SafariChrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

channelCountMode, 类型为 ChannelCountMode

channelCountMode 决定在对节点的任何输入连接进行上混和下混时将如何计算通道数。默认值为 "max"。此属性对没有输入的节点无效。

此外,某些节点对通道计数模式的可能值有额外的 channelCountMode 约束

AudioDestinationNode

如果 AudioDestinationNodedestination 节点,且属于 OfflineAudioContext,则无法更改通道数模式。对于任何试图更改此值的操作,必须抛出 InvalidStateError 异常。

ChannelMergerNode

无法将通道计数模式从 "explicit" 更改,对于任何试图更改此值的操作,必须抛出 InvalidStateError 异常。

ChannelSplitterNode

无法将通道计数模式从 "explicit" 更改,对于任何试图更改此值的操作,必须抛出 InvalidStateError 异常。

ConvolverNode

无法将通道计数模式设置为 "max",对于任何试图将其设置为 "max" 的操作,必须抛出 NotSupportedError 异常。

DynamicsCompressorNode

无法将通道计数模式设置为 "max",对于任何试图将其设置为 "max" 的操作,必须抛出 NotSupportedError 异常。

PannerNode

无法将通道计数模式设置为 "max",对于任何试图将其设置为 "max" 的操作,必须抛出 NotSupportedError 异常。

ScriptProcessorNode

无法将通道计数模式从 "explicit" 更改,对于任何试图更改此值的操作,必须抛出 NotSupportedError 异常。

StereoPannerNode

无法将通道计数模式设置为 "max",对于任何试图将其设置为 "max" 的操作,必须抛出 NotSupportedError 异常。

有关此属性的更多信息,请参阅 § 4 通道上混和下混

AudioNode/channelInterpretation

在所有当前的引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (Legacy)12+IE
Firefox for Android25+iOS SafariChrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

channelInterpretation, 类型为 ChannelInterpretation

channelInterpretation 决定在对节点的任何输入连接进行上混和下混时,如何处理单个通道。默认值为 "speakers"。此属性对没有输入的节点无效。

此外,某些节点对通道解释的可能值有额外的 channelInterpretation 约束

ChannelSplitterNode

通道解释无法从 "discrete" 更改,对于任何试图更改此值的操作,必须抛出 InvalidStateError 异常。

有关此属性的更多信息,请参阅 § 4 通道上混和下混

AudioNode/context

在所有当前的引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (Legacy)12+IE
Firefox for Android25+iOS SafariChrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

context, 类型为 BaseAudioContext,只读

拥有此 AudioNodeBaseAudioContext

AudioNode/numberOfInputs

在所有当前的引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (Legacy)12+IE
Firefox for Android25+iOS SafariChrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

numberOfInputs, 类型为 unsigned long,只读

输入 AudioNode 的数量。对于 源节点,此值为 0。此属性对于许多 AudioNode 类型是预先确定的,但有些 AudioNode,如 ChannelMergerNodeAudioWorkletNode,则有可变的输入数。

AudioNode/numberOfOutputs

在所有当前的引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (Legacy)12+IE
Firefox for Android25+iOS SafariChrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

numberOfOutputs, 类型为 unsigned long,只读

输出 AudioNode 的数量。此属性对于某些 AudioNode 类型是预先确定的,但可能是可变的,例如对于 ChannelSplitterNodeAudioWorkletNode

1.5.5. 方法

AudioNode/connect

在所有当前的引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (Legacy)12+IE
Firefox for Android25+iOS SafariChrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

connect(destinationNode, output, input)

在一个特定节点的给定输出和另一个特定节点的给定输入之间只能有一个连接。具有相同终点的多个连接将被忽略。

例如:
nodeA.connect(nodeB);
nodeA.connect(nodeB);

将具有与以下相同的效果

nodeA.connect(nodeB);

此方法返回 destination AudioNode 对象。

AudioNode.connect(destinationNode, output, input) 方法的参数。
参数 类型 可为空 可选 描述
destinationNode destination 参数是 AudioNode 用于连接到。如果 destination 参数是通过另一个 AudioContext 创建的 AudioNode,则必须抛出 InvalidAccessError也就是说,AudioNode 不能在 AudioContext 之间共享。多个 AudioNode 可以连接到同一个 AudioNode,如在通道上混和下混部分中所述。
output unsigned long output 参数是一个索引,用于描述从哪个输出 AudioNode 进行连接。如果此参数超出范围,则必须抛出 IndexSizeError 异常。 可以通过多次调用 connect() 将 AudioNode 的输出连接到多个输入。因此,支持“扇出”。
input input 参数是一个索引,用于描述连接到目标的哪个输入 AudioNode如果此参数超出范围,则必须抛出 IndexSizeError 异常。 可以将一个 AudioNode 连接到另一个 AudioNode,这将创建一个循环AudioNode 可能会连接到另一个 AudioNode,然后它会连接回第一个 AudioNode 的输入或 AudioParam
返回类型: AudioNode

AudioNode/connect

在所有当前的引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (Legacy)12+IE
Firefox for Android25+iOS SafariChrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

connect(destinationParam, output)

AudioNode 连接到一个 AudioParam,使用a-rate 信号控制参数值。

可以通过多次调用 connect() 将 AudioNode 输出连接到多个 AudioParam。因此,支持“扇出”。

可以通过多次调用 connect() 将多个 AudioNode 输出连接到单个 AudioParam。因此,支持“扇入”。

一个 AudioParam 将从任何连接到它的 AudioNode 输出接收渲染的音频数据,并在不为单声道时通过下混将其转换为单声道,然后将其与其他此类输出混合,最后与 固有 参数值(value)混合,即在没有任何音频连接时 AudioParam 通常具有的值,包括为该参数计划的任何时间轴更改。

下混为单声道等同于 AudioNode 下混,其中channelCount=1,channelCountMode = "explicit",并且channelInterpretation = "speakers"。

在一个特定节点的给定输出和一个特定 AudioParam 之间只能有一个连接。具有相同终点的多个连接将被忽略。

例如:
nodeA.connect(param);
nodeA.connect(param);

将具有与以下相同的效果

nodeA.connect(param);
AudioNode.connect(destinationParam, output) 方法的参数。
参数 类型 可为空 可选 描述
destinationParam AudioParam destination 参数是 AudioParam 用于连接到。此方法不返回 destination AudioParam 对象。如果 destinationParam 属于一个 AudioNode,并且属于一个不同于 BaseAudioContextBaseAudioContext,则必须抛出 InvalidAccessError
output unsigned long output 参数是一个索引,用于描述从哪个输出 AudioNode 进行连接。如果 参数 超出范围,则必须抛出 IndexSizeError 异常。
返回类型: undefined

AudioNode/disconnect

在所有当前的引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (Legacy)12+IE
Firefox for Android25+iOS SafariChrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

disconnect()

断开所有与 AudioNode 的外部连接。

无参数。
返回类型: undefined
disconnect(output)

断开 AudioNode 的单个输出与其他任何 AudioNodeAudioParam 对象的连接。

AudioNode.disconnect(output) 方法的参数。
参数 类型 可为空 可选 描述
output unsigned long 此参数是一个索引,用于描述从哪个输出 AudioNode 进行断开。它会断开给定输出的所有外部连接。如果此参数超出范围,则必须抛出 IndexSizeError 异常。
返回类型: undefined
disconnect(destinationNode)

断开 AudioNode 的所有输出与特定 AudioNode 的连接。

AudioNode.disconnect(destinationNode) 方法的参数。
参数 类型 可为空 可选 描述
destinationNode 此参数是 destinationNode 是要断开的 AudioNode。它会断开给定的 destinationNode 的所有外部连接。如果没有连接到 destinationNode,则必须抛出 InvalidAccessError 异常。
返回类型: undefined
disconnect(destinationNode, output)

断开 AudioNode 的一个特定输出与某个目标 AudioNode 的所有输入的连接。

AudioNode.disconnect(destinationNode, output) 方法的参数。
参数 类型 可为空 可选 描述
destinationNode 此参数是 destinationNode 是要断开的 AudioNode如果没有连接到给定输出的 destinationNode,则必须抛出 InvalidAccessError 异常。
output unsigned long 此参数是一个索引,用于描述从哪个输出 AudioNode 进行断开。如果此参数超出范围,则必须抛出 IndexSizeError 异常。
返回类型: undefined
disconnect(destinationNode, output, input)

断开 AudioNode 的一个特定输出与某个目标 AudioNode 的一个特定输入的连接。

AudioNode.disconnect(destinationNode, output, input) 方法的参数。
参数 类型 可为空 可选 描述
destinationNode 此参数是 destinationNode 是要断开的 AudioNode如果没有从给定输出到给定输入的 destinationNode 的连接,则必须抛出 InvalidAccessError 异常。
output unsigned long 此参数是一个索引,用于描述从哪个输出 AudioNode 进行断开。如果此参数超出范围,则必须抛出 IndexSizeError 异常。
input 此参数是一个索引,用于描述连接到目标的哪个输入 AudioNode 进行断开。如果此参数超出范围,则必须抛出 IndexSizeError 异常。
返回类型: undefined
disconnect(destinationParam)

断开 AudioNode 的所有输出与特定 AudioParam 的连接。当此操作生效时,此 AudioNode 对计算出的参数值的贡献为 0。此操作不会影响固有的参数值。

AudioNode.disconnect(destinationParam) 方法的参数。
参数 类型 可为空 可选 描述
destinationParam AudioParam 此参数是 destinationParam 是要断开的 AudioParam如果没有连接到 destinationParam,则必须抛出 InvalidAccessError 异常。
返回类型: undefined
disconnect(destinationParam, output)

断开 AudioNode 的一个特定输出与特定 AudioParam 的连接。当此操作生效时,此 AudioNode 对计算出的参数值的贡献为 0。此操作不会影响固有的参数值。

AudioNode.disconnect(destinationParam, output) 方法的参数。
参数 类型 可为空 可选 描述
destinationParam AudioParam 此参数是 destinationParam 是要断开的 AudioParam如果没有连接到 destinationParam,则必须抛出 InvalidAccessError 异常。
output unsigned long 此参数是一个索引,用于描述从哪个输出 AudioNode 进行断开。如果 参数 超出范围,则必须抛出 IndexSizeError 异常。
返回类型: undefined

1.5.6. AudioNodeOptions

这指定了在构建所有 AudioNode 时可使用的选项。所有成员都是可选的。然而,每个节点使用的具体值取决于实际的节点。

AudioNodeOptions

Firefox53+Safari?Chrome55+
Opera42+Edge79+
Edge (Legacy)NoneIENone
Firefox for Android53+iOS Safari?Chrome for Android55+Android WebView55+Samsung Internet6.0+Opera Mobile42+
dictionary AudioNodeOptions {
  unsigned long channelCount;
  ChannelCountMode channelCountMode;
  ChannelInterpretation channelInterpretation;
};
1.5.6.1. 字典 AudioNodeOptions 成员
channelCount, 类型为 unsigned long

channelCount 属性的所需通道数。

channelCountMode, 类型为 ChannelCountMode

channelCountMode 属性的所需模式。

channelInterpretation, 类型为 ChannelInterpretation

channelInterpretation 属性的所需模式。

1.6. AudioParam 接口

AudioParam

在所有当前引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (旧版)12+IE
Firefox for Android25+iOS SafariChrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

AudioParam 控制AudioNode的某个具体功能,如音量。 可以使用 value 属性立即将参数设置为特定值,也可以调度参数值的变化 以在非常精确的时间点发生(在 AudioContextcurrentTime 属性的坐标系中),用于包络、音量渐变、LFO、滤波器扫描、粒子窗口等。 通过这种方式,可以在任何 AudioParam 上 设置任意基于时间轴的自动化曲线。此外,来自 AudioNode 的 输出的音频信号可以连接到 AudioParam, 并与内在参数值相加。

一些合成和处理 AudioNode 具有 AudioParam 作为属性,其值必须基于每个音频样本进行考虑。 对于其他 AudioParam, 样本精度并不重要,值的变化可以更粗略地采样。每个单独的 AudioParam 将指定它是一个 a-rate 参数, 这意味着其值必须基于每个音频样本进行考虑,或者它是一个 k-rate 参数。

实现必须使用块处理,每个 AudioNode 处理一个 render quantum

对于每个 render quantumk-rate 参数的值必须在 第一个样本帧采样时确定,并且该值必须用于整个块。a-rate 参数必须为块的每个样本帧采样。 根据 AudioParam 的不同, 可以通过将 automationRate 属性设置为 "a-rate" 或 "k-rate" 来控制其速率。 详见各个 AudioParam 的描述。

每个 AudioParam 包含 minValuemaxValue 属性,这些属性共同形成参数的 简单标称范围。 实际上,参数的值被夹在范围 \([\mathrm{minValue}, \mathrm{maxValue}]\) 之间。 详见 § 1.6.3 值的计算

对于许多 AudioParamminValuemaxValue 的设定目的是达到最大可能范围。在这种情况下,maxValue 应设置为 most-positive-single-float 值,即 3.4028235e38。 (然而,在只支持 IEEE-754 双精度浮点值的 JavaScript 中,必须写为 3.4028234663852886e38。) 同样,minValue 应设置为 most-negative-single-float 值,即 most-positive-single-float 的相反数:-3.4028235e38。 (同样,这在 JavaScript 中必须写为 -3.4028234663852886e38。)

AudioParam 维护一个零个或多个 自动化事件 列表。 每个自动化事件 指定在特定时间范围内相对于 自动化事件时间 的参数值变化, 该时间位于 AudioContextcurrentTime 属性的时间坐标系中。 自动化事件列表按自动化事件时间升序维护。

给定自动化事件的行为取决于 AudioContext 的 当前时间,以及此事件和列表中相邻事件的自动化事件时间。 以下 自动化方法 通过向事件列表中添加特定类型的新事件来更改事件列表:

调用这些方法时将适用以下规则:

注意: AudioParam 属性是只读的,除了 value 属性除外。

可以通过将 AudioParam 的自动化速率设置为 automationRate 属性来选择。 但是,某些 AudioParam 对自动化速率的更改有限制。

enum AutomationRate {
  "a-rate",
  "k-rate"
};
枚举描述
"a-rate" AudioParam 设置为 a-rate 处理。
"k-rate" AudioParam 设置为 k-rate 处理。

每个 AudioParam 有一个内部槽 [[current value]], 初始设置为 AudioParamdefaultValue

[Exposed=Window]
interface AudioParam {
  attribute float value;
  attribute AutomationRate automationRate;
  readonly attribute float defaultValue;
  readonly attribute float minValue;
  readonly attribute float maxValue;
  AudioParam setValueAtTime (float value, double startTime);
  AudioParam linearRampToValueAtTime (float value, double endTime);
  AudioParam exponentialRampToValueAtTime (float value, double endTime);
  AudioParam setTargetAtTime (float target, double startTime, float timeConstant);
  AudioParam setValueCurveAtTime (sequence<float> values,
                                  double startTime,
                                  double duration);
  AudioParam cancelScheduledValues (double cancelTime);
  AudioParam cancelAndHoldAtTime (double cancelTime);
};

1.6.1. 属性

automationRate, 类型为 AutomationRate

AudioParam 的自动化速率。 默认值取决于实际的 AudioParam; 参见各个 AudioParam 的说明以了解默认值。

某些节点有以下附加的 自动化速率约束

AudioBufferSourceNode

AudioParamplaybackRatedetune 必须为 "k-rate"。 如果速率更改为 "a-rate", 必须抛出 InvalidStateError 异常

DynamicsCompressorNode

AudioParamthresholdkneeratioattack、 和 release 必须为 "k-rate"。 如果速率更改为 "a-rate", 必须抛出 InvalidStateError 异常

PannerNode

如果 panningModel 为 "HRTF", 则对 AudioParam 的任何 PannerNode 设置 automationRate 将被忽略。 同样,对 AudioParam 的任何 AudioListener 设置 automationRate 也将被忽略。在这种情况下,AudioParam 的行为就像将 automationRate 设置为 "k-rate"。

AudioParam/defaultValue

在所有当前引擎中均可用。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (旧版)12+IE
Firefox for Android25+iOS SafariChrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

defaultValue, 类型为 float,只读

value 属性的初始值。

AudioParam/maxValue

在所有当前引擎中均可用。

Firefox53+Safari6+Chrome52+
Opera39+Edge79+
Edge (旧版)IE
Firefox for Android53+iOS SafariChrome for Android52+Android WebView52+Samsung Internet6.0+Opera Mobile41+

maxValue, 类型为 float,只读

参数可以取的名义最大值。与 minValue 一起,形成该参数的 名义范围

AudioParam/minValue

在所有当前引擎中均可用。

Firefox53+Safari6+Chrome52+
Opera39+Edge79+
Edge (旧版)IE
Firefox for Android53+iOS SafariChrome for Android52+Android WebView52+Samsung Internet6.0+Opera Mobile41+

minValue, 类型为 float,只读

参数可以取的名义最小值。与 maxValue 一起,形成该参数的 名义范围

AudioParam/value

在所有当前引擎中均可用。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (旧版)12+IE
Firefox for Android25+iOS SafariChrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

value, 类型为 float

参数的浮点值。此属性初始化为 defaultValue

获取此属性返回 [[current value]] 槽的内容。参见 § 1.6.3 值的计算 了解返回值的算法。

设置此属性的效果是将请求的值分配给 [[current value]] 槽,并调用 setValueAtTime() 方法,使用当前 AudioContextcurrentTime[[current value]]。 由 setValueAtTime() 抛出的任何异常也会通过设置此属性而抛出。

1.6.2. 方法

AudioParam/cancelAndHoldAtTime

仅在一个当前引擎中可用。

FirefoxSafariChrome57+
Opera44+Edge79+
Edge (旧版)IE
Firefox for AndroidiOS SafariChrome for Android57+Android WebView57+Samsung Internet7.0+Opera Mobile43+

cancelAndHoldAtTime(cancelTime)

此方法类似于 cancelScheduledValues() ,它取消所有 时间大于或等于 cancelTime 的预定参数更改。然而,此外,在 cancelTime 时发生的自动化值 会传播到所有未来的时间,直到引入其他自动化事件。

当自动化正在运行并且可以在调用 cancelAndHoldAtTime() 后以及 cancelTime 到达之前的任何时间引入时,时间线的行为是相当复杂的。因此,cancelAndHoldAtTime() 的行为在以下算法中进行了指定。

设 \(t_c\) 为 cancelTime 的值。然后
  1. 设 \(E_1\) 为在时间 \(t_1\) 处的事件(如果有),其中 \(t_1\) 是满足 \(t_1 \le t_c\) 的最大数。

  2. 设 \(E_2\) 为在时间 \(t_2\) 处的事件(如果有),其中 \(t_2\) 是满足 \(t_c \lt t_2\) 的最小数。

  3. 如果存在 \(E_2\):

    1. 如果 \(E_2\) 是线性或指数递增,

      1. 将 \(E_2\) 重写为以 \(t_c\) 结束的同类递增,结束值为原始递增在时间 \(t_c\) 的值。在此时间调用 cancelAndHoldAtTime 时,调用 linearRampToValueAtTime 的图形表示。

      2. 转到步骤 5。

    2. 否则,转到步骤 4。

  4. 如果存在 \(E_1\):

    1. 如果 \(E_1\) 是 setTarget 事件,

      1. 隐式插入一个 setValueAtTime 事件,时间为 \(t_c\),值为 setTarget 在时间 \(t_c\) 的值。在此时间调用 cancelAndHoldAtTime 时,调用 setTargetAtTime 的图形表示

      2. 转到步骤 5。

    2. 如果 \(E_1\) 是 setValueCurve,开始时间为 \(t_3\) 且持续时间为 \(d\)

      1. 如果 \(t_c \gt t_3 + d\),转到步骤 5。

      2. 否则,

        1. 有效地将此事件替换为持续时间为 \(t_c-t_3\) 的 setValueCurve 事件。然而,这不是一个真正的替换;此自动化必须注意生成与原始相同的输出,而不是使用不同的持续时间计算的输出。(这会导致以略微不同的方式对值曲线进行采样,从而产生不同的结果。)在此时间调用 cancelAndHoldAtTime 时,调用 setValueCurve 的图形表示

        2. 转到步骤 5。

  5. 移除所有时间大于 \(t_c\) 的事件。

如果没有添加事件,那么在调用 cancelAndHoldAtTime() 之后的自动化值 是原始时间线在时间 \(t_c\) 时会具有的常量值。

AudioParam.cancelAndHoldAtTime() 方法的参数。
参数 类型 可为 null 可选 描述
cancelTime double 取消先前安排的参数更改的时间。它是在与 AudioContextcurrentTime 属性相同的时间坐标系统中的时间。如果 cancelTime 为负或不是有限数,则必须抛出 RangeError 异常。 如果 cancelTime 小于 currentTime, 则将其限制为 currentTime
返回类型: AudioParam

AudioParam/cancelScheduledValues

在所有当前引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (旧版)12+IE
Firefox for Android25+iOS SafariChrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

cancelScheduledValues(cancelTime)

取消所有时间大于或等于 cancelTime 的预定参数更改。取消预定 的参数更改意味着将预定的事件从事件列表中移除。任何自动化事件时间小于 自动化事件时间 且小于 cancelTime 的 也会被取消,并且这种取消可能会导致不连续性,因为原始值(在这种自动化之前)会立即恢复。任何由 cancelAndHoldAtTime() 计划的保持值 如果保持时间发生在 cancelTime 之后,也会被移除。

对于 setValueCurveAtTime(), 设 \(T_0\) 和 \(T_D\) 为该事件的相应 startTimeduration 。然后,如果 cancelTime 在 \([T_0, T_0 + T_D]\) 范围内,则从时间线中移除该事件。

AudioParam.cancelScheduledValues() 方法的参数。
参数 类型 可为 null 可选 描述
cancelTime double 取消先前安排的参数更改的时间。它是在与 AudioContextcurrentTime 属性相同的时间坐标系统中的时间。如果 cancelTime 为负或不是有限数,则必须抛出 RangeError 异常。 如果 cancelTime 小于 currentTime, 则将其限制为 currentTime
返回类型: AudioParam

AudioParam/exponentialRampToValueAtTime

FirefoxSafari6+Chrome14+
Opera15+Edge79+
Edge (旧版)12+IE
Firefox for AndroidiOS SafariChrome for AndroidAndroid WebView37+Samsung Internet1.0+Opera Mobile14+

exponentialRampToValueAtTime(value, endTime)

安排参数值从先前安排的参数值逐步指数变化到给定值。

在时间间隔 \(T_0 \leq t < T_1\) 内的值 (其中 \(T_0\) 是前一个事件的时间,\(T_1\) 是此方法传入的 endTime 参数) 将计算为:

$$
  v(t) = V_0 \left(\frac{V_1}{V_0}\right)^\frac{t - T_0}{T_1 - T_0}
$$

其中 \(V_0\) 是时间 \(T_0\) 时的值,\(V_1\) 是此方法传入的 value 参数值。如果 \(V_0\) 和 \(V_1\) 具有相反的符号或 \(V_0\) 为零, 则 \(v(t) = V_0\) 在 \(T_0 \le t \lt T_1\) 时。

这也意味着不能实现到 0 的指数递增。可以使用 setTargetAtTime() 选择合适的时间常数来实现一个很好的近似。

如果在此 ExponentialRampToValue 事件之后没有更多事件,则在 \(t \geq T_1\) 时, \(v(t) = V_1\)。

如果在此事件之前没有事件,则指数递增行为就像调用 setValueAtTime(value, currentTime) ,其中 value 为属性的当前值,currentTime 为上下文的 currentTime ,在调用 exponentialRampToValueAtTime() 时。

如果前一个事件是 SetTarget 事件,\(T_0\) 和 \(V_0\) 是从 SetTarget 自动化的当前时间和当前值中选择的。也就是说,如果 SetTarget 事件尚未开始,\(T_0\) 是事件的开始 时间,\(V_0\) 是 SetTarget 事件开始前的值。在这种情况下,ExponentialRampToValue 事件有效地替换了 SetTarget 事件。如果 SetTarget 事件已经 开始,\(T_0\) 是当前的上下文时间, \(V_0\) 是 \(T_0\) 时的当前 SetTarget 自动化值。在两种情况下,自动化曲线都是连续的。

AudioParam.exponentialRampToValueAtTime() 方法的参数。
参数 类型 可为 null 可选 描述
value float 参数将在给定时间内指数递增到的值。如果此值等于 0,则必须抛出 RangeError 异常。
endTime double 在与 AudioContextcurrentTime 属性相同的时间坐标系统中,指数递增结束的时间。如果 RangeError 异常必须抛出如果 endTime 为负或不是有限数。 如果 endTime 小于 currentTime, 则将其限制为 currentTime
返回类型: AudioParam

AudioParam/linearRampToValueAtTime

FirefoxSafari6+Chrome14+
Opera15+Edge79+
Edge (旧版)12+IE
Firefox for AndroidiOS SafariChrome for AndroidAndroid WebView37+Samsung Internet1.0+Opera Mobile14+

linearRampToValueAtTime(value, endTime)

安排参数值从先前安排的参数值逐步线性变化到给定值。

在时间间隔 \(T_0 \leq t < T_1\) 内的值 (其中 \(T_0\) 是前一个事件的时间,\(T_1\) 是此方法传入的 endTime 参数) 将计算为:

$$
  v(t) = V_0 + (V_1 - V_0) \frac{t - T_0}{T_1 - T_0}
$$

其中 \(V_0\) 是时间 \(T_0\) 时的值,\(V_1\) 是此方法传入的 value 参数值。

如果在此 LinearRampToValue 事件之后没有更多事件,则在 \(t \geq T_1\) 时, \(v(t) = V_1\)。

如果在此事件之前没有事件,则线性递增行为就像调用 setValueAtTime(value, currentTime) ,其中 value 为属性的当前值,currentTime 为上下文的 currentTime ,在调用 linearRampToValueAtTime() 时。

如果前一个事件是 SetTarget 事件,\(T_0\) 和 \(V_0\) 是从 SetTarget 自动化的当前时间和当前值中选择的。也就是说,如果 SetTarget 事件尚未开始,\(T_0\) 是事件的开始 时间,\(V_0\) 是 SetTarget 事件开始前的值。在这种情况下,LinearRampToValue 事件有效地替换了 SetTarget 事件。如果 SetTarget 事件已经 开始,\(T_0\) 是当前的上下文时间, \(V_0\) 是 \(T_0\) 时的当前 SetTarget 自动化值。在两种情况下,自动化曲线都是连续的。

AudioParam.linearRampToValueAtTime() 方法的参数。
参数 类型 可为 null 可选 描述
value float 参数将在给定时间内线性递增到的值。
endTime double 在与 AudioContextcurrentTime 属性相同的时间坐标系统中,自动化结束的时间。如果 RangeError 异常必须抛出如果 endTime 为负或不是有限数。 如果 endTime 小于 currentTime, 则将其限制为 currentTime
返回类型: AudioParam

AudioParam/setTargetAtTime

在所有当前引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (旧版)12+IE
Firefox for Android25+iOS SafariChrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

setTargetAtTime(target, startTime, timeConstant)

在给定时间以给定时间常数的速率开始指数接近目标值。此方法除了其他用途外,对于实现 ADSR 包络的“衰减”和“释放”部分非常有用。请注意,参数值不会在给定时间立即更改为目标值,而是逐渐更改为目标值。

在时间间隔:\(T_0 \leq t\),其中 \(T_0\) 是 startTime 参数:

$$
  v(t) = V_1 + (V_0 - V_1)\, e^{-\left(\frac{t - T_0}{\tau}\right)}
$$

其中 \(V_0\) 是时间 \(T_0\) 的初始值([[current value]] 属性),\(V_1\) 等于 target 参数值,以及 \(\tau\) 是 timeConstant 参数。

如果此事件后面跟有 LinearRampToValueExponentialRampToValue 事件, 则行为在 linearRampToValueAtTime()exponentialRampToValueAtTime()中描述, 分别。对于所有其他事件,SetTarget 事件在下一个事件的时间结束。

AudioParam.setTargetAtTime() 方法的参数。
参数 类型 可为 null 可选 描述
target float 参数将在给定时间开始变更为的值。
startTime double 在与 AudioContextcurrentTime 属性相同的时间坐标系统中,指数递增开始的时间。如果 RangeError 异常必须抛出如果 start 为负或不是有限数。 如果 startTime 小于 currentTime, 则将其限制为 currentTime
timeConstant float 一级滤波器(指数)逼近目标值的时间常数值。此值越大,过渡时间越长。如果此值为负,则必须抛出 RangeError 异常。 如果 timeConstant 为零,输出 值立即跳至最终值。更准确地说,timeConstant 是一级线性连续时不变系统在给定阶跃输入响应(从 0 到 1 值的转换)的情况下达到 \(1 - 1/e\) 值(约 63.2%)所需的时间。
返回类型: AudioParam

AudioParam/setValueAtTime

在所有当前引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (旧版)12+IE
Firefox for Android25+iOS SafariChrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

setValueAtTime(value, startTime)

安排参数值在给定时间发生更改。

如果此 SetValue 事件之后没有更多事件, 则在 \(t \geq T_0\) 时,\(v(t) = V\),其中 \(T_0\) 是 startTime 参数,\(V\) 是 value 参数。换句话说,该值将 保持不变。

如果此 SetValue 事件之后的下一个事件(时间为 \(T_1\))不是 LinearRampToValueExponentialRampToValue 类型的事件, 则对于 \(T_0 \leq t < T_1\):

$$
  v(t) = V
$$

换句话说,该值将在此时间间隔内保持不变,允许创建“阶跃”函数。

如果此 SetValue 事件之后的下一个事件是 LinearRampToValueExponentialRampToValue 类型的事件,则请参阅 linearRampToValueAtTime()exponentialRampToValueAtTime(), 分别。

AudioParam.setValueAtTime() 方法的参数。
参数 类型 可为 null 可选 描述
value float 参数将在给定时间变更到的值。
startTime double 在与 BaseAudioContextcurrentTime 属性相同的时间坐标系统中,参数更改为给定值的时间。如果 RangeError 异常必须抛出如果 startTime 为负或不是有限数。 如果 startTime 小于 currentTime, 则将其限制为 currentTime
返回类型: AudioParam

AudioParam/setValueCurveAtTime

在所有当前引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (旧版)12+IE
Firefox for Android25+iOS SafariChrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

setValueCurveAtTime(values, startTime, duration)

从给定时间开始并在给定持续时间内设置一组任意参数值。值的数量将根据所需的持续时间进行缩放。

设 \(T_0\) 为 startTime, \(T_D\) 为 duration, \(V\) 为 values 数组, \(N\) 为 values 数组的长度。然后, 在时间间隔 \(T_0 \le t < T_0 + T_D\) 内,令

$$
  \begin{align*} k &= \left\lfloor \frac{N - 1}{T_D}(t-T_0) \right\rfloor \\
  \end{align*}
$$

然后 \(v(t)\) 通过在 \(V[k]\) 和 \(V[k+1]\) 之间线性插值得到,

在曲线时间间隔结束后(\(t \ge T_0 + T_D\)), 该值将在最终曲线值处保持不变,直到 有另一个自动化事件(如果有的话)。

在 \(T_0 + T_D\) 时间隐式调用 setValueAtTime(), 值为 \(V[N-1]\),以便后续的自动化将 从 setValueCurveAtTime() 事件的末尾开始。

AudioParam.setValueCurveAtTime() 方法的参数。
参数 类型 可为 null 可选 描述
values sequence<float> 表示参数值曲线的 float 值序列。这些值将从给定时间开始并持续给定时间。调用此方法时,会为自动化目的创建曲线的内部副本。因此,随后修改传入数组的内容不会影响 AudioParam如果此属性是 sequence<float> 对象且 长度小于 2,则必须抛出 InvalidStateError 异常。
startTime double 在与 AudioContextcurrentTime 属性相同的时间坐标系统中,应用值曲线的开始时间。如果 RangeError 异常必须抛出如果 startTime 为负或不是有限数。 如果 startTime 小于 currentTime, 则将其限制为 currentTime
duration double startTime 参数开始计算值的时间(秒)。如果 RangeError 异常必须抛出如果 duration 不是严格为正数或不是有限数
返回类型: AudioParam

1.6.3. 值的计算

有两种不同类型的AudioParam简单参数复合参数简单参数(默认值)用于 自行计算AudioNode的最终音频输出。 复合参数AudioParam ,与其他AudioParam 一起计算出一个值,然后作为输入用于计算 AudioNode的输出。

计算值是 控制音频DSP的最终值,由音频渲染线程在每个渲染时间量子期间计算。

AudioParam值的计算包括两个部分:

这些值必须按以下方式计算:

  1. paramIntrinsicValue将在每次计算时计算, 该值要么是直接设置给value 属性的值,要么是从自动化事件中计算出的值。如果自动化事件在给定的时间范围内被移除,则paramIntrinsicValue值将保持不变,并停留在其先前的值,直到直接设置value 属性,或者在该时间范围内添加了自动化事件。

  2. 在此渲染量子的开始时,将[[current value]] 设置为paramIntrinsicValue的值。

  3. paramComputedValueparamIntrinsicValue值与输入AudioParam缓冲区的值的总和。如果总和为NaN,则用defaultValue替换该总和。

  4. 如果此AudioParam复合参数, 则使用其他AudioParam来计算其最终值。

  5. 计算值设置为paramComputedValue

标称范围计算值的有效范围的上下限值。对于简单参数计算值被限制在该参数的简单标称范围内。复合参数在从不同AudioParam 计算出最终值后,会被限制在其标称范围内。

使用自动化方法时,仍然会应用限制。 然而,自动化的运行就像没有任何限制一样。 只有当自动化值应用到输出时,才会按照上述规定进行限制。

例如,考虑一个节点 \(N\) 有一个 AudioParam \(p\) ,其标称范围为 \([0, 1]\),并具有以下自动化序列:
N.p.setValueAtTime(0, 0);
N.p.linearRampToValueAtTime(4, 1);
N.p.linearRampToValueAtTime(0, 2);

曲线的初始斜率为4,直到达到最大值1,此时输出保持不变。最后,在接近时间2时,曲线的斜率为-4。下图显示了没有剪裁时的预期行为(虚线)和由于剪裁到标称范围导致的AudioParam的实际预期行为(实线)。

AudioParam automation clipping to nominal
AudioParam自动化从标称范围剪裁的示例。

1.6.4. AudioParam 自动化示例

AudioParam automation
参数自动化示例。
const curveLength = 44100;const curve = new Float32Array(curveLength);for (const i = 0; i < curveLength; ++i)  curve[i] = Math.sin(Math.PI * i / curveLength);const t0 = 0;const t1 = 0.1;const t2 = 0.2;const t3 = 0.3;const t4 = 0.325;const t5 = 0.5;const t6 = 0.6;const t7 = 0.7;const t8 = 1.0;const timeConstant = 0.1;param.setValueAtTime(0.2, t0);param.setValueAtTime(0.3, t1);param.setValueAtTime(0.4, t2);param.linearRampToValueAtTime(1, t3);param.linearRampToValueAtTime(0.8, t4);param.setTargetAtTime(.5, t4, timeConstant);// 计算 setTargetAtTime 在 t5 时的值以确保后续的指数变化从正确的点开始// 以避免出现跳跃不连续性。从规范中,我们得到// v(t) = 0.5 + (0.8 - 0.5)*exp(-(t-t4)/timeConstant)// 因此 v(t5) = 0.5 + (0.8 - 0.5)*exp(-(t5-t4)/timeConstant)param.setValueAtTime(0.5 + (0.8 - 0.5)*Math.exp(-(t5 - t4)/timeConstant), t5);param.exponentialRampToValueAtTime(0.75, t6);param.exponentialRampToValueAtTime(0.05, t7);param.setValueCurveAtTime(curve, t7, t8 - t7);

1.7. AudioScheduledSourceNode 接口

AudioScheduledSourceNode

在所有当前引擎中可用。

Firefox53+Safari14+Chrome57+
Opera44+Edge79+
Edge (Legacy)不支持IE不支持
Android 版 Firefox53+iOS 版 Safari14+Android 版 Chrome57+Android WebView57+Samsung Internet7.0+Opera Mobile43+

此接口表示源节点的通用功能,例如 AudioBufferSourceNodeConstantSourceNodeOscillatorNode

在源开始播放(通过调用 start())之前, 源节点必须输出静音(0)。在源停止播放(通过调用 stop())后, 源节点必须输出静音(0)。

AudioScheduledSourceNode 不能直接实例化,而是通过源节点的具体接口进行扩展。

AudioScheduledSourceNode的关联BaseAudioContextcurrentTime大于等于AudioScheduledSourceNode设置的开始时间且小于它设置的停止时间时,称其为正在播放

AudioScheduledSourceNode在创建时带有一个内部布尔槽[[source started]],初始值为false。

[Exposed=Window]
interface AudioScheduledSourceNode : AudioNode {
  attribute EventHandler onended;
  undefined start(optional double when = 0);
  undefined stop(optional double when = 0);
};

1.7.1. 属性

AudioScheduledSourceNode/ended_event

在所有当前引擎中可用。

Firefox25+Safari7+Chrome30+
Opera17+Edge79+
Edge (Legacy)12+IE不支持
Android 版 Firefox25+iOS 版 Safari7+Android 版 Chrome30+Android WebView37+Samsung Internet2.0+Opera Mobile18+

AudioScheduledSourceNode/onended

在所有当前引擎中可用。

Firefox25+Safari7+Chrome30+
Opera17+Edge79+
Edge (Legacy)12+IE不支持
Android 版 Firefox25+iOS 版 Safari7+Android 版 Chrome30+Android WebView37+Samsung Internet2.0+Opera Mobile18+

onended类型为 EventHandler

用于设置 EventHandler(详见 HTML[HTML])属性,以处理为 AudioScheduledSourceNode 节点类型调度的 ended 事件。当源节点停止播放时(由具体节点决定),将向事件处理程序发送 Event 类型的事件(详见 HTML [HTML])。

对于所有 AudioScheduledSourceNode, 当到达由 stop() 确定的停止时间时,将调度 onended 事件。对于 AudioBufferSourceNode, 该事件也会在达到 duration 或播放完整个 buffer 时调度。

1.7.2. 方法

AudioScheduledSourceNode/start

在所有当前引擎中可用。

Firefox25+Safari6.1+Chrome24+
Opera15+Edge79+
Edge (Legacy)12+IE不支持
Android 版 Firefox25+iOS 版 Safari7+Android 版 Chrome25+Android WebView37+Samsung Internet1.5+Opera Mobile14+

start(when)

计划在准确时间播放声音。

当调用此方法时,执行以下步骤:
  1. 如果此 AudioScheduledSourceNode 内部 插槽 [[source started]] 为 true,则必须抛出 InvalidStateError 异常。

  2. 检查由于以下描述的参数约束而必须抛出的任何错误。如果在此步骤中抛出任何异常,则中止这些步骤。

  3. 将此 [[source started]] 内部插槽 设置为 true

  4. 排队控制消息 以启动 AudioScheduledSourceNode, 包括消息中的参数值。

  5. 仅当满足以下所有条件时,向相关的 AudioContext 发送 控制消息,以 启动渲染线程

    1. 上下文的 [[control thread state]] 为 "suspended"。

    2. 上下文被 允许启动

    3. [[suspended by user]] 标志为 false

    注意:这允许 start() 启动 本来不会被 允许启动AudioContext

AudioScheduledSourceNode.start(when) 方法的参数。
参数 类型 可为空 可选 描述
when double when 参数描述声音应开始播放的时间(以秒为单位)。它与 AudioContextcurrentTime 属性使用相同的时间坐标系统。当 AudioScheduledSourceNode 发出的信号依赖于声音的开始时间时,总是使用 when 的精确值,不会四舍五入到最近的采样帧。如果传入此值为 0 或此值小于 currentTime, 则声音将立即开始播放。如果 when 为负,则必须抛出 RangeError 异常。
返回类型: undefined

AudioScheduledSourceNode/stop

在所有当前引擎中可用。

Firefox25+Safari6.1+Chrome24+
Opera15+Edge79+
Edge (Legacy)12+IE不支持
Android 版 Firefox25+iOS 版 Safari7+Android 版 Chrome25+Android WebView37+Samsung Internet1.5+Opera Mobile14+

stop(when)

计划在准确时间停止播放声音。如果在已经调用后再次调用 stop,则只会应用最后一次调用;先前调用设置的停止时间不会被应用,除非缓冲区在任何后续调用之前已经停止。如果缓冲区已经停止,进一步调用 stop 将不起作用。如果在计划的开始时间之前到达停止时间,声音将不会播放。

当调用此方法时,执行以下步骤:
  1. 如果此 AudioScheduledSourceNode 内部插槽 [[source started]] 不为 true,则必须抛出 InvalidStateError 异常。

  2. 检查由于以下描述的参数约束而必须抛出的任何错误。

  3. 排队控制消息 以停止 AudioScheduledSourceNode, 包括消息中的参数值。

如果节点是 AudioBufferSourceNode, 运行一个 控制消息 以停止 AudioBufferSourceNode 意味着在 播放算法 中调用 handleStop() 函数。
AudioScheduledSourceNode.stop(when) 方法的参数。
参数 类型 可为空 可选 描述
when double when 参数描述声音应停止播放的时间(以秒为单位)。它与 AudioContextcurrentTime 属性使用相同的时间坐标系统。如果传入此值为 0 或此值小于 currentTime, 则声音将立即停止播放。如果 when 为负,则必须抛出 RangeError 异常
返回类型: undefined

1.8. The AnalyserNode Interface

This interface represents a node which is able to provide real-time frequency and time-domain analysis information. The audio stream will be passed un-processed from input to output.

Property Value Notes
numberOfInputs 1
numberOfOutputs 1 This output may be left unconnected.
channelCount 2
channelCountMode "max"
channelInterpretation "speakers"
tail-time No

AnalyserNode

在所有当前引擎中可用。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (Legacy)12+IE不支持
Android 版 Firefox25+iOS 版 Safari6+Android 版 Chrome18+Android WebView37+Samsung Internet1.0+Opera Mobile14+
[Exposed=Window]
interface AnalyserNode : AudioNode {
  constructor (BaseAudioContext context, optional AnalyserOptions options = {});
  undefined getFloatFrequencyData (Float32Array array);
  undefined getByteFrequencyData (Uint8Array array);
  undefined getFloatTimeDomainData (Float32Array array);
  undefined getByteTimeDomainData (Uint8Array array);
  attribute unsigned long fftSize;
  readonly attribute unsigned long frequencyBinCount;
  attribute double minDecibels;
  attribute double maxDecibels;
  attribute double smoothingTimeConstant;
};

1.8.1. Constructors

AnalyserNode/AnalyserNode

Firefox53+Safari不支持Chrome55+
Opera42+Edge79+
Edge (Legacy)不支持IE不支持
Android 版 Firefox53+iOS 版 Safari不支持Android 版 Chrome55+Android WebView55+Samsung Internet6.0+Opera Mobile42+

AnalyserNode(context, options)

当构造函数使用 BaseAudioContext c 和 一个选项对象 option 被调用时,用户代理必须用 contextoptions 作为参数初始化 AudioNode this

AnalyserNode.constructor() 方法的参数。
Parameter Type Nullable Optional Description
context BaseAudioContext 此新的 BaseAudioContext 将与之 关联
options AnalyserOptions AnalyserNode 的可选初始参数值。

1.8.2. Attributes

AnalyserNode/fftSize

在所有当前引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (Legacy)12+IE不支持
Android 版 Firefox25+iOS 版 Safari6+Android 版 Chrome18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

fftSize, 类型为 unsigned long

用于频域分析的 FFT 大小(以样本帧为单位)。此值必须是 32 到 32768 范围内的 2 的幂,否则必须抛出 IndexSizeError 异常。默认值为 2048。请注意,较大的 FFT 大小可能会导致计算成本增加。

如果 fftSize 更改为不同的值,则与频率数据的平滑处理相关的所有状态(用于 getByteFrequencyData()getFloatFrequencyData()) 将被重置。即用于 随时间平滑处理前一个数据块\(\hat{X}_{-1}[k]\) 将为所有 \(k\) 设置为 0。

请注意,增加 fftSize 意味着必须扩展 当前时域数据,以包括之前未包含的过去帧。这意味着 AnalyserNode 实际上必须保留最后的 32768 个样本帧,并且 当前时域数据 是从中提取的最近的 fftSize 个样本帧。

AnalyserNode/frequencyBinCount

在所有当前引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (Legacy)12+IE不支持
Android 版 Firefox25+iOS 版 Safari6+Android 版 Chrome18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

frequencyBinCount, 类型为 unsigned long, 只读

FFT 大小的一半。

AnalyserNode/maxDecibels

在所有当前引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (Legacy)12+IE不支持
Android 版 Firefox25+iOS 版 Safari6+Android 版 Chrome18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

maxDecibels, 类型为 double

maxDecibels 是用于转换为无符号字节值的 FFT 分析数据的缩放范围内的最大功率值。默认值为 -30。如果将此属性的值设置为小于或等于 minDecibels 的值,必须抛出 IndexSizeError 异常。

AnalyserNode/minDecibels

在所有当前引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (Legacy)12+IE不支持
Android 版 Firefox25+iOS 版 Safari6+Android 版 Chrome18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

minDecibels, 类型为 double

minDecibels 是用于转换为无符号字节值的 FFT 分析数据的缩放范围内的最小功率值。默认值为 -100。如果将此属性的值设置为大于或等于 maxDecibels 的值,必须抛出 IndexSizeError 异常。

AnalyserNode/smoothingTimeConstant

在所有当前引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (Legacy)12+IE不支持
Android 版 Firefox25+iOS 版 Safari6+Android 版 Chrome18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

smoothingTimeConstant, 类型为 double

从 0 -> 1 的值,其中 0 表示与最后一个分析帧没有时间平均。默认值为 0.8。如果将此属性的值设置为小于 0 或大于 1,必须抛出 IndexSizeError 异常。

1.8.3. 方法

AnalyserNode/getByteFrequencyData

在所有当前引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (Legacy)12+IE不支持
Android 版 Firefox25+iOS 版 Safari6+Android 版 Chrome18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

getByteFrequencyData(array)

获取传入的 Uint8Array 引用,并将当前的频率数据复制到其中。如果数组中的元素少于 frequencyBinCount,多余的元素将被丢弃。如果数组中的元素多于 frequencyBinCount,多余的元素将被忽略。计算频率数据时会使用最近的 fftSize 帧。

如果在同一个渲染量子中再次调用 getByteFrequencyData()getFloatFrequencyData(),则不会更新当前频率数据,而是返回之前计算的数据。

Y[k] 表示为当前的频率数据,则字节值 b[k] 的计算方式如下:

$$
b[k] = \left\lfloor
  \frac{255}{\mbox{dB}_{max} - \mbox{dB}_{min}}
  \left(Y[k] - \mbox{dB}_{min}\right)
\right\rfloor
$$

如果 b[k] 超出了 0 到 255 的范围,则 b[k] 将被裁剪到该范围内。

AnalyserNode.getByteFrequencyData() 方法的参数。
参数 类型 可空 可选 描述
array Uint8Array 此参数用于存储频域分析数据。
返回类型: undefined

AnalyserNode/getByteTimeDomainData

在所有当前引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (Legacy)12+IE不支持
Android 版 Firefox25+iOS 版 Safari6+Android 版 Chrome18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

getByteTimeDomainData(array)

获取传入的 Uint8Array 引用,并将当前的时域数据(波形数据)复制到其中。如果数组中的元素少于 fftSize,多余的元素将被丢弃。如果数组中的元素多于 fftSize,多余的元素将被忽略。计算波形数据时会使用最近的 fftSize 帧。

x[k] 表示为时域数据,则字节值 b[k] 的计算方式如下:

$$
b[k] = \left\lfloor 128(1 + x[k]) \right\rfloor.
$$

如果 b[k] 超出了 0 到 255 的范围,则 b[k] 将被裁剪到该范围内。

AnalyserNode.getByteTimeDomainData() 方法的参数。
参数 类型 可空 可选 描述
array Uint8Array 此参数用于存储时域样本数据。
返回类型: undefined

AnalyserNode/getFloatFrequencyData

在所有当前引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (Legacy)12+IE不支持
Android 版 Firefox25+iOS 版 Safari6+Android 版 Chrome18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

getFloatFrequencyData(array)

获取传入的 Float32Array 引用,并将当前的频率数据复制到其中。如果数组中的元素少于 frequencyBinCount,多余的元素将被丢弃。如果数组中的元素多于 frequencyBinCount,多余的元素将被忽略。计算频率数据时会使用最近的 fftSize 帧。

如果在同一个渲染量子中再次调用 getFloatFrequencyData()getByteFrequencyData(),则不会更新当前频率数据,而是返回之前计算的数据。

频率数据以 dB 为单位。

AnalyserNode.getFloatFrequencyData() 方法的参数。
参数 类型 可空 可选 描述
array Float32Array 此参数用于存储频域分析数据。
返回类型: undefined

AnalyserNode/getFloatTimeDomainData

Firefox25+SafariNoneChrome14+
Opera15+Edge79+
Edge (Legacy)12+IE不支持
Android 版 Firefox25+iOS 版 SafariNoneAndroid 版 Chrome18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

getFloatTimeDomainData(array)

获取传入的 Float32Array 引用,并将当前的时域数据(波形数据)复制到其中。如果数组中的元素少于 fftSize,多余的元素将被丢弃。如果数组中的元素多于 fftSize,多余的元素将被忽略。计算波形数据时会使用最近的 fftSize 帧(在降混后返回)。

AnalyserNode.getFloatTimeDomainData() 方法的参数。
参数 类型 可空 可选 描述
array Float32Array 此参数用于存储时域样本数据。
返回类型: undefined

1.8.4. AnalyserOptions

此部分指定在构造 AnalyserNode 时使用的选项。 所有成员都是可选的;如果未指定,则使用正常的默认值来构造节点。

dictionary AnalyserOptions : AudioNodeOptions {
  unsigned long fftSize = 2048;
  double maxDecibels = -30;
  double minDecibels = -100;
  double smoothingTimeConstant = 0.8;
};
1.8.4.1. 字典 AnalyserOptions 成员
fftSize, 类型为 unsigned long, 默认值为 2048

用于频域分析的 FFT 的期望初始大小。

maxDecibels, 类型为 double, 默认值为 -30

用于 FFT 分析的期望初始最大功率(以 dB 为单位)。

minDecibels, 类型为 double, 默认值为 -100

用于 FFT 分析的期望初始最小功率(以 dB 为单位)。

smoothingTimeConstant, 类型为 double, 默认值为 0.8

用于 FFT 分析的期望初始平滑常数。

1.8.5. 时域下混

当计算当前时域数据时, 输入信号必须如同channelCount 为 1,channelCountMode 为 "max" 和 channelInterpretation 为 "speakers" 一样混合为单声道。这与AnalyserNode 本身的设置无关。最近的fftSize 帧用于 下混操作。

1.8.6. FFT 窗口化和时间上的平滑

当计算当前频率数据时,需执行以下操作:

  1. 计算当前时域数据

  2. 对时域输入数据应用 Blackman 窗口

  3. 对加窗后的时域输入数据应用傅里叶变换,以获得实部和虚部 频率数据。

  4. 时间上的平滑 频域数据。

  5. 转换为 dB

在以下内容中,令 \(N\) 为该 fftSize 属性的值 AnalyserNode

应用 Blackman 窗口 包括 对输入时域数据进行以下操作。令 \(x[n]\) 对于 \(n = 0, \ldots, N - 1\) 为时域数据。Blackman 窗口定义如下
$$
\begin{align*}
\alpha &= \mbox{0.16} \\ a_0 &= \frac{1-\alpha}{2} \\
a_1 &= \frac{1}{2} \\
a_2 &= \frac{\alpha}{2} \\
w[n] &= a_0 - a_1 \cos\frac{2\pi n}{N} + a_2 \cos\frac{4\pi n}{N}, \mbox{ 对于 } n = 0, \ldots, N - 1
\end{align*}
$$

加窗信号 \(\hat{x}[n]\) 为

$$
\hat{x}[n] = x[n] w[n], \mbox{ 对于 } n = 0, \ldots, N - 1
$$
应用傅里叶变换 包括按以下方式计算傅里叶变换。 令 \(X[k]\) 为复数频域数据, \(\hat{x}[n]\) 为上面计算的加窗时域数据。 然后
$$
X[k] = \frac{1}{N} \sum_{n = 0}^{N - 1} \hat{x}[n]\, W^{-kn}_{N}
$$

对于 \(k = 0, \dots, N/2-1\) ,其中 \(W_N = e^{2\pi i/N}\)。

时间上的平滑 频率 数据包括以下操作:

然后平滑值 \(\hat{X}[k]\) 的计算公式为

$$
\hat{X}[k] = \tau\, \hat{X}_{-1}[k] + (1 - \tau)\, \left|X[k]\right|
$$

对于 \(k = 0, \ldots, N - 1\)。

转换为 dB 包括以下操作,其中 \(\hat{X}[k]\) 在时间上的平滑中计算:
$$
Y[k] = 20\log_{10}\hat{X}[k]
$$

对于 \(k = 0, \ldots, N-1\)。

该数组 \(Y[k]\) 被复制到输出数组以供 getFloatFrequencyData() 使用。对于 getByteFrequencyData(), \(Y[k]\) 被截断以介于 minDecibelsmaxDecibels 之间,然后按比例缩放为一个无符号字节,使得minDecibels 代表值 0, maxDecibels 代表值 255。

1.9. AudioBufferSourceNode 接口

AudioBufferSourceNode/AudioBufferSourceNode

Firefox53+SafariChrome55+
Opera42+Edge79+
Edge (旧版)IE
Firefox for Android53+iOS SafariChrome for Android55+Android WebView55+Samsung Internet6.0+Opera Mobile42+

AudioBufferSourceNode

适用于所有当前引擎。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (旧版)12+IE
Firefox for Android25+iOS Safari6+Chrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

此接口表示来自 AudioBuffer 中的内存音频资源的音频源。它对于需要高度调度灵活性和 准确性的音频资源播放非常有用。如果需要样本精确的网络或磁盘支持的 资源播放,开发者应使用 AudioWorkletNode 来实现播放。

start() 方法用于 调度音频播放的开始时间。start() 方法不可 多次调用。当缓冲区的音频数据播放完毕(如果 loop 属性为 false)时,或当 stop() 方法被 调用且达到指定时间时,播放会自动停止。详细信息请参阅 start()stop() 说明。

属性 备注
numberOfInputs 0
numberOfOutputs 1
channelCount 2
channelCountMode "max"
channelInterpretation "speakers"
尾部时间

输出通道的数量等于分配给 buffer 属性的 AudioBuffer 的通道数, 或者如果 buffernull,则为一个静音通道。

此外,如果缓冲区有多个通道, 那么 AudioBufferSourceNode 的输出必须在渲染量子的开头时改变为一个静音通道,当以下任意一个条件成立时:

播放头位置 是为 AudioBufferSourceNode 定义的,它表示相对于缓冲区中第一个样本帧的时间坐标的时间偏移量。 这些值应独立于节点的 playbackRatedetune 参数。 通常,播放头位置可以是子样本精确的,并且不需要 指定准确的样本帧位置。它们可能假设介于 0 和缓冲区持续时间之间的有效值。

playbackRatedetune 属性组成了一个 复合参数。它们一起用于确定 计算的播放速率 值:

computedPlaybackRate(t) = playbackRate(t) * pow(2, detune(t) / 1200)

复合参数标称范围 是 \((-\infty, \infty)\)。

AudioBufferSourceNodes are created with an internal boolean slot [[buffer set]], initially set to false.

[Exposed=Window]
interface AudioBufferSourceNode : AudioScheduledSourceNode {
  constructor (BaseAudioContext context,
               optional AudioBufferSourceOptions options = {});
  attribute AudioBuffer? buffer;
  readonly attribute AudioParam playbackRate;
  readonly attribute AudioParam detune;
  attribute boolean loop;
  attribute double loopStart;
  attribute double loopEnd;
  undefined start (optional double when = 0,
                   optional double offset,
                   optional double duration);
};

1.9.1. 构造函数

AudioBufferSourceNode(context, options)

当构造函数使用 BaseAudioContext context 和 一个选项对象 option 被调用时,用户代理必须使用 contextoptions 作为参数初始化此 AudioNode

AudioBufferSourceNode.constructor() 方法的参数。
参数 类型 可为 null 可选 描述
context BaseAudioContext 此新的 AudioBufferSourceNode 将会关联到的 BaseAudioContext
options AudioBufferSourceOptions AudioBufferSourceNode 的可选初始参数值。

1.9.2. 属性

AudioBufferSourceNode/buffer

适用于所有当前引擎。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (旧版)12+IE
Firefox for Android25+iOS Safari6+Chrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

buffer类型为 AudioBuffer, 可为空

表示要播放的音频资源。

要设置 buffer 属性,请执行以下步骤:
  1. new buffer 设为要分配给 AudioBuffernull 的值。

  2. 如果 new buffer 不为 null 并且 [[buffer set]] 为 true,则抛出 InvalidStateError 并中止这些步骤。

  3. 如果 new buffer 不为 null,则将 [[buffer set]] 设置为 true。

  4. new buffer 分配给 buffer 属性。

  5. 如果此节点上以前调用过 start(),则对 buffer 执行操作 获取内容

AudioBufferSourceNode/detune

Firefox40+SafariChrome44+
Opera31+Edge79+
Edge (旧版)13+IE
Firefox for Android40+iOS SafariChrome for Android44+Android WebView44+Samsung Internet4.0+Opera Mobile32+

detune类型为 AudioParam, 只读

一个附加参数,以音分为单位,用于调制音频流的渲染速度。此参数与 playbackRate 共同组成复合参数, 形成 计算的播放速率

参数 备注
defaultValue 0
minValue 最小单精度浮点数 约为 -3.4028235e38
maxValue 最大单精度浮点数 约为 3.4028235e38
automationRate "k-rate" 具有自动化速率约束

AudioBufferSourceNode/loop

适用于所有当前引擎。

Firefox25+Safari6+Chrome15+
Opera15+Edge79+
Edge (旧版)12+IE
Firefox for Android25+iOS Safari6+Chrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

loop类型为 boolean

指示由 loopStartloopEnd 指定的音频数据区域是否应连续循环播放。默认值为 false

AudioBufferSourceNode/loopEnd

适用于所有当前引擎。

Firefox25+Safari6+Chrome24+
Opera15+Edge79+
Edge (旧版)12+IE
Firefox for Android25+iOS Safari6+Chrome for Android25+Android WebView37+Samsung Internet1.5+Opera Mobile14+

loopEnd类型为 double

一个可选的播放位置, 用于指定循环应在何时结束,如果 loop 属性为 true。其值不包括循环的内容。默认 为 0,且可设置为 0 和缓冲区持续时间之间的任何值。如果 loopEnd 小于或等于 0,或者 loopEnd 大于缓冲区的持续时间,则循环将在缓冲区结束时结束。

AudioBufferSourceNode/loopStart

适用于所有当前引擎。

Firefox25+Safari6+Chrome24+
Opera15+Edge79+
Edge (旧版)12+IE
Firefox for Android25+iOS Safari6+Chrome for Android25+Android WebView37+Samsung Internet1.5+Opera Mobile14+

loopStart类型为 double

一个可选的播放位置,用于指定循环应在何时开始 如果 loop 属性为 true。默认 为 0,且可设置为 0 和缓冲区持续时间之间的任何值。如果 loopStart 小于 0,则循环将从 0 开始。如果 loopStart 大于缓冲区的持续时间,则循环将在缓冲区结束时开始。

AudioBufferSourceNode/playbackRate

适用于所有当前引擎。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (旧版)12+IE
Firefox for Android25+iOS Safari6+Chrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

playbackRate类型为 AudioParam,只读

渲染音频流的速度。这是一个复合参数,与 detune 结合形成 计算的播放速度

参数 备注
defaultValue 1
minValue 最小单精度浮点数 约为 -3.4028235e38
maxValue 最大单精度浮点数 约为 3.4028235e38
automationRate "k-rate" 具有自动化速率约束

1.9.3. 方法

AudioBufferSourceNode/start

适用于所有当前引擎。

Firefox25+Safari6.1+Chrome24+
Opera15+Edge79+
Edge (旧版)12+IE
Firefox for Android25+iOS Safari7+Chrome for Android25+Android WebView37+Samsung Internet1.5+Opera Mobile14+

start(when, offset, duration)

调度声音在准确的时间播放。

当调用此方法时,执行以下步骤:
  1. 如果此 AudioBufferSourceNode 内部槽 [[source started]]true,则必须抛出 InvalidStateError 异常。

  2. 检查由于参数约束描述而必须抛出的任何错误。如果在此步骤中抛出任何异常, 则中止这些步骤。

  3. 将此 AudioBufferSourceNode 上的内部槽 [[source started]] 设置为 true

  4. 排队控制消息 以启动 AudioBufferSourceNode, 包括消息中的参数值。

  5. 如果已设置 buffer, 则执行 获取内容 操作。

  6. 仅在满足以下所有条件时,向关联的 AudioContext 发送 控制消息启动其渲染线程

    1. 上下文的 [[control thread state]]suspended

    2. 上下文被允许启动

    3. [[suspended by user]] 标志为 false

    注意: 这允许start()启动一个否则不会被允许启动AudioContext

运行 控制消息 以启动 AudioBufferSourceNode 意味着在 播放算法 中调用 handleStart() 函数。
AudioBufferSourceNode.start(when, offset, duration) 方法的参数。
参数 类型 可为空 可选 描述
when double when 参数描述声音应在何时(以秒为单位)开始播放。它与 AudioContextcurrentTime 属性使用相同的时间坐标系。如果该值传入 0 或小于 currentTime,则声音将立即开始播放。如果 when 为负值,则必须抛出 RangeError 异常。
offset double offset 参数提供一个 播放位置 ,从该位置开始播放。如果传入该值为 0,则从缓冲区的开头开始播放。如果 offset 为负值,则必须抛出 RangeError 异常。 如果 offset 大于 loopEndplaybackRate 为正或零,且 looptrue,则播放将在 loopEnd 开始。 如果 offset 大于 loopStartplaybackRate 为负值,且 looptrue,则播放将在 loopStart 开始。 在 startTime 到达时,offset 将被静默地限制在 [0, duration] 范围内,其中 duration 是设置为此 AudioBuffer 属性的 bufferduration 属性值。
duration double duration 参数描述要播放的声音的持续时间,表示为要输出的缓冲区内容的总秒数,包括任何完整或部分循环迭代。 duration 的单位独立于 playbackRate 的效果。例如,播放速率为 0.5 的 5 秒 duration 将以半速输出 5 秒的缓冲区内容,从而产生 10 秒的可听输出。如果 duration 为负值,则必须抛出 RangeError 异常。
返回类型: undefined

1.9.4. AudioBufferSourceOptions

这是用于构造 AudioBufferSourceNode 的选项。所有成员都是可选的;如果未指定,则在构造节点时使用默认值。

dictionary AudioBufferSourceOptions {
  AudioBuffer? buffer;
  float detune = 0;
  boolean loop = false;
  double loopEnd = 0;
  double loopStart = 0;
  float playbackRate = 1;
};
1.9.4.1. Dictionary AudioBufferSourceOptions 成员
buffer, 类型为 AudioBuffer, 可为空

要播放的音频资源。相当于将 buffer 分配给 buffer 属性的 AudioBufferSourceNode

detune, 类型为 float,默认值为 0

detune AudioParam 的初始值。

loop, 类型为 boolean,默认值为 false

loop 属性的初始值。

loopEnd, 类型为 double,默认值为 0

loopEnd 属性的初始值。

loopStart, 类型为 double,默认值为 0

loopStart 属性的初始值。

playbackRate, 类型为 float,默认值为 1

playbackRate AudioParam 的初始值。

1.9.5. 循环

本节为非规范性内容。有关规范性要求,请参阅播放算法

loop 属性设置为 true 将导致缓冲区中由 loopStartloopEnd 定义的区域在播放的任何部分播放后继续无限期地循环播放。只要 loop 保持为 true, 循环播放将继续,直到发生以下情况之一:

循环的主体被认为占据从 loopStartloopEnd 的区域,但不包括该区域。循环区域的播放方向遵循节点的播放速率的符号。对于正的播放速率,循环从 loopStartloopEnd; 对于负的播放速率,循环从 loopEndloopStart

循环不会影响 offset 参数在 start() 中的解释。播放总是从请求的偏移处开始,循环只在播放期间遇到循环主体时才开始。

有效的循环起点和终点必须位于零到缓冲区持续时间的范围内,如以下算法所规定的。 loopEnd 进一步约束为必须在 loopStart 之后或与之相等。如果违反这些约束,则认为循环包括整个缓冲区的内容。

循环端点具有子样本精度。当端点未落在确切的样本帧偏移上,或播放速率不等于 1 时,循环的播放将被插值,以将循环的开始和结束拼接在一起,就像循环音频发生在缓冲区的连续非循环区域中一样。

循环相关的属性可以在缓冲区播放期间发生变化,通常会在下一个渲染量子中生效。确切的结果由接下来的规范播放算法定义。

loopStartloopEnd 属性的默认值均为 0。由于 loopEnd 值为零相当于缓冲区的长度,因此默认端点导致整个缓冲区都包含在循环中。

请注意,循环端点的值以缓冲区的采样率为时间偏移,这意味着这些值独立于节点的 playbackRate 参数,后者在播放过程中可以动态变化。

1.9.6. 播放 AudioBuffer 内容

本规范部分指定了缓冲区内容的播放,考虑到以下因素组合在一起对播放的影响:

内部遵循的算法,以从AudioBufferSourceNode 生成输出,符合以下原则:

算法的描述如下:

let buffer; // 由此节点使用的 AudioBufferlet context; // 由此节点使用的 AudioContext// 以下变量捕获节点的属性和 AudioParam 值。// 在每次调用 process() 之前,它们会以 k-rate 进行更新。let loop;let detune;let loopStart;let loopEnd;let playbackRate;// 节点的播放参数变量let start = 0, offset = 0, duration = Infinity; // 由 start() 设置let stop = Infinity; // 由 stop() 设置// 用于跟踪节点播放状态的变量let bufferTime = 0, started = false, enteredLoop = false;let bufferTimeElapsed = 0;let dt = 1 / context.sampleRate;// 处理 start 方法调用function handleStart(when, pos, dur) {  if (arguments.length >= 1) {    start = when;  }  offset = pos;  if (arguments.length >= 3) {    duration = dur;  }}// 处理 stop 方法调用function handleStop(when) {  if (arguments.length >= 1) {    stop = when;  } else {    stop = context.currentTime;  }}// 为某个样本帧插值多通道信号值。// 返回一个信号值数组。function playbackSignal(position) {  /*    此函数提供缓冲区的播放信号功能,该功能将播放头位置映射到一组输出信号    值,每个输出通道一个信号值。如果 |position| 对应于缓冲区中的确切样本帧    位置,则此函数返回该帧。否则,其返回值由 UA 提供的算法决定,    该算法对 |position| 附近的样本帧进行插值。    如果 |position| 大于或等于 |loopEnd|,并且缓冲区中没有后续样本帧,    则插值应基于从 |loopStart| 开始的后续帧序列。   */   ...}// 生成单个音频渲染量子,并将其放置在由输出定义的通道数组中。// 返回要输出的 |numberOfFrames| 个样本帧数组。function process(numberOfFrames) {  let currentTime = context.currentTime; // 下一个渲染帧的上下文时间  const output = []; // 累积渲染的样本帧  // 结合两个影响播放速率的 k-rate 参数  const computedPlaybackRate = playbackRate * Math.pow(2, detune / 1200);  // 确定适用的循环端点  let actualLoopStart, actualLoopEnd;  if (loop && buffer != null) {    if (loopStart >= 0 && loopEnd > 0 && loopStart < loopEnd) {      actualLoopStart = loopStart;      actualLoopEnd = Math.min(loopEnd, buffer.duration);    } else {      actualLoopStart = 0;      actualLoopEnd = buffer.duration;    }  } else {    // 如果循环标志为 false,则删除任何已进入循环的记录    enteredLoop = false;  }  // 处理缓冲区为空的情况  if (buffer == null) {    stop = currentTime; // 强制在所有时间内输出为零  }  // 渲染量子中的每个样本帧  for (let index = 0; index < numberOfFrames; index++) {    // 检查 currentTime 和 bufferTimeElapsed 是否    // 在允许的播放范围内    if (currentTime < start || currentTime >= stop || bufferTimeElapsed >= duration) {      output.push(0); // 此样本帧静音      currentTime += dt;      continue;    }    if (!started) {      // 注意缓冲区已经开始播放,并获取初始      // 播放头位置。      if (loop && computedPlaybackRate >= 0 && offset >= actualLoopEnd) {        offset = actualLoopEnd;      }      if (computedPlaybackRate < 0 && loop && offset < actualLoopStart) {        offset = actualLoopStart;      }      bufferTime = offset;      started = true;    }    // 处理循环相关的计算    if (loop) {      // 确定是否首次进入循环部分      if (!enteredLoop) {        if (offset < actualLoopEnd && bufferTime >= actualLoopStart) {          // 播放在循环之前或在循环中开始,现在播放头已过循环开始点          enteredLoop = true;        }        if (offset >= actualLoopEnd && bufferTime < actualLoopEnd) {          // 播放在循环之后开始,现在播放头位于循环结束前          enteredLoop = true;        }      }      // 根据需要包装循环迭代。注意,enteredLoop 可能会在前面的条件中变为 true。      if (enteredLoop) {        while (bufferTime >= actualLoopEnd) {          bufferTime -= actualLoopEnd - actualLoopStart;        }        while (bufferTime < actualLoopStart) {          bufferTime += actualLoopEnd - actualLoopStart;        }      }    }    if (bufferTime >= 0 && bufferTime < buffer.duration) {      output.push(playbackSignal(bufferTime));    } else {      output.push(0); // 超出缓冲区末尾,因此输出静音帧    }    bufferTime += dt * computedPlaybackRate;    bufferTimeElapsed += dt * computedPlaybackRate;    currentTime += dt;  } // 渲染量子循环结束  if (currentTime >= stop) {    // 结束此节点的播放状态。不会再调用 process()。    // 调度一个更改,以将输出通道数设置为 1。  }  return output;}

以下非规范图例说明了算法在某些关键场景中的行为。未考虑缓冲区的动态重采样,但只要不更改循环位置的时间,这不会对结果播放产生实质性影响。在所有图例中,适用以下约定:

下图说明了缓冲区的基本播放,循环在缓冲区的最后一个样本帧之后结束:

AudioBufferSourceNode basic playback
AudioBufferSourceNode 基本播放

下图说明了playbackRate插值,显示了缓冲区内容的半速播放,其中每隔一个输出样本帧都会进行插值。特别注意的是循环输出中的最后一个样本帧,它使用循环起点进行插值:

AudioBufferSourceNode playbackRate interpolation
AudioBufferSourceNode playbackRate 插值

下图说明了采样率插值,显示了缓冲区的播放,其采样率为上下文采样率的 50%,导致计算的播放速率为 0.5,纠正了缓冲区和上下文之间的采样率差异。结果输出与前面的示例相同,但原因不同。

AudioBufferSourceNode sample rate interpolation
AudioBufferSourceNode 采样率插值

下图说明了子样本偏移播放,其中缓冲区内的偏移精确地从半个样本帧开始。因此,每个输出帧都进行插值:

AudioBufferSourceNode subsample offset playback
AudioBufferSourceNode 子样本偏移播放

下图说明了子样本循环播放,显示了循环端点中的分数帧偏移如何映射到缓冲区中的插值数据点,这些数据点遵循这些偏移,就像它们是对精确样本帧的引用一样:

AudioBufferSourceNode subsample loop playback
AudioBufferSourceNode 子样本循环播放

1.10. The AudioDestinationNode 接口

AudioDestinationNode

在所有当前引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (旧版)12+IE
Android 版 Firefox25+iOS SafariAndroid 版 Chrome18+Android WebView37+三星互联网1.0+Opera Mobile14+

这是一个表示最终音频目的地的AudioNode, 用户最终会听到的音频输出。它通常可以被视为连接到扬声器的音频输出设备。所有将要听到的音频渲染都将路由到这个节点,这是AudioContext路由图中的“终端”节点。每个AudioContext只有一个 AudioDestinationNode,通过destination属性提供。

AudioDestinationNode的输出是通过求和其输入产生的,允许捕获AudioContext的输出,例如到MediaStreamAudioDestinationNodeMediaRecorder(在[mediastream-recording]中描述)。

AudioDestinationNode可以是AudioContextOfflineAudioContext的目的地,通道属性取决于上下文。

对于AudioContext,默认值如下

属性 备注
numberOfInputs 1
numberOfOutputs 1
channelCount 2
channelCountMode "explicit"
channelInterpretation "speakers"
tail-time

channelCount可以设置为小于或等于maxChannelCount的任何值。如果该值不在有效范围内,则必须抛出IndexSizeError异常。具体来说,如果音频硬件支持 8 声道输出,则我们可以将channelCount设置为 8,并渲染 8 声道的输出。

对于OfflineAudioContext,默认值如下

属性 备注
numberOfInputs 1
numberOfOutputs 1
channelCount numberOfChannels
channelCountMode "explicit"
channelInterpretation "speakers"
tail-time

其中numberOfChannels是构建OfflineAudioContext时指定的通道数。此值不可更改;如果将channelCount更改为不同的值,则必须抛出NotSupportedError异常

[Exposed=Window]
interface AudioDestinationNode : AudioNode {
  readonly attribute unsigned long maxChannelCount;
};

1.10.1. 属性

AudioDestinationNode/maxChannelCount

在所有当前引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (旧版)12+IE
Android 版 Firefox25+iOS 版 SafariAndroid 版 Chrome18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

maxChannelCount, 类型为 unsigned long,只读

此属性表示 channelCount 属性可以设置的最大通道数。表示音频硬件终端(通常情况)的 AudioDestinationNode 可以在音频硬件为多通道时输出多于2个通道的音频。maxChannelCount 是此硬件支持的最大通道数。

1.11. AudioListener 接口

该接口表示聆听音频场景的人的位置和方向。所有 PannerNode 对象均相对于 BaseAudioContextlistener 进行空间化。有关空间化的更多详细信息,请参见 § 6 空间化/声源定位

positionXpositionYpositionZ 参数表示监听者在 3D 笛卡尔坐标空间中的位置。PannerNode 对象使用此位置相对于各个音频源进行空间化。

forwardXforwardYforwardZ 参数表示 3D 空间中的方向向量。forward 向量和 up 向量用于确定监听者的方向。简单来说,forward 向量表示人的鼻子指向的方向。up 向量表示人的头顶指向的方向。期望这两个向量是线性独立的。有关如何解释这些值的规范性要求,请参见 § 6 空间化/声源定位 部分。

AudioListener

在所有当前引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (旧版)12+IE
Android 版 Firefox25+iOS 版 SafariAndroid 版 Chrome18+Android WebView37+Samsung Internet1.0+Opera Mobile14+
[Exposed=Window]
interface AudioListener {
  readonly attribute AudioParam positionX;
  readonly attribute AudioParam positionY;
  readonly attribute AudioParam positionZ;
  readonly attribute AudioParam forwardX;
  readonly attribute AudioParam forwardY;
  readonly attribute AudioParam forwardZ;
  readonly attribute AudioParam upX;
  readonly attribute AudioParam upY;
  readonly attribute AudioParam upZ;
  undefined setPosition (float x, float y, float z);
  undefined setOrientation (float x, float y, float z, float xUp, float yUp, float zUp);
};

1.11.1. 属性

AudioListener/forwardX

在仅一个当前引擎中。

FirefoxSafariChrome52+
Opera39+Edge79+
Edge (旧版)IE
Android 版 FirefoxiOS 版 SafariAndroid 版 Chrome52+Android WebView52+Samsung Internet6.0+Opera Mobile41+

forwardX, 类型为 AudioParam, 只读

设置监听者在 3D 笛卡尔坐标空间中指向的前向方向的 x 坐标分量。

参数 备注
defaultValue 0
minValue most-negative-single-float 约为 -3.4028235e38
maxValue most-positive-single-float 约为 3.4028235e38
automationRate "a-rate"

AudioListener/forwardY

在仅一个当前引擎中。

FirefoxSafariChrome52+
Opera39+Edge79+
Edge (旧版)IE
Android 版 FirefoxiOS 版 SafariAndroid 版 Chrome52+Android WebView52+Samsung Internet6.0+Opera Mobile41+

forwardY, 类型为 AudioParam, 只读

设置监听者在 3D 笛卡尔坐标空间中指向的前向方向的 y 坐标分量。

参数 备注
defaultValue 0
minValue most-negative-single-float 约为 -3.4028235e38
maxValue most-positive-single-float 约为 3.4028235e38
automationRate "a-rate"

AudioListener/forwardZ

在仅一个当前引擎中。

FirefoxSafariChrome52+
Opera39+Edge79+
Edge (旧版)IE
Android 版 FirefoxiOS 版 SafariAndroid 版 Chrome52+Android WebView52+Samsung Internet6.0+Opera Mobile41+

forwardZ, 类型为 AudioParam, 只读

设置监听者在 3D 笛卡尔坐标空间中指向的前向方向的 z 坐标分量。

参数 备注
defaultValue -1
minValue most-negative-single-float 约为 -3.4028235e38
maxValue most-positive-single-float 约为 3.4028235e38
automationRate "a-rate"

AudioListener/positionX

在仅一个当前引擎中。

FirefoxSafariChrome52+
Opera39+Edge79+
Edge (旧版)IE
Android 版 FirefoxiOS 版 SafariAndroid 版 Chrome52+Android WebView52+Samsung Internet6.0+Opera Mobile41+

positionX, 类型为 AudioParam, 只读

设置音频监听者在 3D 笛卡尔坐标空间中的 x 坐标位置。

参数 备注
defaultValue 0
minValue most-negative-single-float 约为 -3.4028235e38
maxValue most-positive-single-float 约为 3.4028235e38
automationRate "a-rate"

AudioListener/positionY

在仅一个当前引擎中。

FirefoxSafariChrome52+
Opera39+Edge79+
Edge (旧版)IE
Android 版 FirefoxiOS 版 SafariAndroid 版 Chrome52+Android WebView52+Samsung Internet6.0+Opera Mobile41+

positionY, 类型为 AudioParam, 只读

设置音频监听者在 3D 笛卡尔坐标空间中的 y 坐标位置。

参数 备注
defaultValue 0
minValue most-negative-single-float 约为 -3.4028235e38
maxValue most-positive-single-float 约为 3.4028235e38
automationRate "a-rate"

AudioListener/positionZ

仅在一个当前引擎中。

FirefoxSafariChrome52+
Opera39+Edge79+
Edge (旧版)IE
Firefox for AndroidiOS SafariChrome for Android52+Android WebView52+Samsung Internet6.0+Opera Mobile41+

positionZ, 类型为 AudioParam,只读

设置音频监听者在 3D 笛卡尔坐标系中的 z 坐标位置。

参数 备注
defaultValue 0
minValue 最负单精度浮点数 大约 -3.4028235e38
maxValue 最正单精度浮点数 大约 3.4028235e38
automationRate "a-rate"

AudioListener/upX

仅在一个当前引擎中。

FirefoxSafariChrome52+
Opera39+Edge79+
Edge (旧版)IE
Firefox for AndroidiOS SafariChrome for Android52+Android WebView52+Samsung Internet6.0+Opera Mobile41+

upX, 类型为 AudioParam,只读

设置监听者在 3D 笛卡尔坐标系中 up 方向的 x 坐标分量。

参数 备注
defaultValue 0
minValue 最负单精度浮点数 大约 -3.4028235e38
maxValue 最正单精度浮点数 大约 3.4028235e38
automationRate "a-rate"

1.11.2. 方法

setOrientation(x, y, z, xUp, yUp, zUp)

此方法已弃用。它等同于直接设置 forwardX.valueforwardY.valueforwardZ.valueupX.valueupY.value,以及upZ.value,分别使用给定的 xyzxUpyUpzUp 值。

因此,如果在调用此方法时,任何 forwardXforwardYforwardZupXupYupZAudioParam 在调用此方法时已通过 setValueCurveAtTime() 设置了自动化曲线,则必须抛出 NotSupportedError

setOrientation() 描述了监听者在 3D 笛卡尔坐标系中的朝向。提供了一个 forward 向量和一个 up 向量。通俗地讲,forward 向量表示人的鼻子指向的方向。up 向量表示人的头顶指向的方向。这两个向量应线性独立。有关这些值的规范要求,请参见 § 6 空间化/声像定位

xyz 参数表示 3D 空间中的一个 forward 方向向量,默认值为 (0,0,-1)。

xUpyUpzUp 参数表示 3D 空间中的一个 up 方向向量,默认值为 (0,1,0)。

AudioListener.setOrientation() 方法的参数。
参数 类型 可为 Null 可选 描述
x float AudioListener 的 forward x 方向
y float AudioListener 的 forward y 方向
z float AudioListener 的 forward z 方向
xUp float AudioListener 的 up x 方向
yUp float AudioListener 的 up y 方向
zUp float AudioListener 的 up z 方向
返回类型: undefined
setPosition(x, y, z)

此方法已弃用。它等同于直接设置 positionX.valuepositionY.value,以及 positionZ.value,分别使用给定的 xyz 值。

因此,如果 positionXpositionYpositionZAudioParam 在调用此方法时已通过 setValueCurveAtTime() 设置了自动化曲线,则必须抛出 NotSupportedError

setPosition() 设置监听者在 3D 笛卡尔坐标系中的位置。PannerNode 对象根据与各个音源的相对位置进行空间化处理。

默认值为 (0,0,0)。

AudioListener.setPosition() 方法的参数。
参数 类型 可为 Null 可选 描述
x float AudioListenerx 坐标
y float AudioListenery 坐标
z float AudioListenerz 坐标

1.11.3. 处理

由于 AudioListener 的参数可以与 AudioNode 连接,并且它们还可以影响同一图中的 PannerNode 的输出,因此节点排序算法在计算处理顺序时应考虑 AudioListener。因此,图中的所有 PannerNode 都将 AudioListener 作为输入。

1.12. AudioProcessingEvent 接口 - 已弃用

这是一个 Event 对象,它会分派给 ScriptProcessorNode 节点。当 ScriptProcessorNode 被移除时,该对象也会被移除,因为替代的 AudioWorkletNode 使用了不同的方法。

事件处理程序通过访问 inputBuffer 属性中的音频数据来处理来自输入(如果有)的音频数据。处理后的音频数据(如果没有输入,则为合成数据)将放入 outputBuffer 中。

[Exposed=Window]
        interface AudioProcessingEvent : Event {
          constructor (DOMString type, AudioProcessingEventInit eventInitDict);
          readonly attribute double playbackTime;
          readonly attribute AudioBuffer inputBuffer;
          readonly attribute AudioBuffer outputBuffer;
        };
        

1.12.1. 属性

inputBuffer, 类型为 AudioBuffer, 只读

包含输入音频数据的 AudioBuffer。它的通道数量等于 createScriptProcessor() 方法的 numberOfInputChannels 参数。此 AudioBuffer 仅在 onaudioprocess 函数的范围内有效。 在此范围之外,它的值将毫无意义。

outputBuffer, 类型为 AudioBuffer, 只读

输出音频数据必须写入的 AudioBuffer。它的通道数量等于 createScriptProcessor() 方法的 numberOfOutputChannels 参数。在 onaudioprocess 函数范围内的脚本代码预计会修改此 AudioBuffer 中代表通道数据的 Float32Array 数组。 在此范围之外对该 AudioBuffer 的任何脚本修改都不会产生可听的效果。

playbackTime, 类型为 double,只读

音频将在与 AudioContextcurrentTime 相同的时间坐标系中播放的时间。

1.12.2. AudioProcessingEventInit

dictionary AudioProcessingEventInit : EventInit {
          required double playbackTime;
          required AudioBuffer inputBuffer;
          required AudioBuffer outputBuffer;
        };
        
1.12.2.1. 字典 AudioProcessingEventInit 成员
inputBuffer, 类型为 AudioBuffer

要分配给事件的 inputBuffer 属性的值。

outputBuffer, 类型为 AudioBuffer

要分配给事件的 outputBuffer 属性的值。

playbackTime, 类型为 double

要分配给事件的 playbackTime 属性的值。

1.13. BiquadFilterNode 接口

BiquadFilterNode 是一个实现非常常见低阶滤波器的AudioNode 处理器。

低阶滤波器是基本音调控制(低音、中音、高音)、图形均衡器和更高级滤波器的 构建块。多个BiquadFilterNode 滤波器可以组合形成更复杂的滤波器。滤波器参数如frequency 可以随着时间的推移而改变,用于滤波器扫描等。每个BiquadFilterNode 都可以配置为以下IDL中显示的一种常见滤波器类型。默认滤波器类型为"lowpass"

frequencydetune 一起组成复合参数,两者都是a-rate。 它们一起用于确定计算的频率值:

computedFrequency(t) = frequency(t) * pow(2, detune(t) / 1200)

复合参数标称范围是[0, Nyquist频率]。

属性 备注
numberOfInputs 1
numberOfOutputs 1
channelCount 2
channelCountMode "max"
channelInterpretation "speakers"
tail-time 在没有输入的情况下继续输出非静音音频。由于这是一个IIR滤波器,滤波器会永远产生非零输入,但在实际应用中,这可以在输出足够接近于零的某个有限时间后限制。实际时间取决于滤波器系数。

输出的通道数始终等于输入的通道数。

enum BiquadFilterType {
  "lowpass",
  "highpass",
  "bandpass",
  "lowshelf",
  "highshelf",
  "peaking",
  "notch",
  "allpass"
};
枚举描述
"lowpass" 低通滤波器允许通过截止频率以下的频率,并衰减截止频率以上的频率。它实现了标准的二阶谐振低通滤波器,衰减率为12dB/倍频程。
频率

截止频率

Q值

控制响应在截止频率处的峰值。较大的值使响应在截止频率处更为尖锐。

增益

在此滤波器类型中不使用

"highpass" 高通滤波器与低通滤波器相反。通过截止频率以上的频率,但衰减截止频率以下的频率。它实现了标准的二阶谐振高通滤波器,衰减率为12dB/倍频程。
频率

衰减以下频率的截止频率

Q值

控制响应在截止频率处的峰值。较大的值使响应在截止频率处更为尖锐。

增益

在此滤波器类型中不使用

"bandpass" 带通滤波器允许通过一范围内的频率,并衰减该频率范围以下和以上的频率。它实现了二阶带通滤波器。
频率

频带的中心频率

Q值

控制频带的宽度。Q值增加时宽度变窄。

增益

在此滤波器类型中不使用

"lowshelf" 低架滤波器允许通过所有频率,但对低频率增加一个提升(或衰减)。它实现了二阶低架滤波器。
频率

施加提升(或衰减)的频率上限。

Q值

在此滤波器类型中不使用。

增益

要应用的提升,单位为dB。如果该值为负数,则频率被衰减。

"highshelf" 高架滤波器与低架滤波器相反,允许通过所有频率,但对高频率增加一个提升。它实现了二阶高架滤波器。
频率

施加提升(或衰减)的频率下限。

Q值

在此滤波器类型中不使用。

增益

要应用的提升,单位为dB。如果该值为负数,则频率被衰减。

"peaking" 峰值滤波器允许通过所有频率,但对一范围内的频率增加一个提升(或衰减)。
频率

施加提升的中心频率。

Q值

控制提升频带的宽度。较大的值意味着较窄的宽度。

增益

要应用的提升,单位为dB。如果该值为负数,则频率被衰减。

"notch" 陷波滤波器(也称为带阻或带拒滤波器)与带通滤波器相反。它允许通过所有频率,除了一组频率。
频率

施加陷波的中心频率。

Q值

控制被衰减频带的宽度。较大的值意味着较窄的宽度。

增益

在此滤波器类型中不使用。

"allpass" 全通滤波器允许通过所有频率,但改变不同频率之间的相位关系。它实现了二阶全通滤波器。
频率

发生相位变化的中心频率。换句话说,这是群延迟最大的频率。

Q值

控制中心频率处相位变化的尖锐程度。较大的值意味着更为尖锐的相位变化和更大的群延迟。

增益

在此滤波器类型中不使用。

BiquadFilterNode的所有属性都是a-rate AudioParam

BiquadFilterNode/BiquadFilterNode

Firefox53+SafariNoneChrome55+
Opera42+Edge79+
Edge (Legacy)NoneIENone
Firefox for Android53+iOS SafariNoneChrome for Android55+Android WebView55+Samsung Internet6.0+Opera Mobile42+

BiquadFilterNode

在所有当前引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (Legacy)12+IENone
Firefox for Android25+iOS SafariYesChrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile14+
[Exposed=Window]
interface BiquadFilterNode : AudioNode {
  constructor (BaseAudioContext context, optional BiquadFilterOptions options = {});
  attribute BiquadFilterType type;
  readonly attribute AudioParam frequency;
  readonly attribute AudioParam detune;
  readonly attribute AudioParam Q;
  readonly attribute AudioParam gain;
  undefined getFrequencyResponse (Float32Array frequencyHz,
                                  Float32Array magResponse,
                                  Float32Array phaseResponse);
};

1.13.1. 构造函数

BiquadFilterNode(context, options)

当构造函数使用BaseAudioContext context和一个选项对象options调用时,用户代理必须初始化 AudioNode this,并将contextoptions作为参数。

BiquadFilterNode.constructor() 方法的参数。
参数 类型 可空 可选 描述
context BaseAudioContext BiquadFilterNode 将与之关联BaseAudioContext
options BiquadFilterOptions BiquadFilterNode 的可选初始参数值。

1.13.2. 属性

BiquadFilterNode/Q

在所有当前引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (Legacy)12+IENone
Firefox for Android25+iOS SafariYesChrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

Q, 类型为 AudioParam, 只读

滤波器的Q因子。

对于lowpasshighpass 滤波器,Q 值以dB为单位解释。对于这些滤波器,标称范围为 \([-Q_{lim}, Q_{lim}]\),其中\(Q_{lim}\)是使得\(10^{Q/20}\)不会溢出的最大值。 这大约是\(770.63678\)。

对于bandpassnotchallpass、 和peaking 滤波器,此值为线性值。该值与滤波器的带宽相关,因此应为正值。标称范围为\([0, 3.4028235e38]\), 上限为最大单精度浮点值

此值不用于lowshelfhighshelf 滤波器。

参数 备注
defaultValue 1
minValue 最小单精度浮点值 大约为-3.4028235e38,但参见上文了解不同滤波器的实际限制
maxValue 最大单精度浮点值 大约为3.4028235e38,但参见上文了解不同滤波器的实际限制
automationRate "a-rate"

BiquadFilterNode/detune

在所有当前引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (Legacy)12+IENone
Firefox for Android25+iOS SafariYesChrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

detune, 类型为 AudioParam, 只读

频率的微调值,以音分为单位。它与frequency 组成一个复合参数, 以形成计算的频率

参数 备注
defaultValue 0
minValue \(\approx -153600\)
maxValue \(\approx 153600\) 此值大约为\(1200\ \log_2 \mathrm{FLT\_MAX}\),其中FLT_MAX为 最大的float值。
automationRate "a-rate"

BiquadFilterNode/frequency

在所有当前引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (Legacy)12+IENone
Firefox for Android25+iOS SafariYesChrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

frequency, 类型为 AudioParam, 只读

BiquadFilterNode 运行的频率,以赫兹(Hz)为单位。它与detune 组成一个复合参数,以形成计算的频率

BiquadFilterNode/gain

在所有当前引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (Legacy)12+IENone
Firefox for Android25+iOS SafariYesChrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

gain, 类型为 AudioParam, 只读

滤波器的增益。其值以分贝为单位。增益仅用于lowshelfhighshelf、 和peaking 滤波器。

参数 备注
defaultValue 0
minValue 最小单精度浮点值 大约为-3.4028235e38
maxValue \(\approx 1541\) 此值大约为\(40\ \log_{10} \mathrm{FLT\_MAX}\),其中FLT_MAX为 最大的float值。
automationRate "a-rate"

BiquadFilterNode/type

在所有当前引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (Legacy)12+IENone
Firefox for Android25+iOS SafariYesChrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

type, 类型为 BiquadFilterType

BiquadFilterNode的类型。 默认值为"lowpass"。 其他参数的具体含义取决于type 属性的值。

1.13.3. 方法

BiquadFilterNode/getFrequencyResponse

在所有当前引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (Legacy)12+IENone
Firefox for Android25+iOS SafariYesChrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

getFrequencyResponse(frequencyHz, magResponse, phaseResponse)

根据每个滤波器参数的[[current value]], 同步计算指定频率的频率响应。三个参数必须是长度相同的Float32Array, 否则必须抛出InvalidAccessError

返回的频率响应必须使用当前处理块采样的AudioParam计算。

BiquadFilterNode.getFrequencyResponse() 方法的参数。
参数 类型 可空 可选 描述
frequencyHz Float32Array 此参数指定一个频率数组(单位:赫兹),用于计算响应值。
magResponse Float32Array 此参数指定一个输出数组,用于接收线性幅度响应值。 如果frequencyHz参数中的某个值不在[0, sampleRate/2]范围内, 其中sampleRatesampleRate 属性的值,AudioContext, 则magResponse数组中相同索引处的相应值必须为NaN
phaseResponse Float32Array 此参数指定一个输出数组,用于接收以弧度表示的相位响应值。 如果frequencyHz参数中的某个值不在[0; sampleRate/2]范围内, 其中sampleRatesampleRate 属性的值,AudioContext, 则phaseResponse数组中相同索引处的相应值必须为NaN
返回类型: undefined

1.13.4. BiquadFilterOptions

此选项用于构造BiquadFilterNode时指定的选项。 所有成员都是可选的;如果未指定,则使用默认值构造节点。

dictionary BiquadFilterOptions : AudioNodeOptions {
  BiquadFilterType type = "lowpass";
  float Q = 1;
  float detune = 0;
  float frequency = 350;
  float gain = 0;
};
1.13.4.1. Dictionary BiquadFilterOptions 成员
Q, 类型为 float,默认值为 1

Q 的期望初始值。

detune, 类型为 float,默认值为 0

detune 的期望初始值。

frequency, 类型为 float,默认值为 350

frequency 的期望初始值。

gain, 类型为 float,默认值为 0

gain 的期望初始值。

type, 类型为 BiquadFilterType,默认值为 "lowpass"

滤波器的期望初始类型。

1.13.5. 滤波器特性

通过BiquadFilterNode 可用的滤波器类型有多种实现方式,每种方式具有非常不同的特性。本节中的公式描述了一个 符合规范的实现必须实现的滤波器, 因为它们决定了不同滤波器类型的特性。它们的灵感来源于 音频EQ手册中的公式。

BiquadFilterNode 通过以下传递函数处理音频

$$
    H(z) = \frac{\frac{b_0}{a_0} + \frac{b_1}{a_0}z^{-1} + \frac{b_2}{a_0}z^{-2}}
                                              {1+\frac{a_1}{a_0}z^{-1}+\frac{a_2}{a_0}z^{-2}}
    $$
    

这相当于一个时域方程:

$$
    a_0 y(n) + a_1 y(n-1) + a_2 y(n-2) =
      b_0 x(n) + b_1 x(n-1) + b_2 x(n-2)
    $$
    

滤波器的初始状态为0。

注意: 虽然固定滤波器是稳定的,但使用 AudioParam 的自动化可以创建不稳定的双二阶滤波器。开发人员有责任管理这一点。

注意: UA可能会发出警告,通知用户滤波器状态中出现了NaN值。 这通常表明滤波器不稳定。

上述传递函数中的系数对于每种节点类型都是不同的。以下中间变量是计算这些系数所必需的, 基于AudioParam计算值

每种滤波器类型的六个系数(\(b_0, b_1, b_2, a_0, a_1, a_2\))如下:

"lowpass"
$$
  \begin{align*}
    b_0 &= \frac{1 - \cos\omega_0}{2} \\
    b_1 &= 1 - \cos\omega_0 \\
    b_2 &= \frac{1 - \cos\omega_0}{2} \\
    a_0 &= 1 + \alpha_{Q_{dB}} \\
    a_1 &= -2 \cos\omega_0 \\
    a_2 &= 1 - \alpha_{Q_{dB}}
  \end{align*}
$$
"highpass"
$$
  \begin{align*}
    b_0 &= \frac{1 + \cos\omega_0}{2} \\
    b_1 &= -(1 + \cos\omega_0) \\
    b_2 &= \frac{1 + \cos\omega_0}{2} \\
    a_0 &= 1 + \alpha_{Q_{dB}} \\
    a_1 &= -2 \cos\omega_0 \\
    a_2 &= 1 - \alpha_{Q_{dB}}
  \end{align*}
$$
"bandpass"
$$
  \begin{align*}
    b_0 &= \alpha_Q \\
    b_1 &= 0 \\
    b_2 &= -\alpha_Q \\
    a_0 &= 1 + \alpha_Q \\
    a_1 &= -2 \cos\omega_0 \\
    a_2 &= 1 - \alpha_Q
  \end{align*}
$$
"notch"
$$
  \begin{align*}
    b_0 &= 1 \\
    b_1 &= -2\cos\omega_0 \\
    b_2 &= 1 \\
    a_0 &= 1 + \alpha_Q \\
    a_1 &= -2 \cos\omega_0 \\
    a_2 &= 1 - \alpha_Q
  \end{align*}
$$
"allpass"
$$
  \begin{align*}
    b_0 &= 1 - \alpha_Q \\
    b_1 &= -2\cos\omega_0 \\
    b_2 &= 1 + \alpha_Q \\
    a_0 &= 1 + \alpha_Q \\
    a_1 &= -2 \cos\omega_0 \\
    a_2 &= 1 - \alpha_Q
  \end{align*}
$$
"peaking"
$$
  \begin{align*}
    b_0 &= 1 + \alpha_Q\, A \\
    b_1 &= -2\cos\omega_0 \\
    b_2 &= 1 - \alpha_Q\,A \\
    a_0 &= 1 + \frac{\alpha_Q}{A} \\
    a_1 &= -2 \cos\omega_0 \\
    a_2 &= 1 - \frac{\alpha_Q}{A}
  \end{align*}
$$
"lowshelf"
$$
  \begin{align*}
    b_0 &= A \left[ (A+1) - (A-1) \cos\omega_0 + 2 \alpha_S \sqrt{A})\right] \\
    b_1 &= 2 A \left[ (A-1) - (A+1) \cos\omega_0 )\right] \\
    b_2 &= A \left[ (A+1) - (A-1) \cos\omega_0 - 2 \alpha_S \sqrt{A}) \right] \\
    a_0 &= (A+1) + (A-1) \cos\omega_0 + 2 \alpha_S \sqrt{A} \\
    a_1 &= -2 \left[ (A-1) + (A+1) \cos\omega_0\right] \\
    a_2 &= (A+1) + (A-1) \cos\omega_0 - 2 \alpha_S \sqrt{A})
  \end{align*}
$$
"highshelf"
$$
  \begin{align*}
    b_0 &= A\left[ (A+1) + (A-1)\cos\omega_0 + 2\alpha_S\sqrt{A} )\right] \\
    b_1 &= -2A\left[ (A-1) + (A+1)\cos\omega_0 )\right] \\
    b_2 &= A\left[ (A+1) + (A-1)\cos\omega_0 - 2\alpha_S\sqrt{A} )\right] \\
    a_0 &= (A+1) - (A-1)\cos\omega_0 + 2\alpha_S\sqrt{A} \\
    a_1 &= 2\left[ (A-1) - (A+1)\cos\omega_0\right] \\
    a_2 &= (A+1) - (A-1)\cos\omega_0 - 2\alpha_S\sqrt{A}
  \end{align*}
$$

1.14. The ChannelMergerNode 接口

ChannelMergerNode 用于更高级的应用程序,并且通常与ChannelSplitterNode一起使用。

属性 备注
numberOfInputs 参见备注 默认为6,但由ChannelMergerOptionsnumberOfInputscreateChannelMerger指定的值决定。
numberOfOutputs 1
channelCount 1 channelCount 限制
channelCountMode "explicit" channelCountMode 限制
channelInterpretation "speakers"
tail-time No

此接口表示AudioNode, 用于将多个音频流的通道组合成一个音频流。它具有可变数量的输入(默认为6),但并非所有输入都需要连接。 当任何一个输入正在主动处理时, 输出的音频流的通道数等于输入的数量。如果没有输入在主动处理,则输出为单声道静音。

要将多个输入合并为一个流,每个输入根据指定的混音规则被下混为一个通道(单声道)。 未连接的输入在输出中仍计为一个静音通道。更改输入流不会影响输出通道的顺序。

例如,如果默认的ChannelMergerNode连接了两个立体声输入, 第一个和第二个输入将在合并之前分别下混为单声道。输出将是一个6通道流,其中前两个通道将填充前两个(下混的)输入,其余通道将是静音的。

此外,ChannelMergerNode 可用于为多通道扬声器阵列(例如5.1环绕声设置)安排多个音频流的顺序。 合并器不会解释通道标识(例如左、右等),而是简单地按输入顺序组合通道。

通道合并器
通道合并器的示意图

ChannelMergerNode/ChannelMergerNode

Firefox53+SafariNoneChrome55+
Opera42+Edge79+
Edge (Legacy)NoneIENone
Firefox for Android53+iOS SafariNoneChrome for Android55+Android WebView55+Samsung Internet6.0+Opera Mobile42+

ChannelMergerNode

在所有当前引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (Legacy)12+IENone
Firefox for Android25+iOS SafariYesChrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile14+
[Exposed=Window]
interface ChannelMergerNode : AudioNode {
  constructor (BaseAudioContext context, optional ChannelMergerOptions options = {});
};

1.14.1. 构造函数

ChannelMergerNode(context, options)

当使用BaseAudioContext c和一个选项对象option调用构造函数时, 用户代理必须使用contextoptions作为参数初始化AudioNode

ChannelMergerNode.constructor()方法的参数。
参数 类型 可空 可选 描述
context BaseAudioContext 这个新的BaseAudioContext 将与此ChannelMergerNode 关联
options ChannelMergerOptions ChannelMergerNode的可选初始参数值。

1.14.2. ChannelMergerOptions

dictionary ChannelMergerOptions : AudioNodeOptions {
unsigned long numberOfInputs = 6;
};
1.14.2.1. 字典ChannelMergerOptions 成员
numberOfInputs, 类型为unsigned long,默认值为6

ChannelMergerNode的输入数量。参见createChannelMerger()以获取此值的约束条件。

1.15. ChannelSplitterNode 接口

ChannelSplitterNode 用于更高级的应用,通常与ChannelMergerNode 一起使用。

属性 备注
numberOfInputs 1
numberOfOutputs 见备注 默认为 6,但可以由ChannelSplitterOptions.numberOfOutputs 或通过createChannelSplitternumberOfOutputs 字典的ChannelSplitterOptions 成员的值决定。
channelCount numberOfOutputs 具有channelCount 限制
channelCountMode "explicit" channelCountMode 限制
channelInterpretation "discrete" 具有channelInterpretation 限制
tail-time

此接口表示用于在路由图中访问音频流的各个通道的AudioNode。它有一个输入,并且其输出数量等于输入音频流中的通道数量。例如, 如果一个立体声输入连接到ChannelSplitterNode,则活跃输出的数量将为两个(一个来自左声道, 一个来自右声道)。总是有 N 个输出(由numberOfOutputs参数通过AudioContext方法createChannelSplitter()确定), 如果没有提供此值,默认为 6。任何不活跃的输出将输出静音,通常不会连接到任何东西。

channel splitter
ChannelSplitter 的图示

请注意,在此示例中,Splitter 不会解释通道标识(例如左、右等), 而是仅按输入顺序分割通道。

ChannelSplitterNode 的一个应用是进行“矩阵混音”, 其中希望对每个通道进行单独增益控制。

ChannelSplitterNode/ChannelSplitterNode

Firefox53+SafariNoneChrome55+
Opera42+Edge79+
Edge (Legacy)NoneIENone
Firefox for Android53+iOS SafariNoneChrome for Android55+Android WebView55+Samsung Internet6.0+Opera Mobile42+

ChannelSplitterNode

在所有当前的引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (Legacy)12+IENone
Firefox for Android25+iOS SafariYesChrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile14+
[Exposed=Window]
interface ChannelSplitterNode : AudioNode {
  constructor (BaseAudioContext context, optional ChannelSplitterOptions options = {});
};

1.15.1. 构造函数

ChannelSplitterNode(context, options)

当构造函数被调用时,传入一个BaseAudioContextc和一个选项对象option, 用户代理必须初始化 AudioNodethis,使用contextoptions作为参数。

ChannelSplitterNode.constructor()方法的参数。
参数 类型 可为空 可选 描述
context BaseAudioContext 此新的BaseAudioContext将与此ChannelSplitterNode关联
options ChannelSplitterOptions ChannelSplitterNode的可选初始参数值。

1.15.2. ChannelSplitterOptions

dictionary ChannelSplitterOptions : AudioNodeOptions {
unsigned long numberOfOutputs = 6;
};
1.15.2.1. 字典ChannelSplitterOptions成员
numberOfOutputs, 类型为unsigned long,默认值为6

ChannelSplitterNode的输出数量。 请参阅createChannelSplitter() 了解对此值的限制。

1.16. ConstantSourceNode 接口

ConstantSourceNode

Firefox52+Safari不支持Chrome56+
Opera43+Edge79+
Edge(旧版)不支持IE不支持
Firefox for Android52+iOS Safari不支持Chrome for Android56+Android WebView56+Samsung Internet6.0+Opera Mobile43+

此接口表示一个恒定音频源,其输出名义上是一个恒定值。它通常用作恒定源节点,并且可以通过自动化其offset或将另一个节点连接到它来像可构造的AudioParam一样使用。

该节点的单一输出由一个通道(单声道)组成。

属性 备注
numberOfInputs 0
numberOfOutputs 1
channelCount 2
channelCountMode "max"
channelInterpretation "speakers"
尾音时间

ConstantSourceNode/ConstantSourceNode

Firefox52+Safari不支持Chrome56+
Opera43+Edge79+
Edge(旧版)不支持IE不支持
Firefox for Android52+iOS Safari不支持Chrome for Android56+Android WebView56+Samsung Internet6.0+Opera Mobile43+
[Exposed=Window]
interface ConstantSourceNode : AudioScheduledSourceNode {
  constructor (BaseAudioContext context, optional ConstantSourceOptions options = {});
  readonly attribute AudioParam offset;
};

1.16.1. 构造函数

ConstantSourceNode(context, options)

当构造函数被调用时,使用BaseAudioContext context 和 一个选项对象 option,用户代理必须用contextoptions作为参数来初始化 AudioNode this

ConstantSourceNode.constructor() 方法的参数。
参数 类型 可为 null 可选 描述
context BaseAudioContext 新的 BaseAudioContext 将与此 ConstantSourceNode 相关联
options ConstantSourceOptions ConstantSourceNode 的可选初始参数值。

1.16.2. 属性

ConstantSourceNode/offset

Firefox52+Safari不支持Chrome56+
Opera不支持Edge79+
Edge(旧版)不支持IE不支持
Firefox for Android52+iOS Safari不支持Chrome for Android不支持Android WebView不支持Samsung Internet不支持Opera Mobile不支持

offset, 类型为 AudioParam, 只读

音频源的恒定值。

参数 备注
defaultValue 1
minValue most-negative-single-float 大约为 -3.4028235e38
maxValue most-positive-single-float 大约为 3.4028235e38
automationRate "a-rate"

1.16.3. ConstantSourceOptions

这指定了构造 ConstantSourceNode 时的选项。所有成员都是可选的; 如果未指定,将使用构造节点的正常默认值。

dictionary ConstantSourceOptions {
float offset = 1;
};
1.16.3.1. Dictionary ConstantSourceOptions 成员
offset, 类型为 float,默认值为 1

此节点的 offset AudioParam 的初始值。

1.17. ConvolverNode 接口

ConvolverNode

在所有当前引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (Legacy)12+IE不支持
Firefox for Android25+iOS Safari支持Chrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

此接口表示一个处理节点,该节点根据脉冲响应应用线性卷积效果。

属性 备注
numberOfInputs 1
numberOfOutputs 1
channelCount 2 参见channelCount 约束
channelCountMode "clamped-max" 参见channelCountMode 约束
channelInterpretation "speakers"
尾音时间 在没有输入的情况下,仍会输出非静音音频,持续时间为buffer的长度。

此节点的输入可以是单声道(1个频道)或立体声(2个频道),无法增加。来自多个频道的节点的连接将适当地降混音

此节点存在channelCount 约束channelCountMode 约束。这些约束确保节点的输入为单声道或立体声。

ConvolverNode/ConvolverNode

Firefox53+Safari不支持Chrome55+
Opera42+Edge79+
Edge(旧版)不支持IE不支持
Firefox for Android53+iOS Safari不支持Chrome for Android55+Android WebView55+Samsung Internet6.0+Opera Mobile42+
[Exposed=Window]
interface ConvolverNode : AudioNode {
  constructor (BaseAudioContext context, optional ConvolverOptions options = {});
  attribute AudioBuffer? buffer;
  attribute boolean normalize;
};

1.17.1. 构造函数

ConvolverNode(context, options)

当构造函数使用 BaseAudioContext context 和一个选项对象 options 调用时,执行以下步骤:

  1. 将属性 normalize 设置为disableNormalization值的反值。

  2. 如果 buffer 存在,将 buffer 属性设置为其值。

    注意:这意味着将根据normalize属性的值来规范化该buffer。

  3. o 成为新的 AudioNodeOptions 字典。

  4. 如果 channelCount 存在于options中,在o上设置与之相同的值。

  5. 如果 channelCountMode 存在于options中,在o上设置与之相同的值。

  6. 如果 channelInterpretation 存在于options中,在o上设置与之相同的值。

  7. 初始化 AudioNode this,参数为co

ConvolverNode.constructor() 方法的参数。
参数 类型 可空 可选 描述
context BaseAudioContext 此新的 BaseAudioContext 将与此新的 ConvolverNode 相关联。
options ConvolverOptions ConvolverNode 的可选初始参数值。

1.17.2. 属性

ConvolverNode/buffer

在所有当前引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (Legacy)12+IE不支持
Firefox for Android25+iOS Safari支持Chrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

buffer, 类型为 AudioBuffer, 可空

当设置此属性时,将使用此 buffernormalize属性的状态来配置ConvolverNode。此属性的初始值为null。

设置缓冲区属性时,同步执行以下步骤:
  1. 如果缓冲区的频道数 不是1、2、4,或者缓冲区的采样率 与其关联的BaseAudioContext的采样率不相同,必须抛出NotSupportedError

  2. 获取 AudioBuffer的内容。

注意:如果将buffer 设置为新缓冲区,音频可能会出现故障。如果这不符合预期,建议创建一个新的ConvolverNode来替换旧的,可能需要在两者之间进行交叉渐变。

注意:仅在输入有一个通道且缓冲区为单通道时,ConvolverNode 产生单声道输出。在所有其他情况下,输出为立体声。特别地,当缓冲区具有四个通道且输入有两个通道时,ConvolverNode 执行矩阵"真"立体声卷积。有关规范信息,请参阅通道配置图

ConvolverNode/normalize

在所有当前引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (Legacy)12+IE不支持
Firefox for Android25+iOS Safari支持Chrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

normalize, 类型为 boolean

控制设置 buffer 属性时,脉冲响应是否通过等功率规范化进行缩放。其默认值为true,以实现加载多种脉冲响应时更均匀的输出级别。如果将normalize设置为false,则卷积将根据脉冲响应进行线性卷积,而无需预处理/缩放。对此值的更改在下次设置buffer属性之前不会生效。

如果 normalize 属性为 false ,当 buffer 属性设置时,ConvolverNode 将根据ConvolverNode中缓冲区的精确脉冲响应进行线性卷积。

否则,如果在设置buffer属性时normalize 属性为 true,则ConvolverNode 将首先对buffer中的音频数据执行缩放 RMS 功率分析,以根据此算法计算normalizationScale值:

function calculateNormalizationScale(buffer) {  const GainCalibration = 0.00125;  const GainCalibrationSampleRate = 44100;  const MinPower = 0.000125;  // 通过 RMS 功率进行规范化。  const numberOfChannels = buffer.numberOfChannels;  const length = buffer.length;  let power = 0;  for (let i = 0; i < numberOfChannels; i++) {    let channelPower = 0;    const channelData = buffer.getChannelData(i);    for (let j = 0; j < length; j++) {      const sample = channelData[j];      channelPower += sample * sample;    }    power += channelPower;  }  power = Math.sqrt(power / (numberOfChannels * length));  // 防止意外过载。  if (!isFinite(power) || isNaN(power) || power < MinPower)    power = MinPower;  let scale = 1 / power;  // 校准以使感知音量与未处理音量相同。  scale *= GainCalibration;  // 缩放取决于采样率。  if (buffer.sampleRate)    scale *= GainCalibrationSampleRate / buffer.sampleRate;  // 真立体声补偿。  if (numberOfChannels == 4)    scale *= 0.5;  return scale;}

在处理期间,ConvolverNode 将使用此计算出的normalizationScale值,并将其乘以输入与脉冲响应(由buffer表示)处理后的线性卷积结果,生成最终输出。也可以使用任何数学等效操作,例如通过normalizationScale预乘输入,或通过normalizationScale预乘脉冲响应的一个版本。

1.17.3. ConvolverOptions

指定用于构造ConvolverNode的选项。所有成员都是可选的;如果未指定,则使用默认值。

dictionary ConvolverOptions : AudioNodeOptions {
AudioBuffer? buffer;
boolean disableNormalization = false;
};
1.17.3.1. 字典 ConvolverOptions 成员
buffer, 类型为 AudioBuffer, 可空

ConvolverNode所需的buffer。该buffer将根据disableNormalization的值进行规范化。

disableNormalization, 类型为 boolean,默认值为false

与此ConvolverNodenormalize属性的期望初始值相反。

1.17.4. 输入、脉冲响应和输出的通道配置

实现必须支持以下可允许的脉冲响应通道配置,以使用 ConvolverNode 实现1或2个通道的输入以获得各种混响效果。

如图所示,单通道卷积在单声道音频输入上操作,使用单声道脉冲响应,并生成单声道输出。图中的其他图片展示了单声道和立体声播放的支持情况,其中输入通道数为1或2,缓冲区中的通道数为1、2或4。希望使用更复杂和任意矩阵的开发人员可以使用ChannelSplitterNode,多个单通道ConvolverNodeChannelMergerNode

如果此节点未主动处理,则输出为单个静音通道。

注意:下图展示了主动处理时的输出情况。

混响矩阵
使用 ConvolverNode 时支持的输入和输出通道数可能性的图形表示。

1.18. DelayNode 接口

DelayNode

在所有当前引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (旧版)12+IE
Firefox for Android25+iOS Safari支持Chrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

延迟线是音频应用中的一个基本构建块。此接口是一个具有单一输入和单一输出的AudioNode

属性 备注
numberOfInputs 1
numberOfOutputs 1
channelCount 2
channelCountMode "max"
channelInterpretation "speakers"
tail-time 在节点的maxDelayTime内,继续输出非静音音频,即使输入为零。

输出的声道数总是等于输入的声道数。

它通过一定的延迟量来延迟输入的音频信号。具体来说,在每个时间点t,输入信号input(t),延迟时间delayTime(t)和输出信号output(t),输出将会是output(t) = input(t - delayTime(t))。默认的delayTime为0秒(无延迟)。

DelayNode的输入的声道数发生变化(从而也改变输出的声道数)时,可能会有尚未被节点输出的延迟音频样本,这些样本是其内部状态的一部分。如果这些样本在之前以不同的声道数接收,则它们必须在与新接收的输入组合之前被上混合或下混合,以便所有内部延迟线混合使用单一的现行声道布局。

注意: 根据定义,DelayNode引入的音频处理延迟等于延迟量。

DelayNode/DelayNode

Firefox53+Safari不支持Chrome55+
Opera42+Edge79+
Edge (旧版)不支持IE不支持
Firefox for Android53+iOS Safari不支持Chrome for Android55+Android WebView55+Samsung Internet6.0+Opera Mobile42+
[Exposed=Window]
interface DelayNode : AudioNode {
  constructor (BaseAudioContext context, optional DelayOptions options = {});
  readonly attribute AudioParam delayTime;
};

1.18.1. 构造函数

DelayNode(context, options)

当构造函数使用BaseAudioContext c和一个选项对象option调用时,用户代理必须使用contextoptions作为参数,初始化AudioNode this

参数DelayNode.constructor()方法的参数。
参数 类型 可为null 可选 描述
context BaseAudioContext 这个新的DelayNode 将与其关联。
options DelayOptions DelayNode 的可选初始参数值。

1.18.2. 属性

DelayNode/delayTime

在所有当前引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (Legacy)12+IE
Firefox for Android25+iOS SafariChrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

delayTime, 类型为 AudioParam, 只读

一个AudioParam 对象,表示要应用的延迟量(以秒为单位)。默认为0(无延迟)。最小值为0,最大值由maxDelayTime 参数或DelayOptions 字典的成员constructor确定。

如果DelayNode循环的一部分, 则delayTime 属性的值限制为至少一个渲染量

1.18.3. DelayOptions

这指定了用于构造DelayNode的选项。 所有成员都是可选的;如果没有给出,节点将使用正常的默认值构造。

dictionary DelayOptions : AudioNodeOptions {
double maxDelayTime = 1;
double delayTime = 0;
};
1.18.3.1. 字典DelayOptions 成员
delayTime, 类型为 double,默认值为0

节点的初始延迟时间。

maxDelayTime, 类型为 double,默认值为1

节点的最大延迟时间。参见createDelay(maxDelayTime) 的约束。

1.18.4. 处理

DelayNode 具有一个内部缓冲区,保存delayTime 秒的音频。

DelayNode 的处理分为两部分:写入延迟线和从延迟线读取。这是通过两个内部AudioNode(不提供给作者,只是为了简化节点内部工作原理的描述)完成的。两者都是从DelayNode创建的。

创建DelayWriter对象意味着创建一个具有相同接口的对象DelayNode, 并将输入音频写入DelayNode的内部缓冲区。 它具有与创建它的DelayNode 相同的输入连接。

创建DelayReader对象意味着创建一个具有相同接口的对象DelayNode, 并可以从DelayNode的内部缓冲区读取音频数据。 它连接到与创建它的AudioNode相同的连接。 DelayReader是一个源节点

在处理输入缓冲区时,DelayWriter必须将音频写入DelayNode的内部缓冲区。

在生成输出缓冲区时,DelayReader必须准确输出DelayWriter在相应delayTime 秒前写入的音频。

注意:这意味着通道数量的更改将在延迟时间之后反映出来。

1.19. DynamicsCompressorNode 接口

DynamicsCompressorNode 是一个AudioNode 处理器,用于实现动态压缩效果。

动态压缩在音乐制作和游戏音频中非常常见。它降低信号中最响部分的音量,并提高最柔部分的音量。整体上可以实现更响亮、更丰富、更饱满的声音。在游戏和音乐应用中,多个单独声音同时播放时控制整体信号级别并帮助避免音频输出到扬声器时产生削波(失真)尤为重要。

属性 备注
numberOfInputs 1
numberOfOutputs 1
channelCount 2 channelCount 约束
channelCountMode "clamped-max" channelCountMode 约束
channelInterpretation "speakers"
tail-time 此节点具有tail-time,因此此节点在输入为零时由于预读延迟仍继续输出非静音音频。

DynamicsCompressorNode/DynamicsCompressorNode

Firefox53+SafariChrome55+
Opera42+Edge79+
Edge (Legacy)IE
Firefox for Android53+iOS SafariChrome for Android55+Android WebView55+Samsung Internet6.0+Opera Mobile42+

DynamicsCompressorNode

在所有当前引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (Legacy)12+IE
Firefox for Android25+iOS SafariChrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile14+
[Exposed=Window]
interface DynamicsCompressorNode : AudioNode {
  constructor (BaseAudioContext context,
               optional DynamicsCompressorOptions options = {});
  readonly attribute AudioParam threshold;
  readonly attribute AudioParam knee;
  readonly attribute AudioParam ratio;
  readonly attribute float reduction;
  readonly attribute AudioParam attack;
  readonly attribute AudioParam release;
};

1.19.1. 构造函数

DynamicsCompressorNode(context, options)

当构造函数使用BaseAudioContext c和一个选项对象option调用时,用户代理必须使用contextoptions作为参数初始化AudioNode this

[[internal reduction]]this上的一个私有槽,用于保存以分贝为单位的浮点数。将[[internal reduction]] 设置为0.0。

参数DynamicsCompressorNode.constructor() 方法的参数。
参数 类型 可为null 可选 描述
context BaseAudioContext 这个新的BaseAudioContext 将与其关联的DynamicsCompressorNode
options DynamicsCompressorOptions DynamicsCompressorNode的可选初始参数值。

1.19.2. 属性

DynamicsCompressorNode/attack

在所有当前引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (Legacy)12+IE
Firefox for Android25+iOS SafariChrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

attack, 类型为 AudioParam,只读

减少 10dB 所需的时间(以秒为单位)。

DynamicsCompressorNode/knee

在所有当前引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (Legacy)12+IE
Firefox for Android25+iOS SafariChrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

knee, 类型为 AudioParam,只读

一个分贝值,表示阈值以上的范围,在该范围内曲线平滑过渡到“压缩”部分。

DynamicsCompressorNode/ratio

在所有当前引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (Legacy)12+IE
Firefox for Android25+iOS SafariChrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

ratio, 类型为 AudioParam,只读

输入信号中变化 1 dB 所需的 dB 变化量。

DynamicsCompressorNode/reduction

在所有当前引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (Legacy)12+IE
Firefox for Android25+iOS SafariChrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

reduction, 类型为 float,只读

用于计量目的的只读分贝值,表示压缩器当前对信号应用的增益减少量。如果没有信号输入,值将为 0(无增益减少)。当读取此属性时,返回私有槽 [[internal reduction]] 的值。

DynamicsCompressorNode/release

在所有当前引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (Legacy)12+IE
Firefox for Android25+iOS SafariChrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

release, 类型为 AudioParam,只读

增加 10dB 所需的时间(以秒为单位)。

DynamicsCompressorNode/threshold

在所有当前引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (Legacy)12+IE
Firefox for Android25+iOS SafariChrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

threshold, 类型为 AudioParam,只读

开始生效的压缩阈值(以分贝为单位)。

1.19.3. DynamicsCompressorOptions

此选项指定用于构建 DynamicsCompressorNode 的配置。 所有成员都是可选的;如果未指定,则在构建节点时使用默认值。

dictionary DynamicsCompressorOptions : AudioNodeOptions {
  float attack = 0.003;
  float knee = 30;
  float ratio = 12;
  float release = 0.25;
  float threshold = -24;
};
1.19.3.1. 字典 DynamicsCompressorOptions 成员
attack, 类型为 float,默认值为 0.003

attack AudioParam 的初始值。

knee, 类型为 float,默认值为 30

knee AudioParam 的初始值。

ratio, 类型为 float,默认值为 12

ratio AudioParam 的初始值。

release, 类型为 float,默认值为 0.25

release AudioParam 的初始值。

threshold, 类型为 float,默认值为 -24

threshold AudioParam 的初始值。

1.19.4. 处理

动态压缩可以通过多种方式实现。DynamicsCompressorNode 实现的动态处理器具有以下特性:

图形上,这样的曲线看起来可能是这样的:

压缩曲线的图形表示
一个典型的压缩曲线,显示了膝盖部分(软或硬)以及阈值。

在内部,DynamicsCompressorNode 通过结合其他 AudioNode 以及一个特殊算法来描述,以计算增益减少值。

以下 AudioNode 图形在内部使用,inputoutput 分别是输入和输出 AudioNodecontextBaseAudioContext 对于此 DynamicsCompressorNode,以及一个新类,EnvelopeFollower,它实例化了一个特殊的对象,该对象表现为一个 AudioNode,如下所述:

const delay = new DelayNode(context, {delayTime: 0.006});
const gain = new GainNode(context);
const compression = new EnvelopeFollower();

input.connect(delay).connect(gain).connect(output);
input.connect(compression).connect(gain.gain);
DynamicCompressorNode 使用的内部图形
作为 DynamicsCompressorNode 处理算法一部分使用的内部 AudioNode 图形。

注意:这实现了预延迟和减少增益的应用。

以下算法描述了一个 EnvelopeFollower 对象执行的处理,以应用于输入信号以产生增益减少值。一个 EnvelopeFollower 有两个持有浮点值的槽。这些值在调用此算法时会持续存在。

以下算法允许为每个输入样本确定一个 reduction gain 值,用于音频渲染量子。
  1. attackrelease 具有在处理时采样的 attackrelease 的值,分别乘以此 BaseAudioContext 的采样率。

  2. detector average 为槽 [[detector average]] 的值。

  3. compressor gain 为槽 [[compressor gain]] 的值。

  4. 对于要处理的渲染量子的每个 input 样本,执行以下步骤:

    1. 如果 input 的绝对值小于 0.0001,则将 attenuation 设为 1.0。否则,设 shaped input 为将 压缩曲线 应用于 input 的绝对值所得的值。设 attenuationshaped input 除以 input 的绝对值。

    2. releasingtrue 如果 attenuation 大于 compressor gain,否则为 false

    3. detector rate 为将 检测器曲线 应用于 attenuation 的结果。

    4. attenuation 中减去 detector average,并将结果乘以 detector rate。将这个新结果加到 detector average 中。

    5. detector average 限制为最大值 1.0。

    6. envelope rate 为基于 attackrelease 值的计算信封速率的结果。

    7. 如果 releasingtrue,则将 compressor gain 设为 compressor gainenvelope rate 的乘积,并将其限制为最大值 1.0。

    8. 否则,如果 releasingfalse,则设 gain incrementdetector average 减去 compressor gain。将 gain increment 乘以 envelope rate,并将结果加到 compressor gain 中。

    9. 计算 reduction gaincompressor gain 乘以计算补偿增益 的返回值。

    10. 计算 metering gainreduction gain,并转换为分贝

  5. [[compressor gain]] 设为 compressor gain

  6. [[detector average]] 设为 detector average

  7. 原子 设置内部槽 [[internal reduction]]metering gain 的值。

    注意:此步骤使得计量增益在每个块处理结束时更新一次。

补偿增益是一个固定的增益阶段,只取决于压缩器的比率、膝盖和阈值参数,而不是输入信号。这里的目的是增加压缩器的输出电平,使其与输入电平相当。

计算补偿增益 意味着执行以下步骤:
  1. full range gain 为将 压缩曲线 应用于值 1.0 时返回的值。

  2. full range makeup gainfull range gain 的倒数。

  3. 返回 full range makeup gain 的 0.6 次方的结果。

计算信封速率 是通过将 compressor gaindetector average 的比率应用于一个函数来完成的。用户代理可以选择信封函数的形状。但是,此函数必须满足以下约束:

此操作返回将此函数应用于 compressor gaindetector average 的比率所计算的值。

检测器曲线 应用于攻击或释放时的变化速率允许实现 自适应释放。它是一个函数,必须满足以下约束:

注意:允许例如实现一个压缩器,该压缩器执行 自适应释放,即压缩越大,释放越快,或者具有不同形状的攻击和释放曲线。

压缩曲线 应用于一个值意味着计算将该样本传递给一个函数时的值,并返回计算结果。此函数必须满足以下特性:
  1. thresholdknee 具有在处理此块时采样的 thresholdknee 的值,并转换为线性单位

  2. 计算 thresholdknee 之和,并转换为线性单位

  3. knee end threshold 为此和的值,转换为线性单位

  4. ratioratio 的值,在处理此块时采样(作为 k-rate 参数)。

  5. 该函数在达到线性 threshold 值之前是恒等的(即,\(f(x) = x\))。

  6. thresholdknee end threshold,用户代理可以选择曲线形状。整个函数必须是单调递增的和连续的。

    注意:如果 knee 为 0,则 DynamicsCompressorNode 被称为硬膝压缩器。

  7. 此函数在线性 threshold 和软膝之后是线性的,基于 ratio 值(即,\(f(x) = \frac{1}{ratio} \cdot x \))。

将值 \(v\) 从线性增益单位转换为分贝 意味着执行以下步骤:
  1. 如果 \(v\) 等于 0,则返回 -1000。

  2. 否则,返回 \( 20 \, \log_{10}{v} \)。

将值 \(v\) 从分贝转换为线性增益单位 意味着返回 \(10^{v/20}\)。

1.20. GainNode 接口

改变音频信号的增益是音频应用中的基本操作。此接口是一个具有单一输入和单一输出的 AudioNode

属性 备注
numberOfInputs 1
numberOfOutputs 1
channelCount 2
channelCountMode "max"
channelInterpretation "speakers"
尾部时间

GainNode 的输入数据的每个通道的每个样本必须乘以 计算值,即 gain 属性的 AudioParam

GainNode/GainNode

Firefox53+SafariChrome55+
Opera42+Edge79+
Edge (旧版)IE
Firefox for Android53+iOS SafariChrome for Android55+Android WebView55+Samsung Internet6.0+Opera Mobile42+

GainNode

在所有当前引擎中可用。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (旧版)12+IE
Firefox for Android25+iOS SafariChrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile14+
[Exposed=Window]
interface GainNode : AudioNode {
  constructor (BaseAudioContext context, optional GainOptions options = {});
  readonly attribute AudioParam gain;
};

1.20.1. 构造函数

GainNode(context, options)

当构造函数以 BaseAudioContextcontext 和选项对象 options 被调用时,用户代理必须 初始化 AudioNode this,并将 contextoptions 作为参数传递。

GainNode.constructor() 方法的参数。
参数 类型 可空 可选 描述
context BaseAudioContext 此新的 BaseAudioContext 将与此 GainNode 关联
options GainOptions GainNode 的可选初始参数值。

1.20.2. 属性

GainNode/gain

在所有当前引擎中可用。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (旧版)12+IE
Firefox for Android25+iOS SafariChrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

gain类型为 AudioParam,只读

表示要应用的增益值。

参数 备注
defaultValue 1
minValue 最小负浮点数 约为 -3.4028235e38
maxValue 最大正浮点数 约为 3.4028235e38
automationRate "a-rate"

1.20.3. GainOptions

此处指定了用于构建 GainNode 的选项。 所有成员都是可选的;如果未指定,则在构建节点时使用正常默认值。

dictionary GainOptions : AudioNodeOptions {
  float gain = 1.0;
};
1.20.3.1. 字典 GainOptions 成员
gain类型为 float,默认值为 1.0

gain AudioParam 的初始增益值。

1.21. IIRFilterNode 接口

IIRFilterNode 是一个 AudioNode 处理器,用于实现通用的 IIR 滤波器。通常情况下,最好使用 BiquadFilterNode 来实现高阶滤波器,原因如下:

然而,无法创建奇数阶滤波器,因此如果需要此类滤波器或不需要自动化,则 IIR 滤波器可能适合使用。

一旦创建,IIR 滤波器的系数将无法更改。

属性 备注
numberOfInputs 1
numberOfOutputs 1
channelCount 2
channelCountMode "max"
channelInterpretation "speakers"
尾时 继续输出非静音音频,而输入为零。由于这是一个 IIR 滤波器,滤波器会永远产生非零输入,但实际上,可以在某些有限时间内将输出限制在接近零的范围内。实际时间取决于滤波器系数。

输出的通道数始终等于输入的通道数。

IIRFilterNode/IIRFilterNode

Firefox53+SafariChrome55+
Opera42+Edge79+
Edge (旧版)IE
Firefox for Android53+iOS SafariChrome for Android55+Android WebView55+Samsung Internet6.0+Opera Mobile42+

IIRFilterNode

Firefox50+SafariChrome49+
Opera36+Edge79+
Edge (旧版)18IE
Firefox for Android50+iOS SafariChrome for Android49+Android WebView49+Samsung Internet5.0+Opera Mobile36+
[Exposed=Window]
interface IIRFilterNode : AudioNode {
  constructor (BaseAudioContext context, IIRFilterOptions options);
  undefined getFrequencyResponse (Float32Array frequencyHz,
                                  Float32Array magResponse,
                                  Float32Array phaseResponse);
};

1.21.1. 构造函数

IIRFilterNode(context, options)

当构造函数使用 BaseAudioContext c 和 一个选项对象 option 调用时,用户代理必须使用 contextoptions 作为参数初始化 AudioNode this

IIRFilterNode.constructor() 方法提供的参数。
参数 类型 可空 可选 描述
context BaseAudioContext 此新的 BaseAudioContext 将与此新的 IIRFilterNode 关联
options IIRFilterOptions IIRFilterNode 的初始参数值。

1.21.2. 方法

IIRFilterNode/getFrequencyResponse

Firefox50+SafariChrome49+
Opera36+Edge79+
Edge (旧版)14+IE
Firefox for Android50+iOS SafariChrome for Android49+Android WebView49+Samsung Internet5.0+Opera Mobile36+

getFrequencyResponse(frequencyHz, magResponse, phaseResponse)

根据当前的滤波器参数设置,同步计算指定频率的频率响应。三个参数必须是长度相同的 Float32Array, 否则必须抛出 InvalidAccessError

IIRFilterNode.getFrequencyResponse() 方法提供的参数。
参数 类型 可空 可选 描述
frequencyHz Float32Array 此参数指定一个频率数组,单位为赫兹,响应值将在这些频率处计算。
magResponse Float32Array 此参数指定一个输出数组,用于接收线性幅度响应值。 如果 frequencyHz 参数中的某个值不在 [0, sampleRate/2] 范围内, 其中 sampleRatesampleRate 属性的值 AudioContext, 则 magResponse 数组中相同索引处的相应值必须为 NaN
phaseResponse Float32Array 此参数指定一个输出数组,用于接收相位响应值,单位为弧度。 如果 frequencyHz 参数中的某个值不在 [0; sampleRate/2] 范围内, 其中 sampleRatesampleRate 属性的值 AudioContext, 则 phaseResponse 数组中相同索引处的相应值必须为 NaN
返回类型: undefined

1.21.3. IIRFilterOptions

IIRFilterOptions 字典用于指定 IIRFilterNode 的滤波器系数。

dictionary IIRFilterOptions : AudioNodeOptions {
  required sequence<double> feedforward;
  required sequence<double> feedback;
};
1.21.3.1. 字典 IIRFilterOptions 成员
feedforward, 类型为 sequence<double>

IIRFilterNode 的前馈系数。此成员是必需的。有关其他约束,请参阅 feedforward 参数 createIIRFilter()

feedback, 类型为 sequence<double>

IIRFilterNode 的反馈系数。此成员是必需的。有关其他约束,请参阅 feedback 参数 createIIRFilter()

1.21.4. 滤波器定义

令 \(b_m\) 为 feedforward 系数,\(a_n\) 为 feedback 系数,这些系数由 createIIRFilter()IIRFilterOptions 字典指定。则通用 IIR 滤波器的传递函数由下式给出:

$$
  H(z) = \frac{\sum_{m=0}^{M} b_m z^{-m}}{\sum_{n=0}^{N} a_n z^{-n}}
$$

其中 \(M + 1\) 是 \(b\) 数组的长度,\(N + 1\) 是 \(a\) 数组的长度。系数 \(a_0\) 必须不为 0(参见 feedback 参数 createIIRFilter())。 至少有一个 \(b_m\) 必须为非零值(参见 feedforward 参数 createIIRFilter())。

等效地,时域方程为:

$$
  \sum_{k=0}^{N} a_k y(n-k) = \sum_{k=0}^{M} b_k x(n-k)
$$

初始滤波器状态为全零状态。

注意: 用户代理可能会发出警告,通知用户滤波器状态中出现了 NaN 值。这通常表明滤波器不稳定。

1.22. MediaElementAudioSourceNode 接口

此接口表示来自 audiovideo 元素的音频源。

属性 注释
numberOfInputs 0
numberOfOutputs 1
尾时间 参考

输出的声道数对应于由 HTMLMediaElement 引用的媒体的声道数。因此,更改媒体元素的 src 属性可以更改此节点输出的声道数。

如果 HTMLMediaElement 的采样率与关联的 AudioContext 的采样率不同,则 HTMLMediaElement 的输出必须重新采样以匹配上下文的 采样率

给定 MediaElementAudioSourceNode 使用 HTMLMediaElement 创建时,使用 AudioContextcreateMediaElementSource() 方法或 mediaElement 成员来构造 MediaElementAudioSourceOptions 字典。

单一输出的声道数等于作为参数传递给 createMediaElementSource()HTMLMediaElement 引用的音频的声道数,或者如果 HTMLMediaElement 没有音频,则为 1。

在创建 MediaElementAudioSourceNode 后,HTMLMediaElement 必须以相同的方式运行,除了 渲染的音频将不再直接听到,而是作为通过路由图连接的 MediaElementAudioSourceNode 的结果听到。因此,暂停、查找、音量、src 属性的更改以及 HTMLMediaElement 的其他方面必须与未使用 MediaElementAudioSourceNode 时的行为相同。

const mediaElement = document.getElementById('mediaElementID');
const sourceNode = context.createMediaElementSource(mediaElement);
sourceNode.connect(filterNode);

MediaElementAudioSourceNode/MediaElementAudioSourceNode

Firefox53+SafariChrome55+
Opera42+Edge79+
Edge(旧版)IE
Firefox for Android53+iOS SafariChrome for Android55+Android WebView55+Samsung Internet6.0+Opera Mobile42+

MediaElementAudioSourceNode

在所有当前的引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge(旧版)12+IE
Firefox for Android25+iOS Safari6+Chrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile14+
[Exposed=Window]
interface MediaElementAudioSourceNode : AudioNode {
  constructor (AudioContext context, MediaElementAudioSourceOptions options);
  [SameObject] readonly attribute HTMLMediaElement mediaElement;
};

1.22.1. 构造函数

MediaElementAudioSourceNode(context, options)
  1. 初始化 AudioNode this, 使用 contextoptions 作为参数。

MediaElementAudioSourceNode.constructor() 方法的参数。
参数 类型 可空 可选 描述
context AudioContext 此新的 AudioContext 将与此 MediaElementAudioSourceNode 关联。
options MediaElementAudioSourceOptions MediaElementAudioSourceNode 的初始参数值。

1.22.2. 属性

MediaElementAudioSourceNode/mediaElement

在所有当前的引擎中。

Firefox70+Safari6+ChromeYes
OperaYesEdgeYes
Edge(旧版)IE
Firefox for AndroidiOS Safari6+Chrome for AndroidYesAndroid WebViewYesSamsung InternetYesOpera MobileYes

mediaElement, 类型为 HTMLMediaElement,只读

在构建此 MediaElementAudioSourceNode 时使用的 HTMLMediaElement

1.22.3. MediaElementAudioSourceOptions

这指定了构建 MediaElementAudioSourceNode 时使用的选项。

dictionary MediaElementAudioSourceOptions {
  required HTMLMediaElement mediaElement;
};
1.22.3.1. 字典 MediaElementAudioSourceOptions 成员
mediaElement, 类型为 HTMLMediaElement

将被重新路由的媒体元素。此项必须指定。

1.22.4. MediaElementAudioSourceNode 与跨源资源的安全性

HTMLMediaElement 允许跨源资源的播放。由于 Web Audio 允许检查资源的内容(例如,使用 MediaElementAudioSourceNode 以及 AudioWorkletNodeScriptProcessorNode 来读取样本),如果一个源的脚本检查来自另一个源的资源的内容,可能会发生信息泄露。

为防止这种情况,如果使用 HTMLMediaElement 创建 MediaElementAudioSourceNode,并且执行 fetch 算法 将资源标记为 CORS 跨源,则 MediaElementAudioSourceNode 必须输出 静音 而不是正常输出。

1.23. MediaStreamAudioDestinationNode 接口

此接口是表示一个 MediaStream 的音频终端,具有单个 MediaStreamTrack,其 kind"audio"。该 MediaStream 是在创建节点时创建的,并且可以通过 stream 属性访问。此流可以像通过 getUserMedia() 获取的 MediaStream 一样使用,例如,可以通过 RTCPeerConnection(如 [webrtc] 中描述的 addStream() 方法)发送给远程对等方。

属性 注释
numberOfInputs 1
numberOfOutputs 0
channelCount 2
channelCountMode "explicit"
channelInterpretation "speakers"
尾音时间

输入的声道数默认是 2(立体声)。

MediaStreamAudioDestinationNode/MediaStreamAudioDestinationNode

Firefox53+SafariChrome55+
Opera42+Edge79+
Edge(旧版)IE
Firefox for Android53+iOS SafariChrome for Android55+Android WebView55+Samsung Internet6.0+Opera Mobile42+

MediaStreamAudioDestinationNode

在所有当前的引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge(旧版)18IE
Firefox for Android25+iOS Safari6+Chrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile14+
[Exposed=Window]
interface MediaStreamAudioDestinationNode : AudioNode {
  constructor (AudioContext context, optional AudioNodeOptions options = {});
  readonly attribute MediaStream stream;
};

1.23.1. 构造函数

MediaStreamAudioDestinationNode(context, options)
  1. 初始化 AudioNode this,将 contextoptions 作为参数。

MediaStreamAudioDestinationNode.constructor() 方法的参数。
参数 类型 可空 可选 描述
context AudioContext 此新 BaseAudioContext 将与之关联的 MediaStreamAudioDestinationNode
options AudioNodeOptions MediaStreamAudioDestinationNode 的可选初始参数值。

1.23.2. 属性

MediaStreamAudioDestinationNode/stream

在所有当前的引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge(旧版)18IE
Firefox for Android25+iOS Safari6+Chrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

stream, 类型为 MediaStream,只读

包含一个与节点本身具有相同声道数且 kind 属性值为 "audio" 的单个 MediaStreamTrackMediaStream

1.24. MediaStreamAudioSourceNode 接口

此接口表示来自 MediaStream 的音频源。

属性 备注
numberOfInputs 0
numberOfOutputs 1
尾部时间 参考

输出通道的数量与 MediaStreamTrack 的通道数量相对应。当 MediaStreamTrack 结束时,该 AudioNode 输出一个通道的静音。

如果 MediaStreamTrack 的采样率与关联的 AudioContext 的采样率不同,则 MediaStreamTrack 的输出将被重采样以匹配该上下文的 采样率

MediaStreamAudioSourceNode

在所有当前的引擎中。

Firefox25+Safari11+Chrome23+
Opera15+Edge79+
Edge(旧版)12+IE
Firefox for Android25+iOS Safari11+Chrome for AndroidAndroid WebView37+Samsung InternetOpera Mobile14+
[Exposed=Window]
interface MediaStreamAudioSourceNode : AudioNode {
  constructor (AudioContext context, MediaStreamAudioSourceOptions options);
  [SameObject] readonly attribute MediaStream mediaStream;
};

1.24.1. 构造函数

MediaStreamAudioSourceNode/MediaStreamAudioSourceNode

Firefox53+SafariChrome55+
Opera42+Edge79+
Edge(旧版)IE
Firefox for Android53+iOS SafariChrome for Android55+Android WebView55+Samsung Internet6.0+Opera Mobile42+

MediaStreamAudioSourceNode(context, options)

  1. 如果 mediaStream 成员在 options 中没有引用至少包含一个 MediaStreamMediaStreamTrack,且其 kind 属性的值为 "audio",则抛出 InvalidStateError 并中止这些步骤。否则,令此流为 inputStream

  2. tracksinputStream 中所有 MediaStreamTrack 的列表,并且其 kind"audio"

  3. 根据 id 属性使用代码单元顺序对 tracks 中的元素进行排序。

  4. 初始化 AudioNode this,并使用 contextoptions 作为参数。

  5. 在此 MediaStreamAudioSourceNode 上设置一个内部槽 [[input track]],该槽为 tracks 的第一个元素。此元素即为此 MediaStreamAudioSourceNode 的输入音频。

构造后,对传递给构造函数的 MediaStream 的任何更改不会影响该 AudioNode 的底层输出。

[[input track]] 仅用于保存对 MediaStreamTrack 的引用。

注意: 这意味着,当从传递给此构造函数的 MediaStreamAudioSourceNodeMediaStream 中移除由构造函数选择的音轨时,MediaStreamAudioSourceNode 仍将从同一音轨获取输入。

注意: 出于历史原因,选择输出音轨的行为是任意的。可以使用 MediaStreamTrackAudioSourceNode 来明确指定要用作输入的音轨。

MediaStreamAudioSourceNode 构造方法的参数。
参数 类型 可空 可选 描述
context AudioContext 此新的 AudioContext 将与 MediaStreamAudioSourceNode 相关联。
options MediaStreamAudioSourceOptions MediaStreamAudioSourceNode 的初始参数值。

1.24.2. 属性

MediaStreamAudioSourceNode/mediaStream

在所有当前的引擎中。

Firefox70+Safari11+Chrome23+
OperaEdge79+
Edge(旧版)IE
Firefox for AndroidiOS Safari11+Chrome for AndroidAndroid WebView37+Samsung InternetOpera Mobile

mediaStream 类型为 MediaStream,只读

用于构造此 MediaStreamMediaStreamAudioSourceNode

1.24.3. MediaStreamAudioSourceOptions

此选项指定用于构造 MediaStreamAudioSourceNode 的参数。

MediaStreamAudioSourceOptions

在所有当前的引擎中。

Firefox53+Safari6+Chrome55+
Opera15+Edge79+
Edge(旧版)18IE
Firefox for Android53+iOS SafariChrome for Android55+Android WebView55+Samsung Internet6.0+Opera Mobile14+
dictionary MediaStreamAudioSourceOptions {
  required MediaStream mediaStream;
};
1.24.3.1. 字典 MediaStreamAudioSourceOptions 成员

MediaStreamAudioSourceOptions/mediaStream

Firefox53+SafariChrome55+
OperaEdge79+
Edge(旧版)IE
Firefox for Android53+iOS SafariChrome for Android55+Android WebView55+Samsung Internet6.0+Opera Mobile

mediaStream 类型为 MediaStream

将作为音源的媒体流。此项必须指定。

1.25. MediaStreamTrackAudioSourceNode 接口

此接口表示来自 MediaStreamTrack 的音频源。

属性 备注
numberOfInputs 0
numberOfOutputs 1
尾声时间 参考

输出通道的数量对应于 mediaStreamTrack 的通道数量。

如果 MediaStreamTrack 的采样率 与关联的 AudioContext 的采样率不同, 则 mediaStreamTrack 的输出 会被重新采样以匹配上下文的 采样率

MediaStreamTrackAudioSourceNode

仅在一个当前引擎中可用。

Firefox68+SafariChrome
OperaEdge
Edge(旧版)IE
Firefox for Android68+iOS SafariChrome for AndroidAndroid WebViewSamsung InternetOpera Mobile
[Exposed=Window]
interface MediaStreamTrackAudioSourceNode : AudioNode {
  constructor (AudioContext context, MediaStreamTrackAudioSourceOptions options);
};

1.25.1. 构造函数

MediaStreamTrackAudioSourceNode/MediaStreamTrackAudioSourceNode

仅在一个当前引擎中可用。

Firefox68+SafariChrome
OperaEdge
Edge(旧版)IE
Firefox for Android68+iOS SafariChrome for AndroidAndroid WebViewSamsung InternetOpera Mobile

MediaStreamTrackAudioSourceNode(context, options)

  1. 如果 mediaStreamTrackkind 属性不是 "audio",抛出 InvalidStateError 并终止这些步骤。

  2. 初始化 AudioNode this,使用 contextoptions 作为参数。

MediaStreamTrackAudioSourceNode.constructor() 方法的参数。
参数 类型 可空 可选 描述
context AudioContext 此新 AudioContext 将与之关联的 MediaStreamTrackAudioSourceNode
options MediaStreamTrackAudioSourceOptions MediaStreamTrackAudioSourceNode 的初始参数值。

1.25.2. MediaStreamTrackAudioSourceOptions

此项指定构建 MediaStreamTrackAudioSourceNode 的选项。 此项为必需项。

MediaStreamTrackAudioSourceOptions

仅在一个当前引擎中可用。

Firefox68+SafariChrome
OperaEdge
Edge(旧版)IE
Firefox for Android68+iOS SafariChrome for AndroidAndroid WebViewSamsung InternetOpera Mobile
dictionary MediaStreamTrackAudioSourceOptions {
  required MediaStreamTrack mediaStreamTrack;
};
1.25.2.1. 字典 MediaStreamTrackAudioSourceOptions 成员

MediaStreamTrackAudioSourceOptions/mediaStreamTrack

仅在一个当前引擎中可用。

Firefox68+SafariChrome
OperaEdge
Edge(旧版)IE
Firefox for Android68+iOS SafariChrome for AndroidAndroid WebViewSamsung InternetOpera Mobile

mediaStreamTrack, 类型为 MediaStreamTrack

将作为源的媒体流轨道。如果该 MediaStreamTrackkind 属性不是 "audio",则必须抛出 InvalidStateError

1.26. 一个 OscillatorNode 接口

OscillatorNode 代表一个生成周期波形的音频源。它可以设置为一些常用的波形。此外,还可以通过使用PeriodicWave对象来设置为任意周期波形。

振荡器是音频合成中的常见基础构建块。OscillatorNode将按照start() 方法指定的时间开始发出声音。

从数学上讲,连续时间周期波形在频域中可能包含非常高(或无限高)的频率信息。当此波形以特定采样率采样为离散时间数字音频信号时,必须小心丢弃(滤除)高于奈奎斯特频率的高频信息,然后再将波形转换为数字形式。如果不这样做,高于奈奎斯特频率的频率将作为镜像折叠回低于奈奎斯特频率的频率。在许多情况下,这会导致可听的瑕疵。这是音频DSP的基本且公认的原理。

实现可能采用几种实际方法来避免这种混叠。无论采用哪种方法,理想化的离散时间数字音频信号在数学上是定义良好的。实现的权衡在于实现成本(以CPU使用率为准)与达到此理想的保真度之间的平衡。

可以预期,实现过程中将采取一些措施来实现这一理想,但在低端硬件上考虑质量较低、成本较低的方法也是合理的。

frequencydetune都是a-rate参数,并且形成了一个复合参数。它们共同用于确定computedOscFrequency值:

computedOscFrequency(t) = frequency(t) * pow(2, detune(t) / 1200)

OscillatorNode在每个时刻的瞬时相位是computedOscFrequency的定积分,假设节点的确切启动时间相位角为零。其名义范围为 [-奈奎斯特频率, 奈奎斯特频率]。

该节点的单个输出由一个通道(单声道)组成。

属性 备注
numberOfInputs 0
numberOfOutputs 1
channelCount 2
channelCountMode "max"
channelInterpretation "speakers"
尾时间
enum OscillatorType {
  "sine",
  "square",
  "sawtooth",
  "triangle",
  "custom"
};
枚举描述
"sine" 一个正弦波
"square" 一个占空比为0.5的方波
"sawtooth" 一个锯齿波
"triangle" 一个三角波
"custom" 一个自定义周期波

OscillatorNode

在所有当前引擎中。

Firefox25+Safari6+Chrome20+
Opera15+Edge79+
Edge (Legacy)12+IE
Firefox for Android25+iOS Safari6+Chrome for Android25+Android WebView37+Samsung Internet1.5+Opera Mobile14+
[Exposed=Window]
interface OscillatorNode : AudioScheduledSourceNode {
  constructor (BaseAudioContext context, optional OscillatorOptions options = {});
  attribute OscillatorType type;
  readonly attribute AudioParam frequency;
  readonly attribute AudioParam detune;
  undefined setPeriodicWave (PeriodicWave periodicWave);
};

1.26.1. 构造函数

OscillatorNode/OscillatorNode

Firefox53+SafariChrome55+
Opera42+Edge79+
Edge (Legacy)IE
Firefox for Android53+iOS SafariChrome for Android55+Android WebView55+Samsung Internet6.0+Opera Mobile42+

OscillatorNode(context, options)

当构造函数使用 BaseAudioContext context 和 一个选项对象 options 调用时,用户代理必须 初始化 AudioNode this,并将 contextoptions 作为参数。

OscillatorNode.constructor() 方法的参数。
参数 类型 可为空 可选 描述
context BaseAudioContext 此新的 BaseAudioContext 将与之关联
options OscillatorOptions OscillatorNode 的可选初始参数值。

1.26.2. 属性

OscillatorNode/detune

在所有当前引擎中。

Firefox25+Safari6+Chrome20+
Opera15+Edge79+
Edge (Legacy)12+IE
Firefox for Android25+iOS Safari6+Chrome for Android25+Android WebView37+Samsung Internet1.5+Opera Mobile14+

detune, 类型为 AudioParam, 只读

音分(cents)为单位的调音值,将按给定的数值偏移 frequency。其默认value为 0。此参数是 a-rate 的。它与 frequency 组成 复合参数,形成 computedOscFrequency。下表列出的名义范围允许此参数在整个可能的频率范围内调音。

参数 备注
defaultValue 0
minValue \(\approx -153600\)
maxValue \(\approx 153600\) 该值大约为 \(1200\ \log_2 \mathrm{FLT\_MAX}\),其中 FLT_MAX 是最大的 float 值。
automationRate "a-rate"

OscillatorNode/frequency

在所有当前引擎中。

Firefox25+Safari6+Chrome20+
Opera15+Edge79+
Edge (Legacy)12+IE
Firefox for Android25+iOS Safari6+Chrome for Android25+Android WebView37+Samsung Internet1.5+Opera Mobile14+

frequency, 类型为 AudioParam, 只读

周期波形的频率(单位:赫兹)。其默认 value 为 440。 此参数是 a-rate 的。它与 detune 组成 复合参数,形成 computedOscFrequency。其 名义范围 是 [-奈奎斯特频率, 奈奎斯特频率]。

OscillatorNode/type

在所有当前引擎中。

Firefox25+Safari6+Chrome20+
Opera15+Edge79+
Edge (Legacy)12+IE
Firefox for Android25+iOS Safari6+Chrome for Android25+Android WebView37+Samsung Internet1.5+Opera Mobile14+

type, 类型为 OscillatorType

周期波形的形状。它可以直接设置为任何类型常量值,除了 "custom"。 这样做必须抛出 InvalidStateError 异常。可以使用 setPeriodicWave() 方法来设置自定义波形,这会将此属性设置为 "custom"。 默认值为 "sine"。 设置此属性时,必须保持振荡器的相位。

1.26.3. 方法

OscillatorNode/setPeriodicWave

在所有当前引擎中。

Firefox25+Safari8+Chrome30+
Opera17+Edge79+
Edge (Legacy)12+IE
Firefox for Android25+iOS Safari8+Chrome for Android30+Android WebView37+Samsung Internet2.0+Opera Mobile18+

setPeriodicWave(periodicWave)

设置一个自定义的周期波形,给定一个 PeriodicWave

OscillatorNode.setPeriodicWave() 方法的参数。
参数 类型 可为空 可选 描述
periodicWave PeriodicWave 振荡器使用的自定义波形
返回类型: undefined

1.26.4. OscillatorOptions

此选项用于构造 OscillatorNode 时指定。所有成员都是可选的;如果未指定,则使用默认值来构造振荡器。

dictionary OscillatorOptions : AudioNodeOptions {
  OscillatorType type = "sine";
  float frequency = 440;
  float detune = 0;
  PeriodicWave periodicWave;
};
1.26.4.1. 字典 OscillatorOptions 成员
detune, 类型为 float, 默认为 0

OscillatorNode 的初始调音值。

frequency, 类型为 float, 默认为 440

OscillatorNode 的初始频率。

periodicWave, 类型为 PeriodicWave

PeriodicWave 用于 OscillatorNode。如果指定了此值,则忽略 type 的任何有效值;它被视为指定了 "custom"。

type, 类型为 OscillatorType, 默认为 "sine"

要构造的振荡器类型。如果将此值设置为 "custom" 而未指定 periodicWave, 则必须抛出 InvalidStateError 异常。如果指定了 periodicWave, 则忽略 type 的任何有效值;它被视为设置为 "custom"。

1.26.5. 基本波形相位

各种振荡器类型的理想化数学波形如下所述。总之,所有波形在时间 0 时被定义为正斜率的奇函数。振荡器产生的实际波形可能有所不同,以防止混叠效应。

振荡器产生的结果必须与使用适当的 PeriodicWave傅立叶级数disableNormalization 设置为 false 时,创建这些基本波形的结果相同。

"sine"

正弦波振荡器的波形为:

$$
  x(t) = \sin t
$$
"square"

方波振荡器的波形为:

$$
  x(t) = \begin{cases}
         1 & \mbox{for } 0≤ t < \pi \\
         -1 & \mbox{for } -\pi < t < 0.
         \end{cases}
$$

通过使用波形是周期为 \(2\pi\) 的奇函数这一事实将其扩展到所有 \(t\)。

"sawtooth"

锯齿波振荡器的波形为斜坡:

$$
  x(t) = \frac{t}{\pi} \mbox{ for } -\pi < t ≤ \pi;
$$

通过使用波形是周期为 \(2\pi\) 的奇函数这一事实将其扩展到所有 \(t\)。

"triangle"

三角波振荡器的波形为:

$$
  x(t) = \begin{cases}
           \frac{2}{\pi} t & \mbox{for } 0 ≤ t ≤ \frac{\pi}{2} \\
           1-\frac{2}{\pi} \left(t-\frac{\pi}{2}\right) & \mbox{for }
           \frac{\pi}{2} < t ≤ \pi.
         \end{cases}
$$

This is extended to all \(t\) by using the fact that the waveform is an odd function with period \(2\pi\).

1.27. PannerNode 接口

此接口表示一个处理节点,它在三维空间中定位 / 空间化传入的音频流。空间化是相对于BaseAudioContextAudioListener (listener 属性)进行的。

属性 备注
numberOfInputs 1
numberOfOutputs 1
channelCount 2 具有channelCount 限制
channelCountMode "clamped-max" 具有channelCountMode 限制
channelInterpretation "speakers"
tail-time Maybe 如果panningModel 设置为"HRTF", 由于头部响应的固有处理,该节点将为静音输入产生非静音输出。否则 tail-time 为零。

此节点的输入为单声道 (1 通道) 或立体声 (2 通道),且无法增加。来自具有更少或更多通道的节点的连接将适当地进行上混或下混

如果节点正在处理,则此节点的输出硬编码为立体声 (2 通道),且无法配置。如果节点未正在处理,则输出为单声道静音。

PanningModelType 枚举确定将使用哪种空间化算法来定位音频在 3D 空间中的位置。默认值为 "equalpower"。

enum PanningModelType {
    "equalpower",
    "HRTF"
};
枚举说明
"equalpower" 一种使用等功率平移的简单高效的空间化算法。

注意: 当使用此平移模型时,用于计算此节点输出的所有 AudioParam 都是 a-rate 的。

"HRTF" 一种使用卷积与人体受试者测量的脉冲响应的高质量空间化算法。此平移方法渲染立体声输出。

注意: 当使用此平移模型时,用于计算此节点输出的所有 AudioParam 都是 k-rate 的。

DistanceModelType 枚举决定了当音频源远离听众时将使用哪种算法来减小音量。默认值为 "inverse"。

在下述每个距离模型的描述中,设 \(d\) 为听众与平移器之间的距离;\(d_{ref}\) 为refDistance 属性的值;\(d_{max}\) 为maxDistance 属性的值;\(f\) 为rolloffFactor 属性的值。

enum DistanceModelType {
  "linear",
  "inverse",
  "exponential"
};
枚举说明
"linear" 一种线性距离模型,根据以下公式计算 distanceGain
$$
  1 - f\ \frac{\max\left[\min\left(d, d’_{max}\right), d’_{ref}\right] - d’_{ref}}{d’_{max} - d’_{ref}}
$$

其中 \(d’_{ref} = \min\left(d_{ref}, d_{max}\right)\) 和 \(d’_{max} = \max\left(d_{ref}, d_{max}\right)\)。如果 \(d’_{ref} = d’_{max}\),线性模型的值取为 \(1-f\)。

注意 \(d\) 被夹到区间 \(\left[d’_{ref},\, d’_{max}\right]\)。

"inverse" 一种反向距离模型,根据以下公式计算 distanceGain
$$
  \frac{d_{ref}}{d_{ref} + f\ \left[\max\left(d, d_{ref}\right) - d_{ref}\right]}
$$

即,\(d\) 被夹到区间 \(\left[d_{ref},\, \infty\right)\)。如果 \(d_{ref} = 0\),则无论 \(d\) 和 \(f\) 的值如何,反向模型的值取为 0。

"exponential" 一种指数距离模型,根据以下公式计算 distanceGain
$$
  \left[\frac{\max\left(d, d_{ref}\right)}{d_{ref}}\right]^{-f}
$$

即,\(d\) 被夹到区间 \(\left[d_{ref},\, \infty\right)\)。如果 \(d_{ref} = 0\),则无论 \(d\) 和 \(f\) 的值如何,指数模型的值取为 0。

PannerNode

在所有当前引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (Legacy)12+IE
Firefox for Android25+iOS Safari6+Chrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile14+
[Exposed=Window]
interface PannerNode : AudioNode {
  constructor (BaseAudioContext context, optional PannerOptions options = {});
  attribute PanningModelType panningModel;
  readonly attribute AudioParam positionX;
  readonly attribute AudioParam positionY;
  readonly attribute AudioParam positionZ;
  readonly attribute AudioParam orientationX;
  readonly attribute AudioParam orientationY;
  readonly attribute AudioParam orientationZ;
  attribute DistanceModelType distanceModel;
  attribute double refDistance;
  attribute double maxDistance;
  attribute double rolloffFactor;
  attribute double coneInnerAngle;
  attribute double coneOuterAngle;
  attribute double coneOuterGain;
  undefined setPosition (float x, float y, float z);
  undefined setOrientation (float x, float y, float z);
};

1.27.1. 构造函数

PannerNode/PannerNode

Firefox53+SafariChrome55+
Opera42+Edge79+
Edge (旧版)IE
Firefox for Android53+iOS SafariChrome for Android55+Android WebView55+Samsung Internet6.0+Opera Mobile42+

PannerNode(context, options)

当构造函数被调用时,传入一个 BaseAudioContext c 和 一个选项对象 option,用户代理必须使用 contextoptions 作为参数 初始化 AudioNode this

PannerNode.constructor() 方法的参数。
参数 类型 可为 null 可选 描述
context BaseAudioContext BaseAudioContext 将与此PannerNode关联。
options PannerOptions PannerNode的可选初始参数值。

1.27.2. 属性

PannerNode/coneInnerAngle

在所有当前引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (旧版)12+IE
Firefox for Android25+iOS Safari6+Chrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

coneInnerAngle, 类型 double

用于定向音频源的一个参数,它是一个角度(以度为单位),在该角度内不会有音量衰减。默认值为360。如果角度超出 [0, 360] 的范围,则行为未定义。

PannerNode/coneOuterAngle

在所有当前引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (旧版)12+IE
Firefox for Android25+iOS Safari6+Chrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

coneOuterAngle, 类型 double

用于定向音频源的一个参数,它是一个角度(以度为单位),在该角度之外,音量将减小到由coneOuterGain定义的常数值。默认值为360。如果角度超出 [0, 360] 的范围,则行为未定义。

PannerNode/coneOuterGain

在所有当前引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (旧版)12+IE
Firefox for Android25+iOS Safari6+Chrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

coneOuterGain, 类型 double

用于定向音频源的一个参数,它是coneOuterAngle之外的增益。默认值为0。它是范围在[0, 1]之间的线性值(而非分贝)。如果该参数超出此范围,必须抛出InvalidStateError异常。

PannerNode/distanceModel

在所有当前引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (旧版)12+IE
Firefox for Android25+iOS Safari6+Chrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

distanceModel, 类型 DistanceModelType

指定此PannerNode使用的距离模型。默认值为"inverse"。

PannerNode/maxDistance

在所有当前引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (旧版)12+IE
Firefox for Android25+iOS Safari6+Chrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

maxDistance, 类型 double

源和听众之间的最大距离,在此之后,音量不再进一步降低。默认值为10000。如果设置为非正值,则必须抛出RangeError异常。

PannerNode/orientationX

Firefox50+SafariChrome52+
Opera39+Edge79+
Edge (旧版)IE
Firefox for Android50+iOS SafariChrome for Android52+Android WebView52+Samsung Internet6.0+Opera Mobile41+

orientationX, 类型 AudioParam, 只读

描述音频源在3D笛卡尔坐标系中指向方向的\(x\)-分量。

PannerNode/orientationY

Firefox50+SafariChrome52+
Opera39+Edge79+
Edge (旧版)IE
Firefox for Android50+iOS SafariChrome for Android52+Android WebView52+Samsung Internet6.0+Opera Mobile41+

orientationY, 类型 AudioParam, 只读

描述音频源在3D笛卡尔坐标系中指向方向的\(y\)-分量。

PannerNode/orientationZ

Firefox50+SafariChrome52+
Opera39+Edge79+
Edge (旧版)IE
Firefox for Android50+iOS SafariChrome for Android52+Android WebView52+Samsung Internet6.0+Opera Mobile41+

orientationZ, 类型 AudioParam, 只读

描述音频源在3D笛卡尔坐标系中指向方向的\(z\)-分量。

PannerNode/panningModel

在所有当前引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (旧版)12+IE
Firefox for Android25+iOS Safari6+Chrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

panningModel, 类型 PanningModelType

指定此PannerNode使用的空间化模型。默认值为"equalpower"。

PannerNode/positionX

Firefox50+SafariChrome52+
Opera39+Edge79+
Edge (旧版)IE
Firefox for Android50+iOS SafariChrome for Android52+Android WebView52+Samsung Internet6.0+Opera Mobile41+

positionX, 类型 AudioParam, 只读

设置音频源在3D笛卡尔坐标系中的\(x\)-坐标位置。

PannerNode/positionY

Firefox50+SafariChrome52+
Opera39+Edge79+
Edge (旧版)IE
Firefox for Android50+iOS SafariChrome for Android52+Android WebView52+Samsung Internet6.0+Opera Mobile41+

positionY, 类型 AudioParam, 只读

设置音频源在3D笛卡尔坐标系中的\(y\)-坐标位置。

PannerNode/positionZ

Firefox50+SafariChrome52+
Opera39+Edge79+
Edge (旧版)IE
Firefox for Android50+iOS SafariChrome for Android52+Android WebView52+Samsung Internet6.0+Opera Mobile41+

positionZ, 类型 AudioParam, 只读

设置音频源在3D笛卡尔坐标系中的\(z\)-坐标位置。

PannerNode/refDistance

在所有当前引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (旧版)12+IE
Firefox for Android25+iOS Safari6+Chrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

refDistance, 类型 double

用于当源远离听众时减小音量的参考距离。对于小于此距离的距离,音量不会减小。默认值为1。 如果设置为负值,必须抛出RangeError异常。

PannerNode/rolloffFactor

在所有当前引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (旧版)12+IE
Firefox for Android25+iOS Safari6+Chrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

rolloffFactor, 类型 double

描述了当音频源远离听众时音量下降的速度。默认值为1。如果设置为负值,必须抛出RangeError异常。

rolloffFactor的名义范围指定了 rolloffFactor可以具有的最小值和最大值。超出范围的值将被限制在此范围内。名义范围取决于distanceModel,如下所示:

"linear"

名义范围是\([0, 1]\)。

"inverse"

名义范围是\([0, \infty)\)。

"exponential"

名义范围是\([0, \infty)\)。

请注意,限制在距离计算的处理过程中进行。属性反映设置的值,并且不会被修改。

1.27.3. 方法

setOrientation(x, y, z)

此方法已弃用。相当于直接设置 orientationX.value, orientationY.value, 和 orientationZ.value 属性,分别对应 xyz 参数。

因此,如果 orientationXorientationYorientationZ AudioParam 设置了自动化曲线,且在调用此方法时使用了 setValueCurveAtTime() ,那么必须抛出 NotSupportedError 异常。

描述音频源在 3D 笛卡尔坐标系中指向的方向。根据声音的方向性(由 锥形 属性控制),指向远离听众的声音可能非常安静或完全静音。

x, y, z 参数表示 3D 空间中的方向向量。

默认值为 (1,0,0)。

PannerNode.setOrientation() 方法的参数。
参数 类型 可为空 可选 描述
x float
y float
z float
返回类型: undefined
setPosition(x, y, z)

此方法已弃用。相当于直接设置 positionX.value, positionY.value, 和 positionZ.value 属性,分别对应 xyz 参数。

因此,如果 positionXpositionYpositionZ AudioParam 设置了自动化曲线,且在调用此方法时使用了 setValueCurveAtTime() ,那么必须抛出 NotSupportedError 异常。

设置音频源相对于 listener 属性的位置。使用 3D 笛卡尔坐标系。

x, y, z 参数表示 3D 空间中的坐标。

默认值为 (0,0,0)。

PannerNode.setPosition() 方法的参数。
参数 类型 可为空 可选 描述
x float
y float
z float
返回类型: undefined

1.27.4. PannerOptions

此部分指定了构造 PannerNode 时的选项。 所有成员都是可选的;如果未指定,则在构造节点时使用正常的默认值。

dictionary PannerOptions : AudioNodeOptions {
  PanningModelType panningModel = "equalpower";
  DistanceModelType distanceModel = "inverse";
  float positionX = 0;
  float positionY = 0;
  float positionZ = 0;
  float orientationX = 1;
  float orientationY = 0;
  float orientationZ = 0;
  double refDistance = 1;
  double maxDistance = 10000;
  double rolloffFactor = 1;
  double coneInnerAngle = 360;
  double coneOuterAngle = 360;
  double coneOuterGain = 0;
};
1.27.4.1. 字典 PannerOptions 成员
coneInnerAngle, 类型为 double,默认值为 360

节点 coneInnerAngle 属性的初始值。

coneOuterAngle, 类型为 double,默认值为 360

节点 coneOuterAngle 属性的初始值。

coneOuterGain, 类型为 double,默认值为 0

节点 coneOuterGain 属性的初始值。

distanceModel, 类型为 DistanceModelType,默认值为 "inverse"

节点使用的距离模型。

maxDistance, 类型为 double,默认值为 10000

节点 maxDistance 属性的初始值。

orientationX, 类型为 float,默认值为 1

节点 orientationX AudioParam 的初始 \(x\)-分量值。

orientationY, 类型为 float,默认值为 0

节点 orientationY AudioParam 的初始 \(y\)-分量值。

orientationZ, 类型为 float,默认值为 0

节点 orientationZ AudioParam 的初始 \(z\)-分量值。

panningModel, 类型为 PanningModelType,默认值为 "equalpower"

节点使用的声像模型。

positionX, 类型为 float,默认值为 0

节点 positionX AudioParam 的初始 \(x\)-坐标值。

positionY, 类型为 float,默认值为 0

节点 positionY AudioParam 的初始 \(y\)-坐标值。

positionZ, 类型为 float,默认值为 0

节点 positionZ AudioParam 的初始 \(z\)-坐标值。

refDistance, 类型为 double,默认值为 1

节点 refDistance 属性的初始值。

rolloffFactor, 类型为 double,默认值为 1

节点 rolloffFactor 属性的初始值。

1.27.5. 频道限制

频道限制的集合也适用于 StereoPannerNode。 也适用于 PannerNode

1.28. PeriodicWave 接口

PeriodicWave 代表一个任意的周期波形,用于 OscillatorNode

一个合规实现必须支持至少8192个元素的 PeriodicWave

PeriodicWave/PeriodicWave

Firefox53+Safari?Chrome55+
Opera42+Edge79+
Edge (Legacy)IE
Firefox for Android53+iOS Safari?Chrome for Android55+Android WebView55+Samsung Internet6.0+Opera Mobile42+

PeriodicWave

在所有当前引擎中。

Firefox25+Safari8+Chrome30+
Opera17+Edge79+
Edge (Legacy)18IE
Firefox for Android26+iOS Safari8+Chrome for Android30+Android WebView37+Samsung Internet2.0+Opera Mobile18+
[Exposed=Window]
interface PeriodicWave {
  constructor (BaseAudioContext context, optional PeriodicWaveOptions options = {});
};

1.28.1. 构造函数

PeriodicWave(context, options)
  1. p 为一个新的 PeriodicWave 对象。令 [[real]][[imag]] 为两个类型为 Float32Array 的内部槽,并且令 [[normalize]] 为一个内部槽。

  2. 根据以下情况处理 options

    1. 如果 options.realoptions.imag 都存在

      1. 如果 options.realoptions.imag 的长度不同或如果任一长度小于 2,则抛出 IndexSizeError 并中止此算法。

      2. [[real]][[imag]] 设置为与 options.real 长度相同的新数组。

      3. 将所有元素从 options.real 复制到 [[real]],并将 options.imag 复制到 [[imag]]

    2. 如果仅 options.real 存在

      1. 如果 options.real 的长度小于 2,则抛出 IndexSizeError 并中止此算法。

      2. [[real]][[imag]] 设置为与 options.real 长度相同的数组。

      3. options.real 复制到 [[real]],并将 [[imag]] 设置为全零。

    3. 如果仅 options.imag 存在

      1. 如果 options.imag 的长度小于 2,则抛出 IndexSizeError 并中止此算法。

      2. [[real]][[imag]] 设置为与 options.imag 长度相同的数组。

      3. options.imag 复制到 [[imag]],并将 [[real]] 设置为全零。

    4. 否则

      1. [[real]][[imag]] 设置为长度为2的零填充数组。

      2. [[imag]] 索引1处的元素设置为1。

      注意:OscillatorNode 上设置此 PeriodicWave 时,相当于使用内置类型 "sine"。

  3. [[real]][[imag]] 索引0处的元素设置为0。(这将直流分量设置为0。)

  4. 初始化 [[normalize]]disableNormalization 的相反值 PeriodicWaveConstraintsPeriodicWaveOptions

  5. 返回 p

PeriodicWave.constructor() 方法的参数。
参数 类型 可空 可选 描述
context BaseAudioContext 此新的BaseAudioContext 将被关联到。与 AudioBuffer不同, PeriodicWave 不能跨越 AudioContextOfflineAudioContext 共享。它与特定的 BaseAudioContext 关联。
options PeriodicWaveOptions PeriodicWave的可选初始参数值。

1.28.2. PeriodicWaveConstraints

PeriodicWaveConstraints 字典用于指定波形如何规范化

dictionary PeriodicWaveConstraints {
  boolean disableNormalization = false;
};
1.28.2.1. Dictionary PeriodicWaveConstraints Members
disableNormalization, of type boolean, defaulting to false

控制是否对周期波形进行规范化。如果为 true,则波形不规范化;否则,波形将被规范化。

1.28.3. PeriodicWaveOptions

PeriodicWaveOptions 字典用于指定如何构建波形。如果只指定了 realimag 中的一个,另一个将被视为相同长度的全零数组,如下文中的字典成员描述中所述。如果两者都未给出,将创建一个 PeriodicWave, 它必须等同于 OscillatorNode, 其 type 为 "sine"。如果两者都给出,则序列必须具有相同长度;否则,将抛出一个 类型错误 NotSupportedError

dictionary PeriodicWaveOptions : PeriodicWaveConstraints {
  sequence<float> real;
  sequence<float> imag;
};
1.28.3.1. Dictionary PeriodicWaveOptions Members
imag, of type sequence<float>

imag 参数表示一个 sine 项的数组。第一个元素(索引 0)在傅里叶级数中不存在。第二个元素(索引 1)表示基频。第三个元素表示第一个泛音,依此类推。

real, of type sequence<float>

real 参数表示一个 cosine 项的数组。第一个元素(索引 0)是周期波形的直流偏移。第二个元素(索引 1)表示基频。第三个元素表示第一个泛音,依此类推。

1.28.4. Waveform Generation

createPeriodicWave() 方法接受两个数组来指定 PeriodicWave 的傅里叶系数。设 \(a\) 和 \(b\) 分别表示长度为 \(L\) 的 [[real]][[imag]] 数组。然后,基本时域波形 \(x(t)\) 可以使用以下公式计算:

$$
  x(t) = \sum_{k=1}^{L-1} \left[a[k]\cos2\pi k t + b[k]\sin2\pi k t\right]
$$

这是基本的(未规范化的)波形。

1.28.5. Waveform Normalization

如果此 PeriodicWave 的内部槽 [[normalize]]true(默认值),则前一节中定义的波形将被规范化,使其最大值为 1。规范化的具体方法如下。

$$
  \tilde{x}(n) = \sum_{k=1}^{L-1} \left(a[k]\cos\frac{2\pi k n}{N} + b[k]\sin\frac{2\pi k n}{N}\right)
$$

其中,\(N\) 是二的幂。(注:\(\tilde{x}(n)\) 可以使用逆 FFT 方便地计算。)固定的规范化因子 \(f\) 计算方法如下。

$$
  f = \max_{n = 0, \ldots, N - 1} |\tilde{x}(n)|
$$

因此,实际的规范化波形 \(\hat{x}(n)\) 为:

$$
  \hat{x}(n) = \frac{\tilde{x}(n)}{f}
$$

此固定规范化因子必须应用于所有生成的波形。

1.28.6. Oscillator Coefficients

内置的振荡器类型是使用 PeriodicWave 对象创建的。为了完整性,给出了每种内置振荡器类型的 PeriodicWave 系数。这对于需要内置类型但不需要默认规范化的情况非常有用。

在以下描述中,设 \(a\) 为实系数数组,\(b\) 为 createPeriodicWave() 的虚系数数组。在所有情况下,\(a[n] = 0\) 对所有 \(n\) 都成立,因为这些波形是奇函数。此外,在所有情况下,\(b[0] = 0\)。因此,仅指定 \(n \ge 1\) 的 \(b[n]\) 如下。

"sine"
$$
  b[n] = \begin{cases}
           1 & \mbox{for } n = 1 \\
           0 & \mbox{otherwise}
         \end{cases}
$$
"square"
$$
  b[n] = \frac{2}{n\pi}\left[1 - (-1)^n\right]
$$
"sawtooth"
$$
  b[n] = (-1)^{n+1} \dfrac{2}{n\pi}
$$
"triangle"
$$
  b[n] = \frac{8\sin\dfrac{n\pi}{2}}{(\pi n)^2}
$$

1.29. ScriptProcessorNode 接口 - 已弃用

此接口是一个 AudioNode,它可以通过脚本直接生成、处理或分析音频。此节点类型已弃用,将被 AudioWorkletNode 替代;此处的文字仅供参考,直到实现中移除此节点类型。

属性 备注
numberOfInputs 1
numberOfOutputs 1
channelCount numberOfInputChannels 这是构造此节点时指定的通道数。存在 channelCount 约束
channelCountMode "explicit" 具有 channelCountMode 约束
channelInterpretation "speakers"
尾时间

ScriptProcessorNode 是通过 bufferSize 构造的,其值必须是以下之一:256, 512, 1024, 2048, 4096, 8192, 16384。此值控制 onaudioprocess 事件的触发频率,以及每次调用需要处理的样本帧数。onaudioprocess 事件仅在 ScriptProcessorNode 至少有一个输入或一个输出连接时才会触发。较低的 bufferSize 数值将导致较低(更好)的延迟。较高的数值将有助于避免音频中断和故障。如果在调用 createScriptProcessor() 时未传入 bufferSize 参数,或其值为 0,则实现将自动选择此值。

numberOfInputChannelsnumberOfOutputChannels 决定了输入和输出通道的数量。numberOfInputChannelsnumberOfOutputChannels 都为零是无效的。

[Exposed=Window]
interface ScriptProcessorNode : AudioNode {
  attribute EventHandler onaudioprocess;
  readonly attribute long bufferSize;
};

1.29.1. 属性

bufferSize, 类型为 long,只读

在每次调用 onaudioprocess 时需要处理的缓冲区大小(以样本帧为单位)。 合法值为 (256, 512, 1024, 2048, 4096, 8192, 16384)。

onaudioprocess, 类型为 EventHandler

用于设置 EventHandler(详见 HTML[HTML])的属性,用于 onaudioprocess 事件,该事件会分派给 ScriptProcessorNode 节点类型。类型为 AudioProcessingEvent 的事件将被分派到事件处理程序。

1.30. StereoPannerNode 接口

此接口表示一个处理节点,该节点使用低成本的声像算法在立体声图像中定位传入的音频流。此声像效果在定位立体声流中的音频组件时非常常见。

属性 备注
numberOfInputs 1
numberOfOutputs 1
channelCount 2 channelCount 限制
channelCountMode "clamped-max" channelCountMode 限制
channelInterpretation "speakers"
tail-time

该节点的输入为立体声(2声道),且不可增加。来自声道数更少或更多的节点的连接将会被适当地上混或下混

该节点的输出硬编码为立体声(2声道),且不可配置。

StereoPannerNode

Firefox37+SafariChrome41+
Opera28+Edge79+
Edge (旧版)12+IE
Firefox for Android37+iOS SafariChrome for Android41+Android WebView41+Samsung Internet4.0+Opera Mobile28+
[Exposed=Window]
interface StereoPannerNode : AudioNode {
  constructor (BaseAudioContext context, optional StereoPannerOptions options = {});
  readonly attribute AudioParam pan;
};

1.30.1. 构造函数

StereoPannerNode/StereoPannerNode

Firefox53+SafariChrome55+
Opera42+Edge79+
Edge (旧版)IE
Firefox for Android53+iOS SafariChrome for Android55+Android WebView55+Samsung Internet6.0+Opera Mobile42+

StereoPannerNode(context, options)

当调用带有 BaseAudioContext c 和 一个选项对象 option 的构造函数时,用户代理必须使用 contextoptions 作为参数来初始化AudioNodethis

StereoPannerNode.constructor() 方法的参数。
参数 类型 可为空 可选 描述
context BaseAudioContext 此新的 BaseAudioContext 将与这个 StereoPannerNode 关联
options StereoPannerOptions StereoPannerNode 的可选初始参数值。

1.30.2. 属性

StereoPannerNode/pan

Firefox37+SafariChrome41+
Opera28+Edge79+
Edge (旧版)12+IE
Firefox for Android37+iOS SafariChrome for Android41+Android WebView41+Samsung Internet4.0+Opera Mobile28+

pan, 类型为 AudioParam, 只读

输入在输出立体声图像中的位置。-1 代表完全左声道,+1 代表完全右声道。

参数 备注
defaultValue 0
minValue -1
maxValue 1
automationRate "a-rate"

1.30.3. StereoPannerOptions

此字典指定用于构建 StereoPannerNode 的选项。 所有成员都是可选的;如果未指定,则使用构造节点时的正常默认值。

dictionary StereoPannerOptions : AudioNodeOptions {
  float pan = 0;
};
1.30.3.1. 字典 StereoPannerOptions 成员
pan, 类型为 float,默认为 0

pan AudioParam 的初始值。

1.30.4. 声道限制

由于其处理受上述定义的约束,StereoPannerNode 限于混合不超过 2个声道的音频,并产生恰好2个声道。可以使用 ChannelSplitterNode, 通过子图的中间处理实现 GainNode 和/或其他节点,并通过ChannelMergerNode 重新组合,实现对声像和混音的任意方法。

1.31. The WaveShaperNode Interface

WaveShaperNode 是一个 AudioNode 处理器,用于实现非线性失真效果。

非线性波形失真常用于实现微妙的非线性增暖效果或更明显的失真效果。可以指定任意非线性成形曲线。

属性 备注
numberOfInputs 1
numberOfOutputs 1
channelCount 2
channelCountMode "max"
channelInterpretation "speakers"
尾时间 可能 仅当 oversample 属性设置为 "2x" 或 "4x" 时才会有 尾时间。实际的 尾时间 长度取决于实现方式。

输出声道的数量始终等于输入声道的数量。

enum OverSampleType {
  "none",
  "2x",
  "4x"
};
枚举描述
"none" 不进行过采样
"2x" 过采样两次
"4x" 过采样四次

WaveShaperNode

在所有当前引擎中。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (旧版)12+IE
Firefox for Android25+iOS SafariChrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile14+
[Exposed=Window]
interface WaveShaperNode : AudioNode {
  constructor (BaseAudioContext context, optional WaveShaperOptions options = {});
  attribute Float32Array? curve;
  attribute OverSampleType oversample;
};

1.31.1. 构造函数

WaveShaperNode/WaveShaperNode

Firefox53+SafariNoneChrome55+
Opera42+Edge79+
Edge (Legacy)NoneIENone
Firefox for Android53+iOS SafariNoneChrome for Android55+Android WebView55+Samsung Internet6.0+Opera Mobile42+

WaveShaperNode(context, options)

当构造函数被调用时,使用 BaseAudioContext context 和 一个选项对象 options,用户代理必须 初始化 AudioNode this,并将 contextoptions 作为参数。

此外,设置 [[curve set]] 为此 WaveShaperNode 的内部槽。 初始化此槽为 false。如果 options 被指定并包含 curve, 则将 [[curve set]] 设置为 true

WaveShaperNode.constructor() 方法的参数。
参数 类型 可为空 可选 描述
context BaseAudioContext WaveShaperNode 将与此 BaseAudioContext 关联。
options WaveShaperOptions WaveShaperNode 的可选初始参数值。

1.31.2. 属性

WaveShaperNode/curve

在所有当前的引擎中可用。

Firefox25+Safari6+Chrome14+
Opera15+Edge79+
Edge (Legacy)12+IE
Firefox for Android25+iOS Safari支持Chrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

curve, 类型为 Float32Array,可为空

用于波形整形效果的曲线。输入信号通常在 [-1, 1] 范围内。该范围内的每个输入样本将索引到整形曲线中,如果数组条目数为奇数,则零信号水平对应于曲线数组的中心值;如果数组条目数为偶数,则零信号水平将在两个最中间的值之间插值。任何小于 -1 的样本值将对应于曲线数组中的第一个值。任何大于 +1 的样本值将对应于曲线数组中的最后一个值。

实现必须在曲线的相邻点之间执行线性插值。最初,curve 属性为 null,这意味着 WaveShaperNode 会将输入传递到输出而不做任何修改。

曲线的值在 [-1; 1] 范围内均匀分布。这意味着一个具有偶数个值的 curve 将没有针对零信号的值,而一个具有奇数个值的 curve 将有一个针对零信号的值。输出由以下算法确定。

  1. 设 \(x\) 为输入样本,\(y\) 为节点的相应输出,\(c_k\) 为 curve 的第 \(k\) 个元素,\(N\) 为 curve 的长度。

  2. $$
      \begin{align*}
      v &= \frac{N-1}{2}(x + 1) \\
      k &= \lfloor v \rfloor \\
      f &= v - k
      \end{align*}
    $$
    
  3. 然后

    $$
      \begin{align*}
      y &=
        \begin{cases}
        c_0 & v \lt 0 \\
        c_{N-1} & v \ge N - 1 \\
        (1-f)\,c_k + fc_{k+1} & \mathrm{otherwise}
        \end{cases}
      \end{align*}
    $$
    

如果此属性被设置为一个 Float32Arraylength 小于 2,则必须抛出 InvalidStateError

设置此属性时,WaveShaperNode 会创建一个曲线的内部副本。 因此,随后修改用于设置属性的数组内容不会产生任何影响。

要设置 curve 属性,执行以下步骤:
  1. new curve 是一个 Float32Array,将被分配给 curvenull。 。

  2. 如果 new curve 不是 null[[curve set]] 为 true,则抛出 InvalidStateError 并中止这些步骤。

  3. 如果 new curve 不是 null,将 [[curve set]] 设置为 true。

  4. new curve 分配给 curve 属性。

注意: 使用在零输入值时会产生非零输出值的曲线会导致此节点生成直流信号,即使没有输入连接到此节点。这将一直持续到节点与下游节点断开连接。

WaveShaperNode/oversample

在所有当前的引擎中可用。

Firefox26+Safari6+Chrome14+
Opera15+Edge79+
Edge (Legacy)12+IE
Firefox for Android26+iOS Safari支持Chrome for Android18+Android WebView37+Samsung Internet1.0+Opera Mobile14+

oversample, 类型为 OverSampleType

指定在应用整形曲线时应使用的过采样类型(如果有)。默认值为 "none",表示曲线将直接应用于输入样本。值为 "2x" 或 "4x" 可通过避免一些混叠来提高处理质量,其中 "4x" 值提供最高质量。对于某些应用程序,最好使用不进行过采样的方法以获得非常精确的整形曲线。

当值为 "2x" 或 "4x" 时,必须执行以下步骤:
  1. 将输入样本上采样至 AudioContext 的采样率的 2 倍或 4 倍。 因此对于每个 render quantum,生成 256(对于 2x)或 512(对于 4x)个样本。

  2. 应用整形曲线。

  3. 将结果下采样至 AudioContext 的采样率。 因此取 256(或 512)个处理样本,生成 128 个最终结果。

未指定确切的上采样和下采样滤波器,并且可以根据音质(低混叠等)、低延迟或性能进行调整。

注意: 使用过采样会因上采样和下采样滤波器的引入而导致某种程度的音频处理延迟。延迟的量因实现而异。

1.31.3. WaveShaperOptions

此部分指定了构建 WaveShaperNode 的选项。 所有成员都是可选的;如果未指定,则在构建节点时使用正常的默认值。

dictionary WaveShaperOptions : AudioNodeOptions {
  sequence<float> curve;
  OverSampleType oversample = "none";
};
1.31.3.1. 字典 WaveShaperOptions 成员
curve, 类型为 sequence<float>

用于波形整形效果的整形曲线。

oversample, 类型为 OverSampleType,默认为 "none"

用于整形曲线的过采样类型。

1.32. AudioWorklet 接口

AudioWorklet

Firefox76+Safari不支持Chrome66+
Opera支持Edge79+
Edge (Legacy)不支持IE不支持
Firefox for Android79+iOS Safari不支持Chrome for Android66+Android WebView66+Samsung Internet9.0+Opera Mobile支持
[Exposed=Window, SecureContext]
interface AudioWorklet : Worklet {
};

1.32.1. 概念

AudioWorklet 对象允许开发者提供脚本 (如 JavaScript 或 WebAssembly 代码)在 渲染线程 上处理音频,支持自定义 AudioNode。 这种处理机制确保了脚本代码与音频图中其他内置 AudioNode 的同步执行。

必须定义一对关联的对象来实现这种机制:AudioWorkletNodeAudioWorkletProcessor。 前者表示类似于其他 AudioNode 对象的主全局范围接口,后者则在名为 AudioWorkletGlobalScope 的特殊范围内实现内部音频处理。

AudioWorklet 概念
AudioWorkletNodeAudioWorkletProcessor

每个 BaseAudioContext 具有一个 AudioWorklet

AudioWorkletWorklet 全局范围类型AudioWorkletGlobalScope

AudioWorkletWorklet 目标类型"audioworklet"

通过 addModule(moduleUrl) 方法导入脚本会在 AudioWorkletGlobalScope 下注册 AudioWorkletProcessor 类定义。 有两个内部存储区用于存储导入的类构造函数和从构造函数创建的活动实例。

AudioWorklet 具有一个内部槽:

// bypass-processor.js script file, runs on AudioWorkletGlobalScope
class BypassProcessor extends AudioWorkletProcessor {
  process (inputs, outputs) {
    // Single input, single channel.
    const input = inputs[0];
    const output = outputs[0];
    output[0].set(input[0]);

    // Process only while there are active inputs.
    return false;
  }
};

registerProcessor('bypass-processor', BypassProcessor);
// The main global scope
const context = new AudioContext();
context.audioWorklet.addModule('bypass-processor.js').then(() => {
  const bypassNode = new AudioWorkletNode(context, 'bypass-processor');
});

在主全局范围内实例化 AudioWorkletNode 时,相应的 AudioWorkletProcessor 也将在 AudioWorkletGlobalScope 中创建。这两个对象通过 第 2 节 处理模型 中描述的异步消息传递进行通信。

1.32.2. AudioWorkletGlobalScope 接口

这个特殊的执行上下文旨在直接使用脚本在音频 渲染线程 中生成、处理和分析音频数据。用户提供的脚本代码在此范围内进行评估,以定义一个或多个 AudioWorkletProcessor 子类,进而用于实例化 AudioWorkletProcessor,与主范围内的 AudioWorkletNode 形成一对一的关联。

每个包含一个或多个 AudioWorkletNodeAudioContext 存在一个 AudioWorkletGlobalScope。导入脚本的运行由 UA 按 [HTML] 中定义的方式执行。覆盖 [HTML] 中指定的默认值,AudioWorkletGlobalScope 不得被用户代理任意 终止

AudioWorkletGlobalScope 具有以下内部槽:

注意:AudioWorkletGlobalScope 还可以包含其他任何数据和代码,以供这些实例共享。举个例子,多个处理器可能共享一个定义了波表或脉冲响应的 ArrayBuffer。

注意:AudioWorkletGlobalScope 与单个 BaseAudioContext 以及该上下文的单个音频渲染线程相关联。这可以防止在并发线程中运行的全局范围代码中发生数据竞争。

AudioWorkletGlobalScope

Firefox76+SafariNoneChrome66+
Opera53+Edge79+
Edge (Legacy)NoneIENone
Firefox for AndroidNoneiOS SafariNoneChrome for Android66+Android WebView66+Samsung Internet9.0+Opera Mobile47+
callback AudioWorkletProcessorConstructor = AudioWorkletProcessor (object options);

[Global=(Worklet, AudioWorklet), Exposed=AudioWorklet]
interface AudioWorkletGlobalScope : WorkletGlobalScope {
  undefined registerProcessor (DOMString name,
                               AudioWorkletProcessorConstructor processorCtor);
  readonly attribute unsigned long long currentFrame;
  readonly attribute double currentTime;
  readonly attribute float sampleRate;
};
1.32.2.1. 属性
currentFrame, 类型为 unsigned long long, 只读

当前正在处理的音频块的帧数。这必须等于 [[current frame]] 内部槽的值,该槽属于 BaseAudioContext

currentTime, 类型为 double, 只读

当前正在处理的音频块的上下文时间。根据定义,这将等于最近在 控制线程 中可观察到的 BaseAudioContextcurrentTime 属性的值。

sampleRate, 类型为 float, 只读

关联的 BaseAudioContext 的采样率。

1.32.2.2. 方法

AudioWorkletGlobalScope/registerProcessor

Firefox76+SafariNoneChrome66+
Opera53+Edge79+
Edge (Legacy)NoneIENone
Firefox for AndroidNoneiOS SafariNoneChrome for Android66+Android WebView66+Samsung Internet9.0+Opera Mobile47+

registerProcessor(name, processorCtor)

AudioWorkletProcessor 派生类下注册一个类构造函数。

当调用 registerProcessor(name, processorCtor) 方法时,执行以下步骤。如果在任何步骤中抛出异常,则中止剩余的步骤。
  1. 如果 name 是一个空字符串,抛出 NotSupportedError

  2. 如果 name 已经作为键存在于 节点名称到处理器构造函数映射 中,抛出 NotSupportedError

  3. 如果 IsConstructor(argument=processorCtor) 的结果为 false抛出 TypeError

  4. prototype 获取(O=processorCtor, P="prototype") 的结果。

  5. 如果 类型(argument=prototype) 的结果不是 Object抛出 TypeError

  6. parameterDescriptorsValue获取(O=processorCtor, P="parameterDescriptors") 的结果。

  7. 如果 parameterDescriptorsValue 不是 undefined,则执行以下步骤:

    1. parameterDescriptorSequence 为将 parameterDescriptorsValue 转换为 sequence<AudioParamDescriptor> 类型的 IDL 值的结果。

    2. paramNames 为一个空数组。

    3. 对于 parameterDescriptorSequence 中的每个 descriptor
      1. paramNamedescriptor 中的成员 name 的值。如果 paramNames 已经包含了 paramName 值,抛出 NotSupportedError

      2. paramName 添加到 paramNames 数组中。

      3. defaultValuedescriptor 中的成员 defaultValue 的值。

      4. minValuedescriptor 中的成员 minValue 的值。

      5. maxValuedescriptor 中的成员 maxValue 的值。

      6. 如果表达式 minValue <= defaultValue <= maxValue 为假,抛出 InvalidStateError

  8. 将键值对 nameprocessorCtor 添加到关联的 AudioWorkletGlobalScope节点名称到处理器构造函数映射 中。

  9. 队列一个媒体元素任务 将键值对 nameparameterDescriptorSequence 添加到关联的 BaseAudioContext节点名称到参数描述符映射 中。

注意: 类构造函数应该只查找一次,因此在注册后它没有机会动态更改。

AudioWorkletGlobalScope.registerProcessor(name, processorCtor) 方法的参数。
参数 类型 可空 可选 描述
name DOMString 表示要注册的类构造函数的字符串键。此键在构造 AudioWorkletNode 时用于查找 AudioWorkletProcessor 的构造函数。
processorCtor AudioWorkletProcessorConstructor AudioWorkletProcessor 派生的类构造函数。
返回类型: undefined
1.32.2.3. AudioWorkletProcessor 的实例化

AudioWorkletNode 构造结束时,将准备一个名为 处理器构造数据结构 进行跨线程传输。该 结构 包含以下

当传输的数据到达 AudioWorkletGlobalScope 时,渲染线程 将调用以下算法:

  1. constructionData 为从 控制线程 传输的 处理器构造数据

  2. processorNamenodeReferenceserializedPortconstructionData名称节点端口

  3. serializedOptionsconstructionData选项

  4. deserializedPort结构化反序列化(serializedPort, 当前 Realm) 的结果。

  5. deserializedOptions结构化反序列化(serializedOptions, 当前 Realm) 的结果。

  6. processorCtor 为在 AudioWorkletGlobalScope节点名称到处理器构造函数映射 中查找 processorName 的结果。

  7. nodeReferencedeserializedPort 分别存储到此 AudioWorkletGlobalScope节点引用传输端口挂起的处理器构造数据 中。

  8. processorCtor 构造一个带有 deserializedOptions 参数的 回调函数。如果在回调中抛出任何异常,则 队列一个任务控制线程触发一个 名为 processorerror 的事件,使用 ErrorEventnodeReference 上。

  9. 清空 挂起的处理器构造数据 槽。

1.32.3. AudioWorkletNode 接口

此接口表示一个用户定义的 AudioNode,它存在于 控制线程 上。用户可以从 BaseAudioContext 创建一个 AudioWorkletNode,并且这样的节点可以与其他内置的 AudioNode 连接形成音频图。

属性 备注
numberOfInputs 1
numberOfOutputs 1
channelCount 2
channelCountMode "max"
channelInterpretation "speakers"
尾音时间 见备注 由节点本身处理任何 尾音时间

每个 AudioWorkletProcessor 都有一个关联的 活动源 标志,初始值为 true。此标志会导致节点在没有任何连接输入的情况下保留在内存中并执行音频处理。

AudioWorkletNode 发出的所有任务都将发布到其关联的 BaseAudioContext 的任务队列中。

[Exposed=Window]
interface AudioParamMap {
  readonly maplike<DOMString, AudioParam>;
};

此接口具有 readonly maplike 带来的 "entries"、"forEach"、"get"、"has"、"keys"、"values"、@@iterator 方法和 "size" getter。

AudioWorkletNode

Firefox76+SafariNoneChrome66+
OperaYesEdge79+
Edge (Legacy)NoneIENone
Firefox for Android79+iOS SafariNoneChrome for Android66+Android WebView66+Samsung Internet9.0+Opera MobileYes
[Exposed=Window, SecureContext]
interface AudioWorkletNode : AudioNode {
  constructor (BaseAudioContext context, DOMString name,
               optional AudioWorkletNodeOptions options = {});
  readonly attribute AudioParamMap parameters;
  readonly attribute MessagePort port;
  attribute EventHandler onprocessorerror;
};
1.32.3.1. 构造函数

AudioWorkletNode/AudioWorkletNode

Firefox76+SafariNoneChrome66+
Opera?Edge79+
Edge (Legacy)NoneIENone
Firefox for Android79+iOS SafariNoneChrome for Android66+Android WebView66+Samsung Internet9.0+Opera Mobile?

AudioWorkletNode(context, name, options)

AudioWorkletNode.constructor() 方法的参数。
参数 类型 可为空 可选 描述
context BaseAudioContext 此新 BaseAudioContext 将与之 关联
name DOMString 一个字符串,是 BaseAudioContext 的键 节点名称到参数描述符映射
options AudioWorkletNodeOptions AudioWorkletNode 的可选初始参数值。

调用构造函数时,用户代理必须在控制线程上执行以下步骤:

当调用 AudioWorkletNode 构造函数时使用 contextnodeNameoptions
  1. 如果 nodeName 不存在于 BaseAudioContext节点名称到参数描述符映射 中,抛出 InvalidStateError 异常并中止这些步骤。

  2. node 值。

  3. 初始化 AudioNode nodecontextoptions 为参数。

  4. 配置 node 的输入、输出和输出通道,并使用 options。如果抛出任何异常,则中止其余步骤。

  5. messageChannel 为新建的 MessageChannel

  6. nodePortmessageChannelport1 属性的值。

  7. processorPortOnThisSidemessageChannelport2 属性的值。

  8. serializedProcessorPort结构化序列化带传输(processorPortOnThisSide, « processorPortOnThisSide ») 的结果。

  9. options 字典转换为 optionsObject

  10. serializedOptions结构化序列化(optionsObject) 的结果。

  11. nodeport 设置为 nodePort

  12. parameterDescriptors 为从 节点名称到参数描述符映射 检索到 nodeName 的结果:

    1. audioParamMap 为新建的 AudioParamMap 对象。

    2. 对于 parameterDescriptors 的每个 descriptor

      1. paramNamedescriptorname 成员的值。

      2. audioParam 为具有 automationRatedefaultValueminValuemaxValue 的新 AudioParam 实例,值等于 descriptor 上相应成员的值。

      3. 将键值对 paramNameaudioParam 添加到 audioParamMap 的条目中。

    3. 如果 parameterData 存在于 options 上,则执行以下步骤:

      1. parameterDataparameterData 的值。

      2. 对于 parameterData 的每个 paramNameparamValue

        1. 如果 audioParamMap 中存在键 paramName 的映射条目,令 audioParamInMap 为此条目。

        2. audioParamInMapvalue 属性设置为 paramValue

    4. nodeparameters 设置为 audioParamMap

  13. 排队一个控制消息,以 调用 对应 构造函数AudioWorkletProcessor,其 处理器构造数据 包含:nodeNamenodeserializedOptionsserializedProcessorPort

1.32.3.2. 属性

AudioWorkletNode/onprocessorerror

Firefox76+SafariNoneChrome67+
Opera?Edge79+
Edge (Legacy)NoneIENone
Firefox for Android79+iOS SafariNoneChrome for Android67+Android WebView67+Samsung Internet9.0+Opera Mobile?

onprocessorerror, 类型为 EventHandler

当处理器的 constructorprocess 方法或任何用户定义的类方法抛出未处理的异常时,处理器将排队一个媒体元素任务触发一个名为processorerror的事件,使用ErrorEvent,在关联的 AudioWorkletNode 上触发。

ErrorEvent 在控制线程上适当创建并初始化其 messagefilenamelinenocolno 属性。

请注意,一旦抛出未处理的异常,处理器将在其整个生命周期内输出静音。

AudioWorkletNode/parameters

Firefox76+SafariNoneChrome67+
OperaYesEdge79+
Edge (Legacy)NoneIENone
Firefox for Android79+iOS SafariNoneChrome for Android67+Android WebView67+Samsung Internet9.0+Opera MobileYes

parameters, 类型为 AudioParamMap,只读

parameters 属性是一个具有关联名称的 AudioParam 对象集合。此类类似映射的对象是从 AudioParamDescriptor 列表中,在 AudioWorkletProcessor 类构造函数实例化时填充的。

AudioWorkletNode/port

Firefox76+SafariNoneChrome67+
OperaYesEdge79+
Edge (Legacy)NoneIENone
Firefox for Android79+iOS SafariNoneChrome for Android67+Android WebView67+Samsung Internet9.0+Opera MobileYes

port, 类型为 MessagePort,只读

每个 AudioWorkletNode 都有一个关联的 port,它是 MessagePort。它连接到对应的 AudioWorkletProcessor 对象上的端口,允许 AudioWorkletNode 与其 AudioWorkletProcessor 之间进行双向通信。

注意: 在此 port 上注册事件监听器的作者,应在 关闭 之前调用此事件的任何一端 MessageChannel,以便资源被回收

1.32.3.3. AudioWorkletNodeOptions

AudioWorkletNodeOptions 字典可用于在 AudioWorkletNode 实例中初始化属性。

dictionary AudioWorkletNodeOptions : AudioNodeOptions {
  unsigned long numberOfInputs = 1;
  unsigned long numberOfOutputs = 1;
  sequence<unsigned long> outputChannelCount;
  record<DOMString, double> parameterData;
  object processorOptions;
};
1.32.3.3.1. 字典 AudioWorkletNodeOptions 成员
numberOfInputs, 类型为 unsigned long,默认值为 1

此参数用于初始化 AudioNodenumberOfInputs 属性值。

numberOfOutputs, 类型为 unsigned long,默认值为 1

此参数用于初始化 AudioNodenumberOfOutputs 属性值。

outputChannelCount, 类型为 sequence<unsigned long>

此数组用于配置每个输出中的通道数。

parameterData, of type record<DOMString, double>

这是用户定义的键值对列表,用于为具有匹配名称的 AudioParamAudioWorkletNode 设置初始 value

processorOptions, 类型为 object

此参数包含任何用户定义的数据,这些数据可用于初始化与 AudioWorkletNode 关联的 AudioWorkletProcessor 实例中的自定义属性。

1.32.3.3.2. 使用 AudioWorkletNodeOptions 配置通道

以下算法描述了如何使用 AudioWorkletNodeOptions 配置各种通道配置。

  1. node 为此算法中给定的 AudioWorkletNode 实例。

  2. 如果 numberOfInputsnumberOfOutputs 都为零,则抛出 NotSupportedError 并中止剩余步骤。

  3. 如果 outputChannelCount 存在

    1. 如果 outputChannelCount 中的任何值为零或大于实现的最大通道数,则抛出 NotSupportedError 并中止剩余步骤。

    2. 如果 outputChannelCount 的长度不等于 numberOfOutputs,则抛出 IndexSizeError 并中止剩余步骤。

    3. 如果 numberOfInputsnumberOfOutputs 都为 1,则将 node 输出的通道数设置为 outputChannelCount 中的一个值。

    4. 否则,将 node 的第 k 个输出的通道数设置为 outputChannelCount 序列中的第 k 个元素并返回。

  4. 如果 outputChannelCount 不存在

    1. 如果 numberOfInputsnumberOfOutputs 都为 1,则将 node 输出的初始通道数设置为 1 并返回。

      注意: 对于这种情况,输出通道数将根据输入和运行时的 channelCountMode 动态更改为 computedNumberOfChannels

    2. 否则,将 node 的每个输出的通道数设置为 1 并返回。

1.32.4. AudioWorkletProcessor 接口

此接口表示在音频 渲染线程 上运行的音频处理代码。它位于 AudioWorkletGlobalScope 中,该类的定义表现了实际的音频处理。注意,AudioWorkletProcessor 的构造只能作为 AudioWorkletNode 构造的结果发生。

AudioWorkletProcessor

Firefox76+SafariNoneChrome64+
Opera?Edge79+
Edge (Legacy)NoneIENone
Firefox for Android79+iOS SafariNoneChrome for Android64+Android WebView64+Samsung Internet9.0+Opera Mobile?
[Exposed=AudioWorklet]
interface AudioWorkletProcessor {
  constructor ();
  readonly attribute MessagePort port;
};

callback AudioWorkletProcessCallback =
  boolean (FrozenArray<FrozenArray<Float32Array>> inputs,
           FrozenArray<FrozenArray<Float32Array>> outputs,
           object parameters);

AudioWorkletProcessor 有两个内部槽位:

[[node reference]]

一个指向关联的 AudioWorkletNode 的引用。

[[callable process]]

一个表示 process() 是否为可调用函数的布尔标志。

1.32.4.1. 构造函数

AudioWorkletProcessor/AudioWorkletProcessor

Firefox76+SafariNoneChrome64+
Opera?Edge79+
Edge (Legacy)NoneIENone
Firefox for Android79+iOS SafariNoneChrome for Android64+Android WebView64+Samsung Internet9.0+Opera Mobile?

AudioWorkletProcessor()

AudioWorkletProcessor 的构造函数被调用时,以下步骤将在 渲染线程 上执行。

  1. nodeReference 设为在当前 AudioWorkletGlobalScopenode reference 中查找的结果。如果槽位为空,抛出 TypeError 异常。

  2. processor 设为 this 值。

  3. processor[[node reference]] 设为 nodeReference

  4. processor[[callable process]] 设为 true

  5. deserializedPort 设为从 transferred port 中查找的结果。

  6. processorport 设为 deserializedPort

  7. 清空 pending processor construction data 槽位。

1.32.4.2. 属性

AudioWorkletProcessor/port

Firefox76+SafariNoneChrome64+
Opera?Edge79+
Edge (Legacy)NoneIENone
Firefox for Android79+iOS SafariNoneChrome for Android64+Android WebView64+Samsung Internet9.0+Opera Mobile?

port, 类型为 MessagePort,只读

每个 AudioWorkletProcessor 都有一个关联的 port,它是一个 MessagePort。它连接到相应的 AudioWorkletNode 对象上的端口,允许 AudioWorkletNode 与其 AudioWorkletProcessor 之间进行双向通信。

注意:在此 port 上注册“message”事件监听器的作者应该在 close 调用后,在 MessageChannel 的任一端(在 AudioWorkletProcessorAudioWorkletNode 一侧)以允许资源被回收

1.32.4.3. 回调 AudioWorkletProcessCallback

用户可以通过扩展 AudioWorkletProcessor 来定义自定义音频处理器。子类必须定义一个名为 process()AudioWorkletProcessCallback,该回调函数实现音频处理算法,并且可能有一个名为 parameterDescriptors 的静态属性,它是 AudioParamDescriptor 的可迭代对象。

process() 回调函数处理时,根据 渲染图表 中的规定进行处理。

该回调的返回值控制 AudioWorkletProcessor 的关联 AudioWorkletNode 的生命周期。

该生命周期策略可以支持内置节点中发现的多种方法,包括以下几种:

请注意,上述定义意味着当未从 process() 的实现中提供返回值时,效果与返回 false 相同(因为有效的返回值是虚假的 undefined)。对于任何仅在具有活动输入时才处于活动状态的 AudioWorkletProcessor,这是合理的行为。

下面的示例展示了如何在 AudioWorkletProcessor 中定义和使用 AudioParam

class MyProcessor extends AudioWorkletProcessor {
  static get parameterDescriptors() {
    return [{
      name: 'myParam',
      defaultValue: 0.5,
      minValue: 0,
      maxValue: 1,
      automationRate: "k-rate"
    }];
  }

  process(inputs, outputs, parameters) {
    // Get the first input and output.
    const input = inputs[0];
    const output = outputs[0];
    const myParam = parameters.myParam;

    // A simple amplifier for single input and output. Note that the
    // automationRate is "k-rate", so it will have a single value at index [0]
    // for each render quantum.
    for (let channel = 0; channel < output.length; ++channel) {
      for (let i = 0; i < output[channel].length; ++i) {
        output[channel][i] = input[channel][i] * myParam[0];
      }
    }
  }
}
1.32.4.3.1. 回调 AudioWorkletProcessCallback 参数
以下描述了 AudioWorkletProcessCallback 函数的参数。

一般来说,inputsoutputs 数组将在调用之间重用,以避免进行内存分配。然而,如果拓扑结构发生变化,例如输入或输出的通道数量发生变化,则会重新分配新数组。如果 inputsoutputs 数组的任何部分被转移,也会重新分配新数组。

inputs,类型为 FrozenArray<FrozenArray<Float32Array>>

来自用户代理提供的输入音频缓冲区。inputs[n][m] 是第 \(n\) 个输入的第 \(m\) 个通道的音频样本的 Float32Array。虽然输入的数量在构建时是固定的,但通道的数量可以根据 computedNumberOfChannels 动态变化。

如果当前渲染量子的 AudioWorkletNode 的第 \(n\) 个输入没有连接任何 正在处理的 AudioNode,则 inputs[n] 的内容为空数组,表示没有可用的输入通道。这是 inputs[n] 的元素数量可以为零的唯一情况。

outputs,类型为 FrozenArray<FrozenArray<Float32Array>>

由用户代理消费的输出音频缓冲区。outputs[n][m] 是第 \(n\) 个输出的第 \(m\) 个通道的音频样本的 Float32Array 对象。每个 Float32Array 都是零填充的。当节点只有一个输出时,输出的通道数量将与 computedNumberOfChannels 匹配。

parameters,类型为 object

一个 有序映射 nameparameterValuesparameters["name"] 返回 parameterValues,它是一个 FrozenArray<Float32Array>,其中包含了 nameAudioParam 的自动化值。

对于每个数组,数组包含参数在整个 渲染量子 中的 计算值。但是,如果在这个渲染量子期间没有调度自动化,数组的长度可能为 1,数组元素是该 渲染量子AudioParam 的常量值。

根据以下步骤冻结此对象:

  1. parameter 为名称和参数值的 有序映射

  2. SetIntegrityLevel(parameter, frozen)

算法中计算出的此冻结的 有序映射 将传递给 parameters 参数。

注意: 这意味着对象无法修改,因此可以对连续调用使用相同的对象,除非数组的长度发生变化。

1.32.4.4. AudioParamDescriptor

AudioParamDescriptor 字典用于为在 AudioWorkletNode 中使用的 AudioParam 对象指定属性。

dictionary AudioParamDescriptor {
  required DOMString name;
  float defaultValue = 0;
  float minValue = -3.4028235e38;
  float maxValue = 3.4028235e38;
  AutomationRate automationRate = "a-rate";
};
1.32.4.4.1. Dictionary AudioParamDescriptor Members

这些成员的值存在约束条件。有关约束条件,请参阅处理 AudioParamDescriptor 的算法

automationRate, 类型为 AutomationRate,默认为 "a-rate"

表示默认的自动化速率。

defaultValue, 类型为 float,默认为 0

表示参数的默认值。

maxValue, 类型为 float,默认为 3.4028235e38

表示最大值。

minValue, 类型为 float,默认为 -3.4028235e38

表示最小值。

name, 类型为 DOMString

表示参数的名称。

1.32.5. AudioWorklet 事件序列

下图说明了相对于 AudioWorklet 发生的理想化事件序列:

AudioWorklet 序列

图中所示步骤是涉及创建 AudioContext 及其关联的 AudioWorkletGlobalScope,然后创建 AudioWorkletNode 及其关联的 AudioWorkletProcessor 的一种可能的事件序列。

  1. 创建一个 AudioContext

  2. 在主作用域中,请求 context.audioWorklet 添加一个脚本模块。

  3. 由于尚不存在,因此会创建一个新的 AudioWorkletGlobalScope,与上下文相关联。这是在其中评估 AudioWorkletProcessor 类定义的全局作用域。(在随后的调用中,将使用先前创建的作用域。)

  4. 导入的脚本在新创建的全局作用域中运行。

  5. 作为运行导入脚本的一部分,AudioWorkletProcessorAudioWorkletGlobalScope 中注册为一个键(在上图中为 "custom")。这会填充全局作用域和 AudioContext 中的映射。

  6. 解析 addModule() 调用的 Promise。

  7. 在主作用域中,使用用户指定的键和选项字典创建一个 AudioWorkletNode

  8. 作为节点创建的一部分,使用此键查找要实例化的正确 AudioWorkletProcessor 子类。

  9. 使用选项字典的结构化克隆实例化 AudioWorkletProcessor 子类的实例。此实例与先前创建的 AudioWorkletNode 配对。

1.32.6. AudioWorklet 示例

1.32.6.1. BitCrusher 节点

Bitcrushing 是一种通过量化样本值(模拟较低的位深度)和时间分辨率(模拟较低的采样率)来降低音频流质量的机制。此示例展示了如何在 AudioWorkletProcessor 内部使用 AudioParam(在这种情况下,作为 a-rate 处理)。

const context = new AudioContext();context.audioWorklet.addModule('bitcrusher.js').then(() => {  const osc = new OscillatorNode(context);  const amp = new GainNode(context);  // 创建一个 worklet 节点。“BitCrusher”标识了  // 在导入 bitcrusher.js 时已注册的 AudioWorkletProcessor。  // 这些选项会自动初始化相应名称的 AudioParams。  const bitcrusher = new AudioWorkletNode(context, 'bitcrusher', {    parameterData: {bitDepth: 8}  });  osc.connect(bitcrusher).connect(amp).connect(context.destination);  osc.start();});
class Bitcrusher extends AudioWorkletProcessor {  static get parameterDescriptors () {    return [{      name: 'bitDepth',      defaultValue: 12,      minValue: 1,      maxValue: 16    }, {      name: 'frequencyReduction',      defaultValue: 0.5,      minValue: 0,      maxValue: 1    }];  }  constructor (options) {    // 初始参数值可以通过将 |options| 传递给处理器的构造函数来设置。    super(options);    this._phase = 0;    this._lastSampleValue = 0;  }  process (inputs, outputs, parameters) {    const input = inputs[0];    const output = outputs[0];    const bitDepth = parameters.bitDepth;    const frequencyReduction = parameters.frequencyReduction;    if (bitDepth.length > 1) {      // bitDepth 参数数组有 128 个样本值。      for (let channel = 0; channel < output.length; ++channel) {        for (let i = 0; i < output[channel].length; ++i) {          let step = Math.pow(0.5, bitDepth[i]);          // 使用模运算索引以处理 frequencyReduction 数组          // 长度为 1 的情况。          this._phase += frequencyReduction[i % frequencyReduction.length];          if (this._phase >= 1.0) {            this._phase -= 1.0;            this._lastSampleValue =              step * Math.floor(input[channel][i] / step + 0.5);          }          output[channel][i] = this._lastSampleValue;        }      }    } else {      // 由于我们知道 bitDepth 在此调用中是常量,      // 我们可以将 step 的计算移到循环外,从而      // 节省许多操作。      const step = Math.pow(0.5, bitDepth[0]);      for (let channel = 0; channel < output.length; ++channel) {        for (let i = 0; i < output[channel].length; ++i) {          this._phase += frequencyReduction[i % frequencyReduction.length];          if (this._phase >= 1.0) {            this._phase -= 1.0;            this._lastSampleValue =              step * Math.floor(input[channel][i] / step + 0.5);          }          output[channel][i] = this._lastSampleValue;        }      }    }    // 不需要返回值;此节点的生命周期仅取决于其输入连接。  }});registerProcessor('bitcrusher', Bitcrusher);

注意:AudioWorkletProcessor 类的定义中,如果作者提供的构造函数具有明确的返回值但不是 this 或没有正确调用 super(),则会抛出 InvalidStateError

1.32.6.2. VU Meter 节点

此简单的声音电平计示例进一步说明了如何创建一个 AudioWorkletNode 子类,该子类像本机 AudioNode 一样工作,接受构造函数选项并封装 AudioWorkletNodeAudioWorkletProcessor 之间的跨线程通信(异步)。此节点不使用任何输出。

/* vumeter-node.js: Main global scope */export default class VUMeterNode extends AudioWorkletNode {  constructor (context, updateIntervalInMS) {    super(context, 'vumeter', {      numberOfInputs: 1,      numberOfOutputs: 0,      channelCount: 1,      processorOptions: {        updateIntervalInMS: updateIntervalInMS || 16.67;      }    });    // States in AudioWorkletNode    this._updateIntervalInMS = updateIntervalInMS;    this._volume = 0;    // Handles updated values from AudioWorkletProcessor    this.port.onmessage = event => {      if (event.data.volume)        this._volume = event.data.volume;    }    this.port.start();  }  get updateInterval() {    return this._updateIntervalInMS;  }  set updateInterval(updateIntervalInMS) {    this._updateIntervalInMS = updateIntervalInMS;    this.port.postMessage({updateIntervalInMS: updateIntervalInMS});  }  draw () {    // Draws the VU meter based on the volume value    // every |this._updateIntervalInMS| milliseconds.  }};
/* vumeter-processor.js: AudioWorkletGlobalScope */const SMOOTHING_FACTOR = 0.9;const MINIMUM_VALUE = 0.00001;registerProcessor('vumeter', class extends AudioWorkletProcessor {  constructor (options) {    super();    this._volume = 0;    this._updateIntervalInMS = options.processorOptions.updateIntervalInMS;    this._nextUpdateFrame = this._updateIntervalInMS;    this.port.onmessage = event => {      if (event.data.updateIntervalInMS)        this._updateIntervalInMS = event.data.updateIntervalInMS;    }  }  get intervalInFrames () {    return this._updateIntervalInMS / 1000 * sampleRate;  }  process (inputs, outputs, parameters) {    const input = inputs[0];    // Note that the input will be down-mixed to mono; however, if no inputs are    // connected then zero channels will be passed in.    if (input.length > 0) {      const samples = input[0];      let sum = 0;      let rms = 0;      // Calculated the squared-sum.      for (let i = 0; i < samples.length; ++i)        sum += samples[i] * samples[i];      // Calculate the RMS level and update the volume.      rms = Math.sqrt(sum / samples.length);      this._volume = Math.max(rms, this._volume * SMOOTHING_FACTOR);      // Update and sync the volume property with the main thread.      this._nextUpdateFrame -= samples.length;      if (this._nextUpdateFrame < 0) {        this._nextUpdateFrame += this.intervalInFrames;        this.port.postMessage({volume: this._volume});      }    }    // Keep on processing if the volume is above a threshold, so that    // disconnecting inputs does not immediately cause the meter to stop    // computing its smoothed value.    return this._volume >= MINIMUM_VALUE;  }});
/* index.js: Main global scope, entry point */import VUMeterNode from './vumeter-node.js';const context = new AudioContext();context.audioWorklet.addModule('vumeter-processor.js').then(() => {  const oscillator = new OscillatorNode(context);  const vuMeterNode = new VUMeterNode(context, 25);  oscillator.connect(vuMeterNode);  oscillator.start();  function drawMeter () {    vuMeterNode.draw();    requestAnimationFrame(drawMeter);  }  drawMeter();});

2. 处理模型

2.1. 背景

本节是非规范性的。

需要低延迟的实时音频系统通常使用回调函数实现,其中操作系统在需要计算更多音频以保持播放不中断时回调程序。理想情况下,这样的回调是在高优先级线程(通常是系统最高优先级)上调用的。这意味着处理音频的程序仅在此回调中执行代码。跨线程边界或在渲染线程和回调之间添加缓冲自然会增加延迟或使系统对故障的抗性降低。

因此,Web平台上传统的执行异步操作的方式(事件循环)在这里不起作用,因为线程并未持续执行。此外,传统执行上下文(Windows 和 Workers)中提供了许多不必要且可能阻塞的操作,而这些操作在达到可接受的性能水平时并不理想。

此外,Worker模型要求为脚本执行上下文创建专用线程,而所有AudioNode通常共享相同的执行上下文。

注意:本节规定了最终结果应如何呈现,而不是如何实现。特别地,替代消息队列,开发者可以使用线程之间共享的内存,只要内存操作不被重新排序。

2.2. 控制线程和渲染线程

Web Audio API 必须使用控制线程渲染线程来实现。

控制线程是实例化AudioContext的线程,开发者通过该线程操作音频图,即在BaseAudioContext上执行操作。渲染线程是计算实际音频输出的线程,用于响应来自控制线程的调用。如果是为AudioContext计算音频,渲染线程可以是基于回调的实时音频线程;如果是为OfflineAudioContext计算音频,则可以是普通线程。

控制线程使用传统的事件循环,如[HTML]中所述。

渲染线程使用专门的渲染循环,描述在渲染音频图部分。

控制线程渲染线程的通信通过传递控制消息来完成。反方向的通信则使用常规的事件循环任务。

每个AudioContext都有一个控制消息队列,该队列是一组在渲染线程上运行的控制消息

排队控制消息意味着将消息添加到BaseAudioContext控制消息队列的末尾。

注意:例如,成功调用start()方法启动AudioBufferSourceNodesource时,会将一个控制消息添加到相关的BaseAudioContext控制消息队列中。

控制消息控制消息队列中按插入时间排序。因此,最早的消息位于控制消息队列的前面。

交换控制消息队列QA与另一个控制消息队列QB意味着执行以下步骤:
  1. QC成为一个新的、空的控制消息队列

  2. 将所有的控制消息QA移动到QC

  3. 将所有的控制消息QB移动到QA

  4. 将所有的控制消息QC移动到QB

2.3. 异步操作

调用 AudioNode 方法 实际上是异步的,必须分为两个阶段进行:同步部分和异步部分。对于每个方法,部分执行发生在 控制线程 上(例如,在参数无效的情况下抛出异常),而另一部分发生在 渲染线程 上(例如,更改 AudioParam 的值)。

AudioNodeBaseAudioContext 的每个操作描述中, 同步部分用 ⌛ 标记。所有其他操作都按照 并行 执行, 如 [HTML] 中所述。

同步部分在 控制线程 上执行,并且立即发生。如果失败,方法执行将被中止, 可能会抛出异常。如果成功,则将编码要在 渲染线程 上执行的操作的 控制消息 排入该 控制消息队列

同步和异步部分相对于其他事件的顺序必须保持一致:给定两个操作 AB 及其各自的同步和 异步部分 ASyncAAsync,以及 BSyncBAsync,如果 A 发生在 B 之前, 那么 ASync 发生在 BSync 之前,并且 AAsync 发生在 BAsync 之前。换句话说,同步和 异步部分不能重新排序。

2.4. 渲染音频图

渲染音频图是以128样本帧为单位完成的。一个128样本帧的块称为渲染量子, 而渲染量子大小为128。

在给定线程上原子化发生的操作只能在没有其他原子操作正在另一线程上运行时执行。

BaseAudioContext G渲染音频块的算法与控制消息队列Q包括多个步骤,并在渲染图表的算法中进一步详细说明。

实际上,AudioContext 渲染线程通常在系统级音频回调之外运行,以同步方式执行。

OfflineAudioContext 不需要有系统级音频回调,但表现得好像它有,回调在前一个回调完成后立即发生。

音频回调也作为任务在控制消息队列中排队。用户代理必须执行以下算法来处理渲染量子以完成此任务,并填充请求的缓冲区大小。与控制消息队列一起,每个AudioContext都有一个常规任务队列,称为其关联任务队列,用于从控制线程发布到渲染线程的任务。在处理渲染量子后,还会执行一个额外的微任务检查点,以运行在执行process方法期间可能已排队的任何微任务。

AudioWorkletNode发布的所有任务都发布到其关联的BaseAudioContext关联任务队列中。

在渲染循环开始之前,必须执行以下步骤一次。
  1. [[current frame]]内部槽的值设置为BaseAudioContext为0。同样将currentTime设置为0。

渲染渲染量子时必须执行以下步骤。
  1. render resultfalse

  2. 处理控制消息队列

    1. Qrendering为一个空的控制消息队列原子化交换Qrendering与当前的控制消息队列

    2. Qrendering中有消息时,执行以下步骤:

      1. 执行Qrendering最早消息的异步部分。

      2. 移除Qrendering中的最早消息

  3. 处理BaseAudioContext关联任务队列

    1. task queueBaseAudioContext关联任务队列

    2. task counttask queue中的任务数。

    3. task count不等于0时,执行以下步骤:

      1. oldest tasktask queue中的第一个可运行任务,并将其从task queue中移除。

      2. 将渲染循环的当前运行任务设置为oldest task

      3. 执行oldest task的步骤。

      4. 将渲染循环的当前运行任务设置回null

      5. 减少task count

      6. 执行微任务检查点。

  4. 处理渲染量子。

    1. 如果[[rendering thread state]]BaseAudioContext不是running,则返回false。

    2. AudioNodeBaseAudioContext处理。

      1. ordered node list成为一个空列表,包括AudioNodeAudioListener。该算法终止后,它将包含一个AudioNodeAudioListener的有序列表。

      2. nodes成为由BaseAudioContext创建的所有节点的集合,并且仍然存在。

      3. AudioListener添加到nodes中。

      4. cycle breakers成为一个空集合,包含DelayNode。它将包含所有DelayNode是循环的一部分。

      5. 对于nodes中的每个AudioNodenode

        1. 如果nodeDelayNode,并且是循环的一部分,将其添加到cycle breakers中,并从nodes中移除。

      6. 对于cycle breakers中的每个DelayNodedelay

        1. 分别让delayWriterdelayReader成为delayDelayWriterDelayReader。将delayWriterdelayReader添加到nodes中。断开delay与其所有输入和输出的连接。

          注意:这会打破循环:如果DelayNode在循环中,则可以单独考虑其两端,因为在循环中延迟线不能小于一个渲染量子。

      7. 如果nodes包含循环,将AudioNode在循环中的所有节点静音,并从nodes中移除它们。

      8. nodes中的所有元素视为未标记的。当nodes中有未标记的元素时:

        1. 选择nodes中的一个元素node

        2. 访问node

        访问节点意味着执行以下步骤:
        1. 如果node已标记,则中止这些步骤。

        2. 标记node

        3. 如果nodeAudioNode,则访问node的每个连接到其输入的AudioNode

        4. 对于node的每个AudioParamparam

          1. 对于连接到param的每个AudioNodeparam input node

            1. 访问param input node

        5. node添加到ordered node list的开头。

      9. 反转ordered node list的顺序。

    3. 计算AudioListenerAudioParam的值用于此块。

    4. 对于ordered node list中的每个AudioNode

      1. 对于此AudioNode的每个AudioParam,执行以下步骤:

        1. 如果此AudioParam具有任何连接到它的AudioNode,则求和所有可读取的缓冲区,通过所有AudioNode连接到此AudioParam下混音结果缓冲区并将此缓冲区称为输入AudioParam缓冲区

        2. 计算此块的AudioParam的值。

        3. 排队控制消息设置[[current value]]槽的此AudioParam根据§ 1.6.3值的计算

      2. 如果此AudioNode具有任何连接到其输入的AudioNode,则求和所有可读取的缓冲区,通过所有连接到此AudioNode的缓冲区。生成的缓冲区称为输入缓冲区向上或向下混合以匹配此AudioNode的输入通道数。

      3. 如果此AudioNode源节点,则计算一个音频块,并使其可读取

      4. 如果此AudioNodeAudioWorkletNode,执行这些子步骤:

        1. processor成为关联的AudioWorkletProcessor实例的AudioWorkletNode

        2. O成为与processor对应的ECMAScript对象。

        3. processCallback成为一个未初始化的变量。

        4. completion成为一个未初始化的变量。

        5. 准备运行脚本,并使用当前设置对象

        6. 准备运行回调,并使用当前设置对象

        7. getResult成为 获取(O,"process")的结果。

        8. 如果getResult 异常完成,将completion设置为getResult,并跳转到标记为返回的步骤。

        9. processCallback设置为getResult.[[值]]。

        10. 如果!IsCallable(processCallback)为false,则:

          1. completion设置为新建的Completion{[[类型]]: throw, [[值]]: 新创建的TypeError对象, [[目标]]: 空}。

          2. 跳转到标记为返回的步骤。

        11. [[可调用的处理]]设置为true

        12. 执行以下子步骤:

          1. args成为 Web IDL参数列表,包括inputsoutputs,和parameters

          2. esArgs成为 转换args为ECMAScript参数列表的结果。

          3. callResult成为 调用(processCallback,O,esArgs)的结果。此操作计算一个音频块esArgs。成功调用函数后,包含Float32Array元素的缓冲区的副本将通过outputs传递并可读取。在此调用中解析的任何Promise将排队到AudioWorkletGlobalScope的微任务队列中。

          4. 如果callResult 异常完成,将completion设置为callResult,并跳转到标记为返回的步骤。

          5. processor活动源标志设置为 ToBoolean(callResult.[[值]])。

        13. 返回:此时completion将设置为ECMAScript完成值。

          1. 回调运行后的清理,并使用当前设置对象

          2. 脚本运行后的清理,并使用当前设置对象

          3. 如果completion 异常完成

            1. [[可调用的处理]]设置为false

            2. processor活动源标志设置为false

            3. 提供一个静音输出缓冲区以供读取

            4. 将任务排队控制线程触发名为ErrorEventprocessorerror事件在关联的AudioWorkletNode上。

      5. 如果此AudioNode目的节点,则记录输入AudioNode

      6. 否则,处理输入缓冲区,并使生成的缓冲区可供读取

    5. 原子化执行以下步骤:

      1. 增加[[current frame]]渲染量子大小

      2. 设置currentTime[[current frame]]除以sampleRate

    6. 设置render resulttrue

  5. 执行微任务检查点

  6. 返回render result

静音一个AudioNode意味着其输出在此音频块的渲染中必须为静音。

使缓冲区可供读取来自一个AudioNode意味着将其置于一个状态,使得连接到此AudioNode的其他AudioNode可以安全地从中读取。

注意:例如,实现可以选择分配一个新的缓冲区,或采用更复杂的机制,重用现在未使用的现有缓冲区。

记录输入一个AudioNode意味着复制此AudioNode的输入数据以供将来使用。

计算一个音频块意味着运行此AudioNode的算法,以生成128个样本帧。

处理输入缓冲区意味着运行一个AudioNode的算法,使用一个输入缓冲区和此AudioParam的值作为此算法的输入。

2.5. 卸载文档

额外的卸载文档清理步骤为使用BaseAudioContext的文档定义:
  1. 对于每个AudioContextOfflineAudioContext,其相关的全局对象与文档关联的窗口相同,使用InvalidStateError拒绝所有[[pending promises]]

  2. 停止所有解码线程

  3. 排队控制消息close()AudioContextOfflineAudioContext

3. 动态生命周期

3.1. 背景

注意:AudioContextAudioNode生命周期特性的规范描述见AudioContext生命周期AudioNode生命周期

本节为非规范性内容。

除了允许创建静态路由配置外,还应该可以对具有有限生命周期的动态分配声音进行自定义效果路由。为了讨论的目的,我们将这些短命的声音称为"音符"。许多音频应用程序都包含音符的概念,例如鼓机、音序器和3D游戏,其中根据游戏进程触发许多一次性声音。

在传统的软件合成器中,音符是从可用资源池中动态分配和释放的。当收到MIDI音符开启消息时,音符被分配。当音符由于到达了其样本数据的末尾(如果不是循环的)、到达其包络的保持阶段(为零),或者由于MIDI音符关闭消息将其置于包络的释放阶段时,音符将被释放。在MIDI音符关闭的情况下,音符不会立即释放,而是仅在释放包络阶段完成后才释放。在任何给定时间内,可能有大量的音符正在播放,但音符集会不断变化,因为新音符被添加到路由图中,而旧音符被释放。

音频系统自动处理单个"音符"事件的路由图部分的拆除。"音符"由AudioBufferSourceNode表示,它可以直接连接到其他处理节点。当音符播放完毕时,context将自动释放对AudioBufferSourceNode的引用,反过来,这将释放它连接到的任何节点的引用,依此类推。这些节点将自动从图中断开连接,并在没有更多引用时被删除。图中长寿命且在动态声音之间共享的节点可以显式管理。虽然这听起来很复杂,但这一切都是自动发生的,不需要额外的处理。

3.2. 示例

动态分配
一个包含将被提前释放的子图的图表。

低通滤波器、声像器和第二个增益节点直接连接到一次性声音。因此,当它播放完毕时,context将自动释放它们(虚线内的所有内容)。如果不再有对一次性声音和连接节点的引用,那么它们将立即从图中移除并删除。流源具有全局引用,将保持连接,直到显式断开连接为止。以下是它在JavaScript中的可能样子:

let context = 0;let compressor = 0;let gainNode1 = 0;let streamingAudioSource = 0;// Initial setup of the "long-lived" part of the routing graphfunction setupAudioContext() {    context = new AudioContext();    compressor = context.createDynamicsCompressor();    gainNode1 = context.createGain();    // Create a streaming audio source.    const audioElement = document.getElementById('audioTagID');    streamingAudioSource = context.createMediaElementSource(audioElement);    streamingAudioSource.connect(gainNode1);    gainNode1.connect(compressor);    compressor.connect(context.destination);}// Later in response to some user action (typically mouse or key event)// a one-shot sound can be played.function playSound() {    const oneShotSound = context.createBufferSource();    oneShotSound.buffer = dogBarkingBuffer;    // Create a filter, panner, and gain node.    const lowpass = context.createBiquadFilter();    const panner = context.createPanner();    const gainNode2 = context.createGain();    // Make connections    oneShotSound.connect(lowpass);    lowpass.connect(panner);    panner.connect(gainNode2);    gainNode2.connect(compressor);    // Play 0.75 seconds from now (to play immediately pass in 0)    oneShotSound.start(context.currentTime + 0.75);}

4. 通道上混音和下混音

本节为规范性内容。

AudioNode输入具有混音规则,用于组合所有连接到它的通道。一个简单的例子是,如果一个输入连接了一个单声道输出和一个立体声输出,那么单声道连接通常会被上混音为立体声并与立体声连接相加。当然,为每个AudioNode的每个输入定义确切的混音规则是很重要的。所有输入的默认混音规则已被选择,以便在不需要过多关注细节的情况下,尤其是在单声道和立体声流的非常常见的情况下,"即插即用"。当然,这些规则可以根据高级用例进行更改,特别是多通道的情况下。

为了定义一些术语,上混音指的是将一个具有较少通道的流转换为具有较多通道的流的过程。下混音指的是将一个具有较多通道的流转换为具有较少通道的流的过程。

AudioNode的输入需要混合所有连接到此输入的输出。作为此过程的一部分,它会计算一个内部值computedNumberOfChannels,表示在任何给定时间输入的实际通道数。

对于每个AudioNode的输入,实现必须:
  1. 计算computedNumberOfChannels

  2. 对于连接到输入的每个连接:

    1. 根据节点的ChannelInterpretation属性给出的值,将连接上混音下混音computedNumberOfChannels

    2. 将其与所有其他混合流(来自其他连接)混合在一起。这是一个直接的将每个对应的通道相加的过程,这些通道在步骤1中对于每个连接都已上混音下混音

4.1. 扬声器通道布局

channelInterpretation为"speakers"时,将为特定通道布局定义上混音下混音

必须支持单声道(一通道)、立体声(两通道)、四声道(四通道)和5.1(六通道)。其他通道布局可能会在本规范的未来版本中支持。

4.2. 通道排序

通道排序由下表定义。单个多通道格式可能不支持所有中间通道。实现必须按下面定义的顺序呈现提供的通道,跳过不存在的通道。

顺序 标签 单声道 立体声 四声道 5.1
0 SPEAKER_FRONT_LEFT 0 0 0 0
1 SPEAKER_FRONT_RIGHT 1 1 1
2 SPEAKER_FRONT_CENTER 2
3 SPEAKER_LOW_FREQUENCY 3
4 SPEAKER_BACK_LEFT 2 4
5 SPEAKER_BACK_RIGHT 3 5
6 SPEAKER_FRONT_LEFT_OF_CENTER
7 SPEAKER_FRONT_RIGHT_OF_CENTER
8 SPEAKER_BACK_CENTER
9 SPEAKER_SIDE_LEFT
10 SPEAKER_SIDE_RIGHT
11 SPEAKER_TOP_CENTER
12 SPEAKER_TOP_FRONT_LEFT
13 SPEAKER_TOP_FRONT_CENTER
14 SPEAKER_TOP_FRONT_RIGHT
15 SPEAKER_TOP_BACK_LEFT
16 SPEAKER_TOP_BACK_CENTER
17 SPEAKER_TOP_BACK_RIGHT

4.3. 尾时间对输入和输出通道数量的影响

当一个AudioNode具有非零的尾时间,并且输出通道数取决于输入通道数时,当输入通道数发生变化时,必须考虑AudioNode尾时间

当输入通道数减少时,输出通道数的变化必须在具有较高通道数的输入不再影响输出时发生。

当输入通道数增加时,行为取决于AudioNode的类型:

注意:直观上,这允许在处理过程中不丢失立体声信息:当多个具有不同通道数的输入渲染量子共同作用于输出渲染量子时,输出渲染量子的通道数是输入渲染量子的通道数的超集。

4.4. 扬声器布局的上混音

单声道上混音:

  1 -> 2 : 从单声道上混音到立体声
    output.L = input;
    output.R = input;

  1 -> 4 : 从单声道上混音到四声道
    output.L = input;
    output.R = input;
    output.SL = 0;
    output.SR = 0;

  1 -> 5.1 : 从单声道上混音到5.1
    output.L = 0;
    output.R = 0;
    output.C = input; // 放入中心通道
    output.LFE = 0;
    output.SL = 0;
    output.SR = 0;

立体声上混音:

  2 -> 4 : 从立体声上混音到四声道
    output.L = input.L;
    output.R = input.R;
    output.SL = 0;
    output.SR = 0;

  2 -> 5.1 : 从立体声上混音到5.1
    output.L = input.L;
    output.R = input.R;
    output.C = 0;
    output.LFE = 0;
    output.SL = 0;
    output.SR = 0;

四声道上混音:

  4 -> 5.1 : 从四声道上混音到5.1
    output.L = input.L;
    output.R = input.R;
    output.C = 0;
    output.LFE = 0;
    output.SL = input.SL;
    output.SR = input.SR;

4.5. 扬声器布局的下混音

例如,如果处理5.1声道的源材料,但在立体声中回放,则需要下混音。

单声道下混音:

  2 -> 1 : 立体声到单声道
    output = 0.5 * (input.L + input.R);

  4 -> 1 : 四声道到单声道
    output = 0.25 * (input.L + input.R + input.SL + input.SR);

  5.1 -> 1 : 5.1到单声道
    output = sqrt(0.5) * (input.L + input.R) + input.C + 0.5 * (input.SL + input.SR)

立体声下混音:

  4 -> 2 : 四声道到立体声
    output.L = 0.5 * (input.L + input.SL);
    output.R = 0.5 * (input.R + input.SR);

  5.1 -> 2 : 5.1到立体声
    output.L = L + sqrt(0.5) * (input.C + input.SL)
    output.R = R + sqrt(0.5) * (input.C + input.SR)

四声道下混音:

  5.1 -> 4 : 5.1到四声道
    output.L = L + sqrt(0.5) * input.C
    output.R = R + sqrt(0.5) * input.C
    output.SL = input.SL
    output.SR = input.SR

4.6. 通道规则示例

// 将增益节点设置为显式2通道(立体声)。gain.channelCount = 2;gain.channelCountMode = "explicit";gain.channelInterpretation = "speakers";// 将"硬件输出"设置为4通道用于具有两个立体声输出总线的DJ应用程序。context.destination.channelCount = 4;context.destination.channelCountMode = "explicit";context.destination.channelInterpretation = "discrete";// 将"硬件输出"设置为8通道用于自定义多通道扬声器阵列// 具有自定义矩阵混音。context.destination.channelCount = 8;context.destination.channelCountMode = "explicit";context.destination.channelInterpretation = "discrete";// 设置"硬件输出"为5.1以播放HTMLAudioElement。context.destination.channelCount = 6;context.destination.channelCountMode = "explicit";context.destination.channelInterpretation = "speakers";// 显式下混音到单声道。gain.channelCount = 1;gain.channelCountMode = "explicit";gain.channelInterpretation = "speakers";

5. 音频信号值

5.1. 音频采样格式

线性脉冲编码调制(线性 PCM)描述了一种 格式,其中音频值在固定间隔内采样,并且两个连续值之间的量化级别是线性均匀的。

在此规范中,任何暴露给脚本的信号值都采用线性32位浮点脉冲编码调制格式(线性32位浮点 PCM),通常以Float32Array 对象的形式。

5.2. 渲染

在任何音频图的目标节点处,所有音频信号的范围通常为 [-1, 1]。此规范未定义超出此范围的信号值或NaN、正无穷或负无穷的音频渲染效果。

6. 空间化/声像控制

6.1. 背景

现代3D游戏的一个常见功能需求是能够在3D空间中动态地空间化和移动多个音频源。例如,OpenAL具有这种能力。

使用PannerNode,可以 相对于AudioListener 在空间中定位或空间化音频流。BaseAudioContext 将包含一个AudioListener。 平移器和监听器都有使用右手笛卡尔坐标系的3D空间中的位置。坐标系中使用的单位未定义,也不需要定义,因为这些坐标计算的效果与任何特定单位(如米或英尺)无关。PannerNode 对象(代表音源流)具有一个表示声音投射方向的方向向量。此外,它们还有一个声锥 ,表示声音的方向性。例如,声音可以是全向的,在任何地方都能听到,而与其方向无关,或者可以更具方向性,只有在面向听众时才能听到。AudioListener 对象(代表人的耳朵)有前向向上向量,表示人面向的方向。

空间化的坐标系如下图所示,显示了默认值。AudioListenerPannerNode 的位置已从默认位置移动,以便我们能更好地看到。

panner-coord
显示 AudioListener 和 PannerNode 属性的坐标系示意图。

在渲染期间,PannerNode 计算方位角仰角。这些值由实现内部使用,以呈现空间化效果。有关如何使用这些值的详细信息,请参见声像控制算法部分。

6.2. 方位角和仰角

必须使用以下算法来计算方位角仰角,该算法适用于PannerNode。 实现必须适当考虑以下各个AudioParam 是“a-rate” 还是“k-rate”。

// Let |context| be a BaseAudioContext and let |panner| be a// PannerNode created in |context|.// Calculate the source-listener vector.const listener = context.listener;const sourcePosition = new Vec3(panner.positionX.value, panner.positionY.value,                                panner.positionZ.value);const listenerPosition =    new Vec3(listener.positionX.value, listener.positionY.value,             listener.positionZ.value);const sourceListener = sourcePosition.diff(listenerPosition).normalize();if (sourceListener.magnitude == 0) {  // Handle degenerate case if source and listener are at the same point.  azimuth = 0;  elevation = 0;  return;}// Align axes.const listenerForward = new Vec3(listener.forwardX.value, listener.forwardY.value,                                 listener.forwardZ.value);const listenerUp =    new Vec3(listener.upX.value, listener.upY.value, listener.upZ.value);const listenerRight = listenerForward.cross(listenerUp);if (listenerRight.magnitude == 0) {  // Handle the case where listener’s 'up' and 'forward' vectors are linearly  // dependent, in which case 'right' cannot be determined  azimuth = 0;  elevation = 0;  return;}// Determine a unit vector orthogonal to listener’s right, forwardconst listenerRightNorm = listenerRight.normalize();const listenerForwardNorm = listenerForward.normalize();const up = listenerRightNorm.cross(listenerForwardNorm);const upProjection = sourceListener.dot(up);const projectedSource = sourceListener.diff(up.scale(upProjection)).normalize();azimuth = 180 * Math.acos(projectedSource.dot(listenerRightNorm)) / Math.PI;// Source in front or behind the listener.const frontBack = projectedSource.dot(listenerForwardNorm);if (frontBack < 0)  azimuth = 360 - azimuth;// Make azimuth relative to "forward" and not "right" listener vector.if ((azimuth >= 0) && (azimuth <= 270))  azimuth = 90 - azimuth;else  azimuth = 450 - azimuth;elevation = 90 - 180 * Math.acos(sourceListener.dot(up)) / Math.PI;if (elevation > 90)  elevation = 180 - elevation;else if (elevation < -90)  elevation = -180 - elevation;

6.3. 声像控制算法

单声道到立体声立体声到立体声声像控制必须得到支持。当输入的所有连接都是单声道时,使用单声道到立体声处理。否则使用立体声到立体声处理。

6.3.1. PannerNode "equalpower" 声像控制

这是一个简单且相对低成本的算法,提供了基本但合理的结果。当PannerNodepanningModel属性设置为"equalpower"时使用, 在这种情况下仰角值将被忽略。必须根据automationRate指定的适当速率实现此算法。 如果PannerNode的 任何AudioParamAudioListener的任何 AudioParam 是 "a-rate", 则必须使用a-rate处理。

  1. 对于此AudioNode要计算的每个样本:

    1. azimuth成为在方位角和仰角部分中计算的值。

    2. 首先将azimuth值限制在[-90, 90]范围内:

      // 首先,将方位角限制在[-180, 180]的允许范围内。
      azimuth = max(-180, azimuth);
      azimuth = min(180, azimuth);
      
      // 然后将其调整到[-90, 90]范围内。
      if (azimuth < -90)
        azimuth = -180 - azimuth;
      else if (azimuth > 90)
        azimuth = 180 - azimuth;
      
    3. 对于单声道输入,从azimuth计算一个归一化的值x

      x = (azimuth + 90) / 180;
      

      对于立体声输入:

      if (azimuth <= 0) { // -90 -> 0
        // 将方位角值从[-90, 0]度转换为[-90, 90]范围。
        x = (azimuth + 90) / 90;
      } else { // 0 -> 90
        // 将方位角值从[0, 90]度转换为[-90, 90]范围。
        x = azimuth / 90;
      }
      
    4. 左声道和右声道增益值计算如下:

      gainL = cos(x * Math.PI / 2);
      gainR = sin(x * Math.PI / 2);
      
    5. 对于单声道输入,立体声输出的计算方法如下:

      outputL = input * gainL;
      outputR = input * gainR;
      

      对于立体声输入,输出计算如下:

      if (azimuth <= 0) {
        outputL = inputL + inputR * gainL;
        outputR = inputR * gainR;
      } else {
        outputL = inputL * gainL;
        outputR = inputR + inputL * gainR;
      }
      
    6. 应用距离增益和声锥增益,距离的计算描述在距离效果中,声锥增益的描述在声锥中:

      let distance = distance();
      let distanceGain = distanceModel(distance);
      let totalGain = coneGain() * distanceGain();
      outputL = totalGain * outputL;
      outputR = totalGain * outputR;
      

6.3.2. PannerNode "HRTF" 声像控制(仅限立体声)

这需要一组在各种方位角和仰角下记录的HRTF (头部相关传递函数)脉冲响应。实现需要一个高度优化的卷积函数。虽然比"equalpower"的成本略高,但提供了更具感知的空间化声音。

使用 HRTF 声像控制源的过程示意图。

6.3.3. StereoPannerNode 声像控制

对于StereoPannerNode, 必须实现以下算法。
  1. 对于此AudioNode要计算的每个样本:

    1. pan成为此StereoPannerNodepanAudioParamcomputedValue

    2. pan限制在[-1, 1]范围内。

      pan = max(-1, pan);
      pan = min(1, pan);
      
    3. 通过将pan值归一化到[0, 1]计算x。对于单声道输入:

      x = (pan + 1) / 2;
      

      对于立体声输入:

      if (pan <= 0)
        x = pan + 1;
      else
        x = pan;
      
    4. 左声道和右声道增益值计算如下:

      gainL = cos(x * Math.PI / 2);
      gainR = sin(x * Math.PI / 2);
      
    5. 对于单声道输入,立体声输出的计算方法如下:

      outputL = input * gainL;
      outputR = input * gainR;
      

      对于立体声输入,输出计算如下:

      if (pan <= 0) {
        outputL = inputL + inputR * gainL;
        outputR = inputR * gainR;
      } else {
        outputL = inputL * gainL;
        outputR = inputR + inputL * gainR;
      }
      

6.4. 距离效果

距离较近的声音较大,而距离较远的声音则较小。声音的音量如何随着与听者的距离变化取决于distanceModel属性。

在音频渲染过程中,将根据声像器和听者的位置计算出distance值,计算方式如下:

function distance(panner) {  const pannerPosition = new Vec3(panner.positionX.value, panner.positionY.value,                                  panner.positionZ.value);  const listener = context.listener;  const listenerPosition =      new Vec3(listener.positionX.value, listener.positionY.value,               listener.positionZ.value);  return pannerPosition.diff(listenerPosition).magnitude;}

distance将用于计算依赖于distanceModel属性的distanceGain值。有关每个距离模型的计算详情,请参见DistanceModelType部分。

在其处理过程中,PannerNode会通过distanceGain缩放/乘以输入音频信号,以使远处的声音变得更安静,而靠近的声音更响亮。

6.5. 声音锥体

听者和每个声源都有一个描述其朝向的方向向量。每个声源的声音投射特性由内锥和外锥描述,表示声源的声音强度是其与听者的角度与声源朝向向量的函数。因此,直接面向听者的声源声音会更响亮,而偏离轴线的声音会更安静。声源也可以是全向的。

下图说明了声源锥体相对于听者的位置关系。在图中,coneInnerAngle= 50coneOuterAngle= 120。即,内锥体在方向向量的两侧各延伸25度。同样,外锥体在两侧各延伸60度。

cone-diagram
声源锥体角度与声源朝向和听者位置及朝向的关系图。

必须使用以下算法来计算由于锥体效应产生的增益,给定声源(PannerNode)和听者:

function coneGain() {  const sourceOrientation =      new Vec3(source.orientationX, source.orientationY, source.orientationZ);  if (sourceOrientation.magnitude == 0 ||      ((source.coneInnerAngle == 360) && (source.coneOuterAngle == 360)))    return 1; // no cone specified - unity gain  // Normalized source-listener vector  const sourcePosition = new Vec3(panner.positionX.value, panner.positionY.value,                                  panner.positionZ.value);  const listenerPosition =      new Vec3(listener.positionX.value, listener.positionY.value,               listener.positionZ.value);  const sourceToListener = sourcePosition.diff(listenerPosition).normalize();  const normalizedSourceOrientation = sourceOrientation.normalize();  // Angle between the source orientation vector and the source-listener vector  const angle = 180 *                Math.acos(sourceToListener.dot(normalizedSourceOrientation)) /                Math.PI;  const absAngle = Math.abs(angle);  // Divide by 2 here since API is entire angle (not half-angle)  const absInnerAngle = Math.abs(source.coneInnerAngle) / 2;  const absOuterAngle = Math.abs(source.coneOuterAngle) / 2;  let gain = 1;  if (absAngle <= absInnerAngle) {    // No attenuation    gain = 1;  } else if (absAngle >= absOuterAngle) {    // Max attenuation    gain = source.coneOuterGain;  } else {    // Between inner and outer cones    // inner -> outer, x goes from 0 -> 1    const x = (absAngle - absInnerAngle) / (absOuterAngle - absInnerAngle);    gain = (1 - x) + source.coneOuterGain * x;  }  return gain;}

7. 性能考虑

7.1. 延迟

latency
延迟可能很重要的用例

对于Web应用程序,鼠标和键盘事件(keydown, mousedown等)与声音被听到之间的时间延迟是很重要的。

这种时间延迟称为延迟,它是由多个因素(输入设备延迟、内部缓冲延迟、DSP处理延迟、输出设备延迟、用户耳朵与扬声器之间的距离等)引起的,并且是累积的。延迟越大,用户的体验就越差。在极端情况下,它可能使音乐制作或游戏无法进行。在中等水平上,它会影响时间的把握,给人一种声音滞后或游戏不响应的印象。对于音乐应用程序,时间问题会影响节奏。对于游戏,时间问题会影响游戏玩法的精确度。对于交互式应用程序,它通常会像非常低的动画帧率一样降低用户体验。根据应用程序的不同,可接受的延迟范围可能从3-6毫秒到25-50毫秒不等。

实现通常会寻求将整体延迟降到最低。

除了最小化整体延迟外,实现通常还会寻求最小化AudioContextcurrentTimeAudioProcessingEventplaybackTime之间的差异。 ScriptProcessorNode的弃用将使这一考虑随着时间的推移变得不那么重要。

此外,一些AudioNode可能会增加音频图中某些路径的延迟,特别是:

7.2. 音频缓冲复制

当对AudioBuffer执行获取内容操作时,整个操作通常可以在不复制通道数据的情况下实现。特别是最后一步应在下次调用getChannelData()时懒惰地执行。 这意味着一系列连续的AudioBufferSourceNode播放相同AudioBuffer获取内容操作序列可以在没有分配或复制的情况下实现。

实现可以执行额外的优化:如果在AudioBuffer上调用getChannelData()时,还没有分配新的ArrayBuffer,但所有先前在AudioBuffer上进行的获取内容操作的调用者已停止使用AudioBuffer的数据, 则可以将原始数据缓冲区回收供新的AudioBuffer使用,从而避免任何重新分配或复制通道数据。

7.3. AudioParam过渡

虽然直接设置AudioParamvalue属性时不会自动平滑处理,但对于某些参数,平滑过渡比直接设置值更为理想。

使用setTargetAtTime()方法并设置较低的timeConstant允许开发者进行平滑过渡。

7.4. 音频故障

音频故障是由正常的连续音频流中断引起的,导致响亮的点击声和爆裂声。它被认为是多媒体系统的灾难性故障,必须避免。它可能是由负责将音频流传递到硬件的线程问题引起的,例如由于线程没有适当的优先级和时间限制而导致的调度延迟。它还可能是由于音频DSP尝试做比CPU速度所允许的实时处理更多的工作而引起的。

8. 安全性和隐私考虑

根据自查问卷:安全性和隐私§questions

  1. 该规范是否处理可识别个人身份的信息?

    可以使用Web Audio API进行听力测试,从而揭示一个人可听见的频率范围(这会随着年龄的增长而减少)。很难想象在没有用户意识和同意的情况下做到这一点,因为这需要用户的积极参与。

  2. 该规范是否处理高价值数据?

    不。Web Audio 不使用信用卡信息等。可能使用Web Audio来处理或分析语音数据,这可能会引发隐私问题,但访问用户的麦克风是基于getUserMedia()的许可。

  3. 该规范是否为原点引入了跨浏览会话持久化的新状态?

    不。AudioWorklet不会在浏览会话之间持久化。

  4. 该规范是否向网络公开了持久的跨源状态?

    是的,支持的音频采样率和输出设备通道数是公开的。参见AudioContext

  5. 该规范是否向原点公开了它目前无法访问的其他数据?

    是的。当提供关于可用AudioNode的各种信息时,Web Audio API可能会向使用AudioNode接口的任何页面公开客户端的特征信息(如音频硬件采样率)。此外,还可以通过AnalyserNodeScriptProcessorNode接口收集时间信息。这些信息可能随后被用来创建客户端的指纹。

    普林斯顿CITP的Web透明度与问责项目的研究表明,DynamicsCompressorNodeOscillatorNode可以用于从客户端收集熵来指纹设备。这是由于不同实现之间在DSP架构、重采样策略和舍入取舍中的小差异(通常是听不见的)。所使用的精确编译器标志以及CPU架构(ARM与x86)也会对此产生影响。

    然而,实际上,这只是允许推断出已经通过更简单的方式(如User Agent字符串)轻松获得的信息,如“这是在平台Y上运行的浏览器X”。然而,为减少可能来自任何节点输出的额外指纹识别问题,我们要求浏览器采取措施来减轻可能的指纹识别问题。

    Steven J Murdoch和Sebastian Zander描述了通过时钟偏差进行指纹识别的研究。这可能通过getOutputTimestamp来确定。Nakibly等人的研究也展示了基于偏移的指纹识别。有关时钟分辨率和漂移的更多信息,请参阅高分辨率时间§7隐私和安全部分。

    通过延迟进行指纹识别也是可能的;这可能通过baseLatencyoutputLatency来推断。缓解策略包括添加抖动(抖动)和量化,以便错误地报告确切的偏移。然而,请注意,大多数音频系统的目标是低延迟,以同步WebAudio生成的音频与其他音频或视频源或视觉提示(例如在游戏中或音频录制或音乐制作环境中)。过高的延迟会降低可用性,并可能成为可访问性问题。

    通过AudioContext的采样率进行指纹识别也是可能的。我们建议采取以下步骤来减少这种情况的发生:

    1. 允许44.1 kHz和48 kHz作为默认速率;系统将在它们之间选择最适用的一个。(显然,如果音频设备的本地采样率是44.1,那么将选择44.1 kHz等,但系统也可能选择最“兼容”的速率——例如,如果系统的本地采样率为96kHz,则可能会选择48kHz,而不是44.1kHz)。

    2. 系统应将本地速率不同的设备重新采样为这两种速率之一,尽管这可能会由于重新采样的音频而导致额外的电池消耗。(再次,系统将选择最兼容的速率——例如,如果本地系统的采样率为16kHz,则预计会选择48kHz)。

    3. 预计(尽管没有强制要求)浏览器会提供一个用户选择的选项来强制使用本地速率——例如,通过在设备上的浏览器中设置一个标志。此设置不会在API中暴露。

    4. 还期望行为是可以在AudioContext的构造函数中明确请求不同的速率(这已经在规范中;它通常会导致音频渲染以请求的采样率进行,然后将其向上或向下采样到设备输出),如果该速率是本地支持的,则可以直接通过渲染。这将使应用程序能够在不干预用户的情况下渲染到更高的速率(尽管无法从Web Audio中观察到音频输出未在输出时向下采样)——例如,如果MediaDevices的能力已读取(需要用户干预)并表明支持更高的速率。

    通过AudioContext的输出通道数量进行指纹识别也是可能的。我们建议将maxChannelCount设置为两个(立体声)。立体声是最常见的通道数量。

  6. 该规范是否启用了新的脚本执行/加载机制?

    不。它使用[HTML]规范中定义的脚本执行方法。

  7. 该规范是否允许原点访问用户的位置?

    不。

  8. 该规范是否允许原点访问用户设备上的传感器?

    不直接。目前,该文档中没有指定音频输入,但它将涉及获取客户端计算机的音频输入或麦克风。这将需要通过getUserMedia() API以适当的方式请求用户许可。

    此外,应注意媒体捕获与流规范中的安全性和隐私考虑。特别是,环境音频分析或播放独特音频可能会使用户位置识别精确到房间级别,甚至同时存在于一个房间内的不同用户或设备。访问音频输出和音频输入还可能使得在一个浏览器中本应隔离的上下文之间进行通信。

  9. 该规范是否允许原点访问用户本地计算环境的某些方面?

    不直接;所有请求的采样率都支持,如果需要,会进行上采样。可以使用媒体捕获与流探测支持的音频采样率MediaTrackSupportedConstraints。这需要明确的用户同意。这确实提供了一个小的指纹识别机会。然而,实际上,大多数消费者和准专业设备使用两种标准化采样率之一:44.1kHz(最初用于CD)和48kHz(最初用于DAT)。高度资源受限的设备可能支持语音质量的11kHz采样率,而高端设备通常支持88.2, 96或甚至192kHz的发烧友级别的采样率。

    要求所有实现上采样到一个单一的、普遍支持的速率(如48kHz)会增加CPU成本,但没有特别的好处,而要求高端设备使用较低的速率只会导致Web Audio被标记为不适合专业用途。

  10. 该规范是否允许原点访问其他设备?

    通常不允许访问其他网络设备(高端录音室的例外情况可能是Dante网络设备,尽管这些设备通常使用单独的专用网络)。但确实有必要访问用户的音频输出设备或设备,这些设备有时与计算机分开。

    对于语音或声音启动的设备,Web Audio API可能会用于控制其他设备。此外,如果声音控制设备对近超声波频率敏感,则这种控制可能是不可听见的。这种可能性也存在于HTML中,通过<audio>或<video>元素。在常见音频采样率下,设计上几乎没有足够的空间来处理大量超声信息:

    人类听力的极限通常被认为是20kHz。对于44.1kHz的采样率,Nyquist极限是22.05kHz。考虑到无法物理实现真正的砖墙滤波器,20kHz和22.05kHz之间的空间用于快速滚降滤波器,以强烈衰减所有高于Nyquist的频率。

    在48kHz的采样率下,仍然会在20kHz到24kHz频段中快速衰减(但在通过带中避免相位波纹错误会更容易)。

  11. 该规范是否允许原点对用户代理的本机UI进行某些控制?

    如果UI有音频组件,如语音助手或屏幕阅读器,Web Audio API可能会用于模拟本机UI的某些方面,使攻击看起来更像本地系统事件。这种可能性也存在于HTML中,通过<audio>元素。

  12. 该规范是否向网络公开临时标识符?

    不。

  13. 该规范是否区分第一方和第三方上下文中的行为?

    不。

  14. 该规范在用户代理的“隐身”模式下应如何工作?

    不应有不同的表现。

  15. 该规范是否将数据持久化到用户的本地设备?

    不。

  16. 该规范是否有“安全考虑”和“隐私考虑”部分?

    是的(您正在阅读它)。

  17. 该规范是否允许降低默认安全特性?

    不。

9. 需求和使用案例

请参见[webaudio-usecases]

10. 规范代码的通用定义

本节描述了在本规范中使用的JavaScript代码所采用的通用函数和类。

// 三维向量类。class Vec3 {  // 从3个坐标构造。  constructor(x, y, z) {    this.x = x;    this.y = y;    this.z = z;  }  // 与另一个向量的点积。  dot(v) {    return (this.x * v.x) + (this.y * v.y) + (this.z * v.z);  }  // 与另一个向量的叉积。  cross(v) {    return new Vec3((this.y * v.z) - (this.z * v.y),      (this.z * v.x) - (this.x * v.z),      (this.x * v.y) - (this.y * v.x));  }  // 与另一个向量的差值。  diff(v) {    return new Vec3(this.x - v.x, this.y - v.y, this.z - v.z);  }  // 获取此向量的大小。  get magnitude() {    return Math.sqrt(dot(this));  }  // 获取此向量的缩放副本。  scale(s) {    return new Vec3(this.x * s, this.y * s, this.z * s);  }  // 获取此向量的归一化副本。  normalize() {    const m = magnitude;    if (m == 0) {      return new Vec3(0, 0, 0);    }    return scale(1 / m);  }}

11. 变更日志

11.1. 自2021年5月6日建议版本以来的变更

11.2. 自2021年1月14日候选推荐快照以来的变更

11.3. 自2020年6月11日候选推荐以来的变更

11.4. 自2018年9月18日候选推荐以来的变更

11.6. 自2015年12月8日工作草案以来的变更

12. 致谢

本规范是W3C 音频工作组的集体成果。

工作组的成员和前成员以及规范的贡献者(在撰写本文时,按字母顺序排列)包括:
Adenot, Paul(Mozilla基金会) - 规范联合编辑; Akhgari, Ehsan(Mozilla基金会); Becker, Steven(微软公司); Berkovitz, Joe(应邀专家,隶属于Noteflight/Hal Leonard) - 自2013年9月至2017年12月担任工作组联合主席; Bossart, Pierre(英特尔公司); Borins, Myles(Google公司); Buffa, Michel(NSAU); Caceres, Marcos(应邀专家); Cardoso, Gabriel(INRIA); Carlson, Eric(苹果公司); Chen, Bin(百度公司); Choi, Hongchan(Google公司) - 规范联合编辑; Collichio, Lisa(高通公司); Geelnard, Marcus(Opera软件公司); Gehring, Todd(杜比实验室); Goode, Adam(Google公司); Gregan, Matthew(Mozilla基金会); Hikawa, Kazuo(AMEI); Hofmann, Bill(杜比实验室); Jägenstedt, Philip(Google公司); Jeong, Paul Changjin(HTML5融合技术论坛); Kalliokoski, Jussi(应邀专家); Lee, WonSuk(电子通信研究院); Kakishita, Masahiro(AMEI); Kawai, Ryoya(AMEI); Kostiainen, Anssi(英特尔公司); Lilley, Chris(W3C工作人员); Lowis, Chris(应邀专家) - 自2012年12月至2013年9月担任工作组联合主席,隶属于英国广播公司; MacDonald, Alistair(W3C应邀专家) - 自2011年3月至2012年7月担任工作组联合主席; Mandyam, Giridhar(高通创新中心); Michel, Thierry(W3C/ERCIM); Nair, Varun(Facebook); Needham, Chris(英国广播公司); Noble, Jer(苹果公司); O’Callahan, Robert(Mozilla基金会); Onumonu, Anthony(英国广播公司); Paradis, Matthew(英国广播公司) - 自2013年9月至今担任工作组联合主席; Pozdnyakov, Mikhail(英特尔公司); Raman, T.V.(Google公司); Rogers, Chris(Google公司); Schepers, Doug(W3C/MIT); Schmitz, Alexander(JS基金会); Shires, Glen(Google公司); Smith, Jerry(微软公司); Smith, Michael(W3C/庆应义塾大学); Thereaux, Olivier(英国广播公司); Toy, Raymond(Google公司) - 自2017年12月至今担任工作组联合主席; Toyoshima, Takashi(Google公司); Troncy, Raphael(电信研究所); Verdie, Jean-Charles(MStar半导体公司); Wei, James(英特尔公司); Weitnauer, Michael(IRT); Wilson, Chris(Google公司); Zergaoui, Mohamed(INNOVIMAX)

一致性

文档约定

一致性要求通过描述性断言和RFC 2119术语的组合来表达。关键字“MUST”(必须),“MUST NOT”(不得),“REQUIRED”(需要),“SHALL”(应),“SHALL NOT”(不应),“SHOULD”(应该),“SHOULD NOT”(不应该),“RECOMMENDED”(推荐),“MAY”(可以)和“OPTIONAL”(可选)在本文件的规范部分中应按照RFC 2119中的描述进行解释。然而,为了可读性,这些词在本规范中并未全部以大写字母出现。

本规范的所有文本均为规范性内容,除非明确标记为非规范性部分、示例和注释。[RFC2119]

本规范中的示例以“例如”开头,或使用class="example"与规范性文本区分开来,例如:

这是一个信息性示例。

信息性注释以“注意”一词开头,并使用class="note"与规范性文本区分开来,例如:

注意,这是一个信息性注释。

一致性算法

作为算法一部分的命令性要求(如“去除所有前导空格字符”或“返回false并中止这些步骤”)应根据引入算法时使用的关键字(“必须”、“应该”、“可以”等)来解释其含义。

作为算法或具体步骤表述的一致性要求可以以任何方式实现,只要最终结果是等效的。特别是,本规范中定义的算法旨在易于理解,而非注重性能。鼓励实现者进行优化。

一致性类别

一致性用户代理必须实现本规范中适用于用户代理的所有要求。

一致性服务器必须实现本规范中适用于服务器的所有要求。

索引

本规范定义的术语

Terms defined by reference

References

Normative References

[DOM]
Anne van Kesteren. DOM Standard. Living Standard. URL: https://dom.spec.whatwg.org/
[ECMASCRIPT]
ECMAScript Language Specification. URL: https://tc39.es/ecma262/
[FETCH]
Anne van Kesteren. Fetch Standard. Living Standard. URL: https://fetch.spec.whatwg.org/
[HR-TIME-3]
Yoav Weiss; et al. High Resolution Time. 24 March 2021. WD. URL: https://www.w3.org/TR/hr-time-3/
[HTML]
Anne van Kesteren; et al. HTML Standard. Living Standard. URL: https://html.spec.whatwg.org/multipage/
[INFRA]
Anne van Kesteren; Domenic Denicola. Infra Standard. Living Standard. URL: https://infra.spec.whatwg.org/
[MEDIACAPTURE-STREAMS]
Cullen Jennings; et al. Media Capture and Streams. 8 April 2021. CR. URL: https://www.w3.org/TR/mediacapture-streams/
[MIMESNIFF]
Gordon P. Hemsley. MIME Sniffing Standard. Living Standard. URL: https://mimesniff.spec.whatwg.org/
[RFC2119]
S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. March 1997. Best Current Practice. URL: https://datatracker.ietf.org/doc/html/rfc2119
[WebIDL]
Boris Zbarsky. Web IDL. 15 December 2016. ED. URL: https://heycam.github.io/webidl/
[WEBRTC]
Cullen Jennings; Henrik Boström; Jan-Ivar Bruaroey. WebRTC 1.0: Real-Time Communication Between Browsers. 26 January 2021. REC. URL: https://www.w3.org/TR/webrtc/

Informative References

[2DCONTEXT]
Rik Cabanier; et al. HTML Canvas 2D Context. 28 January 2021. REC. URL: https://www.w3.org/TR/2dcontext/
[MEDIASTREAM-RECORDING]
Miguel Casas-sanchez; James Barnett; Travis Leithead. MediaStream Recording. 16 February 2021. WD. URL: https://www.w3.org/TR/mediastream-recording/
[WEBAUDIO-USECASES]
Joe Berkovitz; Olivier Thereaux. Web Audio Processing: Use Cases and Requirements. 29 January 2013. NOTE. URL: https://www.w3.org/TR/webaudio-usecases/
[WEBGL]
Dean Jackson; Jeff Gilbert. WebGL 2.0 Specification. 12 August 2017. URL: https://www.khronos.org/registry/webgl/specs/latest/2.0/
[XHR]
Anne van Kesteren. XMLHttpRequest Standard. Living Standard. URL: https://xhr.spec.whatwg.org/

IDL Index

enum AudioContextState {
  "suspended",
  "running",
  "closed"
};

callback DecodeErrorCallback = undefined (DOMException error);

callback DecodeSuccessCallback = undefined (AudioBuffer decodedData);

[Exposed=Window]
interface BaseAudioContext : EventTarget {
  readonly attribute AudioDestinationNode destination;
  readonly attribute float sampleRate;
  readonly attribute double currentTime;
  readonly attribute AudioListener listener;
  readonly attribute AudioContextState state;
  [SameObject, SecureContext]
  readonly attribute AudioWorklet audioWorklet;
  attribute EventHandler onstatechange;

  AnalyserNode createAnalyser ();
  BiquadFilterNode createBiquadFilter ();
  AudioBuffer createBuffer (unsigned long numberOfChannels,
                            unsigned long length,
                            float sampleRate);
  AudioBufferSourceNode createBufferSource ();
  ChannelMergerNode createChannelMerger (optional unsigned long numberOfInputs = 6);
  ChannelSplitterNode createChannelSplitter (
    optional unsigned long numberOfOutputs = 6);
  ConstantSourceNode createConstantSource ();
  ConvolverNode createConvolver ();
  DelayNode createDelay (optional double maxDelayTime = 1.0);
  DynamicsCompressorNode createDynamicsCompressor ();
  GainNode createGain ();
  IIRFilterNode createIIRFilter (sequence<double> feedforward,
                                 sequence<double> feedback);
  OscillatorNode createOscillator ();
  PannerNode createPanner ();
  PeriodicWave createPeriodicWave (sequence<float> real,
                                   sequence<float> imag,
                                   optional PeriodicWaveConstraints constraints = {});
  ScriptProcessorNode createScriptProcessor(
    optional unsigned long bufferSize = 0,
    optional unsigned long numberOfInputChannels = 2,
    optional unsigned long numberOfOutputChannels = 2);
  StereoPannerNode createStereoPanner ();
  WaveShaperNode createWaveShaper ();

  Promise<AudioBuffer> decodeAudioData (
    ArrayBuffer audioData,
    optional DecodeSuccessCallback? successCallback,
    optional DecodeErrorCallback? errorCallback);
};

enum AudioContextLatencyCategory {
    "balanced",
    "interactive",
    "playback"
};

[Exposed=Window]
interface AudioContext : BaseAudioContext {
  constructor (optional AudioContextOptions contextOptions = {});
  readonly attribute double baseLatency;
  readonly attribute double outputLatency;
  AudioTimestamp getOutputTimestamp ();
  Promise<undefined> resume ();
  Promise<undefined> suspend ();
  Promise<undefined> close ();
  MediaElementAudioSourceNode createMediaElementSource (HTMLMediaElement mediaElement);
  MediaStreamAudioSourceNode createMediaStreamSource (MediaStream mediaStream);
  MediaStreamTrackAudioSourceNode createMediaStreamTrackSource (
    MediaStreamTrack mediaStreamTrack);
  MediaStreamAudioDestinationNode createMediaStreamDestination ();
};

dictionary AudioContextOptions {
  (AudioContextLatencyCategory or double) latencyHint = "interactive";
  float sampleRate;
};

dictionary AudioTimestamp {
  double contextTime;
  DOMHighResTimeStamp performanceTime;
};

[Exposed=Window]
interface OfflineAudioContext : BaseAudioContext {
  constructor(OfflineAudioContextOptions contextOptions);
  constructor(unsigned long numberOfChannels, unsigned long length, float sampleRate);
  Promise<AudioBuffer> startRendering();
  Promise<undefined> resume();
  Promise<undefined> suspend(double suspendTime);
  readonly attribute unsigned long length;
  attribute EventHandler oncomplete;
};

dictionary OfflineAudioContextOptions {
  unsigned long numberOfChannels = 1;
  required unsigned long length;
  required float sampleRate;
};

[Exposed=Window]
interface OfflineAudioCompletionEvent : Event {
  constructor (DOMString type, OfflineAudioCompletionEventInit eventInitDict);
  readonly attribute AudioBuffer renderedBuffer;
};

dictionary OfflineAudioCompletionEventInit : EventInit {
  required AudioBuffer renderedBuffer;
};

[Exposed=Window]
interface AudioBuffer {
  constructor (AudioBufferOptions options);
  readonly attribute float sampleRate;
  readonly attribute unsigned long length;
  readonly attribute double duration;
  readonly attribute unsigned long numberOfChannels;
  Float32Array getChannelData (unsigned long channel);
  undefined copyFromChannel (Float32Array destination,
                             unsigned long channelNumber,
                             optional unsigned long bufferOffset = 0);
  undefined copyToChannel (Float32Array source,
                           unsigned long channelNumber,
                           optional unsigned long bufferOffset = 0);
};

dictionary AudioBufferOptions {
  unsigned long numberOfChannels = 1;
  required unsigned long length;
  required float sampleRate;
};

[Exposed=Window]
interface AudioNode : EventTarget {
  AudioNode connect (AudioNode destinationNode,
                     optional unsigned long output = 0,
                     optional unsigned long input = 0);
  undefined connect (AudioParam destinationParam, optional unsigned long output = 0);
  undefined disconnect ();
  undefined disconnect (unsigned long output);
  undefined disconnect (AudioNode destinationNode);
  undefined disconnect (AudioNode destinationNode, unsigned long output);
  undefined disconnect (AudioNode destinationNode,
                        unsigned long output,
                        unsigned long input);
  undefined disconnect (AudioParam destinationParam);
  undefined disconnect (AudioParam destinationParam, unsigned long output);
  readonly attribute BaseAudioContext context;
  readonly attribute unsigned long numberOfInputs;
  readonly attribute unsigned long numberOfOutputs;
  attribute unsigned long channelCount;
  attribute ChannelCountMode channelCountMode;
  attribute ChannelInterpretation channelInterpretation;
};

enum ChannelCountMode {
  "max",
  "clamped-max",
  "explicit"
};

enum ChannelInterpretation {
  "speakers",
  "discrete"
};

dictionary AudioNodeOptions {
  unsigned long channelCount;
  ChannelCountMode channelCountMode;
  ChannelInterpretation channelInterpretation;
};

enum AutomationRate {
  "a-rate",
  "k-rate"
};

[Exposed=Window]
interface AudioParam {
  attribute float value;
  attribute AutomationRate automationRate;
  readonly attribute float defaultValue;
  readonly attribute float minValue;
  readonly attribute float maxValue;
  AudioParam setValueAtTime (float value, double startTime);
  AudioParam linearRampToValueAtTime (float value, double endTime);
  AudioParam exponentialRampToValueAtTime (float value, double endTime);
  AudioParam setTargetAtTime (float target, double startTime, float timeConstant);
  AudioParam setValueCurveAtTime (sequence<float> values,
                                  double startTime,
                                  double duration);
  AudioParam cancelScheduledValues (double cancelTime);
  AudioParam cancelAndHoldAtTime (double cancelTime);
};

[Exposed=Window]
interface AudioScheduledSourceNode : AudioNode {
  attribute EventHandler onended;
  undefined start(optional double when = 0);
  undefined stop(optional double when = 0);
};

[Exposed=Window]
interface AnalyserNode : AudioNode {
  constructor (BaseAudioContext context, optional AnalyserOptions options = {});
  undefined getFloatFrequencyData (Float32Array array);
  undefined getByteFrequencyData (Uint8Array array);
  undefined getFloatTimeDomainData (Float32Array array);
  undefined getByteTimeDomainData (Uint8Array array);
  attribute unsigned long fftSize;
  readonly attribute unsigned long frequencyBinCount;
  attribute double minDecibels;
  attribute double maxDecibels;
  attribute double smoothingTimeConstant;
};

dictionary AnalyserOptions : AudioNodeOptions {
  unsigned long fftSize = 2048;
  double maxDecibels = -30;
  double minDecibels = -100;
  double smoothingTimeConstant = 0.8;
};

[Exposed=Window]
interface AudioBufferSourceNode : AudioScheduledSourceNode {
  constructor (BaseAudioContext context,
               optional AudioBufferSourceOptions options = {});
  attribute AudioBuffer? buffer;
  readonly attribute AudioParam playbackRate;
  readonly attribute AudioParam detune;
  attribute boolean loop;
  attribute double loopStart;
  attribute double loopEnd;
  undefined start (optional double when = 0,
                   optional double offset,
                   optional double duration);
};

dictionary AudioBufferSourceOptions {
  AudioBuffer? buffer;
  float detune = 0;
  boolean loop = false;
  double loopEnd = 0;
  double loopStart = 0;
  float playbackRate = 1;
};

[Exposed=Window]
interface AudioDestinationNode : AudioNode {
  readonly attribute unsigned long maxChannelCount;
};

[Exposed=Window]
interface AudioListener {
  readonly attribute AudioParam positionX;
  readonly attribute AudioParam positionY;
  readonly attribute AudioParam positionZ;
  readonly attribute AudioParam forwardX;
  readonly attribute AudioParam forwardY;
  readonly attribute AudioParam forwardZ;
  readonly attribute AudioParam upX;
  readonly attribute AudioParam upY;
  readonly attribute AudioParam upZ;
  undefined setPosition (float x, float y, float z);
  undefined setOrientation (float x, float y, float z, float xUp, float yUp, float zUp);
};

[Exposed=Window]
interface AudioProcessingEvent : Event {
  constructor (DOMString type, AudioProcessingEventInit eventInitDict);
  readonly attribute double playbackTime;
  readonly attribute AudioBuffer inputBuffer;
  readonly attribute AudioBuffer outputBuffer;
};

dictionary AudioProcessingEventInit : EventInit {
  required double playbackTime;
  required AudioBuffer inputBuffer;
  required AudioBuffer outputBuffer;
};

enum BiquadFilterType {
  "lowpass",
  "highpass",
  "bandpass",
  "lowshelf",
  "highshelf",
  "peaking",
  "notch",
  "allpass"
};

[Exposed=Window]
interface BiquadFilterNode : AudioNode {
  constructor (BaseAudioContext context, optional BiquadFilterOptions options = {});
  attribute BiquadFilterType type;
  readonly attribute AudioParam frequency;
  readonly attribute AudioParam detune;
  readonly attribute AudioParam Q;
  readonly attribute AudioParam gain;
  undefined getFrequencyResponse (Float32Array frequencyHz,
                                  Float32Array magResponse,
                                  Float32Array phaseResponse);
};

dictionary BiquadFilterOptions : AudioNodeOptions {
  BiquadFilterType type = "lowpass";
  float Q = 1;
  float detune = 0;
  float frequency = 350;
  float gain = 0;
};

[Exposed=Window]
interface ChannelMergerNode : AudioNode {
  constructor (BaseAudioContext context, optional ChannelMergerOptions options = {});
};

dictionary ChannelMergerOptions : AudioNodeOptions {
  unsigned long numberOfInputs = 6;
};

[Exposed=Window]
interface ChannelSplitterNode : AudioNode {
  constructor (BaseAudioContext context, optional ChannelSplitterOptions options = {});
};

dictionary ChannelSplitterOptions : AudioNodeOptions {
  unsigned long numberOfOutputs = 6;
};

[Exposed=Window]
interface ConstantSourceNode : AudioScheduledSourceNode {
  constructor (BaseAudioContext context, optional ConstantSourceOptions options = {});
  readonly attribute AudioParam offset;
};

dictionary ConstantSourceOptions {
  float offset = 1;
};

[Exposed=Window]
interface ConvolverNode : AudioNode {
  constructor (BaseAudioContext context, optional ConvolverOptions options = {});
  attribute AudioBuffer? buffer;
  attribute boolean normalize;
};

dictionary ConvolverOptions : AudioNodeOptions {
  AudioBuffer? buffer;
  boolean disableNormalization = false;
};

[Exposed=Window]
interface DelayNode : AudioNode {
  constructor (BaseAudioContext context, optional DelayOptions options = {});
  readonly attribute AudioParam delayTime;
};

dictionary DelayOptions : AudioNodeOptions {
  double maxDelayTime = 1;
  double delayTime = 0;
};

[Exposed=Window]
interface DynamicsCompressorNode : AudioNode {
  constructor (BaseAudioContext context,
               optional DynamicsCompressorOptions options = {});
  readonly attribute AudioParam threshold;
  readonly attribute AudioParam knee;
  readonly attribute AudioParam ratio;
  readonly attribute float reduction;
  readonly attribute AudioParam attack;
  readonly attribute AudioParam release;
};

dictionary DynamicsCompressorOptions : AudioNodeOptions {
  float attack = 0.003;
  float knee = 30;
  float ratio = 12;
  float release = 0.25;
  float threshold = -24;
};

[Exposed=Window]
interface GainNode : AudioNode {
  constructor (BaseAudioContext context, optional GainOptions options = {});
  readonly attribute AudioParam gain;
};

dictionary GainOptions : AudioNodeOptions {
  float gain = 1.0;
};

[Exposed=Window]
interface IIRFilterNode : AudioNode {
  constructor (BaseAudioContext context, IIRFilterOptions options);
  undefined getFrequencyResponse (Float32Array frequencyHz,
                                  Float32Array magResponse,
                                  Float32Array phaseResponse);
};

dictionary IIRFilterOptions : AudioNodeOptions {
  required sequence<double> feedforward;
  required sequence<double> feedback;
};

[Exposed=Window]
interface MediaElementAudioSourceNode : AudioNode {
  constructor (AudioContext context, MediaElementAudioSourceOptions options);
  [SameObject] readonly attribute HTMLMediaElement mediaElement;
};

dictionary MediaElementAudioSourceOptions {
  required HTMLMediaElement mediaElement;
};

[Exposed=Window]
interface MediaStreamAudioDestinationNode : AudioNode {
  constructor (AudioContext context, optional AudioNodeOptions options = {});
  readonly attribute MediaStream stream;
};

[Exposed=Window]
interface MediaStreamAudioSourceNode : AudioNode {
  constructor (AudioContext context, MediaStreamAudioSourceOptions options);
  [SameObject] readonly attribute MediaStream mediaStream;
};

dictionary MediaStreamAudioSourceOptions {
  required MediaStream mediaStream;
};

[Exposed=Window]
interface MediaStreamTrackAudioSourceNode : AudioNode {
  constructor (AudioContext context, MediaStreamTrackAudioSourceOptions options);
};

dictionary MediaStreamTrackAudioSourceOptions {
  required MediaStreamTrack mediaStreamTrack;
};

enum OscillatorType {
  "sine",
  "square",
  "sawtooth",
  "triangle",
  "custom"
};

[Exposed=Window]
interface OscillatorNode : AudioScheduledSourceNode {
  constructor (BaseAudioContext context, optional OscillatorOptions options = {});
  attribute OscillatorType type;
  readonly attribute AudioParam frequency;
  readonly attribute AudioParam detune;
  undefined setPeriodicWave (PeriodicWave periodicWave);
};

dictionary OscillatorOptions : AudioNodeOptions {
  OscillatorType type = "sine";
  float frequency = 440;
  float detune = 0;
  PeriodicWave periodicWave;
};

enum PanningModelType {
    "equalpower",
    "HRTF"
};

enum DistanceModelType {
  "linear",
  "inverse",
  "exponential"
};

[Exposed=Window]
interface PannerNode : AudioNode {
  constructor (BaseAudioContext context, optional PannerOptions options = {});
  attribute PanningModelType panningModel;
  readonly attribute AudioParam positionX;
  readonly attribute AudioParam positionY;
  readonly attribute AudioParam positionZ;
  readonly attribute AudioParam orientationX;
  readonly attribute AudioParam orientationY;
  readonly attribute AudioParam orientationZ;
  attribute DistanceModelType distanceModel;
  attribute double refDistance;
  attribute double maxDistance;
  attribute double rolloffFactor;
  attribute double coneInnerAngle;
  attribute double coneOuterAngle;
  attribute double coneOuterGain;
  undefined setPosition (float x, float y, float z);
  undefined setOrientation (float x, float y, float z);
};

dictionary PannerOptions : AudioNodeOptions {
  PanningModelType panningModel = "equalpower";
  DistanceModelType distanceModel = "inverse";
  float positionX = 0;
  float positionY = 0;
  float positionZ = 0;
  float orientationX = 1;
  float orientationY = 0;
  float orientationZ = 0;
  double refDistance = 1;
  double maxDistance = 10000;
  double rolloffFactor = 1;
  double coneInnerAngle = 360;
  double coneOuterAngle = 360;
  double coneOuterGain = 0;
};

[Exposed=Window]
interface PeriodicWave {
  constructor (BaseAudioContext context, optional PeriodicWaveOptions options = {});
};

dictionary PeriodicWaveConstraints {
  boolean disableNormalization = false;
};

dictionary PeriodicWaveOptions : PeriodicWaveConstraints {
  sequence<float> real;
  sequence<float> imag;
};

[Exposed=Window]
interface ScriptProcessorNode : AudioNode {
  attribute EventHandler onaudioprocess;
  readonly attribute long bufferSize;
};

[Exposed=Window]
interface StereoPannerNode : AudioNode {
  constructor (BaseAudioContext context, optional StereoPannerOptions options = {});
  readonly attribute AudioParam pan;
};

dictionary StereoPannerOptions : AudioNodeOptions {
  float pan = 0;
};

enum OverSampleType {
  "none",
  "2x",
  "4x"
};

[Exposed=Window]
interface WaveShaperNode : AudioNode {
  constructor (BaseAudioContext context, optional WaveShaperOptions options = {});
  attribute Float32Array? curve;
  attribute OverSampleType oversample;
};

dictionary WaveShaperOptions : AudioNodeOptions {
  sequence<float> curve;
  OverSampleType oversample = "none";
};

[Exposed=Window, SecureContext]
interface AudioWorklet : Worklet {
};

callback AudioWorkletProcessorConstructor = AudioWorkletProcessor (object options);

[Global=(Worklet, AudioWorklet), Exposed=AudioWorklet]
interface AudioWorkletGlobalScope : WorkletGlobalScope {
  undefined registerProcessor (DOMString name,
                               AudioWorkletProcessorConstructor processorCtor);
  readonly attribute unsigned long long currentFrame;
  readonly attribute double currentTime;
  readonly attribute float sampleRate;
};

[Exposed=Window]
interface AudioParamMap {
  readonly maplike<DOMString, AudioParam>;
};

[Exposed=Window, SecureContext]
interface AudioWorkletNode : AudioNode {
  constructor (BaseAudioContext context, DOMString name,
               optional AudioWorkletNodeOptions options = {});
  readonly attribute AudioParamMap parameters;
  readonly attribute MessagePort port;
  attribute EventHandler onprocessorerror;
};

dictionary AudioWorkletNodeOptions : AudioNodeOptions {
  unsigned long numberOfInputs = 1;
  unsigned long numberOfOutputs = 1;
  sequence<unsigned long> outputChannelCount;
  record<DOMString, double> parameterData;
  object processorOptions;
};

[Exposed=AudioWorklet]
interface AudioWorkletProcessor {
  constructor ();
  readonly attribute MessagePort port;
};

callback AudioWorkletProcessCallback =
  boolean (FrozenArray<FrozenArray<Float32Array>> inputs,
           FrozenArray<FrozenArray<Float32Array>> outputs,
           object parameters);

dictionary AudioParamDescriptor {
  required DOMString name;
  float defaultValue = 0;
  float minValue = -3.4028235e38;
  float maxValue = 3.4028235e38;
  AutomationRate automationRate = "a-rate";
};