# `ossaudiodev` --- OSS互換オーディオデバイスへのアクセス

バージョン 3.11 で非推奨、バージョン 3.13 で削除予定: `ossaudiodev` モジュールは非推奨です (詳細は PEP 594 参照)。

このモジュールを使うとOSS (Open Sound System) オーディオインターフェースにアクセスできます。OSSはオープンソースあるいは商用のUnixで広く利用でき、Linux (カーネル 2.4まで) とFreeBSDで標準のオーディオインターフェースです。

バージョン 3.3 で変更: このモジュールの操作で以前は `IOError` が送出されていたところで `OSError` が送出されるようになりました。

参考

Open Sound System Programmer's Guide

  OSS C API の公式ドキュメント

このモジュールでは、OSS デバイスドライバが提供している大量の定数が定義されています; 一覧は Linux や FreeBSD 上の `<sys/soundcard.h>` を参照してください。

`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 の read/write における意味づけと OSS デバイスの read/write との間には微妙な違いがあります)。また、オーディオ特有の多くのメソッドがあります;メソッドの完全なリストについては下記を参照してください。

  device は使用するオーディオデバイスファイルネームです。もしこれが指定されないなら、このモジュールは使うデバイスとして最初に環境変数 `AUDIODEV` を参照します。見つからなければ `/dev/dsp` を参照します。

  mode は読み出し専用アクセスの場合には `'r'`、書き込み専用 (プレイバック) アクセスの場合には `'w'`、読み書きアクセスの場合には `'rw'` にします。多くのサウンドカードは一つのプロセスが一度にレコーダとプレーヤのどちらかしか開けないようにしているため、必要な操作に応じたデバイスだけを開くようにするのがよいでしょう。また、サウンドカードには半二重 (half- duplex) 方式のものがあります: こうしたカードでは、デバイスを読み出しまたは書き込み用に開くことはできますが、両方同時には開けません。

  呼び出しの文法が普通と異なることに注意してください: 最初の 引数は省略可能で、2番目が必須です。これは `ossaudiodev` にとってかわられた古い `linuxaudiodev` との互換性のためという歴史的な産物です。

ossaudiodev.openmixer([device])

  ミキサデバイスを開き、OSSミキサデバイスオブジェクトを返します。 device は使用するミキサデバイスのファイル名です。 device を指定しない場合、モジュールはまず環境変数 `MIXERDEV` を参照して使用するデバイスを探します。見つからなければ、 `/dev/mixer` を参照します。

## オーディオデバイスオブジェクト

オーディオデバイスに読み書きできるようになるには、まず 3 つのメソッドを正しい順序で呼び出さねばなりません:

1. `setfmt()` で出力形式を設定し

2. `channels()` でチャンネル数を設定し

3. `speed()` でサンプリングレートを設定します

この代わりに `setparameters()` メソッドを呼び出せば、三つのオーディオパラメタを一度で設定できます。 `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 で変更: 書き込み可能な bytes-like object を使用できるようになりました。

oss_audio_device.writeall(data)

  bytes-like object data をオーディオデバイスに書き込みます。オーディオデバイスがデータを受け取れるようになるまで待機し、書き込めるだけのデータを書き込むという操作を、 data を全て書き込み終わるまで繰り返します。デバイスがブロックモード (デフォルト) の場合には、このメソッドは `write()` と同じです。 `writeall()` が有用なのは非ブロックモードだけです。実際に書き込まれたデータの量と渡したデータの量は必ず同じになるので、戻り値はありません。

  バージョン 3.5 で変更: 書き込み可能な bytes-like object を使用できるようになりました。

バージョン 3.2 で変更: オーディオデバイスオブジェクトはコンテキストマネージメントプロトコルをサポートしています。つまり `with` 文で使うことができます。

以下の各メソッドは、厳密に 1 つの `ioctl()` システムコールに対応しています。対応関係は明らかです: 例えば、 `setfmt()` は ioctl の `SNDCTL_DSP_SETFMT` に対応し、 `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` | Interactive Multimedia Association で定義されている 4:1 圧縮形式
  `AFMT_U8` | 符号なし 8 ビットオーディオ
  `AFMT_S16_LE` | 符号つき 16 ビットオーディオ、リトルエンディアンバイトオーダ (Intelプロセッサで使われている形式)
  `AFMT_S16_BE` | 符号つき 16 ビットオーディオ、ビッグエンディアンバイトオーダ (68k、PowerPC、Sparcで使われている形式)
  `AFMT_S8` | 符号つき 8 ビットオーディオ
  `AFMT_U16_LE` | 符号なし 16 ビットリトルエンディアンオーディオ
  `AFMT_U16_BE` | 符号なし 16 ビットビッグエンディアンオーディオ

  オーディオ形式の完全なリストは OSS の文書をひもといてください。ただ、ほとんどのシステムは、こうした形式のサブセットしかサポートしていません。古めのデバイスの中には `AFMT_U8` だけしかサポートしていないものがあります。現在使われている最も一般的な形式は `AFMT_S16_LE` です。

