嵌入式音频USB Audio调试

驱动适配

1. 配置USB控制器为otg或者host

bash 复制代码
&usb_otg0 {
        dr_mode = "otg";                                                                                       
        vbus-supply = <&vbus_regulator0>;
        status = "okay";
};

编译系统,插入设备查看设备状态:

bash 复制代码
[   35.196082] usb 1-1: new full-speed USB device number 2 using dwc2
[   35.441393] input: C-Media Electronics Inc. AD2000 as /devices/platform/soc/11c0000.usb/usb1/1-1/1-1:1.0/0003:0D8C:033D.0001/input/input0
[   35.516342] hid-generic 0003:0D8C:033D.0001: input,hidraw0: USB HID v1.10 Device [C-Media Electronics Inc. AD2000] on usb-11c0000.usb-1/input0
[   37.556148] usb 1-1: USB disconnect, device number 2
[   38.046082] usb 1-1: new full-speed USB device number 3 using dwc2
[   38.291123] input: C-Media Electronics Inc. AD2000 as /devices/platform/soc/11c0000.usb/usb1/1-1/1-1:1.0/0003:0D8C:033D.0002/input/input1
[   38.367191] hid-generic 0003:0D8C:033D.0002: input,hidraw0: USB HID v1.10 Device [C-Media Electronics Inc. AD2000] on usb-11c0000.usb-1/input0
~ # lsusb 
Bus 003 Device 001: ID 1d6b:0002
Bus 002 Device 002: ID 0483:5740
Bus 001 Device 001: ID 1d6b:0002
Bus 001 Device 003: ID 0d8c:033d
Bus 002 Device 001: ID 1d6b:0002
~ # cat /proc/asound/
cards    devices  pcm      timers   version
~ # cat /proc/asound/cards 
--- no soundcards ---
~ # cat /proc/asound/pcm 

由此可见 usb设备已经识别到了,但是还不是uac设备

2. 配置添加uac设备驱动

bash 复制代码
make  ARCH=arm64 CROSS_COMPILE=/opt/toolchain/7.5.0/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu- menuconfig
bash 复制代码
 Device Drivers  --->                                                             
 	<*> Sound card support  --->
	 <*>   Advanced Linux Sound Architecture  --->
	   [*]   USB sound devices  --->
	      <*>   USB Audio/MIDI driver

或者直接添加在defconfig文件中

bash 复制代码
CONFIG_SND_USB_AUDIO=y
CONFIG_SND_RAWMIDI=y
CONFIG_SND_HWDEP=y

软件库交叉编译

1. 下载源代码(切换至 v1.2.3 标签)

alsa-lib
alsa-utils

bash 复制代码
alsa-lib$ git branch 
* (头指针分离于 v1.2.3)
  master

alsa-utils$ git branch 
* (头指针分离于 v1.2.3)
  master

2. 编译alsa-lib

生成configure文件

bash 复制代码
touch ltconfig
libtoolize --force --copy --automake
aclocal $ACLOCAL_FLAGS
autoheader
automake --foreign --copy --add-missing
touch depcomp           # seems to be missing for old automake
autoconf

配置生成makefile文件

bash 复制代码
./configure --host=aarch64-linux-gnu   --disable-python

编译并安装

bash 复制代码
make -j4
make DESTDIR=/home/xxx/git/asound/test/alsa-lib/install install

编译alsa-utils

拷贝alsa.m4文件

bash 复制代码
cp ../alsa-lib/utils/alsa.m4 m4/

生成configure Makefile 文件,并编译

bash 复制代码
#!/bin/bash

if test -d ../alsa-lib/utils && ! test -r `aclocal --print-ac-dir`/alsa.m4; then
  alsa_m4_flags="-I ../alsa-lib/utils"
fi
aclocal $alsa_m4_flags $ACLOCAL_FLAGS
# save original files to avoid stupid modifications by gettextize
cp Makefile.am Makefile.am.ok
cp configure.ac configure.ac.ok
gettextize -c -f --no-changelog
echo "EXTRA_DIST = gettext.m4" > m4/Makefile.am
cp Makefile.am.ok Makefile.am
cp configure.ac.ok configure.ac
autoheader
automake --foreign --copy --add-missing
touch depcomp           # for older automake
autoconf
export LDFLAGS="-L/home/tuning/git/asound/alsa-lib/install/lib"                                               export CFLAGS="-I/home/tuning/git/asound/alsa-lib/install/include"
export PKG_CONFIG_PATH=/home/tuning/git/asound/alsa-lib/install/lib/pkgconfig:$PKG_CONFIG_PATH
export ACLOCAL_FLAGS="-I /home/tuning/git/asound/alsa-lib/utils"
./configure --host=aarch64-linux-gnu     --prefix=/home/tuning/git/asound/alsa-lib/install/     --disable-alsamixer     --disable-xmlto
make    

