21.10. "ossaudiodev" --- OSS互換オーディオデバイスへのアクセス
**************************************************************

バージョン 2.3 で追加.

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

参考:

  Open Sound System Programmer's Guide
     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 の 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" を参照します。


21.10.1. オーディオデバイスオブジェクト
=======================================

オーディオデバイスに読み書きできるようになるには、まず 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)

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

oss_audio_device.writeall(data)

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

以下の各メソッドは、厳密に 1 つの "ioctl()" システムコールに対応してい
ます。対応関係は明らかです: 例えば、 "setfmt()" は ioctl の
"SNDCTL_DSP_SETFMT" に対応し、 "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"          | 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"" のどれかです。


21.10.2. ミキサデバイスオブジェクト
===================================

ミキサオブジェクトには、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 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" を、サポートされ
   ていないコントロールを指定した場合は "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)

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

      mixer.setrecsrc (1 << ossaudiodev.SOUND_MIXER_MIC)
