我一直在尝试确定此任务的逻辑,并计划使用KissFFT源程序包执行快速傅立叶变换。请让我知道这是否正确:


分配FFT结构,即。 kiss_fft_alloc(N,0,NULL,NULL)
N是我正在使用的窗口大小。输入缓冲区将是N类型的kiss_fft_scalar元素数组。输出缓冲区将是N/2 + 1类型的kiss_fft_cpx元素数组。
解码N(窗口大小)数量的PCM样本。
对于每个PCM样本,平均每个通道的振幅(无符号样本),并从0开始缩放到2(除以65536.0),将结果存储到输入缓冲区中。
在输入缓冲区中执行加窗(即Hanning)。在输入缓冲区中执行快速傅立叶变换,存储到输出缓冲区中。由于我使用实数值作为输入,因此可以使用kiss_fftr()
对于N/2输出值,请获取转换后数据的平方大小,然后使用以下公式将这些值转换为dB标度:
10 * log10 (re * re + im * im)

绘制第6步中的N/2值。
舍弃输入缓冲区的前半部分,解码下一个(窗口大小/ 2)PCM样本,并对数据进行缩放和加窗。这样应该可以有效地滑动输入窗口,并且不必在处理过的PCM样本上重做数学运算。
跳至步骤5,重复这些步骤,直到处理完所有样本为止。
kiss_fft_alloc()中释放使用的内存。 >
建议我在执行FFT之前从输入窗口中减去一个值,以使生成的DC值的大小为零。我应该从输入数据中减去平均值还是平均值?

另外,选择窗口大小时需要考虑哪些事项?除此之外,按照KissFFT的说明,它必须是偶数,使用较小的窗口大小也有好处。它会提供更好的图形吗?我认为大窗口会减少必须执行的FFT数量,这是使用大窗口的唯一好处吗?

最后,当我到达数据准备就绪的地步时绘图,我该如何绘图呢?过去处理波形图逻辑时,我只是沿$ x $轴为每个像素绘制了3个值(最小幅度,最大幅度,RMS幅度),但我不知道该怎么做请使用频谱图数据。

预先感谢您提供的所有指南。

#1 楼

对我来说看起来不错。但是,在第3步中,您实际上想要将信号从-1缩放到1,否则您将添加DC。您提到要减去均值-我不建议对频谱图执行此操作,因为这样可以有效地滤除DC,频谱图应显示该DC是否存在。

选择窗口大小全都需要权衡。较大的窗口将为您提供更清晰的频率分辨率,但时间分辨率却较模糊。较短的窗口会给您相反的效果:时间分辨率更高,而频率分辨率却模糊。窗口大小的适当选择将取决于您要分析数据。通常,这是2的幂,只是因为FFT往往喜欢2的幂。一个不错的经验法则是,您的窗口应该至少是您希望能够准确确定的最低频率周期的两倍左右。

您可能想知道是否有可能更好地应对这种折衷,并且有一些技术可以解决:它们通常涉及一次计算具有几种不同FFT大小的频谱图,并将其组合。此网页上有一些很好的视觉信息:http://www.izotope.com/tech/aes_adapt/

如果您的窗口尺寸太小,则两个非常接近的频率可能无法彼此区分,因为它们都位于同一个FFT档中。如果窗口大小太大,则可能会在时间上合并两个关闭事件,或者急剧的瞬变可能会逐渐演变为攻击。查看我发布的该网页,了解一些可视化方法。

较大的窗口大小并不一定减少FFT的数量。您已选择使用短时傅立叶变换来计算频谱图,其中傅立叶变换的重叠部分是FFT大小的一半。如果需要,可以使用更高的重叠因子。与需要计算多少个FFT相比,选择窗口大小更重要的是要进行时间/频率折衷。在设计频谱图(或任何STFT)时,您可以考虑选择窗口大小,跳数大小,块之间的距离作为独立参数。

绘制时,时间通常在x轴上,频率在y轴上(通常是对数刻度,梅尔刻度等,而不是线性刻度),然后幅度用颜色强度表示,即非常深的颜色对应较小的幅度,非常明亮的颜色对应较大的幅度。

评论


$ \ begingroup $
您的链接似乎已断开。你能更新吗?
$ \ endgroup $
–丹尼尔·沃尔夫(Daniel Wolf)
19年9月1日在10:06