他們多次嘗試推出強大的 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);
}