深度剖析 Android音頻系統解析與改進

導讀:Android是用了一個Google自己開發的中間層API來讓APP和聲音驅動(ALSA或者HAL封閉驅動)通信的。在早期,它是個ALSA的插件;現在則命名爲AudioFlinger。但是安卓音質根本問題在哪?

Android音頻系統的改進設想和展望:

擁有Beats音效的HTC One X當然無需擔心其音質,目前Tegra 3最高端的機器就是已經升級至HTC Sense 4.0華麗界面和Android 4.0.3 ICS系統的四核旗艦HTC One X!需要購港行HTC One X的朋友可以去52htc.net看看,他們能提供全新不拆封原包裝保證正品,並支持免費ROOT升級刷機服務。

\

在這裏先說明,本人並沒有仔細地去看Android和PulseAudio的音頻具體源代碼和實現,歡迎指正。

從硬件用料上看,Android能不能做好音質?答案當然是可以的!MOTO的手機音質就做得不錯。另外,W700也還可以(輸出電平小了點,導致指標不好看)。

從軟件和系統上看?答案是NO。高延遲,劣質SRC,這些玩意只能毀了音樂和音頻應用。

簡單地說,Android是用了一個Google自己開發的中間層API來讓APP和聲音驅動(ALSA或者HAL封閉驅動)通信的。在早期,它是個ALSA的插件;現在則命名爲AudioFlinger。

無論是什麼方式,實際上APP是以訪問中間層API的方式讓自己發出聲音的,而這個API,卻成了Android整個音頻系統的噩夢。

噩夢一:SRC

實際上個人覺得最不可思議的是,AudioFlinger爲什麼要做強制SRC?要知道,ALSA是支持硬件SRC的(早期ALSA標準API本身卻不支持,這個設計也是超級傻,具體表現在如果你在Linux下使用某個使用早期ALSA API的音樂播放器,播放和硬件採樣率不匹配的音頻檔案,就會報錯,同時期的PulseAudio API反而支持……),可實際上Android4.0後ALSA已經是最新的版本了。現在的Linux通過ALSA驅動做硬件SRC也不會是太大問題,當然音質比較一般(相當於高通,全志等芯片組在44.1KHz音源下的音質)就是了。

可是,AudioFlinger爲什麼自身要做一個強制重採樣行爲呢?個人預計,實際上AudioFlinger只是Android早期音頻系統API接口的繼承和擴展,它遺留了太多由於早期ALSA的不足而提供的“臨時解決方案”,Android1.X的時候,ALSA相對現在也是非常的糟糕,google不得已寫了個SSRC插件來解決當時ALSA不支持非匹配採樣率無法發聲的問題。至於Google爲什麼現在不解決,答案很明顯:原來的代碼都是臨時的無證程序員寫的,Android有個叫中子播放器的軟件就能提供相對高質量的SSRC ,google沒道理寫不出來。但是那樣對於現在版本的ALSA能力來說簡直是多餘的行爲,還會導致聲音延時和性能損失。

噩夢二:系統資源佔用和延遲

這兩個爲什麼放到一起說?因爲,高延遲意味着系統IO動作多。Google“聰明”地做了一套soundfx系統,給所有音頻做預處理,比如頻響均衡器(EQ),重採樣後對高頻進行衰減等,這些接口爲開發第三方音頻應用提供了方便,卻導致Android的音頻性能出現了極大地負載和延遲,特別是遊戲應用。Android的音頻接口有兩個,一個是用來播放音樂,這個接口提供了較大的緩衝,延遲也比較大;另一個則是用來做實時事件音效的處理(比如樂器聲,效果音等等),將聲音讀入高速緩存(只能緩存10秒左右),然後進行處理。Google標榜這個爲“低延遲”,可實際上因爲API對音頻做了大量的預處理,導致就算開發人員使用高速緩存接口,出了觸屏感應處理外,音頻也會有180ms以上的延遲,所以一些所謂的樂器演奏軟件或者音樂遊戲,基本就是Android劣勢的徹底體現,這樣的問題也導致Android無法進行音頻處理應用。

PulseAudio簡介

Collabora是一個開源系統解決方案的開發商,對於個人用戶是免費開源的(對廠商似乎要收費,所以,Android開發廠商對此沒興趣掏錢)。PulseAudio是和AudioFlinger一樣的音頻系統API,PulseAudio並不完美,但是並不會有AudioFlinger的那兩個致命問題。而且,HP webOS 、N900/Maemo5、N9/MeeGo都採用了PulseAudio作爲系統音頻API。

PulseAudio能解決的問題:

