Documentation Python

Pythonのlibrosaライブラリは、音声データの分析・可視化・特徴量抽出を簡単に行える強力なツールです。この記事では、基本的な使い方から実践的な音声処理までを解説します。

音声処理ライブラリの比較

ライブラリ用途特徴インストール
librosa音声分析・MIR特徴量抽出が豊富pip install librosa
pydub音声編集フォーマット変換が簡単pip install pydub
soundfile音声読み書き高速・多フォーマット対応pip install soundfile
scipy.io.wavfileWAV読み書き標準ライブラリ不要
pyaudioリアルタイム処理ストリーミング対応pip install pyaudio

librosaの主な機能

機能関数用途
音声読み込みlibrosa.load()音声ファイルの読み込み
波形表示librosa.display.waveshow()時間領域の可視化
スペクトログラムlibrosa.stft()周波数領域への変換
メルスペクトログラムlibrosa.feature.melspectrogram()人間の聴覚に基づく特徴量
MFCClibrosa.feature.mfcc()音声認識の特徴量
テンポ検出librosa.beat.beat_track()BPMとビート位置の推定
ピッチ検出librosa.pyin()基本周波数の推定

インストール

# librosaと可視化用ライブラリをインストール
pip install librosa matplotlib numpy

音声データの読み込み

import librosa
import librosa.display
import matplotlib.pyplot as plt
import numpy as np

# 音声ファイルを読み込む
audio_path = 'example.wav'
y, sr = librosa.load(audio_path, sr=None)  # sr=Noneで元のサンプリングレートを維持

print(f"サンプルデータの長さ: {len(y)}")
print(f"サンプリングレート: {sr} Hz")
print(f"音声の長さ: {len(y) / sr:.2f} 秒")

# サンプリングレートを指定して読み込み(リサンプリング)
y_22k, sr_22k = librosa.load(audio_path, sr=22050)  # 22.05kHzにリサンプリング

# 音声の一部のみ読み込み(offsetとdurationで指定)
y_partial, sr = librosa.load(audio_path, offset=1.0, duration=5.0)  # 1秒目から5秒間

読み込みパラメータ

パラメータ説明デフォルト値
srサンプリングレート22050
monoモノラル変換True
offset開始位置(秒)0.0
duration読み込み時間(秒)None(全体)

音声の可視化

波形の表示

import librosa
import librosa.display
import matplotlib.pyplot as plt

# 音声ファイルを読み込み
y, sr = librosa.load('example.wav')

# 波形を描画
plt.figure(figsize=(12, 4))
librosa.display.waveshow(y, sr=sr, alpha=0.8)
plt.title('Waveform')
plt.xlabel('Time (s)')
plt.ylabel('Amplitude')
plt.tight_layout()
plt.show()

# ステレオ音声の場合
y_stereo, sr = librosa.load('stereo.wav', mono=False)
fig, axes = plt.subplots(2, 1, figsize=(12, 6))
for i, channel in enumerate(['Left', 'Right']):
    librosa.display.waveshow(y_stereo[i], sr=sr, ax=axes[i])
    axes[i].set_title(f'{channel} Channel')
plt.tight_layout()
plt.show()

スペクトログラムの表示

import librosa
import librosa.display
import matplotlib.pyplot as plt
import numpy as np

y, sr = librosa.load('example.wav')

# 短時間フーリエ変換(STFT)
D = librosa.stft(y, n_fft=2048, hop_length=512)

# 振幅スペクトログラム(デシベル表示)
S_db = librosa.amplitude_to_db(np.abs(D), ref=np.max)

# スペクトログラムを描画
plt.figure(figsize=(12, 6))
librosa.display.specshow(S_db, sr=sr, hop_length=512, x_axis='time', y_axis='log')
plt.colorbar(format='%+2.0f dB')
plt.title('Spectrogram')
plt.tight_layout()
plt.show()

メルスペクトログラム

