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。