Правильно ли мое понимание БПФ и обнаружения высоты тона здесь?

было бесчисленное количество дискуссий о Stackoverflow и за его пределами о БПФ и обнаружения высоты тона.

общепризнано, что FFT, хотя и быстрый, не очень точен для многих приложений, но часто не объясняется, почему.

Я хотел бы объяснить мое понимание, почему это так, в надежде, что кто-то умнее меня сможет поправить меня и заполнить пробелы, где я не могу.


FFT преобразует входные данные из временной области в частотную область.

Первоначально мы начнем с ряда данных, которые, если бы мы построили график, имели бы амплитуду звука в заданный момент времени на оси Y и время вдоль оси X. Это во временной области.

FFT преобразует эти значения амплитуд в моменты времени в амплитуды на разных частотах.

количество данных, выводимых из БПФ, совпадает с количеством данных ввод

если мы вводим амплитуды для 10 точек во времени (10 выборок), FFT выведет амплитуды для 10 различных частот в этих выборках (после умножения sqrt мнимого и действительного чисел).

какие частоты определяются следующим образом:

мы называем выход из FFT a bin, ширина каждого ящика высчитана путем разделять частоту дискретизации числом образцов в БПФ:

bin width = Sample Rate(Hz)/FFT Length (n samples)

С некоторыми реальными значениями это может быть:

bin_width = 44100 / 512 = 86.132

Итак, у нас есть 512 бункеров из нашего БПФ (помните, что это то же самое нет. данных в as out), и каждый из них охватывает 86.132 Гц.

поэтому для данного Бина мы можем вычислить, какую частоту он представляет:

Bin Freq (Hz) = Bin number (n) * bin width (Hz)

используя значения сверху, 3-й Бин на выходе БПФ будет представлять амплитуду при 258,398 Гц:

Bin Freq (Hz) = 3 * 86.132 = 258.396Hz

этот означает, что при заданной частоте дискретизации и размере буфера выход FFT не может быть более точным, чем ± 86.132 Гц.

Если вам требуется большая точность (скажем, 1 Гц), вам придется либо уменьшить частоту дискретизации, либо увеличить размер буфера (или оба).

desired bin width: 1Hz = 44100 / 44100  # A buffer size of 44100 would work in this instance 

по мере приближения размера буфера к частоте дискретизации проблема задержки становится все большей проблемой.

FFT Results per second = Sample Rate / Buffer Size = 44100/44100 = 1 FFT per second

(44100 образцов в секунду, заполнить буфер образца 44100 = 1 полный буфер в второй.)

Я понимаю, что БПФ больше, чем просто вычисление основной частоты (бин с самой высокой амплитудой), но правильно ли мое понимание БПФ в обнаружении высоты тона до сих пор?

есть ли какие-либо способы повышения точности БПФ без ущерба для латентности?

4 ответов


в дополнение к хорошему ответу @HartmutPfitzinger, рекомендующему нулевое заполнение и интерполяцию, стоит отметить, что существуют важные фундаментальные ограничения на информацию, которую вы можете получить от преобразования Фурье ограниченного по времени извлечения сигнала.

подумайте об ограничивающем случае нулевого заполнения - например, взятие одного образца, а затем заполнение его длительностью 1 сек, чтобы взять преобразование Фурье с разрешением 1 Гц. Понятно, что очень короткое фрагмент сигнала просто не содержит информации о периодичности. Интуитивно нам нужен фрагмент длиннее рассматриваемого периода, чтобы иметь возможность сказать что-либо о том, действительно ли сигнал повторяется в этот период.

мы можем сделать лучше, если у нас есть ограничения на форму периодического сигнала. Например, если мы ищем один синусоиды (т. е. мы знаем, что наш сигнал s (t) = A * cos (w*t + phi)), то мы можем решить для неизвестной амплитуды A, частота w и фаза phi с использованием всего трех образцов s (t). Тем не менее, довольно редко мы смотрим на сигналы, которые точно соответствуют этой формулировке. По крайней мере, мы ожидаем дополнительного шума, но чаще всего мы имеем много гармоник, т. е. неизвестную, несинусоидальную периодическую форму волны.

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

это иллюстрирует несколько контр-интуитивный, но очень фундаментальный предел:трудно решить частоту сигнала лучше, чем 1/T Гц на основе наблюдения короче, чем T секунд. это иногда называется принципом неопределенности, и математически это то же самое, что и принцип неопределенности Гейзенберга из квантовой механики.

наконец, еще один метод, который я использовал для улучшения разрешения дискретных преобразований Фурье, - это мгновенная частота, как описано в:

Toshihiko Abe, Takao Kobayashi, Satoshi Imai: надежная оценка высоты тона с усилением гармоник в шумных средах на основе мгновенной частоты. ICSLP 1996 (вы можете найти PDF онлайн, у меня закончилось мое пособие по ссылке).

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

http://labrosa.ee.columbia.edu/matlab/chroma-ansyn/ifgram.m

или в Python:

