1.3 Audio的硬件抽象層 1.3.1 Audio硬件抽象層的接口定義 Audio的硬件抽象層是AudioFlinger和Audio硬件的接口,在各個系統的移植過程中可以有不同的實現方式。Audio硬件抽象層的接口路徑爲: hardware/libhardware_legacy/include/hardware/ 其中主要的文件爲:AudioHardwareBase.h和AudioHardwareInterface.h。 Android中的Audio硬件抽象層可以基於Linux標準的ALSA或OSS音頻驅動實現,也可以基於私有的Audio驅動接口來實現。 在AudioHardwareInterface.h中定義了類:AudioStreamOut、AudioStreamIn和AudioHardwareInterface,AudioStreamOut和AudioStreamIn分別對應了音頻的輸出環節和輸入環節,其中負責數據流的接口分別是wirte()和read(),參數是一塊內存的指針和長度;另外還有一些設置和獲取接口。在這個AudioHardwareInterface接口中,使用openOutputStream()和openInputStream()函數分別獲取AudioStreamOut和AudioStreamIn兩個類,它們作爲音頻輸入/輸出設備來使用。此外,AudioHardwareInterface.h定義了C語言的接口來獲取一個AudioHardware Interface類型的指針。 extern"C" AudioHardwareInterface* createAudioHardware(void); 如果實現一個Android的硬件抽象層,則需要實現AudioHardwareInterface、AudioStream Out和AudioStreamIn三個類,將代碼編譯成動態庫libauido.so。AudioFlinger會連接這個動態庫,並調用其中的 createAudioHardware()函數來獲取接口。 在AudioHardwareBase.h中定義了類:AudioHardwareBase,它繼承了Audio HardwareInterface,顯然繼承這個接口也可以實現Audio的硬件抽象層。 1.3.2 AudioFlinger中自帶Audio硬件抽象層實現 在AudioFlinger中可以通過編譯宏的方式選擇使用哪一個Audio硬件抽象層。這些Audio硬件抽象層既可以作爲參考設計,也可以在沒有實際的Audio硬件抽象層(甚至沒有Audio設備)時使用,以保證系統的正常運行。AudioDumpInterface.h和AudioDumpInterface.cpp是一個提供了Dump功能的Audio硬件抽象層,它所起到的作用就是將輸出的Audio數據寫入到文件中。AudioDumpInterface並不是爲了實際的應用使用的,而是爲了調試使用的類。當進行音頻播放器調試時,有時無法確認是解碼器的問題還是Audio輸出單元的問題,這時就可以用這個類來替換實際的Audio硬件抽象層,將解碼器輸出的Audio的PCM數據寫入文件中,由此可以判斷解碼器的輸出是否正確。 1.3.3 Audio硬件抽象層的真正實現 實現一個真正的Audio硬件抽象層,需要完成的工作和實現以上的硬件抽象層類似。 例如:可以基於Linux標準的音頻驅動:OSS(Open Sound System)或者ALSA(Advanced Linux Sound Architecture)驅動程序來實現。 對於OSS驅動程序,實現方式和前面的AudioHardwareGeneric類似,數據流的讀/寫操作通過對/dev/dsp設備的讀/寫來完成;區別在於OSS支持了更多的ioctl來進行設置,還涉及通過/dev/mixer設備進行控制,並支持更多不同的參數。 對於ALSA驅動程序,實現方式一般不是直接調用驅動程序的設備節點,而是先實現用戶空間的alsa-lib,然後Audio硬件抽象層通過調用alsa-lib來實現。 在實現Audio硬件抽象層時,對於系統中有多個Audio設備的情況,可由硬件抽象層自行處理setRouting()函數設定,例如,可以選擇支持多個設備的同時輸出,或者有優先級輸出。對於這種情況,數據流一般來自AudioStreamOut::write()函數,可由硬件抽象層確定輸出方法。對於某種特殊的情況,也有可能採用硬件直接連接的方式,此時數據流可能並不來自上面的write(),這樣就沒有數據通道,只有控制接口。 Audio硬件抽象層也是可以處理這種情況的。 參考文獻:《Android系統原理及開發要點詳解》電子工業出版社 韓超 樑泉 著 |