音频到频谱图图像并返回音频

问题描述 投票:0回答:1

我能够将 wav 文件转换为频谱图,然后以可接受的质量水平再次转换回来。我可以绘制该频谱图并将其保存为 jpg 文件,但我已经能够导入 jpg 并将其转换回音频。

我可以将音频转换为分贝缩放频谱图

import librosa
x, sr = librosa.load(librosa.ex('trumpet'))
X = librosa.stft(x)
Xdb = librosa.amplitude_to_db(abs(X))

我能够将分贝缩放频谱图转换回音频

X2 = librosa.db_to_amplitude(Xdb)
audio = librosa.griffinlim(X2)
import soundfile as sf
sf.write("test1.wav", audio, sr)

我可以将数组保存为 32 位 Tiff,并从该 tiff 文件重新创建音频。

from PIL import Image
import numpy as np

im =Image.fromarray(Xdb).convert('F')
im.save("test.tiff")
img = Image.open("test.tiff")
recspec = np.array(img)

X2 = librosa.db_to_amplitude(recspec)
audio = librosa.griffinlim(X2)
import soundfile as sf
sf.write("test1.wav", audio, sr)

我可以绘制 db 缩放频谱图并将其另存为 jpg

from matplotlib import pyplot as plt
import librosa.display
fig = plt.figure(figsize=(10, 10), 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("test.jpg", bbox_inches=0, pad_inches=0)

但我完全无法弄清楚如何重新导入 jpg 以便从中重新创建音频。我意识到这并不像以与 tiff 相同的方式导入 jpg 并将其保存为像 jpg 这样的有损格式那么简单,这会导致质量的显着损失,但如果生成的音频我会同意至少有点类似于其中的内容。我研究过代码来执行类似的操作,但他们的方法要复杂得多,例如使用颜色通道来编码相位等,我对 griffinlim 重建的质量很满意,所以很高兴跳过那个。如果有人能指出我正确的方向,那就太好了。

python jpeg librosa spectrogram
1个回答
0
投票

正如您所提到的,使用 Griffin-Lim 从幅度谱图中查找波形在保真度方面会存在一些限制。但如果您对这种情况下的结果感到满意,那么问题就特定于 JPEG 编码(或解码)。

首先,你保存JPEG的方式是错误的。您不应该绘制这些值。而是使用 img. 保存频谱图值数组。与处理 TIFF 的方式相同。

将幅度谱图编码为 JPEG 时存在两个关键挑战:

  1. 精度有限。 JPEG 仅支持 8 位整数
  2. 压缩伪影。 JPEG 使用专为视觉设计的有损压缩

关于2) - 在开始时关闭所有压缩。您可以稍后尝试重新引入它,但首先让简单的案例起作用。

关于 1. 您必须确保您的频谱图值在 0-255 范围内。一个好的起点是对频谱图进行分贝缩放(例如使用 librosa.power_to_db()),然后在获得的值和 0-255 之间使用线性映射。稍后解码频谱图的关键是了解这些值,以便您可以反转该过程。这可以通过固定/硬编码缩放值来完成,但找到适用于所有音频/频谱图输入的值可能很棘手。或者,您可以使用自定义 EXIF 标记将缩放因子存储为 JPEG 中的元数据。

© www.soinside.com 2019 - 2024. All rights reserved.