audioop —生のオーディオデータを操作します
audioop モジュールには、サウンドフラグメントに対するいくつかの便利な操作が含まれています。 これは、バイトのようなオブジェクトに格納された、8、16、24、または32ビット幅の符号付き整数サンプルで構成されるサウンドフラグメントで動作します。 特に指定がない限り、すべてのスカラー項目は整数です。
バージョン3.4で変更: 24ビットサンプルのサポートが追加されました。 すべての関数は、バイトのようなオブジェクトを受け入れるようになりました。 文字列を入力すると、すぐにエラーが発生するようになりました。
このモジュールは、a-LAW、u-LAW、およびIntel / DVIADPCMエンコーディングのサポートを提供します。
より複雑な操作のいくつかは16ビットのサンプルのみを取ります。それ以外の場合、サンプルサイズ(バイト単位)は常に操作のパラメーターです。
このモジュールは、次の変数と関数を定義します。
- exception audioop.error
- この例外は、サンプルあたりの不明なバイト数など、すべてのエラーで発生します。
- audioop.add(fragment1, fragment2, width)
- パラメータとして渡された2つのサンプルの加算であるフラグメントを返します。 width は、
1
、2
、3
、または4
のいずれかのバイト単位のサンプル幅です。 両方のフラグメントの長さは同じである必要があります。 オーバーフローが発生した場合、サンプルは切り捨てられます。
- audioop.adpcm2lin(adpcmfragment, width, state)
- Intel / DVIADPCMでコード化されたフラグメントを線形フラグメントにデコードします。 ADPCMコーディングの詳細については、 lin2adpcm()の説明を参照してください。 サンプルの幅が width で指定されているタプル
(sample, newstate)
を返します。
- audioop.alaw2lin(fragment, width)
- a-LAWエンコーディングのサウンドフラグメントを線形エンコードされたサウンドフラグメントに変換します。 a-LAWエンコーディングは常に8ビットのサンプルを使用するため、 width は、ここでは出力フラグメントのサンプル幅のみを指します。
- audioop.avg(fragment, width)
- フラグメント内のすべてのサンプルの平均を返します。
- audioop.avgpp(fragment, width)
- フラグメント内のすべてのサンプルの平均ピークピーク値を返します。 フィルタリングは行われないため、このルーチンの有用性には疑問があります。
- audioop.bias(fragment, width, bias)
- 各サンプルにバイアスが追加された元のフラグメントであるフラグメントを返します。 オーバーフローが発生した場合、サンプルはラップアラウンドします。
- audioop.byteswap(fragment, width)
フラグメント内のすべてのサンプルを「バイトスワップ」し、変更されたフラグメントを返します。 ビッグエンディアンのサンプルをリトルエンディアンに、またはその逆に変換します。
バージョン3.4の新機能。
- audioop.cross(fragment, width)
- 引数として渡されたフラグメント内のゼロ交差の数を返します。
- audioop.findfactor(fragment, reference)
rms(add(fragment, mul(reference, -F)))
が最小になるように係数 F を返します。つまり、参照を乗算してとできるだけ一致させる必要がある係数を返します。フラグメント。 フラグメントには両方とも2バイトのサンプルが含まれている必要があります。このルーチンにかかる時間は、
len(fragment)
に比例します。
- audioop.findfit(fragment, reference)
- 参照をフラグメントの一部(より長いフラグメントである必要があります)にできるだけ一致させるようにしてください。 これは(概念的に)フラグメントからスライスを取り出し、 findfactor()を使用して最適な一致を計算し、結果を最小化することによって行われます。 フラグメントには両方とも2バイトのサンプルが含まれている必要があります。 タプル
(offset, factor)
を返します。ここで、 offset はフラグメントへの(整数)オフセットであり、最適な一致が開始され、 factor は(浮動小数点)です。 ) findfactor()に従って因数分解します。
- audioop.findmax(fragment, length)
フラグメントで、最大エネルギーの長さ長さサンプル(バイトではありません!)のスライスを検索します。つまり、
rms(fragment[i*2:(i+length)*2])
が最大である i を返します。 。 フラグメントには両方とも2バイトのサンプルが含まれている必要があります。このルーチンには、
len(fragment)
に比例した時間がかかります。
- audioop.getsample(fragment, width, index)
- フラグメントからサンプルインデックスの値を返します。
- audioop.lin2adpcm(fragment, width, state)
サンプルを4ビットのIntel / DVIADPCMエンコーディングに変換します。 ADPCMコーディングは適応コーディング方式であり、各4ビット数は1つのサンプルと次のサンプルの差を(変化する)ステップで割ったものです。 Intel / DVI ADPCMアルゴリズムは、IMAで使用するために選択されているため、標準になる可能性があります。
state は、コーダーの状態を含むタプルです。 コーダーはタプル
(adpcmfrag, newstate)
を返し、 newstate は lin2adpcm()の次の呼び出しに渡される必要があります。 最初の呼び出しでは、None
を状態として渡すことができます。 adpcmfrag は、1バイトあたり2つの4ビット値がパックされたADPCMコード化フラグメントです。
- audioop.lin2alaw(fragment, width)
- オーディオフラグメントのサンプルをa-LAWエンコーディングに変換し、これをバイトオブジェクトとして返します。 a-LAWは、8ビットのサンプルのみを使用して約13ビットのダイナミックレンジを取得するオーディオエンコーディング形式です。 とりわけ、Sunオーディオハードウェアによって使用されます。
- audioop.lin2lin(fragment, width, newwidth)
サンプルを1、2、3、および4バイト形式に変換します。
ノート
.WAVファイルなどの一部のオーディオ形式では、16、24、および32ビットのサンプルは署名されていますが、8ビットのサンプルは署名されていません。 したがって、これらの形式で8ビット幅のサンプルに変換する場合は、結果に128を追加する必要もあります。
new_frames = audioop.lin2lin(frames, old_width, 1) new_frames = audioop.bias(new_frames, 1, 128)
逆に、8から16、24、または32ビット幅のサンプルに変換する場合も同じことを適用する必要があります。
- audioop.lin2ulaw(fragment, width)
- オーディオフラグメントのサンプルをu-LAWエンコーディングに変換し、これをバイトオブジェクトとして返します。 u-LAWは、8ビットのサンプルのみを使用して約14ビットのダイナミックレンジを取得するオーディオエンコーディング形式です。 とりわけ、Sunオーディオハードウェアによって使用されます。
- audioop.max(fragment, width)
- フラグメント内のすべてのサンプルの絶対値の最大値を返します。
- audioop.maxpp(fragment, width)
- サウンドフラグメントの最大ピークピーク値を返します。
- audioop.minmax(fragment, width)
- サウンドフラグメント内のすべてのサンプルの最小値と最大値で構成されるタプルを返します。
- audioop.mul(fragment, width, factor)
- 元のフラグメントのすべてのサンプルに浮動小数点値 factor を掛けたフラグメントを返します。 オーバーフローが発生した場合、サンプルは切り捨てられます。
- audioop.ratecv(fragment, width, nchannels, inrate, outrate, state[, weightA[, weightB]])
入力フラグメントのフレームレートを変換します。
state は、コンバーターの状態を含むタプルです。 コンバーターはタプル
(newfragment, newstate)
を返し、 newstate は ratecv()の次の呼び出しに渡される必要があります。 最初の呼び出しは、状態としてNone
を渡す必要があります。weightA および weightB 引数は、単純なデジタルフィルターのパラメーターであり、デフォルトはそれぞれ
1
および0
です。
- audioop.reverse(fragment, width)
- フラグメント内のサンプルを反転し、変更されたフラグメントを返します。
- audioop.rms(fragment, width)
フラグメントの二乗平均平方根を返します。
sqrt(sum(S_i^2)/n)
。これは、オーディオ信号のパワーの尺度です。
- audioop.tomono(fragment, width, lfactor, rfactor)
- ステレオフラグメントをモノラルフラグメントに変換します。 左チャンネルに lfactor を掛け、右チャンネルに rfactor を掛けてから、2つのチャンネルを足してモノラル信号を出します。
- audioop.tostereo(fragment, width, lfactor, rfactor)
- モノラルフラグメントからステレオフラグメントを生成します。 ステレオフラグメント内のサンプルの各ペアは、モノラルサンプルから計算されます。これにより、左チャネルサンプルに lfactor が乗算され、右チャネルサンプルに rfactor が乗算されます。
- audioop.ulaw2lin(fragment, width)
- u-LAWエンコーディングのサウンドフラグメントを線形エンコードされたサウンドフラグメントに変換します。 u-LAWエンコーディングは常に8ビットのサンプルを使用するため、 width は、ここでは出力フラグメントのサンプル幅のみを指します。
mul()や max()などの操作では、モノラルフラグメントとステレオフラグメントが区別されないことに注意してください。 すべてのサンプルは同等に扱われます。 これが問題になる場合は、ステレオフラグメントを最初に2つのモノラルフラグメントに分割し、後で再結合する必要があります。 これを行う方法の例を次に示します。
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コーダーを使用してネットワークパケットを構築し、プロトコルをステートレスにしたい場合(つまり、 パケット損失を許容できるようにするには)データだけでなく状態も送信する必要があります。 初期状態( lin2adpcm()に渡した状態)を、最終状態(コーダーから返される)ではなく、デコーダーに送信する必要があることに注意してください。 struct.Struct を使用して状態をバイナリで格納する場合は、最初の要素(予測値)を16ビットでコーディングし、2番目の要素(デルタインデックス)を8でコーディングできます。
ADPCMコーダーは、他のADPCMコーダーに対して試行されたことはなく、自分自身に対してのみ試行されました。 標準を誤って解釈した可能性があります。その場合、それぞれの標準と相互運用できなくなります。
find*()
ルーチンは、一見すると少しおかしいように見えるかもしれません。 これらは主にエコーキャンセルを行うことを目的としています。 これを行うための適度に高速な方法は、出力サンプルの最もエネルギーの高い部分を選択し、それを入力サンプルで見つけて、入力サンプルから出力サンプル全体を差し引くことです。
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)