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

Open Sound Control messages, as the bytes that go over the wire.

    iex> TuningFork.Osc.encode("/play", [60, 0.8])
    <<"/play", 0, 0, 0, ",if", 0, 0, 0, 0, 60, 63, 76, 204, 205>>

# `bundle`

```elixir
@spec bundle([{String.t(), [term()]}], :now | DateTime.t() | {integer(), integer()}) ::
  binary()
```

Several messages under one time tag.

    iex> bundle = TuningFork.Osc.bundle([{"/a", [1]}, {"/b", [2]}])
    iex> <<"#bundle", 0, _rest::binary>> = bundle

`at` is `:now` (immediately), a `DateTime`, or a two-element `{seconds, fraction}` NTP tag.

# `decode`

```elixir
@spec decode(binary()) :: {:ok, String.t(), [term()]} | {:error, atom()}
```

The address and arguments a message carries.

    iex> TuningFork.Osc.decode(TuningFork.Osc.encode("/play", [60, "bd", true]))
    {:ok, "/play", [60, "bd", true]}

`{:error, :not_a_message}` for anything that is not a message this understands.

# `encode`

```elixir
@spec encode(String.t(), [term()]) :: binary()
```

A message as bytes.

Each argument is an integer (`i`), float (`f`), binary (`s`), `{:blob, bytes}` (`b`),
`true`, `false` or `nil` (`T`, `F`, `N`), `{:int64, n}` (`h`) or `{:double, f}` (`d`).

    iex> TuningFork.Osc.encode("/hush", [])
    <<"/hush", 0, 0, 0, ",", 0, 0, 0>>

---

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