# `TuningFork.Envelope`
[🔗](https://github.com/jaman/tuning_fork/blob/v0.1.11/tuning_fork/lib/tuning_fork/envelope.ex#L1)

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)

# `t`

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

# `duration`

```elixir
@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.

    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

# `hit`

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

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

# `level`

```elixir
@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`

```elixir
@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

# `spanning`

```elixir
@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

---

*Consult [api-reference.md](api-reference.md) for complete listing*
