【问题标题】:Finding the peaks of a spectrogram寻找频谱图的峰值
【发布时间】:2012-05-04 17:49:26
【问题描述】:

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

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

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

因此,我想创建一个方法,例如查找我的 FFT 的前 5 个峰值并将它们及其索引提供给我。

我首先做了一个简单的方法,将频谱图的每个点两个两个进行比较,当符号发生变化时,我就知道有一个峰值。这种方法适用于理想信号(没有任何噪声)。但是,如果我添加噪音,它将变得完全无用。

我在java方面真的很差(我实际上是从这个项目开始的,基本上我上面描述的简单功能是我的杰作......只是让你了解我的水平)。

谁能帮助我?我真的很感激! :) 提前致谢!

祝你有美好的一天!

火神

【问题讨论】:

  • 音高不是 FFT 峰值频率。音高频率可能不是第一个峰值或任何峰值。特别是对于从吉他的低音录制的声音。
  • 感谢 hotpaw2 的回答。我也提出了音高的概念。据我了解,音高与频率有关,所以我认为找到频率可以让我找到音高。

标签: java fft frequency spectrogram


【解决方案1】:

我想说你最好的选择是将所有值作为一个数组读取,然后遍历它们并使用某种滚动平均值“平滑”它们。

之后,您将获得更平滑的曲线。使用这条曲线找到您的峰,然后返回原始数据并使用峰索引找到那里的实际峰。

伪代码:

// 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]];
}

非常基本且非常暴力,但它应该能让你走上正确的任务轨道。

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

【讨论】:

  • 查尔斯您好。非常感谢您的回答。如果我理解正确,您所做的平滑是取我的原始数据的 5 个值的平均值。像这样,所有来自噪音的小峰值都会因为一个真正的峰值而减少。那是对的吗?但是,我不明白的是,如果我寻找第一个峰值之后,我会得到一个与我的真实峰值索引不对应的峰值索引。而且我不知道如何取回真实的....
  • 基本上,您所做的只是对小尖峰进行平均,这意味着平滑线将代表一个总体趋势:平坦、向上、向下、峰值等。问题可能是,如果在原始数据中的“真实”峰值的任一侧都有一个严重的向下或向上峰值,这可能会以一种或另一种方式倾斜平均值,人为地将峰值向任一方向移动一点。您必须使用算法来减少这些噪声峰值的影响。
  • 感谢查尔斯的回答。实际上,我通过使用 Harmonic Product Spectrum 采用了一种全新的方法,现在它可以正常工作了。非常感谢您的帮助!
猜你喜欢
  • 1970-01-01
  • 2014-04-24
  • 2018-06-16
  • 1970-01-01
  • 2014-08-30
  • 2018-05-26
  • 2015-02-10
  • 2021-06-22
  • 1970-01-01
相关资源
最近更新 更多