这是笔记,不定时更新
1、wav文件是基于windows平台的音频资源文件,符合RIFF(Resource Interchange File Format)文件规范,标准化的wav文件44.1k采样率,16位数字表示
2、wav文件分为两给部分,第一个部分是wav头文件,第二给部分是PCM编码的音频数据部分;
3、PCM编码:数字信号是对连续变化的模拟信号进行抽样、量化和编码产生的,称为PCM(Pulse-code modulation),即脉冲编码调制;
4、wav头文件:
RIFF文件由一个简单表头(header)跟随多个“chunks”组成。
wav文件一般由3给区块组成:RIFF chunk、Format chunk、Data chunk和可选区块:Fact chunk、Cue points chunk、Playlist chunk、 Associated data list chunk等
名称 | 偏移地址 | 字节数 | 端序 | 内容 |
---|---|---|---|---|
ID | 0x00 | 4Byte | 大端 | ‘RIFF’(0x52494646) |
Size | 0x04 | 4Byte | 小端 | fileSize-8 |
Type | 0x08 | 4Byte | 大端 | ‘WAVE’(0x57415645) |
名称 | 偏移地址 | 字节数 | 端序 | 内容 |
---|---|---|---|---|
ID | 0x00 | 4Byte | 大端 | ‘fmt’(0x666D7420) |
Size | 0x04 | 4Byte | 小端 | 16 |
AudioFormat | 0x08 | 2Byte | 小端 | 音频格式 |
Numchannels | 0x0A | 2Byte | 小端 | 声道数 |
SampleRate | 0x0C | 4Byte | 小端 | 采样率 |
ByteRate | 0x10 | 4Byte | 小端 | 每秒数据字节数 |
BlockAlign | 0x14 | 2Byte | 小端 | 数据块对齐 |
BitsPerSample | 0x16 | 2Byte | 小端 | 采样位数 |
名称 | 偏移地址 | 字节数 | 端序 | 内容 |
---|---|---|---|---|
ID | 0x00 | 4Byte | 大端 | ‘data’(0x64617461) |
Size | 0x04 | 4Byte | 小端 | N |
Data | 0x08 | NByte | 小端 | 音频数据 |
wav文件以小端形式来进行数据存储
大端:数据低位保存在内存的高位地址中,而数据高位保存在内存的低位地址中
小端:数据高位保存在内存的低位地址中,而数据高位保存在内存的低位地址中
PCM数据在wav文件中的bit位排列方式
PCM数据类型 | 采样 | 采样 |
---|---|---|
8Bit单声道 | 声道0 | 声道0 |
8Bit双声道 | 声道0 | 声道1 |
16Bit单声道 | 声道0低位,声道0高位 | 声道0低位,声道0高位 |
16Bit双声道 | 声道0低位,声道0高位 | 声道1低位,声道1高位 |
import wave
import os
filePath='xxx.wav'
f=wave.open(filePath,"rb")
params=f.getparams()
nchannels,sampwidth,framerate,nframes,comptype,compname=params
print("nchannels:",nchannels)#通道数
print("sampwidth:",sampwidth)#采样字节长度
print("framerate:",framerate)#采样频率
print("nframes",nframes)#总帧数(数据总长)
print("comptype",comptype)#压缩类型 NONE为AIFF-C
print("compname",compname)#可读的压缩类型
#读取波形数据,返回为bytes对象的n帧
strData=f.readframes(nframes)
f.close()
#波形数据转数组
waveData=np.fromstring(strData,dtype=np.int16)#数据的类型要和sampwidth一致
...数据生成waveDataBytes
waveFile=wave.open(r'xxx.wav','wb')
waveFile.setparams((1,2,10000,wavelen,'NONE','Tsinghua'))
waveFile.writeframes(waveDataBytes)
waveFile.close()