matinal:python 读写本地音频文件

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

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

一. 文件读取
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类似。

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),才能与其他读取方式获取数据保持一致。

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。

二. 文件写入
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包等。并且以上方法没有考虑时间复杂度差异,有兴趣的同学可以自己试试。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值