使用 M-Audio Audiophile USB 与 ALSA 和 Jack 的指南

v1.5

Thibault Le Meur <Thibault.LeMeur@supelec.fr>

本文档是关于将 M-Audio Audiophile USB (tm) 设备与 ALSA 和 JACK 配合使用的指南。

历史

  • v1.4 - Thibault Le Meur (2007-07-11)

  • v1.5 - Thibault Le Meur (2007-07-12) - 添加了 AC3/DTS 直通信息

Audiophile USB 规格和正确用法

本部分提醒有关设备功能和限制的重要事实。

该设备有 4 个音频接口和 2 个 MIDI 端口

  • 模拟立体声输入 (Ai)

    • 此端口支持 2 对线路电平音频输入(1/4 英寸 TS 和 RCA)

    • 连接 1/4 英寸 TS(插孔)连接器时,RCA 连接器将被禁用

  • 模拟立体声输出 (Ao)

  • 数字立体声输入 (Di)

  • 数字立体声输出 (Do)

  • Midi 输入 (Mi)

  • Midi 输出 (Mo)

内部 DAC/ADC 具有以下特征

  • 16 位或 24 位的采样深度

  • 从 8kHz 到 96kHz 的采样率

  • 两个接口不能同时使用不同的采样深度。

此外,Audiophile USB 文档给出了以下警告

在切换位深度之前,请退出所有正在运行的音频应用程序

由于 USB 1.1 带宽的限制,根据所选的音频模式,可以同时激活的接口数量有限

  • 16 位/48kHz ==> 4 个输入通道 + 4 个输出通道

    • Ai+Ao+Di+Do

  • 24 位/48kHz ==> 4 个输入通道 + 2 个输出通道,或 2 个输入通道 + 4 个输出通道

    • Ai+Ao+Do 或 Ai+Di+Ao 或 Ai+Di+Do 或 Di+Ao+Do

  • 24 位/96kHz ==> 2 个输入通道 _或_ 2 个输出通道(仅半双工)

    • Ai 或 Ao 或 Di 或 Do

关于数字接口的重要事实:

  • Do 端口还支持环绕编码的 AC-3 和 DTS 直通,尽管我尚未在 Linux 下对其进行测试

    • 请注意,在此设置中,只能启用 Do 接口

  • 除了录制音频数字流之外,启用 Di 端口还可以将设备与外部采样时钟同步

    • 因此,仅当连接了有效的数字源时,才必须启用 Di 端口

    • 在未连接数字源的情况下启用 Di 可能会导致同步错误(例如,以奇怪的采样率播放声音)

ALSA 中的 Audiophile USB MIDI 支持

加载以下模块后,将自动支持 Audiophile USB MIDI 端口

  • snd-usb-audio

  • snd-seq-midi

无需其他设置。

ALSA 中的 Audiophile USB 音频支持

Audiophile USB 设备的音频功能由 snd-usb-audio 模块处理。此模块可以在默认模式(没有任何特定于设备的参数)下工作,或者在具有称为 device_setup 的特定于设备的参数的“高级”模式下工作。

默认的 Alsa 驱动程序模式

snd-usb-audio 驱动程序的默认行为是在启动时列出设备的功能,并在应用程序需要时激活所需的模式:例如,如果用户正在以 24 位深度模式录制,并且立即想切换到 16 位深度模式,则 snd-usb-audio 模块将动态地重新配置设备。

这种方法的优点是可以让驱动程序根据用户的需求自动从采样率/深度切换。但是,那些在 Windows 下使用该设备的人都知道这不是该设备的工作方式:在 Windows 下,必须先关闭应用程序,然后才能使用 m-audio 控制面板来切换设备的工作模式。因此,正如我们将在下一节中看到的那样,这种默认的 Alsa 驱动程序模式可能会导致设备错误配置。

现在让我们回到默认的 Alsa 驱动程序模式。在这种情况下,Audiophile 接口以以下方式映射到 alsa pcm 设备(我假设设备的索引为 1)

  • hw:1,0 是播放中的 Ao 和捕获中的 Di

  • hw:1,1 是播放中的 Do 和捕获中的 Ai

  • hw:1,2 是 AC3/DTS 直通模式下的 Do

在此模式下,设备使用大端字节编码,因此支持的音频格式为 S16_BE(对于 16 位深度模式)和 S24_3BE(对于 24 位深度模式)。

一个例外是 hw:1,2 端口,据报告它符合小端 (supposedly supporting S16_LE),但实际上仅处理 S16_BE 流。这已在内核 2.6.23 及更高版本中修复,现在在此默认驱动程序模式下,hw:1,2 接口据报告为大端。

