Android 2.3 Visualizer - Проблемы с пониманием getFft()
Первый раз здесь, так что заранее извините за любое убойное форматирование.
Так что я совершенно новичок в DSP, поэтому у меня есть только очень общее представление о преобразовании Фурье. Я пытаюсь создать приложение визуализатора для Android SDK 9, которое включает класс Visualizer в android.media.audiofx.Visualizer http://developer.android.com/reference/android/media/audiofx/Visualizer.html
Javadoc для метода getFft(), который я использую состояния:
"Возвращает захват частоты воспроизводимого в данный момент аудиоконтента. Захват представляет собой БПФ с 8-битной величиной. Обратите внимание, что размер БПФ равен половине указанного размера захвата, но обе стороны спектра возвращаются, давая количество байтов, равное к размеру захвата. "
Прежде всего, что означает "обе стороны спектра"? Чем этот вывод отличается от стандартного БПФ?
Вот пример выходных данных байтового массива, getFft() получил 124 балла, чтобы упростить его, и я взял первые 31 лот. Вот величины первых 31 корзин:
{123, -2, -23, -3, 6, -16, 15, -10, -8, -12, 9, -9, 17, -6, -18, -22, -8, 4, -5, -2, 10, -3, -11, 3, -4, -11, -8, 15, 16, 11, -12, 12}
Любая помощь или объяснение будет принята с благодарностью!
Редактировать: Итак, после того, как я посмотрел на кучу графиков, похоже, что часть моей проблемы в том, что Google не указывает, какая единица измерения используется. Почти все другие измерения выполняются в мГц, было бы справедливо предположить, что выход FTT также в мГц? Есть ли место, где я могу увидеть исходный код класса Visualizer, так что, возможно, я смогу выяснить, что, черт возьми, происходит на самом деле под капотом?
Я пошел вперед и взял все выходные данные getFft ()
93, -2, -28, -16, -21, 19, 44, -16, 3, 16, -9, -4, 0, -2, 21, 16, -3, 1, 2, 4, -3, 5, 5, 10, 6, 4, -9, 7, -2, -1, 2, 11, -1, 5, -8, -2, -1, 4, -5, 5, 1, 3, -6, -1, -5, 0, 0, 0, -3, 5, -4, -6, -2, -2, -1, 2, -3, 0, 1, -3, -4, -3, 1, 1, 0, -2, -1, -1, 0, -5, 0, 4, -1, 1, 1, -1, 1, -1, -3, 2, 1, 2, -2, 1, 0, -1, -2, 2, -3, 4, -2, -2, 0, 1, -4, 0, -4, 2, -1, 0, -3, -1, -1, -1, -5, 2, -2, -2, 0, -3, -2, 1, -5, -2, 0, 0, 0, -2, -2, -1, -1, -1, -2, 0, 3, -3, -1, 0
Поэтому, если я правильно понимаю, мои выходные данные должны быть от -N до 0 до N. -N до 0 должны выглядеть как от 0 до N. Но когда я смотрю на эти амплитуды, я не вижу зеркальных данных. Похоже, Google указывает, что вывод должен быть от 0 до N по обе стороны спектра. Поэтому я должен быть в состоянии взять данные из (output.length-1)/2 в output.length-1. Отрицательные амплитуды движутся быстрее, чем частота дискретизации, а положительные амплитуды движутся медленнее, чем частота дискретизации. Я правильно понял?
2 ответа
Частота на выходе БПФ k образца определяется как:
Fk = k * Fs / N, k = 0,1,...,N-1
где
Fs
частота дискретизации входа временного рядаN
это количество образцов, используемых для вычисления БПФ
Две стороны спектра относятся к положительным и отрицательным частотам на выходе БПФ. БПФ заставляет частотный выход быть периодическим с периодом Fs. Если вы посмотрите на выход FFT, он охватывает частоты от 0 до Fs. Часто выгодно просматривать спектр в диапазоне от -0,5*Fs до 0,5*Fs, вместо этого сдвигая выход FFT с 0,5*Fs -> Fs на -0,5*Fs -> 0, поскольку они равны из-за периодичности.
Для реальных значений сигналов, таких как те, которые вы используете при обработке звука, вывод отрицательной частоты будет зеркальным отображением положительных частот. Из-за этого часто только одна сторона спектра используется при анализе реальных сигналов.
Другим важным моментом является значение 0,5*Fs, которое известно как частота Найквиста. Сигнал может только точно представлять частоты вплоть до частоты Найквиста, и все, что выше него, будет совмещено (свернуто) обратно в спектр, вызывая искажение.
Так что на самом деле все, о чем вы должны беспокоиться для целей визуализации, это выходные данные FFT, соответствующие диапазону частот от 0 до Fs/2, поскольку они являются значимыми выборками для реального сигнала с частотой дискретизации Fs.
На случай, если это кому-нибудь поможет, я создал визуализатор, который берет вывод из MediaPlayer и отображает визуализацию. Он работает как с нормальным сигналом, так и с данными БПФ:
https://github.com/felixpalmer/android-visualizer
Он включает в себя код для преобразования вывода getFft() во что-то визуально значимое.