他們多次嘗試推出強大的 audio API 來解決我上面提到的這些音頻限制。推出的這些 API 中值得注意的就是火狐瀏覽器設計的 Audio Data API 原型實現。Mozilla 試圖用
相比于 Audio Data API, Web Audio API 使用了全新的模式,完全獨立于 標簽的實現,盡管有些點與其它 web API 有相交(詳見第7章)。它在 web 應用中提供了更高級的 Javascript API 用于處理和混合音頻。此 API 的目的是實現現代游戲所需的能力,包括混音、處理、濾鏡特效等這些只能在現代桌面應用程序產品所能提供的能力。最終需要的是一個多功能的 API 可以被用于處理多樣的音頻相關的任務,從游戲到可交互應用,到高級音頻合成應用與可視化。
音效在游戲外的應用也同樣重要。它們在命令行工具內交互之始就被應用于 UI 的交互上,當輸出出錯時就發出“嗶”的一聲。同樣被應用現代交互 UI 上,一般用于提醒功能,鈴聲,也應用于音視頻通訊比如 Skype。像 Google Now 和 Siri 這樣的助手軟件同樣提供了豐富的音效反饋。當我們深入發掘這個世界,通用計算設備,語音和手勢交互等可脫離屏幕的交互方式更加的依賴于音頻的反饋。最后,對于視障視弱的計算機用戶來說,音頻提示,語音合成與識別提供了最主要的用戶體驗原則
Web Audio API 是建立在 audio context 音頻上下文的概念之上的。音頻上下文是描述音頻所有節點的,這些節點定義了音頻流是如何從起點(一般是音頻文件)到目的地(一般就是你的揚聲器)。當音頻通過每個節點時,音頻的屬性可被修改和查看。最簡單的音頻上下文就是起始節點到結束節點的直連如圖 1-1
Web Audio API 現已被 Chrome 和 Safari 瀏覽器實現(包含 IOS 6 手機版 Safari )并且通過 JavaScript 開放給了網頁開發者。在這些瀏覽器上,音頻上下文創建時需要加上 webkit 前綴,你不能直接使用 new AudioContext 而應該使用 new webkitAudioContext 創建。然而在未來在 API 足夠穩定且多數瀏覽器供應商都實現了后前綴可去掉。Mozilla 已宣布在火狐瀏覽器上實現 Web Audio API,Opera 也開始參與進工作組。記得這一點即可,下面是通用的兼容寫法:
var contextClass = (window.AudioContext || window.webkitAudioContext || window.mozAudioContext || window.oAudioContext || window.msAudioContext);
if (contextClass) {
// Web Audio API is available.
var context = new contextClass();
} else {
// Web Audio API is not available. Ask the user to use a supported browser.
}
一個音頻上下文即可支持多個音頻的輸入與復雜的音頻圖譜,一般來講,一個應用使用一個音頻上下文即可。音頻上下文的實例包含了眾多的方法用于創建音頻節點以及操作全局音頻屬性。幸運的是這些方法不需要加前綴,且相對穩定。 API 仍在變更,所以還是要小心會有大的變化。
使用 connect() 方法可以將任意音頻節點輸出連接至任意其它的音頻節點。在以下例子,我們連接了音源節點的輸出到 gain 節點,并將其輸出連接到了結束節點:
// Create the source.
var source = context.createBufferSource();
// Create the gain node.
var gain = context.createGain();
// Connect source to filter, filter to destination.
source.connect(gain);
gain.connect(context.destination);
瀏覽器對不同音頻格式的支持差別很大。一般來說,如果是在瀏覽器上, Web Audio API 的實現與 標簽的實現是一樣的。一般來說 WAV(一種簡單的無損壓縮格式)格式所有瀏覽器都支持。 MP3 仍然有專利阻礙,因為在一些純開源的瀏覽器上不支持(比如,Firefox, Chromium)。不幸的是,不太流行但無專利阻礙的 OGG 格式在我寫這篇文章時Safari 還是不支持。更多格式信息可查看這里 http://mzl.la/13kGelS
Firefox Chrommium 現在是支持 mp3 格式的。
聲音的加載與播放
Web Audio API 將緩沖與音源(source)節點區別的很清晰。這樣的架構有利于解構音頻資源與播放狀態。以唱片機為例,緩沖區就像唱片,而源就像播放指針,而在 Web Audio API 的世界中你可以同時在多個播放指針處播放同一個唱片。由于許多應用程序涉及同一緩沖區的多個版本同時播放,因此這種模式是必不可少的。舉個例子,
如果您希望快速連續地發出多個彈跳球的聲音,則只需要加載一次彈跳緩沖并安排多個音源(source)。
在 Web Audio API 加載一個音頻樣本,我們可以使用一個 XMLHttpRequest 加載并對加載的結果用context.decodeAudioData進行音頻解碼處理。這些都是異步的不會阻塞主 UI 進程:
如你所見以上的代碼,Web Audio API 需要一些初始化的程序設置。在真正的游戲中,可以考慮圍繞 Web Audio API 執行 JavaScript 抽象。例如后續的 BufferClass 類。它將所有東西都整合進一個簡單的加載器上,加載器提供了設置路徑,返回音頻緩沖的功能。以下是如何使用 BufferLoader 類的代碼:
window.onload = init;
var context;
var bufferLoader;
function init() {
context = new webkitAudioContext();
bufferLoader = new BufferLoader( context,
[
'../sounds/hyper-reality/br-jam-loop.wav',
'../sounds/hyper-reality/laughter.wav',
],
finishedLoading
);
bufferLoader.load();
}
function finishedLoading(bufferList) {
// 創建兩具音源并把它們整合到一起播放
var source1 = context.createBufferSource();
var source2 = context.createBufferSource();
source1.buffer = bufferList[0];
source2.buffer = bufferList[1];
source1.connect(context.destination);
source2.connect(context.destination);
source1.start(0);
source2.start(0);
}