从 abs 和 phase 恢复到 stft

信息处理 Python 频谱图 stft
2022-02-20 10:51:36

我在python上有以下代码

stftspectro = librosa.stft(audio, n_fft=fft_length, hop_length=stride, win_length=window, window='hann')
abs = np.abs(stftspectro)
angle = np.angle(stftspectro)

我可以从绝对和角度下方恢复到 stftspectro。我对声音信号一无所知,但stft正如我所读到的,来自的频谱图非常适合音频属性,并且我正在应用一些依赖于这些特征的深度神经网络。此外,执行逆 stft 将产生相同的声音:

stfttoaudio = librosa.istft(stftspectro, hop_length=stride, win_length=window, window='hann')

所以收集腹肌和角度对我的想法很有帮助。

1个回答

正如 Marcus Müller 所说,将值转换回复数abs时会出错。angle它应该是这样的:

x=|x|(cosϕ+jsinϕ)

请注意,convstft此转换的结果将接近,但不等于 中的原始值stftspectro,很可能是由于浮点计算的不准确性。

这是一个可重现的示例:

import numpy as np
import librosa

# Creating some audio signal
y, sr = librosa.load(librosa.ex('choice'), duration=10)
tempo, beats = librosa.beat.beat_track(y=y, sr=sr)
audio = librosa.clicks(frames=beats, sr=sr)

# Applying short-time Fourier transform with default parameters
fft_length = 2048
stride = 2048 // 4
window = 2048

stftspectro = librosa.stft(audio, n_fft=fft_length, hop_length=stride, win_length=window, window='hann')
abs_val = np.abs(stftspectro)
angle = np.angle(stftspectro)

# Converting abs and angle back to complex number
convstft = abs_val*(np.cos(angle)+1j*np.sin(angle))

# Checking results
# Choosing an arbitrary element index
n=50
m=45

# Is this element similar?
print("stftspectro element:",stftspectro[n][m])
print("abs_val element:",abs_val[n][m])
print("angle element:",angle[n][m])
print("convstft element:",convstft[n][m])

# Are stftspectro and convstft the same?
A=stftspectro
B=convstft
eps = 0.0001+1j*0.0001
print("Are they similar: ",np.array_equal(A,B))  # test if same shape, same elements values
print("Are they close: ",np.allclose(A,B,atol=eps)) # test if same shape, elements have close enough values

另外,我不会abs用作变量的名称,因为它是 python 方法 abs() 的名称。