处理音频的最佳方法是什么,以便我可以输出正在播放的音符?我正在为大学作业创建吉他调音器,并且我是 Android 开发的新手。
我已经看过关于从 Google API 录制声音的 Android 示例,但我想知道从那里去哪里?
我知道我必须进行傅立叶变换或其他操作才能获得频率,只是想知道是否有人对如何做到这一点有任何建议?
一旦我们可以在屏幕上显示正确的频率,我们将完成大部分项目。
谢谢你的帮助。
处理音频的最佳方法是什么,以便我可以输出正在播放的音符?我正在为大学作业创建吉他调音器,并且我是 Android 开发的新手。
我已经看过关于从 Google API 录制声音的 Android 示例,但我想知道从那里去哪里?
我知道我必须进行傅立叶变换或其他操作才能获得频率,只是想知道是否有人对如何做到这一点有任何建议?
一旦我们可以在屏幕上显示正确的频率,我们将完成大部分项目。
谢谢你的帮助。
如果您从未做过 Android 开发,并且在数字信号处理和傅里叶变换方面几乎没有经验,那么您将面临一个艰巨的挑战。
另一方面,如果您可以按照 anthropomo 建议的那样使用现有的库来完成作业,那么您可能会有很好的机会完成它。
但是,如果您的教授不允许您使用现有的库,您将需要解决以下难题:
您的程序如何自动找到正在播放的音符的基频?看看这个真正的古典原声吉他演奏 E2 音符的频率/频率分贝幅度图。观察到基频 (82.4 Hz) 比一次谐波低约 17 分贝 (17 dB)(一次谐波为 164.8 Hz)。
下面是同一图的特写,您可以更清楚地看到基本峰值:
基频比一次谐波衰减 17 dB,这是一个很大的衰减。下面是相同的 E2 音符频谱,但现在它绘制在线性频率幅度轴上(垂直轴现在是线性频率幅度而不是分贝频率幅度)。现在您可以更清楚地看到基频峰值实际低于一次谐波有多远。
您的程序必须自动检测 82.4 Hz 的 17 dB 衰减基波,但是在您的程序无法提前知道用户在他的吉他上弹奏哪个音符的一般情况下,您如何做到这一点?
上述频谱适用于古典原声吉他上的 E2。钢弦吉他上 E2 的频谱有何不同?放大电吉他上的 E2 怎么样?您的程序将如何处理这些不同光谱之间的差异?
问题不是微不足道的。问题是你有多少时间来完成这项作业,以及你的教授认为什么是已完成的作业。
这篇参考给出了更深入的理解:乐器频谱到 102.4 KHz
您可以在此处绘制频谱并听到 E2 到 Bb5 的吉他音符:乐器频谱
不要使用裸 FFT 幅度或其他频率峰值估计器。对于大多数吉他的低音弦,它们会给您带来非常糟糕/错误的结果。音高是人类的心理声学感知现象,通常与 FFT 频率不同(除了纯正弦音,不像真正的弦乐器产生的音)。
谷歌“音高检测”和“音高估计”方法代替。一些可能性包括加权自相关、AMDF、ASDF、倒谱/倒谱分析、谐波乘积频谱分析以及诸如 RAAPT 和 YAPT 之类的复合算法。关于其中一些估计算法的几篇学术论文的参考资料可能在我的网页上: http: //www.nicholson.com/rhn/dsp.html#1
如果您的讲师同意您使用库进行音频处理,这里是使用 libpd 的完整 android 吉他调音器应用程序的源代码:
https://github.com/nettoyeurny/Making-Musical-Apps/tree/master/android/GuitarTuner
要使用它,您还需要学习 Pure Data 音频合成编程语言的基础知识。调谐器所需的工具并不太广泛,并在上述应用程序中进行了布局。显然,您需要做一些工作才能使这成为您自己的工作。
这是使用纯数据的一个很好的介绍:
吉他特纳应用的好例子。使用 Jtransfrom。
本文对您可能使用的音高检测算法进行了全面评估。
如前所述,自相关是一种易于实现的方法,但不是特别准确——尤其是在经常缺少基频的现实世界乐器信号上。FFT 方法需要大量的后处理。
我怀疑对于大学作业,您最好使用一个并不总是准确的完整工作系统,而不是一个不完整的准确系统。