Ідея автокореляції полягає в тому, щоб забезпечити міру подібності між сигналом і самим собою при заданому відставанні. Існує кілька способів наблизитись до нього, але для виявлення тону / темпу ви можете розглядати це як процедуру пошуку. Іншими словами, ви переходите через зразок за зразком сигналу і здійснюєте кореляцію між вашим опорним вікном та відсталим вікном. Кореляція при "відставанні 0" буде максимальним глобальним, оскільки ви порівнюєте посилання на дослівну копію себе. Коли ви крокуєте вперед, кореляція обов’язково зменшиться, але у випадку періодичного сигналу в якийсь момент він знову почне зростати, після чого досягне локального максимуму. Відстань між "відставанням 0" та першим піком дає оцінку вашому кроку / темпу. Як я '
Обчислення співвідношень вибірки на зразок може бути дуже обчислювально дорогим при високих показниках вибірки, тому зазвичай використовується підхід на основі FFT. Взявши FFT за цікавий сегмент, помноживши його на його складний кон'югат , то прийняття зворотного FFT дасть вам циклічну автокореляцію . У коді (використовуючи 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)
Від того, чи потрібно вам робити більше однієї автокореляції, залежить від того, скільки шуму буде в сигналі.
Звичайно, існує багато тонких варіацій цієї ідеї, і я не збираюся тут все вникати. Найповніше висвітлення, яке я бачив (в контексті виявлення тону), полягає в цифровій обробці мовних сигналів Рабінером і Шафером.
Тепер щодо того, чи буде автокореляція достатньою для виявлення темпу. Відповідь - так і ні. Ви можете отримати деяку інформацію про темп (залежно від вихідного сигналу), але може бути важко зрозуміти, що це означає у всіх випадках. Наприклад, ось сюжет з двох циклів битви, з подальшим графіком циклічної автокореляції всієї послідовності:
Для довідки, ось відповідне аудіо:
Звичайно, є хороший шип прямо в середині, що відповідає точці циклу, але він отримав обробку досить довгого сегмента. Крім того, якби це була не точна копія (наприклад, якщо з нею були прилади), цей шип не був би таким чистим. Автокореляція, безумовно, буде корисною для виявлення темпу, але вона, ймовірно, сама по собі не буде достатньою для складного вихідного матеріалу. Наприклад, навіть якщо ви знайдете колосок, як ви дізнаєтесь, чи це повна міра, або чверть ноти, половина нота чи щось інше? У цьому випадку досить зрозуміло, що це повна міра, але це не завжди так. Я б запропонував пограти з використанням змінного струму на більш простих сигналах, поки не з’ясується внутрішня робота, а потім задати ще одне питання щодо темпового виявлення (оскільки це "більше"