> For the complete documentation index, see [llms.txt](https://book.bsdcn.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://book.bsdcn.org/man/man4/pcm.4.md).

# pcm.4

`sound` — FreeBSD PCM 音频设备基础设施

## 名称

`sound`, `pcm`, `snd` FreeBSD PCM 音频设备基础设施

## 概要

`要将此驱动编译进内核，请在你的内核配置文件中加入以下行：`

> device sound

## 描述

`snd` 驱动是 FreeBSD 声音系统的主要组件。它与所支持设备上的桥设备驱动协同工作，并在附加后提供 PCM 音频录制和播放。每个桥设备驱动支持一组特定的音频芯片组，需要与 `snd` 驱动一起启用。PCI 和 ISA PnP 音频设备会自我标识，因此通常无需用户向 **/boot/device.hints** 中添加任何内容。

`snd` 驱动的一些主要特性包括：多声道音频、按应用程序音量控制、通过虚拟声道进行的动态混音、真正的全双工操作、bit-perfect 音频、速率转换和低延迟模式。

`snd` 驱动默认启用，并附带若干桥设备驱动。未默认启用的驱动可在运行时使用 [kldload(8)](/man/man8/kldload.8.md) 加载，或在引导时通过 loader.conf(5) 加载。可用的桥设备驱动有：

* [snd\_ai2s(4)](https://github.com/FreeBSD-Ask/freebsd-man-sc/blob/main/man4/snd_ai2s.4.powerpc.md)
* [snd\_als4000(4)](/man/man4/snd_als4000.4.md)
* [snd\_atiixp(4)](/man/man4/snd_atiixp.4.md)
* [snd\_cmi(4)](/man/man4/snd_cmi.4.md)
* [snd\_cs4281(4)](/man/man4/snd_cs4281.4.md)
* [snd\_csa(4)](/man/man4/snd_csa.4.md)
* [snd\_davbus(4)](https://github.com/FreeBSD-Ask/freebsd-man-sc/blob/main/man4/snd_davbus.4.powerpc.md)
* [snd\_emu10k1(4)](/man/man4/snd_emu10k1.4.md)
* [snd\_emu10kx(4)](/man/man4/snd_emu10kx.4.md)
* [snd\_envy24(4)](/man/man4/snd_envy24.4.md)
* [snd\_envy24ht(4)](/man/man4/snd_envy24ht.4.md)
* [snd\_es137x(4)](/man/man4/snd_es137x.4.md)
* [snd\_fm801(4)](/man/man4/snd_fm801.4.md)
* [snd\_hda(4)](/man/man4/snd_hda.4.md)
* [snd\_hdsp(4)](/man/man4/snd_hdsp.4.md)
* [snd\_hdspe(4)](/man/man4/snd_hdspe.4.md)
* [snd\_ich(4)](/man/man4/snd_ich.4.md)
* [snd\_maestro3(4)](/man/man4/snd_maestro3.4.md)
* [snd\_neomagic(4)](/man/man4/snd_neomagic.4.md)
* [snd\_solo(4)](/man/man4/snd_solo.4.md)
* [snd\_spicds(4)](/man/man4/snd_spicds.4.md)
* [snd\_uaudio(4)](/man/man4/snd_uaudio.4.md)
* [snd\_via8233(4)](/man/man4/snd_via8233.4.md)
* [snd\_via82c686(4)](/man/man4/snd_via82c686.4.md)
* [snd\_vibes(4)](/man/man4/snd_vibes.4.md)

各桥设备驱动的特定设置和信息请参阅对应的手册页。

### 引导变量

通常，模块 `snd_foo` 对应于 `device snd_foo`，可由引导 [loader(8)](/man/man8/loader.8.md) 通过 loader.conf(5) 加载，或使用 [kldload(8)](/man/man8/kldload.8.md) 实用程序从命令行加载。可在 **/boot/loader.conf** 中指定的选项包括：

**`snd_driver_load`** （“`NO`”）若设为“`YES`”，此选项会加载所有可用驱动。

**`snd_hda_load`** （“`NO`”）若设为“`YES`”，仅加载 Intel High Definition Audio 桥设备驱动及其依赖模块。

**`snd_foo_load`** （“`NO`”）若设为“`YES`”，加载卡/芯片组 foo 的驱动。

要为不同混音器通道定义默认值，可使用 hints 将通道设为期望值，例如：`hint.pcm.0.line`="" `0`。这会默认静音输入通道。

### 多声道音频

多声道音频，通常被称为“环绕声”，受支持并默认启用。FreeBSD 多声道矩阵处理器支持最多 18 个交错声道，但目前限制设为 8 个声道（常用于 7.1 环绕声）。内部矩阵映射可处理声道的缩减、扩展或重路由。这为相关的多声道 Fn ioctl 支持提供了基础接口。多声道音频在有无 VCHAN 时均可工作。

大多数桥设备驱动仍缺少多声道矩阵支持，但在大多数情况下，实现起来应很简单。可使用 `dev.pcm.%d.[play|rec].vchanformat` [sysctl(8)](/man/man8/sysctl.8.md) 调整所使用的声道数。当前的多声道交错结构和排列方式是通过研究各种流行的 UNIX 应用程序实现的。由于没有单一标准，因此尽管每个应用程序都有自己的冲突标准，仍尽力尝试满足每种可能的场景。

### EQ

参数软件均衡器（EQ）支持使用“音调”控制（低音和高音）。常用于由于硬件质量差异较大而进行的声音修饰或频率补偿。

### VCHAN

每个设备可选择性地通过使用“虚拟声道”（VCHAN）支持比物理硬件提供的更多的播放和录制声道。VCHAN 选项可通过 [sysctl(8)](/man/man8/sysctl.8.md) 接口配置，但只能在设备非活动状态下进行操作。

### VPC

FreeBSD 为每个活动应用程序支持独立且个别的音量控制，而不会影响主 `snd` 音量。这有时被称为按通道音量（Volume Per Channel，VPC）。

### 运行时配置

有许多 [sysctl(8)](/man/man8/sysctl.8.md) 变量可在运行时修改。这些值也可存储在 **/etc/sysctl.conf** 中，以便在引导过程中自动设置。`hw.snd.*` 为全局设置，`dev.pcm.*` 为设备特定设置。

**-1** 强制禁用 PROT\_EXEC mmap(2) 请求，即使是 Linux 应用程序。

**0** 仅允许 Linux 应用程序的 PROT\_EXEC mmap(2) 请求。

**0** 不自动分配默认声音单元。

**1** 根据设备的播放和录制能力使用最佳可用声音设备。

**2** 使用最近附加的设备。

**0** 零阶保持（ZOH）。速度非常快，但质量较差。

**1** 线性插值。速度快，质量因人而异。但由于缺乏抗混叠滤波，技术上质量较差。

**2** 带限 SINC 插值器。实现多相滤波以提高转换速度，代价是内存使用量增加，并使用多个高质量多项式插值器来提高转换精度。100% 定点运算，64 位累加器配合 32 位系数和高精度采样缓冲。质量值为 100dB 阻带、8 抽头和 85% 带宽。

**3** 带限 SINC 插值器的延续，质量值为 100dB 阻带、36 抽头和 90% 带宽。

**4** 带限 SINC 插值器的延续，质量值为 100dB 阻带、164 抽头和 97% 带宽。

**0** 已安装的设备及其分配的总线资源。

**1** 每个设备的播放、录制、虚拟声道数和标志。

**2** 每个设备的通道信息，包括通道的当前格式、速度以及伪设备统计信息（如缓冲区溢出和缓冲区欠载）。

**3** 当前加载的声音模块的文件名和版本。

**4** 用于调试的各种消息。

**s16le:1.0** 单声道。

**s16le:2.0** 立体声，2 声道（左、右）。

**s16le:2.1** 3 声道（左、右、LFE）。

**s16le:3.0** 3 声道（左、右、后中置）。

**s16le:4.0** 四声道，4 声道（前/后左和右）。

**s16le:4.1** 5 声道（4.0 + LFE）。

**s16le:5.0** 5 声道（4.0 + 中置）。

**s16le:5.1** 6 声道（4.0 + 中置 + LFE）。

**s16le:6.0** 6 声道（4.0 + 前/后中置）。

**s16le:6.1** 7 声道（6.0 + LFE）。

**s16le:7.1** 8 声道（4.0 + 中置 + LFE + 左右侧）。

**fixed** 通道混音使用固定格式/速率进行。数字直通等高级操作将无法工作。可视为“传统”模式。这是缺乏数字格式支持的硬件声道的默认模式。

**passthrough** 通道混音使用固定格式/速率进行，但数字直通等高级操作也可工作。所有声道将照常发出声音，直到请求播放数字格式。发生此情况时，所有其他声道将被静音，并允许最新传入的数字格式不受干扰地通过。支持多个并发数字流，但最新流将优先并静音所有其他流。

**adaptive** 工作方式类似于“passthrough”模式，但更智能一些，特别是对于具有不同格式/速率的多个 `snd` 声道。当新声道即将启动时，将扫描整个虚拟声道列表，并选择具有最佳格式/速率（通常为最高/最大）的声道。这确保混音质量取决于最佳声道。缺点是需要重启硬件 DMA 模式，可能引起令人烦恼的爆音或咔嗒声。

**`hw.snd.compat_linux_mmap`** 此 [sysctl(8)](/man/man8/sysctl.8.md) 变量仅在 Linux 应用程序支持被编译进内核时才可用，并且仅影响 Linux 二进制文件。它是一种权宜之计，用于解决如下情况：对于 i386 仿真，[linux(4)](/man/man4/linux.4.md) 在 mmap(2) 调用期间设置 PROT\_READ 或 PROT\_WRITE 时会自动设置 PROT\_EXEC，而 FreeBSD 不会。支持以下值（默认为 -1）：

**`hw.snd.default_auto`** 自动分配默认声音单元。支持以下值（默认为 1）：

**`hw.snd.default_unit`** 具有多个声卡的系统的默认声卡。使用 [devfs(4)](/man/man4/devfs.4.md) 时，`/dev/dsp` 的默认设备。等价于从 `/dev/dsp` 到 `/dev/dsp``${hw.snd.default_unit}` 的符号链接。

**`hw.snd.feeder_eq_exact_rate`** 仅某些速率允许进行精确处理。但默认行为是允许对所有速率进行宽松处理，即使是不支持的速率。启用以切换此要求，仅允许对支持的速率进行处理。

**`hw.snd.feeder_rate_max`** 允许的最大采样速率。

**`hw.snd.feeder_rate_min`** 允许的最小采样速率。

**`hw.snd.feeder_rate_polyphase_max`** 调整以设置在构建重采样滤波器过程中允许的最大多相条目数。禁用多相重采样可减少内存使用量，代价是转换速度更慢且质量更低。仅在使用 SINC 插值器时适用。默认值为 183040。设为 0 可禁用多相重采样。

**`hw.snd.feeder_rate_quality`** 采样速率转换器质量。默认值为 1，线性插值。可用选项包括：

**`hw.snd.feeder_rate_round`** 采样速率舍入阈值，以牺牲精度为代价避免大质数除法。所有请求的采样速率将被舍入到最近的阈值值。可能值介于 0（禁用）和 500 之间。默认为 25。

**`hw.snd.latency`** 配置缓冲延迟。仅影响未显式请求块大小/片段的应用程序。此可调参数提供比 `hw.snd.latency_profile` 可调参数更细的粒度。可能值介于 0（最低延迟）和 10（最高延迟）之间。

**`hw.snd.latency_profile`** 为 `hw.snd.latency` 可调参数定义一组缓冲延迟转换表。值为 0 将使用低且激进的延迟配置文件，如果应用程序无法跟上快速的中断速率（特别是在高工作负载下），可能导致欠载。默认值为 1，被视为适度/安全的延迟配置文件。

**`hw.snd.vchans_enable`** 全局 VCHAN 设置，用于启用（1）或禁用（0）VCHAN。可通过使用 `dev.pcm.%d.[play|rec].vchans` 可调参数为单个设备覆盖此设置。默认启用。

**`hw.snd.report_soft_formats`** 如果可用，则透明地控制内部格式转换到应用程序软件。当禁用或不可用时，应用程序只能选择设备原生支持的格式。

**`hw.snd.report_soft_matrix`** 即使硬件不支持，也启用无缝声道矩阵。使得即使是简单的立体声卡也能播放多声道流。

**`hw.snd.verbose`** `/dev/sndstat` 设备的详细程度级别。较高的值包含更多输出，在报告问题时应使用最高级别（即四级）。其他选项包括：

**`hw.snd.vpc_0db`** `snd` 音量的默认值。增大以给衰减控制留出更多空间。减小以获得更多放大，但可能导致声音削波。

**`hw.snd.vpc_autoreset`** 当声道关闭时，声道音量将重置为 0db。这意味着对音量的任何更改都将丢失。启用此项将保留音量，但代价是当应用程序尝试重新打开同一设备时可能会产生混淆。

**`hw.snd.vpc_reset`** 启用以将所有声道音量恢复为默认值 0db。

**`dev.pcm.%d.bitperfect`** 启用或禁用 bitperfect 模式。启用时，声道将跳过所有 dsp 处理，如声道矩阵、速率转换和均衡。纯净的 `snd` 流将直接馈送到硬件。如果启用了 VCHAN，bitperfect 模式将使用 VCHAN 格式/速率作为确定的格式/速率目标。使用 bitperfect 模式的推荐方法是禁用 VCHAN 并启用此 sysctl。默认禁用。

**`dev.pcm.%d.eq`** 设为 1 或 0 以启用（1）或禁用（0）均衡器。默认禁用。启用后，可使用混音器低音和高音控制，以及 `dev.pcm.%d.eq_preamp` 可调参数。

**`dev.pcm.%d.eq_preamp`** 均衡器前置放大器（以 dB 为单位）。必须启用 `dev.pcm.%d.eq` 此可调参数才生效。请阅读可调参数描述以查看可用值范围。

**`dev.pcm.%d.[play|rec].vchans`** 启用（1）或禁用（0）VCHAN。默认启用。

**`dev.pcm.%d.[play|rec].vchanformat`** VCHAN 混音的格式。所有播放路径将在混音过程开始之前转换为此格式。默认仅启用 2 个声道。可用选项包括：

**`dev.pcm.%d.[play|rec].vchanmode`** VCHAN 格式/速率选择。可用选项包括：

**`dev.pcm.%d.[play|rec].vchanrate`** VCHAN 混音的采样速率。所有播放路径将在混音过程开始之前转换为此采样速率。

**`dev.pcm.%d.polling`** 实验性轮询模式支持，驱动通过使用 [callout(9)](https://github.com/FreeBSD-Ask/freebsd-man-sc/blob/main/man9/callout.9.md) 机制在每个时钟滴答上查询设备状态来运行。默认禁用，目前仅对少数设备驱动可用。

### 统计信息

声道统计信息仅在设备打开时才保留。因此，对于涉及溢出和欠载的情况，请在出错的应用程序打开并运行时考虑输出。

### IOCTL 支持

驱动支持大多数 OSS Fn ioctl 函数，大多数应用程序无需修改即可工作。存在一些差异，内存映射播放原生支持和 Linux 仿真中均支持，但由于 VM 系统设计，不支持内存映射录制。因此，某些应用程序可能需要使用稍加修改的音频模块重新编译。参见

`#include <sys/soundcard.h>`

以获取支持的 Fn ioctl 函数的完整列表。

### kqueue 支持

`kevent` 结构的字段定义如下：

* 计算等待时间并调用 clock\_nanosleep(2)。
* 调用 ioctl(2) 执行 `SNDCTL_DSP_GETIPTR` 或 `SNDCTL_DSP_GETOPTR` 以获取内存映射缓冲区中新数据起始处的指针。
* 调用 ioctl(2) 执行 `SNDCTL_DSP_GETERROR` 以获取溢出/欠载并处理它们。
* `ext[0]` 对于使用 mmap(2) 的设备，它包含录制时 `SNDCTL_DSP_GETIPTR` 报告的 `count_info.ptr` 字段或播放时 `SNDCTL_DSP_GETOPTR` 报告的字段，而对于不使用 mmap(2) 的设备，它包含录制时 `SNDCTL_DSP_CURRENT_IPTR` 报告的 `oss_count_t.fifo_samples` 字段或播放时 `SNDCTL_DSP_CURRENT_OPTR` 报告的字段。
* `ext[1]` 包含录制事件的 `audio_errinfo.rec_overruns` 字段或播放事件的 `audio_errinfo.play_underruns` 字段，由 `SNDCTL_DSP_GETERROR` 报告。这允许单个 `kevent` 报告数据已就绪、可读取或写入的字节数、当前缓冲区位置和当前错误计数。这对于使用 mmap(2) 的场景特别有用，因为如果没有 kqueue(2)，典型的处理循环包括：

**`ident`** 设备的文件描述符。

**`filter`** 用于处理事件的内核过滤器。对于录制为 `EVFILT_READ`，对于播放为 `EVFILT_WRITE`。

**`data`** 可读取或写入的字节数。

**`ext`**

## 文件

`snd` 驱动可能创建以下设备节点：

**`/dev/dsp%d`** 音频设备。该数字表示设备的单元号。 **`/dev/dsp`** `/dev/dsp${hw.snd.default_unit}` 的别名。仅在设置了 `hw.snd.basename_clone` 时可用。 **`/dev/sndstat`** 当前 `snd` 状态，包括所有声道和驱动。

所有 `snd` 设备都列在 `/dev/sndstat` 中。在探测和附加设备时有时会记录额外消息，可使用 [dmesg(8)](/man/man8/dmesg.8.md) 实用程序查看这些消息。

用户必须是 audio 组的成员才能访问 `snd` 创建的任何设备节点，以及设备驱动和 virtual\_oss(8)。

## 实例

使用 sound 元驱动一次性加载所有 `snd` 桥设备驱动（例如，当不清楚应使用哪个驱动时）：

```sh
kldload snd_driver
```

加载特定的桥设备驱动，此处为 Intel High Definition Audio 驱动：

```sh
kldload snd_hda
```

检查所有检测到的 `snd` 设备的状态：

```sh
cat /dev/sndstat
```

更改默认声音设备，此处更改为第二个设备。当有多个 `snd` 设备可用时很方便：

```sh
mixer -d pcm1
```

## 诊断

* pcm%d:play:%d:dsp%d.p%d: play interrupt timeout, channel dead 硬件未生成中断以处理传入（播放）或传出（录制）数据。
* unsupported subdevice XX 设备节点未正确创建。

## 参见

[devfs(4)](/man/man4/devfs.4.md), [snd\_ai2s(4)](https://github.com/FreeBSD-Ask/freebsd-man-sc/blob/main/man4/snd_ai2s.4.powerpc.md), [snd\_als4000(4)](/man/man4/snd_als4000.4.md), [snd\_atiixp(4)](/man/man4/snd_atiixp.4.md), [snd\_cmi(4)](/man/man4/snd_cmi.4.md), [snd\_cs4281(4)](/man/man4/snd_cs4281.4.md), [snd\_csa(4)](/man/man4/snd_csa.4.md), [snd\_davbus(4)](https://github.com/FreeBSD-Ask/freebsd-man-sc/blob/main/man4/snd_davbus.4.powerpc.md), [snd\_emu10k1(4)](/man/man4/snd_emu10k1.4.md), [snd\_emu10kx(4)](/man/man4/snd_emu10kx.4.md), [snd\_envy24(4)](/man/man4/snd_envy24.4.md), [snd\_envy24ht(4)](/man/man4/snd_envy24ht.4.md), [snd\_es137x(4)](/man/man4/snd_es137x.4.md), [snd\_fm801(4)](/man/man4/snd_fm801.4.md), [snd\_hda(4)](/man/man4/snd_hda.4.md), [snd\_hdsp(4)](/man/man4/snd_hdsp.4.md), [snd\_hdspe(4)](/man/man4/snd_hdspe.4.md), [snd\_ich(4)](/man/man4/snd_ich.4.md), [snd\_maestro3(4)](/man/man4/snd_maestro3.4.md), [snd\_neomagic(4)](/man/man4/snd_neomagic.4.md), [snd\_solo(4)](/man/man4/snd_solo.4.md), [snd\_spicds(4)](/man/man4/snd_spicds.4.md), snd\_t4dwave(4), [snd\_uaudio(4)](/man/man4/snd_uaudio.4.md), [snd\_via8233(4)](/man/man4/snd_via8233.4.md), [snd\_via82c686(4)](/man/man4/snd_via82c686.4.md), [snd\_vibes(4)](/man/man4/snd_vibes.4.md), [device.hints(5)](/man/man5/device.hints.5.md), loader.conf(5), [dmesg(8)](/man/man8/dmesg.8.md), [kldload(8)](/man/man8/kldload.8.md), mixer(8), [sysctl(8)](/man/man8/sysctl.8.md), virtual\_oss(8)

> "Cookbook formulae for audio EQ biquad filter coefficients (Audio-EQ-Cookbook.txt), by Robert Bristow-Johnson".

> "Julius O'Smith's Digital Audio Resampling".

> "Polynomial Interpolators for High-Quality Resampling of Oversampled Audio, by Olli Niemitalo".

> "The OSS API".

## 历史

`snd` 设备驱动首次出现于 FreeBSD 2.2.6，名为 `pcm`，由 Luigi Rizzo 编写。后来在 FreeBSD 4.0 中由 Cameron Grant 重写。API 演变自 VOXWARE 标准，后者后来成为 OSS 标准。

## 作者

Luigi Rizzo <luigi@iet.unipi.it> 最初编写了 `pcm` 设备驱动和本手册页。Cameron Grant <gandalf@vilnya.demon.co.uk> 后来为 FreeBSD 4.0 修订了设备驱动。Seigo Tanimura <tanimura@r.dl.itc.u-tokyo.ac.jp> 修订了本手册页。之后为 FreeBSD 5.2 重写。

## 缺陷

某些声卡功能（例如全局音量控制）可能并非在所有设备上都受支持。

某些音频设备可能拒绝正常工作，除非为录制和播放配置相同的采样速率，即使仅使用单工模式。参见 `dev.pcm.%d.[play|rec].vchanrate` sysctl。


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://book.bsdcn.org/man/man4/pcm.4.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
