Почему мой FFT выдает другой вывод визуализатора, чем Windows Media Player? - PullRequest
7 голосов
/ 14 августа 2011

Я пытаюсь реализовать анализатор спектра звука в Android с использованием Visualizer class.

Я получаю данные FFT в методе onFftDataCapture() события 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);

Где mVisualizer - объект класса Visualizer, а mBytes - БПФ Данные, полученные из события 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]

Любая идея, ссылка будет полезной.

Partial value drawing

full value drawing

Обновление для @Chris Stratton

Теперь я играю квадратную волну при 1000 Гц файл и сделал снимок экрана этого. Что вы предлагаете сейчас?

1 KHz spectrum

Обновлено после предложения @ruhalde

Сейчас я играю Файл развертки частоты (20-20000 Гц) , и этот файл генерируется после вывода.

Frequency sweep (20-20000 Hz) output

Ответы [ 2 ]

2 голосов
/ 18 августа 2011

Я увижу некоторые недостатки в вашем коде, в основном здесь >>

Visualizer.getMaxCaptureRate() / 2

Нет необходимости использовать максимальную скорость захвата / 2, просто поместите значение где-то между 10 и 30 разами в секунду (миллигерц в соответствии с документацией, то есть между 10000 и 30000, хотя), это было бы достаточно, чтобы не мерцало и не слишком большое давление на ресурсы внутри Visualizer. Кроме того, рисуйте только с величинами от 20 до 20 кГц, то есть слышимым спектром, в вашем коде вы рисуете каждую частоту от 0 до вашей скорости захвата / 2, то есть максимальной скорости / 2, которая знает, какая частота выше. ..

Кроме того, вам понадобится чистая синусоида, постоянно колеблющаяся от 0 до 20 кГц, чтобы увидеть, как она выглядит, лучше, если это RAW-файл без сжатия. Я не буду использовать файлы OGG, MP3 или PCM, я попробую несжатый WAV, а также не буду использовать прямоугольную волну, которая генерирует много пиков в метре из-за гармоник.

Получите файлы развертки от здесь, если хотите Вы пробовали с другим работающим потоком, опрашивая getFft () вместо того, чтобы делать это с OnDataCaptureListener ??. Я попробую этот подход внутри Runnable, обновляя интерфейс с помощью метода runOnUtiThread ().

2 голосов
/ 16 августа 2011

Возможно, было бы полезно выяснить, как именно поведение отличается от ожидаемого (в надежде, что это приведет к пониманию причины), играя синусоиды известной величины как в справочной системе Windows, так и в разрабатываемом приложении для Android.Проверяйте одну синтезированную частоту за раз и смотрите положение, величину и специфичность того, как она отображается на каждом экране, и кажущуюся величину.

Вы можете, например, обнаружить различия в охватываемом диапазоне частот,или, возможно, одна версия отображает частоту на логарифмической оси (десятилетия или октава), а не на линейной.

Если ваш источник данных - микрофон, вы также можете иметь спад во входной схеме или настройках.

Связанный документ не объясняет, какая оконная функция используется.Кроме того, с необработанным выходным сигналом FFT вы можете распределять энергию между соседними ячейками, что позволяет получить более согласованный результат, отображая каждую точку как среднее из двух или трех смежных.

...