音訊錄製及視覺化處理

海唤鱼發表於2024-07-11

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) # 播放音訊

輸出結果展示為錄音回放(編輯器無法展示,這裡只作截圖展示),如下:
image

4.時域波形

plt.figure(figsize = (18,6))
librosa.display.waveshow(audio,sr=25600)
plt.xlabel('Time')
plt.ylabel('Amplitude')
plt.show()

輸出結果展示:
image

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)

輸出結果展示:
image

# 展示區域性結果
plot_magnitude_spectrum(audio_ft,sr,0.01)

輸出結果展示:
image

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()

輸出結果展示:
image

方法二:

# 繪製音訊頻譜圖
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()

輸出結果展示:
image

最後:
文中頻率分析結果看起來有些問題,因作者水平有限,還未解決。頻譜分析的角度比較廣泛,後續會嘗試加入倍頻譜、計權分析,同時將每個模組程式碼寫成函式,也會嘗試寫入GUI。

相關文章