图像缩略图

短时傅里叶反变换(ISTFT)与Matlab

版本5.0.0.0(383 KB)由 斯托伊Zhivomirov
利用逆短时傅里叶变换(ISTFT)进行时频重合成。
5.0
23日评级

54下载

更新2019年2月28日

视图版本历史

查看许可协议

本代码是一个Matlab函数,它提供给定频谱图STFT(k,l)的短时傅里叶逆变换(ISTFT),时间跨列,频率跨行。该函数的输出为:
1)时域重构信号;
2)时间向量。
为方便起见,在函数的开头给出了输入和输出参数

为了阐明该函数的用法,文中给出了一个例子。它代表了一个给定信号x[n]的时频分析和完美重构,分别使用Blackman窗和Hamming窗进行分析和重新合成。此外,还提供了一个名为OLAExam的GUI,通过重叠添加(OLA)方法来表示完美的重建,并帮助选择分析/重新合成窗口(它们的长度和跳跃大小)。

该代码基于以下理论:

[1] H.Zhivomirov。关于STFT分析和ISTFT综合例程的开发及其实际实现。TEM期刊,ISSN:2217-8309,DOI:10.18421/TEM81-07,第8卷,第1期,第56-64页,2019年2月。(http://www.temjournal.com/content/81/TEMJournalFebruary2019_56_64.pdf

引用作为

H.Zhivomirov.关于STFT分析和ISTFT合成程序的开发及其实际实施。TEM期刊,ISSN:2217-8309,DOI:10.18421/TEM81-07,第8卷,第1期,第56-64页,2019年2月(http://www.temjournal.com/content/81/TEMJournalFebruary2019_56_64.pdf)

斯托伊Zhivomirov(2021)。短时傅里叶反变换(ISTFT)与Matlab(//www.tatmou.com/matlabcentral/fileexchange/45577-inverse-short-time-fourier-transform-istft-with-matlab), MATLAB中央文件交换。检索

意见及评分(45

思迪 申

宏磊沈

给林

安妮西亚·班纳吉

Haluk它

迈克尔Crosley

阅读你的论文,很高兴你也上传了代码!

jhonatan Caicedo

福赞·努苏拉

非常感谢分享,非常非常有帮助的XD

马蒂厄·昆茨

非常完美,谢谢!

赵红阳

我想知道为什么你用OLA而不是griffin lim算法来重建信号?

斯托伊Zhivomirov

你好Raden !感谢您对我的投稿感兴趣!关于这个问题,由于没有足够的重叠窗口段,重构信号的开始和结束都没有满足ola约束。解决这个问题的一种方法是在原始信号的开始和结束处填充适当数量的零,然后在重建信号的两端删除相同数量的零。

所有最好的,
斯托伊Zhivomirov

Raden

感谢您提交的Hristo,
我有一个问题,如果信号的开始和结束都是0重建信号是完美的。但如果边界不是0,则代码将其转换为0(因此信号的开始和结束看起来像一个圆锥体)。我如何修复这个,我已经尝试改变窗口和跳跃大小?

托马斯Richner

谢谢,重叠和添加方法的伟大实现。

托米

欢钟

斯托伊Zhivomirov

你好,本杰明,
在实际的时频分析和再合成中,使用了两种类型的窗口。STFT分析窗口是根据其频率分辨率和旁瓣特性选择的。ISTFT合成窗口可最大限度地减少重建伪影(如果有)通过时域平滑。应仔细选择两个窗口,以便相互配合提供完美的重建。如果在合成之前对STFT进行了修改,则必须使用合成窗口。在我的ISTFT功能中,我使用汉明窗口作为合成窗口请仔细检查[1]式(12.8)-(12.11)和[3]式(5.5)-(5.8)。

最好的问候,
斯托伊Zhivomirov

本杰明·哈蒙德

你好,斯托伊,

谢谢你制作了STFT和ISTFT函数,但是通过阅读《语音处理手册》和检查代码,我认为ISTFT可能有一个小错误。m函数。如果我错了,请纠正我。

在STFT中,使用了一个汉明窗口。假设窗口长度为1024个样本,跳跃大小为wlen/4,如您的示例所示。汉明窗口的时间总和构成一个常数(除了最开始和最结束)。在STFT代码中,在每个帧索引l处应用一个窗口w[n],给出公式12.1 x_l[n]=w[n].*x[n+lL]0<=n<=n<=n-1。

当在每个时间帧l执行ifft时,应该返回x_l[n]=w[n]。*x[n+lL];或对于全球时间t=n+lL:
x_l[t- ll]=w[t- ll]x[t]如式12.7所示。

由于窗口w[t-lL]在时间上的总和是一个常数,重构应该通过简单地在ifft之后在正确的时间上添加每个信号帧来给出,然后除以原来由stft中汉明窗口的添加给出的常数。这个常数就是合成窗口v[t-lL]。这就得到了12.8中重建的信号。

在istft的第42和58行。然而,M代码,你已经乘以了一个额外的汉明窗口。好像是《语音处理手册》和你的stft。M编码“。*win"应该被删除,W0也应该被修改。

你同意吗?如果没有,请告诉我哪里做错了。

再次感谢您编写的代码。

帕拉BACHHAV

rabbasi

我检查了ISTFT的输入。你知道,我过滤了数据,所以频率维度改变了。这就是为什么它会给我这个错误。当我将输入更改为主STFT输出时,所有内容都会通过。

但现在,我的问题是,我应该在时间-频率尺度去噪数据,然后返回到时间尺度。????我能做什么

rabbasi

我应该把频率维度的数据转换成时间尺度。我该如何处理这个错误?

rabbasi

亲爱的斯托Zhivomirov,
我和保罗·C有同样的问题。
我使用了与STFT相同的功能。
我有一个498900样本的信号,fs=250KHZ, h=125,wlen=nfft=625。
正如我所说,我在ISTFT中再次使用了这些参数,但我得到了错误“矩阵维数必须一致”
如我所见,这是因为乘法:
(xprim.*赢)
我还有另一个问题,主信号的长度不等于ISTFT代码第一行中产生的长度。
Xlen = NFFT + (coln-1)*h;
谢谢您的宝贵时间

nipawan pakoktom

帕拉BACHHAV

你好,斯托伊,
感谢您的解释,参考资料非常有用。如果窗口选择如下,那么它也满足hop=wlen/2的OLA约束[斯普林格手册第12章]
w =汉明(wlen,“周期性”);
K=总和(w)/h;
w = sqrt (w / K);

你能给我一个参考,解释时域插值对再合成的影响(你在下面的评论中解释的事情之一)?

谢谢,
帕拉

斯托伊Zhivomirov

你好,Pramod,感谢你对我的投稿感兴趣!为了实现信号在时域的完美重构,必须满足OLA约束。在实际应用中,根据STFT的频率分辨率和旁瓣特性选择STFT分析窗口,并结合分析窗口选择ISTFT合成窗口提供完美的重构。在STFT的修改在合成之前进行的情况下,合成窗口使重构伪影最小化。在我的ISTFT函数中,我使用了汉明窗口作为合成窗口(也用于分析)。我相信您有一些问题,因为可能您使用了不满足OLA约束的不同分析/合成窗口。如需进一步阅读,请参阅施普林格语音处理手册第12章。

所有最好的,
斯托伊Zhivomirov

斯托伊Zhivomirov

嗨,亨德里克,谢谢你的关注!我的STFT函数在编程上与Matlab频谱图函数不同,但给出了相同的结果。看看//www.tatmou.com/matlabcentral/fileexchange/45197-short-time-fourier-transformation--stft--with-matlab-implementation?requestedDomain=www.tatmou.com

当做
斯托伊Zhivomirov

•Santosa

嗨,斯托伊,
这个代码(stft)与Matlab中的谱图函数相同吗?
谢谢

帕拉BACHHAV

你好,Hristo,谢谢你的代码。
当我观察和收听用加权OLA重建的波形时,它不如原来的波形文件。但当我在istft移开窗户。M (x((b+1):(b+nfft)) = x((b+1):(b+nfft)) + (xprim)';),则重构后的图像(波形和质量)与原始图像完全相同。所以我的问题是,你们为什么要用加权OLA进行重建?

J.R

谢谢斯托伊!但是如果我希望x是一个复信号,我该如何用ISTFT从s中恢复复信号呢?请给我一些建议,谢谢!

斯托伊Zhivomirov

嗨j ! r感谢您的评论,感谢您对我的投稿感兴趣。

1)选择h = wlen/(4*n),其中n = 1,2,3,…NFFT = wlen。
2)函数假设x是实数信号,不是复数信号。

当做
斯托伊Zhivomirov

阿迪亚胡

你好
我试着先得到时频图,信号的主频率大约是900MHz,但结果是1300MHz左右,

J.R

嗨斯托伊!
1、 为什么我需要130*x_istft才能得到正确的信号
2、 当x为复数(%x=hilbert(x);)时,但x_istft不正确,且x_istft为实值

清除,clc,全部关闭
%定义信号参数
%正弦波信号(静止信号)

fs = 10 * 10 ^ 6;
t = 0:1 / fs: 4999 / fs;
x = 10 * sin(2 *π* t * 100000);
% x = hilbert(x);

%定义分析和合成参数
wlen = 256;
h=8;
nfft = 4095;
进行分析和再合成
[s, f, t_stft] = stft(x, wlen, h, nfft, fs);
[x_istft, t_istft] = istft(s, h, nfft, fs);
%绘制原始信号
图(1)
情节(t, x,“b”)
网格化
轴([0 0.0005 -15 15])
set(gca, 'FontName', 'Times New Roman', 'FontSize', 14)
包含(时间、年代”)
ylabel(振幅,V)
标题(“原始信号和重构信号”)

%绘制重新合成的信号
等等
绘图(t_-istft,130*x_-istft,'-.r')
图例('原始信号','重构信号')

斯托伊Zhivomirov

嗨保罗C !感谢您的关注!从距离上解决这个问题很难,但我会尝试:)首先:检查你的stft -矩阵——它必须只包含唯一的fft点,跨列的时间和跨行的频率。此外,h和nfft参数必须与stft分析中相同。

保罗·C

你好,赫里斯托
我试图使用istft,但它一直给我:
使用时出错*
矩阵维数必须一致。

istft错误(第49行)
x((b+1):(b+nfft))=x((b+1):(b+nfft))+(xprim.*win);

我已经改变了参数h,nfft,正如你之前建议的那样,但没有解决它。我不知道问题出在哪里。你能帮忙吗?
我在SxN矩阵上应用这个函数。

很多谢谢!

保罗

TS沙玛

好的,谢谢你!

斯托伊Zhivomirov

嗨TS Sharma !感谢您对我的投稿感兴趣!在重构信号的开始和结束时,由于没有足够的重叠窗口段,ola约束都没有得到满足。解决这个问题的一种方法是选择一个较小的跳跃大小h = wlen/(4*n)(即更短的窗口或更大的n)。

最好的问候,
斯托伊Zhivomirov

TS沙玛

嗨斯托伊!
非常感谢你的代码。我只在重构信号的边界处观察到衰减。在中间区域,重建是完美的。即使在所提供的例子中,我也观察到同样的效果。如何解决这个问题?
感谢和问候,
Tanushree

斯托伊Zhivomirov

你好Indi_,

感谢您的评论,感谢您对我的投稿感兴趣。
您遇到麻烦的可能原因是您没有满足ola约束。试试这个:

1) 选择h=wlen/(4*n),其中n=1,2,3。。。;
2) 选择nfft=wlen。

