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服務進行解析一下,現在發現還有很多內容不是特別理解,這個課題留在后面進行解決。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM