TuningFork.Envelope (TuningFork v0.1.12)

Copy Markdown View Source

An attack-decay-sustain-release shape in seconds, sampled by time.

TuningFork.Envelope.new(attack: 0.01, decay: 0.2, sustain: 0.4, release: 0.3)

Summary

Functions

How long the envelope sounds, in seconds: attack, decay, hold and release together, or attack and decay alone when sustain is 0.0, since nothing is left to hold or release. A gated/2 envelope lasts until its gate and then its release, or attack and decay alone when it has no sustain and has died away before the gate.

The envelope played as a key held for seconds and then let go: attack, decay and sustain run at their own speeds for as long as the key is held, and the release starts from whatever level has been reached when it is let go — part-way through the attack or decay for a short note. A note with no sustain that has died away before it is let go ends there. Any hold is dropped.

A percussive envelope: a 2 ms attack, decay seconds of fall, and no sustain or release.

The level at t seconds, from 0.0 to 1.0.

An envelope, with anything unset left at its default.

The envelope with its decay set so the whole of it lasts seconds: the decay is seconds less the attack and, when there is a sustain level to release from, the release; any hold is dropped. The decay is never under 10 ms.

Types

t()

@type t() :: %TuningFork.Envelope{
  attack: float(),
  curve: float(),
  decay: float(),
  gate: float() | nil,
  hold: float(),
  release: float(),
  sustain: float()
}

Functions

duration(env)

@spec duration(t()) :: float()

How long the envelope sounds, in seconds: attack, decay, hold and release together, or attack and decay alone when sustain is 0.0, since nothing is left to hold or release. A gated/2 envelope lasts until its gate and then its release, or attack and decay alone when it has no sustain and has died away before the gate.

iex> TuningFork.Envelope.duration(TuningFork.Envelope.new(attack: 0.1, decay: 0.2, sustain: 0.5, hold: 1.0, release: 0.3))
1.6
iex> TuningFork.Envelope.duration(TuningFork.Envelope.new(attack: 0.1, decay: 0.4, sustain: 0.0, hold: 1.0, release: 0.3))
0.5

gated(env, seconds)

@spec gated(t(), number()) :: t()

The envelope played as a key held for seconds and then let go: attack, decay and sustain run at their own speeds for as long as the key is held, and the release starts from whatever level has been reached when it is let go — part-way through the attack or decay for a short note. A note with no sustain that has died away before it is let go ends there. Any hold is dropped.

iex> TuningFork.Envelope.new(attack: 0.1, decay: 0.2, sustain: 0.5, release: 0.3) |> TuningFork.Envelope.gated(2.0) |> TuningFork.Envelope.duration()
2.3
iex> TuningFork.Envelope.new(attack: 0.1, decay: 0.2, sustain: 0.5, release: 0.3) |> TuningFork.Envelope.gated(2.0) |> TuningFork.Envelope.level(1.5)
0.5
iex> TuningFork.Envelope.new(attack: 0.1, decay: 1.0, sustain: 0.0, release: 0.3) |> TuningFork.Envelope.gated(4.0) |> TuningFork.Envelope.duration()
1.1

hit(decay)

@spec hit(float()) :: t()

A percussive envelope: a 2 ms attack, decay seconds of fall, and no sustain or release.

level(env, t)

@spec level(t(), float()) :: float()

The level at t seconds, from 0.0 to 1.0.

0.0 before the envelope starts and after it ends.

new(opts \\ [])

@spec new(keyword()) :: t()

An envelope, with anything unset left at its default.

Options

  • :attack — seconds from silence to full level, default 0.005
  • :decay — seconds from full level down to :sustain, default 0.05
  • :sustain — the level held after the decay, 0.0 to 1.0, default 0.0
  • :hold — seconds spent at :sustain, default 0.0
  • :release — seconds from :sustain back to silence, default 0.02
  • :curve — the exponent the decay falls by, default 2.0; 1.0 is a straight line
  • :gate — seconds after which the note is let go, default nil. See gated/2

spanning(env, seconds)

@spec spanning(t(), number()) :: t()

The envelope with its decay set so the whole of it lasts seconds: the decay is seconds less the attack and, when there is a sustain level to release from, the release; any hold is dropped. The decay is never under 10 ms.

iex> TuningFork.Envelope.spanning(TuningFork.Envelope.new(attack: 0.1, sustain: 0.5, release: 0.2), 1.0).decay
0.7
iex> TuningFork.Envelope.spanning(TuningFork.Envelope.new(attack: 0.1, sustain: 0.0, release: 0.2), 1.0).decay
0.9
iex> TuningFork.Envelope.spanning(TuningFork.Envelope.new(attack: 0.1, sustain: 1.0, hold: 2.0, release: 0.2), 1.0) |> TuningFork.Envelope.duration()
1.0