1、不會強制重採樣,而是交由驅動來解決,避免了AudioFlinger極度劣質的SSRC。

2、不做預處理,極大減少音頻延遲和系統開銷(高速緩存處理延遲可以降低至20ms,雖然並不算很好,但是對於移動裝置和平板來說已經足夠)。

這看起來很美,不是麼?可是爲什麼沒有廠商積極面對呢?實際上,更換Android的音頻系統,遠遠不像換衣服那麼簡單!

授權移植費用

雖然PulseAudio是開源軟件,但開源不等於免費,PulseAudio很可能是針對企業收費的。這裏會導致一個兩頭難的問題:大廠商不掏錢就用,可能會吃官司;而用了,會導致一系列連鎖反應,這個會在後面介紹。小廠商可以完全不鳥什麼商業授權,但是本身的孱弱的開發能力不足以對Android做二次開發。

原有的應用音頻相關功能全部報廢

更換音頻系統是個大工程,因爲現在Android所有的應用都是基於AudioFlinger的,如果更換爲PulseAudio,則現有的應用完全無法在新系統上使用,原有的應用匹配新的音頻API可以說是一個浩瀚的工程,而普通用戶如果強制在自己的Android裝置上安裝PulseAudio,則可能要面對的是連音樂沒法聽,電話都沒法打的風險。這樣巨大的成本和風險,是廠商和用戶都無法承受的。當然,PulseAudio和AudioFlinger可以共存,可共存的代價就是更耗資源更耗電,和更可怕的系統衝突(想象一下兩個不同的API同時請求驅動所導致的風險)。

開發成本,有限的應用資源

如果真有一個有心的廠家思路廣歡樂多,在自己的產品上使用了PulseAudio,那麼廠商最少必須重寫一套通信應用和音樂播放器。而廠商也會很遺憾地告訴用戶,你們在切水果彈小鳥的時候,都不會有聲音。想要正常發聲,必須得移植大量現有的Linux應用軟件,而這些應用軟件不說本身代碼或者用戶體驗怎麼樣,針對臺式機和移動裝置畢竟是完全的兩碼事。

但是,這並不是說PulseAudio取代AudioFlinger完全沒戲,廠商可以再寫一個“AudioFlinger”語法的PulseAudio API兼容現有的應用,雖然會花點時間也有不小風險,這並不算很難。可是,就是沒有廠家考慮過。畢竟這方面用戶很難以這個爲理由把廠家弄上315晚會,廠商也不會有興趣。所以高通的音頻系統再糟糕,如果你打算和高通溝通的話,他也只會認爲你需要廣告費了而已。

PulseAudio不能解決的問題:

高質量音頻應用,就必須避免SRC,codec的硬件能力還不足以提供優質的SRC,所以,根據音源改變採樣率纔是最佳的選擇,這點PulseAudio是做不到的。但是ALSA可以,實際上ALSA是可以和Win7一樣實時更改採樣率的,不過Android和PulseAudio並沒有提供這個功能的API,如果真爲了音質,這個是應該做到的。

綜上所述,Android並不是不能做好音頻,而是由於google一直在使用錯誤的方法處理音頻,而這個錯誤已經延續到了現在幾乎難以挽回。可是現在不改正,這個巨大的成本還會像滾雪球一樣倍增,因爲google和開發人員的一時之便,導致現在的Android平板音質連幾年前的MP3MP4都不如,這是時代的倒退。

Android音頻系統的改進設想和展望(2)

不過由於寫得太匆忙,沒有認真去分析Linux和Android相關的資料,問題也是一大堆。其中,最嚴重的問題就是我實在太高估Google了,認爲現在Android的ALSA驅動是沒問題的。可那並不能完全解釋AudioFlinger爲什麼還要繼承原來ALSA的問題。做大量的預處理和SRC,這些事情完全可以通過ALSA驅動層來調用硬件完成,而不是寫一堆垃圾代碼去實現劣質SRC和延遲高達350ms的“高速緩存”(APP的開發便利性不是理由,因爲Google完全可以把AudioFlinger寫得更簡單)。

所以,答案就是:Google並沒有解決ALSA的問題。Android和ALSA和Linux的ALSA是兩回事。

