2009-03-02 2 views
95

Я пытаюсь создать графический анализатор спектра в python.Анализ звука с использованием быстрого преобразования Фурье

В настоящее время я читаю 1024 байта 16-битного двухканального 44,100 Гц аудиосигнала с частотой дискретизации и усредняет амплитуду двух каналов вместе. Итак, теперь у меня есть массив из 256 подписанных шорт. Теперь я хочу преформировать fft на этом массиве, используя модуль, например numpy, и использовать результат для создания графического анализатора спектра, который для начала будет составлять всего 32 бара.

Я прочитал статьи в Википедии о быстром преобразовании Фурье и дискретном преобразовании Фурье, но я все еще не понимаю, что представляет собой результирующий массив. Это то, что массив выглядит после того, как я преформ в FFT на моем массиве с помощью NumPy:

[ -3.37260500e+05 +0.00000000e+00j 7.11787022e+05 +1.70667403e+04j 
    4.10040193e+05 +3.28653370e+05j 9.90933073e+04 +1.60555003e+05j 
    2.28787050e+05 +3.24141951e+05j 2.09781047e+04 +2.31063376e+05j 
    -2.15941453e+05 +1.63773851e+05j -7.07833051e+04 +1.52467334e+05j 
    -1.37440802e+05 +6.28107674e+04j -7.07536614e+03 +5.55634993e+03j 
    -4.31009964e+04 -1.74891657e+05j 1.39384348e+05 +1.95956947e+04j 
    1.73613033e+05 +1.16883207e+05j 1.15610357e+05 -2.62619884e+04j 
    -2.05469722e+05 +1.71343186e+05j -1.56779748e+04 +1.51258101e+05j 
    -2.08639913e+05 +6.07372799e+04j -2.90623668e+05 -2.79550838e+05j 
    -1.68112214e+05 +4.47877871e+04j -1.21289916e+03 +1.18397979e+05j 
    -1.55779104e+05 +5.06852464e+04j 1.95309737e+05 +1.93876325e+04j 
    -2.80400414e+05 +6.90079265e+04j 1.25892113e+04 -1.39293422e+05j 
    3.10709174e+04 -1.35248953e+05j 1.31003438e+05 +1.90799303e+05j... 

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

ответ

187

Массив, который вы показываете, представляет собой коэффициенты преобразования Фурье аудиосигнала. Эти коэффициенты могут использоваться для получения частотного содержимого аудио. БПФ определяется для комплекснозначных входных функций, поэтому коэффициенты, которые вы выберете, будут мнимыми числами, даже если ваш ввод - все реальные значения. Чтобы получить количество мощности на каждой частоте, вам нужно рассчитать величину коэффициента FFT для каждой частоты. Это не просто действительная составляющая коэффициента, вам нужно вычислить квадратный корень из суммы квадрата его действительной и мнимой составляющих. То есть, если ваш коэффициент равен + b * j, то его величина равна sqrt (a^2 + b^2).

После того, как вы рассчитали величину каждого коэффициента FFT, вам нужно выяснить, к какой аудиочастоте относится каждый из коэффициентов FFT. N-точечный FFT даст вам частотное содержание вашего сигнала на N равноотстоящих частотах, начиная с 0. Поскольку ваша частота дискретизации составляет 44100 выборок в секунду. и количество точек в вашем FFT равно 256, ваш частотный интервал равен 44100/256 = 172 Гц (приблизительно)

Первым коэффициентом в вашем массиве будет коэффициент частоты 0. Это в основном средний уровень мощности для всех частот. Остальные ваши коэффициенты будут отсчитывать от 0 до 172 Гц, пока вы не достигнете 128. В БПФ вы можете измерять частоты до половины ваших выборочных точек. Прочтите эти ссылки на Nyquist Frequency и Nyquist-Shannon Sampling Theorem, если вы являетесь обжором для наказания и должны знать, почему, но основным результатом является то, что ваши более низкие частоты будут реплицироваться или aliased в высокочастотных ковшиках.Таким образом, частоты будут начинаться с 0, увеличиваясь на 172 Гц для каждого коэффициента до коэффициента N/2, а затем уменьшаться на 172 Гц до коэффициента N - 1.

Этого должно быть достаточно информации, чтобы вы начали. Если вы хотите получить гораздо более доступное введение в БПФ, чем указано в Википедии, вы можете попробовать Understanding Digital Signal Processing: 2nd Ed.. Это было очень полезно для меня.

Это то, что представляют эти цифры. Преобразование в процентах от высоты может быть выполнено путем масштабирования величины каждой частотной составляющей на сумму всех составляющих величин. Хотя это даст вам только представление относительного распределения частот, а не фактическую мощность для каждой частоты. Вы можете попробовать масштабировать максимальную возможную величину для частотной составляющей, но я не уверен, что это проявится очень хорошо. Самый быстрый способ найти работоспособный коэффициент масштабирования - это экспериментировать с громкими и мягкими аудиосигналами, чтобы найти правильную настройку.

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

+3

+1 за отличный ответ и заставив меня изучить новую идиому, так как Я не носитель английского языка.;) – macbirdie