您可以使用WindowChoice.m检查分析/合成设置是否满足ola约束

最好的问候,
斯托伊Zhivomirov

Indi_u

嗨,斯托伊,

非常感谢你在stft和istft上的代码。我用你的stft项目把时域信号转换到频域,然后用这个isft项目把它转换回时域。我使用了与调用stft时相同的h, nfft, fs参数。然而,实际信号的结果是不同的。想不出这种差异的原因,你的任何意见都将非常有用。

Darik

优素福

优素福

嗨,斯托伊,
你的评论很有帮助。
非常感谢。

斯托伊Zhivomirov

你好,优素福,

首先,感谢您的评论,感谢您对我的投稿感兴趣。
下面是答案:

1)选择h = wlen/(4*n),其中n = 1,2,3,…(h = wlen/2不满足ola约束,用WindowChoice.m检查)。
2)选择NFFT = wlen (NFFT > wlen cause the interpolation in the time domain of every signal segment = errors in resynthesis,所以如果你真的想要插值,你必须使用时频域的零填充技术)。

试试这个:

清除,clc,全部关闭

%定义信号参数
%正弦波信号(静止信号)

fs=48000;
t = 0:1 / fs: 1 - 1 / f;
x=10*sin(2*pi*t*10);

%定义分析和合成参数
wlen=64;
h = wlen / 4;
nfft = wlen;

