前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >matinal:python 读写本地音频文件

matinal:python 读写本地音频文件

作者头像
matinal
发布2023-10-14 15:49:57
2120
发布2023-10-14 15:49:57
举报
文章被收录于专栏:SAP TechnicalSAP Technical

在语音处理中,音频文件读写是基本操作。 然而读写方式乃至归一化处理的多样化,有可能导致后续处理的偏差乃至错误。 本文汇集实践中所遇的一些方法,并参考了其他文章,确保读写操作的准确性和一致性。

前置条件        本文以实践中常见的音频文件参数(wav格式,PCM编码,单通道,采样率16KHz,位深16bit)为例,如果参数不同需做对应调整。

代码语言:javascript
复制
一. 文件读取
 1. librosa
   import librosa
   wav_path=''
   sample_rate=16000
   data = librosa.core.load(wav_path, sr=sample_rate)[0]
   print(type(data)) #<class 'numpy.ndarray'>

 返回的数组数据类型为float32,数据大小位于(-1,1)之间。该接口内部其实是调用soundfile实现,和方法2类似。

代码语言:javascript
复制
2. soundfile
   import soundfile as sf
   wav_path=''
   with sf.SoundFile(wav_path) as sf_desc:
       data = sf_dest.read(dtype=np.float32)
   print(type(data)) #<class 'numpy.ndarray'>

 或者如下方式:
  import soundfile as sf
   wav_path=''
   data = sf.read(wav_path)[0]
   print(type(data)) #<class 'numpy.ndarray'>

 3. scipy
   from scipy.io import wavfile
   wav_path=''
   data = wavfile.read(wav_path)[1]
   data = data / 32768 #2^15
   print(type(data)) #<class 'numpy.ndarray'>

 该方法需注意的是调用read后返回的数据为int,需要除以32768(2^15,由于位深16bit),才能与其他读取方式获取数据保持一致。

代码语言:javascript
复制
4. wave
   from wave
   wav_path=''
   with wave.open(wav_path, 'rb') as f:
       params = f.getparams()
       nchannels, sampwidth, framerate, nframes = params[0:4]
       strdata = f.readframes(nframes)
       data = np.fromstring(strdata, dtype=np.int16)
       data = data / 32768
       print(type(data)) #<class 'numpy.ndarray'>

 wave为python内置包,但该方法读取过程略显麻烦,同样需要除以32768。

代码语言:javascript
复制
二. 文件写入
 1. soundfile
   import soundfile as sf
   write_wav_path=''
   sf.write(write_wav_path, data, sample_rate, 'PCM_16')

 写入和读取一样简单。
2. scipy
   from scipy.io import wavfile
   write_wav_path=''
   data *= 32768
   wavefile.write(write_wav_path, sample_rate, data.astype(np.int16))

 与读取相反(除以32768,转为float32),需要将数据乘以32768,并转为int进行保存。
3. wave
   from wave
   write_wav_path=''
   nchannels=1
   sampwidth=2
   framerate=16000
   nframes=len(data)
   comptype='NONE'
   compname='not compressed'
   with wave.open(write_wav_path, 'wb') as fw:
       fw.setparams(nchannels, sampwidth, framerate, nframes, comptype, compname)
       data=(data*32768).astype(np.int16)
       fw.writeframes(data.tostring())

 该方法写入过程仍然麻烦,并同样需要乘以32768,转为int。

三. 小结        除了以上列出方法,还存在其他读写方法,例如kaldiio包等。并且以上方法没有考虑时间复杂度差异,有兴趣的同学可以自己试试。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2023-09-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档