1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ハヌマーンで学ぶPython信号処理

Posted at

はじめに

こちらの内容は、音楽データの分析および可視化に関するPythonコードを紹介する記事です。特に、バンド「ハヌマーン」の「アパルトの中の恋人達」の曲を例に、YouTubeから音声データをダウンロードし、音楽の特徴(テンポ、ピッチ、感情分析など)を抽出・解析する方法を実践します。

参考リンクまとめ

image.png

Pythonコード

# 完全統合版:YouTube → MP3 → 可視化 → テンポ解析 → 構造解析 → ピッチ/感情マッピング

# --- Step 1: ライブラリのインストール(Colab再起動後用) ---
!pip install yt-dlp pydub librosa scikit-learn --quiet
!apt install ffmpeg -y

# --- Step 2: YouTubeからMP3をダウンロード ---
import yt_dlp
import os
from pydub import AudioSegment

# ダウンロードするYouTube動画のURL
url = "https://www.youtube.com/watch?v=ahMb9c6jcRs"  # 任意のYouTube動画URL

# 出力パス設定
output_path = "downloaded_audio.%(ext)s"

# yt-dlpの設定オプション
ydl_opts = {
    'format': 'bestaudio/best',  # 最も良い音質を選択
    'outtmpl': output_path,      # 出力ファイル名設定
    'postprocessors': [{
        'key': 'FFmpegExtractAudio',    # MP3形式に変換
        'preferredcodec': 'mp3',        # MP3形式で保存
        'preferredquality': '192',      # 音質設定
    }],
    'quiet': True  # 出力を抑制
}

# YouTubeから音声をダウンロードしてMP3に変換
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
    ydl.download([url])

# ダウンロードしたファイルの名前を変更
os.rename("downloaded_audio.mp3", "audio.mp3")
print("MP3変換完了")  # 成功メッセージ

# --- Step 3: 音声読み込みと可視化 ---
import librosa
import librosa.display
import matplotlib.pyplot as plt
import numpy as np

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

# 波形を表示
plt.figure(figsize=(10, 6))
librosa.display.waveshow(y, sr=sr)
plt.title("Waveform of the Audio")
plt.xlabel("Time (s)")
plt.ylabel("Amplitude")
plt.show()

# --- Step 4: テンポ解析 ---
# テンポの推定
tempo, beat_frames = librosa.beat.beat_track(y=y, sr=sr)

# テンポの表示
print(f"推定されたテンポ: {tempo} BPM")

# ビートの位置をプロット
plt.figure(figsize=(10, 6))
librosa.display.waveshow(y, sr=sr)
plt.vlines(librosa.frames_to_time(beat_frames), ymin=-1, ymax=1, color='r', alpha=0.7, label="Beats")
plt.title(f"Tempo Analysis: {tempo} BPM")
plt.xlabel("Time (s)")
plt.ylabel("Amplitude")
plt.legend()
plt.show()


# --- Step 5: ピッチ/感情マッピング ---
# ピッチを抽出
pitch, mag = librosa.core.piptrack(y=y, sr=sr)

# 最大ピッチを選択
index_max = mag[:, :].argmax(axis=0)
pitch_max = pitch[index_max, range(pitch.shape[1])]

# ピッチをプロット
plt.figure(figsize=(10, 6))
plt.plot(librosa.times_like(pitch_max), pitch_max, label='Pitch', color='g')
plt.title("Pitch Tracking")
plt.xlabel("Time (s)")
plt.ylabel("Frequency (Hz)")
plt.legend()
plt.show()

# 感情分析(仮にピッチとテンポに基づく簡単な感情マッピングを行う)
if tempo > 120 and np.mean(pitch_max) > 200:
    emotion = "Energetic"
elif tempo < 80 and np.mean(pitch_max) < 150:
    emotion = "Calm"
else:
    emotion = "Neutral"

print(f"推定される感情: {emotion}")

# --- Step 6: スペクトログラム解析 ---
# スペクトログラムを計算
D = librosa.amplitude_to_db(librosa.stft(y), ref=np.max)

# スペクトログラムの表示
plt.figure(figsize=(10, 6))
librosa.display.specshow(D, sr=sr, x_axis='time', y_axis='log')
plt.colorbar(format='%+2.0f dB')
plt.title('Spectrogram')
plt.xlabel('Time (s)')
plt.ylabel('Frequency (Hz)')
plt.show()

# --- Step 7: コード認識 ---
# ピッチクラスを取得して、コードを認識する
chroma = librosa.feature.chroma_cens(y=y, sr=sr)

# コードをプロット
plt.figure(figsize=(10, 6))
librosa.display.specshow(chroma, x_axis='time', y_axis='chroma')
plt.colorbar(label='Chroma')
plt.title('Chroma Features (Chords)')
plt.xlabel('Time (s)')
plt.ylabel('Pitch Classes')
plt.show()
# --- Step 8: 和音と打楽器成分の分離 ---
# 音源分離(和音と打楽器)
harmonic, percussive = librosa.effects.hpss(y)

# 和音と打楽器の波形表示
plt.figure(figsize=(10, 6))
plt.subplot(2, 1, 1)
librosa.display.waveshow(harmonic, sr=sr)
plt.title("Harmonic Component")
plt.subplot(2, 1, 2)
librosa.display.waveshow(percussive, sr=sr)
plt.title("Percussive Component")
plt.tight_layout()
plt.show()
# --- Step 9: リズムとテンポの詳細分析 ---
# 発音(オンセット)の検出
onset_frames = librosa.onset.onset_detect(y=y, sr=sr)

# オンセットの位置をプロット
plt.figure(figsize=(10, 6))
librosa.display.waveshow(y, sr=sr)
plt.vlines(librosa.frames_to_time(onset_frames), ymin=-1, ymax=1, color='r', alpha=0.7, label="Onsets")
plt.title("Rhythm and Onset Detection")
plt.xlabel("Time (s)")
plt.ylabel("Amplitude")
plt.legend()
plt.show()

結果

image.png

image.png

image.png

image.png

image.png

image.png

image.png

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?