linux uac 设备,USB Audio Class (UAC) 分析

2023-05-16

一个UAC设备插入到Ubuntu 14.04电脑上dmesg中打印的信息如下:

[ 2367.490491] usb 3-3.2: new full-speed USB device number 9 using xhci_hcd

[ 2367.580010] usb 3-3.2: New USB device found, idVendor=0d8c, idProduct=0132

[ 2367.580018] usb 3-3.2: New USB device strings: Mfr=1, Product=2, SerialNumber=0

[ 2367.580023] usb 3-3.2: Product: USB PnP Audio Device

[ 2367.580027] usb 3-3.2: Manufacturer: C-Media Electronics Inc.

[ 2367.581679] input: C-Media Electronics Inc. USB PnP Audio Device as /devices/pci0000:00/0000:00:14.0/usb3/3-3/3-3.2/3-3.2:1.2/0003:0D8C:0132.0004/input/input18

[ 2367.581999] hid-generic 0003:0D8C:0132.0004: input,hidraw3: USB HID v1.11 Device [C-Media Electronics Inc. USB PnP Audio Device] on usb-0000:00:14.0-3.2/input2

[ 2367.913280] usbcore: registered new interface driver snd-usb-audio

这里可以看到其驱动程序为snd-usb-audio,依据这个关键词在内核中查找到如下内容:

tony@tony-E431:~/linux-3.4.y$grep "registered new interface driver" ./ -rn

Binary file ./vmlinux.o matches

Binary file ./.tmp_vmlinux1 matches

Binary file ./.tmp_vmlinux2 matches

Binary file ./drivers/built-in.o matches

Binary file ./drivers/usb/built-in.o matches

Binary file ./drivers/usb/core/built-in.o matches

