我正在尝试为 Android 手机制作一个简单的音高检测应用程序。我已经让手机显示我计算出的自相关值的图表,这些值存储在一维 double 组中。现在我需要弄清楚如何检测数组中的重复模式。这是自相关图的屏幕截图,其中我以稳定的音调哼唱:
我尝试实现此幻灯片中给出的一维数组的递归峰值查找算法:http://courses.csail.mit.edu/6.006/spring11/lectures/lec02.pdf但我在 Android 上遇到内存不足错误。
接下来我尝试实现类似这样的算法来查找二阶导数:https://stackoverflow.com/a/3869172但是来自手机的自相关值非常不稳定,以至于它发现了太多的最小值和最大值。
我需要弄清楚如何做是将某种过滤器应用于自相关数据以使其平滑,但我的数学很烂,不知道该怎么做。我尝试将自相关值四舍五入到小数点后几位,但没有得到我想要的结果。
基本上,我需要帮助来弄清楚如何找到重复模式的整体最大值(实际上只有第一个可能就可以了)。在上面的屏幕截图中,该模式是一个高峰,后面跟着两个较短的峰。我需要知道第二个高峰何时发生,以便计算音高。
最佳答案
您正在尝试估计样本数据中振幅峰值的频率。您可以执行此操作,而无需手动查找估计峰值,然后计算出频率。相反,您可以使用快速傅里叶变换,它将幅度与时间的关系图转换为频率与时间的关系图。这里对这个概念有很好的描述 http://en.wikipedia.org/wiki/Fast_Fourier_transform
...并且有几个实现转换的 Java 库,包括 Apache Commons 数学 - http://commons.apache.org/proper/commons-math/apidocs/org/apache/commons/math3/transform/FastFourierTransformer.html 和 JTransform - https://sites.google.com/site/piotrwendykier/software/jtransforms
关于java - 检测一维 Java 数组中局部最大值的一般模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17628181/