示例

  • 将 S24_3BE 编码的原始文件播放到 Ao 端口

    % aplay -D hw:1,0 -c2 -t raw -r48000 -fS24_3BE test.raw
    
  • 从 Ai 端口录制 S24_3BE 编码的原始文件

    % arecord -D hw:1,1 -c2  -t raw -r48000 -fS24_3BE test.raw
    
  • 将 S16_BE 编码的原始文件播放到 Do 端口

    % aplay -D hw:1,1 -c2 -t raw -r48000 -fS16_BE test.raw
    
  • 将 ac3 采样文件播放到 Do 端口

    % aplay -D hw:1,2 --channels=6 ac3_S16_BE_encoded_file.raw
    

如果您对默认的 Alsa 驱动程序模式感到满意,并且没有遇到任何问题,则可以跳过以下章节。

高级模块设置

由于上述硬件限制,Alsa 驱动程序在默认模式下进行的设备初始化可能会导致设备处于损坏状态。例如,一个特别令人讨厌的问题是,从 Ai 接口捕获的声音听起来失真(好像音量增益过高)。

对于遇到此问题的人,snd-usb-audio 模块有一个新的模块参数,称为 device_setup(此参数是在内核版本 2.6.17 中引入的)

初始化 Audiophile USB 的工作模式

就 Audiophile USB 设备而言,此值允许用户指定

  • 采样深度

  • 采样率

  • 是否使用 Di 端口

当使用 device_setup=0x00 初始化时,snd-usb-audio 模块的行为与省略参数时相同(请参阅上面的“默认 Alsa 驱动程序模式”段落)

以下小节中描述了其他模式。

16 位模式

支持的两种模式是

  • device_setup=0x01

    • 禁用 Di 的 16 位 48kHz 模式

    • 可以同时使用 Ai、Ao、Do

    • hw:1,0 在捕获模式下不可用

    • hw:1,2 不可用

  • device_setup=0x11

    • 启用 Di 的 16 位 48kHz 模式

    • 可以同时使用 Ai、Ao、Di、Do

    • hw:1,0 在捕获模式下可用

    • hw:1,2 不可用

在这种模式下,设备仅以 16 位模式运行。在内核 2.6.23 之前,设备据报告为大端,但实际上它们是小端,因此播放文件就是使用的问题

% aplay -D hw:1,1 -c2 -t raw -r48000 -fS16_BE test_S16_LE.raw

其中 “test_S16_LE.raw” 实际上是一个小端采样文件。

感谢 Hakan Lennestal(他发现了设备在这些模式下的小端特性),已提交了修复程序(预计在内核 2.6.23 中),并且 Alsa 现在报告小端接口。因此,现在播放文件就像使用一样简单

% aplay -D hw:1,1 -c2 -t raw -r48000 -fS16_LE test_S16_LE.raw

24 位模式

支持的三种模式是

  • device_setup=0x09

    • 禁用 Di 的 24 位 48kHz 模式

    • 可以同时使用 Ai、Ao、Do

    • hw:1,0 在捕获模式下不可用

    • hw:1,2 不可用

  • device_setup=0x19

    • 启用 Di 的 24 位 48kHz 模式

    • 可以同时使用来自 {Ai,Ao,Di,Do} 的 3 个端口

    • hw:1,0 在捕获模式下可用,并且必须将有效的数字源连接到 Di

    • hw:1,2 不可用

  • device_setup=0x0D0x10

    • 24 位 96kHz 模式

    • 默认情况下,为此模式启用了 Di,但不需要连接到有效的源

    • 一次只能使用来自 {Ai,Ao,Di,Do} 的 1 个端口

    • hw:1,0 在捕获模式下可用

    • hw:1,2 不可用

在这些模式下,设备仅符合大端(有关 aplay 命令示例,请参阅上面的“默认 Alsa 驱动程序模式”)

AC3 w/ DTS 直通模式

感谢 Hakan Lennestal,我现在有一份报告说此模式有效。

  • device_setup=0x03

    • 仅启用 Do 端口的 16 位 48kHz 模式

    • AC3 与 DTS 直通

    • 请注意,在此设置中,Do 端口映射到 pcm 设备 hw:1,0

用于在此模式下播放 AC3/DTS 编码的 .wav 文件的命令行

% aplay -D hw:1,0 --channels=6 ac3_S16_LE_encoded_file.raw

如何使用 device_setup 参数

