Java 音訊處理技術簡介
Java Sound包介紹
Java sound API 比較簡單陳舊,受作業系統影響較大,無法滿足一些專業場景。比如在 windows 下8路輸入的音效卡會被識別為4個2路輸入的裝置,無法協同工作。但是它提供了很多基礎 API,還是很有必要了解一下的。
包:
- sampled包 聲音取樣處理
- midi 包 midi 音樂處理
類:
-
AudioSystem 用來操作各種系統資源,如外接的話筒,輸入等;可以從這些裝置直接得到io 流;還可以在各種音訊格式之間轉換。——要注意資料格式和檔案格式的區別!
-
AudioFormat 用來表示資料格式,包括編碼技術(通常是脈碼調製即 PCM),通道數,取樣率,每個樣(敏感詞)本位數,幀速率,幀大小,位元組順序
-
AudioFileFormat 用來表示檔案格式,包括檔案型別,檔案長度(位元組),檔案中的音訊資料長度(幀),
-
Mixer 用來表示各種裝置,作用是接收 n 錄輸入,處理後送到 n 錄輸出。
-
Line 是 Port, Mixer, DataLine 的公共父介面,他們可以對流經的訊號進行控制,如gain(以分貝影響訊號的體積),pan(影響聲音的左右定位,混響(這會增加聲音的混響)模擬不同型別的房間聲學)和取樣率(影響播放速率以及聲音間距)
-
Port 簡單表示來自或到聲音裝置的線
-
DataLine 提供與媒體相關的功能,如音訊格式,媒體位置,緩衝區大小,電平,啟停,暫停和回覆,重新整理,drain,活動狀態
-
SourceDataLine 用來把資料寫入 Mixer,write()的引數表示寫入緩衝區的資料,建議每次寫入的資料大小比緩衝區大。期間如果呼叫 stop()會立刻停止播放,剩餘資料殘留在緩衝區,下次再呼叫 start()會繼續播放。
-
TargetDataLine 用來從Mixer 接收音訊資料,open()表示準備好,start()開始捕獲資料到緩衝區,read()讀取緩衝區的資料,每次讀取的資料應該比緩衝區小,比如例子中是緩衝區大小的1/5。
綜上,兩種 line 都一樣,open/close 是控制線的程式資源;start/stop 是控制裝置;write/read/flush/drain 是控制緩衝區。其中前四個方法會產生事件。
ASIO介紹
ASIO(Audio stream input output)是一種音訊流輸入輸出API,由 Steinberg 公司開發,可實現低延遲、高同步、高吞吐率。當今主流音效卡都會支援,在 windows 和 mac os 下都有驅動。參考資料中有Steinberg 公司的 ASIO SDK 下載連結,是 C++語音實現的。然而要在 Java 中呼叫 ASIO並不需要下載此 SDK,而是可以使用開源的 JAsioHost 庫。見下一節
另外,ASIO 限制每次只能選定一個裝置輸入輸出音訊,無法支援需要多個裝置同時工作的場景。這時可以使用一款通用 ASIO 封裝庫 Asio4all。它底層使用 WDM API(Windows Driver Module,一種和 ASIO 類似的音訊輸入輸出 API,但只有 windows 系統支援)訪問音訊裝置,對外暴露 ASIO介面。使用者可以通過它同時訪問多臺音訊裝置。
JAsioHost 庫
JAsioHost 使用 JNI 技術封裝 asio API,暴露出一套 Java API。開發者可以直接針對此 API 程式設計實現音訊輸入輸出。詳細可參考專案介紹。
我在使用JAsioHost時發現給AsioDriver設定取樣率並不生效,不確定是否bug。
綜上,如果需要用 java 同時操作多臺音訊裝置,需要在本機安裝asio4all 驅動,然後基於 JAsioHost 庫編碼操作音訊裝置。
順帶一提, JAsioHost API 和 Java Sound API 風格不同,前者主動推送資料到呼叫者,後者被動接受呼叫者呼叫拉取資料。因此並不能很簡單地在兩種實現方案之間切換,需要開發者做一些相容處理。
參考資料
Java Sound官方文件: http://docs.oracle.com/javase/tutorial/sound/TOC.html
Steinberg ASIO 驅動 官方下載: https://www.steinberg.net/en/company/developers.html
asio4all官網: http://www.asio4all.com/
JasioHost 專案主頁: https://github.com/mhroth/jasiohost
作者:搞技術的薛彬
連結:https://www.jianshu.com/p/3d27058dc377
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯絡作者獲得授權並註明出處。