はじめまして!エンジニアのUemaです。
音の解析をしてみたいなって思うことありませんか。
あまり無いかと思いますが、もしPythonがあるパソコンであれば手軽にPythonで音の解析ができます。
今回は、librosaを使って音解析の走りをやってみたいと思います。
librosaとは
librosaは、音楽およびオーディオ分析用の Python パッケージです。
オーディオ処理ならたくさんのことができます。
準備
Pythonとhomebrewがインストールされていることが前提です。(Pythonのバージョンはなんでも良いですが、今回はPython 3.12.1で実施しています。)
librosaで必要なffmpegをインストールする。
$ brew install ffmpeg
librosaライブラリをインストールする。
$ pip install librosa
グラフ描画するためMatplotlibもインストールします。
$ pip install matplotlib
今回音源は、librosaが公式で公開しているサンプル音源を使用します。(https://librosa.org/doc/0.10.1/recordings.html)
音楽のテンポを取得する
まず初めに、音源のテンポを下記のプログラムで見ていきましょう。
import os
import librosa
import librosa.display
def main():
# 音声ファイルを読み込み
y, sr = librosa.load(librosa.ex("choice"))
# 音声のテンポを取得する
tempo, _ = librosa.beat.beat_track(y=y, sr=sr)
print(f"Estimated tempo: {tempo:.2f} beats per minute")
if __name__ == "__main__":
main()
結果は下記のようになります。
Estimated tempo: 136.00 beats per minute
音の波形を見る
次に、サンプル音源がどのような波形になっているのかみていきましょう。
音源は、モノラルとステレオで読み込むことができます。
import os
import librosa
import librosa.display
import matplotlib.pyplot as plt
def main():
filename = "choice"
_, ax = plt.subplots(nrows=2, sharex=True)
# 音声ファイルをモノラルとして読み込み
y, sr = librosa.load(librosa.ex(filename), duration=10)
# 波形を可視化する
librosa.display.waveshow(y, sr=sr, ax=ax[0], color="blue")
ax[0].set(title="Envelope view, mono")
ax[0].label_outer()
# 音声ファイルをステレオとして読み込み
y, sr = librosa.load(librosa.ex(filename, hq=True), mono=False, duration=10)
# 波形を可視化する
librosa.display.waveshow(y, sr=sr, ax=ax[1], color="blue")
ax[1].set(title="Envelope view, stereo")
ax[1].label_outer()
plt.show()
if __name__ == "__main__":
main()
倍音とパーカッションに分ける
librosaには、音楽を倍音とパーカッションに分けることができます。
import os
import librosa
import librosa.display
import matplotlib.pyplot as plt
def main():
filename = "choice"
_, ax = plt.subplots(sharex=True)
# 音声ファイルを読み込み
y, sr = librosa.load(librosa.ex(filename), duration=10)
# 音声を倍音とパーカッションに分ける
y_harm, y_perc = librosa.effects.hpss(y)
# 波形を可視化する
librosa.display.waveshow(
y_harm, sr=sr, alpha=0.5, ax=ax, label="Harmonic", color="blue"
)
librosa.display.waveshow(
y_perc,
sr=sr,
color="red",
alpha=0.5,
ax=ax,
label="Percussive",
)
ax.set(title="Multiple waveforms")
ax.legend()
plt.show()
if __name__ == "__main__":
main()
スペクトログラムを見る
最後に、よくテレビで見る音特徴を見る時に使うスペクトログラムをみていきましょう。
スペクトログラムとは、時間に応じた音の周波数、大きさを知ることができ、上に行くほど音が高く、色が黄色いほど音が大きくなるグラフとなります。
import os
import librosa
import librosa.display
import matplotlib.pyplot as plt
import numpy as np
def main():
filename = "choice"
fig, ax = plt.subplots(nrows=2, sharex=True)
# 音声ファイルを読み込み
y, _ = librosa.load(librosa.ex(filename), duration=10)
# 短時間フーリエ変換
D = librosa.stft(y)
# デシベル スケールに割り当てる
S_db = librosa.amplitude_to_db(np.abs(D), ref=np.max)
# 線形周波数を可視化する
img = librosa.display.specshow(S_db, ax=ax[0], x_axis="time", y_axis="linear")
fig.colorbar(img, ax=ax[0], format="%+2.f dB")
ax[0].set(title="linear-frequency spectrogram")
# 対数周波数を可視化する
img = librosa.display.specshow(S_db, ax=ax[1], x_axis="time", y_axis="log")
fig.colorbar(img, ax=ax[1], format="%+2.f dB")
ax[1].set(title="log-frequency spectrogram")
plt.show()
if __name__ == "__main__":
main()
最後に
librosaで音の波形やスペクトログラムを見ることができました。
librosaには、クロマグラム(時間ごとの音階)やピッチシフトなど行うことができます。
音解析を行いたい場合は、librosaを使ってみてください。
プログラムを書くときや音の解析を行う際に、もう少し音に対して勉強が必要だなと思いました。