Snažím se vzorkovat sinusovou vlnu a vykreslit její frekvenční komponenty, ale mám problémy s implementací Níže je vidět výsledek odběru 65 536 vzorků jednoho cyklu sinusové vlny s maximální amplitudou 1 a frekvencí 100. Kde osa Y je velikost komplexního Fourierova součtu a osa x je číslo vzorku Jak zjistím, jakou frekvenci má sinusová vlna z tohoto grafu? Chtěl bych mít graf frekvence vs Magnitude a ne vzorek Number vs magnitude.
Čekal jsem jeden velký bod amplitudy 1 nebo 2 hroty amplitudy po 0,5, ale zdá se, že dostávám velkou amplitudu, nevím, co možná dělám špatně.
Kód Matlab:
Amp = 1; freq = 100; dt = 2 * pi /65536; index = 1; for t = 0:dt:2*pi sine(index) = Amp * sin(2*pi*freq*t); sampleNumber(index) = index; index = index + 1; end transform = fft(sine); magTransform = abs(transform); plot(sampleNumber,magTransform);
Komentáře
- Implementace FFT mají často zisk úměrný $ N $ nebo $ \ sqrt {N} $. Váš výsledek není ' t nepřiměřený.
- Vydělením velikosti o $ N $ získáte dva hroty o velikosti přibližně 0,425 (což je stále méně než očekávaných 0,5 ). Jak mohu změnit osu x na frekvenci z počtu vzorků?
Odpovědět
Vypadá to jako byste dostali frekvenci v Hertzích zaměňovanou s v radiánech / s, protože v obou vzorkovacích obdobích dt máte faktor $ 2 \ pi $ em> a váš signál. Přepsal jsem trochu vašeho kódu, abych objasnil, co si myslím, že opravdu chcete.
Amp = 1; freqHz = 12000; fsHz = 65536; dt = 1/fsHz; t = 0:dt:1-dt; sine = Amp * sin(2*pi*freqHz*t); N = 65536; transform = fft(sine,N)/N; magTransform = abs(transform); faxis = linspace(-fsHz/2,fsHz/2,N); plot(faxis/1000,fftshift(magTransform)); axis([-40 40 0 0.6]) xlabel("Frequency (KHz)")
Pokud je vaše vzorkovací frekvence 65536 vzorků za sekundu , a chcete například tón při 12 KHz, můžete jej vytvořit, jak je znázorněno. Takže zde je vaše vzorkovací perioda 1/65536 sekund.
Vaše očekávání získání dvou hrotů s amplitudou 0,5 bylo správně – právě váš generovaný tón nebyl.
Pokud jde o změnu měřítka osy x na Hertz, stačí vytvořit vektor se stejným počtem bodů jako váš výsledek FFT a s lineárním přírůstkem od $ – fs / 2 $ do $ + fs / 2 $ . Všimněte si také fftshift, který jsem použil v grafu. Je to proto, že výstup funkce FFT Matlabu jde lineárně od 0 do fs. Zdá se mi snazší si představit, že je centrováno DC, ale oba způsoby jsou v pořádku. Bez funkce fftshift by vektor faxis přešel z 0 na fs .
Odpověď
Některé FFT vyžadují dělení 1 / N, aby představovaly velikost „přirozeně“ (což je neenergetické ). Označení osy X vyžaduje znalost vzorkovací frekvence (Fs). Pokud je známo, pak f_x = bin_index * Fs / N, až N / 2, pak se zrcadlí pro záporné frekvence. Pokud frekvence spektrálního píku (vaše vstupní sinusová vlna) není „t přesně periodická v délce FFT (např. Celé číslo cyklů), pak velikost nejbližšího koše výsledků FFT bude menší a budete muset interpolovat mezi zásobníky, abyste našli bližší odhad vrcholové velikosti (běžné jsou interpolace jádra parabolická nebo okenní-Sinc).
Odpověď
Přidání některých vzorců k odpovědi hotpaw2:
Pomocí FFT vypočítáte reprezentaci vašeho signálu as
$$ x (t) = \ sum_ {k = 0} ^ {N-1} \ hat x_k e ^ {2 \ pi i \, f_k \, t} $$
kde $ f_k = \ frac {k} {N} f_s $ za $ k = 0,1, …, N / 2-1 $ a $ f_k = \ frac {kN} {N} f_s $ pro $ k = N / 2, …, N-1 $, za předpokladu, že $ N $ je sudé.
Nyní FFT vyžaduje, aby byly vzorky odebírány s krokem vzorkování $ \ tau = 1 / f_s $ , $ x_n = x (n \ tau) $ a FFT ukázkového pole $ (x_n) _n $ dává škálované amplitudové pole $ (N \ hat x_k) _k $, protože $ \ sum_ {k = 0} ^ {N-1} 1 = N $. Změna měřítka i s obvykle vynechán z implementací FFT, s nimiž se bude uživatel knihovny FFT zabývat.
Odpověď
FFT poskytuje metodu výpočet DFT, to už víte. nyní zvažte signál x (n) a jeho DFT X (k). pokud váš signál sestává z N (65536 ve vašem případě) vzorků, pak X (k) poskytne hodnoty na diskrétních frekvencích 2*pi*k/N
. Ve skutečnosti výše uvedený DFT X (k) znamená X(2*pi*k/N)
. takže pokud nacházíte X (1), znamená to, že nacházíte DFT koeficient na diskrétní frekvenci 2 * pi * 1 / N a podobně, X (2) znamená koeficient pro 2 * pi * 2 / N a tedy tak dále. Každý koeficient ukazuje příspěvek této frekvence v tomto signálu, pokud je velký, znamená to, že frekvence tvoří hlavní část signálu. takže pro vykreslení fft s ohledem na frekvenci nahraďte osu vzorku frekvenční osou s body 2*pi*k/N
kde k = 0 až 65535.FT nikdy neposkytuje žádné informace o čase. stačí poskytnout informace o frekvenci signál.