显示声波图形
这篇文章会使用 Python 内建的 wave 函数库读取的 wav 声音档,并透过 matplotlib 第三方函数库,显示声音文件 ( 录音档、mp3...等 ) 的声波图形。
因为程序中会使用到电脑的麦克风,所以请使用本机环境 ( 参考:使用 Python 虚拟环境 ) 或使用 Anaconda Jupyter 进行实作 ( 参考:使用 Anaconda ),如果不需录音,则可使用 Google Colab 实作,不用安装任何软件 ( 参考:使用 Google Colab )。
安装 matplotlib 函数库
输入下列指令安装 matplotlib 函数库 ( 依照各人环境可使用 pip、pip3 ),相关教学可参考:matplotlib 图表教学
!pip install matplotlib
打开 wav 声音档,显示声波图形
加载 matplotlib、numpy 和 wave 函数库之后,参考下方的程序码,执行后就能绘制出声波图形。
import os
os.chdir('/content/drive/MyDrive/Colab Notebooks') # 使用 Colab 要換路徑使用
import matplotlib.pyplot as plt
import numpy as np
import wave
fig, ax = plt.subplots() # 建立單一圖表
# 建立繪製聲波的函式
def visualize(path):
raw = wave.open(path) # 開啟聲音
signal = raw.readframes(-1) # 讀取全部聲音採樣
signal = np.frombuffer(signal, dtype ="int16") # 將聲音採樣轉換成 int16 的格式所組成的 np 陣列
f_rate = raw.getframerate() # 取得 framerate
time = np.linspace(0, len(signal)/f_rate, num = len(signal)) # 根據聲音採樣產生成對應的時間
ax.plot(time, signal) # 畫線,橫軸時間,縱軸陣列值
plt.title("Sound Wave") # 圖表標題
plt.xlabel("Time") # 橫軸標題
plt.show()
visualize('oxxostudio.wav') # 讀取聲音
显示 mp3 声波图形
如果要显示 mp3 的声波图形,必须要先使用 pydub 函数库,将 mp3 转换成 wav,接着再使用同样的方法打开 wav,就能显示声波图形。
import os
os.chdir('/content/drive/MyDrive/Colab Notebooks') # 使用 Colab 要換路徑使用
import matplotlib.pyplot as plt
import numpy as np
import wave
from pydub import AudioSegment # 載入 pydub 的 AudioSegment 模組
song = AudioSegment.from_mp3("oxxostudio.mp3") # 讀取 mp3 檔案
song.export("oxxostudio.wav", format="wav") # 轉換並儲存為 wav
fig, ax = plt.subplots()
def visualize(path):
raw = wave.open(path)
signal = raw.readframes(-1)
signal = np.frombuffer(signal, dtype ="int16")
f_rate = raw.getframerate()
time = np.linspace(0, len(signal)/f_rate, num = len(signal))
ax.plot(time, signal)
plt.title("Sound Wave")
plt.xlabel("Time")
plt.show()
visualize('oxxostudio.wav')
显示录音文件声波图形
参考“麦克风录音”文章,在程序中加入绘制声波图形的功能,就能在录音之后,即时显示录音文件的声波图形 ( 先将录音档存成 wav,然后再读取进行显示 ),此外,程序里使用了“平行任务处理”的技巧 ( 参考:输入文字,停止函数执行 ),开始录音之后,只要按下键盘的 a 就会停止录音。
import pyaudio
import wave
from concurrent.futures import ThreadPoolExecutor
import numpy as np
import matplotlib.pyplot as plt
chunk = 1024 # 記錄聲音的樣本區塊大小
sample_format = pyaudio.paInt16 # 樣本格式,可使用 paFloat32、paInt32、paInt24、paInt16、paInt8、paUInt8、paCustomFormat
channels = 2 # 聲道數量
fs = 44100 # 取樣頻率,常見值為 44100 ( CD )、48000 ( DVD )、22050、24000、12000 和 11025。
filename = "oxxostudio.wav" # 錄音檔名
p = pyaudio.PyAudio() # 建立 pyaudio 物件
# 開啟錄音串流
stream = p.open(format=sample_format, channels=channels, rate=fs, frames_per_buffer=chunk, input=True)
frames = [] # 建立聲音串列
run = True # 設定開始錄音
fig, ax = plt.subplots() # 建立單一圖表
# 定義錄音的函式
def record():
global run, stream, p, frames, wf
print("錄音開始...")
while run:
data = stream.read(chunk)
frames.append(data) # 將聲音記錄到串列中
stream.stop_stream() # 停止錄音
stream.close() # 關閉串流
p.terminate()
print('錄音結束...')
wf = wave.open(filename, 'wb') # 開啟聲音記錄檔
wf.setnchannels(channels) # 設定聲道
wf.setsampwidth(p.get_sample_size(sample_format)) # 設定格式
wf.setframerate(fs) # 設定取樣頻率
wf.writeframes(b''.join(frames)) # 存檔
wf.close()
visualize(filename) # 執行畫圖函式
# 定義鍵盤按鍵函式
def keyin():
global run
if input() == 'a':
run = False # 如果按下 a,就上 run 等於 False
# 定義繪製圖表函式
def visualize(path):
print('畫圖...')
raw = wave.open(path) # 開啟聲音
signal = raw.readframes(-1) # 讀取全部聲音採樣
signal = np.frombuffer(signal, dtype ="int16") # 將聲音採樣轉換成 int16 的格式所組成的 np 陣列
f_rate = raw.getframerate() # 取得 framerate
time = np.linspace(0, len(signal)/f_rate, num = len(signal)) # 根據聲音採樣產生成對應的時間
ax.plot(time, signal) # 畫線,橫軸時間,縱軸陣列值
plt.title("Sound Wave") # 圖表標題
plt.xlabel("Time") # 橫軸標題
plt.show()
executor = ThreadPoolExecutor() # 平行任務處理
e2 = executor.submit(keyin)
e1 = executor.submit(record)
executor.shutdown()
微信扫码关注
抖音扫码关注