Python处理WAV文件遇struct.error错误,求不改绘图逻辑的修复方案
修复struct.error问题的方案
错误原因
你碰到的struct.error: unpack requires a buffer of 48000 bytes问题根源有两个:
struct.unpack('{n}h'.format(n=48000), data)里的h对应2字节的int16类型,这要求原始data的字节数必须是48000×2=96000字节,但你的音频文件实际数据量可能达不到这么多- 更关键的是,你前面已经用numpy把原始data解析成了处理好的
ys数组(已经搞定了声道拆分、采样宽度适配),后面完全没必要再用struct重复解析原始data
修复后的代码
直接复用前面处理好的ys数组,既保留你原有的处理逻辑,又彻底解决struct的错误:
import wave import struct import matplotlib.pyplot as plt import numpy as np infile = "trumpet.wav" wav_file = wave.open(infile, "r") nchannels = wav_file.getnchannels() nframes = wav_file.getnframes() sampwidth = wav_file.getsampwidth() data = wav_file.readframes(nframes) wav_file.close() dtype_map = {1: np.int8, 2: np.int16, 3: "special", 4: np.int32} if sampwidth not in dtype_map: raise ValueError("sampwidth %d unknown" % sampwidth) if sampwidth == 3: xs = np.fromstring(data, dtype=np.int8).astype(np.int32) ys = (xs[2::3] * 256 + xs[1::3]) * 256 + xs[0::3] else: ys = np.frombuffer(data, dtype=dtype_map[sampwidth]) # if it's in stereo, just pull out the first channel if nchannels == 2: ys = ys[::2] # plot full signal num_samples = 48000 # 直接用处理好的ys,取前num_samples个样本(实际样本数不够时就取全部) data = ys[:num_samples] plt.subplot(1,1,1) plt.plot(data[:300]) plt.title('Entire signal') plt.show()
修改说明
- 删掉了
struct.unpack的冗余步骤,直接使用已经处理好的ys数组,它已经是格式正确的音频样本数组 - 用
ys[:num_samples]获取最多48000个样本,避免了因实际音频长度不足导致的索引越界或字节数不匹配问题 - 绘图部分完全保留你原来的逻辑,只是数据源换成了正确处理后的样本
内容的提问来源于stack exchange,提问作者thiccdan69
相关产品推荐
相关产品推荐

