2014-01-29 2 views
0

Моя цель - обрабатывать одну ноту с гитары (или другого инструмента) и преобразовывать ее в значение частоты.Получите частоту от входа микрофона и FFT-Java

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

Я понимаю, что для этого мне нужно использовать преобразование Фурье (и иметь класс, который будет выполнять БПФ). Тем не менее, я действительно не понимаю ввод/вывод алгоритма FFT - класс, который я использую, по-видимому, использует сложный векторный ввод и дает сложный векторный вывод. Что они представляют?

Кроме того, может ли кто-либо рекомендовать любые классы Java, которые могут обнаруживать и записывать ввод (и, если возможно, давать частоту или значения, которые могут быть подключены к БПФ?)?

Заранее спасибо.

+0

У вас есть код, который вы уже пробовали? – sircapsalot

+0

FFT, который я использую, можно найти здесь: http://nayuki.eigenstate.org/res/free-small-fft-in-multiple-languages/Fft.java –

+1

Здесь имеется множество дубликатов, пожалуйста, используйте функцию поиска , По пути вы узнаете, что «единственная нота» редко соответствует одной частоте. –

ответ

2

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

Если вы дадите это БПФ, так как это вещественный ввод, вы получите симметричный комплексный вывод (симметричный вокруг центрального значения) и можете игнорировать вторую половину комплексного векторного вывода и использовать только первая половина - то есть вторая половина будет симметричной (и, следовательно, «идентичной») первой половине. Выход представляет собой вклад каждой частоты в входную форму сигнала - по существу, каждый индекс «bin» или массив содержит информацию об этой амплитуде частоты. Для того, чтобы извлечь амплитуду вы хотите сделать:

magnitudeFFTData[i] = Math.sqrt((real * real) + (imaginary * imaginary)); 

где real и imaginary являются действительными и мнимыми частями комплексного числа на этой частоте бункере. Для того, чтобы получить частоту, соответствующую данному бункера, вам необходимо следующее:

frequency = i * Fs/N; 

где i является бен или индекс массива, Fs частоты дискретизации и N числа точек данных. Из проекта шахты, где я недавно использовал FFT:

for (int i = (curPersonFFTData.length/64); i < (curPersonFFTData.length/40); i++) { 
      double rr = (curPersonFFTData[i].getReal()); 
      double ri = (curPersonFFTData[i].getImaginary()); 

      magnitudeCurPersonFFTData[i] = Math.sqrt((rr * rr) + (ri * ri)); 
      ds.addValue(magnitudeCurPersonFFTData[i]); 
     } 

по разделам 64 и 40 являются произвольными и полезны только для моего случая, чтобы получить только определенные частотные компоненты, в отличие от всех частот, которые вы могли бы хотеть. Вы можете легко сделать все это в режиме реального времени.

Смежные вопросы