关于内核 OSS 模拟的说明

Jan. 22, 2004 Takashi Iwai <tiwai@suse.de>

模块

ALSA 在内核上提供强大的 OSS 模拟。用于 PCM、混音器和音序器设备的 OSS 模拟作为附加内核模块实现,分别是 snd-pcm-oss、snd-mixer-oss 和 snd-seq-oss。当您需要访问 OSS PCM、混音器或音序器设备时,必须加载相应的模块。

当调用相应的服务时,这些模块会自动加载。别名定义为 sound-service-x-y,其中 x 和 y 分别是声卡编号和次要单元编号。通常您不必自己定义这些别名。

自动加载 OSS 模块的唯一必要步骤是在 /etc/modprobe.d/alsa.conf 中定义声卡别名,例如:

alias sound-slot-0 snd-emu10k1

作为第二张声卡,也定义 sound-slot-1。请注意,您不能使用别名作为目标名称(即,像旧的 modutils 一样,alias sound-slot-0 snd-card-0 不再有效)。

当前可用的 OSS 配置显示在 /proc/asound/oss/sndstat 中。这显示了与 /dev/sndstat 相同的语法,该文件在商业 OSS 驱动程序上可用。在 ALSA 上,您可以将 /dev/sndstat 符号链接到此 proc 文件。

请注意,此 proc 文件中列出的设备仅在加载相应的 OSS 模拟模块后才会显示。即使其中显示“NOT ENABLED IN CONFIG”,也不必担心。

设备映射

ALSA 支持以下 OSS 设备文件:

PCM:
        /dev/dspX
        /dev/adspX

Mixer:
        /dev/mixerX

MIDI:
        /dev/midi0X
        /dev/amidi0X

Sequencer:
        /dev/sequencer
        /dev/sequencer2 (aka /dev/music)

其中 X 是从 0 到 7 的声卡编号。

(注意:某些发行版具有诸如 /dev/midi0 和 /dev/midi1 之类的设备文件。它们不是用于 OSS,而是用于 tclmidi,这完全是另一回事。)

与真正的 OSS 不同,ALSA 不能使用超过分配的设备文件。例如,第一张声卡不能使用 /dev/dsp1 或 /dev/dsp2,而只能使用 /dev/dsp0 和 /dev/adsp0。

如上所示,PCM 和 MIDI 可能有两个设备。通常,第一个 PCM 设备(ALSA 中的 hw:0,0)映射到 /dev/dsp,第二个设备(hw:0,1)映射到 /dev/adsp(如果可用)。对于 MIDI,分别是 /dev/midi 和 /dev/amidi。

您可以通过 snd-pcm-oss 和 snd-rawmidi 的模块选项更改此设备映射。对于 PCM,以下选项可用于 snd-pcm-oss:

dsp_map

分配给 /dev/dspX 的 PCM 设备编号(默认 = 0)

adsp_map

分配给 /dev/adspX 的 PCM 设备编号(默认 = 1)

例如,要将第三个 PCM 设备(hw:0,2)映射到 /dev/adsp0,请像这样定义:

options snd-pcm-oss adsp_map=2

这些选项采用数组。要配置第二张声卡,请指定以逗号分隔的两个条目。例如,要将第二张声卡上的第三个 PCM 设备映射到 /dev/adsp1,请如下定义:

options snd-pcm-oss adsp_map=0,2

要更改 MIDI 设备的映射,以下选项可用于 snd-rawmidi:

midi_map

分配给 /dev/midi0X 的 MIDI 设备编号(默认 = 0)

amidi_map

分配给 /dev/amidi0X 的 MIDI 设备编号(默认 = 1)

例如,要将第一张声卡上的第三个 MIDI 设备分配给 /dev/midi00,请如下定义:

options snd-rawmidi midi_map=2

PCM 模式

默认情况下,ALSA 使用所谓的插件层模拟 OSS PCM,即,当声卡本身不支持时,尝试自动转换采样格式、速率或通道。对于诸如 quake 或 wine 之类的一些应用程序,这将导致一些问题,尤其是当它们仅在 MMAP 模式下使用声卡时。

在这种情况下,您可以通过向 proc 文件写入命令来更改每个应用程序的 PCM 行为。每个 PCM 流都有一个 proc 文件,/proc/asound/cardX/pcmY[cp]/oss,其中 X 是声卡编号(从零开始),Y 是 PCM 设备编号(从零开始),p 用于播放,c 用于捕获。请注意,此 proc 文件仅在加载 snd-pcm-oss 模块后才存在。

命令序列具有以下语法:

app_name fragments fragment_size [options]

app_name 是应用程序的名称,带有(更高优先级)或不带有路径。fragments 指定分段的数量,如果未给出特定数量,则指定为零。fragment_size 是分段的大小(以字节为单位),如果未给出,则为零。options 是可选参数。以下选项可用:

disable

应用程序尝试为此通道打开一个 pcm 设备,但不想使用它。

direct

不使用插件

block

强制阻塞打开模式

non-block

强制非阻塞打开模式

partial-frag

也写入部分片段(仅影响播放)

no-silence

不要提前填充静音以避免咔哒声

当应用程序本身不支持两个方向时,disable 选项在应用程序未正确处理一个流方向(播放或捕获)时非常有用。如上所述,direct 选项用于绕过自动转换,并且对 MMAP 应用程序很有用。例如,要为 quake 无插件地播放第一个 PCM 设备,请通过 echo 发送如下命令:

% echo "quake 0 0 direct" > /proc/asound/card0/pcm0p/oss

