如何使用Python将scipy.signal.spectrogram反转为音频?

4

我有:

import librosa
from scipy import signal 
import scipy.io.wavfile as sf    

samples, sample_rate = sf.read(args.file)
nperseg = int(sample_rate * 0.001 * 20)
frequencies, times, spectrogram = signal.spectrogram(samples, 
                                                     sample_rate, 
                                                     nperseg=nperseg, 
                                                     window=signal.hann(nperseg))

audio_signal = librosa.griffinlim(spectrogram)
print(audio_signal, audio_signal.shape)

sf.write('test.wav', audio_signal, sample_rate)

然而,这会产生一个(几乎)空的音频文件。

要使用Griffin Lim,您需要一个幅度谱图。我建议在signal.spectrogram(... mode='magnitude')调用中指定模式。尚未测试。 - Hendrik
不行。结果相同。 - Shamoon
1
我无法评论librosa库。假设这不是问题,您是否尝试过使用scipy.io库来读写音频文件?scipy.io.wavfile.read和scipy.io.wavfile.write。请注意,顺序从信号、信号速率变为信号速率、信号。(https://docs.scipy.org/doc/scipy/reference/io.html#module-scipy.io.wavfile) - DrSpill
我正在使用 soundfile - Shamoon
2个回答

7

就像@DrSpill提到的那样,scipy.io.wav.readscipy.io.wav.write的顺序是错误的,而且从librosa导入也不正确。应该这样做:

import librosa
import numpy as np
import scipy.signal
import scipy.io.wavfile

# read file
file    = "temp/processed_file.wav"
fs, sig = scipy.io.wavfile.read(file)
nperseg = int(fs * 0.001 * 20)

# process
frequencies, times, spectrogram = scipy.signal.spectrogram(sig, 
                                                           fs, 
                                                           nperseg=nperseg, 
                                                           window=scipy.signal.hann(nperseg))
audio_signal = librosa.core.spectrum.griffinlim(spectrogram)
print(audio_signal, audio_signal.shape)

# write output
scipy.io.wavfile.write('test.wav', fs, np.array(audio_signal, dtype=np.int16))

注意: 当我听到生成的文件时,发现节奏加快了,我认为这是由于你的处理方式,但只需进行一些微调即可解决。

一个好的替代方案是只使用librosa,方法如下:

import librosa
import numpy as np

# read file
file    = "temp/processed_file.wav"
sig, fs = librosa.core.load(file, sr=8000)

# process
abs_spectrogram = np.abs(librosa.core.spectrum.stft(sig))
audio_signal = librosa.core.spectrum.griffinlim(abs_spectrogram)

print(audio_signal, audio_signal.shape)

# write output
librosa.output.write_wav('test2.wav', audio_signal, fs)
 

重建的文件是否具有相同数量的样本? - Shamoon
抱歉回复晚了,我刚刚进行了进一步测试。在第二个解决方案中,应该指定输入采样率(我相应地编辑了代码)。使用 ffmpeg 我验证了输入和输出信号具有相同的采样率。但是,在使用第二个解决方案时,您应该注意比特率和编码。欲了解更多信息,请参阅 librosa 文档 - SuperKogito

2
"librosa.output已被删除。它不再提供其已弃用的输出模块。请改用soundfile.write:"
import numpy as np
import soundfile as sf
sf.write('stereo_file.wav', np.random.randn(10, 2), 44100, 'PCM_24')

#Per your code you could try:
sf.write('test.wav', audio_signal, sample_rate, 'PCM_24')

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接