Я должен сделать взаимную корреляцию двух аудио файлов, чтобы доказать, что они похожи. Я взял БПФ двух звуковых файлов, и их значения спектра мощности находятся в отдельных массивах.
Как мне продолжить кросс-корреляцию и доказать, что они похожи? Есть ли лучший способ сделать это? Любые основные идеи будут полезны для меня, чтобы изучить и применить его.
audio
fft
waveform-similarity
cross-correlation
Лорем Ипсум
источник
источник
Ответы:
Кросс-корреляция и свертка тесно связаны. Короче говоря, чтобы сделать свертку с БПФ, вы
conv(a, b) = ifft(fft(a_and_zeros) * fft(b_and_zeros))
Вам необходимо выполнить заполнение нулями, потому что метод FFT на самом деле представляет собой круговую взаимную корреляцию, то есть сигнал оборачивается на концах. Таким образом, вы добавляете достаточно нулей, чтобы избавиться от перекрытия, чтобы имитировать сигнал, который обнуляется до бесконечности.
Чтобы получить взаимную корреляцию вместо свертки, вам нужно либо повернуть вспять один из сигналов перед выполнением БПФ, либо взять комплексное сопряжение одного из сигналов после БПФ:
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)))
что проще с вашим аппаратным / программным обеспечением. Для автокорреляции (взаимной корреляции сигнала с самим собой) лучше сделать комплексное сопряжение, потому что тогда вам нужно только рассчитать БПФ один раз.
Если сигналы действительны, вы можете использовать реальные БПФ (RFFT / IRFFT) и сэкономить половину времени вычислений, рассчитав только половину спектра.
Также вы можете сэкономить время вычислений, дополнив его большим размером, для которого оптимизировано FFT (например, 5-гладким числом для FFTPACK, ~ 13-гладким числом для FFTW или степенью 2 для простой аппаратной реализации).
Вот пример в Python корреляции БПФ по сравнению с корреляцией грубой силы: https://stackoverflow.com/a/1768140/125507
Это даст вам функцию взаимной корреляции, которая является мерой сходства против смещения. Чтобы получить смещение, при котором волны «выровнены» друг с другом, в корреляционной функции будет пик:
Значение x пика - это смещение, которое может быть отрицательным или положительным.
Я видел только это, чтобы найти смещение между двумя волнами. Вы можете получить более точную оценку смещения (лучше, чем разрешение ваших выборок), используя параболическую / квадратичную интерполяцию на пике.
Чтобы получить значение подобия между -1 и 1 (отрицательное значение, указывающее, что один из сигналов уменьшается по мере увеличения другого), вам необходимо масштабировать амплитуду в соответствии с длиной входов, длиной FFT, вашей конкретной реализацией FFT. масштабирование и т. д. Автокорреляция волны с самим собой даст вам значение максимально возможного соответствия.
Обратите внимание, что это будет работать только на волнах, имеющих одинаковую форму. Если они были сэмплированы на другом оборудовании или имело некоторый добавленный шум, но в остальном они по-прежнему имеют одинаковую форму, это сравнение будет работать, но если форма волны была изменена фильтрацией или фазовыми сдвигами, они могут звучать одинаково, но выиграли не коррелирует также.
источник
Корреляция - это способ выразить сходство двух временных рядов (аудиосэмплов в вашем случае) в одном числе. Это адаптация ковариации, которая реализуется следующим образом:
Корреляция - это нормализованная версия ковариации, которая представляет собой ковариацию, деленную на произведение стандартных отклонений обоих временных рядов. Корреляция даст 0, когда нет корреляции (полностью не похожая) и 1 для полной корреляции (полностью похожая).
Вы можете представить, что два образца звука могут быть похожими, но не синхронизированы. Вот где появляется взаимная корреляция . Вы вычисляете корреляцию между временными рядами, в которых один из них сдвинут на одну выборку:
Затем найдите максимальное значение в
corr
серии, и все готово. (или прекратите, если вы нашли достаточную корреляцию) Конечно, это немного больше. Вы должны реализовать стандартное отклонение, и вы должны сделать некоторое управление памятью и реализовать сдвиг времени. Если все ваши аудиосэмплы равны по длине, вы можете обойтись без нормализации ковариации и продолжить вычислять кросс-ковариацию.Интересное отношение к вашему предыдущему вопросу : анализ Фурье - это всего лишь адаптация кросс-ковариации. Вместо того, чтобы сдвигать один временной ряд и вычислять ковариации с другим сигналом, вы вычисляете ковариации между одним сигналом и количеством (син) синусоидальных волн с разными частотами. Все это основано на том же принципе.
источник
При обработке сигнала взаимная корреляция (xcorr в MATLAB) является операцией свертки с обращением одной из двух последовательностей. Поскольку обращение времени соответствует комплексному сопряжению в частотной области, вы можете использовать ДПФ для вычисления взаимной корреляции следующим образом:
где N = размер (х) + размер (у) - 1 (предпочтительно округленный до степени 2) - длина ДПФ.
Умножение ДПФ эквивалентно круговой свертке во времени. Нулевое заполнение обоих векторов до длины N удерживает циклически сдвинутые компоненты y от перекрытия с x, что делает результат идентичным линейной свертке x и обращенному по времени y.
Отставание 1 - это правое круговое смещение y, а отставание от -1 - левое круговое смещение. Кросс-корреляция - это просто последовательность точечных произведений для всех лагов. Основываясь на стандартном порядке fft, они будут в массиве, к которому можно получить доступ следующим образом. Индексы от 0 до размера (x) -1 являются положительными лагами. Индексы N-размера (y) от +1 до N-1 являются отрицательными лагами в обратном порядке. (В Python к отрицательным лагам можно обращаться с помощью отрицательных индексов, таких как R_xy [-1].)
Вы можете думать о дополненных нулями x и y как о N-мерных векторах. Точечное произведение x и y для данного отставания равно
|x|*|y|*cos(theta)
. Нормы x и y постоянны для круговых сдвигов, поэтому их разделение оставляет только изменяющийся косинус угла тета. Если x и y (для данного лага) ортогональны в N-пространстве, корреляция равна 0 (тета = 90 градусов). Если они коллинеарны, значение равно 1 (положительно коррелируется) или -1 (отрицательно коррелируется, то есть тета = 180 градусов). Это приводит к взаимной корреляции, нормированной к единице:Это можно сделать беспристрастным, пересчитав нормы только для перекрывающихся частей, но тогда вы можете также выполнить все вычисления во временной области. Также вы увидите разные варианты нормализации. Вместо того, чтобы быть нормализованным к единице, иногда взаимная корреляция нормализуется с помощью M (смещения), где M = max (размер (x), размер (y)) или M- | m | (непредвзятая оценка m-го лага).
Для максимальной статистической значимости среднее значение (смещение постоянного тока) должно быть удалено перед вычислением корреляции. Это называется кросс-ковариацией (xcov в MATLAB):
источник
2*size (a) + size(b) - 1
или2*size (b) + size (a) - 1
? Но в любом случае два дополненных массива имеют разные размеры. Каковы последствия заполнения с большим количеством нулей?b
вдольa
, с одним выходом в смену, с минимальным перекрытием одного образца. Это даетsize(a)
положительные лаги иsize(b) - 1
отрицательные лаги. Используя обратное преобразование произведения N-точечных ДПФ,0
сквозные индексыsize(a)-1
являются положительными лагами, аN-size(b)+1
сквозные индексыN-1
- отрицательными лагами в обратном порядке.если вы используете Matlab, попробуйте функцию взаимной корреляции:
Вот документация Matlab:
источник
Быстрый и простой способ сравнить аудио файлы. Возьмите аудиофайл, сделайте копию, в галку, вставьте их рядом, в 2 стереоканала, инвертируйте фазу на одной из стереотреков, выровняйте оба файла в начале в режиме масштабирования, убедитесь, что оба файла имеют одинаковую амплитуду в начале, затем воспроизводите, если есть полная тишина, тогда оба файла идентичны, если есть разница, вы услышите это довольно четко !.
источник
Как большинство здесь написали, вы должны использовать корреляцию.
Просто учтите 2 фактора:
источник
Для непериодических сигналов (размер (y) -1) необходимо вычесть из индекса R_xy, чтобы получить фактическое запаздывание.
N = размер (х) + размер (у) - 1;
лаги = [0, N] - (размер (у) - 1);
источник
Самый простой способ найти разницу, IMO, - вычесть два аудиосигнала во временной области. Если они равны, результат в каждый момент времени будет равен нулю. Если они не равны, разница между ними останется после вычитания, и вы можете слушать ее напрямую. Быстрая оценка того, насколько они похожи, будет среднеквадратичным значением этой разницы. Это часто делается в микшировании и мастеринге аудио, например, чтобы услышать разницу между MP3 и WAV-файлами. (Инверсия фазы одного сигнала и добавление их - это то же самое, что вычитание. Этот метод используется, когда это делается в программном обеспечении DAW.) Они должны быть идеально выровнены по времени, чтобы это работало. Если это не так, вы можете разработать алгоритм их выравнивания, такой как обнаружение первых десяти пиков, вычисление среднего смещения пиков и смещение одного сигнала.
Преобразование в частотную область и сравнение спектров мощности сигналов, которые вы предлагаете, игнорирует некоторую информацию во временной области. Например, звук, воспроизводимый в обратном направлении, будет иметь тот же спектр при воспроизведении вперед. Таким образом, два очень разных аудиосигнала могут иметь одинаковый спектр.
источник