メルスペクトログラムは人間の聴覚特性に基づいた周波数スケールで、音声認識や音楽分類で広く使用されます。

import librosa
import librosa.display
import matplotlib.pyplot as plt
import numpy as np

y, sr = librosa.load('example.wav')

# メルスペクトログラムを計算
S = librosa.feature.melspectrogram(y=y, sr=sr, n_mels=128, fmax=8000)

# デシベル単位に変換
S_dB = librosa.power_to_db(S, ref=np.max)

# メルスペクトログラムを表示
plt.figure(figsize=(12, 6))
librosa.display.specshow(S_dB, sr=sr, x_axis='time', y_axis='mel', fmax=8000)
plt.colorbar(format='%+2.0f dB')
plt.title('Mel Spectrogram')
plt.tight_layout()
plt.show()

音声特徴量の抽出

MFCC(メル周波数ケプストラム係数)

MFCCは音声認識で最も広く使われる特徴量です。

import librosa
import librosa.display
import matplotlib.pyplot as plt
import numpy as np

y, sr = librosa.load('example.wav')

# MFCCを計算(13次元)
mfccs = librosa.feature.mfcc(y=y, sr=sr, n_mfcc=13)

print(f"MFCC shape: {mfccs.shape}")  # (n_mfcc, time_frames)

# MFCCを可視化
plt.figure(figsize=(12, 6))
librosa.display.specshow(mfccs, sr=sr, x_axis='time')
plt.colorbar()
plt.title('MFCC')
plt.ylabel('MFCC Coefficients')
plt.tight_layout()
plt.show()

# デルタ(一次微分)とデルタデルタ(二次微分)も計算
mfcc_delta = librosa.feature.delta(mfccs)
mfcc_delta2 = librosa.feature.delta(mfccs, order=2)

# 特徴量を結合
features = np.vstack([mfccs, mfcc_delta, mfcc_delta2])
print(f"Combined features shape: {features.shape}")  # (39, time_frames)

ゼロ交差率

ゼロ交差率は音声/無音声の判定やノイズ検出に有効です。

import librosa
import matplotlib.pyplot as plt

y, sr = librosa.load('example.wav')

# ゼロ交差率を計算
zcr = librosa.feature.zero_crossing_rate(y)

# フレームごとの時間軸を作成
times = librosa.times_like(zcr, sr=sr)

# 可視化
fig, axes = plt.subplots(2, 1, figsize=(12, 6))

# 波形
librosa.display.waveshow(y, sr=sr, ax=axes[0])
axes[0].set_title('Waveform')

# ゼロ交差率
axes[1].plot(times, zcr[0], color='green')
axes[1].set_title('Zero Crossing Rate')
axes[1].set_xlabel('Time (s)')
axes[1].set_ylabel('Rate')

plt.tight_layout()
plt.show()

スペクトル特徴量

import librosa
import numpy as np

y, sr = librosa.load('example.wav')

# スペクトル重心(音の明るさ)
spectral_centroids = librosa.feature.spectral_centroid(y=y, sr=sr)

# スペクトル帯域幅
spectral_bandwidth = librosa.feature.spectral_bandwidth(y=y, sr=sr)

# スペクトルロールオフ(エネルギーの95%が含まれる周波数)
spectral_rolloff = librosa.feature.spectral_rolloff(y=y, sr=sr)

# スペクトルコントラスト
spectral_contrast = librosa.feature.spectral_contrast(y=y, sr=sr)

# RMS(Root Mean Square)エネルギー
rms = librosa.feature.rms(y=y)

print(f"Spectral Centroid shape: {spectral_centroids.shape}")
print(f"RMS shape: {rms.shape}")

テンポとビートの検出

import librosa
import librosa.display
import matplotlib.pyplot as plt

y, sr = librosa.load('music.wav')

# テンポとビート位置を検出
tempo, beat_frames = librosa.beat.beat_track(y=y, sr=sr)
print(f"推定テンポ: {tempo:.1f} BPM")

