使用Python读写WAV文件

2025年1月5日 | 阅读6分钟

音频处理在许多应用中都至关重要,从音乐创作和广播到语音识别和音频分析。WAV (Waveform Sound Document Organization) 文件因其未压缩和高质量音频而成为存储音频数据的流行选择。这使得它们非常适合各种对质量要求很高的音频处理任务。

WAV (Waveform Audio File Format) 是计算机上存储音频的标准。它是一种未压缩格式,意味着它保留了最高质量,但需要更多存储空间。WAV 文件存储音频数据以及有关文件参数的信息,例如通道数、采样宽度和采样率。

Python 凭借其丰富的库和工具生态系统,为音频处理提供了出色的支持。其中一个工具是 `wave` 模块,它是 Python 标准库的一部分,允许读取和写入 WAV 文件。该模块对于基本的音频处理任务特别有用,是任何音频编程新手的一个很好的起点。

Python 的 `wave` 模块

Python 的 `wave` 模块提供了一个简单的接口来读取和写入 WAV 文件。它允许您通过简单的函数来操作 WAV 文件的参数和数据。让我们开始了解如何使用此模块读取和写入 WAV 文件。

处理 WAV 文件原理

理解 WAV 文件的结构以及如何操作它们对于有效的音频处理至关重要。下面,我们将介绍处理 WAV 文件的基本原理,包括文件结构、基本操作以及音频数据处理的细节。

WAV 文件结构

WAV 文件基于 RIFF (Resource Interchange File Format) 格式,并由块组成。WAV 文件中的主要块是:

RIFF Header:此头指定文件是 RIFF 文件,并包含 WAVE 格式的音频数据。

fmt Chunk:此块包含有关音频格式的信息,包括通道数、采样率、字节率、块对齐和每采样位数。

data Chunk:此块包含实际的音频数据,表示为字节序列。

WAV 文件属性

了解 WAV 文件的属性对于处理音频至关重要。关键属性包括:

通道数:决定音频是单声道(1 个通道)还是立体声(2 个通道)。

采样宽度:表示用于表示每个样本的字节数(例如,8 位音频为 1 字节,16 位音频为 2 字节)。

采样率(帧率):每秒的音频样本数,以赫兹 (Hz) 为单位。

帧数:文件中音频帧的总数。

压缩类型:WAV 文件通常是未压缩的,因此此项通常为“NONE”。

基本操作

Python 的 `wave` 模块提供了执行 WAV 文件基本操作的函数。这些包括:

打开 WAV 文件:使用 `wave.open(filename, mode)` 以读取 ('rb') 或写入 ('wb') 模式打开 WAV 文件。

提取属性:使用 `getnchannels()`、`getsampwidth()`、`getframerate()` 和 `getnframes()` 等函数来检索文件属性。

读取帧:使用 `readframes(n)` 读取指定数量的帧。

写入帧:使用 `writeframes(data)` 将音频数据写入文件。

处理音频数据

WAV 文件中的音频数据通常表示为字节序列。每个样本都根据采样宽度进行编码:

8 位样本:由无符号整数表示(0 到 255)。

16 位样本:由带符号整数表示(-32768 到 32767)。

32 位样本:由带符号整数表示(-2147483648 到 2147483647)。

对于多通道音频(例如立体声),每个通道的样本是交错的。这意味着对于立体声文件,左右通道的数据在字节序列中交替出现。

读取 WAV 文件

读取 WAV 文件时,您需要打开它、提取其属性并读取音频帧。以下是执行此操作的指南:

示例

输出

Channels: 2
Sample Width: 2 bytes
Frame Rate (Sample Rate): 44100 frames per second
Number of Frames: 2646000
Compression Type: NONE
Compression Name: not compressed

说明

打开文件

`wave.open('example.wav', 'rb')`: 以读取模式打开 WAV 文件('rb' 表示“读取二进制”)。

提取属性

`getnchannels()`:返回音频通道数(例如,单声道为 1,立体声为 2)。

`getsampwidth()`:返回以字节为单位的采样宽度。

`getframerate()`:返回采样率(每秒帧数)。

`getnframes()`:返回音频帧数。

`getcomptype()` 和 `getcompname()`:返回压缩类型和名称(WAV 文件通常是未压缩的)。

读取帧

`readframes(n_frames)`:从文件中读取指定数量的帧。

写入 WAV 文件

要写入 WAV 文件,您需要创建一个新文件,设置其参数,然后写入音频帧。以下是一个示例:

示例

输出

WAV file written successfully.

说明

设置参数

`n_channels`:音频通道数。

`sampwidth`:以字节为单位的采样宽度。

`framerate`:采样率(每秒帧数)。

`n_frames`:音频帧数。

生成帧

`frames = b'\x00\x00' * n_frames * n_channels`:为演示目的创建虚拟音频帧。每个帧由一对字节 (`\x00\x00`) 表示,乘以帧数和通道数。

写入帧

`wave.open('output.wav', 'wb')`: 以写入模式打开新 WAV 文件('wb' 表示“写入二进制”)。

`setnchannels(n_channels)`、`setsampwidth(sampwidth)`、`setframerate(framerate)`、`setnframes(n_frames)`:设置文件的参数。

`writeframes(frames)`:将音频帧写入文件。

高级主题

处理音频数据

WAV 文件中的音频数据通常表示为字节。每个样本都是一个字节序列,对于多通道音频,每个通道的样本是交错的。理解这种结构对于更高级的音频处理至关重要。

示例:读取和修改音频数据

让我们读取一个立体声 WAV 文件,修改音频数据(例如,对一个通道应用简单的增益),然后将修改后的数据保存到另一个文件中。

示例

说明

读取原始 WAV 文件

  • 打开 WAV 文件并读取其参数和帧。

应用增益

  • 解包帧:使用 `struct` 模块将字节帧转换为单个样本。格式字符串取决于采样宽度。
  • 修改样本:对第一个通道的样本应用增益。确保修改后的样本保持在有效范围内。
  • 打包帧:将修改后的样本转换回字节。

写入修改后的 WAV 文件

  • 创建一个新的 WAV 文件并设置其参数。
  • 将修改后的帧写入新文件。