У меня есть образец, хранящийся в буфере из DirectX. Это образец ноты, сыгранной и захваченной с инструмента. Как мне проанализировать частоту сэмпла (как это делает гитарный тюнер)? Я считаю, что задействованы БПФ, но у меня нет указаний на HOWTO.
Как вы анализируете основную частоту сэмпла PCM или WAV?
Ответы (7)
БПФ может помочь вам определить, где находится частота, но не может сказать вам, точно что это за частота. Каждая точка в БПФ представляет собой ячейку частот, поэтому, если в вашем БПФ есть пик, все, что вы знаете, это то, что нужная вам частота находится где-то в пределах этой ячейки или диапазона частот.
Если вы хотите, чтобы это было действительно точно, вам нужно длинное БПФ с высоким разрешением и большим количеством бинов (= много памяти и много вычислений). Вы также можете угадать истинный пик из БПФ с низким разрешением, используя квадратичную интерполяцию в логарифмическом масштабе спектра, который работает на удивление хорошо.
Если вычислительные затраты являются наиболее важными, вы можете попытаться получить сигнал в форме, в которой вы можете подсчитывать пересечения нуля, и тогда, чем больше вы считаете, тем точнее ваши измерения.
Однако ни один из них не будет работать, если отсутствует основной принцип. :)
Я описал несколько различных алгоритмов здесь, и интерполированное БПФ обычно является наиболее точным ( хотя это работает только когда основной гармоникой является самая сильная гармоника - в противном случае вам нужно умнее в его поиске), с переходом через нуль на втором месте (хотя это работает только для сигналов с одно пересечение за цикл). Ни одно из этих состояний не является типичным.
Имейте в виду, что частичные частоты выше основной частоты не являются идеальными гармониками во многих инструментах, таких как фортепиано или гитара. Каждый фрагмент на самом деле немного не соответствует действительности или негармонично. Таким образом, высокочастотные пики в БПФ не будут в точности равны целым кратным основной гармоники, а форма волны будет слегка меняться от одного цикла к другому, что нарушает автокорреляцию.
Чтобы получить действительно точное показание частоты, я бы посоветовал использовать автокорреляцию, чтобы угадать фундамент, а затем найти истинный пик с помощью квадратичной интерполяции. (Вы можете выполнить автокорреляцию в частотной области, чтобы сэкономить циклы процессора.) Есть много подводных камней, и правильный метод действительно зависит от вашего приложения.
Существуют и другие алгоритмы, основанные на времени, а не на частоте. Автокорреляция является относительно простым алгоритмом обнаружения основного тона. Ссылка: http://cnx.org/content/m11714/latest/
Я написал C# реализации автокорреляции и других алгоритмов, которые можно читать. Посетите http://code.google.com/p/yaalp/.
http://code.google.com/p/yaalp/source/browse/#svn/trunk/csaudio/WaveAudio/WaveAudio Список файлов, и PitchDetection.cs — это тот, который вам нужен.
(Проект под лицензией GPL, так что разберитесь в терминах, если используете код).
Гитарные тюнеры не используют БПФ или ДПФ. Обычно они просто считают нулевые пересечения. Вы можете не получить основную частоту, потому что некоторые сигналы имеют больше пересечений нуля, чем другие, но обычно таким образом вы можете получить кратное основной частоте. Этого достаточно, чтобы получить ноту, хотя вы можете ошибиться на одну или несколько октав.
Фильтрация нижних частот перед подсчетом пересечений нуля обычно позволяет избавиться от лишних пересечений нуля. Настройка фильтра нижних частот требует некоторого знания диапазона частот, который вы хотите обнаружить.
БПФ (быстрые преобразования Фурье) действительно будут задействованы. БПФ позволяют аппроксимировать любой аналоговый сигнал суммой простых синусоидальных волн фиксированной частоты и различной амплитуды. По сути, вы будете брать образец и разлагать его на пары амплитуда-> частота, а затем брать частоту, которая соответствует самой высокой амплитуде.
Надеюсь, другой читатель SO сможет заполнить пробелы, которые я оставляю между теорией и кодом!
Чуть конкретнее:
Если вы начнете с необработанного PCM во входном массиве, у вас в основном будет график зависимости амплитуды волны от времени. Выполнение БПФ преобразует его в частотную гистограмму для частот от 0 до 1/2 частоты дискретизации входного сигнала. Значение каждой записи в массиве результатов будет «силой» соответствующей подчастоты.
Таким образом, чтобы найти корневую частоту, учитывая входной массив размера N, выбранный с частотой S отсчетов в секунду:
FFT(N, input, output);
max = max_i = 0;
for(i=0;i<N;i++)
if (output[i]>max) max_i = i;
root = S/2.0 * max_i/N ;
Восстановление основных частот в звуковом сигнале PCM - сложная задача, и об этом можно было бы много говорить...
В любом случае, обычно метод, основанный на времени, не подходит для полифонических сигналов, потому что сложная волна, представленная суммой различных гармонических составляющих из-за нескольких основных частот, имеет скорость перехода через нуль, которая зависит только от самой низкой частотной составляющей... Также в В частотной области БПФ не является наиболее подходящим методом, поскольку частотные интервалы между нотами имеют экспоненциальную шкалу, а не линейную. Это означает, что постоянное частотное разрешение, используемое в методе БПФ, может быть недостаточным для разрешения более низких частот, если размер окна анализа во временной области недостаточно велик.
Более подходящим методом было бы преобразование с постоянной добротностью, которое представляет собой ДПФ, применяемый после процесса фильтрации нижних частот и прореживания на 2 (т. е. уменьшения вдвое частоты дискретизации на каждом шаге) сигнала, чтобы получить разные поддиапазоны с разной частотой. разрешающая способность. Таким образом, расчет ДПФ оптимизируется. Беда в том, что и разрешение по времени переменное, и увеличивается для нижних поддиапазонов...
Наконец, если мы пытаемся оценить основную частоту отдельной ноты, методы FFT/DFT подходят. Все меняется в полифоническом контексте, в котором части разных звуков перекрываются и суммируют/отменяют их амплитуду в зависимости от их разности фаз, и поэтому один спектральный пик может принадлежать разным гармоническим содержаниям (принадлежащим разным нотам). Корреляция в этом случае не дает хороших результатов...
Примените ТПФ, а затем из результатов получите основную частоту. Погуглив информацию о ДПФ, вы получите необходимую информацию - я бы дал вам ссылку на некоторые из них, но они сильно различаются по ожиданиям математических знаний.
Удачи.