Python使用soundfile与wave模块读取.wav文件得到不同字节结果如何解决
问题1:两款工具读取结果不一致的原因
两个库的默认输出逻辑完全不同,不存在读取错误的问题:
soundfile的sf.read()方法默认返回归一化到[-1.0, 1.0]区间的浮点型numpy数组,你直接将该浮点数组写入BytesIO得到的是浮点数的二进制编码,和wav文件原生存储的PCM整数编码完全无关。- 标准库
wave的readframes()方法直接读取wav文件中存储的原生PCM整数字节流,比如常见的16bit深度wav,每个采样点对应2字节的有符号短整型数值,和你拿到的soundfile浮点转字节的结果自然完全不同。
你误以为wave输出不符合预期属于用法认知偏差,wave读出来的才是wav文件的原生帧字节。
问题2:格式转换方法
如果要将soundfile输出的浮点采样数组转换为wave模块输出的原生PCM字节流,按以下步骤操作即可:
- 先获取音频的位深参数(16bit/24bit/32bit,常用为16bit),将归一化浮点数组缩放至对应整数区间
- 转换为对应类型的numpy数组后直接导出字节
16bit位深wav的示例代码如下:
import soundfile as sf import numpy as np # 读取音频,同时拿到采样率,subtype参数可以获取位深信息 samples, sr = sf.read(speech_file, dtype='float32') # 16bit PCM的数值范围是[-32768, 32767],先缩放再转int16 pcm_samples = (samples * 32767).astype(np.int16) # 得到的pcm_bytes就和wave.readframes()输出完全一致 pcm_bytes = pcm_samples.tobytes()
内容的提问来源于stack exchange,提问作者dkagramanyan
相关产品推荐
相关产品推荐