# ビートフレームを時間に変換
beat_times = librosa.frames_to_time(beat_frames, sr=sr)

# 波形とビート位置を可視化
plt.figure(figsize=(12, 4))
librosa.display.waveshow(y, sr=sr, alpha=0.6)
plt.vlines(beat_times, -1, 1, color='r', alpha=0.7, linestyle='--', label='Beats')
plt.title(f'Waveform with Beats (Tempo: {tempo:.1f} BPM)')
plt.legend()
plt.tight_layout()
plt.show()

# オンセット検出(音の立ち上がり)
onset_frames = librosa.onset.onset_detect(y=y, sr=sr)
onset_times = librosa.frames_to_time(onset_frames, sr=sr)

ピッチ検出

import librosa
import matplotlib.pyplot as plt
import numpy as np

y, sr = librosa.load('vocal.wav')

# pYINアルゴリズムでピッチを検出
f0, voiced_flag, voiced_probs = librosa.pyin(
    y,
    fmin=librosa.note_to_hz('C2'),  # 最低周波数
    fmax=librosa.note_to_hz('C7'),  # 最高周波数
    sr=sr
)

# 時間軸を作成
times = librosa.times_like(f0, sr=sr)

# ピッチを可視化
fig, axes = plt.subplots(2, 1, figsize=(12, 8))

# 波形
librosa.display.waveshow(y, sr=sr, ax=axes[0])
axes[0].set_title('Waveform')

# ピッチ曲線
axes[1].plot(times, f0, color='blue', linewidth=1)
axes[1].set_title('Pitch (F0)')
axes[1].set_xlabel('Time (s)')
axes[1].set_ylabel('Frequency (Hz)')
axes[1].set_ylim([0, 500])

plt.tight_layout()
plt.show()

# 音名に変換
notes = librosa.hz_to_note(f0[~np.isnan(f0)])
print(f"検出された音名(一部): {notes[:10]}")

音声の変換

ピッチシフト

import librosa
import soundfile as sf

y, sr = librosa.load('example.wav')

# ピッチを2半音上げる
y_shifted_up = librosa.effects.pitch_shift(y=y, sr=sr, n_steps=2)

# ピッチを3半音下げる
y_shifted_down = librosa.effects.pitch_shift(y=y, sr=sr, n_steps=-3)

# 保存
sf.write('pitch_up.wav', y_shifted_up, sr)
sf.write('pitch_down.wav', y_shifted_down, sr)

タイムストレッチ

import librosa
import soundfile as sf

y, sr = librosa.load('example.wav')

# 1.5倍速(ピッチを変えずに速度を上げる)
y_fast = librosa.effects.time_stretch(y=y, rate=1.5)

# 0.75倍速(スロー再生)
y_slow = librosa.effects.time_stretch(y=y, rate=0.75)

# 保存
sf.write('fast.wav', y_fast, sr)
sf.write('slow.wav', y_slow, sr)

ハーモニック・パーカッシブ分離

import librosa
import soundfile as sf

y, sr = librosa.load('music.wav')

# ハーモニック成分とパーカッシブ成分に分離
y_harmonic, y_percussive = librosa.effects.hpss(y)

# それぞれを保存
sf.write('harmonic.wav', y_harmonic, sr)
sf.write('percussive.wav', y_percussive, sr)

実践的な例

音声ファイルの特徴量抽出パイプライン

import librosa
import numpy as np
from typing import Dict, Any

