# `TuningFork.Sample.Font`
[🔗](https://github.com/jaman/tuning_fork/blob/v0.1.12/tuning_fork/lib/tuning_fork/sample/font.ex#L1)

Soundfont instruments as Strudel plays them: one file per instrument, a zone per key
range, each zone a recording with its root pitch and loop.

    {:ok, sample} = TuningFork.Sample.Font.sample("0040_JCLive_sf2_file", 60)

# `zone`

```elixir
@type zone() :: %{
  low: integer(),
  high: integer(),
  root: float(),
  rate: pos_integer(),
  loop: {non_neg_integer(), pos_integer()} | nil,
  data: {:file, binary()} | {:pcm, binary()},
  sample: TuningFork.Sample.t() | nil
}
```

# `child_spec`

Returns a specification to start this module under a supervisor.

See `Supervisor`.

# `clear`

```elixir
@spec clear() :: :ok
```

Forget every font loaded, once any load in flight has finished.

# `decode`

```elixir
@spec decode(zone(), String.t(), non_neg_integer()) ::
  {:ok, TuningFork.Sample.t()} | {:error, term()}
```

The zone's recording as a `TuningFork.Sample`, decoded through
`TuningFork.Sample.Decode` when it is a compressed file. `index` names it in the cache.

# `load`

```elixir
@spec load(String.t()) :: :ok | {:error, term()}
```

Fetch, decode and keep the font `name`; `:ok` when it is there, `{:error, reason}` when not.

# `loaded?`

```elixir
@spec loaded?(String.t()) :: boolean()
```

Whether the font `name` is loaded.

# `parse`

```elixir
@spec parse(String.t()) :: {:ok, [zone()]} | {:error, term()}
```

The zones written in a webaudiofont file, undecoded. `{:error, reason}` for text that is
not one.

# `prefetch`

```elixir
@spec prefetch(String.t()) :: :ok
```

Start loading the font `name` in the background and return at once.

# `sample`

```elixir
@spec sample(String.t(), number(), keyword()) ::
  {:ok, TuningFork.Sample.t()} | :loading | :error
```

The recording to play `midi` on the font `name`, decoded and kept once fetched.

## Options

  * `:wait` — whether to fetch and decode a font not loaded yet, default `true`. With
    `false` that starts in the background and the answer is `:loading` until it is done

`:error` for a font that cannot be fetched or a note no zone covers.

# `source`

```elixir
@spec source() :: String.t()
```

Where font files are fetched from; `source/1` changes it.

# `source`

```elixir
@spec source(String.t()) :: :ok
```

Fetch font files from `url` instead of Strudel's host.

# `zone_for`

```elixir
@spec zone_for([zone()], number()) :: zone() | nil
```

The zone of `zones` covering `midi`, or `nil`.

---

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