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);

はVisualizermVisualizerクラスのオブジェクトで、はイベントmBytesから取得した FFT データです。onFftDataCapture

イベントによって返される 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]

どんなアイデアでも、リンクは役に立ちます。

部分値描画

完全な値の描画

@クリス・ストラットンのアップデート

今、私は1000 Hz のファイルで方形波を再生していて、そのスクリーン ショットを撮りました。あなたは今何を提案しますか?

1KHzスペクトル

@ruhaldeの提案後に更新

現在、周波数スイープ (20 ~ 20000 Hz)ファイルを再生しています。このファイルは次の出力で生成されます。

周波数スイープ (20 ~ 20000 Hz) 出力

4

2 に答える 2

2

Windowsリファレンスと開発中のAndroidアプリの両方で既知の大きさの正弦波を再生することにより、動作が予想とどのように異なるかを正確に把握することが役立つ場合があります(理由の理解につながることを期待して)。一度に1つの合成された周波数をテストし、それが各画面にどのようにプロットされるか、および見かけの等級の位置、大きさ、および特異性を確認します。

たとえば、カバーされている周波数範囲の違いを発見したり、1つのバージョンが線形軸ではなく対数軸(数十年またはオクターブ)に周波数をプロットしている場合があります。

データソースがマイクの場合は、入力回路または設定をロールオフすることもできます。

リンクされたドキュメントでは、使用されているウィンドウ関数について説明されていません。さらに、生のFFT出力を使用すると、隣接するビン間でエネルギーを分散させることができるため、より一貫性のある結果を生成して、各ポイントを2つまたは3つの隣接するビンの平均として表示できます。

于 2011-08-16T19:31:24.723 に答える
2

主にここに、コードにいくつかの欠陥があります>>

Visualizer.getMaxCaptureRate() / 2

最大キャプチャレート/2を使用する必要はありません。1秒あたり10〜30回の値を入力するだけです(ドキュメントによるとミリヘルツ、10000〜30000です)。これは、ちらつきや入れすぎを防ぐのに十分です。 Visualizer内のリソースへの圧力。また、可聴スペクトルである20〜20Khzの大きさでのみ描画します。コードでは、0からキャプチャレート/ 2(最大レート/ 2)までのすべての周波数を描画します。これにより、どちらの周波数が高いかがわかります。 ..

それに加えて、圧縮されていないRAWファイルの場合は、どのように見えるかを確認するために、常に0から20Khzまでスイープする純粋な正弦波が必要になります。OGG、MP3、またはPCMファイルは使用しません。非圧縮のWAVを試してみます。また、ハーモニーのためにメーターに多くのスパイクを生成する方形波も使用しません。

必要に応じて、ここからスイープファイルを取得します 。OnDataCaptureListenerで実行する代わりに、getFft()をポーリングして、別のスレッドを実行してみましたか?Runnable内でこのアプローチを試し、runOnUtiThread()メソッドを使用してUIを更新します。

于 2011-08-18T18:36:18.710 に答える