2010-05-21 23 views
12

Powiedzmy, że mam plik WAV. W tym pliku znajduje się szereg tonów sinusoidalnych w precyzyjnych odstępach 1-sekundowych. Chcę użyć biblioteki FFTW, aby wyodrębnić te dźwięki w sekwencji. Czy to jest szczególnie trudne? Jak bym to zrobił?Jak wyodrębnić pół-dokładne częstotliwości z pliku WAV za pomocą transformacji Fouriera

Co jest najlepszym sposobem na zapisanie dźwięków tego rodzaju w pliku WAV? Zakładam, że potrzebowałbym tylko prostej biblioteki audio dla wyjścia.

Mój język z wyboru jest C

Odpowiedz

1

WAV zawierać linear pulse code modulated (LPCM) danych. Oznacza to po prostu, że jest to sekwencja wartości amplitudy ze stałą częstotliwością próbkowania. Na początku pliku zawarty jest kod RIFF header, który przekazuje informacje takie jak sampling rate i bity na próbkę (na przykład 16-bitowy sygnał 8 kHz).

Format jest bardzo prosty i można łatwo przetworzyć własny. Istnieje jednak kilka bibliotek dostępnych do przyspieszenia procesu, takich jak libsndfile. Simple Direct-media Layer (SDL)/SDL_mixer i to dwie ładne biblioteki do odtwarzania.

Jeśli chodzi o podawanie danych do FFTW, należy buforować 1 sekundę kawałków (określić rozmiar według częstotliwości próbkowania i bitów na próbkę). Następnie zamień wszystkie próbki na zmiennoprzecinkowe IEEE (tj. float lub double w zależności od konfiguracji FFTW - libsndfile może to zrobić dla ciebie). Następnie utwórz kolejną tablicę do przechowywania danych wyjściowych w domenie częstotliwości. Na koniec utwórz i wykonaj plan FFTW, przekazując oba bufory do fftw_plan_dft_r2c_1d i wywołując fftw_execute with the returned fftw_plan handle.

+0

Właściwie nie jest to wersja 'fftw', ale czy została skompilowana z obsługą zmiennoprzecinkową, czyż nie? –

+0

To prawda, jest to kwestia konfiguracji IIRC konfiguracji. Nie używałem FFTW od wielu lat. Być może "wersja" nie jest najdokładniejszym słowem, jakie mogłem wybrać? –

+0

Większość oprogramowania DSP audio dla Linuksa (i innych platform), które używa FFTW wymaga FFTW zbudowanego z obsługą float, a spędzając dużo czasu na budowaniu tego materiału ze źródła, mogę powiedzieć, że przynajmniej w Debianie ma pakiety dla różnych kompilacji opcje FFTW, które można zainstalować jednocześnie. Spodziewam się, że dotyczy to również większości innych dystrybucji Linuksa. –

22

Aby uzyskać power spectrum z odcinka pliku:

  • pobierania próbek n, gdzie n jest potęgą liczby 2 - jeśli częstotliwość próbkowania wynosi 44,1 kHz dla przykładu i chcesz spróbować ok każdy następnie przejdź na przykład N = 32768 próbek.

  • zastosuj odpowiedni window function do próbek, np. Hanning

  • przechodzą okienkowanych próbek do FFT rutyna - idealnie chcesz prawdziwego do kompleksu FFT ale jeśli wszystko masz jest złożona do kompleksowego FFT następnie przepuścić 0 dla wszystkich urojoną wejściowych

  • obliczyć kwadrat wielkości swoich odbiorników FFT (Re * re + im * im)

  • (opcjonalnie) obliczyć 10 * log10 każdej wielkości kwadratu pojemnik wyjściowy, aby uzyskać wartość wielkości w dB

Teraz, gdy masz spektrum mocy, musisz tylko zidentyfikować szczyt (y), co powinno być całkiem proste, jeśli masz rozsądny stosunek S/N. Zauważ, że rozdzielczość częstotliwościowa poprawia się przy większych N. Dla powyższego przykładu częstotliwości próbkowania 44,1 kHz i N = 32768 rozdzielczość częstotliwości każdego z binów wynosi 44100/32768 = 1,35 Hz.

+0

Należy zauważyć, że funkcja okna 'Hanning' będzie rozmazać dane wejściowe przez kilka binów; sugerowany 1,35 Hz jest dość optymistyczny. [Jak pisze Wikipedia] (http://en.wikipedia.org/wiki/Window_function#Comparison_of_windows), może faktycznie nie ma sensu wcale. – MSalters

+0

Okna Hann lub Hamming są najczęściej użytecznymi funkcjami okien ogólnego przeznaczenia. Oba dają rozsądny kompromis w tym sensie, że wielkość i częstotliwość szczytów będą dość wiarygodne (w przeciwieństwie do przypadku bez okna), a szczyt również będzie dość ostry. Jeśli chcesz zidentyfikować oddzielne piki, które są bardzo blisko siebie, to prawdopodobnie są lepsze opcje dla funkcji okna. Brak okna w ogóle (tj. Prostokątna funkcja okna) zwykle ma sens tylko wtedy, gdy patrzysz na komponenty, które są wyrównane dokładnie do częstotliwości bin. –

2

W zasadzie interesuje Cię estimating a Spectrum - zakładając, że już przekroczyłeś etap czytania WAV i przekształcenia go w dyskretny sygnał czasu.

Spośród różnych metod, najbardziej podstawowym jest Periodogram, co oznacza wzięcie okna z dyskretną transformacją Fouriera (z FFT) i zachowanie jej kwadratowej wielkości. Odpowiada to odpowiedzi Pawła. Potrzebujesz okna, które obejmuje kilka okresów najniższej częstotliwości, które chcesz wykryć. Przykład: jeśli twoje sinusoidy mogą być tak niskie jak 10 Hz (okres = 100ms), powinieneś wziąć okno 200ms o 300ms (lub więcej). Jednak periodogram ma pewne disadvantages, choć to proste do obliczenia i jest więcej niż wystarczająco, jeśli wysoka precyzja nie jest wymagane:

Surowa periodogram nie jest dobrym widmowa szacunek bo spektralnego uprzedzeń oraz fakt, że wariancja przy danej częstotliwości nie zmniejsza się , ponieważ zwiększa się liczba próbek używanych w obliczeniach .

periodogram można wykonać lepiej poprzez uśrednienie kilku okien, z judious wyboru tych szerokościach(). Istnieje wiele innych metod szacowania widma (modelowanie AR).

W rzeczywistości nie jesteście Państwo zainteresowani oszacowaniem pełnego widma, a jedynie lokalizacją pojedynczej częstotliwości. Można to zrobić, poszukując szczytu szacowanego widma (wykonanego jak wyjaśniono), ale także bardziej specyficznego i mocnego (i skomplikowanego) methods (Pisarenko, algorytm MUSIC). W twoim przypadku prawdopodobnie byłyby przesadą.