使用 librosa 理解 STFT

Posted

技术标签:

【中文标题】使用 librosa 理解 STFT【英文标题】:STFT understanding using librosa 【发布时间】:2019-07-16 13:51:07 【问题描述】:

我有一个 8khz 采样率的大约 14 秒的音频样本。 我正在使用 librosa 从这个音频文件中提取一些特征。

y, sr = librosa.load(file_name)
stft = np.abs(librosa.stft(y, n_fft=n_fft))

# file_length = 14.650022675736961 #sec
# defaults 
# n_fft =2048
# hop_length = 512 # win_length/4 = n_fft/4 = 512 (win_length = n_fft default)

#windowsTime = n_fft * Ts # (1/sr)

stft.shape
# (1025, 631)

规格展示:

librosa.display.specshow(stft, x_axis='time', y_axis='log')

[![stft sr = 22050][1]][1]

现在, 我可以理解 STFT 的形状

631 time bins = are 4 * ( file_length / Ts * windowsTime) #overlapping
1025 frequency bins = Frames frequency gap sr/n_fft.
so there are 1025 frequencies in 0 to sr/2(Nyquest)

我无法理解的是两种不同采样率的不同图 具有相同的比率。 1 - 22050 作为 librosa 默认值 2 - 8khz 作为采样率文件

y2, sr = librosa.load(file_name, sr=None)

n_fft2 =743 # (same ratio to get same visuals for comparsion)
hop_length = 186 # (1/4 n_fft by default)

stft2 = np.abs(librosa.stft(y2, n_fft=n_fft2))

所以 stft 的形状会有所不同

stft2.shape
# (372, 634)


[![stft sr = 743][2]][2]

1.但是为什么绝对频率不一样?它是相同的信号,只是没有被过采样,因此每个样本都是唯一的。 我错过了什么?是静态y轴吗?

2。我无法理解时间箱值。当第一个 1 在跃点长度中并且第二个 bin 是从该点到文件末尾的 windowTime 时,我期望帧数中的 bin。但是单位很奇怪?

我希望能够在特定时间(帧)内提取特定 Fbin 的幅度,或者另外能够对其中的一些求和以获得时间 RANGE 的幅度。

因此,如果我采用 stft[number of fBin] 即 1 行 1025 fBins (stft[1025]) 并查看它的内容,那么 stft[0] 包含 630 个点,每个频率正好是 630 个时间点因此 1-1025 帧中的每一帧都将具有相同的时间点。

所以如果我取一个适合所有其他 fbin 的样本(相同的时间点),即 stft[0] 我将能够选择时间范围和 fBin 并获得特定的幅度:

times =  librosa.core.frames_to_time(stft2[0], sr=sr2, n_fft=n_fft2, hop_length=hop_length) 

fft_bin = 6
time_idx = 10

print('freq (Hz)', freqs[fft_bin])
print('time (s)', times[time_idx])
print('amplitude', stft[fft_bin, time_idx])

