Я пытаюсь создать графический анализатор спектра на 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 столбцов. Кроме того, следует ли мне усреднять 2 канала вместе?
Хотя этой ветке уже много лет, я нашел ее очень полезной. Я просто хотел поделиться своим мнением со всеми, кто находит это и пытается создать что-то подобное.
Что касается деления на бары, это не следует делать, как предлагает antti, путем поровну деления данных в зависимости от количества баров. Наиболее полезным было бы разделить данные на октавные части, каждая октава в два раза больше частоты предыдущей. (т.е. 100 Гц - это на октаву выше 50 Гц, что на октаву выше 25 Гц).
В зависимости от того, сколько тактов вы хотите, вы делите весь диапазон на диапазоны октавы 1 / X. Основываясь на заданной центральной частоте A на полосе, вы получаете верхний и нижний пределы полосы из:
Чтобы вычислить следующую соседнюю центральную частоту, вы используете аналогичный расчет:
Затем вы усредняете данные, которые попадают в эти диапазоны, чтобы получить амплитуду для каждого столбца.
Например: мы хотим разделить диапазоны на 1/3 октавы и начать с центральной частоты 1 кГц.
Учитывая 44100 Гц и 1024 отсчета (43 Гц между каждой точкой данных), мы должны усреднить значения от 21 до 26 (890,9 / 43 = 20,72 ~ 21 и 1122,5 / 43 = 26,10 ~ 26)
(Полоса 1/3 октавы даст вам около 30 полос между ~ 40 Гц и ~ 20 кГц). Как вы уже понимаете, по мере того, как мы поднимаемся выше, мы будем усреднять больший диапазон чисел. Низкие столбцы обычно включают только 1 или небольшое количество точек данных. В то время как более высокие столбцы могут составлять в среднем сотни точек. Причина в том, что 86 Гц - это октава выше 43 Гц ... тогда как 10086 Гц звучат почти так же, как 10043 Гц.
источник
у вас есть образец, длина которого по времени составляет 256/44100 = 0,00580499 секунды. Это означает, что ваше разрешение по частоте составляет 1 / 0,00580499 = 172 Гц. 256 значений, которые вы получаете из Python, соответствуют частотам, в основном, от 86 Гц до 255 * 172 + 86 Гц = 43946 Гц. Вы получаете комплексные числа (отсюда "j" в конце каждого второго числа).
ИЗМЕНИТЬ: ИСПРАВЛЕННАЯ НЕПРАВИЛЬНАЯ ИНФОРМАЦИЯ
Вам нужно преобразовать комплексные числа в амплитуду, вычислив sqrt (i 2 + j 2 ), где i и j - действительная и мнимая части, соответственно.
Если вы хотите иметь 32 бара, вы должны, насколько я понимаю, взять среднее значение четырех последовательных амплитуд, получив 256/4 = 32 бара, как вы хотите.
источник
БПФ возвращает N комплексных значений, которые из вас могут вычислить
module=sqrt(real_part^2+imaginary_part^2)
. Чтобы получить значение для каждой полосы, вы должны просуммировать модули по всем гармоникам внутри полосы. Ниже вы можете увидеть пример анализатора спектра на 10 полосок. Код c должен быть обернут, чтобы получить модуль pyd python.Я разработал и изготовил на Python целый анализатор спектра с 10 светодиодами. Вместо использования библиотеки nunmpy (слишком большой и бесполезной для получения только БПФ) был создан модуль python pyd (всего 27 КБ) для получения БПФ и разделения всего звукового спектра на полосы.
Кроме того, для чтения выходного аудио был создан модуль pyd loopback WASapi portaudio. Вы можете увидеть проект (блок-схему) на изображении 10BarsSpectrumAnalyzerWithWASapi.jpg
Только что добавил обучающее видео на свой канал на YouTube: как спроектировать и сделать очень умный Python Spectrum Analyzer 10 Led Bar
источник