"audioop" — 生の音声データを操作する
************************************

The "audioop" module contains some useful operations on sound
fragments. It operates on sound fragments consisting of signed integer
samples 8, 16 or 32 bits wide, stored in Python strings.  This is the
same format as used by the "al" and "sunaudiodev" modules.  All scalar
items are integers, unless specified otherwise.

このモジュールはa-LAW、u-LAWそしてIntel/DVI ADPCMエンコードをサポート
しています。

複雑な操作のうちいくつかはサンプル幅が 16 ビットのデータに対してのみ働
きますが、それ以外は常にサンプル幅を操作のパラメタとして (バイト単位で
) 渡します。

このモジュールでは以下の変数と関数を定義しています:

exception audioop.error

   この例外は、未知のサンプル当たりのバイト数を指定した時など、全般的
   なエラーに対して送出されます。

audioop.add(fragment1, fragment2, width)

   Return a fragment which is the addition of the two samples passed
   as parameters. *width* is the sample width in bytes, either "1",
   "2" or "4".  Both fragments should have the same length.  Samples
   are truncated in case of overflow.

audioop.adpcm2lin(adpcmfragment, width, state)

   Intel/DVI ADPCM 形式のデータをリニア (linear) 形式にデコードします
   。 ADPCM 符号化方式の詳細については "lin2adpcm()" の説明を参照して
   下さい。 "(sample, newstate)" からなるタプルを返し、サンプルは
   *width* に指定した幅になります。

audioop.alaw2lin(fragment, width)

   a-LAW形式のデータをリニア (linear) 形式に変換します。a-LAW形式は常
   に 8 ビットのサンプルを使用するので、ここでは *width* は単に出力デ
   ータのサンプル幅となります。

   バージョン 2.5 で追加.

audioop.avg(fragment, width)

   データ中の全サンプルの平均値を返します。

audioop.avgpp(fragment, width)

   データ中の全サンプルの平均 peak-peak 振幅を返します。フィルタリング
   を行っていない場合、このルーチンの有用性は疑問です。

audioop.bias(fragment, width, bias)

   元の音声データの各サンプルにバイアスを加算した音声データを返します
   。オーバーフローした場合はラップアラウンドされます。

audioop.cross(fragment, width)

   引数に渡したデータ中のゼロ交差回数を返します。

audioop.findfactor(fragment, reference)

   "rms(add(fragment, mul(reference, -F)))" を最小にするような係数 *F*
   、すなわち、*reference* に乗算したときにもっとも *fragment* に近く
   なるような値を返します。*fragment* と *reference* のサンプル幅はい
   ずれも 2バイトでなければなりません。

   このルーチンの実行に要する時間は "len(fragment)" に比例します。

audioop.findfit(fragment, reference)

   *reference* を可能な限り *fragment* に一致させようとします
   (*fragment* は *reference* より長くなければなりません)。この処理は
   (概念的には) *fragment* からスライスをいくつか取り出し、それぞれに
   ついて "findfactor()" を使って最良な一致を計算し、誤差が最小の結果
   を選ぶことで実現します。 *fragment* と *reference* のサンプル幅は両
   方とも2バイトでなければなりません。 "(offset, factor)" からなるタプ
   ルを返します。 *offset* は最適な一致箇所が始まる *fragment* のオフ
   セット値（整数）で、 *factor* は "findfactor()" の返す係数 (浮動小
   数点数) です。

audioop.findmax(fragment, length)

   *fragment* から、長さが *length* サンプル (バイトではありません!)
   で最大のエネルギーを持つスライス、すなわち、
   "rms(fragment[i*2:(i+length)* 2])" を最大にするようなスライスを探し
   、*i* を返します。データのはサンプル幅は 2バイトでなければなりませ
   ん。

   このルーチンの実行に要する時間は "len(fragment)" に比例します。

audioop.getsample(fragment, width, index)

   データ中の *index* サンプル目の値を返します。

audioop.lin2adpcm(fragment, width, state)

   データを 4 ビットの Intel/DVI ADPCM 符号化方式に変換します。ADPCM
   符号化方式とは適応符号化方式の一つで、あるサンプルと (可変の) ステ
   ップだけ離れたその次のサンプルとの差を 4 ビットの整数で表現する方式
   です。Intel/DVI ADPCMアルゴリズムは IMA  (国際MIDI協会) に採用され
   ているので、おそらく標準になるはずです。

   *state* はエンコーダの内部状態が入ったタプルです。エンコーダは
   "(adpcmfrag, newstate)" のタプルを返し、次に "lin2adpcm()" を呼び出
   す時に *newstate* を渡さねばなりません。最初に呼び出す時には
   *state* に "None" を渡してもかまいません。 *adpcmfrag* は ADPCMで符
   号化されたデータで、バイト当たり 2 つの4ビット値がパックされていま
   す。

audioop.lin2alaw(fragment, width)

   Convert samples in the audio fragment to a-LAW encoding and return
   this as a Python string.  a-LAW is an audio encoding format whereby
   you get a dynamic range of about 13 bits using only 8 bit samples.
   It is used by the Sun audio hardware, among others.

   バージョン 2.5 で追加.

audioop.lin2lin(fragment, width, newwidth)

   Convert samples between 1-, 2- and 4-byte formats.

   注釈: In some audio formats, such as .WAV files, 16 and 32 bit
     samples are signed, but 8 bit samples are unsigned.  So when
     converting to 8 bit wide samples for these formats, you need to
     also add 128 to the result:

        new_frames = audioop.lin2lin(frames, old_width, 1)
        new_frames = audioop.bias(new_frames, 1, 128)

     The same, in reverse, has to be applied when converting from 8 to
     16 or 32 bit width samples.