安装

bash 复制代码
sudo make install

至此所有的工具和库都在alsa-lib/install 文件中了。

运行时添加下路径:

bash 复制代码
export LD_LIBRARY_PATH=/home/xxx/git/asound/alsa-lib/install/lib:$LD_LIBRARY_PATH

音频设备调试

其中涉及到一些专业知识和名词,针对调试中遇到的一些参数进行说明。

  1. aplay -l
bash 复制代码
# aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: AD2000 [AD2000], device 0: USB Audio [USB Audio]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
  • card 0: AD2000 [AD2000]

    card 0: 第一个声卡,编号为0

    AD2000: 声卡名称,一个 USB 音频设备

  • device 0: 该声卡上的第一个设备,编号为0

    USB Audio: 设备名称,表明是通过 USB 连接的音频设备

  • Subdevices: 1/1

    该设备有 1个子设备,总共也是1个可用

  • Subdevice #0: subdevice #0

    子设备编号 #0,这是唯一可用的子设备

  1. arecord -D hw:0,0 --dump-hw-params
bash 复制代码
 # arecord -D hw:0,0 --dump-hw-params
Recording WAVE 'stdin' : Unsigned 8 bit, Rate 8000 Hz, Mono
HW Params of device "hw:0,0":
--------------------
ACCESS:  MMAP_INTERLEAVED RW_INTERLEAVED
FORMAT:  S24_3LE
SUBFORMAT:  STD
SAMPLE_BITS: 24
FRAME_BITS: 24
CHANNELS: 1
RATE: 48000
PERIOD_TIME: [1000 3640875]
PERIOD_SIZE: [48 174762]
PERIOD_BYTES: [144 524286]
PERIODS: [2 1024]
BUFFER_TIME: [2000 7281771)
BUFFER_SIZE: [96 349525]
BUFFER_BYTES: [288 1048575]
TICK_TIME: ALL
--------------------
arecord: set_params:1343: Sample format non available
Available formats:
 - S24_3LE
  • 格式: 只支持 S24_3LE
    采样率: 固定 48000 Hz
    声道: 只支持 1 个声道(单声道)
    精度: 24位,3字节存储
  1. ./arecord -D plughw:0,0 -f S24_3LE -r 48000 -c 1 -d 5 corrected_test.wav
bash 复制代码
 # ./arecord -D plughw:0,0 -f S24_3LE -r 48000 -c 1 -d 5 corrected_test.wav
Recording WAVE 'corrected_test.wav' : Signed 24 bit Little Endian in 3bytes, Rate 48000 Hz, Mono
[10227.244626] dwc2 11c0000.usb: dwc2_hc_halt() Channel can't be halted
  • -D plughw:0,0
    使用 ALSA 插件系统,自动进行格式转换。0,0:第一个声卡(card 0)的第一个设备(device 0)
    plughw 会在应用程序和硬件之间插入转换层,如果应用程序请求的格式与硬件不匹配,会自动转换。比如:16bit → 24bit,44100Hz → 48000Hz 等
  • -f S24_3LE
    S24:有符号 24 位,3LE:3字节小端序(Little Endian)
  • -r 48000
    每秒采集 48000 个样本,人耳能听到的频率范围:20Hz - 20,000Hz。根据奈奎斯特定理,48000Hz 能完美录制 0-24,000Hz 的音频,这是专业音频和视频的常用采样率。
  • -c 1
    单声道录音,您的设备硬件只支持单声道输入。如果设为 -c 2(立体声),plughw 会自动复制单声道数据到两个声道
  • -d 5
    录制 5 秒后自动停止
    计算公式:
c 复制代码
# 计算 5 秒录音的数据量
位深度:24 bit = 3 字节/样本
采样率:48000 样本/秒
声道数:1 声道
时长:5 秒

数据量 = 3 字节 × 48000 × 1 × 5 = 720,000 字节 ≈ 703 KB
加上 WAV 文件头:约 704 KB
  1. ./aplay -D plughw:0,0 Front_Center.wav
bash 复制代码
# ./aplay -D plughw:0,0 Front_Cente
r.wav 
Playing WAVE 'Front_Center.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Mono
[10950.431463] dwc2 11c0000.usb: dwc2_hc_halt() Channel can't be halted
  • Mono代表是单声道,Signed 16 bit Little Endian表示这个wav的格式

