了解音频文件频谱图值
Posted
技术标签:
【中文标题】了解音频文件频谱图值【英文标题】:Understanding audio file spectrogram values 【发布时间】:2017-01-11 22:42:23 【问题描述】:我目前正在努力了解功率谱是如何存储在 kaldi 框架中的。
我似乎已经成功地创建了一些数据文件使用
$cmd JOB=1:$nj $logdir/spect_$name.JOB.log \
compute-spectrogram-feats --verbose=2 \
scp,p:$logdir/wav_spect_$name.JOB.scp ark:- \| \
copy-feats --compress=$compress $write_num_frames_opt ark:- \
ark,scp:$specto_dir/raw_spectogram_$name.JOB.ark,$specto_dir/raw_spectogram_$name.JOB.scp
这给了我一个包含不同音频文件数据点的大文件,例如this。
问题是我不确定我应该如何解释这个数据集,我知道在此之前执行 fft,我想这是一件好事。
上面给出的输出示例来自一个 1 秒长的文件。 所有标准都已用于计算频谱图,因此采样频率应为 16 kHz,帧长 = 25 ms,重叠 = 10 ms。 第一组数据点数为25186。
鉴于这些信息,我可以以某种方式解释输出吗?
通常当执行 fft 时,频率 bin 大小可以通过F_s/N=bin_size
提取,其中F_s
是采样频率,N
是 FFT 长度。那么这是同一个案例吗? 16000/25186 = 0.6...Hz/bin?
还是我理解错了?
【问题讨论】:
【参考方案1】:通常在执行 fft 时,频率 bin 大小可以通过
F_s/N=bin_size
提取,其中F_s
是采样频率,N
是 FFT 长度。那么这也是同样的情况吗? 16000/25186 = 0.6...Hz/bin?
公式F_s/N
确实是您用来计算频点大小的公式。但是,正如您提到的 N
是 FFT 长度,而不是样本总数。基于大约 25 毫秒的帧长度、10 毫秒的跳跃大小以及您生成的输出数据文件有 98 行的 257 个值的事实,对于一些可能的实值输入,使用的 FFT 长度似乎是 512。这会给你一个频率bin 大小为 16000/512 = 31.25 Hz/bin。
基于这种缩放比例,使用以下 Matlab 脚本绘制您的原始数据(之前在 Z
矩阵中加载的数据):
fs = 16000; % 16 kHz sampling rate
hop_size = 0.010; % 10 millisecond
[X,Y]=meshgrid([0:size(Z,1)-1]*hop_size, [0:size(Z,2)-1]*fs/512);
surf(X,Y,transpose(Z),'EdgeColor','None','facecolor','interp');
view(2);
xlabel('Time (seconds)');
ylabel('Frequency (Hz)');
给出了这个图表(深红色区域是最高强度的区域):
【讨论】:
数据集只有 97 行(不是 98 新行).. 第一行似乎不属于数据集.. @CarltonBanksN
样本上的实 FFT 将输出 N/2 + 1
复数值,包括 DC 和 F_s/2
频率处的 2 个纯实数值。对于N=512
,给出512/2 + 1 = 257
。此外,数据集文件有 99 行。排除不包含数据的第一行得到 98 行数据。
很抱歉问了这么多问题.. 但是您能否详细说明一下数字 98... 我想我理解为什么有 257 个条目,但我不确定我是否理解为什么有 98 行?..这条线在这里代表什么?..
每一行代表使用 FFT 对 1 个输入数据块计算的频谱。因此,它显示了该特定时间片的频谱。如果输入数据被分成不相交的块,那么你会得到 16000/512 ~ 31 行这样的行(它们本质上是独立的)。现在,由于 FFT 块中有重叠,因此您可以获得更多行。这些线不再独立,但提供了更好的时间分辨率(它们可以被视为一种插值)。当每个块开始比前一个晚约 160 个样本时,您需要 (16000-512)/160 + 1 ~ 98 个块来覆盖 1s
...嗯,你的时间轴是不是不正确?..我的意思是它不会是一个百分比,然后是秒吗?..[0:97]/97 = [0 ... 1]
以上是关于了解音频文件频谱图值的主要内容,如果未能解决你的问题,请参考以下文章