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

.. module:: ossaudiodev
   :platform: Linux, FreeBSD
   :synopsis: OSS互換オーディオデバイスへのアクセス。


.. versionadded:: 2.3

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


.. seealso::

   `Open Sound System Programmer's Guide <http://www.opensound.com/pguide/oss.pdf>`_
      OSS C API の公式ドキュメント

   このモジュールではOSSデバイスドライバーが提供している多くの定数を定義しています; 定数のリストについては Linux や FreeBSDの
   :file:`<sys/soundcard.h>` を参照してください。

:mod:`ossaudiodev` では以下の変数と関数を定義しています:


.. exception:: error

   何らかのエラーのときに送出される例外です。引数は何が誤っているかを示す文字列です。

   (:mod:`ossaudiodev` が :c:func:`open` 、 :c:func:`write` 、 :c:func:`ioctl`
   などのシステムコールからエラーを受け取った場合には :exc:`IOError` を送出します。 :mod:`ossaudiodev`
   が直接エラーを検出した場合には :exc:`OSSAudioError` になります。)

   (以前のバージョンとの互換性のため、この例外クラスは ``ossaudiodev.error`` としても利用できます。)


.. function:: open([device, ]mode)

   オーディオデバイスを開き、OSSオーディオデバイスオブジェクトを返します。
   このオブジェクトは :meth:`read` 、 :meth:`write` 、 :meth:`fileno`
   といったファイル類似オブジェクトのメソッドを数多くサポートしています。 (とはいえ、伝統的な Unix の read/write における意味づけと OSS
   デバイスの read/write との間には微妙な違いがあります)。また、オーディオ特有の多くのメソッドがあります;メソッドの完全なリストに
   ついては下記を参照してください。

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

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

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


.. function:: openmixer([device])

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


.. _ossaudio-device-objects:

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

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

#. :meth:`setfmt` で出力形式を設定し、

#. :meth:`channels` でチャンネル数を設定し、

#. :meth:`speed` でサンプリングレートを設定します。

この代わりに :meth:`setparameters` メソッドを呼び出せば、三つのオーディオパラメタを一度で設定できます。
:meth:`setparameters` は便利ですが、多くの状況で柔軟性に欠けるでしょう。

:func:`.open` の返すオーディオデバイスオブジェクトには以下のメソッドおよび(読み出し専用の)属性があります:


.. method:: oss_audio_device.close()

   オーディオデバイスを明示的に閉じます。オーディオデバイスは、読み出しや書き込みが終了したら必ず閉じねばなりません。閉じたオブジェクトを再度開くことは
   できません。


.. method:: oss_audio_device.fileno()

   デバイスに関連付けられているファイル記述子を返します。


.. method:: oss_audio_device.read(size)

   オーディオ入力から *size* バイトを読みだし、 Python 文字列型にして返します。多くの Unix デバイスドライバと違い、
   ブロックデバイスモード (デフォルト) の OSS オーディオデバイスでは、要求した量のデータ全体を取り込むまで :func:`read` がブロックします。


.. method:: oss_audio_device.write(data)

   Python 文字列 *data* の内容をオーディオデバイスに書き込み、書き込まれたバイト数を返します。オーディオデバイスがブロックモード (デフォルト)
   の場合、常に文字列データ全体を書き込みます (前述のように、これは通常のUnix デバイスの振舞いとは異なります)。
   デバイスが非ブロックモードの場合、データの一部が書き込まれないことがあります --- :meth:`writeall` を参照してください。


.. method:: oss_audio_device.writeall(data)

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

以下のメソッドの各々は :func:`ioctl` システムコール一つ一つに対応しています。対応関係ははっきりしています:
例えば、 :meth:`setfmt` は ``SNDCTL_DSP_SETFMT`` ioctl に対応していますし、 :meth:`sync`
は ``SNDCTL_DSP_SYNC`` に対応しています (このシンボル名は OSS のドキュメントを参照する時に助けになるでしょう)。根底にある
:func:`ioctl` が失敗した場合、これらの関数は全て :exc:`IOError` を送出します。


.. method:: oss_audio_device.nonblock()

   デバイスを非ブロックモードにします。いったん非ブロックモードにしたら、ブロックモードは戻せません。


.. method:: oss_audio_device.getfmts()

   サウンドカードがサポートしているオーディオ出力形式をビットマスクで返します。以下はOSSでサポートされているフォーマットの一部です。

   +-------------------------+---------------------------------------------------------------+
   | フォーマット            | 説明                                                          |
   +=========================+===============================================================+
   | :const:`AFMT_MU_LAW`    | 対数符号化 (Sun の ``.au`` 形式や :file:`/dev/audio`          |
   |                         | で使われている形式)                                           |
   +-------------------------+---------------------------------------------------------------+
   | :const:`AFMT_A_LAW`     | 対数符号化                                                    |
   +-------------------------+---------------------------------------------------------------+
   | :const:`AFMT_IMA_ADPCM` | Interactive Multimedia Association で                         |
   |                         | 定義されている 4:1 圧縮形式                                   |
   +-------------------------+---------------------------------------------------------------+
   | :const:`AFMT_U8`        | 符号なし 8 ビットオーディオ                                   |
   +-------------------------+---------------------------------------------------------------+
   | :const:`AFMT_S16_LE`    | 符号つき 16 ビットオーディオ、リトルエンディアンバイトオーダ  |
   |                         | (Intelプロセッサで使われている形式)                           |
   +-------------------------+---------------------------------------------------------------+
   | :const:`AFMT_S16_BE`    | 符号つき 16 ビットオーディオ、ビッグエンディアンバイトオーダ  |
   |                         | (68k、PowerPC、Sparcで使われている形式)                       |
   +-------------------------+---------------------------------------------------------------+
   | :const:`AFMT_S8`        | 符号つき 8 ビットオーディオ                                   |
   +-------------------------+---------------------------------------------------------------+
   | :const:`AFMT_U16_LE`    | 符号なし 16 ビットリトルエンディアンオーディオ                |
   +-------------------------+---------------------------------------------------------------+
   | :const:`AFMT_U16_BE`    | 符号なし 16 ビットビッグエンディアンオーディオ                |
   +-------------------------+---------------------------------------------------------------+

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