常见的预设格式:

CD 质量(最常用)

-f cd # S16_LE, 44100Hz, 立体声

DAT 质量

-f dat # S16_LE, 48000Hz, 立体声

DVD 质量

-f dv # S16_LE, 96000Hz, 立体声

电话质量

-f phone # U8, 8000Hz, 单声道

合成立体声

1. 在ubuntu系统找两个文件Side_Left.wav Side_Right.wav

查看音频信息:

bash 复制代码
$ soxi Side_Right.wav

Input File     : 'Side_Right.wav'
Channels       : 1
Sample Rate    : 48000
Precision      : 16-bit
Duration       : 00:00:01.35 = 64961 samples ~ 101.502 CDDA sectors
File Size      : 130k
Bit Rate       : 768k
Sample Encoding: 16-bit Signed Integer PCM

2. 获取两个音频时长

bash 复制代码
# 获取两个文件的时长
DUR1=$(soxi -D Side_Left.wav)
DUR2=$(soxi -D Side_Right.wav)

# 创建静音文件
sox -n -r 48000 -c 1 silence1.wav trim 0.0 $DUR2
sox -n -r 48000 -c 1 silence2.wav trim 0.0 $DUR1

3. 产生等时长的静音音频文件

bash 复制代码
sox Side_Left.wav silence1.wav left_final.wav
sox silence2.wav Side_Right.wav right_final.wav

4. 合并两个音频文件

bash 复制代码
sox -M left_final.wav right_final.wav stereo_output.wav

5. 如果需要拆开进行验证

bash 复制代码
sox stereo_output.wav left_check.wav remix 1
sox stereo_output.wav right_check.wav remix 2
soxi -D left_check.wav right_check.wav stereo_output.wav

验证了一个事情: 单声道音频文件是不区分左右喇叭的,也就是播放单声道音频文件时,两个喇叭都会响。 立体声音频才区分,如果只想要其中一个喇叭响,那么必须合成立体声音频文件,一个通道为静音,另一个为正常声音。


音频驱动验证:

第一步查看USB驱动,能不能正确识别USB设备:

bash 复制代码
 # lsusb 
Bus 003 Device 001: ID 1d6b:0002
Bus 002 Device 002: ID 0483:5740
Bus 001 Device 001: ID 1d6b:0002
Bus 001 Device 009: ID 0d8c:033d
Bus 002 Device 001: ID 1d6b:0002

第二步判断UAC驱动有没有正确识别呢?

拔插设备内核打印如下:

bash 复制代码
# dmesg | grep -i audio
[    1.178052] usbcore: registered new interface driver snd-usb-audio
bash 复制代码
[11495.556303] usb 1-1: USB disconnect, device number 9
[11499.216233] usb 1-1: new full-speed USB device number 10 using dwc2
[11499.461364] input: C-Media Electronics Inc. AD2000 as /devices/platform/soc/11c0000.usb/usb1/1-1/1-1:1.0/0003:0D8C:033D.0009/input/input8
[11499.536472] hid-generic 0003:0D8C:033D.0009: input,hidraw0: USB HID v1.10 Device [C-Media Electronics Inc. AD2000] on usb-11c0000.usb-1/input0
[11501.556298] usb 1-1: USB disconnect, device number 10
[11502.046234] usb 1-1: new full-speed USB device number 11 using dwc2
[11502.291410] input: C-Media Electronics Inc. AD2000 as /devices/platform/soc/11c0000.usb/usb1/1-1/1-1:1.0/0003:0D8C:033D.000A/input/input9
[11502.366485] hid-generic 0003:0D8C:033D.000A: input,hidraw0: USB HID v1.10 Device [C-Media Electronics Inc. AD2000] on usb-11c0000.usb-1/input0

第三步 查看识别到的设备信息

bash 复制代码
# cat /proc/asound/AD2000/pcm0c/inf
o 
card: 0
device: 0
subdevice: 0
stream: CAPTURE
id: USB Audio
name: USB Audio
subname: subdevice #0
class: 0
subclass: 0
subdevices_count: 1
subdevices_avail: 1
# cat /proc/asound/AD2000/pcm0p/inf
o 
card: 0
device: 0
subdevice: 0
stream: PLAYBACK
id: USB Audio
name: USB Audio
subname: subdevice #0
class: 0
subclass: 0
subdevices_count: 1
subdevices_avail: 1
bash 复制代码
# cat /proc/asound/cards
 0 [AD2000         ]: USB-Audio - AD2000
                      C-Media Electronics Inc. AD2000 at usb-11c0000.usb-1, full speed
