2012-05-04 4 views
0

В настоящее время я работаю над проектом на 2-й год. Я должен закодировать в java тюнер. Я выбрал гитарный тюнер.Поиск пиков спектрограммы

Осмотревшись в интернете, я нашел код Java, чтобы сделать БПФ. Я немного изменил его, понял и проверил. Я знаю, что он отлично работает (я сделал график и посмотрел на разные пики, используя простые функции синусов).

Теперь я пытаюсь найти основную частоту. Насколько я понимаю, эта частота задается первым пиком.

Я хотел бы создать метод, который найдет, например, первые 5 пиков моего БПФ и дает их мне с их индексами.

Сначала я сделал простой способ, когда я сравнивал по две по две точки моей спектрограммы, и когда знак менялся, я знал, что существует пик. Этот метод отлично работает с идеальными сигналами (без шума). Однако, если я добавляю шум, он становится совершенно бесполезным.

Я действительно плохой в java (я действительно начал с этого проекта и в основном простую функцию, описанную выше, это моя мастерская штука ... просто чтобы вы поняли мой уровень).

Может ли кто-нибудь мне помочь? Я был бы очень признателен! :) Спасибо заранее!

Отличный день!

Fireangel

+0

Шаг не является максимальной частотой FFT. Частота шага может не быть первым пиком или любым пиком. Особенно для звуков, записанных на низких струнах гитары. – hotpaw2

+0

Возможный дубликат: http://stackoverflow.com/questions/8699360/audio-analysis-frequency-vs-pitch – hotpaw2

+0

Спасибо, hotpaw2 за ответ. Я также придумал понятие поля. Из того, что я понял, шаг связан с частотой, поэтому я подумал, что найти частоту может получить меня. – fireangel3000

ответ

0

Я бы сказал, что вам лучше всего будет читать все значения как массив, а затем запустить над ними и «гладкий» их, используя скользящее среднее значение некоторого вида.

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

псевдокод:

// Your raw data 
int[] data = getData(); 

// This is an array to hold your 'smoothed' data 
int[] newData = new int[data.length]; 

// Iterate over your data, smooth it, and read it into your smoothed array 
for (i < data.length) { 
    newData[i] = (data[i-2] + data[i-1] + data[i] + data[i+1] + data[i+2])/5; 
} 

// Use your existing peak finding function on your smoothed data, and get 
// another array of the indexes your peaks occur. 
int[] peakIndexes = yourPeakFindingFunction(newData); 

// Create an array to hold your final values. 
int[] peakValues = new int[peakIndexes.length]; 

// Iterate over your peak indexes and get the original data's value at that location. 
for(i < peakIndexes.length) { 
    peadValues[i] = data[peakIndexes[i]]; 
} 

Очень простой и очень грубая сила, но он должен получить Вас на правильном пути для присваивания.

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

+0

Привет, Чарльз. Большое спасибо за ваш ответ. Если я правильно понимаю, сглаживание, вы делаете, принимая среднее значение 5 значений моих исходных данных. Подобно этому все маленькие пики, исходящие от шума, будут уменьшаться из-за одного реального пика. Это верно? Однако я не понимаю, что после того, как я буду искать первый пик, я получу индекс пика, который не соответствует индексу моего реального пика. И я не вижу, как вернуть реальный .... – fireangel3000

+0

В основном, вы делаете просто усреднение небольших всплесков, что означает, что сглаженная линия будет представлять собой общую тенденцию: плоскую, вверх, вниз, и т.п.Проблема может заключаться в том, что, если есть сильный нисходящий или восходящий всплеск по обе стороны от вашего «реального» пика в ваших исходных данных, это может исказить среднее значение так или иначе, искусственно перемещая пик в любом направлении. Вам придется играть с алгоритмом, чтобы уменьшить влияние этих пиков шума. – Charles

+0

Спасибо за ответ Чарльз. Я действительно принял совершенно новый подход, используя Harmonic Product Spectrum, и теперь он отлично работает. Большое спасибо за вашу помощь! – fireangel3000

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