Обнаружение высоты тона с помощью computeSpectrum () возвращает значения FFT - PullRequest
5 голосов
/ 08 июня 2011
  • Я занимаюсь разработкой с использованием Actionscript 3.0 для Flash Player 10.3
  • Я использую computeSpectrum () на загруженном .mp3
  • Выполняется * Событие.ENTER_FRAME * для получения снимков каждого образца в byteArray
  • ByteArray содержит 512 значений (256 для каждого канала).Эти значения представляют собой БПФ-Спектр в диапазоне от 0 до 1.
  • Я не могу использовать пиковую частоту для каждой из выборок (как я выяснил!), Потому что самое высокое значение не обязательно является основной частотой!В результате я получаю много случайных значений повсюду!Конечно, я тоже получаю некоторые правильные данные, но этого недостаточно!

Я узнал о автокорреляции ...
Может кто-нибудь привести примеркак я мог это использовать?

Или ссылки, или примеры сценариев даже из других языков сценариев, чтобы получить контроль над ним?

С уважением
initcode

Ответы [ 4 ]

7 голосов
/ 09 июня 2011

Похоже, вы уже понимаете, как получить спектр БПФ, верно?

spectrum http://flic.kr/p/7notw6

Но если вы ищете фундаментальную (зеленая точка), вы не можете просто использовать самый высокий пик. Это не обязательно фундаментально. В моем примере фактическая частота составляет 100 Гц, но самый высокий пик составляет 300 Гц.

Есть много разных способов найти истинный фундамент, и каждый работает лучше в разных контекстах. Один поток на comp.dsp упоминает «БПФ, кепстр, авто / взаимная корреляция, AMDF / ASDF».

Для простого примера каждая из красных точек находится на расстоянии 100 Гц от своего соседа, поэтому, если вы использовали алгоритм нахождения пика, а затем усреднили вместе расстояние между каждой гармоникой и следующей, вы найдете основную, но это потерпит неудачу, если какой-либо из пиков будет пропущен или включены дополнительные пики, или если сигнал будет симметричным и содержит только нечетные гармоники (1f, 3f, 5f). Вам нужно будет найти режим и затем выбросить выбросы, а затем усреднить. Это, вероятно, подверженный ошибкам метод.

Вы также можете выполнить автокорреляцию исходного сигнала. Концептуально это означает скольжение копии формы волны за собой и поиск задержки, с которой он лучше всего согласуется с самим собой (что будет одним полным циклом). В обычной реализации мы используем БПФ, чтобы ускорить его . Автокорреляция в основном

  • ОБПФ (FFT (сигнал) ⋅FFT (сигнал) *)

где * означает комплексное сопряжение, или обращение времени. В Python, например :

correlation = fftconvolve(sig, sig[::-1], mode='full')

и источник для fftconvolve () относительно прост: https://github.com/scipy/scipy/blob/master/scipy/signal/signaltools.py#L133

1 голос
/ 11 июня 2011

Вы можете использовать метод Harmonic Product Spectrum для оценки расстояния (разности частот) между пиками обертонов в частотном спектре (результаты FFT), даже если некоторые пики отсутствуют, если не слишком много ложных частотных пиков ( шум).

Для получения Гармонического спектра продуктов распечатайте БПФ на полупрозрачной бумаге и сверните его в цилиндр (или сделайте аналог в программном обеспечении). Заворачивайте цилиндр все крепче и плотнее, пока не будет перекрыто наибольшее количество пиков. Окружность будет хорошей оценкой поля. Это работает для любых музыкальных звуков, которые имеют много гармоник, даже если основной пик частоты основного тона отсутствует или слаб.

0 голосов
/ 09 июня 2011

Что вы пытаетесь сделать?

Я не использовал computeSpectrum() раньше, но первую половину моей карьеры в качестве инженера DSP.

Если это делает то, что документыскажем, тогда вам не нужно автоматически коррелировать результаты.

В вашем байтовом массиве индекс представляет частотный блок, а значение индекса представляет величину этой конкретной частоты.

ЕслиПод обнаружением основного тона вы подразумеваете найти самую сильную частоту, затем вам нужно перебрать массив байтов и вычислить sqrt(left*left+right*right) для каждого индекса.Найти максимальное значение из них.Индекс максимального значения представляет самую сильную частоту.

Если предположить, что fs = 44,1 кГц, а i - ваш индекс, то самая большая частота -

f = (i / 255) * (44100/ 2);

Имейте в виду, что вы ограничены интервалом между ячейками для разрешения по частоте.Если вам нужно более высокое разрешение, вам нужно интерполировать данные.

0 голосов
/ 09 июня 2011

Sound.extract() результат может быть передан в SampleDataEvent.data

...