虽然 quake 只需要播放,但您可以附加第二个命令以通知驱动程序即将分配此方向:

% echo "quake 0 0 disable" > /proc/asound/card0/pcm0c/oss

proc 文件的权限取决于 snd 的模块选项。默认情况下,它设置为 root,因此您可能需要成为超级用户才能发送上述命令。

block 和 non-block 选项用于更改打开设备文件的行为。

默认情况下,ALSA 的行为与原始 OSS 驱动程序相同,即,当文件繁忙时不阻塞文件。在这种情况下,返回 -EBUSY 错误。

可以通过 snd-pcm-oss 的 nonblock_open 模块选项全局更改此阻塞行为。要为 OSS 设备默认使用阻塞模式,请如下定义:

options snd-pcm-oss nonblock_open=0

partial-fragno-silence 命令是最近添加的。这两个命令仅用于优化。前者指定仅在填充整个片段时才调用写入传输。后者停止自动提前写入静音数据。默认情况下,两者均已禁用。

您可以通过读取 proc 文件来检查当前定义的配置。读取的图像可以再次发送到 proc 文件,因此您可以保存当前配置:

% cat /proc/asound/card0/pcm0p/oss > /somewhere/oss-cfg

并像这样恢复它:

% cat /somewhere/oss-cfg > /proc/asound/card0/pcm0p/oss

此外,为了清除所有当前配置,请发送如下所示的 erase 命令:

% echo "erase" > /proc/asound/card0/pcm0p/oss

混音器元素

由于 ALSA 具有完全不同的混音器接口,因此 OSS 混音器的模拟相对复杂。ALSA 基于名称字符串从几个不同的 ALSA(混音器)控件构建混音器元素。例如,音量元素 SOUND_MIXER_PCM 由“PCM Playback Volume”和“PCM Playback Switch”控件组成,用于播放方向,由“PCM Capture Volume”和“PCM Capture Switch”组成,用于捕获目录(如果存在)。当 OSS 的 PCM 音量更改时,会自动调整上述所有音量和开关控件。

默认情况下,ALSA 使用以下控件进行 OSS 音量控制:

OSS 音量

ALSA 控件

索引

SOUND_MIXER_VOLUME

主音量

0

SOUND_MIXER_BASS

音调控制 - 低音

0

SOUND_MIXER_TREBLE

音调控制 - 高音

0

SOUND_MIXER_SYNTH

合成器

0

SOUND_MIXER_PCM

PCM

0

SOUND_MIXER_SPEAKER

PC 扬声器

0

SOUND_MIXER_LINE

线路

0

SOUND_MIXER_MIC

麦克风

0

SOUND_MIXER_CD

CD

0

SOUND_MIXER_IMIX

监听混音

0

SOUND_MIXER_ALTPCM

PCM

1

SOUND_MIXER_RECLEV

(未分配)

SOUND_MIXER_IGAIN

捕获

0

SOUND_MIXER_OGAIN

播放

0

SOUND_MIXER_LINE1

辅助

0

SOUND_MIXER_LINE2

辅助

1

SOUND_MIXER_LINE3

辅助

2

SOUND_MIXER_DIGITAL1

数字

0

SOUND_MIXER_DIGITAL2

数字

1

SOUND_MIXER_DIGITAL3

数字

2

SOUND_MIXER_PHONEIN

电话

0

SOUND_MIXER_PHONEOUT

电话

1

SOUND_MIXER_VIDEO

视频

0

SOUND_MIXER_RADIO

收音机

0

SOUND_MIXER_MONITOR

监听

0

第二列是相应 ALSA 控件的基本字符串。实际上,还会检查带有 XXX [Playback|Capture] [Volume|Switch] 的控件。

这些混音器元素的当前分配列在 proc 文件 /proc/asound/cardX/oss_mixer 中,该文件类似于以下内容:

VOLUME "Master" 0
BASS "" 0
TREBLE "" 0
SYNTH "" 0
PCM "PCM" 0
...

其中第一列是 OSS 音量元素,第二列是相应 ALSA 控件的基本字符串,第三列是控件索引。当字符串为空时,表示相应的 OSS 控件不可用。

要更改分配,您可以将配置写入此 proc 文件。例如,要将“Wave Playback”映射到 PCM 音量,请发送如下命令:

% echo 'VOLUME "Wave Playback" 0' > /proc/asound/card0/oss_mixer

该命令与 proc 文件中列出的命令完全相同。您可以更改一个或多个元素,每行一个音量。在最后一个示例中,更改 PCM 音量时,将同时影响“Wave Playback Volume”和“Wave Playback Switch”。

与 PCM proc 文件的情况一样,proc 文件的权限取决于 snd 的模块选项。您可能需要成为超级用户才能发送上述命令。

与 PCM proc 文件的情况一样,您可以通过读取和写入整个文件图像来保存和恢复当前混音器配置。

双工流

请注意,当尝试将单个设备文件用于播放和捕获时,OSS API 无法设置每个方向上不同的格式、采样率或通道数。因此

io_handle = open("device", O_RDWR)

仅当每个方向上的值相同时才能正常运行。

要在两个方向上使用不同的值,请同时使用

input_handle = open("device", O_RDONLY)
output_handle = open("device", O_WRONLY)

并为相应的句柄设置值。

不支持的功能

ICE1712 驱动程序上的 MMAP

ICE1712 仅支持非常规格式,即交错的 10 通道 24 位(打包在 32 位中)格式。因此,您无法以传统的(单声道或 2 通道,8 或 16 位)格式在 OSS 上 mmap 缓冲区。