從大的方面來說,Android2.3的音頻系統架構與Android2.2相比並沒有太多的改變。對2.2的音頻架構分析依然適用於2.3,之前很多人已經對這方面進行非常詳盡的闡述,這裏就不重複了。各模塊文件的存放位置有所變更,這點倒是要了解的。
1、有個較大的改進的是引入了mixable audio effects系統。我草草翻了翻代碼,應該是opensles實現的。opensles也是2.3新引入的一個音頻庫,這使得Android的音效變得更強大。但應該會犧牲一些性能,比方說之前Android Framework層固定audio sample rate爲44.1khz,對音頻流進行resample(AudioResampler.cpp),這使得audio相關線程CPU佔用率非常高。
Android給我的感覺就是太照顧開發者了。縱然是底層都有很多地方使用跨平臺軟件方法,儘量減少HAL,如mixer、equalizer等。mixer還算好,起碼在AudioHardwareInterface.h有提供接口供HAL實現,聲音特效如equalizer就只是軟件實現了。有關HAL的實現參考hardware和device這兩個目錄的文件;對於audio,android2.3.1-gingerbread/device/samsung/crespo/libaudio是極具價值的,我估計就算移植另一個平臺,對於這部分的改動都是非常少的。
2、Android2.2時代還保留opencore多媒體框架,雖然只使用了omx-component,其他默認情況下選擇了stagefright。而2.3則完全使用了stagefright,opencore也從android中移除了。有關opencore和stagefright的介紹見:http://blogold.chinaunix.net/u2/61880/showart.php?id=2339481
與opencore同一命運的是alsa-lib。開始時我挺吃驚的,opencore可以用stagefright來替代,但是有什麼音頻底層庫可以替代alsa-lib?看到android2.3.1-gingerbread/device/samsung/crespo/libaudio才釋然,原來其中的alsa_pcm.c和alsa_mixer.c實現了一個迷你的alsa-lib。
我想在今後的版本中,Google可能還會繼續幹同樣的事,不斷移除一些開源庫,而實現自己的一套,顯得更簡潔。以我個人來說是不大喜歡這個做法。開源庫往往功能更強大,接口也標準,現在開發者又要多花稍許時間去熟悉android閹割版的接口--或許多慮了,畢竟開發者很少會去改動framework層;還有就是開源庫還會不斷更新修正,Google能不能跟上也難說。
--------------------------------------------------------------------------------
4/9 2011
稍微分析一下Audio HAL即audioflinger以下,因爲看了網上幾篇文章,看起來有些錯誤或許闡述得不夠清晰。
首先AudioFlinger.cpp:
AudioFlinger::AudioFlinger()
: BnAudioFlinger(),
mAudioHardware(0), mMasterVolume(1.0f), mMasterMute(false), mNextUniqueId(1)
{
mHardwareStatus = AUDIO_HW_IDLE;
mAudioHardware = AudioHardwareInterface::create();
mHardwareStatus = AUDIO_HW_INIT;
if (mAudioHardware->initCheck() == NO_ERROR) {
// open 16-bit output stream for s/w mixer
mMode = AudioSystem::MODE_NORMAL;
setMode(mMode);
setMasterVolume(1.0f);
setMasterMute(false);
} else {
LOGE("Couldn't even initialize the stubbed audio hardware!");
}
#ifdef LVMX
LifeVibes::init();
mLifeVibesClientPid = -1;
#endif
}
可以看到紅色部分是通過AudioHardwareInterface.create來創建一個audio hardware接口,我們追溯到AudioHardwareInterface.cpp:
AudioHardwareInterface* AudioHardwareInterface::create()
{
/*
* FIXME: This code needs to instantiate the correct audio device
* interface. For now - we use compile-time switches.
*/
AudioHardwareInterface* hw = 0;
char value[PROPERTY_VALUE_MAX];
#ifdef GENERIC_AUDIO
hw = new AudioHardwareGeneric();
#else
// if running in emulation - use the emulator driver
if (property_get("ro.kernel.qemu", value, 0)) {
LOGD("Running in emulation - using generic audio driver");
hw = new AudioHardwareGeneric();
}
else {
LOGV("Creating Vendor Specific AudioHardware");
hw = createAudioHardware();
}
#endif
if (hw->initCheck() != NO_ERROR) {
LOGW("Using stubbed audio hardware. No sound will be produced.");
delete hw;
hw = new AudioHardwareStub();
}
#ifdef WITH_A2DP
hw = new A2dpAudioInterface(hw);
#endif
#ifdef ENABLE_AUDIO_DUMP
// This code adds a record of buffers in a file to write calls made by AudioFlinger.
// It replaces the current AudioHardwareInterface object by an intermediate one which
// will record buffers in a file (after sending them to hardware) for testing purpose.
// This feature is enabled by defining symbol ENABLE_AUDIO_DUMP.
// The output file is set with setParameters("test_cmd_file_name=<name>"). Pause are not recorded in the file.
LOGV("opening PCM dump interface");
hw = new AudioDumpInterface(hw); // replace interface
#endif
return hw;
}
以不同的顏色區分,這裏可以支持6種audio接口,分別爲:
1、Generic Audio:是Android默認選中的audio hardware,操作底層設備節點是/dev/eac,具體見AudioHardwareGeneric.cpp。我沒深入瞭解這個接口對應的底層驅動。
2、Emulator Audio:也是用Generic Audio。
3、Vendor Specific Audio:廠商自定義audio hardware接口,這是我們的重點,一般來說我們需要實現的就是這個接口,稍後重點分析一下。
4、A2DP Audio:藍牙音頻,沒有深入瞭解。
5、Stubbed Audio:實現方法在AudioHardwareStub.cpp,可以看到大多數函數只是返回一個值,並沒有實際操作。它只是保證Android最起碼能得到一個audio hardware實例,從而使其啓動運行,當然是沒有聲音的。
6、Dump Audio:詳細見註釋,主要用來調試上層音頻程序,將上層record的聲音保存到一個文件中,方便分析。
Vendor Specific Audio
一般我們只需要實現hardware/libhardware_legacy/include/hardware_legacy/AudioHardwareInterface.h提供的接口就可以了,然後extern "C" AudioHardwareInterface* createAudioHardware(void);方便AudioHardwareInterface* AudioHardwareInterface::create()調用。
以samsung的crespo爲例,device/samsung/crespo/libaudio/AudioHardware.cpp,它實現一個AudioHardware的類,其方法也是根據AudioHardwareInterface.h提供的純虛函數接口來實現的。
extern "C" AudioHardwareInterface* createAudioHardware(void) {
return new AudioHardware();
}
注:如開篇所說,Android2.3已經去掉了alsa-lib,這裏其實調用到底層還是alsa-driver,它實現了一個mini alsa-lib,有興趣的可以看看。當然根據需要也可以用其他的音頻驅動架構如OSS或許廠商自己的固件(不開源的,想來Android HAL也是這個目的)。
BoardConfig
板配置選項文件見build/target/board/generic/BoardConfig.mk,默認下定義:
BOARD_USES_GENERIC_AUDIO := true
這是使用Generic Audio接口。
如果要使用vendor specific audio接口,可以修改:
HAVE_HTC_AUDIO_DRIVER := false
BOARD_USES_GENERIC_AUDIO := false
然後添加:
BOARD_USES_VENDOR_SPECIFIC_AUDIO := true
BOARD_USES_VENDOR_SPECIFIC_AUDIO要根據自己板子的Android.mk來定。
本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/sepnic/archive/2011/03/11/6241019.aspx