ANDROID2.3音频系统HAL

从大的方面来说,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能不能跟上也难说。




2011/4/9

稍微分析一下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来定。

评论 19
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值