相互相関を実装して、2つのオーディオファイルが似ていることを証明するにはどうすればよいですか?


58

2つのオーディオファイルを相互相関させて、それらが類似していることを証明する必要があります。2つのオーディオファイルのFFTを取得し、それらのパワースペクトル値を別々の配列に格納しています。

それらを相互相関させて、それらが類似していることを証明するには、どのようにさらに進める必要がありますか?それを行うより良い方法はありますか?基本的なアイデアは、それを学び、適用するのに役立ちます。


2つのランダムな信号ベクトルの相互相関を考えます。MATLABで2つのベクトルを取得するために、どのように逆を実装しますか。ジョンMuhehe

回答:


56

相互相関と畳み込みは密接に関連しています。つまり、FFTで畳み込みを行うには、

  1. 入力信号をゼロで埋めます(波の少なくとも半分が「空白」になるように最後にゼロを追加します)
  2. 両方の信号のFFTを取得
  3. 結果を一緒に乗算します(要素ごとの乗算)
  4. 逆FFTを行う

conv(a, b) = ifft(fft(a_and_zeros) * fft(b_and_zeros))

FFTメソッドは実際には循環相互相関であるため、ゼロパディングを行う必要があります。つまり、信号は端でラップアラウンドします。したがって、無限にゼロになる信号をシミュレートするために、オーバーラップを取り除くために十分なゼロを追加します。

畳み込みの代わりに相互相関を得るには、FFTを行う前に信号の1つを時間反転するか、FFTの後に信号の1つの複素共役を取る必要があります。

  • corr(a, b) = ifft(fft(a_and_zeros) * fft(b_and_zeros[reversed]))
  • corr(a, b) = ifft(fft(a_and_zeros) * conj(fft(b_and_zeros)))

ハードウェア/ソフトウェアのどちらが簡単か。自己相関(信号とそれ自体の相互相関)の場合、FFTを計算する必要があるのは一度だけなので、複素共役を行う方が適切です。

信号が実数である場合、実数FFT(RFFT / IRFFT)を使用して、スペクトルの半分のみを計算することにより、計算時間を半分に節約できます。

また、FFTが最適化されるより大きなサイズにパディングすることにより、計算時間を節約できます(FFTPACKの場合は5 スムーズな数値、FFTWの場合は〜13スムーズな数値、単純なハードウェア実装の場合は2のべき乗など)。

以下は、ブルートフォース相関と比較したFFT相関のPythonの例です:https : //stackoverflow.com/a/1768140/125507

これにより、相互相関関数が得られます。これは、類似度とオフセットの尺度です。波が互いに「整列」するオフセットを取得するには、相関関数にピークがあります。

相関関数のピーク

ピークのx値はオフセットであり、負または正の可能性があります。

これは、2つの波の間のオフセットを見つけるために使用されるのを見ただけです。ピークで放物線/二次補間を使用することで、オフセットのより正確な推定値を得ることができます(サンプルの分解能よりも優れています)。

-1と1の間の類似値(他の信号が増加するにつれて信号の1つが減少することを示す負の値)を取得するには、入力の長さ、FFTの長さ、特定のFFT実装に応じて振幅をスケーリングする必要がありますスケーリングなど。波とそれ自体の自己相関により、可能な最大一致の値が得られます。

これは、同じ形状の波でのみ機能することに注意してください。それらが異なるハードウェアでサンプリングされているか、ノイズが追加されているが、それでも同じ形状をしている場合、この比較は機能しますが、波形がフィルタリングまたは位相シフトによって変更された場合、同じように聞こえますが、勝ちます同様に相関しません。


3
ゼロのパディングは、少なくともN = size(a)+ size(b)-1である必要があり、2のべき乗に切り上げることが望ましい。-1と1の間の値を取得するには、norm(a)* norm(b )、指定されたラグ(つまり、Nを法とする循環シフト)のN空間内の2つのベクトル間の角度のコサインを返します。極端なラグでは、重複するサンプルはあまり多くないため(極値では1つのみ)、norm(a)* norm(b)で除算すると、これらの相関が0にバイアスされます(つまり、N空間での相対的な直交性を示します) 。
エリックサン

1
説明に誤りがあるかもしれません。用語ごとにFFTを乗算すると、相互相関の FFTではなく、信号の畳み込みのFFTが得られませんか?私が理解しているように、相互相関のFFTを取得するには、iFFTを取得する前に、項ごとの乗算でFFTベクトルの1つの複素共役を使用する必要があります。
ディリップサルワテ

