音频录制及可视化处理
1.导入数据库
import pyaudio
import wave
import librosa
import librosa.display
import matplotlib.pyplot as plt
import numpy as np
from IPython.display import Audio # IPython提供了播放音频的工具
librosa数据库功能介绍:
librosa 是一个用于音乐和音频分析的Python库,它是开源的,并且专门设计用于处理音频信号。librosa 提供了一系列用于音频和音乐处理的功能,包括但不限于:
详细查看
[1] 读取和写入音频文件:支持多种音频文件格式,如WAV、MP3、FLAC等。
[2] 特征提取:能够计算音频信号的各种特征,如梅尔频率倒谱系数(MFCCs)、光谱对比度、音高检测等。
[3] 时频分析:提供短时傅里叶变换(STFT)等时频分析工具。
[4] 音频处理:包括滤波、重采样、节拍检测等。
[5] 音频合成:可以从特征或频谱中重建音频信号。
[6] 音乐信息检索:如音乐流派分类、音乐情绪识别等。
[7]音频可视化:提供了多种音频和音乐数据的可视化工具。
librosa.display模块功能介绍:
librosa.display 是 librosa 库中的一个模块,它提供了一系列用于可视化音频和音乐数据的函数和工具。这些工具可以帮助用户更直观地理解音频信号的特性和分析结果。使用 librosa.display 进行可视化时,通常需要先通过 librosa 计算音频的特征,然后使用 librosa.display 函数将这些特征绘制成图形。以下是一些librosa.display 模块中常用的功能:
详细查看
[1] waveshow():绘制音频信号的波形图
>> librosa.display.waveshow(y, sr=sr)
[2] specshow():显示频谱图,通常用于展示音频的频率内容,如梅尔频谱图
>> librosa.display.specshow(data, x_axis='time', y_axis='mel', fmax=None, x_max=None, sr=sr),其中 data 可以是功率谱、梅尔频谱等
[3] chroma() 或 chroma_cqt():绘制色谱图,展示音频的色度特征
>> librosa.display.specshow(librosa.chroma_cqt(y=y, sr=sr), y_axis='chroma')
[4] tonnetz():绘制音频的 Tonnetz 表示,这是一种音乐理论中用于描述音高关系的工具
>> librosa.display.specshow(librosa.tonnetz(y=y, sr=sr), y_axis='tonnetz')
[5] pianoroll():绘制钢琴卷帘图,展示音频中各个音符的激活情况
>> librosa.display.specshow(librosa.pianoroll(y, sr=sr), x_axis='time')
[6] 颜色映射和自定义:librosa.display 还允许用户自定义颜色映射和其他视觉元素,以更好地适应不同的可视化需求
>> cmap = plt.get_cmap('magma') 获取颜色映射
>> librosa.display.specshow(data, cmap=cmap)
[7]设置坐标轴:可以设置频率、时间或其他自定义轴
>> librosa.display.specshow(data, x_axis='time', y_axis='mel')
matplotlib数据库功能介绍:
matplotlib 是一个 Python 的绘图库,广泛用于数据可视化。它提供了一个类似于 MATLAB 的绘图框架,使得用户可以轻松地创建各种静态、交互式和动画图表。matplotlib 特别适合用于生成出版质量的图表,并且支持多种输出格式,包括 PNG、PDF、SVG 等。以下是 matplotlib 的一些关键特性:
详细查看
[1]多维数据绘图:可以轻松地绘制多维数据集。
[2]多种图表类型:支持折线图、散点图、柱状图、饼图、直方图、箱线图等多种图表类型。
[3]自定义图表:用户可以自定义图表的几乎每个方面,包括颜色、线型、标记、文字、图例、标题等。
[4]交互式工具:提供了交互式工具,如缩放、平移、旋转等。
[5]动画支持:可以创建动画图表,展示数据随时间的变化。
[6]多种输出格式:支持多种输出格式,包括图片文件、PDF、SVG 等。
[7]与其它库集成:可以与 numpy、pandas、scipy 等科学计算库紧密集成。
[8]Web 后端支持:matplotlib 还支持 Web 后端,如通过 WebAgg 后端在浏览器中显示图表。
[9]样式和主题:可以通过内置的样式或自定义主题来改变图表的外观。
[10]工具栏:提供了一个工具栏,方便进行图表的交互操作。
IPython.display模块功能介绍:
IPython.display 是 IPython 库中的一个模块,它提供了一组用于在 IPython 环境中展示数据和媒体内容的类和函数。IPython 是一个交互式 Python 解释器,广泛用于科学计算、数据分析和研究。IPython.display 模块允许用户在 IPython 笔记本(如 Jupyter Notebook)中展示各种类型的数据和媒体,包括 HTML、图片、视频、音频、Latex 公式等。以下是 IPython.display 模块的一些常用功能:
详细查看
[1]展示图片:** from IPython.display import Image >> display(Image('path_to_image.jpg'))
[2]展示 HTML 内容:** from IPython.display import HTML >> display(HTML('<b>Hello, World!</b>'))
[3]展示 LaTeX 公式:** from IPython.display import Latex >> display(Latex(r'f(x) = \int_{-\infty}^\infty e^{-x^2} dx'))
[4]展示音频:** from IPython.display import Audio >> display(Audio('path_to_audio_file.wav'))
[5]展示视频:** from IPython.display import Video >> display(Video('path_to_video_file.mp4'))
[6]展示 JSON 数据:** from IPython.display import JSON >> display(JSON({'key': 'value'}))
[7]展示纯文本:** from IPython.display import display, Text >> display(Text('Hello, World!'))
[8]展示 Markdown:** from IPython.display import Markdown >> display(Markdown('# Markdown Header'))
[9]清除输出:** from IPython.display import clear_output >> clear_output()
2.录制音频
FORMAT = pyaudio.paInt16 # 音频格式
CHANNELS = 1 # 声道数,1表示单声道
RATE = 44100 # 采样率,单位Hz
# 初始化PyAudio
audio = pyaudio.PyAudio()
# 打开音频流
stream = audio.open(format=FORMAT,channels=CHANNELS,rate=RATE,input=True,frames_per_buffer=1024)
# 创建一个空的列表来存储录制的音频帧
frames = []
print("录制中,按'q'结束...")
try:
while True:
data = stream.read(1024) # 读取音频数据
frames.append(data) # 将音频数据添加到列表中
except KeyboardInterrupt: # 手动结束录音,按'q'退出
print("\n录制结束.")
# 停止并关闭音频流
stream.stop_stream()
stream.close()
audio.terminate()
# 将录制的音频数据写入wav文件
filename = "recording.wav"
with wave.open(filename, 'wb') as wf:
wf.setnchannels(CHANNELS)
wf.setsampwidth(audio.get_sample_size(FORMAT))
wf.setframerate(RATE)
wf.writeframes(b''.join(frames))
print(f"录音保存为 {filename}")
输出结果展示:
录制中,按'q'结束...
录制结束.
录音保存为 recording.wav
3.录音文件回放
audio_path = r'path_to_audio_file.wav'
audio,sr = librosa.load(audio_path,sr=25600) #返回两个参数,振幅矩阵和采样率
Audio(audio_path) # 播放音频
输出结果展示为录音回放(编辑器无法展示,这里只作截图展示),如下:
4.时域波形
plt.figure(figsize = (18,6))
librosa.display.waveshow(audio,sr=25600)
plt.xlabel('Time')
plt.ylabel('Amplitude')
plt.show()
输出结果展示:
5.频谱图
# 绘制频谱图
## 1.先进行傅里叶变换
# numpy.fft.fft.(x,n=none,axis=-1,norm=none)
# x:输入数组数据或信号
# n:输出频率点数量,如果n>x,则充0,如果n<x,则被截断
# axis:表示沿哪个轴进行FFT,常用多维数组
# norm:指定FFT的规范形式
audio_ft = np.fft.fft(audio)
## 2.绘图
def plot_magnitude_spectrum(signal,sr,f_ratio=1):
x = np.fft.fft(signal) #快速傅里叶变换
x_mag = np.absolute(x) #取幅值
plt.figure(figsize = (18,5))
f = np.linspace(0,sr,len(x_mag)) # 创建[0,采样率]的等差数列
f_bins = int(len(x_mag)*f_ratio) # 条形块的数量
plt.plot(f[:f_bins],x_mag[:f_bins])
plt.xlabel('Frequency (Hz)')
plot_magnitude_spectrum(audio_ft,sr,1)
输出结果展示:
# 展示局部结果
plot_magnitude_spectrum(audio_ft,sr,0.01)
输出结果展示:
6.时频图
展示两种时频图绘制方法:
方法一:
from scipy.io import wavfile
from scipy.signal import spectrogram
# 加载音频文件
sample_rate, data = wavfile.read(audio_path)
# 确保音频数据是一维的(单声道)
if len(data.shape) == 2:
data = data.mean(axis=1)
# 计算频谱
f, t, Sxx = spectrogram(data, fs=sample_rate)
# 将功率谱转换为10倍对数
Sxx_dB = 10 * np.log10(Sxx)
# 绘制倍频程图
plt.figure(figsize=(10, 6))
plt.pcolormesh(t, f, Sxx_dB, shading='gouraud')
plt.title('Audio Octave Frequency Plot')
plt.xlabel('Time (seconds)')
plt.ylabel('Frequency (Hz)')
plt.colorbar(label='Power (dB)')
plt.show()
输出结果展示:
方法二:
# 绘制音频频谱图
plt.figure(figsize=(10,6))
librosa.display.specshow(librosa.amplitude_to_db(librosa.stft(audio)), y_axis='log', x_axis='time')
plt.colorbar(format='%2.0f dB')
plt.title('Spectrogram')
plt.xlabel('Time(s)')
plt.ylabel('f (Hz)')
plt.show()
输出结果展示:
最后:
文中频率分析结果看起来有些问题,因作者水平有限,还未解决。频谱分析的角度比较广泛,后续会尝试加入倍频谱、计权分析,同时将每个模块代码写成函数,也会尝试写入GUI。