Matlab绘制对数啁啾的对数

时间:2013-03-14 04:18:31

标签: matlab signal-processing fft frequency-analysis

我创建一个与matlab help page完全相同的对数啁啾。

t = 0:0.001:10;      % 10 seconds @ 1kHz sample rate
fo = 10; f1 = 400;   % Start at 10Hz, go up to 400Hz
X = chirp(t,fo,10,f1,'logarithmic');
figure(2);
spectrogram(X,256,200,256,1000,'yaxis');

Spectrogram

然后我使用以下代码将其带到频域,该代码适用于我的其他应用程序。

fft_prep = fftshift(fft(X));
fft_mag = abs(fft_prep);
pos_fft = fft_mag(1:ceil(length(fft_mag)/2));
db_fft = 20*log10(pos_fft);
figure(1);
plot(db_fft);

我很惊讶地发现以下图表看起来令人兴奋1kHz-5kHz:

SpectrumAnalyzer

我对matlab中的chirp函数并不熟悉,并且想知道是否有人看到了我遗漏的明显事物。欢迎任何其他指示。

4 个答案:

答案 0 :(得分:7)

chirp功能......

没有错

您只需要根据频率值绘制db_fft,而不是矢量索引=)。

plot(linspace(fo,f1,length(db_fft)), db_fft);

enter image description here

我还测试了使用其他FFT方法计算信号的FFT,它们也指示了0到400 Hz之间的范围。

更新:

IMO,我发现在视觉上更容易不以dB或功率(周期图)绘图。这是一个很好的例子和我计算时域信号FFT的goto方法:mathworks.se/help/matlab/ref/fft.html

响应:

经过一番思考后,我同意我的答案不正确,但不是因为你说的原因。频域中的x轴不应该达到啁啾的实际长度(或一半,或dubbel或类似的东西)。频域中的x轴应该达到信号采样率的一半(Fs / 2),并且您有义务确保采样频率是您希望/希望的最大频率的两倍。解决。

换句话说,假设您的FFT与时域信号的长度相同/两倍/一半是不正确的,因为我们可以选择任意数量的频率区来表示FFT,最佳实践是长度= N ^ 2(2的幂)用于快速计算。想一想,为什么在计算FFT时甚至需要知道时间值?你不!您只需要采样频率(应设置为Fs = 1000 btw,而不是Fs = 0.001)。

我上面的回答是不正确的,应该是:

plot(linspace(0, Fs/2, length(db_fft)), db_fft)

而不是Fs / 2,你有写入长度(t)/(2 * Tfinal)。它(几乎)与Fs / 2的值相同,但不是正确的方式=)。

这是我的goto FFT方法(值不是以dB为单位)。

function [X,f] = myfft(x,Fs,norm)
    % usage: [X, f] = myfft(x,Fs,norm);
    %        figure(); plot(f,X)
    % norm: 'true' normalizes max(amplitude(fft))=1, default=false.
    if nargin==2
        norm=false;
    end
    L = length(x); NFFT = 2^nextpow2(L);
    f = Fs/2*linspace(0,1,NFFT/2+1);
    %f =0:(Fs/NFFT):Fs/2;
    X = fft(x,NFFT)/L; X = 2*abs(X(1:NFFT/2+1));
    if norm==true; X = X/max(abs(X)); end
end

这是[Xfft,f] = myfft(X,Fs)的结果图;情节(F,Xfft); 请注意,根据NyQuist定理,返回频率bin向量的max(f)= Fs / 2(任何高于Fs / 2的频率都无法解析)。

enter image description here

答案 1 :(得分:0)

我有几个错误,但并非所有错误都得到修复。在尝试了更多代码之后,这是我提出的解决方案。

我添加了一些变量来使设置更加模块化。

Tfinal = 10;
Fs = 1/1000;
t = 0:Fs:Tfinal;      % 10 seconds @ 1kHz sample rate
fo = 10; f1 = 400;   % Start at 10Hz, go up to 400Hz
X = chirp(t,fo,Tfinal,f1,'linear');

当我绘制幅度与空间的关系时,空间需要匹配实际啁啾信号的长度,而不仅仅是从低频到高频。因为向量t的长度为1000,而在FFT之后我们使用正半数,所以啁啾信号长500而不是400,其中linspace最多为f1

fft_prep = fftshift(fft(X));
fft_mag = abs(fft_prep);
pos_fft = fft_mag(ceil(length(fft_mag)/2)+1:length(fft_mag));
db_fft=20*log10(pos_fft);
figure(1);
plot(linspace(0,length(t)/(2*Tfinal),length(db_fft)), db_fft);

我还做了前面提到的修复,以获得FFT的正面而不是负面。这个情节:

enter image description here

这准确地描绘了令人兴奋的10Hz-400Hz的啁啾声。通过走向极端情况并使其成为线性,您可以更清楚地看到它。尝试采样频率为100,范围为10-25,的linspace更正:

enter image description here

后更正:

enter image description here

答案 2 :(得分:0)

顺便提一下,从FFT中提取原始啁啾振幅可能是有用的。例如,如果您正在以某个设备的频率进行音频扫描,并且您想知道每个频率的响应的幅度和相位(如Pspice givs you)。简而言之,幅度是 a ^ 2 = abs(FFT)^ 2 * 4 * chirp /(Fs * N)的带宽,其中Fs是采样频率,N是FFT中的点数。例如啁啾从200到400Hz的带宽是200Hz。

如果你想知道这个问题,请从Parseval的理论开始:平均时间信号的平均值= PSD下的面积。从而, a ^ 2/2 = sum(abs(FFT)^ 2)/ N ^ 2其中a是扫频信号(例如啁啾)的峰值幅度。如果啁啾在频率分布上是线性的而不是对数的,则FFT是平坦的,如上图所示。那么我们可以用Nb * abs(FFT)^ 2 / N ^ 2代替和,其中Nb是啁啾占据的频率仓的数量,而abs(FFT)是FFT的幅度,这对所有人都是相同的啁啾占据的频率区间。利用一个频率仓的带宽为Fs / N的事实,我们得到啁啾的带宽是Nb * Fs / N.上面的结果现在可以从这里轻松推导出来。

答案 3 :(得分:0)

MATLAB关于request.organisation_id = organisation_id 的{​​{3}}实际上提供了简单的指令,可以任意选择fft(例如,二次或线性):

chirp

要分析的信号示例:

Fs = 1000;            % Sampling frequency                    
T = 1/Fs;             % Sampling period       
L = 1500;             % Length of signal
t = (0:L-1)*T;        % Time vector

计算FFT:

S = 0.7*sin(2*pi*50*t) + sin(2*pi*120*t);
X = S + 2*randn(size(t));

频率向量计算为

Y   = fft(X);       % Calculate FFT
P2  = abs(Y/L);
P1  = P2(1:L/2+1);
P1(2:end-1) = 2*P1(2:end-1);

如果您想要生成Bode幅度图,首先应将频率转换为[rad / s],将fft的结果转换为[dB]:

f = Fs*(0:(L/2))/L;

然后制作一个Bode图(我建议使用散点图,考虑到结果的潜在嘈杂性)

fRad = f*2*pi;
Pdb = 20*log10(P1);