【问题标题】:Plotting FFT on octave在八度音阶上绘制 FFT
【发布时间】:2014-11-06 00:08:45
【问题描述】:

我知道 FFT 将时域中的函数更改为频域中的函数。

但是,当我尝试在频域中绘制所述图表时,我只能通过使用时间作为 X 轴来使其正常工作,而显然应该不是那个,而是频率。

另外,我只能通过将 y 轴除以某个整数来获得与原始信号中的幅度匹配的幅度。这是为什么呢?

这是我的代码

t=0:0.001:2

x=2*sin(20*pi*t) + sin(100*pi*t)
subplot(2,1,1)
plot(1000*t,x)
grid
xlabel("Time in milliseconds")
ylabel("Signal amplitude")

subplot(2,1,2)
y=fft(x)
plot(1000*t,abs(y))
xlabel("Frequency")
ylabel("Signal amplitude")

和图表。

请帮忙=(

【问题讨论】:

    标签: plot signal-processing fft octave


    【解决方案1】:

    频率关系(x轴缩放)

    直到奈奎斯特频率(采样率的一半),FFT产生的每个值的频率通过以下方式与输出值的索引线性相关:

    f(i) = (i-1)*sampling_frequency/N
    

    其中 N 是 FFT 点的数量(即N=length(y))。在您的情况下,N=2001。在奈奎斯特频率之上,频谱显示围绕负频率分量(来自频谱的周期性扩展)。

    可以从您对t 的定义中将采样频率减去 1/T,其中 T 是采样时间间隔(在您的情况下为 T=0.001)。 所以采样频率是1000Hz。

    注意,由于t(i)的值也与索引i线性相关,通过

    t(i) = (i-1)*0.001
    

    定义f = 1000*t*sampling_frequency/N 是可能的(尽管不建议这样做,因为这只会掩盖您的代码)。 请注意,您错过了 sampling_frequency/N 术语,这相应地导致音调以错误的频率显示 (根据x的定义,峰值应该在10Hz和50Hz,对应的混叠在-10Hz和-50Hz,环绕后出现在990Hz和950Hz)。

    幅度关系(y轴缩放)

    请注意,观察到的关系只是近似的,因此以下不是数学证明,而只是一种直观的方式来可视化时域音调幅度和频域峰值之间的关系。 em>

    将问题简化为单音:

    x = A*sin(2*pi*f*t)
    

    可以使用Parseval's theorem推导出相应峰值的近似幅值:

    在时域(等式左侧),表达式约等于0.5*N*(A^2)

    在频域(等式右侧),做出以下假设:

    • spectral leakage effects 可以忽略不计
    • 音调的频谱内容仅包含在 2 个 bin 中(频率 f 和相应的混叠频率 -f)占总和(所有其他 bin 为 ~0)。请注意,这通常仅在音调频率是 sampling_frequency/N 的精确(或接近精确)倍数时才成立。

    右侧的表达式大约等于2*(1/N)*abs(X(k))^2,因为k 的某个值对应于频率f 处的峰值。

    将两者放在一起产生abs(X(k)) ~ 0.5*A*N。换句话说,正如您所观察到的,输出幅度相对于时域幅度显示了0.5*N(或在您的情况下约为 1000)的比例因子。

    这个想法仍然适用于不止一种音调(尽管可以忽略不计的频谱泄漏假设最终会失效)。

    【讨论】:

      【解决方案2】:

      其他答案已表明,此示例中的频率响应为 950Hz 和 990Hz。这是对 FFT 代码如何使用索引的误解。那些“高频”尖峰实际上是 -50Hz 和 -10Hz。

      频域从 -N/2*sampling_frequency/N 扩展到 + N/2*sampling_frequency/N。但是由于历史原因,约定是前N/2条信息是正频,中点是零频,最后N/2条信息是负频,倒序排列。对于一个功率谱,不需要显示超过前 1+N/2 条信息。

      这个约定非常令人困惑,因为我不得不从 Press et al.许多年前,当我第一次使用 FFT 时,在 Cleve Moler 向一些 幸运 博士生传递的 Matlab 1.0 的 beta 测试版之前,我使用了数值食谱和手动编码快速 Hartley 变换 :-)

      【讨论】:

        【解决方案3】:

        你好(帖子很旧,但可能对未来的访问者有用),

        为了完成和说明其他答案,这段代码灵感来自 Matlab 文档,适用于 Octave:

        通过定义 SleuthEye 精确的频率轴,我们得到了预期的 50Hz 和 120Hz 的音调(以及它们的负别名)

        Fs = 1000;
        Ts = 1/Fs;
        L = 1500;
        t = (0:L-1)*Ts;
        
        S = 0.7*sin(2*pi*50*t) + sin(2*pi*120*t);
        X = S + 2*randn(size(t));
        
        figure(1)
        plot(1000*t(1:50),X(1:50))
        title('Signal Corrupted with Zero-Mean Random Noise')
        xlabel('t (milliseconds)')
        ylabel('X(t)')
        
        Y = fft(X);
        
        P2 = abs(Y/L);
        P1 = P2(1:L/2+1);
        P1(2:end-1) = 2*P1(2:end-1);
        
        f = Fs*(0:(L/2))/L;
        
        figure(2)
        plot(f,P1) 
        title('Single-Sided Amplitude Spectrum of X(t)')
        xlabel('f (Hz)')
        ylabel('|P1(f)|')
        
        f2 = Fs*(0:(L-1))/L;
        
        figure(3)
        plot(f2,P2) 
        title('Two-Sided Amplitude Spectrum of X(t)')
        xlabel('f (Hz)')
        ylabel('|P2(f)|')
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-09-11
          • 2011-10-14
          • 2013-10-25
          • 2020-12-31
          • 2012-09-27
          • 1970-01-01
          相关资源
          最近更新 更多