Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Matlab中的FFT:环绕效应、取值范围_Matlab_Signal Processing_Fft - Fatal编程技术网

Matlab中的FFT:环绕效应、取值范围

Matlab中的FFT:环绕效应、取值范围,matlab,signal-processing,fft,Matlab,Signal Processing,Fft,我对在Matlab中使用FFT函数有一些疑问 这是一个wav文件的FFT图,它只记录了一次弹奏的吉他弦 我是通过音频读取文件来完成的: a=audioreada.wav 然后通过写作 普洛塔布塔 正如你所看到的,它的形状非常糟糕。 首先,我们可以看到有某种对称性。是环绕效应吗? 我应该用零填充信号吗 我们还可以看到,价值是巨大的。它的频率高达200000赫兹。 当然,我们对我在可听到的声音上所表现出的高价值不感兴趣 我该怎么办? 我是否应该简单地将频率降低到24000 Hz以上?还有什么特别的事

我对在Matlab中使用FFT函数有一些疑问

这是一个wav文件的FFT图,它只记录了一次弹奏的吉他弦

我是通过音频读取文件来完成的:

a=audioreada.wav

然后通过写作

普洛塔布塔

正如你所看到的,它的形状非常糟糕。 首先,我们可以看到有某种对称性。是环绕效应吗? 我应该用零填充信号吗

我们还可以看到,价值是巨大的。它的频率高达200000赫兹。 当然,我们对我在可听到的声音上所表现出的高价值不感兴趣

我该怎么办? 我是否应该简单地将频率降低到24000 Hz以上?还有什么特别的事要做吗

非常感谢您的帮助:-


请原谅可能的糟糕英语

输出的右半部分本质上是负频率内容,它的存在是因为吉他弦允许波同时向两个方向传播

你们的x轴现在也不是频率,它是FFT系数指数

你应该画出你的FFT

plot([(-numel(a)/2):(numel(a)/2-1)] * fs / numel(a), 20*log10(abs(fftshift(fft(a)))))
其中fs是采样频率


为了更深入地理解,您应该阅读一篇好的教程,我发现这篇教程看起来不错:

输出的右半部分基本上是负频率内容,它的存在是因为您的吉他弦允许波同时向两个方向传播

你们的x轴现在也不是频率,它是FFT系数指数

你应该画出你的FFT

plot([(-numel(a)/2):(numel(a)/2-1)] * fs / numel(a), 20*log10(abs(fftshift(fft(a)))))
其中fs是采样频率


为了更深入地理解,您应该阅读一篇好的教程,我发现这篇教程看起来不错:

绘图中的x轴没有单位赫兹。按照创建绘图的方式,它将是频率向量中频率的索引。。由于您的输入信号看起来大约有20万个样本长,FFT也有那么长。如果希望轴以赫兹为单位,则必须创建一个频率向量,其中包含FFT中每个采样的相应频率

我将通过一个简单的示例向您展示如何做到这一点,您可以根据自己的需要进行调整:

首先,让我们创建一些测试信号:

fs = 8000;               % sampling frequency: 8kHz
t = 0:1/fs:0.1;          % create a time vector
x = cos(2*pi*100*t);     % Testsignal: cosine with 100Hz
现在我们计算FFT。由于FFT例程只处理长度为2的幂的向量,因此我们计算FFT长度,然后进行FFT

NFFT = 2^nextpow2(length(t));
X = fft(x,NFFT);
FFT的频率分辨率为fs/NFFT。由于FFT矢量的长度为NFFT,且频率从零DC开始,因此频率矢量为

f = (0:(NFFT-1)) * fs/NFFT;
因此我们可以创建一个绘图:

plot(f,abs(X));
正如我们所指定的,峰值几乎完全在100Hz。接下来你会注意到:我们的采样频率是fs=8000Hz,所以根据奈奎斯特定理,最大频率可以是fs/2=4000Hz。高于4000Hz的部分是频率轴的负部分,由于混叠,在4000Hz和8000Hz之间可见

