如下图为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.henum {    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 {       /*  省略代码 */    }

更多相关文章

  1. Android音频流程一(JNI部分)
  2. android-音频
  3. Android音频子系统源码分析之AudioTrack的使用
  4. Android音频开发(6):使用 OpenSL ES API(上)
  5. stream audio on android 音频流 android
  6. Android MediaMuxer混合音频和视频
  7. Android MTK 修改默认音频和声音大小
  8. android 实现音频分享功能
  9. Android 4.0原生SDK发布,引入新的流式音频API

随机推荐

  1. Java 中的构造函数引用和方法引用
  2. 深入typeclass_Haskell笔记4
  3. 【Java】留下没有基础眼泪的面试题
  4. 类型_Haskell笔记3
  5. 使用 IntelliJ 调试 Java Streams
  6. 六一儿童节,送你一个F字符串
  7. 每周 10 道 Java 面试题:集合类
  8. 学习linux的第5天
  9. 如何使用maven 轻松重构项目
  10. iPhone要降价?巨头战争很激烈