数组([0.047375, 0.047625, 0.04825, 0.04825, 0.046875, 0.04675, 0.05、0.051625、0.051、0.048、0.05225、0.050375、 0.04925 , 0.04725 , 0.051625 , 0.0465 , 0.05225 , 0.05 , 0.053, 0.053875, 0.048, 0.0485, 0.047875, 0.04775, 0.0485, 0.049, 0.051375, 0.047125, 0.051125, 0.047125, 0.04725、0.05025、0.05425、0.05475、0.051375、0.060375、 0.050625、0.04875、0.054125、0.048、0.05025、0.052375、 0.04975, 0.054125, 0.055625, 0.047125, 0.0475, 0.047, 0.049875, 0.05025, 0.048375, 0.047, 0.050625, 0.05, 0.046625, 0.04925, 0.048, 0.049125, 0.05375, 0.0545, 0.04925, 0.049125, 0.049125, 0.049625, 0.047, 0.047625, 0.0535, 0.051875, 0.05075, 0.04975, 0.047375, 0.049, 0.0485、0.050125、0.048、0.05475、0.05175、0.050125、 0.04725、0.0575、0.056875、0.047、0.0485、0.055375、 0.04975、0.047、0.0495、0.051375、0.04675、0.04925、 0.052125、0.04825、0.048125、0.046875、0.047、0.048625、 0.050875, 0.05125, 0.04825, 0.052125, 0.052375, 0.05125, 0.049875、0.048625、0.04825、0.0475、0.048375、0.050875、 0.052875, 0.0475, 0.0485, 0.05225, 0.053625, 0.05075, 0.0525, 0.047125, 0.0485, 0.048875, 0.049, 0.0515, 0.055875, 0.0515, 0.05025, 0.05125, 0.054625, 0.05525, 0.047、0.0545、0.052375、0.049875、0.051、0.048625、 0.0475、0.048、0.048875、0.050625、0.05375、0.051875、 0.048125、0.052125、0.048125、0.051、0.052625、0.048375、 0.047625, 0.05, 0.048125, 0.050375, 0.049125, 0.053125, 0.053875、0.05075、0.052375、0.048875、0.05325、0.05825、 0.055625, 0.0465, 0.05475, 0.051125, 0.048375, 0.0505, 0.04675, 0.0495, 0.04725, 0.046625, 0.049625, 0.054, 0.056125, 0.05175, 0.050625, 0.050375, 0.047875, 0.047, 0.048125, 0.048875, 0.050625, 0.049875, 0.047, 0.0505, 0.047、0.053125、0.047625、0.05025、0.04825、0.05275、 0.051625, 0.05, 0.051625, 0.05425, 0.052, 0.04775, 0.047 , 0.049125 , 0.05375 , 0.0535 , 0.04925 , 0.05125 , 0.046375、0.04775、0.04775、0.0465、0.047、0.04675、 0.04675 , 0.04925 , 0.05125 , 0.046375 , 0.04825 , 0.0525 , 0.057875, 0.056375, 0.054375, 0.04825, 0.0535, 0.05475, 0.0485, 0.048875, 0.048625, 0.0485, 0.047625, 0.046875, 0.0465 , 0.05125 , 0.054 , 0.05 , 0.048 , 0.047875, 0.0515、0.048125、0.055875、0.054875、0.051625、0.048125、 0.047625, 0.048375, 0.052875, 0.0485, 0.0475, 0.0495, 0.05025 , 0.05675 , 0.0585 , 0.051625 , 0.05625 , 0.0605 , 0.052125, 0.0495, 0.049, 0.047875, 0.051375, 0.054125, 0.0525、0.0515、0.057875、0.055、0.05375、0.046375、 0.04775、0.0485、0.050125、0.050875、0.04925、0.049125、 0.0465、0.04975、0.053375、0.05225、0.0475、0.046375、 0.05375、0.049875、0.049875、0.047375、0.049125、0.049375、 0.04875、0.048125、0.05075、0.0505、0.046375、0.047375、 0.048625, 0.0485, 0.047125, 0.052625, 0.051125, 0.04725, 0.050875、0.053875、0.0475、0.0495、0.051、0.055、 0.053、0.050125、0.04675、0.05375、0.054375、0.04725、 0.046875、0.04925、0.04725、0.0495、0.05075、0.050875、 0.04775、0.05125、0.050125、0.047875、0.04825、0.046625、 0.0475、0.046375、0.04775、0.05075、0.048125、0.046375、 0.049625、0.0495、0.04675、0.046625、0.0475、0.04825、 0.053、0.050875、0.049、0.057875、0.058875、0.049875、 0.049125、0.0475、0.05225、0.055、0.055375、0.053875、 0.051125, 0.049875, 0.05025, 0.050875, 0.049, 0.0575, 0.051875, 0.049375, 0.04775, 0.051125, 0.050375, 0.0465, 0.047375, 0.0465, 0.046375, 0.048875, 0.051875, 0.047, 0.047125, 0.047125, 0.046875, 0.049625, 0.048625, 0.051, 0.049, 0.046375, 0.049, 0.056125, 0.054625, 0.047625, 0.046625、0.0475、0.051875、0.05175、0.047625、0.050375、 0.055125、0.05275、0.047125、0.05325、0.060125、0.056625、 0.053, 0.052125, 0.047125, 0.04825, 0.050375, 0.05025, 0.048, 0.046625, 0.047125, 0.04875, 0.047, 0.05525, 0.0535 , 0.047 , 0.0495 , 0.0535 , 0.05125 , 0.046625 , 0.0495 , 0.04675 , 0.04875 , 0.047125 , 0.04975 , 0.047 , 0.049875, 0.046875, 0.047125, 0.048, 0.046375, 0.0495, 0.04975、0.05125、0.048375、0.049125、0.0515、0.048375、 0.052375, 0.051125, 0.046375, 0.047125, 0.050375, 0.0465, 0.052375、0.05375、0.04925、0.05025、0.0565、0.054875、 0.048, 0.049375, 0.052625, 0.055375, 0.053375, 0.05075, 0.048875, 0.05475, 0.05075, 0.0485, 0.049125, 0.0475, 0.047375, 0.047375, 0.047, 0.052125, 0.053875, 0.049, 0.052625、0.0485、0.04675、0.04875、0.05、0.0545、 0.05025 , 0.0495 , 0.0515 , 0.0485 , 0.05025 , 0.0465 , 0.0465、0.048375、0.06375、0.10175、0.11975、0.118375、 0.121375, 0.12675, 0.123, 0.095375, 0.055, 0.05525, 0.04775, 0.053125, 0.052375, 0.056625, 0.0565, 0.046875, 0.048 , 0.05175 , 0.048 , 0.052 , 0.048 , 0.048 , 0.05175、0.05025、0.049625、0.049625、0.047375、0.046625、 0.052375, 0.0555, 0.051375, 0.050625, 0.052375, 0.050125, 0.048, 0.052125, 0.052125, 0.0495, 0.048875, 0.048, 0.049875, 0.051125, 0.050625, 0.048, 0.0465, 0.048, 0.04675, 0.050875, 0.048, 0.046625, 0.0495, 0.050375, 0.046625、0.0515、0.049875、0.049625、0.04675、0.049125、 0.05025, 0.050375, 0.04725, 0.047625, 0.047, 0.051625, 0.0485、0.05225、0.046875、0.0475、0.04825、0.050375、 0.05725, 0.052375, 0.048, 0.046375, 0.0475, 0.0495, 0.047875、0.046375、0.049875、0.046875、0.048、0.046875、 0.048625, 0.047125, 0.046625, 0.05, 0.048875, 0.04675, 0.050125, 0.05425, 0.051375, 0.050125, 0.053375, 0.052, 0.053875, 0.048, 0.05575, 0.049875, 0.052125, 0.048875, 0.047375、0.048875、0.049125、0.047375、0.047375、0.047625、 0.0495、0.04825、0.047875、0.04875、0.054、0.052125、 0.051, 0.046625, 0.04925, 0.05075, 0.054375, 0.0555, 0.051625, 0.046625, 0.052125, 0.055875, 0.047, 0.053875, 0.050875、0.0505、0.0465、0.053125、0.050875、0.050625、 0.051125、0.050875、0.056875、0.04925、0.050625、0.054125、 0.056625, 0.05025, 0.0465, 0.04675, 0.049625, 0.047, 0.048375, 0.047125, 0.04875, 0.048375, 0.048875, 0.04775, 0.04775、0.047、0.052125、0.050875、0.054、0.058375、 0.054、0.049125、0.04675、0.051875、0.05425、0.050125、 0.04675, 0.047625, 0.046375, 0.05275, 0.053, 0.04875, 0.049125, 0.047125, 0.049375, 0.0475, 0.051125, 0.0495, 0.052375, 0.047 , 0.047125, 0.050875])


  [1]: https://i.imgur.com/OeKzvrb.png
  [2]: https://i.imgur.com/ALtba5F.png