我曾提到ALSA原來並不完善,其中之一就是早期的ALSA API連SRC都無法實現,要播放非匹配採樣率的音頻只能通過切換採樣率和通過PulseAudio等中間層API來解決。而Android內置的ALSA是早期的ALSA版本精簡而來,說好聽點就是Google修改的版本,實際上就是Google自己移植並去掉ALSA大量API甚至驅動層功能的閹割版本。閹割的目的是爲了減少或者說去掉GPL授權的影響,加重Google在Android源代碼控制上的話語權,也能說服不願意將自己驅動或者修改代碼開源的廠商加入到Android的開發上(雖然Android也支持HAL層的私有驅動,但是……現在幾乎所有的音頻Codec驅動是基於ALSA的)。雖然Google樂於聽到“Android和ALSA和Linux的ALSA是兩回事”的說法,並將其內部命名爲“TinyALSA”(精簡版ALSA)。一般來說,在維持功能的基礎上精簡代碼是好事,可Google對於ALSA的精簡,完全可以做爲失敗案例看待。如果說AudioFlinger是Android音頻系統的噩夢,那麼,TinyALSA則是Android音頻系統的災難。

  ALSA同時掌管着Android/Linux的音頻硬件驅動和底層API,因此,ALSA對於codec的性能和功能則起着決定性的作用。Google在大量刪除ALSA代碼的同時,並沒有將失去的功能補回來。PulseAudio相對於AudioFlinger的優勢就是加強底層驅動的作用,但是Android的TinyALSA則是啥功能都缺:

1、不具備重採樣功能(這個待考慮,畢竟硬件支持的)

2、不具備緩存功能

3、無法切換採樣率,採樣率只能在編譯驅動時固定

4、不具備影音相關的重要功能(雙聲道/多聲道切換,AC3 Fliter,AC3解碼等等,仿真輸出只能靠AudioFlinger轉換簡單實現,高級實現則需要數字輸出到獨立的硬件譯碼器。)

消費者們應該慶幸GoogleTV的艱難前進,否則他們能看到的高清影像也是僅限於視訊的層面上。

所以,底層驅動重寫纔是Android音頻系統改造首要的任務。底層的改造可以說很簡單,也可以說很困難,ALSA就有一個叫SALSA(Small ALSA Library)的精簡版本,但是驅動層和API的重要功能都還在,要實現低延遲,硬件採樣切換和硬件SRC,就必須在驅動中實現。所以,PulseAudio想在Android上使用,首先是要在系統上安裝功能和性能都相對完整的ALSA,或者使用更好的底層驅動(如OSS或者非開源的HAL廠商驅動)。

SALSA要在Android上使用並不難,難的不是技術問題,而是接近於政治的授權問題。Google並不樂意在Android裏使用GPL授權的代碼,去GPL化是Android最大的政治任務,而PulseAudio、SALSA等代碼均是以GPL或者LGPL授權的。實際上,這體現了Google和廠商們的極大矛盾:一方面他們依賴於整個GPL開源體系才能得到Android今天的成就,另一方面他們又想將這個成果佔爲己有。而實際上除了底層芯片驅動開發商,Google等企業相對於開源小區對Android,實在是九牛一毛,自己的私有代碼效果還適得其反。Google自己折騰出來的AudioFlinger和TinyAlsa就是很好的例子。但就算如此,享受着開源帶來的成就,Google也無法容忍GPL代碼進入Android源裏面,一個是因爲法律問題,另一個這是爲了保護廠商的利益。就算PulseAudio和SAlsa組合能達到較好的效果,也能保證兼容性的前提下,也無法進入正規的Android體系。

現在,有廠商號稱解決了Android的SRC問題還申請了專利,個人估計也只是將AudioFlinger重寫,讓其忽略SRC處理,並不能說沒有了AudioFlinger的SRC,音質就能有所改善。而且,作爲廠商自主的改進,謀求利益的目標也不會讓其將修改提交至Android主代碼庫或者分享。廠商修改了代碼,卻在自己的產品上用了音質不佳的處理器,那根本問題還是無法解決。而某個堆料的Android隨身聽號稱自帶播放器直接使用底層驅動。但是,TinyALSA底層驅動功能有限,而應用層依然是AudioFlinger在掌控系統,問題也無法解決。如果不能正常播放高清音頻,那麼,採用的DAC芯片就算有32bi192KHz的譯碼能力,它還是會SRC到44KHz來播放,這是極大的浪費。

Android要改善音質,到底該怎麼辦?

對於開源小區和智能裝置開發商來說,可以藉助自己的開發能力或者第三方的API和驅動,繞過Android的API,從而改善延遲和SRC問題,但是不要指望能被Google接受。

對於硬件廠商,他們首先要保證芯片的數字音頻不能有差錯,codec或者DAC要運用合理,電路設計也不能出現低級失誤。

而對於Google來說,必須把現在的垃圾代碼全部砍掉,重來。這是最徹底,也是最好的辦法。

但是,現在的Google完全不具備這樣的開發能力。高質量音頻應用,離Android還很遙遠,離Google更遙遠。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章