目次
1. 楽曲のビート情報を推定してみよう!
- Colaboratoryを使います
- リンクをクリックしてをドライブにコピーをクリック
- music/sample.wavをアップロード
- コードを実行
- beat_times.csvをダウンロード
(beat_times.csvにビートのタイミングの秒数が記録されている)
import librosa
import numpy as np
import pandas as pd
# ローカルから音楽ファイルをアップロード
from google.colab import files
uploaded = files.upload()
filename = list(uploaded.keys())[0]
# ビート検出
y, sr = librosa.load(filename)
tempo, beat_frames = librosa.beat.beat_track(y=y, sr=sr)
beat_times = librosa.frames_to_time(beat_frames, sr=sr)
# データをDataFrameに変換
df = pd.DataFrame(beat_times, columns=["Beat_Times"])
# CSVとして保存
csv_filename = "beat_times.csv"
df.to_csv(csv_filename, index=False)
# ダウンロードリンクを表示
files.download(csv_filename)
2. ビート情報を可視化してみよう!
2.1 Minimライブラリをインストールしよう
ProcessingのIDEを開き、Sketchメニューの中のライブラリをインポート… > Manage Libraries…を選択します。
検索ボックスに”Minim”と入力し、表示されたMinimライブラリをインストールします。
2.2 ビート情報を可視化してみよう
- Processingでファイル=>新規 から新しいコードを作成して保存しよう。
- 新しく作成したファイル名/data にsample.wavと先ほどダウンロードしたbeat_times.csvを入れる。
- 以下のコードを実行!
import ddf.minim.*;
ArrayList<Float> beatTimes;
float circleSize;
float baseSize = 50;
float expandSize = 150;
float shrinkSpeed = 5;
int index = 0;
boolean loopStarted = false;
Minim minim;
AudioPlayer player;
void setup() {
size(800, 600);
background(255);
// CSVからビートのタイムスタンプを読み込む
beatTimes = new ArrayList<Float>();
String[] lines = loadStrings("beat_times.csv");
for (int i = 1; i < lines.length; i++) { // ヘッダー行をスキップ
beatTimes.add(float(lines[i]));
}
circleSize = baseSize;
// Minimを初期化し、音楽ファイルを読み込む
minim = new Minim(this);
player = minim.loadFile("sample.wav");
player.play();
player.loop();
}
void draw() {
background(255);
update();
display();
}
void update()
{
float songCurrentTime = player.position() / 1000.0; // 経過時間を秒単位で計算
// ループ再生の時、再生位置が楽曲の最後に達したら index を0にリセット
if (songCurrentTime >= player.length() / 1000.0 - 0.03) {
println("Loop started!");
index = 0;
} else if (songCurrentTime <= 0.025)
{
index = 0;
}
println(index, songCurrentTime, player.length() / 1000.0);
// 現在の再生時間を表示
fill(0);
text("Current time: " + nf(songCurrentTime, 0, 2) + " seconds", 20, 20);
// 次のビートが来たら円のサイズを大きくする
if (index < beatTimes.size() && songCurrentTime >= beatTimes.get(index)) {
if (index%2==0)
circleSize = expandSize;
index++;
}
// 円のサイズを縮小させる
circleSize = lerp(circleSize, baseSize, shrinkSpeed * 0.01);
}
void display()
{
// 円を描画
fill(127);
ellipse(width/2, height/2, circleSize, circleSize);
}
void stop() {
player.close();
minim.stop();
super.stop();
}
音楽のビートに合わせて円が大きくなったかな?
3. ビート情報に合わせてエフェクトをコントロールしよう!
part09_random_circle_on_beatを実行!
ビートに合わせてエフェクトがどのように変化したかな?コードを追ってみよう!