\section{\module{ossaudiodev} ---
OSS互換オーディオデバイスへのアクセス}

\declaremodule{builtin}{ossaudiodev}
\platform{Linux, FreeBSD}
\modulesynopsis{OSS互換オーディオデバイスへのアクセス。}

\versionadded{2.3}

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

\begin{seealso}
\seetitle[http://www.opensound.com/pguide/oss.pdf]
	{Open Sound System Programmer's Guide}
        {OSS C API の公式ドキュメント}
\seetext{このモジュールではOSSデバイスドライバーが提供している多くの
定数を定義しています; 定数のリストについては Linux や FreeBSDの
\file{<sys/soundcard.h>}を参照してください。}
\end{seealso}

\module{ossaudiodev} では以下の変数と関数を定義しています:

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

(\module{ossaudiodev} が\cfunction{open()}、\cfunction{write()}、
\cfunction{ioctl()} などのシステムコールからエラーを受け取った
場合には \exception{IOError} を送出します。
\module{ossaudiodev} が直接エラーを検出した場合には
\exception{OSSAudioError}になります。) 

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

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

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

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

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

\end{funcdesc}

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

\subsection{オーディオデバイスオブジェクト
\label{ossaudio-device-objects}}

オーディオデバイスに読み書きできるようになるには、まず
3 つのメソッドを正しい順序で呼び出さねばなりません:
\begin{enumerate}
\item 
\method{setfmt()} で出力形式を設定し、
\item 
\method{channels()} でチャンネル数を設定し、
\item 
\method{speed()} でサンプリングレートを設定します。
\end{enumerate}
この代わりに\method{setparameters()} メソッドを呼び出せば、
三つのオーディオパラメタを一度で設定できます。
\method{setparameters()} は便利ですが、多くの状況で
柔軟性に欠けるでしょう。

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

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

\begin{methoddesc}[audio device]{fileno}{}
デバイスに関連付けられているファイル記述子を返します。
\end{methoddesc}

\begin{methoddesc}[audio device]{read}{size}
オーディオ入力から \var{size} バイトを読みだし、 Python 文字列型に
して返します。多くの \UNIX{} デバイスドライバと違い、 
ブロックデバイスモード (デフォルト) の OSS オーディオデバイスでは、
要求した量のデータ全体を取り込むまで\function{read()} がブロックします。
\end{methoddesc}

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

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

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

\begin{methoddesc}[audio device]{nonblock}{}
デバイスを非ブロックモードにします。
いったん非ブロックモードにしたら、ブロックモードは戻せません。
\end{methoddesc}

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

\begin{tableii}{l|l}{constant}{フォーマット}{説明}

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

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

\begin{methoddesc}[audio device]{setfmt}{format}
現在のオーディオ形式を\var{format}に設定しようと試みます ---
\var{format}については\method{getfmts()}のリストを参照してください。
実際にデバイスに設定されたオーディオ形式を返します。要求通りの
形式でないこともあります。\constant{AFMT_QUERY} を渡すと
現在デバイスに設定されているオーディオ形式を返します。
\end{methoddesc}

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

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

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

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

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

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

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

\begin{methoddesc}[audio device]{setparameters}
  {format, nchannels, samplerate, \optional{, strict=False}}

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

以下に例を示します:
\begin{verbatim}
  (fmt, channels, rate) = dsp.setparameters(fmt, channels, rate)
\end{verbatim}
is equivalent to
\begin{verbatim}
  fmt = dsp.setfmt(fmt)
  channels = dsp.channels(channels)
  rate = dsp.rate(channels)
\end{verbatim}
\end{methoddesc}

\begin{methoddesc}[audio device]{bufsize}{}
ハードウェアのバッファサイズをサンプル数で返します。
\end{methoddesc}

\begin{methoddesc}[audio device]{obufcount}{}
ハードウェアバッファ上に残っていてまだ再生されていないサンプル数を返します。
\end{methoddesc}

\begin{methoddesc}[audio device]{obuffree}{}
ブロックを起こさずにハードウェアの再生キューに書き込めるサンプル数を返します。
\end{methoddesc}

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

\begin{memberdesc}[audio device]{closed}{}
デバイスが閉じられたかどうかを示す真偽値です。
\end{memberdesc}

\begin{memberdesc}[audio device]{name}{}
デバイスファイルの名前を含む文字列です。
\end{memberdesc}

\begin{memberdesc}[audio device]{mode}{}
ファイルの I/O モードで、\code{"r"}, \code{"rw"}, \code{"w"} のどれかです。
\end{memberdesc}


\subsection{ミキサデバイスオブジェクト\label{mixer-device-objects}}

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

\begin{methoddesc}[mixer device]{close}{}
すでに開かれているミキサデバイスファイルを閉じます。
ファイルを閉じた後でミキサを使おうとすると、\exception{IOError}を
送出します。
\end{methoddesc}

\begin{methoddesc}[mixer device]{fileno}{}
開かれているミキサデバイスファイルのファイルハンドルナンバを返します。
\end{methoddesc}

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

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

\begin{verbatim}
if mixer.controls() & (1 << ossaudiodev.SOUND_MIXER_PCM):
    # PCM is supported
    ... code ...
\end{verbatim}

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

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

ビットマスクから情報を得る例は関数\method{controls()}のコード例を
参照してください。
\end{methoddesc}

\begin{methoddesc}[mixer device]{reccontrols}{}
録音に使用できるミキサコントロールを特定するビットマスクを返します。
ビットマスクから情報を得る例は関数\method{controls()}のコード例を
参照してください。
\end{methoddesc}

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

不正なコントロールを指定した場合は\exception{OSSAudioError}を送出しま
す。また、サポートされていないコントロールを指定した場合には
\exception{IOError} を送出します。
\end{methoddesc}

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

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

\begin{methoddesc}[mixer device]{get_recsrc}{}
現在録音のソースに使われているコントロールを示すビットマスクを返します。
\end{methoddesc}

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

\begin{verbatim}
mixer.setrecsrc (1 << ossaudiodev.SOUND_MIXER_MIC)
\end{verbatim}
\end{methoddesc}