现在,MATLAB提供了函数fftshift来重新排列向量x,从而使绘图从-fs/2到+fs/2,而不是从0到fs。它所做的唯一一件事是,它将4000Hz和8000Hz之间的部分移动到-4000Hz到0Hz。 因此,您必须相应地创建频率向量

X_shifted = fftshift(X);
f_shifted = (-NFFT/2:NFFT/2-1) * fs/NFFT;
现在,峰值为+-100Hz,正如您所期望的余弦


长话短说:找出采样频率并创建频率向量。然后使用fftshift绘制双边频谱,或者忽略负频率,因为FFT对于实际输入值始终是对称的。

绘图中的x轴没有单位赫兹。按照创建绘图的方式,它将是频率向量中频率的索引。。由于您的输入信号看起来大约有20万个样本长,FFT也有那么长。如果希望轴以赫兹为单位,则必须创建一个频率向量,其中包含FFT中每个采样的相应频率

我将通过一个简单的示例向您展示如何做到这一点,您可以根据自己的需要进行调整:

首先,让我们创建一些测试信号:

fs = 8000;               % sampling frequency: 8kHz
t = 0:1/fs:0.1;          % create a time vector
x = cos(2*pi*100*t);     % Testsignal: cosine with 100Hz
现在我们计算FFT。由于FFT例程只处理长度为2的幂的向量,因此我们计算FFT长度,然后进行FFT

NFFT = 2^nextpow2(length(t));
X = fft(x,NFFT);
FFT的频率分辨率为fs/NFFT。由于FFT矢量的长度为NFFT,且频率从零DC开始,因此频率矢量为

f = (0:(NFFT-1)) * fs/NFFT;
因此我们可以创建一个绘图:

plot(f,abs(X));
正如我们所指定的,峰值几乎完全在100Hz。接下来你会注意到:我们的采样频率是fs=8000Hz,所以根据奈奎斯特定理,最大频率可以是fs/2=4000Hz。高于4000Hz的部分是频率轴的负部分,由于混叠,在4000Hz和8000Hz之间可见

现在,MATLAB提供了函数fftshift来重新排列向量x,从而使绘图从-fs/2到+fs/2,而不是从0到fs。它唯一能做的就是, 它将4000Hz和8000Hz之间的部分移动到-4000Hz到0Hz。 因此,您必须相应地创建频率向量

X_shifted = fftshift(X);
f_shifted = (-NFFT/2:NFFT/2-1) * fs/NFFT;
现在,峰值为+-100Hz,正如您所期望的余弦

长话短说:找出采样频率并创建频率向量。然后使用fftshift绘制双边频谱,或者忽略负频率,因为FFT对于实际输入值始终是对称的。

那么

首先,这些信息应该由你的老师提供

继续,我假设您知道什么是数字音频信号。尽管如此,您必须了解,MATLAB并不关心向量中是否有关于模拟音频信号、印度马铃薯生长统计数据、非洲降雨量或太阳风暴数量的数据。当您创建audiorecorder类的一个对象并向其传递一个向量时,MATLAB会向扬声器发送相应的信号。通过相应的信号,我指的是模拟电流的值

下一点是如何计算这些值,但对于这一点,您应该查看DA/AD转换

与音频再现一样,傅里叶变换系数遵循相同的方式。MATLAB不关心fft函数中传递的内容。它只是做计算

这些计算只是计算序列/信号/任何东西的离散傅里叶变换的一种快速有效的方法。实际的方法称为傅里叶变换。因为它实际上需要模拟信息,所以只能用笔和纸。如果我们在数字域移动,即在计算机内部,那么我们有一个离散傅里叶变换。这也很慢。为了加快速度,一些聪明人找到了按字面意思处理位的方法,并大大减少了必要的计算量。这种方法称为快速傅里叶变换。请注意,这只是一个算法,而不是算法的实现

