自己相関の考え方は、特定の遅延での信号とそれ自体の間の類似性の尺度を提供することです。これにはいくつかの方法がありますが、ピッチ/テンポ検出の目的では、検索手順と考えることができます。つまり、サンプルごとに信号をステップ実行し、参照ウィンドウと遅延ウィンドウの間で相関を実行します。参照をそれ自体の逐語的コピーと比較しているため、「遅延0」での相関はグローバル最大値になります。前進すると、相関は必然的に減少しますが、周期的な信号の場合は、ある時点で再び増加し始め、極大に達します。「ラグ0」とその最初のピークの間の距離は、ピッチ/テンポの推定値を提供します。私のやり方
サンプルごとの相関の計算は、高いサンプルレートでは計算コストが非常に高くなる可能性があるため、通常はFFTベースのアプローチを使用します。対象のセグメントのFFTを取り、その複素共役を掛けてから、逆FFTを行うと、周期的な自己相関が得られます。コード内(numpyを使用):
freqs = numpy.fft.rfft(signal)
autocorr = numpy.fft.irfft(freqs * numpy.conj(freqs))
効果は、周期的な成分(定義上、それら自体と同様)と比較して、信号内のノイズ(それ自体とは相関のない)の量を減らすことになります。逆変換を行う前に自己相関(つまり、共役乗算)を繰り返すと、ノイズがさらに減少します。白色波が混入した正弦波の例を考えてみましょう。次のプロットは、440Hzの正弦波、ノイズによって「破壊された」同じ正弦波、ノイズの多い波の周期的な自己相関、および二重の周期的な自己相関を示しています。
両方の自己相関信号の最初のピークが、元の信号の最初のサイクルの終わりに正確に位置していることに注意してください。それが周期性(この場合はピッチ)を決定するために探しているピークです。最初の自己相関信号はまだ少し「ぎこちない」ので、ピーク検出を行うには、ある種の平滑化が必要になります。周波数領域で2回の自己相関を行うと、同じ結果が得られます(比較的高速です)。「ぼんやり」とは、ズームインしたときに信号がどのように見えるかを意味し、プロットの中央で発生するディップではないことに注意してください。周期的自己相関の後半は常に前半の鏡像になるため、このような「ディップ」が一般的です。アルゴリズムを明確にするために、コードは次のようになります。
freqs = numpy.fft.rfft(signal)
auto1 = freqs * numpy.conj(freqs)
auto2 = auto1 * numpy.conj(auto1)
result = numpy.fft.irfft(auto2)
複数の自己相関を行う必要があるかどうかは、信号内のノイズの量によって異なります。
もちろん、このアイデアには微妙なバリエーションがたくさんありますが、ここではそれらすべてについては説明しません。私が(ピッチ検出のコンテキストで)確認した最も包括的なカバレッジは、RabinerとSchaferによる音声信号のデジタル処理です。
次に、自己相関がテンポ検出に十分かどうかについて説明します。答えはイエスとノーです。(ソース信号に応じて)テンポ情報を取得できますが、すべての場合にそれが何を意味するのかを理解するのは難しい場合があります。たとえば、次はブレイクビートの2つのループのプロットであり、その後にシーケンス全体の周期的自己相関のプロットが続きます。
参考までに、対応する音声は次のとおりです。
案の定、ループポイントに対応する真ん中に素晴らしいスパイクがありますが、それは非常に長いセグメントの処理に起因します。その上、それが正確なコピーではなかった場合(たとえば、それを備えたインストルメンテーションがあった場合)、そのスパイクはそれほどクリーンではありません。自己相関は間違いなくテンポ検出に役立ちますが、複雑なソース素材にはそれだけでは十分ではない可能性があります。たとえば、スパイクを見つけた場合でも、それが完全な小節、4分音符、2分音符などのどれであるかをどのようにして知るのでしょうか。この場合、それは完全な測定値であることは十分明確ですが、常にそうであるとは限りません。内部の仕組みが明らかになるまで、より単純な信号でACをいじってみてから、一般にテンポ検出について別の質問をすることをお勧めします(「大きい」ため)