Идея автокорреляции состоит в том, чтобы обеспечить меру сходства между сигналом и самим собой при данном запаздывании. Есть несколько способов приблизиться к нему, но для целей определения высоты тона / темпа вы можете рассматривать его как процедуру поиска. Другими словами, вы проходите шаг за шагом по сигналу и выполняете корреляцию между вашим опорным окном и запаздывающим окном. Корреляция в «лаг 0» будет глобальным максимумом, потому что вы сравниваете ссылку на дословную копию самого себя. По мере продвижения вперед корреляция обязательно будет уменьшаться, но в случае периодического сигнала в какой-то момент он снова начнет увеличиваться, а затем достигнет локального максимума. Расстояние между "лагом 0" и первым пиком дает вам оценку вашего шага / темпа. Как я
Вычисление корреляций выборка за выборкой может быть очень дорогим в вычислительном отношении при высоких частотах выборки, поэтому обычно используется подход, основанный на БПФ. Взяв БПФ интересующего сегмента, умножив его на комплексное сопряжение , затем взяв обратное БПФ, вы получите циклическую автокорреляцию . В коде (используя numpy ):
freqs = numpy.fft.rfft(signal)
autocorr = numpy.fft.irfft(freqs * numpy.conj(freqs))
Эффект будет заключаться в уменьшении количества шума в сигнале (который не связан с самим собой) относительно периодических компонентов (которые по определению аналогичны самим себе). Повторение автокорреляции (т. Е. Умножения с сопряжением) перед выполнением обратного преобразования уменьшит шум еще больше. Рассмотрим пример синусоидальной волны, смешанной с белым шумом. На следующем графике показана синусоида 440 Гц, та же синусоида, «искаженная» шумом, циклическая автокорреляция шумовой волны и двойная циклическая автокорреляция:
Обратите внимание, как первый пик обоих автокорреляционных сигналов расположен точно в конце первого цикла исходного сигнала. Это пик, который вы ищете, чтобы определить периодичность (в данном случае высоту звука). Первый сигнал автокорреляции все еще немного «волнистый», поэтому для обнаружения пиков потребуется какое-то сглаживание. Автокорреляция дважды в частотной области выполняет то же самое (и относительно быстро). Обратите внимание, что под «волнистой» я имею в виду то, как выглядит сигнал при увеличении, а не провал, который происходит в центре графика. Вторая половина циклической автокорреляции всегда будет зеркальным отображением первой половины, поэтому такой тип «провала» является типичным. Просто для ясности об алгоритме, вот как будет выглядеть код:
freqs = numpy.fft.rfft(signal)
auto1 = freqs * numpy.conj(freqs)
auto2 = auto1 * numpy.conj(auto1)
result = numpy.fft.irfft(auto2)
Требуется ли выполнять более одной автокорреляции, зависит от уровня шума в сигнале.
Конечно, есть много тонких вариаций этой идеи, и я не буду вдаваться во все из них здесь. Наиболее полный охват, который я видел (в контексте обнаружения основного тона), касается цифровой обработки речевых сигналов Рабинера и Шафера.
Теперь о том, будет ли автокорреляция достаточной для определения темпа. Ответ и да и нет. Вы можете получить некоторую информацию о темпе (в зависимости от исходного сигнала), но может быть трудно понять, что это означает во всех случаях. Например, вот график двух циклов перерыва, за которым следует график циклической автокорреляции всей последовательности:
Для справки вот соответствующее аудио:
Конечно, прямо посередине есть хороший всплеск, соответствующий точке цикла, но это произошло из-за обработки довольно длинного сегмента. Вдобавок ко всему, если бы это не была точная копия (например, если бы были инструменты с ним), этот шип не был бы таким чистым. Автокорреляция определенно будет полезна при обнаружении темпа, но, вероятно, ее будет недостаточно для сложного исходного материала. Например, даже если вы обнаружите всплеск, как вы узнаете, будет ли это полная мера, или четвертная нота, половина ноты или что-то еще? В этом случае достаточно ясно, что это полная мера, но это не всегда так. Я бы посоветовал поиграть с использованием AC на более простых сигналах, пока не прояснится внутренняя работа, а затем задать еще один вопрос об определении темпа в целом (так как это «больше»).