def extract_features(file_path: str) -> Dict[str, Any]:
    """音声ファイルから特徴量を抽出"""
    # 音声を読み込み
    y, sr = librosa.load(file_path, sr=22050)

    # 基本情報
    duration = len(y) / sr

    # MFCC(平均と標準偏差)
    mfccs = librosa.feature.mfcc(y=y, sr=sr, n_mfcc=13)
    mfcc_mean = np.mean(mfccs, axis=1)
    mfcc_std = np.std(mfccs, axis=1)

    # スペクトル特徴量
    spectral_centroid = np.mean(librosa.feature.spectral_centroid(y=y, sr=sr))
    spectral_bandwidth = np.mean(librosa.feature.spectral_bandwidth(y=y, sr=sr))
    spectral_rolloff = np.mean(librosa.feature.spectral_rolloff(y=y, sr=sr))

    # ゼロ交差率
    zcr = np.mean(librosa.feature.zero_crossing_rate(y))

    # RMSエネルギー
    rms = np.mean(librosa.feature.rms(y=y))

    # テンポ
    tempo, _ = librosa.beat.beat_track(y=y, sr=sr)

    return {
        'duration': duration,
        'tempo': tempo,
        'mfcc_mean': mfcc_mean,
        'mfcc_std': mfcc_std,
        'spectral_centroid': spectral_centroid,
        'spectral_bandwidth': spectral_bandwidth,
        'spectral_rolloff': spectral_rolloff,
        'zero_crossing_rate': zcr,
        'rms_energy': rms
    }

# 使用例
features = extract_features('example.wav')
print(f"Duration: {features['duration']:.2f}s")
print(f"Tempo: {features['tempo']:.1f} BPM")
print(f"Spectral Centroid: {features['spectral_centroid']:.2f} Hz")

音声の類似度計算

import librosa
import numpy as np
from scipy.spatial.distance import cosine

def compute_audio_similarity(file1: str, file2: str) -> float:
    """2つの音声ファイルの類似度を計算(0-1、1が最も類似)"""
    # 両方の音声を読み込み
    y1, sr1 = librosa.load(file1, sr=22050)
    y2, sr2 = librosa.load(file2, sr=22050)

    # MFCCを計算
    mfcc1 = librosa.feature.mfcc(y=y1, sr=sr1, n_mfcc=13)
    mfcc2 = librosa.feature.mfcc(y=y2, sr=sr2, n_mfcc=13)

    # 平均を取って特徴ベクトルに
    feat1 = np.mean(mfcc1, axis=1)
    feat2 = np.mean(mfcc2, axis=1)

    # コサイン類似度を計算
    similarity = 1 - cosine(feat1, feat2)

    return similarity

# 使用例
similarity = compute_audio_similarity('audio1.wav', 'audio2.wav')
print(f"類似度: {similarity:.4f}")

よくあるエラーと対処法

import librosa

# FileNotFoundError: 音声ファイルが見つからない
# 対処: パスを確認し、絶対パスを使用
import os
audio_path = os.path.abspath('example.wav')
if os.path.exists(audio_path):
    y, sr = librosa.load(audio_path)

# audioreadのエラー: 対応していないフォーマット
# 対処: ffmpegをインストール
# pip install ffmpeg-python
# または: conda install -c conda-forge ffmpeg

# メモリエラー: 長い音声ファイル
# 対処: 分割して処理
def process_long_audio(file_path: str, chunk_duration: float = 30.0):
    """長い音声を分割して処理"""
    duration = librosa.get_duration(path=file_path)
    results = []

    for offset in np.arange(0, duration, chunk_duration):
        y, sr = librosa.load(file_path, offset=offset, duration=chunk_duration)
        # 各チャンクを処理
        features = librosa.feature.mfcc(y=y, sr=sr)
        results.append(features)

    return results

まとめ

用途推奨関数
音声読み込みlibrosa.load()
波形表示librosa.display.waveshow()
スペクトログラムlibrosa.stft() + specshow()
音声認識の特徴量librosa.feature.mfcc()
テンポ検出librosa.beat.beat_track()
ピッチ検出librosa.pyin()
音声変換librosa.effects.*

librosaを使うことで、音声データの分析から特徴量抽出、可視化まで幅広い処理が可能です。音声認識、音楽情報検索、音声合成などの応用に活用できます。

参考文献

円