1. 概述
wave 模块提供了一个处理 WAV 声音格式的便利接口。它不支持压缩/解压,但是支持单声道/立体声。
用法:wave.open(file, mode=None)
,其中,mode为rb
和 wb
:
rb
:生成 wav_read 对象wb
:生成 wav_write 对象
注意不支持同时读写。
注:关于
r
、w
、rb
、wb
r
和w
是普通读和写文件(简单理解为人工编写的文件);
rb
和wb
是读写二进制文件(简单理解为可以操作图片等非手工编写的文件)
1.1 Wave_read对象
import wave
# wave.read 对象方法
wr = wave.open('/Users/robin/Desktop/WavTest.wav', 'rb')
print(wr.getnchannels()) # 返回声道数量(1 为单声道,2 为立体声)
print(wr.getsampwidth()) # 返回采样字节长度
print(wr.getframerate()) # 返回采样频率
print(wr.getnframes()) # 返回音频总的帧数
print(wr.getparams()) # 返回一个 namedtuple() (nchannels, sampwidth, framerate, nframes, comptype, compname),与 get*() 方法的输出相同。
print(wr.readframes(n))
1
2
16000
103765
_wave_params(nchannels=1, sampwidth=2, framerate=16000, nframes=103765, comptype='NONE', compname='not compressed')
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0
...
1.2 Wave_write 对象
# wave.write 对象方法
#(1)open 创建文件
ww = wave.open('/Users/robin/Desktop/WavTest.wav', 'wb')
#(2)set 设置参数
ww.setchannels(n) # 设置通道数
ww.setsampwidth(n) # 设置采样字节长度为 n
ww.setframerate(n) # 设置采样频率为 n
ww.setparams(n) # 设置所有形参,(nchannels, sampwidth, framerate, nframes, comptype, compname),每项的值应可用于 set*() 方法。
# (3) writeframes 写入数据流
ww.writeframes(data) # 写入音频帧并确保 nframes 是正确的
# (4) close 关闭
ww.close()
2. 实际使用中的问题
2.1 音频保存
1、setsampwidth
:采样字节长度 or 采样位数、量化位数
表示用多少bit表达一次采样所采集的数据,通常有8bit、16bit、24bit和32bit等几种,
需要注意的是,在设置setsampwidth
时,采用的单位是bytes
而不是bit
。比如,16 bits per sample (= 2 bytes),应该设置setsampwidth=2
而不是setsampwidth=16
,否则可能会报错:raise Error('sample width not specified')
代码示例:
channel = 1
bits = 2 # 16 bits = 2 bytes(wave模块中使用byte!!!注意除以8进行转换)
rates = 16000
# read(or resample) wav and save
def write_wav(file_name, input_data):
wavfile = wave.open(file_name, 'wb') # 创建(空)文件
wavfile.setparams((channel, bits, rates, 0, 'NONE', 'NONE'))
print("wav文件信息:", wavfile.getparams()[:4])
wavfile.writeframes(input_data) # 写入数据
wavfile.close()
3. 源代码:Lib/wave.py
"""Stuff to parse WAVE files.
Usage.
Reading WAVE files:
f = wave.open(file, 'r')
where file is either the name of a file or an open file pointer.
The open file pointer must have methods read(), seek(), and close().
When the setpos() and rewind() methods are not used, the seek()
method is not necessary.
This returns an instance of a class with the following public methods:
getnchannels() -- returns number of audio channels (1 for
mono, 2 for stereo)
getsampwidth() -- returns sample width in bytes
getframerate() -- returns sampling frequency
getnframes() -- returns number of audio frames
getcomptype() -- returns compression type ('NONE' for linear samples)
getcompname() -- returns human-readable version of
compression type ('not compressed' linear samples)
getparams() -- returns a namedtuple consisting of all of the
above in the above order
getmarkers() -- returns None (for compatibility with the
aifc module)
getmark(id) -- raises an error since the mark does not
exist (for compatibility with the aifc module)
readframes(n) -- returns at most n frames of audio
rewind() -- rewind to the beginning of the audio stream
setpos(pos) -- seek to the specified position
tell() -- return the current position
close() -- close the instance (make it unusable)
The position returned by tell() and the position given to setpos()
are compatible and have nothing to do with the actual position in the
file.
The close() method is called automatically when the class instance
is destroyed.
Writing WAVE files:
f = wave.open(file, 'w')
where file is either the name of a file or an open file pointer.
The open file pointer must have methods write(), tell(), seek(), and
close().
This returns an instance of a class with the following public methods:
setnchannels(n) -- set the number of channels
setsampwidth(n) -- set the sample width
setframerate(n) -- set the frame rate
setnframes(n) -- set the number of frames
setcomptype(type, name)
-- set the compression type and the
human-readable compression type
setparams(tuple)
-- set all parameters at once
tell() -- return current position in output file
writeframesraw(data)
-- write audio frames without patching up the
file header
writeframes(data)
-- write audio frames and patch up the file header
close() -- patch up the file header and close the
output file
You should set the parameters before the first writeframesraw or
writeframes. The total number of frames does not need to be set,
but when it is set to the correct value, the header does not have to
be patched up.
It is best to first set all parameters, perhaps possibly the
compression type, and then write audio frames using writeframesraw.
When all frames have been written, either call writeframes(b'') or
close() to patch up the sizes in the header.
The close() method is called automatically when the class instance
is destroyed.
"""
from chunk import Chunk
from collections import namedtuple
import audioop
import builtins
import struct
import sys
__all__ = ["open", "Error", "Wave_read", "Wave_write"]
class Error(Exception):
pass
WAVE_FORMAT_PCM = 0x0001
_array_fmts = None, 'b', 'h', None, 'i'
_wave_params = namedtuple('_wave_params',
'nchannels sampwidth framerate nframes comptype compname')
class Wave_read:
"""Variables used in this class:
These variables are available to the user though appropriate
methods of this class:
_file -- the open file with methods read(), close(), and seek()
set throu