android音频hal层简介

您所在的位置:网站首页 headset读音 android音频hal层简介

android音频hal层简介

2024-01-02 23:20| 来源: 网络整理| 查看: 265

如下图为android音频hal层所处的位置:

这里写图片描述

从上图可以看出,HAL层下面使用TiniAlsa(Android下一个简约的Alsa版本)。HAL层分为两部分,一部分为各种音频设备,每种音频设备由一个独立的库文件实现:如audio.a2dp.default.so(管理蓝牙a2dp音频),audio.usb.default.so(管理usb外接的音频),audio.primary.default.so(管理设备上的大部分音频)。另一部分为厂家自己实现的音频策略,Android下提供了默认一套音频策略,当厂家有特殊的音频策略时,可以在这部分修改实现。HAL层上面就是音频系统的核心AudioFlinger,这里实现了各种输入、输出音频流的管理,管理实时可用的音频通道,为各种音频流选择音频通道,实现多个音频流的混音等。 这里只介绍HAL中各种音频设备的管理,如何确定各种音频设备支持哪些输入、输出音频等。AudioFlinger在加载音频设备库文件时,从/system/lib/hw/下查找以audio开头的库,同时根据audio_policy.conf中定义的音频设备名(如a2dp、usb、primary)作为库的第二部分名称,对于没有特别指定的,库的第三部分名称就是default,所以加载音频设备库的名称就可以确定了,如:audio.a2dp.default.so。每个音频库的实现接口都是一样的,这样就可以让AudioFlinger使用相同的接口调用不同音频设备。 android\external\bluetooth\bluedroid\audio_a2dp_hw\Audio_a2dp_hw.c /* 音频open函数,用于确定音频输入输出流的实现接口,各种音频数据格式的设置获取接口 */ static int adev_open(const hw_module_t* module, const char* name, hw_device_t** device) { struct a2dp_audio_device *adev; int ret; INFO(" adev_open in A2dp_hw module"); FNLOG(); if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0) { ERROR("interface %s not matching [%s]", name, AUDIO_HARDWARE_INTERFACE); return -EINVAL; } adev = calloc(1, sizeof(struct a2dp_audio_device)); if (!adev) return -ENOMEM; adev->device.common.tag = HARDWARE_DEVICE_TAG; adev->device.common.version = AUDIO_DEVICE_API_VERSION_2_0; adev->device.common.module = (struct hw_module_t *) module; adev->device.common.close = adev_close; adev->device.init_check = adev_init_check; adev->device.set_voice_volume = adev_set_voice_volume; adev->device.set_master_volume = adev_set_master_volume; adev->device.set_mode = adev_set_mode; adev->device.set_mic_mute = adev_set_mic_mute; adev->device.get_mic_mute = adev_get_mic_mute; adev->device.set_parameters = adev_set_parameters; adev->device.get_parameters = adev_get_parameters; adev->device.get_input_buffer_size = adev_get_input_buffer_size; adev->device.open_output_stream = adev_open_output_stream; adev->device.close_output_stream = adev_close_output_stream; adev->device.open_input_stream = adev_open_input_stream; adev->device.close_input_stream = adev_close_input_stream; adev->device.dump = adev_dump; adev->output = NULL; *device = &adev->device.common; return 0; } /* 音频模块open接口函数 */ static struct hw_module_methods_t hal_module_methods = { .open = adev_open, }; /* 定义的音频模块 */ struct audio_module HAL_MODULE_INFO_SYM = { .common = { .tag = HARDWARE_MODULE_TAG, .version_major = 1, .version_minor = 0, .id = AUDIO_HARDWARE_MODULE_ID, .name = "A2DP Audio HW HAL", .author = "The Android Open Source Project", .methods = &hal_module_methods, }, }; 在音频设备库的实现代码里,没有看到该音频设备库支持哪些音频输入、输出设备,音频设备支持的输入、输出设备不是在代码里面写死的,而是通过audio_policy.conf文件进行配置的。如下面的一份配置文件。 audio_hw_modules { primary { /* 主音频配置文件 */ global_configuration { attached_output_devices AUDIO_DEVICE_OUT_SPEAKER default_output_device AUDIO_DEVICE_OUT_SPEAKER attached_input_devices AUDIO_DEVICE_IN_BUILTIN_MIC audio_hal_version 3.0 } devices { speaker { type AUDIO_DEVICE_OUT_SPEAKER gains { gain_1 { mode AUDIO_GAIN_MODE_JOINT min_value_mB -8400 max_value_mB 4000 default_value_mB 0 step_value_mB 100 } } } } outputs { primary { sampling_rates 48000 channel_masks AUDIO_CHANNEL_OUT_STEREO formats AUDIO_FORMAT_PCM_16_BIT devices AUDIO_DEVICE_OUT_EARPIECE|AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_WIRED_HEADSET|AUDIO_DEVICE_OUT_WIRED_HEADPHONE|AUDIO_DEVICE_OUT_AUX_DIGITAL|AUDIO_DEVICE_OUT_ALL_SCO flags AUDIO_OUTPUT_FLAG_PRIMARY } } inputs { primary { sampling_rates 8000|16000 channel_masks AUDIO_CHANNEL_IN_MONO formats AUDIO_FORMAT_PCM_16_BIT devices AUDIO_DEVICE_IN_BUILTIN_MIC|AUDIO_DEVICE_IN_ALL_SCO } } } a2dp { /* a2dp音频配置文件 */ global_configuration { attached_output_devices AUDIO_DEVICE_OUT_BLUETOOTH_A2DP audio_hal_version 2.0 } outputs { a2dp { sampling_rates 44100 channel_masks AUDIO_CHANNEL_OUT_STEREO formats AUDIO_FORMAT_PCM_16_BIT devices AUDIO_DEVICE_OUT_BLUETOOTH_A2DP|AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES|AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER } } } usb { /* usb音频配置文件 */ global_configuration { attached_output_devices AUDIO_DEVICE_OUT_USB_ACCESSORY audio_hal_version 2.0 } outputs { usb_accessory { sampling_rates 44100 channel_masks AUDIO_CHANNEL_OUT_STEREO formats AUDIO_FORMAT_PCM_16_BIT devices AUDIO_DEVICE_OUT_USB_ACCESSORY } usb_device { sampling_rates 44100 channel_masks AUDIO_CHANNEL_OUT_STEREO formats AUDIO_FORMAT_PCM_16_BIT devices AUDIO_DEVICE_OUT_USB_DEVICE } } } }

