Try & Error for Sound Program

FoxDotを始めました。色々と試してみます。

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は構造が面倒なのですが、マクロを使うと簡潔に書ける事が多いので、マクロを多用しています。癖でマクロで無くて良い奴もマクロを使っていますが、気にしないでください。