该算法正在以各种方式实现。一个可以被认为是最快的,但也是最昂贵的。这就是FFTw,我想是麻省理工学院开发的。。。您可以通过在MATLAB help fft中编写代码来检查它,并查看帮助文本的最后条目或查看文档。必须说,还有其他相当快的FFT实现,如Ooras(如果我写对了名称)和KissFFT

无论哪种方式,FFT都只是一种DFT,这意味着它保留了所有DFT属性,作为可以观察到的反射

在音频中,如果不处理x轴,只进行绘图ABSFFTA,则x轴的单位为频率箱索引。没有频率,没有样本,没有其他。频率箱指数。不多不少

所以你现在应该问的问题是:这个箱子是什么,它是如何与音频信号中的频率相联系的

FFT有一个权衡。要么你看到整个信号在时间上缩小,你也可以对频率上的放大进行很好的分析,要么你只分析一帧信号在时间上放大,频率上的较低细节在频率上缩小。这是一个折衷的原因,因为如果你只对整个信号进行FFT,你可以观察到每个频率单元中包含的平均能量。如果你想知道这种能量是如何随着信号的演化而变化的,你必须有帧,这样你的频率分析就更低了

频率单元和信号实际频率的关系可通过FFT的δF给出。δF通过以下公式计算:

Df = Fs/N
其中Df是delta f,也称为fft分析,Fs是采样频率,N是传递给fft的样本量。因此,给定相同的Fs,例如44100Hz,如果有44100个样本的信号,FFT将进行1Hz的分析。如果有22050个样本的信号,则FFT将有2 Hz的分析

这意味着每个FFT系数将表示Df指定的频率范围内的能量

所以,如果你想在你的x轴上有赫兹,你应该做x值的向量,然后用你的信号画出来

下面是一个示例代码,它可能有错误。。。我没有检查它:

[signal, fs] = audioread('a.wav'); % Load your wav file
Df = fs/max(size(signal)); % Calculate the Df
f = 0:Df:fs; % Construct the frequency vector for the X axes