可以给出参数

  • 通过手动探测设备(以 root 身份):

    # modprobe -r snd-usb-audio
    # modprobe snd-usb-audio index=1 device_setup=0x09
    
  • 或者在模块配置文件(通常是 /etc/modprobe.d/ 目录中的 .conf 文件)中配置模块选项时:

    alias snd-card-1 snd-usb-audio
    options snd-usb-audio index=1 device_setup=0x09
    

初始化设备时的注意事项

  • 设备上的正确初始化要求在打开设备电源之前将 device_setup 提供给模块。因此,如果您使用上面描述的“手动探测”方法,请注意在此初始化之后再打开设备电源。

  • 未能遵守此操作将导致设备错误配置。在这种情况下,请关闭设备电源,取消探测 snd-usb-audio 模块,然后使用正确的 device_setup 参数再次探测它,然后再(并且只能在此时)再次打开设备电源。

  • 如果您已在有效模式下正确初始化了设备,然后想切换到另一种模式(可能具有另一种采样深度),也请使用以下步骤

    • 首先关闭设备电源

    • 注销 snd-usb-audio 模块 (modprobe -r)

    • 通过更改 /etc/modprobe.d/*.conf 中的 device_setup 选项来更改 device_setup 参数

    • 打开设备电源

  • 已将针对此最后一个问题的解决方法应用于内核 2.6.23,但这可能不足以确保设备初始化的“稳定性”。

适用于黑客的技术细节

本节适用于想要了解设备内部结构以及 Alsa 如何支持它的黑客。

Audiophile USB 的 device_setup 结构

如果您想了解 Audiophile USB 的 device_setup 神奇数字,则需要对二进制计算有一些非常基本的了解。但是,这不是使用该参数所必需的,您可以跳过本节。

device_setup 是一个字节长,其结构如下

+---+---+---+---+---+---+---+---+
| b7| b6| b5| b4| b3| b2| b1| b0|
+---+---+---+---+---+---+---+---+
| 0 | 0 | 0 | Di|24B|96K|DTS|SET|
+---+---+---+---+---+---+---+---+

其中

  • b0 是 SET

    • 如果初始化 device_setup,则必须设置它

  • b1 是 DTS

    • 仅针对具有 DTS/AC3 的数字输出设置它

    • 未测试此设置

  • b2 是速率选择标志

    • 当设置为 1 时,速率范围为 48.1-96kHz

    • 否则,采样率范围为 8-48kHz

  • b3 是位深度选择标志

    • 当设置为 1 时,采样为 24 位长

    • 否则,它们为 16 位长

    • 请注意,b2 意味着 b3,因为仅 24 位采样支持 96kHz 模式

  • b4 是数字输入标志

    • 当设置为 1 时,设备假定已连接有效的数字源

    • 如果在端口上看不到任何源,则不应启用 Di(这会导致同步问题)

    • b4 由 b2 隐含(因为一次只能启用一个端口,因此不会发生同步错误)

  • b5 到 b7 保留供将来使用,必须设置为 0

    • 对于 b7、b6、b4,可能分别变为 Ao、Do、Ai

注意事项

  • 没有检查您将给 device_setup 的值

    • 例如,选择 0x05 (16bits 96kHz) 将回退到 0x09,因为 b2 意味着 b3。但是 /var/log/messages 中_不会_有_任何_警告

  • 由于 USB 总线限制导致的硬件约束未经过检查

    • 选择 b2 将准备好所有接口以进行 24 位/96kHz,但您一次只能使用一个接口

此设备的 USB 实现细节

如果您对驱动程序黑客不感兴趣,可以安全地跳过本节。

本节介绍设备的一些内部结构,并总结了通过 usb-snooping Windows 和 Linux 驱动程序获得的数据。

M-Audio Audiophile USB 有 7 个 USB 接口:一个“USB 接口”

  • USB 接口编号 0

  • USB 接口编号 1

    • 音频控制功能

  • USB 接口编号 2

    • 模拟输出

  • USB 接口编号 3

    • 数字输出

  • USB 接口编号 4

    • 模拟输入

  • USB 接口编号 5

    • 数字输入

  • USB 接口编号 6

    • 符合 MIDIMAN 怪癖的 MIDI 接口

每个接口都有 5 个备用设置(AltSet 1,2,3,4,5),除了

  • 接口 3(数字输出)有一个额外的 Alset 编号 6

  • 接口 5(数字输入)没有 Alset 编号 3 和 5

以下是 AltSettings 功能的简短说明

  • AltSettings 1 对应于

    • 24 位深度,48.1-96kHz 采样模式

    • 自适应播放(Ao 和 Do),同步捕获(Ai)或异步捕获(Di)

  • AltSettings 2 对应于

    • 24 位深度,8-48kHz 采样模式

    • 异步捕获和播放(Ao,Ai,Do,Di)

  • AltSettings 3 对应于

    • 24 位深度,8-48kHz 采样模式

    • 同步捕获(Ai)和自适应播放(Ao,Do)

  • AltSettings 4 对应于

    • 16 位深度,8-48kHz 采样模式

    • 异步捕获和播放(Ao,Ai,Do,Di)

  • AltSettings 5 对应于

    • 16 位深度,8-48kHz 采样模式

    • 同步捕获(Ai)和自适应播放(Ao,Do)

  • AltSettings 6 对应于

    • 16 位深度,8-48kHz 采样模式

    • 同步播放 (Do),音频格式类型 III IEC1937_AC-3

为了确保设备的正确初始化,驱动程序_必须_知道设备将如何使用

  • 如果选择了 DTS,则必须仅注册具有 AltSet 编号 6 的接口 2

  • 如果 96KHz 仅必须选择每个接口的 AltSets 编号 1

  • 如果采样使用 24bits/48KHz,则如果连接了数字输入,则必须使用 AltSet 2,如果未连接数字输入,则仅使用 AltSet 编号 3

  • 如果采样使用 16bits/48KHz,则如果连接了数字输入,则必须使用 AltSet 4,如果未连接数字输入,则仅使用 AltSet 编号 5

当将 device_setup 作为参数提供给 snd-usb-audio 模块时,parse_audio_endpoints 函数使用一个称为 audiophile_skip_setting_quirk 的怪癖,以防止与 device_setup 不对应的 AltSettings 在驱动程序中注册。

Audiophile USB 和 Jack 支持

本节处理 Jack 中对 Audiophile USB 设备的支持。

将 Jackd 与该设备一起使用时,存在 2 个主要的潜在问题

  • 支持 24 位模式下的大端设备

  • 支持 4 输入/4 输出通道

在 Jackd 中直接支持

仅在最新版本中,Jack 支持大端设备(感谢 Andreas Steinmetz 提供的第一个大端补丁)。我不记得确切的发布时间,就说使用 jackd 版本 0.103.0 几乎可以正常工作(只是一个小错误影响 16 位大端设备,但是由于您仔细阅读了上面的段落,因此您现在正在使用内核 >= 2.6.23,并且您的 16 位设备现在是小端了 ;-))。

您可以使用以下命令运行 jackd,以使用 Ao 进行播放和使用 Ai 进行录制

% jackd -R -dalsa -Phw:1,0 -r48000 -p128 -n2 -D -Chw:1,1

使用 Alsa plughw

如果您没有安装最新的 Jackd,则可以降级为使用 Alsa plug 转换器。

例如,这是一种在 Ao 上使用 2 个播放通道和从 Ai 使用 2 个捕获通道运行 Jack 的方法

% jackd -R -dalsa -dplughw:1 -r48000 -p256 -n2 -D -Cplughw:1,1
但是,您可能会看到以下警告消息

您似乎正在使用 ALSA 软件“plug”层,这可能是使用“default”ALSA 设备的结果。这不如它可能的那样有效。考虑使用硬件设备而不是使用 plug 层。

在 Jack 中获取 2 个输入和/或输出接口

如您所见,以这种方式启动 Jack 服务器将仅启用 1 个立体声输入(Di 或 Ai)和 1 个立体声输出(Ao 或 Do)。

这是由于以下限制

  • Jack 一次只能打开一个捕获设备和一个播放设备

  • Audiophile USB 被视为 2 个(或 3 个)Alsa 设备:hw:1,0, hw:1,1(以及可选的 hw:1,2)

如果您想获得具有 Jack 的 Ai+Di 和/或 Ao+Do 支持,则需要将 Alsa 设备组合成一个逻辑的“复杂”设备。

如果您想尝试一下,我建议阅读此页面中的信息:http://www.sound-man.co.uk/linuxaudio/ice1712multi.html 它与另一个设备 (ice1712) 相关,但可以进行调整以适合 Audiophile USB。

为 Jackd 启用多个 Audiophile USB 接口肯定需要

  • 确保您的 Jackd 版本具有 MMAP_COMPLEX 补丁(请参阅 ice1712 页面)

  • (可能)修补 alsa-lib/src/pcm/pcm_multi.c 文件(请参阅 ice1712 页面)

  • 在您的 .asoundrc 文件中定义一个多设备(hw:1,0 和 hw:1,1 的组合)

  • 使用此设备启动 jackd

到目前为止,我还没有成功地对此进行测试,如果您在此类设置中获得任何成功,请给我发送电子邮件。