grasys blog

Pythonで音の波形やスペクトログラムを見てみる(librosa)

はじめまして!エンジニアの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を使ってみてください。

プログラムを書くときや音の解析を行う際に、もう少し音に対して勉強が必要だなと思いました。

参照

librosa(ドキュメント)

スペクトログラム


採用情報
お問い合わせ