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

Sound synthesised on the BEAM: play a `TuningFork.Voice` on a `TuningFork.Stage`.

    {:ok, _pid} = TuningFork.Stage.start_link(sink: TuningFork.Sink.Speaker)
    TuningFork.play(TuningFork.Voice.new(shape: :sine, freq: 440.0))

# `available?`

```elixir
@spec available?() :: boolean()
```

Whether this machine can play sound.

Asked of `TuningFork.Sink.Speaker`, and false when the `tuning_fork_speaker` package is
not installed.

# `play`

```elixir
@spec play(TuningFork.Voice.t()) :: :ok
```

Sound a voice on the stage registered as `TuningFork.Stage`.

Returns immediately; the voice is rendered inside the stage.

# `render`

```elixir
@spec render(TuningFork.Voice.t(), pos_integer(), pos_integer()) :: binary()
```

Render a voice to signed 16-bit little-endian PCM without playing it.

`rate` is samples per second and `channels` is 1 for mono or 2 for stereo. Stereo applies
the voice's `:pan`.

# `start_stage`

```elixir
@spec start_stage(keyword()) :: DynamicSupervisor.on_start_child()
```

Start a stage under `tuning_fork`'s own `DynamicSupervisor`.

`opts` are `TuningFork.Stage.start_link/1`'s options. The stage is not linked to the
caller.

---

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