GLSLで扱う音源について
FM音源の話に入る前に音源について少し書いておきます。
大雑把に言えば、sound programは、音源とシーケンスだけです。今回は音源の基礎部分だけ書いて行きます。
音源には基本波形が有ります。 sin波、ノコギリ波、矩形波、三角波が有ります。これらを材料として音を作っていきます。その他にノイズを加工するという方法も有りますが、GPUだとフィルターを作る事については不向きです。フィルターについては、良くわかりません。でも別のやり方でノイズを使ってたりはします。ノイズについては、いずれ纏めないとは思ってます。基本波形はオシレーター(OSC)として使います。以後、オシレーターはOSCと表記していきます。
OSCの関数です。入力は時間と周波数を乗算したモノ。OSCには、これを引数にした方が便利だったりします。
// OSC #define osc_sin(x) sin((x)*6.2832) #define osc_saw(x) (1.0-fract(x)*2.0) #define osc_sqr(x) sign(0.5-fract(x)) #define osc_tri(x) asin(sin((x)*6.2832))/1.5708
音源には、もう一つ大事な要素が有ります。それがエンベロープ。音の衰減です。
大抵のshaderを見れば
exp(-time*3.0)
とかで済ましてます。これはディケイだけのエンベロープです。ADSRとかも作れますが、使い道とかが良くわかってません。大抵はアタックとディケイだけのエンベロープを使ってます。これも参考に書いておきます。
float env_adsr(float t, vec4 e, float sLv) { float a=t/max(1e-5,e.x); float d=(t<e.x+e.y)?1.-(t-e.x)*sLv/max(1e-5,e.y):0.; float s=1.-sLv; float r=(1.-sLv)-(t-e.x-e.y-e.z)*(1.-sLv)/max(1e-5,e.w); return max(0.,min(a,max(d,min(s,r)))); } float env_d(float t, float d) { return exp(-t*5./d); } float env_ad(float t, float a, float d) { return min(t/max(1e-5,a),env_d(t-a,d)); }
この辺りは単なる道具なので、こんな説明です。
sound programは構造が面倒なのですが、マクロを使うと簡潔に書ける事が多いので、マクロを多用しています。癖でマクロで無くて良い奴もマクロを使っていますが、気にしないでください。