🎶

[VRChat]自作ShaderからAudioLinkを使う方法メモ

に公開

あくまで個人用メモなので、間違いがあるかもしれないです。

想定読者

頂点シェーダーとフラグメントシェーダーの書き方をある程度理解しており、AudioLinkを使ってみたい方

基本的な使い方

  1. VCCから最新のAudioLinkパッケージを導入する。

  2. シェーダーファイル内で、#include "Packages/com.llealloo.audiolink/Runtime/Shaders/AudioLink.cginc"と書いてAudioLinkの機能をインクルードする。

  3. 上記でインクルードされた関数のうちの一つ、AudioLinkData()を使うと、AudioLinkが提供する音声解析データが載っているテクスチャから指定したピクセルの色データを取り出すことができる(tex2D()みたいな感じ)。引数はuint2で、テクスチャのuv座標を指定する。


AudioLink Textureの一例
(AudioLink公式ドキュメント(https://github.com/llealloo/audiolink/tree/master/Docs)より)

  1. 取得した色データを用いて処理を行う。

取得したい情報のピクセル座標の算出方法

AudioLink.cgincはファイルの最初に以下のように定数を宣言している。

AudioLink.cginc
// Map of where features in AudioLink are.
#define ALPASS_DFT                      uint2(0,4)  //Size: 128, 2
#define ALPASS_WAVEFORM                 uint2(0,6)  //Size: 128, 16
#define ALPASS_AUDIOLINK                uint2(0,0)  //Size: 128, 4
#define ALPASS_AUDIOBASS                uint2(0,0)  //Size: 128, 1
#define ALPASS_AUDIOLOWMIDS             uint2(0,1)  //Size: 128, 1
#define ALPASS_AUDIOHIGHMIDS            uint2(0,2)  //Size: 128, 1
#define ALPASS_AUDIOTREBLE              uint2(0,3)  //Size: 128, 1
#define ALPASS_AUDIOLINKHISTORY         uint2(1,0)  //Size: 127, 4
#define ALPASS_GENERALVU                uint2(0,22) //Size: 12, 1
#define ALPASS_GENERALVU_INSTANCE_TIME  uint2(2,22)
#define ALPASS_GENERALVU_LOCAL_TIME     uint2(3,22)
#define ALPASS_GENERALVU_NETWORK_TIME   uint2(4,22)
#define ALPASS_GENERALVU_PLAYERINFO     uint2(6,22)
#define ALPASS_THEME_COLOR0             uint2(0,23)
#define ALPASS_THEME_COLOR1             uint2(1,23)
#define ALPASS_THEME_COLOR2             uint2(2,23)
#define ALPASS_THEME_COLOR3             uint2(3,23)
#define ALPASS_GENERALVU_UNIX_DAYS      uint2(5,23)
#define ALPASS_GENERALVU_UNIX_SECONDS   uint2(6,23)
#define ALPASS_GENERALVU_SOURCE_POS     uint2(7,23)
#define ALPASS_MEDIASTATE               uint2(5,22)

#define ALPASS_CCINTERNAL               uint2(12,22) //Size: 12, 2
#define ALPASS_CCCOLORS                 uint2(25,22) //Size: 12, 1 (Note Color #0 is always black, Colors start at 1)
#define ALPASS_CCSTRIP                  uint2(0,24)  //Size: 128, 1
#define ALPASS_CCLIGHTS                 uint2(0,25)  //Size: 128, 2
#define ALPASS_AUTOCORRELATOR           uint2(0,27)  //Size: 128, 1
#define ALPASS_FILTEREDAUDIOLINK        uint2(0,28)  //Size: 16, 4
#define ALPASS_CHRONOTENSITY            uint2(16,28) //Size: 8, 4
#define ALPASS_FILTEREDVU               uint2(24,28) //Size: 4, 4
#define ALPASS_FILTEREDVU_INTENSITY     uint2(24,28) //Size: 4, 1
#define ALPASS_FILTEREDVU_MARKER        uint2(24,29) //Size: 4, 1
#define ALPASS_GLOBAL_STRINGS           uint2(40,28) //Size: 8, 4

これらはその定数名[1]の機能に対応付けられたテクスチャの範囲の最初の部分を示している。それぞれの定数名の意味は、公式ドキュメント(https://github.com/llealloo/audiolink/tree/master/Docs)を参照。

例えば、公式ドキュメントによれば、ALPASS_AUDIOLINKは(0,0)から横1px,縦4pxで音声の各周波数に対する音量のデータを提供している。(0,0)がBass帯, (0,1)がLowMid帯, (0,2)がHighMid帯, (0,3)がTreble帯として割り当てられている。

これらは例えば以下のようにして用いる。

fixed4 frag (v2f i) : SV_Target
{
    float impulse = AudioLinkData( ALPASS_AUDIOLINK + uint2( 0, i.uv.y * 4. ) );
    return fixed4(impulse, impulse, impulse, 1.0);
}


結果

上記ではデータを取得する関数としてAudioLinkData()を使ったが、AudioLinkにはこれを含めて4つのデータ取得用関数がAudioLink.cginc内に定義されている。それぞれの機能について解説する。なお、分かりやすさのために若干本来の実装と異なる書き方をしているものもあるが、使用する側としては不都合はないはず。

  • float4 AudioLinkData(uint2 xycoord)
    単純に、指定されたピクセル座標での色を取ってくる。
  • float4 AudioLinkDataMultiline(uint2 xycoord)
    AudioLinkData() に改行機能が付いたもの。AudioLinkが提供する機能の一部は複数行にまたがってデータが提供されていることもあるので、それらを使用する際はこちらを使うと便利だと思う。
  • float4 AudioLinkLerp(float2 xy)
    指定したピクセルと、その右隣のピクセルのデータを線形補完してくれる。内部実装は
    return lerp( AudioLinkData(xy), AudioLinkData(xy+int2(1,0)), frac( xy.x ) ); 
    
    となっている。
    波形表示をするとき、こちらを使うと波が滑らかになる。
  • float4 AudioLinkLerpMultiline(float2 xy)
    AudioLinkLerp() の複数行対応版。

ワールド側でのAudioLinkのセットアップ

アバターのシェーダーとして使用する場合はこの章は読み飛ばしても問題ない。

  1. Tools/AudioLink/Add AudioLink Prefab to SceneでPrefabをシーンに追加
  2. 僕の場合は音声ファイルを直に流したかったので、中にあるAudioLinkInputは消して、Audio Sourceコンポーネントを持つオブジェクトを新たに作成してAudioLinkのスクリプトに参照を設定したが、この辺りはやや理解が怪しい。
  3. Audio Sourceでゲーム開始時に再生にチェックを入れるなり、Udonから再生するなりして音を流し始めると、AudioLinkが自動で音声を解析してテクスチャを毎フレーム作成してくれる。

この記事がお役に立ちましたら、いいねを押していただけると大変励みになります。


(余談: ここまで辿り着くのに5時間くらいかかりました... 自分がシェーダー初心者なのもあるかもしれませんが、AudioLink難しい...)

脚注
  1. ALPASSはたぶんAudioLinkPassの略 ↩︎

Discussion