地図/気まぐれ/音と絵

包絡 — ゆっくりの層

実際の音は、立ち上がって、減って、保たれて、消える。この音量の輪郭がエンベロープ(包絡)。代表的なのが ADSR で、Attack・Decay・Sustain・Release の4区間でできた折れ線。

ADSR は鍵を押している間(ゲート)と離した後で形が分かれる。押すと Attack で 0 から最大へ、Decay で持続レベル(Sustain)まで落ち、離鍵まで Sustain を保つ。鍵を離すと Release で 0 へ戻る。Attack・Decay・Release は時間、Sustain だけが音量で、他の三つと単位が違う。WebAudio では GainNode.gainlinearRampToValueAtTime / setTargetAtTime を時刻ごとに積んで、この折れ線をそのまま音量に重ねる。

時刻 e を入れると 0..1 の音量が返る。立ち上がりは直線、減衰は持続レベルへの直線、ゲート中は平ら、離鍵後は 0 への直線。区間の境目を if で分ける。

const adsr = (e, gateLen) => {
  const attack = 36
  const decay = 40
  const sustain = 0.55
  const release = 64
  if (e < attack) return e / attack
  if (e < attack + decay) return 1 - (1 - sustain) * ((e - attack) / decay)
  if (e < gateLen) return sustain
  const rel = e - gateLen
  if (rel >= release) return 0
  return sustain * (1 - rel / release)
}

下は adsr を左から右へ並べて、折れ線そのものを描いた。attack で一気に上がり、decay で少し落ち、gateLen まで sustain の高さで平らに伸び、ゲートを過ぎると release で 0 へ戻る。四つの区間で傾きが切り替わる。

attack を大きくすると立ち上がりが鈍く、sustain を上げると平らな部分が高くなり、release を伸ばすと右の尾が長くなる。gateLen がゲートの長さで、ここを過ぎた所から離鍵の下りが始まる。

下は時刻 t を毎フレーム進め、その時点の adsr の値を右端に書き込んで左へ流している。波形が右から左へ流れ、右端の点が再生ヘッド。値が 0 に戻りきると次の音が鳴り、ゲートの長さを変えながら包絡を繰り返す。

右端のヘッドが上下しながら、過ぎた音量が左へ尾を引いて残る。ゲートが長い音ほど平らな部分が長く伸び、短い音は山だけで終わる。波形が速い振動だとすれば、包絡は遅い変化で、音はこの速い層と遅い層の二段でできている。