4

我正在开发一种工具来比较两个波形文件的波形相似性。例如,我有一个持续时间为 1 分钟的波形文件,我使用第一个文件制作了另一个波形文件,但每 5 秒的数据以 5 秒的间隔制作为 0。现在我的软件会告诉我在 5 秒到 10 秒的时间间隔内有波形差异, 15 秒到 20 秒, 25 秒到 30 秒等等...

截至目前,随着初步开发,这工作正常。以下是 3 个测试集:

  1. 我有两个采样率为 960Hz 的波形文件,单声道,没有数据样本为 138551(arnd 1min 12sec 文件)。我正在使用 128 点 FFT(将文件拆分为 128 个样本块),结果很好。

  2. 当我对采样率为 48KHz、2 通道的波形文件使用相同的算法时,每个通道没有数据样本 6927361(arnd 2 分 24 秒文件),该过程变得太慢。当我使用 4096 点 FFT 时,过程更好。

  3. 但是,在 22050Hz、2 通道的文件上进行 4096 点 FFT,每个通道的数据样本数为 55776(arnd 0.6sec 文件)给出的结果非常差。在这种情况下,128 点 FFT 给出了很好的结果。

所以,我很困惑如何决定 FFT 的长度,以便我的结果在每种情况下都很好。

我猜长度应该取决于样本数量和采样率。请就此提供您的意见。

谢谢

4

2 回答 2

5

FFT 的长度N, 将决定频域中的分辨率:

resolution (Hz) = sample_rate (Hz) / N

因此,例如,在情况 (1) 中,您有resolution = 960 / 128 = 7.5 Hz. 因此,生成的 FFT(或由此得出的功率谱)中的每个bin将是 7.5 Hz 宽,您将能够区分至少相距这么远的频率分量。

由于您没有说明这些是哪种波形,或者您的应用程序的目的是什么,因此很难知道您需要哪种分辨率。

还有一点很重要——许多第一次使用 FFT 的人都没有意识到,通常您需要在 FFT 之前应用一个窗函数来避免频谱泄漏

于 2011-11-15T09:04:30.850 回答
1

我不得不说我发现你的问题很神秘。我认为您应该研究短时傅里叶变换。我之所以这么说是因为如果您在 2 分钟内使用 44.1KhZ 的采样频率和 2 个通道,那么您正在查看大量样本。整个数量的一个 fft 确实需要相当长的时间,更不用说估计会出现偏差,因为信号均值和方差将在整个持续时间内发生巨大变化。为避免这种情况,您首先要对时域信号进行帧化,这些帧可以小至 20ms-40ms(通常用于语音)并且经常重叠(Welch method of Spectral Estimation)。然后应用诸如汉明或汉宁窗之类的窗函数来减少频谱泄漏并为每一帧计算 N 点 fft。其中 N 是该帧中样本数的二的下一个幂。例如:

  1. Fs = 8Khz,单通道;
  2. 时间 = 120 秒;
  3. no_samples = 时间 * Fs = 960000 ;
  4. 帧长 T_length= 20ms;
  5. 样本中的帧长度 N_length = 160;
  6. 帧重叠 T_overlap= 10ms;
  7. 样本中的帧重叠 N_overlap= 80;
  8. 帧数 N_frames = (no_samples - (N_length-N_overlap))/N_overlap = 11999;
  9. FFT 长度 = 256;

因此,您总共将处理 11999 帧,但您的 FFT 长度会很小。您只需要 256 的 FFT 长度(帧长度 160 以上的 2 次幂)。大多数实现 fft 的算法都要求信号长度和 fft 长度相同。您所要做的就是将零添加到您的成帧信号直到 256。所以用 x 数量的零填充每一帧,其中 x = FFT_length-N_length。我最新的 android 应用程序在录制的语音上执行此操作,并使用短时 FFT 数据来显示语音的频谱图,并执行各种频谱修改和过滤,它称为Android 语音增强

于 2012-03-26T10:17:29.607 回答