树莓派用Python读取WAV文件遇OverflowError 部分文件可正常读取
解决树莓派上scipy读取WAV文件的OverflowError问题
我之前在树莓派上踩过一模一样的坑!这个OverflowError: cannot fit int into an index-sized integer报错,大多和树莓派的32位系统限制、scipy版本兼容性,或者WAV文件本身的非标准格式有关,下面给你几个实测有效的解决办法:
一、先排查核心原因
- 树莓派默认是32位操作系统,旧版本的scipy在处理较大的WAV文件(或者24位采样深度的文件)时,会把读取数据的索引值当成32位整数,一旦文件数据量超出32位int的范围(也就是超过2^31-1个采样点),就会触发溢出错误。
- 部分WAV文件采用了非标准的PCM格式(比如24位采样深度),scipy旧版的
wavfile.read对这类格式的支持有bug。
二、解决方案
1. 升级scipy到最新版本
这是最直接的办法,新版本的scipy已经修复了32位系统下的索引溢出问题,对非标准WAV的兼容性也提升了不少。在树莓派终端执行:
pip install --upgrade scipy
升级完成后再试试你的代码,大概率能解决问题。
2. 手动用wave+numpy读取(兼容特殊格式)
如果升级scipy后还是不行,那可能是你的WAV是24位这类特殊格式,咱们可以用Python标准库的wave模块配合numpy手动读取,避开scipy的bug:
import wave import numpy as np def read_wav(file_path): with wave.open(file_path, 'rb') as wf: fs = wf.getframerate() num_channels = wf.getnchannels() sample_width = wf.getsampwidth() num_frames = wf.getnframes() # 读取原始字节数据 raw_data = wf.readframes(num_frames) # 根据采样宽度转换为对应的数据类型 if sample_width == 1: dtype = np.uint8 data = np.frombuffer(raw_data, dtype=dtype) elif sample_width == 2: dtype = np.int16 data = np.frombuffer(raw_data, dtype=dtype) elif sample_width == 3: # 处理24位深度的WAV文件 dtype = np.int32 # 按字节拆分后组合成24位整数 byte_data = np.frombuffer(raw_data, dtype=np.uint8) byte_data = np.reshape(byte_data, (-1, 3)) data = byte_data[:, 0] | (byte_data[:, 1] << 8) | (byte_data[:, 2] << 16) # 处理有符号整数的符号位 data = np.where(data >= 2**23, data - 2**24, data) else: # 32位及以上深度 dtype = np.int32 data = np.frombuffer(raw_data, dtype=dtype) # 多通道数据重塑为二维数组 if num_channels > 1: data = np.reshape(data, (-1, num_channels)) return fs, data # 调用示例 fs, data = read_wav('/home/pi/chimp.wav')
3. 转换WAV为标准格式
如果上面的方法都不想用,还可以直接把有问题的WAV转换成scipy支持的标准格式(比如16位PCM)。用ffmpeg工具就行,先安装(如果没装的话):
sudo apt install ffmpeg
然后执行转换命令:
ffmpeg -i /home/pi/chimp.wav -acodec pcm_s16le /home/pi/chimp_16bit.wav
转换后的chimp_16bit.wav应该能被你的原代码正常读取。
内容的提问来源于stack exchange,提问作者nanriat
相关产品推荐
相关产品推荐