【问题讨论】:

您是否尝试将sr 指定为specshow 的参数? 【参考方案1】:

问题一:

使用specshow时需要指定采样率:

librosa.display.specshow(stft, x_axis='time', y_axis='log', sr=sr)

否则将使用默认值 (22,050 Hz)(请参阅docs)。

问题 2:

librosa.core.frames_to_time 不以stft[0] 作为参数,这将是第一帧的频率箱。相反,它将帧数作为第一个参数。

假设您有一个sr=10000 Hz 的音频信号。然后使用n_fft=2000hop_length=1000 在其上运行STFT。然后每跳得到一个,并且每跳的长度为0.1s,因为10000个样本对应1s,1000个样本(1跳)因此对应0.1s。

stft[0] 不是帧号。相反,第一个stft 的形状为(1 + n_fft/2, t)(参见here)。这意味着第一个维度是频率 bin,第二个维度是帧号 (t)。

因此stft 中的总帧数为stft.shape[1]。 要获取源音频的长度,您可以这样做:

time = librosa.core.frames_to_time(stft.shape[1], sr=sr, hop_length=hop_length, n_fft=n_fft)

【讨论】:

我曾经拥有过的最大的手掌之一。能否请您也回答第二个问题?谢谢! 无法关闭,因为第二个问题还没有回答。再次感谢。 现在怎么样?所有问题都回答了吗? 我明白你说的。但我想我错过了这个问题。我确实编辑了帖子以使其更清晰。非常感谢您的努力,请再看看? :) 我想我得到了我需要的东西:times = librosa.core.frames_to_time(range(0, stft.shape[1]), sr=sr, n_fft=n_fft, hop_length=hop_length)

以上是关于使用 librosa 理解 STFT的主要内容,如果未能解决你的问题,请参考以下文章

2020-01-18 python实现stft并绘制时频谱

2020-10-07 Librosa 音频处理初学的几点迷思

STFT的参数改怎么选

如何消除 librosa griffin lim 引入的失真?

使用 tensorflow.contrib.signal 重构信号会导致放大或调制(帧、重叠和添加、stft 等)

如何应用二进制掩码和 STFT 来生成音频文件?