Android Audio 3: Audio的实现

https://source.android.com/devices/audio/implement.html

本篇将阐述如何实现Audio HAL和如何配置共享库。

1. 实现HAL

Audio HAL由三部分构成,这三部分必须实现。

  • hardware/libhardware/include/hardware/audio.h
    表征了一个audio device的主要方法

  • hardware/libhardware/include/hardware/audio_policy.h
    表征音频策略管理,包括处理音频路由,音量控制等。

  • hardware/libhardware/include/hardware/audio_effect.h
    表征适用于audio的音效,比如downmixing, echo或者noise suppression.

比如,可以参考Galaxy Nexus的实现,路径:device/samsung/tuna/audio

除了实现HAL,你需要创建文件
device/company_name/device_name/audio/audio_policy.conf,这个文件用来声明在你设备上的audio devices. 比如,可以参考Galaxy Nexus的实现:
device/samsung/tuna/audio/audio_policy.conf,另外,也可以参考audio头文件。

Android M及之后的版本,头文件路径是:

system/media/audio/include/system/audio.h
system/media/audio/include/system/audio_policy.h

Android 5.1及之前的版本,头文件路径是:

system/core/include/system/audio.h
system/core/include/system/audio_policy.h

1.1 多声道支持

如果你的硬件和驱动支持通过HDMI的多声道(multi-channel)音频, 你可以直接输出音频流到音频硬件。这样就绕过了AudioFlinger的mixer,就不用降到双声道了。

音频HAL必现显示的指明output stream是否具有支持多声道音频的能力。如果HAL指明了它的能力,默认的音频管理器允许HDMI上的多声道播放。

更多实现的细节,可以参见Android 4.1上的:
device/samsung/tuna/audio/audio_hw.c

为了指明你的设备包含一个多声道的audio output,编辑audio_policy.conf来描述。下面的代码是Galaxy上的一个列子,它展示了一个”dynamic”的channel mask, 这意味着音频管理器可以在和HDMI连上以后再查询HDMI支持的声道数。你也可以指定一个静态的channel mask比如AUDIO_CHANNEL_OUT_5POINT1

audio_hw_modules {
  primary {
    outputs {
        ...
        hdmi {
          sampling_rates 44100|48000
          channel_masks dynamic
          formats AUDIO_FORMAT_PCM_16_BIT
          devices AUDIO_DEVICE_OUT_AUX_DIGITAL
          flags AUDIO_OUTPUT_FLAG_DIRECT
        }
        ...
    }
    ...
  }
  ...
}

如果音频设备不支持多声道,当发送数据给设备的时候,AudioFlinger的mixer会自动把数据downmix成双声道。

1.2 media编解码

确保你的硬件和驱动支持的audio编解码在你的设备上被声明。关于如何声明支持的编解码,可以参考Exposing Codecs to the Framework

2. 配置共享库

你需要把你的HAL实现打包成一个共享库,并且通过创建一个Android.mk文件来把这个共享库拷贝到一个适合的位置。

  • 创建device/company_name/device_name/audio目录,这个目录要包含共享库的源文件。
  • 创建一个Android.mk文件来编译这个共享库,确保这个mk文件包含以下这一行
LOCAL_MODULE := audio.primary.

注意你的共享库必须命名为audio.primary.device_name.so,这样Android才能正确的加载这个库。这个名字的primary部分指明了这个库是对应于设备上的Primary接口的。命令为audio.a2dp.device_name和audio.usb.device_name的库对应于蓝牙和usb接口的。下面是Galaxy上的一个例子

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := audio.primary.tuna
LOCAL_MODULE_RELATIVE_PATH := hw
LOCAL_SRC_FILES := audio_hw.c ril_interface.c
LOCAL_C_INCLUDES += \
        external/tinyalsa/include \
        $(call include-path-for, audio-utils) \
        $(call include-path-for, audio-effects)
LOCAL_SHARED_LIBRARIES := liblog libcutils libtinyalsa libaudioutils libdl
LOCAL_MODULE_TAGS := optional

include $(BUILD_SHARED_LIBRARY)
  • 如果你的设备支持CDD定义的低延时(low latency)audio,把对应的xml功能文件拷贝到你的设备。比如
    在device/company_name/device_name/device.mk添加
PRODUCT_COPY_FILES := ...

