android系統開發(十)-audio移植一

來源:互聯網
上載者:User

1,移植基礎:
(1)核心聲音驅動和alsa驅動
(2)alsa-lib和alsa-utils庫移植
這兩部分上一節已經介紹過了。

2,android的audio最核心的部分是audioflinger,audioflinger向上處理來自於應用程式的聲音相關的所有請求
向下通過AudioHardwareInterface訪問硬體,android的audio架構如下所示:
             Applications
                  |
              Frameworks
                  |
                 JNI
                  |
             AudioFlinger
                  |
        AudioHardwareInterface
         |        |        |
       專有audio庫         |     alsa使用者庫
                  |        |
             /dev/eac   /dev/snd/*
                  |        |
                          核心eac驅動    核心alsa驅動
AudioHardwareInterface是audioflinger和硬體驅動之間的橋樑,android預設編譯的是generic audio,此時
AudioHardwareInterface直接指向了/dev/eac驅動,它通過eac驅動來操作音效卡,android audio移植就是要讓
AudioHardwareInterface直接或者間接指向我們自己定義的聲音驅動,一般都採用alsa聲音體系,所以我們的目的就是
要讓AudioHardwareInterface指向alsa使用者庫。下面的內容開始移植alsa-audio

3,修改vendor/ardent/merlin/BoardConfig.mk檔案內容如下:
BOARD_USES_GENERIC_AUDIO := false
BOARD_USES_ALSA_AUDIO := true
BUILD_WITH_ALSA_UTILS := true
上面配置的目的就是為了讓要讓AudioHardwareInterface指向alsa使用者庫

4,下面來添加audio庫的編譯
在vendor/ardent/merlin目錄下建立一個libaudio目錄,修改AndroidBoard.mk檔案,添加編譯路徑如下:
LOCAL_PATH := $(call my-dir)
L_PATH := $(LOCAL_PATH)
include $(L_PATH)/libaudio/Mdroid.mk

5,vendor/ardent/merlin/libaudio目錄下建立一個Mdroid.mk檔案,內容如下:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)

LOCAL_MODULE := libaudio

LOCAL_SHARED_LIBRARIES := /
    libcutils /
    libutils /
    libmedia /
    libhardware

LOCAL_SRC_FILES += AudioHardwareMerlin.cpp

LOCAL_CFLAGS +=

LOCAL_C_INCLUDES +=

LOCAL_STATIC_LIBRARIES += libaudiointerface

include $(BUILD_SHARED_LIBRARY)

6,android audio的實現方法,我們現看看介面部分,上面有說道audioflinger是通過AudioHardwareInterface指向驅動的
AudioHardwareInterface類的代碼在frameworks/base/libs/audioflinger/AudioHardwareInterface.cpp檔案中
該檔案中的create函數中定義了AudioHardwareInterface指向驅動的代碼如下:
    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
    return hw;
當系統為generic audio的時候此函數返回的是一個指向AudioHardwareGeneric對象的指標,其實是返回一個指向AudioHardwareInterface對象
的指標,因為AudioHardwareGeneric是AudioHardwareInterface的子類,繼承關係如下:
AudioHardwareInterface->AudioHardwareBase->AudioHardwareGeneric
如果系統不是generic audio,則通過調用createAudioHardware函數來返回一個指向一個指向AudioHardwareInterface對象的指標,
所以,簡單的將,我們要做的事情就是實現這個函數以及它相關的內容即可。createAudioHardware函數我們可以在
hardware/libhardware_legacy/include/hardware_legacy/AudioHardwareInterface.h中也就是AudioHardwareInterface
的聲明中找到原型如下:
extern "C" AudioHardwareInterface* createAudioHardware(void);

7,通過6我們不難知道,我們實現自己的audio介面完全可以模仿generic audio的做法,只是要多實現一個createAudioHardware函數而已,
因此我們將frameworks/base/libs/audioflinger/AudioHardwareInterface.h檔案複製到
vendor/ardent/merlin/libaudio目錄下,改名為AudioHardwareMerlin.h,然後將此檔案中所有的Generic欄位通通替換成Merlin
然後將frameworks/base/libs/audioflinger/AudioHardwareInterface.cpp複製到
vendor/ardent/merlin/libaudio目錄下,改名為AudioHardwareMerlin.cpp,然後將此檔案中所有的Generic欄位通通替換成Merlin
最後在AudioHardwareMerlin.cpp中定義createAudioHardware函數如下:
extern "C" AudioHardwareInterface* createAudioHardware(void)
{
    return new AudioHardwareMerlin();
}

8,進行到7後直接編譯,發現編譯不過,錯誤如下
target thumb C++: libaudioflinger <= frameworks/base/libs/audioflinger/AudioFlinger.cpp
make: *** 沒有規則可以建立“out/target/product/merlin/obj/SHARED_LIBRARIES/libaudioflinger_intermediates/LINKED/libaudioflinger.so”需要的目標“out/target/product/merlin/obj/lib/libaudiopolicy.so”。 停止。
原來是編譯audioflinger的時候需要libaudiopolicy.so的支援
查看frameworks/base/libs/audioflinger/Android.mk檔案,發現有如下內容:
ifeq ($(strip $(BOARD_USES_GENERIC_AUDIO)),true)
  LOCAL_STATIC_LIBRARIES += libaudiointerface libaudiopolicybase
  LOCAL_CFLAGS += -DGENERIC_AUDIO
else
  LOCAL_SHARED_LIBRARIES += libaudio libaudiopolicy
endif
看來generic audio的時候需要的是libaudiointerface和libaudiopolicybase靜態庫,否則需要libaudio和libaudiopolicy動態庫
libaudio庫上面我們已經實現,看來下面的內容就是要實現libaudiopolicy庫了

9,audio policy介面的調用在frameworks/base/libs/audioflinger/AudioPolicyService.cpp檔案中的AudioPolicyService類
的建構函式中,如下:
#if (defined GENERIC_AUDIO) || (defined AUDIO_POLICY_TEST)
    mpPolicyManager = new AudioPolicyManagerBase(this);
    LOGV("build for GENERIC_AUDIO - using generic audio policy");
#else
    // if running in emulation - use the emulator driver
    if (property_get("ro.kernel.qemu", value, 0)) {
        LOGV("Running in emulation - using generic audio policy");
        mpPolicyManager = new AudioPolicyManagerBase(this);
    }
    else {
        LOGV("Using hardware specific audio policy");
        mpPolicyManager = createAudioPolicyManager(this);
    }
#endif
該目錄下的AudioPolicyService.h檔案中定義了mpPolicyManager如下:
    AudioPolicyInterface* mpPolicyManager;          // the platform specific policy manager
可見,當系統為generic audio或者運行在模擬器上時,mpPolicyManager是一個指向AudioPolicyManagerBase對象的指標
否則就要通過createAudioPolicyManager函數來返回。
AudioPolicyInterface類和AudioPolicyManagerBase類聲明在hardware/libhardware_legacy/include/hardware_legacy
目錄下的AudioPolicyInterface.h和AudioPolicyManagerBase.h檔案中,而且AudioPolicyManagerBase類是AudioPolicyInterface
的子類。

10,實現libaudiopolicy庫
libaudiopolicy庫的實現我們也可以模仿generic audio的實現方式,從8我們可以看出,generic audio的時候audiopolicy用的是
靜態libaudiopolicybase庫,從frameworks/base/libs/audioflinger/Android.mk檔案可以找到該靜態庫的編譯內容如下:
include $(CLEAR_VARS)

LOCAL_SRC_FILES:=               /
    AudioPolicyManagerBase.cpp

LOCAL_SHARED_LIBRARIES := /
    libcutils /
    libutils /
    libmedia

ifeq ($(TARGET_SIMULATOR),true)
 LOCAL_LDLIBS += -ldl
else
 LOCAL_SHARED_LIBRARIES += libdl
endif

LOCAL_MODULE:= libaudiopolicybase

ifeq ($(BOARD_HAVE_BLUETOOTH),true)
  LOCAL_CFLAGS += -DWITH_A2DP
endif

ifeq ($(AUDIO_POLICY_TEST),true)
  LOCAL_CFLAGS += -DAUDIO_POLICY_TEST
endif

include $(BUILD_STATIC_LIBRARY)
由此可見,libaudiopolicybase靜態庫編譯的就是frameworks/base/libs/audioflinger/AudioPolicyManagerBase.cpp檔案

11,通過9和10的分析,結合libaudio庫的寫法,要完成libaudiopolicy庫,我們可以將AudioPolicyManagerBase.cpp
和AudioPolicyManagerBase.h複製到vendor/ardent/merlin/libaudio目錄下,然後將這兩個檔案名稱改成和其中的內容作
一定修改,讓它變成兩外一個類如AudioPolicyManagerMerlin類的定義,然後在cpp檔案中定義介面函數createAudioPolicyManager如下:
extern "C" AudioPolicyInterface* createAudioPolicyManager(AudioPolicyClientInterface *clientInterface)
{
    return new AudioPolicyManagerMerlin(clientInterface);
}
然後再修改相關Mdroid.mk檔案編譯成libaudiopolicy.so即可
採用這種方法可以實現,但是卻不必要,因為generic audio所用的AudioPolicyManagerBase已經非常完善,所以我們只需要直接繼承這個類即可
下面來實現它。

12,在vendor/ardent/merlin/libaudio目錄下建立一個AudioPolicyManagerMerlin.h檔案,內容如下:
#include <stdint.h>
#include <sys/types.h>
#include <utils/Timers.h>
#include <utils/Errors.h>
#include <utils/KeyedVector.h>
#include <hardware_legacy/AudioPolicyManagerBase.h>
namespace android {
class AudioPolicyManagerMerlin: public AudioPolicyManagerBase
{

public:
                AudioPolicyManagerMerlin(AudioPolicyClientInterface *clientInterface)
                : AudioPolicyManagerBase(clientInterface) {}

        virtual ~AudioPolicyManagerMerlin() {}
};
};
主要是聲明我們所用的AudioPolicyManagerMerlin,通過直接繼承generic audio所用AudioPolicyManagerBase類來實現

13,在vendor/ardent/merlin/libaudio目錄下建立一個AudioPolicyManagerMerlin.cpp檔案,內容如下:
#include "AudioPolicyManagerMerlin.h"
#include <media/mediarecorder.h>
namespace android {
extern "C" AudioPolicyInterface* createAudioPolicyManager(AudioPolicyClientInterface *clientInterface)
{
    return new AudioPolicyManagerMerlin(clientInterface);
}
}; // namespace android
主要就是定義了介面函數createAudioPolicyManager

14,修改vendor/ardent/merlin/libaudio/Mdroid.mk函數,添加libaudiopolicy的編譯如下:
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= /
        AudioPolicyManagerMerlin.cpp
LOCAL_SHARED_LIBRARIES := /
    libcutils /
    libutils /
    libmedia
LOCAL_STATIC_LIBRARIES += libaudiopolicybase
LOCAL_MODULE:= libaudiopolicy
include $(BUILD_SHARED_LIBRARY)
經過以上過程再修改一些小錯誤,基本上就能編譯通過,聲音的架構也已經起來了,但是系統還是沒喲聲音,因為還需要進一步的工作,
下一節繼續。

 

自己補充,需要關注的檔案:

system/core/init/device.c      /dev/snd 的添加

build/tartget/board/generic/BoardConfig.mk    使用ALSA宏配置

asound.conf          設定檔

init.rc節點許可權

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.