# `ossaudiodev` --- 访问兼容OSS的音频设备

该模块允许您访问 OSS（开放式音响系统）音频接口。 OSS 可用于广泛的开源和商业 Unices，并且是 Linux 和最新版本的 FreeBSD 的标准音频接口。

3.3 版更變: 此模块中过去会引发 `IOError` 的操作现在将引发 `OSError`。

也參考

开放之声系统程序员手册

  OSS C API 的官方文档

该模块定义了大量由OSS设备驱动提供的常量； 请参阅``<sys/soundcard.h>`` Linux 或 FreeBSD 上的列表。

`ossaudiodev` 定义了下列变量和函数:

exception `ossaudiodev.``OSSAudioError`

  此异常会针对特定错误被引发。 其参数为一个描述错误信息的字符串。

  （如果 `ossaudiodev` 从系统调用例如 `open()`, `write()` 或 `ioctl()` 接收到错误，它将引发 `OSError`。 由 `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`。

## 音频设备对象

在你写入或读取音频设备之前，你必须按照正确的顺序调用三个方法:

1. `setfmt()` 设置输出格式

2. `channels()` 设置声道数量

3. `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)

  将一个 bytes-like object data 写入音频设备并返回写入的字节数。 如果音频设备处于阻塞模式（默认），则总是会写入完整数据（这还是不同于通常的 Unix 设备语义）。 如果设备处于非阻塞模式，则可能会有部分数据未被写入 --- 参见 `writeall()`。

  3.5 版更變: 现在支持可写的 字节类对象。

`oss_audio_device.``writeall`(data)

  将一个 bytes-like object data 写入音频设备：等待直到音频设备能够接收数据，将根据其所能接收的数据量尽可能多地写入，并重复操作直至 data 被完全写入。 如果设备处于阻塞模式（默认），则其效果与 `write()` 相同；`writeall()` 仅适用于非阻塞模式。 它没有返回值，因为写入的数据量总是等于所提供的数据量。

  3.5 版更變: 现在支持可写的 字节类对象。

3.2 版更變: 音频设备对象还支持上下文管理协议，就是说它们可以在 `with` 语句中使用。

下列方法各自映射一个 `ioctl()` 系统调用。 对应关系很明显：例如，`setfmt()` 对应 `SNDCTL_DSP_SETFMT` ioctl，而 `sync()` 对应 `SNDCTL_DSP_SYNC` (这在查阅 OSS 文档时很有用)。 如果下层的 `ioctl()` 失败，它们将引发 `OSError`。

`oss_audio_device.``nonblock`()

  将设备转为非阻塞模式。 一旦处于非阻塞模式，将无法将其转回阻塞模式。

`oss_audio_device.``getfmts`()

  返回声卡所支持的音频输出格式的位掩码。 OSS 支持的一部分格式如下:

  文件格式 | 描述
  --- | ---
  `AFMT_MU_LAW` | 一种对数编码格式（被 Sun `.au` 文件和 `/dev/audio` 所使用）
  `AFMT_A_LAW` | 一种对数编码格式
  `AFMT_IMA_ADPCM` | 一种 4:1 压缩格式，由 Interactive Multimedia Association 定义
  `AFMT_U8` | 无符号的 8 位音频
  `AFMT_S16_LE` | Signed, 16-bit audio, little-endian byte order (as used by Intel processors)
  `AFMT_S16_BE` | Signed, 16-bit audio, big-endian byte order (as used by 68k, PowerPC, Sparc)
  `AFMT_S8` | Signed, 8 bit audio
  `AFMT_U16_LE` | Unsigned, 16-bit little-endian audio
  `AFMT_U16_BE` | Unsigned, 16-bit big-endian audio

  Consult the OSS documentation for a full list of audio formats, and note that most devices support only a subset of these formats. Some older devices only support `AFMT_U8`; the most common format used today is `AFMT_S16_LE`.

`oss_audio_device.``setfmt`(format)

  Try to set the current audio format to format---see `getfmts()` for a list. Returns the audio format that the device was set to, which may not be the requested format. May also be used to return the current audio format---do this by passing an "audio format" of `AFMT_QUERY`.

`oss_audio_device.``channels`(nchannels)

  Set the number of output channels to nchannels. A value of 1 indicates monophonic sound, 2 stereophonic. Some devices may have more than 2 channels, and some high-end devices may not support mono. Returns the number of channels the device was set to.

`oss_audio_device.``speed`(samplerate)

  Try to set the audio sampling rate to samplerate samples per second. Returns the rate actually set. Most sound devices don't support arbitrary sampling rates. Common rates are:

  采样率 | 描述
  --- | ---
  8000 | `/dev/audio` 的默认采样率
  11025 | 语音录音
  22050 |
  44100 | CD品质的音频（16位采样和2通道）
  96000 | DVD品质的音频（24位采样）

`oss_audio_device.``sync`()

  Wait until the sound device has played every byte in its buffer. (This happens implicitly when the device is closed.) The OSS documentation recommends closing and re-opening the device rather than using `sync()`.

`oss_audio_device.``reset`()

  Immediately stop playing or recording and return the device to a state where it can accept commands. The OSS documentation recommends closing and re-opening the device after calling `reset()`.

`oss_audio_device.``post`()

  Tell the driver that there is likely to be a pause in the output, making it possible for the device to handle the pause more intelligently. You might use this after playing a spot sound effect, before waiting for user input, or before doing disk I/O.

The following convenience methods combine several ioctls, or one ioctl and some simple calculations.

`oss_audio_device.``setparameters`(format, nchannels, samplerate[, strict=False])

  Set the key audio sampling parameters---sample format, number of channels, and sampling rate---in one method call. format, nchannels, and samplerate should be as specified in the `setfmt()`, `channels()`, and `speed()` methods. If strict is true, `setparameters()` checks to see if each parameter was actually set to the requested value, and raises `OSSAudioError` if not. Returns a tuple (format, nchannels, samplerate) indicating the parameter values that were actually set by the device driver (i.e., the same as the return values of `setfmt()`, `channels()`, and `speed()`).

  For example,

      (fmt, channels, rate) = dsp.setparameters(fmt, channels, rate)

  is equivalent to

      fmt = dsp.setfmt(fmt)
      channels = dsp.channels(channels)
      rate = dsp.rate(rate)

`oss_audio_device.``bufsize`()

  Returns the size of the hardware buffer, in samples.

`oss_audio_device.``obufcount`()

  Returns the number of samples that are in the hardware buffer yet to be played.

`oss_audio_device.``obuffree`()

  Returns the number of samples that could be queued into the hardware buffer to be played without blocking.

Audio device objects also support several read-only attributes:

`oss_audio_device.``closed`

  Boolean indicating whether the device has been closed.

`oss_audio_device.``name`

  String containing the name of the device file.

`oss_audio_device.``mode`

  The I/O mode for the file, either `"r"`, `"rw"`, or `"w"`.

## Mixer Device Objects

The mixer object provides two file-like methods:

`oss_mixer_device.``close`()

  This method closes the open mixer device file. Any further attempts to use the mixer after this file is closed will raise an `OSError`.

`oss_mixer_device.``fileno`()

  Returns the file handle number of the open mixer device file.

3.2 版更變: Mixer objects also support the context management protocol.

The remaining methods are specific to audio mixing:

`oss_mixer_device.``controls`()

  This method returns a bitmask specifying the available mixer controls ("Control" being a specific mixable "channel", such as `SOUND_MIXER_PCM` or `SOUND_MIXER_SYNTH`). This bitmask indicates a subset of all available mixer controls---the `SOUND_MIXER_*` constants defined at module level. To determine if, for example, the current mixer object supports a PCM mixer, use the following Python code:

      mixer=ossaudiodev.openmixer()
      if mixer.controls() & (1 << ossaudiodev.SOUND_MIXER_PCM):
          # PCM is supported
          ... code ...

  For most purposes, the `SOUND_MIXER_VOLUME` (master volume) and `SOUND_MIXER_PCM` controls should suffice---but code that uses the mixer should be flexible when it comes to choosing mixer controls. On the Gravis Ultrasound, for example, `SOUND_MIXER_VOLUME` does not exist.

`oss_mixer_device.``stereocontrols`()

  Returns a bitmask indicating stereo mixer controls. If a bit is set, the corresponding control is stereo; if it is unset, the control is either monophonic or not supported by the mixer (use in combination with `controls()` to determine which).

  See the code example for the `controls()` function for an example of getting data from a bitmask.

`oss_mixer_device.``reccontrols`()

  Returns a bitmask specifying the mixer controls that may be used to record. See the code example for `controls()` for an example of reading from a bitmask.

`oss_mixer_device.``get`(control)

  Returns the volume of a given mixer control. The returned volume is a 2-tuple `(left_volume,right_volume)`. Volumes are specified as numbers from 0 (silent) to 100 (full volume). If the control is monophonic, a 2-tuple is still returned, but both volumes are the same.

  Raises `OSSAudioError` if an invalid control is specified, or `OSError` if an unsupported control is specified.

`oss_mixer_device.``set`(control, (left, right))

  Sets the volume for a given mixer control to `(left,right)`. `left` and `right` must be ints and between 0 (silent) and 100 (full volume). On success, the new volume is returned as a 2-tuple. Note that this may not be exactly the same as the volume specified, because of the limited resolution of some soundcard's mixers.

  Raises `OSSAudioError` if an invalid mixer control was specified, or if the specified volumes were out-of-range.

`oss_mixer_device.``get_recsrc`()

  This method returns a bitmask indicating which control(s) are currently being used as a recording source.

`oss_mixer_device.``set_recsrc`(bitmask)

  Call this function to specify a recording source. Returns a bitmask indicating the new recording source (or sources) if successful; raises `OSError` if an invalid source was specified. To set the current recording source to the microphone input:

      mixer.setrecsrc (1 << ossaudiodev.SOUND_MIXER_MIC)