zoukankan      html  css  js  c++  java
  • Android USB 外置声卡插入Audio系统没有正常识别问题梳理以及分析

    背景:

    现在项目要求实现一个,要使用NDK接口从外接MIC设备(姑且这么称呼吧)上采集声音数据,然后内部进行音频数据格式转换,再进行音频数据输出;

    问题:

    插入客户指定设备,发现在JAVA AudioManager无法查询到新接入到的物理设备;(当使用NDK进行音频数据采集,需要进行deviceId参数;在JAVA侧可以通过audioManager获取指定类型设备的deviceId)

    NDK接口参照:

    https://developer.android.google.cn/ndk/reference/group/audio

    使用NDK接口音频采集过程,可以参照:

    https://developer.android.google.cn/ndk/guides/audio/aaudio/aaudio

    现象以及问题分析:

    在Java AudioManager层使用sdk api无法查询到指定类型设备ID,这就说明新插入的设备没有被andriod 系统audioManager进行正确识别或添加,于是从下到上进行问题分析;

    知识背景:

    在Android系统中整个audio一共分析如下几层:

    1、物理层(开发板以及外接MIC物理设备)

    2、设备驱动层(集成在kernal中)

    3、UsbSever服务(由于外接MIC是通过USB接口与开发板进行连接)

    4、android AudioManager等Audio服务

    问题排查顺序:

    1、当物理设备没有被android 的Audio系统识别,首先排查android系统有没有正确识别到USB声卡插入。

    android Audio HAL一般都使用alsa。是android内核中的驱动识别到了声卡物理设备接入之后,驱动程序会自动在/pro/asound 目录下创建一个目录,表明有新的物理声卡接入;

    ls /proc/asound/
    card0 cards devices hwdep modules oss PCH pcm seq timers version

    然后可以通过查询devices文件中的内容,来了解物理声卡的能力;

    cat /proc/asound/devices
    1: : sequencer
    2: [ 0] : control
    3: [ 0- 0]: digital audio playback
    4: [ 0- 0]: digital audio capture
    5: [ 0- 2]: digital audio capture
    6: [ 0- 3]: digital audio playback
    7: [ 0- 7]: digital audio playback
    8: [ 0- 8]: digital audio playback
    9: [ 0- 9]: digital audio playback
    10: [ 0-10]: digital audio playback
    11: [ 0- 0]: hardware dependent
    12: [ 0- 2]: hardware dependent
    33: : timer

    以上信息为card0的信息;

    2、根据devices中的信息了解物理设备的能力;(是声音采集设备?是声音播放设备?)

    126: [ 1] : control
    127: [ 1- 0]: digital audio capture

    这是我新插入的audio 设备信息(只有控制接口以及声音采集接口),这就证明我这只是一个音频采集设备并不具备音频播放功能;

    3、当/proc/asound/devices 目录下有新的文件夹创建之后。

    UsbSever服务中的UsbAlsaManager就会自动识别到有新的设备插入,通过文件夹的名称来识别插入的是哪种设备,是一个声卡设备还是PCM设备。

    然后通过devices文件中的信息了解设备的能力;然后根据设备能力生成一个usb Audio设备添加内部进行管理;

    未识别时的devices信息:

    126: [ 1] : control

    发生未设备时的LOG如下:

    UsbAlsaManager: Adding ALSA device AlsaDevice:

    UsbAlsaManager: USB Audio Device Added: UsbAudioDevice: [card: 1, device: 0, name: USB-Audio - TA-2, hasPlayback: false, hasCapture: false, class: 0x80000002]

    识别时的devices信息:

    126: [ 1] : control
    127: [ 1- 0]: digital audio capture

    正确识别的LOG信息如下:

    UsbAlsaManager: Adding ALSA device AlsaDevice:

    UsbAlsaManager: USB Audio Device Added: UsbAudioDevice: [card: 1, device: 0, name: USB-Audio - TA-2, hasPlayback: false, hasCapture: true, class: 0x80000002]

    AudioPolicyManagerCustom: setDeviceConnectionStateInt() device: 0x80001000, state 1, address card=1;device=0; name USB-Audio - TA-2

    4、当出现AudioPolicyManagerCustom: setDeviceConnectionStateInt()之后,再使用Java AudioManager就可以正确获取指定类型音频输入设备;

    流程总结:

    正确的USB声卡设备插入流程大致如下:

    1、驱动设备到新的声卡设备插入,并在在proc/asound/目录下创建新的文件夹,并将设备能力写入devices文件中

    2、UsbServer发现在proc/asound/目录下有新的文件夹创建,则对新的文件夹以及设备信息进行获取解析。

    3、通过新获取的信息则,创建usb上层设备抽象。如果是音频设备,并且是(采集或者播放设备),则将新的设备信息通过AudioManager接口添加到android音频系统;

    4、当andriod 系统更新内部设备信息之后,根据audio policy信息重新进行route配置。从而触发音频通路的重新选择。

    问题总结:

    无论设备发现过程以及设备能力怎样。对于Andrioid audio系统添加新设备的主要流程就是调用setDeviceConnectionState();

    如果发现新设备没有被系统所识别:

    先检查设备驱动识别正确识别到新的设备;

    然后调查这种类型设备的发现机制,是通过uevent识别到的,还是像这种文件夹改变而发现的。

    再而检查新设备的设备能力是否与我们设想一致。因为audio系统中所管理的设备要具备音频采集或者播放功能;(混音器没遇到过,所以这部分信息不知道)

    最后看audio设备添加是否正常被执行;

    如果,新假如设备后,音频通路不正常,则就对policy配置进行检查。

    本来想顺着代码将usbserver服务进行解析一下,现在发现还有很多内容不是特别理解,这个课题留在后面进行解决。

  • 相关阅读:
    批处理(*.bat)文件 -> 命令
    设置柱状图:每项颜色不一样
    回到顶部 插件 遇到的一点小问题
    body的滚动事件的坑
    文章标题
    window.open()打开的新窗口被拦截的原因分析和解决方案
    常用正则表达式
    代码整洁之道,clean code
    表单序列化,获取Json对象
    利用聚合函数来去重
  • 原文地址:https://www.cnblogs.com/ouyshy/p/13555510.html
Copyright © 2011-2022 走看看