现在的位置: 首页 > 综合 > 正文

Android Audio Policy小记

2018年06月09日 ⁄ 综合 ⁄ 共 2971字 ⁄ 字号 评论关闭

Android的Audio系统分为两大块,一块是audio的策略管理,即Audio Policy模块;一块是AudioFlinger模块,负责和Audio Hardware Module直接交互。

本文主要讲解Audio Policy模块的以下知识点:

1. audio policy策略文件的加载;

2. 创建AudioRecord的时候,如何根据intput source选择合适的device;

3. 创建AudioTrack的时候,如何根据output stream选择合适的device;

首先讲第一点。

audio policy策略文件即:/system/etc/audio_policy.conf 或者/vendor/etc/audio_policy.conf。在AudioPolicyManagerBase的构造函数中会加载和分析这个配置文件。

那么AudioPolicyManagerBase又是在何时构造的呢?

AudioPolicyService构造函数中会加载audio policy的HAL Module。AudioPolicyService与 audio policy module的组件图如下:

下面是一个audio_policy.conf文件的部分内容:

audio_hw_modules {
  primary {
    outputs {
      primary {
        sampling_rates 44100
        channel_masks AUDIO_CHANNEL_OUT_STEREO
        formats AUDIO_FORMAT_PCM_16_BIT
        devices AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_WIRED_HEADSET|AUDIO_DEVICE_OUT_WIRED_HEADPHONE|AUDIO_DEVICE_OUT_AUX_DIGITAL
        flags AUDIO_OUTPUT_FLAG_PRIMARY
      }
      hdmi {
        sampling_rates dynamic
        channel_masks dynamic
        formats AUDIO_FORMAT_PCM_16_BIT
        devices AUDIO_DEVICE_OUT_AUX_DIGITAL
        flags AUDIO_OUTPUT_FLAG_DIRECT
      }
    }
    inputs {
      primary {
        sampling_rates 8000|11025|16000|22050|24000|32000|44100|48000
        channel_masks AUDIO_CHANNEL_IN_MONO|AUDIO_CHANNEL_IN_STEREO
        formats AUDIO_FORMAT_PCM_16_BIT
        devices AUDIO_DEVICE_IN_BUILTIN_MIC|AUDIO_DEVICE_IN_WIRED_HEADSET|AUDIO_DEVICE_IN_USB_DEVICE
      }
    }
  }

}

audio_hw_modules节点表示系统中包含的audio hardware module。每个子节点都对应一个 hal so。比如primary对应着audio.primary.<device>.so。primary可以理解为一个audio interface。
一个audio interface模块有输入模块和输入模块,在文件中的outputs和inputs中定义。primary 部分解析完毕后对应于抽象的class HwModule 。

        class HwModule {
        public:
                    HwModule(const char *name);
                    ~HwModule();

            void dump(int fd);

            const char *const mName; // base name of the audio HW module (primary, a2dp ...)
            audio_module_handle_t mHandle;
            Vector <IOProfile *> mOutputProfiles; // output profiles exposed by this module
            Vector <IOProfile *> mInputProfiles;  // input profiles exposed by this module
        };


可见每个HwModule都有好多个输入模块和输出模块,输入输出模块的属性用IOProfile抽象。接着讲第二点,创建AudioRecord的时候,如何根据intput source选择合适的device。在创建AudioRecord的时候会指定一个参数:audio_source_t

typedef enum {
    AUDIO_SOURCE_DEFAULT             = 0,
    AUDIO_SOURCE_MIC                 = 1,
    AUDIO_SOURCE_VOICE_UPLINK        = 2,
    AUDIO_SOURCE_VOICE_DOWNLINK      = 3,
    AUDIO_SOURCE_VOICE_CALL          = 4,
    AUDIO_SOURCE_CAMCORDER           = 5,
    AUDIO_SOURCE_VOICE_RECOGNITION   = 6,
    AUDIO_SOURCE_VOICE_COMMUNICATION = 7,
    AUDIO_SOURCE_REMOTE_SUBMIX       = 8, /* Source for the mix to be presented remotely.      */
                                          /* An example of remote presentation is Wifi Display */
                                          /*  where a dongle attached to a TV can be used to   */
                                          /*  play the mix captured by this audio source.      */
    
	AUDIO_SOURCE_USB_DEVICE_1		 = 9,
	AUDIO_SOURCE_USB_DEVICE_2		 = 10,

	AUDIO_SOURCE_CNT,
    AUDIO_SOURCE_MAX                 = AUDIO_SOURCE_CNT - 1,
} audio_source_t;

根据不同的audio_source_t枚举值,AudioPolicyManagerBase会选择不同的Device录入音频数据。具体选择的策略在audio_io_handle_t AudioPolicyManagerBase::getInput
函数中实现。对于一个系统来说,可能有多个设备都可以录入音频数据,那个如何选择正确的设备,这就是getInput函数的职责。


第三个问题,创建AudioTrack的时候,如何根据output stream选择合适的device。这个可以从下面的图标中得知一二:通过AudioTrack的stream
type,获得一个strategy,然后根据strategy获得一个device。然后根据device的属性,AudioPolicyManagerBase会为之匹配合适的audio_io_handle.对于一个audio hardware module来说,AudioFlinger加载完毕之后会为之分配一个handle:audio_module_handle_t。每一个audio_module_handle_t中创建的输入输出流都用audio_io_handle_t标识。每一个audio_io_handle_t背后是一个工作thread和与这个thread所绑定的stream。


抱歉!评论已关闭.