21.10. ossaudiodev — 访问兼容 OSS 的音频设备 — Python 文档
21.10. ossaudiodev — 访问兼容 OSS 的音频设备
2.3 版中的新功能。
该模块允许您访问 OSS(开放式音响系统)音频接口。 OSS 可用于广泛的开源和商业 Unices,并且是 Linux 和 FreeBSD 最新版本的标准音频接口。
也可以看看
- 开放式音响系统程序员指南
- OSS C API 的官方文档
该模块定义了大量由OSS设备驱动提供的常量; 有关列表,请参阅 Linux 或 FreeBSD 上的 <sys/soundcard.h>
。
ossaudiodev 定义了以下变量和函数:
- exception ossaudiodev.OSSAudioError
某些错误会引发此异常。 参数是一个字符串,描述出了什么问题。
(如果 ossaudiodev 收到来自系统调用的错误,例如
open()
、write()
或ioctl()
,它会引发IOError
。 ossaudiodev 直接检测到的错误会导致 OSSAudioError。)(为了向后兼容,异常类也可用作
ossaudiodev.error
。)
- ossaudiodev.open(mode)
ossaudiodev.open(device, mode) 打开一个音频设备并返回一个OSS音频设备对象。 该对象支持许多类文件的方法,例如
read()
、write()
和fileno()
(尽管传统Unix读/写语义与OSS音频的语义有细微差别)设备)。 它还支持许多特定于音频的方法; 有关方法的完整列表,请参见下文。device 是要使用的音频设备文件名。 如果未指定,则该模块首先在环境变量
AUDIODEV
中查找要使用的设备。 如果没有找到,则回退到/dev/dsp
。mode 是用于只读(记录)访问的
'r'
、用于只写(回放)访问的'w'
和用于两者的'rw'
之一。 由于许多声卡一次只允许一个进程打开录音机或播放器,因此最好只为需要的活动打开设备。 此外,一些声卡是半双工的:它们可以打开进行读取或写入,但不能同时打开。注意不寻常的调用语法:first 参数是可选的,第二个是必需的。 这是与 ossaudiodev 取代的旧
linuxaudiodev
模块兼容的历史神器。
- ossaudiodev.openmixer([device])
- 打开一个混合器设备并返回一个 OSS 混合器设备对象。 device 是要使用的混音器设备文件名。 如果未指定,则该模块首先在环境变量
MIXERDEV
中查找要使用的设备。 如果没有找到,则回退到/dev/mixer
。
21.10.1。 音频设备对象
在您可以写入或读取音频设备之前,您必须以正确的顺序调用三个方法:
setfmt()
设置输出格式channels()
设置通道数speed()
设置采样率
或者,您可以使用 setparameters()
方法一次设置所有三个音频参数。 这更方便,但可能不是在所有情况下都那么灵活。
open() 返回的音频设备对象定义了以下方法和(只读)属性:
- oss_audio_device.close()
- 显式关闭音频设备。 当您完成对音频设备的写入或读取后,您应该明确关闭它。 关闭的设备不能再次使用。
- oss_audio_device.fileno()
- 返回与设备关联的文件描述符。
- oss_audio_device.read(size)
- 从音频输入中读取 size 字节并将它们作为 Python 字符串返回。 与大多数 Unix 设备驱动程序不同,处于阻塞模式(默认)的 OSS 音频设备将阻塞 read() 直到所有请求的数据量可用。
- oss_audio_device.write(data)
- 将 Python 字符串 data 写入音频设备并返回写入的字节数。 如果音频设备处于阻塞模式(默认),则始终写入整个字符串(同样,这与通常的 Unix 设备语义不同)。 如果设备处于非阻塞模式,一些数据可能不会被写入——参见 writeall()。
- oss_audio_device.writeall(data)
- 将整个 Python 字符串 data 写入音频设备:等待音频设备能够接受数据,写入尽可能多的数据,并重复直到 data 已经完全书面。 如果设备处于阻塞模式(默认),这与 write() 具有相同的效果; writeall() 仅在非阻塞模式下有用。 没有返回值,因为写入的数据量总是等于提供的数据量。
以下方法分别映射到一个 ioctl()
系统调用。 对应关系很明显:例如,setfmt()
对应于 SNDCTL_DSP_SETFMT
ioctl,而 sync()
对应于 SNDCTL_DSP_SYNC
(这在查阅 OSS 文档时会很有用) . 如果底层的 ioctl()
失败,它们都会提高 IOError
。
- oss_audio_device.nonblock()
- 将设备置于非阻塞模式。 一旦进入非阻塞模式,就无法将其返回到阻塞模式。
- oss_audio_device.getfmts()
返回声卡支持的音频输出格式的位掩码。 OSS支持的一些格式是:
格式
描述
AFMT_MU_LAW
对数编码(用于 Sun
.au
文件和/dev/audio
)AFMT_A_LAW
对数编码
AFMT_IMA_ADPCM
交互式多媒体协会定义的 4:1 压缩格式
AFMT_U8
无符号 8 位音频
AFMT_S16_LE
有符号的 16 位音频小端字节顺序(由英特尔处理器使用)
AFMT_S16_BE
有符号、16 位音频、大端字节序(68k、PowerPC、Sparc 使用)
AFMT_S8
有符号的 8 位音频
AFMT_U16_LE
无符号的 16 位小端音频
AFMT_U16_BE
无符号的 16 位大端音频
有关音频格式的完整列表,请参阅 OSS 文档,并注意大多数设备仅支持这些格式的一个子集。 一些较旧的设备仅支持 [X32X]; 今天最常用的格式是
AFMT_S16_LE
。
- oss_audio_device.setfmt(format)
- 尝试将当前音频格式设置为 format—列表参见 getfmts()。 返回设备设置的音频格式,这可能不是请求的格式。 也可用于返回当前的音频格式——通过传递
AFMT_QUERY
的“音频格式”来实现。
- oss_audio_device.channels(nchannels)
- 将输出通道数设置为 nchannels。 值 1 表示单声道,2 表示立体声。 有些设备可能有 2 个以上的通道,有些高端设备可能不支持单声道。 返回设备设置的通道数。
- oss_audio_device.speed(samplerate)
尝试将音频采样率设置为每秒 samplerate 个样本。 返回实际设置的费率。 大多数声音设备不支持任意采样率。 常见的费率是:
速度
描述
8000
/dev/audio
的默认费率11025
录音
22050
44100
CD 质量音频(16 位/样本和 2 通道)
96000
DVD 质量音频(24 位/样本)
- oss_audio_device.sync()
- 等到声音设备播放完其缓冲区中的每个字节。 (这会在设备关闭时隐式发生。)OSS 文档建议关闭并重新打开设备,而不是使用 sync()。
- oss_audio_device.reset()
- 立即停止播放或录制并将设备返回到可以接受命令的状态。 OSS 文档建议在调用 reset() 后关闭并重新打开设备。
- oss_audio_device.post()
- 告诉驱动程序输出中可能有暂停,使设备可以更智能地处理暂停。 您可以在播放现场音效之后、等待用户输入之前或进行磁盘 I/O 之前使用它。
以下方便的方法结合了几个 ioctl,或者一个 ioctl 和一些简单的计算。
- oss_audio_device.setparameters(format, nchannels, samplerate[, strict=False])
在一个方法调用中设置关键音频采样参数——采样格式、通道数和采样率。 format、nchannels 和 samplerate 应按照 setfmt()、channels()、和 speed() 方法。 如果 strict 为 true,则 setparameters() 检查每个参数是否实际设置为请求的值,如果不是,则引发 OSSAudioError。 返回一个元组 (format, nchannels, samplerate) 表示设备驱动程序实际设置的参数值(即与setfmt()、channels() 和 speed())。
例如,
(fmt, channels, rate) = dsp.setparameters(fmt, channels, rate)
相当于
fmt = dsp.setfmt(fmt) channels = dsp.channels(channels) rate = dsp.rate(rate)
- oss_audio_device.bufsize()
- 返回硬件缓冲区的大小,以样本为单位。
- oss_audio_device.obufcount()
- 返回硬件缓冲区中尚未播放的样本数。
- oss_audio_device.obuffree()
- 返回可以排队进入硬件缓冲区以在不阻塞的情况下播放的样本数。
音频设备对象还支持几个只读属性:
- oss_audio_device.closed
- 指示设备是否已关闭的布尔值。
- oss_audio_device.name
- 包含设备文件名称的字符串。
- oss_audio_device.mode
- 文件的 I/O 模式,
"r"
、"rw"
或"w"
。
21.10.2. 混合器设备对象
混音器对象提供了两种类似文件的方法:
- oss_mixer_device.close()
- 此方法关闭打开的混音器设备文件。 在此文件关闭后任何进一步尝试使用混音器都会引发
IOError
。
- oss_mixer_device.fileno()
- 返回打开的混频器设备文件的文件句柄号。
其余方法特定于音频混合:
- oss_mixer_device.controls()
此方法返回一个位掩码,指定可用的混音器控件(“控件”是特定的可混音“通道”,例如
SOUND_MIXER_PCM
或SOUND_MIXER_SYNTH
)。 此位掩码表示所有可用混音器控件的子集——在模块级别定义的SOUND_MIXER_*
常量。 例如,要确定当前混音器对象是否支持 PCM 混音器,请使用以下 Python 代码:mixer=ossaudiodev.openmixer() if mixer.controls() & (1 << ossaudiodev.SOUND_MIXER_PCM): # PCM is supported ... code ...
对于大多数用途,
SOUND_MIXER_VOLUME
(主音量)和SOUND_MIXER_PCM
控件应该就足够了——但是在选择混音器控件时,使用混音器的代码应该是灵活的。 例如,在 Gravis 超声上,SOUND_MIXER_VOLUME
不存在。
- oss_mixer_device.stereocontrols()
返回指示立体声混音器控件的位掩码。 如果设置了一个位,则相应的控制是立体声; 如果未设置,则该控件要么是单声道的,要么不受混音器支持(与 controls() 结合使用以确定哪个)。
有关从位掩码获取数据的示例,请参阅 controls() 函数的代码示例。
- oss_mixer_device.reccontrols()
- 返回一个位掩码,指定可用于录制的混音器控件。 有关从位掩码读取的示例,请参阅 controls() 的代码示例。
- oss_mixer_device.get(control)
返回给定混音器控件的音量。 返回的卷是一个 2 元组
(left_volume,right_volume)
。 音量指定为从 0(静音)到 100(全音量)的数字。 如果控件是单声道的,仍会返回一个 2 元组,但两个音量相同。如果指定了无效控件,则引发 OSSAudioError,如果指定了不受支持的控件,则引发
IOError
。
- oss_mixer_device.set(control, (left, right))
将给定混音器控件的音量设置为
(left,right)
。left
和right
必须是整数并且介于 0(静音)和 100(全音量)之间。 成功后,新卷将作为 2 元组返回。 请注意,这可能与指定的音量不完全相同,因为某些声卡混音器的分辨率有限。如果指定了无效的混音器控件,或者指定的音量超出范围,则引发 OSSAudioError。
- oss_mixer_device.get_recsrc()
- 此方法返回一个位掩码,指示当前将哪些控件用作记录源。
- oss_mixer_device.set_recsrc(bitmask)
调用此函数指定录音源。 如果成功,则返回指示新录制源(或多个源)的位掩码; 如果指定了无效源,则引发
IOError
。 将当前录音源设置为麦克风输入:mixer.setrecsrc (1 << ossaudiodev.SOUND_MIXER_MIC)