该文主要记录一下常用的python读取wav文件的常用三方库以及优缺点对比,以一段采样率16k,4.99秒单声道的测试语音为例子,音频文件读取后主要有以下几种形式
#格式一:列表 [-0.00015259 -0.00021362 -0.00021362 -0.00027466 -0.00015259] float32
#格式二:列表 [-5, -7, -7, -9, -5] int16
#格式三:字节流 b'\xfb\xff\xf9\xff\xf9' pcm编码格式
#格式四:字节流带文件头 b'RIFF\xb2\xbb\x00\x00WAVEfmt \x12\x00\x0 pcm编码格式
#格式五:字符串 'UklGRhIdAwBXQVZFZm10IBIAAAADAA' 通常是base64编码后的信息
下面介绍6种python读取语音文件的方法;
1、librosa
缺点是需要提前知道语音采样率,mono默认是True,双轨录音需注意改为False
import librosa
filepath='./zh.wav'
wav_list,sr=librosa.load(filepath,sr=16000,mono=False)
print (wav_list[:5])
#[-0.00015259 -0.00021362 -0.00021362 -0.00027466 -0.00015259]
2、soundfile
无需知道采样率,采样率是返回值
import soundfile
wav_list, sr = soundfile.read(filepath,dtype='float32')
print ("sr:"+str(sr))
print (wav_list[:5])
#[-0.00015259 -0.00021362 -0.00021362 -0.00027466 -0.00015259]
wav_list2, sr = soundfile.read(filepath,dtype='int16')
print ("sr:"+str(sr))
wav_list=wav_list2/2**15
print (wav_list[:5])
#[-0.00015259 -0.00021362 -0.00021362 -0.00027466 -0.00015259]
#文件回写
soundfile.write('zh1.wav', wav_list, 16000, subtype='PCM_16')
3、wave
该方法能返回最多语音相关信息
import wave
import numpy as np
fp = wave.open(filepath, 'rb')
byte_data = fp.readframes(fp.getnframes()) #无文件头
params = fp.getparams()
nchannels, sampwidth, sr, nframes = params[:4]
print ("音轨数:" +str(nchannels))
print ("位宽:"+str(sampwidth))
print ("采样率:"+str(sr))
print (nframes)
print ("采样点数:"+str(len(byte_data)))
wav_list= np.frombuffer(byte_data, dtype=np.int16).astype(np.float32) / 2**15 #字节流转list
print (byte_data[:5])
print (wav_list[:5])
#音轨:1
#位宽:2
#采样率:16000
#79949
#采样点数:159898
#b'\xfb\xff\xf9\xff\xf9'
#[-0.00015259 -0.00021362 -0.00021362 -0.00027466 -0.00015259]
with wave.open('zh2.wav', 'wb') as wf:
wf.setnchannels(1)
wf.setsampwidth(2)
wf.setframerate(16000)
wf.writeframes(byte_file)
4、open
该方法缺点是需要先读取成byte数据然后剔除文件头,再转换成语音list
f=open(filepath,'rb')
print ("文件头内容:"+str(f.read()[:20])) #包含文件头的bytes数据
f = open(filepath, "rb")
data = np.fromfile(f, dtype=np.int16) #包含文件头信息
wav_list=data[22:] #剔除文件头信息
wav_list=wav_list/2**15
print (wav_list[:5])
#文件头内容:b'RIFF\xbep\x02\x00WAVEfmt \x10\x00\x00\x00'
#[-0.00015259 -0.00021362 -0.00021362 -0.00027466 -0.00015259]
#如若已知文件头信息,可使用以下函数复原
import io
def audiobytes_header(audio_bytes, sample_rate=16000, fileheader=False):
'''增加文件头方法'''
if fileheader:
val = audio_bytes
else:
fp = io.BytesIO()
with wave.open(fp, mode='wb') as waveobj:
waveobj.setnchannels(1)
waveobj.setframerate(sample_rate)
waveobj.setsampwidth(2)
waveobj.setcomptype('NONE','NONE')
waveobj.writeframes(audio_bytes)
val = fp.getvalue()
return val
#base64的编码与解码
import base64
f=open(filepath,'rb')
input_bytes=f.read()
base64_bytes = base64.b64encode(input_bytes)
audio = base64_bytes.decode('utf-8')
#input_bytes 包含文件头
#audio utf-8编码的base64加密后的字节流信息
base64_bytes=audio.encode('utf-8') #解码
byte_file = base64.b64decode(base64_bytes) #解密
wav_list=np.frombuffer(byte_file[44:], dtype=np.int16).astype(np.float32) / 2**15 #头44为文件头,需剔除
print (wav_list[:5])
5 、scipy
import scipy.io.wavfile as wavfile
sr, data = wavfile.read(filepath)
wav_list=data/2**15
print ("采样率为:"+str(sr))
print (wav_list[:5])
#采样率为:16000
#[-0.00015259 -0.00021362 -0.00021362 -0.00027466 -0.00015259]
#文件回写
audio_array = np.array(data, dtype=np.int16)
wavfile.write('output.wav', sample_rate, audio_array)
6、pydub
from pydub import AudioSegment
audio = AudioSegment.from_file(filepath)
sr = audio.frame_rate
data = audio.get_array_of_samples()
wav_list = [i/2**15 for i in list(data)]
print ("采样率:"+str(sr))
print (wav_list[:5])
#采样率为:16000
#[-0.00015259 -0.00021362 -0.00021362 -0.00027466 -0.00015259]
# 创建AudioSegment对象
audio_segment = AudioSegment(
data=bytes(audio_data),
sample_width=sample_width,
frame_rate=sample_rate,
channels=num_channels
)
# 将音频数据写入文件
audio_segment.export('output.wav', format='wav')
标签:读取,python,sr,list,六种,0.00015259,print,wav,0.00021362
From: https://www.cnblogs.com/jax-/p/17652558.html