+1

+1 Удивительно, это помогло мне понять, что я делаю неправильно. – Davido

+4

+1 - Хотя я знаю о БПФ уже - одно из лучших простых объяснений в Интернете. – OldTinfoil

10

у вас есть образец, длина которого равна 256/44100 = 0,00580499 секунд. Это означает, что ваше частотное разрешение составляет 1/0,00580499 = 172 Гц. 256 значений, которые вы получаете от Python, соответствуют частотам, в основном, от 86 Гц до 255 * 172 + 86 Гц = 43946 Гц. Выбираемые числа - это комплексные числа (следовательно, «j» в конце каждого второго номера).

Редакцией: FIXED НЕПРАВИЛЬНО ИНФОРМАЦИЯ

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

Если вы хотите иметь 32 бара, вы должны, насколько я понимаю, принять среднее значение из четырех последовательных амплитуд, получив 256/4 = 32 бара, как вы хотите.

+0

Привет, извините за первоначальный (неправильный) ответ ... не получил правильную математику. Это должно быть правильно. –

+4

Обратите внимание, что если c - комплексное число, sqrt (c.real ** 2 + c.imag ** 2) == abs (c) – tzot

25

Хотя эта тема лет, я нашел ее очень полезной. Я просто хотел дать свой вклад всем, кто нашел это, и пытается создать нечто подобное.

Что касается деления на стержни, это не должно быть сделано, как полагают antti, разделив данные поровну в зависимости от количества баров. Наиболее полезным было бы разделить данные на октавные части, причем каждая октава удваивает частоту предыдущего. (т.е. 100 Гц - одна октава выше 50 Гц, что на октаву выше 25 Гц).

В зависимости от того, сколько баров вы хотите, вы разделите весь диапазон на 1/X октавные диапазоны. На основании данной центральной частоты А на панели, вы получаете верхние и нижние пределы бара от:

upper limit = A * 2^(1/2X) 
lower limit = A/2^(1/2X) 

Чтобы вычислить следующую частоту прилегающего центра вы используете аналогичный расчет:

next lower = A/2^(1/X) 
next higher = A * 2^(1/X) 

Затем вы усредняете данные, которые вписываются в эти диапазоны, чтобы получить амплитуду для каждого бара.

Например: Мы хотим разделить на диапазоны в 1/3 октавы, и мы начнем с центральной частоты 1 кГц.

Upper limit = 1000 * 2^(1/(2 * 3)) = 1122.5 
Lower limit = 1000/2^(1/(2 * 3)) = 890.9 

Учитывая 44100Hz и 1024 выборки (43hz между каждой точки данных) мы должны усреднить значения от 21 до 26. (890,9/43 = 20,72 ~ 21 и 1122,5/43 = 26,10 ~ 26)

(1/3 октавных бара доставят вам около 30 баров между ~ 40 Гц и ~ 20 кГц). Как вы уже можете понять, по мере того, как мы поднимаемся выше, мы будем усреднять больший диапазон чисел. Низкие бары обычно включают только 1 или небольшое количество точек данных. В то время как более высокие бары могут составлять в среднем сотни точек. Причина в том, что 86hz - октава выше 43hz ... в то время как 10086hz звучит почти так же, как 10043hz.