はじめに
こんにちは! MYJLab Advent Calendar 2024、12日目を担当する松田です。
昨日はうのちゃんの色彩検定についてのお話でした。
PCCSの色相環は見たことありましたが、ドミナントカラーやドミナントトーンについては初めてで、勉強になりました!!
企業のロゴや標識は日常的に目にするのでとても身近に感じ、興味を持てましたよね!
クイズは難しかったなあ☺☺
さて、本記事は、簡単にできる音響信号分析についてになります。
私は、卒業研究で音楽データを解析していたのですが、そこで使用したLibrosaというPythonのライブラリの説明をしようと思います。
簡単にできるので、良かったら一緒にやってみてください!!
Librosaとは?
Librosaは、Pythonで音響信号を処理・分析するためのライブラリです。
音楽や音声データの解析を簡単に行うことができ、音響信号処理における基本的なツールとして活用されています!
インストール方法
Librosaをインストールするには、以下のコマンドを実行します。
pip install librosa
音楽ファイルの読み込み
まずは、音声ファイルを読み込みます。
librosa.loadを使ってファイルの読み込みと音声信号データ(y)とサンプリングレート(sr)の取得ができます。
import librosa
audio_path = 'demo.wav'
y, sr = librosa.load(audio_path)
print(f"サンプルレート: {sr} Hz")
print(f"データの長さ: {len(y)} サンプル")
結果
サンプルレート: 22050 Hz
データの長さ: 3487104 サンプル
波形の描画
次は、波形の描画です。
波形を描画することで、音声データの全体像を視覚的に把握することができます。
import librosa.display
import matplotlib.pyplot as plt
# 波形を描画
plt.figure(figsize=(10, 4))
librosa.display.waveshow(y, sr=sr)
plt.title('Waveform')
plt.xlabel('Time (s)')
plt.ylabel('Amplitude')
plt.show()
クロマグラム
次は、クロマグラムです。
クロマグラムは、音声データの音の高さ(ピッチ)を12の音階 [C, C#, D, D#, E, F, F#, G, G#, A, A#, B] に分類し、それを時間軸に沿って可視化したものです。
クロマは音階を意味しており、クロマグラムはクロマをヒートマップで視覚的に表現したものです。
楽曲の調性やコード進行を分析する際に活用されます。
chromagram = librosa.feature.chroma_stft(y=y, sr=sr)
plt.figure(figsize=(12, 4))
librosa.display.specshow(chromagram, y_axis='chroma', x_axis='time')
plt.colorbar()
plt.title('Chromagram')
plt.tight_layout()
plt.show()
出力をみると、時間経過に伴った音階の強度を把握することができます!
ヒートマップのx軸は時間、y軸は12の音階を示しています。
黄色など明るい色はその音階のエネルギーが高く、
黒など暗い色はその音階がほとんど現れていないことになります。
音圧(RMS)
次は音の大きさの変化や強弱の推定です。
音声データのエネルギー変化を表すRMS値を計算しています。
import numpy as np
# RMSを計算
rms = librosa.feature.rms(y=y, frame_length=65000, hop_length=16250)[0]
rms /= np.max(rms) # 正規化
times = librosa.times_like(rms, hop_length=16250, sr=sr)
# RMSをプロット
plt.figure(figsize=(12, 4))
plt.plot(times, rms, label="RMS")
plt.ylabel("Normalized RMS")
plt.xlabel("Time (s)")
plt.legend()
plt.tight_layout()
plt.show()
テンポ
最後に、楽曲のテンポ推定です。
ビートの位置を検出し、音楽のテンポを推定することができます!
tempo, beats = librosa.beat.beat_track(y=y, sr=sr)
print(f"テンポ: {tempo} BPM")
結果
テンポ: [69.83741554] BPM
まとめ
今日はLibrosaを用いた音響信号分析についてのお話でした。
今回は基本的な機能のみを紹介しましたが、Librosaにはさらに多くの機能があるので、
興味がある方はぜひトライしてみてください~
最後までお読みいただき、ありがとうございました!