Analizuj dźwięk za pomocą szybkiej transformaty Fouriera

Próbuję stworzyć graficzny analizator widma w Pythonie.

Obecnie odczytuję 1024 bajty 16-bitowego dwukanałowego strumienia audio o częstotliwości próbkowania 44,100 Hz i uśredniam amplitudę 2 kanałów razem. Więc teraz mam 256 podpisanych spodenek. Teraz chcę preformować fft na tej tablicy, używając modułu takiego jak numpy, i użyć wyniku do stworzenia graficznego analizatora widma, który na początek będzie miał tylko 32 paski.

Przeczytałem artykuły Wikipedii NA Szybka transformata Fouriera i dyskretna transformata Fouriera, ale nadal Nie wiem, co przedstawia tablica wynikowa. Tak wygląda tablica po preformowaniu fft na mojej tablicy za pomocą 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...

Zastanawiam się, co dokładnie te liczby reprezentują i jak zamieniłbym te liczby na procent wysokości dla każdego z 32 taktów. Czy powinienem uśredniać kanały 2 razem?

Author: A. Levy, 2009-03-03

3 answers

Tablica, którą pokazujesz, to współczynniki transformacji Fouriera sygnału audio. Współczynniki te mogą być wykorzystane do uzyskania zawartości częstotliwości dźwięku. FFT jest zdefiniowany dla złożonych funkcji wejściowych, więc współczynniki, które uzyskasz, będą liczbami urojonymi, nawet jeśli Twoje dane wejściowe są wszystkimi wartościami rzeczywistymi. Aby uzyskać ilość mocy w każdej częstotliwości, musisz obliczyć wielkość współczynnika FFT dla każdej częstotliwości. To jest nie tylko prawdziwe Składnik współczynnika, trzeba obliczyć pierwiastek kwadratowy sumy kwadratu jego rzeczywistych i urojonych składników. Oznacza to, że jeśli Twój współczynnik jest a + b * j, to jego wielkość jest sqrt (a^2 + b^2).

Po obliczeniu wielkości każdego współczynnika FFT, musisz dowiedzieć się, do której częstotliwości audio należy każdy współczynnik FFT. N Punkt FFT daje zawartość częstotliwości sygnału na N równych częstotliwościach, począwszy od 0. Ponieważ twój częstotliwość próbkowania wynosi 44100 próbek / SEK., a liczba punktów w Twoim FFT wynosi 256, Twój odstęp częstotliwości wynosi 44100 / 256 = 172 Hz (w przybliżeniu)

Pierwszy Współczynnik w tablicy będzie 0 współczynnik częstotliwości. To jest w zasadzie średni poziom mocy dla wszystkich częstotliwości. Reszta twoich współczynników będzie liczyć się z 0 w wielokrotnościach 172 Hz, aż dojdziesz do 128. W FFT można mierzyć tylko częstotliwości do połowy punktów próbki. Przeczytaj te linki na Nyquist Frequency i Nyquist-Shannon Sampling Theorem jeśli jesteś żarłokiem kary i musisz wiedzieć dlaczego, ale podstawowym rezultatem jest to, że Twoje niższe częstotliwości będą replikowane lub aliased w wiadrach o wyższej częstotliwości. Tak więc częstotliwości zaczną się od 0, zwiększą się o 172 Hz dla każdego współczynnika do współczynnika N/2, a następnie zmniejszą się o 172 Hz do współczynnika N - 1.

To powinno wystarczyć na początek. Jeśli jeśli chcesz bardziej przystępne wprowadzenie do FFTs niż jest podane na Wikipedii, możesz spróbować zrozumieć cyfrowe przetwarzanie sygnałów: 2nd Ed.. To było dla mnie bardzo pomocne.

