如何用Python实现STFT等音频表示的重构(适配Autoencoder训练)
音频表示逆向重构实现方案(针对Autoencoder隐写训练调参)
我正在为隐写应用训练基于音频数据的Autoencoder模型,第一步需要验证STFT系数、频谱图、MFCC等音频表示的参数合理性。方法是将WAV文件转成这些表示后再逆向重构回音频,通过听感判断失真程度,以此调参避免影响模型训练。目前已经实现了转换代码,但重构部分需要帮助,以下是已实现的代码(缺少重构):
import os import librosa import librosa.display import IPython.display as ipd import numpy as np import matplotlib.pyplot as plt import tensorflow as tf scale_file = "/content/0-m-21-0-1-105.wav" y,sr = librosa.load(scale_file, sr=16000) ###### waveform ####### plt.figure(figsize=(12,5)) plt.xlabel("Time (s)") plt.ylabel("Amplitude") plt.title("Waveform") plt.plot(y) plt.show() ##### STFT ####### n_fft=1024 # window_length hop_length=512 window_type ='hann' sample_rate = 16000 # calculate duration hop length and window in seconds hop_length_duration = float(hop_length)/sample_rate n_fft_duration = float(n_fft)/sample_rate print(f'“STFT hop length duration is:{hop_length_duration}s ”') print(f'“STFT window duration is: {n_fft_duration}s ”.') stft_lib = librosa.stft(y, n_fft=n_fft, hop_length=hop_length, win_length=n_fft, window=window_type) ### spectrogram #### spectrogram = np.abs(stft_lib) log_spectrogram = librosa.amplitude_to_db(spectrogram) librosa.display.specshow(log_spectrogram, sr=sample_rate,hop_length=hop_length) plt.xlabel("Time") plt.ylabel("Frequency") plt.colorbar(format="%+2.0f dB") plt.title("Spectrogram (dB)") plt.savefig("spectogram_log.png") plt.show() ##### mel spectrogram #### mel_spect = librosa.feature.melspectrogram(y=y, sr = sr, n_fft=n_fft, n_mels = 20, hop_length=hop_length, window='hann') log_mel_spect = librosa.amplitude_to_db(mel_spect) librosa.display.specshow(log_mel_spect, sr=sample_rate,x_axis ='time', y_axis='mel',hop_length=hop_length) plt.colorbar(format="%+2.0f dB") plt.title("Log Mel spectrogram") plt.tight_layout() plt.savefig("Log Mel spectrogram.png") plt.show()
各音频表示的重构实现
1. STFT系数重构
STFT包含完整的幅度和相位信息,可直接逆变换还原音频,失真极小:
# 从STFT系数重构音频 y_recon_stft = librosa.istft(stft_lib, hop_length=hop_length, win_length=n_fft, window=window_type) # 播放重构音频 ipd.Audio(y_recon_stft, rate=sample_rate) # 保存重构音频 librosa.output.write_wav('recon_stft.wav', y_recon_stft, sample_rate)
2. 频谱图重构
频谱图仅保留STFT幅度,丢失相位,需用Griffin-Lim算法估计相位实现重构:
# 从频谱图(幅度)重构音频,n_iter为迭代次数,次数越高质量越好 y_recon_spec = librosa.griffinlim(spectrogram, hop_length=hop_length, win_length=n_fft, window=window_type, n_iter=32) # 播放与保存 ipd.Audio(y_recon_spec, rate=sample_rate) librosa.output.write_wav('recon_spectrogram.wav', y_recon_spec, sample_rate)
3. 梅尔频谱图重构
梅尔频谱是经过梅尔滤波的幅度谱,需先转回线性频谱,再用Griffin-Lim重构:
# 对数梅尔频谱转幅度谱 mel_spect_amp = librosa.db_to_amplitude(log_mel_spect) # 梅尔频谱转线性频谱 linear_spect = librosa.feature.inverse.mel_to_stft(mel_spect_amp, sr=sample_rate, n_fft=n_fft) # Griffin-Lim重构音频 y_recon_mel = librosa.griffinlim(linear_spect, hop_length=hop_length, win_length=n_fft, window=window_type, n_iter=64) # 播放与保存 ipd.Audio(y_recon_mel, rate=sample_rate) librosa.output.write_wav('recon_mel.wav', y_recon_mel, sample_rate)
4. MFCC重构(补充)
MFCC是更紧凑的特征,重构需先转回梅尔频谱,再转线性频谱,最后用Griffin-Lim:
# 提取MFCC特征 mfcc = librosa.feature.mfcc(y=y, sr=sample_rate, n_mfcc=13) # MFCC转回梅尔频谱 mfcc_to_mel = librosa.feature.inverse.mfcc_to_mel(mfcc, sr=sample_rate) # 梅尔频谱转线性频谱 linear_spect_mfcc = librosa.feature.inverse.mel_to_stft(mfcc_to_mel, sr=sample_rate, n_fft=n_fft) # 重构音频 y_recon_mfcc = librosa.griffinlim(linear_spect_mfcc, hop_length=hop_length, win_length=n_fft, window=window_type, n_iter=64) # 播放与保存 ipd.Audio(y_recon_mfcc, rate=sample_rate) librosa.output.write_wav('recon_mfcc.wav', y_recon_mfcc, sample_rate)
完整整合代码
将上述重构代码添加到原有代码末尾即可,运行后可直接播放或保存各重构音频,对比听感调参。
内容的提问来源于stack exchange,提问作者chaima rebah
相关产品推荐
相关产品推荐

