BaseAudioContext:createBuffer() 方法
Baseline
Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since 2021年4月.
BaseAudioContext 接口的 createBuffer() 方法用于新建一个空的 AudioBuffer 对象,随后可以填充数据,并通过 AudioBufferSourceNode 播放。
更多关于音频片段的细节,请查阅 AudioBuffer 参考页面。
备注:createBuffer() 过去可以接收压缩音频数据,并返回解码后的采样数据,但这项功能已经从规范中删除,因为所有的解码工作都在主线程中完成,导致 createBuffer() 阻塞了其他代码的执行。异步方法 decodeAudioData() 能够完成相同的工作——传入 MP3 文件之类的压缩音频数据,并直接返回一个可以通过 AudioBufferSourceNode 播放的 AudioBuffer。对于诸如播放 MP3 这类简单使用场景,decodeAudioData() 就是你应当使用的。
如果想深入了解音频片段是如何工作的,以及这些参数的作用,请阅读基本概念指南中的音频片段:帧、样本和声道。
语法
createBuffer(numOfChannels, length, sampleRate)
参数
numOfChannels-
一个整数,表示音频片段应包含的声道数。默认值为 1,所有浏览器必须支持至少 32 个声道。
length-
一个整数,表示音频片段的大小,单位是采样帧(每个采样帧的大小等于单个采样的字节数乘以
numOfChannels)。要确定特定秒数音频所需的length,使用numSeconds * sampleRate。 sampleRate-
线性音频数据的采样率,单位是每秒采样帧数。所有浏览器必须支持至少 8000 Hz 到 96000 Hz 范围内的采样率。
返回值
一个基于指定参数配置的 AudioBuffer。
异常
NotSupportedErrorDOMException-
如果一个或多个参数为负数或具有无效值(例如
numberOfChannels高于支持的值,或sampleRate超出正常范围),则抛出此异常。 RangeError-
如果没有足够的内存来分配音频片段,则抛出此异常。
示例
首先,我们将从几个浅显易懂的示例入手,来解释如何使用这些参数:
const audioCtx = new AudioContext();
const buffer = audioCtx.createBuffer(2, 22050, 44100);
如果你这样调用,你将会得到一个立体声(双声道)的音频片段,当它在一个 44100 Hz(非常常见,大多数普通声卡都运行在该频率下)的音频上下文(AudioContext)中播放的时候,会持续 0.5 秒:22050 帧 / 44100 Hz = 0.5 秒。
const audioCtx = new AudioContext();
const buffer = audioCtx.createBuffer(1, 22050, 22050);
如果你这样调用,你将会得到一个单声道的音频片段,当它在一个 44100 Hz 的音频上下文(AudioContext)中播放的时候,会被自动重采样到 44100 Hz(因此也会产生 44100 个采样帧),并持续 1 秒:44100 帧 / 44100 Hz = 1 秒。
备注:音频重采样与图片的缩放非常类似:假设你有一张 16 x 16 的图片,但希望它填充一个 32 x 32 的区域,你就需要对它进行缩放(重采样)。缩放后的结果质量会有所下降(可能会变得模糊或出现锯齿,取决于缩放算法),但它仍然可用,而且缩放后的图片占用的空间更小。重采样的音频原理相同——你能节省一些空间,但是也会无法准确再现高频内容(高音区)。
现在来看一个更加复杂的 createBuffer() 示例,我们将创建一个 3 秒的音频片段,用白噪声填充它,之后通过一个音频片段源节点(AudioBufferSourceNode)播放。代码中的注释应该能充分解释发生了什么。你可以实时运行代码,或者查看源代码。
const audioCtx = new AudioContext();
// 创建一个 3 秒的立体声空音频片段,采样率与 AudioContext 相同
const myArrayBuffer = audioCtx.createBuffer(
2,
audioCtx.sampleRate * 3,
audioCtx.sampleRate,
);
// 使用白噪声填充音频片段
// 即 -1.0 到 1.0 之间的随机数
for (let channel = 0; channel < myArrayBuffer.numberOfChannels; channel++) {
// 这会给我们提供包含数据的实际 ArrayBuffer
const nowBuffering = myArrayBuffer.getChannelData(channel);
for (let i = 0; i < myArrayBuffer.length; i++) {
// Math.random() 的范围是 [0; 1.0]
// 音频需要在 [-1.0; 1.0] 之间
nowBuffering[i] = Math.random() * 2 - 1;
}
}
// 获取一个 AudioBufferSourceNode
// 这是当我们想要播放 AudioBuffer 时所使用的 AudioNode
const source = audioCtx.createBufferSource();
// 设置 AudioBufferSourceNode 的 buffer
source.buffer = myArrayBuffer;
// 将 AudioBufferSourceNode 连接到 destination,这样我们就能听到声音了
source.connect(audioCtx.destination);
// 开始播放音频源
source.start();
规范
| Specification |
|---|
| Web Audio API> # dom-baseaudiocontext-createbuffer> |