.. method:: oss_audio_device.setfmt(format)

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


.. method:: oss_audio_device.channels(num_channels)

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


.. method:: oss_audio_device.speed(samplerate)

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

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


.. method:: oss_audio_device.sync()

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


.. method:: oss_audio_device.reset()

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


.. method:: oss_audio_device.post()

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

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


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

   主要なオーディオパラメタ、サンプル形式、チャネル数、サンプルレートを一つのメソッド呼び出しで設定します。 *format* 、 *nchannels* および
   *samplerate* には、それぞれ :meth:`setfmt` 、 :meth:`channels` および :meth:`speed`
   と同じやり方で値を設定します。 *strict* の値が真の場合、 :meth:`setparameters` は値が実際に要求通りにデバイスに設定されたか
   どうか調べ、違っていれば :exc:`OSSAudioError` を送出します。実際にデバイスドライバが設定したパラメタ値を表す  (*format*,
   *nchannels*, *samplerate*) からなるタプルを返します (:meth:`setfmt` 、 :meth:`channels` および
   :meth:`speed` の返す値と同じです)。

   以下に例を示します::

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

   これは、以下と同等です ::

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


.. method:: oss_audio_device.bufsize()

   ハードウェアのバッファサイズをサンプル数で返します。


.. method:: oss_audio_device.obufcount()

   ハードウェアバッファ上に残っていてまだ再生されていないサンプル数を返します。


.. method:: oss_audio_device.obuffree()

   ブロックを起こさずにハードウェアの再生キューに書き込めるサンプル数を返します。

オーディオデバイスオブジェクトは読み出し専用の属性もサポートしています:


.. attribute:: oss_audio_device.closed

   デバイスが閉じられたかどうかを示す真偽値です。


.. attribute:: oss_audio_device.name

   デバイスファイルの名前を含む文字列です。


.. attribute:: oss_audio_device.mode

   ファイルの I/O モードで、 ``"r"``, ``"rw"``, ``"w"`` のどれかです。


.. _mixer-device-objects:

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

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


.. method:: oss_mixer_device.close()

   すでに開かれているミキサデバイスファイルを閉じます。ファイルを閉じた後でミキサを使おうとすると、 :exc:`IOError` を送出します。


.. method:: oss_mixer_device.fileno()

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

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


.. method:: oss_mixer_device.controls()

   このメソッドは、利用可能なミキサコントロール (:const:`SOUND_MIXER_PCM` や :const:`SOUND_MIXER_SYNTH`
   のように、ミキシングを行えるチャネル) を指定するビットマスクを返します。このビットマスクは利用可能な全てのミキサコントロールのサブセットです ---
   定数 :const:`SOUND_MIXER_\*` はモジュールレベルで定義されています。例えば、もし現在のミキサオブジェクトがPCM
   ミキサをサポートしているか調べるには、以下のPythonコードを実行します::

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

   ほとんどの用途には、 :const:`SOUND_MIXER_VOLUME` (マスタボリューム)
   と :const:`SOUND_MIXER_PCM` コントロールがあれば十分でしょう --- とはいえ、ミキサを使うコードを書くときには、コントロールを選ぶ時に
   柔軟性を持たせるべきです。例えば Gravis Ultrasound には :const:`SOUND_MIXER_VOLUME` がありません。


.. method:: oss_mixer_device.stereocontrols()

   ステレオミキサコントロールを示すビットマスクを返します。ビットが立っているコントロールはステレオであることを示し、立っていない
   コントロールはモノラルか、ミキサがサポートしていないコントロールである (どちらの理由かは :meth:`controls` と組み合わせて使うことで
   判別できます) ことを示します。

   ビットマスクから情報を得る例は関数 :meth:`controls` のコード例を参照してください。


.. method:: oss_mixer_device.reccontrols()

   録音に使用できるミキサコントロールを特定するビットマスクを返します。ビットマスクから情報を得る例は関数 :meth:`controls` のコード例を
   参照してください。


.. method:: oss_mixer_device.get(control)

   指定したミキサコントロールのボリュームを返します。 2 要素のタプル ``(left_volume,right_volume)`` を返します。ボリュームの値は
   0 (無音) から100 (最大) で示されます。コントロールがモノラルでも2要素のタプルが返されますが、2つの要素の値は同じになります。

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


.. method:: oss_mixer_device.set(control, (left, right))

   指定したミキサコントロールのボリュームを ``(left,right)`` に設定します。 ``left`` と ``right`` は整数で、0 (無音) から100
   (最大) の間で指定せねばなりません。呼び出しに成功すると新しいボリューム値を 2 要素のタプルで返します。
   サウンドカードによっては、ミキサの分解能上の制限から、指定したボリュームと厳密に同じにはならない場合があります。

   不正なコントロールを指定した場合や、指定したボリューム値が範囲外であった場合、 :exc:`IOError` を送出します。


.. method:: oss_mixer_device.get_recsrc()

   現在録音のソースに使われているコントロールを示すビットマスクを返します。


.. method:: oss_mixer_device.set_recsrc(bitmask)

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

      mixer.setrecsrc (1 << ossaudiodev.SOUND_MIXER_MIC)

