最近移植Android,當Android能夠在裝置上面運行之後,首先想到的是讓音訊裝置跑起來。“沒有聲音,再好的戲也出不來”。本文簡單介紹一下
Android音頻適配層。
這個世界音訊裝置千變萬化,Android也不可能為每種裝置都提供支援。Android定義了一個架構,這個框
架來適配底層的音訊裝置。該適配層的定義位於:
hardware/libhardware_legacy/include/hardware_legacy/AudioHardwareInterface.h
要想視頻底層的音訊裝置必須要繼承該檔案中定義的
AudioStreamOut,AudioStreamIn,AudioHardwareInterface等類,並實現
createAudioHardware函數。
下面我們看一下Android建立音訊裝置的代碼,代碼位於:
frameworks/base/libs/audioflinger/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_opening PCM dump interface");
hw =
new AudioDumpInterface(hw); // replace interface
#endif
return hw;
}
從代碼中我們可以看出如果定義了GENERIC_AUDIO的宏,則會建立
AudioHardwareGeneric,如果是模擬器的話,AudioHardwareGeneric會不能初始化,進而建立
AudioHardwareStub。這兩個類都是Audio裝置的適配層,是Android預設提供的。模擬器都是用
AudioHardwareStub,不會有聲音輸出。裝置都是用AudioHardwareGeneric,因為預設GENERIC_AUDIO是設定
的。
一般我們只關心AudioHardwareGeneric實現,誰會去給模擬器去調試聲音呢,反正我沒這個閑心。首先說明一下這個音頻適
配層是 Android內建的,可以保證你的音訊裝置正常運行,但是不能發揮裝置的最佳效能。通過後面的描述你將會瞭解。
AudioHardwareGeneric的定義位於:
frameworks/base/libs/audioflinger/AudioHardwareGeneric.cpp
查看源碼你會發現
這個適配層需要實現裝置/dev/eac,並且該裝置只輸出44.1khz採樣率的音頻資料給
/dev/eac裝置,如果不是44.1khz的採樣率的資料,AudioHardwareGeneric會經過Resample過程把它轉換成
44.1kHZ的音頻資料,然後再輸出給音訊裝置。44.1kHZ音頻資料是最普遍的音頻採樣率,大部分Mp3都是以這個採樣率壓縮的,所以選擇這個採樣
率做為預設採樣率還是有一定的合理性的。AudioHardwareGeneric是軟體實現Resample過程是,效率會比較低。很多音訊裝置支援不
同採樣率的資料,可以理解成硬體實現Resample過程。
通過上面的描述我們可以知道這個通用音頻適配層只是讓你的裝置可以用而已,不能發
揮裝置的效能優勢,如果你的裝置對音頻品質有更高的要求,必須要自己實現音頻適配層。Google只能保證你的音頻可以播放,但是不能保證效率(他也沒有辦法保證
效率)。