我能否将使用librosa生成的频谱图转换回音频?

6

我使用以下代码将一些音频文件转换为了频谱图,并将它们保存到文件中:

import os
from matplotlib import pyplot as plt
import librosa
import librosa.display
import IPython.display as ipd

audio_fpath = "./audios/"
spectrograms_path = "./spectrograms/"
audio_clips = os.listdir(audio_fpath)

def generate_spectrogram(x, sr, save_name):
    X = librosa.stft(x)
    Xdb = librosa.amplitude_to_db(abs(X))
    fig = plt.figure(figsize=(20, 20), dpi=1000, frameon=False)
    ax = fig.add_axes([0, 0, 1, 1], frameon=False)
    ax.axis('off')
    librosa.display.specshow(Xdb, sr=sr, cmap='gray', x_axis='time', y_axis='hz')
    plt.savefig(save_name, quality=100, bbox_inches=0, pad_inches=0)
    librosa.cache.clear()

for i in audio_clips:
    audio_fpath = "./audios/"
    spectrograms_path = "./spectrograms/"
    audio_length = librosa.get_duration(filename=audio_fpath + i)
    j=60
    while j < audio_length:
        x, sr = librosa.load(audio_fpath + i, offset=j-60, duration=60)
        save_name = spectrograms_path + i + str(j) + ".jpg"
        generate_spectrogram(x, sr, save_name)
        j += 60
        if j >= audio_length:
            j = audio_length
            x, sr = librosa.load(audio_fpath + i, offset=j-60, duration=60)
            save_name = spectrograms_path + i + str(j) + ".jpg"
            generate_spectrogram(x, sr, save_name)

我希望保留音频的最多细节和质量,这样以后转换回音频时就不会有太大的损失(它们每个约为80MB)。

能否将它们转换回音频文件?我该怎么做呢?

示例光谱图

我尝试使用librosa.feature.inverse.mel_to_audio,但它没有起作用,并且我认为它不适用。

现在我有1300个光谱图文件并想用它们来训练生成对抗网络,以便可以生成新的音频,但如果我以后无法听到结果,我就不想这样做。


并不是真的 - 你已经抛弃了很多信息(全部相位和一些幅度)。 - Paul R
2
@PaulR STFT通常包含大量冗余信息,可用于估计相位。虽然不完美,但如果将Griffin-Lim算法与生成式深度神经网络的进展结合起来,它可以变得非常好。 - Lukasz Tracewski
2
@LukaszTracewski:非常有趣-OP只保存了对数幅度谱,不确定是否量化?您认为这仍然有效吗? - Paul R
2
@PaulR 这是一个有效的观点,完全的反向转换是不可能的(由于在“amplitude_to_db”中应用了阈值处理和保存为有损格式(jpeg))。话虽如此,除非OP处理一些极端情况,否则这不应该是一个大问题。 OP想要“训练生成对抗网络,以便我可以生成新的音频”,这并不是精确的数学。再加上例如tensorflow/magenta,OP就可以开始了。 - Lukasz Tracewski
谢谢 - 非常有趣。 - Paul R
1个回答

11

是的,使用Griffin-Lim算法(GLA)可以恢复大部分信号并估计相位。其Python "快速"实现可在librosa中找到。以下是如何使用它:

import numpy as np
import librosa

y, sr = librosa.load(librosa.util.example_audio_file(), duration=10)
S = np.abs(librosa.stft(y))
y_inv = librosa.griffinlim(S)

这是原始信号和重构信号的样子:

reconstruction

该算法默认随机初始化相位,然后进行正向和反向STFT操作来估计相位。

根据你的代码,要重构信号,你只需要执行以下操作:

import numpy as np

X_inv = librosa.griffinlim(np.abs(X))

当然,这只是一个示例。正如@PaulR所指出的那样,在您的情况下,您需要从jpeg(它是有损的!)加载数据,然后首先应用反转换到amplitude_to_db

算法,特别是相位估计,可以通过人工神经网络技术的进步进一步改进。 这里是一篇论文,讨论了一些改进。


1
@RamonGriffo 祝你好运!将质量设置为100通常不会给您无损压缩,有关详细信息,请参见此答案 https://dev59.com/uGsz5IYBdhLWcg3wTmCr 如果您可以承受空间,请使用无损格式。我经常选择HDF5,可选高压缩。如果这回答了您的问题,请接受答案 - 谢谢! - Lukasz Tracewski
1
你找到了如何将jpg图像加载/转换为频谱图吗?我认为这个答案并没有完全回答那个部分。 - materialvision
1
@materialvision 这是因为没有明确的方法来做到这一点。你怎么能确定图像中的颜色比例如何转化为振幅呢?至少对于灰度图像,你知道相对差异,因此恢复信号并不是一个大问题。 - Lukasz Tracewski
1
@LukaszTracewski 谢谢,如果您能提供如何使用灰度图像完成此操作的提示也将不胜感激。 我可以在 mel 对象上执行 griffinlim,但不能直接在 mel 图像上执行... 因此我正在寻找一种反向处理的方法。 首先生成声谱图的图像,训练模型(使用不同的现有基于图像的 GANSs),并生成结果图像,然后将新图像转换回声音。 最后一个部分是问题所在。 - materialvision
1
这适用于频谱图像吗?如果我有一张图片,将其作为输入传递并从中获取音频。你能分享相同的代码片段吗? - Hitesh Kumar
显示剩余2条评论

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