bash 复制代码
# cat /proc/asound/pcm 
00-00: USB Audio : USB Audio : playback 1 : capture 1

USB相关知识:

bash 复制代码
ab@zsf:~$ lsusb 
Bus 006 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 005 Device 005: ID 0bda:4852 Realtek Semiconductor Corp. 
Bus 005 Device 003: ID 27c6:6594  
Bus 005 Device 008: ID 0d8c:033d C-Media Electronics, Inc. 
Bus 005 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 003 Device 002: ID 046d:c534 Logitech, Inc. Unifying Receiver
Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 002: ID 13d3:5439 IMC Networks 
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
ab@zsf:~$ lsusb -t
/:  Bus 06.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/2p, 10000M
/:  Bus 05.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/4p, 480M
    |__ Port 2: Dev 8, If 2, Class=Audio, Driver=snd-usb-audio, 12M
    |__ Port 2: Dev 8, If 0, Class=Human Interface Device, Driver=usbhid, 12M
    |__ Port 2: Dev 8, If 3, Class=Audio, Driver=snd-usb-audio, 12M
    |__ Port 2: Dev 8, If 1, Class=Audio, Driver=snd-usb-audio, 12M
    |__ Port 3: Dev 3, If 0, Class=Vendor Specific Class, Driver=, 12M
    |__ Port 4: Dev 5, If 1, Class=Wireless, Driver=btusb, 12M
    |__ Port 4: Dev 5, If 0, Class=Wireless, Driver=btusb, 12M
/:  Bus 04.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/2p, 10000M
/:  Bus 03.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/4p, 480M
    |__ Port 2: Dev 2, If 0, Class=Human Interface Device, Driver=usbhid, 12M
    |__ Port 2: Dev 2, If 1, Class=Human Interface Device, Driver=usbhid, 12M
/:  Bus 02.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/2p, 5000M
/:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/2p, 480M
    |__ Port 2: Dev 2, If 0, Class=Video, Driver=uvcvideo, 480M
    |__ Port 2: Dev 2, If 1, Class=Video, Driver=uvcvideo, 480M

Bus 05.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/4p, 480M

  • Bus 05: 第5个USB总线
  • Port 1: 根集线器的第1个端口
  • Dev 1: 设备号1(通常是主机控制器)
  • Driver=xhci_hcd: 使用xhci驱动(USB 3.0控制器)
  • 480M: 该总线最高支持USB 2.0速度(480 Mbps)

Port 2: Dev 8, If 2, Class=Audio, Driver=snd-usb-audio, 12M

  • Port 2 - 物理端口, 这是主机或USB集线器上的物理插槽编号,表示这个设备插在您电脑的第2个USB物理端口上,是硬件层面的连接点
  • Dev 8 - 设备地址,这是USB系统分配给该设备的逻辑地址(8号设备),当设备插入时,主机给它分配一个唯一的编号用于通信,这个编号在每次重新插拔后可能会变化,是软件层面的标识
  • If 2 - 接口编号,这是最关键的概念:If = Interface(接口),一个USB设备可以有多个独立的功能,每个功能就是一个Interface,If 2 表示这是该设备的第3个功能接口(从0开始计数)

这个 Dev 8 设备有4个Interface:

If 0: HID(人机交互设备)- 可能是音量控制按钮

复制代码
If 1: 音频接口 - 可能是音频流传输
If 2: 音频接口 - 可能是另一个音频通道
If 3: 音频接口 - 可能是麦克风输入

每个bus对应一个usb控制器

相关推荐
代码狂想家1 小时前
CANN视频增强实战:基于Ascend平台的历史影像修复
音视频
Predestination王瀞潞2 小时前
Cuda的安装
linux·人工智能·深度学习
石像鬼₧魂石2 小时前
如何使用Kali Linux自带字典进行密码破解?
linux·运维·服务器
JiMoKuangXiangQu2 小时前
Linux 时间子系统 (1):基础框架概述
linux·timer·时间子系统·timekeeping
天选之女wow2 小时前
【Hard——Day8】65.有效数字、68.文本左右对齐、76.最小覆盖子串
linux·运维·redis·算法·leetcode
精英的英3 小时前
【嵌入式Linux开发】如何在Windows上开发Linux ARM版本QT程序
linux·arm开发·windows
咯哦哦哦哦3 小时前
linux patchelf工具 用法
linux·vscode·编辑器·gcc
努力的小帅3 小时前
Linux_进程控制(Linux入门到精通)
linux·网络·shell·进程创建·linux入门
睡觉然后上课3 小时前
如何让虚拟机运行速度翻倍
linux·arm开发·windows