22.4. "wave" --- 读写WAV格式文件
********************************

**源代码:** Lib/wave.py

======================================================================

"wave" 模块提供了一个处理 WAV 声音格式的便利接口。它不支持压缩/解压，
但是支持单声道/立体声。

"wave" 模块定义了以下函数和异常:

wave.open(file, mode=None)

   如果 *file* 是一个字符串，打开对应文件名的文件。否则就把它作为文件
   类对象来处理。*mode* 可以为以下值：

   "'rb'"
      只读模式。

   "'wb'"
      只写模式。

   注意不支持同时读写WAV文件。

   *mode* 设为 "'rb'" 时返回一个 "Wave_read" 对象，而 *mode* 设为
   "'wb'" 时返回一个 "Wave_write" 对象。如果省略 *mode* 并指定 *file*
   来传入一个文件类对象，则 "file.mode" 会被用作 *mode* 的默认值。

   如果操作的是文件对象，当使用 wave 对象的 "close()" 方法时，并不会真
   正关闭文件对象，这需要调用者负责来关闭文件对象。

   The "open()" function may be used in a "with" statement.  When the
   "with" block completes, the "Wave_read.close()" or
   "Wave_write.close()" method is called.

   在 3.4 版更改: 添加了对不可搜索文件的支持。

wave.openfp(file, mode)

   同 "open()"，用于向后兼容。

exception wave.Error

   当不符合WAV格式或无法操作时引发的错误。


22.4.1. Wave_read对象
=====================

由 "open()" 返回的 Wave_read 对象，有以下几种方法:

Wave_read.close()

   关闭 "wave" 打开的数据流并使对象不可用。当对象销毁时会自动调用。

Wave_read.getnchannels()

   返回声道数量（"1" 为单声道，"2" 为立体声）

Wave_read.getsampwidth()

   返回采样字节长度。

Wave_read.getframerate()

   返回采样频率。

Wave_read.getnframes()

   返回音频总帧数。

Wave_read.getcomptype()

   返回压缩类型（只支持 "'NONE'" 类型）

Wave_read.getcompname()

   "getcomptype()" 的通俗版本。使用 "'not compressed'" 代替 "'NONE'"。

Wave_read.getparams()

   返回一个 "namedtuple()" "(nchannels, sampwidth, framerate, nframes,
   comptype, compname)"，与 "get*()" 方法的输出相同。

Wave_read.readframes(n)

   读取并返回以 "bytes" 对象表示的最多 *n* 帧音频。

Wave_read.rewind()

   重置文件指针至音频开头.

后面两个方法是为了和 "aifc" 保持兼容，实际不做任何事情。

Wave_read.getmarkers()

   返回 "None"。

Wave_read.getmark(id)

   引发错误异常。

以下两个方法都使用指针，具体实现由其底层决定。

Wave_read.setpos(pos)

   设置文件指针到指定位置。

Wave_read.tell()

   返回当前文件指针位置。


22.4.2. Wave_write 对象
=======================

对于可查找的输出流，"wave" 头将自动更新以反映实际写入的帧数。 对于不可
查找的流，当写入第一帧时 *nframes* 值必须准确。 获取准确的 *nframes*
值可以通过调用 "setnframes()" 或 "setparams()" 并附带 "close()" 被调用
之前将要写入的帧数，然后使用 "writeframesraw()" 来写入帧数据，或者通过
调用 "writeframes()" 并附带所有要写入的帧。 在后一种情况下
"writeframes()" 将计算数据中的帧数并在写入帧数据之前相应地设置
*nframes*。

由 "open()" 返回的 Wave_write 对象，有以下几种方法:

在 3.4 版更改: 添加了对不可搜索文件的支持。

Wave_write.close()

   确保 *nframes* 是正确的，并在文件被 "wave" 打开时关闭它。 此方法会
   在对象收集时被调用。 如果输出流不可查找且 *nframes* 与实际写入的帧
   数不匹配时引发异常。

Wave_write.setnchannels(n)

   设置声道数。

Wave_write.setsampwidth(n)

   设置采样字节长度为 *n*。

Wave_write.setframerate(n)

   设置采样频率为 *n*。

   在 3.2 版更改: 对此方法的非整数输入会被舍入到最接近的整数。

Wave_write.setnframes(n)

   设置总帧数为 *n*。 如果与之后实际写入的帧数不一致此值将会被更改（
   如果输出流不可查找则此更改尝试将引发错误）。

Wave_write.setcomptype(type, name)

   设置压缩格式。目前只支持 "NONE" 即无压缩格式。

Wave_write.setparams(tuple)

   *tuple* 应该是 "(nchannels, sampwidth, framerate, nframes,
   comptype, compname)"，每项的值应可用于 "set*()" 方法。设置所有形参
   。

Wave_write.tell()

   返回当前文件指针，其指针含义和 "Wave_read.tell()" 以及
   "Wave_read.setpos()" 是一致的。

Wave_write.writeframesraw(data)

   写入音频数据但不更新 *nframes*。

   在 3.4 版更改: 现在可接受任意 *bytes-like object*。

Wave_write.writeframes(data)

   写入音频帧并确保 *nframes* 是正确的。 如果输出流不可查找且在 *data*
   被写入之后写入的总帧数与之前设定的has been written does not match
   the previously set value for *nframes* 值不匹配将会引发错误。

   在 3.4 版更改: 现在可接受任意 *bytes-like object*。

注意在调用 "writeframes()" 或 "writeframesraw()" 之后再设置任何格式参
数是无效的，而且任何这样的尝试将引发 "wave.Error"。
