2013-08-09 13 views
6

UWAGA: Nie jest to duplikat, mam określone wymagania inne niż powiązane pytania.Jak wykreślić widmo pliku WAV przy użyciu FFT?

Na początek chcę wykreślić spektrum pliku audio (.wav), tak jak to robi audacity (podobne: How to draw a frequency spectrum from a Fourier transform).

Do tej pory mogę czytać i pisać pliki wav. Ale moim problemem jest to, że nie wiem dokładnie, jakie wartości muszę przekazać do funkcji FFT. Przy okazji używam Exocortex dla FFT w C#. Funkcja FFT wymaga ode mnie podania tablicy liczb zespolonych o odpowiednim rozmiarze (512, 1024, ... przypuszczam), opcjonalnym parametrze całkowitym dla długości i kierunku fourier (do przodu/do tyłu).

Konkretne pytania:

  1. Complex (klasa) z biblioteki Exocortex ma dwie wartości, a mianowicie rzeczywiste i urojone. Mam zestaw próbek, więc które powinny być prawdziwe i które powinny być wyimaginowane?
  2. Mam plik wav, więc należy przyjąć długość zmiennej. Jak przekazać to do funkcji FFT? Czy powinienem wybrać rozmiar (512/1024/itd.), Podzielić całą próbkę na rozmiar, a następnie przekazać ją do FFT?
  3. Skąd mam wiedzieć, jakie częstotliwości powinny być wyświetlane na osi X?
  4. Jak wykreślić dane FFT? (Chcę, aby oś X była częstotliwością, a oś Y w decybelach)

Jeśli nie rozumiesz, o co mi chodzi, spróbuj użyć Audacity, zaimportuj plik audio, a następnie kliknij Analizy> Drukuj Widmo. To są rzeczy, które chcesz odtworzyć. Proszę szczegółowo odpowiedzieć na moje pytanie, ponieważ naprawdę chcę się tego nauczyć. Mam tylko małe doświadczenie w tym zakresie. Jestem dopiero początkującym w cyfrowym przetwarzaniu sygnału. W miarę możliwości nie kieruj mnie do innych stron FFT, ponieważ nie odpowiadają one konkretnie na moje pytanie.


EDIT:

Zrobiłem trochę czytania i dowiedział się, jak FFT an danych audio, ale tylko w kompetencji 2. Więc jak mam zrobić to samo w pliku audio o długości, która jest nie ma uprawnień 2? Według niektórych potrzebuję użyć "okna". Zrobiłem też trochę wyszukiwania i odkryłem, że przetwarzanie przebiegu zajmuje tylko część kształtu fali. Pamiętaj powyżej, że chcę uzyskać FFT pliku audio, a nie jego część. Co powinienem teraz zrobić? Proszę o pomoc :(

+0

Czy mówisz o tym http://sourceforge.net/projects/exocortexdsp/?source=navbar? – Vadim

+0

Odnośnie notatki - 1. Zadajesz za dużo pytań. To jest więcej rzeczy z matematyki, a otrzymasz znacznie lepsze (i więcej) odpowiedzi na forach poświęconych temu zagadnieniu. 2. Jeśli twoje pliki zawierają pewną liczbę próbek, która nie jest potęgą dwóch, musisz uzupełnić je zerami, aby rozmiar był potęgą dwóch. Jest to ograniczenie FFT. 3. Zasadniczo za pomocą okna wykonuje się FFT na części danych (jeśli jest to potrzebne). Ale idzie o wiele głębiej, są różne okna z różnymi efektami. – Vadim

+0

To, co próbujesz wygenerować, nazywa się [spektrogramem] (http://en.wikipedia.org/wiki/Spectrogram). Lepiej byłoby zapytać, jak wykreślić spektrogram, niż zapytać o widmo. –

Odpowiedz

6

Podpis jest

public static void FFT(float[] data, int length, FourierDirection direction) 
  1. przekazać tablicę liczb zespolonych, reprezentowana jako pary. Ponieważ masz tylko liczb rzeczywistych (próbki), należy umieścić swoje próbki w nawet miejsca w tablicy - dane [0], dane [2], dane [4] itd. Nieparzyste lokalizacje powinny wynosić 0, dane [1] = dane [3] = 0 ...
  2. Długość jest ilość próbek, które chcesz obliczyć FFT na, powinna być dokładnie połowa długości tablicy danych.Możesz FFT cały WAV lub jego części - w zależności od tego, co chcesz zobaczyć. narysuj spektrum mocy wybranej części pliku, jeśli chcesz zrobić to samo, przeprowadź całe WAV lub wybrane części.
  3. FFT wyświetli tylko częstotliwości do połowy częstotliwości próbkowania. Więc powinieneś mieć wartości od 0 do połowy swojej częstotliwości próbkowania.Ilość wartości zależy od ilości pobranych próbek (ilość próbek wpłynie na dokładność obliczeń).
  4. Audacity kreśli spektrum mocy. Powinieneś wziąć każdą liczbę zespoloną w otrzymanej macierzy i obliczyć jej ABS. ABS definiuje się jako sqrt (r^2 + i^2). Każda wartość ABS będzie odpowiadała jednej częstotliwości.

Oto przykład z kodeksu pracy:

float[] data = new float[8]; 
data[0] = 1; data[2] = 1; data[4] = 1; data[6] = 1; 
Fourier.FFT(data, data.Length/2, FourierDirection.Forward); 

Daję mu 4 próbki, wszystkie takie same. Tak więc spodziewam się uzyskać coś tylko z częstotliwością 0. I rzeczywiście, po uruchomieniu, otrzymuję

danych [0] == 1, danych [2] == 1, danych [4] == 1, danych [ 6] == 1

a inne są 0.

Jeśli chcę użyć Complex przeciążenie tablicy

Complex[] data2 = new Complex[4]; 
data2[0] = new Complex(1,0); 
data2[1] = new Complex(1, 0); 
data2[2] = new Complex(1, 0); 
data2[3] = new Complex(1, 0); 
Fourier.FFT(data2,data2.Length,FourierDirection.Forward); 

Należy pamiętać, że tutaj drugi parametr jest równa długość tablicy, ponieważ każdy element tablicy jest liczbą zespoloną. Otrzymuję taki sam wynik jak poprzednio.

Chyba przegapiłem złożone przeciążenie wcześniej. Wydaje mi się mniej podatny na błędy i bardziej naturalny w użyciu, chyba że dane już są w parach.

+2

nie ma potrzeby dla 'Abs()' podczas obliczania pierwiastka kwadratowego. Wynik 'sort()' nigdy nie jest negatywny. – marko

+0

Oczywiście. Moje frazowanie było prawdopodobnie złe. Chciałem powiedzieć, że powinien obliczyć ABS, a sqrt to sposób na jego obliczenie. Nie oznacza to sugerowania, że ​​musisz zastosować inne mięśnie brzucha. Zmienię moją odpowiedź. Dzięki. – Vadim

+1

Oczywiście mam na myśli 'sqrt()' tam - winę autokorekty! – marko

Powiązane problemy