audioop.lin2ulaw(fragment, width)

   Convert samples in the audio fragment to u-LAW encoding and return
   this as a Python string.  u-LAW is an audio encoding format whereby
   you get a dynamic range of about 14 bits using only 8 bit samples.
   It is used by the Sun audio hardware, among others.

audioop.max(fragment, width)

   音声データ全サンプルの *絶対値* の最大値を返します。

audioop.maxpp(fragment, width)

   音声データの最大 peak-peak 振幅を返します。

audioop.minmax(fragment, width)

   音声データ全サンプル中における最小値と最大値からなるタプルを返しま
   す。

audioop.mul(fragment, width, factor)

   元の音声データの各サンプルに浮動小数点数 *factor* を乗算した音声デ
   ータを返します。オーバーフローした場合は切り捨てられます。

audioop.ratecv(fragment, width, nchannels, inrate, outrate, state[, weightA[, weightB]])

   入力したデータのフレームレートを変換します。

   *state* は変換ルーチンの内部状態を入れたタプルです。変換ルーチンは
   "(newfragment, newstate)" を返し、次に "ratecv()" を呼び出す時には
   *newstate* を渡さなねばなりません。最初の呼び出しでは "None" を渡し
   ます。

   引数 *weightA* と *weightB* は単純なデジタルフィルタのパラメタで、
   デフォルト値はそれぞれ "1" と "0" です。

audioop.reverse(fragment, width)

   データ内のサンプルの順序を逆転し、変更されたデータを返します。

audioop.rms(fragment, width)

   データの自乗平均根(root-mean-square)、すなわち "sqrt(sum(S_i^2)/n)"
   を返します。

   これはオーディオ信号の強度 (power) を測る一つの目安です。

audioop.tomono(fragment, width, lfactor, rfactor)

   ステレオ音声データをモノラル音声データに変換します。左チャネルのデ
   ータに *lfactor*、右チャネルのデータに *rfactor* を掛けた後、二つの
   チャネルの値を加算して単一チャネルの信号を生成します。

audioop.tostereo(fragment, width, lfactor, rfactor)

   モノラル音声データをステレオ音声データに変換します。ステレオ音声デ
   ータの各サンプル対は、モノラル音声データの各サンプルをそれぞれ左チ
   ャネルは *lfactor* 倍、右チャネルは *rfactor* 倍して生成します。

audioop.ulaw2lin(fragment, width)

   u-LAW で符号化されている音声データを線形に符号化された音声データに
   変換します。u-LAW 符号化は常にサンプル当たり 8 ビットを使うため、
   *width* は出力音声データのサンプル幅にしか使われません。

"mul()" や "max()" といった操作はモノラルとステレオを区別しない、すな
わち全てのデータを平等に扱うということに注意してください。この仕様が問
題になるようなら、あらかじめステレオ音声データを二つのモノラル音声デー
タに分割しておき、操作後に再度統合してください。そのような例を以下に示
します:

   def mul_stereo(sample, width, lfactor, rfactor):
       lsample = audioop.tomono(sample, width, 1, 0)
       rsample = audioop.tomono(sample, width, 0, 1)
       lsample = audioop.mul(lsample, width, lfactor)
       rsample = audioop.mul(rsample, width, rfactor)
       lsample = audioop.tostereo(lsample, width, 1, 0)
       rsample = audioop.tostereo(rsample, width, 0, 1)
       return audioop.add(lsample, rsample, width)

もし ADPCM 符号をネットワークパケットの構築に使って独自のプロトコルを
ステートレスにしたい場合 (つまり、パケットロスを許容したい場合)は、デ
ータだけを送信して、ステートを送信すべきではありません。デコーダに従っ
て *initial* ステート ("lin2adpcm()" に渡される値) を送るべきで、最終
状態 (符号化器が返す値) を送るべきではないことに注意してください。 も
し、"struct.Struct" をバイナリでの状態保存に使いたい場合は、最初の要素
(予測値) を 16bit で符号化し、２番目の要素 (デルタインデックス) を
8bit で符号化できます。

このモジュールの ADPCM 符号のテストは自分自身に対してのみ行っており、
他の ADPCM 符号との間では行っていません。作者が仕様を誤解している部分
もあるかもしれず、それぞれの標準との間で相互運用できない場合もあり得ま
す。

"find*()" ルーチンは一見滑稽に見えるかもしれません。これらの関数の主な
目的はエコー除去 (echo cancellation) にあります。エコー除去を十分高速
に行うには、出力サンプル中から最も大きなエネルギーを持った部分を取り出
し、この部分が入力サンプル中のどこにあるかを調べ、入力サンプルから出力
サンプル自体を減算します:

   def echocancel(outputdata, inputdata):
       pos = audioop.findmax(outputdata, 800)    # one tenth second
       out_test = outputdata[pos*2:]
       in_test = inputdata[pos*2:]
       ipos, factor = audioop.findfit(in_test, out_test)
       # Optional (for better cancellation):
       # factor = audioop.findfactor(in_test[ipos*2:ipos*2+len(out_test)],
       #              out_test)
       prefill = '\0'*(pos+ipos)*2
       postfill = '\0'*(len(inputdata)-len(prefill)-len(outputdata))
       outputdata = prefill + audioop.mul(outputdata, 2, -factor) + postfill
       return audioop.add(inputdata, outputdata, 2)
