2011-01-13 3 views
30

Я хочу создать звуковой спектр (как видно из this video) mp3-аудиофайла. В основном эта проблема требует вычисления fft аудиосигнала. Как мне запрограммировать это на C/C++?Как сгенерировать аудио спектр с использованием fft в C++?

Я просмотрел несколько библиотек с открытым исходным кодом, таких как FFTW, и я действительно не знаю, как их использовать для моей проблемы. Любая помощь будет принята с благодарностью. Заранее спасибо!

+1

Вы уже знаете C или C++? Если нет, лучше всего начать с чего-то более простого ... –

+0

Отъезд http://stackoverflow.com/questions/604453/analyze-audio-using-fast-fourier-transform –

+2

Вы знаете что-нибудь о DSP? FFTW - фантастический инструмент, но если вы ничего не знаете о преобразованиях Фурье/окна/разрешении/etc. будет очень сложно что-либо сделать. – cmannett85

ответ

49

Есть немало подобных/вопросы, связанные на SO уже, которые стоит прочитать, как ответы содержат много полезной информации и советов, но по сути вам нужно сделать это:

  • конвертировать аудио данные формат, требуемый FFT (например, Int -> поплавок, отдельный L/R каналов)
  • применение соответствующей window function (например Hann aka Hanning window)
  • применять FFT (Примечание: при использовании типичных комплексно-к сложному БПФ затем задать мнимую части от входного массива до нуля)
  • вычислить величину первых N/2 выходных БПФ бункеров (sqrt(re*re + im*im))
  • необязательно преобразовывать величины в дБ (вход) масштабировать (20 * log10(magnitude))
  • участок N/2 (лог) величины значения

Обратите внимание, что в то время FFTW - очень хороший и очень быстрый FFT, он может быть немного подавляющим для новичка - это тоже очень дорого, если вы хотите включить его в состав коммерческого продукта. Вместо этого я рекомендую начать с KissFFT.

+3

+1 - Единственное, что я добавил - это первый шаг, чтобы отделить левый (или правый, неважно) канал от аудиофайла. И еще один +1, если бы я мог использовать KissFFT, прежде чем сбрасывать FFTW. – mtrw

+0

@mtrw: спасибо за комментарии - добавлено примечание re разделение каналов L/R на первый шаг –

+10

Я бы добавил, что вы можете упростить, если вы делаете масштаб журнала - вместо вычисления величины (с sqrt), а затем масштабирования '20 * log10', возьмите квадрат величины (пропустив sqrt), а затем нарисуйте' 10 * log10'. Математически эквивалент, но сохраняет ненужный вызов 'sqrt'. –

Смежные вопросы