🔥博客主页:是dream
🚀系列专栏:深度学习环境搭建、环境配置问题解决、自然语言处理、语音信号处理、项目开发
💘每日语录:每一个裂缝都是为透出光而努力。
🎉感谢大家点赞👍收藏⭐指正✍️
前言
当我们谈论声音信号处理时, 语音信号处理是一个令人着迷的领域,它涉及到音频信号的获取、分析、处理和合成。然而,了解声音信号处理的基础知识是掌握这一领域的关键。本博客将带您踏上一段关于声音信号处理基础的学习之旅。感谢代码作者:sinat_18131557
本文章内容涵盖内容如下:
1.环境配置
2.通过python录音,并生成.wav文件
3.代码改进
改进的内容有:
1.增加横纵坐标
2.增加选定其中一段时间进行波形图绘制的功能
3.将录制和播放功能集成到一个Python文件中,并增加UI界面,可以输入录音时长,播放指定音频等
准备工作
源码获取
提取码(peng)
https://pan.baidu.com/s/1T2favK-04nlF_E3K-tlEsA
环境配置
这里需要用到以下几个库
pyaudio
librosa
matplotlib
scipy
numpy
pandas
以上的库可以通过pip来进行安装。如:
pip instsall pyaudio
录音(wav格式)
代码实现:
import pyaudio
import wave
CHUNK = 1024
FORMAT = pyaudio.paInt16
CHANNELS = 2
RATE = 16000
RECORD_SECONDS = 2
WAVE_OUTPUT_FILENAME = "Oldboy.wav"
p = pyaudio.PyAudio()
stream = p.open(format=FORMAT,
channels=CHANNELS,
rate=RATE,
input=True,
frames_per_buffer=CHUNK)
print("开始录音,请说话......")
frames = []
for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
data = stream.read(CHUNK)
frames.append(data)
print("录音结束,请闭嘴!")
stream.stop_stream()
stream.close()
p.terminate()
wf = wave.open(WAVE_OUTPUT_FILENAME, 'wb')
wf.setnchannels(CHANNELS)
wf.setsampwidth(p.get_sample_size(FORMAT))
wf.setframerate(RATE)
wf.writeframes(b''.join(frames))
wf.close()
播放音频
"""PyAudio Example: Play a WAVE file."""
import pyaudio
import wave
CHUNK = 1024
FILENAME = 'C2_1_y.wav'
def player(filename=FILENAME):
wf = wave.open(filename, 'rb')
p = pyaudio.PyAudio()
stream = p.open(format=p.get_format_from_width(wf.getsampwidth()),
channels=wf.getnchannels(),
rate=wf.getframerate(),
output=True)
data = wf.readframes(CHUNK)
while data != b'':
stream.write(data)
data = wf.readframes(CHUNK)
stream.stop_stream()
stream.close()
p.terminate()
player(FILENAME)
录音和播放功能集成(UI界面实现)
效果图展示:
这个UI界面中可以输入录制时间,文件保存的名字。
附上代码:
import pyaudio
import wave
import tkinter as tk
from tkinter import filedialog, Entry
import time
CHUNK = 1024
FORMAT = pyaudio.paInt16
CHANNELS = 2
RATE = 16000
class AudioRecorderPlayer:
def __init__(self, root):
self.root = root
self.root.title("音频录制和播放")
# 创建录制参数输入框
self.record_duration_label = tk.Label(root, text="录制时间(秒):")
self.record_duration_label.pack()
self.record_duration_entry = Entry(root)
self.record_duration_entry.pack()
# 创建保存文件名输入框
self.file_name_label = tk.Label(root, text="保存的文件名(不包括扩展名.wav):")
self.file_name_label.pack()
self.file_name_entry = Entry(root)
self.file_name_entry.pack()
# 创建录制音频的按钮
self.record_button = tk.Button(root, text="录制音频", command=self.record_audio)
self.record_button.pack()
# 创建选择播放音频文件的按钮
self.play_button = tk.Button(root, text="选择并播放音频文件", command=self.play_audio)
self.play_button.pack()
def record_audio(self):
# 获取录制参数:录制时间和保存文件名
record_duration = float(self.record_duration_entry.get())
file_name = self.file_name_entry.get()
p = pyaudio.PyAudio()
stream = p.open(
format=FORMAT,
channels=CHANNELS,
rate=RATE,
input=True,
frames_per_buffer=CHUNK
)
print(f"开始录制 {file_name}.wav,请说话......")
frames = []
start_time = time.time()
while (time.time() - start_time) < record_duration:
data = stream.read(CHUNK)
frames.append(data)
print(f"录制结束,{file_name}.wav 已保存!")
stream.stop_stream()
stream.close()
p.terminate()
# 添加.wav扩展名
if not file_name.endswith('.wav'):
file_name += '.wav'
wf = wave.open(file_name, 'wb')
wf.setnchannels(CHANNELS)
wf.setsampwidth(p.get_sample_size(FORMAT))
wf.setframerate(RATE)
wf.writeframes(b''.join(frames))
wf.close()
def play_audio(self):
# 使用文件对话框选择要播放的音频文件
file_path = filedialog.askopenfilename(filetypes=[("WAV files", "*.wav")])
if not file_path:
return
wf = wave.open(file_path, 'rb')
p = pyaudio.PyAudio()
stream = p.open(
format=p.get_format_from_width(wf.getsampwidth()),
channels=wf.getnchannels(),
rate=wf.getframerate(),
output=True
)
data = wf.readframes(CHUNK)
print(f"开始播放 {file_path}......")
while data != b'':
stream.write(data)
data = wf.readframes(CHUNK)
stream.stop_stream()
stream.close()
p.terminate()
if __name__ == "__main__":
root = tk.Tk()
app = AudioRecorderPlayer(root)
root.mainloop()
绘制音频波形图
相较于源码有以下改进:
1.增加横纵坐标。
2.可选择音频的任意一段来绘制波形图。
准备:中文字体,可以自行下载,也可以参考我的另一篇文章“ TF-IDF算法讲解 ”中的词云生成部分,有免费分享的中文字体。附上链接。
NLP自然语言处理——关键词提取之 TF-IDF 算法(五分钟带你深刻领悟TF-IDF算法的精髓)_鹏_Ai心得分享的博客-CSDN博客
import librosa
from scipy.io import wavfile
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties
def load_and_visualize_audio(file_path, select=False, start_time=0, end_time=0):
try:
# 从文件加载音频数据
fs, data = wavfile.read(file_path)
# 打印音频长度
duration = len(data) / fs
print("音频长度 = {:.2f} 秒".format(duration))
# 使用Librosa加载音频,获取数据和采样率
data1, sample_rate = librosa.load(file_path, sr=fs)
# 设置中文字体
font = FontProperties(fname='D:\my_homework\语音信号处理\python_sound_open-master\SimHei.ttf', size=12)
# 如果select为True,选择特定的时间段进行分析
if select:
# 计算选定时间段的样本索引
start_sample = int(start_time * fs)
end_sample = int(end_time * fs)
# 截取选定时间段的音频数据
selected_data = data1[start_sample:end_sample]
# 绘制选定时间段的音频波形
plt.figure(figsize=(14, 5))
plt.plot(selected_data)
plt.title("选定时间段音频波形", fontproperties=font)
plt.xlabel("时间 (s)", fontproperties=font)
plt.ylabel("振幅", fontproperties=font)
else:
# 绘制整段音频波形
plt.figure(figsize=(14, 5))
plt.plot(data1)
plt.title("音频波形", fontproperties=font)
plt.xlabel("时间 (s)", fontproperties=font)
plt.ylabel("振幅", fontproperties=font)
plt.show()
except Exception as e:
print("加载和可视化音频时发生错误:", str(e))
if __name__ == "__main__":
audio_file_path = 'C2_3_y.wav'
select = True # 如果为True,则选择特定时间段进行分析
start_time = 1.0 # 开始时间(以秒为单位)
end_time = 16.0 # 结束时间(以秒为单位)
load_and_visualize_audio(audio_file_path, select, start_time, end_time)
这段代码可以选择分析整段音频的波形图,也可以选择绘制其中的一段波形图,根据自己的需求,修改select变量即可。
选定1.1s到1.2s的波形图如下: