📜  使用Python和 Matplotlib 在图形上绘制各种声音(1)

📅  最后修改于: 2023-12-03 15:36:36.504000             🧑  作者: Mango

使用Python和 Matplotlib 在图形上绘制各种声音

在音频处理领域,可视化是一种极其重要的方法。Python 提供了一个称为 Matplotlib 的画图库,它可以方便地绘制各种音频的图形。本文将介绍如何使用 Python 和 Matplotlib 绘制各种声音的图形。

前置知识

在学习本文之前,您需要掌握以下知识:

  • Python 基础语法和控制流程。
  • NumPy 数组,包括数组的形状、索引和切片。
  • Matplotlib 基础绘图功能。
加载音频数据

要可视化音频数据,我们首先需要将音频文件加载到 Python 中。这可以通过使用 Python 的 wave 模块来完成。以下是一个读取音频文件并打印其基本信息的示例代码:

import wave

wav_file = wave.open('audio.wav', 'r')

num_channels = wav_file.getnchannels()
sample_rate = wav_file.getframerate()
num_frames = wav_file.getnframes()
duration = num_frames / sample_rate

print(f'音频文件有{num_channels}个通道,采样率为{sample_rate} Hz, 共{num_frames}帧,持续时间为{duration:.2f}秒。')

wav_file.close()

其中,'audio.wav'是音频文件的名称。您需要将其替换为您要加载的音频文件的名称。

绘制波形

波形是最基本的音频可视化形式。我们可以使用 Matplotlib 绘制波形。以下是一个绘制单通道 PCM 格式音频文件波形的示例代码:

import wave
import numpy as np
import matplotlib.pyplot as plt

wav_file = wave.open('audio.wav', 'r')

num_channels = wav_file.getnchannels()
sample_rate = wav_file.getframerate()
num_frames = wav_file.getnframes()

wav_data = np.frombuffer(wav_file.readframes(num_frames), dtype=np.int16)

wav_file.close()

plt.plot(wav_data)
plt.show()

在代码中,我们首先加载音频文件,然后使用 NumPy 将音频数据转换为数组。最后,使用 Matplotlib 的 plot 函数绘制波形。

如果您的音频文件是多通道的,您需要将多个通道的数据分别绘制在同一个图形中。以下是一个绘制多通道 PCM 格式音频文件波形的示例代码:

import wave
import numpy as np
import matplotlib.pyplot as plt

wav_file = wave.open('audio.wav', 'r')

num_channels = wav_file.getnchannels()
sample_rate = wav_file.getframerate()
num_frames = wav_file.getnframes()

plt.figure(figsize=(12, 8))

for channel in range(num_channels):
    wav_data = np.frombuffer(wav_file.readframes(num_frames), dtype=np.int16)
    plt.subplot(num_channels, 1, channel + 1)
    plt.plot(wav_data)
    plt.ylabel(f'Channel {channel + 1}')
    plt.xlim(0, num_frames)
    plt.ylim(-32768, 32767)

plt.xlabel('Frame')
plt.show()

wav_file.close()

在代码中,我们首先加载音频文件,然后使用 NumPy 将音频数据转换为数组。然后,我们使用 Matplotlib 的 subplot 函数在同一个图形中绘制多个通道的波形。

绘制频谱

频谱是描述音频信号频率范围的一种形式。我们可以使用快速傅里叶变换(FFT)将音频信号转换为频谱。以下是一个绘制 PCM 格式音频文件频谱的示例代码:

import wave
import numpy as np
import matplotlib.pyplot as plt

wav_file = wave.open('audio.wav', 'r')

num_channels = wav_file.getnchannels()
sample_rate = wav_file.getframerate()
num_frames = wav_file.getnframes()

wav_data = np.frombuffer(wav_file.readframes(num_frames), dtype=np.int16)

_, _, spec = plt.specgram(wav_data, Fs=sample_rate, NFFT=1024, noverlap=900, cmap='gray_r')

plt.xlabel('Time (s)')
plt.ylabel('Frequency (Hz)')
plt.ylim(0, 8000)
plt.colorbar(spec)
plt.show()

wav_file.close()

在代码中,我们首先加载音频文件,然后使用 NumPy 将音频数据转换为数组。然后,我们使用 Matplotlib 的 specgram 函数绘制音频文件的频谱。

绘制声谱图

声谱图是声音在时间和频率上随着时间变化的可视化。我们可以使用简单的声学模型来计算声谱图。以下是一个绘制 PCM 格式音频文件声谱图的示例代码:

import wave
import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import stft

wav_file = wave.open('audio.wav', 'r')

num_channels = wav_file.getnchannels()
sample_rate = wav_file.getframerate()
num_frames = wav_file.getnframes()

wav_data = np.frombuffer(wav_file.readframes(num_frames), dtype=np.int16)

_, _, spec = stft(wav_data, fs=sample_rate, window='hamming', nperseg=512, noverlap=256)

plt.imshow(np.log10(np.abs(spec)), origin='lower', aspect='auto', cmap='gray_r')
plt.xlabel('Time (s)')
plt.ylabel('Frequency (Hz)')
plt.ylim(0, 8000)
plt.colorbar()
plt.show()

wav_file.close()

在代码中,我们首先加载音频文件,然后使用 NumPy 将音频数据转换为数组。然后,我们使用 SciPy 的 stft 函数计算音频文件的声谱图。最后,我们使用 Matplotlib 的 imshow 函数绘制声谱图。

总结

在本文中,我们介绍了如何使用 Python 和 Matplotlib 去绘制各种声音的图形。波形、频谱与声谱图是音频信号可视化中常用的三种形式。程序员可以根据自己的需求灵活运用这三种形式。同时,Matplotlib还提供了许多其他的图形绘制功能,您可以通过查看Matplotlib API了解更多绘图方法。