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


このモジュールを使うと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

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

(ossaudiodevopen()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 を参照します。

22.9.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)

Write a bytes-like object data to the audio device and return the number of bytes written. If the audio device is in blocking mode (the default), the entire data is always written (again, this is different from usual Unix device semantics). If the device is in non-blocking mode, some data may not be written ---see 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])

主要なオーディオパラメタ、サンプル形式、チャネル数、サンプルレートを一つのメソッド呼び出しで設定します。 formatnchannels および 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" のどれかです。

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

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

oss_mixer_device.close()

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

oss_mixer_device.fileno()

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

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

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

oss_mixer_device.controls()

このメソッドは、利用可能なミキサコントロール (SOUND_MIXER_PCMSOUND_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) に設定します。leftright は整数で、0 (無音) から100 (最大) の間で指定せねばなりません。呼び出しに成功すると新しいボリューム値を 2 要素のタプルで返します。サウンドカードによっては、ミキサの分解能上の制限から、指定したボリュームと厳密に同じにはならない場合があります。

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

oss_mixer_device.get_recsrc()

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

oss_mixer_device.set_recsrc(bitmask)

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

mixer.setrecsrc (1 << ossaudiodev.SOUND_MIXER_MIC)