朝花夕拾txt微盘:android系统开发(十)-audio移植一

来源:百度文库 编辑:偶看新闻 时间:2024/04/29 03:15:32
android系统开发(十)-audio移植一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-audio3,修改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.mk5,vendor/ardent/merlin/libaudio目录下新建一个Mdroid.mk文件,内容如下:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)LOCAL_MODULE := libaudioLOCAL_SHARED_LIBRARIES := \
    libcutils \
    libutils \
    libmedia \
    libhardwareLOCAL_SRC_FILES += AudioHardwareMerlin.cppLOCAL_CFLAGS +=LOCAL_C_INCLUDES +=LOCAL_STATIC_LIBRARIES += libaudiointerfaceinclude $(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.cppLOCAL_SHARED_LIBRARIES := \
    libcutils \
    libutils \
    libmediaifeq ($(TARGET_SIMULATOR),true)
 LOCAL_LDLIBS += -ldl
else
 LOCAL_SHARED_LIBRARIES += libdl
endifLOCAL_MODULE:= libaudiopolicybaseifeq ($(BOARD_HAVE_BLUETOOTH),true)
  LOCAL_CFLAGS += -DWITH_A2DP
endififeq ($(AUDIO_POLICY_TEST),true)
  LOCAL_CFLAGS += -DAUDIO_POLICY_TEST
endifinclude $(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
#include
#include
#include
#include
#include
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
namespace android {
extern "C" AudioPolicyInterface* createAudioPolicyManager(AudioPolicyClientInterface *clientInterface)
{
    return new AudioPolicyManagerMerlin(clientInterface);
}
}; // namespace android
主要就是定义了接口函数createAudioPolicyManager14,修改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)
经过以上过程再修改一些小错误,基本上就能编译通过,声音的框架也已经起来了,但是系统还是没哟声音,因为还需要进一步的工作,
下一节继续。 本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/jiajie961/archive/2010/12/01/6047077.aspx