Więc to właśnie oznaczają te liczby. Konwersja na procent wysokości może być wykonana przez skalowanie każdej wielkości składowej częstotliwości przez sumę wszystkich wielkości składowych. Chociaż, to daje tylko reprezentację względnego rozkładu częstotliwości, a nie rzeczywistą moc dla każda częstotliwość. Możesz spróbować skalować o maksymalną możliwą wielkość dla komponentu częstotliwości, ale nie jestem pewien, czy będzie to wyświetlane bardzo dobrze. Najszybszym sposobem znalezienia praktycznego współczynnika skalowania byłoby eksperymentowanie na głośnych i miękkich sygnałach audio, aby znaleźć odpowiednie ustawienie.

Wreszcie, należy uśredniać dwa kanały razem, jeśli chcesz pokazać zawartość częstotliwości całego sygnału audio jako całości. Miksujesz dźwięk stereo na dźwięk mono i pokazujesz częstotliwości łączone. Jeśli chcesz dwa oddzielne wyświetlacze dla prawej i lewej częstotliwości, musisz wykonać transformatę Fouriera na każdym kanale osobno.

 195
Author: A. Levy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-31 22:18:10

Chociaż ten wątek ma lata, uznałem go za bardzo pomocny. Chciałem tylko dać swój wkład każdemu, kto to znajdzie i próbuje stworzyć coś podobnego.

Jeśli chodzi o podział na słupki, nie należy tego robić, jak sugeruje antti, dzieląc dane równo na podstawie liczby słupków. Najbardziej przydatnym byłoby podzielenie danych na części oktawy, przy czym każda oktawa jest dwukrotnie większa od poprzedniej. (tj. 100hz to jedna oktawa powyżej 50hz, czyli jedna oktawa powyżej 25hz).

W zależności od tego, ile taktów chcesz, dzielisz cały zakres na 1 / x zakresy oktaw. Na podstawie podanej częstotliwości środkowej a na takcie, można uzyskać górną i dolną granicę taktu z:

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

Aby obliczyć następną sąsiednią częstotliwość środkową, użyj podobnego obliczenia:

next lower =  A / 2 ^ ( 1 / X )
next higher = A * 2 ^ ( 1 / X )
Następnie uśredniasz dane, które mieszczą się w tych zakresach, aby uzyskać amplitudę dla każdego taktu.

Na przykład: Chcemy podzielić na 1/3 oktaw zakresy i zaczynamy od Częstotliwość środkowa 1khz.

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

Biorąc pod uwagę 44100Hz i 1024 próbki (43hz między każdym punktem danych) powinniśmy uśrednić wartości od 21 do 26. (890.9 / 43 = 20.72 ~ 21 i 1122.5 / 43 = 26.10 ~ 26 )

(paski 1/3 oktawy dadzą ci około 30 pasków między ~40Hz a ~20kHz). Jak już można się domyślić, gdy idziemy wyżej, uśrednimy większy zakres liczb. Niskie słupki zazwyczaj obejmują tylko 1 lub niewielką liczbę punktów danych. Podczas gdy wyższe bary mogą być średnią setki punktów. Powodem jest to, że 86hz jest oktawą powyżej 43hz... podczas gdy 10086hz brzmi prawie tak samo jak 10043hz.

 26
Author: Erik A.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-31 22:18:59

Masz próbkę, której długość w czasie wynosi 256/44100 = 0,00580499 sekund. Oznacza to, że rozdzielczość częstotliwości wynosi 1 / 0.00580499 = 172 Hz. 256 wartości, które otrzymujesz z Pythona, odpowiadają częstotliwości, zasadniczo, od 86 Hz do 255*172+86 Hz = 43946 Hz. Liczby, które otrzymujesz, są liczbami złożonymi (stąd "j" na końcu każdej drugiej liczby).

EDITED: FIXED WRONG INFORMATION

Musisz przeliczyć liczby zespolone na amplitudę obliczając sqrt (i2 + j2) Gdzie ja I j są częściami rzeczywistymi i wyimaginowanymi, resp.

Jeśli chcesz mieć 32 takty, powinieneś, o ile rozumiem, wziąć średnią czterech kolejnych amplitud, uzyskując 256 / 4 = 32 takty, jak chcesz.

 10
Author: Antti Huima,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-20 09:58:45