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

瀏覽器相容性

另見