PRODUCT_COPY_FILES += \
frameworks/native/data/etc/android.hardware.audio.low_latency.xml:system/etc/permissions/android.hardware.audio.low_latency.xml \
  • 把audio_policy.conf拷贝到/system/etc目录,可以在
    device/company_name/device_name/device.mk添加一下代码
PRODUCT_COPY_FILES += \
        device/samsung/tuna/audio/audio_policy.conf:system/etc/audio_policy.conf
  • 在device/company_name/device_name/device.mk中声明你的共享库,以下是Galaxy中Primary和蓝牙相关的共享
PRODUCT_PACKAGES += \
        audio.primary.tuna \
        audio.a2dp.default

3. 音频预处理音效

Android平台通过audiofx包提供了音效的功能,audiofx对开发者是可见的。比如,在Nexus10上,以下的预处理音效是支持的。

  • Acoustic Echo Cancellation
  • Automatic Gain Control
  • Noise Suppression

    预处理音效和在用例模式(use case mode)请求的预处理音效是匹配的。在Android应用开发中,一个用例就是一个AudioSource.应用开发者使用AudioSource来作为实际的音频硬件设备的抽象。Android音频策略管理器通过
    AudioPolicyManagerBase::getDeviceForInputSource(int inputSource)来映射到实际的硬件。以下的AudioSource是开放给开发者的:

android.media.MediaRecorder.AudioSource.CAMCORDER
android.media.MediaRecorder.AudioSource.VOICE_COMMUNICATION
android.media.MediaRecorder.AudioSource.VOICE_CALL
android.media.MediaRecorder.AudioSource.VOICE_DOWNLINK
android.media.MediaRecorder.AudioSource.VOICE_UPLINK
android.media.MediaRecorder.AudioSource.VOICE_RECOGNITION
android.media.MediaRecorder.AudioSource.MIC
android.media.MediaRecorder.AudioSource.DEFAULT

每一个AudioSource使用的默认的预处理音效在/system/ect/audio_effects.conf文件中指定。如果想为每个AudioSource指定你自己的默认的预处理音效,你可以创建一个
/system/vendor/ect/audio_effects.conf文件,并指定预处理音效打开。比如,可以参考Nexus 10的device/samsung/manta/audio_effects.conf文件,音效实例在创建和销毁的时候会申请和释放一个会话(session),在会话的持续时间内要一直使能音效(比如Loudness Enhancer).

提醒:对于VOICE_RECOGNITION这个用例,不要使能Noise Suppression这个预处理音效。当从这个source录音的时候,降噪这个音效不能默认打开,你也不能在你自定义的audio_effects.conf中打开它。不管这个音效是由于配成成默认打开还是音频audio实现的默认行为,默认打开它会导致兼容性失败。

下面的例子针对VoIP和Camcorder这两个AudioSource打开了预处理音效。通过这种方式声明AudioSource的配置,framework会自动请求音频HAL使用这些音效。

pre_processing {
   voice_communication {
       aec {}
       ns {}
   }
   camcorder {
       agc {}
   }
}

3.1 Source tuning

对于AudioSource tuning,除了VOICE_RECOGNITION,在音频增益和音频处理方面没有明确的需求。

tuning VOICE_RECOGNITION方面的需求是:

  • “flat” frequency response (+/- 3dB) from 100Hz to 4kHz
  • close-talk config: 90dB SPL reads RMS of 2500 (16bit samples)
  • level tracks linearly from -18dB to +12dB relative to 90dB SPL
  • THD < 1% (90dB SPL in 100 to 4000Hz range)
  • 8kHz sampling rate (anti-aliasing)
  • Effects/pre-processing must be disabled by default

    以下是对不同的source的不同音效的tunning举例:

  • Noise Suppressor

    • Tuned for wind noise suppressor for CAMCORDER
    • Tuned for stationary noise suppressor for VOICE_COMMUNICATION
  • Automatic Gain Control

    • Tuned for close-talk for VOICE_COMMUNICATION and main phone mic
    • Tuned for far-talk for CAMCORDER

3.2 更多信息

更多信息,参加:

  • audiofx方面的Android文档
  • Noise Suppression audio effect方面的Android文档
  • Nexus 10的device/samsung/manta/audio_effects.conf文件

你可能感兴趣的:(Android多媒体)