oss_audio_device.setfmt(format)

  現在のオーディオ形式を format に設定しようと試みます --- format については `getfmts()` のリストを参照してください。実際にデバイスに設定されたオーディオ形式を返します。要求通りの形式でないこともあります。 `AFMT_QUERY` を渡すと現在デバイスに設定されているオーディオ形式を返します。

oss_audio_device.channels(nchannels)

  出力チャネル数を nchannels に設定します。1 はモノラル、2 はステレオです。いくつかのデバイスでは2つより多いチャンネルを持つものもありますし、ハイエンドなデバイスではモノラルをサポートしないものもあります。デバイスに設定されたチャンネル数を返します。

oss_audio_device.speed(samplerate)

  サンプリングレートを1秒あたり samplerate に設定しようと試み、実際に設定されたレートを返します。たいていのサウンドデバイスでは任意のサンプリングレートをサポートしていません。一般的なレートは以下の通りです:

  レート | 説明
  --- | ---
  8000 | `/dev/audio` のデフォルト
  11025 | 会話音声の録音に使われるレート
  22050 |
  44100 | (サンプルあたり 16 ビットで 2 チャネルの場合) CD 品質のオーディオ
  96000 | (サンプル当たり 24 ビットの場合) DVD 品質のオーディオ

oss_audio_device.sync()

  サウンドデバイスがバッファ内の全てのデータを再生し終えるまで待機します。 (デバイスを閉じると暗黙のうちに `sync()` が起こります) OSS のドキュメント上では、 `sync()` を使うよりデバイスを一度閉じて開き直すよう勧めています。

oss_audio_device.reset()

  再生あるいは録音を即座に中止して、デバイスをコマンドを受け取れる状態に戻します。OSSのドキュメントでは、 `reset()` を呼び出した後に一度デバイスを閉じ、開き直すよう勧めています。

oss_audio_device.post()

  ドライバに出力の一時停止 (pause) が起きそうであることを伝え、ドライバが一時停止をより賢く扱えるようにします。短いサウンドエフェクトを再生した直後やユーザ入力待ちの前、またディスク I/O 前などに使うことになるでしょう。

以下のメソッドは、複数の `ioctl()` を組み合わせたり、`ioctl()` と単純な計算を組み合わせたりした便宜用メソッドです。

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

  主要なオーディオパラメタ、サンプル形式、チャネル数、サンプルレートを一つのメソッド呼び出しで設定します。 format 、 nchannels および samplerate には、それぞれ `setfmt()` 、 `channels()` および `speed()` と同じやり方で値を設定します。 strict の値が真の場合、 `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"` のどれかです。

## ミキサデバイスオブジェクト

ミキサオブジェクトには、2つのファイル類似メソッドがあります:

oss_mixer_device.close()

  このメソッドは開いているミキサデバイスオブジェクトを閉じます。このファイルを閉じた後もミキサを使おうとすると、 `OSError` が送出されます。

oss_mixer_device.fileno()

  開かれているミキサデバイスファイルのファイルハンドルナンバを返します。

バージョン 3.2 で変更: ミキサオブジェクトはコンテキストマネージメントプロトコルもサポートします。

以下はオーディオミキシング固有のメソッドです:

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 Ultrasound には `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要素のタプルが返されますが、2つの要素の値は同じになります。

  不正なコントロールを指定した場合は `OSSAudioError` を、サポートされていないコントロールを指定した場合は `OSError` を送出します。

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)

  録音のソースを指定するために、この関数を呼び出します。成功した場合は、新しい録音のソース (1 つもしくは複数) を示すビットマスクを返します; 不正なソースを指定した場合は、 `OSError` を送出します。現在の録音のソースをマイク入力に設定するには以下のように呼び出します:

      mixer.setrecsrc (1 << ossaudiodev.SOUND_MIXER_MIC)