AndroidUSB外置声卡插⼊Audio系统没有正常识别问题梳理以
及分析
背景:
现在项⽬要求实现⼀个,要使⽤NDK接⼝从外接MIC设备(姑且这么称呼吧)上采集声⾳数据,然后内部进⾏⾳频数据格式转换,再进⾏⾳频数据输出;
问题:
插⼊客户指定设备,发现在JAVA AudioManager⽆法查询到新接⼊到的物理设备;(当使⽤NDK进⾏⾳频数据采集,需要进⾏deviceId参数;在JAVA侧可以通过audioManager获取指定类型设备的deviceId)
NDK接⼝参照:
使⽤NDK接⼝⾳频采集过程,可以参照:
现象以及问题分析:
在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唐立淇6月运势
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服务进⾏解析⼀下,现在发现还有很多内容不是特别理解,这个课题留在后⾯进⾏解决。
发布评论