うえすと開発メモ

Unity上で楽曲をテンポ解析してBPMを推定する機能を作ってみました。

使い方
public AudioClip targetClip;

private void Start()
{
    int bpm = BpmAnalyzer.AnalyzeBpm(targetClip);
    Debug.Log("BPMは多分 " + bpm + " くらい");
}
AnalyzeBpmの中ではAudioClip.GetData()で取ってきたオーディオのサンプルデータを解析しています。

BpmAnalyzer.cs内で
サンプルデータをある程度で区切ってまとめるCreateVolumeArrayメソッドと、
実際にBPMを推定しているSearchBpmメソッドは、
処理時間が結構かかるので別スレッドから呼ぶように変更したほうが良いと思います。

※コルーチンみたいに使えるThread Ninja(Unity Asset Store)はおすすめ。
UnityEngine名前空間でもMathfなら別スレッドからでも呼べます。

また、例のシーンではメトロノームを使っていますが、実際の楽曲はテンポが動的に変わったりするので、万能ではないです。
楽曲を数秒おきに区切ってその範囲でBPMを推定する等が良いかもしれません。


参考
テンポ解析のアルゴリズム:
C/C++言語で音声ファイルのテンポ解析を行うサンプルプログラム 

AudioClip.GetDataで取れる値について:
このエントリーをはてなブックマークに追加

Steam上でゲームをリリースする際に、Steamworks SDKの組み込みが必要になります。
steamworks
Steamworks ドキュメンテーション (要Steam開発者登録)

Steamworks SDKはC++のdllのため、Unityで使う場合はネイティブコード呼び出しで使用する必要がありますが、
ほぼ全APIをC#でラップしてくれているありがたいプロジェクトがありました。

GitHub - Steamworks.NET
ドキュメント - Steamworks.NET

このエントリーをはてなブックマークに追加

Unity5.3で追加されたJsonUtilityを少し使ってみました。
https://docs.unity3d.com/ScriptReference/JsonUtility.html

JsonUtility.ToJsonJsonUtility.FromJsonで変換する。

・内部でUnityのシリアライザを使っているので、自前のクラスを含めたい場合、
MonoBehaviourとScriptableObjectを継承していればそのまま変換される。
そうでないクラスや構造体には[Serializable]属性を付けないと無視される。

・DictinaryやHashtableはシリアライズされないため、これも無視される。
回避策として、Json化したいクラスでISerializationCallbackReceiverを継承し、
OnBeforeSerializeOnAfterDeserializeでシリアライズ前、デシリアライズ後のタイミングをフックできるので、List等の別の型に置き換える。

以下、テスト用のコンポーネント。


このエントリーをはてなブックマークに追加

このページのトップヘ