可以看到对于a2dp来说,只支持音频输出,不支持音频输入,所以只有outputs device,没有inputs device,而对于主音频设备、就有inputs device。然后在device中就会配置该音频设备支持的输入、输出音频,如a2dp的输出音频就支持:AUDIO_DEVICE_OUT_BLUETOOTH_A2DP|AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES|AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER。支持的输入音频设备定义也类似,如主音频中inputs device中的定义。 Android下各种音频输入、输出设备定义如下:

android/system/core/include/system/audio.h enum { AUDIO_DEVICE_NONE = 0x0, /* reserved bits */ AUDIO_DEVICE_BIT_IN = 0x80000000, AUDIO_DEVICE_BIT_DEFAULT = 0x40000000, /* output devices */ AUDIO_DEVICE_OUT_EARPIECE = 0x1, AUDIO_DEVICE_OUT_SPEAKER = 0x2, AUDIO_DEVICE_OUT_WIRED_HEADSET = 0x4, AUDIO_DEVICE_OUT_WIRED_HEADPHONE = 0x8, AUDIO_DEVICE_OUT_BLUETOOTH_SCO = 0x10, AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET = 0x20, AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT = 0x40, AUDIO_DEVICE_OUT_BLUETOOTH_A2DP = 0x80, AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES = 0x100, AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER = 0x200, AUDIO_DEVICE_OUT_AUX_DIGITAL = 0x400, AUDIO_DEVICE_OUT_HDMI = AUDIO_DEVICE_OUT_AUX_DIGITAL, /* uses an analog connection (multiplexed over the USB connector pins for instance) */ AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET = 0x800, AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET = 0x1000, /* USB accessory mode: your Android device is a USB device and the dock is a USB host */ AUDIO_DEVICE_OUT_USB_ACCESSORY = 0x2000, /* USB host mode: your Android device is a USB host and the dock is a USB device */ AUDIO_DEVICE_OUT_USB_DEVICE = 0x4000, AUDIO_DEVICE_OUT_REMOTE_SUBMIX = 0x8000, /* Telephony voice TX path */ AUDIO_DEVICE_OUT_TELEPHONY_TX = 0x10000, /* Analog jack with line impedance detected */ AUDIO_DEVICE_OUT_LINE = 0x20000, /* HDMI Audio Return Channel */ AUDIO_DEVICE_OUT_HDMI_ARC = 0x40000, /* S/PDIF out */ AUDIO_DEVICE_OUT_SPDIF = 0x80000, /* FM transmitter out */ AUDIO_DEVICE_OUT_FM = 0x100000, /* Line out for av devices */ AUDIO_DEVICE_OUT_AUX_LINE = 0x200000, /* limited-output speaker device for acoustic safety */ AUDIO_DEVICE_OUT_SPEAKER_SAFE = 0x400000, AUDIO_DEVICE_OUT_DEFAULT = AUDIO_DEVICE_BIT_DEFAULT, AUDIO_DEVICE_OUT_ALL = (AUDIO_DEVICE_OUT_EARPIECE | AUDIO_DEVICE_OUT_SPEAKER | AUDIO_DEVICE_OUT_WIRED_HEADSET | AUDIO_DEVICE_OUT_WIRED_HEADPHONE | AUDIO_DEVICE_OUT_BLUETOOTH_SCO | AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET | AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT | AUDIO_DEVICE_OUT_BLUETOOTH_A2DP | AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES | AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER | AUDIO_DEVICE_OUT_HDMI | AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET | AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET | AUDIO_DEVICE_OUT_USB_ACCESSORY | AUDIO_DEVICE_OUT_USB_DEVICE | AUDIO_DEVICE_OUT_REMOTE_SUBMIX | AUDIO_DEVICE_OUT_TELEPHONY_TX | AUDIO_DEVICE_OUT_LINE | AUDIO_DEVICE_OUT_HDMI_ARC | AUDIO_DEVICE_OUT_SPDIF | AUDIO_DEVICE_OUT_FM | AUDIO_DEVICE_OUT_AUX_LINE | AUDIO_DEVICE_OUT_SPEAKER_SAFE | AUDIO_DEVICE_OUT_DEFAULT), AUDIO_DEVICE_OUT_ALL_A2DP = (AUDIO_DEVICE_OUT_BLUETOOTH_A2DP | AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES | AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER), AUDIO_DEVICE_OUT_ALL_SCO = (AUDIO_DEVICE_OUT_BLUETOOTH_SCO | AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET | AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT), AUDIO_DEVICE_OUT_ALL_USB = (AUDIO_DEVICE_OUT_USB_ACCESSORY | AUDIO_DEVICE_OUT_USB_DEVICE), /* input devices */ AUDIO_DEVICE_IN_COMMUNICATION = AUDIO_DEVICE_BIT_IN | 0x1, AUDIO_DEVICE_IN_AMBIENT = AUDIO_DEVICE_BIT_IN | 0x2, AUDIO_DEVICE_IN_BUILTIN_MIC = AUDIO_DEVICE_BIT_IN | 0x4, AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET = AUDIO_DEVICE_BIT_IN | 0x8, AUDIO_DEVICE_IN_WIRED_HEADSET = AUDIO_DEVICE_BIT_IN | 0x10, AUDIO_DEVICE_IN_AUX_DIGITAL = AUDIO_DEVICE_BIT_IN | 0x20, AUDIO_DEVICE_IN_HDMI = AUDIO_DEVICE_IN_AUX_DIGITAL, /* Telephony voice RX path */ AUDIO_DEVICE_IN_VOICE_CALL = AUDIO_DEVICE_BIT_IN | 0x40, AUDIO_DEVICE_IN_TELEPHONY_RX = AUDIO_DEVICE_IN_VOICE_CALL, AUDIO_DEVICE_IN_BACK_MIC = AUDIO_DEVICE_BIT_IN | 0x80, AUDIO_DEVICE_IN_REMOTE_SUBMIX = AUDIO_DEVICE_BIT_IN | 0x100, AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET = AUDIO_DEVICE_BIT_IN | 0x200, AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET = AUDIO_DEVICE_BIT_IN | 0x400, AUDIO_DEVICE_IN_USB_ACCESSORY = AUDIO_DEVICE_BIT_IN | 0x800, AUDIO_DEVICE_IN_USB_DEVICE = AUDIO_DEVICE_BIT_IN | 0x1000, /* FM tuner input */ AUDIO_DEVICE_IN_FM_TUNER = AUDIO_DEVICE_BIT_IN | 0x2000, /* TV tuner input */ AUDIO_DEVICE_IN_TV_TUNER = AUDIO_DEVICE_BIT_IN | 0x4000, /* Analog jack with line impedance detected */ AUDIO_DEVICE_IN_LINE = AUDIO_DEVICE_BIT_IN | 0x8000, /* S/PDIF in */ AUDIO_DEVICE_IN_SPDIF = AUDIO_DEVICE_BIT_IN | 0x10000, AUDIO_DEVICE_IN_BLUETOOTH_A2DP = AUDIO_DEVICE_BIT_IN | 0x20000, AUDIO_DEVICE_IN_LOOPBACK = AUDIO_DEVICE_BIT_IN | 0x40000, AUDIO_DEVICE_IN_DEFAULT = AUDIO_DEVICE_BIT_IN | AUDIO_DEVICE_BIT_DEFAULT, AUDIO_DEVICE_IN_ALL = (AUDIO_DEVICE_IN_COMMUNICATION | AUDIO_DEVICE_IN_AMBIENT | AUDIO_DEVICE_IN_BUILTIN_MIC | AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET | AUDIO_DEVICE_IN_WIRED_HEADSET | AUDIO_DEVICE_IN_HDMI | AUDIO_DEVICE_IN_TELEPHONY_RX | AUDIO_DEVICE_IN_BACK_MIC | AUDIO_DEVICE_IN_REMOTE_SUBMIX | AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET | AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET | AUDIO_DEVICE_IN_USB_ACCESSORY | AUDIO_DEVICE_IN_USB_DEVICE | AUDIO_DEVICE_IN_FM_TUNER | AUDIO_DEVICE_IN_TV_TUNER | AUDIO_DEVICE_IN_LINE | AUDIO_DEVICE_IN_SPDIF | AUDIO_DEVICE_IN_BLUETOOTH_A2DP | AUDIO_DEVICE_IN_LOOPBACK | AUDIO_DEVICE_IN_DEFAULT), AUDIO_DEVICE_IN_ALL_SCO = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET, AUDIO_DEVICE_IN_ALL_USB = (AUDIO_DEVICE_IN_USB_ACCESSORY | AUDIO_DEVICE_IN_USB_DEVICE), }; 这样,有了音频设备库及音频配置文件,就可以确定各个音频设备支持哪些输入、输出音频了。这样当上层需要输出一个声音时,就可以根据策略层选择的输出音频设备,选择该输出音频设备对应音频设备库接口。 现在再看一下主音频设备,在主音频设备支持音频输出中,既有AUDIO_DEVICE_OUT_SPEAKER(喇叭),又有AUDIO_DEVICE_OUT_WIRED_HEADSET (有线耳机)AUDIO_DEVICE_OUT_ALL_SCO(蓝牙通话PCM),而在音频设备库中只有一个adev_open_output_stream接口,这时,就需要在adev_open_output_stream中根据实际的音频输出设备进行不同的操作了。 如下面一个例子代码: static int adev_open_output_stream(struct audio_hw_device *dev, audio_io_handle_t handle, audio_devices_t devices, audio_output_flags_t flags, struct audio_config *config, struct audio_stream_out **stream_out, const char *address __unused) { struct audio_device *adev = (struct audio_device *)dev; struct stream_out *out; int i, ret; ALOGV("%s: enter: sample_rate(%d) channel_mask(%#x) devices(%#x) flags(%#x)", __func__, config->sample_rate, config->channel_mask, devices, flags); *stream_out = NULL; out = (struct stream_out *)calloc(1, sizeof(struct stream_out)); if (devices == AUDIO_DEVICE_NONE) devices = AUDIO_DEVICE_OUT_SPEAKER; out->flags = flags; out->devices = devices; out->dev = adev; out->format = config->format; out->sample_rate = config->sample_rate; out->channel_mask = AUDIO_CHANNEL_OUT_STEREO; out->supported_channel_masks[0] = AUDIO_CHANNEL_OUT_STEREO; out->handle = handle; /* Init use case and pcm_config */ if (out->devices & AUDIO_DEVICE_OUT_SPEAKER) { /* AUDIO_DEVICE_OUT_SPEAKER(喇叭输出时处理) */ /* 省略代码 */ } else if (out->devices & AUDIO_DEVICE_OUT_WIRED_HEADSET) { /* AUDIO_DEVICE_OUT_WIRED_HEADSET (有线耳机输出时处理) */ /* 省略代码 */ } else if (out->devices & AUDIO_DEVICE_OUT_ALL_SCO) { /* AUDIO_DEVICE_OUT_ALL_SCO (蓝牙PCM输出时处理) */ /* 省略代码 */ } else { /* 省略代码 */ }


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3