signal_f = abs(fft(signal)); % Get the FFT of the signal
plot(f, signal_f(1:length(f)) % Plot the frequency vector and only the valuable information in signal_f

首先,这些信息应该由你的老师提供

继续,我假设您知道什么是数字音频信号。尽管如此,您必须了解,MATLAB并不关心向量中是否有关于模拟音频信号、印度马铃薯生长统计数据、非洲降雨量或太阳风暴数量的数据。当您创建audiorecorder类的一个对象并向其传递一个向量时,MATLAB会向扬声器发送相应的信号。通过相应的信号,我指的是模拟电流的值

下一点是如何计算这些值,但对于这一点,您应该查看DA/AD conver 锡安

与音频再现一样,傅里叶变换系数遵循相同的方式。MATLAB不关心fft函数中传递的内容。它只是做计算

这些计算只是计算序列/信号/任何东西的离散傅里叶变换的一种快速有效的方法。实际的方法称为傅里叶变换。因为它实际上需要模拟信息,所以只能用笔和纸。如果我们在数字域移动,即在计算机内部,那么我们有一个离散傅里叶变换。这也很慢。为了加快速度,一些聪明人找到了按字面意思处理位的方法,并大大减少了必要的计算量。这种方法称为快速傅里叶变换。请注意,这只是一个算法,而不是算法的实现

该算法正在以各种方式实现。一个可以被认为是最快的,但也是最昂贵的。这就是FFTw,我想是麻省理工学院开发的。。。您可以通过在MATLAB help fft中编写代码来检查它,并查看帮助文本的最后条目或查看文档。必须说,还有其他相当快的FFT实现,如Ooras(如果我写对了名称)和KissFFT

无论哪种方式,FFT都只是一种DFT,这意味着它保留了所有DFT属性,作为可以观察到的反射

在音频中,如果不处理x轴,只进行绘图ABSFFTA,则x轴的单位为频率箱索引。没有频率,没有样本,没有其他。频率箱指数。不多不少

所以你现在应该问的问题是:这个箱子是什么,它是如何与音频信号中的频率相联系的

FFT有一个权衡。要么你看到整个信号在时间上缩小,你也可以对频率上的放大进行很好的分析,要么你只分析一帧信号在时间上放大,频率上的较低细节在频率上缩小。这是一个折衷的原因,因为如果你只对整个信号进行FFT,你可以观察到每个频率单元中包含的平均能量。如果你想知道这种能量是如何随着信号的演化而变化的,你必须有帧,这样你的频率分析就更低了

频率单元和信号实际频率的关系可通过FFT的δF给出。δF通过以下公式计算:

Df = Fs/N
其中Df是delta f,也称为fft分析,Fs是采样频率,N是传递给fft的样本量。因此,给定相同的Fs,例如44100Hz,如果有44100个样本的信号,FFT将进行1Hz的分析。如果有22050个样本的信号,则FFT将有2 Hz的分析

这意味着每个FFT系数将表示Df指定的频率范围内的能量

所以,如果你想在你的x轴上有赫兹,你应该做x值的向量,然后用你的信号画出来

下面是一个示例代码,它可能有错误。。。我没有检查它:

[signal, fs] = audioread('a.wav'); % Load your wav file
Df = fs/max(size(signal)); % Calculate the Df
f = 0:Df:fs; % Construct the frequency vector for the X axes

signal_f = abs(fft(signal)); % Get the FFT of the signal
plot(f, signal_f(1:length(f)) % Plot the frequency vector and only the valuable information in signal_f

你好Pierpo,欢迎来到SO!这是一个很好的问题,陈述得很好,有情节记录,等等。我能问你一个问题吗?请不要生气,这绝不意味着对你有任何负面影响。问题是:你是从哪里学到可以使用FFT进行频率分析的一些大学课程,在哪里,关于什么?你们的老师是只讨论FFT,还是这些信息被嵌入到了一些关于谱估计的讲座中,有没有提到周期图,韦尔奇的方法,随机过程,AR过程,诸如此类的?非常感谢。你好我几乎没有上过信号处理课。今年我有一门关于信号处理的课程,但是内容太差了,我什么都买不到。这就是为什么我会犯巨大的错误,抱歉。如果你真的想知道,我在法国的Ensimag学习!不过,所讨论的课程并非来自Ensimag。谢谢您的回答!正如我所说,你的问题没有错。只是我经常在这里看到一些问题,人们知道如何使用FFT,但显然没有太多,我想知道,在某些学科中,学生们是否只剩下这些基本信息。顺便说一句,如果你想找一本关于信号处理的好书,请看一看索福克勒斯J.奥法尼迪斯的著作。PDF可在他的网站上免费获得,请参见link.@A.Donda供参考:在许多生物学子学科中,没有数学/工程背景的学生经常使用昂贵的点击式软件进行信号分析,而没有任何基础知识,这在该领域是一个非常严重的问题。当上述学生遇到一种新的已发布的方法,而这种方法在任何可用的软件中都没有实现时,唯一的出路就是自学信号处理的基础知识,并尝试他们学校的MATLAB许可证。

在这方面,像这样的问答网站是最好的开始方式。你好,Pierpo,欢迎来到SO!这是一个很好的问题,陈述得很好,有情节记录,等等。我能问你一个问题吗?请不要生气,这绝不意味着对你有任何负面影响。问题是:你是从哪里学到可以使用FFT进行频率分析的一些大学课程,在哪里,关于什么?你们的老师是只讨论FFT,还是这些信息被嵌入到了一些关于谱估计的讲座中,有没有提到周期图,韦尔奇的方法,随机过程,AR过程,诸如此类的?非常感谢。你好我几乎没有上过信号处理课。今年我有一门关于信号处理的课程,但是内容太差了,我什么都买不到。这就是为什么我会犯巨大的错误,抱歉。如果你真的想知道,我在法国的Ensimag学习!不过,所讨论的课程并非来自Ensimag。谢谢您的回答!正如我所说,你的问题没有错。只是我经常在这里看到一些问题,人们知道如何使用FFT,但显然没有太多,我想知道,在某些学科中,学生们是否只剩下这些基本信息。顺便说一句,如果你想找一本关于信号处理的好书,请看一看索福克勒斯J.奥法尼迪斯的著作。PDF可在他的网站上免费获得,请参见link.@A.Donda供参考:在许多生物学子学科中,没有数学/工程背景的学生经常使用昂贵的点击式软件进行信号分析,而没有任何基础知识,这在该领域是一个非常严重的问题。当上述学生遇到一种新的已发布的方法,而这种方法在任何可用的软件中都没有实现时,唯一的出路就是自学信号处理的基础知识,并尝试他们学校的MATLAB许可证。在这方面,像这样的问答网站是最好的开始方式。好答案!但如果你提到fftshift的使用,并将稍后的频率箱与负频率关联,可能会更好…非常感谢你的回答!我非常感激:-我相信这将是非常有帮助的!我现在不能使用Matlab,但我明天会看一看。顺便问一下,你能给我推荐一些关于信号处理的论文或书吗?如果可能,可在线免费获取。。。再次感谢:-x轴不能以样本为单位,因为样本数与时间成正比,而傅里叶变换的自变量是频率。正如我在回答中所说,x轴的单位是FFT系数指数。正是@BenVoigt!X轴是与fft系数指数等效的频率单元指数。不是样品!当然我不是指时间样本,而是频率样本。由于DFT是DTFT的采样版本,所以我选择了这个名称。我发现这可能会产生误导,所以我改变了它。谢谢你的意见,本·沃格特和科斯塔斯回答得好!但如果你提到fftshift的使用,并将稍后的频率箱与负频率关联,可能会更好…非常感谢你的回答!我非常感激:-我相信这将是非常有帮助的!我现在不能使用Matlab,但我明天会看一看。顺便问一下,你能给我推荐一些关于信号处理的论文或书吗?如果可能,可在线免费获取。。。再次感谢:-x轴不能以样本为单位,因为样本数与时间成正比,而傅里叶变换的自变量是频率。正如我在回答中所说,x轴的单位是FFT系数指数。正是@BenVoigt!X轴是与fft系数指数等效的频率单元指数。不是样品!当然我不是指时间样本,而是频率样本。由于DFT是DTFT的采样版本,所以我选择了这个名称。我发现这可能会产生误导,所以我改变了它。感谢您的输入,Ben Voigt和Kostas负频率内容本质上,它的存在是因为您的吉他弦允许波同时向两个方向传播。什么意思?负频率的存在和双向传播之间真的有关系吗?你指的是什么方向?附议。录制的声音不再显示其来源于吉他弦。存在负频率内容的原因是傅里叶系数指的是复谐波,但要分析/重构的信号是实值的。非常感谢您的回答!当我能够再次使用Matlab时,我会看一看它:-但更简单的是,扔一个骰子二十次,然后看出现的一系列数字的FT。说真的,傅立叶变换中的负频率与波的传播无关。正频率和负频率确实存在。例如,想象一下cosx=expi*x+exp-i*x/2。使用傅里叶变换的定义将导致狄拉克脉冲在+-频率
cy.由于DFT的对称性,@BenVoigt解释了fs/2以上的频率的存在。负频率内容本质上,它的存在是因为您的吉他弦允许波同时向两个方向传播。什么意思?负频率的存在和双向传播之间真的有关系吗?你指的是什么方向?附议。录制的声音不再显示其来源于吉他弦。存在负频率内容的原因是傅里叶系数指的是复谐波,但要分析/重构的信号是实值的。非常感谢您的回答!当我能够再次使用Matlab时,我会看一看它:-但更简单的是,扔一个骰子二十次,然后看出现的一系列数字的FT。说真的,傅立叶变换中的负频率与波的传播无关。正频率和负频率确实存在。例如,想象一下cosx=expi*x+exp-i*x/2。使用傅里叶变换的定义将导致狄拉克脉冲在+-频率。由于DFT的对称性,fs/2以上的频率如@BenVoigt所解释的那样存在。