Android 4.1,英文代號簡稱JB。在國人眼裡,JB這個詞還和動物有點關系。Google如此頻繁修改Android,終於推出了一個可以被大家整天JB JB掛在嘴上的版本。以後我的文章也可以一面用JB表示版本號,一面用JB表示毛主席常說的”戰略上的鄙視了“。請大家根據上下文揣摩我寫下JB一詞的心情。
今天將稍深入得介紹一下JB 4.1在Audio系統做的翻天覆地的改動。這裡先啰嗦幾句:就像80後經常抱怨自己晚生了幾年一樣,馬上就會有很多碼農抱怨接觸Android太晚了。為何?JB Audio系統的難度相對4.0, 2.3, 2.2已經非常非常大了。99%的情況下,在你沒有看到這個NB(這不是髒話,4.1 Audio系統中就有一個類叫NBAIO,籃球控不要搞錯成NBA了,原意是Non-block Audio I/O。看到了吧,
非阻塞I/O,各位自問下,有多少人對這個東西有深刻理解?)東西演化的基礎上,不太可能能看懂JB Audio系統。所以,建議這99%中的沒有見識過Audio演化歷史的屌絲同學們,先仔細研究(以前我僅僅建議大家看看,現在提高要求為仔細研究)《深入理解Android 卷I》Audio系統。
BTW,此書在某個章節裡特意提醒過大家要去研究下各種I/O模型,不知道有幾個人屌過我了。
本文將分幾個部分,事前沒有打草稿,所以會有點亂。
先從Java層AudioTrack類說起
一 AudioTrack Java類變化說明
- 聲道數上,以前只有單聲道(MONO)和立體聲(STEREO),現在拓展到最NB八聲道(7.1 HiFi啊)。參數名為CHANNEL_OUT_7POINT1_SURROUND。看到這個參數,我下巴咣當就掉下來了。這玩意,一時半會我還弄不明白是個什麼道理。有知曉的屌絲碼農們不妨告訴大家。 當然,最終的輸出還是雙聲道。多聲道(大於2)的時候會使用downmixer處理(下變換處理,同學們可搜索之)
- 其他的變化也有,但不大了。我這裡先挑一些吸引眼球的。BTW,放心,不會像那個泷澤蘿拉首秀片子一樣只讓大家看見大鼻孔的。
二 AudioTrack JNI層變化說明
這一層包括JNI層和AudioTrack本身
- JNI層變化不大。
- Audio Native核心代碼移到了framework/av下。對,你沒看錯。真的是av。這就是JB Audio一個比較大的變化。Audio Native核心代碼全部移到了frameworks/AV目錄下。
- AudioTrack增加了一個變量,用於控制使用它的進程的調度優先級(前文說錯了,這裡確實設置的是nicer值)。如果處於播放狀態的話,將設置進程調度優先級為ANDROID_PRIORITY_AUDIO。就像你們看到馬賽克時一定會嘟喃一樣。我這裡也要特別啰嗦幾句。在單核CPU的情況下,設置優先級是比較愚蠢的(ANDROID_PRIORITY_AUDIO的值為-16,優先級極高,單核設置個這麼高的怪物,不知道其他app還怎麼玩。如果你不知道我在說什麼,先看看這篇文章吧,http://www.linuxidc.com/Linux/2012-07/65573.htm )。但現在2核,4核已經比較常見了,這裡就可以來玩玩調度方面的事情。對屌絲碼農的真正考驗是:多核並行編程,linux os的原理,需要各位屌絲同學努力掌握。Audio已經不那麼能輕易被你們任意蹂躏了。另外,低端手機,求求你們別移植4.1了,這個真的不是低端能玩的。
- AudioTrack升級為父親了。JB為它定義了一個莫名其妙的的TimedAudioTrack子類。這個類在編解碼的aah_rtp(我現在還不知道aah是什麼)裡邊用到了。從注釋上看,該類是一個帶時間戳(有時間戳,就可以做同步了)的音頻輸出接口。詳細理解的話,就需要結合具體應用場景去分析了(主要是rtp這一塊)。搞編解碼的同學們,抓緊了!
- 另外一個超級復雜的變化,是Audio定義了幾個輸出flag(見audio.h的audio_output_flags_t枚舉定義)。根據注釋,該值有兩個作用,一個是AT的使用者可以指明自己想使用怎樣的outputDevice。另外一個是設備廠商可以通過它聲明自己支持的輸出設備(看來,設備初始化的時候,又增添了參數讀取和配置這方面的工作)。不過,從該枚舉的定義來看,我還看不出它和硬件有什麼關系。它定義的值如下:
typedef enum {
AUDIO_OUTPUT_FLAG_NONE = 0x0, // no attributes
AUDIO_OUTPUT_FLAG_DIRECT = 0x1, // this output directly connects a track
// to one output stream: no software mixer
AUDIO_OUTPUT_FLAG_PRIMARY = 0x2, // this output is the primary output of
// the device. It is unique and must be
// present. It is opened by default and
// receives routing, audio mode and volume
// controls related to voice calls.
AUDIO_OUTPUT_FLAG_FAST = 0x4, // output supports "fast tracks", 《==什麼叫fast track?太難理解了!目前,java層的audiotrack只會使用第一個標志。
// defined elsewhere
AUDIO_OUTPUT_FLAG_DEEP_BUFFER = 0x8 // use deep audio buffers 《==deep buffer是個什麼玩意?這個馬賽克是不是太大了點?現在完全看不清楚啊??!
} audio_output_flags_t;
- AudioTrack其他變化不大。AudioTrack.cpp總共才1600多行,so easy!
OK,上面有好幾個馬賽克,平常看看日本大片的時候也就撸過去了,但分析Audio可不行。把去馬賽克的希望寄托在下一步AudioFlinger的分析上吧!