7

我正在尝试使用Visualizer类在 android 中实现音频频谱分析仪。

我在事件onFftDataCapture()方法中获取 FFT 数据,并使用.OnDataCaptureListener()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);

mVisualizerVisualizer 类对象在哪里,mBytes是从onFftDataCapture事件中获取的 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 的更新

现在我正在播放1000 Hz文件的方波并截屏。你现在建议什么?

1 KHz 频谱

在@ruhalde 建议后更新

现在我正在播放频率扫描(20-20000 Hz)文件,该文件生成以下输出。

频率扫描(20-20000 Hz)输出

4

2 回答 2

2

我会在你的代码中看到一些缺陷,主要在这里>>

Visualizer.getMaxCaptureRate() / 2

无需使用最大捕获率/2,只需在每秒 10 到 30 次之间设置一个值(根据文档,毫赫兹,虽然在 10000 到 30000 之间),这对于不闪烁和不放太多就足够了Visualizer 内部的资源压力。此外,仅绘制 20 到 20Khz 之间的幅度,即可听频谱,在您的代码中,您正在绘制 0 和捕获率 /2 之间的每个频率,这是最大速率 /2,谁知道哪个频率更高。 ..

除此之外,您还需要一个纯正弦波,不断地从 0 扫描到 20Khz 以查看它的外观,最好是未经压缩的 RAW 文件。我不会使用任何 OGG、MP3 或 PCM 文件,我会尝试未压缩的 WAV,也不会使用由于和声而产生大量以米为单位的尖峰的方波。

如果需要,请从此处获取扫描文件您 是否尝试过运行另一个线程,轮询 getFft() 而不是使用 OnDataCaptureListener 执行它??我将在 Runnable 中尝试这种方法,使用 runOnUtiThread() 方法更新 UI。

于 2011-08-18T18:36:18.710 回答
2

通过在 windows 参考和正在开发的 android 应用程序上播放已知幅度的正弦曲线,准确地弄清楚行为与预期有何不同(希望这会导致理解原因)可能很有用。一次测试一个合成频率,并查看其在每个屏幕上的绘制方式的位置、幅度和特异性以及表观幅度。

例如,您可能会发现覆盖频率范围内的差异,或者一个版本可能是在对数轴(十进制或八度音阶)上绘制频率,而不是线性轴。

如果您的数据源是麦克风,您的输入电路或设置也可能会出现衰减。

链接的文档没有说明正在使用什么窗口功能。此外,使用原始 FFT 输出,您可以将能量分布在相邻的 bin 之间,因此它可以产生更一致的结果,将每个点显示为两个或三个相邻点的平均值。

于 2011-08-16T19:31:24.723 回答