@DilipSarwate:はい、そうです。また、私は答えに追加した時間方向に1つの信号を逆にすることができます。
エンドリス

1
x[i]ix[±i]x[i](Ni)x[Ni]ii配線コスト、配線遅延の増加(したがって、達成可能な最大クロックレートの低下)、およびすべてのワイヤが相互に交差する必要があるため、ルーティングの問題が発生します。可能な場合は回避する必要があり、この場合回避可能です。
ディリップサルワテ

1
@Leo要素ごとの乗算。n行1列の配列x n行1列の配列= n行1列の配列回答では、これを「サンプルごと」と呼びました。
エンドリス14年

17

相関は、2つの時系列(あなたの場合は音声サンプル)の類似性を1つの数値で表現する方法です。次のように実装されるのは、共分散の適応です。

period = 1/sampleFrequency;
covariance=0;

for (iSample = 0; iSample<nSamples; iSample++)
    covariance += (timeSeries_1(iSample)*timeSeries_2(iSample))/period;
    //Dividing by `period` might not even be necessary

相関は、共分散の正規化バージョンです。これは、共分散を両方の時系列の標準偏差の積で割ったものです。相関関係がない場合(完全に類似していない場合)は0、相関関係がある場合(完全に類似している場合)は1になります。

2つのサウンドサンプルは似ているかもしれませんが、同期していないと想像できます。そこで相互相関が発生します。時系列間の相関を計算し、そのうちの1つを1つのサンプルでシフトします。

for (iShift=0; iShift<nSamples; iShift++)
    xcorr(iShift) = corr(timeSeries_1, timeSeries_2_shifted_one_sample);

次に、corrシリーズの最大値を探し出します。(または、十分な相関関係が見つかった場合は停止します)もちろん、もう少し多くのことがあります。標準偏差を実装し、メモリ管理をいくつか行い、タイムシフトを実装する必要があります。すべてのオーディオサンプルの長さが等しい場合は、共分散を正規化せずに実行し、相互共分散を計算します。

前の質問とのクールな関係:フーリエ解析は、相互共分散の単なる適応です。1つの時系列をシフトして他の信号との共分散を計算するのではなく、1つの信号とさまざまな周波数の(コ)正弦波の間の共分散を計算します。すべて同じ原理に基づいています。


1
0は相関関係がなく、1は合計相関関係であると述べました。-1は完全に負の相関があることに注意してください。同様に、-1は、サンプル1がサンプル2の反対であることを意味します。X、Yグラフで考えると、正の勾配を持つラインと負の勾配を持つラインです。そして、0に近づくと、線は「太く」なります。
ケレンイブ

@kellenjb、はい、しかし、私はおそらくそれを言います、あなたがおそらく興味を持っている相関の大きさ。1または-1は、信号が互いに直接影響を及ぼすことを意味します。
Kortuk

14

信号処理では、相互相関(MATLABのxcorr)は、2つのシーケンスのいずれかが反転した畳み込み演算です。時間反転は周波数領域での複素共役に対応するため、次のようにDFTを使用して相互相関を計算できます。

R_xy = ifft(fft(x,N) * conj(fft(y,N)))

ここで、N = size(x)+ size(y)-1(2の累乗が望ましい)はDFTの長さです。

DFTの乗算は、時間の循環たたみ込みに相当します。両方のベクトルをゼロの長さNにパディングすると、yの循環シフト成分がxとオーバーラップしないようにします。これにより、xと時間反転yの線形畳み込みと同じ結果になります。

1のラグはyの右循環シフトであり、-1のラグは左循環シフトです。相互相関は、すべてのラグのドット積のシーケンスです。標準のfft順序に基づいて、これらは次のようにアクセスできる配列になります。インデックス0〜size(x)-1は正のラグです。インデックスN-size(y)+1〜N-1は、逆順の負のラグです。(Pythonでは、R_xy [-1]などの負のインデックスを使用して負のラグに簡単にアクセスできます。)

ゼロが埋め込まれたxとyは、N次元のベクトルと考えることができます。所定のラグに対するxとyのドット積は|x|*|y|*cos(theta)です。xとyのノルムは、循環シフトでは一定であるため、それらを除算すると、角度thetaのコサインが変化します。xとy(与えられたラグ)がN空間で直交する場合、相関は0(シータ= 90度)です。それらが同一直線上にある場合、値は1(正の相関)または-1(負の相関、つまりtheta = 180度)のいずれかです。これにより、ユニティに正規化された相互相関が得られます。