进行分析和再合成
[stft, f, t_stft] = stft(x, wlen, h, nfft, fs);
[x_istft, t_istft] = istft(stft, h, nfft, fs);

%绘制原始信号
图(1)
情节(t, x,“b”)
网格化
轴([0 1 -15 15])
set(gca, 'FontName', 'Times New Roman', 'FontSize', 14)
包含(时间、年代”)
ylabel(振幅,V)
标题(“原始信号和重构信号”)

%绘制重新合成的信号
等等
情节(t_istft x_istft,“r”)
图例('原始信号','重构信号')

最好的问候,

斯托伊Zhivomirov

优素福

大家好!
我已经用stft函数将长度为1024的信号转换为时频域。但是,当我使用istft函数将我的信号转换到原始空间时,它得到的信号长度为1984,振幅相差很大。
我的伪代码是:
U =正弦
nfft = 1024;
wlen = 64;
h=32;fs=1;
[stft, f, t] = stft(U, wlen, h, nfft, fs);
[x,t]=istft(stft,h,nfft,fs);
如果您能发表评论,我将不胜感激。

MATLAB版本兼容性
创建R2014b
与任何版本兼容
平台的兼容性
窗户 马科斯 Linux

社区寻宝

在MATLAB中心找到宝藏,并发现社区如何可以帮助你!

开始狩猎!