# `TuningFork.SonicPi.Synth`
[🔗](https://github.com/jaman/tuning_fork/blob/v0.1.11/tuning_fork/lib/tuning_fork/sonic_pi/synth.ex#L1)

Sonic Pi's synths as `TuningFork.Voice`s.

    Synth.voice(:tb303, 110.0, cutoff: 90, res: 0.9, release: 0.25)

# `known?`

```elixir
@spec known?(atom()) :: boolean()
```

Whether `name` is a synth here.

# `names`

```elixir
@spec names() :: [atom()]
```

Every synth name, sorted.

# `resonance`

```elixir
@spec resonance(number()) :: float()
```

The resonance a Sonic Pi `:res` from 0 to 1 stands for, as a `TuningFork.Filter` `:q`.

# `voice`

```elixir
@spec voice(atom() | String.t() | TuningFork.Voice.t(), float(), keyword()) ::
  TuningFork.Voice.t() | [TuningFork.Voice.t()]
```

The voice or voices `name` plays at `hz` with `opts`.

`name` is one of `names/0`, a `TuningFork.Voice` used as it is with the pitch and the
options applied, or a string `TuningFork.Kit.known?/1` accepts, played through the kit at
the note nearest `hz`. A detuned synth gives a list of voices. Raises `ArgumentError` for a
name that is not here.

## Options

  * `:amp` — level, 1 being normal; `:pan` from -1 to 1
  * `:attack`, `:decay`, `:sustain`, `:release` — seconds; `:sustain` is how long the note is
    held. Defaults 0, 0, 0 and 1
  * `:sustain_level` — the level held during `:sustain`, default 1
  * `:cutoff` — a lowpass, as a MIDI note; `:res` — its resonance, 0 to 1; `:cutoff_min` —
    where a swept filter starts
  * `:detune` — semitones between the voices of a detuned synth
  * `:divisor`, `:depth` — FM ratio and depth; `:mod_phase`, `:mod_range` — the `mod_*` synths'
    vibrato
  * `:vib`, `:vibmod`, `:crush`, `:distort`, `:coarse`, `:phaser`, `:phaserdepth`, `:vowel`,
    `:fm`, `:fmh`, `:fmattack`, `:highpass`, `:seed` — `TuningFork.Voice` fields, passed through

Any other key is ignored.

---

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