torchaudio频谱特征提取
1.读取和保存音频
再torchaudio中,加载和保存音频的API 是 load 和 save
import torchaudio
from IPython import display
data, sample = torchaudio.load(r"E:\pycharm\data\2s数据集\test\audio\c6.flac")
print(data.shape, sample)
display.Audio(data.numpy(), rate=sample)
torchaudio.save('./data/audio.wav', src=data, sample_rate=sample)
-------------------------------------------------------------------------
torch.Size([1, 32640]) 16000
需要注意的是,不同于librosa.load()的是,audio.load()不支持指定采样率,没有sr参数。
在保存时,可以通过format参数指定保存格式,encoding参数指定编码方式,bits_per_sample参数值指定编码的采样位数。
format可取值"mp3", “flac”, “vorbis”, “sph”, “amb”, “amr-nb”, “gsm”
encoding可取值:
- “PCM_S”: Signed integer linear PCM
- “PCM_U”: Unsigned integer linear PCM
- “PCM_F”: Floating point linear PCM
- “FLAC”: Flac, Free Lossless Audio Codec
- “ULAW”: Mu-law, [wikipedia]
- “ALAW”: A-law [wikipedia]
- “MP3” : MP3, MPEG-1 Audio Layer III
- “VORBIS”: OGG Vorbis [xiph.org]
- “AMR_NB”: Adaptive Multi-Rate [wikipedia]
- “AMR_WB”: Adaptive Multi-Rate Wideband [wikipedia]
- “OPUS”: Opus [opus-codec.org]
- “GSM”: GSM-FR [wikipedia]
- “UNKNOWN” None of above
2.提取特征
- Spectrogram
- GriffinLim
- Mel Filter Bank
- MelSpectrogram
- MFCC
- Pitch
- Kaldi Pitch (beta)
2.1短时傅里叶变换
以 Spectrogram为例,提取短时傅里叶特征
n_fft = 1024
win_length = None
hop_length = 512
# 短时傅里叶变换
transform = torchaudio.transforms.Spectrogram(
n_fft=n_fft,
win_length=win_length,
hop_length=hop_length,
center=True,
pad_mode="reflect",
power=2.0,
)
spec = transform(data)
print(spec.shape, spec.dtype)
------------------------------------------------------------
torch.Size([1, 513, 64]) torch.float32
2.2pytorch复数值的变换和使用
上述参数中值得注意的是指数power,根据官方文档power的值为大于0的float或者为None。比如1.0返回能量,2.0返回功率,None返回复数的频谱。
# 当power为None,返回的数据类型为复数complex64
transform_complex = torchaudio.transforms.Spectrogram(
n_fft=n_fft,
win_length=win_length,
hop_length=hop_length,
center=True,
pad_mode="reflect",
power=None,
)
spec_complex = transform_complex(data)
print(spec_complex.shape, spec_complex.dtype)
----------------------------------------------------------
torch.Size([1, 513, 64]) torch.complex64
由于复数值在网络中不能使用,可以用torch.view_as_real(),转为伪复数,即将复数拆分为实数和复数两部分,放到最后一个维度(最后一维变为2)
spec_real = torch.view_as_real(spec_complex)
print(spec_real.shape, spec_real.dtype)
----------------------------------------------------------------------------------
torch.Size([1, 513, 64, 2]) torch.float32
2.3Spectrogram的逆变换
API:InverseSpectrogram
InverseSpectrogramde只接受数据类型为复数的频谱,或者最后一维为2的伪复数的频谱矩阵。
inverse_Spect = torchaudio.transforms.InverseSpectrogram(n_fft=n_fft,
win_length=win_length,
hop_length=hop_length,
center=True,
pad_mode="reflect")
# 原始音频
print(data[0, :10])
# 伪复数矩阵的逆变换
data_hat = inverse_Spect(spec_real)
print(data_hat[0, :10])
# 复数矩阵的逆变换
data_hat2 = inverse_Spect(spec_complex)
print(data_hat2[0, :10])
==========================================================================
tensor([ 0.0000e+00, 0.0000e+00, 0.0000e+00, 3.0518e-05, 3.0518e-05,
3.0518e-05, 0.0000e+00, -6.1035e-05, 0.0000e+00, 0.0000e+00])
tensor([-2.2737e-13, 1.8190e-12, 2.0181e-12, 3.0518e-05, 3.0518e-05,
3.0518e-05, -2.2714e-13, -6.1035e-05, -3.5279e-12, -2.7309e-12])
tensor([-2.2737e-13, 1.8190e-12, 2.0181e-12, 3.0518e-05, 3.0518e-05,
3.0518e-05, -2.2714e-13, -6.1035e-05, -3.5279e-12, -2.7309e-12])
可以看到误差在小数点后10几位。