找到频谱图的峰值

时间:2012-05-04 17:49:27

标签: java fft frequency spectrogram

我目前正在为第二年的项目工作。我应该在java中编码一个调谐器。我选择做吉他调音器。

在网上浏览后,我找到了一个用于进行FFT的java代码。我改变了一点,了解它并进行了测试。我知道它工作正常(我制作了一个图表并使用简单的正弦函数查看了不同的峰值。)

我现在正试图找到基本频率。据我所知,这个频率是由第一个峰值给出的。

我想创建一个方法,例如找到我的FFT的前5个峰值,然后用它们的索引给我。

我首先做了一个简单的方法,我在谱图的每个点上比较两个,当符号改变时,我知道那里有一个峰值。这种方法适用于理想信号(没有任何噪声)。但是,如果我添加噪音,它就变得毫无用处。

我在java中真的很糟糕(我实际上是从这个项目开始的,基本上我上面介绍的简单函数是我的主要部分....只是让你了解我的水平)。

任何人都可以帮助我吗?我真的很感激! :) 提前谢谢!

祝你有美好的一天!

fireangel

1 个答案:

答案 0 :(得分: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]];
}

非常基本且非常蛮力,但它应该让你在正确的轨道上进行任务。

您需要使用算法来平滑数据,使其具有代表性,并在平滑数据指示的位置找到实际峰值(因为它不准确)。