介紹如何在 Python 中使用 scipy
與 matplotlib
模組讀取 wav 聲音檔案,並繪製波形圖(waveform)、頻譜圖(spectrum)與時頻譜圖(spectrogram)。
讀取 WAV 聲音檔案
若要讀取一般的 wav 聲音檔案,可以使用 scipy
模組:
from scipy.io.wavfile import read # 讀取 WAV 檔案 rate, data = read("bubbs.wav")
讀取出來的資料包含取樣頻率(rate
)與取樣資料(data
)。
查看取樣頻率:
# 取樣頻率 print("Sample rate: {} Hz".format(rate))
Sample rate: 11000 Hz
查看取樣資料的類型:
# 資料類型 print("Data type: {}".format(data.dtype))
Data type: uint8
繪製波形圖
將取樣資料的前 1024 點資料取出,以 matplotlib
繪製波形圖:
import matplotlib.pyplot as plt # 繪製前 1024 點資料的波形圖 plt.figure(figsize=(15, 5)) plt.plot(data[0:1024]) plt.show()
繪製頻譜圖
經過傅立葉轉換之後,繪製頻譜圖(spectrum):
# 傅立葉轉換 from scipy.fftpack import fft dataFFT = fft(data[0:1024]) dataFFTAbs = abs(dataFFT[1:512]) # 繪製頻譜圖 plt.figure(figsize=(15, 5)) plt.plot(dataFFTAbs, 'r') plt.show()
波形與時頻譜圖
將全部資料的波形圖與時頻譜圖(spectrogram)繪製在一起:
import matplotlib.pyplot as plt import numpy as np # 產生時間資料 time = np.arange(0, len(data)) / rate plt.figure(figsize=(15, 5)) # 繪製波形圖 plotA = plt.subplot(211) plotA.plot(time, data) plotA.set_ylabel("Amplitude") plotA.set_xlim(0, len(data) / rate) # 繪製時頻譜圖 plotB = plt.subplot(212) plotB.specgram(data, NFFT=1024, Fs=rate, noverlap=900) plotB.set_ylabel("Frequency") plotB.set_xlabel("Time") plt.show()
參考資料:StackOverflow
弘岳 表示:
繪製時頻譜圖的部分有些問題
plotB.specgram(data, NFFT=1024, Fs=rate, noverlap=900)
only 1-dimensional arrays can be used
data應該是二維陣列
HoLeeson 表示:
沒問題唷, 立體聲才是2維, 分別處理就好