R_xy = ifft(fft(x,N) * conj(fft(y,N))) / (norm(x) * norm(y))

これは、オーバーラップする部分だけのノルムを再計算することで公平になりますが、時間領域で計算全体を行うこともできます。また、正規化のさまざまなバージョンが表示されます。ユニティに正規化される代わりに、相互相関がM(バイアス)で正規化される場合があります。ここで、M = max(size(x)、size(y))またはM- | m | (m番目のラグの公平な推定値)。

最大の統計的有意性を得るには、相関を計算する前に平均(DCバイアス)を削除する必要があります。これは相互共分散(MATLABではxcov)と呼ばれます。

x2 = x - mean(x)
y2 = y - mean(y)
phi_xy = ifft(fft(x2,N) * conj(fft(y2,N))) / (norm(x2) * norm(y2))

これは、配列の最終サイズがまたはであることを意味します2*size (a) + size(b) - 12*size (b) + size (a) - 1?ただし、どちらの場合も、2つの埋め込み配列のサイズは異なります。ゼロが多すぎるパディングの結果は何ですか?

2

@RobertKJ:あなたがスライディングしているbに沿ってaシフトにつき1つの出力、1つのサンプルの最小の重なりで、。それはsize(a)正の遅延とsize(b) - 1負の遅延をもたらします。N点DFTの積の逆変換を使用すると、インデックス0スルーsize(a)-1は正のラグであり、インデックスN-size(b)+1スルーN-1は逆順の負のラグです。
エリック日

3

Matlabを使用している場合、相互相関関数を試してください:

c= xcorr(x,y)

Matlabのドキュメントは次のとおりです。

xcorrランダムプロセスの相互相関シーケンスを推定します。自己相関は特別なケースとして処理されます。

...

c = xcorr(x,y)長さ2 * N-1のベクトルで相互相関シーケンスを返します。ここでxおよびyは長さのNベクトル(N > 1)です。xyが同じ長さでない場合、短いベクトルは長いベクトルの長さにゼロでパディングされます。

相関http://www.mathworks.com/help/toolbox/signal/ref/eqn1263487323.gif


リンクが壊れているようです。
ダニエル

2

オーディオファイルをすばやく簡単に比較する方法。オーディオファイルを取り出し、コピーを作成し、1ステレオチャンネルで並べて貼り付け、ステレオトラックの1つで位相を反転し、ズームモードで両方のファイルを最初に揃えます。両方のファイルは最初に同じ振幅を持ち、完全に無音の場合は再生し、違いがある場合は両方のファイルが同じであることがわかります。


1

ここで書いたように、相関を使用する必要があります。

考慮中の2つの要素のみを考慮してください。

  1. ボリュームのスケーリングが異なる場合、相関を正規化する必要があります。
  2. 時間のスケーリングがある場合、ダイナミックタイムワーピングを使用できます。

1

非周期信号(size(y)-1)の場合、実際のラグを取得するにはR_xyのインデックスから減算する必要があります。

N =サイズ(x)+サイズ(y)-1;

lags = [0、N]-(size(y)-1);


0

差IMOを見つける最も簡単な方法は、時間領域で2つのオーディオ信号を減算することです。それらが等しい場合、各時点での結果はゼロになります。それらが等しくない場合、それらの差は減算後に残され、直接聞くことができます。それらがどれほど似ているかを示す簡単な尺度は、この差のRMS値です。これは、たとえばMP3ファイルとWAVファイルの違いを聞くために、オーディオのミキシングとマスタリングでよく行われます。(1つの信号の位相を反転して加算することは、減算と同じです。これは、DAWソフトウェアでこれを行うときに使用される方法です。)これが機能するには、完全に時間調整されている必要があります。そうでない場合は、上位10個のピークの検出、ピークの平均オフセットの計算、1つの信号のシフトなど、それらを調整するアルゴリズムを開発できます。

周波数ドメインに変換し、提案されているように信号のパワースペクトルを比較することは、いくつかの時間ドメイン情報を無視します。たとえば、逆方向に再生されるオーディオは、順方向に再生されるときに同じスペクトルを持ちます。したがって、2つの非常に異なるオーディオ信号がまったく同じスペクトルを持つ可能性があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.