使用 Python,我试图绘制一个 wav 文件的信号幅度,但是我收到以下错误“ValueError:x 和 y 必须具有相同的第一维”。这是我的代码:
import wave
import matplotlib.pyplot as plt
import numpy as np
wav_obj = wave.open("loop.wav", "rb")
sample_freq = wav_obj.getframerate()
n_samples = wav_obj.getnframes()
t_audio = n_samples/sample_freq
n_channels = wav_obj.getnchannels()
signal_wave = wav_obj.readframes(n_samples)
signal_array = np.frombuffer(signal_wave, dtype=np.int16)
l_channel = signal_array[0::2]
r_channel = signal_array[1::2]
times = np.linspace(0, t_audio, num=n_samples)
plt.figure(figsize=(15, 5))
plt.plot(times, l_channel)
plt.title('Left Channel')
plt.ylabel("Signal Value")
plt.xlabel("Time in seconds")
plt.xlim(0, t_audio)
plt.show
我知道我的 signal_array 的形状应该等于 (n_samples * n_channels),但事实并非如此,我也不知道为什么。现在 signal_array 的形状是 1076340,并且 (n_samples * n_channels) 是 717560.
我尝试使用不同的 wav 文件,但我得到了同样的错误。
更新: 我有更多的见解,我的 wav 文件是立体声的,所以它有 2 个通道。 “signal_array”的形状实际上是 (n_samples * 3),这是因为 wav 文件的样本宽度是 3。因此我的“l_channel”的形状实际上是 (times * 1.5)。
所以我现在的问题是,如何考虑样本宽度为 3?我应该如何处理我的数组,使它们最终等于我的“时间”数组的形状?
这实际上有点复杂,因为一个 24 位(每个样本 3 个字节)文件没有匹配的 Numpy 数据类型。
如果你想自己做,你需要做类似的事情:
>
):
data = np.frombuffer(signal_wave, dtype=np.uint8)
samples = data.reshape((n_samples * n_channels, sample_width))
padding = np.zeros((n_samples * n_channels, 1), dtype=np.uint8)
padded_samples = np.hstack((padding, samples))
int_samples = padded_samples.view('>u4').flatten()
samples_l = int_samples[::2]
有关详细信息,请参阅此笔记本。这仍然不是一个完整的解决方案,因为它不适用于有符号整数(我认为 PCM 数据已签名)。显然你可以用 as_strided 做一个技巧,但它很危险(允许访问数组外的内存)。
所以如果可以的话,使用scipy.io.wavfile.read代替.