BaseAudioContext: createBuffer() 方法

Baseline 已广泛支持

此特性已得到良好支持,可在多种设备和浏览器版本上使用。自 2021 年 4 月起,所有浏览器均已支持此特性。

BaseAudioContext 接口的 createBuffer() 方法用于创建一个新的、空的 AudioBuffer 对象,然后可以填充数据,并通过 AudioBufferSourceNode 进行播放。

有关音频缓冲区的更多详细信息,请查看 AudioBuffer 参考页。

注意: createBuffer() 曾经能够接受压缩数据并返回解码后的样本,但此功能已从规范中移除,因为所有解码都在主线程上完成,导致 createBuffer() 阻塞了其他代码的执行。异步方法 decodeAudioData() 执行相同的功能——接受压缩音频(例如 MP3 文件),并直接返回一个 AudioBuffer,然后您可以通过 AudioBufferSourceNode 进行播放。对于播放 MP3 等简单用例,您应该使用 decodeAudioData()

要深入了解音频缓冲区的工作原理,包括参数的作用,请阅读我们基本概念指南中的 音频缓冲区:帧、样本和通道

语法

js
createBuffer(numOfChannels, length, sampleRate)

参数

numOfChannels

一个整数,表示此缓冲区应具有的通道数。默认值为 1,所有用户代理都必须支持至少 32 个通道。

length

一个整数,表示缓冲区中的采样帧数(每个采样帧的大小是样本大小乘以 numOfChannels)。要确定特定秒数音频所需的 length,请使用 numSeconds * sampleRate

sampleRate

线性音频数据的采样率,以每秒采样帧数为单位。所有浏览器都必须支持至少 8,000 Hz 到 96,000 Hz 范围内的采样率。

返回值

一个根据指定选项配置的 AudioBuffer

异常

NotSupportedError DOMException

如果一个或多个选项为负数或具有无效值(例如,numberOfChannels 高于支持的范围,或 sampleRate 超出标称范围),则会抛出此错误。

RangeError

如果可用内存不足以分配缓冲区,则会抛出此错误。

示例

首先,提供两个简单的示例,以帮助解释参数的使用方式。

js
const audioCtx = new AudioContext();
const buffer = audioCtx.createBuffer(2, 22050, 44100);

如果使用此调用,您将获得一个立体声缓冲区(两个通道),当在以 44100Hz 运行的 AudioContext 上播放时(非常常见,大多数普通声卡都以该速率运行),它将持续 0.5 秒:22050 帧 / 44100Hz = 0.5 秒。

js
const audioCtx = new AudioContext();
const buffer = audioCtx.createBuffer(1, 22050, 22050);

如果使用此调用,您将获得一个单声道缓冲区(一个通道),当在以 44100Hz 运行的 AudioContext 上播放时,它将被自动重采样到 44100Hz(因此产生 44100 帧),并持续 1.0 秒:44100 帧 / 44100Hz = 1 秒。

注意: 音频重采样非常类似于图像缩放:假设您有一个 16x16 的图像,但想让它填充 32x32 的区域:您会缩放(重采样)它。结果的质量会降低(可能模糊或锯齿状,取决于缩放算法),但它有效,并且缩放后的图像占用的空间更少。重采样的音频完全相同——您节省了空间,但实际上您将无法正确地重现高频内容(高音)。

现在,让我们来看一个更复杂的 createBuffer() 示例,其中我们创建一个三秒钟的缓冲区,用白噪声填充它,然后通过 AudioBufferSourceNode 进行播放。注释将清楚地解释正在发生的事情。您也可以实时运行代码,或查看源代码

js
const audioCtx = new AudioContext();

// Create an empty three-second stereo buffer at the sample rate of the AudioContext
const myArrayBuffer = audioCtx.createBuffer(
  2,
  audioCtx.sampleRate * 3,
  audioCtx.sampleRate,
);

// Fill the buffer with white noise;
// just random values between -1.0 and 1.0
for (let channel = 0; channel < myArrayBuffer.numberOfChannels; channel++) {
  // This gives us the actual ArrayBuffer that contains the data
  const nowBuffering = myArrayBuffer.getChannelData(channel);
  for (let i = 0; i < myArrayBuffer.length; i++) {
    // Math.random() is in [0; 1.0]
    // audio needs to be in [-1.0; 1.0]
    nowBuffering[i] = Math.random() * 2 - 1;
  }
}

// Get an AudioBufferSourceNode.
// This is the AudioNode to use when we want to play an AudioBuffer
const source = audioCtx.createBufferSource();
// set the buffer in the AudioBufferSourceNode
source.buffer = myArrayBuffer;
// connect the AudioBufferSourceNode to the
// destination so we can hear the sound
source.connect(audioCtx.destination);
// start the source playing
source.start();

规范

规范
Web Audio API
# dom-baseaudiocontext-createbuffer

浏览器兼容性

另见