一、 声音的读与写

以下将用到python自带的wave模块进行操作。

  • 声音文件的读取
    以下以wav文件为例。
    使用wave模块进行声音的读取操作是:wave.open(r"wav文件路径",“rb")
    ‘rb‘表示命令为只读模式。
    wav.open命令后将返回一个wave_read对象,通过调用wave_read的方法可以获取wav文件的参数。
  • wave_read对象的方法有以下几种:
    (假定已经执行以下wave.open()代码)
f=wave.open(r"wav文件路径","rb")

(1)f.getparams():获取wav文件的参数
图片1

调用此方法后,将返回六个参数,分别为wav文件的声道、采样深度、采样率、取样点数、压缩类型、压缩类型的描述。wave模块只支持非压缩的类型,后面两项参数可以省略。
另外,通过

f.getchannels()
f.getsampwidth()
f.getframerate()
f.getnframes()

四个方法可分别获得声道数、采样深度、采样率、取样点数四个参数。

(2)f.readframs(nframes):读取声音数据
图片2

nframes为必需指定的参数,指定需要读取的长度。
如上图所示,调用此方法后,将返回以字符串代表的二进制数据。
(3)np.fromstring(str_data,dtype=np.short):将二进制文件转换为可计算的数组。
图片3

str_data=f.readframs(nframes)
np.short ####问题-1
令wave_data=np.fromstring(str_data,dtype=np.short),此时wave_data是一个一维数组。
通过改变它的形状使其重新变为双声道文件:

wave_data.shape=-1,2

将其转置得:
wave_data = wave_data.T

  • 补充:
    通过取样点数和取样频率能计算出每个取样的时间,
time = np.arrange(0, nframes) * (1.0 / framerate)
  • 声音文件的写入

import wave
import numpy as np
import scipy.signal as signal

wave用来导出声音文件,numpy用来作数据处理,signal用于决定声音文件的波形。


framerate = 44100
time = 10

####在0~time范围内,生成framerate个长度为1.0/framerate的小区间,以此近似模拟声音波形。
t = np.arange(0, time, 1.0/framerate)
####以((t, 100,)为起始点,(time, 1000)为终止点,设置频率扫描为线性曲线。
wave_data = signal.chirp(t, 100, time, 1000, method='linear') * 10000
####设置数据存储方式为两个字节为一单位。
wave_data = wave_data.astype(np.short)

f = wave.open(r"文件名.wav", "wb")

f.setnchannels(1)
f.setsampwidth(2)
f.setframerate(framerate)

f.writeframes(wave_data.tostring())
f.close()

在python中,二进制数据以字符串表示,所以wave_data.tostring()即表示将wave_data转换为二进制数据。