关于内核 OSS 仿真的说明¶
2004 年 1 月 22 日 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
。请注意,您不能使用别名作为目标名称(即 alias sound-slot-0 snd-card-0
不再像旧的 modutils 那样工作)。
当前可用的 OSS 配置显示在 /proc/asound/oss/sndstat 中。这显示在与 /dev/sndstat 相同的语法中,该语法在商业 OSS 驱动程序上可用。在 ALSA 上,您可以将 /dev/sndstat 符号链接到此 proc 文件。
请注意,此 proc 文件中列出的设备仅在加载相应的 OSS 仿真模块后才会出现。即使其中显示“未在 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-frag
和 no-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 回放音量”和“PCM 回放开关”控件以及捕获目录(如果存在)的“PCM 捕获音量”和“PCM 捕获开关”控件组成。当 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 文件。例如,要将“波形播放”映射到 PCM 音量,请发送如下命令:
% echo 'VOLUME "Wave Playback" 0' > /proc/asound/card0/oss_mixer
该命令与 proc 文件中列出的命令完全相同。您可以更改一个或多个元素,每行一个音量。在最后一个示例中,当 PCM 音量更改时,“波形播放音量”和“波形播放开关”都将受到影响。
与 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 位)格式。因此,您无法在 OSS 上将缓冲区 mmap 为传统的(单声道或 2 通道,8 位或 16 位)格式。