最近移植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_name=<name>"). Pause are not recorded in the file. LOGV("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過程。

 

通過上面的描述我們可以知道這個通用音訊適配層只是讓你的設備可以用而已,不能發揮設備的性能優勢,如果你的設備對音訊品質有更高的要求,必須要自己實現音訊適配層。谷歌只能保證你的音訊可以播放,但是不能保證效率(他也沒有辦法保證效率)。

 

本文只是粗略的對Android音訊系統進行了簡單介紹。如果有錯誤之處請不吝指教。
arrow
arrow
    全站熱搜

    戮克 發表在 痞客邦 留言(0) 人氣()