https://github.com/bmcfee/librosa/blob/master/librosa/core.py#L343


о ваш 1-й вопрос ("правильно ли мое понимание БПФ в обнаружении высоты тона до сих пор?") Я бы сказал Да, но я хотел бы указать на ловушку:

используя значения сверху, 3-й Бин на выходе БПФ будет представлять амплитуду при 258,398 Гц:

Bin Freq (Hz) = 3 * 86.132 = 258,396 Гц

имейте в виду, что 0-й бин представляет 0 Гц. Это значит что ящик представляя 3 * 86.132 = 258,396 Hz, находится в 4-й позиции результирующего массива.

и для завершения этой ловушки индекса, если у вас есть БПФ 512 точек (=fftsize), значение индекса 256 представляет частоту Найквиста (= частота выборки / 2). Это значит вы всегда получаете fftsize / 2+1 бункеров представляющий реальный частотный спектр, т. е. в вашем случае 257 бункеров.

о ваш 2-й вопрос, 2 широко распространенных и простых метода для увеличения обнаружения частоты точность:

  1. Zero-padding (см., например,некоторые ответы, почему используется нулевое заполнение)

  2. Параболическая Интерполяция (см., например,ответ)

наконец, a не-спросил ответ: абсолютно рекомендуется применять функция окна не только потому, что оно является предпосылкой для параболической интерполяции, но и потому, что уменьшает амплитуду значительных искусственных боковых долей.


Как правило, увеличение длины БПФ не только увеличивает задержку, но также может затруднить обнаружение частоты, поскольку она, вероятно, не является постоянной.
Обычная практика его использования перекрывающихся и оконных, взгляните на это:http://en.wikipedia.org/wiki/Spectral_density_estimation

существует несколько методов повышения точности оцениваемой частоты после обнаружения пика. Например, путем интерполяции на Фурье коэффициенты.
Взгляните на раздел 2 здесь или раздел 1.3 здесь


вы должны сначала понять, что 'поле' на самом деле. Когда одна нота сделана на гитаре или фортепиано, мы слышим не только одну частоту звуковой вибрации, но и совокупность нескольких звуковых колебаний, происходящих на разных математически связанных частотах. Элементы этого соединения вибраций на различных частотах называются гармониками или частицами. Например, если мы нажмем среднюю клавишу C на пианино, отдельные частоты гармоники композита будут начинаться с 261,6 Гц в качестве основной частоты, 523 Гц будет 2-й гармоники, 785 Гц будет 3-й гармоники, 1046 Гц будет 4-й гармоники и т.д. Более поздние гармоники являются целыми кратными основной частоте, 261,6 Гц (например: 2 x 261,6 = 523, 3 x 261,6 = 785, 4 x 261,6 = 1046 ).

ниже, на GitHub.com, это исходный код C++ для необычного двухступенчатого алгоритма, который я разработал, который может выполнять обнаружение шага в реальном времени на полифонических MP3-файлах во время воспроизведения на Windows. Это бесплатное приложение (PitchScope Player, доступный в интернете) часто используется для обнаружения нот гитары или саксофона соло на записи MP3. Вы можете скачать исполняемый файл для Windows, чтобы увидеть мой алгоритм в работе над mp3-файлом по вашему выбору. Алгоритм предназначен для определения наиболее доминирующего тона (музыкальной ноты) в любой момент времени в музыкальном файле MP3 или WAV. Примечание onsets точно выведены изменением в самом доминантном шаг (музыкальная нота) в любой момент во время записи MP3.

Я использую модифицированное логарифмическое преобразование DFT (аналогичное FFT) для первого обнаружения этих возможных гармоник, ища частоты с пиковыми уровнями (см. диаграмму ниже). Из-за того, как я собираю данные для моего измененного журнала DFT, мне не нужно применять функцию Windowing к сигналу, а также добавлять и перекрывать. И я создал DFT, поэтому его частотные каналы логарифмически расположены, чтобы непосредственно выровняйте с частотами, где гармоники создаются нотами на гитаре, саксофоне и т. д.

Мой шаг алгоритма обнаружения фактически в два этапа: а) сначала ScalePitch обнаружено ('ScalePitch имеет 12 возможных значения Pitch: {Е, F, F#, Г, Г#, А# Б, С, C#, D и D#} ) Б) и после ScalePitch определяется, то Октавы рассчитывается путем проверки всех гармоник для 4-х возможных Октав-отмечает кандидат. Алгоритм предназначен для обнаружения наиболее доминирующий тон (музыкальная нота) в любой момент времени в полифоническом MP3-файле. Это обычно соответствует нотам инструментального Соло. Те, кто интересуется исходным кодом C++ для моего двухэтапного алгоритма обнаружения шага, могут захотеть начать с функции Estimate_ScalePitch () в SPitchCalc.cpp файл в GitHub.com.

https://github.com/CreativeDetectors/PitchScope_Player

https://en.wikipedia.org/wiki/Transcription_(music)#Pitch_detection

enter image description here