./drivers/usb/core/driver.c:865: pr_info("%s: registered new interface driver %s\n",

Binary file ./drivers/usb/core/driver.o matches

Binary file ./drivers/usb/core/usbcore.o matches

Binary file ./arch/arm/boot/Image matches

Binary file ./vmlinux matches

tony@tony-E431:~/linux-3.4.y$

以及

// file: linux-3.4.y/sound/usb/card.c

/* * entry point for linux usb interface */

static struct usb_driver usb_audio_driver = {

.name = "snd-usb-audio",

.probe = usb_audio_probe,

.disconnect = usb_audio_disconnect,

.suspend = usb_audio_suspend,

.resume = usb_audio_resume,

.id_table = usb_audio_ids,

.supports_autosuspend = 1,

};

根据probe方法snd_usb_audio_probe调用了snd_usb_apply_boot_quirk和snd_card_register,查到了

// linux-3.4.y/sound/usb/card.c

/* * new 2.5 USB kernel API */

static int usb_audio_probe(struct usb_interface *intf,

const struct usb_device_id *id)

{

struct snd_usb_audio *chip;

chip = snd_usb_audio_probe(interface_to_usbdev(intf), intf, id);

if (chip) {

usb_set_intfdata(intf, chip);

return 0;

} else

return -EIO;

}

// linux-3.4.y/sound/usb/quirks.c

int snd_usb_apply_boot_quirk(struct usb_device *dev,

struct usb_interface *intf,

const struct snd_usb_audio_quirk *quirk)

{

u32 id = USB_ID(le16_to_cpu(dev->descriptor.idVendor),

le16_to_cpu(dev->descriptor.idProduct));

switch (id) {

case USB_ID(0x041e, 0x3000):

/* SB Extigy needs special boot-up sequence */

/* if more models come, this will go to the quirk list. */

return snd_usb_extigy_boot_quirk(dev, intf);

case USB_ID(0x041e, 0x3020):

/* SB Audigy 2 NX needs its own boot-up magic, too */

return snd_usb_audigy2nx_boot_quirk(dev);

case USB_ID(0x10f5, 0x0200):

/* C-Media CM106 / Turtle Beach Audio Advantage Roadie */

return snd_usb_cm106_boot_quirk(dev);

case USB_ID(0x0d8c, 0x0102):

/* C-Media CM6206 / CM106-Like Sound Device */

case USB_ID(0x0ccd, 0x00b1): /* Terratec Aureon 7.1 USB */

return snd_usb_cm6206_boot_quirk(dev);

case USB_ID(0x133e, 0x0815):

/* Access Music VirusTI Desktop */

return snd_usb_accessmusic_boot_quirk(dev);

case USB_ID(0x17cc, 0x1000): /* Komplete Audio 6 */

case USB_ID(0x17cc, 0x1010): /* Traktor Audio 6 */

case USB_ID(0x17cc, 0x1020): /* Traktor Audio 10 */

return snd_usb_nativeinstruments_boot_quirk(dev);

case USB_ID(0x0763, 0x2012): /* M-Audio Fast Track Pro USB */

return snd_usb_fasttrackpro_boot_quirk(dev);

}

return 0;

}

snd_usb_audio_probe

/* * probe the active usb device * * note that this can be called multiple times per a device, when it * includes multiple audio control interfaces. * * thus we check the usb device pointer and creates the card instance * only at the first time. the successive calls of this function will * append the pcm interface to the corresponding card. */

static struct snd_usb_audio *

snd_usb_audio_probe(struct usb_device *dev,

struct usb_interface *intf,

const struct usb_device_id *usb_id)

{

const struct snd_usb_audio_quirk *quirk = (const struct snd_usb_audio_quirk *)usb_id->driver_info;

int i, err;

struct snd_usb_audio *chip;

struct usb_host_interface *alts;

int ifnum;

u32 id;

alts = &intf->altsetting[0];

ifnum = get_iface_desc(alts)->bInterfaceNumber;

id = USB_ID(le16_to_cpu(dev->descriptor.idVendor),

le16_to_cpu(dev->descriptor.idProduct));

if (quirk && quirk->ifnum >= 0 && ifnum != quirk->ifnum)

goto __err_val;

if (snd_usb_apply_boot_quirk(dev, intf, quirk) < 0)

goto __err_val;

/* * found a config. now register to ALSA */

/* check whether it's already registered */

chip = NULL;

mutex_lock(&register_mutex);

for (i = 0; i < SNDRV_CARDS; i++) {

if (usb_chip[i] && usb_chip[i]->dev == dev) {

if (usb_chip[i]->shutdown) {

snd_printk(KERN_ERR "USB device is in the shutdown state, cannot create a card instance\n");

goto __error;

}

chip = usb_chip[i];

chip->probing = 1;

break;

}

}

if (! chip) {

/* it's a fresh one. * now look for an empty slot and create a new card instance */

for (i = 0; i < SNDRV_CARDS; i++)

if (enable[i] && ! usb_chip[i] &&

(vid[i] == -1 || vid[i] == USB_ID_VENDOR(id)) &&

(pid[i] == -1 || pid[i] == USB_ID_PRODUCT(id))) {

if (snd_usb_audio_create(dev, i, quirk, &chip) < 0) {

goto __error;

}

snd_card_set_dev(chip->card, &intf->dev);

chip->pm_intf = intf;

break;

}

if (!chip) {

printk(KERN_ERR "no available usb audio device\n");

goto __error;

}

}

/* * For devices with more than one control interface, we assume the * first contains the audio controls. We might need a more specific * check here in the future. */

if (!chip->ctrl_intf)

chip->ctrl_intf = alts;

chip->txfr_quirk = 0;

err = 1; /* continue */

if (quirk && quirk->ifnum != QUIRK_NO_INTERFACE) {

/* need some special handlings */

if ((err = snd_usb_create_quirk(chip, intf, &usb_audio_driver, quirk)) < 0)

goto __error;

}

if (err > 0) {

/* create normal USB audio interfaces */

if (snd_usb_create_streams(chip, ifnum) < 0 ||

snd_usb_create_mixer(chip, ifnum, ignore_ctl_error) < 0) {

goto __error;

}

}

/* we are allowed to call snd_card_register() many times */

if (snd_card_register(chip->card) < 0) {

goto __error;

}

usb_chip[chip->index] = chip;

chip->num_interfaces++;

chip->probing = 0;

mutex_unlock(&register_mutex);

return chip;

__error:

if (chip) {

if (!chip->num_interfaces)

snd_card_free(chip->card);

chip->probing = 0;

}

mutex_unlock(&register_mutex);

__err_val:

return NULL;

}

probe依次调用了:

snd_usb_apply_boot_quirk

snd_usb_audio_create

snd_usb_create_quirk

snd_usb_create_streams

snd_usb_create_stream

snd_usb_parse_audio_interface 这里根据usb的信息解析成pcm参数(如声道数量,采样率等等)

snd_usb_create_mixer

snd_card_register

// linux-3.4.y/sound/core/init.c

snd_card_register调用了init_info_for_card以及snd_device_register_all。

打开DEBUG后

<6>[ 58.704000] usb 1-1.1: new full-speed USB device number 5 using nxp-ehci

<6>[ 58.804000] usb 1-1.1: New USB device found, idVendor=0d8c, idProduct=0132

<6>[ 58.812000] usb 1-1.1: New USB device strings: Mfr=1, Product=2, SerialNumber=0

<6>[ 58.820000] usb 1-1.1: Product: USB PnP Audio Device

<6>[ 58.824000] usb 1-1.1: Manufacturer: C-Media Electronics Inc.

<6>[ 58.832000] ALSA sound/usb/stream.c:438 5:1:1: add audio endpoint 0x82

<6>[ 58.840000] ALSA sound/usb/stream.c:438 5:1:2: add audio endpoint 0x82

<6>[ 58.848000] ALSA sound/usb/mixer.c:1214 [10] FU [Mic Capture Switch] ch = 1, val = 0/1/1

<3>[ 58.856000] ALSA sound/usb/mixer.c:868 10:0: cannot get min/max values for control 2 (id 10)

<6>[ 58.864000] ALSA sound/usb/mixer.c:1214 [10] FU [Mic Capture Volume] ch = 2, val = 0/1/1

<3>[ 58.876000] ALSA sound/usb/mixer.c:868 10:0: cannot get min/max values for control 2 (id 10)

<6>[ 58.884000] input: C-Media Electronics Inc. USB PnP Audio Device as /devices/platform/nxp-ehci/usb1/1-1/1-1.1/1-1.1:1.2/input/input6

<6>[ 58.896000] generic-usb 0003:0D8C:0132.0003: input,hidraw0: USB HID v1.11 Device [C-Media Electronics Inc. USB PnP Audio Device] on usb-nxp-ehci-1.1/input2

Bus 003 Device 019: ID 0d8c:0132 C-Media Electronics, Inc.

Device Descriptor:

bLength 18

bDescriptorType 1

bcdUSB 1.10

bDeviceClass 0 (Defined at Interface level)

bDeviceSubClass 0

bDeviceProtocol 0

bMaxPacketSize0 16

idVendor 0x0d8c C-Media Electronics, Inc.

idProduct 0x0132

bcdDevice 1.00

iManufacturer 1 C-Media Electronics Inc.

iProduct 2 USB PnP Audio Device

iSerial 0

bNumConfigurations 1

Configuration Descriptor:

bLength 9

bDescriptorType 2

wTotalLength 221

bNumInterfaces 3

bConfigurationValue 1

iConfiguration 0

bmAttributes 0x80

(Bus Powered)

MaxPower 100mA

Interface Descriptor:

bLength 9

bDescriptorType 4

bInterfaceNumber 0

bAlternateSetting 0

bNumEndpoints 0

bInterfaceClass 1 Audio

bInterfaceSubClass 1 Control Device

bInterfaceProtocol 0

iInterface 0

AudioControl Interface Descriptor:

bLength 9

bDescriptorType 36

bDescriptorSubtype 1 (HEADER)

bcdADC 1.00

wTotalLength 47

bInCollection 1

baInterfaceNr( 0) 1

AudioControl Interface Descriptor:

bLength 12

bDescriptorType 36

bDescriptorSubtype 2 (INPUT_TERMINAL)

bTerminalID 2

wTerminalType 0x0201 Microphone

bAssocTerminal 0

bNrChannels 2

wChannelConfig 0x0003

Left Front (L)

Right Front (R)

iChannelNames 0

iTerminal 0

AudioControl Interface Descriptor:

bLength 9

bDescriptorType 36

bDescriptorSubtype 3 (OUTPUT_TERMINAL)

bTerminalID 7

wTerminalType 0x0101 USB Streaming

bAssocTerminal 0

bSourceID 8

iTerminal 0

AudioControl Interface Descriptor:

bLength 7

bDescriptorType 36

bDescriptorSubtype 5 (SELECTOR_UNIT)

bUnitID 8

bNrInPins 1

baSource( 0) 10

iSelector 0

AudioControl Interface Descriptor:

bLength 10

bDescriptorType 36

bDescriptorSubtype 6 (FEATURE_UNIT)

bUnitID 10

bSourceID 2

bControlSize 1

bmaControls( 0) 0x01

Mute Control

bmaControls( 1) 0x02

Volume Control

bmaControls( 2) 0x02

Volume Control

iFeature 0

Interface Descriptor:

bLength 9

bDescriptorType 4

bInterfaceNumber 1

bAlternateSetting 0

bNumEndpoints 0

bInterfaceClass 1 Audio

bInterfaceSubClass 2 Streaming

bInterfaceProtocol 0

iInterface 0

Interface Descriptor:

bLength 9

bDescriptorType 4

bInterfaceNumber 1

bAlternateSetting 1

bNumEndpoints 1

bInterfaceClass 1 Audio

bInterfaceSubClass 2 Streaming

bInterfaceProtocol 0

iInterface 0

AudioStreaming Interface Descriptor:

bLength 7

bDescriptorType 36

bDescriptorSubtype 1 (AS_GENERAL)

bTerminalLink 7

bDelay 1 frames

wFormatTag 1 PCM

AudioStreaming Interface Descriptor:

bLength 29

bDescriptorType 36

bDescriptorSubtype 2 (FORMAT_TYPE)

bFormatType 1 (FORMAT_TYPE_I)

bNrChannels 1

bSubframeSize 2

bBitResolution 16

bSamFreqType 7 Discrete

tSamFreq[ 0] 8000

tSamFreq[ 1] 11025

tSamFreq[ 2] 16000

tSamFreq[ 3] 22050

tSamFreq[ 4] 32000

tSamFreq[ 5] 44100

tSamFreq[ 6] 48000

Endpoint Descriptor:

bLength 9

bDescriptorType 5

bEndpointAddress 0x82 EP 2 IN

bmAttributes 5

Transfer Type Isochronous

Synch Type Asynchronous

Usage Type Data

wMaxPacketSize 0x0064 1x 100 bytes

bInterval 1

bRefresh 0

bSynchAddress 0

AudioControl Endpoint Descriptor:

bLength 7

bDescriptorType 37

bDescriptorSubtype 1 (EP_GENERAL)

bmAttributes 0x01

Sampling Frequency

bLockDelayUnits 0 Undefined

wLockDelay 0 Undefined

Interface Descriptor:

bLength 9

bDescriptorType 4

bInterfaceNumber 1

bAlternateSetting 2

bNumEndpoints 1

bInterfaceClass 1 Audio

bInterfaceSubClass 2 Streaming

bInterfaceProtocol 0

iInterface 0

AudioStreaming Interface Descriptor:

bLength 7

bDescriptorType 36

bDescriptorSubtype 1 (AS_GENERAL)

bTerminalLink 7

bDelay 1 frames

wFormatTag 1 PCM

AudioStreaming Interface Descriptor:

bLength 29

bDescriptorType 36

bDescriptorSubtype 2 (FORMAT_TYPE)

bFormatType 1 (FORMAT_TYPE_I)

bNrChannels 2

bSubframeSize 2

bBitResolution 16

bSamFreqType 7 Discrete

tSamFreq[ 0] 8000

tSamFreq[ 1] 11025

tSamFreq[ 2] 16000

tSamFreq[ 3] 22050

tSamFreq[ 4] 32000

tSamFreq[ 5] 44100

tSamFreq[ 6] 48000

Endpoint Descriptor:

bLength 9

bDescriptorType 5

bEndpointAddress 0x82 EP 2 IN

bmAttributes 5

Transfer Type Isochronous

Synch Type Asynchronous

Usage Type Data

wMaxPacketSize 0x00c8 1x 200 bytes

bInterval 1

bRefresh 0

bSynchAddress 0

AudioControl Endpoint Descriptor:

bLength 7

bDescriptorType 37

bDescriptorSubtype 1 (EP_GENERAL)

bmAttributes 0x01

Sampling Frequency

bLockDelayUnits 0 Undefined

wLockDelay 0 Undefined

Interface Descriptor:

bLength 9

bDescriptorType 4

bInterfaceNumber 2

bAlternateSetting 0

bNumEndpoints 1

bInterfaceClass 3 Human Interface Device

bInterfaceSubClass 0 No Subclass

bInterfaceProtocol 0 None

iInterface 0

HID Device Descriptor:

bLength 9

bDescriptorType 33

bcdHID 1.11

bCountryCode 0 Not supported

bNumDescriptors 1

bDescriptorType 34 Report

wDescriptorLength 26

Report Descriptors:

** UNAVAILABLE **

Endpoint Descriptor:

bLength 7

bDescriptorType 5

bEndpointAddress 0x87 EP 7 IN

bmAttributes 3

Transfer Type Interrupt

Synch Type None

Usage Type Data

wMaxPacketSize 0x0010 1x 16 bytes

bInterval 1

Device Status: 0x0000

(Bus Powered)

总结:

UAC设备的参数是通过USB描述符确定的。比如声道是bNrChannels,位深是bBitResolution,采样率是bSamFreqType。截取其中一段说明:

bNrChannels 1

bSubframeSize 2

bBitResolution 16

bSamFreqType 7 Discrete

tSamFreq[ 0] 8000

tSamFreq[ 1] 11025

tSamFreq[ 2] 16000

tSamFreq[ 3] 22050

tSamFreq[ 4] 32000

tSamFreq[ 5] 44100

tSamFreq[ 6] 48000

声道1,位深16,波特率8000~48000。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

linux uac 设备,USB Audio Class (UAC) 分析 的相关文章

  • 对于任何真实数据集,数据压缩比的最小可能值是多少

    我在写信ZLIB类似于嵌入式硬件压缩器的 API 它使用 deflate 算法来压缩给定的输入流 在进一步讨论之前 我想解释一下数据压缩率 数据压缩率定义为未压缩大小与压缩大小之间的比率 压缩比通常大于一 这意味着压缩数据通常比未压缩数据小
  • 如何获取与 shell 中的文件名模式匹配的所有文件的总文件大小?

    我正在尝试仅使用 shell 来计算与文件名模式匹配的所有文件 在目录树中 的总大小 以字节为单位 这是我到目前为止所拥有的 find name undo exec stat c s awk 总计 1 END 打印总计 有没有更简单的方法来
  • Vagrant 遇到问题 - “404 - 未找到”

    我正在尝试使用 Vagrant 制作一个 LAMP 盒子 有人告诉我它使用起来非常简单 我对网络和虚拟机完全陌生 对 Linux Ubuntu 的经验也很少 我目前已尝试按照官方文档页面上的教程进行操作 http docs vagrantu
  • 在ubuntu中打开spyder

    我想在ubuntu中打开spyder Python IDE 通常我会在 shell 中编写 spyder 它会打开spyder IDE 现在 当我在shell中编写spyder时 它只是换行 什么也没有发生 类似于按 enter 我如何找回
  • 在 Linux 中重新启动时,新创建的文件变为 0 kb(数据被覆盖为空)

    我遇到了一个奇怪的问题 这让我发疯 当前的任务是在 root 用户第一次登录时启动一组文件 并在同一用户第二次登录时启动另一组文件 我决定使用 profile 和 bashrc 文件 并在第一次登录期间发生的任务结束时重新加载 bashrc
  • 更新Linux中的包含路径

    我的 my path to file 文件夹中有几个头文件 我知道如何将这些文件包含在新的 C 程序中 但每次我都需要在包含它之前输入头文件的完整路径 我可以在linux中设置一些路径变量 以便它自动查找头文件吗 您可以创建一个 makef
  • MySQL 与 PHP 的连接无法正常工作

    这是我的情况 我正在尝试使用 Apache 服务器上的 PHP 文件连接到 MySQL 数据库 现在 当我从终端运行 PHP 时 我的 PHP 可以连接到 MySQL 数据库 使用 php f file php 但是当我从网页执行它时 它只
  • bash while 循环的布尔表达式中的 -lt 意味着什么?

    我猜测它代表小于基于输出 但是我在哪里可以找到有关此语法的文档 bin bash COUNTER 0 while COUNTER lt 10 do echo The counter is COUNTER let COUNTER COUNTE
  • Python glob,操作系统,相对路径,将文件名放入列表中[重复]

    这个问题在这里已经有答案了 我正在尝试创建一个目录中所有文件的列表 其中文件名以 root 结尾 在阅读了论坛中的一些文章后 我尝试使用 glob 和 os listdir 的基本策略 但我都遇到了麻烦 首先 当我使用 import glo
  • Android:处理电话中的语音

    我目前正在寻找有关如何在 Android 上操作音频的选项 目标是在通话期间实时处理来自麦克风的音频 最好的解决方案是在本机调用中执行此操作 但重建一个电话应用程序 无 VOIP 也可以 有没有什么方法可以使用 Android API 来实
  • .wav 文件长度/持续时间,无需读入文件

    有没有办法提取有关 wav 文件长度 持续时间的信息 而无需在 R 中读取文件 我有数千个这样的文件 如果我必须阅读每个文件才能找到其持续时间 那将需要很长时间 Windows 文件资源管理器为您提供了打开 长度 字段的选项 并且您可以查看
  • 为 Linux 编译 Objective-C 应用程序(API 覆盖范围)

    我可能在这里问一些奇怪的问题 但我不确定从哪里开始 问题是我正在考虑使用 Obj C 和 Foundation 类在 Mac 上编写一个命令行工具 但存在一个非常大的风险 那就是我希望能够为不同的 Linux 发行版编译它 以便将来作为服务
  • AVAudioPlayer只能在模拟器中播放,但不能在设备中播放,为什么?! (iPhone-SDK)

    我有以下播放声音的简单代码 NSString soundPath NSBundle mainBundle pathForResource sound ofType wav player AVAudioPlayer alloc initWit
  • 来自守护程序的错误响应:加入会话密钥环:创建会话密钥:超出磁盘配额

    我尝试在我的服务器上安装 docker 使用本教程 https docs docker com install linux docker ce ubuntu 我想远程运行 docker 镜像并使用 portainer Web 界面来管理一切
  • 保存录制的 AVAudioRecorder 声音文件:现在怎么办? (iOS、Xcode 4)

    在我的应用程序中 我希望用户能够录制一个声音文件并播放它 然后保存该声音文件以供以后使用 我用了本教程 http www techotopia com index php Recording Audio on an iPhone with
  • 如何在不使用 IDE 的情况下在 Linux 上运行 Java 项目

    我是 Java 新手 基本上 我开发了一个java项目 其中包含Eclipse中的多个Java包 该项目在我安装了 redhat Linux 的桌面上运行正常 然而 我需要在一个更强大的没有安装X11的Linux服务器 redhat ent
  • ssh 连接超时

    我无法在 git 中 ssh 到 github bitbucket 或 gitlab 我通常会收到以下错误消息 如何避免它 输出 ssh T email protected cdn cgi l email protection i ssh
  • 仅使用containerd(不使用Docker)修剪容器镜像

    如果我刚刚containerd安装在 Linux 系统上 即 Docker 是not安装 如何删除未使用的容器映像以节省磁盘空间 Docker 就是这么方便docker system prune https docs docker com
  • 执行命令而不将其保留在历史记录中[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 在进行软件开发时 经常需要在命令行命令中包含机密信息 典型示例是将项目部署到服务器的凭据设置为环境变量 当我不想将某些命令存储在命令历史记
  • 两个类可以使用 C++ 互相查看吗?

    所以我有一个 A 类 我想在其中调用一些 B 类函数 所以我包括 b h 但是 在 B 类中 我想调用 A 类函数 如果我包含 a h 它最终会陷入无限循环 对吗 我能做什么呢 仅将成员函数声明放在头文件 h 中 并将成员函数定义放在实现文

随机推荐