为什么我的FFT会提供与Windows Media Player不同的可视化输出?
我试图在android中使用Visualizer类实现音频频谱分析仪。
我在OnDataCaptureListener()
事件的onFftDataCapture()
方法中获取FFT数据,并使用drawLines()
在画布上绘制该数据。
但是频谱显示不正确。 我只能看到图表左侧的更改。 但在Window Media Player中,同一首歌曲的输出不同。 我错过了什么?
任何人都可以通过示例或链接帮助我解决这个问题吗?
码
mVisualizer.setDataCaptureListener(
new Visualizer.OnDataCaptureListener() {
public void onWaveFormDataCapture(Visualizer visualizer,
byte[] bytes, int samplingRate) {}
public void onFftDataCapture(Visualizer visualizer,
byte[] bytes, int samplingRate) {
mVisualizerView.updateVisualizer(bytes, samplingRate);
}
}, Visualizer.getMaxCaptureRate() / 2, false, true);
OnPaint()方法
for (int i = 0; i < mBytes.length / 2; i++) {
mPoints[i * 4] = i * 8;
mPoints[i * 4 + 1] = 0;
mPoints[i * 4 + 2] = i * 8;
byte rfk = mBytes[2 * i];
byte ifk = mBytes[2 * i + 1];
magnitude = (float) (rfk * rfk + ifk * ifk);
int dbValue = (int) (10 * Math.log10(magnitude));
mPoints[i * 4 + 3] = (float) (dbValue * 7);
}
canvas.drawLines(mPoints, mForePaint);
其中mVisualizer
是Visualizer类对象, mBytes
是从onFftDataCapture
事件mBytes
的FFT数据。
您可以在这里阅读更多关于事件返回的FFT数据的信息。
这是我在onFftDataCapture()
获得的值:
[90, -1, -27, 102, 13, -18, 40, 33, -7, 16, -23, -23, -2, -8, -11, -9, -8, -33, -29, 44, 4, -9, -15, -1, -2, -17, -7, 1, 1, 0, 3, -11, -5, 10, -24, -6, -23, 1, -9, -21, -2, 4, 9, -10, -14, -5, -16, 8, 6, -16, 14, 3, 7, 15, 10, -2, -15, -14, -5, 10, 8, 23, -1, -16, -2, -6, 4, 9, -1, 0, 0, 9, 1, 4, -2, 6, -6, -6, 8, -4, 6, 6, -4, -5, -5, -2, 3, 0, -1, 0, -7, 0, 2, 1, 0, 1, -1, 0, -1, 1, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, -1]
任何想法,链接都会有帮助。
@Chris Stratton更新
现在我正在1000Hz的文件中播放方波,并拍摄了该文件的屏幕截图。 你现在建议什么?
@ruhalde建议后更新
现在我正在播放频率扫描(20-20000 Hz)文件,并且此文件生成以下输出。
通过在正在开发的窗口引用和Android应用程序上播放已知量级的正弦曲线,可以准确计算出行为与预期之间的差异(希望能够理解为什么)。 同时测试一个合成频率,并查看它在每个屏幕上的绘制方式的位置,大小和特异性以及视强度。
例如,您可能会发现覆盖的频率范围的差异,或者可能是一个版本在对数轴(几十年或八度)上绘制频率,而不是线性频率。
如果您的数据源是麦克风,则您也可以在输入电路或设置中滚降。
链接的文档不解释正在使用的窗口功能。 此外,通过原始FFT输出,您可以将能量分配到相邻的分箱之间,因此它可以产生更一致的结果,将每个点显示为两个或三个相邻分区的平均值。
我会在你的代码中看到一些缺陷,主要在这里>>
Visualizer.getMaxCaptureRate() / 2
不需要使用最大捕获速率/ 2,只需要每秒10到30次之间的值(根据文档,即10000到30000之间的毫赫兹),这对于不闪烁并且不会太多对Visualizer内部资源施加压力。 此外,只能以20至20KHz的幅度(即可听频谱)进行绘制,在您的代码中,您正在绘制0和最高速率/ 2之间的每个频率,谁知道哪个频率是较高频率。 ..
除此之外,你需要一个纯正弦波,不断扫描从0到20Khz,看看它的样子,如果它没有压缩的RAW文件,效果会更好。 我不会使用任何OGG,MP3或PCM文件,我会尝试一个未压缩的WAV,既不使用方波,因为谐波,它在电表中产生大量尖峰。
如果你想要从这里获取扫描文件你是否尝试过使用另一个运行的线程,轮询getFft()而不是使用OnDataCaptureListener ??进行轮询。 我将在Runnable中尝试这种方法,并使用runOnUtiThread()方法更新UI。
链接地址: http://www.djcxy.com/p/54399.html上一篇: Why does my FFT gives a different visualizer output than Windows Media Player?
下一篇: Changing the way a JavaScript Alert() or Prompt() looks